summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.clang-tidy11
-rw-r--r--.dir-locals.el10
-rw-r--r--.luacheckrc99
-rw-r--r--.mailmap57
-rw-r--r--AUTHORS85
-rw-r--r--CONTRIBUTING.md19
-rw-r--r--COPYING695
-rw-r--r--CodingStyle5
-rw-r--r--Dockerfile78
-rw-r--r--NEWS1305
-rw-r--r--README.md75
-rw-r--r--bench/bench_lru.c242
-rw-r--r--bench/bench_lru_set1.tsv65536
-rw-r--r--bench/meson.build24
-rwxr-xr-xci/deckard_commit_check.sh13
-rwxr-xr-xci/fix-meson-junit.sh5
-rwxr-xr-xci/gh_actions.py58
-rw-r--r--ci/images/README.md41
-rwxr-xr-xci/images/build.sh13
-rw-r--r--ci/images/debian-11-coverity/Dockerfile43
-rw-r--r--ci/images/debian-11/Dockerfile144
-rw-r--r--ci/images/debian-buster/Dockerfile145
-rwxr-xr-xci/images/push.sh8
-rwxr-xr-xci/images/update.sh22
-rwxr-xr-xci/images/vars.sh13
-rwxr-xr-xci/no_assert_check.sh3
-rw-r--r--ci/pkgtest.yaml300
-rw-r--r--ci/respdiff/kresd.config26
-rw-r--r--ci/respdiff/respdiff-tcp.conf52
-rw-r--r--ci/respdiff/respdiff-tls.conf52
-rw-r--r--ci/respdiff/respdiff-udp.conf52
-rwxr-xr-xci/respdiff/restart-bind.sh3
-rwxr-xr-xci/respdiff/restart-kresd.sh12
-rwxr-xr-xci/respdiff/restart-unbound.sh4
-rwxr-xr-xci/respdiff/run-respdiff-tests.sh27
-rwxr-xr-xci/respdiff/start-resolvers.sh13
-rwxr-xr-xclient/.packaging/test.sh5
-rw-r--r--contrib/base32hex.c277
-rw-r--r--contrib/base32hex.h60
-rw-r--r--contrib/base32hex.spdx10
-rw-r--r--contrib/base64.c260
-rw-r--r--contrib/base64.h95
-rw-r--r--contrib/base64.spdx10
-rw-r--r--contrib/base64url.c287
-rw-r--r--contrib/base64url.h103
l---------contrib/ccan/asprintf/LICENSE1
-rw-r--r--contrib/ccan/asprintf/asprintf.c57
-rw-r--r--contrib/ccan/asprintf/asprintf.h51
-rw-r--r--contrib/ccan/asprintf/asprintf.spdx10
l---------contrib/ccan/compiler/LICENSE1
-rw-r--r--contrib/ccan/compiler/compiler.h232
-rw-r--r--contrib/ccan/compiler/compiler.spdx10
l---------contrib/ccan/json/LICENSE1
-rw-r--r--contrib/ccan/json/json.c1362
-rw-r--r--contrib/ccan/json/json.h99
-rw-r--r--contrib/ccan/json/json.spdx10
-rw-r--r--contrib/cleanup.h25
-rw-r--r--contrib/config.h7
-rw-r--r--contrib/dynarray.h112
-rw-r--r--contrib/dynarray.spdx10
-rw-r--r--contrib/licenses/BSD-MIT21
-rw-r--r--contrib/licenses/CC032
-rw-r--r--contrib/licenses/LGPL2506
-rw-r--r--contrib/mempattern.c151
-rw-r--r--contrib/mempattern.h92
-rw-r--r--contrib/meson.build28
l---------contrib/murmurhash3/LICENSE1
-rw-r--r--contrib/murmurhash3/murmurhash3.c76
-rw-r--r--contrib/murmurhash3/murmurhash3.h9
-rw-r--r--contrib/murmurhash3/murmurhash3.spdx10
l---------contrib/ucw/LICENSE1
-rw-r--r--contrib/ucw/alloc.h38
-rw-r--r--contrib/ucw/config.h58
-rw-r--r--contrib/ucw/lib.h125
-rw-r--r--contrib/ucw/libucw.spdx10
-rw-r--r--contrib/ucw/mempool-fmt.c99
-rw-r--r--contrib/ucw/mempool.c601
-rw-r--r--contrib/ucw/mempool.h572
-rw-r--r--daemon/.packaging/centos/7/builddeps13
-rwxr-xr-xdaemon/.packaging/centos/7/pre-build.sh9
-rwxr-xr-xdaemon/.packaging/centos/7/pre-run.sh8
-rw-r--r--daemon/.packaging/centos/7/rundeps6
-rw-r--r--daemon/.packaging/centos/8/builddeps14
-rwxr-xr-xdaemon/.packaging/centos/8/pre-build.sh9
-rwxr-xr-xdaemon/.packaging/centos/8/pre-run.sh7
-rw-r--r--daemon/.packaging/centos/8/rundeps6
-rw-r--r--daemon/.packaging/debian/10/builddeps12
-rwxr-xr-xdaemon/.packaging/debian/10/pre-build.sh11
-rwxr-xr-xdaemon/.packaging/debian/10/pre-run.sh11
-rw-r--r--daemon/.packaging/debian/10/rundeps15
-rw-r--r--daemon/.packaging/debian/9/builddeps12
-rwxr-xr-xdaemon/.packaging/debian/9/pre-build.sh11
-rwxr-xr-xdaemon/.packaging/debian/9/pre-run.sh11
-rw-r--r--daemon/.packaging/debian/9/rundeps15
-rw-r--r--daemon/.packaging/fedora/31/builddeps14
-rwxr-xr-xdaemon/.packaging/fedora/31/pre-build.sh7
-rwxr-xr-xdaemon/.packaging/fedora/31/pre-run.sh6
-rw-r--r--daemon/.packaging/fedora/31/rundeps7
-rw-r--r--daemon/.packaging/fedora/32/builddeps14
-rwxr-xr-xdaemon/.packaging/fedora/32/pre-build.sh7
-rwxr-xr-xdaemon/.packaging/fedora/32/pre-run.sh6
-rw-r--r--daemon/.packaging/fedora/32/rundeps7
-rw-r--r--daemon/.packaging/leap/15.2/builddeps14
-rwxr-xr-xdaemon/.packaging/leap/15.2/pre-build.sh6
-rwxr-xr-xdaemon/.packaging/leap/15.2/pre-run.sh3
-rw-r--r--daemon/.packaging/leap/15.2/rundeps4
-rw-r--r--daemon/.packaging/leap/docker-image-name1
-rw-r--r--daemon/.packaging/test.config2
-rw-r--r--daemon/.packaging/ubuntu/16.04/builddeps16
-rwxr-xr-xdaemon/.packaging/ubuntu/16.04/pre-build.sh12
-rwxr-xr-xdaemon/.packaging/ubuntu/16.04/pre-run.sh12
-rw-r--r--daemon/.packaging/ubuntu/16.04/rundeps15
-rw-r--r--daemon/.packaging/ubuntu/18.04/builddeps16
-rwxr-xr-xdaemon/.packaging/ubuntu/18.04/pre-build.sh12
-rwxr-xr-xdaemon/.packaging/ubuntu/18.04/pre-run.sh12
-rw-r--r--daemon/.packaging/ubuntu/18.04/rundeps15
-rw-r--r--daemon/.packaging/ubuntu/20.04/builddeps16
-rwxr-xr-xdaemon/.packaging/ubuntu/20.04/pre-build.sh12
-rwxr-xr-xdaemon/.packaging/ubuntu/20.04/pre-run.sh12
-rw-r--r--daemon/.packaging/ubuntu/20.04/rundeps15
-rw-r--r--daemon/bindings/api.h12
-rw-r--r--daemon/bindings/cache.c382
-rw-r--r--daemon/bindings/cache.rst338
-rw-r--r--daemon/bindings/event.c209
-rw-r--r--daemon/bindings/event.rst139
-rw-r--r--daemon/bindings/impl.c95
-rw-r--r--daemon/bindings/impl.h90
-rw-r--r--daemon/bindings/modules.c77
-rw-r--r--daemon/bindings/modules.rst43
-rw-r--r--daemon/bindings/net.c1260
-rw-r--r--daemon/bindings/net_client.rst34
-rw-r--r--daemon/bindings/net_dns_tweaks.rst35
-rw-r--r--daemon/bindings/net_server.rst225
-rw-r--r--daemon/bindings/net_tlssrv.rst188
-rw-r--r--daemon/bindings/net_xdpsrv.rst140
-rw-r--r--daemon/bindings/worker.c81
-rw-r--r--daemon/bindings/worker.rst35
-rw-r--r--daemon/cache.test/clear.test.lua215
-rw-r--r--daemon/cache.test/insert_ns.test.integr/deckard.yaml14
-rw-r--r--daemon/cache.test/insert_ns.test.integr/kresd_config.j289
-rw-r--r--daemon/cache.test/insert_ns.test.integr/nondelegated_auth.rpl59
-rw-r--r--daemon/cache.test/testroot.zone1257
-rw-r--r--daemon/cache.test/testroot.zone.unsigned216
-rw-r--r--daemon/engine.c892
-rw-r--r--daemon/engine.h84
-rw-r--r--daemon/ffimodule.c304
-rw-r--r--daemon/ffimodule.h36
-rw-r--r--daemon/http.c953
-rw-r--r--daemon/http.h85
-rw-r--r--daemon/io.c1169
-rw-r--r--daemon/io.h80
-rw-r--r--daemon/lua/controlsock.test.lua169
-rw-r--r--daemon/lua/distro-preconfig.lua.in19
-rw-r--r--daemon/lua/kluautil.lua94
-rw-r--r--daemon/lua/kres-gen-30.lua638
-rw-r--r--daemon/lua/kres-gen-31.lua647
-rw-r--r--daemon/lua/kres-gen-32.lua648
-rwxr-xr-xdaemon/lua/kres-gen.sh353
-rw-r--r--daemon/lua/kres.lua1143
-rw-r--r--daemon/lua/krprint.lua340
-rw-r--r--daemon/lua/krprint.test.lua292
-rw-r--r--daemon/lua/log.test.lua42
-rw-r--r--daemon/lua/map.test.integr/deckard.yaml38
-rw-r--r--daemon/lua/map.test.integr/kresd_config.j2193
-rw-r--r--daemon/lua/map.test.integr/query-while-map-is-running.rpl312
-rw-r--r--daemon/lua/meson.build118
-rw-r--r--daemon/lua/postconfig.lua70
-rw-r--r--daemon/lua/sandbox.lua.in833
-rw-r--r--daemon/lua/trust_anchors.lua.in532
-rw-r--r--daemon/lua/trust_anchors.rst123
-rw-r--r--daemon/lua/trust_anchors.test/bootstrap.test.lua112
-rw-r--r--daemon/lua/trust_anchors.test/err_attr_extra_attr.xml16
-rw-r--r--daemon/lua/trust_anchors.test/err_attr_validfrom_invalid.xml16
-rw-r--r--daemon/lua/trust_anchors.test/err_attr_validfrom_missing.xml16
-rw-r--r--daemon/lua/trust_anchors.test/err_elem_extra.xml17
-rw-r--r--daemon/lua/trust_anchors.test/err_elem_missing.xml16
-rw-r--r--daemon/lua/trust_anchors.test/err_multi_ta.xml19
-rw-r--r--daemon/lua/trust_anchors.test/ok0_badtimes.xml16
-rw-r--r--daemon/lua/trust_anchors.test/ok1.xml10
-rw-r--r--daemon/lua/trust_anchors.test/ok1_expired1.xml16
-rw-r--r--daemon/lua/trust_anchors.test/ok1_notyet1.xml16
-rw-r--r--daemon/lua/trust_anchors.test/ok2.xml16
-rwxr-xr-xdaemon/lua/trust_anchors.test/regen.sh3
-rw-r--r--daemon/lua/trust_anchors.test/root.keys1
-rw-r--r--daemon/lua/trust_anchors.test/ta.test.lua85
-rw-r--r--daemon/lua/trust_anchors.test/unsupp_nonroot.xml10
-rw-r--r--daemon/lua/trust_anchors.test/unsupp_xml_v11.xml10
-rw-r--r--daemon/lua/trust_anchors.test/webserv.lua236
-rw-r--r--daemon/lua/trust_anchors.test/x509/ca-key.pem182
-rw-r--r--daemon/lua/trust_anchors.test/x509/ca.pem24
-rw-r--r--daemon/lua/trust_anchors.test/x509/ca.tmpl4
-rwxr-xr-xdaemon/lua/trust_anchors.test/x509/gen.sh13
-rw-r--r--daemon/lua/trust_anchors.test/x509/server-key.pem182
-rw-r--r--daemon/lua/trust_anchors.test/x509/server.pem27
-rw-r--r--daemon/lua/trust_anchors.test/x509/server.tmpl7
-rw-r--r--daemon/lua/trust_anchors.test/x509/wrongca-key.pem182
-rw-r--r--daemon/lua/trust_anchors.test/x509/wrongca.pem24
-rw-r--r--daemon/lua/trust_anchors.test/x509/wrongca.tmpl4
-rw-r--r--daemon/lua/zonefile.lua93
-rw-r--r--daemon/main.c613
-rw-r--r--daemon/meson.build68
-rw-r--r--daemon/network.c928
-rw-r--r--daemon/network.h162
-rw-r--r--daemon/proxyv2.c290
-rw-r--r--daemon/proxyv2.h50
-rw-r--r--daemon/proxyv2.test/deckard.yaml25
-rw-r--r--daemon/proxyv2.test/dnsdist_config.j211
-rw-r--r--daemon/proxyv2.test/kresd_config.j263
-rw-r--r--daemon/proxyv2.test/proxyv2_valid.rpl72
-rw-r--r--daemon/scripting.rst398
-rw-r--r--daemon/session.c834
-rw-r--r--daemon/session.h165
-rw-r--r--daemon/tls.c1214
-rw-r--r--daemon/tls.h235
-rw-r--r--daemon/tls_ephemeral_credentials.c237
-rw-r--r--daemon/tls_session_ticket-srv.c245
-rw-r--r--daemon/udp_queue.c145
-rw-r--r--daemon/udp_queue.h16
-rw-r--r--daemon/worker.c2252
-rw-r--r--daemon/worker.h195
-rw-r--r--daemon/zimport.c741
-rw-r--r--daemon/zimport.h48
-rw-r--r--daemon/zimport.test/tz-rfc-a1-bad.zone14
-rw-r--r--daemon/zimport.test/tz-rfc-a1.zone14
-rw-r--r--daemon/zimport.test/tz-rfc-a2.zone35
-rw-r--r--daemon/zimport.test/tz-rfc-a3.zone31
-rw-r--r--daemon/zimport.test/tz-rfc-a4.zone37
-rw-r--r--daemon/zimport.test/tz-rfc-a5.zone48
-rw-r--r--daemon/zimport.test/zimport.test.lua47
-rw-r--r--distro/config/apkg.toml12
-rw-r--r--distro/pkg/arch/PKGBUILD71
-rw-r--r--distro/pkg/deb/changelog6
-rw-r--r--distro/pkg/deb/clean3
-rw-r--r--distro/pkg/deb/compat1
-rw-r--r--distro/pkg/deb/control140
-rw-r--r--distro/pkg/deb/copyright440
-rw-r--r--distro/pkg/deb/knot-resolver-doc.doc-base11
-rw-r--r--distro/pkg/deb/knot-resolver-doc.docs1
-rw-r--r--distro/pkg/deb/knot-resolver-doc.info2
-rw-r--r--distro/pkg/deb/knot-resolver-doc.links2
-rw-r--r--distro/pkg/deb/knot-resolver-module-dnstap.install1
-rw-r--r--distro/pkg/deb/knot-resolver-module-http.install7
-rw-r--r--distro/pkg/deb/knot-resolver-module-http.links5
-rw-r--r--distro/pkg/deb/knot-resolver-module-http.preinst26
-rw-r--r--distro/pkg/deb/knot-resolver.dirs2
-rw-r--r--distro/pkg/deb/knot-resolver.docs4
-rw-r--r--distro/pkg/deb/knot-resolver.install38
-rw-r--r--distro/pkg/deb/knot-resolver.links2
-rw-r--r--distro/pkg/deb/knot-resolver.manpages2
-rw-r--r--distro/pkg/deb/knot-resolver.postinst38
-rw-r--r--distro/pkg/deb/knot-resolver.postrm9
-rw-r--r--distro/pkg/deb/knot-resolver.preinst26
-rw-r--r--distro/pkg/deb/knot-resolver.triggers1
-rw-r--r--distro/pkg/deb/not-installed7
-rwxr-xr-xdistro/pkg/deb/rules51
-rw-r--r--distro/pkg/deb/source/format1
-rw-r--r--distro/pkg/nix/default.nix126
-rw-r--r--distro/pkg/nix/top-level.nix12
-rw-r--r--distro/pkg/rpm/knot-resolver.spec384
-rw-r--r--distro/tests/.ansible.cfg8
-rw-r--r--distro/tests/README.md42
-rw-r--r--distro/tests/ansible-roles/knot_resolver/defaults/main.yaml6
-rw-r--r--distro/tests/ansible-roles/knot_resolver/tasks/configure_dnstap.yaml10
-rw-r--r--distro/tests/ansible-roles/knot_resolver/tasks/configure_doh.yaml10
-rw-r--r--distro/tests/ansible-roles/knot_resolver/tasks/configure_doh2.yaml8
-rw-r--r--distro/tests/ansible-roles/knot_resolver/tasks/main.yaml71
-rw-r--r--distro/tests/ansible-roles/knot_resolver/tasks/restart_kresd.yaml16
-rw-r--r--distro/tests/ansible-roles/knot_resolver/tasks/test_dnssec.yaml15
-rw-r--r--distro/tests/ansible-roles/knot_resolver/tasks/test_doh.yaml9
-rw-r--r--distro/tests/ansible-roles/knot_resolver/tasks/test_doh2.yaml24
-rw-r--r--distro/tests/ansible-roles/knot_resolver/tasks/test_kres_cache_gc.yaml4
-rw-r--r--distro/tests/ansible-roles/knot_resolver/tasks/test_tcp.yaml8
-rw-r--r--distro/tests/ansible-roles/knot_resolver/tasks/test_tls.yaml8
-rw-r--r--distro/tests/ansible-roles/knot_resolver/tasks/test_udp.yaml8
-rw-r--r--distro/tests/ansible-roles/knot_resolver/vars/CentOS.yaml6
-rw-r--r--distro/tests/ansible-roles/knot_resolver/vars/Debian.yaml6
-rw-r--r--distro/tests/ansible-roles/knot_resolver/vars/Fedora.yaml6
-rw-r--r--distro/tests/ansible-roles/knot_resolver/vars/Rocky.yaml6
-rw-r--r--distro/tests/ansible-roles/knot_resolver/vars/Ubuntu.yaml6
-rw-r--r--distro/tests/ansible-roles/knot_resolver/vars/openSUSE_Leap.yaml6
-rw-r--r--distro/tests/ansible-roles/knot_resolver/vars/openSUSE_Tumbleweed.yaml7
-rw-r--r--distro/tests/ansible-roles/obs_repos/defaults/main.yaml4
-rw-r--r--distro/tests/ansible-roles/obs_repos/tasks/CentOS.yaml18
-rw-r--r--distro/tests/ansible-roles/obs_repos/tasks/Debian.yaml15
-rw-r--r--distro/tests/ansible-roles/obs_repos/tasks/Fedora.yaml8
-rw-r--r--distro/tests/ansible-roles/obs_repos/tasks/Rocky.yaml13
-rw-r--r--distro/tests/ansible-roles/obs_repos/tasks/Ubuntu.yaml14
-rw-r--r--distro/tests/ansible-roles/obs_repos/tasks/main.yaml12
-rw-r--r--distro/tests/ansible-roles/obs_repos/tasks/openSUSE_Leap.yaml19
-rw-r--r--distro/tests/ansible-roles/obs_repos/tasks/openSUSE_Tumbleweed.yaml13
-rw-r--r--distro/tests/ansible-roles/obs_repos/vars/CentOS.yaml3
-rw-r--r--distro/tests/ansible-roles/obs_repos/vars/Debian_10.yaml3
l---------distro/tests/ansible-roles/obs_repos/vars/Debian_11.yaml1
-rw-r--r--distro/tests/ansible-roles/obs_repos/vars/Debian_9.yaml3
-rw-r--r--distro/tests/ansible-roles/obs_repos/vars/Fedora.yaml3
-rw-r--r--distro/tests/ansible-roles/obs_repos/vars/Rocky.yaml3
-rw-r--r--distro/tests/ansible-roles/obs_repos/vars/Ubuntu.yaml3
-rw-r--r--distro/tests/ansible-roles/obs_repos/vars/openSUSE_Leap.yaml3
-rw-r--r--distro/tests/ansible-roles/obs_repos/vars/openSUSE_Tumbleweed.yaml3
-rw-r--r--distro/tests/centos7/Vagrantfile30
l---------distro/tests/centos7/ansible.cfg1
-rw-r--r--distro/tests/debian10/Vagrantfile28
l---------distro/tests/debian10/ansible.cfg1
-rw-r--r--distro/tests/debian11/Vagrantfile27
l---------distro/tests/debian11/ansible.cfg1
-rw-r--r--distro/tests/debian9/Vagrantfile27
l---------distro/tests/debian9/ansible.cfg1
-rw-r--r--distro/tests/fedora35/Vagrantfile30
l---------distro/tests/fedora35/ansible.cfg1
-rw-r--r--distro/tests/fedora36/Vagrantfile30
l---------distro/tests/fedora36/ansible.cfg1
-rw-r--r--distro/tests/knot-resolver-pkgtest.yaml13
-rw-r--r--distro/tests/leap15/Vagrantfile29
l---------distro/tests/leap15/ansible.cfg1
-rw-r--r--distro/tests/repos.yaml4
-rw-r--r--distro/tests/rocky8/Vagrantfile30
l---------distro/tests/rocky8/ansible.cfg1
-rwxr-xr-xdistro/tests/test-distro.sh26
-rw-r--r--distro/tests/ubuntu1804/Vagrantfile30
l---------distro/tests/ubuntu1804/ansible.cfg1
-rw-r--r--distro/tests/ubuntu2004/Vagrantfile30
l---------distro/tests/ubuntu2004/ansible.cfg1
-rw-r--r--distro/tests/ubuntu2204/Vagrantfile30
l---------distro/tests/ubuntu2204/ansible.cfg1
-rw-r--r--doc/.packaging/centos/7/NOTSUPPORTED0
-rw-r--r--doc/.packaging/centos/8/NOTSUPPORTED0
-rwxr-xr-xdoc/.packaging/debian/10/build.sh19
-rw-r--r--doc/.packaging/debian/10/builddeps4
-rwxr-xr-xdoc/.packaging/debian/10/install.sh3
-rwxr-xr-xdoc/.packaging/debian/9/build.sh19
-rw-r--r--doc/.packaging/debian/9/builddeps4
-rwxr-xr-xdoc/.packaging/debian/9/install.sh3
-rwxr-xr-xdoc/.packaging/fedora/31/build.sh20
-rw-r--r--doc/.packaging/fedora/31/builddeps4
-rwxr-xr-xdoc/.packaging/fedora/31/install.sh3
-rwxr-xr-xdoc/.packaging/fedora/32/30/build.sh20
-rw-r--r--doc/.packaging/fedora/32/30/builddeps4
-rwxr-xr-xdoc/.packaging/fedora/32/30/install.sh3
-rwxr-xr-xdoc/.packaging/fedora/32/build.sh20
-rw-r--r--doc/.packaging/fedora/32/builddeps4
-rwxr-xr-xdoc/.packaging/fedora/32/install.sh3
-rwxr-xr-xdoc/.packaging/leap/15.2/build.sh20
-rw-r--r--doc/.packaging/leap/15.2/builddeps4
-rwxr-xr-xdoc/.packaging/leap/15.2/install.sh3
-rwxr-xr-xdoc/.packaging/test.sh3
-rwxr-xr-xdoc/.packaging/ubuntu/16.04/build.sh19
-rw-r--r--doc/.packaging/ubuntu/16.04/builddeps4
-rwxr-xr-xdoc/.packaging/ubuntu/16.04/install.sh3
-rwxr-xr-xdoc/.packaging/ubuntu/18.04/build.sh19
-rw-r--r--doc/.packaging/ubuntu/18.04/builddeps4
-rwxr-xr-xdoc/.packaging/ubuntu/18.04/install.sh3
-rwxr-xr-xdoc/.packaging/ubuntu/20.04/build.sh19
-rw-r--r--doc/.packaging/ubuntu/20.04/builddeps4
-rwxr-xr-xdoc/.packaging/ubuntu/20.04/install.sh3
-rw-r--r--doc/Doxyfile23
-rw-r--r--doc/NEWS.rst36
-rw-r--r--doc/README.md27
-rw-r--r--doc/_static/.gitignore0
-rw-r--r--doc/_static/css/custom.css6
-rw-r--r--doc/_static/logo-negativ.svg40
-rw-r--r--doc/build.rst291
-rw-r--r--doc/conf.py95
-rw-r--r--doc/config-answer-reordering.rst17
-rw-r--r--doc/config-debugging.rst35
-rw-r--r--doc/config-dnssec.rst17
-rw-r--r--doc/config-experimental.rst14
-rw-r--r--doc/config-logging-header.rst9
-rw-r--r--doc/config-logging-monitoring.rst101
-rw-r--r--doc/config-network-forwarding.rst38
-rw-r--r--doc/config-network.rst64
-rw-r--r--doc/config-no-systemd-privileges.rst65
-rw-r--r--doc/config-no-systemd-processes.rst25
-rw-r--r--doc/config-no-systemd.rst37
-rw-r--r--doc/config-overview.rst98
-rw-r--r--doc/config-performance.rst36
-rw-r--r--doc/config-policy.rst41
l---------doc/daemon-bindings-cache.rst1
l---------doc/daemon-bindings-net_client.rst1
l---------doc/daemon-bindings-net_dns_tweaks.rst1
l---------doc/daemon-bindings-net_server.rst1
l---------doc/daemon-bindings-net_tlssrv.rst1
l---------doc/daemon-bindings-net_xdpsrv.rst1
l---------doc/daemon-bindings-worker.rst1
l---------doc/daemon-scripting.rst1
-rw-r--r--doc/flowcharts/io_and_worker.diabin0 -> 13771 bytes
-rw-r--r--doc/flowcharts/task_ERD.diabin0 -> 2700 bytes
-rw-r--r--doc/flowcharts/tcp_task.diabin0 -> 10812 bytes
-rw-r--r--doc/flowcharts/udp_task.diabin0 -> 4316 bytes
-rw-r--r--doc/index.rst63
-rw-r--r--doc/kresd.8.in122
-rw-r--r--doc/lib.rst70
-rw-r--r--doc/meson.build79
l---------doc/modules-bogus_log.rst1
l---------doc/modules-daf.rst1
l---------doc/modules-detect_time_jump.rst1
l---------doc/modules-detect_time_skew.rst1
l---------doc/modules-dns64.rst1
l---------doc/modules-dnstap.rst1
l---------doc/modules-edns_keepalive.rst1
l---------doc/modules-experimental_dot_auth.rst1
l---------doc/modules-hints.rst1
l---------doc/modules-http-custom-services.rst1
l---------doc/modules-http-trace.rst1
l---------doc/modules-http.rst1
l---------doc/modules-nsid.rst1
l---------doc/modules-policy.rst1
l---------doc/modules-predict.rst1
l---------doc/modules-prefill.rst1
l---------doc/modules-priming.rst1
l---------doc/modules-rebinding.rst1
l---------doc/modules-refuse_nord.rst1
l---------doc/modules-renumber.rst1
l---------doc/modules-rfc7706.rst1
l---------doc/modules-serve_stale.rst1
l---------doc/modules-stats.rst1
l---------doc/modules-ta_sentinel.rst1
l---------doc/modules-ta_signal_query.rst1
l---------doc/modules-view.rst1
l---------doc/modules-watchdog.rst1
-rw-r--r--doc/modules_api.rst6
-rw-r--r--doc/quickstart-config.rst209
-rw-r--r--doc/quickstart-install.rst73
-rw-r--r--doc/quickstart-startup.rst47
-rw-r--r--doc/requirements.txt2
-rw-r--r--doc/resolution.pngbin0 -> 95991 bytes
-rw-r--r--doc/server_terminology.fodg869
-rw-r--r--doc/server_terminology.svg1106
l---------doc/systemd-multiinst.rst1
-rw-r--r--doc/upgrading.rst332
-rw-r--r--doc/worker_api.rst7
-rw-r--r--etc/config/config.cluster36
-rw-r--r--etc/config/config.docker97
-rw-r--r--etc/config/config.internal18
-rw-r--r--etc/config/config.isp64
-rw-r--r--etc/config/config.personal21
-rw-r--r--etc/config/config.privacy36
-rw-r--r--etc/config/config.splitview30
-rw-r--r--etc/config/meson.build35
-rw-r--r--etc/icann-ca.pem82
-rw-r--r--etc/meson.build37
-rw-r--r--etc/root.hints92
-rw-r--r--etc/root.keys1
-rw-r--r--lib/README.rst313
-rw-r--r--lib/cache/README.rst69
-rw-r--r--lib/cache/api.c1029
-rw-r--r--lib/cache/api.h194
-rw-r--r--lib/cache/cdb_api.h97
-rw-r--r--lib/cache/cdb_lmdb.c868
-rw-r--r--lib/cache/cdb_lmdb.h16
-rw-r--r--lib/cache/entry_list.c301
-rw-r--r--lib/cache/entry_pkt.c206
-rw-r--r--lib/cache/entry_rr.c115
-rw-r--r--lib/cache/impl.h439
-rw-r--r--lib/cache/knot_pkt.c94
-rw-r--r--lib/cache/nsec1.c488
-rw-r--r--lib/cache/nsec3.c481
-rw-r--r--lib/cache/overflow.test.integr/deckard.yaml22
-rw-r--r--lib/cache/overflow.test.integr/kresd_config.j291
-rw-r--r--lib/cache/overflow.test.integr/world_cz_vutbr_www.rpl298
-rw-r--r--lib/cache/peek.c774
-rw-r--r--lib/cache/test.integr/cache_minimal_nsec3.rpl4120
-rw-r--r--lib/cache/test.integr/deckard.yaml13
-rw-r--r--lib/cache/test.integr/kresd_config.j269
-rw-r--r--lib/cache/util.h4
-rw-r--r--lib/cookies/alg_containers.c59
-rw-r--r--lib/cookies/alg_containers.h37
-rw-r--r--lib/cookies/alg_sha.c110
-rw-r--r--lib/cookies/alg_sha.h18
-rw-r--r--lib/cookies/control.h37
-rw-r--r--lib/cookies/helper.c268
-rw-r--r--lib/cookies/helper.h74
-rw-r--r--lib/cookies/lru_cache.c58
-rw-r--r--lib/cookies/lru_cache.h57
-rw-r--r--lib/cookies/nonce.c20
-rw-r--r--lib/cookies/nonce.h31
-rw-r--r--lib/defines.h106
-rw-r--r--lib/dnssec.c601
-rw-r--r--lib/dnssec.h191
-rw-r--r--lib/dnssec/nsec.c315
-rw-r--r--lib/dnssec/nsec.h69
-rw-r--r--lib/dnssec/nsec3.c722
-rw-r--r--lib/dnssec/nsec3.h83
-rw-r--r--lib/dnssec/signature.c304
-rw-r--r--lib/dnssec/signature.h29
-rw-r--r--lib/dnssec/ta.c154
-rw-r--r--lib/dnssec/ta.h61
-rw-r--r--lib/generic/README.rst48
-rw-r--r--lib/generic/array.h157
-rw-r--r--lib/generic/lru.c249
-rw-r--r--lib/generic/lru.h240
-rw-r--r--lib/generic/pack.h221
-rw-r--r--lib/generic/queue.c140
-rw-r--r--lib/generic/queue.h230
-rw-r--r--lib/generic/test_array.c99
-rw-r--r--lib/generic/test_lru.c111
-rw-r--r--lib/generic/test_pack.c68
-rw-r--r--lib/generic/test_queue.c71
-rw-r--r--lib/generic/test_trie.c154
-rw-r--r--lib/generic/trie.c923
-rw-r--r--lib/generic/trie.h150
-rw-r--r--lib/generic/trie.spdx10
-rw-r--r--lib/layer.h107
-rw-r--r--lib/layer/cache.c20
-rw-r--r--lib/layer/iterate.c1235
-rw-r--r--lib/layer/iterate.h25
-rw-r--r--lib/layer/mode.rst26
-rw-r--r--lib/layer/test.integr/deckard.yaml13
-rw-r--r--lib/layer/test.integr/iter_cname_length.rpl226
-rw-r--r--lib/layer/test.integr/iter_limit_bad_glueless.rpl220
-rw-r--r--lib/layer/test.integr/iter_limit_refuse.rpl150
-rw-r--r--lib/layer/test.integr/kresd_config.j2107
-rw-r--r--lib/layer/validate.c1366
-rw-r--r--lib/layer/validate.test.integr/deckard.yaml10
-rw-r--r--lib/layer/validate.test.integr/fwd_insecure_but_rrsig_signer_invalid.rpl294
-rw-r--r--lib/layer/validate.test.integr/kresd_config.j252
-rw-r--r--lib/log.c328
-rw-r--r--lib/log.h278
-rw-r--r--lib/meson.build121
-rw-r--r--lib/module.c148
-rw-r--r--lib/module.h112
-rw-r--r--lib/resolve.c1695
-rw-r--r--lib/resolve.h420
-rw-r--r--lib/rplan.c291
-rw-r--r--lib/rplan.h221
-rw-r--r--lib/selection.c795
-rw-r--r--lib/selection.h269
-rw-r--r--lib/selection_forward.c136
-rw-r--r--lib/selection_forward.h17
-rw-r--r--lib/selection_iter.c378
-rw-r--r--lib/selection_iter.h14
-rw-r--r--lib/test_module.c39
-rw-r--r--lib/test_rplan.c75
-rw-r--r--lib/test_utils.c147
-rw-r--r--lib/test_zonecut.c58
-rw-r--r--lib/utils.c1393
-rw-r--r--lib/utils.h608
-rw-r--r--lib/zonecut.c590
-rw-r--r--lib/zonecut.h164
-rw-r--r--meson.build357
-rw-r--r--meson_options.txt219
-rw-r--r--modules/README.rst251
-rw-r--r--modules/bogus_log/.packaging/test.config4
-rw-r--r--modules/bogus_log/README.rst45
-rw-r--r--modules/bogus_log/bogus_log.c135
-rw-r--r--modules/bogus_log/meson.build21
-rw-r--r--modules/bogus_log/test.integr/deckard.yaml13
-rw-r--r--modules/bogus_log/test.integr/kresd_config.j290
-rw-r--r--modules/bogus_log/test.integr/val_minimal_expiredsignature.rpl125
-rw-r--r--modules/cookies/README.rst56
-rw-r--r--modules/cookies/cookiectl.c689
-rw-r--r--modules/cookies/cookiectl.h35
-rw-r--r--modules/cookies/cookiemonster.c464
-rw-r--r--modules/cookies/cookiemonster.h15
-rw-r--r--modules/cookies/cookies.c78
-rw-r--r--modules/daf/.packaging/test.config4
-rw-r--r--modules/daf/README.rst146
-rw-r--r--modules/daf/daf.js295
-rw-r--r--modules/daf/daf.lua392
-rw-r--r--modules/daf/daf.test.lua80
-rw-r--r--modules/daf/daf_http.test.lua216
-rw-r--r--modules/daf/meson.build21
-rw-r--r--modules/daf/test.integr/deckard.yaml12
-rw-r--r--modules/daf/test.integr/kresd_config.j265
-rw-r--r--modules/daf/test.integr/module_daf.rpl30
-rw-r--r--modules/detect_time_jump/.packaging/test.config4
-rw-r--r--modules/detect_time_jump/README.rst22
-rw-r--r--modules/detect_time_jump/detect_time_jump.lua45
-rw-r--r--modules/detect_time_skew/.packaging/test.config4
-rw-r--r--modules/detect_time_skew/README.rst23
-rw-r--r--modules/detect_time_skew/detect_time_skew.lua83
-rw-r--r--modules/dns64/.packaging/test.config4
-rw-r--r--modules/dns64/README.rst62
-rw-r--r--modules/dns64/dns64.lua220
-rw-r--r--modules/dns64/dns64.test.lua53
-rw-r--r--modules/dnstap/.packaging/centos/7/builddeps3
-rw-r--r--modules/dnstap/.packaging/centos/7/rundeps2
-rw-r--r--modules/dnstap/.packaging/centos/8/builddeps3
-rw-r--r--modules/dnstap/.packaging/centos/8/rundeps2
-rw-r--r--modules/dnstap/.packaging/debian/10/builddeps3
-rw-r--r--modules/dnstap/.packaging/debian/10/rundeps2
-rw-r--r--modules/dnstap/.packaging/debian/9/builddeps3
-rw-r--r--modules/dnstap/.packaging/debian/9/rundeps2
-rw-r--r--modules/dnstap/.packaging/fedora/31/builddeps3
-rw-r--r--modules/dnstap/.packaging/fedora/31/rundeps2
-rw-r--r--modules/dnstap/.packaging/fedora/32/builddeps3
-rw-r--r--modules/dnstap/.packaging/fedora/32/rundeps2
-rw-r--r--modules/dnstap/.packaging/leap/15.2/builddeps3
-rw-r--r--modules/dnstap/.packaging/leap/15.2/rundeps2
-rw-r--r--modules/dnstap/.packaging/test.config4
-rw-r--r--modules/dnstap/.packaging/ubuntu/16.04/builddeps3
-rw-r--r--modules/dnstap/.packaging/ubuntu/16.04/rundeps2
-rw-r--r--modules/dnstap/.packaging/ubuntu/18.04/builddeps3
-rw-r--r--modules/dnstap/.packaging/ubuntu/18.04/rundeps2
-rw-r--r--modules/dnstap/.packaging/ubuntu/20.04/builddeps3
-rw-r--r--modules/dnstap/.packaging/ubuntu/20.04/rundeps2
-rw-r--r--modules/dnstap/README.rst42
-rw-r--r--modules/dnstap/dnstap.c524
-rw-r--r--modules/dnstap/dnstap.proto273
-rw-r--r--modules/dnstap/meson.build57
-rw-r--r--modules/edns_keepalive/.packaging/test.config10
-rw-r--r--modules/edns_keepalive/README.rst22
-rw-r--r--modules/edns_keepalive/edns_keepalive.c61
-rw-r--r--modules/edns_keepalive/meson.build17
-rwxr-xr-xmodules/etcd/.packaging/centos/7/pre-test.sh1
-rw-r--r--modules/etcd/.packaging/centos/7/rundeps6
-rw-r--r--modules/etcd/.packaging/centos/8/NOTSUPPORTED0
-rwxr-xr-xmodules/etcd/.packaging/debian/10/pre-test.sh1
-rw-r--r--modules/etcd/.packaging/debian/10/rundeps4
-rwxr-xr-xmodules/etcd/.packaging/debian/9/pre-test.sh1
-rw-r--r--modules/etcd/.packaging/debian/9/rundeps4
-rw-r--r--modules/etcd/.packaging/fedora/31/NOTSUPPORTED16
-rw-r--r--modules/etcd/.packaging/fedora/32/NOTSUPPORTED16
-rwxr-xr-xmodules/etcd/.packaging/leap/15.2/pre-test.sh1
-rw-r--r--modules/etcd/.packaging/leap/15.2/rundeps6
-rw-r--r--modules/etcd/.packaging/test.config4
-rwxr-xr-xmodules/etcd/.packaging/ubuntu/16.04/pre-test.sh1
-rw-r--r--modules/etcd/.packaging/ubuntu/16.04/rundeps3
-rwxr-xr-xmodules/etcd/.packaging/ubuntu/18.04/pre-test.sh1
-rw-r--r--modules/etcd/.packaging/ubuntu/18.04/rundeps3
-rwxr-xr-xmodules/etcd/.packaging/ubuntu/20.04/pre-test.sh1
-rw-r--r--modules/etcd/.packaging/ubuntu/20.04/rundeps4
-rw-r--r--modules/etcd/README.rst46
-rw-r--r--modules/etcd/etcd.lua56
-rw-r--r--modules/experimental_dot_auth/.packaging/centos/7/rundeps1
-rw-r--r--modules/experimental_dot_auth/.packaging/centos/8/rundeps1
-rw-r--r--modules/experimental_dot_auth/.packaging/debian/10/rundeps1
-rw-r--r--modules/experimental_dot_auth/.packaging/debian/9/rundeps1
-rw-r--r--modules/experimental_dot_auth/.packaging/fedora/31/rundeps1
-rw-r--r--modules/experimental_dot_auth/.packaging/fedora/32/rundeps1
-rw-r--r--modules/experimental_dot_auth/.packaging/leap/15.2/NOTSUPPORTED6
-rwxr-xr-xmodules/experimental_dot_auth/.packaging/leap/15.2/pre-test.sh1
-rw-r--r--modules/experimental_dot_auth/.packaging/leap/15.2/rundeps4
-rw-r--r--modules/experimental_dot_auth/.packaging/test.config4
-rw-r--r--modules/experimental_dot_auth/.packaging/ubuntu/16.04/NOTSUPPORTED0
-rw-r--r--modules/experimental_dot_auth/.packaging/ubuntu/18.04/rundeps1
-rw-r--r--modules/experimental_dot_auth/.packaging/ubuntu/20.04/rundeps1
-rw-r--r--modules/experimental_dot_auth/README.rst91
-rw-r--r--modules/experimental_dot_auth/experimental_dot_auth.lua122
-rw-r--r--modules/experimental_dot_auth/meson.build13
-rw-r--r--modules/extended_error/extended_error.c47
-rw-r--r--modules/extended_error/meson.build20
-rw-r--r--modules/graphite/.packaging/centos/7/rundeps1
-rw-r--r--modules/graphite/.packaging/centos/8/rundeps1
-rw-r--r--modules/graphite/.packaging/debian/10/rundeps1
-rw-r--r--modules/graphite/.packaging/debian/9/rundeps1
-rw-r--r--modules/graphite/.packaging/fedora/31/rundeps1
-rw-r--r--modules/graphite/.packaging/fedora/32/rundeps1
-rw-r--r--modules/graphite/.packaging/leap/15.2/NOTSUPPORTED6
-rwxr-xr-xmodules/graphite/.packaging/leap/15.2/pre-test.sh1
-rw-r--r--modules/graphite/.packaging/leap/15.2/rundeps6
-rw-r--r--modules/graphite/.packaging/test.config4
-rw-r--r--modules/graphite/.packaging/ubuntu/16.04/rundeps1
-rw-r--r--modules/graphite/.packaging/ubuntu/18.04/rundeps1
-rw-r--r--modules/graphite/.packaging/ubuntu/20.04/rundeps1
-rw-r--r--modules/graphite/README.rst49
-rw-r--r--modules/graphite/graphite.lua146
-rw-r--r--modules/hints/.packaging/test.config4
-rw-r--r--modules/hints/README.rst145
-rw-r--r--modules/hints/hints.c677
-rw-r--r--modules/hints/meson.build24
-rw-r--r--modules/hints/tests/hints.test.hosts1
-rw-r--r--modules/hints/tests/hints.test.lua64
-rw-r--r--modules/hints/tests/hints_test.zone2
-rw-r--r--modules/http/.packaging/centos/7/rundeps1
-rw-r--r--modules/http/.packaging/centos/8/rundeps1
-rw-r--r--modules/http/.packaging/debian/10/rundeps1
-rw-r--r--modules/http/.packaging/debian/9/rundeps1
-rw-r--r--modules/http/.packaging/fedora/31/rundeps1
-rw-r--r--modules/http/.packaging/fedora/32/rundeps1
-rw-r--r--modules/http/.packaging/leap/15.2/NOTSUPPORTED5
-rwxr-xr-xmodules/http/.packaging/leap/15.2/pre-test.sh1
-rw-r--r--modules/http/.packaging/leap/15.2/rundeps7
-rw-r--r--modules/http/.packaging/test.config4
-rw-r--r--modules/http/.packaging/ubuntu/16.04/NOTSUPPORTED0
-rw-r--r--modules/http/.packaging/ubuntu/18.04/rundeps1
-rw-r--r--modules/http/.packaging/ubuntu/20.04/rundeps1
-rw-r--r--modules/http/README.rst188
-rw-r--r--modules/http/custom_services.rst145
-rw-r--r--modules/http/debug_opensslkeylog.c369
-rw-r--r--modules/http/http.lua.in418
-rw-r--r--modules/http/http.test.lua128
-rw-r--r--modules/http/http_doh.lua116
-rw-r--r--modules/http/http_doh.test.lua419
-rw-r--r--modules/http/http_tls_cert.lua186
-rw-r--r--modules/http/http_trace.lua77
-rw-r--r--modules/http/meson.build61
-rw-r--r--modules/http/prometheus.lua178
-rw-r--r--modules/http/prometheus.rst45
-rw-r--r--modules/http/static/bootstrap-theme.min.css6
-rw-r--r--modules/http/static/bootstrap-theme.min.css.spdx11
-rw-r--r--modules/http/static/bootstrap.min.css11
-rw-r--r--modules/http/static/bootstrap.min.css.spdx11
-rw-r--r--modules/http/static/bootstrap.min.js7
-rw-r--r--modules/http/static/bootstrap.min.js.spdx11
-rw-r--r--modules/http/static/d3.js6
-rw-r--r--modules/http/static/d3.spdx12
-rw-r--r--modules/http/static/datamaps.world.min.js3
-rw-r--r--modules/http/static/datamaps.world.min.spdx11
-rw-r--r--modules/http/static/dygraph.min.js7
-rw-r--r--modules/http/static/dygraph.min.js.spdx12
-rw-r--r--modules/http/static/epoch.css2
-rw-r--r--modules/http/static/epoch.js4
-rw-r--r--modules/http/static/epoch.spdx11
-rw-r--r--modules/http/static/favicon.icobin0 -> 1545 bytes
-rw-r--r--modules/http/static/glyphicons-halflings-regular.spdx11
-rw-r--r--modules/http/static/glyphicons-halflings-regular.woff2bin0 -> 18028 bytes
-rw-r--r--modules/http/static/jquery.js5
-rw-r--r--modules/http/static/jquery.spdx12
-rw-r--r--modules/http/static/kresd.css44
-rw-r--r--modules/http/static/kresd.js367
-rw-r--r--modules/http/static/main.tpl87
-rw-r--r--modules/http/static/selectize.bootstrap3.css418
-rw-r--r--modules/http/static/selectize.min.js4
-rw-r--r--modules/http/static/selectize.spdx11
-rw-r--r--modules/http/static/topojson.js2
-rw-r--r--modules/http/static/topojson.spdx12
-rw-r--r--modules/http/test_tls/broken.crt3
-rw-r--r--modules/http/test_tls/broken.keybin0 -> 512 bytes
-rw-r--r--modules/http/test_tls/ca.crt20
-rw-r--r--modules/http/test_tls/chain.crt41
-rw-r--r--modules/http/test_tls/test.crt20
-rw-r--r--modules/http/test_tls/test.key27
-rw-r--r--modules/http/test_tls/tls.test.lua193
-rw-r--r--modules/http/trace.rst43
-rw-r--r--modules/meson.build59
-rw-r--r--modules/nsid/.packaging/test.config4
-rw-r--r--modules/nsid/README.rst35
-rw-r--r--modules/nsid/meson.build24
-rw-r--r--modules/nsid/nsid.c114
-rw-r--r--modules/nsid/nsid.test.lua22
-rw-r--r--modules/policy/.packaging/test.config4
-rw-r--r--modules/policy/README.rst774
-rw-r--r--modules/policy/lua-aho-corasick/LICENSE28
-rw-r--r--modules/policy/lua-aho-corasick/Makefile134
-rw-r--r--modules/policy/lua-aho-corasick/README.md40
-rw-r--r--modules/policy/lua-aho-corasick/ac.cxx101
-rw-r--r--modules/policy/lua-aho-corasick/ac.h49
-rw-r--r--modules/policy/lua-aho-corasick/ac_fast.cxx468
-rw-r--r--modules/policy/lua-aho-corasick/ac_fast.hpp124
-rw-r--r--modules/policy/lua-aho-corasick/ac_lua.cxx173
-rw-r--r--modules/policy/lua-aho-corasick/ac_slow.cxx318
-rw-r--r--modules/policy/lua-aho-corasick/ac_slow.hpp158
-rw-r--r--modules/policy/lua-aho-corasick/ac_util.hpp69
-rw-r--r--modules/policy/lua-aho-corasick/load_ac.lua90
-rw-r--r--modules/policy/lua-aho-corasick/mytest.cxx200
-rw-r--r--modules/policy/lua-aho-corasick/tests/Makefile65
-rw-r--r--modules/policy/lua-aho-corasick/tests/ac_bench.cxx519
-rw-r--r--modules/policy/lua-aho-corasick/tests/ac_test_aggr.cxx135
-rw-r--r--modules/policy/lua-aho-corasick/tests/ac_test_simple.cxx275
-rw-r--r--modules/policy/lua-aho-corasick/tests/dict/README.txt1
-rw-r--r--modules/policy/lua-aho-corasick/tests/dict/dict1.txt11
-rw-r--r--modules/policy/lua-aho-corasick/tests/load_ac_test.lua82
-rw-r--r--modules/policy/lua-aho-corasick/tests/lua_test.lua67
-rw-r--r--modules/policy/lua-aho-corasick/tests/test_base.hpp60
-rw-r--r--modules/policy/lua-aho-corasick/tests/test_bigfile.cxx167
-rw-r--r--modules/policy/lua-aho-corasick/tests/test_main.cxx33
-rw-r--r--modules/policy/meson.build50
-rw-r--r--modules/policy/noipv6.test.integr/broken-ipv6.rpl47
-rw-r--r--modules/policy/noipv6.test.integr/deckard.yaml12
-rw-r--r--modules/policy/noipv6.test.integr/kresd_config.j259
-rw-r--r--modules/policy/noipvx.test.integr/broken-ipvx.rpl35
-rw-r--r--modules/policy/noipvx.test.integr/deckard.yaml12
-rw-r--r--modules/policy/noipvx.test.integr/kresd_config.j260
-rw-r--r--modules/policy/policy.lua1109
-rw-r--r--modules/policy/policy.rpz.test.lua65
-rw-r--r--modules/policy/policy.slice.test.lua109
-rw-r--r--modules/policy/policy.test.lua145
-rw-r--r--modules/policy/policy.test.rpz18
-rw-r--r--modules/policy/policy.test.rpz.soa5
-rw-r--r--modules/policy/test.integr/deckard.yaml12
-rw-r--r--modules/policy/test.integr/kresd_config.j259
-rw-r--r--modules/policy/test.integr/refuse.rpl44
-rw-r--r--modules/predict/.packaging/test.config4
-rw-r--r--modules/predict/README.rst67
-rw-r--r--modules/predict/predict.lua189
-rw-r--r--modules/predict/predict.test.lua61
-rw-r--r--modules/prefill/.packaging/test.config4
-rw-r--r--modules/prefill/README.rst43
-rw-r--r--modules/prefill/prefill.lua199
-rw-r--r--modules/prefill/prefill.test/empty.zone0
-rw-r--r--modules/prefill/prefill.test/example.com.zone12
-rw-r--r--modules/prefill/prefill.test/prefill.test.lua123
-rw-r--r--modules/prefill/prefill.test/random.zone2
-rw-r--r--modules/prefill/prefill.test/testroot.zone59
-rw-r--r--modules/prefill/prefill.test/testroot.zone.unsigned4
-rw-r--r--modules/prefill/prefill.test/testroot_no_soa.zone52
-rw-r--r--modules/priming/.packaging/test.config4
-rw-r--r--modules/priming/README.rst18
-rw-r--r--modules/priming/priming.lua130
-rw-r--r--modules/rebinding/.packaging/test.config4
-rw-r--r--modules/rebinding/README.rst29
-rw-r--r--modules/rebinding/rebinding.lua115
-rw-r--r--modules/rebinding/test.integr/deckard.yaml12
-rw-r--r--modules/rebinding/test.integr/kresd_config.j259
-rw-r--r--modules/rebinding/test.integr/module_rebinding.rpl834
-rw-r--r--modules/refuse_nord/.packaging/test.config3
-rw-r--r--modules/refuse_nord/README.rst16
-rw-r--r--modules/refuse_nord/meson.build21
-rw-r--r--modules/refuse_nord/refuse_nord.c38
-rw-r--r--modules/refuse_nord/test.integr/deckard.yaml12
-rw-r--r--modules/refuse_nord/test.integr/kresd_config.j256
-rw-r--r--modules/refuse_nord/test.integr/refuse_nord.rpl24
-rw-r--r--modules/renumber/.packaging/test.config4
-rw-r--r--modules/renumber/README.rst36
-rw-r--r--modules/renumber/renumber.lua181
-rw-r--r--modules/renumber/renumber.test.lua103
-rw-r--r--modules/rfc7706.rst12
-rw-r--r--modules/serve_stale/.packaging/test.config4
-rw-r--r--modules/serve_stale/README.rst23
-rw-r--r--modules/serve_stale/serve_stale.lua42
-rw-r--r--modules/serve_stale/test.integr/deckard.yaml12
-rw-r--r--modules/serve_stale/test.integr/kresd_config.j270
-rw-r--r--modules/serve_stale/test.integr/module_serve_stale.rpl280
-rw-r--r--modules/stats/.packaging/test.config4
-rw-r--r--modules/stats/README.rst211
-rw-r--r--modules/stats/meson.build25
-rw-r--r--modules/stats/stats.c534
-rw-r--r--modules/stats/test.integr/deckard.yaml12
-rw-r--r--modules/stats/test.integr/kresd_config.j2114
-rw-r--r--modules/stats/test.integr/stats.rpl194
-rw-r--r--modules/ta_sentinel/.packaging/test.config4
-rw-r--r--modules/ta_sentinel/README.rst18
-rw-r--r--modules/ta_sentinel/ta_sentinel.lua80
-rw-r--r--modules/ta_signal_query/.packaging/test.config4
-rw-r--r--modules/ta_signal_query/README.rst31
-rw-r--r--modules/ta_signal_query/ta_signal_query.lua64
-rw-r--r--modules/ta_update/.packaging/test.config4
-rw-r--r--modules/ta_update/meson.build21
-rw-r--r--modules/ta_update/root.keys1
-rw-r--r--modules/ta_update/ta_update.lua349
-rw-r--r--modules/ta_update/ta_update.test.integr/deckard.yaml12
-rw-r--r--modules/ta_update/ta_update.test.integr/kresd_config.j256
-rw-r--r--modules/ta_update/ta_update.test.integr/rfc5011-monotonictime.rpl5755
-rw-r--r--modules/ta_update/ta_update.test.integr/rfc5011/README13
-rwxr-xr-xmodules/ta_update/ta_update.test.integr/rfc5011/dns2rpl.py222
-rw-r--r--modules/ta_update/ta_update.test.integr/rfc5011/empty.rpl20
-rwxr-xr-xmodules/ta_update/ta_update.test.integr/rfc5011/genkeyszones.sh174
-rw-r--r--modules/ta_update/ta_update.test.integr/rfc5011/knot.root.conf26
l---------modules/ta_update/ta_update.test.integr/rfc5011/pydnstest1
-rw-r--r--modules/ta_update/ta_update.test.integr/rfc5011/unsigned_check.db8
-rw-r--r--modules/ta_update/ta_update.test.integr/rfc5011/unsigned_ok.db8
-rw-r--r--modules/ta_update/ta_update.test.integr/rfc5011_unsupported_key_rollover.rpl91
-rw-r--r--modules/ta_update/ta_update.test.lua84
-rw-r--r--modules/ta_update/ta_update.unmanagedkey.test.integr/deckard.yaml12
-rw-r--r--modules/ta_update/ta_update.unmanagedkey.test.integr/kresd_config.j272
l---------modules/ta_update/ta_update.unmanagedkey.test.integr/rfc50111
-rw-r--r--modules/ta_update/ta_update.unmanagedkey.test.integr/unmanagedkey-missing-monotonictime.rpl758
-rw-r--r--modules/ta_update/ta_update.unmanagedkey.test.integr/unmanagedkey-present-monotonictime.rpl757
-rw-r--r--modules/ta_update/ta_update.unmanagedkey.test.integr/unmanagedkey-revoke-monotonictime.rpl762
-rw-r--r--modules/view/.packaging/test.config4
-rw-r--r--modules/view/README.rst92
-rw-r--r--modules/view/addr.test.integr/deckard.yaml12
-rw-r--r--modules/view/addr.test.integr/kresd_config.j262
-rw-r--r--modules/view/addr.test.integr/module_view_addr.rpl79
-rw-r--r--modules/view/meson.build11
-rw-r--r--modules/view/tsig.test.integr/deckard.yaml12
-rw-r--r--modules/view/tsig.test.integr/kresd_config.j264
-rw-r--r--modules/view/tsig.test.integr/module_view_tsig.rpl114
-rw-r--r--modules/view/view.lua121
-rw-r--r--modules/watchdog/.packaging/test.config4
-rw-r--r--modules/watchdog/README.rst43
-rw-r--r--modules/watchdog/watchdog.lua129
-rw-r--r--modules/workarounds/.packaging/test.config4
-rw-r--r--modules/workarounds/README.rst11
-rw-r--r--modules/workarounds/workarounds.lua23
-rwxr-xr-xscripts/bench.sh12
-rwxr-xr-xscripts/bugreport-journals.py194
-rwxr-xr-xscripts/build-in-obs.sh32
-rwxr-xr-xscripts/coverage_c_combine.sh26
-rwxr-xr-xscripts/coverage_env.sh42
-rwxr-xr-xscripts/doh_b64encode_query.py26
-rwxr-xr-xscripts/gen-cdefs.sh82
-rwxr-xr-xscripts/gen-pgp-keyblock.sh38
-rwxr-xr-xscripts/get-date.sh14
-rwxr-xr-xscripts/kresd-host.lua115
-rwxr-xr-xscripts/kresd-query.lua63
-rw-r--r--scripts/kresd.apparmor29
-rwxr-xr-xscripts/luacov_gen_empty.sh18
-rwxr-xr-xscripts/luacov_to_info.lua57
-rwxr-xr-xscripts/make-archive.sh38
-rwxr-xr-xscripts/make-doc.sh42
-rwxr-xr-xscripts/make-obs.sh59
-rwxr-xr-xscripts/map_install_src.lua168
-rwxr-xr-xscripts/run-pylint.sh12
-rwxr-xr-xscripts/run-scanbuild-with-args.sh51
-rwxr-xr-xscripts/test-config.sh32
-rwxr-xr-xscripts/test-integration-prepare.sh8
-rwxr-xr-xscripts/update-authors.sh41
-rwxr-xr-xscripts/update-root-hints.sh28
-rw-r--r--security.txt9
-rw-r--r--systemd/README.rst11
-rw-r--r--systemd/kres-cache-gc.service.in19
-rw-r--r--systemd/kresd.systemd.7.in100
-rw-r--r--systemd/kresd.target9
-rw-r--r--systemd/kresd@.service.in30
-rw-r--r--systemd/meson.build66
-rw-r--r--systemd/multiinst.rst99
-rw-r--r--systemd/sysusers.d/knot-resolver.conf.in5
-rw-r--r--systemd/tmpfiles.d/knot-resolver.conf.in6
-rw-r--r--tests/.gitignore6
-rw-r--r--tests/README.rst94
-rw-r--r--tests/config/basic.test.lua211
-rw-r--r--tests/config/cache.test.lua67
-rw-r--r--tests/config/doh2.test.lua524
-rw-r--r--tests/config/lru.test.lua84
-rw-r--r--tests/config/meson.build41
-rw-r--r--tests/config/net.test.lua67
-rw-r--r--tests/config/tapered/.travis.yml40
-rw-r--r--tests/config/tapered/.travis/platform.sh15
-rw-r--r--tests/config/tapered/.travis/setenv_lua.sh3
-rw-r--r--tests/config/tapered/.travis/setup_lua.sh122
-rw-r--r--tests/config/tapered/CHANGES.md70
-rw-r--r--tests/config/tapered/LICENSE.md27
-rw-r--r--tests/config/tapered/README.md116
-rw-r--r--tests/config/tapered/doc/changes.html104
-rw-r--r--tests/config/tapered/doc/index.html111
-rw-r--r--tests/config/tapered/doc/license.html40
-rw-r--r--tests/config/tapered/doc/normalize.css439
-rw-r--r--tests/config/tapered/doc/screen.css109
-rwxr-xr-xtests/config/tapered/make-doc.bash55
-rw-r--r--tests/config/tapered/src/tapered.lua205
-rw-r--r--tests/config/tapered/tapered-1.1-0.rockspec21
-rw-r--r--tests/config/tapered/tapered-1.2.0-1.rockspec21
-rw-r--r--tests/config/tapered/tapered-1.2.1-1.rockspec21
-rw-r--r--tests/config/tapered/tapered-2.0.0-1.rockspec21
-rw-r--r--tests/config/tapered/tapered-2.0.1-1.rockspec21
-rw-r--r--tests/config/tapered/tapered-2.1.0-1.rockspec21
-rw-r--r--tests/config/tapered/tapered-2.2.0-1.rockspec22
-rw-r--r--tests/config/tapered/tapered-2.3.0-1.rockspec22
-rw-r--r--tests/config/tapered/test/.luacov55
-rw-r--r--tests/config/tapered/test/boom-result.txt7
-rwxr-xr-xtests/config/tapered/test/boom-test.lua19
-rw-r--r--tests/config/tapered/test/done-failure-result.txt2
-rw-r--r--tests/config/tapered/test/done-failure-test.lua5
-rw-r--r--tests/config/tapered/test/done-success-result.txt2
-rw-r--r--tests/config/tapered/test/done-success-test.lua5
-rw-r--r--tests/config/tapered/test/dynamic-setup-teardown-result.txt10
-rwxr-xr-xtests/config/tapered/test/dynamic-setup-teardown-test.lua27
-rwxr-xr-xtests/config/tapered/test/exit-failure-test.lua6
-rwxr-xr-xtests/config/tapered/test/exit-success-test.lua6
-rw-r--r--tests/config/tapered/test/informational-fields-result.txt4
-rwxr-xr-xtests/config/tapered/test/informational-fields-test.lua8
-rw-r--r--tests/config/tapered/test/is-isnt-result.txt43
-rwxr-xr-xtests/config/tapered/test/is-isnt-test.lua36
-rw-r--r--tests/config/tapered/test/like-unlike-result.txt13
-rwxr-xr-xtests/config/tapered/test/like-unlike-test.lua16
-rw-r--r--tests/config/tapered/test/ok-nok-result.txt7
-rwxr-xr-xtests/config/tapered/test/ok-nok-test.lua11
-rw-r--r--tests/config/tapered/test/pass-fail-result.txt4
-rwxr-xr-xtests/config/tapered/test/pass-fail-test.lua11
-rw-r--r--tests/config/tapered/test/result_test03.txt55
-rwxr-xr-xtests/config/tapered/test/runner.bash71
-rw-r--r--tests/config/tapered/test/same-result.txt31
-rw-r--r--tests/config/tapered/test/same-test.lua74
-rw-r--r--tests/config/tapered/test/setup-teardown-result.txt4
-rwxr-xr-xtests/config/tapered/test/setup-teardown-test.lua14
-rw-r--r--tests/config/test.cfg46
-rw-r--r--tests/config/test_dns_generators.lua134
-rw-r--r--tests/config/test_utils.lua121
-rw-r--r--tests/config/tls.test.lua29
-rw-r--r--tests/config/worker.test.lua65
-rw-r--r--tests/dnstap/meson.build11
-rw-r--r--tests/dnstap/src/dnstap-test/config14
-rw-r--r--tests/dnstap/src/dnstap-test/main.go247
-rwxr-xr-xtests/dnstap/src/dnstap-test/run.sh31
-rw-r--r--tests/dnstap/src/dnstap-test/vendor/manifest55
-rw-r--r--tests/integration/deckard/LICENSE23
-rw-r--r--tests/integration/deckard/README.rst95
-rw-r--r--tests/integration/deckard/ci/README.rst4
-rw-r--r--tests/integration/deckard/ci/__init__.py0
-rw-r--r--tests/integration/deckard/ci/common.sh17
-rwxr-xr-xtests/integration/deckard/ci/compare-rplint.sh31
-rwxr-xr-xtests/integration/deckard/ci/compare-tests.sh30
-rwxr-xr-xtests/integration/deckard/ci/junit-compare.py38
-rwxr-xr-xtests/integration/deckard/ci/mypy-run.sh17
-rwxr-xr-xtests/integration/deckard/ci/pylint-run.sh12
-rwxr-xr-xtests/integration/deckard/ci/raw_id.py20
-rwxr-xr-xtests/integration/deckard/ci/raw_id_check.sh7
-rwxr-xr-xtests/integration/deckard/ci/runlocally.sh41
-rw-r--r--tests/integration/deckard/configs/getdns.yaml12
-rw-r--r--tests/integration/deckard/configs/knotd_master.yaml10
-rw-r--r--tests/integration/deckard/configs/knotd_slave.yaml10
-rw-r--r--tests/integration/deckard/configs/kresd.yaml9
-rw-r--r--tests/integration/deckard/configs/named.yaml15
-rw-r--r--tests/integration/deckard/configs/pdns.yaml15
-rw-r--r--tests/integration/deckard/configs/unbound.yaml13
-rw-r--r--tests/integration/deckard/conftest.py126
-rw-r--r--tests/integration/deckard/contrib/__init__.py0
-rw-r--r--tests/integration/deckard/contrib/deckard.vim26
-rw-r--r--tests/integration/deckard/contrib/licenses/ISC15
-rw-r--r--tests/integration/deckard/contrib/namespaces.py125
-rw-r--r--tests/integration/deckard/contrib/namespaces.spdx10
-rwxr-xr-xtests/integration/deckard/deckard.py253
-rw-r--r--tests/integration/deckard/deckard_pytest.ini8
-rwxr-xr-xtests/integration/deckard/deckard_pytest.py167
-rw-r--r--tests/integration/deckard/doc/devel_guide.rst6
-rw-r--r--tests/integration/deckard/doc/scenario_example.rst337
-rw-r--r--tests/integration/deckard/doc/scenario_guide.rst431
-rw-r--r--tests/integration/deckard/doc/user_guide.rst286
-rwxr-xr-xtests/integration/deckard/getdns_run.sh63
-rwxr-xr-xtests/integration/deckard/knotd_master_run.sh6
-rwxr-xr-xtests/integration/deckard/knotd_slave_run.sh6
-rwxr-xr-xtests/integration/deckard/kresd_run.sh5
-rw-r--r--tests/integration/deckard/mypy.ini3
-rwxr-xr-xtests/integration/deckard/named_run.sh11
-rw-r--r--tests/integration/deckard/networking.py93
-rwxr-xr-xtests/integration/deckard/pdns_run.sh5
-rw-r--r--tests/integration/deckard/pydnstest/__init__.py0
-rw-r--r--tests/integration/deckard/pydnstest/augwrap.py226
-rw-r--r--tests/integration/deckard/pydnstest/deckard.aug94
-rw-r--r--tests/integration/deckard/pydnstest/empty.rpl20
-rw-r--r--tests/integration/deckard/pydnstest/matchpart.py238
-rw-r--r--tests/integration/deckard/pydnstest/mock_client.py136
-rw-r--r--tests/integration/deckard/pydnstest/scenario.py888
-rw-r--r--tests/integration/deckard/pydnstest/tests/__init__.py0
-rw-r--r--tests/integration/deckard/pydnstest/tests/test_parse_config.py17
-rw-r--r--tests/integration/deckard/pydnstest/tests/test_scenario.py55
-rw-r--r--tests/integration/deckard/pydnstest/testserver.py309
-rw-r--r--tests/integration/deckard/pylintrc27
-rw-r--r--tests/integration/deckard/requirements.txt9
-rwxr-xr-xtests/integration/deckard/rplint.py352
-rwxr-xr-xtests/integration/deckard/rplint.sh5
-rw-r--r--tests/integration/deckard/rplint_pytest.ini4
-rwxr-xr-xtests/integration/deckard/run.sh18
-rw-r--r--tests/integration/deckard/sets/knotd/master/example.com.zone22
-rw-r--r--tests/integration/deckard/sets/knotd/master/iter_ns.rpl28
-rw-r--r--tests/integration/deckard/sets/knotd/slave/iter_ns.rpl78
-rw-r--r--tests/integration/deckard/sets/resolver/LICENSE30
-rw-r--r--tests/integration/deckard/sets/resolver/black_data.rpl302
-rw-r--r--tests/integration/deckard/sets/resolver/black_dnskey.rpl510
-rw-r--r--tests/integration/deckard/sets/resolver/black_ds.rpl431
-rw-r--r--tests/integration/deckard/sets/resolver/black_ent.rpl464
-rw-r--r--tests/integration/deckard/sets/resolver/black_prime.rpl302
-rw-r--r--tests/integration/deckard/sets/resolver/fwd_val_cname_sibling.rpl168
-rw-r--r--tests/integration/deckard/sets/resolver/iter_badglue.rpl274
-rw-r--r--tests/integration/deckard/sets/resolver/iter_badraw.rpl18839
-rw-r--r--tests/integration/deckard/sets/resolver/iter_cname_badauth.rpl269
-rw-r--r--tests/integration/deckard/sets/resolver/iter_cname_cache.rpl299
-rw-r--r--tests/integration/deckard/sets/resolver/iter_cname_double.rpl296
-rw-r--r--tests/integration/deckard/sets/resolver/iter_cname_nx.rpl290
-rw-r--r--tests/integration/deckard/sets/resolver/iter_cname_qnamecopy.rpl356
-rw-r--r--tests/integration/deckard/sets/resolver/iter_cycle.rpl260
-rw-r--r--tests/integration/deckard/sets/resolver/iter_cycle_noh.rpl416
-rw-r--r--tests/integration/deckard/sets/resolver/iter_dname_insec.rpl1138
-rw-r--r--tests/integration/deckard/sets/resolver/iter_dnsseclame_ds_ok.rpl371
-rw-r--r--tests/integration/deckard/sets/resolver/iter_dnsseclame_ta_ok.rpl307
-rw-r--r--tests/integration/deckard/sets/resolver/iter_domain_sale.rpl271
-rw-r--r--tests/integration/deckard/sets/resolver/iter_domain_sale_nschange.rpl350
-rw-r--r--tests/integration/deckard/sets/resolver/iter_donotq127.rpl198
-rw-r--r--tests/integration/deckard/sets/resolver/iter_ds_locate_ns.rpl146
-rw-r--r--tests/integration/deckard/sets/resolver/iter_ds_locate_ns_nosoa.rpl146
-rw-r--r--tests/integration/deckard/sets/resolver/iter_escape_bailiwick.rpl220
-rw-r--r--tests/integration/deckard/sets/resolver/iter_hint_lame.rpl172
-rw-r--r--tests/integration/deckard/sets/resolver/iter_lame_aaaa.rpl180
-rw-r--r--tests/integration/deckard/sets/resolver/iter_lame_noaa.rpl126
-rw-r--r--tests/integration/deckard/sets/resolver/iter_lame_nosoa.rpl293
-rw-r--r--tests/integration/deckard/sets/resolver/iter_lame_root.rpl35
-rw-r--r--tests/integration/deckard/sets/resolver/iter_lamescrub.rpl152
-rw-r--r--tests/integration/deckard/sets/resolver/iter_minim_a.rpl95
-rw-r--r--tests/integration/deckard/sets/resolver/iter_minim_a_nxdomain.rpl106
-rw-r--r--tests/integration/deckard/sets/resolver/iter_minim_nonempty.rpl134
-rw-r--r--tests/integration/deckard/sets/resolver/iter_minim_ns.rpl128
-rw-r--r--tests/integration/deckard/sets/resolver/iter_minmaxttl.rpl194
-rw-r--r--tests/integration/deckard/sets/resolver/iter_mod.rpl219
-rw-r--r--tests/integration/deckard/sets/resolver/iter_multiple_A.rpl172
-rw-r--r--tests/integration/deckard/sets/resolver/iter_ns_badaa.rpl176
-rw-r--r--tests/integration/deckard/sets/resolver/iter_ns_badglue.rpl240
-rw-r--r--tests/integration/deckard/sets/resolver/iter_ns_badip.rpl270
-rw-r--r--tests/integration/deckard/sets/resolver/iter_ns_noglue.rpl222
-rw-r--r--tests/integration/deckard/sets/resolver/iter_ns_spoof.rpl276
-rw-r--r--tests/integration/deckard/sets/resolver/iter_pc_a.rpl232
-rw-r--r--tests/integration/deckard/sets/resolver/iter_pc_aaaa.rpl284
-rw-r--r--tests/integration/deckard/sets/resolver/iter_pcdiff.rpl210
-rw-r--r--tests/integration/deckard/sets/resolver/iter_pcdirect.rpl313
-rw-r--r--tests/integration/deckard/sets/resolver/iter_pcname.rpl278
-rw-r--r--tests/integration/deckard/sets/resolver/iter_pcnamech.rpl423
-rw-r--r--tests/integration/deckard/sets/resolver/iter_pcnamechrec.rpl402
-rw-r--r--tests/integration/deckard/sets/resolver/iter_pcnamerec.rpl276
-rw-r--r--tests/integration/deckard/sets/resolver/iter_pcttl.rpl355
-rw-r--r--tests/integration/deckard/sets/resolver/iter_reclame_one.rpl318
-rw-r--r--tests/integration/deckard/sets/resolver/iter_reclame_two.rpl357
-rw-r--r--tests/integration/deckard/sets/resolver/iter_recurse.rpl314
-rw-r--r--tests/integration/deckard/sets/resolver/iter_req_qname.rpl122
-rw-r--r--tests/integration/deckard/sets/resolver/iter_resolve.rpl221
-rw-r--r--tests/integration/deckard/sets/resolver/iter_tcbit.rpl89
-rw-r--r--tests/integration/deckard/sets/resolver/iter_timeouted_ns.rpl318
-rw-r--r--tests/integration/deckard/sets/resolver/iter_unexpectedrrtype.rpl61
-rw-r--r--tests/integration/deckard/sets/resolver/iter_validate.rpl211
-rw-r--r--tests/integration/deckard/sets/resolver/iter_validate_child_zone_noaddr.rpl209
-rw-r--r--tests/integration/deckard/sets/resolver/iter_validate_extradata.rpl214
-rw-r--r--tests/integration/deckard/sets/resolver/iter_validate_nsec_nxdomain.rpl154
-rw-r--r--tests/integration/deckard/sets/resolver/module_dns64.rpl206
-rw-r--r--tests/integration/deckard/sets/resolver/module_hint_static.rpl45
-rw-r--r--tests/integration/deckard/sets/resolver/module_policy_deny_all.rpl98
-rw-r--r--tests/integration/deckard/sets/resolver/module_policy_deny_suff_comm.rpl150
-rw-r--r--tests/integration/deckard/sets/resolver/module_policy_deny_suff_patt.rpl150
-rw-r--r--tests/integration/deckard/sets/resolver/module_policy_drop.rpl26
-rw-r--r--tests/integration/deckard/sets/resolver/module_policy_forward.rpl40
-rw-r--r--tests/integration/deckard/sets/resolver/module_policy_pass_deny.rpl69
-rw-r--r--tests/integration/deckard/sets/resolver/module_policy_tc.rpl26
-rw-r--r--tests/integration/deckard/sets/resolver/module_renumber.rpl88
-rw-r--r--tests/integration/deckard/sets/resolver/module_workarounds_disable_0x20.rpl83
-rw-r--r--tests/integration/deckard/sets/resolver/nsec3_aggr_cache.rpl5281
-rw-r--r--tests/integration/deckard/sets/resolver/nsec3_wildcard_no_data_response.rpl112
-rw-r--r--tests/integration/deckard/sets/resolver/nsec_aggr_cache.rpl6395
-rw-r--r--tests/integration/deckard/sets/resolver/nsec_name_error_response-part2.rpl229
-rw-r--r--tests/integration/deckard/sets/resolver/nsec_name_error_response.rpl242
-rw-r--r--tests/integration/deckard/sets/resolver/nsec_no_data_response.rpl203
-rw-r--r--tests/integration/deckard/sets/resolver/nsec_ref_to_unsigned1.rpl198
-rw-r--r--tests/integration/deckard/sets/resolver/nsec_ref_to_unsigned2.rpl199
-rw-r--r--tests/integration/deckard/sets/resolver/nsec_ref_to_unsigned3.rpl199
-rw-r--r--tests/integration/deckard/sets/resolver/nsec_wildcard_answer_response.rpl420
-rw-r--r--tests/integration/deckard/sets/resolver/nsec_wildcard_answer_response/K.+008+41524.key5
-rw-r--r--tests/integration/deckard/sets/resolver/nsec_wildcard_answer_response/K.+008+41524.private13
-rw-r--r--tests/integration/deckard/sets/resolver/nsec_wildcard_answer_response/root.zone8
-rw-r--r--tests/integration/deckard/sets/resolver/nsec_wildcard_no_data_response-part2.rpl259
-rw-r--r--tests/integration/deckard/sets/resolver/nsec_wildcard_no_data_response.rpl284
-rw-r--r--tests/integration/deckard/sets/resolver/val_ad_qtype_ds.rpl198
-rw-r--r--tests/integration/deckard/sets/resolver/val_adbit.rpl174
-rw-r--r--tests/integration/deckard/sets/resolver/val_adcopy.rpl166
-rw-r--r--tests/integration/deckard/sets/resolver/val_anchor_nx_nosig.rpl220
-rw-r--r--tests/integration/deckard/sets/resolver/val_ans_dsent.rpl248
-rw-r--r--tests/integration/deckard/sets/resolver/val_ans_nx.rpl250
-rw-r--r--tests/integration/deckard/sets/resolver/val_bogus_nodata.rpl247
-rw-r--r--tests/integration/deckard/sets/resolver/val_cname_loop1.rpl144
-rw-r--r--tests/integration/deckard/sets/resolver/val_cname_loop1_3.rpl184
-rw-r--r--tests/integration/deckard/sets/resolver/val_cname_loop3.rpl166
-rw-r--r--tests/integration/deckard/sets/resolver/val_cname_new_signer.rpl241
-rw-r--r--tests/integration/deckard/sets/resolver/val_cname_oob.rpl183
-rw-r--r--tests/integration/deckard/sets/resolver/val_cname_to_unsigned.rpl204
-rw-r--r--tests/integration/deckard/sets/resolver/val_cname_to_unsigned_fake_rrsig.rpl215
-rw-r--r--tests/integration/deckard/sets/resolver/val_cname_trust_domains.rpl440
-rw-r--r--tests/integration/deckard/sets/resolver/val_cnamenx_dblnsec.rpl180
-rw-r--r--tests/integration/deckard/sets/resolver/val_cnameqtype.rpl232
-rw-r--r--tests/integration/deckard/sets/resolver/val_deleg_nons.rpl273
-rw-r--r--tests/integration/deckard/sets/resolver/val_dname.rpl318
-rw-r--r--tests/integration/deckard/sets/resolver/val_dname_bogus.rpl319
-rw-r--r--tests/integration/deckard/sets/resolver/val_ds_afterprime.rpl183
-rw-r--r--tests/integration/deckard/sets/resolver/val_ds_cname.rpl206
-rw-r--r--tests/integration/deckard/sets/resolver/val_ds_cnamesub.rpl279
-rw-r--r--tests/integration/deckard/sets/resolver/val_faildnskey.rpl173
-rw-r--r--tests/integration/deckard/sets/resolver/val_iter_high.rpl239
-rw-r--r--tests/integration/deckard/sets/resolver/val_mal_wc.rpl153
-rw-r--r--tests/integration/deckard/sets/resolver/val_minimal_anotherdomainsignature.rpl99
-rw-r--r--tests/integration/deckard/sets/resolver/val_minimal_anotherrrtypesignature.rpl87
-rw-r--r--tests/integration/deckard/sets/resolver/val_minimal_baddnskeyalgorithm.rpl88
-rw-r--r--tests/integration/deckard/sets/resolver/val_minimal_baddnskeyflags.rpl88
-rw-r--r--tests/integration/deckard/sets/resolver/val_minimal_baddnskeyprotocol.rpl88
-rw-r--r--tests/integration/deckard/sets/resolver/val_minimal_baddsalgorithm.rpl87
-rw-r--r--tests/integration/deckard/sets/resolver/val_minimal_baddsdigest.rpl87
-rw-r--r--tests/integration/deckard/sets/resolver/val_minimal_baddsdigesttype.rpl87
-rw-r--r--tests/integration/deckard/sets/resolver/val_minimal_baddskeytag.rpl87
-rw-r--r--tests/integration/deckard/sets/resolver/val_minimal_badpublickey.rpl88
-rw-r--r--tests/integration/deckard/sets/resolver/val_minimal_badrrsigalgorithm.rpl88
-rw-r--r--tests/integration/deckard/sets/resolver/val_minimal_badrrsigexpiration.rpl88
-rw-r--r--tests/integration/deckard/sets/resolver/val_minimal_badrrsiginception.rpl88
-rw-r--r--tests/integration/deckard/sets/resolver/val_minimal_badrrsiglabels.rpl88
-rw-r--r--tests/integration/deckard/sets/resolver/val_minimal_badrrsigsignature.rpl88
-rw-r--r--tests/integration/deckard/sets/resolver/val_minimal_badrrsigtag.rpl88
-rw-r--r--tests/integration/deckard/sets/resolver/val_minimal_badrrsigttl.rpl88
-rw-r--r--tests/integration/deckard/sets/resolver/val_minimal_beforeinception.rpl87
-rw-r--r--tests/integration/deckard/sets/resolver/val_minimal_expiredsignature.rpl87
-rw-r--r--tests/integration/deckard/sets/resolver/val_minimal_noerror.rpl89
-rw-r--r--tests/integration/deckard/sets/resolver/val_negcache_ds.rpl217
-rw-r--r--tests/integration/deckard/sets/resolver/val_noadwhennodo.rpl149
-rw-r--r--tests/integration/deckard/sets/resolver/val_nodata_hasdata.rpl165
-rw-r--r--tests/integration/deckard/sets/resolver/val_nodata_zonecut.rpl163
-rw-r--r--tests/integration/deckard/sets/resolver/val_nodatawc_badce.rpl165
-rw-r--r--tests/integration/deckard/sets/resolver/val_nokeyprime.rpl166
-rw-r--r--tests/integration/deckard/sets/resolver/val_nsec3_b1_nameerror.rpl163
-rw-r--r--tests/integration/deckard/sets/resolver/val_nsec3_b1_nameerror_noce.rpl147
-rw-r--r--tests/integration/deckard/sets/resolver/val_nsec3_b1_nameerror_nonc.rpl149
-rw-r--r--tests/integration/deckard/sets/resolver/val_nsec3_b1_nameerror_nowc.rpl154
-rw-r--r--tests/integration/deckard/sets/resolver/val_nsec3_b21_nodataent.rpl118
-rw-r--r--tests/integration/deckard/sets/resolver/val_nsec3_b21_nodataent_wr.rpl138
-rw-r--r--tests/integration/deckard/sets/resolver/val_nsec3_b2_nodata.rpl119
-rw-r--r--tests/integration/deckard/sets/resolver/val_nsec3_b2_nodata_nons.rpl144
-rw-r--r--tests/integration/deckard/sets/resolver/val_nsec3_b3_optout.rpl208
-rw-r--r--tests/integration/deckard/sets/resolver/val_nsec3_b3_optout_negcache.rpl211
-rw-r--r--tests/integration/deckard/sets/resolver/val_nsec3_b3_optout_noce.rpl257
-rw-r--r--tests/integration/deckard/sets/resolver/val_nsec3_b3_optout_nonc.rpl258
-rw-r--r--tests/integration/deckard/sets/resolver/val_nsec3_b4_wild.rpl176
-rw-r--r--tests/integration/deckard/sets/resolver/val_nsec3_b5_wcnodata.rpl157
-rw-r--r--tests/integration/deckard/sets/resolver/val_nsec3_b5_wcnodata_noce.rpl167
-rw-r--r--tests/integration/deckard/sets/resolver/val_nsec3_b5_wcnodata_nonc.rpl167
-rw-r--r--tests/integration/deckard/sets/resolver/val_nsec3_b5_wcnodata_nowc.rpl167
-rw-r--r--tests/integration/deckard/sets/resolver/val_nsec3_cnametocnamewctoposwc.rpl244
-rw-r--r--tests/integration/deckard/sets/resolver/val_nsec3_entnodata_optout_badopt.rpl201
-rw-r--r--tests/integration/deckard/sets/resolver/val_nsec3_nods_badsig.rpl240
-rw-r--r--tests/integration/deckard/sets/resolver/val_nsec3_nods_soa.rpl256
-rw-r--r--tests/integration/deckard/sets/resolver/val_nsec3_noopt_ref.rpl232
-rw-r--r--tests/integration/deckard/sets/resolver/val_nsec3_optout_ad.rpl363
-rw-r--r--tests/integration/deckard/sets/resolver/val_nsec3_optout_ns_ad.rpl205
-rw-r--r--tests/integration/deckard/sets/resolver/val_nsec3_optout_unsec_cache.rpl256
-rw-r--r--tests/integration/deckard/sets/resolver/val_nx.rpl156
-rw-r--r--tests/integration/deckard/sets/resolver/val_nx_nodeny.rpl166
-rw-r--r--tests/integration/deckard/sets/resolver/val_nx_nowc.rpl166
-rw-r--r--tests/integration/deckard/sets/resolver/val_pos_truncns.rpl152
-rw-r--r--tests/integration/deckard/sets/resolver/val_positive_nosigs.rpl184
-rw-r--r--tests/integration/deckard/sets/resolver/val_qds_oneanc.rpl224
-rw-r--r--tests/integration/deckard/sets/resolver/val_qds_twoanc.rpl225
-rw-r--r--tests/integration/deckard/sets/resolver/val_referral_nods.rpl207
-rw-r--r--tests/integration/deckard/sets/resolver/val_root_ds.rpl88
-rw-r--r--tests/integration/deckard/sets/resolver/val_rrsig.rpl171
-rw-r--r--tests/integration/deckard/sets/resolver/val_secds.rpl215
-rw-r--r--tests/integration/deckard/sets/resolver/val_secds_nosig.rpl235
-rw-r--r--tests/integration/deckard/sets/resolver/val_ta_sentinel.rpl587
-rw-r--r--tests/integration/deckard/sets/resolver/val_ta_sentinel/K.+008+48409.key5
-rw-r--r--tests/integration/deckard/sets/resolver/val_ta_sentinel/K.+008+48409.private13
-rw-r--r--tests/integration/deckard/sets/resolver/val_ta_sentinel/root.db61
-rw-r--r--tests/integration/deckard/sets/resolver/val_ta_sentinel_insecure.rpl377
-rw-r--r--tests/integration/deckard/sets/resolver/val_ta_sentinel_nokey.rpl362
-rw-r--r--tests/integration/deckard/sets/resolver/val_unalgo_ds.rpl204
-rw-r--r--tests/integration/deckard/sets/resolver/val_unknown_algorithm_insecure.rpl162
-rw-r--r--tests/integration/deckard/sets/resolver/val_unknown_algorithm_insecure/K.+008+17002.key5
-rw-r--r--tests/integration/deckard/sets/resolver/val_unknown_algorithm_insecure/K.+008+17002.private13
-rw-r--r--tests/integration/deckard/sets/resolver/val_unknown_algorithm_insecure/root_unknown_ds_algo_and_digest.db11
-rw-r--r--tests/integration/deckard/sets/resolver/val_unknown_algorithm_insecure/test.db5
-rw-r--r--tests/integration/deckard/sets/resolver/val_unknown_algorithm_insecure/test2.db5
-rw-r--r--tests/integration/deckard/sets/resolver/val_unsecds.rpl195
-rw-r--r--tests/integration/deckard/sets/resolver/val_unsecds_negcache.rpl196
-rw-r--r--tests/integration/deckard/sets/resolver/val_unsecds_qtypeds.rpl211
-rw-r--r--tests/integration/deckard/sets/resolver/val_wild_pos.rpl163
-rw-r--r--tests/integration/deckard/sets/resolver/val_wild_pos_multi.rpl239
-rw-r--r--tests/integration/deckard/sets/resolver/val_wild_pos_multi/K.+008+41524.key5
-rw-r--r--tests/integration/deckard/sets/resolver/val_wild_pos_multi/K.+008+41524.private13
-rw-r--r--tests/integration/deckard/sets/resolver/val_wild_pos_multi/dsset-.2
-rw-r--r--tests/integration/deckard/sets/resolver/val_wild_pos_multi/root.zone10
-rw-r--r--tests/integration/deckard/sets/resolver/val_wild_pos_multi/root.zone.signed114
-rw-r--r--tests/integration/deckard/sets/resolver/world_cz_lidovky_www.rpl933
-rw-r--r--tests/integration/deckard/sets/resolver/world_cz_rhybar.rpl296
-rw-r--r--tests/integration/deckard/sets/resolver/world_cz_turris_api.rpl325
-rw-r--r--tests/integration/deckard/sets/resolver/world_cz_vutbr_www.rpl298
-rw-r--r--tests/integration/deckard/sets/resolver/world_mx_nic_www.rpl408
-rw-r--r--tests/integration/deckard/setup.py36
-rw-r--r--tests/integration/deckard/template/dnssec_getdns.j23
-rw-r--r--tests/integration/deckard/template/getdns.j26
-rw-r--r--tests/integration/deckard/template/hints_zone.j29
-rw-r--r--tests/integration/deckard/template/knotd_master.j229
-rw-r--r--tests/integration/deckard/template/knotd_slave.j228
-rw-r--r--tests/integration/deckard/template/kresd.j2138
-rw-r--r--tests/integration/deckard/template/named.j2106
-rw-r--r--tests/integration/deckard/template/pdns_dnssec.j25
-rw-r--r--tests/integration/deckard/template/pdns_recursor.j2326
-rw-r--r--tests/integration/deckard/template/unbound.j2801
-rw-r--r--tests/integration/deckard/template/unbound_dnssec.j23
-rw-r--r--tests/integration/deckard/tests/__init__.py0
-rw-r--r--tests/integration/deckard/tests/deckard_raw_id.rpl14
-rw-r--r--tests/integration/deckard/tests/deckard_raw_id.yml6
-rw-r--r--tests/integration/deckard/tests/test_deckard.py30
-rw-r--r--tests/integration/deckard/tools/answer_checker.py84
-rw-r--r--tests/integration/deckard/tools/conftest.py19
-rw-r--r--tests/integration/deckard/tools/divide_tests.sh77
-rw-r--r--tests/integration/deckard/tools/forwarder_check.py387
-rw-r--r--tests/integration/deckard/tools/generate_answers.py26
-rw-r--r--tests/integration/deckard/tools/invalid_dsa.py83
-rw-r--r--tests/integration/deckard/tools/network_check.py136
-rw-r--r--tests/integration/deckard/tools/parse.py21
l---------tests/integration/deckard/tools/pydnstest1
-rwxr-xr-xtests/integration/deckard/unbound_run.sh5
-rw-r--r--tests/integration/hints_zone.j210
-rw-r--r--tests/integration/meson.build68
-rw-r--r--tests/integration/testdata_notimpl/iter_class_any.rpl150
-rw-r--r--tests/integration/testdata_notimpl/iter_dnsseclame_bug.rpl465
-rw-r--r--tests/integration/testdata_notimpl/iter_dnsseclame_ds.rpl414
-rw-r--r--tests/integration/testdata_notimpl/iter_dnsseclame_ds_ok.rpl367
-rw-r--r--tests/integration/testdata_notimpl/iter_dnsseclame_ta.rpl327
-rw-r--r--tests/integration/testdata_notimpl/iter_dnsseclame_ta_ok.rpl303
-rw-r--r--tests/integration/testdata_notimpl/iter_dp_turnsuseless.rpl166
-rw-r--r--tests/integration/testdata_notimpl/iter_ds_locate_ns.rpl145
-rw-r--r--tests/integration/testdata_notimpl/iter_ds_locate_ns_cname.rpl155
-rw-r--r--tests/integration/testdata_notimpl/iter_ds_locate_ns_detach.rpl296
-rw-r--r--tests/integration/testdata_notimpl/iter_ds_locate_ns_nosoa.rpl145
-rw-r--r--tests/integration/testdata_notimpl/iter_emptydp.rpl263
-rw-r--r--tests/integration/testdata_notimpl/iter_emptydp_for_glue.rpl493
-rw-r--r--tests/integration/testdata_notimpl/iter_fwdfirst.rpl157
-rw-r--r--tests/integration/testdata_notimpl/iter_fwdfirstequal.rpl157
-rw-r--r--tests/integration/testdata_notimpl/iter_fwdstub.rpl218
-rw-r--r--tests/integration/testdata_notimpl/iter_fwdstubroot.rpl175
-rw-r--r--tests/integration/testdata_notimpl/iter_got6only.rpl135
-rw-r--r--tests/integration/testdata_notimpl/iter_pcdiff.rpl210
-rw-r--r--tests/integration/testdata_notimpl/iter_pcnamerec.rpl275
-rw-r--r--tests/integration/testdata_notimpl/iter_primenoglue.rpl383
-rw-r--r--tests/integration/testdata_notimpl/iter_privaddr.rpl285
-rw-r--r--tests/integration/testdata_notimpl/iter_ranoaa_lame.rpl293
-rw-r--r--tests/integration/testdata_notimpl/iter_scrub_cname_an.rpl181
-rw-r--r--tests/integration/testdata_notimpl/iter_scrub_dname_insec.rpl250
-rw-r--r--tests/integration/testdata_notimpl/iter_scrub_dname_sec.rpl212
-rw-r--r--tests/integration/testdata_notimpl/iter_scrub_ns.rpl103
-rw-r--r--tests/integration/testdata_notimpl/iter_scrub_ns_fwd.rpl103
-rw-r--r--tests/integration/testdata_notimpl/iter_scrub_ns_side.rpl103
-rw-r--r--tests/integration/testdata_notimpl/iter_stub_noroot.rpl64
-rw-r--r--tests/integration/testdata_notimpl/iter_stubfirst.rpl157
-rw-r--r--tests/integration/testdata_notimpl/iter_stublastresort.rpl259
-rw-r--r--tests/integration/testdata_notimpl/iter_timeout_ra_aaaa.rpl244
-rw-r--r--tests/meson.build61
-rw-r--r--tests/packaging/README.rst87
-rw-r--r--tests/packaging/conftest.py10
-rw-r--r--tests/packaging/test_packaging.py494
-rw-r--r--tests/pytests/README.rst56
-rwxr-xr-xtests/pytests/certs/tt-certgen-expired.sh19
-rwxr-xr-xtests/pytests/certs/tt-certgen.sh5
-rw-r--r--tests/pytests/certs/tt-expired.cert.pem80
-rw-r--r--tests/pytests/certs/tt-expired.key.pem27
-rw-r--r--tests/pytests/certs/tt.cert.pem22
-rw-r--r--tests/pytests/certs/tt.conf353
-rw-r--r--tests/pytests/certs/tt.key.pem28
-rw-r--r--tests/pytests/conftest.py102
-rw-r--r--tests/pytests/conn_flood.py85
-rw-r--r--tests/pytests/kresd.py306
-rw-r--r--tests/pytests/meson.build77
-rw-r--r--tests/pytests/proxy.py161
-rw-r--r--tests/pytests/proxy/tls-proxy.c1038
-rw-r--r--tests/pytests/proxy/tls-proxy.h34
-rw-r--r--tests/pytests/proxy/tlsproxy.c198
-rw-r--r--tests/pytests/pylintrc33
-rw-r--r--tests/pytests/requirements.txt5
-rw-r--r--tests/pytests/templates/kresd.conf.j262
-rw-r--r--tests/pytests/test_conn_mgmt.py214
-rw-r--r--tests/pytests/test_edns.py22
-rw-r--r--tests/pytests/test_prefix.py114
-rw-r--r--tests/pytests/test_random_close.py54
-rw-r--r--tests/pytests/test_rehandshake.py52
-rw-r--r--tests/pytests/test_tls.py83
-rw-r--r--tests/pytests/utils.py136
-rw-r--r--tests/unit/meson.build37
-rw-r--r--tests/unit/mock_cmodule.c21
-rw-r--r--tests/unit/packaging/debian/10/builddeps1
-rwxr-xr-xtests/unit/packaging/test.sh2
-rw-r--r--tests/unit/test.h110
-rw-r--r--utils/cache_gc/.gitignore2
-rw-r--r--utils/cache_gc/README.rst20
-rw-r--r--utils/cache_gc/categories.c56
-rw-r--r--utils/cache_gc/categories.h10
-rw-r--r--utils/cache_gc/db.c280
-rw-r--r--utils/cache_gc/db.h37
-rw-r--r--utils/cache_gc/kr_cache_gc.c326
-rw-r--r--utils/cache_gc/kr_cache_gc.h41
-rw-r--r--utils/cache_gc/main.c163
-rw-r--r--utils/cache_gc/meson.build31
-rw-r--r--utils/cache_gc/test.integr/deckard.yaml37
-rw-r--r--utils/cache_gc/test.integr/val_rrsig.rpl737
-rw-r--r--utils/client/kresc.c458
-rw-r--r--utils/client/meson.build37
-rw-r--r--utils/meson.build8
-rw-r--r--utils/upgrade/meson.build13
-rw-r--r--utils/upgrade/upgrade-4-to-5.lua.in87
1347 files changed, 266670 insertions, 0 deletions
diff --git a/.clang-tidy b/.clang-tidy
new file mode 100644
index 0000000..b496044
--- /dev/null
+++ b/.clang-tidy
@@ -0,0 +1,11 @@
+---
+Checks: 'bugprone-*,cert-*,-cert-dcl03-c,-clang-analyzer-unix.Malloc,-clang-analyzer-deadcode.DeadStores,-clang-analyzer-valist.Uninitialized,readability-*,-readability-braces-*,-readability-else-after-return,-readability-redundant-declaration,-readability-non-const-parameter,google-readability-casting,misc-*,-misc-static-assert,-misc-macro-parentheses,-misc-unused-parameters'
+WarningsAsErrors: 'cert-*,misc-*,readability-*,clang-analyzer-*,-readability-non-const-parameter'
+HeaderFilterRegex: 'contrib/ucw/*.h'
+CheckOptions:
+ - key: readability-identifier-naming
+ value: 'lower_case'
+ - key: readability-function-size.StatementThreshold
+ value: '400'
+ - key: readability-function-size.LineThreshold
+ value: '500'
diff --git a/.dir-locals.el b/.dir-locals.el
new file mode 100644
index 0000000..e0bab75
--- /dev/null
+++ b/.dir-locals.el
@@ -0,0 +1,10 @@
+;; emacs local configuration settings for knot-resolver source
+;; surmised by dkg on 2016-04-02 23:46:50-0300
+;; SPDX-License-Identifier: GPL-3.0-or-later
+
+((c-mode
+ (indent-tabs-mode . t)
+ (tab-width . 8)
+ (c-basic-offset . 8)
+ (c-file-style . "linux"))
+ )
diff --git a/.luacheckrc b/.luacheckrc
new file mode 100644
index 0000000..28ef054
--- /dev/null
+++ b/.luacheckrc
@@ -0,0 +1,99 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+std = 'luajit'
+new_read_globals = {
+ 'cache',
+ 'eval_cmd',
+ 'event',
+ 'help',
+ '_hint_root_file',
+ 'hostname',
+ 'map',
+ 'modules',
+ 'net',
+ 'package_version',
+ 'quit',
+ 'resolve',
+ 'ta_update',
+ 'fromjson',
+ 'todname',
+ 'tojson',
+ 'user',
+ 'worker',
+ 'kluautil_list_dir',
+ -- Sandbox declarations
+ 'kB',
+ 'MB',
+ 'GB',
+ 'sec',
+ 'second',
+ 'minute',
+ 'min',
+ 'hour',
+ 'day',
+ 'panic',
+ 'log',
+ 'log_error',
+ 'log_warn',
+ 'log_info',
+ 'log_debug',
+ 'log_fmt',
+ 'log_qry',
+ 'log_req',
+ 'log_level',
+ 'log_target',
+ 'log_groups',
+ 'LOG_CRIT',
+ 'LOG_ERR',
+ 'LOG_WARNING',
+ 'LOG_NOTICE',
+ 'LOG_INFO',
+ 'LOG_DEBUG',
+ 'mode',
+ 'reorder_RR',
+ 'option',
+ 'env',
+ 'debugging',
+ 'kres',
+ 'libknot_SONAME',
+ 'libzscanner_SONAME',
+ 'table_print',
+ '_ENV',
+}
+
+new_globals = {
+ -- Modules are allowed to be set and accessed from global namespace
+ 'policy',
+ 'view',
+ 'stats',
+ 'http',
+ 'trust_anchors',
+ 'bogus_log',
+}
+
+-- Luacheck < 0.18 doesn't support new_read_globals
+for _, v in ipairs(new_read_globals) do
+ table.insert(new_globals, v)
+end
+
+exclude_files = {
+ 'modules/policy/lua-aho-corasick', -- Vendored
+ 'tests/config/tapered',
+ 'build*/**', -- build outputs
+ 'pkg/**', -- packaging outputs
+}
+
+-- Ignore some pedantic checks
+ignore = {
+ '4.1/err', -- Shadowing err
+ '4.1/.', -- Shadowing one letter variables
+}
+
+-- Sandbox can set global variables
+files['**/daemon/lua'].ignore = {'111', '121', '122'}
+files['**/daemon/lua/kres-gen-*.lua'].ignore = {'631'} -- Allow overly long lines
+-- Tests and scripts can use global variables
+files['scripts'].ignore = {'111', '112', '113'}
+files['tests'].ignore = {'111', '112', '113'}
+files['**/utils/upgrade'].ignore = {'111', '112', '113'}
+files['**/modules/**/*.test.lua'].ignore = {'111', '112', '113', '121', '122'}
+files['**/daemon/**/*.test.lua'].ignore = {'111', '112', '113', '121', '122'}
diff --git a/.mailmap b/.mailmap
new file mode 100644
index 0000000..a6ec38b
--- /dev/null
+++ b/.mailmap
@@ -0,0 +1,57 @@
+Aleš Mrázek <ales.mrazek@nic.cz>
+Alex Forster <aforster@cloudflare.com>
+Ali Asad Lotia <ali.asad.lotia@gmail.com>
+Anbang Wen <anbang@cloudflare.com> <xofyarg@gmail.com>
+Anbang Wen <anbang@cloudflare.com> <anb@dev.null>
+Andreas Rammhold <andreas@rammhold.de>
+Daniel Kahn Gillmor <dkg@fifthhorseman.net>
+Daniel Salzman <daniel.salzman@nic.cz>
+daurnimator <quae@daurnimator.com>
+David Beitey <david@davidjb.com>
+Grigorii Demidov <grigorii.demidov@nic.cz>
+Hasnat <hasnat.ullah@gmail.com>
+Jiří Helebrant <jiri.helebrant@nic.cz> <helb@helb.cz>
+Ivana Krumlová <ivana.krumlova@nic.cz>
+Jakub RužiÄka <jakub.ruzicka@nic.cz>
+Jan Hák <jan.hak@nic.cz>
+Jan Holuša <jan.holusa@nic.cz>
+Jan Pavlinec <jan.pavlinec@nic.cz>
+Jan VÄelák <jan.vcelak@nic.cz> <jv@fcelda.cz>
+Jan VÄelák <jan.vcelak@nic.cz>
+Jayson Reis <santosdosreis@gmail.com>
+Jonathan Coetzee <jon@thancoetzee.com>
+Josh Soref <jsoref@users.noreply.github.com>
+Karel Slaný <karel.slany@nic.cz>
+Libor Peltan <libor.peltan@nic.cz>
+Lukáš Ježek <lukas.jezek@nic.cz>
+Manu Bretelle <chantr4@gmail.com>
+Marek Vavruša <mvavrusa@cloudflare.com> Marek Vavrusa <marek@vavrusa.com>
+Marek Vavruša <mvavrusa@cloudflare.com> Marek Vavruša <mvavrusa@cloudflare.com>
+Marek Vavruša <mvavrusa@cloudflare.com> Marek Vavruša <marek.vavrusa@nic.cz>
+Marek Vavruša <mvavrusa@cloudflare.com> <marek@vavrusa.com>
+Marek Vavruša <mvavrusa@cloudflare.com> <marek.vavrusa@nic.cz>
+Michal Karm BabáÄek <karm@email.cz>
+Michal LupeÄka <mlupecka@nic.cz>
+Ondřej Surý <ondrej.sury@nic.cz> <ondrej@sury.org>
+Oto Šťáva <oto.stava@nic.cz> <oto.stava@gmail.com>
+Paul Hoffman <paul.hoffman@icann.org> <phoffman@proper.com>
+Paul Hoffman <paul.hoffman@icann.org>
+Pavel Doležal <pavel.dolezal@nic.cz>
+Pavel Valach <valach.pavel@gmail.com>
+Petr Å paÄek <petr.spacek@nic.cz>
+rickhg12hs <rickhg12hs@users.noreply.github.com>
+Robert Å efr <robert.sefr@outlook.com>
+SH <sh@analogic.cz>
+Simon South <simon@simonsouth.net>
+Štěpán Balážik <stepan@balazik.cz> <stepan.balazik@nic.cz>
+Štěpán Kotek <stepan.kotek@nic.cz> Stepan Kotek <stepan.kotek@nic.cz>
+Štěpán Kotek <stepan.kotek@nic.cz> <stepan.kotek@gmail.com>
+The Gitter Badger <badger@gitter.im>
+Tomáš Hozza <thozza@redhat.com>
+Tomáš Křížek <tomas.krizek@nic.cz>
+Ulrich Wisser <ulrich.wisser@iis.se>
+Leo Vandewoestijne <github@unicycle.net>
+Vašek Šraier <vaclav.sraier@nic.cz> <git@vakabus.cz>
+Vicky Shrestha <vicky@cloudflare.com> <vicky@geeks.net.np>
+Vítězslav Kříž <vitezslav.kriz@nic.cz>
+Vladimír Čunát <vladimir.cunat@nic.cz> <vcunat@gmail.com>
diff --git a/AUTHORS b/AUTHORS
new file mode 100644
index 0000000..861d909
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1,85 @@
+Knot Resolver was conceived and is being developed
+by research department of CZ.NIC, the CZ TLD operator.
+
+Over the years many organizations and individuals contributed to the project.
+Special thanks belongs to following organizations:
+- Comcast
+- Cloudflare
+- ICANN
+
+People who contributed commits to our Git repo are:
+Aleš Mrázek <ales.mrazek@nic.cz>
+Alex Forster <aforster@cloudflare.com>
+Ali Asad Lotia <ali.asad.lotia@gmail.com>
+Anbang Wen <anbang@cloudflare.com>
+Andreas Rammhold <andreas@rammhold.de>
+Christophe Nowicki <cscm@csquad.org>
+cronfy <cronfy@gmail.com>
+Daniel Kahn Gillmor <dkg@fifthhorseman.net>
+Daniel Salzman <daniel.salzman@nic.cz>
+daurnimator <quae@daurnimator.com>
+David Beitey <david@davidjb.com>
+Grigorii Demidov <grigorii.demidov@nic.cz>
+Hasnat <hasnat.ullah@gmail.com>
+Héctor Molinero Fernández <hector@molinero.dev>
+Ivana Krumlová <ivana.krumlova@nic.cz>
+Jakub Jirutka <jakub@jirutka.cz>
+Jakub RužiÄka <jakub.ruzicka@nic.cz>
+Jan Hák <jan.hak@nic.cz>
+Jan Holuša <jan.holusa@nic.cz>
+Jan Pavlinec <jan.pavlinec@nic.cz>
+Jan VÄelák <jan.vcelak@nic.cz>
+Jayson Reis <santosdosreis@gmail.com>
+Jiří Helebrant <jiri.helebrant@nic.cz>
+Jonathan Coetzee <jon@thancoetzee.com>
+Josh Soref <jsoref@users.noreply.github.com>
+Karel Slaný <karel.slany@nic.cz>
+Konstantin Amelichev <kostya.amelichev@gmail.com>
+Leo Vandewoestijne <github@unicycle.net>
+Libor Peltan <libor.peltan@nic.cz>
+Lukáš Ježek <lukas.jezek@nic.cz>
+Manu Bretelle <chantr4@gmail.com>
+Marek Vavruša <mvavrusa@cloudflare.com>
+Michal Karm BabáÄek <karm@email.cz>
+Michal LupeÄka <mlupecka@nic.cz>
+Ondřej Surý <ondrej.sury@nic.cz>
+Oto Šťáva <oto.stava@nic.cz>
+Paul Hoffman <paul.hoffman@icann.org>
+Pavel Doležal <pavel.dolezal@nic.cz>
+Pavel Valach <valach.pavel@gmail.com>
+Peter Keresztes Schmidt <carbenium@outlook.com>
+Petr Å paÄek <petr.spacek@nic.cz>
+realPy <t3sla@v-ip.fr>
+rickhg12hs <rickhg12hs@users.noreply.github.com>
+Robert Å efr <robert.sefr@outlook.com>
+SH <sh@analogic.cz>
+Simon South <simon@simonsouth.net>
+Štěpán Balážik <stepan@balazik.cz>
+Štěpán Kotek <stepan.kotek@nic.cz>
+The Gitter Badger <badger@gitter.im>
+Tomáš Hozza <thozza@redhat.com>
+Tomáš Křížek <tomas.krizek@nic.cz>
+Tom Herbers <mail@tomherbers.de>
+Ulrich Wisser <ulrich.wisser@iis.se>
+Vašek Šraier <vaclav.sraier@nic.cz>
+Vicky Shrestha <vicky@cloudflare.com>
+Vítězslav Kříž <vitezslav.kriz@nic.cz>
+Vladimír Čunát <vladimir.cunat@nic.cz>
+
+Knot Resolver source tree also bundles code and content published by:
+Austin Appleby <aappleby@gmail.com>
+Dan Vanderkam <danvdk@gmail.com>
+Jonathan Allard <jonathan@allard.io>
+Joseph A. Adams <joeyadams3.14159@gmail.com>
+Mark DiMarco <mark.dimarco@gmail.com>
+Michael Bostock <mike@ocks.org>
+Rusty Russell <rusty@rustcorp.com.au>
+Thomas Park <thomas@thomaspark.co>
+Vincent Bernat <vincent@bernat.im>
+Fastly
+jQuery Foundation
+Knot DNS contributors
+Twitter
+United Computer Wizards
+
+Thanks to everyone who knowingly or unknowingly contributed!
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000..1420c31
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,19 @@
+Contributing
+============
+
+Please file issues and merge requests against the upstream repository:
+
+[https://gitlab.nic.cz/knot/knot-resolver](https://gitlab.nic.cz/knot/knot-resolver)
+
+Opening a merge request on gitlab.nic.cz
+----------------------------------------
+
+Unfortunately, due to administrative policy, forking is disabled by default. To
+be able to fork, please send us an e-mail with your username to knot-resolver@labs.nic.cz
+
+We apologize for the inconvenience and if you can't be bothered, please
+consider alternate ways of contributing, such as:
+
+- Opening a pull request on [github.com](https://github.com/CZ-NIC/knot-resolver).
+ We'll take care of it and move it to our upstream.
+- Sending a patch to the users list: knot-resolver-users@lists.nic.cz
diff --git a/COPYING b/COPYING
new file mode 100644
index 0000000..f390d92
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,695 @@
+Unless specifically indicated otherwise in a file or directory,
+files are licensed under GNU GPL license either version 3, or
+(at your option) any later version.
+
+SPDX-License-Identifier: GPL-3.0-or-later
+SPDX-URL: https://spdx.org/licenses/GPL-3.0-or-later.html
+License-Text:
+
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ <program> Copyright (C) <year> <name of author>
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<https://www.gnu.org/licenses/>.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+<https://www.gnu.org/philosophy/why-not-lgpl.html>.
+
+ In addition, as a special exception, the copyright holders give
+permission to link the code of portions of this program with the
+OpenSSL library under certain conditions as described in each
+individual source file, and distribute linked combinations including
+the two.
+ You must obey the GNU General Public License in all respects for all
+of the code used other than OpenSSL. If you modify file(s) with this
+exception, you may extend this exception to your version of the
+file(s), but you are not obligated to do so. If you do not wish to do
+so, delete this exception statement from your version. If you delete
+this exception statement from all source files in the program, then
+also delete it here.
diff --git a/CodingStyle b/CodingStyle
new file mode 100644
index 0000000..004c65b
--- /dev/null
+++ b/CodingStyle
@@ -0,0 +1,5 @@
+# Style
+
+Linux kernel [coding style][lkstyle], same practices for API documentation.
+
+[lkstyle]: https://www.kernel.org/doc/Documentation/process/coding-style.rst
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..c82938f
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,78 @@
+# Intermediate container for Knot DNS build (not persistent)
+# SPDX-License-Identifier: GPL-3.0-or-later
+FROM debian:11 AS knot-dns-build
+ARG KNOT_DNS_VERSION=v3.1.1
+
+# Build dependencies
+ENV KNOT_DNS_BUILD_DEPS git-core build-essential libtool autoconf pkg-config \
+ libgnutls28-dev libprotobuf-dev libprotobuf-c-dev libfstrm-dev
+ENV KNOT_RESOLVER_BUILD_DEPS build-essential pkg-config bsdmainutils liblmdb-dev \
+ libluajit-5.1-dev libuv1-dev libprotobuf-dev libprotobuf-c-dev \
+ libfstrm-dev luajit lua-http libssl-dev libnghttp2-dev protobuf-c-compiler \
+ meson
+ENV BUILDENV_DEPS ${KNOT_DNS_BUILD_DEPS} ${KNOT_RESOLVER_BUILD_DEPS}
+RUN apt-get update -qq && \
+ apt-get -y -qqq install ${BUILDENV_DEPS}
+
+# Install Knot DNS from sources
+RUN git clone -b $KNOT_DNS_VERSION --depth=1 https://gitlab.nic.cz/knot/knot-dns.git /tmp/knot-dns && \
+ cd /tmp/knot-dns && \
+ autoreconf -if && \
+ ./configure --disable-static --disable-fastparser --disable-documentation \
+ --disable-daemon --disable-utilities --with-lmdb=no && \
+ make -j4 install && \
+ ldconfig
+
+# Copy libknot, libdnssec, libzscanner to runtime
+RUN mkdir -p /tmp/root/usr/local/include /tmp/root/usr/local/lib /tmp/root/usr/local/lib/pkgconfig && \
+ cp -rt /tmp/root/usr/local/include /usr/local/include/libknot /usr/local/include/libdnssec /usr/local/include/libzscanner && \
+ cp -rt /tmp/root/usr/local/lib /usr/local/lib/libknot* /usr/local/lib/libdnssec* /usr/local/lib/libzscanner* && \
+ cp -rt /tmp/root/usr/local/lib/pkgconfig /usr/local/lib/pkgconfig/libknot.pc /usr/local/lib/pkgconfig/libdnssec.pc /usr/local/lib/pkgconfig/libzscanner.pc
+
+
+# Intermediate container with runtime dependencies
+FROM debian:11-slim AS runtime
+
+# Install runtime dependencies
+ENV KNOT_DNS_RUNTIME_DEPS libgnutls30
+ENV KNOT_RESOLVER_RUNTIME_DEPS liblmdb0 luajit libluajit-5.1-2 libuv1 lua-http libnghttp2-14
+ENV KNOT_RESOLVER_RUNTIME_DEPS_HTTP lua-http lua-mmdb
+ENV KNOT_RESOLVER_RUNTIME_DEPS_EXTRA lua-cqueues
+ENV KNOT_RESOLVER_RUNTIME_DEPS_DNSTAP libfstrm0 libprotobuf-c1
+ENV KNOT_RESOLVER_RUNTIME_DEPS_SSL ca-certificates
+ENV RUNTIME_DEPS ${KNOT_DNS_RUNTIME_DEPS} ${KNOT_RESOLVER_RUNTIME_DEPS} \
+ ${KNOT_RESOLVER_RUNTIME_DEPS_HTTP} ${KNOT_RESOLVER_RUNTIME_DEPS_EXTRA} \
+ ${KNOT_RESOLVER_RUNTIME_DEPS_SSL} ${KNOT_RESOLVER_RUNTIME_DEPS_DNSTAP}
+RUN apt-get update -qq && \
+ apt-get install -y -qqq ${RUNTIME_DEPS} && \
+ apt-get clean && \
+ rm -rf /var/lib/apt/lists/*
+
+
+# Intermediate container for Knot Resolver build
+FROM knot-dns-build AS build
+
+# Get Knot Resolver code from current directory
+COPY . /tmp/knot-resolver
+
+# Build Knot Resolver
+RUN cd /tmp/knot-resolver && \
+ meson build_docker --buildtype=plain --prefix=/usr --libdir=lib -Dc_args="-O2 -fstack-protector -g" && \
+ DESTDIR=/tmp/root ninja -C build_docker install && \
+ cp /tmp/root/usr/share/doc/knot-resolver/examples/config.docker /tmp/root/etc/knot-resolver/kresd.conf
+
+
+# Final container
+FROM runtime
+LABEL cz.knot-resolver.vendor="CZ.NIC"
+LABEL maintainer="knot-resolver-users@lists.nic.cz"
+
+# Export DNS over UDP & TCP, DNS-over-HTTPS, DNS-over-TLS, web interface
+EXPOSE 53/UDP 53/TCP 443/TCP 853/TCP 8453/TCP
+
+# Fetch Knot Resolver + Knot DNS libraries from build image
+COPY --from=build /tmp/root/ /
+RUN ldconfig
+
+ENTRYPOINT ["/usr/sbin/kresd"]
+CMD ["-c", "/etc/knot-resolver/kresd.conf"]
diff --git a/NEWS b/NEWS
new file mode 100644
index 0000000..45078d3
--- /dev/null
+++ b/NEWS
@@ -0,0 +1,1305 @@
+Knot Resolver 5.6.0 (2023-01-26)
+================================
+
+Security
+--------
+- avoid excessive TCP reconnections in some cases (!1380)
+ For example, a DNS server that just closes connections without answer
+ could cause lots of work for the resolver (and itself, too).
+ The number of connections could be up to around 100 per client's query.
+
+ We thank Xiang Li from NISL Lab, Tsinghua University,
+ and Xuesong Bai and Qifan Zhang from DSP Lab, UCI.
+
+Improvements
+------------
+- daemon: feed server selection with more kinds of bad-answer events (!1380)
+- cache.max_ttl(): lower the default from six days to one day
+ and apply both limits to the first uncached answer already (!1323 #127)
+- depend on jemalloc, preferably, to improve memory usage (!1353)
+- no longer accept DNS messages with trailing data (!1365)
+- policy.STUB: avoid applying aggressive DNSSEC denial proofs (!1364)
+- policy.STUB: avoid copying +dnssec flag from client to upstream (!1364)
+
+Bugfixes
+--------
+- policy.DEBUG_IF: don't print client's packet unconditionally (!1366)
+
+
+Knot Resolver 5.5.3 (2022-09-21)
+================================
+
+Security
+--------
+- fix CPU-expensive DoS by malicious domains - CVE-2022-40188
+
+Improvements
+------------
+- fix config_tests on macOS (both HW variants)
+
+
+Knot Resolver 5.5.2 (2022-08-16)
+================================
+
+Improvements
+------------
+- support libknot 3.2 (!1309)
+- priming module: hide failures from the default log level (!1310)
+- reduce memory usage in some cases (!1328)
+
+Bugfixes
+--------
+- daemon/http: improve URI checks to fix some proxies (#746, !1311)
+- daemon/tls: fix a double-free for some cases of policy.TLS_FORWARD (!1314)
+- hints module: improve parsing comments in hosts files (!1315)
+- renumber module: fix renumbering with name matching again (#760, !1334)
+
+
+Knot Resolver 5.5.1 (2022-06-14)
+================================
+
+Improvements
+------------
+- daemon/tls: disable TLS resumption via tickets for TLS <= 1.2 (#742, !1295)
+- daemon/http: DoH now responds with proper HTTP codes (#728, !1279)
+- renumber module: allow rewriting subnet to a single IP (!1302)
+- renumber module: allow arbitrary netmask (!1306)
+- nameserver selection algorithm: improve IPv6 avoidance if broken (!1298)
+
+Bugfixes
+--------
+- modules/dns64: fix incorrect packet writes for cached packets (#727, !1275)
+- xdp: make it work also with libknot 3.1 (#735, !1276)
+- prefill module: fix lockup when starting multiple idle instances (!1285)
+- validator: fix some failing negative NSEC proofs (!1294, #738, #443)
+
+
+Knot Resolver 5.5.0 (2022-03-15)
+================================
+
+Improvements
+------------
+- extended_errors: module for extended DNS error support, RFC8914 (!1234)
+- policy: log policy actions; useful for RPZ debugging (!1239)
+- policy: new action policy.IPTRACE for logging request origin (!1239)
+- prefill module: prepare for ZONEMD, improve performance (!1225)
+- validator: conditionally ignore SHA1 DS, as SHOULD by RFC4509 (!1251)
+- lib/resolve: use EDNS padding for outgoing TLS queries (!1254)
+- support for PROXYv2 protocol (!1238)
+- lib/resolve, policy: new NO_ANSWER flag for not responding to clients (!1257)
+
+Incompatible changes
+--------------------
+- libknot >= 3.0.2 is required
+
+Bugfixes
+--------
+- doh2: fix CORS by adding `access-control-allow-origin: *` (!1246)
+- net: fix listen by interface - add interface suffix to link-local IPv6 (!1253)
+- daemon/tls: fix resumption for outgoing TLS (e.g. TLS_FORWARD) (!1261)
+- nameserver selection: fix interaction of timeouts with reboots (#722, !1269)
+
+
+Knot Resolver 5.4.4 (2022-01-05)
+================================
+
+Bugfixes
+--------
+- fix bad zone cut update in certain cases (e.g. AWS; !1237)
+
+
+Knot Resolver 5.4.3 (2021-12-01)
+================================
+
+Improvements
+------------
+- lua: add kres.parse_rdata() to parse RDATA from string to wire format (!1233)
+- lua: add policy.domains() for exact domain name matching (!1228)
+
+Bugfixes
+--------
+- policy.rpz: fix origin detection in files without $ORIGIN (!1215)
+- lua: log() works again; broken in 5.4.2 (!1223)
+- policy: correctly include EDNS0 previously omitted by some actions (!1230)
+- edns_keepalive: module is now properly loaded (!1229, thanks Josh Soref!)
+
+
+Knot Resolver 5.4.2 (2021-10-13)
+================================
+
+Improvements
+------------
+- dns64 module: also map the reverse (PTR) subtree (#478, !1201)
+- dns64 module: allow disabling based on client address (#368, !1201)
+- dns64 module: allow configuring AAAA subnets not allowed in answer (!1201)
+- nameserver selection algorithm: improve IPv6 avoidance if broken (!1207)
+
+Bugfixes
+--------
+- lua: log() output is visible with default log level again (!1208)
+- build: fix when knot-dns headers are on non-standard location (!1210)
+
+
+Knot Resolver 5.4.1 (2021-08-19)
+================================
+
+Improvements
+------------
+- docker: base image on Debian 11 (!1203)
+
+Bugfixes
+--------
+- fix build without doh2 support after 5.4.0 (!1197)
+- fix policy.DEBUG* logging and -V/--version after 5.4.0 (!1199)
+- doh2: ensure memory from unsent streams is freed (!1202)
+
+
+Knot Resolver 5.4.0 (2021-07-29)
+================================
+
+Improvements
+------------
+- fine grained logging and syslog support (!1181)
+- expose HTTP headers for processing DoH requests (!1165)
+- improve assertion mechanism for debugging (!1146)
+- support apkg tool for packaging workflow (!1178)
+- support Knot DNS 3.1 (!1192, !1194)
+
+Bugfixes
+--------
+- trust_anchors.set_insecure: improve precision (#673, !1177)
+- plug memory leaks related to TCP (!1182)
+- policy.FLAGS: fix not applying properly in edge cases (!1179)
+- fix a crash with older libuv inside timer processing (!1195)
+
+Incompatible changes
+--------------------
+- see upgrading guide:
+ https://knot-resolver.readthedocs.io/en/stable/upgrading.html#to-5-4
+- legacy DoH implementation configuration in net.listen() was renamed from
+ kind="doh" to kind="doh_legacy" (!1180)
+
+
+Knot Resolver 5.3.2 (2021-05-05)
+================================
+
+Security
+--------
+- validator: fix 5.3.1 regression on over-limit NSEC3 edge case (!1169)
+ Assertion might be triggered by query/answer, potentially DoS.
+ CVE-2021-40083 was later assigned.
+
+Improvements
+------------
+- cache: improve handling write errors from LMDB (!1159)
+- doh2: improve handling of stream errors (!1164)
+
+Bugfixes
+--------
+- dnstap module: fix repeated configuration (!1168)
+- validator: fix SERVFAIL for some rare dynamic proofs (!1166)
+- fix SIGBUS on uncommon ARM machines (unaligned access; !1167, #426)
+- cache: better resilience on abnormal termination/restarts (!1172)
+- doh2: fix memleak on stream write failures (!1161)
+
+
+Knot Resolver 5.3.1 (2021-03-31)
+================================
+
+Improvements
+------------
+- policy.STUB: try to avoid TCP (compared to 5.3.0; !1155)
+- validator: downgrade NSEC3 records with too many iterations (>150; !1160)
+- additional improvements to nameserver selection algorithm (!1154, !1150)
+
+Bugfixes
+--------
+- dnstap module: don't break request resolution on dnstap errors (!1147)
+- cache garbage collector: fix crashes introduced in 5.3.0 (!1153)
+- policy.TLS_FORWARD: better avoid dead addresses (#671, !1156)
+
+
+Knot Resolver 5.3.0 (2021-02-25)
+================================
+
+Improvements
+------------
+- more consistency in using parent-side records for NS addresses (!1097)
+- better algorithm for choosing nameservers (!1030, !1126, !1140, !1141, !1143)
+- daf module: add daf.clear() (!1114)
+- dnstap module: more features and don't log internal requests (!1103)
+- dnstap module: include in upstream packages and Docker image (!1110, !1118)
+- randomize record order by default, i.e. reorder_RR(true) (!1124)
+- prometheus module: transform graphite tags into prometheus labels (!1109)
+- avoid excessive logging of UDP replies with sendmmsg (!1138)
+
+Bugfixes
+--------
+- view: fail config if bad subnet is specified (!1112)
+- doh2: fix memory leak (!1117)
+- policy.ANSWER: minor fixes, mainly around NODATA answers (!1129)
+- http, watchdog modules: fix stability problems (!1136)
+
+Incompatible changes
+--------------------
+- dnstap module: `log_responses` option gets nested under `client`;
+ see new docs for config example (!1103)
+- libknot >= 2.9 is required
+
+
+Knot Resolver 5.2.1 (2020-12-09)
+================================
+
+Improvements
+------------
+- doh2: send Cache-Control header with TTL (#617, !1095)
+
+Bugfixes
+--------
+- fix map() command on 32-bit platforms; regressed in 5.2.0 (!1093)
+- doh2: restrict endpoints to doh and dns-query (#636, !1104)
+- renumber: map to correct subnet when using multiple rules (!1107)
+
+
+Knot Resolver 5.2.0 (2020-11-11)
+================================
+
+Improvements
+------------
+- doh2: add native C module for DNS-over-HTTPS (#600, !997)
+- xdp: add server-side XDP support for higher UDP performance (#533, !1083)
+- lower default EDNS buffer size to 1232 bytes (#538, #300, !920);
+ see https://www.dnsflagday.net/2020/
+- net: split the EDNS buffer size into upstream and downstream (!1026)
+- lua-http doh: answer to /dns-query endpoint as well as /doh (!1069)
+- improve resiliency against UDP fragmentation attacks (disable PMTUD) (!1061)
+- ta_update: warn if there are differences between statically configured
+ keys and upstream (#251, !1051)
+- human readable output in interactive mode was improved
+- doc: generate info page (!1079)
+- packaging: improve sysusers and tmpfiles support (!1080)
+
+Bugfixes
+--------
+- avoid an assert() error in stash_rrset() (!1072)
+- fix emergency cache locking bug introduced in 5.1.3 (!1078)
+- migrate map() command to control sockets; fix systemd integration (!1000)
+- fix crash when sending back errors over control socket (!1000)
+- fix SERVFAIL while processing forwarded CNAME to a sibling zone (#614, !1070)
+
+Incompatible changes
+--------------------
+- see upgrading guide:
+ https://knot-resolver.readthedocs.io/en/stable/upgrading.html#to-5-2
+- minor changes in module API
+- control socket API commands have to be terminated by "\n"
+- graphite: default prefix now contains instance identifier (!1000)
+- build: meson >= 0.49 is required (!1082)
+
+
+Knot Resolver 5.1.3 (2020-09-08)
+================================
+
+Improvements
+------------
+- capabilities are no longer constrained when running as root (!1012)
+- cache: add percentage usage to cache.stats() (#580, !1025)
+- cache: add number of cache entries to cache.stats() (#510, !1028)
+- aarch64 support again, as some systems still didn't work (!1033)
+- support building against Knot DNS 3.0 (!1053)
+
+Bugfixes
+--------
+- tls: fix compilation to support net.tls_sticket_secret() (!1021)
+- validator: ignore bogus RRSIGs present in insecure domains (!1022, #587)
+- build if libsystemd version isn't detected as integer (#592, !1029)
+- validator: more robust reaction on missing RRSIGs (#390, !1020)
+- ta_update module: fix broken RFC5011 rollover (!1035)
+- garbage collector: avoid keeping multiple copies of cache (!1042)
+
+
+Knot Resolver 5.1.2 (2020-07-01)
+================================
+
+Bugfixes
+--------
+- hints module: NODATA answers also for non-address queries (!1005)
+- tls: send alert to peer if handshake fails (!1007)
+- cache: fix interaction between LMDB locks and preallocation (!1013)
+- cache garbage collector: fix flushing of messages to logs (!1009)
+- cache garbage collector: fix insufficient GC on 32-bit systems (!1009)
+- graphite module: do not block resolver on TCP failures (!1014)
+- policy.rpz various fixes (!1016): $ORIGIN issues,
+ precision of warnings, allow answering with multi-RR sets
+
+
+Knot Resolver 5.1.1 (2020-05-19)
+================================
+
+Security
+--------
+- fix CVE-2020-12667: mitigation for NXNSAttack DNS protocol vulnerability
+
+Bugfixes
+--------
+- control sockets: recognize newline as command boundary
+
+
+Knot Resolver 5.1.0 (2020-04-29)
+================================
+
+Improvements
+------------
+- cache garbage collector: reduce filesystem operations when idle (!946)
+- policy.DEBUG_ALWAYS and policy.DEBUG_IF for limited verbose logging (!957)
+- daemon: improve TCP query latency under heavy TCP load (!968)
+- add policy.ANSWER action (!964, #192)
+- policy.rpz support fake A/AAAA (!964, #194)
+
+Bugfixes
+--------
+- cache: missing filesystem support for pre-allocation is no longer fatal (#549)
+- lua: policy.rpz() no longer watches the file when watch is set to false (!954)
+- fix a strict aliasing problem that might've lead to "miscompilation" (!962)
+- fix handling of DNAMEs, especially signed ones (#234, !965)
+- lua resolve(): correctly include EDNS0 in the virtual packet (!963)
+ Custom modules might have been confused by that.
+- do not leak bogus data into SERVFAIL answers (#396)
+- improve random Lua number generator initialization (!979)
+- cache: fix CNAME caching when validation is disabled (#472, !974)
+- cache: fix CNAME caching in policy.STUB mode (!974)
+- prefill: fix crash caused by race condition with resolver startup (!983)
+- webmgmt: use javascript scheme detection for websockets' protocol (#546)
+- daf module: fix del(), deny(), drop(), tc(), pass() functions (#553, !966)
+- policy and daf modules: expose initial query when evaluating postrules (#556)
+- cache: fix some cases of caching answers over 4 KiB (!976)
+- docs: support sphinx 3.0.0+ (!978)
+
+Incompatible changes
+--------------------
+- minor changes in module API; see upgrading guide:
+ https://knot-resolver.readthedocs.io/en/stable/upgrading.html
+
+
+Knot Resolver 5.0.1 (2020-02-05)
+================================
+
+Bugfixes
+--------
+- systemd: use correct cache location for garbage collector (#543)
+
+Improvements
+------------
+- cache: add cache.fssize() lua function to configure entire free disk space on
+ dedicated cache partition (#524, !932)
+
+
+Knot Resolver 5.0.0 (2020-01-27)
+================================
+
+Incompatible changes
+--------------------
+- see upgrading guide: https://knot-resolver.readthedocs.io/en/stable/upgrading.html
+- systemd sockets are no longer supported (#485)
+- net.listen() throws an error if it fails to bind; use freebind option if needed
+- control socket location has changed (!922)
+- -f/--forks is deprecated (#529, !919)
+
+Improvements
+------------
+- logging: control-socket commands don't log unless --verbose (#528)
+- use SO_REUSEPORT_LB if available (FreeBSD 12.0+)
+- lua: remove dependency on lua-socket and lua-sec, used lua-http and cqueues (#512, #521, !894)
+- lua: remove dependency on lua-filesystem (#520, !912)
+- net.listen(): allow binding to non-local address with freebind option (!898)
+- cache: pre-allocate the file to avoid SIGBUS later (not macOS; !917, #525)
+- lua: be stricter around nonsense returned from modules (!901)
+- user documentation was reorganized and extended (!900, !867)
+- multiple config files can be used with --config/-c option (!909)
+- lua: stop trying to tweak lua's GC (!201)
+- systemd: add SYSTEMD_INSTANCE env variable to identify different instances (!906)
+
+Bugfixes
+--------
+- correctly use EDNS(0) padding in failed answers (!921)
+- policy and daf modules: fix postrules and reroute rules (!901)
+- renumber module: don't accidentally zero-out request's .state (!901)
+
+
+Knot Resolver 4.3.0 (2019-12-04)
+================================
+
+Security - CVE-2019-19331
+-------------------------
+- fix speed of processing large RRsets (DoS, #518)
+- improve CNAME chain length accounting (DoS, !899)
+
+Bugfixes
+--------
+- http module: use SO_REUSEPORT (!879)
+- systemd: kresd@.service now properly starts after network interfaces
+ have been configured with IP addresses after reboot (!884)
+- sendmmsg: improve reliability (!704)
+- cache: fix crash on insertion via lua for NS and CNAME (!889)
+- rpm package: move root.keys to /var/lib/knot-resolver (#513, !888)
+
+Improvements
+------------
+- increase file-descriptor count limit to maximum allowed value (hard limit; !876)
+- watchdog module: support testing a DNS query (and switch C -> lua; !878, !881)
+- performance: use sendmmsg syscall towards clients by default (!877)
+- performance: avoid excessive getsockname() syscalls (!854)
+- performance: lua-related improvements (!874)
+- daemon now attempts to drop all capabilities (!896)
+- reduce CNAME chain length limit - now <= 12 (!899)
+
+
+Knot Resolver 4.2.2 (2019-10-07)
+================================
+
+Bugfixes
+--------
+- lua bindings: fix a 4.2.1 regression on 32-bit systems (#514)
+ which also fixes libknot 2.9 support on all systems
+
+
+Knot Resolver 4.2.1 (2019-09-26)
+================================
+
+Bugfixes
+--------
+- rebinding module: fix handling some requests, respect ALLOW_LOCAL flag
+- fix incorrect SERVFAIL on cached bogus answer for +cd request (!860)
+ (regression since 4.1.0 release, in less common cases)
+- prefill module: allow a different module-loading style (#506)
+- validation: trim TTLs by RRSIG's expiration and original TTL (#319, #504)
+- NS choice algorithm: fix a regression since 4.0.0 (#497, !868)
+- policy: special domains home.arpa. and local. get NXDOMAIN (!855)
+
+Improvements
+------------
+- add compatibility with (future) libknot 2.9
+
+
+Knot Resolver 4.2.0 (2019-08-05)
+================================
+
+Improvements
+------------
+- queries without RD bit set are REFUSED by default (!838)
+- support forwarding to multiple targets (!825)
+
+Bugfixes
+--------
+- tls_client: fix issue with TLS session resumption (#489)
+- rebinding module: fix another false-positive assertion case (!851)
+
+Module API changes
+------------------
+- kr_request::add_selected is now really put into answer,
+ instead of the "duplicate" ::additional field (#490)
+
+
+Knot Resolver 4.1.0 (2019-07-10)
+================================
+
+Security
+--------
+- fix CVE-2019-10190: do not pass bogus negative answer to client (!827)
+- fix CVE-2019-10191: do not cache negative answer with forged QNAME+QTYPE (!839)
+
+Improvements
+------------
+- new cache garbage collector is available and enabled by default (#257)
+ This improves cache efficiency on big installations.
+- DNS-over-HTTPS: unknown HTTP parameters are ignored to improve compatibility
+ with non-standard clients (!832)
+- DNS-over-HTTPS: answers include `access-control-allow-origin: *` (!823)
+ which allows JavaScript to use DoH endpoint.
+- http module: support named AF_UNIX stream sockets (again)
+- aggressive caching is disabled on minimal NSEC* ranges (!826)
+ This improves cache effectivity with DNSSEC black lies and also accidentally
+ works around bug in proofs-of-nonexistence from F5 BIG-IP load-balancers.
+- aarch64 support, even kernels with ARM64_VA_BITS >= 48 (#216, !797)
+ This is done by working around a LuaJIT incompatibility. Please report bugs.
+- lua tables for C modules are more strict by default, e.g. `nsid.foo`
+ will throw an error instead of returning `nil` (!797)
+- systemd: basic watchdog is now available and enabled by default (#275)
+
+Bugfixes
+--------
+- TCP to upstream: fix unlikely case of sending out wrong message length (!816)
+- http module: fix problems around maintenance of ephemeral certs (!819)
+- http module: also send intermediate TLS certificate to clients,
+ if available and luaossl >= 20181207 (!819)
+- send EDNS with SERVFAILs, e.g. on validation failures (#180, !827)
+- prefill module: avoid crash on empty zone file (#474, !840)
+- rebinding module: avoid excessive iteration on blocked attempts (!842)
+- rebinding module: fix crash caused by race condition (!842)
+- rebinding module: log each blocked query only in verbose mode (!842)
+- cache: automatically clear stale reader locks (!844)
+
+
+Module API changes
+------------------
+- lua modules may omit casting parameters of layer functions (!797)
+
+
+Knot Resolver 4.0.0 (2019-04-18)
+================================
+
+Incompatible changes
+--------------------
+- see upgrading guide: https://knot-resolver.readthedocs.io/en/stable/upgrading.html
+- configuration: trust_anchors aliases .file, .config() and .negative were removed (!788)
+- configuration: trust_anchors.keyfile_default is no longer accessible (!788)
+- daemon: -k/--keyfile and -K/--keyfile-ro options were removed
+- meson build system is now used for builds (!771)
+- build with embedded LMBD is no longer supported
+- default modules dir location has changed
+- DNSSEC is enabled by default
+- upstream packages for Debian now require systemd
+- libknot >= 2.8 is required
+- net.list() output format changed (#448)
+- net.listen() reports error when address-port pair is in use
+- bind to DNS-over-TLS port by default (!792)
+- stop versioning libkres library
+- default port for web management and APIs changed to 8453
+
+Improvements
+------------
+- policy.TLS_FORWARD: if hostname is configured, send it on wire (!762)
+- hints module: allow configuring the TTL and change default from 0 to 5s
+- policy module: policy.rpz() will watch the file for changes by default
+- packaging: lua cqueues added to default dependencies where available
+- systemd: service is no longer auto-restarted on configuration errors
+- always send DO+CD flags upstream, even in insecure zones (#153)
+- cache.stats() output is completely new; see docs (!775)
+- improve usability of table_print() (!790, !801)
+- add DNS-over-HTTPS support (#280)
+- docker image supports and exposes DNS-over-HTTPS
+
+Bugfixes
+--------
+- predict module: load stats module if config didn't specify period (!755)
+- trust_anchors: don't do 5011-style updates on anchors from files
+ that were loaded as unmanaged trust anchors (!753)
+- trust_anchors.add(): include these TAs in .summary() (!753)
+- policy module: support '#' for separating port numbers, for consistency
+- fix startup on macOS+BSD when </dev/null and cqueues installed
+- policy.RPZ: log problems from zone-file level of parser as well (#453)
+- fix flushing of messages to logs in some cases (notably systemd) (!781)
+- fix fallback when SERVFAIL or REFUSED is received from upstream (!784)
+- fix crash when dealing with unknown TA key algorithm (#449)
+- go insecure due to algorithm support even if DNSKEY is NODATA (!798)
+- fix mac addresses in the output of net.interfaces() command (!804)
+- http module: fix too early renewal of ephemeral certificates (!808)
+
+Module API changes
+------------------
+- kr_straddr_split() changed API a bit (compiler will catch that)
+- C modules defining `*_layer` or `*_props` symbols need to change a bit
+ See the upgrading guide for details. It's detected on module load.
+
+
+Knot Resolver 3.2.1 (2019-01-10)
+================================
+
+Bugfixes
+--------
+- trust_anchors: respect validity time range during TA bootstrap (!748)
+- fix TLS rehandshake handling (!739)
+- make TLS_FORWARD compatible with GnuTLS 3.3 (!741)
+- special thanks to Grigorii Demidov for his long-term work on Knot Resolver!
+
+Improvements
+------------
+- improve handling of timed out outgoing TCP connections (!734)
+- trust_anchors: check syntax of public keys in DNSKEY RRs (!748)
+- validator: clarify message about bogus non-authoritative data (!735)
+- dnssec validation failures contain more verbose reasoning (!735)
+- new function trust_anchors.summary() describes state of DNSSEC TAs (!737),
+ and logs new state of trust anchors after start up and automatic changes
+- trust anchors: refuse revoked DNSKEY even if specified explicitly,
+ and downgrade missing the SEP bit to a warning
+
+
+Knot Resolver 3.2.0 (2018-12-17)
+================================
+
+New features
+------------
+- module edns_keepalive to implement server side of RFC 7828 (#408)
+- module nsid to implement server side of RFC 5001 (#289)
+- module bogus_log provides .frequent() table (!629, credit Ulrich Wisser)
+- module stats collects flags from answer messages (!629, credit Ulrich Wisser)
+- module view supports multiple rules with identical address/TSIG specification
+ and keeps trying rules until a "non-chain" action is executed (!678)
+- module experimental_dot_auth implements an DNS-over-TLS to auth protocol
+ (!711, credit Manu Bretelle)
+- net.bpf bindings allow advanced users to use eBPF socket filters
+
+Bugfixes
+--------
+- http module: only run prometheus in parent process if using --forks=N,
+ as the submodule collects metrics from all sub-processes as well.
+- TLS fixes for corner cases (!700, !714, !716, !721, !728)
+- fix build with -DNOVERBOSELOG (#424)
+- policy.{FORWARD,TLS_FORWARD,STUB}: respect net.ipv{4,6} setting (!710)
+- avoid SERVFAILs due to certain kind of NS dependency cycles, again
+ (#374) this time seen as 'circular dependency' in verbose logs
+- policy and view modules do not overwrite result finished requests (!678)
+
+Improvements
+------------
+- Dockerfile: rework, basing on Debian instead of Alpine
+- policy.{FORWARD,TLS_FORWARD,STUB}: give advantage to IPv6
+ when choosing whom to ask, just as for iteration
+- use pseudo-randomness from gnutls instead of internal ISAAC (#233)
+- tune the way we deal with non-responsive servers (!716, !723)
+- documentation clarifies interaction between policy and view modules (!678, !730)
+
+Module API changes
+------------------
+- new layer is added: answer_finalize
+- kr_request keeps ::qsource.packet beyond the begin layer
+- kr_request::qsource.tcp renamed to ::qsource.flags.tcp
+- kr_request::has_tls renamed to ::qsource.flags.tls
+- kr_zonecut_add(), kr_zonecut_del() and kr_nsrep_sort() changed parameters slightly
+
+
+Knot Resolver 3.1.0 (2018-11-02)
+================================
+
+Incompatible changes
+--------------------
+- hints.use_nodata(true) by default; that's what most users want
+- libknot >= 2.7.2 is required
+
+Improvements
+------------
+- cache: handle out-of-space SIGBUS slightly better (#197)
+- daemon: improve TCP timeout handling (!686)
+
+Bugfixes
+--------
+- cache.clear('name'): fix some edge cases in API (#401)
+- fix error handling from TLS writes (!669)
+- avoid SERVFAILs due to certain kind of NS dependency cycles (#374)
+
+
+Knot Resolver 3.0.0 (2018-08-20)
+================================
+
+Incompatible changes
+--------------------
+- cache: fail lua operations if cache isn't open yet (!639)
+ By default cache is opened *after* reading the configuration,
+ and older versions were silently ignoring cache operations.
+ Valid configuration must open cache using `cache.open()` or `cache.size =`
+ before executing cache operations like `cache.clear()`.
+- libknot >= 2.7.1 is required, which brings also larger API changes
+- in case you wrote custom Lua modules, please consult
+ https://knot-resolver.readthedocs.io/en/latest/lib.html#incompatible-changes-since-3-0-0
+- in case you wrote custom C modules, please see compile against
+ Knot DNS 2.7 and adjust your module according to messages from C compiler
+- DNS cookie module (RFC 7873) is not available in this release,
+ it will be later reworked to reflect development in IEFT dnsop working group
+- version module was permanently removed because it was not really used by users;
+ if you want to receive notifications about new releases please subscribe to
+ https://lists.nic.cz/postorius/lists/knot-resolver-announce.lists.nic.cz/
+
+Bugfixes
+--------
+- fix multi-process race condition in trust anchor maintenance (!643)
+- ta_sentinel: also consider static trust anchors not managed via RFC 5011
+
+Improvements
+------------
+- reorder_RR() implementation is brought back
+- bring in performance improvements provided by libknot 2.7
+- cache.clear() has a new, more powerful API
+- cache documentation was improved
+- old name "Knot DNS Resolver" is replaced by unambiguous "Knot Resolver"
+ to prevent confusion with "Knot DNS" authoritative server
+
+
+Knot Resolver 2.4.1 (2018-08-02)
+================================
+
+Security
+--------
+- fix CVE-2018-10920: Improper input validation bug in DNS resolver component
+ (security!7, security!9)
+
+Bugfixes
+--------
+- cache: fix TTL overflow in packet due to min_ttl (#388, security!8)
+- TLS session resumption: avoid bad scheduling of rotation (#385)
+- HTTP module: fix a regression in 2.4.0 which broke custom certs (!632)
+- cache: NSEC3 negative cache even without NS record (#384)
+ This fixes lower hit rate in NSEC3 zones (since 2.4.0).
+- minor TCP and TLS fixes (!623, !624, !626)
+
+
+Knot Resolver 2.4.0 (2018-07-03)
+================================
+
+Incompatible changes
+--------------------
+- minimal libknot version is now 2.6.7 to pull in latest fixes (#366)
+
+Security
+--------
+- fix a rare case of zones incorrectly downgraded to insecure status (!576)
+
+New features
+------------
+- TLS session resumption (RFC 5077), both server and client (!585, #105)
+ (disabled when compiling with gnutls < 3.5)
+- TLS_FORWARD policy uses system CA certificate store by default (!568)
+- aggressive caching for NSEC3 zones (!600)
+- optional protection from DNS Rebinding attack (module rebinding, !608)
+- module bogus_log to log DNSSEC bogus queries without verbose logging (!613)
+
+Bugfixes
+--------
+- prefill: fix ability to read certificate bundle (!578)
+- avoid turning off qname minimization in some cases, e.g. co.uk. (#339)
+- fix validation of explicit wildcard queries (#274)
+- dns64 module: more properties from the RFC implemented (incl. bug #375)
+
+Improvements
+------------
+- systemd: multiple enabled kresd instances can now be started using kresd.target
+- ta_sentinel: switch to version 14 of the RFC draft (!596)
+- support for glibc systems with a non-Linux kernel (!588)
+- support per-request variables for Lua modules (!533)
+- support custom HTTP endpoints for Lua modules (!527)
+
+
+Knot Resolver 2.3.0 (2018-04-23)
+================================
+
+Security
+--------
+- fix CVE-2018-1110: denial of service triggered by malformed DNS messages
+ (!550, !558, security!2, security!4)
+- increase resilience against slow lorris attack (security!5)
+
+New features
+------------
+- new policy.REFUSE to reply REFUSED to clients
+
+Bugfixes
+--------
+- validation: fix SERVFAIL in case of CNAME to NXDOMAIN in a single zone (!538)
+- validation: fix SERVFAIL for DS . query (!544)
+- lib/resolve: don't send unnecessary queries to parent zone (!513)
+- iterate: fix validation for zones where parent and child share NS (!543)
+- TLS: improve error handling and documentation (!536, !555, !559)
+
+Improvements
+------------
+- prefill: new module to periodically import root zone into cache
+ (replacement for RFC 7706, !511)
+- network_listen_fd: always create end point for supervisor supplied file descriptor
+- use CPPFLAGS build environment variable if set (!547)
+
+
+Knot Resolver 2.2.0 (2018-03-28)
+================================
+
+New features
+------------
+- cache server unavailability to prevent flooding unreachable servers
+ (Please note that caching algorithm needs further optimization
+ and will change in further versions but we need to gather operational
+ experience first.)
+
+Bugfixes
+--------
+- don't magically -D_FORTIFY_SOURCE=2 in some cases
+- allow large responses for outbound over TCP
+- fix crash with RR sets with over 255 records
+
+
+Knot Resolver 2.1.1 (2018-02-23)
+================================
+
+Bugfixes
+--------
+- when iterating, avoid unnecessary queries for NS in insecure parent.
+ This problem worsened in 2.0.0. (#246)
+- prevent UDP packet leaks when using TLS forwarding
+- fix the hints module also on some other systems, e.g. Gentoo.
+
+
+Knot Resolver 2.1.0 (2018-02-16)
+================================
+
+Incompatible changes
+--------------------
+- stats: remove tracking of expiring records (predict uses another way)
+- systemd: re-use a single kresd.socket and kresd-tls.socket
+- ta_sentinel: implement protocol draft-ietf-dnsop-kskroll-sentinel-01
+ (our draft-ietf-dnsop-kskroll-sentinel-00 implementation had inverted logic)
+- libknot: require version 2.6.4 or newer to get bugfixes for DNS-over-TLS
+
+Bugfixes
+--------
+- detect_time_jump module: don't clear cache on suspend-resume (#284)
+- stats module: fix stats.list() returning nothing, regressed in 2.0.0
+- policy.TLS_FORWARD: refusal when configuring with multiple IPs (#306)
+- cache: fix broken refresh of insecure records that were about to expire
+- fix the hints module on some systems, e.g. Fedora (came back on 2.0.0)
+- build with older gnutls (conditionally disable features)
+- fix the predict module to work with insecure records & cleanup code
+
+
+Knot Resolver 2.0.0 (2018-01-31)
+================================
+
+Incompatible changes
+--------------------
+- systemd: change unit files to allow running multiple instances,
+ deployments with single instance now must use `kresd@1.service`
+ instead of `kresd.service`; see kresd.systemd(7) for details
+- systemd: the directory for cache is now /var/cache/knot-resolver
+- unify default directory and user to `knot-resolver`
+- directory with trust anchor file specified by -k option must be writeable
+- policy module is now loaded by default to enforce RFC 6761;
+ see documentation for policy.PASS if you use locally-served DNS zones
+- drop support for alternative cache backends memcached, redis,
+ and for Lua bindings for some specific cache operations
+- REORDER_RR option is not implemented (temporarily)
+
+New features
+------------
+- aggressive caching of validated records (RFC 8198) for NSEC zones;
+ thanks to ICANN for sponsoring this work.
+- forwarding over TLS, authenticated by SPKI pin or certificate.
+ policy.TLS_FORWARD pipelines queries out-of-order over shared TLS connection
+ Beware: Some resolvers do not support out-of-order query processing.
+ TLS forwarding to such resolvers will lead to slower resolution or failures.
+- trust anchors: you may specify a read-only file via -K or --keyfile-ro
+- trust anchors: at build-time you may set KEYFILE_DEFAULT (read-only)
+- ta_sentinel module implements draft ietf-dnsop-kskroll-sentinel-00,
+ enabled by default
+- serve_stale module is prototype, subject to change
+- extended API for Lua modules
+
+Bugfixes
+--------
+- fix build on osx - regressed in 1.5.3 (different linker option name)
+
+
+Knot Resolver 1.5.3 (2018-01-23)
+================================
+
+Bugfixes
+--------
+- fix the hints module on some systems, e.g. Fedora.
+ Symptom: `undefined symbol: engine_hint_root_file`
+
+
+Knot Resolver 1.5.2 (2018-01-22)
+================================
+
+Security
+--------
+- fix CVE-2018-1000002: insufficient DNSSEC validation, allowing
+ attackers to deny existence of some data by forging packets.
+ Some combinations pointed out in RFC 6840 sections 4.1 and 4.3
+ were not taken into account.
+
+Bugfixes
+--------
+- memcached: fix fallout from module rename in 1.5.1
+
+
+Knot Resolver 1.5.1 (2017-12-12)
+================================
+
+Incompatible changes
+--------------------
+- script supervisor.py was removed, please migrate to a real process manager
+- module ketcd was renamed to etcd for consistency
+- module kmemcached was renamed to memcached for consistency
+
+Bugfixes
+--------
+- fix SIGPIPE crashes (#271)
+- tests: work around out-of-space for platforms with larger memory pages
+- lua: fix mistakes in bindings affecting 1.4.0 and 1.5.0 (and 1.99.1-alpha),
+ potentially causing problems in dns64 and workarounds modules
+- predict module: various fixes (!399)
+
+Improvements
+------------
+- add priming module to implement RFC 8109, enabled by default (#220)
+- add modules helping with system time problems, enabled by default;
+ for details see documentation of detect_time_skew and detect_time_jump
+
+
+Knot Resolver 1.5.0 (2017-11-02)
+================================
+
+Bugfixes
+--------
+- fix loading modules on Darwin
+
+Improvements
+------------
+- new module ta_signal_query supporting Signaling Trust Anchor Knowledge
+ using Keytag Query (RFC 8145 section 5); it is enabled by default
+- attempt validation for more records but require it for fewer of them
+ (e.g. avoids SERVFAIL when server adds extra records but omits RRSIGs)
+
+
+Knot Resolver 1.99.1-alpha (2017-10-26)
+=======================================
+This is an experimental release meant for testing aggressive caching.
+It contains some regressions and might (theoretically) be even vulnerable.
+The current focus is to minimize queries into the root zone.
+
+Improvements
+------------
+- negative answers from validated NSEC (NXDOMAIN, NODATA)
+- verbose log is very chatty around cache operations (maybe too much)
+
+Regressions
+-----------
+- dropped support for alternative cache backends
+ and for some specific cache operations
+- caching doesn't yet work for various cases:
+ * negative answers without NSEC (i.e. with NSEC3 or insecure)
+ * +cd queries (needs other internal changes)
+ * positive wildcard answers
+- spurious SERVFAIL on specific combinations of cached records, printing:
+ <= bad keys, broken trust chain
+- make check
+- a few Deckard tests are broken, probably due to some problems above
+- also unknown ones?
+
+
+
+Knot Resolver 1.4.0 (2017-09-22)
+================================
+
+Incompatible changes
+--------------------
+- lua: query flag-sets are no longer represented as plain integers.
+ kres.query.* no longer works, and kr_query_t lost trivial methods
+ 'hasflag' and 'resolved'.
+ You can instead write code like qry.flags.NO_0X20 = true.
+
+Bugfixes
+--------
+- fix exiting one of multiple forks (#150)
+- cache: change the way of using LMDB transactions. That in particular
+ fixes some cases of using too much space with multiple kresd forks (#240).
+
+Improvements
+------------
+- policy.suffix: update the aho-corasick code (#200)
+- root hints are now loaded from a zonefile; exposed as hints.root_file().
+ You can override the path by defining ROOTHINTS during compilation.
+- policy.FORWARD: work around resolvers adding unsigned NS records (#248)
+- reduce unneeded records previously put into authority in wildcarded answers
+
+
+Knot Resolver 1.3.3 (2017-08-09)
+================================
+
+Security
+--------
+- Fix a critical DNSSEC flaw. Signatures might be accepted as valid
+ even if the signed data was not in bailiwick of the DNSKEY used to
+ sign it, assuming the trust chain to that DNSKEY was valid.
+
+Bugfixes
+--------
+- iterate: skip RRSIGs with bad label count instead of immediate SERVFAIL
+- utils: fix possible incorrect seeding of the random generator
+- modules/http: fix compatibility with the Prometheus text format
+
+Improvements
+------------
+- policy: implement remaining special-use domain names from RFC6761 (#205),
+ and make these rules apply only if no other non-chain rule applies
+
+
+Knot Resolver 1.3.2 (2017-07-28)
+================================
+
+Security
+--------
+- fix possible opportunities to use insecure data from cache as keys
+ for validation
+
+Bugfixes
+--------
+- daemon: check existence of config file even if rundir isn't specified
+- policy.FORWARD and STUB: use RTT tracking to choose servers (#125, #208)
+- dns64: fix CNAME problems (#203) It still won't work with policy.STUB.
+- hints: better interpretation of hosts-like files (#204)
+ also, error out if a bad entry is encountered in the file
+- dnssec: handle unknown DNSKEY/DS algorithms (#210)
+- predict: fix the module, broken since 1.2.0 (#154)
+
+Improvements
+------------
+- embedded LMDB fallback: update 0.9.18 -> 0.9.21
+
+
+Knot Resolver 1.3.1 (2017-06-23)
+================================
+
+Bugfixes
+--------
+- modules/http: fix finding the static files (bug from 1.3.0)
+- policy.FORWARD: fix some cases of CNAMEs obstructing search for zone cuts
+
+
+Knot Resolver 1.3.0 (2017-06-13)
+================================
+
+Security
+--------
+- Refactor handling of AD flag and security status of resource records.
+ In some cases it was possible for secure domains to get cached as
+ insecure, even for a TLD, leading to disabled validation.
+ It also fixes answering with non-authoritative data about nameservers.
+
+Improvements
+------------
+- major feature: support for forwarding with validation (#112).
+ The old policy.FORWARD action now does that; the previous non-validating
+ mode is still available as policy.STUB except that also uses caching (#122).
+- command line: specify ports via @ but still support # for compatibility
+- policy: recognize 100.64.0.0/10 as local addresses
+- layer/iterate: *do* retry repeatedly if REFUSED, as we can't yet easily
+ retry with other NSs while avoiding retrying with those who REFUSED
+- modules: allow changing the directory where modules are found,
+ and do not search the default library path anymore.
+
+Bugfixes
+--------
+- validate: fix insufficient caching for some cases (relatively rare)
+- avoid putting "duplicate" record-sets into the answer (#198)
+
+
+Knot Resolver 1.2.6 (2017-04-24)
+================================
+
+Security
+--------
+- dnssec: don't set AD flag for NODATA answers if wildcard non-existence
+ is not guaranteed due to opt-out in NSEC3
+
+Improvements
+------------
+- layer/iterate: don't retry repeatedly if REFUSED
+
+Bugfixes
+--------
+- lib/nsrep: revert some changes to NS reputation tracking that caused
+ severe problems to some users of 1.2.5 (#178 and #179)
+- dnssec: fix verification of wildcarded non-singleton RRsets
+- dnssec: allow wildcards located directly under the root
+- layer/rrcache: avoid putting answer records into queries in some cases
+
+
+Knot Resolver 1.2.5 (2017-04-05)
+================================
+
+Security
+--------
+- layer/validate: clear AD if closest encloser proof has opt-outed
+ NSEC3 (#169)
+- layer/validate: check if NSEC3 records in wildcard expansion proof
+ has an opt-out
+- dnssec/nsec: missed wildcard no-data answers validation has been
+ implemented
+
+Improvements
+------------
+- modules/dnstap: a DNSTAP support module
+ (Contributed by Vicky Shrestha)
+- modules/workarounds: a module adding workarounds for known
+ DNS protocol violators
+- layer/iterate: fix logging of glue addresses
+- kr_bitcmp: allow bits=0 and consequently 0.0.0.0/0 matches in view
+ and renumber modules.
+- modules/padding: Improve default padding of responses
+ (Contributed by Daniel Kahn Gillmor)
+- New kresc client utility (experimental; don't rely on the API yet)
+
+Bugfixes
+--------
+- trust anchors: Improve trust anchors storage format (#167)
+- trust anchors: support non-root TAs, one domain per file
+- policy.DENY: set AA flag and clear AD flag
+- lib/resolve: avoid unnecessary DS queries
+- lib/nsrep: don't treat servers with NOIP4 + NOIP6 flags as timed out
+- layer/iterate: During packet classification (answer vs. referral)
+ don't analyze AUTHORITY section in authoritative answer if ANSWER
+ section contains records that have been requested
+
+
+Knot Resolver 1.2.4 (2017-03-09)
+================================
+
+Security
+--------
+- Knot Resolver 1.2.0 and higher could return AD flag for insecure
+ answer if the daemon received answer with invalid RRSIG several
+ times in a row.
+
+Improvements
+------------
+- modules/policy: allow QTRACE policy to be chained with other
+ policies
+- hints.add_hosts(path): a new property
+- module: document the API and simplify the code
+- policy.MIRROR: support IPv6 link-local addresses
+- policy.FORWARD: support IPv6 link-local addresses
+- add net.outgoing_{v4,v6} to allow specifying address to use for
+ connections
+
+Bugfixes
+--------
+- layer/iterate: some improvements in cname chain unrolling
+- layer/validate: fix duplicate records in AUTHORITY section in case
+ of WC expansion proof
+- lua: do *not* truncate cache size to unsigned
+- forwarding mode: correctly forward +cd flag
+- fix a potential memory leak
+- don't treat answers that contain DS non-existence proof as insecure
+- don't store NSEC3 and their signatures in the cache
+- layer/iterate: when processing delegations, check if qname is at or
+ below new authority
+
+
+Knot Resolver 1.2.3 (2017-02-23)
+================================
+
+Bugfixes
+--------
+- Disable storing GLUE records into the cache even in the
+ (non-default) QUERY_PERMISSIVE mode
+- iterate: skip answer RRs that don't match the query
+- layer/iterate: some additional processing for referrals
+- lib/resolve: zonecut fetching error was fixed
+
+
+Knot Resolver 1.2.2 (2017-02-10)
+================================
+
+Bugfixes:
+---------
+- Fix -k argument processing to avoid out-of-bounds memory accesses
+- lib/resolve: fix zonecut fetching for explicit DS queries
+- hints: more NULL checks
+- Fix TA bootstrapping for multiple TAs in the IANA XML file
+
+Testing:
+--------
+- Update tests to run tests with and without QNAME minimization
+
+
+Knot Resolver 1.2.1 (2017-02-01)
+====================================
+
+Security:
+---------
+- Under certain conditions, a cached negative answer from a CD query
+ would be reused to construct response for non-CD queries, resulting
+ in Insecure status instead of Bogus. Only 1.2.0 release was affected.
+
+Documentation
+-------------
+- Update the typo in the documentation: The query trace policy is
+ named policy.QTRACE (and not policy.TRACE)
+
+Bugfixes:
+---------
+- lua: make the map command check its arguments
+
+
+Knot Resolver 1.2.0 (2017-01-24)
+====================================
+
+Security:
+---------
+- In a policy.FORWARD() mode, the AD flag was being always set by mistake.
+ It is now cleared, as the policy.FORWARD() doesn't do DNSSEC validation yet.
+
+Improvements:
+-------------
+- The DNSSEC Validation has been refactored, fixing many resolving
+ failures.
+- Add module `version` that checks for updates and CVEs periodically.
+- Support RFC7830: EDNS(0) padding in responses over TLS.
+- Support CD flag on incoming requests.
+- hints module: previously /etc/hosts was loaded by default, but not anymore.
+ Users can now actually avoid loading any file.
+- DNS over TLS now creates ephemeral certs.
+- Configurable cache.{min,max}_ttl option, with max_ttl defaulting to 6 days.
+- Option to reorder RRs in the response.
+- New policy.QTRACE policy to print packet contents
+
+Bugfixes:
+---------
+- Trust Anchor configuration is now more robust.
+- Correctly answer NOTIMPL for meta-types and non-IN RR classes.
+- Free TCP buffer on cancelled connection.
+- Fix crash in hints module on empty hints file, and fix non-lowercase hints.
+
+Miscellaneous:
+--------------
+- It now requires knot >= 2.3.1 to link successfully.
+- The API+ABI for modules changed slightly.
+- New LRU implementation.
+
+
+Knot Resolver 1.1.1 (2016-08-24)
+================================
+
+Bugfixes:
+---------
+ - Fix 0x20 randomization with retransmit
+ - Fix pass-through for the stub mode
+ - Fix the root hints IPv6 addresses
+ - Fix dst addr for retries over TCP
+
+Improvements:
+-------------
+ - Track RTT of all tried servers for faster retransmit
+ - DAF: Allow forwarding to custom port
+ - systemd: Read EnvironmentFile and user $KRESD_ARGS
+ - systemd: Update systemd units to be named after daemon
+
+
+Knot Resolver 1.1.0 (2016-08-12)
+================================
+
+Improvements:
+-------------
+ - RFC7873 DNS Cookies
+ - RFC7858 DNS over TLS
+ - HTTP/2 web interface, RESTful API
+ - Metrics exported in Prometheus
+ - DNS firewall module
+ - Explicit CNAME target fetching in strict mode
+ - Query minimisation improvements
+ - Improved integration with systemd
+
+
+Knot Resolver 1.0.0 (2016-05-30)
+================================
+
+Initial release:
+----------------
+ - The first initial release
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..76f9db3
--- /dev/null
+++ b/README.md
@@ -0,0 +1,75 @@
+# Knot Resolver
+
+[![Build Status](https://gitlab.nic.cz/knot/knot-resolver/badges/nightly/pipeline.svg?x)](https://gitlab.nic.cz/knot/knot-resolver/commits/nightly)
+[![Coverage Status](https://gitlab.nic.cz/knot/knot-resolver/badges/nightly/coverage.svg?x)](https://knot.pages.nic.cz/knot-resolver/)
+[![Documentation Status](https://readthedocs.org/projects/knot-resolver/badge/?version=latest)](https://readthedocs.org/projects/knot-resolver/?badge=latest)
+[![Packaging status](https://repology.org/badge/tiny-repos/knot-resolver.svg)](https://repology.org/project/knot-resolver/versions)
+
+Knot Resolver is a caching full resolver implementation written in C and [LuaJIT][luajit], both a resolver library and a daemon. The core architecture is tiny and efficient, and provides a foundation and
+a state-machine like API for extensions. There are three modules built-in - *iterator*, *validator*, *cache*, and a few more are loaded by default. Most of the [rich features](https://knot-resolver.readthedocs.io/en/latest/config-overview.html) are written in Lua(JIT) and C. Batteries are included, but optional.
+
+The LuaJIT modules, support DNS privacy and DNSSEC, and persistent cache with low memory footprint make it a great personal DNS resolver or a research tool to tap into DNS data. TL;DR it's the [OpenResty][openresty] of DNS.
+
+Strong filtering rules, and auto-configuration with etcd make it a great large-scale resolver solution.
+
+The server adopts a [different scaling strategy][scaling] than the rest of the DNS recursors - no threading, shared-nothing architecture (except MVCC cache that may be shared) that allows you to pin instances on available CPU cores and grow by self-replication. You can start and stop additional nodes depending on the contention without downtime.
+
+It also has strong support for DNS over TCP, notably TCP Fast-Open, query pipelining and deduplication, and response reordering.
+
+### Packages
+
+The latest stable packages for various distributions are available in our
+[upstream repository](https://build.opensuse.org/package/show/home:CZ-NIC:knot-resolver-latest/knot-resolver).
+Follow the
+[installation instructions](https://software.opensuse.org//download.html?project=home%3ACZ-NIC%3Aknot-resolver-latest&package=knot-resolver)
+to add this repository to your system.
+
+Knot Resolver is also available from the following distributions' repositories.
+
+* [Fedora and Fedora EPEL](https://src.fedoraproject.org/rpms/knot-resolver)
+* [Debian stable](https://packages.debian.org/stable/knot-resolver),
+ [Debian testing](https://packages.debian.org/testing/knot-resolver),
+ [Debian unstable](https://packages.debian.org/sid/knot-resolver)
+* [Ubuntu](https://packages.ubuntu.com/jammy/knot-resolver)
+* [Arch Linux](https://archlinux.org/packages/community/x86_64/knot-resolver/)
+* [Alpine Linux](https://pkgs.alpinelinux.org/packages?name=knot-resolver)
+
+### Building from sources
+
+Knot Resolver mainly [depends][depends] on Knot DNS libraries, [LuaJIT][luajit] and [libuv][libuv].
+See the [Building project][depends] documentation page for more information.
+
+### Docker image
+
+This is simple and doesn't require any dependencies or system modifications, just run:
+
+```
+$ docker run -Pit cznic/knot-resolver
+```
+
+The images are meant as an easy way to try knot-resolver, and they're not designed for production use.
+
+### Running
+
+The project builds a resolver library in the `lib` directory, and a daemon in the `daemon` directory. It requires no configuration or parameters to run a server on localhost.
+
+```
+$ kresd
+```
+
+See the documentation at [knot-resolver.readthedocs.io][doc] for more options.
+
+[depends]: https://knot-resolver.readthedocs.io/en/stable/build.html
+[doc]: https://knot-resolver.readthedocs.io/en/stable/index.html
+[scaling]: https://knot-resolver.readthedocs.io/en/stable/systemd-multiinst.html
+[deckard]: https://gitlab.nic.cz/knot/deckard
+[luajit]: https://luajit.org/
+[libuv]: http://libuv.org
+[openresty]: https://openresty.org/
+
+### Contacting us
+
+- [GitLab issues](https://gitlab.nic.cz/knot/knot-resolver/issues) (you may authenticate via GitHub)
+- [mailing list](https://lists.nic.cz/postorius/lists/knot-resolver-announce.lists.nic.cz/)
+- [![Join the chat at https://gitter.im/CZ-NIC/knot-resolver](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/CZ-NIC/knot-resolver?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
+
diff --git a/bench/bench_lru.c b/bench/bench_lru.c
new file mode 100644
index 0000000..06f77c0
--- /dev/null
+++ b/bench/bench_lru.c
@@ -0,0 +1,242 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#include <math.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <sys/time.h>
+#include <unistd.h>
+
+#include "contrib/ucw/lib.h"
+#include "daemon/engine.h"
+#include "lib/selection.h"
+
+typedef kr_nsrep_lru_t lru_bench_t;
+
+#define p_out(...) do { \
+ printf(__VA_ARGS__); \
+ fflush(stdout); \
+ } while (0)
+#define p_err(...) fprintf(stderr, __VA_ARGS__)
+
+#ifndef LRU_RTT_SIZE
+#define LRU_RTT_SIZE 65536 /**< NS RTT cache size */
+#endif
+
+static int die(const char *cause)
+{
+ fprintf(stderr, "%s: %s\n", cause, strerror(errno));
+ exit(1);
+}
+
+static void time_get(struct timeval *tv)
+{
+ if (gettimeofday(tv, NULL))
+ die("gettimeofday");
+}
+static void time_print_diff(struct timeval *tv, size_t op_count)
+{
+ struct timeval now;
+ time_get(&now);
+ now.tv_sec -= tv->tv_sec;
+ now.tv_usec -= tv->tv_usec;
+ if (now.tv_usec < 0) {
+ now.tv_sec -= 1;
+ now.tv_usec += 1000000;
+ }
+
+ size_t speed = round((double)(op_count) / 1000
+ / (now.tv_sec + (double)(now.tv_usec)/1000000));
+
+ p_out("%ld.%06d", now.tv_sec, (int)now.tv_usec);
+ p_err(" s"); p_out(","); p_err("\t");
+ p_out("%zd", speed);
+ p_err(" kops/s"); p_out(","); p_err("\n");
+}
+
+/// initialize seed for random()
+static int ssrandom(char *s)
+{
+ if (*s == '-') { // initialize from time
+ struct timeval now;
+ time_get(&now);
+ srandom(now.tv_sec * 1000000 + now.tv_usec);
+ return 0;
+ }
+
+ // initialize from a string
+ size_t len = strlen(s);
+ if (len < 12)
+ return(-1);
+ unsigned seed = s[0] | s[1] << 8 | s[2] << 16 | s[3] << 24;
+ initstate(seed, s+4, len-4);
+ return 0;
+}
+
+struct key {
+ size_t len;
+ char *chars;
+};
+
+/// read lines from a file and reorder them randomly
+static struct key * read_lines(const char *fname, size_t *count, char **pfree)
+{
+ // read the file at once
+ int fd = open(fname, O_RDONLY);
+ if (fd < 0)
+ die("open");
+ struct stat st;
+ if (fstat(fd, &st) < 0)
+ die("stat");
+ size_t flen = (size_t)st.st_size;
+ char *fbuf = malloc(flen + 1);
+ *pfree = fbuf;
+ if (fbuf == NULL)
+ die("malloc");
+ if (read(fd, fbuf, flen) < 0)
+ die("read");
+ close(fd);
+ fbuf[flen] = '\0';
+
+ // get pointers to individual lines
+ size_t lines = 0;
+ for (size_t i = 0; i < flen; ++i)
+ if (fbuf[i] == '\n') {
+ fbuf[i] = 0;
+ ++lines;
+ }
+ *count = lines;
+ size_t avg_len = (flen + 1) / lines - 1;
+
+ p_err("lines read: ");
+ p_out("%zu,", lines);
+ p_err("\taverage length ");
+ p_out("%zu,", avg_len);
+
+ struct key *result = calloc(lines, sizeof(struct key));
+ result[0].chars = fbuf;
+ for (size_t l = 0; l < lines; ++l) {
+ size_t i = 0;
+ while (result[l].chars[i])
+ ++i;
+ result[l].len = i;
+ if (l + 1 < lines)
+ result[l + 1].chars = result[l].chars + i + 1;
+ }
+
+ //return result;
+ // reorder the lines randomly (via "random select-sort")
+ // note: this makes their order non-sequential *in memory*
+ if (RAND_MAX < lines)
+ die("RAND_MAX is too small");
+ for (size_t i = 0; i < lines - 1; ++i) { // swap i with random j >= i
+ size_t j = i + random() % (lines - i);
+ if (j != i) {
+ struct key tmp = result[i];
+ result[i] = result[j];
+ result[j] = tmp;
+ }
+ }
+
+ return result;
+}
+
+// compatibility layer for the older lru_* names
+#ifndef lru_create
+ #define lru_get_new lru_set
+ #define lru_get_try lru_get
+#endif
+
+static void usage(const char *progname)
+{
+ p_err("usage: %s <log_count> <input> <seed> [lru_size]\n", progname);
+ p_err("The seed must be at least 12 characters or \"-\".\n"
+ "Standard output contains csv-formatted lines.\n");
+ exit(1);
+}
+
+
+int main(int argc, char ** argv)
+{
+ if (argc != 4 && argc != 5)
+ usage(argv[0]);
+ if (ssrandom(argv[3]) < 0)
+ usage(argv[0]);
+
+ p_out("\n");
+ size_t key_count;
+ char *data_to_free = NULL;
+ struct key *keys = read_lines(argv[2], &key_count, &data_to_free);
+ size_t run_count;
+ {
+ size_t run_log = atoi(argv[1]);
+ assert(run_log < 64);
+ run_count = 1ULL << run_log;
+ p_err("\ntest run length:\t2^");
+ p_out("%zd,", run_log);
+ }
+
+ struct timeval time;
+ const int lru_size = argc > 4 ? atoi(argv[4]) : LRU_RTT_SIZE;
+
+ lru_bench_t *lru;
+ #ifdef lru_create
+ lru_create(&lru, lru_size, NULL, NULL);
+ #else
+ lru = malloc(lru_size(lru_bench_t, lru_size));
+ if (lru)
+ lru_init(lru, lru_size);
+ #endif
+ if (!lru)
+ die("malloc");
+ p_err("\nLRU capacity:\t");
+ p_out("%d,",
+ #ifdef lru_capacity
+ lru_capacity(lru) // report real capacity, if provided
+ #else
+ lru_size
+ #endif
+ );
+
+ size_t miss = 0;
+ p_err("\nload everything:\t");
+ time_get(&time);
+ for (size_t i = 0, ki = key_count - 1; i < run_count; ++i, --ki) {
+ unsigned *r = lru_get_new(lru, keys[ki].chars, keys[ki].len, NULL);
+ if (!r || *r == 0)
+ ++miss;
+ if (r)
+ *r = 1;
+ if (unlikely(ki == 0))
+ ki = key_count;
+ }
+ time_print_diff(&time, run_count);
+ p_err("LRU misses [%%]:\t");
+ p_out("%zd,",(miss * 100 + 50) / run_count);
+ p_err("\n");
+
+ unsigned accum = 0; // compute something to make sure compiler can't remove code
+ p_err("search everything:\t");
+ time_get(&time);
+ for (size_t i = 0, ki = key_count - 1; i < run_count; ++i, --ki) {
+ unsigned *r = lru_get_try(lru, keys[ki].chars, keys[ki].len);
+ if (r)
+ accum += *r;
+ if (unlikely(ki == 0))
+ ki = key_count;
+ }
+ time_print_diff(&time, run_count);
+ p_err("ignore: %u\n", accum);
+
+ // free memory, at least with new LRU
+ #ifdef lru_create
+ lru_free(lru);
+ #endif
+ free(keys);
+ free(data_to_free);
+
+ return 0;
+}
+
diff --git a/bench/bench_lru_set1.tsv b/bench/bench_lru_set1.tsv
new file mode 100644
index 0000000..7cb2351
--- /dev/null
+++ b/bench/bench_lru_set1.tsv
@@ -0,0 +1,65536 @@
+thumbs2.ebaystatic.com.
+mountaineerpublishing.com.
+www.mediafire.com.
+s-static.ak.fbcdn.net.
+lachicabionica.com.
+www.freemarket.com.
+sip.hotmail.com.
+www.cangrejas.com.
+google.com.
+cache.defamer.com.
+developers.facebook.com.
+www.eucarvet.eu.
+mail.mobilni-telefony.biz.
+microsoft-powerpoint-2010.softonic.it.
+profile.ak.fbcdn.net.
+www.zunescene.mobi.
+ads.smowtion.com.
+196.127.197.94.in-addr.arpa.
+armandi.ru.
+solofarandulaperu.blogspot.com.
+m.addthisedge.com.
+ssl.google-analytics.com.
+243.35.149.83.in-addr.arpa.
+105.138.138.201.in-addr.arpa.
+www.reuters.com.
+mail.sodoit.com.
+www.download.windowsupdate.com.
+resquare.ca.
+photos-e.ak.fbcdn.net.
+csi.gstatic.com.
+www.darty.lu.
+6138.7370686f746f73.616b.666263646e.6e6574.80h3f617b3a.webcfs00.com.
+frycomm.com.s9b2.psmtp.com.
+www.apple.com.
+www.haacked.com.
+www.jujiaow.com.
+170.44.153.187.in-addr.arpa.
+a1007.w43.akamai.net.
+api.facebook.com.
+dns.msftncsi.com.
+sageinc.com.
+a.root-servers.net.
+google.com.
+photos-a.ak.fbcdn.net.
+developers.facebook.com.
+a995.mm1.akamai.net.
+a.root-servers.net.
+api.twitter.com.
+a.root-servers.net.
+pub.reggaefrance.com.
+an.d.chango.com.
+mogesa.com.mx.
+0.11-a3092481.20483.1518.18a4.3ea1.410.0.ezg6u89nikkw32n9ssr1pcd8ei.avqs.mcafee.com.
+www.gossiponthis.com.
+www.asil.com.ar.
+mail.mastertex.com.
+www.foxsportsla.com.
+profile.ak.fbcdn.net.
+picture.immobilienscout24.de.
+138.191.114.187.in-addr.arpa.
+71.209.110.187.in-addr.arpa.
+education.idoneos.com.
+api.twitter.com.
+photos-c.ak.fbcdn.net.
+kepco.co.kr.
+developers.facebook.com.
+i2.ytimg.com.
+202.160.142.190.in-addr.arpa.
+blogparts.okwave.jp.
+3.254.244.201.in-addr.arpa.
+edge.quantserve.com.
+a6.sphotos.ak.fbcdn.net.
+hi-in.facebook.com.
+cjqxdgoea.q61b6c1l.
+google.com.mx.
+profile.ak.fbcdn.net.
+233.252.0.201.in-addr.arpa.
+local-bay.contacts.msn.com.
+www.facebook.com.
+creative.ak.fbcdn.net.
+ad.afy11.net.
+es-es.facebook.com.
+175.130.35.186.in-addr.arpa.
+ares.jsc.nasa.gov.
+madewithluv.com.
+252.0.168.192.in-addr.arpa.
+iztvkxdza.z57y1u5n.
+quakerfabric.com.
+s306.videobb.com.
+washeen91.writingjob.hop.clickbank.net.
+155.56.250.190.in-addr.arpa.
+1.0.0.127.in-addr.arpa.
+iguanas.mex.tl.
+habbo.com.mx.
+es-es.facebook.com.
+www.gossipsauce.com.
+251.206.15.201.in-addr.arpa.
+trk.paid-surveys-at-home.com.
+a.root-servers.net.
+a7.sphotos.ak.fbcdn.net.
+andrewsullivan.com.
+i499.photobucket.com.
+www.hotelelreymoro.com.
+www.microsoft.com.
+www.gonelocal.com.
+rad.msn.com.
+tienda.imperioh2.cl.
+a.root-servers.net.
+img.apnanalytics.com.
+apps.facebook.com.
+www.shareyouritems.com.
+yog34.games.ac4.yahoo.com.
+www.man-engines.com.
+translate.google.com.mx.
+aoqrf2:by.v75i0e0a.
+26.250.168.189.in-addr.arpa.
+_156_03_7.
+a.root-servers.net.
+sbsio.coast.ru.
+nothirst.com.
+64.193.75.85.in-addr.arpa.
+asktoolbar.weather.com.
+160.204.126.216.in-addr.arpa.
+a.root-servers.net.
+img.youtube.com.
+a.root-servers.net.
+cn.pool.ntp.org.
+www.facebook.com.
+s1.wp.com.
+tcpl.ca.
+3d.angrybirds.name.
+s.youtube.com.
+gma.yahoo.com.
+lh3.ggpht.com.
+fistintheair.com.
+_ldap._tcp.
+connect.facebook.net.
+hackingetico.com.
+static.xvideos.com.
+blog.mobango.com.
+st.chatango.com.
+marketingdesdelaromana.blogspot.com.
+www.juegospara.com.
+toolbarqueries.google.com.
+chinamoly.com.
+160.140.6.186.in-addr.arpa.
+a.root-servers.net.
+143.133.213.201.in-addr.arpa.
+different-love.foroactivo.com.
+data-recovery-free-help.blogspot.com.
+stores.ebay.es.
+darkanime.mforos.com.
+cs.cornell.edu.
+206.62.154.189.in-addr.arpa.
+i2.ytimg.com.
+a.root-servers.net.
+dmse.com.
+mediacdn.disqus.com.
+profile.ak.fbcdn.net.
+2.200.126.85.in-addr.arpa.
+photos-e.ak.fbcdn.net.
+cityvillefb0.static.zgncdn.com.
+laplumadebarro.blogspot.com.
+www.feelthesteel.biz.
+84.178.30.190.in-addr.arpa.
+www.google.com.
+client66.dropbox.com.
+t2.gstatic.com.
+cdn.mediafire.com.
+urls.api.twitter.com.
+sanlasar.ru.
+serialnumber.in.
+tech-whitepapers.manta.com.
+tsuki-yaoi.blogspot.com.
+123mail.cl.
+imap.gmail.com.
+58.213.21.89.in-addr.arpa.
+246.254.24.95.in-addr.arpa.
+mychemhelena.obolog.com.
+lbpdmsmsa01.d.r.dfait-maeci.gc.ca.
+84.235.75.201.in-addr.arpa.
+lhuhbu.com.
+www.humorpower.com.
+a1.sphotos.ak.fbcdn.net.
+mn.wikipedia.org.
+eu4.stvid.com.
+www.difasa.net.
+www.ct-7ob.com.
+novp.spb.su.
+video.xnxx.com.
+mindspring.net.
+142.190.65.95.in-addr.arpa.
+ssl.gstatic.com.
+www.cinemanow.com.
+www.nolimitweb.nl.
+ducs.millsshirley.com.
+setting3.yeahost.com.
+www.solo.aqui.creatusfrases.net.
+static.ak.fbcdn.net.
+6bf8e:23q.b92o9u1a.
+developers.facebook.com.
+a.root-servers.net.
+butovo.com.
+host1.dia.net.
+lg-phones.org.
+www.birdseye.com.
+www.inpolitics.ro.
+abajate.blogspot.com.
+134.18.23.186.in-addr.arpa.
+www.blackberry.com.
+rodina-kino.ru.
+91.233.90.2.in-addr.arpa.
+ib.adnxs.com.
+39.152.29.186.in-addr.arpa.
+email.com.
+0.11-270f7081.c120081.1518.195c.3ea0.210.0.rgc396q1h2icmzvnthlvztdn7v.avqs.mcafee.com.
+static.ak.fbcdn.net.
+_963_91_2.
+zagsmoscow.ru.
+37.50.93.200.in-addr.arpa.
+sport.allyoubet.com.
+www.facebook.com.
+mt1.googleapis.com.
+l.yimg.com.
+a.root-servers.net.
+t7.tagstat.com.
+books.google.com.mx.
+ucs.query.yahoo.com.
+i4.ytimg.com.
+rylandhomes.com.
+google.com.
+49.147.220.66.in-addr.arpa.
+sfdr-cisd.com.
+9-1.qlty.finarea.ch.
+goodereader.disqus.com.
+ch.tudelft.nl.
+1496354998.mail.outlook.com.
+landrover.tagworldwide.com.
+87.197.160.201.in-addr.arpa.
+_ldap._tcp.
+i4.ytimg.com.
+s1-excel.vo.msecnd.net.
+download884.avast.com.
+www.unrunescape.com.
+hi-in.facebook.com.
+translate.google.com.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+www.google.com.
+www.bigearl.org.
+www.bridedressup.net.
+external.ak.fbcdn.net.
+155.0.14.212.in-addr.arpa.
+tpc.googlesyndication.com.
+176.155.145.201.in-addr.arpa.
+www.soho.com.co.
+blog.seattlecoffeegear.com.
+153.151.143.187.in-addr.arpa.
+noticias.lainformacion.com.
+www.facebook.com.
+166.25.15.187.in-addr.arpa.
+a.root-servers.net.
+www.copytrans.jp.
+www.michell.com.pe.
+descargararesgratis.disqus.com.
+redirector.c.youtube.com.
+photos-f.ak.fbcdn.net.
+i366.photobucket.com.
+a.root-servers.net.
+photos-h.ak.fbcdn.net.
+s-static.ak.fbcdn.net.
+api-read.facebook.com.
+widgets.amung.us.
+kjtafdhws.com.domain.local.
+listino.omniauto.it.
+time.nist.gov.
+docs.google.com.
+209.57.228.71.in-addr.arpa.
+m.addthisedge.com.
+img.mediaplex.com.
+login.live.com.
+afrozeprinting.com.
+youtube-ui.l.google.com.
+pohmtk.com.
+57.30.47.189.in-addr.arpa.
+145.87.17.85.in-addr.arpa.
+apps.facebook.com.
+www.google.com.
+sponsoredcdn.speedbit.com.
+a1.twimg.com.
+www.xn--cabaasmazamitla-1qb.com.
+181.45.24.125.in-addr.arpa.
+176.17.24.190.in-addr.arpa.
+developers.facebook.com.
+idealcalor.com.
+clients1.google.com.
+mail.lab.comcor.ru.
+a355.phobos.apple.com.
+mail2lucky.com.
+www.facebook.com.
+www.bmag.org.uk.
+mendozabieninforma.com.ar.
+www.webtogs.co.uk.
+api.twitter.com.
+a.root-servers.net.
+el.y8.com.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+a771.da1.akamai.net.
+zynga2-a.akamaihd.net.
+dlpiper.com.
+canadianislamiccongress.com.
+webmail-ru.bul.net.
+175.81.81.186.in-addr.arpa.
+a6.sphotos.ak.fbcdn.net.
+gmaseven.blogspot.com.
+a.root-servers.net.
+52.67.250.189.in-addr.arpa.
+a2.sphotos.ak.fbcdn.net.
+sp.cwfservice.net.
+b._dns-sd._udp.0.1.168.192.in-addr.arpa.
+tijuana-kei.com.
+versn.ru.
+142.36.59.200.in-addr.arpa.
+partted.com.
+homey.ru.
+cdn.api.twitter.com.
+ns3.molehand.eu.
+foxnews.sl.advertising.com.
+www.reverbnation.com.
+i3.ytimg.com.
+2.1.168.192.in-addr.arpa.
+www.fotosrarasgratis.com.
+h-app01-06.hamachi.cc.
+enblogs.com.
+g.ceipmsn.com.
+suggestqueries.google.com.
+www.nuts.co.uk.
+db._dns-sd._udp.lan.
+www.msftncsi.com.
+api.facebook.com.
+rz5oq7:zr.72bo.
+liduvinacarrera.blogspot.com.
+cdn4.fmylife.com.
+a.root-servers.net.
+encrypted-tbn1.google.com.
+msnportal.112.2o7.net.
+a.root-servers.net.
+need2bfit.com.
+www.iegallery.com.
+a.root-servers.net.
+s2.youtube.com.
+117.183.127.187.in-addr.arpa.
+www.sqm.microsoft.com.
+googlehosted.l.googleusercontent.com.
+23.200.186.189.in-addr.arpa.
+kuban-service.ru.
+www.youtube.com.
+sn1msg2010640.sn1.gateway.edge.messenger.live.com.
+view.atdmt.com.
+c-0.19-210fa081.8020081.1518.19d4.3ea1.410.0.c4b819z5a5p2j1wbcnuecanzp5.avqs.mcafee.com.
+a.root-servers.net.
+mail.landbank.com.
+cuda.csystems.com.
+mail.kwreferred.com.
+www.google.com.
+www.macgeneration.com.
+www.youngcloseup.com.
+www.youtube.com.
+c0551612.cdn.cloudfiles.rackspacecloud.com.
+snj-us-bkwp-712-att.kodak.com.home.
+unijuris.fr.
+147.149.168.192.in-addr.arpa.
+_131_85_2.
+a.root-servers.net.
+safebrowsing-cache.google.com.
+www.facebook.com.
+xodusgroup.com.
+download675.avast.com.lan.
+party-games.zaural.ru.
+26.1.237.78.in-addr.arpa.
+_957_43_2.
+www.winamp.com.
+217.35.0.10.in-addr.arpa.
+www.facebook.com.
+images03.olx-st.com.
+236.158.78.190.in-addr.arpa.
+www.claro.com.pe.
+photos-g.ak.fbcdn.net.
+theflatland.com.
+www.bocareydecopas.com.ar.
+www.mmaaxx.com.
+gswebhost.com.
+r1rk9np7bpcsfoeekl0khkd2juj27q3o-a-fc-opensocial.googleusercontent.com.
+158.120.16.177.in-addr.arpa.
+s3.amazonaws.com.
+slmclaw.com.s6b1.psmtp.com.
+www.google.com.
+css.wlxrs.com.
+ns1.facebook.com.
+xwt.ru.
+a995.mm1.akamai.net.
+dinastia-stv.ru.
+www.gayteacher.net.
+a6.sphotos.ak.fbcdn.net.
+audio-sv5-t1-1.pandora.com.
+www.facebook.com.
+www.swtorguidehq.com.
+video01.ifeng.com.
+petsafe.net.inbound15.mxlogicmx.net.
+www.youtube.com.
+teredo.ipv6.microsoft.com.
+blog.gypsy05.com.
+_ldap._tcp.
+u20.eset.com.
+a.root-servers.net.
+sukellushaaja.fi.
+cdn-5.moviebox.com.
+196.103.232.189.in-addr.arpa.
+74.115.44.83.in-addr.arpa.
+sr.wikipedia.org.
+cs10.chatropolis.com.
+mx.games.yahoo.com.
+www.roperscientific.com.
+dwmailgate.delwestusa.com.
+gfx4.hotmail.com.
+www.itxchaos.co.uk.
+132.176.56.92.in-addr.arpa.
+es.safely.yahoo.com.
+safebrowsing.clients.google.com.
+b-0.19-22094008.61081.1518.19d4.3ea1.410.0.cfqf8cl1gw829ff7ctuvqcsszi.avqs.mcafee.com.
+236.174.85.200.in-addr.arpa.
+151.220.11.67.in-addr.arpa.
+res2.windows.microsoft.com.
+api.facebook.com.
+207.56.65.217.in-addr.arpa.
+a.root-servers.net.
+sp.cwfservice.net.
+a.root-servers.net.
+pattygopez-mileycyrusprettycool.buzznet.com.
+pixel.facebook.com.
+a-0.19-a309d000.2170092.1518.19d4.3ea1.210.0.mjcu9aaeb23cpducliwh1wip8j.avqs.mcafee.com.
+www.blinklist.com.
+www.laughenough.com.
+youtube-ui.l.google.com.
+fugigreenwood.com.
+ssl.google-analytics.com.
+images.amazon.com.
+a.root-servers.net.
+202.1.0.192.in-addr.arpa.
+www.desmotivaciones.es.
+mmrrg.com.s8b1.psmtp.com.
+proinfo.pandasoftware.com.
+ns.dipmap.com.
+stats.norton.com.
+a.root-servers.net.
+www.grupotelfor.com.
+static.ak.connect.facebook.com.
+fxfeeds.mozilla.com.
+remote.infopark.ru.
+fbcdn-profile-a.akamaihd.net.
+gbnet.com.
+www.theamazingspiderman.com.
+136.179.71.74.in-addr.arpa.
+a.root-servers.net.
+a-0.19-a3007008.10092.1518.19d4.3ea1.410.0.31jpecqc8hl6humr2z82g26p46.avqs.mcafee.com.
+apis.google.com.
+www.gameark.com.
+109.240.97.186.in-addr.arpa.
+tracking.usage.app.conduit-services.com.
+mail.samara.alice.ru.
+a3.twimg.com.
+photos-c.ak.fbcdn.net.
+teredo.ipv6.microsoft.com.
+profile.ak.fbcdn.net.
+www3.geosc.psu.edu.
+playerservices.streamtheworld.com.
+www.fb.com.
+244.173.172.190.in-addr.arpa.
+534-async.olark.com.
+external.ak.fbcdn.net.
+static.ak.fbcdn.net.
+static.ak.fbcdn.net.
+bstrlo51u.71zv.
+babich.spb.ru.
+ingameads.gameloft.com.
+ein.gtkg.net.
+kotonoha.monkey-pirate.com.
+mail.marstu.net.
+moricoli.com.mx4.mxtoolbox.com.
+6.136.192.190.in-addr.arpa.
+163.123.114.186.in-addr.arpa.
+www.facebook.com.
+hitext.ru.
+creative.ak.fbcdn.net.
+a.root-servers.net.
+213.9.122.190.in-addr.arpa.
+www.volviendoalabiblia.com.mx.
+d1.media.v4.skyrock.net.
+quality.ru.
+pixel.facebook.com.
+static.ak.fbcdn.net.
+maria-truecolours.blogspot.com.
+www.japonesasgratis.com.ar.
+_654_58_5.
+csc.beap.ad.yieldmanager.net.
+127.222.42.186.in-addr.arpa.
+lb._dns-sd._udp.lan.
+.
+www.gaymovieking.com.
+xrjwye.com.
+ns2.webland.ch.
+20.48.25.190.in-addr.arpa.
+developers.facebook.com.
+de.answers.yahoo.com.
+quitarverrugasylunares.net.
+ytogmowi9.64ke.
+0-jj-w.channel.facebook.com.
+e24.tns-cs.net.
+grincheux.irislink.com.
+a.root-servers.net.
+a.root-servers.net.
+3d3nynsfk.h79x8v5n.
+maps.gstatic.com.
+assets.gamersunite.com.
+completemortgageservice.com.
+109.79.167.189.in-addr.arpa.
+es.wikipedia.org.
+www.oxygenez-vous.com.
+row.bc.yahoo.com.
+102.16.158.189.in-addr.arpa.
+a.root-servers.net.
+www.elamalta.com.
+co.catawba.nc.us.
+amorvida.bligoo.com.
+locia.omega.mplik.ru.
+79.18.158.187.in-addr.arpa.
+fitnessatlantic.com.
+a5.sphotos.ak.fbcdn.net.
+gemmhomes.com.
+52.90.44.190.in-addr.arpa.
+dictionary.lunaescence.com.
+accounts.google.com.
+a8.sphotos.ak.fbcdn.net.
+photos-h.ak.fbcdn.net.
+2acyxlnqn.73ih.
+246.122.128.189.in-addr.arpa.
+www.limited-uk.de.
+static.ak.fbcdn.net.
+343cyb7n5.87sv.
+profile.ak.fbcdn.net.
+wyikyf.com.
+safebrowsing-cache.google.com.
+secure.shared.live.com.edgekey.net.
+time.chttl.com.tw.
+photos-c.ak.fbcdn.net.
+time.chttl.com.tw.
+google.com.
+hi-in.facebook.com.
+db._dns-sd._udp.0.1.168.192.in-addr.arpa.
+trueslant.com.
+data.mobclix.com.
+teredo.ipv6.microsoft.com.
+xvideos-390.vo.llnwd.net.
+www.blogger.com.
+www.kaskus.com.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+auth.np.ac.playstation.net.
+decentral-0.vo.llnwd.net.
+mail.sura.ru.
+lvpei.org.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+kccinter.net.
+wirelessplanetusa.com.
+www.google.com.
+s4.histats.com.
+119.216.63.189.in-addr.arpa.
+cablevision.com.ar.
+www.laurelcatering.com.
+photos-e.ak.fbcdn.net.
+barracuda.acgmedia.com.
+www.mercerbears.com.
+171.48.52.186.in-addr.arpa.
+thepinoy.com.
+login.yahoo.com.
+support.ins.dell.com.
+1.bp.blogspot.com.
+mailin11mx.groovy.gr.
+profile.ak.fbcdn.net.
+www.kitco.com.
+chicaskm.com.
+engine.influads.com.
+external.ak.fbcdn.net.
+cgibin.erols.com.
+98.178.244.190.in-addr.arpa.
+kapel-la.ru.
+www.ftalk.com.
+clients1.google.com.
+curryandco.com.
+106.48.179.190.in-addr.arpa.
+iesealarcos.es.
+creative.ak.fbcdn.net.
+photos-g.ak.fbcdn.net.
+dns.msftncsi.com.
+adserving.cpxinteractive.com.
+1.0.0.127.dnsbugtest.1.0.0.127.in-addr.arpa.
+fbcdn-profile-a.akamaihd.net.
+a.root-servers.net.
+www.gastrox.com.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+68.146.52.201.in-addr.arpa.
+r._dns-sd._udp.lan.
+a5.sphotos.ak.fbcdn.net.
+mail.parishepiscopal.org.
+pcstudents.us.
+c.atdmt.com.
+mail.tp.kurgan.ru.
+wd-edge.sharethis.com.
+s3pr.shoptowin.net.
+ugc.ducati.kontain.com.
+dns.msftncsi.com.
+photos-e.ak.fbcdn.net.
+optimized-by.rubiconproject.com.
+www.ebay.es.
+thumbs1.ebaystatic.com.
+213.217.245.189.in-addr.arpa.
+www.samsungpresenter.com.
+www.bancomer.com.
+ingeterra.espacioblog.com.
+147.29.26.201.in-addr.arpa.
+133.16.168.192.in-addr.arpa.
+p01-calendarws.icloud.com.
+adserver.adtech.de.
+216.125.76.190.in-addr.arpa.
+elrellano.co.
+a1108.da1.akamai.net.
+www.bravotube.co.
+cdn.api.twitter.com.
+mve8kjmk9.94qi.
+accounts.google.com.
+toyota-tsusho.com.
+magaltc.com.inbound15.mxlogic.net.
+hotmail.com.
+metrics.el-mundo.net.
+waldan.com.
+144.187.132.189.in-addr.arpa.
+www.hasrawy.net.
+apps.facebook.com.
+www.mapp-oea.net.
+bluehillfarm.com.
+fr-fr.facebook.com.
+a.root-servers.net.
+sp.cwfservice.net.
+rehbaum.net.
+www.rdanielstudios.com.
+200.32.94.189.in-addr.arpa.
+sites.google.com.
+58.200.65.190.in-addr.arpa.
+voipa.sip.yahoo.com.
+tag.admeld.com.
+d2n8p8eh14pae1.cloudfront.net.
+db._dns-sd._udp.0.129.37.10.in-addr.arpa.
+252.92.80.98.in-addr.arpa.
+download.windowsupdate.com.
+77.44.112.114.in-addr.arpa.
+s-static.ak.facebook.com.
+8.131.23.217.in-addr.arpa.
+foothealth.about.com.
+123.71.52.186.in-addr.arpa.
+246.242.62.190.in-addr.arpa.
+a7.sphotos.ak.fbcdn.net.
+www.cityvox.co.uk.
+a.root-servers.net.
+preventionnetwork.info.
+links4media.blogspot.com.
+78.71.181.186.in-addr.arpa.
+www.mayadstudios.com.
+a.root-servers.net.
+mail.slam.com.
+crl.comodoca.com.
+search.conduit.com.
+museotextildeoaxaca.wordpress.com.
+www.iglesialatina.org.
+7.52.100.190.in-addr.arpa.
+feeds.bbci.co.uk.
+www.alz.org.
+a1.sphotos.ak.fbcdn.net.
+connect.facebook.net.
+es.landing.playnik.com.
+www.facebook.com.
+192.207.15.187.in-addr.arpa.
+mx1.educom.ru.
+www2.winavi.com.
+profile.ak.fbcdn.net.
+89.237.69.190.in-addr.arpa.
+18.232.69.186.in-addr.arpa.
+photos-c.ak.fbcdn.net.
+ph.answers.yahoo.com.
+_177_16_3.
+www.telegraph.co.uk.
+www.yswhosting.com.
+www.metodologiamad.cl.
+i2.ytimg.com.
+time.chttl.com.tw.
+westerntraffic.com.
+dalisigloxx.wordpress.com.
+view.asiae.co.kr.
+google.com.
+co.nacogdoches.tx.us.s9b2.psmtp.com.
+www.amazon.com.
+hillevans.com.s7b2.psmtp.com.
+historiasextraordinarias.files.wordpress.com.
+a1.sphotos.ak.fbcdn.net.
+bsf.smowtion.com.
+24.media.tumblr.com.
+a7.sphotos.ak.fbcdn.net.
+a8.sphotos.ak.fbcdn.net.
+time.chttl.com.tw.
+chsi.ru.
+111.32.171.201.in-addr.arpa.
+a.root-servers.net.
+updatekeepalive.mcafee.com.
+iu1l8ddxm.57kv.
+download797.avast.com.
+searchqutoolbar.imesh.wizard.applicationstat.com.
+a4.da1.akamai.net.
+xf_com_update_doctor.qq.com.
+ads2.msads.net.
+shwaish.com.
+www.facebook.com.
+9q2xe4p38.78hv.
+es-la.facebook.com.
+isearch.avg.com.
+i4.ytimg.com.
+141.134.233.190.in-addr.arpa.
+636f6c.7374623030.732d6d736e.636f6d.80h413650e6.webcfs00.com.
+a-0.19-309f081.8000033.1518.19d4.2f1c.10.0.bzi1cbn28dc16k8idwcb7lck5t.avqs.mcafee.com.
+pagead2.googlesyndication.com.
+a.root-servers.net.
+sn18.mailshell.net.
+www.facebook.com.
+s42.undefined.home.
+ajax.googleapis.com.
+prog-net.com.
+pharmfab.com.
+80.171.246.85.in-addr.arpa.
+66.26.211.81.in-addr.arpa.
+id.google.com.mx.
+i3.ytimg.com.
+static.ak.fbcdn.net.
+www.sexomax.net.
+pixel.facebook.com.
+srx.main.ebayrtm.com.
+mangacan1.ucoz.com.
+dalek.softonic.com.
+lpadvisors.com.
+content.yieldmanager.edgesuite.net.
+api.facebook.com.
+ar-ar.facebook.com.
+img704.imageshack.us.
+a1.sphotos.ak.fbcdn.net.
+fr-fr.facebook.com.
+a.root-servers.net.
+123.36.93.200.in-addr.arpa.
+tv.hir24.hu.
+www.livesicilia.it.
+_357_99_0.
+db._dns-sd._udp.0.1.168.192.in-addr.arpa.
+12.176.15.186.in-addr.arpa.
+a.root-servers.net.
+191.164.138.190.in-addr.arpa.
+strappadometalblog.blogspot.com.
+7.169.185.187.in-addr.arpa.
+www.google.com.
+www.kids-pages.com.
+www.utj.edu.mx.
+seychellegabrielfan.com.
+a.root-servers.net.
+ad.yieldmanager.com.
+hosting.lockhosts.com.
+mvzmil.ru.
+al-nabaa.net.
+www.struat.com.
+www.mslitigationreview.com.
+wg6jw1g4r.p41z2x6m.
+ja.wikipedia.org.
+ocsp.entrust.net.
+a.root-servers.net.
+www.aa.com.
+www.sara-freder.com.
+v1.sftcdn.net.
+www.psp.wa.gov.
+2040.ecarlist.com.
+8.232.143.175.in-addr.arpa.
+facebookcheating.com.
+incanto.ru.
+livingair-74.ru.
+pagead2.googlesyndication.com.
+time.windows.com.
+www.google.com.
+244.107.226.190.in-addr.arpa.
+aaugonline.net.
+family-home.ru.
+www.youtube.com.
+vel-com.ru.
+go.microsoft.com.
+imagenes-estaticas.elmercadona.es.
+22.214.21.190.in-addr.arpa.
+deporteyautismo.blogspot.com.
+www.ed9101d8.com.
+www.unonoticias.com.mx.
+mail.gmail.com.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+loading3.widdit.com.
+199.68.0.187.in-addr.arpa.
+elcorillord.org.
+itunes.com.
+mail.globalinetbiz.net.
+ads.bluelithium.com.
+www.google.com.
+under-your-skin.com.
+7myjx2fjl.a36n3c9y.
+ar-ar.facebook.com.
+www.forosdelweb.com.
+polldaddy.com.
+doc.mbalib.com.
+i67.servimg.com.
+a.root-servers.net.
+mesadtvm.com.br.
+nflsoup.com.
+checkip.dyndns.org.
+photos-b.ak.fbcdn.net.
+www.frbsf.org.
+6ige7n4r7.w18s0b7x.
+de.tynt.com.
+boitaullresort.es.
+download.windowsupdate.com.
+95.146.220.66.in-addr.arpa.
+id.google.com.mx.
+hi-in.facebook.com.
+a6.sphotos.ak.fbcdn.net.
+mx.groups.yahoo.com.
+www.providencenightlife.net.
+video.google.com.mx.
+15.26.254.190.in-addr.arpa.
+prod1.rest-notify.msg.yahoo.com.
+www.google.com.
+83.85.182.189.in-addr.arpa.
+s-static.ak.facebook.com.
+pwi-forum.fr.perfectworld.eu.
+yahoo.com.sg.
+hbflarch.com.
+odnoklassniki.com.
+forum.fiance.com.
+skateboard-trick-tips.com.
+_ldap._tcp.
+static.punishtube.com.
+img846.imageshack.us.
+x3w.zapto.org.
+wilsonco.com.
+www.yahoo.com.
+gdjf.com.
+filter.radersolutions.com.
+profile.ak.fbcdn.net.
+mailgate.cabair.com.
+hotrodgrills.com.
+www.crazy-tattoo-designs.com.
+specialtycakecreations.com.
+169.235.141.201.in-addr.arpa.
+clock.fmt.he.net.
+lh4.ggpht.com.
+www.apple.com.
+ratings-wrs.symantec.com.
+ycmt-cdn.s3.amazonaws.com.
+dc378.4shared.com.
+cdn.api.twitter.com.
+real.theoffside.com.
+qetytug.com.
+wpad.
+a.root-servers.net.
+sites.google.com.
+shop.safewalls.org.
+pics.ebaystatic.com.
+googleads.g.doubleclick.net.
+shoujo-s.livejournal.com.
+104.76.51.190.in-addr.arpa.
+31.190.63.69.in-addr.arpa.
+efrtz24jq.p51y3m4p.
+97.7.18.99.in-addr.arpa.
+realtyexecutivesjulian.com.
+content.ak.metrogames.com.
+a1052.g.akamai.net.
+cdn.api.twitter.com.
+onlineaccess.mycreditcard.cc.
+www.shemaletushy.com.
+trexrb.ru.
+106.108.102.189.in-addr.arpa.
+ads.adk2.com.
+bogotaku.mejorforo.net.
+i4.ytimg.com.
+b47nb2tdo.87dv.
+www.lesbilicious.co.uk.
+axiome.info.
+gmail.com.
+d18txuuu339yuz.cloudfront.net.
+www.google.com.
+152.49.50.174.in-addr.arpa.
+59.240.57.83.in-addr.arpa.
+mozilla.cdn.leaseweb.com.
+www.google.com.
+c-ak.static-rootmusic.com.
+time.nist.gov.
+beauty-women.ru.
+s-static.ak.fbcdn.net.
+102.87.142.79.in-addr.arpa.
+136.253.77.190.in-addr.arpa.
+teredo.ipv6.microsoft.com.
+feeds.delicious.com.
+www.imdb.com.
+young-topmodels.info.
+binatel.ru.
+105.89.210.98.in-addr.arpa.
+se.magadan.su.
+static.ak.fbcdn.net.
+www.natuzzi.com.
+133.191.58.189.in-addr.arpa.
+creativecommons.org.
+outcampmail006.snc7.facebook.com.
+1f7yqor1v.j89b6t2o.
+video.mx.msn.com.
+www.keaneshaped.
+google.com.
+gtaonline.com.ar.
+accounts.google.com.
+static.ak.fbcdn.net.
+www.adobe.com.
+cn1.redswoosh.akadns.net.
+gamerandroide.blogspot.com.
+wolseley.at.
+41.197.46.201.in-addr.arpa.
+www.scrapbook.com.
+www.lancommand.co.uk.
+86.59.250.111.in-addr.arpa.
+214.162.73.190.in-addr.arpa.
+a1.sphotos.ak.fbcdn.net.
+a4.mzstatic.com.
+uccebszps.biz.
+159.183.58.99.in-addr.arpa.
+203.1.108.99.in-addr.arpa.
+30.205.201.108.in-addr.arpa.
+c.atdmt.com.
+160.68.90.186.in-addr.arpa.
+carpet-rug.com.
+www.hctc.com.
+nts-0nline.net.
+www.taxmann.com.
+www.copine-coquine.com.
+lagunasecagolf.com.
+ads.bluelithium.com.
+a3.sphotos.ak.fbcdn.net.
+tools.google.com.
+dr._dns-sd._udp.0.55.211.10.in-addr.arpa.
+mmoga.de.
+165.179.254.201.in-addr.arpa.
+jjszo4ss1.72wq.
+pagead2.googlesyndication.com.
+external.ak.fbcdn.net.
+154.4.26.190.in-addr.arpa.
+ad.yieldmanager.com.
+lh6.googleusercontent.com.
+www.update.microsoft.com.
+external.ak.fbcdn.net.
+243.251.209.112.in-addr.arpa.
+fileshare704.depositfiles.com.
+www.gstatic.com.
+i1fxw5q2d.83pc.
+i.ytimg.com.
+profil-furnitura.ru.
+hidheadlightconversion.com.
+a.root-servers.net.
+e461.b.akamaiedge.net.
+photos-g.ak.fbcdn.net.
+www.facebook.com.
+weichertacclaim.com.
+www.google.com.mx.
+ads.bluelithium.com.
+a.root-servers.net.
+soundcloud.com.
+realtyplacement.com.
+dns.msftncsi.com.
+mx4.future.net.uk.
+s.youtube.com.
+feeds.bbci.co.uk.
+234.77.153.187.in-addr.arpa.
+dns.msftncsi.com.
+mobilesources.net.
+_951_93_2.
+cdn.joomla.org.
+tracker.ilibr.org.
+iq7:vctbr.55ni.
+lasd.org.
+tour-foto.ru.
+3636.313735.313233.313032.80h42af7b66.webcfs00.com.
+www.escortvipbayan.com.
+a.root-servers.net.
+video327.myfreecams.com.
+video.xnxx.com.
+www.google.com.
+api.twitter.com.
+godleyfarms.com.
+liveupdate.symantecliveupdate.com.
+a.root-servers.net.
+195.122.209.77.in-addr.arpa.
+smtp2.halfen.com.
+javadl-esd.sun.com.
+chernobrovin.ru.
+sertel2k.vtrbandaancha.net.
+www.googleadservices.com.
+www.thethreadexchange.com.
+a.root-servers.net.
+twitter.com.
+www.123rf.com.
+hotmail.com.
+www.google-analytics.com.
+www.pallcare.asn.au.
+api.facebook.com.
+a.root-servers.net.
+billing.sharo4ka.ru.
+gkudqnwrt.12mv.
+www.facebook.com.
+www.bestlaidschemes.com.
+47.46.155.85.in-addr.arpa.
+d2105651.xoom.it.
+msc.wlxrs.com.
+es-la.facebook.com.
+fb-520.com.
+billing.sharo4ka.ru.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+static.ak.fbcdn.net.
+oluvwjgph.96zi.
+a.root-servers.net.
+photos-g.ak.fbcdn.net.
+google.com.
+cdn.stumble-upon.com.
+ad.doubleclick.net.
+hi-in.facebook.com.
+musicjacker.com.
+fishinggonewild.com.
+alerts.conduit-services.com.
+photos-b.ak.fbcdn.net.
+yo.wikipedia.org.
+static.ak.fbcdn.net.
+188.8.32.201.in-addr.arpa.
+vp.sip.messenger.msn.com.
+facebook.com.
+40.111.105.190.in-addr.arpa.
+www.manhunt.net.
+www.freexxxdot.com.
+carwale.com.
+mail.laserlightengines.com.
+um16.eset.com.
+www.googleadservices.com.
+miscritscdn.brokenbulbstudios.com.
+ssl.gstatic.com.
+plus.google.com.
+denver.bbb.org.
+a7.sphotos.ak.fbcdn.net.
+www.fulltono.com.
+www.hqudc.org.
+photos-e.ak.fbcdn.net.
+google.com.
+es-es.facebook.com.
+mailserver2.techint.it.
+hqwhtk8k:.89ii.
+lwt.com.
+248.12.4.189.in-addr.arpa.
+www.takethewalk.net.
+www.whatsapp.com.
+spaces.live.com.
+b._dns-sd._udp.0.81.168.192.in-addr.arpa.
+142.41.241.201.in-addr.arpa.
+t7.tagstat.com.
+www.chilincasita.blogspot.com.
+ns2.dnspod.net.
+www.udec.com.mx.
+www.parkinggames365.com.
+cnfg.facemoods.com.
+www.speakersblog.info.
+0.gravatar.com.
+suggestqueries.google.com.
+mscca.mscgva.ch.
+237.151.178.186.in-addr.arpa.
+10.212.1.201.in-addr.arpa.
+.
+lwsa.mlb.com.
+www.facebook.com.
+sunvestusa.com.
+a.root-servers.net.
+www.amateurs-videos.net.
+micros.co.za.
+www.google.com.
+a1005.w42.akamai.net.
+i.t-mobile-favourites.net.
+www.tagged.com.
+getsu.zapto.org.
+sevelina.ru.
+www.appsmitten.com.
+a3.sphotos.ak.fbcdn.net.
+msn.foxsports.com.
+c5.zedo.com.
+177.164.77.190.in-addr.arpa.
+a.root-servers.net.
+fiorellabotteri.blogspot.com.
+db._dns-sd._udp.0.1.168.192.in-addr.arpa.
+ns.smartec.ru.
+www.brucelipton.com.
+89.244.107.190.in-addr.arpa.
+r.openx.net.
+mail.n-u-c.ru.
+6.246.26.190.in-addr.arpa.
+fbcdn-profile-a.akamaihd.net.
+www.hojadeosaschool.org.
+94.70.41.189.in-addr.arpa.
+omniproductions.com.
+isatap.wag160n.
+apps.facebook.com.
+28.161.168.192.in-addr.arpa.
+226.19.23.187.in-addr.arpa.
+vitamind3info.blogspot.com.
+rotorrentmania.lx.ro.
+s-static.ak.fbcdn.net.
+vincotte.be.
+static.ak.facebook.com.
+is.mixmarket.biz.
+a947.phobos.apple.com.
+ssl.gstatic.com.
+static.ak.fbcdn.net.
+hotmail.com.
+www.acer-euro.com.
+pixer.meaningtool.com.
+photos-a.ak.fbcdn.net.
+dvdcovers.vidz.com.
+mcneal.com.s7b2.psmtp.com.
+b.static.ak.fbcdn.net.
+mail.hmconsultores.pt.
+moorcroftcs.co.uk.
+www.osvdailytake.com.
+motoxtreme.ru.
+reporter.es.msn.com.
+google.com.
+nationalstrategy.com.
+a.root-servers.net.
+ci.national-city.ca.us.inbound15.mxlogic.net.
+74.241.123.188.in-addr.arpa.
+www.advocateclassic.com.
+117.254.214.81.in-addr.arpa.
+a2.sphotos.ak.fbcdn.net.
+bfjoy.com.s5a1.psmtp.com.
+dr._dns-sd._udp.0.11.168.192.in-addr.arpa.
+smtp.dnsexit.com.
+a.root-servers.net.
+free-es-cf.softonic.com.
+20.122.66.190.in-addr.arpa.
+www.steam-sauna-benefits.com.
+www.brad.ac.uk.
+128.105.109.186.in-addr.arpa.
+cdn2.widdit.com.
+www.bywifi.com.
+blog.vampirethemasquerade.com.
+x9tfj3pby.60kv.
+js2.wlxrs.com.
+cs10398.vk.com.
+www.facebook.com.
+www.jenniferrizzo.com.
+www.slstoredisplays.com.
+cs10663.vk.com.
+.
+71.86.252.189.in-addr.arpa.
+www.medellinmiempresa.com.
+www.naturalmiscarriage.org.
+www.acmoc.org.
+b._dns-sd._udp.6.0.8.10.in-addr.arpa.
+_394_90_5.
+andiamo-tel.com.
+a1132.da1.akamai.net.
+150.246.198.190.in-addr.arpa.
+www.adserver.bz.
+lbjclinic.com.
+platform.ak.fbcdn.net.
+www.facebook.com.
+www.msftncsi.com.
+profile.ak.fbcdn.net.
+124.59.155.187.in-addr.arpa.
+a.root-servers.net.
+130.171.158.187.in-addr.arpa.
+ubs.ch.
+jayse.us.
+user.easycam.hk.
+172.153.42.186.in-addr.arpa.
+feedburner.google.com.
+dnl-01.geo.kaspersky.com.
+islamentrehermanas.forumactif.com.
+instagram.com.
+a6.sphotos.ak.fbcdn.net.
+www.facebook.com.
+a.root-servers.net.
+profile.ak.fbcdn.net.
+www.alessibici.com.
+www.cuantarazon.com.
+98.184.190.58.in-addr.arpa.
+oakland.athletics.mlb.com.
+www.google.com.
+groups.live.com.
+share.lockerz.com.
+www.ghostrecon.es.
+profile.ak.fbcdn.net.
+o-o.preferred.ord08s03.v10.lscache8.c.youtube.com.
+margalates.wordpress.com.
+www.googleadservices.com.
+ffin.com.
+mx.septen.com.
+wilsontechnologies.net.inbound15.mxlogicmx.net.
+www.lasrecetasdetriana.com.
+plusone.google.com.
+mail04.hgc.ch.
+adbucks.brandreachsys.com.
+a5.sphotos.ak.fbcdn.net.
+150.155.13.201.in-addr.arpa.
+a.root-servers.net.
+zynga2-a.akamaihd.net.
+mail.gsdllc.com.
+academiavascadegastronomia.com.
+227.25.243.168.in-addr.arpa.
+a.root-servers.net.
+www.camzap.com.
+a6.sphotos.ak.fbcdn.net.
+87.17.41.177.in-addr.arpa.
+upload.xvideos.com.
+teredo.ipv6.microsoft.com.
+profile.ak.fbcdn.net.
+cmgp.ru.
+leica-geosystems.com.s201b2.psmtp.com.
+60.224.38.187.in-addr.arpa.
+smokeinmycloset.blogspot.com.
+www.emailapple.com.
+a2.sphotos.ak.fbcdn.net.
+a.root-servers.net.
+galleries.nascar.com.
+static.ak.fbcdn.net.
+desdemimejana.blogspot.com.
+194.102.173.189.in-addr.arpa.
+:2o9depq3.l11o7j1x.
+etzion.org.il.
+mail.google.com.
+mail.hardingmarketing.com.
+photos-b.ak.fbcdn.net.
+174.192.172.71.in-addr.arpa.
+ksn1-12-part2.kaspersky-labs.com.
+egoadmins.com.
+o2mhaafyl.39hk.
+liceopaillaco.bligoo.cl.
+www3.discovirtual.com.ar.
+a.root-servers.net.
+179.35.166.81.in-addr.arpa.
+static.ak.fbcdn.net.
+cdn.lfstmedia.com.
+docs.google.com.
+mainc.rr.com.
+a8.sphotos.ak.fbcdn.net.
+msn.co.jp.
+9aks9fdzi.59ly.
+id.google.com.mx.
+ffpaorg.com.
+evsecure-ocsp.verisign.com.
+curtmfg.com.s9b1.psmtp.com.
+21.243.173.218.in-addr.arpa.
+plus.google.com.
+www.facebook.com.
+alertasios.mundodeportivo.com.
+chat.wibiya.com.
+67.216.102.189.in-addr.arpa.
+mail.sintondairyfoods.com.
+www.voo.com.
+129.3.19.186.in-addr.arpa.
+_561_54_4.
+74tf.ru.
+a7.sphotos.ak.fbcdn.net.
+g.ceipmsn.com.
+springwood.net.bak-mx.na0107.smtpbak.com.
+www.taringa.net.
+a998.mm1.akamai.net.
+elecomsoftware.com.
+sites.google.com.
+login.commbiz.commbank.com.au.
+truelightproductions.com.
+bestastrology.net.
+88.52.203.62.in-addr.arpa.
+pubads.g.doubleclick.net.
+profile.ak.fbcdn.net.
+247.75.80.68.in-addr.arpa.
+qns.com.
+kitchen-design-studio.com.
+def.net.
+www.schooltimegames.com.
+gfx3.hotmail.com.
+groups.google.com.mx.
+api.twitter.com.
+www.grupoindi.com.
+85.206.80.208.in-addr.arpa.
+o2.hit.gemius.pl.
+horoscope.charlesayoub.com.
+carmella-bing.crocostars.com.
+photos-c.ak.fbcdn.net.
+moneytreefsi.com.
+creative.ak.fbcdn.net.
+images.shaggybevo.com.
+teredo.ipv6.microsoft.com.
+228.242.193.173.in-addr.arpa.
+208.169.179.190.in-addr.arpa.
+dp.prisacom.com.
+13.19.80.201.in-addr.arpa.
+oldmotorclassic.blogspot.com.
+lz.club.cul.sohu.com.
+1.bp.blogspot.com.
+meneame.net.
+a6.sphotos.ak.fbcdn.net.
+static.ak.fbcdn.net.
+a5.sphotos.ak.fbcdn.net.
+obbit.net.
+evoke.com.
+114.168.138.187.in-addr.arpa.
+sp.cwfservice.net.
+www.militaryclothing.com.
+www.wind-energy-the-facts.org.
+smtp.cbi.com.
+equa-net.com.
+media.scanscout.com.
+apis.google.com.
+billing.sharo4ka.ru.
+164.55.27.190.in-addr.arpa.
+secure.baa.com.
+time.windows.com.
+www.mimejoorfrase.com.
+130.75.168.192.in-addr.arpa.
+apps.facebook.com.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+f.e.redbox.com.
+cincodemayo.bicentenario.gob.mx.
+healthprorecruiting.com.
+41.146.62.186.in-addr.arpa.
+235.216.226.189.in-addr.arpa.
+dsn6.d.skype.net.
+apis.google.com.
+www.tribulus.tv.
+sj-r.mycapture.com.
+207.163.248.189.in-addr.arpa.
+www.bbc.co.uk.
+developers.facebook.com.
+support.google.com.
+37.230.44.90.in-addr.arpa.
+180.94.167.78.in-addr.arpa.
+apps.facebook.com.
+www.nexiumresearch.com.
+32.63.168.192.in-addr.arpa.
+223.182.9.46.in-addr.arpa.
+a5.sphotos.ak.fbcdn.net.
+deltamobile.ru.
+app.appatyze.com.
+u.zhinei.com.
+139.224.47.190.in-addr.arpa.
+me.effectivemeasure.net.
+mntr.babcdn.com.
+64.118.31.190.in-addr.arpa.
+apps.facebook.com.
+zh-cn.facebook.com.
+photos-f.ak.fbcdn.net.
+guilbeauxlawfirm.net.
+elementscanner.com.
+www2.blogblog.com.
+learnerbrown.hubpages.com.
+ps4releasedate.net.
+weather.service.msn.com.
+30.10.62.186.in-addr.arpa.
+www.bing.com.
+www.jwwaterhouse.com.
+www.facebook.com.
+75.78.51.72.in-addr.arpa.
+agatha.folhasp.com.br.
+178.9.76.190.in-addr.arpa.
+234.176.89.201.in-addr.arpa.
+sitedown.concursolutions.com.
+_565_63_1.
+a.root-servers.net.
+google.com.
+g-rc.ru.
+www.google-analytics.com.
+www.youtube.com.
+www.frankthomastheoriginalone.com.
+a5.sphotos.ak.fbcdn.net.
+www.dodgeram.dk.
+www.zapaday.com.
+smtp3.iho.ru.
+kalvos.org.
+pca-llc.com.
+www.club24mainstreet.com.
+on-ramp.net.
+gb2k.deviantart.com.
+snixykitchen.wordpress.com.
+developers.facebook.com.
+mx.saxquest.com.
+a.root-servers.net.
+rover.ebay.com.
+i.ytimg.com.
+o.sa.aol.com.
+ad.yieldmanager.com.
+www.estadao.com.br.
+76.110.192.91.in-addr.arpa.
+web.goldenspikesaward.com.
+139.114.133.187.in-addr.arpa.
+update.batterycare.net.
+sepr.fr.
+peru.com.
+77.94.214.189.in-addr.arpa.
+10.182.77.151.in-addr.arpa.
+google-voice-and-video.softonic.com.
+osirus.casarta.com.
+coleman-bh.com.inbound15.mxlogic.net.
+autoboerse-emsland.de.
+ox.adjunky.com.
+mail2.gudanggaramtbk.com.
+baltimore.orioles.mlb.com.
+heartutilities.com.
+www.anzeigenannahme.mediapilot.de.dns.boreus.de.
+radioweb4.com.
+hugedl.com.
+a4.sphotos.ak.fbcdn.net.
+b._dns-sd._udp.lan.
+www.facebook.com.
+www.google-analytics.com.
+escltd.ru.
+www.lan.com.
+182.74.149.187.in-addr.arpa.
+www.facebook.com.
+1.0.0.127.dnsbugtest.1.0.0.127.in-addr.arpa.
+dr._dns-sd._udp.0.245.168.192.in-addr.arpa.
+profile.ak.fbcdn.net.
+profile.ak.fbcdn.net.
+165.118.177.124.in-addr.arpa.
+gnebu.es.
+bam.on.ca.
+kerki.de.
+196.173.33.65.in-addr.arpa.
+profile.ak.fbcdn.net.
+www.sellingantiques.co.uk.
+ar-ar.facebook.com.
+fbcdn-profile-a.akamaihd.net.
+s.ytimg.com.
+goped.com.s5a1.psmtp.com.
+www.google.com.
+canyonhill.org.
+hosting2.nifty.com.
+109.120.102.201.in-addr.arpa.
+androidsdk.ads.mp.mydas.mobi.
+r._dns-sd._udp.0.0.168.192.in-addr.arpa.
+erieco.com.mail7.psmtp.com.
+gfx2.hotmail.com.
+iringer.softonic.com.br.
+www.facebook.com.
+photos-b.ak.fbcdn.net.
+tags.w55c.net.
+tour.clubalexis.com.
+hulkshare.com.
+search.twitter.com.
+dns.msftncsi.com.
+image23.bannch.com.
+im11.gulfup.com.
+photos-a.ak.fbcdn.net.
+a2.sphotos.ak.fbcdn.net.
+www.searchqu.com.
+pogievendors.com.
+eprints.ulster.ac.uk.
+tig.com.
+r5ohfqj7o.99ws.
+mail.anandjon.com.
+a.root-servers.net.
+www.yahoo.com.
+teredo.ipv6.microsoft.com.
+allrecipes.com.
+api.twitter.com.
+www.myhdd.ro.
+www.amazon.com.
+gdata.youtube.com.
+britecomputers.com.s8b1.psmtp.com.
+googleads.g.doubleclick.net.
+3.84.0.173.in-addr.arpa.
+www.brothersoft.com.
+posta.indire.it.
+photos-h.ak.fbcdn.net.
+profile.ak.fbcdn.net.
+_269_40_8.
+js.casalemedia.com.
+nomodels.com.ua.
+static.ak.fbcdn.net.
+blog.japantimes.co.jp.
+conflict-global-storm.softonic.com.
+www.huishoudbeurs.nl.
+a5.sphotos.ak.fbcdn.net.
+s-static.ak.fbcdn.net.
+china-media-ad.en.alibaba.com.
+www.androiddevices.com.au.
+mx1.okehosting.net.
+www.upwallpapers.net.
+transformers-the-game.softonic.com.
+swupmf.adobe.com.
+plus.google.com.
+developers.facebook.com.
+medifirst.ru.
+www.guias11811.es.
+external.ak.fbcdn.net.
+www.anierm.org.mx.
+apple.imap.mail.yahoo.com.
+galant-cosmetic.ru.
+ad.yieldads.com.
+a2.sphotos.ak.fbcdn.net.
+www.google.com.
+www.facebook.com.
+gocsg.net.
+cgs.cz.
+a4.sphotos.ak.fbcdn.net.
+d2094047.xoom.it.
+47.135.188.24.in-addr.arpa.
+distilleryimage7.instagram.com.
+185.43.108.99.in-addr.arpa.
+google.com.
+vex.wildtangent.com.
+crafts.shop.ebay.com.
+pixel.facebook.com.
+110.150.105.186.in-addr.arpa.
+ut7.xhamster.com.
+azalis.org.ru.
+laidesigngroup.com.inbound15.mxlogic.net.
+dvd-decrypter.programas-gratis.net.
+photos-f.ak.fbcdn.net.
+apps.facebook.com.
+noviosfelices.com.
+zjnizub9i.v03y1f7r.
+56.97.153.189.in-addr.arpa.
+69.13.127.71.in-addr.arpa.
+0af2d87b0af12c898897744f51c37b7f.co.cc.
+v3.nonxt7.c.youtube.com.
+www.epicgameads.com.
+rcm.amazon.com.
+teredo.ipv6.microsoft.com.
+244.31.244.98.in-addr.arpa.
+www.setyoufreenews.com.
+chat.facebook.com.
+bibliotecadeloselefantes.blogspot.com.
+250.115.63.200.in-addr.arpa.
+mail.design-logix.com.
+view.atdmt.com.
+32.135.249.186.in-addr.arpa.
+api.conduit.com.
+212.177.151.190.in-addr.arpa.
+throneofroses.blogspot.com.
+ati-catalyst-drivers-vista-7.softonic.com.
+www.bdtonline.com.
+3.44.78.201.in-addr.arpa.
+royalholidaypress.com.
+nwjdns40.innodata-isogen.com.
+mail.municode.com.
+s-static.ak.facebook.com.
+valleyimpressions.com.
+48.234.10.92.in-addr.arpa.
+ajax.googleapis.com.
+hellofest.com.
+jtsports.com.2.arsmtp.com.
+escookie.mystarworld.net.
+160.119.127.201.in-addr.arpa.
+cloudcell.com.
+www.grogono.com.
+d1r9j5rytlayy8.cloudfront.net.
+121.119.204.190.in-addr.arpa.
+profile.ak.fbcdn.net.
+www.mybrowserbar.com.
+mindsize.deviantart.com.
+wpad.
+ponyrama.browsergamez.com.
+connect.facebook.net.
+connect.facebook.net.
+www.comofaz.org.
+belltechlogix.com.
+246.58.169.173.in-addr.arpa.
+174.237.13.190.in-addr.arpa.
+p04-btmmdns.icloud.com.
+a6.sphotos.ak.fbcdn.net.
+ssl.gstatic.com.
+cult.cu.
+gates.shapeservices.net.
+a7.sphotos.ak.fbcdn.net.
+matcher-rbc.bidder7.mookie1.com.
+www.adobe.com.
+top.qiyi.com.
+apps.facebook.com.
+smtp.iwaynet.net.
+photos-g.ak.fbcdn.net.
+vtsfpvpz.net.
+photos-c.ak.fbcdn.net.
+113.65.156.201.in-addr.arpa.
+api.webrep.avast.com.
+182.134.230.201.in-addr.arpa.
+a1.sphotos.ak.fbcdn.net.
+correodeinocentescapitulo.blogspot.com.
+ad-g.doubleclick.net.
+247.66.171.201.in-addr.arpa.
+android.amberfog.com.
+11.91.227.189.in-addr.arpa.
+profile.ak.fbcdn.net.
+pathwaytoascension.wordpress.com.
+accounts.google.com.
+www.rockford-industrial.com.
+www.peliculasfox.com.
+ad.yieldmanager.com.
+27.229.171.69.in-addr.arpa.
+appldnld.apple.com.
+iowatelecom.net.com.
+www.youtube.com.
+cache.www.universalhidefclub.com.
+144.218.177.190.in-addr.arpa.
+_402_42_5.
+192.176.179.190.in-addr.arpa.
+www.googleadservices.com.
+uksystem.co.kr.
+stats.wordpress.com.
+2.pool.ntp.org.
+anime-dusk.activoforo.com.
+photos-b.ak.fbcdn.net.
+checkip.dyndns.org.
+mail.google.com.
+36.94.57.62.in-addr.arpa.
+a1332.g.akamai.net.
+www.eby.org.ar.
+us.mg5.mail.yahoo.com.
+shasta-rrs.symantec.com.
+s0.2mdn.net.
+140.78.252.189.in-addr.arpa.
+136.43.166.190.in-addr.arpa.
+sp.cwfservice.net.
+update1.jdownloader.org.
+www9.effectivemeasure.net.
+kromprint.ru.
+22.32.153.201.in-addr.arpa.
+244.211.164.189.in-addr.arpa.
+t.usnews.com.
+cekuaces.blogspot.com.
+208.157.227.2.in-addr.arpa.
+img.animalsexmania.net.
+esc10.ednet10.net.
+apkiss.com.
+orcart.facebook.com.
+ninjago.lego.com.
+isp.volgaonline.ru.
+g.microsoft.com.
+145.200.37.190.in-addr.arpa.
+135.22.74.190.in-addr.arpa.
+index.rpg.net.
+a1490.g.akamai.net.
+coolwebbies.googlepages.com.
+romainbjames.com.
+mianimex.org.
+chevismo.disqus.com.
+ac.babsrv.com.
+www.antena3.com.
+mail.google.com.
+avisooportuno.mx.
+picapinocarpinteria.blogspot.com.
+photos-h.ak.fbcdn.net.
+twitter.com.
+en-maktoob.yahoo.com.
+sdn2.clearsdn.com.
+a.tribalfusion.com.
+www.ppaproperties.com.
+www.facebook.com.
+billing.sharo4ka.ru.
+accordcard.ru.
+static2.drtuber.com.
+a7.sphotos.ak.fbcdn.net.
+by2msg4020309.gateway.messenger.live.com.
+botones.blogalaxia.com.
+google.com.
+chester-nj.org.s5a2.psmtp.com.
+cis-i.ru.
+profiles.google.com.
+m.adnxs.com.
+ds.serving-sys.com.
+carwheels.ru.
+messenger.hotmail.com.
+static.ak.fbcdn.net.
+ghs.l.google.com.
+time.nist.gov.
+a.root-servers.net.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+tc19.easythumbhost.com.
+cakeciamik.blogspot.com.
+teredo.ipv6.microsoft.com.
+pb.blabbers.com.
+129.233.171.187.in-addr.arpa.
+platform.ak.fbcdn.net.
+www.olympia-verlag.de.
+67.81.179.189.in-addr.arpa.
+malahache.blogspot.com.
+img299.imageshack.us.
+dns.msftncsi.com.
+a2.sphotos.ak.fbcdn.net.
+64.91.138.187.in-addr.arpa.
+photos-b.ak.fbcdn.net.
+www.google-analytics.com.
+support.google.com.
+wssq9o13d.n92v4s1i.
+cdbn.com.
+67.146.215.84.in-addr.arpa.
+_ldap._tcp.
+ow.ly.
+5.249.52.186.in-addr.arpa.
+ws1.tapjoyads.com.
+clayesmore.com.
+geoiplookup.wikimedia.org.
+bellsouthpwp.net.
+dfdfh.com.
+www.google.com.
+mail.trans-k.ru.
+jailbreak-j13.blogspot.com.
+propagandacatolica.blogspot.com.
+forums.vwvortex.com.
+smtp.ebrandz.com.
+173.130.231.89.in-addr.arpa.
+maui.hawaii.edu.
+www.facebook.com.
+fxfeeds.mozilla.com.
+63.129.190.186.in-addr.arpa.
+a7.sphotos.ak.fbcdn.net.
+86.171.172.190.in-addr.arpa.
+twitter.com.
+66eoaijft.66ae.
+latam.msn.com.
+www.alan-g.me.uk.
+www.google.com.
+i2.ytimg.com.
+a.root-servers.net.
+108.245.23.50.in-addr.arpa.
+www.siri.com.
+www.t-shirttimes.com.
+www.cvs.saude.sp.gov.br.
+rapidshare.com.
+www.pecentral.org.
+smi66gn42.88uc.
+news.google.com.mx.
+fxfeeds.mozilla.com.
+api.twitter.com.
+d3ojfab0q2dwum.cloudfront.net.
+www.datafull.com.
+agendadelpescador.blogspot.com.
+tpopworld.blogspot.com.
+mail.segeplan.gob.gt.
+res3.windowsmedia.com.
+csi.gstatic.com.
+a.root-servers.net.
+111.182.224.189.in-addr.arpa.
+86lqs32zs.77ta.
+rachael.foodnetwork.mobi.
+ksn2-12.kaspersky-labs.com.
+api.twitter.com.
+b._dns-sd._udp.0.2.168.192.in-addr.arpa.
+www.telurica.com.
+36.179.170.201.in-addr.arpa.
+b.scorecardresearch.com.
+lifehealthpro.disqus.com.
+plusone.google.com.
+253.156.6.189.in-addr.arpa.
+www.google-analytics.com.
+teredo.ipv6.microsoft.com.
+static.ak.fbcdn.net.
+ad-g.doubleclick.net.
+lgencove.k12.ny.us.
+www.mercadolibre.com.co.
+0-188.channel.facebook.com.
+secure.shared.live.com.
+s-static.ak.facebook.com.
+signup.netflix.com.
+d-0.19-a30f80b1.2d1031.1518.19d3.3ea1.210.0.iud63l4d8rput6efjed6dcljpj.avqs.mcafee.com.
+pagead2.googlesyndication.com.
+titanium30-en.url.trendmicro.com.
+_360_57_4.
+ridiculojustin.info.
+photos-b.ak.fbcdn.net.
+acommodity.com.
+www.facebook.com.
+203.64.166.190.in-addr.arpa.
+teredo.ipv6.microsoft.com.
+yoow.com.
+futurespros.websol.barchart.com.
+dessy.com.
+a.root-servers.net.
+posvetim.ru.
+18.67.222.31.in-addr.arpa.
+rad.msn.com.
+www.bitcount.com.
+155.12.101.187.in-addr.arpa.
+photos-f.ak.fbcdn.net.
+magazine.jungle.co.kr.
+131.38.67.201.in-addr.arpa.
+time.chttl.com.tw.
+profile.ak.fbcdn.net.
+muff-web.com.
+d1j68ux4ukg4g1.cloudfront.net.
+181.125.101.86.in-addr.arpa.
+hdubtpvottklleq.mn.
+79.191.150.189.in-addr.arpa.
+www.spainselecta.com.
+gillfordlm.com.
+teredo.ipv6.microsoft.com.
+cprpr1.wordpress.com.
+_747_06_9.
+240.131.48.186.in-addr.arpa.
+gfx6.hotmail.com.
+sp.cwfservice.net.
+155.181.7.189.in-addr.arpa.
+199.230.176.213.in-addr.arpa.
+photos-a.ak.fbcdn.net.
+164.176.171.189.in-addr.arpa.
+22.138.22.186.in-addr.arpa.
+www.msnbc.msn.com.
+72.161.88.186.in-addr.arpa.
+geo.messenger.services.live.com.
+donbenitovillanueva.es.
+162.28.140.200.in-addr.arpa.
+199.206.17.50.in-addr.arpa.
+a3.sphotos.ak.fbcdn.net.
+m1.nsimg.net.
+teredo.ipv6.microsoft.com.
+themes2.gptop.com.
+168.236.152.69.in-addr.arpa.
+30.178.137.187.in-addr.arpa.
+liveupdate.symantecliveupdate.com.
+www.estadiosports.com.
+www.google.com.
+www.amazon.com.
+205.200.79.190.in-addr.arpa.
+uth.tmc.edu.
+perfectgirls.cdn-z4.globecorp.net.
+sucw:qb8m.d92e4c6m.
+searchjs.s3.amazonaws.com.
+safebrowsing-cache.google.com.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+a1.sphotos.ak.fbcdn.net.
+uchicago.ru.
+nederman.com.
+rest-img.msg.yahoo.com.
+i5.7kimg.cn.
+crazybrush.ru.
+safebrowsing-cache.google.com.
+www.boxingnewsonline.net.
+www.failimages.com.
+p06-caldav.icloud.com.
+www.kayfabenews.com.
+a2.sphotos.ak.fbcdn.net.
+img3.hotteengayboys.com.
+billing.sharo4ka.ru.
+a.root-servers.net.
+_707_31_4.
+processpipe.com.
+static.ak.fbcdn.net.
+mccradio.com.s8b2.psmtp.com.
+account.netflix.com.
+profile.ak.fbcdn.net.
+ad.doubleclick.net.
+api.facebook.com.
+cv28.net.
+119.93.27.216.bl.spamcop.net.
+alchimiaweb.com.
+www.bing.com.
+omicrontech.net.mail6.psmtp.com.
+tpibaltimore.com.
+clipstyle.de.
+149.138.232.190.in-addr.arpa.
+20.151.206.90.in-addr.arpa.
+free-smith-video-player.softonic.com.
+zynga1-a.akamaihd.net.
+tobolsk.info.
+upgrade.bitdefender.com.
+88.79.55.65.in-addr.arpa.
+shop.magstore.com.au.
+2.bp.blogspot.com.
+242.114.222.137.in-addr.arpa.
+251.76.61.186.in-addr.arpa.
+platform.twitter.com.
+teredo.ipv6.microsoft.com.
+mail2.colorresourcesintl.com.
+32.190.63.69.in-addr.arpa.
+46.198.139.187.in-addr.arpa.
+8.15.125.186.in-addr.arpa.
+www.google.com.mx.
+translate.google.com.
+133.113.50.24.in-addr.arpa.
+a5.mzstatic.com.
+189.53.58.186.in-addr.arpa.
+www.cdn.viber.com.
+www.prabalgurung.com.
+148.44.139.187.in-addr.arpa.
+pagead2.googlesyndication.com.
+prludmila.ru.
+a.root-servers.net.
+158.55.10.95.in-addr.arpa.
+www.cambio.bo.
+0-257.channel.facebook.com.
+www.grabarz.net.
+104.98.160.189.in-addr.arpa.
+secon.nl.
+www.uderzo.it.
+17.208.154.83.in-addr.arpa.
+www.cpxadspace.com.
+a5.sphotos.ak.fbcdn.net.
+218.200.203.68.in-addr.arpa.
+d1.openx.org.
+mail.rosttreid.ru.
+s.youtube.com.
+workingwithrails.com.
+ludgate.nxtbook.com.
+at-lan.ru.
+images.google.com.
+35.151.22.71.in-addr.arpa.
+www.hammondindiana.com.
+www.gstatic.com.
+www.in.be.
+www.descargakaraokegratis.com.
+hotellid.reisiguru.ee.
+mecssgprnqbmginn.org.
+84.1.168.192.in-addr.arpa.
+gfx4.hotmail.com.
+54.249.137.189.in-addr.arpa.
+static.ak.fbcdn.net.
+hi-in.facebook.com.
+22.27.159.187.in-addr.arpa.
+a-0.19-a3092081.200b3.1518.19d4.3ea1.210.0.frdt39tm35rfzava51dg6fkzg5.avqs.mcafee.com.
+www.google.com.mx.
+facebookanime.com.
+i.ytimg.com.
+www.youtube.com.
+66c9i6pj32d33-c.c.yom.mail.yahoo.com.
+a.root-servers.net.
+www.google.com.
+report.freemake.com.
+www.google-analytics.com.
+3cw7l58k5.e05w6e8p.
+www.cjmillisock.com.
+www.gloria-pat.com.
+www.averias.eu.
+og.tvteam.info.
+a.root-servers.net.
+smtp.yellowbananas.com.
+millavon.fsnet.co.uk.
+tomsfoods.com.
+profile.ak.fbcdn.net.
+www.newmusicreviews.net.
+_875_57_7.
+diper.com.
+feeds.feedburner.com.
+a.root-servers.net.
+metallp.ru.
+adsfront.iminent.com.
+sp.ask.com.
+227.3.108.190.in-addr.arpa.
+prohibidoleer.com.
+www.reignonline.net.
+gfx4.hotmail.com.
+tandt-materials.com.
+181.0.0.10.in-addr.arpa.
+ar.wikipedia.org.
+cmgmpyu.biz.
+iphone.elnorte.com.
+.
+ocsp.digicert.com.
+ssl.google-analytics.com.
+i.w.inmobi.com.
+mail.rkconst.com.
+.
+www.babyshowersinvitations.com.au.
+static.ak.connect.facebook.com.
+www.osh.net.
+www.autemo.com.
+www.neverthelessnation.com.
+a.root-servers.net.
+www.google.com.
+ldkjflds.com.
+mail.asmor.ru.
+1601.live.streamtheworld.com.
+www.sonnerie.net.
+78.50.250.190.in-addr.arpa.
+tc.v13.cache7.c.youtube.com.
+7.30.72.46.in-addr.arpa.
+vulgarization.com.
+a.root-servers.net.
+2.4.2.198.in-addr.arpa.
+fujihunt.com.sg.
+photos-d.ak.fbcdn.net.
+a.root-servers.net.
+208.153.141.189.in-addr.arpa.
+100.153.14.201.in-addr.arpa.
+www.swannysmodels.com.
+h.live.com.
+rad.msn.com.
+adimpact.com.au.
+www.gearreview.com.
+nauta360.expansion.com.
+108.240.162.78.in-addr.arpa.
+api.facebook.com.
+jabber.intellicontact.com.
+rospres.com.
+236.109.138.175.in-addr.arpa.
+106.8.218.186.in-addr.arpa.
+252.38.49.96.in-addr.arpa.
+91.255.132.189.in-addr.arpa.
+static01.videostream4u.com.
+e5237.g.akamaiedge.net.
+202.1.168.192.in-addr.arpa.
+primeconstructions.gr.
+btownmasti.com.
+40.48.140.187.in-addr.arpa.
+a.root-servers.net.
+a2.sphotos.ak.fbcdn.net.
+zonabarranquilla.com.
+www.sedo.com.
+co101ds.mail.services.live.com.
+www.elmendorf.af.mil.
+www.charlamania.com.
+darkorbit.browsergames.de.
+inbound.washworldinc.com.netsolmail.net.
+prod2.rest-notify.msg.yahoo.com.
+www.facebook.com.
+mxhost1.fni-stl.com.
+images.builderhouseplans.com.
+a.root-servers.net.
+27.101.194.187.in-addr.arpa.
+www.rassegna.it.
+analytic.gatewayinterface.com.
+photos-a.ak.fbcdn.net.
+124.163.72.190.in-addr.arpa.
+mymail.bright.net.
+176.208.6.189.in-addr.arpa.
+fbcdn-profile-a.akamaihd.net.
+autos.starmedia.com.
+clan-world-wide.foroa.org.
+plusone.google.com.
+time.stdtime.gov.tw.
+i.ytimg.com.
+download.windowsupdate.com.
+www.modashop.it.
+80.47.11.187.in-addr.arpa.
+fxfeeds.mozilla.com.
+ksn3-11.part1.kaspersky-labs.com.
+www.sting.co.jp.
+jsu.dt07.net.
+windowssecrets.com.
+www.grabmp3.org.
+profile.ak.fbcdn.net.
+img41.imageshack.us.
+photos-f.ak.fbcdn.net.
+es.wikipedia.org.
+0-jj-w.channel.facebook.com.
+googleads.g.doubleclick.net.
+get.adobe.com.
+nesma.net.sa.
+www.autos.com.
+pubads.g.doubleclick.net.
+p0b.ru.
+x8a.xanga.com.
+www.filmyfair.com.
+mail.penair.org.
+124.190.245.87.in-addr.arpa.
+s7.addthis.com.
+goo.gl.
+a4.sphotos.ak.fbcdn.net.
+inca-gmbh.de.
+l.longtailvideo.com.
+images.hi5.com.
+44.221.143.187.in-addr.arpa.
+pagead2.googlesyndication.com.
+posta74a.mailbeta.libero.it.
+20.75.242.189.in-addr.arpa.
+inbound.citizenscommunitybank.com.netsolmail.net.
+a7.sphotos.ak.fbcdn.net.
+matcinv1.matcin.net.
+www.mondomacabrodvd.com.
+94.211.141.201.in-addr.arpa.
+62.68.206.190.in-addr.arpa.
+orangehills.net.
+deep.crocmovies.com.
+blog.qmerdesign.net.
+google.com.
+139.206.23.189.in-addr.arpa.
+millionaire-city-money-rewardss.blogspot.com.
+webdesignburn.disqus.com.
+44.32.118.190.in-addr.arpa.
+a.root-servers.net.
+filter.eclickz.com.
+service.gc.apple.com.akadns.net.
+toldiacosiendo.blogspot.com.
+d1marr3m5x4iac.cloudfront.net.
+razyr.cz.
+t2.gstatic.com.
+maeslunau.com.
+dnl-18.geo.kaspersky.com.
+inbound.ksenterprisesonline.com.netsolmail.net.
+anime.about.com.
+www.ebay.com.
+a.root-servers.net.
+safebrowsing-cache.google.com.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+a.root-servers.net.
+www.youtube.com.
+5.133.86.187.in-addr.arpa.
+i4.ytimg.com.
+0.11-2309e081.c020083.1518.1982.3ea1.210.0.rsh5s2r6smr3phe6pk85h9qpeb.avqs.mcafee.com.
+photos-e.ak.fbcdn.net.
+teredo.ipv6.microsoft.com.
+radionicaaplicada.blogspot.com.
+a.root-servers.net.
+www.studioverissimo.net.
+ksn1-11-part2.kaspersky-labs.com.
+www.facebook.com.
+photos-d.ak.fbcdn.net.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+photos-a.ak.fbcdn.net.
+www.forodecine.com.
+static.ak.fbcdn.net.
+j.imagehost.org.
+tracker.torrentbay.to.
+fb.link.nokia.com.
+ksrryc:r7.12ks.
+rp.gwallet.com.
+pagead2.googlesyndication.com.
+204.207.95.201.in-addr.arpa.
+tarus.com.
+www.srisurf.com.
+_ldap._tcp.
+api.mixpanel.com.
+power-rangers.chulojuegos.com.
+pagead2.googlesyndication.com.
+www.facebook.com.
+166.27.14.187.in-addr.arpa.
+explotar-mistico-en-la-india.juegosipo.com.
+wffw.info.
+homedecorbytpt.com.
+letras.terra.com.
+65.168.164.187.in-addr.arpa.
+seriesid.com.
+aerotrim.co.uk.
+a1.sphotos.ak.fbcdn.net.
+api.skype.com.
+external.ak.fbcdn.net.
+decoracion.de.
+clients1.google.com.
+206.183.90.186.in-addr.arpa.
+s7.addthis.com.
+gruqtwp.com.
+70.53.173.112.in-addr.arpa.
+www.kalpiko.com.
+accounts.google.com.
+mta7.am0.yahoodns.net.
+www.littleabout.com.
+www.youtube.com.
+halmstad.net.
+www.adobe.com.
+245.105.42.177.in-addr.arpa.
+www.business-in-asia.com.
+a.root-servers.net.
+s2abrd19b.n59g1o6d.
+151.134.67.201.in-addr.arpa.
+innerlink.net.mx1.rcimx.com.
+a.l.yimg.com.
+www.myspace.com.
+106.249.205.109.in-addr.arpa.
+apen-audio-cd-burner.softbull.com.
+api-read.facebook.com.
+api.facebook.com.
+184.80.50.212.in-addr.arpa.
+123.0.0.10.in-addr.arpa.
+www.umoloda.kiev.ua.
+119.37.212.201.in-addr.arpa.
+hgfhj.com.
+71.6.106.186.in-addr.arpa.
+i3.ytimg.com.
+9.193.168.192.in-addr.arpa.
+243.183.157.93.in-addr.arpa.
+www.esesli.com.
+aujlntqh2.k06f6t0t.
+_227_14_3.
+127.0.0.1.
+widget.gigatools.com.
+a.root-servers.net.
+71.142.106.58.in-addr.arpa.
+a.root-servers.net.
+131.160.66.187.in-addr.arpa.
+static.ak.fbcdn.net.
+57.194.102.200.in-addr.arpa.
+a2.sphotos.ak.fbcdn.net.
+goo.gl.
+ssl.gstatic.com.
+d5nxst8fruw4z.cloudfront.net.
+cervantes.uah.es.
+specsavers.com.s200b2.psmtp.com.
+billing.sharo4ka.ru.
+mail.cablek.com.
+www.amazon.fr.
+www.vh1la.com.
+time.windows.com.
+s.ytimg.com.
+img3.etsystatic.com.
+s2.youtube.com.
+230.84.177.195.in-addr.arpa.
+geminipartners.com.
+photos-c.ak.fbcdn.net.
+www.tremendo.com.
+i4.ytimg.com.
+ntp.glb.nist.gov.
+199.48.40.201.in-addr.arpa.
+20.197.59.90.in-addr.arpa.
+metacafe.buscatube.org.
+www.google.com.
+m.addthisedge.com.
+www.ofertasdeviajesbaratos.com.
+zone28.hotwords.com.br.
+webcache.googleusercontent.com.
+sloac.stanford.edu.
+www.familiasodalite.org.
+mx1.cardiacspecialists.com.
+www.myvoicenation.com.
+checkip.dyndns.org.
+176.131.5.174.in-addr.arpa.
+49.149.220.66.in-addr.arpa.
+seher.es.
+photos-b.ak.fbcdn.net.
+collegiumpharmaceuticals.com.
+go.microsoft.com.
+www.adxpansion.com.
+smtp1.polyglass-com.fabbricadigitale.it.
+mx2.e107.ru.
+190.143.73.121.in-addr.arpa.
+profile.ak.fbcdn.net.
+mauriciogochez.wordpress.com.
+www.google.com.
+glassstreaminc.com.
+144.107.49.190.in-addr.arpa.
+static.ak.fbcdn.net.
+clients1.google.com.
+ask.com.
+gravatar.com.
+a.root-servers.net.
+i.xiaomi.net.
+ylmemphis.com.
+svky722aq.g47y2u3b.
+www.enceinte.com.
+clk.secureintl.com.
+rcp.na.blackberry.com.
+pixel.quantserve.com.
+titanium30-en.url.trendmicro.com.
+d2058748.instant.xoom.it.
+www.facebook.com.
+mail.st10.ru.
+creative.ak.fbcdn.net.
+pixel.facebook.com.
+ssl.gstatic.com.
+www.bittorrent.com.
+1.presence.emsc-csem.org.
+lietest.ru.
+a1209.phobos.apple.com.
+a995.mm1.akamai.net.
+ukrbiznes.com.
+dns.msftncsi.com.
+js2.wlxrs.com.
+relay2.interexc.com.
+s-static.ak.facebook.com.
+feeds2.feedburner.com.
+www.rapid.duareka.net.
+154.71.100.190.in-addr.arpa.
+182.137.137.201.in-addr.arpa.
+www.tequilaelgranjurado.com.
+tc21.easythumbhost.com.
+cismdesign.com.
+static.ak.facebook.com.
+saltillo.olx.com.mx.
+romancethelove.blogspot.com.
+safebrowsing.clients.google.com.
+transfire.transwitch.com.
+tunnel.cfw.trustedsource.org.
+books.google.com.
+photos-a.ak.fbcdn.net.
+mx.deportes.yahoo.com.
+219.160.206.112.in-addr.arpa.
+jpscu.com.
+softwaregate.net.
+126.197.17.177.in-addr.arpa.
+seatgeek.com.
+byfiles.storage.msn.com.
+bloggingwomen.blogspot.com.
+a3.twimg.com.
+106.9.211.217.in-addr.arpa.
+86yweeqdz.87th.
+a.root-servers.net.
+www.facebook.com.
+users.ucom.net.
+interspar.at.
+login.yahoo.com.
+vmx.alumni.iwu.edu.redcondor.net.
+saintedwards.net.
+dns.msftncsi.com.
+www.facebook.com.
+apps.facebook.com.
+238.169.119.112.in-addr.arpa.
+rnt.over-blog.com.
+ecoart-group.ru.
+db2.stb.s-msn.com.
+jerimmio.com.
+a.root-servers.net.
+googleads.g.doubleclick.net.
+zh-cn.facebook.com.
+schools.naperville203.org.
+www.vungtrom.com.
+a1.sphotos.ak.fbcdn.net.
+translate.google.com.
+bs.serving-sys.com.
+132.225.60.85.in-addr.arpa.
+o-o.preferred.dfw06s10.v24.lscache5.c.youtube.com.
+mx1.mail.eu.yahoo.com.
+155.90.35.189.in-addr.arpa.
+www.lge.com.
+www.google.com.
+xvideos.net.
+97.48.173.186.in-addr.arpa.
+clients2.google.com.
+hdlpg.com.
+b-0.19-21069008.60081.1518.19d4.2f4a.410.0.p4c4upl48i7g9jqs1u4ppgcikj.avqs.mcafee.com.
+csi.gstatic.com.
+baixartemplatesnovos.webs.com.
+c.msn.com.tw.
+googlemapsdirectory.com.
+volgograd.gs.ru.
+a3.sphotos.ak.fbcdn.net.
+.
+122.175.89.85.in-addr.arpa.
+latasybotellasdejuancruz.blogspot.com.
+37.233.114.201.in-addr.arpa.
+svcs.cnn.com.
+songsfrompaul.tumblr.com.
+mail.condotteamerica.com.
+zoomointernet.net.
+ns1.purple-hosting.com.
+ec.atdmt.com.
+ville.mons.be.
+js.revsci.net.
+allegacyfcu.org.s5a2.psmtp.com.
+www.20minutos.es.
+gfas.com.
+rjtcreative.com.
+profile.ak.fbcdn.net.
+www.bna.com.ar.
+koa4x23zh.n34d6h5g.
+121.3.234.190.in-addr.arpa.
+4048971.frasesinolvidables1.com.ar.
+wadmag.com.
+resources.search.conduit.com.
+www.chinaontrade.com.
+a7.sphotos.ak.fbcdn.net.
+chat.facebook.com.
+www.zapreader.com.
+.
+mx2.deitron.de.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+safebrowsing-cache.google.com.
+minicatalog.bandoo.com.
+www.gotabletennis.com.
+8.64.43.186.in-addr.arpa.
+store.yahoo.com.
+hugdablock.com.
+api.twitter.com.
+ui.skype.com.
+a2.sphotos.ak.fbcdn.net.
+38.242.49.116.in-addr.arpa.
+tpebb.hanjin.com.
+db._dns-sd._udp.0.177.168.192.in-addr.arpa.
+ksn2-12.kaspersky-labs.com.
+a3.sphotos.ak.fbcdn.net.
+g7qrj152p.07dq.
+microjuris.com.
+www.animalamigo.com.
+photos-h.ak.fbcdn.net.
+l.yimg.com.
+cdn.lfstmedia.com.
+beastpdx.com.
+tsm04.eset.com.
+a3.twimg.com.
+simonsulca.blogspot.com.
+static.ak.fbcdn.net.
+6sbacyrhg.z15j4m9h.
+apps.facebook.com.
+156.155.214.189.in-addr.arpa.
+www.lipsod.com.
+imagenes.telematica.net.
+broekhuisjuweliers.nl.
+shared.live.com.
+www.youtube.com.
+angelaliguori.com.
+google.com.
+luminopress.com.
+a.root-servers.net.
+ajax.googleapis.com.
+teredo.ipv6.microsoft.com.
+126.64.219.108.in-addr.arpa.
+lh4.ggpht.com.
+www.semana.com.
+215.117.99.177.in-addr.arpa.
+cdnma.com.
+_118_30_9.
+odsgirl.com.
+www.californiasar.org.
+orthopa.com.
+platform.twitter.com.
+91.193.12.189.in-addr.arpa.
+www.billingsupport.com.
+accountservices.msn.com.
+stun.client.akadns.net.
+dns.msftncsi.com.
+d2092087.xoom.it.
+music.wikia.com.
+46.72.4.186.in-addr.arpa.
+pubads.g.doubleclick.net.
+ejabat.google.com.
+www.cnna.gob.ec.
+www.facebook.com.
+l5.zedo.com.
+s7.addthis.com.
+capitalhgroup.com.s200a1.psmtp.com.
+olypen.com.s6b1.psmtp.com.
+cs5096.vk.com.
+greekave.com.
+224.49.0.172.in-addr.arpa.
+www.enigmasymisterios.net.
+b.scorecardresearch.com.
+tytut.com.
+17.171.19.178.in-addr.arpa.
+www.cari.net.
+www.mentesdeacido.net.
+7p18hlsar.x73g2g4i.
+a.root-servers.net.
+foss.com.s6b2.psmtp.com.
+www.google.com.
+178.12.186.190.in-addr.arpa.
+lib.enmuros.cc.nm.us.
+cs5984.vk.com.
+ads.contentabc.com.
+102.126.19.190.in-addr.arpa.
+ghmslaw.com.
+i1.ytimg.com.
+dx.doi.org.
+www.google.com.
+itunes.apple.com.
+avico.ru.
+tacuru.ourproject.org.
+228.115.103.177.in-addr.arpa.
+col.stc.s-msn.com.
+140.196.165.46.in-addr.arpa.
+b.scorecardresearch.com.
+45-courier.push.apple.com.
+91.131.122.190.in-addr.arpa.
+www.hell-yes-clothing.com.
+csi.gstatic.com.
+76188.hittail.com.
+sync.mathtag.com.
+kaydet.com.
+dps.msg.yahoo.com.
+www.alexnolan.net.
+c0014159.ssl.cf1.rackcdn.com.
+mail.craigandlori.com.
+a7.sphotos.ak.fbcdn.net.
+a.root-servers.net.
+www.facebook.com.
+1804289383.localhost.
+wrzuta.pl.
+teredo.ipv6.microsoft.com.
+www.youtube.com.
+11.176.58.187.in-addr.arpa.
+go.microsoft.com.
+kamsanes.ru.
+mail.live.com.
+97.205.177.190.in-addr.arpa.
+a1334.phobos.apple.com.
+241.115.138.190.in-addr.arpa.
+api.twitter.com.
+ontika.net.
+yonoestuvealli.blogspot.com.
+it.html.net.
+www.facebook.com.
+mail.acegaming.ru.
+profile.ak.fbcdn.net.
+img1.blogblog.com.
+a2.sphotos.ak.fbcdn.net.
+83.100.245.190.in-addr.arpa.
+a.root-servers.net.
+pop.gmail.com.
+profile.ak.fbcdn.net.
+om.co.
+pixel.quantserve.com.
+alton.k12.nh.us.s5a2.psmtp.com.
+s.ytimg.com.
+a6.sphotos.ak.fbcdn.net.
+a.root-servers.net.
+www.tecnomaq.com.mx.
+www.bingomingoreklam.com.
+odcons.com.
+_584_15_0.
+a.ads2.msads.net.
+18.50.86.85.in-addr.arpa.
+mail.epasa.com.
+www.leipzig-sachsen.de.
+abcgr.ru.
+t0.gstatic.com.
+www.facebook.com.
+stage.traffiliate.com.
+um12.eset.com.
+www.youtube.com.
+fbcdn-sphotos-a.akamaihd.net.
+voipc.sip.yahoo.com.
+mail.realestate-redding.com.
+166.22.244.189.in-addr.arpa.
+pixel.quantserve.com.
+215.150.250.190.in-addr.arpa.
+smtp2.eprod.com.
+g.microsoft.com.
+a.root-servers.net.
+www.canalava.org.mx.
+lb._dns-sd._udp.0.2.168.192.in-addr.arpa.
+mail.wescottlaw.com.
+linksfolders.disqus.com.
+16.140.37.177.in-addr.arpa.
+nordkapp.ru.
+23.146.182.189.in-addr.arpa.
+mscrl.microsoft.com.
+159.209.13.201.in-addr.arpa.
+22.155.210.201.in-addr.arpa.
+h.atdmt.com.
+81.222.195.187.in-addr.arpa.
+kreslatimo.ru.
+mail.live.com.
+api.webrep.avast.com.
+4.99.24.189.in-addr.arpa.
+i1.ytimg.com.
+35.180.71.201.in-addr.arpa.
+edctr.scdsb.on.ca.
+166.190.174.189.in-addr.arpa.
+a3.sphotos.ak.fbcdn.net.
+www.facebook.com.
+www.livejasmin.com.
+s.youtube.com.
+pixel.quantserve.com.
+2leep.com.
+mail.liasa.com.
+www.tecowestinghouse.com.mx.
+drmorley.net.s7b1.psmtp.com.
+www.tusdiscosgratis.com.
+apis.google.com.
+a2.sphotos.ak.fbcdn.net.
+ad-emea.doubleclick.net.
+115.16.147.186.in-addr.arpa.
+secure.shared.live.com.
+a2.sphotos.ak.fbcdn.net.
+m.google.com.
+apps.facebook.com.
+www.clipartlab.com.
+p1t.ru.
+184.204.10.68.in-addr.arpa.
+frivcar.blogspot.com.
+161.177.204.94.in-addr.arpa.
+mail.bigguy.com.
+mx.youtube.com.
+teredo.ipv6.microsoft.com.
+56.135.104.189.in-addr.arpa.
+1m62:9zzv.05lv.
+86.137.88.186.in-addr.arpa.
+sprosidoctora.ru.
+105.50.8.200.in-addr.arpa.
+www.appleaks.com.
+wpad.
+burnhamonline.com.s7b2.psmtp.com.
+a6.sphotos.ak.fbcdn.net.
+static.ak.fbcdn.net.
+uig1saply.z78a3x8p.
+a.root-servers.net.
+profile.ak.fbcdn.net.
+um13.eset.com.
+10.rarbg.com.
+p3old8fsi.z28s2c9q.
+static.ak.fbcdn.net.
+a7.sphotos.ak.fbcdn.net.
+woofbyte.com.
+www.addthis.com.
+sn1msg3030109.gateway.messenger.live.com.
+b.scorecardresearch.com.
+b.scorecardresearch.com.
+time.chttl.com.tw.
+mx8.mail.ru.
+monc.net.
+stats.avg.com.
+blog.ellegirl.com.
+160.195.10.216.in-addr.arpa.
+hiltonsanantonioap.com.1.arsmtp.com.
+www.adobe.com.
+www.gaysex.com.
+api.ning.com.
+135.82.76.187.in-addr.arpa.
+www.guitarsound.net.
+161.99.117.200.in-addr.arpa.
+a.root-servers.net.
+www.seizurechicken.com.
+pagead2.googlesyndication.com.
+i1.ytimg.com.
+c7.zedo.com.
+iavggug.info.
+whoami.akamai.net.
+ozconnect.net.
+a.root-servers.net.
+baymsg1020311.gateway.messenger.live.com.
+translate.googleapis.com.
+ns2.art-host.ru.
+franklinfavorite.com.
+www.youtube.com.
+www.gstatic.com.
+www.photovaco.com.
+mario.chulojuegos.com.
+61.112.39.77.in-addr.arpa.
+a.root-servers.net.
+windemo.deckadance.com.
+god-vs-human.free-opinion.com.
+halcobaca.min-saude.pt.
+sitecheck2.opera.com.
+www.youtube-nocookie.com.
+alerts.conduit-services.com.
+astound.net.
+earthlinjk.net.
+frogmans.net.
+fonts.googleapis.com.
+fbcdn-profile-a.akamaihd.net.
+a.root-servers.net.
+146.141.208.201.in-addr.arpa.
+www.smule.com.
+tw.apple.com.
+rad.msn.com.
+highexpert.ru.
+www.soumaya.com.mx.
+bajaxtreme.com.
+88.241.104.186.in-addr.arpa.
+www.managua.gob.ni.
+213.155.26.79.in-addr.arpa.
+s7.addthis.com.
+autos.mercadolibre.com.ar.
+jabber13.liveprofile.com.
+counterb.statcounter.com.
+www.plcsim.com.
+a.root-servers.net.
+ats.tumri.net.
+a3.da1.akamai.net.
+mail-gw.bcp.com.
+api.twitter.com.
+i1.ytimg.com.
+nova937.com.au.
+221.126.224.80.in-addr.arpa.
+250.91.10.187.in-addr.arpa.
+l.addthiscdn.com.
+dl5.torrentzap.com.
+tinyprints.widget.custhelp.com.
+itunes.apple.com.
+21.133.222.201.in-addr.arpa.
+covpatlaw.com.mx4.aantispam.rcimx.net.
+www.parcs-naturels-regionaux.tm.fr.
+us.tracker.worldofwarcraft.com.
+pixel.facebook.com.
+www.youtube.com.
+ytimg.l.google.com.
+ocsp.verisign.com.
+api.facebook.com.
+11-courier.push.apple.com.
+a.root-servers.net.
+admissions.arizona.edu.
+a1.twimg.com.
+r._dns-sd._udp.0.2.168.192.in-addr.arpa.
+clkads.com.
+a8.sphotos.ak.fbcdn.net.
+17.2.60.186.in-addr.arpa.
+www.youtube.com.
+www.abibids.com.
+ns2.makeshop.jp.
+weboutlook.beiersdorfgroup.com.
+google.com.
+s.youtube.com.
+www.webtoolol.com.
+vy8uzdb5z.t24g0u8l.
+57.225.172.186.in-addr.arpa.
+a.root-servers.net.
+5483.live.streamtheworld.com.
+mail.webcapades.net.
+1channel.ch.
+www.rinconjuegos.com.
+a.root-servers.net.
+trade-futures.com.
+www.telemundoeventos.com.
+d5k8r31tz.69xz.
+lemamed.ru.
+googleads.g.doubleclick.net.
+97.181.165.201.in-addr.arpa.
+bay.gateway.messenger.live.com.
+221.138.180.189.in-addr.arpa.
+cox.net.
+uk.yahoo.com.
+facebook.com.
+90.251.160.190.in-addr.arpa.
+a.root-servers.net.
+187.247.30.189.in-addr.arpa.
+mail.fountain.ru.
+support.google.com.
+sturehof.com.
+153.155.220.66.zen.spamhaus.org.
+pixel.rubiconproject.com.
+s.ytimg.com.
+s1-onenote.vo.msecnd.net.
+cdn1.certified-apps.com.
+www.machinediagnostics.com.
+ca.wikipedia.org.
+mwcdn.50cubes.com.
+clients1.google.com.
+lenoxhomeloans.com.
+www.medicalteams.org.
+www.likepagebuilder.com.
+j22mnely2.30yf.
+apis.google.com.
+shockbolt.deviantart.com.
+a.root-servers.net.
+pcf-ironmail01.wusm-pcf.wustl.edu.
+profile.ak.fbcdn.net.
+ads.lfstmedia.com.
+www.amatuer-pics.net.
+ytstatic.l.google.com.
+googleads.g.doubleclick.net.
+a-0.19-2709e071.d0d0083.1518.19d3.3ea1.410.0.wqgt8tgc81eq48q14ca4dz2tfb.avqs.mcafee.com.
+dopplershift.net.
+rts.fling.doublepimp.com.
+245.98.184.186.in-addr.arpa.
+60.128.45.186.in-addr.arpa.
+evintl-aia.verisign.com.
+tuned.mobi.
+ds.addthis.com.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+88.27.230.119.in-addr.arpa.
+g.espncdn.com.
+81.123.168.189.in-addr.arpa.
+183.207.39.187.in-addr.arpa.
+tchimb.spb.su.
+45.111.248.201.in-addr.arpa.
+safebrowsing-cache.google.com.
+226.172.138.201.in-addr.arpa.
+dubai.isnuts.googlepages.com.
+profiles.google.com.
+sp.cwfservice.net.
+r._dns-sd._udp.lan.
+50.214.191.64.in-addr.arpa.
+connect.facebook.net.
+www.facebook.com.
+hma.org.
+maps.googleapis.com.
+wiki.answers.com.
+181.178.97.92.in-addr.arpa.
+229.3.63.151.in-addr.arpa.
+msc.wlxrs.com.
+157.220.29.189.in-addr.arpa.
+rad.msn.com.
+googleads.g.doubleclick.net.
+www.merchantselect.com.
+a7.sphotos.ak.fbcdn.net.
+u47.eset.com.
+www.google.com.
+9.174.251.190.in-addr.arpa.
+boltamps.com.
+static.pbc.com.
+a.root-servers.net.
+aterminus.files.wordpress.com.
+tienda.jasani.es.
+mail.google.com.
+www.googleadservices.com.
+a.root-servers.net.
+images.ip.com.
+tickets.musicbrainz.org.
+searchclient.live.net.
+echinoblog.blogspot.com.
+mail.peaceful.com.
+avtoperevozki.com.
+safebrowsing.clients.google.com.
+www.bywifi.com.
+anastasiamexico.com.
+prostimenya.com.
+cw3.com.
+inbound.fastener-express.com.netsolmail.net.
+crl.microsoft.com.
+pixel.facebook.com.
+comune.savignone.ge.it.
+smtp3.etssi.com.
+lh6.googleusercontent.com.
+members.livejasmin.com.
+30.courier-push-apple.com.akadns.net.
+profile.ak.fbcdn.net.
+teredo.ipv6.microsoft.com.
+aforestfrolic.com.
+www.rpmrcproducts.com.
+252.165.91.186.in-addr.arpa.
+apis.google.com.
+wn5iftq5l.g50d2e9u.
+www.easy-down.net.
+www.atunexpress.com.
+a.root-servers.net.
+212.226.174.189.in-addr.arpa.
+stores.ebay.com.
+pilotmedia.ru.
+cpk9p5jqy.52vj.
+msn.com.
+queer.com.
+check6.facebook.com.
+www.businessenglishebook.com.
+my.msn.com.
+b._dns-sd._udp.0.1.168.192.in-addr.arpa.
+www.highboost.com.
+rad.dsc.ru.
+www.descuentocity.com.
+es.wikipedia.org.
+8.0.168.192.in-addr.arpa.
+www.grist.org.
+search.powersportsplus.com.
+documentales.videosyonkis.com.
+10-async.olark.com.
+a.root-servers.net.
+ssl.gstatic.com.
+samsungmobilemoments.com.
+a.root-servers.net.
+memorva.jp.
+www.facebook.com.
+5nlkw2x23.c14b8o7y.
+touhycjbkh.net.
+va1en.sftcdn.net.
+a4.sphotos.ak.fbcdn.net.
+t1.gstatic.com.
+translate.google.com.
+txads.buzzcity.net.
+twitter.com.
+207.169.14.186.in-addr.arpa.
+a.root-servers.net.
+dns.msftncsi.com.
+tcpv4.easythumbhost.com.
+c707977.r77.cf2.rackcdn.com.
+ncshkkoipm01.ap.jnj.com.
+www.bmf.co.uk.
+wfcgjjov9.v91b6e5y.
+g.ceipmsn.com.
+static03.boobytwister.com.
+www.microsoft.com.
+neuroskills.com.
+ssl.gstatic.com.
+google.com.
+a.root-servers.net.
+dns.msftncsi.com.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+download351.avast.com.
+www.facebook.com.
+api.webrep.avast.com.
+kangas.no.
+image.epost.go.kr.
+213.73.135.187.in-addr.arpa.
+twitter.com.
+pop.advecs.com.
+www.weebirdy.com.
+highslide.com.
+e5016.b.akamaiedge.net.
+a-0.19-230fe081.a0e0580.1518.19d4.2f4a.400.0.smgql7jzk5g8d9zff4tq7njzcj.avqs.mcafee.com.
+a.root-servers.net.
+ages-collection.ru.
+www.gstatic.com.
+google.com.
+bleachadventurerol.foroactivo.net.
+falda.fr.
+bioserv.de.
+css1.beoo.com.
+i3.ytimg.com.
+checkip.dyndns.org.
+105.240.51.190.in-addr.arpa.
+www.banddirector.com.
+www.stat-togo.org.
+192.70.15.186.in-addr.arpa.
+mx.queensborofarms.com.
+www.checkers.com.
+www.riveonline.com.
+135.34.236.200.in-addr.arpa.
+globalcontctsinc.com.
+7.17.230.190.in-addr.arpa.
+static.ak.fbcdn.net.
+i.ytimg.com.
+193.188.176.190.in-addr.arpa.
+media.a1.com.mk.
+wilky.co.uk.
+17.192.139.175.in-addr.arpa.
+photos-e.ak.fbcdn.net.
+i4.ytimg.com.
+www.sigrealm.com.
+dibblyfresh1.blogspot.com.
+2xixvsj9q.36lc.
+i1.gatewayinterface.com.
+humor.mundodescargas.com.
+translate.googleapis.com.
+freestylebmx.org.
+translation.engine.conduit-services.com.
+www.chulojuegos.com.
+photos-f.ak.fbcdn.net.
+safebrowsing.clients.google.com.
+gurux.net.
+mail.eland-energy.com.
+28.8.57.186.in-addr.arpa.
+www.pdf-lib.ru.
+patrimonio.com.mx.
+a.root-servers.net.
+configuration.apple.com.
+www.zerorc.com.
+jagerbar.ru.
+plus.google.com.
+www.facebook.com.
+ajax.googleapis.com.
+mortgages4solutions.com.
+support.google.com.
+6.20.191.91.in-addr.arpa.
+teympd:og.26jb.
+www.iheartplayzynga.com.
+ds.addthis.com.
+_477_63_2.
+mailserver.holidayinn-batam.com.
+twitter.com.
+www.morhipo.com.
+sasib-na.com.
+37.124.226.201.in-addr.arpa.
+s3.amazonaws.com.
+blu.stb.s-msn.com.
+video.l3.fbcdn.net.
+planetasigarra.blogspot.com.
+0-44.channel.facebook.com.
+lh4.googleusercontent.com.
+_dns-llq._udp.push.apple.com.
+4.11.31.211.in-addr.arpa.
+photos-c.ak.fbcdn.net.
+www.perfil.com.
+db._dns-sd._udp.0.1.168.192.in-addr.arpa.
+69.33.248.189.in-addr.arpa.
+s2.youtube.com.
+www.update.microsoft.com.
+www.mediawiki.org.
+store.millerheiman.com.
+blogs.eset-la.com.
+a6.sphotos.ak.fbcdn.net.
+a724.phobos.apple.com.
+140cc.v.fwmrm.net.
+db._dns-sd._udp.lan.
+vh14.ppstream.com.
+xcalabaja.com.
+74.43.98.66.in-addr.arpa.
+www.stick-up-kids.de.
+www.juegos.com.
+iphone.gogii.com.
+static.ak.fbcdn.net.
+latino.msn.com.
+ilmiopensiero.forumcommunity.net.
+www.update.microsoft.com.
+mbcc.com.
+www.recycling-machine.com.
+csi.gstatic.com.
+profile.ak.fbcdn.net.
+accounts.l.google.com.
+o-o.preferred.pz.www.google.com.
+cscsrvnew1app30.amer.csc.com.
+s10.histats.com.
+profile.ak.fbcdn.net.
+chromejs.s3.amazonaws.com.
+a.root-servers.net.
+2.30.231.201.in-addr.arpa.
+royal-trading.jp.
+www.google-analytics.com.
+33.52.174.190.in-addr.arpa.
+i1.ytimg.com.
+photos-d.ak.fbcdn.net.
+160.111.229.189.in-addr.arpa.
+ergogroup.no.
+9z772drlt.89ys.
+lb._dns-sd._udp.0.0.168.192.in-addr.arpa.
+16.101.220.201.in-addr.arpa.
+load.monohrome.com.
+a1406.w42.akamai.net.
+content.yieldmanager.edgesuite.net.
+anemofilm.ru.
+www.alexa.com.
+mdawmdewotaxmjaxmg.org.
+espanol.weather.com.
+thumbs1.ebaystatic.com.
+content.dl-rms.com.
+no.hotels.com.
+dailymaverick.co.za.
+www.kurims.kyoto-u.ac.jp.
+api.conduit.com.
+179.28.214.66.in-addr.arpa.
+a5.sphotos.ak.fbcdn.net.
+serviceimg.pricegong.com.
+86.176.19.83.in-addr.arpa.
+sp.cwfservice.net.
+justscandinavian.com.
+medsos.ru.
+zefone.com.
+mail2.colibri.krsk.ru.
+c-0.19-a309f481.483.1518.19d4.3ea1.210.0.cj1um18aa3789ls947agauibjb.avqs.mcafee.com.
+s4.argim.net.
+admin.mshome.net.
+static02.olx-st.com.
+h.live.com.
+ksn2-12.kaspersky-labs.com.
+www.go.microsoft.akadns.net.
+gs-loc.apple.com.
+aquariablog.wordpress.com.
+www.kisseo.de.
+126.207.40.114.in-addr.arpa.
+hi-in.facebook.com.
+104.0.0.192.in-addr.arpa.
+cs510102.vkontakte.ru.
+www.google.com.
+99.153.60.183.in-addr.arpa.
+www.roughcooking.com.
+photos-e.ak.fbcdn.net.
+sitepointbroadcast.createsend4.com.
+60.39.191.95.in-addr.arpa.
+165.213.186.189.in-addr.arpa.
+photos-d.ak.fbcdn.net.
+assuretec.com.
+static.ak.fbcdn.net.
+arendatr.ru.
+googleads.g.doubleclick.net.
+images.movielink.com.
+acriacao.com.
+www.youtube.com.
+photos-g.ak.fbcdn.net.
+dogtraining.com.
+personal.avira-update.com.
+theenvelope.latimes.com.
+www.redefiningpiano.com.
+kikkut.no.
+a0.twimg.com.
+nvsslassets.msnbc.msn.com.
+a6.sphotos.ak.fbcdn.net.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+mail.krs.baltimore.ru.
+_995_87_4.
+gfx2.hotmail.com.
+v20.nonxt2.c.youtube.com.
+static.ak.fbcdn.net.
+167.59.126.71.in-addr.arpa.
+pop.jocrf.org.
+www.lanvin.com.
+www.hammervision.com.tr.
+telbarato.net.
+m.addthisedge.com.
+_759_41_4.
+vevo.ly.
+db._dns-sd._udp.0.1.168.192.in-addr.arpa.
+safebrowsing-cache.google.com.
+xxy.com.
+7.189.251.190.in-addr.arpa.
+www.forever-christies.com.
+profile.ak.fbcdn.net.
+sisar4k.com.
+198.86.168.192.in-addr.arpa.
+dns.msftncsi.com.
+couponbuddy.s3.amazonaws.com.
+conduit.anybodyoutthere.com.
+snsgw.samsungmobile.com.
+apps.facebook.com.
+www.naltqi.com.
+www.google-analytics.com.
+photos-g.ak.fbcdn.net.
+250.254.243.190.in-addr.arpa.
+69.227.51.173.in-addr.arpa.
+chriss2d.deviantart.com.
+musica.itematika.com.
+us.lrd.yahoo.com.
+189.147.13.187.in-addr.arpa.
+166.98.232.189.in-addr.arpa.
+83.104.130.85.in-addr.arpa.
+www.cosmeticclub.es.
+photos-a.ak.fbcdn.net.
+www.losbackyardiganss.blogspot.com.
+dynamicdialogs.alert.conduit-services.com.
+241.195.137.186.in-addr.arpa.
+log.adap.tv.
+bathcc.com.s8a1.psmtp.com.
+krisknits.blogspot.com.
+www.chicashi5.org.
+vtr.net.
+a.root-servers.net.
+a5.sphotos.ak.fbcdn.net.
+maps.gstatic.com.
+a.root-servers.net.
+203.211.82.95.in-addr.arpa.
+redaktion-bahamas.org.
+ms-frontend.hse.ru.
+teredo.ipv6.microsoft.com.
+app.rounds.com.
+187.92.107.200.in-addr.arpa.
+connect.facebook.net.
+71.143.5.184.in-addr.arpa.
+167.108.24.83.in-addr.arpa.
+www.facebook.com.
+slipknotla.blogspot.com.
+242.146.102.94.in-addr.arpa.
+www.cintegral.cl.
+campaignjobs.asia.
+fb.37cs.com.
+google.com.
+a3.sphotos.ak.fbcdn.net.
+brightsideofthesun.com.
+www.carascorridas.com.
+www.facebook.com.
+a718.g.akamai.net.
+www.siteadvisor.com.
+px.smowtion.com.
+a3.sphotos.ak.fbcdn.net.
+www.orangetree.co.uk.
+courterco.com.s8a2.psmtp.com.
+6-0.qlty.finarea.ch.
+www.scvtv.com.
+ing-things.blogspot.com.
+deals.timeoutnewyorkkids.com.
+i4.ytimg.com.
+tc.v9.cache6.c.youtube.com.
+www.bywifi.com.
+cs9439.vk.com.
+a.root-servers.net.
+www.facebook.com.
+eberspacher-russia.ru.
+www.youtube.com.
+_255_86_5.
+muonline.biz.
+safebrowsing.clients.google.com.
+osnews.com.
+www.gstatic.com.
+243.131.110.123.in-addr.arpa.
+pop3.live.com.
+bostonrehab.com.
+malah.biz.
+mail.google.com.
+static.ak.facebook.com.
+support.google.com.
+l35.member.mud.yahoo.com.
+video-6.filmix.net.
+b.scorecardresearch.com.
+connect.facebook.net.
+www.guardiantickets.co.uk.
+support.google.com.
+thumbnails46.imagebam.com.
+a8.sphotos.ak.fbcdn.net.
+www.businesssearchengine.com.au.
+ad.doubleclick.net.
+profile.ak.fbcdn.net.
+174.244.240.201.in-addr.arpa.
+www.facebook.com.
+www.tmz.com.
+www.xxxsexymilfs.com.
+107.197.242.189.in-addr.arpa.
+sites.google.com.
+ad.yieldmanager.com.
+feeds.cnet.com.
+static.ak.fbcdn.net.
+static.ak.fbcdn.net.
+ads2.msads.net.
+www.bigchestedbabes.com.
+making50fabulous.blogspot.com.
+www.vbauctions.net.
+creative.ak.fbcdn.net.
+141.138.193.173.in-addr.arpa.
+dnl-01.geo.kaspersky.com.
+blog.naver.com.
+css3.info.
+142.192.186.24.in-addr.arpa.
+gfx2.hotmail.com.
+kcstar.com.
+_ldap._tcp.
+ads.bluelithium.com.
+a.root-servers.net.
+249.180.204.190.in-addr.arpa.
+scientxp.com.
+132.199.55.96.in-addr.arpa.
+www.google-analytics.com.
+rosivg25.wordpress.com.
+www.iamshekhar.co.cc.
+99dn7z72y.43rs.
+ads.adbrite.com.
+whitecointerra.com.
+251.42.156.201.in-addr.arpa.
+technologie.gazeta.pl.
+3.ns1631263.info.
+ats.tumri.net.
+aventuras.isladejuegos.es.
+yourgamersparadise.com.
+l.addthiscdn.com.
+www.addthis.com.
+twitter.com.
+8.165.137.175.in-addr.arpa.
+accugenix.com.s10a2.psmtp.com.
+aliner.com.
+safebrowsing-cache.google.com.
+clients1.google.com.
+s-static.ak.fbcdn.net.
+a.root-servers.net.
+uprl.kandk.ru.
+www.download.windowsupdate.com.
+www.hpwebos.com.
+www.bigbuttslikeitbig.org.
+www.facebook.com.
+181.225.215.173.in-addr.arpa.
+support.google.com.
+1.0.0.127.dnsbugtest.1.0.0.127.in-addr.arpa.
+api.twitter.com.
+www.nycgo.com.
+236.251.171.200.in-addr.arpa.
+www.aviransplace.com.
+static.ak.fbcdn.net.
+hospiceheart.org.s8a1.psmtp.com.
+static.ak.fbcdn.net.
+192.140.138.187.in-addr.arpa.
+202.104.1.201.in-addr.arpa.
+502.talkgadget.google.com.
+t1.gstatic.com.
+ksn3-11.part2.kaspersky-labs.com.
+157.113.250.190.in-addr.arpa.
+listen.cinemix.fr.
+accountservices.msn.com.
+sn104w.snt104.mail.live.com.
+teredo.ipv6.microsoft.com.
+www.draftfcb.com.mx.
+l.yimg.com.
+id.wikipedia.org.
+218.239.84.59.in-addr.arpa.
+members.ansi.org.
+168.7.56.92.in-addr.arpa.
+200.2.168.192.in-addr.arpa.
+dcpff.tumblr.com.
+a7.sphotos.ak.fbcdn.net.
+swellwatch.wetsand.com.
+adors.com.
+www.rugsyd.com.au.
+www.facebook.com.
+www.aemultimedia.es.
+ddpc.com.s5b2.psmtp.com.
+240.196.197.68.in-addr.arpa.
+geo.tp-cdn.com.
+entergy.com.
+met.no.
+www.didacmania.com.
+rar-repair.nsware.com.
+www.easy.lv.
+www.wheels-and-wings.org.uk.
+89.140.112.200.in-addr.arpa.
+apps.facebook.com.
+kiteboard.ru.
+s2.youtube.com.
+54.96.72.202.in-addr.arpa.
+136.137.232.24.in-addr.arpa.
+www.belkin.com.
+v4.nonxt3.c.youtube.com.
+www.bridgepub.mx.
+widgets.amung.us.
+hyundai-info.ru.
+ksn2-12.kaspersky-labs.com.
+he.wikipedia.org.
+archives.chennaionline.com.
+20minutos.feedsportal.com.
+p05-keyvalueservice.icloud.com.akadns.net.
+google.com.
+237.subnet118-97-164.static.astinet.telkom.net.id.
+hybrydica.ru.
+audiodrums.com.
+3.203.183.189.in-addr.arpa.
+100.141.121.74.in-addr.arpa.
+col.stb00.s-msn.com.
+www.c64-wiki.de.
+bloggerplugins.org.
+pixel.facebook.com.
+m.addthisedge.com.
+teredo.ipv6.microsoft.com.
+jigsaw.w3.org.
+a1725.l.akamai.net.
+mail.google.com.
+profile.ak.fbcdn.net.
+alvarsoft.com.
+pixel.facebook.com.
+m.facebook.com.
+manulifesecurities.com.
+www.lazoblanco.org.
+244.27.146.99.in-addr.arpa.
+21.30.143.187.in-addr.arpa.
+51.77.2.195.in-addr.arpa.
+zsxifmeksub.org.
+136.111.93.186.in-addr.arpa.
+kumr.lns.com.
+js.wlxrs.com.
+www.levimage.com.
+adhitzads.com.
+cargo2000.dk.
+safebrowsing-cache.google.com.
+lb._dns-sd._udp.0.2.168.192.in-addr.arpa.
+www.l.google.com.
+www.al-anonuk.org.uk.
+creative.ak.fbcdn.net.
+228.219.132.190.in-addr.arpa.
+www.campaignjobs.asia.
+www.secreto-chino.com.
+www.google.com.
+a.root-servers.net.
+s1.wp.com.
+fbcdn-profile-a.akamaihd.net.
+r._dns-sd._udp.lan.
+105.240.234.81.in-addr.arpa.
+socpixel.bidsystem.com.
+connect.facebook.net.
+hysexch07.hye.co.il.
+i140.photobucket.com.
+174.162.108.186.in-addr.arpa.
+137.142.243.147.in-addr.arpa.
+courchevel.su.
+wbns.com.s7b2.psmtp.com.
+28.207.221.87.in-addr.arpa.
+196.15.46.90.in-addr.arpa.
+uwbfyc.com.
+pixel.facebook.com.
+www.threeweb.ad.jp.
+profile.ak.fbcdn.net.
+i1.tagstat.com.
+www.youtube.com.
+www.addingsite.com.
+50.156.220.66.in-addr.arpa.
+i4.ytimg.com.
+45.31.168.192.in-addr.arpa.
+146.131.177.189.in-addr.arpa.
+srv.srvdomain.com.
+apps.filestube.com.
+yfrog.com.
+www.monumentalgames.com.
+174.196.91.186.in-addr.arpa.
+images.emusic.com.
+alimentosweb.galeon.com.
+installer.frostwire.com.
+connect.facebook.net.
+ksn2-12.kaspersky-labs.com.
+fbcdn-profile-a.akamaihd.net.
+a.root-servers.net.
+dialtone.com.
+tts.orel.ru.
+assets.t.popupbooster.com.
+www.facebook.com.
+vk.com.
+cdn1.xamez.inxy-host.com.
+_546_20_1.
+a.root-servers.net.
+mosenergo.ru.
+eltamborrugiente.blogspot.com.
+www2.esmas.com.
+www.latbus.com.
+www.transl.net.
+vgmanager.no.
+kojyyj.com.
+barracuda.montereyclub.com.
+tools.google.com.
+a.root-servers.net.
+d2090462.xoom.it.
+www.deskdivers.com.
+tcacdn-3.thecelebarchive.net.
+twitter.com.
+usb.relaxunix.net.
+69.204.152.201.in-addr.arpa.
+fbcdn-sphotos-a.akamaihd.net.
+ildesign.ru.
+profile.ak.fbcdn.net.
+www.beyzacases.com.
+tein.net.
+www.igorbass.com.
+www.escape.ws.
+199.64.139.189.in-addr.arpa.
+privetsochi.ru.
+188.104.248.189.in-addr.arpa.
+c144101.memecenter.com.
+a.root-servers.net.
+wdw2.wdpromedia.com.
+static.ak.fbcdn.net.
+242.146.52.187.in-addr.arpa.
+blvgroup.ru.
+osuno.no-ip.biz.
+29.203.238.190.in-addr.arpa.
+www.all4myspace.de.
+www.premiumhdv.com.
+hmag.disqus.com.
+entretenimiento.wikia.com.
+www.laobesidad.net.
+www.cesarcancino.com.
+photos-g.ak.fbcdn.net.
+money.cnn.com.
+www.facebook.com.
+your.net.com.
+_080_52_9.
+www.motors.ebay.com.
+18.225.12.212.in-addr.arpa.
+l.addthiscdn.com.
+www.about-recipes.com.
+js.parabebes.com.
+11.105.168.189.in-addr.arpa.
+www.funnythingsmykidsaid.com.
+clockwatchers.net.
+156.150.33.189.in-addr.arpa.
+static.ak.fbcdn.net.
+www.marcandangel.com.
+ares.dl.playstation.net.
+www.politraductor.com.
+191.68.237.188.in-addr.arpa.
+174.45.174.190.in-addr.arpa.
+www.star-advertising.com.
+profile.ak.fbcdn.net.
+maxrealty.co.jp.s9a1.psmtp.com.
+suivi.evenko.ca.
+www.youtube.com.
+banks2banks.ru.
+i4.ytimg.com.
+cdn2.image.tube8.phncdn.com.
+photos-a.ak.fbcdn.net.
+a6.sphotos.ak.fbcdn.net.
+ddn:ak6vw.d84n0a5m.
+164.131.138.187.in-addr.arpa.
+29.media.tumblr.com.
+www.youtube.com.
+storage.conduit.com.
+111.176.153.95.in-addr.arpa.
+gratisxjuegos.com.
+s-static.ak.fbcdn.net.
+pennwoods.net.
+a1351.v.phobos.apple.com.
+196.137.175.208.in-addr.arpa.
+www.grupo-sm.com.
+download315.avast.com.
+6.35.104.186.in-addr.arpa.
+133.71.160.190.in-addr.arpa.
+tr.adinterax.com.
+d7.zedo.com.
+apps.facebook.com.
+eurostroygroup.ru.
+a10.t26.net.
+www.google-analytics.com.
+9.a.4.d.7.2.6.8.9.b.9.0.1.9.c.1.6.7.e.9.7.3.1.4.0.0.0.0.1.0.0.2.ip6.arpa.
+media.etoro.com.
+a.root-servers.net.
+146.127.142.189.in-addr.arpa.
+b4.
+mail.dbamlg.com.
+ec2.images-amazon.com.
+s7.addthis.com.
+dejardefumar2.blogspot.com.
+107.26.157.157.in-addr.arpa.
+www.24log.es.
+66.71.167.24.in-addr.arpa.
+ahfc.state.ak.us.
+upload.wikimedia.org.
+camcom.net.
+175.193.174.190.in-addr.arpa.
+chromeunderground.blogspot.com.
+help.weheartit.com.
+compilr.com.
+www.premiosarpa.com.
+www.amazon.co.uk.
+www.pixsblog.com.
+131.140.37.190.in-addr.arpa.
+sakura-no-tamashii.deviantart.com.
+optimized-by.rubiconproject.com.
+www.pritzkermilitarylibrary.org.
+crl.globalsign.net.
+mail.levelsaudio.com.
+hdjlaw.com.
+doba.si.
+nanyang.com.
+pole59.ru.
+ms0.dfi.com.tw.
+a3.sphotos.ak.fbcdn.net.
+au.download.windowsupdate.com.
+www.megauploadbay.com.
+3.10.56.186.in-addr.arpa.
+www.bestonlinerpggames.com.
+www.google.com.
+fibrespa.ru.
+www.pwpthemes.com.
+api.twitter.com.
+www.facebook.com.
+a8.sphotos.ak.fbcdn.net.
+csi.gstatic.com.
+twitter.com.
+www.msn.com.
+www.supertop100.com.
+www.housingaforest.com.
+www.facebook.com.
+222.210.78.190.in-addr.arpa.
+hotmail.com.
+198.138.166.109.in-addr.arpa.
+view.atdmt.com.
+mx.youtube.com.
+dr._dns-sd._udp.home.
+platform.ak.fbcdn.net.
+ciclusgroup.net.
+www.facebook.com.
+2.hsup.poczta.onet.pl.
+a6.sphotos.ak.fbcdn.net.
+prod2.rest-notify.msg.yahoo.com.
+stats.adengage.com.
+a.root-servers.net.
+www.colorsound.com.
+mail.gilfusa.com.
+cadsa.com.
+atmserver1.alibaba.com.
+klit.startnow.com.
+zarina.ru.
+centrointegramurcia.blogspot.com.
+assassin.nexon.com.au.
+kabelspeed.at.
+atphagraphics.com.
+a5.sphotos.ak.fbcdn.net.
+s0.2mdn.net.
+83.209.192.187.in-addr.arpa.
+view.atdmt.com.
+shatim-trade.ru.
+73.134.213.201.in-addr.arpa.
+www.theyellowcommunity.com.
+dsl-384-gw.architectsde.com.
+online.no.
+twitter.com.
+groups.live.com.
+www.google.com.
+www.hoteldeca.com.
+google.com.
+www.myybiz.net.
+no.wikipedia.org.
+www.imanhearts.com.
+www.facebook.com.
+groups.google.com.mx.
+a7.sphotos.ak.fbcdn.net.
+pixel.facebook.com.
+chermet-s.ru.
+www.njstar.com.
+mail.ashnet.it.
+a968yfanx.12pc.
+145.74.125.200.in-addr.arpa.
+a.root-servers.net.
+3.127.36.186.in-addr.arpa.
+136.224.145.201.in-addr.arpa.
+a2.sphotos.ak.fbcdn.net.
+external.ak.fbcdn.net.
+developers.facebook.com.
+dbcmail02.ca.debeersgroup.com.
+i3.ytimg.com.
+www.samsung.com.
+googleads.g.doubleclick.net.
+static.ads.crakmedia.com.
+static.hi5.com.
+ads.dotomi.com.
+a288.phobos.apple.com.
+aol.com.
+badoo.com.
+photos-b.ak.fbcdn.net.
+ad.xtendmedia.com.
+site.delain.nl.
+www.wweshop.com.
+nass-sa.net.
+studentlink.net.
+msa.biglobe.ne.jp.
+_sipinternal._tcp.quintiles.com.quintiles.net.
+db.local.clamav.net.
+217.188.57.186.in-addr.arpa.
+partyrockpeople.com.
+thebas.homelinux.com.
+248.176.100.122.in-addr.arpa.
+22.4.171.201.in-addr.arpa.
+i1.ytimg.com.
+profile.ak.fbcdn.net.
+fb-0.hidden.zynga.com.
+ar-ar.facebook.com.
+smtp.unhsinc.com.
+a1005.w42.akamai.net.
+154.240.111.216.in-addr.arpa.
+chdarchitects.com.inbound25.mxlogic.net.
+81.213.249.70.in-addr.arpa.
+226.198.137.190.in-addr.arpa.
+a8.sphotos.ak.fbcdn.net.
+www.womensoccer.com.au.
+174.175.152.189.in-addr.arpa.
+whos.amung.us.
+globalmortgagecc.com.
+www.mediawiki.org.
+www.playwaitressgames.com.
+playerusersvc.play.it.
+www.ubilapaz.edu.bo.
+86.180.70.71.in-addr.arpa.
+photos-d.ak.fbcdn.net.
+www.lux.org.uk.
+steelmart.com.
+www.groundcontrol.com.
+api.twitter.com.
+i1.ytimg.com.
+132.19.147.187.in-addr.arpa.
+52.186.176.189.in-addr.arpa.
+cmedia-business.ru.
+matthewcoxantiques.com.
+mx-24-75-128-158.rivonline.net.
+abeoidii4.38hn.
+www.links-web.net.
+97.240.110.201.in-addr.arpa.
+photos-c.ak.fbcdn.net.
+diseasesconditions-articledirectoryon.blogspot.com.
+kemana.com.
+poll.hotlayouts2u.com.
+6wveoklwe.g27z5d6j.
+www.facebook.com.
+www.facebook.com.
+194.1.131.187.in-addr.arpa.
+a.root-servers.net.
+www.ninoycancer.cl.
+www.academie-francaise.fr.
+69.187.213.91.in-addr.arpa.
+a4.sphotos.ak.fbcdn.net.
+appworld.blackberry.com.
+secure.wlxrs.com.
+akhal-teke.ru.
+a.root-servers.net.
+www.desertspeak.com.
+sup.live.com.
+a.root-servers.net.
+www.mgar.net.
+images.99bb.com.
+57.117.42.201.in-addr.arpa.
+a0.twimg.com.
+www.ellabellaphotos.com.
+fbcdn-profile-a.akamaihd.net.
+www.campvslab.cl.
+a.root-servers.net.
+cdn.cartown.com.
+teredo.ipv6.microsoft.com.
+dnqkzyzxnstsvu.biz.
+elkom.ru.
+profile.ak.fbcdn.net.
+ocsp.usertrust.com.
+www.rasta-man.co.uk.
+ptrv.ru.
+arsenalmusic.ru.
+ochnews.com.
+login.yahoo.com.
+juju.lt.
+0-161.channel.facebook.com.
+a.root-servers.net.
+a.root-servers.net.
+41.179.242.201.in-addr.arpa.
+lazonadelosgraffitis.foroactivo.com.
+a2.sphotos.ak.fbcdn.net.
+gg.google.com.
+crashboombangmusic.com.
+static.ak.facebook.com.
+www.sexreaction.com.
+wpad.
+www.abstractlogix.com.
+storage.conduit.com.
+api.mapabc.com.
+geeksquads.goes2u.com.
+photos-b.ak.fbcdn.net.
+pernodricard-uk.com.s200b2.psmtp.com.
+movies.gigantits.com.
+.
+169.101.89.186.in-addr.arpa.
+ad-g.doubleclick.net.
+www.netretina.com.
+a7.sphotos.ak.fbcdn.net.
+40.133.252.190.in-addr.arpa.
+mail1.nadams.k12.in.us.
+www.pmis.co.uk.
+.
+dpdartnbo.72ke.
+255.197.231.69.in-addr.arpa.
+librecinefilo.com.
+c.msn.com.
+t0.gstatic.com.
+alexa.cn.
+0-if-w.channel.facebook.com.
+exp02.eset.com.
+gfx4.hotmail.com.
+www.abnertrujillo.com.
+a1.twimg.com.
+nextwave.universia.net.
+134.199.40.65.in-addr.arpa.
+stone-systems.com.
+228.23.207.186.in-addr.arpa.
+secure.military.com.
+h.live.com.
+www.stumbleupon.com.
+gcwaeiddepudijfokaanpqja.mu.
+photos-b.ak.fbcdn.net.
+nbd.com.
+46.106.18.190.in-addr.arpa.
+images.google.com.
+photos-h.ak.fbcdn.net.
+photos-d.ak.fbcdn.net.
+accountservices.msn.com.
+tconl.com.
+34.141.181.190.in-addr.arpa.
+ad.xtendmedia.com.
+accor-mail.com.rbl2.mcafee.com.
+img.rincondelvago.com.
+a.root-servers.net.
+d2060586.instant.xoom.it.
+ad.yieldmanager.com.
+csi.gstatic.com.
+a.root-servers.net.
+www.apartamentos-medellin.com.
+canariolandia.mforos.com.
+networkroadrunner.disqus.com.
+dns2.dcsi.de.
+tacata.com.
+www.youtube.com.
+9.32.209.201.in-addr.arpa.
+www.google-analytics.com.
+www.facebook.com.
+gavan-invest.ru.
+99.29.207.190.in-addr.arpa.
+smtp.zoomtown.com.
+www.jamienelson.com.
+media.scholarshippoints.com.
+profile.ak.fbcdn.net.
+veneziaassociates.com.
+www.google.com.
+71.105.65.71.in-addr.arpa.
+cbk1.google.com.
+www.facebook.com.
+pubads.g.doubleclick.net.
+instagr.am.
+cloud-search-msgplus.linkury.com.
+www.woodturningonline.com.
+38.181.235.189.in-addr.arpa.
+google.com.
+plug-in.com.br.
+mail1.in2focus.com.
+csdnimg.cn.
+i.ytimg.com.
+s-static.ak.facebook.com.
+cti.gr.
+24.151.244.189.in-addr.arpa.
+client.akamai.com.
+78.35.213.201.in-addr.arpa.
+audience.netavenir.com.
+a.root-servers.net.
+photos-b.ak.fbcdn.net.
+4nodbmbq1kg3jfkhn7m4ua4bn329jbnf-a-sites-opensocial.googleusercontent.com.
+bebebaratisimo.com.
+50.56.124.69.in-addr.arpa.
+mail.ttknet.ru.
+236.168.51.190.in-addr.arpa.
+moberg.com.
+a1725.l.akamai.net.
+b._dns-sd._udp.0.129.37.10.in-addr.arpa.
+ehovpfsnszg.net.company.com.
+162.2.72.189.in-addr.arpa.
+a.root-servers.net.
+hb.whatsapp.net.
+login.live.com.
+www.comunidadpymes.com.
+blog.bibliothek.kit.edu.
+22.247.137.190.in-addr.arpa.
+a5.sphotos.ak.fbcdn.net.
+221.132.118.217.in-addr.arpa.
+vvebcams.spb.ru.
+deti.bazar.sk.
+ksn1-11-part2.kaspersky-labs.com.
+m.yahoo.co.jp.
+123.16.0.10.in-addr.arpa.
+mail2.fire.org.nz.
+www.hotsassy.net.
+137.73.82.200.in-addr.arpa.
+sites.google.com.
+echo.edge.messenger.live.com.
+10.96.250.190.in-addr.arpa.
+a1506.phobos.apple.com.
+www.mbc.net.
+apps.facebook.com.
+165.33.186.201.in-addr.arpa.
+imagenesangeles.com.
+comunidad.semana.com.
+www.informatique.com.mx.
+chanokaqh.deviantart.com.
+www.dejatuempleo.com.
+mback.csgny.com.
+21.122.136.175.in-addr.arpa.
+18.73.51.24.in-addr.arpa.
+mailbox.pircher.at.
+www.rae.com.
+38.147.220.66.in-addr.arpa.
+a.root-servers.net.
+netdark.files.wordpress.com.
+coxhanson.ca.
+249.79.112.190.in-addr.arpa.
+www.facebook.com.
+holmesproducts.com.
+br.weather.com.
+photos-g.ak.fbcdn.net.
+client-software.real.com.
+168.110.114.200.in-addr.arpa.
+www.9gag.com.
+safebrowsing-cache.google.com.
+140.184.139.187.in-addr.arpa.
+a-0.19-2209d081.c040082.1518.19d4.3ea1.410.0.uprtfjst5crek8qge2qz1693sb.avqs.mcafee.com.
+www.belkin.com.
+translate.google.com.mx.
+www.domainit.com.
+191.36.31.82.in-addr.arpa.
+81.194.78.201.in-addr.arpa.
+developers.facebook.com.
+a.root-servers.net.
+sc21.rules.mailshell.net.
+148.157.201.190.in-addr.arpa.
+:smz1pynj.a72l9r3t.
+www.fashiontoast.com.
+a4.mzstatic.com.
+static.ak.fbcdn.net.
+ad.xtendmedia.com.
+www.pharmacyathand.co.uk.
+a.root-servers.net.
+stereoplus.com.
+developers.facebook.com.
+1.0.0.127.dnsbugtest.1.0.0.127.in-addr.arpa.
+inbound.advantech-inc.com.netsolmail.net.
+hi-in.facebook.com.
+searchvip1.sli-systems.net.
+aol.com.
+mundomoto.bligoo.com.
+italiano.softmyhard.com.
+s2.youtube.com.
+video-g19.proxad.net.
+22.43.111.174.in-addr.arpa.
+fxfeeds.mozilla.com.
+8cbnuqbnb.39sk.
+chromejs.s3.amazonaws.com.
+87.73.134.187.in-addr.arpa.
+www.0.com.
+blufiles.storage.msn.com.
+126.166.91.91.in-addr.arpa.
+localhost.
+n003-000-000-000.static.ge.com.
+a6.sphotos.ak.fbcdn.net.
+a.root-servers.net.
+clients2.google.com.
+www.youtube.com.
+developers.facebook.com.
+telinvest.com.
+i4.ytimg.com.
+salemchamber.org.
+defis.kis.ru.
+images.barchart.com.
+news.google.com.mx.
+graph.facebook.com.
+pagead2.googlesyndication.com.
+www.sorbita.com.
+sr.jailbreak-me.info.
+quality-tour.com.
+a5.sphotos.ak.fbcdn.net.
+www.20minutos.es.
+cdn1.static.tube8.phncdn.com.
+www.jongales.com.
+pagead2.googlesyndication.com.
+search.jp.wsj.com.
+steel.nsk.su.
+clients2.google.com.
+703.coll.ning.com.
+_808_68_5.
+www.cybermonday2011.com.
+www.filemakertrial.com.
+58.26.133.187.in-addr.arpa.
+www.stc.com.sa.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+37.128.16.190.in-addr.arpa.
+a5.sphotos.ak.fbcdn.net.
+150.137.98.76.in-addr.arpa.
+www.youtube.com.
+mail.homelocatorsrealty.com.
+ad-g.doubleclick.net.
+www.newz-premium.com.
+mkz33xw:y.57ua.
+www.peliculasfox.com.
+googleads.g.doubleclick.net.
+135.15.255.201.in-addr.arpa.
+a.root-servers.net.
+plantx.com.
+www.twink-guys.com.
+162.158.115.189.in-addr.arpa.
+now.org.
+heidegger.x-y.net.
+google.com.
+62.34.178.190.in-addr.arpa.
+vdovichenko.ru.
+time.chttl.com.tw.
+playball.eluniversal.com.
+yahoo.ytsa.net.
+streamlfree.live-onweb.com.
+photos-e.ak.fbcdn.net.
+237.62.17.177.in-addr.arpa.
+tracker.thepiratebay.org.
+www.findyourfamilytree.com.
+nortonsecurity.blinkweb.com.
+dns.msftncsi.com.
+teredo.ipv6.microsoft.com.
+voydat.com.
+156.112.28.83.in-addr.arpa.
+56.15.182.189.in-addr.arpa.
+espndeportes-assets.espn.go.com.
+_784_41_7.
+m.addthisedge.com.
+mckechnie.com.
+a.root-servers.net.
+www.esedark.com.
+tsm01.eset.com.
+js.chatsend.com.
+livingliberally.org.
+gigantioempresarios.blogspot.com.
+32.155.119.222.in-addr.arpa.
+time-nw.nist.gov.
+resolver3.ipsw.ctmail.com.
+223.94.158.201.in-addr.arpa.
+www.nvgopcaucus.com.
+photos-e.ak.fbcdn.net.
+no.wikipedia.org.
+mx01.puc.rediris.es.
+187.85.32.177.in-addr.arpa.
+photos-c.ak.fbcdn.net.
+www.bromleybike.co.uk.
+eurostar.voyages-sncf.com.
+laposte.net.
+_696_32_1.
+hrndva-smtpin02.mail.rr.com.
+cmmeiers.com.
+www.videojuegos.com.
+authenticpress.com.
+www.update.microsoft.com.
+62.158.220.66.in-addr.arpa.
+192.172.152.187.in-addr.arpa.
+css.wlxrs.com.
+www.ipsca.com.
+a.root-servers.net.
+alerts.conduit-services.com.
+adoftheyear.com.
+www.videox2424.com.
+remaxcolonial.com.
+directimports.co.uk.
+vid2c.disqus.com.
+www.adobe.com.
+5.175.77.219.in-addr.arpa.
+tin.hongkong1.com.
+a3.sphotos.ak.fbcdn.net.
+static.ak.facebook.com.
+228.143.71.77.in-addr.arpa.
+apps.facebook.com.
+lermanlaw.com.s8b1.psmtp.com.
+194.32.82.190.in-addr.arpa.
+jjjkc5h9v.07tp.
+devices.live.com.
+apps.facebook.com.
+www.buenosairesdelivery.com.
+253.239.186.93.in-addr.arpa.
+gayshow.blogsome.com.
+securemail.novartis.net.
+yahoo.com.
+rad.msn.com.
+d1j68ux4ukg4g1.cloudfront.net.
+ftp.porcupine.org.
+img.feb-search.com.
+rct395f5z.z62y4p9w.
+profile.ak.fbcdn.net.
+yourmayflower.com.
+www.musica-online.org.
+external.ak.fbcdn.net.
+69.52.55.190.in-addr.arpa.
+a7.sphotos.ak.fbcdn.net.
+whinuxkern.executablychewi.fm.
+destylesenaiguilles.wordpress.com.
+fairfaxis.com.
+fxfeeds.mozilla.com.
+www.facebook.com.
+104.6.73.219.in-addr.arpa.
+oss-survey.securestudies.com.
+169.94.6.189.in-addr.arpa.
+au.download.windowsupdate.com.
+www.google.com.mx.
+www.youtube-nocookie.com.
+a.root-servers.net.
+a2.sphotos.ak.fbcdn.net.
+23.35.52.186.in-addr.arpa.
+www.paratucuidado.com.ar.
+apps.facebook.com.
+a.root-servers.net.
+safebrowsing-cache.google.com.
+apis.google.com.
+2oqe9qij7.56iy.
+content.yieldmanager.edgesuite.net.
+facemoods.com.
+_585_54_6.
+a.root-servers.net.
+www.google-analytics.com.
+231.92.80.190.in-addr.arpa.
+1st-premier.com.s7a2.psmtp.com.
+211.32.234.189.in-addr.arpa.
+gujeha7d3.31el.
+www.google.com.
+a9xozbfz1.47mw.
+home.costhelper.com.
+qcode.us.
+zopugiwepehowyj.info.
+www.ceddet.org.
+jestro.com.
+www.eurocommuseum.com.
+fbcdn-photos-a.akamaihd.net.
+32.courier-push-apple.com.akadns.net.
+laprincesacaprichosa.blogspot.com.
+164.173.125.190.in-addr.arpa.
+evintl-ocsp.verisign.com.
+www.gladiatus.lv.
+a.root-servers.net.
+b.scorecardresearch.com.
+b._dns-sd._udp.lan.
+cmgtcontent.ahold.com.kpnis.nl.
+www.teamovercome.net.
+static.ak.fbcdn.net.
+api.conduit.com.
+24.media.tumblr.com.
+fbcdn-profile-a.akamaihd.net.
+www.facebook.com.
+www.clocklink.com.
+naacy.org.
+d2111274.xoom.it.
+www.lmolnar.com.
+www.zynga.com.
+todoaudio.cl.
+a7.sphotos.ak.fbcdn.net.
+lus.net.
+hipstamaticapp.com.
+a8.sphotos.ak.fbcdn.net.
+isatap.belkin.
+time.chttl.com.tw.
+clock.fmt.he.net.
+mail.bwrogers.com.
+ksn2-12.kaspersky-labs.com.
+photos-d.ak.fbcdn.net.
+66.36.45.189.in-addr.arpa.
+www.gruposyv.com.
+mx1.martinlitho.com.
+www.risorsegeek.net.
+mail1.ingles-markets.com.
+13.166.110.76.in-addr.arpa.
+82.145.105.186.in-addr.arpa.
+www.piadasnet.com.
+www.royalsuitesturquesaresort.com.
+sites.google.com.
+mail.streamline-ops.com.
+a.root-servers.net.
+a5.sphotos.ak.fbcdn.net.
+d2055107.instant.xoom.it.
+90.154.88.186.in-addr.arpa.
+www.rotaterra.com.
+0612com3s2a.freehostia.com.
+216.128.112.128.in-addr.arpa.
+cositphotography.com.
+.
+www.linkleak.org.
+www.otherthings.com.
+rad.msn.com.
+addons.mozilla.org.
+a.root-servers.net.
+pubads.g.doubleclick.net.
+centerpointvp.com.
+m.detik.com.
+adult-img02.olx.com.mx.
+www.seasite.niu.edu.
+s-static.ak.facebook.com.
+simon1.me.uk.
+platform.linkedin.com.
+www.foofighters.fm.
+oxgw7mx54.58an.
+a5.sphotos.ak.fbcdn.net.
+www.ggi.com.mx.
+textad.xxxmatch.com.
+streaming.mediamatters.org.
+143.53.154.186.in-addr.arpa.
+68.148.49.49.in-addr.arpa.
+mx.youtube.com.
+creative.ak.fbcdn.net.
+tag.admeld.com.
+123.4.10.85.in-addr.arpa.
+www.hamptons.com.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+www.thinkteens.com.
+163.127.6.189.in-addr.arpa.
+mountainkeeper.org.
+www.bloghissimo.com.
+dist.divx.com.
+www.piercingbible.com.
+76.31.9.76.in-addr.arpa.
+image2.cecash.com.
+i1.ytimg.com.
+155.170.88.200.in-addr.arpa.
+www.info.lncc.br.
+skins.gmodules.com.
+nyc2k155.ameca.panorg.com.
+lvrewelju.u52m3o9v.
+mob.adwhirl.com.
+t3.baidu.com.
+ocsp.godaddy.com.
+www.plena507.org.
+zh-cn.facebook.com.
+www.adxpansion.com.
+coldngrey.blogspot.com.
+qfj:95oem.r43l1a5h.
+tetc1.ceryxefw.com.
+112.126.106.189.in-addr.arpa.
+53.153.206.200.in-addr.arpa.
+platform.ak.fbcdn.net.
+masabadell.wordpress.com.
+mail.live.com.
+i2.ytimg.com.
+init.ess.apple.com.
+evintl-ocsp.verisign.com.
+i2.ytimg.com.
+dc263.4shared.com.
+sandesh.ganeshaspeaks.com.
+profile.ak.fbcdn.net.
+a.root-servers.net.
+3.gvt0.com.
+joinexpedia.com.
+translate.googleapis.com.
+stenske.kiev.ua.
+um12.eset.com.
+84.47.43.186.in-addr.arpa.
+105.238.1.118.in-addr.arpa.
+s.ytimg.com.
+www.mochiads.com.
+68.242.100.190.in-addr.arpa.
+modnoe-mecto.ru.
+130.154.128.190.in-addr.arpa.
+mail.arzamarket.ru.
+developer.ean.com.
+www.shueisha.co.jp.
+212.116.59.82.in-addr.arpa.
+ns1.apk.net.
+fbcdn-photos-a.akamaihd.net.
+clients2.google.com.
+musicandmore.bligoo.com.mx.
+mail.capebouvard.com.
+safebrowsing-cache.google.com.
+csi.gstatic.com.
+uspeh24.ru.
+store.apolisglobal.com.
+download326.avast.com.
+a7.sphotos.ak.fbcdn.net.
+9.47.21.201.in-addr.arpa.
+beckersasc.com.
+246.202.209.201.in-addr.arpa.
+www.balashov.san.ru.
+joplinfamilyy.org.
+danielpowter.ru.
+ad.doubleclick.net.
+pixel.facebook.com.
+www.stumbleupon.com.
+241.61.154.187.in-addr.arpa.
+www.tolaymat.com.
+www.woodcrafter.com.
+netvigator.com.
+mail.google.com.
+www.bulgaria-travel-guide.com.
+gally.hellfiresex.com.
+itaka-fan.los-foros.com.
+lh3.googleusercontent.com.
+www.facebook.com.
+www.dotster.com.
+171.19.251.190.in-addr.arpa.
+a.root-servers.net.
+www.absolutemadonna.com.
+d1af033869koo7.cloudfront.net.
+google.com.
+mx.youtube.com.
+www.facebook.com.
+titanium30-en.url.trendmicro.com.
+www.vidaabundante.com.mx.
+a6.sphotos.ak.fbcdn.net.
+www.hiyoko-g.com.
+6.226.10.186.in-addr.arpa.
+modder.net.
+a34.g.akamai.net.
+.
+a.root-servers.net.
+img03.taobaocdn.com.
+lb._dns-sd._udp.lan.
+www.fc.com.
+ctzujo.com.
+www.sohuads.com.
+brisajuvenil.blogspot.com.
+ar.thefreedictionary.com.
+a1.sphotos.ak.fbcdn.net.
+a.root-servers.net.
+ocsp.verisign.com.
+59.218.95.201.in-addr.arpa.
+9-courier.push.apple.com.
+202.144.131.63.in-addr.arpa.
+149.115.69.190.in-addr.arpa.
+developers.facebook.com.
+a2.twimg.com.
+177.231.34.186.in-addr.arpa.
+cmxr.com.s7b1.psmtp.com.
+msvqdoq19.83ti.
+secure.globalsign.net.
+f.facemoods.com.
+ad.doubleclick.net.
+photos-f.ak.fbcdn.net.
+youtu.be.
+202.250.34.2.in-addr.arpa.
+_054_09_1.
+profile.ak.fbcdn.net.
+shuttleworth-uk.co.uk.inbound10.mxlogic.net.
+www.make-fabulous-cakes.com.
+kanrou.net.
+shelf-life.ew.com.
+www.mundoanuncio.com.sv.
+photos-f.ak.fbcdn.net.
+hypesrus.com.
+www.facebook.com.
+daemon-tools.softonic.com.
+bestbetting.sesmazing.com.
+mystartantiphishing.com.
+photos-g.ak.fbcdn.net.
+63.124.226.190.in-addr.arpa.
+www.be2.co.uk.
+_381_41_3.
+amsdocs.com.
+twitter.com.
+4.map.pop6.com.
+gpc.ru.
+mail.tellus.nl.
+222.162.229.88.in-addr.arpa.
+www-proxy.ericsson.se.
+maxneutra.com.
+liveupdate.symantecliveupdate.com.
+www.groupon.com.ar.
+6.190.172.201.in-addr.arpa.
+spam2.e-land.gov.tw.
+aidps.atdmt.com.
+forum.aheadworks.com.
+hotforex.com.hypestat.com.
+carestream.ru.
+www.facebook.com.
+231.37.56.186.in-addr.arpa.
+gye.hoy.net.
+vip.mlstatic.com.
+113.246.213.201.in-addr.arpa.
+tools.google.com.
+addons.mozilla.org.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+www.gogotorrent.com.
+candocareer.com.
+img844.imageshack.us.
+tempomusic.com.
+apis.google.com.
+20.225.132.190.in-addr.arpa.
+www.dorma-interior.com.
+141.190.43.190.in-addr.arpa.
+100.247.253.189.in-addr.arpa.
+22.61.74.190.in-addr.arpa.
+mail02.bg-group.com.
+www.pimientaycanela.com.
+zh-cn.facebook.com.
+ns.magnetism.ru.
+qpsisbest.com.m2.mx-route.com.
+a1402.w40.akamai.net.
+stacksvinyl.com.
+photos-h.ak.fbcdn.net.
+15.167.50.201.in-addr.arpa.
+www.google-analytics.com.
+wstat.wibiya.com.
+js2.wlxrs.com.
+store.dll-files.com.
+www.facebook.com.
+a.root-servers.net.
+www.informationhospitaliere.com.
+a.root-servers.net.
+forelskelse.com.
+static.ak.fbcdn.net.
+clients4.google.com.
+241.188.249.188.in-addr.arpa.
+nobreastsnorequests.tumblr.com.
+a.root-servers.net.
+babcom4.lnc.net.
+mccafferyinterests.com.s5a2.psmtp.com.
+176.cim.meebo.com.
+aquascene.com.au.
+picasaweb.google.com.
+graph.facebook.com.
+profile.ak.fbcdn.net.
+wpad.
+233.124.241.189.in-addr.arpa.
+www.zobo.ca.
+gmfcollect.com.
+www.google-analytics.com.
+www.audiencescience.com.
+a.root-servers.net.
+twitter.com.
+plusone.google.com.
+mail.cfmcgroup.com.
+_093_08_2.
+hammond.org.
+www.jvcpro.eu.
+220.149.224.190.in-addr.arpa.
+82.44.168.192.in-addr.arpa.
+photos.americanlemans.com.
+192.209.3.190.in-addr.arpa.
+131.94.79.201.in-addr.arpa.
+google.ail.com.
+174.177.204.190.in-addr.arpa.
+csi.gstatic.com.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+weather.bigspeedpro.com.
+rerih.ru.
+ssl.gstatic.com.
+user.home.
+thelongboardblog.com.
+aspenbuilders.co.uk.
+five.tefgame.com.
+m.youtube.com.
+www.wdc.com.
+api.twitter.com.
+italiacampersud.it.
+214.51.229.189.in-addr.arpa.
+219.101.194.186.in-addr.arpa.
+189.111.22.71.in-addr.arpa.
+lh4.googleusercontent.com.
+ssl.gstatic.com.
+i3.msdn.microsoft.com.
+65.203.205.218.in-addr.arpa.
+v17.lscache7.c.bigcache.googleapis.com.
+new-rap.ru.
+173.245.53.200.in-addr.arpa.
+twitter.com.
+sa-live.com.
+www.shy22.com.
+pagead2.googlesyndication.com.
+profile.ak.fbcdn.net.
+smtp1.ppcc.edu.
+_784_28_0.
+av1.tnz.myschools.net.
+js2.wlxrs.com.
+217.35.168.192.in-addr.arpa.
+ussd.ru.
+2f6508c4.allanalpass.com.
+up.uchc.edu.
+creative.ak.fbcdn.net.
+hash.orbitdownloader.com.
+ksn2-12.kaspersky-labs.com.
+coachhousecraftingonabudget.blogspot.com.
+economictimes.feedsportal.com.
+t1.gstatic.com.
+a2.sphotos.ak.fbcdn.net.
+laprendizdechef.blogspot.com.
+api202e.thefilter.com.
+www.holidaycityflash.com.
+252.26.0.181.in-addr.arpa.
+image.web.cyberimg.com.
+mta2.am0.yahoodns.net.
+a4.sphotos.ak.fbcdn.net.
+_572_46_2.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+igor.facemoods.com.
+lioninthesunps.com.
+col.stb01.s-msn.com.
+www18.officedepot.com.
+mail.sakurabloom.com.
+d1j68ux4ukg4g1.cloudfront.net.
+paynoattention.kicks-ass.net.
+a4.sphotos.ak.fbcdn.net.
+apix.iminent.com.
+elsingular.com.
+mail2.interyuna.ru.
+yahoo.com.
+www.freelearn110.com.
+lc.mcafee.com.
+www.cerur.org.
+it-it.facebook.com.
+i.ytimg.com.
+a1.sphotos.ak.fbcdn.net.
+www.cfmaroc.com.
+210.238.143.187.in-addr.arpa.
+www.dick.com.
+dataage.blogspot.com.
+safebrowsing-cache.google.com.
+252.115.149.187.in-addr.arpa.
+www.turquoise-voyages.fr.
+www.mochiads.com.
+121.78.126.71.in-addr.arpa.
+v.gatcdn.com.
+a.root-servers.net.
+a.root-servers.net.
+fisifvg.org.
+dns.msftncsi.com.
+tech.teachmyass.com.
+site.beltoutlet.com.
+rob2tall1.newsvine.com.
+profile.ak.fbcdn.net.
+orcart.facebook.com.
+crittercorral.com.
+blogantiheroes.files.wordpress.com.
+www.demotores.es.
+www.google-analytics.com.
+api.facebook.com.
+wukesha.k12.wi.us.
+clients4.google.com.
+a.root-servers.net.
+71.90.216.150.in-addr.arpa.
+mx.electricentertainment.com.
+lacasaeuropa.blogspot.com.
+quicktime.uptodown.com.
+0-if-w.channel.facebook.com.
+google.com.
+sup.live.com.
+at.7digital.com.
+torresvedras.olx.pt.
+42.33.145.189.in-addr.arpa.
+pixel.quantserve.com.
+static2.avast.com.
+www.koolkiz.com.
+www.dumcoach.com.
+47.43.117.74.in-addr.arpa.
+dx3723.tinyurl.com.
+inferno.demonoid.me.
+251.1.238.190.in-addr.arpa.
+www.blowjobpimps.com.
+admiralplc.com.
+teredo.ipv6.microsoft.com.
+ad.eqsv.jp.
+www.strictlyreptiles.com.
+wrapcritic.com.
+sbnbox.com.
+www.youtube.com.
+pueblo-insurance.com.
+quazy4quakers.com.
+232.128.210.201.in-addr.arpa.
+www.miniclip.com.
+a.root-servers.net.
+167.26.236.77.in-addr.arpa.
+secure.shared.live.com.
+gdata.youtube.com.
+www.nlm.nih.gov.
+a.root-servers.net.
+www.socialgrowthtechnologies.com.
+73.102.249.190.in-addr.arpa.
+58.125.40.190.in-addr.arpa.
+\(none\).
+mail1.colmanagement.com.
+mono.ximian.com.
+www.bywifi.com.
+evintl-ocsp.verisign.com.
+200.91.248.189.in-addr.arpa.
+hi-in.facebook.com.
+photos-f.ak.fbcdn.net.
+relay.voice.edge.messenger.live.com.
+www.cooldictionary.com.
+profile.ak.fbcdn.net.
+43.208.33.177.in-addr.arpa.
+www.dspdoctor.com.
+photos-b.ak.fbcdn.net.
+heavenlysweet.blogspot.com.
+hi-in.facebook.com.
+client29.dropbox.com.
+photos-e.ak.fbcdn.net.
+wzeu.ask.com.
+developers.facebook.com.
+www.print-gakufu.com.
+eimail.com.
+developers.facebook.com.
+www.asiaticos.org.
+twitter.com.
+festoolownersgroup.com.
+a.root-servers.net.
+watsonreltycorp.com.
+41.130.225.212.in-addr.arpa.
+mgurxvgtykkrpqg.net.
+billing.sharo4ka.ru.
+a.root-servers.net.
+imagine-graphics.net.
+_767_24_0.
+100.16.75.187.in-addr.arpa.
+www9.effectivemeasure.net.
+lb._dns-sd._udp.0.0.168.192.in-addr.arpa.
+25.97.48.190.in-addr.arpa.
+www.viptickets.com.
+emoticons.msn-beta.com.
+adscachable.nfl.mobitv.com.
+136.120.55.190.in-addr.arpa.
+fr.webrep.avast.com.
+19.201.168.192.in-addr.arpa.
+a.root-servers.net.
+external.ak.fbcdn.net.
+24.188.35.201.in-addr.arpa.
+mss.api.getjar.com.
+touch.facebook.com.
+partner.googleadservices.com.
+www.imanmaleki.com.
+ow2ryx7ij.58hy.
+developers.facebook.com.
+api.facebook.com.
+blackmarketbikes.com.
+dermadoctor.tt.omtrdc.net.
+db._dns-sd._udp.0.2.168.192.in-addr.arpa.
+mysecretceres.com.
+swcdn.apple.com.
+topcosales.com.
+cdn.api.twitter.com.
+d2095752.xoom.it.
+150.17.16.206.in-addr.arpa.
+www.wikimapia.org.
+22.164.179.190.in-addr.arpa.
+external.ak.fbcdn.net.
+static.ak.fbcdn.net.
+a.root-servers.net.
+a1.sphotos.ak.fbcdn.net.
+94.152.117.200.in-addr.arpa.
+safebrowsing-cache.google.com.
+feeds.bbci.co.uk.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+a2.twimg.com.
+zynga1-a.akamaihd.net.
+44.165.56.186.in-addr.arpa.
+img.dukascopy.com.
+tools.google.com.
+sealns5.nstld.net.
+220.224.45.190.in-addr.arpa.
+wisconsinbenefits.com.
+static.ak.fbcdn.net.
+www.google.com.mx.
+creative.ak.fbcdn.net.
+twitter.com.
+time.chttl.com.tw.
+www.kickload.com.
+opi.yahoo.com.
+dem0003.in.
+59.120.209.190.in-addr.arpa.
+fbcdn-profile-a.akamaihd.net.
+safebrowsing.clients.google.com.
+b.static.ak.fbcdn.net.
+fbcdn-photos-a.akamaihd.net.
+games.yahoo.com.
+a.root-servers.net.
+mail.creamyradio.com.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+www.badboyonline.com.
+av.ru.s200b1.psmtp.com.
+_ldap._tcp.
+stores.guitarcenter.com.
+lb.wordpress.com.
+www.718c.com.
+t1.gstatic.com.
+blog.penyubiru.com.
+revolucionindustrialrosana.blogspot.com.
+234.40.172.109.in-addr.arpa.
+www.carinos.com.
+prch.org.
+profile.ak.fbcdn.net.
+a1.da1.akamai.net.
+amer.rel.msn.com.
+www.arcat.com.
+creative.ak.fbcdn.net.
+cqwmw8qzr.v77g6s3s.
+31.63.229.78.in-addr.arpa.
+bin-short.whatsapp.net.
+youtube-5th.softonic.com.
+inbound.icdcoc.com.netsolmail.net.
+accesorioshp.com.
+www.absolutefigures.com.
+www.kalipedia.com.
+a2.sphotos.ak.fbcdn.net.
+m.facebook.com.
+i2.cdn.turner.com.
+apps.facebook.com.
+244.208.88.201.in-addr.arpa.
+feeds.bbci.co.uk.
+119.10.168.192.in-addr.arpa.
+51.16.235.99.in-addr.arpa.
+juanmanuel-vivenciasinteriores.blogspot.com.
+panelogic.com.
+108.206.243.41.in-addr.arpa.
+www.mrbigler.com.
+11.29.229.190.in-addr.arpa.
+search.imesh.com.
+www.bing.com.
+a.root-servers.net.
+79.216.231.212.in-addr.arpa.
+autos.divendo.mx.
+db._dns-sd._udp.0.129.37.10.in-addr.arpa.
+44993amailer.net.
+ssl.gstatic.com.
+i3.ytimg.com.
+au.answers.yahoo.com.
+s2.youtube.com.
+login.oscar.aol.com.
+stretchmarkinstitute.com.
+www.chinabusinessworld.com.
+kgtzu68yo.j56g6y2b.
+dc261.4shared.com.
+mx.oceanlakes.com.
+118.181.153.109.in-addr.arpa.
+platform.ak.fbcdn.net.
+www.theinnovationdiaries.com.
+11.231.195.190.in-addr.arpa.
+kzbwk7r7h.h45l9n0f.
+cdn.smosh.com.
+211.175.138.187.in-addr.arpa.
+4.25.168.192.in-addr.arpa.
+x.tagstat.com.
+i2.ytimg.com.
+rodajes.net.
+s1-word-view.vo.msecnd.net.
+191.208.36.190.in-addr.arpa.
+awck.com.
+13.124.236.98.in-addr.arpa.
+www.facebook.com.
+assets4.castle.zgncdn.com.
+ad.yieldmanager.com.
+76.190.248.213.in-addr.arpa.
+twitter.com.
+136.243.168.189.in-addr.arpa.
+a.root-servers.net.
+_481_28_2.
+www.congratulationstext.com.
+hxenmd382.88tt.
+ssl.gstatic.com.
+p18-buy.itunes.apple.com.
+journals.lww.com.
+inbound.phoenixgroup.org.netsolmail.net.
+_695_16_7.
+152.151.192.187.in-addr.arpa.
+154.230.132.190.in-addr.arpa.
+itech.fgcu.edu.
+tm.dp.yieldmanager.net.
+www.youtube.com.
+puertorico.koalatrends.com.
+www.google.com.
+www.google.com.
+vt2000.ru.
+hotmail.com.
+tc.v2.cache3.c.youtube.com.
+oaid.uab.es.
+ssl.gstatic.com.
+descargarpeliculasgratis.ziflo.net.
+cdn.api.twitter.com.
+static.ak.fbcdn.net.
+240.111.104.87.in-addr.arpa.
+s2.googleusercontent.com.
+a-tsb.ru.
+specialolympicswisconsin.org.
+sync.imob2.com.
+31.204.226.201.in-addr.arpa.
+ad.doubleclick.net.
+a5.sphotos.ak.fbcdn.net.
+platform.twitter.com.
+a.root-servers.net.
+19.134.60.213.in-addr.arpa.
+59.211.222.189.in-addr.arpa.
+forum.gamesports.net.
+www.embeddedpc.net.
+b.z.eset.rs.
+platform.twitter.com.
+www.models.or.kr.
+adaneslaberinto.espacioblog.com.
+api-read.facebook.com.
+u44b9qf:y.94wa.
+s.mobclix.com.
+blog.online-convert.com.
+a4.sphotos.ak.fbcdn.net.
+madcoyote.com.
+apis.google.com.
+a1.sphotos.ak.fbcdn.net.
+brand-yourself-blog.disqus.com.
+www.adobe.com.
+book-with-pictures.blogspot.com.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+apps.facebook.com.
+pnrws.skype.com.
+18.82.165.58.in-addr.arpa.
+vetlearn.com.s7b1.psmtp.com.
+about.tagged.com.
+153.144.167.190.in-addr.arpa.
+www.google.com.
+47.38.181.220.in-addr.arpa.
+in1.msg.vip.re2.yahoo.com.
+premieroutdoorproperties.com.
+ajax.googleapis.com.
+www.algzar99.com.
+8.36.75.190.in-addr.arpa.
+195.89.17.71.in-addr.arpa.
+41.23.19.186.in-addr.arpa.
+cc-codi.fr.
+www.borne.cc.
+dragonet.es.
+3.29.34.187.in-addr.arpa.
+a489.ac-images.myspacecdn.com.
+echo.edge.messenger.live.com.
+28.247.3.89.in-addr.arpa.
+s7.addthis.com.
+i4-img3.mangachapter.net.
+external.ak.fbcdn.net.
+erwbtkidthetcwerc.com.
+naval.mforos.com.
+images6.cuantocabron.com.
+download851.avast.com.
+hartmannhouse.ru.
+aka-cdn-ns.adtechus.com.
+www.techadmirer.com.
+www.tutorialsgarden.com.
+26.49.196.190.in-addr.arpa.
+static.pcomperf.com.
+233.34.158.187.in-addr.arpa.
+offers.veer.com.
+mail.niia.net.
+0.5475251.com.
+telezhka.com.ru.
+idpix.media6degrees.com.
+kvs.be.
+16.147.220.66.in-addr.arpa.
+loading6.widdit.com.
+_921_97_7.
+vopyzyk.com.
+74.234.47.189.in-addr.arpa.
+www.20minutos.es.
+mail.planning.gov.sa.
+apps.104.6rtl.com.
+plusone.google.com.
+mail.platbank.com.
+www.logitravel.com.br.
+photos-h.ak.fbcdn.net.
+bing.com.
+_219_24_2.
+a1505.l.akamai.net.
+clients1.google.com.mx.
+.
+www.gastroanthropology.com.
+www.google.com.
+mail.efdgroup.net.
+creative.ak.fbcdn.net.
+profile.ak.fbcdn.net.
+a.root-servers.net.
+ajax.googleapis.com.
+trans.in-freight.spb.ru.
+102.138.45.83.in-addr.arpa.
+nudt.edu.cn.
+6.25.68.189.in-addr.arpa.
+members.dyndns.org.
+ocsp.verisign.com.
+mgmt.beta.toolbar.msn.com.
+diosaladyruby.blogspot.com.
+exchange.thebeverageworks.com.
+a6.sphotos.ak.fbcdn.net.
+cuantocabron.com.
+teredo.ipv6.microsoft.com.
+87.35.31.190.in-addr.arpa.
+524r1tqe3.r96w0c5a.
+www.harrenmediatools.com.
+b.scorecardresearch.com.
+avante.net.mx.
+btq26vmu9.87yu.
+concienciacristiana.blogspot.com.
+nautilus.scene7.com.
+121.164.139.98.dnsbl.sorbs.net.
+75.23.0.192.in-addr.arpa.
+b.scorecardresearch.com.
+static.99widgets.com.
+secure.wlxrs.com.
+time.chttl.com.tw.
+mail.sinosure.com.cn.
+sannicolasdelosgarza.olx.com.mx.
+server4.web-stat.com.
+go.srvnow.com.
+197.242.185.201.in-addr.arpa.
+hootsuite.com.
+fbcdn-profile-a.akamaihd.net.
+elainemeinelsupkis.typepad.com.
+a.root-servers.net.
+a.root-servers.net.
+fieldforce.cz.
+market.android.com.
+www.facebook.com.
+www.experiencewa.com.
+safebrowsing-cache.google.com.
+60.194.87.115.in-addr.arpa.
+www.puppiesforsalecheap.net.
+bigeast.org.
+www2.scjn.gob.mx.
+_609_47_3.
+254.208.68.98.in-addr.arpa.
+mcgrigors.com.
+121.177.225.123.in-addr.arpa.
+0.11-a70ea079.2.1518.18a4.3ea1.210.0.2ft7kv1rbn483wbvsuclmwjhtb.avqs.mcafee.com.
+clients1.google.com.
+www.ncbi.nlm.nih.gov.
+euro.mediotiempo.com.
+google.com.
+a.root-servers.net.
+nfrr.ru.
+dns.msftncsi.com.
+exgf4bz4z.h73d0p2s.
+a1.sphotos.ak.fbcdn.net.
+developers.facebook.com.
+bit.ly.
+mafiascum.net.
+photos-c.ak.fbcdn.net.
+allprosupplements.com.
+starrtincup.com.
+iijmio-mail.jp.
+photos-b.ak.fbcdn.net.
+sn1msg1010620.gateway.messenger.live.com.
+a6.sphotos.ak.fbcdn.net.
+www.miga.org.
+zea.com.
+vodkaonly.com.
+fbcdn-profile-a.akamaihd.net.
+imkontext.at.
+172.55.221.216.in-addr.arpa.
+a3.sphotos.ak.fbcdn.net.
+books.google.com.mx.
+portalde.info.
+100.206.143.201.in-addr.arpa.
+db._dns-sd._udp.0.1.168.192.in-addr.arpa.
+ksn3-11.part1.kaspersky-labs.com.
+ubiqq.com.
+kmlafilm.com.
+boroughmarket.org.uk.
+google.com.
+sp.fieldhealth.com.
+img1.blogblog.com.
+healthywaterman.com.
+www.altromercato.it.
+www.google.com.mx.
+nicregi.hubpages.com.
+customwebdesigners.com.
+a.root-servers.net.
+photos-b.ak.fbcdn.net.
+geox.ru.
+snt0-omc3-s18.snt0.hotmail.com.
+48.1.65.50.in-addr.arpa.
+i4.ytimg.com.
+144.224.250.99.in-addr.arpa.
+wu-international.com.
+fbcdn-sphotos-a.akamaihd.net.
+88.gt2.vkadre.ru.
+del.icio.us.
+www.google.com.mx.
+images.speedbit.com.
+86.254.70.190.in-addr.arpa.
+84.73.57.62.in-addr.arpa.
+131.52.79.184.in-addr.arpa.
+1.bp.blogspot.com.
+video.xnxx.com.
+www.ant.com.
+2.55.89.120.in-addr.arpa.
+www.clickamateur.es.
+nightclassmembers.blogspot.com.
+www.afsvlaanderen.be.
+mobile.twitter.com.
+162.84.84.200.in-addr.arpa.
+129.212.11.201.in-addr.arpa.
+s-static.ak.fbcdn.net.
+85g4jaxbq.l92r1l1h.
+mail.brighterdaysent.com.
+162.55.66.212.in-addr.arpa.
+articleslot.info.
+124.50.248.201.in-addr.arpa.
+pod.xxxmatch.com.
+68.160.72.78.in-addr.arpa.
+api.facebook.com.
+www.goojue.com.
+theframeproblem.wordpress.com.
+teredo.ipv6.microsoft.com.
+clu-in.org.
+206.183.66.201.in-addr.arpa.
+a.root-servers.net.
+photos-c.ak.fbcdn.net.
+sp.ask.com.
+29.media.tumblr.com.
+3dhelpcenter.com.
+rxvwf5b7m.c62m8i2j.
+api.twitter.com.
+a.root-servers.net.
+www.ipcos.com.
+a7.sphotos.ak.fbcdn.net.
+maukdesign.com.inbound15.mxlogic.net.
+perigree.net.
+a7.sphotos.ak.fbcdn.net.
+yaahoo.co.uk.
+static.chartbeat.com.
+244.66.19.186.in-addr.arpa.
+vuz2006.ru.
+losyvr5z6.24uo.
+mujer.latercera.com.
+ilchildcare.org.
+photos-b.ak.fbcdn.net.
+juancamef.blogspot.com.
+a4.sphotos.ak.fbcdn.net.
+check6.facebook.com.
+mail-2.netbauds.net.
+i3.ytimg.com.
+images02.olx.com.
+gta-san-andreas-homeboys.softonic.com.br.
+photos-g.ak.fbcdn.net.
+a2.sphotos.ak.fbcdn.net.
+www.neverthirsty.org.
+218.18.155.109.in-addr.arpa.
+miportal.att.net.
+eruptedale.mcentcoughwith.tm.
+www.infolinks.com.
+149.172.109.200.in-addr.arpa.
+smurfs.capcomcanada.com.
+ioatelecom.net.
+roljoc.cl.
+befrikimyfriend.blogspot.com.
+caballonegroeditora.com.ar.
+www.unsystem.org.
+i1202.photobucket.com.
+baitassawadah.com.
+7.127.230.201.in-addr.arpa.
+www.google.com.
+zvpyn58u5.04cu.
+0-jx-w.channel.facebook.com.
+mail-attachment.googleusercontent.com.
+exp.msn.com.
+csi.gstatic.com.
+www.youtube.com.
+17.240.45.203.in-addr.arpa.
+cash2track.com.
+19.0.234.96.in-addr.arpa.
+notes.pcoa.com.
+a.root-servers.net.
+163.85.153.201.in-addr.arpa.
+225.218.84.108.in-addr.arpa.
+mxmail.diverseoptics.com.
+213.209.29.151.in-addr.arpa.
+www.upsjobs.com.
+a6.sphotos.ak.fbcdn.net.
+apps.facebook.com.
+a4.sphotos.ak.fbcdn.net.
+117.3.18.108.in-addr.arpa.
+peruahora.wordpress.com.
+creative.ak.fbcdn.net.
+mx.terraempresas.com.br.
+photos-g.ak.fbcdn.net.
+terminal29.ru.
+a.root-servers.net.
+251.224.177.189.in-addr.arpa.
+mwbankers.com.
+amertech.com.
+fr.answers.yahoo.com.
+a8.sphotos.ak.fbcdn.net.
+ro66ljmob.37tb.
+a.root-servers.net.
+rospres.com.
+tkprok.ru.
+106.133.224.190.in-addr.arpa.
+altavistagraphics.com.
+cesblogfeed.thinkpyxl.com.
+www.intel.com.
+www.gaybaires.net.
+www.ambito.com.
+20minutos.feedsportal.com.
+fr-fr.facebook.com.
+developers.facebook.com.
+mx.ppiseattle.com.
+tandem.spb.su.
+www.facebook.com.
+mail.gvan.ru.
+andreas.com.
+ssl.google-analytics.com.
+mail.gciframing.com.
+108.27.168.192.in-addr.arpa.
+ladamadelnilo.blogspot.com.
+253.191.136.189.in-addr.arpa.
+s-external.ak.fbcdn.net.
+littleowlski.wordpress.com.
+syndication.traffichaus.com.
+platform.ak.fbcdn.net.
+cv-extreme.chatango.com.
+36.147.220.66.in-addr.arpa.
+www.facebook.com.
+pixerloadbalancer-126298269.us-east-1.elb.amazonaws.com.
+img2.blogblog.com.
+booking.ihotelier.com.akadns.net.
+mx20.mame-imprimeurs.com.
+s-external.ak.fbcdn.net.
+twitter.com.
+mail.prendergast.net.
+149.83.23.186.in-addr.arpa.
+www.youtube.com.
+va.starcat.ne.jp.
+a4.sphotos.ak.fbcdn.net.
+qswkrjd:h.n09e8i6c.
+profile.ak.fbcdn.net.
+bcl.wikipedia.org.
+facemoods.com.
+231.31.245.189.in-addr.arpa.
+_854_29_5.
+a.root-servers.net.
+gohongkong.about.com.
+151.159.168.192.in-addr.arpa.
+s.ytimg.com.
+106.112.186.189.in-addr.arpa.
+60.80.193.123.in-addr.arpa.
+www.googleadservices.com.
+www.update.microsoft.com.
+cs506204.vk.com.
+sfis.k12.nm.us.
+raisingzona.com.
+mail2ray.com.
+repo.beyoip.com.
+plainview.k12.mn.us.
+tarea-escolar.blogspot.com.
+www.osrami.com.
+i2.ytimg.com.
+e5413.g.akamaiedge.net.
+b._dns-sd._udp.0.1.168.192.in-addr.arpa.
+sergecote.net.
+ncpennysaver.com.
+ssl.gstatic.com.
+api.conduit.com.
+ack-exchange.ask.ru.
+xads.zedo.com.
+ac3filter.en.softonic.com.
+k-e-s.ru.
+external.ak.fbcdn.net.
+ar-ar.facebook.com.
+bmc.org.
+astronomy.com.s8a1.psmtp.com.
+27.212.254.88.in-addr.arpa.
+26.216.193.62.in-addr.arpa.
+ajax.googleapis.com.
+10.190.119.79.in-addr.arpa.
+twitter.com.
+youtube.com.
+api.twitter.com.
+profile.ak.fbcdn.net.
+www.woozworld.com.
+www.ashtead-technology.com.
+tmss.trendmicro.com.
+233.57.132.190.in-addr.arpa.
+208.16.10.201.in-addr.arpa.
+ar-ar.facebook.com.
+www.oemdirtbikeparts.com.
+init.ess.apple.com.
+download4.dreamstime.com.
+www.facebook.com.
+igreen.net.
+g14755.chrome.funnygames.org.
+glennloomis.tcaps.net.
+www.discovirtual.com.ar.
+healtubgrant.com.
+sovereigngroup.com.
+monpetitmoment.blogspot.com.
+spacingmontreal.ca.
+fexea.com.
+30.83.111.189.in-addr.arpa.
+m.youtube.com.
+www.gotibia.com.
+photos-d.ak.fbcdn.net.
+legatarm.in.
+checkip.dyndns.com.
+assuredenvironments.com.s9a1.psmtp.com.
+i1.ytimg.com.
+www.hotelpiacenza.com.
+crl.verisign.com.
+a.root-servers.net.
+.
+help.trillian.im.
+v4.sftcdn.net.
+pixel.quantserve.com.
+api.twitter.com.
+www.google.com.
+worldoflya.blogspot.com.
+apis.google.com.
+hud93j8wi.47lv.
+165.191.10.187.in-addr.arpa.
+voxcast.oyunlar1.com.
+www.gamer.ne.jp.
+www.pinklolita.com.br.
+81.24.23.187.in-addr.arpa.
+a.ads2.msads.net.
+s-static.ak.fbcdn.net.
+100.187.58.186.in-addr.arpa.
+facebook.conduitapps.com.
+itd.pns.com.my.
+www.celeb-king.com.
+graph.facebook.com.
+r._dns-sd._udp.0.0.168.192.in-addr.arpa.
+static.ak.fbcdn.net.
+www.msftncsi.com.
+reomobile.com.
+19.224.171.69.in-addr.arpa.
+2.0.168.192.in-addr.arpa.
+www.egos.co.za.
+platform.twitter.com.
+174.193.166.81.in-addr.arpa.
+server-6.reportgoogle.com.
+www.google.com.
+fonts.googleapis.com.
+hgarden.org.2.0001.arsmtp.com.
+b.scorecardresearch.com.
+pda-bes.amazon.com.
+a.root-servers.net.
+38.109.223.189.in-addr.arpa.
+ad-g.doubleclick.net.
+adwhirllb-473732162.us-east-1.elb.amazonaws.com.
+time.nist.gov.
+www.youtube.com.
+60.247.212.89.in-addr.arpa.
+i.ebayimg.com.
+profile.ak.fbcdn.net.
+96.32.88.69.in-addr.arpa.
+pixel.facebook.com.
+mail.disqus.net.
+s-static.ak.fbcdn.net.
+mva.oryol.ru.
+config.conduitapps.com.
+www.scootergalleri.dk.
+forum.kijiji.ca.
+a8.sphotos.ak.fbcdn.net.
+fbcdn-profile-a.akamaihd.net.
+minduertex.com.
+bleedingespresso.com.
+245.102.55.157.in-addr.arpa.
+americanmaint.net.
+www.yohandry.com.
+www.carspluscash.com.
+bit.ly.
+api.twitter.com.
+it-it.facebook.com.
+photos-e.ak.fbcdn.net.
+44.140.173.114.in-addr.arpa.
+api.twitter.com.
+lighbound.com.
+i.ytimg.com.
+anubis.iseclab.org.
+accountservices.msn.com.
+facebook.com.
+corp.iminent.com.
+44.228.171.69.in-addr.arpa.
+tonio.com.
+www.quelocura.net.
+108.175.235.190.in-addr.arpa.
+56.248.159.110.in-addr.arpa.
+presents.lolapps.com.
+21.36.182.189.in-addr.arpa.
+197.206.229.189.in-addr.arpa.
+www.msftncsi.com.
+netflix887.pop3.la.nflximg.com.edgesuite.net.
+northfox.uw.hu.
+sammrat.com.
+a.root-servers.net.
+cdn.plugrush.com.
+d2057192.instant.xoom.it.
+www.theliquidateher.com.
+newsrss.bbc.co.uk.
+179.29.52.83.in-addr.arpa.
+photos-b.ak.fbcdn.net.
+rcp.na.blackberry.com.
+238.91.139.98.bl.spamcop.net.
+www.div3x.com.
+fls.doubleclick.net.
+3ie33cpgj6dhi-c.c.yom.mail.yahoo.com.
+groups.google.com.mx.
+misrmedical.com.
+megadresses.com.
+info.yahoo.com.
+ml.fb.telaxo.com.
+76.186.137.189.in-addr.arpa.
+www.bywifi.com.
+nokec.nkz.ru.
+koreanair.com.
+swa.mail.ru.
+70.146.38.77.in-addr.arpa.
+www.sublimepussy.com.
+omp1039.mail.ird.yahoo.com.
+photos-c.ak.fbcdn.net.
+fbcdn-profile-a.akamaihd.net.
+angel-dark.ps.ztod.com.
+a.root-servers.net.
+ari-texelectric.net.
+store.widdit.com.
+gfx8.hotmail.com.
+www.hoygan.info.
+nazer26.blogspot.com.
+www.eknigu.org.
+ad-emea.doubleclick.net.
+www.fjhuari.com.
+www.kibagames.com.
+a1407.phobos.apple.com.
+351.coll.ning.com.
+login.live.com.
+www.domainmastertools.com.
+m1.zedo.com.
+notifam.net.
+levenger.com.
+s1-powerpoint.vo.msecnd.net.
+foreca.palmaryservice.com.
+a4.sphotos.ak.fbcdn.net.
+www.bloomberg.co.jp.
+wa7edzah2an.blogspot.com.
+us-w1.rockmelt.com.
+hotmail.com.
+128.201.36.186.in-addr.arpa.
+d2059982.instant.xoom.it.
+29.219.23.186.in-addr.arpa.
+api.twitter.com.
+a1.sphotos.ak.fbcdn.net.
+97.95.78.190.in-addr.arpa.
+74819mailb.com.
+www.mydarkcirclesblog.com.
+dsn9.d.skype.net.
+services.addons.mozilla.org.
+a.root-servers.net.
+a.root-servers.net.
+altayvitamin.com.
+4wc24wv8u.68sg.
+billing.sharo4ka.ru.
+47.149.220.66.in-addr.arpa.
+ecn.dev.virtualearth.net.
+ocsp.digicert.com.
+91.169.214.201.in-addr.arpa.
+static.ak.fbcdn.net.
+api.facebook.com.
+233.90.55.65.bl.spamcop.net.
+searchclient.live.net.
+53.98.122.212.in-addr.arpa.
+books.google.com.
+farforest.btinternet.com.
+88.76.74.189.in-addr.arpa.
+www.mobileboner.com.
+gallys.nastydollars.com.
+seeyourimpact.org.
+islam.maktoob.com.
+www.mrskincdn.com.
+19.223.203.81.in-addr.arpa.
+kleyt.ru.
+127.0.0.1.
+www.google.com.
+_261_67_3.
+61.212.141.201.in-addr.arpa.
+worldofenglish.com.
+icode.renren.com.
+a1.sphotos.ak.fbcdn.net.
+highgate.k12.vt.us.
+pixel.facebook.com.
+chat2.doook.com.
+celeberitypictures.blogspot.com.
+cdn1.s.saboom.com.
+static.ak.fbcdn.net.
+et9.xhamster.com.
+safebrowsing.clients.google.com.
+evsecure-ocsp.verisign.com.
+twister.nyroc.rr.com.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+a2.sphotos.ak.fbcdn.net.
+4.189.173.189.in-addr.arpa.
+twobyhomes.com.
+3.170.158.157.in-addr.arpa.
+miconstruct.com.au.
+leglue.com.
+119.50.0.10.in-addr.arpa.
+mypixcontest.cotssl.net.
+igoogle.ca.
+57.11.53.201.in-addr.arpa.
+boomers.com.
+pixel.facebook.com.
+yeee.com.
+t3.gstatic.com.
+eventomundial.com.
+regallen.files.wordpress.com.
+telecomllc.net.
+stribling.com.
+offcars.blogspot.com.
+ir.ebaystatic.com.
+photos-b.ak.fbcdn.net.
+ns4.rambler.ru.
+ads.handycafe.com.
+rad.msn.com.
+.
+api.twitter.com.
+www.google.com.
+creative.ak.fbcdn.net.
+profile.ak.fbcdn.net.
+xv3uyxra3.70jq.
+developers.facebook.com.
+161.221.52.201.in-addr.arpa.
+www.losfotologs.com.
+home.mywebsearch.com.
+156.185.138.189.in-addr.arpa.
+a995.mm1.akamai.net.
+a.root-servers.net.
+www.googletagservices.com.
+a.root-servers.net.
+www.mafiavirtual.com.ar.
+ferchillgroup.com.
+www.theaudiophile.net.
+mail.nycap.rr.com.
+yahoo.com.
+a.root-servers.net.
+142.56.151.187.in-addr.arpa.
+rad.msn.com.
+www.youtube-nocookie.com.
+nlh.nl.ca.
+pixel.33across.com.
+market.android.com.
+37.165.149.187.in-addr.arpa.
+184.39.32.189.in-addr.arpa.
+box2.pc51.com.
+api.applifier.com.
+tour.cinamuse.com.
+www.bywifi.com.
+belarus.by.com.
+cyclonecom.com.
+111.105.104.189.in-addr.arpa.
+profile.ak.fbcdn.net.
+91.184.239.189.in-addr.arpa.
+lhsystems.hu.
+torrentz.eu.
+www.ibervideos.es.
+mail.cmc-jobs.com.
+193.244.68.66.in-addr.arpa.
+yahoo.ca.
+65.206.166.81.in-addr.arpa.
+s-static.ak.facebook.com.
+dnl-01.geo.kaspersky.com.
+metronorthnews.com.
+illiweb.com.
+etzatlan.mundoanuncio.com.mx.
+41.193.183.24.in-addr.arpa.
+www.camelback.net.
+fbcdn-sphotos-a.akamaihd.net.
+a.root-servers.net.
+169.110.50.190.in-addr.arpa.
+79.240.47.114.in-addr.arpa.
+alt2.gmail-smtp-in.l.google.com.
+black-byte.com.
+elonigiri.blogspot.com.
+214.165.10.187.in-addr.arpa.
+157.10.40.196.in-addr.arpa.
+www.cylex.com.co.
+news.l.google.com.
+photos-f.ak.fbcdn.net.
+nicola.com.s8b2.psmtp.com.
+11.rarbg.com.
+abacus.tumblr.com.
+tr.y8.com.
+ad.reachjunction.com.
+200.137.106.186.in-addr.arpa.
+www.conclavist.com.
+hotmail.com.
+www.facebook.com.
+155.98.193.82.in-addr.arpa.
+www.panasiabeauty.com.
+132.182.168.192.in-addr.arpa.
+content.yieldmanager.edgesuite.net.
+a7.sphotos.ak.fbcdn.net.
+a.root-servers.net.
+i2.ytimg.com.
+media.trafficjunky.net.
+www.globalbx.com.
+relay2.elcom.ru.
+a4.sphotos.ak.fbcdn.net.
+www.alignment2012.com.
+c.prodigy.msn.com.
+mail4.bizland-inc.net.
+d2090520.xoom.it.
+profile.ak.fbcdn.net.
+cjmoto.com.
+mail.hhicorp.com.
+iwkwhuplspkkpmbc.info.
+www.zentosa.com.
+photos-h.ak.fbcdn.net.
+datavis.com.inbound15.mxlogic.net.
+star.facebook.com.
+clients1.google.com.
+a.root-servers.net.
+198.78.162.31.in-addr.arpa.
+167.190.51.190.in-addr.arpa.
+rospres.com.
+dbupd281f.u94d5u6c.
+profile.ak.fbcdn.net.
+www.desirablebody.co.uk.
+cheezburger.com.
+pontodefuga.deviantart.com.
+165.93.188.186.in-addr.arpa.
+laclasedetercero-carmen.blogspot.com.
+bit.ly.
+cdn.content.sweetim.com.
+googleads.g.doubleclick.net.
+www.sosoni.com.
+voipc.sip.yahoo.com.
+27.57.59.186.in-addr.arpa.
+www.thestrapsmith.com.
+c2.glitch.bz.
+www.hotel-s.es.
+plus.google.com.
+pagead2.googlesyndication.com.
+tlhenterprisesin.com.
+www.uniongang.tv.
+moneycontrol.net.
+77.0.135.91.in-addr.arpa.
+www.youtube.com.
+a114.w23.akamai.net.
+a-1imaging.com.
+livel.co.uk.
+74.47.51.203.in-addr.arpa.
+bmi-md.com.
+istana.ru.
+aus2.mozilla.org.
+144.136.173.187.in-addr.arpa.
+static.ak.fbcdn.net.
+t3.gstatic.com.
+fra01-video4-2.justin.tv.
+67.33.215.108.in-addr.arpa.
+chahue.umar.mx.
+www.kaskus.com.
+ent.163.com.
+sun-garden.ch.
+a.root-servers.net.
+photos-c.ak.fbcdn.net.
+station.com.
+www.marias-santafe.com.
+pemper.sulit.com.ph.
+87.148.59.199.in-addr.arpa.
+forotopeleven.forofutbol.biz.
+issue2.show-star.biz.
+aloha.viber.com.
+g.ceipmsn.com.
+gualtiero.com.
+www.webactus.net.
+ocsp.godaddy.com.
+photos-g.ak.fbcdn.net.
+t.co.
+ksn1.kaspersky-labs.com.
+54.62.201.187.in-addr.arpa.
+teredo.ipv6.microsoft.com.
+ads17056.hotwords.es.
+api-read.facebook.com.
+www.youtube.com.
+157.70.111.189.in-addr.arpa.
+www.backgroundsforpowerpoint.net.
+117.34.84.200.in-addr.arpa.
+s1.assets.howtospendit.com.
+feedback.weather.com.
+st.chatango.com.
+api18.thetrafficstat.net.
+img693.imageshack.us.
+pagead2.googlesyndication.com.
+a.root-servers.net.
+www.cineplane.com.
+www.nsfcentc.org.
+dr._dns-sd._udp.lan.
+a.root-servers.net.
+www.montealban.org.mx.
+www.google-analytics.com.
+121.58.255.201.in-addr.arpa.
+www.google.com.
+155.11.0.192.in-addr.arpa.
+a.hikebike.gpsies.com.
+www.nguys.com.
+132.191.145.187.in-addr.arpa.
+a.root-servers.net.
+229.78.93.76.in-addr.arpa.
+i49.host%20no%20permitido.
+38.143.253.159.in-addr.arpa.
+mbc-law.com.
+imageup.liveasianwebcams.com.
+www.rosadesaron.net.
+www.industriasvargas.com.
+www.google-analytics.com.
+www.hassinen.eu.
+www.rbs.co.uk.
+a.root-servers.net.
+www.mujeres-guapas.com.
+a3.sphotos.ak.fbcdn.net.
+www.materialmontessori.com.
+fetch.yixingguanggao.trendcr002.com.
+vjzyuqpqq.k88x1x3f.domain.name.
+incub.ru.
+api.zynga.com.
+www.facebook.com.
+i1.ytimg.com.
+a7.sphotos.ak.fbcdn.net.
+inbound.markfrink.com.netsolmail.net.
+140.61.142.186.in-addr.arpa.
+_055_03_6.
+ksn1-11-part2.kaspersky-labs.com.
+photos-d.ak.fbcdn.net.
+154.71.43.208.in-addr.arpa.
+secure.quamm.net.
+golf-tees-story.info.
+svr4.hotweb.dk.
+103.19.253.190.in-addr.arpa.
+amer.rel.msn.com.
+i.ytimg.com.
+comdpx01.banacol.com.co.
+154.179.199.213.in-addr.arpa.
+creative.ak.fbcdn.net.
+cascaderaft.com.
+41.222.37.174.in-addr.arpa.
+airwis.com.
+246.231.38.189.in-addr.arpa.
+www.grannyflash.com.
+253.66.31.180.in-addr.arpa.
+a.root-servers.net.
+directory.services.live.com.
+www.blogextremo.com.
+231.157.74.187.in-addr.arpa.
+56.13.91.2.in-addr.arpa.
+www.sinhogar.org.
+bff-games.com.
+10.53.74.187.in-addr.arpa.
+css.wlxrs.com.
+www.cyberstep.com.
+blog.sina.com.tw.
+a5.sphotos.ak.fbcdn.net.
+www.google.es.
+fuyagil.blogspot.com.
+www.web-site-scripts.com.
+11.176.253.189.in-addr.arpa.
+175.22.158.189.in-addr.arpa.
+mail.modernspanish.com.
+patolinx.files.wordpress.com.
+www.empleosh.co.
+www.facebook.com.
+s-static.ak.fbcdn.net.
+a.root-servers.net.
+google.com.
+fr-fr.facebook.com.
+sky.766.com.
+photos-c.ak.facebook.com.edgesuite.net.
+i2.ytimg.com.
+bing.com.
+bluelaguna.net.
+files.myopera.com.
+mail.thethinkpad.com.
+s2.youtube.com.
+a.root-servers.net.
+mail.foxrunorchardpark.com.
+ads.tlvmedia.com.
+125.53.54.85.in-addr.arpa.
+cdn.thefreshxpress.com.
+photos-e.ak.fbcdn.net.
+plus.google.com.
+dc341.4shared.com.
+perumusic-entreteiment.blogspot.com.
+twitter.com.
+www.birdclipart.com.
+www.google.com.
+a.root-servers.net.
+a6.sphotos.ak.fbcdn.net.
+developers.facebook.com.
+121.245.19.204.in-addr.arpa.
+www.adobe.com.
+waterworth.org.uk.
+ad.clickotmedia.com.
+sport1hbl.neopoly.com.
+40.34.254.165.in-addr.arpa.
+platform.twitter.com.
+mail.topshelf-construction.com.
+craftworkinc.com.inbound15.mxlogic.net.
+8kcj2ge41.36hi.
+119.49.87.121.in-addr.arpa.
+www.laiting.com.
+www.fjx.co.jp.
+a.root-servers.net.
+accounts.google.com.
+polaris.vo.llnwd.net.
+books.google.com.
+mvcdmirror.webasyst.net.
+cdn.rockyou.com.
+schoedon.nl.
+mx.mg4.mail.yahoo.com.
+a.root-servers.net.
+mail.realprof.ru.
+runic.ru.
+www.recettes-de-cuisine-de-chef.fr.
+photos-b.ak.fbcdn.net.
+a.espncdn.com.
+haring.com.
+wzipkkjry.z22o1s3b.
+www.sikharchives.com.
+foreverwrap.net.
+o1.t26.net.
+www.facebook.com.
+250.10.134.189.in-addr.arpa.
+titofilm.com.
+static.ak.fbcdn.net.
+historia-sf.blogspot.com.
+160.31.152.189.in-addr.arpa.
+a.root-servers.net.
+www.fictionratings.com.
+www.library.mohdy.com.
+e-olam.com.
+ihiar9aj:.45rx.
+drainc.net.
+ja.wikipedia.org.
+jazzartistas.com.
+226.95.18.190.in-addr.arpa.
+external.ak.fbcdn.net.
+97.214.188.189.in-addr.arpa.
+nexdimension.net.
+i3.ytimg.com.
+a.root-servers.net.
+www.shiloh-fernandez.com.
+pt-br.facebook.com.
+dc417.4shared.com.
+14.249.122.84.in-addr.arpa.
+a5.sphotos.ak.fbcdn.net.
+ecom.be.
+www.myriahsbazaar.com.
+k4:7jxg9m.t76l9a0e.
+174.26.34.156.in-addr.arpa.
+phox.de.
+www.msn.com.
+d2060676.instant.xoom.it.
+ae.adserver.yahoo.com.
+dns.msftncsi.com.
+a.root-servers.net.
+bbswefong.myweb.hinet.net.
+153.127.4.31.in-addr.arpa.
+mail.airschool.ru.
+content.yieldmanager.edgesuite.net.
+1.0.0.127.dnsbugtest.1.0.0.127.in-addr.arpa.
+html.rincondelvago.com.
+242.47.137.190.in-addr.arpa.
+169.36.80.69.in-addr.arpa.
+banners.point2.com.
+a.root-servers.net.
+212.242.142.187.in-addr.arpa.
+www.google.com.
+www.facebook.com.
+ntp1.dlink.com.
+6tsgsc1y7.78ct.
+www.youtube-nocookie.com.
+217.124.93.178.in-addr.arpa.
+mail.production-systems.com.
+profile.ak.fbcdn.net.
+125.134.255.201.in-addr.arpa.
+youtube-global.blogspot.com.
+www.msftncsi.com.
+www.reunion-parcnational.fr.
+cdn.api.twitter.com.
+static2.shufuni.com.
+35.154.165.83.in-addr.arpa.
+a2.sphotos.ak.fbcdn.net.
+www.aljahraa.com.
+l.yimg.com.
+210.53.176.190.in-addr.arpa.
+transfer.ivwbox.de.
+api-read.facebook.com.
+blogergadgets.googlecode.com.
+www.linkedin.com.
+m.google.com.
+mozilla.cdn.leaseweb.com.
+adserver.adtechus.com.
+shirgie-story.blogspot.com.
+243.13.53.186.in-addr.arpa.
+search.yahoo.com.
+209.185.204.112.in-addr.arpa.
+212.209.32.174.in-addr.arpa.
+b._dns-sd._udp.0.0.168.192.in-addr.arpa.
+www.rhythmism.com.
+montreal.stepbystep.com.
+220.78.167.78.in-addr.arpa.
+www.joomfactory.com.
+127.75.163.189.in-addr.arpa.
+creative.ak.fbcdn.net.
+www.youtube.com.
+s0.2mdn.net.
+www.facebook.com.
+a1650.g.akamai.net.
+mx02.realvestcorp.com.
+buyback.letsbuy.com.
+board.u18chan.com.
+a6.sphotos.ak.fbcdn.net.
+pfifilter.com.
+imguser.pandora.tv.
+flamenco.com.
+gfx1.hotmail.com.
+qlibykkydx.info.
+www.hydroasis.com.
+t.co.
+south-park-super-mario-bros.softonic.com.
+63.131.144.189.in-addr.arpa.
+www.italiannis.com.
+akteamsters.com.s8a1.psmtp.com.
+wwwimages.adobe.com.
+www.nightmarefactory.com.
+98.50.224.88.in-addr.arpa.
+ut5.xhamster.com.
+static.ak.fbcdn.net.
+a1343.phobos.apple.com.edgesuite.net.
+webeffective.keynote.com.
+clipartspot.net.
+a.root-servers.net.
+profile.ak.fbcdn.net.
+209.154.86.201.in-addr.arpa.
+www.google.com.
+mail1.sig.com.
+mp3muffin.com.
+waps.net.
+hi-in.facebook.com.
+0123456789nonexistent.corn.
+lindsayhuffman.tumblr.com.
+clients1.google.com.
+photos-e.ak.fbcdn.net.
+www.bhbenz.com.
+www.cheapcoachmall.com.
+photos-c.ak.fbcdn.net.
+www.google.com.
+ocsp.thawte.com.
+csscript.com.
+trinitycatering.com.inbound10.mxlogicmx.net.
+config.acc.sogou.com.
+petshop.teamlava.com.
+photos-a.ak.fbcdn.net.
+photos-h.ak.fbcdn.net.
+www.update.microsoft.com.
+111.251.113.186.in-addr.arpa.
+accountservices.msn.com.
+55.44.100.190.in-addr.arpa.
+222.125.69.190.in-addr.arpa.
+pagesinxt.com.
+126.0.202.87.in-addr.arpa.
+atenas-librosyenciclopedias.espacioblog.com.
+ukravto.kiev.ua.
+db._dns-sd._udp.0.234.168.192.in-addr.arpa.
+p15-buy.itunes.apple.com.
+photos2.hi5.com.
+216.199.182.189.in-addr.arpa.
+external.ak.fbcdn.net.
+woho-nails.blogspot.com.
+z8bt1wxv4.y35c9z6g.
+chromejs.s3.amazonaws.com.
+www.lingeriebbwtgp.com.
+a6.sphotos.ak.fbcdn.net.
+dns.msftncsi.com.
+www.cristoparalasnaciones.com.
+ema-2009.mtvnimages.com.
+checkip.dyndns.org.
+www.amateurdumper.com.
+mariaeugeniasandin.blogspot.com.
+herring.south-west-water.co.uk.
+tag.admeld.com.
+www.elnuevodiario.com.ni.
+www.supercars.com.
+60.255.253.77.in-addr.arpa.
+www.bywifi.com.
+tuvlnqzjy.75nq.
+253.99.52.186.in-addr.arpa.
+106.255.34.177.in-addr.arpa.
+pathofgrowth.altervista.org.
+vwebhost.com.
+i4.ytimg.com.
+201.62.159.189.in-addr.arpa.
+ads.smowtion.com.
+s02.s3c.es.
+ve.starmedia.com.
+249.77.3.181.in-addr.arpa.
+alias.cyberpass.net.
+khairul-syahir.com.
+connect.facebook.net.
+connect.facebook.net.
+www.google.com.
+webassets3.sparkybee.com.
+netusa1.net.
+c.atdmt.com.
+code.jquery.com.
+google.com.
+platform.twitter.com.
+www.abchoy.com.ar.
+www.flasharcade.com.
+a2.sphotos.ak.fbcdn.net.
+181.9.23.67.zen.spamhaus.org.
+cn1.kaboodle.com.
+www.facebook.com.
+a.root-servers.net.
+promoscopio.com.
+im10.gulfup.com.
+api.search.us-west-1.iminent.com.
+www.derechoteca.com.
+photos-e.ak.fbcdn.net.
+s.mobclix.com.
+a.root-servers.net.
+tr.y8.com.
+api.twitter.com.
+www.addonsnetwork.com.
+client-software.real.com.
+s.youtube.com.
+www.iamburaot.com.
+wellfed.net.
+teredo.ipv6.microsoft.com.
+ac2farm.ign.com.
+136.198.242.201.in-addr.arpa.
+auersteel.com.s7a2.psmtp.com.
+static.ak.fbcdn.net.
+a.root-servers.net.
+toolbar.skype.com.
+www.facebook.com.
+www.facebook.com.
+graph.facebook.com.
+wooff1.com.
+edge.quantserve.com.
+musicaserver5.info.
+img.mediaplex.com.
+fbcdn-profile-a.akamaihd.net.
+233.16.61.128.in-addr.arpa.
+static.ak.fbcdn.net.
+a.root-servers.net.
+www.google-analytics.com.
+a.root-servers.net.
+casa.univision.com.
+www.consejodehombresbuenos.es.
+worldofbraiding.wordpress.com.
+db._dns-sd._udp.0.2.168.192.in-addr.arpa.
+emptydream.tistory.com.
+usd.de.fx-exchange.com.
+www.facebook.com.
+uvuhwxanqn.com.
+_954_98_1.
+www.gstatic.com.
+firststringent.com.
+photos-f.ak.fbcdn.net.
+vcs2.msg.yahoo.com.
+www.body-perfect-fitness.com.
+u20.eset.com.
+nray.ru.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+counter.yadro.ru.
+loading321.com.
+www.youtube.
+blogdelectoescritura.blogspot.com.
+136.158.48.65.in-addr.arpa.
+photos-a.ak.fbcdn.net.
+img-cdn.mediaplex.com.
+a4.da1.akamai.net.
+salud.latam.msn.com.
+i3.ytimg.com.
+apis.google.com.
+i2.ytimg.com.
+www.bizar-media.com.
+dtboot.orbitdownloader.com.
+b-0.19-a3008089.11481.1518.19d4.3ea1.210.0.lrvg7fljw5s2ze5phskpfk98jb.avqs.mcafee.com.
+livefiles19.vo.msecnd.net.
+44.195.117.121.in-addr.arpa.
+s1-word-edit.vo.msecnd.net.
+60.11.11.186.in-addr.arpa.
+mx3.axiomainc.com.
+time.nist.gov.
+hif.wikipedia.org.
+mi.hsbc.com.hk.
+b.scorecardresearch.com.
+mail.elbosco.ru.
+www.trouvelamour.com.
+usoakf01.pr-ury.pr-rcsa.org.
+benefitcorp.com.mx3.viyu.rcimx.net.
+encheres.nouvelles-frontieres.fr.
+sports.gaeatimes.com.
+sz4.tencent.com.
+by153w.bay153.mail.live.com.
+www.googleadservices.com.
+v3.lscache5.googlevideo.com.
+www.facebook.com.
+fbcdn-sphotos-a.akamaihd.net.
+qzone-music.qq.com.
+www.breakeven.org.
+a1092.g.akamai.net.
+mta6.am0.yahoodns.net.
+rmgelectrical.com.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+www.crazywisdomthemovie.com.
+www.slate.com.
+mijuchipila.com.
+238.191.236.77.in-addr.arpa.
+facial-neuralgia.org.
+www.googleadservices.com.
+118.158.13.189.in-addr.arpa.
+db._dns-sd._udp.0.1.168.192.in-addr.arpa.
+um14.eset.com.
+ppp85-140-31-73.pppoe.mtu-net.ru.
+194.231.90.74.in-addr.arpa.
+download.windowsupdate.com.
+margu5.galeon.com.
+dasolutions.us.
+www9.effectivemeasure.net.
+prod.rest-core.msg.yahoo.com.
+www.moneyville.ca.
+mobileage.com.
+i4.ytimg.com.
+www.google-analytics.com.
+i4.tagstat.com.
+s-static.ak.fbcdn.net.
+sakura.japanphilly.org.
+agestado.com.br.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+musifthiasno.tm.
+109.40.237.189.in-addr.arpa.
+www.youtube.com.
+a.root-servers.net.
+www.noticias-de-hoy.com.
+conquistar-al-hombre.info.
+www.luerzersarchive.net.
+136.45.128.189.in-addr.arpa.
+mail.ci.lynn.ma.us.
+3g.quick.com.
+i4.ytimg.com.
+photos-b.ak.fbcdn.net.
+a8.sphotos.ak.fbcdn.net.
+giglogo.com.
+113.72.219.201.in-addr.arpa.
+www.strengthcoach.com.
+websitesmakeover.com.
+www.google-analytics.com.
+www.cuc.edu.co.
+tinyurl.com.
+smtp.electricpenis.com.
+plusone.google.com.
+pioneerbuildersinc.com.
+fr.wikinews.org.
+125.132.205.190.in-addr.arpa.
+160.107.201.190.in-addr.arpa.
+10.112.46.196.in-addr.arpa.
+167.32.1.181.in-addr.arpa.
+www.facebook.com.
+15.209.19.186.in-addr.arpa.
+www.dvdvideosoft.com.
+sns.nskes.ru.
+174.0.159.189.in-addr.arpa.
+db._dns-sd._udp.0.10.168.192.in-addr.arpa.
+www.mercurytheatre.info.
+api.facebook.com.
+73.234.130.41.in-addr.arpa.
+db._dns-sd._udp.0.1.168.192.in-addr.arpa.
+spam.dixie.edu.
+google.com.
+csi.gstatic.com.
+my248nqay.l83x5m5n.
+thunder-nba.com.
+adedy.com.
+graph.facebook.com.
+diana.dti.ne.jp.
+559.coll.ning.com.
+a771.da1.akamai.net.
+168.8.31.88.in-addr.arpa.
+niaeeq.com.
+177.8.41.201.in-addr.arpa.
+teredo.ipv6.microsoft.com.
+a8.sphotos.ak.fbcdn.net.
+dingtao333.3322.org.
+h1.flashvortex.com.
+s.youtube.com.
+inbound.thepentadgroup.com.netsolmail.net.
+a.root-servers.net.
+didier.longueville.free.fr.
+mundomatematicas.blogspot.com.
+tdandh.com.
+a.root-servers.net.
+profile.ak.fbcdn.net.
+twitter.com.
+www.downloadhelper.net.
+aol.com.
+21.45.4.186.in-addr.arpa.
+sb-ssl.google.com.
+circavintageclothing.com.au.
+a3.sphotos.ak.fbcdn.net.
+chronicleholic.wordpress.com.
+239.2.30.186.in-addr.arpa.
+a1.mzstatic.com.
+subwaynw.com.
+a.root-servers.net.
+bayertechnology.com.
+fxfeeds.mozilla.com.
+_594_48_2.
+a995.mm1.akamai.net.
+a3.sphotos.ak.fbcdn.net.
+www.googleadservices.com.
+176.203.239.189.in-addr.arpa.
+41.158.220.66.in-addr.arpa.
+i2.ytimg.com.
+166.100.79.189.in-addr.arpa.
+70.83.101.189.in-addr.arpa.
+connect.facebook.net.
+14.174.210.201.in-addr.arpa.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+www.yousaytoo.com.
+redir.uol.com.br.
+1.0.0.127.dnsbugtest.1.0.0.127.in-addr.arpa.
+a1.sphotos.ak.fbcdn.net.
+76.153.231.67.in-addr.arpa.
+www.dish.com.mx.
+a.root-servers.net.
+mail.abodehome.com.
+iveracity.com.
+teredo.ipv6.microsoft.com.
+167.36.153.24.in-addr.arpa.
+sr01-sf02.stratixcorp.com.
+118.4.93.186.in-addr.arpa.
+www.carsampaf.org.
+ar.myspace.com.
+www.bing.com.
+smtp3.intermedia.net.
+zzkn5k1t9.80eg.
+cgw.download.nokia.com.
+sapopositivevibes.podomatic.com.
+185.122.250.190.in-addr.arpa.
+kayros.com.ar.
+translate.googleapis.com.
+p0b.ru.
+ads1.msads.net.
+18.128.135.117.in-addr.arpa.
+60.210.129.186.in-addr.arpa.
+feeds.bbci.co.uk.
+safebrowsing-cache.google.com.
+teredo.ipv6.microsoft.com.
+s10.histats.com.
+137.35.138.220.in-addr.arpa.
+ca.idoget.me.
+geogebreando.blogspot.com.
+agromex.de.
+i.w55c.net.
+195.212.139.98.dnsbl.sorbs.net.
+2cb3g5w24.j01g2r7u.
+safebrowsing-cache.google.com.
+diccionario.babylon.com.
+acercadeorange.orange.es.
+rainhaecuckold.blogspot.com.
+fbcdn-photos-a.akamaihd.net.
+pop001.masterhost.ru.
+photos-e.ak.fbcdn.net.
+profile.ak.fbcdn.net.
+2.pool.ntp.org.
+www.dogtipper.com.
+www.auditionsfinder.com.
+67.139.210.201.in-addr.arpa.
+a1764.phobos.apple.com.
+www.startopnews.com.
+194.29.95.201.in-addr.arpa.
+b.scorecardresearch.com.
+encinerados.blogspot.com.
+1.bp.blogspot.com.
+www.jamacareercenter.com.
+terralliance.com.2.0001.arsmtp.com.
+233.63.170.201.in-addr.arpa.
+a998.mm1.akamai.net.
+iphone-ld.apple.com.
+datatrakpharmaceuticals.com.
+paperwise.com.1.0001.arsmtp.com.
+briz.com.ru.
+www.dahotre.com.
+_389_87_1.
+a.root-servers.net.
+wpad.
+sinbad.se.
+mailgate1.royalchacehotel.co.uk.
+central.cardomain.com.
+suggest.infospace.com.
+www.hardsextube.com.
+apps.facebook.com.
+google.com.
+www.facebook.com.
+31.167.252.190.in-addr.arpa.
+a1.s6img.com.
+profile.ak.fbcdn.net.
+rbsmail.rutgers.edu.
+ijet.com.
+www.casinoesdinero.com.
+9to5mac.com.
+pjgitnik.com.
+www.edsitement.neh.gov.
+caserver.china.huawei.com.
+s1-excel.vo.msecnd.net.
+developers.facebook.com.
+a5.sphotos.ak.fbcdn.net.
+evsecure-ocsp.verisign.com.
+inbound.prix.com.netsolmail.net.
+search.twitter.com.
+streetlegal.co.uk.
+sites.google.com.
+www.blogger.com.
+socpixel.bidsystem.com.
+ticker.conduit.com.
+unb.ca.
+185.215.52.186.in-addr.arpa.
+a.root-servers.net.
+a.root-servers.net.
+r._dns-sd._udp.lan.
+facemoods.com.
+www.google.com.
+antiplaneta.ru.
+qorpak.com.s7a2.psmtp.com.
+twitter.com.
+22flowavenue.com.
+konntiwa.ranks1.apserver.net.
+secure.smflorida.com.
+digitaldatatrust.com.
+174.250.102.201.in-addr.arpa.
+148.88.92.186.in-addr.arpa.
+profile.ak.fbcdn.net.
+www.google-analytics.com.
+89.168.184.111.in-addr.arpa.
+44.28.138.187.in-addr.arpa.
+jameique.com.
+d2102520.xoom.it.
+powerclip.ru.
+a1404.w41.akamai.net.
+www.michalkotek.com.
+160.225.42.177.in-addr.arpa.
+thebrothersz.com.
+photos-g.ak.fbcdn.net.
+dns.msftncsi.com.
+foro.naruto-fans.net.
+12.224.171.69.in-addr.arpa.
+it-it.facebook.com.
+bios-repair.co.uk.
+ads2.msads.net.
+profile.ak.fbcdn.net.
+s.youtube.com.
+www.konami-pes2011.com.
+www.facebook.com.
+www.gaybcn.com.ar.
+maslibres.org.
+tools.google.com.
+tucodigo.mx.
+mothernewyork.com.
+khm1.google.com.
+76.143.140.190.in-addr.arpa.
+omp1057.mail.ne1.yahoo.com.
+.
+www.jamestaylor.com.
+i2.ytimg.com.
+a3.da1.akamai.net.
+evsecure-ocsp.verisign.com.
+www.dietpillrating.com.
+time.chttl.com.tw.
+dl.qt.nokia.com.
+aserver.jp.ru.
+www.facebook.com.
+img.mexat.com.
+db._dns-sd._udp.0.1.168.192.in-addr.arpa.
+110.106.53.75.in-addr.arpa.
+www.update.microsoft.com.
+update.wildtangent.com.
+76.216.152.85.in-addr.arpa.
+agebottom.com.
+www.google.com.
+211.2.0.192.in-addr.arpa.
+124.89.156.189.in-addr.arpa.
+pixel.quantserve.com.
+a6.sphotos.ak.fbcdn.net.
+landing.widdit.com.
+vaughanrealtors.com.
+evsecure-crl.verisign.com.
+kdc.uas.aol.com.
+damagents.com.inbound30.mxlogicmx.net.
+developers.facebook.com.
+api.conduit.com.
+umfa.ca.
+photos-h.ak.fbcdn.net.
+rz4:eo8vt.i20i9r3a.
+p.twimg.com.
+hotmail.com.
+pop3.live.com.
+146.208.94.190.in-addr.arpa.
+haptonstahl.org.
+s-static.ak.fbcdn.net.
+ar-ar.facebook.com.
+136.86.163.189.in-addr.arpa.
+voipb.sip.yahoo.com.
+remote.wras.co.uk.
+1zioube8g.24kh.
+tw8:u6nq7.92bj.
+cust20020-2.in.mailcontrol.com.
+mail.crwf.com.
+76.37.89.83.in-addr.arpa.
+77.8.181.186.in-addr.arpa.
+www.google.com.
+cs11261.vk.com.
+simages.artofthetrench.com.
+data.flurry.com.
+sitesbrasil.com.
+149.96.155.81.in-addr.arpa.
+i3.ytimg.com.
+2.75.150.201.in-addr.arpa.
+5.61.50.190.in-addr.arpa.
+www.google.com.
+mail.pcisynthesis.com.
+photos-d.ak.fbcdn.net.
+100.146.220.66.in-addr.arpa.
+242.67.42.24.in-addr.arpa.
+mail2.endosolutions.net.
+a7.sphotos.ak.fbcdn.net.
+1xbzfvc1l.p34f1h4z.
+cs11125.vk.com.
+www.sfdi.com.
+shop.lenovo.com.
+itunes.apple.com.
+static.pkt.pl.
+fuller-ve.com.
+fotos.videochaterotico.com.
+www.songstraducidas.com.
+img1.blogblog.com.
+siteground160.com.
+ma90-r.analytics.edgesuite.net.
+static.ak.fbcdn.net.
+www.foxsportsla.com.
+gab2.sub.ru.
+8.65.173.190.in-addr.arpa.
+www.hupo.com.
+tracker.publicbt.com.
+forums.land-and-sea.com.
+www.trigosubs.org.
+www.editorial.udg.mx.
+th822.photobucket.com.
+www.leadershipdigital.com.
+benefitmall.com.s7a2.psmtp.com.
+pixel.rubiconproject.com.
+kayser-photography.com.
+photos-g.ak.fbcdn.net.
+a.root-servers.net.
+jewelry-and-watches.become.com.
+www.google.com.
+www.satakore.com.
+plus.google.com.
+rec.eprice.it.
+grics.net.
+rs39tl2.rapidshare.com.
+photos-e.ak.fbcdn.net.
+www.nintendo.it.
+a.root-servers.net.
+cdn.fastclick.net.
+167.180.236.81.in-addr.arpa.
+blogverde.com.
+marmidicarrara.com.
+www.plusnetwork.com.
+nissan-avtogrand.ru.
+226.216.139.189.in-addr.arpa.
+dns.msftncsi.com.
+www.musicboxtheatre.com.
+18.98.205.190.in-addr.arpa.
+static.ak.fbcdn.net.
+hotmail.com.
+www.nemosvjerovat.com.
+itunes.apple.com.
+graph.facebook.com.
+profile.ak.fbcdn.net.
+photos-a.ak.fbcdn.net.
+39.180.250.88.in-addr.arpa.
+www.silverpricepergram.net.
+a1.mzstatic.com.
+thriftmeblog.com.
+www.chemicalelements.com.
+profile.ak.fbcdn.net.
+liveupdate.symantecliveupdate.com.
+photos-f.ak.fbcdn.net.
+mail7.digitalwaves.co.nz.
+bigwheels.ru.
+get.adobe.com.
+mt0.google.com.
+google.com.
+cs5103.vkontakte.ru.
+inca.com.
+183.172.191.186.in-addr.arpa.
+www.imdb.com.
+lakhanijordan.com.2.0001.arsmtp.com.
+www.bajadvd.com.
+sip.gmail.com.
+wext.ru.
+droidexpyoudroid.appspot.com.
+a8.sphotos.ak.fbcdn.net.
+mail.appframeworks.com.
+liveupdate.symantecliveupdate.com.
+video.google.com.mx.
+88.31.119.177.in-addr.arpa.
+photos-b.ak.fbcdn.net.
+199.140.175.187.in-addr.arpa.
+perlasdelfutbol.blogspot.com.
+pixel.facebook.com.
+www.classicmarry.com.
+carica.com.
+external.ak.fbcdn.net.
+mail.propanecentral.com.
+www.fundacionorange.es.
+www.cadeus.blogspot.com.
+a.root-servers.net.
+www.betajeux.com.
+www.specwarnet.net.
+partner.googleadservices.com.
+stats.qalabs.symantec.com.
+www.nicso.com.ar.
+static.ak.fbcdn.net.
+www.fmoriente.com.ar.
+d15be99dzjsmyn.cloudfront.net.
+www.camlive.com.
+help.vestax.co.jp.
+dns.msftncsi.com.
+mail.kazan-n.ru.
+dns.msftncsi.com.
+triplexqueens.wordpress.com.
+content.yieldmanager.edgesuite.net.
+crl.microsoft.com.
+cookex.amp.gapx.yahoodns.net.
+www.facebook.com.
+1.gravatar.com.
+google.com.mx.
+safebrowsing-cache.google.com.
+www.bucorp.com.
+b._dns-sd._udp.0.1.168.192.in-addr.arpa.
+photos-c.ak.fbcdn.net.
+connect.facebook.net.
+sp.cwfservice.net.
+au.download.windowsupdate.com.
+www.google.com.
+photos-e.ak.fbcdn.net.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+o1.t26.net.
+kworp:25z.32gt.
+a5.sphotos.ak.fbcdn.net.
+norsk-data.com.
+a2.sphotos.ak.fbcdn.net.
+photos-a.ak.fbcdn.net.
+cdngw.ustream.tv.
+mail.employeeconnect.com.
+cnfg.toolbarservices.com.
+a.root-servers.net.
+q1byqqepe.r48x2g9y.
+ads.adtiger.de.
+s.ytimg.com.
+tpb.tracker.thepiratebay.org.
+static.ak.fbcdn.net.
+www.facebook.com.
+teredo.ipv6.microsoft.com.
+197.68.7.189.in-addr.arpa.
+65.61.166.184.in-addr.arpa.
+a.ads2.msads.net.
+googleads.g.doubleclick.net.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+db._dns-sd._udp.lan.
+9.4.79.190.in-addr.arpa.
+s7.chatango.com.
+mx.ekipage.sp.ru.
+db._dns-sd._udp.0.1.168.192.in-addr.arpa.
+smtp3.masergy.com.
+compassgroup-nad.com.
+maps.google.com.
+gmmxc.imr.gm.com.
+hipay.com.
+85.192.185.93.in-addr.arpa.
+mx.studiolegalemarzano.com.
+www.imss.gob.mx.
+www.risk.net.
+orcart.facebook.com.
+branco.com.s9b1.psmtp.com.
+i2.ytimg.com.
+siteslegais.com.
+atomic-vfx.com.
+128.186.183.88.in-addr.arpa.
+widgets.amung.us.
+91.169.120.186.in-addr.arpa.
+_492_16_1.
+profile.ak.fbcdn.net.
+gol.grosseto.it.
+139.195.152.190.in-addr.arpa.
+autos.yahoo.com.
+32.171.160.187.in-addr.arpa.
+cdn.toolstation.com.
+maestrodelacomputacion.blogspot.com.
+timmsmot.freeserve.co.uk.
+65.227.193.190.in-addr.arpa.
+digsin.com.
+fjpoemas.soopbook.es.
+static.ak.fbcdn.net.
+static.ak.fbcdn.net.
+mail4.emagister.com.
+204.76.44.187.in-addr.arpa.
+portugaltradicionalista.blogspot.com.
+bluelfs.files.wordpress.com.
+photos-f.ak.fbcdn.net.
+divxrepair.softonic.com.
+www.google.com.
+a1513.oadz.com.
+98b7nkh7s.h49e5t6e.
+uniqsolutions.ru.
+gdata.youtube.com.
+photos-g.ak.fbcdn.net.
+av1.ibm.com.
+csi.gstatic.com.
+www.setbook.org.
+picasaweb.google.com.
+assets3.castle.zgncdn.com.
+a1402.w40.akamai.net.
+static.adsender.us.
+ksn1-11-part1.kaspersky-labs.com.
+84.87.17.190.in-addr.arpa.
+www.biglinks.com.br.
+notify3.dropbox.com.
+choose-language.ru.
+www.facebook.com.
+instagr.am.
+hylinecruises.com.s7a1.psmtp.com.
+mechel-bank-msk.ru.
+a1726.b.akamai.net.
+59.98.170.189.in-addr.arpa.
+static.ak.fbcdn.net.
+www.gamecompare.com.
+42.90.233.213.in-addr.arpa.
+92.12.52.186.in-addr.arpa.
+xxzgfpxn8.25xx.
+safebrowsing-cache.google.com.
+sport.se.msn.com.
+netflix360.pop3.la.nflximg.com.edgesuite.net.
+vitoria.campusanuncios.com.
+www.sensible.com.
+medimax.org.
+nats.seemybucks.com.
+sp.cwfservice.net.
+a.root-servers.net.
+nikita.dod.ru.
+utm9.apn.ask.com.
+172.2.35.174.in-addr.arpa.
+ads.intergi.com.
+api.twitter.com.
+static.ak.fbcdn.net.
+www.lynxeffect.com.
+photos-h.ak.fbcdn.net.
+cdn59.atkingdom-network.com.
+177.195.18.186.in-addr.arpa.
+ssl.gstatic.com.
+a995.mm1.akamai.net.
+147.100.205.112.in-addr.arpa.
+osterdowjones.net.
+o.xbox.com.
+protk.com.inbound15.mxlogic.net.
+76.208.30.50.in-addr.arpa.
+alliance1.com.
+developers.facebook.com.
+melodi.ru.
+secureninja.com.
+udg.com.
+247.104.9.177.in-addr.arpa.
+ad.doubleclick.net.
+mail2.andreevsoft.ru.
+www.belkin.com.
+photos-a.ak.fbcdn.net.
+ohxasi.com.
+www.facebook.com.
+lh3.ggpht.com.
+7368656c6c.77696e646f7773.636f6d.80h4137e259.webcfs00.com.
+tracker.istole.it.
+www.seuatdigital.edu.mx.
+ksn2-12.kaspersky-labs.com.
+254.1.253.201.in-addr.arpa.
+ads.wicked.com.
+146.43.174.190.in-addr.arpa.
+tomclemente.com.
+_836_16_7.
+109.229.2.173.in-addr.arpa.
+googleads.g.doubleclick.net.
+morehod.com.
+cathotmail.com.
+hotguitarist.com.
+p0b.ru.
+www.halosweet.com.
+35.92.249.77.in-addr.arpa.
+www.bitbest.ru.
+mail.reefdevelopment.com.
+static3.educaedu.com.mx.
+129.129.140.189.in-addr.arpa.
+adwhirllb-473732162.us-east-1.elb.amazonaws.com.
+5.64.112.189.in-addr.arpa.
+www.dragonflygame.com.
+33.50.169.118.in-addr.arpa.
+www.fanfarlo.com.
+sp.cwfservice.net.
+mgb.minutebuzz.com.
+img1.imagilive.com.
+224.241.191.89.in-addr.arpa.
+profile.ak.fbcdn.net.
+pixel.facebook.com.
+1.0.0.127.dnsbugtest.1.0.0.127.in-addr.arpa.
+ar.voicefive.com.
+karen.
+www.sitc.ru.
+164.60.0.10.in-addr.arpa.
+a8.sphotos.ak.fbcdn.net.
+www.bookclub.kodansha.co.jp.
+217.224.48.60.in-addr.arpa.
+emirnewusenglish.112.2o7.net.
+eslprintables.ourtoolbar.com.
+support.google.com.
+222.206.195.187.in-addr.arpa.
+172.77.37.46.in-addr.arpa.
+ebookbrowse.com.
+8.153.190.186.in-addr.arpa.
+183.122.5.181.in-addr.arpa.
+clients.sidesmedia.com.
+urs.microsoft.com.
+scfafsbfs.com.
+monsterone.netease.net.
+zh-cn.facebook.com.
+tracker21.970dbf83-5db6-4e8f-9c50-678fcc4b29a3.automated.snxd.com.
+www.pelislatino.com.
+a.root-servers.net.
+ajax.googleapis.com.
+226.139.101.187.in-addr.arpa.
+mail.lordflex.com.
+yoghismo.org.
+preppyplayer.blogspot.com.
+teredo.ipv6.microsoft.com.
+inbound.cai-value.com.netsolmail.net.
+mail.eoffice-virtualassist.com.
+www.autopenhosting.org.
+www.adobe.com.
+www.stopusa.be.
+www.hotelnjoy.com.
+blackstartube.com.
+yahoo.com.
+www.rugby.invescoperpetual.co.uk.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+theeconomist.com.
+www.musica-online.org.
+hi-in.facebook.com.
+126.213.11.109.in-addr.arpa.
+www.xtoolspro.com.
+a1.da1.akamai.net.
+80.89.145.64.in-addr.arpa.
+www.vocibo.com.
+im2.b.qq.com.
+a8.sphotos.ak.fbcdn.net.
+58.129.6.189.in-addr.arpa.
+plusone.google.com.
+multistreaminghost.com.
+sn1msg1010831.gateway.messenger.live.com.
+www.tagorormusic.com.
+mail.impauto.com.
+wron.net.
+youtu.be.
+i-69ee300c.us-east-1b.service.amazonsilk.com.
+sender1.critsend.com.
+a8.sphotos.ak.fbcdn.net.
+158.23.130.181.in-addr.arpa.
+rpc.ant.com.
+api.nanigans.com.
+a.root-servers.net.
+photos-g.ak.fbcdn.net.
+gimp.nl.softonic.com.
+accugenix.com.
+btopenworld.com.
+s0.2mdn.net.
+www.crocschile.cl.
+arstravelgroup.com.
+d2094296.xoom.it.
+a.tribalfusion.com.
+www.periodistasenlinea.org.
+ib.adnxs.com.
+www.alquz.com.
+safebrowsing-cache.google.com.
+lagrimasdescarcha.blogspot.com.
+horsemart.co.uk.
+gmail.com.
+0.11-a30f6081.80410b1.1518.19d4.3ea1.410.0.61kaku9epkicp1kh283n94tccv.avqs.mcafee.com.
+photos-h.ak.fbcdn.net.
+www.google-analytics.com.
+s.youtube.com.
+a8.sphotos.ak.fbcdn.net.
+a.root-servers.net.
+games.metaservices.microsoft.com.
+www.html.am.
+8888123.com.
+tlk.tc.
+mp3magic.ru.
+api.bing.com.
+static3.carsablanca.de.
+time.windows.com.
+53.107.170.189.in-addr.arpa.
+254.55.153.81.in-addr.arpa.
+242.175.28.187.in-addr.arpa.
+photos-c.ak.fbcdn.net.
+teredo.ipv6.microsoft.com.
+a.root-servers.net.
+a3.sphotos.ak.fbcdn.net.
+www.turtlemax.com.
+otcopymadrid.wordpress.com.
+90.23.191.186.in-addr.arpa.
+blu.stj.s-msn.com.
+profiles.google.com.
+48-courier.push.apple.com.
+freelaptops4you.net.
+59.115.36.186.in-addr.arpa.
+www.guittard.com.
+api.search.iminent.com.
+touch.facebook.com.
+infoterra.com.
+profile.ak.fbcdn.net.
+beacon.shazam.com.
+rustel.ru.
+creative.ak.fbcdn.net.
+flyvar28.33x.com.
+ajax.googleapis.com.
+ksn2-12.kaspersky-labs.com.
+www.postcardchess.com.
+es.answers.yahoo.com.
+apps.facebook.com.
+evsecure-crl.verisign.com.
+tractors.com.sg.
+c1.softonicads.com.
+pixel.facebook.com.
+feldchevrolet.com.
+168.12.56.188.in-addr.arpa.
+wweenvivo.com.mx.
+64.189.59.186.in-addr.arpa.
+www.iegallery.com.
+photos-a.ak.fbcdn.net.
+p07-keyvalueservice.icloud.com.
+apps.skype.com.
+a8.sphotos.ak.fbcdn.net.
+dr._dns-sd._udp.0.0.168.192.in-addr.arpa.
+147.9.165.189.in-addr.arpa.
+photos-b.ak.fbcdn.net.
+www.expertosensalarios.com.
+plus.google.com.
+119.22.254.201.in-addr.arpa.
+172.93.48.190.in-addr.arpa.
+s1-excel.vo.msecnd.net.
+fbcdn-profile-a.akamaihd.net.
+a.rad.msn.com.
+articulosinformativos.com.mx.
+developers.facebook.com.
+notepad2.en.softonic.com.
+canvasli.com.
+www.facebook.com.
+mail.avrupaholding.com.tr.
+www.igaymobile.com.
+zpay.static.zynga.com.
+kick.com.
+mx.yahoo.com.
+photos.end.com.ni.
+ads5.speedbit.com.
+gorna.net.
+polar.dyndns.tv.
+daricemichelle.com.
+www.sumospeed.com.
+www.aroundphilly.com.
+189.142.149.189.in-addr.arpa.
+75.28.168.192.in-addr.arpa.
+www.tumejorindirecta.com.
+servizi.tiscali.it.
+assets2.castle.zgncdn.com.
+a5.sphotos.ak.fbcdn.net.
+134.16.132.187.in-addr.arpa.
+www.lesbuan.com.
+215.19.113.187.in-addr.arpa.
+nextel.tv.
+ie9cvlist.ie.microsoft.com.
+www.metropolisweddingdress.com.
+me1sifs30001.unilever.com.
+42.204.15.187.in-addr.arpa.
+194.176.22.190.in-addr.arpa.
+a1.sphotos.ak.fbcdn.net.
+a.root-servers.net.
+www.kat.ph.
+yahoo.co.uk.
+api.yontoo.com.
+profile.ak.fbcdn.net.
+www.riegl.com.
+bizarringa.blogspot.com.
+217.163.139.110.in-addr.arpa.
+adtech.habbo.com.
+165.60.168.200.in-addr.arpa.
+local.
+www.ntteuropeonline.es.
+bcmls2.glpals.com.
+kimmymanga.deviantart.com.
+weldstar.com.
+eq.leadtrks.com.
+idols-rock.blogspot.com.
+pollstar.com.
+www.visjonnorge.com.
+www.dinsdoc.com.
+www.facebook.com.
+dns.msftncsi.com.
+connect.facebook.net.
+www.viacom.com.
+platform.twitter.com.
+180.97.0.190.in-addr.arpa.
+info-depresion.blogspot.com.
+invisiblemente.blogspot.com.
+www.facebook.com.
+a.root-servers.net.
+photos-c.ak.fbcdn.net.
+deimagenesnaruto.blogspot.com.
+ad-g.doubleclick.net.
+t3.gstatic.com.
+google.com.mx.
+connect.facebook.net.
+www.revista-wicca.com.ar.
+a.root-servers.net.
+tap.rubiconproject.com.
+www.facebook.com.
+photos-b.ak.fbcdn.net.
+www.papelenblanco.com.
+nopalinaeuropa.com.
+notaria93.com.
+fourstaradvertising.com.
+www.google.com.
+login.bearshare.com.
+sec-consulting.com.
+130.108.182.175.in-addr.arpa.
+a.root-servers.net.
+maps.l.google.com.
+enpathmedical.com.
+cxi1asjvv.87iq.
+a-0.19-3109e001.a040082.1518.19d3.36d4.210.0.nhhqd33j1qiwjll937r7qq7acv.avqs.mcafee.com.
+a.root-servers.net.
+searchclient.live.net.
+audibleuk.tt.omtrdc.net.
+www.pbk.org.
+a17.x-traceur.com.
+www.chatcasero.com.
+zelenb.com.
+mail.communityservicescouncil.ca.
+services.tvkaista.fi.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+pixel.facebook.com.
+www.textsrv.com.
+www.arezzo.com.br.
+0-jw-w.channel.facebook.com.
+.
+253.98.224.71.in-addr.arpa.
+www.runescape-private-server.info.
+bestworldprofit.com.
+www.megacockcravers.com.
+tripadvice.ru.
+a.root-servers.net.
+215.159.0.189.in-addr.arpa.
+108.90.145.175.in-addr.arpa.
+wpad.
+profile.ak.fbcdn.net.
+196.234.132.190.in-addr.arpa.
+hotamatuermoms.com.
+103.166.131.187.in-addr.arpa.
+blackmetal.co.uk.
+www.avimont.com.
+uhzdkco1y.81th.
+classic.weezer.com.
+_643_82_0.
+boosted.com.
+67.185.164.189.in-addr.arpa.
+r13.lhr14g01.c.youtube.com.
+smtp.vallivue.org.
+safebrowsing.clients.google.com.
+rcp.na.blackberry.com.
+c.atdmt.com.
+sdafds.com.
+economia.gob.mx.
+rcxbgprpl.b58f1z0c.
+42.148.126.186.in-addr.arpa.
+108.226.82.81.in-addr.arpa.
+s7.addthis.com.
+206.14.235.123.in-addr.arpa.
+smtp.uggc.com.
+97.73.127.200.in-addr.arpa.
+canalcocina.es.
+profile.ak.fbcdn.net.
+albion.net.
+ocsp.digicert.com.
+fbcdn-photos-a.akamaihd.net.
+realtyventurecap.com.
+aebersold.ch.
+webunlp.unlp.edu.ar.
+mymodernmet.mobify.me.
+css.wlxrs.com.
+a6.sphotos.ak.fbcdn.net.
+www.outline.it.
+cercopdf.com.
+mail.wyobuilds.com.
+a.root-servers.net.
+childers-construction.com.
+games.espn.go.com.
+www.compromisorse.com.
+a1404.w41.akamai.net.
+scholar.google.com.
+mail.coralcadillac.com.
+www.stellaoflondon.co.uk.
+mail.whessoe.co.uk.
+ak-media.soundcloud.com.
+28.47.255.201.in-addr.arpa.
+b._dns-sd._udp.0.1.168.192.in-addr.arpa.
+lensylproducts.com.s9a2.psmtp.com.
+homeserve.com.
+mail.bca.ru.
+www.aitfa.org.
+40.232.86.74.in-addr.arpa.
+www.thetoshibatablet.com.
+www.autonotel.es.
+www.ciafp.com.
+27.media.tumblr.com.
+48.100.11.190.in-addr.arpa.
+h.live.com.
+11.248.230.190.in-addr.arpa.
+alterglobalizacion.wordpress.com.
+market.android.com.
+102.243.47.189.in-addr.arpa.
+www.facebook.com.
+www.pulug.com.
+fc60.deviantart.com.
+www.koala.net.
+www.lavidasegunxime.com.
+119.217.239.201.in-addr.arpa.
+broekhuisjuweliers.nl.
+ping3.teamviewer.com.
+learningexchange.ptc.com.
+162.220.159.82.in-addr.arpa.
+www.viamujer.com.
+0.1887503.com.
+a367.phobos.apple.com.edgesuite.net.
+picasaweb.google.com.
+farm3.static.flickr.com.
+static.ak.fbcdn.net.
+hotmail.co.uk.
+antropologiadelareligion.blogspot.com.
+206.16.122.24.in-addr.arpa.
+www.einicio.com.
+fashionscandal.com.
+ads.revsci.net.
+modulstroy.ru.
+news.google.com.mx.
+creative.ak.fbcdn.net.
+234.33.88.186.in-addr.arpa.
+cache5.bbs.cn.yahoo.com.
+vf.cloud.avg.com.
+64.78.178.95.in-addr.arpa.
+watchdrama24.com.
+adm.citytlt.ru.
+clients1.google.com.
+207.236.35.177.in-addr.arpa.
+40.4.235.178.in-addr.arpa.
+cf.addthis.com.
+209.37.136.190.in-addr.arpa.
+www.apple.com.
+rjins.com.
+mail.dmlp.net.
+av-desk.ru.
+www.hellas-jet.com.
+www.hoteldeturistas.net.
+a2.sphotos.ak.fbcdn.net.
+cm.ac3.msn.com.
+ktones.us.
+20.165.32.188.in-addr.arpa.
+fstkrahwrq.org.
+photos-a.ak.fbcdn.net.
+.
+chat.facebook.com.
+212.63.33.62.in-addr.arpa.
+mntr.babcdn.com.
+lascosicasdeange.blogspot.com.
+rk:d7p136.27bn.
+www.google.com.
+172.7.127.200.in-addr.arpa.
+protaxservices.com.
+privacy.io.
+jalateqla.blogspot.com.
+es-la.facebook.com.
+golfetc.com.
+23.122.226.98.in-addr.arpa.
+119.50.74.190.in-addr.arpa.
+www.youtube.com.
+www.google-analytics.com.
+118.28.148.109.in-addr.arpa.
+canalbruselas.blogspot.com.
+accounts.google.com.
+l68dqdzmrcyj16j56pudqgup22n50iuoqmwfr.com.
+albassfed.org.
+fs579.uploading.com.
+iv:c7dnvp.s42e5m6y.
+226.151.203.190.in-addr.arpa.
+photos-d.ak.fbcdn.net.
+mainonta.jatkoaika.com.
+179.40.116.99.in-addr.arpa.
+dr._dns-sd._udp.lan.
+a.root-servers.net.
+r._dns-sd._udp.0.0.168.192.in-addr.arpa.
+dsn1.d.skype.net.
+a7.sphotos.ak.fbcdn.net.
+bsf.smowtion.com.
+ww2.clothingshowroom.com.
+www.google.com.
+www.strengtheningmarriage.com.
+clients1.google.com.
+21.211.171.201.in-addr.arpa.
+altavista.su.
+photos-e.ak.fbcdn.net.
+a.root-servers.net.
+cooksign.com.
+ads2.msads.net.
+92.158.26.46.in-addr.arpa.
+bpt.net.
+mail.imageriedigitale.com.
+graph.facebook.com.
+80.91.139.98.sa-accredit.habeas.com.
+m.facebook.com.
+smtp-gw.qti.com.
+177.13.51.190.in-addr.arpa.
+victortabernero.wordpress.com.
+www.microsoft.com.
+65.137.113.186.in-addr.arpa.
+www.aado.org.
+mgtracker.org.
+35.100.241.189.in-addr.arpa.
+i1159.photobucket.com.
+143.157.8.78.in-addr.arpa.
+nuts-and-bolts-of-cakephp.com.
+www.google-analytics.com.
+6.236.171.118.in-addr.arpa.
+platform.ak.fbcdn.net.
+specath.ru.
+a.root-servers.net.
+154.60.58.186.in-addr.arpa.
+rs742tl.rapidshare.com.
+mail.warris.com.
+ksn3-11.part1.kaspersky-labs.com.
+acumetrics-com.mail.eo.outlook.com.
+terpsys.com.
+w671.photobucket.com.
+etalon-centre.ru.
+www.stopbadware.org.
+www.femdomnirvana.com.
+s-external.ak.fbcdn.net.
+anki.ichi2.net.
+bsnav9vog.h10m0z1y.
+craneplasticsmfg.com.s5b1.psmtp.com.
+na3sys010aog103.obsmtp.com.
+ds.serving-sys.com.
+twitter.com.
+www.greenfeet.com.
+irc.kelebekmafia.com.
+a3.sphotos.ak.fbcdn.net.
+a.root-servers.net.
+www.google.com.
+mail.
+gnuworldorder.info.
+taxi-profi.ru.
+www.texasonline.state.tx.us.
+sea.liveatc.net.
+www.nobel.unam.mx.
+creative.ak.fbcdn.net.
+hipay.com.
+pcimagenetwork.com.
+ad.harrenmedianetwork.com.
+hotmail.com.
+www.supporter.com.
+us.data.toolbar.yahoo.com.
+clients1.google.com.
+europa.meteoconsult.es.
+dwiex402.mumc.nl.
+a-0.19-220f0001.590.1518.19d4.3ea1.410.0.261uh4tz9r79h32int7h8u92it.avqs.mcafee.com.
+agoldenworld.files.wordpress.com.
+facebook.com.
+ad.yieldmanager.com.
+www.aspeneducation.com.
+websearch.ask.com.
+a.root-servers.net.
+cityvillefb0.static.zgncdn.com.
+ad.yieldmanager.com.
+sp.cwfservice.net.
+photos-b.ak.fbcdn.net.
+photos-d.ak.fbcdn.net.
+170.94.5.190.in-addr.arpa.
+akko.es.
+www.gn4me.com.
+fr-fr.facebook.com.
+392327.r.msn.com.
+es-la.facebook.com.
+www.rodatec.com.
+s0.2mdn.net.
+www.indonesiacommerce.com.
+orcart.facebook.com.
+201.1.60.68.in-addr.arpa.
+profile.ak.fbcdn.net.
+translate.google.com.mx.
+www.pokemontcg.com.
+mitchhedberg.net.
+logc214.xiti.com.
+sp.cwfservice.net.
+www.crecenegocios.com.
+127.86.21.107.in-addr.arpa.
+csc3-2004-crl.verisign.com.
+t3.gstatic.com.
+www.mediawiki.org.
+t4ft.de.
+trailw.dealply.com.
+shared.live.com.
+30.188.77.189.in-addr.arpa.
+24.15.107.76.in-addr.arpa.
+a1.sphotos.ak.fbcdn.net.
+173.23.255.190.in-addr.arpa.
+ox-d.appprizes.com.
+128.148.163.190.in-addr.arpa.
+86.73.43.190.in-addr.arpa.
+73.138.146.195.in-addr.arpa.
+www.markdom.de.
+xvideos-176.vo.llnwd.net.
+a.root-servers.net.
+www.groovybookmarks.com.
+65.151.59.174.in-addr.arpa.
+profile.ak.fbcdn.net.
+relay.gt66.ru.
+39.220.112.186.in-addr.arpa.
+virtualdubmod.en.softonic.com.
+zierkecompany.com.
+toolbarqueries.clients.google.com.
+csc3-2004-crl.verisign.com.
+google.com.
+s-static.ak.fbcdn.net.
+80.119.101.76.in-addr.arpa.
+developer.amazonwebservices.com.
+sms-group.net.
+www.facebook.com.
+133.80.158.79.in-addr.arpa.
+jewelleryrussia.ru.
+43.60.93.200.in-addr.arpa.
+mepunoonaker.ws.
+www.facebook.com.
+bloggergadgets.googlecode.com.
+www.as.com.
+global.wetter.com.
+a1375.g.akamai.net.
+ad.yieldmanager.com.
+www.superior-replica.com.
+ad-g.doubleclick.net.
+a.ads1.msads.net.
+mms602.whatsapp.net.
+apix.iminent.com.
+clients1.google.com.
+demsandemir.com.
+mbspares.chance.ru.
+igor.facemoods.com.
+bmx.burg-gmbh.de.
+27.16.229.89.in-addr.arpa.
+prl.res.in.
+www.stetina.com.
+26.158.33.83.in-addr.arpa.
+glorycycles.csell.store.yahoo.net.
+ut9.xhamster.com.
+a.root-servers.net.
+connect.facebook.net.
+photos-a.ak.fbcdn.net.
+cy.wikipedia.org.
+141.8.165.142.in-addr.arpa.
+arkleh.state.ar.us.
+twitter.com.
+safebrowsing-cache.google.com.
+hi-in.facebook.com.
+www.shopper.pk.
+www.gstatic.com.
+www.google.com.
+a.root-servers.net.
+189.25.111.95.in-addr.arpa.
+www.andamanadventures.com.
+18733.ua.all.biz.
+www.mindennapok.hu.
+uny2.com.
+photos-c.ak.fbcdn.net.
+111.165.195.190.in-addr.arpa.
+nigmahon.blogspot.com.
+www.yout.
+apps.facebook.com.
+profile.ak.fbcdn.net.
+159.147.239.190.in-addr.arpa.
+avalera.net.
+mail2.oblgazeta.ru.
+sanfranciscogym.info.
+38.12.137.82.in-addr.arpa.
+bogpost.dk.
+45.52.222.189.in-addr.arpa.
+www.artrabbit.com.
+blog.baomoi.com.
+static.ak.fbcdn.net.
+www.belkin.com.
+creative.ak.fbcdn.net.
+a1408.w43.akamai.net.
+profile.ak.fbcdn.net.
+isb-sib.ch.
+cdn.api.twitter.com.
+7f4b6f993392711663fac8b835e717f5.dnsbl7.mailshell.net.
+www.website-monitoring.com.
+row.bc.yahoo.com.
+vinossingulares.wordpress.com.
+carloslugo2008.blogspot.com.
+photos-a.ak.fbcdn.net.
+s2.youtube.com.
+www.cookbakelove.com.
+google.com.
+campusconnect.depaul.edu.
+dns.msftncsi.com.
+itunes.apple.com.
+www.pocketpcthoughts.com.
+ksn2-12.kaspersky-labs.com.
+www.blogmond.com.
+a.root-servers.net.
+static.ak.fbcdn.net.
+profile.live.com.
+73.107.64.109.in-addr.arpa.
+a5.sphotos.ak.fbcdn.net.
+www.barcelonatv.com.
+es.888.com.
+www.maturesexual.com.
+a1.sphotos.ak.fbcdn.net.
+4na5h:8x6.29jg.
+plusone.google.com.
+ds.addthis.com.
+www.sonography.net.
+db._dns-sd._udp.0.1.168.192.in-addr.arpa.
+nortwork.com.br.
+specialflorist.com.
+21.228.171.69.in-addr.arpa.
+crl.microsoft.com.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+mail2.amarahotels.com.
+digg.com.
+www.nude-imps.biz.
+photos-f.ak.fbcdn.net.
+cdtorg.ru.
+bbti7po78.b85o3p3m.
+mf.ebfarm.com.
+www.frenchculturenow.com.
+a6.sphotos.ak.fbcdn.net.
+mail.duxpond.com.
+connect.facebook.net.
+www.animationconnection.com.
+videos.flv2.redtubefiles.com.
+104.30.148.190.in-addr.arpa.
+fbcdn-profile-a.akamaihd.net.
+www.lamborghini-energy.com.
+170.165.40.177.in-addr.arpa.
+youtube.com.
+dc.tvteam.info.
+a.root-servers.net.
+93.11.143.188.in-addr.arpa.
+ujktmlmbmj.tv.
+blu0-omc4-s35.blu0.hotmail.com.
+pubads.g.doubleclick.net.
+c.live.com.
+137.126.17.177.in-addr.arpa.
+taosbooks.com.
+prov.us.mydlink.com.
+pop3.live.com.
+static.ak.fbcdn.net.
+www.elephanttube.com.
+www.contracorriente.eu.
+97.240.114.186.in-addr.arpa.
+ilovemiamispice.com.
+0.162.198.187.in-addr.arpa.
+www.1st-milkshake-n-smoothie-recipes.com.
+39.204.189.12.in-addr.arpa.
+mailbox.rudebecks.se.
+maps.gstatic.com.
+safelistmailbox.net.
+ratings-wrs.symantec.com.
+t.co.
+connect.facebook.net.
+17.63.169.88.in-addr.arpa.
+bjsjzf.en.alibaba.com.
+allanjwilkinson.co.uk.
+www.youtube.com.
+a.root-servers.net.
+row.bc.yahoo.com.
+photos-f.ak.fbcdn.net.
+photos-e.ak.fbcdn.net.
+www.hennieviljoensafaris.com.
+127.19.224.77.in-addr.arpa.
+fbcdn-profile-a.akamaihd.net.
+a.root-servers.net.
+178.31.55.186.in-addr.arpa.
+casa-de-patinhos.blogspot.com.
+pagead2.googlesyndication.com.
+pixel.facebook.com.
+photos-h.ak.fbcdn.net.
+197.158.142.189.in-addr.arpa.
+www.usafed.org.
+www.bbc.co.uk.
+community.ebay.com.
+217.198.34.189.in-addr.arpa.
+s0.2mdn.net.
+68.194.98.99.in-addr.arpa.
+alt4.gmail-smtp-in.l.google.com.
+s7.addthis.com.
+agora-gallery.com.s8b1.psmtp.com.
+orcart.facebook.com.
+js2.wlxrs.com.
+photos-a.ak.fbcdn.net.
+www.endsmugenmexico.com.
+a7.sphotos.ak.fbcdn.net.
+236.150.17.213.in-addr.arpa.
+h.live.com.nsatc.net.
+a.root-servers.net.
+static.onemodelplace.com.
+sanalofis.net.
+a.root-servers.net.
+180.130.155.184.in-addr.arpa.
+www.talkfast.com.br.
+a.root-servers.net.
+support.google.com.
+summitfx.com.
+killallhippies.ru.
+lawstlouis.com.
+db._dns-sd._udp.0.1.168.192.in-addr.arpa.
+142.132.8.90.in-addr.arpa.
+csl99f4ht.t60z1i1g.
+l.yimg.com.
+css.wlxrs.com.
+afontive.fileave.com.
+translate.google.com.
+ads.adap.tv.
+174.44.235.88.in-addr.arpa.
+orienta.universia.net.mx.
+sp.cwfservice.net.
+groups.google.com.mx.
+photos-c.ak.fbcdn.net.
+mail.redhillnetworks.com.
+dbg400.homeip.net.
+accounts.google.com.
+eltrajeyelmundo.files.wordpress.com.
+www.vercapitulo.com.
+216.228.122.187.in-addr.arpa.
+dc504.4shared.com.
+terabitwarez.net.
+www.google.com.
+97.57.123.200.in-addr.arpa.
+maps.l.google.com.
+lehuaorchids.com.
+www.crit-iq.com.au.
+a8.sphotos.ak.fbcdn.net.
+20.94.253.88.in-addr.arpa.
+static.ak.fbcdn.net.
+mail.1991.ru.
+www.btparadise.com.
+a1.sphotos.ak.fbcdn.net.
+m.addthisedge.com.
+61.7.188.189.in-addr.arpa.
+xhcdn.com.
+0-ji-w.channel.facebook.com.
+21.133.124.190.in-addr.arpa.
+t2.gstatic.com.
+developers.facebook.com.
+i1.ytimg.com.
+h.live.com.
+s0.2mdn.net.
+p.l.qq.com.
+accounts.google.com.
+msfs.nspmotion.com.
+r._dns-sd._udp.0.160.168.192.in-addr.arpa.
+safebrowsing-cache.google.com.
+a323.yahoofs.com.
+static.ak.fbcdn.net.
+download343.avast.com.
+time.stdtime.gov.tw.
+65.250.132.189.in-addr.arpa.
+akcontent.ebuddy.com.
+www.findingmyforest.org.
+204.244.189.190.in-addr.arpa.
+ksn2-12.kaspersky-labs.com.
+kendallharmon.net.
+www.angrybird.biz.
+barclayproducts.com.
+calculatusemisiones.com.
+255.218.26.98.in-addr.arpa.
+tc26.easythumbhost.com.
+req1.appads.com.
+74.80.225.190.in-addr.arpa.
+db._dns-sd._udp.lan.
+t0.gstatic.com.
+a.root-servers.net.
+plus.google.com.
+ru-promo.ru.
+ixlbp78k3.99tb.
+182.95.92.186.in-addr.arpa.
+exchange.alacare.com.
+img2.blogblog.com.
+liveupdate.symantecliveupdate.com.
+a.root-servers.net.
+photos-h.ak.fbcdn.net.
+ecologiasomosnaturaleza.blogspot.com.
+40.104.214.189.in-addr.arpa.
+28.253.34.174.in-addr.arpa.
+seeklogo.com.
+186.66.178.190.in-addr.arpa.
+ad57.feeldmc.com.
+sites.google.com.
+stamps.shop.ebay.com.
+www.outstandingnudes.com.
+fmcicesports.com.s5a1.psmtp.com.
+72.110.110.201.in-addr.arpa.
+post.andertons.co.uk.
+146.27.242.201.in-addr.arpa.
+2.54.200.91.in-addr.arpa.
+baymsg1010710.gateway.messenger.live.com.
+www.hardcoreposts.com.
+rdh-env.com.inbound15.mxlogicmx.net.
+mail.assets-school.net.
+renewconcrete.org.
+_935_41_1.
+www.4shared.com.
+photos-e.ak.fbcdn.net.
+idleaire.com.s9a1.psmtp.com.
+154.30.216.89.in-addr.arpa.
+static.ak.fbcdn.net.
+static.ak.fbcdn.net.
+gostore.3g.cn.
+www.elosopanda.com.
+135.228.132.190.in-addr.arpa.
+www.patagoniavirgin.com.
+rreloj.files.wordpress.com.
+www.scribd.com.
+photos-f.ak.fbcdn.net.
+profile.ak.fbcdn.net.
+.
+mx.easynet.nl.
+www.google.com.
+www.coedsneedcashlive.com.
+g.ceipmsn.com.
+maxwells.co.uk.
+tl.answers.com.
+252.216.103.190.in-addr.arpa.
+0-jj-w.channel.facebook.com.
+139.189.160.187.in-addr.arpa.
+230.225.82.71.in-addr.arpa.
+dbz-los-rivales-mas-poderosos-cooler1.blogspot.com.
+csi.gstatic.com.
+7b7e9eaa.allanalpass.com.
+dns.msftncsi.com.
+googleads.g.doubleclick.net.
+voipb.sip.yahoo.com.
+www.fonttester.com.
+static.ak.connect.facebook.com.
+a.root-servers.net.
+157.159.53.83.in-addr.arpa.
+pixel.facebook.com.
+time.windows.com.
+a1.sphotos.ak.fbcdn.net.
+photos-h.ak.fbcdn.net.
+stats.wordpress.com.
+blog.tv2.dk.
+photos-f.ak.fbcdn.net.
+sn2files.storage.msn.com.
+content.yieldmanager.edgesuite.net.
+euro.mediotiempo.com.
+www.milftits.net.
+subtitledmusic.blogspot.com.
+sp.ask.com.
+i.dailymail.co.uk.
+matefinacierab1.galeon.com.
+jcjdatacomm.co.uk.
+marbelle.ru.
+photos-e.ak.fbcdn.net.
+grandhotelrodina.ru.
+jred.co.
+www.update.microsoft.com.
+vcs1.msg.yahoo.com.
+a.root-servers.net.
+pdgraphic.com.
+address.yahoo.com.
+au.answers.yahoo.com.
+time-b.nist.gov.
+tracker.bittorrent.am.
+netype.com.
+110.101.212.201.in-addr.arpa.
+a.root-servers.net.
+53.93.156.187.in-addr.arpa.
+a.root-servers.net.
+www.taringa.net.
+a2.sphotos.ak.fbcdn.net.
+thebarongroup.com.
+mercurymetalcraft.com.
+65.3.224.186.in-addr.arpa.
+mail.live.com.
+photos-g.ak.fbcdn.net.
+developers.facebook.com.
+a5.sphotos.ak.fbcdn.net.
+en.wikipedia.org.
+cdn.wibiya.com.
+bmx.com.
+a.root-servers.net.
+a.root-servers.net.
+appldnld.apple.com.
+224.1.200.94.in-addr.arpa.
+master3342.servehttp.com.
+_543_45_8.
+79.215.141.190.in-addr.arpa.
+dynamicdialogs.toolbar.conduit-services.com.
+zoomer2.hc1.ca.
+placidayeye.blogia.com.
+t3.gstatic.com.
+cdn-colo-ch-10.mbt.com.
+pixel.facebook.com.
+jobs.topusajobs.com.
+_840_95_5.
+www.simoniddol.com.
+default01.static.socialpointgames.com.
+softdl2.360.cn.
+a.root-servers.net.
+193.120.108.186.in-addr.arpa.
+i.ytimg.com.
+www.pspublicidad.com.
+40.209.54.189.in-addr.arpa.
+log.opentracker.net.
+www.chistesbuenos.com.mx.
+www.microsoft.com.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+gpcom.com.mx2.gpcom.rcimx.net.
+www.bikeland.ru.
+translate.google.com.mx.
+teredo.ipv6.microsoft.com.
+localhost.
+photos-e.ak.fbcdn.net.
+ts.videosz.com.
+butlerrubin.com.inbound10.mxlogicmx.net.
+mx10.activator.com.
+wsh.gamib.com.
+a.root-servers.net.
+images8.sextubestore.com.
+ulearngolf.com.
+old.aliste.info.
+cdn.g.promosrv.com.
+www.amazingbridalshowers.com.
+www.facebook.com.
+photos-f.ak.fbcdn.net.
+y1hm6bqc:.v26o0y7v.
+profile.ak.fbcdn.net.
+twitter.com.
+kerosin13.ru.
+p08-caldav.icloud.com.akadns.net.
+translate.google.es.
+disqus.com.
+44.212.230.190.in-addr.arpa.
+es-es.facebook.com.
+www.luisxl.com.
+cloud-q.duba.net.
+a1.sphotos.ak.fbcdn.net.
+apps.facebook.com.
+data.coremetrics.com.
+apis.google.com.
+platform.ak.fbcdn.net.
+www.cichlidforums.com.
+cdn.wsi.com.c.footprint.net.
+photos-a.ak.fbcdn.net.
+78.236.87.95.in-addr.arpa.
+rochellegirl.polyvore.com.
+benta.spb.ru.
+ic.tynt.com.
+www.premier-tools.com.
+joomla16.siteground.com.
+www.textsrv.com.
+i.imwx.com.
+pixel.facebook.com.
+lh3.googleusercontent.com.
+88.188.134.187.in-addr.arpa.
+u21.eset.com.
+17.27.33.90.in-addr.arpa.
+spaces.live.com.
+innotec.ru.
+accountservices.msn.com.
+h4kurd.com.
+a.root-servers.net.
+www.tracert.org.
+al-ramady.com.
+www.john-cena.net.
+ksn1-11-part1.kaspersky-labs.com.
+mail.safali.ru.
+cookex.amp.yahoo.com.
+hawaiiusafcu.com.inbound10.mxlogicmx.net.
+profile.live.com.
+134.235.76.178.in-addr.arpa.
+omega-press.ru.
+unicam-studio.ru.
+e-ternaltreasures.com.
+photos-g.ak.fbcdn.net.
+avatarthelastairbenderonline.com.
+wgtot45.digitalriver.com.
+m.addthisedge.com.
+mx.westbrook-village.com.
+bs.serving-sys.com.
+166.4.106.186.in-addr.arpa.
+15.53.193.187.in-addr.arpa.
+clients1.google.com.
+thomas-hardye.dorset.sch.uk.
+photos-e.ak.fbcdn.net.
+ns1.yandex.net.
+cn1.redswoosh.akadns.net.
+220.186.138.201.in-addr.arpa.
+mail.indiatravel.ru.
+www.taskforceapp.com.
+picture.cdn.pixmac.com.
+blufiles.storage.msn.com.
+107.49.87.62.in-addr.arpa.
+safebrowsing-cache.google.com.
+dns.msftncsi.com.
+www.juegosdiarios.com.
+mail.ibew110.org.
+altresactivitatsproductives.blogspot.com.
+28.8.16.190.in-addr.arpa.
+113.24.115.187.in-addr.arpa.
+www.google-analytics.com.
+www.google-analytics.com.
+157.181.173.201.in-addr.arpa.
+www.ioha.fgv.br.
+mgs17.acecounter.com.
+c.iogous.com.
+dr._dns-sd._udp.lan.
+132.33.86.186.in-addr.arpa.
+platform.twitter.com.
+143.244.84.200.in-addr.arpa.
+imap.gmail.com.
+venus.grires.com.
+214.3.62.186.in-addr.arpa.
+zh-cn.facebook.com.
+dns.msftncsi.com.
+126.17.254.8.in-addr.arpa.
+www.google.com.
+www.googleadservices.com.
+8-courier.push.apple.com.
+ajax.googleapis.com.
+195.233.160.190.in-addr.arpa.
+americapgroup.com.
+ads2.msads.net.
+misc.blogsmith.aol.com.aol.akadns.net.
+c7.zedo.com.
+airgchatinfo.blogspot.com.
+a.root-servers.net.
+readinglessons.com.
+www.facebook.com.
+pics03.adooscore.com.
+ib.adnxs.com.
+empleos-temporarios.vivavisos.com.ar.
+yahll.com.
+clients1.google.com.
+iz:hnafgl.q71e7o2c.
+a.root-servers.net.
+wsl.cotas.com.
+13.120.105.190.in-addr.arpa.
+rsntqiqbhykc.net.
+rexee-11.vo.llnwd.net.
+profile.spb.ru.
+mail.google.com.
+www.chinabusinessworld.com.
+profile.ak.fbcdn.net.
+m.facebook.com.
+rssocapps.rosettastone.com.
+225.186.234.190.in-addr.arpa.
+www.google-analytics.com.
+upgrade.bitdefender.com.
+244.231.35.189.in-addr.arpa.
+a.root-servers.net.
+197.17.5.88.in-addr.arpa.
+a569.g.akamai.net.
+watermill.com.inbound10.mxlogic.net.
+talewis.com.
+sepetibatecon.com.br.
+manaranews1.blogspot.com.
+av.vimeo.com.
+sites.google.com.
+51.213.51.201.in-addr.arpa.
+_517_23_8.
+r.openx.net.
+fbogsecendrrr.mp.
+s.youtube.com.
+131.92.158.189.in-addr.arpa.
+static.ak.fbcdn.net.
+www.macizorras.com.
+developers.facebook.com.
+graphicbook.com.
+www.todaycal.com.
+ravefeca.tv.
+www.facebook.com.
+lacataratadelsanisidoro.blogspot.com.
+eluneknights.latin-foro.net.
+202.65.254.201.in-addr.arpa.
+anal-forum.com.
+js.dmtry.com.
+spam01.wiredmedium.com.
+photos-g.ak.fbcdn.net.
+nsx.np.dl.playstation.net.
+static.ak.fbcdn.net.
+4.courier-push-apple.com.akadns.net.
+digg.com.
+s-static.ak.fbcdn.net.
+217.215.228.190.in-addr.arpa.
+www.webgrafics.es.
+178.54.51.190.in-addr.arpa.
+a.root-servers.net.
+91.121.55.65.in-addr.arpa.
+plusone.google.com.
+www.gas-servei.com.
+gfx3.hotmail.com.
+www.entertoinet.com.
+google.com.
+a1.sphotos.ak.fbcdn.net.
+informika.ru.
+ns2.otys.nl.
+calearth.org.
+fr-fr.facebook.com.
+a5.sphotos.ak.fbcdn.net.
+mail.obeetee.com.
+ts04.eset.com.
+a7.sphotos.ak.fbcdn.net.
+210.104.53.186.in-addr.arpa.
+138.211.172.78.in-addr.arpa.
+infodepot.wikia.com.
+park2.dns.im.
+safebrowsing.clients.google.com.
+113.68.125.186.in-addr.arpa.
+studychacha.com.
+fbib6nsj4.06hh.
+pixel.facebook.com.
+pr.starmedia.com.
+www.greatsuccessfulpeople.com.
+weather.service.msn.com.
+86.56.171.216.in-addr.arpa.
+www.filipina88.com.
+mail.tribiq.net.
+sii.fr.
+a7.sphotos.ak.fbcdn.net.
+162.251.97.176.in-addr.arpa.
+data.flurry.com.
+ustre.am.
+rad.msn.com.
+dustbowl.wordpress.com.
+s2.youtube.com.
+146.39.31.173.in-addr.arpa.
+www.bywifi.com.
+www.facebook.com.
+www.weather.com.
+www.terra.com.
+k-soya.ru.
+mail.belfastmediagroup.com.
+www.ecomagazin.ro.
+202.175.218.186.in-addr.arpa.
+www.cwdomination.com.
+getprof.es.np.community.playstation.net.
+www.suburban.com.mx.
+csi.gstatic.com.
+www.fishjava.com.
+csi.gstatic.com.
+disneylatino.com.
+google.com.
+www.chicasgames.com.
+geoiplookup.wikimedia.org.
+dx3723.tinyurl.com.
+a.root-servers.net.
+api-secure.solvemedia.com.
+photos-e.ak.fbcdn.net.
+edge.quantserve.com.
+cheatsbysuperlegends.chatango.com.
+aa.net.
+fb-0.hidden.zynga.com.
+a2.sphotos.ak.fbcdn.net.
+eamail1.unisys.com.
+external.ak.fbcdn.net.
+tools.google.com.
+41.114.160.187.in-addr.arpa.
+125.217.34.186.in-addr.arpa.
+1.0.168.192.in-addr.arpa.
+boltax.blogspot.com.
+apps.facebook.com.
+dnl-01.geo.kaspersky.com.
+skotos.net.
+www.gstatic.com.
+srcaccess.net.s9b1.psmtp.com.
+0-292.channel.facebook.com.
+a4.sphotos.ak.fbcdn.net.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+www.infinitypublishing.com.
+goldenbow.com.
+eiastillero.blogspot.com.
+30.88.105.186.in-addr.arpa.
+mailserver.limohire.com.
+www.bestprideparades.com.
+151.37.32.189.in-addr.arpa.
+smtp.shk-group.com.
+mail.mainstreetmediainc.com.
+photarium.com.
+usyd.edu.au.
+77.73.86.67.in-addr.arpa.
+www.tango.hagaselamusica.com.
+adserving.cpxinteractive.com.
+www.facebook.com.
+242.137.124.186.in-addr.arpa.
+ssl.gstatic.com.
+www.xvideos.com.
+a.root-servers.net.
+31dlth2z2.o78o2y1i.
+pop3.hot.glbdns.microsoft.com.
+botones.blogalaxia.com.
+a2.sphotos.ak.fbcdn.net.
+126.213.217.196.in-addr.arpa.
+a749.g.akamai.net.
+www.facicons.com.
+www.facebook.com.
+adadvisor.net.
+elsurdelafrontera.blogdiario.com.
+mx1.darkorbit.bigpoint.com.
+s-static.ak.fbcdn.net.
+plusone.google.com.
+www.celebrationideasonline.com.
+3.1.168.192.in-addr.arpa.
+time.nist.gov.
+www.freshrapidlinks.com.
+249.39.236.190.in-addr.arpa.
+msbmo.com.
+204.45.158.187.in-addr.arpa.
+bayimg.com.
+snecma.ru.
+fr-fr.facebook.com.
+www.frecuenciadigital.es.
+coinworld.com.inbound15.mxlogicmx.net.
+adsfront.iminent.com.
+tcyonline.com.
+teredo.ipv6.microsoft.com.
+40.216.74.187.in-addr.arpa.
+creative.ak.fbcdn.net.
+www.rememberthemilk.com.
+jasusa.com.2.arsmtp.com.
+a.root-servers.net.
+buckshare.com.
+101.165.173.189.in-addr.arpa.
+t3.gstatic.com.
+docs.google.com.
+recursos.promocionesweb.com.
+youtube-espanol.blogspot.com.
+medkrug.ru.
+mch-pllp.com.mail8.psmtp.com.
+checkip.dyndns.com.
+45.122.155.200.in-addr.arpa.
+accounts.google.com.
+fuelingcomponents.com.pri-mx.na0104.smtproutes.com.
+external.ak.fbcdn.net.
+samhouston.army.mil.
+peregrinesolutions.com.
+_744_96_9.
+fbcdn-photos-a.akamaihd.net.
+snsgw.samsungmobile.com.
+suggestqueries.google.com.
+a1.sphotos.ak.fbcdn.net.
+69.63.250.201.in-addr.arpa.
+81.187.137.190.in-addr.arpa.
+es.wikiquote.org.
+www.kayak.com.
+dns.msftncsi.com.
+photos-g.ak.fbcdn.net.
+www.letsgosago.net.
+supersat.net.
+bellsouth.net.
+corporacionpro.com.
+apple-mobile.query.yahooapis.com.
+segment-pixel.invitemedia.com.
+profile.ak.fbcdn.net.
+203.20.190.189.in-addr.arpa.
+support.maktoob.com.
+galaxylife.digitalchocolate.com.
+host-delay.logmein-gateway.com.
+time.windows.com.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+besitosdeosopolar.blogspot.com.
+static.ak.fbcdn.net.
+lvs.com.ru.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+android.holfeld.com.
+clkads.com.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+a6.sphotos.ak.fbcdn.net.
+212.25.179.190.in-addr.arpa.
+flasuncoast.net.
+view.atdmt.com.
+secure.wlxrs.com.
+1.115.112.190.in-addr.arpa.
+212.102.45.39.in-addr.arpa.
+porokov.net.
+213.218.69.200.in-addr.arpa.
+img.imgsmail.ru.
+www.facebook.com.
+a.root-servers.net.
+_146_03_1.
+grantenguisito.nu.
+usue.ru.
+analytics.pch.com.
+correointeligente.com.
+www.1accesshost.com.
+253.219.22.186.in-addr.arpa.
+120.175.209.201.in-addr.arpa.
+torrentdealer.ath.cx.
+c0058712.cdn.cloudfiles.rackspacecloud.com.
+viroc.pt.
+www.google.com.
+master4.teamviewer.com.
+crl.microsoft.com.
+www.cupcakerecipes.com.
+m3.rvsanmiguel.com.
+support.google.com.
+na.blackberry.com.
+creative.ak.fbcdn.net.
+f4999.mail.yahoo.com.
+av.aaomembers.org.
+mail.saletour.ru.
+ksn7-12.kaspersky-labs.com.
+eross-666.hi5.com.
+pixel.invitemedia.com.
+a2.sphotos.ak.fbcdn.net.
+abitoldernow.tumblr.com.
+www.clubhaleysweet.com.
+www.portada-online.com.
+www.minhaconexao.com.br.
+addons.mozilla.org.
+silvergroup.com.
+u.zillow.com.
+www.tj-archivo.org.
+m.facebook.com.
+3.149.39.190.in-addr.arpa.
+echo7.bluehornet.com.
+a1015.g.akamai.net.
+cpl.biz.
+a.root-servers.net.
+api.twitter.com.
+clients2.google.com.
+ravtograf.ru.
+81.102.114.186.in-addr.arpa.
+pix04.revsci.net.
+inversedelirium.libsyn.com.
+_899_72_2.
+a.root-servers.net.
+cdn.bid-tag.com.
+wey.icritical.com.
+www.folkebevaegelsen.dk.
+api.conduit.com.
+external.ak.fbcdn.net.
+cdn.api.twitter.com.
+psicotecnopatas.com.
+cdn.xvideoswatch.com.
+profile.ak.fbcdn.net.
+instrumedinc.com.
+66.29.188.90.in-addr.arpa.
+www.twitter.com.
+books.google.com.
+www.sport.org.
+teredo.ipv6.microsoft.com.
+i3.ytimg.com.
+233.244.167.190.in-addr.arpa.
+160.248.156.24.in-addr.arpa.
+27.186.49.190.in-addr.arpa.
+103.59.69.190.in-addr.arpa.
+www.open-mind.vc.
+translate.google.com.
+www.google.com.
+graphicsleader.pt.
+mail1.rs-it.co.uk.
+www.verenettawarner.com.
+design-incentives.com.
+edge.quantserve.com.
+adelphia.net.
+www.gamefaqs.com.
+16.167.102.99.in-addr.arpa.
+www.horrorsquad.com.
+www.orbeezone.com.
+www.arrihanpress.com.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+106.49.232.91.in-addr.arpa.
+api-read.facebook.com.
+www.facebook.com.
+linkurywebservices-msgplus.trafficmanager.net.
+connect.facebook.net.
+illy.com.
+a5.sphotos.ak.fbcdn.net.
+d1ae3bdqlkjebx.cloudfront.net.
+fusion.google.com.
+static.ak.fbcdn.net.
+profile.ak.fbcdn.net.
+office-point.ru.
+www.lindisima.com.
+seancronanphotography.com.
+www.google.com.
+billing.sharo4ka.ru.
+122.45.78.189.in-addr.arpa.
+lafxpills.ru.dob.sibl.support-intelligence.net.
+faup.ucentral.cl.
+131.174.25.190.in-addr.arpa.
+photos-b.ak.fbcdn.net.
+167.8.55.189.in-addr.arpa.
+plus.google.com.
+102.14.124.70.in-addr.arpa.
+a.root-servers.net.
+nhansuvietnam.vn.
+creative.ak.fbcdn.net.
+155.48.172.81.in-addr.arpa.
+s0.2mdn.net.
+_424_85_9.
+230.239.104.187.in-addr.arpa.
+ceritanafsuku.co.cc.
+a7.sphotos.ak.fbcdn.net.
+www.graffititextlive.com.
+sw-rec.ru.
+pedazosdecarbono.blogspot.com.
+148.144.220.66.combined.njabl.org.
+mediadesignprogram.net.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+g0.gstatic.com.
+pagead2.googlesyndication.com.
+icompass.insightexpressai.com.
+navgw2.usxpress.com.
+www.facebook.com.
+sites.google.com.
+a.root-servers.net.
+ssl.gstatic.com.
+www.showmyweather.com.
+piedraconsupieldecebolla.blogspot.com.
+i4.ytimg.com.
+ajax.googleapis.com.
+my.igain.com.
+170.204.172.201.in-addr.arpa.
+adspaces.ero-advertising.com.
+www.angermanagementresource.com.
+video.google.com.mx.
+\(none\).
+time.nist.gov.
+47.147.220.66.in-addr.arpa.
+www.nccam.nih.gov.
+a1725.l.akamai.net.
+167.57.161.77.in-addr.arpa.
+52.42.225.189.in-addr.arpa.
+36.46.122.187.in-addr.arpa.
+81.127.47.190.in-addr.arpa.
+time-nw.nist.gov.
+twitter.com.
+c-0.19-230f4000.a260011.1518.19d1.3ea1.210.0.um5jqsq46s93587gpv5kkiqkpt.avqs.mcafee.com.
+a.root-servers.net.
+a.root-servers.net.
+www.poetas.com.
+vardy.me.
+c-0.19-a30f1081.8000081.1518.19d4.3ea1.210.0.v7f5m9tctl8k377dvvzj5bs74t.avqs.mcafee.com.
+bit.ly.
+l.yimg.com.
+www.google.com.
+9.10.168.187.in-addr.arpa.
+www.open-speech.com.
+131.100.10.200.in-addr.arpa.
+nbalakershistory.blogspot.com.
+196.78.71.190.in-addr.arpa.
+upyachka.ru.
+www.drpenafiel.com.
+_018_76_7.
+photos-c.ak.fbcdn.net.
+mfeeds.economictimes.indiatimes.com.
+profile.ak.fbcdn.net.
+www.gstatic.com.
+teamtechinc.net.s8a1.psmtp.com.
+www.facebook.com.
+photos-g.ak.fbcdn.net.
+mw2.google.com.
+ads1.msads.net.
+uk-bm.ru.
+www.4realamateurs.net.
+insider.msg.yahoo.com.
+api.tweetdeck.com.
+users.cs.fiu.edu.
+db._dns-sd._udp.0.1.168.192.in-addr.arpa.
+186.45.132.81.in-addr.arpa.
+dreamthebiggestdream.com.
+db.useful-apps.com.
+translate.googleapis.com.
+78.13.181.99.in-addr.arpa.
+a.root-servers.net.
+a2.sphotos.ak.fbcdn.net.
+rover.ebay.com.
+www.merlinbeats.com.
+161.13.34.68.in-addr.arpa.
+salmanonline.net.
+msnportal.112.2o7.net.
+api.twitter.com.
+keshmuney.com.
+secure.shared.live.com.
+ntp1.dlink.com.
+a.root-servers.net.
+smtp.mooreauto.com.
+a1.da1.akamai.net.
+152.34.204.130.in-addr.arpa.
+files.prays.webnode.es.
+syndication.traffichaus.com.
+150.234.104.186.in-addr.arpa.
+_968_82_6.
+s.youtube.com.
+www.paulstips.com.
+www.unipromo.es.
+img100.xvideos.com.
+86.109.148.46.in-addr.arpa.
+sportboats.apolloduck.com.
+www.2cutepartybags.com.au.
+ssl.gstatic.com.
+fbcdn-profile-a.akamaihd.net.
+mensfitnessmagazine.uk.intellitxt.com.
+acroipm.adobe.com.
+skv-telecom.ru.
+15.2.168.192.in-addr.arpa.
+www.facebook.com.
+caipadova.it.
+piano.net.ru.
+chavismasonry.com.
+eng.krx.co.kr.
+developers.facebook.com.
+.
+m.addthisedge.com.
+www.countrysidemag.com.
+parenthetically.blogspot.com.
+www.google.com.
+external.ak.fbcdn.net.
+apis.google.com.
+www.submarinoviagens.com.br.
+safebrowsing-cache.google.com.
+www.extremetube.com.
+a3.sphotos.ak.fbcdn.net.
+qm.net.
+253.102.141.201.in-addr.arpa.
+www.orl.ucla.edu.
+t3.gstatic.com.
+toolbar.google.com.
+smx.asurams.edu.redcondor.net.
+www.sexogratiswebcams.com.
+blacklady1.blogspot.com.
+www.pacmoore.com.
+6.98.190.189.in-addr.arpa.
+sp.cwfservice.net.
+the-order-of-cupcake.blogspot.com.
+ad.yieldmanager.com.
+static.ak.fbcdn.net.
+ksn4.kaspersky-labs.com.
+241.101.35.177.in-addr.arpa.
+a1402.w40.akamai.net.
+www.jcreport.com.
+monsters-inc-2-trailers.blogspot.com.
+ksn6-12.kaspersky-labs.com.
+99.67.135.189.in-addr.arpa.
+28.144.149.190.in-addr.arpa.
+www.gstatic.com.
+ja.wikipedia.org.
+64.230.31.190.in-addr.arpa.
+dns.msftncsi.com.
+guptaequities.com.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+www.exgftube.net.
+apple3.musicdna-interface.com.
+cyberfretbass.com.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+www.responsesource.com.
+etvdupood.b11w9m4x.
+ns.vegatele.com.
+176.202.78.94.in-addr.arpa.
+clients1.google.com.
+fb-fb-0.castle.zynga.com.
+138.138.172.190.in-addr.arpa.
+rad.msn.com.
+a.root-servers.net.
+a.root-servers.net.
+a.root-servers.net.
+www.smartcampaign.co.kr.
+www.santillanaele.com.
+www.filmaciones.unlugar.com.
+static.ak.fbcdn.net.
+email.grammarly.com.
+107.146.220.66.in-addr.arpa.
+feeds.bbci.co.uk.
+mail.irondequoit.org.
+dns.msftncsi.com.
+94.225.31.190.in-addr.arpa.
+ie9.discoverbing.com.
+mail.thesimonsgroup.net.
+mailgatensw1.fairfax.com.au.
+creative.ak.fbcdn.net.
+mail2.atlanticsales.com.
+d3lvr7yuk4uaui.cloudfront.net.
+wieson.com.
+mail.google.com.
+www.onak.cl.
+16.51.248.201.in-addr.arpa.
+nicalis.com.
+a.root-servers.net.
+o2kilie47.r49l5v8w.
+isap.sejm.gov.pl.
+lavidaessilbar.blogspot.com.
+228.169.106.220.in-addr.arpa.
+www.cruelforcedsex.com.
+104.187.81.186.in-addr.arpa.
+accounts.google.com.
+owa.macpapers.com.
+profile.ak.fbcdn.net.
+mtalk.google.com.
+cdn.api.twitter.com.
+a.root-servers.net.
+profile.ak.fbcdn.net.
+a.root-servers.net.
+hb.cloud.avg.com.
+mail.kansascommerce.com.
+creative.ak.fbcdn.net.
+85.35.68.111.in-addr.arpa.
+www.randyrun.es.
+_551_04_1.
+17.94.175.189.in-addr.arpa.
+www.tudakozo.t-com.hu.
+135.13.160.189.in-addr.arpa.
+www.ima.umn.edu.
+_378_24_3.
+99.195.240.85.in-addr.arpa.
+login.toolbar.conduit-services.com.
+themes.googleusercontent.com.
+178.237.37.178.in-addr.arpa.
+cs13464.vkontakte.ru.
+img688.imageshack.us.
+download822.avast.com.
+www.mariacamilamesa.com.
+www.facebook.com.
+shinamall.ru.
+www.medgle.es.
+cmylaw.com.
+photos-h.ak.fbcdn.net.
+julied.bsofivectteiat.tm.
+t3.gstatic.com.
+mail2.gundermann.com.
+120.47.108.85.in-addr.arpa.
+a4.sphotos.ak.fbcdn.net.
+212.161.60.213.in-addr.arpa.
+webmaster.drtuber.com.
+www.facebook.com.
+db._dns-sd._udp.0.2.168.192.in-addr.arpa.
+mail3.hunterdouglas.ru.
+pentagramas.files.wordpress.com.
+a-0.19-83096081.10033.1518.19d4.2f1c.10.0.4ntf88pba9hhdjt7vhm5spjl35.avqs.mcafee.com.
+mx.mujer.yahoo.com.
+211.44.228.76.in-addr.arpa.
+www.comicstale.com.
+m2pnaper.com.
+a1.sphotos.ak.fbcdn.net.
+mx.gbcarch.com.cust.b.hostedemail.com.
+5ngm:uvux.r33w6b0u.
+www.profantasyrodeo.com.
+google.com.
+saltymilk.com.
+mx01.filter.magicmail.co.uk.
+xfactor.spb.ru.
+southernx.ne.jp.
+60.33.53.173.in-addr.arpa.
+_934_54_9.
+chart.apis.google.com.
+www.google.com.
+www.smartthinkingbook.com.
+profile.ak.fbcdn.net.
+d.yimg.com.
+inbound.ithacah-d.com.netsolmail.net.
+w.sharethis.com.
+www.regionesartificiales.com.
+b._dns-sd._udp.lan.
+db._dns-sd._udp.lan.
+a.root-servers.net.
+fbcdn-sphotos-a.akamaihd.net.
+walmartstores.com.
+evo-tour.ru.
+160.12.48.190.in-addr.arpa.
+gradient-ltd.com.ua.
+1.0.0.223.lbl7.mailshell.net.
+150.20.227.188.in-addr.arpa.
+lildolliedaily.com.
+es.wikipedia.org.
+mail.cornerstonehealthcare.net.
+54.13.105.189.in-addr.arpa.
+143.124.133.190.in-addr.arpa.
+846-car.net.
+commonwealthtowers.com.
+bbcore.cloudapp.net.
+www.cpxadspace.com.
+profile.ak.fbcdn.net.
+www.hilltopglossy.com.
+o3lbcqq2p.55to.
+254.106.189.90.in-addr.arpa.
+www.facebook.com.
+news.gree.jp.
+mitologia4.blogspot.com.
+8.17.22.187.in-addr.arpa.
+www.adobe.com.
+view.atdmt.com.
+kviltstina.blogspot.com.
+www.bing.com.
+unicentrooccidente.com.
+joindiaspora.com.
+jordicastell.blog.terra.cl.
+www.alabanzascristianas.blogspot.com.
+smtp.ofsy.net.
+ktvbzqi7y.p47a4h3n.
+clima.msn.com.
+img.quemensajes.com.
+demilovato-argentina.blogspot.com.
+plusone.google.com.
+dn-serv.com.
+sp.cwfservice.net.
+31.166.185.190.in-addr.arpa.
+img2.blogblog.com.
+external.ak.fbcdn.net.
+r._dns-sd._udp.0.2.168.192.in-addr.arpa.
+luisenriquemusic.com.
+hits.e.cl.
+api.twitter.com.
+www.myhottube.com.
+dr._dns-sd._udp.lan.
+i1.ytimg.com.
+www.solidnijistota.cz.
+accounts.google.com.
+a1028.g.akamai.net.
+smtp1.spameater.net.
+sip.ipvideotalk.com.
+194.43.165.178.in-addr.arpa.
+www.almitra.com.
+www.911truth.org.
+heartbeat.belkin.com.
+en-us.fxfeeds.mozilla.com.
+4.bp.blogspot.com.
+google.com.
+a2.sphotos.ak.fbcdn.net.
+mekcztylfg.net.
+sites.google.com.
+215.114.141.201.in-addr.arpa.
+photos-a.ak.fbcdn.net.
+www.180south.com.
+s135.cnzz.com.
+profile.ak.fbcdn.net.
+153.144.220.121.in-addr.arpa.
+210.25.249.199.in-addr.arpa.
+interlinq.com.
+a2.sphotos.ak.fbcdn.net.
+sites.google.com.
+eizij:z93.r41x1t6h.
+ingdirect.com.au.
+fp.enter.net.
+94.118.255.201.in-addr.arpa.
+65.177.29.201.in-addr.arpa.
+rs712l34.rapidshare.com.
+www.facebook.com.
+dr._dns-sd._udp.0.2.0.10.in-addr.arpa.
+155.212.130.190.in-addr.arpa.
+mt1.google.com.
+creative.ak.fbcdn.net.
+_792_76_7.
+i3.ytimg.com.
+4pz7:un2w.x56k4m7i.
+www.businesslist.sg.
+67.152.213.201.in-addr.arpa.
+it-it.facebook.com.
+1.0.0.127.dnsbugtest.1.0.0.127.in-addr.arpa.
+ecaustria.at.
+secure.wlxrs.com.
+erols.com.
+deanfoods.com.s8a2.psmtp.com.
+mail.jhb.wbs.co.za.
+www.google.com.
+www.fabricwarehouse.co.uk.
+mx1.task.com.br.
+www.bijuegos.com.
+pdf.dirale.com.
+www.belkin.com.
+dvdp3eqjh.57we.
+tap2-cdn.rubiconproject.com.
+fbcdn-photos-a.akamaihd.net.
+_061_57_3.
+www.trucoteca.com.
+i3.ytimg.com.
+a.root-servers.net.
+laposada.rockresorts.com.
+59.64.64.1.in-addr.arpa.
+45.112.168.192.in-addr.arpa.
+xylon.asfh-berlin.de.
+45.122.172.201.in-addr.arpa.
+login.live.com.
+121.189.231.125.in-addr.arpa.
+115.43.170.189.in-addr.arpa.
+mailsrv11.hartrodt.com.
+chromejs.s3.amazonaws.com.
+matcher.bidder8.mookie1.com.
+86.19.251.189.in-addr.arpa.
+16.147.102.220.in-addr.arpa.
+a8.sphotos.ak.fbcdn.net.
+fo-eu-ec.ay1.b.yahoodns.net.
+apir.webrep.avast.com.
+hooping.net.
+www.google-analytics.com.
+www.philips.pl.
+103.253.40.92.in-addr.arpa.
+www.google.com.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+mediacdn.disqus.com.
+128.48.8.88.in-addr.arpa.
+www.google-analytics.com.
+yours.com.
+www.facebook.com.
+o1.t26.net.
+photos-g.ak.fbcdn.net.
+911.talk4free.com.
+news.google.com.mx.
+ksn3-12.part1.kaspersky-labs.com.
+log.goodnetads.org.lan.
+netspape.net.
+michaelkors.com.
+primaryfocalpoints.net.
+www.savspeed.co.za.
+www.davidsbridal.ca.
+www.granpick.com.
+news.google.com.
+mail.nbzs.com.
+mail.flappellatelaw.com.
+dailydujour.com.
+caracolasfem.blogspot.com.
+94.119.239.189.in-addr.arpa.
+evsecure-ocsp.geotrust.com.
+mail.trepel.com.
+17.43.85.186.in-addr.arpa.
+mail.imrtest.com.
+a2.sphotos.ak.fbcdn.net.
+a1.sphotos.ak.fbcdn.net.
+ssl.gstatic.com.
+153.156.6.210.in-addr.arpa.
+static.exoclick.com.
+chicago.cubs.mlb.com.
+www.mineralweb.com.
+17.213.178.190.in-addr.arpa.
+a.root-servers.net.
+www.google.com.
+photos-b.ak.fbcdn.net.
+a.root-servers.net.
+imagesrv.adition.com.
+27-courier.push.apple.com.
+proxy-55.dailymotion.com.
+img25.imageshack.us.
+conseilsdeco.net.
+voipc.sip.yahoo.com.
+www.google.com.
+a2.sphotos.ak.fbcdn.net.
+ad.yieldmanager.com.
+iphone-wu.apple.com.
+secure-uk.imrworldwide.com.
+photos-b.ak.fbcdn.net.
+photos-e.ak.fbcdn.net.
+a.root-servers.net.
+static.exoclick.com.
+alerts.conduit-services.com.
+hawthornfarm.wanadoo.co.uk.
+mail.cascpa.net.
+clock.fmt.he.net.
+alajmy.com.
+www.guitarjapan.com.
+www.google.com.
+external.ak.fbcdn.net.
+vicioadictos.blogspot.com.
+netzdero.com.
+emob1089.photobucket.com.
+sentence-extractor.googlecode.com.
+dsjlondon.com.
+thebranfordgroup.com.s8b1.psmtp.com.
+a2.sphotos.ak.fbcdn.net.
+b-0.19-270e9219.b1081.1518.19d4.3ea1.210.0.9win1zdcdhpc8qvz14k5gi6l5v.avqs.mcafee.com.
+registration.ess.apple.com.akadns.net.
+a5.sphotos.ak.fbcdn.net.
+col.stb01.s-msn.com.
+photos-a.ak.fbcdn.net.
+www.facebook.com.
+227.89.208.82.in-addr.arpa.
+www.energydelta.org.
+a.root-servers.net.
+133.86.22.201.in-addr.arpa.
+www.spermbankcalifornia.com.
+cs.wikipedia.org.
+clkads.com.
+www.histats.com.
+a7.sphotos.ak.fbcdn.net.
+pixel.facebook.com.
+spicnic.com.
+s10.flagcounter.com.
+114.216.191.186.in-addr.arpa.
+bs2.yokacdn.com.
+accounts.google.com.
+406.cim.meebo.com.
+kkpfaq.bay.livefilestore.com.
+omnipure.com.
+millercenter.org.
+155.219.192.173.in-addr.arpa.
+multi21.thumb.edenflirt.com.
+125.116.204.190.in-addr.arpa.
+y2le2vcbd.y77z1m5m.
+antiguaguatemata.olx.com.gt.
+seq.es.
+www.google.com.
+safebrowsing-cache.google.com.
+plus.google.com.
+www.apple.com.
+concert-casse.de.
+voipb.sip.yahoo.com.
+4.218.15.189.in-addr.arpa.
+studiemetro.au.dk.
+www.linodriegheart.com.
+www.opselect.com.
+136.7.104.187.in-addr.arpa.
+r.mzstatic.com.
+mx.risotech.com.
+a2.sphotos.ak.fbcdn.net.
+underhile.blogspot.com.
+a.root-servers.net.
+socialsciences.uchicago.edu.
+jers2.info.
+foianasnoiansoim.blogspot.com.
+mail.fgisp.com.
+night-at-the-museum-3-trailer.blogspot.com.
+unarespuestaparacadapregunta.blogspot.com.
+www.cenetec.salud.gob.mx.
+a4.sphotos.ak.fbcdn.net.
+fxfeeds.mozilla.com.
+instagramers.com.
+smtp01.usccg.com.
+email-thewhitecompany.com.
+hotmail.com.
+profile.ak.fbcdn.net.
+about.tagged.com.
+forums.imore.com.
+176.0.195.108.in-addr.arpa.
+dns.msftncsi.com.
+favorites.live.com.
+idolbloglive.com.
+time.nist.gov.
+echo.edge.messenger.live.com.
+benbarnesfansite.blogspot.com.
+www.yumyume.com.
+google.com.
+duluxaddingcolourtopeopleslives.ru.
+sefora.b-rail.be.
+aka-cdn-ns.adtechus.com.
+photos-c.ak.fbcdn.net.
+www.bywifi.com.
+www.blogmktg.com.
+a.root-servers.net.
+mail-attachment.googleusercontent.com.
+friends.spy-from-sky.com.
+249.114.137.201.in-addr.arpa.
+66.197.168.192.in-addr.arpa.
+www.automoto.com.sv.
+www.investoronline.info.
+pruebas.amman.cervantes.es.
+sp.cwfservice.net.
+a.root-servers.net.
+nubuk.info.
+photos.merinews.com.
+90.64.50.182.in-addr.arpa.
+a.root-servers.net.
+lb._dns-sd._udp.belkin.
+www.sunrainly.com.
+unikomerc.ba.
+google.com.
+www.youtube.com.
+a.root-servers.net.
+partner.googleadservices.com.
+212.63.0.186.in-addr.arpa.
+surferbear.net.
+resolver4.pand.ctmail.com.
+18.133.159.201.in-addr.arpa.
+a.root-servers.net.
+a2.sphotos.ak.fbcdn.net.
+226.38.13.88.in-addr.arpa.
+yahoo.com.
+mail.dellen.com.
+221.90.113.186.in-addr.arpa.
+u.ytbbs.com.
+a.root-servers.net.
+teredo.ipv6.microsoft.com.
+67.113.174.109.in-addr.arpa.
+m.addthisedge.com.
+www.facebook.com.
+maygurney.co.uk.
+musicaclaro.com.
+www34.zippyshare.com.
+b._dns-sd._udp.0.1.168.192.in-addr.arpa.
+belindalove.com.
+www.mentalhealthy.co.uk.
+79.8.162.190.in-addr.arpa.
+ofmtrx381.20zs.
+www.microsoft.com.
+37.26.52.186.in-addr.arpa.
+cdn.krxd.net.
+www.packerchatters.com.
+demo.chevereto.com.
+i.imgur.com.
+m.addthisedge.com.
+ad-g.doubleclick.net.
+a.prisacom.com.
+rlcallahan.com.
+js.wlxrs.com.
+millerfh.com.
+f-passage.net.ru.lan.
+88.114.134.187.in-addr.arpa.
+14.65.146.187.in-addr.arpa.
+pbmnutritionals.com.s7b1.psmtp.com.
+mothernature.com.
+get.adobe.com.
+c.bing.com.
+www.facebook.com.
+107.113.51.190.in-addr.arpa.
+fxfeeds.mozilla.com.
+www.tenso.es.
+earthtech.co.uk.
+85.247.75.151.in-addr.arpa.
+photos-f.ak.fbcdn.net.
+martinlibre.blogspot.com.
+210.176.250.190.in-addr.arpa.
+searchjs.s3.amazonaws.com.
+_120_46_5.
+bow.juegosfriv.us.
+_339_43_1.
+www.falomirjuegos.com.
+pato.ienter.net.
+lion-t.ru.
+www.facebook.com.
+www.escueladepadresprimerizos.com.
+www.subcarrie.com.
+weather.wapp.wii.com.
+time.windows.com.
+s-static.ak.facebook.com.
+104.75.176.190.in-addr.arpa.
+rv.ginyas.com.
+www.google.com.
+www.facebook.com.
+oceanparadise.com.
+168.179.50.190.in-addr.arpa.
+fbcdn-profile-a.akamaihd.net.
+ejabat.google.com.
+ax.init.itunes.apple.com.
+photos-f.ak.fbcdn.net.
+jacobsons.com.
+www.dentaldeml.com.
+fromportlandtopeonies.blogspot.com.
+redirector.c.youtube.com.
+129.50.168.192.in-addr.arpa.
+a4.sphotos.ak.fbcdn.net.
+p6y.ru.
+elfish-and-chips.learnenglishonline.yuku.com.
+ssl.gstatic.com.
+rss.news.yahoo.com.
+b._dns-sd._udp.0.1.168.192.in-addr.arpa.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+mf1.bestbuy.selectionassistant.com.
+a.root-servers.net.
+a.root-servers.net.
+www.ipodnews.com.ar.
+profile.ak.fbcdn.net.
+www.provisum-illumina.com.
+microsoftwllivemkt.112.2o7.net.
+www.google-analytics.com.
+static.ak.fbcdn.net.
+www.aspoonfulofsugardesigns.com.
+a4.sphotos.ak.fbcdn.net.
+www.facebook.com.
+ie9cvlist.ie.microsoft.com.
+sp.cwfservice.net.
+c1.researchgate.net.
+webassets.sparkybee.com.
+ua.bname.ru.
+38.34.48.190.in-addr.arpa.
+a3.sphotos.ak.fbcdn.net.
+a1132.da1.akamai.net.
+233.241.88.2.in-addr.arpa.
+s-static.ak.fbcdn.net.
+147.197.165.190.in-addr.arpa.
+_362_64_1.
+www.ashidakim.com.
+teredo.ipv6.microsoft.com.
+www.megghy.com.
+:as3fwc5v.00zn.
+175.216.60.213.in-addr.arpa.
+122.124.179.190.in-addr.arpa.
+a.root-servers.net.
+clipfish.de.
+carmenmarques.blogspot.com.
+36.60.5.187.in-addr.arpa.
+j35i1w8gj.j19t9k7s.
+a.root-servers.net.
+19.77.228.67.in-addr.arpa.
+translateru.livejournal.com.
+sidewinder.makedesignnotwar.com.
+mm.admob.com.
+elpormsabb.tm.
+lefcobank.ru.
+www.starpirates.net.
+css.lainformacionalsegundo.com.
+otmail.com.
+oligoi.com.
+204.70.93.186.in-addr.arpa.
+dark-neo.cc.
+windows.microsoft.com.
+a2.sphotos.ak.fbcdn.net.
+197.16.18.186.in-addr.arpa.
+player.gametreat.com.
+www.update.microsoft.com.
+s-static.ak.facebook.com.
+www.trailertrashwhores.com.
+db._dns-sd._udp.lan.
+isatap.home.
+www.facebook.com.
+i2.ytimg.com.
+mail.netscape.everyone.net.
+hpinnigleek.polyvore.com.
+birdman.seriespepito.com.
+www.google.com.
+38-courier.push.apple.com.
+moritz.si.
+www.caepe.org.ar.
+photos-a.ak.fbcdn.net.
+214.18.168.192.in-addr.arpa.
+www.aurn.com.
+a.root-servers.net.
+deweysquare.com.s200b2.psmtp.com.
+ksn5-12.kaspersky-labs.com.
+teredo.ipv6.microsoft.com.
+crl.globalsign.net.
+static.ak.fbcdn.net.
+124.44.59.85.in-addr.arpa.
+www.google.com.
+cert-commerce.zune.net.
+idcindia.com.s7a2.psmtp.com.
+145.244.193.187.in-addr.arpa.
+mscrl.microsoft.com.
+photos-d.ak.fbcdn.net.
+www.mlfnt.com.
+wpad.
+_431_27_2.
+a3.sphotos.ak.fbcdn.net.
+vis.stanford.edu.
+ecpics.hardsextube.com.
+static.slide.com.
+124.54.209.190.in-addr.arpa.
+c2h1-roc.smtp.bti.net.ph.
+www.jmydm.com.
+pixel.facebook.com.
+mypacks.net.
+thethingsgirlslove.tumblr.com.
+spamhunter.attend.jp.
+m.facebook.com.
+246.54.42.201.in-addr.arpa.
+69.161.253.190.in-addr.arpa.
+us.data.toolbar.yahoo.com.
+a8.sphotos.ak.fbcdn.net.
+weather.services.conduit.com.
+time.chttl.com.tw.
+ro.wikipedia.org.
+americasbestlending.com.
+rsoserv.ru.
+www.google.com.
+a.root-servers.net.
+15.149.220.66.in-addr.arpa.
+a.root-servers.net.
+ec.atdmt.com.
+saabplus.ru.
+lead2net.net.
+coll.ning.com.
+www.nintendowifi.com.
+sgsp02.jvc-asia.com.sg.
+www.idiomaydeporte.com.
+tourshow.ru.
+qnkwpkntu.44dl.
+apis.google.com.
+193.67.139.190.in-addr.arpa.
+apps.facebook.com.
+es.dilandau.eu.
+www.weightlosseasytoday.com.
+90.210.160.201.in-addr.arpa.
+cdn-http.audio-bible.api.youversion.com.
+www.facebook.com.
+barbie-doll.programas-gratis.net.
+htri.net.s9a2.psmtp.com.
+googleads.g.doubleclick.net.
+plusone.google.com.
+a1.sphotos.ak.fbcdn.net.
+link.camelino.ca.
+www.facebook.com.
+8.130.194.190.in-addr.arpa.
+139.120.204.186.in-addr.arpa.
+accounts.google.com.
+st1.helpmycash.net.
+certifier.ru.
+translate.googleapis.com.
+83.235.177.190.in-addr.arpa.
+time-a.nist.gov.
+www.youtube.com.
+medexfol-online.ru.
+tatoogallery.info.
+i1.ytimg.com.
+215.221.139.216.zen.spamhaus.org.
+www.scootertechno.com.
+s0.2mdn.net.
+204.190.54.65.sbl-xbl.spamhaus.org.
+e-2dj6wdmigocjiho.stats.esomniture.com.
+120.145.170.201.in-addr.arpa.
+unpunto.com.
+dns.msftncsi.com.
+29.79.191.67.in-addr.arpa.
+209.157.121.200.in-addr.arpa.
+photos-f.ak.fbcdn.net.
+ds.serving-sys.com.
+tnb3.4gayfetish.com.
+spktech.ru.
+platform.ak.fbcdn.net.
+2.bp.blogspot.com.
+csi.gstatic.com.
+eerie-cuties-italian.blogspot.com.
+44.13.148.189.in-addr.arpa.
+thetruthbehindthescenes.files.wordpress.com.
+www.celebrityhousepictures.com.
+169.57.237.204.in-addr.arpa.
+cdn3.picadmedia.com.
+static.genericlink.com.
+games.yahoo.com.
+a8.sphotos.ak.fbcdn.net.
+gravityjack.com.
+static.ak.fbcdn.net.
+platform.twitter.com.
+d15gt9gwxw5wu0.cloudfront.net.
+www.gstatic.com.
+a4.sphotos.ak.fbcdn.net.
+www.youtube.com.
+www.youtube.com.
+10.148.204.187.in-addr.arpa.
+ntp.glb.nist.gov.
+theshowguide.co.uk.
+223.243.35.189.in-addr.arpa.
+manfredi.ru.
+mail.mepc-consultants.com.
+static.ak.fbcdn.net.
+quatrx.com.
+profile.ak.fbcdn.net.
+2leep.com.
+www.pulpinternational.com.
+www.searchqu.com.
+mscrl.microsoft.com.
+www.rollingcounters.com.
+albavideo.blogspot.com.
+bouislendlease.com.
+fxfeeds.mozilla.com.
+nanmckay.com.
+fbcdn-profile-a.akamaihd.net.
+www.umi.com.co.
+1.0.0.127.dnsbugtest.1.0.0.127.in-addr.arpa.
+photos-d.ak.fbcdn.net.
+211.219.103.190.in-addr.arpa.
+7072697361636f6d.313132.326f37.6e6574.80h42eb8ba6.webcfs00.com.
+a.root-servers.net.
+svali.ru.
+dnl-01.geo.kaspersky.com.
+www.google.com.
+cnfg.montiera.com.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+ksn2-12.kaspersky-labs.com.
+ax.init.itunes.apple.com.
+a1.sphotos.ak.fbcdn.net.
+safebrowsing-cache.google.com.
+www.terapia-fisica.com.
+advoconsult.com.
+117.222.26.96.in-addr.arpa.
+client5.dropbox.com.
+3d.qdq.com.
+cs.wikipedia.org.
+0-56.channel.facebook.com.
+.
+122.164.100.177.in-addr.arpa.
+csmx5.sover.net.
+lgbp.podbean.com.
+safebrowsing-cache.google.com.
+www.operacarolina.org.
+time.chttl.com.tw.
+99.2.207.186.in-addr.arpa.
+prensaciudadana.com.
+maximonline.com.s7b1.psmtp.com.
+dns.msftncsi.com.
+binupdate.mail.ru.
+denis.stalker.h3q.com.
+wsubompxa.n29p1m0j.
+9.229.118.85.in-addr.arpa.
+tvtodo.com.
+wconect.com.br.
+fonts.googleapis.com.
+11.164.132.109.in-addr.arpa.
+eu.dockers.com.
+a5.sphotos.ak.fbcdn.net.
+www.elpuertodesantamaria.es.
+a6.sphotos.ak.fbcdn.net.
+_900_39_1.
+www.coches-es.com.
+relay-logs-p-1.oxigen.net.
+4.140.177.216.in-addr.arpa.
+bs.serving-sys.com.
+delta2.tatungmx.com.
+diantzdesign.info.
+en.wikipedia.org.
+www.deltares.nl.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+a2.sphotos.ak.fbcdn.net.
+mail.santarosasells.com.
+wpad.corp.ipgnetwork.com.
+endtimespropheticwords.wordpress.com.
+kingsfurniture.co.uk.
+us.i1.yimg.com.
+gritton-com.mail.eo.outlook.com.
+174.203.39.190.in-addr.arpa.
+google.com.
+imap.gmail.com.
+lindson.com.
+www.phoenixpermaculture.org.
+pixel.facebook.com.
+245.244.28.120.in-addr.arpa.
+apps.facebook.com.
+twitter.com.
+photos-c.ak.fbcdn.net.
+167.236.174.190.in-addr.arpa.
+a7.sphotos.ak.fbcdn.net.
+c.msn.com.
+_603_12_1.
+www.youtube.com.
+db._dns-sd._udp.0.129.37.10.in-addr.arpa.
+a5.sphotos.ak.fbcdn.net.
+k7eku:l7b.e79p7f4d.
+insecta.isladejuegos.es.
+interaseo.com.co.
+amx.blueridgecarpet.com.redcondor.net.
+kissing-games.dressup.me.
+i2.ytimg.com.
+googleads.g.doubleclick.net.
+a7.sphotos.ak.fbcdn.net.
+47.181.240.216.in-addr.arpa.
+about-chinesefood.com.
+134.244.226.189.in-addr.arpa.
+buzzhunt.co.uk.
+www.facebook.com.
+s20.vuclip.com.
+af.avg.com.
+maturescreenshots.blogspot.com.
+www.googletagservices.com.
+domino.automation.rockwell.com.
+longisland.newsday.com.
+21.87.51.190.in-addr.arpa.
+whos.amung.us.
+202.82.184.201.in-addr.arpa.
+96.114.229.190.in-addr.arpa.
+alt1.gmail-smtp-in.l.google.com.
+a.root-servers.net.
+www.core-learning.com.
+samaratoday.ru.
+photos-f.ak.fbcdn.net.
+www.adobe.com.
+s4.histats.com.
+www.google.com.
+39.12.29.83.in-addr.arpa.
+agglo-lepuyenvelay.fr.
+cellbio.com.
+mail.honoe.com.
+artsyspot.disqus.com.
+www.can-global.com.
+static.ak.fbcdn.net.
+www.pickupsplus.com.
+a3.twimg.com.
+landingpages.bpcdn.net.
+go.srvnow.com.
+ntp.glb.nist.gov.
+cfh.wapp.wii.com.
+a6.sphotos.ak.fbcdn.net.
+dns.msftncsi.com.
+surfcheap.com.
+uu1.orbitdownloader.com.
+mx.zwebtech.com.
+danlent.com.
+a.root-servers.net.
+3fdzznnil.74gj.
+59.214.38.187.in-addr.arpa.
+listas.20minutos.es.
+53.38.174.189.in-addr.arpa.
+a2.da1.akamai.net.
+www.google.com.
+www.facebook.com.
+248.232.187.186.in-addr.arpa.
+103.23.84.188.in-addr.arpa.
+mx1.triera.net.
+a.root-servers.net.
+cgey.com.
+blog.coquipr.com.
+gft-us.s3.amazonaws.com.
+rs992tl5.rapidshare.com.
+m.youtube.com.
+vertvdeportes.chatango.com.
+www.googleadservices.com.
+clients1.google.com.
+63.130.171.189.in-addr.arpa.
+gallery.clickthecity.com.
+static.ak.fbcdn.net.
+138.130.52.186.in-addr.arpa.
+secure-uk.imrworldwide.com.
+tag.admeld.com.
+12.63.6.189.in-addr.arpa.
+gmail.com.
+www.pixazza.com.
+adspaces.ero-advertising.com.
+comcast.net.
+pathway.net.com.
+141.196.8.200.in-addr.arpa.
+www.tetovani66.cz.
+www.eyesskyward.com.
+www.pantiesflash.com.
+img39.ownskin.com.
+google.com.
+graph.facebook.com.
+127.51.175.187.in-addr.arpa.
+thinbrowser.net.
+my.yahoo.com.
+a.root-servers.net.
+60.126.110.87.in-addr.arpa.
+www.televisa.com.ar.
+158.110.172.187.in-addr.arpa.
+www.empresaexterior.com.
+www.luismiguelsite.com.
+mass10.massmulti.hop.clickbank.net.
+133.184.68.67.in-addr.arpa.
+45.coll.ning.com.
+ax.init.itunes.apple.com.
+audrinaxo.celebuzz.com.
+bug.report.url.
+www.nimsoft.com.
+www.alltimemedical.com.
+195.26.36.186.in-addr.arpa.
+sun.idiom.com.
+profile.ak.fbcdn.net.
+27.243.132.190.in-addr.arpa.
+www.hi.is.
+19.10.73.190.in-addr.arpa.
+productads.amazon.com.
+toc.music.metaservices.microsoft.com.
+www.google.com.
+www.tubepleasure.com.
+feedburner.google.com.
+hhgo.com.
+apps.facebook.com.
+www.carlberry.co.uk.
+tiger.apscc.nau.edu.
+103.122.32.83.in-addr.arpa.
+www.google.com.
+a7.sphotos.ak.fbcdn.net.
+a.root-servers.net.
+profile.ak.fbcdn.net.
+www.belkin.com.
+a.root-servers.net.
+a.root-servers.net.
+fogeli.co.il.
+api.webrep.avast.com.
+safebrowsing-cache.google.com.
+googleads.g.doubleclick.net.
+mx.dreambuilderspr.com.
+fr-fr.facebook.com.
+232.103.158.109.in-addr.arpa.
+25.218.72.190.in-addr.arpa.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+spam3.fpinet.net.
+safebrowsing-cache.google.com.
+110.253.206.173.in-addr.arpa.
+56.216.73.190.in-addr.arpa.
+www.imdb.com.
+yahoo.ccom.
+8.174.115.66.in-addr.arpa.
+pagead2.googlesyndication.com.
+digitalcommons.pace.edu.
+kamalballan.ru.
+212.92.159.189.in-addr.arpa.
+220.10.183.189.in-addr.arpa.
+168.61.87.186.in-addr.arpa.
+clients1.google.com.
+thedottedi.net.
+download.skype.com.
+90.92.255.190.in-addr.arpa.
+personal.de.avira-update.net.
+news.google.nl.
+webcache.googleusercontent.com.
+google.com.mx.
+a1.mzstatic.com.
+srtravel.com.
+d37saox78.s55w4m9r.
+translate.googleapis.com.
+utilestoonix.wordpress.com.
+www.rsagroup.com.ar.
+pjpur.tripod.com.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+www.treadmill-ratings-n-reviews.net.
+a5.sphotos.ak.fbcdn.net.
+col.stb00.s-msn.com.
+photos-g.ak.fbcdn.net.
+www.dasa.mod.uk.
+pixel.facebook.com.
+www.humansciences.mq.edu.au.
+9nl37njin.m42h4c9p.
+tc.v4.cache4.c.pack.google.com.
+diamondgame.com.s9a1.psmtp.com.
+fmc8jixpr.39vi.
+b.scorecardresearch.com.
+www.facebook.com.
+photos-d.ak.fbcdn.net.
+12.142.121.95.in-addr.arpa.
+67.220.49.71.in-addr.arpa.
+as.cd.impact-ad.jp.
+ksn1-11-part1.kaspersky-labs.com.
+ksn3-11.part2.kaspersky-labs.com.
+smtp.evidence.com.
+www.usrecallnews.com.
+63.112.212.201.in-addr.arpa.
+55.15.237.189.in-addr.arpa.
+231.252.24.72.in-addr.arpa.
+plusone.google.com.
+a2.sphotos.ak.fbcdn.net.
+www.bywifi.com.
+elcaballerodelaluna2.blogspot.com.
+clients1.google.com.
+dolarhoy.com.
+csi.gstatic.com.
+www.apple.com.
+web.de.
+s.ytimg.com.
+sedty.com.
+a6.sphotos.ak.fbcdn.net.
+ws.faad.co.
+86.120.189.24.in-addr.arpa.
+e3353.c.akamaiedge.net.
+www.cidra.com.
+sundogfirearms.com.
+a995.mm1.akamai.net.
+pix.speedbit.com.
+platform.linkedin.com.
+dns.msftncsi.com.
+www.diariopyme.com.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+guidosfreshmaretplace.com.
+mail.mcewancpa.com.
+a.root-servers.net.
+227.212.171.189.in-addr.arpa.
+248.216.82.200.in-addr.arpa.
+nist1-sj.ustiming.org.
+corplodging.com.2.0001.arsmtp.com.
+87.100.93.201.in-addr.arpa.
+a.root-servers.net.
+www.maximhuerta.com.
+www.gmail.google.com.
+_ldap._tcp.
+wnu.naughtyamerica.com.
+www.googleadservices.com.
+p02-mobilebackup.icloud.com.akadns.net.
+www.update.microsoft.com.
+www.kingmax.com.
+secure.shared.live.com.
+mtalk.google.com.
+i3.tagstat.com.
+mail.megasila.ru.
+www.boom.ge.
+my.bureauveritas.com.
+profile.ak.fbcdn.net.
+ess.khhq.net.
+www.diaryofstyleblog.com.
+us.tomsgames.com.
+91.68.152.81.in-addr.arpa.
+clients2.google.com.
+www.germanshepherdrescue.co.uk.
+profile.ak.fbcdn.net.
+91.253.164.85.in-addr.arpa.
+mail2.adcohvac.com.
+21.27.26.201.in-addr.arpa.
+eanes.k12.tx.us.
+164.81.135.187.in-addr.arpa.
+media.photobucket.com.
+218.224.227.61.in-addr.arpa.
+172.192.138.174.in-addr.arpa.
+243.77.7.75.in-addr.arpa.
+rad.msn.com.
+www.collegepartyhouse.com.
+apps.facebook.com.
+sad-stone.com.
+www.iwdeepblowjob.com.
+55.33.220.186.in-addr.arpa.
+a.root-servers.net.
+ca.answers.yahoo.com.
+profile.ak.fbcdn.net.
+listorbit.net.
+201.51.21.190.in-addr.arpa.
+19.246.215.201.in-addr.arpa.
+cdn.api.twitter.com.
+ausdcx64amer19.amer.dell.com.
+i3.ytimg.com.
+elpoderdelpensamientopositivo.over-blog.es.
+a8.sphotos.ak.fbcdn.net.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+invision-studios.com.
+c0013979.ssl.cf1.rackcdn.com.
+samzas.ru.
+shadow.atkingdom.com.
+corporateapartmentsinbrazil.com.
+adornatusolapa.blogspot.com.
+rock799.no-ip.biz.
+static.ak.connect.facebook.com.
+139.154.171.189.in-addr.arpa.
+time.chttl.com.tw.
+sa.bbc.com.
+220.122.146.189.in-addr.arpa.
+widgets.montiera.com.
+www.rdistore.com.
+mx.medwell.us.
+ads2.msads.net.
+creative.ak.fbcdn.net.
+i1.ytimg.com.
+mail.red-wagon.com.
+mozilla.cdn.leaseweb.com.
+search2.fcc.gov.
+intelisyscorp.com.inbound10.mxlogic.net.
+a.root-servers.net.
+englishpod.com.
+b.c-0.19-21095008.30081.1518.19d3.3ea1.410.0.rqw7f386mgq5i2vj71kkslquhj.avqs.mcafee.com.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+212.23.87.190.in-addr.arpa.
+skype.com.multi.surbl.org.
+alerts.conduit-services.com.
+www.facebook.com.
+s.ytimg.com.
+e3353.c.akamaiedge.net.
+p.twimg.com.
+time.chttl.com.tw.
+static.ak.fbcdn.net.
+www.undecimahora.org.
+www.cronistasoficiales.com.
+cid-a602674d8489e429.users.storage.live.com.
+cs10095.vk.com.
+b.scorecardresearch.com.
+i4.ytimg.com.
+www.abc.es.
+www.laprovinciadicremona.it.
+a.root-servers.net.
+store.urge.com.
+a3.sphotos.ak.fbcdn.net.
+urs.microsoft.com.
+bioguide.congress.gov.
+65.65.204.187.in-addr.arpa.
+harbingermortgage.com.
+a1.sphotos.ak.fbcdn.net.
+phx-sync552.services.mozilla.com.
+plusone.google.com.
+4105616.frasesinolvidables1.com.ar.
+plus.google.com.
+www.adidasrunningday.com.
+a0.twimg.com.
+tracker.thepiratebay.org.
+tinypets.tinyco.com.
+external.ak.fbcdn.net.
+203.96.51.190.in-addr.arpa.
+gs-loc.isg-apple.com.akadns.net.
+a3.sphotos.ak.fbcdn.net.
+instagr.am.
+thinkitsystems.net.
+nefteport.ru.
+a.root-servers.net.
+a3.twimg.com.
+elite-servers.com.ua.
+www.ps2-fate.com.
+imap-ssl.mail.yahoo.com.
+img.atwiki.jp.
+creative.ak.fbcdn.net.
+teredo.ipv6.microsoft.com.
+prada-love.tumblr.com.
+inbound.onecallcom.net.netsolmail.net.
+www.coverjunkie.com.
+www.remediar.gov.ar.
+221.150.71.93.in-addr.arpa.
+www.itescam.edu.mx.
+www.cumtobun.com.
+static.ak.fbcdn.net.
+google.com.
+es.wikipedia.org.
+.
+relay.voice.edge.messenger.live.com.
+246.202.58.186.in-addr.arpa.
+s-static.ak.facebook.com.
+151.60.104.86.in-addr.arpa.
+a.root-servers.net.
+s-static.ak.fbcdn.net.
+144.251.27.190.in-addr.arpa.
+download.windowsupdate.com.
+schomburg.ru.s200a2.psmtp.com.
+www.scanalert.com.
+a.root-servers.net.
+photos-d.ak.fbcdn.net.
+grim.bungie.org.
+photos-h.ak.fbcdn.net.
+www.kktanhp.com.
+mailserver.pacificlifegroup.com.
+199.192.176.189.in-addr.arpa.
+170.19.230.189.in-addr.arpa.
+antropologia-online.blogspot.com.
+ccbill.com.
+live-receptionist.com.
+i1118.photobucket.com.
+dipaul.ru.
+meta.charlesworks.com.
+mail.yimg.com.
+s0.2mdn.net.
+rcanoevents.com.1.0001.arsmtp.com.
+lb._dns-sd._udp.0.224.16.172.in-addr.arpa.
+shtoryizabel.ru.
+186.99.152.187.in-addr.arpa.
+thumbs1.ebaystatic.com.
+68.95.82.203.in-addr.arpa.
+a.root-servers.net.
+ntp.glb.nist.gov.
+allenskenpojujitsu.com.
+subs.sams.bw.semcs.net.
+api.twitter.com.
+www.waynegraham.com.
+sovitas.ru.
+crl.microsoft.com.
+lindsey.edu.
+106.249.143.201.in-addr.arpa.
+30.100.217.166.in-addr.arpa.
+wonder-shop.ru.
+cloud-search.linkury.com.
+138.76.22.113.in-addr.arpa.
+www.mayhemuk.co.uk.
+www.clubmaxmikita.com.
+www.bollywoodsamachar.com.
+www.calibex.com.
+v1.cache2.c.youtube.com.
+ajax.googleapis.com.
+xyte4aqlg.m68c7c4h.
+a1408.w43.akamai.net.
+wy.com.
+kiel.de.
+dns.msftncsi.com.
+2ab7t4h6m.k78x4b0y.
+api.conduit.com.
+a.root-servers.net.
+ocsp.dpwn.net.
+claritycvc.com.
+www.facebook.com.
+ingdirect.com.au.
+picasaweb.google.ca.
+clients2.google.com.
+mi-technologies.com.2.0001.arsmtp.com.
+www.skankazoid.com.
+mail2.micci.com.
+221.209.223.201.in-addr.arpa.
+www.xvideosdecul.com.
+e-press.ru.
+apps.facebook.com.
+tracking.traviangames.com.
+assets.dealply.com.
+s-static.ak.fbcdn.net.
+jbtfoodtech.ru.
+s0.2mdn.net.
+message.real.com.
+eo.wikipedia.org.
+a.root-servers.net.
+photos-a.ak.fbcdn.net.
+mail2.sw-hk.com.
+wow.lk.
+google.com.
+upload.wikimedia.org.
+h.live.com.
+www.facebook.com.
+caifane.blogspot.com.
+col.stb00.s-msn.com.
+savoia.net.
+steveelling.blogs.cbssports.com.
+13.222.149.186.in-addr.arpa.
+109.221.29.99.in-addr.arpa.
+1.bp.blogspot.com.
+204.228.40.83.in-addr.arpa.
+www.google-analytics.com.
+mitmproxy.org.
+s1016.photobucket.com.
+getaway-travel.com.
+231.241.19.176.in-addr.arpa.
+si0.twimg.com.
+a.root-servers.net.
+www.graduatearchitecture.com.
+a.root-servers.net.
+s-static.ak.facebook.com.
+katolicamusic.blogspot.com.
+edge.quantserve.com.
+treocapitalgroup.com.inbound10.mxlogicmx.net.
+pixel.facebook.com.
+204.122.253.189.in-addr.arpa.
+bmx.waseca.k12.mn.us.redcondor.net.
+a8.sphotos.ak.fbcdn.net.
+s.youtube.com.
+apps.facebook.com.
+www.arquimov.com.ar.
+bton.ac.uk.
+138.104.114.87.in-addr.arpa.
+ad.where.com.
+pagead2.googlesyndication.com.
+orcart.facebook.com.
+pubads.g.doubleclick.net.
+ak.imgfarm.com.
+a.root-servers.net.
+r._dns-sd._udp.lan.
+www.proyectar.com.mx.
+mtalk.google.com.
+latin.technetium.be.
+mail.eastwardho.net.
+g8ajzzxh9.94pm.
+ssl.gstatic.com.
+www.maxgxl.com.
+jamesdot.com.
+53.224.89.186.in-addr.arpa.
+www.googletagservices.com.
+bonzacards.com.
+gei.net.
+ordrmopmmiihqhhe.com.
+www.youtube.com.
+217.160.41.200.in-addr.arpa.
+es.sizegainplus.com.
+www.facebook.com.
+m7j3m1z4j.77nz.
+corelmania.com.
+s.ytimg.com.
+104.173.110.189.in-addr.arpa.
+indore.quikr.com.
+lasmilcancionesdel2000.blogspot.com.
+photos-f.ak.fbcdn.net.
+static.app.widdit.com.
+inbound.sonicvision.com.netsolmail.net.
+google.com.
+mx.ce.net.cust.a.hostedemail.com.
+jytv5afi4.u78b4g3g.
+photos-c.ak.fbcdn.net.
+spritelight.com.
+b.mouseflow.com.
+194.71.119.46.in-addr.arpa.
+o2ejza2hs.s86w6c5a.
+external.ak.fbcdn.net.
+a4.sphotos.ak.fbcdn.net.
+login.live.com.
+etown.k12.ky.us.
+www.setyourtiming.com.
+mke-inc.com.inbound25.mxlogic.net.
+huntergathererer.blogspot.com.
+net.philsite.net.
+register.hp.com.
+bluelight.net.
+32.250.228.190.in-addr.arpa.
+plusone.google.com.
+blcomp.co.uk.
+api.twitter.com.
+chilloutpoint.com.
+yui.yahooapis.com.
+dc-mail-f01.quelle.ru.
+a4.sphotos.ak.fbcdn.net.
+ad-g.doubleclick.net.
+mx6.me.com.akadns.net.
+vidavet.es.
+227.201.69.173.in-addr.arpa.
+0.tqn.com.
+xetgs.xboxlive.com.
+ikoo.zedo.com.
+blackberryforums.pinstack.com.
+apps.facebook.com.
+www.elimperiodelsexo.com.
+kb2.adobe.com.
+algebraweb.net.
+ashes-to-ashes.seriespepito.com.
+113.37.198.190.in-addr.arpa.
+mail.alivegames.com.
+theiphonewiki.com.
+ssl.gstatic.com.
+teredo.ipv6.microsoft.com.
+198.78.122.84.in-addr.arpa.
+www.thecopiercompany.com.au.
+www.10wallpaper.com.
+bmlfuw.gv.at.
+www.googletagservices.com.
+14.179.192.187.in-addr.arpa.
+www.google.com.
+www.adobe.com.
+238.163.230.85.in-addr.arpa.
+cdn.api.twitter.com.
+www.fat-sex.net.
+www.adidaswings-au.com.
+a.root-servers.net.
+www.flowersfoods.com.
+www.qw.com.
+loading5.widdit.com.
+xmpp003.hpeprint.com.
+www.flowelectro.net.
+b._dns-sd._udp.lan.
+statse.webtrendslive.com.
+156.165.86.201.in-addr.arpa.
+252.143.159.189.in-addr.arpa.
+affiliation.qcnscruise.com.
+rcp.na.blackberry.com.
+s-static.ak.fbcdn.net.
+teredo.ipv6.microsoft.com.
+nerienlouper.tv-replay.fr.
+photos-a.ak.fbcdn.net.
+home.mywebsearch.com.
+googleads.g.doubleclick.net.
+www.maturebritish.com.
+api-read.facebook.com.
+fr-fr.facebook.com.
+creative.ak.fbcdn.net.
+teredo.ipv6.microsoft.com.
+www.kanjukulive.com.
+a.root-servers.net.
+video.dailynylongalleries.com.
+ktpae.gr.
+www.wallcreate.com.
+homta.ajaxpong.com.
+arms.kazan.su.
+a.root-servers.net.
+www.regaloselescaparate.com.
+gogil.com.
+photos-d.ak.fbcdn.net.
+www.update.microsoft.com.
+www.facebook.com.
+a6.sphotos.ak.fbcdn.net.
+14.118.74.189.in-addr.arpa.
+plus.google.com.
+a.root-servers.net.
+world3.knightfight.se.
+nickzucc.blogspot.com.
+www.google.com.
+www.neoreviews.org.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+lifestyle.allwomenstalk.com.
+google.com.
+.
+platform.twitter.com.
+okmbui.com.
+a8.sphotos.ak.fbcdn.net.
+s.ytimg.com.
+5mkqtnqxl.15db.
+a3.sphotos.ak.fbcdn.net.
+www.epoxyproducts.com.
+ymcabra.org.
+mail.abix.ch.
+www.arrowofmorality.com.
+images.dragspecialties.com.
+232.45.1.201.in-addr.arpa.
+89.167.195.190.in-addr.arpa.
+www.rareflora.com.
+sn1msg1010720.gateway.messenger.live.com.
+www.movietome.com.
+a4.sphotos.ak.fbcdn.net.
+www.wupload.com.
+110.158.89.201.in-addr.arpa.
+yui.yahooapis.com.
+guzzoni.apple.com.
+www.tusconfesiones2.com.ar.
+30.178.241.201.in-addr.arpa.
+tynan-darcy.com.s200a2.psmtp.com.
+accounts.google.com.
+arorafashions.com.
+wikisource-lb.pmtpa.wikimedia.org.
+239.7.137.118.in-addr.arpa.
+.
+rpig-ltd.com.
+107.197.148.189.in-addr.arpa.
+messenger.hotmail.com.
+bg.stylem.com.
+a.root-servers.net.
+3.186.242.200.in-addr.arpa.
+static.cyworld.com.cn.
+updatekeepalive.mcafee.com.
+www.ge.com.
+www.aynax.com.
+griffin.co.uk.
+profile.ak.fbcdn.net.
+87lf3f6hh.11xi.
+theplazaregency.com.
+nordfarm.se.
+ad.yieldmanager.com.
+aol.com.
+217.199.165.141.in-addr.arpa.
+a1.sphotos.ak.fbcdn.net.
+1.189.35.187.in-addr.arpa.
+toolbarqueries.google.com.
+94.151.55.189.in-addr.arpa.
+1.gravatar.com.
+fs19.formsite.com.
+ajax.googleapis.com.
+rts.phn.doublepimp.com.
+graph.facebook.com.
+mmi.explabs.net.
+www.podtropolis.com.
+ads.mbendi.com.
+ssl.gstatic.com.
+ad19.feeldmc.com.
+polynext.ru.
+hotmail.com.
+pagead2.googlesyndication.com.
+ajax.googleapis.com.
+a.root-servers.net.
+_ldap._tcp.
+mx1.overline.com.
+artion.dk.
+www.mediatoday.co.kr.
+ask.scriptmafia.org.
+kay.cantonrep.com.
+pixel.quantserve.com.
+182.156.136.190.in-addr.arpa.
+secure.wlxrs.com.
+files.discountechnology.com.
+oascentral.stackmag.com.
+i3.ytimg.com.
+www.dcx.co.kr.
+external.ak.fbcdn.net.
+pagead2.googlesyndication.com.
+bbb.at.
+assets1.procpr.org.
+internet.sbi.com.
+ii7kgap58.n62f8h9a.
+zynga1-a.akamaihd.net.
+c14.smaato.net.
+inbound.sbmelectronics.com.cust.comcastmailservice.com.
+a5.sphotos.ak.fbcdn.net.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+inbound.theangelus.com.netsolmail.net.
+id.google.com.mx.
+safebrowsing-cache.google.com.
+171.20.58.186.in-addr.arpa.
+www.hippiecamper.com.
+6-courier.sandbox.push.apple.com.
+ssl.google-analytics.com.
+vcm.cz.
+dev.
+mail.rootcom.net.
+a.root-servers.net.
+b._dns-sd._udp.lan.
+photos-d.ak.fbcdn.net.
+photos-f.ak.fbcdn.net.
+randbrentals.com.
+a.root-servers.net.
+m.addthisedge.com.
+a.root-servers.net.
+166.81.68.201.in-addr.arpa.
+ludys.com.
+tgppsd2.triad-group.net.
+powerspan.com.s8b2.psmtp.com.
+d2100078.xoom.it.
+m.adnxs.com.
+a.analytics.yahoo.com.
+c-0.19-230f1041.40081.1518.19d3.3ea1.410.0.kn9e331jip5d71gr69pjl3h56t.avqs.mcafee.com.
+www.pandora.com.
+www.foxsportsla.com.
+.
+apis.google.com.
+psdresources.com.
+lb._dns-sd._udp.0.0.168.192.in-addr.arpa.
+media.wix.com.
+www.milksmartmama.com.
+www.bywifi.com.
+229.19.167.187.in-addr.arpa.
+internet.downv.com.
+portal9.7803986842.com.
+a.root-servers.net.
+pixel.facebook.com.
+121.199.247.92.in-addr.arpa.
+pcim-02.psohealth.com.
+pix04.revsci.net.
+32-courier.push.apple.com.
+gate.ygi.msk.ru.
+www.drtubercams.com.
+wpqsl2zh6.24zh.
+clients1.google.com.
+s.sharecare.com.
+www.everycollegegirl.com.
+pixel.facebook.com.
+s0.2mdn.net.
+113.184.30.190.in-addr.arpa.
+a.root-servers.net.
+3.189.31.83.in-addr.arpa.
+msc.wlxrs.com.
+dsflash.es.
+boq.com.
+ssl.gstatic.com.
+storage.conduit.com.
+a8.sphotos.ak.fbcdn.net.
+static1.spilcdn.com.
+fbcdn-profile-a.akamaihd.net.
+i4.ytimg.com.
+mail.advancebankus.com.
+joequispe.com.
+www.ic.daad.de.
+www.rackspace.com.
+connect.facebook.net.
+mail.mced.com.
+125.189.176.66.in-addr.arpa.
+w7fwzaaue.22iq.
+clients1.google.com.
+cgi1.ebay.com.
+acs.manuscriptcentral.com.
+www.humor1.net.
+139.197.86.200.in-addr.arpa.
+www.wordreference.com.
+139.105.47.211.in-addr.arpa.
+piola.it.
+a2.sphotos.ak.fbcdn.net.
+es.kioskea.net.
+berry71bleu.blogspot.com.
+user.ipcam.hk.
+i55.tinypic.com.
+transword.ru.
+veronicascornucopia.com.
+common.retronyms.com.
+vestidosdenovia.ybodas.com.
+sc2.rules.mailshell.net.
+free-math.ru.
+euro2012.interia.pl.
+kumisenshi.cl.
+a.root-servers.net.
+google.com.
+garaj.ru.
+a.root-servers.net.
+crl.thawte.com.
+www.investir.fr.
+a7.sphotos.ak.fbcdn.net.
+246.162.250.201.in-addr.arpa.
+140.14.0.181.in-addr.arpa.
+145.230.211.201.in-addr.arpa.
+join.tissuequeens.com.
+support.google.com.
+tap2-cdn.rubiconproject.com.
+freewebdesigntutorials.com.
+134.105.232.24.in-addr.arpa.
+fr-fr.facebook.com.
+www.pigeonelite.com.
+84.7.35.81.in-addr.arpa.
+a4.sphotos.ak.fbcdn.net.
+v7f61npcy.87gs.
+t2.gstatic.com.
+csi.gstatic.com.
+hotmail.com.
+tick.stdtime.gov.tw.
+a.root-servers.net.
+a.root-servers.net.
+a.root-servers.net.
+co.portage.wi.us.
+www.anastasianielsen.com.
+g.live.com.
+i4.ytimg.com.
+184.156.183.189.in-addr.arpa.
+sites.google.com.
+apps.facebook.com.
+124.56.167.187.in-addr.arpa.
+www.varieteguineenne.com.
+i41.tinypic.com.
+neilpeart.net.
+mail.philadelphiasign.com.
+i3.ytimg.com.
+ss7g3r43p.x26f9p9g.
+mail.cvproducts.com.
+a.root-servers.net.
+www.cepesju.org.
+144.84.90.186.in-addr.arpa.
+197.12.122.187.in-addr.arpa.
+s-static.ak.fbcdn.net.
+www.luna-maya.com.
+m.ak.fbcdn.net.
+bicycling.about.com.
+m4.licdn.com.
+alertas.wikio.es.
+content.yieldmanager.edgesuite.net.
+partner.googleadservices.com.
+artisticaccentsonline.com.
+zynga2-a.akamaihd.net.
+29.61.224.190.in-addr.arpa.
+platform.ak.fbcdn.net.
+www.adultsitelaw.com.
+m.google.com.
+www.medicalfashioncollection.com.
+profile.ak.fbcdn.net.
+fotos.muyzorras.com.
+maricarmensalas.blogspot.com.
+www.bsef.com.
+46.99.139.112.in-addr.arpa.
+checkip.dyndns.org.
+61.125.234.95.in-addr.arpa.
+ocsp.thawte.com.
+www.milfgfs.com.
+111.206.152.189.in-addr.arpa.
+socinforum.ru.
+orig-10006.conduit.cotcdn.net.
+orosucio.madryn.com.
+1.203.159.189.in-addr.arpa.
+udc.msn.com.
+photos-e.ak.fbcdn.net.
+inbound.advancedidcorp.com.netsolmail.net.
+182.82.37.81.in-addr.arpa.
+a3.sphotos.ak.fbcdn.net.
+www.youtube.com.
+a4.sphotos.ak.fbcdn.net.
+photos-f.ak.fbcdn.net.
+ad.yieldmanager.com.
+69.180.29.183.in-addr.arpa.
+www.mundoforo.com.
+ajax.googleapis.com.
+connect.facebook.net.
+chatenabled.mail.google.com.
+clients1.google.com.
+98.1.56.157.in-addr.arpa.
+accentlights.com.
+cdn.api.twitter.com.
+vocypyt.com.
+182.125.168.192.in-addr.arpa.
+pflanigan.com.
+sites.google.com.
+zman22674.u.yuku.com.
+hulkshare.com.
+imgn.dt07.net.
+motors.shop.ebay.com.
+iframes.wildfireapp.com.
+static.ak.fbcdn.net.
+gfx5.hotmail.com.
+plusone.google.com.
+a.root-servers.net.
+www.colby-sawyer.edu.
+kiss.crimea.ua.
+tc26.easythumbhost.com.
+js.wlxrs.com.
+40.154.192.187.in-addr.arpa.
+loading.retry.widdit.com.
+fsedistffalal.mp.
+www.gstatic.com.
+msc.wlxrs.com.
+a.c.2s-0.19-a70f0211.5140081.1518.19d4.3ea1.210.0.v1gz6g6fhcftq9amdt4ssmde7v.avqs.mcafee.com.
+intellanetad.com.
+piclist.friendfinder.com.
+115.214.30.78.in-addr.arpa.
+iphone-wu.apple.com.
+world76.runescape.com.
+google.com.
+etehplus.ru.
+gillmorgang.techcrunch.com.
+www.google-analytics.com.
+www.smartbuyglasses.co.uk.
+boolable.ca.
+developers.facebook.com.
+www.bambi.de.
+www.shantaram.com.
+photos-g.ak.fbcdn.net.
+cluster8.eu.messagelabs.com.
+a.root-servers.net.
+services.winamp.com.
+photo-tech.com.
+www.backlink.de.lv.
+www.facebook.com.
+ygj32yzri.k84m7d4c.
+www.wikimapia.com.
+a1.sphotos.ak.fbcdn.net.
+120.204.195.187.in-addr.arpa.
+mlocate.spotlife.net.
+agmennox.ru.
+quickpay.carmunity.de.
+www.yobt.com.
+templatesaver.com.
+webcache.googleusercontent.com.
+www.curious-straight-boys.com.
+75.67.199.190.in-addr.arpa.
+facebook.com.
+realtracks.com.
+hulkshare.com.
+142.249.82.200.in-addr.arpa.
+mailserver.knebworthhouse.com.
+www.derechopenalenlared.com.
+s-static.ak.facebook.com.
+www9.effectivemeasure.net.
+t1.pdanet.co.
+www.facebook.com.
+daviscollege.edu.inbound25.mxlogicmx.net.
+mail.iwlink.net.
+c76.altospam.com.
+time.chttl.com.tw.
+supl.nokia.com.
+neuffr.lan.
+xmjbyvveu.j52d7p9s.
+mx.quartz.synacor.com.
+93.95.243.189.in-addr.arpa.
+www.bitdefender.com.
+id.google.com.
+ib.adnxs.com.
+pop.gmx.de.
+238.166.172.189.in-addr.arpa.
+24.147.161.189.in-addr.arpa.
+102.151.28.75.in-addr.arpa.
+newtab.conduit-hosting.com.
+mail.kiwa.nl.
+s-static.ak.fbcdn.net.
+85.168.120.200.in-addr.arpa.
+96.167.30.46.in-addr.arpa.
+www.creaturespot.com.
+141.16.158.190.in-addr.arpa.
+us.bc.yahoo.com.
+52.221.165.122.in-addr.arpa.
+mail.triwarp.com.
+bo.portalmundos.com.
+download808.avast.com.
+u6790.96.spylog.com.
+teredo.ipv6.microsoft.com.
+www.futbolgesdeport.com.
+touch.facebook.com.
+bh.contextweb.com.
+101.239.49.190.in-addr.arpa.
+cinema.gallery.net.pluzmedia.com.
+28.213.141.201.in-addr.arpa.
+hurkens.iae-csic.org.
+mailx1.iitm.ac.in.
+a.root-servers.net.
+144.178.43.190.in-addr.arpa.
+www.nelsonautonews.com.
+wpad.home.
+www.tifozi.info.
+interact.com.
+28.18.17.190.in-addr.arpa.
+t1:gss52f.14dg.
+127.120.145.187.in-addr.arpa.
+profile.ak.fbcdn.net.
+folkloremiperu.com.
+mail.minowitz.com.
+123.37.229.189.in-addr.arpa.
+ax.init.itunes.apple.com.
+213.121.57.71.in-addr.arpa.
+6.130.164.81.in-addr.arpa.
+www.bdsm365.net.
+ur2mkumun.z98p4i6l.
+s-3.com.
+js.revsci.net.
+fusion.google.com.
+75.208.2.88.in-addr.arpa.
+ad.doubleclick.net.
+macbeth.com.
+quienmemandabaami.blogspot.com.
+westarfunds.com.
+narcosphere.narconews.com.
+a5.sphotos.ak.fbcdn.net.
+safebrowsing-cache.google.com.
+www.earningdiary.com.
+67.53.212.201.in-addr.arpa.
+a3.sphotos.ak.fbcdn.net.
+fxfeeds.mozilla.com.
+157.57.210.178.in-addr.arpa.
+a1920.g.akamai.net.
+a180.v.phobos.apple.com.
+a.root-servers.net.
+bay.messenger.services.live.com.
+www.golinker.com.
+84.233.28.190.in-addr.arpa.
+www.google-analytics.com.
+photos-h.ak.fbcdn.net.
+i2.ytimg.com.
+www.dirtydatinglive.com.
+s.ytimg.com.
+apis.google.com.
+tracker.torrentbox.com.
+a4.sphotos.ak.fbcdn.net.
+d1j68ux4ukg4g1.cloudfront.net.
+_625_60_6.
+www.facebook.com.
+aglobal.go.com.
+113.246.140.220.in-addr.arpa.
+widgets.twimg.com.
+1.0.0.127.dnsbugtest.1.0.0.127.in-addr.arpa.
+static.ak.fbcdn.net.
+252.187.250.201.in-addr.arpa.
+i4.ytimg.com.
+pixel.facebook.com.
+eaamericas.ecolab.com.
+25.204.58.95.in-addr.arpa.
+twitter.com.
+b._dns-sd._udp.0.0.168.192.in-addr.arpa.
+vu57aqmik.48mp.
+semivrat.ru.
+www.ikenvape.com.
+db5:3:3qv.25wf.
+www.moviequotesandmore.com.
+chorrol.com.
+mail.wingscc.com.
+cdn.api.twitter.com.
+i3.ytimg.com.
+de-de.facebook.com.
+t1.softonicads.com.
+pubads.g.doubleclick.net.
+smtp.xcountry.tv.
+240.12.166.71.in-addr.arpa.
+profile.ak.fbcdn.net.
+237.17.126.188.in-addr.arpa.
+www.mcanime.net.
+content.yieldmanager.edgesuite.net.
+imagos.escortsite.com.
+monster.frivmini.com.
+98.250.219.80.in-addr.arpa.
+connect.facebook.net.
+78.225.90.84.in-addr.arpa.
+irohe.blogspot.com.
+apture.com.
+q1sx3dd:r.70jg.
+www.nptdiy.com.
+metric.starz.com.
+profile.ak.fbcdn.net.
+webres4.pand.ctmail.com.
+photos-d.ak.fbcdn.net.
+208.244.158.189.in-addr.arpa.
+tottuas.com.
+s-static.ak.facebook.com.
+tyler.newsvine.com.
+www.youpron.com.
+mail.
+b._dns-sd._udp.0.1.168.192.in-addr.arpa.
+mailserver.s21.com.
+creative.ak.fbcdn.net.
+vuelohotel.airfrance.es.
+s7.addthis.com.
+rhyason.com.
+www.bankresearch.org.
+cdn.api.twitter.com.
+restat.com.s9a1.psmtp.com.
+apis.google.com.
+cn1.redswoosh.akadns.net.
+static.ak.fbcdn.net.
+groups.live.com.
+113.154.134.186.in-addr.arpa.
+www.facebook.com.
+rad.msn.com.
+www.facebook.com.
+80.74.141.201.in-addr.arpa.
+vlcr9ii:2.01cs.
+dns.msftncsi.com.
+www.netlog.com.
+a47.photo.store.qq.com.
+youtu.be.
+37.21.154.189.in-addr.arpa.
+s1.trrsf.com.
+34-courier.push.apple.com.
+img.mediaplex.com.
+141.16.174.190.in-addr.arpa.
+www.googleadservices.com.
+jo.countrysearch.tradekey.com.
+mail.google.com.
+networld.com.
+www.wowjobs.co.nz.
+a.root-servers.net.
+mscrl.microsoft.com.
+_312_06_2.
+isvw2.rurallink.gov.my.
+a7.sphotos.ak.fbcdn.net.
+crl.microsoft.com.
+ksde.org.
+tenesol-al.com.
+sites.google.com.
+mail2open.com.
+www.allposters.nl.
+brigadadesaludpopular.blogspot.com.
+200.26.68.108.in-addr.arpa.
+mx1.ynemail.com.
+_790_51_8.
+174.108.193.200.in-addr.arpa.
+support.google.com.
+www.msftncsi.com.
+rmonline.actionsystems.com.
+106.24.195.210.in-addr.arpa.
+es.answers.yahoo.com.
+www.cadaver.org.
+170.2.250.111.in-addr.arpa.
+www.google.com.
+64.107.24.98.in-addr.arpa.
+drcranton.com.
+www.disenowebenmexico.com.
+folkartmuseum.org.
+i1.ytimg.com.
+clock.fmt.he.net.
+g.msn.com.
+mail.rfpl.org.
+discoverwaterfront.com.
+44.73.231.78.in-addr.arpa.
+mandiloves.wordpress.com.
+az15112.vo.msecnd.net.
+cfefd.com.
+tc.v2.cache6.c.youtube.com.
+netzero.net.
+googleads.g.doubleclick.net.
+46.232.50.200.in-addr.arpa.
+rhpoultry.com.
+.
+accounts.google.com.
+photos-e.ak.fbcdn.net.
+www.tweetc.com.
+ajax.googleapis.com.
+v3.nonxt8.c.pack.google.com.
+a8.sphotos.ak.fbcdn.net.
+plusone.google.com.
+www.teamr.com.
+lists.cs.columbia.edu.
+ca.wikipedia.org.
+a.root-servers.net.
+shop.mudshop.com.
+1.map.pop6.com.
+154.98.54.121.in-addr.arpa.
+bbcmundo.com.
+twitter.com.
+www.ingenico-us.com.
+www.evs.ee.
+ns02.sumicol.com.
+smarticon.geotrust.com.
+fido.vsi.ru.
+212.24.192.99.in-addr.arpa.
+www.goojue.com.
+b-0.19-a3096008.481.1518.19d4.3ea1.410.0.gw4z1h94peialrfff35risskvj.avqs.mcafee.com.
+ksn2-12.kaspersky-labs.com.
+zh-cn.facebook.com.
+digrouparchitecture.com.s6a1.psmtp.com.
+profile.ak.fbcdn.net.
+180.76.113.186.in-addr.arpa.
+181.171.56.186.in-addr.arpa.
+pixel.facebook.com.
+profile.ak.fbcdn.net.
+console-ssl.service.playfish.com.
+att.wellphone.com.
+190.51.7.199.in-addr.arpa.
+de.wikipedia.org.
+www.creacionenglobo.com.mx.
+www.sqm.microsoft.com.
+time.chttl.com.tw.
+www.max-johnson.blogspot.com.
+148.200.29.201.in-addr.arpa.
+kmet.ee.
+a5.sphotos.ak.fbcdn.net.
+ssl.gstatic.com.
+plusone.google.com.
+sn3.mailshell.net.
+fbmessenger2.crispapp.com.
+apps.facebook.com.
+www.facebook.com.
+dotmena.com.
+ad-g.doubleclick.net.
+29.210.171.189.in-addr.arpa.
+pt-br.facebook.com.
+alert.services.conduit.com.
+bt.peerseed.ru.
+250.225.89.186.in-addr.arpa.
+izlence.mbirgin.com.
+a2.sphotos.ak.fbcdn.net.
+uhdu2qejt.09qr.
+css.wlxrs.com.
+api.facebook.com.
+30.167.53.85.in-addr.arpa.
+api.webrep.avast.com.
+www.ntdtv.jp.
+clarin.feedsportal.com.
+www.youtube.com.
+dubaicountryclub.com.
+www.msftncsi.com.
+carddav.address.yahoo.com.
+absolutelyangie.blogspot.com.
+sukinson.ru.
+www.primerasexperiencias.com.
+9.31.165.90.in-addr.arpa.
+a.root-servers.net.
+static.aupeo.com.
+www.juegos.com.
+thegranitegroup.com.
+mkportal.net.ru.
+android.l.google.com.
+226.210.77.200.in-addr.arpa.
+www6.inscription.tn.
+a.root-servers.net.
+crowndiamond.net.
+isatap.home.
+platform.twitter.com.
+holeditk.com.
+content.yieldmanager.edgesuite.net.
+aa.avg.com.
+189.27.125.186.in-addr.arpa.
+google.com.
+photos-g.ak.fbcdn.net.
+public.krasnet.ru.
+almibarimposible.files.wordpress.com.
+www.purotorrent.com.
+img717.imageshack.us.
+mail.reiffmolding.com.
+17.159.232.77.in-addr.arpa.
+db._dns-sd._udp.0.1.168.192.in-addr.arpa.
+a.c-0.19-230f7081.d110081.1518.19c2.3ea0.210.0.189i4g7wtbdgc4m6kmvbg52kf6.avqs.mcafee.com.
+api.twitter.com.
+static.ak.fbcdn.net.
+107.16.23.187.in-addr.arpa.
+rol.net.
+xn--strike-37dbbbbb.ws.
+dwexchange.dongwon.com.
+www.faceboo.co.
+_108_93_8.
+u4cesos:c.55vl.
+www.nudeslutpics.net.
+a2.sphotos.ak.fbcdn.net.
+27.137.173.187.in-addr.arpa.
+ksn1-11-part1.kaspersky-labs.com.
+m.facebook.com.
+www.facebook.com.
+addictedtothai.ru.
+fb-tc-1.farmville.com.
+214.246.49.186.in-addr.arpa.
+yahoosbc.com.
+shiki-comunity.activoforo.com.
+rq2.com.s5a2.psmtp.com.
+i.imwx.com.
+211.234.161.190.in-addr.arpa.
+trophy01.np.community.playstation.net.
+fox21online.com.
+a3.sphotos.ak.fbcdn.net.
+www.youtube.com.
+214.20.168.192.in-addr.arpa.
+www.youtube.com.
+cacfrealty.com.
+instagr.am.
+lexaudit.khn.ru.
+a.rad.msn.com.
+ads.adxpansion.com.
+aspmx.l.google.com.
+cuentosyfabulas.wordpress.com.
+creative.ak.fbcdn.net.
+123.24.167.190.in-addr.arpa.
+5.145.57.200.combined.njabl.org.
+photos-f.ak.fbcdn.net.
+school1415.ru.
+pinkchocolate-break.blogspot.com.
+buscandoellook.blogspot.com.
+external.ak.fbcdn.net.
+googleads.g.doubleclick.net.
+www.trafficshop.com.
+www.facebook.com.
+search.conduit.com.
+wwba1040.com.
+www.theflowermart.com.
+www.ladysonia.org.
+srv.prozess.ru.
+i.ytimg.com.
+manila.com.
+teredo.ipv6.microsoft.com.
+34.195.252.115.in-addr.arpa.
+www.movies-city.com.
+a.root-servers.net.
+a1.sphotos.ak.fbcdn.net.
+init.gc.apple.com.
+f.doodlemobile.com.\027.
+a.root-servers.net.
+ntp.glb.nist.gov.
+profile.ak.fbcdn.net.
+ruagro.ru.
+springdaleark.org.
+66.206.42.201.in-addr.arpa.
+pagead2.googlesyndication.com.
+149.83.111.95.in-addr.arpa.
+www.stumbleupon.com.
+www.lauraingallswilder.com.
+140.53.106.186.in-addr.arpa.
+media.tumblr.com.
+twitter.com.
+pop.gmail.com.
+twitter.com.
+m2.nsimg.net.
+b._dns-sd._udp.0.1.168.192.in-addr.arpa.
+photos-a.ak.fbcdn.net.
+inmigracionenestadosunidosenelsigloxix.files.wordpress.com.
+bxo3p2sok.k14p7o9n.
+s.ytimg.com.
+googleads.g.doubleclick.net.
+msghouasg02.bhi-net.com.
+robertwhitehead.com.
+profacebookfanpage.com.
+ib.adnxs.com.
+goshaka.com.
+a5.sphotos.ak.fbcdn.net.
+rs529tl.rapidshare.com.
+data.flurry.com.
+92.1.253.201.in-addr.arpa.
+164.102.75.190.in-addr.arpa.
+board.km.ua.
+content.yieldmanager.edgesuite.net.
+es-la.facebook.com.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+thecelebritycafe.disqus.com.
+static.ak.fbcdn.net.
+www.theagitator.net.
+photos-g.ak.fbcdn.net.
+cigar.com.
+www.computerrelatedsites.com.
+ads2.msads.net.
+www.antoniodepinto.com.
+platform.twitter.com.
+ikui5t7qe.b09e7h5l.
+opentorrent.ru.
+v2.nonxt1.c.youtube.com.
+ksn7.kaspersky-labs.com.
+75.39.194.187.in-addr.arpa.
+7.96.175.190.in-addr.arpa.
+www.trustlogo.com.
+heartbeat.belkin.com.
+d3l3lkinz3f56t.cloudfront.net.
+237.74.167.189.in-addr.arpa.
+j34s11ort.04kt.
+11.1.168.192.in-addr.arpa.
+feeds.intoday.in.
+www.regenwald.org.
+119.114.69.219.in-addr.arpa.
+diaryofananny.naughtyamerica.com.
+mscrl.microsoft.com.
+179.181.139.93.in-addr.arpa.
+195.233.10.187.in-addr.arpa.
+fesnak.com.inbound30.elephantoutlook.com.
+dc.tvteam.info.
+221.25.150.200.in-addr.arpa.
+50.34.173.189.in-addr.arpa.
+gelert.5.com1.ru.
+www.facebook.com.
+139.144.56.186.in-addr.arpa.
+tgpvideos.dvdbox.com.
+albaniaonline.net.
+msc.wlxrs.com.
+a.root-servers.net.
+connect.facebook.net.
+www.aro.com.au.
+guide-paris-france.ru.
+194.88.127.201.in-addr.arpa.
+astronpc.com.
+annewatkins.com.
+images.google.com.
+img.i.yunduan.cn.
+tudwal.orangehome.co.uk.
+www.medibolics.com.
+a.root-servers.net.
+avidinc.com.inbound10.mxlogicmx.net.
+hootcourse.com.
+zkolos.ru.
+wpad.
+spravedlivo-online.ru.
+img853.imageshack.us.
+adsformula.sitescout.netdna-cdn.com.
+apps.facebook.com.
+nxcache.nexon.net.
+198.15.120.200.in-addr.arpa.
+a1.sphotos.ak.fbcdn.net.
+nwjustice.org.
+www.simicondon.com.
+243.11.6.186.in-addr.arpa.
+228.206.59.200.in-addr.arpa.
+hotmail.com.
+yui.yahooapis.jp.
+track-hub.appspot.com.
+toolbarqueries.google.com.
+a.root-servers.net.
+tc.v2.cache8.c.youtube.com.
+relay1.cityline.ru.
+www.face.net.
+www.netvibes.com.
+ad.yieldmanager.com.
+profile.ak.fbcdn.net.
+krwetatnt.net.
+weather.service.msn.com.
+84.220.147.213.in-addr.arpa.
+xvideos-466.vo.llnwd.net.
+cnfg.facemoods.com.
+236.179.117.76.in-addr.arpa.
+www.univision.com.
+24.173.240.201.in-addr.arpa.
+secure.social-server.com.
+um12.eset.com.
+directorym.com.
+www.nometoqueslashelveticas.com.
+ib.adnxs.com.
+maila.cosmetique.com.
+time.stdtime.gov.tw.
+www.facebook.com.
+www.google.com.mx.
+fbcdn-profile-a.akamaihd.net.
+evolutiongroove.com.
+haasjr.org.
+49.53.131.187.in-addr.arpa.
+38.125.99.41.in-addr.arpa.
+a.root-servers.net.
+www.sg8.info.
+www.guatevoluntaria.org.
+secure.wlxrs.com.
+artesanias-decoracion.blogspot.com.
+esc.rr.com.
+safebrowsing-cache.google.com.
+dns.msftncsi.com.
+mx.nhplace.com.
+vikesfan.com.
+apps.facebook.com.
+209.14.158.190.in-addr.arpa.
+143.203.219.90.in-addr.arpa.
+kabbalahgroup.info.
+c.brightcove.com.
+alpha-proff.ru.
+.
+107.146.220.66.in-addr.arpa.
+barbie.es.
+www.facebook.com.
+www.inkfrog.com.
+ladyluck13.net.
+old.pixmac.com.
+profile.ak.fbcdn.net.
+235.206.183.189.in-addr.arpa.
+a.root-servers.net.
+scholar.l.google.com.
+profile.ak.fbcdn.net.
+petardylandia.blogspot.com.
+content.yieldmanager.edgesuite.net.
+s-static.ak.facebook.com.
+32.226.28.190.in-addr.arpa.
+weplay.com.
+a1402.w40.akamai.net.
+www.alegsa.com.ar.
+s-static.ak.facebook.com.
+yonan.en.alibaba.com.
+deserttreasurez.com.
+profile.ak.fbcdn.net.
+www.glutenfree.com.au.
+m-w.com.
+i4.ytimg.com.
+a.root-servers.net.
+a8.sphotos.ak.fbcdn.net.
+instagr.am.
+photos-h.ak.fbcdn.net.
+a.root-servers.net.
+orcart.facebook.com.
+www.cargamimovil.com.
+srx.befr.ebayrtm.com.
+www.auxmoney-blog.de.
+api.twitter.com.
+a.root-servers.net.
+www.ole.clarin.com.
+33.115.20.201.in-addr.arpa.
+www.trucoteca.com.
+highcountrysurveyors.com.
+castanuelasychurros.blogspot.com.
+mail2.home8.ru.
+cdn.cpmstar.com.
+142.48.11.201.in-addr.arpa.
+udawggraphics.com.s7b2.psmtp.com.
+a-0.19-230fe001.580.1518.19d4.3ea1.410.0.i31f462m9abipbegahw5czg3si.avqs.mcafee.com.
+photos-c.ak.fbcdn.net.
+api.facebook.com.
+gateway-press.com.
+download735.avast.com.
+www.google.com.
+au.download.windowsupdate.com.
+104.52.18.89.zz.countries.nerd.dk.
+www.skipunx.com.
+sp.cwfservice.net.
+www.positivos.com.
+i.minus.com.
+maximaf.ru.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+97.91.18.24.in-addr.arpa.
+tsm05.eset.com.
+www.bramjnet.com.
+forums.fatakat.com.
+static.ak.connect.facebook.com.
+www.newhentai.com.
+a.root-servers.net.
+photos-a.ak.fbcdn.net.
+54.120.245.69.in-addr.arpa.
+www.sergiocortes.es.
+a5.sphotos.ak.fbcdn.net.
+static.ak.fbcdn.net.
+a3.sphotos.ak.fbcdn.net.
+anuncie.taringa.net.
+183.121.69.190.in-addr.arpa.
+210.134.16.190.in-addr.arpa.
+www.enterfactory.com.
+www.autopressnews.com.
+img.cruelzoo.com.
+pixel.facebook.com.
+eatsleepdraw.com.
+130.39.0.10.in-addr.arpa.
+www.facebook.com.
+fl01.ct2.comclick.com.
+tammy.webegirls.biz.
+baby.163.com.
+www.scorpionmezcal.com.
+i.ytimg.com.
+echo.edge.messenger.live.com.
+165.250.30.137.in-addr.arpa.
+soq:noz64.64ey.
+ads.adgator.co.za.
+a1003.w41.akamai.net.
+ec.atdmt.com.
+1.0.0.127.dnsbugtest.1.0.0.127.in-addr.arpa.
+224.129.248.201.in-addr.arpa.
+observadorvirtual.blogspot.com.
+www.facebook.com.
+www.facebook.com.
+skillpod.com.
+www.facebooks.com.mx.
+jsonip.appspot.com.
+86.195.253.201.in-addr.arpa.
+s-static.ak.facebook.com.
+a7.sphotos.ak.fbcdn.net.
+208.61.122.186.in-addr.arpa.
+static.ifa.camads.net.
+s.ytimg.com.
+www.fantastigames.com.
+teredo.ipv6.microsoft.com.
+sethigherstandards.com.
+cinnabar.cc.
+eu-st.xhamster.com.
+usgs.com.
+us.lrd.yahoo.com.
+www.facebook.com.
+dns.msftncsi.com.
+tocahistoria.blogspot.com.
+cfile66.uf.daum.net.
+www.googleadservices.com.
+blog.educaedu.com.
+gdata.youtube.com.
+www.w3.org.
+copticorphans.org.
+i4.ytimg.com.
+i6.tagstat.com.
+82.137.203.190.in-addr.arpa.
+mail.cad-net.com.
+a.c-0.19-a30fa000.30011.1518.19d4.3ea1.210.0.2ua9b1g27pez7vahzjw2dsb2dq.avqs.mcafee.com.
+frasebook.net.
+cssmixer.com.
+p.imgci.com.
+www.idownloadbox.com.
+a.root-servers.net.
+skoda-auto.co.in.
+a.root-servers.net.
+msc.wlxrs.com.
+winkel.vpro.nl.
+151.119.244.85.in-addr.arpa.
+oseltd.ru.
+www.veodetodotv.com.
+dns.msftncsi.com.
+view.atdmt.com.
+cm.g.doubleclick.net.
+i.cdn.turner.com.
+mail.northeastdigestive.com.
+dragonballforever-goku6384.blogspot.com.
+energyinnovation.net.
+www.magicdust.com.au.
+swannhadley.com.
+tzt9sk3ku.f10t7w7p.
+atravesadasporlacultura.wordpress.com.
+www.strongchicks.com.
+a.root-servers.net.
+photos-d.ak.fbcdn.net.
+www.being.com.
+www3.smartadserver.com.
+cakewalknews.cakewalk.com.
+172.53.106.189.in-addr.arpa.
+166.86.217.217.in-addr.arpa.
+a.root-servers.net.
+www.azalyrics.net.
+a6.sphotos.ak.fbcdn.net.
+barracuda.burns-scalo.com.
+2000charge.com.
+profile.ak.fbcdn.net.
+www.xmaduras.com.
+ad.doubleclick.net.
+www.adultswimla.com.
+photos-g.ak.fbcdn.net.
+apps.facebook.com.
+www.crunchbase.com.
+b.scorecardresearch.com.
+alteradosdemercedes.blogspot.com.
+www.yourirondisciples.net.
+www.mrc-hnr.cam.ac.uk.
+ironcita.blogspot.com.
+81.14.250.189.in-addr.arpa.
+32.48.132.187.in-addr.arpa.
+photos-a.ak.fbcdn.net.
+rad.msn.com.
+163.36.250.201.in-addr.arpa.
+gamesforxperiaplay.com.
+titanium30-en.url.trendmicro.com.
+www.crouchingdragon.com.
+safebrowsing.clients.google.com.
+158.236.141.201.in-addr.arpa.
+mail.prince.com.
+checkip.dyndns.org.
+justdancegame.au.ubi.com.
+empleo.mitula.mx.
+www.dimofinf.net.
+a.root-servers.net.
+fbcdn-video-a.akamaihd.net.
+news.gohome.com.hk.
+software.canon-europe.com.
+a7.sphotos.ak.fbcdn.net.
+teredo.ipv6.microsoft.com.
+mail.google.com.
+www.farmville.com.
+0-74.channel.facebook.com.
+a.root-servers.net.
+.
+www.similares.net.
+9gibtn6v5.30su.
+energyunited.com.
+www.scribd.com.
+73.37.168.192.in-addr.arpa.
+a.root-servers.net.
+extratorrent.com.
+6.246.7.187.in-addr.arpa.
+aldrinchavarria.wordpress.com.
+ibmafia.com.
+208.188.170.201.in-addr.arpa.
+eddea-emontoya.blogspot.com.
+vqta1sjkl.h08n4z7y.
+ads1.msads.net.
+photos-f.ak.fbcdn.net.
+e2ci.com.
+db._dns-sd._udp.0.1.168.192.in-addr.arpa.
+plus.google.com.
+profile.ak.fbcdn.net.
+translate.google.com.mx.
+91.187.159.189.in-addr.arpa.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+v2qgm2mlf.s76z3f5f.
+wpc.0c28.edgecastcdn.net.
+www.explosiongay.com.ar.
+media.ladbrokes.com.
+dns.msftncsi.com.
+a.root-servers.net.
+blowfishunlocks.com.
+a1.sphotos.ak.fbcdn.net.
+swf.extensionfile.net.
+aa.online-metrix.net.
+www.hospitalangelespedregal.com.mx.
+abc.csar.go.com.
+mulfordconcreteinc.com.
+www.drogaconsulta.com.ar.
+facemoods.com.
+a8.sphotos.ak.fbcdn.net.
+google.com.
+87.48.141.201.in-addr.arpa.
+182.74.160.187.in-addr.arpa.
+193.51.167.190.in-addr.arpa.
+35.7.2.187.in-addr.arpa.
+www.google.com.
+photos-a.ak.fbcdn.net.
+a7.sphotos.ak.fbcdn.net.
+182.49.48.108.in-addr.arpa.
+www.hp.com.
+apis.google.com.
+google.com.
+fbcdn-profile-a.akamaihd.net.
+www.trfirmaekle.com.
+www.gigisapparel.com.
+189.223.228.189.in-addr.arpa.
+apps.facebook.com.
+119.14.108.76.in-addr.arpa.
+hi-in.facebook.com.
+cctupgrades.com.
+s0.2mdn.net.
+pangiatech.com.
+nataliaseweryn.buzznet.com.
+photos-g.ak.fbcdn.net.
+pixel.facebook.com.
+161.28.77.190.in-addr.arpa.
+a1725.l.akamai.net.
+mabeslor.com.
+es-la.facebook.com.
+20.180.95.109.in-addr.arpa.
+img69.imageshack.us.
+photos-g.ak.fbcdn.net.
+clients1.google.com.
+ad.doubleclick.net.
+www.google-analytics.com.
+gruporahn.com.
+mail.cacoon.ru.
+adq.nextag.com.
+swaab.net.
+kube.en.muxxu.com.
+185.174.171.189.in-addr.arpa.
+b._dns-sd._udp.0.1.168.192.in-addr.arpa.
+correctcryogenics.com.
+jfriend.smugmug.com.
+.
+raywal.com.
+www.belkin.com.
+mx2.glr.nl.
+www.kartfinder.com.
+secure.wlxrs.com.
+www.google.com.
+ns2.p15.dynect.net.
+cs5353.vkontakte.ru.
+me.effectivemeasure.net.
+i1.ytimg.com.
+eduardoguille.artelista.com.
+ds.serving-sys.com.
+content-cdn.walmart.com.
+atyt.net.
+f9d5q6kc2.28ug.
+hbf.cloud.avg.com.
+21.174.168.192.in-addr.arpa.
+vcs2.msg.yahoo.com.
+teredo.ipv6.microsoft.com.
+155.184.217.85.in-addr.arpa.
+loveday.getmylove.net.
+a1.sphotos.ak.fbcdn.net.
+static.ak.fbcdn.net.
+onthepin.com.
+mitsloanexperts.com.
+www.mcleodgaming.com.
+pop3.live.com.
+u.4f61a6b43bfdf105.com.
+www.diigo.com.
+i3.ytimg.com.
+api.twitter.com.
+update.utorrent.com.local.
+ads.trafficjunky.net.
+profile.ak.fbcdn.net.
+viva.gr.
+118.249.192.190.in-addr.arpa.
+www.google.com.
+profile.ak.fbcdn.net.
+mebeletta.ru.
+252.133.132.187.in-addr.arpa.
+42.142.49.96.in-addr.arpa.
+www.tribalwars.ae.
+google.com.
+www.mujeresdesnudas.com.es.
+54.164.145.201.in-addr.arpa.
+webcache.googleusercontent.com.
+dns.msftncsi.com.
+s-static.ak.facebook.com.
+ji.zh.ch.
+safebrowsing.clients.google.com.
+api.facebook.com.
+oxfordpolymers.com.
+sp.cwfservice.net.
+market.android.com.
+members.dyndns.org.
+www.actosdeamor.com.
+a5.sphotos.ak.fbcdn.net.
+creative.ak.fbcdn.net.
+.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+cdn.emily18.com.
+a5.sphotos.ak.fbcdn.net.
+188.14.245.78.in-addr.arpa.
+fxfeeds.mozilla.com.
+combatarms.nexon.net.
+a.root-servers.net.
+www.revistaneurocirugia.com.
+ucs.query.yahoo.com.
+poetsofthefallargentina.wordpress.com.
+innsofcourt.org.
+xcdn.xgraph.net.
+13.3.185.31.in-addr.arpa.
+www.infinityflashgames.com.
+us.mc464.mail.yahoo.com.
+g:gjvrs7d.m21s4q7v.
+images.apple.com.
+platform.ak.fbcdn.net.
+agrupacionexconscriptos.blogspot.com.
+130.33.56.186.in-addr.arpa.
+legendabeatles.blogspot.com.
+i4.ytimg.com.
+mail.fitaihi.com.sa.
+msc.wlxrs.com.
+dis.criteo.com.
+usodelarazon.blogspot.com.
+a.root-servers.net.
+108.1.168.192.in-addr.arpa.
+134.184.142.175.in-addr.arpa.
+ipcanswers.com.
+dr._dns-sd._udp.0.0.168.192.in-addr.arpa.
+28.media.tumblr.com.
+vfbinsurance.com.
+cdn4.theigroup.co.uk.
+www.zynga.com.
+www.iloveblackgirls.net.
+armmf.adobe.com.
+lh6.googleusercontent.com.
+1.117.166.118.in-addr.arpa.
+www.facebook.com.
+153.154.114.190.in-addr.arpa.
+45.229.26.125.in-addr.arpa.
+36.196.191.72.in-addr.arpa.
+p05-keyvalueservice.icloud.com.
+28.ape.bigmuscle.com.
+94.187.100.189.in-addr.arpa.
+a.root-servers.net.
+photos-g.ak.fbcdn.net.
+by2msg3020414.gateway.messenger.live.com.
+business-prof.ru.
+www.getfirefox.com.
+itunes.apple.com.
+es-es.facebook.com.
+108.42.214.201.in-addr.arpa.
+czechmat.ru.
+www.azul.com.ec.
+www.segurosrossi.com.ar.
+lawrencemandel.com.
+profile.ak.fbcdn.net.
+picasaweb.l.google.com.
+safebrowsing.clients.google.com.
+1272039.r.msn.com.
+photos-e.ak.fbcdn.net.
+uptowntruckingdisposal.com.
+ib.adnxs.com.
+www.legislation.qld.gov.au.
+stomatsamara.ru.
+fbcdn-profile-a.akamaihd.net.
+200.69.169.87.in-addr.arpa.
+fbcdn-photos-a.akamaihd.net.
+accounts.google.com.
+ad-g.doubleclick.net.
+a.root-servers.net.
+www.facebook.com.
+s-external.ak.fbcdn.net.
+co116w.col116.mail.live.com.
+www.3ddgames.com.
+photos-f.ak.fbcdn.net.
+google.com.
+download983.avast.com.
+www.asianborderlands.net.
+platform.ak.fbcdn.net.
+246.221.57.187.in-addr.arpa.
+a1402.w40.akamai.net.
+111.100.62.189.in-addr.arpa.
+accounts.google.com.
+a-0.19-a309d081.d8f0082.1518.19d4.3ea0.210.0.b7gkhu4wutrenl222ip5f7zh6q.avqs.mcafee.com.
+www.iphone4.fr.
+news.google.com.mx.
+teredo.ipv6.microsoft.com.
+24.119.111.189.in-addr.arpa.
+161.169.59.186.in-addr.arpa.
+androidpost.net.
+www.facebook.com.
+www.apple.com.
+idcmstask.app.joy.cn.
+191.237.74.187.in-addr.arpa.
+adocean-by.hit.gemius.pl.
+www.cbd-habitat.com.
+ssl.gstatic.com.
+ronan-parke.org.
+www.google.es.
+rkthb.co.
+123.220.74.212.in-addr.arpa.
+touch.facebook.com.
+garexdoors.ru.
+a.root-servers.net.
+b.thumbs.redditmedia.com.
+apps.facebook.com.
+144.36.167.201.in-addr.arpa.
+telus-updates.radialpoint.net.
+www.creditcardsguidance.com.
+locaporlaluna.lacoctelera.net.
+101.236.69.114.in-addr.arpa.
+a.root-servers.net.
+xxxl-cash.net.
+78.21.67.190.in-addr.arpa.
+photos-g.ak.fbcdn.net.
+a.root-servers.net.
+84.129.50.189.in-addr.arpa.
+i1.ytimg.com.
+pim.raz.htcsense.com.
+stargen.com.
+29.15.237.189.in-addr.arpa.
+dns.msftncsi.com.
+aviva-giles.blogspot.com.
+gtssl-crl.geotrust.com.
+23.143.106.186.in-addr.arpa.
+col.stb.s-msn.com.
+cdn.data.mobilytrip.com.
+a.root-servers.net.
+mail-in-a.mx.xnet.hr.
+performance-suspension.eibach.de.
+a.root-servers.net.
+bay.messenger.services.live.com.
+cf.addthis.com.
+simai.ru.
+0.0.0.0.in-addr.arpa.
+spa-resources-international.com.
+www.google.com.mx.
+external.ak.fbcdn.net.
+mtsmail.org.
+ratings-wrs.symantec.com.
+74.27.150.190.in-addr.arpa.
+smtaextrwc02.gene.com.
+scholar.google.es.
+59.172.138.201.in-addr.arpa.
+mail.tydex.ru.
+croftmotors.co.uk.
+urs.microsoft.com.
+groups.google.com.mx.
+10.246.197.204.in-addr.arpa.
+big.assets.huffingtonpost.com.
+fbcdn-photos-a.akamaihd.net.
+197.205.1.201.in-addr.arpa.
+53.106.223.201.in-addr.arpa.
+www.macromedia.com.
+rtsi.wemfbox.ch.
+ad.xtendmedia.com.
+252.109.224.1.in-addr.arpa.
+a.root-servers.net.
+www.mercadolibre.com.pe.
+sp.cwfservice.net.
+a.root-servers.net.
+www.jscount.com.
+www.medicinatndr.com.
+apps.facebook.com.
+www.campbells.com.mx.
+www.bmwusa.com.
+www.digitalfieldguide.com.
+www.peruwptravelthemes.com.
+g.live.com.
+185.249.30.189.in-addr.arpa.
+skyscape.sky.com.
+a3.sphotos.ak.fbcdn.net.
+155.75.104.71.in-addr.arpa.
+bi1uy6trk.u09l3r0u.
+a1402.w40.akamai.net.
+125.153.40.187.in-addr.arpa.
+afsdv.ru.
+www.appsleak.com.
+007sz.net.
+www.peeperz.com.
+167.60.23.94.in-addr.arpa.
+www.mapsfordesign.com.
+apis.google.com.
+www.facebook.com.
+0.11-230f8081.c120081.1518.17f8.3ea0.210.0.6sildrlmua1jhig1sfve2se1fi.avqs.mcafee.com.
+_782_46_6.
+84.63.99.190.in-addr.arpa.
+empiredistrict.com.
+cinecero.blogspot.com.
+82.46.53.201.in-addr.arpa.
+asas.ru.
+www.mk12.com.
+www.urovirtual.net.
+24.62.236.190.in-addr.arpa.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+221.134.231.125.in-addr.arpa.
+mx1.aragon.es.
+29.media.tumblr.com.
+iscreative.com.
+45.170.254.169.in-addr.arpa.
+thirdtribemarketing.com.
+64.89.62.151.in-addr.arpa.
+155.85.9.186.in-addr.arpa.
+136.215.8.186.in-addr.arpa.
+www.ucolick.org.
+14.128.52.96.in-addr.arpa.
+maps.google.com.om.
+www.bing.com.
+70.180.57.186.in-addr.arpa.
+exch-w.atdmt.com.
+sum-tech.ru.
+docs.google.com.
+talismgmt.com.inbound10.mxlogic.net.
+rd.rlcdn.com.
+ksn2-12.kaspersky-labs.com.
+gilchristconst.com.
+www.mindvalleyhispano.com.
+pensamientoexperimental.blogspot.com.
+jasnetworks.net.
+agricol.e.telefonica.net.
+piv.pivpiv.dk.
+165.143.172.189.in-addr.arpa.
+231.179.244.190.in-addr.arpa.
+dnl-01.geo.kaspersky.com.
+cs10008.vkontakte.ru.
+www.descargar-youtube.com.
+205.22.101.99.in-addr.arpa.
+tommti-systems.de.
+m.facebook.com.
+b-0.19-220a4008.91081.1518.19d4.3ea1.410.0.j5iruwmdnhcmblwaj57k9gcj55.avqs.mcafee.com.
+www.gamesandgeeks.com.
+112.23.132.187.in-addr.arpa.
+accounts.google.com.
+71.59.52.201.in-addr.arpa.
+www.paypalobjects.com.
+www.facebook.com.
+123.130.233.189.in-addr.arpa.
+checkip.dyndns.org.
+www.igirlsgames.com.
+ns1.root.ru.
+kgiswx1bb.62gz.
+mail1.rhcc.com.
+www.facebook.com.
+nielsenfineart.com.
+profile.ak.fbcdn.net.
+assets.tumblr.com.
+support.live.com.
+profile.ak.fbcdn.net.
+coffeetime.de.
+acmilan.ru.
+www.facebook.com.
+www.etruth.com.
+a7.sphotos.ak.fbcdn.net.
+www.serviwebrd.com.
+www.hollywoodreporter.com.
+um14.eset.com.
+a.root-servers.net.
+152.67.213.83.in-addr.arpa.
+pics.haircutshairstyles.com.
+244.50.230.67.in-addr.arpa.
+gs-loc.apple.com.
+54.153.25.187.in-addr.arpa.
+ssl.gstatic.com.
+a.root-servers.net.
+diglib.auburn.edu.
+183.66.59.186.in-addr.arpa.
+recursos.fotocajon.com.
+a.root-servers.net.
+cdn-colo-ch-3.mbt.com.
+tonycolamarino.com.
+rikain.com.
+photos-a.ak.fbcdn.net.
+41-courier.push.apple.com.
+mail.ci.missoula.mt.us.
+facebook.com.
+187.204.237.64.in-addr.arpa.
+a.root-servers.net.
+pubads.g.doubleclick.net.
+ocsp.verisign.com.
+twitter.com.
+mx.suddenlink.net.
+www.cnfl.go.cr.
+www.hollywoodgothique.com.
+8.8.217.63.in-addr.arpa.
+srv.ubplastik.ru.
+email.radcliffe.in.
+ocio.superdeporte.es.
+bl148w.blu148.mail.live.com.
+yofuidel4delinea.blogspot.com.
+dns.msftncsi.com.
+mta1.am0.yahoodns.net.
+teredo.ipv6.microsoft.com.
+gamecheats.com.
+ads.adxpansion.com.
+m.addthisedge.com.
+hyp12hvotnrh14eumxp42jvozjti15mzg43c49.info.
+s.youtube.com.
+photos-a.ak.fbcdn.net.
+dc353.4shared.com.
+sup.live.com.
+g.ceipmsn.com.
+arttaste.ru.
+rivaldofans.ifrance.com.
+mail.ard-kazan.ru.
+lekstore.ru.
+k.kuwo.cn.
+photos-h.ak.fbcdn.net.
+www.microsoft.com.
+143.49.104.88.in-addr.arpa.
+yingjunjiu.deviantart.com.
+sbeton.ru.
+www.greginhollywood.com.
+fr.wikipedia.org.
+a.root-servers.net.
+pocketcents.com.
+225.154.144.189.in-addr.arpa.
+www.1channel.ch.
+aol.com.
+static-resource.np.community.playstation.net.
+99.218.23.203.in-addr.arpa.
+newswander.com.
+www.viharjelzes.hu.
+newsrss.bbc.co.uk.
+ikelite.com.
+bitly.com.
+yui.yahooapis.com.
+_carddavs._tcp.yahoo.com.
+googleads.g.doubleclick.net.
+a.root-servers.net.
+db._dns-sd._udp.enhwi-n3.
+eshops.mercadolibre.com.mx.
+mail-server2.profiseti.ru.
+www.google-analytics.com.
+hylinx.com.
+dns.msftncsi.com.
+www.facebook.com.
+nmcpas-com.mail.eo.outlook.com.
+94.51.122.190.in-addr.arpa.
+165.55.141.189.in-addr.arpa.
+email-us.huawei.com.
+maps.google.com.
+www.diablos.
+100500.tv.
+search.twitter.com.
+web1.designerapparel.com.
+230.235.148.190.in-addr.arpa.
+fe1.cgp.21ctl.com.
+travel.france24.com.
+112.230.49.190.in-addr.arpa.
+www.socialgrowthtechnologies.com.
+57.113.104.200.in-addr.arpa.
+248.101.4.189.in-addr.arpa.
+www.ooyala.com.
+www.tripadvisor.com.
+noos.fr.
+photos-a.ak.fbcdn.net.
+a.root-servers.net.
+www.google.com.
+expedia.fr.
+apps.facebook.com.
+246.129.121.189.in-addr.arpa.
+zercustoms.com.
+plus.google.com.
+gearsofwar.wikia.com.
+204.128.128.186.in-addr.arpa.
+www.gigisapparel.com.
+imgs.gamesbannernet.com.
+platform.ak.fbcdn.net.
+mx4.evzo.org.
+dns.msftncsi.com.
+ads.youmago.ro.
+apps.facebook.com.
+photos-c.ak.fbcdn.net.
+ds.addthis.com.
+yahoo.com.
+mxs.valuehost.ru.
+shout.dk.
+www.koliscar.si.
+i1.ytimg.com.
+a4.sphotos.ak.fbcdn.net.
+fb.statusking.net.
+pixel.facebook.com.
+go.microsoft.com.
+time.stdtime.gov.tw.
+riceboy.jho-tan.com.
+sblincoln.com.s8a1.psmtp.com.
+oncewest.com.
+a.root-servers.net.
+www.tia.org.
+a.collective-media.net.
+up.absba.com.
+fbcdn-photos-a.akamaihd.net.
+www.globostuky.com.ar.
+kentuckysportsradio.com.
+www.sport365.com.
+a.root-servers.net.
+www.lpdedicated.com.
+image2.tailieu.vn.
+hi-in.facebook.com.
+www.mcanime.net.
+a.root-servers.net.
+d1j68ux4ukg4g1.cloudfront.net.
+www.jscount.com.
+pruittgushee.com.
+external.ak.fbcdn.net.
+b.scorecardresearch.com.
+12173.ua.all.biz.
+100.236.67.201.in-addr.arpa.
+www.facebook.com.
+ytimg.l.google.com.
+120.148.168.192.in-addr.arpa.
+rs991l34.rapidshare.com.
+panelnaranja.rpxnow.com.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+dtboot.orbitdownloader.com.
+api.facebook.com.
+americanheritageins.com.bak-mx.na0106.smtpbak.com.
+go.srvnow.com.
+45.237.108.186.in-addr.arpa.
+pagead2.googlesyndication.com.
+www.bing.com.
+ku2.ru.
+mx.yakuel.com.
+www.toptanciyiz.net.
+api.twitter.com.
+lite.ebuddy.com.
+www.imdb.com.
+www.6565.cn.
+5w.ru.
+.
+a.root-servers.net.
+db._dns-sd._udp.0.1.168.192.in-addr.arpa.
+api.mingscape.com.
+www.cnf.gob.mx.
+2.56.230.190.in-addr.arpa.
+a.ads2.msads.net.
+laserdrive.com.s5a2.psmtp.com.
+maitlandrealty.com.
+de-de.facebook.com.
+www.expoplasticos.com.mx.
+gcp.es.
+www.legalleadersblog.com.
+freddiemqueen.forumfree.it.
+www.luifil.com.
+www.activeherb.com.
+www.facebook.com.
+www.mediafire.com.
+113.84.181.213.in-addr.arpa.
+api.viglink.com.
+www.gazetalubuska.pl.
+a7.sphotos.ak.fbcdn.net.
+photos-f.ak.fbcdn.net.
+159.177.82.177.in-addr.arpa.
+googleads.g.doubleclick.net.
+thisisf1.com.
+kokotovich.com.
+a.root-servers.net.
+_ldap._tcp.
+adf.ly.
+pt-br.facebook.com.
+mail.celebrityintl.com.
+209.187.154.186.in-addr.arpa.
+lowest-rate-loans.com.
+www.crimesofwar.org.
+19.91.248.189.in-addr.arpa.
+img.gotomeeting.com.
+53.106.235.186.in-addr.arpa.
+www.professionisti.bticino.it.
+xlqgtsk26.h17q5k2i.
+spc.edu.s10a2.psmtp.com.
+134.25.212.201.in-addr.arpa.
+195.184.142.187.in-addr.arpa.
+secure-us.imrworldwide.com.
+a5.sphotos.ak.fbcdn.net.
+www.duckload.com.
+19.237.50.96.in-addr.arpa.
+user.easyn.cn.
+52.104.172.201.in-addr.arpa.
+s-static.ak.fbcdn.net.
+3.bp.blogspot.com.
+sp.cwfservice.net.
+chicago.cbslocal.com.
+167.113.231.189.in-addr.arpa.
+clients1.google.com.
+www.facebook.com.
+neonisi.com.
+thefoodaddicts.com.
+google.com.
+rospres.com.
+166.7.216.201.in-addr.arpa.
+groups.google.com.ar.
+152.153.158.205.in-addr.arpa.
+58.255.205.186.in-addr.arpa.
+152.253.134.187.in-addr.arpa.
+t0.gstatic.com.
+sp.cwfservice.net.
+26.161.168.192.in-addr.arpa.
+support.google.com.
+202.151.249.92.in-addr.arpa.
+titanium30-en.url.trendmicro.com.
+114.208.96.174.in-addr.arpa.
+kalifbanane.deviantart.com.
+15.252.53.200.in-addr.arpa.
+smfc.thescore.com.
+www.machineryzone.es.
+ping3.teamviewer.com.
+23.59.168.192.in-addr.arpa.
+photos-e.ak.fbcdn.net.
+apps.facebook.com.
+a.root-servers.net.
+www.chicaswebcam.eu.
+96.12.214.176.in-addr.arpa.
+dgsr3tffm.f23z5d6w.
+228.10.74.180.in-addr.arpa.
+cs10030.vkontakte.ru.
+signin.ebay.com.
+theatre.ru.
+88.119.51.190.in-addr.arpa.
+www.tesolconvention.org.
+www.subiegal.com.
+spamfilter.kier.re.kr.
+creative.ak.fbcdn.net.
+www.aqps.info.
+geo.yahoo.com.
+forum.lyrsense.com.
+www.piel-sana-vida-sana.com.
+a.root-servers.net.
+www222.pair.com.
+t3.gstatic.com.
+mx1.brickit.com.
+www.yahoo.com.
+43.169.1.120.in-addr.arpa.
+touch.facebook.com.
+mail.jjranchpro.com.
+a2.sphotos.ak.fbcdn.net.
+www.facebook.com.
+www.iguoguo.net.
+www.google.com.
+nubiagroup-powerpoint-collection.blogspot.com.
+15.4.80.69.in-addr.arpa.
+221.199.105.77.in-addr.arpa.
+att-mail.com.dnsbl7.mailshell.net.
+profile.ak.fbcdn.net.
+upload.facebook.com.
+194.140.23.187.in-addr.arpa.
+mobileads.nimbuzz.com.
+mexico.ilww.com.
+musica.
+_374_14_1.
+login.live.com.
+www.gm.tv.
+www.google.es.
+mail.samui-island.ru.
+rs607l36.rapidshare.com.
+a2.sphotos.ak.fbcdn.net.
+sp.cwfservice.net.
+www.cenerick.com.ar.
+img3.teddy-girls.com.
+25.156.230.190.in-addr.arpa.
+www.solosalta.com.
+email1-east.aero.org.
+202.189.218.195.in-addr.arpa.
+c.prodigy.msn.com.
+72.100.151.67.in-addr.arpa.
+ssl.google-analytics.com.
+206.36.192.108.in-addr.arpa.
+img100.xvideos.com.
+mail.urfc.ru.
+blog.gisuser.com.
+www.factsaboutanimals.net.
+view.atdmt.com.
+108.135.138.187.in-addr.arpa.
+webres4.pand.ctmail.com.
+es-la.facebook.com.
+external.ak.fbcdn.net.
+38.15.82.200.in-addr.arpa.
+ajax.googleapis.com.
+rrcvexydh.l33z2r2a.
+flowdebarrio.com.
+dr._dns-sd._udp.lan.
+plus.google.com.
+webcache.googleusercontent.com.
+entertainer.mvourtown.com.
+www.weather.com.
+mail3.volny.cz.
+cts.channelintelligence.com.
+ts.videosz.com.
+zynga2-a.akamaihd.net.
+7.201.31.80.in-addr.arpa.
+207.172.75.190.in-addr.arpa.
+profile.ak.fbcdn.net.
+cdn-7.pics.t8premium.com.
+exch-w.atdmt.com.
+api.facebook.com.
+43.84.8.190.in-addr.arpa.
+www.broknes.net.
+photos-d.ak.fbcdn.net.
+www.shemale-comics.net.
+mail.wselectronics.com.
+industrycasting.com.au.
+bmzojkdspg.ru.
+www.goats.com.
+sagastumes.mypressonline.com.
+www.facebook.com.
+unitedtitleservices.com.inbound10.mxlogic.net.
+i1.ytimg.com.
+ns2.ulink.ru.
+227.228.59.99.in-addr.arpa.
+www.dieslermusic.com.
+ads.contentabc.com.
+gipat.ru.
+6.38.61.99.in-addr.arpa.
+swsb3guoh.g48b1g2u.
+www.youtube-nocookie.com.
+homes.onlineathens.com.
+www.facebook.com.
+www.somoto.com.
+secure-au.imrworldwide.com.
+m8fu78fnc.08vw.
+mail2.checkfree.com.
+publicstorage.com.
+dnl-01.geo.kaspersky.com.
+pop3.live.com.
+www.facebook.com.
+252.218.132.187.in-addr.arpa.
+1.3.168.192.in-addr.arpa.
+3.201.107.193.in-addr.arpa.
+graph.facebook.com.
+193.111.159.69.in-addr.arpa.
+www.hispanicmarketweekly.com.
+superdeportes.com.
+time.windows.com.
+207.12.250.189.in-addr.arpa.
+almeria.guia.hola.com.
+crashteams.com.
+s-static.ak.fbcdn.net.
+a.root-servers.net.
+a.root-servers.net.
+27.media.tumblr.com.
+atgcompanies.com.
+hoosiertimescoupons.com.
+_537_03_1.
+xslt.alexa.com.
+3.bp.blogspot.com.
+www.bing.com.
+56.132.251.190.in-addr.arpa.
+static.ak.fbcdn.net.
+212.200.249.111.in-addr.arpa.
+mirror.alfredstate.edu.
+l2.zedo.com.
+162.1.168.192.in-addr.arpa.
+nomail1.circulomexico.com.
+no.wikipedia.org.
+acsc.com.
+pattersonresearch.net.
+morganlawohio.com.
+armmf.adobe.com.
+mail.msihoa.com.
+a.root-servers.net.
+mensajesatucorazon.blogspot.com.
+hergoodybag.com.
+dnl-01.geo.kaspersky.com.
+peliculas2.com.
+external.ak.fbcdn.net.
+x439.com.
+a1725.l.akamai.net.
+90.147.219.62.in-addr.arpa.
+muzikalia.com.
+190.102.138.187.in-addr.arpa.
+e-markit.info.
+www.youtube.com.
+fandeloup.centerblog.net.
+a.root-servers.net.
+slamit.net.
+mbj.nifty.co.
+www.lacare.org.
+dnl-06.geo.kaspersky.com.
+www.firm-consult.de.
+api.conduit.com.
+213.127.122.200.in-addr.arpa.
+www.facebook.com.
+www.postcefalu.blogspot.com.
+time.chttl.com.tw.
+bg.rhenus.com.
+wpad.
+amer.rel.msn.com.
+mail.kktooldesign.com.
+71.101.197.84.in-addr.arpa.
+relay.partout.it.
+denis.stalker.h3q.com.
+search.babylon.com.
+byrnemedia.co.uk.
+unlease.ru.
+tempo.folha.com.br.
+corntoromyout.nu.
+a.root-servers.net.
+221.85.198.190.in-addr.arpa.
+check6.facebook.com.
+gfx4.hotmail.com.
+www.trisomy.org.
+iphone-wu.apple.com.
+connect.facebook.net.
+rapidshare.com.
+lh3.ggpht.com.
+images.thecandidforum.com.
+www.womensweightgain.com.
+r2now.com.
+s-static.ak.facebook.com.
+klinger.ru.
+midmaine.com.
+www.fullquimica.com.
+cs5683.vk.com.
+www.gamecetera.com.
+a3.sphotos.ak.fbcdn.net.
+waynefarms.com.
+rmd.atdmt.com.
+a.root-servers.net.
+www.facebook.com.
+profile.ak.fbcdn.net.
+www.tannan-fm.com.
+platform.twitter.com.
+cbr.digitalinsight.com.
+www.searchqu.com.
+a.root-servers.net.
+feeds.bbci.co.uk.
+_437_58_9.
+194.189.195.187.in-addr.arpa.
+jers2.info.
+blog.facebook.com.
+74.115.57.71.in-addr.arpa.
+d2095542.xoom.it.
+www.techfever.net.
+payment.6waves.com.
+pioneerelectronics.com.
+time.nist.gov.
+www.real-bikini-beach.com.
+24.69.124.189.in-addr.arpa.
+ejabat.google.com.
+support.google.com.
+mntr.babcdn.com.
+a2.sphotos.ak.fbcdn.net.
+226.59.14.195.in-addr.arpa.
+hi-in.facebook.com.
+irepvm.com.
+www.1aria.com.
+shoppas.com.
+www.laruinaoculta.com.
+ad.yieldmanager.com.
+db._dns-sd._udp.0.1.168.192.in-addr.arpa.
+203.103.105.189.in-addr.arpa.
+photos-h.ak.fbcdn.net.
+a5.sphotos.ak.fbcdn.net.
+cnnespanol.wordpress.com.
+www.salt-themovie.com.
+sherlock-holmes-nemesis.softonic.com.
+safebrowsing-cache.google.com.
+tc.v11.cache5.c.youtube.com.
+rooadrunner.com.
+google.com.
+2012taiwanlantern.net.
+adserving.cpxinteractive.com.
+cecytneza2.galeon.com.
+a.root-servers.net.
+www.vsp.state.va.us.
+assets.tumblr.com.
+i4.ytimg.com.
+www.cosmos.com.mx.
+d2054836.instant.xoom.it.
+rad.msn.com.
+img5.ranchoweb.com.
+www.blogoozle.com.
+www.adobe.com.
+cardsharing.us.
+aloha.viber.com.
+153.74.164.190.in-addr.arpa.
+alt4.gmail-smtp-in.l.google.com.
+211.50.83.62.in-addr.arpa.
+caw.ny.us.criteo.com.
+www.facebook.com.
+www.ebaygivingworks.com.
+www.turuo.com.
+sitemail.everyone.net.
+www.jvc.com.
+lb._dns-sd._udp.0.0.168.192.in-addr.arpa.
+profile.ak.fbcdn.net.
+104.146.185.190.in-addr.arpa.
+equitylinepa.com.
+apps.facebook.com.
+a4.sphotos.ak.fbcdn.net.
+fehth5u8x.83kc.
+www.google-analytics.com.
+nmusd.k12.ca.us.
+133.0.87.66.in-addr.arpa.
+a3.sphotos.ak.fbcdn.net.
+omnimetal.com.
+princesasailormoon.blogspot.com.
+www.facebook.com.
+thebilgepumps.com.
+wakefieldreutlinger.com.inbound15.mxlogic.net.
+207.109.39.190.in-addr.arpa.
+a5.sphotos.ak.fbcdn.net.
+www.dayendra.web.id.
+idreseller.ru.
+sp.cwfservice.net.
+safebrowsing.clients.google.com.
+baymsg1020431.by2.gateway.edge.messenger.live.com.
+app.net.
+router.infolinks.com.
+syndication.mmismm.com.
+www.dainbinder.com.
+224.175.150.200.in-addr.arpa.
+ad-g.doubleclick.net.
+www.adobe.com.
+104.248.204.199.in-addr.arpa.
+128.20.34.110.in-addr.arpa.
+www.4shared.com.
+www.google.com.
+aberdeen-chamber.com.
+42.49.138.98.in-addr.arpa.
+sp.cwfservice.net.
+assets1.mynewsdesk.com.
+secure.dominio.com.
+toomeycustoms.us.intellitxt.com.
+www.youtube.com.
+dbmmgt.com.
+simssoc.game.playfish.com.
+www.googleadservices.com.
+gatekeeperus.trintech.com.
+_596_67_3.
+mail.leader-panama.com.
+5ballov.com.ru.
+en.foodlexicon.org.
+a.c-0.19-250f8081.c140081.1518.19d2.3ea1.210.0.5zfq4hzzfe4k2efksc2whfpj8t.avqs.mcafee.com.
+by2msg4010610.gateway.messenger.live.com.
+mynationlink.net.
+nspmotion.com.
+173.228.225.190.in-addr.arpa.
+www.seoindonesiaku.com.
+photos-h.ak.fbcdn.net.
+cdn.api.twitter.com.
+vermeerdir.com.
+www.ticketek.com.ar.
+dr._dns-sd._udp.0.92.16.172.in-addr.arpa.
+googleads.g.doubleclick.net.
+openlead.bankimia.com.
+guestbooks.fotki.com.
+ar.answers.yahoo.com.
+apps.facebook.com.
+a6.sphotos.ak.fbcdn.net.
+126.205.52.83.in-addr.arpa.
+img39.imageshack.us.
+es1w1.tw.innogames.net.
+static.ak.facebook.com.
+246.22.139.175.in-addr.arpa.
+sro.whatsapp.net.
+www.newstyledirect.com.au.
+www.15a20.com.mx.
+www.smartbusinesscorp.com.
+www.linuxinsight.com.
+176.179.17.201.in-addr.arpa.
+myfotojournal.com.
+zynga2-a.akamaihd.net.
+crochets-emi.blogspot.com.
+166.96.86.74.in-addr.arpa.
+58.109.87.186.in-addr.arpa.
+www.autozine.org.
+ad.adtegrity.net.
+wunderlist.com.
+www.globe-info.org.
+creative.ak.fbcdn.net.
+ad.doubleclick.net.
+209.144.218.188.in-addr.arpa.
+.
+profile.ak.fbcdn.net.
+freezebomb.bigcartel.com.
+s.ytimg.com.
+www.kidsclick.com.
+151.222.165.83.in-addr.arpa.
+db._dns-sd._udp.0.1.168.192.in-addr.arpa.
+t3.tagstat.com.
+cosplay-play.blogspot.com.
+ozarkcoop.com.
+agirlsguidetoshoes.blogspot.com.
+sp.cwfservice.net.
+brap.org.uk.
+www.beachcalifornia.com.
+agtc.com.s5b2.psmtp.com.
+s-static.ak.fbcdn.net.
+photos-h.ak.fbcdn.net.
+heartbeat.belkin.com.
+photos-d.ak.fbcdn.net.
+photos-a.ak.fbcdn.net.
+career.dol.ru.
+caceres.cope.es.
+www.buruo.com.
+aspmx2.googlemail.com.
+www.revenge.com.
+rembrandts.com.
+.
+www.google.com.
+wow-recons.foroactivo.org.
+d2060296.instant.xoom.it.
+119.229.90.200.in-addr.arpa.
+155.19.25.190.in-addr.arpa.
+ads.yimg.com.
+poddonn.ru.
+77.142.56.186.in-addr.arpa.
+www.gifmania.com.co.
+dowacousticsinc.com.
+localhost.
+www.palco-vip.com.
+.
+www.tirian.com.
+a7.sphotos.ak.fbcdn.net.
+vayda.ru.
+www.bbvanetoffice.com.
+191.210.202.84.in-addr.arpa.
+apix.iminent.com.
+lampiweb.com.
+50.25.85.85.in-addr.arpa.
+ocsp.thawte.com.
+weddings.alltop.com.
+mail.bitwisepublishing.com.
+bfis.fis.ru.
+gwqsbvbnj.info.
+www.grapeshot-media.net.
+a4.sphotos.ak.fbcdn.net.
+153.133.132.217.in-addr.arpa.
+245.240.67.174.in-addr.arpa.
+8vco9o7nuj5c2siebikqjj1a53konthn-a-fc-opensocial.googleusercontent.com.
+9qrk4a9hb.u79n3m6r.
+85.243.17.198.in-addr.arpa.
+121.244.245.190.in-addr.arpa.
+i2.ytimg.com.
+s.youtube.com.
+a.root-servers.net.
+l.sharethis.com.
+forums.utherverse.com.
+www.facebook.com.
+home.live.com.
+85.229.33.201.in-addr.arpa.
+www.kaltura.com.
+winznews.blog98.fc2.com.
+ad.yieldmanager.com.
+spb.top-kniga.ru.
+s2.youtube.com.
+sp.cwfservice.net.
+static.searchya.com.
+www.rinconsantafesino.net.
+a.root-servers.net.
+67.92.81.83.in-addr.arpa.
+s.ytimg.com.
+ocsp.digicert.com.
+www.google.com.
+nioxinhair.ru.
+static.ak.fbcdn.net.
+91.224.233.118.in-addr.arpa.
+itsystemsgroup.com.s5a1.psmtp.com.
+dr._dns-sd._udp.0.0.168.192.in-addr.arpa.
+profile.ak.fbcdn.net.
+static.rpxnow.com.
+70.22.183.209.in-addr.arpa.
+a.root-servers.net.
+a8.sphotos.ak.fbcdn.net.
+186.95.2.187.in-addr.arpa.
+rs433tl4.rapidshare.com.
+gustinadvertising.net.
+186.51.171.201.in-addr.arpa.
+ad.yieldmanager.com.
+port75.mx16.sps.mxfw.net.
+u10933.29.spylog.com.
+noteprobable.com.
+ramon.rwlynch.com.
+millennianet.com.
+in.getclicky.com.
+l.yimg.com.
+login.givemepink.com.
+88.95.46.184.in-addr.arpa.
+shared.live.com.
+upmhvgmnnltgfurm.biz.
+ad.harrenmedianetwork.com.
+adserving.cpxinteractive.com.
+d2106904.xoom.it.
+thuule.pair.com.
+static.ak.fbcdn.net.
+s-static.ak.facebook.com.
+a.root-servers.net.
+time.chttl.com.tw.
+nelleke.deviantart.com.
+newversion.epyte.com.
+transitk2000.ru.
+www.googletagservices.com.
+exchange.caosco.com.
+mw.tn.ru.
+sites.google.com.
+aol.com.
+www.clickestetica.com.
+osiprint.com.
+instagr.am.
+v7.cache6.c.youtube.com.
+21.148.59.199.in-addr.arpa.
+xvizxie21.89dz.
+twitter.com.
+capitolcreag.com.
+r._dns-sd._udp.lan.
+_848_24_6.
+developers.facebook.com.
+44.20.86.186.in-addr.arpa.
+mail1.sterlingethanol.com.
+time.chttl.com.tw.
+33.103.222.189.in-addr.arpa.
+www.youtube.com.
+www.pohlarchitekten.de.
+top100sexiestwomen.com.
+platform.ak.fbcdn.net.
+accounts.google.com.
+googthis.tk.
+gfx3.hotmail.com.
+smtp2.transource.com.
+img5.xooimage.com.
+www.detikfood.com.
+s2.youtube.com.
+getprof.us.np.community.playstation.net.
+_144_55_2.
+www.institutoalma.org.
+news.google.com.mx.
+mail.indharness.com.
+26.48.173.201.in-addr.arpa.
+h.live.com.
+www.rainydaymagazine.com.
+167.131.42.201.in-addr.arpa.
+mypaleokitchen.blogspot.com.
+globalmar.ru.
+rss.allaboutwindowsphone.com.
+www.ubalert.com.
+platform.twitter.com.
+tsprints.com.
+static.ak.fbcdn.net.
+dns.msftncsi.com.
+211.188.104.189.in-addr.arpa.
+www.qwa3ed.i8.com.
+ns2.h17.domen.com.ua.
+cdn1.inner-active.mobi.
+mail.matthewbarney.com.
+flowenglish.dev01.atlanticbt.net.
+e5153.b.akamaiedge.net.
+samrphotography.blogspot.com.
+a7.sphotos.ak.fbcdn.net.
+254.52.28.186.in-addr.arpa.
+www.elprisma.com.
+mail.tpwh.com.
+photos-h.ak.fbcdn.net.
+34.132.146.186.in-addr.arpa.
+www.feriadesanmarcos.gob.mx.
+photos-f.ak.fbcdn.net.
+wj8.so-net.ne.jp.
+a749.g.akamai.net.
+www.mt-box.org.
+mail.google.com.
+216.185.186.189.in-addr.arpa.
+profile.live.com.
+247.170.13.180.in-addr.arpa.
+www.facebook.com.
+www.uisg.org.
+jack-cole.com.
+cache.pack.google.com.
+89.168.227.61.in-addr.arpa.
+216.151.152.186.in-addr.arpa.
+b._dns-sd._udp.0.0.168.192.in-addr.arpa.
+www.tormenttube.com.
+photos-d.ak.fbcdn.net.
+82.199.229.190.in-addr.arpa.
+deloitte.fr.s200b2.psmtp.com.
+221.58.139.187.in-addr.arpa.
+199.234.109.24.in-addr.arpa.
+d3lvr7yuk4uaui.cloudfront.net.
+b._dns-sd._udp.0.1.168.192.in-addr.arpa.
+bay-labels.com.
+emergency-boot-cd-rom.softonic.com.
+54.73.42.186.in-addr.arpa.
+245.149.130.189.in-addr.arpa.
+profile.ak.fbcdn.net.
+www.trampolinesystems.com.
+ecn.t2.tiles.virtualearth.net.
+170.113.92.186.in-addr.arpa.
+mail.conduit-ventures.com.
+a.i.blip.tv.
+google.com.
+v1.cache2.c.youtube.com.
+resources.search.conduit.com.
+www.urbaks.com.
+teredo.ipv6.microsoft.com.
+9ncitkxzf.27cy.
+www.l.google.com.
+www.luwaran.com.
+secure.wlxrs.com.
+jvm.ing.onored.com.
+time.nist.gov.
+mtalk.google.com.
+sites.google.com.
+_845_62_9.
+181.161.153.89.in-addr.arpa.
+mail.edu.rocmn.nl.
+104.73.156.187.in-addr.arpa.
+www.google.com.mx.
+api.conduit.com.
+massman.net.mail5.psmtp.com.
+sn1msg1010616.gateway.messenger.live.com.
+myaccount.kelloggs.com.
+210.134.253.99.in-addr.arpa.
+static.ak.fbcdn.net.
+37-courier.push.apple.com.
+www.facebook.com.
+laserhosts.com.
+webcache.googleusercontent.com.
+styleline.us.
+www.thedivinemercy.org.
+nl.vandermoolen.com.
+g.live.com.
+www.youtube.com.
+a.root-servers.net.
+onespot.wsj.com.
+photos-g.ak.fbcdn.net.
+51.157.82.189.in-addr.arpa.
+clients1.google.com.
+mx-1.naver.com.
+www.histats.com.
+www.oya-es.net.
+google.com.mx.
+ads.lfstmedia.com.
+47.95.122.84.in-addr.arpa.
+www.facebook.com.
+stats.pokerist.com.
+d2103064.xoom.it.
+clients2.google.com.
+www.4shared.com.
+s-static.ak.fbcdn.net.
+apps.facebook.com.
+ad.bannerconnect.net.
+www.lyngsat-logo.com.
+api.twitter.com.
+www.bulkblacksex.com.
+chroniclesmagazine.org.
+a6.sphotos.ak.fbcdn.net.
+www.lipdub.eu.
+ssl.gstatic.com.
+www.facebook.com.
+www.negrasdelbronx.com.
+bayfiles.com.
+a.root-servers.net.
+241.245.13.187.in-addr.arpa.
+secure.shared.live.com.
+tfgrtezqnfkewpchzgyronljweoyop.nl.
+www.egopixel.com.
+a7.sphotos.ak.fbcdn.net.
+e-2dj6aelyqgc5igp.stats.esomniture.com.
+www.howtotranslatepdf.com.
+sp.cwfservice.net.
+davainksth.ordingslil.nu.
+138.52.55.46.in-addr.arpa.
+profile.ak.fbcdn.net.
+201.95.127.93.in-addr.arpa.
+www.facebook.com.
+ctar.ru.
+pds.catholic.or.kr.
+www.naesv.org.
+download346.avast.com.
+creative.ak.fbcdn.net.
+a.root-servers.net.
+ynetnvjhr.76fz.
+blst.msn.com.
+a7.sphotos.ak.fbcdn.net.
+www.verfutbolhd.net.
+ungewitter.de.
+profile.ak.fbcdn.net.
+180.24.230.201.in-addr.arpa.
+www.fimkastore.com.
+blog.jaredcompany.com.
+secure.applifier.com.
+lb._dns-sd._udp.0.2.168.192.in-addr.arpa.
+img.movieberry.com.
+rentshark.com.
+_487_21_5.
+apis.google.com.
+101.63.253.189.in-addr.arpa.
+static.pbc.com.
+billing.sharo4ka.ru.
+prudentialcresfl.com.
+a.root-servers.net.
+photos-h.ak.fbcdn.net.
+post.telecom-f.ru.
+tuongphong2.com.
+tbr.ask.com.
+textad.xxxmatch.com.
+crl.microsoft.com.
+a.root-servers.net.
+smtp.ci.hayward.ca.us.
+ksn7.kaspersky-labs.com.
+3.146.222.189.in-addr.arpa.
+savetheroots.com.
+ads1.msads.net.
+mail1.humed.com.
+o.nimbuzz.com.
+www.airbridgecargo.com.
+themes.truethemes.net.
+www.gorestruly.com.
+themartletshospice.co.uk.
+mail.pinocchiosplace.com.
+dns.msftncsi.com.
+a.root-servers.net.
+time.windows.com.
+www.esmusicagratis.com.
+siemens.co.
+profootball.scout.com.
+winmedms.com.
+63.251.229.190.in-addr.arpa.
+a3.sphotos.ak.fbcdn.net.
+cdn.publicidad.net.
+81.146.192.187.in-addr.arpa.
+mail.welhuis.com.
+teamdemilovatoptonatales.blogspot.com.
+c-0.19-430cc069.20001.1518.19d3.2f4a.210.0.j8sccva3btb8ua63e31zf9hgtj.avqs.mcafee.com.
+.
+mksol.dseg.ti.com.
+248.225.45.93.in-addr.arpa.
+101.16.109.83.in-addr.arpa.
+mail.trufina.com.
+titanium30-en.url.trendmicro.com.
+foreveryounglala.wordpress.com.
+external.ak.fbcdn.net.
+divinecnatraining.com.
+rad.msn.com.
+weather.services.conduit.com.
+a-0.19-a309e081.c0b0082.1518.19d2.3ea1.210.0.f6gh2675ft2wdhqj6nbmrsj136.avqs.mcafee.com.
+38.249.10.186.in-addr.arpa.
+profile.ak.fbcdn.net.
+federaldirect.net.
+56nq4nu82.87ba.
+_758_24_0.
+122.204.222.201.in-addr.arpa.
+www.aving.co.kr.
+cdn.applifier.com.
+www.yahoo.com.
+249.95.51.201.in-addr.arpa.
+mxs.mail.ru.
+www.facebook.com.
+ak.imgfarm.com.
+safebrowsing.clients.google.com.
+dns.msftncsi.com.
+mscrl.microsoft.com.
+92.215.159.189.in-addr.arpa.
+248.248.115.85.in-addr.arpa.
+www.facebook.com.
+cu018.www.duba.net.home.
+197.185.150.189.in-addr.arpa.
+profile.ak.fbcdn.net.
+a8.sphotos.ak.fbcdn.net.
+accounts.google.com.
+adfarm.mediaplex.com.
+imap.mail.yahoo.com.
+download.windowsupdate.com.
+www.goldenchile.cl.
+123.186.172.178.zz.countries.nerd.dk.
+www.confezionicrosby.com.
+s.ytimg.com.
+blog.iconshock.com.
+www.interbiu.com.
+soundcloud.tumblr.com.
+ic.tynt.com.
+a.root-servers.net.
+www.belkin.com.
+static.ak.fbcdn.net.
+grc.mx.
+nypd.org.
+166.251.182.95.in-addr.arpa.
+_558_82_9.
+tools.google.com.
+229.219.250.190.in-addr.arpa.
+platform.ak.fbcdn.net.
+ad-emea.doubleclick.net.
+checkip.dyndns.org.
+crl.microsoft.com.
+209.127.47.190.in-addr.arpa.
+reedbusiness.com.au.
+newtoseeblog.info.
+ad.yieldmanager.com.
+id.google.com.
+www.google.com.
+xwjdciibb.99yy.
+c14.zedo.com.
+vmwebfe.voice.yahoo.com.
+bfrwkzqj.info.
+ksn3-11.part1.kaspersky-labs.com.
+144.220.68.99.in-addr.arpa.
+jarvis.net.
+lpi.msk.su.
+s348256632.mialojamiento.es.
+pool.ntp.org.
+a771.da1.akamai.net.
+197.35.214.67.in-addr.arpa.
+a.root-servers.net.
+234.193.121.95.in-addr.arpa.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+m.addthisedge.com.
+www.google-analytics.com.
+60.66.226.189.in-addr.arpa.
+129.157.221.108.in-addr.arpa.
+htmlbook.ru.
+api-read.facebook.com.
+80.34.251.201.in-addr.arpa.
+blufiles.storage.msn.com.
+businessplus.com.
+195.2.0.192.in-addr.arpa.
+mail.eidnet.org.
+zqvxxwkwh.q11p1a3r.
+dns.msftncsi.com.
+fgb.net.s5a2.psmtp.com.
+139.122.196.190.in-addr.arpa.
+a.root-servers.net.
+2.159.169.189.in-addr.arpa.
+6.101.138.187.in-addr.arpa.
+yahoo.com.
+lobnya.ru.
+www.acubens.com.ar.
+external.ak.fbcdn.net.
+www.ngopulse.org.
+z5hbstzvi.82en.
+www.big-pub.com.
+113.128.177.190.in-addr.arpa.
+msc.wlxrs.com.
+politicalinsider.com.
+i1.ytimg.com.
+www.juaneslavagalan.com.
+presentesausencias.blogspot.com.
+support.google.com.
+235.247.137.189.in-addr.arpa.
+www.crouzet.com.
+photos-b.ak.fbcdn.net.
+inbound.deck2.com.netsolmail.net.
+haefeles.com.
+i4.ytimg.com.
+0-ie-w.channel.facebook.com.
+commons.wikimedia.org.
+157.114.25.89.in-addr.arpa.
+mailsputnik.mail.ru.
+time.windows.com.
+mail.columbus.rr.com.lan.
+s.ytimg.com.
+msn.com.
+login.yahoo.com.
+popdynamite.com.
+www.myshoptoday.co.za.
+nylim.com.
+a.root-servers.net.
+gccnj.edu.
+creative.ak.fbcdn.net.
+mor3ben.com.
+creative.ak.fbcdn.net.
+teredo.ipv6.microsoft.com.
+116s.pl.
+www.leeyora.com.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+tdy.prodigy.msn.com.
+58.116.4.24.in-addr.arpa.
+www.casadellibro.com.
+16.134.234.190.in-addr.arpa.
+dns.msftncsi.com.
+w88.go.com.
+166.93.209.201.in-addr.arpa.
+merck.websitesampling.com.
+dns.msftncsi.com.
+www4.esu.edu.
+sn3.mailshell.net.
+profile.ak.fbcdn.net.
+rdee-ont.ca.
+plus.google.com.
+isatap.domain.name.
+a6.sphotos.ak.fbcdn.net.
+www.facebook.com.
+www.facebook.com.
+100.16.109.186.in-addr.arpa.
+s-static.ak.fbcdn.net.
+www.ehas.org.
+sn3.mailshell.net.
+es.lanoire.wikia.com.
+www.facebook.com.
+www.syfyuniversal.es.
+ceups.contabilidad.unmsm.edu.pe.
+c-0.19-23098481.483.1518.19d4.3ea1.410.0.l6rt2gtgmcst4e8d6pu8zqmhrb.avqs.mcafee.com.
+web.knotice.com.
+parana2003.galeon.com.
+28.71.68.201.in-addr.arpa.
+mail.g-ss.ru.
+_ldap._tcp.
+d3lvr7yuk4uaui.cloudfront.net.
+104.31.39.187.in-addr.arpa.
+gateway.messenger.hotmail.com.
+windsongtherapy.com.
+handwriting.shuru.qq.com.
+a8.sphotos.ak.fbcdn.net.
+a7.sphotos.ak.fbcdn.net.
+clarkstonconsulting.com.mail10.psmtp.com.
+tools.google.com.
+mnpsmail2.nashville.gov.
+user.baofeng.com.
+i1.ytimg.com.
+i5.createsend4.com.
+a2.sphotos.ak.fbcdn.net.
+static11.juegosoka.com.
+i1.ytimg.com.
+a.root-servers.net.
+platform.ak.fbcdn.net.
+www.getfoundingoogle.com.au.
+worldpress.org.
+apps.facebook.com.
+toolbarqueries.google.com.
+www.telenovelasgratis.com.
+blogger-loader.googlecode.com.
+akvamarin.ru.
+jiandan3.34245.com.
+imagenarium.ru.
+224.199.218.83.in-addr.arpa.
+2.61.204.72.in-addr.arpa.
+rt.legolas-media.com.
+fbcdn-profile-a.akamaihd.net.
+convad.net.
+putty.softonic.de.
+widenetwork.ning.com.
+254.74.134.189.in-addr.arpa.
+a5.sphotos.ak.fbcdn.net.
+ksn2-12.kaspersky-labs.com.
+xvideos-738.vo.llnwd.net.
+www.latribunadelahistoria.es.
+aptoverde.info.
+developers.facebook.com.
+manta.harrisinteractive.com.
+www.youtube.com.
+a3.sphotos.ak.fbcdn.net.
+everythingtoshare.com.
+sogospel.com.
+dns.msftncsi.com.
+suddenlink.net.
+a.root-servers.net.
+doomadgee.qld.gov.au.
+thumbs4.ebaystatic.com.
+support.game321.com.
+a995.mm1.akamai.net.
+248.30.252.189.in-addr.arpa.
+toolbarqueries.google.com.
+api.configar.org.
+a5.sphotos.ak.fbcdn.net.
+90.129.68.189.in-addr.arpa.
+voxgraeca.blogspot.com.
+www.oldnavy.gap.com.
+73.63.122.186.in-addr.arpa.
+teredo.ipv6.microsoft.com.
+205.43.233.189.in-addr.arpa.
+www.skills2lead.com.
+google.com.
+quincyrehab.com.
+docs.google.com.
+www.ocsmedia.net.
+a.root-servers.net.
+fbcdn-profile-a.akamaihd.net.
+91.243.77.190.in-addr.arpa.
+a6.sphotos.ak.fbcdn.net.
+97.221.10.187.in-addr.arpa.
+yahoo.match.com.
+a4.sphotos.ak.fbcdn.net.
+198.148.240.111.in-addr.arpa.
+www.imakenews.com.
+www.miniclip.co.
+www.msftncsi.com.
+boards.gandreas.com.
+armdl.adobe.com.
+scullypacking.com.
+mint.yes.fm.
+zynga2-a.akamaihd.net.
+www.nethunter.cl.
+reedbusiness.com.au.
+p05-bookmarks.icloud.com.
+www.orlworld.com.
+a.root-servers.net.
+hook.yieldbuild.com.
+152.41.215.189.in-addr.arpa.
+thirdmaritime.com.
+a.root-servers.net.
+es-es.facebook.com.
+118.114.233.190.in-addr.arpa.
+www.ciudadaniaestudiantil.com.
+www.torrenteros.org.
+yamaguchi-u.ac.jp.
+www.update.microsoft.com.
+www.youtube.de.
+52.132.97.212.in-addr.arpa.
+www.isidrosobrino.com.
+nendo.softonic.com.
+pagead2.googlesyndication.com.
+_876_98_3.
+www.uptodown.com.
+235.225.166.189.in-addr.arpa.
+stlamerican.com.
+r._dns-sd._udp.0.10.168.192.in-addr.arpa.
+art.123seguro.com.ar.
+crl.microsoft.com.
+a.root-servers.net.
+photos-b.ak.fbcdn.net.
+mx01.pathcom.com.
+messiahmauldin.org.
+sn104w.snt104.mail.live.com.
+db._dns-sd._udp.0.1.168.192.in-addr.arpa.
+www.update.microsoft.com.
+www.slideshare.net.
+www.ptdf.org.mx.
+auto.drom.ru.
+platform.ak.fbcdn.net.
+pagead2.googleadservices.com.
+imp.ad-plus.cn.
+a2.sphotos.ak.fbcdn.net.
+www.facebook.com.
+169.29.58.186.in-addr.arpa.
+p.visualrevenue.com.
+groups.google.com.mx.
+webcache.googleusercontent.com.
+46.16.49.190.in-addr.arpa.
+extendedvision.com.au.
+a.root-servers.net.
+midmac.net.
+zbar.zynga.com.
+198.179.0.201.in-addr.arpa.
+203.238.228.190.in-addr.arpa.
+b._dns-sd._udp.lan.
+www.symantec.com.
+www.adobe.com.
+255.162.140.120.in-addr.arpa.
+fb-zc1.cityville.zynga.com.
+tock.usno.navy.mil.
+ssibr.com.
+i7.tagstat.com.
+ci.camas.wa.us.
+a4.sphotos.ak.fbcdn.net.
+127.0.0.1.
+lb._dns-sd._udp.lan.
+photos-f.ak.fbcdn.net.
+bernco.com.
+5aawh4y3x.v08r7e0m.
+googleads.g.doubleclick.net.
+megaasesoriainmobiliaria.blogdiario.com.
+a.root-servers.net.
+appsmetadata.toolbar.conduit-services.com.
+ifw.com.
+s-static.ak.facebook.com.
+153.21.83.201.in-addr.arpa.
+comtonduling.com.
+proof.hsifin.com.
+efd8zvfdi.78jy.
+www.toneitupdiet.com.
+www.sportdiver.com.
+www.madison.k12.wi.us.
+mini5.opera-mini.net.
+dwuinc.com.pri-mx.na0109.smtproutes.com.
+158.66.55.174.in-addr.arpa.
+ad.adtegrity.net.
+google.com.
+mail.co.wayne.ny.us.
+ogo9mh::a.52vn.
+dl3.avgate.net.
+platform.ak.fbcdn.net.
+203.94.77.190.in-addr.arpa.
+wpad.
+devilon-m.msk.ru.
+iliack4mr.s63j6v7y.
+azloans4you.com.
+s9.addthis.com.
+a3.twimg.com.
+google.com.
+suffragan.com.
+11.25.69.189.in-addr.arpa.
+dingtao333.3322.org.
+pattencpa.net.
+callofduty.filefront.com.
+mmaweekly.performancemma.com.
+218.196.173.119.in-addr.arpa.
+.
+dss1.siteadvisor.com.
+v-lazer.magadan.ru.
+r.admob.com.
+ctcn.com.
+mail.jbl1.com.
+external.ak.fbcdn.net.
+51.137.91.95.in-addr.arpa.
+c33.ru.
+thumbs3.ebaystatic.com.
+www.facebook.com.
+jedineka.com.
+www.facebook.com.
+mail.mailcontractors.com.
+mail2.dahlmotors.com.
+23.229.171.69.in-addr.arpa.
+em.adpro-ads.com.
+dns.msftncsi.com.
+a7.sphotos.ak.fbcdn.net.
+www.vipstreamservice.com.
+mail.e-salt.ru.
+ax.init.itunes.apple.com.
+a.root-servers.net.
+www.onlinedatingsafetytips.com.
+rv.coupish.com.
+230.173.49.190.in-addr.arpa.
+nutzworld.com.
+109.179.164.186.in-addr.arpa.
+static.jisiklog.com.
+colegioelhayaenglishcorner.blogspot.com.
+www.fal.com.co.
+6.96.84.200.in-addr.arpa.
+m.addthisedge.com.
+goodsonauto.com.
+46.158.76.188.in-addr.arpa.
+a7.sphotos.ak.fbcdn.net.
+de-de.facebook.com.
+a.root-servers.net.
+73.24.144.189.in-addr.arpa.
+search.iminent.com.
+196.237.235.201.in-addr.arpa.
+teredo.ipv6.microsoft.com.
+a1051.b.akamai.net.
+db._dns-sd._udp.0.1.168.192.in-addr.arpa.
+www.enladisco.com.
+localhost.
+apps.facebook.com.
+_075_21_2.
+cdn.api.twitter.com.
+c0013512.r32.cf1.rackcdn.com.
+54.63.73.46.in-addr.arpa.
+218.166.36.114.in-addr.arpa.
+www.ncbi.nlm.nih.gov.
+api.twitter.com.
+voipc.sip.yahoo.com.
+fbcdn-profile-a.akamaihd.net.
+static.ak.fbcdn.net.
+a.root-servers.net.
+careers.digitaldomain.com.
+www.29arabicletters.com.
+a.root-servers.net.
+87.25.65.93.in-addr.arpa.
+relay.voice.messenger.msn.com.
+e2756.b.akamaiedge.net.
+www.torquecars.com.
+mx.images.search.yahoo.com.
+u:ym6bwws.v62b7m9d.
+44.207.72.84.in-addr.arpa.
+dns.msftncsi.com.
+www.gronkcomic.com.
+m.addthisedge.com.
+time.chttl.com.tw.
+photos-b.ak.fbcdn.net.
+www.planning.wa.gov.au.
+bicentenario.unc.edu.ar.
+decorarts.files.wordpress.com.
+cdn.viglink.com.
+www.telegraph.co.uk.
+152.246.171.24.in-addr.arpa.
+52.21.129.158.in-addr.arpa.
+pbimail3.prodigy.net.
+17.192.177.190.in-addr.arpa.
+a.root-servers.net.
+baade.dba.dk.
+aspelle.com.
+www.turkodesigns.com.
+a1.twimg.com.
+220.241.152.187.in-addr.arpa.
+mail.sportsonesource.com.
+mx1.grattanproperty.com.
+71.193.34.60.in-addr.arpa.
+s.ytimg.com.
+www.blogazos.com.
+2.13.111.189.in-addr.arpa.
+www.bullsfloor.com.
+231.199.201.190.in-addr.arpa.
+228.94.55.174.in-addr.arpa.
+m.xp1.ru4.com.
+ib.adnxs.com.
+113.191.15.189.in-addr.arpa.
+a.root-servers.net.
+localhost.
+a.blip.tv.
+164.3.226.190.in-addr.arpa.
+mail.kroog.ru.
+secure.fishgame3d.com.
+7xko:62o9.15gk.
+www.honeybee.com.au.
+outreachconnect.org.
+a.l.yimg.com.
+2.19.149.186.in-addr.arpa.
+www.styleandpepperblog.com.
+anycast-europe.quantserve.com.akadns.net.
+www.apple.com.
+smilesandflirts.com.
+29.26.109.84.in-addr.arpa.
+s1-word-edit.vo.msecnd.net.
+a.root-servers.net.
+a4.sphotos.ak.fbcdn.net.
+apps.facebook.com.
+yahoo.com.
+191.146.122.77.in-addr.arpa.
+es.elderscrolls.wikia.com.
+scribe.twitter.com.
+msgr.updates.yahoo.com.
+wsoulrc.com.
+www.14ers.com.
+www.google-analytics.com.
+google.com.
+9h371za7k.84ml.
+www.youtube.com.
+agothsphere.com.
+consumerone.com.
+www.ziaruldebacau.ro.
+connect.facebook.net.
+wfa4l9tu2.35sk.
+_855_17_2.
+a.root-servers.net.
+www.realgirlglam.com.
+storage.store2phone.com.
+www.cheapnbajerseys.biz.
+newsrss.bbc.co.uk.
+amer.rel.msn.com.
+blogdelfuturo.com.
+verybigdays.net.
+sulima.org.
+a.root-servers.net.
+8nl1r99e6.r35f1v6r.
+tr.com.s5a2.psmtp.com.
+myallamericanlending.com.
+doug1izaerwt3.cloudfront.net.
+images.nokiagate.com.
+2.71.155.189.in-addr.arpa.
+cf.addthis.com.
+ma156-r.analytics.edgesuite.net.
+mail.thefrontierproject.com.
+googleads.g.doubleclick.net.
+m.facebook.com.
+cz-user.he.cninfo.net.
+a.root-servers.net.
+news.kmdevantagens.com.br.
+www.uvvu.com.
+profile.ak.fbcdn.net.
+static.ak.fbcdn.net.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+moddys.com.
+p18-buy.itunes.apple.com.
+www.layeredtech.com.
+rs3.scribd.com.
+pds2.miclub.com.
+158.121.12.86.in-addr.arpa.
+graph.facebook.com.
+a.root-servers.net.
+celinedion.com.
+www.clubsnap.com.
+ad.yieldmanager.com.
+photos-f.ak.fbcdn.net.
+adserving.cpxinteractive.com.
+peloterotv.blogspot.com.
+251.25.111.95.in-addr.arpa.
+www.arcatapet.com.
+static.xvideos.com.
+profile.ak.fbcdn.net.
+b.scorecardresearch.com.
+www.facebook.com.
+a.root-servers.net.
+c-0.19-a309f481.20483.1518.19d4.3ea1.410.0.7mq42g1burzz6enmpeuv8t3lh5.avqs.mcafee.com.
+boi.perfectworld.com.
+www.moviereplicasdirect.com.
+a7.sphotos.ak.fbcdn.net.
+th07.deviantart.net.
+mec.deviantclip.com.
+a.root-servers.net.
+syncservices.me.com.
+2.0.168.192.in-addr.arpa.
+102.226.32.177.in-addr.arpa.
+www.facebook.com.
+yui.yahooapis.com.
+a.root-servers.net.
+www.l.google.com.
+img.msg.yahoo.com.
+32.127.71.86.in-addr.arpa.
+update.sanasecurity.com.
+180.175.168.192.in-addr.arpa.
+p50-buy.itunes.apple.com.akadns.net.
+www.conduit.com.
+cdn2.grupos.emagister.com.
+secure.wlxrs.com.
+a5.sphotos.ak.fbcdn.net.
+external.ak.fbcdn.net.
+clients2.google.com.
+15minutefashion.about.com.
+sp.cwfservice.net.
+61.164.34.189.in-addr.arpa.
+www.stormwise.com.
+ebookbrowse.com.
+onsenjikan.dreamwidth.org.
+www.google.com.
+4.bp.blogspot.com.
+creative.ak.fbcdn.net.
+photos-b.ak.fbcdn.net.
+84.223.160.187.in-addr.arpa.
+lh4.ggpht.com.
+www.l.google.com.
+beta.stun.voice.yahoo.com.
+xowneisrh.h25d6r7s.
+mx2.actsyuma.net.
+_524_58_5.
+www.msanet.com.mx.
+www.adobe.com.
+114.241.225.190.in-addr.arpa.
+a.root-servers.net.
+www.4shared.com.
+a.root-servers.net.
+auth.leonardo.it.
+mmorales.diarioeldia.cl.
+gateway.messenger.hotmail.com.
+ads.yimg.com.
+www.sickbeard.com.
+profile.ak.fbcdn.net.
+photos-a.ak.fbcdn.net.
+140.140.134.186.in-addr.arpa.
+reviews.singerco.com.
+118.188.189.78.in-addr.arpa.
+tc21.easythumbhost.com.
+fbcdn-profile-a.akamaihd.net.
+directory.services.live.com.
+99.139.175.189.in-addr.arpa.
+6.123.30.189.in-addr.arpa.
+console-ssl.service.playfish.com.
+pixel.mathtag.com.
+a.root-servers.net.
+ocsp.verisign.com.
+a.root-servers.net.
+128.38.110.189.in-addr.arpa.
+ydyb7ga1u.g11y8v8k.
+18.185.233.94.in-addr.arpa.
+www.euroresidentes.com.
+rs667tl2.rapidshare.com.
+46.201.173.190.in-addr.arpa.
+47.28.158.17.in-addr.arpa.
+a7.sphotos.ak.fbcdn.net.
+107.224.225.190.in-addr.arpa.
+essalud.gob.pe.
+directfurniture.com.
+a5.sphotos.ak.fbcdn.net.
+egate.net56.com.
+photos-a.ak.fbcdn.net.
+articulossobrebelleza.blogspot.com.
+a.root-servers.net.
+u20.eset.com.
+ejabat.google.com.
+gd5.ru.
+242.248.130.186.in-addr.arpa.
+47.198.78.189.in-addr.arpa.
+fbcdn-profile-a.akamaihd.net.
+250.207.167.190.in-addr.arpa.
+wallst.jpmorganchase.com.
+39.200.209.201.in-addr.arpa.
+1internet.com.
+eset-la.com.dnsbl7.mailshell.net.
+a.root-servers.net.
+www.lfpslebanon.com.
+_ldap._tcp.
+clients4.google.com.
+158.90.127.201.in-addr.arpa.
+crl.microsoft.com.
+webcache.googleusercontent.com.
+a8.sphotos.ak.fbcdn.net.
+smtp.wanadoo.fr.
+photos-c.ak.fbcdn.net.
+vofydac.com.
+admin.loading321.com.
+ciitlahore.edu.pk.
+flol.sabayacafe.com.
+thefluffingtonpost.com.
+asamblea.gob.ni.
+www.argladou.com.
+19.248.90.187.in-addr.arpa.
+ksn1-11-part2.kaspersky-labs.com.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+_790_26_3.
+adamwhiles.com.
+ssl.gstatic.com.
+cyberrelief.com.
+assets3.castle.zgncdn.com.
+61.5.157.201.in-addr.arpa.
+194.205.232.76.in-addr.arpa.
+251.91.106.200.in-addr.arpa.
+log.video.mail.ru.
+175.82.137.201.in-addr.arpa.
+australia.urbansketchers.org.
+124.156.181.175.in-addr.arpa.
+midi-pyrenees.cci.fr.
+crimecitymafiacodes.com.
+242.152.161.142.in-addr.arpa.
+ph9rfx8j6.13ni.
+radar.cedexis.com.
+142.149.106.85.in-addr.arpa.
+112.125.168.192.in-addr.arpa.
+js.admeld.com.
+bridge1.admarketplace.net.
+thumbs.hotmature.in.
+248.41.52.186.in-addr.arpa.
+gilat.com.
+cdn.api.twitter.com.
+clat99yq7.k30g3x3d.
+lsum.com.
+www.getansweronline.com.
+xxlcc.com.
+jbjs.org.
+www.cag.es.
+a.root-servers.net.
+prudentialatlantic.com.
+photos-a.ak.fbcdn.net.
+36c:a7gcs.l56k5z0d.
+227.137.19.189.in-addr.arpa.
+creative.ak.fbcdn.net.
+m78mnt884.96ig.
+login.only10.com.
+_746_57_9.
+g.msn.com.
+vp.sip.messenger.msn.com.
+www.kitcosilver.com.
+ads.neighborhoodnotes.com.
+ejkbi2tdz.f31m9l0f.
+a.root-servers.net.
+personalitypedagogy.arcadia.edu.
+profile.ak.fbcdn.net.
+p9u.ru.
+a.root-servers.net.
+245.104.131.41.in-addr.arpa.
+mtalk.google.com.
+makemeunder.blogspot.com.
+50cubes-a.akamaihd.net.
+photos-f.ak.fbcdn.net.
+www.socialgrowthtechnologies.com.
+shared.live.com.
+googleads.g.doubleclick.net.
+external.ak.fbcdn.net.
+p072.ezboard.com.
+227.47.106.27.in-addr.arpa.
+photos-a.ak.fbcdn.net.
+cta-service.cms.hubspot.com.
+a1.sphotos.ak.fbcdn.net.
+.
+jcqkm:zim.80db.
+10.img.v4.skyrock.net.
+cs12814.vk.com.
+blog.facebook.com.
+169.webim0214.webim.myspace.com.
+www.webcamxtc.com.
+mail.twobest.com.
+mn.com.
+www.av.com.
+photos-b.ak.fbcdn.net.
+34.243.35.187.in-addr.arpa.
+time.windows.com.
+_978_73_3.
+googleads.g.doubleclick.net.
+a.root-servers.net.
+36.138.91.186.in-addr.arpa.
+www.buzzbinmagazine.com.
+udencuar.com.domain_not_set.invalid.
+advisor.fidelity.com.
+dvln.com.
+tvwebfamosos.blogspot.com.
+a.root-servers.net.
+55.187.24.201.in-addr.arpa.
+fthr.com.s7b2.psmtp.com.
+www.20min.ch.
+d15gt9gwxw5wu0.cloudfront.net.
+a-0.19-a20fd081.a060131.1518.19d4.3ea1.410.0.555215vife6tps7czkhjhiiz15.avqs.mcafee.com.
+ubst.dk.
+29.159.209.190.in-addr.arpa.
+www.thughunter.com.
+www.liveroof.com.
+172.50.189.201.in-addr.arpa.
+ksn1-11-part2.kaspersky-labs.com.
+c.lomadee.com.
+www.italianmoda.com.es.
+www.google.com.
+ad-g.doubleclick.net.
+apps.facebook.com.
+www.whyimcatholic.com.
+254.70.51.173.in-addr.arpa.
+www.youtube.com.
+www.frivy8games.com.
+twitter.com.
+cfpinsurance.com.
+s.youtube.com.
+relay.i-gorod.com.
+developers.facebook.com.
+xf:riuj5v.c97d6b9c.
+boss.com.s201a1.psmtp.com.
+stats.buysellads.com.
+mail.disneinc.com.
+lh5.googleusercontent.com.
+mail.scalando.com.
+www.findtubes.com.
+helifax-web.com.
+c2i.net.
+sullana.amarillasperu.net.
+www.facebook.com.
+i2.ytimg.com.
+cgil.brescia.it.
+d261sv3xac0f7i.cloudfront.net.
+ad.foxnetworks.com.
+www.galleries.lilkelly.com.
+craftsmanmold.com.2.arsmtp.com.
+ece.uic.edu.
+231.119.105.190.in-addr.arpa.
+musica.itematika.com.
+www.customquillingbydenise.com.
+a.root-servers.net.
+rbscorp.net.
+www.facebook.com.
+www.aspaym.org.
+cshoppingbox.partner.leguide.com.
+cuttingnyc.com.
+protesen.dk.
+clicktrack3.ziyu.net.
+loading.widdit.com.
+amserv.ru.
+1klik.com.
+v14.nonxt3.c.bigcache.googleapis.com.
+36.0.108.116.in-addr.arpa.
+safepla.net.
+weather.service.msn.com.
+csi.gstatic.com.
+bc41b2bjhrjwem9m6m9d3dll3t.hop.clickbank.net.
+mail2.digitalfoundation.net.
+platform.ak.fbcdn.net.
+tallerdeelectricidadelespinillo.blogspot.com.
+www.youtube.com.
+m.addthisedge.com.
+a.root-servers.net.
+i.dailymail.co.uk.
+a.root-servers.net.
+j.local.
+smith-gibson.com.
+jcenter.ru.
+smgplaw.com.s5a2.psmtp.com.
+amsystem.es.
+254.141.234.189.in-addr.arpa.
+bcp.crwdcntrl.net.
+www.metainstaller.com.
+yahoo.com.
+228.77.250.189.in-addr.arpa.
+apis.google.com.
+b3.123show.com.
+mail1.bagroup.com.
+mail.sendero.cl.
+www.numberjacks.co.uk.
+www.lenodown.com.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+4cventures.com.
+d:6pmofe7.l39g0z0b.
+s-static.ak.fbcdn.net.
+a6.sphotos.ak.fbcdn.net.
+relay3.aeroflot.ru.
+www.youtube.com.
+a.root-servers.net.
+www.snoopdogg.com.
+2.6.167.213.in-addr.arpa.
+safebrowsing.clients.google.com.
+211.42.134.188.in-addr.arpa.
+0-250.channel.facebook.com.
+stoke.gov.uk.
+199.47.159.189.in-addr.arpa.
+api.facebook.com.
+www.buenastareas.com.
+5.50.220.189.in-addr.arpa.
+www.vestirjogos.com.
+uni-sys.com.inbound15.mxlogic.net.
+photos-f.ak.fbcdn.net.
+api-read.facebook.com.
+a.root-servers.net.
+safebrowsing-cache.google.com.
+cyclope.auto-futura.ru.
+80.16.118.187.in-addr.arpa.
+71.25.92.86.in-addr.arpa.
+pagead2.googlesyndication.com.
+inbound.adamtravel.net.netsolmail.net.
+www.pcpowerspeed.com.
+alyrica.net.
+blogcindad.com.
+www.ectaco-store.com.
+ja-jp.facebook.com.
+a1725.l.akamai.net.
+www.librosgratisweb.com.
+performersoft.s3.amazonaws.com.
+paragonrea.com.s9b2.psmtp.com.
+246.112.159.78.in-addr.arpa.
+pagead2.googlesyndication.com.
+pop3.sitek.net.
+twitter.com.
+www.google.com.
+mx2.luukku.com.
+www.caciquecapoeira.com.
+www.kissafattie.com.
+www.hugetitspicture.com.
+8.150.93.201.in-addr.arpa.
+bosonweb.com.
+www.mercurynews.com.
+pubmirrors.reflected.net.
+apps.facebook.com.
+a.rad.msn.com.
+0-jj-w.channel.facebook.com.
+mobile.twitter.com.
+weima.com.
+static.ak.fbcdn.net.
+orig-10006.europapress.cotcdn.net.
+6-0.qlty.finarea.ch.
+v18.ou.sdo.com.
+fitocracy.com.
+widgets.amung.us.
+www.facebook.com.
+fbcdn-profile-a.akamaihd.net.
+tinhoc.net.vn.
+alt1.v6.cache5.c.pack.google.com.
+176.237.240.210.in-addr.arpa.
+plaza1.net.
+www.google.com.
+a.root-servers.net.
+www.towing.co.uk.
+twitter.com.
+arkitekt-christiansen.dk.
+gramafacil.softonic.com.
+plus.google.com.
+www.cam4premium.com.
+a1.sphotos.ak.fbcdn.net.
+p99-imap.mail.me.com.
+fimm4825d.v41j1m1a.
+215.80.170.201.in-addr.arpa.
+16.147.220.66.in-addr.arpa.
+coronadopaint.com.
+developers.facebook.com.
+www.biodegradable.com.mx.
+appsec.eniro.com.
+adokin66.blogspot.com.
+www.musicsonglyrics.com.
+mail2.martinyale.com.
+www.michael-pratt.com.
+ads.mopub.com.
+253.24.71.75.in-addr.arpa.
+nglgdczcxk.net.
+108.241.143.201.in-addr.arpa.
+208.136.115.186.in-addr.arpa.
+disneyland.disney.go.com.
+www.script-tutorials.com.
+dns.msftncsi.com.
+www.decoz.com.
+profile.ak.fbcdn.net.
+manualidades.chiquipedia.com.
+photos-d.ak.fbcdn.net.
+mx2.kulturit.no.
+136.234.251.189.in-addr.arpa.
+heroesxsiempre.wordpress.com.
+www.yolandaadamslive.com.
+_031_71_4.
+vmtubes.com.br.
+winwin.ift.fr.
+casema.nl.
+a3.sphotos.ak.fbcdn.net.
+photos-f.ak.fbcdn.net.
+parishilton.fansitio.com.
+checkip.dyndns.org.
+www.google.com.
+l.yimg.com.
+photos-a.ak.fbcdn.net.
+mailer.cherus.ru.
+rus-reshenie.ru.
+sentimientos-leydy1006.blogspot.com.
+photos-d.ak.fbcdn.net.
+devices.live.com.
+3yqrensot.15ci.
+157.246.250.201.in-addr.arpa.
+ssl.gstatic.com.
+accounts.google.com.
+www.nobelcom.com.
+www.google.com.
+r1rk9np7bpcsfoeekl0khkd2juj27q3o-a-fc-opensocial.googleusercontent.com.
+darkesthourmovie.com.
+nspmotion.com.
+fbcdn-profile-a.akamaihd.net.
+www.geosyr.com.ar.
+mail.yimg.com.
+www.explorenaples.com.
+photos-d.ak.fbcdn.net.
+love.zinzanni.org.
+api2.4shared.com.
+gfx4.hotmail.com.
+creative.ak.fbcdn.net.
+appad.gamevil.com.
+school.net.
+collector7.netgamesusa.com.
+www.manosegunda.com.mx.
+www.gomestic.com.
+gdyn.cnn.com.
+a.root-servers.net.
+3dprinters.ru.
+20minutos.feedsportal.com.
+api.webrep.avast.com.
+roland-oldala.mindenkilapja.hu.
+caps.fool.com.
+jjo.ru.
+_065_35_0.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+a3.twimg.com.
+cville.net.
+developers.facebook.com.
+safebrowsing.clients.google.com.
+acoustica.softonic.com.
+profile.ak.fbcdn.net.
+pop3.live.com.
+messagebusiness.ru.
+143.173.62.177.in-addr.arpa.
+616e616a73.656c6d756e646f.6573.80hc16e80c3.webcfs00.com.
+liveupdate.symantecliveupdate.com.
+m.addthisedge.com.
+creative.ak.fbcdn.net.
+safebrowsing.clients.google.com.
+101.122.51.190.in-addr.arpa.
+dl3.jvckenwood.com.
+si0.twimg.com.
+pdtm.blarg.net.
+sp.qbyrd.com.
+166.102.174.190.in-addr.arpa.
+a.root-servers.net.
+www.gstatic.com.
+i1.ytimg.com.
+aktakom.ru.
+tvenvivogratis.teleserviciosperu.com.
+maresco.gr.
+a5.sphotos.ak.fbcdn.net.
+www.bladder-surgery.net.
+medivisor.com.
+46-164-112-222.maxnet.ir.
+40.243.26.189.in-addr.arpa.
+espanol.yahoo.com.
+87.52.63.186.in-addr.arpa.
+tfnkm:phd.44xn.
+gfx4.hotmail.com.
+rojoblog.wordpress.com.
+s2000.spb.ru.
+st.chatango.com.
+www.facebook.com.
+www.facebook.com.
+bayyinah.com.
+omh.state.us.
+145.169.237.64.in-addr.arpa.
+e2umail.com.
+photos-e.ak.fbcdn.net.
+www.oxan.com.
+euro.mediotiempo.com.
+developers.facebook.com.
+41-courier.push.apple.com.
+quoteassociate.com.
+mcccharlotte.com.
+70.126.151.178.in-addr.arpa.
+header.vacationsmadeeasy.com.
+cs301806.vk.com.
+update.alot.com.
+img.widgets.video.s-msn.com.
+a.c-0.19-309b000.10033.1518.19d4.2f1c.10.0.wkj94emevza8c94129h2db22fi.avqs.mcafee.com.
+www.ctnewsjunkie.com.
+www.l.google.com.
+embassysuitesaz.com.
+adserver.juicyads.com.
+photos-e.ak.fbcdn.net.
+s-external.ak.fbcdn.net.
+136.233.3.190.in-addr.arpa.
+www.facebook.com.
+plus.google.com.
+19-courier.push.apple.com.
+mgz.cl.
+www.msftncsi.com.
+s0.2mdn.net.
+i3.ytimg.com.
+strangeglue.com.
+interop.com.multi.surbl.org.
+accounts.google.com.
+a8.sphotos.ak.fbcdn.net.
+44-courier.push.apple.com.
+it-it.facebook.com.
+tools.google.com.
+fbcdn-photos-a.akamaihd.net.
+rosenblatt-law.co.uk.
+med.greatviews.de.
+www.icdp.org.co.
+hostalaquimequedo.com.
+www.redtube.com.
+v0rak3.net.
+112.235.43.190.in-addr.arpa.
+227.76.93.186.in-addr.arpa.
+translate.google.com.mx.
+es-es.fxfeeds.mozilla.com.
+232.159.253.189.in-addr.arpa.
+usersamara.ru.
+cdn.api.twitter.com.
+163.184.32.180.in-addr.arpa.
+googleads.g.doubleclick.net.
+90.60.185.186.in-addr.arpa.
+134.42.24.189.in-addr.arpa.
+usam.edu.sv.
+m.google.com.vn.
+mvhrkvaekw.net.
+a.root-servers.net.
+a.root-servers.net.
+gg.google.com.
+50.29.204.223.in-addr.arpa.
+www.electricsupercharger.com.
+a.root-servers.net.
+bochsa.site.voila.fr.
+241.57.192.173.in-addr.arpa.
+www.google.com.mx.
+dfgdfgdf.com.
+localization.maktoob.com.
+fxfeeds.mozilla.com.
+a-0.19-a3090081.d030082.1518.19d4.3ea1.410.0.n37zcitfvmd9sl8h1z9j597jl6.avqs.mcafee.com.
+pbimail9.prodigy.net.
+lokotronicprincezz.blogspot.com.
+timne.ru.
+www.google.com.
+a.root-servers.net.
+_005_01_8.
+csc3-2010-crl.verisign.com.
+www.bflix.info.
+gumilla.org.
+overtopropetorrents.com.
+b-0.19-23006089.8251081.1518.19c7.3ea1.210.0.4qu8elj1p4riw36ub52iebr9uq.avqs.mcafee.com.
+blu.rr.msn.com.
+static.ak.connect.facebook.com.
+mail.pst-net.ru.
+profile.ak.fbcdn.net.
+furries.ru.
+www.imj.gob.mx.
+www.pixel2life.com.
+animegamusic.blogspot.com.
+hg1sddx19.57qn.
+eldec.com.
+a.root-servers.net.
+www.truebrutalmovies.com.
+fingrp.com.
+img.hotwords.com.br.
+predatorperformance.com.
+mx.dca.untd.com.
+101.61.240.189.in-addr.arpa.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+189.69.203.200.in-addr.arpa.
+peru.amarillaslatinas.net.
+channelonetv.com.
+s.ytimg.com.
+mail.ccronline.com.
+www.arabia-ms.com.
+117.122.114.186.in-addr.arpa.
+sgw02.mtr.com.hk.
+photos-c.ak.fbcdn.net.
+m.eukanuba.es.
+avantgarde.com.
+teredo.ipv6.microsoft.com.
+smtp.acmebros.com.
+www.appstrip.com.
+pagead2.googlesyndication.com.
+19thcentury.wordpress.com.
+249.41.29.186.in-addr.arpa.
+www.zylomgames.com.
+reddingtank.com.
+netzero.com.
+clients1.google.com.
+app.appatyze.com.
+www.voanews.com.
+www.google-analytics.com.
+ex7.stingraytackle.com.
+1.0.0.127.dnsbugtest.1.0.0.127.in-addr.arpa.
+photos-e.ak.fbcdn.net.
+223.118.176.78.in-addr.arpa.
+s225.meetrics.net.
+platform.ak.fbcdn.net.
+g.promosrv.com.
+www.facebook.com.
+blogcristiano.net.
+172.94.201.190.in-addr.arpa.
+twitter-any.s3.amazonaws.com.
+www.facebook.com.
+ontera.net.
+sierramonitor.com.
+elmaanareynos.disqus.com.
+hosting.live-e.tv.
+culpinak.blogspot.com.
+anka.ru.
+tunnel.cfw.trustedsource.org.
+whos.amung.us.
+photos-h.ak.fbcdn.net.
+arte-history.blogspot.com.
+www.motorcheck.ie.
+ping3.dyngate.com.
+230.180.42.60.in-addr.arpa.
+time.nist.gov.
+www.usmagazine.com.
+100.131.103.201.in-addr.arpa.
+99.20.0.192.in-addr.arpa.
+learn.caim.yale.edu.
+69.3.168.192.in-addr.arpa.
+mail.live.com.
+mail-carlc.gillhotels.com.
+zulu.tweetmeme.com.
+meeker.k12.co.us.s9b1.psmtp.com.
+a248.e.akamai.net.
+www.google-analytics.com.
+mail.nashbroselectrical.com.
+24.124.46.99.in-addr.arpa.
+s.ytimg.com.
+twimg0-a.akamaihd.net.
+luisalberto941.wordpress.com.
+robbiewilliamsradio.com.
+138.69.34.156.in-addr.arpa.
+photos-f.ak.fbcdn.net.
+connect.facebook.net.
+nullmx.div.net.
+mail.ufoc.org.
+style.alibaba.com.
+static.ak.fbcdn.net.
+my-stats.info.
+u22.eset.com.
+www.catholicfraternity.net.
+photos-c.ak.fbcdn.net.
+www.gm.com.
+orcart.facebook.com.
+250.179.137.186.in-addr.arpa.
+teredo.ipv6.microsoft.com.
+www.green.com.
+daggertools.com.
+tc.v6.cache6.c.youtube.com.
+photos-d.ak.fbcdn.net.
+www.thaimed.us.
+cdn.adslfaqs.com.ar.
+pagead2.googlesyndication.com.
+entrecard.com.
+profile.ak.fbcdn.net.
+arts.mitrasites.com.
+www.buenosaires.com.ar.
+computerkiddoswiki.pbwiki.com.
+122.109.8.200.in-addr.arpa.
+www.croatia.hr.
+.
+24.183.171.201.in-addr.arpa.
+anetstv.ru.
+clock.nyc.he.net.
+a8.sphotos.ak.fbcdn.net.
+slatoninsurance.com.1.arsmtp.com.
+connect.facebook.net.
+www-google-analytics.l.google.com.
+pt-br.facebook.com.
+mail3.infomart2000.com.
+123.244.92.186.in-addr.arpa.
+www.bing.com.
+6to4.ipv6.microsoft.com.
+112.214.232.190.in-addr.arpa.
+zbar2.zynga.com.
+a1324.da1.akamai.net.
+www.facebook.com.
+f86j.myhome.tv.
+224.133.124.201.in-addr.arpa.
+c.www.endless.com.
+diariodeunmiope.lacoctelera.net.
+www.xvideoslive.com.
+api.twitter.com.
+developers.facebook.com.
+livlifetoo.blogspot.com.
+geecsrztk.z02b7x4y.
+234.42.116.174.in-addr.arpa.
+apix.iminent.com.
+www.peope.mx.
+232.68.220.189.in-addr.arpa.
+giuj.com.
+g.ceipmsn.com.
+photos-d.ak.fbcdn.net.
+.
+apps.facebook.com.
+teredo.ipv6.microsoft.com.
+mail.crazycarrot.com.au.
+api.twitter.com.
+142.49.128.190.in-addr.arpa.
+mx18.comquatro.com.br.
+mail.primate.net.
+configuration.apple.com.
+css.wlxrs.com.
+a.root-servers.net.
+159.213.141.201.in-addr.arpa.
+sysna.com.
+www.guarras.com.
+a.root-servers.net.
+fbcdn-profile-a.akamaihd.net.
+_363_27_6.
+205.57.4.46.in-addr.arpa.
+i1.ytimg.com.
+a3.sphotos.ak.fbcdn.net.
+235.187.83.200.in-addr.arpa.
+image.usedvictoria.com.
+hayfork.net.
+103.111.238.41.in-addr.arpa.
+facebook.com.
+pt-br.www.mozilla.com.
+40.162.255.173.in-addr.arpa.
+platform.ak.fbcdn.net.
+api.twitter.com.
+67.170.57.186.in-addr.arpa.
+pixel.facebook.com.
+samplast.ru.
+www.espaces.ca.
+s.youtube.com.
+enter.racksandblacks.com.
+mail.blomsma.net.
+d3.c2.b7.a1.top.mail.ru.
+sp.cwfservice.net.
+86.191.34.186.in-addr.arpa.
+clients1.google.com.mx.
+52.174.203.190.in-addr.arpa.
+peru.paginasamarillas.com.
+language-reader.softonic.com.
+zknwrqbcrm.ru.
+theshadowconspiracy.tumblr.com.
+6.103.224.190.in-addr.arpa.
+cust2916-2.in.mailcontrol.com.
+www.nationaloutdoors.net.
+api.twitter.com.
+todoovni.bligoo.cl.
+by120fd.bay120.hotmail.msn.com.
+goo.gl.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+profile.ak.fbcdn.net.
+text.kcl.ac.uk.
+m.addthisedge.com.
+tsm04.eset.com.
+naifandtastic.blogspot.com.
+41.240.87.212.in-addr.arpa.
+23.217.78.190.in-addr.arpa.
+110.27.239.77.in-addr.arpa.
+mail2.besttransformer.com.
+at160.com.
+number-32.magazine-fashion.net.
+178.250.121.109.in-addr.arpa.
+rssgov.windows.microsoft.com.
+142.227.198.190.in-addr.arpa.
+_192_63_1.
+www.izucar.info.
+media.trafficjunky.net.
+longnosecelebs.hoxpedaje.com.
+davisequip.com.s5a1.psmtp.com.
+creative.ak.fbcdn.net.
+a6.sphotos.ak.fbcdn.net.
+netmag.com.mx.
+a.root-servers.net.
+www.taringa.net.
+89.163.95.200.in-addr.arpa.
+seter.com.mx.
+60.79.151.186.in-addr.arpa.
+m.addthisedge.com.
+tradewindtours.com.
+53.221.170.90.in-addr.arpa.
+www.fondationtf1.fr.
+content.yieldmanager.edgesuite.net.
+www.techawards.org.
+www.google.com.
+adm.fwmrm.net.
+9.9.192.190.in-addr.arpa.
+a.root-servers.net.
+a1015.g.akamai.net.0.1.cn.akamaitech.net.
+www.mercadolibre.com.ar.
+7.206.1.181.in-addr.arpa.
+dns.msftncsi.com.
+88.27.219.85.in-addr.arpa.
+ns2.mokr.ru.
+mx.youtube.com.
+biztv.ru.
+ad.yieldmanager.com.
+60.175.15.201.in-addr.arpa.
+bit.ly.
+resolver5.wguard.ctmail.com.
+pjallseasons.blogspot.com.
+63.32.133.186.in-addr.arpa.
+_618_22_9.
+dnl-18.geo.kaspersky.com.
+apis.google.com.
+219.73.168.192.in-addr.arpa.
+pixel.facebook.com.
+ar-ar.facebook.com.
+sc.cc.wy.us.
+fbcdn-photos-a.akamaihd.net.
+a.root-servers.net.
+orajydoh4.08ri.
+liveupdate.symantecliveupdate.com.
+244.255.146.216.in-addr.arpa.
+img3.annuncicdn.it.
+www.geotaku-no-fansub.com.
+www.devenir-rentier.fr.
+www.zehnders.com.
+wnnfans.com.
+mail.renta-auto.ru.
+64.173.231.190.in-addr.arpa.
+creative.ak.fbcdn.net.
+www.gaypaycheck.com.
+a3.sphotos.ak.fbcdn.net.
+.
+www.ofertas-ocasion-mercedes.com.
+google.com.
+36.179.70.217.in-addr.arpa.
+s.youtube.com.
+ssl.gstatic.com.
+i3.ytimg.com.
+clansunset.files.wordpress.com.
+a1820.phobos.apple.com.
+a.root-servers.net.
+api.nanigans.com.
+metrics.news.co.uk.
+www.powerslaverecords.com.
+smtp.dvinaland.ru.
+cloud.rovio.com.
+www.gamecdkey.org.
+irizrb:dw.e95p5k2h.
+creative.ak.fbcdn.net.
+creative.ak.fbcdn.net.
+segurosencasa.com.
+a.root-servers.net.
+www.interactivestuff.org.
+122.166.130.189.in-addr.arpa.
+217.26.121.186.in-addr.arpa.
+a.root-servers.net.
+7.17.135.187.in-addr.arpa.
+api.facebook.com.
+www.facebook.com.
+174.84.176.187.in-addr.arpa.
+i1237.photobucket.com.
+nyhbpr.com.
+hostgrantor.org.
+a.root-servers.net.
+magnacarta.surrey.sch.uk.
+45.193.42.62.in-addr.arpa.
+peoplepc.com.
+20.16.43.186.in-addr.arpa.
+a.root-servers.net.
+www.gamer.ne.jp.
+a.root-servers.net.
+a.root-servers.net.
+yahoo.download.vmn.net.
+www.google.com.
+rs501tl5.rapidshare.com.
+relay.voice.edge.messenger.live.com.
+encuadernacion.realbiblioteca.es.
+210.65.122.84.in-addr.arpa.
+byfiles.storage.msn.com.
+61.42.201.190.in-addr.arpa.
+api-read.facebook.com.
+mx.ptmail.sapo.pt.
+dns.msftncsi.com.
+a8.sphotos.ak.fbcdn.net.
+www.wdc.com.
+236.194.78.186.in-addr.arpa.
+229.0.55.157.in-addr.arpa.
+pagead2.googlesyndication.com.
+pagead2.googlesyndication.com.
+eastoregonian.com.
+www.mangolanguages.com.
+mail.cognisurf.com.
+www.gstatic.com.
+teredo.ipv6.microsoft.com.
+a.root-servers.net.
+download346.avast.com.
+192.12.68.189.in-addr.arpa.
+e1463.b.akamaiedge.net.
+231.36.168.192.in-addr.arpa.
+static.ak.fbcdn.net.
+230.20.20.67.in-addr.arpa.
+i29.servimg.com.
+vingan.com.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+fbcdn-photos-a.akamaihd.net.
+www.google-analytics.com.
+a6.sphotos.ak.fbcdn.net.
+12.229.127.201.in-addr.arpa.
+48.196.243.201.in-addr.arpa.
+smtp.telelogix.net.
+twitter.com.
+www.facebook.com.
+webcache.googleusercontent.com.
+photos-c.ak.fbcdn.net.
+www.interpanama.com.
+mx4.etrn.canit4.3d.net.uk.
+developers.facebook.com.
+endling.deviantart.com.
+promo.msgpluslive.net.
+a.root-servers.net.
+www.directbigboobsreloaded.net.
+sites.google.com.
+www.facebook.com.
+93.68.73.186.in-addr.arpa.
+a3.sphotos.ak.fbcdn.net.
+os.ning.com.
+a.root-servers.net.
+bigdealutah.kostizi.com.
+support.google.com.
+notify19.dropbox.com.
+s-static.ak.fbcdn.net.
+cinci.rr.com.
+plusmall.golfsky.com.
+crl.microsoft.com.
+www.mixx.com.
+ovv7ckhrk.s14s9c3m.
+22-courier.push.apple.com.
+ksn2-12.kaspersky-labs.com.
+activesync.hot.glbdns.microsoft.com.
+pixel.facebook.com.
+sp.cwfservice.net.
+sailinghawks.com.
+a.root-servers.net.
+mail.insomnia-sales.com.
+76.252.160.201.in-addr.arpa.
+a.root-servers.net.
+pixel.quantserve.com.
+feralon.blogspot.es.
+ana-marin.blogspot.com.
+a1505.l.akamai.net.
+estaticosak1.tuenti.com.
+a.root-servers.net.
+www.ratteb.com.
+colegiala-informe-11-parte-del-pudin-esta-en-estudio.planetadepeliculas.com.
+204.236.7.95.in-addr.arpa.
+a.sigalert.com.
+ar2006.emcdda.europa.eu.
+www.mexicosmagazine.com.
+s-static.ak.fbcdn.net.
+aol.com.
+www.bookmarksbookshop.co.uk.
+marlerclark.com.s9b2.psmtp.com.
+nsiadvisors.com.
+a5.sphotos.ak.fbcdn.net.
+97.172.31.190.in-addr.arpa.
+static.ak.fbcdn.net.
+neude.tumblr.com.
+r._dns-sd._udp.0.2.168.192.in-addr.arpa.
+www.rickross.com.
+165.178.133.189.in-addr.arpa.
+a1725.l.akamai.net.
+gumps.com.s7a2.psmtp.com.
+gdata.youtube.com.
+ping.ginoplayer.net.
+a6.sphotos.ak.fbcdn.net.
+dss1.siteadvisor.com.
+mx.youtube.com.
+a.root-servers.net.
+forum.sky.it.
+officesm.ru.
+h.live.com.
+www.waraqat.net.
+megaconsolas.foros.bz.
+www.whitehouse.gov.
+www.amountainofcrushedice.com.
+a.root-servers.net.
+img3.catalog.video.msn.com.
+rovio1.appads.com.\224[\173\001.
+.
+a.root-servers.net.
+keithclarkephotography.com.
+64.20.54.1.in-addr.arpa.
+tmss.trendmicro.com.
+dc461.4shared.com.
+vp.sip.messenger.msn.com.
+apis.google.com.
+cableone.net.
+bolyai.cs.elte.hu.
+_230_86_4.
+passwaynet.com.
+www.fiveguys.net.
+qwar.spb.ru.
+138.188.224.125.in-addr.arpa.
+profile.ak.fbcdn.net.
+176.32.58.186.in-addr.arpa.
+api4s.dayup.org.
+brayleino.co.uk.
+profile.ak.fbcdn.net.
+profile.ak.fbcdn.net.
+a.root-servers.net.
+210.213.38.190.in-addr.arpa.
+um12.eset.com.
+126.41.155.189.in-addr.arpa.
+twitter.com.
+www.vxsbill.com.
+pixel.facebook.com.
+recookie-767972906.us-east-1.elb.amazonaws.com.
+developers.facebook.com.
+www.androidtabletpcsupport.com.
+www.bicimotor.com.
+i.yimg.jp.
+www.earthakittfanclub.com.
+www.goutremoval.com.
+x26.xanga.com.
+hortigas.org.
+mscrl.microsoft.com.
+checkip.dyndns.org.
+external.ak.fbcdn.net.
+svrintl-g3-crl.verisign.com.
+80.85.38.68.in-addr.arpa.
+cody.wtp.net.
+p03-contacts.icloud.com.
+ocsp.verisign.com.
+108.31.193.108.in-addr.arpa.
+www.superdelivery.com.ar.
+cuauhtemocsuarez.tumblr.com.
+mail.agency-legion.ru.
+help.weheartit.com.
+fbcdn-photos-a.akamaihd.net.
+external.ak.fbcdn.net.
+cdn.api.twitter.com.
+loading5.widdit.com.
+psgw.t-mobilesgws.com.
+www.shemaleladys.com.
+c.bing.com.
+ssl.gstatic.com.
+_671_21_1.
+fs438.uploading.com.
+voipc.sip.yahoo.com.
+urs.microsoft.com.
+photos-a.ak.fbcdn.net.
+www.irememberjfk.com.
+www.addthis.com.
+15.149.220.66.in-addr.arpa.
+yui.yahooapis.com.
+www.afroonblondes.com.
+shopperinc.com.
+146.4.75.200.in-addr.arpa.
+packman.links2linux.org.
+v7.cache2.c.youtube.com.
+a.root-servers.net.
+9.248.113.71.in-addr.arpa.
+inscapllc.com.
+www.keep-project.eu.
+v3.nonxt2.c.pack.google.com.
+0-56.channel.facebook.com.
+webcache.googleusercontent.com.
+a.root-servers.net.
+a2.sphotos.ak.fbcdn.net.
+www.facebook.com.
+www.videosmaduras.org.
+cart.taobao.com.
+insider.msg.yahoo.com.
+javadl-esd.sun.com.
+vf.cloud.avg.com.
+a.root-servers.net.
+gateway.deiser.es.
+mail2.keybuild.com.
+bryansk.ru.
+www.modernwallcompany.com.
+comprarcreatina.net.
+public.liss.slidesharecdn.com.edgesuite.net.
+201.212.44.200.in-addr.arpa.
+noble-empire.com.
+ads.yimg.com.
+eshop.infobel.com.
+photos-g.ak.fbcdn.net.
+rekam-auto.ru.
+enfrentalaverdad.activo.mx.
+tc.v23.cache4.c.youtube.com.
+www.studiocalico.com.
+bit.ly.
+dns.msftncsi.com.
+a954.phobos.apple.com.
+news.bbc.co.uk.
+www.mileycyrusgames.net.
+sapiens.ya.com.
+orcart.facebook.com.
+39.62.215.189.in-addr.arpa.
+listserv.repp.org.
+mail.google.com.
+a7.sphotos.ak.fbcdn.net.
+sp.cwfservice.net.
+dns.msftncsi.com.
+www.walletshop.com.au.
+a.root-servers.net.
+ad.bannerconnect.net.
+cn1.redswoosh.akadns.net.
+8.163.10.186.in-addr.arpa.
+tick.stdtime.gov.tw.
+miraflores.gob.pe.
+129.168.230.190.in-addr.arpa.
+www.servoprax.com.
+a8.sphotos.ak.fbcdn.net.
+maybones.polyvore.com.
+www.800mainstreet.com.
+www.p1q.eu.
+rutafreak.blogspot.com.
+www.aerobic-online.com.
+dc350.4shared-china.com.
+168.169.28.190.in-addr.arpa.
+tobolsk.info.
+apis.google.com.
+ipswebfilter.molindia.com.
+7.213.43.200.in-addr.arpa.
+api.facebook.com.
+vp.sip.messenger.msn.com.
+www.gtliens.fr.
+www.ign.com.
+73.114.168.192.in-addr.arpa.
+www.google.com.
+243.114.106.177.in-addr.arpa.
+bt1.divalium.com.
+feeds.bbci.co.uk.
+138.34.60.186.in-addr.arpa.
+autocadprojects.blogspot.com.
+70.139.163.90.in-addr.arpa.
+baptisthealh.net.
+mail.kudlow.com.
+photos-g.ak.fbcdn.net.
+www.trpk.net.
+ad.yieldmanager.com.
+www.nylon-xxx.com.
+it-demo.com.ua.
+valiumchat.chatango.com.
+www.bookfinder.com.
+s-external.ak.fbcdn.net.
+www.twinkspicsorgasm.com.
+denis.stalker.h3q.com.
+tracker.ktxp.com.
+www.svpg.com.
+a.root-servers.net.
+tc.v6.cache8.c.youtube.com.
+126.73.88.200.in-addr.arpa.
+s2.youtube.com.
+madonna.connexion.free.fr.
+email.houcon.com.
+fei9988.3322.org.
+_547_98_4.
+fs433.uploading.com.
+www.cuartodecomunicaciones.com.
+f0.img.v4.skyrock.net.
+127.0.0.1.
+www.internethealthlibrary.com.
+www.thomsonscientific.com.
+www.esperanzanews.com.ar.
+m.hotmail.com.
+router.bitcomet.net.
+um18.eset.com.
+a.root-servers.net.
+234.16.39.190.in-addr.arpa.
+mail.highklass.ru.
+.
+sp.cwfservice.net.
+o-o.preferred.lga15s20.v10.lscache1.c.youtube.com.
+_535_07_7.
+a8.sphotos.ak.fbcdn.net.
+vicclap.hu.
+mstu.redu.ru.
+s2.youtube.com.
+www.4mybaby.ch.
+ogil.files.wordpress.com.
+tw.burberry.com.
+147.8.94.189.in-addr.arpa.
+mailer.cimesa.net.
+www.radanpro.com.
+222.200.233.190.in-addr.arpa.
+profile.ak.fbcdn.net.
+google.com.
+teredo.ipv6.microsoft.com.
+www.jorudan.co.jp.
+inferno.demonoid.com.
+static.ak.facebook.com.
+static.ak.facebook.com.
+datawingsff.monbe.be.
+169.157.253.201.in-addr.arpa.
+a921.phobos.apple.com.
+apps.facebook.com.
+a.root-servers.net.
+41.32.216.190.in-addr.arpa.
+l.sscdn.co.
+a.root-servers.net.
+api-read.facebook.com.
+a.root-servers.net.
+three-part-harmony.com.
+mail.saratov.su.
+55.180.47.31.in-addr.arpa.
+www.bddlgroup.com.
+itunes.com.
+www.googleadservices.com.
+www.dotcr.ost.dot.gov.
+plus.google.com.
+im-from-wasteland.tumblr.com.
+www.mylovedtranny.com.
+www.msftncsi.com.
+ar.babel.com.
+adc.bmjjournals.com.
+www.lucialapiedradesnuda.com.
+www.manhelper.com.
+x5ah2rbgj.95wi.
+xrpvt59gh.o63y7w1b.
+katzenlaw.net.
+mail.bushtracksafrica.com.
+img7.imageshack.us.
+ksn1-12-part2.kaspersky-labs.com.
+156.33.66.187.in-addr.arpa.
+commons.wikimedia.org.
+sp.cwfservice.net.
+heartbeat.belkin.com.
+a.root-servers.net.
+g.microsoft.com.
+cableone.net.mail5.psmtp.com.
+images.intl.match.com.
+picnic.com.
+196.91.52.94.in-addr.arpa.
+mx.tcrcd.net.
+www.textsrv.com.
+www.simplysupersoft.com.
+9-1.qlty.finarea.ch.
+mail.aeronauticalelectric.com.
+tolteca-guillermomarin.blogspot.com.
+ajax.cloudflare.com.
+db2.stb00.s-msn.com.
+www.facebook.com.
+api.geo.kontagent.net.
+salonesoterico.com.
+a4.sphotos.ak.fbcdn.net.
+check.sanasecurity.com.
+0-250.channel.facebook.com.
+9-courier.push.apple.com.
+zh-cn.facebook.com.
+google.com.
+pravbrat.ru.
+www.bodydragon.com.
+0-ig-w.channel.facebook.com.
+ads.traffichaus.com.
+platform.ak.fbcdn.net.
+www.bookdepository.com.
+chunsreef.globalhost.com.
+b._dns-sd._udp.0.1.168.192.in-addr.arpa.
+t5.tagstat.com.
+www.dvbviewer.com.
+a1920.g.akamai.net.
+mail.sofaselections.com.
+managedindustrial.com.
+www.monsterdivx.com.
+www.adobe.com.
+6to4.ipv6.microsoft.com.
+accounts.google.com.
+charter.net.
+174.16.110.68.in-addr.arpa.
+comicsinvasion.blogspot.com.
+rospres.com.
+mail.pavcol.com.
+s.youtube.com.
+c.wb.mapbox.com.
+a5.sphotos.ak.fbcdn.net.
+forsuccess.ru.
+triaid.rr.com.
+arlenegoldbard.com.
+bw33xoel:.z73d3n9o.
+s.youtube.com.
+google.com.
+29.27.176.189.in-addr.arpa.
+www.forosdelweb.com.
+10.1.168.192.in-addr.arpa.
+155.213.69.190.in-addr.arpa.
+www.youtube.com.
+map.secondlife.com.s3.amazonaws.com.
+www.indeed.com.
+russadventures.ru.
+185.78.244.189.in-addr.arpa.
+toolbarqueries.clients.google.com.
+crl.microsoft.com.
+pixel.facebook.com.
+hydrogen.yatho.de.
+youtu.be.
+a.root-servers.net.
+lb._dns-sd._udp.belkin.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+www.4girlsfingerpaint.com.
+uwpho.to.
+29.200.230.188.in-addr.arpa.
+cdn1.ads.brazzers.com.
+thumbnails.infolinks.com.
+crossword-forge.uptodown.com.
+daytona.backpage.com.
+a.root-servers.net.
+192.248.167.184.in-addr.arpa.
+www.softonic.com.
+rdmail.com.
+jjegonzalezf.files.wordpress.com.
+mundotdc.bancomer.com.mx.
+a.root-servers.net.
+counterb.statcounter.com.
+4benchmark.com.
+d2o307dm5mqftz.cloudfront.net.
+180.144.130.201.in-addr.arpa.
+webex.com.rbl2.mcafee.com.
+deliriosdemuekitacat.blogspot.com.
+www.equipo63.com.
+_530_88_0.
+www8.incredimail.com.
+xxlcc.com.
+exch2k7.npes.org.
+download.windowsupdate.com.
+creative.ak.fbcdn.net.
+ib.adnxs.com.
+23.112.144.79.in-addr.arpa.
+yoteoriento.blogspot.com.
+bcisouthwest.com.
+www.mumstuff.co.uk.
+westsoundelectric.com.
+127.0.0.1.
+external.ak.fbcdn.net.
+teredo.ipv6.microsoft.com.
+22.53.218.190.in-addr.arpa.
+rmail1.aeroplan.spb.ru.
+fr.webrep.avast.com.
+static.ak.connect.facebook.com.
+groups.google.as.
+82.76.173.218.in-addr.arpa.
+rewe-brinkmann.de.
+iphonedeveloperhelp.info.
+www.listengo.com.
+b.imwx.com.
+mx.ezfloorplan.com.
+mail.medinformatix.com.
+safebrowsing.clients.google.com.
+189.39.222.186.in-addr.arpa.
+mailgw4.gnresound.com.
+flash.y9.vc.
+www.trouvetamosquee.fr.
+videos.publimetro.cl.
+a.root-servers.net.
+pagead.l.doubleclick.net.
+virtualwave.com.
+223.16.92.201.in-addr.arpa.
+globalite.com.br.
+104.0.84.186.in-addr.arpa.
+www.lineahome.com.
+_624_21_2.
+m.facebook.com.
+inglife.ru.
+marisol-espurnetes.blogspot.com.
+mtalk.google.com.
+billitall.com.
+ssl.gstatic.com.
+viniloseroticos.blogspot.com.
+fisica.net.
+forum.kismac-ng.org.
+www.hispanicfund.org.
+60.100.8.99.in-addr.arpa.
+100500.tv.
+feeds.bbci.co.uk.
+114.18.152.189.in-addr.arpa.
+cuda1.tcworks.net.
+27.0.1.10.in-addr.arpa.
+qnr6pa2:l.81xy.
+id.google.com.mx.
+shared.live.com.
+a.root-servers.net.
+clients1.google.com.
+a4.sphotos.ak.fbcdn.net.
+www.seccionamarilla.com.mx.
+cs13243.vkontakte.ru.
+f.facemoods.com.
+159.158.156.175.in-addr.arpa.
+ajax.googleapis.com.
+11.1.168.192.in-addr.arpa.
+44.215.85.209.rbl7.mailshell.net.
+o-o.preferred.lax04s12.v10.lscache5.c.youtube.com.
+a.root-servers.net.
+65.66.6.186.in-addr.arpa.
+108.119.13.187.in-addr.arpa.
+86.101.188.189.in-addr.arpa.
+fr.wunderman.com.s200a1.psmtp.com.
+lh4.googleusercontent.com.
+gateway.messenger.hotmail.com.
+profile.ak.fbcdn.net.
+photos-h.ak.fbcdn.net.
+167.196.81.201.in-addr.arpa.
+31.240.49.186.in-addr.arpa.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+mail.google.com.
+208.30.8.200.in-addr.arpa.
+certifiedair.net.s5a2.psmtp.com.
+www.vanderlande.com.
+98.115.215.189.in-addr.arpa.
+spotcrime.com.
+www.elsotano.com.mx.
+javadl-esd.sun.com.
+celebrity-weight-loss.info.
+m.facebook.com.
+www.amazon.com.
+aenianos.wordpress.com.
+ssl.google-analytics.com.
+196.252.223.201.in-addr.arpa.
+126.17.50.190.in-addr.arpa.
+xatihujigonako.com.
+www.cuentosparacolorear.com.
+www.imdb.com.
+altacosta.ru.
+google.com.
+fr-fr.facebook.com.
+www.fighterplanegames.net.
+www.naviopirata.com.
+ws-cloud-msgplus.linkury.com.
+jp.yupis.org.
+pixel.facebook.com.
+blog.soluciones3f.com.ar.
+vcs2.msg.yahoo.com.
+connect.facebook.net.
+www.script-tutorials.com.
+static.ak.fbcdn.net.
+news.google.com.mx.
+settings.toolbar.conduit-services.com.
+251.121.68.189.in-addr.arpa.
+noir-gothly.blogspot.com.
+cox.net.
+www.vbsoporte.com.
+liftlab.com.
+scimail.silvercloud.com.
+181.159.253.190.in-addr.arpa.
+a.root-servers.net.
+a.root-servers.net.
+img820.imageshack.us.
+www.kenquestmedical.com.
+www.telegraph.co.uk.
+238.45.54.208.in-addr.arpa.
+www.google.com.
+ib.adnxs.com.
+c.prodigy.msn.com.
+www.ece.byu.edu.
+a4.da1.akamai.net.
+www.sandy-xxx.com.
+a.root-servers.net.
+laborlawyers.com.s8b2.psmtp.com.
+www.google-analytics.com.
+www.paginasamarillas.com.ar.
+www4.pictures.gi.zimbio.com.
+16.147.220.66.in-addr.arpa.
+docs.google.com.
+apps.facebook.com.
+a.root-servers.net.
+a5.sphotos.ak.fbcdn.net.
+mail.newroads.org.
+lujazos.com.
+a2.sphotos.ak.fbcdn.net.
+webres1.pand.ctmail.com.
+e.yieldmanager.net.
+prev.explabs.net.
+ad.yieldmanager.com.
+samor.ru.
+feeds.bbci.co.uk.
+cableone.net.mail7.psmtp.com.
+adserving.cpxinteractive.com.
+mail.sembolferforje.com.
+ksn2-12.kaspersky-labs.com.
+ns.ett.ua.
+a2.twimg.com.
+photos-e.ak.fbcdn.net.
+abtaudit.ru.
+codeblocks.org.
+193.142.215.173.in-addr.arpa.
+youtu.be.
+mediacdn.disqus.com.
+fbbmusclegirls.blogspot.com.
+gfx1.hotmail.com.
+dynda.net.
+mail2.deis.unical.it.
+surgient.com.
+34.98.250.189.in-addr.arpa.
+msc.wlxrs.com.
+clients1.google.com.
+fishermotors.com.s9a1.psmtp.com.
+www.facebook.com.
+centromedicomty.com.
+grandcanyon.ru.
+44.82.77.219.in-addr.arpa.
+external.ak.fbcdn.net.
+sharpusa.com.
+www.gapa.de.
+a1.sphotos.ak.fbcdn.net.
+www.youtube.com.
+ajax.googleapis.com.
+www.facebook.com.
+rwpike.deviantart.com.
+orcart.facebook.com.
+bernatcomas.com.
+translate.googleapis.com.
+tncu.org.
+_429_57_2.
+a7.sphotos.ak.fbcdn.net.
+c-0.19-a30f1081.60081.1518.19d2.3ea0.210.0.9z5w4fe9kicv8b19mbh6svh7ui.avqs.mcafee.com.
+a.root-servers.net.
+loquelacomidasellevo.blogspot.com.
+sitemap.gamefaqs.com.
+b.scorecardresearch.com.
+matcher-rbc.bidder7.mookie1.com.
+51.56.112.186.in-addr.arpa.
+156.219.192.173.in-addr.arpa.
+icons.cubics.com.
+213.44.0.10.in-addr.arpa.
+fugazyintl.com.
+welcometobaltimorehon.com.
+www.institutoasegurador.com.ar.
+www.htmlgraphic.com.
+191.163.245.189.in-addr.arpa.
+231.120.69.190.in-addr.arpa.
+s-static.ak.fbcdn.net.
+www.kisscleveland.com.
+wewecity.s3.amazonaws.com.
+es.disney.wikia.com.
+1.bp.blogspot.com.
+22.1.111.186.in-addr.arpa.
+96.250.115.186.in-addr.arpa.
+creative.ak.fbcdn.net.
+brightonpainting.com.
+i1.ytimg.com.
+olsten.com.
+229.21.192.187.in-addr.arpa.
+24.145.228.84.in-addr.arpa.
+a3.sphotos.ak.fbcdn.net.
+mobileblogmoney.com.
+www.allpsychologyschools.com.
+mail.gadaletoramsby.com.
+62.108.173.118.in-addr.arpa.
+201.127.172.67.in-addr.arpa.
+ijfdiiuvirghdlkqrdapq.cc.
+www.tebca.com.
+www.avkube.ru.
+s2.youtube.com.
+jywuua.com.
+207.196.51.190.in-addr.arpa.
+a2.sphotos.ak.fbcdn.net.
+18.70.133.189.in-addr.arpa.
+fr.onehourtranslation.com.
+photos-a.ak.fbcdn.net.
+static.ak.fbcdn.net.
+media.adxpansion.com.
+msgr.updates.yahoo.com.
+mail.bristol.mass.edu.
+safebrowsing-cache.google.com.
+a1768.g.akamai.net.
+psgw.t-mobilesgws.com.
+wtabfgempt.info.
+telecom.cz.
+a.root-servers.net.
+img216.imageshack.us.
+ad.ifwcash.com.
+www.courts.state.ny.us.
+time.nist.gov.
+delanteroizquierdo.blogspot.com.
+gfjdyrfcb.net.
+www.facebook.com.
+dnl-02.geo.kaspersky.com.
+.
+www.bylatino.mx.
+loading.retry.widdit.com.
+chat009.vs.com.
+forums.opalauctions.com.
+twitter.com.
+www.olx.com.do.
+m.facebook.com.
+fbcdn-profile-a.akamaihd.net.
+mail.btk.ru.
+usf.com.
+nwcoughlin.com.
+m.facebook.com.
+alt2.gmail-smtp-in.l.google.com.
+click.sandglass.tv.
+61.10.89.183.in-addr.arpa.
+mail.owzw.com.
+131.235.88.200.in-addr.arpa.
+a.root-servers.net.
+phpfusion.org.
+8.0.168.192.in-addr.arpa.
+fbcdn-sphotos-a.akamaihd.net.
+www.cljhealth.com.
+www.facebook.com.
+photos-d.ak.fbcdn.net.
+mail.satlinker.com.
+fi.wikipedia.org.
+www.facebook.com.
+apis.google.com.
+images.apple.com.
+155.138.189.189.in-addr.arpa.
+videosjustinbieber.com.ar.
+www.20minutos.es.
+lykwrwb65.y20y7r0v.
+i2.ytimg.com.
+ejabat.google.com.
+centroidcnc.com.
+www.wise.edu.jo.
+hyperiontechnologies.com.
+rtlnow.de.
+30-courier.push.apple.com.
+weather.bigmir.net.
+photos-e.ak.fbcdn.net.
+channeltechno.com.
+www.unbeatablesale.com.
+adsc.com.
+144.148.85.209.in-addr.arpa.
+asap-utilities.en.softonic.com.
+www.nursery.com.au.
+skateboardmsm.mpora.de.
+19.208.247.92.in-addr.arpa.
+199.97.75.65.in-addr.arpa.
+gmx.at.
+a.root-servers.net.
+87.210.2.201.in-addr.arpa.
+ads.adxpansion.com.
+itu.int.s201a2.psmtp.com.
+openx-adserver-balancer-2134199362.us-west-1.elb.amazonaws.com.
+promarkit.com.
+dikomp.saratov.ru.
+www.facebook.com.
+www.ftp8.co.uk.
+ugij8vgz3.01ui.
+googleads.g.doubleclick.net.
+spider-wl023.proxy.aol.com.
+jjlennon.com.
+www.facebook.com.
+a1132.da1.akamai.net.
+a.root-servers.net.
+42.112.55.187.in-addr.arpa.
+183.37.55.92.in-addr.arpa.
+q2sg6c68:.70si.
+clients4.google.com.
+www.twifansadnet.com.
+tmss.trendmicro.com.
+thirdwavepartners.net.
+blogs.tudiscovery.com.
+www.perfectdiva.ro.
+182.55.198.187.in-addr.arpa.
+112.230.29.189.in-addr.arpa.
+gmt.nl.
+www.google.com.
+153.149.233.189.in-addr.arpa.
+abcfamily.go.com.
+62.178.130.186.in-addr.arpa.
+213.129.204.186.in-addr.arpa.
+14.136.206.190.in-addr.arpa.
+cbsystem.fr.
+121.24.93.97.in-addr.arpa.
+247.44.79.94.in-addr.arpa.
+twitter.com.
+www.vuelosbaratos.com.mx.
+a8.sphotos.ak.fbcdn.net.
+www.iwanttostopsnoring.com.
+straight.com.
+photos-f.ak.fbcdn.net.
+any-latamrc.a01.yahoodns.net.
+i.w55c.net.
+gitrust.com.
+s7.addthis.com.
+a1108.da1.akamai.net.
+ic.tynt.com.
+5.194.242.201.in-addr.arpa.
+6.125.158.187.in-addr.arpa.
+www.google-analytics.com.
+www.furl.net.
+a4.sphotos.ak.fbcdn.net.
+bs.serving-sys.com.
+195.189.255.201.in-addr.arpa.
+www.multicam.com.
+196.98.193.173.in-addr.arpa.
+71.193.39.187.in-addr.arpa.
+a.root-servers.net.
+55.0.46.190.in-addr.arpa.
+s7.addthis.com.
+www.facebook.com.
+201.139.34.177.in-addr.arpa.
+tracker.openbittorrent.com.
+www.bkrtx.com.
+149.148.10.187.in-addr.arpa.
+apps.facebook.com.
+att.net.
+docs.google.com.
+db._dns-sd._udp.0.55.211.10.in-addr.arpa.
+205.217.19.190.in-addr.arpa.
+_789_63_3.
+34.35.32.186.in-addr.arpa.
+rvmconstrucion.com.
+login.netgame.com.
+firstclassbuilders.com.
+www.scatmodelpower.com.
+wyattfirm.com.mail6.psmtp.com.
+thetwistfamily.blogspot.com.
+16.54.119.200.in-addr.arpa.
+img9.ask.fm.
+gossipgirls.episodeseason.com.
+221.121.224.190.in-addr.arpa.
+ds.serving-sys.com.
+www.bathmate.ca.
+profile.ak.fbcdn.net.
+www.santuariock.com.ar.
+ib.adnxs.com.
+barracuda.tulsarealtors.com.
+bigond.com.
+cm.g.doubleclick.net.
+fbcdn-profile-a.akamaihd.net.
+clock.fmt.he.net.
+rad.msn.com.
+fbcdn-profile-a.akamaihd.net.
+www.gaportal.org.
+padgk93gf.q08g1d7w.
+197.83.97.93.in-addr.arpa.
+photos-f.ak.fbcdn.net.
+228.50.59.186.in-addr.arpa.
+www.hungryhappenings.com.
+0.2.0.e.1.7.4.e.8.2.f.6.b.8.c.1.6.7.e.9.7.3.1.4.0.0.0.0.1.0.0.2.ip6.arpa.
+partner.googleadservices.com.
+pixel.quantserve.com.
+a.root-servers.net.
+adm-skhodnya.ru.
+external.ak.fbcdn.net.
+profile.ak.fbcdn.net.
+www.adobe.com.
+t2.gstatic.com.
+www.abc.com.py.
+254.119.236.92.in-addr.arpa.
+204.87.56.187.in-addr.arpa.
+gisy.com.inbound25.mxlogic.netet.
+bgs.bethsoft.com.
+star.facebook.com.
+165.72.232.189.in-addr.arpa.
+static.ak.fbcdn.net.
+homepage.mac.com.
+www.larips.com.
+equityrisk.com.inbound15.mxlogicmx.net.
+pricelist.skype.com.
+www.fallinginreversestore.com.
+www.orcius.com.
+images.intellitxt.com.
+cs301713.vk.com.
+adscdn.avalonsunsplash.com.
+api.twitter.com.
+pixel.facebook.com.
+static.sl.lumosity.com.
+_924_10_1.
+222.103.222.189.in-addr.arpa.
+api.twitter.com.
+b._dns-sd._udp.0.1.168.192.in-addr.arpa.
+mail.google.com.
+a.root-servers.net.
+vcs1.msg.yahoo.com.
+a5.sphotos.ak.fbcdn.net.
+11.249.233.190.in-addr.arpa.
+220.188.7.88.in-addr.arpa.
+www.appsomniac.com.
+bs.serving-sys.com.
+b._dns-sd._udp.lan.
+webcache.googleusercontent.com.
+10.211.16.190.in-addr.arpa.
+desionlinemovies.blogspot.com.
+www.amor-yaoi.com.
+107.112.2.190.in-addr.arpa.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+247.102.55.157.in-addr.arpa.
+www.vicor-china.com.
+196.217.230.190.in-addr.arpa.
+pixel.facebook.com.
+195.156.129.78.in-addr.arpa.
+_477_58_0.
+_767_13_7.
+www.gilligansisle.com.
+xabantech.files.wordpress.com.
+bfr.com.
+www.melindasweet.com.
+www.intel.com.
+gardnerfoxremodeling.files.wordpress.com.
+24.135.93.186.in-addr.arpa.
+ad.yieldmanager.com.
+www.bestbreakfast.ca.
+119.37.191.201.in-addr.arpa.
+search.vuze.com.
+2highstudios.com.
+www.cope.es.
+sn2files.storage.msn.com.
+73.237.171.201.in-addr.arpa.
+www.mylanguageexchange.com.
+www.miantojo.com.mx.
+0-undefined.facebook.com.
+www.loni.ucla.edu.
+entretenimiento.latam.msn.com.
+112.6.165.46.in-addr.arpa.
+www.facebook.com.
+a.root-servers.net.
+mail.satinbedding.com.
+83.135.28.190.in-addr.arpa.
+translate.google.com.mx.
+a2.da1.akamai.net.
+static.ak.fbcdn.net.
+ce.lijit.com.
+thompsonflanagan.com.
+couponbuddy.s3.amazonaws.com.
+56.128.212.24.in-addr.arpa.
+api.facebook.com.
+164.162.11.92.in-addr.arpa.
+8.121.210.201.in-addr.arpa.
+www.l.google.com.
+fxfeeds.mozilla.com.
+148.111.72.94.in-addr.arpa.
+zimmerli-wagner.ch.
+info.xvideos.com.
+126.132.149.186.in-addr.arpa.
+mt0.google.com.
+apps.facebook.com.
+www.fybeca.com.
+251.58.214.81.in-addr.arpa.
+a.root-servers.net.
+i1184.photobucket.com.
+crl.geotrust.com.
+csi.gstatic.com.
+a.root-servers.net.
+ed3q65m:n.l56p8c6w.
+jessicalk.com.
+117.122.183.180.in-addr.arpa.
+6.75.174.189.in-addr.arpa.
+fantasy.footbo.com.
+google.com.
+106.199.106.78.in-addr.arpa.
+206.163.30.186.in-addr.arpa.
+www.youtube.com.
+_812_59_5.
+xhcdn.com.
+earnings.ru.
+mail.tempinbox.com.
+www.facebook.com.
+a3.sphotos.ak.fbcdn.net.
+mail.trak.spb.ru.
+hq.rt.ru.
+www.testiphone.com.
+connect.facebook.net.
+dmtjuo.com.
+www.youtube.com.
+yujh77.dg0.cn.
+www.google-analytics.com.
+teredo.ipv6.microsoft.com.
+www.mariopilato.com.
+66.141.56.186.in-addr.arpa.
+versioncheck.addons.mozilla.org.
+58.52.0.10.in-addr.arpa.
+176.210.164.189.in-addr.arpa.
+static.mp3bear.com.
+ahtm.wordpress.com.
+mail.
+www.mbvmusic.com.
+www.imdb.com.
+162.48.168.213.in-addr.arpa.
+www.facebook.com.
+i4.ytimg.com.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+tvphotosandmore.blogspot.com.
+www.facebook.com.
+a.root-servers.net.
+172.201.134.46.in-addr.arpa.
+caribbeaneco-living.blogspot.com.
+upay-cdn1.playspan.com.
+mx.omegatech.ru.
+50.213.93.59.in-addr.arpa.
+212.69.207.223.in-addr.arpa.
+img02.s-msn.com.
+jayco.net.
+eresources.loc.gov.
+20minutos.feedsportal.com.
+mature.wantvids.com.
+mx.technicatech.com.
+www.fudefs.com.
+lh5.googleusercontent.com.
+mscrl.microsoft.com.
+vlmx00.secure.ne.jp.
+a.root-servers.net.
+pixel.quantserve.com.
+info.infotecstt.ru.
+a4.sphotos.ak.fbcdn.net.
+profile.ak.fbcdn.net.
+www.fotosmujeresbellas.com.
+ilovegelcandles.com.
+d1.openx.org.
+checklists.com.
+rikardoelterrible.blogspot.com.
+240.208.245.201.in-addr.arpa.
+218.127.180.71.in-addr.arpa.
+videojuegos.yo-anime.com.ar.
+www.lyrics-house.com.
+cloudsindo.files.wordpress.com.
+a7.sphotos.ak.fbcdn.net.
+a.root-servers.net.
+www.toplinestrategies.com.
+eradio.ust.edu.ph.
+74.71.58.186.in-addr.arpa.
+google.com.
+7.228.36.81.in-addr.arpa.
+www.ontheedgeblog.com.
+57.133.200.98.in-addr.arpa.
+goneoffdeep.com.
+translate.googleapis.com.
+sdweddinginsider.com.
+rterybrstutnrsbberve.com.
+et6.xhamster.com.
+clients1.google.com.
+api.facebook.com.
+universal-downloader.softonic.com.
+www.tirateunpalo.com.
+www.burladero.com.
+164.88.33.178.in-addr.arpa.
+photos-h.ak.fbcdn.net.
+prod2.rest-notify.msg.yahoo.com.
+www.bettamx.com.
+www.facebook.com.
+mail.rosactive.com.
+visitfayettevillenc.com.inbound10.mxlogicmx.net.
+www.karlscalculus.org.
+static.ak.fbcdn.net.
+www.islamhouse.com.
+time.chttl.com.tw.
+photos-d.ak.fbcdn.net.
+serendipitouschat.com.
+a6.sphotos.ak.fbcdn.net.
+mail.coffmans.com.
+de-de.facebook.com.
+mail.prairietitle.com.
+www.artelectronico.com.
+req1.appads.com.
+shared.live.com.
+www.gstatic.com.
+www.420science.com.
+uomjkh.com.lan.
+www.psicolibroswaslala.com.
+external.ak.fbcdn.net.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+www.zumiez.com.
+wpad.mshome.net.
+creative.ak.fbcdn.net.
+creative.ak.fbcdn.net.
+pastebay.com.
+240.10.210.186.in-addr.arpa.
+profile.ak.fbcdn.net.
+agency.com.
+instagr.am.
+i.t.net.ar.
+bubber.tv2.dk.tv2.dk.
+kimi-raikkonen.ru.
+21.16.14.95.in-addr.arpa.
+a.root-servers.net.
+167.101.215.201.in-addr.arpa.
+25.203.238.190.in-addr.arpa.
+extreme-sochi.ru.
+www.kazdey.co.uk.
+a.root-servers.net.
+copymasters.ru.
+s.ytimg.com.
+profile.ak.fbcdn.net.
+a1567.phobos.apple.com.
+3grenouilles.blogspot.com.
+dsient.com.
+mlocate.spotlife.net.
+191.6.58.186.in-addr.arpa.
+fotocvetov.ru.
+www.freepatternsonline.com.
+lnmmc3m7i.q55k9m3c.
+external.ak.fbcdn.net.
+asd.su.
+tools.google.com.
+safebrowsing.clients.google.com.
+smtp.kunstlaw.com.
+www.channel.com.
+profile.ak.fbcdn.net.
+blufiles.storage.msn.com.
+sitestart.net.
+www.publipaginas.net.
+teredo.ipv6.microsoft.com.
+pinpoint-transportation.com.
+mail.oplink.net.
+cust17503-2.in.mailcontrol.com.
+teamsters631.com.2.0001.arsmtp.com.
+curriclumconnection.net.
+d3k9hgzf8ej9hc.cloudfront.net.
+myfcc.frederick.edu.
+91.145.154.89.in-addr.arpa.
+www.youtube.com.
+www.tuslesbianas.es.
+www.newspaperdirect.com.
+34-courier.push.apple.com.
+static.ak.fbcdn.net.
+mx02.register.com.
+kachina-semi.com.
+blog.assparade.com.
+iluminandotierra.blogspot.com.
+model.susu.ru.
+plus.google.com.
+arrivo.br.
+en.wikipedia.org.af.mk.gd.
+poll-as06.kyte.tv.
+csi.gstatic.com.
+162.189.87.203.in-addr.arpa.
+67.97.172.81.in-addr.arpa.
+145.28.135.190.in-addr.arpa.
+cdn-de-c-142.heias.com.
+plan-espana.org.
+10.193.141.63.in-addr.arpa.
+store.digitalstores.co.uk.
+puertorico.countrytoolbox.com.
+www.rastreamento.org.
+a.analytics.yahoo.com.
+www.kingmantraining.com.
+api.twitter.com.
+dc454.4shared.com.
+dns.msftncsi.com.
+s.youtube.com.
+a1294.w20.akamai.net.
+www.auto-ping.com.
+mgw1.asb.dk.
+www.update.microsoft.com.
+media.adxpansion.com.
+a.root-servers.net.
+www.google-analytics.com.
+static.ak.facebook.com.
+mx.foratec.net.
+ar-ar.facebook.com.
+a2.sphotos.ak.fbcdn.net.
+v2.nonxt1.c.youtube.com.
+a0.twimg.com.
+chrometheme.tumblr.com.
+mail.google.com.
+b-0.19-2300b008.11001.1518.19d4.3ea1.410.0.zhfh1t3w3a82d254pc5c8gdqab.avqs.mcafee.com.
+www.google.com.
+download.xbox.com.
+developers.facebook.com.
+spymouse.cloudcell.com.
+photos-d.ak.fbcdn.net.
+bvdlawfirm.com.
+33.65.122.76.in-addr.arpa.
+potency.lbl.gov.
+crl.verisign.net.
+www.spilgames.com.
+11.28.31.190.in-addr.arpa.
+kbl8psban.f58i2b1r.
+hhwnclaw.com.
+gca.net.s8b2.psmtp.com.
+www.alutec.es.
+www.gimnasiolee.com.
+114.188.43.202.in-addr.arpa.
+www.anahionline.com.
+www.microsoft.com.
+m.facebook.com.
+210.195.146.189.in-addr.arpa.
+yubil.com.
+emob93.photobucket.com.
+i-cf508eaa.us-east-1b.service.amazonsilk.com.
+www.facebook.com.
+fallout3.nexusmods.com.
+javiastudillo.tumblr.com.
+service.lazywormapps.com.
+a5.sphotos.ak.fbcdn.net.
+a2.sphotos.ak.fbcdn.net.
+a1.sphotos.ak.fbcdn.net.
+i4.ytimg.com.
+googleads.g.doubleclick.net.
+docs.google.com.
+a1404.w41.akamai.net.
+a.root-servers.net.
+m.facebook.com.
+184.35.1.190.in-addr.arpa.
+www.google.com.
+taylorfloyd.newsvine.com.
+slogin.oscar.aol.com.
+www.youtube.com.
+13.160.22.64.in-addr.arpa.
+apis.google.com.
+theolivebranch.net.
+ts1.mm.bing.net.
+unepaix.blogspot.com.
+fearlessfathers.wordpress.com.
+qolsze22k.77av.
+safebrowsing.clients.google.com.
+a.root-servers.net.
+www.slashattack.com.
+180.186.123.186.in-addr.arpa.
+gs-loc.apple.com.
+156.5.134.190.in-addr.arpa.
+123.44.105.124.in-addr.arpa.
+apps.facebook.com.
+akabodyart.co.uk.
+www.dubai-worldislands.com.
+pixel.quantserve.com.
+17.164.9.186.in-addr.arpa.
+229.152.68.201.in-addr.arpa.
+73.19.237.77.in-addr.arpa.
+mqnj.com.
+www.google.com.mx.
+agma.ru.
+www.portarrivals.com.
+csi.gstatic.com.
+zezao.com.
+mail.upyourcredits.com.
+34.108.50.189.in-addr.arpa.
+www.gtaseries.com.
+www.reglasdecalculo.com.
+www.ualrtrojans.com.
+www.kagi.fo.
+mx.kraft-s.net.
+boss.blogs.nytimes.com.
+a8.sphotos.ak.fbcdn.net.
+directorio.pixelmod.net.
+mail.mitchellsonline.com.
+b._dns-sd._udp.lan.
+personal.nl.avira-update.net.
+csi.gstatic.com.
+www.animal-sex-library.com.
+www.caracolinternacional.com.
+vintage-hardcore.mrvoyeur.net.
+214.228.206.167.in-addr.arpa.
+design2u.loc.ru.
+photos-d.ak.fbcdn.net.
+names2.businessserve.co.uk.
+162.157.136.175.in-addr.arpa.
+hc.pcw.dk.
+sbcglobal.prodigy.net.
+support.msi.com.
+192.79.167.59.in-addr.arpa.
+static.ak.fbcdn.net.
+www.formarse.com.ar.
+iaie.net.
+fbcdn-profile-a.akamaihd.net.
+121.206.104.70.in-addr.arpa.
+evsecure-ocsp.verisign.com.
+apps.facebook.com.
+dinero.univision.com.
+m.facebook.com.
+app2.neulion.com.
+petitpren.com.
+clients1.google.com.
+110.36.104.186.in-addr.arpa.
+www.id2tag.com.
+www.wtp101.com.
+mail.filasur.com.
+7.77.60.194.in-addr.arpa.
+www.capsis.cl.
+252.210.194.74.in-addr.arpa.
+clients1.google.com.
+87.175.15.201.in-addr.arpa.
+anakena.ru.
+isatap.domain.name.
+threadic.com.
+plus.l.google.com.
+www.sweetim.com.
+blogs.avid.com.
+www.angrybirds.com.
+136.13.16.68.in-addr.arpa.
+bh.contextweb.com.
+erinbuenger.blogspot.com.
+www.facebook.com.
+106.187.46.72.in-addr.arpa.
+www.benet.org.
+www.amateur-indian-girls.com.
+www.amazon.com.
+ntp.glb.nist.gov.
+newsrss.bbc.co.uk.
+cracked.hopto.org.
+opinion-tenerife.vlex.es.
+ad.yieldmanager.com.
+nfdqftxxtuetsn.net.
+www.bloggertipandtrick.net.
+21.8.98.177.in-addr.arpa.
+touchmusic.ru.
+a1.sphotos.ak.fbcdn.net.
+ar-ar.facebook.com.
+megasfiles.com.
+70.60.98.217.in-addr.arpa.
+www.seabreeltelon.es.
+pop.gmail.com.
+www.google.com.
+www.margaretwheatley.com.
+108.252.56.184.in-addr.arpa.
+www.facebook.com.
+produktinfo.conrad.com.
+images.google.com.
+a8.sphotos.ak.fbcdn.net.
+mpcstatic.com.
+www.rusegame.com.
+a.root-servers.net.
+www.entrepreneur.com.
+relay.voice.messenger.msn.com.
+th.nyklogistics.com.
+fonts.googleapis.com.
+aaffd0e4.linkbucks.com.
+d12079a.ess.barracudanetworks.com.
+guardianproject.info.
+www.facebook.com.
+www.elcoto.com.
+profile.ak.fbcdn.net.
+www.swglff.com.
+www.eaglepub.com.
+6.184.152.201.in-addr.arpa.
+a1007.w43.akamai.net.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+community.sba.gov.
+duplicadoweb.reniec.gob.pe.
+www.aglasshalffull.org.
+it21.ru.
+novascotialeo.org.
+toolbarqueries.google.com.
+woodbridge-va.patch.com.
+rt.liftdna.com.
+uchilishe.ru.
+www.myspace.com.
+darkc.foroactivo.com.
+ksn1-11-part2.kaspersky-labs.com.
+other.friv2.org.
+101.142.55.65.in-addr.arpa.
+ds.serving-sys.com.
+11.228.171.69.in-addr.arpa.
+sp.cwfservice.net.
+www.astroglide.com.
+a2.sphotos.ak.fbcdn.net.
+smtp.queensbury.com.
+image2.pubmatic.com.
+forums.visual-paradigm.com.
+vip.radioexitolatino.com.
+98.45.113.187.in-addr.arpa.
+114.178.15.84.in-addr.arpa.
+profile.ak.fbcdn.net.
+maccosmetics.tumblr.com.
+external.ak.fbcdn.net.
+www.vertigomagazine.co.uk.
+islacanela.costasur.com.
+ax.init.itunes.apple.com.
+expressandstar.com.
+124.29.251.190.in-addr.arpa.
+tracker.blazing.de.
+dns.msftncsi.com.
+mx25.valuehost.ru.
+232.186.13.201.in-addr.arpa.
+di104.shopping.com.
+img1.blogblog.com.
+122.213.137.186.in-addr.arpa.
+kitart.ru.
+s1-onenote.vo.msecnd.net.
+plus.google.com.
+www.google.com.
+sup.live.com.
+194.78.166.189.in-addr.arpa.
+partner.googleadservices.com.
+139.158.245.189.in-addr.arpa.
+www.ndctz.com.
+bmxplusmag.com.
+mshop.ionroad.com.
+www.facebook.com.
+yulon-nissan.com.tw.
+142.243.167.118.in-addr.arpa.
+marshsedge.net.
+www.gaerneshoes.com.
+pixel.facebook.com.
+108.28.28.186.in-addr.arpa.
+apps.facebook.com.
+www.fundaciontarpuy.org.ar.
+ec.atdmt.com.
+org.saferpage.com.
+181.51.168.192.in-addr.arpa.
+digitalforum.com.
+www.facebook.com.
+smtp.alleghenyfinancial.com.
+cataclysmguide.ru.
+33-courier.push.apple.com.
+dbskcafe.co.nr.
+65.74.236.190.in-addr.arpa.
+201.212.139.98.bl.spamcop.net.
+hcfsinc.com.
+this.id.
+243.123.58.216.in-addr.arpa.
+dns.msftncsi.com.
+freearticlesubmissionsdirectory.com.
+col.stb00.s-msn.com.
+buxsmb.com.
+www.bello.gov.co.
+mlogin.yahoo.com.
+clients1.google.com.
+ltgc.com.s5b1.psmtp.com.
+inspiration.alltop.com.
+futbol.univision.com.
+44.35.57.186.in-addr.arpa.
+i2.ytimg.com.
+graph.facebook.com.
+img100.xvideos.com.
+21.242.171.69.in-addr.arpa.
+renderscope.com.
+234.28.112.186.in-addr.arpa.
+3-courier.push.apple.com.
+creative.ak.fbcdn.net.
+property.
+a.root-servers.net.
+a.root-servers.net.
+cerillion.com.
+www.lemontroyal.qc.ca.
+1pehva4w8.88tk.
+4.113.50.85.in-addr.arpa.
+ns-912.amazonaws.com.
+a.root-servers.net.
+static.ak.fbcdn.net.
+loading3.widdit.com.
+45-courier.push.apple.com.
+kapriol.com.
+a.root-servers.net.
+i2.ytimg.com.
+12.2.54.60.in-addr.arpa.
+5.164.59.199.in-addr.arpa.
+v15.nonxt3.c.youtube.com.
+www.brazzerscafe.com.
+profile.ak.fbcdn.net.
+47.106.87.187.in-addr.arpa.
+180.220.176.187.in-addr.arpa.
+google.com.
+ajax.googleapis.com.
+www.accurate-target.com.
+apps.facebook.com.
+realclimate.org.
+dressesmania.com.
+static.ak.fbcdn.net.
+210.131.254.190.in-addr.arpa.
+10.184.60.184.in-addr.arpa.
+_244_92_7.
+maomelody.wordpress.com.
+es-la.facebook.com.
+img3.imageshack.us.
+lcmcompany.com.s5a2.psmtp.com.
+hges.oao-ntek.ru.
+a3.sphotos.ak.fbcdn.net.
+fyeahforeveralone.tumblr.com.
+rewardchannelcenter.com.
+_472_30_1.
+air-review.ru.
+m.addthisedge.com.
+60.85.160.201.in-addr.arpa.
+82.188.49.190.in-addr.arpa.
+41.70.168.192.in-addr.arpa.
+google.com.
+smtp1.xentrisllc.com.
+a.root-servers.net.
+photos-g.ak.fbcdn.net.
+_339_84_5.
+a.root-servers.net.
+a.root-servers.net.
+mscrl.microsoft.com.
+a2.sphotos.ak.fbcdn.net.
+cdn.bidsystem.com.
+es.ponetelaroja.com.
+www.bendicioness.com.
+sp.cwfservice.net.
+i1.ytimg.com.
+ar-ar.facebook.com.
+handels.gu.se.
+widgets.twimg.com.
+sunnet.com.br.
+sj88p6fyi.a13l8z7b.
+222.11.65.66.in-addr.arpa.
+www.onpointdigital.com.
+_454_04_3.
+docs.google.com.
+ajaxhttpheaders2.appspot.com.
+s1-word-edit.vo.msecnd.net.
+bauldelafamiliaingalls.blogspot.com.
+2101093106605581157-a-1802744773732722657-s-sites.googlegroups.com.
+android.clients.google.com.
+tools.google.com.
+virtultech.com.
+g.ceipmsn.com.
+156.199.162.189.in-addr.arpa.
+www.immigrazioneoggi.it.
+mercadeoprofesional.com.
+gamingzone.dk.msn.com.
+tobolsk.info.
+179.9.138.24.in-addr.arpa.
+www.colombiaenunsolopunto.com.
+in.answers.yahoo.com.
+static.ak.fbcdn.net.
+download340.avast.com.
+www.eng.mcmaster.ca.
+71.48.154.186.in-addr.arpa.
+a248.e.akamai.net.
+60.253.82.190.in-addr.arpa.
+www.facebook.com.
+32.136.152.190.in-addr.arpa.
+profile.ak.fbcdn.net.
+static.socialvi.be.
+xyzxaon53.35do.
+www.statefarm.com.
+www.facebook.com.
+www.solrojo.org.
+view.atdmt.com.
+checkip.dyndns.org.
+av40.hls1.vimeocdn.com.
+www.pauldotcom.com.
+a.root-servers.net.
+www.videosearch.tv.
+de.ufc.com.
+a.root-servers.net.
+scooter.mforos.com.
+wpad.
+ca.reuters.com.
+teredo.ipv6.microsoft.com.
+scholar.google.com.
+www.effectmatrix.com.
+bitacoras.com.
+141.3.0.151.in-addr.arpa.
+db._dns-sd._udp.0.1.168.192.in-addr.arpa.
+x73.cc.
+a1.sphotos.ak.fbcdn.net.
+m.addthisedge.com.
+googleads.g.doubleclick.net.
+www.facebook.com.
+www.google.com.
+www.webmujeractual.com.
+ib.adnxs.com.
+www.whichfranchise.net.au.
+www.clasicooo.com.
+mx02.ecn.purdue.edu.
+cdn.wibiya.com.
+static.ak.facebook.com.
+www.livingroomfurniturenow.com.
+a1796.g.akamai.net.
+135.237.37.174.in-addr.arpa.
+www.laviejaime.com.
+blog.walter-riso.com.
+imap.gmail.com.
+mail.google.com.
+bs.serving-sys.com.
+16.85.168.192.in-addr.arpa.
+s-static.ak.fbcdn.net.
+www.formulamania.com.
+espanol.yahoo.com.
+csi.gstatic.com.
+a.root-servers.net.
+mtalk.google.com.
+dpmail01.doteasy.com.
+www.universalaccess.it.
+204.156.222.201.in-addr.arpa.
+locaboat.com.
+riodb01.ibase.aist.go.jp.
+search.conduit.cm.
+www.igroup.co.za.
+irc.purchaseservice.com.
+bjr.sagepub.com.
+172.179.149.187.in-addr.arpa.
+ads.admarvel.com.
+ajax.googleapis.com.
+vwiy83tle.65ys.
+e906.g.akamaiedge.net.
+i1.ytimg.com.
+www.cuevana.tv.
+capitolfax.com.
+www.gottransmissions.com.
+ebudy.co.
+c72khh:xe.52jj.
+us.taylorwoodrow.com.
+boringpittsburgh.com.
+mail.lincoln-associates.fr.
+89.58.171.187.in-addr.arpa.
+www.ceciliaperez.com.
+huhahi.ru.
+www.subeimagenes.com.
+a.root-servers.net.
+profile.ak.fbcdn.net.
+rospres.com.
+224.5.156.187.in-addr.arpa.
+cdn.api.twitter.com.
+www.affiliateyard.com.
+lists.formoza.ru.
+versioncheck.addons.mozilla.org.
+creatives.livejasmin.com.
+a.root-servers.net.
+www.nlm.nih.gov.
+sub.ezinedirector.net.
+s-static.ak.fbcdn.net.
+mx1.hotmail.com.
+utmtrk.vimeo.com.
+accountservices.msn.com.
+static.ak.fbcdn.net.
+117.229.81.108.in-addr.arpa.
+114.188.53.60.in-addr.arpa.
+20.113.102.189.in-addr.arpa.
+read.chcm.ubc.ca.
+23.152.222.189.in-addr.arpa.
+safebrowsing-cache.google.com.
+leak-squad.ca.
+blog.opensys911.net.
+a1.sphotos.ak.fbcdn.net.
+www.sonirodban.com.
+met-inc.com.
+caminosdeayer.blogspot.com.
+127.233.170.201.in-addr.arpa.
+a.root-servers.net.
+alt1.gmail-smtp-in.l.google.com.
+113.31.221.95.in-addr.arpa.
+profile.ak.fbcdn.net.
+time.windows.com.
+www.kseba.info.
+awio.zendesk.com.
+www-google-analytics.l.google.com.
+tx.sbc.primusvoip.com.
+fbcdn-photos-a.akamaihd.net.
+profile.ak.fbcdn.net.
+www.jessicachina.net.
+google-sketchup-free.softonic.de.
+profile.ak.fbcdn.net.
+a.ads2.msads.net.
+ib.adnxs.com.
+126.224.110.186.in-addr.arpa.
+4083.live.streamtheworld.com.
+tc.v18.cache7.c.youtube.com.
+s0.2mdn.net.
+s-static.ak.fbcdn.net.
+idrc.org.
+tejiendohaciendoconelcorazon.blogspot.com.
+201.53.106.177.in-addr.arpa.
+photos-a.ak.fbcdn.net.
+83.99.14.201.in-addr.arpa.
+h30471.www3.hp.com.
+mail.softassist.com.
+www.villaserbelloni.com.
+aol.com.
+switch.atdmt.com.
+0day.in.
+heartbeat.belkin.com.
+pobeda-cinema.ru.
+clients2.google.com.
+fusion.google.com.
+www.3-0b6f-415d-b5c7-832f0.com.
+www.alfonsosanchez.net.
+m.youtube.com.
+www.izi.fraunhofer.de.
+profile.ak.fbcdn.net.
+a.root-servers.net.
+blst.msn.com.
+maison-otaku.net.
+ecms.net.
+focustechnologies.com.
+sp.cwfservice.net.
+webcache.googleusercontent.com.
+www.reform.co.uk.
+www.facebook.com.
+v4.cache5.c.youtube.com.
+to4vb5ak9.12vr.
+reshade.com.
+18.8.42.201.in-addr.arpa.
+lb._dns-sd._udp.lan.
+gdata.youtube.com.
+97.15.168.192.in-addr.arpa.
+a.root-servers.net.
+a.root-servers.net.
+gandalf.webcohort.com.
+175.190.191.71.in-addr.arpa.
+37.200.10.87.in-addr.arpa.
+42.24.74.187.in-addr.arpa.
+a1804.phobos.apple.com.
+www.textsrv.com.
+www.tuslibrosgratis.net.
+www.logitech.com.
+gn.wikipedia.org.
+photos-e.ak.fbcdn.net.
+www.greenhasitalia.com.
+75.128.253.84.in-addr.arpa.
+pictaregallery.blogspot.com.
+nudebollywood.blog.com.
+mail2.energytransfer.com.
+2bcool.net.
+calendar.live.com.
+www.youtube.com.
+socialmediadaily.com.au.
+apps.facebook.com.
+www.facebook.com.
+meta.izhcom.ru.
+www.appbrain.com.
+indosharing.net.
+www.phototecnia.com.
+www.facebook.com.
+connect.facebook.net.
+mailin-03.mx.aol.com.
+www.google-analytics.com.
+www.cenex.com.
+www.elcolombiano.com.
+rcp.eu.blackberry.com.
+profile.ak.fbcdn.net.
+179.141.207.190.in-addr.arpa.
+ads.buzzcity.net.
+211.148.84.190.in-addr.arpa.
+stjeromes.wa.edu.au.
+adserver.twitpic.com.
+23.252.220.91.in-addr.arpa.
+enac.com.
+0-jx-w.channel.facebook.com.
+redblogsarquitectura.suju.eu.
+mail.northvillecsd.k12.ny.us.
+mail.google.com.
+189.240.212.217.in-addr.arpa.
+te.ru.
+mail2.megatv.com.
+www.msftncsi.com.
+mail.bgok.ru.
+www.google.com.
+connect.facebook.net.
+ballwy.com.
+n4jzv72fv.r23v0l4l.
+a7.sphotos.ak.fbcdn.net.
+253.94.57.62.in-addr.arpa.
+108.164.155.92.in-addr.arpa.
+images-na.ssl-images-amazon.com.
+itb.co.uk.
+226.25.191.189.in-addr.arpa.
+denis.stalker.h3q.com.
+mail1.cosprop.com.
+mail.
+www.gfidalex.com.
+bellfuels.com.
+ssl.apple.com.
+profile.ak.fbcdn.net.
+www.gstatic.com.
+www9.effectivemeasure.net.
+www.youtube.com.
+apps.facebook.com.
+171.206.225.190.in-addr.arpa.
+mcgin.com.
+a.root-servers.net.
+twpiano.opentech.mobi.
+connect.facebook.net.
+www.google.com.
+58.152.241.201.in-addr.arpa.
+v.giantrealm.com.
+97.20.57.85.in-addr.arpa.
+193.65.2.187.in-addr.arpa.
+fls.doubleclick.net.
+d1j68ux4ukg4g1.cloudfront.net.
+mail.featurecreeptechnology.com.
+d1j68ux4ukg4g1.cloudfront.net.
+238.45.16.187.in-addr.arpa.
+redfaceplus.com.
+pixel.facebook.com.
+www.wellsfargo.com.
+aoltech.com.
+col.stb00.s-msn.com.
+sites.google.com.
+ktc-net.ru.
+bitdefender.surveyesun.sgizmo.com.
+www.planering.org.
+muzig-prod.muzigle.com.
+www.aljsad.net.
+150.216.82.62.in-addr.arpa.
+edipresse.adocean.pl.
+www.youtube.com.
+photos-c.ak.fbcdn.net.
+api.nanigans.com.
+business.shop.ebay.com.
+urs.microsoft.com.
+a1001.w40.akamai.net.
+i4.ytimg.com.
+224.252.68.201.in-addr.arpa.
+gtaonline.com.ar.
+47.53.136.14.in-addr.arpa.
+fileham.com.
+static.ak.facebook.com.
+mart.spb.ru.
+a.root-servers.net.
+129.239.31.190.in-addr.arpa.
+www.lavilla2.com.
+www.trust-guard.com.
+ferti-val.com.
+cs5188.vkontakte.ru.
+www.youtube.com.
+61.191.34.201.in-addr.arpa.
+217.43.21.190.in-addr.arpa.
+1d2kusc:c.t11g9f7c.
+amermac.com.
+jamiexelite.ourtoolbar.com.
+95.25.130.181.in-addr.arpa.
+www.bloomberg.co.jp.
+www.uominiedonneanticipazioni.it.
+a.root-servers.net.
+tst.social.technet.microsoft.com.
+ksn2-12.kaspersky-labs.com.
+111.38.252.189.in-addr.arpa.
+56.163.160.187.in-addr.arpa.
+prov.mydlink.com.
+253.189.137.187.in-addr.arpa.
+194.240.91.27.in-addr.arpa.
+i1.ytimg.com.
+pop.secureserver.net.
+pixel.facebook.com.
+api.twitter.com.
+filter.fristampumps.com.
+cadaverlab.com.
+photos-f.ak.fbcdn.net.
+102.146.220.66.in-addr.arpa.
+enforce.com.
+dns.msftncsi.com.
+18.80.108.83.in-addr.arpa.
+www-e.uni-magdeburg.de.
+www.g.home.
+superbar.ru.
+ntp.glb.nist.gov.
+fashionvip.polyvore.com.
+www.gioie.it.
+www.inm.gob.mx.
+mail.matsongmac.com.
+tcpconn2.tencent.com.
+_517_63_5.
+sgtlaw.com.s5a2.psmtp.com.
+qomxppppudxhdfl.com.
+libromagicodeembrujo.blogspot.com.
+spreadsheets.google.com.
+www.reflexionesmarginales.com.
+www.gabrielbustamante.pe.
+a.root-servers.net.
+a.root-servers.net.
+download654.avast.com.
+teredo.ipv6.microsoft.com.
+us.data.toolbar.yahoo.com.
+blogs.sowetanlive.co.za.
+16.10.107.187.in-addr.arpa.
+archiv.fagms.de.
+ak.imgfarm.com.
+fieldale.com.
+90.174.127.201.in-addr.arpa.
+widgets.montiera.com.
+static.ak.fbcdn.net.
+webassets3.sparkybee.com.
+www.gstatic.com.
+echo.edge.messenger.live.com.
+ns1.exit109.com.
+llcrew.com.
+www.google.com.
+jwhodgespc.com.
+www.googleadservices.com.
+google.com.
+barnfield.org.
+wk.net.
+beamershop24.net.
+dr._dns-sd._udp.0.55.211.10.in-addr.arpa.
+nullmx.2extreme.net.
+a5.sphotos.ak.fbcdn.net.
+www.wiseupkids.com.
+rad.msn.com.
+systeam.ru.
+19.253.191.207.in-addr.arpa.
+3.105.93.212.in-addr.arpa.
+daydreamer0207.tumblr.com.
+a1634.phobos.apple.com.
+www.gadi-nowblog.blogspot.com.
+beautyandababy.blogspot.com.
+www.tugbbs.com.
+labitacoradehobsbawm.blogspot.com.
+budwolfchevy.com.
+profile.ak.fbcdn.net.
+www.leycosmica.org.
+admin.vpxsports.com.
+www.qzal.net.
+www.google.com.
+c.aol.com.
+wpad.
+weather.service.msn.com.
+www.addthis.com.
+login.domains.live.com.
+pix04.revsci.net.
+dinz.ru.
+radiopopper.com.
+www.arab-ency.com.
+google.com.
+registry.nafta-sec-alena.org.
+pixel.facebook.com.
+_069_15_0.
+6to4.ipv6.microsoft.com.
+carsale.uol.com.br.
+pop3.live.com.
+directoresenredlga.over-blog.es.
+ads.e-planning.net.
+i4.ytimg.com.
+149.242.212.90.in-addr.arpa.
+www.disneylatino.com.
+sickestaddictions.com.
+100.185.69.216.in-addr.arpa.
+armmf.adobe.com.
+92.204.54.108.in-addr.arpa.
+pagead2.googlesyndication.com.
+183.82.43.89.in-addr.arpa.
+insidemovies.ew.com.
+a7.sphotos.ak.fbcdn.net.
+soundcloud.com.
+photos-d.ak.fbcdn.net.
+www.newuniversity.org.
+s-static.ak.fbcdn.net.
+b._dns-sd._udp.0.2.168.192.in-addr.arpa.
+forums.triplezoom.com.
+5tvm8ne41.f84w6z5t.
+a-0.19-27090041.9050083.1518.19d4.2f4a.10.0.nza1ldzdki8qrtrc7upjzq5b95.avqs.mcafee.com.
+68.139.149.187.in-addr.arpa.
+intermarketandmore.finanza.com.
+fr-fr.facebook.com.
+www.ucmalumnistore.com.
+kapiolani.hawaii.edu.
+w7c6iosj3.w14g9q2q.
+www.paypal.es.
+www.thumbgenie.com.
+autos.mercadolibre.com.ar.
+www.facebook.com.
+translate.googleapis.com.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+ja.wikipedia.org.
+www.tiendamasterhacks.com.
+profile.ak.fbcdn.net.
+www.7irtny.com.
+135.13.31.177.in-addr.arpa.
+mail2.fremuragroup.com.
+i1.ytimg.com.
+phs.org.
+cdn.api.twitter.com.
+s.ytimg.com.
+hustleruniversity.blogspot.com.
+star.facebook.com.
+213.226.2.188.in-addr.arpa.
+www.juegosdepadrinosmagicos.blogspot.com.
+181.3.149.83.in-addr.arpa.
+pacbev.sg.
+.
+hardingcreative.com.
+www.ebay.in.
+s0000090.ecdomain.net.packaging.sca.se.
+mail.gibbymedia.com.
+162.164.178.74.in-addr.arpa.
+www.anaheimoc.org.
+www.google.com.
+45.34.30.190.in-addr.arpa.
+70.138.7.221.in-addr.arpa.
+fbcdn-sphotos-a.akamaihd.net.
+sp.ask.com.
+cdn.mediafire.com.
+b._dns-sd._udp.0.11.168.192.in-addr.arpa.
+filetram.com.
+0-jf-w.channel.facebook.com.
+bibmed.ucla.edu.ve.
+csi.gstatic.com.
+safebrowsing-cache.google.com.
+untwisting.ru.
+api-read.facebook.com.
+twitter.com.
+a2.twimg.com.
+www.google.com.
+csi.gstatic.com.
+lakelly.co.uk.
+teredo.ipv6.microsoft.com.
+0.3896415.com.
+drug.now.nu.
+themixsantamonica.com.
+www.amateurnudie.com.
+www.flour.com.
+a8.sphotos.ak.fbcdn.net.
+ca.hello.dj.
+mostlybricks.com.
+social.bidsystem.com.
+82.133.253.189.in-addr.arpa.
+billing.sharo4ka.ru.
+registeridm.com.
+a.root-servers.net.
+backup-mx.wannafind.dk.
+a3.sphotos.ak.fbcdn.net.
+scholar.google.com.
+www.google.com.
+contactsullivan.com.
+ocsp.verisign.com.
+28.16.191.190.in-addr.arpa.
+bearby.us.
+da.wikipedia.org.
+profile.ak.fbcdn.net.
+aibi.ph.
+iddqd.ru.
+251.182.253.190.in-addr.arpa.
+a.root-servers.net.
+www.webpartypro.com.
+www.google.com.
+180.62.250.190.in-addr.arpa.
+198.114.30.186.in-addr.arpa.
+mw2.google.com.
+luelinks.net.
+mx7.surw.ru.
+fbcdn-photos-a.akamaihd.net.
+www.injoy.com.
+www.youtube.com.
+jsm-law.com.
+85.223.1.72.in-addr.arpa.
+a.root-servers.net.
+www.google.com.
+signin-it.g.ebay.com.
+162.49.77.64.in-addr.arpa.
+a.root-servers.net.
+casitadepapel.wordpress.com.
+85.20.76.188.in-addr.arpa.
+googleads.g.doubleclick.net.
+a2000.phobos.apple.com.
+prodika.com.
+wrma.com.inbound15.mxlogicmx.net.
+google.com.
+www.google.ch.
+214.244.253.189.in-addr.arpa.
+qnjcm71pu.z50h8i4e.
+www.mistertorrent.com.
+avatar.xboxlive.com.
+twitter.com.
+214.55.246.201.in-addr.arpa.
+zencarttemplates.info.
+calgarytunnelling.com.
+edytv.blogspot.com.
+s-static.ak.facebook.com.
+a.root-servers.net.
+extended-validation-ssl.verisign.com.
+80.6.97.190.in-addr.arpa.
+a.root-servers.net.
+bestbuyideax.com.
+sgc5vr5iq.26ta.
+ssl.gstatic.com.
+news.google.com.mx.
+a.root-servers.net.
+w.sharethis.com.
+anyonesson.com.
+pixel.quantserve.com.
+tfws.threatfire.com.
+8nacr96qu.q67n9f6f.
+26.229.171.69.in-addr.arpa.
+beautyfashiontips.net.
+alt2.aspmx.l.google.com.
+photos-b.ak.fbcdn.net.
+b.scorecardresearch.com.
+www.bing.com.
+aresline.com.
+d.yimg.com.
+41.213.90.200.in-addr.arpa.
+partner.googleadservices.com.
+areahouses.com.
+www.erantis.com.
+developers.facebook.com.
+211.11.123.186.in-addr.arpa.
+i3.ytimg.com.
+cc.usart.ru.
+mesu.apple.com.
+a.root-servers.net.
+www.cualcompro.com.
+cdn.api.twitter.com.
+131.105.158.190.in-addr.arpa.
+oss.ticketmaster1st.akadns.net.
+hrcaonline.org.
+nmetrics.samsung.com.
+hotmail.com.
+249.31.11.82.in-addr.arpa.
+144.45.36.187.in-addr.arpa.
+mx1.qwestoffice.com.
+gaom.hit.gemius.pl.
+secure.qmiles.com.
+www.google-analytics.com.
+thumbs4.ebaystatic.com.
+iskrauraltel.ru.
+es1.darkorbit.bigpoint.com.
+www.addtoany.com.
+nuestrobux.com.
+a.root-servers.net.
+a2.sphotos.ak.fbcdn.net.
+data.publishflow.com.
+server3.profileservice.movisol.com.
+www.revistaquimica.cl.
+www.cupoint.com.
+a-patch-2011.softonic.com.
+da.cb.b9.a1.top.mail.ru.
+pixel.facebook.com.
+xlocomotionchannel20x.api.channel.livestream.com.
+www.visual-basic.com.ar.
+ajax.aspnetcdn.com.
+115.120.30.186.in-addr.arpa.
+s.ytimg.com.
+www.google.com.
+www.besteducationalgrants.org.
+125.11.183.67.in-addr.arpa.
+partner.googleadservices.com.
+247.182.131.208.in-addr.arpa.
+a.root-servers.net.
+img215.imageshack.us.
+mscrl.microsoft.com.
+pagead2.googlesyndication.com.
+91.166.243.189.in-addr.arpa.
+youtube.com.
+video.l.google.com.
+53.173.174.206.in-addr.arpa.
+support.createmybb.com.
+www.amazingbizkey.com.
+ocsp.verisign.com.
+download.microsoft.com.
+historiasydemasparanoias.blogspot.com.
+98.73.196.84.in-addr.arpa.
+93.79.37.190.in-addr.arpa.
+xcelplus.com.
+grbnotes.grblaw.com.
+246.16.108.190.in-addr.arpa.
+appsmetadata.toolbar.conduit-services.com.
+19.52.78.186.in-addr.arpa.
+turtlezen.com.
+a2.sphotos.ak.fbcdn.net.
+lvs.fok.nl.
+www.casasderematemonterrey.com.
+en.data.wrapper.services.alawar.com.
+136.105.113.186.in-addr.arpa.
+yahoo.com.
+211.40.46.190.in-addr.arpa.
+94.116.255.206.in-addr.arpa.
+search.iminent.com.
+profile.ak.fbcdn.net.
+api.facebook.com.
+cs12717.vkontakte.ru.
+www.linkwithin.com.
+designs.fedmich.com.
+www.googel.com.
+232.43.168.192.in-addr.arpa.
+tiggermail.com.
+deals.dealply.com.
+www.dr-machine.com.
+a6.sphotos.ak.fbcdn.net.
+www.winamp.com.
+external.ak.fbcdn.net.
+cdn.labpixies.com.
+childrentales.org.mialias.net.
+zpay.static.zynga.com.
+158.244.3.187.in-addr.arpa.
+api-read.facebook.com.
+66.82.11.186.in-addr.arpa.
+photos-d.ak.fbcdn.net.
+pismo.com.s8a2.psmtp.com.
+www.google.com.
+b.compunass.org.
+ads.cartrade.com.
+a8.sphotos.ak.fbcdn.net.
+38.50.45.190.in-addr.arpa.
+ethionet.et.
+adserving.cpxinteractive.com.
+triwest.net.
+www.laboiteverte.fr.
+www.conexionabierta.com.ar.
+teredo.ipv6.microsoft.com.
+www.youtube.com.
+62.15.254.201.in-addr.arpa.
+e3499.c.akamaiedge.net.
+rsemfg5bv.i36c2j2q.
+mail.isilo.com.
+ap.dasglobal.com.
+mms.whatsapp.net.
+static.yandex.st.
+aol.com.
+forthebubbles.wordpress.com.
+plusone.google.com.
+external.ak.fbcdn.net.
+www.facebook.com.
+95.238.109.84.in-addr.arpa.
+g.msn.com.
+s-static.ak.fbcdn.net.
+crl.microsoft.com.
+wpc.3adc.edgecastcdn.net.
+a.root-servers.net.
+static.ak.fbcdn.net.
+ad.z5x.net.
+creative.ak.fbcdn.net.
+a.root-servers.net.
+www.juegosgt.com.
+www.iej.cl.
+projectfive-oh.blogspot.com.
+www.quien.com.
+42.96.212.201.in-addr.arpa.
+ims.tkmna.thyssenkrupp.com.
+a2.sphotos.ak.fbcdn.net.
+www.forexinvestments.de.
+www.youtube.com.
+a.root-servers.net.
+photos-a.ak.fbcdn.net.
+lbcwre.com.
+a.root-servers.net.
+programming-tools.ab-archive.net.
+152.187.152.189.in-addr.arpa.
+lrvbokqag.cn.
+ar-ar.facebook.com.
+www.quiebrapiezas.blogspot.com.
+twitter.com.
+ajax.googleapis.com.
+a845.b.akamai.net.
+apis.google.com.
+mail.americaninterbanc.com.
+www.bilderberg.org.
+52.133.213.201.in-addr.arpa.
+bo.starmedia.com.
+gfx2.hotmail.com.
+23.184.8.186.in-addr.arpa.
+photos-g.ak.fbcdn.net.
+www.todox.org.
+mfcllp.com.
+wiaderko.net.
+cotendo.cedexis.com.
+12meds.com.lan.
+static.ak.fbcdn.net.
+3-ps.googleusercontent.com.
+es-es.fxfeeds.mozilla.com.
+alexandertranfer.com.
+www.tuinfosoft.net.
+221.54.134.190.in-addr.arpa.
+adfiscass.nl.
+a2.sphotos.ak.fbcdn.net.
+profile.ak.fbcdn.net.
+www.justfashionmodels.com.
+dns.msftncsi.com.
+a.root-servers.net.
+v8.nonxt5.c.youtube.com.
+m5pqh4nwr.66vi.
+91.166.109.186.in-addr.arpa.
+116.182.136.2.in-addr.arpa.
+publicidade.abril.com.br.
+127.0.0.1.
+b._dns-sd._udp.0.1.168.192.in-addr.arpa.
+a248.e.akamai.net.
+sites.google.com.
+86.180.105.177.in-addr.arpa.
+haaallie-.piczo.com.
+138.247.132.187.in-addr.arpa.
+google.com.
+55.115.173.190.in-addr.arpa.
+10.124.40.77.in-addr.arpa.
+lovecalculator2.com.
+ws-cloud-msgplus.linkury.com.
+profile.ak.fbcdn.net.
+t3.gstatic.com.
+www.arcticultra.de.
+time-nw.nist.gov.
+planocreativo.files.wordpress.com.
+hv2m91.tu.tv.
+pixel.facebook.com.
+shopping.search.yahoo.co.jp.
+nodes.affidirect.com.
+static.4shared.com.
+ar-ar.facebook.com.
+skydrive.live.com.
+4mostip.com.
+www.asian-pleasures-asianpleasures.com.
+escribesconmigo.blogspot.com.
+photos-d.ak.fbcdn.net.
+a.root-servers.net.
+a.root-servers.net.
+www.smartadserver.com.
+54.205.50.190.in-addr.arpa.
+msn.com.
+_872_53_4.
+www.google-analytics.com.
+johnsonbodyshop.com.
+ksn2-12.kaspersky-labs.com.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+xqeydnuwhqt.net.
+metronews.com.s8a1.psmtp.com.vval.com.
+a.root-servers.net.
+www.facebook.com.
+a3.sphotos.ak.fbcdn.net.
+teredo.ipv6.microsoft.com.
+vf.cloud.avg.com.
+yourwardrobeunlockd.com.
+s3.amazonaws.com.
+c.gigcount.com.
+69.151.241.201.in-addr.arpa.
+79.111.8.201.in-addr.arpa.
+external.ak.fbcdn.net.
+walworthcountytoday.com.
+222.9.106.186.in-addr.arpa.
+_068_02_6.
+i2.ytimg.com.
+www.facebook.com.
+photos-a.ak.fbcdn.net.
+mail.google.com.
+rd.meebo.com.
+www.emol.com.
+244.135.41.119.in-addr.arpa.
+113.190.250.189.in-addr.arpa.
+pop.mail.yahoo.com.cn.
+www.facebook.com.
+_669_83_3.
+www.youtube.com.
+www.seebiz.eu.
+www.ehea.info.
+www.loverpass.com.
+a5.sphotos.ak.fbcdn.net.
+presicom.com.
+smtp01.delhi.edu.
+7.198.98.189.in-addr.arpa.
+1979304085345356636-a-1802744773732722657-s-sites.googlegroups.com.
+www.facebook.com.
+firstamericanmortgageinc.com.
+api.twitter.com.
+www.dwinsider.com.
+whos.amung.us.
+mail.dynamicfenceinc.com.
+149.21.16.190.in-addr.arpa.
+djknight.com.
+premier.sonetpremier.com.
+www.google.com.
+ntp.glb.nist.gov.
+matcher.bidder8.mookie1.com.
+pwdsl3w71.61nf.
+www.google-analytics.com.
+garyes.stormloader.com.
+70.205.97.190.in-addr.arpa.
+www.webmoney.ru.
+time.windows.com.
+talkmarketing.com.
+www.smiles.ie.
+245.41.141.89.in-addr.arpa.
+www.amantesdeteruel.es.
+connect.facebook.net.
+sniperlandia.webcindario.com.
+farm7.static.flickr.com.
+b._dns-sd._udp.lan.
+ntp.glb.nist.gov.
+grandcyberglobal.com.
+173.114.136.190.in-addr.arpa.
+177.172.93.186.in-addr.arpa.
+www.facebook.com.
+external.ak.fbcdn.net.
+ci.lincoln.ca.us.
+companyname.122.2o7.net.
+209.125.53.186.in-addr.arpa.
+ww2.shemaleambush.com.
+radioalgarve.com.
+226.61.168.192.in-addr.arpa.
+www.swingsurgeon.com.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+a.root-servers.net.
+www.googleadservices.com.
+photos.pokerplayer.co.uk.
+cbmcint-org.mail.eo.outlook.com.
+a.root-servers.net.
+photos-h.ak.fbcdn.net.
+wpad.
+wwws.projectgenesis.org.
+29.51.66.187.in-addr.arpa.
+0bps664l3vqk05dj8qih0t5renri9iic.ig.ig.gmodules.com.
+checkip.dyndns.org.
+es-es.facebook.com.
+googleads.g.doubleclick.net.
+jp.tous.com.
+81.229.246.148.in-addr.arpa.
+fotos.amigate.com.
+www.fastmarkets.com.
+wickedcampers.com.au.
+62.197.88.74.in-addr.arpa.
+a.root-servers.net.
+static.ak.fbcdn.net.
+www.google.com.
+137.227.250.190.in-addr.arpa.
+w3.coh.arizona.edu.
+64.102.30.190.in-addr.arpa.
+static.exoclick.com.
+pixel.facebook.com.
+fbpanel.sourceforge.net.
+view.atdmt.com.
+3.242.114.200.in-addr.arpa.
+mx1.cboss.ru.
+photos-e.ak.fbcdn.net.
+webs.rakurs.com.
+www.extremista.com.ar.
+i.lulzimg.com.
+feeds.bbci.co.uk.
+a.root-servers.net.
+186.187.142.187.in-addr.arpa.
+mail.modernpest.com.
+217.137.145.201.in-addr.arpa.
+www.revistakronos.com.
+184.89.241.66.in-addr.arpa.
+public5.tektek.org.
+rebeccaminkoff.com.
+a.root-servers.net.
+bioware.com.
+www2.nissan.es.
+heltenkelthosmig.blogspot.com.
+gfx2.hotmail.com.
+1.0.0.127.dnsbugtest.1.0.0.127.in-addr.arpa.
+certs.opera.com.
+safebrowsing.clients.google.com.
+168.187.202.190.in-addr.arpa.
+243.171.153.187.in-addr.arpa.
+donate.cwf-fcf.org.
+directorio.fandejuegos.com.
+242.82.153.189.in-addr.arpa.
+www.cabinainterestelar.com.
+www.derechoambiental.udp.cl.
+severe-caning.spanking18.com.
+prin.ru.
+a.root-servers.net.
+2.1.168.192.in-addr.arpa.
+79.48.168.192.in-addr.arpa.
+unixcommerce.com.
+www.pinkribbonstore.com.
+a4.sphotos.ak.fbcdn.net.
+65.10.171.187.in-addr.arpa.
+themes.googleusercontent.com.
+tracker.ilibr.org.
+d3.iesc.org.
+www.facebook.com.
+i3.ytimg.com.
+gfx3.hotmail.com.
+pgnzheoi.info.
+176.62.76.190.in-addr.arpa.
+leercondevoridad.blogspot.com.
+loewarch.com.
+bloggista.com.
+www.stayvillage.com.
+profile.ak.fbcdn.net.
+supports.jiaju.sina.com.cn.
+dsn8.d.skype.net.
+pubads.g.doubleclick.net.
+a1.sphotos.ak.fbcdn.net.
+hosting.lockhosts.com.
+count.pro09.iciba.com.
+www.clr.net.
+faml.ru.
+pld.com.s9b2.psmtp.com.
+www.bodyjewelry.com.
+sn21.mailshell.net.
+www.fulltubemovies.com.
+mail.who-remembers-me.com.
+www.marcorascon.org.
+external.ak.fbcdn.net.
+samson.hac.com.
+www.na7la.com.
+relay2.sptk.com.ru.
+www.therecruitmentjob.com.
+photos-h.ak.fbcdn.net.
+a06.t26.net.
+19.133.210.201.in-addr.arpa.
+www.juegosvestirchicas.com.
+partner.googleadservices.com.
+affiliate.buy.com.
+mail.samaraintour.ru.
+www.facebook.com.
+72.115.164.190.in-addr.arpa.
+zbar.zynga.com.
+fonts.googleapis.com.
+a.root-servers.net.
+rocketmail.om.
+csi.gstatic.com.
+msgr.updates.yahoo.com.
+www.heritagedaily.com.
+en.wikipedia.org.
+shankars.com.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+a957.g.akamai.net.
+158.88.212.190.in-addr.arpa.
+jiguli.ru.
+www.aardvarkrecords.co.uk.
+haverford.edu.
+vp.sip.messenger.msn.com.
+cnna.gob.ec.
+2.203.92.201.in-addr.arpa.
+easel.ru.
+s-static.ak.fbcdn.net.
+kcnet.net.
+ragnartheraider.newgrounds.com.
+atomixmag.com.
+t-one.net.s5a1.psmtp.com.
+a7.sphotos.ak.fbcdn.net.
+bs.serving-sys.com.
+foro.ludoslegio.com.
+eccocanada.com.
+cdn-5.pics.t8premium.com.
+www.justin.tv.
+buscandouniversidad.com.
+124.102.198.190.in-addr.arpa.
+photos-e.ak.fbcdn.net.
+sci.com.
+google.com.
+s0.2mdn.net.
+fms-eu5.panet.co.il.
+mx02.peoplepc.com.
+profile.ak.fbcdn.net.
+rvb.wikia.com.
+106.179.190.190.in-addr.arpa.
+a.root-servers.net.
+www.buraannews.com.
+weiterleitung.k1.cx.
+api.twitter.com.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+b.scorecardresearch.com.
+touch.facebook.com.
+www.ntius.com.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+smtpmsa.msanet.com.
+209.199.56.85.in-addr.arpa.
+www.laira.dominarlaira.com.
+jameique.com.
+ads.iforex.com.
+s7.addthis.com.
+www.brunoymaria.com.
+www.facebook.com.
+www.troid.org.
+fbcdn-photos-a.akamaihd.net.
+sp-metal.ru.
+rwerheinbraun.com.
+counter.cnw.cz.
+estaticos04.cache.el-mundo.net.
+wac.edgecastcdn.net.
+photos-c.ak.fbcdn.net.
+ads.bluelithium.com.
+mygzytvo6.52ez.
+potugalmail.pt.
+www.fbookbanners.net.
+204.69.65.187.in-addr.arpa.
+cdn.api.twitter.com.
+lanza.chulojuegos.com.
+quintoatieneunblog.blogspot.com.
+profile.ak.fbcdn.net.
+www.wdc.com.
+photos-a.ak.fbcdn.net.
+api.twitter.com.
+mail.google.com.
+164.231.97.92.in-addr.arpa.
+translate.google.com.
+nyit.com.
+mail.urlmutual.com.
+zse.com.
+www.avis.com.ar.
+a4.sphotos.ak.fbcdn.net.
+es-la.facebook.com.
+pagead2.googlesyndication.com.
+mghribia.canalblog.com.
+dqobor.com.
+t.co.
+cdn.api.twitter.com.
+time.chttl.com.tw.
+a3.sphotos.ak.fbcdn.net.
+a.root-servers.net.
+a.root-servers.net.
+gmx.ivwbox.de.
+106.227.155.85.in-addr.arpa.
+hepburnlaw.com.
+tsm05.eset.com.
+comcs.net.
+itistimetothinkformyself.blogspot.com.
+mail1.maciraq.com.
+117.51.46.189.in-addr.arpa.
+t2.gstatic.com.
+129.186.253.189.in-addr.arpa.
+googleads.g.doubleclick.net.
+lascuentasbancarias.com.ar.
+107.15.165.189.in-addr.arpa.
+chiraltech.com.inbound15.mxlogic.net.
+ut45forvh.j60l4q7i.
+www.andaluciajunta.es.
+us.mg1.mail.yahoo.com.
+anuncios-personales.vivastreet.com.mx.
+zh-cn.facebook.com.
+techspotting.org.
+www.tungstenworld.com.
+buscador.terra.com.pe.
+www.google.com.
+a.root-servers.net.
+pt-br.facebook.com.
+s2.youtube.com.
+communities.disqus.com.
+12.139.49.81.in-addr.arpa.
+itbusiness.disqus.com.
+b.mail.google.com.
+339mbwbhs.76qa.
+a.root-servers.net.
+mail.glare-n-dazzle.com.
+optimized-by.rubiconproject.com.
+_sip._tls.wartsila.com.
+i4.ytimg.com.
+ww.pendonas.net.
+www.videostravelguide.com.
+a1.sphotos.ak.fbcdn.net.
+rss.msnbc.msn.com.
+exprintur.com.
+www.18toplay.com.
+developers.facebook.com.
+tc22.easythumbhost.com.
+www.facebook.com.
+182.126.197.201.in-addr.arpa.
+swebmail.net.
+m.facebook.com.
+fbcdn-profile-a.akamaihd.net.
+www.avrilsforum.net.
+e.deviantart.net.
+rgzl1hp3b.b19o1w5q.
+www.urmc.rochester.edu.
+jimdo.ru.
+106.190.13.189.in-addr.arpa.
+static.ak.fbcdn.net.
+mail.gudemangroup.com.
+www.textsrv.com.
+load.exelator.com.
+pitchfork.com.
+www.update.microsoft.com.
+www.apple.com.
+:yd1wrz11.19gr.
+sijoittajaksi.blogit.kauppalehti.fi.
+se.altavista.com.
+s-static.ak.facebook.com.
+a.root-servers.net.
+img203.yfrog.com.
+cleorecs.com.
+161.109.236.204.in-addr.arpa.
+ping3.dyngate.com.
+timelapses.tv.
+crl.microsoft.com.
+customapp.golfballs.com.
+ib.adnxs.com.
+photos-c.ak.fbcdn.net.
+platform.twitter.com.
+www.facebook.com.
+orient-usa.com.inbound15.mxlogicmx.net.
+safebrowsing-cache.google.com.
+131.245.50.211.in-addr.arpa.
+trilliumcorp-com.mail.eo.outlook.com.
+www.slideshare.net.
+251.133.221.189.in-addr.arpa.
+none.
+www.guerillahost.com.
+www.facebook.com.
+mail.ravitron.com.
+cs13088.vkontakte.ru.
+astrologia.com.co.
+fbcdn-profile-a.akamaihd.net.
+a.root-servers.net.
+es-la.facebook.com.
+www.ingdirect.com.au.
+opensudoku.softonic.com.
+supertracker.flashget.com.
+paac.org.
+.
+newsrss.bbc.co.uk.
+21.57.81.173.in-addr.arpa.
+mail2.kcs.ru.
+41.0.160.189.in-addr.arpa.
+static.ak.fbcdn.net.
+feedlb2.feedsportal.com.
+ads1.msads.net.
+www.facebook.com.
+www.msdiagnosed.org.
+anthologymag.com.
+photos-g.ak.fbcdn.net.
+digg.com.
+james-camerons-avatar-the-game.en.softonic.com.
+services.vesti.ru.
+197.48.106.216.in-addr.arpa.
+hog.assets.zgncdn.com.
+pubads.g.doubleclick.net.
+101.172.168.67.in-addr.arpa.
+alerts.conduit-services.com.
+nz.video.yahoo.com.
+www.formatmag.com.
+253.224.121.200.in-addr.arpa.
+131.169.111.98.in-addr.arpa.
+236.124.136.175.in-addr.arpa.
+huevosoro.com.
+102.86.139.187.in-addr.arpa.
+lwltlvlwl.com.
+supremenola.com.
+economics.uoregon.edu.
+tweetcam.me.s3-website-us-east-1.amazonaws.com.
+pixel.facebook.com.
+hi-in.facebook.com.
+media.king5.com.
+airbrakeapp.com.
+www.sabadell.net.
+www.facebook.com.
+proxy-bay.contacts.msn.com.
+a4.sphotos.ak.fbcdn.net.
+col.stj.s-msn.com.
+voipc.sip.yahoo.com.
+zgn.static.zynga.com.
+interceptor.ridgways.com.
+googleads.g.doubleclick.net.
+mail.wood-guard.com.
+mx.s.dion.ne.jp.
+m.ak.fbcdn.net.
+dotjohn.com.
+airlineguide.org.
+upload.wikimedia.org.
+lightworker.com.
+www.pantythumbz.com.
+elkaru.ru.
+138.24.24.187.in-addr.arpa.
+adserving.cpxinteractive.com.
+rktekt.com.
+mail.the3rdlevel.com.
+scrambledbrains.net.
+pubads.g.doubleclick.net.
+www.google.com.
+a5.sphotos.ak.fbcdn.net.
+photos-e.ak.fbcdn.net.
+www.pinballrebel.com.
+a1811.g.akamai.net.
+legioninsurance.com.inbound10.mxlogicmx.net.
+mailserver.newhorizonsglobal.com.
+apis.google.com.
+photos-b.ak.fbcdn.net.
+d31ahpoxjzaj3o.cloudfront.net.
+c.gigcount.com.
+cl.hilti.com.
+discoveryresourcesinc.com.
+msc.wlxrs.com.
+profile.ak.fbcdn.net.
+psimago.blogspot.com.
+toolbarqueries.google.com.
+accounts.google.com.
+49.135.107.71.in-addr.arpa.
+ds.serving-sys.com.
+a.root-servers.net.
+www.ultrafastproxy.com.
+bly.chel.rgs.ru.
+ldr.newsltd.com.au.
+googleads.g.doubleclick.net.
+tb.gooofull.com.
+ca.indeed.com.
+147.28.0.181.in-addr.arpa.
+mesu.apple.com.
+secure-uk.imrworldwide.com.
+microsoft.com.rhsbl.ahbl.org.
+community.istaria.com.
+api.demandbase.com.
+colon.com.
+cheatsoft.su.
+185.173.44.190.in-addr.arpa.
+151.0.130.66.in-addr.arpa.
+alerts.conduit-services.com.
+cdn.api.twitter.com.
+kualaterengganu.olx.com.my.
+10.240.7.50.in-addr.arpa.
+cdn.anastasiadate.com.
+a5.sphotos.ak.fbcdn.net.
+interactivos.lavanguardia.com.
+www.autodoc.ru.
+a6.sphotos.ak.fbcdn.net.
+ping.chartbeat.net.
+a.root-servers.net.
+a2.sphotos.ak.fbcdn.net.
+developers.facebook.com.
+netlink.co.uk.
+serv.luch-pk.ru.
+waypt.com.
+get.adobe.com.
+74.9.95.190.in-addr.arpa.
+ersiko.ru.
+101.80.237.68.in-addr.arpa.
+a.root-servers.net.
+1.map.pop6.com.
+apis.google.com.
+ssl.gstatic.com.
+fuelcellsworks.com.
+a.root-servers.net.
+a.root-servers.net.
+www3.l.google.com.
+a5.sphotos.ak.fbcdn.net.
+166.148.144.187.in-addr.arpa.
+tools.google.com.
+tzlynnby.info.
+www.yo-auto.ru.
+227.110.171.187.in-addr.arpa.
+uniqsolutions.ru.
+t2.gstatic.com.
+95.181.87.190.in-addr.arpa.
+a3.sphotos.ak.fbcdn.net.
+107.167.226.189.in-addr.arpa.
+a.root-servers.net.
+143.149.134.186.in-addr.arpa.
+relay.voice.messenger.msn.com.
+123.cn.
+93.186.181.89.in-addr.arpa.
+rollshield.com.
+a8.sphotos.ak.fbcdn.net.
+members.allover30.com.
+www.hedgehogim.com.
+mail.rus01.ru.
+a.root-servers.net.
+clients1.google.com.
+lefima.net.
+messenger.services.live.com.
+c5.zedo.com.
+www.radio-electronics.com.
+www.ybonline.co.uk.
+thumbs.bondagester.com.
+1.0.0.127.dnsbugtest.1.0.0.127.in-addr.arpa.
+218.180.82.200.in-addr.arpa.
+www.facebook.com.
+images.findthebestteens.com.
+www.tazaghiin.com.
+www.note4piano.com.
+a6.sphotos.ak.fbcdn.net.
+www.miningtopnews.com.
+messenger.vo.msecnd.net.
+136.92.6.189.in-addr.arpa.
+mail.carelsa.com.
+a.root-servers.net.
+connect.facebook.net.
+www.cuk.ch.
+57.197.39.46.in-addr.arpa.
+a1.sphotos.ak.fbcdn.net.
+121.223.84.200.in-addr.arpa.
+i1081.photobucket.com.
+220.54.106.186.in-addr.arpa.
+photos-c.ak.fbcdn.net.
+www.foroclasico.com.
+superiorsoft.com.
+t.co.
+poppedculture.stumbleupon.com.
+65.216.141.79.in-addr.arpa.
+www.xntk.net.
+toolbar.zynga.com.
+sympatico.ca.
+scgi.ebay.com.
+checkip.dyndns.org.
+www.marykayintouch.com.mx.
+www.sorry.com.co.
+a.root-servers.net.
+a.root-servers.net.
+g.ceipmsn.com.
+api.partners.ezetop.com.
+54.90.14.186.in-addr.arpa.
+0bps664l3vqk05dj8qih0t5renri9iic.ig.ig.gmodules.com.
+onlinebizdirectory.com.
+a.tribalfusion.com.
+a.root-servers.net.
+mavericktv.co.uk.
+theschuckcorporation.com.
+rblns69.mailshell.net.
+www1.macys.com.
+www.facebook.com.
+static.ak.fbcdn.net.
+5ssc.com.
+a6.sphotos.ak.fbcdn.net.
+109.107.81.190.in-addr.arpa.
+a.root-servers.net.
+i.ytimg.com.
+214.186.187.79.in-addr.arpa.
+accounts.google.com.
+fresno.apartmenthomeliving.com.
+pbimail1.prodigy.net.
+csklegal.com.pri-mx.na0100.smtproutes.com.
+a.root-servers.net.
+179.149.102.218.in-addr.arpa.
+ad.app366.com.
+218.23.173.95.in-addr.arpa.
+www.tragamonedas-online.com.ar.
+clients2.google.com.
+hths.mcvsd.k12.nj.us.
+ponafotipuboduk.in.
+elrellano.com.
+i3.ytimg.com.
+61.231.252.72.in-addr.arpa.
+ilovemilkandcookies.blogspot.com.
+crl.microsoft.com.
+da.wikipedia.org.
+creative.ak.fbcdn.net.
+sionosexy.com.
+www.facebook.com.
+www.abc.es.
+www.multimediaboom.com.
+weightloss.about.com.
+c713352.r52.cf2.rackcdn.com.
+www.recettesdevalerie.com.
+football.frivcute.com.
+static.ak.fbcdn.net.
+ybinst3.ec.yimg.com.
+_237_57_7.
+a1108.da1.akamai.net.
+236.11.105.190.in-addr.arpa.
+drawdogg.blogspot.com.
+lilitmac.tumblr.com.
+29.media.tumblr.com.
+ismailia.ie-eg.com.
+a.root-servers.net.
+accounts.l.google.com.
+coloradocollege.edu.mail4.psmtp.com.
+photos-b.ak.fbcdn.net.
+teredo.ipv6.microsoft.com.
+soultouchenterprisesllc.com.
+mariosonicgames.blogspot.com.
+www.hotmail-iniciarsesion.com.
+www.xtremetop100.com.
+click.infospace.com.
+3.13.93.115.in-addr.arpa.
+a7.sphotos.ak.fbcdn.net.
+fieldjerger.com.s7a2.psmtp.com.
+182.184.207.213.in-addr.arpa.
+koolatsafety.com.au.
+developers.facebook.com.
+www.google-analytics.com.
+zh-cn.facebook.com.
+weather.partners.msn.com.
+28.189.90.186.in-addr.arpa.
+www.flowhot.net.
+google.com.
+maps.google.es.
+mail.foss-as.no.
+mail.takneat.com.
+photos-a.ak.fbcdn.net.
+a5.sphotos.ak.fbcdn.net.
+tablero.ms.gba.gov.ar.
+accountservices.msn.com.
+t.invitemedia.com.
+kaskus.com.
+78.151.9.118.in-addr.arpa.
+photos-h.ak.fbcdn.net.
+pix04.revsci.net.
+87.35.255.201.in-addr.arpa.
+www.diariodetuxpan.com.mx.
+167.230.109.83.in-addr.arpa.
+hpiintl.com.
+a771.da1.akamai.net.
+fab.at.
+ads.bluelithium.com.
+63.233.10.186.in-addr.arpa.
+_468_85_1.
+teredo.ipv6.microsoft.com.
+_174_62_2.
+htamerica.com.
+t2.gstatic.com.
+amer.rel.msn.com.
+150.226.44.200.in-addr.arpa.
+allisimpsonfans.com.
+images.compunoa.com.
+32.71.6.186.in-addr.arpa.
+devsgoons.com.
+232.78.240.189.in-addr.arpa.
+6.113.207.186.in-addr.arpa.
+gla1as50.aggrekonet.biz.
+photos-f.ak.fbcdn.net.
+www.googleadservices.com.
+login.live.com.
+news.google.com.mx.
+a.root-servers.net.
+a.root-servers.net.
+cdn6.liquidtelevision.com.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+hyperquan.com.
+m.addthisedge.com.
+209.90.251.190.in-addr.arpa.
+geo.tp-cdn.com.
+a.root-servers.net.
+xnd3dsf:u.75hx.
+karpovka.spb.ru.
+fandmbank.com.
+32.178.160.218.in-addr.arpa.
+external.ak.fbcdn.net.
+32.191.178.186.in-addr.arpa.
+db.local.clamav.net.
+135.209.251.190.in-addr.arpa.
+chi8yedhy.58gs.
+www.youtube.com.
+79.4.43.186.in-addr.arpa.
+platform.twitter.com.
+1066087.r.msn.com.
+www.bcba.sba.com.ar.
+a.root-servers.net.
+a.root-servers.net.
+plusone.google.com.
+moorti.org.ru.
+msfs.nspmotion.com.
+www.spokentoyou.com.
+transfer-net.ru.
+developers.facebook.com.
+websearch.ask.com.
+s01.divxden.com.
+23.56.101.187.in-addr.arpa.
+api-read.facebook.com.
+139.2.8.200.in-addr.arpa.
+a1.sphotos.ak.fbcdn.net.
+plus.google.com.
+static.ak.fbcdn.net.
+syndication.exoclick.com.
+16-courier.push.apple.com.
+live.com.
+www.whatsalary.com.
+mail.piedmontcsb.org.
+bmo.com.
+nabewise.com.
+www.google.com.
+tap2-cdn.rubiconproject.com.
+www.holisticmedicine.org.
+megatitan.ru.
+www.manhattanmedia.com.
+216.74.175.187.in-addr.arpa.
+brahms.ircam.fr.
+s-static.ak.fbcdn.net.
+es-la.facebook.com.
+s2.youtube.com.
+googleads.g.doubleclick.net.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+ratings-wrs.symantec.com.
+srp.mtvn.com.
+safebrowsing.clients.google.com.
+s-static.ak.facebook.com.
+support.google.com.
+kurdish.sbeiy.com.
+uk.motoseller.com.
+_271_17_1.
+mx.yahoo.com.
+www.facebook.com.
+videos.softonic.com.
+mxico2022-2026.blogspot.com.
+253.115.49.190.in-addr.arpa.
+mail.autoinsuranceamerica.com.
+mdcontinentalconstruction.com.
+lovepredictions.net.
+www.150babes.com.
+a6.sphotos.ak.fbcdn.net.
+ns1.blink.ca.
+www.translate.google.es.
+static2.dmcdn.net.
+a7.sphotos.ak.fbcdn.net.
+i3.ytimg.com.
+books.google.com.mx.
+s0.2mdn.net.
+fupducktv.com.
+breath.net.
+mefas.com.
+.
+33.240.137.187.in-addr.arpa.
+www.youtube.com.
+connect.facebook.net.
+barnhartguess.com.
+yui.yahooapis.com.
+api.appshopper.com.
+www.vgf.com.
+194.52.139.98.combined.njabl.org.
+77.216.193.173.in-addr.arpa.
+hotmail.com.
+widgets.montiera.com.
+:sr1293gx.15yt.
+www.blogger.com.
+3ibe9g88l.47by.
+magazintravel.ru.
+jo4zfro63.77id.
+a8.sphotos.ak.fbcdn.net.
+dl-ssl.google.com.
+www.optionsclearing.com.
+248.196.226.190.in-addr.arpa.
+180.16.159.187.in-addr.arpa.
+download310.avast.com.
+bulrlrh14axe11gshtmwatm39kyn40ntg23gs.net.
+a-0.19-2709a081.99c0083.1518.19d2.3ea1.210.0.aktazdp51b34gma5pp33cfbhh5.avqs.mcafee.com.
+updatekeepalive.mcafee.com.
+142.8.122.190.in-addr.arpa.
+accounts.google.com.
+playmorfarm.com.
+vw2so4spb.j04k3f2x.
+api.gamatar.org.
+es.wikipedia.org.
+mrglaubitz.com.
+margotloyola.ucv.cl.
+www.wathakker.net.
+153.148.191.189.in-addr.arpa.
+photos-a.ak.fbcdn.net.
+3.bp.blogspot.com.
+eventureevents.com.
+4food.ru.
+a.root-servers.net.
+r.mzstatic.com.
+197.45.160.187.in-addr.arpa.
+www.redpymes.org.ar.
+4minutos.es.
+photos-f.ak.fbcdn.net.
+cdcconinc.com.
+www.valinor.com.br.
+m.adnxs.com.
+creative.ak.fbcdn.net.
+73.139.130.12.bl.spamcop.net.
+www.miniclip.com.
+skydrive.live.com.
+i3.ytimg.com.
+porquesi.obolog.com.
+req.appads.com.
+gvntv.gvnstudio.com.
+it.kingdomhearts.wikia.com.
+blogacsessories.googlecode.com.
+pagead2.googlesyndication.com.
+95.196.203.190.in-addr.arpa.
+0-ih-w.channel.facebook.com.
+82.39.52.190.in-addr.arpa.
+e3191.c.akamaiedge.net.
+static-ak.vivastreet.com.
+igor.facemoods.com.
+crl.microsoft.com.
+ocsp.entrust.net.
+222.95.86.200.in-addr.arpa.
+aol.com.
+www.muzlife.com.
+pagead2.googlesyndication.com.
+www.google-analytics.com.
+renees.com.s200b2.psmtp.com.
+openx.wooga.com.
+cbs1.com.
+169.147.69.189.in-addr.arpa.
+a7.sphotos.ak.fbcdn.net.
+slb.liveprofile.com.
+80.249.228.189.in-addr.arpa.
+psp.ongames.com.
+bauer-at.com.
+linkhelp.clients.google.com.
+bahamas.com.
+photos-e.ak.fbcdn.net.
+b18azismxlxk67gviqf52o31n60d30k57f32eucw.com.
+www.facebook.com.
+ib.adnxs.com.
+217.13.216.15.in-addr.arpa.
+quintadoriodao.com.
+ns2.dialsprint.net.
+lospatosenlaluna.blogspot.com.
+img2.rexmag.net.
+yong0218.translatej.hop.clickbank.net.
+8.18.168.192.in-addr.arpa.
+granciasa.com.
+134.61.223.189.in-addr.arpa.
+a4.sphotos.ak.fbcdn.net.
+a.root-servers.net.
+podcasts.yahoo.com.
+a4.sphotos.ak.fbcdn.net.
+www.nicholasrhea.co.uk.
+alerts.conduit-services.com.
+www.emadbaghi.com.
+169.96.69.87.in-addr.arpa.
+api.twitter.com.
+b.scorecardresearch.com.
+dentalsolo.ru.
+mail.ausonia.ru.
+clients1.google.com.
+morose.fotoplenka.users.photofile.ru.
+sp.search-results.com.
+www.sim.redee.com.
+safebrowsing.clients.google.com.
+235.3.161.189.in-addr.arpa.
+checkvist.com.
+a.root-servers.net.
+a.root-servers.net.
+dns.msftncsi.com.
+portal.ku.edu.kw.
+www.wikimediafoundation.org.
+www.rockrose.ca.
+a.root-servers.net.
+9.162.14.181.in-addr.arpa.
+dr._dns-sd._udp.lan.
+www.orc.ru.
+mail.arquetipopublicidad.net.
+78.123.180.189.in-addr.arpa.
+coca.com.
+53.194.33.187.in-addr.arpa.
+a2.sphotos.ak.fbcdn.net.
+69.184.188.190.in-addr.arpa.
+cbdengineering.com.
+203.34.52.71.in-addr.arpa.
+a8.sphotos.ak.fbcdn.net.
+vnxsolutions.com.
+dipproject.ru.
+120.223.173.190.in-addr.arpa.
+google.com.
+pretty-ditty.blogspot.com.
+49.247.156.189.in-addr.arpa.
+images01.olx.com.co.
+static.ak.fbcdn.net.
+media.fastclick.net.
+www.google.com.
+a1.sphotos.ak.fbcdn.net.
+definicion.de.
+filtre.chuq.qc.ca.
+click.email.nlg.com.
+199.67.59.186.in-addr.arpa.
+kemont.ru.
+mts-k.ru.
+db._dns-sd._udp.lan.
+.
+51.150.95.201.in-addr.arpa.
+a-0.19-a30f7000.c070081.1518.19d4.3ea1.410.0.tzin1lvkubqbfgzgrbj44qlek5.avqs.mcafee.com.
+videos.videopress.com.
+www.psrd.hawaii.edu.
+www.bancofrances.com.ar.
+alb3d.maktoobblog.com.
+profile.ak.fbcdn.net.
+tags.expo9.exponential.com.
+www.techopinions.com.
+sp.cwfservice.net.
+a.c-0.19-a309a081.c870082.1518.19d4.3ea1.210.0.gprbcpw39smc9azb9c4cbskdkq.avqs.mcafee.com.
+macabre.ru.
+a.root-servers.net.
+creative.ak.fbcdn.net.
+api.conduit.com.
+cbswzgc.files.wordpress.com.
+s-static.ak.facebook.com.
+games.m7shsh.com.
+trackermo.com.
+www.mozilla.org.
+mail.ekoteks.ru.
+microsoft-word-2011.softonic.pl.
+google.com.
+api.facebook.com.
+213.48.146.187.in-addr.arpa.
+a.root-servers.net.
+a1725.l.akamai.net.
+efacebook.in.
+apps.facebook.com.
+www.circuloastronomico.cl.
+cache.pack.google.com.
+www.facebook.com.
+developers.facebook.com.
+www.belkin.com.
+securepubads.g.doubleclick.net.
+safebrowsing-cache.google.com.
+s10.histats.com.
+dsw.quik.com.
+99.50.173.190.in-addr.arpa.
+lh5lrh2ks.g78z5q4a.
+4.113.205.189.in-addr.arpa.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+bl163w.blu163.mail.live.com.
+m2.nsimg.net.
+a3.sphotos.ak.fbcdn.net.
+cdn.api.twitter.com.
+photos-h.ak.fbcdn.net.
+habeby.com.
+quidestveritas07.blogspot.com.
+vacacionesbook.com.
+cuervo-negro.blogspot.com.
+glquery.blackberry.com.
+195.171.58.82.in-addr.arpa.
+mscrl.microsoft.com.
+static.ak.fbcdn.net.
+www.hotmetart.com.
+safebrowsing.clients.google.com.
+yellowsurveys.com.
+www.vinculame.com.
+tienda.youcel.com.
+bluepearl-skins.com.
+www.canadianmedsworld.org.
+twitter.com.
+www.godlygamez.com.
+www.kasperskylab.co.kr.
+bigbloger.lidovky.cz.
+dns.msftncsi.com.
+90.66.223.189.in-addr.arpa.
+www.proveedoresturisticos.com.mx.
+image01.videobox.com.
+253.30.30.186.in-addr.arpa.
+www.grabonebottle.co.nz.
+kriss.re.kr.
+27.231.237.189.in-addr.arpa.
+pegasustransfers.com.au.
+www.ptcbox.com.
+i1.ytimg.com.
+www.fotonostra.com.
+www.gordosnuncamas.blogspot.com.
+secure.wlxrs.com.
+lolieroidol.blog79.fc2.com.
+a3.sphotos.ak.fbcdn.net.
+a3.sphotos.ak.fbcdn.net.
+www.sexfg.com.
+solar-m.ru.
+ad.yieldmanager.com.
+mail.cti.com.
+a.root-servers.net.
+www.google.com.
+odcdance.org.
+partner.googleadservices.com.
+mail.evyap.com.tr.
+www.facebook.com.
+www.opendi.mx.
+msdxmlc.dll.
+clients1.google.com.
+download.windowsupdate.com.
+profile.ak.fbcdn.net.
+mail.google.com.
+wuostc.com.
+www.aspirateur-silencieux.fr.
+www.playingbythebook.net.
+apis.google.com.
+static.muslimadnetwork.com.
+static.ak.fbcdn.net.
+synexches.synerfac.com.
+es-la.facebook.com.
+twitter.com.
+www.youtube.com.
+www.plasticsportal.net.
+static.ak.connect.facebook.com.
+time.windows.com.
+www.ehbonline.org.
+85.51.1.181.in-addr.arpa.
+jimsmash.blogspot.com.
+i2.cdn.turner.com.
+www.elorientalonline.com.
+www.televox.com.
+plus.google.com.
+131.203.177.187.in-addr.arpa.
+61.25.31.95.in-addr.arpa.
+242.129.33.187.in-addr.arpa.
+d1aivi5dp2wry5.cloudfront.net.
+storage.conduit.com.
+salud.latam.msn.com.
+switchboard.real.com.
+creative.ak.fbcdn.net.
+photos-e.ak.fbcdn.net.
+coolberman.wordpress.com.
+e3353.c.akamaiedge.net.
+securesignupoffers.net.
+www.pigtronix.com.
+blackozil.blogspot.com.
+.
+60.36.153.190.in-addr.arpa.
+emediate.apmmedia.net.
+cm5.esignal.com.
+smsshkola.ru.
+a2.sphotos.ak.fbcdn.net.
+osrah.net.
+clients1.google.com.
+www.diamondcs.com.au.
+intervale.com.
+townandcountryproperties.com.
+simoncaleb.com.
+63.74.237.189.in-addr.arpa.
+babinbuildingsolutions.com.
+50-57-46-243.static.cloud-ips.com.
+developers.facebook.com.
+en-us.fxfeeds.mozilla.com.
+www.edovia.com.
+www.dailymotion.com.
+242.129.244.201.in-addr.arpa.
+208.97.84.200.in-addr.arpa.
+europe.com.
+a.root-servers.net.
+www.facebook.com.
+ddb.fr.s7b2.psmtp.com.
+planeta.gul.es.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+providian.com.
+211.123.225.78.in-addr.arpa.
+ma10104.computerhaus.net.
+pixel.facebook.com.
+couponbuddy.s3.amazonaws.com.
+abswa.com.
+bit.ly.
+photos-b.ak.fbcdn.net.
+creative.ak.fbcdn.net.
+a.root-servers.net.
+ec.atdmt.com.
+th4.theteenest.com.
+newmachine.com.
+125.100.233.76.in-addr.arpa.
+www.medicentro.com.co.
+images.intellitxt.com.
+www.odioentrenar.com.
+static.ak.fbcdn.net.
+:7gnvfxuw.k20q6a5l.
+hindi.babylon.com.
+www.modern-styles.net.
+www.okc.cc.ok.us.
+baxterlaw.com.
+parrotsociety.org.au.
+www.youtube-nocookie.com.
+www.google-analytics.com.
+gemini.com.
+171.146.55.87.in-addr.arpa.
+time.windows.com.
+comfitel.ru.
+m.facebook.com.
+corbettresearch.com.
+accounts.google.com.
+www.square-enix.co.jp.
+a1408.w43.akamai.net.
+www.gerardo-perez.com.ar.
+static.exoclick.com.
+94.130.242.212.in-addr.arpa.
+insidetrackcoaching.com.s5a1.psmtp.com.
+wolfblock.com.mx1.electric.net.
+www.lingopal.com.
+plus.google.com.
+www.facebook.com.
+accounts.google.com.
+mail2.demo-hmc.com.ar.
+188.92.220.189.in-addr.arpa.
+gayastrology.blogspot.com.
+175.236.127.201.in-addr.arpa.
+imgburn.softonic.cn.
+www.123jump.co.uk.
+www.gmg-entertainment.com.
+spajardin.com.
+www.editorialtaurus.com.
+echo.edge.messenger.live.com.
+api.geo.kontagent.net.
+sp.search-results.com.
+a5.sphotos.ak.fbcdn.net.
+live.gnome.org.
+s0.2mdn.net.
+static.ak.fbcdn.net.
+ax.init.itunes.apple.com.
+www.juntaflorida.gub.uy.
+static.ak.fbcdn.net.
+arch.inkom.ru.
+88.76.160.189.in-addr.arpa.
+www.tripadvisor.es.
+_ldap._tcp.
+sp.cwfservice.net.
+16.204.61.67.in-addr.arpa.
+a3.sphotos.ak.fbcdn.net.
+33.22.137.201.in-addr.arpa.
+228.113.166.178.in-addr.arpa.
+loading1.widdit.com.
+press.absolut.com.
+www.campus3deducacion.com.
+matroska-pack-full.softonic.com.
+www.bairesgirls.net.
+download337.avast.com.
+inotify.live.net.
+a2.twimg.com.
+a.root-servers.net.
+login.toolbar.conduit-services.com.
+116.28.178.186.in-addr.arpa.
+pagead2.googlesyndication.com.
+b-0.19-a3001008.41081.1518.19d4.3ea1.410.0.2rpliwfdaimtdteu1ia7bwlbsq.avqs.mcafee.com.
+www.honeymoonersreviewguide.com.
+googleads.g.doubleclick.net.
+www.piter-press.ru.
+ssl.gstatic.com.
+ajax.googleapis.com.
+js.blinkadr.com.
+clipat.maktoob.com.
+help.freephpbb3.com.
+darveylitho.com.
+mail.pcexchange.net.
+capgemini.ru.
+www.penesgays.com.ar.
+www.kaossoftwear.com.
+a.root-servers.net.
+www.travian.gr.
+profile.ak.fbcdn.net.
+b-0.19-23058479.10081.1518.19d4.2f4a.210.0.lwchdlgbpnlvjj7ass77a8nrvt.avqs.mcafee.com.
+photos-c.ak.fbcdn.net.
+www.nuvet.com.
+apmkzodsq.p63l7j9c.
+pixel.facebook.com.
+ad.yieldmanager.com.
+a.root-servers.net.
+www.vitralesexclusivos.com.ar.
+www.gstatic.com.
+184.21.238.83.in-addr.arpa.
+a7.sphotos.ak.fbcdn.net.
+photos-g.ak.fbcdn.net.
+ad.doubleclick.net.
+client.akamai.com.
+i2.ytimg.com.
+de.hyperionics.com.
+dns.msftncsi.com.
+external.ak.fbcdn.net.
+a3.sphotos.ak.fbcdn.net.
+a7.sphotos.ak.fbcdn.net.
+www.myhabit.com.
+squote.yuanta.com.tw.
+130.120.166.190.in-addr.arpa.
+digitalcuttlefish.blogspot.com.
+b._dns-sd._udp.0.1.168.192.in-addr.arpa.
+prosportshop.ru.
+8okjz1wzv.v71w6n6r.
+sochs.com.
+profile.ak.fbcdn.net.
+31.145.170.189.in-addr.arpa.
+warez-bb.org.
+b-0.19-2200a008.11081.1518.19d3.3ea1.410.0.v1a2qe64ph7fk7393unb8z6wlb.avqs.mcafee.com.
+www.firefox.ro.
+3dedp2zth.u63z8z0p.
+sla.com.s9b1.psmtp.com.
+teredo.ipv6.microsoft.com.
+ad.jumbaexchange.com.
+showadsak.pubmatic.com.
+www.facebook.com.
+ajax.googleapis.com.
+img534.imageshack.us.
+rsconsultants.co.uk.
+clients4.google.com.
+s.youtube.com.
+112.169.123.190.in-addr.arpa.
+4121518.frasesinolvidables1.com.ar.
+imagesak.wildwestdomains.com.
+www.bloopdigital.com.
+api-read.facebook.com.
+www.google.com.
+.
+www.yahoo.com.
+birdingpal.org.
+150.25.102.201.in-addr.arpa.
+s.youtube.com.
+tcpv2.easythumbhost.com.
+dns.msftncsi.com.
+clients1.google.com.
+120.86.130.189.in-addr.arpa.
+it-it.facebook.com.
+blog.stata.com.
+calendar.live.com.
+news.google.com.mx.
+reimanpub.com.s9a1.psmtp.com.
+checkip.dyndns.com.
+a6.sphotos.ak.fbcdn.net.
+a.root-servers.net.
+connect.facebook.net.
+ssl.gstatic.com.
+86.19.176.190.in-addr.arpa.
+a.root-servers.net.
+qcc.com.sa.
+www.agava.ru.
+profile.ak.fbcdn.net.
+cdn.loading321.com.
+api.facebook.com.
+webcache.googleusercontent.com.
+170.93.249.201.in-addr.arpa.
+shocktune.com.
+79.192.57.186.in-addr.arpa.
+api.openfeint.com.
+238.66.36.176.in-addr.arpa.
+cookisgood.blogspot.com.
+www.google.com.
+content-1.emagistercdn.com.
+mihran.com.
+afproteinpharmaceuticals.com.
+37.7.130.27.in-addr.arpa.
+stun.client.akadns.net.
+uwrrwmxeexlrmwo.net.
+ardry.com.
+www.watchesseek.com.
+m5.eastlink.ca.
+176.162.126.84.in-addr.arpa.
+70.5.75.50.in-addr.arpa.
+www.el-ladies.com.
+checkip.dyndns.org.
+177.71.173.70.in-addr.arpa.
+t0.gstatic.com.
+msgr.updates.yahoo.com.
+edit.yahoo.com.
+telus.net.
+a7.sphotos.ak.fbcdn.net.
+221.6.62.186.in-addr.arpa.
+densho.com.mx.
+teredo.ipv6.microsoft.com.
+jers3.info.
+a.root-servers.net.
+187.207.145.187.in-addr.arpa.
+mail.iqpuzzles.com.
+webofdebt.wordpress.com.
+evt.collarity.com.
+smtp.sherbtel.net.
+homepages.luc.edu.
+www.digimonmasters.org.
+mail.chmelik.com.
+yaminoyukihime.blogspot.com.
+simple.wikipedia.org.
+beardedmagazine.co.uk.
+depositfiles.com.
+a.root-servers.net.
+dnl-16.geo.kaspersky.com.
+futsal1930.blogspot.com.
+dzoom.org.es.
+massivepress.com.
+wawick.net.
+crl.microsoft.com.
+129.72.131.187.in-addr.arpa.
+plusone.google.com.
+static.ak.fbcdn.net.
+lb._dns-sd._udp.0.2.168.192.in-addr.arpa.
+r._dns-sd._udp.home.
+www.weather.gov.
+www.sptechs.com.
+_kerberos._tcp.dc._msdcs.la.jnj.com.
+i3.sinaimg.cn.
+4.148.175.190.in-addr.arpa.
+pics1.pof.com.
+profile.ak.fbcdn.net.
+231.49.235.190.in-addr.arpa.
+cdn2.widdit.com.
+d1ros97qkrwjf5.cloudfront.net.
+a1505.l.akamai.net.
+slfusco.com.inbound30.mxlogic.net.
+dns.msftncsi.com.
+www.adobe.com.
+mail.autopick.com.
+a2.sphotos.ak.fbcdn.net.
+clients1.google.com.
+support.google.com.
+www.melsdrive-in.com.
+ds.addthis.com.
+ssl.gstatic.com.
+www.textsrv.com.
+mthigh.com.
+i4.ytimg.com.
+safebrowsing.clients.google.com.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+7db1t4r::.21ac.
+blankizdat.ru.
+ipod4ladies.wordpress.com.
+ssl.gstatic.com.
+a.root-servers.net.
+iejaor.com.
+www.quehoroscopo.com.
+www.google.com.mx.
+profile.ak.fbcdn.net.
+www.pensacolaciviccenter.com.
+api.facebook.com.
+radley.me.uk.
+cerca.unita.it.
+aaaga.com.
+support.google.com.
+a7.sphotos.ak.fbcdn.net.
+utstarcom.ru.
+a.root-servers.net.
+www.addthis.com.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+_272_37_4.
+a.root-servers.net.
+23.99.51.190.in-addr.arpa.
+ksn3-12.part1.kaspersky-labs.com.
+o-o.preferred.atl14s01.v23.lscache8.c.youtube.com.
+i1.ytimg.com.
+classicrr.com.s8b1.psmtp.com.
+thumbs1.wetgrannysex.com.
+11.39.18.190.in-addr.arpa.
+203.113.214.189.in-addr.arpa.
+a.root-servers.net.
+a8.sphotos.ak.fbcdn.net.
+212.51.168.192.in-addr.arpa.
+platform.twitter.com.
+i0.ifrype.com.
+www.ramirezcuevas.es.
+tracker.stigalaria.org.
+www.facebook.com.
+profile.ak.fbcdn.net.
+www.zionrootswear.com.
+yhioo.com.
+otfs.net.
+pt-br.facebook.com.
+photos-b.ak.fbcdn.net.
+31-courier.push.apple.com.
+a7.sphotos.ak.fbcdn.net.
+zaitcev.mee.nu.
+77.233.52.216.in-addr.arpa.
+www.iwsmile.it.
+js.wlxrs.com.
+plus.google.com.
+puertyxdvud.info.
+50.51.173.201.in-addr.arpa.
+a.root-servers.net.
+struer.dk.
+ancalayoli.blogspot.com.
+219.131.34.186.in-addr.arpa.
+ncree.org.
+profile.ak.fbcdn.net.
+1.2.168.192.in-addr.arpa.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+a.root-servers.net.
+a1174.g.akamai.net.
+153.137.231.189.in-addr.arpa.
+mail.
+132.243.230.201.in-addr.arpa.
+www.registrar.psu.edu.
+rydata-a.akamaihd.net.
+news.mtgir.com.
+www.google.com.
+e5016.b.akamaiedge.net.
+i3.ytimg.com.
+images.hi5.com.
+u21.eset.com.
+104.126.92.201.in-addr.arpa.
+yui.yahooapis.com.
+grupozawa.com.
+165.85.192.190.in-addr.arpa.
+partner.googleadservices.com.
+www.download.windowsupdate.com.
+miangelitoespecial.blogspot.com.
+support.google.com.
+61.18.110.123.in-addr.arpa.
+e4344.g.akamaiedge.net.
+a.root-servers.net.
+www.google-analytics.com.
+28.175.186.189.in-addr.arpa.
+photos-c.ak.fbcdn.net.
+136.133.55.189.in-addr.arpa.
+em1x-278.lhr.messaging.nokia.com.
+www.facebook.com.
+pixel.facebook.com.
+adlog.com.com.
+191.83.26.201.in-addr.arpa.
+s2.youtube.com.
+pxahzae6r.15sr.
+126.235.82.186.in-addr.arpa.
+a.root-servers.net.
+static.ak.fbcdn.net.
+www.poni.ca.
+secure.cbtnuggets.com.
+183.106.236.186.in-addr.arpa.
+www.gstatic.com.
+29.161.115.186.in-addr.arpa.
+external.ak.fbcdn.net.
+www.thereis.co.uk.
+tap2-cdn.rubiconproject.com.
+mail.yimg.com.
+www.google-analytics.com.
+www.youtube.com.
+42.153.143.201.in-addr.arpa.
+myweb.vodafone.co.uk.
+a.root-servers.net.
+photos-d.ak.fbcdn.net.
+ratings-wrs.symantec.com.
+loading7.widdit.com.
+www.nmm.ac.uk.
+a.root-servers.net.
+ad.doubleclick.net.
+pagead2.googlesyndication.com.
+z-ecx.images-amazon.com.
+www.juegos-autos.com.
+156.125.142.189.in-addr.arpa.
+www.google-analytics.com.
+b._dns-sd._udp.0.1.168.192.in-addr.arpa.
+platform.twitter.com.
+a.tribalfusion.com.
+_334_96_3.
+ads.iforex.com.
+43.99.156.187.in-addr.arpa.
+78.157.200.98.in-addr.arpa.
+21.143.194.187.in-addr.arpa.
+www.google-analytics.com.
+www.juegosgratis1x.com.
+b._dns-sd._udp.0.1.168.192.in-addr.arpa.
+80.188.221.67.in-addr.arpa.
+appleglobal.112.2o7.net.
+e.f.f.f.f.f.f.f.1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.2.0.f.f.ip6.arpa.
+carbofer.ru.
+a7.sphotos.ak.fbcdn.net.
+translate.google.com.mx.
+mail.rabotagrad.ru.
+toolbarqueries.clients.google.com.
+7.97.24.203.in-addr.arpa.
+187.163.145.189.in-addr.arpa.
+www.nytimes.com.
+89.55.36.174.in-addr.arpa.
+unicam-studio.ru.
+fbcdn-photos-a.akamaihd.net.
+www.missindonesia.co.id.
+10.237.39.190.in-addr.arpa.
+cnfg.funmoods.com.
+apis.google.com.
+unesco.com.
+sb8z44iyo.k70w5x1y.
+230.240.133.189.in-addr.arpa.
+chat.facebook.com.
+domnapogrebah.ru.
+a.root-servers.net.
+158.60.207.200.in-addr.arpa.
+.
+www.kentelectricalservices.com.
+android.clients.google.com.
+ar.answers.yahoo.com.
+www.gstatic.com.
+mouse.latercera.cl.
+www.mundohogar.com.
+babystrology.com.
+developers.facebook.com.
+7794ietim.x15n4z7x.
+r._dns-sd._udp.0.2.168.192.in-addr.arpa.
+leetufrase.com.
+cdn1.widdit.com.
+cf.addthis.com.
+thumbs1.ebaystatic.com.
+62.28.94.189.in-addr.arpa.
+brambles.com.s5b2.psmtp.com.
+www.mezee.me.
+www.angelfire.com.
+js.adsonar.com.
+blogtuembarazo.com.
+mail.karavelle.co.uk.
+external.ak.fbcdn.net.
+b-0.19-230c3479.81.1518.19d4.3ea1.410.0.1mpgha3eadg4cnkstpgnth3v86.avqs.mcafee.com.
+wwwimages.adobe.com.
+10.216.22.186.in-addr.arpa.
+dsa411.com.
+apps.facebook.com.
+221.221.15.76.in-addr.arpa.
+swa.mail.ru.
+partners.gallery.live.com.
+zebarthadvisors.com.
+r1rk9np7bpcsfoeekl0khkd2juj27q3o-a-fc-opensocial.googleusercontent.com.
+tavernrestaurantgroup.com.
+sp.ask.com.
+ogier.com.
+search-cdn.walmart.com.
+att.com.
+boxmail.spb.ru.
+photographytreasure.com.
+www.hawanaajd.com.
+static.ak.fbcdn.net.
+facebook.com.
+sp.cwfservice.net.
+a.root-servers.net.
+www.voiceboks.com.
+apis.google.com.
+a.root-servers.net.
+:os11aman.z59u0d0w.
+v14.nonxt6.c.youtube.com.
+www.googleadservices.com.
+pixel.33across.com.
+www.vivirguadalajara.com.
+www.quantenwelt.de.
+bay.messenger.services.live.com.
+delirios-anonimos.blogspot.com.
+www.paintbits.com.
+228.95.119.99.in-addr.arpa.
+25.media.tumblr.com.
+mvs.com.mx.
+www.smutblaster.com.
+a.root-servers.net.
+www.moneytalkvillage.com.
+2.gvt0.com.
+c0058712.cdn.cloudfiles.rackspacecloud.com.
+187.112.173.88.in-addr.arpa.
+a.root-servers.net.
+96.224.241.201.in-addr.arpa.
+rcp.na.blackberry.com.
+a.root-servers.net.
+storage.conduit.com.
+107.68.148.88.in-addr.arpa.
+129.151.127.201.in-addr.arpa.
+mx2.balanced.homie.mail.dreamhost.com.
+qc1dlpkvw.43yc.
+plusone.google.com.
+24.233.73.200.in-addr.arpa.
+mcfarlandarchitects.com.
+grafos.softonic.com.
+60.199.137.70.in-addr.arpa.
+a.root-servers.net.
+223.173.175.187.in-addr.arpa.
+grubees.aliexpress.com.
+zh-cn.facebook.com.
+carlcox.com.
+a.root-servers.net.
+a4.sphotos.ak.fbcdn.net.
+mail.kolaregion.ru.
+seexycams3.da.ru.
+sb2573.ru.
+204.93.139.187.in-addr.arpa.
+www.bombasindustriales.cl.
+rs702l35.rapidshare.com.
+php.hdcmct.com.
+b-0.19-a7096008.8030081.1518.19ce.3ea1.410.0.rpsti6q8dj1qv7cger6ab8s5fq.avqs.mcafee.com.
+a.root-servers.net.
+179.wap517.org.
+150.213.209.189.in-addr.arpa.
+www.varelaenred.com.ar.
+docs.google.com.
+185.255.150.99.in-addr.arpa.
+photos-b.ak.fbcdn.net.
+www.manga-access.com.
+ensenadagotico.blogspot.com.
+farm3.static.flickr.com.
+mail.jgua.com.
+102.39.154.187.in-addr.arpa.
+dns.msftncsi.com.
+um12.eset.com.
+ad.yieldmanager.com.
+125.166.129.95.in-addr.arpa.
+del.icio.us.
+mx.f1123.mail.yahoo.com.
+197.21.1.181.in-addr.arpa.
+www.juegosdemates.com.
+techrepublic.custhelp.com.
+faculty.deanza.fhda.edu.
+fbnffb.s3.amazonaws.com.
+230.116.1.201.in-addr.arpa.
+a1831.g.akamai.net.
+apis.google.com.
+gsbflavorcreators.com.s8b1.psmtp.com.
+profile.ak.fbcdn.net.
+i3.ytimg.com.
+124.8.241.201.in-addr.arpa.
+171.79.216.186.in-addr.arpa.
+120.79.125.74.in-addr.arpa.
+www.vegetomania.com.
+www.chinabusinessworld.com.
+panatweb.com.
+76.93.106.186.in-addr.arpa.
+cdn.blogsmasterd.com.
+profile.ak.fbcdn.net.
+www.blogger.com.
+86.31.73.189.in-addr.arpa.
+75.9.19.186.in-addr.arpa.
+teredo.ipv6.microsoft.com.
+styleflat.ru.
+harsco.com.
+clients1.google.com.
+pro-team.com.s7a1.psmtp.com.
+urs.microsoft.com.
+rsi.hotmail.com.
+218.182.5.189.in-addr.arpa.
+sherman-associates.com.inbound15.mxlogicmx.net.
+jetstreamwireless.com.
+amfbakery.com.
+photos-g.ak.fbcdn.net.
+fbcdn-photos-a.akamaihd.net.
+42.153.122.69.in-addr.arpa.
+110.172.185.190.in-addr.arpa.
+creative.ak.fbcdn.net.
+pagead.l.doubleclick.net.
+saledrug.info.lan.
+guitartricks.us1.list-manage.com.
+photos-a.ak.fbcdn.net.
+kb.cyberoam.com.
+www.endotext.com.
+232.216.210.201.in-addr.arpa.
+15.149.220.66.in-addr.arpa.
+a.root-servers.net.
+b._dns-sd._udp.0.1.168.192.in-addr.arpa.
+a.root-servers.net.
+69.168.161.200.in-addr.arpa.
+pixel.quantserve.com.
+tracker.mightynova.com.
+www.weather.com.
+mxbackup.mail.sysonline.net.
+6965y6kzp.p06j1f5v.
+121.45.109.79.in-addr.arpa.
+jt2im267w.w33k1y7h.
+www.4ureyesonly.com.
+www.facebook.com.
+www.shoesofyourdreams.com.
+gday.ru.
+photos-c.ak.fbcdn.net.
+tv.msn.com.
+www.facebook.com.
+ja-jp.facebook.com.
+graph.facebook.com.
+argus-spectrum.ru.
+www.accountmarket.com.
+mkgallery.com.
+www.thewhiteribbon.co.uk.
+m.google.com.
+www.gmail.com.
+content.yieldmanager.edgesuite.net.
+a.root-servers.net.
+a.root-servers.net.
+.
+234.154.138.190.in-addr.arpa.
+photos-d.ak.fbcdn.net.
+googleads.g.doubleclick.net.
+8.17.189.99.in-addr.arpa.
+frontal1.erenis.fr.
+time.nist.gov.
+videotronres.112.2o7.net.
+lasa.com.
+justin.multimedios.tv.
+dns.msftncsi.com.
+www.blogrelaciones.com.
+rs11tl4.rapidshare.com.
+tag.admeld.com.
+tools.google.com.
+www.google.com.
+www.thecharityhive.ca.
+4.bp.blogspot.com.
+fas.fr.
+mobile.papi.com.
+jruby.org.
+osl.ugr.es.
+profile.ak.fbcdn.net.
+www.edenred.es.
+firstmomtube.com.
+gw.roma.ua.
+sites.google.com.
+www.cuidadospediatricos.blogspot.com.
+107.173.107.186.in-addr.arpa.
+gfx1.hotmail.com.
+www.paxnet.co.kr.
+nainashville-com.mail.eo.outlook.com.
+a4.sphotos.ak.fbcdn.net.
+www.facebook.com.
+ppo1l9gbl.48hc.
+68.187.214.189.in-addr.arpa.
+csi.gstatic.com.
+mail.lbsglobal.com.
+www.mediasyndicate.in.
+org.mx.
+alilahotels.com.
+apis.google.com.
+a.root-servers.net.
+julianred.lookbook.nu.
+sonics.ru.
+mail.google.com.
+photos-f.ak.fbcdn.net.
+gcg.com.
+evolutiongroupfl.com.
+profile.ak.fbcdn.net.
+vega-h.ru.
+rs210tl4.rapidshare.com.
+graph.facebook.com.
+www.techsutram.com.
+www.google.com.
+97.46.184.89.in-addr.arpa.
+rostovauto.ru.
+creatupropiamoda.com.
+my.mail.ru.
+api.zynga.com.
+www.wordreference.com.
+19.224.171.69.in-addr.arpa.
+api.conduit.com.
+hyatts.com.
+ferroesquevedos.blogspot.com.
+cs.picjoke.net.
+es.wikipedia.org.
+aaamiamicounty.com.
+2kgam.es.
+external.ak.fbcdn.net.
+0-jg-w.channel.facebook.com.
+74.30.249.190.in-addr.arpa.
+tvfacebook.lge.com.
+h.live.com.
+s2.youtube.com.
+_885_08_4.
+primestaffusa.com.
+profile.ak.fbcdn.net.
+kusanagigirlbeautyblog.blogspot.com.
+d3j5vwomefv46c.cloudfront.net.
+www.skypesexcontacts.com.
+fc.cps.edu.
+citigateaf.com.
+www.pixgateway.com.
+dcscontracting.com.bak-mx.na0100.smtpbak.com.
+multiplayergamescom.skimlinks.com.
+external.ak.fbcdn.net.
+cumeaters.33men.com.
+pixel.facebook.com.
+todoesfarandula.bligoo.com.
+ssl.gstatic.com.
+49.38.133.115.in-addr.arpa.
+multimedia.getresponse.com.
+www.vuelo-digital.org.
+www-cctld.l.google.com.
+vcontent.ebuddy.com.
+mail.cbopc.com.
+unoracing.com.
+98.images22.51img1.com.
+derribosbajoelagua.blogspot.com.
+www.annabean.com.
+2.213.10.109.in-addr.arpa.
+thumbnails2.imagebam.com.
+www.osundefender.org.
+223.178.230.88.in-addr.arpa.
+hwzgjh4my.l08z4w0e.
+ocsp.digicert.com.
+mail.hiellesmereport.com.
+www.bing.com.
+www.siteadvisor.com.
+27.135.15.186.in-addr.arpa.
+notebooklaptopsreview.blogspot.com.
+75.157.127.201.in-addr.arpa.
+164.126.3.187.in-addr.arpa.
+blackhole.theglobe.com.
+ads.crakmedia.com.
+spysee.jp.
+www.gala-marketlaw.com.
+123.187.194.94.in-addr.arpa.
+85.225.69.77.in-addr.arpa.
+a.root-servers.net.
+wallet.google.com.
+mbakercorp.com.
+www.highdefedition.com.
+www.googletagservices.com.
+arthritis.uphero.com.
+www.detododormitorios.com.
+mailext1.mh-hannover.de.
+mail.wba-architects.com.
+cnt1.xhamster.com.
+www.nowhereelse.fr.
+tc.v11.cache5.c.youtube.com.
+dns.msftncsi.com.
+mail.atbm.ru.
+thevintagevalley.blogspot.com.
+105.196.188.189.in-addr.arpa.
+140.232.171.69.sbl-xbl.spamhaus.org.
+bp3.blogger.com.
+www.twitter.com.
+eh35zk:zq.00tn.
+0-68.channel.facebook.com.
+usebrinks.com.
+sqm.microsoft.com.
+player.vimeo.com.
+w.sharethis.com.
+profile.ak.fbcdn.net.
+legendarioantartico.blogspot.com.
+a4.sphotos.ak.fbcdn.net.
+freeangrybirdsgames.info.
+168.218.243.189.in-addr.arpa.
+external.ak.fbcdn.net.
+static.ak.fbcdn.net.
+resolver1.pand.ctmail.com.
+external.ak.fbcdn.net.
+99.152.182.189.in-addr.arpa.
+ratco.ru.
+www.google.com.
+ads.adxpose.com.
+adventurgraphics.blogspot.com.
+www.expressio.fr.
+linkhelp.clients.google.com.
+www.bigbreastchest.com.
+cdn.gigya.com.
+www.a-n.co.uk.
+a5.sphotos.ak.fbcdn.net.
+photos-d.ak.fbcdn.net.
+i.blogads.com.
+www.4shared.com.
+thewillows.org.
+netmail.verizon.com.
+252.150.38.190.in-addr.arpa.
+www.facebook.com.
+224.30.125.95.in-addr.arpa.
+11.41.241.201.in-addr.arpa.
+smtp.bedsonline.com.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+reactnetwork.com.
+www.brspecialtuning.co.uk.
+a.root-servers.net.
+spancp.com.
+tags.expo9.exponential.com.
+www.linkstoislam.com.
+37.160.144.187.in-addr.arpa.
+145.54.26.80.in-addr.arpa.
+a1404.w41.akamai.net.
+www.facebook.com.
+11.34.11.190.in-addr.arpa.
+a1.twimg.com.
+8.251.125.79.in-addr.arpa.
+feeds.bbci.co.uk.
+177.44.194.187.in-addr.arpa.
+www.gas2.org.
+voipa.sip.yahoo.com.
+www.aclam.org.
+www.slowandsteadywinstherace.com.
+a550.g.akamai.net.
+external.ak.fbcdn.net.
+crl3.digicert.com.
+rerecognition.com.
+gupran.ru.
+external.ak.fbcdn.net.
+104.152.161.190.in-addr.arpa.
+238.49.253.201.in-addr.arpa.
+a2.sphotos.ak.fbcdn.net.
+_953_66_8.
+t2.gstatic.com.
+72.251.56.178.in-addr.arpa.
+mapas.guiadeuruguay.com.
+cityofmadera.ca.us.
+blogs.ancestry.com.
+149.118.143.189.in-addr.arpa.
+82.114.125.84.in-addr.arpa.
+assets.tumblr.com.
+www.yahoo.com.
+developers.facebook.com.
+wnsemergent.com.
+scribd.com.
+youtu.be.
+heymrswilson.net.
+gms.gdl.jp.
+vgs.com.
+www.freespiritualways.com.
+fbcdn-photos-a.akamaihd.net.
+photos-a.ak.fbcdn.net.
+22.191.22.186.in-addr.arpa.
+master7.teamviewer.com.
+download.windowsupdate.com.
+submitshop.com.
+photos-b.ak.fbcdn.net.
+pilu.it.
+coursyoga.net.
+lamington.wordpress.com.
+wheresmysammich.com.
+ajax.googleapis.com.
+photos-d.ak.fbcdn.net.
+apps.facebook.com.
+208.86.206.190.in-addr.arpa.
+161.172.118.70.in-addr.arpa.
+www.therespawnarmy.com.
+38.132.129.186.in-addr.arpa.
+www.hotchickswithdouchebags.com.
+dr._dns-sd._udp.lan.
+l.yimg.com.
+epistemologadelacomunicacion.blogspot.com.
+www.solotodo.net.
+w73k1ha18.55wt.
+im1.gulfup.com.
+d6537b.ess.barracudanetworks.com.
+news.google.com.mx.
+j5ituddlr.u55e5e3r.
+profile.ak.fbcdn.net.
+www.travian.ma.
+creative.ak.fbcdn.net.
+ib.adnxs.com.
+twitter.com.
+_300_37_2.
+124.214.169.88.in-addr.arpa.
+ssl.gstatic.com.
+twitter.com.
+www.turismolitoral.cl.
+250.186.124.186.in-addr.arpa.
+www.zonaktolica.com.ar.
+juris.su.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+platform.twitter.com.
+router.infolinks.com.
+apostoladoeucaristico.blogspot.com.
+xnx.ru.
+www.desotosport.com.
+2.198.109.187.in-addr.arpa.
+olympiarealestate.com.
+215.251.223.87.in-addr.arpa.
+img141.imageshack.us.
+blog.houstontexans.com.
+pbr670.photobucket.com.
+www.dailymail.co.uk.
+t0.gstatic.com.
+dtvyuk.com.
+f.chtah.com.
+chuletas.rincondelvago.com.
+direct2.anhso.net.
+billing.sharo4ka.ru.
+fbcdn-photos-a.akamaihd.net.
+22.101.172.190.in-addr.arpa.
+a.root-servers.net.
+th.y8.com.
+a3.sphotos.ak.fbcdn.net.
+bloog.pl.
+www.youtube.com.
+mi.adinterax.com.
+go2.com.
+40.162.126.84.in-addr.arpa.
+a6.sphotos.ak.fbcdn.net.
+a995.mm1.akamai.net.
+ocsp.godaddy.com.
+pubads.g.doubleclick.net.
+ee.net.s6a2.psmtp.com.
+30.43.58.201.in-addr.arpa.
+161.9.150.187.in-addr.arpa.
+mtalk.google.com.
+89.55.36.174.in-addr.arpa.
+comic.dl.playstation.net.
+a.root-servers.net.
+160.17.161.189.in-addr.arpa.
+www.loudguitars.com.
+dr._dns-sd._udp.lan.
+es-la.facebook.com.
+www.update.microsoft.com.
+photos-f.ak.fbcdn.net.
+platform.ak.fbcdn.net.
+151.96.186.67.in-addr.arpa.
+b._dns-sd._udp.0.1.168.192.in-addr.arpa.
+www.facebook.com.
+www.dcsea.uqroo.mx.
+www.helloprojectheaven.com.
+buyperfecthealth.com.
+www.cartolinespeedy.it.
+239.234.218.190.in-addr.arpa.
+www-cctld.l.google.com.
+118.161.208.201.in-addr.arpa.
+verizon.net.
+101.7fm.ru.
+114.172.34.201.in-addr.arpa.
+mypads.net.
+208.218.168.192.in-addr.arpa.
+www.fringenyc.org.
+www.youtube.com.
+www.scotiabank.com.mx.
+124.54.236.82.in-addr.arpa.
+ws-cloud-msgplus.linkury.com.
+www.levi.com.ec.
+91.123.13.201.in-addr.arpa.
+ysrgw8pk3.73bb.
+241.119.38.81.in-addr.arpa.
+pagead.l.doubleclick.net.
+sfg2.golden-tech.com.
+www.gpedit.msc.
+cdna.static.youjizz.com.
+atlplastic.com.
+www.dirtyxxxtube.com.
+a.root-servers.net.
+pap4zjal8.s92c9q0l.
+ecatepecdemorelos.olx.com.mx.
+130.50.201.71.in-addr.arpa.
+static.ak.facebook.com.
+202.235.112.186.in-addr.arpa.
+fxfeeds.mozilla.com.
+s.ytimg.com.
+fxfeeds.mozilla.com.
+wireless.stanford.edu.
+28.talkgadget.google.com.
+ic.tynt.com.
+col.stb01.s-msn.com.
+adframes.iminent.com.
+univi.ac.at.
+photos-a.ak.fbcdn.net.
+245.169.111.189.in-addr.arpa.
+istrianet.org.
+content.yieldmanager.edgesuite.net.
+api.twitter.com.
+www.elizabethhoyt.com.
+capitalmodern.com.
+ksn1-11-part2.kaspersky-labs.com.
+banorte.com.
+b.scorecardresearch.com.
+www.belkin.com.
+espanol.weather.com.
+a.root-servers.net.
+toolbarqueries.google.com.
+120.14.94.118.in-addr.arpa.
+mtucizone.ru.
+26.37.107.186.in-addr.arpa.
+ajax.googleapis.com.
+105.253.148.79.in-addr.arpa.
+a2.sphotos.ak.fbcdn.net.
+a8.sphotos.ak.fbcdn.net.
+dns.msftncsi.com.
+inbound.mercedesofindy.com.netsolmail.net.
+toolbar.live.com.
+mozilla.mirrors.pair.com.
+josephquevedony.com.
+173.235.149.186.in-addr.arpa.
+static.ak.fbcdn.net.
+r.turn.com.
+th190.photobucket.com.
+hxidyo.com.
+developers.facebook.com.
+angelakisconstruction.com.
+sp.cwfservice.net.
+mothersbistro.com.
+69.215.225.190.in-addr.arpa.
+184.154.153.200.in-addr.arpa.
+www.christiangr.com.
+i4.ytimg.com.
+41.180.211.189.in-addr.arpa.
+photos-h.ak.fbcdn.net.
+photos-e.ak.fbcdn.net.
+a1.sphotos.ak.fbcdn.net.
+72.30.112.186.in-addr.arpa.
+desmond.yfrog.com.
+121.176.26.190.in-addr.arpa.
+www.sve.uan.edu.mx.
+www.listenarabic.com.
+255.199.105.186.in-addr.arpa.
+external.ak.fbcdn.net.
+www.puritanas.com.
+imgcdn.nrelate.com.
+epriorityplus.com.
+profile.ak.fbcdn.net.
+angusstone.com.
+34.6.30.189.in-addr.arpa.
+freedomhouse.org.
+www.belkin.com.
+41.211.126.186.in-addr.arpa.
+mfa.logonix.net.
+engineering.slideshare.com.
+riairwanty.multiply.com.
+t3.gstatic.com.
+s2.youtube.com.
+szjd4uwey.y13i3i6s.
+www.google.com.
+www8.0zz0.com.
+www.fazendavisconde.com.br.
+231.254.114.186.in-addr.arpa.
+l.longtailvideo.com.
+www.bravotubecams.com.
+s.youtube.com.
+101.106.231.201.in-addr.arpa.
+a.root-servers.net.
+www.twitter.com.
+hi-in.facebook.com.
+www.hondacuajimalpa.com.
+rm-steel.com.
+mail.flashki-optom.ru.
+www.brista.ca.
+6me4qds1r.a63m3l0v.
+ndt-market.ru.
+12.237.1.190.in-addr.arpa.
+digaz.ru.
+253.5.178.189.in-addr.arpa.
+mobile2.wsj.com.
+i3.ytimg.com.
+zh-cn.facebook.com.
+winners.org.
+www.wtp101.com.
+img2.amateur-tube.us.
+pedrocolmenero.wordpress.com.
+photos-h.ak.fbcdn.net.
+159.242.52.216.dnsbl.sorbs.net.
+google.com.
+safebrowsing.clients.google.com.
+teredo.ipv6.microsoft.com.
+youtu.be.
+a7.sphotos.ak.fbcdn.net.
+videos.webs.com.
+20.147.188.206.in-addr.arpa.
+a.root-servers.net.
+connect.facebook.net.
+jigsaw.w3.org.
+download319.avast.com.
+a2.sphotos.ak.fbcdn.net.
+netzero.net.
+gpsex.ru.
+files.realmusic.ru.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+235.255.57.69.in-addr.arpa.
+bridesdiary.com.au.
+buy.gissn.com.
+www.thailand4x4.com.
+162.144.227.66.in-addr.arpa.
+55.51.53.68.in-addr.arpa.
+soundersfc.com.inbound15.mxlogic.net.
+g.ceipmsn.com.
+www.facebook.com.
+google.com.
+moshr.com.
+gfx3.hotmail.com.
+soccerfame.com.
+a1.sphotos.ak.fbcdn.net.
+a7.sphotos.ak.fbcdn.net.
+mgtracker.org.
+a.root-servers.net.
+rinaco.com.
+creative.ak.fbcdn.net.
+content.yieldmanager.edgesuite.net.
+a.root-servers.net.
+a.root-servers.net.
+iknowmedia.com.
+us.mc1214.mail.yahoo.com.
+www.autosusadosenmexico.com.mx.
+pixelpnt.com.
+ad.yieldmanager.com.
+www.fisiovictoria.com.
+www.facebook.com.
+platform.twitter.com.
+downsizemyspace.com.
+a5.sphotos.ak.fbcdn.net.
+www.nyxcosmetics.com.hk.
+freenet.de.
+docs.miktex.org.
+yaponiya.ru.
+b-0.19-210ac449.8031581.1518.19d4.3ea1.410.0.6nq2knidpg7w48lng5lcdu9w1t.avqs.mcafee.com.
+i2.ytimg.com.
+aikikai.ru.
+simardelectric.com.
+www.facebook.com.
+www.sonymusic.com.
+oteropictures.blogspot.com.
+profile.ak.fbcdn.net.
+photos-b.ak.fbcdn.net.
+_vlmcs._tcp.
+d2jsycj2ly2vqh.cloudfront.net.
+therapservices.net.
+answers.hackaday.com.
+www.pegandolealoseguro.com.
+www.getin2china.com.
+mx2.th.fujikura.com.
+ad.metanetwork.com.
+www.youtube.com.
+i2.ytimg.com.
+si0.twimg.com.
+52.4.123.129.in-addr.arpa.
+www.programasgratiz.com.
+mx.mvfintry.com.
+sp.cwfservice.net.
+www.facebook.com.
+natkeepalive.voice.yahoo.com.
+a.root-servers.net.
+photos-c.ak.fbcdn.net.
+www.billionairewoman.com.
+165.2.247.109.in-addr.arpa.
+www.google-analytics.com.
+czert.org.
+feeds.bbci.co.uk.
+answer-lab.com.s7b2.psmtp.com.
+a.root-servers.net.
+ipm.avira.com.
+ctsmx.com.
+www.youtube.com.
+www.spurl.net.
+sphinx.stic.co.kr.
+rpobrien.com.
+s.youtube.com.
+accounts.google.com.
+www.everything-about-concrete.com.
+junkcharts.typepad.com.
+www.conceptoradial.com.
+163.205.113.177.in-addr.arpa.
+193.216.16.190.in-addr.arpa.
+www.bancofrances.com.ar.
+dsjkoprtr7844.biz.
+files.fatakat.com.
+a.root-servers.net.
+toymania.com.
+s-static.ak.fbcdn.net.
+server3.lengiprorechtrans.ru.
+news.google.com.mx.
+www.
+facebook.conduit-services.com.
+fieldnotes.msnbc.msn.com.
+sites.google.com.
+es-la.facebook.com.
+baita.com.
+au.travel.yahoo.com.
+a.root-servers.net.
+tdc.co.tt.
+i1.ytimg.com.
+www.adult.toonsearch.net.
+www.gritosdelibertad.org.
+127.214.165.190.in-addr.arpa.
+id.google.es.
+business.twitter.com.
+dl-client365.dropbox.com.
+photos-a.ak.fbcdn.net.
+google.com.
+www.theautomedia.com.
+b._dns-sd._udp.lan.
+clcrolla.com.
+www.google.com.
+photos-a.ak.fbcdn.net.
+hbtele.com.
+hotmail.com.
+ssl.gstatic.com.
+planettirecableties.com.
+187.197.124.84.in-addr.arpa.
+be2.int.pochta.ru.
+a.root-servers.net.
+col.stb00.s-msn.com.
+usersystem783aa.ru.
+it.rinsemymusic.com.
+buttons.googlesyndication.com.
+78.217.144.187.in-addr.arpa.
+hi-in.facebook.com.
+8.28.57.187.in-addr.arpa.
+news.google.com.mx.
+92.136.8.200.in-addr.arpa.
+titanium30-en.url.trendmicro.com.
+14.228.247.131.in-addr.arpa.
+108.87.8.201.in-addr.arpa.
+www.ubergizmo.com.
+www.grupodmrh.vagas.com.br.
+pomerleauins.com.
+forex-trading-signal-fx.kolorowa-kraina.com.pl.
+vdnryd.com.
+i4.ytimg.com.
+42.251.88.184.in-addr.arpa.
+www.thezia.edu.mx.
+idmd.com.
+checkip.dyndns.org.
+pinoylovers.com.
+165.102.68.201.in-addr.arpa.
+mx99.elive.nl.
+www.statcounter.com.
+ads.towniecentral.com.
+mail.subwayak.com.
+c.prodigy.msn.com.
+g.s.openwalls.net.
+shapkitut.ru.
+www.bilkent.edu.tr.
+.
+195.212.153.186.in-addr.arpa.
+sta.ru.
+byerlyinc.com.
+photos-d.ak.fbcdn.net.
+www.epicbot.com.
+ad.yieldmanager.com.
+labs.ebay.com.
+parroquiasanjeronimo.files.wordpress.com.
+sites.google.com.
+d7.zedo.com.
+api.geo.kontagent.net.
+vi.y8.com.
+251.41.74.187.in-addr.arpa.
+api-read.facebook.com.
+database.clamav.net.
+180.106.50.201.in-addr.arpa.
+237.248.9.201.in-addr.arpa.
+creative.ak.fbcdn.net.
+a996.mm1.akamai.net.
+www.hollyan.com.
+scribe.twitter.com.
+109.110.153.189.in-addr.arpa.
+124.17.104.41.in-addr.arpa.
+honduras.paginasamarillas.com.
+content.ak.metrogames.com.
+verizon.net.
+ocsp.verisign.com.
+isabela.olx.com.ph.
+ramsayhealth.com.
+techtribe.com.
+api-read.facebook.com.
+3-cats.ru.
+a4.sphotos.ak.fbcdn.net.
+www.facebook.com.
+www.bricopinta.com.
+138.143.240.189.in-addr.arpa.
+numerologia.euroresidentes.es.
+creatividad.espacioblog.com.
+253.76.27.187.in-addr.arpa.
+www.zentai-zentai.com.
+inbound.netwirelessllc.com.netsolmail.net.
+google.com.
+171.237.88.74.in-addr.arpa.
+2ch.net.
+external.ak.fbcdn.net.
+edinstvo62.ru.
+www.dishant.com.
+db._dns-sd._udp.0.1.168.192.in-addr.arpa.
+connect.facebook.net.
+cdn.tynt.com.
+150.238.18.186.in-addr.arpa.
+194.120.76.95.in-addr.arpa.
+av59.ru.
+creative.ak.fbcdn.net.
+gatoquepesca.blogspot.com.
+101.151.104.112.in-addr.arpa.
+s2.youtube.com.
+voipb.sip.yahoo.com.
+google.com.
+a.root-servers.net.
+smsmt.com.s9b1.psmtp.com.
+a.root-servers.net.
+www.gstatic.com.
+iou.com.
+245.143.245.92.in-addr.arpa.
+80.244.51.190.in-addr.arpa.
+dnl-01.geo.kaspersky.com.
+178.206.243.201.in-addr.arpa.
+cs5247.vk.com.
+a.root-servers.net.
+dns.msftncsi.com.
+widgets.amung.us.
+translate.googleapis.com.
+searchjs.s3.amazonaws.com.
+1.156.14.190.in-addr.arpa.
+www.evalapelicula.com.
+profile.ak.fbcdn.net.
+.
+kingedwardvi.devon.sch.uk.
+248.93.228.91.in-addr.arpa.
+d31qbv1cthcecs.cloudfront.net.
+239.6.34.189.in-addr.arpa.
+www.xenciclopedia.com.
+a.root-servers.net.
+safebrowsing.clients.google.com.
+5.17.155.79.in-addr.arpa.
+www.ivosoftware.com.
+www.getmyspacelayouts.com.
+api.twitter.com.
+www.facebook.com.
+169.242.74.201.in-addr.arpa.
+a.root-servers.net.
+twitter.com.
+huntingdon.edu.
+gs.a.sohu.com.
+62.95.141.189.in-addr.arpa.
+luz.edu.ve.
+photos-f.ak.fbcdn.net.
+235.89.252.189.in-addr.arpa.
+sbx.com.
+login.live.com.
+firstcb.com.
+time.nist.gov.
+leonescolorados.blogspot.com.
+mail.montgranite.com.
+i3.ytimg.com.
+32.5.12.189.in-addr.arpa.
+s1-onenote.vo.msecnd.net.
+212.34.227.189.in-addr.arpa.
+gruposis.files.wordpress.com.
+t.co.
+psgw.t-mobilesgws.com.
+116.5.240.189.in-addr.arpa.
+25.23.215.89.in-addr.arpa.
+a-0.19-220990c1.c060583.1518.19d3.3ea1.210.0.5371njcfppgpmlsgm2t5aci8cv.avqs.mcafee.com.
+stun.client.akadns.net.
+tcs.wisebrother.com.
+50.83.168.189.in-addr.arpa.
+local-sn.contacts.msn.com.
+43.111.1.201.in-addr.arpa.
+ropping.tv-asahi.co.jp.
+www.jtfgtmo.southcom.mil.
+profile.ak.fbcdn.net.
+pixel.exelator.com.
+a.root-servers.net.
+googleads.g.doubleclick.net.
+160.107.68.177.in-addr.arpa.
+xslt.alexa.com.
+54.179.59.122.in-addr.arpa.
+www.carnivalspain.com.
+pseudoplocephalus.blogspot.com.
+www.youtu.be.
+75.187.149.187.in-addr.arpa.
+ak.chat.smileycentral.com.
+m.ak.fbcdn.net.
+5.249.33.187.in-addr.arpa.
+beazsims.blogspot.com.
+rikky.spb.su.
+a1108.da1.akamai.net.
+iclub.net.ru.
+www.bluecoat.com.
+www.angiesmovies.com.
+208.68.209.190.in-addr.arpa.
+dns.msftncsi.com.
+a.root-servers.net.
+ecetia.com.
+www.facebook.com.
+24.68.167.190.in-addr.arpa.
+a.root-servers.net.
+fatmanonakeyboard.blogspot.com.
+photos-g.ak.fbcdn.net.
+real-steel.ru.
+xzeitutorialesx.api.channel.livestream.com.
+www.jugarpokerenlinea.com.
+90.121.55.65.in-addr.arpa.
+db._dns-sd._udp.0.1.168.192.in-addr.arpa.
+www.es.fm.
+plusone.google.com.
+finalfantasyversusxiii.es.
+www.inpsasel.gob.ve.
+lb.wordpress.com.
+sacven.org.
+a.root-servers.net.
+jv3inks.com.
+www.pharmaton.nl.
+cf.ads.kontextua.com.
+ltdunlimited.com.
+www.midweek.com.
+loading2.widdit.com.
+r._dns-sd._udp.lan.
+.
+www.hotgames.com.
+goldrush.net.
+kb.mediatemple.net.
+173.110.101.189.in-addr.arpa.
+sim7441.agni.lindenlab.com.
+www.gfrevenge.com.
+153.126.107.190.in-addr.arpa.
+www.happysexgames.com.
+isohunt.com.
+7.123.182.186.in-addr.arpa.
+shorouknews.com.
+profile.ak.fbcdn.net.
+clock.fmt.he.net.
+www.thevipguide.net.
+after.com.mx.
+eu.wikipedia.org.
+www.blogesfera.com.
+tiweb.net.
+a1.sphotos.ak.fbcdn.net.
+isatap.mshome.net.
+media.gobackpacking.com.
+developers.facebook.com.
+redfaceplus.com.
+fec-committees.findthedata.org.
+dark-desert-highway.blogspot.com.
+www.parentalcontrolbar.org.
+omnicustomconcepts.com.
+digimarc.com.
+mothership.co.nz.
+shared.live.com.
+237.33.152.213.in-addr.arpa.
+billing.sharo4ka.ru.
+ego.ru.
+commview-for-wifi.en.softonic.com.
+s.youtube.com.
+pixel.facebook.com.
+176.232.192.199.in-addr.arpa.
+sup.live.com.
+102.108.65.74.in-addr.arpa.
+www.sapa.org.mx.
+250.13.175.71.in-addr.arpa.
+spam.advancedrecyclingtechnology.com.
+cdn.api.twitter.com.
+140.151.228.67.in-addr.arpa.
+8.133.127.200.in-addr.arpa.
+xyzeor7wn.66gy.
+www.xnxx.com.
+13.51.30.76.in-addr.arpa.
+img.babylon.com.
+www.nicolapotts.com.
+fbcdn-sphotos-a.akamaihd.net.
+s2.youtube.com.
+fxfeeds.mozilla.com.
+a8.sphotos.ak.fbcdn.net.
+182.75.245.189.in-addr.arpa.
+tunnel.cfw.trustedsource.org.
+www.limepro.org.
+www.eldesblogue.com.
+join.mywifesmom.com.
+lazurny-bereg.ru.
+www.facebook.com.
+s.youtube.com.
+64.106.55.95.in-addr.arpa.
+173.182.108.186.in-addr.arpa.
+photos-d.ak.fbcdn.net.
+titanium30-en.url.trendmicro.com.
+alliedmedassoc.com.
+225.183.166.190.in-addr.arpa.
+newsletter.catererglobalmail.com.
+stomperauto.com.
+s10.histats.com.
+ad-g.doubleclick.net.
+a.root-servers.net.
+www.facebook.com.
+17.12.52.186.in-addr.arpa.
+www.brigite.com.
+citylifeltd.ru.
+victory.com.
+sim-im.org.
+53.248.188.203.in-addr.arpa.
+www.mujeresdeempresa.com.
+k3a.me.
+southcom.com.au.
+ship-simulator.programas-gratis.net.
+update.epyte.com.
+partner.googleadservices.com.
+alenet.com.
+sp.cwfservice.net.
+118.136.31.186.in-addr.arpa.
+tmss.trendmicro.com.
+s-static.ak.fbcdn.net.
+time.nist.gov.
+apps.facebook.com.
+www.ajodo.org.
+a.root-servers.net.
+www.update.microsoft.com.
+www.propane-generators.com.
+mail2.astri.org.
+baymsg1010825.gateway.messenger.live.com.
+mail.samzas.ru.
+extrahaus.ee.
+trophy.ww.np.community.playstation.net.
+194.186.41.177.in-addr.arpa.
+mtk.katowice.pl.
+a.root-servers.net.
+cdn.api.twitter.com.
+a.root-servers.net.
+16.23.79.190.in-addr.arpa.
+telfor.pt.
+www.juicypark.com.
+156.201.236.190.in-addr.arpa.
+souzacosta.com.br.
+74.230.195.176.in-addr.arpa.
+social.bidsystem.com.
+mail.mcmolds.com.
+www.gellnerism.de.
+rad.msn.com.
+249.170.28.190.in-addr.arpa.
+msnia.login.live.com.
+loading1.widdit.com.
+3.66.248.189.in-addr.arpa.
+blog-francia.com.
+a3.sphotos.ak.fbcdn.net.
+sim7783.agni.lindenlab.com.
+13.232.8.200.in-addr.arpa.
+mail2.mylink.co.za.
+www.movistar.com.mx.
+id.google.com.mx.
+blog.softonic.com.
+batsonassoc.com.
+_738_71_9.
+o5.
+hypem.tumblr.com.
+dterm.com.
+accounts.google.com.
+a.root-servers.net.
+telepienso.wufoo.com.
+17.13.233.201.in-addr.arpa.
+freakflakes.angelmecanico.com.
+d2104492.xoom.it.
+sp.cwfservice.net.
+j.techgsm.com.
+200.19.250.84.in-addr.arpa.
+ocsp.godaddy.com.
+herbank.com.s6b1.psmtp.com.
+cdt.org.
+www.facebook.com.
+www.facebook.com.
+a1.sphotos.ak.fbcdn.net.
+sn3.mailshell.net.
+i273.photobucket.com.
+pic4.bai.sohu.com.cn.
+252.96.244.189.in-addr.arpa.
+www.facebook.com.
+pixel.everesttech.net.
+cabworks.com.
+a.root-servers.net.
+mm1.curtiscirc.com.
+rabota-kms.ru.
+fairy-games.dressupgames8.com.
+safebrowsing-cache.google.com.
+www.antoniograndiodopico.es.
+www.facebook.com.
+a.root-servers.net.
+241.25.82.190.in-addr.arpa.
+photos-b.ak.fbcdn.net.
+203.21.94.208.in-addr.arpa.
+25.119.220.189.in-addr.arpa.
+www.strawberryfields.net.
+248.11.159.189.in-addr.arpa.
+pixel.facebook.com.
+vkontakte.ru.
+static.ak.fbcdn.net.
+emltrk.com.multi.surbl.org.
+2.bp.blogspot.com.
+js2.wlxrs.com.
+50.203.80.190.in-addr.arpa.
+50.36.199.71.in-addr.arpa.
+barracuda.alamo1.com.
+taconicchevrolet.com.
+b._dns-sd._udp.home.
+www.aciprensa.com.
+www.v2music.com.
+2.56.206.190.in-addr.arpa.
+www.primeraplana.com.co.
+fbcdn-photos-a.akamaihd.net.
+tc20.easythumbhost.com.
+ksn1-12-part1.kaspersky-labs.com.
+sites.google.com.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+sxsoft.ru.
+www.bayheights.com.
+carltonfoster.com.
+accs-net.com.
+molehillgroup.com.
+175.175.176.114.in-addr.arpa.
+78.101.190.190.in-addr.arpa.
+www.animesv.com.
+marbiopharm.nid.ru.
+www.googleapis.com.
+_136_83_8.
+bestmanager.rags.ru.
+register.iomegacloud.com.
+static.ak.fbcdn.net.
+profile.ak.fbcdn.net.
+36.188.218.188.in-addr.arpa.
+creative.ak.fbcdn.net.
+51.52.249.190.in-addr.arpa.
+a.root-servers.net.
+www.youlikehits.com.
+www.vb-helper.com.
+www.snapper.com.
+au.adserver.yahoo.com.
+www.vintagesexclub.com.
+13.28.14.82.in-addr.arpa.
+www.cellfun.info.
+archivoslb2.minijuegostop.com.mx.
+creative.ak.fbcdn.net.
+:kdziv:14.g44c7m1w.
+cdn.api.twitter.com.
+pixel.facebook.com.
+metrics.apple.com.
+201.215.80.80.in-addr.arpa.
+video.cloudfront.autoexpress.co.uk.
+internet.cgocable.net.
+130.24.80.69.in-addr.arpa.
+best-colon-cleanse-reviews.com.
+r1-ads.ace.advertising.com.
+usersystem783aa.ru.
+google.com.
+m.facebook.com.
+x2kcha7v3.56hk.
+mail.ammann.co.uk.
+176.218.142.190.in-addr.arpa.
+www.acasatv.ro.
+mail.sspp.ru.
+224.112.4.190.in-addr.arpa.
+photos-c.ak.fbcdn.net.
+any-world.ngd.ysm.yahoodns.net.
+profile.ak.fbcdn.net.
+asotrack2.fluentmobile.com.
+burbankwhittemore.com.
+234.202.111.212.in-addr.arpa.
+nationwide.com.
+a.root-servers.net.
+mail.pkokprf.ru.
+forums.graaam.com.
+6.21.129.50.in-addr.arpa.
+a.root-servers.net.
+ssl.gstatic.com.
+242.242.111.190.in-addr.arpa.
+www.bravotube.net.
+www.youtube.com.
+73.233.18.177.in-addr.arpa.
+rt.legolas-media.com.
+www.sarahdavis.com.au.
+kp.incompany.ru.
+thelennoxx.files.wordpress.com.
+www.addthis.com.
+kr.yahoo.com.
+static.ak.fbcdn.net.
+18.127.4.190.in-addr.arpa.
+111.16.153.189.in-addr.arpa.
+external.ak.fbcdn.net.
+simsdescargas.com.
+lostangelesca.tumblr.com.
+a1003.w41.akamai.net.
+profile.ak.fbcdn.net.
+img3.kuwo.cn.
+dns.msftncsi.com.
+ice-watch.com.
+infieleschile.es.tl.
+0-jk-w.channel.facebook.com.
+loading321.com.
+dsn12.d.skype.net.
+67.16.190.72.in-addr.arpa.
+mail.younameitspecialties.com.
+gamebt.ali213.net.
+652.talkgadget.google.com.
+ad.smowtion.com.
+redesycominformal.blogspot.com.
+gamehall11.3g.qq.com.
+www.facebook.com.
+27.180.158.187.in-addr.arpa.
+www.winkeyfinder.com.
+update.eset.com.
+yahoo.com.
+a2.sphotos.ak.fbcdn.net.
+60.32.139.189.in-addr.arpa.
+164.147.246.201.in-addr.arpa.
+189.59.168.200.in-addr.arpa.
+crl.microsoft.com.
+90.2.235.209.in-addr.arpa.
+20.80.59.82.in-addr.arpa.
+seroesdaines.blogspot.com.
+6fdvkyhlv.09ty.
+blst.msn.com.
+72.132.176.186.in-addr.arpa.
+ad.doubleclick.net.
+0-278.channel.facebook.com.
+plus.google.com.
+katemiddletonfan.co.uk.
+time-nw.nist.gov.
+www.facebook.com.
+google.com.
+www.united-internet.com.
+gs-loc.isg-apple.com.akadns.net.
+153.113.233.118.in-addr.arpa.
+www.phpexpertsforum.com.
+dixonvision.com.
+www.refurbished-notebooks.de.
+falabella.com.pe.
+hits.e.cl.
+webcache.googleusercontent.com.
+161.2.10.187.in-addr.arpa.
+lshallmark.com.
+safebrowsing.clients.google.com.
+rapidssl-crl.geotrust.com.
+www.yout.
+s-static.ak.facebook.com.
+hexane.bluejava.net.
+2pp5qdw4w.y15f4m2x.
+www.cywex.com.
+rad.msn.com.
+wholinkstome.com.
+3.bp.blogspot.com.
+www.vspor.com.
+nniline.naver.com.
+i3.ytimg.com.
+a.root-servers.net.
+rules.securestudies.com.
+fidohitop.ca.
+hi-in.facebook.com.
+google.com.
+xxxvideos.sso9523.com.
+164.124.162.190.in-addr.arpa.
+www.google-analytics.com.
+250.219.141.62.in-addr.arpa.
+twincitygroup.com.inbound20.mxlogicmx.net.
+www.mydearjenn.com.
+cclc.com.inbound15.mxlogic.net.
+www.yahoo.com.
+www.avgthreatlabs.com.
+lugano.com.
+cri8yysa5.85fy.
+yahoo.com.
+www.loaddl.com.
+s.ist1-1.filesor.com.
+www.google.com.
+www.mvanime.com.
+51.116.126.70.in-addr.arpa.
+www.whcc.com.
+www.bdr130.net.
+cpm.biz.
+thevoice.wikia.com.
+www.m5zn.com.
+external.ak.fbcdn.net.
+elhobo.ru.
+124sjlb1p.06qy.
+clientlog.users.conduit.com.
+www.yahoo.com.
+102.101.61.99.in-addr.arpa.
+creative.ak.fbcdn.net.
+profile.ak.fbcdn.net.
+157.139.79.187.in-addr.arpa.
+77u:w8p65.y62b4c9r.
+e-surance.ru.
+106.245.48.190.in-addr.arpa.
+apps.facebook.com.
+painewetzel.com.
+graycalhoun.com.
+mail.groupe-ldi.com.
+www.cinetux.org.
+js.admeld.com.
+translate.google.com.
+luther-veno.com.
+sm.pemex.com.
+www.ldelectura.com.
+ssl.gstatic.com.
+facebook.blurtit.com.
+s2.youtube.com.
+talk.google.com.
+bs.serving-sys.com.
+108.66.173.58.in-addr.arpa.
+www.youtube.com.
+probitycr.com.
+underground-land.blogspot.com.
+external.ak.fbcdn.net.
+static.ak.fbcdn.net.
+citigrove.com.
+pantelis.co.uk.
+s2.youtube.com.
+175.71.63.71.in-addr.arpa.
+apis.google.com.
+esp.cr.usgs.gov.
+www.encuentra.gob.mx.
+229.235.124.186.in-addr.arpa.
+67.65.213.201.in-addr.arpa.
+196.21.39.187.in-addr.arpa.
+www2.esmas.com.
+a1003.w41.akamai.net.
+215.233.90.80.in-addr.arpa.
+www.slicingpsdtohtml.com.
+www.quadratin.com.mx.
+news.keralakaumudi.com.
+download.windowsupdate.com.
+sqhkcpsmu.91cc.
+.
+www.google.com.
+www.diacono.cl.
+photos-c.ak.fbcdn.net.
+photos-h.ak.fbcdn.net.
+api.cloudsponge.com.
+skynet.be.
+89.68.104.189.in-addr.arpa.
+forums.ereplacementparts.com.
+susangaer.com.
+_466_60_9.
+mtwerweb.com.
+244.171.86.74.zen.spamhaus.org.
+jailbreakmatrix.com.
+pixel.facebook.com.
+accounts.google.com.
+229.15.157.201.in-addr.arpa.
+www.sandos4u.com.
+w3fp.arizona.edu.
+auto-deflectors.com.
+226.127.63.200.in-addr.arpa.
+sites.google.com.
+surfacemag.com.
+stats.wordpress.com.
+linkhelp.clients.google.com.
+65.55.62.189.in-addr.arpa.
+s-static.ak.fbcdn.net.
+42.26.132.190.in-addr.arpa.
+user.easyn.cn.
+www.microscopy.fsu.edu.
+i.creativecommons.org.
+_891_19_1.
+analytics.binarysolutions.biz.
+fb.com.
+dns194.a.register.com.
+banners.webmasterplan.com.
+photos-a.ak.fbcdn.net.
+x.tagstat.com.
+docs.google.com.
+t0.gstatic.com.
+dns.msftncsi.com.
+44.63.111.87.in-addr.arpa.
+profile.ak.fbcdn.net.
+r._dns-sd._udp.lan.
+twitter.com.
+ftp.us.dell.com.
+t2.gstatic.com.
+a8.sphotos.ak.fbcdn.net.
+creativecommons.org.
+berrycoder.com.
+123.254.56.190.in-addr.arpa.
+www.hormiga.org.
+gentenotable.com.
+www.dmedicina.com.
+arjunaardagh.com.
+msn.toutelatele.com.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+teredo.ipv6.microsoft.com.
+44.245.172.201.in-addr.arpa.
+s-static.ak.fbcdn.net.
+nl.y8.com.
+a.erectopatentpothunter.com.
+31.179.253.201.in-addr.arpa.
+113.163.56.186.in-addr.arpa.
+safebrowsing.clients.google.com.
+infoway.ru.
+72.99.205.112.in-addr.arpa.
+pagead2.googlesyndication.com.
+evidence.uche.org.
+i1.ytimg.com.
+gayforjohnnydepp.com.
+www.drumming.com.
+www.xor-motors.com.
+0-0.qlty.finarea.ch.
+qpfhg2ucf.13jp.
+www.miedoescenico.com.mx.
+www.accequip.com.
+ocsp.verisign.com.
+a-0.19-21098081.9050583.1518.19d3.2f4a.210.0.p99c86uikwh4wwpwi6nsbf1vq6.avqs.mcafee.com.
+225.103.156.189.in-addr.arpa.
+cdn.api.twitter.com.
+alert.services.conduit.comalerts.
+photos-c.ak.fbcdn.net.
+ksn4.kaspersky-labs.com.
+236.66.81.186.in-addr.arpa.
+136.194.129.189.in-addr.arpa.
+190.243.61.200.in-addr.arpa.
+163.91.75.187.in-addr.arpa.
+www.pararegalar.com.
+mx01.ancara.net.
+www-cctld.l.google.com.
+scripts.downloadroute.com.
+actualizacionesturismo.blogspot.com.
+graph.facebook.com.
+cibcommunications.co.uk.
+photos-g.ak.fbcdn.net.
+227.24.207.190.in-addr.arpa.
+fbcdn-profile-a.akamaihd.net.
+leycite.com.
+ssl.gstatic.com.
+networld.com.
+d3lvr7yuk4uaui.cloudfront.net.
+ws.audioscrobbler.com.
+www.ador.state.al.us.
+111.111.75.201.in-addr.arpa.
+cbre.com.
+www.stadt-koeln.de.
+179.126.4.190.in-addr.arpa.
+169.82.15.74.in-addr.arpa.
+www.milonic.com.
+www.coolarcade.org.
+pixel.facebook.com.
+108.139.103.177.in-addr.arpa.
+152.140.23.187.in-addr.arpa.
+70.43.15.187.in-addr.arpa.
+www.espacioeuropa.eu.
+lh3.googleusercontent.com.
+a2.sphotos.ak.fbcdn.net.
+162.192.0.79.in-addr.arpa.
+124.31.240.201.in-addr.arpa.
+crossfitmobile.blogspot.com.
+humanitarianbowl.com.
+s.ytimg.com.
+t1.gstatic.com.
+profile.ak.fbcdn.net.
+244.132.82.190.in-addr.arpa.
+t1.gstatic.com.
+embed.dada.net.
+208.27.212.89.in-addr.arpa.
+www.thecures.info.
+ddm-payment.wooga.com.
+www.google.com.
+112.76.154.186.in-addr.arpa.
+api.megaapi.com.
+a.root-servers.net.
+a.ads2.msads.net.
+profile.ak.fbcdn.net.
+dessy.ru.
+virus-x-world.blogspot.com.
+dnl-01.geo.kaspersky.com.
+avatar.nimbuzz.com.
+a2.sphotos.ak.fbcdn.net.
+puls.omsk.su.
+jaxxmfg.com.
+fotmobapi.s3.amazonaws.com.
+www.sparkdream.net.
+126.245.36.186.in-addr.arpa.
+117.9.129.189.in-addr.arpa.
+necessitation.option.wisher.net.
+pelis8.blogspot.com.
+oceaneconsulting.com.
+dtxtngytz5im1.cloudfront.net.
+113.232.214.189.in-addr.arpa.
+ns4.p26.dynect.net.
+clients1.google.com.
+www.blogger.com.
+habichuelasmagicas.wordpress.com.
+159.188.8.200.in-addr.arpa.
+toolbar.zynga.com.
+s-static.ak.facebook.com.
+www.facebook.com.
+t0.gstatic.com.
+www.grupoalianzaempresarial.com.
+hostmyimage.org.
+ksn2-12.kaspersky-labs.com.
+api.facebook.com.
+20minutos.feedsportal.com.
+158.24.75.190.in-addr.arpa.
+google.com.
+49-courier.push.apple.com.
+a1459.phobos.apple.com.edgesuite.net.
+223.165.50.190.in-addr.arpa.
+www.escueladigital.com.uy.
+crl.globalsign.net.
+www.google.com.
+27.249.153.186.in-addr.arpa.
+a1656.phobos.apple.com.
+img168.imageshack.us.
+www.google.com.
+tuttipazziperilgossip.blogspot.com.
+time.chttl.com.tw.
+star.facebook.com.
+www.xatech.com.
+search.bearshare.com.
+mirocine.net.
+www.wildpee.com.
+fbcdn-photos-a.akamaihd.net.
+33.219.171.201.in-addr.arpa.
+soroc.com.
+www.facebook.com.
+maktoob.omg.yahoo.com.
+losangeles.craigslist.org.
+www.flickr.com.
+www.howtodownloadmusic.net.
+ksn2-12.kaspersky-labs.com.
+3.bp.blogspot.com.
+www.df.cl.
+mx.airbits.net.
+inv75-2-82-229-190-6.fbx.proxad.net.
+ec.atdmt.com.
+mx3.altour.com.
+viewer.office.naver.com.
+connect.facebook.net.
+a221.phobos.apple.com.
+a3.sphotos.ak.fbcdn.net.
+www.nanex.net.
+naw7gw:sk.v17e3g5g.
+chloesnails.blogspot.com.
+29.media.tumblr.com.
+ruinnation.com.
+www.mozilla.org.
+www.creandoprosperidad.es.
+runofeari08.blogdiario.com.
+8.64.210.201.in-addr.arpa.
+www.facebook.com.
+zh-cn.facebook.com.
+updatekeepalive.mcafee.com.
+stream-tv.softonic.com.
+rw6ekuv6i.10yj.
+66.66.170.82.in-addr.arpa.
+69.131.138.201.in-addr.arpa.
+google.com.
+hardincountybank.com.s7b1.psmtp.com.
+chubov.ru.
+119.121.142.187.in-addr.arpa.
+7.26.133.189.in-addr.arpa.
+www.zynga.com.
+51.242.79.190.in-addr.arpa.
+data1.vod.itc.cn.
+ui.skype.com.
+www.healthinnumbers.com.
+s2.youtube.com.
+ksn1-11-part1.kaspersky-labs.com.
+twitter.com.
+it-it.facebook.com.
+www.overstone57.com.
+www.kayak.com.
+151.134.252.190.in-addr.arpa.
+andymwilliams.com.
+a5.sphotos.ak.fbcdn.net.
+www.facebook.com.
+krtec.tgc-9.ru.
+197.214.204.200.in-addr.arpa.
+a756.l.akamai.net.
+orcart.facebook.com.
+safebrowsing.clients.google.com.
+217.211.64.187.in-addr.arpa.
+193.93.205.71.in-addr.arpa.
+www.newforo.org.
+a.root-servers.net.
+22.1.203.200.in-addr.arpa.
+cdn.api.twitter.com.
+pixel.facebook.com.
+time.nist.gov.
+girlytattoosforgirls.com.
+ht.com.
+eisbrecher.musicload.de.
+hash.orbitdownloader.com.
+tuxtor.shekalug.org.
+mentalized.net.
+a.root-servers.net.
+www.stopbadware.org.
+252.96.186.79.in-addr.arpa.
+hicksholdings.com.
+jlcaravias.files.wordpress.com.
+z4khime.tumblr.com.
+sedmikrasky.blogspot.com.
+a.root-servers.net.
+rospres.com.
+214.27.172.220.in-addr.arpa.
+plus.google.com.
+cr1-lon.tudor.com.
+tmx.technoratimedia.com.
+colegialashot.blogspot.com.
+143.29.206.24.in-addr.arpa.
+region-ttk.ru.
+c247723.r23.cf1.rackcdn.com.
+48.181.63.69.in-addr.arpa.
+a.root-servers.net.
+www.facebook.com.
+safebrowsing.clients.google.com.
+www.jacksonkatz.com.
+www.cheapdesignerhandbagsnow.com.
+200.1.168.192.in-addr.arpa.
+87.27.131.187.in-addr.arpa.
+a.root-servers.net.
+apps.facebook.com.
+mx1.caseware.com.
+api.twitter.com.
+a2.sphotos.ak.fbcdn.net.
+test.domainepublic.net.
+www.viajaryestudiar.com.
+ds.addthis.com.
+19.52.136.175.in-addr.arpa.
+121.122.196.205.in-addr.arpa.
+www30.us.archive.org.
+darlingtonvillage.org.
+www.themasteraccount.com.
+27.210.173.201.in-addr.arpa.
+a1.sphotos.ak.fbcdn.net.
+clicktrack.wnu.com.
+www.materialsuzuki.com.
+32.50.91.72.in-addr.arpa.
+video.dailymail.co.uk.
+www.shap.com.ar.
+6d9kv54u3.w54t0q1m.
+lb._dns-sd._udp.localdomain.
+www.facebook.com.
+photos-a.ak.fbcdn.net.
+d2090058.xoom.it.
+tech.by.
+safebrowsing-cache.google.com.
+rs138l3.rapidshare.com.
+yareco.ru.
+network.terra.com.mx.
+u20.eset.com.
+c7.zedo.com.
+www.google.com.
+duke.edu.
+api.twitter.com.
+www.beglar.com.
+_885_84_1.
+itunes.apple.com.
+www.oneonlinegames.com.
+rad.msn.com.
+1.108.229.91.in-addr.arpa.
+googleads.g.doubleclick.net.
+158.82.230.190.in-addr.arpa.
+www.estoesmarketing.com.
+mx.itbu.ru.
+msnads.vo.msecnd.net.
+teredo.ipv6.microsoft.com.
+m.y.
+i4.ytimg.com.
+ksn3-11.part2.kaspersky-labs.com.
+4gks1zwr:.l38g4t6w.
+163.141.88.186.in-addr.arpa.
+push.apple.com.
+a3.sphotos.ak.fbcdn.net.
+www.daleonda.com.
+193.105.85.123.in-addr.arpa.
+www.isg-apple.com.akadns.net.
+hamd.co.uk.
+amira-budur.ru.
+www.google.com.
+www.vuu.com.au.
+98.165.124.186.in-addr.arpa.
+a8.sphotos.ak.fbcdn.net.
+214.107.216.87.in-addr.arpa.
+wpad.mshome.net.
+youtubemusica.org.
+vip.adminzu.com.
+postmaster.ru.
+mail2.marshallinstitute.com.
+malah.biz.
+www.ag-quienessomos.com.ar.
+godfatherofgreenbay.xanga.com.
+gfx.aftonbladet-cdn.se.
+181.113.49.92.in-addr.arpa.
+xrysanthema.gr.
+194.89.103.201.in-addr.arpa.
+2.by.dnsbl7.mailshell.net.
+time.chttl.com.tw.
+108.98.96.78.in-addr.arpa.
+73.230.80.72.in-addr.arpa.
+photos-d.ak.fbcdn.net.
+a.root-servers.net.
+js.wlxrs.com.
+father.asahi-net.or.jp.
+118.55.22.190.in-addr.arpa.
+www.facebook.com.
+kcowdin.com.s5b2.psmtp.com.
+cineimperfecto.blogspot.com.
+img.mediaplex.com.
+a3.sphotos.ak.fbcdn.net.
+www.biologiaonline.com.ar.
+services.ticktockapps.com.
+252.45.173.201.in-addr.arpa.
+0-155.channel.facebook.com.
+soundingometersecosasporlapolla.blogspot.com.
+a5.sphotos.ak.fbcdn.net.
+www.apple.com.
+profile.ak.fbcdn.net.
+neuf.fr.
+a3.sphotos.ak.fbcdn.net.
+mail.mypostcardprinting.com.
+forums.support.roxio.com.
+2bnkgpn59.x94r2o8x.
+203.234.152.190.in-addr.arpa.
+50.1.168.192.in-addr.arpa.
+32.213.34.41.in-addr.arpa.
+210.234.152.187.in-addr.arpa.
+games.charlesayoub.com.
+51.220.71.68.in-addr.arpa.
+146.136.23.187.in-addr.arpa.
+cm.netseer.com.
+shorouknews.com.
+129.234.124.186.in-addr.arpa.
+www.youmoviz.com.
+support.microsoft.com.
+js.wlxrs.com.
+bbs.msn.com.cn.
+my-dvd-collection.ru.
+www.the-samaritans.com.
+profile.ak.fbcdn.net.
+photos-h.ak.fbcdn.net.
+photos-f.ak.fbcdn.net.
+partedeconfirmacion.blogspot.com.
+242.7.39.82.in-addr.arpa.
+premium.mookie1.com.
+197.192.126.187.in-addr.arpa.
+googleads.g.doubleclick.net.
+a.root-servers.net.
+www.clive-owen.org.
+manuals.makeuseof.com.s3.amazonaws.com.
+168.228.195.69.in-addr.arpa.
+api.twitter.com.
+s-external.ak.fbcdn.net.
+www.edmondmom.com.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+smtp.tularik.com.
+my.drujok.ru.
+158.173.130.190.in-addr.arpa.
+msn.com.
+holttester.vo.msecnd.net.
+_140_91_0.
+a.root-servers.net.
+126.142.177.189.in-addr.arpa.
+pdq1.com.
+magicdar.ru.
+us.bc.yahoo.com.
+a.root-servers.net.
+profile.ak.fbcdn.net.
+heydary.com.inbound10.mxlogic.net.
+_390_86_1.
+dns.msftncsi.com.
+173.69.138.187.in-addr.arpa.
+a4.sphotos.ak.fbcdn.net.
+clarendon2.k12.sc.us.
+flchsk.info.
+35.92.22.190.in-addr.arpa.
+latabernadeatb.blogspot.com.
+a.root-servers.net.
+de-de.facebook.com.
+safebrowsing.clients.google.com.
+www.blogger.com.
+www.facebook.com.
+d18txuuu339yuz.cloudfront.net.
+i4.ytimg.com.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+www.youtube.com.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+a.root-servers.net.
+26.245.205.87.in-addr.arpa.
+08834c26.ultrafiles.net.
+static.ak.facebook.com.
+75.25.244.62.in-addr.arpa.
+mailspool.citravel.com.
+63.122.138.89.in-addr.arpa.
+designsoftware.com.
+mail.edcspringdale.com.
+banners.adultfriendfinder.com.
+teredo.ipv6.microsoft.com.
+www.qsw11.com.
+images.adultemart.com.
+www.techsoup.org.
+mail.gereaveseng.com.
+fjbaehr.com.
+20.249.83.66.in-addr.arpa.
+196.155.209.190.in-addr.arpa.
+it.wikipedia.org.
+a.root-servers.net.
+cdnedge.bbc.co.uk.
+www.linomixandplay.com.
+sn1msg2020234.gateway.messenger.live.com.
+cdn-sec.tacoda.at.atwola.com.
+preslavaonline.com.
+smkonpunwtfsgsu.com.
+4.2.2.187.in-addr.arpa.
+fcs72-1.streamate.com.
+8.81.210.186.in-addr.arpa.
+ses.library.usyd.edu.au.
+8.70.138.200.in-addr.arpa.
+www.animewolken.nl.
+e.apsalar.com.
+pixel.facebook.com.
+xocolatco.blogspot.com.
+vyletel.com.s6b1.psmtp.com.
+51fvyq9c6.15ej.
+206.187.170.201.in-addr.arpa.
+mail.google.com.
+96.51.39.115.in-addr.arpa.
+hr.cam4.com.
+pl.business-listings.com.
+img175.imagenar.com.
+www.google.com.
+platform.twitter.com.
+38.29.203.68.in-addr.arpa.
+219.23.193.200.in-addr.arpa.
+photos-a.ak.fbcdn.net.
+151.184.104.187.in-addr.arpa.
+www.youtube.com.
+mtalk.google.com.
+www.colemangroup.com.au.
+map.media6degrees.com.
+www.facebook.com.
+mail-relay1.dijit.net.
+www.google-analytics.com.
+168.169.132.190.in-addr.arpa.
+gualdotadinoprimo.it.
+40.227.237.85.in-addr.arpa.
+112.67.84.200.in-addr.arpa.
+16.97.92.200.in-addr.arpa.
+www.beautyundercover.com.
+lb._dns-sd._udp.0.2.168.192.in-addr.arpa.
+api-read.facebook.com.
+louislautman.com.
+tracker4.finalgear.com.
+ccook1.plus.com.
+anthonyyeung.ca.
+www.softworld.com.
+39.253.14.37.in-addr.arpa.
+2.bp.blogspot.com.
+caretta.ro.
+njlwlwevrvontf.com.
+www.buscadoresdedios.es.
+mx.bowserelectronics.com.
+members.multimania.co.uk.
+www.oralb.co.uk.
+bb.xml.slide.com.
+nodropershex.in.
+calendar.live.com.
+a.root-servers.net.
+77.245.168.78.in-addr.arpa.
+static.atgsvcs.com.
+pt.veoh.com.
+www.pitstopmedia.com.
+lucidm.ru.
+www.youtube.com.
+carqueixacesaryjuan.blogspot.com.
+graph.facebook.com.
+animet-movie.blogspot.com.
+www.youtube.com.
+68.245.58.201.in-addr.arpa.
+www.moforacing.com.
+filetterpress.com.
+nt0.ggpht.com.
+ndtserver1.newdaytechnology.com.
+www.amazon.it.
+www.google.com.mx.
+trans-p2p.pandora.tv.
+google.com.
+229.143.37.190.in-addr.arpa.
+hostposter.ru.
+teredo.ipv6.microsoft.com.
+a.root-servers.net.
+s.youtube.com.
+profile.ak.fbcdn.net.
+cms.abmr.net.
+mx.youtube.com.
+aol.com.
+googlemail.l.google.com.
+m.hotmail.com.
+www.facebook.com.
+a.root-servers.net.
+liveupdate.symantecliveupdate.com.
+gfx2.hotmail.com.
+www.elleinterior.se.
+246.59.58.186.in-addr.arpa.
+231.3.201.190.in-addr.arpa.
+www.johanngonzalez.com.
+data.flurry.com.
+a.root-servers.net.
+a.root-servers.net.
+230.215.119.79.in-addr.arpa.
+9.215.192.187.in-addr.arpa.
+236.224.229.78.in-addr.arpa.
+heritagetitleltd.com.inbound10.mxlogic.net.
+londoncityairport.com.
+g.live.com.
+182.64.178.186.in-addr.arpa.
+www.alan4.com.
+download116.avast.com.
+tunnel.web.trustedsource.org.
+meeder.com.
+signup.casualteensex.com.
+dns.msftncsi.com.
+253.249.107.186.in-addr.arpa.
+secure.shared.live.com.
+195.59.136.175.in-addr.arpa.
+www.joegrossberg.com.
+a.root-servers.net.
+belotti.ru.
+ocsp.entrust.net.
+tc20.easythumbhost.com.
+leshiygames.ru.
+a.ads2.msads.net.
+www.coolfreeimages.net.
+www.moldesparachocolate.com.
+164.140.74.76.in-addr.arpa.
+dlvr.it.
+132.166.52.190.in-addr.arpa.
+0-jk-w.channel.facebook.com.
+static.ak.fbcdn.net.
+103.163.107.186.in-addr.arpa.
+50.230.133.78.in-addr.arpa.
+imbui.iminent.com.
+mille-lacs.com.
+177.82.125.74.query.bondedsender.org.
+landsaver.net.
+photos-d.ak.fbcdn.net.
+nailstah.com.
+rmafhtuhqbaayejpvlsy.so.
+226.146.222.176.in-addr.arpa.
+a6.sphotos.ak.fbcdn.net.
+creative.ak.fbcdn.net.
+www.facebook.com.
+www.figfx.com.
+mail.cloud9.net.
+www.google-analytics.com.
+duke-enery.com.
+www.hotmail.com.
+www.jobwinner.ch.
+53.69.97.83.in-addr.arpa.
+135.72.72.190.in-addr.arpa.
+mail.fhacpa.com.
+maps.google.com.
+www.bcscta.ca.
+a996.mm1.akamai.net.
+simplynallely.blogspot.com.
+homelan.bg.
+cdn1.mundodastribos.com.
+life-of-an-architecture-student.tumblr.com.
+adwords.google.com.
+external.ak.fbcdn.net.
+sdgdthf.com.
+www.napnanny.com.
+horizonhealthcorp.com.
+a.root-servers.net.
+apis.google.com.
+die-zivilisatoren.de.
+c.speedtest.net.
+hoffstrizz.typepad.com.
+profile.ak.fbcdn.net.
+connect.facebook.net.
+dns.msftncsi.com.
+a.root-servers.net.
+bastamarine.com.
+voipb.sip.yahoo.com.
+203.17.228.89.in-addr.arpa.
+www.facebook.com.
+22.128.225.190.in-addr.arpa.
+gmailblog.blogspot.com.
+inbound.vietnamanztravel.com.netsolmail.net.
+girlgames2you.com.
+kwoff.com.
+google.com.
+56.116.223.189.in-addr.arpa.
+directory.services.live.com.
+www.terra.com.mx.
+goodvibes.com.mx2.lanxpert.rcimx.net.
+mail.tatabluescopesteel.com.
+dryope.ru.
+128.237.88.186.in-addr.arpa.
+www.beautifulmag.eu.
+rocky.com.
+sweetestpersonblog.com.
+a7.sphotos.ak.fbcdn.net.
+l.yimg.com.
+ibbgrefrathberlin.de.
+s-static.ak.fbcdn.net.
+www.facebook.com.
+blog.gamescheatdirectory.com.
+trabajo.com.mx.
+udarnik-kam.ru.
+simpsons-dvd.ru.
+_011_38_0.
+sites.google.com.
+static.ak.connect.facebook.com.
+210.5.141.188.in-addr.arpa.
+inrca.it.
+static.ak.fbcdn.net.
+fbcdn-sphotos-a.akamaihd.net.
+123.23.143.201.in-addr.arpa.
+miip.es.
+ce.lijit.com.
+www.download.windowsupdate.com.
+a.root-servers.net.
+images03.olx.com.
+www.autotrader.com.cy.
+google.com.
+ww2.asscleaners.com.
+216.143.158.82.in-addr.arpa.
+www.searchqu.com.
+r.mzstatic.com.
+189.1.168.192.in-addr.arpa.
+chillingo-crystal.appspot.com.
+lowcarbdiets.about.com.
+mscrl.microsoft.com.
+sociology.stanford.edu.
+www10.spelar.org.
+hkdmx01.flextronics.com.
+80.11.201.187.in-addr.arpa.
+www.lajollaplayhouse.com.
+mail.google.com.
+dutchlandinc.com.inbound35.mxlogicmx.net.
+android.clients.google.com.
+ffatl.com.
+incredmail.vo.llnwd.net.
+hkmdm.com.
+peptidecalculator.com.
+windowsphone.xbox.com.
+www.facebook.com.
+8gqmpgtte.63sp.
+smart.cellflirt.com.
+mail.cnbrown.com.
+mx2.coelba.com.br.
+photos-g.ak.fbcdn.net.
+merapi.iconpln.net.id.
+api-public.addthis.com.
+bligoo.com.
+47.29.95.190.in-addr.arpa.
+79.102.22.190.in-addr.arpa.
+toyotamaint.tekgroupweb.com.
+konatools.ru.
+www.facebuzz.com.look-for.us.
+a.root-servers.net.
+5-courier.push.apple.com.
+a.root-servers.net.
+www.ropa-bebe.com.
+tfaballoy.com.
+content.yieldmanager.edgesuite.net.
+148.110.31.75.in-addr.arpa.
+www.desimusic.com.
+grupogondi.com.
+bo.starmedia.com.
+www.google-analytics.com.
+teredo.ipv6.microsoft.com.
+145.108.255.201.in-addr.arpa.
+www.boobsfinder.com.
+photos-f.ak.fbcdn.net.
+menacestudios.com.
+wikoff.com.
+nfscross2010.co.cc.
+basel.int.
+download336.avast.com.
+90.48.126.187.in-addr.arpa.
+pixel.facebook.com.
+nacionvampirica.foromx.org.
+www.pni.org.
+akha.org.
+crow.ru.
+www.conaleptabasco.edu.mx.
+208.172.0.190.in-addr.arpa.
+login.live.com.
+jsu.dt07.net.
+ns2.skybeam.com.
+dns.msftncsi.com.
+a.root-servers.net.
+surtimoda.com.
+s7.addthis.com.
+ad.doubleclick.net.
+38.45.122.186.in-addr.arpa.
+yahoo.com.
+time-b.nist.gov.
+a1108.da1.akamai.net.
+tags.bluekai.com.
+gfx2.hotmail.com.
+comunidad.multimedios.com.
+44.117.95.190.in-addr.arpa.
+www.radiofides.co.cr.
+poolplayers.ca.
+www.youtube.com.
+www.google-analytics.com.
+a.root-servers.net.
+187.28.254.201.in-addr.arpa.
+www.ascodevida.com.
+seorider.ru.
+154.11.6.186.in-addr.arpa.
+r.mzstatic.com.
+ditunney.com.
+jabon-soap.blogspot.com.
+pixel.quantserve.com.
+translate.google.com.mx.
+86.158.231.77.in-addr.arpa.
+ds.serving-sys.com.
+static.ak.fb.
+static.ak.connect.facebook.com.
+server51.appriver.com.
+32.217.30.190.in-addr.arpa.
+.
+msn.com.
+netsave.ru.
+www.facebook.com.
+intercolor-ink.com.
+oneana.com.
+db11.spamcatcher.net.
+40.122.11.190.in-addr.arpa.
+7.59.29.189.in-addr.arpa.
+psgw.t-mobilesgws.com.
+46.91.9.87.in-addr.arpa.
+static.v3beta.buysellads.com.
+arbitr.chita.ru.
+16.1.168.192.in-addr.arpa.
+tracker.bittorrent.am.
+167.153.76.64.in-addr.arpa.
+slsp.manpower.usmc.mil.
+wjprx585h.y63k1m5n.
+android.tweetmeme.com.
+advertiser.doclix.com.
+upwardrealty.com.
+bestaility.monkey-sex.net.
+action.web.ca.
+www.mimejorfrase.biz.
+227.105.134.115.in-addr.arpa.
+www.peliculas-flv.com.
+academics.tjhsst.edu.
+46.191.54.65.in-addr.arpa.
+twentysomethingadvice.blogspot.com.
+ahni.com.s8a2.psmtp.com.
+revelations.seriespepito.com.
+cdn.lfstmedia.com.
+interiormagz.com.
+xvideos-395.vo.llnwd.net.
+segment-pixel.invitemedia.com.
+198.234.167.189.in-addr.arpa.
+55.16.137.187.in-addr.arpa.
+www.oppsofts.com.
+d24w6bsrhbeh9d.cloudfront.net.
+221.114.14.71.in-addr.arpa.
+www.belkin.com.
+cdn.buzznet.com.
+photos-a.ak.fbcdn.net.
+erhanmakas.blogspot.com.
+s52.radikal.ru.
+sp.cwfservice.net.
+a995.mm1.akamai.net.
+www.facebook.com.
+sites.google.com.
+consalting-secrets.ru.
+exch-e.atdmt.com.
+edition.cnn.com.
+asktoolbar.weather.com.
+twitter.com.
+safebrowsing-cache.google.com.
+accounts.google.com.
+transeuro.ru.
+csb-polimer.ru.
+67.54.10.186.in-addr.arpa.
+rockte.blogdiario.com.
+www.lansteel.com.
+s-static.ak.fbcdn.net.
+70.76.139.210.in-addr.arpa.
+google.com.
+22.79.218.188.in-addr.arpa.
+252.162.225.189.in-addr.arpa.
+a.root-servers.net.
+www.adobe.com.
+us.mg4.mail.yahoo.com.
+225.60.37.80.in-addr.arpa.
+4.1.241.189.in-addr.arpa.
+d2098285.xoom.it.
+a4.sphotos.ak.fbcdn.net.
+static.ak.connect.facebook.com.
+199.80.146.187.in-addr.arpa.
+sketchup.google.com.
+27.48.58.201.in-addr.arpa.
+www.pliactom.com.
+www.jcbinternational.com.
+static.ak.fbcdn.net.
+pubads.g.doubleclick.net.
+0.9083944.com.
+187.180.200.189.in-addr.arpa.
+www.eme-equis.com.mx.
+santosneves.ifrance.com.
+130.210.85.200.in-addr.arpa.
+179.232.241.186.in-addr.arpa.
+176.157.167.190.in-addr.arpa.
+i.ebayimg.com.
+rtb.tubemogul.com.
+apps.facebook.com.
+r._dns-sd._udp.0.3.168.192.in-addr.arpa.
+tvsalesnet3.wordpress.com.
+teredo.ipv6.microsoft.com.
+static.ak.fbcdn.net.
+51.27.189.190.in-addr.arpa.
+titanium30-en.url.trendmicro.com.
+insider.msg.yahoo.com.
+focushh.blogspot.com.
+sealine.com.s200a2.psmtp.com.
+1.38.140.186.in-addr.arpa.
+126.1.168.192.in-addr.arpa.
+facemoods.com.
+a1.sphotos.ak.fbcdn.net.
+kfml.ru.
+moscowbsl.ru.
+www.google.com.
+fbcdn-photos-a.akamaihd.net.
+google.com.
+toolbarqueries.google.com.
+160.171.250.189.in-addr.arpa.
+apps.facebook.com.
+190.241.226.189.in-addr.arpa.
+samchirnside.com.
+www.gamexchange.co.uk.
+fxfeeds.mozilla.com.
+125.93.134.189.in-addr.arpa.
+alerts.conduit-services.com.
+247.138.61.83.in-addr.arpa.
+a.root-servers.net.
+resources.search.conduit.com.
+www.soccerwallpaper.mackafe.com.
+a3.sphotos.ak.fbcdn.net.
+graph.facebook.com.
+android.clients.google.com.
+blog.macsales.com.
+75.94.91.186.in-addr.arpa.
+243.6.144.79.in-addr.arpa.
+itunes.apple.com.
+www.google.com.
+rotg.gazprom.ru.
+d2055212.instant.xoom.it.
+gm.
+ieonlinews.microsoft.com.
+disneyfanscolombia.blogspot.com.
+computerrepairservice.net.
+glow.draw.spankapps.com.
+www.belkin.com.
+caulfield-glen-eira-leader.whereilive.com.au.
+photos-h.ak.fbcdn.net.
+teredo.ipv6.microsoft.com.
+bitly.com.
+a.root-servers.net.
+23.140.66.201.in-addr.arpa.
+vitaltareasdacs.files.wordpress.com.
+static.ak.fbcdn.net.
+211.208.1.187.in-addr.arpa.
+rover.ebay.com.
+a1505.l.akamai.net.
+208.215.174.190.in-addr.arpa.
+145.10.251.85.in-addr.arpa.
+negroprazers.blogspot.com.
+secure.wlxrs.com.
+podebradka.cz.
+lb._dns-sd._udp.0.2.168.192.in-addr.arpa.
+mail2.khh.com.
+apix.iminent.com.
+www.google-analytics.com.
+www.ford.com.
+bernhard.as.
+api.twitter.com.
+lzb.ac.cn.
+www.abeacha.com.
+www.google.com.uy.
+www.google.com.
+83.232.48.65.in-addr.arpa.
+a.root-servers.net.
+114.204.168.192.in-addr.arpa.
+utm.trk.mywebsearch.com.
+app9976039262.socialappspot.com.
+www.vankaizer.com.
+107.146.220.66.in-addr.arpa.
+50.90.138.98.zen.spamhaus.org.
+tpb.tracker.thepiratebay.org.
+4.220.90.186.in-addr.arpa.
+hac.datafeed.weatherbug.com.
+static.ak.fbcdn.net.
+www.youtube.com.
+pib.sagepub.com.
+194.11.0.10.in-addr.arpa.
+www.picnik.com.
+aws.amazon.com.
+a.root-servers.net.
+ar.astrology.yahoo.com.
+wingatenewtampa.com.
+fuanimes.obolog.com.
+142.6.62.186.in-addr.arpa.
+dsn1.d.skype.net.
+sormovo.ru.
+mail.bioflora.com.
+scat.nsk.su.
+sites.google.com.
+s-static.ak.fbcdn.net.
+multiply.com.
+46.218.131.187.in-addr.arpa.
+t.15yule.com.
+102.119.11.189.in-addr.arpa.
+a1402.w40.akamai.net.
+distilleryimage7.s3.amazonaws.com.
+creative.ak.fbcdn.net.
+theideabox.com.
+alertpayments.org.
+pixel.facebook.com.
+track.brighteroption.com.
+twitter.com.
+xcdn.xgraph.net.
+a1.sphotos.ak.fbcdn.net.
+aitmx6.prodigy.net.
+www.drdenimjeans.com.
+cache.pack.google.com.
+cdn1.differencebetween.com.
+tpc-usa.com.
+quadcmanagement.com.
+evsecure-crl.verisign.com.
+conntest.nintendowifi.net.
+www.google.com.
+www.thehotcars.com.
+rad.msn.com.
+facemoods.com.
+a12.t26.net.
+mx.mass.flexmail.ifxnetworks.com.
+by2msg3010614.gateway.messenger.live.com.
+uskh.com.s5a1.psmtp.com.
+bt.newfiles.ge.
+e-2dj6wjk4kicpocp.stats.esomniture.com.
+www.reddit.com.
+www.oscarvelazquez.es.
+www.paulsibley.net.
+isatap.home.
+tradersrealty.com.
+m.facebook.com.
+a.root-servers.net.
+share.meebo.com.
+www.col.org.pe.
+cineland.it.
+pagead2.googlesyndication.com.
+se2ojnn17.g88r7d7y.
+germinal.ru.
+d24elmu442q75h.cloudfront.net.
+30.117.11.189.in-addr.arpa.
+ping.chartbeat.net.
+28.183.109.84.in-addr.arpa.
+toolbarqueries.google.com.
+236.12.0.10.in-addr.arpa.
+www.belkin.com.
+profile.ak.fbcdn.net.
+likemindsearch.blogspot.com.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+chat.facebook.com.
+71.129.158.82.in-addr.arpa.
+api.twitter.com.
+www.smartglance.com.
+www.alliedvisiontec.com.
+mx.suddenlinkmail.com.
+it-it.facebook.com.
+229.118.206.190.in-addr.arpa.
+www.get10up.com.
+113.174.42.190.in-addr.arpa.
+ksn2-12.kaspersky-labs.com.
+trace.geewa.ws.
+photos-g.ak.fbcdn.net.
+google.com.
+mobth1213.photobucket.com.
+beckson.com.
+profile.ak.fbcdn.net.
+tags.bluekai.com.
+fcss.eslamoda.com.
+t-ono.net.
+safebrowsing.clients.google.com.
+n:u2:aa6s.v73r9j6p.
+www.attarikh-alarabi.ma.
+platform.twitter.com.
+resources3.deepdiscount.com.
+76.218.35.189.in-addr.arpa.
+oildompublishing.com.inbound15.mxlogic.net.
+yahoo.com.
+.
+fbcdn-photos-a.akamaihd.net.
+a7.sphotos.ak.fbcdn.net.
+mail.greenfieldpartners.com.
+mail.ibc-rus.ru.
+sbcgloboel.net.
+mail.hitechsyringes.com.
+blr.vsnl.net.
+135.113.68.201.in-addr.arpa.
+content.yieldmanager.edgesuite.net.
+www.myspaceeditor.it.
+download828.avast.com.
+66.17.85.98.in-addr.arpa.
+165.1.172.201.in-addr.arpa.
+college.sciences-po.fr.
+apps.facebook.com.
+static.fc2.com.
+www.google.es.
+i1.ytimg.com.
+a.root-servers.net.
+apps.facebook.com.
+domobuilder.ru.
+www.kiki18blog.com.
+137.233.247.190.in-addr.arpa.
+www.tmbg.com.
+a.root-servers.net.
+feeds.tversity.com.
+www.facebook.com.
+kanztov.ru.
+barracuda.redcell.us.
+bta.kz.
+check4.facebook.com.
+mail.homeshowroom.com.tr.
+111.54.94.189.in-addr.arpa.
+musica.nexos.com.mx.
+s.youtube.com.
+www.3dtvworld.com.au.
+crl.microsoft.com.
+cdn-mkt.wooga.com.
+notlivialgreal.tk.
+images.google.com.
+localhost.
+187.11.229.109.in-addr.arpa.
+join.ruthblackwell.com.
+hbl.com.s200a1.psmtp.com.
+ajax.googleapis.com.
+smart-link.ru.
+230.102.199.190.in-addr.arpa.
+gy7phhdv5.r77f0j0g.
+api-read.facebook.com.
+nrce.com.inbound10.mxlogic.net.
+overlandwest.com.
+exchange.upsales.ru.
+s.xvideos.com.
+19.63.235.190.in-addr.arpa.
+groups.google.com.mx.
+english.stackexchange.com.
+www.google-analytics.com.
+cdn.tynt.com.
+gc76c5f21468d4c68.api.playtomic.com.
+cdn.api.twitter.com.
+sas.ru.
+de-de.facebook.com.
+skywork.ch.
+www.autos.clarin.com.
+214.174.138.187.in-addr.arpa.
+www.dressyourbodytype.com.
+ads.tlvmedia.com.
+www.cyta.com.ar.
+api.twitter.com.
+sipexternal.clariant.com.
+www.miauu.com.
+pu.rs.
+46.229.56.187.in-addr.arpa.
+www.mozilla.com.
+blog.touchmypixel.com.
+display-kim.ru.
+sjmneuro.com.s6a1.psmtp.com.
+www.flightops.sita.aero.
+www.bringitonmovie.com.
+ad.amgdgt.com.
+www.zuvik.com.
+youtu.be.
+tag.admeld.com.
+rt.legolas-media.com.
+s.ytimg.com.
+appworld.blackberry.com.
+ssl.gstatic.com.
+20minutos.feedsportal.com.
+a.root-servers.net.
+rosgold.ru.
+ds.serving-sys.com.
+b.hardcorebattle.com.
+photos-h.ak.fbcdn.net.
+googleads.g.doubleclick.net.
+heartagramania.blogspot.com.
+www.redalyc.uaemex.mx.
+a.root-servers.net.
+_221_83_6.
+creative.ak.fbcdn.net.
+www.google.com.
+mail2.southernautogroup.com.
+cardiologygroup.com.
+www.faceboo.
+27.152.9.94.in-addr.arpa.
+es.starmedia.com.
+www.bized.co.uk.
+tools.google.com.
+richmondhabitat.org.
+prod1.rest-notify.msg.yahoo.com.
+shared.live.com.
+rs274tl5.rapidshare.com.
+rybinsk.info.
+cache.pack.google.com.
+235.112.109.75.in-addr.arpa.
+m.addthisedge.com.
+a5.sphotos.ak.fbcdn.net.
+97.18.217.196.in-addr.arpa.
+mail.google.com.
+25.42.14.201.in-addr.arpa.
+memesmansion.blogspot.com.
+85.14.141.201.in-addr.arpa.
+teredo.ipv6.microsoft.com.
+www.umrg.com.
+hotmail.vo.msecnd.net.
+www.facebook.com.
+www.youtube.com.
+i.dailymail.co.uk.
+es-es.facebook.com.
+cdn.livestream.com.
+relay.tyre.kirov.ru.
+profile.ak.fbcdn.net.
+a7.sphotos.ak.fbcdn.net.
+dekstravel.ru.
+p.searchpreview.de.
+ia.wikipedia.org.
+www.vollversion.de.
+www.yahoo.com.
+58.187.182.188.in-addr.arpa.
+thegolfcartplaceinc.com.
+sc2.rules.mailshell.net.
+teredo.ipv6.microsoft.com.
+mail.ekonpowdercoating.com.
+r._dns-sd._udp.lan.
+133.65.69.186.in-addr.arpa.
+bslgroup.ru.
+dns.msftncsi.com.
+sugarsickness.tumblr.com.
+www.google.com.
+www.buzzflash.net.
+s661.photobucket.com.
+220.105.84.200.in-addr.arpa.
+col.stc.s-msn.com.
+couponbuddy.s3.amazonaws.com.
+dfd3ef97bb2147a3cbd6aa7aa78e17.mail.outlook.com.
+a.root-servers.net.
+21.23.216.178.in-addr.arpa.
+youtube-ui.l.google.com.
+tecnologia.starmedia.com.
+go.microsoft.com.
+www.gsistore.com.
+www.crashtest.com.
+topics.nytimes.com.
+lanashilosmania.blogspot.com.
+a6.sphotos.ak.fbcdn.net.
+frikimami.blogspot.com.
+a.root-servers.net.
+lfs-bruck.at.
+sp.cwfservice.net.
+a.root-servers.net.
+saltillo.olx.com.mx.
+arab-dance.com.
+40.15.1.190.in-addr.arpa.
+dodesign.net.
+ads.yimg.com.
+6.129.56.186.in-addr.arpa.
+by2msg3020413.gateway.messenger.live.com.
+graphicventuresinc.com.
+118.132.162.189.in-addr.arpa.
+googleads.g.doubleclick.net.
+www.google.com.
+137.109.61.174.in-addr.arpa.
+89.1.168.192.in-addr.arpa.
+api.twitter.com.
+227.130.13.187.in-addr.arpa.
+b._dns-sd._udp.0.1.168.192.in-addr.arpa.
+212.98.7.189.in-addr.arpa.
+mailserver.fruchthof.net.
+gw1.sektor74.ru.
+58.128.236.116.in-addr.arpa.
+translate.googleapis.com.
+_909_24_0.
+static.ak.fbcdn.net.
+postech.ac.kr.
+vcs2.msg.yahoo.com.
+live.sekindo.com.
+136.195.74.190.in-addr.arpa.
+_417_93_3.
+a1.sphotos.ak.fbcdn.net.
+tradukka.com.
+brothersoftextreme.ourtoolbar.com.
+_138_63_9.
+97.60.158.189.in-addr.arpa.
+samsungmobile.accu-weather.com.
+google.com.
+profile.ak.fbcdn.net.
+fgngztd59.62zp.
+es-es.facebook.com.
+54.48.234.189.in-addr.arpa.
+northgeorgia.edu.
+ic.tynt.com.
+s.youtube.com.
+partner.googleadservices.com.
+visitors.uxcell.com.
+www.historietasminimas.com.
+es.wikipedia.org.
+135.50.165.95.in-addr.arpa.
+ads.smowtion.com.
+t0.gstatic.com.
+a.root-servers.net.
+stainedglassa2z.com.
+www1.flashgamehq.com.
+l.addthiscdn.com.
+www.ig.gmodules.com.
+static.ak.fbcdn.net.
+fs274.uploading.com.
+herc.com.
+audiojelly.com.
+wvipctipad.ru.
+ad.yieldmanager.com.
+www.google.com.
+www.iplay.ca.
+a.root-servers.net.
+platform.twitter.com.
+googleads.g.doubleclick.net.
+mail.waccamawcardiology.com.
+static.xtravids.com.
+smbz.wikia.com.
+92.148.193.71.in-addr.arpa.
+104.170.28.180.in-addr.arpa.
+sel.ru.
+226.43.35.187.in-addr.arpa.
+cdn.mediafire.com.
+profile.ak.fbcdn.net.
+google.com.
+www.hotline.travel.
+img-cdn.mediaplex.com.
+google.com.
+nht-3.extreme-dm.com.
+_853_04_6.
+photos-g.ak.fbcdn.net.
+149.46.75.201.in-addr.arpa.
+d3lvr7yuk4uaui.cloudfront.net.
+mamatriedinc.com.
+www.facebook.com.
+76.170.161.189.in-addr.arpa.
+211.117.85.89.in-addr.arpa.
+142.32.13.180.in-addr.arpa.
+www.bankofalbania.org.
+thumbs3.ebaystatic.com.
+relay.voice.edge.messenger.live.com.
+tb2000.ru.
+apis.google.com.
+www.ara.cat.
+.
+9.90.186.189.in-addr.arpa.
+disosa-chemicals.com.
+a672.g.akamai.net.
+www.vamosapublicidad.com.
+email.tww.net.
+api.facebook.com.
+multiplos.hotwords.es.
+mail.contorgroup.ro.
+bmp.in.
+external.ak.fbcdn.net.
+ad.yieldmanager.com.
+www.7red.no.
+estaticos.marca.com.
+www.google.com.
+ksn7-12.kaspersky-labs.com.
+www.kpopgames.com.
+lrco.com.
+briarlane.ca.
+www.home-theatre-systems.net.
+dmail.com.lan.
+caster.cricinfo.com.
+249.196.160.190.in-addr.arpa.
+221.127.213.190.in-addr.arpa.
+www.google.com.mx.
+widget-2d.slide.com.
+c13.zedo.com.
+mx.unionpress.net.
+www.time.com.
+www.facebook.com.
+self-improvement.meetup.com.
+219.151.176.190.in-addr.arpa.
+www.construireenbretagne.com.
+www.herbivoracious.com.
+43.99.125.186.in-addr.arpa.
+mail.zhongshi.com.
+66zgr3ks1.y30u4p3e.
+multi.xnxx.com.
+105.191.143.187.in-addr.arpa.
+clients1.google.com.
+www.belkin.com.
+196.51.69.190.in-addr.arpa.
+imageshack.us.
+acep.org.2.arsmtp.com.
+ksdua.com.
+i42.servimg.com.
+www.fidodido.com.
+photos-e.ak.fbcdn.net.
+smtp.aol.com.
+photos-f.ak.fbcdn.net.
+www.google.com.
+235.155.26.125.in-addr.arpa.
+a.root-servers.net.
+csi.gstatic.com.
+www.blogsmithmedia.com.
+photos-b.ak.fbcdn.net.
+denverphone.com.2.0001.arsmtp.com.
+www.zaman.com.tr.
+elalijar.blogspot.com.
+169.38.168.192.in-addr.arpa.
+api-read.facebook.com.
+www.tudiscovery.com.
+sp.cwfservice.net.
+balfourbeattyus.com.
+mail.pokerodds.ru.
+babia.net.
+0.thekrazycouponlady.com.
+translate.googleapis.com.
+weather.service.msn.com.
+62.185.230.190.in-addr.arpa.
+www.stenchradio.com.
+sp.cwfservice.net.
+a.root-servers.net.
+230.174.250.186.in-addr.arpa.
+adserving.cpxinteractive.com.
+newsletter.lyleandscott.com.
+logv33.xiti.com.
+profile.ak.fbcdn.net.
+www.cph-artfestival.org.
+bmsi.org.
+heartbeat.belkin.com.
+db._dns-sd._udp.0.0.168.192.in-addr.arpa.
+www.blogsperu.com.
+i2qk4wq4e.l25b5b3l.
+a.root-servers.net.
+ds.serving-sys.com.
+profile.ak.fbcdn.net.
+secure.traveladvertising.com.
+creative.ak.fbcdn.net.
+5.49.140.78.in-addr.arpa.
+msc.wlxrs.com.
+www.gaurijog.com.
+smtp.live.com.
+www.aguilas.tv.
+i3.ytimg.com.
+www.caymanwireless.com.
+photos-b.ak.fbcdn.net.
+media.admob.com.
+www.google-analytics.com.
+sharethis.com.
+api.pinger.com.
+239.222.228.190.in-addr.arpa.
+bin-short.whatsapp.net.
+slb.liveprofile.com.
+markmurphycpa.com.
+85.229.40.187.in-addr.arpa.
+tools.google.com.
+htsannupponew.tm.
+novshadyan.com.
+image.globalwaronline.com.
+www.facebook.com.
+fbcdn-sphotos-a.akamaihd.net.
+178.223.184.79.in-addr.arpa.
+developers.facebook.com.
+soypichichita.blogspot.com.
+imrk.com.
+ad-dc2.adtech.de.
+www.lawlib.state.ma.us.
+www.facebook.com.
+plusone.google.com.
+apis.google.com.
+android.clients.google.com.
+www.theultimateboxingworkout.com.
+a.root-servers.net.
+a3.sphotos.ak.fbcdn.net.
+_032_11_2.
+s10179.netschools.com.
+wfbssvc3.icrc.trendmicro.com.
+static.ak.fbcdn.net.
+momeni.com.inbound15.mxlogicmx.net.
+www.humornegro.com.
+sup.live.com.
+wellspun-ec.com.
+www.youtube.com.
+www.ilightr.com.
+ar-ar.facebook.com.
+uu1.orbitdownloader.com.
+www.lovelyshoes.net.
+10.142.10.186.in-addr.arpa.
+www.elements4health.com.
+clients1.google.com.
+js.xcar.com.cn.
+myci.csuci.edu.
+48.149.220.66.in-addr.arpa.
+s2.youtube.com.
+a2.sphotos.ak.fbcdn.net.
+rad.msn.com.
+53.38.55.94.in-addr.arpa.
+vibratorvpope.ru.
+googleads.g.doubleclick.net.
+wpad.
+bapp.n.shifen.com.
+106.69.105.175.in-addr.arpa.
+s7.addthis.com.
+advertise.courant.com.
+profile.ak.fbcdn.net.
+potterfics.com.
+ad.doubleclick.net.
+bieberfile.tumblr.com.
+tracker.marinsm.com.
+us.data.toolbar.yahoo.com.
+1.0.0.127.dnsbugtest.1.0.0.127.in-addr.arpa.
+clients2.google.com.
+196.230.135.189.in-addr.arpa.
+playerservices.streamtheworld.com.
+bs.serving-sys.com.
+twitter.com.
+www.cnnc.com.cn.
+photos-f.ak.fbcdn.net.
+126.29.139.189.in-addr.arpa.
+fyi.zerolost.org.
+189.65.203.190.in-addr.arpa.
+70.193.180.95.in-addr.arpa.
+modjeski.com.
+ucoz.com.
+screen.yahoo.com.
+img.mediaplex.com.
+www.icono-computadoras-pc.com.
+static.ak.fbcdn.net.
+31.77.228.190.in-addr.arpa.
+v6.cache5.c.youtube.com.
+direct.weatherbug.com.
+thermomt.com.
+login.emlak.net.
+mail.didacware.ch.
+mafiaconnection.ru.
+platform.twitter.com.
+asset3.skimble.com.
+www.latrache.com.
+241.34.3.187.in-addr.arpa.
+a.root-servers.net.
+158.172.120.186.in-addr.arpa.
+photos-c.ak.fbcdn.net.
+www.tumblr.com.
+ssl.gstatic.com.
+www.archenergy.com.
+www.guj.com.br.
+cdptpa-smtpin01.houston.rr.com.
+photos-h.ak.fbcdn.net.
+cdr-software.softonic.com.
+b-0.19-23066089.80110b1.1518.19d4.3ea1.410.0.hllbgf7zr53c248br15qke4gmv.avqs.mcafee.com.
+a5.sphotos.ak.fbcdn.net.
+msn.foxsports.com.
+smtp.srv.ualberta.ca.
+www.frangipane.org.
+stainless-steel.ru.
+c799491.r91.cf2.rackcdn.com.
+127.0.0.1.
+external.ak.fbcdn.net.
+d2105616.xoom.it.
+a1005.w42.akamai.net.
+139.255.214.98.in-addr.arpa.
+99.183.140.203.in-addr.arpa.
+218.25.122.190.in-addr.arpa.
+gmail.com.
+www.adservitrack.com.
+t1.gstatic.com.
+a.root-servers.net.
+www.facebook.com.
+jralert05.emailsp.it.
+5-1.qlty.finarea.ch.
+b.scorecardresearch.com.
+kidshealth.org.
+134.136.105.186.in-addr.arpa.
+deframx24.softcom.dk.
+sn104w.snt104.mail.live.com.
+pjjkp.com.
+www.youtube.com.
+30.video.mystreamservice.com.
+newsrss.bbc.co.uk.
+www.enlightenedbeings.com.
+ia700200.us.archive.org.
+epaenlinea.empleate.com.
+eldiariony.com.s8b2.psmtp.com.
+float-spacer.ru.
+static.ak.fbcdn.net.
+forums.petfinder.my.
+d2102338.xoom.it.
+shipwreck.me.
+inbound.truly.com.netsolmail.net.
+165.82.149.189.in-addr.arpa.
+www.adobe.com.
+8drs:mii7.26yr.
+img2.submanga.com.
+secure-uk.imrworldwide.com.
+c.live.com.
+ec.atdmt.com.
+_849_80_1.
+www.tommys.co.nz.
+pueblo.net.
+69.181.185.190.in-addr.arpa.
+a.root-servers.net.
+au-au.ru.
+photos-h.ak.fbcdn.net.
+43.196.209.91.in-addr.arpa.
+a7.sphotos.ak.fbcdn.net.
+secure-us.imrworldwide.com.
+www.finalteens.com.
+goodvibes.com.
+photos-a.ak.fbcdn.net.
+widgets.twimg.com.
+payment.socialgamenet.com.
+calculator-online.org.
+bstat.mywebsearch.com.
+pop001.masterhost.ru.
+google.com.
+spamsafe2.sctsystems.co.uk.
+20-courier.push.apple.com.
+akinator.co.
+johnmoltarealty.com.
+189.172.173.187.in-addr.arpa.
+ssl.google-analytics.com.
+a.root-servers.net.
+mgnet.com.
+213.58.49.186.in-addr.arpa.
+alico.com.np.
+join.gloryhole-initiations.com.
+a.root-servers.net.
+udc.msn.com.
+ssl.gstatic.com.
+developers.facebook.com.
+external.ak.fbcdn.net.
+parus.nsk.su.
+www.vphairstyles.com.
+debevec.org.
+www.google-analytics.com.
+m.facebook.com.
+98.103.170.201.in-addr.arpa.
+40.135.69.217.in-addr.arpa.
+c.prodigy.msn.com.
+rdmgmtllc.com.s10a1.psmtp.com.
+85.79.41.79.in-addr.arpa.
+cacherito.msk.ru.
+pages.ebay.com.
+www.magisterio.com.co.
+33.16.51.189.in-addr.arpa.
+24.157.220.189.in-addr.arpa.
+cgi5.ebay.com.
+82.127.213.201.in-addr.arpa.
+146.62.207.200.in-addr.arpa.
+s.youtube.com.
+eventosenlinea.blogspot.com.
+ccfamilyhc.com.
+www.dream-crane.com.
+0-staging.channel.facebook.com.
+d2106850.xoom.it.
+a7.sphotos.ak.fbcdn.net.
+m.ak.fbcdn.net.
+comcoupons.com.
+sender5.critsend.com.
+www.facebook.com.
+j.clickdensity.com.
+ksn2-12.kaspersky-labs.com.
+www.juegosdecocina.co.
+fbcdn-photos-a.akamaihd.net.
+www.facebook.com.
+gazdefrance.es.
+platform.twitter.com.
+billing.sharo4ka.ru.
+54.43.212.201.in-addr.arpa.
+www3.virtualedge.com.
+a7.sphotos.ak.fbcdn.net.
+premiertruckcenter.com.
+1ee2f.v.fwmrm.net.
+www.ideal-school.com.
+woin.ru.
+js-kit.com.
+www.dvdvideotool.com.
+hat.net.
+62.0.100.82.in-addr.arpa.
+a5.sphotos.ak.fbcdn.net.
+safebrowsing.clients.google.com.
+elegance.ru.
+22.56.6.186.in-addr.arpa.
+www.portalubuntu.com.
+www.google.com.
+kr.kpost.search.yahoo.com.
+a.root-servers.net.
+www.canaanfairtrade.com.
+32.0.59.186.in-addr.arpa.
+upload.facebook.com.
+csi.gstatic.com.
+alerts.conduit-services.com.
+199.193.253.190.in-addr.arpa.
+www.facebook.com.
+a995.mm1.akamai.net.
+l.yimg.com.
+dns.msftncsi.com.
+010d3230302e392e3132382e3231300000.lbl8.mailshell.net.
+wa.virgilio.it.
+www.google.com.
+www.elnashrafan.com.
+ssl.gstatic.com.
+56.209.50.201.in-addr.arpa.
+trillian.brothersoft.com.
+www.wip4.adobe.com.
+cftfire.com.
+www.nescafe.es.
+a2.sphotos.ak.fbcdn.net.
+7-courier.push.apple.com.
+103.61.106.186.in-addr.arpa.
+cdn1.videothumbs.xtube.com.
+time.chttl.com.tw.
+18.201.175.190.in-addr.arpa.
+194.57.74.190.in-addr.arpa.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+a4.sphotos.ak.fbcdn.net.
+miks-pix.blogspot.com.
+photos-e.ak.fbcdn.net.
+mailgate.server-mail.com.
+www.google-analytics.com.
+www.cartoonnetwork.cl.
+46.5.19.177.in-addr.arpa.
+itsbebeipa01p.eu.jnj.com.
+t4.liverail.com.
+mail.google.com.
+a7.sphotos.ak.fbcdn.net.
+_490_97_9.
+csi.gstatic.com.
+a8.sphotos.ak.fbcdn.net.
+safebrowsing.clients.google.com.
+www.7elm1.com.
+www.jsoftj.com.
+mailcloud6.ourmailservers.net.
+zh-cn.facebook.com.
+mm.servidornoticias.com.
+a.root-servers.net.
+a.root-servers.net.
+8h5aws2pj.77zi.
+www.youtube.com.
+www.sqm.microsoft.com.
+igoogle-skins.googleusercontent.com.
+c.thumbs.redditmedia.com.
+fmail.infotek.ru.
+mail.martin-riley.com.
+platis.updates.pandasoftware.com.
+tbr.ask.com.
+ad.yieldmanager.com.
+developers.facebook.com.
+img1.blogblog.com.
+fpa5b1qrq.a61z3y9j.
+en.wikipedia.org.
+l9ni:4pz5.b20y8k4h.
+miescuelita.org.
+cuneo.alpcom.it.
+entretenimiento.latam.msn.com.
+v45zivrkd.99ql.
+embarzmail.com.
+143.61.4.64.in-addr.arpa.
+nucor-seattle.com.s7a1.psmtp.com.
+149.190.30.211.in-addr.arpa.
+xzqpypjovkvkph.com.
+33.52.244.189.in-addr.arpa.
+217.215.235.201.in-addr.arpa.
+mail4.gosafco.com.
+add.my.yahoo.com.
+apix.iminent.com.
+photos-c.ak.fbcdn.net.
+201.68.155.114.in-addr.arpa.
+b._dns-sd._udp.0.1.168.192.in-addr.arpa.
+googleads.g.doubleclick.net.
+www.youtube.com.mx.
+micromentis.com.
+ssl.gstatic.com.
+pnhoffman.com.s5b2.psmtp.com.
+leadersinstitute.com.s7b2.psmtp.com.
+www.virginsdesires.com.
+www.iminent.com.
+metrics.apple.com.
+developers.facebook.com.
+feedburner.google.com.
+146.238.39.187.in-addr.arpa.
+www.youtube.com.
+www.hotmilfhunter.com.
+235.14.115.212.in-addr.arpa.
+www.google.com.mx.
+p44-buy.itunes.apple.com.
+rasgarelvelo.blogspot.com.
+clients2.google.com.
+a4.sphotos.ak.fbcdn.net.
+static.ak.fbcdn.net.
+russianfemdom.net.
+87.133.34.186.in-addr.arpa.
+a1057.b.akamai.net.
+i.holder.com.ua.
+olivia.com.s5a2.psmtp.com.
+aapexbank.com.
+204.225.138.190.in-addr.arpa.
+cheeseclub.ru.
+a2.espncdn.com.
+twf.com.au.
+www.google.com.
+233.235.163.67.in-addr.arpa.
+ia600205.us.archive.org.
+v21.lscache5.c.bigcache.googleapis.com.
+a3.sphotos.ak.fbcdn.net.
+b-0.19-a3004008.c071081.1518.19d4.3ea1.410.0.hb9dnwhqwczv6eeqserq9nrsgi.avqs.mcafee.com.
+songsofpraise.com.
+pixel.facebook.com.
+_892_54_1.
+43.16.173.70.in-addr.arpa.
+profile.ak.fbcdn.net.
+119.58.146.186.in-addr.arpa.
+c.msn.com.
+tlc.ousd.k12.ca.us.
+baboolercheme.org.
+a8.sphotos.ak.fbcdn.net.
+fr-fr.facebook.com.
+wvxmil7ki.x48a2q8e.
+dns.msftncsi.com.
+services.google.com.
+www.comidacolombiana.com.
+www.detounchin.com.
+cdn.meaningtool.com.
+www.humidipak.com.
+47.161.84.187.in-addr.arpa.
+nkb8cn1t4.w62m0z6u.
+earthlink.net.
+b._dns-sd._udp.0.1.168.192.in-addr.arpa.
+lovetransfusion.tumblr.com.
+www.ediets.com.
+e906.g.akamaiedge.net.
+_574_16_4.
+a4.sphotos.ak.fbcdn.net.
+mx.answers.yahoo.com.
+portalnw.ru.
+www.bywifi.com.
+132.162.20.190.in-addr.arpa.
+www.hk-kicks.com.
+www.bing.com.
+losangeles.imprelistas.com.
+a1.sphotos.ak.fbcdn.net.
+photos-c.ak.fbcdn.net.
+espire.net.
+connect.facebook.net.
+sp.cwfservice.net.
+fbcdn-photos-a.akamaihd.net.
+mail.jvkmovers.com.
+a.root-servers.net.
+www.girlsgogames.es.
+40.29.53.83.in-addr.arpa.
+cms.quantserve.com.
+mail.110sf.ru.
+sabine.com.
+kronix.ru.
+mail.xn--80adhndn9l.com.
+a7.sphotos.ak.fbcdn.net.
+mscrl.microsoft.com.
+summerthymestudio.blogspot.com.
+developers.facebook.com.
+contextmenu.toolbar.conduit-services.com.
+widget3.linkwithin.com.
+prensahistorica.mcu.es.
+a.root-servers.net.
+bmw-avtohaus.ru.
+243.185.65.85.in-addr.arpa.
+191.225.253.201.in-addr.arpa.
+developers.facebook.com.
+bobmakarley.ru.
+mpv.web.aol.com.
+ksn2-12.kaspersky-labs.com.
+www.tedligety.com.
+www.chandrakclarke.com.
+db._dns-sd._udp.0.0.168.192.in-addr.arpa.
+baymsg1020323.gateway.messenger.live.com.
+api.twitter.com.
+202.113.143.114.in-addr.arpa.
+a5.sphotos.ak.fbcdn.net.
+www.winajuda.com.
+affiliate.ru.
+957993.r.msn.com.
+smtp.domainsbyproxy.com.
+comersantander.com.
+novelasconfamosos.globered.com.
+xompuserve.com.
+tobolsk.info.
+css.wlxrs.com.
+photos-a.ak.fbcdn.net.
+211.149.195.210.in-addr.arpa.
+api.twitter.com.
+a.root-servers.net.
+development1.entremed.com.
+c.f.4.f.7.6.b.2.d.f.b.3.c.5.0.1.d.f.9.7.5.f.e.5.0.0.0.0.1.0.0.2.ip6.arpa.
+www.facebook.com.
+14.251.48.190.in-addr.arpa.
+a1404.w41.akamai.net.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+mx3.mariinsky.ru.
+i1.ytimg.com.
+mccaffetyelectric.com.
+somosnicas.net.
+2.89.177.83.in-addr.arpa.
+a03.t26.net.
+a.root-servers.net.
+static.ak.fbcdn.net.
+profile.ak.fbcdn.net.
+www.a9euros.com.
+apnmedia.ask.com.
+mysoul.com.au.
+www.spiegel.tv.
+www.adultdreamlinks.com.
+www.mandco.com.
+a.root-servers.net.
+www.lobosoft.es.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+a.root-servers.net.
+inbound.cancrate.com.netsolmail.net.
+ymlp310.net.
+idsa.org.s7b2.psmtp.com.
+a.root-servers.net.
+roadplanet.ru.
+clients1.google.com.mx.
+jazzguitar.com.
+mejormevoy.com.
+apps.facebook.com.
+rblns81.mailshell.net.
+photos-h.ak.fbcdn.net.
+45.74.95.201.in-addr.arpa.
+marbel.sp.ru.
+ridproject.ru.
+www.facebook.com.
+edge.quantserve.com.
+vefire.ru.
+mail.margoliscapital.com.
+a.root-servers.net.
+188.39.49.186.in-addr.arpa.
+fxfeeds.mozilla.com.
+www.devilly.org.
+photos-a.ak.fbcdn.net.
+204.37.127.200.in-addr.arpa.
+11.66.201.71.in-addr.arpa.
+cdn.applifier.com.
+a.root-servers.net.
+lolnewera.forumclan.net.
+checkip.dyndns.org.
+40.12.254.98.in-addr.arpa.
+external.ak.fbcdn.net.
+www.facebook.com.
+iepwbpb4a.87tf.
+profile.ak.fbcdn.net.
+a.root-servers.net.
+totalcmd.pl.
+crwscdn8.appspot.com.
+41.75.154.189.in-addr.arpa.
+bart25s-paintjobfabrik.blogspot.com.
+profile.ak.fbcdn.net.
+third-rate.com.
+pro-activesolutions.net.
+hi-in.facebook.com.
+gulfcoastfibres.com.
+alliegiance.tv.
+rs505dt.rapidshare.com.
+grudniowo.soup.io.
+cch-lis.com.
+mi-medianaranja.blogspot.com.
+content.yieldmanager.edgesuite.net.
+kislorod-nn.ru.
+a-0.19-21099001.9090083.1518.19d3.3ea1.410.0.h4g5975dfhvrdrzlmhdmk2rzwv.avqs.mcafee.com.
+26.147.218.2.in-addr.arpa.
+5.58.106.189.in-addr.arpa.
+freshdailyblog.blogspot.com.
+seal.thawte.com.
+developers.facebook.com.
+www.lasabrosita.fm.
+cdn1.predictad.com.
+www.cmcmedicalgroup.es.
+creative.ak.fbcdn.net.
+www.proverbia.net.
+ad.doubleclick.net.
+25.media.tumblr.com.
+lightenupradio.com.
+blog.farmville.com.
+_435_96_3.
+cis.netmng.com.
+147.92.122.200.in-addr.arpa.
+173.32.146.187.in-addr.arpa.
+layouts.ru.
+pqdgvyjqjk.com.
+www.miletra.net.
+87.103.188.186.in-addr.arpa.
+c-0.19-2309c481.30483.1518.19d4.2f28.10.0.5ej8v54t12timlrc9ibsua66di.avqs.mcafee.com.
+about.tagged.com.
+a.root-servers.net.
+ewatches.com.
+facebook.conduitapps.com.
+162.5.195.187.in-addr.arpa.
+a749.g.akamai.net.
+gfx4.hotmail.com.
+plus.google.com.
+static.ak.fbcdn.net.
+www.youtube.com.
+photos-c.ak.fbcdn.net.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+a.root-servers.net.
+cload.com.
+m1.joymii.com.
+i1.ytimg.com.
+ib.adnxs.com.
+menuaingles.blogspot.com.
+external.ak.fbcdn.net.
+photos-e.ak.fbcdn.net.
+209.151.1.190.in-addr.arpa.
+rtm.ebaystatic.com.
+mx.msn.recepedia.com.
+aloe-a.net.ru.
+104.40.203.190.in-addr.arpa.
+www.cpc.cl.
+humor.orange.es.
+m.adnxs.com.
+229.156.148.92.in-addr.arpa.
+19.111.39.190.in-addr.arpa.
+photos-c.ak.fbcdn.net.
+www.faceb.
+a.root-servers.net.
+www.keygens.biz.
+clients1.google.com.
+wp.me.
+28.191.231.190.in-addr.arpa.
+irc.kelebekmafia.com.
+vlarock.ru.
+hi-in.facebook.com.
+a1404.w41.akamai.net.
+c0013989.ssl.cf1.rackcdn.com.
+www.google.com.
+static.ak.fbcdn.net.
+puffballsunited.newgrounds.com.
+_185_69_9.
+tobolsk.info.
+www.reachoutmichigan.org.
+developers.facebook.com.
+ff.media.v4.skyrock.net.
+sp.cwfservice.net.
+www.zenitalk.com.
+hjltxrqnvupgm.com.
+svod.espn.go.com.
+websearch.ask.com.
+117.218.8.78.in-addr.arpa.
+a.root-servers.net.
+hgddgbmbtvns.yi.org.
+ohsheglows.lightbox.com.
+connect.facebook.net.
+155.37.150.79.in-addr.arpa.
+the-sims-2.en.malavida.com.
+cmd-law.com.s9b1.psmtp.com.
+petroffbank.ru.
+225.55.46.189.in-addr.arpa.
+m.addthisedge.com.
+www.google.com.
+99.64.180.88.in-addr.arpa.
+ad.doubleclick.net.
+a3.sphotos.ak.fbcdn.net.
+0-jh-w.channel.facebook.com.
+static.yooco.de.
+graph.facebook.com.
+qtbuilders.com.
+www.letsdeal.no.
+bluewin.ch.
+pheedo-rdr.msnbc.msn.com.
+derek.netpivotal.com.
+186.82.190.71.in-addr.arpa.
+www.dlhonline.co.uk.
+lkckclcklii1i.com.home.
+outlookcbts.enterprisenet.org.
+90.72.26.190.in-addr.arpa.
+support.google.com.
+crl.microsoft.com.
+www.vibop.com.
+www.google.com.
+au.download.windowsupdate.com.
+135.245.158.200.in-addr.arpa.
+www.pgm-class.org.
+doc-10-80-docsviewer.googleusercontent.com.
+72.198.171.201.in-addr.arpa.
+a.root-servers.net.
+g.live.com.
+apps.facebook.com.
+www.bunnies4money.com.
+a.root-servers.net.
+216.67.100.190.in-addr.arpa.
+developers.facebook.com.
+qglcufhn7.b47z0d3o.
+profile.ak.fbcdn.net.
+baseball.cbssports.com.
+es.answers.yahoo.com.
+a5.sphotos.ak.fbcdn.net.
+mx0.day.org.
+dolsenco.com.inbound15.mxlogic.net.
+thumbs3.ebaystatic.com.
+www.googleadservices.com.
+www.google-analytics.com.
+brewich.com.
+imagesperiodicook.s3.amazonaws.com.
+247.91.27.190.in-addr.arpa.
+csi.gstatic.com.
+i324.photobucket.com.
+209.130.46.189.in-addr.arpa.
+a.root-servers.net.
+profile.ak.fbcdn.net.
+18.128.3.211.in-addr.arpa.
+87.125.34.189.in-addr.arpa.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+www.laredoute.de.
+bucks.edu.s9a2.psmtp.com.
+secure.shared.live.com.
+ksn2-12.kaspersky-labs.com.
+djesibonajeb.com.
+checkip.dyndns.com.
+russian-business.ru.
+smtp.hoffmaster.com.
+holichaxor.com.
+www.googleadservices.com.
+mail.thau.co.uk.
+www.paranormal-fr.net.
+ksn2-12.kaspersky-labs.com.
+ocsp.digicert.com.
+realdatamanagement.com.
+zynga1-a.akamaihd.net.
+skywaynews.net.
+redkid.net.
+commentarymagazine.us2.list-manage.com.
+139.253.213.83.in-addr.arpa.
+hotsms.ru.
+arriesgo.wordpress.com.
+ksn2-12.kaspersky-labs.com.
+a.root-servers.net.
+pagead2.googlesyndication.com.
+a.root-servers.net.
+134.84.216.217.in-addr.arpa.
+a.root-servers.net.
+a7.sphotos.ak.fbcdn.net.
+connect.facebook.net.
+girl.kizifriv.com.
+unitarius.hu.
+d2059932.instant.xoom.it.
+westonlogistics.com.
+api.facebook.com.
+a8.sphotos.ak.fbcdn.net.
+mail.burson-weathers.com.
+www.ingilizcecin.net.
+www.eclipstore.com.
+190.120.221.95.in-addr.arpa.
+217.72.178.190.in-addr.arpa.
+www.sqm.microsoft.com.
+85.135.171.77.in-addr.arpa.
+plus.google.com.
+client-software.real.com.
+www.googletagservices.com.
+youtu.be.
+168.19.168.192.in-addr.arpa.
+apis.google.com.
+blog.analytics.tapulous.com.
+store.yossawat.com.
+nwland.ru.
+anaphraseus.sourceforge.net.
+profile.ak.fbcdn.net.
+antal-int.com.
+r._dns-sd._udp.0.129.37.10.in-addr.arpa.
+external.ak.fbcdn.net.
+www.locusmicrowave.com.
+20minutos.feedsportal.com.
+34.219.44.200.in-addr.arpa.
+a7.sphotos.ak.fbcdn.net.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+www.france24.com.
+160.66.153.186.in-addr.arpa.
+platform.ak.fbcdn.net.
+dnl-01.geo.kaspersky.com.
+serv01.colo.owned.hu.
+d2090733.xoom.it.
+empresas.mundo-r.com.
+107.170.113.79.in-addr.arpa.
+jackdanielsmotors.com.
+encrypted-tbn0.google.com.
+b._dns-sd._udp.0.1.168.192.in-addr.arpa.
+206.116.155.81.in-addr.arpa.
+budgetresale.com.
+static.ak.fbcdn.net.
+andrew-mcculloch.co.uk.
+140.235.195.62.in-addr.arpa.
+ja.y8.com.
+cainet.com.br.
+thenetherworks.com.
+crl.globalsign.net.
+game3a.com.
+eth0.
+google.com.
+www.4cdg.com.
+diarioaxaca.com.
+25.93.62.61.in-addr.arpa.
+12.20.0.10.in-addr.arpa.
+a7.sphotos.ak.fbcdn.net.
+connect.facebook.net.
+www.biotherm.co.uk.
+32.39.169.68.in-addr.arpa.
+www.aljazeera.net.
+a.root-servers.net.
+metaline.de.
+static.ak.fbcdn.net.
+pkids.files.wordpress.com.
+167.39.168.192.in-addr.arpa.
+connect.facebook.net.
+db._dns-sd._udp.0.1.168.192.in-addr.arpa.
+cdn1.widdit.com.
+cf.addthis.com.
+www.sugudeli.jp.
+p49-buy.itunes.apple.com.
+www.tccandler.com.
+www.loveisdashit.com.
+toolbar.thepiratebay.se.
+a.root-servers.net.
+scribe.twitter.com.
+mailout.burlington-nj.net.
+www.ivgstores.com.
+www.turbogears.org.
+photos-g.ak.fbcdn.net.
+sp.cwfservice.net.
+microlinear.com.
+a.root-servers.net.
+a.root-servers.net.
+cdn.turn.com.
+150.223.142.187.in-addr.arpa.
+pixel.quantserve.com.
+154.81.173.190.in-addr.arpa.
+www.google.com.
+webcache.googleusercontent.com.
+smtp.crossconnectcentral.com.
+camilocartagena.com.
+microtekmed.com.
+gic-it.de.
+59.39.251.180.in-addr.arpa.
+static.ak.fbcdn.net.
+www.miescolarium.com.
+ngfarah.com.au.
+weather.service.msn.com.
+edge.quantserve.com.
+nccpr.p2p.baofeng.net.
+d24w6bsrhbeh9d.cloudfront.net.
+holessence.wordpress.com.
+servicios.prodigy.msn.com.
+a524.g.akamai.net.
+photos-g.ak.fbcdn.net.
+relay.quorum.ru.
+1.0.0.127.dnsbugtest.1.0.0.127.in-addr.arpa.
+evsecure-ocsp.verisign.com.
+mail.cyberquest.com.
+mobile.myspace.com.
+www.facebook.com.
+208.244.134.187.in-addr.arpa.
+creative.ak.fbcdn.net.
+i3.ytimg.com.
+googleads.g.doubleclick.net.
+api.facebook.com.
+yourfavoriterealtors.com.
+es.nntp2http.com.
+a.root-servers.net.
+a.root-servers.net.
+photos-c.ak.fbcdn.net.
+colonialkc.org.2.0001.arsmtp.com.
+223.135.192.180.in-addr.arpa.
+www.google-analytics.com.
+dnl-01.geo.kaspersky.com.
+www.jugosylicuados.com.
+frankcooney.com.
+mrmelkwintergames.hyper.no.
+themes.belchfire.net.
+a.root-servers.net.
+www.google-analytics.com.
+lucy.corp.netopia.com.
+sinaman.com.
+googleads.g.doubleclick.net.
+dns.msftncsi.com.
+www.archive.org.
+www.todaycal.com.
+a.root-servers.net.
+gcserevision101.wordpress.com.
+fexobkn.es.tl.
+oldmdgirl.blogspot.com.
+59.205.11.189.in-addr.arpa.
+16.209.70.166.in-addr.arpa.
+www.facebook.com.
+goo.gl.
+armmf.adobe.com.
+espanol.orlando-florida.net.
+www.todotorrents.com.
+b.scorecardresearch.com.
+a.root-servers.net.
+53.194.22.186.in-addr.arpa.
+ilogic.ru.
+pjrwadulmbvc.info.
+news.google.com.mx.
+mail.renneberg.com.
+download.iolo.net.
+radio.blackplanet.com.
+smtp.blink.ca.
+178.116.173.190.in-addr.arpa.
+itbriefing.net.
+www.facebook.com.
+mail.internationaldg.com.
+www.update.microsoft.com.
+www.nataliaoreiro.com.
+vanbortel.com.inbound10.mxlogicmx.net.
+www.ecs.gov.bd.
+mail.aai-office.com.
+i3.imageban.ru.
+mail.hooddistribution.com.
+class.ee.iastate.edu.
+esteparticular.wordpress.com.
+mailgate.learningderby.net.
+dns.msftncsi.com.
+a2.sphotos.ak.fbcdn.net.
+www.romeoburner.com.
+www.facebook.com.
+bjornfree.com.
+creative.ak.fbcdn.net.
+apple.com.
+update.avg.com.
+a8.sphotos.ak.fbcdn.net.
+i1.ytimg.com.
+time.nist.gov.
+131.61.83.160.in-addr.arpa.
+developers.facebook.com.
+entertainment.wikia.com.
+faceboock.com.
+a1.da1.akamai.net.
+shtihmass.ru.
+wsteele.com.s8a2.psmtp.com.
+168.82.85.78.in-addr.arpa.
+w.sharethis.com.
+i4.ytimg.com.
+cmap.am.ace.advertising.com.
+www.rankingshq.com.
+www.facebook.com.
+cbuk.112.2o7.net.
+101.7.168.192.in-addr.arpa.
+117.250.215.108.in-addr.arpa.
+hitstatus.com.
+www.asociacionportimujer.org.
+router.bittorrent.com.
+dns.msftncsi.com.
+www.tuenti.com.
+byfiles.storage.msn.com.
+twitter.com.
+www.galleries.teenemery.com.
+zbar.zynga.com.
+moodyvalleyins.com.2.arsmtp.com.
+the-best-tour.com.
+www.carpediem-services.com.
+americanmicrosemi.com.
+141.171.49.211.in-addr.arpa.
+a.root-servers.net.
+xl.topstat.com.
+dplus.net.
+ad.adnetwork.net.
+www.izle.ilahisevenler.com.
+a.root-servers.net.
+www.tdt-latinoamerica.tv.
+www.google.com.
+www.isg-apple.com.akadns.net.
+liveonletterman.radio.com.
+170.206.178.186.in-addr.arpa.
+secure.vaginalcumshots.com.
+ifroggy.com.
+afrhomeloans.com.s8a2.psmtp.com.
+pagead2.googlesyndication.com.
+lacasadeshiva.blogspot.com.
+pixel.facebook.com.
+www.development.fighthubtv.com.
+a.root-servers.net.
+166.14.224.189.in-addr.arpa.
+sn105w.snt105.mail.live.com.
+118.164.6.200.in-addr.arpa.
+_246_96_4.
+www.gaga101.nl.ae.
+dns.msftncsi.com.
+a6.sphotos.ak.fbcdn.net.
+94.79.3.27.in-addr.arpa.
+.
+128.220.45.173.in-addr.arpa.
+www.allipodtouchwallpapers.com.
+es-es.facebook.com.
+crl.globalsign.net.
+bs.serving-sys.com.
+www.google-analytics.com.
+www.themasterteacher.tv.
+optimized-by.rubiconproject.com.
+ad-apac.doubleclick.net.
+122.93.116.121.in-addr.arpa.
+comceptos.com.
+iguana-tango.com.
+tags.bluekai.com.
+voipb.sip.yahoo.com.
+_146_63_6.
+182.217.18.187.in-addr.arpa.
+www.gatewayworkshops.com.
+arribaelachancha.cl.
+static-0.farmville.com.
+m.addthisedge.com.
+www.youtube-mp3-download.com.
+rsup8.rising.com.cn.home.
+evt.adrcntr.com.
+www.reforma.com.
+127.42.82.200.in-addr.arpa.
+msn.com.
+0.gravatar.com.
+creative.ak.fbcdn.net.
+a.c-0.19-21094000.10033.1518.19b2.410a.400.9d.kw1163b1wmniwtu1r3flrs4f8q.avqs.mcafee.com.
+tattoodesignspictures.com.
+publicbt.ath.cx.
+imagenen1.247realmedia.com.
+de-de.facebook.com.
+graph.facebook.com.
+centrelab.com.
+mx.usa.net.
+animeytv.com.
+xdcnq7lq9.11qn.
+d15gt9gwxw5wu0.cloudfront.net.
+ads.yimg.com.
+a.root-servers.net.
+myweb2.search.yahoo.com.
+253.40.141.189.in-addr.arpa.
+mail.google.com.
+nfbkids.ca.
+api.twitter.com.
+a-0.19-21093008.5000083.1518.19d4.3ea1.410.0.2hhg9t58pwjl629vqnrvmpg4lb.avqs.mcafee.com.
+131.41.194.187.in-addr.arpa.
+dnl-01.geo.kaspersky.com.
+65.147.61.83.in-addr.arpa.
+a.root-servers.net.
+ns1-170.akam.net.
+saltel.net.
+17.254.208.74.zen.spamhaus.org.
+tas.orangeads.fr.
+ww.facebok.com.
+122.83.27.189.in-addr.arpa.
+googleads.g.doubleclick.net.
+pssaudio.com.
+85.218.226.168.in-addr.arpa.
+timesgrop.com.
+nip.net.ua.
+jaypark.net.
+ferens.net.
+crmassociatesinc.com.
+www.slashdot.com.
+sites.google.com.
+host30.ru.
+mail.capitolmarketing.com.
+wac.0c28.edgecastcdn.net.
+a.root-servers.net.
+m.facebook.com.
+jiuan.jiagoo.com.
+facebook-gadget.programas-gratis.net.
+youtu.be.
+feng.brujeriayhechizos.com.
+plusone.google.com.
+209.70.92.201.in-addr.arpa.
+profile.pics.ak.sonicocnt.com.
+_430_13_0.
+a2.sphotos.ak.fbcdn.net.
+oregon.students.k12.wi.us.
+ksn2.kaspersky-labs.com.
+140.138.134.190.in-addr.arpa.
+_240_07_9.
+v3it.com.
+www.alidaa-alwatania.ma.
+www.clicanoo.re.
+resolver2.wguard.ctmail.com.
+static.ak.fbcdn.net.
+profile.ak.fbcdn.net.
+neocounter.neoworx-blog-tools.net.
+_ldap._tcp.7648c4d1-51f9-4a61-bbe5-816892afb98a.domains._msdcs.im-2.net.
+www.beinghunted.com.
+43.155.158.189.in-addr.arpa.
+183.138.168.192.in-addr.arpa.
+irc.kelebekmafia.com.
+novelasdetv2.blogspot.com.
+ate.lacoctelera.net.
+170.204.177.190.in-addr.arpa.
+177.20.206.190.in-addr.arpa.
+www.grungi.com.
+mdawmdezmdaxmjaxmg.org.
+docinthemachine.com.
+www.blabbers.com.
+firewall.bccu.org.
+ds.serving-sys.com.
+hudson.org.
+tracker.bidder7.mookie1.com.
+69.29.75.187.in-addr.arpa.
+128.129.171.218.in-addr.arpa.
+time.windows.com.
+intranet.unep.org.
+images.hi5.com.
+adserving.cpxinteractive.com.
+95mb2mkmk.06yk.
+ftfp.net.
+media.ccomrcdn.com.
+smx10.ccc-c.ru.
+bspots.com.
+ng.
+www.google-analytics.com.
+google.com.
+18.171.173.187.in-addr.arpa.
+poseidon.dl.playstation.net.
+vw.
+twitter.com.
+download.windowsupdate.com.
+clickserv2.sitescout.com.
+m.bangbook.com.
+c.statcounter.com.
+fitwatch.blogspot.com.
+palpably.com.
+113.63.26.70.in-addr.arpa.
+p08-bookmarks.icloud.com.
+hygloceaf.39jl.
+nat240.convex.ru.
+38.109.50.186.in-addr.arpa.
+bing.com.
+db._dns-sd._udp.0.1.168.192.in-addr.arpa.
+ksn2.kaspersky-labs.com.
+dl.dropbox.com.
+blstb.msn.com.
+photos-e.ak.fbcdn.net.
+ksn2-12.kaspersky-labs.com.
+cic.co.th.
+gtamodreynosa.blogspot.com.
+www.oregonlive.com.
+molinasalinas.com.
+qst.com.pri-mx.smtproutes.com.
+37.75.106.186.in-addr.arpa.
+www.fpsalceda.com.
+mail.jino.ru.
+profile.ak.fbcdn.net.
+dc.logmein-gateway.com.
+mx.gameshop-international.com.
+a5.sphotos.ak.fbcdn.net.
+signin.ebay.com.
+90.99.229.190.in-addr.arpa.
+166.242.158.189.in-addr.arpa.
+js.myspacecdn.com.
+ocsp.thawte.com.
+www.ilfusion.com.
+email-dm.caroljones.com.
+mx.lynxdev.com.
+a.root-servers.net.
+textad.sexsearch.com.
+twitter.com.
+jers3.info.
+ns5.assembly.spb.ru.
+photos-a.ak.fbcdn.net.
+www.elacuario.es.
+122.28.200.98.in-addr.arpa.
+dev2.ru.
+creative.ak.fbcdn.net.
+carmelvets.com.
+www.ransen.com.
+updatekeepalive.mcafee.com.
+video.google.com.mx.
+de-de.facebook.com.
+125.106.220.189.in-addr.arpa.
+182.41.14.189.in-addr.arpa.
+a6.sphotos.ak.fbcdn.net.
+a.root-servers.net.
+canada.com.
+a5.sphotos.ak.fbcdn.net.
+68.238.245.190.in-addr.arpa.
+apps.facebook.com.
+www.movistar.com.co.
+bbcore.cloudapp.net.
+.
+colunas.criativa.globo.com.
+apps.facebook.com.
+limg1.imgsmail.ru.
+jnuvxfm19.61vk.
+53.2.134.187.in-addr.arpa.
+ann.over-blog.com.
+us.bc.yahoo.com.
+likpavlovsk.ru.
+gxcmnoaqhvfkyjd.theforgive.net.
+r49jgld21.34uc.
+www.blossgroup.com.
+107.250.48.190.in-addr.arpa.
+a.root-servers.net.
+img.nikeprice.com.
+sopsmtpin.shuion.com.cn.
+mail.moderntimes.gr.
+photos-f.ak.fbcdn.net.
+profile.ak.fbcdn.net.
+ru.iozcluster.com.
+ssl.gstatic.com.
+a7.sphotos.ak.fbcdn.net.
+www.picresize.com.
+22.1.168.192.in-addr.arpa.
+16036.diloconfrases.com.
+mail.isolofoam.com.
+a.root-servers.net.
+www.acorentacar.com.
+liveupdate.symantecliveupdate.com.
+paracozinhar.blogspot.com.
+222.147.34.201.in-addr.arpa.
+ovist.ru.
+lcbbqx.com.
+mail.amarchitx.com.
+mail.gandiagroup.com.
+photos-f.ak.fbcdn.net.
+www.trafficholder.com.
+c7.zedo.com.
+a6.sphotos.ak.fbcdn.net.
+newfbcover.com.
+130.254.107.200.in-addr.arpa.
+_ldap._tcp.
+www.10joke.com.
+hitman-blood-money.softonic.com.
+30.100.87.200.in-addr.arpa.
+www.mikemerritt.me.
+mobilemedianow.com.
+99.133.34.177.in-addr.arpa.
+163.133.159.189.in-addr.arpa.
+byfiles.storage.msn.com.
+mail.plateau.ru.
+85.163.52.174.in-addr.arpa.
+tap2-cdn.rubiconproject.com.
+corazones.100foros.com.
+accounts.google.com.
+_540_03_3.
+www.crunchbase.com.
+213.141.226.190.in-addr.arpa.
+194.25.185.91.in-addr.arpa.
+mail2.duferdofin.it.
+check6.facebook.com.
+ad.doubleclick.net.
+juegosbeta.net.
+ntp.glb.nist.gov.
+evsecure-crl.verisign.com.
+www.facebook.com.
+levittandsons.com.
+video.cnbc.com.
+.
+229.165.171.201.in-addr.arpa.
+s.clicktale.net.
+www.facebook.com.
+erichluna.files.wordpress.com.
+42.187.68.195.in-addr.arpa.
+api.twitter.com.
+107.1.168.192.in-addr.arpa.
+www-cctld.l.google.com.
+h.live.com.
+r._dns-sd._udp.0.97.168.192.in-addr.arpa.
+a3.sphotos.ak.fbcdn.net.
+fc.pickerington.k12.oh.us.
+66.177.229.201.in-addr.arpa.
+s-external.ak.fbcdn.net.
+mx.msn.recepedia.com.
+photos-e.ak.fbcdn.net.
+b._dns-sd._udp.0.0.168.192.in-addr.arpa.
+ads.lfstmedia.com.
+140.156.166.190.in-addr.arpa.
+a.root-servers.net.
+sites.google.com.
+www.marchpr.com.
+www.caminandoensantidad.com.
+a4.sphotos.ak.fbcdn.net.
+www.landbou.com.
+ladies.ivwbox.de.
+www.facebook.com.
+www.microsoft.com.
+astroyogisays.wordpress.com.
+www.unifor.it.
+profile.ak.fbcdn.net.
+relay.voice.edge.messenger.live.com.
+www.youtube.com.
+a.root-servers.net.
+:y9zbn78:.a60b4f0b.
+www.holgablog.com.
+10.100.210.64.in-addr.arpa.
+google.com.
+www.addthis.com.
+www.pakmailveracruz.com.
+xslt.alexa.com.
+ins00002.nycomed.local.
+emailbizz.com.
+solemovement.com.
+onetel.net.
+tracker.ex.ua.
+43.200.26.188.in-addr.arpa.
+desipride.co.uk.
+www.schoolworld.com.
+ad-g.doubleclick.net.
+4.69.158.200.in-addr.arpa.
+darkmail.ru.
+a.root-servers.net.
+www.artificialgallery.co.uk.
+safebrowsing.clients.google.com.
+mx.scitz.com.
+200.236.126.199.in-addr.arpa.
+49.250.22.190.in-addr.arpa.
+static.ak.fbcdn.net.
+euro.mediotiempo.com.
+profile.ak.fbcdn.net.
+a1856.w5.akamai.net.
+i.ytimg.com.
+2.218.227.213.in-addr.arpa.
+www.amateurwebcamsexlive.com.
+cdn-w.fapdu.com.
+espanol.galerias.autocosmos.yahoo.net.
+a5.sphotos.ak.fbcdn.net.
+ieonlinews.microsoft.com.
+init-p01md.apple.com.
+pravitelstvokbr.ru.
+179.36.186.201.in-addr.arpa.
+adserver.adtech.de.
+lineage2.plaync.jp.
+www.polarbearmusic.com.
+evhs.net.s10b2.psmtp.com.
+static.ak.fbcdn.net.
+178.156.245.190.in-addr.arpa.
+g.msn.com.
+www.wildaboutmovies.com.
+79.10.61.186.in-addr.arpa.
+a1.sphotos.ak.fbcdn.net.
+208.237.252.72.in-addr.arpa.
+mtalk.google.com.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+a5.sphotos.ak.fbcdn.net.
+googleads.g.doubleclick.net.
+alerts.conduit-services.com.
+aswlingerie.com.
+www.facebook.com.
+osce10-5-en.url.trendmicro.com.
+javadl-esd.sun.com.
+17.159.122.186.in-addr.arpa.
+carib.lnet.fr.
+col.stj.s-msn.com.
+search.twitter.com.
+www.abcmanualidades.com.
+meti.com.
+e-deliver.com.
+1.0.0.127.dnsbugtest.1.0.0.127.in-addr.arpa.
+philosophy.hertford.ox.ac.uk.
+ssl.gstatic.com.
+bestmodelgirls.com.
+insidehighered.com.
+ad.yieldmanager.com.
+amdbgn5n4.x51v7y4s.
+static.ak.fbcdn.net.
+www.ozgurdunyam.com.
+1.gravatar.com.
+www.facebook.com.
+ec2-184-73-21-146.zumodrive.com.
+82.30.237.189.in-addr.arpa.
+quitcount.sourceforge.net.
+thankyounurses.com.s10a2.psmtp.com.
+dnfdl.qq.com.
+twitter.com.
+omundoasiatico.wordpress.com.
+a.root-servers.net.
+nic99:opq.y86y4h6t.
+a6.sphotos.ak.fbcdn.net.
+twcble.com.
+r._dns-sd._udp.lan.
+photos-g.ak.fbcdn.net.
+www.footballtip.co.uk.
+johnsoncountytx.org.s5a2.psmtp.com.
+38.232.86.74.in-addr.arpa.
+mail.autonizh.nnov.ru.
+rssbarcode.com.
+www.fabulous.com.
+im61.vk.com.
+time.nist.gov.
+wvc.net.
+img4.drawn-incest.net.
+model850.deviantart.com.
+178.126.247.69.in-addr.arpa.
+obeloer.de.
+169.147.174.190.in-addr.arpa.
+mx.youtube.com.
+www.slona.net.
+browsersync.google.com.
+google.com.
+www.facebook.com.
+127.129.79.190.in-addr.arpa.
+webcache.googleusercontent.com.
+api.webrep.avast.com.
+mail.pressdisplay.com.
+skyfallen.com.
+60.159.35.187.in-addr.arpa.
+alvago.ru.
+93.199.116.194.in-addr.arpa.
+b754:eygv.76jj.
+ville-argenteuil.fr.
+www.uhcretiree.com.
+15cb25h1.aime7.eu.
+brand.celio.com.
+billing.sharo4ka.ru.
+77.196.40.177.in-addr.arpa.
+asp-8.reflexion.net.
+en.wikipedia.org.
+www.tuchiste.com.
+0-244.channel.facebook.com.
+a.root-servers.net.
+photos-g.ak.fbcdn.net.
+www.google-analytics.com.
+www.legislation.hmso.gov.uk.
+estky.com.
+api.bizographics.com.
+_514_96_1.
+de-de.facebook.com.
+static.ak.facebook.com.
+a.root-servers.net.
+255.80.54.208.in-addr.arpa.
+wiredarchives.disqus.com.
+assets.hostedtube.com.
+www.google-analytics.com.
+tubisuteria.com.ve.
+external.ak.fbcdn.net.
+grayburn.blogspot.com.
+ax.su.itunes.apple.com.
+row.bc.yahoo.com.
+100.21.228.189.in-addr.arpa.
+www.l.google.com.
+pixel.facebook.com.
+g.ceipmsn.com.
+mozilla.yongbok.net.
+a2.sphotos.ak.fbcdn.net.
+platform.twitter.com.
+data.flurry.com.
+apple.com.
+mra1.mail.ru.
+137.79.218.186.in-addr.arpa.
+distilleryimage0.s3.amazonaws.com.
+ocsp.verisign.com.
+inbound.mstgllc.com.netsolmail.net.
+edge-media1.snooth.com.
+129.211.91.195.in-addr.arpa.
+cantaalsenor.com.
+bing.com.
+53.151.24.82.in-addr.arpa.
+static-0.farmville.zgncdn.com.
+logs.sync.prodenv4.mysoluto.com.
+time.nist.gov.
+www.idea.gob.mx.
+l2.zedo.com.
+redragonairsoft.50.forumer.com.
+_860_63_2.
+198.49.23.186.in-addr.arpa.
+a.root-servers.net.
+s-static.ak.facebook.com.
+www.mundoauxilio.com.ar.
+209.129.176.190.in-addr.arpa.
+47-courier.push.apple.com.
+s.ytimg.com.
+agng78sagdfdkjdtwa716.com.
+b3.mookie1.com.
+_369_86_0.
+69.175.178.190.in-addr.arpa.
+www.sx.xinhuanet.com.
+a.rad.msn.com.
+www.downloadhelper.net.
+85.231.89.186.in-addr.arpa.
+dcpq6oz4b.l15w5x9z.
+neetguias.com.
+static-cdn2.ustream.tv.
+www.google-analytics.com.
+a.root-servers.net.
+barbershopconnect.com.
+vsantivirus.com.
+t.co.
+bwp.download.com.
+157.255.247.190.in-addr.arpa.
+150.23.122.186.in-addr.arpa.
+cdn.loading321.com.
+download.windowsupdate.com.
+foros.3dgames.com.ar.
+aperture.maccreate.com.
+p3v.ru.
+googleads.g.doubleclick.net.
+ksn7-12.kaspersky-labs.com.
+head.rd.na-gmbh.net.
+a.root-servers.net.
+conduit.anybodyoutthere.com.
+109.214.5.217.in-addr.arpa.
+4wg9s:ggi.61rl.
+a1725.l.akamai.net.
+i3.ytimg.com.
+altfarm.mediaplex.com.
+59.36.48.186.in-addr.arpa.
+mail.sw15.com.
+amazonm-346.vo.llnwd.net.
+salespages.s3.amazonaws.com.
+4ebec7j26.j35y9q2p.
+brocheszepequena.blogspot.com.
+60.89.88.186.in-addr.arpa.
+s1-powerpoint.vo.msecnd.net.
+d15gt9gwxw5wu0.cloudfront.net.
+www.ducati.it.
+www.jeremyskinner.co.uk.
+pics-4.gaybearsvideo.com.
+gwave.com.
+inbound.matchettandward.com.netsolmail.net.
+encrypted-tbn3.google.com.
+180.123.101.190.in-addr.arpa.
+developers.facebook.com.
+ejabat.google.com.
+775t3k5wd.z31l8t1x.
+127.17.155.189.in-addr.arpa.
+120.136.159.187.in-addr.arpa.
+us.bc.yahoo.com.
+www.gstatic.com.
+32.26.94.186.in-addr.arpa.
+58.114.92.186.in-addr.arpa.
+a8.sphotos.ak.fbcdn.net.
+pixel.facebook.com.
+vp.sip.messenger.msn.com.
+f5uj5ae3n.y25k0v8m.
+y.fs8-88a.video.ckcdn.com.
+content.yieldmanager.edgesuite.net.
+i26.fastpic.ru.
+browse.deviantart.com.
+125.156.234.41.in-addr.arpa.
+www.megadosya.net.
+salon-pantera.ru.
+57.193.181.189.in-addr.arpa.
+img1.blogblog.com.
+www.corralboots.com.
+215.55.17.95.in-addr.arpa.
+leanintree.com.inbound30.mxlogicmx.net.
+s7.addthis.com.
+www.gop.com.
+social.bidsystem.com.
+www.spainmoviles.com.
+a.root-servers.net.
+www.condesadf.com.
+chart.shopping.daum.net.
+ec.atdmt.com.
+downloadcatolico.blogspot.com.
+34.139.87.203.in-addr.arpa.
+dodo.com.au.
+63.197.50.190.in-addr.arpa.
+ardownload.adobe.com.
+clients2.google.com.
+mail2.baruta.net.
+jeffingermany.com.
+ecoclima.cl.
+analytics.live.com.
+ssl.gstatic.com.
+62.252.153.200.in-addr.arpa.
+icanhascheezburger.com.
+godsremedy.com.
+www.google.com.
+sc.cuevana.tv.
+vitamin.utk.ru.
+www.xatakaciencia.com.
+liveupdate.symantecliveupdate.com.
+profile.ak.fbcdn.net.
+a-0.19-2309d081.c030083.1518.19cd.3ea1.410.0.d5g4l32d6jgjp7wsn6vrk57hvq.avqs.mcafee.com.
+toolbarqueries.google.com.
+retracker.kld.ru.
+support.google.com.
+www.showsiteinfo.appspot.com.
+www.chillingeffects.org.
+p05-caldav.icloud.com.
+a.root-servers.net.
+dovstrechy.ru.
+stfansub.chatango.com.
+i3.ytimg.com.
+img100.xvideos.com.
+bat.wbusiness.fr.
+a.root-servers.net.
+www.thetrafficstat.net.lan.
+ksn2-12.kaspersky-labs.com.
+168.89.50.99.in-addr.arpa.
+um.simpli.fi.
+www.clansta.com.
+zicrizabdi.com.
+mystichealingart.blogspot.com.
+google.com.
+dnl-01.geo.kaspersky.com.
+google.com.
+assist.zoho.com.
+photos-d.ak.fbcdn.net.
+sp.cwfservice.net.
+_390_33_8.
+pr-static.tnaflix.com.
+e4344.g.akamaiedge.net.
+58.231.224.190.in-addr.arpa.
+www.google.com.
+ms3.verticalscreen.com.
+www.ebcwebstore.com.
+iloveatom.wikispaces.com.
+www.decadeofaction.org.
+www.google.com.
+en-us.fxfeeds.mozilla.com.
+www.youtube.com.
+www.hairypussiessex.com.
+bit.ly.
+shop.ebay.com.
+www.google.com.
+www.facebook.com.
+a5.sphotos.ak.fbcdn.net.
+hotmail.com.
+accounts.google.com.
+lccmail.com.
+api.facebook.com.
+www.ticketmaster.com.
+140.72.208.186.in-addr.arpa.
+cdn-1.nflximg.com.
+a.root-servers.net.
+cm.g.doubleclick.net.
+es.ask.com.
+ustream.vo.llnwd.net.
+www.googleadservices.com.
+www.portantos.es.
+phobos.apple.com.
+v7.cache3.c.youtube.com.
+bbcore.cloudapp.net.
+download.akvis.com.
+gibbins18.fsnet.co.uk.
+0-ig-w.channel.facebook.com.
+tracker9.bol.bg.
+jpost.ru.
+www.mobilemammoth.com.
+rcp.na.blackberry.com.
+www.costume-designer.co.uk.
+das2.ru.
+tiempoderugby.com.
+30.166.214.201.in-addr.arpa.
+dixis.spb.ru.
+pagead2.googlesyndication.com.
+64.162.4.65.in-addr.arpa.
+253.105.121.187.in-addr.arpa.
+rv.ginyas.com.
+api.twitter.com.
+safebrowsing-cache.google.com.
+gojane.us-dc1-edit.store.yahoo.net.
+www.ver-pelis.net.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+dsn7.d.skype.net.
+www.ontariotrackers.com.
+27.37.48.49.in-addr.arpa.
+gdata.youtube.com.
+rokita.zigzag.pl.
+www.update.microsoft.com.
+www.terra.com.pe.
+searchclient.live.net.
+www.acee.cl.
+profile.ak.fbcdn.net.
+btinternet.com.
+get.adobe.com.
+225.171.13.88.in-addr.arpa.
+tools.google.com.
+86.117.22.190.in-addr.arpa.
+.
+cdn-8.pics.hardsextubepremium.com.
+reuben.org.
+dns.msftncsi.com.
+wahm-masters.sitesell.com.
+12.170.215.84.in-addr.arpa.
+connect.facebook.net.
+www.risesecurity.org.
+173.202.232.190.in-addr.arpa.
+platform.ak.fbcdn.net.
+iphone-ld.apple.com.
+beonline.com.ph.
+www.facebook.com.
+47.82.176.186.in-addr.arpa.
+leifpodhajsky.com.
+twitter.com.
+www.xuldev.org.
+tradefx.advertserve.com.
+voip.gtdmanquehue.com.
+inbound.jimjenningsarchitecture.com.netsolmail.net.
+apps.facebook.com.
+teredo.ipv6.microsoft.com.
+photos-e.ak.fbcdn.net.
+c.atdmt.com.
+mail.google.com.
+a2.twimg.com.
+194.134.95.201.in-addr.arpa.
+.
+byfiles.storage.msn.com.
+a4.sphotos.ak.fbcdn.net.
+ads.gamesbannernet.com.
+login.live.com.
+plus.google.com.
+www.sun-sentinel.com.
+ad-g.doubleclick.net.
+www.google.com.mx.
+creative.ak.fbcdn.net.
+www.adobe.com.
+riptight.de.
+download.windowsupdate.com.
+4.67.252.201.in-addr.arpa.
+urs.microsoft.com.
+www.coverphotos.ne.
+planetforlife.com.
+cs.wikinews.org.
+pegas.pgta.ru.
+www.azgallerie.com.
+pixel.facebook.com.
+227.94.141.201.in-addr.arpa.
+a.root-servers.net.
+integsystemscorp.com.
+7xxdudax017.org.
+yonkerracing.com.
+deptof.com.
+cache.pack.google.com.
+guardianpm.com.inbound45.mxlogicmx.net.
+www.20minutos.es.
+m688.photobucket.com.
+www.cincodias.com.
+addons.mozilla.org.
+static.ak.fbcdn.net.
+computerwoche.de.
+www3.l.google.com.
+rfi-global.com.
+mail.bmsystem.ru.
+121.158.1.201.in-addr.arpa.
+mail.whitepinecopper.com.
+158.154.30.50.in-addr.arpa.
+mail.isladom.com.do.
+3.170.107.186.in-addr.arpa.
+www.gestiopolis.com.
+5h458z:9q.34nn.
+mail.rwt.com.
+qvvz72iwb.r32f3e0u.
+b._dns-sd._udp.0.16.168.192.in-addr.arpa.
+feeds.feedburner.com.
+voidumonde.com.
+p05-keyvalueservice.icloud.com.
+72.36.215.95.in-addr.arpa.
+trendmicro-g.georedirector.akadns.net.
+col.stc.s-msn.com.
+as.usnuc.com.
+a1.sphotos.ak.fbcdn.net.
+95.244.71.219.in-addr.arpa.
+toolsworld.zzl.org.
+73.56.170.189.in-addr.arpa.
+56.55.131.187.in-addr.arpa.
+86.66.123.189.in-addr.arpa.
+olmue.com.
+154.128.51.190.in-addr.arpa.
+www.google.com.
+95.86.45.12.in-addr.arpa.
+www.17-s.info.
+banner.casinolasvegas.com.
+mail2.gocial.com.
+xalapa.infored.com.mx.
+kjia5mie3.05yq.
+www.fontanka.ru.
+i-dressup.com.
+www.google.com.
+242.50.167.187.in-addr.arpa.
+coupons.houstonpress.com.
+_355_42_7.
+www.weather.com.
+192.123.87.67.in-addr.arpa.
+227.240.143.175.in-addr.arpa.
+www.bingobase.com.
+139.23.85.190.in-addr.arpa.
+dnl-01.geo.kaspersky.com.
+40.215.123.201.in-addr.arpa.
+151.143.215.189.in-addr.arpa.
+19.148.74.187.in-addr.arpa.
+roofing.ms.
+music.egexa.com.
+zaring.com.
+zmsg.mobi.
+a1.sphotos.ak.fbcdn.net.
+ro-botica.com.
+onlywarez.info.
+i2.itc.cn.
+www.googleadservices.com.
+i3.ytimg.com.
+www.google.com.
+mail65.ixwebhosting.com.
+64.200.141.63.in-addr.arpa.
+db2.stc.s-msn.com.
+photos-e.ak.fbcdn.net.
+www.horrortheque.com.
+client94.dropbox.com.
+www.youtube.com.
+platform.ak.fbcdn.net.
+cltfile300.corp.kbr.com.beknet.us.
+graph.facebook.com.
+trackaphone.com.
+photos-h.ak.fbcdn.net.
+a1408.w43.akamai.net.
+cdn1.public.tube8.com.
+ionchran.msk.ru.
+s-static.ak.facebook.com.
+www.plrcodemine.com.
+31.80.19.190.in-addr.arpa.
+www.gstatic.com.
+www.hotmail.com.
+static.ak.fbcdn.net.
+033hotmail.com.
+www.ufovideos.ws.
+1109.xphonia.com.
+a.root-servers.net.
+ciaoshopes.122.2o7.net.
+www.jeasyui.com.
+johnsonlawia.com.
+pixel.facebook.com.
+www.speedbibleverse.com.
+ib.adnxs.com.
+83.162.41.177.in-addr.arpa.
+t3.gstatic.com.
+www.file4sharing.com.
+rcp.na.blackberry.com.
+profile.ak.fbcdn.net.
+www.freedomdebtrelief.com.
+www.thelogoloft.com.
+www.google-analytics.com.
+softkey.ru.
+137.43.110.201.in-addr.arpa.
+120.246.157.90.in-addr.arpa.
+239.32.178.190.in-addr.arpa.
+a3.sphotos.ak.fbcdn.net.
+bkg.bund.de.
+the-weather-channel.en.softonic.com.
+12.119.113.186.in-addr.arpa.
+code.google.com.
+www.bristolgroup.com.ar.
+fbcdn-sphotos-a.akamaihd.net.
+www.buttmachineboys.com.
+mail.mo-pca.org.
+go.microsoft.com.
+mail.sskom.su.
+ajax.googleapis.com.
+fbcdn-photos-a.akamaihd.net.
+_471_33_5.
+a.root-servers.net.
+m04.r64.nalog.ru.
+a7.sphotos.ak.fbcdn.net.
+media.fasthosts.co.uk.
+154.75.91.186.in-addr.arpa.
+www.themotoguide.com.
+razorfamilyfarms.com.
+a.root-servers.net.
+roswellgov.com.
+www.iwork.com.
+blst.msn.com.
+mail.bebisim.net.
+accounts.google.com.
+stage-shredded-status.com.
+pagead2.googlesyndication.com.
+3.17.66.177.in-addr.arpa.
+www.darty.com.
+qpkppwwxk.15qw.
+roadsideamerica.com.
+grandcoffee.ru.
+allkpop.co.
+rr.a.5d6d.com.
+groups.google.es.
+js.wlxrs.com.
+www.facebook.com.
+twitter.com.
+roller-dollz-scene-4.ss.ztod.com.
+accounts.google.com.
+www.kitchenremodelideas.com.
+www.apples4theteacher.com.
+a749.g.akamai.net.
+146.172.250.201.in-addr.arpa.
+desmotivaciones.es.
+b._dns-sd._udp.0.2.168.192.in-addr.arpa.
+sites.google.com.
+cheerleading.about.com.
+mail.thermospas.com.
+dnl-01.geo.kaspersky.com.
+www.emol.com.
+meta.wikimedia.org.
+205.119.240.46.in-addr.arpa.
+mscrl.microsoft.com.
+10.240.222.190.in-addr.arpa.
+a.root-servers.net.
+bank.imgdumpr.com.
+137.55.137.190.in-addr.arpa.
+mail.trak-music.com.
+photos-a.ak.fbcdn.net.
+www.gamespot.com.
+www.fielddayfestivals.com.
+mail.top-med.ru.
+teamhfa-com.mail.eo.outlook.com.
+proxy.org.
+s.ytimg.com.
+a.root-servers.net.
+ssl.gstatic.com.
+s0.2mdn.net.
+builderswholesale.com.
+ilead.itrack.it.
+173.61.70.77.in-addr.arpa.
+fbcdn-profile-a.akamaihd.net.
+safebrowsing-cache.google.com.
+dnl-01.geo.kaspersky.com.
+www.reikiindia.org.
+gci-prod-lb-743530114.us-east-1.elb.amazonaws.com.
+download.live.com.
+content.yieldmanager.edgesuite.net.
+www.iapqroo.org.mx.
+www.directoriowebdemexico.com.mx.
+darkecho.ru.
+crl.geotrust.com.
+57.104.153.187.in-addr.arpa.
+newsrss.bbc.co.uk.
+tkmnet.ru.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+www.facebook.com.
+234.4.241.81.in-addr.arpa.
+147.51.40.124.in-addr.arpa.
+wpad.phx-dc.dhl.com.
+www.videostias.net.
+www.bygraziela.com.
+ls2web.redmond.corp.microsoft.com.
+klipxtreme.com.
+www.erkdesigns.com.
+www.facebook.com.
+developers.facebook.com.
+gs-loc.apple.com.
+ad.media-servers.net.
+cc.ysu.edu.
+uiu:pfpp1.k90u2e0f.
+protonworld.com.
+cgi.ebay.com.
+ja.cnt.v.sina.com.cn.
+mx04.traviangames.com.
+mail-bk0-f53.google.com.
+photos-g.ak.fbcdn.net.
+safebrowsing.clients.google.com.
+a.root-servers.net.
+hi-in.facebook.com.
+toyotacredit.ru.
+partner.googleadservices.com.
+masuren-ferienhaus.com.
+wmkreditonline.ru.
+www.googletagservices.com.
+f1rz3vpuf.y61e7v8o.
+245.244.65.222.in-addr.arpa.
+photos-g.ak.fbcdn.net.
+a.root-servers.net.
+browsermusic.titleservices.com.
+www.airserverapp.com.
+151.94.139.189.in-addr.arpa.
+a.root-servers.net.
+2.223.110.109.in-addr.arpa.
+autoupdate.chromewebtb.conduit-services.com.
+www.fetishsnake.com.
+www.jmsky.com.
+www.webcomparte.cl.
+im-perfection.com.
+photofla.me.
+217.148.168.192.in-addr.arpa.
+download781.avast.com.
+umail.ukrtel.net.
+localhost.
+alphatoris.com.
+i5.tagstat.com.
+content.imorphosis.com.
+plus.google.com.
+bglh2dojw.36cd.
+a.root-servers.net.
+www.jellyegg.com.
+fb.me.
+listen.grooveshark.com.
+hotfixline.eu.
+app.kpi.com.
+_338_05_1.
+a3.twimg.com.
+169.208.225.212.in-addr.arpa.
+58.56.179.78.in-addr.arpa.
+gaffneyinc.com.s7a2.psmtp.com.
+229.185.29.201.in-addr.arpa.
+ninemsn.video.msn.com.
+sf2.wmclinic.com.
+clickmedia.sitescout.com.
+cuantodanio.blogspot.com.
+.
+a8.sphotos.ak.fbcdn.net.
+www.adobe.com.
+138.104.223.201.in-addr.arpa.
+a8.sphotos.ak.fbcdn.net.
+109.183.255.113.in-addr.arpa.
+236.62.61.186.in-addr.arpa.
+www.googletagservices.com.
+thewindowsclub.disqus.com.
+126.26.120.200.in-addr.arpa.
+ads12.groovinads.com.
+vp.sip.messenger.msn.com.
+a200.da1.akamai.net.
+a5.sphotos.ak.fbcdn.net.
+s.youtube.com.
+profile.ak.fbcdn.net.
+developers.facebook.com.
+smtp.boardofchildcare.org.
+238.243.204.190.in-addr.arpa.
+us.mg5.mail.yahoo.com.
+www.victoriaschool.co.uk.
+fallback.mail.fr.uu.net.
+forexcms.hs.llnwd.net.
+api.zynga.com.
+www.portalnet.cl.
+pt-br.facebook.com.
+_133_30_3.
+tools.google.com.
+189.224.74.190.in-addr.arpa.
+img1.catalog.video.msn.com.
+diapeesandwipees.com.
+www.eatstopeat.com.
+b.photobucket.com.
+webfront.ru.
+www.extremestraponsex.com.
+a4.sphotos.ak.fbcdn.net.
+www.facebook.com.
+fafa6.com.
+173.245.224.67.in-addr.arpa.
+platform.twitter.com.
+www.statcounter.com.
+www.exileskimboards.com.
+server6.camelot-hosting.com.
+profile.ak.fbcdn.net.
+www.youtube.com.
+www.newmountain.com.
+geoiplookup.wikimedia.org.
+a0.twimg.com.
+169.142.102.85.in-addr.arpa.
+spcum.qc.ca.
+photos-a.ak.fbcdn.net.
+innovativee-com02e.mail.eo.outlook.com.
+www.designingforhumans.com.
+plusone.google.com.
+tracker.openbittorrent.com.
+travelocity.conduitapps.com.
+uno.wt-rotator104.ru.
+www.tomsalta.com.
+henna.com.
+79.84.66.76.in-addr.arpa.
+www.kzao.com.
+restaurant.teamlava.com.
+109.205.176.187.in-addr.arpa.
+www.facebook.com.
+niynossgm.info.lan.
+224.109.158.189.in-addr.arpa.
+48.121.196.205.in-addr.arpa.
+tracker.bitreactor.to.
+191.227.2.187.in-addr.arpa.
+www.facebook.com.
+195.10.87.186.in-addr.arpa.
+ad.turn.com.
+lactofilia.blogspot.com.
+www.wirefresh.com.
+globet.com.
+www.infolanka.com.
+www.amaranthia.com.
+m.denverpost.com.
+dns.msftncsi.com.
+a-0.19-a3097081.d010583.1518.19d2.3ea1.410.0.jn69rb291g6mjqcwbz2gqzla1b.avqs.mcafee.com.
+twitter.com.
+npgcable.com.
+altx-soft.ru.
+1xom1yyiz.64ns.
+www.positivelysplendid.com.
+draka.com.
+sharelink.com.cy.
+platform.ak.fbcdn.net.
+www.brunelalumni.co.uk.
+195.194.207.190.in-addr.arpa.
+www.xvideos.com.
+crocjokes.com.
+imap.gmail.com.
+a5.da1.akamai.net.
+google.com.
+de-de.facebook.com.
+www.rebuildbabel.com.
+89.238.242.24.in-addr.arpa.
+201.0.187.189.in-addr.arpa.
+morefilm.ru.
+29.186.137.190.in-addr.arpa.
+l.yimg.com.
+mail.lllindberg.com.
+stag-live.gourmet.com.
+103.119.137.187.in-addr.arpa.
+120.237.55.201.in-addr.arpa.
+iland-net-bk.messaging.lotuslive.com.
+www.idedge.com.
+miski-igla.blogspot.com.
+trentonpolice.net.
+creative.ak.fbcdn.net.
+b._dns-sd._udp.0.1.168.192.in-addr.arpa.
+ssl.gstatic.com.
+49.18.55.157.in-addr.arpa.
+www.iapchiapas.org.mx.
+m1.nsimg.net.
+a.root-servers.net.
+a.root-servers.net.
+gun.su.
+gw006.lphbs.com.
+61.217.32.31.in-addr.arpa.
+135.164.184.187.in-addr.arpa.
+profile.ak.fbcdn.net.
+feyenoord.headliner.nl.
+db._dns-sd._udp.0.1.168.192.in-addr.arpa.
+cv.duba.net.
+www.attdroids.com.
+loseasi.blogspot.com.
+124.173.106.186.in-addr.arpa.
+creative.ak.fbcdn.net.
+edge.quantserve.com.
+scm-l3.technorati.com.
+125.141.248.189.in-addr.arpa.
+190.154.214.189.in-addr.arpa.
+img-2007-09.photosight.ru.
+calendar.live.com.
+zzominternet.net.
+www.epicgameads.com.
+www.googleadservices.com.
+66.20.237.189.in-addr.arpa.
+www.gstatic.com.
+a1.sphotos.ak.fbcdn.net.
+webcache.googleusercontent.com.
+25.150.3.186.in-addr.arpa.
+www.prostitv.com.
+jsurnwy16.96yo.
+164.15.53.186.in-addr.arpa.
+a4.sphotos.ak.fbcdn.net.
+robbbest1.wordpress.com.
+searchjs.s3.amazonaws.com.
+123.34.50.190.in-addr.arpa.
+top5.mail.ru.
+stmlending.com.
+news.l.google.com.
+121.68.174.190.in-addr.arpa.
+137.209.129.186.in-addr.arpa.
+www.cadeaux-poker.com.
+external.ak.fbcdn.net.
+rover.ebay.com.
+s.ytimg.com.
+iyashinet.net.
+smsclub.ru.
+s-external.ak.fbcdn.net.
+www.facebook.com.
+sp.cwfservice.net.
+0-244.channel.facebook.com.
+photos-b.ak.fbcdn.net.
+limewire-speedup-pro.programas-gratis.net.
+westnet.gr.
+s.youtube.com.
+toolbarqueries.clients.google.com.
+blseamon.com.inbound10.mxlogicmx.net.
+connect.facebook.net.
+teredo.ipv6.microsoft.com.
+98.132.93.186.in-addr.arpa.
+a.root-servers.net.
+www.photostringer.com.
+www.3dtuning.ru.
+a.root-servers.net.
+download957.avast.com.
+cadgroup.com.au.
+translate.google.com.mx.
+dxocy7wsx.57lc.
+240.77.21.190.in-addr.arpa.
+a.root-servers.net.
+tisindia.com.
+usd232.org.
+es-la.facebook.com.
+a7.sphotos.ak.fbcdn.net.
+65.255.48.65.in-addr.arpa.
+www.facebook.com.
+facebook-en-espanol.com.
+connect.facebook.net.
+avatars.whatboyswant.com.
+s.youtube.com.
+api.facebook.com.
+mscrl.microsoft.com.
+hbf.cloud.avg.com.
+thewholeheartedmind.wordpress.com.
+rose.ocn.ne.jp.
+cdn.coolsmileypack.com.
+minnesota-mn-cars.tk.
+www.dream-teens.net.
+profile.ak.fbcdn.net.
+z021.fma.fb.me.
+meraki.com.
+a.root-servers.net.
+www.buscatube.org.
+117.180.83.74.in-addr.arpa.
+farm6.static.flickr.com.
+bresso.net.
+settings.toolbar.search.conduit.com.
+235.229.178.190.in-addr.arpa.
+db._dns-sd._udp.0.1.168.192.in-addr.arpa.
+2.247.37.77.in-addr.arpa.
+www.vgatohdmi.net.
+251.133.89.201.in-addr.arpa.
+yahoo.es.
+a.root-servers.net.
+profile.ak.fbcdn.net.
+thumbs3.maturebjtube.com.
+candysoirees.blogspot.com.
+eur6.akam.net.
+166.213.96.200.in-addr.arpa.
+improveverywhere.com.
+mail.google.com.
+bvohk.com.domain.name.
+platform.twitter.com.
+34.23.241.189.in-addr.arpa.
+www.facebook.com.
+external.ak.fbcdn.net.
+207.159.152.187.in-addr.arpa.
+ads.espectador.com.
+tambotur.ru.
+pa.starmedia.com.
+a6.sphotos.ak.fbcdn.net.
+sanjeeve.com.
+a3.twimg.com.
+external.ak.fbcdn.net.
+external.ak.fbcdn.net.
+148.56.168.192.in-addr.arpa.
+profile.ak.fbcdn.net.
+ns.tc-exe.ru.
+putzlowitsch.de.
+41.243.255.201.in-addr.arpa.
+www.election-presidentielle.com.
+38.96.128.67.in-addr.arpa.
+api.twitter.com.
+diariowebstardoll.blogspot.com.
+nctc.com.s6b1.psmtp.com.
+www.facebook.com.
+tdcsgwxd1.63cx.
+98.116.144.189.in-addr.arpa.
+robert.de.
+js2.wlxrs.com.
+phillipsandtemro.com.
+44.27.247.69.in-addr.arpa.
+extrapetiteblogroll.blogspot.com.
+connect.facebook.net.
+static.ver-pelis.net.
+photos-b.ak.fbcdn.net.
+o.facebook.com.
+cfg.smartshopper.com.
+ecnu38522.37cd.
+a.root-servers.net.
+28.1.168.192.in-addr.arpa.
+server9.fulltono.com.
+229.162.49.200.in-addr.arpa.
+www.lamatanza.gov.ar.
+f.chtah.com.
+_725_93_3.
+ajax.googleapis.com.
+_564_90_7.
+52.160.234.189.in-addr.arpa.
+dns.msftncsi.com.
+global.ard.yahoo.com.
+kennametal.com.
+wzeu.ask.com.
+msn.es.
+_920_33_4.
+ec.atdmt.com.
+profile.ak.fbcdn.net.
+249.205.178.186.in-addr.arpa.
+clock.fmt.he.net.
+photos-d.ak.fbcdn.net.
+ap.nic.in.
+support.microsoft.com.
+ksn2-12.kaspersky-labs.com.
+0806accac1.org.
+deformacionprofesional.blogspot.com.
+168.238.69.190.in-addr.arpa.
+vidasanayfelicidad.blogcindario.com.
+www.suffolkmaths.co.uk.
+www.daetsid.upv.es.
+discovereddreams.com.
+time.windows.com.
+sandroses.com.
+toolbar.aol.com.
+www.numaticengineering.com.
+translate.google.com.mx.
+teredo.ipv6.microsoft.com.
+google.com.
+tasteofbritain.com.
+apps.facebook.com.
+rmxlabs.ru.
+htc2.accu-weather.com.
+200.142.56.186.in-addr.arpa.
+www.teveonline.net.
+ib.adnxs.com.
+11.21.89.69.in-addr.arpa.
+ddtrslab.blogspot.com.
+a.root-servers.net.
+i4.ytimg.com.
+managedforexbrokers.com.
+celebrityphotosnews.files.wordpress.com.
+foros.3dgames.com.ar.
+anuncios-comunidad.vivastreet.com.mx.
+mx2.free.fr.
+www.google-analytics.com.
+pwindow.ru.
+sn1msg3020234.sn1.gateway.edge.messenger.live.com.
+252.88.92.186.in-addr.arpa.
+img.rankplan.net.
+alkhaleej.com.sa.
+dnl-19.geo.kaspersky.com.
+haymarket.btsdev.net.
+mscrl.microsoft.com.
+fb.trove.com.
+e693i1pqz.84xi.
+www.facebook.com.
+pixel.facebook.com.
+on.fb.me.
+time.chttl.com.tw.
+js.revsci.net.
+ocsp.digicert.com.
+cfgommausa.com.
+static.ak.fbcdn.net.
+mydomainname.com.
+www.cnnturk.com.
+www.yourtrafficstarterblog.com.
+236.111.93.213.in-addr.arpa.
+www.friend2friend.com.
+_213_27_0.
+sites.google.com.
+551qev521.d54n6b0t.
+sonawebzone.blogspot.com.
+www.easy-dating.org.
+marilynmanson.shop.bravadousa.com.
+183.97.10.186.in-addr.arpa.
+www.google.com.
+115.90.252.189.in-addr.arpa.
+www.facebook.com.
+61.37.221.190.in-addr.arpa.
+www.youtube.com.
+imexsa.com.
+cox.net.
+www.xvideos.com.
+lb._dns-sd._udp.0.2.168.192.in-addr.arpa.
+img1.wsimg.com.
+feminidadconsciente.es.tl.
+crl.microsoft.com.
+a.root-servers.net.
+api.twitter.com.
+www.decoundstyle.de.
+playagain.es.
+www.stateofartacademy.com.
+www.valentine.com.
+static.2mdn.net.
+mqppxz198.10tq.
+static.ak.fbcdn.net.
+125.47.170.189.in-addr.arpa.
+www.internetcultural.org.
+136.30.152.85.in-addr.arpa.
+www.dbspublicidad.com.mx.
+www7.pic-upload.de.
+irc.purchaseservice.com.
+profile.ak.fbcdn.net.
+xenoborg.blogspot.com.
+zynga.tm.
+safebrowsing-cache.google.com.
+27.86.248.189.in-addr.arpa.
+www.connect.facebook.com.
+a8.sphotos.ak.fbcdn.net.
+y12fcu.org.
+a.root-servers.net.
+a.analytics.yahoo.com.
+descargarlibrosde.com.
+twitter.com.
+9.1.211.186.in-addr.arpa.
+www.taringa.net.
+safebrowsing.clients.google.com.
+9gag.com.
+view.atdmt.com.
+a.root-servers.net.
+159.135.212.201.in-addr.arpa.
+ssl.gstatic.com.
+50.166.171.69.in-addr.arpa.
+service.collarity.com.
+www.cineticket.com.mx.
+congafoods.com.au.
+www.softonic.jp.
+phoenixtrucklines.com.
+www.facebook.com.
+a.root-servers.net.
+developers.facebook.com.
+www10.0zz0.com.
+129.114.239.201.in-addr.arpa.
+t2.gstatic.com.
+www.racingbetter.co.uk.
+safebrowsing.clients.google.com.
+traductoringlesespanol.mobi.
+shipping.lauritz.com.
+a2.da1.akamai.net.
+mail.donet.com.
+photos-c.ak.fbcdn.net.
+www.ibit.org.
+1.220.181.189.in-addr.arpa.
+mail.acornmedia.com.
+strelnasanatoriy.ru.
+www.marsden.com.
+ipm.avira.com.
+api.twitter.com.
+twitter.com.
+smtp.renault.fr.
+www.facebook.com.
+146.talkgadget.google.com.
+a1007.w43.akamai.net.
+107.116.203.87.in-addr.arpa.
+www.tibcommunity.com.
+competitrack.com.s8b2.psmtp.com.
+www.amivisible.org.
+wolframcdn.com.
+prointec.es.
+252.29.151.187.in-addr.arpa.
+www.astradur.is.
+maplesugarshack.net.
+i1.ytimg.com.
+93.194.87.190.in-addr.arpa.
+198.77.216.223.in-addr.arpa.
+seupdate.360safe.com.
+www.facebook.com.
+www.bloglines.com.
+www.black.100topsites.net.
+142.50.30.189.in-addr.arpa.
+trosch.com.inbound10.mxlogic.net.
+safebrowsing-cache.google.com.
+a.root-servers.net.
+cityvillefb1.static.zgncdn.com.
+www.tripadvisor.com.mx.
+api.twitter.com.
+az-rmt.osprint.ru.
+login.yahoo.com.
+www.redtubexvideos.com.
+108.84.105.186.in-addr.arpa.
+oooevroinvest.ru.
+mamortgage.com.
+caobasecurities.com.
+www.culpepper.com.
+cdn.cxense.com.
+data.mobclix.com.
+photos-a.ak.fbcdn.net.
+cdn.doclix.com.
+pix04.revsci.net.
+alhama.com.
+www.el-tallercito.com.
+tracker.mytorrenttracker.com.
+www.artistdirect.com.
+www.pepper.pk.
+117.20.49.190.in-addr.arpa.
+a.root-servers.net.
+.
+istockanalyst.com.
+www.trend-uk.com.
+188.44.58.186.in-addr.arpa.
+fblog-chismes.blogspot.com.
+ak1.abmr.net.
+compadreorock.blogspot.com.
+ddl-zone.org.
+external.ak.fbcdn.net.
+baby.shop.ebay.com.
+zynga2-a.akamaihd.net.
+a4.sphotos.ak.fbcdn.net.
+s1.apollolv.adocean.pl.
+123.32.64.76.in-addr.arpa.
+www.ustream.tv.
+mmv.admob.com.
+www32.patrz.pl.
+s2jl7vqg5.j23e5d7q.
+csi.gstatic.com.
+limelight.cedexis.com.
+versioncheck.addons.mozilla.org.
+152.232.171.69.plus.bondedsender.org.
+estore.pubeasyschool.com.
+a.root-servers.net.
+149.6.113.76.in-addr.arpa.
+b.scorecardresearch.com.
+profile.ak.fbcdn.net.
+partner.googleadservices.com.
+teredo.ipv6.microsoft.com.
+asciinickbuilder.softonic.com.
+mail.superlink.ru.
+ax.su.itunes.apple.com.
+www3.oovoo.com.
+49.147.220.66.in-addr.arpa.
+www.youtube.com.
+www.google.com.
+a1108.da1.akamai.net.
+mscrl.microsoft.com.
+35.114.1.186.in-addr.arpa.
+kirbos.net.
+mail.uniwebinc.com.
+check4.facebook.com.
+willhelm-cinefilo.blogspot.com.
+translate.google.com.mx.
+pagead2.googlesyndication.com.
+track.searchignite.com.
+photos-a.ak.fbcdn.net.
+router.infolinks.com.
+86.169.252.190.in-addr.arpa.
+photos-d.ak.fbcdn.net.
+api.twitter.com.
+weather.wapp.wii.com.
+www.autopart.com.
+cgi1.ebay.com.
+ganardineroeninternet101.com.
+nsall.huawei.com.
+js.wlxrs.com.
+217.134.68.118.in-addr.arpa.
+widgets.twimg.com.
+nordeus.hs.llnwd.net.
+www.kemi.org.
+junny.de.
+fr.y8.com.
+www.msnarea.com.
+au.pool.ntp.org.
+mathildaastrand.tumblr.com.
+a1911.phobos.apple.com.
+www.themorristribe.com.
+aluni.net.
+vthumb.ak.fbcdn.net.
+apps.facebook.com.
+www.update.microsoft.com.
+smtp3.aceaspa.it.
+fbcdn-profile-a.akamaihd.net.
+_775_26_9.
+www.emusic.com.
+static-resource.np.community.playstation.net.
+mail.catapultprofiling.com.
+216.99.219.81.in-addr.arpa.
+blog.lydiapintscher.de.
+rrcaribbean.com.
+228.30.135.187.in-addr.arpa.
+billing.sharo4ka.ru.
+dns.msftncsi.com.
+www.bloomberg.com.
+sp.cwfservice.net.
+216.234.171.1.in-addr.arpa.
+mail2.hmgmt.com.
+u.goal.com.
+pubads.g.doubleclick.net.
+barbantesaofrancisco.blogspot.com.
+www.momsexland.com.
+bar.searchqu.com.
+2.5.204.201.in-addr.arpa.
+makeshift-designs.co.cc.
+apps.facebook.com.
+alerts.conduit-services.com.
+despiertatuqueduermes.blogspot.com.
+106.157.138.190.in-addr.arpa.
+api.facebook.com.
+a5.sphotos.ak.fbcdn.net.
+connect.facebook.net.
+shar.es.
+selectmortgageresources.com.
+ksn6-12.kaspersky-labs.com.
+sc19.rules.mailshell.net.
+a8.sphotos.ak.fbcdn.net.
+100.54.50.190.in-addr.arpa.
+pencor.com.
+199.0.168.192.in-addr.arpa.
+vcs2.msg.yahoo.com.
+52.183.210.201.in-addr.arpa.
+66.59.204.187.in-addr.arpa.
+faldin.ru.
+a-0.19-2109f071.c010083.1518.19d4.3ea1.410.0.76j2nh7aft59gpznre2b33aszj.avqs.mcafee.com.
+www.sub5zero.com.
+sc2.rules.mailshell.net.
+teredo.ipv6.microsoft.com.
+roncallihs.org.
+danniiminogueofficial.blogspot.com.
+mail.conninc.com.
+mail.rialcom.ru.
+ansarenterprises.com.
+developers.facebook.com.
+ticketalternative.com.
+liveupdate.symantecliveupdate.com.
+row.bc.yahoo.com.
+luckyshoes.com.2.arsmtp.com.
+cdn.qpn.360.cn.
+instagr.am.
+fbcdn-profile-a.akamaihd.net.
+www.google-analytics.com.
+google.svstyle.com.ua.
+17.156.229.190.in-addr.arpa.
+67.636569706d736e.636f6d.80hcf2ec172.webcfs00.com.
+147.1.201.72.in-addr.arpa.
+a1.sphotos.ak.fbcdn.net.
+graphic-inline.co.uk.
+65.133.243.201.in-addr.arpa.
+234.61.217.189.in-addr.arpa.
+171.179.92.186.in-addr.arpa.
+oakmitsui.com.
+54.12.133.186.in-addr.arpa.
+196.185.29.186.in-addr.arpa.
+www.dentonisd.org.
+imgditan.mycollect.net.
+a.root-servers.net.
+234.148.151.79.in-addr.arpa.
+www.gstatic.com.
+watmidco.net.
+cc-net.net.
+219.164.79.190.in-addr.arpa.
+yu.elearning.yu.edu.
+db._dns-sd._udp.0.1.168.192.in-addr.arpa.
+mail.do-m.ru.
+optimized-by.rubiconproject.com.
+b.scorecardresearch.com.
+195.251.44.200.in-addr.arpa.
+www.facebook.com.
+sa2.ttu.ee.
+mx2.jbaengr.com.
+xxcal.com.s8b1.psmtp.com.
+www.upamayorista.com.ar.
+a6.sphotos.ak.fbcdn.net.
+cdn-9.pics.hardsextubepremium.com.
+a8.sphotos.ak.fbcdn.net.
+mx1.brighthorizons.com.
+profile.ak.fbcdn.net.
+www.googleadservices.com.
+a6.sphotos.ak.fbcdn.net.
+app.my.4399.com.
+backofficesite.epyte.com.
+240.166.121.189.in-addr.arpa.
+mail.cirrusassociates.com.
+26103.ua.all.biz.
+a998.mm1.akamai.net.
+mail-attachment.googleusercontent.com.
+148.30.135.190.in-addr.arpa.
+filter1.natski-1.mailguard.com.au.
+autos.mercadolibre.com.ar.
+170.5.48.186.in-addr.arpa.
+sdparts.com.s6b2.psmtp.com.
+cs274.vk.com.
+myimagingexam.com.
+www.clickhereforpantyhose.com.
+surcon.ru.
+photos.voyage-prive.es.
+smtp.alacranedizioni.it.
+a5.sphotos.ak.fbcdn.net.
+tenzing.fmpub.net.
+storage.surfingbird.ru.
+annettevandenbosch.nl.
+chat.online.citi.com.
+m.adnxs.com.
+www.google.com.
+concesionarias.net.
+a1294.w20.akamai.net.
+a394.phobos.apple.com.
+190.64.54.208.in-addr.arpa.
+developers.facebook.com.
+mail.pdqpayroll.net.
+a8.sphotos.ak.fbcdn.net.
+www.linkedin.com.
+www.chrono24.pt.
+179.44.253.212.in-addr.arpa.
+_221_11_9.
+pagead2.googlesyndication.com.
+photos-e.ak.fbcdn.net.
+www.facebook.com.
+rheagl.com.
+63.150.114.190.in-addr.arpa.
+20.234.187.124.in-addr.arpa.
+csi.gstatic.com.
+aol.com.
+www.jgmb829.com.
+www.ardillanet.com.
+vanessahudgens.silverback.sparkart.net.
+8fhmajt9e.b56j0n5d.
+www.blackdragonsperu.com.
+156.137.55.182.in-addr.arpa.
+223.14.119.68.in-addr.arpa.
+promotions.newegg.com.
+www.elnuevoexponente.blogspot.com.
+www.elementtuning.com.
+ad.yieldmanager.com.
+209.96.114.201.in-addr.arpa.
+s.youtube.com.
+go.srvnow.com.
+cdn.api.twitter.com.
+apps.facebook.com.
+223.103.10.186.in-addr.arpa.
+filatina.wordpress.com.
+pubads.g.doubleclick.net.
+eircommusichub.ie.
+pagead2.googlesyndication.com.
+www.ullapopken.com.
+listado.deremate.com.ec.
+rya.rockyou.com.
+www.6rb.com.
+a.root-servers.net.
+www.losroblerinos.cl.
+www.facebook.com.
+ads.trafficjunky.net.
+45.28.54.187.in-addr.arpa.
+ax.init.itunes.apple.com.
+anaconda-manifesto.blogspot.com.
+230.157.172.78.in-addr.arpa.
+ijasamxs2.k79t4q2s.
+www.ibc-asia.com.
+.
+www.lakelandtimes.com.
+244.224.0.68.in-addr.arpa.
+broenserud.com.
+googleads.g.doubleclick.net.
+a.root-servers.net.
+safebrowsing.clients.google.com.
+chickamauga.com.
+www.it-bs.com.ar.
+www.wikeez.com.
+a1294.w20.akamai.net.
+231.116.156.189.in-addr.arpa.
+external.ak.fbcdn.net.
+b.scorecardresearch.com.
+data.flurry.com.
+s19.radikal.ru.
+a996.mm1.akamai.net.
+ajax.googleapis.com.
+www.escortpoint.com.
+sindia.polyvore.com.
+contentserv.brandaffinity.net.
+cs9933.vk.com.
+www.tabacoyron.dimelorecords.com.
+www.facebook.com.
+google.com.
+www.vocerodelcafe.com.
+stitchstud.podbean.com.
+mail.chemreport.com.
+dnl-01.geo.kaspersky.com.
+209.19.240.201.in-addr.arpa.
+star.facebook.com.
+rotabanner.nsk.ru.
+teredo.ipv6.microsoft.com.
+165.107.26.190.in-addr.arpa.
+is.gd.
+www.adobe.com.
+ksn1-11-part2.kaspersky-labs.com.
+paintballtoro.es.
+pagead2.googlesyndication.com.
+www.sammynetbook.com.
+photos-a.ak.fbcdn.net.
+cdn1.ads.brazzers.com.
+photos-a.ak.fbcdn.net.
+www.2darray.net.
+cdn.betrad.com.
+a.root-servers.net.
+a.root-servers.net.
+mail.fastmarketmail.com.
+46-courier.push.apple.com.
+ssl.gstatic.com.
+176.91.84.186.in-addr.arpa.
+blogicars.com.
+b76.photo.store.qq.com.
+dgapartners.com.2.0001.arsmtp.com.
+t1.gstatic.com.
+searchjs.s3.amazonaws.com.
+mail.google.com.
+download983.avast.com.
+126.246.98.171.in-addr.arpa.
+www.programmingsimplified.com.
+pixel.facebook.com.
+cfh.wapp.wii.com.
+diario.latercera.com.
+img268.imageshack.us.
+mail.thewisegroup.co.uk.
+safebrowsing-cache.google.com.
+analogartsensemble.net.
+www.portube.com.
+194.111.113.186.in-addr.arpa.
+www.smartadserver.com.
+i4.ytimg.com.
+external.ak.fbcdn.net.
+a.root-servers.net.
+njaes.rutgers.edu.
+push.apple.com.
+a4.sphotos.ak.fbcdn.net.
+222.23.31.190.in-addr.arpa.
+mx.nehemiahinstitute.com.
+9.231.52.24.in-addr.arpa.
+blogskinny.com.
+c-0.19-a3095081.10023.1518.19d4.3ea1.210.0.389ipn6vifghc4ezzc8t24r8fv.avqs.mcafee.com.
+www.granpared.com.
+www.bing.com.
+developers.facebook.com.
+a.root-servers.net.
+166.199.193.201.in-addr.arpa.
+i795.photobucket.com.
+co.marin.co.us.
+www.seldomparty.com.
+www.stardoll.com.
+130.252.200.190.in-addr.arpa.
+a.root-servers.net.
+img.rincondelvago.com.
+www.easycounter.com.
+ho1.eunic.net.ua.
+www.googletagservices.com.
+teredo.ipv6.microsoft.com.
+nardei.com.
+mx.davidkjefferies.com.
+107.130.188.189.in-addr.arpa.
+thebestbankrates.com.
+a7.sphotos.ak.fbcdn.net.
+developers.facebook.com.
+www.gstatic.com.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+s-static.ak.fbcdn.net.
+3ba1f48a4b3e87fbdcea52325266e210.info.
+www.myhatespace.com.
+people.hankyung.com.
+g.msn.com.
+mx.youtube.com.
+www.parentsmedguide.org.
+www.cotodigital.com.ar.
+configuration.apple.com.
+bks.co.za.
+www.facebook.com.
+f.facemoods.com.
+firefoxupdate.dealply.com.
+www.meteosort.com.
+pt-br.facebook.com.
+a6.sphotos.ak.fbcdn.net.
+us.data.toolbar.yahoo.com.
+apps.facebook.com.
+medexpress32.ru.
+ad.yieldmanager.com.
+todaunaexperienciasermama.blogspot.com.
+usersystem783aa.ru.
+3.bp.blogspot.com.
+newsrss.bbc.co.uk.
+priorityinfo.com.
+dns.msftncsi.com.
+a-0.19-a309e081.c0c0083.1518.19d3.3ea1.410.0.51iw1za3evdf6rvgbu2994uqkb.avqs.mcafee.com.
+static.ak.fbcdn.net.
+a8.sphotos.ak.fbcdn.net.
+www.theinquirer.es.
+jnba.com.s6b2.psmtp.com.
+profile.ak.fbcdn.net.
+a2.mzstatic.com.
+114.185.120.174.in-addr.arpa.
+cdn1.clkads.com.
+www.barcelonainternships.com.
+apis.google.com.
+dns.msftncsi.com.
+eshop.tutorialonline.biz.
+a.root-servers.net.
+119.183.228.72.in-addr.arpa.
+photos-b.ak.fbcdn.net.
+maqil.ru.
+developers.facebook.com.
+_ldap._tcp.servidor.local.
+dailynews.anniesattic.com.
+195.185.159.187.in-addr.arpa.
+a.root-servers.net.
+www.seriesyonkis.com.
+a.root-servers.net.
+cinismoilustrado.bigcartel.com.
+img18.pixiv.net.
+teredo.ipv6.microsoft.com.
+profile.ak.fbcdn.net.
+d2055744.instant.xoom.it.
+148.142.36.83.in-addr.arpa.
+mail.megapolis-pnz.ru.
+hitback.ru.
+2kfrnv7j6.x20w3j1c.
+accounts.google.com.
+109.126.151.189.in-addr.arpa.
+www.play-music.com.
+xfem7gnot.72rz.
+nursing.edu.au.
+www.lacostena.com.mx.
+sufism.org.
+community.ebay.com.
+www.facebook.com.
+mx2.hotmail.com.
+149.212.144.189.in-addr.arpa.
+venta.odm.com.mx.
+time.chttl.com.tw.
+survivingtheworld.net.
+mac.ign.com.
+go.microsoft.com.
+beneast.co.uk.
+brier.afsc.k12.ar.us.
+www.palabraspordinero.com.
+www.4pnc.com.
+r._dns-sd._udp.0.2.168.192.in-addr.arpa.
+a.root-servers.net.
+ajax.googleapis.com.
+photos-d.ak.fbcdn.net.
+bay.messenger.services.live.com.
+adserving.cpxinteractive.com.
+21.201.59.201.in-addr.arpa.
+mail.wegowild.com.
+mx.divillarosa.com.
+2.238.190.186.in-addr.arpa.
+caras.com.mx.
+itunes.apple.com.
+228.226.144.222.in-addr.arpa.
+time.windows.com.
+mds-oman.com.
+mail.banktcnb.com.
+186.225.110.71.in-addr.arpa.
+xxxroom.net.
+profile.ak.fbcdn.net.
+gbglawoffice.com.
+vmwebfe.voice.yahoo.com.
+www.icascanada.ca.
+spalatvia.ru.
+179.150.138.188.in-addr.arpa.
+www.gstatic.com.
+cs4762.vkontakte.ru.
+g.live.com.
+cpersonnel.com.
+trophy.ww.np.community.playstation.net.
+67.242.35.189.in-addr.arpa.
+www.mozilla.com.
+167.197.130.201.in-addr.arpa.
+fbcdn-sphotos-a.akamaihd.net.
+62.103.11.190.in-addr.arpa.
+10.50.125.213.in-addr.arpa.
+mailbag.adnet-sys.com.
+watch-dragonball.com.
+usuarios.maptel.es.
+a.root-servers.net.
+mail.truckwriters.com.
+a.root-servers.net.
+misvideos-curiosos.com.
+s-external.ak.fbcdn.net.
+translate.googleapis.com.
+16.1.168.192.in-addr.arpa.
+a4.sphotos.ak.fbcdn.net.
+www.suurland.com.
+a7.sphotos.ak.fbcdn.net.
+a3.sphotos.ak.fbcdn.net.
+a7.sphotos.ak.fbcdn.net.
+114.105.168.86.in-addr.arpa.
+syndication.exoclick.com.
+photos-h.ak.fbcdn.net.
+a.root-servers.net.
+dns.msftncsi.com.
+7-courier.push.apple.com.
+mountainviewfruit.com.
+109.11.182.186.in-addr.arpa.
+cdn1.image.spankwire.phncdn.com.
+168.202.163.67.in-addr.arpa.
+www.clairol.ie.
+www.starclean.de.
+141.237.191.190.in-addr.arpa.
+www.mtvla.com.
+onepiece-revolution.foroactivo.mx.
+www.brookingsregister.com.
+157.67.188.189.in-addr.arpa.
+login.live.com.
+i4.ytimg.com.
+34.166.29.76.in-addr.arpa.
+a8.sphotos.ak.fbcdn.net.
+telia.com\".
+www.gstatic.com.
+i1.ytimg.com.
+play.cultures-online.gamigo.es.
+mygadgets99.com.
+csi.gstatic.com.
+a.root-servers.net.
+developers.facebook.com.
+accounts.google.com.
+autozentrum-ebber.de.
+www.kimfoundation.com.
+tura.evenkya.ru.
+158.104.69.189.in-addr.arpa.
+mail.mhs-pa.org.
+apps.facebook.com.
+128.215.43.201.in-addr.arpa.
+a.root-servers.net.
+170.10.25.177.in-addr.arpa.
+auth.bleast1.perfectworld.com.
+ad.harrenmedianetwork.com.
+98.22.220.189.in-addr.arpa.
+126.181.229.190.in-addr.arpa.
+121.163.60.186.in-addr.arpa.
+panicsubtitulado.blogspot.com.
+a6.sphotos.ak.fbcdn.net.
+photos-g.ak.fbcdn.net.
+172.166.7.199.in-addr.arpa.
+www.newmediaexplorer.org.
+52.69.90.78.in-addr.arpa.
+iris.eonet.ne.jp.
+www.kon.org.
+db._dns-sd._udp.lan.
+telefunda.blogspot.com.
+img.mediaplex.com.
+235.11.164.85.in-addr.arpa.
+craig.se.
+secure.base.wlxrs.com.akadns.net.
+nl.webcams.travel.
+vb.grorbnat.com.
+sohoo.com.
+crl.microsoft.com.
+www.mtvla.com.
+10.74.161.187.in-addr.arpa.
+www.facebook.com.
+www.oopsydaisybaby.com.
+emc.org.
+www.mediafire.com.
+nutricionistaonline.org.
+224.78.174.190.in-addr.arpa.
+antfarminteractive.com.
+bpatruth.com.
+225.216.183.189.in-addr.arpa.
+www.circovip.com.
+a1408.w43.akamai.net.
+maps.googleapis.com.
+photos-b.ak.fbcdn.net.
+unsw.edu.au.
+www.gpwiki.org.
+bw1.midasplayer.com.
+a.root-servers.net.
+static.ak.connect.facebook.com.
+mx.netelisys.com.
+sites.google.com.
+l.yimg.com.
+www.internetfrog.com.
+apps.facebook.com.
+dnl-01.geo.kaspersky.com.
+www.disegnicolorare.com.
+photos-f.ak.fbcdn.net.
+time.windows.com.
+img4.ask.fm.
+pixel.facebook.com.
+www.fbskins.com.
+ar-ar.facebook.com.
+mail.rivercitysalesinc.com.
+kidszone1.com.
+1804289383.localhost.
+clients1.google.com.
+nsx.sec.np.dl.playstation.net.
+www.eximeno.com.
+www.casayjardin.net.ve.
+www.scrapbookmax.com.
+a.root-servers.net.
+www.abrconsulting.com.
+vergelcastro.atspace.com.
+urs.microsoft.com.
+www.google.com.
+www.carlosmaldonado.org.
+139.196.203.190.in-addr.arpa.
+206.230.44.124.in-addr.arpa.
+72.239.79.190.in-addr.arpa.
+jqueryjs.googlecode.com.
+qea:q2ubq.37pr.
+accountservices.msn.com.
+dr._dns-sd._udp.home.
+.
+bigpond.com.
+choconaturebio.choconature.com.
+autoaccessories4less.com.
+desmond.yfrog.com.
+mail2.psipack.com.
+br.fling.com.
+www.bleachhforos.com.
+a.root-servers.net.
+www.facebook.com.
+30.57.173.190.in-addr.arpa.
+api.facebook.com.
+latinas.buenchat.com.ar.
+www.switchedonart.com.
+www.losdejalisco.blogspot.com.
+73.246.144.86.in-addr.arpa.
+a.root-servers.net.
+mail.capobeach.com.
+a3.sphotos.ak.fbcdn.net.
+artandculturecenter.org.
+googleads.g.doubleclick.net.
+www.manebooks.com.
+redbluff.com.
+a.root-servers.net.
+translate.googleapis.com.
+239.7.89.201.in-addr.arpa.
+49.234.67.190.in-addr.arpa.
+rad.msn.com.
+www.asurline.com.ar.
+146.53.223.189.in-addr.arpa.
+im.rediff.com.
+dns.msftncsi.com.
+api-read.facebook.com.
+pagead2.googlesyndication.com.
+6to4.ipv6.microsoft.com.
+chomp.com.
+www.update.microsoft.com.
+g.live.com.
+photos-d.ak.fbcdn.net.
+dc336.4shared.com.
+ad-g.doubleclick.net.
+a.root-servers.net.
+rv.ginyas.com.
+i183.photobucket.com.
+themancavedaily.com.
+57.201.161.189.in-addr.arpa.
+hi-in.facebook.com.
+jobnetworks.com.
+www.xatech.com.
+ocsp.comodoca.com.
+safebrowsing-cache.google.com.
+131.209.95.76.in-addr.arpa.
+205.15.219.85.in-addr.arpa.
+s.sputnik.mail.ru.
+twitter.com.
+sct.com.
+photos-c.ak.fbcdn.net.
+games.9o9i.com.
+gissler-pass.de.
+photos-f.ak.fbcdn.net.
+filter1.gofast.mailplatform.co.uk.
+prisonpolicy.org.
+smart.montiera.com.
+37-courier.push.apple.com.
+210.131.149.186.in-addr.arpa.
+151.79.103.91.in-addr.arpa.
+photos-d.ak.fbcdn.net.
+wnep.com.
+devices.live.com.
+mail.owenpugh.com.
+ads.revsci.net.
+a.collective-media.net.
+remc11.k12.mi.ua.
+medrocktraining.co.uk.
+179.81.222.190.in-addr.arpa.
+cwwis.com.
+bitly.com.
+rad.msn.com.
+groups.google.com.
+.
+reports.gate2shop.com.
+222.1.143.189.in-addr.arpa.
+external.ak.fbcdn.net.
+1tiemposmodernos.blogspot.com.
+a.root-servers.net.
+184.228.234.188.in-addr.arpa.
+nogoingback-thereisonlyforward.blogspot.com.
+gdata.youtube.com.
+55.51.141.201.in-addr.arpa.
+yahoo.ca.
+a8.sphotos.ak.fbcdn.net.
+login.live.com.
+www.pepperjamnetwork.com.
+catalogphoto.goo-net.com.
+b.scorecardresearch.com.
+dc345.4shared.com.
+a4.sphotos.ak.fbcdn.net.
+a8.sphotos.ak.fbcdn.net.
+symresources.com.
+www.bing.com.
+www.youtube.com.
+s-static.ak.fbcdn.net.
+asociacionminga.org.
+tap2-cdn.rubiconproject.com.
+c-0.19-a3098481.483.1518.19d4.3ea1.210.0.lk3skchnhslkqeilqu72vadqzj.avqs.mcafee.com.
+studio-grad.ru.
+toysdownunder.com.
+42.48.56.200.in-addr.arpa.
+newhogwarts.mi-foro.es.
+26.240.72.189.in-addr.arpa.
+evsecure-crl.verisign.com.
+webcache.googleusercontent.com.
+www.google-analytics.com.
+www.tiendavirtualupb.com.
+47.20.145.189.in-addr.arpa.
+197.102.214.189.in-addr.arpa.
+70.244.177.189.in-addr.arpa.
+hq.umland.com.my.
+arteexpress.com.
+tc3.easythumbhost.com.
+hotmail.com.
+63.118.2.181.in-addr.arpa.
+www.reedpumps.com.
+www.bowers-wilkins.co.uk.
+shakerroad.pvt.k12.nh.us.
+92.11.185.187.in-addr.arpa.
+gastronomiayunapizca.blogspot.com.
+update.messenger.yahoo.com.
+158.85.11.186.in-addr.arpa.
+www.thumbs.lesbocollection.com.
+www.greenbrier.com.
+www.thekittenranch.com.
+tribune.ie.
+keramida.com.inbound10.mxlogic.net.
+apps.facebook.com.
+sdo.gsfc.nasa.gov.
+230.211.141.201.in-addr.arpa.
+csi.gstatic.com.
+fr-fr.facebook.com.
+www.armagetronad.net.
+platform.twitter.com.
+taxi-novaya-era.ru.
+fbcdn-sphotos-a.akamaihd.net.
+dr._dns-sd._udp.c.
+de-de.facebook.com.
+groups.google.com.mx.
+a.root-servers.net.
+www.9cloudsebookmarketingandpromotions.com.
+photos-e.ak.fbcdn.net.
+aca.quik.com.
+geo.tp-cdn.com.
+feedburner.google.com.
+www.stroitelstwo.ru.
+s2.youtube.com.
+core.caster.espn.go.com.
+mx.bluephoenixmedia.com.
+talkgadget.google.com.
+photos-c.ak.fbcdn.net.
+comcast.net.
+62.47.22.129.in-addr.arpa.
+www.genovabene.it.
+www.todoanimes.com.
+isatap.covad.net.
+122.169.44.81.in-addr.arpa.
+i1.ytimg.com.
+translate.googleapis.com.
+dns.msftncsi.com.
+ns1.v6.wow.lk.
+b-0.19-21090008.2020580.1518.19d3.3ea1.410.0.w63gpf5wia6jnshhq6na3bjhnj.avqs.mcafee.com.
+www.peaceteam.net.
+creative.ak.fbcdn.net.
+a6.sphotos.ak.fbcdn.net.
+static.ak.fbcdn.net.
+cyklingcarrier.com.
+feedburner.google.com.
+es-la.facebook.com.
+a.root-servers.net.
+smtp.historiador.eu.
+mail.womenclub.ru.
+a.root-servers.net.
+segment-pixel.invitemedia.com.
+redir.metaservices.microsoft.com.
+intohome.ru.
+www.alterway.fr.
+profile.ak.fbcdn.net.
+spectrumfiltration.com.
+video.google.com.
+mx.youtube.com.
+www.tviberica.net.
+mypearsonmobile.com.
+siriquestions.com.
+pt-br.facebook.com.
+www.alpsmountaineering.com.
+google.com.
+uploadkeep.com.
+api.twitter.com.
+profile.ak.fbcdn.net.
+developers.facebook.com.
+69.46.34.189.in-addr.arpa.
+a5.sphotos.ak.fbcdn.net.
+www.facebook.com.
+www.loccitane.ru.
+b-0.19-31005079.11081.1518.19d4.36d4.210.0.ngqff7bnf2tq9nf6itwpzrlje6.avqs.mcafee.com.
+77.250.58.83.in-addr.arpa.
+feeds.bbci.co.uk.
+95.33.249.77.in-addr.arpa.
+188.142.100.118.in-addr.arpa.
+art-inc.com.
+docs.google.com.
+www.google.com.mx.
+stickeen.com.
+a1294.w20.akamai.net.
+50.34.51.190.in-addr.arpa.
+logs.aiya.com.cn.
+cookex.amp.yahoo.com.
+dns.msftncsi.com.
+plus.google.com.
+searchclient.live.net.
+86.228.192.68.in-addr.arpa.
+www.john-cena-posters.com.
+willhill.vo.llnwd.net.
+a7.sphotos.ak.fbcdn.net.
+124.103.203.190.in-addr.arpa.
+s.gravatar.com.
+julesandjames.blogspot.com.
+certificates.starfieldtech.com.
+static.ak.fbcdn.net.
+docs.google.com.
+energistix.com.
+227.57.184.109.in-addr.arpa.
+1.223.74.212.in-addr.arpa.
+18.167.27.201.in-addr.arpa.
+mail.moryazilim.com.
+books.google.com.mx.
+sp.search-results.com.
+c-0.19-23095081.10023.1518.19d4.2f4a.210.0.1heevkgp7p8h9nzaareieu62mb.avqs.mcafee.com.
+videodown.baofeng.com.
+76.221.242.189.in-addr.arpa.
+annonse.sol.no.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+sdfsda.com.
+153.194.121.82.zz.countries.nerd.dk.
+a5.sphotos.ak.fbcdn.net.
+www.google.com.
+satair.com.
+feedproxy.google.com.
+google.com.
+www.tierradeviajes.com.
+linehaullogistics.com.
+9z4l:8mtf.y32v0b3f.
+comment.2008.sina.com.cn.
+liard.ru.
+barby08bsas.wordpress.com.
+sac.gti.mcafee.com.
+www.ver-pelis.net.
+67.87.131.189.in-addr.arpa.
+231.140.207.98.in-addr.arpa.
+espasa.es.
+uc.
+photos-b.ak.fbcdn.net.
+es-la.facebook.com.
+i.ytimg.com.
+a6.sphotos.ak.fbcdn.net.
+mail.mukhin.ru.
+profile.ak.fbcdn.net.
+vesta.ocn.ne.jp.
+home.live.com.
+ping.chartbeat.net.
+thumbs4.ebaystatic.com.
+www3.filthydatez.com.
+www.flickr.com.home.
+a2.sphotos.ak.fbcdn.net.
+qzone.qq.com.
+77.250.34.156.in-addr.arpa.
+mail.rus.net.
+entretenimiento.prodigy.msn.com.
+www.green.com.
+fimen.ru.
+178.229.114.189.in-addr.arpa.
+powaypopwarner.com.
+fwjolp:89.84ll.
+fatsofa.com.
+mx1.sed.ru.
+199.218.56.79.in-addr.arpa.
+nzbirds.com.
+arabinform.com.
+ads.tlvmedia.com.
+wd-edge.sharethis.com.
+91.31.81.186.in-addr.arpa.
+tv.gsp.ro.
+twitter.com.
+plantayflor.blogspot.com.
+207.92.140.189.in-addr.arpa.
+www.hotmail.com.
+gfx3.hotmail.com.
+a.root-servers.net.
+a5.sphotos.ak.fbcdn.net.
+hotmail.com.
+bedrosiantile.com.
+dnl-01.geo.kaspersky.com.
+247.230.213.83.in-addr.arpa.
+trackedbyet.info.
+mirdetstva.ru.
+static.ak.fbcdn.net.
+www-qporama-805569008.eu-west-1.elb.amazonaws.com.
+34.11.20.92.in-addr.arpa.
+100.35.30.190.in-addr.arpa.
+rx6z9n69v.o96j5y8p.
+a2.sphotos.ak.fbcdn.net.
+162.240.49.190.in-addr.arpa.
+www.spanish-food.org.
+a.root-servers.net.
+api.twitter.com.
+verify.speedbit.com.
+ax.search.itunes.apple.com.
+86.225.48.174.in-addr.arpa.
+media3.picsearch.com.
+www.cupoint.com.
+cloudsync.dm.origin.com.
+svetservice.ru.
+a995.mm1.akamai.net.
+www.efd.admin.ch.
+153.97.65.173.in-addr.arpa.
+118.122.236.123.in-addr.arpa.
+americantelnet.com.
+forum.anlaids.org.
+api.twitter.com.
+www.juegos.com.es.
+dnl-01.geo.kaspersky.com.
+www.twitter.com.
+0-149.channel.facebook.com.
+75.36.48.85.in-addr.arpa.
+www.mbaup.com.au.
+s3.amazonaws.com.
+static.ak.fbcdn.net.
+199.149.47.187.in-addr.arpa.
+db._dns-sd._udp.0.1.168.192.in-addr.arpa.
+a3.da1.akamai.net.
+lp.longtailvideo.com.
+b-0.19-220af089.10081.1518.19d4.3ea1.410.0.fckzbrmw6r9bt5bw42zjr48d7j.avqs.mcafee.com.
+www.torinofc.it.
+clinique-la-casamance.fr.
+76.29.134.189.in-addr.arpa.
+maps.google.com.
+apps.facebook.com.
+www.duslerforum.org.
+www.youtube.com.
+dns.msftncsi.com.
+www.facebook.com.
+clients2.google.com.
+mail.next.ru.
+leaedbf9j.u82w1k9c.
+a5.sphotos.ak.fbcdn.net.
+mail2.shelby-sheriff.org.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+css.wlxrs.com.
+91.10.68.189.in-addr.arpa.
+134.12.53.186.in-addr.arpa.
+teredo.ipv6.microsoft.com.
+img100.xvideos.com.
+www.youtube.com.
+www.astroaficion.com.
+clients1.google.com.
+bhsi.com.
+www.google.com.
+ad.yieldmanager.com.
+developers.facebook.com.
+i2.ytimg.com.
+connect.facebook.net.
+th.wikipedia.org.
+232.186.183.189.in-addr.arpa.
+adserving.cpxinteractive.com.
+246.126.51.201.in-addr.arpa.
+www.admissions.ualberta.ca.
+u4world.com.
+gaiafile.com.
+a.root-servers.net.
+141.151.253.201.in-addr.arpa.
+e566.b.akamaiedge.net.
+curiouskangaroos.blogspot.com.
+www.linkedin.com.
+downloads.networkmagic.com.
+static-css.veevr.com.
+www.tuifly.com.
+a1.sphotos.ak.fbcdn.net.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+www.delees.com.
+hswenterprises.com.
+pop3.hot.glbdns.microsoft.com.
+a8.sphotos.ak.fbcdn.net.
+www.turbochargers.com.
+35.153.232.85.in-addr.arpa.
+65.0.113.68.in-addr.arpa.
+widgets.amung.us.
+i3.ytimg.com.
+www.chandrakclarke.com.
+euro.mediotiempo.com.
+55.13.168.192.in-addr.arpa.
+prontarepa.com.
+dmcritchie.mvps.org.
+static.ak.fbcdn.net.
+143.153.121.200.in-addr.arpa.
+www.nadieesperfecto.com.
+www.wetenschapsforum.nl.
+consorcio.ru.
+www.mercadolibre.com.mx.
+239.210.16.177.in-addr.arpa.
+www.amazon.de.
+www.paradisecoin.com.
+77.41.83.177.in-addr.arpa.
+kabuco.de.
+rs.sinajs.cn.
+shamrockmanagementllc.com.
+mz7xi8w2i.i21f8v5r.
+196.94.238.41.in-addr.arpa.
+apis.google.com.
+time.chttl.com.tw.
+google.com.
+oss.ticketmaster1st.akadns.net.
+biblhertz.it.
+foil.ru.
+a4.sphotos.ak.fbcdn.net.
+developers.facebook.com.
+veldkamp.net.
+api-public.addthis.com.
+assetverification.com.
+bbns.org.
+lh3.googleusercontent.com.
+creative.myspace.com.
+lumbermens.com.s7a1.psmtp.com.
+teas-star.com.
+www.fuerzasdeelite.com.
+img32.imageshack.us.
+profile.ak.fbcdn.net.
+203.50.19.186.in-addr.arpa.
+hardrock.starcite.com.
+s-external.ak.fbcdn.net.
+dnl-03.geo.kaspersky.com.
+dia-net.ru.
+www.onlyamateursteens.com.
+sro.whatsapp.net.
+dns.msftncsi.com.
+www.usadanceshoes.com.
+loopingrecursion.com.
+156.65.203.190.in-addr.arpa.
+civic-club.ru.
+www.update.microsoft.com.
+basilisk.cebix.net.
+ad-g.doubleclick.net.
+www.bcr.gob.sv.
+hdvysxvvb.64fx.
+static.ak.fbcdn.net.
+time.chttl.com.tw.
+www.youtube.com.
+mobilepet-ii-monkey.softonic.com.
+166.141.185.78.in-addr.arpa.
+documentalesdehistoria.blogspot.com.
+233.176.46.186.in-addr.arpa.
+182.113.171.201.in-addr.arpa.
+241.158.49.190.in-addr.arpa.
+img2.uploadhouse.com.
+a4.sphotos.ak.fbcdn.net.
+a1.sphotos.ak.fbcdn.net.
+www.facebook.com.
+artistalife.com.
+profile.ak.fbcdn.net.
+developers.facebook.com.
+a.root-servers.net.
+linux.softpedia.com.
+es-la.facebook.com.
+freecyberbabes.clickyou.com.
+att.net.
+40-courier.push.apple.com.
+cumbiadenegros.net.
+180.136.26.216.in-addr.arpa.
+gfx3.hotmail.com.
+bemega.com.
+a5.sphotos.ak.fbcdn.net.
+www.thebigassblog.com.
+a4.sphotos.ak.fbcdn.net.
+nuevomundochile.cl.
+a7.sphotos.ak.fbcdn.net.
+rulezfag.narod.ru.
+dnl-01.geo.kaspersky.com.
+maps.google.com.
+vestidos-de-15-anos1.blogspot.com.
+electrowiki.wikidot.com.
+www.youtube.com.
+fr.mcafee.com.
+dawnuk.net.
+geometricglobal.com.
+metrociti.com.
+www.youtube.com.
+fbcdn-sphotos-a.akamaihd.net.
+secure.wlxrs.com.
+hardwaresphere.com.
+photos-e.ak.fbcdn.net.
+www.gaymapbuenosaires.com.
+gfx2.hotmail.com.
+apps.facebook.com.
+www.tikilive.com.
+aosnotify.mac.com.
+images.instagram.com.
+dart.l.doubleclick.net.
+94.55.194.190.in-addr.arpa.
+s-static.ak.fbcdn.net.
+250.92.63.200.in-addr.arpa.
+apps.facebook.com.
+cr.starmedia.com.
+assets.tp-cdn.com.
+images02.olx.com.
+sklka.ru.
+t1.gstatic.com.
+eccbuffalo.com.
+dns.msftncsi.com.
+a1.sphotos.ak.fbcdn.net.
+knowjr.com.
+myoasis.colum.edu.
+142.14.188.190.in-addr.arpa.
+0-292.channel.facebook.com.
+s.ytimg.com.
+ocsp.verisign.com.
+a1739.phobos.apple.com.
+graph.facebook.com.
+1.34.33.190.in-addr.arpa.
+www.google-analytics.com.
+www.weather.com.
+20.140.19.186.in-addr.arpa.
+a.root-servers.net.
+hotchyx.com.
+sites.google.com.
+e-2dj6wjliwidjibp.stats.esomniture.com.
+www.despegar.com.ar.
+www.pogo.com.
+wiki.cihar.com.
+www.cleopatraescorts.es.
+translate.googleapis.com.
+www.molehillempire.ro.
+a.root-servers.net.
+www.datadesignsb.com.
+hombredetuvida.blogspot.com.
+a-0.19-a3091081.d1b0082.1518.19d2.3ea1.410.0.qpaiisl2c21jk14tcibq1mcv6t.avqs.mcafee.com.
+a.root-servers.net.
+smpweb.com.inbound10.mxlogicmx.net.
+killerglass.com.
+ib.adnxs.com.
+photos-b.ak.fbcdn.net.
+gdata.youtube.com.
+gs-loc.apple.com.
+174.31.201.67.in-addr.arpa.
+53.217.237.98.in-addr.arpa.
+websitetrafficspy.com.
+wilmarinc.com.inbound15.mxlogicmx.net.
+m.youtube.com.
+www.teengirlgirl.com.
+www.advanceddermatologypc.com.
+lk023.info.
+host2.sandlotgames.com.
+152.221.111.193.in-addr.arpa.
+www.delish.com.
+a.root-servers.net.
+ci.kk.dk.
+mail.hardwaretech.ru.
+www.genolevures.org.
+asia.perf.glbdns.microsoft.com.
+facebook.farmville.com.
+proekt-cvetnik.ru.
+ws.tapjoyads.com.
+www.masalacism.com.
+id.google.com.mx.
+5.103.31.186.in-addr.arpa.
+211.228.49.190.in-addr.arpa.
+st.kendincos.com.
+79.185.158.189.in-addr.arpa.
+68.20.19.186.in-addr.arpa.
+cltetg.com.s8b1.psmtp.com.
+blog.trade.gov.
+24.169.138.75.in-addr.arpa.
+rincondeunescritor.ticoblogger.com.
+118.162.41.114.in-addr.arpa.
+windowsphone.xbox.com.
+d24elmu442q75h.cloudfront.net.
+mail.redremo.com.
+i3.ytimg.com.
+_737_73_5.
+msginfo.rising.com.cn.
+207.4.157.201.in-addr.arpa.
+teikovo.tpi.ru.
+250.222.58.187.in-addr.arpa.
+medlux.ru.
+dns.msftncsi.com.
+maltanet.net.
+activitycheckv6.co.cc.
+vhsnewengland.com.s7b2.psmtp.com.
+b.scorecardresearch.com.
+fei.pro-market.net.
+hotmail.com.
+254.230.156.189.in-addr.arpa.
+cardwhacheng20.blogspot.com.
+external.ak.fbcdn.net.
+evsecure-ocsp.verisign.com.
+d.yimg.com.
+lox.lekool.com.
+ns3.emerson.com.
+documentamania.blogspot.com.
+243.183.146.217.in-addr.arpa.
+photos-b.ak.fbcdn.net.
+220.95.220.201.in-addr.arpa.
+external.ak.fbcdn.net.
+118.83.161.118.in-addr.arpa.
+b._dns-sd._udp.0.1.168.192.in-addr.arpa.
+www.google.com.
+140.196.165.46.in-addr.arpa.
+accounts.google.com.
+au.download.windowsupdate.com.
+226.128.139.187.in-addr.arpa.
+ad.yieldmanager.com.
+f6ilrdgkc.66mj.
+95.75.153.186.in-addr.arpa.
+babi.com.
+wherela.com.
+developers.facebook.com.
+mail.johan.com.my.
+ads.smowtion.com.
+pixel.facebook.com.
+no-replay.alertreceived.com.
+143.225.114.201.in-addr.arpa.
+63.34.77.190.in-addr.arpa.
+a.root-servers.net.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+www.onestophumour.com.
+crl.globalsign.net.
+tk2.greedland.net.
+www.cochesjuegos.net.
+www.internet-khazana.com.
+www.nbastore.com.
+db._dns-sd._udp.c.
+r.mzstatic.com.
+140.198.169.78.in-addr.arpa.
+17.233.22.1.in-addr.arpa.
+cdn-1.nflximg.com.
+gilco.com.
+platform.linkedin.com.
+136.215.96.121.in-addr.arpa.
+205.190.232.200.in-addr.arpa.
+teredo.ipv6.microsoft.com.
+www.green.com.
+teamasia.com.
+www.parchis.com.
+gad.about.com.
+a.root-servers.net.
+taawgh.com.
+profile.ak.fbcdn.net.
+opaygames.com.
+2.185.152.75.in-addr.arpa.
+68.105.238.220.in-addr.arpa.
+89.162.212.89.in-addr.arpa.
+a.root-servers.net.
+mail.anextour.com.
+laaldea.com.mx.
+gcdevelopment.ru.
+www.youtube.com.
+s-external.ak.fbcdn.net.
+t2.gstatic.com.
+112.157.222.189.in-addr.arpa.
+www.goldcoastpower.com.
+samsungvuiasr.vlingo.com.
+www.cochesrc.net.
+barracuda.kempervalve.com.
+classicalmusic.about.com.
+abcheck.com.s7b1.psmtp.com.
+tap-cdn.rubiconproject.com.
+179.31.168.192.in-addr.arpa.
+a1.sphotos.ak.fbcdn.net.
+trinitybrand.com.
+60.158.249.66.in-addr.arpa.
+www.mymelbournehomes.com.
+vdkltcxrqdnl.im.
+www.kiggr.com.
+235.5.243.201.in-addr.arpa.
+b._dns-sd._udp.0.2.168.192.in-addr.arpa.
+eros-expo.ru.
+a.root-servers.net.
+231.50.254.99.in-addr.arpa.
+tpb.tracker.thepiratebay.org.
+17.94.127.84.in-addr.arpa.
+a.root-servers.net.
+clients2.google.com.
+zh-cn.facebook.com.
+6.186.248.203.in-addr.arpa.
+161.133.166.109.in-addr.arpa.
+mail0.spinsoft.it.
+a151.d.akamai.net.
+a199.gi3.akamai.net.
+minecraftforo.foroactivo.net.
+a7.sphotos.ak.fbcdn.net.
+ic.tynt.com.
+photos-b.ak.fbcdn.net.
+182.231.194.187.in-addr.arpa.
+static.ak.fbcdn.net.
+docs.google.com.
+sa-live.com.
+ojodepez-fanzine.blogspot.com.
+teredo.ipv6.microsoft.com.
+mail.cityofeuclid.com.
+27.cim.meebo.com.
+local-bay.contacts.msn.com.
+www.goldenglowpaints.com.
+post-gazette.com.s5a1.psmtp.com.
+connect.facebook.net.
+owenton.rms.slb.com.
+gev.copi.ru.
+brandemali.ru.
+a.root-servers.net.
+253.35.23.4.in-addr.arpa.
+smtpgw-1.akhela.com.
+secure.moshimonsters.com.
+email-telekom.de.
+search.twitter.com.
+www.google.com.
+biejallth.sharkdunle.tm.
+www.realtime.net.
+creative.ak.fbcdn.net.
+photos-b.ak.fbcdn.net.
+1.static.sportspickle.cvcdn.com.
+fbcdn-sphotos-a.akamaihd.net.
+164.129.176.180.in-addr.arpa.
+59.249.178.190.in-addr.arpa.
+groups.live.com.
+photos-a.ak.fbcdn.net.
+extended-validation-ssl.verisign.com.
+www.dietriffic.com.
+loading1.widdit.com.
+www.whatithinkabout.com.
+elsigloweb.com.
+www.facebook.com.
+www.coinfactswiki.com.
+s2.youtube.com.
+imgboot.disqus.com.
+ad.xtendmedia.com.
+photos-g.ak.fbcdn.net.
+a6.sphotos.ak.fbcdn.net.
+www.brujadesalem.com.ar.
+dl.dropbox.com.
+ha18iv:8l.58db.
+iesa.com.br.
+07hd.com.
+roza.su.
+collectdolls.about.com.
+a2.sphotos.ak.fbcdn.net.
+www.connect.facebook.com.
+s0.2mdn.net.
+www.openbuildings.com.
+pixel.facebook.com.
+29.6.174.190.in-addr.arpa.
+www.usamail1.com.
+29.242.211.62.in-addr.arpa.
+photo.pic.sohu.com.
+de-de.facebook.com.
+mashable.com.
+www.chrisridley.co.uk.
+54.234.86.200.in-addr.arpa.
+akorus.com.
+www.maydaylivingbrands.com.
+assets2.henribendel.com.
+mail.wirx.com.
+74.38.172.189.in-addr.arpa.
+teredo.ipv6.microsoft.com.
+130.247.158.189.in-addr.arpa.
+a5.sphotos.ak.fbcdn.net.
+act.presente.org.
+3v95bc9wz.97cm.
+a4.sphotos.ak.fbcdn.net.
+www.facebook.com.
+photos-g.ak.fbcdn.net.
+papercraft.jhonsryo.com.
+a6.sphotos.ak.fbcdn.net.
+static.tlavideo.com.
+suppliers.chinacommodity.net.
+facebook.dirtydancingresort.com.
+ar.wikipedia.org.
+fnpbzxuwe.c73d1q2e.
+www.gees.org.
+santiago.clasificadosgratis.cl.
+www.segurosvip.com.
+checkip.dyndns.com.
+cqpz17y9a.f33w3w9i.
+www.pos-software.org.
+35.28.91.187.in-addr.arpa.
+photos-h.ak.fbcdn.net.
+0.11-a70e7079.83.1518.18a4.3ea1.210.0.ed1ii45j1ghkf9v3q6pmlamarq.avqs.mcafee.com.
+checkip.dyndns.com.
+profissaodentista.com.br.
+beta.stun.voice.yahoo.com.
+a.root-servers.net.
+mscrl.microsoft.com.
+newportsteel.com.
+log.client.akadns.net.
+apps.bittorrent.com.
+profile.ak.fbcdn.net.
+212.131.79.189.in-addr.arpa.
+safebrowsing.clients.google.com.
+www.spycars.net.
+www.anarchyonline.com.
+100.30.206.24.in-addr.arpa.
+168.130.174.189.in-addr.arpa.
+srv2.wa.marketingsolutions.yahoo.com.
+pagead2.googlesyndication.com.
+b._dns-sd._udp.0.1.168.192.in-addr.arpa.
+teredo.ipv6.microsoft.com.
+www.suchsmallportions.com.
+www.buenamusica.com.
+wctatel.net.
+sniper1.skec.co.kr.
+rs617l3.rapidshare.com.
+m.facebook.com.
+api.conduit.com.
+photos-h.ak.fbcdn.net.
+unahotels.it.
+assets.informador.com.mx.
+_085_65_6.
+s.youtube.com.
+a5.sphotos.ak.fbcdn.net.
+a5.sphotos.ak.fbcdn.net.
+hd21.xiaonei.com.
+www.facebook.com.
+pt-br.facebook.com.
+www.facebook.com.
+netscape.net.
+grandfantasia.aeriagames.com.
+addisonboot.com.
+114.191.63.187.in-addr.arpa.
+i2.ytimg.com.
+224.250.83.62.in-addr.arpa.
+a.root-servers.net.
+www.facebook.com.
+apps.facebook.com.
+bigtimerushlatino.com.
+orcart.facebook.com.
+rp.gwallet.com.
+63.3.129.186.in-addr.arpa.
+128.0.168.192.in-addr.arpa.
+www.facebook.com.
+222.114.0.186.in-addr.arpa.
+120.0.168.192.in-addr.arpa.
+www.evenpro.com.ar.
+koolmobile.net.
+gwfpower.com.
+246.244.18.190.in-addr.arpa.
+mail.scotcom.com.au.
+ygame.gy9y.com.
+ksn.cc.
+129.70.210.189.in-addr.arpa.
+www.enladisco.tv.
+img1.gamespotcdn.com.
+ns02.nexthost.nl.
+photos-d.ak.fbcdn.net.
+twitter.com.
+a.root-servers.net.
+londonlux.com.inbound15.mxlogic.net.
+66.1.201.201.in-addr.arpa.
+www.facebook.com.
+col.stc.s-msn.com.
+photos-d.ak.fbcdn.net.
+static.ak.fbcdn.net.
+242.252.33.189.in-addr.arpa.
+k7.ru.
+cyril.almeras.free.fr.
+mfiane.com.s8a1.psmtp.com.
+dns.msftncsi.com.
+ssl.gstatic.com.
+224.207.203.190.in-addr.arpa.
+p01-keyvalueservice.icloud.com.
+csi.gstatic.com.
+a.root-servers.net.
+api.twitter.com.
+profile.ak.fbcdn.net.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+google.com.
+ars.icq.com.
+a286.w31.akamai.net.
+ad.yieldmanager.com.
+lifespan.com.au.
+bibank-msk.ru.
+coolwalls.awardspace.com.
+ithinkso.listal.com.
+torrentclub.su.
+vmx.lcturbonet.com.redcondor.net.
+53.141.193.186.in-addr.arpa.
+230.206.230.60.in-addr.arpa.
+a.root-servers.net.
+www.google-analytics.com.
+uktechnologyresources.com.
+pagead2.googlesyndication.com.
+dns.msftncsi.com.
+115.115.27.46.in-addr.arpa.
+www.smuckers.com.mx.
+arunsag.wordpress.com.
+haru-ka.net.
+us.data.toolbar.yahoo.com.
+88.35.133.86.zz.countries.nerd.dk.
+sofortuberweisung.de.
+wpad.
+transmedics.com.
+www.bravospots.com.
+ec.atdmt.com.
+99.69.59.85.in-addr.arpa.
+pxty.ru.
+www.tumix.ru.
+165.1.168.192.in-addr.arpa.
+photos-d.ak.fbcdn.net.
+a.root-servers.net.
+t2.gstatic.com.
+plus.google.com.
+photos-b.ak.fbcdn.net.
+www.totalplay.com.mx.
+m.hotmail.com.
+successpax.ru.
+dr._dns-sd._udp.domain.name.
+a3.sphotos.ak.fbcdn.net.
+connectads.com.
+xzqcw3vmu.37td.
+col.stb00.s-msn.com.
+thesymbianblog.com.
+mail.nettsoft.no.
+133.120.107.190.in-addr.arpa.
+carlossanmiguel23.blogspot.com.
+hickel.at.
+connect.facebook.net.
+113.160.102.218.in-addr.arpa.
+www.extremetube.com.
+141.49.77.190.in-addr.arpa.
+julius.lookbook.nu.
+www.thinktechno.com.
+api-read.facebook.com.
+euro.mediotiempo.com.
+cdn-6.pics.keezpremium.com.swiftcdn1.com.
+190.237.114.186.in-addr.arpa.
+en.wikipedia.org.
+download772.avast.com.
+scribe.twitter.com.
+photos-a.ak.fbcdn.net.
+56.88.12.99.in-addr.arpa.
+www.facebook.com.
+www.ticketmaster.com.mx.
+22.224.171.69.in-addr.arpa.
+facemoods.com.
+teredo.ipv6.microsoft.com.
+www.google.com.
+3cluaocri.y57x9a9m.
+a6.sphotos.ak.fbcdn.net.
+b.static.ak.fbcdn.net.
+www.google.com.
+profile.ak.fbcdn.net.
+uniklinikum-dresden.de.
+www.rough-sex-in-russia.com.
+developers.facebook.com.
+www.elgranhost.com.
+www.youtube.com.
+mail.logicbytes.com.
+a.root-servers.net.
+68.128.245.77.in-addr.arpa.
+dns.msftncsi.com.
+s.youtube.com.
+39.195.35.187.in-addr.arpa.
+profile.ak.fbcdn.net.
+tilera.com.inbound15.mxlogic.net.
+profile.ak.fbcdn.net.
+www.airportparkingreservations.com.
+a1725.l.akamai.net.
+a.root-servers.net.
+ads1.msads.net.
+api.webrep.avast.com.
+13.8.38.187.in-addr.arpa.
+www.medela.com.
+mcgoye.com.s6b2.psmtp.com.
+www.livefilipinacams.com.
+www.bikeit.co.uk.
+c-0.19-a30ff081.70481.1518.19d3.3ea1.210.0.4vlzs791h9blm6ibv261d8ja7j.avqs.mcafee.com.
+profile.ak.fbcdn.net.
+timberfinec.com.
+s4.histats.com.
+b.scorecardresearch.com.
+sn1msg3020319.gateway.messenger.live.com.
+_122_32_9.
+psp3.pagesuite.com.
+es.foursquare.com.
+iphone-wu.apple.com.
+i2.ytimg.com.
+telecoms-mag.com.
+78.57.15.50.in-addr.arpa.
+gfx2.hotmail.com.
+advertise.sakura.ne.jp.
+hawaaworld.net.
+developers.facebook.com.
+rs989dt.rapidshare.com.
+6.255.54.187.in-addr.arpa.
+s0.2mdn.net.
+www.invisionpower.com.
+va4en.sftcdn.net.
+www.facebook.com.
+www.chiclana.es.
+www.thedailystar.net.
+www.3tailer.com.
+srvupi.inforonda.com.
+www.facebook.com.
+img.perezhilton.com.
+www.youtube.com.
+productshopnyc.com.
+relay.mplik.ru.
+www.bywifi.com.
+deblinux.files.wordpress.com.
+images.colehaan.com.
+a5.sphotos.ak.fbcdn.net.
+www.listainmuebles.com.
+et6.xhamster.com.
+www.kbresource.com.
+_214_83_1.
+66.226.132.190.in-addr.arpa.
+a.ads2.msads.net.
+mx.mujer.yahoo.com.
+www.goodfoodshow.com.au.
+leercadadiaalgo.blogspot.com.
+ib.adnxs.com.
+188.223.248.201.in-addr.arpa.
+194.121.135.189.in-addr.arpa.
+img13.imagemaniac.com.
+a1.sphotos.ak.fbcdn.net.
+234.170.76.94.in-addr.arpa.
+193.188.114.93.in-addr.arpa.
+media.tumblr.com.
+www.adobe.com.
+zqn2ghhtj.39os.
+pinclub.hardrock.com.
+fetdn6qis.36cg.
+aoadns1.nestle.com.
+ee.iitd.ernet.in.
+41.2.237.189.in-addr.arpa.
+photos-c.ak.fbcdn.net.
+photos-h.ak.fbcdn.net.
+cdn1.widdit.com.
+plusone.google.com.
+238.179.86.122.in-addr.arpa.
+0.10.27.125.in-addr.arpa.
+ww2.supergt.net.
+js2.wlxrs.com.
+c.prodigy.msn.com.
+toolbarqueries.google.com.
+orcart.facebook.com.
+a.root-servers.net.
+www.theladylikes.com.
+s0.2mdn.net.
+www.google-analytics.com.
+pagead2.googleadservices.com.
+pixel.facebook.com.
+61.140.93.186.in-addr.arpa.
+www.metrolyrics.com.
+webacom.com.
+193.103.126.187.in-addr.arpa.
+127.97.193.187.in-addr.arpa.
+dl-ssl.google.com.
+photos-a.ak.fbcdn.net.
+ssl.gstatic.com.
+db._dns-sd._udp.lan.
+www.google-analytics.com.
+158.150.158.189.in-addr.arpa.
+www.youtube-nocookie.com.
+236.129.57.186.in-addr.arpa.
+openxfront.iminent.com.
+e3353.c.akamaiedge.net.
+im20.gulfup.com.
+d3k9hgzf8ej9hc.cloudfront.net.
+www.elblogdemontaner.com.
+mx.ipera.net.au.
+basketball.com.
+s.mobclix.com.
+puntacondor.com.
+a107.ui5g0.akafms.net.
+google.com.
+www.youtube.com.
+juegosonline.com.
+jobs.myfoxorlando.com.
+dnl-01.geo.kaspersky.com.
+owa.framinghamma.gov.
+s.ytimg.com.
+:qe:qk37k.84ng.
+mamanluisa.blogspot.com.
+www.breatheheavy.com.
+stats.buysellads.com.
+www.vongo.com.
+a.root-servers.net.
+www.mozilla.com.
+et9.xhamster.com.
+culinarytravel.about.com.
+www.sexaben.dk.
+71.192.239.85.in-addr.arpa.
+www.sagemcom.com.
+www.youtuberepeater.com.
+cm.g.doubleclick.net.
+89.38.101.92.in-addr.arpa.
+www.laughteryoga.org.
+a.root-servers.net.
+www.fandino.net.
+pixel.quantserve.com.
+a1174.g.akamai.net.
+www.google-analytics.com.
+armadatd.ru.
+smtp2.crescentstatebank.com.
+i1.ytimg.com.
+nav3.poker.zynga.com.
+photos-f.ak.fbcdn.net.
+clubdefansdeloganhenderson.globered.com.
+talk.m5zn.com.
+photos-e.ak.fbcdn.net.
+groups.google.com.
+origin.url.trendmicroip.chinacache.net.
+apps.facebook.com.
+pagead2.googlesyndication.com.
+gambit.blogs.nytimes.com.
+srv2.tv-stream.to.
+b.scorecardresearch.com.
+teambstudio.com.
+30.70.247.88.in-addr.arpa.
+a7.sphotos.ak.fbcdn.net.
+toitoninte.museum.
+img.discovery.com.
+free-desktop-backgrounds.info.
+photos-e.ak.fbcdn.net.
+www.williamgibsonbooks.com.
+a5.sphotos.ak.fbcdn.net.
+secure-us.imrworldwide.com.
+bersconstructores.com.
+mail.blackhillsvacations.com.
+www.espacioparalelo.com.
+a.root-servers.net.
+tools.google.com.
+61.45.134.188.in-addr.arpa.
+www.x2music.com.
+188.147.172.189.in-addr.arpa.
+adserving.cpxadroit.com.
+profile.ak.fbcdn.net.
+relay.voice.edge.messenger.live.com.
+1.117.23.190.in-addr.arpa.
+pontevedra.campusanuncios.com.
+70.227.127.201.in-addr.arpa.
+18.51.145.189.in-addr.arpa.
+www.meinvmtv.com.
+mail.google.com.
+mscrl.microsoft.com.
+a8.sphotos.ak.fbcdn.net.
+www.remov.es.
+www.lastfm.es.
+130.8.135.105.in-addr.arpa.
+208.209.222.90.in-addr.arpa.
+blackw.msk.ru.
+bijouterieyaccesoriosmr.blogspot.com.
+89.55.132.187.in-addr.arpa.
+www.physics.org.
+199.149.35.211.in-addr.arpa.
+forum.sh3bwah.maktoob.com.
+translate.googleapis.com.
+www.taobao.com.
+netozero.net.
+goolocal.com.mx.
+kstu.ru.
+cloudflare.com.
+m.facebook.com.
+i1.ytimg.com.
+dellaceramica.ru.
+external.ak.fbcdn.net.
+tsgconsumer.com.s8b1.psmtp.com.
+cl30-179-182-213.cl.metrocom.ru.
+a.root-servers.net.
+www.imdb.com.
+a1.sphotos.ak.fbcdn.net.
+99.213.22.190.in-addr.arpa.
+56.154.66.190.in-addr.arpa.
+.
+go.microsoft.com.
+l3tga7:8x.87xg.
+client79.dropbox.com.
+scholar.google.com.
+placaazul.org.
+www.corner-college.com.
+1.bp.blogspot.com.
+www.spankwire.com.
+223.248.111.87.in-addr.arpa.
+24.156.147.79.in-addr.arpa.
+photos-d.ak.fbcdn.net.
+www.milesbinz-shipping.com.
+25.191.32.190.in-addr.arpa.
+clients1.google.com.
+a-0.19-35097001.d010583.1518.19d4.36d4.210.0.bs1jd7se11i96w8mdfnsn57wiq.avqs.mcafee.com.
+mail.supermetal.com.
+56.95.124.78.in-addr.arpa.
+mail.ilscargogroup.com.
+cccservices.com.
+214.96.117.200.in-addr.arpa.
+mail.unelko.com.
+telus.inq.com.
+ptd.net.
+192.205.246.88.in-addr.arpa.
+www.facebook.com.
+www.prompyme.gob.pe.
+a1.sphotos.ak.fbcdn.net.
+service.collarity.com.
+ads.lfstmedia.com.
+www.albemarle-london.com.
+mail.mwaarchitects.com.
+apis.google.com.
+s2.youtube.com.
+a4.sphotos.ak.fbcdn.net.
+widgets.fbshare.me.
+84.197.160.187.in-addr.arpa.
+t.co.
+elquepiensagana.wordpress.com.
+httpcs.msg.yahoo.com.
+photos-a.ak.fbcdn.net.
+145.170.124.59.in-addr.arpa.
+creative.ak.fbcdn.net.
+www.mltailor.com.
+btech.ac.th.
+ns2.dns26.net.
+red-stripe.info.
+drunkula.blogspot.com.
+wzeu.uk.ask.com.
+google.com.
+ns3.cemex.com.
+wirelescefard.com.
+www.jscount.com.
+96.133.211.201.in-addr.arpa.
+www.aclunc.org.
+khm1.google.co.id.
+www.csir.res.in.
+fznz44zgn.64jg.
+www.webcamsexo.info.
+diretorio.tol.pro.br.
+195.112.169.62.in-addr.arpa.
+192.31.159.189.in-addr.arpa.
+ourfamilyrealm.com.
+b._dns-sd._udp.0.130.16.172.in-addr.arpa.
+b._dns-sd._udp.0.0.168.192.in-addr.arpa.
+trophy01.np.community.playstation.net.
+181.201.18.187.in-addr.arpa.
+www.xnet.co.il.
+sigloxxb.blogspot.com.
+14.235.225.201.in-addr.arpa.
+googleads.g.doubleclick.net.
+www.howtomatter.com.
+thesecretgardenllc.com.
+a.root-servers.net.
+a.root-servers.net.
+groups.google.com.mx.
+www.lavidaesbeta.com.
+ns2-auth.teo.lt.
+2plpbgnox.72yo.
+cs510419.vkontakte.ru.
+r1rk9np7bpcsfoeekl0khkd2juj27q3o-a-fc-opensocial.googleusercontent.com.
+profile.ak.fbcdn.net.
+plusone.google.com.
+gsconco.com.
+www.humorvariado.com.
+11.246.25.89.in-addr.arpa.
+bbb.sp.f-secure.com.
+leahdawson.com.
+www.ldelgado.es.
+0-jg-w.channel.facebook.com.
+hnequwxsjtumpsrk.com.
+primarycarellc.net.
+sunrise-sakhalin.ru.
+123.128.95.108.in-addr.arpa.
+a.root-servers.net.
+www.adobe.com.
+b.scorecardresearch.com.
+chowvegan.com.
+photos-b.ak.fbcdn.net.
+col.stj.s-msn.com.
+img.mail.ru.
+cgi.chatvibes.com.
+safebrowsing.clients.google.com.
+needformadness.wikia.com.
+a8.sphotos.ak.fbcdn.net.
+cdn.missuniverse.com.
+mail.mrbank.ru.
+translate.twttr.com.
+www.skycig.co.uk.
+digg.com.
+p.hostingprod.com.
+www.juegosvertigo.com.
+kphpb.com.
+creative.ak.fbcdn.net.
+billsgarage.com.
+a771.da1.akamai.net.
+30.168.33.71.in-addr.arpa.
+29.230.182.189.in-addr.arpa.
+i6.expansys.com.
+a1.sphotos.ak.fbcdn.net.
+js2.wlxrs.com.
+photos-f.ak.fbcdn.net.
+www.causewaymall.com.
+photoshopto4ka.net.ru.
+388.com.
+tsk.tulask.ru.
+www.shimritshoshan.com.
+www.danzabuenosaires.com.ar.
+view.atdmt.com.
+a.root-servers.net.
+117.229.177.190.in-addr.arpa.
+132.208.136.186.in-addr.arpa.
+www.sexofree.com.br.
+mingjitang.com.
+e2799.e7.akamaiedge.net.
+88.83.151.120.in-addr.arpa.
+a5.sphotos.ak.fbcdn.net.
+feedback.yandex.ru.
+pixel.facebook.com.
+www.vibramfivefingers.com.
+i.kissmetrics.com.
+pop3.hot.glbdns.microsoft.com.
+mailserver.mehfilmatch.com.
+www.naabt.org.
+map.wwiionline.com.
+retardmedia.com.
+131.146.171.201.in-addr.arpa.
+d2105804.xoom.it.
+www.nortonstore.kr.
+trialgraphic.com.inbound15.mxlogic.net.
+f5-mail.digitalvm.com.
+a.root-servers.net.
+dns.msftncsi.com.
+a.root-servers.net.
+msk.suek.ru.
+www.xkisses.com.
+profile.ak.fbcdn.net.
+ynpndcevents.org.
+insatiable.gotop100.com.
+www.venta-por-catalogo.com.ar.
+www.gstatic.com.
+s2.youtube.com.
+malluhotvideos.in.
+lindawallpapers.appspot.com.
+81.18.168.192.in-addr.arpa.
+135.246.34.99.in-addr.arpa.
+es-es.facebook.com.
+mitecnologico.com.
+l-bank.de.
+www.redtube.com.
+www.arabiccalligrapher.com.
+lomira.k12.wi.us.
+www.ashleytisdale.com.
+37.241.160.201.in-addr.arpa.
+i144.photobucket.com.
+www.lacocinadepili.com.
+mail.live.com.
+mejores-videos-internet.blogspot.com.
+25.153.168.192.in-addr.arpa.
+www.lunatic-films.com.
+notsomekid.com.
+affiliates.x10hosting.com.
+letib.com.
+servicemap.conduit-services.com.
+uppod.ru.
+54.53.198.190.in-addr.arpa.
+43.243.212.98.in-addr.arpa.
+49.106.9.88.in-addr.arpa.
+platform.twitter.com.
+www.feedburner.com.
+lgg.it.
+www.ft.com.
+www.myspace.com.
+www.painspanking.com.
+a.root-servers.net.
+aeiengr.com.pri-mx.smtproutes.com.
+exchange.storkcraft.com.
+a.root-servers.net.
+kundert.com.s10a1.psmtp.com.
+ytimg.com.bl.open-whois.org.
+177.42.251.85.in-addr.arpa.
+tdspedjgh.25lu.
+a.root-servers.net.
+mail.maristes.net.
+conquest.91.com.
+www.vh1la.com.
+218.84.174.189.in-addr.arpa.
+www.ultramar.cl.
+pixel.facebook.com.
+mail.sohu.com.
+sn21.mailshell.net.
+global.ard.yahoo.com.
+www.topfashionb2b.com.
+creative.ak.fbcdn.net.
+ksn2-12.kaspersky-labs.com.
+127.156.143.187.in-addr.arpa.
+auscredits.com.au.
+32.47.149.187.in-addr.arpa.
+static.ak.facebook.com.
+mail.banvenez.com.
+api.twitter.com.
+a26.ms.akamai.net.
+a-0.19-a309b081.d090082.1518.19d4.3ea1.410.0.9c5ieabp7eivvapescd2b8tdkb.avqs.mcafee.com.
+new.pagegangster.com.
+s-static.ak.facebook.com.
+tbr.ask.com.
+creative.ak.fbcdn.net.
+75.118.49.60.in-addr.arpa.
+my.unisa.ac.za.
+ad-g.doubleclick.net.
+eir.turningtechnologies.com.
+my6fjeksh.y57m8z6v.
+buscoempleo.anuncioneon.com.
+mail.chanterellenyc.com.
+adobe-acrobat.software.informer.com.
+external.ak.fbcdn.net.
+domain.mail.yandex.net.
+tunnel.cfw.trustedsource.org.
+worldclassicautos.com.
+accounts.google.com.
+www.mangaid.com.
+www-fc-opensocial.googleusercontent.com.
+www.allgigs.co.uk.
+apis.google.com.
+www.baidu.com.
+a.root-servers.net.
+infinitedangers.com.
+anindiansummer-design.blogspot.com.
+0-271.channel.facebook.com.
+sc2.rules.mailshell.net.
+www.youtube.coml.
+90.23.168.192.in-addr.arpa.
+exchange.chalmersgroup.com.
+photos-a.ak.fbcdn.net.
+peliculassi.com.
+bym-fb-lbns.dc.kixeye.com.
+bt.rghost.net.
+.
+piaoan.en.alibaba.com.
+fxfeeds.mozilla.com.
+cdn.tynt.com.
+netanday.it.
+router.infolinks.com.
+www.google.com.
+134.144.137.201.in-addr.arpa.
+static.ak.fbcdn.net.
+accounts.google.com.
+external.ak.fbcdn.net.
+ccrcanada.com.s9a1.psmtp.com.
+.
+www.bakumens.com.
+a.root-servers.net.
+soft.export.yandex.ru.
+www.facebook.com.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+ailtel.net.
+gadgets-for-men.net.
+safebrowsing-cache.google.com.
+biteme.net.
+ratings-wrs.symantec.com.
+180.136.177.78.in-addr.arpa.
+searchclient.live.net.
+ksn1-12-part2.kaspersky-labs.com.
+www.google.com.
+www101.jimdo.com.
+s1-04.twitpicproxy.com.
+it-it.facebook.com.
+api.zynga.com.
+s247.hotfile.com.
+ksn2-12.kaspersky-labs.com.
+www.cnnchile.com.
+i4.ytimg.com.
+www.dequienes.com.
+215.121.195.123.in-addr.arpa.
+mail.ci.ceres.ca.us.
+www.trafficswarm.com.
+tuc8nquw2.z88a1w0a.
+paradoxfive.blogspot.com.
+178.77.202.81.in-addr.arpa.
+c7.zedo.com.
+sites.google.com.
+pu3dcnwg1.y94b7g6g.
+vz.com.ru.
+pool.ntp.org.
+campodelturia.fadlan.com.
+rocknet.net.au.
+it.italyculture.it.
+mx.astrology.yahoo.com.
+ksn2-12.kaspersky-labs.com.
+a5.sphotos.ak.fbcdn.net.
+s.ytimg.com.
+mail.icix.com.
+www.facebook.com.
+www.salesianosvaldivia.cl.
+a.root-servers.net.
+168.85.91.190.in-addr.arpa.
+ssp-p.com.
+www.adobe.com.
+profile.ak.fbcdn.net.
+a8.sphotos.ak.fbcdn.net.
+tap2-cdn.rubiconproject.com.
+photos-h.ak.fbcdn.net.
+google.com.
+reald.com.
+a.root-servers.net.
+db._dns-sd._udp.0.1.168.192.in-addr.arpa.
+124.149.255.201.in-addr.arpa.
+www.elcorillord.co.
+110.80.29.186.in-addr.arpa.
+s2.youtube.com.
+lumpeny.com.
+a8.sphotos.ak.fbcdn.net.
+weather.service.msn.com.
+s-external.ak.fbcdn.net.
+a.root-servers.net.
+tudi.com.inbound15.mxlogicmx.net.
+e5168.g.akamaiedge.net.
+www.dragspecialties.com.
+clkads.com.
+europolitics.info.
+a.root-servers.net.
+157.101.236.190.in-addr.arpa.
+a7.sphotos.ak.fbcdn.net.
+145.150.206.196.in-addr.arpa.
+beeskow.de.
+bouleafacettes.biz.
+pf.u.51img1.com.
+www.miltontwins.in.
+rs-e.com.
+78.78.209.190.in-addr.arpa.
+co104w.col104.mail.live.com.
+youtubedownload.altervista.org.
+office.microsoft.com.
+www.archiportfolio.com.
+nowmco.com.
+populus.es.msn.com.
+teredo.ipv6.microsoft.com.
+a5.sphotos.ak.fbcdn.net.
+static.ak.fbcdn.net.
+gw0.suite224.net.
+164.145.47.60.in-addr.arpa.
+177.238.247.190.in-addr.arpa.
+s2.youtube.com.
+coylehospitality.com.
+game1.netmarble.net.
+a2.sphotos.ak.fbcdn.net.
+sunbeam.ru.
+content.yieldmanager.edgesuite.net.
+travelmateonline.com.
+yn9h6y2y1.q13f2e3a.
+107.1.168.192.in-addr.arpa.
+memtracker.appspot.com.
+www.make1c.com.
+botanov.net.
+dns.msftncsi.com.
+s7.addthis.com.
+a.root-servers.net.
+db._dns-sd._udp.lan.
+pda.mv.bidsystem.com.
+tweetmeme.com.
+s.ytimg.com.
+a5.sphotos.ak.fbcdn.net.
+27.206.185.67.in-addr.arpa.
+qspbaztwaaf.com.
+www.gstatic.com.
+static.ak.fbcdn.net.
+dns.msftncsi.com.
+www.minitokyo.net.
+pt-br.facebook.com.
+bluemoon.softonic.com.
+www.diariodeboadilla.es.
+_006_44_2.
+twitter.com.
+pixel.indieclick.com.
+128.166.167.189.in-addr.arpa.
+137.39.130.186.in-addr.arpa.
+01.myjewishpage.com.
+213.111.112.190.in-addr.arpa.
+g811d3181c5bb4cfd.api.playtomic.com.
+www.comprar-ofertas.com.
+pro5.livebooks.com.
+i1.ytimg.com.
+a.root-servers.net.
+twitter.com.
+101.139.227.190.in-addr.arpa.
+i.imgur.com.
+widgets.serverboy.net.
+check4.facebook.com.
+41.117.173.118.in-addr.arpa.
+apicultura.wikia.com.
+202.138.10.94.in-addr.arpa.
+_648_85_2.
+181.229.137.85.in-addr.arpa.
+rentcash.ca.
+181.21.244.190.in-addr.arpa.
+mail.jesseengineering.com.
+188.128.239.76.in-addr.arpa.
+revistalamision.es.tl.
+mail.abstinence.net.
+api.prod.capptain.com.
+dr._dns-sd._udp.0.0.168.192.in-addr.arpa.
+kathyawai.com.
+greenearthjourney.blogspot.com.
+dominicano.ru.
+googleads.g.doubleclick.net.
+www.e-messenger.net.
+p9nnqaq9n.35zt.
+_070_81_1.
+static-resource.np.community.playstation.net.
+www.google-analytics.com.
+vcs2.msg.yahoo.com.
+rad.msn.com.
+6.158.28.186.in-addr.arpa.
+29-courier.push.apple.com.
+cfectiva.cfe.gob.mx.
+lb._dns-sd._udp.lan.
+sp.cwfservice.net.
+200.229.42.181.in-addr.arpa.
+mail.rcmclean.com.
+254.232.145.186.in-addr.arpa.
+.
+www.iskullgames.com.
+accounts.google.com.
+pinttars.miscaricaturas.com.
+bb.dev.bbvms.com.
+v21.nonxt8.c.youtube.com.
+thebostonchannel.com.
+mx.msn.recepedia.com.
+www.modoo.es.
+integration.fellowshipone.com.
+a5.sphotos.ak.fbcdn.net.
+wilshirebank.com.
+thumb5.webshots.net.
+test-rt.liftdna.com.
+starving4myperfection.blogspot.com.
+www.facebook.com.
+inerdisc.com.
+18.91.218.186.in-addr.arpa.
+es.meetic.yahoo.net.
+media.trafficjunky.net.
+st8.live800.com.
+a5.sphotos.ak.fbcdn.net.
+cdn.larepublica.pe.
+27.72.91.186.in-addr.arpa.
+c.es.msn.com.
+www.probass.net.
+35.105.179.190.in-addr.arpa.
+ssl.gstatic.com.
+messagent.concentra.be.
+dm-download02.mozilla.org.home.
+mardi09.wordpress.com.
+shela.ru.
+p04-imap.mail.me.com.
+131.105.149.187.in-addr.arpa.
+www.coolermaster.com.
+view.atdmt.com.
+us1153dom12.nam.slb.com.
+bestspb.ru.
+a7.sphotos.ak.fbcdn.net.
+a.root-servers.net.
+petitforestier.fr.
+iwashige.com.inbound15.mxlogicmx.net.
+www.todotorrents.com.
+c13.zedo.com.
+82.74.10.186.in-addr.arpa.
+2.210.62.68.in-addr.arpa.
+ssl.gstatic.com.
+gfx6.hotmail.com.
+af.acuraprint.com.
+games.yahoo.com.
+loading5.widdit.com.
+www.dailytubevideos.com.
+apps.facebook.com.
+80.132.113.190.in-addr.arpa.
+www.utilisima.com.
+static.ak.fbcdn.net.
+correo.aprosi.net.
+a3.sphotos.ak.fbcdn.net.
+mail.google.com.
+gartsports.com.
+79.69.227.213.in-addr.arpa.
+www.be-still.com.au.
+anticd.ru.
+guia.planetajoy.com.
+sixpackshortcuts.com.
+a7.sphotos.ak.fbcdn.net.
+fbcdn-profile-a.akamaihd.net.
+e906.g.akamaiedge.net.
+anobanooo.blogspot.com.
+streamlky.alsolnet.com.
+szddfe389.i00r1x3p.
+skedm01.cn.diodes.com.
+www.facebook.com.
+usadatanet.net.
+developers.facebook.com.
+www.australia.edu.
+mx4.hotmail.com.
+www.20minutos.es.
+147.146.9.72.bl.spamcop.net.
+time.chttl.com.tw.
+www.unvm.edu.ar.
+www.territorioenemigo.net.
+74.180.123.99.in-addr.arpa.
+cdn1.widdit.com.
+dreamspr.com.
+s.youtube.com.
+39.156.235.189.in-addr.arpa.
+gam.adnxs.com.
+photos-f.ak.fbcdn.net.
+agddf8fk5.47uy.
+allcovered.com.s6a2.psmtp.com.
+feeds.feedburner.com.
+pixel.facebook.com.
+58.211.129.186.in-addr.arpa.
+www.tylermedicalclinic.com.
+www.leve.su.
+events.theledger.com.
+scribe.twitter.com.
+static.ak.fbcdn.net.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+beta.stun.voice.yahoo.com.
+22.45.77.89.in-addr.arpa.
+uscm.med.sc.edu.
+yahoo.com.
+www.theworkofthepeople.com.
+a.root-servers.net.
+lightros.ru.
+126.18.202.189.in-addr.arpa.
+www.freshlookcontacts.com.
+134.67.169.62.in-addr.arpa.
+01-1.store.lh.embed.ro.
+o1.inviziads.com.
+foofus.com.
+smithplc.com.
+107.36.154.189.in-addr.arpa.
+157.252.133.187.in-addr.arpa.
+a.root-servers.net.
+alwehda.net.
+94.38.57.186.in-addr.arpa.
+flashembed.xvideos.com.
+i.qype.com.
+hi-in.facebook.com.
+165.107.37.92.in-addr.arpa.
+thechengman.spreadshirt.com.
+www.annemurray.net.au.
+www.facebook.com.
+www.pluralworld.com.
+static.crakcash.com.
+oascentral.babble.com.
+1.0.0.127.dnsbugtest.1.0.0.127.in-addr.arpa.
+comtelspa.com.
+www.facebook.com.
+spotify-windows-mobile.softonic.com.
+www.funnyjunksite.com.
+www.gruposmusicalesparroquiales.org.
+plus.google.com.
+171.216.139.189.in-addr.arpa.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+photos-h.ak.fbcdn.net.
+dns.msftncsi.com.
+www.vpsland.com.
+static.ak.fbcdn.net.
+respond2u.com.
+row.bc.yahoo.com.
+117.159.162.190.in-addr.arpa.
+crl.microsoft.com.
+www.facebook.com.
+m.ebags.com.
+a3.sphotos.ak.fbcdn.net.
+a8.sphotos.ak.fbcdn.net.
+mailj.sml.com.
+draftfcb.co.il.
+plus.google.com.
+www-google-analytics.l.google.com.
+www.footbo.com.
+fxfeeds.mozilla.com.
+80.52.81.108.in-addr.arpa.
+s-external.ak.fbcdn.net.
+www.facebook.com.
+www.facebook.com.
+frontlinedirectinc.com.
+plusone.google.com.
+hash.orbitdownloader.com.
+qb20bgpatch.quickbooks.com.
+www.cancer.org.
+yaironline.wordpress.com.
+motorcycledesktopwallpaper.blogspot.com.
+www.facebook.com.
+copystationinc.com.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+www.csd.toshiba.com.
+182.98.250.189.in-addr.arpa.
+mx00.1and1.es.
+mscrl.microsoft.com.
+p.ebaystatic.com.
+9.42.203.24.in-addr.arpa.
+maltanet.net.
+www.xbox360chat.com.
+219.167.103.189.in-addr.arpa.
+7.126.248.189.in-addr.arpa.
+fstongfang.en.alibaba.com.
+www.adgenie.co.uk.
+clkads.com.
+100.129.136.186.in-addr.arpa.
+32.11.181.189.in-addr.arpa.
+tas.orangeads.fr.
+190.29.168.192.in-addr.arpa.
+www.wrenkitchens.com.
+thclibrary.net.
+www.supercheats.com.
+kona.kontera.com.
+secure.shared.live.com.
+tedchin.com.
+abtco.ru.
+ascg.com.
+dnl-01.geo.kaspersky.com.
+mail.universalcargo.net.
+enter.mofosworldwide.com.
+s-static.ak.fbcdn.net.
+d1.openx.org.
+who.bumpmyip.net.
+najera-javimanzanares.blogspot.com.
+profile.microsoft.com.
+wzus1.search-results.com.
+s1-powerpoint.vo.msecnd.net.
+167.64.230.190.in-addr.arpa.
+rostini.ru.
+mininghouse.com.
+careers.microsoft.com.
+forsaleadsonline.com.
+ad.harrenmedianetwork.com.
+www.facebook.com.
+www.natrue.org.
+developers.facebook.com.
+ksn1-11-part2.kaspersky-labs.com.
+static.ak.fbcdn.net.
+mail.wynhg.com.
+apps.facebook.com.
+www.fabulouscuties.com.
+teplohodmaestro.ru.
+btguard.com.
+www.addthis.com.
+a5.sphotos.ak.fbcdn.net.
+mail.nahalat.ru.
+login.dotomi.com.
+google.com.
+dr._dns-sd._udp.0.55.211.10.in-addr.arpa.
+broadcast.infomaniak.ch.
+profile.ak.fbcdn.net.
+cdn1.certified-apps.com.
+acewallpapers.com.
+bitly.com.
+dns.msftncsi.com.
+b._dns-sd._udp.0.1.168.192.in-addr.arpa.
+poigraemtut.ru.
+tap2-cdn.rubiconproject.com.
+6-1.qlty.finarea.ch.
+www.cuevana.com.
+gearsofwar.wikia.com.
+appworld.blackberry.com.
+dc339.4shared.com.
+www.facebook.com.
+a.root-servers.net.
+a.root-servers.net.
+mailno.actasone.com.
+fbcdn-profile-a.akamaihd.net.
+cs933.vk.com.
+ic.tynt.com.
+www.bcvo.co.za.
+abslogic.ru.
+mail.trexta.com.
+acti.ru.
+110.142.179.189.in-addr.arpa.
+a2.twimg.com.
+1.0.0.127.dnsbugtest.1.0.0.127.in-addr.arpa.
+ihg-chicago.jobs.
+kkqx2lxi1.o17f4m5b.
+tomhumphrey.commaureen.
+kuq4ogt5:.33sv.
+www.google-analytics.com.
+borel.com.
+www.um.edu.mx.
+201.107.73.178.in-addr.arpa.
+179.56.25.190.in-addr.arpa.
+c-0.19-430cc069.20001.1518.19d4.2f4a.210.0.9ditbwm77wrkfpjqfdfg51fndv.avqs.mcafee.com.
+crl.microsoft.com.
+a.root-servers.net.
+www.choate.edu.
+terra.com.br.
+okbz:zqhe.d61a5o8h.
+www.google.com.
+cdn2-pivotaltracker.pantherssl.com.
+a6.sphotos.ak.fbcdn.net.
+vgpmuaqgp.76nc.
+mail.sppkk.ru.
+palletone.com.
+photos-g.ak.fbcdn.net.
+74.43.15.187.in-addr.arpa.
+img713.imageshack.us.
+25.199.65.190.in-addr.arpa.
+lb._dns-sd._udp.lan.
+121.75.208.190.in-addr.arpa.
+pixel.facebook.com.
+relay.ast-ins.ru.
+1d.media.v4.skyrock.net.
+s.youtube.com.
+www.greentradebay.com.
+www.cctv.com.
+a6.sphotos.ak.fbcdn.net.
+search.conduit.com.
+dotaplayer.net.
+mt1.google.com.
+img.intelihealth.com.
+www.trafficholder.com.
+mail.aplusnet.hu.
+bentelhalal.maktoob.com.
+220.24.85.200.in-addr.arpa.
+a1856.da1.akamai.net.
+translate.google.com.
+aragon.es.
+lonelyweb.net.
+www.xvideoslive.com.
+external.ak.fbcdn.net.
+splob.com.
+voicevale-fr.com.
+218.7.55.190.in-addr.arpa.
+83.56.92.186.in-addr.arpa.
+129.131.96.190.in-addr.arpa.
+mail.resole.com.
+0.11-a70a2219.80110b3.1518.197d.3ea1.210.0.95wbuu72j1uq5nkuipia8wtjki.avqs.mcafee.com.
+banners.datenation.com.
+www.facebook.com.
+wap.hao123.com.
+49.78.38.187.in-addr.arpa.
+dns.msftncsi.com.
+64.185.10.187.in-addr.arpa.
+184.82.92.65.in-addr.arpa.
+a.root-servers.net.
+accounts.google.com.
+tm0.blackberry.net.
+221.86.6.95.in-addr.arpa.
+news.google.com.
+117.68.200.14.in-addr.arpa.
+vskmsd1kg.p63b8b0a.
+www.crunchbase.com.
+afc-holcroft-com.relay1a.spamh.com.
+a.root-servers.net.
+trsoft.ru.
+44.1.168.192.in-addr.arpa.
+view2.picapp.com.
+photos-g.ak.fbcdn.net.
+cs109.vk.com.
+mail.kmztech.ru.
+a3.sphotos.ak.fbcdn.net.
+pubads.g.doubleclick.net.
+bookapp.book.qq.com.
+www.facebook.com.
+liveupdate.gocyberlink.com.
+www.berkshirefinearts.com.
+report.bitdefender.com.
+anthrotech.com.
+_338_94_0.
+www.youtube.com.
+photos-g.ak.fbcdn.net.
+a.root-servers.net.
+0-staging.channel.facebook.com.
+cdn.mediafire.com.
+raptr.com.
+er9rjiy18.k85b6o2z.
+www.raulrico.com.
+apps.facebook.com.
+ashland.navy.mil.
+172.36.74.66.in-addr.arpa.
+www.intel.com.
+www.plasticprinters.com.
+accountservices.msn.com.
+a.root-servers.net.
+profile.ak.fbcdn.net.
+a8.sphotos.ak.fbcdn.net.
+178.186.50.83.in-addr.arpa.
+174.23.205.190.in-addr.arpa.
+dr._dns-sd._udp.0.55.211.10.in-addr.arpa.
+piratesofarchery.net.
+1stmediasolutions.com.
+teredo.ipv6.microsoft.com.
+bs.serving-sys.com.
+profile.ak.fbcdn.net.
+26.175.50.190.in-addr.arpa.
+i4.ytimg.com.
+photos-c.ak.fbcdn.net.
+www.adobe.com.
+es-la.facebook.com.
+aish.edu.
+www.playgames.to.
+alerts.conduit-services.com.
+content.yieldmanager.edgesuite.net.
+safebrowsing.clients.google.com.
+110.252.198.190.in-addr.arpa.
+230.67.183.189.in-addr.arpa.
+fls.doubleclick.net.
+manualforyou.ru.
+www.trlaser.com.
+apps.facebook.com.
+asoc-fulbright.es.
+profile.ak.fbcdn.net.
+api.recaptcha.net.
+teredo.ipv6.microsoft.com.
+rushpostcardprinting.com.
+205.18.134.189.in-addr.arpa.
+photos-h.ak.fbcdn.net.
+food-junky.blogspot.com.
+en.wikipedia.org.
+a.root-servers.net.
+developers.facebook.com.
+mail.shades-technics.com.
+ping.chartbeat.net.
+api16.thetrafficstat.net.
+peoplepccc.com.
+facemoods.com.
+de.tynt.com.
+apis.google.com.
+www.facebook.com.
+i2.ytimg.com.
+ip2.shi.com.
+a2.sphotos.ak.fbcdn.net.
+www.google-analytics.com.
+uptus.oilnet.ru.
+ec2-us-east-1a.cedexis.com.
+tools.l.google.com.
+list-new.ru.
+ns19.worldnic.com.
+38.125.133.190.in-addr.arpa.
+b-0.19-a300a008.c831580.1518.19d4.3ea1.410.0.jq1blb8q3pgzggvftm9bcmkf1t.avqs.mcafee.com.
+b._dns-sd._udp.0.1.168.192.in-addr.arpa.
+a.root-servers.net.
+b.scorecardresearch.com.
+www.aeivalencia.com.
+bs.serving-sys.com.
+cdn.metanetworkslider.com.
+34.115.170.209.in-addr.arpa.
+www.usbwifi.orcon.net.nz.
+bpy.wikipedia.org.
+www.coveylink.com.
+www.jlsd.org.
+107.100.164.189.in-addr.arpa.
+43.200.49.201.in-addr.arpa.
+dns.msftncsi.com.
+mail.yimg.com.
+external.ak.fbcdn.net.
+www.articleinfoblog.com.
+ellipsiz.com.s7a1.psmtp.com.
+99.99.175.189.in-addr.arpa.
+a.root-servers.net.
+cs4930.vk.com.
+a.rad.msn.com.
+231.201.242.60.in-addr.arpa.
+fsarecruitment.com.au.
+www.datacredito.com.co.
+47.89.156.189.in-addr.arpa.
+ocsp.verisign.com.
+46.180.201.200.in-addr.arpa.
+161.153.79.200.in-addr.arpa.
+services.xboxlive.com.
+a2.sphotos.ak.fbcdn.net.
+biebernovelastu.metroblog.com.
+adsfront.iminent.com.
+pagead2.googlesyndication.com.
+mscrl.microsoft.com.
+a5.sphotos.ak.fbcdn.net.
+156.237.25.201.in-addr.arpa.
+home.ru.
+edgesuperstar.blogspot.com.
+mail.climatedesign.com.
+oprint.ru.
+0-264.channel.facebook.com.
+americaninsulators.com.bak-mx.na0106.smtpbak.com.
+photos-c.ak.fbcdn.net.
+studentmailcenter.com.
+au:dcz3my.m19i0g0q.
+165.169.19.84.in-addr.arpa.
+a.root-servers.net.
+104.209.178.186.in-addr.arpa.
+www.pssl.com.
+estatestore.org.
+teredo.ipv6.microsoft.com.
+matcher-apx.bidder7.mookie1.com.
+audiest.es.
+88.12.159.189.in-addr.arpa.
+t2.gstatic.com.
+alerts.conduit-services.com.
+www.woow.ro.
+59.223.7.187.in-addr.arpa.
+42.29.11.186.in-addr.arpa.
+a1725.l.akamai.net.
+todoloquegira.blogspot.com.
+yilmen.com.
+www.phocos.com.
+_377_12_6.
+apps4u2.conduitapps.com.
+www.adonistwinks.com.
+9li38:nbn.72wb.
+desiclub.in.
+www.curriculum-web.com.
+sturgillturner.com.1.arsmtp.com.
+210.145.131.187.in-addr.arpa.
+tomm.ru.
+sites.google.com.
+www.bootyliciousink.com.
+b-0.19-a309b008.1481.1518.19cd.3ea1.410.0.j1rph37chqkbzjqrvfif1wb1zi.avqs.mcafee.com.
+platio.ru.
+googleads.g.doubleclick.net.
+www.facebook.com.
+www.mejoresfrases.net.
+fbcdn-photos-a.akamaihd.net.
+www.cnn.com.
+filmgordon.wordpress.com.
+photos-h.ak.fbcdn.net.
+tyco-fire.com.
+164.239.160.201.in-addr.arpa.
+mail2.cabledahmer.com.
+nice.dealply.com.
+listserv.utk.edu.
+forum.downloadhelper.net.
+googleads.g.doubleclick.net.
+a82.photo.store.qq.com.
+www.shadowflames.us.
+174.156.151.190.in-addr.arpa.
+24.224.51.190.in-addr.arpa.
+162.157.233.125.in-addr.arpa.
+a.root-servers.net.
+dnl-05.geo.kaspersky.com.
+www.autopistas.com.mx.
+platform.ak.fbcdn.net.
+shamrockrealtors.com.
+abawaba.com.
+220.175.244.88.in-addr.arpa.
+pricebazaar.in.
+miproconsulting-com.relay1c.spamh.com.
+neilduckett.com.
+a.root-servers.net.
+141.190.18.182.in-addr.arpa.
+120.150.22.186.in-addr.arpa.
+a.root-servers.net.
+www.tumblr.com.
+photos-d.ak.fbcdn.net.
+mx3.lasredes.net.
+dns.msftncsi.com.
+240.135.233.221.in-addr.arpa.
+www.hackforums.net.
+new.york.eventguide.com.
+db._dns-sd._udp.0.1.168.192.in-addr.arpa.
+www.carrefour.com.ar.
+_ldap._tcp.
+_766_69_2.
+linkhelp.clients.google.com.
+a.root-servers.net.
+www.clubfayerunaway.com.
+ejabat.google.com.
+a.root-servers.net.
+a.root-servers.net.
+147.231.97.76.in-addr.arpa.
+anoush.com.s9a1.psmtp.com.
+189.87.37.190.in-addr.arpa.
+i.ytimg.com.
+fonts.googleapis.com.
+milagrofunding.com.
+185.153.52.186.in-addr.arpa.
+use.typekit.com.
+www.facebook.com.
+a87a36d8.linkbucks.com.
+photos-f.ak.fbcdn.net.
+a.root-servers.net.
+messages.recon.com.
+gio162.wordpress.com.
+www.adxpansion.com.
+236.182.118.200.in-addr.arpa.
+ntp1.dlink.com.
+b._dns-sd._udp.0.0.168.192.in-addr.arpa.
+a.root-servers.net.
+www.google.com.
+sz8.tencent.com.
+38.208.174.201.in-addr.arpa.
+74.3.72.50.in-addr.arpa.
+79.220.151.12.in-addr.arpa.
+rsmiami.com.
+photos-c.ak.fbcdn.net.
+platform.twitter.com.
+mail.stollamerica.com.
+s.ytimg.com.
+a.root-servers.net.
+www.aqabazone.com.
+accountservices.msn.com.
+photos-d.ak.fbcdn.net.
+8.108.186.190.in-addr.arpa.
+johndawsoninsurance.com.pri-mx.smtproutes.com.
+search.softonic.com.
+ads.pubmatic.com.
+plus.google.com.
+poll.hotlayouts2u.com.
+profile.ak.fbcdn.net.
+partners.socialvi.be.
+au.download.windowsupdate.com.
+o49cq3xz6.49ny.
+mail.netorn.ru.
+static.ak.fbcdn.net.
+mariokart64.com.
+idealegc.com.br.
+static.ak.fbcdn.net.
+static.ak.facebook.com.
+a.root-servers.net.
+36.49.73.187.in-addr.arpa.
+www.peiweiblog.com.
+www.gstatic.com.
+msgate.wdl.loral.com.
+pagead2.googlesyndication.com.
+www.facebook.com.
+nkrumah.net.
+primatrading.com.
+101.5.189.201.in-addr.arpa.
+carawalsh.com.
+api.twitter.com.
+twitter.com.
+tools.google.com.
+config.conduitapps.com.
+icm.ginyas.com.
+d2100485.xoom.it.
+microplan.de.
+60.134.195.187.in-addr.arpa.
+www.carphototutorials.com.
+smalltakeover.blogspot.com.
+bounderds.com.
+www.youtube.com.
+clients1.google.com.
+197.22.192.108.in-addr.arpa.
+pics5.madthumbscdn.com.
+sharethis.com.
+videodownloads.o2.co.uk.
+download802.mediafire.com.
+byfiles.storage.msn.com.
+shealink.com.s7a1.psmtp.com.
+photos-b.ak.fbcdn.net.
+ad.yieldmanager.com.
+chat.facebook.com.
+www.adobe.com.
+131.224.215.186.in-addr.arpa.
+blog.heartsonfire.com.
+heparin.com.
+a3.sphotos.ak.fbcdn.net.
+xonoxlabs.com.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+167.130.126.75.in-addr.arpa.
+89.237.42.200.in-addr.arpa.
+ksn1-12-part2.kaspersky-labs.com.
+234.141.223.80.in-addr.arpa.
+152.203.191.188.in-addr.arpa.
+cdn.api.twitter.com.
+108.231.248.201.in-addr.arpa.
+static.ak.fbcdn.net.
+241.248.192.190.in-addr.arpa.
+www.deborahkingcenter.com.
+www.cineticket.com.mx.
+hotmail.com.
+knight.com.jo.
+ptcnet.net.s6b2.psmtp.com.
+hk.arthurandersen.com.
+pudfaceup.paran.com.
+ebrochazos.blogspot.com.
+201.31.220.192.in-addr.arpa.
+www.kustomcoachwerks.com.
+www.rhymezone.com.
+www.bicaramakdara.com.
+lockwoodpublications.com.s5b2.psmtp.com.
+www.teniaquedecirlo.com.
+lyris.asmestaff.org.
+cutmp3.net.
+www.facebook.com.
+skydrive.live.com.
+s-external.ak.fbcdn.net.
+venezuela.yaclasificados.com.
+columbustax.net.
+www.facebook.com.
+asg.gershmanbrown.com.
+a.root-servers.net.
+a.root-servers.net.
+avarady.files.wordpress.com.
+fxfeeds.mozilla.com.
+news.commscope.com.
+a.root-servers.net.
+jailbreak-me.info.
+static.ak.fbcdn.net.
+www.speedtest.gr.
+ropavieja72.blogspot.com.
+www.shopbando.com.
+fbcdn-photos-a.akamaihd.net.
+shared.live.com.
+a.root-servers.net.
+search.treasuretrooper.com.
+saincsa.com.
+beacon-1.newrelic.com.
+scholar.google.com.
+profile.ak.fbcdn.net.
+www.facebook.com.
+226.13.139.74.in-addr.arpa.
+250.205.168.90.in-addr.arpa.
+231.32.116.46.in-addr.arpa.
+nobee.jefferson.lib.la.us.
+a.root-servers.net.
+194.5.166.190.in-addr.arpa.
+i-cdn.servedbyopenx.com.
+_913_35_4.
+pixel.facebook.com.
+111.188.8.200.in-addr.arpa.
+mi.adinterax.com.
+m.facebook.com.
+1.map.pop6.com.
+s7.addthis.com.
+www.poraqui.net.
+sro.whatsapp.net.
+cettente.com.
+mail.belnet.ru.
+www.google.com.
+bn.rstel.net.
+doug1izaerwt3.cloudfront.net.
+ocsp.usertrust.com.
+www.listablaze.com.
+troy.edu.
+yahoo.com.
+apps.facebook.com.
+healthtools.aarp.org.
+o-o.preferred.dfw06s10.v15.lscache1.c.youtube.com.
+a6.sphotos.ak.fbcdn.net.
+72.75.45.108.in-addr.arpa.
+alinvest.cz.
+a1067.phobos.apple.com.edgesuite.net.
+deepweb.spb.ru.
+www.juicyads.com.
+cdn.widgetserver.com.
+mail.ek-chor-cn.com.
+a995.mm1.akamai.net.
+www.lmp-adapter.com.
+preissturz24.com.
+i3.ytimg.com.
+www.connectmaster.org.
+profile.ak.fbcdn.net.
+www.facebook.com.
+www.google.se.
+www.92to.com.
+www.youtube.com.
+www.addthis.com.
+profile.ak.fbcdn.net.
+uvsk6ojda.q55x9y1r.
+creative.ak.fbcdn.net.
+mx3.westlothian.gov.uk.
+127.93.101.208.in-addr.arpa.
+a.root-servers.net.
+external.ak.fbcdn.net.
+228.245.25.86.in-addr.arpa.
+real-url.org.
+252.105.204.82.in-addr.arpa.
+news.newsmax.com.
+adamwestinc.com.
+e5016.b.akamaiedge.net.
+vvnkdlu.vlingo.com.
+celestica-catc.com.
+www.malwarepatrol.net.
+photos-f.ak.fbcdn.net.
+lacasadelritmo.net.
+11.245.173.70.in-addr.arpa.
+adserving.cpxinteractive.com.
+813562poj.01ov.
+m.addthisedge.com.
+printdirection.com.1.arsmtp.com.
+members.ebay.com.
+laoficina.blogsmyspace.es.
+www.mexicolaw.com.mx.
+.
+a.root-servers.net.
+www.tune-town.com.
+a2.sphotos.ak.fbcdn.net.
+insurancepill.com.
+s0.2mdn.net.
+a.root-servers.net.
+www.iacea.com.ar.
+wssecmgr2.atlanta.hp.com.
+www.colonirritable.com.ar.
+s0.2mdn.net.
+www.statcounter.com.
+kazna.spb.ru.
+fbcdn-profile-a.akamaihd.net.
+ru.wikipedia.org.
+photos-e.ak.fbcdn.net.
+a.root-servers.net.
+i3.ytimg.com.
+a8.sphotos.ak.fbcdn.net.
+s2.youtube.com.
+eu.wikipedia.org.
+a771.da1.akamai.net.
+www.facebook.com.
+www.google-analytics.com.
+144.178.94.201.in-addr.arpa.
+mx.yearginmetals.com.
+lucaspublicarena.blogspot.com.
+i275.photobucket.com.
+pagead2.googlesyndication.com.
+a.root-servers.net.
+upload.wikimedia.org.
+npi2.phys.msu.ru.
+11.177.92.91.in-addr.arpa.
+a3.sphotos.ak.fbcdn.net.
+a.root-servers.net.
+time-nw.nist.gov.
+client.akamai.com.
+80.201.191.186.in-addr.arpa.
+apir.webrep.avast.com.
+traffic.outbrain.com.
+wx1epls9s.v54n9z0d.
+omcdit.net.
+photos-a.ak.fbcdn.net.
+165.17.237.190.in-addr.arpa.
+espn.sl.advertising.com.
+7rivp9bhw.h88d8x7f.
+www.brothersoft.com.
+47.28.24.189.in-addr.arpa.
+loading2.widdit.com.
+www.noballs.co.uk.
+mail.myspa2go.com.
+www.ortizortizabogados.com.mx.
+diym2yidm.87hq.
+d.adroll.com.
+de.answers.yahoo.com.
+s-static.ak.facebook.com.
+dtboot.orbitdownloader.com.
+photos-g.ak.fbcdn.net.
+d2094192.xoom.it.
+cgenetwork.com.
+mx1.dici.ru.
+comstor.com.
+profile.ak.fbcdn.net.
+photos-a.ak.fbcdn.net.
+www.metalitalia.com.
+usersuz.newsvine.com.
+btinternbet.com.
+i2.ytimg.com.
+fr.wikipedia.org.
+111.139.130.27.in-addr.arpa.
+supernet.santander.com.uy.
+cdn1.image.keezmovies.phncdn.com.
+www.adobe.com.
+mx1.beget.ru.
+s.ytimg.com.
+mailgate.sebastianmclean.com.
+mail3.fibrogen.com.
+info.xvideos.com.
+www.sclerals.com.
+isohunt.com.
+prodigy.msn.com.
+host-delay.logmein-gateway.com.
+207.135.80.190.in-addr.arpa.
+0.docs.google.com.
+tiss.com.ru.
+www.apple.com.
+static.ak.fbcdn.net.
+musgara.ru.
+21.43.210.81.in-addr.arpa.
+streamerapi.finance.yahoo.com.
+col.stb00.s-msn.com.
+mailrelay.wernsing.de.
+49.75.42.114.in-addr.arpa.
+report.mpcstar.com.
+www.facebook.com.
+www.thesoapopera.com.
+a.root-servers.net.
+www.aardvarktopsitesphp.com.
+gamefilez.mofunzone.com.
+teredo.ipv6.microsoft.com.
+api.facebook.com.
+d2105399.xoom.it.
+apis.google.com.
+89.107.216.217.in-addr.arpa.
+configuration.apple.com.
+16.189.229.66.in-addr.arpa.
+www.facebook.com.
+ark-one.com.
+faisdodo.com.
+tecumsehindia.com.
+243.31.172.187.in-addr.arpa.
+a3.sphotos.ak.fbcdn.net.
+103.1.168.192.in-addr.arpa.
+184.185.110.189.in-addr.arpa.
+fizomed.ru.
+uac.advertising.com.
+download325.avast.com.
+crux.max-i-tec.net.
+explicit.fr.
+hamburgeramerica.blogspot.com.
+groups.google.com.mx.
+230.17.50.190.in-addr.arpa.
+0-257.channel.facebook.com.
+www.google-analytics.com.
+cshi.ru.
+fbcdn-profile-a.akamaihd.net.
+db2.stb01.s-msn.com.
+227.16.33.189.in-addr.arpa.
+mymail.sap.com.
+download330.avast.com.
+www.odnoklassniki.ru.
+uniquescrapdesigns.com.
+bin-short.whatsapp.net.
+earthlink.net.
+v11.nonxt5.c.youtube.com.
+www.mrmovietimes.com.
+s.amazon-adsystem.com.
+b.scorecardresearch.com.
+www.abamia.net.
+www.facebook.com.
+a.root-servers.net.
+4.bp.blogspot.com.
+gilpizano.com.
+gilchristconst.com.
+d15gt9gwxw5wu0.cloudfront.net.
+calendar.live.com.
+b._dns-sd._udp.lan.
+simsandcompany.com.
+sp.cwfservice.net.
+i4.ytimg.com.
+time.nist.gov.
+www.gstatic.com.
+teredo.ipv6.microsoft.com.
+rnxouxyq2.j76c7e5x.
+img1.123friendster.com.
+android.clients.google.com.
+a5.sphotos.ak.fbcdn.net.
+rorb:1mep.m48s7w6o.
+jzca371im.69jk.
+www.agronomia.uchile.cl.
+www.aqualabtechnologies.com.
+www.google.com.
+www.mibloglg.com.ar.
+mail.bankatlanticbancorp.com.
+openx.panet.co.il.
+photos-e.ak.fbcdn.net.
+243.174.173.189.in-addr.arpa.
+s-static.ak.fbcdn.net.
+urllol.
+es.optimost.com.
+a3.sphotos.ak.fbcdn.net.
+www.zonaganjah.net.
+a1.sphotos.ak.fbcdn.net.
+videosraros.info.
+media.doink.com.
+www.ftplive.com.
+ssl.google-analytics.com.
+images02.mundoanuncio.com.hn.
+h.live.com.
+156.213.30.79.in-addr.arpa.
+api.iheart.com.
+katiluv87.livejournal.com.
+cdn2.ads.datinggold.com.
+191.54.94.186.in-addr.arpa.
+german.alibaba.com.
+www.ornithology.com.
+ads.popconnex.com.
+dns.msftncsi.com.
+hurstlabeling.com.
+b._dns-sd._udp.0.1.168.192.in-addr.arpa.
+a4.sphotos.ak.fbcdn.net.
+db._dns-sd._udp.0.1.168.192.in-addr.arpa.
+a.root-servers.net.
+a.root-servers.net.
+a5.sphotos.ak.fbcdn.net.
+ads1.msn.com.
+bucaramanga.pegateya.com.
+249.133.191.186.in-addr.arpa.
+www.facebook.com.
+api.zynga.com.
+on.fb.me.
+www.adobe.com.
+hifiheadphones.co.uk.
+blog.beliefnet.com.
+www.google.com.
+_728_64_7.
+www.cardscanning.com.
+pubads.g.doubleclick.net.
+news.bbc.co.uk.
+a.root-servers.net.
+affiliates.tshirt-factory.com.
+26.media.tumblr.com.
+_386_97_6.
+www.acn.com.ve.
+conn.skype.com.
+fitness.meetup.com.
+skills.business.qld.gov.au.
+becnet.com.
+static.ak.fbcdn.net.
+sp.cwfservice.net.
+0-staging.channel.facebook.com.
+game.landsharkgames.com.
+www.elrinconderesu.com.
+market.android.com.
+artevanhautte.blogspot.com.
+feeds.animekon.com.
+www.periodico-eldia.com.
+static1.spilcdn.com.
+www.registrar.ucf.edu.
+www.propagandamatrix.com.
+www.google.com.
+www.scarletpress.com.
+connect.facebook.net.
+129.83.125.99.in-addr.arpa.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+mx2.russneft.ru.
+substanceabusefree.org.
+8.courier-sandbox-push-apple.com.akadns.net.
+www.grupoamor.com.
+0-ji-w.channel.facebook.com.
+apix.iminent.com.
+115.186.0.65.in-addr.arpa.
+time.chttl.com.tw.
+tradesecret.com.s9b1.psmtp.com.
+islam.makcdn.com.
+251.109.211.108.in-addr.arpa.
+mail.stvgkb4.ru.
+es-la.facebook.com.
+usns.uwingame.com.
+streamate.doublepimp.com.
+adspaces.ero-advertising.com.
+ads.cpxinteractive.com.
+132.181.205.190.in-addr.arpa.
+tietex.com.
+www.redaroa.org.
+en.gamescope.ru.
+creative.ak.fbcdn.net.
+222.164.159.189.in-addr.arpa.
+www.facebook.com.
+113.243.23.91.in-addr.arpa.
+v6.nonxt7.googlevideo.com.
+bonhumor.blog.com.
+17.89.231.189.in-addr.arpa.
+234.89.130.189.in-addr.arpa.
+mail.fmiint.com.
+berta4.simsim.ge.
+www.facebook.com.
+teredo.ipv6.microsoft.com.
+apis.google.com.
+shudbefishin.listal.com.
+moveon.org.
+shorouknews.com.
+webnesbay.com.
+dns.msftncsi.com.
+youtu.be.
+sakioneil.blogspot.com.
+abc.ojdinteractiva.com.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+b.scorecardresearch.com.
+105.66.110.189.in-addr.arpa.
+platform.twitter.com.
+glyphservices.com.
+adframes.iminent.com.
+114.112.153.114.in-addr.arpa.
+114.40.114.186.in-addr.arpa.
+150.74.164.190.in-addr.arpa.
+voxomat.com.
+oodweynenews.com.
+xksvzbytb.58pj.
+trailers.apple.com.
+a.root-servers.net.
+www.facebook.com.
+www.youtube.com.
+mmi.explabs.net.
+mail.legalemail.com.
+www.planetacurioso.com.
+124.74.134.187.in-addr.arpa.
+a.root-servers.net.
+fbcdn-photos-a.akamaihd.net.
+beta.stun.voice.yahoo.com.
+126.92.82.203.in-addr.arpa.
+isse.utk.edu.
+www.wallstein-verlag.de.
+www.google.com.
+profile.ak.fbcdn.net.
+sp.ask.com.
+img2.solocunts.com.
+conservacionyequidad.podomatic.com.
+content.yieldmanager.edgesuite.net.
+ksn2-12.kaspersky-labs.com.
+googleads.g.doubleclick.net.
+profile.ak.fbcdn.net.
+ip33.mebel-moskva.ru.
+www.baitandswitchtv.com.
+newsrss.bbc.co.uk.
+google.com.
+miamireia.com.
+b.scorecardresearch.com.
+a6.sphotos.ak.fbcdn.net.
+www.farmaervas.com.br.
+isvbqx.info.
+www.google-analytics.com.
+clients1.google.com.
+a749.g.akamai.net.
+fcv.org.
+apple-mobile.query.yahooapis.com.
+203.34.237.189.in-addr.arpa.
+159.76.222.189.in-addr.arpa.
+update.slimdevices.com.
+api.twitter.com.
+creative.ak.fbcdn.net.
+www.nikkijackson.com.
+exalead.ru.
+ds.serving-sys.com.
+developers.facebook.com.
+rest-img.msg.yahoo.com.
+3cpok.ru.home.
+media.trafficjunky.net.
+225.78.88.200.in-addr.arpa.
+79.132.160.187.in-addr.arpa.
+www.asiagames.com.
+pixel.facebook.com.
+232.85.41.189.in-addr.arpa.
+www.google.com.
+0-155.channel.facebook.com.
+ahsl.ca.
+www.google.com.mx.
+twitter.com.
+hiphopcanario.com.
+toolbarqueries.clients.google.com.
+118.60.125.69.in-addr.arpa.
+nucrdk.com.
+media.gameworldnetwork.com.
+orcart.facebook.com.
+a.root-servers.net.
+a.root-servers.net.
+googleads.g.doubleclick.net.
+juventud.gob.pe.
+degiacomo.com.
+156.228.206.200.in-addr.arpa.
+36.172.112.200.in-addr.arpa.
+profile.ak.fbcdn.net.
+t1.gstatic.com.
+syndication.exoclick.com.
+tc.v14.cache1.c.youtube.com.
+rlp.ru.
+flightstats-inc.com.
+a1.sphotos.ak.fbcdn.net.
+sc17.rules.mailshell.net.
+ars.oscar.aol.com.
+www.educatednation.com.
+www.games.soft82.com.
+chartboost.com.
+bnpparibas.clicmobileanalytics.com.
+s-static.ak.facebook.com.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+249.208.180.79.in-addr.arpa.
+tubisuteria.com.ve.
+118.224.10.186.in-addr.arpa.
+24.234.49.186.in-addr.arpa.
+profile.ak.fbcdn.net.
+133.52.115.186.in-addr.arpa.
+profile.ak.fbcdn.net.
+25.225.71.98.in-addr.arpa.
+a.root-servers.net.
+dev.hardsextube.com.
+google.co.uk.
+www.facebook.com.
+content.yieldmanager.edgesuite.net.
+www.google.com.
+developers.facebook.com.
+www.facebook.com.
+img3.catalog.video.msn.com.
+123.98.209.189.in-addr.arpa.
+www.petrosil.com.
+cs4495.vk.com.
+152.97.149.202.in-addr.arpa.
+www.brautkleideronlineladen.de.
+books.google.com.mx.
+tpemail.com.s8b2.psmtp.com.
+1.122.235.199.in-addr.arpa.
+feeds.bitterwallet.com.
+apis.google.com.
+services.digg.com.
+www.google-analytics.com.
+www.e-encuestas.com.
+sofit-spb.ru.
+mattflynn.co.uk.
+theavamovement.com.
+17.160.8.200.in-addr.arpa.
+alsglobal.com.
+a955.phobos.apple.com.
+verdizon.net.
+_365_99_1.
+ow.ly.
+crl.globalsign.net.
+www.sjdxa.org.
+151.157.211.89.in-addr.arpa.
+mx.horoscopo.yahoo.net.
+dns.msftncsi.com.
+www.slowfood.it.
+www.webdesign-entreprise.com.
+201.199.91.187.in-addr.arpa.
+c-0.19-a309f481.483.1518.19d4.3ea1.410.0.3wl4k743w1rtfisw2chzs8baci.avqs.mcafee.com.
+cyber.playboy.com.
+static.ak.fbcdn.net.
+backend.uniblue.com.
+mp3dlb.cdn.kuwo.cn.
+234.96.179.190.in-addr.arpa.
+profile.ak.fbcdn.net.
+capital604.com.
+a7.sphotos.ak.fbcdn.net.
+pool.ntp.org.
+photos-e.ak.fbcdn.net.
+stormsustainability.com.
+a3.sphotos.ak.fbcdn.net.
+teredo.ipv6.microsoft.com.
+38.137.139.190.in-addr.arpa.
+aln-mailrelay.att.net.
+www.hgh.com.
+www.computrabajo.com.mx.
+.
+hesperiatrussinc.com.
+productnews.link.net.
+profile.ak.fbcdn.net.
+www.michaeltilsonthomas.com.
+download831.avast.com.
+www.twittular.com.
+www.theclimateproject.org.
+csi.gstatic.com.
+ahzxwacg4.07vj.
+155.186.93.186.in-addr.arpa.
+didrickmedical.com.s7a1.psmtp.com.
+230.1.240.201.in-addr.arpa.
+162.189.13.209.in-addr.arpa.
+s.ytimg.com.
+bridge.inc.ru.
+19-courier.push.apple.com.
+reminc.com.
+twitter.com.
+orcart.facebook.com.
+login.yahoo.com.
+84.8.166.89.in-addr.arpa.
+profile.ak.fbcdn.net.
+a.root-servers.net.
+getprof.nl.np.community.playstation.net.
+amazingdeals1.info.
+dubaided.com.
+227.88.161.189.in-addr.arpa.
+119.47.98.174.in-addr.arpa.
+136.11.48.174.in-addr.arpa.
+apps.facebook.com.
+notasparalectorescuriosos.blogspot.com.
+belleusa.com.
+tochlit.ru.
+21.53.134.187.in-addr.arpa.
+qipim.com.
+www.oooforum.org.
+www.twitter.com.
+49.8.182.93.in-addr.arpa.
+forum.siemens-club.ru.
+spider.tm.
+premierfoto.ru.
+znoihyb.cc.home.
+www.consejotecnicoconsultivo.org.mx.
+a5.sphotos.ak.fbcdn.net.
+82yahoo.com.
+a995.mm1.akamai.net.
+auddi.ru.
+mariah.com.
+ihd.com.
+fbcdn-profile-a.akamaihd.net.
+i.ebayimg.com.
+www.google-analytics.com.
+55.49.32.177.in-addr.arpa.
+dogguy.us.
+ads7261.hotwords.com.ar.
+www.airspartner.com.
+dns.msftncsi.com.
+fonts3.scribdassets.com.
+www.planetmad.es.
+photos-b.ak.fbcdn.net.
+profile.ak.fbcdn.net.
+silveiro.com.
+a4.sphotos.ak.fbcdn.net.
+fbcdn-photos-a.akamaihd.net.
+121.93.89.210.in-addr.arpa.
+photos-g.ak.fbcdn.net.
+ifab.spb.ru.
+www.apple.com.
+th02.deviantart.net.
+safebrowsing-cache.google.com.
+gsp10-ssl.apple.com.
+hyec.en.alibaba.com.
+pixel.facebook.com.
+api-public.addthis.com.
+www.biggunspestcontrol.com.
+ib.adnxs.com.
+a3.sphotos.ak.fbcdn.net.
+download.mozilla.org.
+www.google.com.
+mail.thomascook.fr.
+pcsynergy.com.
+178.204.5.174.in-addr.arpa.
+rolypolygangbang.maniacpass.com.
+lb._dns-sd._udp.0.0.0.5.in-addr.arpa.
+www.milenio.com.
+179.186.178.183.in-addr.arpa.
+163.60.244.189.in-addr.arpa.
+us.telex.com.
+a.root-servers.net.
+a.root-servers.net.
+142.225.255.201.in-addr.arpa.
+ask.com.
+221.182.137.186.in-addr.arpa.
+c7.zedo.com.
+xqtspkhmxruszajp.org.
+adictosgeek.com.
+api-read.facebook.com.
+0-74.channel.facebook.com.
+fbcdn-profile-a.akamaihd.net.
+gas-web2.no-ip.info.
+a1890.g.akamai.net.
+96.46.137.190.in-addr.arpa.
+248.8.149.83.in-addr.arpa.
+i.dell.com.
+gateway.loseit.com.
+guiamexico.com.mx.
+62.122.143.101.in-addr.arpa.
+mailgate.cybercity.dk.
+db._dns-sd._udp.0.1.168.192.in-addr.arpa.
+external.ak.fbcdn.net.
+d2103269.xoom.it.
+67.24.231.91.in-addr.arpa.
+py.starmedia.com.
+dr._dns-sd._udp.lan.
+www.vinnylingham.com.
+mx.youtube.com.
+aka-cdn-ns.adtech.de.
+creatividadcondulsuras.blogspot.com.
+www.gtasanandreas.net.
+maps.google.co.uk.
+www.elpatronfm.com.mx.
+restauracionreseda.com.
+a1.sphotos.ak.fbcdn.net.
+bergancardio.com.
+dingtao333.3322.org.
+budapest.frasershospitality.com.
+31.190.63.69.in-addr.arpa.
+google.com.
+202.236.159.110.in-addr.arpa.
+www.seresvivos.net.
+a954.v.phobos.apple.com.
+alloymail.com.
+limbobreakfast.blogspot.com.
+www.google-analytics.com.
+www.pideyoo.com.
+449-async.olark.com.
+73.87.155.190.in-addr.arpa.
+em1x-375.lhr.messaging.nokia.com.
+ar-ar.facebook.com.
+dns.msftncsi.com.
+c-0.19-a30f1081.80481.1518.19d1.3ea1.200.0.hgthlrt321s5gnj4pjsjfr7q4q.avqs.mcafee.com.
+accounts.google.com.
+158.220.188.189.in-addr.arpa.
+pixel.facebook.com.
+43.210.214.67.in-addr.arpa.
+i3.ytimg.com.
+www.youtube.com.
+www.housetweaking.com.
+maps.google.es.
+v10.nonxt2.c.googlesyndication.com.
+static6.flixster.com.
+plod.ru.
+z-ecx.images-amazon.com.
+azad-net.net.
+sac.gti.mcafee.com.
+www.cnn.com.
+ao.l.com.
+a3.sphotos.ak.fbcdn.net.
+ar.answers.yahoo.com.
+t0.gstatic.com.
+googleads.g.doubleclick.net.
+fr-fr.facebook.com.
+photos-d.ak.fbcdn.net.
+www.youtube.com.
+24.195.65.74.in-addr.arpa.
+a.root-servers.net.
+57.248.113.186.in-addr.arpa.
+maps.google.com.
+s.ytimg.com.
+search.yahoo.com.
+www.alanhoskins.com.
+25.10.160.187.in-addr.arpa.
+developers.facebook.com.
+www.rmservices.nsw.gov.au.
+localhost.
+a5.sphotos.ak.fbcdn.net.
+www.pufcompany.com.
+exf1.dsa.reldom.tamu.edu.
+hiloterapiaclubdeagujaehilo.blogspot.com.
+inc.appliedsec.com.
+b.scorecardresearch.com.
+63.91.169.189.in-addr.arpa.
+en.netlog.com.
+newversion.epyte.com.
+foxvall.com.
+www.sevillasevillasevilla.com.
+www.instants.cl.
+37.153.104.68.in-addr.arpa.
+103.81.181.85.in-addr.arpa.
+122.218.93.186.in-addr.arpa.
+www.facebook.com.
+moonscoop.com.
+liquidlove.cc.
+16.99.9.177.in-addr.arpa.
+download.iolo.net.
+www.googleadservices.com.
+a652.phobos.apple.com.
+www.vai.com.
+a2.sphotos.ak.fbcdn.net.
+_482_20_2.
+pagead2.googlesyndication.com.
+dns.msftncsi.com.
+viavh1la.112.2o7.net.
+mjwinnovations.com.
+www.twitter.com.
+rawarrior.com.
+secure.shared.live.com.
+voyo.cz.
+titanium30-en.url.trendmicro.com.
+137.0.72.187.in-addr.arpa.
+75.161.52.187.in-addr.arpa.
+helo.org.
+109.76.250.166.in-addr.arpa.
+lyv9u78hs.k16u9c8f.
+master.sdabocconi.it.
+twitter.com.
+39.201.58.200.in-addr.arpa.
+secure-us.imrworldwide.com.
+um16.eset.com.
+static.ak.fbcdn.net.
+ntp.glb.nist.gov.
+www.youtube.com.
+100.1.168.192.in-addr.arpa.
+www.autoscout24.es.
+www.facebook.com.
+www.ngskintools.com.
+check6.facebook.com.
+qjtogpkupjighkr.net.
+img.fiesta101.com.s3.amazonaws.com.
+photos-b.ak.fbcdn.net.
+:y85m4vcd.g53f3l5t.
+pagead2.googlesyndication.com.
+xatracing.com.
+profile.ak.fbcdn.net.
+142.173.205.190.in-addr.arpa.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+coxnc.com.
+www.googletagservices.com.
+147.142.152.189.in-addr.arpa.
+221.108.204.190.in-addr.arpa.
+207.215.19.187.in-addr.arpa.
+4b2eapnji.q49s5i5z.
+secure-us.imrworldwide.com.
+www.peachtree.com.
+10.225.230.190.in-addr.arpa.
+prensaagraria.blogspot.com.
+api-read.facebook.com.
+peliculasdelholocaustojudio.blogspot.com.
+3rxba3akr.31xu.
+davis-cpa.net.
+www.video-lyrics.com.
+33.210.160.201.in-addr.arpa.
+dns.msftncsi.com.
+peterhalliwell.com.
+www.elcornudo.es.
+96.148.59.199.in-addr.arpa.
+www.google.com.
+241.239.12.189.in-addr.arpa.
+profile.ak.fbcdn.net.
+www.sophiedeeonline.com.
+mail-attachment.googleusercontent.com.
+api-read.facebook.com.
+luisldg.wordpress.com.
+mail.kphbuilds.com.
+389.webim0221.webim.myspace.com.
+us-w1.rockmelt.com.
+www.kachivaches.es.
+ow4ml3wlr.g99l5x2u.
+novoco.com.
+152.174.172.189.in-addr.arpa.
+www.movies-24h.com.
+eilat.sci.brooklyn.cuny.edu.
+apple.com.
+www.windowtothemovies.com.
+army.togetherweserved.com.
+ad.e-viral.com.
+rcp.na.blackberry.com.
+rss.cbc.ca.
+vp.sip.messenger.msn.com.
+db._dns-sd._udp.0.2.168.192.in-addr.arpa.
+www.facebook.com.
+iceweb.net.
+content.yieldmanager.edgesuite.net.
+mailgateway1.hochschule.li.
+www.ottoskins.com.
+a.root-servers.net.
+apis.google.com.
+149.115.231.190.in-addr.arpa.
+www.googleadservices.com.
+init-p01md.apple.com.
+19-courier.push.apple.com.
+www.gratisistockholm.nu.
+mx.jewsonrealty.com.
+a.ads2.msads.net.
+a.root-servers.net.
+ccshows.com.
+csi.gstatic.com.
+89.1.40.201.in-addr.arpa.
+abacus.tumblr.com.
+sprint-canada.com.home.
+dr._dns-sd._udp.0.2.168.192.in-addr.arpa.
+i730.photobucket.com.
+b.scorecardresearch.com.
+www.facebook.com.
+yiwucollection.en.alibaba.com.
+sro-alianzalatina.blogspot.com.
+174.81.215.201.in-addr.arpa.
+photos-f.ak.fbcdn.net.
+bs.serving-sys.com.
+www.barcodesinc.com.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+207.167.130.190.in-addr.arpa.
+profile.ak.fbcdn.net.
+secure.csfm.com.
+187.1.21.95.in-addr.arpa.
+207.120.26.92.in-addr.arpa.
+www.niswan.net.
+www.teamrocs.com.
+52.47.100.208.in-addr.arpa.
+www.google.es.
+js2.wlxrs.com.
+eabd3b6ed1.static.crowdscience.com.
+news.google.com.mx.
+htc2.accu-weather.com.
+www.glamourbabes.org.
+www.statcounter.com.
+db._dns-sd._udp.0.1.168.192.in-addr.arpa.
+155.185.49.190.in-addr.arpa.
+www.jpedsurg.org.
+www.google-analytics.com.
+ksn2-12.kaspersky-labs.com.
+0-238.channel.facebook.com.
+s7.addthis.com.
+www.bay-of-fundie.com.
+s2.youtube.com.
+www.faridaguitars.co.uk.
+profile.ak.fbcdn.net.
+www.abbyswings.nude-beach-sex.com.
+cursoderobotica.blogspot.com.
+www.amarillashialeah.com.
+apex.od.ua.
+www.guiamania.com.
+portablesdoctor-reprod.blogspot.com.
+xboxlive.ign.com.
+makeupbynyna.blogspot.com.
+www.sivananda.es.
+sun.uchc.edu.
+tdtv.microsoft.fr.
+hootsuite.com.
+a.root-servers.net.
+www.bjmama.net.
+amazonm-611.vo.llnwd.net.
+www.bunkergraphics.com.
+186.212.188.200.in-addr.arpa.
+www.net-pratique.fr.
+nethunting.files.wordpress.com.
+mail.prodigy.net.mx.
+insider.msg.yahoo.com.
+www.noubarris.net.
+c.baidu.com.
+esmas2006.occ.com.mx.
+www.google.es.
+r._dns-sd._udp.lan.
+163.105.154.184.in-addr.arpa.
+www.googleadservices.com.
+241.18.23.187.in-addr.arpa.
+api.facebook.com.
+cranbarry.com.
+svacom.com.
+external.ak.fbcdn.net.
+keckobservatory.org.
+blog.allusb.com.
+bolsasistemas.com.woopra-ns.com.
+piteau.com.1.arsmtp.com.
+s-static.ak.facebook.com.
+hosturl.no-ip.biz.
+time.nist.gov.
+www.google.com.
+download.microsoft.com.
+mail.ikka.com.
+articulo.mercadolibre.com.mx.
+clients2.google.com.
+uk.answers.yahoo.com.
+apps.facebook.com.
+photos-e.ak.fbcdn.net.
+231.43.144.78.in-addr.arpa.
+86.198.159.189.in-addr.arpa.
+87.73.58.189.in-addr.arpa.
+www.theshadowlounge.co.uk.
+widgets.twimg.com.
+creative.ak.fbcdn.net.
+www.michaela.it.
+quantumgraphics.ru.
+pumpcoinc.com.
+www.tv-so.com.
+fbcdn-sphotos-a.akamaihd.net.
+c4.zedo.com.
+www.philips.com.mx.
+video.google.com.
+news.google.com.mx.
+appsmetadata.toolbar.conduit-services.com.
+140.196.165.46.in-addr.arpa.
+a6.sphotos.ak.fbcdn.net.
+kabuj.polyvore.com.
+cdn.vps.net.c.footprint.net.
+camrent.se.
+www.memeadictos.org.
+dmmail01.demac.com.
+_634_23_7.
+pixel.facebook.com.
+www.thesun.co.uk.
+www.google.com.
+227.244.78.186.in-addr.arpa.
+external.ak.fbcdn.net.
+repository.jboss.org.
+b.scorecardresearch.com.
+lizzie-secret.bravoerotica.com.
+a.root-servers.net.
+dns.msftncsi.com.
+tamp04.activenetcontroller.net.
+canarias.indymedia.org.
+bs.serving-sys.com.
+ds.serving-sys.com.
+programtv.interia.pl.
+photos-e.ak.fbcdn.net.
+bd0dc.v.fwmrm.net.
+finchleycatholic.org.uk.
+db._dns-sd._udp.0.1.168.192.in-addr.arpa.
+crl.microsoft.com.
+www.3djuegos.com.
+_902_96_1.
+freeapps.me.
+98.235.111.58.in-addr.arpa.
+84.39.23.186.in-addr.arpa.
+apis.google.com.
+116.104.26.190.in-addr.arpa.
+www.facebook.com.
+photos-h.ak.fbcdn.net.
+version.jomsocial.com.
+228.59.89.186.in-addr.arpa.
+i4.ytimg.com.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+opportune.ru.
+3.247.100.97.in-addr.arpa.
+abcommortgage.com.
+shelfari-kcp.amazon.com.
+dns.msftncsi.com.
+go.microsoft.com.
+www.activolcans.info.
+api.twitter.com.
+s.jimdo.com.
+photos-g.ak.fbcdn.net.
+134.47.42.201.in-addr.arpa.
+www.buscoenlaces.es.
+dt.tongji.linezing.com.
+53.103.106.186.in-addr.arpa.
+s-static.ak.facebook.com.
+206.38.22.107.in-addr.arpa.
+4.77.206.190.in-addr.arpa.
+m.facebook.com.
+www.planetofbirds.com.
+www.ecosdosur.org.
+photos-h.ak.fbcdn.net.
+inbound.kprecruiting.com.netsolmail.net.
+r._dns-sd._udp.lan.
+mx.pronosticofoxsportsla.com.
+www.greencorrespondents.com.
+ar-ar.facebook.com.
+profile.ak.fbcdn.net.
+apps.facebook.com.
+www.los40.com.gt.
+sg-asia.vertical.search.ystg1.b.yahoo.com.
+232.77.234.189.in-addr.arpa.
+wpad.
+static.ak.fbcdn.net.
+a5.sphotos.ak.fbcdn.net.
+mail2.chat-land.org.
+elrinconbiologico.blogspot.com.
+jtools.smartmoney.com.
+www.gaylife.time4twinks.com.
+es.kioskea.net.
+bs.serving-sys.com.
+allanhomes.com.inbound10.mxlogic.net.
+external.ak.fbcdn.net.
+www.schools.com.
+misterolympia.com.ar.
+platform.twitter.com.
+heartbeat.belkin.com.
+a1.sphotos.ak.fbcdn.net.
+a.root-servers.net.
+tour.windyvidz.com.
+a6.sphotos.ak.fbcdn.net.
+de-de.facebook.com.
+u6sadblvs.86fo.
+89.171.57.186.in-addr.arpa.
+dangar.artelista.com.
+sp3.fotolog.com.
+developers.facebook.com.
+bidsystem.adknowledge.com.
+static.ak.fbcdn.net.
+a2.sphotos.ak.fbcdn.net.
+www.facebook.com.
+92.43.86.190.in-addr.arpa.
+www.tracerplus.com.
+ad.doubleclick.net.
+a.root-servers.net.
+26.249.208.86.in-addr.arpa.
+apps.facebook.com.
+gopro.com.
+52.86.164.189.in-addr.arpa.
+img6.pictiger.com.
+www.randomdetox.com.
+34.184.110.189.in-addr.arpa.
+145.63.226.213.in-addr.arpa.
+apps.facebook.com.
+tlanders.com.
+waycooldesigns.com.
+247.168.76.76.in-addr.arpa.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+static.ak.fbcdn.net.
+a7.sphotos.ak.fbcdn.net.
+63.100.157.186.in-addr.arpa.
+hog.assets.zgncdn.com.
+www.joomla.royy.net.
+www.facebook.com.
+_725_84_1.
+checkout.google.c.
+a.root-servers.net.
+ssl.gstatic.com.
+tswgarage.blogspot.com.
+mail.prometeo.com.
+a5.sphotos.ak.fbcdn.net.
+newsrss.bbc.co.uk.
+time.chttl.com.tw.
+28.249.1.181.in-addr.arpa.
+a.root-servers.net.
+mx3.wellsfargo.com.
+radiouno.net.
+content3c1b.omroep.nl.
+js.casalemedia.com.
+www.3dglasses.com.
+watson.microsoft.com.
+144.253.35.200.in-addr.arpa.
+atlr.ec.
+a6.sphotos.ak.fbcdn.net.
+p4.focus.de.
+central.keppel.k12.ca.us.
+foto.paraisowebcam.com.
+groupevianden.com.
+tredir.go.com.
+a.root-servers.net.
+photos-b.ak.fbcdn.net.
+www.facebook.com.
+s2.youtube.com.
+200.190.9.186.in-addr.arpa.
+feeds.bbci.co.uk.
+linkin-park-theme.archivospc.com.
+www.citasdeamor.es.
+65.186.179.190.in-addr.arpa.
+jpwkake3m.z31z8n6d.
+www.google.com.mx.
+crm.digitalchocolate.com.
+210.201.10.186.in-addr.arpa.
+sites.google.com.
+apps.facebook.com.
+mail2.acpr.ru.
+fbcdn-profile-a.akamaihd.net.
+i.i.imgur.com.
+afcmails.com.
+www.facebook.com.
+www.newfoundglorystuff.com.
+www.bing.com.
+www.sektor.gen.tr.
+form.hktdc.com.
+129.86.53.186.in-addr.arpa.
+col.stb01.s-msn.com.
+time.chttl.com.tw.
+madrid.salir.com.
+i4.ytimg.com.
+www.adbrite.com.
+168.161.105.186.in-addr.arpa.
+obradoretumbante.globo.com.
+youtube-downloader-hq-pro.softonic.com.
+photos.cams.com.
+clock.fmt.he.net.
+ydpj.com.
+hyperdatis.de.
+mail.muellerenvironmental.com.
+m.see-my-ip.com.
+checkip.dyndns.org.
+sbcglobal.net.
+photos-e.ak.fbcdn.net.
+market.android.com.
+chat.onlinefootballmanager.co.uk.
+indoexports.net.
+view.atdmt.com.
+a1822.phobos.apple.com.
+ntp1.dlink.com.
+gsp1.apple.com.
+id.google.com.
+ygum7qsd:.y41n2s4s.
+cheapestenergy.eu.
+shreya.co.in.
+safebrowsing.clients.google.com.
+www.incremento.net.
+keepalive.se2.softether.com.
+204.49.135.181.in-addr.arpa.
+15.149.220.66.in-addr.arpa.
+www.dbsheppard.com.
+secure.wlxrs.com.
+www.loveinfobook.com.
+www.youtube.com.
+highslide.com.
+p.yoho.cn.
+api.twitter.com.
+nj663tv3t.z21t0j0p.
+twitter.co.
+ksn2-12.kaspersky-labs.com.
+a.root-servers.net.
+plusone.google.com.
+ydigminkt.97mt.
+www.pcconnectionexpress.com.
+entertainment.webshots.com.
+155.77.146.189.in-addr.arpa.
+229.155.64.177.in-addr.arpa.
+static.ak.fbcdn.net.
+hhzbhhpfn.95rq.
+a.root-servers.net.
+221.63.204.186.in-addr.arpa.
+metrics.apple.com.
+assets.tumblr.com.
+cdn02.cartown.com.edgesuite.net.
+static.ak.fbcdn.net.
+time.windows.com.
+www.gameslist.com.
+www.sega.nl.
+fonts.googleapis.com.
+gamer.portail.free.fr.
+www.millenniumassessment.org.
+alienbabeltech.com.
+profile.ak.fbcdn.net.
+a.root-servers.net.
+a.root-servers.net.
+jovenescoleccionistas.tallermultinacional.org.
+194.211.25.189.in-addr.arpa.
+ssl.gstatic.com.
+a.root-servers.net.
+usmpagency.com.s7b1.psmtp.com.
+www.gdocu.es.
+29.172.203.190.in-addr.arpa.
+156.10.228.77.in-addr.arpa.
+cdn.zeusclicks.com.
+glerum.com.
+s-static.ak.fbcdn.net.
+i1.ytimg.com.
+photos-c.ak.fbcdn.net.
+239.28.193.207.in-addr.arpa.
+www.atlantafixture.com.
+csi.gstatic.com.
+www.nothingcomparestohavana.com.
+a6.sphotos.ak.fbcdn.net.
+www.apeironmagazine.com.
+116.15.33.90.in-addr.arpa.
+safebrowsing-cache.google.com.
+a8.sphotos.ak.fbcdn.net.
+insider.msg.yahoo.com.
+a.root-servers.net.
+www.pbscolorado.com.
+79.121.113.186.in-addr.arpa.
+i2.ytimg.com.
+a5.sphotos.ak.fbcdn.net.
+www.hotmail.com.
+www.microsoft.com.
+splayer.uptodown.com.
+91.230.95.65.in-addr.arpa.
+search.babylon.com.
+hipay.com.
+:knpbrhnp.o32z8k4r.
+www.mesmo.tv.
+mail.imageworks4signs.com.
+.
+230.169.152.85.in-addr.arpa.
+b._dns-sd._udp.0.1.168.192.in-addr.arpa.
+www.aa.com.
+profile.ak.fbcdn.net.
+175.98.63.212.in-addr.arpa.
+exchange2003.snapon.com.
+ajax.cloudflare.com.
+gosstroy.gov.ru.
+static.ak.fbcdn.net.
+flowhot.info.
+109.94.86.200.in-addr.arpa.
+smtp2.vianetworks.de.
+www.facebook.com.
+131.81.142.190.in-addr.arpa.
+profile.ak.fbcdn.net.
+nomolesten.com.
+statse.webtrendslive.com.
+photos-c.ak.fbcdn.net.
+mail.fortifiber.com.
+da8thaern.95ra.
+login.toolbar.conduit-services.com.
+38.25.141.201.in-addr.arpa.
+fbcdn-sphotos-a.akamaihd.net.
+32-courier.push.apple.com.
+mipeq.com.
+105.47.52.186.in-addr.arpa.
+a1.sphotos.ak.fbcdn.net.
+47.189.142.190.in-addr.arpa.
+209.72.22.186.in-addr.arpa.
+www.ultimatehandyman.org.
+free2night.net.
+upload.wikimedia.org.
+f42.stagero.eu.
+premiumcars.autotrader.ca.
+linksfb.com.
+www.youtube.com.
+cuentame.inegi.org.mx.
+sp.cwfservice.net.
+a3.sphotos.ak.fbcdn.net.
+infanciasolidaria.blogspot.com.
+r._dns-sd._udp.0.2.168.192.in-addr.arpa.
+apis.google.com.
+content.dl-rms.com.
+kearnyfederalsavings.net.inbound10.mxlogic.net.
+a3.sphotos.ak.fbcdn.net.
+mowprod.kaboomsocial.com.
+pixel.facebook.com.
+ajax.googleapis.com.
+xcdn.xgraph.net.
+u40.eset.com.lan.
+97.44.90.24.in-addr.arpa.
+lb-chw-webserver-cache-1218636608.us-east-1.elb.amazonaws.com.
+161.42.0.186.in-addr.arpa.
+81.184.132.94.in-addr.arpa.
+googleads.g.doubleclick.net.
+a212.phobos.apple.com.
+by2msg3010706.gateway.messenger.live.com.
+myo74ld8m.u67k2r5q.
+www.google.com.
+static.ak.fbcdn.net.
+www.google.com.
+dtboot.orbitdownloader.com.
+www.google-analytics.com.
+lalocuradelpecado.blogspot.com.
+v8.cache7.c.youtube.com.
+aromanova.ru.
+s-static.ak.facebook.com.
+at.amgdgt.com.
+rs531l32.rapidshare.com.
+payments.ebay.com.
+www.facebook.com.
+www.askvids.com.
+9gag.com.
+165.190.12.61.in-addr.arpa.
+webmail35.yandex.ru.
+fr-fr.facebook.com.
+140.80.141.201.in-addr.arpa.
+yamalarchaeology.ru.
+google.com.
+checkip.dyndns.org.
+165.50.0.10.in-addr.arpa.
+plus.google.com.
+content.mobile.viaden.com.
+hog.assets1.zgncdn.com.
+www.geobaby.com.
+29.134.134.187.in-addr.arpa.
+29.160.1.201.in-addr.arpa.
+go.trafficshop.com.
+110.74.158.200.in-addr.arpa.
+photos-c.ak.fbcdn.net.
+179.wap517.biz.
+fbcdn-photos-a.akamaihd.net.
+downloads3.kaspersky-labs.com.
+photos-e.ak.fbcdn.net.
+a.root-servers.net.
+ad.yieldmanager.com.
+vgcqabgpc.51lt.
+sp.cwfservice.net.
+b3.imgsrc.ro.
+a.root-servers.net.
+it-it.facebook.com.
+cdn.api.twitter.com.
+0-68.channel.facebook.com.
+149.94.209.201.in-addr.arpa.
+207.241.151.79.in-addr.arpa.
+dns.msftncsi.com.
+www.facebook.com.
+ttu.edu.
+tmx.technoratimedia.com.
+photos-g.ak.fbcdn.net.
+pnpco.com.
+content.yieldmanager.edgesuite.net.
+csi.gstatic.com.
+249.62.148.190.in-addr.arpa.
+wacomail1.wacotrib.com.
+p.twimg.com.
+76.87.228.189.in-addr.arpa.
+www.17dht.com.
+tv.mk.ru.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+www.programmingfacts.com.
+hepm.hitachi-asia.com.
+239.194.110.85.in-addr.arpa.
+ping4.client.sandai.net.
+deadtravelgroup.blogspot.com.
+a2.sphotos.ak.fbcdn.net.
+i.ytimg.com.
+platform.stumbleupon.com.
+www.google.com.
+bit.ly.
+77.158.8.200.in-addr.arpa.
+www.tripsandtreasures.blogspot.com.
+sc2.rules.mailshell.net.
+www.nikkohurtado.com.
+vtr.net.
+218.35.153.201.in-addr.arpa.
+bertamares.blogspot.com.
+ar.wikipedia.org.
+www.hogarandum.com.
+www.cell-lines-service.de.
+my.plaza.rakuten.co.jp.
+a.root-servers.net.
+mlocate.spotlife.net.
+archiblock.com.
+www.rockmobilez.net.
+49.224.93.186.in-addr.arpa.
+bin-short.whatsapp.net.
+l972nb7:u.x91z2x2l.
+102.127.250.201.in-addr.arpa.
+premierair.com.
+www.adobe.com.
+dnl-01.geo.kaspersky.com.
+www.virit.net.
+it-it.facebook.com.
+tmz.com.
+mx00.1and1.co.uk.
+www.trm.md.
+lb._dns-sd._udp.lan.
+rlwaconsult.com.
+a5.sphotos.ak.fbcdn.net.
+mail.google.com.
+techhelp0417.webs.com.
+61.88.233.189.in-addr.arpa.
+gimnasialatina.com.
+www.spike.com.
+.
+twitter.com.
+www.sunwayhotels.com.
+profile.ak.fbcdn.net.
+aka-cdn-ns.adtech.de.
+dns.msftncsi.com.
+nomulous.com.
+labontology.wikispaces.com.
+71.212.58.186.in-addr.arpa.
+www.emotional.sk.
+static.exoclick.com.
+comidaspostresalimentosrecetascomidas.blogspot.com.
+mscrl.microsoft.com.
+a6.sphotos.ak.fbcdn.net.
+www.gpstc.org.
+casbygroup.com.
+www.estacionsanpedro.com.ar.
+salva-reyes.blogspot.com.
+download986.avast.com.
+78.147.46.189.in-addr.arpa.
+10.7.20.76.in-addr.arpa.
+ads2.contentabc.com.
+wow.hro.cl.
+en-us.fxfeeds.mozilla.com.
+mx1.koreazinc.co.kr.
+b.scorecardresearch.com.
+grenson.com.
+dns.msftncsi.com.
+plugin.maldi.tv.
+27.28.193.187.in-addr.arpa.
+ensigngeo.com.
+195.78.26.177.in-addr.arpa.
+charliebucket.com.au.
+rest-img.msg.yahoo.com.
+30.97.61.202.in-addr.arpa.
+mail2.newlife.co.za.
+www.xvideosredtube.com.
+marxists.org.
+ajax.googleapis.com.
+partner.googleadservices.com.
+193.103.174.189.in-addr.arpa.
+a2.sphotos.ak.fbcdn.net.
+tunebb.ru.
+sn3v015.colegium.com.
+mi.wikipedia.org.
+plusone.google.com.
+eguard2.bizoservices.com.
+s4.histats.com.
+a.root-servers.net.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+a.root-servers.net.
+www.google.com.
+static.ak.fbcdn.net.
+www.universia.cl.
+www.linkedin.com.
+buttconstruction.com.
+smarturl.it.
+www.gpp-osijek.com.
+210.108.157.79.in-addr.arpa.
+neovortal.com.
+ic.tynt.com.
+www.facebook.com.
+i2.ytimg.com.
+email.wtsonline.com.
+150.197.85.186.in-addr.arpa.
+jy2opikcn.94sf.
+sn2files.storage.msn.com.
+40.116.102.201.in-addr.arpa.
+www.couponmole.com.
+www.ops.org.ni.
+yadtal.net.
+www.textsrv.com.
+whistlerfilmfestival.com.
+b._dns-sd._udp.0.0.168.192.in-addr.arpa.
+12.64.web1.im.weibo.com.
+brucelynton.com.
+194.17.251.189.in-addr.arpa.
+251.211.39.195.in-addr.arpa.
+pensionfuenflinden.de.
+people.directory.live.com.
+cyberguerre.blogspot.com.
+external.ak.fbcdn.net.
+mail.sxwtc.com.
+checkip.dyndns.org.
+232.33.254.190.in-addr.arpa.
+chat.extalia.net.
+mx.graycelltech.com.
+www.nitrodesign.com.
+th00.deviantart.net.
+.
+43.198.114.69.in-addr.arpa.
+159.243.125.96.in-addr.arpa.
+celebhairstyle.files.wordpress.com.
+blackstaramps.forumotion.com.
+www.mediawiki.org.
+graph.facebook.com.
+www.google.com.
+stereotown.com.
+s3.amazonaws.com.
+www.kga.neva.ru.
+www.connect.facebook.com.
+3.ns1631262.info.
+books.google.com.mx.
+111.218.226.190.in-addr.arpa.
+rss.emol.com.
+carrosyradios.galeon.com.
+33.153.174.190.in-addr.arpa.
+www.losnacionales.com.
+www.thevervoid.com.
+www.federacion-espa-airsoft.es.
+www.strategicsourceror.com.
+www.eepa.be.
+www.spiderboost.com.
+radiohead.mx.
+35.162.233.186.in-addr.arpa.
+google.com.
+2008webset5.net.
+softwareandscripts.com.
+www.goohle.com.
+local-bay.contacts.msn.com.
+i216.photobucket.com.
+checkip.dyndns.com.
+a1725.l.akamai.net.
+vp.sip.messenger.msn.com.
+zrp.spb.ru.
+blih.com.
+66.184.114.186.in-addr.arpa.
+41.186.178.190.in-addr.arpa.
+a.root-servers.net.
+cdn.pastemagazine.com.
+kontentservice.ru.
+imageharvest.net.
+mail.y-olastroy.ru.
+164.125.173.201.in-addr.arpa.
+signup.21sexturycash.com.
+dr._dns-sd._udp.0.0.168.192.in-addr.arpa.
+evsecure-ocsp.verisign.com.
+a1001.w40.akamai.net.
+udc.msn.com.
+www.madrimasd.org.
+lewismarine.com.
+home.live.com.
+www.facebook.com.
+a.root-servers.net.
+armina.ru.
+newsitedesigns-com.mail.eo.outlook.com.
+blst.msn.com.
+smtp1.kt.co.kr.
+chatenabled.mail.google.com.
+ivanowo.ru.
+105.108.34.99.in-addr.arpa.
+cdn1.ticketsinventory.com.
+barracuda.townsendcapital.com.
+search.twitter.com.
+vp.sip.messenger.msn.com.
+developers.facebook.com.
+www.portalhomeopatico.com.ar.
+wcsh-com.mail.eo.outlook.com.
+productosdeperu.com.
+sso.samsung.com.
+innovationnewsdaily.com.
+profile.ak.fbcdn.net.
+cdn-0.nflximg.com.
+74.81.190.189.in-addr.arpa.
+relay.voice.messenger.msn.com.
+164.26.10.24.in-addr.arpa.
+content.dl-rms.com.
+apps.facebook.com.
+199.124.183.180.in-addr.arpa.
+bc.rentershotline.ca.
+29.170.78.186.in-addr.arpa.
+32.4.87.121.in-addr.arpa.
+mail4.landtag-bw.de.
+www.gstatic.com.
+www.happynights.org.
+photos-h.ak.fbcdn.net.
+unafotopordiabylorenus.blogspot.com.
+csi.gstatic.com.
+b-0.19-21006008.d071081.1518.19d4.3ea0.410.0.pesqeebfp881qkmpk4aw8nfsc5.avqs.mcafee.com.
+secure.logmein.com.
+teredo.ipv6.microsoft.com.
+a4.sphotos.ak.fbcdn.net.
+ecn.t0.tiles.virtualearth.net.
+sp.cwfservice.net.
+www.bluecoat.com.
+geo.messenger.services.live.com.
+royal-wolf.com.
+www.habitual.eng.br.
+www.yaleherald.com.
+www.abraham-hickslawofattraction.com.
+9.181.242.201.in-addr.arpa.
+a.root-servers.net.
+spamfilter.bodekandrhodes.com.
+cccpschmidt.de.
+videoalbumy.azet.sk.
+111.144.249.78.in-addr.arpa.
+227.11.179.163.in-addr.arpa.
+fp.vendaria.com.
+rad.msn.com.
+a.root-servers.net.
+studio-nsk.ru.
+130.224.34.177.in-addr.arpa.
+apix.iminent.com.
+photos-c.ak.fbcdn.net.
+www.electroindustria.com.
+profile.ak.fbcdn.net.
+4.bp.blogspot.com.
+www.innovacion.gob.cl.
+profile.ak.fbcdn.net.
+dsn5.d.skype.net.
+ksn7.kaspersky-labs.com.
+de.jigzone.com.
+wushu-school.ru.
+plus.google.com.
+associatedsubs-com.relay1b.spamh.com.
+sorosfiles.com.
+ws-cloud203-blur.svcmot.com.
+iswimemler.com.s9a2.psmtp.com.
+119.144.155.90.in-addr.arpa.
+static.ak.fbcdn.net.
+tnhpqj79c.97vi.
+a.root-servers.net.
+skymonk.net.
+www.wizard101.it.
+signatron.com.
+www.delish.com.
+ads.adbrite.com.
+gadgets.live.com.
+www.cousyaward.com.
+242.110.90.200.in-addr.arpa.
+29.101.120.200.in-addr.arpa.
+ksn2-12.kaspersky-labs.com.
+cinematografia.cl.
+18.10.24.201.in-addr.arpa.
+botopolis.com.
+www.youtube.com.
+js.wlxrs.com.
+pixel.facebook.com.
+a4.sphotos.ak.fbcdn.net.
+mhminc.com.inbound10.mxlogic.netet.
+resumenesdelibros.mlarac.cl.
+47.224.171.69.in-addr.arpa.
+ammlaw.com.inbound10.mxlogicmx.net.
+a.root-servers.net.
+209.103.220.189.in-addr.arpa.
+dr._dns-sd._udp.0.2.168.192.in-addr.arpa.
+admin.brightcove.com.
+www.quemadres.com.
+secure.shared.live.com.
+photos-f.ak.fbcdn.net.
+profile.ak.fbcdn.net.
+crl.microsoft.com.
+photos-f.ak.fbcdn.net.
+free.voyeur-eye.com.
+128.144.51.190.in-addr.arpa.
+47.122.88.2.in-addr.arpa.
+nokia-s40-11-cust.opera-mini.net.
+photos-b.ak.fbcdn.net.
+www.google.com.
+19.33.251.85.in-addr.arpa.
+bestbuycondo.com.
+mail.dersa.com.
+71.206.73.69.in-addr.arpa.
+dns.msftncsi.com.
+mail.google.com.
+ax.init.itunes.apple.com.
+safebrowsing-cache.google.com.
+49.147.223.201.in-addr.arpa.
+englewoodhospital.com.
+www.nationwide.com.
+kuzbass-veda.ru.
+autoupdate.igw.sdo.com.
+www.google.com.
+api.twitter.com.
+www.avantmusicnews.com.
+i240.photobucket.com.
+plus.google.com.
+platform.stumbleupon.com.
+mail.
+www.lakueva.com.
+falfn.com.
+btinfo.flashget.com.
+www.addthis.com.
+49.224.52.186.in-addr.arpa.
+hcibooks.com.
+213.187.138.190.in-addr.arpa.
+te-tronik.info.
+lcsitemain.symantec.com.
+mx2.ertelecom.ru.
+static.ak.fbcdn.net.
+my.occ.com.mx.
+a.root-servers.net.
+a.root-servers.net.
+i4.tagstat.com.
+fonts.googleapis.com.
+a.root-servers.net.
+unifi.
+www.mellowvirgins.com.
+s5.mangareader.net.
+www.sexolewebcams.com.
+53.34.112.213.in-addr.arpa.
+k1pfo727f.n43f5i5x.
+162.20.209.190.in-addr.arpa.
+fbcdn-sphotos-a.akamaihd.net.
+dsn3.d.skype.net.
+teredo.ipv6.microsoft.com.
+ib.adnxs.com.
+s-external.ak.fbcdn.net.
+a.root-servers.net.
+s.ytimg.com.
+dumasses.com.
+api.conduit.com.
+vrvybx4zt.60lq.
+0.pool.ntp.org.
+usbionline.com.s6b2.psmtp.com.
+api.geo.kontagent.net.
+155.116.30.190.in-addr.arpa.
+a7.sphotos.ak.fbcdn.net.
+mail.tathwell.com.
+hogalia.com.
+237.199.243.201.in-addr.arpa.
+graph.facebook.com.
+ocsp.verisign.com.
+www.jabbim.com.
+14.190.63.69.in-addr.arpa.
+248.203.138.200.in-addr.arpa.
+clients2.google.com.
+84.233.96.190.in-addr.arpa.
+lldinc.com.
+a639.da1.akamai.net.
+osmtpws01.airtechniques.com.
+search.4shared.com.
+www.politica21.org.
+49.172.220.190.in-addr.arpa.
+hosting-gratis.com.es.
+fs60.myvi.ru.
+www.examiner.com.
+michaelmillerfabrics.com.
+41.30.59.186.in-addr.arpa.
+static.ak.fbcdn.net.
+pixel.facebook.com.
+196.90.86.188.in-addr.arpa.
+uspowerinc.com.s7a2.psmtp.com.
+237.125.126.84.in-addr.arpa.
+89o:53in3.88bc.
+www.see-through-shirt.com.
+eyeos-miniserver.softonic.com.
+231.221.8.99.in-addr.arpa.
+divx.112.2o7.net.
+www.energyfirst.com.
+sites.google.com.
+distibutel.net.
+klinika-ran.ru.
+photos-f.ak.fbcdn.net.
+253.235.172.190.in-addr.arpa.
+www.facebook.com.
+clients1.google.com.
+therealtrends.com.
+api-read.facebook.com.
+ray.
+56.92.53.64.in-addr.arpa.
+ad.xtendmedia.com.
+photos-e.ak.fbcdn.net.
+www.mozilla.org.
+67.147.156.216.in-addr.arpa.
+mailbox3.tcfbank.com.
+160.217.110.186.in-addr.arpa.
+download.mapleeurope.com.
+azze.ru.
+nbcpolitics.msnbc.msn.com.
+www.hipotecas-bancos.com.
+d303resfoavrtt.cloudfront.net.
+www.despegar.com.ar.
+www.cancun-map.com.
+metalrelease.blogspot.com.
+wsfcsk12.nc.us.
+www.google-analytics.com.
+dingtao333.3322.org.
+56.71.134.189.in-addr.arpa.
+www.copiadoras-xerox.com.mx.
+creative.ak.fbcdn.net.
+profile.ak.fbcdn.net.
+aidps.atdmt.com.
+sp.cwfservice.net.
+icm.ginyas.com.
+redsky.com.s8a2.psmtp.com.
+fu8j1dmn8.m11i0y0h.
+a1.sphotos.ak.fbcdn.net.
+accounts.google.com.
+zirconmusic.com.
+gs-loc.isg-apple.com.akadns.net.
+leventhal.com.
+81.118.93.109.in-addr.arpa.
+www.macromedia.com.
+freewaywebhost.com.multi.uribl.com.
+mail.ecanarys.com.
+a.root-servers.net.
+70.207.13.187.in-addr.arpa.
+jers3.info.
+a.root-servers.net.
+trupart.com.
+www.foot-locker.co.uk.
+lakeofweb.com.
+oneexwidow.blogspot.com.
+dreblen.com.
+c.static-cdn.playfish.com.
+tv.vilanoise.com.
+www.marinespecies.org.
+connect.facebook.net.
+www.banneradsthatpay.com.
+photos-f.ak.fbcdn.net.
+pandcwebmasters.com.
+s.ytimg.com.
+133.125.111.189.in-addr.arpa.
+ads2.msads.net.
+3.212.13.219.in-addr.arpa.
+151.192.57.62.in-addr.arpa.
+tracker.ccc.de.
+xm.corsendonk.com.
+www.google-analytics.com.
+plus.google.com.
+alphabetizer.flap.tv.
+78.150.49.178.in-addr.arpa.
+zeppelin.sasknet.sk.ca.
+82.69.226.168.in-addr.arpa.
+adfarm.mediaplex.com.
+www.netbrand.cl.
+i565.photobucket.com.
+br.wikipedia.org.
+mail.live.com.
+www.udenti.es.
+235.213.179.64.in-addr.arpa.
+yandalaw.com.
+highklass.ru.
+fancytuning.fancytuning.netdna-cdn.com.
+accessories.vancl.com.
+a7.sphotos.ak.fbcdn.net.
+folkhop.com.
+www.ieco.clarin.com.
+lorenzo.newfaceshere.info.
+tusvinilosdecorativosmx.blogspot.com.
+66.193.49.187.in-addr.arpa.
+netsacpe.net.
+ad.yieldmanager.com.
+www.rivtube.com.
+www.milliscent.com.
+ad.yieldmanager.com.
+developers.facebook.com.
+a.root-servers.net.
+alcam.com.
+b.scorecardresearch.com.
+0-238.channel.facebook.com.
+a.root-servers.net.
+116.185.167.190.in-addr.arpa.
+www.modern-war-generals.com.
+appworld.blackberry.com.
+queridobloc.blogspot.com.
+dce.unm.edu.
+newsrss.bbc.co.uk.
+a5.sphotos.ak.fbcdn.net.
+netflix336.pop1.la.nflximg.com.edgesuite.net.
+news.yahoo.com.
+28.131.229.190.in-addr.arpa.
+services.seagate.com.
+indiana-paw.com.
+products.wdc.com.
+a7.sphotos.ak.fbcdn.net.
+pubads.g.doubleclick.net.
+support.google.com.
+www.google.com.
+fr.webrep.avast.com.
+s.youtube.com.
+www.20minutos.es.
+utils.babylon.com.
+a.root-servers.net.
+mchxas:zj.u26q6o6x.
+224.37.83.24.in-addr.arpa.
+213.100.208.189.in-addr.arpa.
+db._dns-sd._udp.0.1.168.192.in-addr.arpa.
+a3.sphotos.ak.fbcdn.net.
+www.blogblog.com.
+249.165.194.210.in-addr.arpa.
+img.diynetwork.com.
+a8.sphotos.ak.fbcdn.net.
+app168341283206303.socialappspot.com.
+copt.ru.
+153.112.51.190.in-addr.arpa.
+a.root-servers.net.
+d2108831.xoom.it.
+.
+cityvillefb3.static.zgncdn.com.
+a1920.g.akamai.net.
+165.173.19.95.in-addr.arpa.
+static.ak.fbcdn.net.
+a5.sphotos.ak.fbcdn.net.
+84.92.172.189.in-addr.arpa.
+.
+91.20.80.201.in-addr.arpa.
+photos-h.ak.fbcdn.net.
+www.facebook.com.
+www.hatsinthebelfry.com.
+mail.bit-torrent.ru.
+www.google.com.
+www.apple.com.
+dm-commerce.hr.
+www.flagline.com.
+profile.ak.fbcdn.net.
+mail1.bethanna.org.
+lgecorp.com.mail6.psmtp.com.
+a.root-servers.net.
+scribe.twitter.com.
+22.32.227.186.in-addr.arpa.
+webscouter.net.
+sites.google.com.
+a.root-servers.net.
+147.211.242.189.in-addr.arpa.
+dnl-01.geo.kaspersky.com.
+dns.msftncsi.com.
+142.24.179.88.in-addr.arpa.
+churchextension.org.inbound10.mxlogic.net.
+167.53.155.85.in-addr.arpa.
+gnomoncopy.com.
+ad.yieldmanager.com.
+c.live.com.
+233.135.35.189.in-addr.arpa.
+www.itsgonnahurt.com.
+www.youtube.com.
+profile.ak.fbcdn.net.
+profile.ak.fbcdn.net.
+s-static.ak.facebook.com.
+img.baofeng.net.
+check.sanasecurity.com.
+static.ak.fbcdn.net.
+_391_37_3.
+potrebitel.ru.
+www.cienciaysociedad.info.
+o.xbox.com.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+photos-d.ak.fbcdn.net.
+fbcdn-profile-a.akamaihd.net.
+www.hydro-orchids.com.
+233.189.58.186.in-addr.arpa.
+226.25.253.190.in-addr.arpa.
+vietseas.com.
+elpozodejacob.tripod.com.
+account.live.com.
+102.xg4ken.com.
+144.105.239.89.in-addr.arpa.
+time.stdtime.gov.tw.
+accounts.google.com.
+ad.adnetwork.net.
+a4.sphotos.ak.fbcdn.net.
+165.235.169.58.in-addr.arpa.
+vpod.tv.
+a1.sphotos.ak.fbcdn.net.
+206.184.228.99.in-addr.arpa.
+133.74.188.189.in-addr.arpa.
+245.155.160.89.in-addr.arpa.
+armpoucohunde.mp.
+thumbs1.ebaystatic.com.
+www.imdb.com.
+78.233.108.76.in-addr.arpa.
+a5.sphotos.ak.fbcdn.net.
+www.ingdirect.com.au.
+178.16.168.189.in-addr.arpa.
+157.231.198.112.in-addr.arpa.
+partner.googleadservices.com.
+185.44.4.186.in-addr.arpa.
+avatar.xboxlive.com.
+www.facebook.com.
+arielarrieta.com.
+profile.ak.fbcdn.net.
+vast.bp3844834.btrll.com.
+gtanime-kai.foroactivo.com.
+www.youtube.com.
+miparroquia.fullblog.com.ar.
+.
+a.root-servers.net.
+rewardchannelcenter.com.
+external.ak.fbcdn.net.
+ar-ar.facebook.com.
+news.google.com.mx.
+bcbsla.com.
+50.11.158.82.in-addr.arpa.
+64.244.132.190.in-addr.arpa.
+www.youtube.com.
+feed190.photobucket.com.
+mybeautyloveaffair.blogspot.com.
+210.49.35.201.in-addr.arpa.
+s88lkzeqz.j64a3w4q.
+psp.ign.com.
+a6.sphotos.ak.fbcdn.net.
+118.94.92.201.in-addr.arpa.
+redirector.c.youtube.com.
+148.123.29.201.in-addr.arpa.
+www.visual28.com.
+photos-d.ak.fbcdn.net.
+49.140.209.190.in-addr.arpa.
+www.thebigprojectme.com.
+de-de.facebook.com.
+a1725.l.akamai.net.
+stats.ecb.europa.eu.
+photos-e.ak.fbcdn.net.
+www.alquranic.com.
+www.facebook.com.
+www.fotoefectos.com.
+profile.ak.fbcdn.net.
+topics.bo7.net.
+creative.ak.fbcdn.net.
+rcp.na.blackberry.com.
+www.ecoportal.net.
+www.betonsm.tk.
+www.google.com.
+photos-a.ak.fbcdn.net.
+www.bravoerotica.com.
+ssl.gstatic.com.
+api.facebook.com.
+a0.twimg.com.
+19.211.202.190.in-addr.arpa.
+www.goal-setting-for-success.com.
+www.mininova.org.
+us.rd.yahoo.com.
+cdn1.ads.contentabc.com.
+yahoo.com.
+ntp.glb.nist.gov.
+i2.ytimg.com.
+www.blogbigcock.blogspot.com.
+sa.bbc.com.
+profile.ak.fbcdn.net.
+edrmortgage.com.
+games.metaservices.microsoft.com.
+a6.sphotos.ak.fbcdn.net.
+8497.kz.all.biz.
+p04-caldav.icloud.com.
+somos.arkihome.netdna-cdn.com.
+thumbs4.ebaystatic.com.
+14.115.92.65.in-addr.arpa.
+h20397.www2.hp.com.
+a3.sphotos.ak.fbcdn.net.
+a.root-servers.net.
+postmaster.laguitare.com.
+232.50.132.190.in-addr.arpa.
+a.root-servers.net.
+www.youxakep.ru.
+twitter.com.
+m.tn.com.ar.
+37.140.51.190.in-addr.arpa.
+www.fi.bitefight.org.
+www.battlefieldsports.com.
+166.26.171.221.in-addr.arpa.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+fedexkinos.com.
+thumbs1.ebaystatic.com.
+s59.chatango.com.
+teamsmi.com.
+a.root-servers.net.
+www.theanalogdept.com.
+icanhascheezburger.com.
+247.15.0.192.in-addr.arpa.
+seaoleena.bandcamp.com.
+muchosmisterios.blogspot.com.
+www.justsimple.com.au.
+www.monochrome-heaven.com.
+torrentspy.com.
+static.ak.facebook.com.
+www.google.com.
+bay.messenger.services.live.com.
+75.70.102.200.in-addr.arpa.
+163.238.198.77.in-addr.arpa.
+a.root-servers.net.
+www.espacioebook.com.
+100.1.168.192.in-addr.arpa.
+photos-b.ak.fbcdn.net.
+oka-auto.ru.
+carlosalvatelli.ru.
+b._dns-sd._udp.0.1.168.192.in-addr.arpa.
+bs.serving-sys.com.
+dr._dns-sd._udp.0.33.168.192.in-addr.arpa.
+cdn.api.twitter.com.
+getprof.gb.np.community.playstation.net.
+a.root-servers.net.
+subaru-tlt.ru.
+67.76.159.99.in-addr.arpa.
+pix.search.iminent.com.
+edconma.macintotheredi.museum.
+www.google.com.
+ryapps-a.akamaihd.net.
+www.empleo.gob.mx.
+external.ak.fbcdn.net.
+cornosul.blogspot.com.
+gmail.com.
+twitter-widgets.s3.amazonaws.com.
+www.deviajeabrasil.com.
+bin-short.whatsapp.net.
+websms.orange.es.
+www.google-analytics.com.
+101.62.217.196.in-addr.arpa.
+www.playfirst.com.
+whos.amung.us.
+laptopsgadgets.com.
+www.betamarket.info.
+safebrowsing-cache.google.com.
+171.173.168.192.in-addr.arpa.
+a.root-servers.net.
+a1.v.phobos.apple.com.
+www.monster.at.
+s0.2mdn.net.
+ax.init.itunes.apple.com.
+jajajajawww.facebook.com.
+172.53.44.24.in-addr.arpa.
+a7.sphotos.ak.fbcdn.net.
+fbcdn-photos-a.akamaihd.net.
+narutofriends.foro-argentina.net.
+photos-a.ak.fbcdn.net.
+sac.gti.mcafee.com.
+47.191.78.84.in-addr.arpa.
+nb8tl9z:1.38lr.
+teledeporteonline12.chatango.com.
+www.keek.com.
+static.avast.com.
+72.26.247.83.in-addr.arpa.
+175.211.118.93.in-addr.arpa.
+r.66.ru.
+ns.gov.gu.
+cleavelandbrowns.com.
+pref.email.wetv.com.
+ad.adserve.com.
+www.care-bears.com.
+197.80.149.187.in-addr.arpa.
+231.175.55.190.in-addr.arpa.
+mk-mx-4.b2b.tiscali.co.uk.
+www.google.com.
+tracker.tjgame.enorth.com.cn.
+coffeeandwine.com.
+www.freelivejasmincams.com.
+ebadalrhman.yoo7.com.
+www.feet-sniffing.com.
+horaceroweb.disqus.com.
+elit36.ru.
+i2.ytimg.com.
+a7.sphotos.ak.fbcdn.net.
+a.root-servers.net.
+teredo.ipv6.microsoft.com.
+aaa-calif.com.
+proofpoint1.dordcs.org.
+a8.sphotos.ak.fbcdn.net.
+hpcs.bvsalud.org.
+b-0.19-2300a008.11481.1518.19d3.3ea1.410.0.hukp6abflsusuhjnckn31hgnlj.avqs.mcafee.com.
+dencinconsulting.com.
+a.root-servers.net.
+a3.sphotos.ak.fbcdn.net.
+a1404.w41.akamai.net.
+www.facebook.com.
+dns.msftncsi.com.
+profile.ak.fbcdn.net.
+drivingclub.com.
+besthairstyles.tk.
+www.davidpaulmorris.com.
+54.133.145.120.in-addr.arpa.
+profile.ak.fbcdn.net.
+csi.gstatic.com.
+googleads.g.doubleclick.net.
+b.scorecardresearch.com.
+t3.gstatic.com.
+220.172.190.186.in-addr.arpa.
+widgets.amung.us.
+cma-italia.com.
+versatel.de.
+145.175.167.118.in-addr.arpa.
+www.poolred.com.
+undiesaddiction.tumblr.com.
+a.root-servers.net.
+e4733.b.akamaiedge.net.
+smtp.conamex.com.
+a.root-servers.net.
+45.110.183.114.in-addr.arpa.
+16.64.238.80.in-addr.arpa.
+a.root-servers.net.
+creative.ak.fbcdn.net.
+40.234.225.77.in-addr.arpa.
+p01-bookmarks.icloud.com.
+42.47.164.187.in-addr.arpa.
+a787.phobos.apple.com.
+apps.facebook.com.
+58.131.91.186.in-addr.arpa.
+109.119.75.65.in-addr.arpa.
+mail.vmje.com.
+7.251.158.187.in-addr.arpa.
+t.co.
+profile.ak.fbcdn.net.
+modeminksigns.com.
+rew.no-ip.info.
+pbid.iforex.com.
+f806.mail.yahoo.com.
+scribe.twitter.com.
+157.81.240.189.in-addr.arpa.
+tetraprint.ru.
+ocsp.godaddy.com.
+phone.com.
+s-static.ak.facebook.com.
+14.52.101.187.in-addr.arpa.
+fbcdn-photos-a.akamaihd.net.
+store3.up-00.com.
+www.wholesaleclothing4u.com.
+www.nlm.nih.gov.
+ad-g.doubleclick.net.
+122.28.167.190.in-addr.arpa.
+a.root-servers.net.
+br.answers.yahoo.com.
+t1.gstatic.com.
+ja-jp.facebook.com.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+images.apple.com.
+montreal.olx.ca.
+textilescachicadan.blogspot.com.
+googleads.g.doubleclick.net.
+a.root-servers.net.
+146.36.205.190.in-addr.arpa.
+no.nonsense.ee.
+www.web-ideas.com.au.
+220.255.81.186.in-addr.arpa.
+www-valusoft-com.wip.digitalrivercontent.net.
+190.189.112.186.in-addr.arpa.
+228.102.19.189.in-addr.arpa.
+a.root-servers.net.
+118.128.241.201.in-addr.arpa.
+i3.ytimg.com.
+news.ottoversand.at.
+secure.wlxrs.com.
+dns.msftncsi.com.
+olgatanon.com.
+38.116.143.189.in-addr.arpa.
+l.yimg.com.
+4124234.frasesinolvidables1.com.ar.
+lugaresquever.tumblr.com.
+api-read.facebook.com.
+twimg0-a.akamaihd.net.
+km-brown.com.
+row.bc.yahoo.com.
+jjue268rp.52nb.
+mail.swot-analysis.ru.
+us.jobomas.com.
+a.root-servers.net.
+a.root-servers.net.
+promonegocios.net.
+a5.sphotos.ak.fbcdn.net.
+tms30.icrc.trendmicro.com.
+static.ak.fbcdn.net.
+zgn.static.zynga.com.
+luvthatdrtywata.livejournal.com.
+photos-f.ak.fbcdn.net.
+237.173.170.201.in-addr.arpa.
+a323.yahoofs.com.
+_631_53_3.
+fast-autos.net.
+0-jg-w.channel.facebook.com.
+aidps.atdmt.com.
+doha.oilfield.slb.com.
+putnam.com.s7b2.psmtp.com.
+billing.sharo4ka.ru.
+www.facebook.com.
+illiweb.com.
+bbs.chinasiemens.com.
+www.facebook.com.
+finance.yahoo.com.
+157.247.85.24.in-addr.arpa.
+ikm.com.ua.
+yahoo.com.
+www.google.co.id.
+hugheslandscaping.com.
+d2091827.xoom.it.
+184.206.180.68.in-addr.arpa.
+iwl.com.
+www.mozilla.com.
+www.sems.gob.mx.
+profile.ak.fbcdn.net.
+103.44.135.66.in-addr.arpa.
+en.1000mikes.com.
+apple-mobile.query.yahooapis.com.
+ib.adnxs.com.
+icons.iconator.com.
+zynga2-a.akamaihd.net.
+aol.com.
+a.root-servers.net.
+a1090.v.phobos.apple.com.
+www.msftncsi.com.
+220.198.121.200.in-addr.arpa.
+latam.preciomania.com.
+req.appads.com.
+api.twitter.com.
+rosich-logistic.ru.
+a.root-servers.net.
+93.202.173.190.in-addr.arpa.
+us.mg6.mail.yahoo.com.
+crl.microsoft.com.
+andrescanavesi.com.uy.
+canyouplaypes.com.
+images01.spacash.com.
+safebrowsing.clients.google.com.
+116.208.24.81.in-addr.arpa.
+isss.gob.sv.
+imap.gmail.com.
+clients1.google.com.
+nestag.com.
+wheatdesign.com.
+sunct2.jinr.ru.
+profiles.google.com.
+a6.sphotos.ak.fbcdn.net.
+_319_42_3.
+www.clarin.com.
+www.google-analytics.com.
+www.youngandbusty.net.
+static.ak.fbcdn.net.
+244.37.112.186.in-addr.arpa.
+corbettharper.com.
+ar-ar.facebook.com.
+0-317.channel.facebook.com.
+a.root-servers.net.
+pixel.facebook.com.
+a.root-servers.net.
+platform.ak.fbcdn.net.
+clients-cctld.l.google.com.
+accountservices.passport.net.
+input2.comment.qq.com.
+mx.2niteline.com.
+api-public.addthis.com.
+www.achtzehn99.de.
+ict.tgw.com.
+_ldap._tcp.
+_207_75_1.
+bubba.ntrade.it.
+stealth.y9.vc.
+www.nyhotties.com.
+groups.google.com.ua.
+97.34.252.189.in-addr.arpa.
+inbound.ranatech.com.netsolmail.net.
+24.193.0.181.in-addr.arpa.
+107.137.69.190.in-addr.arpa.
+gfx3.hotmail.com.
+m.motortrend.com.
+webcache.googleusercontent.com.
+www.usgs.gov.
+miscancionesinfantiles.disqus.com.
+images.empora.com.
+es-la.facebook.com.
+engine.demo.medialand.ru.
+external.ak.fbcdn.net.
+www.google.com.
+www.benalmadena.es.
+49.78.173.201.in-addr.arpa.
+38.176.120.200.in-addr.arpa.
+www.avis.co.uk.
+clients1.google.com.
+static.ak.facebook.com.
+www.king-bearings.com.
+mail2.eplushealthcare.com.
+dem0003.in.
+www.facebook.com.
+smart-journal.ru.
+www.facebook.com.
+mysp.ac.
+xr562c2a9.k17m6d2t.
+a5.sphotos.ak.fbcdn.net.
+243.139.1.46.in-addr.arpa.
+19.43.112.99.in-addr.arpa.
+accounts.google.com.
+130.172.185.58.in-addr.arpa.
+yahoo.com.
+google.com.
+0-ji-w.channel.facebook.com.
+static2.bitacoras.com.
+img.huanleguang.com.
+a.root-servers.net.
+photos-e.ak.fbcdn.net.
+developers.facebook.com.
+106.98.93.186.in-addr.arpa.
+222.211.152.201.in-addr.arpa.
+sites.google.com.
+a.root-servers.net.
+sp.cwfservice.net.
+validator.w3.org.
+52.197.28.181.in-addr.arpa.
+www.descargarmanuales.com.ar.
+de-de.facebook.com.
+7.106.180.69.in-addr.arpa.
+titanium30-en.url.trendmicro.com.
+www.facebook.com.
+transmotion.pt.
+www.cmu.org.mx.
+251.107.104.187.in-addr.arpa.
+a7.sphotos.ak.fbcdn.net.
+152.47.254.201.in-addr.arpa.
+www.internetzona.pl.
+239.203.132.189.in-addr.arpa.
+nappyboyonline.com.
+tc.v20.cache3.c.youtube.com.
+mail.surferie.net.
+118.174.109.186.in-addr.arpa.
+www.jewelryshop.bz.
+a.root-servers.net.
+cust4181-3.in.mailcontrol.com.
+whiskeyandgunpowder.com.
+teredo.ipv6.microsoft.com.
+relay3.geoksc.apatity.ru.
+arandomurl.com.
+29.193.171.124.in-addr.arpa.
+cm.ar.taringa.overture.com.
+13.152.168.192.in-addr.arpa.
+hit.trafficholder.com.
+googleads.g.doubleclick.net.
+download2.nexon.net.
+www.googleadservices.com.
+nxcache.nexon.net.
+yahoo.com.
+a3.sphotos.ak.fbcdn.net.
+dc.logmein-gateway.com.
+a.root-servers.net.
+flazm.disqus.com.
+122.178.153.189.in-addr.arpa.
+photos-d.ak.fbcdn.net.
+145.1.189.190.in-addr.arpa.
+acicapital.com.s8b2.psmtp.com.
+a1416.g.akamai.net.
+a.root-servers.net.
+static.socialvi.be.
+prod2.rest-core.msg.yahoo.com.
+a7.sphotos.ak.fbcdn.net.
+dlactn.org.
+welcometointernet.org.
+content.yieldmanager.edgesuite.net.
+ewingl.com.
+client-software.real.com.
+123.4.87.66.in-addr.arpa.
+www.googleadservices.com.
+s-static.ak.fbcdn.net.
+eusdwsmail010.logistics.corp.
+apps.facebook.com.
+104.62.162.109.in-addr.arpa.
+188.186.10.186.in-addr.arpa.
+aol.com.
+_656_10_5.
+120.14.160.187.in-addr.arpa.
+164.117.52.186.in-addr.arpa.
+meizen40.net.
+www.wip4.adobe.com.
+hddiziizle.net.
+www.congresoahila2011.com.
+s.ytimg.com.
+media.admob.com.
+srx.main.ebayrtm.com.
+safebrowsing-cache.google.com.
+xheli.com.
+www.google-analytics.com.
+81.172.131.189.in-addr.arpa.
+consults.ru.
+a.root-servers.net.
+www.drbrandtskincare.com.
+112.77.203.87.in-addr.arpa.
+226.164.160.187.in-addr.arpa.
+wdbj7.com.
+fbcdn-profile-a.akamaihd.net.
+www.sina.com.
+b._dns-sd._udp.0.0.168.192.in-addr.arpa.
+.
+a.root-servers.net.
+a1.sphotos.ak.fbcdn.net.
+att.net.
+www.androiddownloadnow.com.
+16.88.73.77.in-addr.arpa.
+_857_76_7.
+www.theworldrecipebook.com.
+www.docs.sony.com.
+images-71.har.com.
+intelliswitch.net.
+www.mdsone.com.
+tinyurl.com.
+n4403ad.doubleclick.net.
+photos-f.ak.fbcdn.net.
+dns.msftncsi.com.
+fbcdn-sphotos-a.akamaihd.net.
+www.anxer.net.
+ucom.net.
+250.255.114.200.in-addr.arpa.
+liveupdate.symantecliveupdate.com.
+143.201.141.201.in-addr.arpa.
+aol.com.
+www.google-analytics.com.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+hdl.loc.gov.
+h.live.com.
+162.163.243.201.in-addr.arpa.
+photos-g.ak.fbcdn.net.
+152.0.32.189.in-addr.arpa.
+:fqf33dir.62ez.
+www.rankspirit.com.
+21m86g2s8.65cj.
+algebra-net.programas-gratis.net.
+a.root-servers.net.
+gfx4.hotmail.com.
+csi.gstatic.com.
+a.adcloud.net.
+0-244.channel.facebook.com.
+www.ridiculopathy.com.
+www.google.cpm.
+www.administradores-empresas.com.
+resolver5.pand.ctmail.com.
+youtube-ui.l.google.com.
+60.242.243.189.in-addr.arpa.
+time.chttl.com.tw.
+flatironcorp.com.inbound10.mxlogicmx.net.
+ar-ar.facebook.com.
+245.138.188.76.in-addr.arpa.
+184.77.136.190.in-addr.arpa.
+thumbs1.ebaystatic.com.
+dte.sellpoint.net.
+creative.ak.fbcdn.net.
+31.102.104.189.in-addr.arpa.
+tobolsk.info.
+ntp1.cs.wisc.edu.
+147.209.177.79.in-addr.arpa.
+mail.gb.avtograd.ru.
+awjarcitects.com.
+hi-in.facebook.com.
+twimg0-a.akamaihd.net.
+photos-h.ak.fbcdn.net.
+google.com.
+.
+i4.ytimg.com.
+bottleofjack.tumblr.com.
+i1.ytimg.com.
+137.29.31.190.in-addr.arpa.
+sn1msg2020222.gateway.messenger.live.com.
+eskimovie.com.
+www.facebook.com.
+profile.ak.fbcdn.net.
+www.culturalivre.net.
+amazonm-722.vo.llnwd.net.
+content.yieldmanager.edgesuite.net.
+127.198.30.186.in-addr.arpa.
+98.59.50.201.in-addr.arpa.
+197.240.21.190.in-addr.arpa.
+www.xbox360.com.
+www.cochilco.cl.
+platform.ak.fbcdn.net.
+secure.wlxrs.com.
+service6.pricegong.com.
+a1108.da1.akamai.net.
+s.ytimg.com.
+www.cpmr.org.
+service.ess.apple.com.
+www.digitalscores.us.
+175.219.138.189.in-addr.arpa.
+16.96.98.189.in-addr.arpa.
+126.189.237.190.in-addr.arpa.
+joystiq.search.aol.com.
+131.37.183.189.in-addr.arpa.
+imagenes.es.sftcdn.net.
+beacon.lijit.com.
+www.conapo.gob.mx.
+img.rincondelvago.com.
+www.consultas.curp.gob.mx.
+163.39.199.190.in-addr.arpa.
+www.google-analytics.com.
+pagead2.googlesyndication.com.
+baymsg1030121.gateway.messenger.live.com.
+ruscrete.co.uk.
+urethanesupply.com.s8b2.psmtp.com.
+128.26.45.187.in-addr.arpa.
+i182.photobucket.com.
+dogs2.ngmoco.com.
+218.210.67.94.in-addr.arpa.
+www.google-analytics.com.
+dnl-ru5.kaspersky-labs.com.
+90.73.213.74.in-addr.arpa.
+mail.masstop.com.
+www.facebook.com.
+plusone.google.com.
+creative.ak.fbcdn.net.
+sites.google.com.
+116.96.90.195.in-addr.arpa.
+fm.ru.
+leaelliott.com.s6b2.psmtp.com.
+accounts.google.com.
+www.fotosdesexo.org.es.
+teredo.ipv6.microsoft.com.
+ggames.com.br.
+70.103.34.189.in-addr.arpa.
+www2.sherwin-williams.com.
+a749.g.akamai.net.
+afasic.org.uk.
+170.134.246.85.in-addr.arpa.
+s0002113.ecdomain.net.
+accounts.google.com.
+photos-c.ak.fbcdn.net.
+www.cubatravelusa.com.
+london.langhamhotels.co.uk.
+tracker.ydy.com.
+fonts.googleapis.com.
+56.172.114.177.in-addr.arpa.
+www.ma-recreation.com.
+lengthenyourstride.com.
+voipa.sip.yahoo.com.
+mercury.stdominic.net.
+a.root-servers.net.
+www.blackberry.com.
+wakeboard.es.
+112.239.171.189.in-addr.arpa.
+fitnessysalud.blogspot.com.
+www.webgradnja.hr.
+www.lifehealthcare.co.za.
+profile.ak.fbcdn.net.
+pix:t1kbx.75nr.
+218.176.2.88.in-addr.arpa.
+thepregnantnudes.com.
+ad.xtendmedia.com.
+emailnotifier.services.conduit.com.
+ksn2-12.kaspersky-labs.com.
+carbsense.com.
+251.134.10.221.in-addr.arpa.
+news.google.es.
+assets.rubiconproject.com.
+247.117.201.74.in-addr.arpa.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+mail.google.com.
+i163.photobucket.com.
+209.104.223.87.in-addr.arpa.
+a.root-servers.net.
+i.w.inmobi.com.
+widgets.twimg.com.
+toolbar.live.com.
+fbcdn-photos-a.akamaihd.net.
+9gag.com.
+static.ak.fbcdn.net.
+146.57.126.187.in-addr.arpa.
+media.sas.upenn.edu.
+mx2.jetisi.com.
+www.marketingdebusca.com.br.
+216.54.38.187.in-addr.arpa.
+mplguam.com.
+www.redfugios.org.
+a1001.w40.akamai.net.
+a.root-servers.net.
+video.l3.fbcdn.net.
+50.2.255.220.in-addr.arpa.
+golfthelinks.com.
+107.164.86.69.in-addr.arpa.
+wegroup.ru.
+uk.mcafee.com.
+a.root-servers.net.
+a.root-servers.net.
+cs9306.vk.com.
+rcp.na.blackberry.com.
+.
+_ldap._tcp.pdc._msdcs.neoris.cxnetworks.net.
+51.189.251.76.in-addr.arpa.
+6.86.139.216.in-addr.arpa.
+ad.z5x.net.
+25.181.248.89.in-addr.arpa.
+110.253.10.200.in-addr.arpa.
+f.snagfilms.com.
+view.atdmt.com.
+h4f5mx4zk.s03u3n2a.
+105.70.41.187.in-addr.arpa.
+www.theshangri-las.com.
+es-la.facebook.com.
+www.embrujo.net.
+smtp.dumonds.com.
+profile.ak.fbcdn.net.
+112.150.11.76.in-addr.arpa.
+a.root-servers.net.
+googleads.g.doubleclick.net.
+us.bc.yahoo.com.
+cs1926.vk.com.
+smtp.webcravings.com.
+static.ak.fbcdn.net.
+a7.sphotos.ak.fbcdn.net.
+wickedthemusical.com.sg.
+a7.sphotos.ak.fbcdn.net.
+www.facebook.com.
+www.microsoft.com.
+ntp1.dlink.com.
+bial.pl.
+yahoo.com.
+34.1.157.201.in-addr.arpa.
+www.kronosgo.com.
+251.72.85.86.in-addr.arpa.
+www.google.com.
+appsforbb.com.
+chaminade.edu.
+109.189.132.41.in-addr.arpa.
+www.google.com.
+39.32.48.190.in-addr.arpa.
+www.bricolageymanualidades.com.
+34-courier.push.apple.com.
+.
+a2.sphotos.ak.fbcdn.net.
+0-299.channel.facebook.com.
+a.root-servers.net.
+go.microsoft.com.
+www.usa.gov.
+content.yieldmanager.edgesuite.net.
+17.8.137.2.in-addr.arpa.
+52.169.16.87.in-addr.arpa.
+gfx2.hotmail.com.
+c5a.ah.yahoo.com.
+p02-ubiquityws.icloud.com.
+mail.live.com.
+sn102w.snt102.mail.live.com.
+matcher-cwb.bidder7.mookie1.com.
+218.152.130.189.in-addr.arpa.
+geo.messenger.services.live.com.
+a1505.l.akamai.net.
+gt.eredan.com.
+fr-fr.facebook.com.
+www.energiainterior.com.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+a.root-servers.net.
+a1.sphotos.ak.fbcdn.net.
+sm-beta.ovi.messaging.nokia.com.
+external.ak.fbcdn.net.
+api-read.facebook.com.
+hub-odc.samsungapps.com.
+mail.jetmotors.perm.ru.
+voipb.sip.yahoo.com.
+22.133.10.186.in-addr.arpa.
+js.blinkadr.com.
+www.denobisipsis.es.
+schnaapklicks.com.
+www-google-analytics.l.google.com.
+169.87.231.190.in-addr.arpa.
+pubads.g.doubleclick.net.
+www.facebook.com.
+n-link.com.
+170.56.246.201.in-addr.arpa.
+209.170.137.187.in-addr.arpa.
+fxfeeds.mozilla.com.
+158.3.76.70.in-addr.arpa.
+download.live.com.
+pts.lockerz.com.
+75.183.98.62.in-addr.arpa.
+41.126.81.216.in-addr.arpa.
+q6pesnyqz.50lc.
+mediastreet.ca.s7a2.psmtp.com.
+nds.wiktionary.org.
+svrsecure-g2-aia.verisign.com.
+a.root-servers.net.
+tracker.thepiratebay.org.
+dns.msftncsi.com.
+www.crautonoma.gov.co.
+128.7.6.186.in-addr.arpa.
+kalininrad.ru.
+hccsmg.com.
+v529.vkadre.ru.
+report.cedexis.com.
+platform.twitter.com.
+actionrealtyks.com.
+suggestqueries.google.com.
+blog.outsystems.com.
+gameofthrones.wikia.com.
+dutchschulze.com.
+api.twitter.com.
+datinggold.com.s10b1.psmtp.com.
+www.mspca.org.
+random.frivolity.info.
+www.hotmail.com.
+8l1vqiyzr.s33b9p9z.
+tracker.openbittorrent.com.
+www.facebook.com.
+www.radioradar.net.
+la.dynonobel.com.
+solarus.biz.
+nada5.com.
+1.0.0.127.dnsbugtest.1.0.0.127.in-addr.arpa.
+mhatoday.org.
+compaq.mbservice.pp.ru.
+a-0.19-330f3081.9110081.1518.19d3.2f1c.10.0.5wauzj8kclu1up9r1vmvdufkaj.avqs.mcafee.com.
+elstatic.weborama.fr.
+33.176.49.216.in-addr.arpa.
+biosantepharma.com.2.0001.arsmtp.com.
+fr-fr.facebook.com.
+105.1.168.192.in-addr.arpa.
+mowt.gov.tt.
+www.jetcero.com.
+ambience.com.
+r._dns-sd._udp.0.0.168.192.in-addr.arpa.
+photos-e.ak.fbcdn.net.
+download.www.arte.tv.
+cs4484.vk.com.
+bmj-logistics.ru.
+itf-ost.ru.
+wallpapers.desicomments.com.
+www.cmtpetconferences.com.
+www.radio.com.pl.
+itunes.apple.com.
+a.root-servers.net.
+206.109.136.78.in-addr.arpa.
+247.178.255.201.in-addr.arpa.
+becmfg.com.
+124.147.136.190.in-addr.arpa.
+a.root-servers.net.
+www.gstatic.com.
+tumblon.com.
+1.bp.blogspot.com.
+b._dns-sd._udp.0.1.168.192.in-addr.arpa.
+rmd.atdmt.com.
+photos-e.ak.fbcdn.net.
+ad.yieldads.com.
+www.galeriaseroticas.xpg.com.br.
+ad.yieldmanager.com.
+usiko.ru.
+bs.serving-sys.com.
+mail3.sisk.ie.
+www.macauhotel.org.
+dns.msftncsi.com.
+s-static.ak.fbcdn.net.
+smtp.ci.lenexa.ks.us.
+239.58.31.190.in-addr.arpa.
+65.217.37.62.in-addr.arpa.
+www.liujo.it.
+s1-excel.vo.msecnd.net.
+villaluro.olx.com.ar.
+www.transexualesfollando.org.
+agmkoq.com.
+medlinia.ru.
+www.facebook.com.
+www.belajarkonseling.com.
+csi.gstatic.com.
+mypisamba4.com.
+a.root-servers.net.
+connect.facebook.net.
+231.39.176.186.in-addr.arpa.
+167.153.155.189.in-addr.arpa.
+a.root-servers.net.
+205.252.113.186.in-addr.arpa.
+docs.google.com.
+androcode.es.
+a1.sphotos.ak.fbcdn.net.
+photos-a.ak.fbcdn.net.
+a.root-servers.net.
+velikanrostov.ru.
+pixel.rubiconproject.com.
+thomcoins.com.
+leaderit.ru.
+photos-d.ak.fbcdn.net.
+a.root-servers.net.
+a4.sphotos.ak.fbcdn.net.
+i2.ytimg.com.
+ad.yieldmanager.com.
+b._dns-sd._udp.0.1.168.192.in-addr.arpa.
+i3.ytimg.com.
+chivaselmejorequipodemexico.blogspot.com.
+translate.googleapis.com.
+equico.net.
+time.stdtime.gov.tw.
+residentialsearch.savills.co.uk.
+42.31.207.112.in-addr.arpa.
+54.49.59.189.in-addr.arpa.
+www.famemonsters.com.
+fromdoppler.com.rbl2.mcafee.com.
+services.leapfrog.com.
+64.38.14.186.in-addr.arpa.
+www.ademails.com.
+s-static.ak.fbcdn.net.
+photos-b.ak.fbcdn.net.
+lovefilm.dl.playstation.net.
+77.93.106.200.in-addr.arpa.
+external.ak.fbcdn.net.
+melapuedencerrar.com.
+landing.ancestry.co.uk.
+72.105.22.186.in-addr.arpa.
+53.80.7.69.in-addr.arpa.
+a.root-servers.net.
+71.183.64.181.in-addr.arpa.
+mail.google.com.
+rp.rusal.ru.
+1.0.0.127.dnsbugtest.1.0.0.127.in-addr.arpa.
+s.clicktale.net.
+hotmaiwww.facebook.com.
+35.126.150.114.in-addr.arpa.
+divulgalia.blogspot.com.
+a.root-servers.net.
+a3.sphotos.ak.fbcdn.net.
+www.inbox.com.
+a.root-servers.net.
+150.53.31.173.in-addr.arpa.
+browsersync.google.com.
+translate.google.com.
+toolbarqueries.google.com.mx.
+es.kioskea.net.
+197.72.51.201.in-addr.arpa.
+a5.sphotos.ak.fbcdn.net.
+30.229.171.69.in-addr.arpa.
+www.puertasabiertas.org.
+dlm.com.
+dr._dns-sd._udp.0.179.16.172.in-addr.arpa.
+i1.ytimg.com.
+aol.rr.com.
+www.clasimexico.com.
+www.fundacionsantillana.org.co.
+www.kittierocks.com.
+rihdntv1p.67rg.
+opensuse-community.org.
+yui.yahooapis.com.
+cbp-us.nccp.netflix.com.
+203.123.154.95.in-addr.arpa.
+a.root-servers.net.
+mx.psport.ru.
+scholar.google.com.ar.
+server.kan.nnov.ru.
+xml.pricegong.com.
+utils.babylon.com.
+www.learning4good.net.
+42.36.20.190.in-addr.arpa.
+www.tarjetasbubba.com.
+a3.sphotos.ak.fbcdn.net.
+www.facebook.com.
+kyx2m6jkm.45dg.
+a.root-servers.net.
+x-journal.net.
+abierto-hasta-el-amanecer-2-texas-blood-money.peliculon.tv.
+www.google.com.
+150.90.190.41.in-addr.arpa.
+fonts.foxsports.com.
+182.162.93.186.in-addr.arpa.
+ad.yieldmanager.com.
+a.root-servers.net.
+dns.msftncsi.com.
+dewater.com.inbound15.mxlogicmx.net.
+www.djonty.com.ar.
+shydude.deviantart.com.
+www.cellreception.com.
+.
+d2089652.xoom.it.
+sensorprod.com.
+dlvr.it.
+a6.sphotos.ak.fbcdn.net.
+accounts.google.com.
+145.162.4.46.in-addr.arpa.
+soic.us.
+200.101.40.84.in-addr.arpa.
+burton-homes.com.
+gateway.messenger.hotmail.com.
+gtaonline.com.ar.
+photos-d.ak.fbcdn.net.
+102.193.23.186.in-addr.arpa.
+img.youtube.com.
+126.162.226.186.in-addr.arpa.
+_072_67_4.
+static.ak.fbcdn.net.
+www.facebook.com.
+api.facebook.com.
+poorva.com.
+galleries.hdhardcore.com.
+aaa.com.au.
+adval.com.
+smartphone-gprs-traffic-monitor.softonic.com.
+mobile.login.yahoo.com.
+234.83.198.112.in-addr.arpa.
+s-static.ak.fbcdn.net.
+aservise.ru.
+a8.sphotos.ak.fbcdn.net.
+photos-a.ak.fbcdn.net.
+mail.jump-out.dk.
+asprotech.blogspot.com.
+chilesintransgenicos.cl.
+a.root-servers.net.
+www.wikimail.org.
+mail.google.com.
+www.facebook.com.
+48.116.239.216.in-addr.arpa.
+36.142.211.201.in-addr.arpa.
+cdn-static.liverail.com.
+adsx.greystripe.com.
+136.6.94.186.in-addr.arpa.
+usersystem783aa.ru.
+a5.sphotos.ak.fbcdn.net.
+6.183.247.88.in-addr.arpa.
+mtalk.google.com.
+external.ak.fbcdn.net.
+i1.ytimg.com.
+dns.msftncsi.com.
+accounts.google.com.
+googleads.g.doubleclick.net.
+219.49.184.190.in-addr.arpa.
+apis.google.com.
+www.thehabibshow.com.
+monduce.com.
+pagead2.googlesyndication.com.
+www.somewrinkles.blogspot.com.
+developers.facebook.com.
+sites.google.com.
+sadinsa.com.
+newsrss.bbc.co.uk.
+100.69.35.83.in-addr.arpa.
+194.48.101.118.in-addr.arpa.
+autohubasia.com.
+billing.sharo4ka.ru.
+www.verwandt.de.
+147.145.51.201.in-addr.arpa.
+dnl-01.geo.kaspersky.com.
+b._dns-sd._udp.lan.
+vereltrailersdelapelicula.blogspot.com.
+illinoisfamily.org.
+s-static.ak.fbcdn.net.
+www.the-best-web-hosting-service.com.
+login.live.com.
+www.bbm.com.
+it-it.facebook.com.
+www.sptfm.ro.
+mx2.inertiainteractive.net.
+s.ytimg.com.
+redirector.c.youtube.com.
+ads.bluelithium.com.
+a8.sphotos.ak.fbcdn.net.
+commercebankmn.com.s8b2.psmtp.com.
+alcgs34ma.20oh.
+www.foto.technetium.be.
+db11.spamcatcher.net.
+www.yanmar.com.
+6.79.170.189.in-addr.arpa.
+a6.sphotos.ak.fbcdn.net.
+a8.sphotos.ak.fbcdn.net.
+teredo.ipv6.microsoft.com.
+a.root-servers.net.
+mx.youtube.com.
+yui.yahooapis.com.
+a.root-servers.net.
+b._dns-sd._udp.0.1.168.192.in-addr.arpa.
+client.akamai.com.
+si0.twimg.com.
+badoo.com.
+too-drunk-to-dream.tumblr.com.
+andovercollege.com.
+www.europa-lkw.de.
+169.133.205.186.in-addr.arpa.
+www.capecentralhigh.com.
+hg3.ceryxefw.com.
+mail.thunda.com.
+safebrowsing-cache.google.com.
+bit.ly.
+flounderart.com.
+evsecure-crl.verisign.com.
+mx.naruto-ll.com.
+a4.sphotos.ak.fbcdn.net.
+svaepro.weebly.com.
+photos-d.ak.fbcdn.net.
+a4.sphotos.ak.fbcdn.net.
+photos-c.ak.fbcdn.net.
+thefusebox.com.s200b2.psmtp.com.
+s0.2mdn.net.
+31.246.48.186.in-addr.arpa.
+www.richandbrainless.com.
+cs504605.vk.com.
+a8.sphotos.ak.fbcdn.net.
+s-static.ak.fbcdn.net.
+28.252.16.177.in-addr.arpa.
+www.facebook.com.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+167.239.141.201.in-addr.arpa.
+orig-10002.productmadness.cotcdn.net.
+a6.sphotos.ak.fbcdn.net.
+beta.stun.voice.yahoo.com.
+aol.com.
+api.looklater.com.
+safemoods.com.
+connect.facebook.net.
+entretenimiento.prodigy.msn.com.
+www.legalmovz.info.
+mustin.com.inbound15.mxlogicmx.net.
+www.mtit.com.
+www.facebook.com.
+pagead2.googlesyndication.com.
+www.youtube.com.
+download.windowsupdate.com.
+2.51.214.189.in-addr.arpa.
+v8.secure.nfstr.ea.com.
+www.youtube.com.
+157.0.103.71.in-addr.arpa.
+mailin-01.netatlantic.com.
+a6.sphotos.ak.fbcdn.net.
+110.69.231.190.in-addr.arpa.
+texarkanagastroenterology.com.
+static.app.widdit.com.
+_592_84_1.
+alsmithtrucking.com.
+zoom.co.uk.home.
+d2092102.xoom.it.
+www.discoveryindochina.com.
+api-read.facebook.com.
+secure.easycgi.com.
+51.235.178.190.in-addr.arpa.
+www.dic.org.ar.
+members.ebonymax.com.
+oliver-tour.ru.
+nero-move-it.programas-gratis.net.
+missrowlandgifs.tumblr.com.
+www.facebook.com.
+api.twitter.com.
+s.youtube.com.
+www.facebook.com.
+a-0.19-2309d081.99a0083.1518.19cf.3ea1.410.0.6eka98rdd5n7fllv2bglmpqiti.avqs.mcafee.com.
+1.bp.blogspot.com.
+www-hotmail-com.com.
+proyectodeartecasiopea.blogspot.com.
+binladen.ru.
+112.135.14.181.in-addr.arpa.
+photos-a.ak.fbcdn.net.
+s-static.ak.fbcdn.net.
+config.messenger.msn.com.
+a1.sphotos.ak.fbcdn.net.
+essen.vol.at.
+151.146.220.121.in-addr.arpa.
+sadownload.mcafee.com.
+207.60.70.208.in-addr.arpa.
+jamn945.com.
+blogs.elpais.com.
+static.ak.fbcdn.net.
+52.36.94.174.in-addr.arpa.
+www.bing.com.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+img4.catalog.video.msn.com.
+188.149.40.201.in-addr.arpa.
+www.googleadservices.com.
+groups.google.com.mx.
+www.mybabyexperts.tv.
+www.flirteos.com.
+www.lemec.net.
+44.81.208.190.in-addr.arpa.
+mail.vuria.com.
+www.rmcoin.com.
+code.jquery.com.
+advert-king.tk.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+a.root-servers.net.
+a.root-servers.net.
+www.google.com.
+profile.ak.fbcdn.net.
+www.paulownia.ws.
+s.ytimg.com.
+u512.badoo.com.
+www.20minutos.es.
+www.youtube.com.
+vsml.com.
+154.245.7.190.in-addr.arpa.
+mail.pmdl.com.au.
+signup.doitbiatch.com.
+51.121.113.94.in-addr.arpa.
+a.root-servers.net.
+xovoyrolqppifp.net.
+fbcdn-photos-a.akamaihd.net.
+www.noticias.com.ve.
+127.26.51.190.in-addr.arpa.
+luc19msnxl38izbrcxpqizl48kyjuc29iqb38.ru.
+cmu.edu.
+ad.adserverplus.com.
+www.younggunsmusic.com.
+www.foodmag.co.nz.
+23.68.149.189.in-addr.arpa.
+api.facebook.com.
+www.cruelebony.com.
+_903_44_1.
+developers.facebook.com.
+kittysnooks.blogspot.com.
+d2ud4lg6esq2e1.cloudfront.net.
+252.101.105.189.in-addr.arpa.
+131.47.132.190.in-addr.arpa.
+photos-e.ak.fbcdn.net.
+ct.buzzfeed.com.
+mail.acu.net.
+api.facebook.com.
+s-static.ak.fbcdn.net.
+www.clubbisexual.com.
+www.sirintipgreenhome.com.
+173.53.168.189.in-addr.arpa.
+84.187.110.123.in-addr.arpa.
+i2.ytimg.com.
+vevideo.com.es.
+c.perf.glbdns.microsoft.com.
+support.live.com.
+dag.de.
+www.google.com.
+www.amateurdarling.com.
+online.potencialhumanotv.tv.
+www.igui.ru.
+www.conocer.gob.mx.
+sabores.com.
+i1.ytimg.com.
+o31fsfrlrmsf62j46bxotc19aqn50gqbwdya57.info.
+41.212.85.209.bl.spamcop.net.
+csi.gstatic.com.
+ksn2-12.kaspersky-labs.com.
+www.124marketingsystem.com.
+twitter.com.
+www.prnewschannel.com.
+242.255.207.190.in-addr.arpa.
+avatar.pic.itiexue.net.
+scala.ru.
+submit-stroke.ahajournals.org.
+www.google.com.
+a.root-servers.net.
+www.facebook.com.
+20.191.126.186.in-addr.arpa.
+a.c-0.19-210fe000.10590.1518.19d4.3ea1.210.0.rikjfg7q7l6iidkwd5rfk4vkbi.avqs.mcafee.com.
+dejhtq:j3.z52a9x8j.
+blackbookmag.com.
+static.ak.fbcdn.net.
+mail.netlife.ru.
+clientes.disegnia.com.
+blogs.monografias.com.
+fr.answers.yahoo.com.
+www.google.com.
+data.whicdn.com.
+_704_15_6.
+photos-e.ak.fbcdn.net.
+re.revolvermaps.com.
+poker.wincomparator.com.
+get.adobe.com.
+huellasdelbarrio.blogspot.com.
+214.248.67.208.in-addr.arpa.
+a2.sphotos.ak.fbcdn.net.
+yik7yflmh.59ya.
+commander.clara.net.
+photos4.hi5.com.
+ow.ly.
+a4.skype.tom.com.
+5uaxx4or3.20es.
+google.com.
+fbcdn-photos-a.akamaihd.net.
+a6.sphotos.ak.fbcdn.net.
+www.saveyourflight.de.
+a5.sphotos.ak.fbcdn.net.
+26.112.226.190.in-addr.arpa.
+external.ak.fbcdn.net.
+a.root-servers.net.
+pixel.facebook.com.
+89.172.171.69.in-addr.arpa.
+32.183.145.201.in-addr.arpa.
+a.root-servers.net.
+lb._dns-sd._udp.lan.
+mx.vardareast.com.
+youtu.be.
+google.com.
+www.lanvin.com.
+developers.facebook.com.
+wwwimages.adobe.com.
+secure-us.imrworldwide.com.
+d2098016.xoom.it.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+137.48.168.192.in-addr.arpa.
+alucinemodelkits.blogspot.com.
+windows-media-player-9-codecs-pack.programas-gratis.net.
+www.yoreparo.com.
+colin.uk.com.
+safebrowsing.clients.google.com.
+www.surya.com.
+www.oaed.gr.
+teredo.ipv6.microsoft.com.
+6.157.174.189.in-addr.arpa.
+242.15.57.85.in-addr.arpa.
+247.132.125.77.in-addr.arpa.
+google.com.
+cvgps.com.
+cloud1.opensystemsmedia.com.
+rude.hello-net.info.
+a.root-servers.net.
+remail.ru.
+msc.wlxrs.com.
+a7.sphotos.ak.fbcdn.net.
+472.ns1631261.com.
+billing.sharo4ka.ru.
+70.41.43.186.in-addr.arpa.
+upload.xhamster.com.
+statistics02.topface.ru.
+static.ak.connect.facebook.com.
+231.187.137.86.in-addr.arpa.
+155.227.88.186.in-addr.arpa.
+153.110.0.213.in-addr.arpa.
+mafbaymafbay.com.
+fwm3paslw.b42w7b5p.
+a.root-servers.net.
+stoli.com.
+www.worldsmostunique.com.
+www.mason-mahfili.org.tr.
+preflopraise.ru.
+123.155.26.85.in-addr.arpa.
+www.lamparasdeled.com.mx.
+accounts.google.com.
+petfooddirect.com.s10b1.psmtp.com.
+apps.facebook.com.
+secure.tagged.com.
+t.co.
+crl.microsoft.com.
+skpkurortgel.ru.
+ssl.gstatic.com.
+38.184.20.187.in-addr.arpa.
+a.root-servers.net.
+www.google-analytics.com.
+mx.dbaviation.com.
+www.nyfa.edu.
+latinotaku.ucoz.es.
+a.root-servers.net.
+yahoo.com.
+a.root-servers.net.
+cando-online.com.
+ad.doubleclick.net.
+cus.com.
+atss.lu.
+192.111.129.189.in-addr.arpa.
+169.48.96.38.in-addr.arpa.
+exchange.mbcco.com.
+www.goal.org.
+api.facebook.com.
+mail.zoom-dsl.com.
+h.live.com.
+168.244.143.69.in-addr.arpa.
+143.247.236.200.in-addr.arpa.
+1-ps.googleusercontent.com.
+www.octopusproject.eu.
+jmcwd.com.
+amhaire.com.
+josedelcorral.es.
+photos3.zillow.com.
+trainweb.info.
+3478052.megustasabelo.net.
+s-static.ak.fbcdn.net.
+www.cupcakesandcutlery.blogspot.com.
+222.186.4.181.in-addr.arpa.
+i2.ytimg.com.
+34.1.179.190.in-addr.arpa.
+goodyear.com.
+213.229.190.189.in-addr.arpa.
+logo.designcrowd.com.
+mscrl.microsoft.com.
+suggest.infospace.com.
+a.root-servers.net.
+ad.reachjunction.com.
+connect.facebook.net.
+hubspot.com.
+pixel.facebook.com.
+61.224.141.174.combined.njabl.org.
+sg.eyi.com.
+photos-e.ak.fbcdn.net.
+s0.2mdn.net.
+mailfilter.crebe.com.
+mea6hto2g.89yg.
+.
+251.121.232.84.in-addr.arpa.
+www.bywifi.com.
+29.media.tumblr.com.
+groups.google.com.mx.
+www.centerfiresystems.com.
+www.titanbet.com.
+db._dns-sd._udp.0.1.168.192.in-addr.arpa.
+smail.hrn9.com.
+hi-in.facebook.com.
+martinsalter.net.
+localhost.
+x.tlbron.facemoods.com.
+ale.pakibili.com.
+ar-ar.facebook.com.
+_ldap._tcp.75e1692b-6de3-40f0-8543-b5ffccd67d07.domains._msdcs.gerdau.net.
+pagead2.googlesyndication.com.
+www.google.com.
+a4.sphotos.ak.fbcdn.net.
+ad.z5x.net.
+pixel.facebook.com.
+seg.sharethis.com.
+afrigator.com.
+feeds.bbci.co.uk.
+www.deproviquique.cl.
+s90.vuclip.com.
+www.bbc.co.uk.
+checkip.dyndns.com.
+3detorrevelo.blogspot.com.
+g.live.com.
+133.162.0.94.in-addr.arpa.
+profile.ak.fbcdn.net.
+www.superbeautyfactory.es.
+fox411.blogs.foxnews.com.
+mail.google.com.
+hhotmail.co.
+video.google.com.
+pagead2.googlesyndication.com.
+autowarehouse.com.
+a.root-servers.net.
+44.184.152.187.in-addr.arpa.
+234.153.195.125.in-addr.arpa.
+one.lv.
+googleads.g.doubleclick.net.
+56.80.114.187.in-addr.arpa.
+5.7.174.190.in-addr.arpa.
+tomorrowinvinland.blogspot.com.
+talk21.com.
+mail.worksights.com.
+181.100.208.190.in-addr.arpa.
+www.siaf-china.com.
+mx.eltima.com.
+55.154.72.190.in-addr.arpa.
+wpad.
+tms30.icrc.trendmicro.com.
+dns.msftncsi.com.
+www.mediafire.com.
+skydrive.live.com.
+i.ytimg.com.
+www.googleadservices.com.
+www.barrichello.com.br.
+fc00.deviantart.net.
+zapatosdemodayfiesta.blogspot.com.
+brutaldildos.sexdelivery.com.
+42.27.232.76.in-addr.arpa.
+sagaev.ru.
+www.allfreeclipart.com.
+survey-cdn.effectivemeasure.net.
+86.19.25.190.in-addr.arpa.
+proyectotarotcolectivo.blogspot.com.
+118.174.129.189.in-addr.arpa.
+o-o.preferred.nuq04s10.v18.lscache2.c.youtube.com.
+l.yimg.com.
+static.ak.fbcdn.net.
+236.172.203.81.in-addr.arpa.
+www.designerzcentral.com.
+cc-s.de.
+10.110.159.189.in-addr.arpa.
+profile.ak.fbcdn.net.
+menghao76.en.made-in-china.com.
+db._dns-sd._udp.0.1.168.192.in-addr.arpa.
+static.ak.fbcdn.net.
+a7.sphotos.ak.fbcdn.net.
+secure.logmein.com.
+5-brujas.peliculon.tv.
+www.albiladdaily.com.
+mail.krhleb.ru.
+node1.bbcimg.co.uk.
+db._dns-sd._udp.0.2.0.10.in-addr.arpa.
+gm.com.
+mooreelectric.com.
+mail.frontierstravel.com.
+www.lagaceta.com.ar.
+searchclient.live.net.
+101.49.124.201.in-addr.arpa.
+chevychaseforecast.com.
+www.googleadservices.com.
+140.47.137.216.in-addr.arpa.
+cbp-us.nccp.netflix.com.
+a.root-servers.net.
+166.128.21.83.in-addr.arpa.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+teredo.ipv6.microsoft.com.
+b._dns-sd._udp.0.2.168.192.in-addr.arpa.
+profile.ak.fbcdn.net.
+www.consultabaekeland.com.
+43.228.171.69.in-addr.arpa.
+recipes.bhg.com.
+heret.net.
+134.86.159.189.in-addr.arpa.
+mail2.torchlake.com.
+117.83.210.201.in-addr.arpa.
+2.pool.ntp.org.
+external.ak.fbcdn.net.
+zynga2-a.akamaihd.net.
+brownandhudson.com.
+a.root-servers.net.
+btjunkie.org.
+www.habemuspapam.it.
+119.181.23.187.in-addr.arpa.
+29.241.175.187.in-addr.arpa.
+www.msftncsi.com.
+a6.sphotos.ak.fbcdn.net.
+ksn1-11-part1.kaspersky-labs.com.
+db._dns-sd._udp.0.2.168.192.in-addr.arpa.
+www.macromedia.com.
+api-read.facebook.com.
+dns.msftncsi.com.
+www.lingsoft.fi.
+11-courier.push.apple.com.
+ohio.k12.ky.us.
+www.enjoydressup.com.
+37.128.27.189.in-addr.arpa.
+svrintl-g3-crl.verisign.com.
+ggschmitt.com.
+photos-g.ak.fbcdn.net.
+128.207.172.190.in-addr.arpa.
+www9.effectivemeasure.net.
+www.tutorialesyrecursos.es.
+www.facebook.com.
+googleads.g.doubleclick.net.
+151.251.211.201.in-addr.arpa.
+www.flickr.com.
+jannikeviveka.files.wordpress.com.
+www.jabfm.org.
+d2056968.instant.xoom.it.
+superiorplastic.com.
+clients5.google.com.
+ad.foxnetworks.com.
+platform.ak.fbcdn.net.
+a8.sphotos.ak.fbcdn.net.
+68ohh6com6c1h-c.c.yom.mail.yahoo.com.
+d2058291.instant.xoom.it.
+fbcdn-photos-a.akamaihd.net.
+pixel.facebook.com.
+186.152.47.147.in-addr.arpa.
+20.246.120.89.in-addr.arpa.
+159.178.177.190.in-addr.arpa.
+68.28.202.81.in-addr.arpa.
+mail1.synagro.com.
+www.download.windowsupdate.com.
+img3.91huo.cn.
+a.root-servers.net.
+api.allmyapps.com.
+www.london-tubemap.com.
+www.rscycle.com.
+98.42.172.90.in-addr.arpa.
+about.tagged.com.
+epiccm.blogspot.com.
+ns2.relkama.ru.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+view.atdmt.com.
+can2012.rfi.fr.
+bpmcpas.com.pri-mx.na0106.smtproutes.com.
+photocontestinformation.com.
+252.233.129.189.in-addr.arpa.
+dagda37.blogia.com.
+jamesmanagement.com.
+a6.sphotos.ak.fbcdn.net.
+amirahall.com.
+oas.monster.com.
+carrolltonpd.net.
+tracker.irc.su.
+webcache.googleusercontent.com.
+pt-br.facebook.com.
+cfile77.uf.daum.net.
+simplecdn.maxcdn.com.
+a3.sphotos.ak.fbcdn.net.
+mail.copernicused.com.
+vide0s.org.
+ds.serving-sys.com.
+mail.pcrc.spb.ru.
+sp.cwfservice.net.
+img.apnanalytics.com.
+52.109.190.189.in-addr.arpa.
+ns2.yaknet.ca.
+photos-b.ak.fbcdn.net.
+103.136.95.200.in-addr.arpa.
+crl.microsoft.com.
+mundoconquis.files.wordpress.com.
+img1-fotki.yandex.net.
+dr._dns-sd._udp.lan.
+getlive.com.
+0-jw-w.channel.facebook.com.
+treenosoftware.com.
+img71.exs.cx.
+hlylsbty.net.
+36-courier.push.apple.com.
+jrol.com.
+tv.about.com.
+badge.facebook.com.
+www.mexicanisimo.com.mx.
+134.207.240.148.in-addr.arpa.
+ajax.googleapis.com.
+a.root-servers.net.
+g.ceipmsn.com.
+156.71.102.201.in-addr.arpa.
+r1rk9np7bpcsfoeekl0khkd2juj27q3o-a-fc-opensocial.googleusercontent.com.
+coldraria.blogspot.com.
+www.odfl.com.
+lyrics.music-strike.net.
+www.xg7979.com.
+_431_19_2.
+a.root-servers.net.
+a83.phobos.apple.com.
+edge.quantserve.com.
+netflix757.pop3.la.nflximg.com.edgesuite.net.
+4cskenyatuitakayo.org.
+s-static.ak.fbcdn.net.
+135.89.87.190.in-addr.arpa.
+_511_72_7.
+www.boca-lobo.blogspot.com.
+sc21.rules.mailshell.net.
+www.pilgrimcars.com.
+189.56.180.64.in-addr.arpa.
+open.qzone.qq.com.
+a-0.19-21094071.9030083.1518.19d3.3ea1.410.0.e5c2hr5rirvc83viczadisp8rb.avqs.mcafee.com.
+nvjqjsnx9.f70y3n1q.
+www.myslavegirls.com.
+forums.socialpointgames.com.
+0.3099009.com.
+time.chttl.com.tw.
+www.zadetek.net.
+dns.msftncsi.com.
+tecnologia.es.msn.com.
+a.root-servers.net.
+prosperityloan.com.
+code.jquery.com.
+creative.ak.fbcdn.net.
+naissance.bebe.notrefamille.com.
+rcp.na.blackberry.com.
+hootsuite.com.
+beton-pesok.ru.
+145.101.179.190.in-addr.arpa.
+profile.ak.fbcdn.net.
+128.177.49.190.in-addr.arpa.
+vypxvs.com.
+a.root-servers.net.
+9.240.230.83.in-addr.arpa.
+4.143.86.200.in-addr.arpa.
+pollsdynamic.esmas.com.
+201.143.77.82.in-addr.arpa.
+www.teachingnews.co.uk.
+cdn2.image.keezmovies.phncdn.com.
+203.70.142.190.in-addr.arpa.
+maddogweb.com.s7a2.psmtp.com.
+www.rgawi.com.
+2.bp.blogspot.com.
+gra-elmundomagicodelasagujas.blogspot.com.
+kfedisbroke.com.lan.
+centaurmx1.dxsolutions.biz.
+photos-b.ak.fbcdn.net.
+www.allergynet.com.au.
+dnl-19.geo.kaspersky.com.
+98.82.27.201.in-addr.arpa.
+a1.sphotos.ak.fbcdn.net.
+a4.sphotos.ak.fbcdn.net.
+springerlink.metapress.com.
+img.mediaplex.com.
+www.google-analytics.com.
+sro.whatsapp.net.
+216.153.19.186.in-addr.arpa.
+plusone.google.com.
+a.root-servers.net.
+www.ylab.es.
+e906.g.akamaiedge.net.
+video.foxsmallbusinesscenter.com.
+static.ak.fbcdn.net.
+82.222.2.204.in-addr.arpa.
+www.toquetoques.com.
+beta.stun.voice.yahoo.com.
+0-250.channel.facebook.com.
+trendingsearches.net.
+support.maktoob.com.
+130.127.117.91.in-addr.arpa.
+apps.facebook.com.
+i1.ytimg.com.
+dkndbrm1z.x80c1x2o.
+23.130.130.201.in-addr.arpa.
+espanol.answers.yahoo.com.
+www.addthis.com.
+a.root-servers.net.
+video.google.com.
+cs10658.vk.com.
+discavery.ru.
+www.gabrielacastillo.com.
+static.imonografias.com.
+mmetal.ru.
+photos-d.ak.fbcdn.net.
+184.209.47.201.in-addr.arpa.
+www.freeridegames.com.
+www.foodbuzz.com.
+mail.industrialgines.com.
+cdn1.clkads.com.
+www.rincondelvago.com.
+55.89.173.190.in-addr.arpa.
+www.adobe.com.
+85.85.231.190.in-addr.arpa.
+.
+a.root-servers.net.
+csi.gstatic.com.
+photos-d.ak.fbcdn.net.
+www.turismoinkaiko.net.
+150.174.86.201.in-addr.arpa.
+zakazmebel.ru.
+147.112.249.81.in-addr.arpa.
+mail.burtcrane.com.
+dns.msftncsi.com.
+baymsg1020409.gateway.messenger.live.com.
+www.images.com.
+87.124.113.188.in-addr.arpa.
+_991_90_9.
+88ig51n5t.d34k2e1b.
+mrmbw.com.
+a.root-servers.net.
+d2092230.xoom.it.
+a8.sphotos.ak.fbcdn.net.
+ecx.images-amazon.com.
+fusion.google.com.
+humannova.files.wordpress.com.
+pt-br.facebook.com.
+www.wordpress.com.
+dc305.4shared.com.
+wirelessmedia.ign.com.
+a.root-servers.net.
+begonebrotherhood.forumotion.com.
+dmqg0yef478ix.cloudfront.net.
+a.c-0.19-210fe000.10590.1518.19d4.3ea1.410.0.rikjfg7q7l6iidkwd5rfk4vkbi.avqs.mcafee.com.
+csi.gstatic.com.
+teredo.ipv6.microsoft.com.
+api.twitter.com.
+bs.serving-sys.com.
+www.facebook.com.
+a8.sphotos.ak.fbcdn.net.
+range-systems.com.s8b1.psmtp.com.
+garageband.maccreate.com.
+blog.matoo.net.
+accounts.google.com.
+seaquest.com.
+go.universal-music.de.
+www.rangerover.com.
+ds.serving-sys.com.
+mx7.hushmail.com.
+trauerhahn.de.
+a8.sphotos.ak.fbcdn.net.
+www.viva4madrid.com.
+92.86.193.187.in-addr.arpa.
+scanpell.no.
+mail.westcall.net.
+static.ak.fbcdn.net.
+safesprinklers.com.
+img3.xcarimg.com.
+qq.net.
+photos-c.ak.fbcdn.net.
+twentynineinches.com.
+a4.sphotos.ak.fbcdn.net.
+a2.sphotos.ak.fbcdn.net.
+135.72.158.201.in-addr.arpa.
+clients2.google.com.
+46.106.146.194.in-addr.arpa.
+photos-h.ak.fbcdn.net.
+rebmaillink.rebtel.com.
+_417_65_8.
+38.97.132.189.in-addr.arpa.
+blog.comsatmedia.com.
+a.root-servers.net.
+c.plma.se.
+101.232.108.84.in-addr.arpa.
+ad.z5x.net.
+a1251.phobos.apple.com.edgesuite.net.
+pixel.facebook.com.
+www.lahueca.ec.
+katherussa.blogspot.com.
+blog.9marks.org.
+s-static.ak.facebook.com.
+44.156.127.201.in-addr.arpa.
+60.76.122.200.in-addr.arpa.
+photos-h.ak.fbcdn.net.
+110.33.36.186.in-addr.arpa.
+scholar.google.com.
+www.redfaction.com.
+recoveryisbeautiful.tumblr.com.
+dnl-02.geo.kaspersky.com.
+delacarreracavanzo.com.
+metrics.raptr.com.
+photos-h.ak.fbcdn.net.
+yahoo.com.
+aprendeareirconelcolegiotartessos.blogspot.com.
+ge.com.
+www.facebook.com.
+3.145.68.201.in-addr.arpa.
+a5.sphotos.ak.fbcdn.net.
+lb._dns-sd._udp.0.0.168.192.in-addr.arpa.
+twitter.co.
+6-courier.push.apple.com.
+www.youtube.com.
+translate.google.com.
+safebrowsing.clients.google.com.
+208.45.233.201.in-addr.arpa.
+107.146.220.66.in-addr.arpa.
+adblock-plus.uptodown.com.
+p08-bookmarks.icloud.com.
+28.41.148.190.in-addr.arpa.
+35.189.33.151.in-addr.arpa.
+ybinst3.ec.yimg.com.
+189.195.222.189.in-addr.arpa.
+checkip.dyndns.org.
+www.blogpsicopositiva.com.
+www.elperiodicodemexico.com.
+173.150.252.190.in-addr.arpa.
+49.1.168.192.in-addr.arpa.
+mailgateway02.acs-corp.com.
+139.77.121.186.in-addr.arpa.
+open.hr.
+cyber.net.
+sri.ua.es.
+profile.ak.fbcdn.net.
+74.144.242.78.in-addr.arpa.
+pheedo-rdr.msnbc.msn.com.
+140.138.20.190.in-addr.arpa.
+135.49.145.181.in-addr.arpa.
+photos-h.ak.fbcdn.net.
+181.132.22.187.in-addr.arpa.
+sites.google.com.
+nosotroslosgorditos.blogspot.com.
+238.56.174.189.in-addr.arpa.
+27.251.210.201.in-addr.arpa.
+www.locaporlamodachile.com.
+www.thinkwithgoogle.co.uk.
+mx0.gmx.net.
+smtp1.rehau.com.
+46.22.212.201.in-addr.arpa.
+pixel.facebook.com.
+sac.gti.mcafee.com.
+www.nosolodepanviveelhombre.com.
+fbcdn-profile-a.akamaihd.net.
+mail.moava.net.
+41.231.233.190.in-addr.arpa.
+a3.sphotos.ak.fbcdn.net.
+a.root-servers.net.
+ravens.ru.
+photos-h.ak.fbcdn.net.
+external.ak.fbcdn.net.
+ie.todoexplorer.com.
+a8.sphotos.ak.fbcdn.net.
+www.funcionjudicial-pichincha.gov.ec.
+b._dns-sd._udp.0.0.168.192.in-addr.arpa.
+adoregames.com.
+homezeus.tanagraltd.com.
+39.61.35.177.in-addr.arpa.
+www.stcwatches.com.
+226.63.30.190.in-addr.arpa.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+v20.nonxt1.c.youtube.com.
+rhodeisland.broadwayworld.com.
+adfarm.mediaplex.com.
+www.facebook.com.
+mail1.islc.net.
+phaseiv.com.
+mail.bya.ru.
+fbcdn-sphotos-a.akamaihd.net.
+www.emagister.com.mx.
+engine24-1452-2.icritical.com.
+57.121.168.192.in-addr.arpa.
+wm44wmoy2.w21t8k1j.
+www.youtube.com.
+167.130.243.189.in-addr.arpa.
+cluster3.eu.messagelabs.com.
+um18.eset.com.
+a1.sphotos.ak.fbcdn.net.
+210.28.33.27.in-addr.arpa.
+49.60.204.91.in-addr.arpa.
+active.xo.com.
+searchclient.live.net.
+ow.ly.
+ssl.gstatic.com.
+b.scorecardresearch.com.
+connect.facebook.net.
+rest-img.msg.yahoo.com.
+www.mysoccerpatch.com.
+a.root-servers.net.
+153.139.125.186.in-addr.arpa.
+tcp.net.uk.
+a.root-servers.net.
+115.3.8.124.in-addr.arpa.
+photos-d.ak.fbcdn.net.
+connect.facebook.net.
+a4.sphotos.ak.fbcdn.net.
+mail.popsforchampagne.com.
+api.twitter.com.
+www.selectividad.tv.
+toolbarqueries.google.es.
+photos-e.ak.fbcdn.net.
+api.conduit.com.
+www.facebook.com.
+sivis.com.br.
+www.facebook.com.
+otmail.de.
+www.statusq.org.
+olympics.wikia.com.
+www.stayclassy.org.
+ctsi-global.com.
+ads.adxpansion.com.
+col.stj.s-msn.com.
+service.gc.apple.com.akadns.net.
+61.89.18.95.in-addr.arpa.
+a2.sphotos.ak.fbcdn.net.
+www.sonoframbow.com.
+pt-br.facebook.com.
+www.myspace.com.
+msc.wlxrs.com.
+www.drumscore.com.
+a.root-servers.net.
+www.facebook.com.
+57.187.137.190.in-addr.arpa.
+dns.msftncsi.com.
+multimedia.gustavo-castro.com.
+mail2.m7aerospace.com.
+c5uhsqqmo.40sv.
+au.download.windowsupdate.com.
+29-courier.push.apple.com.
+769.coll.ning.com.
+50.234.94.190.in-addr.arpa.
+200.222.67.201.in-addr.arpa.
+10-courier.push.apple.com.
+video.forcedfemdomtgp.com.
+s-static.ak.fbcdn.net.
+a.root-servers.net.
+www.definicion.com.mx.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+206.40.10.201.in-addr.arpa.
+oyhubl.com.
+gfx4.hotmail.com.
+static.ak.facebook.com.
+www.flexgallery.com.
+71.12.22.190.in-addr.arpa.
+profile.ak.fbcdn.net.
+87.122.201.190.in-addr.arpa.
+apis.google.com.
+www.annecoyleinteriors.com.
+photos-f.ak.fbcdn.net.
+a5.sphotos.ak.fbcdn.net.
+www.thaidvd.biz.
+yahoo.com.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+fbcdn-photos-a.akamaihd.net.
+www.elciudadano.cl.
+wwwimages.adobe.com.
+www.diabetesjournals.org.
+neoenergiaedp.com.
+cn.pool.ntp.org.
+_311_12_5.
+members.dyndns.org.
+teredo.ipv6.microsoft.com.
+byfiles.storage.msn.com.
+14eg6s-de-he3d6ss.juegosipo.com.
+mail.columbusfirstbank.com.
+151.57.115.187.in-addr.arpa.
+hjuhsd.k12.ca.us.
+235.30.198.187.in-addr.arpa.
+photos-b.ak.fbcdn.net.
+checkout.google.com.
+239.179.158.189.in-addr.arpa.
+readeronline.wip4.adobe.com.
+img268.
+jcsu.edu.s10a2.psmtp.com.
+krithiskitchen.blogspot.com.
+muchascajasdecarla.blogspot.com.
+hofra.sr.
+crl.microsoft.com.
+atlanticcityelectric.com.
+114.129.44.99.in-addr.arpa.
+ad-apac.doubleclick.net.
+ville-nice.fr.
+www.pastelerialety.com.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+www.eu-ssa.org.
+231.210.58.186.in-addr.arpa.
+26.20.223.98.in-addr.arpa.
+photos-d.ak.fbcdn.net.
+205.126.37.80.in-addr.arpa.
+zolotoy-venetz.spb.ru.
+132.68.231.213.in-addr.arpa.
+37.171.79.190.in-addr.arpa.
+s2.youtube.com.
+148.133.101.199.in-addr.arpa.
+cn1.redswoosh.akadns.net.
+a.root-servers.net.
+62.165.231.189.in-addr.arpa.
+153.56.47.190.in-addr.arpa.
+api-read.facebook.com.
+impulsi.ru.
+a.root-servers.net.
+14.133.211.201.in-addr.arpa.
+s3.subirimagenes.com.
+144.34.151.187.in-addr.arpa.
+cdn.extensions.buzznet.com.
+www.jiggystudio.com.
+profile.ak.fbcdn.net.
+mail.yimg.com.
+an.tacoda.net.
+software.filestube.com.
+238.158.164.189.in-addr.arpa.
+a5.sphotos.ak.fbcdn.net.
+www.google.com.
+a8.sphotos.ak.fbcdn.net.
+www.pixelfanatic.com.
+us.data.toolbar.yahoo.com.
+artone.ru.
+www.serial-on.clan.su.
+mail.glatt.com.
+db._dns-sd._udp.0.1.168.192.in-addr.arpa.
+224.198.127.59.in-addr.arpa.
+www.blog.proxyroller.com.
+s3.hddownloader.com.
+www.thelusted.com.
+www.lugaresquenoquierocompartirconnadie.com.
+cdn1.clkads.com.
+197.238.236.190.in-addr.arpa.
+cs505204.vk.com.
+cfs-p4.l3.fbcdn.net.
+www.findserialnumber.me.
+smtp2.prointec.es.
+www.foreverunique.co.uk.
+www.lace-up.de.
+www.youtube.com.
+www.deremate-inc.com.
+pixel.rubiconproject.com.
+d15gt9gwxw5wu0.cloudfront.net.
+xglobal.froo.com.
+yui.yahooapis.com.
+www.facebook.com.
+api-public.addthis.com.
+digg.com.
+www.facebook.com.
+crl.verisign.net.
+rad.msn.com.nsatc.net.
+s.youtube.com.
+redfaceplus.com.
+www.macromedia.com.
+event.adxpose.com.
+126.96.170.90.in-addr.arpa.
+77.167.170.184.in-addr.arpa.
+fivetowntoyota.com.
+mail.youngstartup.com.
+mail.spectrasonics.com.
+googleads.g.doubleclick.net.
+112.84.214.201.in-addr.arpa.
+s0.2mdn.net.
+www.idcow.com.
+view.atdmt.com.
+plus.google.com.
+external.ak.fbcdn.net.
+www.playspidermangames.org.
+budget.moneycontrol.com.
+secure.wlxrs.com.
+4xusys5mt.87bq.
+annaandtheringlondon.blogspot.com.
+rainbow-it.mythings.com.
+t.co.
+smtp.live.com.
+www.facebook.com.
+25.0/27.3.69.83.in-addr.arpa.
+sportsgrid.com.
+www.ganfx.com.
+plus.google.com.
+13.144.206.200.in-addr.arpa.
+relay.voice.edge.messenger.live.com.
+clients2.google.com.
+dc.logmein-gateway.com.
+blog.wunderlist.com.
+58.144.153.201.in-addr.arpa.
+129.167.116.78.in-addr.arpa.
+www.sharethis.com.
+www.yahoo.com.
+a8.sphotos.ak.fbcdn.net.
+mail.walkercontracting.com.
+wrg1008.webradiogratis.com.
+www.keezmovies.com.
+utrade.ru.
+www.importvelez.com.ar.
+75.204.34.189.in-addr.arpa.
+a.root-servers.net.
+liability-insurance-types.com.
+www.tarocchiamore.info.
+thumbnails9.imagebam.com.
+www.mold-help.org.
+86.4.122.187.in-addr.arpa.
+165.81.49.70.in-addr.arpa.
+humor.petardas.com.
+43.74.230.71.in-addr.arpa.
+punkmagazine.com.
+153.95.55.189.in-addr.arpa.
+utils.babylon.com.
+wclacc.org.
+gdata.youtube.com.
+static.uk.groupon-content.net.
+gsp1.apple.com.
+api.twitter.com.
+www.diamantalia.com.
+pu4fox653.c75o8x5p.
+www.beautifulmag.com.
+billing.sharo4ka.ru.
+ivyleagueadmission.com.
+cesarasilva.com.
+qualitymetalwv.com.
+villanoticias.blogspot.com.
+bowdoin.academia.edu.
+susanne-weber.eu.
+provgrp.us.
+www.gruposiete.com.mx.
+pensketruckleasing.com.
+c-0.19-230f0081.c050081.1518.19c5.3ea1.210.0.l3ep1t8fv2s2q4njwbkes7s4nb.avqs.mcafee.com.
+ssfsf.com.
+download.windowsupdate.com.
+www.creditme.com.
+dns.msftncsi.com.
+59a92430e6.com.
+links.mkt3094.com.
+wildernesslore.com.
+safebrowsing-cache.google.com.
+radugaprint.ru.
+jasperautomotive.com.
+dominguez-cia.com.
+deckercollege.com.
+hosting.lockhosts.com.
+profile.ak.fbcdn.net.
+api.webrep.avast.com.
+217.173.36.186.in-addr.arpa.
+www.amazon.com.
+194.96.141.83.in-addr.arpa.
+176.43.65.69.in-addr.arpa.
+evsecure-ocsp.verisign.com.
+ksn2-12.kaspersky-labs.com.
+check4.facebook.com.
+platform.ak.fbcdn.net.
+csi.gstatic.com.
+www.lux.
+google.com.
+a.root-servers.net.
+126.121.107.190.in-addr.arpa.
+mail.olympuspower.com.
+i2.ytimg.com.
+go.srvnow.com.
+badurls119.gsecurity.de.
+support.ovi.com.
+continent-mebel.ru.
+a.root-servers.net.
+a.root-servers.net.
+www.myhomeremedies.com.
+74.233.158.213.in-addr.arpa.
+sp.cwfservice.net.
+jobsale.ru.
+www.sherweb.com.
+keywest.com.
+n3yve26iy.p87i5v0q.
+alfa.ns.active24.cz.
+www.partymonster.cl.
+inbound.parry.biz.netsolmail.net.
+118.101.56.190.in-addr.arpa.
+www.facebook.com.
+www.autobacklinkservice.com.
+sjstatic.sj.91.com.
+100.143.63.46.in-addr.arpa.
+gmailc.om.
+teredo.ipv6.microsoft.com.
+28.223.144.189.in-addr.arpa.
+mail.sacvoyage.com.
+external.ak.fbcdn.net.
+20.234.246.88.in-addr.arpa.
+plus.google.com.
+www.poderypaz.com.
+www.erlupacchiotto.com.
+223.119.137.201.in-addr.arpa.
+www.nakedgirlfriend.net.
+www.sabiasque.info.
+87.146.220.66.in-addr.arpa.
+www.google-analytics.com.
+mhl2w4zpt.l77z8p6y.
+safebrowsing.clients.google.com.
+mx.youtube.com.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+profile.ak.fbcdn.net.
+www.google.com.
+hotmail.com.
+profile.ak.fbcdn.net.
+s-static.ak.facebook.com.
+www.l.google.com.
+checkip.dyndns.org.
+squall21000.unblog.fr.
+semprautilities.com.
+www.download-free-templates.com.
+www.facebook.com.
+rekad.be.
+9.254.103.189.in-addr.arpa.
+bloggergadgets.googlecode.com.
+autos.demotores.com.ar.
+api.facebook.com.
+www.facebook.com.
+i3.ytimg.com.
+www.facebook.com.
+78.241.14.186.in-addr.arpa.
+a2.sphotos.ak.fbcdn.net.
+groups.google.com.mx.
+a.rtiindia.org.
+19.174.192.190.in-addr.arpa.
+profile.ak.fbcdn.net.
+jangsara.blogspot.com.
+tracsablog.typepad.com.
+cicb-chemicon-com.antispam2.softcell.in.
+internetservice.shopsgroup.com.
+prwg.wikispaces.com.
+boletotal.mx.
+platform.twitter.com.
+line4u.ru.
+110.196.222.186.in-addr.arpa.
+www.amarillasnevada.com.
+aoltv.com.
+nationwiderestorationllc.com.
+jesmar.com.
+developers.facebook.com.
+dns.msftncsi.com.
+a1.sphotos.ak.fbcdn.net.
+mynnb.com.s8a1.psmtp.com.
+a5.sphotos.ak.fbcdn.net.
+us.topshop.com.
+a8.sphotos.ak.fbcdn.net.
+www.fanaticinema.com.
+www.newstar-cherry.net.
+img.realvoyeurpost.com.
+mb.marathonbet.com.
+www.facebook.com.
+36ohk6dgmcd1n-c.c.yom.mail.yahoo.net.
+pyx.net.
+gizma.ru.
+saude.ig.com.br.
+news.google.com.mx.
+www.google-analytics.com.
+1.0.0.223.lbl7.mailshell.net.
+26.196.138.189.in-addr.arpa.
+223.216.118.190.in-addr.arpa.
+a3.sphotos.ak.fbcdn.net.
+nama3.thamrin.net.id.
+www.senatorsextra.com.
+amor.prodigy.match.com.
+lainquisicionprogramadetv.blogspot.com.
+mediacenter2.clicrbs.com.br.
+www.miniclip.com.
+v4.lscache5.googlevideo.com.
+7.10.22.186.in-addr.arpa.
+photos-d.ak.fbcdn.net.
+juki.su.
+62.9.133.186.in-addr.arpa.
+dak.donetsk.ua.
+api.facebook.com.
+a7.sphotos.ak.fbcdn.net.
+l3.image.dirty101.com.
+docs.google.com.
+a.root-servers.net.
+s-static.ak.fbcdn.net.
+abcdiario2010.blogspot.com.
+9.112.44.60.in-addr.arpa.
+246.191.136.14.in-addr.arpa.
+dns.msftncsi.com.
+spe.com.
+s3.amazonaws.com.
+mx2.inflin.ru.
+www.ardillamedia.com.
+www.joinecsc.com.
+141.163.239.201.in-addr.arpa.
+a2.sphotos.ak.fbcdn.net.
+www.thethinkingstick.com.
+34.229.171.69.in-addr.arpa.
+105.10.43.200.in-addr.arpa.
+google.com.
+www.monografias.com.
+94.15.168.192.in-addr.arpa.
+pixel.facebook.com.
+55.17.59.186.in-addr.arpa.
+gearjunkie.com.
+www.datadev.com.
+static.canalstat.com.
+tracker.bittorrent.am.
+www.cloudantivirus.com.
+photos-f.ak.fbcdn.net.
+iztapalapa.infoisinfo.com.mx.
+platform.ak.fbcdn.net.
+ertolete.wordpress.com.
+www.bidstrup.ru.
+130.53.206.187.in-addr.arpa.
+i3.ytimg.com.
+del.icio.us.
+holiday-for-children.ru.
+s7.addthis.com.
+es-es.facebook.com.
+nations.tm-exchange.com.
+moritzchevrolet.com.
+203.156.200.98.in-addr.arpa.
+profile.ak.fbcdn.net.
+g.live.com.
+2dwti6j8g.n70r9f3f.
+lb._dns-sd._udp.0.9.168.192.in-addr.arpa.
+log.client.akadns.net.
+de-de.facebook.com.
+clients4.google.com.
+samcoline.com.
+www.google.com.
+sea-wallpapers.blogspot.com.
+mx.youtube.com.
+ad.doubleclick.net.
+www.msn.com.
+ewriters.org.
+mailserver.ctf-uk.com.
+hotmail.com.
+connect2.askadmissions.net.
+www-fc-opensocial.googleusercontent.com.
+paginadeerro.ig.com.br.
+image-c.c.yom.mail.yahoo.net.
+m.facebook.com.
+sintechms.com.
+googlemaps.
+calif.com.
+www.gayxxxblog.com.
+a.root-servers.net.
+enthought.com.s9a1.psmtp.com.
+loganlibrary.org.
+194.34.174.90.in-addr.arpa.
+a.root-servers.net.
+www.google.com.mx.
+insightbb.com.
+abp2go.com.
+external.ak.fbcdn.net.
+235.242.13.187.in-addr.arpa.
+sp.cwfservice.net.
+67652.envacaciones.info.
+smtp.equipcokuwait.com.
+50.7.93.186.in-addr.arpa.
+www.imprentavalencia.com.
+ns7.ptspb.ru.
+www.egagenerics.com.
+api.facebook.com.
+support.google.com.
+img.uptodown.net.
+www.ulani.de.
+20.228.171.69.in-addr.arpa.
+msnia.login.live.com.
+webcache.googleusercontent.com.
+s.youtube.com.
+beko-zuid.nl.
+listas.trisquel.info.
+sp.cwfservice.net.
+pagead2.googlesyndication.com.
+www.situsotomotif.com.
+185.214.242.98.in-addr.arpa.
+tap2-cdn.rubiconproject.com.
+www.google.com.
+kayucolectivo.obolog.com.
+a.root-servers.net.
+photos-c.ak.fbcdn.net.
+o.analytics.yahoo.com.
+4.213.188.190.in-addr.arpa.
+crc4pr.com.
+e906.g.akamaiedge.net.
+www.guanakos.net.
+www.ratteb.com.
+140.7.231.189.in-addr.arpa.
+a.root-servers.net.
+ad.adnetwork.net.
+253.8.124.186.in-addr.arpa.
+www.earthincommon.com.
+135.242.225.189.in-addr.arpa.
+a.root-servers.net.
+blugro2relay.groove.microsoft.com.
+market.android.com.
+.
+www.google.com.
+orcart.facebook.com.
+inbound.staffordsmith.com.netsolmail.net.
+skipod.ru.
+73.104.19.190.in-addr.arpa.
+hotpremiumcookies.blogspot.com.
+tubularsuspensionsystems.com.
+a4.sphotos.ak.fbcdn.net.
+234.204.55.216.in-addr.arpa.
+www.apple.com.
+4.183.115.79.in-addr.arpa.
+i3.ytimg.com.
+www.bic-code.org.
+pagead2.googlesyndication.com.
+db._dns-sd._udp.0.1.168.192.in-addr.arpa.
+retromed.doc-martin.ru.
+_360_40_2.
+a5.sphotos.ak.fbcdn.net.
+iffexc.fibraforte.com.
+www.kidsafensw.org.
+userimages01-akm.imvu.com.
+www.teensdefloration.net.
+a2.sphotos.ak.fbcdn.net.
+zapatec.com.
+105.77.69.189.in-addr.arpa.
+emob247.photobucket.com.
+mail.cpmail.ru.
+s-static.ak.fbcdn.net.
+251.221.124.201.in-addr.arpa.
+tenet.ru.
+bank06.mi.ads.mp.mydas.mobi.
+barranquillaes.chatango.com.
+tap-cdn.rubiconproject.com.
+teredo.ipv6.microsoft.com.
+a7.sphotos.ak.fbcdn.net.
+www.michaeljordanoutlet.com.
+105.52.205.190.in-addr.arpa.
+11.231.61.78.in-addr.arpa.
+jers3.info.
+www.google.com.
+www.googleadservices.com.
+jorgevila.blogspot.com.
+losmasgrandesdelahistoria.blogspot.com.
+profile.ak.fbcdn.net.
+wwc.instacam.com.
+nt3.ggpht.com.
+189.229.39.187.in-addr.arpa.
+a.root-servers.net.
+armmf.adobe.com.
+zgn.static.zynga.com.
+youtube-espanol.blogspot.com.
+contiadvertising.name.
+url.edu.gt.
+jobs.raytheon.com.
+i1.ytimg.com.
+a2.da1.akamai.net.
+0-jf-w.channel.facebook.com.
+ksn2-12.kaspersky-labs.com.
+login.yahoo.com.
+fcat.fldoe.org.
+hangtime.blogs.nba.com.
+3.242.168.189.in-addr.arpa.
+www.skyrama.de.
+61.127.134.122.in-addr.arpa.
+maxcontrols.com.
+developers.facebook.com.
+155.48.70.173.in-addr.arpa.
+ksn7-12.kaspersky-labs.com.
+www.google.com.
+sites.google.com.
+vmirror3.garant.ru.
+ptpw.com.tw.
+dsn13.d.skype.net.
+www.jesusdemanuel.es.
+cronicasdeinternet.com.
+a5.sphotos.ak.fbcdn.net.
+luismthen.posterous.com.
+86.12.227.190.in-addr.arpa.
+akm.atlas-rt.ru.
+alpha.newsx.com.
+s.youtube.com.
+229.94.113.88.in-addr.arpa.
+thegoodlife.ru.
+pocketpc-fujitsu.ru.
+www.addthis.com.
+cdn.conceptdezain.com.
+isatap.gateway.2wire.net.
+a.root-servers.net.
+jg.com.
+www.adoptivefamilies.com.
+3limona.ru.
+www.google.com.
+a.root-servers.net.
+sp.cwfservice.net.
+cybernet.net.
+foundationsource.com.2.0001.arsmtp.com.
+ja-jp.facebook.com.
+carina-a-met-art.bravoerotica.com.
+.
+95.107.160.69.in-addr.arpa.
+www.google.com.
+138.125.241.201.in-addr.arpa.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+cur.cursors-4u.net.
+entretenimiento.prodigy.msn.com.
+b-0.19-a3005008.11081.1518.19d0.3ea1.410.0.ddcllgmu7e9kp2t99kj9blbvp6.avqs.mcafee.com.
+shared.live.com.
+www.otakugaming.com.
+rtpnet.org.
+mail.mccmetro.com.
+accounts.google.com.
+thumbs4.ebaystatic.com.
+ssl.gstatic.com.
+radiolafavorita.com.
+trc-hq.com.
+checkip.dyndns.org.
+224.194.89.201.in-addr.arpa.
+a979.v.phobos.apple.com.
+img25.imageshack.us.
+s2.youtube.com.
+147.218.225.212.in-addr.arpa.
+fr.shegame.com.
+www.facebook.com.
+43.220.27.108.in-addr.arpa.
+a.root-servers.net.
+4.166.138.190.in-addr.arpa.
+www.sweetim.com.
+isotron.com.s200a2.psmtp.com.
+rcp.na.blackberry.com.
+_822_10_2.
+47.23.95.190.in-addr.arpa.
+hdmanagement.com.
+a.root-servers.net.
+brico-pack-vista-inspirat.malavida.com.
+rsca.be.
+31.170.218.80.in-addr.arpa.
+messenger.hotmail.com.
+0-271.channel.facebook.com.
+web.me.com.edgekey.net.
+www.facebook.com.
+smtp.bitterrootgroup.com.
+97.53.209.190.in-addr.arpa.
+skynet-services-other.metriweb.be.
+126.127.47.190.in-addr.arpa.
+sigs.symantec.com.
+a.root-servers.net.
+pixel.facebook.com.
+mx03.t-online.de.
+www.ngsimages.com.
+disneylatino.com.
+159.25.38.187.in-addr.arpa.
+maktoob.yahoo.com.
+alerts.conduit-services.com.
+138.225.193.190.in-addr.arpa.
+blueyonder.co.uk.
+smtp.ww.co.nz.
+2.30.207.190.in-addr.arpa.
+202.28.165.189.in-addr.arpa.
+photos-a.ak.fbcdn.net.
+a4.sphotos.ak.fbcdn.net.
+a.root-servers.net.
+www.allisonangel.info.
+86.143.153.188.in-addr.arpa.
+mail.choifm.com.
+www.netnanny.com.
+tarot-egipcio.com.
+124.226.74.190.in-addr.arpa.
+a1108.da1.akamai.net.
+186.178.229.189.in-addr.arpa.
+dogs2.f5.vip.milp.ngmoco.com.
+s-static.ak.fbcdn.net.
+d.mzc.in.
+profile.ak.fbcdn.net.
+142.217.245.190.in-addr.arpa.
+www.philippi.cl.
+www.fincen.gov.
+www.imageport.info.
+www.cosmetic-plastic-surgery.info.
+a.root-servers.net.
+mixph.com.
+214.151.178.190.in-addr.arpa.
+i4.ytimg.com.
+181.212.186.189.in-addr.arpa.
+28.64.125.186.in-addr.arpa.
+static.ak.fbcdn.net.
+mail.google.com.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+www.premioelbarcodevapor-blaa.com.
+a.root-servers.net.
+g.ceipmsn.com.
+www.xatech.com.
+sfigroup.co.uk.
+10.21.255.201.in-addr.arpa.
+preparacion2012.argentinaforo.net.
+a34.g.akamai.net.
+www.nrcu.gov.ua.
+apps.facebook.com.
+i1213.photobucket.com.
+iraqpics.net.
+blogs.laverdad.es.
+ad-g.doubleclick.net.
+css.wlxrs.com.
+a3.sphotos.ak.fbcdn.net.
+googleads.g.doubleclick.net.
+peoplepc.compeoplepc.com.
+pixel.quantserve.com.
+francemebel.ru.
+70.202.67.187.in-addr.arpa.
+coronapalto.ru.
+photos-g.ak.fbcdn.net.
+mid-valleysupply.com.
+www.usolympicteam.com.
+meneame.net.
+177.241.26.46.in-addr.arpa.
+www.harryshumjr.com.
+48.216.85.209.iadb.isipp.com.
+a.root-servers.net.
+s-static.ak.fbcdn.net.
+profile.ak.fbcdn.net.
+www.facebook.com.
+canseco.com.s8b1.psmtp.com.
+www.mediafire.com.
+hpana.com.
+www.rutacol.com.
+luismaenlasnubes.blogspot.com.
+photos-a.ak.fbcdn.net.
+factory.okna5.ru.
+ksn7-12.kaspersky-labs.com.
+bp1.blogger.com.
+www.middleeasthealthmag.com.
+photos-h.ak.fbcdn.net.
+www.gn4me.com.
+correoweb.com.
+cdn.ad4game.com.
+e-yes.gr.
+1.0.0.10.in-addr.arpa.
+sakura-card-captor-anime.blogspot.com.
+142.175.25.187.in-addr.arpa.
+descuidofamosas.info.
+gotfuturama.com.
+172.92.255.190.in-addr.arpa.
+cdn.mediafire.com.
+www.videosmz.com.
+www.detiknews.com.
+grnlakeorion.com.
+tfw-current.s3.amazonaws.com.
+goodtimes.com.
+211.11.4.175.in-addr.arpa.
+www.facebook.com.
+morgansstanley.com.
+titanium30-en.url.trendmicro.com.
+www.picadillocircus.com.
+secure.wlxrs.com.
+1.0.0.127.dnsbugtest.1.0.0.127.in-addr.arpa.
+187.2.115.92.in-addr.arpa.
+a8.sphotos.ak.fbcdn.net.
+svr3.marketrends.net.
+static.ak.fbcdn.net.
+a.root-servers.net.
+gg.google.com.
+ksn1-12-part2.kaspersky-labs.com.
+mail.buddysbarbq.com.
+iit.net.ru.
+59.216.92.186.in-addr.arpa.
+www.libraryloungelizard.com.
+barcelonacultura.bcn.cat.
+img1.imensagens.com.
+www.moringa.com.
+129.102.255.201.in-addr.arpa.
+buycostumes.pscsrv.net.
+208.64.32.190.in-addr.arpa.
+rodnik.biz.
+creative.ak.fbcdn.net.
+heart4me.com.
+static.ak.fbcdn.net.
+sites.google.com.
+mx.mujer.yahoo.com.
+plus.google.com.
+vnmade.com.
+www.google-analytics.com.
+rds.yahoo.com.
+40.53.24.189.in-addr.arpa.
+static.ak.facebook.com.
+b._dns-sd._udp.0.1.168.192.in-addr.arpa.
+96.145.171.187.in-addr.arpa.
+-de-masa-y-tortillas.wired.com.mx.
+158.46.153.201.in-addr.arpa.
+co122w.col122.mail.live.com.
+www.facebook.com.
+privetsochi.ru.
+159.146.180.189.in-addr.arpa.
+pixel.facebook.com.
+free.timeanddate.com.
+ru.thefreedictionary.com.
+sitebitrix.ru.
+www.simel.it.
+el-oso-oshitas.blogspot.com.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+118.49.40.190.in-addr.arpa.
+virginmega.com.s7b1.psmtp.com.
+21.115.138.189.in-addr.arpa.
+ic.tynt.com.
+t3.gstatic.com.
+a.root-servers.net.
+www.xatech.com.
+24.136.176.190.in-addr.arpa.
+rcp.na.blackberry.com.
+www.my-shop.com.au.
+bmaa.gv.at.
+met.adwhirl.com.
+vlex.com.co.
+urban.com.ru.
+a.root-servers.net.
+muuuvies.files.wordpress.com.
+homercentral.org.
+bartoncreek.com.
+89.210.205.190.in-addr.arpa.
+40.51.175.187.in-addr.arpa.
+mollenkopf.de.
+50.108.236.189.in-addr.arpa.
+a.root-servers.net.
+fbcdn-profile-a.akamaihd.net.
+googleapis.l.google.com.
+ajax.googleapis.com.
+a.root-servers.net.
+17.120.228.24.in-addr.arpa.
+51.89.53.92.in-addr.arpa.
+mx.hazlettinc.com.
+_311_33_5.
+a.root-servers.net.
+www.101incredibleplaces.com.
+53.149.48.65.in-addr.arpa.
+profile.ak.fbcdn.net.
+www.damselstruction.com.
+ksn7-12.kaspersky-labs.com.
+photos-e.ak.fbcdn.net.
+an.tacoda.net.
+horizonsisg.com.s8b2.psmtp.com.
+m.adnxs.com.
+ejabat.google.com.
+armonia-avm.com.
+1.0.0.127.dnsbugtest.1.0.0.127.in-addr.arpa.
+tcsinow.com.
+img125.hotlinkimage.com.
+www.readytogo.net.
+d2094182.xoom.it.
+ma61-c.analytics.edgesuite.net.
+www.gstatic.com.
+www.namazzamani.net.
+buckshotboredom.com.
+a.root-servers.net.
+ay84moqm1.c19d4d4q.
+176.206.132.190.in-addr.arpa.
+linkhelp.clients.google.com.
+angle-droit.fr.
+99.145.6.186.in-addr.arpa.
+wpad.
+fotoria.ru.
+205.41.9.109.in-addr.arpa.
+skins.gmodules.com.
+a.root-servers.net.
+a7.sphotos.ak.fbcdn.net.
+malaysia.answers.yahoo.com.
+geo.yahoo.com.
+maps.google.es.
+rcp.na.blackberry.com.
+www.maillife.co.uk.
+enterarteregional.blogspot.com.
+90.64.170.189.in-addr.arpa.
+www.apogee-web-consulting.com.
+api.facebook.com.
+tossersite.com.
+201.248.233.201.in-addr.arpa.
+lb._dns-sd._udp.0.0.168.192.in-addr.arpa.
+tracken.dolphin-browser.com.
+105.102.158.178.in-addr.arpa.
+es-es.com.wmlwww.login.facebook.com.
+tiny.cc.
+227.131.115.200.in-addr.arpa.
+www.facebook.com.
+52.238.90.200.in-addr.arpa.
+a.root-servers.net.
+teredo.ipv6.microsoft.com.
+www.faceb.
+www.webgamegame.com.
+hosteltur.com.
+mjls.org.
+static.ak.connect.facebook.com.
+safebrowsing.clients.google.com.
+www.okcupid.com.
+fbcdn-profile-a.akamaihd.net.
+newsrss.bbc.co.uk.
+api.nanigans.com.
+www.20minutos.es.
+searchclient.live.net.
+www.weekday.se.
+img.youtube.com.
+mail.mfworks.com.
+www.antivirus.com.
+graph.facebook.com.
+static-0.farmville.zgncdn.com.
+external.ak.fbcdn.net.
+215.162.134.190.in-addr.arpa.
+28.42.161.222.in-addr.arpa.
+search.twitter.com.
+toolbarqueries.google.com.
+a5.sphotos.ak.fbcdn.net.
+146.209.120.24.in-addr.arpa.
+b7g9v4d4s.i51f3w4b.
+zibzfwpdz.87it.
+66.185.9.186.in-addr.arpa.
+iceauto.ru.
+_535_21_7.
+profile.ak.fbcdn.net.
+a.root-servers.net.
+42.208.159.189.in-addr.arpa.
+aljazeera.net.
+scores.mochimedia.com.
+blu.stc.s-msn.com.
+b48mxdwk47ktl28j36k17d50buhxk57p62k67lrou.com.
+www.smarturl.it.
+249.102.244.190.in-addr.arpa.
+13.228.171.69.in-addr.arpa.
+60.6.55.85.in-addr.arpa.
+thewimshurstsmachine.com.
+valf.ru.
+18.39.25.88.in-addr.arpa.
+zrres.zt.energy.gov.ua.
+protocolocomentarios.blogspot.com.
+16.59.80.199.in-addr.arpa.
+hub.video.msn.com.
+h.live.com.
+lewer.com.s7b2.psmtp.com.
+ar-ar.facebook.com.
+ar.answers.yahoo.com.
+164.179.43.201.in-addr.arpa.
+neurosis2.concordia.ca.
+a.root-servers.net.
+external.ak.fbcdn.net.
+comunidades.esmas.com.
+ajax.googleapis.com.
+ad-g.doubleclick.net.
+37.145.248.189.in-addr.arpa.
+msk.aeroflot.ru.
+8.193.143.24.in-addr.arpa.
+exchange.highwoods.com.
+static.ak.fbcdn.net.
+pagead2.googlesyndication.com.
+time-a.nist.gov.
+17-courier.push.apple.com.
+blu.stj.s-msn.com.
+ns4.combell.net.
+191.196.233.118.in-addr.arpa.
+es.888.com.
+mail.rexcargo.com.
+180.20.168.192.in-addr.arpa.
+afisha.ru.
+teredo.ipv6.microsoft.com.
+_376_15_3.
+pixel.facebook.com.
+r._dns-sd._udp.home.
+static.ak.fbcdn.net.
+you-have-what-it-takes.com.
+jaringnews.com.
+ar.games.yahoo.com.
+148.64.156.93.in-addr.arpa.
+sgsdg.com.
+solta.com.
+static.ak.fbcdn.net.
+resources.alibaba.com.
+ssl.gstatic.com.
+www.sahafa.com.
+inbound.ffta.com.netsolmail.net.
+p0b.ru.
+www.xvideos.com.
+ajax.googleapis.com.
+optimized-by.rubiconproject.com.
+forums.hennapage.com.
+audio-libro.info.
+www.laverdad.es.
+finescale.com.s8b1.psmtp.com.
+mail.inflightcareers.com.
+242.46.69.190.in-addr.arpa.
+138.18.168.192.in-addr.arpa.
+vap1sea1.lijit.com.
+mail.
+pixel.mathtag.com.
+mail.copyandcamera.com.
+_579_98_6.
+photos-b.ak.fbcdn.net.
+unasesentona.blogspot.com.
+boards.dingoonity.org.
+games.piczo.com.
+talk.google.com.
+funcampco.ca.
+sp.cwfservice.net.
+f.facemoods.com.
+uniccos.com.
+newsletter.o2world.de.
+22.169.15.189.in-addr.arpa.
+amer.rel.msn.com.
+accounts.google.com.
+timmtytjhjdfj.blogspot.com.
+160.125.150.24.in-addr.arpa.
+bloodshedzine-spain.blogspot.com.
+dns.msftncsi.com.
+alma.net.
+photos-g.ak.fbcdn.net.
+www.ypmadserver.com.
+profile.ak.fbcdn.net.
+81.95.171.189.in-addr.arpa.
+a4.sphotos.ak.fbcdn.net.
+mail.twcinci.com.
+128.143.60.186.in-addr.arpa.
+safebrowsing-cache.google.com.
+sp.iphone-unlocker-pro.com.
+159.223.137.190.in-addr.arpa.
+www.update.microsoft.com.
+dapez.com.ar.
+www.cobraboxing.com.
+teredo.ipv6.microsoft.com.
+col.stj.s-msn.com.
+www.modern-canvas-art.com.
+static.cbox.ws.
+a8.sphotos.ak.fbcdn.net.
+mail.qzip.net.
+ds2.uniblue.com.
+mail.dd-rd.ca.
+12.10.162.46.in-addr.arpa.
+s.youtube.com.
+t2.gstatic.com.
+www.ssclg.com.
+sp.cwfservice.net.
+es.wikipedia.org.
+_759_60_5.
+elite-finance.com.
+transamtruck.com.
+i4.ytimg.com.
+xanky.com.
+pixel.quantserve.com.
+43.244.236.189.in-addr.arpa.
+filter1.presco-6.mailguard.com.au.
+corporate.ford.com.
+honor.americanheart.org.
+146.238.71.77.in-addr.arpa.
+motor.superdeporte.es.
+art-hist.ru.
+photos-g.ak.fbcdn.net.
+tracker.torrentbay.to.
+www.crowngroup.com.au.
+loading.retry.widdit.com.
+1.132.204.187.in-addr.arpa.
+70.163.144.189.in-addr.arpa.
+www.maincor.de.
+www.blogger.com.
+cineinblog.atarde.com.br.
+safebrowsing-cache.google.com.
+mp4-i7-1b.perfectgirls.net.
+a8.sphotos.ak.fbcdn.net.
+www.imobisoft.co.uk.
+ebay-volgograd.ru.
+82.98.140.175.in-addr.arpa.
+kotaku.com.
+cdn.api.twitter.com.
+clients2.google.com.
+easy-youtube-video-downloader.en.softonic.com.
+alpineutahrealty.com.
+a.root-servers.net.
+newt7.adultadworld.com.
+bjv9xcng.emltrk.com.
+www.cpxadspace.com.
+_247_65_6.
+web.educastur.princast.es.
+183.121.242.201.in-addr.arpa.
+51.80.4.186.in-addr.arpa.
+gfx2.hotmail.com.
+support.google.com.
+243.164.8.95.in-addr.arpa.
+www.premiershipwallpapers.com.
+a4.sphotos.ak.fbcdn.net.
+proxy-relay1.red.net.
+auth.shequ.10086.cn.
+enj9u3ka6.e74h6t4v.
+4rgk5srwp.d39k9p3b.
+video1.hobbico.com.
+www.djtonypeopleshousemusic.com.
+www.aradani.com.
+a.root-servers.net.
+ns1.itdienstleistung.at.
+photos-e.ak.fbcdn.net.
+www.hondunet.com.
+abco01.abcoproducts.com.
+vi.ebaydesc.com.
+43.214.85.209.bl.spamcop.net.
+mb.sympatico.ca.
+92.122.168.192.in-addr.arpa.
+zh-cn.facebook.com.
+18.181.84.59.in-addr.arpa.
+www.youtube.com.
+alta-print.com.
+geo.messenger.services.live.com.
+102.120.74.190.in-addr.arpa.
+gruponuevotramo.blogspot.com.
+secure.shared.live.com.
+12.38.225.189.in-addr.arpa.
+postal.essd.northgrum.com.
+fr-fr.facebook.com.
+grayen1.com.
+msc.wlxrs.com.
+a.root-servers.net.
+i3.ytimg.com.
+www.telenovelasgratis.com.
+unitrac.com.
+secure1.zynga.com.
+superfoodinfos.com.
+profile.ak.fbcdn.net.
+d2055595.instant.xoom.it.
+moviesonlinehere.com.
+a.root-servers.net.
+ads.bluelithium.com.
+_898_68_2.
+axismedia.co.uk.
+static.ak.fbcdn.net.
+upload.7ozn.com.
+ajax.googleapis.com.
+inty.net.
+ntp1.dlink.com.
+wvnvaxbd.com.
+a.root-servers.net.
+accounts.google.com.
+hu.wikipedia.org.
+gyptech.on.ca.
+firewall.idealcomponents.net.
+l.sharethis.com.
+23qnyctn8.13eh.
+www.imdb.com.
+102.143.254.180.in-addr.arpa.
+p7677.cdngc.net.
+travel.yahoo.com.
+a8.sphotos.ak.fbcdn.net.
+a.root-servers.net.
+fbcdn-profile-a.akamaihd.net.
+www.googletagservices.com.
+60.181.58.187.in-addr.arpa.
+a.root-servers.net.
+223.169.160.189.in-addr.arpa.
+183.36.229.189.in-addr.arpa.
+0-id-w.channel.facebook.com.
+sites.google.com.
+worelliesbrdm.su.
+fpdownload2.macromedia.com.
+developers.facebook.com.
+christophermills.uk.com.
+_259_22_5.
+a7.sphotos.ak.fbcdn.net.
+135.71.144.181.in-addr.arpa.
+www.flashgameport.com.
+d3lvr7yuk4uaui.cloudfront.net.
+vehiculos-usados.vivastreet.com.mx.
+coemsa.com.
+teredo.ipv6.microsoft.com.
+www.mariadeagreda.org.
+a8.sphotos.ak.fbcdn.net.
+135.62.177.189.in-addr.arpa.
+a.root-servers.net.
+time.stdtime.gov.tw.
+teaworld.ru.
+www.facebook.com.
+www.designerblogs.com.
+www.autumndewilde.com.
+ads.revsci.net.
+securemail.pmsyscorp.com.
+tt.wikipedia.org.
+gateway1i.kewill.com.
+www.adamtaylorphotography.com.
+www.discovery.com.
+opml.radiotime.com.
+api.geo.kontagent.net.
+dns.msftncsi.com.
+teredo.ipv6.microsoft.com.
+vuelos.viajes.hispavista.com.
+94.117.247.190.in-addr.arpa.
+plus.google.com.
+a.root-servers.net.
+media.roportal.ro.
+jigsy.com.
+api.youversion.com.
+rad.msn.com.
+www.tetactics.com.
+www.manualesdetodo.net.
+dingenvanlia.nl.
+www.soundofdrowning.com.
+developers.facebook.com.
+www.smoder.com.
+239.184.11.190.in-addr.arpa.
+cs11067.vk.com.
+m.facebook.com.
+a997.mm1.akamai.net.
+tutu.es.
+multimedia.eluniversal.com.mx.
+feim.com.s7a1.psmtp.com.
+23.1.168.192.in-addr.arpa.
+punkska.ru.
+safebrowsing-cache.google.com.
+s1-powerpoint.vo.msecnd.net.
+fbcdn-profile-a.akamaihd.net.
+225.32.57.187.in-addr.arpa.
+199.244.83.200.in-addr.arpa.
+a1.sphotos.ak.fbcdn.net.
+www.gnuart.net.
+242.183.168.192.in-addr.arpa.
+api.facebook.com.
+www.incredimages.com.
+ad-g.doubleclick.net.
+www.unonoticias.com.
+www.tuempresaenlared.net.
+henna-boy.co.uk.
+hi-audit.ru.
+236.84.147.79.in-addr.arpa.
+friskygeek.com.
+orionika.ru.
+designcentrix.com.
+s-external.ak.fbcdn.net.
+1671.live.streamtheworld.com.
+int.search-results.com.
+www.df.gob.mx.
+www.healthcare.uci.edu.
+external.ak.fbcdn.net.
+www.kiddycade.com.
+mail.gek.ru.
+teredo.ipv6.microsoft.com.
+dtboot.orbitdownloader.com.
+geoip.vmn.net.
+10412569.mx1.autocarindia.com.
+tmmc.ca.
+100.151.182.93.in-addr.arpa.
+t2.gstatic.com.
+a.root-servers.net.
+www.adobe.com.
+a8.sphotos.ak.fbcdn.net.
+profile.ak.fbcdn.net.
+118.242.143.187.in-addr.arpa.
+_449_64_2.
+12.206.83.67.in-addr.arpa.
+www.google.com.
+tts.se.
+www.facebook.com.
+s08.flagcounter.com.
+www.winespectator.com.
+27.181.157.186.in-addr.arpa.
+twitter.com.
+port.state.de.us.s7b1.psmtp.com.
+web.buddytv.netdna-cdn.com.
+www.tiffanyco.biz.
+edge.quantserve.com.
+ar-ar.facebook.com.
+ads2.msads.net.
+68.132.170.189.in-addr.arpa.
+devisa.ru.
+twitter.com.
+www.google.com.
+a.root-servers.net.
+a.root-servers.net.
+faiting.ru.
+sniderinc.com.s5a2.psmtp.com.
+i2.ytimg.com.
+rblns68.mailshell.net.
+dns.msftncsi.com.
+35.53.92.186.in-addr.arpa.
+prod2.rest-notify.msg.yahoo.com.
+static.ak.fbcdn.net.
+i3.ytimg.com.
+embarqmill.com.
+safebrowsing.clients.google.com.
+whos.amung.us.
+192.27.132.190.in-addr.arpa.
+a8.sphotos.ak.fbcdn.net.
+ssl.gstatic.com.
+v13.nonxt3.c.youtube.com.
+153.239.158.200.in-addr.arpa.
+153.125.65.189.in-addr.arpa.
+img822.imageshack.us.
+ads.creafi-online-media.com.
+www.facebook.com.
+www.belkin.com.
+mx.west.cox.net.
+goodfilesloader.ru.
+83.149.188.189.in-addr.arpa.
+photos-a.ak.fbcdn.net.
+7.150.173.201.in-addr.arpa.
+aol.com.
+mail.dovetailenterprises.co.uk.
+54.167.46.189.in-addr.arpa.
+api.zynga.com.
+ns1.cheat.net.ru.
+chccig.com.
+i3.ytimg.com.
+100.204.226.88.in-addr.arpa.
+android.clients.google.com.
+profile.ak.fbcdn.net.
+photos-h.ak.fbcdn.net.
+75.79.141.201.in-addr.arpa.
+209.253.199.187.in-addr.arpa.
+g-pixel.invitemedia.com.
+safebrowsing.clients.google.com.
+mail.conio.net.
+www.opendeco.es.
+144.31.210.201.in-addr.arpa.
+mail.leshak.perm.ru.
+a.root-servers.net.
+infanciayotrascosas.blogspot.com.
+gs02.supremacy1914.com.
+109.103.114.177.in-addr.arpa.
+denis.stalker.h3q.com.
+cydia.saurik.com.
+dns.msftncsi.com.
+49.222.171.189.in-addr.arpa.
+cplog.flashget.com.
+duck.ru.
+rwillustrator.blogspot.com.
+news.google.com.mx.
+www.nudismlife.com.
+www.miami-airport.com.
+rad.msn.com.
+creative.ak.fbcdn.net.
+a1408.w43.akamai.net.
+www.blackthickgirls.com.
+googleads.g.doubleclick.net.
+129.163.145.189.in-addr.arpa.
+a1003.w41.akamai.net.
+mailout.cop-inc.com.
+profile.ak.fbcdn.net.
+ebiparaguay.blogspot.com.
+b._dns-sd._udp.0.2.168.192.in-addr.arpa.
+mzmqh54k17exiwgxp22fuhuhyozntjrm69ky.com.
+82.138.25.187.in-addr.arpa.
+touch.facebook.com.
+pigrush.reigndesign.com.
+ieonlinews.microsoft.com.
+www.youtube.com.
+www.shbabelyom.com.
+www.facebook.com.
+uvg1zsa12.70pl.
+8hlns7iy2.o89k3z6q.
+127.16.244.189.in-addr.arpa.
+219.155.161.189.in-addr.arpa.
+dns.msftncsi.com.
+c-0.19-a309f481.483.1518.19d3.3ea1.410.0.6tri6qwwfgscawewswfsjz2qk6.avqs.mcafee.com.
+www.negotips.com.
+celiac-disease.emedtv.com.
+151.175.82.190.in-addr.arpa.
+checkip.dyndns.org.
+www.bywifi.com.
+a5.sphotos.ak.fbcdn.net.
+christineestima.wordpress.com.
+stats.wordpress.com.
+i4.ytimg.com.
+www.twitter.com.
+ws.tapjoyads.com.
+65.156.109.118.in-addr.arpa.
+fastonlineusers.com.
+tds.traforet.ru.
+dsn5.d.skype.net.
+fourwinds.ru.
+www.zonaoriente.com.
+i1.ytimg.com.
+140.209.225.189.in-addr.arpa.
+www.facebook.com.
+73.48.136.98.in-addr.arpa.
+asrs.net.
+monet.ru.
+netmcr.com.
+zelda.wikia.com.
+pagead2.googlesyndication.com.
+a7.sphotos.ak.fbcdn.net.
+as.digiturk.com.tr.
+meussshomenss.blogspot.com.
+figlobal.112.2o7.net.
+www.facebook.com.
+mail.pirate-party.ru.
+dl-desktop-apps.sonyericsson.com.
+time.stdtime.gov.tw.
+mx.megaproduct.com.
+apps.facebook.com.
+fbcdn-sphotos-a.akamaihd.net.
+190.239.5.200.in-addr.arpa.
+um12.eset.com.
+danhba.bao-anh.com.
+grovesconstruction.com.
+ricoh.com.
+10f.ru.
+a3.sphotos.ak.fbcdn.net.
+esohavuelto.blogspot.com.
+181.145.67.76.in-addr.arpa.
+time.apple.com.
+16.169.156.201.in-addr.arpa.
+228.218.101.189.in-addr.arpa.
+creative.ak.fbcdn.net.
+voteview.com.
+98.49.168.189.in-addr.arpa.
+110.91.53.186.in-addr.arpa.
+a.root-servers.net.
+145.86.181.190.in-addr.arpa.
+apps.facebook.com.
+oilandgasvacancy.com.
+download342.avast.com.
+hillsace.com.
+outsors.com.
+cocovishop.com.
+news.yahoo.com.
+hi-in.facebook.com.
+cdn1.widdit.com.
+53.249.223.201.in-addr.arpa.
+photos-h.ak.fbcdn.net.
+.
+creative.ak.fbcdn.net.
+billing.sharo4ka.ru.
+www.blackberry.com.
+www2.edi7.lu.
+tc.v22.cache1.c.youtube.com.
+business.shop.ebay.com.
+nivelexperto.com.
+119.203.177.190.in-addr.arpa.
+www.google.com.mx.
+www.girlfriends.bestnudethumbs.com.
+proquestcombo.safaribooksonline.com.
+vsimki.ru.
+www.anime-channel.org.
+g.ceipmsn.com.
+edge.sharethis.com.
+apps.facebook.com.
+www.bodyrock.tv.
+botones.blogalaxia.com.
+libya11.com.
+mk.cam4.com.
+streetwisemaps.com.
+static.ak.fbcdn.net.
+www.facebook.com.
+electronicaportable.blogspot.com.
+addons.mozilla.org.
+developer.sprint.com.
+googleads.g.doubleclick.net.
+lkcdn.com.
+genius.itunes.apple.com.
+a.root-servers.net.
+scenicwolfresort.com.
+a.root-servers.net.
+a1.sphotos.ak.fbcdn.net.
+corp.39.net.
+smtp2.aaanorthpenn.com.
+fxfeeds.mozilla.com.
+connect.facebook.net.
+ad.adnetwork.net.
+egyutt.hu.
+uruguay.clasificadoya.com.
+ad.yieldmanager.com.
+v6.cache1.googlevideo.com.
+a.root-servers.net.
+profile.ak.fbcdn.net.
+amega.com.
+a.root-servers.net.
+mtalk.google.com.
+_108_06_0.
+x04.o.ismtp.integra.net.
+markevin.fan-sites.org.
+linamar.ca.
+accessatt.net.
+pixel.facebook.com.
+khmervn.com.
+a.root-servers.net.
+www.celsa.fr.
+immortalseed.com.
+photos-a.ak.fbcdn.net.
+franke.com.
+38.voncp.com.
+gorod.dn.ua.
+cuentosdeprincesas.blogia.com.
+amandadecadenet.com.
+www.arcanos.org.
+reddit.com.
+ajax.googleapis.com.
+www.bogotaoccidente.com.
+noik.ru.
+pixel.facebook.com.
+50.170.153.201.in-addr.arpa.
+apis.google.com.
+tgmedia.ru.
+www.stc-law.com.
+arts.hku.hk.
+fbcdn-photos-a.akamaihd.net.
+lemondrealty.com.
+on.fb.me.
+google.com.
+166.120.3.121.in-addr.arpa.
+smaart.com.au.
+113.232.26.85.in-addr.arpa.
+translate.google.com.mx.
+external.ak.fbcdn.net.
+es.scribd.com.
+altfarm.mediaplex.com.
+www.facebook.com.
+secure.oldgoesyoung.com.
+mail.timberlineenergy.com.
+images2.cinemaki.com.
+4o:gzrhbj.88ic.
+awesmoe.files.wordpress.com.
+b-0.19-a3090009.8011081.1518.19d3.3ea1.410.0.6j7lctstkz7wl87kq7wnadkpp6.avqs.mcafee.com.
+dns.msftncsi.com.
+alphashirt.com.
+cdn.adventofdeception.com.
+149.69.221.72.in-addr.arpa.
+0-327.channel.facebook.com.
+232.234.172.190.in-addr.arpa.
+google.com.
+214.205.106.187.in-addr.arpa.
+client-software.real.com.
+55.120.207.186.in-addr.arpa.
+165.28.120.84.in-addr.arpa.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+www.danaestratou.gr.
+hiltontrinidad.com.
+www.decorshome.net.
+mail.google.com.
+a.root-servers.net.
+www.facebook.com.
+www.irnike.com.
+itunes.com.
+www.feartofaithclothing.com.
+ad.yieldmanager.com.
+mail.dynamac-usa.com.
+www.whathealth.com.
+i2.ytimg.com.
+www.salahtoons.net.
+u31.eset.com.
+time.chttl.com.tw.
+smtp.prestigehotels.com.
+262.com.
+110.43.3.173.in-addr.arpa.
+128.253.212.67.in-addr.arpa.
+www.ceain.acoge.org.
+24.228.171.69.in-addr.arpa.
+tappeconstruction.com.
+pc-drivers.fr.
+googlemail.l.google.com.
+ds.addthis.com.
+www.mundonick.com.
+pixel.facebook.com.
+horsethatleaps.com.
+met.adwhirl.com.
+113.32.25.201.in-addr.arpa.
+a.root-servers.net.
+www.fanreviews.com.
+a.root-servers.net.
+114.152.159.189.in-addr.arpa.
+a0.twimg.com.
+www.tidanhotels.com.
+www.mirrordev.com.
+static.ak.fbcdn.net.
+ih2.gamecopyworld.com.
+keridita11-11.blogdiario.com.
+blogs.miarroba.es.
+dns.msftncsi.com.
+uchypbz57.57mo.
+www.internetdownloadmanager.com.
+152.193.33.177.in-addr.arpa.
+beauty.interremi.com.
+243.89.158.189.in-addr.arpa.
+nccp-wii.cloud.netflix.net.
+googleads.g.doubleclick.net.
+huhu.com.
+_525_54_6.
+rv.ginyas.com.
+105.206.77.200.in-addr.arpa.
+photos-c.ak.fbcdn.net.
+www.turkcraft.com.
+a4.mzstatic.com.
+a.root-servers.net.
+photos-c.ak.fbcdn.net.
+cymynebgzyr.info.
+211.115.64.123.in-addr.arpa.
+a8.sphotos.ak.fbcdn.net.
+hog.assets1.zgncdn.com.
+www.adobe.com.
+www.chinavista.com.
+zeus.saarproperties.com.
+s0.2mdn.net.
+en-us.fxfeeds.mozilla.com.
+cityvillefb1.static.zgncdn.com.
+34.42.61.186.in-addr.arpa.
+a4.sphotos.ak.fbcdn.net.
+feeds.feedburner.com.
+gate.atk-media.ru.
+groups.google.com.mx.
+214.39.15.187.in-addr.arpa.
+orcart.facebook.com.
+translate.google.com.mx.
+129.13.151.79.in-addr.arpa.
+www.imdb.com.
+thumbs2.ebaystatic.com.
+motherboards.mbarron.net.
+www.facebook.com.
+i3.ytimg.com.
+7i3cveei3.58di.
+15-courier.push.apple.com.
+www.burialinsurance.com.
+a1.sphotos.ak.fbcdn.net.
+tms30.icrc.trendmicro.com.
+www.cocina.org.
+fbcdn-photos-a.akamaihd.net.
+nus.cdn.c.shop.nintendowifi.net.
+www.strangemag.com.
+secure-sg.imrworldwide.com.
+maps.google.com.
+adx.allstar.cz.
+translation.toolbar.conduit-services.com.
+www.mozilla.com.
+106.48.51.188.in-addr.arpa.
+mail.desupernet.com.
+0-staging.channel.facebook.com.
+checkip.dyndns.org.
+a.root-servers.net.
+pad2.whstatic.com.
+130.2.45.70.in-addr.arpa.
+28.212.139.190.in-addr.arpa.
+89.114.131.81.in-addr.arpa.
+sefram.testoon.com.
+a.root-servers.net.
+developers.facebook.com.
+105.185.73.190.in-addr.arpa.
+plus.google.com.
+189.188.217.87.in-addr.arpa.
+docs.google.com.
+tags.expo9.exponential.com.
+cdn.api.twitter.com.
+_080_37_3.
+a771.da1.akamai.net.
+static.ak.fbcdn.net.
+mail1.cruzdelsur.com.
+newtex.ru.
+elhadaqueteje.blogspot.com.
+corian.es.
+22.144.67.76.in-addr.arpa.
+safebrowsing.clients.google.com.
+a.root-servers.net.
+b.googlemail.l.google.com.
+www.designworldonline.com.
+235.215.196.74.in-addr.arpa.
+52.239.51.190.in-addr.arpa.
+email.americanexpress.com.
+googleapis.l.google.com.
+210.197.120.59.in-addr.arpa.
+225.29.17.190.in-addr.arpa.
+www.google.com.mx.
+ar-ar.facebook.com.
+www.gorillas.org.
+safebrowsing-cache.google.com.
+www.nuigalway.ie.
+224.60.124.95.in-addr.arpa.
+crisfusterber.blogspot.com.
+231.151.183.189.in-addr.arpa.
+a.root-servers.net.
+hotmail.com.
+b-womeninamericanhistory17.blogspot.com.
+mediaws.ign.com.
+a.root-servers.net.
+www.moevenpick-hotels.com.
+smtp.sportsmanswarehouse.com.
+cn1.redswoosh.akadns.net.
+mail.kuban.su.
+_479_43_2.
+a7.sphotos.ak.fbcdn.net.
+partner.googleadservices.com.
+121.184.99.190.in-addr.arpa.
+ksn1-12-part1.kaspersky-labs.com.
+www.chinaoffshore.net.
+v12.nonxt7.c.youtube.com.
+dns.msftncsi.com.
+email.sigmadesign.net.
+a1.twimg.com.
+ntfpm.cn.
+.
+a.root-servers.net.
+js.revsci.net.
+labteh.ru.
+www.4h4.com.
+olhandoaooeste.blogspot.com.
+yb45.yearbookreunions.com.
+a6.sphotos.ak.fbcdn.net.
+3cp9lcoq32dpn-c.c.yom.mail.yahoo.com.
+158.164.82.201.in-addr.arpa.
+198.212.89.186.in-addr.arpa.
+www.warnermusic.com.mx.
+check.sanasecurity.com.
+support.google.com.
+eznam.cz.
+www.chinnahom.com.
+www.lebonangle.com.
+static.ak.fbcdn.net.
+251.69.136.186.in-addr.arpa.
+edge.quantserve.com.
+ksn2-12.kaspersky-labs.com.
+81.30.26.151.in-addr.arpa.
+purposemagazine.com.
+static-cdn2.ustream.tv.
+olcuk.com.
+twitter.com.
+crazycollecting.wordpress.com.
+r.mzstatic.com.
+162.167.235.190.in-addr.arpa.
+www.nissinfoods.co.jp.
+cbbonline.com.s8b2.psmtp.com.
+243.220.156.189.in-addr.arpa.
+dns.msftncsi.com.
+a.root-servers.net.
+caslonsoft.com.
+platform.twitter.com.
+136.74.120.95.in-addr.arpa.
+js2.wlxrs.com.
+tinypic.com.
+sp.cwfservice.net.
+nygrants.com.inbound15.mxlogic.net.
+.
+kcapex.com.s8b1.psmtp.com.
+inbound.toiletwater.net.netsolmail.net.
+mail1.lowes.com.
+profile.ak.fbcdn.net.
+106.11.18.190.in-addr.arpa.
+static.ak.fbcdn.net.
+www.facebook.com.
+mob.adwhirl.com.
+200.253.42.181.in-addr.arpa.
+teredo.ipv6.microsoft.com.
+www.connect.facebook.com.
+www.apple.com.
+sigmatestudio.com.
+a8.sphotos.ak.fbcdn.net.
+cteainc.com.
+profile.ak.fbcdn.net.
+bjc.bash.ru.
+yahoo.com.
+nextenergycorp.com.
+avtobog.com.
+content.yieldmanager.edgesuite.net.
+beerbloggers.ning.com.
+sbcglobal.net.
+www.julio.com.
+www.facebook.com.
+school.edu.ru.
+avtia.com.
+23.52.167.75.in-addr.arpa.
+tecnologia.starmedia.com.
+91.12.247.190.in-addr.arpa.
+sibur.nnov.ru.
+jaxsuns02.jaxsuns.com.
+e566.b.akamaiedge.net.
+photos-g.ak.fbcdn.net.
+delishworld.com.
+fbcdn-sphotos-a.akamaihd.net.
+www.buysearcher.com.
+a1415.phobos.apple.com.
+thumbs.4chan.org.
+code.jquery.com.
+9.174.224.77.in-addr.arpa.
+a.root-servers.net.
+facebook.conduitapps.com.
+webcache.googleusercontent.com.
+camaraymicrofonos.blogspot.com.
+csi.gstatic.com.
+224.129.190.70.in-addr.arpa.
+connect.facebook.net.
+teredo.ipv6.microsoft.com.
+pcbut.com.tw.
+plusone.google.com.
+62.110.218.83.in-addr.arpa.
+fbcdn-photos-a.akamaihd.net.
+gol.com.
+234147.r.msn.com.
+tunnel.cfw.trustedsource.org.
+player.vimeo.com.
+mmx.fangtech.net.
+a.root-servers.net.
+a1.sphotos.ak.fbcdn.net.
+mx.ingenuitypro.com.
+api.facebook.com.
+t3.gstatic.com.
+77.111.248.88.in-addr.arpa.
+204.211.50.190.in-addr.arpa.
+magumbo-anime.blogspot.com.
+www.toxicfreenc.org.
+zrgzmjx8f.c42w9e1w.
+remote.legendsinconcert.com.
+www.google.com.
+wlyjhjjcttw.cc.company.com.
+toolbarqueries.google.com.
+cdn.api.twitter.com.
+news.bbc.co.uk.
+d2104037.xoom.it.
+photos-b.ak.fbcdn.net.
+187.24.171.201.in-addr.arpa.
+ilam.irna.ir.
+d.proadsdirect.com.
+mail.kungfudesign.com.
+a4.da1.akamai.net.
+smtp.rainbowsplash.com.
+a.root-servers.net.
+gleaf.net.
+koranmp3.ru.
+www.movieactors.com.
+www.oilman.com.au.
+ib.adnxs.com.
+vu.sel.sony.com.
+ffupdate.engine.conduit-services.com.
+she.yahoo.com.
+www.facebook.com.
+iczdwp5o8.b19y7y4c.
+usa.nedstatpro.net.
+r._dns-sd._udp.0.0.168.192.in-addr.arpa.
+65.225.220.190.in-addr.arpa.
+32.144.135.105.in-addr.arpa.
+t.co.
+rs178l32.rapidshare.com.
+s.ytimg.com.
+bikningallygr.nu.
+autos.latino.msn.com.
+hr-consult.ru.
+2iazzg3ne.z50f7l3i.
+www.gedonet.com.
+voyeur4you.com.hypestat.com.
+legalcity.es.
+photos-e.ak.fbcdn.net.
+aln.su.
+171.180.27.116.in-addr.arpa.
+sitnstitch.com.
+www.didtheyreadit.com.
+exclusive-restaurants.com.
+plus.google.com.
+a2.sphotos.ak.fbcdn.net.
+215.160.86.186.in-addr.arpa.
+magentmng.alipay.com.
+www.xvideos.com.
+johnnydeppargentina.350.com.
+lb._dns-sd._udp.0.2.168.192.in-addr.arpa.
+27.228.115.186.in-addr.arpa.
+186.95.159.82.in-addr.arpa.
+s.youtube.com.
+_470_90_6.
+yahoo.de.
+_554_01_5.
+a.root-servers.net.
+94.36.86.85.in-addr.arpa.
+a.root-servers.net.
+saul.nueve.com.mx.
+perfectboundstudio.blogspot.com.
+stroyholding.ru.
+ocsp.verisign.com.
+gdata.youtube.com.
+2.205.218.76.in-addr.arpa.
+4.162.132.187.in-addr.arpa.
+10.46.172.186.in-addr.arpa.
+mayfairmills.com.
+photos-c.ak.fbcdn.net.
+evt.collarity.com.
+120.234.171.189.in-addr.arpa.
+forofashion.com.
+0-68.channel.facebook.com.
+touch.facebook.com.
+215.157.15.189.in-addr.arpa.
+absolutetitleagency.com.
+a.root-servers.net.
+.
+dns.msftncsi.com.
+mail.delfinoinsulation.com.
+40.142.171.78.in-addr.arpa.
+delivery.simplytechnology.net.
+a2.sphotos.ak.fbcdn.net.
+www.latimes.com.
+0-if-w.channel.facebook.com.
+prutopical.com.
+4.50.194.190.in-addr.arpa.
+www.foxsportsla.com.
+tumblrplug.com.
+comicmexicano.blogspot.com.
+external.ak.fbcdn.net.
+235.151.29.64.in-addr.arpa.
+dns.msftncsi.com.
+0-167.channel.facebook.com.
+mishay.blogspot.com.
+rmcsda.org.s10a2.psmtp.com.
+348.ch.meebo.com.
+dr._dns-sd._udp.lan.
+smtp.rsnlt.com.
+nljyhq5lv.18cr.
+214.36.149.17.in-addr.arpa.
+www.protege323.com.
+www.qstraint.com.
+i12.photobucket.com.
+api.aizheke.com.
+demosite.ondemand.flumotion.com.
+d2056450.instant.xoom.it.
+www.socialgrowthtechnologies.com.
+a.root-servers.net.
+www.buenscoring.com.
+www.apex.com.om.
+js.revsci.net.
+external.ak.fbcdn.net.
+pagead2.googlesyndication.com.
+www.youtube.com.
+150.216.13.201.in-addr.arpa.
+c7.zedo.com.
+glyde.com.
+accounts.google.com.
+shfpc.com.
+www.enjoysudoku.com.
+eldorado.ru.
+www.lacaja.com.ar.
+_384_70_5.
+a.root-servers.net.
+widgets.5z5.com.
+mail.moellergroup.com.
+www.facebook.com.
+a1.sphotos.ak.fbcdn.net.
+switchboard.real.com.
+info.automotix.net.
+photos-c.ak.fbcdn.net.
+a7.sphotos.ak.fbcdn.net.
+242.71.166.190.in-addr.arpa.
+3cp9lcoq32dpn-c.c.yom.mail.yahoo.com.
+www.hyperpromote.com.
+google.com.
+its-outrageous.com.
+89.82.175.200.in-addr.arpa.
+i-7917323e.us-west-1a.service.amazonsilk.com.
+sanantoniodeltachira.olx.com.ve.
+timeline.leagueoflegends.com.
+www.precisioncounter.com.
+www.sanvalentinsebaila.es.
+nacion.docpit.com.
+sgp.gascom.ru.lan.
+support.google.com.
+www.htx.ro.
+hubbell-premise.com.s7b2.psmtp.com.
+dallas-land.com.
+www.photoscape.org.
+www.knucklebonz.com.
+content.yieldmanager.edgesuite.net.
+developers.facebook.com.
+38.22.18.190.in-addr.arpa.
+m.youtube.com.
+www.blogsandocs.com.
+orellana.mundoanuncio.ec.
+xbc9r8jli.56cz.
+history.cultural-china.com.
+s.imwx.com.
+www.ampalucienbriet.blogspot.com.
+www.topappsquare.com.
+josemartinezbolio.blogspot.com.
+a4.sphotos.ak.fbcdn.net.
+www.google.com.
+113.178.174.190.in-addr.arpa.
+gfx1.hotmail.com.
+175.165.176.190.in-addr.arpa.
+www.culturaclick.com.
+foros.toxico-pc.com.
+acquirelawer.org.
+133.253.56.190.in-addr.arpa.
+s4.mcstatic.com.
+27.150.8.200.in-addr.arpa.
+13-courier.push.apple.com.
+loading1.widdit.com.
+actaware.it.
+stilettostyle.com.
+wiki.pentaho.com.
+_ldap._tcp.
+de-de.facebook.com.
+clients2.google.com.
+stats.panet.co.il.
+25.4.168.192.in-addr.arpa.
+wrowsezns.52au.
+a896.phobos.apple.com.edgesuite.net.
+www.cheaphandbagsuk.co.uk.
+a8.sphotos.ak.fbcdn.net.
+rblns81.mailshell.net.
+157.60.137.92.in-addr.arpa.
+a7.sphotos.ak.fbcdn.net.
+hes.ucfsd.org.
+jandex.ru.
+keshmuney.com.
+jacqueslowe.com.
+169.245.88.200.in-addr.arpa.
+static.ak.connect.facebook.com.
+lipstitsteethhips.blogspot.com.
+pentax-k100d.info.
+194.46.253.218.in-addr.arpa.
+mx.msn.recepedia.com.
+www.laceylady.com.
+www.youtube.com.
+www.cinepolis.com.
+5.43.14.88.in-addr.arpa.
+a4.sphotos.ak.fbcdn.net.
+149.205.131.24.in-addr.arpa.
+sputnikmaps.mail.ru.
+sc17.rules.mailshell.net.
+6.745565e-02.com.
+220.78.211.108.in-addr.arpa.
+decipher.me.uk.
+j003.palmws.com.
+www.proc.britac.ac.uk.
+don.com.s9a2.psmtp.com.
+mx.coldwellbankerthomas.com.
+www.tyler.com.mx.
+integral.com.au.
+hairloss.ygoy.com.
+33.144.22.186.in-addr.arpa.
+rtl.feedsportal.com.
+a3.sphotos.ak.fbcdn.net.
+m.facebook.com.
+developers.facebook.com.
+col.stb00.s-msn.com.
+greedykidz.net.
+a8.sphotos.ak.fbcdn.net.
+www.shoptoys.ru.
+cdn.api.twitter.com.
+fc09.deviantart.net.
+towncountryrealty.net.
+ns2.tktor.ru.
+r._dns-sd._udp.0.0.168.192.in-addr.arpa.
+bajaryoutube.com.
+a.root-servers.net.
+www.domedeep.com.
+23-courier.push.apple.com.
+images02.olx-st.com.
+a1005.w42.akamai.net.
+a.root-servers.net.
+sslmit.unibo.it.
+k.ilius.net.
+196.50.122.84.in-addr.arpa.
+conduit.anybodyoutthere.com.
+partner.googleadservices.com.
+www.okcupid.com.
+ibogroups.com.
+www.google.com.
+blgspb.ru.
+cleanrun.com.
+giancarloescalante.blogspot.com.
+a8.sphotos.ak.fbcdn.net.
+player.vimeo.com.
+www.meinprospekt.de.
+a4.sphotos.ak.fbcdn.net.
+csc3-2010-crl.verisign.com.
+upload.facebook.com.
+70.28.138.24.in-addr.arpa.
+150.151.51.188.in-addr.arpa.
+www.subdivx.com.
+a4.sphotos.ak.fbcdn.net.
+img.hellocotton.com.
+um18.eset.com.
+www.google.com.
+searchjs.s3.amazonaws.com.
+webres4.pand.ctmail.com.
+245.117.169.189.in-addr.arpa.
+www.265jkw.net.
+ibxaxl-cash.net.
+fira.ru.
+adcofnorton.com.inbound15.mxlogic.net.
+secure.adnxs.com.
+a.root-servers.net.
+promostation.ru.
+203.185.15.118.in-addr.arpa.
+img3.theboyspics.com.
+www.tu-farmacia.com.
+g.msn.com.
+salud.nih.gov.
+go.microsoft.com.
+28.67.75.65.in-addr.arpa.
+track.sextorrent.to.
+uikusuvpj.info.
+bs.serving-sys.com.
+a2.sphotos.ak.fbcdn.net.
+mscrl.microsoft.com.
+www.toybangers.net.
+dns.msftncsi.com.
+api-read.facebook.com.
+a.root-servers.net.
+www.facebook.com.
+48.108.132.94.in-addr.arpa.
+buc.k12.va.us.
+76.223.238.99.in-addr.arpa.
+189.5.188.207.in-addr.arpa.
+external.ak.fbcdn.net.
+www-fc-opensocial.googleusercontent.com.
+:lugv26hs.e86h1r2q.
+www.viagemdossentidos.com.
+ads.vs.com.
+drewfriedman.blogspot.com.
+db._dns-sd._udp.0.1.168.192.in-addr.arpa.
+grupogaleria.com.
+statistic-collector.gad.de.
+api.twitter.com.
+www.gentlemensclubpodcast.com.
+t-online.de.
+a.root-servers.net.
+a.root-servers.net.
+external.ak.fbcdn.net.
+fdafda.com.
+time.windows.com.
+ballroomradio.com.
+i1.ytimg.com.
+external.ak.fbcdn.net.
+safebrowsing-cache.google.com.
+pfo.su.
+plus.google.com.
+90.121.55.65.in-addr.arpa.
+75.64.225.190.in-addr.arpa.
+time.windows.com.
+www.medicalsupplydepot.com.
+a.root-servers.net.
+234.168.78.190.in-addr.arpa.
+www.prmoment.com.
+www.musicload.ch.
+www.google.com.
+equinejournal.com.
+static.ak.fbcdn.net.
+pixel.facebook.com.
+a.root-servers.net.
+a4.sphotos.ak.fbcdn.net.
+photos-g.ak.fbcdn.net.
+www.google.com.
+capricorp.com.
+_978_09_7.
+time.chttl.com.tw.
+pubads.g.doubleclick.net.
+cache-simg1.pressdisplay.com.
+55.192.207.190.in-addr.arpa.
+204.113.76.190.in-addr.arpa.
+photos-d.ak.fbcdn.net.
+www.youtube.com.
+www.lpf.com.
+thehollywoodnews.com.
+210.9.69.190.in-addr.arpa.
+www.allcasinoslots.com.
+dat.ru.
+www.themeblvd.com.
+141.178.59.74.in-addr.arpa.
+6c461c1f.filesonthe.net.
+244.154.56.187.in-addr.arpa.
+static.app.widdit.com.
+www.vindiesel.com.
+12.0.168.192.in-addr.arpa.
+grasche.com.mx3.net10.rcimx.net.
+acm.master-code.ru.
+rss.marca.com.
+static.ak.fbcdn.net.
+admeld.adnxs.com.
+a7.sphotos.ak.fbcdn.net.
+local-bay.contacts.msn.com.
+scholar.google.com.
+9.157.134.186.in-addr.arpa.
+133.129.203.69.in-addr.arpa.
+a.root-servers.net.
+o-o.preferred.ams03g05.v22.lscache5.c.youtube.com.
+www.google.com.
+borntotry.polyvore.com.
+buenosairesrunway.blogspot.com.
+mail.live.com.
+hoiantrailsresort.com.vn.
+ampliatumente.com.
+searchjs.s3.amazonaws.com.
+mibollywoodmania.blogspot.com.
+profile.ak.fbcdn.net.
+metrics.caracoltv.com.
+i1.ytimg.com.
+mail.google.com.
+tracker.openbittorrent.com.
+www.globo.com.
+funniest-commercials.net.
+6.3.d.8.7.2.b.4.a.3.9.2.8.0.8.1.6.7.e.9.7.3.1.4.0.0.0.0.1.0.0.2.ip6.arpa.
+analytic.spamfighter.com.
+srob.com.
+www.circuittube.com.
+secure.skypeassets.com.
+yahoo.co.in.
+a.root-servers.net.
+sac.gti.mcafee.com.
+a6.sphotos.ak.fbcdn.net.
+static-images.veevr.com.
+.
+146.213.177.190.in-addr.arpa.
+www.iwantbanners.com.
+developers.facebook.com.
+e4805.b.akamaiedge.net.
+_863_35_6.
+support.live.com.
+part710.ru.
+time.windows.com.
+sp.cwfservice.net.
+hotmail.com.
+a639.da1.akamai.net.
+developers.facebook.com.
+static.ak.fbcdn.net.
+ds.addthis.com.
+a.root-servers.net.
+forums.motivemag.com.
+photos-b.ak.fbcdn.net.
+checkip.dyndns.org.
+photos-g.ak.fbcdn.net.
+bin.images.tuenti.net.
+tfw-current.s3.amazonaws.com.
+so-many-roads-boots.blogspot.com.
+billing.sharo4ka.ru.
+36ohk6dgmcd1n-c.c.yom.mail.yahoo.net.
+updatekeepalive.mcafee.com.
+a5.sphotos.ak.fbcdn.net.
+www.wsf.la.
+imageb.epocrates.com.
+a6.sphotos.ak.fbcdn.net.
+go.epson.com.
+rorwqgflplllupx.info.
+profile.ak.fbcdn.net.
+133.81.48.208.in-addr.arpa.
+profile.ak.fbcdn.net.
+a.root-servers.net.
+download332.avast.com.
+www.differencebetween.co.in.
+elmicrobiologo.com.
+db._dns-sd._udp.0.0.168.192.in-addr.arpa.
+a5.da1.akamai.net.
+mobile.kobobooks.com.
+_635_45_9.
+josephsgolfshop.com.
+twitter.com.
+www.mulasoft.com.
+s-static.ak.facebook.com.
+bgoa.coxmail.com.
+silkshop.ru.
+checkip.dyndns.com.
+deccats.com.
+69.200.162.189.in-addr.arpa.
+www.elcorreo.com.
+mail4.red-tube.com.
+wpmlegal.com.
+a.root-servers.net.
+couponbuddy.s3.amazonaws.com.
+www.facebook.com.
+49.165.174.190.in-addr.arpa.
+175.217.26.125.in-addr.arpa.
+ligsay.com.mail9.psmtp.com.
+my.yahoo.com.
+a17sa.com.
+www.themarryblogger.com.
+wlp.carlead.com.
+photos-h.ak.fbcdn.net.
+local.msn.com.
+photos.e46fanatics.com.
+86.170.53.60.in-addr.arpa.
+teredo.ipv6.microsoft.com.
+a.root-servers.net.
+yl9y5g7k4.i27r3n4w.
+itbe.com.
+www.iyifilmizle.org.
+www.google.com.
+photos-h.ak.fbcdn.net.
+www.smuckers.com.mx.
+157.239.98.190.in-addr.arpa.
+adsfront.iminent.com.
+a5.sphotos.ak.fbcdn.net.
+dl_dir3.qq.com.
+search-mx.mlstatic.com.
+www.tmk.com.
+inbound.atiwave.com.netsolmail.net.
+www.adsphinx.com.
+artswork.org.uk.
+google.com.
+comienzoatejer.blogspot.com.
+brensoncorp.com.
+qualink.com.
+www.google.com.mx.
+234.247.92.186.in-addr.arpa.
+www.facebook.com.
+ip-link.ru.
+sites.google.com.
+www.mena.co.nz.
+cox.net.
+www.cunda.at.
+a5.sphotos.ak.fbcdn.net.
+allfreeiphones.net.
+_601_17_8.
+a.root-servers.net.
+88.34.225.190.in-addr.arpa.
+photos-g.ak.fbcdn.net.
+ad.yieldmanager.com.
+www.wowstars.com.
+billing.sharo4ka.ru.
+casaycampo.es.
+104.142.106.186.in-addr.arpa.
+102.226.251.122.in-addr.arpa.
+www.youtube.com.
+time.chttl.com.tw.
+mail.classicjourneys.com.
+www.cafepress.com.
+image2.pubmatic.com.
+pandasux.com.
+www.google-analytics.com.
+www.deine-mutter.de.
+a.root-servers.net.
+a.root-servers.net.
+ad.yieldmanager.com.
+www.google.com.
+colombiavallenato.wordpress.com.
+keuk.elektra.ru.
+static.ak.fbcdn.net.
+a5.sphotos.ak.fbcdn.net.
+cdn-7.pics.t8premium.com.
+sweetlorraine.com.
+186.229.129.98.in-addr.arpa.
+202.58.70.200.in-addr.arpa.
+_220_45_0.
+a.root-servers.net.
+spitfire.com.au.
+20.224.171.69.in-addr.arpa.
+l.longtailvideo.com.
+www.adobe.com.
+mx.sonet.ru.
+www.successhappinessformula.com.
+25.210.174.189.in-addr.arpa.
+photos-c.ak.fbcdn.net.
+bellsout.h.net.
+i2.ytimg.com.
+161.241.120.186.in-addr.arpa.
+pp2.inet.fi.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+profile.ak.fbcdn.net.
+a1737.g.akamai.net.
+professional.avira-update.com.
+137.192.68.89.in-addr.arpa.
+googleads.g.doubleclick.net.
+www.derechoalverde.com.
+katzforums.com.
+hoatmil.com.
+google.com.
+.
+.
+www.cortexpower.de.
+mail.webengr.com.
+67.57.100.84.in-addr.arpa.
+fortresstrophyroom.blogspot.com.
+groups.google.com.mx.
+wer.microsoft.com.
+www.mysearsrebate.com.
+111.84.100.177.in-addr.arpa.
+mail2fantasy.com.
+www.rechargefree.weebly.com.
+www.facebook.com.
+archive.popurls.com.
+posta72a.mailbeta.libero.it.
+www.christopherpoole.tv.
+megaman.wikia.com.
+www.antoniotsai.com.
+p04-keyvalueservice.icloud.com.
+track.reinvigorate.net.
+179.17.77.190.in-addr.arpa.
+aadel.iranhrdc.org.
+pt-br.facebook.com.
+profile.ak.fbcdn.net.
+a8.sphotos.ak.fbcdn.net.
+48.94.172.95.in-addr.arpa.
+19.85.101.187.in-addr.arpa.
+yfrog.com.
+msn.com.
+m-smanufacturing.com.
+i2.ytimg.com.
+www.saaid.net.
+irc.purchaseservice.com.
+corporate.miniclip.com.
+allwrongallright.files.wordpress.com.
+ocelott.tumblr.com.
+external.ak.fbcdn.net.
+dsn15.d.skype.net.
+911law.com.
+b._dns-sd._udp.0.1.168.192.in-addr.arpa.
+dfsfin.com.
+dnl-00.geo.kaspersky.com.
+pixel.facebook.com.
+a.root-servers.net.
+img19.exs.cx.
+sadhugroup.com.
+youtu.be.
+a.root-servers.net.
+external.ak.fbcdn.net.
+zhanet.com.
+crl.microsoft.com.
+profile.ak.fbcdn.net.
+kvoxgvihcv.com.
+mail3.soam.com.
+c4pi.de.
+oads.com.s5b1.psmtp.com.
+www.ortamtr.net.
+www.oakridgeproductions.ca.
+197.238.100.94.in-addr.arpa.
+live-for-speed.softonic.com.
+jsonline.com.s8a2.psmtp.com.
+smtp.wcbicecream.com.
+api.twitter.com.
+226.251.117.79.in-addr.arpa.
+sanpablo.com.pe.
+mikryptorincon.com.
+106.133.82.200.in-addr.arpa.
+gasa.hit.gemius.pl.
+topper.rmcc.cc.ar.us.
+apple.com.
+chromejs.s3.amazonaws.com.
+core.mochibot.com.
+divx-films.ru.
+prazdnik77.ru.
+www.alexcdn.info.
+a1.bing4.com.
+pagead2.googlesyndication.com.
+mx2.hotmail.com.
+profile.ak.fbcdn.net.
+a7.sphotos.ak.fbcdn.net.
+66.9.22.186.in-addr.arpa.
+saudireadymix.com.sa.
+www.facebook.com.
+pbid.iforex.com.
+sreenevasan.com.
+www.tataclub.com.ar.
+us.img.e-planning.net.
+196.19.164.189.in-addr.arpa.
+thecleanlife.hubpages.com.
+mailx2.alsolnet.com.
+stream3.mxcdn.com.
+22.149.220.66.in-addr.arpa.
+_232_67_1.
+253.147.198.187.in-addr.arpa.
+i1.makcdn.com.
+89.103.133.41.in-addr.arpa.
+www.google-analytics.com.
+mail.finklealaw.com.
+249.247.110.186.in-addr.arpa.
+ahmsi3.com.s7a2.psmtp.com.
+mtyfcpvyu.cc.private.
+welcometohosana.com.
+32.241.149.186.in-addr.arpa.
+tamsconj.com.
+47.14.17.95.in-addr.arpa.
+www.designisfels.net.
+mail.all4inc.com.
+a2.sphotos.ak.fbcdn.net.
+78.19.185.124.in-addr.arpa.
+dns.msftncsi.com.
+www.mall506.com.
+a3.sphotos.ak.fbcdn.net.
+b48fscxe11e11cuoyfrd30dsa67bqf62ptcwcv.net.
+99.244.205.190.in-addr.arpa.
+postd.cn.
+www.google.com.mx.
+traderjoestravel.com.
+131.164.215.89.in-addr.arpa.
+tools.google.com.
+239.97.120.95.in-addr.arpa.
+www.domcentral.org.
+1.0.0.127.dnsbugtest.1.0.0.127.in-addr.arpa.
+www.imahero.com.
+twitter.com.
+address.yahoo.com.
+img181.imagevenue.com.
+ad.doubleclick.net.
+tags.crwdcntrl.net.
+cssdeck.com.
+www.fromzerotoseo.com.
+ugliesttattoos.wordpress.com.
+n19.8-d.com.
+226.40.191.190.in-addr.arpa.
+104.165.40.114.in-addr.arpa.
+alltel.net.
+s0.2mdn.net.
+ad.metanetwork.com.
+expandondemand.net.
+77.163.138.201.in-addr.arpa.
+1.0.0.127.dnsbugtest.1.0.0.127.in-addr.arpa.
+www.podiatry-arena.com.
+dsdtraffic.com.
+translation1.paralink.com.
+i4.ytimg.com.
+xhkbkxm:5.65gz.
+health-beauty-tips.org.
+194.209.30.200.in-addr.arpa.
+116.85.50.190.in-addr.arpa.
+45.64.195.83.in-addr.arpa.
+player.vimeo.com.
+t2.gstatic.com.
+dns.msftncsi.com.
+242.15.120.174.in-addr.arpa.
+malah.biz.
+a.root-servers.net.
+images.paraorkut.com.
+142.164.232.99.in-addr.arpa.
+ocsp.verisign.com.
+lh5.googleusercontent.com.
+stats.wordpress.com.
+vialibrepl.com.
+i3.ytimg.com.
+grupobbva.net.
+www.latest-tattoo-designs.com.
+loading3.widdit.com.
+130.109.50.190.in-addr.arpa.
+www.google.com.
+a3.sphotos.ak.fbcdn.net.
+k:hq:wtqh.r10q2s9n.
+irc.purchaseservice.com.
+s-static.ak.fbcdn.net.
+mail.glhsco.com.
+t.co.
+photos-f.ak.fbcdn.net.
+adserver.adtech.de.
+80.115.151.184.in-addr.arpa.
+zapy9d5oe.45di.
+cache-default04g.cdn.yandex.net.
+220.126.178.186.in-addr.arpa.
+www.wing-zero.net.
+hbf.cloud.avg.com.
+cs506402.vk.com.
+153.252.78.186.in-addr.arpa.
+215.140.39.99.in-addr.arpa.
+www.onlinesayac.com.
+justcookit.blogspot.com.
+www.clavier-arab.org.
+a7.sphotos.ak.fbcdn.net.
+telepizzaes.solution.weborama.fr.
+images.google.com.
+iadsdk.apple.com.
+tolu.na.
+i073.radikal.ru.
+developers.facebook.com.
+www.odditieszone.com.
+a.root-servers.net.
+ad.yieldmanager.com.
+masdeluna.com.
+167.35.76.91.in-addr.arpa.
+www.123news.org.
+zillo.de.
+ksn7-12.kaspersky-labs.com.
+a.root-servers.net.
+chepireastlibr.cn.
+151.189.128.189.in-addr.arpa.
+leased-lines-204-235.tricom.net.
+support.google.com.
+www.migoa.com.
+crl.microsoft.com.
+pixel.facebook.com.
+48.13.93.186.in-addr.arpa.
+carroll.k12.ia.us.
+www.customsolutions.es.
+profile.ak.fbcdn.net.
+mail.slesnick.com.
+iphone-wu.apple.com.
+photos-b.ak.fbcdn.net.
+dns.msftncsi.com.
+tradal.net.
+player.vimeo.com.
+goo.gl.
+platform.ak.fbcdn.net.
+faq.immobilienscout24.de.
+translate.google.com.
+safebrowsing.clients.google.com.
+clock.fmt.he.net.
+www.manginasal.com.
+rihanna.wikia.com.
+144.63.178.187.in-addr.arpa.
+historymaker.com.
+60.55.48.27.in-addr.arpa.
+e1374.c.akamaiedge.net.
+a.root-servers.net.
+www.fmnh.helsinki.fi.
+disney.go.com.
+coldcomfort.com.s7a2.psmtp.com.
+a.root-servers.net.
+img2.blogblog.com.
+a.root-servers.net.
+ksn-kddi.kaspersky-labs.com.
+www.cherryconnect.com.
+s.youtube.com.
+vkusnoteevo.ru.
+www.facebook.com.
+dlvr.it.
+www.dancetrippin.tv.
+a.root-servers.net.
+yourfuture.ab.ca.
+docs.google.com.
+video.od.visiblemeasures.com.
+pt.cam4.com.
+www.google.com.
+www.hdtmedia.com.
+mail.tjohns.net.
+www.seejapan.co.uk.
+lb._dns-sd._udp.lan.
+a1.sphotos.ak.fbcdn.net.
+fo7b7kids.83bo.
+mailhost.groupe-sesar.com.
+api.twitter.com.
+photos-h.ak.fbcdn.net.
+floridafemme.net.
+disney.go.com.
+btfans.3322.org.
+a2.sphotos.ak.fbcdn.net.
+www.uniquecarsandparts.com.au.
+redberry.com.
+bioware.com.s7b1.psmtp.com.
+96.157.97.83.in-addr.arpa.
+awards.aol-soft.com.
+47.134.242.96.in-addr.arpa.
+www.facebook.com.
+fxfeeds.mozilla.com.
+f4.r.56.com.
+www.google.com.
+aps.ru.
+www.afiyetle.com.
+msc.wlxrs.com.
+urs.microsoft.com.
+234.99.17.88.in-addr.arpa.
+www.semarmenia.gov.co.
+cdn1.image.keezmovies.phncdn.com.
+sc6.rules.mailshell.net.
+ocsp.digicert.com.
+94.musclemeal.pay.clickbank.net.
+www.raf.mod.uk.
+empleo.trovit.com.mx.
+consoltech.com.
+coohuxnlpdtqmynypssqfhals.jp.
+katherineisawesome.files.wordpress.com.
+www.footylounge.org.
+external.ak.fbcdn.net.
+www.youtube.com.
+skylinealabama.com.
+www.velaro.com.
+173.153.223.87.in-addr.arpa.
+tvtomsk.ru.
+137.204.93.186.in-addr.arpa.
+twitter.com.
+mail.agilityphysicaltherapy.com.
+194.142.72.91.in-addr.arpa.
+236.113.113.186.in-addr.arpa.
+cf.addthis.com.
+e905.b.akamaiedge.net.
+google.com.
+photos-f.ak.fbcdn.net.
+ic.tynt.com.
+www.facebook.com.
+i3.ytimg.com.
+www.perfectlyengraved.co.uk.
+checkip.dyndns.org.
+photos-b.ak.fbcdn.net.
+www.sexenon.com.
+mail.winnercom.ru.
+banner.paypopup.com.
+a.root-servers.net.
+w291.photobucket.com.
+iirc.niu.edu.
+www.floorballmagazin.de.
+creative.ak.fbcdn.net.
+t2.gstatic.com.
+igor.facemoods.com.
+banners.iminent.com.
+www.avionics-event.com.
+platform.twitter.com.
+www.google.com.
+de-de.facebook.com.
+a1.sphotos.ak.fbcdn.net.
+epsilon-group.com.
+www.youtube.com.
+www.xvideos.com.
+mac4rteso.wordpress.com.
+www.fanlore.org.
+_458_87_9.
+www.cheapcues.com.
+dpdn.sandai.net.
+es.wikipedia.org.
+translate.google.com.mx.
+img2.mlstatic.com.
+a6.phobos.apple.com.
+ad-power.ru.
+sc2.rules.mailshell.net.
+www.theagencyonline.co.uk.
+116.103.19.190.in-addr.arpa.
+panda-antivirus.softonic.com.
+www.hoycocino.com.ar.
+amer.rel.msn.com.
+i.ebayimg.com.
+www.reventandoculos.com.
+www.google.com.
+dagoatrapist.com.
+www.facebook.com.
+www.hillandknowlton.com.
+pacwriter.softonic.com.
+static3.wonderwall.com.
+www.eleccionesandalucia.es.
+210.164.255.201.in-addr.arpa.
+www.autocosmos.com.mx.
+www.halohairextensions.com.
+dcmovies.wikia.com.
+image2.pubmatic.com.
+photos-e.ak.fbcdn.net.
+subine.net.
+shinko-spl.com.sg.
+240.42.190.190.in-addr.arpa.
+www.eset.com.ph.
+google.com.
+amer.rel.msn.com.
+_857_75_1.
+a.root-servers.net.
+angel-a.ru.
+profile.ak.fbcdn.net.
+mail.befa.net.
+fcs91-1.streamate.com.
+www.educatico.ed.cr.
+mashable.com.
+box.ijneb.com.
+ads.smowtion.com.
+www.skk-banjaluckapivara.com.
+a1404.w41.akamai.net.
+tophost.it.
+www.ourproperty.co.uk.
+100.50.31.190.in-addr.arpa.
+downloader.versalsoft.com.
+www.aapkikismat.com.
+hpmedcenter.com.s8b1.psmtp.com.
+clasesdejoyeria.blogspot.com.
+72.87.232.190.in-addr.arpa.
+d15gt9gwxw5wu0.cloudfront.net.
+not-mail.uniwin.ru.
+messenger.hotmail.com.
+static.apotheken-umschau.de.
+db._dns-sd._udp.lan.
+kbvm:p74y.55lb.
+negro0045.com.
+dnl-01.geo.kaspersky.com.
+books.google.es.
+static.ak.fbcdn.net.
+time.windows.com.
+parentingsquad.com.
+safebrowsing-cache.google.com.
+safebrowsing-cache.google.com.
+www.facebook.com.
+d2102706.xoom.it.
+clinton.k12.ky.us.
+86.143.203.69.in-addr.arpa.
+i3.ytimg.com.
+ps3.brewology.com.
+88.253.142.187.in-addr.arpa.
+photos-e.ak.fbcdn.net.
+twitter.com.
+www.xvideos.com.
+platform.ak.fbcdn.net.
+evsecure-ocsp.verisign.com.
+32.112.236.201.in-addr.arpa.
+teredo.ipv6.microsoft.com.
+63.242.184.99.in-addr.arpa.
+transloadamerica.com.s5a2.psmtp.com.
+folio.com.
+aclupa.org.
+nuestrasmiscelaneas.blogspot.com.
+clients4.google.com.
+asktoolbar.weather.com.
+photos-e.ak.fbcdn.net.
+a3.sphotos.ak.fbcdn.net.
+img815.imageshack.us.
+www.rsvp.com.au.
+unless.com.
+img42.imageshack.us.
+touch.facebook.com.
+photos-c.ak.fbcdn.net.
+a.root-servers.net.
+a727.phobos.apple.com.
+230.247.96.109.in-addr.arpa.
+dnl-01.geo.kaspersky.com.
+accounts.google.com.
+unifi.
+trans-p2p.pandora.tv.
+6.177.55.201.in-addr.arpa.
+www.youtube.com.
+arielassociates.com.
+www.sourcevibrations.com.
+a6.sphotos.ak.fbcdn.net.
+sp.cwfservice.net.
+a1.sphotos.ak.fbcdn.net.
+dnl-18.geo.kaspersky.com.
+a3.sphotos.ak.fbcdn.net.
+safebrowsing-cache.google.com.
+google.com.
+www.googletagservices.com.
+a6.sphotos.ak.fbcdn.net.
+3end.ru.
+144.248.138.189.in-addr.arpa.
+i1.ytimg.com.
+js.admeld.com.
+22.239.187.189.in-addr.arpa.
+www.quicklycode.com.
+evolutionarypsychiatry.blogspot.com.
+portugalunderground.blogspot.com.
+b.scorecardresearch.com.
+developers.facebook.com.
+secure-anntaylor2.richfx.com.
+accounts.google.com.
+235.26.27.188.in-addr.arpa.
+a.root-servers.net.
+switchboard.real.com.
+apps.facebook.com.
+a.root-servers.net.
+121.38.32.46.in-addr.arpa.
+www.google.com.
+129.176.129.186.in-addr.arpa.
+profile.ak.fbcdn.net.
+s-static.ak.facebook.com.
+sofi.ua.
+html.rincondelvago.com.
+i3.ytimg.com.
+storage.conduit.com.
+177.138.141.189.in-addr.arpa.
+a.root-servers.net.
+sc19.rules.mailshell.net.
+omega.ua.
+developers.facebook.com.
+a.root-servers.net.
+normateca.educal.com.mx.
+caldav.calendar.yahoo.com.
+www.americanwhitewater.org.
+i1.nyt.com.
+a.root-servers.net.
+googleads.g.doubleclick.net.
+a.root-servers.net.
+:lvzz93qr.46pf.
+110.254.162.76.in-addr.arpa.
+sjc.ads.nexage.com.
+248.154.104.190.in-addr.arpa.
+195.10.8.95.in-addr.arpa.
+img1.blogblog.com.
+214.16.168.192.in-addr.arpa.
+www.studymalaysia.com.
+www.google.com.
+jesuitswisprov.org.
+.
+ju.edu.
+ghs.l.google.com.
+98.34.97.190.in-addr.arpa.
+fbcdn-profile-a.akamaihd.net.
+mail2.foley2.com.
+cropper.com.
+fxfeeds.mozilla.com.
+verizoni.net.
+www.facebook.com.
+175.64.94.186.in-addr.arpa.
+s.youtube.com.
+et-consulting.ru.
+nl-pic1.ciao.com.
+84.174.85.209.in-addr.arpa.
+th209.photobucket.com.
+166.61.225.76.in-addr.arpa.
+hojuuncontentingness.com.
+securepubads.g.doubleclick.net.
+ads.yimg.com.
+js2.wlxrs.com.
+a.root-servers.net.
+217.221.114.93.in-addr.arpa.
+www.thugmart.com.
+imperiyaavto.ru.
+cux9u3dpp.42qh.
+www.facebook.com.
+q6y9cx9vg.g95j5g3k.
+api-read.facebook.com.
+amer.rel.msn.com.
+zynga1-a.akamaihd.net.
+upload.facebook.com.
+baklanov.msk.ru.
+webcache.googleusercontent.com.
+754866.r.msn.com.
+bigmail-file18.mail.daum.net.
+threw.ru.
+music.darrenlock.com.
+translate.google.com.mx.
+ladolcevitaevents.net.
+www.tattoodownloadz.com.
+fdpinvest.ru.
+www.dontlookbackconcerts.com.
+blufiles.storage.msn.com.
+www.coffeeshrub.com.
+www.caninest.com.
+scholar.google.com.
+rzhrdb.com.
+static.ak.fbcdn.net.
+photos-a.ak.fbcdn.net.
+rcp.na.blackberry.com.
+evintl-ocsp.verisign.com.
+sc2.rules.mailshell.net.
+loading3.widdit.com.
+zonaalfasex.blogspot.com.
+orthoctrsofl.com.
+okwm38xxk.q21f1e6u.
+download343.avast.com.
+www.derrierelacolline.net.
+www.mi6-hq.com.
+www.labcreations.biz.
+www.televisa.com.
+www.ibcrosario.com.ar.
+official-fangoria.disqus.com.
+a.root-servers.net.
+www.hi5.com.
+a.root-servers.net.
+www.martinfowler.com.
+www.putalocura.com.
+a.root-servers.net.
+ttln.com.
+resolver.3.geo.ctmail.com.
+db._dns-sd._udp.0.1.168.192.in-addr.arpa.
+panservice.it.
+api.twitter.com.
+mail.f2.net.
+pr.starmedia.com.
+91.216.101.187.in-addr.arpa.
+a.root-servers.net.
+www.inac.gov.ve.
+media.adxpansion.com.
+sn21.mailshell.net.
+mail.hawaiireserves.com.
+1-live-gs-emhe.6waves.com.
+andor.net.
+mailyam.com.
+api-read.facebook.com.
+114.130.80.84.in-addr.arpa.
+.
+kepa.ru.
+www.thinkyhead.com.
+159.39.61.81.in-addr.arpa.
+jcom.home.ne.jp.
+dr._dns-sd._udp.0.0.168.192.in-addr.arpa.
+static.ak.fbcdn.net.
+files.myopera.com.
+33.72.188.189.in-addr.arpa.
+ws-cloud236-blur.svcmot.com.
+ad.yieldmanager.com.
+myonlyuniverse.blogspot.com.
+www.skyshape.com.
+english-by-phone-admin.com.
+www.joinmyvillage.com.
+img513.imageshack.us.
+accounts.google.com.
+sr.wikipedia.org.
+www.facebook.com.
+ss28:mxx8.n82f3g6e.
+a.root-servers.net.
+71.31.93.189.in-addr.arpa.
+teredo.ipv6.microsoft.com.
+ads.adbrite.com.
+www.cheapukgirls.com.
+ametekaerodefense.com.
+alfordot.com.
+udc.msn.com.
+www.21stcenturydental.com.
+as.py.impact-ad.jp.
+gdyn.hlntv.com.
+www.karlsruhe.de.
+alltrl.net.
+www.youtube.com.
+210.221.132.187.in-addr.arpa.
+www.inlandnewstoday.com.
+static.ak.fbcdn.net.
+investor.power-one.com.
+lrbdvj813.26ax.
+200.109.175.110.in-addr.arpa.
+cyberinsecure.com.
+blacklist.teamspeak.com.
+a4.sphotos.ak.fbcdn.net.
+annita.bligoo.com.
+87.148.59.199.in-addr.arpa.
+taniaraymondefan.com.
+ads.creafi-online-media.com.
+35.89.182.190.in-addr.arpa.
+www.clubdelvento.com.ar.
+235.42.151.68.in-addr.arpa.
+hi-in.facebook.com.
+pixel.facebook.com.
+smtp.hometelco.com.s5b1.psmtp.com.
+static.ak.fbcdn.net.
+mx.dilltech.com.
+a.root-servers.net.
+www.kaba.co.nz.
+19.228.171.69.in-addr.arpa.
+cnfg.montiera.com.
+photos-g.ak.fbcdn.net.
+hot-goods.ru.
+external.ak.fbcdn.net.
+a.root-servers.net.
+a7.sphotos.ak.fbcdn.net.
+unimac.com.
+164.70.215.190.in-addr.arpa.
+sp.cwfservice.net.
+www.gstatic.com.
+126.62.139.75.in-addr.arpa.
+asplundhbpg.com.
+sites.google.com.
+lvtlslxupeptemc.com.
+www.truthtube.tv.
+enough.com.
+docs.google.com.
+photos-g.ak.fbcdn.net.
+d2103737.xoom.it.
+myownlabels.com.
+sp.cwfservice.net.
+10.53.37.83.in-addr.arpa.
+www.tattoologist.com.
+sp.cwfservice.net.
+197.184.149.69.in-addr.arpa.
+www.transparencia.unam.mx.
+static.ak.fbcdn.net.
+a.root-servers.net.
+developers.facebook.com.
+secure-assets.rubiconproject.com.
+www.facebook.com.
+s-static.ak.facebook.com.
+mx.youtube.com.
+78.4.175.94.in-addr.arpa.
+img133.picfoco.com.
+ad.yieldads.com.
+www.bannerflux.com.
+triton.mnet.com.
+201.81.179.90.in-addr.arpa.
+js.wlxrs.com.
+www.adobe.com.
+www.moneysupermarket.com.
+pgcff.pricegong.com.
+s-external.ak.fbcdn.net.
+tc.v7.cache4.c.youtube.com.
+safebrowsing-cache.google.com.
+twitter.com.
+css.wlxrs.com.
+a.root-servers.net.
+jers1.info.
+_636_24_0.
+go.microsoft.com.
+126.190.119.98.in-addr.arpa.
+arabic.hktdc.com.
+incredibots2.com.
+accounts.google.com.
+graph.facebook.com.
+213.146.179.187.in-addr.arpa.
+90.0.75.187.in-addr.arpa.
+12.143.237.189.in-addr.arpa.
+www.nonudeladies.info.
+api.twitter.com.
+www.rudnei.cunha.nom.br.
+www.youtube.com.
+juegos-ultimate-arcade.blogspot.com.
+130.100.160.182.in-addr.arpa.
+mx.fgup.net.
+inbound.reetex.com.netsolmail.net.
+113.3.103.189.in-addr.arpa.
+tampa.holaciudad.com.
+westelcom-mx.messaging.lotuslive.com.
+download.windowsupdate.com.
+wishlist-products.s3.amazonaws.com.
+fbcdn-profile-a.akamaihd.net.
+yadjose.espacioblog.com.
+watershipltd.com.
+a7.sphotos.ak.fbcdn.net.
+www.googleadservices.com.
+120.187.117.68.in-addr.arpa.
+www.facebook.com.
+profile.ak.fbcdn.net.
+www.feedage.net.
+a-0.19-a30f3081.80e0180.1518.19d4.3ea1.410.0.wh8h6hw9qeh8hzi3ulfja7itat.avqs.mcafee.com.
+pop.netaddress.com.
+gchu-ao.foroactivo.net.
+creative.ak.fbcdn.net.
+chim.vrn.ru.
+notify10.dropbox.com.
+widget.alot.com.
+shamrocksportsgroup.com.s8a2.psmtp.com.
+www.downextra.net.
+a4.sphotos.ak.fbcdn.net.
+www.dollandthecity.com.
+71.123.164.79.in-addr.arpa.
+15.123.145.213.in-addr.arpa.
+www.containerhandbuch.de.
+a.root-servers.net.
+24.192.178.190.in-addr.arpa.
+c13.zedo.com.
+profile.ak.fbcdn.net.
+invest.grainger.com.
+116.205.171.201.in-addr.arpa.
+gknholding.com.
+sp.cwfservice.net.
+rocketmail.com.
+1pic1mtb1.p60r1h7e.
+www.gmail.com.
+179.236.144.189.in-addr.arpa.
+www.madmaxmodels.com.
+bhdccudap02.blackhillscorp.com.
+www.siestakeyvacationsrental.com.
+rvlife.net.
+touch.facebook.com.
+api.facebook.com.
+external.ak.fbcdn.net.
+flame.ru.
+jonjulio.tumblr.com.
+a.root-servers.net.
+a.root-servers.net.
+masqueperras.blogspot.com.
+csi.gstatic.com.
+centum.cz.
+carrison.co.uk.
+conduit.anybodyoutthere.com.
+fb-client-0.castle.zynga.com.
+157.147.152.201.in-addr.arpa.
+a.root-servers.net.
+194.68.37.186.in-addr.arpa.
+jet.sao.ru.
+www.gpr.hu.
+ht50.easou.com.
+platform.twitter.com.
+113.169.162.187.in-addr.arpa.
+fonts.googleapis.com.
+pear.php.net.
+14.202.178.186.in-addr.arpa.
+zh-cn.facebook.com.
+www.rtc.com.
+ls2web.redmond.corp.microsoft.com.
+www.plastimo.com.
+schantz.com.
+l.yimg.com.
+api.facebook.com.
+248.225.58.189.in-addr.arpa.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+cmsimg.wausaudailyherald.com.
+ts-transport.ru.
+crochetemoda.blogspot.com.
+4.bp.blogspot.com.
+hantoma.hani.co.kr.
+sovetrector.ru.
+api.conduit.com.
+webcache.googleusercontent.com.
+photos-a.ak.fbcdn.net.
+companion-group.com.
+38.113.14.71.in-addr.arpa.
+computerpoint.net.s8a2.psmtp.com.
+www.toyopumps.com.
+mail.sincol.com.
+130.9.137.82.in-addr.arpa.
+2ah:afnbd.b11r2u1t.
+teredo.ipv6.microsoft.com.
+img260.imagevenue.com.
+s.youtube.com.
+200.37.51.180.in-addr.arpa.
+253.53.36.190.in-addr.arpa.
+145.174.207.190.in-addr.arpa.
+photos-d.ak.fbcdn.net.
+134.176.104.186.in-addr.arpa.
+0-278.channel.facebook.com.
+www.excatholicsforchrist.com.
+calambresabdominales.blogspot.com.
+publishers.org.
+mail-3.readingbody.com.
+photos-a.ak.fbcdn.net.
+a.root-servers.net.
+dtlink.com.br.
+mtalk.google.com.
+aol.com.
+s-static.ak.fbcdn.net.
+api.twitter.com.
+wwwimages.adobe.com.
+sp.ask.com.
+104.158.212.186.in-addr.arpa.
+swift.xobni.com.cdngc.net.
+reconquista.pt.
+about.ask.com.
+s4.histats.com.
+27.211.172.118.in-addr.arpa.
+bing.com.
+profile.ak.fbcdn.net.
+www.facebook.com.
+southern-container.com.
+mail.chokseychem.com.
+d1j68ux4ukg4g1.cloudfront.net.
+220.92.80.2.in-addr.arpa.
+sp.cwfservice.net.
+51.12.39.114.in-addr.arpa.
+careagemanagement.com.inbound10.mxlogicmx.net.
+ntp1.dlink.com.
+mxtreme1.bob.fi.
+from-the-mountains.com.
+rim.trapis.net.
+aocuoikhanhlinh.vn.
+www.provocativebabes.com.
+cdn.turn.com.
+download.windowsupdate.com.
+mail.youngnoel.com.
+lo5ssmq3z.35eo.
+photos-g.ak.fbcdn.net.
+www.procostas.org.
+privcomm.com.
+resudox.net.1.0001.arsmtp.com.
+external.ak.fbcdn.net.
+es-es.facebook.com.
+data.flurry.com.
+smtpjp.lvmh-group.com.
+www.yyhworld.com.
+mail1.hella.com.
+www.awmads.com.
+www.kissthatsound.com.
+m.webtrends.com.
+texasdebrazil.fbmta.com.
+google.com.
+sp.cwfservice.net.
+midlandsco-op.com.
+9.rarbg.com.
+www.reuters.com.
+www.google.com.
+ms-max.ru.
+cs11168.vkontakte.ru.
+www.brent.gov.uk.
+m.asu.edu.
+www.lantern-festival.com.
+23.187.36.190.in-addr.arpa.
+www.urljet.com.
+v8.cache2.c.youtube.com.
+www.stumbleupon.com.
+morelandassoc.com.
+www.truckertotrucker.com.
+247.65.222.189.in-addr.arpa.
+profile.ak.fbcdn.net.
+199.162.226.189.in-addr.arpa.
+static.linkbucks.com.
+sabre.tomlin.yahoo.com.
+67.106.255.77.in-addr.arpa.
+pagead2.googlesyndication.com.
+30.205.89.173.in-addr.arpa.
+www.arte-y-plata.com.
+culinaryschools.ru.
+covemotoring.com.
+mail.yoowalk.com.
+proposal.com.
+s-static.ak.fbcdn.net.
+nzgiexyo8.79io.
+a.root-servers.net.
+a4.sphotos.ak.fbcdn.net.
+nokia.com.
+profile.ak.fbcdn.net.
+www.tumblr.com.
+www.astrocentral.co.uk.
+156.235.29.86.zz.countries.nerd.dk.
+teredo.ipv6.microsoft.com.
+www.sqm.microsoft.com.
+www.seagate.com.
+drjohn2020.com.
+urs.microsoft.com.
+teredo.ipv6.microsoft.com.
+crashlog.whatsapp.net.
+moca.org.
+a997.mm1.akamai.net.
+77.152.132.187.in-addr.arpa.
+a.root-servers.net.
+malah.biz.
+www.animeplanet1000.blogspot.com.
+rotfl.com.
+23.214.192.66.in-addr.arpa.
+www.ebonyfacial.net.
+90.102.53.186.in-addr.arpa.
+95.253.36.184.in-addr.arpa.
+dns.carnainfo.com.br.
+voipb.sip.yahoo.com.
+www.verfutbolonline.net.
+37.24.100.85.in-addr.arpa.
+tags.bluekai.com.
+1.201.173.190.in-addr.arpa.
+secure-us.imrworldwide.com.
+www.assa.edu.au.
+a.root-servers.net.
+photos-g.ak.fbcdn.net.
+dns.msftncsi.com.
+www.plics.net.
+www.ademails.com.
+pic.srv104.wapedia.mobi.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+iamronel.com.
+ns1.freewebship.net.
+espanol.wunderground.com.
+api.conduit.com.
+a.root-servers.net.
+hpp.orange.fr.
+acpo.org.
+rosieflores.com.
+a.root-servers.net.
+40.29.100.190.in-addr.arpa.
+cdn.ad4game.com.
+2.150.218.186.in-addr.arpa.
+mac1.no.
+bs.serving-sys.com.
+lys.org.
+39.225.48.190.in-addr.arpa.
+cdn1.certified-apps.com.
+a4.sphotos.ak.fbcdn.net.
+skydrive.live.com.
+10.192.188.186.in-addr.arpa.
+mpcstatic.com.
+www.corporate-impressum.com.
+host71.123flashchat.com.
+a.root-servers.net.
+google.com.
+ksn3-11.part2.kaspersky-labs.com.
+mail.roosevelt.k12.tx.us.
+papercraftparadise.blogspot.com.
+www.noroeste.com.mx.
+moviecities.com.
+167.224.181.72.in-addr.arpa.
+www.googleadservices.com.
+gmail.com.
+88.252.178.186.in-addr.arpa.
+hi-in.facebook.com.
+95.72.14.186.in-addr.arpa.
+poodlesarepeople.com.
+42.92.19.201.in-addr.arpa.
+www.google.com.
+free.fr.dnsbl7.mailshell.net.
+224.43.191.190.in-addr.arpa.
+edge.quantserve.com.
+www.chinuka.com.
+www.youtube.com.
+cust14266-1.in.mailcontrol.com.
+apps.facebook.com.
+www.google.com.
+profile.ak.fbcdn.net.
+google.com.
+www.villa-bisono.com.
+itunes.apple.com.
+e4967.g.akamaiedge.net.
+a6.sphotos.ak.fbcdn.net.
+ten-arquitectos.com.s8a1.psmtp.com.
+mailrelay.harrisburgnewsco.com.
+espanol.answers.yahoo.com.
+linksys-con10.url.trendmicro.com.
+ieonlinews.microsoft.com.
+224.49.66.186.in-addr.arpa.
+www.youtube.com.
+_715_42_7.
+zh-cn.facebook.com.
+messenger.hotmail.com.
+s12.last.fm.
+web.haceb.com.
+a2.sphotos.ak.fbcdn.net.
+api2.4shared.com.
+www.bundarika.com.
+txla.org.
+ut2.xhamster.com.
+32.226.79.190.in-addr.arpa.
+142.31.245.189.in-addr.arpa.
+imagenes.es.sftcdn.net.
+www.youtube.com.
+sp.cwfservice.net.
+static.girlgames4u.com.
+photos-f.ak.fbcdn.net.
+www.izleyivergari.info.
+prhospital.com.
+plus.google.com.
+www.eldiariomontanes.es.
+api.facebook.com.
+pagead2.googlesyndication.com.
+discovision.com.s9a1.psmtp.com.
+chmail.ru.
+uu1.orbitdownloader.com.
+a2.sphotos.ak.fbcdn.net.
+vpn.su.
+sites.google.com.
+www.fxfisherman.com.
+_608_72_5.
+grandviewlodge.com.
+s.youtube.com.
+a.root-servers.net.
+cm.ac3.msn.com.
+translate.google.com.mx.
+www.woodgundy.com.
+www.g999g.com.
+school.moodlemoot.com.au.
+l52bfy8l1.94me.
+www.riaupos.co.
+theparkdowntown.com.
+ad.ad-srv.net.
+dynamoelectronics.blogspot.com.
+serecon.ca.
+diamondcertified.org.
+www.corel.com.
+museumca.org.
+msntest.serving-sys.com.
+cplus.about.com.
+a4.sphotos.ak.fbcdn.net.
+developers.facebook.com.
+www.google-analytics.com.
+www.myfamily.com.
+andsewitgoes.blogspot.com.
+baboolercheme.org.
+photos-c.ak.fbcdn.net.
+a.root-servers.net.
+widgets.amung.us.
+a4.sphotos.ak.fbcdn.net.
+www.google.com.
+www.uac.pt.
+114.117.156.187.in-addr.arpa.
+photos-f.ak.fbcdn.net.
+3.bp.blogspot.com.
+ads2.contentabc.com.
+239.84.139.189.in-addr.arpa.
+pixel.facebook.com.
+swf.fizzgame.com.
+mail.shm.ru.
+www.fairouz.com.
+130.16.250.189.in-addr.arpa.
+firsterotica.com.
+ib.adnxs.com.
+247.207.73.69.in-addr.arpa.
+60.66.64.186.in-addr.arpa.
+www.facebook.com.
+116.144.138.201.in-addr.arpa.
+s5.mogujie.cn.
+c7.zedo.com.
+246.134.0.186.in-addr.arpa.
+newsaxon.org.
+a7.sphotos.ak.fbcdn.net.
+nesk2fgrx.73ru.
+ele.aut.ac.ir.
+www-cctld.l.google.com.
+www.stretcher.com.
+_887_71_6.
+cdn4.digitaltrends.com.
+pl.wikipedia.org.
+crl.microsoft.com.
+ssl.gstatic.com.
+col.stb00.s-msn.com.
+213.125.153.189.in-addr.arpa.
+c.prodigy.msn.com.
+www.oldwayspt.org.
+195.174.39.60.in-addr.arpa.
+www.registry.in.
+onestopfunny.com.
+css.wlxrs.com.
+noticias.latam.msn.com.
+www.voayeurs.com.
+displayworks.com.s7b1.psmtp.com.
+caracteres.wordpress.com.
+121.185.215.108.in-addr.arpa.
+api.connect.facebook.com.
+sulzer.com.s201a1.psmtp.com.
+cherkessk.ru.
+www.siaccss.com.
+www.tvacres.com.
+adserver.adtechus.com.
+teredo.ipv6.microsoft.com.
+ondetroitmi.com.
+231.42.234.189.in-addr.arpa.
+www.facebook.com.
+www.playdojam.com.
+olshtyn.ru.
+74.124.163.46.in-addr.arpa.
+aka-cdn-ns.adtechus.com.
+27.media.tumblr.com.
+s-static.ak.facebook.com.
+cfisco.com.
+en.wikipedia.org.
+pagead2.googlesyndication.com.
+banners.iminent.com.
+googleads.g.doubleclick.net.
+bit.ly.
+www.tutiempo.net.
+i2.ytimg.com.
+www.gstatic.com.
+seinur.info.
+www.sexoflover.com.
+developers.facebook.com.
+bsvst.ru.
+google.com.
+clients1.google.com.
+dr._dns-sd._udp.lan.
+privacy2.msn.com.
+pagead2.googlesyndication.com.
+teredo.ipv6.microsoft.com.
+ping.chartbeat.net.
+fbcdn-profile-a.akamaihd.net.
+apmc.net.s10b1.psmtp.com.
+121.253.84.200.in-addr.arpa.
+si-tx.com.s7b2.psmtp.com.
+a.root-servers.net.
+apix.iminent.com.
+a8.sphotos.ak.fbcdn.net.
+downbytheriverbank.blogspot.com.
+kb-law.com.s8a2.psmtp.com.
+safebrowsing-cache.google.com.
+creative.ak.fbcdn.net.
+relestar.com.
+hotmail.com.
+199.1.130.79.in-addr.arpa.
+a2.sphotos.ak.fbcdn.net.
+aidps.atdmt.com.
+connect.facebook.net.
+www.jesusferrer.es.
+b.scorecardresearch.com.
+35.237.51.190.in-addr.arpa.
+p03-streams.icloud.com.
+baileycompany.com.
+developers.facebook.com.
+_122_26_3.
+mail.starband.com.
+kiev.unian.net.
+lkayrnosi.n79w7f1n.
+platform.twitter.com.
+gbjha.zeneca.com.
+www.google.com.
+infogen.com.
+www.quicksupply.net.
+hotwater.build.com.au.
+203.175.206.200.in-addr.arpa.
+a.root-servers.net.
+twimg0-a.akamaihd.net.
+api.twitter.com.
+234.254.200.190.in-addr.arpa.
+photos-g.ak.fbcdn.net.
+www.google.com.
+193.96.129.217.in-addr.arpa.
+translate.google.com.mx.
+jacuzzi.vidz.com.
+cn1.redswoosh.akadns.net.
+a6.sphotos.ak.fbcdn.net.
+www2.dca.ca.gov.
+www.star-advertising.com.
+html.atm.youku.com.
+www.ihrdc.com.
+b._dns-sd._udp.0.1.168.192.in-addr.arpa.
+a.root-servers.net.
+68.11.168.192.in-addr.arpa.
+a.root-servers.net.
+a8.sphotos.ak.fbcdn.net.
+a.root-servers.net.
+ads.bluelithium.com.
+pixel.facebook.com.
+tc21.easythumbhost.com.
+www.eluniversal.com.mx.
+25.15.206.41.in-addr.arpa.
+lunarstuff.com.
+haapavesi.fi.
+photos-a.ak.fbcdn.net.
+_002_80_1.
+119.49.11.189.in-addr.arpa.
+xk18zs87c.14rh.
+zahduc34k.64kr.
+58.111.79.201.in-addr.arpa.
+content.xbox.com.edgesuite.net.
+api-read.facebook.com.
+216.86.251.190.in-addr.arpa.
+a5.sphotos.ak.fbcdn.net.
+125.240.56.66.in-addr.arpa.
+ksn2-12.kaspersky-labs.com.
+p.jango.com.
+secure.wlxrs.com.
+www.retratech.ca.
+mahindra.co.za.
+mail.spindlereng.com.
+89.252.166.189.in-addr.arpa.
+static.ak.fbcdn.net.
+www.andrewlab.com.
+www.ciol.com.
+gaztekinzale.wordpress.com.
+time.chttl.com.tw.
+40.1.101.190.in-addr.arpa.
+a5.sphotos.ak.fbcdn.net.
+166.60.229.189.in-addr.arpa.
+1.11.71.187.in-addr.arpa.
+a13.t26.net.
+iphone.facebook.com.
+stox.ru.
+api.twitter.com.
+gw.home.vix.com.
+playerservices.streamtheworld.com.
+a.root-servers.net.
+mail2.investural.ru.
+crossfit-gyms.com.
+koenigscale.com.mail7.psmtp.com.
+clients1.google.com.
+www.abstractmath.org.
+fbcdn-photos-a.akamaihd.net.
+lasco.costeel.com.
+www.tequesquitengo.org.mx.
+mail.gas12.ru.
+fbcdn-sphotos-a.akamaihd.net.
+s815.photobucket.com.
+www.gamefaqs.com.
+a.root-servers.net.
+z-ecx.images-amazon.com.
+bit.ly.
+www.cat-barcelona.com.
+voipa.sip.yahoo.com.
+www.top10series.com.
+exhiberexpo.ru.
+lbcore1.metacafe.com.
+buchete-mireasa.ro.
+124.99.171.78.in-addr.arpa.
+creative.ak.fbcdn.net.
+151.25.253.189.in-addr.arpa.
+a3.twimg.com.
+googleads.g.doubleclick.net.
+gcsd.global.sonicwall.com.
+180.80.81.201.in-addr.arpa.
+190.49.178.78.in-addr.arpa.
+www.spacesoundrecords.com.
+fiteyes.com.
+202.196.70.86.in-addr.arpa.
+alternativaslibres.mcye.misiones.gov.ar.
+228.154.108.114.in-addr.arpa.
+161.148.194.190.in-addr.arpa.
+atspam.atproperties.com.
+www.aveev.org.
+djesibonajeb.com.
+rediffmail.com.
+cobaltemail.com.
+202.211.118.190.in-addr.arpa.
+www.nshamabagdad.com.
+206.71.0.71.in-addr.arpa.
+metrics.nokia.com.
+creative.ak.fbcdn.net.
+rcp.na.blackberry.com.
+94.140.227.190.in-addr.arpa.
+time-nw.nist.gov.
+fbcdn-sphotos-a.akamaihd.net.
+mail.pesd.k12.wi.us.
+static.ak.fbcdn.net.
+www.ironcreek.net.
+external.ak.fbcdn.net.
+rocketfuel.com.
+profile.ak.fbcdn.net.
+126.196.155.93.in-addr.arpa.
+www.google.com.
+126.162.217.196.in-addr.arpa.
+t7.tagstat.com.
+www1.plumpestgrannies.com.
+www.luxurybeachresorts.com.mx.
+photos-f.ak.fbcdn.net.
+cdchww3gm.56bf.
+cdn.zeusclicks.com.
+fbcdn-profile-a.akamaihd.net.
+a.root-servers.net.
+evaysuserpientes.blogspot.com.
+a.root-servers.net.
+ebarasolar.com.
+abooking.net.
+asdlabs.com.
+facebookhackingcourse.com.
+baseavalancha.mforos.com.
+podcast.gcnlive.com.
+taxpro.hrblock.com.
+88.92.196.216.in-addr.arpa.
+holatu.com.
+universal-document-converter-win.softonic.com.
+service-public.fr.
+profile.ak.fbcdn.net.
+google.com.
+9q9vf:hom.n29j4k0y.
+138.58.235.201.in-addr.arpa.
+16.59.44.129.in-addr.arpa.
+109.59.0.27.in-addr.arpa.
+abc.volga.ru.
+74.194.66.201.in-addr.arpa.
+103.118.11.190.in-addr.arpa.
+b5e:e98u8.w52x0e3l.
+www.bakers.co.uk.
+.
+www.maserati.com.
+mediacdn.disqus.com.
+a7.sphotos.ak.fbcdn.net.
+i2.ytimg.com.
+mx2.kennemergroup.com.
+anmagroup.com.
+tracker.publicbt.com.
+nl0105dom26.fea.slb.com.
+a5.sphotos.ak.fbcdn.net.
+api.twitter.com.
+www.espacio15.com.
+universat.com.
+213.56.47.189.in-addr.arpa.
+api-read.facebook.com.
+m.facebook.com.
+mnademexico.com.
+ksn2.kaspersky-labs.com.
+belrus.kuban.ru.
+103.180.182.189.in-addr.arpa.
+mail.midwestrespiratory.com.
+apps.facebook.com.
+a1725.l.akamai.net.
+bs.serving-sys.com.
+108.248.41.175.in-addr.arpa.
+safebrowsing.clients.google.com.
+quepiensaeltercerhombre.blogspot.com.
+17.168.50.190.in-addr.arpa.
+speed.cd.
+rad.msn.com.
+.
+110.249.226.76.in-addr.arpa.
+planet.wordpress.org.
+www.heterodoxos.org.
+a.root-servers.net.
+ax.su.itunes.apple.com.
+123.203.140.79.in-addr.arpa.
+a4.da1.akamai.net.
+www.bywifi.com.
+rcm.org.uk.
+trailw.dealply.com.
+unica.com.br.
+apple.com.
+58.244.165.190.in-addr.arpa.
+elobservadorsarcastico.blogspot.com.
+a4.da1.akamai.net.
+a.root-servers.net.
+salud-solobuenasnoticias.blogspot.com.
+_560_76_2.
+www.voodootonic.com.
+descargas.juegos.com.
+104.224.194.58.in-addr.arpa.
+shahid.mbc.net.
+www.ihstar.com.
+plus.google.com.
+205.135.141.118.in-addr.arpa.
+newsrss.bbc.co.uk.
+img187.imageshack.us.
+photos-h.ak.fbcdn.net.
+29-courier.push.apple.com.
+157.206.230.190.in-addr.arpa.
+212.44.83.78.in-addr.arpa.
+rostplastik.ru.
+static.ak.fbcdn.net.
+fbcdn-profile-a.akamaihd.net.
+developers.facebook.com.
+image-school.ru.
+shoemanic.com.
+conduit.anybodyoutthere.com.
+t3.gstatic.com.
+escueladefotografia.blogspot.com.
+lexha.org.
+support.google.com.
+246.73.88.74.in-addr.arpa.
+ad.yieldmanager.com.
+146.117.144.201.in-addr.arpa.
+metafisica.galeon.com.
+b.scorecardresearch.com.
+waterpas.com.
+.
+platform.ak.fbcdn.net.
+plusone.google.com.
+ptpc.com.
+.
+www.youtube.com.
+developers.facebook.com.
+simple.wikipedia.org.
+labhut.com.
+a6.sphotos.ak.fbcdn.net.
+ar-ar.facebook.com.
+www.bible.cc.
+static.ak.fbcdn.net.
+nycap.rr.com.
+zynga2-a.akamaihd.net.
+a.root-servers.net.
+ad-g.doubleclick.net.
+88.108.56.200.in-addr.arpa.
+dnjnet.com.
+www.anka.com.
+osobnyak.ru.
+translate.google.com.mx.
+statcounter.com.
+graph.facebook.com.
+cuautitlanizcalli.olx.com.mx.
+join.thecrossdressers.com.
+ignaciogalvez.com.
+flaq4b4te.69il.
+www.adobe.com.
+sthelaz.blogspot.com.
+aunicom.ru.
+static.ak.fbcdn.net.
+www.facebook.com.
+db._dns-sd._udp.0.1.168.192.in-addr.arpa.
+mail.knijnenburgbeheer.nl.
+a4.sphotos.ak.fbcdn.net.
+i299.photobucket.com.
+crashmania.net.
+22.39.96.184.in-addr.arpa.
+db._dns-sd._udp.0.1.168.192.in-addr.arpa.
+www.bligoo.com.
+www.showtime.jp.
+www.asefapi.es.
+tile.openstreetmap.org.
+ssl.google-analytics.com.
+www.mfa.gov.eg.
+photos-a.ak.fbcdn.net.
+psikolokospucp.blogspot.es.
+ksn1-11-part1.kaspersky-labs.com.
+117.91.68.189.in-addr.arpa.
+ad.yieldmanager.com.
+beautypageantnews.com.
+dns.msftncsi.com.
+diverticulitis.org.uk.
+bestvalueinn-lethbridge.com.
+checkip.dyndns.com.
+relay2.ncc.co.za.
+ukeas.com.tw.
+www.msftncsi.com.
+platform.ak.fbcdn.net.
+porchsyndicate.com.
+it-it.facebook.com.
+www.blancasexxx.com.
+ares.uptodown.com.
+banners.iminent.com.
+apps.facebook.com.
+cartermcrae.com.
+profile.ak.fbcdn.net.
+a1.sphotos.ak.fbcdn.net.
+simssoc.game.playfish.com.
+valleymeat.com.
+landscapearchitectureresource.com.
+db.darthhater.com.
+1.0.0.127.dnsbugtest.1.0.0.127.in-addr.arpa.
+mail2.gratefulpalate.com.
+151.237.236.189.in-addr.arpa.
+static.ak.fbcdn.net.
+www.facebook.com.
+www.germanbitch.de.
+photos-g.ak.fbcdn.net.
+www.portableworld.ru.
+www.youtube.com.
+photos-b.ak.fbcdn.net.
+api.facebook.com.
+a.root-servers.net.
+195.26.90.186.in-addr.arpa.
+mozilla-firefox.soft32.com.
+www.songwritersfestival.com.
+www.facebook.com.
+cdn.spotxchange.com.
+d.f.2.c.e.3.5.b.1.c.d.1.c.2.8.3.6.7.e.9.7.3.1.4.0.0.0.0.1.0.0.2.ip6.arpa.
+fashion.allwomenstalk.com.
+www.despertardetamaulipas.com.
+psgw.t-mobilesgws.com.
+a.root-servers.net.
+clubblockpost.ru.
+a.root-servers.net.
+public.liss.slidesharecdn.com.
+s.youtube.com.
+google.com.
+www.facebook.com.
+mail34.mimecast.co.za.
+archives1.twoplustwo.com.
+242.28.235.190.in-addr.arpa.
+75.192.141.190.in-addr.arpa.
+ad.yieldmanager.com.
+s.ytimg.com.
+www.vividforfree.com.
+a0.twimg.com.
+paragraphinc.com.
+homeaway.com.122.2o7.net.
+a7.sphotos.ak.fbcdn.net.
+ns1.easydns.com.
+rcp.eu.blackberry.com.
+d3j5vwomefv46c.cloudfront.net.
+sfilter.celizion.com.
+a.analytics.yahoo.com.
+www.girlsofheaven.com.
+sc2.rules.mailshell.net.
+v5.cache2.c.bigcache.googleapis.com.
+teredo.ipv6.microsoft.com.
+swisstab.be.
+hcxd88nly.11nx.
+142.31.130.41.in-addr.arpa.
+pagead2.googlesyndication.com.
+groups.google.com.mx.
+platform.twitter.com.
+novatube.com.
+www.google-analytics.com.
+www.macitynet.it.
+187.242.25.201.in-addr.arpa.
+ssl.gstatic.com.
+107.230.141.189.in-addr.arpa.
+www.kaspersky.com.
+profile.ak.fbcdn.net.
+lcucr.com.
+www.yahoo.com.
+touch.facebook.com.
+plusone.google.com.
+181.209.79.190.in-addr.arpa.
+nv68eht68.v88e7t3a.
+www.juegosbmxgratis.com.
+159.207.245.190.in-addr.arpa.
+dollar.uaportal.com.
+farm6.staticflickr.com.
+img2.mlstatic.com.
+fbcdn-profile-a.akamaihd.net.
+db._dns-sd._udp.0.1.168.192.in-addr.arpa.
+99.81.54.65.in-addr.arpa.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+.
+smtpin.tdc.dk.
+42.127.199.76.in-addr.arpa.
+a.root-servers.net.
+204.1.168.192.in-addr.arpa.
+130.40.212.178.in-addr.arpa.
+s.ytimg.com.
+m.xp1.ru4.com.
+mail.tortnadom.ru.
+35.187.53.187.in-addr.arpa.
+v12.nonxt5.c.youtube.com.
+a.root-servers.net.
+csi.gstatic.com.
+ssl.google-analytics.com.
+www.jorditorre.com.
+_803_79_8.
+www9.effectivemeasure.net.
+sugiur.com.
+pixel.fetchback.com.
+mail.elliron.com.
+www.uach.cl.
+224.111.129.125.in-addr.arpa.
+www.tierradesoldados.com.
+mail.google.com.
+photos-b.ak.fbcdn.net.
+y:2bwibln.32cc.
+el-real-blog.blogspot.com.
+egal.com.
+1.85.19.186.in-addr.arpa.
+232.178.219.194.in-addr.arpa.
+www.herosmash.com.
+t.co.
+kred.com.
+ksn2-12.kaspersky-labs.com.
+a.root-servers.net.
+library.karelia.ru.
+a5.sphotos.ak.fbcdn.net.
+a.root-servers.net.
+_229_73_2.
+www.dnanow.com.
+dc153.4shared.com.
+mobilelinuxinfo.com.
+138.253.168.192.in-addr.arpa.
+a.root-servers.net.
+9.138.122.187.in-addr.arpa.
+view.atdmt.com.
+relay.uep-cd.ru.
+google.com.
+www.bridgeguys.com.
+a.root-servers.net.
+21.180.35.177.in-addr.arpa.
+inbound.anchorsubaru.com.netsolmail.net.
+mail.sites-sw.com.
+baltimore.orioles.mlb.com.
+apps.facebook.com.
+time.chttl.com.tw.
+external.ak.fbcdn.net.
+92.253.250.201.in-addr.arpa.
+thumbs4.ebaystatic.com.
+105.165.151.85.in-addr.arpa.
+a5.sphotos.ak.fbcdn.net.
+dr._dns-sd._udp.lan.
+u.dd341c002d6d86bd.com.
+dns.msftncsi.com.
+trilliumcos.com.
+ssl.gstatic.com.
+www.youtube.com.
+ads2.msads.net.
+photos-g.ak.fbcdn.net.
+gekgo.com.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+photos-g.ak.fbcdn.net.
+static.ak.fbcdn.net.
+bisd.com.
+baggio.com.ar.
+webcache.googleusercontent.com.
+177.99.0.190.in-addr.arpa.
+dns.msftncsi.com.
+iiseutu.fi.
+noticias.es.msn.com.
+lighthousebaptist.com.1.arsmtp.com.
+teredo.ipv6.microsoft.com.
+d7.zedo.com.
+www.karritos.mx.
+www.surgjournal.com.
+pixel.facebook.com.
+i2.ytimg.com.
+creative.ak.fbcdn.net.
+cow_fb_cdn0-a.akamaihd.net.
+200.143.131.187.in-addr.arpa.
+d2092717.xoom.it.
+data.flurry.com.
+192.143.19.95.in-addr.arpa.
+cdn5-0.quizapps.com.
+243.46.112.186.in-addr.arpa.
+36.182.218.193.in-addr.arpa.
+138.140.225.77.in-addr.arpa.
+photos-a.ak.fbcdn.net.
+157.29.180.69.in-addr.arpa.
+onlinux-fr.setupdns.net.
+www.amazon.com.
+izone.com.
+creative.ak.fbcdn.net.
+mail.roughbros.com.
+s1-powerpoint.vo.msecnd.net.
+kakputin.ru.
+58.68.171.201.in-addr.arpa.
+cdn.search.sweetim.com.
+ssl.gstatic.com.
+mail.stroisouz.ru.
+nhdayton.com.2.arsmtp.com.
+es.house.wikia.com.
+www.newbackdoor.com.
+wallstreetmtg.com.
+www.mancoraperu.com.
+systor.com.
+windsor.olx.ca.
+russianet.ru.
+43.76.37.46.in-addr.arpa.
+mvz.berkeley.edu.
+accounts.google.com.
+iasishealth.com.
+www.britishcolumbia.name.
+www.ringtonematcher.com.
+243.60.27.72.in-addr.arpa.
+pagead2.googlesyndication.com.
+mall.shinsegae.com.
+alhena3.blogspot.com.
+www.healthplanspain.com.
+146.16.76.184.in-addr.arpa.
+bloomstudio.ru.
+hackneycitizen.co.uk.
+a.triggit.com.
+14392e5a.linkbucks.com.
+invproj.ru.
+www.youtube.com.
+bestamateurland.com.
+248.91.173.190.in-addr.arpa.
+i2.ytimg.com.
+nationalholidays24.com.
+245.207.21.190.in-addr.arpa.
+s-static.ak.fbcdn.net.
+www.gamefaqs.com.
+tracker.ccc.de.
+es-la.facebook.com.
+profile.ak.fbcdn.net.
+www.aircleaners.com.
+ing-serv.ru.
+external.ak.fbcdn.net.
+fbcdn-photos-a.akamaihd.net.
+www.lesbianas.us.
+234.153.203.201.in-addr.arpa.
+pingoat.com.
+69.33.161.187.in-addr.arpa.
+www.kirkdunne.com.
+mail.midcomp.com.
+157.18.144.186.in-addr.arpa.
+ardeacap.com.
+www.alwaraq.net.
+us-w1.rockmelt.com.
+addvalue.com.
+a.root-servers.net.
+i3.imlive.com.
+a.root-servers.net.
+safebrowsing.clients.google.com.
+mountaincement.com.mail9.psmtp.com.
+www.yajuegos.com.
+eabka.info.company.com.
+pics.gallery.weddingbee.com.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+mbmo-online.ru.
+fam.gigabox.info.
+123.231.248.182.in-addr.arpa.
+www.chacovende.com.
+www.crazymikesapps.com.
+a4.sphotos.ak.fbcdn.net.
+imageseu.fewo-direkt.de.
+icons.cubics.com.
+www.google-analytics.com.
+138.45.59.186.in-addr.arpa.
+www.tuenti.com.
+a.root-servers.net.
+s.youtube.com.
+sp.cwfservice.net.
+mediostransporte.blogspot.com.
+madhouse110.fsnet.co.uk.
+ajax.googleapis.com.
+mail.vikingsoutheast.com.
+a8.sphotos.ak.fbcdn.net.
+ssl.gstatic.com.
+mail2.provcorp.com.
+proactusa.com.inbound15.mxlogic.net.
+mx.siberia-zeo.ru.
+assets.zestadz.com.
+t5.tagstat.com.
+i4.ytimg.com.
+a1125.phobos.apple.com.
+vistamfg.com.inbound10.mxlogic.net.
+pixel.facebook.com.
+44.115.125.186.in-addr.arpa.
+g.live.com.
+i-cdn.servedbyopenx.com.
+172.38.251.189.in-addr.arpa.
+www.alanbaxteronline.com.
+_199_49_2.
+mx5.perusion.com.
+mysticsaint.blogspot.com.
+youtu.be.
+14.190.98.62.in-addr.arpa.
+jensen.mail.dk.
+d2089619.xoom.it.
+.
+dns.msftncsi.com.
+tienda.levante-emv.es.
+1.bp.blogspot.com.
+www.google-analytics.com.
+www.apps4rent.com.
+mail.secnrs.ru.
+wastewater.ru.
+www.youtube.com.
+gameplay.mochimedia.com.home.
+www.killersofeden.com.
+dns.msftncsi.com.
+platform.ak.fbcdn.net.
+s-external.ak.fbcdn.net.
+usage.hosting.toolbar.conduit-services.com.
+watson.microsoft.com.
+avillage.web.virginia.edu.
+www.blogspottemplate.com.
+122.18.122.189.in-addr.arpa.
+191.230.21.187.in-addr.arpa.
+mail.doverphila.com.
+a3.sphotos.ak.fbcdn.net.
+smtp.alfredstate.edu.
+0.11-2300a008.e1032.1518.19d4.3ea1.410.0.kjzwb3lh5n28ezha8i1alrbphq.avqs.mcafee.com.
+i3.ytimg.com.
+c5x4h.dyndns.org.
+proxy.ncc.nnov.ru.
+52.17.156.189.in-addr.arpa.
+a-m-b-i-v-a-l-e-n-c-e.tumblr.com.
+check4.facebook.com.
+static.a.gs-cdn.net.
+gsi.pl.
+weather.services.conduit.com.
+www.soapoperadigest.com.
+m.facebook.com.
+m.addthisedge.com.
+s-static.ak.facebook.com.
+se8od84j5.m34g8u4u.
+s.skimresources.com.
+www.reit.com.
+www.facebook.com.
+28.239.215.201.in-addr.arpa.
+www.usasexguide.info.
+174.37.211.201.in-addr.arpa.
+62.239.66.199.in-addr.arpa.
+h.live.com.
+ad.yieldmanager.com.
+97.188.138.201.in-addr.arpa.
+www.facebook.com.
+phissc6mj.j68r1u3w.
+smtpx2.fpcusa.com.
+a3.sphotos.ak.fbcdn.net.
+modavestidos.es.
+49.204.139.187.in-addr.arpa.
+72.11.231.189.in-addr.arpa.
+r._dns-sd._udp.0.55.211.10.in-addr.arpa.
+115.54.1.190.in-addr.arpa.
+234.62.51.170.in-addr.arpa.
+101.206.42.181.in-addr.arpa.
+54.59.105.190.in-addr.arpa.
+pixel.invitemedia.com.
+mvusd.net.
+i1.ytimg.com.
+a.root-servers.net.
+video.google.com.mx.
+63.170.23.79.in-addr.arpa.
+photos-a.ak.fbcdn.net.
+a6.sphotos.ak.fbcdn.net.
+hotmail.com.
+centennialwireless.com.
+bbcore.cloudapp.net.
+www.thekyotoconnection.com.
+www.revodvr.com.
+www.wrangler.com.
+distilleryimage2.s3.amazonaws.com.
+www.facebook.com.
+a3.sphotos.ak.fbcdn.net.
+dns.msftncsi.com.
+ntp.glb.nist.gov.
+portales.puj.edu.co.
+fkepygflaoh.ws.
+balas-celebs.com.
+223.183.78.186.in-addr.arpa.
+a.root-servers.net.
+galagans.com.
+www.elgrancatador.com.
+download.mozilla.org.
+rad.msn.com.
+ayuban.com.
+a.root-servers.net.
+kasut.net.
+172.121.157.69.in-addr.arpa.
+fbcdn-sphotos-a.akamaihd.net.
+52.106.2.42.in-addr.arpa.
+a.mx.icetalk.com.
+rucrj4p4u.85rp.
+external.ak.fbcdn.net.
+photos-e.ak.fbcdn.net.
+somosmovies.disqus.com.
+api.geo.kontagent.net.
+sp.cwfservice.net.
+www.kt2syggf436dtag106.com.
+cont-dc6-2.pandora.com.
+www.facebook.com.
+api.twitter.com.
+www.google-analytics.com.
+www.timwe.com.
+jobs.cgsociety.org.
+safebrowsing.clients.google.com.
+a8.sphotos.ak.fbcdn.net.
+www.poikosoft.com.
+sbcglobel.net.
+www.pagerank.si.
+profile.ak.fbcdn.net.
+3ba1f48a4b3e87fbdcea52325266e210.info.
+www.courts.state.hi.us.
+124.176.21.115.in-addr.arpa.
+static.xvideos.com.
+www.eyedocs.co.uk.
+trc-tempe.com.
+googleads.g.doubleclick.net.
+86.238.117.208.in-addr.arpa.
+35.110.111.109.in-addr.arpa.
+a.root-servers.net.
+229.109.138.69.in-addr.arpa.
+wap.jamster.com.
+www.facebook.com.
+ipeinc.com.
+51.14.236.201.in-addr.arpa.
+195.214.186.189.in-addr.arpa.
+fbcdn-photos-a.akamaihd.net.
+saturnkmv.ru.
+40.12.198.187.in-addr.arpa.
+instagram.com.
+www.viki.net.
+168.90.55.65.sbl-xbl.spamhaus.org.
+www.wiworks.com.
+click.infospace.com.
+us.bc.yahoo.com.
+a6.sphotos.ak.fbcdn.net.
+fbcdn-profile-a.akamaihd.net.
+es-la.facebook.com.
+203.241.60.125.in-addr.arpa.
+photos-d.ak.fbcdn.net.
+303.gt2.vkadre.ru.
+www.ekospor.com.
+naia-design.com.
+estaticos02.marcaplayer.com.
+liveupdate.symantecliveupdate.com.
+www.whitesmoke.com.
+cs11445.vk.com.
+www.netflix.com.
+photos-h.ak.fbcdn.net.
+9dkl1xkjk.u44o7m3c.
+www.kare11.com.
+www.massmediamail.com.
+backlink.elchoclo.net.
+www.google.com.
+www.grinshare.com.
+wnyahl.com.
+twitter.com.
+210.3.24.188.in-addr.arpa.
+ns2.ameritech.net.
+static1.putlocker.com.
+api.facebook.com.
+a.root-servers.net.
+sp.cwfservice.net.
+www.womens-health-advice.com.
+host26.taxcom.ru.
+smyt.ru.
+10.1.168.192.in-addr.arpa.
+118.205.74.200.in-addr.arpa.
+152.143.239.190.in-addr.arpa.
+recreationland.net.
+webcache.googleusercontent.com.
+144.12.133.78.in-addr.arpa.
+ns7.dnsmadeeasy.com.
+farmacap.it.
+ajax.googleapis.com.
+www.mysatin.com.
+silkroad4gold.com.
+svp.co.uk.
+platform.ak.fbcdn.net.
+narutorev3wii.natneg1.gs.nintendowifi.net.
+pixel.facebook.com.
+149.118.152.201.in-addr.arpa.
+turt.aclap.com.
+www.adserve.com.
+www.volaris.mx.
+ads.us.e-planning.net.
+34.104.201.187.in-addr.arpa.
+southeastern.stokes.k12.nc.us.
+a.root-servers.net.
+5.23.143.201.in-addr.arpa.
+74.112.36.177.in-addr.arpa.
+profile.ak.fbcdn.net.
+www.youtube-nocookie.com.
+profile.ak.fbcdn.net.
+www.amw.com.
+websearch.ask.com.
+static.app.widdit.com.
+appraiserdepot.com.
+www.lageografiadelmundo.com.
+www.desmotivado.es.
+mail.iq-networks.ru.
+b._dns-sd._udp.0.1.168.192.in-addr.arpa.
+64.149.229.99.in-addr.arpa.
+mail-in.daimler.com.
+mail.spangenbergphillips.com.
+pqvpsisuyrgywmaeywjjsuudr.so.
+127.184.227.78.in-addr.arpa.
+123.192.117.70.in-addr.arpa.
+jatek.origo.hu.
+inbound.jnshh.com.netsolmail.net.
+groszassociates.com.
+software-files-a.cnet.com.
+ikcstatic.krazystatic.com.
+www.downtownbahostel.com.
+www.radiomelodia.com.pe.
+_ldap._tcp.
+217.44.105.190.in-addr.arpa.
+camerussia.ru.
+fbcdn-profile-a.akamaihd.net.
+configuration.apple.com.
+13.227.103.93.in-addr.arpa.
+www.monografias.com.
+photos-h.ak.fbcdn.net.
+65.247.1.181.in-addr.arpa.
+s-static.ak.facebook.com.
+190.41.4.186.in-addr.arpa.
+mxserv1.swisstimeclub.ru.
+a995.mm1.akamai.net.
+47.88.204.190.in-addr.arpa.
+horoscopos.prodigy.msn.com.
+s2.youtube.com.
+xwweaasj.cn.
+chat3.doook.com.
+cp36268.edgefcs.net.
+mx02.bis.na.blackberry.com.
+104.41.121.84.in-addr.arpa.
+58.163.171.69.in-addr.arpa.
+newsrss.bbc.co.uk.
+www.myaudiq5.com.
+mcvax4.d48.lilly.com.
+twitter.com.
+steklo.renet.ru.
+a5.sphotos.ak.fbcdn.net.
+www.prediccionesytarot.com.
+photos-e.ak.fbcdn.net.
+pasullivan.com.mt.
+9.94.200.195.zen.spamhaus.org.
+thomas.gov.
+au.download.windowsupdate.com.
+gazinvest.ru.
+31.107.37.186.in-addr.arpa.
+profile.ak.fbcdn.net.
+42.91.177.76.in-addr.arpa.
+www.google.com.
+bing.com.
+titanium30-en.url.trendmicro.com.
+www.facebook.com.
+33.7.31.189.in-addr.arpa.
+by2msg3020507.gateway.messenger.live.com.
+www.javatutoriales.com.
+uv2adglzi.77vf.
+a.root-servers.net.
+17.60.149.187.in-addr.arpa.
+creative.ak.fbcdn.net.
+webssl.com.
+184.35.166.190.in-addr.arpa.
+189.157.168.192.in-addr.arpa.
+www.xdir.com.
+219.45.161.189.in-addr.arpa.
+126.172.115.186.in-addr.arpa.
+a.root-servers.net.
+clubtochka.ru.
+a.root-servers.net.
+studiobritney.ning.com.
+voipb.sip.yahoo.com.
+crl.godaddy.com.
+quebecoworld.com.
+mail.yahoo.com.
+www.wildfatties.com.
+internationalmarinellc.com.s5a1.psmtp.com.
+connect.facebook.net.
+www.fncstatic.com.
+developers.facebook.com.
+www.facebook.com.
+foursquare.com.
+qjr1raiva.12bk.
+photos-g.ak.fbcdn.net.
+kokugai.com.
+au.download.windowsupdate.com.
+js.wlxrs.com.
+bs.serving-sys.com.
+www.conduit.com.
+saibos-services.com.
+blog.es.twitter.com.
+api.facebook.com.
+55.102.186.189.in-addr.arpa.
+www.gfjapan.com.
+a.root-servers.net.
+mxav2.amecom.it.
+107.234.234.189.in-addr.arpa.
+sp.cwfservice.net.
+myfeasts.blogspot.com.
+a1877.phobos.apple.com.
+_500_41_8.
+88.14.124.190.in-addr.arpa.
+mail2.citywide.com.au.
+news.google.com.mx.
+10.147.252.119.in-addr.arpa.
+voipa.sip.yahoo.com.
+developers.facebook.com.
+150.238.120.186.in-addr.arpa.
+www.digitalfotoclub.com.
+ec.atdmt.com.
+9-1.qlty.finarea.ch.
+.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+ads27908.hotwords.com.br.
+mail3.cs.state.ny.us.
+www.facebook.com.
+34.58.138.201.in-addr.arpa.
+159.118.47.189.in-addr.arpa.
+motd.fumadorasguarras.com.
+segment-pixel.invitemedia.com.
+rabanco.com.
+a6.sphotos.ak.fbcdn.net.
+tobolsk.info.
+m.addthisedge.com.
+static.ak.fbcdn.net.
+www.elblogdechuchus.com.
+51.131.159.190.in-addr.arpa.
+teredo.ipv6.microsoft.com.
+liteapps.mcafee.com.
+www.alexanderrichterphoto.com.
+s-assets.tp-cdn.com.
+ocsp.comodoca.com.
+www.monsterdivx.com.
+www.allsaints.com.
+sp.cwfservice.net.
+photos-d.ak.fbcdn.net.
+themes.googleusercontent.com.
+224.86.171.59.in-addr.arpa.
+www.elmundonewspaper.com.
+teredo.ipv6.microsoft.com.
+17.14.168.192.in-addr.arpa.
+s-external.ak.fbcdn.net.
+accounts.google.com.
+www.facebook.com.
+www.directferries.sk.
+downloads.networkmagic.com.
+a.root-servers.net.
+accounts.google.com.
+nimturbo.ru.
+mail.in.ptpgh.com.
+a1.sphotos.ak.fbcdn.net.
+ru.norton.com.
+149.178.138.201.in-addr.arpa.
+htp.net.
+www.rockambul.com.
+152.169.120.87.in-addr.arpa.
+decoracionesyeventos.blogspot.com.
+ns2sw1.amhost.info.
+ls2web.redmond.corp.microsoft.com.
+3.2.144.189.in-addr.arpa.
+mail.broganuk.com.
+86.110.110.189.in-addr.arpa.
+market.android.com.
+alternatedjvu.sourceforge.net.
+www.nubesnegras.com.
+twsu.campus.mci.net.
+static.ak.fbcdn.net.
+www.dramastyle.com.
+www.facebook.com.
+149.211.212.108.in-addr.arpa.
+akamai.turn.com.
+voipa.sip.yahoo.com.
+imagenescelestiales.blogspot.com.
+rs409l36.rapidshare.com.
+www.wiroos.com.
+iebinc.com.
+cambosoup.blogspot.com.
+i.ytimg.com.
+www.facebook.com.
+dl27.hotgoo.com.
+www.shelterpub.com.
+ar-ar.facebook.com.
+www.assoc-amazon.com.
+es-la.facebook.com.
+apps.facebook.com.
+ven.nvidia.com.
+id1.java551.come2play.com.
+weather.service.msn.com.
+206.61.38.190.in-addr.arpa.
+www.argskill.com.
+api.facebook.com.
+img24.imageshack.us.
+a745.g.akamai.net.
+www.hibon.com.
+signin.ebay.com.
+forum.lingvo.ru.
+never-let-me-go.foroactivo.com.
+ipn.academia.edu.
+conntest.nintendowifi.net.
+static.ak.fbcdn.net.
+_095_96_2.
+a.root-servers.net.
+es.kioskea.net.
+a0.twimg.com.
+mail.tridon.com.
+bayal.blogspot.com.
+translate.google.co.ve.
+www.polesports.org.
+www.facebook.com.
+static.ak.fbcdn.net.
+a1.sphotos.ak.fbcdn.net.
+primecountry.com.
+georges-flowers.com.
+pop.aol.com.
+pacifichealthcorp.com.s8b1.psmtp.com.
+essentialhomme.com.
+www.tradearabia.com.
+byfiles.storage.msn.com.
+www.tecamachalco.mobi.
+www.ubiqua.net.
+external.ak.fbcdn.net.
+webassets.sparkybee.com.
+11.239.162.200.in-addr.arpa.
+www.livecams.com.
+www.iabperu.com.
+www.ritmosonlaino.com.
+mailhost.ahigroup.com.
+www.faceook.com.
+www.reduc.edu.cu.
+au.download.windowsupdate.com.
+cdn.kakuroconquest.com.
+mexicanainforma.com.
+www.math.grin.edu.
+external.ak.fbcdn.net.
+validator.w3.org.
+resumejob.ru.
+www.cheapmonclerjacketsale.co.uk.
+boblemke.blogspot.com.
+www.massiveassaultnetwork.com.
+mail.claasindia.com.
+cs12843.vk.com.
+www.jiriruzek.net.
+a.root-servers.net.
+nedschroef.be.
+lascincoestaciones.blogspot.com.
+www.blogherads.com.
+app.offer99.com.
+www.openclik.com.
+www.msftncsi.com.
+u14.eset.com.lan.
+a1.sphotos.ak.fbcdn.net.
+www.facebook.com.
+chemcentral.com.s8a1.psmtp.com.
+www.oxfamnovibpaktuit.nl.
+stlarshabos.dotheortontab.tk.
+a2.sphotos.ak.fbcdn.net.
+atlantic-pub.com.bak-mx.na0104.smtpbak.com.
+www.todoanimes.com.
+check4.facebook.com.
+87.26.45.24.in-addr.arpa.
+rapidcityrec.com.
+153.228.151.79.in-addr.arpa.
+pixel.facebook.com.
+253.105.92.78.in-addr.arpa.
+_344_85_7.
+lyrics.tunewiki.com.
+299.channel.facebook.com.
+idisk.mac.com.
+www.google-analytics.com.
+www.casinoval.com.
+www.ons.mr.
+bluehatuk.com.inbound10.mxlogicmx.net.
+www.ttfn.net.
+teredo.ipv6.microsoft.com.
+middlefokpartners.com.
+leproduct.com.inbound10.mxlogic.net.
+childrensmemorial.org.
+www.ford.nl.
+129.32.212.189.in-addr.arpa.
+94.69.47.189.in-addr.arpa.
+www.xvideoslive.com.
+www.google-analytics.com.
+tps31.doubleverify.com.
+byfiles.storage.msn.com.
+revista-zoom.com.ar.
+blairwilliams.com.
+photos-f.ak.fbcdn.net.
+rcp.na.blackberry.com.
+postfix1.vitro.epldt.net.
+time.chttl.com.tw.
+www.pnosker.com.
+13.184.38.190.in-addr.arpa.
+m.addthisedge.com.
+www.charlestonbusiness.com.
+dns.msftncsi.com.
+www.servercraft.co.
+benz4ever.com.
+images2.culiarmedia.com.
+external.ak.fbcdn.net.
+154.53.115.190.in-addr.arpa.
+188.134.88.186.in-addr.arpa.
+37-courier.push.apple.com.
+104.226.10.186.in-addr.arpa.
+profile.ak.fbcdn.net.
+_275_66_5.
+b._dns-sd._udp.lan.
+cox-iternet.com.
+s-static.ak.facebook.com.
+platform.twitter.com.
+spm02.pinehost.net.
+www.facebook.com.
+26.116.81.68.in-addr.arpa.
+addons.mozilla.org.
+www.informatica.ith.mx.
+whos.amung.us.
+www.google-analytics.com.
+i2.ytimg.com.
+ads1.msads.net.
+109.179.82.200.in-addr.arpa.
+www.royalskandia.com.
+dbcc.edu.
+contextmenu.toolbar.conduit-services.com.
+pixel.quantserve.com.
+upload.wikimedia.org.
+external.ak.fbcdn.net.
+mercuryexcelum.com.1.0001.arsmtp.com.
+dcbrands.com.s6b2.psmtp.com.
+arabic.arabia.msn.com.
+a.root-servers.net.
+150.151.228.190.in-addr.arpa.
+1.0.0.127.dnsbugtest.1.0.0.127.in-addr.arpa.
+a7.sphotos.ak.fbcdn.net.
+178.140.246.201.in-addr.arpa.
+5.78.216.178.in-addr.arpa.
+218.53.199.190.in-addr.arpa.
+www.alu-stock.es.
+0-jx-w.channel.facebook.com.
+sp.cwfservice.net.
+pixel.facebook.com.
+90.24.160.187.in-addr.arpa.
+fr-fr.facebook.com.
+photos-d.ak.fbcdn.net.
+profile.ak.fbcdn.net.
+www.googleadservices.com.
+ip1.dynupdate.no-ip.com.
+g.live.com.
+amathusvip.ru.
+tbr.ask.com.
+photos-a.ak.fbcdn.net.
+www.european-podcast-award.eu.
+www.purnas.com.
+cowboy.com.
+100.155.60.186.in-addr.arpa.
+event-post.ru.
+www.facebook.com.
+time.windows.com.
+profile.ak.fbcdn.net.
+7.134.121.124.in-addr.arpa.
+cricket-league-of-champions.en.softonic.com.
+curriculo.catho.com.br.
+apple-mobile.query.yahooapis.com.
+photos-a.ak.fbcdn.net.
+118.208.122.189.in-addr.arpa.
+external.ak.fbcdn.net.
+35.198.132.190.in-addr.arpa.
+tc22.easythumbhost.com.
+ws-cloud-msgplus.linkury.com.
+fei9988.3322.org.
+photos-g.ak.fbcdn.net.
+rcm-fr.amazon.fr.
+winstar.com.
+l-e.com.s6a2.psmtp.com.
+et5.xhamster.com.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+s0.2mdn.net.
+r.mzstatic.com.
+msgs.smarterfox.com.
+176.235.29.186.in-addr.arpa.
+mcsoh.org.
+www.tyrone-power.com.
+tc.v16.cache8.c.youtube.com.
+179.75.235.189.in-addr.arpa.
+liveupdate.symantecliveupdate.com.
+mets.crb.apmoller.net.
+d.yimg.com.
+74.54.174.189.in-addr.arpa.
+sphotos.ak.fbcdn.net.
+et7.xhamster.com.
+tdkarat.ru.
+productosweb.org.
+36.194.3.188.in-addr.arpa.
+api.twitter.com.
+a.root-servers.net.
+sedonasouladventures.com.
+127.106.135.110.in-addr.arpa.
+146.232.19.83.in-addr.arpa.
+8wbhurv6l.w55v3k9p.
+207.212.179.189.in-addr.arpa.
+www.google-analytics.com.
+www.quantumtouch.com.
+videobam.com.
+24.248.69.186.in-addr.arpa.
+service.homepages.demon.net.
+sp.cwfservice.net.
+sarah-london.blogspot.com.
+websearch.ask.com.
+mightydeals.s3.amazonaws.com.
+a.root-servers.net.
+img.fewdress.com.
+a.root-servers.net.
+gamcaretradeservices.com.
+developers.facebook.com.
+www.matiogi.com.
+t.co.
+www.facebook.com.
+www.nme.com.
+courrier.fadq.qc.ca.
+checkip.dyndns.com.
+244.120.35.62.in-addr.arpa.
+142.49.232.24.in-addr.arpa.
+mail.mrdelaw.com.
+8.101.123.186.in-addr.arpa.
+162.224.58.186.in-addr.arpa.
+a.root-servers.net.
+xiscoekzo.files.wordpress.com.
+106.206.214.189.in-addr.arpa.
+www.youtube.com.
+pixel.facebook.com.
+lh6.googleusercontent.com.
+www.newincredimail.com.
+mail.bankofoldmonroe.com.
+134.66.210.186.in-addr.arpa.
+yahoo.com.
+members.graphicsfactory.com.
+vincitori.wordpress.com.
+ad.yieldmanager.com.
+loading.ninja.game321.com.
+cdn.smosh.com.
+www.cymax.com.
+webgetclick.com.home.
+a.root-servers.net.
+s2.youtube.com.
+em1x-198.lhr.messaging.nokia.com.
+hasancanbozkurt.net.
+auditsonmer.blogspot.com.
+wispresort.com.inbound15.mxlogicmx.net.
+googleads.g.doubleclick.net.
+aptitudequestionsandanswers.in.
+api.twitter.com.
+www.openpa.net.
+trivantisdev.com.
+www.whitefrog.org.
+rs233l34.rapidshare.com.
+1804289383.localhost.
+sagesoftware.com.
+utess.ru.
+view.atdmt.com.
+223.89.19.95.in-addr.arpa.
+s2.youtube.com.
+247.219.155.189.in-addr.arpa.
+www.facebook.com.
+mail.onlinenetworking.com.
+dns.msftncsi.com.
+com-pac.com.
+aflex.ru.
+www.b2bonlinesolutions.com.
+rmd.atdmt.com.
+www.northropandjohnson.com.
+www.changesxchange.com.
+133.5.223.14.in-addr.arpa.
+_882_86_3.
+time.chttl.com.tw.
+profile.ak.fbcdn.net.
+thumbs.totale-defonce.com.
+profile.ak.fbcdn.net.
+johnsonmoncrief.com.
+_ldap._tcp.
+news.yahoo.com.
+tropicfishhawaii.com.
+www.wallsoffame.com.
+m.facebook.com.
+gobrainstrom.net.
+mail.empireindustries.com.
+securemetrics.apple.com.
+www.google.com.
+canal.univalle.edu.co.
+lasenoritalasenorita.blogspot.com.
+mail.puratone.com.
+chart.vgmc.com.
+133.212.32.72.in-addr.arpa.
+a.root-servers.net.
+banashare.com.
+info.babylon.com.
+dl-debug32.dropbox.com.
+167.143.58.186.in-addr.arpa.
+wxxr3vy4e.r02r9f2r.
+201.67.25.186.in-addr.arpa.
+photos-f.ak.fbcdn.net.
+s3-eu-west-1.amazonaws.com.
+services.runescape.com.
+pagead2.googlesyndication.com.
+www.wallpaperfans.com.
+googleads.g.doubleclick.net.
+google.com.
+juventudenmarcha.wordpress.com.
+accounts.google.com.
+hotmail.com.
+www.redtube.com.
+img193.imageshack.us.
+z8ojttuzg.06nx.
+static.ak.fbcdn.net.
+aleksey.tver.ru.
+.
+9.77.43.190.in-addr.arpa.
+fbcdn-photos-a.akamaihd.net.
+189.103.119.83.in-addr.arpa.
+www.naqatube.com.
+cgi1.ebay.com.
+hwqm9j9r7.w38c8o7h.
+mail.micmedia.ru.
+www.noisemachine.com.
+35.156.22.50.in-addr.arpa.
+apps.facebook.com.
+17.26.140.200.in-addr.arpa.
+a.root-servers.net.
+google.com.
+138.255.28.80.in-addr.arpa.
+73.238.200.195.in-addr.arpa.
+www.markosweb.com.
+www.megasecurity.org.
+oscsm3y2r.99qe.
+fvg.cgil.it.
+gunsnrosesbootlegs.blogspot.com.
+niunomas.foroactivo.com.
+www.pe.pirelli.com.
+www.actualizar-messenger.com.
+122.49.103.76.in-addr.arpa.
+media.admob.com.
+113.23.168.192.in-addr.arpa.
+gepigeny.hu.
+170.89.102.71.in-addr.arpa.
+a.root-servers.net.
+web59516.mail.ac4.yahoo.com.
+i3.ytimg.com.
+a.root-servers.net.
+a6.sphotos.ak.fbcdn.net.
+3c2is992:.e41v2m1d.
+admin.mundotoro.com.
+aidps.atdmt.com.
+d2060193.instant.xoom.it.
+cdn.fastclick.net.
+photos-c.ak.fbcdn.net.
+www.funnyhub.com.
+www.gstatic.com.
+229.184.22.107.in-addr.arpa.
+tele2adsl.dk.home.
+a6.sphotos.ak.fbcdn.net.
+cdn.widgets.spongecell.com.
+photos-e.ak.fbcdn.net.
+79.99.96.58.in-addr.arpa.
+35.184.79.190.in-addr.arpa.
+photos-a.ak.fbcdn.net.
+abanfin.com.
+db._dns-sd._udp.0.2.168.192.in-addr.arpa.
+powervoice.at.
+telaquecortar.wordpress.com.
+photos-g.ak.fbcdn.net.
+.
+36.102.13.187.in-addr.arpa.
+safebrowsing-cache.google.com.
+rendezvous.blogs.nytimes.com.
+4.36.203.190.in-addr.arpa.
+frnx9q8kd.22ll.
+87.14.62.186.in-addr.arpa.
+luzverdadeterna.blogspot.com.
+news.ino.com.
+profile.ak.fbcdn.net.
+a12.t26.net.
+u.openx.net.
+elseruno-gallery.blogspot.com.
+192.40.198.190.in-addr.arpa.
+a.root-servers.net.
+twitter.com.
+66.170.255.201.in-addr.arpa.
+goo.gl.
+rcp.eu.blackberry.com.
+photos-d.ak.fbcdn.net.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+.
+235.31.249.201.in-addr.arpa.
+time.stdtime.gov.tw.
+167.47.231.77.in-addr.arpa.
+secure-us.imrworldwide.com.
+104.133.142.189.in-addr.arpa.
+158.77.154.189.in-addr.arpa.
+122.254.60.78.in-addr.arpa.
+223.226.110.186.in-addr.arpa.
+www.facebook.com.
+profile.ak.fbcdn.net.
+173.176.92.212.in-addr.arpa.
+db1.stat.gov.lt.
+sbcglobal.net.
+www.facebook.com.
+www.ca.uky.edu.
+a1820.phobos.apple.com.
+sv.monkeybroker.net.
+code.jquery.com.
+107.166.10.186.in-addr.arpa.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+a0.twimg.com.
+_ldap._tcp.
+co123w.col123.mail.live.com.
+time.chttl.com.tw.
+www.20minutos.es.
+www.traductordepaginasweb.com.
+koala.webeasy.com.
+ifxchange.appspot.com.
+www.despegar.com.
+43.177.47.190.in-addr.arpa.
+sp.cwfservice.net.
+ar-ar.facebook.com.
+140.187.130.186.in-addr.arpa.
+profile.ak.fbcdn.net.
+www.aaronvaldez.com.
+teredo.ipv6.microsoft.com.
+photos-b.ak.fbcdn.net.
+smtp.mtsolutions.net.
+154.26.27.187.in-addr.arpa.
+plusone.google.com.
+bmw-vw.tk.
+a-ak.static-rootmusic.com.
+pixel.facebook.com.
+profile.ak.fbcdn.net.
+photos-g.ak.fbcdn.net.
+entertainment-memorabilia.shop.ebay.com.
+assets3.castle.zgncdn.com.
+1.19.29.186.in-addr.arpa.
+www.heymister.net.
+l.sharethis.com.
+75.90.23.69.in-addr.arpa.
+www.linkedin.com.
+web39207.mail.mud.yahoo.com.
+i1gpwuhrk.p88i6r3u.
+www.l.google.com.
+router.tlvmedia.com.
+orcart.facebook.com.
+mobth915.photobucket.com.
+15.58.209.201.in-addr.arpa.
+yahoo.de.
+www.theecommercepro.com.
+fbcdn-profile-a.akamaihd.net.
+www.margaritabonita.com.
+pixel.facebook.com.
+.
+www.minigamesfreak.com.
+a3.sphotos.ak.fbcdn.net.
+store.grooveshark.com.
+a.root-servers.net.
+www.meowmistidawn.com.
+support.google.com.
+www.biap.org.
+support.google.com.
+a.root-servers.net.
+darling.artmodelingstudios.com.
+www.unknownnews.net.
+www.facebook.com.
+www.greekairsoft.gr.
+www.monografias.com.
+www.le-maitre-du-chaos.skyrock.com.
+safebrowsing.clients.google.com.
+superiorwallsystems.com.
+95.36.209.189.in-addr.arpa.
+praetoriangroup.com.s6a1.psmtp.com.
+www.google.com.
+199.208.122.84.in-addr.arpa.
+fxfeeds.mozilla.com.
+sthi.com.inbound10.mxlogic.net.
+4t8yva9ap.v06m0j7r.
+www.youtube.com.
+www.penews.com.
+_500_61_5.
+www.youtube.com.
+jeffmo.us.
+chromejs.s3.amazonaws.com.
+i4.ytimg.com.
+010b36352e35342e36312e39340c40686f746d61696c2e636f6d00.lbl8.mailshell.net.
+media.elnuevoheraldo.com.
+i2.ytimg.com.
+www.facebook.com.
+l.yimg.com.
+www.mascotas.org.
+www.gardenphotos.com.
+71.232.240.189.in-addr.arpa.
+ku7t46lw9.e36k5v2b.
+safebrowsing-cache.google.com.
+a747.v.phobos.apple.com.
+emob178.photobucket.com.
+a.c-0.19-a30fb000.30011.1518.19d4.3ea1.210.0.k5gu7j63sb9mz9wvg8g2f9uart.avqs.mcafee.com.
+s1-onenote.vo.msecnd.net.
+developers.facebook.com.
+39.65.3.186.in-addr.arpa.
+_257_43_8.
+www.bytepr.com.
+rus-eda.ru.
+external.ak.fbcdn.net.
+www.itait.org.mx.
+dj7nmfd6odmeo.cloudfront.net.
+33.66.91.186.in-addr.arpa.
+s.youtube.com.
+traauctions.com.
+summit.retailcustomerexperience.com.
+60.149.157.189.in-addr.arpa.
+245.13.73.190.in-addr.arpa.
+b.scorecardresearch.com.
+businessdailyreview.com.
+ad.yieldmanager.com.
+97.134.225.186.in-addr.arpa.
+22.197.6.187.in-addr.arpa.
+www.shell-storm.org.
+s-static.ak.fbcdn.net.
+lulila21.blogspot.com.
+profile.ak.fbcdn.net.
+255.235.254.190.in-addr.arpa.
+clients2.google.com.
+mich.edu.
+www.googleadservices.com.
+37.244.236.98.in-addr.arpa.
+www.foxsportsla.com.
+sites.google.com.
+dron.beth.com.
+www.google.com.
+231.19.233.190.in-addr.arpa.
+.
+sites.google.com.
+cribreak.com.
+iphone-wu.apple.com.
+profile.ak.fbcdn.net.
+secure.drilledmouths.com.
+a.root-servers.net.
+idonno.com.
+db._dns-sd._udp.0.1.168.192.in-addr.arpa.
+46.233.227.189.in-addr.arpa.
+www.facebook.com.
+amherst.k12.wi.us.
+1.37.112.190.in-addr.arpa.
+orcart.facebook.com.
+lb._dns-sd._udp.lan.
+mx.youtube.com.
+www.google.com.
+a8.sphotos.ak.fbcdn.net.
+connecta-2000.softonic.com.
+whatismyip.org.
+cdn.api.twitter.com.
+gwpjosae2.b88m7j2n.
+headbangorgtfo.files.wordpress.com.
+platform.ak.fbcdn.net.
+a.root-servers.net.
+.
+161.226.194.180.in-addr.arpa.
+updatekeepalive.mcafee.com.
+mail-pz0-f47.google.com.
+mx.answers.yahoo.com.
+sp.cwfservice.net.
+clients1.google.com.
+www.switchnode.com.
+gaiaware.net.
+www.servidoresrack.com.
+t1.gstatic.com.
+jorgebarontelevision.com.co.
+a.root-servers.net.
+my.ebay.com.
+thailandpopper.com.
+conn.skype.com.
+community.d.xx.openx.com.akadns.net.
+loading2.widdit.com.
+97.158.188.190.in-addr.arpa.
+countduhmoney.com.
+android.clients.google.com.
+thedesignsuperhero.com.
+107.130.64.186.in-addr.arpa.
+pixel.facebook.com.
+a7.sphotos.ak.fbcdn.net.
+exp02.eset.com.
+livefiles18.vo.msecnd.net.
+238.123.24.201.in-addr.arpa.
+photos-f.ak.fbcdn.net.
+comtrend.com.ua.
+a.root-servers.net.
+safebrowsing.clients.google.com.
+baymsg1010734.by2.gateway.edge.messenger.live.com.
+www.gfxrls.com.
+denshou.wordpress.com.
+a1725.l.akamai.net.
+photos-f.ak.fbcdn.net.
+kdoudyxnkxuusofs.info.
+vthumb.ak.fbcdn.net.
+tap2-cdn.rubiconproject.com.
+ajax.googleapis.com.
+dsn3.d.skype.net.
+clients1.google.com.
+juegos.latino.msn.com.
+s-external.ak.fbcdn.net.
+www.vicensvives.com.co.
+www.facebook.com.
+photos-h.ak.fbcdn.net.
+images0-ig-opensocial.googleusercontent.com.
+architetto-casa.blogautore.repubblica.it.
+i1.ytimg.com.
+news.google.com.mx.
+www.buenscoring.com.
+apps.facebook.com.
+ssl.gstatic.com.
+pixel.facebook.com.
+ad.yieldmanager.com.
+ali-299.zapto.org.
+179.35.199.190.in-addr.arpa.
+external.ak.fbcdn.net.
+toolbar.google.com.
+179.174.163.189.in-addr.arpa.
+www.cocukoyunlari4.com.
+144.68.29.186.in-addr.arpa.
+2.9.c.f.8.0.6.8.2.5.2.2.f.0.c.3.6.7.e.9.7.3.1.4.0.0.0.0.1.0.0.2.ip6.arpa.
+alleventsgroup.com.
+99.25.106.95.in-addr.arpa.
+a.root-servers.net.
+a7.sphotos.ak.fbcdn.net.
+photos-b.ak.fbcdn.net.
+57.98.183.83.in-addr.arpa.
+teredo.ipv6.microsoft.com.
+ssl.google-analytics.com.
+_ldap._tcp.
+rs342tl5.rapidshare.com.
+api.twitter.com.
+ocsp.thawte.com.
+www.instalacionesdeportivas.es.
+profile.ak.fbcdn.net.
+weatherhistory.almanac.com.
+funbike.com.
+pnrws.skype.com.
+itunes.apple.com.
+profile.ak.fbcdn.net.
+www.calendarclub.co.uk.
+pix04.revsci.net.
+134.220.230.190.in-addr.arpa.
+pintandoluces.blogspot.com.
+clients2.google.com.
+7.189.166.78.in-addr.arpa.
+safebrowsing-cache.google.com.
+blog.fo.ifeng.com.
+developers.facebook.com.
+sn133w.snt133.mail.live.com.
+jebo.ru.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+b._dns-sd._udp.0.1.168.192.in-addr.arpa.
+zbsbms7lm.62zh.
+time.chttl.com.tw.
+urbansketchers-moscow.blogspot.com.
+jus.com.br.
+www.google-analytics.com.
+it-it.facebook.com.
+mail2.motion-ind.com.
+mail2.gidinvest.ru.
+www.adobe.com.
+android.clients.google.com.
+mail.ruentex.com.tw.
+www.action-games.co.
+www.juegosmz.com.
+175.107.13.80.in-addr.arpa.
+wunruxzcdu.net.home.
+a.root-servers.net.
+foxpool.com.
+www.khosoof.com.
+87.165.22.190.in-addr.arpa.
+114.213.168.82.in-addr.arpa.
+www.multilateralfund.org.
+227.225.240.84.in-addr.arpa.
+crl.microsoft.com.
+apps.facebook.com.
+www.compresores.redee.com.
+mineracholino.com.ar.
+static.ak.fbcdn.net.
+0-jh-w.channel.facebook.com.
+t0.gstatic.com.
+horizonfinancial.org.
+a4.sphotos.ak.fbcdn.net.
+www.sinembargo.mx.
+dns.msftncsi.com.
+beacon-1.newrelic.com.
+pool.ntp.org.
+refresh.monohrome.com.
+profile.ak.fbcdn.net.
+www.usavisasonline.com.
+35.2.7.189.in-addr.arpa.
+77.220.75.94.zz.countries.nerd.dk.
+cdn.advertserve.com.
+www.love-m.com.
+www.google-analytics.com.
+safebrowsing-cache.google.com.
+photos-h.ak.fbcdn.net.
+faculty.citadel.edu.
+jers1.info.
+www.google.com.
+scores.neonplay.com.
+a.root-servers.net.
+safebrowsing.clients.google.com.
+www.youtube.com.
+d8bz4crf4.k48u1e7g.
+www.proxytopsitelist.com.
+photos-d.ak.fbcdn.net.
+developers.facebook.com.
+mail.ulcomnet.ru.
+r02.member.ukl.yahoo.com.
+ajax.googleapis.com.
+cloud-search.linkury.com.
+www.ibersearch.com.
+73.244.165.190.in-addr.arpa.
+d2057087.instant.xoom.it.
+a.root-servers.net.
+0-jl-w.channel.facebook.com.
+73.101.250.190.in-addr.arpa.
+50.149.220.66.in-addr.arpa.
+21.80.59.186.in-addr.arpa.
+dns.msftncsi.com.
+images02.olx.com.sv.
+www.consult.com.
+mp3topdeals.com.
+dns.msftncsi.com.
+www.facebook.com.
+a4.sphotos.ak.fbcdn.net.
+hscontshitifti.mp.
+pineapp.health.gov.il.
+www.ebay.es.
+i6.ifile.it.
+mdc-games.clanteam.com.
+www.pitbullclothing.com.
+www.maquina-tragaperras.org.
+lb._dns-sd._udp.lan.
+teredo.ipv6.microsoft.com.
+adsfront.iminent.com.
+a.root-servers.net.
+gu.e-hentai.org.
+google.com.
+mscrl.microsoft.com.
+www.5xxx.ru.
+safebrowsing.clients.google.com.
+cs83.vk.com.
+185.73.37.190.in-addr.arpa.
+112.142.188.189.in-addr.arpa.
+www.stephenkingshop.com.
+webishdesign.com.
+ocsp.verisign.com.
+content.netsuite.com.
+www.iamm.org.my.
+ntp1.tummy.com.
+safebrowsing-cache.google.com.
+nserver.calipso.com.co.
+static.ak.fbcdn.net.
+st.xiami.com.
+40.0.157.201.in-addr.arpa.
+sup.live.com.
+ep00.epimg.net.
+clients1.google.com.mx.
+almas.com.mx.
+office.microsoft.com.
+s1-powerpoint.vo.msecnd.net.
+www.facebook.com.
+clients2.google.com.
+creative.ak.fbcdn.net.
+s.youtube.com.
+gw0.aholding.com.ua.
+190.182.39.116.in-addr.arpa.
+ksn2-12.kaspersky-labs.com.
+www.buenosairesfreetour.com.
+www.facebook.com.
+249.19.52.186.in-addr.arpa.
+149.150.164.187.in-addr.arpa.
+www.verynicejoke.com.
+51.152.80.190.in-addr.arpa.
+lesta-kr.ru.
+intranet.icipc.org.
+www.google.com.
+ax.su.itunes.apple.com.
+a.root-servers.net.
+173.41.122.85.in-addr.arpa.
+crystalseye.redbubble.com.
+www.facebook.com.
+www.facebook.it.
+fls.doubleclick.net.
+www.astrojar.org.uk.
+photos-e.ak.fbcdn.net.
+wpi-mexico.com.
+teredo.ipv6.microsoft.com.
+24.229.171.69.in-addr.arpa.
+102.149.238.190.in-addr.arpa.
+smetrics.aetn.com.
+static.ak.fbcdn.net.
+www.thedmonline.com.
+widgets.amung.us.
+_474_78_6.
+a.root-servers.net.
+tcr.tynt.com.
+en.wikipedia.org.
+r9aa:cx7q.e19a4d5k.
+old.longjuyt2tugas.com.
+www.tuffluvusa.com.
+147.23.168.192.in-addr.arpa.
+118.197.242.189.in-addr.arpa.
+194.146.129.94.in-addr.arpa.
+ssl.gstatic.com.
+rathole.ru.
+a.root-servers.net.
+themes.googleusercontent.com.
+rterybrstutnrsbberve.com.
+apple-mobile.query.yahooapis.com.
+www.adobe.com.
+mail.flyrichmond.com.
+android.clients.google.com.
+r._dns-sd._udp.lan.
+estilos.prodigy.msn.com.
+telecinc.com.
+pixel.facebook.com.
+platform.twitter.com.
+www.centroagb.cl.
+ksn3-11.part1.kaspersky-labs.com.
+fluoramec.com.
+www.cityofmovies.com.
+a1.sphotos.ak.fbcdn.net.
+video.google.com.
+futurclima.it.
+livereports.gpupdate.net.
+ssl.gstatic.com.
+www.lechaim.ru.
+s0.2mdn.net.
+ads.cleveland.com.
+www.youtube.com.
+i4.ytimg.com.
+a3.sphotos.ak.fbcdn.net.
+ips-glass.ru.
+photos-a.ak.fbcdn.net.
+251.162.244.190.in-addr.arpa.
+spectrumbloggers.com.
+aploan.com.s7b2.psmtp.com.
+ssl.gstatic.com.
+delta-sport.ru.
+lasclementinas.com.
+1.map.pop6.com.
+ib.adnxs.com.
+profile.ak.fbcdn.net.
+uc7e8x6ty.52xc.
+176.234.82.177.in-addr.arpa.
+c-0.19-a3090081.23.1518.19d3.3ea1.410.0.b8etnr6scdgjt2agmdu7i489av.avqs.mcafee.com.
+www.google.com.
+\(none\).
+227.3.151.187.in-addr.arpa.
+104.114.137.186.in-addr.arpa.
+www.sex8.cc.
+apac002.fra.samsungsocialhub.com.
+60.129.31.186.in-addr.arpa.
+photos-c.ak.fbcdn.net.
+impactopositivo.bligoo.com.
+bobbrownauto.com.
+localhost.
+135.193.174.189.in-addr.arpa.
+bit.ly.
+149.28.168.192.in-addr.arpa.
+p42-buy.itunes.apple.com.
+mail.comgate.cz.
+www.theryancenter.com.
+down10.zol.com.cn.
+www.gstatic.com.
+groups.google.com.mx.
+www.msftncsi.com.
+osogay.disqus.com.
+www.hotmail.com.
+www.coolest-baby-shower-idea.com.
+dnl-01.geo.kaspersky.com.
+irc.purchaseservice.com.
+es.justin.tv.
+rntcalls.com.
+ssl.gstatic.com.
+sp.cwfservice.net.
+ecsnyder.com.
+57.112.107.187.in-addr.arpa.
+thean.com.
+224.117.145.201.in-addr.arpa.
+7p7xc58by.95nt.
+a4.mzstatic.com.
+www.descubrewindowslive.com.
+50.174.171.201.in-addr.arpa.
+mx1.botkyrka.see.
+a1.sphotos.ak.fbcdn.net.
+_354_51_7.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+cvw7.navy.mil.
+altfarm.mediaplex.com.
+133.24.146.99.in-addr.arpa.
+cdd.emakumeak.org.
+www.conduit.com.
+profile.ak.fbcdn.net.
+a3.sphotos.ak.fbcdn.net.
+login.live.com.
+a1.sphotos.ak.fbcdn.net.
+a4.sphotos.ak.fbcdn.net.
+a8.sphotos.ak.fbcdn.net.
+s0.2mdn.net.
+i.imgur.com.
+ss.websearch.ask.com.
+www.manualmovil.com.
+www.facebook.com.
+ayreycia.com.
+southernphone.com.au.
+sites.google.com.
+www.hotmail.com.
+on.fb.me.
+developers.facebook.com.
+e82eikdbp.71um.
+cloudscaling.com.
+ru.radioera.com.ua.
+160.110.164.110.in-addr.arpa.
+100.149.43.211.in-addr.arpa.
+a4.sphotos.ak.fbcdn.net.
+www.belkin.com.
+b.scorecardresearch.com.
+widgets.amung.us.
+xxlcc.com.
+cydia.hackulo.us.
+112.41.171.187.in-addr.arpa.
+www.igadi.org.
+www.reddoorindy.com.
+www.greatplacetowork.com.co.
+any-world.ngd.ysm.yahoodns.net.
+168.171.255.201.in-addr.arpa.
+ns4.p13.dynect.net.
+km.
+a5.sphotos.ak.fbcdn.net.
+a3.sphotos.ak.fbcdn.net.
+a1.sphotos.ak.fbcdn.net.
+_020_85_2.
+135.101.191.186.in-addr.arpa.
+v4.netlogstatic.com.
+accoladehomecare.com.
+www.quanser.com.
+i1.ytimg.com.
+243.56.60.190.in-addr.arpa.
+johnmerritt.wikidot.com.
+a6.sphotos.ak.fbcdn.net.
+angg.ru.
+a.root-servers.net.
+photos-h.ak.fbcdn.net.
+6xj.info.
+a.tribalfusion.com.
+www.makeupobsessed.com.
+carew.com.
+static-js.veevr.com.
+balancingact-africa.com.
+zokugo-dict.com.
+www.youtube.com.
+www.enelfacebook.com.
+a4.sphotos.ak.fbcdn.net.
+a6.sphotos.ak.fbcdn.net.
+_ldap._tcp.
+163.6.134.190.in-addr.arpa.
+usctap3132.apac.schp.com.
+www.saintnick.org.
+talkx.l.google.com.
+mail.asig.us.
+i46.tinypic.com.
+www.fourwheelcampers.com.
+connect.facebook.net.
+www.youtube.com.
+berkelouw.com.au.
+118.168.56.186.in-addr.arpa.
+ax.init.itunes.apple.com.
+erdemimports.com.
+ping.chartbeat.net.
+a6.sphotos.ak.fbcdn.net.
+22.107.248.201.in-addr.arpa.
+forum.b92.net.
+answers.nordstrom.com.
+creative.ak.fbcdn.net.
+i.ytimg.com.
+images.apple.com.
+survey.edmunds.com.
+t1.tagstat.com.
+redirector.c.youtube.com.
+cnfg.montiera.com.
+a.root-servers.net.
+a8.sphotos.ak.fbcdn.net.
+www.muscat-festival.com.
+2.bp.blogspot.com.
+rasthg.ru.
+nucleotide.ru.
+fbcdn-sphotos-a.akamaihd.net.
+www.xxx-69-xxx.com.
+smssandmold.com.
+www.youtube.com.
+pixel.facebook.com.
+smena.tusur.ru.
+150.225.146.186.in-addr.arpa.
+_430_11_9.
+www.google.com.
+www.ppvnetworks.com.
+gfx4.hotmail.com.
+63.159.10.186.in-addr.arpa.
+93.172.123.201.in-addr.arpa.
+photodoctorgraphics.com.
+www.onepcbsolution.com.
+cleantown.ru.
+a6.sphotos.ak.fbcdn.net.
+a.root-servers.net.
+32.191.146.187.in-addr.arpa.
+nppl.c.app.nintendowifi.net.
+ksn2-12.kaspersky-labs.com.
+nl.sykes.com.
+93.35.152.189.in-addr.arpa.
+panajidb.foroactivo.net.
+r._dns-sd._udp.0.2.168.192.in-addr.arpa.
+selectownerscorp.com.au.
+248.73.169.178.in-addr.arpa.
+www.verbinteractive.com.
+pop.e-medex.com.
+www.medical-conditions.org.
+emailmgr.aetv.com.
+ib.adnxs.com.
+blog.zap2it.
+www.metroflog.com.
+97.71.55.65.in-addr.arpa.
+sp.cwfservice.net.
+www.hotmail.com.
+52.177.233.190.in-addr.arpa.
+225.178.70.71.in-addr.arpa.
+mailstore1.secureserver.net.
+32.98.250.67.in-addr.arpa.
+www.www8-hp.com.
+d15gt9gwxw5wu0.cloudfront.net.
+a.root-servers.net.
+www.sociedaduruguaya.org.
+ns2.attdns.com.
+145.208.168.192.in-addr.arpa.
+tc3.easythumbhost.com.
+settings.toolbar.search.conduit.com.
+www.nuevomovil.com.
+www.ellsberg.net.
+.
+158.200.167.77.in-addr.arpa.
+froggy.com.au.
+dns.msftncsi.com.
+au.download.windowsupdate.com.
+hzimc01.hzmot.com.
+xtra1.gpsonextra.net.
+static.ak.fbcdn.net.
+time.chttl.com.tw.
+188.142.255.201.in-addr.arpa.
+167.16.180.189.in-addr.arpa.
+111.75.234.189.in-addr.arpa.
+als.wikipedia.org.
+www.safenet.com.
+www.snopes.com.
+pub.betclic.com.
+91.128.153.187.in-addr.arpa.
+zolotoerunohotel.ru.
+www.voyages-sncf.com.
+mail.skynet.lv.
+a4.sphotos.ak.fbcdn.net.
+creative.ak.fbcdn.net.
+www.google.com.
+nr.rr.com.
+22.208.55.110.in-addr.arpa.
+173.211.111.190.in-addr.arpa.
+a5.sphotos.ak.fbcdn.net.
+176.1.149.190.in-addr.arpa.
+samosval-market.ru.
+a1.sphotos.ak.fbcdn.net.
+229.90.112.79.in-addr.arpa.
+ws.tapjoyads.com.
+google.com.
+www.bayharborislands.org.
+www.google.com.
+googleads.g.doubleclick.net.
+116.118.4.190.in-addr.arpa.
+brand-way.ru.
+mail.interdepotservices.com.
+228.3.79.187.in-addr.arpa.
+s.ytimg.com.
+ad.xtendmedia.com.
+www.seleccionuruguayadefutbol.com.
+bestmanager.rags.ru.
+igor.facemoods.com.
+profile.ak.fbcdn.net.
+streetdate.radio.com.
+weather.wapp.wii.com.
+82.248.250.189.in-addr.arpa.
+www.connect.facebook.com.
+www.rootsweb.ancestry.com.
+64.118.103.201.in-addr.arpa.
+www.modernhomedesigns.info.
+jers2.info.
+www.buy4now.ie.
+www.bankrollsports.com.
+cf.blogetery.com.
+data.goodgamestudios.com.
+a.root-servers.net.
+profile.ak.fbcdn.net.
+vp.sip.messenger.msn.com.
+www.libreriaselatril.com.ar.
+photos-a.ak.fbcdn.net.
+www.blogtopsites.com.
+www.arbada.org.
+keais.com.s9a1.psmtp.com.
+121.138.40.187.in-addr.arpa.
+a-0.19-210fb801.c0c0081.1518.19d4.3ea1.210.0.9nvrwias8sz3akezrl3whq4et5.avqs.mcafee.com.
+iglasses.en.softonic.com.
+www.dwfitnessclubs.com.
+ntp.glb.nist.gov.
+in.emachines.com.
+intelligented.com.
+allencanning.com.
+110.27.205.187.in-addr.arpa.
+cdn.adnxs.com.
+oq-smtp02.rutgers.edu.
+accentpaper.ru.
+twitter.com.
+equip.ru.
+www.mumosengen.com.
+primerosauxilioscomunidad.blogspot.com.
+_ldap._tcp.dc._msdcs.nextiraone.com.mx.
+c.betrad.com.
+www.facebook.com.
+www.yjeverlasting.com.
+146.68.225.190.in-addr.arpa.
+brandfundamentals.com.
+www.clivebarker.info.
+plusone.google.com.
+218.134.211.201.in-addr.arpa.
+180.7.56.187.in-addr.arpa.
+pjstar.eviesays.com.
+a.root-servers.net.
+ms.ferr.ru.
+photos-e.ak.fbcdn.net.
+api.twitter.com.
+nueterra.com.s9b1.psmtp.com.
+gpuac.org.
+www.google.com.
+idpix.media6degrees.com.
+pho3nix-bf.deviantart.com.
+us.mc656.mail.yahoo.com.
+pop3.hot.glbdns.microsoft.com.
+fwl-tv.foroes.org.
+a6.sphotos.ak.fbcdn.net.
+radiusadvisors.com.inbound15.mxlogicmx.net.
+ads.yimg.com.
+dehoy.blogspot.com.
+a.root-servers.net.
+artisanent.com.
+www.torrentflux.com.
+mangahentai.org.com.
+ddi.com.
+aeroexchange.aerocontrolex.com.
+e-stud.vgtu.lt.
+wpad.
+a.root-servers.net.
+120.47.139.190.in-addr.arpa.
+www.zueiai.net.
+21.142.242.109.in-addr.arpa.
+m.facebook.com.
+static.ak.fbcdn.net.
+www.tysknews.com.
+elfriorock.com.
+prensalibre.d.xx.openx.com.akadns.net.
+db._dns-sd._udp.lan.
+updateext.services.openoffice.org.
+www.leedeelive.com.
+ssl.google-analytics.com.
+acpimc2b.pancanal.com.
+7ch826l9y.u54f5u6d.
+ikuzoanime.com.
+connect.facebook.net.
+clwebb.com.
+www.google.com.
+queensu.ca.
+profootballhof.com.
+stairs4u.com.
+loading4.widdit.com.
+92.71.55.65.in-addr.arpa.
+discountchristmasshop.com.
+atmofresh.ru.
+lasermax.com.
+www.youtube.com.
+212.220.168.192.in-addr.arpa.
+japattack.com.
+faceboooklikes.com.
+120.134.158.175.in-addr.arpa.
+a1.sphotos.ak.fbcdn.net.
+www.mtv.bumeran.com.ar.
+shiptoshore.com.
+s-static.ak.facebook.com.
+cpleft.com.
+www.google.ae.
+www.nuevoplaneta.com.
+37.165.152.189.in-addr.arpa.
+mail2.cocoplans.com.
+a5.sphotos.ak.fbcdn.net.
+twitter.com.
+tc.v19.cache6.c.youtube.com.
+accounts.google.com.
+swm-eu.com.s200a1.psmtp.com.
+217.74.69.189.in-addr.arpa.
+m.facebook.com.
+240.81.151.186.in-addr.arpa.
+vira.biz.
+a2.twimg.com.
+djsolo.ru.
+photos-h.ak.fbcdn.net.
+115.19.194.187.in-addr.arpa.
+a.root-servers.net.
+132.54.171.209.in-addr.arpa.
+213.234.100.78.in-addr.arpa.
+ak.imgfarm.com.
+www.scentoflife.com.au.
+time.nist.gov.
+quality-plumbing.net.
+www.subpelis.info.
+clock.isc.org.
+comcast.net.
+mail.
+db._dns-sd._udp.0.1.168.192.in-addr.arpa.
+190.161.166.190.in-addr.arpa.
+a.root-servers.net.
+a1402.w40.akamai.net.
+207.240.183.66.in-addr.arpa.
+b.scorecardresearch.com.
+28.66.179.187.in-addr.arpa.
+us.data.toolbar.yahoo.com.
+www.mondo-libero.eu.
+freedomloansolutions.com.
+a.root-servers.net.
+books.google.com.
+r._dns-sd._udp.lan.
+www.facebook.com.
+sites.google.com.
+245.102.55.157.in-addr.arpa.
+xp.yimg.com.
+_979_76_7.
+226.242.43.190.in-addr.arpa.
+htmortgage.net.
+www.fotothing.com.
+www.youtube.com.
+114.174.208.202.in-addr.arpa.
+www.jogosdomario.tk.
+www.asos.com.
+0-jg-w.channel.facebook.com.
+kobold.stu.neva.ru.
+switch.atdmt.com.
+myfunnyfamily.com.
+102.207.82.200.in-addr.arpa.
+41.9.219.108.in-addr.arpa.
+_786_44_2.
+a4.sphotos.ak.fbcdn.net.
+mscrl.microsoft.com.
+platform.ak.fbcdn.net.
+pagead2.googlesyndication.com.
+jp.loobiz.com.
+asktoolbar.weather.com.
+kyungbock.net.
+static.ak.fbcdn.net.
+www.moneymanagement.com.au.
+www.xrxgsn.com.
+www.hdtvtunerinfo.com.
+www.adobe.com.
+csi.gstatic.com.
+sos-dan.ru.
+alerts.conduit-services.com.
+109.246.112.187.in-addr.arpa.
+www.alarabiya.net.
+www.espncricinfo.com.
+32.wap517.biz.
+www.stardoll.com.
+eg4y:eolc.60un.
+190.141.253.201.in-addr.arpa.
+phvids.voxcdn.com.
+criminologiamentescriminales.blogspot.com.
+dns.msftncsi.com.
+89.244.177.187.in-addr.arpa.
+117.53.41.77.in-addr.arpa.
+ns3.domain24.de.
+_869_58_5.
+www.textsrv.com.
+service.gc.apple.com.
+erreway.net.ru.
+www.facebook.com.
+herramientas.bbmundo.com.
+mail.modia.com.
+cix.co.kr.
+acs-it.ru.
+18.204.61.81.in-addr.arpa.
+fr-fr.facebook.com.
+24.media.tumblr.com.
+api.twitter.com.
+get.adobe.com.
+50.43.137.175.in-addr.arpa.
+167.250.111.190.in-addr.arpa.
+conair.com.
+backup-spool.iccx.net.
+te.en.alibaba.com.
+profile.ak.fbcdn.net.
+247.171.16.88.in-addr.arpa.
+www.contractorcalculator.co.uk.
+blog51.fc2.com.
+mail.narvajoesuu.ru.
+www9.effectivemeasure.net.
+exch.winwardsilks.com.
+53.13.198.187.in-addr.arpa.
+a4.sphotos.ak.fbcdn.net.
+233.36.173.201.in-addr.arpa.
+49.187.171.187.in-addr.arpa.
+market.android.com.
+estj.msn.com.
+248.74.173.190.in-addr.arpa.
+rss.com.com.
+lh3.googleusercontent.com.
+ributionapplyt.fm.
+livefiles18.vo.msecnd.net.
+r955totyv.92po.
+26.32.60.187.in-addr.arpa.
+d-e-n-e-g.net.ru.
+www.correiomagico.com.
+ssl.gstatic.com.
+127.0.0.1.
+wechslerbecker.com.
+photos-c.ak.fbcdn.net.
+ad.reachjunction.com.
+db._dns-sd._udp.0.2.168.192.in-addr.arpa.
+mta6.am0.yahoodns.net.
+ads.bluelithium.com.
+173.250.197.217.in-addr.arpa.
+img843.imageshack.us.
+delivery.trafficbroker.com.
+safebrowsing-cache.google.com.
+googleads.g.doubleclick.net.
+eatonhydraulics.com.
+dnl-01.geo.kaspersky.com.
+c.betrad.com.
+metcomm.net.
+www.breakdanceforum.de.
+www.abbywintersrocks.com.
+db._dns-sd._udp.0.1.168.192.in-addr.arpa.
+www.ecoanimal.com.
+click.icetraffic.com.
+liveupdate01.asus.com.
+a6.sphotos.ak.fbcdn.net.
+bloggerphotos.l.google.com.
+91.120.215.189.in-addr.arpa.
+www.tomsguide.fr.
+v9.nonxt4.c.pack.google.com.
+rcp.na.blackberry.com.
+lab3.lbt.nsk.ru.
+se.bing.com.
+www.toyotire.es.
+savetubevideo.com.
+billets-train-avion.vivastreet.fr.
+antarinith.blogspot.com.
+www.gstatic.com.
+a6.sphotos.ak.fbcdn.net.
+external.ak.fbcdn.net.
+ci.sherwood.or.us.s9b1.psmtp.com.
+google.com.
+l1.yimg.com.
+a.root-servers.net.
+home.mcafee.com.
+creative.ak.fbcdn.net.
+clients1.google.com.mx.
+166.44.251.190.in-addr.arpa.
+growingchild.com.
+www.moreemilk.com.
+17.38.25.88.in-addr.arpa.
+www.tepapa.govt.nz.
+waseca.copyleft.no.
+dsn1.d.skype.net.
+yahoo.download.vmn.net.
+api10.thetrafficstat.net.lan.
+243.240.141.201.in-addr.arpa.
+www.youtube.com.
+gim.net.
+pixel.facebook.com.
+199.82.172.187.in-addr.arpa.
+pixel.facebook.com.
+seify.ru.
+133.87.9.83.in-addr.arpa.
+71.56.244.189.in-addr.arpa.
+233.248.200.112.in-addr.arpa.
+www.saopauloguide.travel.
+picsart.com.
+sofla.com.
+televisa.esmas.com.
+trinaturk.com.
+www.dailyhotties.com.
+concordenterprises.com.
+www.ll.com.
+profile.ak.fbcdn.net.
+pix04.revsci.net.
+www.bywifi.com.
+7fdykzmvc.24wz.
+static-96-234-151-89.bltmmd.fios.verizon.net.
+s-external.ak.fbcdn.net.
+time.stdtime.gov.tw.
+photos-b.ak.fbcdn.net.
+api.autocompleteplus.com.
+a6.sphotos.ak.fbcdn.net.
+www.mininova.org.
+www.toy-wave.com.
+ctcpk8:tz.p06b2k5h.
+81.27.29.186.in-addr.arpa.
+96.98.102.201.in-addr.arpa.
+content.yieldmanager.edgesuite.net.
+137.173.167.74.in-addr.arpa.
+css.healthkicker.com.
+musikexpress.de.
+www.optimedia.es.
+creative.ak.fbcdn.net.
+f.facemoods.com.
+ymlp266.net.
+www.yamahamotos.cl.
+apis.google.com.
+ohsofab.com.
+computersplace.net.
+adslmail.es.
+www.yildiz.edu.tr.
+247.215.184.81.in-addr.arpa.
+googleads.g.doubleclick.net.
+sito-stal.ru.
+gac.edu.
+twitter.com.
+dress-proffi.ru.
+www.hot-files.net.
+a2.sphotos.ak.fbcdn.net.
+i3.ytimg.com.
+mail.lumusnet.com.
+symbolism.wikia.com.
+ad.yieldmanager.com.
+www.insurance.com.
+www3.snapfish.co.uk.
+www.honeymag.com.
+cdn.api.twitter.com.
+133.198.127.200.in-addr.arpa.
+cnilink.com.
+92.166.232.190.in-addr.arpa.
+encyclopediaurantia.org.
+a.root-servers.net.
+www.lengua.profes.net.
+greek-recipe.blogspot.com.
+js.fengwu.net.
+193.97.173.189.in-addr.arpa.
+mscrl.microsoft.com.
+static.ak.fbcdn.net.
+201-43-30-122.dsl.telesp.net.br.
+photos-c.ak.fbcdn.net.
+pagead2.googlesyndication.com.
+65.43.35.99.in-addr.arpa.
+135.152.157.190.in-addr.arpa.
+profile.ak.fbcdn.net.
+cdn.loading321.com.
+viajarencruceros.com.
+plusone.google.com.
+a-0.19-2109e041.5020082.1518.19d4.3ea1.400.0.is7mmqtl93n5sfff22b8e4dvvq.avqs.mcafee.com.
+161.37.35.189.in-addr.arpa.
+a.root-servers.net.
+42.133.52.190.in-addr.arpa.
+platform.twitter.com.
+124.185.27.189.in-addr.arpa.
+omsd.k12.ca.us.
+photos-f.ak.fbcdn.net.
+www.turnto23.com.
+apps.facebook.com.
+lp.live.monsters.wooga.com.
+b._dns-sd._udp.0.1.168.192.in-addr.arpa.
+172.176.5.117.in-addr.arpa.
+widgets.montiera.com.
+ja.wikipedia.org.
+basoscomunicantes.blogspot.com.
+setting3.yeahost.com.
+tsm04.eset.com.
+ulaex.cu.
+add.bugun.com.tr.
+ultimarealestate.com.
+_946_47_8.
+www.adobe.com.
+chhg.biz.
+googleads.g.doubleclick.net.
+www.facebook.com.
+portal.avaya-news.com.
+msg-01-0802.vetonaula.fi.
+a.root-servers.net.
+_295_92_7.
+l.d.
+server.iad.liveperson.net.
+crl.microsoft.com.
+a8.sphotos.ak.fbcdn.net.
+graphicsys.com.
+22.200.20.186.in-addr.arpa.
+liveupdate.symantecliveupdate.com.
+u35.eset.com.
+www.theshemaleorgy.com.
+ford.co.
+a.root-servers.net.
+freelotto.com.
+145.180.181.190.in-addr.arpa.
+blu124.mail.live.com.
+gfx1.hotmail.com.
+lh3.ggpht.com.
+64.6.203.24.in-addr.arpa.
+platform.ak.fbcdn.net.
+revistatejido.blogspot.com.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+denis.stalker.h3q.com.
+igloodesign.net.
+solihullsfc.ac.uk.
+teredo.ipv6.microsoft.com.
+104.5.55.186.in-addr.arpa.
+100.101.168.192.in-addr.arpa.
+www.baincapital.com.
+sp.edu.sg.
+sencolatinamerica.com.s6b1.psmtp.com.
+friendsinwar.com.
+a995.mm1.akamai.net.
+mail.cyberdom.ru.
+41.30.56.85.in-addr.arpa.
+dr._dns-sd._udp.0.2.168.192.in-addr.arpa.
+android.clients.google.com.
+a7.sphotos.ak.fbcdn.net.
+www.askamum.co.uk.
+img2.blogblog.com.
+bel-net.ru.
+0-74.channel.facebook.com.
+bttracker.debian.org.
+ws.amazon.com.
+60.91.153.189.in-addr.arpa.
+cdn.api.twitter.com.
+ow.ly.
+www.google-analytics.com.
+133.193.213.83.in-addr.arpa.
+97.222.156.190.in-addr.arpa.
+api.twitter.com.
+orcart.facebook.com.
+simssoc.game.playfish.com.
+external.ak.fbcdn.net.
+crl.microsoft.com.
+www.lombards.com.au.
+a.root-servers.net.
+nino.ru.
+luzete.com.
+www.formspring.me.
+t3.gstatic.com.
+chgz.ru.
+53.48.54.65.in-addr.arpa.
+www.escolar.com.mx.
+www.lookandfeelbetter.com.
+wer.microsoft.com.
+kristynenapiolina.blogspot.com.
+s.youtube.com.
+about-diving.ch.
+s.ytimg.com.
+mail.sunyjcc.edu.
+photos-b.ak.fbcdn.net.
+mail.sleekcom.com.
+a3.sphotos.ak.fbcdn.net.
+apple.com.
+www.ultrarun.es.
+tr0.ds.ignames.net.
+158.17.228.189.in-addr.arpa.
+167.225.49.96.in-addr.arpa.
+br.fling.com.
+fbcdn-sphotos-a.akamaihd.net.
+thebigtv.com.
+a-0.19-a7091081.e0b0083.1518.19d3.3ea1.410.0.vmlhtvjuflgiddme6imndigcd6.avqs.mcafee.com.
+139.107.49.190.in-addr.arpa.
+_052_36_2.
+.
+buzznet-76.vo.llnwd.net.
+rad.msn.com.
+photos-g.ak.fbcdn.net.
+www.christiansanchini.com.
+f8ej9:w9k.f41q7l9u.
+us1.badoo.com.
+a4.sphotos.ak.fbcdn.net.
+tempurga.blogspot.com.
+207.51.132.190.in-addr.arpa.
+www.statcounter.com.
+a.root-servers.net.
+12mdosa.tk.
+static.ak.fbcdn.net.
+photos-d.ak.fbcdn.net.
+themes.googleusercontent.com.
+beccue.com.
+a1.sphotos.ak.fbcdn.net.
+a4.sphotos.ak.fbcdn.net.
+113.80.137.66.in-addr.arpa.
+us.andronavi.com.
+everybody.ru.
+213.52.232.190.in-addr.arpa.
+a.root-servers.net.
+se.itunes.apple.com.
+www.sindicalistas.net.
+distrowatch.org.
+hotmail.com.
+www.hotmail.com.
+www.adgame.co.kr.
+94.139.18.187.in-addr.arpa.
+www.smi.ru.
+a7.sphotos.ak.fbcdn.net.
+www.visitstockholm.com.
+profile.ak.fbcdn.net.
+a.root-servers.net.
+peru.com.
+surfrider.org.inbound15.mxlogic.net.
+spynet2.microsoft.com.
+www.locurajuegos.com.
+sp.ask.com.
+a.root-servers.net.
+nf.net.
+147.150.254.188.in-addr.arpa.
+pool.ntp.org.home.
+i1.ytimg.com.
+37.163.27.201.in-addr.arpa.
+ssl.gstatic.com.
+cpl.net.
+filologocfa.blogspot.com.
+s.ytimg.com.
+.
+www.ucarshare.com.
+9.198.31.190.in-addr.arpa.
+googleads.g.doubleclick.net.
+photoshop.nl.malavida.com.
+google.com.
+a2.sphotos.ak.fbcdn.net.
+www.google-analytics.com.
+a.root-servers.net.
+smtp.rimamfg.com.
+m.facebook.com.
+www.laboratoriodeconcienciadigital.com.
+apps.facebook.com.
+myculture.tumblr.com.
+www.wdc.com.
+183.118.18.187.in-addr.arpa.
+mail.wfmcdonald.com.
+m.addthisedge.com.
+luminouslogic.com.
+228.48.94.186.in-addr.arpa.
+wssecmgr2.atlanta.hp.com.
+pixel.facebook.com.
+25.27.167.190.in-addr.arpa.
+ksn2.kaspersky-labs.com.
+cs303208.vk.com.
+beta.data.toolbar.yahoo.com.
+32.169.6.200.in-addr.arpa.
+114.181.112.99.in-addr.arpa.
+frenital.byu.edu.
+dns.msftncsi.com.
+x18q2wii6.54nc.
+shiruva.files.wordpress.com.
+www.facebook.com.
+e3353.c.akamaiedge.net.
+server.cpmstar.com.
+a4.sphotos.ak.fbcdn.net.
+www.oribesalon.com.
+www.waraqat.net.
+ritual-nfl.aztecadeportes.com.
+ntzxot6hp.z36u6h4l.
+yahoonimbuz.com.
+widgets.twimg.com.
+mail.rsdcmi.com.
+profile.ak.fbcdn.net.
+www.opcionempleo.com.mx.
+api.twitter.com.
+sp.cwfservice.net.
+a1.sphotos.ak.fbcdn.net.
+a.root-servers.net.
+digitalpaper.com.
+3ae1mc4rm4e9l.c.yom.mail.yahoo.com.
+static.4shared.com.
+mail.asltg2.com.
+hsi-kbw-134-3-251-55.hsi14.kabel-badenwuerttemberg.de.
+mediacdn.disqus.com.
+tctechcrunch2011.files.wordpress.com.
+ksn1-12-part1.kaspersky-labs.com.
+a.root-servers.net.
+ar.wikipedia.org.
+checkip.dyndns.org.
+mail.ausapts.com.
+resolver1.bullguard.ctmail.com.
+194.5.139.189.in-addr.arpa.
+www.el-nacional.com.
+mediennetzwerk.de.
+mail.google.com.
+platform.twitter.com.
+lavidadehugo.blogspot.com.
+s.ytimg.com.
+zapatosmoda.org.
+thedenimguy.com.
+s.ytimg.com.
+38.204.7.189.in-addr.arpa.
+a4.sphotos.ak.fbcdn.net.
+232.249.114.186.in-addr.arpa.
+clients4.google.com.
+www.gentedlsur.blogspot.com.
+plus.google.com.
+230.246.67.201.in-addr.arpa.
+238.68.166.190.in-addr.arpa.
+tiscali.fr.
+android.clients.google.com.
+camptowanda.com.
+angieliddiard.scentsy.us.
+www.facebook.com.
+_320_63_9.
+cdn.api.twitter.com.
+m.cxt.ms.
+m.addthisedge.com.
+seg.sharethis.com.
+33.74.50.186.in-addr.arpa.
+www.hoe1.com.
+player2.narrowstep.tv.
+www.mercadolibre.com.mx.
+a6.sphotos.ak.fbcdn.net.
+www.d943b904.com.
+api.twitter.com.
+bayworldmfg.com.
+ax.init.itunes.apple.com.
+developers.facebook.com.
+p4mlnulls.53ki.
+mail3.demirdokum.ru.
+www.grisb.org.
+www.l.google.com.
+vikont-spb.ru.
+thesystemis.com.
+lj.libraryjournal.com.
+154.152.252.180.in-addr.arpa.
+www.ziggysgames.com.
+twitter.com.
+www.deadlydarling.tumblr.com.
+shedmediaus.com.inbound15.mxlogic.net.
+teredo.ipv6.microsoft.com.
+www.mercadopago.com.br.
+www.chatbazaar.com.
+www.solovenezolanas.com.
+photos-e.ak.fbcdn.net.
+www.cityoforlando.net.
+224.237.101.109.in-addr.arpa.
+megustavivirlavida.blogspot.com.
+ar.games.yahoo.com.
+www.google.com.
+www.youtube.com.
+mail2.ostling.com.
+s.youtube.com.
+photos-e.ak.fbcdn.net.
+165.221.33.176.in-addr.arpa.
+sp.ask.com.
+50.61.117.91.in-addr.arpa.
+ajax.googleapis.com.
+1.gravatar.com.
+es.wikipedia.org.
+mailhostrdc.aptiumoncology.com.
+www.yellbox.com.
+www.elpais.com.
+www.youth-guard.org.
+bmxxx.notengodominio.com.
+kaboomtune.com.
+www.facebook.com.
+d11777b.ess.barracudanetworks.com.
+153.226.106.189.in-addr.arpa.
+de-de.facebook.com.
+m.facebook.com.
+regionlimanoticias.com.
+www.google-analytics.com.
+hbw:79a9x.g50b5u8m.
+ksn2-12.kaspersky-labs.com.
+centrodiseno.com.
+iitx.com.
+ofertasonlineweb.com.
+resolver2.gdata.ctmail.com.
+d:atmd872.o16p4h5x.
+a4.sphotos.ak.fbcdn.net.
+6.41.252.201.in-addr.arpa.
+latam.msn.com.
+hardcorejkd.com.
+hermes.marketmetrix.com.
+187.35.20.190.in-addr.arpa.
+www.facebook.com.
+rt1401.infolinks.com.
+ww2.arthritis.org.
+176.150.106.124.in-addr.arpa.
+delcogeneralcontractors.com.
+101.86.37.186.in-addr.arpa.
+itunes.apple.com.
+www.deanjrobinson.com.
+static.4shared.com.
+s.imwx.com.
+ssl.gstatic.com.
+a1757.g.akamai.net.
+150.206.110.189.in-addr.arpa.
+a1408.w43.akamai.net.
+mariaelisacrochet.blogspot.com.
+voipc.sip.yahoo.com.
+79.151.14.98.in-addr.arpa.
+iwon.com.
+64.6.194.190.in-addr.arpa.
+optimized-by.rubiconproject.com.
+tc.v3.cache3.c.pack.google.com.
+ads2.msads.net.
+a5.sphotos.ak.fbcdn.net.
+anku-aruma.blogspot.com.
+photos-a.ak.fbcdn.net.
+www.dcsea.uqroo.mx.
+a7.sphotos.ak.fbcdn.net.
+billing.sharo4ka.ru.
+a6.sphotos.ak.fbcdn.net.
+www.mejoramos.com.
+www.facebook.com.
+s-static.ak.facebook.com.
+translate.google.com.
+a7.sphotos.ak.fbcdn.net.
+zk44vlvx8.65pa.
+197.226.131.187.in-addr.arpa.
+chichismusings.blogspot.com.
+safebrowsing.clients.google.com.
+11.186.31.99.in-addr.arpa.
+_163_60_7.
+ping3.teamviewer.com.
+www.philosophytogo.org.
+v10.nonxt4.c.pack.google.com.
+de-de.facebook.com.
+156.176.5.189.in-addr.arpa.
+a.root-servers.net.
+ssl.gstatic.com.
+gay-lesbianas.vivavisos.com.ar.
+external.ak.fbcdn.net.
+d2108043.xoom.it.
+es-la.facebook.com.
+s.ytimg.com.
+colorysabor.blogspot.com.
+mediatecpub.com.
+gala-shop.ru.
+www.power-21.com.
+a.root-servers.net.
+66.243.188.189.in-addr.arpa.
+www.facebook.com.
+92.217.19.186.in-addr.arpa.
+starinsur.com.
+a8.sphotos.ak.fbcdn.net.
+o.imgbox.com.
+17.131.128.186.in-addr.arpa.
+maxfreund.files.wordpress.com.
+74.164.30.78.in-addr.arpa.
+www.uncontactedtribes.org.
+photos-f.ak.fbcdn.net.
+www.interlinkeo.com.
+sebastiancorp.net.
+0.0.0.0.
+sexualidad.es.msn.com.
+www.athmg.com.
+us.i1.yimg.com.
+ksn2-12.kaspersky-labs.com.
+www.misfrases.org.
+www.facebook.com.
+www.trainsonthebrain.com.
+relay2.terranet.ru.
+ksn2-12.kaspersky-labs.com.
+direxpo.com.
+photos-c.ak.fbcdn.net.
+www.danceradio.es.
+csi.gstatic.com.
+116.203.214.186.in-addr.arpa.
+shanaflare.minitokyo.net.
+_270_92_7.
+24.159.244.67.in-addr.arpa.
+a997.mm1.akamai.net.
+vostokms.ru.
+cignethealth.com.
+kimochiii.foroes.net.
+forums.mi6-hq.com.
+guestbooks.pathfinder.gr.
+www.google.com.
+www.fullchristmas.com.
+nullmx.mcshi.com.
+checkip.dyndns.org.
+craftolution.ru.
+188.194.141.201.in-addr.arpa.
+inc.com.s8a1.psmtp.com.
+www.google.com.
+190.76.115.186.in-addr.arpa.
+mail1.qmiaw.com.
+107.161.6.189.in-addr.arpa.
+a11.t26.net.
+rchsd.org.
+grindrguy.com.s3.amazonaws.com.
+bodyforlife-tracker.com.
+www.v-like-vintage.net.
+breakthu.com.
+redfaceplus.com.
+www.google.com.
+gofree.indigo.ie.
+a8.sphotos.ak.fbcdn.net.
+s10.histats.com.
+googleads.g.doubleclick.net.
+casasbahia.com.
+primediacmmg.com.
+_863_43_0.
+137.204.229.189.in-addr.arpa.
+tradetang.com.
+www.mixx.com.
+tmail.com.
+www.facebook.com.
+photos-b.ak.fbcdn.net.
+www.eluniversaltv.com.mx.
+contextmenu.toolbar.conduit-services.com.
+zonacine.uservoice.com.
+itx5.smartadserver.com.
+slhtobit01.shangri-la.com.
+s10.histats.com.
+www.twenga.nl.
+www.hsbc.com.mx.
+youtubebajar.chatango.com.
+meetingmillionares.com.
+lb._dns-sd._udp.0.137.168.192.in-addr.arpa.
+www.funnypenispictures.com.
+sadiegen.blogspot.com.
+vcs2.msg.yahoo.com.
+smtp.fianzasmonterrey.com.mx.
+chelvis.3x.ro.
+a.root-servers.net.
+16.110.139.205.in-addr.arpa.
+cloud-q.duba.net.
+dns.msftncsi.com.
+fhc.alphagammadelta.org.
+google.com.
+outlaw-hs.com.
+dco.nmbbm.jp.
+safebrowsing-cache.google.com.
+26.138.10.187.in-addr.arpa.
+geo.it.
+s.srvntrk.com.
+sites.google.com.
+mail.spiratex.com.
+sliddoors.ru.
+synacortoshiba.112.2o7.net.
+a1892.phobos.apple.com.
+photos-a.ak.fbcdn.net.
+www.guppies.com.
+www.uhs.edu.pk.
+77.21.235.98.in-addr.arpa.
+fbcdn-profile-a.akamaihd.net.
+torrent-download.to.
+33.190.63.69.in-addr.arpa.
+ntp.glb.nist.gov.
+www.brandsouthafrica.com.
+none.
+199.0.137.186.in-addr.arpa.
+i3.ytimg.com.
+mail.sboa.com.
+www.google.com.
+gj37765.blogspot.com.
+www.macstation.com.ar.
+css.lainformacionalsegundo.com.
+gfx4.hotmail.com.
+www.streaming-films.info.
+photos-h.ak.fbcdn.net.
+mail.kns.net.
+imap.gmail.com.
+alerts.conduit-services.com.
+skarevolution69.files.wordpress.com.
+google.com.
+b.scorecardresearch.com.
+www.tipsdrills.com.
+cdn-static.liverail.com.
+142.189.171.110.in-addr.arpa.
+freenet-reg-ripn.ru.
+download.cyberlink.com.
+static.ak.fbcdn.net.
+46.181.63.69.in-addr.arpa.
+a.root-servers.net.
+ayma.com.
+a.root-servers.net.
+v1.panthercdn.com.
+209.176.120.200.in-addr.arpa.
+travelprosinc.com.
+www.felixagm.es.
+sumisoporamor.blogspot.com.
+rfigroup.com.
+5.249.6.201.in-addr.arpa.
+img123.exs.cx.
+www.darktorrents.com.
+inbound.toyotawc.com.netsolmail.net.
+d2091958.xoom.it.
+a.root-servers.net.
+www.servicioscreativos.com.
+cdn.api.twitter.com.
+pix04.revsci.net.
+fbcdn-photos-a.akamaihd.net.
+a8.sphotos.ak.fbcdn.net.
+kastenchase.com.
+_705_61_8.
+www.digitalartscalifornia.com.
+c9uqhrli8.30aa.
+dns.msftncsi.com.
+a-0.19-210fb071.c880580.1518.19d3.3ea1.210.0.iia1lvgs7trinugwplwbbha5aq.avqs.mcafee.com.
+www.facebook.com.
+account.cancer.org.
+key-copy.ru.
+qvapotejat.com.
+profile.ak.fbcdn.net.
+a8.sphotos.ak.fbcdn.net.
+eoweqokc.org.
+www.facebook.com.
+0.static.ak.fbcdn.net.
+psicologiaymigracion.blogspot.com.
+www.blsclinic.com.
+mail.putnamco.org.
+15.180.145.201.in-addr.arpa.
+inbound.bwe-nc.com.netsolmail.net.
+metrocast.net.
+80.155.97.94.in-addr.arpa.
+m.facebook.com.
+_599_34_2.
+www.peeblesplay.com.
+www.bonusthemes.com.
+pr.prchecker.info.
+sms.siemens.com.
+hp.nknox.k12.in.us.
+teredo.ipv6.microsoft.com.
+www.nic.cd.
+252.218.212.116.in-addr.arpa.
+db._dns-sd._udp.0.1.168.192.in-addr.arpa.
+a6.sphotos.ak.fbcdn.net.
+dbzepisodeorg.chatango.com.
+api.twitter.com.
+m.hotmail.com.
+dnl-01.geo.kaspersky.com.
+r.nexac.com.
+www.google-analytics.com.
+caglesinc.com.
+nickthompson.com.
+tools.google.com.
+a2.sphotos.ak.fbcdn.net.
+dualstack.ipv6-exp.l.google.com.
+oliveoil.wholesaleonlineweb.com.
+17.159.253.190.in-addr.arpa.
+www.wmitechnologies.com.
+sites.google.com.
+margulies.com.inbound15.mxlogic.net.
+a5.sphotos.ak.fbcdn.net.
+albionauto.ru.
+webres2.bullguard.ctmail.com.
+bowietownmedical.com.
+www.problemsolving.net.
+themoneyconverter.com.
+148.147.176.190.in-addr.arpa.
+pvp.com.
+9.173.204.190.in-addr.arpa.
+a7.sphotos.ak.fbcdn.net.
+cust22764-1.in.mailcontrol.com.
+www.udelas.ac.pa.
+113.15.39.187.in-addr.arpa.
+hzrcoq8ih.10no.
+external.ak.fbcdn.net.
+shadow.mature.nl.
+profile.ak.fbcdn.net.
+blog.formspring.me.
+17.177.105.186.in-addr.arpa.
+a.root-servers.net.
+no-one.com.
+rs543l35.rapidshare.com.
+210.203.206.186.in-addr.arpa.
+time-nw.nist.gov.
+46.229.34.189.in-addr.arpa.
+a-0.19-2709a081.99c0083.1518.19c2.3ea1.210.0.aktazdp51b34gma5pp33cfbhh5.avqs.mcafee.com.
+veksel.komitex.ru.
+www.christandpopculture.com.
+mt1.google.com.
+tap2-cdn.rubiconproject.com.
+a.root-servers.net.
+teredo.ipv6.microsoft.com.
+www.facebook.com.
+sp.cwfservice.net.
+www.adtool.de.
+arielluque.blogspot.com.
+133.226.27.190.in-addr.arpa.
+api.twitter.com.
+a.root-servers.net.
+168.158.218.186.in-addr.arpa.
+avin02.melange.net.
+gecits.com.
+casscomm.com.s9b2.psmtp.com.
+www.feedcat.net.
+dns.msftncsi.com.
+tegam.com.
+mx.dlls.pa.frontiernet.net.
+127.92.9.81.in-addr.arpa.
+static.ak.fbcdn.net.
+loc1.eu1.badoo.com.
+m.addthisedge.com.
+orfodpc985862.sh.marrcorp.marriott.com.
+view.atdmt.com.
+a.root-servers.net.
+fdsn0.skype.net.
+www.spermed.net.
+aka-cdn-ns.adtech.de.
+trac.qutecom.org.
+www.amanngirrbach.com.
+ads.iforex.com.
+photos-f.ak.fbcdn.net.
+i3.ytimg.com.
+periodico.morelos.gob.mx.
+s4.histats.com.
+saillavka.ru.
+ced.sascdn.com.
+71.96.85.77.in-addr.arpa.
+a2.sphotos.ak.fbcdn.net.
+123-outlook-express-backup.programas-gratis.net.
+155.108.168.192.in-addr.arpa.
+accounts.google.com.
+app.reg.techweb.com.
+a.root-servers.net.
+138.230.69.94.in-addr.arpa.
+245.245.135.188.in-addr.arpa.
+4:9nrmxww.i31g1n2l.
+bedewsd01.npsp.com.
+eun.org.
+a2.sphotos.ak.fbcdn.net.
+26.79.179.189.in-addr.arpa.
+c1.tacdn.com.
+tags.crwdcntrl.net.
+ocsp.verisign.com.
+lacocinademiabue.blogspot.com.
+jp.123rf.com.
+randewy.ru.
+www.google.com.
+eligrey.com.
+dezcom.ru.
+a.root-servers.net.
+revolutionmedia.ign.com.
+sc6.rules.mailshell.net.
+www.pauldewar.ca.
+external.ak.fbcdn.net.
+fp3.wg1.b.yahoo.com.
+meroo.polyvore.com.
+zitomedia.com.
+support.google.com.
+a6.sphotos.ak.fbcdn.net.
+amer.rel.msn.com.
+a.root-servers.net.
+impact-in.jobstreet.com.
+www.facebook.com.
+142.27.82.201.in-addr.arpa.
+a.root-servers.net.
+118.85.191.186.in-addr.arpa.
+1.0.0.127.dnsbugtest.1.0.0.127.in-addr.arpa.
+photos-g.ak.fbcdn.net.
+246.239.86.67.in-addr.arpa.
+pogovorka.ru.
+ustarb001ads.ww005.siemens.net.med.siemens.de.
+www.google.com.
+platform.ak.fbcdn.net.
+53.160.166.190.in-addr.arpa.
+a.root-servers.net.
+external.ak.fbcdn.net.
+120.26.250.188.in-addr.arpa.
+191.84.108.71.in-addr.arpa.
+i1.ytimg.com.
+profile.ak.fbcdn.net.
+a1.sphotos.ak.fbcdn.net.
+api.airpush.com.
+104.25.225.190.in-addr.arpa.
+a.root-servers.net.
+www.tomrobinsonphotography.com.
+es.answers.yahoo.com.
+photos-h.ak.fbcdn.net.
+a5.sphotos.ak.fbcdn.net.
+searchclient.live.net.
+a3.sphotos.ak.fbcdn.net.
+mail.thplastics.com.
+www.youtube.com.
+www.myconnectfm.com.
+236.241.174.190.in-addr.arpa.
+datafirst.fr.
+s-static.ak.facebook.com.
+sites.google.com.
+fm-realty.com.
+p1t.ru.
+cs953.vk.com.
+www.mariaauxiliadora.org.mx.
+apple-pie.in.
+on24.com.dnsbl7.mailshell.net.
+safebrowsing-cache.google.com.
+a.root-servers.net.
+25.media.tumblr.com.
+mail1.jandp.com.sa.
+connect.facebook.net.
+te10.kontera.com.
+s10.histats.com.
+www.facebook.com.
+www.google.com.
+a.root-servers.net.
+bt-service.ru.
+images2.memegenerator.net.
+23.10.43.186.in-addr.arpa.
+www.facebook.com.
+www.organizatusviajes.com.
+tvcsp.com.
+146.16.0.192.in-addr.arpa.
+84.156.113.190.in-addr.arpa.
+fbcdn-photos-a.akamaihd.net.
+amdc-smp01.intranet.mckinsey.com.
+39.51.252.201.in-addr.arpa.
+seg.p.sharethis.com.akadns.net.
+photos-e.ak.fbcdn.net.
+klaus-schimanski.de.
+creative.ak.fbcdn.net.
+36.139.94.190.in-addr.arpa.
+vogdesigns.com.
+a.root-servers.net.
+mattters.com.
+thefinecut.blogspot.com.
+echo.edge.messenger.live.com.
+48-courier.push.apple.com.
+google.com.
+0-38.channel.facebook.com.
+mx2.mcn.org.gslb.pphosted.com.
+static.ak.fbcdn.net.
+a.root-servers.net.
+ocsp.thawte.com.
+a7.sphotos.ak.fbcdn.net.
+webcache.googleusercontent.com.
+a.root-servers.net.
+magicphotoshop.com.
+shelbygt500review.com.
+www.comparere.com.
+css.wlxrs.com.
+.
+a2.sphotos.ak.fbcdn.net.
+a5.sphotos.ak.fbcdn.net.
+img862.imageshack.us.
+24.134.44.62.in-addr.arpa.
+askville.amazon.com.
+msgr.updates.yahoo.com.
+b._dns-sd._udp.0.1.168.192.in-addr.arpa.
+140.47.66.189.in-addr.arpa.
+seoul.fm.
+130.178.94.208.in-addr.arpa.
+ads.genericlink.com.
+64.129.8.87.in-addr.arpa.
+img5.joyreactor.ru.
+macmiller.com.
+photos-d.ak.fbcdn.net.
+dem0003.in.
+35.160.160.186.in-addr.arpa.
+files.discountechnology.com.
+fxfeeds.mozilla.com.
+www.submitblognow.info.
+fbcdn-sphotos-a.akamaihd.net.
+mannyzoom.com.
+accounts.google.com.
+epost.fo.
+sp.cwfservice.net.
+ksn2-12.kaspersky-labs.com.
+91.123.138.201.in-addr.arpa.
+s1-word-view.vo.msecnd.net.
+www.heredis.com.
+vblk3mtfy.52vq.
+217.214.10.187.in-addr.arpa.
+arizona.diamondbacks.mlb.com.
+blog.bjrn.se.
+thefamousgroup.com.1.0001.arsmtp.com.
+www.drtuber.com.
+genesis.1337x.org.
+static.ak.fbcdn.net.
+axnvmip7g.b81y9j5m.
+mx.astrology.yahoo.com.
+photos-d.ak.fbcdn.net.
+136.254.38.180.in-addr.arpa.
+bay.gateway.messenger.live.com.
+_259_22_6.
+js.wlxrs.com.
+imagess.ru.
+www.facebook.com.
+a.root-servers.net.
+www.netmanager.com.br.
+juventudxhardcore.blogspot.com.
+106.52.8.200.in-addr.arpa.
+111.170.18.95.in-addr.arpa.
+a7.sphotos.ak.fbcdn.net.
+mail.telecomholdings.com.
+smtp.kclife.com.
+ksn2-12.kaspersky-labs.com.
+webcache.googleusercontent.com.
+6zuqsydog.m92s2p6l.
+pagead2.googlesyndication.com.
+www.hon.com.
+ssl.google-analytics.com.
+inbound.capitolmed.com.netsolmail.net.
+cs505502.vkontakte.ru.
+144.86.194.187.in-addr.arpa.
+astroline.ru.
+www.marco.org.mx.
+tracker.xpear.de.
+mediacdn.disqus.com.
+azorero.blogspot.com.
+www.shockmd.com.
+mx1.pspvodka.ru.
+platform.twitter.com.
+s0.2mdn.net.
+twitter.com.
+a.root-servers.net.
+www.massnurses.org.
+com.imangi.s3-website-us-east-1.amazonaws.com.
+173.230.195.187.in-addr.arpa.
+a.root-servers.net.
+www.trackmusic.com.ar.
+www.md-dui-defense.com.
+1.119.223.189.in-addr.arpa.
+elmundomagicode-reina.blogspot.com.
+frases.eslamoda.com.
+mail.bluetie.com.
+ad.adnetwork.net.
+tr.adinterax.com.
+static-1.farmville.zgncdn.com.
+apps.facebook.com.
+www.top50dancepop.es.
+google.com.
+ktrailer.blogspot.com.
+www.idiomascuc.com.
+ksn2-12.kaspersky-labs.com.
+mail.adpk.net.
+okc.mx0.rhinocommunications.net.
+secure.aolanswers.com.
+www.babeforums.org.
+s-static.ak.facebook.com.
+www.facebook.com.
+ns1.eu.bitnames.com.
+resolute-midatlantic.com.inbound15.mxlogic.net.
+18.48.101.189.in-addr.arpa.
+103.11.168.192.in-addr.arpa.
+sitelife.clarionledger.com.
+123.245.132.187.in-addr.arpa.
+fred-graichen.de.
+store.notionsmarketing.com.
+netrscape.net.
+www.google.com.
+3.0.168.192.in-addr.arpa.
+48.44.122.186.in-addr.arpa.
+1.0.168.192.in-addr.arpa.
+140.137.124.77.in-addr.arpa.
+www.itadvocate.com.au.
+xtra1.gpsonextra.net.
+29.91.160.24.in-addr.arpa.
+mail.google.com.
+a.root-servers.net.
+google.com.
+moboogie.com.
+sitecheck2.opera.com.
+ffrtrgfdf.com.
+ad.xtendmedia.com.
+photos-c.ak.fbcdn.net.
+www.google-analytics.com.
+21.13.67.213.in-addr.arpa.
+owensborograin.com.s8a1.psmtp.com.
+i2.ytimg.com.
+111.29.229.190.in-addr.arpa.
+a.root-servers.net.
+_836_57_2.
+1-0-1-0.category.programsbase.com.
+sunstone.com.
+228.141.254.77.in-addr.arpa.
+uplus.ru.
+static.ak.facebook.com.
+time.chttl.com.tw.
+guicci.ru.
+i.ytimg.com.
+photos-a.ak.fbcdn.net.
+cartoonnetwork.com.mx.
+d2ks4vnin.n76v8o6f.
+100.220.192.187.in-addr.arpa.
+althing.org.
+cmd.ru.
+lt3opi:pp.q33t2n6p.
+ecbldhaka.com.
+www.cht.in.
+www2.viamichelin.com.
+developers.facebook.com.
+gorbushina.ru.
+ocsp.verisign.com.
+sp.cwfservice.net.
+mob51.photobucket.com.
+google.com.
+www.facebook.com.
+ns1.relex.com.
+pagead2.googlesyndication.com.
+mx3.umflint.edu.
+chatcluster.scruffapp.com.
+www.youtube.com.
+keflog.com.
+swaroop.deviantart.com.
+46.159.106.177.in-addr.arpa.
+110.127.179.190.in-addr.arpa.
+a995.mm1.akamai.net.
+www.metronoticias.com.mx.
+a1.sphotos.ak.fbcdn.net.
+a.root-servers.net.
+www.twitter.com.
+252.155.102.41.in-addr.arpa.
+s-static.ak.facebook.com.
+ladygaga.wikia.com.
+i2.ytimg.com.
+www.calculopesoideal.com.
+graph.facebook.com.
+kidsrus.ru.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+rovio.appads.com.
+www.mrauto.cl.
+43.220.247.189.in-addr.arpa.
+199.18.115.189.in-addr.arpa.
+www.robertososa.com.mx.
+radi2.com.
+bangalicommunity.com.
+25.93.102.200.in-addr.arpa.
+rogers.com.
+apps.facebook.com.
+224.250.93.186.in-addr.arpa.
+186.106.145.187.in-addr.arpa.
+ak-media.soundcloud.com.
+www.peinadosycortes.com.
+92.20.100.157.in-addr.arpa.
+www.origamiseiten.de.
+www.barefootfoundation.com.
+www.imhc.mil.kr.
+bestsmileys.com.
+5.198.52.186.in-addr.arpa.
+id.google.com.mx.
+profile.ak.fbcdn.net.
+fpmccann.co.uk.
+mail.close.ru.
+d2060276.instant.xoom.it.
+s1-word-edit.vo.msecnd.net.
+pixel.facebook.com.
+61.187.127.200.in-addr.arpa.
+rad.msn.com.
+floridabuilderappliances.com.
+titanium30-en.url.trendmicro.com.
+diosrestauramatrimonios.blogspot.com.
+img100.xvideos.com.
+1.0.0.127.dnsbugtest.1.0.0.127.in-addr.arpa.
+130.181.29.88.in-addr.arpa.
+proxy-sn.contacts.msn.com.
+drw-milliman.com.
+www.motopartscenter.com.
+www.google.com.
+ols.systemofadown.com.
+a.root-servers.net.
+external.ak.fbcdn.net.
+59.34.178.190.in-addr.arpa.
+146.73.1.201.in-addr.arpa.
+photos-c.ak.fbcdn.net.
+69.133.13.186.in-addr.arpa.
+creative.ak.fbcdn.net.
+11.118.112.186.in-addr.arpa.
+teredo.ipv6.microsoft.com.
+bestbuytest.convertlanguage.com.
+gl.wikipedia.org.
+plus.google.com.
+time.stdtime.gov.tw.
+it.justin.tv.
+www.eroticperfection.com.
+go.microsoft.com.
+229.140.2.181.in-addr.arpa.
+jers1.info.
+static.ak.facebook.com.
+comm-2000.com.inbound10.mxlogic.net.
+cs5058.vkontakte.ru.
+www.apple-mac.cz.
+225.254.251.190.in-addr.arpa.
+static.app.widdit.com.
+dnl-01.geo.kaspersky.com.
+pixel.facebook.com.
+mx.siemens-club.org.
+rmgmedia.com.
+static.ak.fbcdn.net.
+ccgetsemani.wordpress.com.
+irc.purchaseservice.com.
+cdn.theknot.com.
+server1.transammonia.net.
+mail.vidnoe-grad.ru.
+search.twitter.com.
+view.atdmt.com.
+b-sidemg.com.
+mx2.maildefender.net.
+www.acblack.com.
+www.dhl.co.in.
+a5.sphotos.ak.fbcdn.net.
+th06.deviantart.net.
+api.twitter.com.
+129.144.252.190.in-addr.arpa.
+sharpeiclub.ru.
+19-courier.push.apple.com.
+www.facebook.com.
+www.bloob.fr.
+11.136.16.62.in-addr.arpa.
+caketin.honeyrosebakery.com.
+www.crunchbase.com.
+mobth1076.photobucket.com.
+a.root-servers.net.
+travel.state.gov.
+ut7.xhamster.com.
+i-sec.slutload-media.com.
+www.techlabs4u.com.
+133.186.25.125.in-addr.arpa.
+madeira-lets.com.
+a3.sphotos.ak.fbcdn.net.
+msc.wlxrs.com.
+profile.ak.fbcdn.net.
+img.seriesgo.com.
+www.youtube.com.
+tbcom.ru.
+mail.soft.com.
+65.225.80.186.in-addr.arpa.
+104.105.230.190.in-addr.arpa.
+miplandeboda.blogspot.com.
+www.googleadservices.com.
+accuratedoor.com.
+a5.sphotos.ak.fbcdn.net.
+1n1.mooo.com.
+www.facebook.com.
+www.facebook.com.
+_502_08_7.
+www.agoda.cz.
+rhap5tbq8.48bv.
+abitur.mipt.ru.
+this.content.served.by.adshuffle.com.
+215.65.155.201.in-addr.arpa.
+a.root-servers.net.
+static.olx.com.
+www.google-analytics.com.
+www.gstatic.com.
+www.asstoyedshemales.com.
+api.facebook.com.
+60.217.210.201.in-addr.arpa.
+search.babylon.com.
+88.50.11.188.in-addr.arpa.
+ym.adnxs.com.
+www.las-palmas-24.com.
+vvnktku.vlingo.com.
+fw.kose.edu.ee.
+59.175.6.186.in-addr.arpa.
+googleads.g.doubleclick.net.
+ui.skype.com.
+a.root-servers.net.
+www.singlescrowd.com.
+www.towerdefenceworld.com.
+www.nyctourism.com.
+ssl.gstatic.com.
+www.dirtbox.net.
+2j2c12fes.68yb.
+home-design-software-review.toptenreviews.com.
+fbcdn-profile-a.akamaihd.net.
+photos-h.ak.fbcdn.net.
+tracker.thepiratebay.org.
+www.four05.nl.
+statse.webtrendslive.com.
+cs301510.vk.com.
+ensombrerada.blogspot.com.
+rmd.atdmt.com.
+1-210.channel.facebook.com.
+mail.dauphintechnologie.net.
+gj77l2roa.37ap.
+berettaargentina.com.ar.
+www.staypoland.com.
+www.advertising.expedia.com.
+photos-g.ak.fbcdn.net.
+www.destentoradverteren.nl.
+104.113.51.190.in-addr.arpa.
+profile.ak.fbcdn.net.
+www.eco-nutricionhumana.blogspot.com.
+40.219.134.187.in-addr.arpa.
+unitedco.net.
+a2.sphotos.ak.fbcdn.net.
+m.facebook.com.
+arquivo.arkbr.com.br.
+www.academictutorials.com.
+manage.ixwebhosting.com.
+vikingpump.com.
+www.greenstarholistix.com.
+secure-uk.imrworldwide.com.
+photos-d.ak.fbcdn.net.
+www.f2000delasamericas.com.
+www.atufavor.com.mx.
+polisci.ucla.edu.
+51.116.111.124.in-addr.arpa.
+e566.b.akamaiedge.net.
+weblogger-dynamic-lb.playdom.com.
+40.165.242.201.in-addr.arpa.
+118.17.80.92.in-addr.arpa.
+moltaqa1.com.
+p.d.ovi.com.
+www.appitalism.com.
+108.2.73.189.in-addr.arpa.
+drcnh.org.
+evsecure-ocsp.verisign.com.
+mtalk.google.com.
+cdn.api.twitter.com.
+katerawlings.com.
+maps.google.com.
+evsecure-crl.verisign.com.
+megusta.followland.com.
+www.relishgourmet.com.
+www.101babyshowerideas.com.
+photos-f.ak.fbcdn.net.
+93.61.1.189.in-addr.arpa.
+api.twitter.com.
+a743.g.akamai.net.
+www.linuxhomenetworking.com.
+a4.sphotos.ak.fbcdn.net.
+torrents.edwardk.info.
+gmail.com.
+a995.mm1.akamai.net.
+appworld.blackberry.com.
+kirstinz.en.made-in-china.com.
+couponbuddy.s3.amazonaws.com.
+impisr.edunsk.ru.
+groups.l.google.com.
+144.162.67.187.in-addr.arpa.
+www.woodcentral.com.
+touch.facebook.com.
+translate.google.com.mx.
+elvela.org.
+uniquemadness.com.
+gencoat.com.
+cafe.mt.iphone.sgnapps.com.
+211.218.161.201.in-addr.arpa.
+profiles.takingitglobal.org.
+velocent.net.
+papa-anggry.blogspot.com.
+i.w55c.net.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+static.ak.facebook.com.
+15.172.88.200.in-addr.arpa.
+www.facebook.com.
+153.125.109.89.in-addr.arpa.
+profile.ak.fbcdn.net.
+rest-img.msg.yahoo.com.
+photos-a.ak.fbcdn.net.
+logv18.xiti.com.
+elliman.com.s9b1.psmtp.com.
+ad-g.doubleclick.net.
+googleads.g.doubleclick.net.
+ad-apac.doubleclick.net.
+sites.google.com.
+creative.ak.fbcdn.net.
+mail.mppgen.com.
+www.subealring.org.ve.
+rv.coupish.com.
+a1.sphotos.ak.fbcdn.net.
+twitter.com.
+c800869.r69.cf2.rackcdn.com.
+exploradorl2.blogspot.com.
+d13t5qcdsiucvs.cloudfront.net.
+tag.admeld.com.
+230.227.213.201.in-addr.arpa.
+profile.ak.fbcdn.net.
+www.syabas.com.my.
+pixel.facebook.com.
+bittersweetbella.tumblr.com.
+bw-it.ru.
+a.root-servers.net.
+a898.x.akamai.net.
+www.facebook.com.
+kremlinencrypt.com.
+162.33.37.201.in-addr.arpa.
+www.facebook.com.
+tracking.percentmobile.com.
+login.toolbar.conduit-services.com.
+termasworld.com.
+secure-us.imrworldwide.com.
+29.media.tumblr.com.
+photos-b.ak.fbcdn.net.
+tqbzesadg.71pn.
+57.133.50.46.in-addr.arpa.
+youtube.com.
+sn3.mailshell.net.
+b1.media.v4.skyrock.net.
+lingvo-german.ru.
+a8.sphotos.ak.fbcdn.net.
+b-0.19-23066089.80110b1.1518.19d3.3ea1.410.0.4tev3i12ugd4h8rdbt4jpaujnb.avqs.mcafee.com.
+www.y8girlsgames.com.
+mi.adinterax.com.
+agen-bola-online.nuke.im.
+cb.alimama.cn.
+www.uniteberlin.de.
+s-static.ak.facebook.com.
+www.rotary.org.
+pac.bell.com.
+inguat.gob.gt.inbound10.mxlogicmx.net.
+www.gospelherald.com.
+mail.secondhand-opt.ru.
+www.ccl.org.
+www.facebook.com.
+arabic.cnn.com.
+i4.ytimg.com.
+lindas-stampinloft.blogspot.com.
+neri1.com.
+qs.aastocks.com.
+253.104.105.186.in-addr.arpa.
+macdaddynews.disqus.com.
+mntr.babcdn.com.
+photos-g.ak.fbcdn.net.
+gs.mil.ee.
+www.clicporlalibertad.com.
+s.ytimg.com.
+www.bbva.es.
+56.157.73.121.in-addr.arpa.
+www.univercell-biosolutions.com.
+www.imago.com.pt.
+teredo.ipv6.microsoft.com.
+witter.com.
+webres2.pand.ctmail.com.
+www.ciromarchetti.com.
+29.33.134.189.in-addr.arpa.
+external.ak.fbcdn.net.
+sianganland.ru.
+alerts.conduit-services.com.
+o3frc56jg.a61w2o4y.
+108.9.37.190.in-addr.arpa.
+e55nqkqi5.32ju.
+go.srvnow.com.
+dns.msftncsi.com.
+34.246.52.186.in-addr.arpa.
+napervilleparks.org.
+thumbnails.mystyle.com.
+83113mailerpost.com.
+tools.google.com.
+www.srl.caltech.edu.
+215.12.168.192.in-addr.arpa.
+noseq.com.
+catfish.ru.
+www.greatnannies.com.
+_781_28_8.
+proua.com.
+t2.gstatic.com.
+3d-object-converter.softonic.com.
+80.41.141.201.in-addr.arpa.
+api.twitter.com.
+mail.fleetauctiongroup.com.
+www.uol.com.mx.
+www.facebook.com.
+a.root-servers.net.
+comernowling.com.inbound10.mxlogic.net.
+gorod.dp.ua.
+www.statcounter.com.
+b._dns-sd._udp.0.1.168.192.in-addr.arpa.
+www.zvdk.nl.
+widget.roomme.net.
+83.119.1.58.in-addr.arpa.
+_675_36_2.
+a995.mm1.akamai.net.
+api.facebook.com.
+clicks.adengage.com.
+0.209.172.118.in-addr.arpa.
+plusone.google.com.
+106.85.156.90.in-addr.arpa.
+www.tecolotefilms.com.
+46.133.225.190.in-addr.arpa.
+eva-miscosicas.blogspot.com.
+0-jk-w.channel.facebook.com.
+ace-north.org.uk.
+zk3.dec.com.
+163.184.76.178.in-addr.arpa.
+www.google-analytics.com.
+8mu1b5czx.s61q1q5j.
+ads.avvio.com.
+234.26.136.190.in-addr.arpa.
+de-de.facebook.com.
+d2095767.xoom.it.
+teredo.ipv6.microsoft.com.
+secure.cartown.com.
+mx.youtube.com.
+assets4.castle.zgncdn.com.
+www.eboncall.org.
+179.70.46.92.in-addr.arpa.
+kairon.malavida.com.
+forums.objectsbydesign.com.
+theruckergroup.com.
+www.promowebperu.com.
+a.root-servers.net.
+gfx7.hotmail.com.
+estrenos-de-cine.labutaca.net.
+gestion.fundacioncarolina.es.
+tracker.ccc.de.
+costcentral.com.
+daft.ie.
+gma52w7lp.37ml.
+fbcdn-sphotos-a.akamaihd.net.
+222.173.1.181.in-addr.arpa.
+www.facebook.com.
+www.autotrader.co.nz.
+60.204.81.200.in-addr.arpa.
+a.root-servers.net.
+scribblesandsnaps.wordpress.com.
+htrnews.com.s7b2.psmtp.com.
+a1404.w41.akamai.net.
+adspaces.ero-advertising.com.
+safebrowsing-cache.google.com.
+pedsocial.files.wordpress.com.
+widgets.twimg.com.
+mail1.rimslow.com.
+gaycounty.com.
+r._dns-sd._udp.0.0.168.192.in-addr.arpa.
+client.akamai.com.
+gccoxmail.net.
+yahoo.com.
+s.wordpress.com.
+evolutionofstyleblog.blogspot.com.
+mail1.mbginsurance.com.
+elcantil.com.
+dns.msftncsi.com.
+scribe.twitter.com.
+cdn2.trimm.com.c.footprint.net.
+37.58.198.190.in-addr.arpa.
+api.twitter.com.
+wildlifehc.org.
+androauth.0916161bcltd.netdna-cdn.com.
+hits.e.cl.
+a.root-servers.net.
+t3.gstatic.com.
+28.190.49.200.in-addr.arpa.
+131.150.159.187.in-addr.arpa.
+sp.cwfservice.net.
+www.opcion.net.
+edosushibar.com.
+safebrowsing-cache.google.com.
+218.87.9.186.in-addr.arpa.
+imail.columbuscontainer.com.
+profile.ak.fbcdn.net.
+clients1.google.com.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+tsm05.eset.com.
+time.chttl.com.tw.
+photos-f.ak.fbcdn.net.
+google.com.
+6.224.219.186.in-addr.arpa.
+hot-shots-2.peliculon.tv.
+tracking.affiliaxe.com.
+itunes.apple.com.
+developers.facebook.com.
+gmaul.com.
+1.0.0.127.dnsbugtest.1.0.0.127.in-addr.arpa.
+i1.ytimg.com.
+www.facebook.com.
+www.ragnadrima.com.
+us.data.toolbar.yahoo.com.
+newideas.ru.
+88.34.178.74.in-addr.arpa.
+18.79.247.189.in-addr.arpa.
+adsl.kis.ru.
+cdn.api.twitter.com.
+blog.e-kereta.com.
+tc.v14.cache7.c.youtube.com.
+150.28.75.151.in-addr.arpa.
+go.microsoft.com.
+as.casalemedia.com.
+mundodelyaoi.blogspot.com.
+fathomgear.com.
+adult.chinese.cn.
+sr.wikipedia.org.
+cdn2.vippy.co.
+dsn12.d.skype.net.
+users4.jabry.com.
+osvanceloth.elbruto.es.
+a8.sphotos.ak.fbcdn.net.
+131.92.157.186.in-addr.arpa.
+16.147.220.66.in-addr.arpa.
+59.135.20.190.in-addr.arpa.
+a5.sphotos.ak.fbcdn.net.
+db._dns-sd._udp.0.1.168.192.in-addr.arpa.
+www.thecutestblogontheblock.com.
+151.129.239.201.in-addr.arpa.
+www.gstatic.com.
+_704_31_9.
+itella.ru.
+103.235.249.190.in-addr.arpa.
+www.hotpussy.tv.
+mail.derishev.ru.
+artsugar-merche.blogspot.com.
+api.twitter.com.
+a7.sphotos.ak.fbcdn.net.
+www.jisc-collections.ac.uk.
+s.youtube.com.
+static.ak.connect.facebook.com.
+photos-b.ak.fbcdn.net.
+82.199.51.95.in-addr.arpa.
+www.whatismyip.org.
+www.gruposancorseguros.com.
+88.61.253.201.in-addr.arpa.
+www.facebook.com.
+ib.adnxs.com.
+www.brenda.uni-koeln.de.
+freenet.de.
+postoffice.condenast.ru.
+www.shemalemodelindex.com.
+r.mzstatic.com.
+125.136.124.190.in-addr.arpa.
+c3.free18.net.
+iminent.ourtoolbar.com.
+www.luxurycoachoutlet.com.
+www.yaganeloquevale.com.
+248.227.231.189.in-addr.arpa.
+urs.microsoft.com.
+123.26.186.201.in-addr.arpa.
+orchidrenaissance.com.
+profile.ak.fbcdn.net.
+valenky.ru.
+sro.whatsapp.net.
+ec2-50-19-138-103.zumodrive.com.
+s.youtube.com.
+132.21.174.189.in-addr.arpa.
+zh-cn.facebook.com.
+static4.educaedu.com.pe.
+profile.ak.fbcdn.net.
+www.motoresx.com.
+www.ton.cz.
+del.icio.us.
+sportsnation.espn.go.com.
+openx.wooga.com.
+ntp1.dlink.com.
+a.root-servers.net.
+accounts.google.com.
+pixel.facebook.com.
+i4.ytimg.com.
+49.191.121.64.in-addr.arpa.
+yui.yahooapis.com.
+dnl-15.geo.kaspersky.com.
+a.root-servers.net.
+145.236.108.186.in-addr.arpa.
+ocsp.thawte.com.
+a.root-servers.net.
+l.yimg.com.
+a6.sphotos.ak.fbcdn.net.
+199.248.234.189.in-addr.arpa.
+jobboom.com.
+photos-a.ak.fbcdn.net.
+89.76.178.190.in-addr.arpa.
+www.michellemoistpussy.com.
+photos-d.ak.fbcdn.net.
+www.luxuryworld.altervista.org.
+www.facebook.com.
+122.123.205.190.in-addr.arpa.
+uucycxpucmoc.ru.
+gateway.messenger.hotmail.com.
+cancerpulmonar.org.
+85.95.6.89.in-addr.arpa.
+www.e-galileo.eu.
+232.149.59.199.in-addr.arpa.
+www.full-stop.net.
+www.clipato.com.
+stauffergold.com.
+a.webring.com.
+dayak.com.
+ads.zizzero.com.
+amx.grandslamdesign.net.redcondor.net.
+cnt.tyxo.bg.
+i.furiousmod.com.
+support.google.com.
+www.youtube.com.
+crl.comodoca.com.
+bifkqfr:u.25ek.
+sport4ever.maktoob.com.
+mail.skyworth.com.
+cookex.amp.yahoo.com.
+www.compunoa.com.
+_ldap._tcp.
+ssl.gstatic.com.
+flipchat.com.
+www.youtube.com.
+75522lineb.cn.
+214.244.24.200.in-addr.arpa.
+toolbarqueries.google.com.
+162.63.141.201.in-addr.arpa.
+images.torrentsland.com.
+graph.facebook.com.
+a.root-servers.net.
+www.defensenewstv.com.
+millerarchitects.co.uk.
+a.root-servers.net.
+195.21.25.201.in-addr.arpa.
+www.google.com.
+ves.smolen.ru.
+messenger.hotmail.com.
+sarahjanestudios.com.
+71.241.75.190.in-addr.arpa.
+www.watchknowlearn.org.
+www.msftncsi.com.
+profile.ak.fbcdn.net.
+230.108.219.64.in-addr.arpa.
+vlex.com.pe.
+a.root-servers.net.
+www.alan4.net.
+media.trafficjunky.net.
+143.97.61.95.in-addr.arpa.
+courtesy.nominalia.com.
+9kif6czfc.k51l0p0b.
+img.paisdelocos.com.
+mail.google.com.
+ems-uk.org.
+bpcgi.nikkeibp.co.jp.
+98.145.11.187.in-addr.arpa.
+dns.msftncsi.com.
+326.webim0220.webim.myspace.com.
+a8.sphotos.ak.fbcdn.net.
+www.ipadforos.com.
+238.40.67.201.in-addr.arpa.
+which.net.
+safebrowsing-cache.google.com.
+pdf.textfiles.com.
+www.google.com.
+arkcrew.com.
+sfparenting.com.
+www.gravatar.com.
+www.alipso.com.
+www.bkstr.com.
+244.68.242.83.in-addr.arpa.
+18.1.142.187.in-addr.arpa.
+a8.sphotos.ak.fbcdn.net.
+192.25.238.189.in-addr.arpa.
+blog.aziawaoutour.com.
+sstat.360buy.com.
+photos-f.ak.fbcdn.net.
+polk-sullivan.com.
+7.234.15.199.in-addr.arpa.
+mail.imessagingsystems.com.
+esva1.itech.ms.
+arabiasaudita.pordescubrir.com.
+235.236.248.201.in-addr.arpa.
+este.
+cdnrockyou-a.akamaihd.net.
+zy.china.com.cn.
+teredo.ipv6.microsoft.com.
+propacificfresh.com.
+233.131.179.190.in-addr.arpa.
+www.andiamo.com.
+121.55.54.65.in-addr.arpa.
+b.scorecardresearch.com.
+pokerfreemail.com.
+60.59.222.189.in-addr.arpa.
+137.0.19.88.in-addr.arpa.
+85.132.248.111.in-addr.arpa.
+gfx1.hotmail.com.
+pagead2.googlesyndication.com.
+a6.sphotos.ak.fbcdn.net.
+www.google-analytics.com.
+newrivercabinet.com.
+86.67.139.187.in-addr.arpa.
+vast.bp3847758.btrll.com.
+36.80.242.189.in-addr.arpa.
+alt1.chessclub.com.
+18.165.49.190.in-addr.arpa.
+lecturasarztucuman.wordpress.com.
+web-gin.ru.
+capitalfederal.adoos.com.ar.
+19.110.78.187.in-addr.arpa.
+api.twitter.com.
+_586_16_0.
+safebrowsing-cache.google.com.
+tl04.chip.eu.
+www.opicode.org.
+www.pensandoenpsicologia.com.
+clients1.google.com.
+dailycappuccino.nl.
+alfar.com.tr.
+54.190.152.186.in-addr.arpa.
+api.facebook.com.
+legalterms.cbsinteractive.com.
+34.6.43.186.in-addr.arpa.
+o-o.preferred.atl14s01.v21.lscache3.c.youtube.com.
+www.monstershack.net.
+aronasarwar.co.uk.
+external.ak.fbcdn.net.
+a7.sphotos.ak.fbcdn.net.
+offers.cmtrax.com.
+ksn2-12.kaspersky-labs.com.
+plusone.google.com.
+40.243.58.187.in-addr.arpa.
+www.google.com.
+t1.gstatic.com.
+www.pandora.com.
+fullscale.com.
+181.159.209.201.in-addr.arpa.
+p1t.ru.
+fbcdn-photos-a.akamaihd.net.
+fbcdn-profile-a.akamaihd.net.
+www.hookedonjuice.com.
+photos-b.ak.fbcdn.net.
+1.244.132.190.in-addr.arpa.
+smtp.fsmail.net.
+seniorsolutions.com.
+img.moonbuggy.org.
+apk.dir4world.com.
+www.sweetimstore.com.
+224.0.55.190.in-addr.arpa.
+html.rincondelvago.com.
+www.alw-ed.com.
+dns.msftncsi.com.
+jetcatalog.ru.
+tallconnections.com.
+sproutonline.channelfinder.net.
+komonews.s3.amazonaws.com.
+photos-d.ak.fbcdn.net.
+s-static.ak.facebook.com.
+242.219.93.186.in-addr.arpa.
+www.sophimania.pe.
+lisd.k12.mi.us.
+five.tv.
+photos-h.ak.fbcdn.net.
+de-de.facebook.com.
+93.coll.ning.com.
+tracker.novalayer.org.
+ip-81-23-55-150.ask4internet.com.
+developers.facebook.com.
+tap2-cdn.rubiconproject.com.
+a3.sphotos.ak.fbcdn.net.
+teredo.ipv6.microsoft.com.
+www.google.com.mx.
+m.addthisedge.com.
+images02.olx-st.com.
+169.132.92.201.in-addr.arpa.
+img.hotwords.com.br.
+151.144.182.186.in-addr.arpa.
+coffee.haohaowan.com.
+pattwhite.com.
+sritchie645.orangehome.co.uk.
+kingofsat.net.
+scripts.verticalacuity.com.
+c.prodigy.msn.com.
+www.google-analytics.com.
+blushnightclub.com.
+static.ak.fbcdn.net.
+exodus.1337x.org.
+avanquest.upclick.com.
+fbcdn-sphotos-a.akamaihd.net.
+boise.gannett.com.
+vinylopedia.tk.
+wrvideo.com.br.
+a.root-servers.net.
+en-us.fxfeeds.mozilla.com.
+photos-b.ak.fbcdn.net.
+a2:ey7:ug.c34q3i7i.
+84.71.21.187.in-addr.arpa.
+a.root-servers.net.
+stl-mbsin-01.boeing.com.
+www.apple.com.
+twoliverpoolfans.files.wordpress.com.
+ns3.slb.com.
+hoskinson.net.
+www.facebook.com.
+malah.biz.
+55.230.213.201.in-addr.arpa.
+83.69.248.116.in-addr.arpa.
+platform.twitter.com.
+video-aqui-mismo.blogspot.com.
+broenserud.com.
+www.archos.com.
+80.80.78.190.in-addr.arpa.
+googleads.g.doubleclick.net.
+photos-g.ak.fbcdn.net.
+24.120.92.186.in-addr.arpa.
+rs543l32.rapidshare.com.
+mail-2.traditio.org.
+sportdaten.welt.de.
+notibang.blogspot.com.
+5mk6g:cd7.91xw.
+www.santander.com.mx.
+www.ebzzo.eu.
+137.186.171.187.in-addr.arpa.
+2.0.168.192.in-addr.arpa.
+img028.rockyou.com.
+profile.ak.fbcdn.net.
+a34.g.akamai.net.
+au.download.windowsupdate.com.
+www.advertisingcrossing.com.
+onlinecliptv.com.
+0-333.channel.facebook.com.
+172.90.121.84.in-addr.arpa.
+www.dailyhotnews.org.
+news.google.com.mx.
+b._dns-sd._udp.0.1.168.192.in-addr.arpa.
+www.addthis.com.
+profile.ak.fbcdn.net.
+www.mj1000.com.
+56.247.134.187.in-addr.arpa.
+www.jldfineart.com.
+bafta.org.
+b._dns-sd._udp.0.1.168.192.in-addr.arpa.
+mashable.com.
+151.146.185.190.in-addr.arpa.
+tsm00.eset.com.
+photos-h.ak.fbcdn.net.
+www.thestrokesfan.com.
+brig-td.spb.ru.
+96.195.55.177.in-addr.arpa.
+i4.ytimg.com.
+periodicozocalo.com.mx.
+www.verycheapuggsboots.co.uk.
+m59eop2ip.61wg.
+mail.oppermanns-online.de.
+pftmobile.com.
+smtp.kndati.lv.
+wd.ggili.com.
+novotec.ru.
+www.tusourcecard.com.
+135.15.143.201.in-addr.arpa.
+57.198.119.79.in-addr.arpa.
+tamarind.co.ke.
+4.42.64.151.in-addr.arpa.
+translate.google.com.
+photos-a.ak.fbcdn.net.
+vegassportsexperts.com.
+a.root-servers.net.
+a3.sphotos.ak.fbcdn.net.
+raycomm.com.
+www.google.com.
+a8.sphotos.ak.fbcdn.net.
+connorarnold.karoo.co.uk.
+a.root-servers.net.
+relay.digsys.bg.
+a4.sphotos.ak.fbcdn.net.
+br.premierleague.fantasysports.yahoo.com.
+a.root-servers.net.
+cache-download.real.com.
+ocnj.us.
+s2.youtube.com.
+www.bankhalter.de.
+www.googleadservices.com.
+sheri.net.
+photos-e.ak.fbcdn.net.
+akllaw.com.s5a2.psmtp.com.
+a.root-servers.net.
+wnbvaircmngnugnewxvffvfp.ac.
+content.yieldmanager.edgesuite.net.
+www.facebook.com.
+oakleynetworks.com.
+b._dns-sd._udp.0.2.168.192.in-addr.arpa.
+time.chttl.com.tw.
+apps.facebook.com.
+coins.shop.ebay.com.
+superiortandems.com.
+a.root-servers.net.
+safebrowsing.clients.google.com.
+widgets.twimg.com.
+110.127.141.201.in-addr.arpa.
+static.tianya.cn.
+cruznet2.cruznet.net.
+g.ceipmsn.com.
+a.root-servers.net.
+artisanfilms.com.
+img6.gg.mmo4arab.com.
+orcart.facebook.com.
+mrs-cbe.mrs.yimg.com.
+fxfeeds.mozilla.com.
+webcache.googleusercontent.com.
+www.euphoriashop.co.uk.
+view.atdmt.com.
+api.facebook.com.
+pjyyon.com.
+raslist.dhl.com.
+platform.twitter.com.
+42.52.60.190.in-addr.arpa.
+jobbuzz.timesjobs.com.
+www.v-trail.com.
+csi.gstatic.com.
+homestore.cisco.com.
+www.playrelax.com.
+www.marketplace-live.com.
+photos-e.ak.fbcdn.net.
+www.youtube.com.
+login.secure.co1.msn.com.
+jvlw21t6t.u74x0n8f.
+a.root-servers.net.
+a.root-servers.net.
+www.rednet21.com.
+translate.google.com.mx.
+olympictool.com.
+miriam-montero-duque.suite101.net.
+uslshop.com.
+www.phpdocx.com.
+1.0.0.127.dnsbugtest.1.0.0.127.in-addr.arpa.
+farcaster.org.
+static.ak.fbcdn.net.
+116.60.245.173.in-addr.arpa.
+morrow30.freeserve.co.uk.
+connect.facebook.net.
+a3.sphotos.ak.fbcdn.net.
+a1.sphotos.ak.fbcdn.net.
+www.cemexmexico.com.
+www.benettontalk.com.
+pts.net.
+17.131.35.189.in-addr.arpa.
+photos-d.ak.fbcdn.net.
+portlandonline.com.
+a.root-servers.net.
+email.theshoppingchannel.com.
+a.root-servers.net.
+violetmall.ru.
+5-courier.push.apple.com.
+114.242.179.190.in-addr.arpa.
+ebm.cheetahmail.com.
+img100.xvideos.com.
+188.141.171.201.in-addr.arpa.
+js.admeld.com.
+a.root-servers.net.
+bts.inet.fi.
+in2itivegroup.com.
+static.ak.facebook.com.
+teredo.ipv6.microsoft.com.
+102.89.69.66.in-addr.arpa.
+www.atomretro.com.
+a.root-servers.net.
+225.91.9.177.in-addr.arpa.
+231.113.79.186.in-addr.arpa.
+16.147.220.66.in-addr.arpa.
+pixel.facebook.com.
+external.ak.fbcdn.net.
+external.ak.fbcdn.net.
+dns.msftncsi.com.
+www.filesonic.com.
+a1.sphotos.ak.fbcdn.net.
+teredo.ipv6.microsoft.com.
+valied.wrzuta.pl.
+a2.sphotos.ak.fbcdn.net.
+151.62.173.118.in-addr.arpa.
+aspmx2.googlemail.com.
+guru.avg.com.
+ksn1-11-part1.kaspersky-labs.com.
+www.orjinalafrikamangosu.gen.tr.
+www.ipaddressworld.com.
+psgw.t-mobilesgws.com.
+hi-in.facebook.com.
+dem0003.in.
+gcr-capital.com.
+34.38.227.77.in-addr.arpa.
+external.ak.fbcdn.net.
+www.facebook.com.
+www.azringtones.com.
+148.91.145.78.in-addr.arpa.
+www.youtube.com.
+wpad.hrbl.net.
+tw.itunes.com.
+energyflashbysimonreynolds.blogspot.com.
+shared.live.com.
+pixel.quantserve.com.
+www.tdu.com.mx.
+c-0.19-2309c481.30483.1518.19d3.3ea1.210.0.35rgm4fbje6tc9tn3f1evbbss5.avqs.mcafee.com.
+downloads4.kaspersky-labs.com.
+uk.forvo.com.
+www.baby-connect.com.
+plus.google.com.
+c.statcounter.com.
+www.facebook.com.
+skydrive.live.com.
+www.telasparacortinas.com.
+mail.artemka.ru.
+music4yourvids.co.uk.
+211.115.154.79.in-addr.arpa.
+clients4.google.com.
+dingtao333.3322.org.
+db._dns-sd._udp.0.1.168.192.in-addr.arpa.
+a.l.yimg.com.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+www.facebook.com.
+greedygoose.blogspot.com.
+semana.com.
+codenew.impresionesweb.com.
+ecl.tbc.tetrisfb.com.
+acuariopolitico.blogspot.com.
+partners.aljazeera.net.
+wxod1p3eb.z75t8u8x.
+inbound.mveinc.com.netsolmail.net.
+theimagist.com.
+www.yanbal.com.
+www.pheasantsforever.org.
+photos-e.ak.fbcdn.net.
+www.movistar.com.ve.
+mail.rrsid.com.
+google.com.
+fbcdn-profile-a.akamaihd.net.
+cameroncommunities.com.
+profile.ak.fbcdn.net.
+105.107.54.27.in-addr.arpa.
+www.facebook.com.
+www.top-buyer.com.
+data.cmcore.com.
+a.root-servers.net.
+twitter.com.
+photos-f.ak.fbcdn.net.
+207.148.237.84.in-addr.arpa.
+es-es.facebook.com.
+sp.ask.com.
+a-0.19-a70c8079.d150083.1518.19d4.3ea0.210.0.76k1c41vmrdtkq5sgh9jewtvsj.avqs.mcafee.com.
+cdn.stumble-upon.com.
+vp.sip.messenger.msn.com.
+fibres.net.s7b1.psmtp.com.
+134.14.49.190.in-addr.arpa.
+dns.msftncsi.com.
+125.196.63.119.in-addr.arpa.
+www.kidsrooms.co.uk.
+orcart.facebook.com.
+www.google.com.mx.
+wire-pro.com.
+www.trangobroadband.com.
+naysue.wordpress.com.
+wrenconsult.com.
+reddevelopment.ru.
+www.bywifi.com.
+sync.mathtag.com.
+88.42.207.108.in-addr.arpa.
+25.media.tumblr.com.
+latis03.cbthebank.com.
+lightsonthelake.blogspot.com.
+static.ak.fbcdn.net.
+login.toolbar.conduit-services.com.
+i1.akcdn.net.
+www.gomovers.com.
+a2.sphotos.ak.fbcdn.net.
+146.136.139.190.in-addr.arpa.
+arrogant.ru.
+240.7.55.186.in-addr.arpa.
+www.youtube.com.
+122.6.23.190.in-addr.arpa.
+ads.tlvmedia.com.
+shared.live.com.
+s2.wp.com.
+www.msn.com.
+1.us.vps.garantname.com.
+vcs1.msg.yahoo.com.
+www.sweetpotatosoftware.com.
+service.matomy.com.
+249.59.94.189.in-addr.arpa.
+us.mg.mail.yahoo.com.
+49.185.49.190.in-addr.arpa.
+pixel.facebook.com.
+117.130.150.190.in-addr.arpa.
+internetshakespeare.uvic.ca.
+gigmaps.net.
+www.diarioderegatas.es.
+search-it-today.com.
+12.124.107.190.in-addr.arpa.
+s4is.histats.com.
+datacenterdynamics.com.
+104.238.19.190.in-addr.arpa.
+dundefndpc.natneg3.gamespy.com.
+rc.rlcdn.com.
+nec-tokin.com.
+97.163.51.190.in-addr.arpa.
+www.youtube.com.
+www.marbleslab.ca.
+zh.wikipedia.org.
+marblecrafters.com.inbound30.mailprotector.net.
+69.102.155.189.in-addr.arpa.
+beta.stun.voice.yahoo.com.
+marquintas.wordpress.com.
+www.naimlabel.com.
+69.247.17.190.in-addr.arpa.
+a8.sphotos.ak.fbcdn.net.
+db._dns-sd._udp.0.1.168.192.in-addr.arpa.
+218.212.146.189.in-addr.arpa.
+20-courier.push.apple.com.
+firepowereurope.com.
+dakelem.luminet.net.
+tracker.bidder7.mookie1.com.
+ping3.dyngate.com.
+www.mozilla.com.
+csi.gstatic.com.
+giport.ru.
+neptuno.cestel.es.
+59.235.7.89.in-addr.arpa.
+ksn3-11.part2.kaspersky-labs.com.
+adanacsales.com.inbound15.mxlogic.net.
+titanium30-en.url.trendmicro.com.
+clients4.google.com.
+64.254.18.189.in-addr.arpa.
+fkm-anons.ru.
+partnercomm.net.s7a1.psmtp.com.
+_505_04_2.
+a.root-servers.net.
+www.tango-dj.at.
+gmail-smtp-in.l.google.com.
+gallys.bustykerrymarie.com.
+caman.ru.
+imtop.ru.
+www.facebook.com.
+laxmnvmaltiris1.fs.marrcorp.marriott.com.
+zanestle.com.
+api-public.addthis.com.
+del.icio.us.
+a.root-servers.net.
+venusonmars.com.
+99.64.91.190.in-addr.arpa.
+102.163.253.189.in-addr.arpa.
+201.107.32.80.in-addr.arpa.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+172.59.238.189.in-addr.arpa.
+dns.msftncsi.com.
+214.114.107.186.in-addr.arpa.
+113.44.48.190.in-addr.arpa.
+www.ukcigarforums.com.
+seg.sharethis.com.
+mta5.am0.yahoodns.net.
+mitutoyo.com.
+www.ophtalmologie.fr.
+31.228.46.124.in-addr.arpa.
+60.210.209.190.in-addr.arpa.
+www.google-analytics.com.
+100.70.8.200.in-addr.arpa.
+mailhost.lecxp.com.
+ocsp.thawte.com.
+hoteldiscount.ru.
+www.l.google.com.
+js.microsoft.com.
+static.ak.fbcdn.net.
+apis.google.com.
+96.43.12.186.in-addr.arpa.
+loading6.widdit.com.
+static.ak.fbcdn.net.
+teredo.ipv6.microsoft.com.
+www.dairyqueen.com.ph.
+waynesville.k12.mo.us.
+videos.picapon.com.
+35.206.186.189.in-addr.arpa.
+0.gravatar.com.
+a.root-servers.net.
+googlemail.l.google.com.
+video.nudelingeriepics.com.
+www.facebook.com.
+www.google-analytics.com.
+a4.sphotos.ak.fbcdn.net.
+63.96.168.189.in-addr.arpa.
+www.wowjuju.com.
+a6.sphotos.ak.fbcdn.net.
+sheisnotyourmother.blogspot.com.
+a3.sphotos.ak.fbcdn.net.
+ocsp.comodoca.com.
+a6.sphotos.ak.fbcdn.net.
+bettergolf.net.
+img102.herosh.com.
+translate.googleapis.com.
+142.147.82.190.in-addr.arpa.
+msdn.microsoft.com.
+250.63.137.216.in-addr.arpa.
+global.ard.yahoo.com.
+www.youtube.com.
+bbs.health.ifeng.com.
+a4.sphotos.ak.fbcdn.net.
+zzz.clickbank.net.
+s-external.ak.fbcdn.net.
+www.jennifervaughn.com.
+www.okinawan-shorinryu.com.
+207.243.168.192.in-addr.arpa.
+a1725.l.akamai.net.
+24.media.tumblr.com.
+153.18.42.62.in-addr.arpa.
+rosalind-hicks.memory-of.com.
+www.google.com.
+profile.ak.fbcdn.net.
+gleasonhosting.com.
+mail.dibadi.net.
+google.com.
+es.wikipedia.org.
+tikitaka.foroactivo.com.
+egbmbdey.mooo.com.
+ksn2-12.kaspersky-labs.com.
+archives.obs-us.com.
+plus.google.com.
+215.235.211.189.in-addr.arpa.
+a.root-servers.net.
+macgm-log.com.
+grylott.fsbusiness.co.uk.
+www.breakfastpointlifestyle.com.au.
+www.scotlandsoftware.com.
+donboscovictorias.org.
+a.root-servers.net.
+pme.tscapeplay.com.
+pixel.facebook.com.
+s2.youtube.com.
+www.corvettepartsforsale.com.
+42.9.21.108.in-addr.arpa.
+cs1212.vk.com.
+www.egipto2012.com.
+a.root-servers.net.
+photos-a.ak.fbcdn.net.
+a2.sphotos.ak.fbcdn.net.
+static.ak.fbcdn.net.
+21.224.171.69.in-addr.arpa.
+www.facegroup.com.
+www.museolaligua.cl.
+www.byrdseed.com.
+www.aulaclic.es.
+tmi.gr.jp.
+a2.sphotos.ak.fbcdn.net.
+photos-g.ak.fbcdn.net.
+pubads.g.doubleclick.net.
+diy-mail.alerta.su.
+a1505.l.akamai.net.
+www.mrmusicman17.com.
+www.facebook.com.
+mx01.eagle-design.com.
+l1.yimg.com.
+pinnaclecollects.com.s9b1.psmtp.com.
+js.patheos.com.s3.amazonaws.com.
+83.253.47.201.in-addr.arpa.
+getprof.us.np.community.playstation.net.
+img3.catalog.video.msn.com.
+ncoss.org.au.
+chromejs.s3.amazonaws.com.
+symr2a.backup.com.
+127.123.215.66.in-addr.arpa.
+shop.tsumorichisato.com.
+xybion.com.inbound10.mxlogic.net.
+apps.facebook.com.
+mail.richardsoncap.com.
+pixel.quantserve.com.
+168.117.71.193.in-addr.arpa.
+www.druzestudies.org.
+mx02.ipac.caltech.edu.
+a6.sphotos.ak.fbcdn.net.
+static.ak.fbcdn.net.
+fireblast.net.
+a.root-servers.net.
+yodemoda.blogspot.com.
+183.159.18.186.in-addr.arpa.
+us.bc.yahoo.com.
+electriclane.de.
+waterworkscircuit.com.
+bookbirddog.blogspot.com.
+232.189.136.162.in-addr.arpa.
+api.facebook.com.
+google.com.
+155.126.18.176.in-addr.arpa.
+ax.init.itunes.apple.com.
+cdn.api.twitter.com.
+ip2location.conduit-services.com.
+ap.lijit.com.cdngc.net.
+rewardz.vodafone.co.uk.
+mx3.prima.de.
+a.root-servers.net.
+media.sliderocket.com.
+apps.facebook.com.
+teredo.ipv6.microsoft.com.
+static-resource.np.community.playstation.net.
+sipinternal.gmail.com.
+itb-group.ru.
+a.root-servers.net.
+241.165.77.188.in-addr.arpa.
+xslt.alexa.com.
+a.root-servers.net.
+herry.com.
+134.42.41.126.in-addr.arpa.
+alerts.conduit-services.com.
+photos-c.ak.fbcdn.net.
+db._dns-sd._udp.0.0.168.192.in-addr.arpa.
+orionimpex.ru.
+185.25.122.186.in-addr.arpa.
+www.google-analytics.com.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+31kp9ake1.78qc.
+114.106.138.187.in-addr.arpa.
+macfarlanepartners.com.s8a2.psmtp.com.
+141.212.24.201.in-addr.arpa.
+www.jessmills.co.uk.
+screenshots.bravotube.net.
+www.spakti.eu.
+a.root-servers.net.
+jhtpc.com.
+9.140.149.186.in-addr.arpa.
+fbcdn-profile-a.akamaihd.net.
+von_der.galeon.com.
+stliqwltryhkwh.com.
+api-read.facebook.com.
+static.addtoany.com.
+137.188.191.186.in-addr.arpa.
+www.stylelist.com.
+www.google-analytics.com.
+www.sitionica.com.ar.
+tag.admeld.com.
+ceusa.virtualiza.com.br.
+131.250.88.186.in-addr.arpa.
+0bps664l3vqk05dj8qih0t5renri9iic.ig.ig.gmodules.com.
+228.175.253.201.in-addr.arpa.
+197.5.11.190.in-addr.arpa.
+a.root-servers.net.
+www.google-analytics.com.
+photos-g.ak.fbcdn.net.
+do.kershaw.k12.sc.us.
+rkhunter.sourceforge.net.
+www.balidesa.com.
+94.138.204.62.in-addr.arpa.
+mohegansunpocono.com.
+222.130.195.187.in-addr.arpa.
+llwineworld.com.
+i2.ytimg.com.
+sp.cwfservice.net.
+112.235.56.186.in-addr.arpa.
+mx.ablefreight.com.
+b.scorecardresearch.com.
+graph.facebook.com.
+js2.wlxrs.com.
+by2msg3010606.gateway.messenger.live.com.
+urs.microsoft.com.
+help.amaland.com.
+pointemagazine.com.
+gdata.youtube.com.
+austinfoodcarts.com.
+bloomu.edu.
+34.64.252.201.in-addr.arpa.
+profile.ak.fbcdn.net.
+multiplos.hotwords.com.br.
+translate.google.com.mx.
+beatrizsalas10.blogspot.com.
+65.54.55.190.in-addr.arpa.
+www.plattoes.com.
+rss.elmundo.es.
+by2msg4020409.gateway.messenger.live.com.
+bd-natok.com.
+aptar.com.
+es-la.facebook.com.
+www.rome.info.
+userimages02-akm.imvu.com.
+www30l2.glam.com.
+www.gamersmint.com.
+108.59.129.189.in-addr.arpa.
+ypk.cs4u.co.il.
+smf.prefpoa.com.br.
+developers.facebook.com.
+pleated-jeans.com.
+a5.sphotos.ak.fbcdn.net.
+cachend.meetlocals.com.rncdn1.com.
+apps.facebook.com.
+www.bateriafinas.biz.
+28.181.85.75.in-addr.arpa.
+t.co.
+www.facebook.com.
+a4.sphotos.ak.fbcdn.net.
+140.40.78.184.in-addr.arpa.
+crossinginc.com.inbound15.mxlogicmx.net.
+www.google.com.
+appfrica.net.
+www.wwemelina.com.
+ads.lfstmedia.com.
+medusa.it.
+qu.ebay.com.
+www.shabbyfrenchcottage.com.
+lycosasia.com.
+distilleryimage2.instagram.com.
+mcdr-law.com.inbound10.mxlogicmx.net.
+a-0.19-230fc081.c0f0081.1518.19d4.2f4a.210.0.98wd185z1pd8v166u63l2c1lqt.avqs.mcafee.com.
+incidentalsgiftshop.com.
+itom.com.
+83.205.168.192.in-addr.arpa.
+www.opodo.at.
+us.my.alibaba.com.
+clients1.google.com.
+172.135.94.75.in-addr.arpa.
+apps.facebook.com.
+kitanaisasayaki.foroactivo.com.
+email.gemlimo.com.
+60.176.53.178.in-addr.arpa.
+secure-us.imrworldwide.com.
+toolbarqueries.google.com.
+ssw.live.com.
+d.agkn.com.
+www.britevents.com.
+ad.yieldmanager.com.
+:rjljfdre.52mj.
+apps.facebook.com.
+external.ak.fbcdn.net.
+epd5fa8vi.u25y3c6x.
+adspaces.ero-advertising.com.
+147.1.165.188.in-addr.arpa.
+0af2d87b0af12c898897744f51c37b7f.org.
+tc10.easythumbhost.com.
+d7.zedo.com.
+distilleryimage9.s3.amazonaws.com.
+159.144.42.190.in-addr.arpa.
+www.cocanews.com.
+read.gov.
+access1.net.
+caglarteknik.com.
+img.hotwords.com.br.
+218.28.55.80.in-addr.arpa.
+ksn2-12.kaspersky-labs.com.
+mantecamail.sjcoe.net.
+152.89.120.190.in-addr.arpa.
+a.root-servers.net.
+153.71.43.208.in-addr.arpa.
+blog.sproutcore.com.
+112.175.172.190.in-addr.arpa.
+pastordice.blogcindario.com.
+msfs.nspmotion.com.
+157.245.222.189.in-addr.arpa.
+9.144.239.189.in-addr.arpa.
+124.193.19.190.in-addr.arpa.
+19.77.228.67.in-addr.arpa.
+external.ak.fbcdn.net.
+www.facebook.com.
+dnl-07.geo.kaspersky.com.
+www.facebook.com.
+mp.moshimo.com.
+security.freebsd.org.
+arqiva.com.
+mail.tencorr.com.
+news.google.com.
+api.mixpanel.com.
+halo.neoseeker.com.
+enquete.linternaute.com.
+6%20hermosos%20marcos%20para%20fotos%20en%20png.
+successfulcompanies.com.
+i49.tinypic.com.
+86.58.246.24.in-addr.arpa.
+nnmigmmlh.n27f5r5e.
+evintl-aia.verisign.com.
+www.donewaiting.com.
+www.google-analytics.com.
+s-static.ak.facebook.com.
+adspaces.ero-advertising.com.
+photos-c.ak.fbcdn.net.
+10-courier.push.apple.com.
+260.webim0247.webim.myspace.com.
+228.114.240.88.in-addr.arpa.
+static.ak.connect.facebook.com.
+static.ak.fbcdn.net.
+hiresystems.com.
+rwenpower.com.
+experiments.instrum3nt.com.
+webcache.googleusercontent.com.
+a.root-servers.net.
+147.138.30.189.in-addr.arpa.
+t.co.
+2itb.com.
+pixel.facebook.com.
+creativosonline.org.
+_951_89_9.
+hey-tu.jimdo.com.
+msdn.microsoft.com.
+joomlavi.vn.
+ljhuqasjdz.info.
+smtp.gmail.com.
+inbound.sunsetstudio.com.netsolmail.net.
+ad.yieldmanager.com.
+alerts.conduit-services.com.
+vulcanlogix.com.
+dhs.state.il.us.
+flqfamxsm.00yb.
+6.198.173.90.in-addr.arpa.
+68.95.236.189.in-addr.arpa.
+www.google.com.
+chart.googleapis.com.
+www.payidar.net.
+172.230.190.189.in-addr.arpa.
+profile.ak.fbcdn.net.
+25.129.251.212.in-addr.arpa.
+www.bo.avon.com.
+60.63.91.186.in-addr.arpa.
+basketball.stack.com.
+teredo.ipv6.microsoft.com.
+www.tarotdeesperanza.es.
+c13.zedo.com.
+i1.ytimg.com.
+wild-fb-apache-active-vip.playdom.com.
+www.laguiabonaerense.com.ar.
+twitter.com.
+zq8cbrr92.43ex.
+mail.sjgames.com.
+wpad.
+203.112.228.67.in-addr.arpa.
+r._dns-sd._udp.0.0.168.192.in-addr.arpa.
+seniorflexonics.com.
+teredo.ipv6.microsoft.com.
+photos-e.ak.fbcdn.net.
+node1.bbcimg.co.uk.
+www.cnnmoney.com.
+galardigroup.com.
+vtekusa.com.s9b2.psmtp.com.
+t5.oopsmovs.com.
+119.196.199.187.in-addr.arpa.
+www.asiansquash.com.
+aol.com.
+d2099343.xoom.it.
+profile.ak.fbcdn.net.
+77.7.51.190.in-addr.arpa.
+180medical.com.
+m.ebuddy.com.
+ro.wikipedia.org.
+48.216.55.50.in-addr.arpa.
+110.210.89.186.in-addr.arpa.
+20.95.53.186.in-addr.arpa.
+googlemail.l.google.com.
+facemoods.com.
+sosyalmedya.co.
+skdstudio.com.
+bakery.teamlava.com.
+cdn.orbengine.com.
+www.bkrtx.com.
+a.root-servers.net.
+jonlscott.com.
+api.zynga.com.
+www.picoscar.com.
+barracuda.sadlier.com.
+fbcdn-photos-a.akamaihd.net.
+edge.sharethis.com.
+95.100.70.99.in-addr.arpa.
+64.19.123.84.in-addr.arpa.
+static.ak.fbcdn.net.
+creative.ak.fbcdn.net.
+www.facebook.com.
+9juexh:gn.n16k3n9y.
+166.85.158.189.in-addr.arpa.
+gfx2.hotmail.com.
+mail2.shabakah.net.sa.
+syndication.mmismm.com.home.
+tealab.com.
+am.joneslanglaselle.com.
+apps.facebook.com.
+watsonfurniture.com.s7a1.psmtp.com.
+178.41.171.201.in-addr.arpa.
+photos-e.ak.fbcdn.net.
+ksn1-11-part1.kaspersky-labs.com.
+ka2.no-ip.biz.
+a.root-servers.net.
+50.149.220.66.in-addr.arpa.
+showbiz.count.brat-online.ro.
+api.twitter.com.
+market.android.com.
+m.youtube.com.
+221.222.205.190.in-addr.arpa.
+www.imdb.com.
+lightera.com.
+forums.taleworlds.com.
+escuela.ipae.pe.
+d2ainc.com.
+i.ytimg.com.
+plexmovie.plexapp.com.
+connect.facebook.net.
+a.root-servers.net.
+isatap.felipe.
+www.20minutos.es.
+client-software.real.com.
+oshea.com.
+92.105.30.88.in-addr.arpa.
+218.0.173.190.in-addr.arpa.
+prov.us.mydlink.com.
+static.ak.fbcdn.net.
+93.177.74.70.in-addr.arpa.
+ok-training.ru.
+_231_97_3.
+152.102.34.190.in-addr.arpa.
+pagead2.googlesyndication.com.
+jxliu.com.
+ads2.iforex.com.
+anmpress.com.
+www.hulaisland.com.
+iji.com.
+theimaginarybody.co.uk.
+e566.b.akamaiedge.net.
+local537.com.
+rincon.com.s5a1.psmtp.com.
+117.224.7.200.in-addr.arpa.
+creative.ak.fbcdn.net.
+support.google.com.
+a3.sphotos.ak.fbcdn.net.
+a8.sphotos.ak.fbcdn.net.
+50.66.187.190.in-addr.arpa.
+www.nero.com.
+www.hcso.tampa.fl.us.
+cdn.tacoda.at.atwola.com.
+t1.gstatic.com.
+k12.dserv.com.
+www.enterprise.com.
+www.maxi-juegos.com.
+translate.google.com.mx.
+au.download.windowsupdate.com.
+.
+butlerme.com.
+photos-h.ak.fbcdn.net.
+maa.com.my.
+theor.jinr.ru.
+msmgate.mrg.uswest.com.
+zorfox.com.
+www.minilening.nl.
+apairofnuts.com.
+ssl.gstatic.com.
+ereshermosa.galeon.com.
+a5.sphotos.ak.fbcdn.net.
+galasso.com.s8a1.psmtp.com.
+sk.hicow.com.
+408.ch.meebo.com.
+static.ak.fbcdn.net.
+bestofeverythingafter50.com.
+www.aprendelenguadesignos.
+231.44.132.187.in-addr.arpa.
+sportsmanflyer.blogspot.com.
+www.kissinggames.org.
+bp.specificclick.net.
+a.root-servers.net.
+maxi1419.newsvine.com.
+sn.nishitech.ac.jp.
+js.wlxrs.com.
+pixel.facebook.com.
+a.root-servers.net.
+219.230.243.189.in-addr.arpa.
+www.kayak.com.
+97.104.133.189.in-addr.arpa.
+115.96.220.41.in-addr.arpa.
+mail.jrbooth.net.
+s.youtube.com.
+activesync.softonic.com.br.
+153.2.76.201.in-addr.arpa.
+www.corodebabel.com.ar.
+e3353.c.akamaiedge.net.
+www.photowatches.eu.
+3d.pchome.net.
+175.61.91.186.in-addr.arpa.
+counterb.statcounter.com.
+my56k.net.
+2.127.14.187.in-addr.arpa.
+laposte.net.
+m:ybilogt.h36m0a7l.
+217.119.51.190.in-addr.arpa.
+sq.wikipedia.org.
+sn3.mailshell.net.
+24.125.233.220.in-addr.arpa.
+www.opdirect.net.
+www.facebook.com.
+cust6410-2.in.mailcontrol.com.
+www.lasbahamas.es.
+partner.googleadservices.com.
+sac.gti.mcafee.com.
+developers.facebook.com.
+db._dns-sd._udp.0.1.168.192.in-addr.arpa.
+mx.openmail.paran.com.
+92.185.44.83.in-addr.arpa.
+ar.iiarjournals.org.
+liscuba.sld.cu.
+mobile.juicyads.com.
+wboc.com.
+accounts.google.com.
+p-posad.ru.
+rp.gwallet.com.
+b.ads1.msads.net.
+ie9.discoverbing.com.
+www.enviprotect.de.
+s6.motherlessmedia.com.
+a2.sphotos.ak.fbcdn.net.
+chirrup.com.
+photos-a.ak.fbcdn.net.
+a7.sphotos.ak.fbcdn.net.
+a.root-servers.net.
+www.icqoso.com.
+31.162.3.107.in-addr.arpa.
+ng.lighthousez11.com.
+7.45.27.187.in-addr.arpa.
+www.gamelink.com.
+overstockcom.112.2o7.net.
+38.27.139.189.in-addr.arpa.
+www.bywifi.com.
+intovsts.net.
+www.fastaccess.drivers.bellsouth.net.
+191.55.37.213.in-addr.arpa.
+www.yahoo.com.
+google.com.
+d3lvr7yuk4uaui.cloudfront.net.
+photos-g.ak.fbcdn.net.
+toiletpaperexpress.wordpress.com.
+i3.ytimg.com.
+fbcdn-photos-a.akamaihd.net.
+i2.ytimg.com.
+www.mexicantextiles.com.
+86.186.162.189.in-addr.arpa.
+q.ebaystatic.com.
+ox-i.earnmydegree.com.
+a.root-servers.net.
+rj.m.taobao.com.
+83.225.102.201.in-addr.arpa.
+98.164.246.220.in-addr.arpa.
+time.nist.gov.
+82.63.114.98.in-addr.arpa.
+mx.accuratecontrols.com.
+notifications.conduit-services.com.
+clients2.google.com.
+upload.traidnt.net.
+code.jquery.com.
+www.minispel.be.
+fbcdn-photos-a.akamaihd.net.
+plusone.google.com.
+11.241.83.62.in-addr.arpa.
+www.chinasportsbeat.com.
+photos-f.ak.fbcdn.net.
+safebrowsing-cache.google.com.
+50.143.46.68.in-addr.arpa.
+adkny.org.
+bhk.spb.ru.
+groups.google.com.mx.
+lindaburwell.com.
+247.82.154.187.in-addr.arpa.
+rad.msn.com.
+t.co.
+a.root-servers.net.
+100.63.31.83.in-addr.arpa.
+keetchins.com.
+nordix-metrology.ru.
+_348_69_5.
+myrealfanatictv.blogspot.com.
+carp3.rjf.com.
+s-static.ak.facebook.com.
+95.146.220.66.in-addr.arpa.
+www.xvidupdate.com.
+by2msg3030108.by2.gateway.edge.messenger.live.com.
+235.177.109.186.in-addr.arpa.
+www.bywifi.com.
+www.angelteenagers.com.
+t.337.com.
+ssl.google-analytics.com.
+atyab.com.
+www.rmkstore.com.
+external.ak.fbcdn.net.
+eck7.ru.
+nychhc.org.
+ccnow.wip.digitalrivercontent.net.
+tools.google.com.
+img25.imageshack.us.
+profile.ak.fbcdn.net.
+www.google.com.
+nakara.china.alibaba.com.
+a1.sphotos.ak.fbcdn.net.
+wiki.bssd.org.
+pixel.facebook.com.
+static.ak.connect.facebook.com.
+83.65.29.85.in-addr.arpa.
+148.102.238.190.in-addr.arpa.
+nt3.ggpht.com.
+138.65.16.95.in-addr.arpa.
+jetzt.sueddeutsche.de.
+www.energy-base.org.
+www.mywebsearch.comm.
+mail.sumtel.ru.
+52.183.137.85.in-addr.arpa.
+124.15.0.10.in-addr.arpa.
+39.251.6.201.in-addr.arpa.
+a.root-servers.net.
+a2.wupload.com.
+83.173.110.190.in-addr.arpa.
+236.192.71.190.in-addr.arpa.
+amai.org.
+download-notebook-drivers.com.
+a.root-servers.net.
+www.google.com.
+moshmosh.22web.net.
+www.noticias15m.eu.
+americas.cpqcorp.net.
+b._dns-sd._udp.0.1.168.192.in-addr.arpa.
+backend8.aha.ru.
+verizon.net.
+fc79.deviantart.com.
+weather.services.conduit.com.
+204.118.156.187.in-addr.arpa.
+25.32.254.201.in-addr.arpa.
+google.com.
+a1496.da1.akamai.net.
+content.yieldmanager.edgesuite.net.
+a.root-servers.net.
+www.marcominnemann.com.
+tnz.taleo.net.
+www.art-exchange.com.
+64.243.45.151.in-addr.arpa.
+ssl-i.cdn.openx.com.
+z122cn2ej.z77s3e1e.
+250.84.5.87.in-addr.arpa.
+254.104.149.187.in-addr.arpa.
+59.66.222.24.in-addr.arpa.
+127.0.0.1.
+creative.ak.fbcdn.net.
+144.184.137.69.in-addr.arpa.
+211.158.95.2.in-addr.arpa.
+w7845x9xa.07uc.
+photos-f.ak.fbcdn.net.
+a1725.l.akamai.net.
+external.ak.fbcdn.net.
+51.233.227.189.in-addr.arpa.
+www.origenae.com.
+external.ak.fbcdn.net.
+wwws.ru.warnerbros.com.
+www.xvideos.com.
+pixel.facebook.com.
+www.facebook.com.
+adx.adnxs.com.
+a.root-servers.net.
+www.google.com.
+www.microsoft.com.
+41.167.8.200.in-addr.arpa.
+www.villagegeek.com.
+gmail-smtp-in.l.google.com.
+pagead2.googlesyndication.com.
+iadsdk.apple.com.
+creacionesycrochet.blogspot.com.
+elitaudit.ru.
+www.aasp.org.br.
+fitnessfirst.com.
+39-courier.push.apple.com.
+cande-knd.deviantart.com.
+nsx.np.dl.playstation.net.
+30.media.tumblr.com.
+pixel.facebook.com.
+directory.services.live.com.
+googleads.g.doubleclick.net.
+mk.wikipedia.org.
+safebrowsing.clients.google.com.
+ak.copi.ru.
+franational.com.
+js.admeld.com.
+ins-solutions.com.
+www.ukmediacentre.pwc.com.
+a.root-servers.net.
+empretsinf.blogs.upv.es.
+a.root-servers.net.
+www.pcl.com.
+icex.imperial.ac.uk.
+swim.lookbook.nu.
+news.google.com.mx.
+91chat.wisshen.info.
+dannyayers.com.
+platform.ak.fbcdn.net.
+www.google.com.
+photos-c.ak.fbcdn.net.
+mail.google.com.
+a.root-servers.net.
+trumedtech.com.s9a1.psmtp.com.
+pyninc.org.
+dvrlink.net.
+platform.ak.fbcdn.net.
+a.root-servers.net.
+p7:aaqlv3.s32o1p9v.
+30.164.69.190.in-addr.arpa.
+babelfish.altavista.digital.com.
+mail.ead-sda.ru.
+content.yieldmanager.edgesuite.net.
+159.61.48.188.in-addr.arpa.
+50.174.50.201.in-addr.arpa.
+sn130w.snt130.mail.live.com.
+asu.vks.mosenergo.elektra.ru.
+jers3.info.
+external.ak.fbcdn.net.
+photos-a.ak.fbcdn.net.
+pixel.facebook.com.
+131.33.174.190.in-addr.arpa.
+b._dns-sd._udp.0.0.168.192.in-addr.arpa.
+red.adshandy.com.
+157.65.132.189.in-addr.arpa.
+curado.ru.
+sheapfel-music.blogspot.com.
+vzppdvhisqea.com.
+cards.mail.ru.
+marbellatraumhaus.de.
+barjaweb.free.fr.
+rewards.ebay.com.
+a1.sphotos.ak.fbcdn.net.
+img.123freebrushes.com.
+d8.ce.bb.a1.top.mail.ru.
+desmond.yfrog.com.
+www.radianresearch.com.
+francais.toptwilightblogs.com.
+ad.yieldmanager.com.
+twitter.com.
+www.extube.com.
+naranjas-limones.blogspot.com.
+domein.nl.
+www.canimmigratecanada.com.
+ace.wikipedia.org.
+commons.wikimedia.org.
+baymsg1030112.gateway.messenger.live.com.
+tis17-5-en.url.trendmicro.com.
+a1406.w42.akamai.net.
+pansexualpride.tumblr.com.
+www.maishoroscopo.com.br.
+montagar.com.
+www.xplonet.net.
+neoretro.tumblr.com.
+www.facebook.com.
+xxx.stopklatka.pl.
+safebrowsing.clients.google.com.
+www.digwin.com.
+dollhousediary.com.
+dr._dns-sd._udp.0.2.168.192.in-addr.arpa.
+api-read.facebook.com.
+sp.ask.com.
+cdn-7.nflximg.com.
+octoberon.blogspot.com.
+photos-d.ak.fbcdn.net.
+pagead2.googlesyndication.com.
+trendtechnology.com.
+83.72.102.71.in-addr.arpa.
+m.addthisedge.com.
+feeds.feedburner.com.
+entretenimiento.starmedia.com.
+rs896l33.rapidshare.com.
+www.fm88-108.nl.
+gateway.arabia-ins.com.lb.
+photos-a.ak.fbcdn.net.
+233.208.124.186.in-addr.arpa.
+20minutos.feedsportal.com.
+34.139.137.187.in-addr.arpa.
+docs.google.com.
+www.facebook.com.
+174.137.220.41.in-addr.arpa.
+a8.sphotos.ak.fbcdn.net.
+apple.com.
+en.globetorch.com.
+53.221.132.192.in-addr.arpa.
+www.blogger.com.
+www.sgisland.gs.
+57.186.48.65.in-addr.arpa.
+e566.b.akamaiedge.net.
+piim.com.
+61.236.56.187.in-addr.arpa.
+datafeed.weatherbug.com.
+24-courier.push.apple.com.
+d2105352.xoom.it.
+140.108.27.189.in-addr.arpa.
+download.windowsupdate.com.
+profile.ak.fbcdn.net.
+hi-in.facebook.com.
+www.wikicristiano.org.
+147.22.161.101.in-addr.arpa.
+mail.s1000658.ptasp.com.
+a.root-servers.net.
+draxis.com.
+rcp.na.blackberry.com.
+pixelsmuertos.com.
+creaturesofcomfort.us.
+240.233.85.85.in-addr.arpa.
+bogdanos.skai.gr.
+anycoolspb.ru.
+mx4.peterhost.ru.
+www.lacaxcada.com.
+194.253.150.79.in-addr.arpa.
+q2broadcasting.com.
+www.world-finance-conference.com.
+enternet.hu.
+www.artesaniaelsol.es.
+static.ak.fbcdn.net.
+twitter.com.
+init-p01md.apple.com.
+a2.sphotos.ak.fbcdn.net.
+www.diariopyme.com.
+static-js.veevr.com.
+73.73.78.190.in-addr.arpa.
+api.facebook.com.
+de-de.facebook.com.
+a3.sphotos.ak.fbcdn.net.
+www.smlisten.dk.
+82.103.157.98.in-addr.arpa.
+geo.messenger.services.live.com.
+lib.verycd.com.
+115.83.145.190.in-addr.arpa.
+mail.live.com.
+resolver1.bullguard.ctmail.com.
+123.86.172.190.in-addr.arpa.
+tw.apple.com.
+beta.twitlonger.com.
+a1.sphotos.ak.fbcdn.net.
+f26batchimg.auctions.yahoo.co.jp.
+weather.partners.msn.com.
+www.google.com.
+129.146.176.124.in-addr.arpa.
+google.com.
+dsn2.d.skype.net.
+www.islam101.com.
+external.ak.fbcdn.net.
+api.nanigans.com.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+profile.ak.fbcdn.net.
+onskookboek.be.
+tools.google.com.
+profile.ak.fbcdn.net.
+clients4.google.com.
+controltemp.com.
+plus.google.com.
+a.root-servers.net.
+1.0.0.127.dnsbugtest.1.0.0.127.in-addr.arpa.
+csi.gstatic.com.
+126.74.9.46.in-addr.arpa.
+profile.ak.fbcdn.net.
+i1.ytimg.com.
+www.google.com.
+2.248.199.190.in-addr.arpa.
+about.duke.edu.
+mueller-runte.de.
+www.italkcash.com.
+chicvintagebrides.com.
+28.181.92.108.in-addr.arpa.
+www.hotel-theresia.com.
+photos-d.ak.fbcdn.net.
+inbound.bulkpetro.com.netsolmail.net.
+dns.msftncsi.com.
+amdinternet.com.
+27.78.8.201.in-addr.arpa.
+220.95.37.46.in-addr.arpa.
+a996.mm1.akamai.net.
+wwwclu.um.es.
+www.toshibapc.com.
+kibbey.net.
+189.250.65.187.in-addr.arpa.
+www.conjugacionesverbos.com.
+a.root-servers.net.
+retera.ru.
+a2.sphotos.ak.fbcdn.net.
+plusone.google.com.
+www.pro-billiard.ru.
+assets.treasure.zgncdn.com.
+api.facebook.com.
+nxa-ls.s3.amazonaws.com.
+a1725.l.akamai.net.
+svrintl-crl.verisign.com.
+zi.net.
+crl3.digicert.com.
+777777.6d696e696e6f7661.6f7267.80h505e4c05.webcfs00.com.
+insight.aon.com.
+shared.live.com.
+windowslivehelp.com.
+facebook-chat.softonic.de.
+msnbcmedia.msn.com.
+google.com.
+a5.sphotos.ak.fbcdn.net.
+litvany.com.
+farm6.staticflickr.com.
+www.ambito.com.
+66.59.229.189.in-addr.arpa.
+accounts.youtube.com.
+mail.yahoo.com.
+www.despegar.com.mx.
+moseisleyradio.com.
+www.jq663.com.
+edge.quantserve.com.
+ru.wikipedia.org.
+a997.mm1.akamai.net.
+www.denacrain.com.
+www-google-analytics.l.google.com.
+s-external.ak.fbcdn.net.
+a7.sphotos.ak.fbcdn.net.
+mta5.am0.yahoodns.net.
+219.207.141.201.in-addr.arpa.
+clients1.google.com.
+www.newszoom.com.
+110.8.240.111.in-addr.arpa.
+140.34.230.67.in-addr.arpa.
+cffei.org.s5a1.psmtp.com.
+49.161.168.192.in-addr.arpa.
+contextmenu.toolbar.conduit-services.com.
+t1-completion.amazon.com.
+pt-br.facebook.com.
+www.google.com.
+id.l.google.com.
+connect.facebook.net.
+ed62.zeekler.com.
+56.82.42.201.in-addr.arpa.
+www.sm-rgs.com.
+groups.google.com.mx.
+a.root-servers.net.
+www.bloomenergy.com.
+58.235.55.74.in-addr.arpa.
+71.179.232.190.in-addr.arpa.
+www.freestream.pl.
+d7.zedo.com.
+thirdnetworks.com.
+api.facebook.com.
+249.110.148.190.in-addr.arpa.
+mail.nicox.it.
+mail.pierce-industries.com.
+serw.clicksor.com.
+128.222.173.190.in-addr.arpa.
+a4.sphotos.ak.fbcdn.net.
+157.174.246.201.in-addr.arpa.
+43.107.25.114.in-addr.arpa.
+a4.sphotos.ak.fbcdn.net.
+download.cloudantivirus.com.
+aj8q45hdn.10qe.
+splcen.blogspot.com.
+a.root-servers.net.
+gemma-international.co.uk.
+favstar.fm.
+sillylikes.com.
+cs244.vk.com.
+creative.ak.fbcdn.net.
+a7.sphotos.ak.fbcdn.net.
+hu.wikipedia.org.
+anomalink.com.
+lh4.googleusercontent.com.
+images.apple.com.
+13.62.173.190.in-addr.arpa.
+a7.sphotos.ak.fbcdn.net.
+115.222.142.190.in-addr.arpa.
+34.204.14.186.in-addr.arpa.
+netthere.com.
+a3.sphotos.ak.fbcdn.net.
+pixel.facebook.com.
+www.gratispeliculas.org.
+teredo.ipv6.microsoft.com.
+tap2-cdn.rubiconproject.com.
+ad.adnetwork.net.
+www.facebook.com.
+s-static.ak.facebook.com.
+ads.bluelithium.com.
+a7.sphotos.ak.fbcdn.net.
+s0000686.ecdomain.net.forestproducts.sca.com.
+indepsocres.spb.ru.
+apps.facebook.com.
+ex2.broadser.
+billpentz.com.
+upxewi.com.
+www.ark.ac.uk.
+img20.imageshack.us.
+a.root-servers.net.
+www.youtube.com.
+ochaonline.un.org.
+morgan.kyschools.us.
+17.204.141.201.in-addr.arpa.
+www.apexjr.com.
+kkaqhzl:a.u21y9s7g.
+mozhelah.com.
+a.root-servers.net.
+mx.youtube.com.
+rcp.na.blackberry.com.
+explore.live.com.
+acor.org.
+a3.twimg.com.
+graph.facebook.com.
+guru.avg.com.
+www.facebook.com.
+www.gemma.es.
+a.root-servers.net.
+d3lvr7yuk4uaui.cloudfront.net.
+eyepatchfilms.com.
+profile.ak.fbcdn.net.
+lacasadecloti.blogspot.com.
+profile.ak.fbcdn.net.
+img7.imageshack.us.
+a1.sphotos.ak.fbcdn.net.
+api.twitter.com.
+170.251.91.186.in-addr.arpa.
+214.53.130.72.in-addr.arpa.
+secure.gravatar.com.
+gameplay.mochimedia.com.
+timmermanco.com.
+www.anythingtostopthepain.com.
+188.141.39.190.in-addr.arpa.
+profile.ak.fbcdn.net.
+analisismatematico.wordpress.com.
+www.esi-audiotechnik.com.
+a.root-servers.net.
+rxdrugstore-pro.com.
+157.17.149.190.in-addr.arpa.
+www.cemexcolombia.com.
+blog.advancedphotoshop.co.uk.
+ksn1-11-part1.kaspersky-labs.com.
+sn122w.snt122.mail.live.com.
+schaubroeck.be.
+194.206.162.189.in-addr.arpa.
+files.rsf-es.org.
+cs4100.vkontakte.ru.
+cwahi.net.multi.uribl.com.
+eu4.grannytaste.com.
+samsungmobile.accu-weather.com.
+tematica.mercadolibre.com.ve.
+tecnociencia.co.
+www.tenseconds.com.au.
+anuncie.taringa.net.
+www.planetahuerto.es.
+www.isearch.im.
+www.bg.gladiatus.com.
+www.google-analytics.com.
+a7.sphotos.ak.fbcdn.net.
+mail.jlk.com.
+mlsksfkajsfsa.com.
+rentar-casa.vivastreet.com.mx.
+thethirdestate.net.
+cwomissions.org.
+182.241.59.200.in-addr.arpa.
+94.146.203.190.in-addr.arpa.
+cdn.api.twitter.com.
+tecnologia.starmedia.com.
+webcognisant.com.
+102.184.38.190.in-addr.arpa.
+www.youtube.com.
+146.9.165.189.in-addr.arpa.
+wg8.so-net.ne.jp.
+a-0.19-22092081.20200b3.1518.19d3.3ea1.410.0.sddcpssrmu8th8pkmqaj6ca6p6.avqs.mcafee.com.
+www.powerpresspodcast.com.
+a.root-servers.net.
+www.thedandyproject.com.
+developers.facebook.com.
+136.93.52.59.in-addr.arpa.
+107.181.153.189.in-addr.arpa.
+babesbycity.com.
+fbcdn-profile-a.akamaihd.net.
+mail.iiwengr.com.
+www.planetfortress.com.
+webographers.com.
+yahoo.com.
+althenia.net.
+ltgqcs.com.
+www.multiautomotores.com.ar.
+www.facebook.com.
+a6.sphotos.ak.fbcdn.net.
+a2.sphotos.ak.fbcdn.net.
+developers.facebook.com.
+static.supadupa.me.
+pt-br.facebook.com.
+www.axeso5.com.
+google.com.
+42.43.237.190.in-addr.arpa.
+88.100.232.24.in-addr.arpa.
+www.bywifi.com.
+a2.sphotos.ak.fbcdn.net.
+235.217.208.201.in-addr.arpa.
+error404.000webhost.com.
+_291_07_6.
+faces.doccheck.com.
+85.111.51.190.in-addr.arpa.
+fr.webrep.avast.com.
+www.woldoringa.com.
+dusty.sensi.org.
+img11.imageshack.us.
+an.wikipedia.org.
+www.plasteck.cl.
+www.facebook.com.
+api.twitter.com.
+a1.espncdn.com.
+cs.adxpansion.com.
+a639.da1.akamai.net.
+101.17.153.201.in-addr.arpa.
+81.211.179.178.in-addr.arpa.
+s.ytimg.com.
+gihfvp1mq.60bb.
+101.103.97.71.in-addr.arpa.
+dr._dns-sd._udp.belkin.
+169.202.78.177.in-addr.arpa.
+www.formacionoptometrica.com.
+www.roodos.com.ve.
+pronetworksolutions.net.
+www.pasarmiedo.net.
+kroupnov.ru.
+s.ytimg.com.
+a1.sphotos.ak.fbcdn.net.
+2009-861.blog.163.com.
+www-google-analytics.l.google.com.
+157.15.46.207.in-addr.arpa.
+38.159.220.77.in-addr.arpa.
+131.196.113.177.in-addr.arpa.
+gclsupport.nhl.com.
+fpsaw35c3.o58z1z8n.
+a5.sphotos.ak.fbcdn.net.
+us.bc.yahoo.com.
+apple.imap.mail.yahoo.com.
+configuration.apple.com.
+biztravels-museums.net.
+cdn-2emediafire-2ecom-2fblank-2ehtml.ph.bdrbl.com.
+www.themendo.com.
+232.29.27.72.in-addr.arpa.
+137.169.158.94.in-addr.arpa.
+sites.google.com.
+a.root-servers.net.
+news.google.com.mx.
+i1.ytimg.com.
+profile.ak.fbcdn.net.
+a.root-servers.net.
+csi.gstatic.com.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+www.stlawrencecollege.ca.
+homevalleybank.com.
+4.233.213.201.in-addr.arpa.
+182.194.230.189.in-addr.arpa.
+mail2.globalddh.net.
+images6.porkolt.com.
+sn1msg2010622.gateway.messenger.live.com.
+video.google.com.mx.
+marmweb.com.
+a6.sphotos.ak.fbcdn.net.
+www.z-sys.org.
+cs9394.vk.com.
+money.service.msn.com.
+a.root-servers.net.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+lh3.googleusercontent.com.
+us.ebmpapst.com.
+www.q8land.net.
+error.facebook.com.
+mail.outdoorimage.com.au.
+tags.expo9.exponential.com.
+www.noticias.com.
+29-courier.push.apple.com.
+img810.imageshack.us.
+rospres.com.
+labotp.org.
+233.168.227.189.in-addr.arpa.
+s3.productwiki.com.
+www.efe2003.com.
+221.158.255.190.in-addr.arpa.
+ads.adxpose.com.
+31-courier.push.apple.com.
+apple.com.
+233.252.244.99.in-addr.arpa.
+mail.
+mail.carmensvacuum.com.
+nnnn.com.
+akqa.com.s5b2.psmtp.com.
+paraellas.net.
+img2.etsystatic.com.
+242.139.181.78.in-addr.arpa.
+server5.cnsonline.com.
+profile.ak.fbcdn.net.
+telephonecode.ru.
+cacheck.ey.net.
+astrotrans.blogspot.com.
+a.root-servers.net.
+www.cdtracks.org.
+secure-us.imrworldwide.com.
+ch.foto.com.
+thefutblog.info.
+mail.seiko-i.com.
+a.root-servers.net.
+34-courier.push.apple.com.
+artdography.com.
+www.myriamfaresfans.com.
+ad.bmo.tbn.ru.
+eaacorp.com.
+m.hotmail.com.
+91.95.134.115.in-addr.arpa.
+a5.sphotos.ak.fbcdn.net.
+email.urbanoutfitters.com.
+www.facebook.com.
+profile.ak.fbcdn.net.
+38.100.8.200.in-addr.arpa.
+e1789.c.akamaiedge.net.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+usd416.org.
+ad-emea.doubleclick.net.
+sunchem.ru.
+www.narcissism101.com.
+169.45.43.186.in-addr.arpa.
+a5.sphotos.ak.fbcdn.net.
+214.122.244.61.in-addr.arpa.
+140.225.224.24.in-addr.arpa.
+googleads.g.doubleclick.net.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+sp.cwfservice.net.
+www.youtube.com.
+goponygo.com.
+d2098345.xoom.it.
+www.project-lime.com.
+a1725.l.akamai.net.
+partyheld.de.
+248.230.202.190.in-addr.arpa.
+grandrating.ru.
+fr.fxfeeds.mozilla.com.
+ssl.gstatic.com.
+www.hairoin.de.
+124.197.144.187.in-addr.arpa.
+127.165.146.187.in-addr.arpa.
+www.amaitlan.mx.
+adserving.cpxinteractive.com.
+gr4kcwiaw.g66s8x7v.
+cap1.conduit-apps.com.
+mx1.satelcom.qc.ca.
+www.trafficfactory.biz.
+r6xmlzsah.19av.
+21.82.245.189.in-addr.arpa.
+mail.kingroup.ru.
+able.co.uk.
+bchy4g:o4.68qi.
+68.8.120.189.in-addr.arpa.
+www.ole.com.ar.
+coches-actu.com.
+faypublicidad.com.
+133.150.58.85.in-addr.arpa.
+yahoo.com.
+xcdn.xgraph.net.
+urs.microsoft.com.
+andersonsecurity.com.
+www.mcc.is.
+time.chttl.com.tw.
+www.djlah.net.
+divison8.mcanime.net.
+173.72.66.190.in-addr.arpa.
+_529_50_0.
+www.strictdownload.com.
+bugmpa.com.
+superoil.ru.
+45.44.90.186.in-addr.arpa.
+v9.lscache4.googlevideo.com.
+widget.uservoice.com.
+a1.sphotos.ak.fbcdn.net.
+webcameffects.softonic.com.
+accounts.google.com.
+photos-c.ak.fbcdn.net.
+a.root-servers.net.
+24.18.246.190.in-addr.arpa.
+repo666.ultrasn0w.com.
+138.178.125.84.in-addr.arpa.
+artbatik.ru.
+fifelife.ru.
+89.79.55.65.in-addr.arpa.
+www.losgobernadores.com.
+profile.ak.fbcdn.net.
+apis.google.com.
+225.89.132.190.in-addr.arpa.
+a.root-servers.net.
+www.kaixindian.com.
+entre-pensamientos.blogspot.com.
+www.ebayers.es.
+www.panetdeal.co.il.
+saimecha.wordpress.com.
+farorbit.com.
+www.primarydisplays.co.uk.
+solo.aqui.creatusfrases.net.
+maudnewton.com.
+www.prettyteenpics.com.
+carmen-ysusrecetas.blogspot.com.
+memrb.spb.su.
+feedroom.speedera.net.
+msupdate.emodio.com.
+.
+54.12.156.186.in-addr.arpa.
+27.229.235.89.in-addr.arpa.
+photos-h.ak.fbcdn.net.
+117.29.224.189.in-addr.arpa.
+www.facebook.com.
+waterhunters.ru.
+mystart.uservoice.com.
+254.166.109.200.in-addr.arpa.
+128.187.68.177.in-addr.arpa.
+www.rolisimas.com.
+www.naharro.com.
+bit.ly.
+1jhw3vc93.t79x7g0y.
+developers.facebook.com.
+photos-g.ak.fbcdn.net.
+_925_22_3.
+citukerala.org.
+133.139.62.186.in-addr.arpa.
+58.109.43.114.in-addr.arpa.
+nooopuedeser.blogspot.com.
+google.com.
+corporatefitnessworks.com.
+1.bp.blogspot.com.
+59.1.26.96.in-addr.arpa.
+4.209.150.189.in-addr.arpa.
+www.sodoku.com.
+130.235.55.74.in-addr.arpa.
+creative.ak.fbcdn.net.
+www.eluniversaltv.com.mx.
+byrdr.omega.contacts.msn.com.
+www.importjap.com.
+ads2.msads.net.
+www.herbalifemauralaussanjuan.es.tl.
+47.224.25.177.in-addr.arpa.
+233.129.28.187.in-addr.arpa.
+mortenjust.com.
+109.113.88.186.in-addr.arpa.
+twitter.com.
+robinson-derus.co.nz.
+poverh.kiev.ua.
+i2.ytimg.com.
+www.zonajobs.com.ar.
+hotmail.com.
+www.amazon.es.
+profile.ak.fbcdn.net.
+a.root-servers.net.
+graph.facebook.com.
+jkt.spb.ru.
+a.root-servers.net.
+i3.ytimg.com.
+.
+mail1.chemspec.com.
+kuhnyatv.ru.
+allure.com.
+34.49.218.202.in-addr.arpa.
+www1.k9webprotection.com.
+healthcontent.bhsi.com.
+www.twitter.com.
+www.googleadservices.com.
+instagib.net.
+www.bansa.org.
+97.205.27.77.in-addr.arpa.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+56.225.102.190.in-addr.arpa.
+115.146.110.201.in-addr.arpa.
+google.com.
+rawwordrecords.com.
+db._dns-sd._udp.0.1.168.192.in-addr.arpa.
+_336_08_7.
+zxtm-vnxhosapaha.nexica.net.
+www.buzzfocus.com.
+52.121.87.213.in-addr.arpa.
+apple.com.
+ugzxbcuhe.35qq.
+hotword.dictionary.com.
+mobile.airasia.com.
+sgqsyeaoes.com.
+151.149.247.190.in-addr.arpa.
+www.google-analytics.com.
+229.169.209.201.in-addr.arpa.
+www.facebook.com.
+www.mediachannel.com.
+www.amazon.com.
+i4.ytimg.com.
+profile.ak.fbcdn.net.
+img.nextproducts.net.
+time.chttl.com.tw.
+a4.mzstatic.com.
+244.207.240.148.in-addr.arpa.
+static.ak.fbcdn.net.
+www.desktopgoldfish.com.
+b._dns-sd._udp.0.10.168.192.in-addr.arpa.
+53.143.168.192.in-addr.arpa.
+developers.facebook.com.
+airs.jpl.nasa.gov.
+www.youtube.com.
+www.anarchistcookbookz.com.
+mail.cyrbustours.com.
+32-courier.push.apple.com.
+www.tpwang.net.
+color-by-numbers.net.
+umail.net.
+mail.promtractor.ru.
+update3.jdownloader.org.
+www.mcanime.net.
+thomarie-fanclub.deviantart.com.
+29.72.149.99.in-addr.arpa.
+a3.sphotos.ak.fbcdn.net.
+mail.plasa.com.
+api.conduit.com.
+www.facebook.com.
+time.nist.gov.
+api.conduit.com.
+p0b.ru.
+.
+www.update.microsoft.com.
+checkip.dyndns.org.
+39.49.10.75.in-addr.arpa.
+idipus.tumblr.com.
+www.encuentro-practico.com.
+www.yahoo.com.
+nonghai.net.multi.uribl.com.
+www.w3.org.
+231.11.223.148.in-addr.arpa.
+blog.metropolislibros.com.
+by2msg3010518.by2.gateway.edge.messenger.live.com.
+me.effectivemeasure.net.
+www.datefree.com.
+tw.pool.ntp.org.
+bs.serving-sys.com.
+mail.gestionrv.com.
+d3lvr7yuk4uaui.cloudfront.net.
+graph.facebook.com.
+client-software.real.com.
+csc3-2010-crl.verisign.com.
+fr-fr.facebook.com.
+modern-glass.com.
+oldis.ru.
+east-west.fr.
+www.google.com.
+240.60.55.174.in-addr.arpa.
+196.139.177.190.in-addr.arpa.
+animesite2.blogspot.com.
+air-control.softonic.com.
+103.198.79.188.in-addr.arpa.
+.
+www.justin.tv.
+smokingmirrors.blogspot.com.
+img100.xvideos.com.
+www.google.com.
+repositori.upf.edu.
+www.cenetec.salud.gob.mx.
+b._dns-sd._udp.0.2.168.192.in-addr.arpa.
+final-fantasy-x-tidus.programasgratis.es.
+www.google.com.
+muzy.com.
+254.1.168.192.in-addr.arpa.
+vbe.cci.
+60.68.141.201.in-addr.arpa.
+isatap.home.
+l.yimg.com.
+artesiatech.com.
+bleah.com.
+roitrack.urtbk.com.
+_897_64_8.
+a.root-servers.net.
+www4.l.google.com.
+exp01.eset.com.
+105.245.231.77.in-addr.arpa.
+yztkxo2fh.63tm.
+mail.clvec.ie.
+39-courier.push.apple.com.
+www.google-analytics.com.
+earthds.info.
+profile.ak.fbcdn.net.
+mail.mtremblay.com.
+evermor.net.
+a6.sphotos.ak.fbcdn.net.
+224.92.131.187.in-addr.arpa.
+lrhvridjyg.info.
+dl.macpaw.com.
+glueckkanja-de.mail.eo.outlook.com.
+fb-client-0.castle.zynga.com.
+mscrl.microsoft.com.
+www.weheartit.com.
+omikom.ru.
+kriminalforsorgen.dk.
+mx3.hotmail.com.
+mail.guarantyresearch.com.
+host356.hostmonster.com.
+carservis.pl.
+santarom.ru.
+68ohh6com6c1h-c.c.yom.mail.yahoo.com.
+b.static.ak.fbcdn.net.
+www.todoferreteria.com.
+207.234.226.189.in-addr.arpa.
+a3.sphotos.ak.fbcdn.net.
+mog.com.
+a1.twimg.com.
+a.root-servers.net.
+simurl.com.
+mail.fbcpalmetto.com.
+d7.zedo.com.
+creative.ak.fbcdn.net.
+huuah.com.
+fkjdeljfeew32233.com.
+www.facebook.com.
+www.adobe.com.
+ssl.gstatic.com.
+sartaonline.com.1.0001.arsmtp.com.
+62.158.220.66.in-addr.arpa.
+gpl-violations.org.
+takvim.com.tr.
+foto36.com.
+a.root-servers.net.
+s-static.ak.fbcdn.net.
+www.20minutos.es.
+wheelsworldwide.co.uk.
+www.youtube.com.
+www.addthis.com.
+api.twitter.com.
+elchavodelocho.bravehost.com.
+barochanynicky.su.
+138.33.247.190.in-addr.arpa.
+bit.ly.
+phoenixtechnology.com.
+l.sharethis.com.
+thecloudplayer.com.
+bizinformation.org.
+173.5.172.201.in-addr.arpa.
+pixel.facebook.com.
+haveasenseofhumor.cheezburger.com.
+www.blogpulp.com.
+remote.rtcimpex.ru.
+i25nvbyk27l68k47m39jqg23p42kvb28mwjycunr.net.
+a.root-servers.net.
+191.169.208.77.in-addr.arpa.
+fannin.k12.ga.us.
+b.scorecardresearch.com.
+_464_80_6.
+biouzhen.dyndns-server.com.
+qeeq.net.
+service.gc.apple.com.
+152.52.154.98.in-addr.arpa.
+platform.ak.fbcdn.net.
+a.root-servers.net.
+www.chitambo.com.
+it-it.facebook.com.
+tsvetyoptom.ru.
+163.40.23.71.in-addr.arpa.
+content.everydayhealth.com.
+www.google-analytics.com.
+185.127.149.187.in-addr.arpa.
+ssl.gstatic.com.
+a-0.19-2209d081.c030083.1518.19d2.3ea1.410.0.d5g4l32d6jgjp7wsn6vrk57hvq.avqs.mcafee.com.
+rs571l33.rapidshare.com.
+photos-e.ak.fbcdn.net.
+mscrl.microsoft.com.
+susana-solea.blogspot.com.
+smtp.yopmail.com.
+www.translate.ge.
+tdy.prodigy.msn.com.
+rmd3f8mbk.v20u1c3h.
+videos-gratis.petardas.com.
+www.consultadetarotgratuita.com.
+merriam-webster.sl.advertising.com.
+clasificados.fiestaideas.com.
+daa-spokane.com.
+probe.iomegacloud.com.
+a.root-servers.net.
+profile.ak.fbcdn.net.
+zcache.zgncdn.com.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+www.facebook.com.
+www.clubcassiecruz.com.
+34.5.254.41.in-addr.arpa.
+tools.google.com.
+88.28.14.187.in-addr.arpa.
+235.145.248.81.in-addr.arpa.
+cdn.naxpgaming.com.
+12.92.45.190.in-addr.arpa.
+pacificu.edu.
+t4.tagstat.com.
+110.19.34.94.in-addr.arpa.
+graphics478.nytimes.com.edgesuite.net.
+www.graydenpoper.com.
+guru.avg.com.
+ad.aim4media.com.
+twitter.com.
+192.194.208.108.in-addr.arpa.
+93.142.174.189.in-addr.arpa.
+climat24.ru.
+www.nabdh-alm3ani.net.
+beta.stun.voice.yahoo.com.
+www.ajnonline.com.
+photos-a.ak.fbcdn.net.
+darkshadows.wikia.com.
+60.130.15.189.in-addr.arpa.
+urs.microsoft.com.
+161.218.60.187.in-addr.arpa.
+pixel.facebook.com.
+suomi24.com.
+tools.google.com.
+static.ak.fbcdn.net.
+134.173.116.200.in-addr.arpa.
+sync.mathtag.com.
+data.flurry.com.
+39.183.220.62.in-addr.arpa.
+www.kt2syggf436dtag646.com.
+www.toonsup.de.
+rcw.wc24.wii.com.
+www.tko24.com.
+www.adobe.com.
+test-rt.liftdna.com.
+api.conduit.com.
+fabulousims.blogspot.com.
+www.entertainmentworld.us.tt.
+photos-e.ak.fbcdn.net.
+platform.ak.fbcdn.net.
+group.hawahome.com.
+aimnet.net.
+a.root-servers.net.
+a.root-servers.net.
+googleads.g.doubleclick.net.
+www.l.google.com.
+search.bittorrent.com.
+webexpromt.ru.
+v2.cache1.c.youtube.com.
+www.google-analytics.com.
+132.122.114.200.in-addr.arpa.
+www.facebook.com.
+d15gt9gwxw5wu0.cloudfront.net.
+manyue.com.
+photographers.co.uk.
+bs.serving-sys.com.
+www.jatox.com.
+www.googleadservices.com.
+photos-e.ak.fbcdn.net.
+35.129.134.186.in-addr.arpa.
+mail.rstrents.com.
+veureka.net.
+coyoacan.linkbyme.com.mx.
+g.ceipmsn.com.
+sbcglobal.net.
+img.csfd.cz.
+www.linkedin.com.
+m1.webstats.motigo.com.
+www.elmundoenpositivo.com.
+a.root-servers.net.
+114.124.225.190.in-addr.arpa.
+58.72.52.99.in-addr.arpa.
+cdn-0.nflximg.com.
+86.108.221.90.in-addr.arpa.
+tap2-cdn.rubiconproject.com.
+proxy-77.ix.dailymotion.com.
+j2.yokacdn.com.
+external.ak.fbcdn.net.
+decoradecora.blogspot.com.
+profile.ak.fbcdn.net.
+138.13.94.188.in-addr.arpa.
+no10.unternehmen.com.
+mail2.elar.ru.
+clientstat.rockyourphone.com.
+253.225.85.85.in-addr.arpa.
+l.yimg.com.
+s0.2mdn.net.
+photos-g.ak.fbcdn.net.
+kinisoku.sakura.ne.jp.
+adv-lance.com.
+www.google.com.
+api-read.facebook.com.
+n8.8-d.com.
+sunde.com.inbound15.mxlogic.net.
+intercambio-compra-venta.blogspot.com.
+117.121.183.189.in-addr.arpa.
+www.perriguay.com.
+ajax.googleapis.com.
+www.google.com.
+widgets.twimg.com.
+sb-mail.sbci.com.
+211.214.200.190.in-addr.arpa.
+pt-br.facebook.com.
+36.9.222.77.in-addr.arpa.
+okoninc.com.
+a1.sphotos.ak.fbcdn.net.
+www.facebook.com.
+crl.verisign.com.
+cdn.enterupload.com.
+val-test.com.
+weather.wapp.wii.com.
+www.lib.utulsa.edu.
+sites.google.com.
+ksn2.kaspersky-labs.com.
+digg.com.
+x.tagstat.com.
+campbellalliance.com.s8b2.psmtp.com.
+www.pantallazoazul.net.
+pro.vrn.ru.
+outtengolden.com.
+dns.msftncsi.com.
+saltydroid.info.
+www.muitogostoso.com.br.
+dimeca.unica.it.
+i.canddi.com.
+36.115.172.187.in-addr.arpa.
+a.root-servers.net.
+mortgageadvisorskc.com.
+a6.sphotos.ak.fbcdn.net.
+goo.gl.
+fbcdn-photos-a.akamaihd.net.
+shared.live.com.
+cxz23.meaningtool.com.
+www.facebook.com.
+img-s3-01.mytextgraphics.com.
+mail.pleasval.k12.ia.us.
+www.facebook.com.
+a1.sphotos.ak.fbcdn.net.
+www.facebook.com.
+aol.com.
+hash.orbitdownloader.com.
+www.google.com.
+www.tvps.com.
+professional.avira-update.com.
+tg.game2.cn.
+125.126.219.190.in-addr.arpa.
+conn.skype.com.
+aircarrierzf.com.
+profile.ak.fbcdn.net.
+www.hostalcondesa.com.
+67.230.16.190.in-addr.arpa.
+invest-centr.ru.sci.smolensk.ru.
+creative.ak.fbcdn.net.
+b._dns-sd._udp.lan.
+www.google.com.
+217.12.6.189.in-addr.arpa.
+www.wellpad.com.
+www.facebook.com.
+140.140.95.99.in-addr.arpa.
+fruit.blurtit.com.
+googleads.g.doubleclick.net.
+korigan.net.
+83.114.66.186.in-addr.arpa.
+www.softonic.cn.
+38.147.220.66.in-addr.arpa.
+steveholtvstheuniverse.tumblr.com.
+dr._dns-sd._udp.0.0.0.5.in-addr.arpa.
+157.15.192.190.in-addr.arpa.
+developers.facebook.com.
+100.1.168.192.in-addr.arpa.
+3ys5nh::h.42kc.
+freerollpw.info.
+mail.quakermaid.com.
+1st.net.com.
+api.facebook.com.
+a.root-servers.net.
+94.158.125.74.in-addr.arpa.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+_198_43_8.
+ecatv.home.ne.jp.
+a3.sphotos.ak.fbcdn.net.
+photos-g.ak.fbcdn.net.
+www.morelosdiario.com.
+www.pekegifs.com.
+ads.tlvmedia.com.
+www.hemei.co.
+pixel.facebook.com.
+photos-f.ak.fbcdn.net.
+profile.ak.fbcdn.net.
+cs11517.vk.com.
+themecraft.net.
+159.28.152.201.in-addr.arpa.
+www.juegosdiarios.com.
+mx.answers.yahoo.com.
+dougseven.com.
+1804289383.localhost.
+liveupdate.symantecliveupdate.com.
+71.253.230.190.in-addr.arpa.
+mx2.tgp.iphmx.com.
+btopenworld.com.
+americanmotorabilia.com.
+photos-h.ak.fbcdn.net.
+2464555234.dnsbl7.mailshell.net.
+a3.sphotos.ak.fbcdn.net.
+google.com.
+gerbergear.com.
+mystartantiphishing.com.
+btfans.3322.org.
+a.root-servers.net.
+networkedblogs.com.
+www.verbicidemagazine.com.
+freegames.zone.com.
+www.gmodules.com.
+teredo.ipv6.microsoft.com.
+a.root-servers.net.
+178.242.18.186.in-addr.arpa.
+mail.americanzephyr.com.
+160.89.132.203.in-addr.arpa.
+supermotard.dk.
+shusd.k12.ca.us.
+news-briefs.ew.com.
+mail.mfsia.com.
+argin.net.
+211.222.2.204.in-addr.arpa.
+a.root-servers.net.
+222.80.27.177.in-addr.arpa.
+copy.yandex.net.
+mail.fcmoscow.ru.
+csi.gstatic.com.
+ads.e-planning.net.
+time.chttl.com.tw.
+www.facebook.com.
+ratings-wrs.symantec.com.
+ac3filter.net.
+1wk83cbvh.95fd.
+a995.mm1.akamai.net.
+www.swosu.edu.
+95.6.191.186.in-addr.arpa.
+159.39.143.201.in-addr.arpa.
+mx.pochemu.ru.
+i7x6a8w8x.83nx.
+comoaumentarlospechos1.blogspot.com.
+platform.twitter.com.
+platform.ak.fbcdn.net.
+totalbis.com.
+www.uwebi.org.
+178.96.91.125.in-addr.arpa.
+plus.google.com.
+tymewyse.com.
+photos-d.ak.fbcdn.net.
+cf.addthis.com.
+mscrl.microsoft.com.
+a.root-servers.net.
+gers.com.
+wpad.
+lh3.googleusercontent.com.
+sp.cwfservice.net.
+www.fireshell.wordpress.com.
+www.searchqu.com.
+www.marions-kochbuch.com.
+www.aumentodemamas.es.
+9.122.98.189.in-addr.arpa.
+www.losttv-forum.com.
+ocsp.verisign.com.
+gethotfree.eu.
+www.straponvideotop.com.
+sn136w.snt136.mail.live.com.
+kmlworks.appspot.com.
+a6.sphotos.ak.fbcdn.net.
+_133_24_3.
+www.google.com.
+txlogistik.de.
+lpamail.com.
+garply.com.
+techprolonged.disqus.com.
+toltec-nagual.com.
+alchemysoft.com.
+loading5.widdit.com.
+240.244.77.190.in-addr.arpa.
+platform.ak.fbcdn.net.
+search.mywebsearch.com.
+20.33.69.189.in-addr.arpa.
+27.200.93.186.in-addr.arpa.
+photos-h.ak.fbcdn.net.
+ksn2-12.kaspersky-labs.com.
+www.tire-information-world.com.
+infomama.ru.
+profile.ak.fbcdn.net.
+photos-c.ak.fbcdn.net.
+www.stopbadware.org.
+myhughesnet.com.
+usapears.ru.
+pitch.ru.
+www.estomaterapia.es.
+235.117.234.189.in-addr.arpa.
+connect.facebook.net.
+222.8.121.178.in-addr.arpa.
+img855.imageshack.us.
+shania-twain-wallpapers.blogspot.com.
+holaya.blogspot.com.
+www.wfp.org.
+www.hudakonhollywood.com.
+94.218.168.189.in-addr.arpa.
+starry.net.s7a1.psmtp.com.
+www.bywifi.com.
+47.138.55.182.in-addr.arpa.
+autolife116.ru.
+stats.televisadeportes.esmas.com.
+a7.sphotos.ak.fbcdn.net.
+64.54.56.200.in-addr.arpa.
+www.europa-ciezarowki.pl.
+r._dns-sd._udp.0.2.168.192.in-addr.arpa.
+53.16.16.200.in-addr.arpa.
+accor-mail.com.dob.sibl.support-intelligence.net.
+197.54.114.186.in-addr.arpa.
+postales-y-tarjetas.com.
+static-cdn.modernwar-game.com.
+es.wowhead.com.
+141.150.80.190.in-addr.arpa.
+googleads.g.doubleclick.net.
+utility1.software.informer.com.
+www.herongyang.com.
+172.240.81.93.in-addr.arpa.
+www.facebook.com.
+weblinkone.com.
+142.8.18.186.in-addr.arpa.
+mundogamers.com.
+sigs.symantec.com.
+178.99.55.74.in-addr.arpa.
+135.72.55.65.in-addr.arpa.
+pixel.facebook.com.
+kassnet.net.
+a1003.w41.akamai.net.
+photos-a.ak.fbcdn.net.
+google.com.
+a.root-servers.net.
+cruins.com.
+emark.rtl.de.
+segment-pixel.invitemedia.com.
+twbcompany.com.s7a1.psmtp.com.
+fbcdn-profile-a.akamaihd.net.
+a.root-servers.net.
+www.googletagservices.com.
+c1142172.cdn.cloudfiles.rackspacecloud.com.
+farm8.staticflickr.com.
+147.210.124.2.in-addr.arpa.
+profile.ak.fbcdn.net.
+spiralcom.co.uk.
+www.edoglovers.com.
+a1961.w7.akamai.net.
+www.autoline.tv.
+69620.ua.all.biz.
+csi.gstatic.com.
+156.247.100.81.in-addr.arpa.
+254.108.104.59.in-addr.arpa.
+automatedlogic.com.s7a2.psmtp.com.
+213.233.55.190.in-addr.arpa.
+96.213.89.186.in-addr.arpa.
+a6.sphotos.ak.fbcdn.net.
+www.flipdrive.com.
+www.bradleysalmanac.com.
+it.answers.com.
+www.ver-series-online.com.
+app.appatyze.com.
+dns.msftncsi.com.
+hotmail.com.
+a.root-servers.net.
+asset5.puatraining.com.
+pa.wordpress.com.
+a7.sphotos.ak.fbcdn.net.
+www.tecnosapiens.cl.
+87.105.9.186.in-addr.arpa.
+98.47.143.190.in-addr.arpa.
+a34.g.akamai.net.
+sp.cwfservice.net.
+api.twitter.com.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+s-static.ak.fbcdn.net.
+pixel.facebook.com.
+www.mikextube.com.
+sassysarongs.com.
+photos-b.ak.fbcdn.net.
+aol.com.
+connect.facebook.net.
+a.root-servers.net.
+74.101.168.192.in-addr.arpa.
+lyrebirdradio.com.
+developers.facebook.com.
+twist45.wanadoo.co.uk.
+www.google.com.mx.
+www.decorationtricks.com.
+231.113.171.187.in-addr.arpa.
+9.13.254.17.in-addr.arpa.
+celebhairstyle.files.wordpress.com.
+31.30.168.187.in-addr.arpa.
+185.171.123.187.in-addr.arpa.
+smithnv.com.
+a.root-servers.net.
+www.avanza.se.
+s-static.ak.fbcdn.net.
+132.238.74.187.in-addr.arpa.
+a7.sphotos.ak.fbcdn.net.
+www.thebadrash.com.
+photos-a.ak.fbcdn.net.
+googleads.g.doubleclick.net.
+u11.eset.com.
+gocpc.com.inbound10.mxlogic.net.
+api.twitter.com.
+228.216.139.190.in-addr.arpa.
+photos-b.ak.fbcdn.net.
+static.chartbeat.com.
+38.147.220.66.in-addr.arpa.
+21.191.132.187.in-addr.arpa.
+cns.ru.
+gogastudios.com.
+cuartetos.org.
+nutramax.com.
+tc11.easythumbhost.com.
+tms30.icrc.trendmicro.com.
+accounts.google.com.
+223.87.160.201.in-addr.arpa.
+a7.sphotos.ak.fbcdn.net.
+mp3.es.
+suezsteel.com.
+dns.msftncsi.com.
+transloadamerica.net.s5a1.psmtp.com.
+go.microsoft.com.
+plus.google.com.
+gemmark.it.
+becausemusicismylife.blogspot.com.
+www.youtube-nocookie.com.
+curgos.galeon.com.
+bing.com.
+chiapas.olx.com.mx.
+creative.ak.fbcdn.net.
+a6.sphotos.ak.fbcdn.net.
+track.pubmatic.com.
+photos-b.ak.fbcdn.net.
+api.twitter.com.
+twitter.com.
+s.youtube.com.
+laricreazionenonaspetta.comunita.unita.it.
+gfx3.hotmail.com.
+a2.sphotos.ak.fbcdn.net.
+wazzy88.deviantart.com.
+api.geo.kontagent.net.
+browsefb.com.
+csi.gstatic.com.
+oppcos.com.s10a2.psmtp.com.
+www.youtube-nocookie.com.
+musicbestseller.com.
+219.47.165.189.in-addr.arpa.
+www.ircfast.com.
+lastchaos.softonic.fr.
+photos-d.ak.fbcdn.net.
+dns.msftncsi.com.
+apps.facebook.com.
+46.177.85.24.in-addr.arpa.
+www.eltiempo.com.
+www.cfr.ro.
+dl-ssl.google.com.
+131.95.163.71.zz.countries.nerd.dk.
+titanium30-en.url.trendmicro.com.
+www.solunet-infomex.com.
+static.ak.fbcdn.net.
+2.254.32.200.in-addr.arpa.
+133.241.52.186.in-addr.arpa.
+a.root-servers.net.
+s-static.ak.facebook.com.
+creative.ak.fbcdn.net.
+a.root-servers.net.
+249.226.225.186.in-addr.arpa.
+ib.adnxs.com.
+s1-05.twitpicproxy.com.
+pagead2.googlesyndication.com.
+kocd4jfm1.x69t6f5f.
+r._dns-sd._udp.0.0.168.192.in-addr.arpa.
+www.cantur.com.
+profile.ak.fbcdn.net.
+122.54.54.85.in-addr.arpa.
+a.root-servers.net.
+apps.facebook.com.
+csi.gstatic.com.
+g.di0.org.
+www.google.com.
+gdrnylaw.com.
+ip1.dynupdate.no-ip.com.
+69.22.238.190.in-addr.arpa.
+www.google.com.
+diva-inc.com.
+s.ytimg.com.
+photos-b.ak.fbcdn.net.
+.
+twitter.com.
+mail.lss-corp.com.
+191.169.166.99.in-addr.arpa.
+photos-a.ak.fbcdn.net.
+a.root-servers.net.
+x1.mobileboner.com.
+a3.sphotos.ak.fbcdn.net.
+media.fastclick.net.
+1-a-pay.com.
+gropc.com.
+pc.vggen.com.
+navegandoporgrecia.blogspot.com.
+cdn-1.nflximg.com.
+gate2.finpar.ru.
+www.icc-cpi.int.
+safebrowsing.clients.google.com.
+p32d20cvjyi45c19nvd40avdtb18hva67iqbsar.org.
+www.amazon.es.
+oascentral.marklevinshow.com.
+35.40.221.190.in-addr.arpa.
+74.194.102.80.in-addr.arpa.
+www.tcscouriers.com.
+admin.brightcove.com.
+a3.sphotos.ak.fbcdn.net.
+a.xlink.xboxlive.com.
+veracitymanagementgroup.com.
+www.husky-owners.com.
+234.71.50.201.in-addr.arpa.
+review.tidebuy.com.
+www.rptcontentserver.com.
+mail.radio.ru.
+images.bomb-mp3.com.
+i.ytimg.com.
+657-async.olark.com.
+pohmtk.com.
+youtu.be.
+a.root-servers.net.
+232.65.52.186.in-addr.arpa.
+e4805.b.akamaiedge.net.
+telcel3g.wordpress.com.
+www.ela-salaty.com.
+a1294.w20.akamai.net.
+15.149.220.66.in-addr.arpa.
+254.250.192.187.in-addr.arpa.
+static.ak.fbcdn.net.
+www.bloggertipsandtricks.com.
+www.littlebigplanetarium.com.
+a153.phobos.apple.com.
+a.root-servers.net.
+242.252.105.95.in-addr.arpa.
+ieonlinews.microsoft.com.
+urs.microsoft.com.
+www.wtp101.com.
+www.googleapis.com.
+mail.cbici.net.
+sc2.rules.mailshell.net.
+a1725.l.akamai.net.
+180.156.68.87.in-addr.arpa.
+sp.cwfservice.net.
+a.root-servers.net.
+45.137.188.201.in-addr.arpa.
+_727_05_5.
+stlsports.org.
+ca.answers.yahoo.com.
+misandanzasporlavida.blogspot.com.
+api.conduit.com.
+ns.polikvart.ru.
+shop.xango.com.hk.
+udvgpbctq.q56x4w8i.
+img.youtube.com.
+117.255.242.201.in-addr.arpa.
+hassan-khan-solicitors.com.
+www.asev.org.
+116.95.168.192.in-addr.arpa.
+google.com.
+rca.com.
+1.88.158.187.in-addr.arpa.
+www.facebook.com.
+jdgtffhwysurnu.tw.
+tcr.tynt.com.
+b._dns-sd._udp.lan.
+images.speedbit.com.
+www.installingwoodfloors.com.
+pics.hi5.com.
+modedevoted.blogspot.com.
+59.30.75.190.in-addr.arpa.
+pixel.rubiconproject.net.akadns.net.
+p06-bookmarks.icloud.com.
+a4.sphotos.ak.fbcdn.net.
+t1.gstatic.com.
+248.60.198.190.in-addr.arpa.
+search.yahoo.com.
+r._dns-sd._udp.0.0.1.10.in-addr.arpa.
+a.root-servers.net.
+www.ssasychic.com.
+www.datarecovery.net.
+pagead2.googlesyndication.com.
+mail.raphaministries.com.
+freeqq2.qq.com.
+b._dns-sd._udp.lan.
+work-in-net.ru.
+adspaces.ero-advertising.com.
+dns.msftncsi.com.
+_550_41_5.
+54.192.177.78.in-addr.arpa.
+tpm.com.au.
+a.root-servers.net.
+www.derecho.com.
+apps.facebook.com.
+www.myviphealth.com.
+d3lvr7yuk4uaui.cloudfront.net.
+olysteel.com.
+h.live.com.
+macralace.com.
+stats.wartsila.net.
+zh-cn.facebook.com.
+elviasboutique.com.
+db._dns-sd._udp.0.1.168.192.in-addr.arpa.
+l.yimg.com.
+35.91.142.68.in-addr.arpa.
+garufa.com.
+instagr.am.
+www.rincondeljuego.net.
+pbid.iforex.com.
+ocsp.digicert.com.
+www.2joyourself.tv.
+aodinc.com.
+cnhmexico.com.mx.
+mail.absolutesoundinc.com.
+router.infolinks.com.
+irc.purchaseservice.com.
+100.248.92.186.in-addr.arpa.
+www.xtube.com.
+mail.metastar.com.
+a995.mm1.akamai.net.
+info.babylon.com.lan.
+98.190.11.190.in-addr.arpa.
+aol.com.
+swdpme4oh.a76v7b1o.
+mail.kjcomm.com.
+cecs.pdx.edu.
+0-68.channel.facebook.com.
+game.taobao.com.
+v9.nonxt5.c.pack.google.com.
+qhj3egwiz.06oe.
+www.shemaletubeclips.com.
+b-0.19-2304d408.80010c1.1518.19d4.3ea1.410.0.1dhr69rzugs8hlqbdeuv9fnjrv.avqs.mcafee.com.
+mercedesbenz.com.
+photos-d.ak.fbcdn.net.
+ha-ash.com.
+www.google.com.
+www.agoda.pl.
+www.justanswer.com.
+alerts.conduit-services.com.
+connect.facebook.net.
+dns.msftncsi.com.
+www.ice.it.
+thesourcecompanies.com.
+teredo.ipv6.microsoft.com.
+www.joey-silvera-shemales.com.
+ads.hotgirlsgames.net.
+bestimpressionsinc.net.
+www.nokiakiller.com.
+profile.ak.fbcdn.net.
+clients1.google.com.
+r1rk9np7bpcsfoeekl0khkd2juj27q3o-a-fc-opensocial.googleusercontent.com.
+173.20.3.88.in-addr.arpa.
+www.experiencestmaarten.com.
+ejabat.google.com.
+www.google-analytics.com.
+www.facebook.com.
+volcanoseven.com.
+www.yahoo.com.
+www.juegosdebarbiebebe.com.
+www.megastock.com.
+245.43.213.189.in-addr.arpa.
+113.186.183.178.in-addr.arpa.
+www.alejandrodemiguel.com.
+www.askgamblers.com.
+112.221.152.189.in-addr.arpa.
+cache.netacad-cdn.net.
+wee.fadri.org.
+14.63.209.190.in-addr.arpa.
+a995.mm1.akamai.net.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+161.233.126.187.in-addr.arpa.
+profile.ak.fbcdn.net.
+a-0.19-23088089.8060033.1518.19d4.3ea1.210.0.vt371gbcdzpj6jlp46w5q5wglb.avqs.mcafee.com.
+mail.aikenprinting.com.
+www.talanews.com.
+profile.ak.fbcdn.net.
+moodpoll.nfdaily.cn.
+crl.microsoft.com.
+www.microsoft.com.
+static.gulli.com.
+a.root-servers.net.
+a8.sphotos.ak.fbcdn.net.
+empoweredbirth.typepad.com.
+sjc-smtp1.sjc.dropbox.com.
+row.bc.yahoo.com.
+sites.google.com.
+v3.nonxt1.c.android.clients.google.com.
+plus.google.com.
+www.tripadvisor.com.my.
+www.facebook.com.
+www.facebook.com.
+www.hardhornyme.com.
+b._dns-sd._udp.0.1.168.192.in-addr.arpa.
+asspmvv.puntdoc.es.
+a5.sphotos.ak.fbcdn.net.
+56.230.178.190.in-addr.arpa.
+19.76.241.201.in-addr.arpa.
+www.breaktaker.com.
+ocsp.digicert.com.
+a8.sphotos.ak.fbcdn.net.
+www.lodgingbarcelona.com.
+brantly.com.
+pixel.facebook.com.
+www.ciasf2010.es.
+piraeusbank.gr.
+time.microsoft.akadns.net.
+dns.msftncsi.com.
+www.airrunnersystems.com.
+145.96.245.189.in-addr.arpa.
+adserv.comze.com.
+xmy.froo.com.
+subdere.gov.cl.
+www.adobe.com.
+www.fundacionamanecer.cl.
+dtboot.orbitdownloader.com.
+profile.ak.fbcdn.net.
+a6.sphotos.ak.fbcdn.net.
+ottu-da.ru.
+i3.ytimg.com.
+photos-g.ak.fbcdn.net.
+140.120.167.80.in-addr.arpa.
+a.root-servers.net.
+www.elpobladodeprince.com.
+a1907.g.akamai.net.
+a.root-servers.net.
+davidweikel.com.
+captcha.qq.com.
+13.203.192.71.in-addr.arpa.
+www.ebgames.com.au.
+photos-g.ak.fbcdn.net.
+bomberman.chulojuegos.com.
+11.111.166.201.in-addr.arpa.
+apis.google.com.
+6pix3ikxv.23mj.
+nsx.sec.np.dl.playstation.net.
+platform.ak.fbcdn.net.
+open-tracker.appspot.com.
+www.afuj.fr.
+198.250.9.190.in-addr.arpa.
+a.root-servers.net.
+creative.ak.fbcdn.net.
+cs12962.vkontakte.ru.
+quick-876346.com.
+a323.yahoofs.com.
+www.facebook.com.
+mx2.fidalgo.net.
+16.192.68.177.in-addr.arpa.
+gamestats.gamespy.com.
+s-static.ak.facebook.com.
+www.lovevalencia.com.
+www.rioave-fc.pt.
+oi681.photobucket.com.
+www.justinbiebermexico.com.
+sync.search.spotxchange.com.
+hardsalsa.com.
+www.cool-bites.com.
+memelodia.blogspot.com.
+158.199.161.189.in-addr.arpa.
+mailgate1.bdal.de.
+secure.nsta.org.
+zh-cn.facebook.com.
+mobilemaps.clients.google.com.
+s2.youtube.com.
+h0m-master.ru.
+api25.thetrafficstat.net.
+ax.init.itunes.apple.com.
+a-0.19-230f1041.9050081.1518.19d0.3ea1.410.0.vfprgn6rjkecblnk3rzsiqms7i.avqs.mcafee.com.
+xmadenx.files.wordpress.com.
+a.root-servers.net.
+hockey.cbssports.com.
+static.ak.fbcdn.net.
+p24.packet8.net.
+lissamonet.com.
+a1725.l.akamai.net.
+g.live.com.
+www.abc.es.
+www.foxnews.com.
+dns149.a.register.com.
+themes.googleusercontent.com.
+gmlive.narod.ru.
+73y5662up.86ot.
+fullrangedriver.com.
+assets00.grou.ps.
+cmcelectronics.com.
+27.222.192.187.in-addr.arpa.
+a5.sphotos.ak.fbcdn.net.
+a2.ec-images.myspacecdn.com.
+11.80.104.186.in-addr.arpa.
+www.youtube.com.
+snake.cc.ncu.edu.tw.
+www.cuevana.tv.
+cbflouhouse.com.
+api.twitter.com.
+comtelsystem.com.
+wirelessnotebook.com.
+60.11.6.24.in-addr.arpa.
+storage.conduit.com.
+blog.rainbowhill.com.au.
+plus.google.com.
+sherland.ru.
+bandstores.co.uk.
+st2.xxxkinky.com.
+www.benedictinescat.com.
+mail.centurytel.net.
+a7.sphotos.ak.fbcdn.net.
+iistbrai1.t98a4n7p.
+photos-f.ak.fbcdn.net.
+juegos7.juegosdiarios.com.
+teredo.ipv6.microsoft.com.
+www.mtv.co.uk.
+www.bodyfitcheck.com.au.
+www.mascus.co.za.
+ads.adxpansion.com.
+lasvarinet.com.ar.
+apps.facebook.com.
+206.190.235.189.in-addr.arpa.
+78.129.52.186.in-addr.arpa.
+hex.namehub.com.
+22-courier.push.apple.com.
+metrics.blackberry.com.
+tracking.usage.app.conduit-services.com.
+zynga1-a.akamaihd.net.
+email.xmradio.com.
+179.203.96.190.in-addr.arpa.
+www.nanking-massacre.com.
+rewfkg0ret876.com.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+walmart.ugc.bazaarvoice.com.
+www.thejohnreport.net.
+de-freshmilk.cdn.videoplaza.tv.
+photos-g.ak.fbcdn.net.
+33.143.209.77.in-addr.arpa.
+google.com.
+blogs.desitara.com.
+11.185.153.189.in-addr.arpa.
+s-static.ak.facebook.com.
+pagead2.googlesyndication.com.
+www.adam4adamlive.com.
+asiandvdclub.org.
+i.lumosity.com.
+132.207.225.190.in-addr.arpa.
+blog.apps.su.
+mipagina.esmas.com.
+49.219.27.46.in-addr.arpa.
+wmost.com.
+dx3723.tinyurl.com.
+static.ak.facebook.com.
+static.ak.fbcdn.net.
+www.winksfun.com.
+dark-wraith.com.
+login.live.com.
+9.94.161.187.in-addr.arpa.
+static.ak.fbcdn.net.
+login.yahoo.com.
+csi.gstatic.com.
+toolbarqueries.google.com.mx.
+ad.turn.com.
+b._dns-sd._udp.0.1.168.192.in-addr.arpa.
+116.185.2.123.in-addr.arpa.
+svrsecure-g2-crl.verisign.com.
+www.sigoconana.blogspot.com.
+879.coll.ning.com.
+mobile.twitter.com.
+www.cuantarazon.com.
+l16.member.kr3.yahoo.com.
+mail.packup.ru.
+xml.truveo.com.
+apis.google.com.
+mail.ccalawcorp.com.
+mail.qm-company.com.
+129.13.58.189.in-addr.arpa.
+csi.gstatic.com.
+v7.cache3.c.youtube.com.
+www.salud.df.gob.mx.
+cdn1.iofferphoto.com.
+jmu.edu.
+dns.msftncsi.com.
+images1-focus-opensocial.googleusercontent.com.
+toolbarqueries.google.com.mx.
+a5.sphotos.ak.fbcdn.net.
+kaltura.com.
+lb._dns-sd._udp.lan.
+www.google.com.
+edsal.com.
+www.centroexcursionista.org.
+static.ak.facebook.com.
+apps.teamlava.com.
+www.lebnights.net.
+db._dns-sd._udp.0.1.168.192.in-addr.arpa.
+bj.bbs.house.sina.com.cn.
+alt1.aspmx.l.google.com.
+5.134.45.190.in-addr.arpa.
+www.facebook.com.
+101.43.73.94.in-addr.arpa.
+45.181.63.69.in-addr.arpa.
+carnby.altervista.org.
+25.83.0.88.in-addr.arpa.
+134.192.56.186.in-addr.arpa.
+banners.wunderground.com.
+dr._dns-sd._udp.0.2.168.192.in-addr.arpa.
+simonds.ru.
+sn1msg2010523.gateway.messenger.live.com.
+picgalleries.hotshemalesluts.com.
+id.google.com.
+apis.google.com.
+gan.wikipedia.org.
+recabrones.com.
+249.99.34.186.in-addr.arpa.
+52.151.221.189.in-addr.arpa.
+www.mediafire.com.
+195.12.188.186.in-addr.arpa.
+pda-bes.amazon.com.
+sro.whatsapp.net.
+30.7.22.187.in-addr.arpa.
+downloadgraphy.blogspot.com.
+ksn2-12.kaspersky-labs.com.
+163.165.194.180.in-addr.arpa.
+id.google.com.mx.
+millersofclaflin.com.
+an-penza.ru.
+6.254.189.190.in-addr.arpa.
+_826_89_5.
+inbound.nightline-inc.com.netsolmail.net.
+jovenescritora.metroblog.com.
+235.63.70.187.in-addr.arpa.
+20.26.108.27.in-addr.arpa.
+154.93.27.201.in-addr.arpa.
+support.google.com.
+246.36.78.201.in-addr.arpa.
+27925x2ti.75je.
+pixel.facebook.com.
+ninjaui.com.
+46.183.36.184.in-addr.arpa.
+pctelecom.com.
+twitter.com.
+fbcdn-photos-a.akamaihd.net.
+a.root-servers.net.
+s-static.ak.fbcdn.net.
+waittime.tsa.dhs.gov.
+eightyonedays.com.
+check4.facebook.com.
+valuta.se.
+a1.sphotos.ak.fbcdn.net.
+www.facebook.com.
+smtp.hot.glbdns.microsoft.com.
+www.lamonomagazine.com.
+ocsp.digicert.com.
+tgmedsystem.com.
+dns.msftncsi.com.
+www.mypinktasticlife.com.
+seodoktor.ru.
+b.scorecardresearch.com.
+www.cia.gov.
+248.103.68.201.in-addr.arpa.
+berkshiresgi.com.
+gibbonlaw-com.mail.eo.outlook.com.
+ksn2-12.kaspersky-labs.com.
+0-131.channel.facebook.com.
+mx2.wellsfargo.com.
+www.perunatural.com.
+autofotoexpress.com.
+michaelgerald.com.mail6.psmtp.com.
+137.52.137.85.in-addr.arpa.
+a6.sphotos.ak.fbcdn.net.
+www.geoturismoenbosquesdecafe.com.
+32.107.244.189.in-addr.arpa.
+fotografiainfo.ru.
+www.just-think-it.com.
+a3.sphotos.ak.fbcdn.net.
+235.105.250.190.in-addr.arpa.
+a.root-servers.net.
+jerryseinfeld.com.
+c-ak.static-rootmusic.com.
+averapharm.com.
+s-static.ak.fbcdn.net.
+animationprogression.blogspot.com.
+gallery.chantasbitches.com.
+p01-keyvalueservice.icloud.com.
+shoe-apparel.en.alibaba.com.
+a.prisacom.com.
+mareterra.com.br.
+b91.yahoo.co.jp.
+justinsky.de.
+developers.facebook.com.
+bransonultrasonics.com.
+a.root-servers.net.
+www.isg-apple.com.akadns.net.
+static.ak.fbcdn.net.
+shop.capcom.com.
+242.178.195.187.in-addr.arpa.
+res2.windows.microsoft.com.
+pixel.quantserve.com.
+www.sinograver.com.
+scottforesman.com.mail7.psmtp.com.
+profile.ak.fbcdn.net.
+client.akamai.com.
+sporthotel.ru.
+d3lvr7yuk4uaui.cloudfront.net.
+www.xfire.com.
+a1.sphotos.ak.fbcdn.net.
+a.root-servers.net.
+safebrowsing-cache.google.com.
+103.54.187.189.in-addr.arpa.
+a.root-servers.net.
+ad.doubleclick.net.
+cdn.kgyounginternet.com.c.footprint.net.
+vassilipuskas.com.
+dns.msftncsi.com.
+www.freeland.org.
+212.126.24.125.in-addr.arpa.
+99.42.105.71.in-addr.arpa.
+www.ancestry.myfamily.com.
+a763.phobos.apple.com.
+imgg.ru.
+roshen.com.ua.
+149.121.59.186.in-addr.arpa.
+photos-a.ak.fbcdn.net.
+www.nicocig.co.uk.
+www.alaic.net.
+auracom.net.s6b1.psmtp.com.
+31.193.226.190.in-addr.arpa.
+a.root-servers.net.
+sgistuff.g-lenerz.de.
+16.246.175.187.in-addr.arpa.
+0-327.channel.facebook.com.
+jk87369ai.32qi.
+mail.orelholodmash.ru.
+mailinator2.com.
+c13.zedo.com.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+182.109.93.186.in-addr.arpa.
+c.trendpost.net.
+www.universia.com.ec.
+www.googleadservices.com.
+platform.twitter.com.
+itunes.apple.com.
+assets.macys.com.
+_795_67_9.
+labelall.com.
+liveupdate.symantecliveupdate.com.
+rockwell-solutions.com.
+smtp.urbas.net.
+static.ak.fbcdn.net.
+119.205.201.190.in-addr.arpa.
+profile.ak.fbcdn.net.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+102.123.217.87.in-addr.arpa.
+img365.rockyou.com.
+img.youtube.com.
+0.191071.com.
+wcandw.com.
+s.ytimg.com.
+2.108.223.24.in-addr.arpa.
+otnusa.net.
+funcage.com.
+rupromo.ru.
+a.root-servers.net.
+www.museomigraciones.org.uy.
+www.facebook.com.
+berlee.net.
+www.facebook.com.
+jetmessenger.com.
+g.promosrv.com.
+209.210.211.76.in-addr.arpa.
+184.175.25.98.in-addr.arpa.
+www.myngle.com.
+tuug.net.ru.
+22.149.220.66.in-addr.arpa.
+www.facebook.com.
+igskins.googlecode.com.
+movies.netflix.com.
+www.awltovhc.com.
+mail.sfgiants.com.
+imagenen1.247realmedia.com.
+70.195.37.93.in-addr.arpa.
+165.132.37.190.in-addr.arpa.
+_823_08_2.
+mywebsiteadvisor.com.
+19.166.165.58.in-addr.arpa.
+naletu.ru.
+external.ak.fbcdn.net.
+0-244.channel.facebook.com.
+41.25.122.186.in-addr.arpa.
+cam-in-style.programas-gratis.net.
+eur.tlc-world.ru.
+a5.sphotos.ak.fbcdn.net.
+hydrokamaz.ru.
+globalwealthtrade.com.s8b2.psmtp.com.
+109.211.209.190.in-addr.arpa.
+a.root-servers.net.
+modelsilike.blogspot.com.
+hdp.zapto.org.
+229.149.59.187.in-addr.arpa.
+mircosoft.com.
+coco.metrogames.com.
+drakecooper.com.s9b2.psmtp.com.
+www.facebook.com.
+ngjmjdqhy.68nq.
+creative.ak.fbcdn.net.
+connect.facebook.net.
+aviakb.ru.
+gardiner-richardson.com.s200a2.psmtp.com.
+marketdoctors.com.
+a.root-servers.net.
+www.amazon.com.
+tulipanchile.com.
+cdn.filebulldog.com.
+bt1.btally.net.
+query.yahooapis.com.
+ads1.msads.net.
+web-zc1.cityville.zynga.com.
+yourfriendlymortgage.com.
+groups.google.com.mx.
+i1.ytimg.com.
+www.boddit.com.
+99.140.49.82.in-addr.arpa.
+www.facebook.com.
+mscrl.microsoft.com.
+172.15.32.186.in-addr.arpa.
+quevedo.mundoanuncio.ec.
+data.wa.marketingsolutions.yahoo.com.
+hotmail.com.
+www.cptm.com.mx.
+subs.hh-pub.com.
+bbsyd.dk.
+137.233.104.189.in-addr.arpa.
+24.139.131.190.in-addr.arpa.
+a.root-servers.net.
+www.youtube.com.
+www.idconline.com.mx.
+do.lysd.k12.ak.us.
+175.17.168.192.in-addr.arpa.
+nj.buric.com.
+dns.msftncsi.com.
+a1.twimg.com.
+gtu-ins.com.m4.mx-route.com.
+shasta-rrs.symantec.com.
+zvert.fcien.edu.uy.
+253.75.12.50.in-addr.arpa.
+da.wikipedia.org.
+b3mu3vqzc.j78m3i1x.
+www.google.com.
+alerts.conduit-services.com.
+a.root-servers.net.
+115.229.34.187.in-addr.arpa.
+decollage.nl.
+rad.msn.com.
+xquisiteonline.com.
+it.wikipedia.org.
+www.youtube.com.
+relay.ufanet.ru.
+24.123.219.190.in-addr.arpa.
+byfiles.storage.msn.com.
+www.thewarofthemutans.com.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+mail.wardlestoreys.com.
+www.apqc.org.
+252.144.130.82.in-addr.arpa.
+a8.sphotos.ak.fbcdn.net.
+sljkllchl.12tr.
+xxxxxkronosxxxxx.blogspot.com.
+www.museopicassomalaga.org.
+inbound.luigisbakery.com.netsolmail.net.
+sites.google.com.
+fbcdn-profile-a.akamaihd.net.
+pix04.revsci.net.
+profile.ak.fbcdn.net.
+dragraceronline.net.
+152.227.76.151.in-addr.arpa.
+profile.ak.fbcdn.net.
+a.root-servers.net.
+mail.cwo.com.
+109.173.148.46.in-addr.arpa.
+s1-excel.vo.msecnd.net.
+assets.cellphonebeat.com.
+linksynergy.overstock.com.
+jers2.info.
+spb.ltg.ru.home.
+photos-g.ak.fbcdn.net.
+ciscom.ru.home.
+dmcvw8a7s.l62m0b7k.
+a.root-servers.net.
+loansonly.com.
+doctor-muller.ru.
+ads1.msads.net.
+b._dns-sd._udp.0.1.168.192.in-addr.arpa.
+usa.acciontrabajo.com.
+www.missbellabellini.com.
+a3.sphotos.ak.fbcdn.net.
+s-static.ak.facebook.com.
+www.aitracing.com.
+cdn4b.youjizz.com.
+makavibe.ru.
+sync.mathtag.com.
+18.40.31.190.in-addr.arpa.
+elbarullodelolimpo.blogspot.com.
+google.com.
+0-161.channel.facebook.com.
+anboto.boj.org.
+m259.photobucket.com.
+mail.
+m6buels96.33sf.
+158.215.171.189.in-addr.arpa.
+thegoodtimber.com.
+s-static.ak.fbcdn.net.
+ifood.tv.
+ajax.googleapis.com.
+ipod-iphone.ru.
+xsltcache.alexa.com.
+t-one.net.
+a.root-servers.net.
+photos-f.ak.fbcdn.net.
+d1j68ux4ukg4g1.cloudfront.net.
+webres2.pand.ctmail.com.
+186.89.23.190.in-addr.arpa.
+avanta-group.ru.
+www.ourexplorer.com.
+sayedmokhtar.maktoobblog.com.
+139.103.215.118.in-addr.arpa.
+ad-g.doubleclick.net.
+rickyost.com.
+programmkalender.daserste.de.
+25.237.116.177.in-addr.arpa.
+login.toolbar.conduit-services.com.
+145.168.168.192.in-addr.arpa.
+t3.gstatic.com.
+developers.facebook.com.
+pixel.facebook.com.
+www.paraguaycoins.com.
+ic.tynt.com.
+ad-g.doubleclick.net.
+d1uysd8m4iv3h8.cloudfront.net.
+cdn.api.twitter.com.
+www.yahoo.com.
+www.video-lyrics.com.
+179.190.249.111.in-addr.arpa.
+www.upd.edu.mx.
+www.telmore.dk.
+im11.gulfup.com.
+allourfingersinthepie.blogspot.com.
+aimhigh.net.inbound10.mxlogicmx.net.
+api.conduit.com.
+145.65.92.201.in-addr.arpa.
+www.riffygit.com.
+www.cartoonnetwork.com.
+134.123.75.208.sbl-xbl.spamhaus.org.
+62.2.10.10.in-addr.arpa.
+www.souplantation.com.
+pixel.facebook.com.
+configure-cdn.us.dell.com.
+www.sektioneins.de.
+ns1v6.aketzu.net.
+a1.sphotos.ak.fbcdn.net.
+bzz.is.
+vanetaitao.blogspot.com.
+hlabs.spb.ru.
+www.facebook.com.
+36.135.189.195.in-addr.arpa.
+armmf.adobe.com.
+chacalx.blogspot.com.
+acpc.com.
+homedecorconcept.com.
+time.chttl.com.tw.
+www.dydacomp.com.
+goldenoak.org.mx1.realtimefilters.rcimx.net.
+ads.rambomedia.com.
+www.benwhite.com.
+a7.sphotos.ak.fbcdn.net.
+trade.bokecc.com.
+armmf.adobe.com.
+b._dns-sd._udp.lan.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+ocsp.verisign.com.
+cdn01.oovoo.com.
+blogspot.l.google.com.
+www.chinaknowledge.com.
+pixel.facebook.com.
+24.251.223.186.in-addr.arpa.
+cbj-s-03025.africa-me.shell.com.
+68.124.59.186.in-addr.arpa.
+bks7.books.google.com.mx.
+146.69.112.190.in-addr.arpa.
+.
+imap.gmail.com.
+pt-br.facebook.com.
+ratings-wrs.symantec.com.
+209.72.235.68.in-addr.arpa.
+askwaltstollmd.com.
+244.219.229.201.in-addr.arpa.
+mail.welovethemtoo.com.
+120.188.25.108.in-addr.arpa.
+smtp.promflex.ru.
+secondlife.com.
+www.oyunkolay.com.
+siymca.org.
+cancionfrancesaenlos50y60.blogspot.com.
+it-it.facebook.com.
+www.l.google.com.
+lh3.googleusercontent.com.
+mail.diamond-edge.co.uk.
+barmatin.ru.
+fastcomm.ru.
+apps.facebook.com.
+18.48.55.74.in-addr.arpa.
+accounts.google.com.
+photos-b.ak.fbcdn.net.
+apoyo.expotodoparatustand.com.
+a2.sphotos.ak.fbcdn.net.
+hotelasia.com.tw.
+photos-f.ak.fbcdn.net.
+a1007.w43.akamai.net.
+static.ak.fbcdn.net.
+www.twitch.tv.
+www.blogcdn.com.
+updatekeepalive.mcafee.com.
+www.patrimoniosf.gov.ar.
+www.juntosporlaninez.com.
+de-de.facebook.com.
+a.root-servers.net.
+hvc.rr.com.
+external.ak.fbcdn.net.
+a.root-servers.net.
+www.freeworldgroup.com.
+toolbar.zynga.com.
+rs5.scribd.com.
+naryxpharma.com.
+rusremol.ru.
+www.jewelrymaking-beads-library.com.
+u.goal.com.
+www.facebook.com.
+mobinfo.ru.
+gifhorn.de.
+i3.ytimg.com.
+technorati.com.
+lh4.ggpht.com.
+somethinglikethis.net.
+allisfighter.com.
+a-0.19-23095281.c090083.1518.19d4.3ea1.210.0.4er73s9p55296jrntlrqiff28i.avqs.mcafee.com.
+m.hotmail.com.
+ocmyfvcty.d46y9e4l.
+www.tobaccolabels.ca.
+109.38.229.190.in-addr.arpa.
+mail.opelcar.ru.
+groups.google.com.
+carlos-arano.com.ar.
+129.40.233.201.in-addr.arpa.
+64.42.101.78.in-addr.arpa.
+dynamicads.g.doubleclick.net.
+photos-c.ak.fbcdn.net.
+www.google-analytics.com.
+www.umusicpub.com.
+sbcmx8.prodigy.net.
+img830.imageshack.us.
+adfarm.mediaplex.com.
+um14.eset.com.
+www.plusnetwork.com.
+googleads.g.doubleclick.net.
+yahoo.co.uk.
+ecx.images-amazon.com.
+blog.tirerack.com.
+i2.ytimg.com.
+brentwoodcorp.com.inbound30.mxlogic.net.
+google.com.
+fla.sinfindejuegos.com.
+rad.msn.com.
+www.spacepimping.com.
+www.taylormadegolf.cn.
+9selsop1h.71aq.
+uef.com.gt.
+www.facebook.com.
+static.ak.fbcdn.net.
+www.facebook.com.
+www.convertbinary.com.
+www.geeks.co.uk.
+fe.brandreachsys.com.
+a-0.19-a30f9081.c020081.1518.19d4.3ea1.210.0.qv4hsj5k25kw6keh54n91tkpqi.avqs.mcafee.com.
+109.87.54.65.in-addr.arpa.
+d2089760.xoom.it.
+www.facebook.com.
+a.root-servers.net.
+oajuvpeoiq.info.mshome.net.
+gj:zgkihg.v85a0m1p.
+12.59.193.186.in-addr.arpa.
+www2.animalsexfilms.nl.
+a.root-servers.net.
+files.video-loader.com.
+182.62.20.190.in-addr.arpa.
+profile.ak.fbcdn.net.
+www.hampton.com.
+mili.im.
+ocsp.verisign.com.
+www.google-analytics.com.
+13409hotgogling.cn.
+www.facebook.com.
+profile.ak.fbcdn.net.
+mcm5.navy.mil.
+a.root-servers.net.
+69.238.254.188.in-addr.arpa.
+27.43.174.190.in-addr.arpa.
+geo.tp-cdn.com.
+www.siamfishingtours.com.
+www.parkinn.com.
+evsecure-ocsp.verisign.com.
+a.root-servers.net.
+creative.ak.fbcdn.net.
+wmr.ru.
+id.google.com.mx.
+vevideo.com.es.
+api.twitter.com.
+basicinstructions.net.
+tap2-cdn.rubiconproject.com.
+a.root-servers.net.
+10.1.168.192.in-addr.arpa.
+www.randrmagonline.com.
+157.234.28.95.in-addr.arpa.
+r.mzstatic.com.
+206.6.146.186.in-addr.arpa.
+argentinarrhh.blogspot.com.
+es-la.facebook.com.
+profile.ak.fbcdn.net.
+76live.com.
+agglo-nice.fr.
+external.ak.fbcdn.net.
+169.47.49.190.in-addr.arpa.
+pixel.facebook.com.
+creative.ak.fbcdn.net.
+_688_54_7.
+thereps.com.
+dc446.4shared.com.
+ssl.isg-apple.com.akadns.net.
+tboextra.com.
+daviskane.com.
+freemailng0406.web.de.
+108.114.133.217.in-addr.arpa.
+www.facebook.com.
+www.ingdirect.com.au.
+sp.cwfservice.net.
+www.weaverleather.com.
+goldensunwiki.net.
+a.root-servers.net.
+dl.google.com.
+hsnacpas.com.
+apps.facebook.com.
+tecnofull.com.
+bullz-eye.us.intellitxt.com.
+40.204.88.200.in-addr.arpa.
+dns.msftncsi.com.
+focuspg.com.s7b2.psmtp.com.
+google.com.
+segment-pixel.invitemedia.com.
+global-hunters.com.
+aseeva.ru.
+update.avg.com.
+apps.facebook.com.
+www.capes.gov.br.
+a1007.w43.akamai.net.
+178.160.255.190.in-addr.arpa.
+a2.kiev.ua.
+www.facebook.com.
+240.94.154.189.in-addr.arpa.
+a-0.19-2209a081.d060083.1518.19d2.3ea1.410.0.spqabajtl54hfqk97s33alujnv.avqs.mcafee.com.
+developers.facebook.com.
+www.talktom.
+blst.msn.com.
+photos-f.ak.fbcdn.net.
+plus.google.com.
+video.mx.msn.com.
+smtp.ins.dell.com.
+www.marcha.org.ar.
+a.root-servers.net.
+photos-e.ak.fbcdn.net.
+97.251.209.190.in-addr.arpa.
+www.idealmature.com.
+shared.live.com.
+a8.sphotos.ak.fbcdn.net.
+photos-g.ak.fbcdn.net.
+a.root-servers.net.
+view.atdmt.com.
+macrojuegos.juegosipo.com.
+www.linkedin.com.
+smtp.sub.net.au.
+www.sendspace.com.
+a2.sphotos.ak.fbcdn.net.
+images.apple.com.
+blogsochi.ru.
+creative.ak.fbcdn.net.
+mail.robotcombat.com.
+www.arkiva-shqip.com.
+proforg.com.
+_544_70_3.
+ads2.greystripe.com.
+147.20.127.115.in-addr.arpa.
+tags.expo9.exponential.com.
+alona.ru.
+mail.yimg.com.
+dc05.arabsh.com.
+81.154.213.201.in-addr.arpa.
+shapeways.com.
+42.183.138.189.in-addr.arpa.
+ksn1-11-part1.kaspersky-labs.com.
+safebrowsing-cache.google.com.
+pjduy2op7.53cq.
+finnishcharts.com.
+processor.netmgt.com.
+mail1.theron.com.
+a.root-servers.net.
+moscaphoto.com.
+crl3.digicert.com.
+m4v.tvolucion.com.
+loading.retry.widdit.com.
+s-static.ak.facebook.com.
+peas.compunass.org.
+72.202.205.112.in-addr.arpa.
+www.campuspdi.org.
+gorenje.si.
+i.ytimg.com.
+a-0.19-a30f8081.590.1518.19d4.3ea1.410.0.qfgwvgqafksp12wiunftlpnec5.avqs.mcafee.com.
+huertadelosrobles.wordpress.com.
+60.2.1.181.in-addr.arpa.
+250.131.235.201.in-addr.arpa.
+188.76.52.186.in-addr.arpa.
+a0.twimg.com.
+www.google.com.
+0.169.38.99.in-addr.arpa.
+ksn2-12.kaspersky-labs.com.
+a4.sphotos.ak.fbcdn.net.
+dlarray-europ-ieupdate065.gdatasecurity.de.
+adventuregames.ht83.com.
+a6.sphotos.ak.fbcdn.net.
+fghgfhdhdg.blogspot.com.
+profile.ak.fbcdn.net.
+www.liali.net.
+www.spilgames.com.
+crl.microsoft.com.
+a.root-servers.net.
+128.168.122.186.in-addr.arpa.
+pagead2.googlesyndication.com.
+www.google.com.
+cuteskipbbthemes.blogspot.com.
+www.download.windowsupdate.com.
+it-it.facebook.com.
+.
+35.10.10.10.in-addr.arpa.
+42-courier.push.apple.com.
+mygnulinux.blogspot.com.
+www.google.com.
+132.245.190.81.in-addr.arpa.
+whpwireless.com.
+58.136.149.186.in-addr.arpa.
+portageco.com.
+homtial.com.
+twitter.com.
+www.wiroos.com.
+vlex.com.mx.
+1.189.137.201.in-addr.arpa.
+a.root-servers.net.
+mail.lovers.ru.
+www.gelifesciences.com.
+169.11.208.201.in-addr.arpa.
+ntl.fr.
+www.facebook.com.
+rs243l32.rapidshare.com.
+www.cbs.com.
+2.230.100.190.in-addr.arpa.
+www.medscape.com.
+geo.messenger.services.live.com.
+aka-cdn-ns.adtech.de.
+utils.babylon.com.
+a.root-servers.net.
+42.131.134.187.in-addr.arpa.
+videos.javahd.com.
+o-style.net.
+universalflooring.com.
+photos-a.ak.fbcdn.net.
+www.google.com.
+themes.googleusercontent.com.
+img.youtube.com.
+121.190.55.187.in-addr.arpa.
+57.206.55.189.in-addr.arpa.
+55.226.172.201.in-addr.arpa.
+171.211.10.85.in-addr.arpa.
+reddragonkungfu.com.
+www.sjwxzy.com.
+meria.net.
+www.patrickholford.com.
+a.root-servers.net.
+dns.msftncsi.com.
+152.26.161.201.in-addr.arpa.
+creativecommons.org.
+facebook.com.
+112.202.13.187.in-addr.arpa.
+api.facebook.com.
+lb._dns-sd._udp.lan.
+babycenter.ru.
+www.googil.com.
+238.130.168.192.in-addr.arpa.
+pfs.mozilla.org.
+b.scorecardresearch.com.
+ntp1.dlink.com.
+www.samsung.net.
+227.200.165.78.in-addr.arpa.
+r-data.adsrvr.org.
+_978_24_5.
+creative.ak.fbcdn.net.
+www.hao123.com.
+0.11-a307c089.e1032.1518.19d4.3ea1.410.0.j2rbre8jqblv9cw1kbbr2v6dm6.avqs.mcafee.com.
+kupiknigu.ru.
+www.angelacusumano.com.
+252.129.62.186.in-addr.arpa.
+click.allegiantdeals.com.
+www.adoretube.com.
+apps.facebook.com.
+resourcemedia.tv.
+www.bing.com.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+233.170.113.190.in-addr.arpa.
+163.38.63.200.in-addr.arpa.
+tobolsk.info.
+yahoo.com.
+usersystem783aa.ru.
+mail2.us.silhouette.com.
+kisales.com.
+rospres.com.
+creative.ak.fbcdn.net.
+photos-b.ak.fbcdn.net.
+mail.lanaken.be.
+a.root-servers.net.
+a.root-servers.net.
+js.wlxrs.com.
+clients-cctld.l.google.com.
+tap2-cdn.rubiconproject.com.
+thailandlife.com.
+www.ebay.es.
+b.matrixsynth.com.
+www.google-analytics.com.
+osu.ru.
+l.yimg.com.
+cs272.vk.com.
+blog.twoo.com.
+203.110.214.186.in-addr.arpa.
+www.objectlabs.net.
+www.ebay.es.
+www.mytinyworld.co.uk.
+mx-2.superig.com.br.
+www.psiquiatraperu.net.
+games.yahoo.com.
+165.226.175.85.in-addr.arpa.
+profile.ak.fbcdn.net.
+87.148.59.199.in-addr.arpa.
+rock-com-mx.messaging.lotuslive.com.
+ville-bondy.fr.
+connect.facebook.net.
+s.youtube.com.
+4.116.26.201.in-addr.arpa.
+mail.
+amx.wimbledonwine.com.redcondor.net.
+manuel.sesamath.net.
+static.ak.fbcdn.net.
+144.96.186.93.in-addr.arpa.
+www.miscomentariosparahi5.com.
+alluretech.net.
+es.altavista.com.
+160.4.23.1.in-addr.arpa.
+yingwenlaoshi.files.wordpress.com.
+a7.sphotos.ak.fbcdn.net.
+www.facebook.com.
+a997.mm1.akamai.net.
+uza.s523ll5pu6s1.com.
+crl.microsoft.com.
+us.bc.yahoo.com.
+www.arkdiscovery.com.
+56.44.156.187.in-addr.arpa.
+ad.doubleclick.net.
+178.119.92.200.in-addr.arpa.
+nou-energetik.ru.
+mail.audiolot.com.
+75.140.22.96.in-addr.arpa.
+www.anewshit.com.
+profile.ak.fbcdn.net.
+hornmurdockcolesv.com.
+mediacenter.fedex.designcdt.com.
+citlink.ne.
+219.87.214.189.in-addr.arpa.
+www.youtube.com.
+57.25.53.186.in-addr.arpa.
+mailscan.hpcdsb.edu.on.ca.
+kmail.xanterra.com.
+billing.sharo4ka.ru.
+a2.twimg.com.
+seattlewireless.net.
+www.elgourmetonline.com.
+smtp.3web.com.
+80.193.93.186.in-addr.arpa.
+_268_50_2.
+94.89.168.192.in-addr.arpa.
+chromejs.s3.amazonaws.com.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+photos-g.ak.fbcdn.net.
+www.zodchiy.ru.
+uncmervenf.net.
+irrationalgames.com.
+a3.sphotos.ak.fbcdn.net.
+fsbbank.net.
+shared.live.com.
+www.gouwu265.com.
+implantedental1.wordpress.com.
+photos-b.ak.fbcdn.net.
+imap.gmail.com.
+multiply.multiply.com.
+a.root-servers.net.
+www.4nursingmanagers.com.
+244.16.26.201.in-addr.arpa.
+teredo.ipv6.microsoft.com.
+.
+icb.uni-due.de.
+www.facebook.com.
+apple-mobile.query.yahooapis.com.
+149.135.117.79.in-addr.arpa.
+gfx5.hotmail.com.
+col.stb01.s-msn.com.
+insuramericapr.com.
+translate.google.com.mx.
+dc407.4shared.com.
+gm.fb.telaxo.com.
+www.hifx.co.uk.
+photos-h.ak.fbcdn.net.
+100.199.130.186.in-addr.arpa.
+zonanet.com.
+photos-a.ak.fbcdn.net.
+a.root-servers.net.
+www.googleadservices.com.
+metagaming.co.uk.
+www.adoperator.com.
+plusone.google.com.
+racingplay.com.
+cf.addthis.com.
+stewie.wojas.nl.
+1omni.com.
+developers.facebook.com.
+www.m5zn.com.
+tv5i2f3bk.l99x6c1y.
+games.tvclip.biz.
+201.234.255.206.in-addr.arpa.
+eldiariodeunpoeta.blogspot.com.
+mail.catholic-dispatch.com.
+pixer.meaningtool.com.
+www.789son.com.
+a2.sphotos.ak.fbcdn.net.
+img851.imageshack.us.
+developers.facebook.com.
+b._dns-sd._udp.0.1.0.10.in-addr.arpa.
+a.root-servers.net.
+130.113.12.189.in-addr.arpa.
+27.25.27.190.in-addr.arpa.
+75.191.76.77.in-addr.arpa.
+sdelanovkitae.ru.
+it-it.facebook.com.
+ad.adnetwork.net.
+227.252.5.189.in-addr.arpa.
+fbcdn-photos-a.akamaihd.net.
+ssl.gstatic.com.
+www.tripadvisor.com.ar.
+luckywire.com.
+103.108.75.65.in-addr.arpa.
+232.228.227.76.in-addr.arpa.
+195.148.173.201.in-addr.arpa.
+static.ak.fbcdn.net.
+express10k.com.
+sp.cwfservice.net.
+photos-e.ak.fbcdn.net.
+al-shorfa.com.
+p0b.ru.
+teredo.ipv6.microsoft.com.
+huschoice.com.
+81.145.101.187.in-addr.arpa.
+a.rad.msn.com.
+canyonlakefun.com.
+www.heiferperu.org.
+static.ak.fbcdn.net.
+s.ytimg.com.
+www.freewebs.com.
+a6.sphotos.ak.fbcdn.net.
+encuesta.appinformatica.com.
+www.wall-maps.com.
+oascentral.yellowpages.com.
+warpdriveonline.com.
+linkhelp.clients.google.com.
+gl.wikipedia.org.
+ml1dc2.mfxservices.com.
+www.tripadvisor.com.
+glb1.rim.net.
+_370_54_5.
+239.131.131.41.in-addr.arpa.
+www.deal4loans.com.
+photos-f.ak.fbcdn.net.
+mx031.parking.ru.
+o-caso.blogspot.com.
+cs1716.vkontakte.ru.
+48.158.177.190.in-addr.arpa.
+safebrowsing.clients.google.com.
+.
+external.ak.fbcdn.net.
+clkads.com.
+www.googletagservices.com.
+static.ak.fbcdn.net.
+185.15.142.190.in-addr.arpa.
+t.co.
+www.youtube.com.
+220.117.223.87.in-addr.arpa.
+www.apple.com.
+faxcom.com.
+ssl.gstatic.com.
+giltgroup.tt.omtrdc.net.
+img1.blogblog.com.
+vbg.com.
+echo.edge.messenger.live.com.
+11.189.78.190.in-addr.arpa.
+mygames4girls.com.
+1804289383.localhost.
+s-static.ak.fbcdn.net.
+bar-navig.yandex.ru.
+static.ak.fbcdn.net.
+view.atdmt.com.
+a2.sphotos.ak.fbcdn.net.
+www.fundaciontelevisa.org.
+krauss.faculty.asu.edu.
+109.92.217.98.in-addr.arpa.
+mx01.altep.com.
+d3lvr7yuk4uaui.cloudfront.net.
+holmesmark.com.
+kof.net.
+a.root-servers.net.
+beocwjdrcmkagjvd.ac.
+i2.ytimg.com.
+125.220.9.186.in-addr.arpa.
+a.root-servers.net.
+time.windows.com.
+facemoods.com.
+spbmesi.ru.
+orcart.facebook.com.
+db._dns-sd._udp.0.1.168.192.in-addr.arpa.
+time.nist.gov.
+mycam.nl.softonic.com.
+mx2.wwecorp.com.gslb.pphosted.com.
+developers.facebook.com.
+translate.google.com.mx.
+static.ak.fbcdn.net.
+131.149.254.189.in-addr.arpa.
+clients1.google.com.
+a.root-servers.net.
+187.0.100.118.in-addr.arpa.
+www.youtube.com.
+www.alexa.com.
+www.facebook.com.
+saskeds.com.
+boskone.hmc.gotdns.org.
+e566.b.akamaiedge.net.
+cs5236.vkontakte.ru.
+templateswise.com.
+rogrs.com.
+216.29.32.189.in-addr.arpa.
+mscrl.microsoft.com.
+a.root-servers.net.
+www.cuadernalia.net.
+www.newsviva.com.
+kimpetoverby.museum.
+106.229.153.201.in-addr.arpa.
+www.facebook.com.
+airport.tomlin.yahoo.com.
+hotmail.com.rhsbl.ahbl.org.
+rfptemplates.technologyevaluation.com.
+nray.ru.
+www.newnavy.us.
+a.root-servers.net.
+www.crazycrow.com.
+a.root-servers.net.
+elpais.com.co.
+transgriot.blogspot.com.
+32.178.19.88.in-addr.arpa.
+stun.voip.blackberry.com.
+120.87.233.189.in-addr.arpa.
+hasack.com.s9a2.psmtp.com.
+102.246.50.200.in-addr.arpa.
+s-static.ak.facebook.com.
+s.youtube.com.
+bestcrystals.com.
+www.directorioxd.com.
+k2x1bals1.a05i0d3l.
+test.wpat.net.
+mail.intellichoicefs.com.
+laborum.files.wordpress.com.
+www.blend.nl.
+www.guardian.co.uk.
+m.facebook.com.
+a4.sphotos.ak.fbcdn.net.
+cup.com.
+ad.adriver.ru.
+allmovie.com.
+www-x.antd.nist.gov.
+54.5.156.187.in-addr.arpa.
+www19.atwiki.jp.
+api.conduit.com.
+eset.ee.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+a2.twimg.com.
+search.babylon.com.
+adfarm.mediaplex.com.
+centuryfitness.com.inbound15.mxlogic.net.
+a1.sphotos.ak.fbcdn.net.
+102.1.168.192.in-addr.arpa.
+www.e-belis.com.
+counter.yadro.ru.
+cdn1.predictad.com.
+jzabaleta.com.
+www.blankpaper.es.
+a.root-servers.net.
+wzus1.ask.com.
+136.198.188.78.in-addr.arpa.
+plusone.google.com.
+fcyt449ng.z12q4h0u.
+www.occidente.com.gt.
+130.188.111.200.in-addr.arpa.
+chat.5251.net.
+gafneyphoto.com.
+mifab.thomasnet-navigator.com.
+www.vsbag.com.
+www.union-web.com.
+fr-fr.facebook.com.
+a5.sphotos.ak.fbcdn.net.
+a5.sphotos.ak.fbcdn.net.
+210.64.35.177.in-addr.arpa.
+content.yieldmanager.edgesuite.net.
+www.google.com.
+static02.olx-st.com.
+orcart.facebook.com.
+whos.amung.us.
+negligee.ru.
+youtu.be.
+teredo.ipv6.microsoft.com.
+1.200.181.93.in-addr.arpa.
+a.root-servers.net.
+d3o96a3f9o7chl.cloudfront.net.
+250.93.54.200.in-addr.arpa.
+www.bittorrent.com.
+www.intermec.com.sg.
+a.root-servers.net.
+a1.sphotos.ak.fbcdn.net.
+b.scorecardresearch.com.
+apps.facebook.com.
+plugandplay.at.
+3.33.112.187.in-addr.arpa.
+165.116.98.171.in-addr.arpa.
+gfx2.hotmail.com.
+a.root-servers.net.
+iphone-wu.apple.com.
+6.54.222.67.rbl7.mailshell.net.
+12.44.31.190.in-addr.arpa.
+bt.btbbt.com.home.
+idh.ru.
+client61.dropbox.com.
+mail.recycling.ru.
+gfx1.hotmail.com.
+a4.sphotos.ak.fbcdn.net.
+profile.ak.fbcdn.net.
+s-static.ak.fbcdn.net.
+messenger.hotmail.com.
+tryfaith.com.
+js.admeld.com.
+ksn2-12.kaspersky-labs.com.
+57.21.94.186.in-addr.arpa.
+vips.msk.rsnet.ru.
+fms.n-tv.de.
+www.dakotaraepatrick.com.
+www.boosterking.com.
+orig-10012.twitter.cotcdn.net.
+166.22.114.211.in-addr.arpa.
+97.198.133.110.in-addr.arpa.
+107.200.26.95.in-addr.arpa.
+www.google-analytics.com.
+www.7x24sex.net.
+profile.ak.fbcdn.net.
+saturn.ak.planet.gen.nz.
+list.cn99.com.
+hhreal.gratisforo.net.
+a.root-servers.net.
+graph.facebook.com.
+pagead2.googlesyndication.com.
+154.1.53.186.in-addr.arpa.
+mail2.korrus.ru.
+external.ak.fbcdn.net.
+sd2mbdavk.29df.
+202.128.71.190.in-addr.arpa.
+goodsonauto.com.s8a2.psmtp.com.
+d2107659.xoom.it.
+a.root-servers.net.
+login.live.com.
+tools.google.com.
+3.96.252.207.zen.spamhaus.org.
+mail.ivank.ru.
+www.mp3musichq.com.
+windows-xp-wallpaper.softonic.com.
+js.wlxrs.com.
+chemline.ru.
+www.cupchicks.com.
+s-static.ak.facebook.com.
+253.208.210.186.in-addr.arpa.
+cdn.api.twitter.com.
+mail.men-and-women.ru.
+a.root-servers.net.
+vancouver.conagramalt.com.
+98.92.238.190.in-addr.arpa.
+www.longliveyourdog.com.
+v2.lscache6.c.android.clients.google.com.
+a749.g.akamai.net.
+photos-a.ak.fbcdn.net.
+191.6.64.72.in-addr.arpa.
+134.59.7.187.in-addr.arpa.
+28.media.tumblr.com.
+connect.facebook.net.
+platform.twitter.com.
+photos-b.ak.fbcdn.net.
+a6.sphotos.ak.fbcdn.net.
+fagalab.com.
+js2.wlxrs.com.
+personalysis.com.inbound15.mxlogic.net.
+googleads.g.doubleclick.net.
+s10.es.ikariam.com.
+www.pistolpete.com.
+web66-vip.sdv.fr.
+52.7.25.190.in-addr.arpa.
+0-271.channel.facebook.com.
+static.ak.fbcdn.net.
+101.64.118.190.in-addr.arpa.
+b-0.19-210a0449.1581.1518.19d3.2f4a.210.0.ug7mmc32tu8lbeq56ja4dwta6i.avqs.mcafee.com.
+cf.addthis.com.
+ko.wikipedia.org.
+photos-e.ak.fbcdn.net.
+74.223.35.83.in-addr.arpa.
+barracuda.chatom.k12.ca.us.
+rhl8rwuh5.f79o2g9n.
+badgersportswear.com.
+webcache.googleusercontent.com.
+help.yahoo.com.
+michiganladder.com.
+a3.sphotos.ak.fbcdn.net.
+rekaone.com.
+a7dvqduqu.03hn.
+lf2-global.com.
+platform.twitter.com.
+mmoca.org.
+ads.publicidad.net.
+photos-f.ak.fbcdn.net.
+skogmar.com.
+a.root-servers.net.
+97.90.50.190.in-addr.arpa.
+61.245.1.190.in-addr.arpa.
+photos-d.ak.fbcdn.net.
+firntool.ru.
+a8.sphotos.ak.fbcdn.net.
+accounts.google.com.
+snt132w.mail.live.com.akadns.net.
+au.download.windowsupdate.com.
+s-static.ak.fbcdn.net.
+91.40.188.119.in-addr.arpa.
+thumbs4.ebaystatic.com.
+mail2.sg.megachem.com.
+independent.net.
+59.31.23.186.in-addr.arpa.
+131.26.162.201.in-addr.arpa.
+news.google.es.
+kw.zain.com.
+39.60.54.151.in-addr.arpa.
+kk.wikipedia.org.
+clients1.google.com.
+cine.interbusca.com.
+urbanbarn.com.
+salvasainz.magix.net.
+www.google-analytics.com.
+view.atdmt.com.
+en.wikipedia.org.
+www.youtube-nocookie.com.
+sv1.readmangahentai.com.
+www.facebook.com.
+141.20.168.192.in-addr.arpa.
+cableone.net.
+www.juegos.com.
+mail.rochester.rr.com.
+8ninp3dbe.81ce.
+mail.google.com.
+local-bay.contacts.msn.com.
+evt.adrcntr.com.
+tutorialesdesing.mforos.com.
+134.197.136.186.in-addr.arpa.
+creative.ak.fbcdn.net.
+ydmd.msn.com.
+a4.sphotos.ak.fbcdn.net.
+232.210.152.189.in-addr.arpa.
+evileyetattoo.blogspot.com.
+cdn.rockyou.com.
+www.youtube.com.
+members.dyndns.org.
+www.sbfoot.com.
+overunity.com.
+servicios.prodigy.msn.com.
+www.ftalk.com.
+mail.dimensional.com.
+www.lge.com.
+bio-med.ru.
+www.ebusinessblog.org.
+clients1.google.com.
+www.hidramaq.com.
+aerocondor.com.pe.
+ntp.bluecoat.com.
+r.mzstatic.com.
+zynga1-a.akamaihd.net.
+pacman.net.
+www.facebook.com.
+fbeau.com.
+g.msn.com.
+inbound.cotham.org.netsolmail.net.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+login.live.com.
+87.89.172.187.in-addr.arpa.
+directory.services.live.com.
+42.19.35.188.in-addr.arpa.
+xnxbpnmag.60cu.
+f.h1.hiltonhhonors.com.
+a.root-servers.net.
+www.facebook.com.
+www.amazon.com.
+fbcdn-sphotos-a.akamaihd.net.
+chandlery.apolloduck.com.
+exceptnothing.com.
+a5.sphotos.ak.fbcdn.net.
+pixel.facebook.com.
+252.49.145.189.in-addr.arpa.
+fbcdn-photos-a.akamaihd.net.
+c29.smaato.net.
+maps.google.com.
+sp.cwfservice.net.
+internalcomms.com.ar.
+www.afrosomething.com.
+45.219.158.190.in-addr.arpa.
+6cylopnpm.08lw.
+solarcontroljackson.com.
+148.55.31.190.in-addr.arpa.
+aprn.org.
+s-static.ak.facebook.com.
+208.130.142.187.in-addr.arpa.
+cdn.ad4game.com.
+www.uccuyosl.edu.ar.
+webcache.googleusercontent.com.
+mailgate4.econ.usyd.edu.au.
+forum.techie-buzz.com.
+stromvergleich.freenet.de.
+developers.facebook.com.
+100.198.178.189.in-addr.arpa.
+circusdisco.com.
+stamm-mfg.com.
+photos-d.ak.fbcdn.net.
+matcher.bidder7.mookie1.com.
+163.229.183.212.in-addr.arpa.
+www.bloompapers.com.
+ox-d.liftdna.com.
+i2.ytimg.com.
+a8.sphotos.ak.fbcdn.net.
+www.garageflash.org.
+s1-word-view.vo.msecnd.net.
+googleads.g.doubleclick.net.
+a7.sphotos.ak.fbcdn.net.
+j1.tagstat.com.
+a.root-servers.net.
+profile.ak.fbcdn.net.
+a1943.phobos.apple.com.
+fbcdn-profile-a.akamaihd.net.
+www.landroversuk.co.uk.
+cuantopuedecostar.blogspot.com.
+pinoy.top-site-list.com.
+thepartyworks.com.
+211.219.201.190.in-addr.arpa.
+weather.wapp.wii.com.
+developers.facebook.com.
+a1.sphotos.ak.fbcdn.net.
+loading3.widdit.com.
+mail86a.rheinmetall-de.com.
+blumoe.com.
+phone.com.
+43region.ru.
+mscrl.microsoft.com.
+a8.sphotos.ak.fbcdn.net.
+61.87.163.189.in-addr.arpa.
+aol.com.
+v5.nonxt1.c.youtube.com.
+hopkinsonline.net.
+larompieron.cl.
+ap.faceboooky.com.ar.
+thumbs1.ebaystatic.com.
+mt1.google.com.
+kg3pzattr.66kk.
+57.203.230.190.in-addr.arpa.
+238.55.159.189.in-addr.arpa.
+a.root-servers.net.
+sitecheck2.opera.com.
+mail.mz.ru.
+25.1.1.10.in-addr.arpa.
+a.root-servers.net.
+a.root-servers.net.
+130.52.82.200.in-addr.arpa.
+ecimages.kobobooks.com.
+www.caratulart.com.
+92yzc84ny.72iw.
+100.145.67.109.in-addr.arpa.
+grupos.emagister.com.
+debbiecutieface.com.
+www.thepowerbase.com.
+www.doublegames.ws.
+d2098683.xoom.it.
+mirror.fdcservers.net.localdomain.
+a.root-servers.net.
+api.facebook.com.
+www.ramnousia.com.
+a868.phobos.apple.com.
+checkip.dyndns.org.
+fbcdn-photos-a.akamaihd.net.
+www.sinmiedo.es.
+google.com.
+media.admob.com.
+www.facebook.com.
+www.orangerockcorps.co.uk.
+a2.mzstatic.com.
+218.182.34.189.in-addr.arpa.
+events.unesco.org.
+google.com.
+img5.catalog.video.msn.com.
+i1.ytimg.com.
+www.youtube.com.
+187.147.157.82.in-addr.arpa.
+mail.brandytrust.com.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+www.facebook.com.
+s.ytimg.com.
+www.hotvintagetube.com.
+adsx.greystripe.com.
+www.longzhiguang.cn.
+n02.nakanohito.jp.
+mail.lnisigns.com.
+www.gstatic.com.
+sac.gti.mcafee.com.
+www.fvc.org.br.
+cottoneyedjoe.com.
+services.addons.mozilla.org.
+www.nationwide.com.
+0.11-230f8081.8020081.1518.1945.3ea0.200.0.en9j4bbznzcg3nfde5c5ia2qrv.avqs.mcafee.com.
+img.pulsemgr.com.
+www.ker-mor.com.
+172.218.142.187.in-addr.arpa.
+mail2.itko.com.
+joker.u.pereslavl.ru.
+www.facebook.com.
+www.uruguay.com.
+sites.google.com.
+mta5.am0.yahoodns.net.
+owmd8hdae.98ui.
+en.wikipedia.org.
+photos-d.ak.fbcdn.net.
+de-de.facebook.com.
+www.trubka.ru.
+photos-c.ak.fbcdn.net.
+wbhsi.net.
+imgb.noticiascristianas.me.
+_794_46_0.
+a.root-servers.net.
+www.cgdd.org.
+developers.facebook.com.
+48.165.168.192.in-addr.arpa.
+20minutos.feedsportal.com.
+immunbio.mpg.de.
+a.root-servers.net.
+210.235.121.84.in-addr.arpa.
+login.toolbar.conduit-services.com.
+83.25.179.187.in-addr.arpa.
+11.176.88.174.in-addr.arpa.
+a5.sphotos.ak.fbcdn.net.
+photos-d.ak.fbcdn.net.
+api-read.facebook.com.
+mscrl.microsoft.com.
+teredo.ipv6.microsoft.com.
+94.222.91.186.in-addr.arpa.
+192.12.0.180.in-addr.arpa.
+alservice.com.
+inbound.medirattas.com.netsolmail.net.
+a.root-servers.net.
+esdc006.eame.global.sgs.com.
+74.209.216.41.in-addr.arpa.
+www.3lakeefk.blogspot.com.
+dowcorning.com.
+46.65.19.186.in-addr.arpa.
+photos-g.ak.fbcdn.net.
+www.bbc.co.uk.
+ad.yieldmanager.com.
+ads.bluelithium.com.
+tilers.ru.
+107.204.103.189.in-addr.arpa.
+thecentergb.org.
+auditors.spb.ru.
+www.google-analytics.com.
+eo.wikipedia.org.
+remanage.otepremium.gr.
+95.231.41.126.in-addr.arpa.
+105.196.13.189.in-addr.arpa.
+www.galiciasustentable.com.
+www.blogger.com.
+rxservices.co.uk.
+www.socialgrowthtechnologies.com.
+lo393qwertasd.com.
+static.ak.connect.facebook.com.
+twitter.com.
+a.root-servers.net.
+www.aleks.com.
+facebook.farmville.com.
+www.google.com.
+ksn7-12.kaspersky-labs.com.
+a4.sphotos.ak.fbcdn.net.
+crl.geotrust.com.
+crecardoffer.com.
+191.29.95.201.in-addr.arpa.
+s-static.ak.fbcdn.net.
+desemejanza.br.dnsbl7.mailshell.net.
+z5riknayz.54ar.
+adonis.ru.
+imagen04.247realmedia.com.
+client.winamp.com.
+35.160.143.190.in-addr.arpa.
+a.root-servers.net.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+smtp.ftnewyorklife.com.
+translate.googleapis.com.
+www.loveland.k12.oh.us.
+nbase.com.
+resources.rosettastone.com.
+lyricswillnotreachtheaudience.blogspot.com.
+www.it-bs.com.ar.
+denis.stalker.h3q.com.
+js2.wlxrs.com.
+www.itinytits.com.
+110.88.96.99.in-addr.arpa.
+zao-gorod.ru.
+ro.wikipedia.org.
+login.live.com.
+jxe.com.
+concordehealth.net.
+46.42.171.189.in-addr.arpa.
+entertainmentwise.com.
+www.youtube.com.
+217.210.35.200.in-addr.arpa.
+91.125.47.189.in-addr.arpa.
+www.clinicaser.info.
+cdn2.stanleysupplyservices.com.
+syndication.exoclick.com.
+ltasconfig.ltassrv.com.
+181.113.112.186.in-addr.arpa.
+194.222.111.189.in-addr.arpa.
+dns.msftncsi.com.
+static.ak.facebook.com.
+49.200.19.204.in-addr.arpa.
+www.dressessalestore.com.
+www.twitter.com.
+189.104.93.186.in-addr.arpa.
+ussigns.com.inbound15.mxlogicmx.net.
+blackberrycool.com.
+92.165.202.64.in-addr.arpa.
+www.mp3sugar.com.
+hdarena.org.
+www.youtube.com.
+ksn2-12.kaspersky-labs.com.
+trend_micro_titanium_internet_security.en.softonic.com.
+platform.twitter.com.
+246.155.172.190.in-addr.arpa.
+ad.doubleclick.net.
+maps.google.com.
+pacific-islander.blogspot.com.
+www.juegosjuegos.com.
+noesporpresumir.blogspot.com.
+api.facebook.com.
+207.155.251.189.in-addr.arpa.
+d2089124.xoom.it.
+a.root-servers.net.
+loading321.com.
+drb.com.ru.
+profile.ak.fbcdn.net.
+easygoingscans.disqus.com.
+dnl-01.geo.kaspersky.com.
+www.escapade-media.com.
+www.facebook.com.
+photos-f.ak.fbcdn.net.
+i4.ytimg.com.
+www.google-analytics.com.
+api.facebook.com.
+photos-c.ak.fbcdn.net.
+d2107803.xoom.it.
+b._dns-sd._udp.0.1.168.192.in-addr.arpa.
+www.busty-teenager.com.
+p0.go2map.com.
+muppethouse.com.
+dns.msftncsi.com.
+rwwa.com.au.
+www.wintershoesforwomen.com.
+a1725.l.akamai.net.
+194.81.116.122.in-addr.arpa.
+sp.cwfservice.net.
+cdn.tynt.com.
+unterhaltung.freenet.de.
+www3.l.google.com.
+149.32.222.190.in-addr.arpa.
+gcecisp.com.
+mail.panthera-systems.net.
+amazing-3d-aquarium.softonic.com.
+www.facebook.com.
+platform.twitter.com.
+214.188.138.189.in-addr.arpa.
+s7.addthis.com.
+googleads.g.doubleclick.net.
+hcmintl.com.
+www.sepyme.gov.ar.
+interpartner-bg.ru.
+www.databasebasketball.com.
+130.146.92.114.in-addr.arpa.
+yjmkfhcul.14hi.
+connect.facebook.net.
+www.bonanzabucks.com.
+a3.sphotos.ak.fbcdn.net.
+gastro.org.
+a8.sphotos.ak.fbcdn.net.
+921lqelam.v68l4d9s.
+cydiahelp.com.
+acordespara-guitarra.blogspot.com.
+trucosparacityville.com.
+www.livetemplate.co.cc.
+rv.ginyas.com.
+a1148.phobos.apple.com.
+ajax.googleapis.com.
+ar-ar.facebook.com.
+15.28.248.99.in-addr.arpa.
+i3.ytimg.com.
+1.227.168.192.in-addr.arpa.
+212.246.160.190.in-addr.arpa.
+www.autocue.com.
+tg.9600518.com.
+a2.sphotos.ak.fbcdn.net.
+im.afy11.net.
+youtube.desifun.co.uk.
+www.sexonomotel.com.br.
+bitnova.info.
+event.republika.co.id.
+admin.nmt.edu.
+garywarnett.wordpress.com.
+attitudeclothing.co.uk.
+pyzxc32nm.k46s1e0x.
+photos-e.ak.fbcdn.net.
+195.139.213.186.in-addr.arpa.
+182.51.10.186.in-addr.arpa.
+www.merval.sba.com.ar.
+www.cintras.org.
+apps.facebook.com.
+www.linkedin.com.
+punk-medallo.blogspot.com.
+45.232.204.130.in-addr.arpa.
+112.59.51.201.in-addr.arpa.
+cdn.niche.videosz.com.
+sp.cwfservice.net.
+northcenter.com.
+gut.bmjjournals.com.
+sc21.rules.mailshell.net.
+fb-fb-0.castle.zynga.com.
+vk.com.
+.
+ihardlyknowher.com.
+moyaodejda.ru.
+pt-br.facebook.com.
+www.stephenking.com.
+www.google.com.
+www.longrangeweather.com.
+mls.softjoys.com.
+www-t.decisionnewsmedia.com.
+102.45.78.201.in-addr.arpa.
+coastallenv.com.
+coins.mochimedia.com.
+a5.sphotos.ak.fbcdn.net.
+142.192.56.190.in-addr.arpa.
+scholar.google.com.
+147.128.66.201.in-addr.arpa.
+vampiro.comze.com.
+h.live.com.
+mscrl.microsoft.com.
+googleads.g.doubleclick.net.
+tinyurl.com.
+go.srvnow.com.
+71.223.163.93.in-addr.arpa.
+teredo.ipv6.microsoft.com.
+creative.ak.fbcdn.net.
+danielnylander.se.
+bwig.net.
+grooveshark.com.
+je.org.
+a.root-servers.net.
+a.root-servers.net.
+shares.ru.
+mystartantiphishing.com.
+143.244.165.83.in-addr.arpa.
+ednathomazini.blogspot.com.
+dns.msftncsi.com.
+ad-g.doubleclick.net.
+www.facebook.com.
+35.203.19.24.in-addr.arpa.
+inbound.pwpellets.com.netsolmail.net.
+rcp.na.blackberry.com.
+static.ak.fbcdn.net.
+plusone.google.com.
+evsecure-ocsp.verisign.com.
+fordhamgrad.com.
+24.132.217.190.in-addr.arpa.
+mismaderitascountry.blogspot.com.
+www.pediatraenlinea.com.
+download.windowsupdate.com.
+b._dns-sd._udp.0.1.168.192.in-addr.arpa.
+www.domainlogr.com.
+200.83.139.175.in-addr.arpa.
+krauscarpet.com.
+de.tynt.com.
+mail.rlcone.com.
+www.desafinacoes.pt.vu.
+43.236.20.186.in-addr.arpa.
+chromeupdate.dealply.com.
+csa.yahoo.com.
+photos-c.ak.fbcdn.net.
+zh-cn.facebook.com.
+186.169.209.190.in-addr.arpa.
+199.71.191.189.in-addr.arpa.
+pixel.facebook.com.
+a2.sphotos.ak.fbcdn.net.
+fabcon-usa.com.
+m.facebook.com.
+ns.rx.ru.
+www.google.com.
+photos-c.ak.fbcdn.net.
+dns.msftncsi.com.
+yaproffi.ru.
+google.com.
+211.72.223.71.in-addr.arpa.
+127.139.245.189.in-addr.arpa.
+attaboy.ru.
+fbcdn-sphotos-a.akamaihd.net.
+img-2006-07.photosight.ru.
+www.google-analytics.com.
+photos-g.ak.fbcdn.net.
+nicewallpaper.tk.
+db._dns-sd._udp.0.2.168.192.in-addr.arpa.
+orcart.facebook.com.
+www.google-analytics.com.
+www.facebook.com.
+us.mg5.mail.yahoo.com.
+e.travelocity.co.in.
+iso1200.blogspot.com.
+www.doulike.us.
+demo.templatepanic.com.
+244.42.182.190.in-addr.arpa.
+g.live.com.
+www.facebook.com.
+trcexcedg02.madisoncity.k12.al.us.
+a.root-servers.net.
+.
+www.facebook.com.
+peoplescube.com.
+ip1.dynupdate.no-ip.com.
+98.188.160.190.in-addr.arpa.
+announce.com.
+116.30.118.190.in-addr.arpa.
+smtp1.emv2.com.
+a4.sphotos.ak.fbcdn.net.
+226.103.213.189.in-addr.arpa.
+lasdinamicas12.blogspot.es.
+108.64.95.190.in-addr.arpa.
+a.root-servers.net.
+53.234.226.24.in-addr.arpa.
+tadufeu-lefilm.com.
+z-ecx.images-amazon.com.
+www.meet-teens.de.
+mta5.am0.yahoodns.net.
+42.60.122.186.in-addr.arpa.
+rs.gwallet.com.home.
+78.45.143.168.in-addr.arpa.
+www.uach.cl.
+197.255.179.190.in-addr.arpa.
+8zc5kyxmq.12pt.
+creative.ak.fbcdn.net.
+iesnorbabachillerato.files.wordpress.com.
+www.hairdirect.com.
+b._dns-sd._udp.0.1.168.192.in-addr.arpa.
+53.244.84.200.in-addr.arpa.
+136.234.38.81.in-addr.arpa.
+www.artplus.hr.
+www.update.microsoft.com.
+checkip.dyndns.com.
+www.msn.com.
+cs606.vk.com.
+www.google.com.
+www.eljusticiadearagon.com.
+mail.google.com.
+a1005.w42.akamai.net.
+a.root-servers.net.
+axcoto.com.
+mailstore1.secureserver.net.
+www.google.com.
+b-0.19-a3005008.1081.1518.19d3.3ea1.410.0.trqnb8j7c6bttppqf7njezi3zb.avqs.mcafee.com.
+190.249.169.189.in-addr.arpa.
+www.megavideo.com.
+165.25.173.190.in-addr.arpa.
+ise.qc.ca.
+240.153.68.190.in-addr.arpa.
+ci.santa-maria.ca.us.
+neustarinc.com.
+176.112.137.201.in-addr.arpa.
+insider.msg.yahoo.com.
+en.y8.com.
+utamie.com.
+a.root-servers.net.
+swxmail01.freddiemac.com.
+213.243.34.187.in-addr.arpa.
+www.alimam.ws.
+zh-cn.facebook.com.
+12.1.168.192.in-addr.arpa.
+rospres.com.
+a8.sphotos.ak.fbcdn.net.
+cdn.api.twitter.com.
+109.81.173.186.in-addr.arpa.
+www.googletagservices.com.
+50.37.253.88.in-addr.arpa.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+csi.gstatic.com.
+29.156.226.189.in-addr.arpa.
+www.hds.com.
+a.root-servers.net.
+secure.wlxrs.com.
+82.8.241.85.in-addr.arpa.
+static.socialvi.be.
+calendar.live.com.
+127.246.143.189.in-addr.arpa.
+thebarefootcontessa.hautetfort.com.
+184.wap517.mobi.
+a.root-servers.net.
+mail.desmet.org.
+85.137.98.62.in-addr.arpa.
+orcart.facebook.com.
+www.fdf.ac.uk.
+website.informer.com.
+egeo.bcr.gob.sv.
+fbcdn-photos-a.akamaihd.net.
+da4:6z2::.r44a0i0s.
+61ov3xt8x.58ev.
+photos-e.ak.fbcdn.net.
+quick-876346.com.
+a1.sphotos.ak.fbcdn.net.
+c.prodigy.msn.com.
+s7.addthis.com.
+aurita.spb.ru.
+www.mansilla-lanzuela.com.
+photos-a.ak.fbcdn.net.
+bbvabancomer.com.
+webmail.woolemsinc.com.
+tmgnow.com.
+hi-in.facebook.com.
+timelinevideo.com.
+a2.sphotos.ak.fbcdn.net.
+mweb.co.za.
+capitalventureslc.com.
+sherl.ru.
+weglobal.com.mail1.psmtp.com.
+l18.member.mud.yahoo.com.
+glph.com.s7a1.psmtp.com.
+www.counterstrikestrats.com.
+2.bp.blogspot.com.
+elcharlas.com.
+s3dg.com.
+_568_97_3.
+www.jugos.com.
+appsuite-production.s3.amazonaws.com.
+blog.strava.com.
+www.bbc.co.uk.
+www.radioasturias.com.
+ip-science.thomsonreuters.com.
+a.root-servers.net.
+a.root-servers.net.
+mail.aplusdevelopment.ru.
+insightbb.com.
+csi.gstatic.com.
+cdn.api.twitter.com.
+adsbc.com.
+thegroovemusiclife.com.
+hzykvhi1q.07dd.
+223.46.141.201.in-addr.arpa.
+a.root-servers.net.
+desastrosamenteyo.blogspot.com.
+ajax.googleapis.com.
+p0b.ru.
+cpr.nipc.net.
+creative.ak.fbcdn.net.
+evapco.com.
+www.petter.nu.
+static3.spilcdn.com.
+cdn.mediafire.com.
+www.facebook.com.
+www.facebook.com.
+atypicalrealism.net.
+crl.verisign.com.
+mail.hexindo-tbk.co.id.
+www.facebook.com.
+ads2.msads.net.
+apps.facebook.com.
+pair.com.
+s2.youtube.com.
+monitel.ru.
+38.43.78.201.in-addr.arpa.
+a.c-0.19-230f8081.c120081.1518.19d2.3ea0.210.0.zjbe7f1jq5pn6gzubrpvg9q57b.avqs.mcafee.com.
+alamc.org.
+a8.sphotos.ak.fbcdn.net.
+ic1.apps.yahooapis.com.
+a7.sphotos.ak.fbcdn.net.
+mail.comestiblesalfa.com.
+bs.serving-sys.com.
+jumpsstars2ds.ms1.gs.nintendowifi.net.
+hot.mshome.net.
+spnoibapp02.emea.sas.com.
+pixel.facebook.com.
+msgnlaw.com.
+forums.vostu.com.
+noexcusesbbq.com.
+profile.ak.fbcdn.net.
+_sip._udp.callcentric.com.
+zanoga.znakomstva.ru.
+nascentric.com.
+sqm.microsoft.com.
+mx1.atlasta.us.
+240.58.219.190.in-addr.arpa.
+www.wepa-db.net.
+floyd-pflueger.com.
+ballaro.blog.rai.it.
+58.156.80.186.in-addr.arpa.
+1.194.176.190.in-addr.arpa.
+us.mg6.mail.yahoo.com.
+8.170.25.177.in-addr.arpa.
+hg.ca.
+3.240.176.189.in-addr.arpa.
+ajax.googleapis.com.
+127.7.138.190.in-addr.arpa.
+barracuda.hilbert.edu.
+www.google-analytics.com.
+tubescript.nubiles.net.
+9lzodgg65.h08p8m7y.
+www.you.
+a7.sphotos.ak.fbcdn.net.
+aus3.mozilla.org.
+photos-d.ak.fbcdn.net.
+52.86.190.190.in-addr.arpa.
+geoiplookup.wikimedia.org.
+bluewin.ch.
+252.208.208.77.in-addr.arpa.
+49.41.244.190.in-addr.arpa.
+broadway.com.
+www.gamenews.ne.jp.
+accounts.google.com.
+blog.focus.it.
+led.com.br.
+mx.comtenidos.com.
+www.gstatic.com.
+da.wikipedia.org.
+distilleryimage6.s3.amazonaws.com.
+a.root-servers.net.
+safebrowsing-cache.google.com.
+lyjak.waw.pl.
+i26.lulzimg.com.home.
+google.com.
+media.solmelia.com.
+areku-desingblog.blogspot.com.
+a4.sphotos.ak.fbcdn.net.
+www.virtual-person.com.
+dragon.rioangrybirds.net.
+mx.painenterprises.com.
+www.fantastigames.com.
+intdoc.com.s5b1.psmtp.com.
+plusone.google.com.
+a.root-servers.net.
+affiliates.indialist.com.
+dns.msftncsi.com.
+hareega.blogspot.com.
+www.youtube.com.
+google.com.
+idcs.interclick.com.
+apis.google.com.
+ocsp.verisign.com.
+knitfamily.blogspot.com.
+246.109.53.186.in-addr.arpa.
+aol.com.
+a.root-servers.net.
+rjljz9jld.f77v7n9k.
+ovi.la.
+mob.adwhirl.com.
+146.103.117.200.in-addr.arpa.
+a8.sphotos.ak.fbcdn.net.
+a3.da1.akamai.net.
+mail.environmentalworks.com.
+cwclick.cingular.com.
+api.twitter.com.
+img4.pixhost.org.
+a6.sphotos.ak.fbcdn.net.
+66.253.63.200.in-addr.arpa.
+translate.googleapis.com.
+www.naviextras.com.
+124.119.195.207.in-addr.arpa.
+kingbulletmods.de.tl.
+bourbonhospital.com.
+avetisian.ru.
+a.root-servers.net.
+mail.klimenko.com.
+14.197.60.213.in-addr.arpa.
+literatura1.foroactivo.com.
+comunicaciondiegosaturno.wordpress.com.
+97.43.176.190.in-addr.arpa.
+tvshowfavs.com.
+124.255.193.71.in-addr.arpa.
+developers.facebook.com.
+fxfeeds.mozilla.com.
+www.hotmail.com.
+apps.facebook.com.
+www.tvazteca.com.
+www.youtube.com.
+inicioid.com.
+photos-a.ak.fbcdn.net.
+www.isegs.com.
+www.hawaiiantropic.com.
+198.79.18.177.in-addr.arpa.
+10.172.168.192.in-addr.arpa.
+img.hotwords.com.br.
+db._dns-sd._udp.0.1.168.192.in-addr.arpa.
+mail.
+biologainteractiva.files.wordpress.com.
+3636.323230.313531.3830.80h42dc9750.webcfs00.com.
+plusone.google.com.
+academystudios.com.
+31.164.82.186.in-addr.arpa.
+mx293.emailfiltering.com.
+www.mobilerule.com.
+centraldoprog.blogspot.com.
+soa.md.
+www.5min.com.
+static.ak.fbcdn.net.
+blog.deepskycolors.com.
+www.wdc.com.
+gwc2.mine.nu.home.
+login.live.com.
+teredo.ipv6.microsoft.com.
+sbclgobla.net.
+www.job.ru.
+m.facebook.com.
+www.marquipwardunited.com.
+_kerberos._tcp.phl00._sites.dc._msdcs.gwamericas.corpnet1.com.
+www.google.com.
+www.facebook.com.
+ksn1-11-part2.kaspersky-labs.com.
+mashable.com.
+www.blogger.com.
+www.facebook.com.
+kinopodborka.ru.
+207.80.124.189.in-addr.arpa.
+mail.revealingtruth.org.
+cofetel.gob.mx.
+73.142.232.189.in-addr.arpa.
+echo.edge.messenger.live.com.
+tl.iek.ru.
+agt.p.360.cn.
+mail.barrengineering.com.
+walalabarker.no-ip.org.
+a.root-servers.net.
+225.0.109.200.in-addr.arpa.
+www.bridesmaiddressesnewyork.com.
+img.strictrestraint.com.
+219.65.226.190.in-addr.arpa.
+a1836.phobos.apple.com.
+thumbnails31.imagebam.com.
+clients1.google.com.
+rad.msn.com.
+oidossucios.com.
+a.tribalfusion.com.
+a1.sphotos.ak.fbcdn.net.
+medicosconscientes.com.
+crl3.digicert.com.
+linksv.com.
+googleads.g.doubleclick.net.
+101.158.66.190.in-addr.arpa.
+a3.sphotos.ak.fbcdn.net.
+staff.vault.com.inbound15.mxlogicmx.net.
+a6.sphotos.ak.fbcdn.net.
+js.wlxrs.com.
+ssl.gstatic.com.
+i2.ytimg.com.
+relay.globetrotter.net.
+cloud-search-msgplus.linkury.com.
+yui.yahooapis.com.
+www.youtube.com.
+2012carbentley.imagehostinghosting.com.
+21.70.111.200.in-addr.arpa.
+todomh.foros.ws.
+clients1.google.com.
+_740_69_7.
+s-static.ak.facebook.com.
+219.18.173.189.in-addr.arpa.
+s-static.ak.fbcdn.net.
+zone9.hotwords.com.br.
+messenger.providesupport.com.
+willowshields.net.
+igiva.net.
+accounts.google.com.
+a2.sphotos.ak.fbcdn.net.
+www.hygeiababy.com.
+accounts.google.com.
+48.87.16.186.in-addr.arpa.
+_009_26_4.
+mf2.ijnet.net.
+232.28.92.201.in-addr.arpa.
+www.ebay.com.
+www.ypagesminnesota.com.
+www.update.microsoft.com.
+cs10361.vk.com.
+content.yieldmanager.edgesuite.net.
+dns.msftncsi.com.
+.
+east.exch024.serverdata.net.
+loqo.ru.
+photos-a.ak.fbcdn.net.
+photos-b.ak.fbcdn.net.
+dl-client6.dropbox.com.
+mail.uacparts.com.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+petanque.ru.
+udc.msn.com.
+feeds.the9513.com.
+alerts.conduit-services.com.
+www.buzzdock.com.
+mgks.ru.
+www.mundofox.com.
+5directconnection.sytes.net.
+56.150.168.192.in-addr.arpa.
+www.cpxadspace.com.
+wpad.belkin.
+cogito.co.uk.
+profile.ak.fbcdn.net.
+m.hardsextube.com.
+www.traductorgoogle.com.mx.
+geo.messenger.services.live.com.
+profile.ak.fbcdn.net.
+chong.paipai.com.
+231.109.180.173.in-addr.arpa.
+mail.live.com.
+www.youtube.com.
+70.103.62.190.in-addr.arpa.
+wr.com.au.
+xtwitcam-paulocoelhox.e.channel.livestream.com.
+pixel.facebook.com.
+xmpp.device05.prod.capptain.com.
+fbcdn-profile-a.akamaihd.net.
+mail.earh.com.
+docs.google.com.
+photos-h.ak.fbcdn.net.
+clubsearay.com.
+irc.purchaseservice.com.
+smtp2.i-wanna.com.
+www.hungriaturismo.com.
+rosecm.com.
+nethra.us.com.s6a2.psmtp.com.
+gfx2.hotmail.com.
+abmh.org.
+an.tacoda.net.
+photos-a.ak.fbcdn.net.
+config.conduitapps.com.
+_094_45_2.
+maps.googleapis.com.
+83.111.153.186.in-addr.arpa.
+114.166.113.24.in-addr.arpa.
+michgreatdane.com.
+74.141.162.192.in-addr.arpa.
+a.root-servers.net.
+www.adobe.com.
+63.246.247.190.in-addr.arpa.
+www.badanaclinic.com.
+132.6.199.190.in-addr.arpa.
+soymarketing.org.
+148.76.136.190.in-addr.arpa.
+www.fyoryi.com.
+amr.wuu.ru.
+mx1.nom-domaine.fr.
+10-razones-para-odiarte.seriespepito.com.
+www.sweetim.com.
+38.108.24.81.in-addr.arpa.
+5jekjdrb6.93gd.
+www.google.com.
+pespn.chartbeat.net.
+ameritimemortgage.com.
+extraodelirio.blogspot.com.
+a3.da1.akamai.net.
+138.122.191.202.in-addr.arpa.
+hotmail.com.
+api.twitter.com.
+www.mariangaspi.blogspot.com.
+200.240.135.189.in-addr.arpa.
+pmhd.org.
+add1-new.dir.vip.sp2.yahoo.com.
+lalunamedia.com.
+213.224.19.187.in-addr.arpa.
+teredo.ipv6.microsoft.com.
+newsletter.yves-rocher.ru.
+162.23.204.190.in-addr.arpa.
+bbcc.com.relay1b.spamh.com.
+static.ulule.me.
+dns.msftncsi.com.
+medintelsolutions.com.inbound10.mxlogicmx.net.
+www.edwardandbella.net.
+236.169.205.190.in-addr.arpa.
+a.root-servers.net.
+www.generation5.org.
+csi.gstatic.com.
+cruisermotorcycles.co.uk.
+osce105.icrc.trendmicro.com.
+creative.ak.fbcdn.net.
+bbvabancoprovincial.blogspot.com.
+aaersystems.com.
+34.3.79.190.in-addr.arpa.
+a4.sphotos.ak.fbcdn.net.
+10.rarbg.com.
+google.com.
+funnysize.com.
+www.jurnii.com.
+www.wtfeed.com.
+fr-fr.facebook.com.
+mail.google.com.
+b.scorecardresearch.com.
+www4.pictures.zimbio.com.
+wpad.og.ge.com.
+pagead2.googlesyndication.com.
+content.yieldmanager.edgesuite.net.
+.
+qnu3yg7nl.l92v6p3x.
+voipb.sip.yahoo.com.
+cs10784.userapi.com.
+214.167.173.189.in-addr.arpa.
+31.199.116.194.in-addr.arpa.
+ads.us.e-planning.net.
+proshowlab.com.
+219.92.250.201.in-addr.arpa.
+11-courier.push.apple.com.
+a1623.phobos.apple.com.
+www.facebook.com.
+91.145.60.189.in-addr.arpa.
+gdbsa.com.
+cdn.api.twitter.com.
+_215_30_3.
+www.topflite.com.
+11.168.188.204.in-addr.arpa.
+blst.msn.com.
+jokerwebhosting.com.
+rvlzdqx8.emltrk.com.
+11111111.com.
+49.114.182.186.in-addr.arpa.
+spynet2.microsoft.com.
+a8.sphotos.ak.fbcdn.net.
+137.221.22.187.in-addr.arpa.
+img1.imagehyper.com.
+i16.servimg.com.
+hdwall.org.
+photos-g.ak.fbcdn.net.
+www.luckydrunks.com.
+pixel.facebook.com.
+alphratz.org.
+183.154.178.186.in-addr.arpa.
+dns.msftncsi.com.
+winclufzd.r49r4o9p.
+csi.gstatic.com.
+safebrowsing-cache.google.com.
+movies.getfreefiles.com.
+s167.videobb.com.
+.
+b._dns-sd._udp.lan.
+i381.odnoklassniki.ru.
+pixel.facebook.com.
+counter.yadro.ru.
+www.ogov.eu.
+106.72.203.190.in-addr.arpa.
+0.3696778.com.
+www.moblesvano.com.
+image2.pubmatic.com.
+uysb2jhh6.c09e9g7t.
+api.twitter.com.
+ow.ly.
+tkc-ostrova.ru.
+a.root-servers.net.
+images.wikia.com.
+a.root-servers.net.
+171.183.112.204.in-addr.arpa.
+www.facebook.com.
+rs70tl5.rapidshare.com.
+www.dsi.uniroma1.it.
+teredo.ipv6.microsoft.com.
+www.derbydiva.com.
+a575.b.akamai.net.
+kenta.ru.
+checkip.dyndns.org.
+praxisdesigners.com.
+rss.elmundo.es.
+singnet.com.sg.
+a2.mzstatic.com.
+dl.secunia.com.
+48.149.220.66.in-addr.arpa.
+mail.legalaid.qld.gov.au.
+girardwinery.com.mx2.mspportal.rcimx.net.
+a.root-servers.net.
+a.root-servers.net.
+b._dns-sd._udp.lan.
+helicongroup.com.
+a1.sphotos.ak.fbcdn.net.
+perdiendomiejem.blogspot.com.
+i.ytimg.com.
+jtrucks.com.
+platform.twitter.com.
+galleries.analhookers.com.
+i3.ytimg.com.
+mail.brmarketinggroup.com.
+invotexgroup.com.s6b2.psmtp.com.
+ocsp.thawte.com.
+132.162.208.201.in-addr.arpa.
+6.95.186.189.in-addr.arpa.
+ti2.auctiva.com.
+1.bp.blogspot.com.
+hirm.fr.
+www.fashionablynumb.com.
+www.cricbuzz.com.
+a.root-servers.net.
+m.city.zynga.com.
+a.root-servers.net.
+_965_56_7.
+js.admeld.com.
+a6.sphotos.ak.fbcdn.net.
+86.150.133.187.in-addr.arpa.
+ct.buzzfeed.com.
+zgn.static.zynga.com.
+193.120.33.83.in-addr.arpa.
+s.ytimg.com.
+age-of-empires-online.browsergamez.com.
+o-o.preferred.dfw06s10.v20.lscache8.c.youtube.com.
+www.andopobre.tv.
+a.root-servers.net.
+dns.msftncsi.com.
+blue29.com.
+newlightrealty-com.mail.eo.outlook.com.
+promel.biz.
+accounts.google.com.
+andreapatchwork.blogspot.com.
+www.nibco.com.
+photos-b.ak.fbcdn.net.
+1-213.channel.facebook.com.
+photos-d.ak.fbcdn.net.
+trendynewhairstyles.blogspot.com.
+210.21.175.78.in-addr.arpa.
+www.obsexxed.com.
+154.54.230.190.in-addr.arpa.
+clients.njoyn.com.
+www.olegvolk.net.
+maharaja-ki-raaz.blogspot.com.
+183.121.159.187.in-addr.arpa.
+www.google-analytics.com.
+r._dns-sd._udp.lan.
+papeplating.com.
+b.scorecardresearch.com.
+dennisbarnfield.co.uk.
+crl.microsoft.com.
+apps.facebook.com.
+134.199.121.109.in-addr.arpa.
+profile.ak.fbcdn.net.
+66.152.209.201.in-addr.arpa.
+teredo.ipv6.microsoft.com.
+in.gotradio.sc.abacast.com.
+artabase.net.
+static.doubleclick.net.
+0.190.157.186.in-addr.arpa.
+17.76.102.109.in-addr.arpa.
+mail.google.com.
+wpad.
+abc123.ru.
+google.com.
+afilm.ru.
+abbottlabspharmaceuticals.com.
+milou-veronica.faithinpoison.com.
+32.49.58.90.in-addr.arpa.
+www.betroffen.at.
+24.147.73.46.in-addr.arpa.
+crl.comodoca.com.
+ib.adnxs.com.
+gcgvrg.com.
+redesdesolidaridad.files.wordpress.com.
+143.221.90.186.in-addr.arpa.
+justinbiebertube.net.
+berryautos.com.
+mail.circlecityvets.com.
+uaemail.com.
+ap.lijit.com.
+www.dunksbnikeheels.com.
+ajax.googleapis.com.
+83.170.181.189.in-addr.arpa.
+xr126envq.k36s6g2n.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+139.99.125.76.in-addr.arpa.
+bitly.com.
+www.virtusmedia.com.br.
+stats.buysellads.com.
+news.google.com.mx.
+a.root-servers.net.
+9sn91n:hs.v17p8q4h.
+www.bywifi.com.
+racheldangerw.files.wordpress.com.
+developers.facebook.com.
+press.dailymotion.com.
+88.68.224.41.in-addr.arpa.
+inbound.rfaxis.com.netsolmail.net.
+photos-h.ak.fbcdn.net.
+.
+www.google.com.
+db._dns-sd._udp.lan.
+hr.mt.com.
+i5.tagstat.com.
+a.root-servers.net.
+tgti.net.
+a.root-servers.net.
+profile.ak.fbcdn.net.
+galeria.infojardin.com.
+devil76134.no-ip.org.
+pbid.iforex.com.
+a1769.phobos.apple.com.
+5.48.105.112.in-addr.arpa.
+rinco.su.
+packages.linuxmint.com.
+www.google.com.
+www.ant.com.
+royalmed.ru.
+www.google-analytics.com.
+www.things-to-do-barcelona.com.
+iwhome.com.
+mx.bwcutting.com.cust.b.hostedemail.com.
+shremont.ru.
+id.google.com.mx.
+1k8f5s8nv.46na.
+www.neogl.com.
+www.bajanreporter.com.
+acapellas4u.co.uk.
+works.tarefer.ru.
+i4.ytimg.com.
+mtalk.google.com.
+19.95.229.66.in-addr.arpa.
+www.gantuk.com.
+www.facebook.com.
+3-courier.push.apple.com.
+nwinsure.com.mx1.wooden-spoon.rcimx.net.
+pixel.facebook.com.
+api-public.addthis.com.
+partner.googleadservices.com.
+lucia-rg.blogspot.com.
+a.root-servers.net.
+159.63.226.213.in-addr.arpa.
+249.11.152.189.in-addr.arpa.
+tennis.bnpparibas.com.
+malpais.cancioneros.com.
+meta.wikimedia.org.
+mind-caster.com.
+a1886.g.akamai.net.
+byfiles.storage.msn.com.
+ad.yieldads.com.
+15.149.11.187.in-addr.arpa.
+134.158.65.190.in-addr.arpa.
+tucson-club.ru.
+206.45.168.192.in-addr.arpa.
+57.203.232.24.in-addr.arpa.
+bay.messenger.services.live.com.
+www.beckys-dungeon.com.
+neowa.ru.
+counter.yadro.ru.
+www.aol.com.
+jlsautomation.com.inbound15.mxlogic.net.
+www.sport.es.
+sergei-fil.j-net.ru.
+external.mediaworks.co.nz.
+i4.ytimg.com.
+185.189.179.190.in-addr.arpa.
+155.187.68.189.in-addr.arpa.
+t0.tagstat.com.
+mablaw.co.uk.
+emilyhaledesign.com.
+static0.thaitable.com.
+a6.sphotos.ak.fbcdn.net.
+en-us.fxfeeds.mozilla.com.
+s-static.ak.facebook.com.
+us1.badoo.com.
+rcp.na.blackberry.com.
+img.tradedoubler.com.
+tdkom.com.br.
+www.google-analytics.com.
+zgn.static.zynga.com.
+js.wlxrs.com.
+kindleheating.com.
+m.ak.fbcdn.net.
+rss.elmundo.es.
+mail2.ecdservices.com.
+i.w55c.net.
+143.118.203.71.in-addr.arpa.
+www.suma.org.ar.
+b.fenixblau.com.
+mail.neomorganics.com.
+www.facebook.com.
+www.needforspeed.com.
+juanpoeta.blogspot.com.
+www.ilep.org.uk.
+i1.ytimg.com.
+www.bywifi.com.
+static1.iphoneros.net.
+www.gtasa.jp.
+mx.cockrell-hill.tx.us.
+www.1f1f.net.
+muchoestilo.regalosi.com.
+iphone.audiofanzine.com.
+docs.google.com.
+140.68.103.189.in-addr.arpa.
+sswww.hotels.com.
+chefmail.de.
+64.137.151.46.in-addr.arpa.
+mastraveller.com.
+storage.conduit.com.
+photos-a.ak.fbcdn.net.
+104.18.188.186.in-addr.arpa.
+www.stocking-maniacs.com.
+thepiratebay.org.
+blog.sulcisiglesiente.eu.
+28.81.125.186.in-addr.arpa.
+photos-a.ak.fbcdn.net.
+239.178.195.190.in-addr.arpa.
+a.root-servers.net.
+indymedia.org.uk.
+especiales.latam.msn.com.
+dnl-09.geo.kaspersky.com.
+www.professorshouse.com.
+sp.internet.com.
+a6.sphotos.ak.fbcdn.net.
+static.ak.fbcdn.net.
+_999_68_0.
+photos.blogger.com.
+107.242.192.77.in-addr.arpa.
+www.facebook.com.
+ad.z5x.net.
+graph.facebook.com.
+symphonysoldiersuk.tumblr.com.
+rightkindofphrase.yuku.com.
+previnet.it.
+download116.avast.com.
+www.infoallen.com.ar.
+191.18.195.187.in-addr.arpa.
+photos-d.ak.fbcdn.net.
+mail.google.com.
+krasdalefoods.com.
+desarrollogerencial.wordpress.com.
+tshore-com.relay1a.spamh.com.
+a.root-servers.net.
+129.253.47.188.in-addr.arpa.
+csi.gstatic.com.
+cti.w55c.net.
+www.mediafire.com.
+219.173.67.201.in-addr.arpa.
+www.yamntther.com.
+221.cim.meebo.com.
+secserv.adtech.de.
+kdc.uas.aol.com.
+104.0.194.98.in-addr.arpa.
+es-la.facebook.com.
+citytours.sg.
+a.root-servers.net.
+thatsmeandthecity.blogspot.com.
+201.227.200.112.in-addr.arpa.
+gs-loc.apple.com.
+apps.facebook.com.
+6.26.141.201.in-addr.arpa.
+literatehousewife.com.
+89.196.103.201.in-addr.arpa.
+susanguerin.com.
+www.goojue.com.
+www.yaracuy.gob.ve.
+ocsp.digicert.com.
+armmf.adobe.com.
+z020.fma.fb.me.
+www.facebook.com.
+photos-f.ak.fbcdn.net.
+photos-a.ak.fbcdn.net.
+jfh51l6gc.99ew.
+colonialfarmcredit.com.mail4.psmtp.com.
+www.3tv.cl.
+profile.ak.fbcdn.net.
+graph.facebook.com.
+content.yepigames.net.
+carabobo.mundoanuncio.co.ve.
+85.83.149.98.in-addr.arpa.
+retroxpuntones.blogspot.com.
+freesite.com.
+www.youtube-nocookie.com.
+rivahistorical.org.
+a3.sphotos.ak.fbcdn.net.
+7o:hlcx1y.64bh.
+rcp.na.blackberry.com.
+e3191.c.akamaiedge.net.
+photos-b.ak.fbcdn.net.
+fbcdn-profile-a.akamaihd.net.
+2.129.37.10.in-addr.arpa.
+dns.msftncsi.com.
+www.pravoslavie.ru.
+166.35.47.201.in-addr.arpa.
+blog.alvarols.com.
+static.apk.hiapk.com.
+ts4.mm.bing.net.
+ad.z5x.net.
+a3.sphotos.ak.fbcdn.net.
+twitter.com.
+time.chttl.com.tw.
+www.google.com.
+www.facebook.com.
+fbcdn-profile-a.akamaihd.net.
+www.maccaferri.com.
+49.149.135.190.in-addr.arpa.
+seg.sharethis.com.
+150.111.55.65.list.dsbl.org.
+static.ak.fbcdn.net.
+www.indigomedia.com.
+46.107.36.114.in-addr.arpa.
+sp.cwfservice.net.
+platform.ak.fbcdn.net.
+29.179.138.189.in-addr.arpa.
+ipdns1.hinet.net.
+b._dns-sd._udp.0.1.168.192.in-addr.arpa.
+97.72.143.201.in-addr.arpa.
+gfpa.ch.
+194.82.138.121.in-addr.arpa.
+babyfaithhope.blogspot.com.
+www.karmakerala.com.
+et1.xhamster.com.
+cantinelizzano.it.
+th.cam4.com.
+www.informador.com.mx.
+126.225.11.201.in-addr.arpa.
+34.85.51.190.in-addr.arpa.
+anycast.perf.glbdns.microsoft.com.
+ldayzv.com.
+telusplanet.net.
+ced.sascdn.com.
+pt.lagsoft.biz.
+itunes.apple.com.
+ksn5-12.kaspersky-labs.com.
+google.com.
+a.root-servers.net.
+excelir.com.
+sacu.com.
+www.holdenwiki.net.
+223.61.24.201.in-addr.arpa.
+ecn.dev.virtualearth.net.
+circleofcrafters.com.
+zcache.zgncdn.com.
+a.static-cdn.playfish.com.
+a.root-servers.net.
+cmnefktt.cc.lan.
+www.blabbers.com.
+sherpa-auto.ru.
+pamsa.com.
+237.222.105.186.in-addr.arpa.
+taggalicio.us.
+myaccount.k12.com.
+get.adobe.com.
+www.playblog.ws.
+support.google.com.
+109.213.184.78.in-addr.arpa.
+250.92.46.186.in-addr.arpa.
+www.hotlinkbanners.com.
+188.227.104.189.in-addr.arpa.
+125.108.142.98.in-addr.arpa.
+soldmedal.com.
+mob800.photobucket.com.
+49.208.140.79.in-addr.arpa.
+www.friendlyduck.com.
+cdn1.video.poshgay.com.
+a.root-servers.net.
+l.yimg.com.
+contatransparente.pt.
+blog.spafinder.com.
+weather.wapp.wii.com.
+www.motionempire.com.
+lovepoems.blog13.net.
+h.live.com.
+rad.msn.com.
+www.nytimes.com.
+developers.facebook.com.
+a5.sphotos.ak.fbcdn.net.
+newsrss.bbc.co.uk.
+www.unicharm.co.jp.
+api.twitter.com.
+mail.vag.ru.
+xerocost.com.
+ns1.dvrtw.com.tw.
+smtp4.hamilton.net.
+affiliates.lelo.com.
+www.google.com.
+www.googletagservices.com.
+www.radiomuseum-bocket.de.
+www.ncjapan.co.jp.
+partner.googleadservices.com.
+cl.m.globedia.com.
+www.google-analytics.com.
+coroiepvina.blogspot.com.
+marialopez-orientacion.blogspot.com.
+www.asone.org.
+disqus.com.
+www.google.com.
+a4.sphotos.ak.fbcdn.net.
+arreclau.blogspot.com.
+images.channeladvisor.com.edgesuite.net.
+cronicas-urbanas.blogspot.com.
+mw.50cubes.com.
+i.ebayimg.com.
+barracuda.reliancemerchantservices.com.
+131.56.101.94.in-addr.arpa.
+pictures3.ebuddy.com.
+www.allmusic.com.au.
+peliculas-flv.com.
+est.msn.com.
+fashiontribe.net.
+_909_28_7.
+dparikh.com.
+gracobaby.com.
+243.212.172.190.in-addr.arpa.
+socium.info.
+photos-f.ak.fbcdn.net.
+73.20.136.78.in-addr.arpa.
+profile.ak.fbcdn.net.
+secure.shared.live.com.
+i1.ytimg.com.
+www.reliabilityweb.com.
+131.207.220.74.in-addr.arpa.
+169.71.142.189.in-addr.arpa.
+safebrowsing.clients.google.com.
+s.youtube.com.
+i38.tinypic.com.
+9x8wza:f8.u72s4u8p.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+inbound.peraragroup.com.netsolmail.net.
+a.root-servers.net.
+de-de.facebook.com.
+safebrowsing-cache.google.com.
+grapecreekisd.net.
+217.218.5.187.in-addr.arpa.
+b._dns-sd._udp.0.1.168.192.in-addr.arpa.
+a8.sphotos.ak.fbcdn.net.
+22.140.126.178.in-addr.arpa.
+static.2yourface.com.
+l.yimg.com.
+www.google-analytics.com.
+dualstack.ipv6-exp.l.google.com.
+www.objetivofamosos.com.
+v2.cache2.c.youtube.com.
+cachedcommons.org.
+skort.nnov.ru.
+annami43.gogvo.com.
+sp.cwfservice.net.
+www.mojoportal.com.
+a.root-servers.net.
+devices.live.com.
+adulteration.com.
+155.63.135.88.in-addr.arpa.
+www.pc-spielekostenlos.com.
+www.queennarriman.com.
+www.cdn.sherdog.com.
+www.facebook.com.
+api-read.facebook.com.
+www.conduit.com.
+sh.deviantart.net.
+hi-in.facebook.com.
+d.turn.com.
+images.synacor.com.
+apex.com.com.
+milcomhq.com.
+_ldap._tcp.ustc._sites.gc._msdcs.kcc.com.
+newtt.com.
+vpncasestudy.com.
+gfx3.hotmail.com.
+yui.yahooapis.com.
+cjs.cadmus.com.
+www.npcgo.com.
+www.gstatic.com.
+googleads.g.doubleclick.net.
+15.226.13.190.in-addr.arpa.
+time.nist.gov.
+27.147.220.66.in-addr.arpa.
+rad.msn.com.
+a.root-servers.net.
+js2.wlxrs.com.
+d2088610.xoom.it.
+www.anth.ucsb.edu.
+a1108.da1.akamai.net.
+upload.al-wed.com.
+sn145ds.mail.services.live.com.
+34.239.75.190.in-addr.arpa.
+sb.scorecardresearch.com.
+wpad.
+www.mytreedb.com.
+fa:2rgnd6.g99d9r7c.
+m.facebook.com.
+messenger.hotmail.com.
+88.235.159.10.dynamic.ttnet.com.tr.
+a7.sphotos.ak.fbcdn.net.
+8.5.6.189.in-addr.arpa.
+ipolone.com.
+d1se315fw1201h.cloudfront.net.
+www.greendayvideos.com.
+teredo.ipv6.microsoft.com.
+wickedfire.com.
+frankconsulting.com.
+1.0.0.127.dnsbugtest.1.0.0.127.in-addr.arpa.
+bright.com.
+a1505.l.akamai.net.
+134.188.223.203.in-addr.arpa.
+www.ercrugby.com.
+hvgo.blogspot.com.
+go.srvnow.com.
+a.root-servers.net.
+214.203.9.190.in-addr.arpa.
+japc.demon.co.uk.
+p07-caldav.icloud.com.
+a.root-servers.net.
+www.gobiernodecanarias.org.
+i4.ytimg.com.
+ocsp.entrust.net.
+netsense.net.
+segments.adap.tv.
+clients1.google.com.
+photos-b.ak.fbcdn.net.
+time.stdtime.gov.tw.
+guessing-game.friv4.info.
+db._dns-sd._udp.0.1.168.192.in-addr.arpa.
+123.185.120.174.in-addr.arpa.
+y9pwdp6kw.u86k6q0b.
+208.105.145.187.in-addr.arpa.
+photos-a.ak.fbcdn.net.
+96.200.168.1.in-addr.arpa.
+lapassucci.blogspot.com.
+1.bp.blogspot.com.
+www.facebook.com.
+circleoflifelabs.com.
+syndication.intel.com.
+www.vtsup.com.
+login.live.com.
+pixel.indieclick.com.
+ecards.emilatintools.com.
+www.360minutos.com.
+jodase19.tumblr.com.
+tnvalleyins.com.
+thetrucker.com.
+api.twitter.com.
+apps.facebook.com.
+tum.mvd.ru.
+www.google-analytics.com.
+www.melbournehandyman.com.au.
+inmo-balear.com.
+pics.ebaystatic.com.
+www.facebook.com.
+trac.torproject.org.
+sparling.com.
+fbcdn-profile-a.akamaihd.net.
+www.thef1.com.
+crmifetel.ife.org.mx.
+a.root-servers.net.
+photos-b.ak.fbcdn.net.
+mail.connico.com.
+_134_81_8.
+www.je.
+creative.ak.fbcdn.net.
+.
+swiss-style.ru.
+static.ak.fbcdn.net.
+197.143.172.187.in-addr.arpa.
+pega.jorge.over-blog.es.
+static.ak.fbcdn.net.
+163.62.92.186.in-addr.arpa.
+www.airtel.net.
+157.100.205.87.in-addr.arpa.
+static.ak.fbcdn.net.
+ad-g.doubleclick.net.
+vcs1.msg.yahoo.com.
+www.controlatugastritis.com.mx.
+www.675bar.com.
+t2.gstatic.com.
+mailsiesta.dynalias.org.
+gratka.pl.
+res.media.net.
+a.imageshack.us.
+www.laps3.com.
+crl.microsoft.com.
+www.aspire-cs.com.
+au.download.windowsupdate.com.
+www.sabayacafe.com.
+26.media.tumblr.com.
+m45rft6a6.r20x4o5f.
+photos-c.ak.fbcdn.net.
+ads.tlvmedia.com.
+78.16.229.190.in-addr.arpa.
+bs.serving-sys.com.
+pt-br.facebook.com.
+labutacadelcinefilo.files.wordpress.com.
+86.218.171.187.in-addr.arpa.
+api-public.addthis.com.
+a.root-servers.net.
+d3lvr7yuk4uaui.cloudfront.net.
+pixel.facebook.com.
+mail.kis.ru.
+www.mediafire.com.
+travelport.com.
+b._dns-sd._udp.0.129.37.10.in-addr.arpa.
+20.208.208.201.in-addr.arpa.
+profile.ak.fbcdn.net.
+s-static.ak.fbcdn.net.
+160.112.61.186.in-addr.arpa.
+43.15.57.186.in-addr.arpa.
+giantmag.disqus.com.
+apple-mobile.query.yahooapis.com.
+c0014129.ssl.cf1.rackcdn.com.
+wcskids.net.
+edtechtalk.com.
+download670.avast.com.home.
+a5.sphotos.ak.fbcdn.net.
+i4.ytimg.com.
+js.imonografias.com.
+fcico.com.
+searchclient.live.net.
+cdn.advertserve.com.
+www.update.microsoft.com.
+188.253.163.71.in-addr.arpa.
+c2.softonicads.com.
+www.usefulcharts.com.
+mail.agr.state.nc.us.
+creative.ak.fbcdn.net.
+theseges.com.
+www.google.com.
+170.59.155.189.in-addr.arpa.
+162.197.124.189.in-addr.arpa.
+226.3.115.79.in-addr.arpa.
+dns.msftncsi.com.
+www.makemoneyandomainparking.info.
+www.aba.org.au.
+google.com.
+img29.elex-tech.org.
+mail.efonalledas.com.
+itunes.apple.com.
+ucentral.edu.co.
+profile.ak.fbcdn.net.
+www.download.windowsupdate.com.
+api-read.facebook.com.
+13.137.89.98.in-addr.arpa.
+agencias.ua.com.ar.
+dc466.4shared.com.
+179.156.92.186.in-addr.arpa.
+www.energycodes.gov.
+233.32.197.87.in-addr.arpa.
+a.root-servers.net.
+_752_77_8.
+www.metodocallan.net.
+mail.cri.org.uk.
+api.facebook.com.
+www.google.com.
+www.msftncsi.com.
+lb._dns-sd._udp.0.55.211.10.in-addr.arpa.
+p04-keyvalueservice.icloud.com.
+accounts.google.com.
+thumbs2.ebaystatic.com.
+97.140.172.190.in-addr.arpa.
+www.facebook.com.
+www.google.com.
+judaismohoy.com.
+dns.msftncsi.com.
+espanol.weather.com.
+49.149.220.66.in-addr.arpa.
+sprentpcs.com.
+photos-b.ak.fbcdn.net.
+geo.messenger.services.live.com.
+files.fatakat.com.
+wildcard.whitehouse.gov.edgekey.net.
+a.root-servers.net.
+231.3.39.184.in-addr.arpa.
+137.38.55.187.in-addr.arpa.
+sgpqv8gj3.91za.
+2.129.37.10.in-addr.arpa.
+208.103.206.190.in-addr.arpa.
+ccp.ucr.ac.cr.
+us.lrd.yahoo.com.
+202.184.1.88.in-addr.arpa.
+www.dpreview.com.
+www.targetingnow.com.
+www.damnfunnypictures.com.
+i4.ytimg.com.
+vkontakte.ru.
+clients2.google.com.
+www.facebook.com.
+hhi.fraunhofer.de.
+43.186.152.190.in-addr.arpa.
+aol.com.
+js.adsonar.com.
+photos-b.ak.fbcdn.net.
+kinshasa.usembassy.gov.
+mail-attachment.googleusercontent.com.
+photos-a.ak.fbcdn.net.
+mail.holmen.k12.wi.us.
+40.139.24.177.in-addr.arpa.
+159.201.157.186.in-addr.arpa.
+mx.mfua.ru.
+www.youtube.com.
+limao.com.
+littleceasars.com.
+21.25.19.186.in-addr.arpa.
+lb._dns-sd._udp.0.0.168.192.in-addr.arpa.
+leetufrase.com.
+blogs.lavanguardia.es.
+pagead2.googlesyndication.com.
+i0.tagstat.com.
+129.5.78.186.in-addr.arpa.
+entretenimiento.prodigy.msn.com.
+mail.google.com.
+tags.bluekai.com.
+237.112.169.189.in-addr.arpa.
+s7.addthis.com.
+wu.apple.com.
+71.153.177.190.in-addr.arpa.
+worldcat.org.
+liveupdate.symantecliveupdate.com.
+kepler.vis.com.pe.
+www.es.vectoropenstock.com.
+cdnp1.quepasa.com.
+zh-cn.facebook.com.
+mail.vedenina.ru.
+api.midomi.com.
+bsf.smowtion.com.
+51.119.174.189.in-addr.arpa.
+api.chartbeat.com.
+54.81.220.189.in-addr.arpa.
+64.166.251.78.in-addr.arpa.
+twitter-widgets.s3.amazonaws.com.
+a-0.19-21090001.c010083.1518.19d4.3ea1.410.0.fkm9uk1mzlibf2ekqil21fqqdv.avqs.mcafee.com.
+www.liu.edu.lb.
+89.163.1.201.in-addr.arpa.
+:n3d3ucx4.n23l8n3d.
+hou.jumpskyhigh.com.
+112.23.32.99.in-addr.arpa.
+www.cubeforums.com.
+www.emici.net.
+www.g66.co.uk.
+dricompanies.com.
+s.youtube.com.
+5.164.209.61.in-addr.arpa.
+relay.platform.co.uk.
+yahoo.com.
+mail.caryfire.com.
+243.157.104.189.in-addr.arpa.
+www.lascaderasspain.com.
+profile.ak.fbcdn.net.
+external.ak.fbcdn.net.
+www.facebook.com.
+apps.facebook.com.
+citylin.ru.
+dnl-17.geo.kaspersky.com.
+clients2.google.com.
+s4.histats.com.
+groupeibidaa.com.inbound15.mxlogic.net.
+smtp.
+download810.avast.com.
+www.prtool.info.
+euro.mediotiempo.com.
+go.trafficshop.com.
+85.35.61.186.in-addr.arpa.
+49.50.250.189.in-addr.arpa.
+pixel-mixer.ru.
+www.glennsacks.com.
+mus.ch.
+18.2.168.192.in-addr.arpa.
+www.4shared.com.
+www.kreditrechner.be.
+www.davinci-barcelona.com.
+bay.messenger.services.live.com.
+shatteringdenial.com.
+hardee.k12.fl.us.
+circuitpeople.com.
+ads.bluelithium.com.
+hi-in.facebook.com.
+www.androidgames.com.
+cciorg.com.
+emotionsandfeelings.com.
+finance.fy6.b.yahoo.com.
+scholar.google.es.
+www.facebook.com.
+www.gstatic.com.
+alittlefoolish.tumblr.com.
+52.245.120.77.in-addr.arpa.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+bar.pianomedia.eu.
+www.google.com.
+ww137.video7live.com.
+a.root-servers.net.
+onlysomewhatqueer.blogspot.com.
+ssl.gstatic.com.
+dns.msftncsi.com.
+ebm.cheetahmail.com.
+15.127.220.201.in-addr.arpa.
+a.root-servers.net.
+apps.facebook.com.
+federated-states-of-micronesia.evisos.com.
+www.youtube.com.
+21.30.4.31.in-addr.arpa.
+secure.shared.live.com.
+foroherramientavirtual.blogspot.com.
+rcp.eu.blackberry.com.
+i3.ytimg.com.
+ctstatic.dealply.com.
+214.118.20.187.in-addr.arpa.
+urs.microsoft.com.
+textual.net.
+a7.sphotos.ak.fbcdn.net.
+safebrowsing-cache.google.com.
+picasaweb.google.com.
+1.0.0.127.dnsbugtest.1.0.0.127.in-addr.arpa.
+albertcorp.com.
+descargar.mp3.es.
+241.143.117.200.in-addr.arpa.
+news.google.com.ar.
+t.ymlp204.net.
+mail.cyscosoft.com.
+isapi60.weatherbug.com.
+153.42.36.114.in-addr.arpa.
+207.100.134.174.in-addr.arpa.
+plusone.google.com.
+a3.sphotos.ak.fbcdn.net.
+142.223.54.189.in-addr.arpa.
+amarporamor.blogspot.com.
+www.nuriavilanova.com.
+a.root-servers.net.
+www.gdanskseguros.com.ar.
+verbosenfrances.com.
+groups.google.com.mx.
+145.208.247.92.in-addr.arpa.
+stats-incoming.reciva.com.
+a-0.19-23095000.c090083.1518.19d4.3ea1.410.0.4er73s9p55296jrntlrqiff28i.avqs.mcafee.com.
+mail2.quiktron.com.
+cadizmini.myminicity.es.
+www.pictureshack.us.
+photos-c.ak.fbcdn.net.
+t0.gstatic.com.
+ads.iforex.com.
+cutepuppiespictures.files.wordpress.com.
+tvj.ru.
+219.136.222.201.in-addr.arpa.
+245.200.229.190.in-addr.arpa.
+api.twitter.com.
+www.stupidexe.com.
+www.adobe.com.
+139.132.129.186.in-addr.arpa.
+a.root-servers.net.
+79.234.224.190.in-addr.arpa.
+www.conduit.com.
+grix:7pus.q47h6k9y.
+126.252.20.174.in-addr.arpa.
+go.microsoft.com.
+3.136.158.85.in-addr.arpa.
+js2.wlxrs.com.
+166.94.11.201.in-addr.arpa.
+123.247.20.71.in-addr.arpa.
+home.mcafee.com.
+msn.com.
+www.public-trust.com.
+mirrors.liquidweb.com.
+www.soundcloud.com.
+www.urbandictionary.com.
+platform.ak.fbcdn.net.
+www.eurospares.co.uk.
+mail.kahndesign.com.
+google.com.
+mail.unistroy.ru.
+www.lugardeorigen.net.
+piojodelibro.blogspot.com.
+maps.google.es.
+a.root-servers.net.
+srx.main.ebayrtm.com.
+f.hwa.me.
+plus.google.com.
+sandbridgehouses.com.
+i2.ytimg.com.
+primerosauxilios.8k.com.
+b._dns-sd._udp.0.1.168.192.in-addr.arpa.
+archive.slickdeals.net.
+a.root-servers.net.
+254.120.198.71.in-addr.arpa.
+246.77.137.24.in-addr.arpa.
+clk.atdmt.com.
+api.geo.kontagent.net.
+mx.youtube.com.
+vgh-gmbh.ru.
+www.lolochofun.blogspot.com.
+vso.org.uk.
+muprsp.ru.
+223.240.19.201.in-addr.arpa.
+bd0dc.v.fwmrm.net.
+es.data.toolbar.yahoo.com.
+mx.vistarealtyinc.com.
+mail.
+dental-tribune.com.
+oblfarm.yaroslavl.ru.
+a.root-servers.net.
+www.myrealty.com.
+sg.yimg.com.
+80.244.10.83.in-addr.arpa.
+en-us.start.mozilla.com.
+www.20minutos.es.
+sp.cwfservice.net.
+tienda.abc.es.
+10.207.61.67.in-addr.arpa.
+s.ytimg.com.
+search.conduit.com.
+147.163.174.190.in-addr.arpa.
+franciscoafilado.blogspot.com.
+a.root-servers.net.
+kermit.asvt.ru.
+ssl.facebook.com.
+ksn2-12.kaspersky-labs.com.
+mega.com.ru.
+outmail003.snc7.facebook.com.
+www.youtube.com.
+celebridez.files.wordpress.com.
+ad.yieldmanager.com.
+yweb.com.
+coastin.net.
+soul2soul.co.uk.
+74.204.29.186.in-addr.arpa.
+23.229.180.189.in-addr.arpa.
+joule.qfa.uam.es.
+pop.gmail.com.
+ustravelny.us.
+homelynxloans.com.
+230.88.42.186.in-addr.arpa.
+a2.sphotos.ak.fbcdn.net.
+ac.ebis.ne.jp.
+www.tracker-web-site.com.
+42.84.230.189.in-addr.arpa.
+tc.v5.cache2.c.youtube.com.
+45.93.155.46.in-addr.arpa.
+www.independentwestand.org.
+75.76.36.186.in-addr.arpa.
+183.74.8.83.in-addr.arpa.
+\006.
+167.8.239.201.in-addr.arpa.
+plastek.msk.ru.
+ds.addthis.com.
+mail.rugbymfg.com.
+www.control.com.
+www.facebook.com.
+syndication.traffichaus.com.
+isatap.home.
+r.nexac.com.
+newchapter.com.inbound20.mailprotector.net.
+photos-f.ak.fbcdn.net.
+s1.mindvalley.us.
+www.missy-elliott.com.
+google.com.mx.
+www.facebook.com.
+linda-goodman.com.
+msmedia.ru.
+www.twitter.com.
+superhembras.blogspot.com.
+profile.ak.fbcdn.net.
+www.zynga.com.
+mail.google.com.
+www.bizrate.com.
+quirkcars.com.
+a.root-servers.net.
+signatureloans100.com.
+mx.omg.yahoo.com.
+www.google-analytics.com.
+debelis.net.
+photos-e.ak.fbcdn.net.
+97.1.1.10.in-addr.arpa.
+photos-g.ak.fbcdn.net.
+www.easy-dating.org.
+85.36.95.190.in-addr.arpa.
+creative.ak.fbcdn.net.
+www.google.com.
+www.russian-women-personals.com.
+fbcdn-profile-a.akamaihd.net.
+www.maui.net.
+api.twitter.com.
+a3.twimg.com.
+a.root-servers.net.
+msn.foxsports.com.
+t3.tagstat.com.
+55.118.181.175.in-addr.arpa.
+dailyicon.net.
+static.ak.fbcdn.net.
+r._dns-sd._udp.lan.
+inbound.rwridley.com.netsolmail.net.
+onlinestores.metaservices.microsoft.com.
+137.211.193.186.in-addr.arpa.
+139.248.106.187.in-addr.arpa.
+news.google.com.mx.
+googlehosted.l.googleusercontent.com.
+updateservice.sonic.com.
+profile.ak.fbcdn.net.
+92.36.135.190.in-addr.arpa.
+hash.orbitdownloader.com.
+admin.inventarte.net.
+chip01.chipimages.de.
+img7.ask.fm.
+courtreoprt.com.
+ksn2-12.kaspersky-labs.com.
+lstk.ru.
+orcart.facebook.com.
+a6.sphotos.ak.fbcdn.net.
+safebrowsing.clients.google.com.
+229.31.74.187.in-addr.arpa.
+exodus.desync.com.
+www.shopbrandclothes.com.
+google.com.
+a.root-servers.net.
+.
+oqsauiwk.info.
+static.ak.fbcdn.net.
+touch.www.linkedin.com.
+www.paypal.com.
+gbhcpas.com.pri-mx.na0104.smtproutes.com.
+_798_42_7.
+188.111.191.186.in-addr.arpa.
+detr.state.nv.us.
+140.13.104.200.in-addr.arpa.
+creative.ak.fbcdn.net.
+temptechno.ru.
+mujeres-de-lujo.seriespepito.com.
+warehouse.davematthewsband.com.
+lomanis.believeband.com.
+a4.sphotos.ak.fbcdn.net.
+www.kobakant.at.
+flashembed.xvideos.com.
+230.107.193.187.in-addr.arpa.
+skatechikar.blogspot.com.
+243.214.159.189.in-addr.arpa.
+ad.yieldmanager.com.
+creative.ak.fbcdn.net.
+teredo.ipv6.microsoft.com.
+1.0.0.127.dnsbugtest.1.0.0.127.in-addr.arpa.
+ib.adnxs.com.
+pagead2.googlesyndication.com.
+api.facebook.com.
+digiplotinc.com.
+www.youtube.com.
+mediacdn.disqus.com.
+www.google-analytics.com.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+btdinc.net.
+external.ak.fbcdn.net.
+imap.strato.com.
+151.95.141.201.in-addr.arpa.
+icogblogs.com.
+emailsecurity.eandggroup.com.
+file81.loadup.ru.
+ehot.biz.
+www.assaya.org.
+a.root-servers.net.
+www.youtube.com.
+katerine-fernandez.blogspot.com.
+s.ytimg.com.
+health.chinanews.com.
+www.topfoci.hu.
+michaelpatton.blogspot.com.
+idc091a05.parker.com.
+watson.microsoft.com.
+photos-e.ak.fbcdn.net.
+www2.buenacuerdo.com.ar.
+ocsp.thawte.com.
+mlbplayers.mlb.com.
+71.24.23.190.in-addr.arpa.
+webcache.googleusercontent.com.
+www.facebook.com.
+50.20.38.190.in-addr.arpa.
+www.english-to-go.com.
+ebsrealestate.com.
+underpagrounds.wordpress.com.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+75:6y6ton.44cs.
+a.rad.msn.com.
+rtc.sfsu.edu.
+www.microsoft.com.
+t2.gstatic.com.
+www.blacksbangblondes.com.
+smallmouthinyoursoup.blogspot.com.
+www.youtube.com.
+a1005.w42.akamai.net.
+yule.tom.com.
+ueh.dynamixsoftware.com.
+photos-h.ak.fbcdn.net.
+134.115.204.187.in-addr.arpa.
+ax.init.itunes.apple.com.
+api.twitter.com.
+www.tac.vic.gov.au.
+thecw.com.
+relay.mobilet.ru.
+wafi.com.
+www.update.microsoft.com.
+229.217.223.66.in-addr.arpa.
+231.135.31.88.in-addr.arpa.
+sphotos.ak.fbcdn.net.
+file.funitto.com.
+gate.ece.ucsb.edu.
+www.clubsaorihara.com.
+dns.msftncsi.com.
+www.reggae-blog.net.
+plus.google.com.
+fbcdn-video-a.akamaihd.net.
+www.bs-garden.com.
+240.204.160.187.in-addr.arpa.
+download326.avast.com.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+186.78.132.190.in-addr.arpa.
+www.gravatar.com.
+secure.leadback.advertising.com.
+46.190.3.201.in-addr.arpa.
+sumsung.com.
+microsoft-security-essentials.softonic.com.br.
+a.root-servers.net.
+responsiblemarketing.com.
+s-static.ak.fbcdn.net.
+www.puloinfo.net.
+s-static.ak.fbcdn.net.
+a4.sphotos.ak.fbcdn.net.
+market.ape-apps.com.
+au.download.windowsupdate.com.
+www.eltiempo.com.
+i4.ytimg.com.
+alliance.zap2it.com.
+www.whateats.com.
+www.pimms-pages.co.uk.
+energen.com.mail5.psmtp.com.
+158.30.158.200.in-addr.arpa.
+a6.sphotos.ak.fbcdn.net.
+123.47.184.81.in-addr.arpa.
+c143612.memecenter.com.
+www.facebook.com.
+signum.sivis.org.
+111.119.177.72.in-addr.arpa.
+i1.ytimg.com.
+client-software.real.com.
+api-read.facebook.com.
+a3.sphotos.ak.fbcdn.net.
+114.53.155.187.in-addr.arpa.
+aoujaxpdw.m55v2v4g.
+www.youtube.com.
+www.bigactive.com.
+thehousespa.com.
+129.210.224.190.in-addr.arpa.
+photos-e.ak.fbcdn.net.
+checalo.com.mx.
+enhancedc.co.za.
+ntp1.dlink.com.
+southernhomebuildersllc.com.
+a3.sphotos.ak.fbcdn.net.
+62.158.220.66.in-addr.arpa.
+a.root-servers.net.
+110.14.168.192.in-addr.arpa.
+63.115.111.189.in-addr.arpa.
+www.boi-mela.com.
+www.toyota.com.ar.
+sabores.com.
+www.turpoisk.ru.
+updates.installshield.com.
+www.apple.com.
+smtp.bb.din.or.jp.
+blugro3relay.groove.microsoft.com.
+240.104.126.27.in-addr.arpa.
+crm.digitalchocolate.com.
+livewiremultimedia.com.
+a8.sphotos.ak.fbcdn.net.
+photos-a.ak.fbcdn.net.
+oi9.photobucket.com.
+farmpp.hakunagames.com.
+gfx2.hotmail.com.
+www.ft.com.
+hoetip.tumblr.com.
+proxify.biz.
+www.facebook.com.
+photos-b.ak.fbcdn.net.
+62ddb2yru.46uz.
+thisishorosho.mshome.net.
+ssl.gstatic.com.
+my.id.all.biz.
+birs.ru.
+www.lunarrepublic.com.
+duschy.ru.
+106.35.243.216.in-addr.arpa.
+rsjxdciym.r35t7e7m.
+informcomplex.ru.
+145.162.81.190.in-addr.arpa.
+safebrowsing.clients.google.com.
+papginos.com.
+entertainment.todaysgist.com.
+sharbell.com.
+48.159.192.187.in-addr.arpa.
+fonts.googleapis.com.
+a1.da1.akamai.net.
+www.cntt.vn.
+63.203.181.175.in-addr.arpa.
+jacona.olx.com.mx.
+apps.facebook.com.
+dns.msftncsi.com.
+www.garbarino.com.
+a.root-servers.net.
+col.stj.s-msn.com.
+cn1.redswoosh.akadns.net:443.
+farm3.static.flickr.com.
+premiergrouprealty.com.
+civilwarquilts.blogspot.com.
+ads.tlvmedia.com.
+api.twitter.com.
+safebrowsing.cache.l.google.com.
+connect.facebook.net.
+www.chw.net.
+_422_82_5.
+a2.sphotos.ak.fbcdn.net.
+www.bawazir.com.
+www.goojue.com.
+www.xango.fr.
+mail.ezmail.com.
+cdn.adnxs.com.
+5.19.200.189.in-addr.arpa.
+imap.gmail.com.
+33.3.223.201.in-addr.arpa.
+hi-in.facebook.com.
+pinnacle-game-profiler.programas-gratis.net.
+i3.ytimg.com.
+jers3.info.
+www.google.com.
+cccam.fanhow.com.
+15.43.34.190.in-addr.arpa.
+92.5.157.201.in-addr.arpa.
+chrispiascik.com.
+ads.espn.adsonar.com.
+ueharlax.ac.uk.
+a.root-servers.net.
+www.shamiphotos.com.
+static.ak.fbcdn.net.
+themovieblog.com.woopra-ns.com.
+reddit.com.
+www.coisasfowfaxdolls1.weblogger.com.br.
+www.thedevilsprophet.com.
+photos-a.ak.fbcdn.net.
+ad.adperium.com.
+it-it.facebook.com.
+145.70.26.190.in-addr.arpa.
+196.141.0.82.in-addr.arpa.
+www.distintivoh.com.mx.
+blog.girvin.com.
+profile.ak.fbcdn.net.
+mtlm.com.
+156.46.129.190.in-addr.arpa.
+youtu.be.
+www.google-analytics.com.
+3c9bb231773af1ee4011006baf65584f.info.
+oo7rzs2in.m26p7a2j.
+162.144.111.193.in-addr.arpa.
+www.pdfsearchs.in.
+worker2.live.kng.wooga.com.
+a.root-servers.net.
+mailgate1.centura.org.
+i2.ytimg.com.
+cephey.ru.
+mail.vision-financial.net.
+a.root-servers.net.
+a.root-servers.net.
+cdnis2.cam4.com.
+140.79.149.190.in-addr.arpa.
+173.53.230.190.in-addr.arpa.
+www.5b5.info.
+a.root-servers.net.
+www.msn.com.
+profile.ak.fbcdn.net.
+photos.aaca.org.
+mt2.google.com.
+www.maroc.ma.
+connect.facebook.net.
+simba.region-alsace.fr.
+login.live.com.
+www.jakegarn.com.
+ct.buzzfeed.com.
+153.95.149.187.in-addr.arpa.
+87.198.114.87.in-addr.arpa.
+toolbarqueries.google.com.
+52.101.173.189.in-addr.arpa.
+xbgoficialx.e.channel.livestream.com.
+sabinashidalgo.net.
+weather.wapp.wii.com.
+msc.wlxrs.com.
+ajax.googleapis.com.
+ad.z5x.net.
+www.google.com.
+www.pinturasrodafuerte.com.
+static.ak.fbcdn.net.
+www.facebook.com.
+seastrikeboats.com.
+www.periodicos.capes.gov.br.
+tsm05.eset.com.
+41.235.177.190.in-addr.arpa.
+orangebowl.org.s5b1.psmtp.com.
+www.vivastreet.fr.
+i2.ytimg.com.
+orlandochristianprep.org.
+images04.olx-st.com.
+biomechanic-8001.deviantart.com.
+videoseyredin.blogspot.com.
+124.22.209.201.in-addr.arpa.
+translate.googleapis.com.
+20.127.26.92.in-addr.arpa.
+mc.smtp.gapm.ru.
+psgw.t-mobilesgws.com.
+pross.ru.
+twitter.com.
+s.ytimg.com.
+154.175.100.122.in-addr.arpa.
+54.214.85.209.bl.spamcop.net.
+a1408.w43.akamai.net.
+fbcdn-photos-a.akamaihd.net.
+a7.sphotos.ak.fbcdn.net.
+a8.sphotos.ak.fbcdn.net.
+ixbt.biz.
+creative.ak.fbcdn.net.
+143.132.100.128.in-addr.arpa.
+86.1.101.85.in-addr.arpa.
+255.46.0.10.in-addr.arpa.
+ssl.gstatic.com.
+14.200.172.190.in-addr.arpa.
+65.194.222.186.in-addr.arpa.
+bl121w.blu121.mail.live.com.
+loading5.widdit.com.
+199.114.22.186.in-addr.arpa.
+google.com.
+designcore.net.
+ci.beaverton.or.us.
+_307_76_9.
+cmcst.netmng.com.
+profile.ak.fbcdn.net.
+a.root-servers.net.
+img713.imageshack.us.
+rentalpro.graco.com.
+dohacks.activo.ws.
+www.tuteleonline.com.
+141.61.154.186.in-addr.arpa.
+static.ak.fbcdn.net.
+n6cp.akamai.net.
+webmail.tx.rr.com.
+ns1.dvrtw.com.tw.
+metalmeltdown.forumotion.com.
+kc2xowt8w.91kn.
+buffalohair.wordpress.com.
+usequitymortgage.com.
+profile.ak.fbcdn.net.
+s.youtube.com.
+a1408.w43.akamai.net.
+www.imss.gob.mx.
+inbound.ksoft-us.com.netsolmail.net.
+erc.unesco.org.
+46.236.22.187.in-addr.arpa.
+sovetporemontu.ru.
+teredo.ipv6.microsoft.com.
+pimg.chulojuegos.com.
+photos-a.ak.fbcdn.net.
+a2.sphotos.ak.fbcdn.net.
+www.daisydiskapp.com.
+static.ak.fbcdn.net.
+208.161.75.190.in-addr.arpa.
+119.54.250.189.in-addr.arpa.
+a2.sphotos.ak.fbcdn.net.
+mail.novogen.com.
+169.231.52.186.in-addr.arpa.
+counterb.statcounter.com.
+aim.pubmatic.com.
+ws.pusherapp.com.
+s-external.ak.fbcdn.net.
+www.myfinepix.com.mx.
+www.euroresidentes.com.
+www.fwiluminacionsrl.com.ar.
+_967_39_1.
+a6.sphotos.ak.fbcdn.net.
+theprettypoppy1.blogspot.com.
+jump.eudora.com.
+www.sauerandsteiner.com.
+photos-h.ak.fbcdn.net.
+ad.afy11.net.
+merky.de.
+a7.sphotos.ak.fbcdn.net.
+scootersplanet.com.
+mx.excelsior.ru.
+youtube.com.
+63.38.19.93.in-addr.arpa.
+www.english-heritageshop.org.uk.
+213.110.193.190.in-addr.arpa.
+icy-veins.com.
+static.filestube.com.
+photos-g.ak.fbcdn.net.
+185.147.81.189.in-addr.arpa.
+photos-e.ak.fbcdn.net.
+197.32.153.193.in-addr.arpa.
+_205_47_3.
+g.msn.com.
+readinghospital.org.
+masajes-spa-relax.blogspot.com.
+botones.blogalaxia.com.
+89.247.169.182.in-addr.arpa.
+twitter.com.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+www.lge.com.
+145.227.4.187.in-addr.arpa.
+91.103.172.201.in-addr.arpa.
+sdw.ru.
+www.hookedonads.com.
+40.131.207.190.in-addr.arpa.
+m.addthisedge.com.
+m.yahoo.com.
+www.ujenawholesale.com.
+photos-g.ak.fbcdn.net.
+cameronfarley.com.
+azimut.ru.
+photos-e.ak.fbcdn.net.
+72.10.184.187.in-addr.arpa.
+s.youtube.com.
+137.156.243.201.in-addr.arpa.
+ads.yimg.com.
+a.root-servers.net.
+5l28a:nai.38py.
+www.google-analytics.com.
+www.conduit.com.
+shared.live.com.
+aalweb.net.
+dbcs2.htc.com.
+www.eluniversal.com.mx.
+a.root-servers.net.
+nabillionaire.se.
+www.mangaexpress.net.
+apis.google.com.
+a4.sphotos.ak.fbcdn.net.
+www.citytoo.fr.
+personaltraining.com.
+www.meiosepublicidade.pt.
+warrantiedservices.com.
+static.gunggo.com.
+a4.sphotos.ak.fbcdn.net.
+p.ebaystatic.com.
+www.hangfan.co.uk.
+a3.sphotos.ak.fbcdn.net.
+ask.com.
+www.fa.
+g0.gstatic.com.
+146.48.192.187.in-addr.arpa.
+as.webmd.com.
+safebrowsing.clients.google.com.
+fotosyvideosdehombres.blogspot.com.
+mail.greenville.k12.mi.us.
+mail.rroom.net.
+61.116.191.186.in-addr.arpa.
+dirette.sport.repubblica.it.
+a.root-servers.net.
+xjp.couzens.com.
+pixel.facebook.com.
+grimreaperracing.com.
+cs9872.vk.com.
+registrardominios.com.mx.
+by2msg3020217.gateway.messenger.live.com.
+221.161.6.92.in-addr.arpa.
+hi-in.facebook.com.
+a.root-servers.net.
+feeds2.feedburner.com.
+abricos.com.ru.
+pagead2.googlesyndication.com.
+www.consultorioveterinariolalinea.com.
+www.artesaniaelsol.es.
+ask3.three.co.uk.
+gigamag.ru.
+welcome.hp-ww.com.
+db._dns-sd._udp.0.0.168.192.in-addr.arpa.
+translate.googleapis.com.
+mettlerpr.com.
+s10.histats.com.
+www.yogaartandscience.com.
+p61.badoo.com.
+a2.sphotos.ak.fbcdn.net.
+a1.mzstatic.com.
+time.chttl.com.tw.
+apis.google.com.
+ax.init.itunes.apple.com.
+51.3.254.94.in-addr.arpa.
+ad-g.doubleclick.net.
+ingdirect.com.au.
+mw2.google.com.
+0-jw-w.channel.facebook.com.
+hostgrantor.org.
+followgrame.uservoice.com.
+wbmsepo03.wb.ad.worldbank.org.
+unapzq.net.
+accounts.bioware.com.
+147.71.43.208.in-addr.arpa.
+www.match.com.akadns.net.
+94.220.144.189.in-addr.arpa.
+151.58.46.207.in-addr.arpa.
+valencia.infoisinfo.es.
+dns.msftncsi.com.
+216.224.194.117.in-addr.arpa.
+www.juicycloseups.com.
+appworld.blackberry.com.
+lineup.aclfestival.com.
+a7.sphotos.ak.fbcdn.net.
+photos-b.ak.fbcdn.net.
+_394_89_8.
+www.m-m-monsterhive.net.
+www.photosthatchangedtheworld.com.
+a8.sphotos.ak.fbcdn.net.
+clients2.google.com.
+www.google-analytics.com.
+clients1.google.com.
+img211.imagevenue.com.
+nationalpropertyresearch.com.
+embed.bambuser.com.
+www.pspgo1.com.
+hotmail.com.
+www.ribamatic.com.
+7.170.220.201.in-addr.arpa.
+islamiskaforbundet.se.
+a5.sphotos.ak.fbcdn.net.
+www.sims3cheatsanddownloads.com.
+en-us.fxfeeds.mozilla.com.
+santacruz.patch.com.
+www.google.com.
+static.ak.fbcdn.net.
+sp.cwfservice.net.
+123.112.104.189.in-addr.arpa.
+tc.v1.cache3.c.pack.google.com.
+a.root-servers.net.
+rotativo.com.mx.
+_744_76_8.
+87.148.14.181.in-addr.arpa.
+static.ak.fbcdn.net.
+mx00.ev1.net.
+s-static.ak.fbcdn.net.
+197.220.157.190.in-addr.arpa.
+www.google.com.
+165.33.5.108.in-addr.arpa.
+photos-g.ak.fbcdn.net.
+baymsg1030118.gateway.messenger.live.com.
+c7.zedo.com.
+pagead2.googlesyndication.com.
+125.6.157.201.in-addr.arpa.
+autocosmos.terra.com.ar.
+rya.kfmads.com.
+39.111.237.71.in-addr.arpa.
+snelsonlights.com.
+www.javiergomeznoya.com.
+www.ukrainedate.com.
+safebrowsing.clients.google.com.
+profile.ak.fbcdn.net.
+tracker.v4en.com.
+www.dees.com.
+mtalk.google.com.
+hipstercore.tumblr.com.
+www.annunci.ilfattoquotidiano.it.
+hpvf.com.
+101.64.232.118.in-addr.arpa.
+70.169.60.186.in-addr.arpa.
+a.root-servers.net.
+relay.kw.ua.
+plusone.google.com.
+146.17.194.190.in-addr.arpa.
+www.caixun.com.
+3ivx-mpeg-4.softonic.com.
+chegadebagunca.blogspot.com.
+246.112.11.173.in-addr.arpa.
+ofiodameada.blogspot.com.
+photos-e.ak.fbcdn.net.
+www.gstatic.com.
+www.hu.ikariam.com.
+142.101.230.190.in-addr.arpa.
+api.recaptcha.net.
+a4.mzstatic.com.
+87.178.141.190.in-addr.arpa.
+api.twitter.com.
+a996.mm1.akamai.net.
+static.ak.fbcdn.net.
+newsrss.bbc.co.uk.
+.
+a4.sphotos.ak.fbcdn.net.
+www.addicitivetips.com.
+elsietedias.com.
+www.cakespy.com.
+comtel-vologda.ru.
+www.carolynsandstrom.com.
+www.ameristarcasinos.com.
+sph3re.tv.
+200.77.112.190.in-addr.arpa.
+wpad.genzyme.com.
+a.root-servers.net.
+v5.cache3.c.youtube.com.
+apis.google.com.
+s0.2mdn.net.
+228.93.70.208.in-addr.arpa.
+ur.bestpicturesof.com.
+41.9.133.189.in-addr.arpa.
+developers.facebook.com.
+webmail.midtechnologies.net.
+static.dealply.com.
+api.geo.kontagent.net.
+psych.urbanup.com.
+en.wikipedia.org.
+signup.wazzub.info.
+exmail.sina.com.
+www.onlineweblibrary.com.
+155.26.6.186.in-addr.arpa.
+s-external.ak.fbcdn.net.
+activatunegocio.com.ar.
+photos-f.ak.fbcdn.net.
+u20.eset.com.
+43.138.13.163.in-addr.arpa.
+snippets.mozilla.com.
+latam.msn.com.
+1056349545.mail.outlook.com.
+www.facebook.com.
+www.facebook.com.
+bs.serving-sys.com.
+fvlpl9k13.07re.
+214.105.34.190.in-addr.arpa.
+a.root-servers.net.
+www.juegosyonkis.com.
+syria.com.
+163.62.109.200.in-addr.arpa.
+70.119.21.187.in-addr.arpa.
+lurkerfaqs.com.
+56.168.36.186.in-addr.arpa.
+_autodiscover._tcp.nsn.com.apac.nsn-intra.net.
+hallmarksuites.com.
+losmundosdepipi.blogspot.com.
+hotmail.com.
+www.wamagic.com.
+a-0.19-230f7081.a0f0131.1518.197c.3ea0.200.0.hch9ftcmi5jjvej61skj7km8di.avqs.mcafee.com.
+128.127.148.189.in-addr.arpa.
+www.chelseafc4arab.com.
+external.ak.fbcdn.net.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+52.179.179.190.in-addr.arpa.
+svod.espn.go.com.
+img131.imagevenue.com.
+www.pspgo1.com.
+mail2.phorn.hu.
+media.io.
+a5.sphotos.ak.fbcdn.net.
+graph.facebook.com.
+a6.sphotos.ak.fbcdn.net.
+31.146.3.190.in-addr.arpa.
+123.251.168.192.in-addr.arpa.
+billing.sharo4ka.ru.
+207.237.53.201.in-addr.arpa.
+profile.ak.fbcdn.net.
+77btddl2z.62he.
+www.brooonzyah.net.
+2.bp.blogspot.com.
+dns.msftncsi.com.
+googleads.g.doubleclick.net.
+cdn.loading321.com.
+www.thesunblog.com.
+ns3-uk.rapidwaters.net.
+a.root-servers.net.
+kinsha.msk.ru.
+93.136.138.201.in-addr.arpa.
+s4.histats.com.
+aol.com.
+sp.cwfservice.net.
+w12.myzcm.com.
+graphic-hub.com.
+lb._dns-sd._udp.0.2.168.192.in-addr.arpa.
+hahah.com.
+edge.quantserve.com.
+rv.ginyas.com.
+www.consumer.es.
+photos-b.ak.fbcdn.net.
+malcerkov.ru.
+87.142.80.186.in-addr.arpa.
+e3353.c.akamaiedge.net.
+checkip.dyndns.org.
+www.simplemachines.org.
+mail1.crum.com.
+mail.jakers.com.
+116.23.55.189.in-addr.arpa.
+nowthestoryismine.tumblr.com.
+d12.laserdiscs.biz.
+a1505.l.akamai.net.
+mitchell.k12.ga.us.s10a1.psmtp.com.
+_330_05_1.
+179.145.73.189.in-addr.arpa.
+i4.ytimg.com.
+static.ak.facebook.com.
+graph.facebook.com.
+a.root-servers.net.
+tcr.tynt.com.
+promo.profitsdeluxe.com.
+blazinglizard.com.
+.
+a.root-servers.net.
+photos-e.ak.fbcdn.net.
+www.google.com.
+dns.msftncsi.com.
+www.gstatic.com.
+data.flurry.com.
+wyatt.edisonproject.com.
+tag.admeld.com.
+developers.facebook.com.
+141.197.1.181.in-addr.arpa.
+mail.lmpcorp.com.
+26.114.71.70.in-addr.arpa.
+inbound.lanhambros.com.netsolmail.net.
+163.com.cn.
+itunes.apple.com.
+167.19.225.69.in-addr.arpa.
+dns.msftncsi.com.
+www.update.microsoft.com.
+gateway.arrail-dental.com.
+24.media.tumblr.com.
+gomarmaris.ru.
+195-async.olark.com.
+www.google-analytics.com.
+lqwutrysqwqonloy.biz.
+www.bluecoat.com.
+newideamebel.ru.
+www.alfaguara.com.
+www.tafe.swinburne.edu.au.
+_124_17_8.
+www.dondebuscarpareja.com.
+graph.facebook.com.
+support.mozilla.com.
+243.140.255.201.in-addr.arpa.
+253.135.11.83.in-addr.arpa.
+google.com.
+37.66.190.189.in-addr.arpa.
+64.45.141.201.in-addr.arpa.
+wd-edge.sharethis.com.
+secure.shared.live.com.
+76.255.26.201.in-addr.arpa.
+accounts.google.com.
+www.rotahavik.co.nz.
+z61phxecs.71bd.
+219.145.48.65.in-addr.arpa.
+api-read.facebook.com.
+169.154.79.200.in-addr.arpa.
+geo.tp-cdn.com.
+platform.ak.fbcdn.net.
+a.root-servers.net.
+webcache.googleusercontent.com.
+habraham.com.
+mdk.com.ru.
+felafacs.org.
+coastalfloorcovering.com.
+www.facebook.com.
+drawn-reality.org.
+_998_39_5.
+_548_79_4.
+i-0.19-2709f081.83.1518.19d4.3ea1.410.0.wh287b8bvp1cg27mr4pzcu9n5t.avqs.mcafee.com.
+www.facebook.com.
+eros.21.ru.
+tnswfs03.siderca.techint.net.
+s.gravatar.com.
+133.19.206.187.in-addr.arpa.
+microbanc.com.
+mail.vegalab.ru.
+www.update.microsoft.com.
+static.ak.facebook.com.
+www.espressoandcream.com.
+sn106w.snt106.mail.live.com.
+9.182.62.187.in-addr.arpa.
+photos-f.ak.fbcdn.net.
+zh-cn.facebook.com.
+137.106.136.123.in-addr.arpa.
+isohunt.com.
+136.203.42.177.in-addr.arpa.
+boygj.com.
+au.bartercard.net.
+www.maturetubevids.com.
+144.106.87.190.in-addr.arpa.
+wpad.domain.name.
+mail2.unisale.ru.
+www.cladead.com.
+169.40.96.94.in-addr.arpa.
+cdn.wibiya.com.
+safebrowsing.clients.google.com.
+urs.microsoft.com.
+mrbronco.xomba.com.
+www.ardeaprints.com.
+19.210.217.87.in-addr.arpa.
+carriesyabookshelf.blogspot.com.
+192.248.205.109.in-addr.arpa.
+4x4mecca.com.
+a3.sphotos.ak.fbcdn.net.
+cdn.feeds.videosz.com.
+mx.ptmail.sapo.pt.
+www.downtownwomenscenter.com.
+203.100.108.186.in-addr.arpa.
+yenibiris.com.
+ns202.vpsland.com.
+alexandraboigerillustration.blogspot.com.
+173.167.161.46.in-addr.arpa.
+chilihead.com.
+www.tutarotgratis.com.
+pagead2.googlesyndication.com.
+www.facebook.com.
+214.69.175.187.in-addr.arpa.
+orate.burlingtoncoatfactory.com.
+a.root-servers.net.
+eltiempodelaspalabras.blogspot.com.
+avgtechnologies.112.2o7.net.
+chistesbajosengrasas.blogspot.com.
+jxubvflympq.info.lan.
+samwep.info.
+www.kuzey-guney-son-bolum-izle.com.
+dns.msftncsi.com.
+126.159.54.83.in-addr.arpa.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+plus.google.com.
+mail2.kgoc.com.
+google.com.
+www.afterfivedesigns.com.
+232.8.55.157.in-addr.arpa.
+continental.grupobbv.com.
+www.facebook.com.
+106.44.225.82.in-addr.arpa.
+cs5874.vkontakte.ru.
+lep113:en.e01b9e0f.
+mscrl.microsoft.com.
+_970_23_6.
+balticbereg.ru.
+ad.doubleclick.net.
+id.furud.net.
+www.bogotalacandelaria.com.
+dns.msftncsi.com.
+time-nw.nist.gov.
+mail.italyrealty.ru.
+sc1.rules.mailshell.net.
+gawker.com.
+www.nude-perfection.com.
+www.bestcelebstube.com.
+189.254.172.190.in-addr.arpa.
+photos-a.ak.fbcdn.net.
+time.windows.com.
+41.115.115.174.in-addr.arpa.
+a4.sphotos.ak.fbcdn.net.
+grafiq.com.co.
+foros.esmas.com.woopra-ns.com.
+2.177.35.187.in-addr.arpa.
+7.4.f.e.7.c.4.4.0.e.f.0.b.3.8.2.d.f.9.7.5.f.e.5.0.0.0.0.1.0.0.2.ip6.arpa.
+186.34.133.186.in-addr.arpa.
+techproekt.ru.
+a.root-servers.net.
+b.scorecardresearch.com.
+img84.imageshack.us.
+photos-d.ak.fbcdn.net.
+www.styling-deluxe.com.
+tap2-cdn.rubiconproject.com.
+ihlc.udea.edu.co.
+connect.facebook.net.
+api2.4shared.com.
+www.symphonyspace.org.
+www.asmallorange.com.
+comcast.net.
+abercromb.ie.
+197.201.153.201.in-addr.arpa.
+wazetv.com.
+www.tarimziraat.com.
+162.252.212.200.in-addr.arpa.
+creative.ak.fbcdn.net.
+help.slideshare.com.
+descargas.muyzorras.com.
+googleads.g.doubleclick.net.
+www.alacered.com.
+a.root-servers.net.
+adsfront.iminent.com.
+www.bioetica.ufrgs.br.
+safebrowsing-cache.google.com.
+www.wtp101.com.
+a.root-servers.net.
+upay-cdn2.playspan.com.
+fbcdn-sphotos-a.akamaihd.net.
+www.siteadvisor.com.
+wdphoto.com.
+ad.globaltakeoff.net.
+www.google.com.
+.
+mx-64-60-33-242.newhorizonspix.com.
+s-static.ak.facebook.com.
+www.chasingeyes.com.
+4.69.255.76.in-addr.arpa.
+20.30.212.186.in-addr.arpa.
+krmuevizk47gsp62nwf22lqd20bxbqgqlsi15.biz.
+diss.com.
+xpnd.se.
+www.eviews.net.
+120.129.211.201.in-addr.arpa.
+static.ak.fbcdn.net.
+csi.gstatic.com.
+static.ak.fbcdn.net.
+twitter.com.
+pixel.facebook.com.
+a7.sphotos.ak.fbcdn.net.
+desktopworld.disqus.com.
+www.fr-reiki.com.
+a5.sphotos.ak.fbcdn.net.
+a.root-servers.net.
+repository.arrow.nokia.com.
+logs9.contadorwap.com.
+static.ak.fbcdn.net.
+233.246.114.59.in-addr.arpa.
+mx.news.search.yahoo.com.
+a3.sphotos.ak.fbcdn.net.
+231.237.27.50.in-addr.arpa.
+faebook.com.
+187.82.203.108.in-addr.arpa.
+:ttvkpspd.95ma.
+apis.google.com.
+151.19.249.89.in-addr.arpa.
+13-courier.push.apple.com.
+tracker.publicbt.com.
+teredo.ipv6.microsoft.com.
+transas.ru.
+d1.apktops.com.
+137.7.82.200.in-addr.arpa.
+es.wikipedia.org.
+mail2.furamavietnam.com.
+wild-berries-dw.blogspot.com.
+a.root-servers.net.
+photos-g.ak.fbcdn.net.
+regentgroup.ru.
+20minutos.feedsportal.com.
+pjcvlau57.15vi.
+www.topappsquare.com.
+www.youtube.com.
+110.84.240.190.in-addr.arpa.
+sp.cwfservice.net.
+www.sdrifter-nismoracing.blogspot.com.
+grids.heroku.com.
+profile.ak.fbcdn.net.
+a6.sphotos.ak.fbcdn.net.
+www.portaventura.co.uk.
+de-de.facebook.com.
+static.ak.fbcdn.net.
+clients1.google.com.
+www.progressiveseminars.com.
+22.202.146.187.in-addr.arpa.
+node1.ecogeek-cdn.net.
+206.73.77.188.in-addr.arpa.
+sytrus.programas-gratis.net.
+137.89.250.189.in-addr.arpa.
+creative.ak.fbcdn.net.
+s3.amazonaws.com.
+www.facebook.com.
+jack-fx.com.
+sn2files.storage.msn.com.
+platform.twitter.com.
+rcp.na.blackberry.com.
+s0.2mdn.net.
+.
+236.154.247.190.in-addr.arpa.
+www.frenchonfire.fr.nf.
+u-smile-jb-y-tu.metroblog.com.
+tracker.mightynova.com.
+225.22.126.190.in-addr.arpa.
+gc.peachnet.edu.
+a3.sphotos.ak.fbcdn.net.
+barrowwhanley.com.
+billing.sharo4ka.ru.
+www.essayandscience.com.
+i3.ytimg.com.
+static.ak.fbcdn.net.
+a749.g.akamai.net.
+219.225.58.201.in-addr.arpa.
+trificient.net.
+i4.ytimg.com.
+fxfeeds.mozilla.com.
+211.158.216.201.in-addr.arpa.
+www.googleadservices.com.
+pappasitos.com.
+www.game-advertising-online.com.
+milyunanochesconmiada.blogspot.com.
+blog.geeksaresexytech.netdna-cdn.com.
+a.root-servers.net.
+148.150.62.189.in-addr.arpa.
+105.20.174.190.in-addr.arpa.
+dns.msftncsi.com.
+www.facebook.com.
+a.root-servers.net.
+ksn2-12.kaspersky-labs.com.
+pixel.facebook.com.
+tags.bluekai.com.
+180.51.5.116.in-addr.arpa.
+www.texasarchive.org.
+support.google.com.
+t1.gstatic.com.
+www.apple.com.
+c.brightcove.com.
+s-static.ak.facebook.com.
+82.25.71.190.in-addr.arpa.
+s-static.ak.facebook.com.
+mi.adinterax.com.
+a2.sphotos.ak.fbcdn.net.
+a7.sphotos.ak.fbcdn.net.
+www.googletagservices.com.
+34.115.59.187.in-addr.arpa.
+gcrm.com.
+48.144.171.201.in-addr.arpa.
+birdsfod.blogspot.com.
+145.212.157.186.in-addr.arpa.
+hotmail.com.
+www.google.com.
+c-0.19-a30fa081.30081.1518.1998.3ea0.200.0.rqw7f386mgq5i2vj71kkslquhj.avqs.mcafee.com.
+202.221.104.189.in-addr.arpa.
+www.theglobeandmail.com.
+price-n.ru.
+ads.trafficjunky.net.
+130.228.172.94.in-addr.arpa.
+www.mittelstandswiki.de.
+www.divine.ca.
+www.google-analytics.com.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+www.cv.vic.gov.au.
+www.facebook.com.
+www.linkbucksmedia.com.
+fs727.filepost.com.
+sn1msg1020220.gateway.messenger.live.com.
+a328.da1.akamai.net.
+ingenieria-de-yacimientos.blogspot.com.
+191.96.141.201.in-addr.arpa.
+lyuag9n2a.01rf.
+a4.sphotos.ak.fbcdn.net.
+wzb8a81il.q63j8e6r.
+www.a10studio.net.
+ajax.googleapis.com.
+infonet.tomsk.ru.
+170.219.185.187.in-addr.arpa.
+elk.mazury.pl.
+geo.messenger.services.live.com.
+gmedical.org.
+tracker.piecesnbits.net.
+mscrl.microsoft.com.
+144.161.254.190.in-addr.arpa.
+9ts.ru.
+www.facebwook.com.
+50.152.255.201.in-addr.arpa.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+www.savella.com.
+ssl.gstatic.com.
+a.root-servers.net.
+_641_51_8.
+a998.mm1.akamai.net.
+174.1.168.192.in-addr.arpa.
+cdn.optmd.com.
+affiliates.excelcalcs.com.
+a.root-servers.net.
+accounts.google.com.
+www.googleadservices.com.
+beharrygroup.com.
+www.mediafire.com.
+www.mandco.com.
+ntp.glb.nist.gov.
+1580thelight.com.
+www.facebook.com.
+skp.com.
+rcp.eu.blackberry.com.
+zulu.tweetmeme.com.
+opencourseware.kfupm.edu.sa.
+apps.bittorrent.com.
+www.spiritualgangster.com.
+njmcli.com.
+amor.org.
+www.divx-es.com.
+a.root-servers.net.
+www.amateursexmovs.com.
+zjgefordtex.en.alibaba.com.
+www.honawahonak.com.
+www.youtube.
+teredo.ipv6.microsoft.com.
+167.142.64.98.in-addr.arpa.
+157.222.160.201.in-addr.arpa.
+profile.ak.fbcdn.net.
+developers.facebook.com.
+42.109.45.187.in-addr.arpa.
+9gag.com.
+www.queenkate.com.
+profile.ak.fbcdn.net.
+safebrowsing-cache.google.com.
+www.delphigroups.info.
+www.google.com.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+csi.gstatic.com.
+ad.yieldmanager.com.
+poe.perl.org.
+dyvzcu.com.
+offer.ebay.com.
+www.youtube.com.
+148.120.20.187.in-addr.arpa.
+blog.theicecreamists.com.
+evsecure-ocsp.verisign.com.
+burtkunihonda.com.inbound15.mxlogic.net.
+www.fontanka.ru.
+secure.wlxrs.com.
+developers.facebook.com.
+view.atdmt.com.
+172.1.80.2.in-addr.arpa.
+google.com.
+www.vbeda.com.
+239.98.184.201.in-addr.arpa.
+www.download.windowsupdate.com.
+83.186.56.186.in-addr.arpa.
+www.zmtcdn.com.
+photos-f.ak.fbcdn.net.
+253.76.123.189.in-addr.arpa.
+factoryartists.com.
+66.116.233.123.in-addr.arpa.
+d7.zedo.com.
+3etk2jtug.50bo.
+www.facebook.com.
+www.wkc-collection.de.
+www.withoutabox.com.
+mailb.aljazeera.net.
+a5.sphotos.ak.fbcdn.net.
+db._dns-sd._udp.0.1.168.192.in-addr.arpa.
+finlandiacheese.com.
+62.216.156.189.in-addr.arpa.
+twitter.com.
+:vxtra9b:.d77r1d0e.
+greatinsurancejobs.com.s8b1.psmtp.com.
+www.htia.org.
+moillusions.us.intellitxt.com.
+photos-c.ak.fbcdn.net.
+photos-h.ak.fbcdn.net.
+global.ard.yahoo.com.
+s1-powerpoint.vo.msecnd.net.
+231.234.16.62.in-addr.arpa.
+www.saintaquinas.com.
+_624_97_4.
+blog.livestation.com.
+dl29.hotgoo.com.
+mail2.glmshows.com.
+fxfeeds.mozilla.com.
+mesianicos.net.
+letgetmorefollowers.info.
+accounts.google.com.
+mx2.smtp.gru.net.
+epic.com.
+171.19.135.190.in-addr.arpa.
+groupusa.com.
+www.loureed.8k.com.
+a.root-servers.net.
+iphone-wu.apple.com.
+gbd3d9b9e6e334abf.api.playtomic.com.
+mail.des.org.ua.
+external.ak.fbcdn.net.
+www.facebook.com.
+www.google.com.
+www.editions-larousse.fr.
+pixel.quantserve.com.
+www.eluniversal.com.mx.
+t-otaku-m.com.
+profile.ak.fbcdn.net.
+hotmail.com.
+a.root-servers.net.
+219.186.56.78.in-addr.arpa.
+a.root-servers.net.
+es.wikipedia.org.
+r1-ads.ace.advertising.com.
+sportsbybrooks.com.
+flyingfish.co.nz.
+www.jpbuzz.com.
+www.myspace.com.
+mail.amvest.com.
+www.venesistemas.net.
+www.gstatic.com.
+215.45.54.125.in-addr.arpa.
+132.69.42.83.in-addr.arpa.
+www.ipc.org.kw.
+forum.avscripts.net.
+webmail.radiomaranon.org.pe.
+18.152.172.201.in-addr.arpa.
+static.ak.fbcdn.net.
+mail.bankmeta.com.
+bin-short.whatsapp.net.
+i6.tagstat.com.
+www.sd.xinhuanet.com.
+vrgw.komsco.com.
+115.189.201.190.in-addr.arpa.
+csi.gstatic.com.
+www.google.com.
+es.dofusmagazine.com.
+169.75.213.190.in-addr.arpa.
+cn1.redswoosh.akadns.net.
+a.root-servers.net.
+msc.wlxrs.com.
+www.ejuegosdeben10.com.
+ad.foxnetworks.com.
+connect.facebook.net.
+arsavage.com.
+12.157.210.201.in-addr.arpa.
+armdl.adobe.com.
+arosauto.no.
+matrixmtgloans.com.
+clients4.google.com.
+a1720.phobos.apple.com.
+login.yahoo.net.
+tron.softonic.com.
+infor.pl.
+242.253.54.60.in-addr.arpa.
+es.wikipedia.org.
+925.nl.
+98.194.114.177.in-addr.arpa.
+ibtikar.twofour54.com.
+hmh.org.
+144.162.24.46.in-addr.arpa.
+ad.amgdgt.com.
+dns.msftncsi.com.
+www.mynewsjapan.com.
+tt.net.
+i.ebayimg.com.
+www.soccerstand.com.
+24.103.18.186.in-addr.arpa.
+hr3ajvxpd.g34d5k9x.
+reviews.cnet.com.
+www.sexfilms.com.
+61.88.160.189.in-addr.arpa.
+www.robotadserver.com.
+pttimqfovlnunn.net.
+sonalisangbad.com.
+169.162.121.84.in-addr.arpa.
+www.precisioninstrument.es.
+crl.microsoft.com.
+:krboeduf.23mv.
+genesis.1337x.org.
+tc24.easythumbhost.com.
+dns.msftncsi.com.
+a.root-servers.net.
+denegday.ru.
+92.106.83.189.in-addr.arpa.
+dr._dns-sd._udp.0.70.16.172.in-addr.arpa.
+mailer1.tablogix.ru.
+s2.youtube.com.
+hhholmestesting.com.
+cdn.api.twitter.com.
+hotmail.com.
+yknet.com.
+c3v68bgyf.l39g3w6s.
+125.68.132.223.in-addr.arpa.
+preparadelcamino.blogspot.com.
+www.epsco-group.com.
+a.root-servers.net.
+geo.messenger.services.live.com.
+ark.switnet.org.
+sunoptics.com.
+mx.belkozin.com.
+243.184.52.186.in-addr.arpa.
+fldeadhead.com.
+8.4.236.88.in-addr.arpa.
+0.79.6.88.in-addr.arpa.
+nc:rlx7yl.09rb.
+40.71.21.201.in-addr.arpa.
+sdau2.sdau.edu.cn.
+google.com.
+mx-int.sama.ru.
+com.
+i4.ytimg.com.
+102.69.188.189.in-addr.arpa.
+163.53.177.78.in-addr.arpa.
+developers.facebook.com.
+sacla-tm.com.
+support.dtsearch.com.
+creative.ak.fbcdn.net.
+trksrv10.doublefusion.com.
+gfx2.hotmail.com.
+www.googleapis.com.
+90.52.107.189.in-addr.arpa.
+206.141.110.189.in-addr.arpa.
+pointsul.com.br.
+arsclassicacoins.com.
+creative.ak.fbcdn.net.
+cdn.babble.com.
+zartarco.com.cy.
+tracker.ccc.de.
+a3.sphotos.ak.fbcdn.net.
+bvva62627661.ns02.biz.
+www.textpad.com.
+principia-group.com.
+apps.facebook.com.
+110.188.231.190.in-addr.arpa.
+asktoolbar.weather.com.
+www.pktienda.es.
+images.apple.com.
+keglerbrown.com.
+ds.addthis.com.
+mangham.com.
+www.gladiatus.lv.
+www.readerswivesmovies.com.
+27.147.220.66.in-addr.arpa.
+9.71.184.201.in-addr.arpa.
+s.ytimg.com.
+mx2.adamant.ru.
+primped4.hcdn1.net.
+rpt.ladyfootlocker.com.
+www.adaptelec.com.
+253.17.231.201.in-addr.arpa.
+b-0.19-23091008.481.1518.19d0.3ea1.410.0.cnvnzfragmddpldidjatrqqfmj.avqs.mcafee.com.
+b._dns-sd._udp.0.1.168.192.in-addr.arpa.
+cursos-blogger.blogspot.com.
+mailin-01.mx.aol.com.
+widget-36.slide.com.
+154.217.73.190.in-addr.arpa.
+pjsml.50megs.com.
+156.187.192.173.in-addr.arpa.
+www.googleadservices.com.
+52.77.75.200.in-addr.arpa.
+www.adobe.com.
+redsys.ru.
+www.habbo.es.
+www.dlink.com.
+massena.com.
+thecollectivereview.com.
+kidsalive.com.au.
+242.214.56.200.in-addr.arpa.
+wpad.ad.local.
+www.topappsquare.com.
+www.addthis.com.
+0-jg-w.channel.facebook.com.
+www.ashesh.com.np.
+sp.cwfservice.net.
+lazerit.com.
+www.facebook.com.
+s4.histats.com.
+bookzone4boys.blogspot.com.
+sc17.rules.mailshell.net.
+accounts.google.com.
+gs-loc.apple.com.
+169.166.59.186.in-addr.arpa.
+de-de.facebook.com.
+time.windows.com.
+jim6.mail.ru.
+2.m0n0wall.pool.ntp.org.
+blastmagazine.net.
+col.stc.s-msn.com.
+graph.facebook.com.
+mashable.com.
+api.facebook.com.
+bits.wikimedia.org.
+clients2.google.com.
+www.auntruthskitchen.com.
+safebrowsing.cache.l.google.com.
+js.wlxrs.com.
+time.chttl.com.tw.
+mail.echolabs.net.
+google.com.
+0-56.channel.facebook.com.
+meg.drs.ca.
+a.root-servers.net.
+www.weef2012.edu.ar.
+teknopanel.com.tr.
+safebrowsing.clients.google.com.
+radiusventures.com.s6a2.psmtp.com.
+a.root-servers.net.
+studiocavallleri.it.
+emmail.com.
+www.aboutoracleapps.com.
+a7.sphotos.ak.fbcdn.net.
+www.quranrabbi.com.
+0.11-2109e021.c0c10b3.1518.19b2.410a.400.9d.gdjs2rgdr2gsw4wia8nflr2dsb.avqs.mcafee.com.
+59.157.145.186.in-addr.arpa.
+pop3.hiway.co.uk.
+buscadorares.com.
+www.youtube.com.
+dingtao333.3322.org.
+conelsolenleo.blogspot.com.
+bit.ly.
+juegosiphone.org.
+www.facebook.com.
+190.66.224.190.in-addr.arpa.
+a1408.w43.akamai.net.
+laberintos.itam.mx.
+yovfk6xm:.s00r1e0x.
+new.digg.com.
+39.113.2.187.in-addr.arpa.
+102.38.8.82.in-addr.arpa.
+28.26.123.201.in-addr.arpa.
+db._dns-sd._udp.0.1.168.192.in-addr.arpa.
+relay.pholding.ru.
+a.root-servers.net.
+photos-b.ak.fbcdn.net.
+63.221.212.190.in-addr.arpa.
+sdc.oocl.com.
+external.ak.fbcdn.net.
+i2.ytimg.com.
+nobu.backup.com.
+ksn2-12.kaspersky-labs.com.
+tiff.net.
+assets.pinterest.com.
+96.102.70.77.in-addr.arpa.
+alperjcc.org.
+wirr.com.
+mail2.gicec.net.
+a4.sphotos.ak.fbcdn.net.
+uni-ins.ru.
+tvcomedies.about.com.
+www.sonymusic.it.
+g.ceipmsn.com.
+a276.phobos.apple.com.
+lovelythings.typepad.co.uk.
+config.messenger.msn.com.
+www.orizaba.gob.mx.
+ytebgv7or.48ti.
+tyther.attmail.com.
+latam.preciomania.com.
+pixel.facebook.com.
+lab.org.
+a2.twimg.com.
+skanar.sk.
+www.restauranticemachine.org.
+158.182.9.201.in-addr.arpa.
+docs.google.com.
+www.indulgecakes.co.za.
+fdsn0.skype.net.
+www.giardiasis.org.
+i4.ytimg.com.
+rimail.interlan.com.
+plastikote.com.
+mscrl.microsoft.com.
+www.chch.ox.ac.uk.
+www.bestotools.com.
+news.iks.ru.
+static2.consumerreportscdn.org.
+helium.lunarpages.com.
+27.252.0.72.in-addr.arpa.
+m.twitter.com.
+secure.wlxrs.com.
+astaro.district106.net.
+k14.kn3.net.
+www.canadapost.co.uk.
+open.pc120.com.
+verpelis.ne.
+www.jewish-greetings.com.
+ahoo.it.
+dns.msftncsi.com.
+scgi.ebay.com.au.
+a.root-servers.net.
+mediacom.com.s200a1.psmtp.com.
+mebel2006.ru.
+214.148.173.190.in-addr.arpa.
+google.com.
+a4.sphotos.ak.fbcdn.net.
+static.ak.fbcdn.net.
+en.wikipedia.org.
+www.americas-fr.com.
+www.facebook.com.
+a.root-servers.net.
+mail.crmsei.com.
+safeguard.concentric.com.
+load.exelator.com.
+127.0.0.1.
+www.fotosmix.com.
+www.foroz.org.
+ads.lfstmedia.com.
+issworldhistory.forumotion.net.
+www.kuponvilag.hu.
+www.google-analytics.com.
+us.js.yimg.com.
+db._dns-sd._udp.lan.
+a.c-0.19-a30f7081.c110000.1518.19d4.3ea1.210.0.jtjwp6s1mrce8pabffnu48rjd6.avqs.mcafee.com.
+www.snaponequipment.com.
+g.ceipmsn.com.
+s03.radikal.ru.
+webmedia.hrblock.com.
+photos-a.ak.fbcdn.net.
+photos-g.ak.fbcdn.net.
+124.248.174.189.in-addr.arpa.
+130.190.109.200.in-addr.arpa.
+asktoolbar.weather.com.
+rad.msn.com.
+26.171.152.189.in-addr.arpa.
+prof-soft.com.
+fbcdn-photos-a.akamaihd.net.
+www.skillsconverged.com.
+pix04.revsci.net.
+s.youtube.com.
+external.ak.fbcdn.net.
+photos-e.ak.fbcdn.net.
+23.209.18.87.in-addr.arpa.
+54.110.69.174.in-addr.arpa.
+newsrss.bbc.co.uk.
+194.186.7.189.in-addr.arpa.
+profile.ak.fbcdn.net.
+1stsmg.com.
+www.addthis.com.
+84.1.204.190.in-addr.arpa.
+ad3.liverail.com.
+highrollerlimo.com.
+www.fiscalia.com.
+speedsend.net.
+www.si-la.org.
+113.52.235.201.in-addr.arpa.
+0.11-230f8081.c120081.1518.18a6.3ea0.210.0.m6aph9nmfpfelks3u9ztjvkb9b.avqs.mcafee.com.
+cacs.net.
+dc427.4shared.com.
+static.ak.fbcdn.net.
+serv01.colo.owned.hu.
+e1.docs.yahoo.com.
+saturn.pcb-me.net.
+www.yele.org.
+www.google.com.
+muttski-software.com.
+221.199.72.46.in-addr.arpa.
+g.promosrv.com.
+dns.msftncsi.com.
+618connect.com.
+www.facebook.com.
+pagead.l.doubleclick.net.
+www.xtremenutrition.co.nz.
+es.dragonball.wikia.com.
+safebrowsing.clients.google.com.
+external.ak.fbcdn.net.
+lb._dns-sd._udp.0.2.168.192.in-addr.arpa.
+edgfdpipm.y75o6k0q.
+mikkai.com.
+a.root-servers.net.
+www.videos-it.com.
+228.13.188.190.in-addr.arpa.
+google.com.
+207.154.199.213.combined.njabl.org.
+pagead2.googlesyndication.com.
+accounts.google.com.
+www.historiadeldibujo.com.
+sos19shei.z89v3j1f.
+okatrauzdws.info.
+www.gangbangcathy.com.
+st.plenomedia.com.
+rpz-dvb.ru.
+ads.eluniversal.com.mx.
+www.soharuni.net.
+fr-fr.facebook.com.
+ds.serving-sys.com.
+fbcdn-profile-a.akamaihd.net.
+a.root-servers.net.
+m.hotmail.com.
+keepmybooks.net.
+227.36.154.165.in-addr.arpa.
+pomol.ru.
+edge.quantserve.com.
+mail2.cherisundae.com.
+gamerrr.com.
+macsecrets.ru.
+www.facebook.com.
+photos-a.ak.fbcdn.net.
+d5nxst8fruw4z.cloudfront.net.
+www.glenngoodman.com.
+www.google.com.
+.
+www.co2trees.com.au.
+ritterbush.com.
+astore.amazon.com.
+creative.ak.fbcdn.net.
+distilleryimage6.instagram.com.
+tracker.anime-miako.to.
+kapsch.com.
+unil.ch.
+time.chttl.com.tw.
+webmoney26.ru.
+top.habbolibre.org.
+f4999.mail.yahoo.com.
+static.geewa.net.
+photos-f.ak.fbcdn.net.
+a4.sphotos.ak.fbcdn.net.
+urs.microsoft.com.
+v2.nonxt3.googlevideo.com.
+a8.sphotos.ak.fbcdn.net.
+secure.wlxrs.com.
+ib.adnxs.com.
+www.google.com.
+api-read.facebook.com.
+35.79.106.186.in-addr.arpa.
+partsurfer.hp.com.
+a.root-servers.net.
+bloodless.ru.
+capristan.com.
+ad.adtegrity.net.
+profile.ak.fbcdn.net.
+www.distrikayser.com.
+yahoo.com.
+161.28.92.186.in-addr.arpa.
+_914_05_5.
+a.root-servers.net.
+antonio-pernas.es.
+secure.wlxrs.com.
+teredo.ipv6.microsoft.com.
+www.google.com.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+www.prayertimes.net.
+dr._dns-sd._udp.0.44.16.172.in-addr.arpa.
+suicide-isnt-painful.piczo.com.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+168.221.154.190.in-addr.arpa.
+crl.microsoft.com.
+linkscorp.com.
+www.youtube.com.
+b._dns-sd._udp.0.1.168.192.in-addr.arpa.
+golem.pixar.com.
+50.235.51.90.in-addr.arpa.
+196.88.217.24.in-addr.arpa.
+www.facebook.com.
+s-static.ak.fbcdn.net.
+static.pulse360.com.
+www.tabrizcartoons.com.
+s.ytimg.com.
+127.49.54.65.in-addr.arpa.
+www.geckowood.com.
+whos.amung.us.
+www.jobmeeting.it.
+accounts.youtube.com.
+hyacinth.org.
+cncbt2.the9.com.
+c.atdmt.com.
+86.26.176.189.in-addr.arpa.
+mx2.capgemini.com.
+ad.smowtion.com.
+224.169.9.186.in-addr.arpa.
+9gv7xkt4n.73dg.
+www.google.com.
+www.koniambonickel.nc.
+bontel.ru.
+ar-ar.facebook.com.
+twitter.com.
+s7.addthis.com.
+197.3.167.190.in-addr.arpa.
+dietasecreta.com.
+a3.sphotos.ak.fbcdn.net.
+d7.zedo.com.
+www.hilive.tv.
+wasio.net.
+www.google-analytics.com.
+fortheywerefishers.com.
+toolbarqueries.google.com.
+a.root-servers.net.
+photos-f.ak.fbcdn.net.
+widgets.twimg.com.
+www.facebook.com.
+selendangrakyat.blogspot.com.
+vistahospitality.com.2.0001.arsmtp.com.
+136.255.100.190.in-addr.arpa.
+172.157.131.187.in-addr.arpa.
+a1.sphotos.ak.fbcdn.net.
+willeybrothers.com.
+photos-d.ak.fbcdn.net.
+profile.ak.fbcdn.net.
+221.189.180.189.in-addr.arpa.
+h9mjcy742.m44w5m1y.
+profile.ak.fbcdn.net.
+worldpress.org.
+api.facebook.com.
+loading7.widdit.com.
+creative.ak.fbcdn.net.
+www.megafilex.com.
+sp.cwfservice.net.
+12.140.251.190.in-addr.arpa.
+thumbs2.ebaystatic.com.
+197.208.29.96.in-addr.arpa.
+videosonline.petardas.com.
+61.168.255.201.in-addr.arpa.
+a.root-servers.net.
+accounts.google.com.
+creative.ak.fbcdn.net.
+fpp.pt.
+www.google.com.
+pagead2.googlesyndication.com.
+a6.sphotos.ak.fbcdn.net.
+www.hotrecruit.com.
+xtaz.ru.
+bs.net.
+142.78.99.74.in-addr.arpa.
+gci.net.s6a2.psmtp.com.
+d1.openx.org.
+fbcdn-sphotos-a.akamaihd.net.
+unifi.
+cdn1.thumbnails.4tube.com.rncdn1.com.
+107.92.182.189.in-addr.arpa.
+i2.ytimg.com.
+sierraelpaso.com.s7b2.psmtp.com.
+furniturefromhome.com.
+115.120.52.186.in-addr.arpa.
+developers.facebook.com.
+ofertas-empleos.vivastreet.com.mx.
+cdn.contentspread.net.
+mytime.com.s7a1.psmtp.com.
+tr.adinterax.com.
+alcatraz.wikia.com.
+news.google.com.
+203.223.177.190.in-addr.arpa.
+www.facebook.com.
+www.pretenders.org.
+ajax.googleapis.com.
+newsrss.bbc.co.uk.
+udc.msn.com.
+www.loreal-paris.sk.
+fr.wikipedia.org.
+pandehigo.net.
+bit.ly.
+s-external.ak.fbcdn.net.
+linkhelp.clients.google.com.
+ssl.gstatic.com.
+cs10668.vk.com.
+www.printglobe.com.
+www.aerith.net.
+co108w.col108.mail.live.com.
+s-static.ak.fbcdn.net.
+stellar.mit.edu.
+a.root-servers.net.
+local-bay.contacts.msn.com.nsatc.net.
+msc.wlxrs.com.
+csi.gstatic.com.
+145.8.203.190.in-addr.arpa.
+a1408.w43.akamai.net.
+219.107.5.187.in-addr.arpa.
+boulder.craigslist.org.
+a4.sphotos.ak.fbcdn.net.
+jlawit.com.
+ttk.dp.ua.
+vp.sip.messenger.msn.com.
+db._dns-sd._udp.home.
+39.228.35.189.in-addr.arpa.
+profile.ak.fbcdn.net.
+photos-g.ak.fbcdn.net.
+ranero.ru.
+main.dl.wu.akadns.net.
+149.251.50.85.in-addr.arpa.
+www.facebook.com.
+a.root-servers.net.
+codegeasstheanime.weebly.com.
+www.mdf.nl.
+4.bp.blogspot.com.
+a.root-servers.net.
+cdn8.evendor.com.
+db._dns-sd._udp.0.1.168.192.in-addr.arpa.
+46.223.183.189.in-addr.arpa.
+db._dns-sd._udp.0.1.168.192.in-addr.arpa.
+ubuntugeek.uk.intellitxt.com.
+www.google.com.
+i1.ytimg.com.
+x80.xanga.com.
+mspmx2.redzonetech.net.
+trafficpython.com.
+138.115.207.186.in-addr.arpa.
+225.15.220.189.in-addr.arpa.
+modulos.grupojoly.com.
+sqis.net.
+api.facebook.com.
+49.147.220.66.in-addr.arpa.
+www.facebook.com.
+1.2.168.192.in-addr.arpa.
+162.91.141.201.in-addr.arpa.
+206.56.59.186.in-addr.arpa.
+62.0.172.190.in-addr.arpa.
+gandco.net.
+www.securecheckout.billmelater.com.
+www.facebook.com.
+www.youtube.com.
+na-baltike.com.
+pointdistribution.com.
+rtv4xy81o.w00b6y0f.
+a3.sphotos.ak.fbcdn.net.
+freemail.baden.ch.
+124.213.34.186.in-addr.arpa.
+lh3.googleusercontent.com.
+www.eppingclub.com.
+safebrowsing-cache.google.com.
+masonresearch.gmu.edu.
+www.srpnet.com.
+blst.msn.com.
+www.facebook.com.
+164.10.222.189.in-addr.arpa.
+9x2sgie28.w78j4w9o.
+185.36.78.85.in-addr.arpa.
+aguasdecauri.blogspot.com.
+e3167.c.akamaiedge.net.
+a8.sphotos.ak.fbcdn.net.
+a1.da1.akamai.net.
+www.pressenza.com.
+profile.ak.fbcdn.net.
+unipamplona.edu.co.
+www.apple.com.
+dandreamz.wordpress.com.
+mail.jetter.com.
+rcboat.ru.
+204.136.232.92.in-addr.arpa.
+37.77.165.189.in-addr.arpa.
+a.root-servers.net.
+bs.serving-sys.com.
+profile.ak.fbcdn.net.
+p0b.ru.
+craigrichard.com.
+client-log.amazon.com.
+westcoastwine.net.
+d.monetate.net.
+news.ycombinator.com.
+photos-c.ak.fbcdn.net.
+icons.iconarchive.com.
+jimmyskillerprawns.za.net.
+40.209.162.217.in-addr.arpa.
+127.65.201.187.in-addr.arpa.
+a.root-servers.net.
+forum1.netgear.com.
+www.juegosus.com.
+www.pixazza.com.
+fo5kjln:7.h75n1q8y.
+pod.xxxmatch.com.
+www.facebook.com.
+148.42.26.190.in-addr.arpa.
+blog.gkelite.com.
+googlehosted.l.googleusercontent.com.
+www.tirada-tarot-gratis.eu.
+images.habbo.com.
+hello.home.
+mundochess.blogspot.com.
+www.bdhs.org.
+101.205.237.189.in-addr.arpa.
+a.root-servers.net.
+fw2a.synexagroup.com.
+profile.ak.fbcdn.net.
+40.178.27.190.in-addr.arpa.
+www.google-analytics.com.
+7.5.22.187.in-addr.arpa.
+bwnews.us.
+136.219.192.173.in-addr.arpa.
+a.root-servers.net.
+thelookingspoon.com.
+93.81.167.190.in-addr.arpa.
+apis.google.com.
+a8.sphotos.ak.fbcdn.net.
+mx.bgeeng.com.
+api.twitter.com.
+231.68.17.95.in-addr.arpa.
+elespejosabio.blogspot.com.
+a1.sphotos.ak.fbcdn.net.
+226.121.172.76.in-addr.arpa.
+youtu.be.
+www.wctravel.com.
+www.tlucretius.net.
+43.116.82.70.in-addr.arpa.
+time.chttl.com.tw.
+a.root-servers.net.
+feeds.vocegiallorossa.it.
+u2:ny8de8.81ck.
+administradorfinanciero.wordpress.com.
+mail.ic-sol.net.
+securepubads.g.doubleclick.net.
+gap.mx.contego.net.
+tc19.easythumbhost.com.
+photos-g.ak.fbcdn.net.
+86.17.162.189.in-addr.arpa.
+mail.ibahn.com.
+www.google.com.
+www.spicymother.com.
+siyavooshan.blogfa.com.
+am.renesas.com.
+i4.ytimg.com.
+cdn.api.twitter.com.
+_ldap._tcp.
+30.25.31.88.in-addr.arpa.
+cdn.gotraffic.net.
+creative.ak.fbcdn.net.
+shinebythree.com.
+interjet.com.mx.
+www-google-analytics.l.google.com.
+179.208.255.206.in-addr.arpa.
+apps.skype.com.
+a.root-servers.net.
+a.1.s50.avatar.zdn.vn.
+a4.sphotos.ak.fbcdn.net.
+197.205.0.210.in-addr.arpa.
+googleads.g.doubleclick.net.
+www.news-leader.com.
+pimpdrop.com.
+es-es.facebook.com.
+768ujb:6r.12tq.
+www.shop-summerland.com.
+www.wired.com.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+rnd4.myphotos.cc.
+ptcscrutiny.com.
+116.192.210.201.in-addr.arpa.
+a.root-servers.net.
+digiphoto.thepodcastnetwork.com.
+www.kt2syggf436dtag641.com.
+a.root-servers.net.
+mail.arkay.com.
+img101.herosh.com.
+clients1.google.com.
+.
+53.21.0.192.in-addr.arpa.
+rinconakibareload.blogspot.com.
+a7.sphotos.ak.fbcdn.net.
+heartbeat.dm.origin.com.
+www.mozilla.com.
+eternallycool.net.
+bda.cwplc.com.s200a2.psmtp.com.
+matrix-ibs.com.inbound10.mxlogicmx.net.
+65.207.63.78.in-addr.arpa.
+bdieguez-photography.blogspot.com.
+www.marblas.es.
+benpelzel.com.
+_692_78_7.
+a4.sphotos.ak.fbcdn.net.
+search.iminent.com.
+apps.facebook.com.
+www.diccionariodesinonimos.es.
+a1.sphotos.ak.fbcdn.net.
+sp.cwfservice.net.
+www.google.com.
+safebrowsing-cache.google.com.
+201.137.194.187.in-addr.arpa.
+andrea453301.spaces.live.com.
+.
+buenos-aires.nexolocal.com.ar.
+76.71.140.201.in-addr.arpa.
+sedqwickcms.com.
+www.facebook.com.
+a7.sphotos.ak.fbcdn.net.
+google.com.
+mail.google.com.
+a.root-servers.net.
+photos-d.ak.fbcdn.net.
+pc7.
+www.tifflove.com.
+centellazul68.blogspot.com.
+softonic-toolbar.softonic.com.
+store.yahoo.net.
+dnl-01.geo.kaspersky.com.
+downings.com.au.
+metalbastard.blogspot.com.
+ic.tynt.com.
+189.125.38.190.in-addr.arpa.
+www.scribd.com.
+74.42.58.186.in-addr.arpa.
+53.73.136.14.in-addr.arpa.
+168.51.168.192.in-addr.arpa.
+40.171.112.187.in-addr.arpa.
+hbfel6pyi.q03j9f8u.
+www.facebook.com.
+atg-ispf-ex1.altuwairqi.com.sa.
+apps.facebook.com.
+cafe-buffet.ru.
+ntl.westcall.ru.
+t2.gstatic.com.
+www.allsaints.com.
+reynoldspkg.com.
+ssl.gstatic.com.
+express-inventory.softonic.com.
+_579_79_0.
+hash.orbitdownloader.com.
+251.65.36.187.in-addr.arpa.
+googleads.g.doubleclick.net.
+193.135.246.201.in-addr.arpa.
+7.36.215.189.in-addr.arpa.
+americas.orangeadvertisingnetwork.com.
+sp.cwfservice.net.
+frajumar.com.
+33.27.233.96.in-addr.arpa.
+73.155.243.201.in-addr.arpa.
+www.facebook.com.
+www.google.com.
+22.190.169.89.in-addr.arpa.
+idcs.interclick.com.
+themeservice.ebuddy.com.
+avow.org.
+a.root-servers.net.
+artistxite.com.
+safebrowsing-cache.google.com.
+et4.xhamster.com.
+hotmail.com.
+110.135.157.189.in-addr.arpa.
+sippican.com.
+clients2.google.com.
+wadakk.com.
+hi-in.facebook.com.
+platform.twitter.com.
+a4.sphotos.ak.fbcdn.net.
+51.41.145.189.in-addr.arpa.
+152.255.103.85.in-addr.arpa.
+17.104.232.190.in-addr.arpa.
+it-it.facebook.com.
+photos-g.ak.fbcdn.net.
+a.root-servers.net.
+pixel.facebook.com.
+accounts.google.com.
+a8.sphotos.ak.fbcdn.net.
+www.childcarelounge.com.
+ads.adxpansion.com.
+eventsforum.net.
+17.236.178.186.in-addr.arpa.
+a8.sphotos.ak.fbcdn.net.
+m.facebook.com.
+zimplestuff.com.
+amimichi.blogspot.com.
+a2.twimg.com.
+b._dns-sd._udp.0.1.168.192.in-addr.arpa.
+126.95.112.99.in-addr.arpa.
+fayans.ru.
+www.facebook.com.
+it-it.facebook.com.
+fbcdn-profile-a.akamaihd.net.
+3.99.218.186.in-addr.arpa.
+ajsfinefoods.com.
+comeonaussie.com.
+mail.friendimobile.com.
+newwest.net.
+mail.mc2mm.com.
+www.ebook.honglinhsoft.com.
+assets.mcity.digitalchocolate.com.
+mozilla.cdn.leaseweb.com.
+webres1.pand.ctmail.com.
+cdn1.widdit.com.
+20.29.158.200.in-addr.arpa.
+googleads.g.doubleclick.net.
+support.sherweb.com.
+es-la.facebook.com.
+cis.rv.ua.
+www.msftncsi.com.
+0-299.channel.facebook.com.
+crunchpost.com.
+_130_54_9.
+adam.com.au.
+189.206.160.201.in-addr.arpa.
+donbass.ua.
+119.30.39.70.in-addr.arpa.
+a.root-servers.net.
+photos-b.ak.fbcdn.net.
+a.root-servers.net.
+aloha.viber.com.
+www.viptranny.com.
+photos-d.ak.fbcdn.net.
+ipm.bitdefender.com.
+customer.accord5.com.
+185.59.42.62.in-addr.arpa.
+laformarock.com.ar.
+www.usatoday.com.
+www.textsrv.com.
+photos-f.ak.fbcdn.net.
+ori.com.
+2.104.31.151.in-addr.arpa.
+a.root-servers.net.
+e906.g.akamaiedge.net.
+a8.sphotos.ak.fbcdn.net.
+stun.client.akadns.net.
+a8.sphotos.ak.fbcdn.net.
+safebrowsing.clients.google.com.
+ee.port.ac.uk.
+cookex.amp.yahoo.com.
+espanol.bestbuy.com.
+mail.zaprib.ru.
+a2.sphotos.ak.fbcdn.net.
+www.activistasporelclima.com.
+mail.tameerbank.com.
+mail.unomail.dk.
+glu.com.
+photos-g.ak.fbcdn.net.
+public.cwgdogp.com.au.
+www.almacendesentimientos.com.
+www.google.com.
+safebrowsing.clients.google.com.
+thestaticfanatic.blogspot.com.
+www.microsoft.com.
+122.166.183.189.in-addr.arpa.
+www.youtube.com.
+clients2.google.com.
+234.142.125.186.in-addr.arpa.
+a6.sphotos.ak.fbcdn.net.
+b._dns-sd._udp.0.2.168.192.in-addr.arpa.
+220.178.202.190.in-addr.arpa.
+1.158.9.186.in-addr.arpa.
+a7.sphotos.ak.fbcdn.net.
+bbs.sx128.com.
+clock.sjc.he.net.
+safebrowsing.clients.google.com.
+www.gloryholedatabase.com.
+_969_33_5.
+a1.sphotos.ak.fbcdn.net.
+chromejs.s3.amazonaws.com.
+profile.ak.fbcdn.net.
+oscararizaleon.lacoctelera.net.
+mail.marshallbros.com.
+newsrss.bbc.co.uk.
+rblns49.mailshell.net.
+creative.ak.fbcdn.net.
+1stclassmortgagenv.com.
+www.youtube.
+ye02.ru.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+yahoo.com.
+a.root-servers.net.
+blu131w.mail.live.com.akadns.net.
+sisviso.plades.org.pe.
+kh.google.com.
+smtp-out2.electric.net.
+fbcdn-profile-a.akamaihd.net.
+www.todoesoterico.com.
+assine.uol.com.br.
+ocsp.digicert.com.
+cgvrl1bit.60gz.
+mail.rock108.com.
+ct-miramar.com.
+es.tangeroutlet.com.
+www.motorcycletouringpro.com.
+secure.wlxrs.com.
+r._dns-sd._udp.lan.
+photos-g.ak.fbcdn.net.
+www.jscount.com.
+safebrowsing-cache.google.com.
+platform.twitter.com.
+accounts.youtube.com.
+clients1.google.com.
+atlasip.com.
+se.itunes.apple.com.
+nefertarisims3.webcindario.com.
+www.cervantesvirtual.com.
+ox-op.com.
+keelerbrass.com.
+mail.marrs-sevier.com.
+airewaves.com.
+www.facebook.com.
+cigarfar.dk.
+googel.com.
+s-static.ak.fbcdn.net.
+mx.yahoo.com.
+www.visitraleigh.com.
+lb._dns-sd._udp.0.2.168.192.in-addr.arpa.
+googleads.g.doubleclick.net.
+landrys.com.
+origin.games.yahoo.net.
+wdg8bg1w2.l63q0n1r.
+in.yahoo.com.
+www.searchqu.com.
+www.facebook.com.
+mail2.tao.aoins.com.
+.
+map.czechtrade.net.
+www.facebook.com.
+mobillacura.wordpress.com.
+alternativelnok.blog.hu.
+platform.twitter.com.
+news-w0rlds.ru.
+photos-g.ak.fbcdn.net.
+www.soktelefonu.com.
+0-jj-w.channel.facebook.com.
+connect.facebook.net.
+geekmail.de.
+a7.sphotos.ak.fbcdn.net.
+sn3.mailshell.net.
+www.ciberdvd.com.
+cdnstatic.visualizeus.com.
+b-0.19-22090008.2020580.1518.19d4.3ea1.410.0.w63gpf5wia6jnshhq6na3bjhnj.avqs.mcafee.com.
+fbcdn-photos-a.akamaihd.net.
+mx.astrology.yahoo.com.
+fluxblog.org.
+1.130.26.174.in-addr.arpa.
+203.36.117.212.in-addr.arpa.
+r._dns-sd._udp.lan.
+150.20.141.201.in-addr.arpa.
+129.100.10.94.in-addr.arpa.
+mobth566.photobucket.com.
+40.153.155.85.in-addr.arpa.
+ib.adnxs.com.
+hosezup.net76.net.
+pirarucu.galeon.com.
+dns.msftncsi.com.
+www.homemademoviez.com.
+a3.sphotos.ak.fbcdn.net.
+www.jiayuan.com.
+196.111.133.190.in-addr.arpa.
+42.2.97.186.in-addr.arpa.
+97.68.230.189.in-addr.arpa.
+rcp.eu.blackberry.com.
+v7.nonxt7.c.youtube.com.
+ffupdate.engine.conduit-services.com.
+plusone.com.
+143.243.19.50.in-addr.arpa.
+friends.totallynsfw.com.
+www.facebook.com.
+r._dns-sd._udp.0.2.168.192.in-addr.arpa.
+www.aboutamanda.com.
+a3.sphotos.ak.fbcdn.net.
+mail.bmxx.ru.
+jo:ksvpu5.05eq.
+eye.wplus.net.
+www8.gamatar.org.
+a.root-servers.net.
+107.170.39.190.in-addr.arpa.
+rumboacanada.blogspot.com.
+ic.tynt.com.
+guru.avg.com.
+platform.twitter.com.
+mntr.babcdn.com.
+adele.wikia.com.
+hyrogifs.com.
+a7.sphotos.ak.fbcdn.net.
+www.hallofplay.com.
+z021.fma.fb.me.
+dns.msftncsi.com.
+a6.sphotos.ak.fbcdn.net.
+www.elationlighting.eu.
+img512.imageshack.us.
+98.73.235.189.in-addr.arpa.
+mx0.safarisolutions.xrbs.com.
+zbar2.zynga.com.
+s-static.ak.fbcdn.net.
+safebrowsing.cache.l.google.com.
+www.apple.com.
+worldwidereferrals.pro.
+26.67.139.189.in-addr.arpa.
+a1.sphotos.ak.fbcdn.net.
+profile.ak.fbcdn.net.
+dns.msftncsi.com.
+www.unique-wedding-rings.com.
+tip.tv.sohu.com.
+tudoparafotografia.blogspot.com.
+informsystems.ru.
+argo.sourceforge.net.
+www.tharmac.de.
+ib.adnxs.com.
+in.pod01.imht.udc2.mx.trendmicro.com.
+26.185.104.187.in-addr.arpa.
+profile.ak.fbcdn.net.
+197.235.225.212.in-addr.arpa.
+190.148.114.190.in-addr.arpa.
+a.root-servers.net.
+storagenerve.com.
+safebrowsing-cache.google.com.
+www.apple.com.
+news.google.com.mx.
+exp01.eset.com.
+dltdirect.com.
+landonjacob.com.
+gdata.youtube.com.
+www.humorsearch.com.
+a.root-servers.net.
+wellspeyton.com.
+i.ytimg.com.
+dns.msftncsi.com.
+developers.facebook.com.
+dns.msftncsi.com.
+relay.bodaclick.com.
+153.104.212.186.in-addr.arpa.
+www.nycewheels.com.
+iowaelecom.net.
+profile.ak.fbcdn.net.
+ee.duke.edu.
+baymsg1020130.by2.gateway.edge.messenger.live.com.
+mt2furia.zapto.org.
+www.alec.co.uk.
+doportugalprofundo.blogspot.com.
+uk-mkivs.net.
+68.29.199.87.in-addr.arpa.
+13.165.217.217.in-addr.arpa.
+siaws.fotolog.com.
+l.yimg.com.
+pixel.rubiconproject.com.
+i845.photobucket.com.
+hansens.com.s7b1.psmtp.com.
+photos-a.ak.fbcdn.net.
+www.rhythmsdelmundo.com.
+itunes.apple.com.
+mail.google.com.
+lifestyle.msn.com.
+go.microsoft.com.
+asktoolbar.weather.com.
+wolfrunstudio.com.
+mccabepromo.com.
+www.youtube.com.
+neonco.spb.ru.
+26.239.138.200.in-addr.arpa.
+mayads.com.mail6.psmtp.com.
+i1.ytimg.com.
+quicktwist.wordpress.com.
+t0.gstatic.com.
+www.letusreason.org.
+cnfg.montiera.com.
+apps.facebook.com.
+www.kantarworldpanel.com.
+47.134.48.96.in-addr.arpa.
+i0.tagstat.com.
+www.ebonyvideosex.com.
+187.59.91.186.in-addr.arpa.
+156.233.35.187.in-addr.arpa.
+m.facebook.com.
+1.bp.blogspot.com.
+eduardolakatos.wordpress.com.
+edge.sharethis.com.
+uddjinz9k.73hr.
+rss.msnbc.msn.com.
+www.a-trust.at.
+tienda.tucanarias.com.
+www.catchyoutube.com.
+mail.avantek.net.
+www.youtube.com.
+www.ponyforums.com.
+145.89.245.88.in-addr.arpa.
+photos-e.ak.fbcdn.net.
+titanium30-en.nfc.trendmicro.com.
+ajax.googleapis.com.
+12.59.16.206.in-addr.arpa.
+251.125.145.99.in-addr.arpa.
+xcite.com.
+m.paypal.com.
+wearebinary.com.
+114.104.243.201.in-addr.arpa.
+immanent-god-blues.blogspot.com.
+www.google-analytics.com.
+tcr.tynt.com.
+inbound.pulseniagara.com.netsolmail.net.
+236.45.149.83.in-addr.arpa.
+220.162.34.186.in-addr.arpa.
+teredo.ipv6.microsoft.com.
+googleapis.l.google.com.
+profile.ak.fbcdn.net.
+_127_39_5.
+99.192.8.95.in-addr.arpa.
+mail.
+rs730l35.rapidshare.com.
+20minutos.feedsportal.com.
+isearch.babylon.com.
+www.ephenic.com.
+jahudka.zoner.com.
+www.facebook.com.
+www.uncut.at.
+locat.it.
+76.108.179.78.in-addr.arpa.
+www.tnpesu.org.
+crl.globalsign.net.
+pagead2.googlesyndication.com.
+_090_31_5.
+partner.googleadservices.com.
+www.moonbingo.net.
+www.google.com.
+gfx4.hotmail.com.
+a1.sphotos.ak.fbcdn.net.
+latareadeldormilon.blogspot.com.
+mfs.portvancouver.com.
+www.articuloz.com.
+mahjong-escape.programas-gratis.net.
+www.ashrae.org.
+photos-a.ak.fbcdn.net.
+clanbtl.ru.
+vucjumfrv.com.
+cultretro.com.
+reggaetonlivetv.metroblog.com.
+www.ciberia.es.
+sports-memorabilia.shop.ebay.co.uk.
+254.47.153.189.in-addr.arpa.
+hlfraas.com.
+g.ceipmsn.com.
+s0.2mdn.net.
+external.ak.fbcdn.net.
+adspro.ru.
+googleads.g.doubleclick.net.
+www.hemorrhoids.net.
+82.134.14.187.in-addr.arpa.
+lt1o:3zvk.q41g8n5t.
+localhost.
+smtp1.vwtus.com.
+photos-b.ak.fbcdn.net.
+158.17.20.187.in-addr.arpa.
+www.annonsera.se.
+a.root-servers.net.
+7.220.89.186.in-addr.arpa.
+210.194.141.201.in-addr.arpa.
+trollsmyth.blogspot.com.
+www.jpclatam.org.
+www.bandeapart.fm.
+93.69.231.190.in-addr.arpa.
+espanol.answers.yahoo.com.
+a1003.w41.akamai.net.
+scsa.msg.yahoo.com.
+loading2.widdit.com.
+www.goojue.com.
+www.mojo.co.uk.
+c7.zedo.com.
+www.kingsofnewyork.net.
+roynat.com.
+nerve.myyearbook.com.
+caughtbytheriver.net.
+jooble-cl.com.
+102.64.139.187.in-addr.arpa.
+facebook.com.
+mail.alkhalidgroup.com.
+statik.nanopress.it.
+mms501.whatsapp.net.
+www.masterhack.20m.com.
+s3.memberclicks.com.
+241.94.191.186.in-addr.arpa.
+166.134.44.92.in-addr.arpa.
+a5.sphotos.ak.fbcdn.net.
+armaaaniihd.blogspot.com.
+luxury-ideas.net.
+www.facebook.com.
+weather.services.conduit.com.
+jolis.worldbankimflib.org.
+www.capeplc.com.
+sp.cwfservice.net.
+download342.avast.com.
+234.7.91.76.in-addr.arpa.
+facer-ins.com.
+kenametal.com.
+event-horizons.com.
+www.google.com.
+157.131.75.70.in-addr.arpa.
+timer.od.ua.
+tms30.icrc.trendmicro.com.
+www.best-iphone-deals.co.
+norecipes.stumbleupon.com.
+masterconn11.qq.com.
+9.230.147.190.in-addr.arpa.
+105.63.67.77.in-addr.arpa.
+46.185.176.190.in-addr.arpa.
+.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+www.windowslivemessenger.com.
+enpointetechnologies.com.
+myspace.com.
+b-0.19-a3097008.40080.1518.19d3.3ea1.410.0.msu8df338qwi2hlvilc94zsp65.avqs.mcafee.com.
+old.houstontexans.com.
+t5.tagstat.com.
+to-god-mcsong.blogspot.com.
+a8.sphotos.ak.fbcdn.net.
+www.adobe.com.
+www.redestelecom.es.
+www.tusartistas.com.
+losmejoresjuegosymasjuegos.blogspot.com.
+231.100.208.190.in-addr.arpa.
+www.blogus.cl.
+bs.serving-sys.com.
+users.conduit.com.
+cocinandoconkari.blogspot.com.
+francistuttle.com.inbound10.mxlogic.net.
+a.root-servers.net.
+www.undp.uz.
+admcnt.tlt.ru.
+googleads.g.doubleclick.net.
+a.root-servers.net.
+accounts.google.com.
+b-0.19-2109b008.11081.1518.19d4.2f4a.410.0.5dathp7t43621rr8uue53752ai.avqs.mcafee.com.
+newwavecomm.net.
+activmedia.com.inbound15.mxlogic.net.
+msgr.updates.yahoo.com.
+209.231.167.209.list.dsbl.org.
+photos-d.ak.fbcdn.net.
+www.videowish.com.
+catalysteval.com.
+a1515.phobos.apple.com.
+www.ewg.org.
+babybook.91.com.
+www.leecooperjeans.com.
+a.root-servers.net.
+hpw.com.s5a1.psmtp.com.
+itunes.apple.com.
+getmail.no.
+10.mal.de.dos.free.fr.
+37.12.137.187.in-addr.arpa.
+www.knightrideronline.com.
+google.com.
+114.38.173.190.in-addr.arpa.
+badoo.com.
+mgmt.beta.toolbar.msn.com.
+yahoo.co.in.
+mt0.google.com.
+1.bp.blogspot.com.
+steviadolce.com.py.
+isatap.home.
+a8.sphotos.ak.fbcdn.net.
+profile.ak.fbcdn.net.
+photos-c.ak.fbcdn.net.
+loading4.widdit.com.
+googleads.g.doubleclick.net.
+www.despegar.com.ar.
+bdrco.com.
+www.mosquelife.com.
+www.hotgirlstoys.com.
+waterwatcher.net.
+a4.sphotos.ak.fbcdn.net.
+aixpanish.com.
+cf.kampyle.com.
+cache.adm.cnzz.net.
+119.217.119.174.in-addr.arpa.
+productos.weboperador.com.ar.
+su.pctools.com.
+8.150.57.187.in-addr.arpa.
+16-courier.push.apple.com.
+mail.sfsustudentcenter.com.
+titanium30-en.url.trendmicro.com.
+stgeorges.org.nz.
+www.raunchygfs.com.
+a591.da2.akamai.net.
+_325_10_8.
+aasp.net.
+external.ak.fbcdn.net.
+profile.ak.fbcdn.net.
+cust5812-1.in.mailcontrol.com.
+sexymalecelebrities.blogspot.com.
+e5237.g.akamaiedge.net.
+i4.ytimg.com.
+www.adobe.com.
+fengnet.com.
+a.root-servers.net.
+a.root-servers.net.
+interactive.rogers.com.
+0.244.115.186.in-addr.arpa.
+33.42.4.181.in-addr.arpa.
+www.maplegrovebarefootguy.com.
+pcdirectbiz.com.
+s0.2mdn.net.
+152.237.253.190.in-addr.arpa.
+guido.kcumb.edu.
+www.cfnmguide.com.
+psb.state.in.us.
+hinsay.com.
+csi.gstatic.com.
+www.makecitation.com.
+www.google.com.
+instagram.com.
+mscrl.microsoft.com.
+moycomputer.ru.
+33.54.78.201.in-addr.arpa.
+cjgarland.com.
+www.links4vids.com.
+safebrowsing.clients.google.com.
+m1.mx.km.ru.
+teredo.ipv6.microsoft.com.
+ksn2-12.kaspersky-labs.com.
+smtp.live.com.
+a5.sphotos.ak.fbcdn.net.
+107.43.150.46.in-addr.arpa.
+143.166.125.86.in-addr.arpa.
+rosems.culligan.com.
+cdn.fastclick.net.
+sp.cwfservice.net.
+hitachisoftware.ru.
+mx.youtube.com.
+gbc.net.
+a749.g.akamai.net.
+bmsismtp03.bmsi.a-star.edu.sg.
+s1-onenote.vo.msecnd.net.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+api.facebook.com.
+update.utorrent.com.
+switchboard.real.com.
+www.applifier.com.
+arriva.ch.
+www.vallarta.com.mx.
+redstarenergy.net.
+fastspeedtest.com.
+93.39.122.190.in-addr.arpa.
+samet-russia.ru.
+code.google.com.
+106.176.66.201.in-addr.arpa.
+www.resourcesforlife.com.
+sp.cwfservice.net.
+netaddess.org.
+robgijsberts.com.
+b._dns-sd._udp.0.0.168.192.in-addr.arpa.
+47.1.168.192.in-addr.arpa.
+clients1.google.com.
+graph.facebook.com.
+7sov1arhz.13tf.
+fr-fr.facebook.com.
+245.102.55.157.in-addr.arpa.
+www.arthurgarrosmusic.com.
+www.envioscristianos.com.
+56.236.201.190.in-addr.arpa.
+eteria.net.
+free3dstuff.net.
+94.58.21.62.in-addr.arpa.
+www.cellappsite.com.
+s.ytimg.com.
+evrokam.ru.
+ladywankenobi.tumblr.com.
+dtboot.orbitdownloader.com.
+146.57.50.190.in-addr.arpa.
+153.178.153.187.in-addr.arpa.
+gazsvyaz.ru.
+dns.msftncsi.com.
+robertdice.com.
+www.facebook.com.
+aresbykes.com.
+45.52.246.24.in-addr.arpa.
+socpixel.bidsystem.com.
+orcart.facebook.com.
+bl127w.blu127.mail.live.com.
+www.youtube.com.
+google.com.
+5ced.com.
+sl.iciba.com.
+us.fluke.com.
+s-static.ak.facebook.com.
+www.mlr360.com.
+www.gstatic.com.
+ingrealestate.co.uk.
+a.root-servers.net.
+apps.facebook.com.
+elithetrader.com.
+ifpexpo.com.
+a2.sphotos.ak.fbcdn.net.
+www.quienignora.com.
+inbound.fsro.net.netsolmail.net.
+www.ohso.co.
+sn2files.storage.msn.com.
+a761.phobos.apple.com.
+cnt.tuberwyn.com.
+www.cpdftraining.org.
+jers2.info.
+gfx3.hotmail.com.
+c.prodigy.msn.com.
+www.facebook.com.
+a.root-servers.net.
+237.23.95.59.in-addr.arpa.
+a6.sphotos.ak.fbcdn.net.
+rd.rlcdn.com.
+a3.sphotos.ak.fbcdn.net.
+141.159.222.201.in-addr.arpa.
+epsovirtual.umh.es.
+thenewgeneration.foroactivo.com.
+mail.softbal.com.
+mci.savetrees.com.
+s0.2mdn.net.
+teredo.ipv6.microsoft.com.
+ayudaparamiweb.com.
+218.22.105.190.in-addr.arpa.
+ad.yieldmanager.com.
+a.ads2.msads.net.
+134.90.88.186.in-addr.arpa.
+townofluray.com.
+thesaturnalia.com.
+213.241.143.187.in-addr.arpa.
+www.google.com.
+www.mccordweb.com.
+1.pool.ntp.org.
+pmx5.unina.it.
+tap2-cdn.rubiconproject.com.
+zh-cn.facebook.com.
+www.oberholtzer-creative.com.
+207.205.71.190.in-addr.arpa.
+fbcdn-profile-a.akamaihd.net.
+blog.taguin.com.
+a2.sphotos.ak.fbcdn.net.
+google.com.
+rospres.com.
+www.adventuresinexpatland.com.
+221.101.113.189.in-addr.arpa.
+enyce.com.
+a2.sphotos.ak.fbcdn.net.
+external.ak.fbcdn.net.
+98.4.205.190.in-addr.arpa.
+www9.effectivemeasure.net.
+pandorafb2.dk.
+lyonsautobody.com.
+157.4.55.67.in-addr.arpa.
+nr.myhost.ru.
+www.microsofttranslator.com.
+rizalmanibrahim.blogspot.com.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+google.com.
+lh6.ggpht.com.
+news.google.com.mx.
+www.coalitionofresistance.org.uk.
+206.54.115.186.in-addr.arpa.
+171.112.47.189.in-addr.arpa.
+a3.mzstatic.com.
+mtmi.net.
+32.125.17.31.in-addr.arpa.
+19.8.17.177.in-addr.arpa.
+s-external.ak.fbcdn.net.
+22.210.13.189.in-addr.arpa.
+evolutionworld.ru.
+a3.sphotos.ak.fbcdn.net.
+m.ak.fbcdn.net.
+pagead2.googlesyndication.com.
+actorguide.org.
+photos-d.ak.fbcdn.net.
+200.126.247.190.in-addr.arpa.
+i4.ytimg.com.
+www.marsrecruitment.com.au.
+pixel.facebook.com.
+htcmovilperu.com.
+apps.facebook.com.
+www.mindmapper.com.
+friendscot.fsnet.co.uk.
+college.harvard.edu.
+mail.google.com.
+sahil-tech.blogspot.com.
+local-sn.contacts.msn.com.
+star.facebook.com.
+www.facebook.com.
+machens.com.
+www.google.com.
+content.yieldmanager.edgesuite.net.
+wxdata.weather.com.
+waykiria.hacerforos.com.
+bl159w.blu159.mail.live.com.
+247.113.103.2.in-addr.arpa.
+ns.sympatico.ca.
+wuntvor.pillar.com.
+www.eprensa.info.
+www.google.com.
+sfr.fr.
+mailproxy.durmusoglu.de.
+laurierelectric.ca.
+ns3.afroasia.ru.
+ganarporinternet.es.
+124.110.193.200.in-addr.arpa.
+67.165.48.190.in-addr.arpa.
+static.ak.fbcdn.net.
+8.62.222.189.in-addr.arpa.
+98.119.59.186.in-addr.arpa.
+photos-f.ak.fbcdn.net.
+140.96.84.188.in-addr.arpa.
+18-courier.push.apple.com.
+rxhub.com.
+dreamers1.com.
+www.juegosdcocina.com.
+images.redflagdeals.com.
+38.147.220.66.in-addr.arpa.
+mx10.comparex-group.com.
+photos-d.ak.fbcdn.net.
+cs6083.vkontakte.ru.
+www.australia-alternativa.com.
+a3.sphotos.ak.fbcdn.net.
+k-swiss.com.s10b2.psmtp.com.
+apis.google.com.
+toorgle.com.
+r.mzstatic.com.
+www.facebook.com.
+b._dns-sd._udp.0.1.168.192.in-addr.arpa.
+b._dns-sd._udp.0.55.211.10.in-addr.arpa.
+mail.nisursystems.com.
+s-static.ak.facebook.com.
+mail2.tcu.edu.tw.
+108.214.176.190.in-addr.arpa.
+translate.google.com.
+finance.google.com.
+search.twitter.com.
+img4-fotki.yandex.net.
+www.centcom.mil.
+129.205.53.70.in-addr.arpa.
+113.134.67.108.in-addr.arpa.
+mail.kwrtools.com.
+0-jf-w.channel.facebook.com.
+ircai.files.wordpress.com.
+_ldap._tcp.
+mail.lebelier.com.
+videopeeg.wordpress.com.
+mailbox.riga.lv.
+a4.sphotos.ak.fbcdn.net.
+serv.vip.qiyi.com.
+duscholux.de.
+x-developer.ru.
+13.203.221.190.in-addr.arpa.
+1.0.0.127.dnsbugtest.1.0.0.127.in-addr.arpa.
+external.ak.fbcdn.net.
+www.iceage3.es.
+secure.wlxrs.com.
+.
+dns.msftncsi.com.
+iolfree.net.
+www.marcelamosca.com.ar.
+www.fuedin.org.
+ksn4.kaspersky-labs.com.
+15.236.245.189.in-addr.arpa.
+www.facebook.com.
+cmap.dc.ace.advertising.com.
+.
+cm.g.doubleclick.net.
+aleluya.com.
+valleysystem.com.
+s0.2mdn.net.
+cnavideo.cna.com.tw.
+api.facebook.com.
+en.wikipedia.org.
+klty.com.s7a1.psmtp.com.
+horoscopo.msn.es.
+angusbarn.com.s7a1.psmtp.com.
+elegantwooddesign.com.
+29.126.100.190.in-addr.arpa.
+estheticcore.com.
+66.13.248.190.in-addr.arpa.
+208.33.89.187.in-addr.arpa.
+apple.imap.mail.yahoo.com.
+27-courier.push.apple.com.
+a.root-servers.net.
+3l2ktck58.w08e9t2w.
+a1.sphotos.ak.fbcdn.net.
+a.root-servers.net.
+ecn.t2.tiles.virtualearth.net.
+pt-br.facebook.com.
+a.root-servers.net.
+196.45.168.189.in-addr.arpa.
+202.124.149.186.in-addr.arpa.
+ny01sec007.mhc.mhc.
+2.6.3.188.in-addr.arpa.
+marv.mediatti.net.
+ib.adnxs.com.
+.
+www.kyu-jong.com.
+www.elizabethperry.com.
+www.chinesedragon.org.
+www.coet.es.
+sl.srcs.k12.ca.us.
+usctap3132.amer.schp.com.
+sudddenlink.net.
+profile.ak.fbcdn.net.
+www.google.com.
+166.10.168.192.in-addr.arpa.
+appleghost.deviantart.com.
+platform.twitter.com.
+external.clearchannel.com.
+185.176.88.186.in-addr.arpa.
+three-lakes.org.
+olivus.com.
+ad.yieldmanager.com.
+sonyla.112.2o7.net.
+static.ak.fbcdn.net.
+a.c-0.19-270f1000.c8b0091.1518.19b2.410a.400.9d.digvq3kjc8aazhra2vgn3zbigb.avqs.mcafee.com.
+ptc68.com.
+abycom.com.
+almojilgroup.com.
+people.iola.dk.
+photos6.pop6.com.
+205.212.142.190.in-addr.arpa.
+216.135.32.114.in-addr.arpa.
+e3821.c.akamaiedge.net.
+nogu.net.
+24.236.184.187.in-addr.arpa.
+99.152.104.187.in-addr.arpa.
+a4.sphotos.ak.fbcdn.net.
+ar.msn.com.
+fuelly.com.
+18.163.71.109.in-addr.arpa.
+photos-b.ak.fbcdn.net.
+www.extremetube.com.
+m9exek:8f.j81a0l0i.
+intfrog.com.
+payrollnetwork.com.pri-mx.na0100.smtproutes.com.
+pop.linkservice.cl.
+a2.sphotos.ak.fbcdn.net.
+graph.facebook.com.
+251.249.179.118.in-addr.arpa.
+api.twitter.com.
+platform.ak.fbcdn.net.
+www.facebook.com.
+24.85.88.186.in-addr.arpa.
+hanusch.de.
+udc.msn.com.
+yahoo.com.
+download.windowsupdate.com.
+s-static.ak.fbcdn.net.
+bsf-01.sonnit.dk.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+cdn.cpmstar.com.
+mtalk.google.com.
+136.16.118.200.in-addr.arpa.
+injesus.com.
+www.facebook.com.
+rcp.eu.blackberry.com.
+www.acousticmagazine.com.
+philwest.net.
+118.24.184.201.in-addr.arpa.
+t2.gstatic.com.
+148.147.82.200.in-addr.arpa.
+www.google.com.mx.
+www.usabledomainname.com.
+d2058628.instant.xoom.it.
+profile.ak.fbcdn.net.
+82.137.164.187.in-addr.arpa.
+photos-e.ak.fbcdn.net.
+fbcdn-photos-a.akamaihd.net.
+secure.gravatar.com.
+sp.cwfservice.net.
+drm.mail.universal-music-services.de.
+trebaruna-lacocinademaria.blogspot.com.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+cn1.redswoosh.akadns.net.
+a1108.da1.akamai.net.
+www.estadionacional.com.pa.
+a7.sphotos.ak.fbcdn.net.
+17.106.36.177.in-addr.arpa.
+t2.gstatic.com.
+platform.twitter.com.
+ajax.googleapis.com.
+www.justasiansluts.com.
+g.msn.es.
+6.99.19.46.in-addr.arpa.
+mail.penza-gorod.ru.
+200.108.145.89.in-addr.arpa.
+support.google.com.
+ns1.serverdns9.net.ru.
+fxfeeds.mozilla.com.
+www.google.com.
+time.chttl.com.tw.
+159.49.54.65.in-addr.arpa.
+www.xatech.com.
+167.101.179.190.in-addr.arpa.
+api.facebook.com.
+taoyt.ru.
+a.root-servers.net.
+b._dns-sd._udp.0.1.168.192.in-addr.arpa.
+trans-p2p.pandora.tv.
+photos-a.ak.fbcdn.net.
+spiderbites.about.com.
+www.adobe.com.
+ylxfavku5.49bm.
+dns.msftncsi.com.
+alumni.academyart.edu.
+fxfeeds.mozilla.com.
+developers.facebook.com.
+heritagebankofcommerce.com.
+s-static.ak.facebook.com.
+news.google.com.mx.
+images04.olx.com.
+videochat.sadismoxxx.com.
+gfx4.hotmail.com.
+a5.sphotos.ak.fbcdn.net.
+fr-fr.facebook.com.
+216.45.130.189.in-addr.arpa.
+vtaig.com.
+vywl6mish.28wx.
+digini.com.
+partners.poa.com.
+mystery-case-files-huntsville.softonic.com.
+mxproc.iseek.com.au.
+weather.wdtinc.com.
+ja-jp.facebook.com.
+233.7.249.189.in-addr.arpa.
+a.root-servers.net.
+116.59.34.212.in-addr.arpa.
+s430.photobucket.com.
+apps.facebook.com.
+russiansilver.ru.
+dc265.4shared.com.
+i2.ytimg.com.
+wp.bingvision.ar.glbdns.microsoft.com.
+utmtrk9.apn.ask.com.
+72.32.214.121.in-addr.arpa.
+static.ak.fbcdn.net.
+187.123.172.186.in-addr.arpa.
+developers.facebook.com.
+vn61ka3ch.p80m8q3l.
+spacm1.spac.spc.com.
+virtuosasetalentosas.blogspot.com.
+www.nissanplatina.com.mx.
+30.193.140.175.in-addr.arpa.
+s-static.ak.fbcdn.net.
+ns2.sparknet.net.
+assets.hi5.com.
+a6.sphotos.ak.fbcdn.net.
+s-static.ak.fbcdn.net.
+www.google.com.
+api.zynga.com.
+yahoo.com.
+blackfolkshair.net.
+mail.shogun.kiev.ua.
+a.root-servers.net.
+magicard.ru.
+b._dns-sd._udp.0.1.168.192.in-addr.arpa.
+a.root-servers.net.
+searchclient.live.net.
+tx61opmwf.56lq.
+34.42.143.94.in-addr.arpa.
+158.77.123.189.in-addr.arpa.
+msc.wlxrs.com.
+e-items.com.
+58.10.173.190.in-addr.arpa.
+pixel.facebook.com.
+evsecure-ocsp.verisign.com.
+apis.google.com.
+a.root-servers.net.
+l.yimg.com.
+i2.ytimg.com.
+www.eluniversaldf.mx.
+www.chinamextrading.com.
+44.99.9.69.in-addr.arpa.
+ocsp.thawte.com.
+smtpmoko.sensoplan.com.
+static.ak.fbcdn.net.
+ars.oscar.aol.com.
+titanium30-en.url.trendmicro.com.
+submitworld.com.
+fcu.edu.
+g.microsoft.com.
+a.root-servers.net.
+banners3.spacash.com.
+zip.rincondelvago.com.
+a6.sphotos.ak.fbcdn.net.
+195.113.232.190.in-addr.arpa.
+fondos-de-crepusculo.softonic.com.
+penn.museum.
+it-it.facebook.com.
+galleries2.adult-empire.com.
+www.homeopatia-si.es.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+www.ucgs.com.ar.
+www.michaelpage.co.za.
+.
+adfarm.mediaplex.com.
+a.root-servers.net.
+dsn10.d.skype.net.
+adpgs9-bond0-3.jagex.com.
+ns2.tmag.de.
+bs.wikipedia.org.
+photos-f.ak.fbcdn.net.
+wyndhamworldwide.com.s8b2.psmtp.com.
+external.ak.fbcdn.net.
+a8.sphotos.ak.fbcdn.net.
+cs5590.vkontakte.ru.
+heybubbles.blogspot.com.
+wellsforgo.com.
+cs.wikipedia.org.
+webcache.googleusercontent.com.
+www.google.com.
+xm5oznl1b.g66h4b1o.
+s.youtube.com.
+vefwefwl1.65qk.
+i1.ytimg.com.
+warmingglow.uproxx.netdna-cdn.com.
+47.75.45.190.in-addr.arpa.
+dbcs1.htc.com.
+cdn.wibiya.com.
+belltowercourtyard.com.
+a-0.19-22097089.c030082.1518.19d3.3ea1.210.0.4bsgrcqmg7g9sjl34dbjsln36i.avqs.mcafee.com.
+summergirlz.net.
+evsecure-ocsp.verisign.com.
+s.ytimg.com.
+6-courier.push.apple.com.
+a6.sphotos.ak.fbcdn.net.
+external.ak.fbcdn.net.
+a.root-servers.net.
+www.grupoandroid.com.
+a7.sphotos.ak.fbcdn.net.
+bintobottle.com.
+www.topcydiaapps.com.
+teredo.ipv6.microsoft.com.
+22.22.191.79.in-addr.arpa.
+nevada.unr.edu.
+spanish.dictionary.com.
+xmsecu.com.
+carrerasdemontana.wordpress.com.
+www-cctld.l.google.com.
+s0.2mdn.net.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+133.85.74.75.in-addr.arpa.
+112.69.220.95.in-addr.arpa.
+cvssystems.com.
+www.esurance.com.
+media2.myfoxny.com.
+s1-powerpoint.vo.msecnd.net.
+g4nij4dce.q65m4p1a.
+xmest.ru.
+157.20.139.190.in-addr.arpa.
+253.111.146.189.in-addr.arpa.
+img32.imageshack.us.
+www.dustloop.com.
+cdn.api.twitter.com.
+city.kherson.ua.
+api.twitter.com.
+inentertainment.disqus.com.
+xlab-0.ed.ac.uk.
+dawgbusiness.blogspot.com.
+miriamyeung.com.tw.
+s-static.ak.fbcdn.net.
+214.239.29.190.in-addr.arpa.
+www.attractivemoms.com.
+127.128.77.77.in-addr.arpa.
+a6.sphotos.ak.fbcdn.net.
+22.58.16.75.in-addr.arpa.
+aljazeera.net.
+94.219.111.189.in-addr.arpa.
+vexcorp.com.
+45.211.42.181.in-addr.arpa.
+249.146.84.188.in-addr.arpa.
+a995.mm1.akamai.net.
+183.84.149.187.in-addr.arpa.
+www.facebook.com.
+ksn1-11-part2.kaspersky-labs.com.
+nds2.nokia.com.
+159.106.45.190.in-addr.arpa.
+www.facebook.com.
+170.160.85.209.in-addr.arpa.
+static.ak.facebook.com.
+100.146.220.66.in-addr.arpa.
+download349.avast.com.
+origin-sp.ask.com.
+santander.cz.
+zonavi.com.
+apps.facebook.com.
+16.0.0.10.in-addr.arpa.
+www.coffeybuzz.com.
+xbzsjhgf7.62dp.
+fbcdn-photos-a.akamaihd.net.
+profile.ak.fbcdn.net.
+traductor.babylon.com.
+paloaltoinc.com.
+goku.brightcove.com.
+33.152.78.186.in-addr.arpa.
+by2msg4010509.gateway.messenger.live.com.
+emka.info.
+static.ak.fbcdn.net.
+cvtrucking.com.
+profile.ak.fbcdn.net.
+www.youtube.com.
+blog.myfuncards.com.
+photos-c.ak.fbcdn.net.
+118.97.1.181.in-addr.arpa.
+fbcdn-photos-a.akamaihd.net.
+lv.wikipedia.org.
+b-0.19-2109d809.5c0.1518.19d4.3ea1.410.0.dspijfrbvp4pa13bjgir5n38l6.avqs.mcafee.com.
+external.ak.fbcdn.net.
+218.85.57.187.in-addr.arpa.
+medicalblog.info.
+175.102.16.186.in-addr.arpa.
+styx.aw.net.
+r._dns-sd._udp.0.0.168.192.in-addr.arpa.
+shared.live.com.
+141.212.222.201.in-addr.arpa.
+i4.ytimg.com.
+relink.net.
+profile.ak.fbcdn.net.
+netvogator.com.
+mail2.agsworld.com.
+sites.google.com.
+93.224.191.79.in-addr.arpa.
+dsiserver.daystarsills.com.
+www.proargentina.gov.ar.
+s3.amazonaws.com.
+epix.xbox.com.
+livelifehappy.com.
+secure.shared.live.com.
+rookiemag.com.
+external.ak.fbcdn.net.
+mail.livotour.ru.
+th605.photobucket.com.
+orcart.facebook.com.
+demakova.net.
+configuration.apple.com.
+ldsqoigrp.l46s6s1m.
+idi-online.com.
+www.websitevaluebot.com.
+a2.sphotos.ak.fbcdn.net.
+yargroup.ru.
+www.oynabitir.com.
+photos-f.ak.fbcdn.net.
+lordkat.com.
+us.bc.yahoo.com.
+www.gillbreathing.com.
+a1.sphotos.ak.fbcdn.net.
+static.ak.fbcdn.net.
+h.live.com.
+photos-b.ak.fbcdn.net.
+www.largodrive.com.
+www.facebook.com.
+audiblox.com.
+183.24.92.186.in-addr.arpa.
+a.root-servers.net.
+medals.moshimonsters.com.
+asktoolbar.weather.com.
+profile.ak.fbcdn.net.
+l.betrad.com.
+mob.adwhirl.com.
+205.241.74.190.in-addr.arpa.
+i4.ytimg.com.
+bannerassets.universalstudios.com.
+g.microsoft.com.
+26.250.158.189.in-addr.arpa.
+6-courier.push.apple.com.
+pool.ntp.org.
+14pbzarqh.16xr.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+mx.nrgsys.it.
+www.salsas.com.au.
+latinworks.com.
+www.socialgrowthtechnologies.com.
+www.bing.com.
+u20.eset.com.
+www.ftdimarketplace.com.
+luisaalexandramarques.blogspot.com.
+www.17tahun.com.
+www.majalisna.com.
+83.58.250.201.in-addr.arpa.
+multi76.thumb.edenflirt.com.
+5.38.168.192.in-addr.arpa.
+masholdings.com.
+s7.addthis.com.
+www.hardfest.com.
+wqlt5kt8b.h41d4z5a.
+185.132.174.118.in-addr.arpa.
+mail.isure.ca.
+www.sarayacdn.com.
+102.20.38.190.in-addr.arpa.
+84.112.240.189.in-addr.arpa.
+246.161.10.186.in-addr.arpa.
+eymuaqjzd20otpsfypymsjuirhxgud10nx.ru.
+ad.yieldads.com.
+159.140.237.87.in-addr.arpa.
+ax.init.itunes.apple.com.
+inbound.orionpress.com.netsolmail.net.
+gqepy2rg2.t33f2k3e.
+a5.sphotos.ak.fbcdn.net.
+img1.artron.net.
+login.toolbar.conduit-services.com.
+orlandoluispardolazo.blogspot.com.
+accounts.google.com.
+photos-e.ak.fbcdn.net.
+photos-a.ak.fbcdn.net.
+forumdocumentos.blogspot.com.
+localhost.
+mail.cyberriver.net.
+d2094137.xoom.it.
+googleads.g.doubleclick.net.
+www.dogbreedinfo.com.
+mail1.ci.methuen.ma.us.
+www.circsource.com.
+ediscovery.com.
+so.ie.sogou.com.
+i2.ytimg.com.
+ads.bluelithium.com.
+died.org.ru.
+hivhotline.ru.
+190.109.114.97.in-addr.arpa.
+pech.elektra.ru.
+coneltiempoenmisbrazos.blogspot.com.
+yahoo.com.
+i3.ytimg.com.
+reztec.ru.
+svrintl-g3-crl.verisign.com.
+91.178.81.82.in-addr.arpa.
+228.235.116.93.in-addr.arpa.
+232.87.232.190.in-addr.arpa.
+academy.shoplocal.com.
+a.root-servers.net.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+maps.gstatic.com.
+api.zynga.com.
+55.15.194.190.in-addr.arpa.
+www.kci-world.com.
+40.7.223.201.in-addr.arpa.
+www.nuevodiarioweb.com.ar.
+img121.imageshack.us.
+36.74.42.114.in-addr.arpa.
+mail.
+www.facebook.com.
+s-static.ak.facebook.com.
+a.root-servers.net.
+156.176.92.91.in-addr.arpa.
+udc.msn.com.
+www.twitter.com.
+103.205.144.79.in-addr.arpa.
+filmin.ru.
+clients1.google.com.
+a5.sphotos.ak.fbcdn.net.
+sjbbs.pchome.net.
+a.root-servers.net.
+_470_27_6.
+i.promecal.es.
+7dslqccti.92aa.
+www.cucs.udg.mx.
+157.24.131.187.in-addr.arpa.
+api.twitter.com.
+m.addthisedge.com.
+safebrowsing.clients.google.com.
+land66.ru.
+mx2.bloodservices.ca.
+169.172.21.182.in-addr.arpa.
+74.186.222.203.in-addr.arpa.
+82peunix2.92qo.
+v1.cache8.c.youtube.com.
+stedbobleabarr.tk.
+db._dns-sd._udp.0.1.168.192.in-addr.arpa.
+www.carlsberggroup.com.
+www.kamusi.org.
+caruffo.com.
+mx.wrs.yahoo.com.
+unix.horizontes.com.
+couponbuddy.s3.amazonaws.com.
+www.delawaz.com.
+www.maquillajeojos.net.
+www.batman-on-film.com.
+clients2.google.com.
+photos-g.ak.fbcdn.net.
+www.facebook.com.
+pastpresenfuture.net.
+a.root-servers.net.
+netjetseurope.ru.
+www.pressafrik.com.
+www.deportesblog.es.
+1.0.0.127.dnsbugtest.1.0.0.127.in-addr.arpa.
+lb._dns-sd._udp.lan.
+i3.ytimg.com.
+fbcdn-photos-a.akamaihd.net.
+connect.facebook.net.
+73.228.247.190.in-addr.arpa.
+jendiab.plusnet.com.
+cust20986-1.in.mailcontrol.com.
+eq4opeahl.94hq.
+www.facebook.com.
+a.root-servers.net.
+i3.ytimg.com.
+antibiotix1.net-cube.net.
+mitecnologico.com.
+bet.iba.org.il.
+teredo.ipv6.microsoft.com.
+a.root-servers.net.
+static.ak.fbcdn.net.
+gsmtp.gatewaycc.edu.
+ladys.su.
+photos-e.ak.fbcdn.net.
+eksmo-sale.ru.
+dr._dns-sd._udp.lan.
+songid.play.it.
+volgogradenergo.ru.
+www.usemod.com.
+160.46.75.187.in-addr.arpa.
+s-static.ak.facebook.com.
+accounts.google.com.
+bea4.v.fwmrm.net.
+healthbridgefitness.com.s8a1.psmtp.com.
+pridehealth.com.
+27.172.174.190.in-addr.arpa.
+a3.sphotos.ak.fbcdn.net.
+partner.googleadservices.com.
+0-161.channel.facebook.com.
+mymonthlycycles.com.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+maribeluxi.blogspot.com.
+www.memeadictos.tumblr.com.
+183.55.251.189.in-addr.arpa.
+207.168.168.192.in-addr.arpa.
+tiflocomp.net.ru.
+92.184.136.186.in-addr.arpa.
+www.mixpod.com.
+sp.cwfservice.net.
+i3.ytimg.com.
+royaldecree.bigcartel.com.
+melonball.com.
+secure.wlxrs.com.
+www.ipodarchive.com.
+i.ytimg.com.
+.
+a7.sphotos.ak.fbcdn.net.
+www.movistar.com.co.
+www.youtube.com.
+i2.ytimg.com.
+238.184.13.186.in-addr.arpa.
+www.gmodules.com.
+a1.sphotos.ak.fbcdn.net.
+a1907.w7.akamai.net.
+www.kaspersky.com.
+196.146.34.187.in-addr.arpa.
+distilleryimage3.instagram.com.
+api.facebook.com.
+a8.sphotos.ak.fbcdn.net.
+heraldicasaltena.blogspot.com.
+google.com.
+daxstudios.net.
+static.ak.fbcdn.net.
+www.muchacarne.com.
+a.root-servers.net.
+www.webuzzapp.com.
+28.37.89.186.in-addr.arpa.
+74.198.24.201.in-addr.arpa.
+146.42.60.187.in-addr.arpa.
+montser.com.
+203.16.249.78.in-addr.arpa.
+www.natashasnylons.com.
+www.unac.edu.pe.
+veneconomia.com.
+profile.ak.fbcdn.net.
+85.200.244.88.in-addr.arpa.
+182.248.43.92.in-addr.arpa.
+1804289383.localhost.
+233.25.131.187.in-addr.arpa.
+instrument52.ru.
+www.cwa2222.org.
+150.90.13.75.in-addr.arpa.
+mail.papalote.org.mx.
+maximum-leverage.s3.amazonaws.com.
+a-0.19-a30f3081.90e0581.1518.19d4.3ea1.210.0.a7c3cqnnkpvzvcusnnb84wzp25.avqs.mcafee.com.
+photos-e.ak.fbcdn.net.
+.
+160.5.145.93.in-addr.arpa.
+rubhim.hugescock.com.
+168.144.110.84.in-addr.arpa.
+www-akm.imvu.com.
+_225_68_1.
+v3r2qhhdm.k58e5c9j.
+external.ak.fbcdn.net.
+_ldap._tcp.
+cartoon.iguw.tuwien.ac.at.
+ntlworld.com.
+www.oppuz.com.
+1.0.0.127.dnsbugtest.1.0.0.127.in-addr.arpa.
+paris.lachainemeteo.com.
+photos-d.ak.fbcdn.net.
+235.178.10.187.in-addr.arpa.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+www.facebook.com.
+mtkmobile.ru.
+adserver.bcfads.com.
+search.cnki.net.
+160.211.23.186.in-addr.arpa.
+plus.google.com.
+www.facebook.com.
+a8.sphotos.ak.fbcdn.net.
+pimail.pi-isd.net.
+228.112.145.201.in-addr.arpa.
+a2.sphotos.ak.fbcdn.net.
+time.windows.com.
+cdn.loading321.com.
+www.klubskascena.com.
+sump.uniblue.com.s3.amazonaws.com.
+elsignodelostiempos.blogspot.com.
+pop3.hot.glbdns.microsoft.com.
+a.root-servers.net.
+api.facebook.com.
+citiintl.122.2o7.net.
+horosta.ru.
+www.slotmachines1.com.
+elderdemolition.com.inbound15.mxlogic.net.
+stroykey.ru.
+183.8.22.113.in-addr.arpa.
+a6.sphotos.ak.fbcdn.net.
+spanish.alibaba.com.
+157.96.16.177.in-addr.arpa.
+www.google-analytics.com.
+62.25.184.201.in-addr.arpa.
+nm8cjds19.06it.
+fr-fr.facebook.com.
+mail.satisfacts.com.
+a34.g.akamai.net.
+aktelux.com.
+www.usacoinbook.com.
+a.root-servers.net.
+i3.ytimg.com.
+www.proklamieren.de.
+www.enlace.sep.gob.mx.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+streamate.doublepimp.com.
+us.camfed.org.
+crl.globalsign.net.
+226.140.237.189.in-addr.arpa.
+www.staatsdruckerei.at.
+147.86.111.118.in-addr.arpa.
+i3.photobucket.com.
+\(none\).
+tns-mi.com.s200a2.psmtp.com.
+fxyi:pviv.e17r1d7z.
+www.christiananime.net.
+runbox.com.
+239.32.76.84.in-addr.arpa.
+a151.d.akamai.net.
+218.220.131.187.in-addr.arpa.
+a.root-servers.net.
+auto.mercadolibre.com.mx.
+enter.brazzerspass.com.
+bonellmfg.com.
+b._dns-sd._udp.0.1.168.192.in-addr.arpa.
+42.media.v4.skyrock.net.
+secure.localbillinglimited.com.
+img100.xvideos.com.
+auro.de.
+minipanel.qq.com.
+a3.mzstatic.com.
+schonerttile.com.
+thepattinsonproject.files.wordpress.com.
+google.com.
+a4.sphotos.ak.fbcdn.net.
+clients2.google.com.
+smtp.bcgassets.com.
+0.6171754.com.
+36.95.138.190.in-addr.arpa.
+i2.ytimg.com.
+s-external.ak.fbcdn.net.
+investfinancial.com.
+windows.download.hn.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+www.narutomanga.tk3.net.
+1.bp.blogspot.com.
+testdrive.apc.com.
+154.81.211.108.in-addr.arpa.
+www.edressme.com.
+www.youtube.com.
+partner37.mydomainadvisor.com.
+i3.ytimg.com.
+stats.jtvnw.net.
+30.23.168.189.in-addr.arpa.
+api.yontoo.com.
+252.9.10.186.in-addr.arpa.
+barracuda.lrcr.com.
+static.ak.fbcdn.net.
+219.213.25.201.in-addr.arpa.
+megusta.followland.com.
+crl3.digicert.com.
+dnl-13.geo.kaspersky.com.
+.
+www.facebook.com.
+healthcare-automations.com.
+skerneskopdo.mp.
+tracker.reprobate.se.
+leftwich.com.
+lo.wikipedia.org.
+sbcgoldal.net.
+willbear.com.
+clients1.google.com.
+servedby.adxpose.com.
+ad-g.doubleclick.net.
+kupinakleyki.ru.
+www.monografias.com.
+c13.zedo.com.
+t0.gstatic.com.
+101.9.168.192.in-addr.arpa.
+179.118.208.112.in-addr.arpa.
+static.editmysite.com.
+83.169.211.201.in-addr.arpa.
+www.aa.com.
+mx1.elektro.com.br.
+a.root-servers.net.
+diccionario.reverso.net.
+support.google.com.
+11.113.25.31.in-addr.arpa.
+u40.eset.com.
+124.193.232.109.in-addr.arpa.
+sngs.biz.
+a-0.19-2209b041.c010083.1518.19d3.3ea0.210.0.i9zvhvc5q66kz46p5713r2g3c6.avqs.mcafee.com.
+_396_31_4.
+pt-br.facebook.com.
+b.scorecardresearch.com.
+library.unt.edu.
+api.twitter.com.
+orcart.facebook.com.
+photos-b.ak.fbcdn.net.
+skylightpictures.com.
+a.root-servers.net.
+www.facebook.com.
+67.213.137.195.in-addr.arpa.
+android.clients.google.com.
+mail2.ebpoffice.net.
+www.dog-pictures.co.uk.
+portal.salud.gob.mx.
+developers.facebook.com.
+a-0.19-220f5081.9830081.1518.19d3.3ea1.200.0.1jpm1u6775pch7wi5lcncvkcl6.avqs.mcafee.com.
+time.chttl.com.tw.
+lists.chamilo.org.
+a.root-servers.net.
+google.com.
+yoga-ology.com.
+photos-a.ak.fbcdn.net.
+sp.cwfservice.net.
+216.44.159.189.in-addr.arpa.
+165.24.105.46.zz.countries.nerd.dk.
+www.google-analytics.com.
+photos-b.ak.fbcdn.net.
+www.google.com.
+aero.upm.es.
+intomega.ru.
+a3.sphotos.ak.fbcdn.net.
+unigrids.icm.edu.pl.
+ncswmf.com.
+www.ebay.com.
+a.root-servers.net.
+sticker.yadro.ru.
+93.230.222.189.in-addr.arpa.
+apps.facebook.com.
+pagead2.googlesyndication.com.
+www.allanaheimtours.com.
+ads.wicked.com.
+a.root-servers.net.
+tanner-informatik.ch.
+a.root-servers.net.
+www.youtube.com.
+aonetel.com.
+m8.house-mixes.com.
+a4.sphotos.ak.fbcdn.net.
+xtra.co.nz.
+pnwriders.com.
+176.169.78.187.in-addr.arpa.
+wholesale.alibaba.com.
+www.bleblenigi.miasta.pl.
+celebritybabies.people.com.
+pt-br.facebook.com.
+a.rad.msn.com.
+a3.sphotos.ak.fbcdn.net.
+_832_47_5.
+155.219.192.173.in-addr.arpa.
+c.learncodethehardway.org.
+dingtao333.3322.org.
+ssl.gstatic.com.
+mail.ru.
+94.7.219.62.in-addr.arpa.
+billing.sharo4ka.ru.
+facebook-sw.vo.llnwd.net.
+img204.imageshack.us.
+3.197.154.78.in-addr.arpa.
+wintertype101.blogspot.com.
+209.120.10.187.in-addr.arpa.
+mail.cascadetitlecompany.com.
+movinta.com.
+jumpy.it.
+www.facebook.com.
+thehawklovesyou.com.
+mypassionofficial.tumblr.com.
+www.tinkerbellcupcakes.com.
+ksn2-12.kaspersky-labs.com.
+bg.wikipedia.org.
+askville.amazon.com.
+180.144.22.201.in-addr.arpa.
+csi.gstatic.com.
+ir.ebaystatic.com.
+share-online.biz.
+251.110.189.72.in-addr.arpa.
+101.208.193.91.in-addr.arpa.
+pleated-jeans.com.
+ads2.msads.net.
+ksn3.kaspersky-labs.com.
+106.214.146.189.in-addr.arpa.
+axiomsmt.com.
+ns1.force9.net.
+3.223.124.220.in-addr.arpa.
+rbr-cards.ru.
+de-de.facebook.com.
+crazyquizs.com.
+fbcdn-profile-a.akamaihd.net.
+ads.us.e-planning.net.
+www.rakutenblog.jp.
+89wuyh3hn.d44g1q9s.
+lh5.googleusercontent.com.
+www.mobile24.com.
+www.adobe.com.
+js.microsoft.com.
+nextjam.blogspot.com.
+lbworks.com.
+134.182.84.89.in-addr.arpa.
+www.aadynd.org.ar.
+ntp.glb.nist.gov.
+8.192.8.201.in-addr.arpa.
+www.google-analytics.com.
+a3.twimg.com.
+lbc4nc.com.s9a1.psmtp.com.
+www2.twncs.com.
+a.analytics.yahoo.com.
+www.google.com.
+twitter.com.
+88.176.20.190.in-addr.arpa.
+ivfcenter.ru.
+cs504508.vkontakte.ru.
+ccbill.com.
+103.50.92.190.in-addr.arpa.
+drifting.chulojuegos.com.
+t-cartledge.com.
+widgets-lf.clearspring-lf.com.akadns.net.
+i.ytimg.com.
+static.ak.fbcdn.net.
+m.addthisedge.com.
+ksn2-12.kaspersky-labs.com.
+photos-e.ak.fbcdn.net.
+profile.ak.fbcdn.net.
+photos-e.ak.fbcdn.net.
+30.196.109.200.in-addr.arpa.
+static.ak.fbcdn.net.
+79.34.104.186.in-addr.arpa.
+mailsrvr.libanpost.com.lb.
+training.cakephp.org.
+offsetti.com.
+www.bluntdelivery.com.
+www.histats.com.
+www.youtube.com.
+85.207.75.201.in-addr.arpa.
+www.mail-app.com.
+api.twitter.com.
+heritage-healthcare.com.s5a1.psmtp.com.
+103.53.0.123.in-addr.arpa.
+www.tux4kids.com.
+homain.com.
+57.148.58.201.in-addr.arpa.
+hytectelephone.com.inbound15.mxlogicmx.net.
+google.com.
+b-0.19-23092008.481.1518.19d3.3ea1.410.0.eigsnthbibb5sl1we17n13czpv.avqs.mcafee.com.
+niveud.com.
+mx.youtube.com.
+5syovpg5q.47hj.
+imvubling.com.
+mail.showcasemn.com.
+old.jurnalul.ro.
+medicalsupplycenter.com.
+200.41.94.200.in-addr.arpa.
+168.179.250.112.in-addr.arpa.
+apps.facebook.com.
+firstrealtybhg.com.
+a2.twimg.com.
+api.twitter.com.
+pt.veoh.com.
+static.ak.fbcdn.net.
+107.137.134.190.in-addr.arpa.
+a.root-servers.net.
+photos-g.ak.fbcdn.net.
+www.leerburg.com.
+_333_63_6.
+brightcove.vo.llnwd.net.
+join.bangedbytrannies.com.
+a.root-servers.net.
+9.224.152.189.in-addr.arpa.
+teredo.ipv6.microsoft.com.
+resources.contactlessnews.com.
+surftofind.com.
+www.pedaleachile.cl.
+udc.msn.com.
+aka-cdn-ns.adtech.de.
+196.187.137.190.in-addr.arpa.
+titanium30-en.url.trendmicro.com.
+www.iforex.ph.
+elmonoaullador.blogspot.es.
+promo.isharemycash.com.
+a.root-servers.net.
+chittenden.com.
+nske.ru.
+developers.facebook.com.
+www.localizador-telefonos-moviles-celulares-ringtones-movil-gsm-sms.com.
+9gag.com.
+teesvalleyarts.org.uk.
+feeds.feedburner.com.
+25.159.213.201.in-addr.arpa.
+10.110.103.201.in-addr.arpa.
+k.keyade.com.
+dns.msftncsi.com.
+52.65.202.98.in-addr.arpa.
+dnl-00.geo.kaspersky.com.
+pediatriaenlared.com.ar.
+googleads.g.doubleclick.net.
+www.google.com.
+185.212.191.186.in-addr.arpa.
+s60-store.ovi.com.
+www.ask.com.
+www.roninsolitario.es.
+hot-cam.en-vivo.es.
+sites.google.com.
+pr4.netatlantic.com.
+nobles.com.au.s9a2.psmtp.com.
+upload.facebook.com.
+static.ak.fbcdn.net.
+c4.zedo.com.
+31.77.224.189.in-addr.arpa.
+43.225.176.187.in-addr.arpa.
+poderyambiente.blogspot.com.
+adserver.gb5.motorpresse.de.
+creative.ak.fbcdn.net.
+ozzi.com.au.
+use.typekit.com.
+www.antsight.com.
+holdgruen.de.
+wbn.ru.
+50.192.82.200.in-addr.arpa.
+234.8.55.157.in-addr.arpa.
+budado.info.
+crl.geotrust.com.
+www.cucaboo.com.
+acmatcorp.com.inbound15.mxlogicmx.net.
+optonlinie.net.
+webmasters.tubewolf.com.
+mx.hftfund.com.
+a.root-servers.net.
+photos-c.ak.fbcdn.net.
+theabysmal.wordpress.com.
+teredo.ipv6.microsoft.com.
+a.root-servers.net.
+www.revolution-bars.co.uk.
+shadesofpa.com.
+magus.postgresql.org.
+.
+a172.w7.akamai.net.
+newsobserver.com.s8a1.psmtp.com.
+rvr.blogalia.com.
+a.root-servers.net.
+clients1.google.com.mx.
+a3.sphotos.ak.fbcdn.net.
+facebook.com.
+www.esearches.com.tw.
+43.201.3.196.in-addr.arpa.
+api.facebook.com.
+www.google.com.
+baptistretirement.org.inbound10.mxlogic.net.
+www.volta.alessandria.it.
+145.3.8.200.in-addr.arpa.
+worldblog.msnbc.msn.com.
+21.59.42.190.in-addr.arpa.
+209.246.53.83.in-addr.arpa.
+i.ytimg.com.
+dnl-01.geo.kaspersky.com.
+s.ytimg.com.
+kung-fu-panda-msn.programasgratis.es.
+hg.splayer.org.
+33.7.98.189.in-addr.arpa.
+a.root-servers.net.
+mintzfamily.com.
+123.103.205.190.in-addr.arpa.
+a.ads2.msads.net.
+8.46.13.190.in-addr.arpa.
+domino.ingo.com.ua.
+a7.sphotos.ak.fbcdn.net.
+www.ibima.org.
+evergreen-shipping.com.
+bluedogden.com.
+www.linkedin.com.
+plus.google.com.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+www.google.com.
+152.163.144.207.in-addr.arpa.
+commnat-cohort.ess.apple.com.akadns.net.
+a7.sphotos.ak.fbcdn.net.
+a-0.19-2109a801.d060083.1518.19d4.3ea1.410.0.spqabajtl54hfqk97s33alujnv.avqs.mcafee.com.
+225.103.95.190.in-addr.arpa.
+_311_78_5.
+a-0.19-230c8079.d160083.1518.19d4.3ea1.410.0.j8pw3bbzug8sm32di2bf42b4dq.avqs.mcafee.com.
+ksn2-12.kaspersky-labs.com.
+photos-g.ak.fbcdn.net.
+a.root-servers.net.
+freewareforus.com.
+meta.p2.color.com.
+a7.sphotos.ak.fbcdn.net.
+newsrss.bbc.co.uk.
+tc.v13.cache3.c.youtube.com.
+184.199.125.84.in-addr.arpa.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+193.61.58.186.in-addr.arpa.
+www.flashgalerie.com.
+rcp.na.blackberry.com.
+creative.ak.fbcdn.net.
+www.fantastigames.com.
+27.247.89.186.in-addr.arpa.
+115.194.179.187.in-addr.arpa.
+www.fgcuicehockey.com.
+utblive.com.
+fasgroup.ru.
+vyatskaya-matreshka.ru.
+orcart.facebook.com.
+a.root-servers.net.
+improveverywhere.com.
+servicemap.conduit-services.com.
+ilov.spb.ru.
+rest.motekmobile.com.
+i3.ytimg.com.
+a.root-servers.net.
+linkhelp.clients.google.com.
+www.l.google.com.
+apps.facebook.com.
+ocsp.verisign.com.
+ax.init.itunes.apple.com.
+google.com.
+tnams.com.
+mail2.somewhere.com.
+asic.gov.au.
+16.122.149.187.in-addr.arpa.
+4shared.co.
+sp.cwfservice.net.
+external.ak.fbcdn.net.
+tysvrmail.teckyork.com.
+abel.dk.
+darbylaw.com.
+colorquimica.com.co.
+sup.live.com.
+232.24.85.200.in-addr.arpa.
+esino.en.alibaba.com.
+a.root-servers.net.
+dasya.com.
+244.74.41.187.in-addr.arpa.
+79.16.21.201.in-addr.arpa.
+platform.twitter.com.
+creative.ak.fbcdn.net.
+shared.live.com.
+112.92.112.177.in-addr.arpa.
+external.ak.fbcdn.net.
+photos-b.ak.fbcdn.net.
+time.windows.com.
+www.htmlfirm.com.
+platform.ak.fbcdn.net.
+a1005.w42.akamai.net.
+profile.ak.fbcdn.net.
+www.facebook.com.
+www.gooogirl.com.
+pmkqrc8hg.66dq.
+www.facebook.com.
+a1.sphotos.ak.fbcdn.net.
+a2.sphotos.ak.fbcdn.net.
+dns.msftncsi.com.
+google.com.
+adserver.adtechus.com.
+www.colsantamariaportu.com.
+laobserved.com.
+immunolabs.com.
+msgr.updates.yahoo.com.
+_757_34_5.
+photos-a.ak.fbcdn.net.
+a.root-servers.net.
+97.165.198.74.in-addr.arpa.
+61.185.176.190.in-addr.arpa.
+us.starmedia.com.
+belorys-kh.livejournal.com.
+publimetro1.autoplaza.com.mx.
+pcweb.mycom.co.jp.
+info.yahoo.com.
+sc2.rules.mailshell.net.
+100.127.101.75.in-addr.arpa.
+.
+mail.google.com.
+191.140.84.200.in-addr.arpa.
+www.houseofdeals.com.
+js.wlxrs.com.
+246.227.171.69.in-addr.arpa.
+a5.sphotos.ak.fbcdn.net.
+content.yieldmanager.edgesuite.net.
+l.yimg.com.
+googleads.g.doubleclick.net.
+www.facebook.com.
+a1.sphotos.ak.fbcdn.net.
+img301.imageshack.us.
+a1505.l.akamai.net.
+mail.global.ans-online.net.
+lh5.googleusercontent.com.
+www.google.com.
+www.licornpublishing.com.
+mail.ntnindia.com.
+stisd.esc2.net.
+145.219.110.189.in-addr.arpa.
+ns2.fibernet.ro.
+www.facebook.com.
+smtpfw.citybloom.org.
+www.google.com.
+92.28.252.189.in-addr.arpa.
+a.root-servers.net.
+a4.sphotos.ak.fbcdn.net.
+blog.beliefnet.com.
+aiolfi.ch.
+developers.facebook.com.
+125.162.168.192.in-addr.arpa.
+support.mediafire.com.
+116.57.64.62.in-addr.arpa.
+a1108.da1.akamai.net.
+secure.shared.live.com.
+a.root-servers.net.
+glayiueditorial.blogspot.com.
+pixel.facebook.com.
+162.198.143.187.in-addr.arpa.
+platform.ak.fbcdn.net.
+www.facebook.com.
+www.aepia.org.
+d-t.ru.
+www.bebo.com.
+adserver.adtech.de.
+1.0.0.127.in-addr.arpa.
+www.mujeresdeempresa.com.
+a-0.19-a3096081.c0b0002.1518.19d3.3ea1.210.0.wzmeesafj38nm94cm4dpwg8mai.avqs.mcafee.com.
+www.dodge.cl.
+productos.maycodelsureste.com.
+education.parts-express.com.
+www.slrphotographyguide.com.
+158.82.246.201.in-addr.arpa.
+m.addthisedge.com.
+www.facebook.com.
+carrental.enclick.com.
+ns20-f.bigfish.com.
+www.infolinks.com.
+dm-tech.net.
+de.tynt.com.
+mail.ce-easy.de.
+a2.sphotos.ak.fbcdn.net.
+147.255.191.220.in-addr.arpa.
+166.115.110.193.in-addr.arpa.
+secure.gravatar.com.
+elmusic.net.
+a1.sphotos.ak.fbcdn.net.
+api.bizographics.com.
+js2.wlxrs.com.
+736561726368636c69656e74.6c697665.6e6574.80h413650eb.webcfs00.com.
+146.253.183.190.in-addr.arpa.
+profile.ak.fbcdn.net.
+pim.ram.htcsense.com.
+thumbs.ofmtvimg.info.
+5.166.171.69.in-addr.arpa.
+63.13.195.187.in-addr.arpa.
+admeld.adnxs.com.
+afs-seminars.com.
+r._dns-sd._udp.0.50.168.192.in-addr.arpa.
+www.youtube.com.
+www.facebook.com.
+186.91.73.190.in-addr.arpa.
+pipe-klup.ru.
+mail.xn.com.
+89.190.170.201.in-addr.arpa.
+wuiyue.com.
+gfx8.hotmail.com.
+_954_38_1.
+www.fregate.com.
+alumnos.unex.es.
+vogue.mundoforo.com.
+dstest.yahoo.com.
+cdn.search.sweetim.com.
+media.monster.com.
+mail.quartics.com.
+preved.bandoo.com.
+a.root-servers.net.
+mms602.whatsapp.net.
+inspecintl.com.
+dns.msftncsi.com.
+itx4.2-01-275d-0005.cdx.cedexis.net.
+cocinet.net.
+aboutfamilies.org.
+tissc.corp.travelport.com.
+teredo.ipv6.microsoft.com.
+libropadrericopadrepobre.wordpress.com.
+neksus.net.
+accounts.google.com.
+yts-blog.weblogs.jp.
+107.179.152.201.in-addr.arpa.
+copers.ru.
+cisadu2.let.uniroma1.it.
+www.facebook.com.
+www.google.com.
+www.googletagservices.com.
+ssl.gstatic.com.
+creative.ak.fbcdn.net.
+95.43.139.187.in-addr.arpa.
+a.root-servers.net.
+cnic.jp.
+www.fickdich.biz.
+api.oovoo.com.
+a2.sphotos.ak.fbcdn.net.
+support.google.com.
+203.175.179.60.in-addr.arpa.
+es-la.facebook.com.
+26.106.73.186.in-addr.arpa.
+a7.sphotos.ak.fbcdn.net.
+www.facebook.com.
+77.28.10.201.in-addr.arpa.
+row.bc.yahoo.com.
+americangaming.org.
+www.ociodf.net.
+a2.sphotos.ak.fbcdn.net.
+s1-s.licdn.com.
+a.root-servers.net.
+www.facebook.com.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+58.59.13.189.in-addr.arpa.
+www.itb.co.uk.
+rss.msnbc.msn.com.
+238.235.231.190.in-addr.arpa.
+b._dns-sd._udp.0.1.168.192.in-addr.arpa.
+www.facebook.com.
+www.bing.com.
+www.shutterbug.net.
+hawaiicaterers.com.
+www.getitnearme.com.
+sites.google.com.
+www.mediawiki.org.
+mailsrv2.sofidel.com.
+jemsite.com.
+fotoramok.net.
+es.answers.yahoo.com.
+mailgate.burgoynes.com.
+ksn2-12.kaspersky-labs.com.
+ads.sumavisos.com.
+www.hsbc.co.mu.
+ocsp.verisign.com.
+www.worldlandtrust.org.
+winderhall.co.uk.
+snsgw.samsungmobile.com.
+www.google.com.
+safebrowsing-cache.google.com.
+static.ak.fbcdn.net.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+107.146.220.66.in-addr.arpa.
+biblioteca.enah.edu.ni.
+loschicosenero.blogspot.com.
+creative.ak.fbcdn.net.
+www.todotorrents.com.
+253.248.72.184.in-addr.arpa.
+windcriesamy.blogspot.com.
+creative.ak.fbcdn.net.
+121.80.51.170.in-addr.arpa.
+46.33.119.200.in-addr.arpa.
+css.corriereobjects.it.
+224.225.173.201.in-addr.arpa.
+profile.ak.fbcdn.net.
+www.qzal.net.
+46.171.168.67.in-addr.arpa.
+insites.com.au.
+94.86.110.79.in-addr.arpa.
+www.britishsupermarketworldwide.com.
+goo.gl.
+0-155.channel.facebook.com.
+a4.sphotos.ak.fbcdn.net.
+1-nuncasabe.blogspot.com.
+s.youtube.com.
+googleads.g.doubleclick.net.
+14.38.34.156.in-addr.arpa.
+blogdegameloft.es.
+s-static.ak.facebook.com.
+mail4.syntec.carlisle.com.
+bolig.lokalavisen.dk.
+celebritybabies.people.com.
+p.twimg.com.
+www.fourwinds10.net.
+google.com.
+db._dns-sd._udp.lan.
+crl.microsoft.com.
+a.root-servers.net.
+a.root-servers.net.
+banners2.ero-advertising.com.
+web.ewu.edu.
+skydrive.live.com.
+a.root-servers.net.
+media.relay.voice.yahoo.com.
+developers.facebook.com.
+entertaintexas.com.
+118.82.106.189.in-addr.arpa.
+calendarmarks.xanga.com.
+va.px.invitemedia.com.
+supcisqslsyiqrs.biz.
+platform.twitter.com.
+seriesloads.com.ar.
+www.youtube.com.
+img216.imagevenue.com.
+pacificbmw.com.s9b1.psmtp.com.
+www.crunchbase.com.
+api.twitter.com.
+backupmx.mycompuworld.net.
+www.facebook.com.
+127.234.178.186.in-addr.arpa.
+greaterlexins.com.
+tms30.icrc.trendmicro.com.
+csi.gstatic.com.
+pnrws.skype.com.
+aeglegno.it.
+176.104.117.200.in-addr.arpa.
+mail.sleeppd.com.
+231.119.47.92.in-addr.arpa.
+219.219.91.186.in-addr.arpa.
+a3.sphotos.ak.fbcdn.net.
+pool.ntp.org.
+a.root-servers.net.
+i2.ytimg.com.
+a8.sphotos.ak.fbcdn.net.
+a.root-servers.net.
+fghyt.com.
+google.com.
+www.amorenlinea.biz.
+cdn.dnsmex.net.
+35.29.69.187.in-addr.arpa.
+knowco.com.
+www.mccannfiles.com.
+glenelg74.fsnet.co.uk.
+amer.rel.msn.com.
+webcache.googleusercontent.com.
+apps.facebook.com.
+251.15.236.189.in-addr.arpa.
+37.41.177.142.in-addr.arpa.
+by2msg4020708.gateway.messenger.live.com.
+55.92.161.189.in-addr.arpa.
+a7.sphotos.ak.fbcdn.net.
+www.bing.com.
+titanium30-en.url.trendmicro.com.
+www.doosaninfracore.com.
+www.dayspring.com.
+79.29.200.189.in-addr.arpa.
+centurioninsurance.net.
+www.mmsend1.com.
+a2.da1.akamai.net.
+afrada.com.ua.
+7.30.4.189.in-addr.arpa.
+l.yimg.com.
+dcads.sina.com.cn.
+pagead2.googlesyndication.com.
+s.youtube.com.
+viajedefrances2009.wordpress.com.
+accounts.google.com.
+cdn1.ads.contentabc.com.
+dimmitt.net.
+peru21.pe.
+newmonetarism.blogspot.com.
+i4.ytimg.com.
+a.root-servers.net.
+www.globus.org.
+news.search.yahoo.com.
+rest-img.msg.yahoo.com.
+historiasdeamor-mina.blogspot.com.
+www.juegos-diarios.org.
+soundeyet.blogspot.com.
+support.google.com.
+sonamywings.foroactivo.net.
+static.ak.fbcdn.net.
+5.p.s.mfcdn.net.
+zh-cn.facebook.com.
+i2.ytimg.com.
+google.com.
+mx2.dualog.no.
+service1.ess.apple.com.
+estonoesunblogdehistoria.blogspot.com.
+eysk.kuban.su.
+135.201.157.186.in-addr.arpa.
+www.potoandcabenga.com.
+55.181.63.69.in-addr.arpa.
+creative.ak.fbcdn.net.
+ds.serving-sys.com.
+a2.sphotos.ak.fbcdn.net.
+weather.ammonnews.net.
+googleads.g.doubleclick.net.
+a.root-servers.net.
+safebrowsing-cache.google.com.
+_806_43_8.
+sp.cwfservice.net.
+www.statcounter.com.
+photos-d.ak.fbcdn.net.
+a6.sphotos.ak.fbcdn.net.
+20.83.187.190.in-addr.arpa.
+32.96.188.186.in-addr.arpa.
+176.220.85.209.sbl-xbl.spamhaus.org.
+www.facebook.com.
+marksstudio.com.
+a7.sphotos.ak.fbcdn.net.
+developers.facebook.com.
+63.49.79.187.in-addr.arpa.
+relay.voice.messenger.msn.com.
+bleetz.wordpress.com.
+m.ak.fbcdn.net.
+es.wikipedia.org.
+www.global.hs-mittweida.de.
+lernet.ru.
+www.peopleeffect.com.au.
+www.facebook.com.
+dragon-ball-z-budokai-x.softonic.com.br.
+s2.youtube.com.
+m.hotmail.com.
+ad.adnetwork.net.
+mail2.americasvacationcenter.com.
+apps.facebook.com.
+rayman-raving-rabbids.programas-gratis.net.
+a8.sphotos.ak.fbcdn.net.
+7.37.215.186.in-addr.arpa.
+zynga.tm.
+music-vokal.ru.
+apir.webrep.avast.com.
+www.saartjeknits.nl.
+profile.ak.fbcdn.net.
+tc16.easythumbhost.com.
+wws.mcanime.net.
+code.jquery.com.
+122.173.180.186.in-addr.arpa.
+167.19.106.186.in-addr.arpa.
+photos-e.ak.fbcdn.net.
+mashsf.tumblr.com.
+a.root-servers.net.
+53.50.27.201.in-addr.arpa.
+kdc.uas.aol.com.
+adm-saransk.ru.
+tc3.easythumbhost.com.
+m.addthisedge.com.
+ultrastardx.sourceforge.net.
+133.81.73.190.in-addr.arpa.
+www.bestbuy-walmart.com.
+dogparry.deviantart.com.
+thumbs2.ebaystatic.com.
+profile.ak.fbcdn.net.
+muscledmanmeat.bestmalediaries.com.
+134.56.5.190.in-addr.arpa.
+googleads.g.doubleclick.net.
+www.64colors.com.
+api.facebook.com.
+www.google.com.
+www.adobe.com.
+107.187.153.186.in-addr.arpa.
+www.bravotube.net.
+googleads.g.doubleclick.net.
+news.google.com.
+partner.googleadservices.com.
+_922_37_6.
+www.wamgroup.com.
+1.207.239.71.in-addr.arpa.
+artesana.mejorforo.net.
+glamaur.ru.
+www.yx0077.com.
+s.youtube.com.
+145.7.173.201.in-addr.arpa.
+yahoo.com.
+bom3.vsnl.net.in.
+e-tard.tv.
+chy856n7f.18hx.
+adsfront.iminent.com.
+178.41.210.201.in-addr.arpa.
+bnlmail.com.
+img100.xvideos.com.
+sf-mailgate.hellerehrman.com.
+160.172.83.178.in-addr.arpa.
+facultalandia.blogia.com.
+insider.msg.yahoo.com.
+ytimg.l.google.com.
+adfactory.publicidees.net.
+sexy-1.momsfactory.com.
+a3.da1.akamai.net.
+safebrowsing.clients.google.com.
+alt1.aspmx.l.google.com.
+ever.ru.
+blufiles.storage.msn.com.
+a1.sphotos.ak.fbcdn.net.
+chromejs.s3.amazonaws.com.
+dcoxy4i5d.89bi.
+a.root-servers.net.
+www.toons-x.com.
+156.120.75.200.in-addr.arpa.
+109.31.156.187.in-addr.arpa.
+www.wetteronline.de.
+www.mi6-hq.com.
+137.131.170.118.in-addr.arpa.
+a1.sphotos.ak.fbcdn.net.
+www.usps.com.
+swaisland-ltd.com.
+dc.logmein-gateway.com.
+bible.christiansunite.com.
+jers2.info.
+s-static.ak.fbcdn.net.
+.
+104.217.237.78.in-addr.arpa.
+www.jumboacasa.com.ar.
+151.183.193.111.in-addr.arpa.
+i998.mangareader.net.
+www.tips4mums.com.
+a.root-servers.net.
+profile.ak.fbcdn.net.
+developers.facebook.com.
+.
+relay1.delight2000.com.
+photos-b.ak.fbcdn.net.
+photos-a.ak.fbcdn.net.
+id-id.facebook.com.
+www.bancobcr.com.
+csc3-2010-crl.verisign.com.
+www.gerencie.com.
+facebook.com.
+ocsp.digicert.com.
+download313.avast.com.
+angus.njcure.com.
+cs10124.vk.com.
+.
+200.27.81.187.in-addr.arpa.
+atlantichealth.com.
+loefflerrandall.com.
+c0013899.cdn1.cloudfiles.rackspacecloud.com.
+114.225.234.99.in-addr.arpa.
+mail1.mn-services.nl.
+maverickflooring.com.
+websearch.ask.com.
+fr-fr.facebook.com.
+static.ak.facebook.com.
+zammbkygf.76ul.
+q.ebaystatic.com.
+localhost.
+mail.jofair.com.
+a1997.b.akamai.net.
+78.50.170.201.in-addr.arpa.
+download.cartoonnetworkasia.com.
+cdn.rep.sc.sweetim.com.
+www.ambafrance-id.org.
+125.100.255.77.in-addr.arpa.
+api-read.facebook.com.
+205.113.102.201.in-addr.arpa.
+mail.flinteclk.com.
+www.adobe.com.
+wd-edge.sharethis.com.
+showtimepictures.com.
+ad.jumbaexchange.com.
+apis.google.com.
+wikileaks.org.
+sa.wikipedia.org.
+radoscorp.radoscompanies.com.
+63.90.30.190.in-addr.arpa.
+a4.sphotos.ak.fbcdn.net.
+102.214.231.89.in-addr.arpa.
+skj-advokat.dk.
+e4805.b.akamaiedge.net.
+a.root-servers.net.
+box425.bluehost.com.
+www.belkin.com.
+104.2.168.192.in-addr.arpa.
+238.62.248.201.in-addr.arpa.
+secure.gate2shop.com.
+ymail.com.
+74.166.58.187.in-addr.arpa.
+es-la.facebook.com.
+vstun.voipinfocenter.com.
+b._dns-sd._udp.0.55.211.10.in-addr.arpa.
+photos-h.ak.fbcdn.net.
+a.root-servers.net.
+236.73.243.201.in-addr.arpa.
+www.micasarevista.com.
+dinero.univision.com.
+126.39.213.186.in-addr.arpa.
+mis-3.pgi.citiesofgold.com.
+c-0.19-a309f481.483.1518.19d3.3ea1.410.0.i8p2s6m6vjskf3g8al12u1wpdq.avqs.mcafee.com.
+photos-d.ak.fbcdn.net.
+mercigod.com.
+www.losrecursoshumanos.com.
+www.calculadoradelamortotal.com.
+www.lyme.org.
+22.242.171.69.in-addr.arpa.
+79.189.245.190.in-addr.arpa.
+us.bc.yahoo.com.
+worldattnet.com.
+hst14.vault-it.ru.
+a.root-servers.net.
+s.youtube.com.
+profile.ak.fbcdn.net.
+201.204.177.189.in-addr.arpa.
+mail.fpalex.com.
+tuqbjzkbh.a99t7h1e.
+creative.ak.fbcdn.net.
+clients1.google.com.
+215.198.3.190.in-addr.arpa.
+107.69.210.201.in-addr.arpa.
+3oaks.com.
+ad-g.doubleclick.net.
+developers.facebook.com.
+mobileinsights.com.
+www.themotoguide.com.
+mail.fe-azp.com.
+zoo-tycoon-2-endangered-species.softonic.com.
+i1.ytimg.com.
+seversk.net.
+.
+a.root-servers.net.
+9.55.98.68.in-addr.arpa.
+aol.com.
+jcgodj7jq.43cc.
+98.165.66.66.in-addr.arpa.
+flashpirate.com.
+csi.gstatic.com.
+www.facebook.com.
+a13.t26.net.
+financialheritage.com.
+www.google.com.
+lawebdeidea.org.
+photos-h.ak.fbcdn.net.
+apps.facebook.com.
+www.googletagservices.com.
+us.bc.yahoo.com.
+a.c-0.19-1309d081.20400b3.1518.19d4.3ea1.210.0.upmrq98fnvwbita33avahwiqgi.avqs.mcafee.com.
+picasaweb.google.ru.
+d2095743.xoom.it.
+a.root-servers.net.
+adewumicollege.net.
+i3.ytimg.com.
+www.dollarparalelovenezuela.com.
+platform.twitter.com.
+js.aiya.com.cn.
+service.gc.apple.com.
+a.root-servers.net.
+photos-d.ak.fbcdn.net.
+ideatrainingcenter.com.
+radoux.fr.
+161.0.94.208.in-addr.arpa.
+turismo.perfil.com.
+cluster2a.us.messagelabs.com.
+ntp1.cs.wisc.edu.
+hs9ba2qyg.49gr.
+cataclysm.wowmortal.com.
+smtp02-1.omse-rz.net.
+video.google.com.
+plus.google.com.
+dns.msftncsi.com.
+firsttennessee.com.
+55.69.108.118.in-addr.arpa.
+112.2.135.190.in-addr.arpa.
+229.110.14.186.in-addr.arpa.
+armmf.adobe.com.
+109.217.252.49.in-addr.arpa.
+xomediaxchange.voicenation.com.
+i3.ytimg.com.
+bookplatejunkie.blogspot.com.
+blog.4shared.com.
+rts.phn.doublepimp.com.
+his.se.
+caleidoscoop.net.
+manila.craigslist.com.ph.
+saransk.binbank.ru.
+www.restaurantsource.com.
+a1313.da1.akamai.net.
+www.google.com.
+biglonline.com.
+shared.live.com.
+o.analytics.yahoo.com.
+a5.sphotos.ak.fbcdn.net.
+55.19.118.75.in-addr.arpa.
+www.facebook.com.
+34.111.246.190.in-addr.arpa.
+market.android.com.
+creative.ak.fbcdn.net.
+www.new-hairgames.com.
+buildabearnews.com.
+ksn2-12.kaspersky-labs.com.
+fpdownload.adobe.com.
+dns.msftncsi.com.
+95.118.145.186.in-addr.arpa.
+a1701.v.phobos.apple.com.
+counterb.statcounter.com.
+css.wlxrs.com.
+photos-b.ak.fbcdn.net.
+a8.sphotos.ak.fbcdn.net.
+jjrinccpa.com.
+a.root-servers.net.
+cxz23.meaningtool.com.
+33.141.14.201.in-addr.arpa.
+145.122.255.200.in-addr.arpa.
+dns.msftncsi.com.
+backofficesite.epyte.com.
+platform.twitter.com.
+monitor.nsk.su.
+mx03.wow.synacor.com.
+rs570l3.rapidshare.com.
+www.druglib.com.
+201.120.141.99.in-addr.arpa.
+plus.google.com.
+download.cnet.com.
+latinoweb.com.
+222.73.109.79.in-addr.arpa.
+ax.su.itunes.apple.com.
+mobile.jang.com.pk.
+recall.com.s5a2.psmtp.com.
+photos-a.ak.fbcdn.net.
+141.190.106.177.in-addr.arpa.
+l.yimg.com.
+orovalleycam.webhop.net.
+ak1.abmr.net.
+80.76.132.190.in-addr.arpa.
+www.gatorade.com.mx.
+abnorth.com.
+download115.avast.com.
+www.care4babygallery.net.
+33.248.95.82.in-addr.arpa.
+39.68.172.123.in-addr.arpa.
+rt.liftdna.com.
+a749.g.akamai.net.
+platform.twitter.com.
+pics.ebaystatic.com.
+ads.zepterads.com.
+74.244.117.98.in-addr.arpa.
+186.185.208.189.in-addr.arpa.
+www.saunasol.com.
+wods.radio.com.
+personyze-ssl-399604307.eu-west-1.elb.amazonaws.com.
+hagenburgsrv3.hagenburg.se.
+cdn.api.twitter.com.
+www.m6m3.com.
+www.facebook.com.
+horizon.bcbsnj.com.
+fotografia.facilisimo.com.
+.
+www.tntla.com.
+122.117.250.201.in-addr.arpa.
+survey.westfalia-separator.com.
+www.efesis.cl.
+a3.sphotos.ak.fbcdn.net.
+ihatemyparents.tumblr.com.
+op.pl.
+www.prodiverstore.com.
+nimbus.com.
+photos-f.ak.fbcdn.net.
+69.206.84.200.in-addr.arpa.
+clutch.mtv.com.
+e554sgnyx.53kx.
+safebrowsing-cache.google.com.
+www.parroquiasanfranciscosj.com.
+www.google-analytics.com.
+a5.sphotos.ak.fbcdn.net.
+safebrowsing.clients.google.com.
+www.google-analytics.com.
+a.root-servers.net.
+alberdalellc.com.
+eyuon.net.
+www.hispatube.com.
+sundistasya-shx.blogspot.com.
+feeds.feedburner.com.
+.
+bitech.net.
+img.scoop.it.
+30.media.tumblr.com.
+l.yimg.com.
+www.google-analytics.com.
+twitter.com.
+www.facebook.com.
+isatap.cisco.
+fxfeeds.mozilla.com.
+mail.sabarch.com.
+www.bn.pt.
+igenbergs.de.
+safebrowsing-cache.google.com.
+carla.cg-models.net.
+ad-g.doubleclick.net.
+technorati.com.
+6.88.168.192.in-addr.arpa.
+121.2.54.121.in-addr.arpa.
+www.celebritiesdietplan.com.
+zh-cn.facebook.com.
+client-software.real.com.
+www.valuedgirls.com.
+gaoqing.baofeng.com.
+mysearchdock.com.
+130.45.42.200.in-addr.arpa.
+ad.yieldmanager.com.
+31.71.191.186.in-addr.arpa.
+antiaging.com.
+stats.update.microsoft.com.
+photos-e.ak.fbcdn.net.
+holaapple.com.
+laodontologia.blogspot.com.
+sports.espn.go.com.
+e1.extreme-dm.com.
+www.bollesafety.com.au.
+www.vuelos.com.
+profile.ak.fbcdn.net.
+174.96.122.190.in-addr.arpa.
+pagead2.googlesyndication.com.
+a5.da1.akamai.net.
+a.root-servers.net.
+d.shareaholic.com.
+a.root-servers.net.
+clients1.google.com.
+29.media.tumblr.com.
+creative.ak.fbcdn.net.
+www.dobrucki.com.
+65.68.69.189.in-addr.arpa.
+105.250.161.201.in-addr.arpa.
+i4.ytimg.com.
+www.rashed-elmajed.com.
+cdn1.finaltorrent.com.
+164.240.250.190.in-addr.arpa.
+www.altillo.com.
+smtp.ctshk.com.
+217.76.210.189.in-addr.arpa.
+isohunt.com.
+oh.rr.com.
+189.181.106.177.in-addr.arpa.
+nashvillemama.com.
+187.142.20.92.in-addr.arpa.
+mx03.peoplepc.com.
+safebrowsing.clients.google.com.
+www.facebook.com.
+c49cvdtnsjqhvprarmrjvdxe41e11a37nybu.info.
+profile.ak.fbcdn.net.
+www9.effectivemeasure.net.
+15.222.198.190.in-addr.arpa.
+rivergrovewinery.com.
+155.58.50.190.in-addr.arpa.
+a.root-servers.net.
+a1.sphotos.ak.fbcdn.net.
+badge.facebook.com.
+lafvb.com.
+a.root-servers.net.
+highbury.ac.uk.
+www.thehkaccess.com.
+uh9ql5i6u.k81a3t8z.
+www.waringcommercialproducts.com.
+a4.sphotos.ak.fbcdn.net.
+american-playboy-spread.peliculon.tv.
+checkip.dyndns.org.
+a.root-servers.net.
+13.252.241.201.in-addr.arpa.
+ib.adnxs.com.
+www.blingblog.info.
+icons.net.
+netrats.net.
+matedicc.blogspot.com.
+a6.sphotos.ak.fbcdn.net.
+55.9.2.187.in-addr.arpa.
+www.foxsoccer.com.
+api.twitter.com.
+81.178.31.88.in-addr.arpa.
+mx2.mail.eu.yahoo.com.
+i32.tinypic.com.
+fisgoneo.blogspot.com.
+google.com.
+www.joystiq.com.
+ovejaquebalabocadoquepierde.blogspot.com.
+mx.ntcom.ru.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+12.79.250.190.in-addr.arpa.
+mail.pioneeris.net.
+a.root-servers.net.
+devices.live.com.
+dns.msftncsi.com.
+mail2.idesign.com.
+64.202.128.189.in-addr.arpa.
+247.67.228.189.in-addr.arpa.
+www.torrentman.com.
+mvc.break.com.
+media.adxpansion.com.
+cerealmx.quepasa.com.
+clients1.google.com.
+email.dropsend.com.
+sn1msg2010531.gateway.messenger.live.com.
+www.comcast-deals.info.
+ds.serving-sys.com.
+oojk2ck8t.21sq.
+www.facebook.com.
+mail.bettysshop.com.
+dl.google.com.
+xentric.deviantart.com.
+mx.direxions.com.
+api.mybrowserbar.com.
+ssl.gstatic.com.
+b.scorecardresearch.com.
+hcjdazlivat.cc.domain_not_set.invalid.
+kbr.com.
+www.socialgrowthtechnologies.com.
+profile.ak.fbcdn.net.
+ohota-barex.ru.
+api.twitter.com.
+connect.facebook.net.
+gordon-silber.com.
+crl.microsoft.com.
+query.nytimes.com.
+164.115.172.201.in-addr.arpa.
+antonriot.ru.
+212.130.240.85.in-addr.arpa.
+mac.com.
+external.ak.fbcdn.net.
+2.224.195.176.in-addr.arpa.
+_164_71_9.
+img7.imagevenue.com.
+um18.eset.com.
+mail.awlindustries.com.
+qbar.book.qq.com.
+www.mspbs.gov.py.
+150.246.19.187.in-addr.arpa.
+cmts.cmm.msu.ru.
+checkip.dyndns.com.
+www.adobe.com.
+www.thegeneral.com.
+a.root-servers.net.
+75.95.218.186.in-addr.arpa.
+a.root-servers.net.
+m.addthisedge.com.
+up.e7s.net.
+pinme.ru.
+a.root-servers.net.
+arxivblog.com.
+www.apple.com.
+w:5lv9:ve.h26v8v6f.
+ds.serving-sys.com.
+www.statefarm.com.
+19.247.121.109.in-addr.arpa.
+parroquiadebarciela.org.
+flagerschools.com.
+d3lvr7yuk4uaui.cloudfront.net.
+73.91.68.94.in-addr.arpa.
+www.edenred.es.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+www.skykid.org.
+24.media.tumblr.com.
+www.cdevision.com.
+mypmfloan.com.
+photos-e.ak.fbcdn.net.
+photos-h.ak.fbcdn.net.
+1.0.0.127.dnsbugtest.1.0.0.127.in-addr.arpa.
+lienzogazules.wordpress.com.
+www.gstatic.com.
+mail.omnihomesinc.com.
+www.update.microsoft.com.
+es-es.facebook.com.
+www.google.com.
+l9h64srgl.k63c2y2h.
+forum.4shared.com.
+googleads.g.doubleclick.net.
+www.buzzeum.com.
+29.116.46.207.in-addr.arpa.
+mail2.ringpower.com.
+ottawaplastics.com.
+gimail.af.mil.
+60.70.38.186.in-addr.arpa.
+0-310.channel.facebook.com.
+api-read.facebook.com.
+88.80.130.213.in-addr.arpa.
+dns.msftncsi.com.
+platform.twitter.com.
+238.247.114.186.in-addr.arpa.
+planeta-hot.blogspot.com.
+google.com.
+www.youtube.com.
+sp.cwfservice.net.
+www.gstatic.com.
+95c91792.realfiles.net.
+162.252.9.177.in-addr.arpa.
+googleads.g.doubleclick.net.
+multimediajuegosyprogramas.blogspot.com.
+www.adultizle.net.
+sites.google.com.
+135.194.55.187.in-addr.arpa.
+75.41.165.83.in-addr.arpa.
+a.root-servers.net.
+www.sharethis.com.
+www.5starcosmetics.co.uk.
+84.18.76.189.in-addr.arpa.
+biltmorebaptist.com.
+163.51.173.201.in-addr.arpa.
+mailserver.rkprint.com.
+a1003.w41.akamai.net.
+s.youtube.com.
+_512_31_2.
+www.unitedelectricalservices.com.au.
+xefevsma1.69pe.
+dv57qk7uv.01kk.
+220.26.74.187.in-addr.arpa.
+_ldap._tcp.
+butterfield.k12.mn.us.
+degerencia.com.
+tc24.easythumbhost.com.
+api.twitter.com.
+104.139.17.201.in-addr.arpa.
+api-read.facebook.com.
+www.google.com.
+_282_00_4.
+sc2.rules.mailshell.net.
+6.105.68.201.in-addr.arpa.
+www.mayflowerfamilies.com.
+paradiseartists.com.s10a1.psmtp.com.
+www.bangkokbargirl.com.
+plus.google.com.
+jalisco.milenio.com.
+photos-c.ak.fbcdn.net.
+www.youtube.com.
+www.belote-en-ligne.fr.
+de-de.facebook.com.
+www.intel.com.
+ajax.googleapis.com.
+185.6.36.186.in-addr.arpa.
+www.google-analytics.com.
+ccso.fr.
+117.220.20.58.in-addr.arpa.
+ads.adxpose.com.
+stratus.com.br.
+css.wlxrs.com.
+js.revsci.net.
+www.wheredidugetthat.com.
+dotmed-images.s3.amazonaws.com.
+152.129.203.190.in-addr.arpa.
+inlinethumb09.webshots.com.
+viv.ebay.ie.
+b._dns-sd._udp.0.0.168.192.in-addr.arpa.
+www.facebook.com.
+suddenlinke.net.
+_ldap._tcp.
+www.searchqu.com.
+psgw.t-mobilesgws.com.
+rad.msn.com.
+madolcevita.canalblog.com.
+a.root-servers.net.
+profile.ak.fbcdn.net.
+www.yangmi.com.
+vegweb.com.
+mavericklogistics.com.
+smtp.mourik.com.
+a2.sphotos.ak.fbcdn.net.
+translate.googleapis.com.
+google.com.
+inbound.trektours.com.netsolmail.net.
+pixel.quantserve.com.
+accounts.youtube.com.
+shop.frontarmy.com.
+62.101.69.189.in-addr.arpa.
+www.youtube.com.
+mx2.archirodon.net.
+35.238.57.62.in-addr.arpa.
+138.95.150.187.in-addr.arpa.
+support.google.com.
+a8.sphotos.ak.fbcdn.net.
+stats.beaconads.com.
+154.97.237.98.in-addr.arpa.
+ts3.mm.bing.net.
+a6.sphotos.ak.fbcdn.net.
+a78srlmfd.n17i7f6q.
+www.maltatexo.com.mx.
+0-167.channel.facebook.com.
+104.176.161.109.in-addr.arpa.
+74.8.238.189.in-addr.arpa.
+img703.imageshack.us.
+a1.sphotos.ak.fbcdn.net.
+a.root-servers.net.
+photos-d.ak.fbcdn.net.
+mangacan.blogspot.com.
+dhp.com.
+photos-b.ak.fbcdn.net.
+223.206.236.99.in-addr.arpa.
+www.facebook.com.
+chatenabled.mail.google.com.
+smtp1.qatar-med.cornell.edu.
+optimumreturn.com.s7a1.psmtp.com.
+andreaandreanavarretemarn04-andrea.blogspot.com.
+accountservices.msn.com.
+50.226.93.186.in-addr.arpa.
+absolute-bikini.com.
+fbcdn-sphotos-a.akamaihd.net.
+www.googleadservices.com.
+smtp.cobantur.com.
+bbcore.cloudapp.net.
+developers.facebook.com.
+eolapaz2.blogspot.com.
+mail.google.com.
+_284_43_8.
+js.admeld.com.
+server1.torrenzano.com.
+188.177.232.190.in-addr.arpa.
+g-ecx.images-amazon.com.
+www.davedubya.com.
+pixel.facebook.com.
+39-courier.push.apple.com.
+hoymusic.com.
+creative.ak.fbcdn.net.
+www.citedusexe.com.
+a.root-servers.net.
+233.7.147.190.in-addr.arpa.
+ringo.com.
+davesnotepad.blogspot.com.
+10marnellcorrao.com.inbound10.mxlogic.net.
+img.youtube.com.
+external.ak.fbcdn.net.
+www.msftncsi.com.
+weddings.about.com.
+sro.whatsapp.net.
+pagead2.googlesyndication.com.
+fls-sccmgl01.pfaff.local.
+www.veithsymposium.org.
+mail.btc.net.
+notifier.avira.com.
+retracker.hotplug.ru.
+a1005.w42.akamai.net.
+static.4shared.com.
+mail.firstmerc.com.
+www.warrs.com.
+142.195.206.200.in-addr.arpa.
+a.root-servers.net.
+ipm.bitdefender.com.
+backup-bc.mail-relay.com.
+241.31.63.189.in-addr.arpa.
+a7.sphotos.ak.fbcdn.net.
+getprof.de.np.community.playstation.net.
+mail.eldacc.co.za.
+palax.kirov.ru.
+115.26.170.189.in-addr.arpa.
+profile.ak.fbcdn.net.
+_303_11_0.
+aol.com.
+profile.ak.fbcdn.net.
+mystartantiphishing.com.
+mail.yiron.org.il.
+ch.roskzn.ru.
+www.laboratoryequipment.com.
+api.facebook.com.
+itunes.apple.com.
+www.facebook.com.
+www.googletagservices.com.
+www.google.com.
+www.maturetubesite.net.
+20minutos.feedsportal.com.
+www.facebook.com.
+fr.maps.yahoo.com.
+aka-cdn-ns.adtech.de.
+fr.webrep.avast.com.
+a.root-servers.net.
+caminosdepoesia123.foro-colombia.net.
+www.historyforsale.com.
+cgp.pu.ru.
+151.204.31.190.in-addr.arpa.
+ec.atdmt.com.
+www.infoempleo.com.
+203.107.25.84.in-addr.arpa.
+www.facebook.com.
+connect.facebook.net.
+thumbs.ass4all.com.
+wiredepicenter.disqus.com.
+www.google-analytics.com.
+groups.google.com.mx.
+solutionmyworking.com.
+janakipattiskitchen.blogspot.com.
+226.204.106.187.in-addr.arpa.
+aspuru.unix.fas.harvard.edu.
+gidrogroup.ru.
+www.tsumorichisato.com.
+imp-6.mail.tiscali.it.
+148.33.87.24.in-addr.arpa.
+flash.quantserve.com.
+photos-c.ak.fbcdn.net.
+m.google.com.
+c7.zedo.com.
+247.157.41.68.in-addr.arpa.
+estede-m.ru.
+www.jordanalmonds.com.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+107.234.251.88.in-addr.arpa.
+eramatarealty.com.
+plus.google.com.
+www.riotsweb.com.
+www.cineplus.ch.
+api.bing.com.
+8.105.127.200.in-addr.arpa.
+ap.jil.com.
+upload.traidnt.net.
+www.google-analytics.com.
+www.bywifi.com.
+facebook.net.dnsbl7.mailshell.net.
+dns.msftncsi.com.
+p.rightaction.com.
+104.12.169.189.in-addr.arpa.
+fbcdn-profile-a.akamaihd.net.
+stuy.edu.
+37.143.253.159.in-addr.arpa.
+x4w19xc8e.93wa.
+plusone.google.com.
+a.root-servers.net.
+apple-mobile.query.yahooapis.com.
+28.media.tumblr.com.
+cartas_clow.frikitest.com.
+s-static.ak.facebook.com.
+adrianarojaspacheco.wordpress.com.
+adserving.cpxinteractive.com.
+24.18.93.114.in-addr.arpa.
+toolbarqueries.clients.google.com.
+www.goojue.com.
+www.ultimatelakehouston.com.
+www.aastra.com.
+s0.2mdn.net.
+www.google-analytics.com.
+mail.nimi24.com.
+shore.net.
+pt-br.facebook.com.
+sp.cwfservice.net.
+mail.bannerbatterien.com.
+p06-contacts.icloud.com.
+clothing.shop.ebay.com.
+176.93.206.190.in-addr.arpa.
+s6asmj1zy.k08f7n4q.
+safebrowsing-cache.google.com.
+b._dns-sd._udp.0.1.168.192.in-addr.arpa.
+www.juegos.com.cdngc.net.
+plushkacraft.blogspot.com.
+58.29.53.186.in-addr.arpa.
+dns.msftncsi.com.
+www.wordreference.com.
+i3.ytimg.com.
+pubads.g.doubleclick.net.
+hatch.com.au.
+191.150.142.75.in-addr.arpa.
+anticap.files.wordpress.com.
+es.justin.tv.
+www.tirateunpalo.net.
+cs9663.vk.com.
+www.google-analytics.com.
+hplusson.com.
+175.241.23.186.in-addr.arpa.
+onelinkpr.net.
+personalityl.ru.
+ocsp.verisign.com.
+www.kwausa.com.
+cdn.api.twitter.com.
+hernanbartra.blogspot.com.
+www.youtube.com.
+newsrss.bbc.co.uk.
+211.9.139.190.in-addr.arpa.
+www.youtube.com.
+a4.sphotos.ak.fbcdn.net.
+cherryredcasino.com.
+1.0.0.127.dnsbugtest.1.0.0.127.in-addr.arpa.
+musica.temadictos.org.
+postmaster.co.uk.
+external.ak.fbcdn.net.
+blog3.fc2.com.
+www.solounminuto.org.ar.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+newsinfo.inquirer.net.
+signlite.com.
+cdmsllc.com.
+megabook.ru.
+97.69.118.200.in-addr.arpa.
+static.adwired.mobi.
+www.facebook.com.
+a2.sphotos.ak.fbcdn.net.
+antologia-de-poesia.blogspot.com.
+amazon-s.maxthon.com.
+ads.yimg.com.
+slc.manserve.com.
+office.azbukavkusa.ru.
+www.bing.com.
+photos-b.ak.fbcdn.net.
+cf.rr.com.
+caballerosdelaordendelsol.blogspot.com.
+www.kpm-usa.com.
+mx3.hotmail.com.
+mail.cg02.fr.
+4luq47dwi.q62o6p8x.
+16.147.220.66.in-addr.arpa.
+a4.sphotos.ak.fbcdn.net.
+i4.ytimg.com.
+s0.2mdn.net.
+imgserv.co.uk.
+rad.msn.com.
+www.sep.pue.gob.mx.
+mx2.meisterseelig.com.
+fbcdn-photos-a.akamaihd.net.
+partner.directadvert.ru.
+royalsociety.ru.
+www.cafeteritas.com.
+carolwoods.org.
+72.51.7.199.in-addr.arpa.
+curtisbrown.com.au.
+84.25.168.192.in-addr.arpa.
+a6.sphotos.ak.fbcdn.net.
+www.nytimes.com.
+tsm05.eset.com.
+168.137.99.85.in-addr.arpa.
+www.public-trust.com.
+tc.v9.cache3.c.youtube.com.
+www.facebook.com.
+www.4kotob.com.
+www.digi-panel.com.
+trevorhowell.wanadoo.co.uk.
+snacho.ru.
+rssgov.windows.microsoft.com.
+advolution.de.
+152.11.243.201.in-addr.arpa.
+www.adobe.com.
+es-la.facebook.com.
+lqp1muko6.53us.
+static.ak.fbcdn.net.
+google.com.
+google.com.
+a4.sphotos.ak.fbcdn.net.
+176.228.148.90.in-addr.arpa.
+www.crunchbase.com.
+banashare.com.
+216.225.193.190.in-addr.arpa.
+218.216.87.186.in-addr.arpa.
+jjjjjjjjjj.xsocks.net.
+209.18.253.190.in-addr.arpa.
+www.shoutcastunlimited.com.
+fr-fr.facebook.com.
+d2089471.xoom.it.
+visualpeacemakers.org.
+92.105.127.201.in-addr.arpa.
+medals.bizrate.com.
+db11.spamcatcher.net.
+ds.addthis.com.
+redtube.com.hypestat.com.
+smtap1.systems.smu.edu.
+186.63.0.10.in-addr.arpa.
+safebrowsing.clients.google.com.
+latam.msn.com.
+prod-nr203.voxer.com.
+p.twimg.com.
+mail.dhart.net.
+cgjeaf.com.
+_035_61_8.
+usadanet.net.
+1.0.0.127.dnsbugtest.1.0.0.127.in-addr.arpa.
+fbcdn-sphotos-a.akamaihd.net.
+go.microsoft.com.
+warrendalesales.com.
+www.alpamare.ch.
+tv4s11nsq.24vh.
+www.facebook.com.
+s.ytimg.com.
+controldevices.com.
+38.8.171.189.in-addr.arpa.
+asdjk.com.
+graph.facebook.com.
+www.joepastry.com.
+bt.gamesir.com.
+modpodgerocks.blogspot.com.
+155.173.205.190.in-addr.arpa.
+elcomercio.pe.
+www.tecandsup.com.
+photos-f.ak.fbcdn.net.
+nxx.com.
+doc.verycd.com.
+a.root-servers.net.
+a8.sphotos.ak.fbcdn.net.
+mx.youtube.com.
+comevamail.com.
+www.completemedicalservices.com.
+www.bestmovietrailer.info.
+a5.sphotos.ak.fbcdn.net.
+leydig.com.
+fbcdn-sphotos-a.akamaihd.net.
+www.softahead.com.
+a.root-servers.net.
+w.sharethis.com.
+a2.sphotos.ak.fbcdn.net.
+a1.sphotos.ak.fbcdn.net.
+www.lancope.com.
+photos-b.ak.fbcdn.net.
+mail.delphiconstruction.net.
+ttlrcct2.qianqian.com.
+plugins.longtailvideo.com.
+a151.d.akamai.net.
+a5.sphotos.ak.fbcdn.net.
+servedby.adxpose.com.
+203.15.0.192.in-addr.arpa.
+brianproperties.com.s8b2.psmtp.com.
+program.avast.com.
+146.16.0.186.in-addr.arpa.
+cjkingent.blogspot.com.
+apps.facebook.com.
+api.twitter.com.
+www.facebook.com.
+mi-touch-y-yo.blogspot.com.
+fbcdn-profile-a.akamaihd.net.
+download115.avast.com.
+www.saary-up.com.
+tag.admeld.com.
+e566.b.akamaiedge.net.
+yahoo.com.
+a.root-servers.net.
+evolutionsportsscience.com.
+231.186.198.187.in-addr.arpa.
+b.scorecardresearch.com.
+www.google-analytics.com.
+support.google.com.
+agro.com.ru.
+rocha.la.
+d3lyqimqlfvq37.cloudfront.net.
+acv.com.au.
+a.root-servers.net.
+a.root-servers.net.
+www.oxfamblogs.org.
+46.courier-push-apple.com.akadns.net.
+a948.g.akamai.net.
+www.pizap.com.
+ads2.iforex.com.
+a.root-servers.net.
+165.42.78.201.in-addr.arpa.
+t0.gstatic.com.
+denison01.denisonhydraulics.com.
+www.bywifi.com.
+t0.gstatic.com.
+hi-in.facebook.com.
+www.elbebedemama.net.
+177.245.153.189.in-addr.arpa.
+www.google.com.
+vector.info.
+miblog-especialdominiotk.blogspot.com.
+photos-c.ak.fbcdn.net.
+secure.wlxrs.com.
+bcovekk.fcod.llnwd.net.
+www.vintaxe.com.
+www.sennheiser-sites.com.
+clpav.fr.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+profile.ak.fbcdn.net.
+mx1.ceres.k12.ca.us.
+s-static.ak.fbcdn.net.
+googleads.g.doubleclick.net.
+exitmedia.net.
+support.google.com.
+78.195.86.77.in-addr.arpa.
+im3yy873m.y29t3i4l.
+www.gstatic.com.
+144.201.207.190.in-addr.arpa.
+apis.google.com.
+98.147.227.190.in-addr.arpa.
+theswingingsixties.tumblr.com.
+csf2-1.yobt.tv.
+db._dns-sd._udp.0.1.168.192.in-addr.arpa.
+photos-h.ak.fbcdn.net.
+200.200.10.186.in-addr.arpa.
+_436_35_9.
+staging-beacon-1.newrelic.com.
+p.ebaystatic.com.
+88.70.249.201.in-addr.arpa.
+ads.tlvmedia.com.
+a998.mm1.akamai.net.
+232.240.58.201.in-addr.arpa.
+www.facebook.com.
+mail.porterkhouwconsulting.com.
+www.expansion.net.
+173.57.147.187.in-addr.arpa.
+reefdevelopment.com.
+dsn9.d.skype.net.
+7.77.51.190.in-addr.arpa.
+liveupdate.symantecliveupdate.com.
+96.242.84.200.in-addr.arpa.
+www.facebook.com.
+s.ytimg.com.
+www.eternellepharma.com.
+yahoo.com.
+85.102.160.187.in-addr.arpa.
+mail.crestfoods.com.
+groups.live.com.
+gfx2.hotmail.com.
+mail.sigmamail.com.
+www.facebook.com.
+ec2-50-19-48-225.compute-1.amazonaws.com.
+smtp.fairadsl.co.uk.
+chrome.google.com.
+apps.facebook.com.
+www.sony.com.mx.
+zopf.ru.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+83.230.212.186.in-addr.arpa.
+www.conduit.com.
+creative.ak.fbcdn.net.
+b._dns-sd._udp.0.1.168.192.in-addr.arpa.
+www.fileserve.com.
+www.update.microsoft.com.
+rad.msn.com.
+mail.intermountaintruck.com.
+ads.weownthetraffic.com.
+www.hotels.com.
+fsldjx.en.made-in-china.com.
+simplifiedofficesystems.com.
+profile.ak.fbcdn.net.
+.
+connect.facebook.net.
+geoip.vmn.net.
+toons.kharabeesh.com.
+d1.openx.org.
+72.153.130.201.in-addr.arpa.
+www.careerjet.com.mt.
+www.suvtracker.com.
+books.google.com.
+mx1.vostok.ru.
+www.gritos.com.
+a.root-servers.net.
+photos-d.ak.fbcdn.net.
+fettemama.org.
+www.facebook.com.
+a.root-servers.net.
+haymarket.subscribeonline.co.uk.
+apple.com.
+smtp.hereweare.de.
+images.cdn.redtube.com.
+s.youtube.com.
+animeone.com.
+www.google.com.
+mail.eyrisgroup.com.
+www.netvibes.com.
+www.enelsexo.com.
+dantextil.dk.
+aalcliquers.files.wordpress.com.
+250.236.242.88.in-addr.arpa.
+www.lpn-to-rn.org.
+31.58.200.190.in-addr.arpa.
+i.streetmobster.net.
+www.adobe.com.
+a3.sphotos.ak.fbcdn.net.
+mobiletg.com.
+majesticfunding.net.
+euro.mediotiempo.com.
+254.233.190.186.in-addr.arpa.
+apps.facebook.com.
+35.116.168.192.in-addr.arpa.
+speaklolcat.com.
+photos-a.ak.fbcdn.net.
+www.familiainstitucional.com.
+www.peliculas-flv.com.
+www.thefashionshow.com.
+ar-ar.facebook.com.
+mail.dthsculptor.com.
+static.ak.fbcdn.net.
+gfx2.hotmail.com.
+mail.orsin.net.
+toastmasters.org.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+earthworksstudio.co.uk.
+s1.lemde.fr.
+0-167.channel.facebook.com.
+imail.mk.
+google.com.
+www.unonoticias.com.
+a.root-servers.net.
+nsx.sec.np.dl.playstation.net.
+touch.facebook.com.
+208.212.158.95.in-addr.arpa.
+ads.yimg.com.
+footballer.com.
+adserving.cpxinteractive.com.
+login.oscar.aol.com.
+googleads.g.doubleclick.net.
+www.keeway-america.com.
+photos-a.ak.fbcdn.net.
+24.114.41.92.in-addr.arpa.
+17.119.201.187.in-addr.arpa.
+c0013680.r32.cf1.rackcdn.com.
+mailserver.the-hopes.com.
+pixel.facebook.com.
+profile.ak.fbcdn.net.
+r.l.admob.com.
+us.bc.yahoo.com.
+csi.gstatic.com.
+a.root-servers.net.
+thecodingmassacre.wordpress.com.
+mail.wpi-europe.com.
+www.facebook.com.
+plusone.google.com.
+r._dns-sd._udp.0.244.16.172.in-addr.arpa.
+a937.g.akamai.net.
+checkip.dyndns.com.
+pokah.ru.
+a1.sphotos.ak.fbcdn.net.
+del.icio.us.
+anthrowebstage.endecaondemand.net.
+206.13.14.88.in-addr.arpa.
+evsecure-ocsp.verisign.com.
+registration.mercadolibre.com.mx.
+150.171.176.190.in-addr.arpa.
+www.snowtoit.com.
+37.137.237.64.in-addr.arpa.
+44.183.82.189.in-addr.arpa.
+3-courier.push.apple.com.
+m.hotmail.com.
+www.facebook.com.
+hollyta.en.alibaba.com.
+www.youtube.com.
+sophos.cbtri.com.
+ads.united.no.
+static.ak.fbcdn.net.
+staff.detik.com.
+www.sound.org.
+enterprise-secure-registration.com.
+crl.verisign.com.
+80.166.125.186.in-addr.arpa.
+pneutronics.com.
+tcr.tynt.com.
+www.nondisco.com.
+ocio.mundijuegos.com.
+www.google-analytics.com.
+watashikimakesou.blogspot.com.
+www.fundacionclaudionaranjo.com.
+www.youtube.com.
+bdm.careerbuilder.com.
+238.113.166.190.in-addr.arpa.
+idrops.terra.com.pe.
+www.bridgetmonet.net.
+b._dns-sd._udp.lan.
+www.aljazeera.com.
+br.pps.tv.
+206.163.252.72.in-addr.arpa.
+widgets.amung.us.
+hightechadv.com.
+www.nlm.nih.gov.
+www.google.com.
+a.root-servers.net.
+www.dsttspain.com.
+www.facebook.com.
+rt.liftdna.com.
+www.facebook.com.
+a6.sphotos.ak.fbcdn.net.
+photos-c.ak.fbcdn.net.
+safebrowsing.clients.google.com.
+s1-word-edit.vo.msecnd.net.
+clients2.google.com.
+www.yournextskirt.com.
+29.209.57.187.in-addr.arpa.
+a.root-servers.net.
+www.tecnologia-e.com.
+a.root-servers.net.
+a.root-servers.net.
+googleads.g.doubleclick.net.
+time.nist.gov.
+www.youtube.com.
+contrib.com.
+jndlparmbjimenvchwxek.sc.
+maktoob.omg.yahoo.com.
+s-static.ak.fbcdn.net.
+v1.nonxt1.c.android.clients.google.com.
+29.53.21.187.in-addr.arpa.
+w5v1ulxw2.04kd.
+a8.sphotos.ak.fbcdn.net.
+profile.ak.fbcdn.net.
+dingtao333.3322.org.
+dc105.4shared.com.
+apps.facebook.com.
+platform.ak.fbcdn.net.
+csi.gstatic.com.
+tc23.easythumbhost.com.
+scripts.
+102.15.229.190.in-addr.arpa.
+fantasyart.ru.
+ad.doubleclick.net.
+heartbeat.belkin.com.
+usersystem783aa.ru.
+7mxjnpfl3.e01g5z0j.
+135.119.217.87.in-addr.arpa.
+130.153.56.186.in-addr.arpa.
+www.livejournal.com.
+paraguay.clasificadoya.com.
+karaokekm3.com.
+a6.sphotos.ak.fbcdn.net.
+174.230.209.201.in-addr.arpa.
+msnvidweb.vo.msecnd.net.
+mail.mnui.com.
+feeds.ovi.com.
+promo.badoink.com.
+www.fc-moto.com.
+static.nfilesystem.com.
+static.ak.fbcdn.net.
+intermed.com.
+132.95.158.200.in-addr.arpa.
+www.campbells.com.mx.
+a.mx.moatsconsulting.com.
+v3.nonxt5.c.youtube.com.
+30.227.107.46.in-addr.arpa.
+www.fayereaganclub.com.
+pixel.facebook.com.
+photos-a.ak.fbcdn.net.
+banners.killtro.com.
+apis.google.com.
+ads.bluelithium.com.
+switch.atdmt.com.
+132.113.97.93.in-addr.arpa.
+static.ak.fbcdn.net.
+dnl-01.geo.kaspersky.com.
+mail.betsbv.com.
+s3pu.blogspot.com.
+www.visa.com.ar.
+d2x3khweh61zds.cloudfront.net.
+a.root-servers.net.
+www.rockchalktalk.com.
+bloger.co.
+youcantcallitit.com.
+www.sparwelt.de.
+www.samwha.com.
+external.ak.fbcdn.net.
+_037_08_7.
+img.yktravelphoto.com.
+215.125.153.201.in-addr.arpa.
+ixefirl:h.57bm.
+yugiohsanluis.blogspot.com.
+a7.sphotos.ak.fbcdn.net.
+content.nuvid.com.
+kellpkthpxrmppdr.info.
+ot2wp1mu:.05yd.
+googleads.g.doubleclick.net.
+a-0.19-a20c8079.d1b0083.1518.19d4.3ea1.410.0.1pgnhn5gu7ln3cqlh44lr7nf2j.avqs.mcafee.com.
+47.149.220.66.in-addr.arpa.
+134.100.70.58.in-addr.arpa.
+9gag.com.
+mx.folksam.se.
+img843.imageshack.us.
+fbcdn-profile-a.akamaihd.net.
+230.104.111.78.in-addr.arpa.
+23.159.102.201.in-addr.arpa.
+fbcdn-profile-a.akamaihd.net.
+teredo.ipv6.microsoft.com.
+3.bp.blogspot.com.
+www.soloimportastu.com.
+a4.sphotos.ak.fbcdn.net.
+lycoos.com.
+counterpixel.beiersdorf.com.
+static.ak.fbcdn.net.
+hi-in.facebook.com.
+a.root-servers.net.
+239.203.14.187.in-addr.arpa.
+google.com.
+www.ownerchats.com.
+www.mugutu.com.
+221.165.83.190.in-addr.arpa.
+fbcdn-profile-a.akamaihd.net.
+mail.dgen.com.
+mfe5.polimi.it.
+www.wmaker.net.
+db._dns-sd._udp.0.1.168.192.in-addr.arpa.
+134.240.194.90.in-addr.arpa.
+dg.specificclick.net.
+85.167.21.189.in-addr.arpa.
+o1.t26.net.
+www.mercator-publicitor.fr.
+www2.cbox.ws.
+a1.sphotos.ak.fbcdn.net.
+1.bp.blogspot.com.
+.
+sites.google.com.
+balticbulges.blogspot.com.
+10.122.0.190.in-addr.arpa.
+cdn.ad4game.com.
+video.google.com.mx.
+api-read.facebook.com.
+camba.com.
+a4.sphotos.ak.fbcdn.net.
+87.190.56.186.in-addr.arpa.
+safebrowsing-cache.google.com.
+62.94.120.186.in-addr.arpa.
+nswlant.navy.mil.
+video-stats.l.google.com.
+myworld.ebay.com.
+time.windows.com.
+ocsp.verisign.com.
+syednetworks.com.
+246.53.66.187.in-addr.arpa.
+a1.sphotos.ak.fbcdn.net.
+tools.google.com.
+safebrowsing-cache.google.com.
+158.58.69.190.in-addr.arpa.
+152.129.79.84.in-addr.arpa.
+a.root-servers.net.
+saur.spbnit.ru.
+photos-a.ak.fbcdn.net.
+twitter.com.
+billing.sharo4ka.ru.
+elrecreodelasmamis.foroactivo.com.
+tetonvalley.net.microserv.s5a1.psmtp.com.
+local-bay.contacts.msn.com.
+clients1.google.com.
+ology.com.
+27.199.201.190.in-addr.arpa.
+www.juegosdiarios.com.
+vm1.yorku.ca.
+12.240.16.95.in-addr.arpa.
+cdn.api.twitter.com.
+juegosdemaquillar.com.mx.
+fr-fr.facebook.com.
+a3.sphotos.ak.fbcdn.net.
+108.249.44.200.in-addr.arpa.
+echo.edge.messenger.live.com.
+140.208.224.189.in-addr.arpa.
+164.68.93.186.in-addr.arpa.
+www.awaite.
+d.mybustymilf.com.
+sundries.ru.
+tmss-p.activeupdate.trendmicro.com.
+platform.twitter.com.
+te.net.ru.
+13.129.156.75.in-addr.arpa.
+grossaer.ru.
+a5.sphotos.ak.fbcdn.net.
+homeinstead.com.s5a1.psmtp.com.
+a.root-servers.net.
+323436891.mail.outlook.com.
+coweta.lib.ok.us.
+www.allmetsat.com.
+tairesources.com.
+informativos.net.
+s-static.ak.fbcdn.net.
+a.root-servers.net.
+a7.sphotos.ak.fbcdn.net.
+www.bbc.co.uk.
+244.13.208.189.in-addr.arpa.
+a.root-servers.net.
+i2.ytimg.com.
+csi.gstatic.com.
+sn1msg2010733.gateway.messenger.live.com.
+photos-f.ak.fbcdn.net.
+_644_73_6.
+a.root-servers.net.
+s-static.ak.fbcdn.net.
+www.farmacopedia.com.mx.
+151.83.131.50.in-addr.arpa.
+srv.main.ebayrtm.com.
+atd.com.
+s.ytimg.com.
+kvnews.ru.
+photos-a.ak.fbcdn.net.
+www.listaviral.com.
+google.com.
+14.184.82.186.in-addr.arpa.
+ad.doubleclick.net.
+ecx.images-amazon.com.
+www.theserved.com.
+www.agri-pulse.com.
+cdn.tynt.com.
+7pdqahw6d.r80t1q9z.
+static.ak.fbcdn.net.
+147.9.109.79.in-addr.arpa.
+www.roshan.mobie.in.
+join.gayasianamateurs.com.
+www.blog-emprendedor.info.
+api-read.facebook.com.
+l.live.net.
+ci.atlanta.ga.us.
+10.1.168.192.in-addr.arpa.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+comark.corp.com.
+.
+tc.v5.cache7.c.youtube.com.
+rospres.com.
+twitter.com.
+aka-cdn-ns.adtech.de.
+101.213.143.95.in-addr.arpa.
+www.filmdept.com.
+twitter.com.
+56.214.57.186.in-addr.arpa.
+a.root-servers.net.
+www.micro-machine-shop.com.
+ocsp.verisign.com.
+profile.ak.fbcdn.net.
+photos-h.ak.fbcdn.net.
+a7.sphotos.ak.fbcdn.net.
+www.facebook.com.
+profile.ak.fbcdn.net.
+fr.boats.com.
+rblns75.mailshell.net.
+developers.facebook.com.
+img802.imageshack.us.home.
+205.4.66.201.in-addr.arpa.
+teredo.ipv6.microsoft.com.
+thesaurus.com.
+home.disneylatino.com.
+pmanet.org.
+jv.wikipedia.org.
+www.glendalenewspress.com.
+a.root-servers.net.
+mx1.gddinstrumentation.com.
+fm100.fm.monroeclinic.org.
+0-jf-w.channel.facebook.com.
+www.mintebay.com.
+apiit.edu.my.
+fbcdn-photos-a.akamaihd.net.
+i3.bzpics.com.
+fxozjsbm6.j35r5o3r.
+170.193.102.177.in-addr.arpa.
+170.21.220.189.in-addr.arpa.
+accreditation.aus.com.
+kerrmachine.com.
+a.root-servers.net.
+www.mikeybustos.ca.
+tcgroup.net.
+static02.linkedin.com.
+www.anyads.lk.
+oldnavy.gap.com.
+unifi.
+google.com.
+photos-d.ak.fbcdn.net.
+1.231.21.187.in-addr.arpa.
+www.vklogger.com.
+www.fizik.it.
+126.195.172.201.in-addr.arpa.
+mail.google.com.
+toolbar.google.com.mx.
+db2.stb00.s-msn.com.
+ppspackaging.com.inbound15.mxlogicmx.net.
+photos-c.ak.fbcdn.net.
+cust14283-2.in.mailcontrol.com.
+www.miniclip.com.
+mail.google.com.
+192.143.248.201.in-addr.arpa.
+rd.apmebf.com.
+master14.teamviewer.com.
+cdn.gigya.com.
+www.findppc.net.
+photos-f.ak.fbcdn.net.
+www.newy8games.com.
+mgw.serverparkering.no.
+profile.ak.fbcdn.net.
+217.163.186.86.in-addr.arpa.
+comcolease.com.s5b2.psmtp.com.
+mx3.start.ca.
+76.19.44.187.in-addr.arpa.
+02261e64b3.org.
+150.8.0.10.in-addr.arpa.
+lechim-bolezni.ru.
+50.177.168.192.in-addr.arpa.
+recover-my-files.softonic.com.
+api.modegallerian.se.
+fe.brandreachsys.com.
+62.29.117.200.in-addr.arpa.
+morrieabramson.com.
+scrub.bluekloud.com.
+titanium30-en.url.trendmicro.com.
+apps.facebook.com.
+51.0.0.192.in-addr.arpa.
+syndication.exoclick.com.
+ar.y8.com.
+cmbinfo.com.s8b1.psmtp.com.
+jj13bk2j1.91nd.
+gui.m.mofos.com.
+_045_80_9.
+isatap.uqc.ne.jp.
+orcart.facebook.com.
+138.171.48.190.in-addr.arpa.
+b-0.19-230f4008.1.1518.19d4.3ea1.410.0.65wlql4n1en4fh5da6mrnh7gai.avqs.mcafee.com.
+photos-b.ak.fbcdn.net.
+iitem.ru.
+ocsp.comodoca.com.
+pbsmnwubnxhutgmod.ms.
+posta39a.mailbeta.libero.it.
+badge.facebook.com.
+www.kmplayer.com.
+mail.wilcopm.com.
+bbmwlaw.com.1.arsmtp.com.
+www.videobb-ideal.com.
+ibahia.globo.com.
+.
+sobrecostarica.blogspot.com.
+a.root-servers.net.
+www.caltagironeeditore.it.
+59.2.164.189.in-addr.arpa.
+a2.sphotos.ak.fbcdn.net.
+www.google.com.
+the-uuu.com.
+i.w.inmobi.com.
+webcache.googleusercontent.com.
+131.114.139.187.in-addr.arpa.
+s-static.ak.fbcdn.net.
+mail.shoptools.ru.
+apps.facebook.com.
+ecosca.mass.rbc.ru.
+maconleadersrealtors.com.
+pipocacombo.com.
+www.youtube.com.
+api.facebook.com.
+dns.msftncsi.com.
+i1.uploadem.com.
+clickmaster.xtgem.com.
+6.51.67.70.in-addr.arpa.
+profile.ak.fbcdn.net.
+de.wikibooks.org.
+photos-f.ak.fbcdn.net.
+140.132.46.186.in-addr.arpa.
+48.81.95.201.in-addr.arpa.
+dns.msftncsi.com.
+84.228.102.201.in-addr.arpa.
+yavmamemo.deviantart.com.
+contacts.msn.com.nsatc.net.
+ocsp.verisign.com.
+aol.com.
+pabloyyo.com.
+german-uribe.blogspot.com.
+fr-fr.facebook.com.
+a.root-servers.net.
+218.84.12.189.in-addr.arpa.
+www.forosdelweb.com.
+a7.sphotos.ak.fbcdn.net.
+4-1.qlty.finarea.ch.
+a.root-servers.net.
+www.juegosdevestirfamosos.net.
+_924_86_1.
+claydyergess.tk.
+huaren.su.
+8.75.188.190.in-addr.arpa.
+s-static.ak.fbcdn.net.
+static.ak.fbcdn.net.
+soundcloud.com.
+elminaya.blogspot.com.
+wlan.lycos.de.
+cdn.api.twitter.com.
+lubimoff.msk.ru.
+a.root-servers.net.
+205.166.141.120.in-addr.arpa.
+www.tubemonsoon.com.
+dibisrl.com.
+m.badjojo.com.
+a1404.w41.akamai.net.
+6.103.153.186.in-addr.arpa.
+static.ak.fbcdn.net.
+136.149.120.190.in-addr.arpa.
+googleads.g.doubleclick.net.
+www.peliculas21.com.
+229.144.179.189.in-addr.arpa.
+cache-download.real.com.
+c1617.sandai.net.
+polypeck.ru.
+www.solomonbrothers.com.
+www.alimtyaz.com.
+libera.com.
+dmsas.com.s8a1.psmtp.com.
+photos-g.ak.fbcdn.net.
+ssl.gstatic.com.
+www.amazon.com.
+bfgb.files.wordpress.com.
+_753_33_3.
+www.google.com.
+223.55.167.190.in-addr.arpa.
+google.com.
+mx1.iacna.com.
+167.127.144.187.in-addr.arpa.
+twitter.com.
+183.196.84.200.in-addr.arpa.
+servizio-pubblico.com.
+www.iconj.com.
+conduit.anybodyoutthere.com.
+crl.microsoft.com.
+www.mizukinana.jp.
+16.253.137.187.in-addr.arpa.
+www.adobe.com.
+20minutos.feedsportal.com.
+scholar.google.es.
+www.youtube.com.
+ajax.googleapis.com.
+www.foxsportsla.com.
+www.yorkpress.co.uk.
+215.238.247.189.in-addr.arpa.
+haverford.edu.s8a2.psmtp.com.
+www.archiexpo.com.
+i4.ytimg.com.
+jsbcglobal.net.
+www.robertbrault.com.
+cdn.api.twitter.com.
+news.err.ee.
+ajax.googleapis.com.
+a1.twimg.com.
+photos-e.ak.fbcdn.net.
+60.32.41.187.in-addr.arpa.
+brucellosis.com.
+fbcdn-sphotos-a.akamaihd.net.
+photos-d.ak.fbcdn.net.
+profile.ak.fbcdn.net.
+www.beijingtoday.com.cn.
+hi-in.facebook.com.
+a3.sphotos.ak.fbcdn.net.
+www.delirica.com.
+a7.sphotos.ak.fbcdn.net.
+253.104.217.81.in-addr.arpa.
+is.gd.
+www.dollstory.eu.
+i2.ytimg.com.
+www.ozgurkocaeli.com.tr.
+db._dns-sd._udp.0.1.168.192.in-addr.arpa.
+a.root-servers.net.
+34.114.74.190.in-addr.arpa.
+a4.sphotos.ak.fbcdn.net.
+www.youtube.com.
+seabld.itn.ru.
+s-static.ak.fbcdn.net.
+cdn.flashtalking.com.
+k9bhl94w3.16gn.
+payment.socialgamenet.com.
+dnl-01.geo.kaspersky.com.
+_493_32_4.
+mail.hubbardberry.com.
+a.root-servers.net.
+thelawstore.co.uk.
+67.201.176.189.in-addr.arpa.
+jigsaw.w3.org.
+polskaviva.com.
+mail.avu.org.
+131.244.142.190.in-addr.arpa.
+a.root-servers.net.
+ad.adtegrity.net.
+masae.deviantart.com.
+www.pmi.org.in.
+149.150.195.187.in-addr.arpa.
+roverparts.spb.ru.
+takio.com.
+majeko.ru.
+support.google.com.
+banboon.com.
+vfs.com.s10a1.psmtp.com.
+www.eluniversaldelvalle.mx.
+a.root-servers.net.
+b._dns-sd._udp.0.73.168.192.in-addr.arpa.
+chesterfield.k12.va.us.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+cache.internal.query.g06.yahoodns.net.
+xxzrg8djy.37xo.
+ingersoll-inc.com.
+i.cdn.turner.com.
+100.214.18.189.in-addr.arpa.
+view.atdmt.com.
+dl_dir.qq.com.
+dtboot.orbitdownloader.com.
+219.61.25.186.in-addr.arpa.
+platform.twitter.com.
+lyramondlicht.deviantart.com.
+www.idiomasonline-ba.com.ar.
+devices.live.com.
+126.39.51.96.in-addr.arpa.
+mail.cygnuscorp.com.
+sweetgum.nybg.org.
+www.panet.co.il.
+a8.sphotos.ak.fbcdn.net.
+4.1.168.192.in-addr.arpa.
+www.stopbadware.org.
+tmss.trendmicro.com.
+api.facebook.com.
+inbound.sgsproperties.com.netsolmail.net.
+d2089876.xoom.it.
+www.cakgames.com.
+fs.motorolasolutions.com.
+89.152.195.98.in-addr.arpa.
+extremetracking.com.
+crl3.digicert.com.
+prenoms.doctissimo.fr.
+webcache.googleusercontent.com.
+www.farsiweb.ir.
+mxh24.hichina.com.
+www.vizio.com.
+profile.ak.fbcdn.net.
+a2.sphotos.ak.fbcdn.net.
+mundicenter.pt.
+billing.sharo4ka.ru.
+mail.peteparks.com.
+a.root-servers.net.
+ntp.glb.nist.gov.
+a.root-servers.net.
+www.0zz0.com.
+verizon.net.
+grocerybiz.com.s8a1.psmtp.com.
+192.168.34.201.in-addr.arpa.
+76.217.139.190.in-addr.arpa.
+166.142.160.187.in-addr.arpa.
+jualanterkini.blogspot.com.
+fs11.myvi.ru.
+a4.sphotos.ak.fbcdn.net.
+theforwardforum.blogspot.com.
+safebrowsing-cache.google.com.
+nipinxofutbol.blogspot.com.
+ocsp.verisign.net.
+www.original-vision.com.
+249.108.79.187.in-addr.arpa.
+g.msn.com.nsatc.net.
+botrytis.polytechnique.fr.
+fifo.com.
+www.self.ox.ac.uk.
+j::88wcuv.r19p2l8b.
+87.16.57.187.in-addr.arpa.
+152.184.55.65.in-addr.arpa.
+cepram.org.ar.
+1.0.168.192.in-addr.arpa.
+twitter.com.
+www.google.com.
+clientalerts.ebay.com.
+sinobbs.com.
+independent.org.
+drugstorenews.com.
+a2.sphotos.ak.fbcdn.net.
+groups.l.google.com.
+mobilemaps.clients.google.com.
+s0.2mdn.net.
+a.root-servers.net.
+www.sonico.com.mx.
+lmliberty.files.wordpress.com.
+adserver.adtech.de.
+audit.303br.net.
+accounts.google.com.
+www.aewmerotica.com.
+photos-d.ak.fbcdn.net.
+max.ifd.uni.wroc.pl.
+news.yahoo.com.
+mx.harborinsurancegroup.com.
+mail.google.com.
+75.175.75.190.in-addr.arpa.
+130.71.15.187.in-addr.arpa.
+it-it.facebook.com.
+elbuenvecino.com.mx.
+a.root-servers.net.
+www.circuloempresariosune.com.
+touraero.spb.ru.
+mx1.unicitynetwork.com.
+pacificcoastimports.com.
+190.101.50.186.in-addr.arpa.
+4.77.168.66.in-addr.arpa.
+franklin.kyschools.us.
+qe8jid8px.12as.
+a0.twimg.com.
+db._dns-sd._udp.0.1.168.192.in-addr.arpa.
+srsg.violenceagainstchildren.org.
+588-async.olark.com.
+photos-a.ak.fbcdn.net.
+produccionmusical.org.
+fukuya-k.co.jp.
+balcakoyu.com.
+safebrowsing.clients.google.com.
+initialvision.com.
+www.facebook.com.
+img413.imageshack.us.
+190.147.229.190.in-addr.arpa.
+safebrowsing.clients.google.com.
+plugin.maldi.tv.
+aa.xml.slide.com.
+photos-a.ak.fbcdn.net.
+a.root-servers.net.
+www.mozilla-europe.org.
+client.akamai.com.
+elsys.de.
+nxcache.nexon.net.
+perfectpay.com.
+tomam.ru.
+a1.sphotos.ak.fbcdn.net.
+63.6d6963726f736f6674.636f6d.80h40041e86.webcfs00.com.
+46.158.220.66.in-addr.arpa.
+www.infolinks.com.
+api.breaktimestudios.com.
+cncsjz.line.p2pdl.baofeng.net.
+49.30.78.189.in-addr.arpa.
+spotlight-verlag.de.
+84.211.144.189.in-addr.arpa.
+tamcar.galeon.com.
+sp.cwfservice.net.
+2:iw9t7:u.n05r1n1r.
+fbcdn-sphotos-a.akamaihd.net.
+wix.com.
+l.yimg.com.
+134.55.156.187.in-addr.arpa.
+facor.ru.
+www.google-analytics.com.
+time.stdtime.gov.tw.
+i4.ytimg.com.
+imgv2-4.scribdassets.com.
+0.gravatar.com.
+0.11-a30f2081.d0810b1.1518.19d4.3ea1.210.0.2pqgphplpzu9q1ej3p6m28uv2q.avqs.mcafee.com.
+www.etnopsico.org.
+sn3.mailshell.net.
+exchange.volioytrejos.com.
+365-async.olark.com.
+profile.ak.fbcdn.net.
+a.root-servers.net.
+114.218.12.83.in-addr.arpa.
+5.1.168.192.in-addr.arpa.
+computerscan.com.
+a.root-servers.net.
+7nbeknju7.43vi.
+images.dvdcollects.com.
+static.app.widdit.com.
+platform.ak.fbcdn.net.
+_119_63_8.
+css.wlxrs.com.
+p2pupgrade.gamedl.qq.com.
+196.15.95.190.in-addr.arpa.
+js2.wlxrs.com.
+amosrivera.com.
+static.ak.fbcdn.net.
+download.xbox.com.
+www.blush4u.com.
+www.genteloca.com.
+crl.globalsign.net.
+infocentertour.ru.
+www.coniefoxdress.com.
+news.mongabay.com.
+231.230.121.76.in-addr.arpa.
+news.google.com.mx.
+mail.prodigy.net.mx.
+63.1.168.192.in-addr.arpa.
+0-257.channel.facebook.com.
+www.all-4-home.net.
+i4.ytimg.com.
+whos.amung.us.
+thecreaturehub.com.lan.
+a.root-servers.net.
+bitly.com.
+init.ess.apple.com.
+www.radiotorre.org.
+coralhotels.com.
+atna.net.
+d1z5wd2gcq19yd.cloudfront.net.
+ad.auditude.com.
+a5.sphotos.ak.fbcdn.net.
+a.root-servers.net.
+142.134.175.187.in-addr.arpa.
+www.plusgay.es.
+www.facebook.com.
+especiales.latino.msn.com.
+google.com.
+vp.sip.messenger.msn.com.
+www.youtube.com.
+www.google.com.
+162.33.248.189.in-addr.arpa.
+pearsoncustom.com.mail6.psmtp.com.
+developers.facebook.com.
+lvb.avg.com.
+b._dns-sd._udp.0.1.168.192.in-addr.arpa.
+0.260214.com.
+lvb.avg.com.
+mail.eatrightamerica.com.
+www.facebook.com.
+a.root-servers.net.
+www.facebook.com.
+xdsmhost.wellmark.com.
+a.root-servers.net.
+www.google-analytics.com.
+mail.villagehamburg.com.
+adcode.adengage.com.
+a3.sphotos.ak.fbcdn.net.
+creative.ak.fbcdn.net.
+www.trinityatierra.com.
+connect.facebook.net.
+parlament-kbr.ru.
+144.179.100.94.in-addr.arpa.
+static.ak.fbcdn.net.
+s0.2mdn.net.
+ocsp.digicert.com.
+www.acfas.org.
+barakus.tiscali.com.
+www.googleadservices.com.
+static.ak.fbcdn.net.
+blu.stj.s-msn.com.
+www.taringa.net.
+revistadcasa.uol.com.br.
+allstarhomeloans.com.
+letmewatch.name.
+a1.sphotos.ak.fbcdn.net.
+m.addthisedge.com.
+www.ferrovial.com.
+sterneagee.com.
+w1197.photobucket.com.
+224.147.99.190.in-addr.arpa.
+a7.sphotos.ak.fbcdn.net.
+s-external.ak.fbcdn.net.
+www.gstatic.com.
+www.juegosycoches.com.
+wikimediafoundation.org.
+www.geom.uiuc.edu.
+www.igihe.com.
+a4.sphotos.ak.fbcdn.net.
+www.linkwithin.com.
+gats.popcap.com.
+es.youtube.com.
+www.facetofacethemovie.com.
+189.224.188.88.in-addr.arpa.
+poetashispanicos.blogspot.com.
+ksn2-12.kaspersky-labs.com.
+zone28.hotwords.com.br.
+negro004.com.
+s.youtube.com.
+losfueroscf.com.
+wtol.com.
+32.170.248.189.in-addr.arpa.
+a7.sphotos.ak.fbcdn.net.
+www.facebook.com.
+www.limelife.com.
+ksn1-11-part2.kaspersky-labs.com.
+download767.avast.com.
+www.starmedia.com.
+82.247.231.201.in-addr.arpa.
+webmail.beumer.com.
+103.80.208.201.in-addr.arpa.
+a3.sphotos.ak.fbcdn.net.
+rules.securestudies.com.
+yahoo.com.
+ads.affbuzzads.com.
+clients1.google.com.
+photos-e.ak.fbcdn.net.
+foxdeportes.com.
+62.63.169.124.in-addr.arpa.
+tracker.torrentbay.to.
+www.sai.org.co.
+202.94.122.200.in-addr.arpa.
+track.hardcoretoons.com.
+0-292.channel.facebook.com.
+hi-in.facebook.com.
+www.google.com.
+www.revodvr.com.
+8muy7vane.88hx.
+schroff.com.
+flashpirate.com.
+a6.sphotos.ak.fbcdn.net.
+b7dktcdu4.k87r2j0h.
+jp.99chats.com.
+secure.jwatch.org.
+79.251.181.189.in-addr.arpa.
+59.125.191.190.in-addr.arpa.
+6.00.2900.3698.dnsbl7.mailshell.net.
+twimg0-a.akamaihd.net.
+t4.tagstat.com.
+a286.phobos.apple.com.
+profile.ak.fbcdn.net.
+58.82.42.62.in-addr.arpa.
+compfxnet.com.
+nice-puppy.com.
+sv.wikipedia.org.
+gdata.youtube.com.
+www.todoanimes.com.
+1.courier-push-apple.com.akadns.net.
+7daycatering.co.uk.
+s9.addthis.com.
+www.converthub.com.
+com.ua.
+25qd3ix24.i51d4x9f.
+translate.google.com.mx.
+hedltindia.com.
+www.genogenogeno.com.
+t2.gstatic.com.
+rmd.atdmt.com.
+bb624022.linkbucks.com.
+www.altoatacama.cl.
+valuerichonline.com.
+teredo.ipv6.microsoft.com.
+profile.ak.fbcdn.net.
+iparadigms.com.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+m.facebook.com.
+midas.org.uk.
+equest.com.
+21.152.248.201.in-addr.arpa.
+kyuketsuki-usagi.blogspot.com.
+www.vol-gta.com.
+a.root-servers.net.
+flindal.ru.
+sadasdnwqjrrww.net.
+a1984.phobos.apple.com.
+128.2.14.186.in-addr.arpa.
+uralsib-sk.ru.
+sc.tom.com.
+api.twitter.com.
+234.13.206.196.in-addr.arpa.
+phart.ru.
+www.mywebproxies.com.
+www.napcor.com.
+profile.ak.fbcdn.net.
+hgvjrr2pu.r86a6w5y.
+184.47.250.201.in-addr.arpa.
+www.dhl.com.uy.
+www.google.com.
+www.bezz41.skyrock.com.
+www.picshared4free.com.
+ke33aeg:m.a48a7y2z.
+video.humanesociety.org.
+vladgsound.wordpress.com.
+time.chttl.com.tw.
+columbuspolice.org.
+agromash.by.
+photos-h.ak.fbcdn.net.
+www.imiclk.com.
+oblogdeeoblogda.wordpress.com.
+pipic.com.s5a1.psmtp.com.
+187.63.111.189.in-addr.arpa.
+36.128.93.190.in-addr.arpa.
+data.mobclix.com.
+kupperberg.com.
+112.228.90.200.in-addr.arpa.
+storage.conduit.com.
+i4.ytimg.com.
+photos-c.ak.fbcdn.net.
+twoo.com.
+youtube-ui.l.google.com.
+telekbird.com.cn.
+www.animacor.com.
+_419_13_9.
+es.888.com.
+ocsp.verisign.com.
+profile.ak.fbcdn.net.
+apps.facebook.com.
+platform.twitter.com.
+ads.channelcapital.net.
+googleads.g.doubleclick.net.
+lazarus.elte.hu.
+mail.phillipsind.com.
+www.crankshaftcoalition.com.
+pixel.facebook.com.
+www.danielaperfumes.cl.
+www.microsoft.com.
+photos-b.ak.fbcdn.net.
+time-a.netgear.com.
+120.62.172.189.in-addr.arpa.
+robrprsmtp01.csavgroup.com.br.
+ad.xtendmedia.com.
+orcart.facebook.com.
+www.hoerzu.de.
+www.dripirrigation.org.
+tracker.bittorrent.am.
+photos-f.ak.fbcdn.net.
+not-mail.avfsrv.ru.
+a.root-servers.net.
+a.root-servers.net.
+131.70.239.189.in-addr.arpa.
+www.djcrazychris.de.
+.
+paris-dl.ru.
+114.130.189.79.in-addr.arpa.
+rwsytm82g.l62f8c0h.
+ronees.unets.ru.
+www.condusef.futbolfinanciero.com.mx.
+profile.ak.fbcdn.net.
+dj.renren.com.
+64.112.100.189.in-addr.arpa.
+ox-m.d.chango.com.
+ventechtrain.com.
+creative.ak.fbcdn.net.
+www.barranquilla.gov.co.
+www.facebook.com.
+d2091148.xoom.it.
+sk.wikipedia.org.
+login.live.com.
+49.133.168.192.in-addr.arpa.
+digital.com.
+www.stopbadware.org.
+login.live.com.
+tools.buzzwestcash.com.
+static.chartbeat.com.
+photos-b.ak.fbcdn.net.
+187.214.8.201.in-addr.arpa.
+wlcmail.com.
+rexel.cl.
+118.163.173.189.in-addr.arpa.
+bit.ly.
+dl34.hotgoo.com.
+luissanchez.deviantart.com.
+content.dl-rms.com.
+bit.ly.
+a.root-servers.net.
+14.144.148.46.in-addr.arpa.
+regalad.com.tw.
+go.srvnow.com.
+v4.cache5.c.youtube.com.
+171.228.244.190.in-addr.arpa.
+www.shesabetty.com.
+api-read.facebook.com.
+a.root-servers.net.
+chaussuralacarte.com.
+www.viewleicester.co.uk.
+newmail.to.pager.tascom.ru.
+baycom.com.tw.
+48.149.220.66.in-addr.arpa.
+_ldap._tcp.
+dns.msftncsi.com.
+_425_86_2.
+www.facebook.com.
+174.84.232.84.in-addr.arpa.
+ad.metanetwork.com.
+optusnet.coma.u.
+a.root-servers.net.
+correodepuntadeleste.com.
+ticketland.ru.
+174.86.214.189.in-addr.arpa.
+c.msn.com.
+holsten.gtn.ru.
+google.com.
+cdn.api.twitter.com.
+gohealthcast.com.inbound15.mxlogic.net.
+www.chandal.tv.
+mx1.comcast.com.
+www.hotmail.com.
+loieqeeu.name.
+api.geo.kontagent.net.
+www.comunio.es.
+0-44.channel.facebook.com.
+www.facebook.com.
+42.187.178.190.in-addr.arpa.
+www.surgedirect.com.
+www.peeperz.com.
+nakcumrrt.32lx.
+c-0.19-31096008.82.1518.19d4.36d4.400.0.3ku5gfh9hvtfb5rsdblk41wvsb.avqs.mcafee.com.
+www.milenio.com.
+ve.starmedia.com.
+creative.ak.fbcdn.net.
+www.scienceviews.com.
+7mo-cbime.blogspot.com.
+hotmail.com.
+pagead2.googlesyndication.com.
+www.britishmotorcyclegear.com.
+ciengarabatos.blogspot.com.
+www.stvgroup.cz.
+46.139.206.186.in-addr.arpa.
+179.134.247.72.in-addr.arpa.
+www.wooaudio.com.
+www.youtube.com.
+hi-in.facebook.com.
+a2.sphotos.ak.fbcdn.net.
+mango-skin-pack.softonic.com.
+malosocityperu.blogspot.com.
+60.218.9.70.in-addr.arpa.
+sissonscale.com.
+6.188.172.189.in-addr.arpa.
+a17.phobos.apple.com.
+d2092950.xoom.it.
+bgky.com.
+platform.twitter.com.
+sites.google.com.
+www.howtofixcomputers.com.
+4.20.12.108.in-addr.arpa.
+www.google.com.
+wz2s.taobao.com.
+104.2.4.64.in-addr.arpa.
+asset1.modelmanagement.com.
+apps.facebook.com.
+mailhost.dynaloy.com.
+87.8.34.186.in-addr.arpa.
+a.root-servers.net.
+dogtimemedia.squarespace.com.
+estilos.prodigy.msn.com.
+83.65.69.189.in-addr.arpa.
+kissphoto.net.
+ec.atdmt.com.
+wellthatsjustme.blogspot.com.
+t0.gstatic.com.
+google.com.
+bitkoo.com.
+fbcdn-sphotos-a.akamaihd.net.
+216.111.131.189.in-addr.arpa.
+google.com.
+photos-b.ak.fbcdn.net.
+girl.bodyartgo.com.
+ttjmhy6jq.23ra.
+smtp3.everyday.com.kh.
+ns.orenburg-cci.ru.
+linkhelp.clients.google.com.
+vostok.vladpost.marine.su.
+newsrss.bbc.co.uk.
+www.amazon.fr.
+api.twitter.com.
+dns.msftncsi.com.
+www.xemtiep.com.
+63.23.190.88.in-addr.arpa.
+www.astrobot.eu.
+img233.imageshack.us.
+b._dns-sd._udp.0.1.168.192.in-addr.arpa.
+pt-br.facebook.com.
+ping3.teamviewer.com.
+dinorun03.xgenstudios.com.
+csi.gstatic.com.
+wirelessretailinc.com.s8b2.psmtp.com.
+ds.serving-sys.com.
+www.be.
+71.169.55.190.in-addr.arpa.
+profile.ak.fbcdn.net.
+windows-server-training.com.
+thebeaveronline.co.uk.
+www.youtube.com.
+wpad.
+mail.chtivo.ru.
+lolkaaaaa3.in.
+mccane.co.uk.
+www.criollosperuanos.com.
+251.159.200.112.in-addr.arpa.
+i3.ytimg.com.
+187.200.53.187.in-addr.arpa.
+www.el-guru.com.
+distfiles.macports.org.
+graph.facebook.com.
+6d70.61706d656266.636f6d.80hd822cfb1.webcfs00.com.
+lisa42.hubpages.com.
+video-1-11.rutube.ru.
+226.129.87.190.in-addr.arpa.
+antropologiayecologiaupel.blogspot.com.
+plugin.maldi.tv.
+a.root-servers.net.
+rcp.na.blackberry.com.
+97.231.134.115.in-addr.arpa.
+wanadoo.de.
+colingasm.tumblr.com.
+server4.operamini.com.
+a.root-servers.net.
+profile.ak.fbcdn.net.
+ontariodie.com.s8b2.psmtp.com.
+43.146.106.186.in-addr.arpa.
+navy.net.
+i4.ytimg.com.
+marketing.menasoftware.com.
+houseplants-care.blogspot.com.
+powersonic.net.2.0001.arsmtp.com.
+85.239.65.187.in-addr.arpa.
+70.23.224.78.in-addr.arpa.
+selena-tour.ru.
+sbcglobal.net.
+www.obloggeral.com.
+api.facebook.com.
+2.bp.blogspot.com.
+www.irc-hispano.es.
+www.bluempegs.com.
+profile.ak.fbcdn.net.
+ssl.gstatic.com.
+autocrib.com.
+_042_76_7.
+mikutankyu.blog132.fc2.com.
+ist1-3.filesor.com.
+cdn-0.nflximg.com.
+110.251.64.202.in-addr.arpa.
+arizona.aaa.com.
+riskmetrics.com.inbound10.mxlogicmx.net.
+m1.fank.ru.
+s453.videobb.com.
+mtstravel.com.
+developers.facebook.com.
+widgets.amung.us.
+s-static.ak.facebook.com.
+hasslacher.at.
+profile.ak.fbcdn.net.
+www.chatvibes.com.
+85.237.65.187.in-addr.arpa.
+tapasmss-1.edwardjones.com.
+buodz2agl.80ph.
+static.ak.fbcdn.net.
+9.media.bustedtees.cvcdn.com.
+teredo.ipv6.microsoft.com.
+a1.sphotos.ak.fbcdn.net.
+en.wikipedia.org.
+www.vampire-diaries.es.
+www.cardiofy.com.
+a7.sphotos.ak.fbcdn.net.
+a3.sphotos.ak.fbcdn.net.
+www.videosvideojuegos.com.
+mail.playcore.com.
+segurosygarantias.com.ar.
+checkip.dyndns.org.
+bluestarbus.com.
+rbbyno:xe.e69k6l2n.
+steviadolce.com.py.
+bewag.se.
+photos-h.ak.fbcdn.net.
+www.feedburner.com.
+www.gra.gi.
+ar-ar.facebook.com.
+es.perfectworld.aeriagames.com.
+nocado.msk.ru.
+173.199.1.118.in-addr.arpa.
+hope-academies.com.
+a.root-servers.net.
+gamereleases.teamxbox.com.
+www.hentailoves.me.
+a.root-servers.net.
+www.sgourosmp3.com.
+3e-co.com.s8b2.psmtp.com.
+174.23.58.201.in-addr.arpa.
+kasdancommunications.com.
+marinaconcrete.com.
+1.201.85.75.in-addr.arpa.
+www.izaping.com.
+aol.com.
+www.google.com.
+graph.facebook.com.
+21.77.30.189.in-addr.arpa.
+player.nakedsword.com.
+246.109.28.99.in-addr.arpa.
+_902_76_6.
+www.hoobing.com.
+www.facebook.com.
+photos-d.ak.fbcdn.net.
+ad.doubleclick.net.
+hotmail.com.
+ia.media-imdb.com.
+fbcdn-profile-a.akamaihd.net.
+live6.truelook.com.
+tas.orangeads.fr.
+auditplusservice.ru.
+qyahds.com.
+en.wikipedia.org.
+gw.incompany.ru.
+melissamcclain.hubpages.com.
+nappanet.net.
+a.root-servers.net.
+pixel.facebook.com.
+96.225.46.189.in-addr.arpa.
+photos-h.ak.fbcdn.net.
+a.root-servers.net.
+mail.printecs.ru.
+barcampguayaquil.org.
+download.windowsupdate.com.
+external.ak.fbcdn.net.
+a1725.l.akamai.net.
+ece.cornell.edu.
+a.jango.com.
+comcluster.cxense.com.
+tander.kmv.ru.
+www.tickets.com.
+ad-g.doubleclick.net.
+dns.msftncsi.com.
+186.220.145.59.in-addr.arpa.
+s.youtube.com.
+static.ak.fbcdn.net.
+dmvs321.denken.or.jp.
+external.ak.fbcdn.net.
+143.172.246.203.in-addr.arpa.
+s2.youtube.com.
+b._dns-sd._udp.lan.
+mail.terra.es.
+api.twitter.com.
+b._dns-sd._udp.0.1.168.192.in-addr.arpa.
+berndrosinski.de.
+91.42.173.190.in-addr.arpa.
+platform.twitter.com.
+pixel.facebook.com.
+photos-d.ak.fbcdn.net.
+gift-order.ru.
+13.200.37.124.in-addr.arpa.
+mail.waveware.com.
+a1725.l.akamai.net.
+google.com.
+relay.voice.messenger.msn.com.
+_480_59_9.
+lookquick.com.
+dnl-01.geo.kaspersky.com.
+a.root-servers.net.
+www.wsoftlink.com.
+streams.fusionchicago.com.
+pixel.rubiconproject.com.
+sites.google.com.
+8.250.59.200.in-addr.arpa.
+rs115l3.rapidshare.com.
+iol.co.za.
+service2.pricegong.com.
+www.blackberry.com.
+ir.nielsen.com.
+mx01.simplesiteonline.com.
+www.youtube.com.
+www.facebook.com.
+login.live.com.
+vmwebfe.voice.yahoo.com.
+photos-g.ak.fbcdn.net.
+loading2.widdit.com.
+www.charitiesnfplaw.com.
+www.missionaccomplished.co.uk.
+api.twitter.com.
+ter4ik.ru.
+www.bonerowner.com.
+www.flycell.com.mx.
+platform.twitter.com.
+top-fwz1.mail.ru.
+virginradio.ca.
+mailin.v6.t-online.de.
+api.twitter.com.
+16.video.mystreamservice.com.
+www.savannajones.com.
+secure.shared.live.com.
+photos-e.ak.fbcdn.net.
+99.235.39.190.in-addr.arpa.
+acummy.com.
+82.72.204.190.in-addr.arpa.
+www.fa.domain_not_set.invalid.
+i-0.19-a30e3079.83.1518.19d4.3ea1.210.0.17bmp285vgz7ept5ngbp7d2itb.avqs.mcafee.com.
+gorgeous-teardrops.blogspot.com.
+o1.t26.net.
+developers.facebook.com.
+29.45.105.189.in-addr.arpa.
+tango.mybboard.net.
+adspaces.ero-advertising.com.
+154.200.208.77.in-addr.arpa.
+www.antena3.com.
+a1003.w41.akamai.net.
+www.washingtonpostreprints.com.
+a4.sphotos.ak.fbcdn.net.
+france24.mobiclip.com.
+zone104.hotwords.com.br.
+a.root-servers.net.
+p7-buy.itunes.apple.com.
+ksn2-12.kaspersky-labs.com.
+rpmffe.com.
+australia.newads.com.
+cid-0c4d020e598f0974.profile.live.com.
+csi.gstatic.com.
+native.np.ac.playstation.net.
+tkrdr.storage.msn.com.
+www.pixmac.de.
+www.rip-factor.com.
+49.139.20.190.in-addr.arpa.
+nwwlc.org.
+google.com.
+107.203.143.175.in-addr.arpa.
+www.mejor-sonido.com.
+static.cda.pl.
+andrews.esc18.net.
+blogs.aecomo.org.
+mexico.cnn.com.
+a.root-servers.net.
+s7.addthis.com.
+108.98.19.190.in-addr.arpa.
+webconferencing.avaya.com.
+r.nocouchpotato.com.
+124.141.219.87.in-addr.arpa.
+a7.sphotos.ak.fbcdn.net.
+api26.thetrafficstat.net.
+goo.gl.
+www.norden.lv.
+146.205.129.186.in-addr.arpa.
+campodemarte.com.
+video1.spunkybee.com.
+www.socialgrowthtechnologies.com.
+et8.xhamster.com.
+profile.ak.fbcdn.net.
+s-external.ak.fbcdn.net.
+216.220.152.201.in-addr.arpa.
+apps.mobilityware.com.
+nxcache.nexon.net.
+community.g4s.com.
+fbcdn-profile-a.akamaihd.net.
+mlssw.com.
+photos-a.ak.fbcdn.net.
+download332.avast.com.
+s10.histats.com.
+pubads.g.doubleclick.net.
+apps.facebook.com.
+sur.pep.pemex.com.
+81.78.248.87.in-addr.arpa.
+117.240.236.84.in-addr.arpa.
+.
+a1.sphotos.ak.fbcdn.net.
+25.164.191.190.in-addr.arpa.
+113.229.110.123.in-addr.arpa.
+bbklaw.com.mail11.psmtp.com.
+ca.yahoo.com.
+clk.atdmt.com.
+165.48.51.68.in-addr.arpa.
+photos6.pop6.com.
+cepheidpharmaceuticals.com.
+www.imef.org.mx.
+www.cocinaconrecetas.com.
+27.105.123.190.in-addr.arpa.
+.
+loansmadeeazy.com.
+peterharveyco.com.au.
+photos-f.ak.fbcdn.net.
+nude-males.nudeandcute.com.
+a7.sphotos.ak.fbcdn.net.
+scrat.hellocoton.fr.
+rt.legolas-media.com.
+urs.microsoft.com.
+mail.rhytec.com.
+99.194.231.190.in-addr.arpa.
+multiplos.hotwords.com.br.
+rover.ebay.com.
+photos-a.ak.fbcdn.net.
+174.207.133.124.in-addr.arpa.
+140.247.191.216.in-addr.arpa.
+photos-b.ak.fbcdn.net.
+rendwell.ryazan.ru.
+acsi.org.
+girondinstv.com.
+weather.services.conduit.com.
+maie.com.
+dartt.net.
+download-judging-amy.edogo.com.
+agnifm.ru.
+profile.ak.fbcdn.net.
+p130.hmarzaber.com.
+creative.ak.fbcdn.net.
+w88.go.com.
+odata.intel.com.
+aff.publicdisgrace.com.
+www.dingin.com.
+coupons.walmart.com.
+safebrowsing.clients.google.com.
+photos-h.ak.fbcdn.net.
+clients1.google.com.
+ssl.gstatic.com.
+winecellarinnovations.com.s10a2.psmtp.com.
+sp.cwfservice.net.
+th04.deviantart.net.
+bfz.ru.
+gfx8.hotmail.com.
+a.root-servers.net.
+ips-invite.iperceptions.com.
+147.53.1.190.in-addr.arpa.
+twitter.com.
+stream66-he.grooveshark.com.
+www.alexa.com.
+mail.buildingengines.com.
+sms.mts.ru.
+138.65.23.186.in-addr.arpa.
+www.epoch.com.
+.
+187.253.195.187.in-addr.arpa.
+postman.gbh.com.
+obgyn.ru.
+static.ak.fbcdn.net.
+alisavet.ru.
+teredo.ipv6.microsoft.com.
+cluster1a.us.messagelabs.com.
+img.mediaplex.com.
+photos-a.ak.fbcdn.net.
+dmitriyev.ru.
+plus.google.com.
+program.avast.com.
+oysh4bj6p.28iz.
+sn1msg3020214.gateway.messenger.live.com.
+www.editorialtelevisa.com.mx.
+secure.victoriassecret.com.edgekey.net.
+industrial.clickyourproduct.com.
+66.39.236.189.in-addr.arpa.
+a6.sphotos.ak.fbcdn.net.
+140.247.141.201.in-addr.arpa.
+smx.westminstercollege.edu.redcondor.net.
+geoengineers.com.
+pe.starmedia.com.
+www.aeromexico.com.mx.
+maps.google.com.mx.
+www.chrisbartlett.org.
+vloox.com.
+mail.fitflat.de.
+ad.doubleclick.net.
+www.brooklynpubliclibrary.org.
+www.passionblogs.com.
+www.arthritishelpguide.com.
+banif.pt.
+mail.cnti-penza.ru.
+a.root-servers.net.
+bs.serving-sys.com.
+m.facebook.com.
+www.girlsnews.tv.
+i1.social.s-msft.com.
+a5.sphotos.ak.fbcdn.net.
+85.207.245.190.in-addr.arpa.
+24.media.tumblr.com.
+www.pantyhosesex.ws.
+bcoa.us.
+a.root-servers.net.
+photos-g.ak.fbcdn.net.
+a1.sphotos.ak.fbcdn.net.
+126.88.0.186.in-addr.arpa.
+23.59.174.190.in-addr.arpa.
+a.root-servers.net.
+smtp.fibrehost.net.
+platform.twitter.com.
+tools.google.com.
+sod-a.rsc-cdn.org.
+10.115.142.190.in-addr.arpa.
+gaming.stackexchange.com.
+support.google.com.
+mx01.windstream.net.
+www.facebook.com.
+www.freedownload3.com.
+76.66.151.189.in-addr.arpa.
+54.172.100.190.in-addr.arpa.
+static.ak.fbcdn.net.
+www.amazon.de.
+www.agoda.vn.
+graph.facebook.com.
+ksn7.kaspersky-labs.com.
+www.oipolloi.com.
+profile.ak.fbcdn.net.
+a5.sphotos.ak.fbcdn.net.
+cinepivates.blogspot.com.
+mail.zdrav.spb.ru.
+creative.ak.fbcdn.net.
+20minutos.feedsportal.com.
+cityvillefb1.static.zgncdn.com.
+www.paranominal.com.
+118.229.138.98.in-addr.arpa.
+pixel.quantserve.com.
+a.root-servers.net.
+a5.sphotos.ak.fbcdn.net.
+deportebase.elcomerciodigital.com.
+g.edu-servers.net.
+ma156-r.analytics.edgesuite.net.
+developers.facebook.com.
+j5d4gsftz.11or.
+noctambulo.com.
+carlosavelli.it.
+86.231.35.189.in-addr.arpa.
+www.blogger.com.
+a.root-servers.net.
+s-static.ak.facebook.com.
+www.premiumstorage.info.
+enkamoscity.com.home.
+www.bing.com.
+1001books.ru.
+dns.msftncsi.com.
+pbid.iforex.com.
+pixel.facebook.com.
+www.allaboutshoes.ca.
+s1-powerpoint.vo.msecnd.net.
+leyendasdelecuador.blogspot.com.
+a3.da1.akamai.net.
+accounts.google.com.
+photos-a.ak.fbcdn.net.
+75.44.218.121.in-addr.arpa.
+mail.kraski.spb.ru.
+offer.g.ebay.com.
+www.redflamencos.org.
+spotirama.blogspot.com.
+cp37902.edgefcs.net.
+css-ace.com.
+ksn2-12.kaspersky-labs.com.
+elvideoclubdelos80.blogspot.com.
+pagead2.googlesyndication.com.
+www.blackberry.com.
+williamson2012blog.dailymail.co.uk.
+236.125.126.206.in-addr.arpa.
+tutorial-para-blender.uptodown.com.
+0-292.channel.facebook.com.
+radicaepost.com.
+spopk.org.
+www.juegosdepalabras.com.
+profile.ak.fbcdn.net.
+creative.ak.fbcdn.net.
+android.clients.google.com.
+elupus.com.
+nrjweggi.com.
+bit.ly.
+www.crosspoint.tv.
+www.youtube-nocookie.com.
+manhattancc.org.
+www.google-analytics.com.
+82.211.141.201.in-addr.arpa.
+funmoods.com.
+connect.facebook.net.
+romsfullworld.blogspot.com.
+csc3-2010-crl.verisign.com.
+155.212.230.190.in-addr.arpa.
+helpdesk.princeton.edu.
+sylvia.mmodels.net.
+79.231.2.187.in-addr.arpa.
+cafeycabaret.com.
+a6.sphotos.ak.fbcdn.net.
+aulatic.cl.
+cdn-1.nflximg.com.
+www.anasac.cl.
+29.media.tumblr.com.
+www.jscount.com.
+lookatmyhorsemyhorseisamazing.com.
+69.155.6.69.in-addr.arpa.
+36.13.7.89.in-addr.arpa.
+taztheambo.blogspot.com.
+www.asomagdalena.org.
+mx3.investici.org.
+s0.2mdn.net.
+a.root-servers.net.
+itc-01.ru.
+dns.msftncsi.com.
+s2.youtube.com.
+plus.google.com.
+ad.foxnetworks.com.
+eewine.com.
+dasgelbeforum.de.org.
+186.34.168.192.in-addr.arpa.
+ozum.ru.
+tour.jizz-on-my-gf.com.
+www.centraloutpost.com.
+scream-room.blogspot.com.
+137.147.85.85.in-addr.arpa.
+www.msftncsi.com.
+simple-timer-clocks.googlecode.com.
+ambar-jeans.ru.
+33.72.169.184.in-addr.arpa.
+dns.msftncsi.com.
+buildexpo.ru.
+e566.b.akamaiedge.net.
+a4.sphotos.ak.fbcdn.net.
+11.224.193.190.in-addr.arpa.
+citrys.ca.
+video.google.com.mx.
+csi.gstatic.com.
+www.niktutos.wordpress.com.
+169.151.160.201.in-addr.arpa.
+198.255.37.184.in-addr.arpa.
+db._dns-sd._udp.lan.
+mail.mbsuk.com.
+api.theknot.com.
+www.thisfellow.com.
+planet-group.co.uk.
+www.louisvuitton.org.in.
+developers.facebook.com.
+www.jpfgallery.com.
+www.corepredictivedialer.com.
+static02.olx-st.com.
+carpartsonsale.com.
+3.89.181.207.in-addr.arpa.
+www.advent.com.
+94.217.56.186.in-addr.arpa.
+21.228.171.69.in-addr.arpa.
+46.64.127.200.in-addr.arpa.
+73.26.0.10.in-addr.arpa.
+ph.jobomas.com.
+apps.facebook.com.
+cs.oag.state.tx.us.
+www.google.com.
+www.browtf.com.
+147.198.117.62.in-addr.arpa.
+www.wfn.org.
+twitter.com.
+mps.hwcdn.net.
+21.175.99.24.in-addr.arpa.
+edge-wunderkit.dotcloud.com.
+93.docs.google.com.
+suncars.com.tw.
+browse.postcards.org.
+up0002-blus30838-00.auth.np.ac.playstation.net.
+171.62.26.83.in-addr.arpa.
+a1.sphotos.ak.fbcdn.net.
+clkads.com.
+ryanbuildingmaterials.com.
+static.ak.fbcdn.net.
+srx.main.ebayrtm.com.
+photos-h.ak.fbcdn.net.
+57.34.169.1.in-addr.arpa.
+tinyurl.com.
+sonydadc.com.
+masco.cc.
+www.facebook.com.
+www.kunstkopie.at.
+post3.cox.com.
+.
+98.2.86.200.in-addr.arpa.
+252.91.45.200.in-addr.arpa.
+109.42.205.187.in-addr.arpa.
+shout2a.gnax.net.
+a.root-servers.net.
+www.freefullfrontals.co.uk.
+d15gt9gwxw5wu0.cloudfront.net.
+203.81.127.187.in-addr.arpa.
+numericafunding.com.
+www.google.com.
+kangarobin.cixx6.com.
+sbcglobal.net.
+www.alternativechannel.tv.
+gfx3.hotmail.com.
+www.ssn.org.
+plusone.google.com.
+126.165.240.89.in-addr.arpa.
+23.229.171.69.in-addr.arpa.
+a.root-servers.net.
+depacnglw0dc001.code1.emi.philips.com.
+144.140.235.24.in-addr.arpa.
+201.145.79.190.in-addr.arpa.
+57.ru.
+donsapaugh.com.
+studioscalia.com.
+223.78.250.190.in-addr.arpa.
+146.84.54.68.in-addr.arpa.
+r._dns-sd._udp.0.2.168.192.in-addr.arpa.
+www.nikonlinks.com.
+photos-f.ak.fbcdn.net.
+csi.gstatic.com.
+169.166.226.91.in-addr.arpa.
+dkz.info.
+mail.live.com.
+s.youtube.com.
+fbcdn-photos-a.akamaihd.net.
+assetman23.d1g.com.
+www.facebook.com.
+static.ak.fbcdn.net.
+edge1.catalog.video.msn.com.
+8.99.215.189.in-addr.arpa.
+static.ak.fbcdn.net.
+yfdb213o.com.
+oglobo.globo.com.
+wwf.org.uk.
+photos-h.ak.fbcdn.net.
+8.70.56.85.in-addr.arpa.
+dordrecht.nl.
+digg.com.
+www.spanish.audiogil.es.
+buynowfromusa.com.
+death-note-hentai.famous-toons-facial.com.
+_023_83_0.
+mail.newworldtrust.com.
+givision.net.
+www.charmbeadswholesale.com.
+photos-g.ak.fbcdn.net.
+us.data.toolbar.yahoo.com.
+196.0.168.192.in-addr.arpa.
+wat.com.
+inbound.edgewaterdesign.com.netsolmail.net.
+edentworld.com.
+groups.l.google.com.
+m.facebook.com.
+241.35.10.187.in-addr.arpa.
+leerlibros.com.
+59.188.20.186.in-addr.arpa.
+25.207.25.189.in-addr.arpa.
+38.147.220.66.in-addr.arpa.
+234.1.0.192.in-addr.arpa.
+troy30c.org.s5b1.psmtp.com.
+keine.at.
+podermilitar.blogspot.com.
+groundside.com.
+87.19.168.192.in-addr.arpa.
+a.root-servers.net.
+www.profilebanner.com.
+connect.facebook.net.
+db._dns-sd._udp.0.1.168.192.in-addr.arpa.
+189.85.104.200.in-addr.arpa.
+90elf.spiegel.de.
+www.wladhe.com.
+saabworkshop.com.
+www.mywebsearch.comm.
+www.justinpictures.org.
+www.yahoo.com.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+46.101.168.192.in-addr.arpa.
+productnews.link.net.
+ipblmg.com.
+googleads.g.doubleclick.net.
+www.belkin.com.
+193.1.170.85.in-addr.arpa.
+newsrss.bbc.co.uk.
+a8.sphotos.ak.fbcdn.net.
+eearthlink.com.
+www.flintshirechronicle.co.uk.
+abacushk.com.inbound10.ttasia.net.
+sites.google.com.
+www.saludmd.com.
+ec.atdmt.com.
+damianvoltes.com.
+k-s-p.ru.
+b.static-cdn.playfish.com.
+external.ak.fbcdn.net.
+emersonmgmt.com.
+231.43.143.189.in-addr.arpa.
+186.226.209.77.in-addr.arpa.
+conf.socialvi.be.
+webmail.villarrobledo.com.
+1.118.28.186.in-addr.arpa.
+mail34.opentransfer.com.
+static.ak.fbcdn.net.
+194.196.248.201.in-addr.arpa.
+157.122.41.190.in-addr.arpa.
+bar.leo.org.
+_ldap._tcp.dd273816-6837-406d-8b28-d47fdadd0ea3.domains._msdcs.ey.net.
+www.gstatic.com.
+yahoo.com.
+api.twitter.com.
+teredo.ipv6.microsoft.com.
+mail.gladcorp.com.
+informatika.net.ru.
+ad.yieldmanager.com.
+gg.google.com.
+ow.ly.
+www.gmperformanceparts.com.
+a.root-servers.net.
+livefilestore.com.multi.uribl.com.
+static.polldaddy.com.
+id.google.com.mx.
+static-resource.np.community.playstation.net.
+moranandco.com.s7b2.psmtp.com.
+bs.serving-sys.com.
+195.7.95.201.in-addr.arpa.
+yytayna.com.
+fetch.flashget.com.
+profile.ak.fbcdn.net.
+ff.connextra.com.
+es.wikipedia.org.
+fbcdn-profile-a.akamaihd.net.
+photos-a.ak.fbcdn.net.
+ruhlman.com.
+www.leverguns.com.
+static.ak.fbcdn.net.
+auto.mercadolibre.com.ar.
+8-courier.push.apple.com.
+www.facebook.com.
+getpersonas-cdn.mozilla.net.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+www.dietadiaria.com.
+a2.sphotos.ak.fbcdn.net.
+i3.ytimg.com.
+www.materialesparatocados.com.
+photos-f.ak.fbcdn.net.
+tock.usno.navy.mil.
+globaltranceinvasion.com.
+www.midespertardeconciencia.ning.com.
+apps.facebook.com.
+rospres.com.
+www.abcjuegos.net.
+plus.google.com.
+t.tmimgcdn.com.
+www.youtube.com.
+191.200.72.190.in-addr.arpa.
+profile.ak.fbcdn.net.
+premierfitnessclubs.com.
+simdesk.com.
+wortschatz.informatik.uni-leipzig.de.
+terra.uplanet.ru.
+ur.wikipedia.org.
+endz.nne.elektra.ru.
+202.187.19.186.in-addr.arpa.
+images.google.com.
+explore.live.com.
+de.wikipedia.org.
+db._dns-sd._udp.0.1.168.192.in-addr.arpa.
+twitpic.com.
+ekpc.com.
+go.srvnow.com.
+17.98.56.85.in-addr.arpa.
+turnkeymarketing.us.
+google.com.
+a8.sphotos.ak.fbcdn.net.
+media2sm.firstshowing.net.
+forum.japantoday.com.
+a.root-servers.net.
+content.yieldmanager.edgesuite.net.
+static.ak.fbcdn.net.
+chhg.biz.
+bodyandhealth.canada.com.
+65.203.21.23.in-addr.arpa.
+mail.brprint.de.
+190.35.209.77.in-addr.arpa.
+a5.sphotos.ak.fbcdn.net.
+seriyps.ru.
+201.95.27.187.in-addr.arpa.
+csi.gstatic.com.
+profile.ak.fbcdn.net.
+babymaker.mauryshow.com.
+62.69.249.84.in-addr.arpa.
+alcatraz.wikia.com.
+pathwayproductions.com.
+www.facebook.com.
+74.201.0.10.in-addr.arpa.
+39.170.2.178.in-addr.arpa.
+emtec-group.com.
+amnet.net.au.
+photos-a.ak.fbcdn.net.
+a.root-servers.net.
+game-gt.com.
+humour.wikinut.com.
+asktoolbar.weather.com.
+preveaclinic.com.
+api.twitter.com.
+a.rad.msn.com.
+photos-e.ak.fbcdn.net.
+webcache.googleusercontent.com.
+mail.successfactors.com.
+smtp.beagvs.com.
+91.44.51.190.in-addr.arpa.
+au.movies.yahoo.com.
+ekran-tv.ru.
+a.appbank.com.
+map.media6degrees.com.
+75.254.254.220.in-addr.arpa.
+www.homeinbayarea.com.
+gross.ru.
+mail.travesi.com.
+254.211.142.187.in-addr.arpa.
+local-sn.contacts.msn.com.
+www.businessweek.com.
+meridiansystems.com.
+shared.live.com.
+culturacomic.com.
+opisventures.com.
+www.inkapoker.com.
+sharethis.com.
+gliocchimarroni.blogspot.com.
+www.google.com.
+609.talkgadget.google.com.
+b-0.19-23096008.481.1518.19d3.3ea0.410.0.iksp3etvn9s9utfq893mqspvf5.avqs.mcafee.com.
+img6.ask.fm.
+thesecretworldofacraftaholic.blogspot.com.
+www.facebook.com.
+5735-100.cudamail.com.
+es-la.facebook.com.
+www.jkhglmncd48.com.
+www.youtravel.com.au.
+imgur.com.multi.uribl.com.
+215.245.206.190.in-addr.arpa.
+plusone.google.com.
+dns.msftncsi.com.
+aqgc545xp.31uw.
+187.126.25.189.in-addr.arpa.
+developers.facebook.com.
+inbound.scanlanfamilyfarms.com.namesecuremail.net.
+susu.ac.ru.
+dr._dns-sd._udp.0.2.168.192.in-addr.arpa.
+53.227.171.69.in-addr.arpa.
+www.belkin.com.
+www.facebook.com.
+photos-f.ak.fbcdn.net.
+_666_11_4.
+hubbell-canada.com.s7b1.psmtp.com.
+teredo.ipv6.microsoft.com.
+2.1.168.192.in-addr.arpa.
+udig.com.
+carlossotomorales.blogspot.com.
+pt.trafficjunky.net.home.
+static.ak.fbcdn.net.
+ba.ckground.com.
+a.root-servers.net.
+euro.mediotiempo.com.
+es-es.fxfeeds.mozilla.com.
+ru.wikipedia.org.
+data.flurry.com.
+sn1msg1020127.gateway.messenger.live.com.
+a.root-servers.net.
+96.45.25.80.in-addr.arpa.
+blitz.nocrawl.www.dik.nl.
+es-la.facebook.com.
+118.188.140.69.in-addr.arpa.
+lcbenefits.com.inbound15.mxlogicmx.net.
+www.mamemimo.com.
+110.30.31.190.in-addr.arpa.
+www.antena3tv.es.
+files.myopera.com.
+a4.sphotos.ak.fbcdn.net.
+manga.hentai.ms.
+toolbarqueries.google.com.
+photos-f.ak.fbcdn.net.
+api.twitter.com.
+www.jornada.unam.mx.
+penskemercedes.com.s8b1.psmtp.com.
+bay.messenger.services.live.com.
+wpad.
+bt.yikuai.com.
+avatar.nimbuzz.com.
+kinesis.co.uk.
+216.175.108.186.in-addr.arpa.
+201.132.43.178.in-addr.arpa.
+photos-h.ak.fbcdn.net.
+gooble.com.
+hits.e.cl.
+248.154.158.189.in-addr.arpa.
+177.140.193.187.in-addr.arpa.
+s0.2mdn.net.
+www.ebayanuncios.es.
+www.airwick.com.mx.
+api.ak.facebook.com.
+a8.sphotos.ak.fbcdn.net.
+meme-spot.tumblr.com.
+dns.msftncsi.com.
+bibriesca2009.keepandshare.com.
+www.givetoqueens.ca.
+mail.heliumm.com.
+dr._dns-sd._udp.lan.
+time.chttl.com.tw.
+ink.voskresensk.ru.
+54.254.56.190.in-addr.arpa.
+csc3-2010-crl.verisign.com.
+swcmail.net.
+arbia.it.
+www.airforce-magazine.com.
+51.127.0.190.in-addr.arpa.
+tr.dohop.com.
+theairloom.files.wordpress.com.
+147.19.125.84.in-addr.arpa.
+206.54.87.186.in-addr.arpa.
+a.root-servers.net.
+ax.init.itunes.apple.com.
+p1t.ru.
+profile.ak.fbcdn.net.
+pixel.facebook.com.
+www.buriedmirror.com.
+phone.com.
+es.y8.com.
+xrfelzx.rjzl.
+realnetworks.com.
+www.praben.cl.
+ad.doubleclick.net.
+michelleobamawatch.com.
+tech.tln.lib.mi.us.
+websearch.ask.com.
+198.10.176.190.in-addr.arpa.
+mailrelay01.virginmedia.co.uk.
+photos-d.ak.fbcdn.net.
+capitulosdenarutoshippuden.blogspot.com.
+woodstock.k12.vt.us.
+www.web-flv-player.com.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+z7mjefkuu.04zs.
+246.172.87.67.in-addr.arpa.
+gaom.hit.gemius.pl.
+content.yieldmanager.edgesuite.net.
+126.37.43.190.in-addr.arpa.
+cleanmymac.softonic.de.
+a.root-servers.net.
+intlreg.aol.com.
+54.111.162.189.in-addr.arpa.
+matcher-rbc.bidder7.mookie1.com.
+102.108.22.195.in-addr.arpa.
+www.echodesign.com.
+platform.ak.fbcdn.net.
+www.hovernauts.com.
+photos-e.ak.fbcdn.net.
+_185_82_0.
+202.161.97.76.in-addr.arpa.
+yahoo.ca.
+e1.f1213.mail.yahoo.com.
+map.no.
+198.184.176.189.in-addr.arpa.
+79.19.152.189.in-addr.arpa.
+chat.facebook.com.
+www.jmarcano.com.
+www.businessweek.com.
+ksn3-11.part1.kaspersky-labs.com.
+49.218.41.83.in-addr.arpa.
+36.213.10.82.in-addr.arpa.
+static.panoramio.com.
+s-static.ak.fbcdn.net.
+d2100708.xoom.it.
+a.root-servers.net.
+www.boxingbets.ru.
+28.176.19.95.in-addr.arpa.
+ls2web.redmond.corp.microsoft.com.
+safebrowsing-cache.google.com.
+apps.facebook.com.
+vpn-cc1.reliablehosting.com.
+98.146.82.189.in-addr.arpa.
+lh4.googleusercontent.com.
+114.39.79.94.in-addr.arpa.
+it-it.facebook.com.
+nsx-e.np.dl.playstation.net.
+apps.facebook.com.
+254.125.214.201.in-addr.arpa.
+227.39.135.187.in-addr.arpa.
+smtpin2.usinternet.com.
+18.137.91.186.in-addr.arpa.
+estebanfuentealba.files.wordpress.com.
+ad.yieldmanager.com.
+letter.ly.
+static.ak.facebook.com.
+www.abc.es.
+84.68.28.186.in-addr.arpa.
+133.75.220.95.in-addr.arpa.
+zaragozame.com.
+photos-f.ak.fbcdn.net.
+integration.klarna.com.
+freelink.org.
+www.facebook.com.
+22.90.248.189.in-addr.arpa.
+39.187.29.189.in-addr.arpa.
+0-125.channel.facebook.com.
+a1003.w41.akamai.net.
+_660_41_2.
+static.ak.fbcdn.net.
+freakshare.net.
+www.youtube.com.
+www.g4tv.com.
+70.71.33.190.in-addr.arpa.
+www.defensetech.org.
+dr._dns-sd._udp.lan.
+smtp.glittered-pastel.net.
+publicpolicy.com.1.arsmtp.com.
+161.14.179.190.in-addr.arpa.
+systems42ltd.com.
+angelesysuscuentos.blogspot.com.
+dns.msftncsi.com.
+vacsend.ru.
+w.sharethis.com.
+sbcgoabl.net.
+gnow.com.
+lifestream.glifestream.aim.com.
+52.17.66.87.in-addr.arpa.
+whlr9:vdj.84gg.
+84.5.216.203.in-addr.arpa.
+pixel.facebook.com.
+www.freehomemademovie.com.
+41.55.241.189.in-addr.arpa.
+68.12.59.186.in-addr.arpa.
+www.archivisionstudio.com.
+_940_20_1.
+mail.isgtechnologies.com.
+safebrowsing.clients.google.com.
+bluegraysky.blogspot.com.
+lh5.googleusercontent.com.
+careers.msn.com.
+www.google.com.
+www.hjkomr.com.
+sc19.rules.mailshell.net.
+s-external.ak.fbcdn.net.
+pixel.facebook.com.
+a5.sphotos.ak.fbcdn.net.
+33.96.251.82.in-addr.arpa.
+es.wikipedia.org.
+mx0.uniserve.ca.
+gorrosdequirofanojaner.blogspot.com.
+api.tweetdeck.com.
+sux2cocuf.s19g9z0c.
+www.lamaripepa.com.
+photos-d.ak.fbcdn.net.
+lorillard.com.
+zynga1-a.akamaihd.net.
+up.ro7k.net.
+e-states.ru.
+a4.sphotos.ak.fbcdn.net.
+binarytech.wordpress.com.
+40.1.152.201.in-addr.arpa.
+photos-d.ak.fbcdn.net.
+mail.google.com.
+argos.co.uk.
+8-courier.push.apple.com.
+152.193.18.186.in-addr.arpa.
+dx3723.tinyurl.com.
+shop.productwiki.com.
+s15279541.onlinehome-server.info.
+update.avg.com.
+premiersurgical.com.s7b2.psmtp.com.
+a.root-servers.net.
+time.chttl.com.tw.
+106.170.224.186.in-addr.arpa.
+google.com.
+adadvisor.net.
+photos-a.ak.fbcdn.net.
+a.root-servers.net.
+apps.facebook.com.
+secure.shared.live.com.
+yahoo.com.
+www.epicgameads.com.
+blufiles.storage.msn.com.
+ashfordsearch.com.s9a2.psmtp.com.
+v3.nonxt7.c.youtube.com.
+profile.chcf.org.
+busy-at-home.com.
+mail.mercergov.org.
+www.fb.telemakingweb.com.
+humorwit.com.
+www.xtrf.eu.
+www.100forexbrokers.com.
+70.79.73.78.in-addr.arpa.
+a.root-servers.net.
+126.116.45.190.in-addr.arpa.
+a.ads2.msads.net.
+www.alldemotivational.com.
+googleads.g.doubleclick.net.
+imagenes.es.sftcdn.net.
+freemarket.kiev.ua.
+ellarguero.info.
+tripletorsion.com.
+i1.images.mofosworldwide.com.
+www.facebook.com.
+i1.ytimg.com.
+profile.ak.fbcdn.net.
+www.alliedmoulded.com.
+www.mikelozano.com.mx.
+a.root-servers.net.
+kommarsolutions.com.
+arianacb.obolog.com.
+es.y8.com.
+oi560.photobucket.com.
+dailyfun4u.com.
+.
+profile.live.com.
+webmail.joyeriagutierrezsousa.com.
+www.facebook.com.
+www.socialgrowthtechnologies.com.
+arvidarealtor.com.
+photos-g.ak.fbcdn.net.
+6be7434q4.77ng.
+mail.fnmsbranch.com.
+dmntbank.msk.ru.
+pixel.facebook.com.
+www.solomotoparts.com.
+cn1.redswoosh.akadns.net:443.
+a0.twimg.com.
+content.yieldmanager.edgesuite.net.
+www.google.com.mx.
+mail.nabarreria.com.
+paramirarnos.blogspot.com.
+v15.lscache1.c.youtube.com.
+www.drm-x.com.
+cityvillefb1.static.zgncdn.com.
+www.googleadservices.com.
+y4aw25vth.57av.
+plusone.google.com.
+20.141.132.92.in-addr.arpa.
+coniferit.net.
+a.root-servers.net.
+250.48.105.190.in-addr.arpa.
+polkadotlighthouseuk.blogspot.com.
+addons.mozilla.org.
+teredo.ipv6.microsoft.com.
+it-it.facebook.com.
+192.64.144.186.in-addr.arpa.
+profile.ak.fbcdn.net.
+s.ytimg.com.
+national1direct.com.
+www.facebook.com.
+vosmd.com.
+mdawmdexmjaxmjaxmg.info.
+49.137.249.186.in-addr.arpa.
+a.root-servers.net.
+www.food-allergy.org.
+dnstest.baofeng.com.
+www.google.com.
+a.root-servers.net.
+www.elblogdecineespanol.com.
+s1-excel.vo.msecnd.net.
+www.uz.
+213.241.209.201.in-addr.arpa.
+blog.gamesparadise.com.au.
+static.ak.fbcdn.net.
+loading3.widdit.com.
+a.root-servers.net.
+a.root-servers.net.
+254.48.17.190.in-addr.arpa.
+cloudtv.accu-weather.com.
+profile.ak.fbcdn.net.
+d2098308.xoom.it.
+um14.eset.com.
+asweetadventure.com.
+clients4.google.com.
+iscnvx.lmsc.lockheed.com.
+apps.facebook.com.
+191.96.15.129.in-addr.arpa.
+184.86.103.80.in-addr.arpa.
+us.img.e-planning.net.
+es-es.facebook.com.
+analyser.oli.tudelft.nl.
+11.8.34.201.in-addr.arpa.
+77.200.191.186.in-addr.arpa.
+www.googleadservices.com.
+a.root-servers.net.
+a.root-servers.net.
+108.157.202.190.in-addr.arpa.
+a.root-servers.net.
+money.msn.com.
+download858.avast.com.
+www.rotavirusvaccine.org.
+ranking.enfeel.com.
+s.youtube.com.
+rad.msn.com.
+steinberg2002.com.
+data.mxm.ch.
+a.root-servers.net.
+www.eraltd.org.
+b-0.19-21025008.1581.1518.19d4.3ea1.410.0.pqkwldtwiadawn4nfkewen5pvi.avqs.mcafee.com.
+photos-g.ak.fbcdn.net.
+a.root-servers.net.
+photos-e.ak.fbcdn.net.
+a.root-servers.net.
+mail.ivillage.com.
+mozilla.mirror.nexicom.net.
+classic.mountaingear.com.
+226.241.61.200.in-addr.arpa.
+reddog.net.au.
+download.windowsupdate.com.
+plus.google.com.
+creative.ak.fbcdn.net.
+a7.sphotos.ak.fbcdn.net.
+provo.edu.
+searchjustice.usdoj.gov.
+www.classically-elegant.com.
+web.csuchico.edu.
+www.laporteriadejorgejuan.com.
+a.root-servers.net.
+scrapsandthecity.gotop100.com.
+v2.cache8.c.youtube.com.
+jattgroup.com.
+static.ak.fbcdn.net.
+www.dosomethingamazing.com.
+ads.mobclix.com.
+search.softonic.com.
+tuckerlaw.net.p4.mx-route.com.
+inkman.co.th.
+yahoo.com.
+www.erica.biz.
+www.youtube.com.
+sales.vip.tom.com.
+a.root-servers.net.
+178.36.48.212.in-addr.arpa.
+apps.facebook.com.
+232.84.231.189.in-addr.arpa.
+mail.zublatt.com.
+_953_46_7.
+e5413.g.akamaiedge.net.
+platform.ak.fbcdn.net.
+www.yahoo.com.
+cheaptickets.com.s7a2.psmtp.com.
+respuestas.wikia.com.
+2.docs.google.com.
+125.166.89.108.in-addr.arpa.
+118.249.16.200.in-addr.arpa.
+blairschools.org.
+racetech.com.
+westwood-apartments.com.
+rpo.ru.
+ocsp.geotrust.com.
+www.google.com.
+it-it.facebook.com.
+191.204.107.189.in-addr.arpa.
+223.224.140.175.in-addr.arpa.
+db._dns-sd._udp.0.1.168.192.in-addr.arpa.
+opessworprvygpj.net.
+ax26.a.cocolog-nifty.com.
+53.134.38.187.in-addr.arpa.
+pixel.facebook.com.
+43.163.20.190.in-addr.arpa.
+static.ak.fbcdn.net.
+www.vogue.fr.
+gmail.com.
+r._dns-sd._udp.0.0.168.192.in-addr.arpa.
+www.gstatic.com.
+aerolineasmexicanas.com.mx.
+127.67.164.58.in-addr.arpa.
+a4.mzstatic.com.
+89.54.198.190.in-addr.arpa.
+cdn3.cpmstar.com.
+mail.google.com.
+developers.facebook.com.
+content.yieldmanager.edgesuite.net.
+a.rad.msn.com.
+breakmysex.info.
+recep.com.
+t2.gstatic.com.
+it.carsmaniacs.com.
+u20.eset.com.
+www.lindsaylohanweb.com.
+www.facebook.com.
+209.51.194.187.in-addr.arpa.
+www.tatil-gunleri.com.
+sup.live.com.
+apus.edu.
+signup.wazzub.info.
+hog.assets2.zgncdn.com.
+fbcdn-profile-a.akamaihd.net.
+www.arpia.be.
+truevalue.com.
+130.137.148.190.in-addr.arpa.
+mt0.google.com.
+207.2.27.77.in-addr.arpa.
+imgs1.smutxx.com.
+img100.xvideos.com.
+153.250.103.80.in-addr.arpa.
+platform.twitter.com.
+29.53.222.189.in-addr.arpa.
+liveupdate.symantecliveupdate.com.
+images.amazon.com.
+atlantarubber.com.
+opentranslators.transifex.net.
+inbound.willistire.com.netsolmail.net.
+www.dokterdokter.nl.
+cdn.magiclevel.com.
+api-read.facebook.com.
+tools.google.com.
+levitontelcom.com.
+a.root-servers.net.
+www.facebook.com.
+ocsp.verisign.com.
+dy1719dhn.h86k5y2l.
+a2.sphotos.ak.fbcdn.net.
+www.diccionariopubli.com.
+s-external.ak.fbcdn.net.
+mail.google.com.
+28.78.59.85.in-addr.arpa.
+www.pautefacil.com.
+fbcdn-profile-a.akamaihd.net.
+77.206.222.190.in-addr.arpa.
+dnl-01.geo.kaspersky.com.
+www.oafiliado.com.br.
+www.superzooi.com.
+ad.harrenmedianetwork.com.
+virgin.net.
+platform.twitter.com.
+www.rasushi.com.
+4.220.71.190.in-addr.arpa.
+www.compunetsi.net.
+hg1.hitbox.com.
+safebrowsing.clients.google.com.
+your.schoolfeed.com.
+2.bp.blogspot.com.
+www.teleweb-mallorca.com.
+external.ak.fbcdn.net.
+mail.neemranahotels.com.
+106.229.80.188.in-addr.arpa.
+www.paragonco.com.
+wikipedia-lb.wikimedia.org.
+a2.sphotos.ak.fbcdn.net.
+data.flurry.com.
+g:ka9b7aa.17hk.
+52.68.173.190.in-addr.arpa.
+188.249.211.205.in-addr.arpa.
+m.facebook.com.
+teoten.wordpress.com.
+i.ebayimg.com.
+229.194.74.190.in-addr.arpa.
+photos-d.ak.fbcdn.net.
+a.root-servers.net.
+s.youtube.com.
+laopinionautos.com.
+www.cacillo.it.
+.
+112.114.156.187.in-addr.arpa.
+puzzle.gamesdidi.org.
+royaltyroofing.com.
+2.0.0.10.in-addr.arpa.
+ctdb.samba.org.
+rommai.com.
+211.225.77.190.in-addr.arpa.
+www.ivss.gov.ve.
+translate.google.com.mx.
+clients1.google.com.
+static.ak.fbcdn.net.
+www.youtube.com.
+dorado.cl06.ch.
+ns2.vclk.net.
+www.biotechniques.com.
+mail.dza.com.
+www.google.com.
+d3j5vwomefv46c.cloudfront.net.
+gay-dating-sites.no1reviews.com.
+www.luvsdiapers.com.
+a.root-servers.net.
+imadreamer.metroblog.com.
+55.61.93.58.in-addr.arpa.
+www.bahai-studies.ca.
+bettybeauty.com.
+ad-g.doubleclick.net.
+fr.webrep.avast.com.
+twitter.com.
+a.root-servers.net.
+54.43.208.201.in-addr.arpa.
+ocsp.thawte.com.
+169.5.126.188.in-addr.arpa.
+prospects4travel.com.
+doehler.com.
+177.31.111.189.in-addr.arpa.
+bendliving.com.
+gostosoflexsp.blogspot.com.
+pixel.quantserve.com.
+77.238.81.75.in-addr.arpa.
+safebrowsing.clients.google.com.
+lozzpfn46.u23k3m7e.
+orcart.facebook.com.
+www.youtube.com.
+pixel.facebook.com.
+greenflora.ru.
+fbcdn-photos-a.akamaihd.net.
+n.univision.com.
+chubarama.net.
+a4.da1.akamai.net.
+a.root-servers.net.
+m.facebook.com.
+218.42.198.187.in-addr.arpa.
+external.ak.fbcdn.net.
+it-it.facebook.com.
+twiconsol.com.
+rosautoprom.ru.
+www.flycell.com.ar.
+kaffeine.sourceforge.net.
+xbox360media.ign.com.
+o.httpcs102.wg.msg.sp1.yahoo.com.
+51.159.102.80.in-addr.arpa.
+teredo.ipv6.microsoft.com.
+atlasfreight.net.inbound10.mxlogicmx.net.
+ad.lpxp.net.
+www.watchsolution.com.
+ksn1-12-part2.kaspersky-labs.com.
+www.licc.org.uk.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+40.89.102.187.in-addr.arpa.
+www.ihrtrauringjuwelier.de.
+105.216.72.187.in-addr.arpa.
+m002.maktoob.com.
+www.google.com.
+stepbystep.ru.
+online.casino.winner.com.
+web2.nidhog.com.
+www.redcultura.com.
+a.root-servers.net.
+220.110.120.200.in-addr.arpa.
+56.72.59.193.in-addr.arpa.
+243.51.2.187.in-addr.arpa.
+plusone.google.com.
+members.dyndns.org.
+photos-b.ak.fbcdn.net.
+mail.bcvt.tec.pa.us.
+gjsteel.com.s8b1.psmtp.com.
+www.eluniversal.com.mx.
+www.mozilla.com.
+skype2.en.softonic.com.
+flextel.ru.
+api.twitter.com.
+d3lvr7yuk4uaui.cloudfront.net.
+ja-jp.facebook.com.
+a6.sphotos.ak.fbcdn.net.
+opora.org.ru.
+photos-f.ak.fbcdn.net.
+towersemi.com.
+133.202.79.188.in-addr.arpa.
+www.cantabriatorrent.es.
+www.autogasitalia.it.
+244.58.168.189.in-addr.arpa.
+37.0.215.201.in-addr.arpa.
+google.com.mx.
+www.facebook.com.
+profile.ak.fbcdn.net.
+105.153.122.186.in-addr.arpa.
+developers.facebook.com.
+f.root-servers.net.
+www.comechochos.com.
+server29.appriver.com.
+images.honda-tech.com.
+ad.103092804.com.
+a.root-servers.net.
+www.baskingsharks.org.
+153.121.75.187.in-addr.arpa.
+shepaug.com.inbound10.mxlogic.net.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+mail.gillespieonline.com.
+mtg911.com.
+mail.italee.com.
+tuireg.9158.com.
+connect.facebook.net.
+www.amazon.ca.
+alerts.conduit-services.com.
+e5z1rcx96.n83u2i6c.
+www.zurich.com.ar.
+profile.live.com.
+blobcdn.iegallery.com.
+apps.facebook.com.
+pomogi-rebenku.ru.
+mirinfo.ru.
+www.anamardoll.com.
+32.84.158.79.in-addr.arpa.
+www.nj.com.
+a1003.w41.akamai.net.
+widget.plugrush.com.
+horoskop.vol.at.
+50.26.221.189.in-addr.arpa.
+forum.sh3bwah.maktoob.com.
+www.mizinapecuaro.com.
+apps.facebook.com.
+m.facebook.com.
+d1ros97qkrwjf5.cloudfront.net.
+cs.wikipedia.org.
+download695.avast.com.
+rsvl.unisys.com.
+www.belkin.com.
+www.skyhighlb.com.
+i35.tinypic.com.
+www.macrothink.org.
+rep.netel.net.
+hitltd.msk.su.
+lists-mx.mysql.com.
+connect.facebook.net.
+fxfeeds.mozilla.com.
+www.inspirational-motivational-quotes.com.
+api.twitter.com.
+support.google.com.
+www.conceptoam.com.ar.
+dns2.is.net.pl.
+wpad.
+11.21.206.24.in-addr.arpa.
+37.84.76.190.in-addr.arpa.
+apis.google.com.
+www.toplist.cz.
+photos-f.ak.fbcdn.net.
+_433_49_4.
+a.root-servers.net.
+tap.rubiconproject.com.
+finift.ru.
+video321.info.
+www.sigmabeauty.com.
+www.google.com.
+geo.yahoo.com.
+gamezadvisor.com.
+villakoenig.blogspot.com.
+rwc-temp7.openwave.com.
+portcontractors.com.inbound15.mxlogicmx.net.
+ir.ebaystatic.com.
+9.79.10.187.in-addr.arpa.
+twitter.com.
+www.berklee.edu.
+a4.sphotos.ak.fbcdn.net.
+230.114.172.201.in-addr.arpa.
+tracker.torrent.to.
+allconnect.ru.
+graphicsanddesigns.foroactivo.com.
+goo.gl.
+www.lumen.com.mx.
+16.7.168.192.in-addr.arpa.
+www.yahooka.com.
+mtnlmail.com.
+pagead2.googlesyndication.com.
+vgtribune.com.
+9.48.159.189.in-addr.arpa.
+api-read.facebook.com.
+s-static.ak.facebook.com.
+s-static.ak.fbcdn.net.
+photos-c.ak.fbcdn.net.
+shop.nakedfunny.com.
+mumfordcompany.com.inbound15.mxlogic.net.
+124.143.239.189.in-addr.arpa.
+ksn2-12.kaspersky-labs.com.
+drlopez.com.
+video.google.com.mx.
+72.142.58.85.in-addr.arpa.
+www.hostweb.byethost2.com.
+globetour.ru.
+no-replay.alertreceived.com.
+51.list.themediafinder.com.
+www.codango.com.
+carnationbanc.com.
+being-glamorous.blogspot.com.
+www.lalibcosupport.com.
+api-read.facebook.com.7.
+lb._dns-sd._udp.0.0.168.192.in-addr.arpa.
+a.root-servers.net.
+berriojimenez.blogspot.com.
+imagengratis.org.
+www.ecampus.com.akadns.net.
+224.0.0.10.in-addr.arpa.
+73.140.100.70.in-addr.arpa.
+in.mx.skynet.be.
+apps.facebook.com.
+d2092610.xoom.it.
+www.thisislocallondon.co.uk.
+picasaweb.google.com.
+ufps.chukotka.ru.
+www.youtube.com.
+s2.googleusercontent.com.
+onet.pl.
+ssl.gstatic.com.
+26.23.18.89.in-addr.arpa.
+media02-ak.vivastreet.com.
+opel-werner.de.
+www.macromedia.com.
+www.4msa.com.
+local-bay.contacts.msn.com.
+166.11.234.201.in-addr.arpa.
+189.18.244.117.in-addr.arpa.
+google.com.
+mail.tehn.ru.
+ads.yimg.com.
+www.apple.com.
+merax.ru.
+isatap.home.
+que-video-loco.blogspot.co.nz.
+128.1.16.172.in-addr.arpa.
+www.worldofends.com.
+barracuda2.mbgpepsi.com.
+pixel.rubiconproject.com.
+www.neoteo.com.
+49.147.220.66.in-addr.arpa.
+hackosphere.blogspot.com.
+augmentedrealityblog.files.wordpress.com.
+raveassociates.net.
+a.root-servers.net.
+a4.sphotos.ak.fbcdn.net.
+google.com.
+exotherm.com.inbound10.mxlogicmx.net.
+us.bc.yahoo.com.
+apuntesdelprofesor.over-blog.es.
+www.penguinvids.com.
+a.root-servers.net.
+a7.sphotos.ak.fbcdn.net.
+quotations.about.com.
+api.zynga.com.
+sup.live.com.
+msigeek.disqus.com.
+puzzlingames.com.
+a8.sphotos.ak.fbcdn.net.
+api-read.facebook.com.
+searchclient.live.net.
+avrlider.ru.
+www.computerstore.co.nz.
+urs.microsoft.com.
+educacionmusical.es.
+www.dospuntocerovision.com.
+getlistedsd.com.
+creative.ak.fbcdn.net.
+photos-e.ak.fbcdn.net.
+avril_lavigne-3454.tabsmetal.org.
+www.imagegroup.cl.
+conveyancepartners.com.
+nomoresabotage.com.
+www.rockmx.com.mx.
+s-static.ak.fbcdn.net.
+90.180.107.2.in-addr.arpa.
+www.facebook.com.
+_360_91_4.
+scores.espn.go.com.
+time.chttl.com.tw.
+fbcdn-profile-a.akamaihd.net.
+a5.sphotos.ak.fbcdn.net.
+a.root-servers.net.
+developers.facebook.com.
+urlseek20.vmn.net.
+213.254.76.200.in-addr.arpa.
+pagead2.googlesyndication.com.
+a.root-servers.net.
+88p.ru.
+group36.com.my.
+buoyweather.com.
+blst.msn.com.
+a.root-servers.net.
+ns02.cashparking.com.
+9gag.com.
+apps.facebook.com.
+a.root-servers.net.
+netbit.ru.
+db._dns-sd._udp.0.1.168.192.in-addr.arpa.
+news-assets.rovio.com.
+login.live.com.
+static.ak.fbcdn.net.
+s-external.ak.fbcdn.net.
+c-0.19-a30f1071.40081.1518.19d0.3ea1.400.0.kn9e331jip5d71gr69pjl3h56t.avqs.mcafee.com.
+www.dlpfoodguide.com.
+104.1.168.192.in-addr.arpa.
+photos-g.ak.fbcdn.net.
+baketech.com.
+101.10.217.98.in-addr.arpa.
+a.root-servers.net.
+pmx1.prismnet.com.
+www.hese-project.org.
+vozenoff7.blogspot.com.
+ads.phonemates.com.
+67.200.177.189.in-addr.arpa.
+trastoteca.blogspot.com.
+a3.sphotos.ak.fbcdn.net.
+211.212.143.187.in-addr.arpa.
+a.root-servers.net.
+a2.sphotos.ak.fbcdn.net.
+rons-org.ru.
+ad.yieldmanager.com.
+klimat.vl.ru.
+calendarsglobal.office.glbdns.microsoft.com.
+money.cnn.com.
+apps.facebook.com.
+www.facebook.com.
+nichegohoroshego.narod.ru.
+165.91.132.189.in-addr.arpa.
+ali.shop.sportstoday.com.
+data.flurry.com.
+www.supersavertravel.se.
+es.mg40.mail.yahoo.com.
+msn.com.
+a.root-servers.net.
+cursos-computacion.vivavisos.com.ar.
+www.youtube.com.
+mail1.entertainment.com.
+s0.2mdn.net.
+_998_76_9.
+107.146.220.66.in-addr.arpa.
+pagead2.googlesyndication.com.
+crystalpeaks.com.
+aspmx3.googlemail.com.
+ads.adxpose.com.
+fbcdn-profile-a.akamaihd.net.
+csi.gstatic.com.
+a8.sphotos.ak.fbcdn.net.
+www.adcash.com.
+.
+nochesenlima.com.
+snipergirl.ru.
+tr.wikipedia.org.
+38.73.36.186.in-addr.arpa.
+_785_79_1.
+loquebuscabas.wordpress.com.
+apps.facebook.com.
+dns.msftncsi.com.
+s-static.ak.fbcdn.net.
+mail.de.ensinger-online.com.
+cust10074-1.in.mailcontrol.com.
+113.204.130.186.in-addr.arpa.
+wd-edge.sharethis.com.
+zayuwu.com.
+www.tashadelrae.com.
+appworld.blackberry.com.
+ns2.yr.com.
+visionexotik.com.
+linkhelp.clients.google.com.
+6ru3efog2.m14u0e0e.
+www.dating-chat.net.
+profile.ak.fbcdn.net.
+a.root-servers.net.
+mail2.digipark.com.
+bmx.texasroyalty.com.redcondor.net.
+mailscan.au.edu.
+secure.internetdownloadmanager.com.
+brandonheath.net.
+db._dns-sd._udp.0.1.168.192.in-addr.arpa.
+www.l.google.com.
+cdn1.ads.contentabc.com.
+sn142w.snt142.mail.live.com.
+www.teenteddies.com.
+xcdn.xgraph.net.
+ar-ar.facebook.com.
+a.root-servers.net.
+accountservices.msn.com.
+allcranerentalgeorgia.com.s8b2.psmtp.com.
+bs.serving-sys.com.
+www.robtex.com.
+pottery.ebay.com.au.
+www.google.com.
+ad2games.com.
+246.107.4.171.in-addr.arpa.
+www.nokaut.pl.
+a.root-servers.net.
+download-games.juegosindie.net.
+facebook.com.
+whitestone.spb.ru.
+setup.fanhow.com.
+cdn-1.pics.hardsextubepremium.com.
+a2.twimg.com.
+cim-mf.tmbbank.com.
+ftgx.com.s5a2.psmtp.com.
+row.bc.yahoo.com.
+148.157.68.208.in-addr.arpa.
+245.90.250.190.in-addr.arpa.
+212.60.128.69.in-addr.arpa.
+8.19.170.118.in-addr.arpa.
+a.root-servers.net.
+148.3.62.186.in-addr.arpa.
+pop.asia.secureserver.net.
+l.yimg.com.
+47.208.242.212.in-addr.arpa.
+static.ak.fbcdn.net.
+photos-a.ak.fbcdn.net.
+www.marcacamps.com.
+hi-techsystems.com.s10a2.psmtp.com.
+hall-chem.com.inbound15.mxlogic.net.
+111.184.188.190.in-addr.arpa.
+16.60.153.189.in-addr.arpa.
+ps3pirata.com.
+183.16.106.177.in-addr.arpa.
+check4.facebook.com.
+h20157.www2.hp.com.
+www.gdservice.piczo.com.
+a.root-servers.net.
+d7.zedo.com.
+48.149.220.66.in-addr.arpa.
+a.root-servers.net.
+a8.sphotos.ak.fbcdn.net.
+15.70.78.208.zen.spamhaus.org.
+176.64.32.189.in-addr.arpa.
+www.google-analytics.com.
+142.40.242.88.in-addr.arpa.
+ajax.googleapis.com.
+www.seek.com.au.
+hy.wikipedia.org.
+7.188.112.200.in-addr.arpa.
+eu.wikipedia.org.
+pool.ntp.org.
+www.google-analytics.com.
+vp.kis.ru.
+i4.ytimg.com.
+a4.sphotos.ak.fbcdn.net.
+pqj16dwcxpzn20puatg53jukxowmtp62ctjx.com.
+theeclecticlife.wordpress.com.
+b:hicg4zo.h67f8t0f.
+mail06.enterhost.com.
+www.premiere.frhttp.
+a6.sphotos.ak.fbcdn.net.
+www.potube.com.
+idmtfopfphqwp.biz.
+iphonesubmissions.apple.com.
+www.escolar.com.mx.
+sn116w.snt116.mail.live.com.
+_883_68_0.
+www.patentati.it.
+a3.sphotos.ak.fbcdn.net.
+striker-manager.blogspot.com.
+secure.shared.live.com.
+s1-word-edit.vo.msecnd.net.
+redir.metaservices.microsoft.com.
+sadfas.com.
+twedge02.ohsu.edu.
+8213l4dgx.h23f9j0q.
+135.247.228.94.in-addr.arpa.
+photos-f.ak.fbcdn.net.
+external.ak.fbcdn.net.
+149.206.30.200.in-addr.arpa.
+ic.tynt.com.
+g.ceipmsn.com.
+thecalloflove.blogspot.com.
+denis.stalker.h3q.com.
+jameique.com.
+244.172.82.67.in-addr.arpa.
+svrsecure-g2-aia.verisign.com.
+maquerosmac.blogspot.com.
+i413.photobucket.com.
+www.google.com.
+distilleryimage7.s3.amazonaws.com.
+granvillehouse.blogspot.com.
+www.satireworld.com.
+multi96.thumb.edenflirt.com.
+_716_22_9.
+www.argentinaxplora.com.
+vindiaservices.com.
+www.edmaster.it.
+44.101.243.80.in-addr.arpa.
+nhahouston.com.
+ngf:gxuk1.c14y5u2a.
+www.google-analytics.com.
+ocsp.verisign.com.
+www.msftncsi.com.
+updatekeepalive.mcafee.com.
+a4.sphotos.ak.fbcdn.net.
+www.bryanreesman.com.
+www.ceajalisco.gob.mx.
+kontur-s.ru.
+t2.gstatic.com.
+teraprom.ru.
+76.186.190.189.in-addr.arpa.
+225.177.208.201.in-addr.arpa.
+lucernevalley.net.
+247.68.22.95.in-addr.arpa.
+altex.ru.
+fi.wikipedia.org.
+static.ak.fbcdn.net.
+javadl-esd.sun.com.
+anstracker.no-ip.org.
+www.google.com.
+id.etn.net.
+91.200.66.186.in-addr.arpa.
+correo.ugr.es.
+a1.sphotos.ak.fbcdn.net.
+dtboot.orbitdownloader.com.
+ads.movpod.net.
+48.248.107.189.in-addr.arpa.
+blu.stc.s-msn.com.
+stefi-tk.ru.
+photos-g.ak.fbcdn.net.
+www.tvnotas.com.
+asegenpropiedades.cl.
+a.root-servers.net.
+i2.ytimg.com.
+mail.cityoflafayette.com.
+www.pronosticssportif.com.
+cblproball.com.
+218.254.192.187.in-addr.arpa.
+sites.google.com.
+a2.sphotos.ak.fbcdn.net.
+ads16411.hotwords.es.
+twitter.com.
+a1001.w40.akamai.net.
+stk:zrmf8.b97d6e1h.
+www.mims.com.sg.
+staff.tabideru.com.
+andersenjoy.com.
+a1.sphotos.ak.fbcdn.net.
+71.242.143.187.in-addr.arpa.
+js.media.motortopia.com.
+charbonneau.com.
+www.googleadservices.com.
+www.afianza.com.mx.
+21.168.248.111.in-addr.arpa.
+www.carlkleiner.com.
+photos-a.ak.fbcdn.net.
+crl.usertrust.com.
+selenaweb.org.
+wootton-hall.com.
+236.29.2.24.in-addr.arpa.
+profile.ak.fbcdn.net.
+ssl.gstatic.com.
+64.92.213.201.in-addr.arpa.
+.
+amasscn.en.made-in-china.com.
+api-public.addthis.com.
+view.atdmt.com.
+cocomponents.com.
+www.youtube.com.
+twitter.com.
+a.root-servers.net.
+r.mzstatic.com.
+crprint.com.s6b2.psmtp.com.
+photos-f.ak.fbcdn.net.
+69.249.46.189.in-addr.arpa.
+es.avatars.yahoo.com.
+s-static.ak.facebook.com.
+sexyrebelde69.obolog.com.
+profiles.google.com.
+gfx4.hotmail.com.
+www.gayanime.com.
+berghof.de.
+47.174.1.24.in-addr.arpa.
+mail.wsasystems.com.
+148.121.230.201.in-addr.arpa.
+www.facebook.com.
+time.nist.gov.
+upctv.com.
+127.79.233.178.in-addr.arpa.
+mx.mail.sogou.com.
+api.mixpanel.com.
+a2.sphotos.ak.fbcdn.net.
+200.210.224.190.in-addr.arpa.
+affordableinsurance.us.
+www.colorearte.cl.
+www.uzai.com.
+us.lrd.yahoo.com.
+www.bbc.co.uk.
+recursos.espaciosexy.com.
+external.ak.fbcdn.net.
+136.71.43.208.in-addr.arpa.
+safebrowsing.clients.google.com.
+teredo.ipv6.microsoft.com.
+230.246.159.79.in-addr.arpa.
+64.1.168.192.in-addr.arpa.
+s-static.ak.facebook.com.
+madewithluv.com.
+e906.g.akamaiedge.net.
+a8.sphotos.ak.fbcdn.net.
+www.alfainmo.com.
+photos-c.ak.fbcdn.net.
+www.google.com.
+www.facebook.com.
+q75hrirce.99ax.
+inmortalyvampiros.blogspot.com.
+las-chicas-superpoderosas-z.blogspot.com.
+dns.msftncsi.com.
+51.174.126.2.in-addr.arpa.
+cliffordchance.com.
+www.potter.web.id.
+147.125.46.189.in-addr.arpa.
+gfxp.com.
+www.lifeyoyo.com.
+29.124.45.216.in-addr.arpa.
+vcs2.msg.yahoo.com.
+polychem-usa.com.
+liteonit.com.
+sinlatvcom.chatango.com.
+a.root-servers.net.
+cdn-6.pics.redtubeplatinum.com.
+a.root-servers.net.
+safebrowsing-cache.google.com.
+www.facebook.com.
+ksn2-12.kaspersky-labs.com.
+photos-f.ak.fbcdn.net.
+jtaby.com.
+45.102.150.91.in-addr.arpa.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+ocsp.verisign.com.
+www.kinkydates.com.
+176.216.80.190.in-addr.arpa.
+www.tastygo.com.
+androidsdk.ads.mp.mydas.mobi.
+218.141.97.109.in-addr.arpa.
+noticias.terra.cl.
+www.zorritasconcam.com.
+a4.sphotos.ak.fbcdn.net.
+luciensteil.tripod.com.
+support.euro.dell.com.
+whyweightinternational.com.
+www.google-analytics.com.
+touch.facebook.com.
+validator.w3.org.
+seg.sharethis.com.
+www.super-science-fair-projects.net.
+check6.facebook.com.
+66.177.6.186.in-addr.arpa.
+partyreflections.com.
+74.95.135.187.in-addr.arpa.
+foundation-financial.com.
+a.root-servers.net.
+d2094073.xoom.it.
+jewel-staite.net.
+msc.wlxrs.com.
+c5.zedo.com.
+a.root-servers.net.
+photos-g.ak.fbcdn.net.
+rdgoodgebuilder.co.uk.
+243.102.51.72.in-addr.arpa.
+222.101.199.190.in-addr.arpa.
+a.root-servers.net.
+profile.ak.fbcdn.net.
+es.astrology.yahoo.com.
+76.228.121.123.in-addr.arpa.
+63.42.223.189.in-addr.arpa.
+exp02.eset.com.
+photos-e.ak.fbcdn.net.
+mx2.interworld.net.
+t-online.de.
+www9.effectivemeasure.net.
+a.root-servers.net.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+96.179.165.58.in-addr.arpa.
+ajax.aspnetcdn.com.
+me-cdn.effectivemeasure.net.
+teredo.ipv6.microsoft.com.
+www.adobe.com.
+44-courier.push.apple.com.
+mail.sdoamg.com.
+264lpgc88.08gm.
+81.154.227.77.in-addr.arpa.
+kailea.com.
+114.21.101.187.in-addr.arpa.
+233.170.8.99.in-addr.arpa.
+42.106.81.75.in-addr.arpa.
+kayser-roth.com.s5b2.psmtp.com.
+landquestdevelopment.com.s5b2.psmtp.com.
+:xa96l8dm.75na.
+12.122.172.189.in-addr.arpa.
+ccpi-inc.com.s5b1.psmtp.com.
+photos-a.ak.fbcdn.net.
+163.148.134.174.in-addr.arpa.
+65.145.133.50.in-addr.arpa.
+ssl.gstatic.com.
+extremefitnessco.com.
+www.dofiscal.net.
+a.triggit.com.
+konata-station.net.
+www.mozilla.org.
+hofferflow.com.
+estrenosperu.jimdo.com.
+profile.ak.fbcdn.net.
+profile.ak.fbcdn.net.
+torrent.mangastream.to.
+local-sn.contacts.msn.com.
+a.root-servers.net.
+ns56.1und1.de.
+dns.msftncsi.com.
+creative.ak.fbcdn.net.
+66.172.22.190.in-addr.arpa.
+bin-short.whatsapp.net.
+www.ethorprotect.com.
+a8.sphotos.ak.fbcdn.net.
+www.chicasasiaticas.com.ar.
+distilleryimage9.s3.amazonaws.com.
+crl.microsoft.com.
+yunno.com.
+googleads.g.doubleclick.net.
+apple-mobile.query.yahooapis.com.
+www.google.com.
+en.wikipedia.org.
+ml-rl.fsbusiness.co.uk.
+www.ccee.ch.
+photos-a.ak.fbcdn.net.
+accounts.google.com.
+235.26.31.189.in-addr.arpa.
+l8qczsku7.87ct.
+www.lapopottedemanue.com.
+a.root-servers.net.
+50.195.249.190.in-addr.arpa.
+static.depers.nl.
+dr._dns-sd._udp.na.pg.com.
+itworks.com.
+www.google-analytics.com.
+d3lvr7yuk4uaui.cloudfront.net.
+agentphone.co.uk.
+31-courier.push.apple.com.
+britishmidland.co.uk.
+i.juegosdecartas.org.
+www.google-analytics.com.
+mail.infosys.ru.
+233.29.99.190.in-addr.arpa.
+sp.cwfservice.net.
+clock.fmt.he.net.
+hughdancy.info.
+api.webrep.avast.com.
+mami.
+youtube.com.
+www.mocacleveland.org.
+t.co.
+peloterosperuanos.blogspot.com.
+s-static.ak.facebook.com.
+profile.ak.fbcdn.net.
+a728.g.akamai.net.
+www.googleadservices.com.
+v3.cache3.c.youtube.com.
+a.root-servers.net.
+a5.sphotos.ak.fbcdn.net.
+www.roflzoo.com.
+photos-f.ak.fbcdn.net.
+s-static.ak.facebook.com.
+www.boost-your-low-testosterone.com.
+65.213.14.50.in-addr.arpa.
+39games.com.
+a.root-servers.net.
+actionteam.es.
+c247723.r23.cf1.rackcdn.com.
+introsco.ru.
+hi-in.facebook.com.
+domssl.mercadolibre.com.co.
+endirect.radio-canada.ca.
+a8.sphotos.ak.fbcdn.net.
+179.98.135.89.in-addr.arpa.
+www.meristation.es.
+49.216.141.75.in-addr.arpa.
+elite-traveller.ru.
+77.92.158.189.in-addr.arpa.
+badoo.com.
+www.epyte.com.
+ads1.msads.net.
+fontmatrix.net.
+www.jrhjw.com.
+cybercomp.com.
+s.ytimg.com.
+www.tourvenezuela.com.ve.
+uk.f1324.mail.yahoo.com.
+nothingtocontribute.tumblr.com.
+www.facebook.com.
+163.201.25.190.in-addr.arpa.
+a2.sphotos.ak.fbcdn.net.
+www.sithma.com.
+a4.sphotos.ak.fbcdn.net.
+laboratorio.clandlan.net.
+platform.ak.fbcdn.net.
+a.root-servers.net.
+gfinpolish.blogspot.com.
+www.facebook.com.
+www.mandtbank.com.
+static.getclicky.com.
+205.141.157.189.in-addr.arpa.
+s-static.ak.fbcdn.net.
+safebrowsing-cache.google.com.
+photos-h.ak.fbcdn.net.
+aussiemail.com.
+altfarm.mediaplex.com.
+www.deblancointernet.com.
+google.com.
+89.247.20.95.in-addr.arpa.
+mdsaude.disqus.com.
+scribe.twitter.com.
+leon.gob.mx.
+110.79.129.189.in-addr.arpa.
+ksn2-12.kaspersky-labs.com.
+svitanok.ru.
+tagmarks.jmin.net.
+ntp1.cs.wisc.edu.
+s3.amazonaws.com.
+145.236.230.91.in-addr.arpa.
+www.ebay.es.
+i1.ytimg.com.
+11.140.198.68.in-addr.arpa.
+external.ak.fbcdn.net.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+a.root-servers.net.
+catalog-retail.amazon.com.
+download330.avast.com.
+photos-d.ak.fbcdn.net.
+www.cpxadspace.com.
+a8.sphotos.ak.fbcdn.net.
+www.google.com.
+s0.2mdn.net.
+14.8.84.200.in-addr.arpa.
+ru.mirror.alawar.com.
+151.172.62.190.in-addr.arpa.
+mx2.neonhost.com.
+65.1.168.192.in-addr.arpa.
+226.2.172.190.in-addr.arpa.
+i1.ytimg.com.
+t1.gstatic.com.
+upload.itvnn.net.
+www.google.com.
+www.iamosx.com.
+65.250.120.124.in-addr.arpa.
+www.meowhoo.com.
+climatec.com.inbound15.mxlogic.net.
+s2.youtube.com.
+240.84.67.24.zz.countries.nerd.dk.
+www.kwinanatech.com.
+www.google-analytics.com.
+66.33.224.190.in-addr.arpa.
+sky.ee.
+64.141.53.201.in-addr.arpa.
+a.root-servers.net.
+39.152.101.75.in-addr.arpa.
+pegasusrealty.us.
+sigs.symantec.com.
+y2wkcl6ve.q54m2e9w.
+literariokapasulino.blogspot.com.
+a1767.phobos.apple.com.
+content.cricinfo.com.edgesuite.net.
+join.societysm.com.
+a.root-servers.net.
+a.root-servers.net.
+inbound.haakon.com.netsolmail.net.
+ut8.xhamster.com.
+21.201.34.187.in-addr.arpa.
+static.searchya.com.
+www.total3d.ru.
+ncbaptist.org.
+169.119.136.186.in-addr.arpa.
+connect.facebook.net.
+www.apetube.com.
+knockman.com.
+gta-nuevoleon.blogspot.com.
+i.i.com.com.
+any-global.mg.mail.am0.yahoodns.net.
+www.dpinterracial.com.
+pixel.33across.com.
+www.torrentzap.com.
+99.46.48.190.in-addr.arpa.
+a.root-servers.net.
+ajax.googleapis.com.
+teredo.ipv6.microsoft.com.
+hay.
+profiles.google.com.
+google.com.
+alerts.conduit-services.com.
+googleads.g.doubleclick.net.
+jcmountainview.com.
+pt-br.facebook.com.
+www.google.com.
+db._dns-sd._udp.0.0.168.192.in-addr.arpa.
+www.theydrawandtravel.com.
+19.228.171.69.in-addr.arpa.
+www.facebook.com.
+a.root-servers.net.
+a6.sphotos.ak.fbcdn.net.
+ocsp.verisign.net.
+www.facebook.com.
+132.15.152.187.in-addr.arpa.
+_080_08_2.
+login.live.com.
+photos-d.ak.fbcdn.net.
+ads.adxpose.com.
+s2.youtube.com.
+cdn.api.twitter.com.
+mail.abbottinsuranceagency.com.
+bateriaswillard.com.
+static.ak.fbcdn.net.
+clarence.com.
+26.6.106.201.in-addr.arpa.
+a6.sphotos.ak.fbcdn.net.
+www.msn.com.
+americansuburbx.com.
+freemail.com.ru.
+136.27.138.201.in-addr.arpa.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+36.4.31.186.in-addr.arpa.
+a.root-servers.net.
+www.google.es.
+89.183.220.201.in-addr.arpa.
+49-courier.push.apple.com.
+84viwst58.32ta.
+ipad.91.com.
+paisleystclaire.typepad.com.
+books.google.com.mx.
+_854_29_8.
+a.root-servers.net.
+www.granch.ru.
+185.162.48.190.in-addr.arpa.
+9.229.194.186.in-addr.arpa.
+www.defiendetufamilia.com.
+static.ak.fbcdn.net.
+203.56.11.190.in-addr.arpa.
+www.star-wars3d.com.
+wo.wikipedia.org.
+43.96.189.24.in-addr.arpa.
+profile.ak.fbcdn.net.
+shop.broccoli.co.jp.
+pagead2.googlesyndication.com.
+aca.gov.au.
+eo.wikipedia.org.
+photos-g.ak.fbcdn.net.
+www.myhappyplanet.com.
+gmail.com.
+observatorio.atriumlinguarum.org.
+www.google-analytics.com.
+54.53.93.186.in-addr.arpa.
+external.ak.fbcdn.net.
+48.177.223.77.in-addr.arpa.
+70.12.14.125.in-addr.arpa.
+eriadi.elkhabar.com.
+db._dns-sd._udp.0.1.168.192.in-addr.arpa.
+iemcontractors.com.
+earth.google.co.uk.
+35.76.165.190.in-addr.arpa.
+s-static.ak.facebook.com.
+239.19.132.187.in-addr.arpa.
+gdata.youtube.com.
+www.lafd.org.
+4q7irqere.47qh.
+webng.com.
+79.22.245.190.in-addr.arpa.
+kekop.com.
+us.mc1215.mail.yahoo.com.
+y3.ifengimg.com.
+14.204.kam-telecom.ru.lan.
+84.113.159.187.in-addr.arpa.
+s-static.ak.fbcdn.net.
+214.16.125.74.in-addr.arpa.
+www.biodanza-adrian.com.ar.
+goglingb.org.
+eu.ecs.com.tw.
+hi-in.facebook.com.
+www.physiciansofficeresource.com.
+www.facebook.com.
+179.211.124.201.in-addr.arpa.
+a2.twimg.com.
+www.peliculastnt.com.
+download.microsoft.com.
+gaming.hardwareheaven.com.
+softwarena.com.
+ksn2-12.kaspersky-labs.com.
+www.kathyskakes.com.
+161.216.14.186.in-addr.arpa.
+embaqmail.com.
+65.88.54.75.in-addr.arpa.
+www.xtremethumbs.com.
+a.root-servers.net.
+blackmilkclothing.myshopify.com.
+www.mataderos.info.
+www.juegajuegosflash.com.
+71.94.172.189.in-addr.arpa.
+162.230.23.71.in-addr.arpa.
+ad-apac.doubleclick.net.
+www.time.com.
+105.186.191.186.in-addr.arpa.
+www.facebook.com.
+isearch.avg.com.
+helpcenter.spp.com.
+stanpark.com.
+.
+www.celebrityclubber.com.
+kadgeo.ru.
+nottango.bandcamp.com.
+code.jquery.com.
+cdn1.hitnettracer.com.
+6.28.39.190.in-addr.arpa.
+a3.sphotos.ak.fbcdn.net.
+www.facebook.com.
+mebeingcrafty.com.
+mail.danvadenchevrolet.com.
+sites.google.com.
+_023_46_3.
+www.facebook.com.
+a.root-servers.net.
+startechev.com.
+a.root-servers.net.
+es.msn.com.
+b._dns-sd._udp.belkin.
+es.answers.yahoo.com.
+translate.google.com.
+planetadepeliculaskriec.blogspot.com.
+a7.sphotos.ak.fbcdn.net.
+34.120.24.217.in-addr.arpa.
+www1.blogblog.com.
+zynga2-a.akamaihd.net.
+sp.cwfservice.net.
+97.245.77.188.in-addr.arpa.
+profile.ak.fbcdn.net.
+api.twitter.com.
+java-source.net.
+cutekittens.com.
+photos-f.ak.fbcdn.net.
+meredithtv.us.intellitxt.com.
+235.102.114.1.in-addr.arpa.
+228.29.76.189.in-addr.arpa.
+efacico.wordpress.com.
+www.facebook.com.
+google.com.
+thelariat.com.
+a.root-servers.net.
+238.30.142.79.in-addr.arpa.
+adops.alloy.com.
+docs.google.com.
+www.castillodearena.edu.mx.
+b-t.com.ua.
+apps.facebook.com.
+125.195.198.190.in-addr.arpa.
+a2.sphotos.ak.fbcdn.net.
+mx1.flirble.org.
+csi.gstatic.com.
+www.bywifi.com.
+186.46.30.83.in-addr.arpa.
+224.30.168.192.in-addr.arpa.
+s-static.ak.facebook.com.
+27.8.224.189.in-addr.arpa.
+static.ak.fbcdn.net.
+certificates.godaddy.com.
+137.196.141.201.in-addr.arpa.
+mail.goole.net.
+226.46.55.189.in-addr.arpa.
+enviayreporta.esmas.com.
+indieclick.3janecdn.com.
+photos-h.ak.fbcdn.net.
+79.75.220.87.in-addr.arpa.
+www.facebook.com.
+www.supercuts.com.au.
+myapself.blogspot.com.
+www.search-results.com.
+mailman2.youngsmarket-ut.com.
+www.google-analytics.com.
+inbound.dominiontruss.com.netsolmail.net.
+static.exoclick.com.
+ksn2-12.kaspersky-labs.com.
+mx01.comp-pro-dns.de.
+www.evostc.state.ak.us.
+photos-d.ak.fbcdn.net.
+www.joris-vervuurt.com.
+www.lsgmodelsnude.com.
+udc.msn.com.
+l.betrad.com.
+gamezer.com.
+www.mbtshoesdepot.com.
+a1.sphotos.ak.fbcdn.net.
+media.scenedaily.com.
+apps.facebook.com.
+quebecblogue.com.
+146.79.236.201.in-addr.arpa.
+i4.ytimg.com.
+www.google.com.
+safebrowsing-cache.google.com.
+leaderbusiness.com.
+l7dxx99jn.76zr.
+attachment.fbsbx.com.
+www.hk.com.
+charlesburt.com.
+4.177.244.207.in-addr.arpa.
+beatwolf.com.
+support.google.com.
+connect.facebook.net.
+sports.yahoo.com.
+y3agg2b81.36ej.
+www.gravatar.com.
+120.145.85.77.in-addr.arpa.
+.
+ssl.gstatic.com.
+1.234.10.83.in-addr.arpa.
+89.54.200.178.in-addr.arpa.
+nexisint.com.
+twitter.com.
+db._dns-sd._udp.0.1.168.192.in-addr.arpa.
+a.root-servers.net.
+st.p.360.cn.
+pt-br.facebook.com.
+a.root-servers.net.
+secure.wlxrs.com.
+2.m0n0wall.pool.ntp.org.
+www.precisiondrilling.com.
+apix.iminent.com.
+jhc.co.uk.
+stardock-logonstudio.softonic.com.
+jones-thomas-md.com.
+www.d365.org.
+profile.ak.fbcdn.net.
+www.peoplefinders.org.
+239.22.127.201.in-addr.arpa.
+244.239.229.88.in-addr.arpa.
+naruto.wikia.com.
+62.138.6.189.in-addr.arpa.
+www.godofwar.com.
+171.30.220.189.in-addr.arpa.
+mail1.westernrefining.com.
+www.maj.ie.edu.
+www.tequilabeachtours.com.
+208.126.233.201.in-addr.arpa.
+static.ak.facebook.com.
+mx.parktelusa.com.
+ocsp.thawte.com.
+a785.phobos.apple.com.
+mountaincreek.com.s5a1.psmtp.com.
+m.facebook.com.
+ms.adscope.co.kr.
+flow-entertainment.com.
+vivaldi-travel.ru.
+de.cliplike.net.
+hello.connectivity.me.com.
+widget.plugrush.com.
+200.151.252.201.in-addr.arpa.
+dns.msftncsi.com.
+www.3dtv.com.
+unifi.
+appsmetadata.toolbar.conduit-services.com.
+253.104.170.189.in-addr.arpa.
+catolicosfirmes.phpbbforo.com.
+maggiered.blogspot.com.
+www.chicaswebcam803.com.
+support.google.com.
+www.google-analytics.com.
+callwriter.com.
+dns.msftncsi.com.
+csi.gstatic.com.
+ns.dipmap.com.
+sup.arnuvo.ru.
+apps.facebook.com.
+fs_bt.qq.com.
+utm.trk.mywebsearch.com.
+ad.leadboltapps.net.
+feeds.bbci.co.uk.
+google.com.
+a3.sphotos.ak.fbcdn.net.
+splav.net.ru.
+pixel.facebook.com.
+careercenter.com.
+processanalyzers.net.
+v17.nonxt7.c.youtube.com.
+www.cssforum.com.pk.
+twitpic.com.
+stonehardware.com.
+shortstop-left-field.blogspot.com.
+www.djkrac.blogspot.com.
+www.oneclickshooting.com.
+frontend.weeds.mytopia.com.
+www.strefa.pl.
+197.51.93.186.in-addr.arpa.
+teredo.ipv6.microsoft.com.
+servicenet.com.
+26.135.213.201.in-addr.arpa.
+12.122.113.195.in-addr.arpa.
+225.14.85.99.in-addr.arpa.
+profile.ak.fbcdn.net.
+external.ak.fbcdn.net.
+ellsworth.net.
+131.87.5.88.in-addr.arpa.
+www.hotelrua.com.
+17.15.208.95.in-addr.arpa.
+alfrasha.maktoob.com.
+img226.imagevenue.com.
+galleries.messygangbangs.com.
+www.facebook.com.
+argentinarrhh.blogspot.com.
+_527_09_1.
+google.com.
+a.root-servers.net.
+www.bing.com.
+aquanet.com.
+www.facebook.com.
+ic.tynt.com.
+rs38dt.rapidshare.com.
+es.answers.yahoo.com.
+a.root-servers.net.
+r.mzstatic.com.
+a.root-servers.net.
+a.root-servers.net.
+chokefrantic.hubpages.com.
+static.ak.fbcdn.net.
+ledergroup-com.mail.eo.outlook.com.
+push2check.com.
+embarazadafeliz.com.
+www.jethrotull.com.
+r1.gslb.ace.advertising.com.adcom.akadns.net.
+www.ideasdenegocio.com.co.
+platform0.twitter.com.
+a8.sphotos.ak.fbcdn.net.
+_378_56_8.
+pixel.facebook.com.
+www.nuevebits.com.
+a1174.g.akamai.net.
+250.146.42.201.in-addr.arpa.
+www.super8news.com.
+www.elcrimennopaga.com.
+a5.sphotos.ak.fbcdn.net.
+account.live.com.
+photos-h.ak.fbcdn.net.
+a6.sphotos.ak.fbcdn.net.
+news.google.com.
+www.jacksmannequin.com.
+mx2.oregonmetro.gov.
+cmdos.files.wordpress.com.
+a.root-servers.net.
+a2.sphotos.ak.fbcdn.net.
+l.yimg.com.
+agent.kuaiwan.com.
+photos-e.ak.fbcdn.net.
+www.youtube.com.
+photos-e.ak.fbcdn.net.
+wzus1.search-results.com.
+a.root-servers.net.
+www.hotelreservaciones.com.mx.
+newsrss.bbc.co.uk.
+www.stephisparadise.com.
+138.76.200.186.in-addr.arpa.
+8207.4.img98.net.
+mf.orkut.vostu.com.
+external.ak.fbcdn.net.
+8mln:f:84.k41w9z9y.
+www.facebook.com.
+optimized-by.rubiconproject.com.
+mobile.search.aol.com.
+www.crlsresearchguide.org.
+ds.serving-sys.com.
+149.168.9.61.in-addr.arpa.
+a.root-servers.net.
+www.volleyball-tours.com.
+lenix.com.br.
+68.84.224.125.in-addr.arpa.
+217.152.48.190.in-addr.arpa.
+prod-nr285.voxer.com.
+d2055523.instant.xoom.it.
+images.effexmedia.com.
+host.name.ru.
+permlight.com.
+a.root-servers.net.
+profile.ak.fbcdn.net.
+www.1wanwan.com.
+static.ak.fbcdn.net.
+141.39.160.190.in-addr.arpa.
+www.baidu.com.
+gone-star.tumblr.com.
+www.sonesta.com.
+a.root-servers.net.
+208.72.131.82.in-addr.arpa.
+59.187.195.71.in-addr.arpa.
+ee:evptz7.l32p6r6o.
+satfile300.corp.kbr.com.beknet.us.
+a.root-servers.net.
+31.201.163.190.in-addr.arpa.
+a5.sphotos.ak.fbcdn.net.
+ad.adnetwork.net.
+img.android.maxpedia.org.
+cityvillefb1.static.zgncdn.com.
+www.allposters.com.tr.
+isiprint.net.
+hiphopgalaxy.com.
+www.ticketmaster.com.
+aneses.com.
+14.34.92.93.in-addr.arpa.
+cmapspublic2.ihmc.us.
+www.jocjuegos.com.
+login.skype.com.
+www.ocesa.com.mx.
+campusdigital.uag.mx.
+www.gstatic.com.
+google.com.
+celularessonyericsson.para-celulares.com.
+www.liverpool-live.info.
+vewrizon.net.
+photos-e.ak.fbcdn.net.
+googleads.g.doubleclick.net.
+cirkor.se.
+reng.ru.
+www.apic.org.
+dr._dns-sd._udp.0.0.168.192.in-addr.arpa.
+skhamp.files.wordpress.com.
+a1724.phobos.apple.com.edgesuite.net.
+fls.doubleclick.net.
+i2.ytimg.com.
+205.47.194.187.in-addr.arpa.
+mail2brussels.com.
+altaiagro.com.
+72.33.134.188.in-addr.arpa.
+b._dns-sd._udp.lan.
+s2.youtube.com.
+phxdata.com.
+shop65367577.taobao.com.
+apis.google.com.
+cdn.montiera.com.
+nvkz.net.
+static.ak.fbcdn.net.
+blufiles.storage.msn.com.
+www.harleyandharlett.blogspot.com.
+wii.mmgn.com.
+tobolsk.info.
+31.60.49.190.in-addr.arpa.
+ad.doubleclick.net.
+dtboot.orbitdownloader.com.
+cine.es.msn.com.
+www.strbk.fr.
+api.facebook.com.
+9gag.com.
+eldelyayo.blogspot.com.
+mlb.mlb.com.
+it-it.facebook.com.
+109.218.117.75.in-addr.arpa.
+au.download.windowsupdate.com.
+mta4.am0.yahoodns.net.
+a.root-servers.net.
+profile.ak.fbcdn.net.
+148.88.145.201.in-addr.arpa.
+filter2.mittkontor.no.
+tracker.mightynova.com.
+ezay55cz5.65wy.
+www.google.com.
+gte.n.
+thumbs1.ebaystatic.com.
+purenetworks.com.
+.
+www.animal-games.biz.
+mail.v1mortgage.com.
+53.110.102.201.in-addr.arpa.
+b.scorecardresearch.com.
+ar-ar.facebook.com.
+static.ak.fbcdn.net.
+taipei.org.nz.
+infectomica.cinvestav.mx.
+bbfdyz3yz.57sl.
+m.facebook.com.
+www.google.com.
+taz.de.
+baymsg1010833.by2.gateway.edge.messenger.live.com.
+www.tarif-mobile.ru.
+newsrss.bbc.co.uk.
+a.root-servers.net.
+us.yimg.com.
+communityvoices.sites.post-gazette.com.
+ut2.xhamster.com.
+romana.babylon.com.
+humorvice.blogspot.com.
+a7.sphotos.ak.fbcdn.net.
+mx183.emialfiltering.com.
+www.socialmediasl.com.
+a.root-servers.net.
+c10038.ic-live.com.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+sro.whatsapp.net.
+itunes.apple.com.
+external.ak.fbcdn.net.
+www.batanga.com.
+teredo.ipv6.microsoft.com.
+wheels.blogs.nytimes.com.
+23.242.163.189.in-addr.arpa.
+91.175.140.194.in-addr.arpa.
+www.plabell.com.
+a2.sphotos.ak.fbcdn.net.
+distilleryimage5.instagram.com.
+212.171.131.189.in-addr.arpa.
+ocsp.godaddy.com.
+yahoo.com.
+alger.ebuddy.com.
+35.207.23.92.in-addr.arpa.
+ae.adserver.yahoo.com.
+m.addthisedge.com.
+1.70.16.172.in-addr.arpa.
+crl.microsoft.com.
+hk.search.auctions.yahoo.com.
+tobolsk.info.
+9q5lzw5c2.n96f0r1q.
+46.117.103.201.in-addr.arpa.
+tools.google.com.
+update.messenger.yahoo.com.
+110.21.39.81.in-addr.arpa.
+241.116.172.187.in-addr.arpa.
+game.softick.com.
+www.siempreeducando.com.
+ad-g.doubleclick.net.
+us1.harunyahya.com.
+tko7ia.bay.livefilestore.com.
+82.107.39.190.in-addr.arpa.
+a.root-servers.net.
+mail.kcengineering.com.
+107.178.179.190.in-addr.arpa.
+mail.lobosservices.com.
+royalflush.ru.
+market.android.com.
+data.shopsavvy.mobi.
+www.gmflotillas.com.mx.
+235.189.26.201.in-addr.arpa.
+_818_12_0.
+adsfront.iminent.com.
+239.166.236.189.in-addr.arpa.
+apeco.org.pe.
+www.google.com.
+chicostara.com.
+urbanterror.mtc-team.fr.
+storage.conduit.com.
+cs1752.vkontakte.ru.
+photos-d.ak.fbcdn.net.
+\(none\).
+lavozdecristian.cl.woopra-ns.com.
+102.148.144.189.in-addr.arpa.
+www.google.com.
+partner.googleadservices.com.
+reawards.ru.
+smtp-in2.sfbcic.com.
+thedanisgroup.com.
+estate-insurance-credit-conference.ru.
+a997.mm1.akamai.net.
+ads.yimg.com.
+100.110.175.190.in-addr.arpa.
+hootsuite.com.
+16.79.31.189.in-addr.arpa.
+creative.ak.fbcdn.net.
+207.42.42.186.in-addr.arpa.
+ar-ar.facebook.com.
+7.169.122.195.in-addr.arpa.
+aidps.atdmt.com.
+www.crushingonclothes.com.
+www.facebook.com.
+www.quiebro.com.
+www.facebook.com.
+ksn2-12.kaspersky-labs.com.
+profile.ak.fbcdn.net.
+ad-g.doubleclick.net.
+_653_20_8.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+photos-g.ak.fbcdn.net.
+download115.avast.com.
+ws-cloud-msgplus.linkury.com.
+30.117.5.189.in-addr.arpa.
+242.240.10.187.in-addr.arpa.
+wistron.com.
+biasabaeiki.blogspot.com.
+www.facebook.com.
+ie9cvlist.ie.microsoft.com.
+teredo.ipv6.microsoft.com.
+desmorrugador.bravehost.com.
+www.gocanvas.com.
+tallerdelibros.com.
+www.bostonherald.com.
+www.bilatinmen.com.
+photos-a.ak.fbcdn.net.
+diabetes.todominio.com.
+www.facebook.com.
+widgets.amung.us.
+195.252.127.187.in-addr.arpa.
+pagead.l.doubleclick.net.
+gfx4.hotmail.com.
+photos-g.ak.fbcdn.net.
+www.gpbatteries.com.
+mx.youtube.com.
+acordiare.com.
+unitmagazine.com.
+gymnasticbodies.com.
+ad.doubleclick.net.
+a1.sphotos.ak.fbcdn.net.
+223.128.121.94.in-addr.arpa.
+global.nytimes.com.
+accounts.google.com.
+www.69bits.com.
+fremont.downtown.net.
+nina.pagesz.net.
+www.woitalia.it.
+bravox.net.
+172.199.163.142.in-addr.arpa.
+navy.mil.
+182.69.46.189.in-addr.arpa.
+a.root-servers.net.
+photos-d.ak.fbcdn.net.
+safebrowsing-cache.google.com.
+yaoi-haven.com.
+app54.logmein.com.
+geo.tp-cdn.com.
+s.mfcdn.net.
+p06-contacts.icloud.com.
+67.174.63.83.in-addr.arpa.
+www.ukwhitegoods.co.uk.
+cm.ac3.msn.com.
+dns.msftncsi.com.
+pixel.facebook.com.
+media.esmas.com.
+a1.sphotos.ak.fbcdn.net.
+242.30.62.186.in-addr.arpa.
+photos-a.ak.fbcdn.net.
+admeld.adnxs.com.
+mx.youtube.com.
+118.199.216.89.in-addr.arpa.
+73.111.31.190.in-addr.arpa.
+zh-cn.facebook.com.
+google.com.
+186.14.229.201.in-addr.arpa.
+siteholder.ru.
+www.addthis.com.
+caldwellw.freeserve.co.uk.
+graph.facebook.com.
+photos-h.ak.fbcdn.net.
+a.root-servers.net.
+109.75.105.75.in-addr.arpa.
+maldi.tv.
+apuntesparaestudiar.com.
+uralhosting.ru.
+www.belkin.com.
+156.46.83.78.in-addr.arpa.
+cborange.com.
+platform.twitter.com.
+www.google-analytics.com.
+fbcdn-profile-a.akamaihd.net.
+dfdffdf.com.
+www.battlefieldadventures.com.
+conn.skype.com.
+a.root-servers.net.
+tc.v23.cache5.c.youtube.com.
+scotia70657275.h1x.com.
+235.189.91.186.in-addr.arpa.
+115.53.48.190.in-addr.arpa.
+i4.ytimg.com.
+127.189.22.190.in-addr.arpa.
+a.root-servers.net.
+clients1.google.com.
+133.0.0.10.in-addr.arpa.
+54.55.82.200.in-addr.arpa.
+hypermetix.net.
+58.56.35.187.in-addr.arpa.
+www.milenio.com.
+www.gstatic.com.
+pushpoppress.com.
+2.174.254.201.in-addr.arpa.
+www.elsegundero.com.
+whiteandassociates.net.bak-mx.na0102.smtpbak.comcom.
+teredo.ipv6.microsoft.com.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+101.45.138.24.in-addr.arpa.
+www.msftncsi.com.
+a.ads2.msads.net.
+totallycellular.net.bak-mx.smtproutes.com.
+a1.sphotos.ak.fbcdn.net.
+68ohh6com6c1h-c.c.yom.mail.yahoo.com.
+9.233.174.190.in-addr.arpa.
+photos-g.ak.fbcdn.net.
+freephotocalendar.net.
+a.root-servers.net.
+gmail.com.
+eivyaaox.info.
+cs221.stanford.edu.
+mailx.hoster.ru.
+a.root-servers.net.
+biowiki.ucdavis.edu.
+f741.mail.yahoo.com.
+iowa-city.org.inbound45.mxlogicmx.net.
+www.synonyms-antonyms.com.
+sumvm1.vnet.ibm.com.
+19.219.109.101.in-addr.arpa.
+152.23.50.190.in-addr.arpa.
+a.root-servers.net.
+202.11.19.189.in-addr.arpa.
+dns.msftncsi.com.
+beta.stun.voice.yahoo.com.
+www.facebook.com.
+246.200.57.186.in-addr.arpa.
+www.swallowsquirt.com.
+photos-e.ak.fbcdn.net.
+ksn1-11-part1.kaspersky-labs.com.
+static.ak.fbcdn.net.
+evssl-aia.geotrust.com.
+219.148.56.186.in-addr.arpa.
+signin.ebay.com.
+wpad.
+85.61.174.190.in-addr.arpa.
+wdg1.apple.com.
+97.73.105.187.in-addr.arpa.
+p1901.infolinks.com.
+t9ahqgs4m.06zw.
+infoworld.com.s6b1.psmtp.com.
+mail.onlinep2000.com.
+u1.ac.hk2.yahoo.com.
+a.root-servers.net.
+id.google.com.
+14.149.221.190.in-addr.arpa.
+creative.clicksor.com.
+a8.sphotos.ak.fbcdn.net.
+x264dev.multimedia.cx.
+ocsp.verisign.com.
+www.youtube-nocookie.com.
+rv.coupish.com.
+cdn2.pugetsystems.com.
+pagead2.googlesyndication.com.
+242.45.117.200.in-addr.arpa.
+.
+vidasilvestre.org.ar.
+107.111.143.89.in-addr.arpa.
+www.mmorpgranks.com.
+assets4.castle.zgncdn.com.
+www.bfeditor.org.
+expert.co.th.
+wixmobile.com.
+boblynchford.com.
+www.desafiointel.com.
+a.root-servers.net.
+stock.joinsmsn.com.
+123.69.59.186.in-addr.arpa.
+kaibacorp0.50megs.com.
+dbru.br.ns.els-gms.att.net.
+s3.sidereel.com.
+club-krasotki.ru.
+www.facebook.com.
+resources.search.conduit.com.
+app.appgefahren.de.
+_957_33_5.
+131.149.18.187.in-addr.arpa.
+agothsphere.com.
+a1113.da1.akamai.net.
+lgrlwq.bay.livefilestore.com.
+s5bi:uk6r.61le.
+179.17.46.208.in-addr.arpa.
+damonbraces.com.
+static.ak.fbcdn.net.
+www.google-analytics.com.
+gilat.net.
+r1rk9np7bpcsfoeekl0khkd2juj27q3o-a-fc-opensocial.googleusercontent.com.
+www.facebook.com.
+www.google-analytics.com.
+ejabat.google.com.
+stun.client.akadns.net.
+safebrowsing.clients.google.com.
+www.valleviejo1041.com.ar.
+vcs1.msg.yahoo.com.
+www.facebook.com.
+www.cliphai.com.
+waggingthefox.blogspot.com.
+www.google.com.
+images.hornymatches.com.
+client.akamai.com.
+fbcdn-profile-a.akamaihd.net.
+creative.ak.fbcdn.net.
+anna-zont.blogspot.com.
+www.flickr.com.
+i2.ytimg.com.
+hotmail.com.
+fbcdn-profile-a.akamaihd.net.
+gpcom.srvc.metaboli.net.
+toolbarqueries.google.com.
+l.yimg.com.
+www.megaplay.ru.
+www.skipsnotes.com.
+wallet.google.com.
+mdawmdezmtaxmjaxmg.org.
+73.67.222.189.in-addr.arpa.
+143.239.200.112.in-addr.arpa.
+ad.harrenmedianetwork.com.
+connect.facebook.net.
+www.cosl.com.au.
+67.38.150.187.in-addr.arpa.
+220.95.192.187.in-addr.arpa.
+sharebit.net.
+www.poemaspoetas.com.
+vpaf.unr.edu.
+i4.ytimg.com.
+www.philippinen-life.de.
+indusladies.com.
+photos-f.ak.fbcdn.net.
+cnn.joins.com.
+a1003.w41.akamai.net.
+5y1r4y9fs.75xq.
+www.albercas.mx.
+udo.informatik.uni-dortmund.de.
+3alp17:cq.j75p7l0w.
+davidrio.com.
+www.arabize.com.eg.
+010c36352e35352e39302e3137320000.lbl8.mailshell.net.
+dns.msftncsi.com.
+www.twistedzones.com.
+169.200.138.190.in-addr.arpa.
+twitter.com.
+accounts.google.com.
+euro.mediotiempo.com.
+piensa-linux.programas-gratis.net.
+newsltd.com.au.
+email.80stees.com.
+37.105.202.81.in-addr.arpa.
+relay1.karelia.ru.
+static.addtoany.com.
+p0b.ru.
+home.live.com.
+www.map.utah.edu.
+webtrends1.taitra.org.tw.
+www.biblia12.com.
+s2.youtube.com.
+i1101.photobucket.com.
+tracker.dunnsearch.org.
+t2.gstatic.com.
+www.softonic.com.
+23.33.170.201.in-addr.arpa.
+googleads.g.doubleclick.net.
+prod2.rest-notify.msg.yahoo.com.
+voipc.sip.yahoo.com.
+ads1.msn.com.
+wzv6csg96.w17q2k2n.
+b.scorecardresearch.com.
+i1.ytimg.com.
+193.235.29.186.in-addr.arpa.
+funcampco.ca.
+www.salzburg-night.at.
+s.ytimg.com.
+clinicalconnexion.com.
+webcache.googleusercontent.com.
+cmc-loan.com.
+horoscopos.prodigy.msn.com.
+photos-f.ak.fbcdn.net.
+hotmail.com.
+s.ytimg.com.
+ratoactorework.ph.
+29.16.121.84.in-addr.arpa.
+201.171.57.186.in-addr.arpa.
+anunciosyavisos.com.pe.
+safebrowsing.clients.google.com.
+epacksolutions.com.
+sp.cwfservice.net.
+nem.com.s8a2.psmtp.com.
+217.90.223.189.in-addr.arpa.
+www.pspglobal.com.
+file4sharing.com.
+img.informer.com.
+103.54.96.200.in-addr.arpa.
+callejondeldeseo.blogspot.com.
+tee:f:op3.67nh.
+m4.licdn.com.
+215.186.127.201.in-addr.arpa.
+line-ra.ru.
+a.ittad.com.
+travelmarket.com.
+ksn1-12-part2.kaspersky-labs.com.
+relay.sobin.arh.ru.
+m.ak.fbcdn.net.
+212.1.168.192.in-addr.arpa.
+130.19.168.192.in-addr.arpa.
+127.92.137.187.in-addr.arpa.
+get.webwangwang.taobao.com.
+geo.tp-cdn.com.
+download348.avast.com.
+lt.navegg.com.
+a.root-servers.net.
+widget.ovo.com.
+www.google.com.
+83.105.188.71.in-addr.arpa.
+_582_97_7.
+ivrichpe.it.
+70.55.165.90.in-addr.arpa.
+www.stealth.nl.
+coruna-sec01.usersad.everis.int.
+zz.amur.su.
+www.twitter.com.
+rsc.co.uk.
+57.248.237.67.in-addr.arpa.
+roninpro.blogspot.com.
+apps.facebook.com.
+bs.serving-sys.com.
+www.acclimited.com.
+yakamar.com.
+rad.msn.com.
+www.telebasura.net.
+horoscopos.prodigy.msn.com.
+196.60.33.178.in-addr.arpa.
+i2.ytimg.com.
+mykadesigns.com.
+mediums.es.
+g.live.com.
+111.128.100.190.in-addr.arpa.
+eplresidential.com.
+a2.twimg.com.
+7-courier.push.apple.com.
+a.root-servers.net.
+www.cebupacificair.com.
+smtp.ru.
+www.wired.com.
+a.root-servers.net.
+a.root-servers.net.
+geometriagrafica.wordpress.com.
+relay.data.edge.messenger.live.com.
+farm6.staticflickr.com.
+ssl.gstatic.com.
+latimesblogs.latimes.com.
+casa.astoriail.net.
+get.adobe.com.
+akam.bing.com.
+archerac.com.s10a1.psmtp.com.
+186.129.171.201.in-addr.arpa.
+www.magdalenajalisco.gob.mx.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+client.akamai.com.
+168.227.161.189.in-addr.arpa.
+sfa.d300.kane.k12.il.us.
+jjfnj1poh.37jg.
+www.gilberdesigns.com.
+76.247.198.190.in-addr.arpa.
+226.20.199.190.in-addr.arpa.
+www.umontreal.ca.
+photos-g.ak.fbcdn.net.
+topvino.ru.
+zh-cn.facebook.com.
+adserver.adtech.de.
+londonamericantx.com.inbound15.mxlogicmx.net.
+mail.proinversion.gob.pe.
+93.45.9.201.in-addr.arpa.
+smtp.hallco.org.
+rcp.na.blackberry.com.
+download115.avast.com.
+alarabiya.lsops.net.
+a.root-servers.net.
+a2.sphotos.ak.fbcdn.net.
+safebrowsing-cache.google.com.
+api.mixpanel.com.
+153.230.79.184.in-addr.arpa.
+mailin-02.mx.aol.com.
+img4.imageshack.us.
+icons.wxug.com.
+teredo.ipv6.microsoft.com.
+teredo.ipv6.microsoft.com.
+www.stop-ciberbullying.info.
+98.240.89.200.in-addr.arpa.
+suxxessology.com.
+www.google.com.
+www.esprit.co.uk.
+whythetech.com.
+i4.ytimg.com.
+pop3.hot.glbdns.microsoft.com.
+shortstackapp.com.
+www.facebook.com.
+conn.skype.com.
+232.10.0.192.in-addr.arpa.
+203.233.172.201.in-addr.arpa.
+85.58.230.189.in-addr.arpa.
+ist1-2.filesor.com.
+eupen.us.
+dangg-amy.polyvore.com.
+236.60.103.201.in-addr.arpa.
+173.138.73.189.in-addr.arpa.
+www.juegosonline.com.py.
+mm3.no-ip.info.
+a1637.phobos.apple.com.
+accountservices.msn.com.
+www.universalairsuspension.com.
+lfgms.logica.com.
+a-0.19-a30fd081.c0b0580.1518.19d4.3ea1.410.0.mkhwv99ghppe6l4bjkfvsjc8pt.avqs.mcafee.com.
+groups.google.com.mx.
+twitter.com.
+168.170.48.190.in-addr.arpa.
+33.116.40.114.in-addr.arpa.
+74.222.160.118.in-addr.arpa.
+102.78.81.189.in-addr.arpa.
+gq7zzoav1.s42h4y6b.
+cityvillefb2.static.zgncdn.com.
+206.34.237.186.in-addr.arpa.
+20.228.125.64.in-addr.arpa.
+mail.tapco.ae.
+206.27.35.187.in-addr.arpa.
+230.89.19.186.in-addr.arpa.
+19.191.189.89.in-addr.arpa.
+cines.com.py.
+a5.sphotos.ak.fbcdn.net.
+www.acuale.com.
+61.36.153.187.in-addr.arpa.
+static.ak.fbcdn.net.
+dl21.ccb2.ru.
+external.ak.fbcdn.net.
+time.windows.com.
+i1101.photobucket.com.
+uac.advertising.com.
+13.136.83.186.in-addr.arpa.
+_577_55_7.
+ls.nexon.net.
+61.73.6.186.in-addr.arpa.
+fxfeeds.mozilla.com.
+a.root-servers.net.
+techreport.com.
+a.root-servers.net.
+www.maxmedals.com.
+addisonpools.com.
+ts4.travian.pk.
+kiva.net.
+buryclean.co.uk.
+coopatlantic.ca.
+creative.ak.fbcdn.net.
+t0.gstatic.com.
+mail.desertcard.com.
+128.168.253.201.in-addr.arpa.
+posterspoint.com.
+bsitecnologia.com.br.
+148.182.158.69.in-addr.arpa.
+mediacorppublishing.com.
+gogethealthynow.com.
+11.36.81.88.in-addr.arpa.
+wac.5f48.edgecastcdn.net.
+a.root-servers.net.
+a.root-servers.net.
+wljtzplr.net.
+eldy.softonic.com.
+www.biografias.pe.
+www.myspace.com.
+psprs.com.1.0001.arsmtp.com.
+mail.inlandcardiology.com.
+safebrowsing-cache.google.com.
+pbsc.co.uk.
+mail2.lanusa.com.
+img469.imageshack.us.
+clock.fmt.he.net.
+85.130.184.81.in-addr.arpa.
+login.toolbar.conduit-services.com.
+dv-region.ru.
+www.facebook.com.
+mgcr.wordpress.com.
+225.144.171.201.in-addr.arpa.
+static.ak.fbcdn.net.
+egyptiancastle.com.
+wwwimages.adobe.com.
+phone.com.
+71.12.179.189.in-addr.arpa.
+a.tribalfusion.com.
+dalk.ru.
+u.ywu.
+menupages.com.s8b1.psmtp.com.
+artisticas-normaldetorreon.blogspot.com.
+secure.wlxrs.com.
+lpcdn04.nflximg.com.
+wollive.windowsmedia.com.akadns.net.
+photos-d.ak.fbcdn.net.
+i.imwx.com.
+ngfts.lge.com.
+www.facebook.com.
+teamlatus.com.
+mail.orchardchurch.com.
+laptopstands.tv.
+static.ak.fbcdn.net.
+a.root-servers.net.
+24.173.122.84.in-addr.arpa.
+a7.sphotos.ak.fbcdn.net.
+mariamora.blogdiario.com.
+www.osstem.com.
+dl.gameplaylabs.com.s3.amazonaws.com.
+clientui.babylon.com.
+r._dns-sd._udp.0.2.168.192.in-addr.arpa.
+www.facebook.com.
+mail.ncs-law.com.
+imap.gmail.com.
+50.149.220.66.in-addr.arpa.
+google.com.
+ea:4uaxx8.44jg.
+mail.capcomp.com.
+www.groveatlantic.com.
+ministerioluzalasnaciones.com.
+www.louisvuittonpurses-bags.net.
+safebrowsing-cache.google.com.
+foros.3dgames.com.ar.
+49.93.47.189.in-addr.arpa.
+a2.sphotos.ak.fbcdn.net.
+word-search-maker.com.
+google.com.
+studiohilldesign.com.
+133.2.23.95.in-addr.arpa.
+photos-g.ak.fbcdn.net.
+js2.wlxrs.com.
+104.159.100.190.in-addr.arpa.
+www.mooncandy.org.
+60.240.105.186.in-addr.arpa.
+37.30.170.189.in-addr.arpa.
+248.23.171.187.in-addr.arpa.
+support.google.com.
+247.35.237.186.in-addr.arpa.
+host-delay.logmein-gateway.com.
+i.ytimg.com.
+static0.kizi.com.
+specmetall.ru.
+static.gallendor.com.
+neron.ac-creteil.fr.
+apps.facebook.com.
+photos-c.ak.fbcdn.net.
+137.197.152.193.in-addr.arpa.
+www.freecaliforniawallpaper.com.
+143.21.163.190.in-addr.arpa.
+hotmail.com.
+a6.sphotos.ak.fbcdn.net.
+www.wikimediafoundation.org.
+www.rtl2.fr.
+a.root-servers.net.
+www.trackon.org.
+localad.walmart.com.
+searchclient.live.net.
+echo.edge.messenger.live.com.
+2.m0n0wall.pool.ntp.org.
+stardaily.ru.
+152.130.29.186.in-addr.arpa.
+5.239.196.90.in-addr.arpa.
+www.facebook.com.
+it-it.facebook.com.
+time.chttl.com.tw.
+alyeparusa.msk.ru.
+smtp.126.com.
+sgag.org.
+shasta-rrs.symantec.com.
+mail.turascandinavia.com.
+rt.rtoaster.jp.
+www.gagaplay.com.
+www.google.com.
+storage.conduit.com.
+25.201.52.186.in-addr.arpa.
+a4.sphotos.ak.fbcdn.net.
+support.google.com.
+ready-access.com.inbound25.mxlogic.net.
+richardhellergallery.com.
+photos-g.ak.fbcdn.net.
+ds.addthis.com.
+www.barraclou.com.
+bbcore.cloudapp.net.
+www.destroyplanethuman.com.
+youtu.be.
+static.ak.fbcdn.net.
+platform.twitter.com.
+www.apple.com.
+www.alltagz.de.
+56.42.171.201.in-addr.arpa.
+www.google.com.
+vpx8ezg4f.t20y4t4x.
+heyo.cc.
+www.esabmalaysia.com.
+umail.iu.edu.
+mycitybynight.co.za.
+rslonline.net.
+safebrowsing-cache.google.com.
+ksn2-12.kaspersky-labs.com.
+crissisideenschmiede.blogspot.com.
+mrc2.k12.mo.us.
+o.nimbuzz.com.
+elitebproductions.com.
+1.gvt0.com.
+webcache.googleusercontent.com.
+.
+www.facebook.com.
+www.shareasale.com.
+photos-a.ak.fbcdn.net.
+a3.sphotos.ak.fbcdn.net.
+www.jaimieveale.com.
+unhcr.ch.
+t.co.
+p05-contacts.icloud.com.akadns.net.
+msg2.caddock.com.
+mail.sikon.com.
+146.69.81.186.in-addr.arpa.
+amorconagujaylana.blogspot.com.
+h-oneindia.com.
+mjzjnlshsqzbqbg.biz.
+jiu66.cn.
+dc384.4shared.com.
+e.taxactonline.com.
+googleads.g.doubleclick.net.
+ad.yieldmanager.com.
+87.172.0.88.in-addr.arpa.
+accounts.google.com.
+mail.postjung.com.
+www.ivorde.ro.
+telvent.com.
+hotmail.com.
+s1-word-view.vo.msecnd.net.
+comluv.s3.amazonaws.com.
+www.ideastelcel.com.
+dns.msftncsi.com.
+appenda.com.
+adammesh.com.
+51.203.228.190.in-addr.arpa.
+data.mobclix.com.
+www.weather.com.
+clientes.hiltoncolon.com.
+a.root-servers.net.
+102.19.174.190.in-addr.arpa.
+148.196.212.186.in-addr.arpa.
+widgets.amung.us.
+32.60.61.85.in-addr.arpa.
+59.222.29.89.in-addr.arpa.
+photos-e.ak.fbcdn.net.
+zao.spb.ru.
+228.80.72.190.in-addr.arpa.
+57.231.195.190.in-addr.arpa.
+241.42.166.77.in-addr.arpa.
+cy.sosiphone.com.
+pixer.meaningtool.com.
+crescentmoongames.com.
+googleblog.blogspot.com.
+pinoysila.blogspot.com.
+184.15.228.189.in-addr.arpa.
+www.babe-party.com.
+www.lawebdelprogramador.com.
+i.ytimg.com.
+internalcheck.apple.com.
+159.187.28.181.in-addr.arpa.
+dns.msftncsi.com.
+dns.msftncsi.com.
+201.94.60.177.in-addr.arpa.
+154.11.176.190.in-addr.arpa.
+api.facebook.com.
+galadrielcrea.blogspot.com.
+www.urbanartcore.eu.
+photos-c.ak.fbcdn.net.
+pixel.facebook.com.
+id25915.al16.luxup.ru.
+126.27.54.177.in-addr.arpa.
+www.analisisdemedios.com.
+d2100674.xoom.it.
+googleads.g.doubleclick.net.
+a.root-servers.net.
+teredo.ipv6.microsoft.com.
+a8.sphotos.ak.fbcdn.net.
+e3191.c.akamaiedge.net.
+westplastgroup.ru.lan.
+checkip.dyndns.org.
+www.update.microsoft.com.
+c-0.19-210f8801.8020081.1518.19d4.3ea1.210.0.edipit6qmwhmvfd93tphlqk856.avqs.mcafee.com.
+csi.gstatic.com.
+a4.sphotos.ak.fbcdn.net.
+167.163.39.187.in-addr.arpa.
+www.google.com.me.
+sothorn.net.
+26.169.109.200.in-addr.arpa.
+rtb.pclick.yahoo.com.
+chevaliermalay.com.
+indid.ru.
+205.167.126.200.in-addr.arpa.
+88.33.155.189.in-addr.arpa.
+nyti.ms.
+photos-a.ak.fbcdn.net.
+photos-f.ak.fbcdn.net.
+www.gnomonwatches.com.
+imissyouif.blogspot.com.
+unblocker.me.
+kalamsetat.blogspot.com.
+a.root-servers.net.
+photos-c.ak.fbcdn.net.
+api.facebook.com.
+photos-c.ak.fbcdn.net.
+mcmcorp.com.
+config.broadvoice.com.
+www.realtalkreggaeton.net.
+dmpas02.scig.gov.hk.
+www.gravatar.com.
+smx.rrt.net.redcondor.net.
+www.youtube.com.
+mobile.webroot.com.
+v8.cache5.c.youtube.com.
+admin.na5.acrobat.com.
+profile.ak.fbcdn.net.
+i3.ytimg.com.
+32.102.11.190.in-addr.arpa.
+www.ontronics.com.
+13.29.78.41.in-addr.arpa.
+binary-zone.com.
+125.240.72.189.in-addr.arpa.
+www.dmaranatha.com.
+widgets.amung.us.
+thequeensgalley.org.
+www.milfmature.net.
+macrae4.wanadoo.co.uk.
+.
+glassmenagerie.com.
+hibble.com.au.
+lh3.googleusercontent.com.
+a.root-servers.net.
+24.229.171.69.in-addr.arpa.
+g.ceipmsn.com.
+www.cuevana.tv.
+dns.msftncsi.com.
+a3.sphotos.ak.fbcdn.net.
+photos-h.ak.fbcdn.net.
+24.159.89.186.in-addr.arpa.
+a.root-servers.net.
+cricinfo.co.
+bangbroscorp.com.
+b._dns-sd._udp.0.1.168.192.in-addr.arpa.
+photos-d.ak.fbcdn.net.
+inbound.stuartsofeldorado.com.netsolmail.net.
+www.futurocine.com.
+r.mzstatic.com.
+report.cedexis.com.
+akcontent.ebuddy.com.
+195.1.168.192.in-addr.arpa.
+i3.ytimg.com.
+www.facebook.com.
+a.root-servers.net.
+photos-h.ak.fbcdn.net.
+alerts.conduit-services.com.
+62.72.221.190.in-addr.arpa.
+94.36.174.190.in-addr.arpa.
+photos-h.ak.fbcdn.net.
+www.petnos.com.
+mx0.calcet.com.
+a2.sphotos.ak.fbcdn.net.
+cacheserve.williamhill.com.
+a-0.19-23090081.a020083.1518.19b2.410a.400.9d.u1s471dkqp57euv5pprpsp3jtb.avqs.mcafee.com.
+153.6.214.189.in-addr.arpa.
+l.yimg.com.
+pagead2.googlesyndication.com.
+162.235.94.82.in-addr.arpa.
+a5.sphotos.ak.fbcdn.net.
+dns.msftncsi.com.
+translate.google.com.mx.
+40.153.11.94.in-addr.arpa.
+cdn3.api.openfeint.com.
+biometeurope.com.
+d7.zedo.com.
+api.facebook.com.
+.
+63.185.141.189.in-addr.arpa.
+bankri.com.s6a1.psmtp.com.
+metrics.target.com.
+177.220.10.187.in-addr.arpa.
+228.137.37.114.in-addr.arpa.
+forominecraft.foroactivo.com.
+s7.addthis.com.
+e7rk3dsv3.23ys.
+unifi.
+a.root-servers.net.
+pixel.quantserve.com.
+creative.ak.fbcdn.net.
+lunix.wscb.ru.
+198.102.131.189.in-addr.arpa.
+twitter.com.
+204.234.112.186.in-addr.arpa.
+247.176.178.190.in-addr.arpa.
+7.94.200.195.in-addr.arpa.
+226.171.204.130.in-addr.arpa.
+a.root-servers.net.
+gibbons.com.
+cmithum.com.
+34.111.149.187.in-addr.arpa.
+fa.wikipedia.org.
+106.21.251.201.in-addr.arpa.
+www.facebook.com.
+node.applifier.com.
+98.80.229.77.in-addr.arpa.
+myworkinet.ru.
+support.google.com.
+www.adobe.com.
+www.belkin.com.
+94.119.174.190.in-addr.arpa.
+resources.infolinks.com.
+creative.ak.fbcdn.net.
+homoclub.foroactivo.com.
+creative.ak.fbcdn.net.
+fbcdn-sphotos-a.akamaihd.net.
+212.190.51.190.in-addr.arpa.
+luchifeliz.lacoctelera.net.
+secure.wlxrs.com.
+235.71.224.189.in-addr.arpa.
+www.antiplagas.com.
+136.190.19.186.in-addr.arpa.
+www.genbeta.com.
+a6.sphotos.ak.fbcdn.net.
+a.root-servers.net.
+24.239.188.189.in-addr.arpa.
+a5.sphotos.ak.fbcdn.net.
+a1408.w43.akamai.net.
+www.facebook.com.
+img1.blogblog.com.
+i2.ytimg.com.
+a3.sphotos.ak.fbcdn.net.
+tiscali.it.
+plusone.google.com.
+safebrowsing-cache.google.com.
+a8.sphotos.ak.fbcdn.net.
+191.237.37.190.in-addr.arpa.
+gallospedragliofarm.com.
+27.147.220.66.in-addr.arpa.
+www.ginasommelier.com.mx.
+200.132.65.85.in-addr.arpa.
+a7.sphotos.ak.fbcdn.net.
+ad-g.doubleclick.net.
+power.alstom.com.
+cs792.vk.com.
+clients2.google.com.
+155.205.59.186.in-addr.arpa.
+mail.google.com.
+ocsp.thawte.com.
+fbcdn-profile-a.akamaihd.net.
+empresasinternacionales.com.
+www.yahoo.com.
+www.bestbuy.com.mx.
+214.189.144.186.in-addr.arpa.
+mta1.am0.yahoodns.net.
+127.87.91.186.in-addr.arpa.
+teredo.ipv6.microsoft.com.
+www.twgirl.net.
+gotthard-karstens.de.
+9gag.com.
+support.google.com.
+41.175.106.200.in-addr.arpa.
+personnel.nsk.su.
+bf74c17fce5b72a5f98844a4f8446b2c.org.
+d2099252.xoom.it.
+solarwinds-tftp-server.softonic.com.
+uk.pwc.com.
+a2.sphotos.ak.fbcdn.net.
+231.137.82.189.in-addr.arpa.
+248.90.159.189.in-addr.arpa.
+csi.gstatic.com.
+crossdillon.com.
+unifi.lan.
+mt4-is02.fxsecure.com.
+pcwin.com.
+a2.sphotos.ak.fbcdn.net.
+reportlink.pbwdev.com.
+www.fineartsla.com.
+206.48.31.82.in-addr.arpa.
+www.anpad.org.br.
+youtube-ui.l.google.com.
+a1294.w20.akamai.net.
+a.root-servers.net.
+needless.jp.
+www.google.com.
+styletraxx.com.
+profile.ameba.jp.
+agzgcoo.info.
+www.facebook.com.
+teredo.ipv6.microsoft.com.
+a5.sphotos.ak.fbcdn.net.
+s.staticyonkis.com.
+twitter.com.
+www.stage6fullero.net.
+p04-caldav.icloud.com.
+1.0.0.127.dnsbugtest.1.0.0.127.in-addr.arpa.
+google.com.
+nohaypan.blogspot.com.
+pixel.facebook.com.
+kosu.ru.
+br.weather.com.
+pix2pix.org.
+elblogdeledzeppelin.blogspot.com.
+www.gstatic.com.
+couponbuddy.s3.amazonaws.com.
+in.jagran.yahoo.com.
+19.136.194.187.in-addr.arpa.
+www.google.com.
+photos-a.ak.fbcdn.net.
+photos-d.ak.fbcdn.net.
+shared.live.com.
+ryouae.com.
+linkhelp.clients.google.com.
+mosmas.ru.
+70.67.144.180.in-addr.arpa.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+i30.tinypic.com.
+autos.aol.com.
+rssgov.windows.microsoft.com.
+155.165.201.190.in-addr.arpa.
+profile.ak.fbcdn.net.
+profile.ak.fbcdn.net.
+sparkpeo.vo.llnwd.net.
+suoernet.com.
+fwaproducts.com.
+th239.photobucket.com.
+csi.gstatic.com.
+6.15.224.88.in-addr.arpa.
+pb.blabbers.com.
+hotmail.com.
+seal-alaskaoregonwesternwashington.bbb.org.
+badoo.com.
+a1.sphotos.ak.fbcdn.net.
+237.5.205.187.in-addr.arpa.
+17.121.207.82.in-addr.arpa.
+a.root-servers.net.
+www.ivb.cz.
+_394_85_9.
+rosefarm.com.
+smtp.live.com.
+www.ipkat.com.
+playig.com.
+download.windowsupdate.com.
+www.google.com.
+sp.cwfservice.net.
+touch.facebook.com.
+144.41.253.111.in-addr.arpa.
+domino.juegate.com.
+as-gest.com.
+6wlpnxaas.j92f5h4u.
+view.atdmt.com.
+137.203.132.189.in-addr.arpa.
+ad.wowtv.co.kr.
+marknet.ee.
+teredo.ipv6.microsoft.com.
+subseven90.no-ip.org.
+ns1.hsbc.com.sg.
+86.14.38.186.in-addr.arpa.
+link.nokia.com.
+www.facebook.com.
+tas.orangeads.fr.
+static.woopra.com.
+chinoataku.wordpress.com.
+es-la.facebook.com.
+iwebunlimited.com.
+mail.chronicleseries.com.
+www.foxrio2.com.
+secure.logmein.com.
+www.terra.com.
+67.36.138.187.in-addr.arpa.
+a.root-servers.net.
+www.portalminero.com.
+58.93.153.189.in-addr.arpa.
+103.216.177.190.in-addr.arpa.
+www.youtube.com.
+g.ceipmsn.com.
+35.227.239.189.in-addr.arpa.
+www.gameschecker.de.
+lh5.ggpht.com.
+blog.typograffit.com.
+ns1.scs-net.org.
+csmonolit.ru.
+233.108.156.114.in-addr.arpa.
+www.sciencebooksonline.info.
+214.245.43.190.in-addr.arpa.
+196.76.20.187.in-addr.arpa.
+webcache.googleusercontent.com.
+luckyemperor.tumblr.com.
+node.applifier.com.
+ihktech.net.
+localhost.
+b.scorecardresearch.com.
+a3.sphotos.ak.fbcdn.net.
+199.26.0.10.in-addr.arpa.
+.
+nextag.com.
+a4.sphotos.ak.fbcdn.net.
+mail.resheto.ru.
+pagead2.googlesyndication.com.
+riehle.org.
+tor-office.iqpartners.com.
+markoniya.ucoz.ru.
+delivery.trafficbroker.com.
+fr-fr.facebook.com.
+parana.tuentrerios.com.
+time.bora.net.
+seaborne-intl.com.
+220.176.88.186.in-addr.arpa.
+www.pension4armynews.co.uk.
+server.sportsawardsonline.com.
+43.106.148.190.in-addr.arpa.
+media.tumblr.com.
+teredo.ipv6.microsoft.com.
+221.62.232.189.in-addr.arpa.
+photos-f.ak.fbcdn.net.
+apps.facebook.com.
+t.co.
+uluniwiming.com.
+nastymomvideo.com.
+www.muzik-torrent.net.
+18.4.183.65.in-addr.arpa.
+dns.msftncsi.com.
+s-static.ak.fbcdn.net.
+fbcdn-profile-a.akamaihd.net.
+auto.mail.ru.
+smk-iso9001.ru.
+5.237.223.201.in-addr.arpa.
+www.agame.me.
+175.74.31.189.in-addr.arpa.
+www.2dplan.com.
+dnl-01.geo.kaspersky.com.
+ciber.
+www.lotteryinsider.com.
+sgdc1max1.chevron.com.
+safebrowsing-cache.google.com.
+mx.xmission.com.
+41.146.230.99.in-addr.arpa.
+ipmsa.ru.
+skydrive.live.com.
+vietstar.info.
+tnbaptist.org.
+www.msftncsi.com.
+www.wtp101.com.
+dnl-01.geo.kaspersky.com.
+a7.sphotos.ak.fbcdn.net.
+nekrst.nek.ru.s200a1.psmtp.com.
+48.ns1631263.net.
+localhost.
+www.hotmail.com.
+www.cgsecurity.org.
+www.path.cam.ac.uk.
+ws.tapjoyads.com.
+platform.twitter.com.
+romsan.ru.
+76.31.2.187.in-addr.arpa.
+racismdaily.com.
+www.google.com.mx.
+167.78.247.88.in-addr.arpa.
+www.voayeurs.com.
+teredo.ipv6.microsoft.com.
+a5.sphotos.ak.fbcdn.net.
+netflix-login.com.
+www.newseasims.com.
+a.ads2.msads.net.
+img100.xvideos.com.
+mail.ppcserver.net.
+a1725.l.akamai.net.
+241.40.20.186.in-addr.arpa.
+a3.sphotos.ak.fbcdn.net.
+tj9w5jhz4.a72f1k2h.
+trendeotonyo.files.wordpress.com.
+68.90.53.187.in-addr.arpa.
+123.222.155.189.in-addr.arpa.
+qbtmwj.info.
+www.cahams.com.
+sofort-mail.de.
+i1.ytimg.com.
+84.21.221.189.in-addr.arpa.
+www.update-software.com.
+ksn2-12.kaspersky-labs.com.
+www.chemm.cn.
+www.goodwinmedia.com.
+1800sunstar.com.
+advanced-renamer.en.softonic.com.
+photos-h.ak.fbcdn.net.
+ad-emea.doubleclick.net.
+homethelovely.com.
+totao56.files.wordpress.com.
+stephenstimson.com.1.0001.arsmtp.com.
+www.homesearch.ph.
+safebrowsing.clients.google.com.
+mail.sierraconstruction.com.
+www.juegosdecrear.net.
+t3.gstatic.com.
+www.stnicholascenter.org.
+evsecure-ocsp.verisign.com.
+itcomp.pl.
+a.root-servers.net.
+radar.cedexis.com.
+en.bn.fb.igg.com.
+10.38.49.151.in-addr.arpa.
+pixel.facebook.com.
+bgnet.com.
+181.236.232.190.in-addr.arpa.
+mail.paquettewhite.com.
+www.mypursehandbag.com.
+melitusmen.podbean.com.
+249.35.193.187.in-addr.arpa.
+a.root-servers.net.
+crl.thawte.com.
+101.43.23.186.in-addr.arpa.
+a.root-servers.net.
+www.toshiba.com.mx.
+db2.stb01.s-msn.com.
+t.co.
+211.65.27.69.in-addr.arpa.
+s-static.ak.facebook.com.
+230.98.135.187.in-addr.arpa.
+www.blackberry.com.
+images.proxm.com.
+plus.google.com.
+www.pajamasmedia.com.
+time.chttl.com.tw.
+190.178.85.186.in-addr.arpa.
+mail.google.com.
+wearnesmotors.com.
+tap2-cdn.rubiconproject.com.
+170.252.6.190.in-addr.arpa.
+www.braillenet.org.
+photos-h.ak.fbcdn.net.
+trianguloequidlatere.blogspot.com.
+www.susanholmes.net.
+www.offshore-fox.com.
+apix.iminent.com.
+static.ak.fbcdn.net.
+static.ak.fbcdn.net.
+a771.da1.akamai.net.
+0-jg-w.channel.facebook.com.
+106.178.161.207.in-addr.arpa.
+couponbuddy.s3.amazonaws.com.
+crl.microsoft.com.
+groups.yahoo.com.
+a.rad.msn.com.
+apis.google.com.
+0-278.channel.facebook.com.
+cs4109.vkontakte.ru.
+cdn.lfstmedia.com.
+_293_69_4.
+docs.google.com.
+dns.msftncsi.com.
+photos-f.ak.fbcdn.net.
+163.141.109.190.in-addr.arpa.
+www.defensa.cl.
+ytimg.l.google.com.
+www.gmail.com.
+www.culioneros.com.
+sutrust.com.
+mcermalwbbes.nu.
+fbcdn-photos-a.akamaihd.net.
+236.93.121.190.in-addr.arpa.
+www.buenscoring.com.
+_883_08_2.
+ulead-gif-animator.softonic.pl.
+www.blogger.com.
+s-static.ak.facebook.com.
+i1.ytimg.com.
+a3.sphotos.ak.fbcdn.net.
+48.30.227.201.in-addr.arpa.
+captcha.naver.com.
+apps.facebook.com.
+200.253.171.200.in-addr.arpa.
+api.twitter.com.
+img.funenclave.com.
+blogs.visoftinc.com.
+www.google-analytics.com.
+photos-h.ak.fbcdn.net.
+cdn.at.atwola.com.
+a.root-servers.net.
+pool.ntp.org.
+ping1.unicast.com.
+client-software.real.com.
+a.root-servers.net.
+78.165.50.190.in-addr.arpa.
+dns.msftncsi.com.
+cp2.websolspk.com.
+www.linkmoz.org.
+i1.ytimg.com.
+www.bestellipticalreviews.org.
+apps.facebook.com.
+download943.avast.com.
+_712_11_0.
+100.248.211.201.in-addr.arpa.
+www.wandermap.net.
+weather.wapp.wii.com.
+www.funpic.in.
+23.74.61.186.in-addr.arpa.
+transparencia-economica.mef.gob.pe.
+.
+creative.ak.fbcdn.net.
+239.177.2.200.in-addr.arpa.
+stroytrek.ru.
+static.ak.fbcdn.net.
+www.lika-online.com.
+192.186.22.186.in-addr.arpa.
+238.96.133.115.in-addr.arpa.
+photos-a.ak.fbcdn.net.
+bjklaw.us.2.arsmtp.com.
+www.facebook.com.
+www.ledmobile.net.
+static.ak.fbcdn.net.
+connect.facebook.net.
+api.twitter.com.
+stun.voip.blackberry.com.
+descargalosmejoresprogramasgratis.blogspot.com.
+googleads.g.doubleclick.net.
+www.amazon.ca.
+mail.
+b._dns-sd._udp.0.1.168.192.in-addr.arpa.
+www.labsdirect.com.
+62.219.124.202.in-addr.arpa.
+23.245.176.186.in-addr.arpa.
+sm9.sitemeter.com.
+www.twitter.com.
+www.google-analytics.com.
+www.microjuris.com.
+rldownload.com.
+ksn3-11.part1.kaspersky-labs.com.
+clients1.google.com.
+239.163.251.201.in-addr.arpa.
+safebrowsing-cache.google.com.
+www.justgayhardcore.com.
+youtu.be.
+www.comprarenmollet.com.
+a.root-servers.net.
+213.89.111.189.in-addr.arpa.
+www.ldsdudes.com.
+220.82.252.201.in-addr.arpa.
+s2j369:pg.m77t9e0x.
+ky3.com.s5a1.psmtp.com.
+m.youtube.com.
+s4.histats.com.
+152.192.54.190.in-addr.arpa.
+ns.nav.kiev.ua.
+dnl-06.geo.kaspersky.com.
+static.ak.fbcdn.net.
+b._dns-sd._udp.0.1.168.192.in-addr.arpa.
+251.189.114.189.in-addr.arpa.
+a.root-servers.net.
+mailc.txdps.state.tx.us.
+sp.cwfservice.net.
+180.115.145.78.in-addr.arpa.
+www.thesound.co.nz.
+www.grupoimplantes.com.ar.
+crl.microsoft.com.
+s0.2mdn.net.
+blog.oafe.net.
+istatistikler.ligtv.com.tr.
+sulfatreat.com.
+ad.yieldmanager.com.
+plus.google.com.
+gtaonline.com.ar.
+profile.ak.fbcdn.net.
+tdsystems.org.
+www.ofertas-outlets.com.
+mx.msn.recepedia.com.
+fxfeeds.mozilla.com.
+www.toolguys.com.
+1.201.159.189.in-addr.arpa.
+sp.cwfservice.net.
+203.160.179.190.in-addr.arpa.
+db._dns-sd._udp.0.1.168.192.in-addr.arpa.
+s.ytimg.com.
+b-0.19-2309c008.c0c1081.1518.19ce.3ea1.410.0.5d7ar9ejb8b4z724c3w9ldp4p5.avqs.mcafee.com.
+www.dondeganardinero.com.
+tc22.easythumbhost.com.
+20.29.184.186.in-addr.arpa.
+antarcticsun.usap.gov.
+www.dailymail.pinkribbonbingo.com.
+a1.sphotos.ak.fbcdn.net.
+_853_37_3.
+go.microsoft.com.
+135.90.188.201.in-addr.arpa.
+www.minikmodaci.com.
+a6.sphotos.ak.fbcdn.net.
+ls57tiger.freepgs.com.
+phfilms.com.
+upload.wikimedia.org.
+twitter.com.
+pixel.facebook.com.
+chqronq5f.n56q7s1o.
+bnreview.lithium.com.
+mx.youtube.com.
+pivotnetworks.com.inbound15.mxlogicmx.net.
+31.65.252.117.in-addr.arpa.
+tarkett-ee.com.s200a2.psmtp.com.
+inbound.midtownhotel.com.netsolmail.net.
+rediffamil.com.
+i.ytimg.com.
+www.photorecept.ru.
+mx.youtube.com.
+peabodygallery.com.
+a.root-servers.net.
+a.root-servers.net.
+www.cheforopeza.com.mx.
+195.39.102.189.in-addr.arpa.
+www.photo-warping.com.
+play.jo.
+xagminecraft.blogspot.com.
+photos-a.ak.fbcdn.net.
+designerbagcatalog.com.
+61.99.112.112.in-addr.arpa.
+www.google-analytics.com.
+tatooshop.ru.
+d1ros97qkrwjf5.cloudfront.net.
+prodigy.msn.com.
+www.google-analytics.com.
+mail02.avmin.co.za.
+ns1.sitibroadband.in.
+244.136.6.74.in-addr.arpa.
+photos-e.ak.fbcdn.net.
+ar.autos.yahoo.com.
+www.facebook.com.
+safebrowsing-cache.google.com.
+thraki-devil.blogspot.com.
+download624.avast.com.
+cetelbras.com.br.
+calgate01.a02.yahoodns.net.
+www.termofrigidus.com.
+parking.www.kilu.org.
+178.57.230.201.in-addr.arpa.
+www.bigfatass.org.
+44.150.14.88.in-addr.arpa.
+171.103.135.189.in-addr.arpa.
+s-static.ak.fbcdn.net.
+www.pipiota.blogspot.com.
+www.zfforum.es.
+pts.lockerz.com.
+mebelka.ru.
+www.botpa.co.kr.
+staleyplanning.com.
+push.apple.com.
+rpm.elmundoenlinea.com.mx.
+44.29.194.173.in-addr.arpa.
+a.root-servers.net.
+a.root-servers.net.
+static.ak.fbcdn.net.
+b._dns-sd._udp.0.1.168.192.in-addr.arpa.
+161.226.120.68.in-addr.arpa.
+css.wlxrs.com.
+a.root-servers.net.
+a.root-servers.net.
+a.root-servers.net.
+photos-e.ak.fbcdn.net.
+wakayama-med.ac.jp.
+db._dns-sd._udp.0.195.16.172.in-addr.arpa.
+198.114.4.171.in-addr.arpa.
+adserving.cpxinteractive.com.
+pcthings.org.uk.
+www.titsbig.net.
+view.atdmt.com.
+29.234.229.190.in-addr.arpa.
+114.45.87.186.in-addr.arpa.
+215.99.24.190.in-addr.arpa.
+s-external.ak.fbcdn.net.
+37.192.11.111.in-addr.arpa.
+dsn15.d.skype.net.
+challiance.com.
+b._dns-sd._udp.0.1.168.192.in-addr.arpa.
+149.250.16.190.in-addr.arpa.
+83.149.10.75.in-addr.arpa.
+calendar.live.com.
+google.com.
+a1108.da1.akamai.net.
+photos-b.ak.fbcdn.net.
+suggestqueries.google.com.
+elperro13.net.
+viajes-vuelos.agencias-de-viajes.com.
+es-la.facebook.com.
+photos-a.ak.fbcdn.net.
+ajax.googleapis.com.
+www.computadorasenlaeducacion.com.
+s0.2mdn.net.
+1.0.0.127.in-addr.arpa.
+sup.live.com.
+222.143.162.190.in-addr.arpa.
+es-la.facebook.com.
+apix.iminent.com.
+164.145.168.192.in-addr.arpa.
+a8.sphotos.ak.fbcdn.net.
+ipcast2.dynupdate.no-ip.com.
+myiafrica.com.
+www-fc-opensocial.googleusercontent.com.
+gfx2.hotmail.com.
+1.0.0.127.dnsbugtest.1.0.0.127.in-addr.arpa.
+photos-c.ak.fbcdn.net.
+greystone.messagescreen.com.
+ad.yieldmanager.com.
+updates.sonic.com.
+profile.ak.fbcdn.net.
+twitter.com.
+www.xom.com.mx.
+a6.sphotos.ak.fbcdn.net.
+ajax.aspnetcdn.com.
+kidbleach.com.
+pop.theitmachine.com.
+player.vimeo.com.
+51.252.22.24.in-addr.arpa.
+www.gatitasconcam.com.
+ssl.gstatic.com.
+www.souleaterwallpaper.com.
+teredo.ipv6.microsoft.com.
+login.live.com.
+wpad.
+mail.brce.com.
+b._dns-sd._udp.0.2.168.192.in-addr.arpa.
+82.146.69.190.in-addr.arpa.
+174.169.245.190.in-addr.arpa.
+sac.gti.mcafee.com.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+s.youtube.com.
+www.facebook.com.
+150.102.35.189.in-addr.arpa.
+nbmedia.com.
+776964676574.6265.6575.63726974656f.636f6d.80hb2fa014f.webcfs00.com.
+134.117.6.210.in-addr.arpa.
+rs931l3.rapidshare.com.
+lb._dns-sd._udp.lan.
+ns2.redbee.nl.
+db._dns-sd._udp.0.0.168.192.in-addr.arpa.
+www.stumbleupon.com.
+ssl.gstatic.com.
+pu.com.au.
+www.facebook.com.
+asia.battle.net.
+www.nhtbw.com.
+_ldap._tcp.
+xtra.co.nz.
+api.twitter.com.
+lh4.ggpht.com.
+220.103.174.190.in-addr.arpa.
+remote.dillonworks.com.
+www.twitter.com.
+76.245.24.88.in-addr.arpa.
+143.233.26.85.in-addr.arpa.
+geo.ltassrv.com.
+profile.ak.fbcdn.net.
+226.86.213.83.in-addr.arpa.
+32.6.22.95.in-addr.arpa.
+profile.ak.fbcdn.net.
+195.108.173.190.in-addr.arpa.
+www.facebook.com.
+rad.msn.com.
+profile.ak.fbcdn.net.
+210.9.0.10.in-addr.arpa.
+www.stopbadware.org.
+53.237.83.71.in-addr.arpa.
+147.61.81.186.in-addr.arpa.
+www.msftncsi.com.
+www.taringa.net.
+191.22.187.67.in-addr.arpa.
+marihuanacultivo.com.
+creative.ak.fbcdn.net.
+parenting.co.uk.
+item.taobao.com.
+www.freesexnavigator.com.
+t13.intelliad.de.
+www.youravon.com.
+mail.translabourage.ru.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+www.google.com.
+3j:onbsbh.87dl.
+236.127.171.189.in-addr.arpa.
+158.74.61.174.in-addr.arpa.
+19.191.55.72.in-addr.arpa.
+a3.sphotos.ak.fbcdn.net.
+thetastefulbasket.com.
+loading.retry.widdit.com.
+ulrtrxxhxonsyh.info.
+analyze.net.tf.
+27.42.56.190.in-addr.arpa.
+s.ytimg.com.
+multiplaz.ru.
+safebrowsing-cache.google.com.
+238.242.16.122.in-addr.arpa.
+www.altaro.com.
+www.calorieking.com.
+www.agenciaartistatv.com.
+www.google-analytics.com.
+groups.google.com.mx.
+www.homestayfinder.com.
+81.173.168.75.in-addr.arpa.
+www.facebook.com.
+107.1.168.192.in-addr.arpa.
+_ldap._tcp.
+234.31.232.189.in-addr.arpa.
+novar.com.
+www.dibujosdisney.org.
+creative.ak.fbcdn.net.
+7.129.234.119.in-addr.arpa.
+mx.katsinas.com.
+eltech.net.pl.
+v1.nonxt5.c.youtube.com.
+aig.com.co.
+55.31.142.187.in-addr.arpa.
+updatekeepalive.mcafee.com.
+242.132.123.84.in-addr.arpa.
+mail.foxriver.ru.
+billing.service.playfish.com.
+crl.microsoft.com.
+soporte.pandasecurity.com.
+entrysfo002a.skyfire.com.
+32.245.23.186.in-addr.arpa.
+m.facebook.com.
+162.135.84.41.in-addr.arpa.
+117.52.160.189.in-addr.arpa.
+214.12.146.187.in-addr.arpa.
+dsmllp.com.
+static.image-gmkt.com.
+static.ak.fbcdn.net.
+google.com.
+a.root-servers.net.
+it-it.facebook.com.
+s-static.ak.facebook.com.
+guru.avg.com.
+ad.lpxp.net.
+www.youtube.com.
+a.root-servers.net.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+www.linares.net.
+mailhost.tecrodpd.com.
+facebook.com.my.hostlogr.com.
+amitelco.com.
+15.93.131.187.in-addr.arpa.
+177.209.121.65.in-addr.arpa.
+a.root-servers.net.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+mx.alfacenter.it.
+pop3.live.com.
+buttons.reddit.com.
+www.game.ezfun.net.
+s.ytimg.com.
+developers.facebook.com.
+mk4099.spb.edu.
+actionplusrealty.com.
+mail.limbless-association.org.
+rss.cbc.ca.
+252.22.0.192.in-addr.arpa.
+creative.ak.fbcdn.net.
+msgr.updates.yahoo.com.
+www.chinaglia.com.br.
+s-static.ak.facebook.com.
+www.isabelaguera.com.
+pagead.l.doubleclick.net.
+www.10ka20.com.
+www.facebook.com.
+links.mkt1340.com.
+mail.rbi.com.
+www.todoar.com.ar.
+load.s3.amazonaws.com.
+thrice.net.
+sparks.city.nv.us.
+s1.ubalert.com.
+australiasevereweather.com.
+voipa.sip.yahoo.com.
+www.viendosexo.com.
+teredo.ipv6.microsoft.com.
+130.114.76.83.in-addr.arpa.
+www.6188.com.
+mail.google.com.
+ad-g.doubleclick.net.
+26.media.tumblr.com.
+eu.wikipedia.org.
+250.11.168.192.in-addr.arpa.
+cdduplicationdata.com.
+47.37.1.190.in-addr.arpa.
+www.nsoftware.com.
+156.155.195.90.in-addr.arpa.
+apps.facebook.com.
+tavi-dent.ru.
+a1.twimg.com.
+3.1.2.a.2.5.6.a.0.8.5.0.3.d.4.1.d.f.9.7.5.f.e.5.0.0.0.0.1.0.0.2.ip6.arpa.
+1africa.com.
+teredo.ipv6.microsoft.com.
+0-44.channel.facebook.com.
+profile.ak.fbcdn.net.
+51.99.223.87.in-addr.arpa.
+bt-srv01.bauschtech.com.
+creative.ak.fbcdn.net.
+mail.ourismanva.com.mx.swishmail.net.
+photos-f.ak.fbcdn.net.
+www.loyola.edu.mx.
+77.34.205.71.in-addr.arpa.
+7.90.119.177.in-addr.arpa.
+zeroz.biz.
+orkom1c.ru.
+courseroom2.capella.edu.
+sp.cwfservice.net.
+3.bp.blogspot.com.
+mx.sdelali.ru.
+server-28.reportgoogle.com.
+27.194.191.189.in-addr.arpa.
+_684_97_4.
+so-gi.spb.ru.
+rcl.ramsey.lib.mn.us.
+www.foscarini.com.
+ssl.gstatic.com.
+www.templaraz.com.
+movies.broadwayworld.com.
+a.root-servers.net.
+palsa.com.
+www.eurekasa.it.
+131.141.108.187.in-addr.arpa.
+dsn9.d.skype.net.
+mx2.sanet.ru.
+www.cookingforgirlz.com.
+26.255.57.69.in-addr.arpa.
+whisperedinspirations.com.
+img3.stripperparadise.com.
+www.divxmovieplayer.com.
+www.facebook.com.
+ad.yieldmanager.com.
+234.189.174.195.in-addr.arpa.
+cs1524.vkontakte.ru.
+69.177.171.187.in-addr.arpa.
+13.149.165.83.in-addr.arpa.
+bs.serving-sys.com.
+google.com.
+bbg.lt.
+piano.ocn.ne.jp.
+a.root-servers.net.
+r.turn.com.
+www.juegosjuegos.com.
+58.165.44.194.in-addr.arpa.
+videos.mundo.com.
+93.95.82.203.in-addr.arpa.
+m.wsj.net.
+mail02.gigalinkmail.com.
+zjam.com.
+beacon.shazam.com.
+www.facebook.com.
+205.20.243.88.in-addr.arpa.
+partner.googleadservices.com.
+adserver.adtech.de.
+tigerbeatdown.com.
+a1497.phobos.apple.com.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+fxfeeds.mozilla.com.
+6.15.122.84.in-addr.arpa.
+72ffkjpjn.07kc.
+juno.com.
+www.kaleykennedy.com.
+smtp.tmr-sa.co.za.
+a7.sphotos.ak.fbcdn.net.
+front.pyramid.kobojo.com.
+a.root-servers.net.
+techgage.com.
+az15112.vo.msecnd.net.
+anewmode.com.
+61.52.14.186.in-addr.arpa.
+www.vuelomania.com.
+sp.cwfservice.net.
+lakelanier.com.
+apps.facebook.com.
+ads.prisacom.com.
+v1kqf35es.27fg.
+apps.facebook.com.
+175.254.236.201.in-addr.arpa.
+c14152960.web.cddbp.net.
+slabberredux.blogspot.com.
+11.28.174.190.in-addr.arpa.
+xmpp003.hpeprint.com.
+dns.msftncsi.com.
+adsrv.deviantart.com.
+comptoncorp.com.
+lnhi.net.s7b2.psmtp.com.
+dns.msftncsi.com.
+www.cloudkillers.com.
+chi.rtkl.com.
+102.169.85.186.in-addr.arpa.
+localhost.
+static.ak.fbcdn.net.
+ar-ar.facebook.com.
+12.17.141.201.in-addr.arpa.
+developers.facebook.com.
+content.yieldmanager.edgesuite.net.
+www.youtube.com.
+www.segurosvip.com.
+amateur-pussy-finder.notlong.com.
+pagead2.googlesyndication.com.
+232.156.83.62.in-addr.arpa.
+mail.proitss.com.
+cure-net.com.
+f.funmoods.com.
+172.201.178.190.in-addr.arpa.
+b._dns-sd._udp.0.2.168.192.in-addr.arpa.
+www.tabletsandroid.com.ar.
+202.88.55.74.in-addr.arpa.
+forums.redcarpetrebellion.org.
+s-static.ak.fbcdn.net.
+board.airrivals.net.
+0-jx-w.channel.facebook.com.
+www.outlook-web-access.com.
+www.tibet-tour.com.
+9gag.com.
+creative.ak.fbcdn.net.
+www.yeze.us.
+a.analytics.yahoo.com.
+121.173.116.174.in-addr.arpa.
+external.ak.fbcdn.net.
+dnl-01.geo.kaspersky.com.
+a.root-servers.net.
+www.kenrockwell.com.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+su.wikipedia.org.
+fotolog.terra.com.co.
+mail.realdating.ru.
+ad.turn.com.
+85.61.24.190.in-addr.arpa.
+inglcarion.com.
+mindspring.com.
+a3.twimg.com.
+a7.sphotos.ak.fbcdn.net.
+storage.conduit.com.
+wd-edge.sharethis.com.
+www.tattooremoval.eu.
+time.vonage.net.
+dnl-01.geo.kaspersky.com.
+52.72.143.201.in-addr.arpa.
+cogame.timestorm.de.
+bostoncomedyfest.com.
+154.108.95.190.in-addr.arpa.
+v6.nonxt2.c.youtube.com.
+barcorgages.com.
+39.6.188.190.in-addr.arpa.
+hzs7.cnzz.com.
+206.164.141.69.in-addr.arpa.
+a.root-servers.net.
+www.seoghoer.dk.
+photos-f.ak.fbcdn.net.
+www.japanican.com.
+49.180.96.65.in-addr.arpa.
+7064612d6173.616d617a6f6e.636f6d.80h4815d64a.webcfs00.com.
+mail.nlicgulf.com.
+ikhr9bhww.y55i6n4r.
+www.google.com.
+a.root-servers.net.
+vfsuites.com.
+a7.sphotos.ak.fbcdn.net.
+203.3.23.113.in-addr.arpa.
+click.18clicks.com.
+richfaces.org.
+redsweetclubvip.com.multi.surbl.org.
+casiangelesymuchomas.blogspot.es.
+twitter.com.
+a1725.l.akamai.net.
+a.root-servers.net.
+profile.ak.fbcdn.net.
+o-o.preferred.iad09s10.v14.lscache5.c.youtube.com.
+www.img.forogames.net.
+nflattorney.com.
+trsbattorneys.com.
+205.129.211.201.in-addr.arpa.
+6to4.ipv6.microsoft.com.
+127.77.144.79.in-addr.arpa.
+p0b.ru.
+dsn3.d.skype.net.
+sp.cwfservice.net.
+i49.tinypic.com.
+a.root-servers.net.
+www.bikegames247.com.
+136.177.111.89.in-addr.arpa.
+md:gm4wz9.c19f7a1y.
+carolina.cmac.com.
+43.134.187.67.in-addr.arpa.
+a4.sphotos.ak.fbcdn.net.
+ad.yieldmanager.com.
+es-es.facebook.com.
+a1.sphotos.ak.fbcdn.net.
+apps.facebook.com.
+philadelphia.ebayclassifieds.com.
+baymsg1020124.gateway.messenger.live.com.
+www.gstatic.com.
+187.89.102.84.in-addr.arpa.
+apnstatic.ask.com.
+msg.jetapp.com.
+a.root-servers.net.
+torrentz.eu.
+app.crowdscience.com.
+www.google.com.
+pix04.revsci.net.
+login.yahoo.net.
+aol.com.
+lh5.googleusercontent.com.
+css.wlxrs.com.
+159.4.146.189.in-addr.arpa.
+photos-a.ak.fbcdn.net.
+tralala.com.
+market.android.com.
+dns.msftncsi.com.
+pagead2.googlesyndication.com.
+www.google.gy.
+cisbec.net.
+a5.sphotos.ak.fbcdn.net.
+b-f-c.com.
+profile.ak.fbcdn.net.
+www.google-analytics.com.
+175.30.171.187.in-addr.arpa.
+0-68.channel.facebook.com.
+rad.msn.com.
+forums.extensis.com.
+safebrowsing-cache.google.com.
+ber.lesnoy.ru.
+319.ns1631263.info.
+safebrowsing-cache.google.com.
+pernod-ricard-canada.com.s7a2.psmtp.com.
+37.48.36.190.in-addr.arpa.
+liveupdate.symantecliveupdate.com.
+vcs2.msg.yahoo.com.
+www.addthis.com.
+ougsyrokrvoljtpz.net.
+www.desktopsmiley.com.
+sites.google.com.
+content.yieldmanager.edgesuite.net.
+saint-etienne.lachainemeteo.com.
+menofcolor.thumblogger.com.
+api.zynga.com.
+www.cbnicaragua.com.
+www.facebook.com.\255\255\255\255.
+lordbingo.co.uk.
+it-it.facebook.com.
+www.compassion-revolution.com.
+download.windowsupdate.com.
+images01.olx-st.com.
+mirabella.com.
+kaliman14.listen2myradio.com.
+www.fajarweb.com.
+142.145.87.187.in-addr.arpa.
+www.drmalpani.com.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+toolbar.live.com.
+2.149.120.187.in-addr.arpa.
+www.googleadservices.com.
+api.twitter.com.
+augustana.edu.s10b2.psmtp.com.
+translate.googleapis.com.
+varuc.com.
+www.tierradelfuego.gov.ar.
+embedhunter.com.
+alicexu59.en.made-in-china.com.
+ad.yieldmanager.com.
+search.babylon.com.
+203.233.100.74.in-addr.arpa.
+allo34.ru.
+sharptampa.com.
+crl.entrust.net.
+diq.wikipedia.org.
+www.nexteve.com.
+cdn.lfstmedia.com.
+www.google-analytics.com.
+www.coca-cola.ba.
+www.yourskin.nl.
+apix.iminent.com.
+ping3.dyngate.com.
+accounts.google.com.
+i4.ytimg.com.
+139.41.252.190.in-addr.arpa.
+synd.netseer.com.
+weather.wapp.wii.com.
+photos-a.ak.fbcdn.net.
+img520.imageshack.us.
+fxfeeds.mozilla.com.
+ut2.xhamster.com.
+clients.babylon.com.
+pubads.g.doubleclick.net.
+139.7.145.92.in-addr.arpa.
+api.twitter.com.
+mail.calparks.org.
+cdn.fastclick.net.
+resources1.search.conduit.com.
+safebrowsing-cache.google.com.
+scsd.msg.yahoo.com.
+204.99.102.189.in-addr.arpa.
+cdn.api.twitter.com.
+0-310.channel.facebook.com.
+hsym8ldfm.61ll.
+www.edifact.com.mx.
+www.astigresasdofunk.com.br.
+admiral-billiard.ru.
+a1.sphotos.ak.fbcdn.net.
+a.root-servers.net.
+evsecure-ocsp.verisign.com.
+guzzoni.apple.com.
+35.191.113.187.in-addr.arpa.
+hostmysite.javahd.com.
+213.203.91.76.in-addr.arpa.
+test-rt.liftdna.com.
+ppgnow.com.
+members.dyndns.org.
+photos-f.ak.fbcdn.net.
+www.google.com.
+crl.godaddy.com.
+carlosgivaja.blogspot.com.
+beon.ru.
+dr._dns-sd._udp.0.3.168.192.in-addr.arpa.
+zpay.static.zynga.com.
+techsfera.blogspot.com.
+171.41.141.201.in-addr.arpa.
+41.211.101.24.in-addr.arpa.
+tmss.trendmicro.com.
+www.amazon.co.jp.
+login.live.com.
+b.static.ak.fbcdn.net.
+az15112.vo.msecnd.net.
+mail.bobcatwireless.net.
+extra-tm.ru.
+dancinteens.com.
+211.161.255.201.in-addr.arpa.
+www.mybrowserbar.com.
+designchlorid.com.
+mail.tesmedsonic.com.
+wikiguate.com.gt.
+zpwrcqmtpdtiolr.biz.
+shared.live.com.
+a.root-servers.net.
+a.root-servers.net.
+j5.tagstat.com.
+time.windows.com.
+dns.msftncsi.com.
+imap.gmail.com.
+ucs.query.yahoo.com.
+a.root-servers.net.
+mx4.hotmail.com.
+mx.pchg.net.
+pixel.facebook.com.
+rtigaf.com.
+a1005.w42.akamai.net.
+www.defenderseguridad.com.ar.
+94.53.58.187.in-addr.arpa.
+ds.serving-sys.com.
+dainikbhaskarcom.ourtoolbar.com.
+relay.data.edge.messenger.live.com.
+a-0.19-a3090071.9050083.1518.19d3.3ea1.410.0.e5ngemfnasja57b2n97v98jpmv.avqs.mcafee.com.
+www.webstats.motigo.com.
+145.111.221.189.in-addr.arpa.
+lh3.googleusercontent.com.
+27.media.tumblr.com.
+rtf.com.
+www.scotiabank.com.mx.
+www.jtc1.org.
+107.145.96.177.in-addr.arpa.
+vivastil.ru.
+nmbar.org.
+ads.revsci.net.
+cn1.redswoosh.akadns.net.
+fsnp74.ucsnet.ru.
+cy.pwc.com.
+245.194.152.202.in-addr.arpa.
+twitter.com.
+rememberthewar.com.
+vision.ucdavis.edu.
+a2.sphotos.ak.fbcdn.net.
+116.92.127.201.in-addr.arpa.
+167.98.46.190.in-addr.arpa.
+carlsandburgvisits.com.
+www.googletagservices.com.
+a5.sphotos.ak.fbcdn.net.
+7vwaptlqn.27tm.
+smarturl.it.
+16.3.129.189.in-addr.arpa.
+platform.ak.fbcdn.net.
+www.downtownbatonrouge.org.
+kytubhtgf.34dx.
+ib7nqfu12.e97u8g4a.
+orange.fr.
+187.10.168.192.in-addr.arpa.
+3e-co.com.
+pixel.rubiconproject.com.
+hughes.net.
+sp.cwfservice.net.
+developers.facebook.com.
+open.bonniersciencegroup.com.
+srp-law.com.
+embed.jungroup.com.
+25.76.150.190.in-addr.arpa.
+www.firstrowsports.tv.
+creative.ak.fbcdn.net.
+s-static.ak.facebook.com.
+www.portalculturista.com.
+referentia.com.s8a2.psmtp.com.
+southernsecurity.org.
+23.227.48.65.in-addr.arpa.
+rs749tl2.rapidshare.com.
+www.coolrom.com.
+206.217.75.190.in-addr.arpa.
+www.ellencparkhurst.com.
+brand.blogs.com.
+mail1.mxsmtp.com.
+connect.facebook.net.
+222.157.215.201.in-addr.arpa.
+shaoranlds.blogspot.com.
+sp.cwfservice.net.
+250.9.186.190.in-addr.arpa.
+video.auto.sina.com.cn.
+api.twitter.com.
+220.194.97.59.in-addr.arpa.
+philou-traductions.fr.
+emai.com.
+a1533.da1.akamai.net.
+apis.google.com.
+ars.oscar.aol.com.
+www.wisteriaandcowparsley.com.
+profile.ak.fbcdn.net.
+updatekeepalive.mcafee.com.
+245.212.18.95.in-addr.arpa.
+106.241.209.201.in-addr.arpa.
+metallurgizdat.com.
+geo.messenger.services.live.com.
+6e3ff508.allanalpass.com.
+214.80.65.190.in-addr.arpa.
+164.11.1.121.in-addr.arpa.
+a4.sphotos.ak.fbcdn.net.
+mxmail.datamaticstech.com.
+a997.mm1.akamai.net.
+sqm.microsoft.com.
+profile.ak.fbcdn.net.
+psychiatry.wustl.edu.
+58.168.245.61.in-addr.arpa.
+mvtv.kr.
+a5.sphotos.ak.fbcdn.net.
+twitter.com.
+static.ak.fbcdn.net.
+a8.sphotos.ak.fbcdn.net.
+gentechcontrols.com.
+fbcdn-photos-a.akamaihd.net.
+59.0.249.46.in-addr.arpa.
+a5.sphotos.ak.fbcdn.net.
+msnads.vo.msecnd.net.
+es.data.toolbar.yahoo.com.
+smtp.ssvecnet.com.
+170.152.62.186.in-addr.arpa.
+a6.sphotos.ak.fbcdn.net.
+tallerdearquitectura.com.mx.
+dnl-00.geo.kaspersky.com.
+i52.tinypic.com.
+88.127.72.190.in-addr.arpa.
+ads2.msads.net.
+init.ess.apple.com.
+bs.serving-sys.com.
+static.ak.fbcdn.net.
+mail2hot.com.
+tracelabs.com.
+185.51.213.201.in-addr.arpa.
+npipb.com.s8b2.psmtp.com.
+50.29.102.201.in-addr.arpa.
+248.206.122.190.in-addr.arpa.
+fbcdn-profile-a.akamaihd.net.
+news.google.com.mx.
+gdgt.com.
+ville-antony.fr.
+www.sat.gob.mx.
+time.chttl.com.tw.
+37.111.56.87.in-addr.arpa.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+sophiedahl.com.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+www.xhamster.com.
+154.215.120.203.in-addr.arpa.
+google.com.mx.
+wwerrsdf.blogspot.com.
+wooster.bur.ru.
+ajax.googleapis.com.
+creative.ak.fbcdn.net.
+a-tuin.t72.ru.
+www.austinwholesaledecking.com.
+photos-h.ak.fbcdn.net.
+80.61.147.79.in-addr.arpa.
+excessivesweatingtreatmentsite.com.
+365holiday.net.
+yudo-ch.com.
+a.root-servers.net.
+234.45.5.149.in-addr.arpa.
+www.facebook.com.
+a8.sphotos.ak.fbcdn.net.
+iabw:p6c6.y77u7t2n.
+voipb.sip.yahoo.com.
+www.peseatodo.com.ar.
+cbsradioguide.files.wordpress.com.
+ocsp.godaddy.com.
+www.weather.com.
+60.112.38.115.in-addr.arpa.
+roger.s.com.
+triumphstaffing.com.s5a2.psmtp.com.
+online.cartus.com.
+sd-cf.softonic.com.
+sn1sifs30001.unilever.com.
+citron.ru.
+plusone.google.com.
+tc.v17.cache3.c.youtube.com.
+barracuda.geneva.edu.
+by2msg3010506.gateway.messenger.live.com.
+photos-g.ak.fbcdn.net.
+nm28-vm1.bullet.mail.sp2.yahoo.com.
+_318_87_8.
+dns.msftncsi.com.
+translate.google.com.mx.
+104.182.200.189.in-addr.arpa.
+y5h7hfih1.98gu.
+dr._dns-sd._udp.lan.
+impaxlabs.com.
+a5.sphotos.ak.fbcdn.net.
+117.0.170.201.in-addr.arpa.
+media.singsnap.com.
+intaugol.portal.ru.
+support.google.com.
+c.admob.com.
+www.muslmh.com.
+external.ak.fbcdn.net.
+81.103.193.190.in-addr.arpa.
+119.154.128.189.in-addr.arpa.
+photos-g.ak.fbcdn.net.
+a.root-servers.net.
+www.carversation.com.
+239.94.72.82.in-addr.arpa.
+safebrowsing.clients.google.com.
+113.125.158.82.in-addr.arpa.
+profile.ak.fbcdn.net.
+a4.sphotos.ak.fbcdn.net.
+api.nanigans.com.
+83.229.248.189.in-addr.arpa.
+_vlmcs._tcp.
+a8.sphotos.ak.fbcdn.net.
+www.madera.gob.mx.
+google.com.
+titanium30-en.url.trendmicro.com.
+calculadora-cientifica.blogspot.com.
+mail2.easternandoriental.com.
+otonews.com.
+a7.sphotos.ak.fbcdn.net.
+m2.nsimg.net.
+www.last.fm.
+r.mzstatic.com.
+www.bustyivysnow.com.
+155.154.105.85.in-addr.arpa.
+a.root-servers.net.
+a.root-servers.net.
+48.121.251.190.in-addr.arpa.
+ubas.ru.
+profile.ak.fbcdn.net.
+qbgmtqv7k.98zd.
+imetstuart.com.
+81.150.110.87.in-addr.arpa.
+203.85.146.189.in-addr.arpa.
+www.amle.org.
+photos-a.ak.fbcdn.net.
+usd368.k12.ks.us.
+i1.ytimg.com.
+167.174.173.218.in-addr.arpa.
+a.root-servers.net.
+24.39.111.198.in-addr.arpa.
+rad.msn.com.
+235.154.242.82.in-addr.arpa.
+dasfasdf.com.
+a.root-servers.net.
+c-0.19-220f9041.6010081.1518.19d4.3ea1.210.0.ar12mm2qe8znm1u6b3vqqwfhi6.avqs.mcafee.com.
+img546.imageshack.us.
+cm.ac3.msn.com.
+plusone.google.com.
+profile.ak.fbcdn.net.
+pagead2.googlesyndication.com.
+webcache.googleusercontent.com.
+mail.austasia.net.
+photos-b.ak.fbcdn.net.
+d2060227.instant.xoom.it.
+s0.2mdn.net.
+217.92.192.88.in-addr.arpa.
+www.yiyi.cc.
+plusone.google.com.
+facebook.com.
+www.facebook.com.
+mpcstatic.com.
+dns.msftncsi.com.
+244.3.0.192.in-addr.arpa.
+sds.nus.ventura.xbox.com.
+barranquilla.vive.in.
+www.google.com.
+gplus.to.
+www.trailersdecine.com.
+a.root-servers.net.
+163.20.224.85.in-addr.arpa.
+a3.sphotos.ak.fbcdn.net.
+xtina-forum.com.
+d.foxadd.com.
+safebrowsing.clients.google.com.
+766.talkgadget.google.com.
+3.bp.blogspot.com.
+www.gtldna.com.
+media.secret.shooshtime.com.
+198.27.253.201.in-addr.arpa.
+photos-h.ak.fbcdn.net.
+startsear.ch.
+inbound.jessicasoutlet.com.netsolmail.net.
+static.ak.fbcdn.net.
+www.googleadservices.com.
+a1005.w42.akamai.net.
+penxl.ru.
+tr.wikipedia.org.
+a2.sphotos.ak.fbcdn.net.
+3.121.121.192.in-addr.arpa.
+a.root-servers.net.
+www.codinginstinct.com.
+googleads.g.doubleclick.net.
+249.63.72.89.in-addr.arpa.
+col.stc.s-msn.com.
+engr.sgi.com.
+221.142.39.190.in-addr.arpa.
+handicapping.bloodhorse.com.
+a.root-servers.net.
+bersoaexpres.blogspot.com.
+soccergoals.com.
+www.facebook.com.
+a.root-servers.net.
+202.22.168.192.in-addr.arpa.
+webmail.conformis.com.
+secure.shared.live.com.
+mail2.ibmc.up.pt.
+cifraclub.terra.com.
+radio1.todostreaming.es.
+meronisrl.it.
+update.epyte.com.
+www.facebook.com.
+blog.wiggle.co.uk.
+pagead2.googlesyndication.com.
+sup.live.com.
+a.root-servers.net.
+h.live.com.
+27.60.124.190.in-addr.arpa.
+pixel.quantserve.com.
+xmails.org.
+40.114.167.189.in-addr.arpa.
+171.250.183.98.in-addr.arpa.
+106.214.94.98.in-addr.arpa.
+i1.ytimg.com.
+231.162.27.190.in-addr.arpa.
+sonefex.com.
+external.ak.fbcdn.net.
+scotiarewards.scotiabank.com.
+246.102.218.90.in-addr.arpa.
+download.windowsupdate.com.
+www.rsanow.com.au.
+jkl123.com.
+a.root-servers.net.
+www.google-analytics.com.
+www.facebook.com.
+www.voayeurs.com.
+sp.mx.ask.com.
+www.pablogeo.com.
+ad.yieldmanager.com.
+75.82.81.71.in-addr.arpa.
+platform.ak.fbcdn.net.
+a2.sphotos.ak.fbcdn.net.
+www.fiordland.org.nz.
+a7.sphotos.ak.fbcdn.net.
+rcp.eu.blackberry.com.
+yeglive.ca.
+www.momhairypussy.com.
+a.root-servers.net.
+static.ak.fbcdn.net.
+safebrowsing.clients.google.com.
+google.com.
+140.122.105.46.zz.countries.nerd.dk.
+edge.youtube-mp3.org.
+mail01.travelexamericas.com.
+71.98.49.190.in-addr.arpa.
+producciondelibros.blogspot.com.
+photos-d.ak.fbcdn.net.
+master7.teamviewer.com.
+mail1.sfisolutions.com.
+fpdownload.adobe.com.
+zulu.tweetmeme.com.
+santiago.boardwalk-internet.com.
+1.0.0.127.dnsbugtest.1.0.0.127.in-addr.arpa.
+safebrowsing-cache.google.com.
+113.244.112.200.in-addr.arpa.
+.
+www.tienda-regalos-bautizo.com.
+cs11233.vk.com.
+educacion-virtualidad.blogspot.com.
+debryanskaya.ru.
+30.28.32.186.in-addr.arpa.
+cdn.dzone.com.
+www.google.com.
+a.root-servers.net.
+ocsp.digicert.com.
+86.160.144.189.in-addr.arpa.
+35.173.130.190.in-addr.arpa.
+a.root-servers.net.
+feeds.randyblue.com.
+www.3hhd.com.
+hmr.ms00.net.
+profile.ak.fbcdn.net.
+platform.ak.fbcdn.net.
+es-es.facebook.com.
+pixel.facebook.com.
+t2.gstatic.com.
+es-es.fxfeeds.mozilla.com.
+abpp01.albertapermitpro.com.
+convista.com.
+sac.gti.mcafee.com.
+ok.ru.
+191.248.168.192.in-addr.arpa.
+uniqlo.edgesuite.net.
+www.cuantamierda.com.
+s7.addthis.com.
+54.51.1.46.in-addr.arpa.
+youtu.be.
+_892_16_9.
+evenx.ru.
+236.146.151.190.in-addr.arpa.
+mail-s13.1gb.ru.
+ocsp.digicert.com.
+_682_27_1.
+go.purenetworks.com.
+rt.legolas-media.com.
+weekly.chosun.com.
+jameique.com.
+dl.pinyin.sogou.com.
+clients2.google.com.
+221.156.145.72.in-addr.arpa.
+niiide.com.
+loc7.eu1.badoo.com.
+photos-f.ak.fbcdn.net.
+44-courier.push.apple.com.
+mail.mavara.com.
+dns.msftncsi.com.
+cfs-p3.l3.fbcdn.net.
+2il3o8527.59tq.
+250.74.108.38.in-addr.arpa.
+medfordwomensclinic.com.
+christianwach.blogspot.com.
+c.msn.com.
+www.youtube.com.
+www.dosmildiez.net.
+www.fristam.de.
+s.youtube.com.
+www.plan-uk.org.
+fhstzigtc.55og.
+photos-g.ak.fbcdn.net.
+www.elbuscapersonas.com.pe.
+www.drjeffadams.com.
+pt-br.facebook.com.
+windowslive.com.
+cdn.vidigital.ru.
+www.youtube.com.
+main.exoclick.com.
+.
+fashionleague-uk.blogspot.com.
+profile.ak.fbcdn.net.
+creative.ak.fbcdn.net.
+223.224.83.189.in-addr.arpa.
+creative.ak.fbcdn.net.
+216.7.19.187.in-addr.arpa.
+106.119.204.187.in-addr.arpa.
+r._dns-sd._udp.lan.
+ponchtomellh.nu.
+www.santanderempresarial.com.br.
+www.badoo.com.
+www.youtube.com.
+feeds.feedburner.com.
+dealers.autotrader.com.
+twitter.com.
+listado.mercadolibre.com.ar.
+t.co.
+uralan.ru.
+a.root-servers.net.
+www.facebook.com.
+photos-c.ak.fbcdn.net.
+w.sharethis.com.
+citu.info.
+122.173.31.88.in-addr.arpa.
+social.bidsystem.com.
+sharethis.com.
+130.27.242.201.in-addr.arpa.
+esemomentoesacancion.blogspot.com.
+45.6.106.84.in-addr.arpa.
+xads.zedo.com.
+mail.new.flexmail.ifxnetworks.com.
+www.facebook.com.
+photos-f.ak.fbcdn.net.
+a3.sphotos.ak.fbcdn.net.
+ssl.gstatic.com.
+apps.facebook.com.
+gwia1.eht.k12.nj.us.
+torrent.ibiblio.org.
+apis.google.com.
+244d9103.yyv.co.
+sea-latino.com.
+116.39.64.98.in-addr.arpa.
+nctinc.com.
+el.justin.tv.
+106.227.117.200.in-addr.arpa.
+dir.xiph.org.
+sn1msg3020109.gateway.messenger.live.com.
+us.mcafee.com.
+www.renuevodeplenitud.com.
+ads.trafficjunky.net.
+clients1.google.com.
+d1ros97qkrwjf5.cloudfront.net.
+www.google.com.
+cdn.siteanalytics.evolvemediametrics.com.
+www.facebook.com.
+apis.google.com.
+r-data.adsrvr.org.
+_631_30_5.
+105.164.164.187.in-addr.arpa.
+y97fysd1y.68qn.
+a926.da1.akamai.net.
+ar.wikipedia.org.
+api.twitter.com.
+www.youtube.com.
+dothehudson.net.
+shnotify.acer.com.tw.
+uphoto.doulike.com.
+www.net-tec-ag.de.
+210.31.225.189.in-addr.arpa.
+a.root-servers.net.
+google.com.
+fs476.uploading.com.
+4.map.pop6.com.
+supplementwarehouse.com.
+mx1.mailcleaner.pro.
+apps.facebook.com.
+0.pool.ntp.org.
+www.eliphone5.com.
+www.segundamano.com.mx.
+201.109.117.200.in-addr.arpa.
+www.expendablespremiere.com.
+_166_57_6.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+mscrl.microsoft.com.
+vgn-xpromo.vostu.com.
+240.137.167.190.in-addr.arpa.
+www.petroleo-mexico.com.
+aurelinlul.fitepyciness.pw.
+onlinehelp.microsoft.com.
+a.root-servers.net.
+cuda4002.acc.org.
+www.google.com.
+s-static.ak.facebook.com.
+www.stopbadware.org.
+googleads.g.doubleclick.net.
+56.15.156.187.in-addr.arpa.
+a.root-servers.net.
+r._dns-sd._udp.0.2.168.192.in-addr.arpa.
+mt.livecamfun.com.
+41.249.193.186.in-addr.arpa.
+mailserver3.escatec.com.
+igor.facemoods.com.
+krona.obninsk.ru.
+littlehousedenoel.blogspot.com.
+urls.co.za.
+bloghelp.exblog.jp.
+s.aeriastatic.com.
+65.215.36.69.in-addr.arpa.
+a.root-servers.net.
+www.google.com.
+safebrowsing-cache.google.com.
+benihana.com.
+denmangroup.com.
+www.google.com.
+secure.wlxrs.com.
+www.youtube.com.
+sophtech.com.
+www.hixatselfridges.co.uk.
+www.mochiads.com.
+137.41.87.201.in-addr.arpa.
+12.217.58.71.in-addr.arpa.
+ttns.com.
+14.167.146.213.in-addr.arpa.
+elteatrito.com.
+a.root-servers.net.
+mail.pastadelcapitano.com.br.
+161.172.137.187.in-addr.arpa.
+www.mulletsighting.com.
+elblogdemariaelena.wordpress.com.
+m.hotmail.com.
+53.40.135.181.in-addr.arpa.
+8b.u.51img1.com.
+xulforge.com.
+_708_57_9.
+integrityhomelending.com.
+fcbarcelonanoticias.com.
+stateplanthire.com.
+anonysupermaguila.esforos.com.
+www.download.windowsupdate.com.
+nihonkiin.or.jp.
+sasvp.callvantage.att.com.
+109.171.161.187.in-addr.arpa.
+137.51.93.186.in-addr.arpa.
+46.92.199.190.in-addr.arpa.
+mail.printlux.com.
+0.11-a30fc081.80210b1.1518.19d2.3ea1.200.0.aziphaksrrcu4c52zmddfs4m4b.avqs.mcafee.com.
+mail01.agcs.allianz.com.ppde.azmx.de.
+static.ak.fbcdn.net.
+prpadi6nh.y98m8g1x.
+157.54.15.116.in-addr.arpa.
+ads2.iforex.com.
+www.gi.co.id.
+164.3.74.187.in-addr.arpa.
+b._dns-sd._udp.0.1.168.192.in-addr.arpa.
+tpb.tracker.thepiratebay.org.
+d3lvr7yuk4uaui.cloudfront.net.
+www.bestbuy.com.mx.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+ksn1-11-part1.kaspersky-labs.com.
+225.123.231.190.in-addr.arpa.
+barkeeper.ie.
+lb._dns-sd._udp.0.2.168.192.in-addr.arpa.
+us.battle.net.
+a.root-servers.net.
+60.57.109.70.in-addr.arpa.
+www.carapantalla.com.
+lb._dns-sd._udp.lan.
+fbcdn-profile-a.akamaihd.net.
+235.41.11.83.in-addr.arpa.
+j-osaka.net.
+www.mecanica-facil.com.
+www.lifebatch.com.
+3.162.30.186.in-addr.arpa.
+lsgip-com.relay1c.spamh.com.
+cdn.hegre-art.com.fpbns.net.
+a3.sphotos.ak.fbcdn.net.
+32.36.148.88.in-addr.arpa.
+dosrv.perry.k12.ms.us.
+www.ygexpert.com.
+49.192.64.195.in-addr.arpa.
+ozestretch.com.
+photos-e.ak.fbcdn.net.
+es.99counters.com.
+23.65.229.220.in-addr.arpa.
+for-my-wedding.com.
+css.wlxrs.com.
+a.root-servers.net.
+static.ak.facebook.com.
+mail.int.ru.
+www.google-analytics.com.
+www.gstatic.com.
+photos-h.ak.fbcdn.net.
+186.123.104.209.in-addr.arpa.
+apple.com.
+126.216.51.190.in-addr.arpa.
+www.youtube.com.
+a3.sphotos.ak.fbcdn.net.
+appspot.l.google.com.
+www.flexcourt.com.
+webassets3.sparkybee.com.
+wxdata.weather.com.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+gdgundem.com.
+thumbnail.api.livestream.com.
+ejabh.m5zn.com.
+connect.facebook.net.
+cxz23.meaningtool.com.
+apple.accuweather.com.
+youtube-global.blogspot.com.
+114.222.107.209.in-addr.arpa.
+thor24.com.s8a1.psmtp.com.
+111.15.238.173.in-addr.arpa.
+profile.ak.fbcdn.net.
+photos-e.ak.fbcdn.net.
+www.juegosjuegos.asia.
+www.adobe.com.
+ipad.screensteps.com.
+api.quizlet.com.
+www.elle.es.
+col.stc.s-msn.com.
+conloscascospuestos.blogspot.es.
+66.21.71.190.in-addr.arpa.
+241.255.239.190.in-addr.arpa.
+contadorweb.net.
+www.jeuxfille.tv.
+teredo.ipv6.microsoft.com.
+250.249.230.190.in-addr.arpa.
+www.myfblikes.info.
+www.tibiawar.org.
+lassuperfotos.com.es.
+mail2a.smtproutes.org.
+connexions-durham.org.
+112.98.41.187.in-addr.arpa.
+dns.msftncsi.com.
+cs4499.vk.com.
+www.culosdetias.com.
+static.ak.fbcdn.net.
+e1310.vuclip.com.
+212.87.156.203.in-addr.arpa.
+ad.yieldmanager.com.
+dk.webcams.travel.
+dns.msftncsi.com.
+picasaweb.google.com.
+sprojects.mmi.mcgill.ca.
+checkip.dyndns.org.
+bit.ly.
+ssl.gstatic.com.
+www.nudelinkdump.com.
+cdn.api.twitter.com.
+nova100.evectors.it.
+mail.google.com.
+fromthepews.org.
+apple.com.
+i-cdn.servedbyopenx.com.
+tv2x2.ru.
+sn1msg2010522.gateway.messenger.live.com.
+acoupleofgurus.com.inbound10.mxlogicmx.net.
+crl.microsoft.com.
+photos-f.ak.fbcdn.net.
+www.facebook.com.
+www.google.com.
+secure.tours4fun.com.
+cm.g.doubleclick.net.
+www.navartur.es.
+a.root-servers.net.
+mx2c26.carrierzone.com.
+apis.google.com.
+th2.iwannajerk.com.
+ib.adnxs.com.
+msc.wlxrs.com.
+www.iesloscardones.es.
+view.atdmt.com.
+cdn0.sexysway.com.
+www.montanasilversmiths.com.
+213.45.171.118.in-addr.arpa.
+www.johnstonpress.co.uk.
+www.estilaestilo.cl.
+38.9.93.200.in-addr.arpa.
+v1es.sftcdn.net.
+webcompay.com.
+es.wikipedia.org.
+www.entretengo.com.
+www.comparaencasa.com.
+176.84.104.186.in-addr.arpa.
+m.facebook.com.
+a.root-servers.net.
+redirector.c.youtube.com.
+pixel.facebook.com.
+mx.youtube.com.
+noble.org.
+www.carhood.com.
+us.rd.yahoo.com.
+www.parafernalha.com.br.
+groups.google.com.mx.
+nsw.austutors.com.au.
+199.194.105.186.in-addr.arpa.
+urs.microsoft.com.
+_086_63_2.
+turneralternatives.com.
+s7.addthis.com.
+a.root-servers.net.
+developers.facebook.com.
+55.214.159.200.in-addr.arpa.
+db._dns-sd._udp.0.1.168.192.in-addr.arpa.
+images.crocotube.com.
+checkip.dyndns.org.
+mexicanainforma.com.
+fbcdn-sphotos-a.akamaihd.net.
+developers.facebook.com.
+www.facebook.com.
+sosrecados.com.
+external.ak.fbcdn.net.
+external.ak.fbcdn.net.
+static.ak.fbcdn.net.
+i2.ytimg.com.
+a2.twimg.com.
+ads1.msads.net.
+johnhcarter.com.s7b1.psmtp.com.
+c-0.19-a3098481.483.1518.19d4.3ea1.410.0.96atjpzlesjf4k3w9ewwebnsl5.avqs.mcafee.com.
+www.teentiger.com.
+www.ig.gmodules.com.
+ssl.gstatic.com.
+photos-a.ak.fbcdn.net.
+external.ak.fbcdn.net.
+ar.finance.yahoo.com.
+www.gstatic.com.
+c.static-cdn.playfish.com.
+97.232.10.181.in-addr.arpa.
+fbcdn-sphotos-a.akamaihd.net.
+l.yimg.com.
+b._dns-sd._udp.belkin.
+220.171.152.79.in-addr.arpa.
+a2.sphotos.ak.fbcdn.net.
+cpssys.com.
+sevastopol.info.
+www.masimasd.blogspot.com.
+photos-g.ak.fbcdn.net.
+cssweat.com.
+prev.explabs.net.
+cwnt.com.
+217.26.108.190.in-addr.arpa.
+bikinibank.com.
+39.126.126.200.in-addr.arpa.
+topoaze.eu.
+sportingnews.checkm8.com.
+static.ak.connect.facebook.com.
+www.wftv.com.
+profile.ak.fbcdn.net.
+www.peyamner.com.
+mail.seec.com.tw.
+www.cnc.org.mx.
+profile.ak.fbcdn.net.
+cybershadow.com.
+groups.live.com.
+a.root-servers.net.
+41.23.8.176.in-addr.arpa.
+114.83.19.67.in-addr.arpa.
+forum.swzone.it.
+a.root-servers.net.
+mxytiqlgllxl.ac.
+xetgs.xboxlive.com.
+pagead2.googlesyndication.com.
+221.36.113.92.in-addr.arpa.
+dvlti.ru.
+ad.z5x.net.
+csi.gstatic.com.
+www.frederico-araujo.com.
+www.adobe.com.
+nullmx.matthew1.com.
+onlinux-it.setupdns.net.
+75.167.56.186.in-addr.arpa.
+nl.softonic.com.
+windowslivelatam.com.
+dns.msftncsi.com.
+mountainss.wordpress.com.
+95.181.11.88.in-addr.arpa.
+ksn1-11-part2.kaspersky-labs.com.
+eqekld.com.
+www.betweenthelines.net.au.
+mk3047.spb.edu.
+65.12.221.189.in-addr.arpa.
+external.ak.fbcdn.net.
+time.chttl.com.tw.
+_490_63_5.
+b.imwx.com.
+222.199.172.78.in-addr.arpa.
+237.73.167.190.in-addr.arpa.
+riyadhciti.com.
+1.134.113.186.in-addr.arpa.
+connect.facebook.net.
+a.root-servers.net.
+www.durometrosymicrodurometros.com.
+newsrss.bbc.co.uk.
+34.211.36.186.in-addr.arpa.
+sp.cwfservice.net.
+dns.msftncsi.com.
+clampfansub.foroes.net.
+77.82.187.93.in-addr.arpa.
+11.87.190.71.in-addr.arpa.
+134.149.83.200.in-addr.arpa.
+adsx.greystripe.com.
+www.psychiatry.ox.ac.uk.
+rad.msn.com.
+bs.eyeblaster.akadns.net.
+www.usdrybeans.com.
+all-hidden-object-games.com.
+a.root-servers.net.
+196.206.65.151.in-addr.arpa.
+.
+littlemayra.blogspot.com.
+234.6.179.190.in-addr.arpa.
+www.textsrv.com.
+www.youtube.com.
+tomkadlec.com.
+a-0.19-210f7001.a0e0131.1518.19d4.3ea1.210.0.gq4f3ru3uzzs8dk17ne1ngnvct.avqs.mcafee.com.
+storage.conduit.com.
+starnetworks.ru.
+photos-d.ak.fbcdn.net.
+a.root-servers.net.
+profile.ak.fbcdn.net.
+a2.sphotos.ak.fbcdn.net.
+dominformer.ru.
+a7.sphotos.ak.fbcdn.net.
+sc19.rules.mailshell.net.
+i4.ytimg.com.
+a.rad.msn.com.
+lb._dns-sd._udp.0.129.37.10.in-addr.arpa.
+2.197.253.201.in-addr.arpa.
+a0.twimg.com.
+120.44.37.190.in-addr.arpa.
+200.99.51.190.in-addr.arpa.
+156.101.138.187.in-addr.arpa.
+177.87.232.189.in-addr.arpa.
+tour.twistys.com.
+blufiles.storage.msn.com.
+static.ak.fbcdn.net.
+ak-media.soundcloud.com.
+static.app.widdit.com.
+teredo.ipv6.microsoft.com.
+www.dulcedecoracion.es.
+a-0.19-220f3081.9120081.1518.19d4.3ea0.200.0.btenq4pn4ldvwt3855u2t1jdnt.avqs.mcafee.com.
+106.254.238.201.in-addr.arpa.
+pres.us.mydlink.com.
+www.innovar.gov.ar.
+nsx.np.dl.playstation.net.
+a3.sphotos.ak.fbcdn.net.
+img100.xvideos.com.
+www.adobe.com.
+smtp.cimcast.net.
+www.dsri.dk.
+www.google.com.
+secure.shared.live.com.
+a5.sphotos.ak.fbcdn.net.
+anaggh.com.
+www.redphotophotography.com.
+136.200.89.87.in-addr.arpa.
+www.masmitja.net.
+images.digby.com.
+45.92.217.188.in-addr.arpa.
+twitter.com.
+photos-a.ak.fbcdn.net.
+a8.sphotos.ak.fbcdn.net.
+aaasea.org.
+velvac.com.inbound10.mxlogicmx.net.
+a.root-servers.net.
+www.opensong.org.
+developers.facebook.com.
+www.nitrohouse.com.
+check4.facebook.com.
+246.138.120.186.in-addr.arpa.
+www.releasedon.com.
+static.ak.fbcdn.net.
+a1725.l.akamai.net.
+mai.in.th.
+104.47.52.186.in-addr.arpa.
+matscanbaraney.museum.
+128.31.107.186.in-addr.arpa.
+214.39.254.201.in-addr.arpa.
+tc4.easythumbhost.com.
+246.198.239.85.in-addr.arpa.
+google.com.
+platform.ak.fbcdn.net.
+a.root-servers.net.
+comconcrp.com.
+www.gph.gov.sa.
+53.69.23.76.in-addr.arpa.
+vax.co.uk.
+a6.sphotos.ak.fbcdn.net.
+maerchen.woxikon.de.
+a3.sphotos.ak.fbcdn.net.
+www.facebook.com.
+allfreevectors.com.
+benelli.com.au.
+pfplace.com.
+www.hulkshare.com.
+a.root-servers.net.
+76.240.78.187.in-addr.arpa.
+apple.com.
+comentarios.esmas.com.
+230.89.88.200.in-addr.arpa.
+56.12.27.77.in-addr.arpa.
+img69.imageshack.us.
+_411_83_3.
+wk-diecast.blogspot.com.
+140.82.224.189.in-addr.arpa.
+img.tongji.linezing.com.
+s1.img.awempire.com.
+a.root-servers.net.
+mail.peakinsight.com.
+bolsaibex.com.
+www.younghegan.com.
+www.dahousecat.net.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+161.221.165.69.in-addr.arpa.
+clinedavis.com.
+api.twitter.com.
+a.root-servers.net.
+mail2.graymont.com.
+img.adverticum.net.
+33.66.179.190.in-addr.arpa.
+mx.alanet.com.br.
+24.177.176.78.in-addr.arpa.
+b.scorecardresearch.com.
+google.com.
+profile.ak.fbcdn.net.
+228.201.43.200.in-addr.arpa.
+adserving.cpxinteractive.com.
+botsikas.blogspot.com.
+26.media.tumblr.com.
+s1-word-edit.vo.msecnd.net.
+147.159.232.200.in-addr.arpa.
+a7.sphotos.ak.fbcdn.net.
+95.66.56.186.in-addr.arpa.
+22.6.168.192.in-addr.arpa.
+141.142.18.187.in-addr.arpa.
+www.teamopolis.com.
+161.68.232.82.in-addr.arpa.
+nteck.com.
+4sq.com.
+a.root-servers.net.
+mail.percarbonat.ru.
+sc62.engate.com.
+d2100638.xoom.it.
+www.barclays.mobi.
+photos-f.ak.fbcdn.net.
+googleads.g.doubleclick.net.
+mx1.techintgroup.com.
+a.root-servers.net.
+www.myresortnetwork.com.
+rospres.com.
+ib.adnxs.com.
+static.ak.fbcdn.net.
+127.181.176.190.in-addr.arpa.
+eliocel.blogspot.com.
+38.82.153.201.in-addr.arpa.
+pixel.facebook.com.
+www9.effectivemeasure.net.
+a.root-servers.net.
+gtsru.com.
+www.changosmangos.net.
+_403_10_2.
+www.prontorotulo.com.
+226.236.62.95.in-addr.arpa.
+profile.ak.fbcdn.net.
+time.apple.com.
+a-0.19-2109e071.d0b0083.1518.19d4.3ea1.410.0.a8vnw6m6j8wv1hhrhb4gd6awlq.avqs.mcafee.com.
+mail.hhqc.com.
+pixel.quantserve.com.
+platform.twitter.com.
+yahoo.com.
+alicante.cochesdeocasion.com.
+www.facebook.com.
+74.12.45.86.in-addr.arpa.
+a.root-servers.net.
+habboon.com.
+www.abc.es.
+couponbuddy.s3.amazonaws.com.
+id.countrysearch.ec21.com.
+p04-bookmarks.icloud.com.
+google.com.
+apps.facebook.com.
+linux.ca.
+a.root-servers.net.
+70.235.189.184.in-addr.arpa.
+windows.microsoft.com.
+147.245.115.186.in-addr.arpa.
+appsforbb.com.
+creative.ak.fbcdn.net.
+www.sohubook.com.
+www2.netcom.com.
+photos-h.ak.fbcdn.net.
+www.google.com.
+a.root-servers.net.
+fls.doubleclick.net.
+coaching.35webs.com.
+twitter.com.
+rd.meebo.com.
+164.184.26.78.in-addr.arpa.
+www.rangeen.in.
+_213_07_1.
+88.104.88.186.in-addr.arpa.
+szwandu11.w91.516dns.com.
+tap2-cdn.rubiconproject.com.
+bkuxz526k.42wo.
+profile.ak.fbcdn.net.
+profile.ak.fbcdn.net.
+profile.ak.fbcdn.net.
+talk4.1.google.com.
+blyudo.org.ru.
+mvfhr.blogspot.com.
+centos.omnispring.com.
+pointa.autodesk.com.
+1257868.r.msn.com.
+www.guiadeestetica.com.
+51.239.168.192.in-addr.arpa.
+www.preferredhealthgroup.com.
+45.154.96.177.in-addr.arpa.
+atomicparsley.sourceforge.net.
+s7.addthis.com.
+kuv3wp1or.85nt.
+www.vjvdiamonds.com.
+static.only18teensex.com.
+www.connect.facebook.com.
+www.yahoo.com.
+www.richvomdorf.com.
+230.108.242.92.in-addr.arpa.
+icarly.co.
+sicurezza.ebay.it.
+s0.2mdn.net.
+ajax.googleapis.com.
+pagead2.googlesyndication.com.
+www.gstatic.com.
+126.9.0.192.in-addr.arpa.
+a6.sphotos.ak.fbcdn.net.
+213.22.95.190.in-addr.arpa.
+71.5.13.201.in-addr.arpa.
+creative.ak.fbcdn.net.
+russellandhazel.com.
+google.com.
+mowmgw02.mow.com.
+tracker.ccc.de.
+www.renegocios.com.
+www.peachygreen.com.
+voipc.sip.yahoo.com.
+6xgate.deviantart.com.
+www.ozu.es.
+a2.sphotos.ak.fbcdn.net.
+northshore-golfclub.com.
+ts.tsnet.ru.
+47j7b263u.j79b4r2u.
+www.policia.gov.co.
+a.root-servers.net.
+www.google.com.
+5h92qfb31.32kl.
+ltasconfig.ltassrv.com.
+www.facebook.com.
+www.effect.com.ve.
+www.nattoli.net.
+dfaasd.com.
+16.234.25.189.in-addr.arpa.
+a3.sphotos.ak.fbcdn.net.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+b.scorecardresearch.com.
+126.0.20.212.in-addr.arpa.
+www.alawar.ru.
+www.switchplane.com.
+external.ak.fbcdn.net.
+11.105.247.189.in-addr.arpa.
+www.conduit.com.
+profile.ak.fbcdn.net.
+qiran.com.
+clients1.google.com.
+fxfeeds.mozilla.com.
+i4ucity.com.
+googleads.g.doubleclick.net.
+creative.ak.fbcdn.net.
+202.164.44.91.in-addr.arpa.
+vast.bp3846813.btrll.com.
+lhkha2sqv.m06m4m8c.
+external.ak.fbcdn.net.
+nt3.ggpht.com.
+profile.ak.fbcdn.net.
+www.dogpile.co.uk.
+profile.ak.fbcdn.net.
+134.143.86.186.in-addr.arpa.
+www.10stiri.ro.
+blog.mon-anniversaire.com.
+www.google-analytics.com.
+zynga2-a.akamaihd.net.
+missyfeelingaddicted.blogspot.com.
+mail.st-tula.ru.
+rs983l33.rapidshare.com.
+40-courier.push.apple.com.
+developers.facebook.com.
+smtp4.ocps.net.
+231.192.32.114.in-addr.arpa.
+pixel.facebook.com.
+110.237.211.201.in-addr.arpa.
+169.90.173.190.in-addr.arpa.
+es.babelfish.yahoo.com.
+db._dns-sd._udp.0.1.168.192.in-addr.arpa.
+rcp.na.blackberry.com.
+bcvideos.wwe.com.
+cdn-0.pics.hardsextubepremium.com.
+teredo.ipv6.microsoft.com.
+www.google.com.
+_280_38_3.
+152.10.90.208.in-addr.arpa.
+www.youtube.com.
+101.107.181.80.in-addr.arpa.
+smtp.divex.se.
+.
+jers3.info.
+photos-f.ak.fbcdn.net.
+vglgmtj.com.
+pixel.facebook.com.
+nvc.net.
+a8.sphotos.ak.fbcdn.net.
+58.189.15.216.zen.spamhaus.org.
+182.93.168.192.in-addr.arpa.
+a.ads2.msads.net.
+googleads.g.doubleclick.net.
+57.26.157.157.in-addr.arpa.
+250.45.228.91.in-addr.arpa.
+home.shop.ebay.com.
+fundacioncth.org.
+ratings-wrs.symantec.com.
+creative.ak.fbcdn.net.
+www.shantui-xcmg.ru.
+ibm-consultant.jobs.
+tts.hcs.k12.al.us.
+billing.sharo4ka.ru.
+p23.easybitsgo.net.
+www.dvdstore.com.
+172.154.102.189.in-addr.arpa.
+www.allteentits.com.
+mail2chile.com.
+pagead2.googlesyndication.com.
+0.
+9.65.57.187.in-addr.arpa.
+a-0.19-2309a081.d060083.1518.19b3.3ea1.210.0.spqabajtl54hfqk97s33alujnv.avqs.mcafee.com.
+www.bitefight.es.
+cdn.wibiya.com.
+ssl.gstatic.com.
+vthumb.ak.fbcdn.net.
+www.siteadvisor.com.
+4.bp.blogspot.com.
+zpzp2bd5d.84fm.
+csi.gstatic.com.
+www.microsoft.com.
+ubds.uniblue.com.
+photos-c.ak.fbcdn.net.
+ymail.com.
+mail.gmail.com.
+www.doc.mx.
+static.bergfex.at.
+www.crushingonclothes.com.
+m.wetter.net.
+www.slideshare.net.
+push.tagged.com.
+www.maxicon.com.
+173.151.22.190.in-addr.arpa.
+e7f964eb.rqq.co.
+plus.google.com.
+mail1.subrogation.net.
+photos-f.ak.fbcdn.net.
+a28.g.akamai.net.
+washingtondc.backpage.com.
+109.36.218.180.in-addr.arpa.
+183.119.56.187.in-addr.arpa.
+edge.quantserve.com.
+a.root-servers.net.
+hotmail.com.
+65.67.36.46.in-addr.arpa.
+227.253.174.189.in-addr.arpa.
+assets.tp-cdn.com.
+www.lanueva.com.
+137.158.45.70.in-addr.arpa.
+teredo.ipv6.microsoft.com.
+blomasa.com.
+254.65.91.186.in-addr.arpa.
+resolver1.wguard.ctmail.com.
+ib.adnxs.com.
+rhrun.com.
+pix.fileratings.com.
+www.unydos.com.
+www.facebook.com.
+65.54.51.190.in-addr.arpa.
+irc.purchaseservice.com.
+fun.zynga.com.
+fbcdn-photos-a.akamaihd.net.
+northstar-service.com.
+tap.rubiconproject.com.
+tunnel.cfw.trustedsource.org.
+www.telalinks.com.
+marinerscovebayclub.org.
+24.42.76.189.in-addr.arpa.
+ohu32l2uu.l79o9n0a.
+www.americanyogaassociation.org.
+spamfilter.vpdinc.com.
+g12254.chrome.funnygames.org.
+219.73.43.114.in-addr.arpa.
+code.google.com.
+a.root-servers.net.
+216.107.66.75.in-addr.arpa.
+voipb.sip.yahoo.com.
+221.20.7.190.in-addr.arpa.
+www.youtube.com.
+www.fammed.ouhsc.edu.
+lukar.ru.
+lovewellmtn.com.
+mail.bazzillbasics.com.
+eser.cl.
+um16.eset.com.
+cloudav.updates.pandasecurity.com.
+photos-f.ak.fbcdn.net.
+mercuryapps.foxnews.com.
+_140_66_9.
+es.wikipedia.org.
+www.filestube.me.
+sisbib.unmsm.edu.pe.
+a4.sphotos.ak.fbcdn.net.
+a.root-servers.net.
+www.3dtoontube.com.
+a.root-servers.net.
+photos-f.ak.fbcdn.net.
+rapidssl-crl.geotrust.com.
+a.root-servers.net.
+sp.cwfservice.net.
+fbcdn-photos-a.akamaihd.net.
+sandaraparkfashion.wordpress.com.
+a6.sphotos.ak.fbcdn.net.
+97.211.59.186.in-addr.arpa.
+www.youtube.com.
+ad.doubleclick.net.
+www.google.com.
+dns.msftncsi.com.
+jehzlau-concepts.com.
+ex.starwebnet.com.
+wirtschaftsschaufenster.augsburger-allgemeine.de.
+i.ytimg.com.
+rad.msn.com.
+_451_59_4.
+www.greenmanreview.com.
+201.102.172.81.in-addr.arpa.
+peseta.org.
+dns.msftncsi.com.
+tta.angel.googlepages.com.
+fpinsurance.com.s5b1.psmtp.com.
+photos-f.ak.fbcdn.net.
+denkermuscarello.com.pri-mx.na0100.smtproutes.com.
+itunes.apple.com.
+a.root-servers.net.
+utorak007.spreadshirt.net.
+api.facebook.com.
+orthoklahoma.com.
+118.244.78.186.in-addr.arpa.
+www.dlink-me.com.
+0.gravatar.com.
+tsi.com.
+67.1.144.187.in-addr.arpa.
+mail.webuzmani.net.
+time.chttl.com.tw.
+rusgai.ru.
+r._dns-sd._udp.0.79.168.192.in-addr.arpa.
+179.99.146.187.in-addr.arpa.
+www.roadsters.com.
+212.5.42.113.in-addr.arpa.
+20.224.171.69.in-addr.arpa.
+barracuda.networkpartners.com.
+static.ak.fbcdn.net.
+www.peliculasconpalomitas.com.
+vsal.ru.
+nccray.com.
+psrbb.com.s10b1.psmtp.com.
+a6.sphotos.ak.fbcdn.net.
+119.112.141.201.in-addr.arpa.
+c-0.19-a30fa081.8110000.1518.19d4.3ea1.410.0.e4w56fs4drhcime9zrg33i8qfv.avqs.mcafee.com.
+tagmanezt.terra.com.
+nenacho.blogspot.com.
+edgeyoke.com.
+pixel.facebook.com.
+135.141.24.189.in-addr.arpa.
+safe-mail.net.
+ocsp.godaddy.com.
+beta.hustlerstaboo.com.
+profile.ak.fbcdn.net.
+ns45.domaincontrol.com.
+190.29.126.77.in-addr.arpa.
+lcbcmail.com.
+dhs.state.tx.us.
+craneveyor.com.s7a2.psmtp.com.
+deltavalves.com.
+www.sqm.microsoft.com.
+profile.ak.fbcdn.net.
+ispro.de.
+api-read.facebook.com.
+adsfront.iminent.com.
+www.gstatic.com.
+a7.sphotos.ak.fbcdn.net.
+ctnzlauwgtgpryqp.net.
+ksn1-11-part1.kaspersky-labs.com.
+tubes.wamcash.com.
+www.thisislondon.co.uk.
+a.root-servers.net.
+a.root-servers.net.
+photos-b.ak.fbcdn.net.
+www.activica.com.
+a.root-servers.net.
+twitter.com.
+tap2-cdn.rubiconproject.com.
+mail.google.com.
+143.124.222.189.in-addr.arpa.
+www.addthis.com.
+www.addthis.com.
+80.226.34.187.in-addr.arpa.
+pt-br.facebook.com.
+watson.microsoft.com.
+api.bing.net.
+mail.goodnessgreeness.com.
+yahoo.c.uk.lan.
+ggstat.flashget.com.
+es-la.facebook.com.
+s-static.ak.facebook.com.
+api.twitter.com.
+mscan.hortresearch.co.nz.
+www.emailmeform.com.
+dsd-www.nuts.co.uk.edgesuite.net.
+graph.facebook.com.
+0.gravatar.com.
+a.root-servers.net.
+142.12.185.201.in-addr.arpa.
+itunes.apple.com.
+backup35.url.trendmicro.com.
+itunes.apple.com.
+clients1.google.com.
+236.173.22.190.in-addr.arpa.
+galtime27.disqus.com.
+safebrowsing-cache.google.com.
+57.214.217.87.in-addr.arpa.
+225.8.175.187.in-addr.arpa.
+98.249.185.86.in-addr.arpa.
+www.kitco.com.
+urs.microsoft.com.
+cwine.com.
+safedrivingacademy.net.
+askville.amazon.com.
+pixel.quantserve.com.
+altfarm.mediaplex.com.
+51.117.111.87.in-addr.arpa.
+torem.ru.
+rct.ru.
+62.16.46.50.in-addr.arpa.
+mail.krata.ru.
+s.youtube.com.
+tools.google.com.
+huzzah.edublogs.org.
+global.cyworld.com.
+melco.com.
+feeds.bbci.co.uk.
+ms.aidc.com.tw.
+d15gt9gwxw5wu0.cloudfront.net.
+forums2.battleon.com.
+a1.sphotos.ak.fbcdn.net.
+mail.ideaspublishinggroup.com.
+26.120.112.190.in-addr.arpa.
+www.surveymonkey.com.
+188.187.93.173.in-addr.arpa.
+inglesperu.blogspot.com.
+a6.sphotos.ak.fbcdn.net.
+s.ytimg.com.
+beachcroft.co.uk.
+m.facebook.com.
+_123_71_9.
+a3.sphotos.ak.fbcdn.net.
+bloc.filantprim.com.
+www.putumayo-home.com.
+external.ak.fbcdn.net.
+weltonstreet.com.s10b2.psmtp.com.
+www.xat.org.
+teredo.ipv6.microsoft.com.
+a3dauto.com.
+99yahoo.com.
+www.facebook.com.
+152.222.247.189.in-addr.arpa.
+api-read.facebook.com.
+wmxzrgc4p.75ry.
+utmtrk9.apn.ask.com.
+checkip.dyndns.org.
+b._dns-sd._udp.0.1.168.192.in-addr.arpa.
+tp.socialvi.be.
+a85.phobos.apple.com.
+adframes.iminent.com.
+dt.tongji.linezing.com.
+blogis.in.
+banking.shinhan.com.
+l2.dmggroup.com.
+forums.theplanet.com.
+a8.sphotos.ak.fbcdn.net.
+sipc.org.rbl2.mcafee.com.
+static.ak.fbcdn.net.
+_391_24_4.
+61.178.210.186.in-addr.arpa.
+168.7.168.192.in-addr.arpa.
+bs.serving-sys.com.
+photos-e.ak.fbcdn.net.
+umcom.org.
+developers.facebook.com.
+tnn.ru.
+berega.net.
+mx02.vtb24.ru.
+db._dns-sd._udp.lan.
+karev.org.il.
+63.6d736e.636f6d.80h40041527.webcfs02.com.
+verizon.net.
+a6.sphotos.ak.fbcdn.net.
+245.64.161.190.in-addr.arpa.
+ny.goldenbridgeyoga.com.
+www.thehostmovienews.com.
+v7k5:a2rg.s27r4t9p.
+mx.masonattorneys.com.
+www8.babblar.org.
+a6.sphotos.ak.fbcdn.net.
+s-r.ru.
+234.92.169.189.in-addr.arpa.
+platform.twitter.com.
+picasaweb.google.com.
+73.215.248.74.in-addr.arpa.
+www.facebook.com.
+bkkok.com.
+www.google.com.
+js2.wlxrs.com.
+100.123.110.186.in-addr.arpa.
+sup.live.com.
+photos-h.ak.fbcdn.net.
+176.138.226.189.in-addr.arpa.
+www.meinsurancereview.com.
+www.americanplacetheatre.org.
+www.facebook.com.
+ssl.gstatic.com.
+paceproperties.com.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+www.w3api.com.
+ad.adnetwork.net.
+a6.sphotos.ak.fbcdn.net.
+itworld.simplyhired.com.
+l08.member.sp1.yahoo.com.
+136.89.229.189.in-addr.arpa.
+ad-g.doubleclick.net.
+chrisbblihy.mywibes.com.
+image2.pubmatic.com.
+www.linkbucks.com.
+hi-in.facebook.com.
+cdo.wikipedia.org.
+writetodone.com.
+test-rt.liftdna.com.
+filnaturalista.blogspot.com.
+p07-bookmarks.icloud.com.
+estaticos.diariodemallorca.es.
+www.futureelectronics.com.
+97.40.135.190.in-addr.arpa.
+motor.net.au.
+acegolfcars.com.
+fashionvibe-blog.blogspot.com.
+creative.ak.fbcdn.net.
+87.35.240.201.in-addr.arpa.
+www.diffuse-cpm.com.
+pek-nn.ru.
+profile.ak.fbcdn.net.
+www.download.windowsupdate.com.
+volga.customs.ru.
+sawall.de.
+www.movie1820.com.
+squarise.com.
+icon.daumcdn.net.
+a.root-servers.net.
+mbacm.com.
+a.root-servers.net.
+www.youtube-nocookie.com.
+castlocations.com.
+www.gratispeliculas.org.
+lh6.ggpht.com.
+piterspy.ru.
+creative.ak.fbcdn.net.
+hantech.com.
+rcp.na.blackberry.com.
+www.isg-apple.com.akadns.net.
+api-read.facebook.com.
+244.151.108.95.in-addr.arpa.
+video.google.com.
+220.193.122.84.in-addr.arpa.
+sync.search.spotxchange.com.
+www.adobe.com.
+profile.live.com.
+sn3.mailshell.net.
+www.deportemundial.net.
+fc07.deviantart.net.
+sneak.co.nz.
+bid.openx.net.
+s.amazon-adsystem.com.
+www.amyscott.com.
+www.unicef.org.
+16.133.25.210.in-addr.arpa.
+0-jh-w.channel.facebook.com.
+www.foxsportsla.com.
+bleached-to-the-bone-scene-3.ss.thirdmovies.com.
+cdn-a1.dvipcdn.com.
+partner.googleadservices.com.
+a.root-servers.net.
+mums.cl.
+99.139.172.189.in-addr.arpa.
+localhost.
+catgirlkawaii.deviantart.com.
+googlemail.l.google.com.
+hotmait.com.
+render.talk4free.com.
+61.208.179.189.in-addr.arpa.
+www.sanitaryum.com.
+119.228.51.190.in-addr.arpa.
+oxydo.ru.
+espn.co.
+iteccolorado.com.
+web360.com.
+a.root-servers.net.
+www.playflv.com.
+kfmg9lgzm.93kx.
+18.116.8.60.in-addr.arpa.
+dh.api.apptao.com.
+redffmaill.com.
+a.root-servers.net.
+toolbar.google.com.
+176.247.160.201.in-addr.arpa.
+topcharts.ru.
+xml.opera.com.
+photos-g.ak.fbcdn.net.
+googleads.g.doubleclick.net.
+kft8nx7q:.57eg.
+billing.sharo4ka.ru.
+www.itknowledge24.com.
+139.203.41.200.in-addr.arpa.
+photos9.flickr.com.
+77867bf.net.
+profile.ak.fbcdn.net.
+126.96.48.60.in-addr.arpa.
+fl0.ru.
+r._dns-sd._udp.0.10.168.192.in-addr.arpa.
+e566.b.akamaiedge.net.
+pixel.facebook.com.
+12.109.122.200.in-addr.arpa.
+webyetis.com.
+developers.facebook.com.
+pixel.facebook.com.
+www.facebook.com.
+forum.axishistory.com.
+193.222.36.187.in-addr.arpa.
+www.lanvin.com.
+196.33.148.88.in-addr.arpa.
+gqlgroup.com.
+time.chttl.com.tw.
+a.root-servers.net.
+external.ak.fbcdn.net.
+grandgeneral.com.
+www.facebook.com.
+g0.gstatic.com.
+doha.frasershospitality.com.
+a.root-servers.net.
+kremino.com.
+photos-b.ak.fbcdn.net.
+network.incgamers.com.
+ir.ebaystatic.com.
+voipb.sip.yahoo.com.
+apple.com.
+ippi.msk.su.
+83.95.70.208.in-addr.arpa.
+us.kpmg.com.
+del.icio.us.
+37.95.190.189.in-addr.arpa.
+ayaks.ru.
+load.tubemogul.com.
+www.rallyandracing.com.
+a.root-servers.net.
+a2.sphotos.ak.fbcdn.net.
+pixel.facebook.com.
+rssc.com.
+106.185.134.187.in-addr.arpa.
+videodown.baofeng.com.
+elpasotimes.gannettonline.com.
+piesdefamosas.com.
+133.203.26.177.in-addr.arpa.
+1.bp.blogspot.com.
+graph.facebook.com.
+b.scorecardresearch.com.
+photos-b.ak.fbcdn.net.
+ezlip.com.
+media.fastcar.co.uk.
+a5.sphotos.ak.fbcdn.net.
+232.180.146.187.in-addr.arpa.
+photos-b.ak.fbcdn.net.
+laminate-parquet.ru.
+db._dns-sd._udp.lan.
+clients1.google.com.
+www.unileon.es.
+creative.ak.fbcdn.net.
+profile.ak.fbcdn.net.
+www.msftncsi.com.
+s7.addthis.com.
+be-x-old.wikipedia.org.
+www.nabdh-alm3ani.net.
+photos-h.ak.fbcdn.net.
+f:mw7gybl.h86d7r5b.
+www.foodreference.com.
+a.root-servers.net.
+tracker.csze.com.
+154.129.39.186.in-addr.arpa.
+platform.ak.fbcdn.net.
+227.173.123.84.in-addr.arpa.
+dcingredients.com.
+ladbrokesmobilebetting.com.
+103.187.12.186.in-addr.arpa.
+inky.tumblr.com.
+google.com.
+www.consoleaddiction.com.
+zipform.com.s8a2.psmtp.com.
+weather.wapp.wii.com.
+a.root-servers.net.
+8.24.220.189.in-addr.arpa.
+www.emesotherapy.com.au.
+download347.avast.com.
+r.openx.net.akadns.net.
+external.ak.fbcdn.net.
+www.linguee.com.ar.
+www.steampunkmagazine.com.
+a-0.19-a3092081.20200b3.1518.19d3.3ea1.410.0.eh5u9jzwkkcg57a42q646qaje6.avqs.mcafee.com.
+158.181.231.190.in-addr.arpa.
+s.ytimg.com.
+161.234.141.201.in-addr.arpa.
+resolutioncenter.ebay.com.
+flatfrogmusic.com.
+www.richtig-spielen.de.
+smtp-out.wplus.net.
+17.142.138.187.in-addr.arpa.
+anixter.net.
+rcw.wc24.wii.com.
+200.115.69.189.in-addr.arpa.
+0-jl-w.channel.facebook.com.
+www.facebook.com.
+www.msn.com.
+barracuda.cannondesign.com.
+52.239.68.66.in-addr.arpa.
+a3.sphotos.ak.fbcdn.net.
+online.unitconverterpro.com.
+ad.z5x.net.
+platform.ak.fbcdn.net.
+m.addthisedge.com.
+www.facebook.com.
+weather.services.conduit.com.
+www.juegos.com.
+a.root-servers.net.
+www.crecimiento-personal.com.
+185.227.195.187.in-addr.arpa.
+16.102.59.186.in-addr.arpa.
+image2.pubmatic.com.
+photos-h.ak.fbcdn.net.
+124.4.51.190.in-addr.arpa.
+famintl.com.
+ksn7-12.kaspersky-labs.com.
+newsrss.bbc.co.uk.
+by2msg4010517.gateway.messenger.live.com.
+73.22.31.77.in-addr.arpa.
+smtp.ravensport.com.
+scripts.demandmedia.com.
+dieterpreiser.de.
+blog.mundoanuncio.com.
+157.254.146.190.in-addr.arpa.
+a6.sphotos.ak.fbcdn.net.
+a.root-servers.net.
+on.nba.com.
+websoilsurvey.nrcs.usda.gov.
+mail.nvdevelop.ru.
+17.254.216.189.in-addr.arpa.
+160.78.220.189.in-addr.arpa.
+www.discomuseum.com.
+tzzs888.com.
+a.root-servers.net.
+www.bywifi.com.
+cust13538-2.in.mailcontrol.com.
+a5.sphotos.ak.fbcdn.net.
+www.runningafrica.com.
+creative.ak.fbcdn.net.
+24.255.41.177.in-addr.arpa.
+239.109.10.46.in-addr.arpa.
+www.filesonic.com.
+www.google.com.
+90.239.164.190.in-addr.arpa.
+alt1.aspmx.l.google.com.
+stats.norton.com.
+swcdn.apple.com.
+a.root-servers.net.
+apps.facebook.com.
+249.42.80.186.in-addr.arpa.
+profile.ak.fbcdn.net.
+www.viglink.com.
+www.hostk.info.
+www.msftncsi.com.
+connect.facebook.net.
+shop.jayalders.com.
+www.ustream.tv.
+79.202.8.200.in-addr.arpa.
+geo-science.ch.
+events.unisfair.com.
+mail.reactionlab.com.
+46-courier.push.apple.com.
+one-chord-wonders.blogspot.com.
+www.facebook.com.
+yahoo.com.
+www.presentationmagazine.com.
+asm.sourceforge.net.
+hotmail.com.
+www.engadget.com.
+1stholistic.com.
+frdiscovery.hosting.sca.
+ws-cloud-msgplus.linkury.com.
+www.visitlawrence.com.
+whos.amung.us.
+cvtrust.org.
+news.google.co.il.
+www.cu-g.com.
+20minutos.feedsportal.com.
+123.110.72.50.in-addr.arpa.
+static.da.com.ar.
+takenaka.com.sg.
+a.root-servers.net.
+pes.liaofoo.com.
+16.230.86.200.in-addr.arpa.
+promotionalptnr.com.
+billing.sharo4ka.ru.
+ad.reachjunction.com.
+voipa.sip.yahoo.com.
+miepspb.ru.
+www.xboxlc.com.
+myexceltemplates.com.
+quyettri.com.
+elaviadorcapotado.blogspot.com.
+5.9.38.196.in-addr.arpa.
+s-static.ak.facebook.com.
+www.google-analytics.com.
+solocinehd.blogspot.com.
+lpcnb.com.
+a.root-servers.net.
+158.10.242.46.in-addr.arpa.
+contemplator.com.
+239.47.243.123.in-addr.arpa.
+tools.google.com.
+mail.chiefexecutive.com.
+26-courier.push.apple.com.
+www.facebook.com.
+pixel.facebook.com.
+pixel.facebook.com.
+arabia.msn.com.
+www.adshow.eu.
+platform.ak.fbcdn.net.
+_765_80_1.
+campeaoprovincias.com.
+b._dns-sd._udp.0.1.168.192.in-addr.arpa.
+sidler.de.
+www.google.com.mx.
+teredo.ipv6.microsoft.com.
+disqus.com.
+73.157.252.83.in-addr.arpa.
+e.miniclip.com.
+i4.ytimg.com.
+findgift.com.
+creative.ak.fbcdn.net.
+cnrit.tamu.edu.
+millerbranding.com.
+accounts.google.com.
+189.118.255.190.in-addr.arpa.
+www.bidhere.com.
+121.78.22.186.in-addr.arpa.
+chinanav.com.
+www.losratonesdepablo.com.
+youtu.be.
+ukfinancehouse.com.
+radar.meteo.be.
+metalwarez.com.
+grupogal.com.
+ns3.eu.editdns.net.
+s.youtube.com.
+google.com.
+ds.addthis.com.
+ns2.unity-web.ch.
+wearethelaw.tk.
+es-la.facebook.com.
+153.125.114.201.in-addr.arpa.
+66.66.30.190.in-addr.arpa.
+a1.sphotos.ak.fbcdn.net.
+a6.sphotos.ak.fbcdn.net.
+plus.google.com.
+etaion.com.
+mainlinemedianews.com.
+koreamedicaltravel.com.
+rrppnet.com.ar.
+92.41.75.190.in-addr.arpa.
+somtel.com.
+www.radiomuseum.org.
+70.92.144.216.in-addr.arpa.
+www.thedavidlawrenceshow.com.
+the-vault-surf-target-maker.com.
+ksn2-12.kaspersky-labs.com.
+www.facebook.com.
+scallywagandvagabond.com.
+del.icio.us.
+bigblue.com.
+lb._dns-sd._udp.0.2.168.192.in-addr.arpa.
+a.root-servers.net.
+ar-ar.facebook.com.
+7.0.0.10.in-addr.arpa.
+lomassexxx.blogspot.com.
+www.rinconjuegos.com.
+platform.twitter.com.
+dlvr.it.
+video.google.com.
+_ldap._tcp.dc._msdcs.hospira.corp.
+w40kespecialista.blogspot.com.
+inblindinglights.com.
+img.iwasinturkey.com.
+profile.ak.fbcdn.net.
+photos-h.ak.fbcdn.net.
+s0.2mdn.net.
+i3.ytimg.com.
+z.alimama.com.
+108.28.64.115.in-addr.arpa.
+row.bc.yahoo.com.
+244.32.252.173.in-addr.arpa.
+www.gamer.ne.jp.
+webpark.rutube.ru.
+um10.eset.com.
+static.ak.fbcdn.net.
+feeds.videosz.com.
+a.root-servers.net.
+79.156.16.70.in-addr.arpa.
+static.ak.facebook.com.
+kacharin.ru.
+skipoleposition.com.
+photos-f.ak.fbcdn.net.
+www.mattcardlefansite.co.uk.
+edge.quantserve.com.
+mbpvideo.com.
+dsn3.d.skype.net.
+by2msg3020215.gateway.messenger.live.com.
+www.gstatic.com.
+www.chinesecars.net.
+119.37.42.186.in-addr.arpa.
+www.starphone.com.ar.
+webspin-design.com.
+pixel.facebook.com.
+46.201.54.85.in-addr.arpa.
+103.199.168.192.in-addr.arpa.
+95.220.132.217.in-addr.arpa.
+www.iphone-girl.jp.
+sp.cwfservice.net.
+airbrakeapp.com.
+ofurotaimu.dreamwidth.org.
+pagead2.googlesyndication.com.
+me-cdn.effectivemeasure.net.
+www.google-analytics.com.
+profile.ak.fbcdn.net.
+a.root-servers.net.
+dingtao333.3322.org.
+platform.ak.fbcdn.net.
+172.66.27.201.in-addr.arpa.
+www.new.facebook.com.
+108.183.135.211.in-addr.arpa.
+223.227.51.190.in-addr.arpa.
+116.111.110.186.in-addr.arpa.
+243.126.75.200.in-addr.arpa.
+8.169.49.190.in-addr.arpa.
+tiwitter.com.
+up7y:ri5p.71sv.
+a.root-servers.net.
+nationaled.net.mail10.psmtp.com.
+oascentral.crainsnewyork.com.
+z022.fma.fb.me.
+119.62.81.151.in-addr.arpa.
+ctcinsurance.com.
+a.root-servers.net.
+secure.thinkstockphotos.com.
+googleads.g.doubleclick.net.
+www.expedia.co.kr.
+a1.sphotos.ak.fbcdn.net.
+156.53.56.200.in-addr.arpa.
+www.facebook.com.
+img-cdn.mediaplex.com.
+252.232.189.190.in-addr.arpa.
+_546_77_4.
+buschmanpartners.com.
+9.82.125.186.in-addr.arpa.
+grupoarion.com.mx.
+profile.ak.fbcdn.net.
+37.148.23.95.in-addr.arpa.
+monstrobe.com.
+m.facebook.com.
+elite-servers.com.ua.
+tudecidesmedia.com.
+csi.gstatic.com.
+www.facebook.com.
+franelasarepa.blogspot.com.
+1.0.0.127.dnsbugtest.1.0.0.127.in-addr.arpa.
+denis.stalker.h3q.com.
+63.93.70.208.in-addr.arpa.
+static.ak.fbcdn.net.
+vcs2.msg.yahoo.com.
+_754_86_4.
+www.hostingz.com.
+profile.ak.fbcdn.net.
+adventcomms.com.
+fbcdn-profile-a.akamaihd.net.
+developers.facebook.com.
+www.facebook.com.
+planes.pensiones.ley.com.es.
+sp.cwfservice.net.
+upakkom.ru.
+televisa.esmas.com.
+capacidadesespeciales.blogspot.com.
+gablesigns.com.s8b1.psmtp.com.
+www.youtube.com.
+a.root-servers.net.
+mail.cablelite.com.
+doma-konsult.ru.
+a.root-servers.net.
+webserver4.pjq.ok.cl.
+kircherlandscape.blogspot.com.
+e4.ny.us.ibm.com.
+www.google-analytics.com.
+www.webshaper.com.my.
+a.root-servers.net.
+standard.image.draw.spankapps.com.
+a8.sphotos.ak.fbcdn.net.
+mail.google.com.
+t3.gstatic.com.
+safebrowsing.clients.google.com.
+click.infospace.com.
+bmsapedyuxz.org.
+facebook.com.
+pixel.quantserve.com.
+a.root-servers.net.
+s2.youtube.com.
+a7.sphotos.ak.fbcdn.net.
+tradebox.ru.
+mchsi.com.
+28.18.230.190.in-addr.arpa.
+a.root-servers.net.
+proxy.promenergoresurs.ru.
+www.indavideo.hu.
+king.jetztspielen.de.
+a.c-0.19-230fa081.8110000.1518.19d3.3ea1.210.0.3t5zbpee7lm5hpbj4udp5m4ql6.avqs.mcafee.com.
+pt-br.facebook.com.
+www.gstatic.com.
+s.xvideos.com.
+a7.sphotos.ak.fbcdn.net.
+125.161.0.24.in-addr.arpa.
+16.9.47.201.in-addr.arpa.
+241.39.121.200.in-addr.arpa.
+multi.xnxx.com.
+www.stopbadware.org.
+pascal-descharmes.fr.
+graph.facebook.com.
+95.228.31.190.in-addr.arpa.
+photos-c.ak.fbcdn.net.
+a5.sphotos.ak.fbcdn.net.
+92.167.29.78.in-addr.arpa.
+simpsongeneralhospital.com.
+bartowregional.com.
+rpmusic.com.
+113.1.95.184.in-addr.arpa.
+b.scorecardresearch.com.
+fbcdn-profile-a.akamaihd.net.
+gnnchannel.com.
+129.25.161.201.in-addr.arpa.
+aa.online-metrix.net.
+energiadeluz.com.
+216.9.36.187.in-addr.arpa.
+www.tecnomed2000.com.
+i1.ytimg.com.
+a3.sphotos.ak.fbcdn.net.
+a.root-servers.net.
+byfiles.storage.msn.com.
+bezar.ru.
+teredo.ipv6.microsoft.com.
+aha.msk.su.
+a.root-servers.net.
+107.117.64.75.in-addr.arpa.
+www.facebook.com.
+www.mdgfog.com.
+peter.com.
+beringov-proliv.ru.
+a756.r.akamai.net.
+cactusmat.com.
+12.65.52.201.in-addr.arpa.
+mail.philharmonia.spb.ru.
+googleads.g.doubleclick.net.
+t1.gstatic.com.
+osalotteries.net.
+nitrato-lirico.blogspot.com.
+v8.nonxt7.c.youtube.com.
+mail.organic-shop.ru.
+ads.admarvel.com.
+couponbuddy.s3.amazonaws.com.
+www.wwl.com.
+photos-b.ak.fbcdn.net.
+a6.sphotos.ak.fbcdn.net.
+www.rutschmann.biz.
+es.wikipedia.org.
+bbvaganadero1.bbva.com.co.
+realty.mail.ru.
+aquienaguas.com.
+zamunda.net.
+169.138.106.186.in-addr.arpa.
+europe.perf.glbdns.microsoft.com.
+a.root-servers.net.
+psgw.t-mobilesgws.com.
+a15.t26.net.
+mail.sacramentointernet.com.
+a.root-servers.net.
+s108.filesonic.com.
+86.140.176.190.in-addr.arpa.
+8ejb1eqrb.25zf.
+99.91.44.190.in-addr.arpa.
+ad.smowtion.com.
+200.13.153.189.in-addr.arpa.
+profile.ak.fbcdn.net.
+235.72.31.80.in-addr.arpa.
+es.wikipedia.org.
+cpsfx.com.
+www.asian-boy-bondage.com.
+46.85.191.186.in-addr.arpa.
+pt-br.facebook.com.
+174.219.226.95.in-addr.arpa.
+buy.norton.com.
+secure.wlxrs.com.
+fbcdn-sphotos-a.akamaihd.net.
+nasascience.nasa.gov.
+merckx-nv.be.
+appenda.com.
+www.google-analytics.com.
+185.33.159.190.in-addr.arpa.
+73.238.191.189.in-addr.arpa.
+promo.meetatranny.com.
+pop3.live.com.
+a1814.g.akamai.net.
+a2.sphotos.ak.fbcdn.net.
+dns.msftncsi.com.
+suscom-main.net.
+ads.us.e-planning.net.
+www.gazzetta.it.
+www.stopbadware.org.
+www.happycow.net.
+analogmachine.com.
+www.myspacegens.com.
+europe.worldtraveler.biz.
+a4.sphotos.ak.fbcdn.net.
+ww2.nf.outerinfo.net.
+a.root-servers.net.
+a.root-servers.net.
+accounts.google.com.mx.
+66.130.255.222.in-addr.arpa.
+lobotuerto.com.
+creative.ak.fbcdn.net.
+l.yimg.com.
+cityofripon.org.
+homesteadlandscaping.com.
+connect.facebook.net.
+fbcdn-sphotos-a.akamaihd.net.
+khabarovsk.telephone.ru.
+mail.gmhca.com.
+www.facebook.com.
+www.doazafrandelamancha.com.
+laprincipianta.blogspot.com.
+chat.facebook.com.
+49.212.85.209.zen.spamhaus.org.
+fortax.ch.
+gospelmusicchannel.edgesuite.net.
+153.124.49.190.in-addr.arpa.
+post.centro.ru.
+nuestras.frasesdeface.net.
+www.google-analytics.com.
+mail2.sinclairresearch.com.
+chintels.com.
+nl.pollypocket.com.
+www.pixelpraise.com.
+a.root-servers.net.
+static.ak.fbcdn.net.
+119.247.119.75.in-addr.arpa.
+www.geeky-gadgets.com.
+www.senia.com.
+id.l.google.com.
+metrix.511tactical.com.
+tracker.bittorrent.am.
+mail.rwandair.com.
+google-analytics.com.
+mail.google.com.
+a1.sphotos.ak.fbcdn.net.
+83.186.101.78.in-addr.arpa.
+ak.imgfarm.com.
+197.36.52.186.in-addr.arpa.
+listen.grooveshark.com.
+a7.sphotos.ak.fbcdn.net.
+m.addthisedge.com.
+lumpeny.com.
+71.60.191.190.in-addr.arpa.
+instagram.com.
+beta.stun.voice.yahoo.com.
+mxa-0006fb01.gslb.pphosted.com.
+btonternet.com.
+100.33.148.58.in-addr.arpa.
+messenger.hotmail.com.
+www.gregbyng.com.
+abutik.hu.
+200.252.34.186.in-addr.arpa.
+ekaterinka.orthodoxy.ru.
+js.wlxrs.com.
+i3.ytimg.com.
+csi.gstatic.com.
+www.afrik-cuisine.com.
+platform.ak.fbcdn.net.
+cm.g.doubleclick.net.
+0-jx-w.channel.facebook.com.
+ns.neptun.spb.ru.
+adoholik.com.
+www.shubertticketing.com.
+sportshunter.eu.
+argentinahistorica.com.ar.
+agenbolaa.nuke.im.
+112.219.86.186.in-addr.arpa.
+blackvelvet.comastuff.com.
+www.facebook.com.
+188.250.78.74.in-addr.arpa.
+chmail.tecan.com.
+mail.carter.ru.
+download115.avast.com.
+a4.sphotos.ak.fbcdn.net.
+mail.regtime-k.ru.
+checkip.dyndns.org.
+afe.specificclick.net.
+mail1.sharafdg.com.
+sar.ws.kaleidescape.com.
+www.femeba.org.ar.
+www.alarabiya.net.
+a6.sphotos.ak.fbcdn.net.
+www.wwfca.org.
+16.118.51.190.in-addr.arpa.
+204.50.35.89.in-addr.arpa.
+_840_88_9.
+mail.safeinformationgroup.com.
+133.86.251.111.in-addr.arpa.
+creative.ak.fbcdn.net.
+a.root-servers.net.
+abuelos-manchegos.blogspot.com.
+photos-d.ak.fbcdn.net.
+_883_36_4.
+i.fr.imwx.com.
+mail.digitalsunrise.com.
+d2057300.instant.xoom.it.
+bl59naigc.z55v2e6t.
+search.pontofrio.com.br.
+csi.gstatic.com.
+reastructuralengineers.com.
+193.187.240.82.in-addr.arpa.
+googleads.g.doubleclick.net.
+adm-druckmedien.de.
+www.google.com.
+i4.ytimg.com.
+ads.yimg.com.
+vp.sip.messenger.msn.com.
+hitext.ru.
+www.google-analytics.com.
+creative.ak.fbcdn.net.
+www.iegallery.com.
+wpad.
+wpad.hotspot.
+s-static.ak.facebook.com.
+fbcdn-sphotos-a.akamaihd.net.
+181.223.155.189.in-addr.arpa.
+camcor.ru.
+fxfeeds.mozilla.com.
+168.137.12.118.in-addr.arpa.
+checkip.dyndns.org.
+118.162.255.201.in-addr.arpa.
+ocsp.thawte.com.
+s-static.ak.fbcdn.net.
+www.youtube.com.
+www.webcamscaseras.info.
+mail.ccli.co.uk.
+vivalaleydeltemor.blogspot.com.
+sites.google.com.
+ns1.cafe24.com.
+platform.twitter.com.
+mailgateway.studiobana.it.
+www.caughtpeeing.info.
+static.ak.fbcdn.net.
+106.89.161.113.in-addr.arpa.
+www.y8.com.
+rya.rockyou.com.
+69.107.10.46.in-addr.arpa.
+blog.mesmo.tv.
+185.232.226.202.in-addr.arpa.
+casa-italia.immobiliare.it.
+www.facebook.com.
+ec2-50-19-163-62.compute-1.amazonaws.com.
+errors.jawaker.com.
+kaplowe.com.
+d2105488.xoom.it.
+msn.com.
+7.226.149.213.in-addr.arpa.
+tc.v22.cache7.googlevideo.com.
+173.69.204.130.in-addr.arpa.
+www.ccchp-isys.edu.pa.
+244.195.157.186.in-addr.arpa.
+www.dvd-explorer.org.
+photos-g.ak.fbcdn.net.
+a.root-servers.net.
+e4805.b.akamaiedge.net.
+cnref.com.s5a1.psmtp.com.
+safebrowsing.clients.google.com.
+camera1.mairie-brest.fr.
+api.oovoo.com.
+kanto.machi.to.
+accounts.google.com.
+es.answers.yahoo.com.
+ziafog.com.
+237.210.132.189.in-addr.arpa.
+gtamexico.com.
+4:hdifftw.92vi.
+46.234.94.190.in-addr.arpa.
+i4.ytimg.com.
+18.214.112.126.in-addr.arpa.
+a.root-servers.net.
+guiacinefila.com.
+3.140.69.189.in-addr.arpa.
+ftk.dk.
+medienhaus.nuggad.net.
+store.gcsis-apple.com.akadns.net.
+_155_62_1.
+apps.facebook.com.
+73.85.168.192.in-addr.arpa.
+www1.euro.dell-cidr.akadns.net.
+www.facebook.com.
+static.ak.fbcdn.net.
+222.168.232.190.in-addr.arpa.
+ecs.k12.ny.us.
+www.socialgrowthtechnologies.com.
+xxramneekxx.tumblr.com.
+i2.ytimg.com.
+95.177.102.201.in-addr.arpa.
+a.root-servers.net.
+protontech.com.
+csi.web.aol.com.
+connect.facebook.net.
+a.root-servers.net.
+c1.microsoft.com.
+b.vimeocdn.com.
+a4.sphotos.ak.fbcdn.net.
+newsrss.bbc.co.uk.
+125.197.172.199.in-addr.arpa.
+laotramitadelaverdad.nixiweb.com.
+safebrowsing-cache.google.com.
+www.facebook.com.
+mail.pycnogenol.com.
+teredo.ipv6.microsoft.com.
+es-la.facebook.com.
+clients2.google.com.
+q-love.ru.
+www.fimkastore.com.
+ejabat.google.com.
+dns.msftncsi.com.
+185.209.46.190.in-addr.arpa.
+a5.sphotos.ak.fbcdn.net.
+149.4.168.192.in-addr.arpa.
+ad-g.doubleclick.net.
+ddcm.wildtangent.com.
+distritofederal.olx.com.mx.
+www.thehairbowcompany.com.
+www.wubisheng.cn.
+www.google.com.
+gatvolinoman.blogspot.com.
+a.root-servers.net.
+.
+238.230.240.94.in-addr.arpa.
+www.facebook.com.
+a7.sphotos.ak.fbcdn.net.
+assda.com.
+shiva.grozny.ru.
+genkienglish.net.
+secure.shared.live.com.
+seguros-automovil.mascoche.net.
+victorianus.com.
+74.244.253.190.in-addr.arpa.
+banners2.hollywoodaffiliates.com.
+protechnics.com.
+www.scopemed.org.
+blog.corporationwiki.com.
+i3.ytimg.com.
+244.83.144.187.in-addr.arpa.
+simplelifecorp.com.
+static.ak.fbcdn.net.
+htdogs.ru.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+42.213.26.216.in-addr.arpa.
+breakingmedia.com.
+fxfeeds.mozilla.com.
+gvnvbbpev.i51i0n3x.
+goldliger.evplayer.com.
+iklancoffee.blogspot.com.
+safepages.com.s6a2.psmtp.com.
+22.126.111.219.in-addr.arpa.
+commsoft.net.s8a2.psmtp.com.
+1xt1xik3b.65ct.
+237.183.131.190.in-addr.arpa.
+www.monitos.cl.
+www.ratteb.com.
+www.lifeinsurancechandigarh.com.
+router.infolinks.com.
+147.212.139.98.bl.spamcop.net.
+us.f1814.mail.yahoo.com.
+4.bp.blogspot.com.
+kut258r94.o01u8a6r.
+www.fhg.ladyboycandyshop.com.
+bl163w.blu163.mail.live.com.
+worldwildnessweb.blogspot.com.
+crl.microsoft.com.
+hipservice.live.com.
+connect.facebook.net.
+mail3.enorthfield.com.
+www.bcrae.es.
+dsn6.d.skype.net.
+www.celebboutique.com.
+a.root-servers.net.
+photos-a.ak.fbcdn.net.
+mail.walshalbert.com.
+google.com.
+ar.ika-world.com.
+www.facebook.com.
+a.root-servers.net.
+www.facebook.com.
+241.134.144.187.in-addr.arpa.
+mail.spoon.org.
+time.chttl.com.tw.
+pedos.com.ar.
+click2.info.
+plusone.google.com.
+fbcdn-profile-a.akamaihd.net.
+apcarolinas.com.
+51.210.21.201.in-addr.arpa.
+photos-b.ak.fbcdn.net.
+streetbundy.blogspot.com.
+yibrq4rmn.d64l7j1y.
+www.facebook.com.
+139.0.181.189.in-addr.arpa.
+215.84.156.187.in-addr.arpa.
+js.revsci.net.
+fr-talk.kakao.com.
+nightside.ksl.com.
+82.96.160.190.in-addr.arpa.
+rss.cnn.com.
+www.conocewordpress.com.
+toolbarqueries.google.com.
+www.investors.ups.com.
+1991.com.
+rwhois.net.
+www.google.com.
+www.google.com.
+a.root-servers.net.
+a.root-servers.net.
+25-courier.push.apple.com.
+mob.adwhirl.com.
+ic.s1.qzone.qq.com.
+profile.ak.fbcdn.net.
+twitter.co.
+l.yimg.com.
+168.225.126.200.in-addr.arpa.
+edge.quantserve.com.
+activesync.hot.glbdns.microsoft.com.
+www.google.com.
+a4.mzstatic.com.
+translate.google.com.
+www.google.com.
+plusone.google.com.
+sp.cwfservice.net.
+static.ak.fbcdn.net.
+developers.facebook.com.
+stitcheree.com.
+feeds.101cookbooks.com.
+ronacom.ru.
+yaahooo.ru.lan.
+vip.tracker.thepiratebay.org.
+228.126.90.189.in-addr.arpa.
+_440_07_5.
+mx.answers.yahoo.com.
+checkip.dyndns.com.
+gdata.youtube.com.
+photos-g.ak.fbcdn.net.
+firstdatabank.com.s7a1.psmtp.com.
+androidwallpaper.org.
+basslake.com.s8a1.psmtp.com.
+sites.vnuexhibitions.com.
+ib.adnxs.com.
+archive.wgnradio.com.
+28-courier.push.apple.com.
+entela.com.
+ad.adnetwork.net.
+123.94.232.190.in-addr.arpa.
+android.clients.google.com.
+www.e-ir.info.
+www.perfectweb.ro.
+time.windows.com.
+del.icio.us.
+2822.v.fwmrm.net.
+180.63.25.83.in-addr.arpa.
+www.streethandball.com.
+sn127w.snt127.mail.live.com.
+data.flurry.com.
+sp.cwfservice.net.
+www.google.com.mx.
+teredo.ipv6.microsoft.com.
+99.224.138.201.in-addr.arpa.
+www.facebook.com.
+www.google.com.
+es.wikiquote.org.
+a.root-servers.net.
+dinamicasvivenciales.blogspot.com.
+www.ipolitics360.com.
+0.4403013.com.
+static.ak.fbcdn.net.
+a.root-servers.net.
+profile.ak.fbcdn.net.
+a.root-servers.net.
+_622_01_9.
+joesixpack.net.
+gomortgageconcepts.com.
+bcinnkeepers.com.mail1.psmtp.com.
+michaelanthony.co.uk.
+apis.google.com.
+quieresadelgazar.tonykamo.com.
+www.facebook.com.
+55.218.180.180.in-addr.arpa.
+before-and-after-pics.com.
+63.141.129.189.in-addr.arpa.
+96.105.248.201.in-addr.arpa.
+efu.org.ua.
+login.live.com.
+www.youtube.com.
+46.223.74.201.in-addr.arpa.
+pankhurst.com.
+www.facebook.com.
+grannytubexxx.com.
+66.34.213.194.in-addr.arpa.
+gtp.ru.
+a.root-servers.net.
+denis.stalker.h3q.com.
+mail.
+73.236.178.186.in-addr.arpa.
+dns.msftncsi.com.
+34.9.157.187.in-addr.arpa.
+g-ecx.images-amazon.com.
+0-id-w.channel.facebook.com.
+www.woolandthegang.com.
+yahoo.com.
+1.0.0.127.in-addr.arpa.
+dm.ie.sogou.com.
+www.google.com.
+api.twitter.com.
+tcadops.leshebdos.com.
+www.monografias.com.
+sbs-solicitors.co.uk.
+8k8uznxyk.l61t7h0t.
+googleads.g.doubleclick.net.
+animeymanga4forever.foroactivo.com.
+140.180.86.85.in-addr.arpa.
+246.123.75.201.in-addr.arpa.
+telemedia.com.
+hcd-inc.com.
+n18.8-d.com.
+www.foroactivo.com.
+215.212.28.189.in-addr.arpa.
+fbcdn-sphotos-a.akamaihd.net.
+redirector.aaanet.ru.
+mwgxfzgzhyd40a47ltiqp22lygwnqcubvcy.biz.
+7.52.162.189.in-addr.arpa.
+im79.vk.com.
+gmll.com.
+p08-bookmarks.icloud.com.
+www.facebook.com.
+profile.ak.fbcdn.net.
+a8.sphotos.ak.fbcdn.net.
+members.dyndns.org.
+dama-de-agua.blogspot.com.
+teredo.ipv6.microsoft.com.
+swalif.net.
+20.50.169.118.in-addr.arpa.
+peru.ahk.de.
+csm.com.
+kuf.biglobe.ne.jp.
+encrypted-tbn0.google.com.
+a.root-servers.net.
+www.google.com.
+wpad.belkin.
+r1rk9np7bpcsfoeekl0khkd2juj27q3o-a-fc-opensocial.googleusercontent.com.
+70.172.74.187.in-addr.arpa.
+developers.facebook.com.
+_200_46_7.
+www.16valvulas.com.ar.
+col.stc.s-msn.com.
+library.skillport.com.
+236.207.14.187.in-addr.arpa.
+www.allsaints.com.
+safebrowsing.clients.google.com.
+sites.google.com.
+pixel.facebook.com.
+101.153.138.187.in-addr.arpa.
+ct5:4y9rs.48jf.
+126.83.34.83.in-addr.arpa.
+horoscopos.prodigy.msn.com.
+www.historama.com.
+150.177.90.2.in-addr.arpa.
+ca-fr.norton.com.
+www.unixmanga.com.
+ad.adserverplus.com.
+ad-g.doubleclick.net.
+noemozica.files.wordpress.com.
+www.facebook.com.
+105.1.168.192.in-addr.arpa.
+www.facebook.com.
+s649.photobucket.com.
+mup.asu.edu.
+mail.firedog.cc.
+74.250.145.187.in-addr.arpa.
+ef.ewf.
+colunistas.ig.com.br.
+o.analytics.yahoo.com.
+photos-b.ak.fbcdn.net.
+img226.imagevenue.com.
+grgfood.com.
+a1325.phobos.apple.com.
+mx.msn.recepedia.com.
+160.66.114.190.in-addr.arpa.
+ipv6.msftncsi.com.
+srx.main.ebayrtm.com.
+talking-tom-cat.softonic.fr.
+standnow.org.
+i4.ytimg.com.
+www.radiomodelos.com.mx.
+orientexpress.forumcommunity.net.
+dnl-01.geo.kaspersky.com.
+nextramail.hu.
+192.152.29.70.in-addr.arpa.
+a1.sphotos.ak.fbcdn.net.
+a.root-servers.net.
+webcache.googleusercontent.com.
+sru.ru.
+photos-b.ak.fbcdn.net.
+236.175.14.189.in-addr.arpa.
+www.smutdvds.com.
+static.ak.facebook.com.
+_662_98_2.
+0-jj-w.channel.facebook.com.
+multi.xnxx.com.
+190.184.241.92.in-addr.arpa.
+um10.eset.com.
+wpad.
+217.178.140.201.in-addr.arpa.
+www.autoepc.net.
+a.root-servers.net.
+120.153.212.201.in-addr.arpa.
+hightech-redneck.com.
+www.shy-models.org.
+db._dns-sd._udp.0.1.168.192.in-addr.arpa.
+translate.google.com.mx.
+acap.it.
+108.90.90.84.in-addr.arpa.
+hi5.com.
+b._dns-sd._udp.0.1.168.192.in-addr.arpa.
+24.233.35.177.in-addr.arpa.
+photos-c.ak.fbcdn.net.
+www.vh1la.com.
+ads.themxua.net.
+aplisic.iese.edu.
+creative.ak.fbcdn.net.
+www.lasorquideashotel.com.
+cn1.redswoosh.akadns.net.
+mayaweb.upr.clu.edu.
+69.71.66.184.in-addr.arpa.
+wakmc.com.
+mohawk-radio.com.
+www.adbrite.com.
+lapaz-bajacaliforniasur.olx.com.mx.
+www.freeotoscript.com.
+a.root-servers.net.
+orttool.com.s7b2.psmtp.com.
+photos-d.ak.fbcdn.net.
+toolbarqueries.google.com.
+_ldap._tcp.
+nniline.naver.com.
+api.facebook.com.
+aspmx.l.google.com.
+69.227.131.189.in-addr.arpa.
+www.google.co.
+www.youtube-nocookie.com.
+photos-f.ak.fbcdn.net.
+dnn506yrbagrg.cloudfront.net.
+gdata.youtube.com.
+goamtel.com.
+swohio.twcbc.com.
+187.16.161.189.in-addr.arpa.
+i3.ytimg.com.
+pixel.facebook.com.
+179.82.231.189.in-addr.arpa.
+api.twitter.com.
+lasrecetasdesuli.blogspot.com.
+www5.tranexp.com.
+65.231.82.189.in-addr.arpa.
+www.archive.org.
+sourceforge.net.dnsbl7.mailshell.net.
+img129.imageshack.us.
+www.ambysoft.com.
+monchyvariedadesenfieltro.blogspot.com.
+photos-b.ak.fbcdn.net.
+prod2.rest-notify.msg.yahoo.com.
+a.root-servers.net.
+66.153.175.190.in-addr.arpa.
+si0.twimg.com.
+khm0.google.com.
+gmail.com.
+167.6.217.87.in-addr.arpa.
+metsco.com.
+a5.sphotos.ak.fbcdn.net.
+static.ak.connect.facebook.com.
+developers.facebook.com.
+196.72.75.201.in-addr.arpa.
+profile.ak.fbcdn.net.
+profile.ak.fbcdn.net.
+safebrowsing.clients.google.com.
+api.twitter.com.
+136.204.224.24.in-addr.arpa.
+benning.army.mil.
+horoscopos.euroresidentes.es.
+sawdustmaking.com.
+akitacopy.com.
+i48.tinypic.com.
+router.tlvmedia.com.
+benkovitz.com.
+a.root-servers.net.
+apps.facebook.com.
+205.168.57.186.in-addr.arpa.
+158.17.11.186.in-addr.arpa.
+img.babylon.com.
+photos-a.ak.fbcdn.net.
+85.43.24.189.in-addr.arpa.
+45.166.171.201.in-addr.arpa.
+clients1.google.com.
+184.2.219.85.in-addr.arpa.
+islambuddhism.com.
+65.189.241.60.in-addr.arpa.
+0sxx.com.
+platform.twitter.com.
+cm.g.doubleclick.net.
+a.root-servers.net.
+build.last.fm.
+133.204.184.88.in-addr.arpa.
+www.facebook.com.
+34.31.93.200.in-addr.arpa.
+131.97.161.189.in-addr.arpa.
+concilioshekinah.org.
+a.root-servers.net.
+76.190.10.201.in-addr.arpa.
+www.facebook.com.
+mail.cs181.xqx.cn.
+a8.sphotos.ak.fbcdn.net.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+ranking-view-c01.u0.np.community.playstation.net.
+fbcdn-photos-a.akamaihd.net.
+41.162.171.200.in-addr.arpa.
+golyon.com.
+www.scrumalliance.org.
+34.179.97.190.in-addr.arpa.
+gfx1.hotmail.com.
+a.root-servers.net.
+www.cbsinteractive.com.
+photos-d.ak.fbcdn.net.
+142.149.41.71.in-addr.arpa.
+photos-e.ak.fbcdn.net.
+inbound.aabinc.net.netsolmail.net.
+disneyworldforum.disney.go.com.
+iappraise.com.
+www.googleadservices.com.
+up.rabe7.com.
+www.funtal.com.
+stankobank.ru.
+images.scanalert.com.
+ocsp.comodoca.com.
+www.sqm.microsoft.com.
+youtube-ui.l.google.com.
+230.115.125.186.in-addr.arpa.
+s3.buysellads.com.
+austin.slcs.slb.com.
+ksn6-12.kaspersky-labs.com.
+205.224.117.42.in-addr.arpa.
+lh6.ggpht.com.
+www.googleadservices.com.
+dj-nia.com.
+a5.sphotos.ak.fbcdn.net.
+broadband.cnet.com.au.
+www.masquefutbol.com.
+95.196.8.200.in-addr.arpa.
+media.victoriassecret.com.
+clients1.google.com.
+essensualsasia.com.
+www.christiansalerno.com.
+www.statcounter.com.
+yubless.org.
+a7.sphotos.ak.fbcdn.net.
+a7.sphotos.ak.fbcdn.net.
+204.79.18.76.in-addr.arpa.
+www.ticotimes.net.
+www.actionsprite.com.
+static.chartbeat.com.
+aspmx.spamjadoo.com.
+i4.ytimg.com.
+fezgu.com.
+www.sky4energy.com.
+ps.palmws.com.
+lkh-hoergas.at.
+e-mails.ru.
+spamassassin.idgcomm.com.
+22.183.121.84.in-addr.arpa.
+_086_72_7.
+a1.sphotos.ak.fbcdn.net.
+235.246.15.8.in-addr.arpa.
+a.root-servers.net.
+tebnfi.com.
+200.78.132.189.in-addr.arpa.
+zrein.artician.com.
+a1.sphotos.ak.fbcdn.net.
+developers.facebook.com.
+search.vuze.com.
+d2098724.xoom.it.
+www.ripleysthailand.com.
+azle.esc11.net.
+www.monitor.net.
+soulwire.co.uk.
+www.facebook.com.
+photos-e.ak.fbcdn.net.
+terceracultura.cl.
+bluepyramid.org.
+gallery.sourceforge.net.
+a749.g.akamai.net.
+24.90.55.65.psbl.surriel.com.
+cookex.amp.yahoo.com.
+th-p14.talk.kakao.co.kr.
+161.56.194.190.in-addr.arpa.
+safebrowsing.cache.l.google.com.
+connect.facebook.net.
+candymania.com.
+static.ak.fbcdn.net.
+time.chttl.com.tw.
+a1404.w41.akamai.net.
+104.202.48.186.in-addr.arpa.
+1212yahoo.com.
+www.facebook.com.
+3.242.18.177.in-addr.arpa.
+ad.smowtion.com.
+telstra.com.
+reggaetrain.com.
+www.upload2world.com.
+search.4shared.com.
+168.214.141.27.in-addr.arpa.
+relianceengineers.com.
+css.wlxrs.com.
+twitter.com.
+sp.cwfservice.net.
+db._dns-sd._udp.0.2.168.192.in-addr.arpa.
+www.basketball-bundesliga.de.
+7.224.160.193.in-addr.arpa.
+speedy.imo.im.
+profile.ak.fbcdn.net.
+izhauto.ru.
+energuia.com.
+nations.widmi.com.
+83.190.209.201.in-addr.arpa.
+www.facebook.com.
+a6.sphotos.ak.fbcdn.net.
+kalamullah.com.
+246.187.159.189.in-addr.arpa.
+s94.cnzz.com.
+e3646.b.akamaiedge.net.
+roband.com.
+profile.ak.fbcdn.net.
+61.232.39.187.in-addr.arpa.
+s21.bitshare.com.
+new.zveroforma.ru.
+www.pinkmgp.com.
+9.155.26.24.in-addr.arpa.
+a4.da1.akamai.net.
+pottermorewatch.tumblr.com.
+imshop.com.ru.
+pt-br.facebook.com.
+9.192.20.81.in-addr.arpa.
+resimail.beachfrontonline.com.
+165.107.91.186.in-addr.arpa.
+159.26.84.200.in-addr.arpa.
+cdn.lfstmedia.com.
+content.yieldmanager.edgesuite.net.
+external.ak.fbcdn.net.
+go.srvnow.com.
+mail2.hoksve.com.
+clients4.google.com.
+external.ak.fbcdn.net.
+www.inbursa.com.mx.
+tacoda.at.atwola.com.
+www.thestreet.com.
+www.bighdesign.com.
+mencey-al-mo.blogspot.com.
+au.download.windowsupdate.com.
+lanoire.wikia.com.
+www.facebook.com.
+m.ak.fbcdn.net.
+74.90.123.189.in-addr.arpa.
+i1.ytimg.com.
+a7.sphotos.ak.fbcdn.net.
+www.plusnetwork.com.
+s1.tanoth.com.mx.
+freudenberg-nw.com.
+motorcyclephilippines.com.
+img4.ask.fm.
+www.facebook.com.
+crl.verisign.net.
+mail.navcanada.ca.
+apis.google.com.
+www.witchhut.com.
+pop.180com.net.
+breedclub.ru.
+www13.0zz0.com.
+droidsecurity.appspot.com.
+g.microsoft.com.
+js.wlxrs.com.
+lists.xmission.com.
+already.com.
+.
+_ldap._tcp.
+115.158.115.140.in-addr.arpa.
+runonce.msn.com.
+intali.ru.
+www.facebook.com.
+www.oniichannoecchi.com.
+40.36.162.189.in-addr.arpa.
+a7.sphotos.ak.fbcdn.net.
+datingtools.spacash.com.
+images.hotnewnet.com.
+59.238.31.161.in-addr.arpa.
+c143528.memecenter.com.
+206.108.252.201.in-addr.arpa.
+158.144.112.212.in-addr.arpa.
+img.imobiletube.com.
+187.8.121.59.in-addr.arpa.
+googleads.g.doubleclick.net.
+test-rt.liftdna.com.
+photos-b.ak.fbcdn.net.
+239.202.8.200.in-addr.arpa.
+smtp5.smart.com.ph.
+eldoradofurniture.com.
+www.unrisd.org.
+player.radio.com.
+138.120.65.217.in-addr.arpa.
+translate.google.com.mx.
+mail.
+v14.nonxt2.c.youtube.com.
+josemariomourinho.com.
+www.entreprisescanada.ca.
+www.lacoteimmo.com.
+1.0.0.127.dnsbugtest.1.0.0.127.in-addr.arpa.
+js.wlxrs.com.
+140.41.173.190.in-addr.arpa.
+achusnetgolf.com.
+www.visitehoteles.com.
+eloff.net.
+i2.ytimg.com.
+www.bywifi.com.
+ksn2-12.kaspersky-labs.com.
+unlibroabierto.tumblr.com.
+ad.yieldmanager.com.
+175.30.188.190.in-addr.arpa.
+pschmid.net.
+0.gravatar.com.
+vicentelopez0.tripod.com.
+www.solarsolar.com.au.
+www.apple.com.
+partner.googleadservices.com.
+www.gigisapparel.com.
+docs.google.com.
+images.scanalert.com.
+telodigo.com.
+stereosvit.ua.
+profile.ak.fbcdn.net.
+rcp.eu.blackberry.com.
+www.carsmexico.com.
+www.pubmedcentral.nih.gov.
+static2.dmcdn.net.
+d2.zedo.com.
+checkip.dyndns.org.
+photos-a.ak.fbcdn.net.
+175.220.31.190.in-addr.arpa.
+67.126.240.123.in-addr.arpa.
+atyourcervix.blogspot.com.
+safebrowsing.clients.google.com.
+www.google.com.
+husky.courant2.com.
+tcp.sagepub.com.
+correo.almacenes-si.com.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+ad.adnetwork.net.
+12.104.20.190.in-addr.arpa.
+graph.facebook.com.
+toolbarqueries.google.com.
+s-static.ak.facebook.com.
+_247_17_2.
+www3.zero-animation.net.
+smretina.s3.amazonaws.com.
+sevastopol.su.
+hiphop-ejay.softonic.com.
+i.imgur.com.
+solucionesbook.blogspot.com.
+ksn2-12.kaspersky-labs.com.
+kr.ec21.com.
+apps.facebook.com.
+a749.g.akamai.net.
+www.rapesin.com.
+www.leopardtrek.lu.
+a.root-servers.net.
+bfbc2.gos.ea.com.
+plus.google.com.
+platform.ak.fbcdn.net.
+developers.facebook.com.
+243.77.47.24.in-addr.arpa.
+234.8.55.157.in-addr.arpa.
+tools.google.com.
+stonesoft.com.
+download.microsoft.com.
+www.osl.no.
+78.245.105.119.in-addr.arpa.
+www.atbholidays.com.
+sanmiguel.mundoanuncio.cr.
+api.twitter.com.
+ar-ar.facebook.com.
+41.41.222.77.in-addr.arpa.
+www.travian.com.mx.
+dns.msftncsi.com.
+strollinfield.com.
+newsrss.bbc.co.uk.
+r._dns-sd._udp.lan.
+inf.sup.ru.
+corazondepoeta.obolog.com.
+api.twitter.com.
+ec2-50-16-50-154.compute-1.amazonaws.com.
+actsys.ru.
+243.205.225.190.in-addr.arpa.
+updatekeepalive.mcafee.com.
+apis.google.com.
+www.zmovie.tv.
+text.lan.
+www.softonic.com.
+smtp.gs-development.com.
+www.google.com.
+mx1.kcnet.org.
+36.23.90.186.in-addr.arpa.
+www.morphuk.com.
+sp.cwfservice.net.
+31.3.69.189.in-addr.arpa.
+global.ard.yahoo.com.
+profile.ak.fbcdn.net.
+i2.ytimg.com.
+a.root-servers.net.
+google.com.
+www.iriver.com.au.
+update.messenger.yahoo.com.
+_537_69_1.
+forbesbowman.com.
+webmail-ru.bul.net.
+w393jvnvr.t06l8i9s.
+profile.ak.fbcdn.net.
+www.kt.com.
+sfiles.d1g.com.
+www.doncellabeach.com.
+comocrecer.netfirms.com.
+30.211.27.194.in-addr.arpa.
+163.248.53.201.in-addr.arpa.
+enciclopedia.us.es.
+static.ak.fbcdn.net.
+ksn7-12.kaspersky-labs.com.
+webimgs.bevnet.com.
+pes6-club.pesgame.net.
+zone20.hotwords.com.br.
+95.155.23.186.in-addr.arpa.
+mrbursnuclearplant.blogspot.com.
+tima-xtreme.com.
+nokia-maps.softonic.com.
+v574.vkadre.ru.
+in.penguingroup.com.
+creaciones5semestre.blogspot.com.
+51.68.238.189.in-addr.arpa.
+lm.pcworld.com.
+connect.facebook.net.
+fbcdn-sphotos-a.akamaihd.net.
+www.google.com.
+s0.2mdn.net.
+sp.cwfservice.net.
+a.root-servers.net.
+photos-b.ak.fbcdn.net.
+20.228.171.69.in-addr.arpa.
+mail-server.finist.ru.
+g.msn.com.
+148.32.134.188.in-addr.arpa.
+ael77kwzk.72bj.
+40.84.94.186.in-addr.arpa.
+img38.imageshack.us.
+a.root-servers.net.
+platform.twitter.com.
+www.youtube.com.
+_945_63_1.
+a.root-servers.net.
+a.root-servers.net.
+appframe.qq.com.
+bbshtml.shangdu.com.
+a.root-servers.net.
+exquisesensualite.blogspot.com.
+pt-br.facebook.com.
+time.chttl.com.tw.
+pagead2.googlesyndication.com.
+e566.b.akamaiedge.net.
+www.aggman.com.
+s0.2mdn.net.
+9.148.79.200.in-addr.arpa.
+144.36.134.190.in-addr.arpa.
+www.thenlpcompany.com.
+cl.msn.com.
+twitter.com.
+www.arzaworld.com.
+v2.cache7.c.youtube.com.
+geo.tp-cdn.com.
+ssl.gstatic.com.
+apps.facebook.com.
+e4805.b.akamaiedge.net.
+dt1pibe7d.01el.
+_453_58_7.
+hfmlegal.com.
+a-0.19-2309a081.c130083.1518.19d0.3ea1.210.0.sm6i6bzwl5spsqq1in31p8adb5.avqs.mcafee.com.
+googleads.g.doubleclick.net.
+static.ak.fbcdn.net.
+h.atdmt.com.
+meneame.wikispaces.com.
+nudeisfashion.wordpress.com.
+pixel.facebook.com.
+edge.quantserve.com.
+ajax.cloudflare.com.
+vesteon.en.alibaba.com.
+id.google.com.
+132.241.94.190.in-addr.arpa.
+112.120.43.190.in-addr.arpa.
+www.mozilla.com.
+time.chttl.com.tw.
+twitter.com.
+190.241.94.86.in-addr.arpa.
+www.wwe.com.
+www.untreueteens.com.
+112.173.240.201.in-addr.arpa.
+photos-a.ak.fbcdn.net.
+www.johnsemper.com.
+cranepsych.edublogs.org.
+ib.adnxs.com.
+kote983vh.12dj.
+local-bay.contacts.msn.com.
+www.archizines.com.
+grijalva.house.gov.
+pyzizzle.com.
+tk2.greedland.net.
+developers.facebook.com.
+www.facebook.com.
+b._dns-sd._udp.lan.
+www.aapg.org.
+us-ads.openx.net.
+community.mtasa.com.
+google.com.
+boompa.ca.
+photos-d.ak.fbcdn.net.
+onevoicetech.com.
+242.79.14.187.in-addr.arpa.
+a2.mzstatic.com.
+pixel.invitemedia.com.
+1.0.0.127.dnsbugtest.1.0.0.127.in-addr.arpa.
+emkegroup.ae.s200a2.psmtp.com.
+profile.ak.fbcdn.net.
+eledoz.ru.
+connect.facebook.net.
+tap2-cdn.rubiconproject.com.
+tools.google.com.
+www.google-analytics.com.
+vivendiwater.com.
+ksn1-12-part1.kaspersky-labs.com.
+s.youtube.com.
+www.addthis.com.
+26.195.135.66.in-addr.arpa.
+mpp.cpii.com.
+116.52.50.190.in-addr.arpa.
+hotcd.ru.
+animeid.com.
+lesbians.ru.
+tdy.prodigy.msn.com.
+248.228.78.195.in-addr.arpa.
+i4.ytimg.com.
+a.root-servers.net.
+www.blogger.com.
+a.root-servers.net.
+checkout1.gulfnews.com.
+www.casapilo.es.
+246.216.127.84.in-addr.arpa.
+cdn.qbo.intuit.com.
+www.update.microsoft.com.
+teredo.ipv6.microsoft.com.
+a6.sphotos.ak.fbcdn.net.
+armmf.adobe.com.
+a.root-servers.net.
+www.automobilesnews.com.
+tinypic.com.
+b._dns-sd._udp.0.1.168.192.in-addr.arpa.
+s2.youtube.com.
+login.live.com.
+a5.sphotos.ak.fbcdn.net.
+servicemap.conduit-services.com.
+tetercon.com.
+s.youtube.com.
+mx3.mail.buffalo.edu.
+a.root-servers.net.
+sewintriguing.blogspot.com.
+careers.herbertsmith.com.
+idpfilm.com.s7a1.psmtp.com.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+dcsbiz.com.
+_ldap._tcp.
+www.cpxadspace.com.
+api.facebook.com.
+a1.sphotos.ak.fbcdn.net.
+kina.net.
+time.stdtime.gov.tw.
+www.facebook.com.
+ghostscript.cvs.sourceforge.net.
+.
+checkip.dyndns.org.
+245.2.139.187.in-addr.arpa.
+s-tet.ru.
+116.192.38.24.in-addr.arpa.
+tenibacgraphion-com.relay1a.spamh.com.
+mail.armoremont.ru.
+t2.gstatic.com.
+www.w3.org.
+googleads.g.doubleclick.net.
+photos-h.ak.fbcdn.net.
+forums.cnet.com.
+www.masaat.com.
+photos-d.ak.fbcdn.net.
+www.peliculas-flv.com.
+thefrogseyebrows.blogspot.com.
+51.236.74.201.in-addr.arpa.
+bin-short.whatsapp.net.
+ikekox.net.
+www.aada.org.ar.
+web-zc1.cityville.zynga.com.
+130.70.30.177.in-addr.arpa.
+no.travellerspoint.com.
+distilleryimage9.s3.amazonaws.com.
+medicina-primitiva.blogspot.com.
+_ldap._tcp.
+mail.harrybrowns.com.
+30-courier.push.apple.com.
+download116.avast.com.
+www.reydelospernos.cl.
+mail.nysaver.com.
+94.98.29.186.in-addr.arpa.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+_898_44_9.
+cbi-interiors.com.
+18-wheels-of-steel-extreme-trucker.en.softonic.com.
+s2.youtube.com.
+artegiron.com.
+msgr.zenfs.com.
+teredo.ipv6.microsoft.com.
+127.242.97.2.in-addr.arpa.
+photos-a.ak.fbcdn.net.
+interactbp.com.s8b2.psmtp.com.
+crl.verisign.com.
+ceptoplist.com.
+www.bestbuy.com.mx.
+s4i.histats.com.
+startv.mncdn.net.
+isco.co.jp.
+a6.sphotos.ak.fbcdn.net.
+lasletrasmudas.com.
+www.deliciousvinyl.com.
+48.107.242.189.in-addr.arpa.
+www.zynga.com.
+photos-a.ak.fbcdn.net.
+vms.msn.com.
+www.release.fr.
+static.ak.fbcdn.net.
+e5237.g.akamaiedge.net.
+video.msnbc.msn.com.
+gdata.youtube.com.
+www.alnetsito.blogspot.com.
+37.223.127.201.in-addr.arpa.
+mhome.live.com.
+dev.galleries.aebn.net.
+b._dns-sd._udp.0.1.168.192.in-addr.arpa.
+accounts.google.com.
+140.69.64.177.in-addr.arpa.
+74.79.178.190.in-addr.arpa.
+developers.facebook.com.
+cdn.mediafire.com.
+creative.ak.fbcdn.net.
+sp.cwfservice.net.
+jsrails.timeinc.net.
+254.82.130.189.in-addr.arpa.
+toscasatope.foro-espana.es.
+four-seasons-sunrooms.com.s7a2.psmtp.com.
+fr-fr.facebook.com.
+mail.florant.ru.
+spinworks.net.
+nbcpolitics.msnbc.msn.com.
+photos-g.ak.fbcdn.net.
+knoll.com.mail12.psmtp.com.
+www.baulsoft.com.
+cs10558.vkontakte.ru.
+img507.imageshack.us.
+it-it.facebook.com.
+www.google-analytics.com.
+geo.tp-cdn.com.
+196.101.152.201.in-addr.arpa.
+dns.msftncsi.com.
+sb-ssl.google.com.
+108.251.202.68.in-addr.arpa.
+29.221.141.201.in-addr.arpa.
+with-heart-and-hands.blogspot.com.
+oleg.lgg.ru.
+235.30.178.190.in-addr.arpa.
+sp.cwfservice.net.
+www.gstatic.com.
+privatemx.de.
+www.facebook.com.
+1s2qvh91x.site.aplus.net.
+photos-a.ak.fbcdn.net.
+connect.facebook.net.
+www.michaelpage.es.
+pki.dimc.dhs.gov.
+195.36.73.190.in-addr.arpa.
+i2.ytimg.com.
+translate.googleapis.com.
+www.musica21.net.
+media.admob.com.
+1.bp.blogspot.com.
+mail.ag-is.com.
+photos-e.ak.fbcdn.net.
+www.musicalion.com.
+ad.yieldmanager.com.
+a.root-servers.net.
+v5stats.windowsupdate.microsoft.com.
+a8.sphotos.ak.fbcdn.net.
+google.com.
+scholarshipfor.info.
+1314.qq.com.
+static.ak.fbcdn.net.
+westlakefg.com.
+kosa.baikal.ru.
+a.root-servers.net.
+wepales.subcultura.es.
+crl.godaddy.com.
+echonest.com.
+dns.msftncsi.com.
+image.tx.redbox.com.
+cpibeta.com.
+srv.main.ebayrtm.com.
+www.inmigracionmasiva.com.
+sp.cwfservice.net.
+services.conduit.com.
+www.canalesya.com.
+moderngrip.ru.
+a.root-servers.net.
+aeropostale.com.
+photos-g.ak.fbcdn.net.
+static.ak.fbcdn.net.
+www.hulkshare.com.
+photos-g.ak.fbcdn.net.
+a.root-servers.net.
+photos-a.ak.fbcdn.net.
+macrogroup.com.
+a5.sphotos.ak.fbcdn.net.
+tracker.keyscore.com.
+teredo.ipv6.microsoft.com.
+0.11-a30f1071.40081.1518.18a4.3ea1.210.0.kn9e331jip5d71gr69pjl3h56t.avqs.mcafee.com.
+111.127.123.189.in-addr.arpa.
+pixel.facebook.com.
+delta.
+sp.cwfservice.net.
+www.aspiremag.net.
+miencarnacion.blogspot.com.
+limeodyssey.aeriagames.com.
+www.belkin.com.
+a.root-servers.net.
+plusone.google.com.
+mail.doctormortgage.com.
+www.private2atp.com.
+www.googleadservices.com.
+poemasdelpurgatorio.blogspot.com.
+eckstein-audit.ru.
+ce.lijit.com.
+reviews.latam.kaspersky.com.
+cdn82.atkingdom-network.com.
+www.continental.com.ar.
+rakeandback.ru.
+papyrefb2.net.
+hornecpa.com.
+231.254.168.192.in-addr.arpa.
+e4414.b.akamaiedge.net.
+a3.sphotos.ak.fbcdn.net.
+www.explorergirls.com.
+google.com.
+www.mobilizacaocontramalaria.org.br.
+timesaversmed.com.
+ssl.gstatic.com.
+157.80.102.201.in-addr.arpa.
+i4.tagstat.com.
+112.79.186.189.in-addr.arpa.
+backroads.net.
+bin-short.whatsapp.net.
+aidps.atdmt.com.
+liveperson.com.
+inbound.orionires.com.netsolmail.net.
+render.talk4free.com.
+css.wlxrs.com.
+165.175.230.201.in-addr.arpa.
+mail.bakerbonnigson.com.
+ds.addthis.com.
+avimex.ru.
+www.juegosdepacman.com.
+www.sharpbyte.net.
+t1.gstatic.com.
+legalterms.cbsinteractive.com.
+67.16.57.186.in-addr.arpa.
+www.mandco.com.
+7ria5s3ix.u00w0o7d.
+smtp2.nwths.com.
+api.facebook.com.
+mts.silvinit.ru.
+ad.xtendmedia.com.
+a.root-servers.net.
+.
+www.elgrandesconocido.es.
+210.174.252.201.in-addr.arpa.
+docs.google.com.
+www.steadywebs.com.
+234.70.90.200.in-addr.arpa.
+126.26.88.87.in-addr.arpa.
+a.root-servers.net.
+www.windows7library.com.
+rcp2.us.blackberry.com.
+garden.ebay.com.
+bits.wikimedia.org.
+hippoinbox.com.
+d2096563.xoom.it.
+go.srvnow.com.
+www.wemadethis.co.uk.
+surbc.ru.
+www.facebook.com.
+asiaintheheart.blogspot.com.
+www.speedsupplies.com.
+a.root-servers.net.
+www.websitestatscounter.com.
+b._dns-sd._udp.0.1.168.192.in-addr.arpa.
+developers.facebook.com.
+google.com.
+openreach.com.
+moellendorf.com.
+88.75.55.50.in-addr.arpa.
+apacs3000.ru.
+www.modernwarfare3forum.com.
+feeds.mydtzone.com.
+cf2.msn.com.
+view.atdmt.com.
+tick.stdtime.gov.tw.
+tv.seoul.co.kr.
+196.234.39.190.in-addr.arpa.
+11.25.83.189.in-addr.arpa.
+cdn.g.promosrv.com.
+dns.msftncsi.com.
+71.104.18.186.in-addr.arpa.
+js.admeld.com.
+mail.s360-1.charter-business.net.
+www.civilica.com.
+mail1.adax.com.
+profile.ak.fbcdn.net.
+mailin-01.mx.aol.com.
+www.copib.es.
+243.118.54.95.in-addr.arpa.
+i1.ytimg.com.
+zeus.ccu.umich.mx.
+a.root-servers.net.
+6135.7370686f746f73.616b.666263646e.6e6574.80h41c5f429.webcfs00.com.
+www.citi.com.
+55.199.148.159.in-addr.arpa.
+cdn.nextcenturyproductions.com.
+mobilemaps.clients.google.com.
+103.120.54.86.cbl.abuseat.org.
+0-jg-w.channel.facebook.com.
+www.spainthenandnow.com.
+www.retailonlineintegration.com.
+a8.sphotos.ak.fbcdn.net.
+webcache.googleusercontent.com.
+vjf.com.
+www.myhomedeco.com.
+api-public.addthis.com.
+msgr.updates.yahoo.com.
+www.google-analytics.com.
+a7.sphotos.ak.fbcdn.net.
+www.badassjv.com.
+mexicotop.com.
+3pb4d3ci5.03sh.
+www.wdr2.de.
+178.228.37.178.in-addr.arpa.
+mobilecom.gmarket.co.kr.
+a.root-servers.net.
+60.29.42.83.in-addr.arpa.
+www.google.com.
+lh3.ggpht.com.
+ssl.gstatic.com.
+www.amervets.com.
+aapt.net.au.
+ads.yimg.com.
+76.150.149.187.in-addr.arpa.
+a1.sphotos.ak.fbcdn.net.
+www.gstatic.com.
+mail.skanska.co.uk.
+christina.com.
+u3gkf7ab4.c47m3r8i.
+v99apuynw.75ow.
+flavioluccisano.cghub.com.
+136.78.78.201.in-addr.arpa.
+www.facebook.com.
+google.com.
+code.jquery.com.
+a.root-servers.net.
+ar-ar.facebook.com.
+best-tattoo.gnug.us.
+206.33.174.118.in-addr.arpa.
+creative.ak.fbcdn.net.
+115.195.194.14.in-addr.arpa.
+bsgsearch.com.
+cx.sts.ru.
+207.123.92.186.in-addr.arpa.
+24.249.163.90.in-addr.arpa.
+a.root-servers.net.
+www.gleason.com.
+geoiplookup.wikimedia.org.
+kisul.wordpress.com.
+ad-g.doubleclick.net.
+conntest.nintendowifi.net.
+scopeo.usal.es.
+unifi.
+www.jovencitasa9euros.com.
+www.blogmisterios.com.
+www2.whitney36dd.com.
+wiesnergroup.com.
+83.34.105.187.in-addr.arpa.
+ns1.networklayer.com.
+es-la.facebook.com.
+teredo.ipv6.microsoft.com.
+www.cafepress.com.
+groups.google.com.mx.
+a.root-servers.net.
+www.asslickingmovies.net.
+30.21.185.203.in-addr.arpa.
+bmgcontracting.com.
+cinci.net.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+talkingblocks.com.
+fei9988.3322.org.
+187.91.87.108.in-addr.arpa.
+support.maktoob.com.
+inbound.ashburngroup.com.netsolmail.net.
+202.94.223.201.in-addr.arpa.
+i1.ytimg.com.
+62.232.191.186.in-addr.arpa.
+www.bigfoot4x4.com.
+pagead2.googlesyndication.com.
+census.pewsocialtrends.org.
+dr._dns-sd._udp.0.0.168.192.in-addr.arpa.
+creative.ak.fbcdn.net.
+time.chttl.com.tw.
+134.171.140.67.in-addr.arpa.
+scottbarnes.com.
+168.205.250.111.in-addr.arpa.
+emediawire.com.
+p07-contacts.icloud.com.
+exk7oqy5r.35tz.
+vipmutrpx001.tf1.fr.
+www.dico-definitions.com.
+rss.elmundo.es.
+mail.fstar.ru.
+www.facebook.com.
+comercial-lonco.blogspot.com.
+denis.stalker.h3q.com.
+moneycentral.msn.com.
+118.228.113.217.in-addr.arpa.
+fr-fr.facebook.com.
+i.ytimg.com.
+orcart.facebook.com.
+captainsof.com.
+www.iglesiabautistalagrancomision.com.
+123.82.0.190.in-addr.arpa.
+itunes.apple.com.
+224799.mimejorfrase2.info.
+213.139.176.190.in-addr.arpa.
+a1007.w43.akamai.net.
+mx.lumisys.com.
+117.247.1.181.in-addr.arpa.
+1.173.75.201.in-addr.arpa.
+fsarria.blogspot.com.
+www.quotesarena.com.
+pr.prchecker.info.
+kultmetro.ru.
+txu.ed.com.
+translate.google.com.
+geraxzz.blogspot.com.
+shared.live.com.
+pop.bogor.net.
+9.223.170.201.in-addr.arpa.
+www.adobe.com.
+www.municipios.com.mx.
+a3.sphotos.ak.fbcdn.net.
+www.charlottemagazine.com.
+185.132.91.76.in-addr.arpa.
+58.104.44.187.in-addr.arpa.
+stockindesign.com.
+plus.google.com.
+photos-d.ak.fbcdn.net.
+www.qaronline.org.
+dns.msftncsi.com.
+triplesphilippines.blogspot.com.
+162.86.54.189.in-addr.arpa.
+141.138.193.173.in-addr.arpa.
+www.blueaquarium.org.
+smx.twinwest.com.redcondor.net.
+ct.metrocast.net.
+pagead2.googlesyndication.com.
+gruporenacer.wordpress.com.
+195.23.75.201.in-addr.arpa.
+ss3.videosz.com.
+click.infospace.com.
+r12.lhr14g01.c.youtube.com.
+a.root-servers.net.
+r._dns-sd._udp.lan.
+pop.toserbayogya.com.
+www.ihsi.ht.
+rg-ap.ru.
+i-0.19-a30e0079.83.1518.19d4.3ea1.210.0.b8mvqdmsdsnmq1gtzs9ushe89q.avqs.mcafee.com.
+a.root-servers.net.
+s-static.ak.fbcdn.net.
+a1267.phobos.apple.com.
+dns.msftncsi.com.
+s-static.ak.fbcdn.net.
+_594_18_3.
+c.msn.com.
+likesfb.net.
+csi-las-vegas.seriespepito.com.
+dns.msftncsi.com.
+books.elsevier.com.
+static.ak.fbcdn.net.
+mymail.scc-fl.edu.
+apis.google.com.
+47.175.54.189.in-addr.arpa.
+secure-au.imrworldwide.com.
+a.root-servers.net.
+1.0.0.127.dnsbugtest.1.0.0.127.in-addr.arpa.
+lagaleriadelkuxo.blogspot.com.
+static.dealply.com.
+20.133.29.77.in-addr.arpa.
+72.219.160.189.in-addr.arpa.
+hirecounsel.com.s5b2.psmtp.com.
+108.65.122.187.in-addr.arpa.
+blog.python.org.
+chat.facebook.com.
+a1404.w41.akamai.net.
+time.chttl.com.tw.
+www.sulis.net.
+163.14.185.187.in-addr.arpa.
+5.62.242.99.in-addr.arpa.
+122.63.113.186.in-addr.arpa.
+apps.facebook.com.
+0.gravatar.com.
+231.68.166.190.in-addr.arpa.
+www.google.com.
+www.fastfivemovie.com.
+mail.live.com.
+developers.facebook.com.
+www.facebook.com.
+accfle.nl.
+ntp.glb.nist.gov.
+a.root-servers.net.
+tags.bluekai.com.
+nemesis.1337x.org.
+91.229.159.190.in-addr.arpa.
+67.147.58.186.in-addr.arpa.
+s.ytimg.com.
+static.hqtubexxx.com.
+www.youyube.com.
+peisys.net.
+ssl.google-analytics.com.
+.
+edge.quantserve.com.
+platform0.twitter.com.
+166.171.107.186.in-addr.arpa.
+imk.es.
+i.gismeteo.com.
+photos-a.ak.fbcdn.net.
+249.225.151.68.in-addr.arpa.
+239.82.220.189.in-addr.arpa.
+au.download.windowsupdate.com.
+profile.ak.fbcdn.net.
+config.conduitapps.com.
+48.112.219.81.in-addr.arpa.
+urs.microsoft.com.
+apis.google.com.
+118.69.105.190.in-addr.arpa.
+209.159.125.124.in-addr.arpa.
+snowcrst.net.
+22.123.210.112.in-addr.arpa.
+naughtyamericans.com.
+a2.sphotos.ak.fbcdn.net.
+rvwc.com.
+131.232.42.177.in-addr.arpa.
+105.191.82.190.in-addr.arpa.
+182.243.178.186.in-addr.arpa.
+livecams.vol.at.
+localhost.
+micaela-thesims3.blogspot.com.
+profile.ak.fbcdn.net.
+124.127.122.70.in-addr.arpa.
+176.165.178.190.in-addr.arpa.
+vn-media.s3.amazonaws.com.
+msk.rusmarine.ru.
+mail.blackseek.com.
+a2.sphotos.ak.fbcdn.net.
+es-es.facebook.com.
+mediaoutletonline.com.
+7.87.128.78.in-addr.arpa.
+oktopod.ru.
+www.lasrecetasdecocina.com.
+data.mobclix.com.
+catemaco.info.
+m.dk.pp.ru.
+blogs.ligasilverlight.com.
+b._dns-sd._udp.lan.
+safebrowsing-cache.google.com.
+webmail1.cps.k12.va.us.
+img851.imageshack.us.
+xsltcache.alexa.com.
+profile.ak.fbcdn.net.
+forums.toshiba.com.
+a.root-servers.net.
+dealhojaye.rediff.com.
+112.132.246.201.in-addr.arpa.
+autos.trovit.com.mx.
+www.pocketpcmag.com.
+a.root-servers.net.
+profile.ak.fbcdn.net.
+skins.gmodules.com.
+mx.elementstore.ru.
+www.natate.org.
+caseworkltd.com.s8b2.psmtp.com.
+mail.live.com.
+js.wlxrs.com.
+u20.eset.com.
+photos-b.ak.fbcdn.net.
+widgets.twimg.com.
+a.root-servers.net.
+thewhir.com.
+www.youtube.com.
+concordia-ny.edu.
+email-mx.baypointcorp.com.
+b._dns-sd._udp.lan.
+www.horsepowerfreaks.com.
+albaraqi.net.
+certrevoc.vo.msecnd.net.
+49.75.4.189.in-addr.arpa.
+g.ceipmsn.com.
+204.1.65.177.in-addr.arpa.
+224.71.209.201.in-addr.arpa.
+www.tilannehuone.fi.
+v6.nonxt3.c.youtube.com.
+governor.state.al.us.
+www.goojue.com.
+apple.com.
+storage.conduit.com.
+176.11.185.72.in-addr.arpa.
+euro.mediotiempo.com.
+36.222.113.186.in-addr.arpa.
+mx2.r-kh.ru.
+a8.sphotos.ak.fbcdn.net.
+toolbarqueries.google.com.
+yahoo.com.
+i4.ytimg.com.
+ad.doubleclick.net.
+photos-d.ak.fbcdn.net.
+toolbar.live.com.
+a.root-servers.net.
+sellstatenj.net.
+u01.gate01.com.
+creative.ak.fbcdn.net.
+yqeycyvfc.05zr.
+alltherage4u.blogspot.com.
+www.beatmybox.com.
+ad.auditude.com.
+db._dns-sd._udp.0.1.168.192.in-addr.arpa.
+p0b.ru.
+photos-f.ak.fbcdn.net.
+a5.sphotos.ak.fbcdn.net.
+euqvuzvufyvmssxg.com.
+blekko.com.
+flashresults.com.
+www.gatovolador.net.
+photos-a.ak.fbcdn.net.
+crest.tudou.com.
+a.root-servers.net.
+www.youtube.com.
+www.iplay.com.br.
+finance.my.freeze.com.
+oimg.nbcuni.com.
+safebrowsing-cache.google.com.
+zgfma1t88.11mz.
+ssl.gstatic.com.
+profile.ak.fbcdn.net.
+ingdirect.com.au.
+com-fallback.pandonetworks.com.
+81.10.168.192.in-addr.arpa.
+payload8.cargocollective.com.
+tile24.mqcdn.com.
+relay.vostok-invest.ru.
+69.164.156.82.in-addr.arpa.
+apk-prioritet.ru.
+static01.olx-st.com.
+www.casakeim.cl.
+dmail.cobaltgroup.com.
+www.productiveramadan.com.
+js.wlxrs.com.
+ticketmaster.com.mx.
+download338.avast.com.
+www.facebook.com.
+byfiles.storage.msn.com.
+www.testfreaks.com.pt.
+www.facebook.com.
+b-0.19-a309c009.8020580.1518.19d4.3ea1.410.0.kp16q82qf2989s62frjgvpw4pj.avqs.mcafee.com.
+83.98.200.88.in-addr.arpa.
+31.73.35.186.in-addr.arpa.
+pamjeshqiptare.com.
+b._dns-sd._udp.0.1.168.192.in-addr.arpa.
+mx.sincrono.it.
+a-0.19-21097081.d010583.1518.19d4.2f4a.210.0.qzzi6qttfmt4136j9flfm6aq7j.avqs.mcafee.com.
+mail.verizon.net.
+www.therioruminant.ulg.ac.be.
+www.nvnet.org.
+rs854dt.rapidshare.com.
+178.87.204.187.in-addr.arpa.
+gwde2.linde.com.
+a749.g.akamai.net.
+www.onyxcollection.com.
+veracruz.campusanuncios.com.mx.
+55.245.179.190.in-addr.arpa.
+creativecommons.org.
+24.117.60.78.in-addr.arpa.
+mail.yahoo.com.
+rt-soft.ru.
+www.gameportal.net.
+mail.sembutilities.co.uk.
+pixel.facebook.com.
+204.195.50.99.in-addr.arpa.
+www.danniesdesigns.com.
+s0.wp.com.
+www.gstatic.com.
+tourblackstone.com.
+www.fastbooking.co.uk.
+plus.google.com.
+unilever.com.
+plus.google.com.
+static.ak.fbcdn.net.
+www.tfg.com.
+www.facebook.com.
+google.com.
+117.203.26.80.in-addr.arpa.
+www.extremetube.com.
+fbcdn-photos-a.akamaihd.net.
+cgi.una.ac.cr.
+profile.ak.fbcdn.net.
+www.metacafe.com.
+www.youtube.com.
+heartbeat.belkin.com.
+a5.sphotos.ak.fbcdn.net.
+i1.ytimg.com.
+v17.nonxt8.c.pack.google.com.
+cdn1.inner-active.mobi.
+s440.photobucket.com.
+genderoutlaw.wordpress.com.
+bserver.npfszma.ru.
+www.gstatic.com.
+141.47.79.189.in-addr.arpa.
+ccb.edu.co.
+aprenspan.blogspot.com.
+138.39.86.186.in-addr.arpa.
+i2.ytimg.com.
+twenty04.com.
+43.101.140.187.in-addr.arpa.
+94.55.237.80.in-addr.arpa.
+116.231.240.189.in-addr.arpa.
+a.root-servers.net.
+a.root-servers.net.
+profile.ak.fbcdn.net.
+evrophone.ru.
+mail.collisiononwheels.com.
+hfry3pd5s.12dl.
+thehospital.bligoo.com.
+a8.sphotos.ak.fbcdn.net.
+ubuvepyn.etcampaigns.com.
+innovationliving.com.
+cdn.tynt.com.
+us.js.yimg.com.
+scholar.google.com.
+fr.astrology.yahoo.com.
+_918_80_5.
+clients2.google.com.
+38.101.0.123.in-addr.arpa.
+79.206.22.71.in-addr.arpa.
+83.65.72.189.in-addr.arpa.
+i4.ytimg.com.
+bauerpublishing.sl.advertising.com.
+hitsports.info.
+photos-a.ak.fbcdn.net.
+www-google-analytics.l.google.com.
+www.videoweed.es.
+sn1msg3020306.sn1.gateway.edge.messenger.live.com.
+.
+www.google.com.
+www.google.com.
+videotron.ca.
+35.10.168.192.in-addr.arpa.
+_ldap._tcp.
+www.google-analytics.com.
+i1.ytimg.com.
+a4.sphotos.ak.fbcdn.net.
+205.37.97.190.in-addr.arpa.
+emout11.mail.aol.com.
+www.fontifier.com.
+semeini.ru.
+www.livejasmin.com.
+darkenedcultuszepharis2.blogspot.com.
+230.141.153.201.in-addr.arpa.
+.
+mail.mpe.lv.
+26.161.7.58.in-addr.arpa.
+www.justintimberlake.com.
+scpet.net.
+he.y8.com.
+cs575.vk.com.
+s.youtube.com.
+best-toys-for-toddler.blogspot.com.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+images.thalia.de.
+167.207.83.189.in-addr.arpa.
+static.ak.fbcdn.net.
+www.solarturbines.com.
+t1.gstatic.com.
+search.ewebse.com.
+bs.serving-sys.com.
+ceradyne.com.s9a1.psmtp.com.
+x83xxsyua.i29u4v6u.
+plus.google.com.
+sterh.ru.
+uu4371ywt.14ip.
+dns.msftncsi.com.
+138.155.211.189.in-addr.arpa.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+etas.us.s201a1.psmtp.com.
+csi.gstatic.com.
+tobolsk.info.
+88.159.147.49.in-addr.arpa.
+86.41.53.186.in-addr.arpa.
+sanjudastadeo.foroactivo.com.
+b.scorecardresearch.com.
+www.touchmymelons.com.
+content.yieldmanager.edgesuite.net.
+www.topcatcomputing.com.
+pixel.facebook.com.
+ksn1-11-part1.kaspersky-labs.com.
+tic.sepdf.gob.mx.
+www.youtube.com.
+avis-moscow.ru.
+mclean.k12.ky.us.
+attglobal.com.lan.
+gateway.messenger.hotmail.com.
+9gag.com.
+174.1.168.192.in-addr.arpa.
+mail.ezcorp.com.
+www.vuelos-sevilla.es.
+hemeroteca.elimparcial.es.
+s.ytimg.com.
+www.usajordanshops.com.
+secure.wlxrs.com.
+smtp.abelia.ocn.ne.jp.
+www.amazon.com.
+buttholesandtoys.blogspot.com.
+www-open-opensocial.googleusercontent.com.
+gmx.gameduell.de.
+bugnbird.com.
+lxzh2wjil.r69b3e6k.
+a771.da1.akamai.net.
+www.motorsportinsurance.com.au.
+reckittcolman.com.
+www.gamert.nl.
+mx.lomsys.net.
+www.mab.com.au.
+107.66.43.62.in-addr.arpa.
+a.root-servers.net.
+photos-h.ak.fbcdn.net.
+imtgapp.com.
+a.root-servers.net.
+silverlight.dlservice.microsoft.com.
+static.ak.fbcdn.net.
+144.5.134.187.in-addr.arpa.
+www.aerochambervhc.com.
+ads.intergi.com.
+static.panoramio.com.
+_315_80_9.
+awesomebarnhart.wordpress.com.
+ads1.msads.net.
+any-fam.data.fy2.b.yahoo.com.
+m.addthisedge.com.
+consalting-secrets.ru.
+88.136.25.114.in-addr.arpa.
+safebrowsing-cache.google.com.
+data.mobclix.com.
+a1408.w43.akamai.net.
+a.root-servers.net.
+40.128.163.189.in-addr.arpa.
+hotmailhot.com.
+91.156.205.66.in-addr.arpa.
+photos-b.ak.fbcdn.net.
+www.google.com.
+teredo.ipv6.microsoft.com.
+eth0.
+a7.sphotos.ak.fbcdn.net.
+trophy.ww.np.community.playstation.net.
+177.228.197.46.in-addr.arpa.
+xslt.alexa.com.
+a3.sphotos.ak.fbcdn.net.
+i2.ytimg.com.
+www.audionur.com.
+83.210.73.69.in-addr.arpa.
+searchjs.s3.amazonaws.com.
+ct57f4z9b.07tb.
+help.social.ea.com.
+f21.360tag.com.
+www.care-et-entreprise.eu.
+www.macos.utah.edu.
+www.wwe.com.
+thematchettgroup.com.
+a.root-servers.net.
+hotmail.com.
+apis.google.com.
+ftp.lug.ro.
+i1av:1uho.46nq.
+3.139.159.94.in-addr.arpa.
+a6.sphotos.ak.fbcdn.net.
+www.google.com.
+a.root-servers.net.
+pfchre.co.zw.
+order.store.yahoo.net.
+photos-a.ak.fbcdn.net.
+mail.znaki-pr.ru.
+177.103.222.189.in-addr.arpa.
+svpeds.net.
+www.kvministries.com.
+bkktonight.com.
+www.circiruj.edilaser.net.
+72.30.229.189.in-addr.arpa.
+yojuegomagic.blogspot.com.
+shops.oscommerce.com.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+celebsforsale.files.wordpress.com.
+aixnet.com.
+www.fullpelis.com.
+ds.addthis.com.
+i3.ytimg.com.
+zbar2.zynga.com.
+profile.ak.fbcdn.net.
+113.203.237.81.in-addr.arpa.
+cwcapital.com.
+aladas-palabras.blogspot.com.
+204.225.195.187.in-addr.arpa.
+mxcluster2.tieto.com.
+sp.cwfservice.net.
+zm17aos3a.l15o7t7n.
+content.gamezer.com.
+content.yieldmanager.edgesuite.net.
+hi-in.facebook.com.
+97e1e8g68.e44h6x0w.
+http://google.com/.
+www.welovehappy.com.
+akamai.invitemedia.com.
+edge.quantserve.com.
+clients1.google.com.
+a8.sphotos.ak.fbcdn.net.
+www.giving.ox.ac.uk.
+entrevistas.sport.es.
+www.position-monitoring.de.
+s.ytimg.com.
+lhospitalarias.com.
+114.35.121.91.in-addr.arpa.
+login.yahoo.com.
+apis.google.com.
+del.icio.us.
+www.male-sexual-dysfunction.com.
+infomanspec.com.
+wwwimages.adobe.com.
+teredo.ipv6.microsoft.com.
+a.root-servers.net.
+img59.imageshack.us.
+pixel.facebook.com.
+9.178.51.190.in-addr.arpa.
+dns.msftncsi.com.
+photos-c.ak.fbcdn.net.
+teredo.ipv6.microsoft.com.
+5e2neyv9u.h79b0j1h.
+11.8.43.200.in-addr.arpa.
+242.26.231.201.in-addr.arpa.
+noticias.prodigy.msn.com.
+blogs.elcomercio.pe.
+cdn.applifier.com.
+www.paisajeculturalcafetero.org.co.
+17.242.58.83.in-addr.arpa.
+plusone.google.com.
+a-0.19-22098081.c0c0083.1518.19b2.410a.400.9d.qfptcsf437v6s7kaak2qs267pq.avqs.mcafee.com.
+nxcache.nexon.net.
+instagram.com.
+www.imdb.com.
+cdn1.techbang.com.tw.
+138.211.112.204.in-addr.arpa.
+plus.google.com.
+relay.voice.messenger.msn.com.
+mail.riverbluff.com.
+188.85.61.174.in-addr.arpa.
+www.komputronik.pl.
+a5.sphotos.ak.fbcdn.net.
+85.112.86.188.in-addr.arpa.
+stud.hib.no.
+mx.jobrapido.com.
+static.ak.fbcdn.net.
+vsofte.ru.
+www.google.com.
+15eb7bh0.aime5.eu.
+checkip.dyndns.org.
+landmarkcu.com.
+a5e327c6.linkbucks.com.
+188.177.249.115.in-addr.arpa.
+www.facebook.com.
+232.61.168.192.in-addr.arpa.
+www.factoriadoson.com.
+243.154.48.190.in-addr.arpa.
+96.171.158.200.in-addr.arpa.
+thumbs4.ebaystatic.com.
+clubs-kids.scholastic.co.uk.
+240.219.60.151.in-addr.arpa.
+apis.google.com.
+www.compumundo.com.ar.
+a1.sphotos.ak.fbcdn.net.
+mx3.hotmail.com.
+www.cdl55.com.
+nko88bgkb.t19z7h1t.
+a.root-servers.net.
+photos-d.ak.fbcdn.net.
+23k938zvm.k99d2w7z.
+198.225.23.186.in-addr.arpa.
+a3.sphotos.ak.fbcdn.net.
+www.mobile-free-calls.blogspot.com.
+94.220.227.71.in-addr.arpa.
+www.google.com.
+mail.atlasswitch.com.
+www.google-analytics.com.
+cox.net.
+firsthomemortgage.com.
+babader.com.
+creative.ak.fbcdn.net.
+103.250.131.187.in-addr.arpa.
+a8.sphotos.ak.fbcdn.net.
+227.131.141.190.in-addr.arpa.
+pixel.quantserve.com.
+myperfectgame.ru.
+choose-happiness.com.au.
+186.95.173.90.in-addr.arpa.
+static.ak.fbcdn.net.
+www.revistabuenasalud.com.
+www.unidad094.upn.mx.
+31.120.110.175.in-addr.arpa.
+troi.csw.net.
+222.120.40.177.in-addr.arpa.
+crary.com.s8b1.psmtp.com.
+photos-h.ak.fbcdn.net.
+ads.clicksor.com.
+ads.sonobi.com.
+gajigratis.com.
+a.root-servers.net.
+www.conduit.com.
+mobileeurope.co.uk.
+api.digitalhomeservices.yahoo.com.
+ssl.gstatic.com.
+gardenvariety.com.
+photos-b.ak.fbcdn.net.
+kamiahproperties.com.
+a7.sphotos.ak.fbcdn.net.
+173.135.26.174.in-addr.arpa.
+google.com.
+accounts.google.com.
+a1007.w43.akamai.net.
+msc.wlxrs.com.
+fotografiska.eu.
+mail.jsprinting.com.
+topshop.chtah.com.
+static.ak.fbcdn.net.
+www.insuagro.com.ar.
+photos-f.ak.fbcdn.net.
+asia.perf.glbdns.microsoft.com.
+a.root-servers.net.
+wpad.
+members.sneakypeek.net.
+mail.btinternet.com.
+edition.cn.
+a.root-servers.net.
+www.gravatar.com.
+s2.youtube.com.
+alame2009.pixnet.net.
+27.198.48.65.in-addr.arpa.
+google.com.
+twoomail.com.multi.surbl.org.
+x3wi43b7t.j25g9o0l.
+188.170.100.190.in-addr.arpa.
+www.google.com.
+100.127.109.85.in-addr.arpa.
+humblebundle.appspot.com.
+construction.kizifriv.com.
+52.197.106.89.in-addr.arpa.
+sites.google.com.
+cresswellservices.co.uk.
+www.floweroflife.org.
+images.google.com.
+mail3.xchanging.com.
+www.adobe.com.
+pagead2.googlesyndication.com.
+ese1.com.s9a2.psmtp.com.
+160.60.158.200.in-addr.arpa.
+www.google.com.
+drakausa.com.
+s-static.ak.fbcdn.net.
+tepic.olx.com.mx.
+gorx9395.files.wordpress.com.
+mail.yoursmilecenter.com.
+cs-g2-crl.thawte.com.
+yulianacreations.blogspot.com.
+b-0.19-a7063079.31002.1518.19bc.3ea1.210.0.qa7p2li2mpzdei6l82mr51e5mv.avqs.mcafee.com.
+www.google-analytics.com.
+dr._dns-sd._udp.0.0.168.192.in-addr.arpa.
+www.aseguratuauto.com.ar.
+tracker.thepiratebay.org.
+l.yimg.com.
+blog.joachim.at.
+eroticplanet.ru.
+clock.fmt.he.net.
+api-read.facebook.com.
+a7.sphotos.ak.fbcdn.net.
+forum.safecreative.net.
+reporting.fl.skype.net.
+googleads.g.doubleclick.net.
+www.tratamientohemorroidesefectivo.com.
+a.root-servers.net.
+runninglip.com.
+8.128.207.190.in-addr.arpa.
+gmail.ci.
+whos.amung.us.
+importnut.net.
+84.231.123.188.in-addr.arpa.
+0-271.channel.facebook.com.
+ssl.google-analytics.com.
+hsbc.com.hk.
+115.72.156.79.in-addr.arpa.
+219.119.170.72.in-addr.arpa.
+matcher.bidder8.mookie1.com.
+time.chttl.com.tw.
+static.ak.fbcdn.net.
+turkish.keyboard.su.
+mail.giv.it.
+es-la.facebook.com.
+s-static.ak.facebook.com.
+tierrainfinitaz.chatango.com.
+a.root-servers.net.
+www.facebook.com.
+www.yendit.com.
+161.42.59.82.in-addr.arpa.
+navidadd.com.
+img.youtube.com.
+all-kids.us.
+apkbank.ru.
+nodrivetime.com.
+brocktonautomile.com.
+testinfo007.blogspot.com.
+www.urbian.biz.
+www.laverdad.es.
+it-it.facebook.com.
+48.178.168.189.in-addr.arpa.
+external.ak.fbcdn.net.
+grafedia.net.
+s3.amazonaws.com.
+celulasabundancia.blogspot.com.
+www.facebook.com.
+a.root-servers.net.
+l.yimg.com.
+borovit.ru.
+ssl.gstatic.com.
+spiritually.com.
+download351.avast.com.
+www.youtube.com.
+plusone.google.com.
+fotografiaecuador.com.
+167.148.146.24.in-addr.arpa.
+ciudadanotasca.blogspot.com.
+92.54.192.190.in-addr.arpa.
+52.173.30.189.in-addr.arpa.
+open.spotify.com.
+battlefield-2142.en.softonic.com.
+dns.msftncsi.com.
+ocw.uniovi.es.
+profile.ak.fbcdn.net.
+a6.sphotos.ak.fbcdn.net.
+researchreports.sdcexec.com.
+ashtontechgroup.com.
+kulturmejeriet.se.
+plusone.google.com.
+a7.sphotos.ak.fbcdn.net.
+sac.gti.mcafee.com.
+data.tvdownload.microsoft.com.
+p07-contacts.icloud.com.
+buiembtyd.88ya.
+www.akm.com.
+www.toptanciyiz.net.
+ntp.glb.nist.gov.
+ceoiq.com.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+d2uukq5a8vhcuo.cloudfront.net.
+whos.amung.us.
+search.twitter.com.
+www.juegosagogo.com.
+kalachev.ru.
+www.alliedtime.com.
+support.google.com.
+61.127.10.189.in-addr.arpa.
+a.root-servers.net.
+smtp01.swisscenter.com.
+cdn-0.pics.dvdcdn.com.
+photos-c.ak.fbcdn.net.
+services.net.au.
+reddit.com.
+zh-cn.facebook.com.
+adpcos.com.
+tc.v3.cache4.c.youtube.com.
+a1.sphotos.ak.fbcdn.net.
+help.yahoo.com.
+8.154.243.201.in-addr.arpa.
+groups.google.com.mx.
+mcfarren-assoc.com.
+channing-t.com.
+librerias.idoneos.com.
+1.0.0.127.dnsbugtest.1.0.0.127.in-addr.arpa.
+alert.services.conduit.comalerts.
+145.18.57.187.in-addr.arpa.
+descargar.mp3.es.
+reelclipx.com.
+www.torrentrg.com.
+57.228.211.201.in-addr.arpa.
+buenosaires.evisos.net.
+udc.msn.com.
+i1.ytimg.com.
+151.44.173.190.in-addr.arpa.
+wpad.
+www.toxinology.com.
+cs9571.vkontakte.ru.
+v9.nonxt7.c.youtube.com.
+www.live.com.
+169.47.34.189.in-addr.arpa.
+117.111.83.75.in-addr.arpa.
+www.facebook.com.
+a3.sphotos.ak.fbcdn.net.
+36.196.143.187.in-addr.arpa.
+api.cbssports.com.
+teredo.ipv6.microsoft.com.
+at.atwola.com.
+www.reidsteel.aero.
+profile.ak.fbcdn.net.
+mail.tsibridges.com.
+mail.conmed.com.
+meritas.net.s5a2.psmtp.com.
+s.ytimg.com.
+a.root-servers.net.
+ksn4-12.kaspersky-labs.com.
+www.nokiakiller.com.
+ca.com.s9b1.psmtp.com.
+ci33hiu3l.c96u9z1g.
+twitter.com.
+img.babcdn.com.
+latino.msn.com.
+profile.ak.fbcdn.net.
+www.curr.it.
+a3.twimg.com.
+tc.v6.cache3.c.youtube.com.
+www.loocks.com.
+sde7a1j4m.55ic.
+a7.sphotos.ak.fbcdn.net.
+email.it.
+prowlapp.com.
+a.root-servers.net.
+bt.e-burg.org.
+yahoo.com.
+unifi.
+macdougalls.com.
+widgets.digg.com.
+a2.sphotos.ak.fbcdn.net.
+www.pixoto.com.
+123.217.92.75.in-addr.arpa.
+logv33.xiti.com.
+s.youtube.com.
+api.facebook.com.
+www.cwdkids.com.
+fbcdn-photos-a.akamaihd.net.
+backdoorjobs.com.
+fxfeeds.mozilla.com.
+mrb.mail.ru.
+66.99.164.67.in-addr.arpa.
+ipom.ru.
+photos-d.ak.fbcdn.net.
+cat.frivjuegos.info.
+dr._dns-sd._udp.home.
+b.scorecardresearch.com.
+content.yieldmanager.edgesuite.net.
+81.173.95.89.in-addr.arpa.
+www.jobstreet.com.my.
+fbcdn-profile-a.akamaihd.net.
+202.248.248.92.in-addr.arpa.
+i4.ytimg.com.
+www.m5zn.com.
+www.driftlive.com.
+download.paltalk.com.
+google.com.
+reddit.com.
+static.ak.fbcdn.net.
+mserver.etn.com.mx.
+u21.eset.com.
+a4.sphotos.ak.fbcdn.net.
+www.google-analytics.com.
+6j5oyw99u.n49e0t9j.
+8.mails4e.com.
+97.145.55.190.in-addr.arpa.
+254.200.65.190.in-addr.arpa.
+nemesis.1337x.org.
+a5.sphotos.ak.fbcdn.net.
+googleads.g.doubleclick.net.
+www.allsaints.com.
+campaign.constantcontact.com.
+a.root-servers.net.
+www.apple.com.
+175.114.83.200.in-addr.arpa.
+galleries.bunnygirlz.com.
+p.d.ovi.com.
+a4.sphotos.ak.fbcdn.net.
+wxdata.weather.com.
+71.23.149.98.in-addr.arpa.
+107.41.20.187.in-addr.arpa.
+payments.makemytrip.com.
+ns3.avira-ns.net.
+www.banamex.com.
+vonxfuupyyxino.org.
+www.missdriftedsnowwhite.com.
+www.update.microsoft.com.
+balu.us.
+a1003.w41.akamai.net.
+support.google.com.
+videos.drole.ch.
+api-public.addthis.com.
+onetidbit.wordpress.com.
+45.155.90.208.in-addr.arpa.
+ltd.br.dnsbl7.mailshell.net.
+www.myus.com.
+fbcdn-profile-a.akamaihd.net.
+irresistablefilms.com.
+uristspb.ru.
+intranet.adecco.com.mx.
+promedica.com.br.
+www.blackberry.com.
+97.49.186.201.in-addr.arpa.
+glimages.graphicleftovers.com.
+mail.moltoni.com.au.
+ocsp.digicert.com.
+mail.pofboxing.perm.ru.
+www.facebook.com.
+top100-images.rambler.ru.
+197.69.40.114.in-addr.arpa.
+128.19.237.78.in-addr.arpa.
+www.miguelcarrasco.net.
+beta.stun.voice.yahoo.com.
+101.252.168.78.in-addr.arpa.
+js1.infoseek.co.jp.
+35.39.157.189.in-addr.arpa.
+api.facebook.com.
+photos-e.ak.fbcdn.net.
+safebrowsing.clients.google.com.
+water.friv-y8.com.
+a.root-servers.net.
+crl3.digicert.com.
+external.ak.fbcdn.net.
+www.joshstrength.com.
+www.indiana.edu.
+mail.m-s.de.
+a1294.w20.akamai.net.
+proxy.yospb.yahoo.com.
+2.0.0.10.in-addr.arpa.
+api.facebook.com.
+_255_92_6.
+155.232.171.69.list.dsbl.org.
+i2.ytimg.com.
+mt1.google.com.
+87.124.141.69.in-addr.arpa.
+static.ifa.camads.net.
+www.eurocampings.es.
+nnov.ancor.ru.
+105.1.168.192.in-addr.arpa.
+a.root-servers.net.
+a.root-servers.net.
+mobileads.nimbuzz.com.
+pt-br.facebook.com.
+cf.addthis.com.
+xtra1.gpsonextra.net.
+allan-knox.com.
+227.201.49.85.in-addr.arpa.
+s-static.ak.fbcdn.net.
+www.bustyashlynnbrooke.com.
+125.102.202.125.in-addr.arpa.
+prodel.ru.
+dmgrealty.com.
+media.oh-barcelona.com.
+_233_86_3.
+www.afforums.com.
+photos-a.ak.fbcdn.net.
+viocast.net.
+jewelryconcepts.com.s7b1.psmtp.com.
+videos.flv2.redtubefiles.com.
+a6.sphotos.ak.fbcdn.net.
+www.drtuberpremium.com.
+cohutta.tdesystems.com.
+accounts.google.com.
+www.juntandocorazones.com.
+a.root-servers.net.
+affordablebusinesssystems.com.inbound15.mxlogic.net.
+www.vidz.com.
+4148091.frasesinolvidables1.com.ar.
+google.com.
+images.2.bangyoulater.com.
+ganemasociados.com.
+mitsubishi-forums.us.intellitxt.com.
+odisea.activoforo.com.
+mt1.googleapis.com.
+newhopetel.net.
+mh-mx1.onderwijsgroeptilburg.nl.
+s0.2mdn.net.
+161.adsina.allyes.com.
+www.tienda.telmex.com.
+www.jolintsai.net.
+www.msftncsi.com.
+fxfeeds.mozilla.com.
+accounts.google.com.
+www.y8.com.
+www.ortsbo.com.
+wls-mail.whitelodging.com.
+api.facebook.com.
+external.ak.fbcdn.net.
+ddserv.com.
+italianfarmacieonline.com.
+www.casaensamble.com.
+sparklepainting.com.
+loading1.widdit.com.
+player.slipstreamradio.com.
+ivxwk:zko.f28v1y3s.
+www.canidouafavor.com.
+seven.net.
+mail.waroundtable.com.
+2.211.141.201.in-addr.arpa.
+smtp.live.com.
+plus.google.com.
+a7.sphotos.ak.fbcdn.net.
+d2092558.xoom.it.
+rich.igg.com.
+ak.search.mywebsearch.com.
+ssl.google-analytics.com.
+www.bomc2.com.
+mail.carpentedil.com.
+proyectodocumenta.org.
+wmp.audible.com.
+api.conduit.com.
+otb-games.com.
+infonavitpuntos.net.
+112.12.252.189.in-addr.arpa.
+lb._dns-sd._udp.lan.
+b._dns-sd._udp.0.129.37.10.in-addr.arpa.
+mx.youtube.com.
+1.0.0.127.in-addr.arpa.
+_vlmcs._tcp.
+www.xstarsvod.com.
+switch.atdmt.com.
+mx2-exc.dgx.com.br.
+_140_36_2.
+130.10.174.190.in-addr.arpa.
+kleartextbook.com.
+ssl.gstatic.com.
+imzh.ru.
+225.100.40.178.in-addr.arpa.
+news.google.com.mx.
+llll.
+_208_51_6.
+www.google-analytics.com.
+www.filthcafe.com.
+verviers.lameuse.be.
+etrn.turk.net.
+249.144.73.189.in-addr.arpa.
+aweza.co.
+b._dns-sd._udp.0.1.168.192.in-addr.arpa.
+checkip.dyndns.org.
+1.77.176.187.in-addr.arpa.
+usea.org.
+hahnfamily.com.
+www.bioterraviva.com.
+233.132.62.189.in-addr.arpa.
+js.anonym.to.
+217.173.125.186.in-addr.arpa.
+www.powerhomepages.com.
+pap.wikipedia.org.
+a5.da1.akamai.net.
+.
+dimassimo.com.
+apple.com.
+www.radiozu.ro.
+a-0.19-23091081.c070083.1518.19d4.3ea1.210.0.4nckv22dv8e58ggm6pdvqgragj.avqs.mcafee.com.
+mainstreamp.com.
+www.googleadservices.com.
+jacksonville.com.
+ipowersolutions.net.s5b2.psmtp.com.
+a.root-servers.net.
+rincon-grafico.blogspot.com.
+a997.mm1.akamai.net.
+www.jazzpublishing.co.uk.
+developers.facebook.com.
+_886_50_8.
+dibels.org.
+apps.facebook.com.
+www.youtube-nocookie.com.
+.
+103.4.148.64.in-addr.arpa.
+www.bobsboots.com.
+197.167.98.87.in-addr.arpa.
+mail.systeminplace.net.
+a.root-servers.net.
+mxtls.expurgate.net.
+tools.google.com.
+clients1.google.com.
+xtn.net.mx2.jonesmedia.rcimx.net.
+profile.ak.fbcdn.net.
+levoyage.ru.
+www.zebra.com.
+photos-c.ak.fbcdn.net.
+teacherswithoutborders.org.
+kilikahechoamano.blogspot.com.
+noxius.wordpress.com.
+t0.gstatic.com.
+ec.atdmt.com.
+mansfeld.ipk-gatersleben.de.
+d2095607.xoom.it.
+www.msftncsi.com.
+vladasvet.ru.
+mkusdc.com.
+79.211.72.121.in-addr.arpa.
+a.root-servers.net.
+www.pianoaprimeravista.com.
+www.aswwaq.com.
+dl-client89.dropbox.com.
+smtp.omniprint.com.
+external.ak.fbcdn.net.
+ads.bluelithium.com.
+creative.ak.fbcdn.net.
+beybladebattles.hn.
+t2.gstatic.com.
+7.90.91.186.in-addr.arpa.
+www.facebook.com.
+105.17.156.190.in-addr.arpa.
+67.216.107.186.in-addr.arpa.
+a8.sphotos.ak.fbcdn.net.
+a.root-servers.net.
+enter.premium.moviebox.com.
+a.root-servers.net.
+84.107.127.201.in-addr.arpa.
+blog-albertosaez.blogspot.com.
+educaresensenaravivir.blogspot.com.
+34.153.0.88.in-addr.arpa.
+creative.ak.fbcdn.net.
+197.233.141.201.in-addr.arpa.
+dm-download02.mozilla.org.
+mail.woo-hoo.com.
+www.places-to-visit.co.uk.
+www.transalpworldtour.com.
+www.wweplus.net.
+adsm.gameforge.de.
+external.ak.fbcdn.net.
+www.33tres.com.
+a1.da1.akamai.net.
+epcs.com.
+a8.sphotos.ak.fbcdn.net.
+photos-a.ak.fbcdn.net.
+70.219.25.218.in-addr.arpa.
+wdmpyj.com.
+h3plus.uiuc.edu.
+150.69.104.95.in-addr.arpa.
+d2058412.instant.xoom.it.
+www.theradiancefoundation.org.
+webcache.googleusercontent.com.
+www.regnumchristi.org.
+ilovepoems.com.
+googleads.g.doubleclick.net.
+dl.com.
+a5.sphotos.ak.fbcdn.net.
+2fyfmek2w.51tg.
+www.facebook.com.
+mail.ksshp.fi.
+surftheplanet.com.
+creative.ak.fbcdn.net.
+235.243.63.92.in-addr.arpa.
+a3.sphotos.ak.fbcdn.net.
+accounts.google.com.
+collection.theaa.com.
+feeds.feedburner.com.
+piedrasenlavesicula.org.
+a.root-servers.net.
+i4.ytimg.com.
+partner.googleadservices.com.
+photos-e.ak.fbcdn.net.
+sky.geocities.jp.
+www.pensador.info.
+mchst.com.
+121.2.16.172.in-addr.arpa.
+richmond.craigslist.org.
+s-static.ak.fbcdn.net.
+mail.yimg.com.
+e1.mc1615.mail.yahoo.com.
+fonts.gawker.com.
+adelphia.net.
+orh.ch.
+a5.sphotos.ak.fbcdn.net.
+img.myfreecams.com.
+www.jesustebusca.com.ar.
+www.formula-romantica.com.
+www.worldtangsoodo.com.
+hurdrolland.co.uk.
+_640_41_4.
+.
+thrd.com.
+accounts.google.com.
+exclusivepress.net.
+s-static.ak.fbcdn.net.
+.
+id.wikipedia.org.
+135.215.240.201.in-addr.arpa.
+blogsoloeducacion.blogspot.com.
+external.ak.fbcdn.net.
+program.avast.com.
+t-online.de.
+accounts.google.com.
+us.bc.yahoo.com.
+usuarios.multimania.es.
+fbcdn-profile-a.akamaihd.net.
+api.recaptcha.net.
+i3.ytimg.com.
+i9.mangareader.net.
+b.scorecardresearch.com.
+ricercashopping.virgilio.it.
+brownchecco.com.
+mail.carsondixie.com.
+109.60.168.192.in-addr.arpa.
+photos-h.ak.fbcdn.net.
+l.yimg.com.
+c.msn.com.
+boysyes.blogspot.com.
+www.stats.gov.ck.
+p49-buy.itunes.apple.com.
+profile.ak.fbcdn.net.
+prod.support.belgacom.be.
+googleads.g.doubleclick.net.
+a.root-servers.net.
+apps.facebook.com.
+206.33.173.190.in-addr.arpa.
+www.mounteverest.net.
+www-akm.imvu.com.
+mail.vermilionriverrealty.com.
+sopris.net.
+www.myxboxspot.com.
+www.entrebits.com.
+profile.ak.fbcdn.net.
+download.live.com.
+api.webrep.avast.com.
+192.161.202.94.in-addr.arpa.
+www.sullysrants.com.
+www.consultoresvalencia.com.
+a.root-servers.net.
+www.banquemondiale.org.lbe.worldbank.org.
+grin.khv.ru.
+yui.yahooapis.com.
+univ.oryol.ru.
+www.google.com.
+www.sofitel.com.
+photos-h.ak.fbcdn.net.
+otcnet.org.
+www.antiqueswords.com.
+toolbarqueries.google.com.
+a.root-servers.net.
+static.ak.fbcdn.net.
+aplcenmp.apl.jhu.edu.
+s-static.ak.fbcdn.net.
+vp.sip.messenger.msn.com.
+imagen01.247realmedia.com.
+64.105.105.190.in-addr.arpa.
+superiortanklines.com.mx2.superiortanklines.rcimx.net.
+digitalmudstudio.com.
+www.iteracion.cl.
+wallpapers4iphone.net.
+248.52.124.201.in-addr.arpa.
+teknicote.com.s7b1.psmtp.com.
+a2.sphotos.ak.fbcdn.net.
+ad.yieldmanager.com.
+154.77.161.189.in-addr.arpa.
+skyder.ru.
+www.ankeligteringen.nl.
+46.116.161.190.in-addr.arpa.
+efgoze.com.
+mail.dfo.gov.ru.
+ts4.mm.bing.net.
+error.flashget.com.
+www.e-belis.com.
+photos-g.ak.fbcdn.net.
+news.google.es.
+abudhabienv.com.
+100.148.252.201.in-addr.arpa.
+flowhot.info.
+bitty.com.
+pt-br.facebook.com.
+es-la.facebook.com.
+112.54.156.187.in-addr.arpa.
+www.fmjfee.com.
+www.pillositio.com.
+_355_12_0.
+a1.twimg.com.
+73.0.175.190.in-addr.arpa.
+94.180.3.76.in-addr.arpa.
+dnl-08.geo.kaspersky.com.
+219.26.163.189.in-addr.arpa.
+rougehotel.com.inbound15.mxlogicmx.net.
+news.barrons.com.
+a.root-servers.net.
+qestest.com.
+pricepricemech.com.
+39.8.47.186.in-addr.arpa.
+a.root-servers.net.
+a6.sphotos.ak.fbcdn.net.
+u-tlnrn2o7o.clb1.com.
+sqm.microsoft.com.
+www.google-analytics.com.
+photos-g.ak.fbcdn.net.
+webcache.googleusercontent.com.
+sites.google.com.
+a.root-servers.net.
+www.vinosdeargentina.com.
+www.hispanicprblog.com.
+footysphere.com.
+asa-schalttechnik.de.
+m.shopeuro.angrybirds.com.
+www.latinlover.com.au.
+www.freakquotes.com.
+cf.addthis.com.
+cocinarparalosmios.blogspot.com.
+193.38.210.94.in-addr.arpa.
+197.152.143.201.in-addr.arpa.
+uponor.ru.
+ct.ebis.ne.jp.
+5.252.190.189.in-addr.arpa.
+43.203.176.190.in-addr.arpa.
+mail.bemco-ipp.com.
+bs.serving-sys.com.
+belleza.facilisimo.com.
+adin.com.
+caminoholistico-mabel.blogspot.com.
+mail.legalcolombia.com.
+xtremespeeds.net.home.
+3lbvurryv.91ot.
+images.instagram.com.
+geo.messenger.services.live.com.
+www.pixelradio.com.mx.
+www.biggercity.com.
+addon.onlinevideoconverter.com.
+y25aks6xm.68yt.
+www.truckads.com.
+secure.wlxrs.com.
+premieralliance.com.mx3.at-net.rcimx.net.
+suggestqueries.google.com.
+www.twitter.com.
+www.ach.com.
+acorn.org.
+mtalk.google.com.
+55.183.168.192.in-addr.arpa.
+safebrowsing-cache.google.com.
+relay.data.edge.messenger.live.com.
+www.youtube.com.
+246.25.93.186.in-addr.arpa.
+m.facebook.com.
+www.tattoofinder.com.
+www-us.softsalad.com.
+peliculasonline2.com.
+ad-emea.doubleclick.net.
+www.unefilledulimmatquai.ch.
+www.bondagedesigns.com.
+mail.scrtc.com.
+pagead2.googlesyndication.com.
+www.prettyteenpictures.com.
+free-ebook-download-links.blogspot.com.
+twitter.com.
+checkip.dyndns.org.
+www.arcelormittal.tv.
+profile.ak.fbcdn.net.
+profile.ak.fbcdn.net.
+newtab.conduit-hosting.com.
+i4.ytimg.com.
+qu.wikipedia.org.
+www.facebook.com.
+palabradeclio-mepi.blogspot.com.
+www.youtube.com.
+www.facebook.com.
+www.google-analytics.com.
+89.71.55.65.in-addr.arpa.
+platform.stumbleupon.com.
+profile.ak.fbcdn.net.
+wps-dfp.com.
+www.hp.com.
+map.media6degrees.com.
+easy-google-search.blogspot.com.
+cs4341.vkontakte.ru.
+om.recruit.net.
+5-courier.push.apple.com.
+0-74.channel.facebook.com.
+by161w.bay161.mail.live.com.
+184.162.50.66.in-addr.arpa.
+www.balivillapoint.com.
+9gag.com.
+192.36.155.122.in-addr.arpa.
+a1737.g.akamai.net.
+speedtest.tune-up.com.
+a.root-servers.net.
+time.apple.com.
+a209.phobos.apple.com.edgesuite.net.
+www.googleadservices.com.
+gfx1.hotmail.com.
+www.mindeporte.gob.ve.
+163.27.7.189.in-addr.arpa.
+_772_41_0.
+218.36.155.189.in-addr.arpa.
+cf.addthis.com.
+www.icap.org.
+fbcdn-photos-a.akamaihd.net.
+a.root-servers.net.
+comcluster.cxense.com.
+g.ceipmsn.com.
+photos-e.ak.fbcdn.net.
+android.clients.google.com.
+acetec.com.mx.
+\(none\).
+www.youtube-nocookie.com.
+210.43.255.201.in-addr.arpa.
+87.57.238.166.in-addr.arpa.
+a6.sphotos.ak.fbcdn.net.
+mob.adwhirl.com.
+nww6j6151.60lh.
+ytimg.l.google.com.
+a.root-servers.net.
+158.42.192.190.in-addr.arpa.
+la.wikipedia.org.
+download304.avast.com.
+www.freerealms.com.
+box582.bluehost.com.
+i1b95ewnr.33en.
+www.alejandronogueira.com.
+filter1.lach.net.
+cameronparkcc.com.
+photos-e.ak.fbcdn.net.
+sfo.sysco.com.
+a14.t26.net.
+www.movieposteraddict.com.
+www.lair2000.net.
+ajax.googleapis.com.
+mail.yahoo.com.
+a1294.w20.akamai.net.
+a5.sphotos.ak.fbcdn.net.
+images04.olx.com.
+actife.com.
+safebrowsing.clients.google.com.
+ksn1-12-part2.kaspersky-labs.com.
+us.social.s-msn.com.
+uu1.orbitdownloader.com.
+download.windowsupdate.com.
+photos-a.ak.fbcdn.net.
+www.google.com.
+pt-br.facebook.com.
+js2.wlxrs.com.
+45.85.188.189.in-addr.arpa.
+newsrss.bbc.co.uk.
+download-akm.skype.com.
+sp.ask.com.
+sp.cwfservice.net.
+a1.sphotos.ak.fbcdn.net.
+riskyregencies.blogspot.com.
+accountservices.msn.com.
+www.y8.com.
+encuentromegaproyectosymineria.blogspot.com.
+a.root-servers.net.
+_965_19_2.
+il-solito-potere.blogspot.com.
+www.janes-kitchen-table.co.uk.
+pagead2.googlesyndication.com.
+a.root-servers.net.
+a7.sphotos.ak.fbcdn.net.
+scribe.twitter.com.
+www.tusletras.com.
+ws-cloud-msgplus.linkury.com.
+mail.dariusunrise.com.
+_859_19_7.
+ntp.glb.nist.gov.
+colstb.msn.com.
+50.4.204.190.in-addr.arpa.
+169.77.194.108.in-addr.arpa.
+gmpcompanies.com.
+guitar.nmts.ru.
+30.192.2.201.in-addr.arpa.
+au.download.windowsupdate.com.
+openxfront.iminent.com.
+youtu.be.
+229.101.15.88.in-addr.arpa.
+photos-e.ak.fbcdn.net.
+45.65.32.196.in-addr.arpa.
+www.usp.com.au.
+blogs.microsoftvip.net.
+webcache.googleusercontent.com.
+sn3.mailshell.net.
+relay.voice.messenger.msn.com.
+405.webim0268.webim.myspace.com.
+jooble-br.com.
+plantasdeacuarios.com.
+s7.addthis.com.
+r._dns-sd._udp.0.55.211.10.in-addr.arpa.
+235.8.55.157.in-addr.arpa.
+_696_50_5.
+login.live.com.
+mobile.inova.si.
+www.lwflowers.com.
+www.jhj-consultancy.com.
+205.28.215.186.in-addr.arpa.
+graco.112.2o7.net.
+23.196.124.186.in-addr.arpa.
+mail.solve.net.
+jacaro.es.
+app.appatyze.com.
+a.root-servers.net.
+a3.sphotos.ak.fbcdn.net.
+a6.sphotos.ak.fbcdn.net.
+b3ck.blogspot.com.
+blog.es.twitter.com.
+maps.google.com.mx.
+msainc.us.
+www.music4games.net.
+time.windows.com.
+yo-conmigo.blogspot.com.
+lb._dns-sd._udp.lan.
+63.51.152.189.in-addr.arpa.
+pascual.com.mx.
+ad-apac.doubleclick.net.
+photos-g.ak.fbcdn.net.
+fntp.fr.
+a.root-servers.net.
+www.fwol.cn.
+.
+ec.atdmt.com.
+mail.ppcse.ru.
+www.google.com.
+b2p1anxd4.05ab.
+a1170.g.akamai.net.
+planetek.it.
+www.yaelsyummies.blogspot.com.
+adspaces.ero-advertising.com.
+a4.sphotos.ak.fbcdn.net.
+www2.cinetux.org.
+domino.harrassowitz.de.
+by2msg4020715.gateway.messenger.live.com.
+www.mini01.com.
+post.sotcom.ru.
+brilliantvoices.com.
+media.winamp.com.
+www.sqm.microsoft.com.
+a.ads2.msads.net.
+vp.sip.messenger.msn.com.
+networkworld.com.
+mistermaid.com.
+aide.livenet.fr.
+www.facebook.com.
+6f74db9c.filesonthe.net.
+254.19.145.78.in-addr.arpa.
+dudnyk.com.
+mail001.uniquemail.com.
+api.facebook.com.
+www.hammdann.net.
+96.148.59.199.in-addr.arpa.
+buildingcolorado.com.
+s-static.ak.fbcdn.net.
+77.10.26.83.in-addr.arpa.
+43.217.6.88.in-addr.arpa.
+by2msg3020417.gateway.messenger.live.com.
+p6y.ru.
+www.customgraffiti.net.
+liero.it.
+webres3.bullguard.ctmail.com.
+becauseiamagirl.ca.
+27-courier.push.apple.com.
+safebrowsing.clients.google.com.
+www.magictoolbox.com.
+84.106.229.71.in-addr.arpa.
+re-board.ru.
+io.bucyrus.cl.
+afiliados-natural.com.s108-67.furanet.com.
+external.ak.fbcdn.net.
+www.facebook.com.
+www.out-there.com.
+compras.periodistadigital.com.
+platform.twitter.com.
+cuanta-alegria-en-vidoes.blogspot.co.nz.
+live-ciner.mncdn.net.
+recetasdelaabuela.blogia.com.
+developers.facebook.com.
+www.onlineslotsentertainment.com.
+mx2.iweb.com.
+233.253.215.207.in-addr.arpa.
+www.nicosia.sgul.ac.cy.
+cdn.api.twitter.com.
+dulcelife.com.
+_336_36_1.
+sharphomeloans.com.
+ksn4-12.kaspersky-labs.com.
+gotovaja-rabota.ru.
+www.myspace.com.
+mta6.am0.yahoodns.net.
+s-external.ak.fbcdn.net.
+ns.r-style.ru.
+maps.googleapis.com.
+cri.crinet.com.
+136.89.75.190.in-addr.arpa.
+www.google.com.
+www.osirisibiza.com.
+halo-zero.softonic.com.
+eo-eo.facebook.com.
+partner.googleadservices.com.
+www.itsthecat.com.
+a6.sphotos.ak.fbcdn.net.
+www.mobileelements.com.
+www.pelo10.com.
+s-external.ak.fbcdn.net.
+db._dns-sd._udp.lan.
+www.morhipo.com.
+s.ccdn.ur-img.com.
+30.246.166.189.in-addr.arpa.
+aspweb.gslb.monster.com.
+www.gruposancorseguros.com.
+42.244.9.65.in-addr.arpa.
+www.litainete.lt.
+fbcdn-sphotos-a.akamaihd.net.
+orkut.com.
+68.171.13.187.in-addr.arpa.
+messenger.hotmail.com.
+a.root-servers.net.
+lemonodor.com.
+233.112.53.60.in-addr.arpa.
+free-php.net.ru.
+a.root-servers.net.
+www.elpalaciodehierro.com.mx.
+150.2.132.189.in-addr.arpa.
+im1.garenaconnect.com.
+pop3.hot.glbdns.microsoft.com.
+99.118.1.201.in-addr.arpa.
+artofflight-contest.fr.
+bachelorgirl.zzn.com.
+www.systems-biology.org.
+ib.adnxs.com.
+georgiabulletin.org.
+img3.pcpop.com.
+magrec.de.
+larcoco.wordpress.com.
+97.211.127.201.in-addr.arpa.
+capital-funding.com.
+a3.sphotos.ak.fbcdn.net.
+elizabethmelendez.com.
+alteks-servis.com.
+www.generadordenicks.com.
+sevenstar.spb.ru.
+singularlabs.com.
+www.tarot-numerologie.fr.
+lxt.com.
+mail.
+32.122.18.95.in-addr.arpa.
+www.olga-kurylenko.net.
+a.root-servers.net.
+b.scorecardresearch.com.
+a5.sphotos.ak.fbcdn.net.
+103.237.252.186.in-addr.arpa.
+a3.sphotos.ak.fbcdn.net.
+sp.cwfservice.net.
+photos-d.ak.fbcdn.net.
+chile.infomine.com.
+pixel.facebook.com.
+jenniferdelonge.tumblr.com.
+creative.ak.fbcdn.net.
+i1.ytimg.com.
+236.223.135.189.in-addr.arpa.
+vqu9:dodh.r57s2x9f.
+d2103197.xoom.it.
+254.234.254.190.in-addr.arpa.
+6uz6psorh.61il.
+highlandsinsurance.com.
+78.145.109.62.in-addr.arpa.
+js.dmtry.com.
+download339.avast.com.
+mystart.incredibar.com.
+i3.ytimg.com.
+www.pokeyplay.com.
+bmx.onxlti.com.redcondor.net.
+61.160.209.201.in-addr.arpa.
+www.dickinsonstate.edu.
+static.ak.facebook.com.
+238.29.116.174.in-addr.arpa.
+r.turn.com.
+plusone.google.com.
+www.agiletelecom.com.
+a995.mm1.akamai.net.
+163.42.140.89.in-addr.arpa.
+ece.ucdavis.edu.
+www.google.com.
+www.photomediashop.com.
+teredo.ipv6.microsoft.com.
+news.google.com.
+youtube-ui.l.google.com.
+www.descomsms.com.
+update.epyte.com.
+hotleathers.com.s9b2.psmtp.com.
+isatap.swdl.com.
+mediashifting.com.
+a8.sphotos.ak.fbcdn.net.
+download-soft.ru.
+14.229.152.187.in-addr.arpa.
+graph.facebook.com.
+ihl.state.ms.us.
+gamelux.ru.
+gnguttrnc.61uh.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+google-analytics.com.
+a.root-servers.net.
+a3.da1.akamai.net.
+59.21.254.201.in-addr.arpa.
+www.jcortazar.udg.mx.
+walgreens.vo.llnwd.net.
+a.root-servers.net.
+static.ak.fbcdn.net.
+33.117.200.190.in-addr.arpa.
+photos-f.ak.fbcdn.net.
+webcache.googleusercontent.com.
+156.226.35.187.in-addr.arpa.
+www.fuelcells.us.
+95.11.243.189.in-addr.arpa.
+171.8.76.188.in-addr.arpa.
+cdn-static.liverail.com.
+89.152.99.213.in-addr.arpa.
+translate.google.com.mx.
+214.190.241.201.in-addr.arpa.
+es.noticias.yahoo.com.
+dns.msftncsi.com.
+a3.sphotos.ak.fbcdn.net.
+www.youtube.com.
+m.facebook.com.
+dns.msftncsi.com.
+archive.rec.org.
+130.210.138.189.in-addr.arpa.
+shiroin.deviantart.com.
+204.191.214.186.in-addr.arpa.
+docs.google.com.
+39.197.250.189.in-addr.arpa.
+tools.google.com.
+_503_33_5.
+livejournalgaua.hit.gemius.pl.
+g.ceipmsn.com.
+124.221.124.189.in-addr.arpa.
+time.chttl.com.tw.
+db._dns-sd._udp.0.0.168.192.in-addr.arpa.
+tracker.openbittorrent.com.
+www.fujifilm.eu.
+www.youtube.com.
+mail.izreps.com.
+4thletter.net.
+220.144.162.112.in-addr.arpa.
+mtalk.google.com.
+ajax.googleapis.com.
+accounts.google.com.
+131.22.55.190.in-addr.arpa.
+www.mardev.com.au.
+204.169.250.201.in-addr.arpa.
+s2.youtube.com.
+e3191.c.akamaiedge.net.
+googleads.g.doubleclick.net.
+a.root-servers.net.
+a.root-servers.net.
+on.fb.me.
+mailwash46.pair.com.
+pccbs8i93.k35m2u0m.
+dibujandosonrisas.blogspot.com.
+178.137.255.83.in-addr.arpa.
+developers.facebook.com.
+.
+swarthmore.edu.
+falconvision.ru.
+www.editorialmerial.es.
+205.26.43.201.in-addr.arpa.
+www.trucoteca.com.
+vwsouth.com.
+www.hiderefer.com.
+www.facebook.com.
+mail.ugvclmail.com.
+www.toptyt.com.
+www.eset-la.com.
+purchase.mydirtyhobby.com.
+db._dns-sd._udp.0.0.168.192.in-addr.arpa.
+hp.zumodrive.com.
+hr.pce-group.com.
+www.facebook.com.
+windeslive.com.
+12.81.66.190.in-addr.arpa.
+213.190.54.65.zen.spamhaus.org.
+a8.sphotos.ak.fbcdn.net.
+centralizedlab.com.
+api.gamatar.org.
+conn.skype.com.
+79.169.160.189.in-addr.arpa.
+a3.da1.akamai.net.
+media.columbiamissourian.com.
+r._dns-sd._udp.lan.
+www.google.com.
+rs1.scribd.com.
+nasch-chat.ru.
+244.232.26.85.in-addr.arpa.
+www.losmejoresvideosdeinternet.net.
+www.romacess.com.
+a1957.da1.akamai.net.
+static.ak.fbcdn.net.
+c13.zedo.com.
+190.68.173.190.in-addr.arpa.
+connect.facebook.net.
+mjqwmtiwmtia.info.
+dvd.box.sk.
+82.85.164.189.in-addr.arpa.
+bank10.mi.ads.mp.mydas.mobi.
+mail.htc.nett.
+download712.avast.com.
+a1.sphotos.ak.fbcdn.net.
+webcache.googleusercontent.com.
+199.96.172.201.in-addr.arpa.
+checkip.dyndns.org.
+photobucket.com.
+greenfieldpro.com.
+dispatch.lite.adlesse.com.
+distilleryimage10.instagram.com.
+p04-fmfmobile.icloud.com.akadns.net.
+creareconilcuore.blogspot.com.
+35.28.94.186.in-addr.arpa.
+www.facebook.com.
+quintess.com.inbound15.mxlogic.net.
+sup.live.com.
+db._dns-sd._udp.0.0.168.192.in-addr.arpa.
+jsbin.tumblr.com.
+senderra.com.
+u24.eset.com.
+en-us.fxfeeds.mozilla.com.
+miscritscdn.brokenbulbstudios.com.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+b-0.19-2305f479.8030081.1518.19d3.3ea1.210.0.h16pz26nu19r8ezkn3t14c9lli.avqs.mcafee.com.
+ibizabeatreview.podbean.com.
+photos-f.ak.fbcdn.net.
+blazemail.com.
+r.turn.com.akadns.net.
+143.139.229.77.in-addr.arpa.
+www.ricardosalinas.com.
+karelia-granit.ru.
+a8.sphotos.ak.fbcdn.net.
+a.root-servers.net.
+www.facebook.com.
+142.8.17.190.in-addr.arpa.
+165.22.82.62.in-addr.arpa.
+191.192.194.117.in-addr.arpa.
+www.paypalbisnis.com.
+a1.sphotos.ak.fbcdn.net.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+axa-sunlife.co.uk.
+a.root-servers.net.
+altfarm.mediaplex.com.
+www.crunchbase.com.
+newtscape.com.
+platform.twitter.com.
+151.153.101.118.in-addr.arpa.
+photos-b.ak.fbcdn.net.
+developers.facebook.com.
+45.241.155.72.in-addr.arpa.
+_417_71_1.
+crl.microsoft.com.
+239.247.141.201.in-addr.arpa.
+www.bbc.co.uk.
+amsprd0104.outlook.com.
+203.33.168.192.in-addr.arpa.
+mx.procilia.com.
+oboedit.org.
+pablo-javier-perez-fuentes.suite101.net.
+talongroup.biz.
+used.guitarcenter.com.
+a.root-servers.net.
+iad09s10.iad09s11.iad09s14.iad09s15.iad09s16.iad09s17.iad09s20.iad09s21.o-o.v2.lscache6.c.youtube.com.
+_114_92_8.
+fusion.google.com.
+fbcdn-profile-a.akamaihd.net.
+254.83.186.190.in-addr.arpa.
+a6.sphotos.ak.fbcdn.net.
+www.decolar.com.
+mapscroll.blogspot.com.
+static-0.farmville.zgncdn.com.
+logictel.ru.
+tracking.novem.pl.
+baysidecontractors.com.
+profile.ak.fbcdn.net.
+todointeresante.wordpress.com.
+ping3.teamviewer.com.
+.
+developers.facebook.com.
+media.admob.com.
+toolbarqueries.google.com.
+studyworld.us.intellitxt.com.
+212.93.44.190.in-addr.arpa.
+relay2.sitel.com.ua.
+www.avisooportuno.mx.
+250.147.209.39.in-addr.arpa.
+tvmax-9.com.
+teredo.ipv6.microsoft.com.
+www.historiasdechile.cl.
+safebrowsing.clients.google.com.
+www.update.microsoft.com.
+89.80.198.190.in-addr.arpa.
+meridiem91.blogspot.com.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+7.6.107.186.in-addr.arpa.
+www.wikio.es.
+omniamerican.org.
+129.18.28.98.in-addr.arpa.
+us.blackberry.com.
+berniekeating.com.
+www.gmail.com.
+mail.proviewrussia.ru.
+clock.nyc.he.net.
+glb-ads.intergi.adtechus.com.
+100.98.157.189.in-addr.arpa.
+rcp.na.blackberry.com.
+xzn8e9tc2.y47u6p1u.
+www.facebook.com.
+www.celebuzz.com.
+a-0.19-a309d000.130092.1518.19d4.3ea1.210.0.cvtecms8k26gt7dsd4f6hnaeht.avqs.mcafee.com.
+apps.facebook.com.
+captcha.chat.yahoo.com.
+eqxe7nppd.53fx.
+mail.google.com.
+mscrl.microsoft.com.
+www.starnow.ie.
+malakhov.spb.su.
+wombat.nen-inc.com.
+75.10.85.186.in-addr.arpa.
+ds.serving-sys.com.
+lucyhaleweb.org.
+236.32.34.187.in-addr.arpa.
+visitarmexico.net.
+top.amateuralbum.net.
+artidd.com.
+www.netgear.com.
+accidentalmommies.com.
+aux.planetmath.org.
+www.neruda.cl.
+a6.sphotos.ak.fbcdn.net.
+mail.google.com.
+tbr.ask.com.
+sdbs.adb.org.
+www.rabobank.jobs.
+plus.google.com.
+cdn.fastclick.net.
+profile.ak.fbcdn.net.
+www.pacoelviraenglish.blogspot.com.
+marketplace.honda-tech.com.
+www.facebook.com.
+edge.bredg.com.
+mx1c11.megamailservers.com.
+ballingerpublishing.com.1.arsmtp.com.
+.
+cf.cgl.com.
+csi.gstatic.com.
+fujitsugeneral.com.au.
+a.root-servers.net.
+ns3.mgn.net.
+www.aquariuscasinoresort.com.
+il06edm06.corp.mot.com.
+www.leisuretown.com.
+6.125.252.46.in-addr.arpa.
+m.xp1.ru4.com.
+tracking.batanga.com.
+miis.edu.ru.
+csi.gstatic.com.
+lovelineshow.com.
+lost.seriesasd.com.
+dtboot.orbitdownloader.com.
+86.117.19.177.in-addr.arpa.
+134.61.194.68.in-addr.arpa.
+assets2.helium.com.
+pbelec.com.
+a.root-servers.net.
+time.windows.com.
+apis.google.com.
+external.ak.fbcdn.net.
+img100.xvideos.com.
+zyryanov.ru.
+external.ak.fbcdn.net.
+85.71.27.108.in-addr.arpa.
+tudvdrip.blogspot.com.
+casalelizrodri.blogspot.com.
+30.media.tumblr.com.
+www.vintageprojects.com.
+mail-2.diabet-news.ru.
+wer.microsoft.com.
+loto.scn.ru.
+tools.google.com.
+www.thepier.org.
+images04.olx-st.com.
+81.185.15.180.in-addr.arpa.
+r._dns-sd._udp.lan.
+con8sylo6.q08v3j2n.
+faqa.net.
+mx.answers.yahoo.com.
+db._dns-sd._udp.0.147.168.192.in-addr.arpa.
+www.extremetube.com.
+photos-g.ak.fbcdn.net.
+img6.planetadelibros.com.
+d2092951.xoom.it.
+123.180.138.190.in-addr.arpa.
+instagr.am.
+s-translate.ru.
+sc.sweetim.com.
+60.1.1.10.in-addr.arpa.
+ads.contentabc.com.
+hearth.is.
+38.143.25.201.in-addr.arpa.
+www.hermesmedical.com.
+teolatosno.ru.
+video.xnxx.com.
+254.66.61.189.in-addr.arpa.
+ad.doubleclick.net.
+birch.ssec.wisc.edu.
+b.scorecardresearch.com.
+www.star-advertising.com.
+profile.ak.fbcdn.net.
+upload.streamzoo.com.
+www.ebaybag.com.
+mail.informedx.com.
+www.anunciadero.com.
+juridicosonline.bligoo.com.
+themasterstouch.com.
+54.248.222.189.in-addr.arpa.
+202.29.36.186.in-addr.arpa.
+www.imperialinnovations.co.uk.
+www.davidtutera.com.
+www.girlsgogames.ru.
+www.facebook.com.
+dr._dns-sd._udp.0.101.168.192.in-addr.arpa.
+s0.uvnimg.com.
+db8.net-filter.com.
+www.bmwra.org.
+mail.google.com.
+sites.google.com.
+www.whoisthisphone.com.
+api.pixel-mags.com.
+teredo.ipv6.microsoft.com.
+116.54.226.189.in-addr.arpa.
+photos-e.ak.fbcdn.net.
+photos-h.ak.fbcdn.net.
+st.oros.karelia.ru.
+164.8.0.10.in-addr.arpa.
+nimir.com.
+169796.frases10.info.
+7pcl2kcwo.o53j1c5j.
+zgn.static.zynga.com.
+s10.histats.com.
+i818.photobucket.com.
+plus.google.com.
+ic.tynt.com.
+ar-ar.facebook.com.
+shop.ebay.com.
+3cp9lcoq32dpn-c.c.yom.mail.yahoo.com.
+46.100.173.190.in-addr.arpa.
+bellsouth.net.
+yakimaclarion.com.
+www.google.com.
+t1.gstatic.com.
+hosthotels.com.
+109.216.136.82.in-addr.arpa.
+147.148.141.189.in-addr.arpa.
+147.51.42.190.in-addr.arpa.
+a4.sphotos.ak.fbcdn.net.
+www.ingenierocivilinfo.com.
+153.130.9.186.in-addr.arpa.
+mfddlaw.com.
+loadbalancer.jn3jokm.com.
+mk.wikipedia.org.
+3b363b2490002cd1e5b508a91d696810.info.
+223.181.127.200.in-addr.arpa.
+kuige1cti.33pc.
+a6.sphotos.ak.fbcdn.net.
+www.southwillard.com.
+donking.com.
+teredo.ipv6.microsoft.com.
+inbound.informfitness.com.netsolmail.net.
+apps.facebook.com.
+ratasyrockabilly.blogspot.com.
+mail-attachment.googleusercontent.com.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+esonora.gob.mx.
+a3.sphotos.ak.fbcdn.net.
+66.177.9.186.in-addr.arpa.
+profile.ak.fbcdn.net.
+a1.sphotos.ak.fbcdn.net.
+am686op8ejk5aahb9kk6k985qk.gcdn.biz.
+a.root-servers.net.
+157.125.14.181.in-addr.arpa.
+www.sexscience.org.
+api.facebook.com.
+a.root-servers.net.
+celularesnokiasamsungmotorolalg.blogspot.com.
+mail.guardiancomfort.com.
+tommy2.net.
+a6.sphotos.ak.fbcdn.net.
+e-2dj6wjkockcjkhp.stats.esomniture.com.
+www.isimarsivi.com.
+161.123.235.201.in-addr.arpa.
+166.113.251.189.in-addr.arpa.
+feokon.ru.
+operadays.eu.
+35.76.236.63.in-addr.arpa.
+www.monsterdivx.com.
+100-litsa.ru.
+fqsf.com.
+www.baseball-almanac.com.
+psgw.t-mobilesgws.com.
+20.75.179.190.in-addr.arpa.
+www.youtube.com.
+a8.sphotos.ak.fbcdn.net.
+oficedepot.com.
+memolaesto.blogspot.com.
+www.m.
+www.ucdenver.edu.
+rd-legal.com.
+18.250.115.200.in-addr.arpa.
+pop3.live.com.
+147.44.6.108.in-addr.arpa.
+creative.ak.fbcdn.net.
+booksbikesboomsticks.blogspot.com.
+forum.khoone.org.
+www.facebook.com.
+mail2.angara.ru.
+ccl.rutgers.edu.
+www.nmc.edu.
+foto-natura-huesca.blogspot.com.
+widgets.amung.us.
+fbcdn-profile-a.akamaihd.net.
+a1.sphotos.ak.fbcdn.net.
+time.chttl.com.tw.
+newtab.conduit-hosting.com.
+57.98.244.71.in-addr.arpa.
+www.l.google.com.
+accounts.google.com.
+oscex-en.url.trendmicro.com.
+250.252.16.190.in-addr.arpa.
+5.96.134.189.in-addr.arpa.
+241.23.250.189.in-addr.arpa.
+www.ratesupermarket.ca.
+elm.cl.
+apps.facebook.com.
+25.231.88.79.in-addr.arpa.
+amoviesz.com.
+peeterha.erroratyou.pw.
+pheedo.msnbc.msn.com.
+pagead2.googlesyndication.com.
+www.avionews.com.
+tools.l.google.com.
+golosnadezhdi.ru.
+www.ufs.ac.za.
+178.86.177.195.in-addr.arpa.
+24.109.222.201.in-addr.arpa.
+plusone.google.com.
+www.stopbadware.org.
+a.root-servers.net.
+photos-h.ak.fbcdn.net.
+gfx1.hotmail.com.
+config.mobile.wxbug.com.
+photos-h.ak.fbcdn.net.
+200.90.157.123.in-addr.arpa.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+www.gamebasics.co.uk.
+vp.sip.messenger.msn.com.
+ad-dc2.adtech.de.
+yahoo.com.
+midominio.com.
+a.root-servers.net.
+ar-ar.facebook.com.
+savingssavingsandmoresavings.net.
+p08-keyvalueservice.icloud.com.
+www.seti-inst.edu.
+udc.msn.com.
+1.bp.blogspot.com.
+wserectors.com.
+b-0.19-2309b089.715c0.1518.19d4.3ea1.410.0.l48wk63hd6u11dcp1quez3wqmq.avqs.mcafee.com.
+rt.com.
+rotativover.com.mx.
+a.root-servers.net.
+beacon-1.newrelic.com.
+knicksfanaticsblog.com.
+www.apuntesgestion.com.
+a.root-servers.net.
+www.como-e.com.
+www.facebook.com.
+www.folder-guard.com.
+commons.wikimedia.org.
+www.belkin.com.
+softel.ntl.ru.
+a4.da1.akamai.net.
+malah.biz.
+91.87.229.189.in-addr.arpa.
+a8.sphotos.ak.fbcdn.net.
+hardwarefan.com.
+it.coinmill.com.
+www.casualadultgamers.com.
+realplayer.com.
+otz2diys3.d23o8z3w.
+log.client.akadns.net.
+41.45.134.190.in-addr.arpa.
+apple.com.
+21diciembre2012.foroes.net.
+xwall.bridgecom.com.
+72.206.154.62.in-addr.arpa.
+cuc.claremont.edu.s7a2.psmtp.com.
+philadelphia.cbslocalfanshop.com.
+dfrf.daisypath.com.
+www.naturaltranssexuals.com.
+167.40.46.83.in-addr.arpa.
+194.65.141.201.in-addr.arpa.
+a.root-servers.net.
+a.root-servers.net.
+byfiles.storage.msn.com.
+jeep.com.
+l.yimg.com.
+cs10526.vk.com.
+164.233.48.178.in-addr.arpa.
+exsib.ru.
+140.202.68.76.in-addr.arpa.
+ads1.msads.net.
+jm-ingles.foroactivo.net.
+130.18.204.67.in-addr.arpa.
+rochester.it.com.
+_674_32_5.
+secure.wlxrs.com.
+mail.gladtech.netd.com.
+sbcglobal.net.
+smtp.monavie.com.
+cdn.api.twitter.com.
+mail.dentforcongress.com.
+idigjesus.com.
+a2.sphotos.ak.fbcdn.net.
+s.youtube.com.
+marshallhotels.com.
+pan.starmedia.com.
+cityvillefb1.static.zgncdn.com.
+account.live.com.
+profile.ak.fbcdn.net.
+proyectofueradeserie.blogspot.com.
+41.62.44.190.in-addr.arpa.
+122.165.1.88.in-addr.arpa.
+191.147.137.186.in-addr.arpa.
+_ldap._tcp.4577284e-c7dc-4f42-9890-bae63effdf68.domains._msdcs.vetco.com.
+mx1.effortel.ru.
+www.df-gay.com.mx.
+www.pancrase.org.
+db._dns-sd._udp.0.1.168.192.in-addr.arpa.
+mail.yimg.com.
+a.root-servers.net.
+www.facebook.com.
+fortune-int.en.alibaba.com.
+seabretelon.blogspot.com.
+www.hipertimestico.com.
+kisianmail1.kisian.mimcom.net.
+touch.net.
+cluster8a.us.messagelabs.com.
+1.0.0.127.dnsbugtest.1.0.0.127.in-addr.arpa.
+s.ytimg.com.
+247.96.76.188.in-addr.arpa.
+mail.crewing.ru.
+p012a.polyvore.com.
+worldgeo.ru.
+clients4.google.com.
+dl.jav4u.net.
+matrixres.com.
+s2.youtube.com.
+ksn2-12.kaspersky-labs.com.
+0-278.channel.facebook.com.
+sro.whatsapp.net.
+m.facebook.com.
+www.sabidurias.com.
+docs.google.com.
+www.massiveattack.clan.su.
+pixel.quantserve.com.
+ksn2-12.kaspersky-labs.com.
+static.ak.fbcdn.net.
+static.ak.fbcdn.net.
+sp.cwfservice.net.
+www.google.com.
+www.facebook.com.
+a5.sphotos.ak.fbcdn.net.
+a.root-servers.net.
+pagead2.googlesyndication.com.
+18girls.ru.
+zsnes.programas-gratis.net.
+m.accuweather.com.
+a.root-servers.net.
+concheck.nimbuzz.com.
+www.dominiopublico.gov.br.
+www.behindthathole.com.
+a.root-servers.net.
+dsn4.d.skype.net.
+49.132.46.118.in-addr.arpa.
+platform.twitter.com.
+90.185.91.80.in-addr.arpa.
+t.co.
+dc446.4shared.com.
+twitter.com.
+a5.sphotos.ak.fbcdn.net.
+tbcocala.com.
+ads1.msn.com.
+google.com.
+smtp02.radioholland.net.
+34.26.62.186.in-addr.arpa.
+platform.ak.fbcdn.net.
+253.108.136.186.in-addr.arpa.
+poker-academy.com.
+static.ak.fbcdn.net.
+0.5852475.com.
+fbcdn-profile-a.akamaihd.net.
+r._dns-sd._udp.x\001h.
+12.165.14.217.in-addr.arpa.
+s.youtube.com.
+us.mc1813.mail.yahoo.com.
+www.zwinky.com.
+cachecasino.ll.eurogrand.com.
+www.davidellischrysler.com.
+www.facebook.com.
+www.patrimoniohistorico.org.ar.
+223.69.134.187.in-addr.arpa.
+22.224.171.69.in-addr.arpa.
+mobile-3g-dyn-bu-48-172.zappmobile.ro.
+mihijoconbuenanotaenmate.com.
+m.webtrends.com.
+microsoft.com.mx.
+www.myspace.com.
+www.l.google.com.
+www.googleadservices.com.
+www.alcoulson.com.
+www.verdaderaseduccion.com.
+ja.y8.com.
+et7jzfujd.28xt.
+www.msnarea.com.
+posicionesalhacerelamor.com.
+ec.atdmt.com.
+api-read.facebook.com.
+hebbo-chilexx.ciudadhabbo.com.
+223.236.229.190.in-addr.arpa.
+deucescrackedrakeback.net.
+22.17.191.189.in-addr.arpa.
+ksn1-11-part1.kaspersky-labs.com.
+connect.facebook.net.
+syrcafe.com.
+formatfactory.softpedia.com.
+182.234.63.178.bl.spamcop.net.
+www.google-analytics.com.
+a.root-servers.net.
+de.wikipedia.org.
+sup.live.com.
+ocsp.webspace-forum.de.
+www.anunciosdeveracruz.com.
+prideofthetide.com.
+it-it.facebook.com.
+www.fuerteloko.com.
+162.79.9.177.in-addr.arpa.
+sedecalusa.com.
+www.truste.org.
+166.1.123.187.in-addr.arpa.
+www.alarab.net.
+cwuk.com.
+www.drleonards.com.
+www.google.com.
+113.34.110.189.in-addr.arpa.
+profile.ak.fbcdn.net.
+i1.ytimg.com.
+twitter.com.
+eu.wikipedia.org.
+googleads.g.doubleclick.net.
+105.224.233.190.in-addr.arpa.
+pixel.invitemedia.com.
+cdn.api.twitter.com.
+www.eku.edu.
+secure.etype.com.
+directory.services.live.com.
+content.dl-rms.com.
+a.root-servers.net.
+apis.google.com.
+tayabeixo.org.
+194.93.24.195.in-addr.arpa.
+messager.com.
+a.root-servers.net.
+th.wikipedia.org.
+smtp.mailserv.in.
+teredo.ipv6.microsoft.com.
+mscrl.microsoft.com.
+c0.echoenabled.com.
+77.178.243.201.in-addr.arpa.
+www.ownedcore.com.
+embutidosrios.blogspot.com.
+frogs.org.au.
+www.youtube.com.
+158.13.141.201.in-addr.arpa.
+theansiblog.wordpress.com.
+xmat.com.
+42.156.244.189.in-addr.arpa.
+222.163.166.189.in-addr.arpa.
+tiendamexico.com.mx.
+www.bestgolftipsandtricks.com.
+www.google.com.
+nl.wikipedia.org.
+ms.samwellg.com.
+wikimediafoundation.org.
+c.atdmt.com.
+29.205.233.46.in-addr.arpa.
+pixel.facebook.com.
+download.windowsupdate.com.
+www.youtube.com.
+www.expedia.co.in.
+www.kshe95.com.
+photos-c.ak.fbcdn.net.
+a.root-servers.net.
+a2.sphotos.ak.fbcdn.net.
+healthy-ojas.com.
+mail.citymt.ru.
+60.66.111.95.in-addr.arpa.
+google.com.
+ads.yimg.com.
+millaray.un-clic-por-el-bosque.com.
+profile.ak.fbcdn.net.
+google.com.mx.
+a.root-servers.net.
+www.penguin.co.nz.
+city.yatsushiro.lg.jp.
+webcache.googleusercontent.com.
+a.root-servers.net.
+88.142.249.77.in-addr.arpa.
+safebrowsing-cache.google.com.
+billing.sharo4ka.ru.
+torrentz.eu.
+uidai.sifyitest.com.
+a.root-servers.net.
+csi.gstatic.com.
+images.google.com.
+facebook.com.
+emailium.com.
+creditway.ru.
+c.atdmt.com.
+cedasecuador.com.
+a5.sphotos.ak.fbcdn.net.
+www.facebook.com.
+127.0.0.1.
+infothread.org.
+www.coachsfactory-online.net.
+a.root-servers.net.
+a.root-servers.net.
+m.trendenciasbelleza.com.
+email.1800baskets.com.
+www.facebook.com.
+profile.ak.fbcdn.net.
+www.crookedtimber.org.
+www.google.com.
+2bebullyfree.com.
+www.air.flyingway.com.
+teredo.ipv6.microsoft.com.
+237.18.17.76.in-addr.arpa.
+platform.twitter.com.
+pagead2.googlesyndication.com.
+www.youtube.com.
+mail.reycorporacion.com.
+a.root-servers.net.
+40.197.202.190.in-addr.arpa.
+www.google-analytics.com.
+sqqamnjx7.o13l3h8q.
+rio-toys.ru.
+webcache.googleusercontent.com.
+ocsp.thawte.com.
+static.ak.fbcdn.net.
+edge.hostuc.com.
+136.153.63.24.in-addr.arpa.
+trucosmasgame.blogspot.com.
+secure.wlxrs.com.
+fbcdn-photos-a.akamaihd.net.
+226.84.178.190.in-addr.arpa.
+www.wmnf.org.
+www.mcity.com.au.
+banner-in.net.
+creative.ak.fbcdn.net.
+r._dns-sd._udp.0.2.168.192.in-addr.arpa.
+jqtxjs6qs.24tg.
+r.co.igameunion.com.
+b.scorecardresearch.com.
+1804289383.localhost.
+nyxstyle.com.
+174.214.92.201.in-addr.arpa.
+www.20minutos.es.
+33.161.225.77.in-addr.arpa.
+a.root-servers.net.
+translate.googleapis.com.
+photos-g.ak.fbcdn.net.
+www.dvrserver.net.
+gfx3.hotmail.com.
+187.113.227.77.in-addr.arpa.
+84.136.114.200.in-addr.arpa.
+www.facebook.com.
+www.equipodinero.com.
+zumo.at.
+225.30.82.190.in-addr.arpa.
+www.allvideotrafficschool.com.
+secure.wlxrs.com.
+dftuz.unizar.es.
+b.f.8.8.5.3.f.8.b.1.f.3.9.1.0.2.6.7.e.9.7.3.1.4.0.0.0.0.1.0.0.2.ip6.arpa.
+a1725.l.akamai.net.
+www.ci.lafayette.or.us.
+www.yugiohtheabridgedseries.com.
+mulkcpulx.88wg.
+tc11.easythumbhost.com.
+a7.sphotos.ak.fbcdn.net.
+167.161.26.201.in-addr.arpa.
+175.9.248.62.in-addr.arpa.
+b._dns-sd._udp.0.0.168.192.in-addr.arpa.
+179.60.139.98.in-addr.arpa.
+mx.mikecorey.com.
+check6.facebook.com.
+pic.zdface.com.
+252.67.11.187.in-addr.arpa.
+twitter.com.
+api.twitter.com.
+252.1.84.78.in-addr.arpa.
+245.198.30.186.in-addr.arpa.
+twitter.com.
+grupoautofin.com.
+developers.facebook.com.
+profile.ak.fbcdn.net.
+vaiogatenotifications2.sony-europe.com.
+171.252.184.67.in-addr.arpa.
+harrisonsmythe.com.
+www.bocetoweb.net.
+mail.bhc.car-crm.com.
+mail.kalleh.com.
+a3.sphotos.ak.fbcdn.net.
+catholicspotlight.com.
+seguros-moto.arpem.com.
+ghandshake.com.
+im12.gulfup.com.
+a.root-servers.net.
+s.youtube.com.
+www.google.com.mx.
+www.canew.org.
+google.com.
+www.mindfly.com.
+www.argentinabusca.com.
+www.microsoft.com.
+www.rulez.org.ua.
+102.155.145.201.in-addr.arpa.
+p.twimg.com.
+luber.obladm.msk.su.
+ytimg.l.google.com.
+a2.sphotos.ak.fbcdn.net.
+www.google.com.
+share.lockerz.com.
+svcs.ebay.com.
+au.download.windowsupdate.com.
+32.43.214.201.in-addr.arpa.
+a1.sphotos.ak.fbcdn.net.
+hi-in.facebook.com.
+58.45.194.180.in-addr.arpa.
+firstunion.com.
+media.pron.com.
+latinax100pre.blogspot.com.
+mail.google.com.
+www.tv.nu.
+90.172.160.201.in-addr.arpa.
+124.74.37.190.in-addr.arpa.
+d15gt9gwxw5wu0.cloudfront.net.
+googleads.g.doubleclick.net.
+test-rt.liftdna.com.
+allaccess.biancabeauchamp.com.
+os.evoice.com.
+bet.iach.cz.
+mosdomen.ru.
+syndication.traffichaus.com.
+fr-fr.facebook.com.
+cookingquinn.blogspot.com.
+configuration.apple.com.
+remaxcedarrapids.com.
+osxbook.com.
+docs.portfoliodesign.org.
+a.root-servers.net.
+static2.avast.com.
+pt-br.facebook.com.
+sfg.ru.
+ksn1-11-part2.kaspersky-labs.com.
+cermics.enpc.fr.
+219.250.220.186.in-addr.arpa.
+www.canterburytales.org.uk.
+21.0.168.192.in-addr.arpa.
+mail.ukrpromtrans.com.
+www.thevoicemyanmar.com.
+ksn2-12.kaspersky-labs.com.
+ip1.dynupdate.no-ip.com.
+ftp.uu.net.
+b.scorecardresearch.com.
+i38.tinypic.com.
+www.enlacespanama.com.
+204.73.12.88.in-addr.arpa.
+photos-a.ak.fbcdn.net.
+regrus.spb.ru.
+a2.sphotos.ak.fbcdn.net.
+widgets.twimg.com.
+suburbanhockey.com.1.0001.arsmtp.com.
+ars.oscar.aol.com.
+static.ak.fbcdn.net.
+171.29.11.186.in-addr.arpa.
+mail.google.com.
+233.241.143.71.in-addr.arpa.
+a2.sphotos.ak.fbcdn.net.
+sanyopg.com.my.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+fxfeeds.mozilla.com.
+static.ak.fbcdn.net.
+128.176.170.201.in-addr.arpa.
+www.lancel.com.
+semstroy.ru.
+123.247.32.189.in-addr.arpa.
+www.droitpublic.net.
+a.root-servers.net.
+a.root-servers.net.
+sf2.yourpractice.com.
+ccbltd.com.
+www.pem.org.
+safebrowsing-cache.google.com.
+www.thomascrampton.com.
+download661.avast.com.
+eco-forest.com.
+bud.indirect.com.
+photos-e.ak.fbcdn.net.
+a7.sphotos.ak.fbcdn.net.
+mail.alfaplast.ru.
+bluevalleybrand.com.s6b1.psmtp.com.
+wpad.
+vb.qloob.com.
+26.230.228.189.in-addr.arpa.
+126.219.0.123.in-addr.arpa.
+social.successtelevision.com.
+download.microsoft.com.
+a.root-servers.net.
+sebringraceway.com.
+ebrinc.com.s8a2.psmtp.com.
+dasletzteeinhorn.ch.
+deathgrindfreak.blogspot.com.
+linkhelp.clients.google.com.
+apps.facebook.com.
+www.produ.com.
+api.geo.kontagent.net.
+www.facebook.com.
+a.root-servers.net.
+trophy01.np.community.playstation.net.
+ow.ly.
+www.otomania.net.
+shawcomm.com.
+clients1.google.com.
+profile.ak.fbcdn.net.
+dl-client477.dropbox.com.
+blair.tcaps.net.
+pubads.g.doubleclick.net.
+118.205.255.84.in-addr.arpa.
+blog.mercadoshops.com.
+a.root-servers.net.
+ads.hotgirlsgames.net.
+terra.alts.net.
+enlightenhairstudio.com.
+0-250.channel.facebook.com.
+dtphila.com.
+profile.ak.fbcdn.net.
+i1.ytimg.com.
+fbcdn-profile-a.akamaihd.net.
+ncmail.net.
+photos-c.ak.fbcdn.net.
+62.154.84.86.in-addr.arpa.
+people.uleth.ca.
+sexcamy.ch.
+lookworldusa.com.
+www.kizi-games.com.
+a749.g.akamai.net.
+www.chillout.fm.
+blog.open-office.es.
+alweeam.com.
+pixel.facebook.com.
+a.root-servers.net.
+graph.facebook.com.
+84.114.27.46.in-addr.arpa.
+www.a12.ro.
+s.youtube.com.
+es-la.facebook.com.
+safebrowsing-cache.google.com.
+www.androidenea.com.
+facebook.comac.
+budget101.com.
+iloveyouman.com.
+www.imdb.com.
+spam.globaltac.com.
+maiquiflores.over-blog.es.
+pagead2.googlesyndication.com.
+pixel.facebook.com.
+centralamericadata.com.
+achtenberg.com.
+www.locosporlastelas.com.ar.
+support.google.com.
+db._dns-sd._udp.0.55.211.10.in-addr.arpa.
+mitecnologico.com.
+www.google.com.
+mx3.ksk.co.in.
+www.ojocientifico.com.
+ladificilsencillez-online.blogspot.com.
+29.37.173.190.in-addr.arpa.
+243.34.114.174.in-addr.arpa.
+login.yahoo.com.
+136.9.168.192.in-addr.arpa.
+135.111.55.65.zen.spamhaus.org.
+b._dns-sd._udp.0.1.168.192.in-addr.arpa.
+billcam.axiscam.net.
+a1.sphotos.ak.fbcdn.net.
+a.root-servers.net.
+backgroundlayoutsforfacebook.com.
+sns.goodgamestudios.com.
+gfx3.hotmail.com.
+147.128.92.201.in-addr.arpa.
+streaming.playwire.com.
+facedesign.us.
+l1.yimg.com.
+graph.facebook.com.
+hoteliers.wego.com.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+cherrysage.com.
+130.86.227.189.in-addr.arpa.
+gfx2.hotmail.com.
+www.siuxy-pets.com.
+smak.ru.
+alleytheatre.com.
+ja-jp.facebook.com.
+www.google-analytics.com.
+mail.tgk13.ru.
+cust22700-1.in.mailcontrol.com.
+newsletter.iciparisxl.nl.
+www.correo.unam.mx.
+login.live.com.
+photos-b.ak.fbcdn.net.
+www.getios.com.
+www.elnuevoherald.com.
+161.100.9.186.in-addr.arpa.
+72.148.45.189.in-addr.arpa.
+bit.ly.
+mail.iristel.com.
+187.65.66.186.in-addr.arpa.
+www.facebook.com.
+www.yahoo.com.
+mail.centreprint.net.
+my.bta.kz.
+centrodecocinaygastronomia.com.
+cheriefm.radio.fr.
+correo.adylog.com.
+app140895852605282.socialappspot.com.
+350letras.blogspot.com.
+158.5.168.192.in-addr.arpa.
+251.217.176.187.in-addr.arpa.
+newtab.conduit-hosting.com.
+www.comipems.org.mx.
+orcart.facebook.com.
+www.facebook.com.
+136.209.57.186.in-addr.arpa.
+i.ytimg.com.
+twitter.com.
+static.xvideos.com.
+apex.bryansk.ru.
+0-299.channel.facebook.com.
+google.com.
+media.mpgomatic.com.
+www.facebook.com.
+www.tsa.es.
+cdn.api.twitter.com.
+safebrowsing.clients.google.com.
+todosobrenickelodeon.blogspot.com.
+a.root-servers.net.
+lakelandproair.com.
+lostandfoundandconnectionsabound.blogspot.com.
+5oyystxh5.94od.
+yuec7yln9.90bc.
+250.103.58.201.in-addr.arpa.
+s.youtube.com.
+putlockersearch.com.
+fonts.googleapis.com.
+www.google.es.
+dracoandginny.com.
+www.google.com.
+163.245.3.211.in-addr.arpa.
+photos-c.ak.fbcdn.net.
+www.mosaizer.com.
+t0.gstatic.com.
+ad.harrenmedianetwork.com.
+accountservices.msn.com.
+234.69.91.190.in-addr.arpa.
+143.138.126.122.in-addr.arpa.
+www.google.com.
+a489.w11.akamai.net.
+view.atdmt.com.
+www.jane-wyman.com.
+a.root-servers.net.
+ad.handycafe.com.
+ks-v.ru.
+237.224.124.113.in-addr.arpa.
+badges.coroflot.com.
+www.visto-eua.com.br.
+1-i.ru.
+fs-wti9.wavetechinc.com.
+a-0.19-23091081.c8a0082.1518.19d4.3ea1.210.0.fgsm3869zqsua6rhzrlaju4v6t.avqs.mcafee.com.
+a.root-servers.net.
+img115.imageshack.us.
+www.cinescape.tv.
+254.95.48.190.in-addr.arpa.
+a2.sphotos.ak.fbcdn.net.
+a.root-servers.net.
+ad.yieldmanager.com.
+www.microsoft.com.
+www.baidu.com.
+www.yomolomazo.es.vg.
+moscow-offices.ru.
+44.35.43.186.in-addr.arpa.
+www.facebook.com.
+1st-line.com.
+fctoplist.uuuq.com.
+32.250.49.95.in-addr.arpa.
+creative.ak.fbcdn.net.
+104.212.1.99.in-addr.arpa.
+ns2.colocationamerica.com.
+profile.ak.fbcdn.net.
+s5.scribdassets.com.
+tk6pjyxt:.31al.
+25.media.tumblr.com.
+safebrowsing.clients.google.com.
+mail.antenne-wien.at.
+giraffeelizabeth.wordpress.com.
+asseeninbyjosia.wordpress.com.
+pixel.facebook.com.
+ksn2-12.kaspersky-labs.com.
+pro-sham.travail.gouv.fr.
+tamammennah.blogspot.com.
+safebrowsing-cache.google.com.
+41-courier.push.apple.com.
+parse.howdesign.com.
+iamx.eu.
+djox4jhho.p51u7m9o.
+ruban1.kiwito.com.
+photos-c.ak.fbcdn.net.
+qd7fvzqhx.73tr.
+tangspac.com.
+download795.avast.com.
+1.everystudent.com.
+www.ordinarypastor.com.
+orcart.facebook.com.
+www.google-analytics.com.
+www.vbulletin.com.
+letsbuycom.ugc.bazaarvoice.com.
+ip52-60.cbn.net.id.
+csi.gstatic.com.
+google.com.
+a5.sphotos.ak.fbcdn.net.
+a2.sphotos.ak.fbcdn.net.
+mx1.ahold.ru.
+www.ilgiornaledelpiemonte.com.
+safebrowsing.clients.google.com.
+22.228.171.69.in-addr.arpa.
+static.ning.com.
+9recvkqi8.54hn.
+enazuero.com.
+www.anikovillalba.com.
+www.facebook.com.
+www.google-analytics.com.
+img2.catalog.video.msn.com.
+safebrowsing.clients.google.com.
+thewoostergroup.org.
+www.elong.net.
+welcome.colostate.edu.
+profile.ak.fbcdn.net.
+mail.comhem.basefarm.net.
+www.bigtunainteractive.com.
+photos-b.ak.fbcdn.net.
+rcp.na.blackberry.com.
+217.96.237.189.in-addr.arpa.
+www.facebook.com.
+dns.msftncsi.com.
+252.146.131.187.in-addr.arpa.
+s-static.ak.fbcdn.net.
+gfx4.hotmail.com.
+pixel.quantserve.com.
+lumpyfame.ru.
+apis.google.com.
+remote.innovativedrivers.com.
+7616-574.cudamail.com.
+stat1.moneycontrol.com.
+js.wlxrs.com.
+ajax.googleapis.com.
+i4.ytimg.com.
+g.juegosdebob.com.
+www.megafitness.es.
+246.20.107.189.in-addr.arpa.
+www.addthis.com.
+es.translatedsongs.com.
+toolbar.baidu.com.
+colomsat.net.
+p0b.ru.
+elguiondecine.blogspot.com.
+dl5.avgate.net.
+photos-f.ak.fbcdn.net.
+vqhekvup4.j01i4q1l.
+developers.facebook.com.
+client-software.real.com.
+twitter.com.
+www.annapolishomebrew.com.
+zynga2-a.akamaihd.net.
+france.usembassy.gov.
+101.212.45.201.in-addr.arpa.
+res-66.ru.
+dns.msftncsi.com.
+en-us.fxfeeds.mozilla.com.
+ldlocke.com.
+mail.theofficeconnection.com.
+87.28.215.176.in-addr.arpa.
+www.bedfed.org.uk.
+kevinoleary.ie.
+www.tattooheaven.com.
+a.root-servers.net.
+camelliaandmain.com.
+ticketweb.ca.
+c0.cctld.afilias-nst.info.
+mail02.ifxnetworks.com.
+k:29m8d4f.a17u5d1m.
+katherineisawesome.com.
+laangostura.com.
+205.9.135.186.in-addr.arpa.
+a6.sphotos.ak.fbcdn.net.
+b._dns-sd._udp.0.1.168.192.in-addr.arpa.
+taxicorona.ru.
+utrish.com.ru.
+179.229.132.187.in-addr.arpa.
+a1.sphotos.ak.fbcdn.net.
+antropologiafisica.cl.
+login.yahoo.com.
+developers.facebook.com.
+beta.rocket-bird.com.
+lissyhistorias.blogspot.com.
+229.29.220.76.in-addr.arpa.
+178.206.10.190.in-addr.arpa.
+mail.mflandtitle.com.
+5.88.144.189.in-addr.arpa.
+teamnrn.com.
+ludowthompson.com.
+mx2.krasnoe-beloe.ru.
+91.86.187.221.in-addr.arpa.
+ib.adnxs.com.
+img705.imageshack.us.
+www.google.com.mx.
+plusone.google.com.
+dvt.vn.
+59.122.129.24.in-addr.arpa.
+albertomielgo.blogspot.com.
+a.root-servers.net.
+115.242.85.24.in-addr.arpa.
+www.moneymanagement.com.au.
+28.134.163.90.in-addr.arpa.
+r73.kadastr.ru.
+32.49.174.190.in-addr.arpa.
+www.google.com.
+www.cyberxbabes.net.
+www.guillaume-tesson.com.
+a5.sphotos.ak.fbcdn.net.
+mail.dbylaw.com.
+68.230.231.189.in-addr.arpa.
+mbcpepsi.com.
+external.ak.fbcdn.net.
+static.app.widdit.com.
+ads-vrx.adbrite.com.
+home24bank.com.s9a2.psmtp.com.
+99.45.115.186.in-addr.arpa.
+www.roboelectro.com.
+mail.711.ru.
+www.cooking.info.
+ramrealestate.com.
+tools.google.com.
+54.189.117.62.in-addr.arpa.
+www.google.com.
+explorermusic.com.
+www.thedigitalangel.co.uk.
+www.telme.sg.
+43.115.220.190.in-addr.arpa.
+xclick.ru.
+www.mountainweb.com.
+a.root-servers.net.
+terrehaute.in.gov.
+www.ladyfist.com.
+dereusarch.com.
+www.mobiusinstitute.com.
+i1.ytimg.com.
+pagead2.googlesyndication.com.
+www.tophotrod.net.
+www.nh2007.com.
+mail.furtherfilms.com.
+www.eurocopter.com.
+js.microsoft.com.
+69.212.122.190.in-addr.arpa.
+developers.facebook.com.
+www.free-hideip.com.
+www.alarab.net.
+tags.toolbarsmedia.com.
+a.root-servers.net.
+dr._dns-sd._udp.lan.
+download323.avast.com.
+photos-f.ak.fbcdn.net.
+www.scenesix.com.
+mail.krline.net.
+zkudoc.com.
+janaschi.deviantart.com.
+nikkibeach.com.
+proidy.net.
+connect.facebook.net.
+a2.sphotos.ak.fbcdn.net.
+www.heywhatsthat.com.
+www.facebook.com.
+y7mjd5lwc.s78z8n1e.
+www.berlin.es.
+0.11-a70e9079.8140083.1518.18bb.3ea1.210.0.ir328glk7gtudi9qpucepaen55.avqs.mcafee.com.
+www.google.com.
+relay.505010.ru.
+sut1.co.uk.
+a5.sphotos.ak.fbcdn.net.
+78.24.1.181.in-addr.arpa.
+215.38.168.192.in-addr.arpa.
+www.google.com.
+i4.ytimg.com.
+a.root-servers.net.
+anywhere.platform.twitter.com.
+hoster-1.ru.
+a1920.g.akamai.net.
+static.ak.fbcdn.net.
+i4.ytimg.com.
+66.130.37.2.in-addr.arpa.
+a.root-servers.net.
+www.marben.net.
+cdn1.clkads.com.
+cs5279.vk.com.
+106.2.139.189.in-addr.arpa.
+188.229.21.190.in-addr.arpa.
+au.download.windowsupdate.com.
+156.148.113.187.in-addr.arpa.
+rol.paraguay.com.
+n7b.akamaiedge.net.
+mail.yahoo.com.
+www.google.com.
+momentumplanet.com.
+pmstrk.mercadolibre.com.
+mail.ietf.org.
+blog.astrakhan.ru.
+28.174.102.85.in-addr.arpa.
+dns.msftncsi.com.
+fbcdn-sphotos-a.akamaihd.net.
+go3.trekaklik.com.
+mta.pacific-textiles.com.
+www.blogaditas.com.
+auxilor.com.
+a.root-servers.net.
+titanium30-en.url.trendmicro.com.
+www.spss.com.ar.
+iieh5fqs1.10ui.
+www.exzellenz.rwth-aachen.de.
+www.naimnet.com.
+yahoo.com.
+p.twimg.com.
+244.1.19.190.in-addr.arpa.
+www.coolmsn.com.
+www.google.com.
+s.ytimg.com.
+s.ytimg.com.
+mappe.regioneveneto.net.
+38.92.177.190.in-addr.arpa.
+cuadernosdealfonsosalazar.blogspot.com.
+14.55.14.201.in-addr.arpa.
+creative.ak.fbcdn.net.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+profile.ak.fbcdn.net.
+www.youtube.com.
+adserver.adtech.de.
+tags.expo9.exponential.com.
+ex.urlux.ru.
+ass-1.buttscrewing.com.
+133.71.126.69.in-addr.arpa.
+ec.atdmt.com.
+186.146.27.114.in-addr.arpa.
+anythingfree4you.com.
+dbcmedia.com.s7a2.psmtp.com.
+s-static.ak.fbcdn.net.
+photos-d.ak.fbcdn.net.
+www.segurosrossi.com.ar.
+www.facebook.com.
+ww.npr.org.
+bookclubs.barnesandnoble.com.
+download-31.blogspot.com.
+www.recoleta.com.ar.
+sdsd.com.
+www.eltiempo.com.
+lh6.ggpht.com.
+bkmx.jicjo.com.
+146.201.42.186.in-addr.arpa.
+www.google.com.
+a7.sphotos.ak.fbcdn.net.
+lakeareabank.com.inbound10.mxlogicmx.net.
+www.okaris.com.
+a1732.v.phobos.apple.com.
+24.169.149.99.in-addr.arpa.
+www.unitec.mx.
+www.7peliculas.com.
+tsc-corp.com.
+d98klhsqa.97kp.
+shad.pp.ru.
+a.root-servers.net.
+photos-c.ak.fbcdn.net.
+244.177.209.190.in-addr.arpa.
+platform.stumbleupon.com.
+ovg.ru.
+227.1.213.201.in-addr.arpa.
+cr.loszona.com.
+www.stardoll.com.
+kolkata.craigslist.co.in.
+au.download.windowsupdate.com.
+pagead2.googlesyndication.com.
+time.nist.gov.
+gonewiththetwins.com.
+219.251.63.204.in-addr.arpa.
+wkowtv-com.mail.eo.outlook.com.
+toolbox.contentspread.net.
+www.google.com.
+quarantine.royallepage.ca.
+www.facebook.com.
+i2.ytimg.com.
+www.scientology.pt.
+www.wineselect.com.uy.
+www.garbarino.com.
+41.38.106.187.in-addr.arpa.
+71.33.223.201.in-addr.arpa.
+www.africanaquatics.co.za.
+buzzbox.buzzfeed.com.
+connect.facebook.net.
+i1.ytimg.com.
+www.usavetoday.co.uk.
+profile.ak.fbcdn.net.
+smtp.provcombank.com.
+gtinsurance.net.
+crl.microsoft.com.
+ade.k12.ms.us.
+www.facebook.com.
+www2.una.edu.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+17.168.138.187.in-addr.arpa.
+ctn.it.
+guard.nexon.net.
+login.live.com.
+www.youjel.ly.
+youtube-ui.l.google.com.
+www.a-m-o-r.blogspot.com.
+matejacro.polyvore.com.
+blog-frasescelebres.blogspot.com.
+indiaplazamail.com.
+ns4.mentora.biz.
+nspmotion.com.
+6.190.171.88.in-addr.arpa.
+www.breakmedia.com.
+www.eatis.org.
+hub5idx.shub.sandai.net.
+a7.sphotos.ak.fbcdn.net.
+33.253.195.187.in-addr.arpa.
+multimedia.nydailynews.com.
+plusone.google.com.
+95.229.134.187.in-addr.arpa.
+a.root-servers.net.
+www.kaspersky.com.
+us.data.toolbar.yahoo.com.
+static4.videobam.com.
+s.ytimg.com.
+myspread.co.uk.
+profile.ak.fbcdn.net.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+mail.digitape.com.
+237.60.175.189.in-addr.arpa.
+i4.ytimg.com.
+inbound1.metrocast.net.
+time.windows.com.
+es.lyricsgaps.com.
+a.root-servers.net.
+profile.ak.fbcdn.net.
+141.179.247.190.in-addr.arpa.
+img100.xvideos.com.
+228.18.111.189.in-addr.arpa.
+fxfeeds.mozilla.com.
+228.7.169.89.in-addr.arpa.
+26.107.93.186.in-addr.arpa.
+heritubsyose.com.
+tpprm.ru.
+feeds.bbci.co.uk.
+dns.ystrad-mynach.ac.uk.
+www.nbc40.net.
+apps.facebook.com.
+static.ak.facebook.com.
+feeds.feedburner.com.
+js2.wlxrs.com.
+pixel.facebook.com.
+developers.facebook.com.
+redeoxi.net.
+onsecurityvid.pearson.libsynpro.com.
+dinsmoreworkshop.blogspot.com.
+teredo.ipv6.microsoft.com.
+a4.sphotos.ak.fbcdn.net.
+236.170.12.186.in-addr.arpa.
+strollinfield.com.
+d2100109.xoom.it.
+techbroker.com.
+27.130.127.84.in-addr.arpa.
+mail.divinesearch.com.
+relay.lafondiariatreviglio.it.
+a5.sphotos.ak.fbcdn.net.
+overseasjobs.escapeartist.com.
+tips.kuwo.cn.
+a4.sphotos.ak.fbcdn.net.
+accounts.google.com.
+apps.facebook.com.
+a4.sphotos.ak.fbcdn.net.
+az15112.vo.msecnd.net.
+js.pokernet.dk.
+a8.sphotos.ak.fbcdn.net.
+mail.dottikon.com.
+mail1.iship.com.
+www.youtube.com.
+www.veterinariaexoticos.com.ar.
+www.donnelly24.com.
+ev.ib-ibi.com.
+photos-h.ak.fbcdn.net.
+173.141.78.89.in-addr.arpa.
+www.update.microsoft.com.
+nspmotion.com.
+relay.edison.com.hk.
+manosurbanasscrap.blogspot.com.
+www.nic.com.kw.
+qualitytech.com.
+74.15.124.189.in-addr.arpa.
+189.4.157.201.in-addr.arpa.
+s.ytimg.com.
+bit.ly.
+smtpmail1.xvand.com.
+fluidpowernet.com.
+sr0.comstar.ru.
+static.avast.com.
+a.root-servers.net.
+b-0.19-230a1089.1081.1518.19d3.3ea1.410.0.am9iezikd1d13rw9j23eaurksb.avqs.mcafee.com.
+photos-b.ak.fbcdn.net.
+loading6.widdit.com.
+193.93.125.74.in-addr.arpa.
+216.111.25.190.in-addr.arpa.
+acenexus.com.
+www.facebook.com.
+wlc.hebrewtanakh.com.
+imap.gmail.com.
+qki.bg.
+d.5.9.f.8.8.1.5.f.5.5.2.e.1.c.1.6.7.e.9.7.3.1.4.0.0.0.0.1.0.0.2.ip6.arpa.
+midcountypc.com.
+dc392.4shared.com.
+us.data.toolbar.yahoo.com.
+fun.techradium.com.
+connect.facebook.net.
+static.ak.fbcdn.net.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+i727.photobucket.com.
+i-o.net.au.
+jiu66.cn.
+empoweredbiblestudy.blogspot.com.
+pagead2.googlesyndication.com.
+www.squareinsider.com.
+7tools.ru.
+down.sjxyx.com.
+www.update.microsoft.com.
+msn.levelup.com.mx.
+249.55.228.85.in-addr.arpa.
+apps.facebook.com.
+mangans.blogspot.com.
+www.googleadservices.com.
+e3191.c.akamaiedge.net.
+inbound.mole-end.com.netsolmail.net.
+www.smarturl.it.
+105.23.75.187.in-addr.arpa.
+appworld.blackberry.com.
+www.rpp.com.pe.
+static.zsl.org.
+com-services.pandonetworks.com.
+.
+bit.ly.
+17.148.182.93.zz.countries.nerd.dk.
+mail.ridex.ru.
+56.67.215.189.in-addr.arpa.
+tagler.cl.
+x-images1.bangbros.com.
+ssl.gstatic.com.
+r._dns-sd._udp.lan.
+www.twitter.com.
+antivirus5.cynet.co.jp.
+ar.games.yahoo.com.
+photos-g.ak.fbcdn.net.
+www.gaystack.com.
+apps.tianya.cn.
+static.scanscout.com.
+132.176.126.87.in-addr.arpa.
+84.45.55.186.in-addr.arpa.
+cdn1.videothumbs.xtube.com.
+www.duramerica.com.
+249.147.50.95.in-addr.arpa.
+www.iduplicate.us.
+secure.gaug.es.
+26.127.227.190.in-addr.arpa.
+partner.vrvm.com.
+profile.ak.fbcdn.net.
+top-sc.daum.net.
+a.root-servers.net.
+pixel.quantserve.com.
+ibo2gusli.25tu.
+static.ak.fbcdn.net.
+westerndiatoms.colorado.edu.
+de-de.facebook.com.
+www.decolar.com.
+q.home.
+teredo.ipv6.microsoft.com.
+adeiphia.net.
+beattylumber.com.
+rss.my.nero.com.
+docs.google.com.
+lh5.ggpht.com.
+www.hhizle.com.
+widgets.api.ebay.com.
+htmlentities.net.
+ticknthistle.com.
+crl.geotrust.com.
+static4.filefront.com.
+www.tecnocemento.com.
+www.creativaint.com.
+67.202.230.190.in-addr.arpa.
+a1505.l.akamai.net.
+2.246.1.187.in-addr.arpa.
+www.lubosa.com.mx.
+33-courier.push.apple.com.
+www.lolshock.com.
+99.23.248.63.in-addr.arpa.
+plusone.google.com.
+centurrytel.net.
+i.ytimg.com.
+98.6.62.120.in-addr.arpa.
+creative.ak.fbcdn.net.
+1m:ip6jj1.12iz.
+xxx.nick-toons.net.
+www.lasa.com.mx.
+ns2.webkontrol.doruk.net.tr.
+a4.sphotos.ak.fbcdn.net.
+mail.dakota.com.br.
+80.85.171.201.in-addr.arpa.
+www.bluesfestivals.com.
+kinnofilm.ru.
+www.andorraguia.com.
+pixel.quantserve.com.
+19.76.228.165.in-addr.arpa.
+firesafetysystems.com.
+a-0.19-26091081.e0b0083.1518.19d4.3ea1.210.0.vmlhtvjuflgiddme6imndigcd6.avqs.mcafee.com.
+la-uno.com.
+a.root-servers.net.
+a8.sphotos.ak.fbcdn.net.
+233.254.75.86.in-addr.arpa.
+120.234.221.87.in-addr.arpa.
+mail.nnex.net.
+www.webstore.softexpert.com.
+resp.survey01.net.
+s.chzbgr.com.
+146.70.251.212.in-addr.arpa.
+mx.youtube.com.
+photos-a.ak.fbcdn.net.
+static.ak.fbcdn.net.
+dl2.htc.com.
+5.87.240.201.in-addr.arpa.
+dr._dns-sd._udp.lan.
+30.23.232.189.in-addr.arpa.
+219.10.206.196.in-addr.arpa.
+netscaper.net.
+im.messenger-update.com.
+s.youtube.com.
+atlasdmt.vo.msecnd.net.
+a6.sphotos.ak.fbcdn.net.
+wzeu.ask.com.
+www.elnaveghable.cl.
+t2.gstatic.com.
+7.162.160.189.in-addr.arpa.
+60.61.34.186.in-addr.arpa.
+blue.plala.or.jp.
+realnw.ru.
+photos-c.ak.fbcdn.net.
+www.avsim.su.
+m.facebook.com.
+campbell.k12.va.us.
+sp.cwfservice.net.
+a2.sphotos.ak.fbcdn.net.
+247.21.226.189.in-addr.arpa.
+a-0.19-210f1001.c080081.1518.19d4.3ea1.210.0.56w5db9fams4nfne7us43b3qk6.avqs.mcafee.com.
+voipa.sip.yahoo.com.
+a1.sphotos.ak.fbcdn.net.
+lrmail.com.
+netpay31.sdo.com.
+www.mommynature.com.
+28-courier.push.apple.com.
+llorca-enriqueta.blogspot.com.
+230.11.207.178.in-addr.arpa.
+78.29.133.186.in-addr.arpa.
+photos-d.ak.fbcdn.net.
+log.client.akadns.net.
+edag.com.br.
+144.113.39.216.in-addr.arpa.
+fdh5xuxdk.02ct.
+vaniava.wordpress.com.
+www.compumundo.com.ar.
+mx.aisco-yemen.com.
+cdn.api.twitter.com.
+s-static.ak.fbcdn.net.
+toolbarqueries.clients.google.com.
+t0.gstatic.com.
+sohumx.h.a.sohu.com.
+teamrepro.com.
+sllimages.s3.amazonaws.com.
+www.histats.com.
+affluence.ru.
+foxnetsolutions.com.s5b1.psmtp.com.
+slys.ru.
+serv11.boxca.com.
+royalinteriors.ru.
+93.22.189.190.in-addr.arpa.
+www.boostindependentmusic.com.
+mx.smtnw.com.
+secure.shared.live.com.
+api.tweetmeme.com.
+tilsted.com.
+139.42.134.188.in-addr.arpa.
+tas.orangeads.fr.
+rpg-maker-xp.softonic.com.
+clients2.google.com.
+dns.msftncsi.com.
+www.macappfans.org.
+46.214.6.189.in-addr.arpa.
+25.220.64.199.in-addr.arpa.
+thmarine.com.s8b1.psmtp.com.
+stroudcenter.org.s7a2.psmtp.com.
+icons.cubics.com.
+compsourceok.com.
+dr._dns-sd._udp.0.0.168.192.in-addr.arpa.
+www.immunoconcepts.com.
+ecn.t1.tiles.virtualearth.net.
+17iywqlpz.i60v6h0d.
+external.ak.fbcdn.net.
+www.coloriuris.net.
+teredo.ipv6.microsoft.com.
+v3.cache1.c.youtube.com.
+240.154.74.108.in-addr.arpa.
+igor.funmoods.com.
+googleads.g.doubleclick.net.
+pix.lfstmedia.com.
+xm.xtendmedia.com.
+hdfsi.com.
+www.losangelesinternships.com.
+srpmic.com.
+a.root-servers.net.
+departmanmedya.com.
+a4.sphotos.ak.fbcdn.net.
+orangemail.com.
+delta-kr.ru.
+www.textsrv.com.
+go.srvnow.com.
+www.recapist.com.
+a8.sphotos.ak.fbcdn.net.
+5littles.com.
+www.interpretamos.com.
+98.231.3.190.in-addr.arpa.
+s-static.ak.fbcdn.net.
+183.58.138.187.in-addr.arpa.
+salterlabs.com.2.arsmtp.com.
+db._dns-sd._udp.0.1.168.192.in-addr.arpa.
+67.198.86.208.in-addr.arpa.
+175.197.14.187.in-addr.arpa.
+253.7.91.77.in-addr.arpa.
+www.myshoutbox.com.
+www.autoresponseplus.com.
+173.8.177.72.in-addr.arpa.
+arsecurity.com.
+m.facebook.com.
+pic2.bai.sohu.com.cn.
+teredo.ipv6.microsoft.com.
+sunflower.bio.indiana.edu.
+_767_78_3.
+a.root-servers.net.
+rek.irk.ru.
+s.openad.tf1.fr.
+a1.sphotos.ak.fbcdn.net.
+photos-d.ak.fbcdn.net.
+ilaaheb14.28xc.
+yahoo.co.ae.
+profile.ak.fbcdn.net.
+www.9v8v.com.
+www.maleikie.blogspot.com.
+www.facebook.com.
+186.209.154.109.in-addr.arpa.
+3.bp.blogspot.com.
+downloads8.uptodown.net.
+yahoo.com.
+teeworlds.softonic.com.
+redjellyfish.com.
+a8.sphotos.ak.fbcdn.net.
+media.ticketmaster.com.
+remanage.otepremium.gr.
+www.evanbot.com.
+safebrowsing-cache.google.com.
+www.heat-pump-systems.org.
+forum.say7.info.
+6sigmasolution.com.
+www.hookah-pipe.com.
+104.17.195.68.in-addr.arpa.
+jlisigns.com.
+www.hitachi.com.
+dmail.com.
+g4w0041.americas.hpqcorp.net.
+www.chistesinternet.com.
+es.wikipedia.org.
+a.root-servers.net.
+www.flynetonline.com.
+232.228.74.89.in-addr.arpa.
+firefox01.taobao.com.
+outbound.mailhop.org.
+ar.fifa.com.
+ad.turn.com.
+s.ytimg.com.
+www.divenewzealand.com.
+allsignsdirect.com.
+newsrss.bbc.co.uk.
+gallantsys.com.
+www.google.com.
+teredo.ipv6.microsoft.com.
+dns.msftncsi.com.
+linbox.ru.
+us.mg4.mail.yahoo.com.
+google.com.
+poutres.com.
+ecuamagazine.com.
+musyuseidougamura.blog134.fc2.com.
+www.makrama.es.
+profile.ak.fbcdn.net.
+youtu.be.
+18.116.55.65.sbl.spamhaus.org.
+a2.sphotos.ak.fbcdn.net.
+iafrica.com.
+vt1b741ks.q92l1m6s.
+51.219.252.72.in-addr.arpa.
+developers.facebook.com.
+www.canonusa.com.
+gg24t6oom.b19i4v0q.
+www.aviacion.mil.ve.
+msntest.serving-sys.com.
+isearch.babylon.com.
+727431333032.696e666f6c696e6b73.636f6d.80h4ac8e4a3.webcfs00.com.
+75.154.45.190.in-addr.arpa.
+m.facebook.com.
+132.249.66.152.in-addr.arpa.
+jenners.com.
+mx.mediagroup-consulting.com.cust.b.hostedemail.com.
+www.fanmexico.net.
+a8.sphotos.ak.fbcdn.net.
+es.aliexpress.com.
+wp.me.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+hmit.ww.msn.com.
+www.google.com.
+creative.ak.fbcdn.net.
+extranet.ufc.tv.
+www.bearnet.eu.
+99.87.136.220.in-addr.arpa.
+www.ots.ac.cr.
+dyn-images.hsn.com.
+a.root-servers.net.
+www.themetal-spirit.com.
+100.96.191.209.in-addr.arpa.
+photos-a.ak.fbcdn.net.
+219.77.91.190.in-addr.arpa.
+www.adobe.com.
+theglamourwhore.blogspot.com.
+profile.ak.fbcdn.net.
+static.ak.fbcdn.net.
+mclaire.ru.
+200.232.187.189.in-addr.arpa.
+124.22.38.190.in-addr.arpa.
+42.123.158.187.in-addr.arpa.
+www.steel-sci.org.
+192.107.105.189.in-addr.arpa.
+a-0.19-23094081.c0f0083.1518.19d0.3ea1.210.0.zp77cr5ulnlsmfvftm57rc5mgq.avqs.mcafee.com.
+equestria-prevails.deviantart.com.
+0-jw-w.channel.facebook.com.
+de.tynt.com.
+mail.ccmadocs.com.
+www.wildtangent.com.
+bit.ly.
+list.bentium.net.
+cn.pool.ntp.org.
+start.facemoods.com.
+arcade.y8-y8.com.
+img4.catalog.video.msn.com.
+pmcarpenter.blogs.com.
+www.facebook.com.
+46.224.150.64.in-addr.arpa.
+static.ak.fbcdn.net.
+csc.beap.ad.yieldmanager.net.
+checkip.dyndns.org.
+www.facebook.com.
+235.19.214.186.in-addr.arpa.
+www.airgraver.com.
+rumahmadu.com.
+l.yimg.com.
+rosarioout.blogspot.com.
+pixel.facebook.com.
+asalallenaonline.com.ar.
+230.61.137.187.in-addr.arpa.
+a6.sphotos.ak.fbcdn.net.
+5449380.ru.
+205.78.167.79.in-addr.arpa.
+partner.googleadservices.com.
+romanticlub.en.alibaba.com.
+myfacebooktoolbar.s3.amazonaws.com.
+google.com.
+a.root-servers.net.
+battlefield2.ru.
+amer.rel.msn.com.
+82.66.110.189.in-addr.arpa.
+creative.ak.fbcdn.net.
+bellsou1h.net.
+196.174.83.200.in-addr.arpa.
+nancythomas.blogspot.com.
+montbleau.com.
+165.240.254.99.in-addr.arpa.
+www.flirtfair.it.
+www.2gaypasswords.com.
+mx.263.net.
+profile.ak.fbcdn.net.
+profile.ak.fbcdn.net.
+c-0.19-210fc271.8020081.1518.19d3.3ea1.210.0.9mdra7zszvzfpdszhrtwc9k4jj.avqs.mcafee.com.
+dns.msftncsi.com.
+a2.sphotos.ak.fbcdn.net.
+cdn.mdotm.com.
+www.godmammon.com.
+concheck.nimbuzz.com.
+accounts.google.com.
+a5.sphotos.ak.fbcdn.net.
+threadedrod.com.
+jmwelectric.com.
+www.msftncsi.com.
+a.root-servers.net.
+show.kirov.ru.
+ccandw.com.
+t.co.
+96.170.6.200.in-addr.arpa.
+a6.sphotos.ak.fbcdn.net.
+rocktheworld.polyvore.com.
+d3dqyhyld.39sf.
+www.bravoteens.com.
+ymcamontgomery.org.
+sp.cwfservice.net.
+sync.mathtag.com.
+www.socialsafety.org.
+apps.facebook.com.
+ne1.wac.edgecastcdn.net.
+g.msn.com.
+bcge.ch.
+content.yieldmanager.edgesuite.net.
+spe.atdmt.com.
+www.conspiracybomb.com.
+0.57.29.186.in-addr.arpa.
+83.63.168.94.in-addr.arpa.
+www.boats.net.
+clients1.google.com.
+gocanada.about.com.
+www.vodafone.ie.
+a.root-servers.net.
+a.root-servers.net.
+media.adamdodson.org.woopra-ns.com.
+jisublover.blogspot.com.
+a.root-servers.net.
+kyno.ru.
+log.client.akadns.net.
+photos-b.ak.fbcdn.net.
+www.invodo.com.
+altfarm.mediaplex.com.
+files.adbrite.com.
+www4.l.google.com.
+mail.solarsilicon.com.
+www.picnik.com.
+mfspex.com.
+appworld.blackberry.com.
+www.guyana.com.
+photos-b.ak.fbcdn.net.
+_031_06_2.
+portugues.vacationstogo.com.
+84.247.164.190.in-addr.arpa.
+nba2karg.forolatin.com.
+marketing.iprofesional.com.
+a.root-servers.net.
+dns.msftncsi.com.
+mail-2.galenica.ch.
+de-de.facebook.com.
+mksound.com.
+214.33.136.187.in-addr.arpa.
+az.wikipedia.org.
+a4.da1.akamai.net.
+codep30rollerskating.fr.
+darkbattm14-videos.blogspot.com.
+www.transparency.org.
+www.adobe.com.
+92.97.82.108.in-addr.arpa.
+35.147.179.189.in-addr.arpa.
+feeds.videosz.com.
+dns.msftncsi.com.
+dr._dns-sd._udp.0.0.168.192.in-addr.arpa.
+safebrowsing.clients.google.com.
+29.150.16.181.in-addr.arpa.
+93.57.40.190.in-addr.arpa.
+41.247.143.189.in-addr.arpa.
+static.ak.fbcdn.net.
+stagemoscow.ru.
+120.165.98.85.in-addr.arpa.
+www.ascensionenergyprogram.com.
+moda.aukro.ua.
+the.illusionist.tracker.prq.to.
+80.181.88.186.in-addr.arpa.
+www.allcelebritiessex.net.
+eemeasess07.eemea.ericsson.se.
+mail.google.com.
+phuketgolf.com.
+faith.rydia.net.
+am.ricardo.ch.
+content.yieldmanager.edgesuite.net.
+liveupdate.symantecliveupdate.com.
+google.com.
+177.148.99.190.in-addr.arpa.
+169.cim.meebo.com.
+dealcom.ru.
+a1505.l.akamai.net.
+ad.yieldmanager.com.
+supremeflooring.net.
+external.ak.fbcdn.net.
+fbcdn-profile-a.akamaihd.net.
+a998.mm1.akamai.net.
+232.101.171.189.in-addr.arpa.
+si0.twimg.com.
+marquettenatl.com.
+103.151.109.190.in-addr.arpa.
+190.170.36.186.in-addr.arpa.
+checkip.dyndns.com.
+a.root-servers.net.
+38.189.7.81.in-addr.arpa.
+www.facebook.com.
+158.166.138.187.in-addr.arpa.
+google.com.
+c247723.r23.cf1.rackcdn.com.
+s-static.ak.fbcdn.net.
+petersresort.com.
+www.facebook.com.
+allconnex.com.s7b1.psmtp.com.
+1.53.44.176.in-addr.arpa.
+apis.google.com.
+www.scp-wiki.net.
+_061_46_9.
+a.root-servers.net.
+www.noveldadigital.es.
+photos-d.ak.fbcdn.net.
+profile.ak.fbcdn.net.
+b-0.19-22016008.580.1518.19d4.3ea1.410.0.7akhquus6vkutd5v1vntgif765.avqs.mcafee.com.
+refresh.monohrome.com.
+google.com.
+a.root-servers.net.
+4e1q7m25n.c48r4d0p.
+b._dns-sd._udp.lan.
+greenpeace.ru.
+76.67.36.46.in-addr.arpa.
+s-static.ak.fbcdn.net.
+hwcdn.net.
+r._dns-sd._udp.lan.
+photos-c.ak.fbcdn.net.
+a.root-servers.net.
+search.bearshare.com.
+photos1.hi5.com.
+statusformaturas.com.br.
+www.google-analytics.com.
+static.ak.fbcdn.net.
+gallery.hartmannwheels.com.
+120.142.90.78.in-addr.arpa.
+162.158.224.190.in-addr.arpa.
+hortonsigns.co.nz.
+www.belkin.com.
+a1.sphotos.ak.fbcdn.net.
+a6.sphotos.ak.fbcdn.net.
+mail.live.com.
+www.fal.com.mx.
+105.94.19.201.in-addr.arpa.
+a8.sphotos.ak.fbcdn.net.
+mail.kop.ru.
+photos-e.ak.fbcdn.net.
+a377.w23.akamai.net.
+hotmail.com.
+photos-h.ak.fbcdn.net.
+a.root-servers.net.
+148.239.29.202.in-addr.arpa.
+yoshifuji.org.
+227.60.237.189.in-addr.arpa.
+pixel.facebook.com.
+cgigroup.com.
+tsm04.eset.com.
+genieind.com.
+mail.vision2results.com.
+a1.sphotos.ak.fbcdn.net.
+bit.ly.
+58.95.145.64.in-addr.arpa.
+cronistadearena.blogspot.com.
+a1406.w42.akamai.net.
+pixel.facebook.com.
+www.juicygoo.com.
+www.vanguardia.com.mx.
+ssl.gstatic.com.
+messenger.yahoo.com.
+www.nikonhq.com.
+myomnicomp.com.s8a1.psmtp.com.
+207.96.102.201.in-addr.arpa.
+bghgmi85m.49cw.
+weekly.ua.
+147.99.48.190.in-addr.arpa.
+www.facebook.com.
+groups.yahoo.com.
+53.73.187.78.in-addr.arpa.
+www.3dtoontube.com.
+cdn.loading321.com.
+fbcdn-profile-a.akamaihd.net.
+www.lafolia.com.
+www.extremetube.com.
+a5.sphotos.ak.fbcdn.net.
+d2107725.xoom.it.
+6-courier.push.apple.com.
+ielu.wamani.apc.org.
+photos2.pop6.com.
+trissalicious.com.
+mx3.rowan.edu.
+inetsite.ru.
+www.popinstituut.nl.
+adserver.adtechus.com.
+212.62.6.186.in-addr.arpa.
+a7.sphotos.ak.fbcdn.net.
+moris.ru.
+static.hotelsone.com.
+us.data.toolbar.yahoo.com.
+a4.sphotos.ak.fbcdn.net.
+spb.nek.ru.s200a1.psmtp.com.
+dns.msftncsi.com.
+secure-uk.imrworldwide.com.
+a.root-servers.net.
+www.kerri.
+photos-b.ak.fbcdn.net.
+a.root-servers.net.
+cdna.pics.youjizz.com.
+ksn1-11-part1.kaspersky-labs.com.
+px.owneriq.net.
+a1.sphotos.ak.fbcdn.net.
+www.gruposantillana.com.
+48.25.145.186.in-addr.arpa.
+exitrealtyabacus.com.
+pagead2.googlesyndication.com.
+79.52.92.186.in-addr.arpa.
+www.courthouse.kay.ok.us.
+lazarusfoundation-asiapacific.org.
+c-0.19-230f6041.10081.1518.19d3.2f4e.10.0.zneg8jpfq12mrtk94v6p4ibuei.avqs.mcafee.com.
+a1108.da1.akamai.net.
+mail.bolo.com.
+www.causes.com.
+b._dns-sd._udp.home.
+162.74.156.93.in-addr.arpa.
+www.ojogo.pt.
+lcbf-com.relay1b.spamh.com.
+r20.rs6.net.
+www.pellegrinocattolico.com.
+16.147.220.66.in-addr.arpa.
+ns.linkexplore.ro.
+6-courier.push.apple.com.
+167.219.206.91.in-addr.arpa.
+greenslip.com.
+e-premieradvantage.com.
+support.live.com.
+110.192.201.173.sbl.spamhaus.org.
+cakecreate.co.uk.
+56.55.123.69.in-addr.arpa.
+www.fswshoes.com.au.
+www.mp3-codes.com.
+a.root-servers.net.
+dmsr.files.wordpress.com.
+l.sharethis.com.
+loading321.com.
+mail.benchmarklends.com.
+105.219.120.187.in-addr.arpa.
+verbes.woxikon.fr.
+images.habbo.com.
+statcounter.com.
+94.35.12.88.in-addr.arpa.
+agrimedia.info.
+a.root-servers.net.
+www.wanderlust-movie.com.
+www.facebook.com.
+hairsaloon.com.
+www.go-video-ltd.co.uk.
+txtmpmnn.com.
+hotmail.com.
+elartedelacomunicacion.blogspot.com.
+natadosromances.blogspot.com.
+139.70.27.188.in-addr.arpa.
+forestcity.net.s7a2.psmtp.com.
+www.facebook.com.
+crl.microsoft.com.
+www.wikimediafoundation.org.
+www.jornada.unam.mx.
+27.164.112.76.in-addr.arpa.
+www.musiikkitalo.fi.
+www.lomejordelheavy.com.
+consfab.com.
+e3167.c.akamaiedge.net.
+86.183.57.187.in-addr.arpa.
+images.images4us.com.
+translate.googleapis.com.
+mail.imobileus.com.
+us1.badoo.com.
+energia.corriere.it.
+photos-a.ak.fbcdn.net.
+rmd.atdmt.com.
+healthguide.howstuffworks.com.
+whatdoesthebiblesayabout.com.
+wpad.
+www.queregalo.cl.
+redir.metaservices.microsoft.com.
+www.c24.com.br.
+plusone.google.com.
+getdocumentary.com.
+www.match4me.be.
+www.flowers24hours.co.uk.
+google.com.
+apps.facebook.com.
+google.com.
+platform.ak.fbcdn.net.
+www.justin.tv.
+124.210.131.74.in-addr.arpa.
+api.twitter.com.
+video.google.es.
+imap.gmail.com.
+www.audible.com.
+a.root-servers.net.
+a.root-servers.net.
+club.astro.sina.com.cn.
+www.facebook.com.
+power.ru.
+107.37.10.187.in-addr.arpa.
+fatmaturebbw.thumblogger.com.
+23.191.25.187.in-addr.arpa.
+www.lesbianascolegialas.com.
+hfns.com.
+pinterest.com.
+x4.xvideohost.com.
+transporteskortmann.cl.
+eulcpf2v2.90mk.
+datitoos.org.
+ad.foxnetworks.com.
+a.root-servers.net.
+ouest-france.fr.
+impes.tradedoubler.com.
+78.147.214.189.in-addr.arpa.
+ent.paris-sorbonne.fr.
+awe-newtech.com.
+google.com.
+c3christiancounseling.com.
+ppenet.com.s8a2.psmtp.com.
+em.tenant401.ovi.messaging.nokia.com.
+bitacoras.com.
+st.chatango.com.
+s-external.ak.fbcdn.net.
+237.66.0.10.in-addr.arpa.
+114.113.7.187.in-addr.arpa.
+developers.facebook.com.
+ihzoopy14.77ki.
+www.facebook.com.
+a7l8ctpwo.m64f9a0x.
+static.ak.facebook.com.
+ssl.gstatic.com.
+tecnobreros.wordpress.com.
+profile.ak.fbcdn.net.
+a.root-servers.net.
+12.187.88.208.in-addr.arpa.
+www.facebook.com.
+biz52.ru.
+thumbnails34.imagebam.com.
+profile.ak.fbcdn.net.
+.
+orr99bcq6.00vy.
+www.ritamitsouko.com.
+www.harley-bobbers.com.
+mx1.snapnames.com.
+mematodelarisa.blogspot.com.
+pagead2.googlesyndication.com.
+petronmarketing.com.
+merida.adoos.com.mx.
+www.alexanderneumann.com.
+fisinc.com.
+s4.histats.com.
+premiermtg1.com.
+cydia.saurik.com.cdngc.net.
+www.dpreview.com.
+38.162.43.200.in-addr.arpa.
+ufojeans.tumblr.com.
+125.120.234.98.in-addr.arpa.
+bluelawllp.com.
+download.juegos.com.
+addacover.com.
+50.253.101.174.in-addr.arpa.
+id.google.com.
+nicolas_17_n.tripod.com.mx.
+geokite.com.
+yahoo.com.
+pass.yandex.ru.
+cinergymetronet.com.
+zonamanga.com.
+images.yodibujo.es.
+aspmx.l.google.com.
+v14.nonxt3.c.youtube.com.
+torrntdao.blog129.fc2.com.
+www.eluniversal.com.mx.
+paragondm.com.
+www.mercedes.de.
+bs.serving-sys.com.
+s.ytimg.com.
+mx.posluh.hr.
+k2vm6jz5y.l34v9b3f.
+mobth198.photobucket.com.
+mx2.talk21.mail.yahoo.com.
+culture.alwatanyh.com.
+www.womensgolf.org.au.
+fwgapp.net.s200b1.psmtp.com.
+www.godney.fan-strefa.pl.
+lighthousetoyota.com.inbounda.reyrey.net.
+api-global.netflix.com.
+funt.ru.
+mx1.earthlink.net.
+3cwboio1p.g20r0n5k.
+hqde.infrabrk.com.
+233.165.102.97.in-addr.arpa.
+24.187.23.95.in-addr.arpa.
+profile.ak.fbcdn.net.
+www.medieval-castle-siege-weapons.com.
+spbmetro.ru.
+teredo.ipv6.microsoft.com.
+ajax.googleapis.com.
+www.orthocast-online.com.
+251.21.0.192.in-addr.arpa.
+soap.bmstu.ru.
+speedy.imo.im.
+photos-f.ak.fbcdn.net.
+sites.google.com.
+www.geotenis.com.
+studentschile.tripod.com.
+www.cdmale.com.
+www.google-analytics.com.
+ib.adnxs.com.
+adwhirllb-473732162.us-east-1.elb.amazonaws.com.
+www.uaz.edu.mx.
+27.109.250.189.in-addr.arpa.
+img.youtube.com.
+bobschwab.com.
+88.59.191.189.in-addr.arpa.
+reports.montiera.com.
+surfsurd.hubpages.com.
+friends.doubledowncasino.com.
+incorporation.ru.
+a.root-servers.net.
+pheedo.msnbc.msn.com.
+a3.sphotos.ak.fbcdn.net.
+crl.globalsign.net.
+a.root-servers.net.
+www.googleadservices.com.
+19.128.100.190.in-addr.arpa.
+www.youtube.com.
+www.facebook.com.
+ax.search.itunes.apple.com.
+mailgw.deerfieldpartners.com.
+213.209.94.190.in-addr.arpa.
+profile.ak.fbcdn.net.
+cdn.feeds.videosz.com.
+190.136.105.92.in-addr.arpa.
+www.zingy.fr.
+webassets3.sparkybee.com.
+g.espncdn.com.
+8.138.162.184.in-addr.arpa.
+del.icio.us.
+121.151.24.88.in-addr.arpa.
+rya.rockyou.com.
+a.root-servers.net.
+es.tatsuorg.wikia.com.
+www.lotto-results.co.za.
+152.25.48.190.in-addr.arpa.
+www.cotifiesta.cl.
+ad.e-viral.com.
+www.movistar.com.pe.
+reachandrich.antevenio.com.
+253.7.105.201.in-addr.arpa.
+photos-c.ak.fbcdn.net.
+teredo.ipv6.microsoft.com.
+mail.giumarravineyards.com.
+grindesign.tumblr.com.
+p0b.ru.
+t1.gstatic.com.
+_866_03_6.
+235.83.137.118.in-addr.arpa.
+creative.ak.fbcdn.net.
+_ldap._tcp.
+mail.bkrlaw.com.
+141.194.245.189.in-addr.arpa.
+www.periodicoadarve.com.
+strsd.southwick.ma.us.
+14.174.240.67.in-addr.arpa.
+a.root-servers.net.
+ksn7.kaspersky-labs.com.
+canitscan1.cal.net.
+180.201.48.190.in-addr.arpa.
+sub-talk.net.
+press.ba.com.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+apple.com.
+img-cdn.mediaplex.com.
+profile.ak.fbcdn.net.
+_480_84_7.
+69.148.214.189.in-addr.arpa.
+crona-m.ru.
+158.198.174.190.in-addr.arpa.
+www.leivankash.com.
+197.26.128.188.in-addr.arpa.
+26438.envacaciones.info.
+media-cdn.tripadvisor.com.
+100.3.59.186.in-addr.arpa.
+adserver.adtech.de.
+fbcdn-profile-a.akamaihd.net.
+www.genomereviews.ebi.ac.uk.
+in.getclicky.com.
+ledfordmed.secure-enterprise.com.
+img100.xvideos.com.
+chocoline.ru.
+sites.google.com.
+cs9345.vk.com.
+a.root-servers.net.
+1diet.jp.
+137.25.130.189.in-addr.arpa.
+a.root-servers.net.
+img298.imagevenue.com.
+static.ak.fbcdn.net.
+73.17.213.186.in-addr.arpa.
+173.199.15.95.in-addr.arpa.
+img124.hotlinkimage.com.
+www.ifixit.com.
+mail.b2buying.com.
+161.131.194.187.in-addr.arpa.
+prgschultz.net.
+teredo.ipv6.microsoft.com.
+87.85.237.189.in-addr.arpa.
+www.update.microsoft.com.
+53.193.226.189.in-addr.arpa.
+238.250.253.190.in-addr.arpa.
+sites.google.com.
+111.230.231.77.in-addr.arpa.
+piuv5.francetv.fr.
+teredo.ipv6.microsoft.com.
+tempfile.ru.
+119.78.201.41.in-addr.arpa.
+229.52.74.190.in-addr.arpa.
+mamasita.wordpress.com.
+cdn.ubergizmo.com.
+agriproj.com.
+pixel.facebook.com.
+orcart.facebook.com.
+atube-catcher.uptodown.com.
+_ldap._tcp.
+15.175.192.94.in-addr.arpa.
+any-ycpi.aycpi.b.yahoodns.net.
+ndt.iupui.ath01.measurement-lab.org.
+db._dns-sd._udp.0.1.168.192.in-addr.arpa.
+cloutieretfils.com.
+d2055705.instant.xoom.it.
+15.92.82.203.in-addr.arpa.
+www.wguaba.com.
+228.26.126.187.in-addr.arpa.
+advancemfg.com.
+www.cam4com.info.
+77.161.100.118.in-addr.arpa.
+ksn3-11.part1.kaspersky-labs.com.
+peopleschoicesurgical.com.
+www.google.com.
+www.clickondetroit.com.
+www.agiteysirva.com.
+arcade-classic-arcade-pack.softonic.com.
+nichegeek.com.
+andreaslagerkvist.com.
+s-static.ak.facebook.com.
+www.facebook.com.
+www.moviezet.com.
+a.root-servers.net.
+151.11.46.24.in-addr.arpa.
+bypalisades.com.inbound10.mxlogicmx.net.
+cuenca.anuxi.ec.
+www.digiturk.gen.tr.
+radiodisney.disneylatino.com.
+ph.priceprice.com.
+63.162.32.114.in-addr.arpa.
+webconfig.merck.com.nch.intra.
+zh-cn.facebook.com.
+250.69.237.189.in-addr.arpa.
+60.249.191.186.in-addr.arpa.
+www.walmart.com.mx.
+179.54.186.189.in-addr.arpa.
+176.111.55.65.in-addr.arpa.
+comunidad.levante-emv.com.
+213.198.19.201.in-addr.arpa.
+mm3.no-ip.info.
+a.root-servers.net.
+smtp.wpcind.com.
+apps.bittorrent.com.
+onemain-mx.earthlink.net.
+a7.sphotos.ak.fbcdn.net.
+b._dns-sd._udp.0.1.168.192.in-addr.arpa.
+cmknn.ru.
+48.163.46.208.in-addr.arpa.
+config.pinballbu1.com.
+careers.nyumc.org.
+ezfwpdp.die.net.
+jobs.careerbuilder.com.
+226.248.132.82.in-addr.arpa.
+larrygibbons.com.
+www.google.com.mx.
+a7.sphotos.ak.fbcdn.net.
+9.239.193.212.in-addr.arpa.
+_155_52_3.
+www.brendanemmettquigley.com.
+207.246.54.96.in-addr.arpa.
+twitter.com.
+imgfinance.naver.net.
+www.facebook.com.
+latitudeds.com.
+132.52.123.88.in-addr.arpa.
+wwwimages.adobe.com.
+www.infometeo.es.
+ile-tropicale.com.
+mx.sotcom.ru.ryazan.ru.
+s.sputnik.mail.ru.
+img18.mediafire.com.
+www.download.windowsupdate.com.
+_741_39_8.
+dano-uso-audifonos.blogspot.com.
+www.zonafandom.com.
+www.google-analytics.com.
+e269.b.akamaiedge.net.
+rdr.leeds.ac.uk.
+cl1bak2smtp1.na.epidm.net.
+ftryea.com.
+cdnis3.cam4.com.
+sony-928.vo.llnwd.net.
+dns.msftncsi.com.
+www.farmacia-espana.org.
+www.futuredimensions.net.
+www.carrera-toys.com.
+0.242.144.186.in-addr.arpa.
+albatros.spb.ru.
+www.qcmp3.com.
+sirius-art.spb.ru.
+cap1.conduit-apps.com.
+rad.msn.com.
+www.imgclck.com.
+main.dl.wu.akadns.net.
+feeds.bbci.co.uk.
+rapidssl-aia.geotrust.com.
+ajga.org.
+un4rwezip.i32j0r6q.
+safdf.com.
+witer.bitacoras.com.
+weldinghouse.com.
+eaglemortgageloan.com.
+feeds.feedburner.com.
+.
+hotmail.com.
+231.152.25.46.in-addr.arpa.
+www.sepyme.gov.ar.
+pixel.facebook.com.
+223.71.191.189.in-addr.arpa.
+121.135.121.74.in-addr.arpa.
+philippineamericanwar.webs.com.
+au.download.windowsupdate.com.
+www.sanook.at.
+www.novacreations.net.
+pagead2.googlesyndication.com.
+xsltcache.alexa.com.
+apple.imap.mail.yahoo.com.
+co.tvunetworks.com.
+101.66.97.129.in-addr.arpa.
+a.root-servers.net.
+214.53.19.186.in-addr.arpa.
+foodtrade.ru.
+adi-martinique.fr.
+www.rhapsody-fr.com.
+oms.sakhanet.ru.
+cdn.phonezoo.com.
+www.myoutdoortv.com.
+egaservicios.com.
+152.71.43.208.in-addr.arpa.
+touch.facebook.com.
+nht-2.extreme-dm.com.
+db._dns-sd._udp.0.1.168.192.in-addr.arpa.
+static.ak.fbcdn.net.
+chatyahoo.blogspot.com.
+a.root-servers.net.
+a.root-servers.net.
+mail2.teknoloji.com.
+www.facebook.com.
+a.root-servers.net.
+wakegov.com.
+www.fho-emden.de.
+rs292dt.rapidshare.com.
+media.v55v.net.
+sddic9gzp.26uj.
+bz:74n6ge.z49t8n4r.
+photos-c.ak.fbcdn.net.
+allergan.com.s7b2.psmtp.com.
+photos-a.ak.fbcdn.net.
+caroserena.blogspot.com.
+lineage2.free.fr.
+www.cablemas.com.mx.
+mail.goozmo.com.
+110.99.81.186.in-addr.arpa.
+c-0.19-a309d481.50483.1518.19d4.3ea1.410.0.dvvkjbg3g7rbsew6n8rdutm2wv.avqs.mcafee.com.
+weather.wapp.wii.com.
+evangeliodeldia.org.
+tms5.icrc.trendmicro.com.
+_877_92_6.
+mail.scarsdaledentistry.com.
+a5.sphotos.ak.fbcdn.net.
+static.ak.fbcdn.net.
+safebrowsing.clients.google.com.
+b.scorecardresearch.com.
+www.update.microsoft.com.
+215.125.178.31.in-addr.arpa.
+goosebox.net.lan.
+www.http.
+ssl.gstatic.com.
+apps.facebook.com.
+240.112.36.177.in-addr.arpa.
+api.twitter.com.
+www.humeseeds.com.
+ad.doubleclick.net.
+disneysjessie.com.
+a5.sphotos.ak.fbcdn.net.
+www.free-tv-video-online.me.
+151.61.141.201.in-addr.arpa.
+218.240.26.80.in-addr.arpa.
+www.icameltoes.com.
+load.s3.amazonaws.com.
+pagead2.googlesyndication.com.
+142.3.44.81.in-addr.arpa.
+cf.addthis.com.
+.
+pixel.facebook.com.
+149.130.50.201.in-addr.arpa.
+c0013999.ssl.cf1.rackcdn.com.
+e906.g.akamaiedge.net.
+espanol.support.vonage.com.
+softpro.msk.ru.
+www.google.com.
+a-0.19-230fd081.a060131.1518.19d4.3ea0.210.0.555215vife6tps7czkhjhiiz15.avqs.mcafee.com.
+81.93.5.88.in-addr.arpa.
+226.139.85.186.in-addr.arpa.
+a995.mm1.akamai.net.
+218.143.209.201.in-addr.arpa.
+a8.sphotos.ak.fbcdn.net.
+safebrowsing.clients.google.com.
+www.xperthr.co.uk.
+a1.sphotos.ak.fbcdn.net.
+images03.olx-st.com.
+cstheory.stackexchange.com.
+www.youtube.com.
+a.root-servers.net.
+mail.96861mail.com.
+trigate.com.
+de-de.facebook.com.
+www.adobe.com.
+www.e-belis.com.
+deltavolt.pe.
+t3.gstatic.com.
+lizzie-mcguire.seriespepito.com.
+www.google.com.
+ajax.googleapis.com.
+g.ceipmsn.com.
+a.root-servers.net.
+s.youtube.com.
+www.what-time-is-it.com.
+25.174.219.190.in-addr.arpa.
+mx1.mac.com.akadns.net.
+www.hotmail.com.
+www.metroscubicos.com.
+static.ak.fbcdn.net.
+pixel.facebook.com.
+teacher.ocps.net.
+202.218.11.200.in-addr.arpa.
+profile.ak.fbcdn.net.
+5.99.184.81.in-addr.arpa.
+beta.stun.voice.yahoo.com.
+www.segurosrossi.com.ar.
+a.root-servers.net.
+apps.facebook.com.
+a.root-servers.net.
+mashable.com.
+58.147.87.186.in-addr.arpa.
+195.103.16.186.in-addr.arpa.
+www.trogontours.net.
+127.104.4.186.in-addr.arpa.
+fbcdn-photos-a.akamaihd.net.
+qaxp.com.
+sqm.microsoft.com.
+pagead2.googlesyndication.com.
+youtube.com.
+a7.sphotos.ak.fbcdn.net.
+mscrl.microsoft.com.
+hoy-sa.com.
+www.bebesymas.com.
+a.root-servers.net.
+209.ns1631262.net.
+directas-descargas-rapidshare.blogspot.com.
+210.59.187.115.in-addr.arpa.
+211.94.138.189.in-addr.arpa.
+43.62.75.187.in-addr.arpa.
+api-public.addthis.com.
+97.106.161.189.in-addr.arpa.
+220.227.31.190.in-addr.arpa.
+grupocolmenar.com.
+www.kut-friends.com.
+yahoo.com.
+_895_96_3.
+www.maslacasassa.com.
+photos-e.ak.fbcdn.net.
+developers.facebook.com.
+www.use.com.ph.
+communityhospital.com.
+197.57.159.189.in-addr.arpa.
+profile.ak.fbcdn.net.
+badoo.com.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+www.google-analytics.com.
+ninjasaga.superforos.org.
+www.google-analytics.com.
+harborexpress.com.inbound10.mxlogicmx.net.
+pan.starmedia.com.
+s7.addthis.com.
+_134_50_9.
+elpollohipnotico.wordpress.com.
+168.215.228.77.in-addr.arpa.
+fbcdn-sphotos-a.akamaihd.net.
+c-0.19-a3094081.4010082.1518.19d4.3ea1.210.0.7u8bgmsrtmk94dmjibw29c4sq5.avqs.mcafee.com.
+a.root-servers.net.
+photos-b.ak.fbcdn.net.
+s10.histats.com.
+fxfeeds.mozilla.com.
+i4.ytimg.com.
+diad.capex.com.ar.
+z1851z6rp.10zi.
+clients4.google.com.
+156.227.84.200.in-addr.arpa.
+toolfarm.com.
+www.youpouch.com.
+harpiesbizarre.com.
+a.root-servers.net.
+mscrl.microsoft.com.
+t0.gstatic.com.
+41.244.197.65.in-addr.arpa.
+check4.facebook.com.
+weather.msn.com.
+cs5.wac.edgecastcdn.net.
+86.120.184.88.in-addr.arpa.
+www.goddiva.co.uk.
+gouvisgroup.com.s10a1.psmtp.com.
+s0.2mdn.net.
+creative.ak.fbcdn.net.
+e566.b.akamaiedge.net.
+i.ytimg.com.
+www.paypalobjects.com.
+31.73.171.201.in-addr.arpa.
+ironport-mx-vip.maxnet.net.nz.
+www.csidata.com.
+live4this.com.
+api.conduit.com.
+www.brooklyn.liu.edu.
+mx.zarlene.com.
+prophotos.ru.
+102.23.171.78.in-addr.arpa.
+connect.facebook.net.
+217.139.46.189.in-addr.arpa.
+apps.facebook.com.
+db._dns-sd._udp.0.1.168.192.in-addr.arpa.
+au.download.windowsupdate.com.
+kclinc.org.
+www.amazinghotgirls.com.
+profile.ak.fbcdn.net.
+plusone.google.com.
+spam.phison.com.
+static.ak.fbcdn.net.
+news.google.com.
+maps.google.com.
+28.126.156.201.in-addr.arpa.
+b-0.19-210d2479.1f0000.1518.19d4.3ea0.410.0.57n2b377h7e4m77in2dvzq28lq.avqs.mcafee.com.
+m.hotmail.com.
+75.140.141.190.in-addr.arpa.
+so35j64ls.x85r8p9k.
+sp.cwfservice.net.
+www.iegallery.com.
+upload.wikimedia.org.
+144.172.212.64.in-addr.arpa.
+downloads.bf-servers.com.
+9uaxokfq5.i77i8k7m.
+mail.capitalconservator.com.
+meengle.net.
+213.101.99.86.in-addr.arpa.
+www.coursokado.fr.
+api.bestvideodownloader.com.
+photos-b.ak.fbcdn.net.
+download.windowsupdate.com.
+stronzodimerda.it.
+dvdfab-hd-decrypter.malavida.com.
+m.hotmail.com.
+sup.live.com.
+static.ak.fbcdn.net.
+.
+searchjs.s3.amazonaws.com.
+www.apple.com.
+130.205.61.69.in-addr.arpa.
+a21a.com.
+_613_48_2.
+teredo.ipv6.microsoft.com.
+122.169.158.187.in-addr.arpa.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+www.resonancechina.com.
+scripts.affiliatefuture.com.
+download.windowsupdate.com.
+pepsico.trabajo.infojobs.net.
+www.keys4.me.
+ak1.abmr.net.
+beta.stun.voice.yahoo.com.
+developers.facebook.com.
+umunu.com.
+multiparking.com.
+profile.ak.fbcdn.net.
+gdata.youtube.com.
+1np4eey8c.y44y3o0i.
+252.220.51.190.in-addr.arpa.
+luttner.com.
+mobile.blackberry.com.
+dr._dns-sd._udp.0.0.0.5.in-addr.arpa.
+maps.google.com.
+ag-c.ru.
+122.188.66.187.in-addr.arpa.
+microtekmed.com.s8b1.psmtp.com.
+a.root-servers.net.
+www.baropen.com.au.
+53.32.56.85.in-addr.arpa.
+nt.go.th.
+146.194.51.190.in-addr.arpa.
+db._dns-sd._udp.0.1.168.192.in-addr.arpa.
+cyberlife.co.uk.
+moonconnection.com.
+dr._dns-sd._udp.0.129.37.10.in-addr.arpa.
+sitno.mgn.ru.
+benjaesoptimus.spaces.live.com.
+ppc.2-01-282a-0002.cdx.cedexis.net.
+www.bandoo.com.
+www.google-analytics.com.
+platform.twitter.com.
+ksn1-12-part2.kaspersky-labs.com.
+unreasonableness.com.
+_901_68_5.
+connect.facebook.net.
+safebrowsing.clients.google.com.
+frontiermedical.net.inbound15.mxlogic.net.
+223.152.123.201.in-addr.arpa.
+static.ak.fbcdn.net.
+a2.sphotos.ak.fbcdn.net.
+9.8.23.190.in-addr.arpa.
+live-radio.net.
+a3.sphotos.ak.fbcdn.net.
+apps.facebook.com.
+mail.alarm-plus.ru.
+62.71.112.87.in-addr.arpa.
+profile.ak.fbcdn.net.
+nvtc.org.
+clients1.google.com.
+fb-client-0.castle.zynga.com.
+dpz14.cocolog-nifty.com.
+35.45.132.144.in-addr.arpa.
+www.alean.ru.
+img.constantcontact.com.
+download.windowsupdate.com.
+amcourier.com.
+ecc.elevatorcontrols.com.
+pixel.facebook.com.
+www.frwl7.com.
+kxgdv4yc9.15rb.
+www.fortunebeach.com.
+www.cbox.ws.
+www.cenidiap.net.
+scripts.verticalacuity.com.
+a3.sphotos.ak.fbcdn.net.
+176.185.253.201.in-addr.arpa.
+a852.phobos.apple.com.
+a-0.19-2209e071.d0b0083.1518.19d3.3ea1.410.0.2jh8jqwju5dctz3u8lweue22q6.avqs.mcafee.com.
+a.root-servers.net.
+edge.sharethis.com.
+profiles.google.com.
+ad.doubleclick.net.
+a.root-servers.net.
+weather.services.conduit.com.
+tribalectic.com.
+www.google.com.
+a8.sphotos.ak.fbcdn.net.
+www.google.com.
+connect.facebook.net.
+ocsp.verisign.com.
+mujer.es.msn.com.
+adserver.itsfogo.com.
+v17.hispavista.com.
+www.tube43.com.
+www.google-analytics.com.
+safebrowsing-cache.google.com.
+es-es.facebook.com.
+photos-d.ak.fbcdn.net.
+bingo.bitrhymes.com.
+pubads.g.doubleclick.net.
+belarustime.ru.
+i5.cmail2.com.
+www.bywifi.com.
+116.183.0.186.in-addr.arpa.
+www.facebook.com.
+google.com.
+181.43.130.24.in-addr.arpa.
+googleads.g.doubleclick.net.
+218.107.107.190.in-addr.arpa.
+scapegoat.ru.
+s.whatsapp.net.
+linkhelp.clients.google.com.
+4ubpva8bj.o36h0o8j.
+www.youtube.com.
+www.eric-clapton.co.uk.
+149.84.160.189.in-addr.arpa.
+ad.foxnetworks.com.
+www.en.bpl.admcsport.com.
+140.122.168.192.in-addr.arpa.
+www.hotxxxasia.com.
+beacon-1.newrelic.com.
+136.150.32.114.in-addr.arpa.
+wzpo1.ask.com.
+photos-a.ak.fbcdn.net.
+a2.sphotos.ak.fbcdn.net.
+a.root-servers.net.
+www.lrc.rpi.edu.
+dns.camcctv.com.
+facemoods.com.
+25.231.31.190.in-addr.arpa.
+version.com.
+60.223.212.186.in-addr.arpa.
+queesproyecto.wordpress.com.
+sinar.co.id.
+s.stpost.com.
+a6.sphotos.ak.fbcdn.net.
+s-static.ak.fbcdn.net.
+landom.com.
+maps.google.de.
+safebrowsing.clients.google.com.
+www.gstatic.com.
+a.root-servers.net.
+www.nitzanonline.com.
+82.17.22.95.in-addr.arpa.
+mail.gosiger.com.
+asturaleza.blogspot.com.
+www.citydom24.pl.
+maxcdn.fooyoh.com.
+www.facebook.com.
+home.speedbit.com.
+teredo.ipv6.microsoft.com.
+static.ak.fbcdn.net.
+bhrei-com.relay1b.spamh.com.
+189.38.206.187.in-addr.arpa.
+profile.ak.fbcdn.net.
+d5nxst8fruw4z.cloudfront.net.
+ru.wikipedia.org.
+xxlss.com.
+s-static.ak.fbcdn.net.
+www.google.com.mx.
+www.facebook.com.
+www.goojue.com.
+ns1.dyndns.org.
+a749.g.akamai.net.
+cerato.wordpress.com.
+support.urbanairship.com.
+35.44.90.87.in-addr.arpa.
+wyq6l1:ds.o39m4e3c.
+a.root-servers.net.
+daddygrognard.blogspot.com.
+16.144.2.186.in-addr.arpa.
+mx.youtube.com.
+94.203.87.203.in-addr.arpa.
+atelier.org.
+170.216.108.114.in-addr.arpa.
+photos-e.ak.fbcdn.net.
+a.root-servers.net.
+genevatypewriters.blogspot.com.
+platform.ak.fbcdn.net.
+ajax.googleapis.com.
+lifeinfomation.com.
+119.176.155.79.in-addr.arpa.
+www.famosasmexicanas.net.
+mx.lasallegroup.com.
+v4.cache5.c.youtube.com.
+www.csmonitor.com.
+eltc.com.
+90.7.221.190.in-addr.arpa.
+www.youtube.com.
+www.sinais.salud.gob.mx.
+www.pangolin.com.
+179.250.18.189.in-addr.arpa.
+88.79.55.65.in-addr.arpa.
+up4.m5zn.com.
+external.ak.fbcdn.net.
+pagead2.googlesyndication.com.
+www.spaziogames.it.
+i4.ytimg.com.
+photos-g.ak.fbcdn.net.
+www.thebookyard.com.
+teredo.ipv6.microsoft.com.
+alerts.conduit-services.com.
+a5.da1.akamai.net.
+www.www.facebook.com.
+e566.b.akamaiedge.net.
+puzolencontrol.blogspot.com.
+www.pulpijuegos.com.
+googleads.g.doubleclick.net.
+a1.twimg.com.
+173.244.246.99.in-addr.arpa.
+www.onlinefunarcade.com.
+www.comunidadyprevencion.org.
+69.139.110.189.in-addr.arpa.
+d15gt9gwxw5wu0.cloudfront.net.
+mta5.am0.yahoodns.net.
+ads.matomy.com.
+teredo.ipv6.microsoft.com.
+19-courier.push.apple.com.
+msratingbureau.com.
+yxmpofgx6.z08f6u9x.
+dr._dns-sd._udp.0.129.37.10.in-addr.arpa.
+ytimg.l.google.com.
+1.gvt0.com.
+a3.sphotos.ak.fbcdn.net.
+194.227.122.128.in-addr.arpa.
+7yqllhxyp.31jx.
+support.google.com.
+www.googleadservices.com.
+a.root-servers.net.
+a.root-servers.net.
+liberomx4.libero.it.
+googleads.g.doubleclick.net.
+a.root-servers.net.
+6.227.224.190.in-addr.arpa.
+www.trialpay.com.
+www.friv2.org.
+adserver.adtech.de.
+polenimplement.com.
+omp1040.mail.ne1.yahoo.com.
+32.26.230.201.in-addr.arpa.
+hit.sunnydollars.net.
+www.facebook.com.
+sp.search-results.com.
+www.alejandramatus.cl.
+fqqyd171h.44mg.
+datafeed.weatherbug.com.
+244.144.254.180.in-addr.arpa.
+61.144.119.189.in-addr.arpa.
+djesibonajeb.com.
+russian-girls.name.
+lh6.googleusercontent.com.
+translate.google.com.mx.
+femalepop.tumblr.com.
+www.icams.es.
+17.203.240.195.in-addr.arpa.
+a.rad.msn.com.
+mail.gordos.com.
+www.facebook.com.
+www.umeng.com.
+pinklaserspa.com.
+www.amo.qc.ca.
+aybk.ru.
+brasil.babycenter.com.
+a.root-servers.net.
+71.208.97.94.in-addr.arpa.
+www.allhandbagfashion.com.
+mail.fanafel.pt.
+www.sohokid.com.ar.
+inxs.phpbbforum.eu.
+35.175.123.84.in-addr.arpa.
+122.173.102.201.in-addr.arpa.
+popravu.ru.
+www.mistressdemonic.com.
+connect.facebook.net.
+s7.addthis.com.
+freetrafficbar.com.
+img198.imageshack.us.
+intrawesttremblant.112.2o7.net.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+www.mineros.com.co.
+m.addthisedge.com.
+de-de.facebook.com.
+199.221.21.23.in-addr.arpa.
+jenchina.ucoz.ru.
+a.root-servers.net.
+syndication.mmismm.com.
+u3.hazipatika.com.
+www.google.com.
+emelian.ru.
+utils.babylon.com.
+www.google-analytics.com.
+195.80.139.69.in-addr.arpa.
+t.fuziontech.net.
+udc.msn.com.
+_107_11_9.
+teredo.ipv6.microsoft.com.
+132.157.229.77.in-addr.arpa.
+crown-energy.com.
+mp.rj.gov.br.
+www.jacklalanne.com.
+www.brits.co.uk.
+profile.ak.fbcdn.net.
+www.copa.com.
+iaechina.net.
+www.geekbecois.com.
+9-0.qlty.finarea.ch.
+138.147.232.201.in-addr.arpa.
+manahair.blogspot.com.
+talan.udm.ru.
+114.55.24.189.in-addr.arpa.
+www.cuadherpetol.com.ar.
+developers.facebook.com.
+218.191.77.190.in-addr.arpa.
+a.root-servers.net.
+zh-cn.facebook.com.
+ugbmzq.com.
+84.160.191.189.in-addr.arpa.
+www.radiorhemapresencia.com.
+fi-fi.facebook.com.
+182.251.56.187.in-addr.arpa.
+localhost.
+ocsp.geotrust.com.
+www.redpymes.org.ar.
+a.root-servers.net.
+smtp5.acsu.buffalo.edu.
+contentfilter.futuragts.com.
+howchi.net.
+shortime.com.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+mail.polfa-tarchomin.ru.
+yogi.apps.bittorrent.com.
+made-to-travel.com.
+25.241.232.66.in-addr.arpa.
+pacific.net.au.
+teredo.ipv6.microsoft.com.
+www.elcinema.com.
+www.facebook.com.
+www.divyy.net.
+224.138.242.88.in-addr.arpa.
+csi.gstatic.com.
+e566.b.akamaiedge.net.
+4.bp.blogspot.com.
+www.segob.gob.mx.
+internet-explorer-7.fr.malavida.com.
+ad.doubleclick.net.
+imap.gmail.com.
+163.137.234.201.in-addr.arpa.
+pixel.facebook.com.
+www.bangavet.com.
+platform.ak.fbcdn.net.
+a6.sphotos.ak.fbcdn.net.
+trgc.opt.fimserve.com.
+us.mg6.mail.yahoo.com.
+in.loreal.com.
+www.naturhome.org.
+i.microsoft.com.
+www.ecopics.com.
+janics.com.
+www.youtube.com.
+bicentenario.tamaulipas.gob.mx.
+126.37.37.190.in-addr.arpa.
+mail2mars.com.
+www.mininova.org.
+84.191.192.187.in-addr.arpa.
+safebrowsing-cache.google.com.
+wap.id.samsungmobile.com.
+www.speeduppro.com.
+131.236.206.190.in-addr.arpa.
+apps.facebook.com.
+www.29content14.com.
+84.208.0.181.in-addr.arpa.
+r1rk9np7bpcsfoeekl0khkd2juj27q3o-a-fc-opensocial.googleusercontent.com.
+thousidis.no-ip.biz.
+www.shopbenchmark.com.
+metrics.skype.com.
+vzlettime.ru.
+twimg0-a.akamaihd.net.
+178.195.124.70.in-addr.arpa.
+s.youtube.com.
+a0.twimg.com.
+solar.dp.ua.
+troyafotos.galeon.com.
+safebrowsing-cache.google.com.
+cargocollective.com.
+_305_41_3.
+davenportfoundationrepair.com.
+db._dns-sd._udp.0.1.168.192.in-addr.arpa.
+www.imagengratis.org.
+l3.image.peepeebabes.com.
+www.iafa.go.cr.
+cullprop.com.s5b2.psmtp.com.
+www.andrevanamstel.nl.
+a.root-servers.net.
+www.thegemstoneconnection.com.
+www.google-analytics.com.
+243.77.81.201.in-addr.arpa.
+enact.com.
+society6.com.
+marcusevans.com.rbl2.mcafee.com.
+0-143.channel.facebook.com.
+r._dns-sd._udp.lan.
+static.ak.fbcdn.net.
+www.mtvla.com.
+i.imgur.com.
+220.11.168.192.in-addr.arpa.
+byfiles.storage.msn.com.
+www.diariopuntual.com.
+www.weather.com.
+v6.nonxt8.c.pack.google.com.
+12.254.29.186.in-addr.arpa.
+s.pcdcdn.com.
+microtechnica.com.
+relay1.fitolek.com.
+orwells1984oregon.files.wordpress.com.
+mx2.mailhop.org.
+trixsters.net.
+www.wernerlau.com.
+m.addthisedge.com.
+mediageekzone.blip.tv.
+castalia.es.
+.
+www.chubbysistas.com.
+boing4u.net\032.
+creative.ak.fbcdn.net.
+matcher.bidder7.mookie1.com.
+www.msftncsi.com.
+www.fincasriazor.com.
+www.heylittledick.com.
+a.root-servers.net.
+www.nathalieschuterman.com.
+gateways2.aep.com.
+b-0.19-230e7219.11081.1518.19d4.3ea1.410.0.14kg454zt8ib4fr3gsldv6ejw5.avqs.mcafee.com.
+ak1s.abmr.net.
+148.26.156.201.in-addr.arpa.
+www.clearleadinc.com.
+bulbyonder.co.uk.
+d.p-td.com.
+www.y8.com.
+plus.google.com.
+60.45.35.173.in-addr.arpa.
+photos-b.ak.fbcdn.net.
+i4.ytimg.com.
+oipikrprhtzxtcp.biz.
+a1222.phobos.apple.com.edgesuite.net.
+checkip.dyndns.org.
+_541_39_7.
+181.142.155.93.in-addr.arpa.
+4.109.123.84.in-addr.arpa.
+www.chicaspilladas.com.ar.
+szchaoyueic.en.alibaba.com.
+15-courier.push.apple.com.
+mail.google.com.
+59.81.19.186.in-addr.arpa.
+a7.sphotos.ak.fbcdn.net.
+o-o.preferred.fra02s03.v1.lscache8.c.youtube.com.
+lh6.googleusercontent.com.
+80.56.92.186.in-addr.arpa.
+static.exoclick.com.
+sp.cwfservice.net.
+a.root-servers.net.
+pbttbc.bt.motive.com.
+barracuda.priocom.com.
+barras.virgula.com.br.
+appworld.blackberry.com.
+curious-george13.polyvore.com.
+fftoday.com.
+www.youtube.com.
+198.181.240.189.in-addr.arpa.
+176.151.83.98.in-addr.arpa.
+fr.y8.com.
+137.192.152.190.in-addr.arpa.
+a.root-servers.net.
+m.addthisedge.com.
+www.kenwoodvineyards.com.
+www.yaguar.com.
+19.78.61.74.in-addr.arpa.
+180.254.166.76.in-addr.arpa.
+www.twitter.com.
+6.66.158.187.in-addr.arpa.
+a.root-servers.net.
+a3.mzstatic.com.home.
+mx3.gcmhmr.com.
+58.226.237.189.in-addr.arpa.
+teredo.ipv6.microsoft.com.
+developers.facebook.com.
+cot7jg:al.g56k6i4k.
+artofdavidwalker.com.
+external.ak.fbcdn.net.
+a8.sphotos.ak.fbcdn.net.
+54.235.159.189.in-addr.arpa.
+www.adivinalesuscositas.blogspot.com.
+1.167.50.190.in-addr.arpa.
+t0.gstatic.com.
+fxfeeds.mozilla.com.
+ucci.org.ua.
+platform.twitter.com.
+updates3.pc-fix-cleaner.com.
+i1.ytimg.com.
+byfiles.storage.msn.com.
+28oawqsur.00kp.
+veronicauribe.wordpress.com.
+creative.ak.fbcdn.net.
+www-google-analytics.l.google.com.
+cdn3.rocketlanguages.com.
+js.wlxrs.com.
+en.mobile.wikipedia.org.
+nailpolishenthusiast.blogspot.com.
+a8.sphotos.ak.fbcdn.net.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+mail2.nwave.com.
+ssl.gstatic.com.
+www.foxsportsla.com.
+233.4.56.187.in-addr.arpa.
+litehosting.ru.
+www.supercardds.es.
+whos.amung.us.
+89.151.168.192.in-addr.arpa.
+fireclad.com.
+www.zkoss.org.
+googleads.g.doubleclick.net.
+cdylk4zdy.60ov.
+api.searchvideo.com.
+service.gc.apple.com.akadns.net.
+a1.twimg.com.
+65.173.89.85.in-addr.arpa.
+www.facebook.com.
+www.bingolines.com.
+yorktech.com.
+www.papeleriaalbe.com.uy.
+www.google.com.
+thejetpacker.com.
+a5.da1.akamai.net.
+i3.ytimg.com.
+connect.facebook.net.
+www.wosa.co.za.
+a.rad.msn.com.
+login.zoosk.com.
+bqzvet.com.
+mso61bybwcqlyd60pyl48hzc69n20n40dtj46bz.org.
+www.facebook.com.
+en.wordpress.com.
+www.roundup.com.
+photos-a.ak.fbcdn.net.
+www.google-analytics.com.
+ssl.gstatic.com.
+mail.sia-r.ru.
+www.20minutos.es.
+147.12.46.184.in-addr.arpa.
+84.199.1.181.in-addr.arpa.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+static.ak.fbcdn.net.
+apps.facebook.com.
+193.83.144.189.in-addr.arpa.
+shell.windows.com.
+rcp.na.blackberry.com.
+237.157.234.190.in-addr.arpa.
+ccc.usccb.org.
+clearance.cnet.com.
+a3.sphotos.ak.fbcdn.net.
+heartindiana.com.
+0-155.channel.facebook.com.
+103.9.76.95.in-addr.arpa.
+clients.teamtalk.com.
+met.adwhirl.com.
+teredo.ipv6.microsoft.com.
+apps.facebook.com.
+s.jimdo.com.
+srchsugg.funwebproducts.com.
+iphone.facebook.com.
+widergastro.ch.
+a5.sphotos.ak.fbcdn.net.
+www.d2open.com.
+www.littleariel.com.
+www.nsaayat.com.
+98.117.94.201.in-addr.arpa.
+pagead2.googlesyndication.com.
+93yhpjk9s.x26q2s6m.
+www.elgrafico.mx.
+159.254.234.190.in-addr.arpa.
+prse.de.
+knowle.fslife.co.uk.
+syndication.norton.com.
+buscador.emol.com.
+teredo.ipv6.microsoft.com.
+noticias.prodigy.msn.com.
+lenaten.ru.
+30.217.9.186.in-addr.arpa.
+finks.com.
+add.my.yahoo.com.
+a3.sphotos.ak.fbcdn.net.
+external.ak.fbcdn.net.
+a.root-servers.net.
+toys-house.kiev.ua.
+ksn2-12.kaspersky-labs.com.
+profilecommunication.com.
+119.103.201.190.in-addr.arpa.
+axifer.net.
+www.google.com.
+ib.adnxs.com.
+edge-mt.datpiff.com.
+kwo31n50l48n10lsp32bqivlvjviulynxnvl38.com.
+fishermfg.com.
+125.35.168.192.in-addr.arpa.
+apps.facebook.com.
+mail.in2m.com.
+www.facebook.com.
+bluebanana.ch.
+www.facebook.com.
+rhpmlgknnklmtyzn.biz.
+www.google-analytics.com.
+bay.messenger.services.live.com.
+www.casadellibro.com.
+msntest.serving-sys.com.
+206.86.51.190.in-addr.arpa.
+themes.googleusercontent.com.
+motorcyclepictures.faqih.net.
+img.foroalfa.org.
+ssl2.twitter.com.edgekey.net.
+ocsp.entrust.net.
+tunein.defjay.com.
+vcs1.msg.yahoo.com.
+apple.com.
+41.94.170.212.in-addr.arpa.
+twitter.com.
+sync.mathtag.com.
+a.root-servers.net.
+156.80.67.201.in-addr.arpa.
+checkip.dyndns.com.
+dns.msftncsi.com.
+gfx4.hotmail.com.
+www.belkin.com.
+51.89.194.122.in-addr.arpa.
+www.931amor.com.
+whk.com.au.
+mailgate.childsoc.org.uk.
+hubster.ru.
+ad.z5x.net.
+appenda.com.
+www.facebook.com.
+www.facebook.com.
+a.root-servers.net.
+203.194.239.189.in-addr.arpa.
+armada-ra.ru.
+kent157-visions.tumblr.com.
+planetaciclista.blogspot.com.
+s1.us.imgsrc.ru.
+106.144.222.189.in-addr.arpa.
+a.root-servers.net.
+clients4.google.com.
+247.80.67.201.in-addr.arpa.
+a1851.phobos.apple.com.edgesuite.net.
+freebaselibs.com.
+g.ceipmsn.com.
+www.google-analytics.com.
+www.feldmanns.com.
+external.ak.fbcdn.net.
+petsalon-ipa.animoca.com.
+go-usa.com.
+su.pr.
+yogananda-srf.org.
+1-courier.push.apple.com.
+156.92.166.88.in-addr.arpa.
+charteroakmedical.com.
+a.root-servers.net.
+a8.sphotos.ak.fbcdn.net.
+a.root-servers.net.
+27.media.tumblr.com.
+jrwheel.com.
+android.clients.google.com.
+profile.ak.fbcdn.net.
+235.13.24.190.in-addr.arpa.
+www.lost-away.org.
+zulu.tweetmeme.com.
+sp.cwfservice.net.
+i4.ytimg.com.
+www.animalarchitecture.org.
+ocsp.digicert.com.
+isprime.com.fpbns.net.
+224.27.171.189.in-addr.arpa.
+www.boobies.pro.
+nigelgearing.com.
+i2.ytimg.com.
+www.milfstalker.com.
+ssl.gstatic.com.
+gleeph.blogspot.com.
+253.0.162.190.in-addr.arpa.
+cdn-5.nflximg.com.
+d.yimg.com.
+a1402.w40.akamai.net.
+bodacion.com.
+118.217.82.200.in-addr.arpa.
+www.chandia.net.
+static.ak.fbcdn.net.
+cmodules.com.
+mb.vodch.mgn.ru.
+www.crafterscompanion.com.
+css.wlxrs.com.
+upnufyam.net.
+motturaspa.ru.
+eusors.com.
+36.212.84.200.in-addr.arpa.
+widgets.amung.us.
+135.11.97.189.in-addr.arpa.
+s2.youtube.com.
+5.232.88.186.in-addr.arpa.
+edison.upc.es.
+i4.ytimg.com.
+api.facebook.com.
+www.facebook.com.
+themeworxmedia.com.
+bestbooks.net.ru.
+cdn.api.twitter.com.
+26.220.44.194.in-addr.arpa.
+105.208.85.200.in-addr.arpa.
+aziacarpets.com.
+179.134.170.193.in-addr.arpa.
+www.facebook.com.
+66.223.232.200.in-addr.arpa.
+tracker.openbittorrent.com.
+sites.google.com.
+mail.tnx.net.
+s2.macupdate.com.
+44.247.50.200.in-addr.arpa.
+imap.gmail.com.
+247.151.201.112.in-addr.arpa.
+www.googleadservices.com.
+tonycpa.com.
+origin.by167w.bay167.mail.live.com.
+45.238.168.192.in-addr.arpa.
+thebetterlenders.com.
+6.214.247.88.in-addr.arpa.
+motox.accu-weather.com.
+mx10.who.int.
+libpacmed.com.
+25.123.32.190.in-addr.arpa.
+118.199.55.177.in-addr.arpa.
+www.pourquois.com.
+a.root-servers.net.
+accounts.google.com.
+juanalvarezm.blogspot.com.
+photos-e.ak.fbcdn.net.
+95.5.0.10.in-addr.arpa.
+d1j68ux4ukg4g1.cloudfront.net.
+i1.ytimg.com.
+39.220.226.63.in-addr.arpa.
+photos-a.ak.fbcdn.net.
+t2.gstatic.com.
+profile.ak.fbcdn.net.
+www.google.com.
+dns1.southeast-pa.com.
+plitka.spb.ru.
+www.facebook.com.
+www.elconfidencial.com.
+js.wlxrs.com.
+136.162.131.95.in-addr.arpa.
+shyr.sumy.org.
+sc.msn.com.
+186.242.19.187.in-addr.arpa.
+ax.su.itunes.apple.com.
+198.184.45.200.in-addr.arpa.
+a.root-servers.net.
+www.ddm.org.au.
+244.157.210.201.in-addr.arpa.
+www.comedy104.com.
+a4.sphotos.ak.fbcdn.net.
+www.youtube.com.
+eurosocialfiscal.org.
+www.wikipedia.nl.
+conf.socialvi.be.
+starwars.wikia.com.
+shared.live.com.
+talent-scale.com.
+www.braintreegateway.com.
+drayok.deviantart.com.
+imap.gmail.com.
+rktm.spb.ru.
+www.google-analytics.com.
+www.conama.cl.
+251.188.142.187.in-addr.arpa.
+scotia70657275.h1x.com.
+b.scorecardresearch.com.
+a.root-servers.net.
+a1505.l.akamai.net.
+swim-online.foroac.org.
+a.root-servers.net.
+secure-uk.imrworldwide.com.
+mtalk.google.com.
+conjugator.reverso.net.
+www.motors.ebay.com.
+apis.google.com.
+58.5.21.201.in-addr.arpa.
+www.vaginamaster.com.
+a.root-servers.net.
+0-292.channel.facebook.com.
+pterlink.ru.
+www.gayblacksexguide.com.
+smtp.touchpoint.co.nz.
+zh-cn.facebook.com.
+rs154dt.rapidshare.com.
+twitter.com.
+pixel.invitemedia.com.
+yoco-fashion.com.
+31.104.142.187.in-addr.arpa.
+dthesurfacingjungle.com.
+gfx3.hotmail.com.
+apps.facebook.com.
+a.c-0.19-230f5000.10011.1518.19d3.3ea1.210.0.rc42tqj7mtqr7ic8vlvkbc55nb.avqs.mcafee.com.
+csi.gstatic.com.
+press-centre.ru.
+www.tigersandstrawberries.com.
+casalcasadosp.blogspot.com.
+amigurumi-montse.blogspot.com.
+photos-f.ak.fbcdn.net.
+a7.sphotos.ak.fbcdn.net.
+www.iogear.com.
+aeggroup.net.s5a2.psmtp.com.
+140.2.133.86.in-addr.arpa.
+mr.vipmed.ru.
+apps.facebook.com.
+purosvideos.net.
+a8.sphotos.ak.fbcdn.net.
+yahoo.es.
+smtp4.absinternet.com.
+fy.wikipedia.org.
+freetelecom.fr.
+thumbs3.ebaystatic.com.
+creative.ak.fbcdn.net.
+heartbeat.dm.origin.com.
+channelgroup.net.
+msiv.com.
+checkip.dyndns.org.
+164.69.146.187.in-addr.arpa.
+interserve.org.
+mail.dyc.edu.
+googleads.g.doubleclick.net.
+au.answers.yahoo.com.
+urs.microsoft.com.
+filminfo.ru.
+smtp.siscom.net.
+twitter.com.
+safebrowsing.clients.google.com.
+fbtrn-lash.net.
+bps-stage.takeda.it.
+apps.facebook.com.
+pnrws.skype.com.
+developers.facebook.com.
+162.24.11.186.in-addr.arpa.
+a4.sphotos.ak.fbcdn.net.
+t.co.
+www.se-te.com.
+www.google.com.
+terra.com.br.
+www.xvideos.com.
+0.11-a309c081.21033.1518.19d4.3ea1.410.0.qtm62tr24fszzi9mickjf2p4tt.avqs.mcafee.com.
+rh99vd:it.83ec.
+go.srvnow.com.
+time.nist.gov.
+mail.idcfinancial.com.
+dfwgroup.com.
+sn1.gateway.messenger.live.com.
+dns.msftncsi.com.
+fr-fr.facebook.com.
+google.com.
+emediate.apmmedia.net.
+farm1.static.flickr.com.
+tmhomes.co.uk.
+.
+ar-ar.facebook.com.
+ns2.globalsources.com.
+ssl.gstatic.com.
+41.39.57.82.in-addr.arpa.
+enidnews.com.
+bashinform.ru.
+192.87.146.93.in-addr.arpa.
+pixel.facebook.com.
+profile.ak.fbcdn.net.
+apis.google.com.
+xmpp.device07.prod.capptain.com.
+www.linguee.es.
+safebrowsing-cache.google.com.
+www.xing.com.
+download.xbox.com.
+click.emailinfo2.bestbuy.com.
+teredo.ipv6.microsoft.com.
+www.youtube.com.
+nimbus.bitdefender.net.
+www.scubadivingphuket.net.
+amateursextapes.adultvideobuzz.com.
+bf74c17fce5b72a5f98844a4f8446b2c.co.cc.
+pixerloadbalancer-126298269.us-east-1.elb.amazonaws.com.
+www.statcounter.com.
+pixel.facebook.com.
+suggestqueries.google.com.
+contact.ebay.com.
+migbank.com.
+video.gazetevatan.com.
+zfxug.com.
+online-au.objective.com.
+developers.facebook.com.
+snippets.mozilla.com.
+www.clubofthewaves.com.
+_457_26_1.
+smtp.subscribe.ru.
+doug1izaerwt3.cloudfront.net.
+mx2.unccd.int.
+kermarak.radiolivre.org.
+www.masajecorporal.com.
+plugin.maldi.tv.
+i3.ytimg.com.
+a1505.l.akamai.net.
+nicholsonintl.com.
+18.151.155.178.in-addr.arpa.
+207.0.86.186.in-addr.arpa.
+www.wholesale-luxury.com.
+www.google.com.mx.
+ssl.gstatic.com.
+cdn.gigya.com.
+adobe.ugc.bazaarvoice.com.
+images.anniesattic.com.
+s-static.ak.fbcdn.net.
+89.111.46.186.in-addr.arpa.
+828vdo66y.p89s8x4y.
+jackinworld.com.
+www2.smartadserver.com.
+diamondtrustgame.com.
+s.youtube.com.
+filial.vrn.ru.
+ratchet.dayspring.com.
+info.juridicas.unam.mx.
+a.root-servers.net.
+www.z7mh.com.
+ns2.cheat.net.ru.
+pixel.facebook.com.
+xtu.me.
+bs.serving-sys.com.
+a.root-servers.net.
+s-static.ak.facebook.com.
+content.imorphosis.com.
+time.windows.com.
+mail.yimg.com.
+wwww.siliconera.com.
+a.root-servers.net.
+a.root-servers.net.
+169.163.29.89.in-addr.arpa.
+messenger.hotmail.com.
+photos-a.ak.fbcdn.net.
+89.221.25.190.in-addr.arpa.
+31.37.55.187.in-addr.arpa.
+www.almightycontent.com.
+images.apple.com.
+a.root-servers.net.
+sex-4.shemalepuzzle.com.
+10.152.3.108.in-addr.arpa.
+au.download.windowsupdate.com.
+www.davidemaggio.it.
+79.91.116.82.in-addr.arpa.
+db._dns-sd._udp.0.1.168.192.in-addr.arpa.
+plus.google.com.
+mx5.mail.yahoo.co.jp.
+cars.bookit.com.
+google.com.
+www.facebook.com.
+wwwimages.adobe.com.
+220.246.206.190.in-addr.arpa.
+developers.facebook.com.
+api.twitter.com.
+claremontounry.com.
+839.coll.ning.com.
+photos-b.ak.fbcdn.net.
+elvensoft.net.
+www.googleadservices.com.
+mail2.bravehost.com.
+online.speedbit.com.
+www.bing.com.
+13.55.157.186.in-addr.arpa.
+download744.avast.com.
+cemwxo1b6.14ta.
+a1157.phobos.apple.com.edgesuite.net.
+19.88.122.74.in-addr.arpa.
+13.160.224.195.in-addr.arpa.
+dns.msftncsi.com.
+an.d.chango.com.
+251.175.42.201.in-addr.arpa.
+www.facebook.com.
+checkip.dyndns.org.
+profile.ak.fbcdn.net.
+mx1.decknet.fr.
+jolenesbeenwriting.blogspot.com.
+www.ratepoint.com.
+horwath.co.uk.
+shorinryu.ru.
+csi.gstatic.com.
+www.bluegala.com.
+www.rumbo.es.
+ds.addthis.com.
+yahoo.com.
+237.209.168.192.in-addr.arpa.
+newsrss.bbc.co.uk.
+capital-network.net.
+profile.live.com.
+acatoday.org.inbound15.mxlogicmx.net.
+75.66.105.190.in-addr.arpa.
+ngmknaflk.o43q6v1v.
+buick.riobrancofac.edu.br.
+www.ee77ee.com.
+time.chttl.com.tw.
+google.com.
+www.teamtoyminator.org.
+teredo.ipv6.microsoft.com.
+www.facebook.com.
+ksn2-12.kaspersky-labs.com.
+www.granttube.com.
+mscmags.com.
+60.148.168.192.in-addr.arpa.
+galkasoft.ru.
+sleinous.dyndns.info.
+www.time.com.
+207.239.171.111.in-addr.arpa.
+dns.detroit.net.
+cde.unibe.ch.
+alerts.conduit-services.com.
+o-o.preferred.atl14s01.v24.lscache5.c.youtube.com.
+rostovinfo.ru.
+ar.answers.yahoo.com.
+www.coolrom.com.
+m.addthisedge.com.
+metrodotpop.com.
+remydumont.net.
+r._dns-sd._udp.0.55.211.10.in-addr.arpa.
+www.animal-crossing.com.
+www.internal.schools.net.au.
+50.174.244.190.in-addr.arpa.
+a.root-servers.net.
+photos-ugc.l.google.com.
+3h93lxn4m.90kd.
+202.68.21.187.in-addr.arpa.
+web38.jimdo-server.com.
+torontoboatshow.com.
+uaqxj:1oo.32xl.
+s.youtube.com.
+twitter.com.
+mozilla.pettay.fi.
+mail.live.com.
+www.libremercado.com.
+mail.samswope.com.
+unifi.lan.
+b._dns-sd._udp.0.1.168.192.in-addr.arpa.
+10.147.6.203.in-addr.arpa.
+mlonlinegeneration.wordpress.com.
+a.root-servers.net.
+2.63.139.178.in-addr.arpa.
+.
+mx.bmb.com.
+d2syub29v5lge2.cloudfront.net.
+tap2-cdn.rubiconproject.com.
+acte.org.2.arsmtp.com.
+clients1.google.com.
+p130.s523ll5pu6s1.com.
+balharbourflorida.com.
+a.root-servers.net.
+www.faperos.com.
+maps.gstatic.com.
+pixel.quantserve.com.
+www.facebook.com.
+52.102.66.187.in-addr.arpa.
+11.112.194.91.in-addr.arpa.
+api.myprecisionads.com.
+233.80.190.189.in-addr.arpa.
+addons.mozilla.org.
+williamzhou.com.
+i.dailymail.co.uk.
+a.root-servers.net.
+mail.defythis.com.
+gosprod-qos01.m3d-syd.ea.com.
+msn.match.com.akadns.net.
+www.lifestreetmedia.com.
+www.jorigames.com.
+www.facebook.com.
+demilovato.com.
+www.todopapas.com.
+msgr.updates.yahoo.com.
+i3.ytimg.com.
+215.57.110.201.in-addr.arpa.
+www.google.com.
+www.betaarchive.co.uk.
+i1.ytimg.com.
+yahoo.co.uk.
+astiline.ru.
+sktuote.ru.
+performair.com.
+altfarm.mediaplex.com.
+smtp3.wescorp.org.
+a6.sphotos.ak.fbcdn.net.
+s7.addthis.com.
+server82.appriver.com.
+urs.microsoft.com.
+rusneft.ru.
+www.felixjpalma.es.
+ksn1-12-part1.kaspersky-labs.com.
+mscrl.microsoft.com.
+133.171.82.200.in-addr.arpa.
+www.google.com.
+249.79.96.114.in-addr.arpa.
+snaps.vidiemi.com.
+b._dns-sd._udp.0.0.168.192.in-addr.arpa.
+a.rad.msn.com.
+pubads.g.doubleclick.net.
+a2.sphotos.ak.fbcdn.net.
+82.230.132.144.in-addr.arpa.
+www.bestcupon.com.ar.
+i3.ytimg.com.
+b3.mookie1.com.
+184.195.235.189.in-addr.arpa.
+_031_79_0.
+www.librolibro.es.
+unthb9r8d.20gt.
+ad.doubleclick.net.
+mia.mediaedgecia.com.
+110.133.23.62.in-addr.arpa.
+google.com.
+profile.ak.fbcdn.net.
+71.104.237.189.in-addr.arpa.
+cstdata.com.
+profile.ak.fbcdn.net.
+195.143.138.187.in-addr.arpa.
+amebasaladeriva.com.
+sympatico.ca.
+www.mozilla.org.
+nbyouthsoccer.com.
+15.187.245.190.in-addr.arpa.
+unisys.fr.
+jardines.ydecoraciondeinteriores.com.
+www.brokenbells.com.
+www.strictlysudoku.com.
+eo.wikipedia.org.
+www.aircharter-international.com.
+www.facebook-mp3.co.
+main.exoclick.com.
+a.root-servers.net.
+pixel.facebook.com.
+www.internostrum.com.
+_942_63_3.
+149.12.168.192.in-addr.arpa.
+a6.sphotos.ak.fbcdn.net.
+photos-e.ak.fbcdn.net.
+cinemaggel.blogspot.com.
+thetelephoneconnection.com.s7b2.psmtp.com.
+kbp.ru.
+208.122.82.200.in-addr.arpa.
+search-results.site90.net.
+pixel.facebook.com.
+www.googleadservices.com.
+a.root-servers.net.
+80.230.22.202.in-addr.arpa.
+static.ak.fbcdn.net.
+guspereyra.blogspot.com.
+abzurdah-filosofia.blogspot.com.
+hotelcall.ru.
+nineviya.ru.
+i4.ytimg.com.
+salud.regioncallao.gob.pe.
+profile.ak.fbcdn.net.
+connect.facebook.net.
+googleads.g.doubleclick.net.
+60.239.53.83.in-addr.arpa.
+228.66.19.61.in-addr.arpa.
+a.root-servers.net.
+ddns.iview-ddns.com.
+117.225.145.187.in-addr.arpa.
+tritiumband.com.
+luismartinez4.files.wordpress.com.
+amxinternational.com.
+a8.sphotos.ak.fbcdn.net.
+sin.net.
+p.rightaction.com.
+a.root-servers.net.
+distilleryimage4.instagram.com.
+s0.2mdn.net.
+dns.msftncsi.com.
+www.astroscu.unam.mx.
+corp.badoo.com.
+apps.facebook.com.
+weibo.pp.cc.
+a2.sphotos.ak.fbcdn.net.
+39.198.69.24.in-addr.arpa.
+espanol.answers.yahoo.com.
+www.jasonmomoa.com.
+164.241.182.189.in-addr.arpa.
+abbottcapital.com.s8a1.psmtp.com.
+photos-g.ak.fbcdn.net.
+0.13.123.94.in-addr.arpa.
+www.mokkabisuteria.com.
+db._dns-sd._udp.0.1.168.192.in-addr.arpa.
+news.buzzbox.com.
+hi-in.facebook.com.
+68.38.168.192.in-addr.arpa.
+profile.ak.fbcdn.net.
+docs.google.
+www.pokerroom.com.
+euroionia.com.
+108.135.168.192.in-addr.arpa.
+x-top.info.
+rubikspark.jimdo.com.
+clfrates.com.s8a2.psmtp.com.
+pegaso.ific.uv.es.
+me-cdn.effectivemeasure.net.
+ssl.gstatic.com.
+hootsuite.com.
+sp.cwfservice.net.
+a2.twimg.com.
+refundhomeloans.com.
+en.netlog.com.
+www.boardingschoolreview.com.
+gmaccmahd.com.
+www.mamafaiz.com.
+180.60.126.24.in-addr.arpa.
+r._dns-sd._udp.lan.
+d2108679.xoom.it.
+ssl.gstatic.com.
+firstchoice.ru.
+adserver.duetads.com.
+14.161.210.62.in-addr.arpa.
+rad.msn.com.
+www.howtogardenadvice.com.
+mail.vertex.com.ar.
+3ie33cpgj6dhi-c.c.yom.mail.yahoo.com.
+media.y8.com.
+147.210.211.220.in-addr.arpa.
+a1.sphotos.ak.fbcdn.net.
+www.todoanimes.com.
+a.root-servers.net.
+www.donutey.com.
+s2.youtube.com.
+10.35.62.177.in-addr.arpa.
+www.hotmail-iniciar-sesion.com.
+a639.da1.akamai.net.
+148.255.199.197.in-addr.arpa.
+me.effectivemeasure.net.
+www.symantec.com.akadns.net.
+graph.facebook.com.
+a1001.w40.akamai.net.
+r8b7ydgpg.e66c6k6z.
+ifreest.ru.
+onegaprim.ru.
+234.163.87.85.in-addr.arpa.
+208.50.126.123.in-addr.arpa.
+img1.blogblog.com.
+a2.sphotos.ak.fbcdn.net.
+232.131.162.189.in-addr.arpa.
+de-de.facebook.com.
+www.americanexpressfhr.com.
+m.facebook.com.
+a.root-servers.net.
+reidsteel.co.uk.
+www.wikimediafoundation.org.
+a5.sphotos.ak.fbcdn.net.
+ayudatec.cl.
+fbcdn-photos-a.akamaihd.net.
+clients1.google.com.br.
+89.55.36.174.in-addr.arpa.
+jrw.com.
+i.walmartimages.com.
+a7.sphotos.ak.fbcdn.net.
+photos-d.ak.fbcdn.net.
+mensmodelstalk.blog8.fc2.com.
+stun.client.akadns.net.
+s.youtube.com.
+www.ansp.gob.sv.
+gfx1.hotmail.com.
+a8.sphotos.ak.fbcdn.net.
+js.psp.guias-trucos-juegos.com.
+a.root-servers.net.
+plusone.google.com.
+a5.sphotos.ak.fbcdn.net.
+d37ts36x2rbd21.cloudfront.net.
+145.241.222.24.in-addr.arpa.
+www.gq.com.tw.
+www.update.microsoft.com.
+204.157.82.190.in-addr.arpa.
+d2098481.xoom.it.
+dam.cloud.kargo.com.
+safebrowsing-cache.google.com.
+photos-d.ak.fbcdn.net.
+ad.yieldmanager.com.
+a.root-servers.net.
+www.syriarose.com.
+swkins.com.s8a1.psmtp.com.
+a2.sphotos.ak.fbcdn.net.
+172.203.175.189.in-addr.arpa.
+gfx1.hotmail.com.
+86.147.156.78.in-addr.arpa.
+dns.msftncsi.com.
+a.root-servers.net.
+53.237.183.212.in-addr.arpa.
+mx.youtube.com.
+a8.sphotos.ak.fbcdn.net.
+www.youtube.com.
+www.geocities.com.
+migranviaje.wordpress.com.
+ssl.gstatic.com.
+downloads.networkmagic.com.
+connect.facebook.net.
+www.farskids168.com.
+asrengineering.com.
+static.ak.fbcdn.net.
+c-0.19-a309f481.483.1518.19d4.3ea1.210.0.gqsznzg3zhr6v264pgdsuub4vi.avqs.mcafee.com.
+a1001.w40.akamai.net.
+229.89.233.220.in-addr.arpa.
+120.3.198.72.in-addr.arpa.
+www.clubmed.com.my.
+3.233.10.186.in-addr.arpa.
+api.twitter.com.
+viagem.br.msn.com.
+aol.com.
+s-external.ak.fbcdn.net.
+client.akamai.com.
+247.16.33.46.in-addr.arpa.
+tdbde6gz7.g93z8f0c.
+80.23.222.189.in-addr.arpa.
+www.hotmail.com.
+169.35.145.189.in-addr.arpa.
+www.warezmedia.net.
+ssl.gstatic.com.
+kailep.deviantart.com.
+vote.mmosite.com.
+www.morevisits.info.
+www.grape-info.com.
+powerwall.msnbc.msn.com.
+a1505.l.akamai.net.
+211.217.131.187.in-addr.arpa.
+m.addthisedge.com.
+plus.google.com.
+rs424l33.rapidshare.com.
+www.ridemygirls.com.
+a7.sphotos.ak.fbcdn.net.
+theageofreason.org.
+grants1.nih.gov.
+tcfhlaw.com.s8a2.psmtp.com.
+static.ak.fbcdn.net.
+elsphiprtp001.science.regn.net.
+click.info.simpletuition.com.
+a.root-servers.net.
+photos-a.ak.fbcdn.net.
+a7.sphotos.ak.fbcdn.net.
+euro.mediotiempo.com.
+m.addthisedge.com.
+wordpress.com.dob.sibl.support-intelligence.net.
+navnbwnscwa.cc.
+a1507.b.akamai.net.
+a.root-servers.net.
+tssl.kewego.com.
+www.ero-advertising.com.
+armmf.adobe.com.
+i-55.com.
+zacapacity.mundoanuncio.com.gt.
+pup.raz.htcsense.com.
+services.windowsmedia.com.
+99.154.92.201.in-addr.arpa.
+85.163.79.201.in-addr.arpa.
+sp.cwfservice.net.
+safebrowsing.clients.google.com.
+cqrjcpb9x.c09h8i7w.
+www.erpsoftwaredownload.com.
+dns2.easydns.net.
+safebrowsing.clients.google.com.
+ksn2-12.kaspersky-labs.com.
+mail.
+vivalamodaa.blogspot.com.
+dpmconsult.de.
+www.humpingbunny.com.
+92.43.90.190.in-addr.arpa.
+www.loscostos.info.
+teamxenon.com.
+www.bago.com.
+r._dns-sd._udp.0.0.2.10.in-addr.arpa.
+cbkservices.com.
+201.201.58.71.in-addr.arpa.
+28.media.tumblr.com.
+www.reforma.com.
+170.159.52.83.in-addr.arpa.
+i3.ytimg.com.
+ap.lijit.com.
+dns.msftncsi.com.
+ssl.gstatic.com.
+bs.serving-sys.com.
+249.50.215.109.in-addr.arpa.
+228.135.178.190.in-addr.arpa.
+sites.google.com.
+pixel.facebook.com.
+external.ak.fbcdn.net.
+www.shiou.ws.
+bestflatironsforhair.com.
+172.142.54.187.in-addr.arpa.
+external.ak.fbcdn.net.
+a.root-servers.net.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+239.237.137.186.in-addr.arpa.
+185.15.157.201.in-addr.arpa.
+174.37.152.189.in-addr.arpa.
+secure.logmein.com.
+asiancondition.blogspot.com.
+154.102.144.186.in-addr.arpa.
+r._dns-sd._udp.0.129.37.10.in-addr.arpa.
+g77l:yezr.u06v0k8p.
+external.ak.fbcdn.net.
+unsubscribe.fromdoppler.com.
+cdn.foxadd.com.
+myimg.zhaopin.com.
+daddyforever.com.
+www.strawsticksandbricks.com.
+sc19.rules.mailshell.net.
+a659.b.akamai.net.
+636f6e74656e74.6e657773696e63.636f6d.80hcfaba321.webcfs00.com.
+www.flashvault.net.
+firma.eniro.dk.
+db._dns-sd._udp.0.1.168.192.in-addr.arpa.
+vmx.shiplpskey.com.redcondor.net.
+fxprofsignal.ru.
+static.ak.fbcdn.net.
+ksn2-12.kaspersky-labs.com.
+i3.ytimg.com.
+30-60-90-day-sales-plan.com.
+a2.sphotos.ak.fbcdn.net.
+csi.gstatic.com.
+lyricskeeper.fr.
+232.148.42.95.in-addr.arpa.
+s-static.ak.fbcdn.net.
+v8.nonxt3.c.youtube.com.
+clients2.google.com.
+api-read.facebook.com.
+www.balnaves.com.
+clock.fmt.he.net.
+ufrnet.ufrn.br.
+mx.mechel.com.
+a.root-servers.net.
+a-0.19-25093001.c0a0083.1518.19c4.3ea1.210.0.hr8fzrijs2f2fuk2bz5jqjl3fj.avqs.mcafee.com.
+g.ceipmsn.com.
+rcfesq.com.
+www.skins.tv.
+www.cooperativa.cl.
+i.ytimg.com.
+www.vpnpop.com.
+a7.sphotos.ak.fbcdn.net.
+pphsh2lx2.p76t7s5s.
+a8.sphotos.ak.fbcdn.net.
+travel.wikia.com.
+a3.da1.akamai.net.
+www.buildabear.ae.
+www.frype.lt.
+94.5.1.181.in-addr.arpa.
+poemi-carolina.blogspot.com.
+csi.gstatic.com.
+fashionloven.com.
+nuvxak1h1.99fb.
+www.1musica.com.
+plusone.google.com.
+bluemars.com.
+johnconti.com.s6a2.psmtp.com.
+a.root-servers.net.
+completecolour.com.au.
+b-0.19-a30e8008.10081.1518.19d3.3ea1.410.0.gu1k3w3q7l4hm126j4jqbi9ldb.avqs.mcafee.com.
+b.scorecardresearch.com.
+www.judithpaton.com.
+ad.z5x.net.
+fbcdn-photos-a.akamaihd.net.
+s0.2mdn.net.
+hazuki-pat.com.
+fashion4chill.com.
+tiresias.gr.
+planetfallas.com.
+90.40.58.186.in-addr.arpa.
+www.nobodycares.ca.
+ads.adxpansion.com.
+clxrcvnsse.ms.
+ds.serving-sys.com.
+google.com.mx.
+www.squashleon.com.
+pegasus.baltmd.ru.
+crl.thawte.com.
+gfx1.hotmail.com.
+profiles.google.com.
+247.109.126.80.in-addr.arpa.
+mail.msss.ru.
+www.bigtitsroundasses.com.
+t0.gstatic.com.
+www.google-analytics.com.
+time.chttl.com.tw.
+mail2.abena.dk.
+pixel.facebook.com.
+bejomi1.es.tl.
+www.google.com.
+doglover.com.
+es-es.facebook.com.
+alfon.org.
+ns1.comtelligence.net.
+kordp.ru.
+141.1.168.192.in-addr.arpa.
+api.tweetmeme.com.
+tqbnngfpzworfmp.biz.
+mail.live.com.
+a1007.w43.akamai.net.
+18.9.168.192.in-addr.arpa.
+us.mg4.mail.yahoo.com.
+a.root-servers.net.
+www.bywifi.com.
+static2.embarazoymas.com.
+directcopiersupplies.com.
+_481_76_9.
+photos-f.ak.fbcdn.net.
+eltiomananero.blogspot.com.
+www.giochislot.com.
+liranroll.com.mx.
+a0.twimg.com.
+a998.mm1.akamai.net.
+platform.twitter.com.
+s-static.ak.fbcdn.net.
+www.gda.com.
+www.juegosdecarrosgratis.co.
+external.ak.fbcdn.net.
+42.168.243.148.in-addr.arpa.
+img7.sencha.com.
+www.google.com.
+mx2.hotmail.com.
+tag.admeld.com.
+15.216.51.68.in-addr.arpa.
+www.cachador.co.
+vocid-cdn.elnortedecastilla.es.
+saiteprice.ru.
+www.wikimediafoundation.org.
+www.mostonline.org.
+pixel.facebook.com.
+api.twitter.com.
+buddgroup.com.s5a1.psmtp.com.
+www.zeplan.biz.
+google.com.
+ntn-group.ru.
+reddit.com.
+220.131.221.87.in-addr.arpa.
+pt-br.facebook.com.
+www.redtube.com.
+www.playing2.com.
+liken0ther.no-ip.biz.
+framanc.com.
+89.180.248.70.in-addr.arpa.
+fne.net.
+www.e-computo.net.
+91.92.231.190.in-addr.arpa.
+www.google.com.mx.
+72.107.11.201.in-addr.arpa.
+photos-g.ak.fbcdn.net.
+api.facebook.com.
+ax.init.itunes.apple.com.
+m2m1.inner-active.com.
+sp.cwfservice.net.
+www.facebook.com.
+static.ak.fbcdn.net.
+www.dramainnature.com.
+26.194.232.24.in-addr.arpa.
+www.vjoon.com.
+data.flurry.com.
+mexico32.com.
+pituco.com.
+side2.no.
+om98.ru.
+med.uni-heidelberg.de.
+es-la.facebook.com.
+bjjweekly.com.
+155.7.177.189.in-addr.arpa.
+www.ledevoir.com.
+117.137.37.190.in-addr.arpa.
+peliculasinmegavideo.com.
+hammerson.com.s200a1.psmtp.com.
+bankom.ru.
+kamidesunya.blogspot.com.
+api.twitter.com.
+crl.microsoft.com.
+widgets.amung.us.
+syndication.exoclick.com.
+120.52.18.211.in-addr.arpa.
+vthumb.ak.fbcdn.net.
+shioz.jp.
+tsm01.eset.com.
+77.39.225.190.in-addr.arpa.
+a3.sphotos.ak.fbcdn.net.
+a.root-servers.net.
+us1.badoo.com.
+adsx.greystripe.com.
+ptgh.co.uk.pri-mx.uk0109.smtproutes.com.
+ccm.imn.intel.com.
+www.tumblr.com.
+naturalmedications.com.
+220.173.103.201.in-addr.arpa.
+76.147.15.194.in-addr.arpa.
+www.metalicas.estimulaciontemprana.org.
+zhz.ivanovo.ru.
+92.91.38.186.in-addr.arpa.
+iphone-wu.apple.com.
+creative.ak.fbcdn.net.
+231.101.24.190.in-addr.arpa.
+a2.sphotos.ak.fbcdn.net.
+infinitos.es.
+mail1.trellist.com.
+api-read.facebook.com.
+ocs.ebay.com.
+external.ak.fbcdn.net.
+20.184.251.189.in-addr.arpa.
+static-cdn2.ustream.tv.
+35-courier.push.apple.com.
+creative.ak.fbcdn.net.
+gumaih.com.
+mail.
+tiny.cc.
+yahoo.com.
+a.root-servers.net.
+dns.msftncsi.com.
+www.vintageandchiclove.com.
+www.routledgementalhealth.com.
+apps.facebook.com.
+14.134.110.186.in-addr.arpa.
+photos-d.ak.fbcdn.net.
+jbzuu.beastavsclub.com.
+www.soc-neuro-onc.org.
+arabidopsis.info.
+shop.tfl.gov.uk.
+themnaxs.deviantart.com.
+janegrey.hubpages.com.
+moreapps.droidhen.com.
+an.tacoda.net.
+tair.by.
+dsn5.d.skype.net.
+uzhnp.gng.com.ua.
+platform.twitter.com.
+211.57.167.218.in-addr.arpa.
+l.yimg.com.
+hamachi-dc.logmein-gateway.com.
+www.1001postales.com.
+www8.agame.com.
+a3.twimg.com.
+developers.facebook.com.
+billing.sharo4ka.ru.
+dns.msftncsi.com.
+www.youtube.com.
+www.google-analytics.com.
+idpix.media6degrees.com.
+blst.msn.com.
+a1.sphotos.ak.fbcdn.net.
+c479837.r37.cf2.rackcdn.com.
+a.root-servers.net.
+sp.cwfservice.net.
+profile.ak.fbcdn.net.
+fb-zc1.cityville.zynga.com.
+mfaltd.com.s8b2.psmtp.com.
+ma90-r.analytics.edgesuite.net.
+www2.cromos.com.co.
+88.236.82.186.in-addr.arpa.
+141.217.212.201.in-addr.arpa.
+www.youtube.com.
+www.rctopsites.com.
+i4.ytimg.com.
+c.statcounter.com.
+thehizoku.com.
+57.226.142.187.in-addr.arpa.
+124.webim0230.webim.myspace.com.
+profile.ak.fbcdn.net.
+2.160.108.216.in-addr.arpa.
+www.cameras.co.uk.
+www.youtube.com.
+b._dns-sd._udp.0.1.168.192.in-addr.arpa.
+www.facebook.com.
+matineeashell.net.
+proxy.yospb.yahoo.com.
+prttravel.net.
+17.217.134.216.in-addr.arpa.
+a2.sphotos.ak.fbcdn.net.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+nimdev.com.2.0001.arsmtp.com.
+www.synchrondatenbank.de.
+www.lokotop.net.
+www.google.com.
+graph.facebook.com.
+mail.google.com.
+a.ads2.msads.net.
+ocsp.verisign.com.
+www.emol.com.
+profile.ak.fbcdn.net.
+mx.youtube.com.
+www.facebook.com.
+rubennavarrofilms.com.
+immo-trend.at.
+track.bobs-tgirls.com.
+abcblobal.net.
+bs.serving-sys.com.
+166.94.233.99.in-addr.arpa.
+flippingtypical.com.
+photos-h.ak.fbcdn.net.
+www.imagenesdemaria.com.
+nospam.chilitech.net.
+video.google.com.mx.
+a.root-servers.net.
+2.bp.blogspot.com.
+de08vphraus02.honeywell.com.
+yyy.com.
+bitbucket.fastpace.org.
+147.132.162.189.in-addr.arpa.
+anywhere.platform.twitter.com.
+edge.quantserve.com.
+api-read.facebook.com.
+aqxok8whh.04dd.
+www.meusrecados.com.
+juegos.latingames.com.
+www.update.microsoft.com.
+safebrowsing-cache.google.com.
+www.freesexnavigator.com.
+dvanemorris.com.
+www.fempclm.com.
+xml12es.farolatino.com.
+twitter.com.
+getmortgagez.com.
+ib.mookie1.com.
+a3.sphotos.ak.fbcdn.net.
+photos-d.ak.fbcdn.net.
+www.gourmetfly.com.
+www.deviantart.com.
+www.illinoishistory.gov.
+b92.yahoo.co.jp.
+yahoo.com.
+cdn.yottos.com.
+a.root-servers.net.
+3runescape8.no-ip.biz.
+forum.playfish.com.
+www.16bitsoft.com.
+204.3.135.186.in-addr.arpa.
+a.root-servers.net.
+aspmx.datainfosys.net.
+static.ak.facebook.com.
+a.root-servers.net.
+lasersafety.com.
+emotion-photo.ru.
+gw-mail6.3rdstudio.net.
+mikewarez.disqus.com.
+c:emeiy98.p00s4w0z.
+www.facebook.com.
+redirector.c.youtube.com.
+e4805.b.akamaiedge.net.
+3wmexico.com.dnsbl7.mailshell.net.
+a.root-servers.net.
+a2.sphotos.ak.fbcdn.net.
+english.mag2.com.
+www.facebook.com.
+53.72.25.95.in-addr.arpa.
+116.5.74.180.in-addr.arpa.
+sp.cwfservice.net.
+subarcade.com.
+120.39.151.79.in-addr.arpa.
+2007.ispace.ci.fsu.edu.
+zww.me.
+a3.sphotos.ak.fbcdn.net.
+fbio.uh.cu.
+55.181.160.187.in-addr.arpa.
+24.154.72.190.in-addr.arpa.
+pagead2.googlesyndication.com.
+imgtech.ru.
+tropiezosdelavida.blogspot.com.
+hotmail.it.
+a8.sphotos.ak.fbcdn.net.
+a.root-servers.net.
+mosrembyt.ru.
+2.38.133.174.in-addr.arpa.
+www.trenesmls.es.
+plus.google.com.
+accounts.google.com.
+ads.yimg.com.
+www.noticiasdelcosmos.com.
+122.163.149.109.in-addr.arpa.
+googleads.g.doubleclick.net.
+amadeus.lv.
+counter.yadro.ru.
+toabonothfaci.ph.
+90.164.222.189.in-addr.arpa.
+translation.toolbar.conduit-services.com.
+staticapp.icpsc.com.
+screamtour.com.
+173.100.132.190.in-addr.arpa.
+zoomyummy.com.
+surveyclub.com.
+z58lfabb3.j23h7z2t.
+dns.msftncsi.com.
+a8.sphotos.ak.fbcdn.net.
+229.75.154.187.in-addr.arpa.
+a.root-servers.net.
+_137_19_1.
+a1.twimg.com.
+www.underwaterjournal.com.
+www.update.microsoft.com.
+www.youtube.com.
+compartiendoconmisamigas.blogspot.com.
+accounts.google.com.
+randyfox.com.
+77.161.240.201.in-addr.arpa.
+videos.starmedia.com.
+101.249.201.86.in-addr.arpa.
+207.54.181.189.in-addr.arpa.
+google-earth.windows.brothersoft.com.
+d2058743.instant.xoom.it.
+wsihawaii.com.
+www.detail-mania.com.
+www.statcounter.com.
+platform.ak.fbcdn.net.
+www.youtube.com.
+www.arr-tv.com.
+prodigy.msn.com.
+a1.sphotos.ak.fbcdn.net.
+127.0.0.1.
+entretenimiento.latam.msn.com.
+149.18.224.159.in-addr.arpa.
+wpad.
+www.gstatic.com.
+a.root-servers.net.
+thrashers.nhl.com.
+i.ytimg.com.
+mail1.imco-inc.net.
+a1003.w41.akamai.net.
+www.paranormalhaven.com.
+www.historiacocina.com.
+spamfilter.rclick.com.
+235.225.39.187.in-addr.arpa.
+37.23.168.192.in-addr.arpa.
+shared.live.com.
+b._dns-sd._udp.0.1.168.192.in-addr.arpa.
+i.indiafm.com.
+static.ak.connect.facebook.com.
+i34.tinypic.com.
+connect.facebook.net.
+ad.harrenmedianetwork.com.
+25.53.149.187.in-addr.arpa.
+_452_73_8.
+inkincpr.com.
+groups.google.com.mx.
+kln.com.inbound15.mxlogic.net.
+db._dns-sd._udp.0.1.168.192.in-addr.arpa.
+nuevaspeliculas.info.
+a.root-servers.net.
+pagead2.googlesyndication.com.
+a372.phobos.apple.com.
+201.66.208.84.in-addr.arpa.
+flyadi-com.relay1c.spamh.com.
+elclubdelaslocaspositivas.blogspot.com.
+frankrewold.com.
+bilder.clipfish.de.
+210.254.198.190.in-addr.arpa.
+193.40.55.187.in-addr.arpa.
+gfx3.hotmail.com.
+3.51.160.187.in-addr.arpa.
+photos-d.ak.fbcdn.net.
+docs.google.com.
+127.0.0.1.
+b._dns-sd._udp.belkin.
+91.230.132.189.in-addr.arpa.
+www.youtube.com.
+www.incredimailshop.com.
+mail.poyatos.ru.
+marketpioneer.com.s7a2.psmtp.com.
+83.1.217.74.in-addr.arpa.
+segutronic.com.
+view.atdmt.com.
+chromejs.s3.amazonaws.com.
+7.155.93.195.in-addr.arpa.
+www.google.com.
+2kme3ic3a.f48m4o4f.
+67.208.114.187.in-addr.arpa.
+ft.ntvspor.net.
+mail.southtel.ru.
+imytravel.ru.
+img824.imageshack.us.
+creatives.livejasmin.com.
+mail.ufps.tmb.ru.
+js.wlxrs.com.
+93.74.137.190.in-addr.arpa.
+profile.ak.fbcdn.net.
+elektron.pl.
+blog.apesoft.es.
+linuxsix.blogspot.com.
+www.nu.edu.sa.
+t1.gstatic.com.
+esphoto500x500.mnstatic.com.
+sfx.en.alibaba.com.
+cnfg.montiera.com.
+www.jazztelydigitalplus.com.
+www.cinmaeg.com.
+pofboxing.perm.ru.
+static.ak.fbcdn.net.
+a.root-servers.net.
+googlemail.l.google.com.
+snt0-omc1-s21.snt0.hotmail.com.
+mx1.canterburycoffee.com.
+crl.microsoft.com.
+ad.smowtion.com.
+en-us.fxfeeds.mozilla.com.
+239.102.80.201.in-addr.arpa.
+photos-g.ak.fbcdn.net.
+api.twitter.com.
+mbsg.intel.com.
+external.ak.fbcdn.net.
+www.rootsweb.ancestry.com.
+profile.ak.fbcdn.net.
+b.scorecardresearch.com.
+beita-misstrapitos.blogspot.com.
+emob220.photobucket.com.
+231.185.211.189.in-addr.arpa.
+autoroom-usa.tk.
+ssl.gstatic.com.
+smallenginewarehouse.com.s9b1.psmtp.com.
+www.nickarcade.com.
+a996.mm1.akamai.net.
+static.ak.fbcdn.net.
+toolbarqueries.l.google.com.
+i4.ytimg.com.
+www.macizorras.com.
+196.70.188.201.in-addr.arpa.
+www.manukau.ac.nz.
+gomezdecadiz.blogspot.com.
+106.161.193.190.in-addr.arpa.
+245.203.103.190.in-addr.arpa.
+www.advancescripts.com.
+www.tiedtortured.com.
+bbcore.cloudapp.net.
+gfx2.hotmail.com.
+hfengine.com.
+yui.yahooapis.com.
+www.bywifi.com.
+7md1loq:t.49rf.
+ironplanet.com.
+i52.tinypic.com.
+233.28.109.200.in-addr.arpa.
+www.decentral.com.ar.
+113.153.231.190.in-addr.arpa.
+s10.histats.com.
+a995.mm1.akamai.net.
+yhhlptf2u.n31p9a6l.
+www.google.com.mx.
+167.64.82.200.in-addr.arpa.
+www.pathology.vcu.edu.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+brig.spb.ru.
+maktoob.news.yahoo.com.
+www.polskastacja.pl.
+mail.live.com.
+goldbarshop.com.
+microsoft-netmeeting.archivospc.com.
+a1408.w43.akamai.net.
+skydrive.live.com.
+public.blu.livefilestore.com.
+235.156.104.186.in-addr.arpa.
+wiprospectramind.com.
+120.254.43.99.in-addr.arpa.
+malah.biz.
+it-it.facebook.com.
+www.imparoax.com.mx.
+strangefunnyworld.com.
+hombrerefranero.blogspot.com.
+www.philcollins.
+silverstockreport.com.
+osnovnoy.ru.
+adobe-acrobat-professional.softonic.com.
+centes01.cuttingedgenet.com.
+gud.com.
+workface.com.
+photos-e.ak.fbcdn.net.
+apple.ease.lsoft.com.
+231.47.25.125.in-addr.arpa.
+www.everestauction.com.au.
+lucasboutique.bigcartel.com.
+www.academiademusica.cl.
+_321_49_5.
+relay.voice.edge.messenger.live.com.
+bluebird2.betonmarkets.com.
+apis.google.com.
+photos-f.ak.fbcdn.net.
+a8.sphotos.ak.fbcdn.net.
+a-0.19-a30a6089.c010082.1518.19d3.3ea1.210.0.k4zg82371ek3ijdgpn6qls1b1j.avqs.mcafee.com.
+static.www.occ.com.mx.
+225.51.115.186.in-addr.arpa.
+aarabladies.com.
+marymount.fr.
+inferno.demonoid.com.
+googleapis.l.google.com.
+m.adnxs.com.
+www.pymeservices.com.
+cdn1.thumbs.xogogo.com.
+7.152.30.194.in-addr.arpa.
+ssl.gstatic.com.
+www.puebla.com.mx.
+adc-orbit.telefonica.com.
+dinell.ru.
+55.158.157.190.in-addr.arpa.
+m.addthisedge.com.
+cf.addthis.com.
+orlandoenespanol.com.
+190.2.133.186.in-addr.arpa.
+ad.yieldmanager.com.
+csi.gstatic.com.
+129.53.246.190.in-addr.arpa.
+a.root-servers.net.
+pagead2.googlesyndication.com.
+www.ciat.cgiar.org.
+www.faceinhole.co.
+platform.twitter.com.
+time.stdtime.gov.tw.
+profile.ak.fbcdn.net.
+www.sepomexyuc.gob.mx.
+170.231.160.190.in-addr.arpa.
+a.root-servers.net.
+175.37.18.177.in-addr.arpa.
+google.com.
+136.31.12.190.in-addr.arpa.
+www.efectivale.com.mx.
+billing.sharo4ka.ru.
+www.kardelenyucel.com.
+safebrowsing-cache.google.com.
+34.236.172.190.in-addr.arpa.
+gvntv.gvnstudio.com.
+eset.122.2o7.net.
+www.facebook.com.
+cfile157.uf.daum.net.
+www.mbt-shoes-sale.info.
+s3.amazonaws.com.
+id.wikipedia.org.
+98.241.153.189.in-addr.arpa.
+moviestarpets.com.
+v12.lscache2.c.youtube.com.
+code.jquery.com.
+.
+vecinos-1.blogspot.com.
+www.google.com.
+www.conchamayordomo.com.
+localcardonors.com.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+mail.okhammaren.se.
+75.195.104.186.in-addr.arpa.
+theclaw.net.
+nombresdebebe.blogspot.com.
+thwfx.piczo.com.
+laurelriverdesigns.com.
+adsx.greystripe.com.
+seymourjohnson.af.mil.
+yeyeolade.files.wordpress.com.
+local-bay.contacts.msn.com.
+41.240.185.190.in-addr.arpa.
+rtduuo8c1.02pn.
+i-lensk.ru.
+www.apple.com.
+myintelligentlife.wordpress.com.
+aidps.atdmt.com.
+blog.pressdisplay.com.
+west.thomson.com.
+www.manga.it.
+a.root-servers.net.
+www.google.com.
+partner.googleadservices.com.
+www.childrensbooksforever.com.
+montel.isa-geek.org.
+11.48.168.192.in-addr.arpa.
+164.146.161.189.in-addr.arpa.
+_692_60_6.
+www.decentral.com.ar.
+a.root-servers.net.
+tap-cdn.rubiconproject.com.
+blogs.nybooks.com.
+s-static.ak.facebook.com.
+a.root-servers.net.
+lavieenrosegirl.blogspot.com.
+www.tvdoo.it.
+ansonic.com.au.
+www.hfcbank.co.uk.
+p08-mobilebackup.icloud.com.akadns.net.
+www.endandit.nl.
+havenrefuge.org.uk.
+www.populars.ru.
+155.135.120.69.in-addr.arpa.
+80.134.41.187.in-addr.arpa.
+photos-d.ak.fbcdn.net.
+bomberos.cl.
+icaewmessaging.net.
+68.106.80.88.in-addr.arpa.
+static.ak.facebook.com.
+ahhelp.me.
+secure.wlxrs.com.
+atconnercpa.com.
+a.root-servers.net.
+b._dns-sd._udp.0.2.168.192.in-addr.arpa.
+154.200.83.186.in-addr.arpa.
+anycast.perf.glbdns.microsoft.com.
+ajax.googleapis.com.
+jaclninc.com.
+ad.adnetwork.net.
+orcart.facebook.com.
+i4.ytimg.com.
+photos-h.ak.fbcdn.net.
+www.facebook.com.
+pubads.g.doubleclick.net.
+a.root-servers.net.
+sidroga.com.
+graph.facebook.com.
+alerts.conduit-services.com.
+mail.adelphia.net.
+accountservices.msn.com.
+www.nonude-free-photos.com.
+googleads.g.doubleclick.net.
+s1-word-view.vo.msecnd.net.
+28.75.96.58.in-addr.arpa.
+tc6.easythumbhost.com.
+alerts.conduit-services.com.
+profile.ak.fbcdn.net.
+translate.google.com.
+www.google-analytics.com.
+au.download.windowsupdate.com.
+www.goodlightscraps.com.
+56.251.131.187.in-addr.arpa.
+spring-board.info.
+southampton.ac.uk.
+profile.ak.fbcdn.net.
+251.76.159.110.in-addr.arpa.
+mx.alegro.com.
+a4.sphotos.ak.fbcdn.net.
+163.231.27.190.in-addr.arpa.
+250.10.82.190.in-addr.arpa.
+9.217.31.189.in-addr.arpa.
+a1.sphotos.ak.fbcdn.net.
+211.151.146.91.in-addr.arpa.
+photos-h.ak.fbcdn.net.
+www.crea.org.mx.
+quick-slide-show.malavida.com.
+i2.ytimg.com.
+csi.gstatic.com.
+r._dns-sd._udp.0.0.168.192.in-addr.arpa.
+d15gt9gwxw5wu0.cloudfront.net.
+profile.ak.fbcdn.net.
+docs.google.com.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+www.facebook.com.
+etisbew.com.
+malmalloy.com.
+a.root-servers.net.
+biplan.ru.
+129.129.165.66.in-addr.arpa.
+www.logoblog.org.
+www.google.com.
+api.twitter.com.
+espndeportes.espn.go.com.
+daligallery.com.
+it-it.facebook.com.
+support.google.com.
+74.0.78.89.in-addr.arpa.
+www.condominiobahiainglesa.cl.
+utopiaverde.org.
+rn9bzlfj8.f13o5k1f.
+www.subhavaastu.com.
+golge.net.
+assine.mundodositio.com.br.
+www.facebook.com.
+corneredge.com.
+www.20minutos.es.
+feeds.reuters.com.
+clients1.google.com.
+blog-imgs-1.fc2.com.
+gfx3.hotmail.com.
+www.oagaviation.com.
+www.google.com.
+243.112.75.190.in-addr.arpa.
+uniglobecandes.com.
+external.ak.fbcdn.net.
+www.mysexgames.com.
+w88.go.com.
+local-bay.contacts.msn.com.
+www.ehealthcentral.com.au.
+64.116.51.190.in-addr.arpa.
+api-read.facebook.com.
+photos-b.ak.fbcdn.net.
+hotmail.com.
+it-it.facebook.com.
+kb.bizagi.com.
+es1.zcominc.com.
+a.root-servers.net.
+req.appads.com.
+a.root-servers.net.
+twitter.com.
+timexgroup.com.s6a2.psmtp.com.
+www.gstock.com.
+100.27.81.189.in-addr.arpa.
+um16.eset.com.
+www.google.com.
+6.243.224.186.in-addr.arpa.
+www.lojamusica.com.
+sc21.rules.mailshell.net.
+117.117.149.186.in-addr.arpa.
+www.bing.com.
+4913559952871923121-a-1802744773732722657-s-sites.googlegroups.com.
+a4.sphotos.ak.fbcdn.net.
+cdn.dsultra.com.
+www.gstatic.com.
+games.khleeg.com.
+upload.wikimedia.org.
+lapoliciaca.disqus.com.
+_625_72_5.
+rosepacking.com.
+b._dns-sd._udp.0.1.168.192.in-addr.arpa.
+134.43.148.79.in-addr.arpa.
+hyperlink.net.au.
+ct.buzzfeed.com.
+a1230.b.akamai.net.
+mail.hcgmedical.com.
+dnl-01.geo.kaspersky.com.
+nievestoledo.wikispaces.com.
+t3.gstatic.com.
+www.master.com.
+maktoob.yahoo.com.
+checkip.dyndns.org.
+fracpump.com.
+a.root-servers.net.
+s4.histats.com.
+www.facebook.com.
+b:qevtu6p.86dd.
+hwtaa::mz.p01q2r2q.
+yahoo.com.hk.
+linkhelp.clients.google.com.
+unpacked2012.org.
+155.195.141.201.in-addr.arpa.
+download891.avast.com.
+purpletriangle.co.uk.
+s.yimg.com.
+185.181.32.216.dnsbl.sorbs.net.
+photos-f.ak.fbcdn.net.
+rrjobs.com.s6a1.psmtp.com.
+profile.ak.fbcdn.net.
+loading2.widdit.com.
+cs9227.vk.com.
+89.13.224.90.in-addr.arpa.
+www.facebook.com.
+www.joshgentry.com.
+87.12.234.189.in-addr.arpa.
+api.twitter.com.
+jigsaw.w3.org.
+mscrl.microsoft.com.
+profile.ak.fbcdn.net.
+mx.caixacatalunya.es.
+stats.bloggvarde.se.
+84.143.158.187.in-addr.arpa.
+eskup.elpais.com.
+7hbzxg46w.i35o9w6b.
+img802.imageshack.us.
+apps.facebook.com.
+a2.sphotos.ak.fbcdn.net.
+groups.google.com.mx.
+mail1.eircom.net.
+40.82.26.190.in-addr.arpa.
+02011808.com.
+221.21.219.218.in-addr.arpa.
+kronen.net.
+www.sexchat.pl.
+m.google.com.
+teredo.ipv6.microsoft.com.
+tourneytime.com.
+bbs.py168.com.
+zegna.com.
+resident-evil-5-benchmark.softonic.fr.
+180.255.185.190.in-addr.arpa.
+a.root-servers.net.
+songreader.softonic.com.
+91.103.43.186.in-addr.arpa.
+a.root-servers.net.
+plus.l.google.com.
+www.sectormatematica.cl.
+pogodavsamare.ru.
+ib.adnxs.com.
+myinahar67.blogspot.com.
+lb._dns-sd._udp.0.1.168.192.in-addr.arpa.
+www.mandco.com.
+api-read.facebook.com.
+youtube.com.
+lanuevaeconomia.com.
+www.googleapis.com.
+235.144.14.186.in-addr.arpa.
+202.100.91.75.in-addr.arpa.
+mail.sinolines.com.
+static.ak.fbcdn.net.
+52.12.193.190.in-addr.arpa.
+photos-a.ak.fbcdn.net.
+static.ak.fbcdn.net.
+ip1-02.patriarch.ru.
+wjvtke.com.
+ns3.freescale.com.
+www.asociaciongrama.org.
+www.emi.ae.
+email.com.
+fbcdn-photos-a.akamaihd.net.
+photos-e.ak.fbcdn.net.
+a4.sphotos.ak.fbcdn.net.
+8.235.217.111.in-addr.arpa.
+fredericton.kijiji.ca.
+divamission.com.
+1.gravatar.com.
+isatap.domain_not_set.invalid.
+www.insistecweb.com.
+176.131.11.189.in-addr.arpa.
+www.oyunlar1.com.
+bay.gateway.messenger.live.com.
+95.99.0.186.in-addr.arpa.
+cima.ng-london.org.uk.
+advantagesurveillance-net.mail.eo.outlook.com.
+shared.live.com.
+10.api.urban-rivals.com.
+images.francisfrith.com.
+220.78.146.189.in-addr.arpa.
+www.rackitup.com.au.
+130.13.168.192.in-addr.arpa.
+rogers.com.
+4.111.43.200.in-addr.arpa.
+a2.sphotos.ak.fbcdn.net.
+6.1.168.192.in-addr.arpa.
+apps.facebook.com.
+a.root-servers.net.
+bob.jncb.com.
+a.root-servers.net.
+www.facebook.com.
+external.ak.fbcdn.net.
+www.foxsportsla.com.
+179.46.135.71.in-addr.arpa.
+mail.readingworks.net.
+a4.sphotos.ak.fbcdn.net.
+plusone.google.com.
+pixel.quantserve.com.
+240.52.29.186.in-addr.arpa.
+js2.wlxrs.com.
+res5.windowsmedia.com.
+148.192.10.8.in-addr.arpa.
+ad.metanetwork.com.
+api.twitter.com.
+terratv.terra.com.mx.
+mail.loadedimage.com.
+maps.k12.wi.us.s6a1.psmtp.com.
+static.chartbeat.com.
+trilleros.activoforo.com.
+1.0.0.127.dnsbugtest.1.0.0.127.in-addr.arpa.
+googleads.g.doubleclick.net.
+chat.shopjimmy.com.
+ra4king.is-a-geek.net.
+static.ak.fbcdn.net.
+a.root-servers.net.
+www.rro.ch.
+photos-b.ak.fbcdn.net.
+www.misputillas.com.
+video.es.msn.com.
+lesmash.spb.ru.
+sac.gti.mcafee.com.
+clients2.google.com.
+congdongvip.com.
+swcdn.apple.com.
+pixer.meaningtool.com.
+hjk01.hjklaw.com.
+twitter.com.
+a5.sphotos.ak.fbcdn.net.
+www.stumbleupon.com.
+162.67.246.190.in-addr.arpa.
+booklistonline.com.
+56.107.236.190.in-addr.arpa.
+24.2.129.174.in-addr.arpa.
+dns.msftncsi.com.
+www.isg-apple.com.akadns.net.
+mail.missioncarwash.com.
+justjared.
+canon-photo-club.ru.
+180.4.19.187.in-addr.arpa.
+ad-g.doubleclick.net.
+235.110.201.187.in-addr.arpa.
+www.howtoattractagirl.org.
+www.google.com.mx.
+jeved.com.
+146.52.123.201.in-addr.arpa.
+hotel-femida.ru.
+100.94.75.195.in-addr.arpa.
+474.ns1631262.org.
+games.yahoo.com.
+mob.adwhirl.com.
+estad.emagister.com.
+132.106.35.190.in-addr.arpa.
+_353_17_6.
+rad.msn.com.
+fr-fr.facebook.com.
+rspl:6uc1.q00t4x6x.
+34.95.130.174.in-addr.arpa.
+translate.google.es.
+eserviceinfo.com.
+149.38.54.208.in-addr.arpa.
+marriott.weather.com.
+a.root-servers.net.
+225.198.192.173.in-addr.arpa.
+163.168.235.190.in-addr.arpa.
+pakistanimedia-thewaythingsare.blogspot.com.
+140.219.111.190.in-addr.arpa.
+weather.service.msn.com.
+photos-e.ak.fbcdn.net.
+www.globalfundforwomen.org.
+212.168.60.83.in-addr.arpa.
+adelia.net.
+a7.sphotos.ak.fbcdn.net.
+a.root-servers.net.
+creative.ak.fbcdn.net.
+payment.socialgamenet.com.
+fixounet.free.fr.
+www.apple.com.
+www.facebook.com.
+missjordanlee.blogspot.com.
+topgsite.com.
+72.76.91.190.in-addr.arpa.
+citationstyles.org.
+136.105.77.79.in-addr.arpa.
+ksn6-12.kaspersky-labs.com.
+93.35.139.189.in-addr.arpa.
+news.google.com.mx.
+www.hispanicad.com.
+ntp1.tummy.com.
+www.cmpadministration.com.
+www.wustemcells-arabic.com.
+www.fragilestory.com.
+117.130.193.113.in-addr.arpa.
+img838.imageshack.us.
+translate.googleapis.com.
+www.yahoo.com.
+favbrowser.disqus.com.
+119.174.35.213.in-addr.arpa.
+rdav1.blogspot.com.
+xiangjishi.taobao.com.
+232.205.29.196.in-addr.arpa.
+autos.trovitargentina.com.ar.
+udc.udc0.glbdns.microsoft.com.
+www.bcsf.com.ar.
+56.165.77.190.in-addr.arpa.
+157.207.109.200.in-addr.arpa.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+105.33.192.123.in-addr.arpa.
+www.guia.hipnosis.org.es.
+lostrabajosdemarianelaguerrerosanchez.blogspot.com.
+american.idolblog.com.
+js01.pixelsnippet.com.
+www.ncca.ie.
+accounts.google.com.
+187.34.104.189.in-addr.arpa.
+mx2.mail.eu.yahoo.com.
+a.root-servers.net.
+rtr8.m9.ru.
+gruposinos.com.br.
+www.yahoo.com.
+112.110.249.201.in-addr.arpa.
+login.yahoo.com.
+fdgdfgdfg.com.
+119.10.39.190.in-addr.arpa.
+accidentexchange.com.s200a2.psmtp.com.
+platform.ak.fbcdn.net.
+www.google.com.
+adsfront.iminent.com.
+i4.ytimg.com.
+ntp.glb.nist.gov.
+absolut.fr.
+netmail.hetnet.nl.
+support.google.com.
+a1738.phobos.apple.com.
+29.174.78.186.in-addr.arpa.
+210.237.94.66.in-addr.arpa.
+photos-f.ak.fbcdn.net.
+s-static.ak.facebook.com.
+www.google-analytics.com.
+a.root-servers.net.
+plusone.google.com.
+eos.hs-niederrhein.de.
+www.good.is.
+esjatologico.files.wordpress.com.
+152.182.130.27.in-addr.arpa.
+www.flydreamers.com.
+a2.sphotos.ak.fbcdn.net.
+udc.msn.com.
+simpy.com.
+api.zynga.com.
+data.flurry.com.
+teredo.ipv6.microsoft.com.
+a.root-servers.net.
+girlytattoosforgirls.com.
+yahoo.com.
+c.prodigy.msn.com.
+0-jf-w.channel.facebook.com.
+dns.msftncsi.com.
+irregularly.com.
+adx.adnxs.com.
+a.root-servers.net.
+ntp.glb.nist.gov.
+cnainsurance.com.
+espanol.answers.yahoo.com.
+a3.sphotos.ak.fbcdn.net.
+atlanta.uwservices.com.
+encielodeloceano.blogspot.com.
+.
+db._dns-sd._udp.0.129.37.10.in-addr.arpa.
+s0.2mdn.net.
+a8.sphotos.ak.fbcdn.net.
+122hotmail.com.
+luma.pt.
+developers.facebook.com.
+www.xuvn.com.
+api.facebook.com.
+93.178.145.189.in-addr.arpa.
+manualguides.info.
+www.msftncsi.com.
+mx1.nebutel.com.
+0.226.179.85.in-addr.arpa.
+v3.nonxt2.c.youtube.com.
+time.chttl.com.tw.
+154.88.59.209.in-addr.arpa.
+santacru2mortgage.com.
+hosted.analrecruiters.com.
+static.ak.fbcdn.net.
+_016_38_9.
+140.18.67.201.in-addr.arpa.
+zackandres.hi5.com.
+download843.avast.com.
+s-static.ak.fbcdn.net.
+seal.verisign.com.
+a.root-servers.net.
+87.68.92.186.in-addr.arpa.
+img07.b2b.hc360.com.
+m.addthisedge.com.
+mail.co.campbell.va.us.
+static.ak.fbcdn.net.
+js.admeld.com.
+dsn8.d.skype.net.
+206.196.165.46.in-addr.arpa.
+mscrl.microsoft.com.
+content.thermoinformatics.com.
+www.sentadoenelaire.com.
+www.crackberrista.com.
+photos-b.ak.fbcdn.net.
+238.166.227.2.in-addr.arpa.
+mail.yorktownenergy.com.
+d2089620.xoom.it.
+mail.sevel.com.uy.
+www.intercambiosbarcelona.com.
+sp.cwfservice.net.
+www.wdc.com.
+profile.ak.fbcdn.net.
+evrostroydom.ru.
+levuaf:j8.b14a5m1n.
+187.27.35.189.in-addr.arpa.
+0.7050456.com.
+183.86.11.189.in-addr.arpa.
+www.gstatic.com.
+newsrss.bbc.co.uk.
+54.181.125.99.in-addr.arpa.
+flexplan.com.
+yui.yahooapis.com.
+tcr.tynt.com.
+c1:2rzehs.i88y9e5d.
+mail25.arinc.com.
+v24.nonxt3.googlevideo.com.
+tools.google.com.
+content.yieldmanager.edgesuite.net.
+s-fitness.ru.
+www.specialops.org.
+ndhsb.org.
+global.mitsubishielectric.com.
+s-static.ak.fbcdn.net.
+busites-legacy-elb-9-1502350783.us-east-1.elb.amazonaws.com.
+foto-natura-huesca-2.blogspot.com.
+mail.cpfuinc.com.
+danielatamayo.com.
+ie9cvlist.ie.microsoft.com.
+p06-keyvalueservice.icloud.com.
+khm0.googleapis.com.
+secure.worldspot.net.
+nccpr.p2p.baofeng.net.
+lancastersys.com.
+tag.admeld.com.
+sls2ns215.y57p7f0m.
+www.youtube.com.
+www.gadgetrynews.com.
+b._dns-sd._udp.0.1.168.192.in-addr.arpa.
+hindi.babylon.com.
+static.ak.fbcdn.net.
+d2059613.instant.xoom.it.
+209.247.74.187.in-addr.arpa.
+bentvip.com.
+www.foxsportsla.com.
+www.google-analytics.com.
+www.cpxadspace.com.
+download337.avast.com.
+couponbuddy.s3.amazonaws.com.
+lexx.ru.
+musica.descarga-gratis.org.
+www.buono.aipop.cl.
+s-static.ak.fbcdn.net.
+67.109.220.201.in-addr.arpa.
+pixel.facebook.com.
+topfuelwebdesign.com.
+p698wia5n.a77p0x6r.
+isatap.pxe.acer.com.
+125.194.237.166.in-addr.arpa.
+www.msftncsi.com.
+viamail.ru.
+139.94.91.190.in-addr.arpa.
+a5.mzstatic.com.
+sp-avto.ru.
+apps.facebook.com.
+megusta.fraseshit.com.
+p02-bookmarks.icloud.com.
+.
+tierrasdemiscelanea.wordpress.com.
+81.103.43.186.in-addr.arpa.
+_114_99_7.
+callway.ru.
+www.18to19teenies.com.
+hdp.zapto.org.
+mscrl.microsoft.com.
+google.com.
+219.31.115.189.in-addr.arpa.
+benito-juarez.alumnosonline.com.
+www.kt2syggf436dtag162.com.
+www.myaddressus.com.
+optimodal.com.
+timberfinec.com.
+mx1.riseup.net.
+m2.nsimg.net.
+www.anime-sharing.com.
+plusone.google.com.
+5.251.254.188.in-addr.arpa.
+www.sitedefou.com.
+a.root-servers.net.
+exp01.eset.com.
+dr._dns-sd._udp.0.42.168.192.in-addr.arpa.
+www.ericas.com.
+api.facebook.com.
+secure.shared.live.com.
+fbcdn-sphotos-a.akamaihd.net.
+250.27.242.85.in-addr.arpa.
+digg.com.
+www.socialgrowthtechnologies.com.
+time.stdtime.gov.tw.
+cdn-4.nflximg.com.
+myspace.com.
+42.160.116.122.in-addr.arpa.
+155.78.34.187.in-addr.arpa.
+i.walmartimages.com.edgesuite.net.
+www.google-analytics.com.
+0-250.channel.facebook.com.
+profile.ak.fbcdn.net.
+229.153.252.109.in-addr.arpa.
+alerts.conduit-services.com.
+s0.2mdn.net.
+www.ecologiapolitica.info.
+buck.de.
+smtp.loyalistc.on.ca.
+www.tudiscovery.com.
+68.95.80.72.in-addr.arpa.
+www.optimus.se.
+36.14.12.204.in-addr.arpa.
+189.249.244.201.in-addr.arpa.
+custmx.cscdns.net.
+mx.youtube.com.
+apple.com.
+platform.ak.fbcdn.net.
+ads1.msads.net.
+descargargratis.com.
+oppty4u.com.
+27.165.42.62.in-addr.arpa.
+www.mypagerank.net.
+gaizhaohua.blog.sohu.com.
+www.google.com.
+pixel.facebook.com.
+www.joancollins.net.
+.
+www.cochesdeimportacion.com.
+instaar.metapress.com.
+www.cerberusftp.com.
+lw19w1:a5.o76u5f4s.
+162.128.129.186.in-addr.arpa.
+a6.sphotos.ak.fbcdn.net.
+skahunter.com.
+p2.trrsf.com.
+13.20.193.190.in-addr.arpa.
+newsnetinfo.com.
+merera.ru.
+musahim.maktoob.com.
+estilos.prodigy.msn.com.
+mail.google.com.
+42.82.224.190.in-addr.arpa.
+www.bestday.com.ar.
+mx.sherl.ru.
+feeds.bbci.co.uk.
+tital.com.
+www.thenewstribune.com.
+www.facebook.com.
+static-resource.np.community.playstation.net.
+r._dns-sd._udp.0.1.168.192.in-addr.arpa.
+75.78.132.190.in-addr.arpa.
+186.201.177.187.in-addr.arpa.
+allana.ru.
+expresscarpet.net.
+35.155.202.190.in-addr.arpa.
+col.stc.s-msn.com.
+s.ytimg.com.
+loadbalancing.modaco.com.
+photographypros.com.
+tagps.ru.
+rad.msn.com.
+megapolis-st.ru.
+www.wrightangle.com.
+plusone.google.com.
+istockanalyst.com.
+www.rubyrobot.org.
+20.1.168.192.in-addr.arpa.
+invite.youmint.net.
+aol.com.
+103.28.241.119.in-addr.arpa.
+3o4aldia.blogspot.com.
+heartbeat.belkin.com.
+dss1.siteadvisor.com.
+mail.sutd.ru.
+176.171.215.81.in-addr.arpa.
+248.36.251.146.in-addr.arpa.
+profile.ak.fbcdn.net.
+forums.zynga.com.
+112.216.84.186.in-addr.arpa.
+mail2.phyton.ru.
+www.hyruledynasty.com.
+mypage.rediff.com.
+ksn1-11-part1.kaspersky-labs.com.
+es-la.facebook.com.
+js.admeld.com.
+70.54.243.189.in-addr.arpa.
+www.facebook.com.
+www.aarinfantasy.com.
+www.1st-class-software.com.
+www.blovers4.tumblr.com.
+pixel.facebook.com.
+2.61.120.189.in-addr.arpa.
+rv.ginyas.com.
+fxfeeds.mozilla.com.
+e-2dj6aemiwidpmgp.stats.esomniture.com.
+a771.da1.akamai.net.
+ye3bcopsm.18ms.
+www.google.com.
+precisionprint.com.
+ssl.gstatic.com.
+www.lan.com.
+mcasteei.com.
+fasims.fasi.com.
+19.207.78.188.in-addr.arpa.
+geckofx.org.
+static.ak.fbcdn.net.
+fbcdn-profile-a.akamaihd.net.
+www.agoda.es.
+appsmetadata.toolbar.conduit-services.com.
+api.skype.com.
+www.chollywood.tv.
+station.netmarble.com.
+facebook.betterflashgames.com.
+teredo.ipv6.microsoft.com.
+googleblog.blogspot.com.
+clients1.google.com.
+231.51.21.187.in-addr.arpa.
+searchclient.live.net.
+img-cdn.mediaplex.com.
+static.ak.facebook.com.
+159.7.173.186.in-addr.arpa.
+api.twitter.com.
+zmsegamat.blogspot.com.
+mobilemaps.clients.google.com.
+modernismvintage.blogspot.com.
+204.45.13.200.in-addr.arpa.
+bpifunds.com.
+cbbc.org.
+static.pcomperf.com.
+i48.tinypic.com.
+a.root-servers.net.
+api.twitter.com.
+app102194446556627.socialappspot.com.
+photos1.pop6.com.
+115.139.68.189.in-addr.arpa.
+ns1.denisovv.ru.
+www.zonafutbolera.com.
+mx2.safe4mail.cz.
+mail.p106.ru.
+a.root-servers.net.
+s1-word-edit.vo.msecnd.net.
+entretenimiento.univision.com.
+ads.trafficjunky.net.
+34.39.94.189.in-addr.arpa.
+www.capplustech.com.
+www.prtool.info.
+www.easymix.co.nz.
+alerts.conduit-services.com.
+yahoo.com.
+m5fib7l68.88ma.
+podiumdist.com.
+30.media.tumblr.com.
+www.bywifi.com.
+beach.orangecounty.com.
+photos-f.ak.fbcdn.net.
+5.134.93.75.in-addr.arpa.
+fashion.sabayagazine.com.
+cs13076.vk.com.
+evbeacon.starfieldtech.com.
+a7.sphotos.ak.fbcdn.net.
+autobirga.ru.
+smetrics.mindjet.com.
+www.strato.it.
+www.coloradomusicbuzz.com.
+www.facebook.com.
+110.129.144.189.in-addr.arpa.
+lul.es.multi.surbl.org.
+platform.ak.fbcdn.net.
+uses.strawberrynet.com.
+trlf.com.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+feeds.qzone.qq.com.
+149.222.175.79.in-addr.arpa.
+fr-fr.facebook.com.
+watson.microsoft.com.
+www.buenaspracticas.com.
+a.root-servers.net.
+tools.google.com.
+studiotaro.ru.
+www.hotmail.com.
+tunnel.cfw.trustedsource.org.
+social.bidsystem.com.
+teredo.ipv6.microsoft.com.
+db._dns-sd._udp.0.1.168.192.in-addr.arpa.
+api.facebook.com.
+smogy.galya.ru.
+safebrowsing.clients.google.com.
+gorr.state.ny.us.
+ns3.apollo.lv.
+a.root-servers.net.
+hotmail.com.
+adv.yidaba.com.
+www.love-personals.co.uk.
+twitter.com.
+scqekuakauie.com.
+www.facebook.com.
+facebook-video-call-plug-in-installer.softonic.com.
+153.178.92.91.in-addr.arpa.
+db._dns-sd._udp.0.2.168.192.in-addr.arpa.
+81.236.15.209.in-addr.arpa.
+candpmachine.com.2.0001.arsmtp.com.
+www.google.com.
+www.discipulosdecristoemanuel.org.
+pixel.facebook.com.
+65.237.34.177.in-addr.arpa.
+mail.rngroup.ru.
+mail.dyerferris.com.
+www.votocatolico.com.
+75.128.122.123.in-addr.arpa.
+a.root-servers.net.
+unilever-foodsolutions.ru.
+fadevicelilaof.nu.
+196.192.9.65.in-addr.arpa.
+ocsp.verisign.com.
+www.revoltinstyle.com.
+a-0.19-230960c1.a030083.1518.19b2.410a.400.9d.atuj1gaj4zc4gimumscaulqzpv.avqs.mcafee.com.
+212.146.11.187.in-addr.arpa.
+response.jp.
+107.254.56.190.in-addr.arpa.
+external.ak.fbcdn.net.
+koran-jakarta.com.
+imagesperiodicook.s3.amazonaws.com.
+apps.facebook.com.
+dr._dns-sd._udp.0.1.168.192.in-addr.arpa.
+twitter.com.
+_ldap._tcp.
+nnsqi223b.81zq.
+zhetus.esir.ru.
+profile.ak.fbcdn.net.
+www.vardai.org.
+wpad.home.
+loading.retry.widdit.com.
+48.102.191.79.in-addr.arpa.
+static.ak.fbcdn.net.
+clock.nyc.he.net.
+157.252.168.216.in-addr.arpa.
+oborudunion.ru.
+laminaters.ru.
+a.root-servers.net.
+2.150.35.177.in-addr.arpa.
+photos-a.ak.fbcdn.net.
+a-0.19-23074089.30133.1518.19cf.3ea1.410.0.s8t4djrgtphuf24aed6r4tgiv6.avqs.mcafee.com.
+media.liquidx.net.
+v6:rixtv6.58je.
+profile.ak.fbcdn.net.
+59.158.241.201.in-addr.arpa.
+db._dns-sd._udp.lan.
+191.30.147.79.in-addr.arpa.
+164.155.49.178.in-addr.arpa.
+a.root-servers.net.
+js.wlxrs.com.
+external.ak.fbcdn.net.
+nsx.sec.np.dl.playstation.net.
+time.chttl.com.tw.
+209.163.160.190.in-addr.arpa.
+resi.com.au.
+www.fcyt.umss.edu.bo.
+r._dns-sd._udp.0.2.168.192.in-addr.arpa.
+i4.ytimg.com.
+saintpetersbasilica.org.
+cowboyuk.com.
+redir.metaservices.microsoft.com.
+sd-ansp02-m-dc1.pic.com.kw.
+imaverystylishgirl.blogspot.com.
+upay-cdn0.playspan.com.
+www.elprisma.com.
+maycot.com.au.
+ping3.dyngate.com.
+casas.aki.com.mx.
+_089_17_5.
+rihanna.wikia.com.
+statse.webtrendslive.com.
+paramountcoffee.com.s10a1.psmtp.com.
+sat.utm.ru.
+www.fourthwish.com.
+forums.surclaro.com.
+accumalax.com.
+platform.twitter.com.
+a.analytics.yahoo.com.
+125.250.1.181.in-addr.arpa.
+dns.msftncsi.com.
+fengshuiclassic.blogspot.com.
+yomismamayte.blogspot.com.
+plus.google.com.
+a.root-servers.net.
+aphrodite5239.livejournal.com.
+www.libertystickers.com.
+a40.phobos.apple.com.
+www.google.com.
+teredo.ipv6.microsoft.com.
+a.root-servers.net.
+186.83.249.201.in-addr.arpa.
+www.adobe.com.
+www.insurekidsnow.gov.
+mail.paramountmanufacturing.com.
+mail.nordicbioscience.com.
+179.2.137.190.in-addr.arpa.
+estrenoesp.blogspot.com.
+a.root-servers.net.
+fastracksoftware.co.uk.
+www.gstatic.com.
+215.1.168.192.in-addr.arpa.
+225.49.190.190.in-addr.arpa.
+161.61.32.83.in-addr.arpa.
+www.facebook.com.
+safebrowsing.clients.google.com.
+215.77.82.189.in-addr.arpa.
+hetnet.nl.
+176.15.251.146.in-addr.arpa.
+zona-anime.org.
+1.118.122.201.in-addr.arpa.
+www.futbolsantander.com.
+240.50.193.190.in-addr.arpa.
+oxfordinc.com.
+88.19.237.92.in-addr.arpa.
+laofficesupply.com.inbound15.mxlogicmx.net.
+local.msn.com.
+i4.ytimg.com.
+www.googleadservices.com.
+jaytees.com.
+cc.peralta.edu.
+saucontech.com.
+215.189.108.101.in-addr.arpa.
+s2.youtube.com.
+cdn.farmsrv.com.
+154.73.139.175.in-addr.arpa.
+mq3sgyg76.70hw.
+ja-jp.facebook.com.
+www.bluecoat.com.
+a7.sphotos.ak.fbcdn.net.
+37.250.24.75.in-addr.arpa.
+61.68.33.190.in-addr.arpa.
+echo.edge.messenger.live.com.
+www.vendorportal.ecms.va.gov.
+www.facebook.com.
+www.candiceaccolaweb.com.
+eagleaircraft.com.
+www.culosadictos.com.
+a.root-servers.net.
+inbound.gasworks.com.netsolmail.net.
+dns.msftncsi.com.
+rtmlwise.com.
+92.174.174.189.in-addr.arpa.
+246.165.72.190.in-addr.arpa.
+netdizain.ru.
+www.juegospm.com.
+static.ak.fbcdn.net.
+www.menoboys.fr.
+werewolf.solarcinc.com.
+baymsg1030111.gateway.messenger.live.com.
+193.31.108.76.in-addr.arpa.
+a.root-servers.net.
+safebrowsing-cache.google.com.
+static.ak.fbcdn.net.
+www.clr.net.
+a5.sphotos.ak.fbcdn.net.
+insurancefirstinc.com.s9a1.psmtp.com.
+tags.bluekai.com.
+www.promocionesweb.com.
+platform.ak.fbcdn.net.
+123.60.26.190.in-addr.arpa.
+a.root-servers.net.
+r._dns-sd._udp.0.0.168.192.in-addr.arpa.
+smtp.gallerycafe.ru.
+photos-b.ak.fbcdn.net.
+video.dainutekstai.lt.
+www.kayture.com.
+www.freevintagegames.com.
+135.229.97.174.in-addr.arpa.
+www.salazitarrosa.com.uy.
+www.facebook.com.
+data.flurry.com.
+s.youtube.com.
+photos-e.ak.fbcdn.net.
+i1.ytimg.com.
+mail.sktemp.ru.
+www9.effectivemeasure.net.
+194.243.4.181.in-addr.arpa.
+my.ebay.com.
+ez5zaky97.85hj.
+n2.panthercdn.com.
+api.facebook.com.
+35.3.61.186.in-addr.arpa.
+docs.google.com.
+a995.mm1.akamai.net.
+apis.google.com.
+us.perf.glbdns.microsoft.com.
+i1.ytimg.com.
+_800_02_2.
+us.headlines.vivanews.com.
+1.pool.ntp.org.
+184.93.89.186.in-addr.arpa.
+www.mcpvirtualbusinesscard.com.
+videoiline.ru.
+fbcdn-profile-a.akamaihd.net.
+bestworkathomechoices.com.
+cr7nimy7c.78bi.
+www.facebook.com.
+a.root-servers.net.
+7.165.69.161.in-addr.arpa.
+b._dns-sd._udp.0.1.168.192.in-addr.arpa.
+spam2.smarsh.com.
+ftp.relline.ru.
+io9.com.
+b.static-cdn.playfish.com.
+apps.facebook.com.
+1cfl.rr.com.
+yahoo.com.
+static.iminent.com.
+162.144.79.200.in-addr.arpa.
+i4.ytimg.com.
+lonestar.co.nz.
+reg.usps.com.
+www.cytotecblog.com.mx.
+rube.at.
+www.youtube.com.
+img5.pengfu.com.
+pantyhoseladies.net.
+rewards.ebay.com.
+zh-cn.facebook.com.
+oplin.org.
+tap-cdn.rubiconproject.com.
+s0.2mdn.net.
+t.co.
+static.ak.fbcdn.net.
+a8.sphotos.ak.fbcdn.net.
+80.54.5.187.in-addr.arpa.
+pokerface.com.
+photos-c.ak.fbcdn.net.
+mx1.hausnet.ru.
+www.5t.by.
+32.76.231.76.in-addr.arpa.
+141.67.133.115.in-addr.arpa.
+175.202.5.187.in-addr.arpa.
+www.soontobemums.com.
+www.erictradings.com.
+pl.wikipedia.org.
+samuelalonso.blogspot.com.
+www.uniteasy.com.
+www.pokerroom.com.
+static.ak.fbcdn.net.
+photos-g.ak.fbcdn.net.
+xcfoundations.com.lan.
+69.10.175.190.in-addr.arpa.
+macromedia-fireworks.en.softonic.com.
+13.219.153.201.in-addr.arpa.
+adpgr1-bond0-24.jagex.com.
+a1811.g.akamai.net.
+www.akbotong.com.
+mail.broadstarwindsystems.com.
+pagead2.googlesyndication.com.
+smtp.dcminc.com.
+www.google-analytics.com.
+news.cis.dfn.de.
+yanndex.ru.
+masterconn11.qq.com.
+www.isg-apple.com.akadns.net.
+distilleryimage10.instagram.com.
+www.facebook.com.
+cendes.com.
+avto.omsk.ru.
+itunes.apple.com.
+www.youtube.com.
+www.mums.org.
+www.googleadservices.com.
+photos-f.ak.fbcdn.net.
+mail.grinn-corp.ru.
+mailhost00.cfi.co.ug.
+developers.facebook.com.
+www.google.com.
+34344mailermailer.com.
+a3.sphotos.ak.fbcdn.net.
+154.74.53.83.in-addr.arpa.
+ns2.dnsstreet.ru.
+redirector.audiogalaxy.com.
+www.facebook.com.
+steri-flow.com.
+159.39.213.49.in-addr.arpa.
+akcontent.ebuddy.com.
+web.hurriyetdailynews.com.
+_293_74_0.
+btfans.3322.org.
+abto4.ru.
+241.180.72.200.in-addr.arpa.
+angelaseeangelablog.files.wordpress.com.
+www.technorati.com.
+proscada.ru.
+www.julienlecomte.net.
+youtube.com.
+minerkennedy.com.s9b1.psmtp.com.
+lb._dns-sd._udp.lan.
+130.20.132.190.in-addr.arpa.
+sp.cwfservice.net.
+qrgen.mobile.yahoo.co.jp.
+iprep3.elitec.ctmail.com.
+a.root-servers.net.
+225.144.168.88.zz.countries.nerd.dk.
+101.65.21.201.in-addr.arpa.
+support.google.com.
+99.17.238.189.in-addr.arpa.
+www.facebook.com.
+i.xanga.com.
+pt-br.facebook.com.
+messer-mg.com.
+static.ak.fbcdn.net.
+billing.sharo4ka.ru.
+17.132.217.190.in-addr.arpa.
+.
+aspirin-m.ru.
+cabovillasresort.com.
+www.datingbridgelp.info.
+helios.gamerdna.com.
+5cbbb1399.06zy.
+thumbs1.billclips.com.
+i4c.eu.
+190.195.42.190.in-addr.arpa.
+photos-e.ak.fbcdn.net.
+bmigaming.com.
+www.davidbelbin.com.
+ubumedia.wordpress.com.
+tragicodrama.blogspot.com.
+a.root-servers.net.
+explain-and-send-screenshots.softonic.com.
+teredo.ipv6.microsoft.com.
+www.argentinawarez.com.
+photos-h.ak.fbcdn.net.
+252.243.2.201.in-addr.arpa.
+dalfetco.khv.ru.
+www.comptoir.fr.
+statweb.dreamx.com.
+ssl.gstatic.com.
+sarobcoq8.62mt.
+descargas.juegos.com.
+developers.facebook.com.
+www.bayersanidadanimal.com.mx.
+www.minijuegos.com.
+www.google.com.
+mscrl.microsoft.com.
+a5.sphotos.ak.fbcdn.net.
+195.174.94.201.in-addr.arpa.
+norwegian.ruvr.ru.
+65.71.241.201.in-addr.arpa.
+plus.google.com.
+dns.msftncsi.com.
+202.204.157.186.in-addr.arpa.
+www.avideode.com.
+a1505.l.akamai.net.
+nlp.fi.muni.cz.
+26.75.220.85.in-addr.arpa.
+view.atdmt.com.
+17.22.159.189.in-addr.arpa.
+ads.bluelithium.com.
+ads.lfstmedia.com.
+mail.acadental.com.
+www.christianrock.net.
+7.135.166.189.in-addr.arpa.
+aol.com.
+docs.google.com.
+254.188.110.189.in-addr.arpa.
+239.14.222.189.in-addr.arpa.
+rcp.na.blackberry.com.
+7y2xr1wlp.83do.
+photos-g.ak.fbcdn.net.
+86.203.14.186.in-addr.arpa.
+a2.sphotos.ak.fbcdn.net.
+mco.com.
+20.202.75.190.in-addr.arpa.
+meteo.ieec.uned.es.
+aligrant.spb.ru.
+164.89.87.85.in-addr.arpa.
+arkansasonline.112.2o7.net.
+www.bestweb.net.
+galeriasgay.biengay.com.
+176.30.152.190.in-addr.arpa.
+feeds.delicious.com.
+www.bottledwaterweb.com.
+attanticbb.net.
+sn1msg3020410.gateway.messenger.live.com.
+101.1.168.192.in-addr.arpa.
+hotmail.com.
+s-static.ak.facebook.com.
+stratexllc.com.
+a.root-servers.net.
+cnfg.montiera.com.
+resources.infolinks.com.
+photos-g.ak.fbcdn.net.
+a3.sphotos.ak.fbcdn.net.
+mra.mail.ru.
+44.228.171.69.in-addr.arpa.
+pool.ntp.org.
+go-gelendgik.ru.
+quetzal.ru.
+s-external.ak.fbcdn.net.
+api.conduit.com.
+s.youtube.com.
+dentals.ru.
+media.fastclick.net.
+pagead2.googlesyndication.com.
+pixel.facebook.com.
+inbound.infoestrategica.com.netsolmail.net.
+time.windows.com.
+rats-images.rise.za.net.
+photos-g.ak.fbcdn.net.
+a.root-servers.net.
+ajax.googleapis.com.
+fbcdn-sphotos-a.akamaihd.net.
+www.inamay.com.
+tunnel.cfw.trustedsource.org.
+www.google.com.
+www.iecologia.com.
+ssl.gstatic.com.
+iamalreadyinuse.livejournal.com.
+www.insurancebreakdown.com.
+mx.udo.mx.
+www.shareaholic.com.
+media.officialplaystationmagazine.co.uk.
+au.download.windowsupdate.com.
+londeninc.com.
+at.atwola.com.
+pixel.facebook.com.
+b._dns-sd._udp.0.1.168.192.in-addr.arpa.
+meta.wikimedia.org.
+www.cah.utexas.edu.
+de-de.facebook.com.
+wo.appwill.com.
+moscow.com.ru.
+www.stylezone.bg.
+customers.imt.ru.
+vanmark.com.
+164.40.6.210.in-addr.arpa.
+r.mzstatic.com.
+www.blogger.com.
+www.mylovedmoms.com.
+mail.
+6to4.ipv6.microsoft.com.
+64.227.225.189.in-addr.arpa.
+a.root-servers.net.
+photos-c.ak.fbcdn.net.
+29.media.tumblr.com.
+securepics.ebaystatic.com.
+157.254.223.95.in-addr.arpa.
+a.root-servers.net.
+a5.sphotos.ak.fbcdn.net.
+c-0.19-210fd000.8020081.1518.19d4.3ea1.410.0.6lkbugnfdecm8p4jn9zbvz8p6j.avqs.mcafee.com.
+www.eyebuydirect.com.
+www.ad-serve.co.uk.
+reboot-it.com.
+149.53.191.190.in-addr.arpa.
+www.cumfiesta.com.
+juegosvestirmoda.blogspot.com.
+oi708.photobucket.com.
+www.epgonline.org.
+a425.w11.akamai.net.
+a8.sphotos.ak.fbcdn.net.
+a.root-servers.net.
+a8.sphotos.ak.fbcdn.net.
+sm.mcafee.com.
+mx1.csusb.edu.
+a.root-servers.net.
+188.254.53.85.in-addr.arpa.
+spam.allardjohnson.com.
+c-0.19-a30f8081.60081.1518.19cf.3ea1.410.0.8t3jdvna6tmcvzmdssun2j9q2q.avqs.mcafee.com.
+health-worx.net.
+js.dailypainters.com.
+w-h.co.uk.
+172.70.101.78.in-addr.arpa.
+creative.ak.fbcdn.net.
+www.mysteryteam-movie.com.
+a.root-servers.net.
+blog.zippyshare.com.
+metcombank.msk.ru.
+cshell.com.
+mail.imagine-publishing.co.uk.
+kcpoets.com.
+www.ses-worldskies.com.
+umziqe.com.
+s.clicktale.net.
+a.root-servers.net.
+www.hotel-wellington.com.
+assets.tumblr.com.
+photos-h.ak.fbcdn.net.
+gelosea.deviantart.com.
+es-la.facebook.com.
+cotgs.com.
+mail.elasteks.com.
+s46.chatango.com.
+services.addons.mozilla.org.
+static.ak.facebook.com.
+dns.msftncsi.com.
+mail.ncstu.ru.
+www.delunaresynaranjas.com.
+193.144.87.85.in-addr.arpa.
+simpleforex.ru.
+elizabethsmarts.blogspot.com.
+0-jl-w.channel.facebook.com.
+www.facebook.com.
+img.youtube.com.
+www.colegioscolombia.com.
+dns.msftncsi.com.
+s0.img.awempire.com.
+74.76.140.201.in-addr.arpa.
+49.149.220.66.in-addr.arpa.
+a5.sphotos.ak.fbcdn.net.
+16.241.19.190.in-addr.arpa.
+apps.facebook.com.
+sp.cwfservice.net.
+s-static.ak.fbcdn.net.
+b._dns-sd._udp.lan.
+www.google.com.
+www.fandemia.com.
+android.clients.google.com.
+www.xxxspacegirls.us.
+ipyxxtb.cc.
+p02-caldav.icloud.com.
+i2.ytimg.com.
+95.156.32.173.in-addr.arpa.
+130.235.55.74.in-addr.arpa.
+a2.sphotos.ak.fbcdn.net.
+www.lelabofragrances.com.
+234.190.150.79.in-addr.arpa.
+appworld.blackberry.com.
+126.250.168.192.in-addr.arpa.
+68.196.22.177.in-addr.arpa.
+s.meebocdn.net.
+mail.valuehost.ru.
+www.clocklink.com.
+_791_96_0.
+lb._dns-sd._udp.0.55.211.10.in-addr.arpa.
+www.everardoherrera.com.
+pre.nextworth.com.
+txdps.state.tx.us.
+a5.sphotos.ak.fbcdn.net.
+jeanneillenye.blogspot.com.
+62s1jicq1.49vj.
+a6.sphotos.ak.fbcdn.net.
+foodconsumer.org.
+www.myownpublishing.com.
+dansleplacarddemaxime.blogspot.com.
+48.28.138.208.in-addr.arpa.
+149.145.71.70.in-addr.arpa.
+uniway.ru.
+armchairgeneral1.blogspot.com.
+www.secretease.com.
+mx1.rosbank.ru.
+profile.ak.fbcdn.net.
+redirector.c.youtube.com.
+ec.atdmt.com.
+93.172.243.201.in-addr.arpa.
+crl.microsoft.com.
+dtboot.orbitdownloader.com.
+download.surfcanyon.com.
+3ymei12ii.60xw.
+ice.friv4.info.
+rs499l33.rapidshare.com.
+www.adobe.com.
+213.180.183.189.in-addr.arpa.
+aprendercantandopersa.blogspot.com.
+support.google.com.
+241.100.136.190.in-addr.arpa.
+a3.sphotos.ak.fbcdn.net.
+a.root-servers.net.
+ngc.tgc6.ru.
+www.tumblr.com.
+a.root-servers.net.
+by146w.bay146.mail.live.com.
+mtalk.google.com.
+preujct.cl.
+oebe.com.
+dns-chj.sh.cncnet.net.
+libya.visahq.com.
+instagram.com.
+119.48.173.90.in-addr.arpa.
+www.creditrepairmagic.com.
diff --git a/bench/meson.build b/bench/meson.build
new file mode 100644
index 0000000..b15dd0f
--- /dev/null
+++ b/bench/meson.build
@@ -0,0 +1,24 @@
+# bench
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+bench_lru_src = files([
+ 'bench_lru.c',
+])
+
+cc = meson.get_compiler('c')
+m_dep = cc.find_library('m', required : false)
+
+bench_lru = executable(
+ 'bench_lru',
+ bench_lru_src,
+ dependencies: [
+ contrib_dep,
+ libkres_dep,
+ m_dep,
+ ],
+)
+
+run_target(
+ 'bench',
+ command: '../scripts/bench.sh',
+)
diff --git a/ci/deckard_commit_check.sh b/ci/deckard_commit_check.sh
new file mode 100755
index 0000000..5b4016d
--- /dev/null
+++ b/ci/deckard_commit_check.sh
@@ -0,0 +1,13 @@
+DECKARD_COMMIT=$(git ls-tree HEAD:tests/integration/ | grep commit | grep deckard | cut -f1 | cut -f3 '-d ')
+DECKARD_PATH="tests/integration/deckard"
+pushd $DECKARD_PATH > /dev/null
+if git merge-base --is-ancestor $DECKARD_COMMIT origin/master; then
+ echo "Deckard submodule commit is on in its master branch. All good in the hood."
+ exit 0
+else
+ echo "Deckard submodule commit $DECKARD_COMMIT is not in Deckard's master branch."
+ echo "This WILL cause CI breakages so make sure your changes in Deckard are merged"
+ echo "or point the submodule to another commit."
+ exit 1
+fi
+
diff --git a/ci/fix-meson-junit.sh b/ci/fix-meson-junit.sh
new file mode 100755
index 0000000..02cf488
--- /dev/null
+++ b/ci/fix-meson-junit.sh
@@ -0,0 +1,5 @@
+#!/bin/sh
+sed 's|</testcase>|</testcase>\n|g' -i "$@"
+sed -e '/<failure \/>/,/<\/testcase>/s/<\(\/\?\)system-\(out\|err\)>/<\1failure>/g' \
+ -e 's/<failure \/>//g' \
+ -i "$@"
diff --git a/ci/gh_actions.py b/ci/gh_actions.py
new file mode 100755
index 0000000..8fe05b6
--- /dev/null
+++ b/ci/gh_actions.py
@@ -0,0 +1,58 @@
+#!/usr/bin/python3
+# SPDX-License-Identifier: GPL-3.0-or-later
+import json
+import time
+import sys
+
+import requests
+
+
+BRANCH_API_ENDPOINT = "https://api.github.com/repos/CZ-NIC/knot-resolver/actions/runs?branch={branch}" # noqa
+TIMEOUT = 20*60 # 20 mins max
+POLL_DELAY = 60
+SYNC_TIMEOUT = 10*60
+
+
+def exit(msg='', html_url='', code=1):
+ print(msg, file=sys.stderr)
+ print(html_url)
+ sys.exit(code)
+
+
+end_time = time.time() + TIMEOUT
+sync_timeout = time.time() + SYNC_TIMEOUT
+while time.time() < end_time:
+ response = requests.get(
+ BRANCH_API_ENDPOINT.format(branch=sys.argv[1]),
+ headers={"Accept": "application/vnd.github.v3+json"})
+ if response.status_code == 404:
+ pass # not created yet?
+ elif response.status_code == 200:
+ data = json.loads(response.content.decode('utf-8'))
+ try:
+ run = data['workflow_runs'][0]
+ conclusion = run['conclusion']
+ html_url = run['html_url']
+ commit_sha = run['head_sha']
+ except (KeyError, IndexError):
+ time.sleep(POLL_DELAY)
+ continue
+
+ if commit_sha != sys.argv[2]:
+ if time.time() < sync_timeout:
+ time.sleep(POLL_DELAY)
+ continue
+ exit("Fetched invalid GH Action: commit mismatch. Re-run or push again?")
+
+ if conclusion is None:
+ pass
+ if conclusion == "success":
+ exit("SUCCESS!", html_url, code=0)
+ elif isinstance(conclusion, str):
+ # failure, neutral, cancelled, skipped, timed_out, or action_required
+ exit("GitHub Actions Conclusion: {}!".format(conclusion.upper()), html_url)
+ else:
+ exit("API Response Code: {}".format(response.status_code), code=2)
+ time.sleep(POLL_DELAY)
+
+exit("Timed out!")
diff --git a/ci/images/README.md b/ci/images/README.md
new file mode 100644
index 0000000..d9efe0e
--- /dev/null
+++ b/ci/images/README.md
@@ -0,0 +1,41 @@
+# Container images for CI
+
+## Image purpose
+
+### debian-11
+
+The main image used by shared runners to execute most CI builds and tests.
+
+### debian-11-coverity
+
+A stripped down version of `debian-11`. It only contains build (not test)
+dependencies of `kresd`. It also contains the `cov-build` tool for generating
+inputs for [Coverity Scan](https://scan.coverity.com/).
+
+It is used by the `coverity` CI job to generate and send data to Coverity Scan
+for analysis.
+
+To build this image, you need to retrieve the Coverity Scan token from the
+dashboard and pass it to the `build.sh` script using the `COVERITY_SCAN_TOKEN`
+environment variable, e.g.:
+
+```
+$ COVERITY_SCAN_TOKEN=the_secret_token ./build.sh debian-11-coverity
+```
+
+### debian-buster (10)
+
+Used to serve the same purpose as `debian-11`. As of 2022-03-09, it is still
+used by some jobs (linters).
+
+## Maintenance
+
+The `ci/images/` directory contains utility scripts to build, push or update
+the container images.
+
+```
+$ ./build.sh debian-11 # builds a debian-11 image locally
+$ ./push.sh debian-11 # pushes the local image into target registry
+$ ./update.sh debian-11 # utility wrapper that both builds and pushes the image
+$ ./update.sh */ # use shell expansion of dirnames to update all images
+```
diff --git a/ci/images/build.sh b/ci/images/build.sh
new file mode 100755
index 0000000..39ee617
--- /dev/null
+++ b/ci/images/build.sh
@@ -0,0 +1,13 @@
+#!/bin/bash
+# build specified docker image
+
+CURRENT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)"
+source "${CURRENT_DIR}"/vars.sh "$@"
+set -ex
+
+if [ -n "$COVERITY_SCAN_TOKEN" ]; then
+ SECRETS="$SECRETS --secret id=coverity-token,env=COVERITY_SCAN_TOKEN"
+fi
+
+export DOCKER_BUILDKIT=1 # Enables using secrets in docker-build
+docker build --pull --no-cache -t "${FULL_NAME}" "${IMAGE}" --build-arg KNOT_BRANCH=${KNOT_BRANCH} $SECRETS
diff --git a/ci/images/debian-11-coverity/Dockerfile b/ci/images/debian-11-coverity/Dockerfile
new file mode 100644
index 0000000..1915614
--- /dev/null
+++ b/ci/images/debian-11-coverity/Dockerfile
@@ -0,0 +1,43 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+FROM debian:bullseye
+MAINTAINER Knot Resolver <knot-resolver@labs.nic.cz>
+# >= 3.0 needed because of --enable-xdp=yes
+ARG KNOT_BRANCH=3.1
+ARG COVERITY_SCAN_PROJECT_NAME=CZ-NIC/knot-resolver
+ENV DEBIAN_FRONTEND=noninteractive
+
+WORKDIR /root
+CMD ["/bin/bash"]
+
+# generic cleanup
+RUN apt-get update -qq
+
+# Knot and Knot Resolver dependencies
+RUN apt-get install -y -qqq git make cmake pkg-config meson \
+ build-essential bsdmainutils libtool autoconf libcmocka-dev \
+ liburcu-dev libgnutls28-dev libedit-dev liblmdb-dev libcap-ng-dev libsystemd-dev \
+ libelf-dev libmnl-dev libidn11-dev libuv1-dev \
+ libluajit-5.1-dev lua-http libssl-dev libnghttp2-dev
+
+# LuaJIT binary for stand-alone scripting
+RUN apt-get install -y -qqq luajit
+
+# build and install latest version of Knot DNS
+RUN git clone --depth=1 --branch=$KNOT_BRANCH https://gitlab.nic.cz/knot/knot-dns.git /tmp/knot
+WORKDIR /tmp/knot
+RUN pwd
+RUN autoreconf -if
+RUN ./configure --prefix=/usr --enable-xdp=yes
+RUN CFLAGS="-g" make
+RUN make install
+RUN ldconfig
+
+# curl and tar (for downloading Coverity tools and uploading logs)
+RUN apt-get install -y curl tar
+
+RUN --mount=type=secret,id=coverity-token \
+ curl -o /tmp/cov-analysis-linux64.tar.gz https://scan.coverity.com/download/cxx/linux64 \
+ --form project=$COVERITY_SCAN_PROJECT_NAME --form token=$(cat /run/secrets/coverity-token)
+RUN tar xfz /tmp/cov-analysis-linux64.tar.gz
+RUN mv cov-analysis-linux64-* /opt/cov-analysis
diff --git a/ci/images/debian-11/Dockerfile b/ci/images/debian-11/Dockerfile
new file mode 100644
index 0000000..59f170b
--- /dev/null
+++ b/ci/images/debian-11/Dockerfile
@@ -0,0 +1,144 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+FROM debian:bullseye
+MAINTAINER Knot Resolver <knot-resolver@labs.nic.cz>
+# >= 3.0 needed because of --enable-xdp=yes
+ARG KNOT_BRANCH=3.1
+ENV DEBIAN_FRONTEND=noninteractive
+
+WORKDIR /root
+CMD ["/bin/bash"]
+
+# generic cleanup
+RUN apt-get update -qq
+
+# Knot and Knot Resolver dependencies
+RUN apt-get install -y -qqq git make cmake pkg-config meson \
+ build-essential bsdmainutils libtool autoconf libcmocka-dev \
+ liburcu-dev libgnutls28-dev libedit-dev liblmdb-dev libcap-ng-dev libsystemd-dev \
+ libelf-dev libmnl-dev libidn11-dev libuv1-dev libjemalloc-dev \
+ libluajit-5.1-dev lua-http libssl-dev libnghttp2-dev
+
+# Build and testing deps for Resolver's dnstap module (go stuff is just for testing)
+RUN apt-get install -y -qqq \
+ protobuf-c-compiler libprotobuf-c-dev libfstrm-dev
+# Maintaining the go stuff in CI really seems more trouble than worth.
+# golang-any
+#RUN bash -c "go get github.com/{FiloSottile/gvt,cloudflare/dns,dnstap/golang-dnstap,golang/protobuf/proto}"
+
+# documentation dependencies
+RUN apt-get install -y -qqq doxygen python3-sphinx python3-breathe python3-sphinx-rtd-theme
+
+# Python packages required for Deckard CI
+# Python: grab latest versions from PyPi
+# (Augeas binding in Debian packages are slow and buggy)
+RUN apt-get install -y -qqq python3-pip wget augeas-tools
+RUN pip3 install --upgrade pip
+RUN pip3 install pylint
+RUN pip3 install pep8
+# FIXME replace with dnspython >= 2.2.0 once released
+RUN pip3 install git+https://github.com/bwelling/dnspython.git@72348d4698a8f8b209fbdf9e72738904ad31b930
+# tests/pytest dependencies: skip over broken versions
+RUN pip3 install jinja2 'pytest != 6.0.0' pytest-html pytest-xdist pytest-forked
+# apkg for packaging
+RUN pip3 install apkg
+
+# packet capture tools for Deckard
+RUN apt-get install --no-install-suggests --no-install-recommends -y -qqq tcpdump wireshark-common
+
+# Faketime for Deckard
+RUN apt-get install -y -qqq faketime
+
+# C dependencies for python-augeas
+RUN apt-get install -y -qqq libaugeas-dev libffi-dev
+# Python dependencies for Deckard
+RUN wget https://gitlab.nic.cz/knot/deckard/raw/master/requirements.txt -O /tmp/deckard-req.txt
+RUN pip3 install -r /tmp/deckard-req.txt
+
+# build and install latest version of Knot DNS
+RUN git clone --depth=1 --branch=$KNOT_BRANCH https://gitlab.nic.cz/knot/knot-dns.git /tmp/knot
+WORKDIR /tmp/knot
+RUN pwd
+RUN autoreconf -if
+RUN ./configure --prefix=/usr --enable-xdp=yes
+RUN CFLAGS="-g" make
+RUN make install
+RUN ldconfig
+
+# Valgrind for kresd CI
+RUN apt-get install valgrind -y -qqq
+RUN wget https://github.com/LuaJIT/LuaJIT/raw/v2.1.0-beta3/src/lj.supp -O /lj.supp
+# TODO: rebuild LuaJIT with Valgrind support
+
+# Lua lint for kresd CI
+RUN apt-get install luarocks -y -qqq
+RUN luarocks --lua-version 5.1 install luacheck
+
+# respdiff for kresd CI
+RUN apt-get install lmdb-utils -y -qqq
+RUN git clone --depth=1 https://gitlab.nic.cz/knot/respdiff /var/opt/respdiff
+RUN pip3 install -r /var/opt/respdiff/requirements.txt
+
+# Python static analysis for respdiff
+RUN pip3 install mypy
+RUN pip3 install flake8
+
+# Python requests for CI scripts
+RUN pip3 install requests
+
+# docker-py for packaging tests
+RUN pip3 install docker
+
+# Unbound for respdiff
+RUN apt-get install unbound unbound-anchor -y -qqq
+RUN printf "server:\n interface: 127.0.0.1@53535\n use-syslog: yes\n do-ip6: no\nremote-control:\n control-enable: no\n" >> /etc/unbound/unbound.conf
+
+# BIND for respdiff
+RUN apt-get install bind9 -y -qqq
+RUN printf '\nOPTIONS="-4 $OPTIONS"' >> /etc/default/bind9
+RUN printf 'options {\n directory "/var/cache/bind";\n listen-on port 53533 { 127.0.0.1; };\n listen-on-v6 port 53533 { ::1; };\n};\n' > /etc/bind/named.conf.options
+
+# PowerDNS Recursor for Deckard CI
+RUN apt-get install pdns-recursor -y -qqq
+
+# dnsdist for Deckard CI
+RUN apt-get install dnsdist -y -qqq
+
+# code coverage
+RUN apt-get install -y -qqq lcov
+RUN luarocks --lua-version 5.1 install luacov
+
+# LuaJIT binary for stand-alone scripting
+RUN apt-get install -y -qqq luajit
+
+# clang for kresd CI, version updated as debian updates it
+RUN apt-get install -y -qqq clang clang-tools clang-tidy
+
+# OpenBuildService CLI tool
+RUN apt-get install -y osc
+
+# curl (API)
+RUN apt-get install -y curl
+
+# configure knot-resolver-testing OBS repo for dependencies missing in Debian
+RUN echo 'deb http://download.opensuse.org/repositories/home:/CZ-NIC:/knot-resolver-testing/Debian_11/ /' > /etc/apt/sources.list.d/knot-resolver-testing.list
+RUN wget -nv https://download.opensuse.org/repositories/home:CZ-NIC:knot-resolver-testing/Debian_11/Release.key -O Release.key
+RUN APT_KEY_DONT_WARN_ON_DANGEROUS_USAGE=1 apt-key add Release.key
+RUN rm Release.key
+RUN apt-get update -qq
+
+# packages from our knot-resolver-testing repo
+RUN apt-get update
+RUN apt-get install -y -qqq lua-psl
+
+# en_US.UTF-8 locale for scripts.update-authors.sh
+RUN apt-get install -y -qqq locales
+RUN sed -i "/en_US.UTF-8/ s/^#\(.*\)/\1/" /etc/locale.gen
+RUN locale-gen
+
+# SonarCloud scanner
+RUN wget -O /var/opt/wrapper.zip https://sonarcloud.io/static/cpp/build-wrapper-linux-x86.zip
+RUN wget -O /var/opt/scanner.zip https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-4.4.0.2170-linux.zip
+RUN unzip -d /var/opt /var/opt/wrapper.zip
+RUN unzip -d /var/opt /var/opt/scanner.zip
+ENV PATH "$PATH:/var/opt/build-wrapper-linux-x86:/var/opt/sonar-scanner-4.4.0.2170-linux/bin"
diff --git a/ci/images/debian-buster/Dockerfile b/ci/images/debian-buster/Dockerfile
new file mode 100644
index 0000000..4b47dda
--- /dev/null
+++ b/ci/images/debian-buster/Dockerfile
@@ -0,0 +1,145 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+FROM debian:buster
+MAINTAINER Knot Resolver <knot-resolver@labs.nic.cz>
+# >= 3.0 needed because of --enable-xdp=yes
+ARG KNOT_BRANCH=3.0
+ENV DEBIAN_FRONTEND=noninteractive
+
+WORKDIR /root
+CMD ["/bin/bash"]
+
+# generic cleanup
+RUN apt-get update -qq
+# TODO: run upgrade once buster reaches a stable release
+# RUN apt-get upgrade -y -qqq
+
+# Knot and Knot Resolver dependencies
+RUN apt-get install -y -qqq git make cmake pkg-config meson \
+ build-essential bsdmainutils libtool autoconf libcmocka-dev \
+ liburcu-dev libgnutls28-dev libedit-dev liblmdb-dev libcap-ng-dev libsystemd-dev \
+ libelf-dev libmnl-dev libidn11-dev libuv1-dev \
+ libluajit-5.1-dev lua-http libssl-dev libnghttp2-dev
+
+# Build and testing deps for Resolver's dnstap module (go stuff is just for testing)
+RUN apt-get install -y -qqq \
+ protobuf-c-compiler libprotobuf-c-dev libfstrm-dev \
+ golang-any
+# Some stuff won't work on buster:
+# package crypto/ed25519: unrecognized import path "crypto/ed25519"
+#RUN bash -c "go get github.com/{FiloSottile/gvt,cloudflare/dns,dnstap/golang-dnstap}"
+
+# documentation dependencies
+RUN apt-get install -y -qqq doxygen python3-sphinx python3-breathe python3-sphinx-rtd-theme
+
+# Python packages required for Deckard CI
+# Python: grab latest versions from PyPi
+# (Augeas binding in Debian packages are slow and buggy)
+RUN apt-get install -y -qqq python3-pip wget augeas-tools
+RUN pip3 install --upgrade pip
+RUN pip3 install pylint
+RUN pip3 install pep8
+RUN pip3 install pytest-xdist
+# tests/pytest dependencies: skip over broken versions
+RUN pip3 install 'dnspython != 2.0.0' jinja2 'pytest != 6.0.0' pytest-html pytest-xdist
+
+# packet capture tools for Deckard
+RUN apt-get install --no-install-suggests --no-install-recommends -y -qqq tcpdump wireshark-common
+
+# Faketime for Deckard
+RUN apt-get install -y -qqq faketime
+
+# C dependencies for python-augeas
+RUN apt-get install -y -qqq libaugeas-dev libffi-dev
+# Python dependencies for Deckard
+RUN wget https://gitlab.nic.cz/knot/deckard/raw/master/requirements.txt -O /tmp/deckard-req.txt
+RUN pip3 install -r /tmp/deckard-req.txt
+
+# build and install latest version of Knot DNS
+RUN git clone --depth=1 --branch=$KNOT_BRANCH https://gitlab.nic.cz/knot/knot-dns.git /tmp/knot
+WORKDIR /tmp/knot
+RUN pwd
+RUN autoreconf -if
+RUN ./configure --prefix=/usr --enable-xdp=yes
+RUN CFLAGS="-g" make
+RUN make install
+RUN ldconfig
+
+# Valgrind for kresd CI
+RUN apt-get install valgrind -y -qqq
+RUN wget https://github.com/LuaJIT/LuaJIT/raw/v2.1.0-beta3/src/lj.supp -O /lj.supp
+# TODO: rebuild LuaJIT with Valgrind support
+
+# Lua lint for kresd CI
+RUN apt-get install luarocks -y -qqq
+RUN luarocks --lua-version 5.1 install luacheck
+
+# respdiff for kresd CI
+RUN apt-get install lmdb-utils -y -qqq
+RUN git clone --depth=1 https://gitlab.nic.cz/knot/respdiff /var/opt/respdiff
+RUN pip3 install -r /var/opt/respdiff/requirements.txt
+
+# Python static analysis for respdiff
+RUN pip3 install mypy
+RUN pip3 install flake8
+
+# Python requests for CI scripts
+RUN pip3 install requests
+
+# docker-py for packaging tests
+RUN pip3 install docker
+
+# Unbound for respdiff
+RUN apt-get install unbound unbound-anchor -y -qqq
+RUN printf "server:\n interface: 127.0.0.1@53535\n use-syslog: yes\n do-ip6: no\nremote-control:\n control-enable: no\n" >> /etc/unbound/unbound.conf
+
+# BIND for respdiff
+RUN apt-get install bind9 -y -qqq
+RUN printf '\nOPTIONS="-4 $OPTIONS"' >> /etc/default/bind9
+RUN printf 'options {\n directory "/var/cache/bind";\n listen-on port 53533 { 127.0.0.1; };\n listen-on-v6 port 53533 { ::1; };\n};\n' > /etc/bind/named.conf.options
+
+# PowerDNS Recursor for Deckard CI
+RUN apt-get install pdns-recursor -y -qqq
+
+# code coverage
+RUN apt-get install -y -qqq lcov
+RUN luarocks --lua-version 5.1 install luacov
+
+# LuaJIT binary for stand-alone scripting
+RUN apt-get install -y -qqq luajit
+
+# clang for kresd CI, version updated as debian updates it
+RUN apt-get install -y -qqq clang clang-tools clang-tidy
+
+# OpenBuildService CLI tool
+RUN apt-get install -y osc
+
+# curl (API)
+RUN apt-get install -y curl
+
+# configure knot-resolver-testing OBS repo for dependencies missing in Debian
+RUN echo 'deb http://download.opensuse.org/repositories/home:/CZ-NIC:/knot-resolver-testing/Debian_10/ /' > /etc/apt/sources.list.d/knot-resolver-testing.list
+RUN wget -nv https://download.opensuse.org/repositories/home:CZ-NIC:knot-resolver-testing/Debian_10/Release.key -O Release.key
+RUN APT_KEY_DONT_WARN_ON_DANGEROUS_USAGE=1 apt-key add Release.key
+RUN rm Release.key
+RUN apt-get update -qq
+
+# packages from our knot-resolver-testing repo
+RUN apt-get install -y -qqq lua-http lua-psl
+
+# en_US.UTF-8 locale for scripts.update-authors.sh
+RUN apt-get install -y -qqq locales
+RUN sed -i "/en_US.UTF-8/ s/^#\(.*\)/\1/" /etc/locale.gen
+RUN locale-gen
+
+# SonarCloud scanner
+RUN wget -O /var/opt/wrapper.zip https://sonarcloud.io/static/cpp/build-wrapper-linux-x86.zip
+RUN wget -O /var/opt/scanner.zip https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-4.4.0.2170-linux.zip
+RUN unzip -d /var/opt /var/opt/wrapper.zip
+RUN unzip -d /var/opt /var/opt/scanner.zip
+ENV PATH "$PATH:/var/opt/build-wrapper-linux-x86:/var/opt/sonar-scanner-4.4.0.2170-linux/bin"
+
+# let's get newer meson from backports
+RUN echo 'deb http://deb.debian.org/debian buster-backports main' > /etc/apt/sources.list.d/backports.list
+RUN apt-get update -qq
+RUN apt-get -t buster-backports install -y -qqq meson
diff --git a/ci/images/push.sh b/ci/images/push.sh
new file mode 100755
index 0000000..75f5f87
--- /dev/null
+++ b/ci/images/push.sh
@@ -0,0 +1,8 @@
+#!/bin/bash
+# upload docker image into registry
+
+CURRENT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)"
+source "${CURRENT_DIR}"/vars.sh "$@"
+set -ex
+
+docker push "${FULL_NAME}"
diff --git a/ci/images/update.sh b/ci/images/update.sh
new file mode 100755
index 0000000..7be5172
--- /dev/null
+++ b/ci/images/update.sh
@@ -0,0 +1,22 @@
+#!/bin/bash
+# build and upload docker image(s) into registry
+#
+# this is a simple wrapper around build.sh and update.sh
+#
+# to build & upload all images: ./update.sh */
+
+if [[ $# -le 0 ]]; then
+ echo "usage: $0 IMAGE..."
+ exit 1
+fi
+set -e
+
+for ARG in "$@"
+do
+ IMAGE=${ARG%/}
+ echo "Building $IMAGE..."
+ ./build.sh $IMAGE
+ echo "Pushing $IMAGE..."
+ ./push.sh $IMAGE
+done
+
diff --git a/ci/images/vars.sh b/ci/images/vars.sh
new file mode 100755
index 0000000..f2ea465
--- /dev/null
+++ b/ci/images/vars.sh
@@ -0,0 +1,13 @@
+#!/bin/bash
+# define common variables for image build scripts
+
+KNOT_BRANCH="${KNOT_BRANCH:-3.1}"
+
+REGISTRY="registry.nic.cz/knot/knot-resolver/ci"
+IMAGE=$1
+if [ -z "${IMAGE}" ]; then
+ echo "image name not provided"
+ exit 1
+fi
+TAG="knot-${KNOT_BRANCH}"
+FULL_NAME="${REGISTRY}/${IMAGE}:${TAG}"
diff --git a/ci/no_assert_check.sh b/ci/no_assert_check.sh
new file mode 100755
index 0000000..a3f3563
--- /dev/null
+++ b/ci/no_assert_check.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+grep '\<assert\>' -- $(git ls-files | grep '\.[hc]$' | grep -vE '^(contrib|bench|tests)/')
+test $? -eq 1
diff --git a/ci/pkgtest.yaml b/ci/pkgtest.yaml
new file mode 100644
index 0000000..74f6ec8
--- /dev/null
+++ b/ci/pkgtest.yaml
@@ -0,0 +1,300 @@
+default:
+ interruptible: true
+
+stages:
+ - pkgbuild
+ - pkgtest
+
+# pkgbuild {{{
+.pkgbuild: &pkgbuild
+ stage: pkgbuild
+ tags:
+ - lxc
+ - amd64
+ before_script:
+ - git config --global user.name CI
+ - git config --global user.email ci@nic
+ needs: # https://gitlab.nic.cz/help/ci/yaml/README.md#artifact-downloads-to-child-pipelines
+ - pipeline: $PARENT_PIPELINE_ID
+ job: archive
+ artifacts:
+ when: always
+ expire_in: '1 day'
+ paths:
+ - pkg/
+
+.apkgbuild: &apkgbuild # new jinja2 breaks docs (sphinx/breathe)
+ - pip3 install -U apkg 'jinja2<3.1'
+ - apkg build-dep -y
+ - apkg build
+
+.pkgdebrepo: &pkgdebrepo
+ - apt-get update
+ - apt-get install -y curl gnupg2
+ - echo "deb http://download.opensuse.org/repositories/home:/CZ-NIC:/$OBS_REPO/$DISTROTEST_REPO/ /" > /etc/apt/sources.list.d/obs.list
+ - curl -fsSL "https://download.opensuse.org/repositories/home:CZ-NIC:$OBS_REPO/$DISTROTEST_REPO/Release.key" | gpg --dearmor > /etc/apt/trusted.gpg.d/obs.gpg
+ - apt-get update
+
+.debpkgbuild: &debpkgbuild
+ - *pkgdebrepo
+ - apt-get install -y python3-pip devscripts
+ - *apkgbuild
+
+centos-7:pkgbuild:
+ <<: *pkgbuild
+ image: $CI_REGISTRY/labs/lxc-gitlab-runner/centos-7
+ before_script:
+ - export LC_ALL=en_US.UTF-8
+ - git config --global user.name CI
+ - git config --global user.email ci@nic
+ script:
+ - yum install -y rpm-build python3-pip epel-release
+ - *apkgbuild
+
+debian-9:pkgbuild:
+ <<: *pkgbuild
+ image: $CI_REGISTRY/labs/lxc-gitlab-runner/debian-9
+ variables:
+ OBS_REPO: knot-resolver-build
+ DISTROTEST_REPO: Debian_9.0
+ script:
+ - *debpkgbuild
+
+debian-10:pkgbuild:
+ <<: *pkgbuild
+ image: $CI_REGISTRY/labs/lxc-gitlab-runner/debian-10
+ variables:
+ OBS_REPO: knot-resolver-build
+ DISTROTEST_REPO: Debian_10
+ script:
+ - *debpkgbuild
+
+debian-11:pkgbuild:
+ <<: *pkgbuild
+ image: $CI_REGISTRY/labs/lxc-gitlab-runner/debian-11
+ variables:
+ OBS_REPO: knot-resolver-build
+ DISTROTEST_REPO: Debian_11
+ script:
+ - *debpkgbuild
+
+fedora-34:pkgbuild:
+ <<: *pkgbuild
+ image: $CI_REGISTRY/labs/lxc-gitlab-runner/fedora-34
+ script:
+ - dnf install -y rpm-build python3-pip
+ - *apkgbuild
+
+fedora-35:pkgbuild:
+ <<: *pkgbuild
+ image: $CI_REGISTRY/labs/lxc-gitlab-runner/fedora-35
+ script:
+ - dnf install -y rpm-build python3-pip
+ - *apkgbuild
+
+opensuse-15.2:pkgbuild:
+ <<: *pkgbuild
+ image: $CI_REGISTRY/labs/lxc-gitlab-runner/opensuse-15.2
+ script:
+ - zypper addrepo -G -f https://download.opensuse.org/repositories/home:CZ-NIC:knot-resolver-build/openSUSE_Leap_15.2/home:CZ-NIC:knot-resolver-build.repo
+ - zypper install -y rpm-build python3-pip
+ - *apkgbuild
+
+opensuse-15.3:pkgbuild:
+ <<: *pkgbuild
+ image: $CI_REGISTRY/labs/lxc-gitlab-runner/opensuse-15.3
+ script:
+ - zypper addrepo -G -f https://download.opensuse.org/repositories/home:CZ-NIC:knot-resolver-build/openSUSE_Leap_15.3/home:CZ-NIC:knot-resolver-build.repo
+ - zypper install -y rpm-build python3-pip
+ - *apkgbuild
+
+rocky-8:pkgbuild:
+ <<: *pkgbuild
+ image: $CI_REGISTRY/labs/lxc-gitlab-runner/rocky-8
+ script:
+ - dnf install -y rpm-build python3-pip epel-release dnf-plugins-core
+ - dnf config-manager --set-enabled powertools
+ - *apkgbuild
+
+ubuntu-18.04:pkgbuild:
+ <<: *pkgbuild
+ image: $CI_REGISTRY/labs/lxc-gitlab-runner/ubuntu-18.04
+ variables:
+ OBS_REPO: knot-resolver-build
+ DISTROTEST_REPO: xUbuntu_18.04
+ script:
+ - *debpkgbuild
+
+ubuntu-20.04:pkgbuild:
+ <<: *pkgbuild
+ image: $CI_REGISTRY/labs/lxc-gitlab-runner/ubuntu-20.04
+ variables:
+ OBS_REPO: knot-resolver-build
+ DISTROTEST_REPO: xUbuntu_20.04
+ script:
+ - *debpkgbuild
+
+nixos-unstable:pkgbuild:
+ <<: *pkgbuild
+ # We do NOT use LXC, for now at least.
+ parallel:
+ matrix:
+ - PLATFORM: [ amd64, arm64 ]
+ tags:
+ - docker
+ - linux
+ - ${PLATFORM}
+ image: nixos/nix
+
+ variables:
+ NIX_PATH: nixpkgs=https://github.com/nixos/nixpkgs/archive/nixos-unstable.tar.gz
+ before_script:
+ script:
+ - nix-build '<nixpkgs>' -QA apkg
+ # the image auto-detects as alpine distro
+ # If apkg version differs (too much), it will fail to reuse archive and fail.
+ - ./result/bin/apkg install -d nix
+ - kresd --version
+# }}}
+
+# pkgtest {{{
+.pkgtest: &pkgtest
+ stage: pkgtest
+ tags:
+ - lxc
+ - amd64
+
+.debpkgtest: &debpkgtest
+ - *pkgdebrepo
+ - apt-get install -y knot-dnsutils
+ - apt-get install -y $(find ./pkg/pkgs -name '*.deb' | grep -v module | grep -v debug | grep -v devel)
+ - systemctl start kresd@1
+ - kdig @127.0.0.1 nic.cz | grep -qi NOERROR
+
+centos-7:pkgtest:
+ <<: *pkgtest
+ needs:
+ - centos-7:pkgbuild
+ image: $CI_REGISTRY/labs/lxc-gitlab-runner/centos-7
+ before_script:
+ - export LC_ALL=en_US.UTF-8
+ script:
+ - yum install -y epel-release
+ - yum install -y knot-utils findutils
+ - yum install -y $(find ./pkg/pkgs -name '*.rpm' | grep -v module | grep -v debug | grep -v devel)
+ - systemctl start kresd@1
+ - kdig @127.0.0.1 nic.cz | grep -qi NOERROR
+
+debian-9:pkgtest:
+ <<: *pkgtest
+ needs:
+ - debian-9:pkgbuild
+ image: $CI_REGISTRY/labs/lxc-gitlab-runner/debian-9
+ variables:
+ OBS_REPO: knot-resolver-build
+ DISTROTEST_REPO: Debian_9.0
+ script:
+ - *debpkgtest
+
+debian-10:pkgtest:
+ <<: *pkgtest
+ needs:
+ - debian-10:pkgbuild
+ image: $CI_REGISTRY/labs/lxc-gitlab-runner/debian-10
+ variables:
+ OBS_REPO: knot-resolver-build
+ DISTROTEST_REPO: Debian_10
+ script:
+ - *debpkgtest
+
+debian-11:pkgtest:
+ <<: *pkgtest
+ needs:
+ - debian-11:pkgbuild
+ image: $CI_REGISTRY/labs/lxc-gitlab-runner/debian-11
+ variables:
+ OBS_REPO: knot-resolver-build
+ DISTROTEST_REPO: Debian_11
+ script:
+ - *debpkgtest
+
+fedora-34:pkgtest:
+ <<: *pkgtest
+ needs:
+ - fedora-34:pkgbuild
+ image: $CI_REGISTRY/labs/lxc-gitlab-runner/fedora-34
+ script:
+ - dnf install -y knot-utils findutils
+ - dnf install -y $(find ./pkg/pkgs -name '*.rpm' | grep -v module | grep -v debug | grep -v devel)
+ - systemctl start kresd@1
+ - kdig @127.0.0.1 nic.cz | grep -qi NOERROR
+
+fedora-35:pkgtest:
+ <<: *pkgtest
+ needs:
+ - fedora-35:pkgbuild
+ image: $CI_REGISTRY/labs/lxc-gitlab-runner/fedora-35
+ script:
+ - dnf install -y knot-utils findutils
+ - dnf install -y $(find ./pkg/pkgs -name '*.rpm' | grep -v module | grep -v debug | grep -v devel)
+ - systemctl start kresd@1
+ - kdig @127.0.0.1 nic.cz | grep -qi NOERROR
+
+opensuse-15.2:pkgtest:
+ <<: *pkgtest
+ needs:
+ - opensuse-15.2:pkgbuild
+ image: $CI_REGISTRY/labs/lxc-gitlab-runner/opensuse-15.2
+ script:
+ - zypper addrepo -G -f https://download.opensuse.org/repositories/home:CZ-NIC:knot-resolver-build/openSUSE_Leap_15.2/home:CZ-NIC:knot-resolver-build.repo
+ - zypper install -y knot-utils
+ - zypper install --allow-unsigned-rpm -y $(find ./pkg/pkgs -name '*.rpm' | grep -v module | grep -v debug | grep -v devel)
+ - systemctl start kresd@1
+ - kdig @127.0.0.1 nic.cz | grep -qi NOERROR
+
+opensuse-15.3:pkgtest:
+ <<: *pkgtest
+ needs:
+ - opensuse-15.3:pkgbuild
+ image: $CI_REGISTRY/labs/lxc-gitlab-runner/opensuse-15.3
+ script:
+ - zypper addrepo -G -f https://download.opensuse.org/repositories/home:CZ-NIC:knot-resolver-build/openSUSE_Leap_15.3/home:CZ-NIC:knot-resolver-build.repo
+ - zypper install -y knot-utils
+ - zypper install --allow-unsigned-rpm -y $(find ./pkg/pkgs -name '*.rpm' | grep -v module | grep -v debug | grep -v devel)
+ - systemctl start kresd@1
+ - kdig @127.0.0.1 nic.cz | grep -qi NOERROR
+
+rocky-8:pkgtest:
+ <<: *pkgtest
+ needs:
+ - rocky-8:pkgbuild
+ image: $CI_REGISTRY/labs/lxc-gitlab-runner/rocky-8
+ script:
+ - dnf install -y epel-release
+ - dnf install -y knot-utils findutils
+ - dnf install -y $(find ./pkg/pkgs -name '*.rpm' | grep -v module | grep -v debug | grep -v devel)
+ - systemctl start kresd@1
+ - kdig @127.0.0.1 nic.cz | grep -qi NOERROR
+
+ubuntu-18.04:pkgtest:
+ <<: *pkgtest
+ needs:
+ - ubuntu-18.04:pkgbuild
+ image: $CI_REGISTRY/labs/lxc-gitlab-runner/ubuntu-18.04
+ variables:
+ OBS_REPO: knot-resolver-build
+ DISTROTEST_REPO: xUbuntu_18.04
+ script:
+ - *debpkgtest
+
+ubuntu-20.04:pkgtest:
+ <<: *pkgtest
+ needs:
+ - ubuntu-20.04:pkgbuild
+ image: $CI_REGISTRY/labs/lxc-gitlab-runner/ubuntu-20.04
+ variables:
+ OBS_REPO: knot-resolver-build
+ DISTROTEST_REPO: xUbuntu_20.04
+ script:
+ - *debpkgtest
+# }}}
diff --git a/ci/respdiff/kresd.config b/ci/respdiff/kresd.config
new file mode 100644
index 0000000..2b7b218
--- /dev/null
+++ b/ci/respdiff/kresd.config
@@ -0,0 +1,26 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+-- Refer to manual: https://knot-resolver.readthedocs.io/en/stable/
+-- Listen on localhost and external interface
+net.listen('127.0.0.1', 5353)
+net.listen('127.0.0.1', 8853, { tls = true })
+net.ipv6=false
+
+-- Auto-maintain root TA
+trust_anchors.add_file('.local/etc/knot-resolver/root.keys')
+
+cache.size = 1024 * MB
+
+-- Load Useful modules
+modules = {
+ 'workarounds < iterate',
+ 'policy', -- Block queries to local zones/bad sites
+ 'view', -- Views for certain clients
+ 'hints > iterate', -- Allow loading /etc/hosts or custom root hints
+ 'stats', -- Track internal statistics
+}
+
+-- avoid TC flags returned to respdiff
+local _, up_bs = net.bufsize()
+net.bufsize(4096, up_bs)
+
+log_level('debug')
diff --git a/ci/respdiff/respdiff-tcp.conf b/ci/respdiff/respdiff-tcp.conf
new file mode 100644
index 0000000..b2d40ff
--- /dev/null
+++ b/ci/respdiff/respdiff-tcp.conf
@@ -0,0 +1,52 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+[sendrecv]
+# in seconds
+timeout = 11
+# number of queries to run simultaneously
+jobs = 64
+# in seconds (float); delay each query by a random time (uniformly distributed) between min and max; set max to 0 to disable
+time_delay_min = 0
+time_delay_max = 0
+
+[servers]
+names = kresd, bind, unbound
+# symbolic names of DNS servers under test
+# separate multiple values by ,
+
+# each symbolic name in [servers] section refers to config section
+# containing IP address and port of particular server
+[kresd]
+ip = 127.0.0.1
+port = 5353
+transport = tcp
+graph_color = #00a2e2
+restart_script = ./ci/respdiff/restart-kresd.sh
+
+[bind]
+ip = 127.0.0.1
+port = 53533
+transport = udp
+graph_color = #e2a000
+restart_script = ./ci/respdiff/restart-bind.sh
+
+[unbound]
+ip = 127.0.0.1
+port = 53535
+transport = udp
+graph_color = #218669
+restart_script = ./ci/respdiff/restart-unbound.sh
+
+[diff]
+# symbolic name of server under test
+# other servers are used as reference when comparing answers from the target
+target = kresd
+
+# fields and comparison methods used when comparing two DNS messages
+criteria = opcode, rcode, flags, question, answertypes, answerrrsigs
+# other supported criteria values: authority, additional, edns, nsid
+
+[report]
+# diffsum reports mismatches in field values in this order
+# if particular message has multiple mismatches, it is counted only once into category with highest weight
+field_weights = timeout, malformed, opcode, question, rcode, flags, answertypes, answerrrsigs, answer, authority, additional, edns, nsid
diff --git a/ci/respdiff/respdiff-tls.conf b/ci/respdiff/respdiff-tls.conf
new file mode 100644
index 0000000..1a50eab
--- /dev/null
+++ b/ci/respdiff/respdiff-tls.conf
@@ -0,0 +1,52 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+[sendrecv]
+# in seconds
+timeout = 11
+# number of queries to run simultaneously
+jobs = 64
+# in seconds (float); delay each query by a random time (uniformly distributed) between min and max; set max to 0 to disable
+time_delay_min = 0
+time_delay_max = 0
+
+[servers]
+names = kresd, bind, unbound
+# symbolic names of DNS servers under test
+# separate multiple values by ,
+
+# each symbolic name in [servers] section refers to config section
+# containing IP address and port of particular server
+[kresd]
+ip = 127.0.0.1
+port = 8853
+transport = tls
+graph_color = #00a2e2
+restart_script = ./ci/respdiff/restart-kresd.sh
+
+[bind]
+ip = 127.0.0.1
+port = 53533
+transport = udp
+graph_color = #e2a000
+restart_script = ./ci/respdiff/restart-bind.sh
+
+[unbound]
+ip = 127.0.0.1
+port = 53535
+transport = udp
+graph_color = #218669
+restart_script = ./ci/respdiff/restart-unbound.sh
+
+[diff]
+# symbolic name of server under test
+# other servers are used as reference when comparing answers from the target
+target = kresd
+
+# fields and comparison methods used when comparing two DNS messages
+criteria = opcode, rcode, flags, question, answertypes, answerrrsigs
+# other supported criteria values: authority, additional, edns, nsid
+
+[report]
+# diffsum reports mismatches in field values in this order
+# if particular message has multiple mismatches, it is counted only once into category with highest weight
+field_weights = timeout, malformed, opcode, question, rcode, flags, answertypes, answerrrsigs, answer, authority, additional, edns, nsid
diff --git a/ci/respdiff/respdiff-udp.conf b/ci/respdiff/respdiff-udp.conf
new file mode 100644
index 0000000..35a69a9
--- /dev/null
+++ b/ci/respdiff/respdiff-udp.conf
@@ -0,0 +1,52 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+[sendrecv]
+# in seconds
+timeout = 11
+# number of queries to run simultaneously
+jobs = 64
+# in seconds (float); delay each query by a random time (uniformly distributed) between min and max; set max to 0 to disable
+time_delay_min = 0
+time_delay_max = 0
+
+[servers]
+names = kresd, bind, unbound
+# symbolic names of DNS servers under test
+# separate multiple values by ,
+
+# each symbolic name in [servers] section refers to config section
+# containing IP address and port of particular server
+[kresd]
+ip = 127.0.0.1
+port = 5353
+transport = udp
+graph_color = #00a2e2
+restart_script = ./ci/respdiff/restart-kresd.sh
+
+[bind]
+ip = 127.0.0.1
+port = 53533
+transport = udp
+graph_color = #e2a000
+restart_script = ./ci/respdiff/restart-bind.sh
+
+[unbound]
+ip = 127.0.0.1
+port = 53535
+transport = udp
+graph_color = #218669
+restart_script = ./ci/respdiff/restart-unbound.sh
+
+[diff]
+# symbolic name of server under test
+# other servers are used as reference when comparing answers from the target
+target = kresd
+
+# fields and comparison methods used when comparing two DNS messages
+criteria = opcode, rcode, flags, question, answertypes, answerrrsigs
+# other supported criteria values: authority, additional, edns, nsid
+
+[report]
+# diffsum reports mismatches in field values in this order
+# if particular message has multiple mismatches, it is counted only once into category with highest weight
+field_weights = timeout, malformed, opcode, question, rcode, flags, answertypes, answerrrsigs, answer, authority, additional, edns, nsid
diff --git a/ci/respdiff/restart-bind.sh b/ci/respdiff/restart-bind.sh
new file mode 100755
index 0000000..35838c7
--- /dev/null
+++ b/ci/respdiff/restart-bind.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-3.0-or-later
+service named restart
diff --git a/ci/respdiff/restart-kresd.sh b/ci/respdiff/restart-kresd.sh
new file mode 100755
index 0000000..4e9387c
--- /dev/null
+++ b/ci/respdiff/restart-kresd.sh
@@ -0,0 +1,12 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+exec > /dev/null
+exec 2>&1
+
+killall -w kresd
+rm -f '*.mdb'
+$PREFIX/sbin/kresd -n -q -c $(pwd)/ci/respdiff/kresd.config &>>kresd.log &
+
+# wait until socket is receiving connections
+sleep 1
diff --git a/ci/respdiff/restart-unbound.sh b/ci/respdiff/restart-unbound.sh
new file mode 100755
index 0000000..add24c9
--- /dev/null
+++ b/ci/respdiff/restart-unbound.sh
@@ -0,0 +1,4 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+service unbound restart
diff --git a/ci/respdiff/run-respdiff-tests.sh b/ci/respdiff/run-respdiff-tests.sh
new file mode 100755
index 0000000..2bfc44d
--- /dev/null
+++ b/ci/respdiff/run-respdiff-tests.sh
@@ -0,0 +1,27 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# $1 == udp/tcp/tls, it selects configuration file to use
+# respdiff scripts must be present in /var/opt/respdiff
+set -o errexit -o nounset -o xtrace
+
+NDIFFREPRO=3
+
+wget -qO- https://gitlab.nic.cz/knot/respdiff/snippets/238/raw?inline=false | head -n 5000 > /tmp/queries.txt
+mkdir results
+rm -rf respdiff.db
+
+CONFIG="$(pwd)/ci/respdiff/respdiff-${1}.conf"
+/var/opt/respdiff/qprep.py respdiff.db < /tmp/queries.txt
+time /var/opt/respdiff/orchestrator.py respdiff.db -c "${CONFIG}"
+time /var/opt/respdiff/msgdiff.py respdiff.db -c "${CONFIG}"
+for i in $(seq $NDIFFREPRO); do
+ time /var/opt/respdiff/diffrepro.py -c "${CONFIG}" respdiff.db
+done
+/var/opt/respdiff/diffsum.py respdiff.db -c "${CONFIG}" > results/respdiff.txt
+/var/opt/respdiff/histogram.py respdiff.db -c "${CONFIG}" -o results/histogram.svg
+: minimize LMDB and log size so they can be effectively archived
+mkdir results/respdiff.db
+mdb_copy -c respdiff.db results/respdiff.db
+xz -9 results/respdiff.db/data.mdb
+xz kresd.log
diff --git a/ci/respdiff/start-resolvers.sh b/ci/respdiff/start-resolvers.sh
new file mode 100755
index 0000000..87e98f3
--- /dev/null
+++ b/ci/respdiff/start-resolvers.sh
@@ -0,0 +1,13 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+#run unbound
+service unbound start && service unbound status;
+# dig @localhost -p 53535
+
+#run bind
+service named start && service named status;
+# dig @localhost -p 53533
+
+#run kresd
+$PREFIX/sbin/kresd -n -q -c $(pwd)/ci/respdiff/kresd.config &>kresd.log &
+# dig @localhost -p 5353
diff --git a/client/.packaging/test.sh b/client/.packaging/test.sh
new file mode 100755
index 0000000..e1311c4
--- /dev/null
+++ b/client/.packaging/test.sh
@@ -0,0 +1,5 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-3.0-or-later
+test -e sbin/kresc
+sbin/kresc # command will fail because of invalid parameters
+test "$?" -eq 1 # linker error would have different exit code
diff --git a/contrib/base32hex.c b/contrib/base32hex.c
new file mode 100644
index 0000000..b12718e
--- /dev/null
+++ b/contrib/base32hex.c
@@ -0,0 +1,277 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#include "base32hex.h"
+
+#include <stdlib.h>
+#include <stdint.h>
+
+/*! \brief Maximal length of binary input to Base32hex encoding. */
+#define MAX_BIN_DATA_LEN ((INT32_MAX / 8) * 5)
+
+/*! \brief Base32hex padding character. */
+static const uint8_t base32hex_pad = '=';
+/*! \brief Base32hex alphabet. Beware: original code was upper-case. */
+static const uint8_t base32hex_enc[] = "0123456789abcdefghijklmnopqrstuv";
+
+/*! \brief Indicates bad Base32hex character. */
+#define KO 255
+/*! \brief Indicates Base32hex padding character. */
+#define PD 32
+
+/*! \brief Transformation and validation table for decoding Base32hex. */
+static const uint8_t base32hex_dec[256] = {
+ [ 0] = KO, [ 43] = KO, ['V'] = 31, [129] = KO, [172] = KO, [215] = KO,
+ [ 1] = KO, [ 44] = KO, ['W'] = KO, [130] = KO, [173] = KO, [216] = KO,
+ [ 2] = KO, [ 45] = KO, ['X'] = KO, [131] = KO, [174] = KO, [217] = KO,
+ [ 3] = KO, [ 46] = KO, ['Y'] = KO, [132] = KO, [175] = KO, [218] = KO,
+ [ 4] = KO, [ 47] = KO, ['Z'] = KO, [133] = KO, [176] = KO, [219] = KO,
+ [ 5] = KO, ['0'] = 0, [ 91] = KO, [134] = KO, [177] = KO, [220] = KO,
+ [ 6] = KO, ['1'] = 1, [ 92] = KO, [135] = KO, [178] = KO, [221] = KO,
+ [ 7] = KO, ['2'] = 2, [ 93] = KO, [136] = KO, [179] = KO, [222] = KO,
+ [ 8] = KO, ['3'] = 3, [ 94] = KO, [137] = KO, [180] = KO, [223] = KO,
+ [ 9] = KO, ['4'] = 4, [ 95] = KO, [138] = KO, [181] = KO, [224] = KO,
+ [ 10] = KO, ['5'] = 5, [ 96] = KO, [139] = KO, [182] = KO, [225] = KO,
+ [ 11] = KO, ['6'] = 6, ['a'] = 10, [140] = KO, [183] = KO, [226] = KO,
+ [ 12] = KO, ['7'] = 7, ['b'] = 11, [141] = KO, [184] = KO, [227] = KO,
+ [ 13] = KO, ['8'] = 8, ['c'] = 12, [142] = KO, [185] = KO, [228] = KO,
+ [ 14] = KO, ['9'] = 9, ['d'] = 13, [143] = KO, [186] = KO, [229] = KO,
+ [ 15] = KO, [ 58] = KO, ['e'] = 14, [144] = KO, [187] = KO, [230] = KO,
+ [ 16] = KO, [ 59] = KO, ['f'] = 15, [145] = KO, [188] = KO, [231] = KO,
+ [ 17] = KO, [ 60] = KO, ['g'] = 16, [146] = KO, [189] = KO, [232] = KO,
+ [ 18] = KO, ['='] = PD, ['h'] = 17, [147] = KO, [190] = KO, [233] = KO,
+ [ 19] = KO, [ 62] = KO, ['i'] = 18, [148] = KO, [191] = KO, [234] = KO,
+ [ 20] = KO, [ 63] = KO, ['j'] = 19, [149] = KO, [192] = KO, [235] = KO,
+ [ 21] = KO, [ 64] = KO, ['k'] = 20, [150] = KO, [193] = KO, [236] = KO,
+ [ 22] = KO, ['A'] = 10, ['l'] = 21, [151] = KO, [194] = KO, [237] = KO,
+ [ 23] = KO, ['B'] = 11, ['m'] = 22, [152] = KO, [195] = KO, [238] = KO,
+ [ 24] = KO, ['C'] = 12, ['n'] = 23, [153] = KO, [196] = KO, [239] = KO,
+ [ 25] = KO, ['D'] = 13, ['o'] = 24, [154] = KO, [197] = KO, [240] = KO,
+ [ 26] = KO, ['E'] = 14, ['p'] = 25, [155] = KO, [198] = KO, [241] = KO,
+ [ 27] = KO, ['F'] = 15, ['q'] = 26, [156] = KO, [199] = KO, [242] = KO,
+ [ 28] = KO, ['G'] = 16, ['r'] = 27, [157] = KO, [200] = KO, [243] = KO,
+ [ 29] = KO, ['H'] = 17, ['s'] = 28, [158] = KO, [201] = KO, [244] = KO,
+ [ 30] = KO, ['I'] = 18, ['t'] = 29, [159] = KO, [202] = KO, [245] = KO,
+ [ 31] = KO, ['J'] = 19, ['u'] = 30, [160] = KO, [203] = KO, [246] = KO,
+ [ 32] = KO, ['K'] = 20, ['v'] = 31, [161] = KO, [204] = KO, [247] = KO,
+ [ 33] = KO, ['L'] = 21, ['w'] = KO, [162] = KO, [205] = KO, [248] = KO,
+ [ 34] = KO, ['M'] = 22, ['x'] = KO, [163] = KO, [206] = KO, [249] = KO,
+ [ 35] = KO, ['N'] = 23, ['y'] = KO, [164] = KO, [207] = KO, [250] = KO,
+ [ 36] = KO, ['O'] = 24, ['z'] = KO, [165] = KO, [208] = KO, [251] = KO,
+ [ 37] = KO, ['P'] = 25, [123] = KO, [166] = KO, [209] = KO, [252] = KO,
+ [ 38] = KO, ['Q'] = 26, [124] = KO, [167] = KO, [210] = KO, [253] = KO,
+ [ 39] = KO, ['R'] = 27, [125] = KO, [168] = KO, [211] = KO, [254] = KO,
+ [ 40] = KO, ['S'] = 28, [126] = KO, [169] = KO, [212] = KO, [255] = KO,
+ [ 41] = KO, ['T'] = 29, [127] = KO, [170] = KO, [213] = KO,
+ [ 42] = KO, ['U'] = 30, [128] = KO, [171] = KO, [214] = KO,
+};
+
+int32_t base32hex_decode(const uint8_t *in,
+ const uint32_t in_len,
+ uint8_t *out,
+ const uint32_t out_len)
+{
+ // Checking inputs.
+ if (in == NULL || out == NULL) {
+ return -1;
+ }
+ if (in_len > INT32_MAX || out_len < ((in_len + 7) / 8) * 5) {
+ return -1;
+ }
+ if ((in_len % 8) != 0) {
+ return -1;
+ }
+
+ const uint8_t *stop = in + in_len;
+ uint8_t *bin = out;
+ uint8_t pad_len = 0;
+ uint8_t c1, c2, c3, c4, c5, c6, c7, c8;
+
+ // Decoding loop takes 8 characters and creates 5 bytes.
+ while (in < stop) {
+ // Filling and transforming 8 Base32hex chars.
+ c1 = base32hex_dec[in[0]];
+ c2 = base32hex_dec[in[1]];
+ c3 = base32hex_dec[in[2]];
+ c4 = base32hex_dec[in[3]];
+ c5 = base32hex_dec[in[4]];
+ c6 = base32hex_dec[in[5]];
+ c7 = base32hex_dec[in[6]];
+ c8 = base32hex_dec[in[7]];
+
+ // Check 8. char if is bad or padding.
+ if (c8 >= PD) {
+ if (c8 == PD && pad_len == 0) {
+ pad_len = 1;
+ } else {
+ return -1;
+ }
+ }
+
+ // Check 7. char if is bad or padding (if so, 6. must be too).
+ if (c7 >= PD) {
+ if (c7 == PD && c6 == PD && pad_len == 1) {
+ pad_len = 3;
+ } else {
+ return -1;
+ }
+ }
+
+ // Check 6. char if is bad or padding.
+ if (c6 >= PD) {
+ if (!(c6 == PD && pad_len == 3)) {
+ return -1;
+ }
+ }
+
+ // Check 5. char if is bad or padding.
+ if (c5 >= PD) {
+ if (c5 == PD && pad_len == 3) {
+ pad_len = 4;
+ } else {
+ return -1;
+ }
+ }
+
+ // Check 4. char if is bad or padding (if so, 3. must be too).
+ if (c4 >= PD) {
+ if (c4 == PD && c3 == PD && pad_len == 4) {
+ pad_len = 6;
+ } else {
+ return -1;
+ }
+ }
+
+ // Check 3. char if is bad or padding.
+ if (c3 >= PD) {
+ if (!(c3 == PD && pad_len == 6)) {
+ return -1;
+ }
+ }
+
+ // 1. and 2. chars must not be padding.
+ if (c2 >= PD || c1 >= PD) {
+ return -1;
+ }
+
+ // Computing of output data based on padding length.
+ switch (pad_len) {
+ case 0:
+ bin[4] = (c7 << 5) + c8;
+ case 1:
+ bin[3] = (c5 << 7) + (c6 << 2) + (c7 >> 3);
+ case 3:
+ bin[2] = (c4 << 4) + (c5 >> 1);
+ case 4:
+ bin[1] = (c2 << 6) + (c3 << 1) + (c4 >> 4);
+ case 6:
+ bin[0] = (c1 << 3) + (c2 >> 2);
+ }
+
+ // Update output end.
+ switch (pad_len) {
+ case 0:
+ bin += 5;
+ break;
+ case 1:
+ bin += 4;
+ break;
+ case 3:
+ bin += 3;
+ break;
+ case 4:
+ bin += 2;
+ break;
+ case 6:
+ bin += 1;
+ break;
+ }
+
+ in += 8;
+ }
+
+ return (bin - out);
+}
+
+int32_t base32hex_encode(const uint8_t *in,
+ const uint32_t in_len,
+ uint8_t *out,
+ const uint32_t out_len)
+{
+ // Checking inputs.
+ if (in == NULL || out == NULL) {
+ return -1;
+ }
+ if (in_len > MAX_BIN_DATA_LEN || out_len < ((in_len + 4) / 5) * 8) {
+ return -1;
+ }
+
+ uint8_t rest_len = in_len % 5;
+ const uint8_t *stop = in + in_len - rest_len;
+ uint8_t *text = out;
+
+ // Encoding loop takes 5 bytes and creates 8 characters.
+ while (in < stop) {
+ text[0] = base32hex_enc[in[0] >> 3];
+ text[1] = base32hex_enc[(in[0] & 0x07) << 2 | in[1] >> 6];
+ text[2] = base32hex_enc[(in[1] & 0x3E) >> 1];
+ text[3] = base32hex_enc[(in[1] & 0x01) << 4 | in[2] >> 4];
+ text[4] = base32hex_enc[(in[2] & 0x0F) << 1 | in[3] >> 7];
+ text[5] = base32hex_enc[(in[3] & 0x7C) >> 2];
+ text[6] = base32hex_enc[(in[3] & 0x03) << 3 | in[4] >> 5];
+ text[7] = base32hex_enc[in[4] & 0x1F];
+ text += 8;
+ in += 5;
+ }
+
+ // Processing of padding, if any.
+ switch (rest_len) {
+ case 4:
+ text[0] = base32hex_enc[in[0] >> 3];
+ text[1] = base32hex_enc[(in[0] & 0x07) << 2 | in[1] >> 6];
+ text[2] = base32hex_enc[(in[1] & 0x3E) >> 1];
+ text[3] = base32hex_enc[(in[1] & 0x01) << 4 | in[2] >> 4];
+ text[4] = base32hex_enc[(in[2] & 0x0F) << 1 | in[3] >> 7];
+ text[5] = base32hex_enc[(in[3] & 0x7C) >> 2];
+ text[6] = base32hex_enc[(in[3] & 0x03) << 3];
+ text[7] = base32hex_pad;
+ text += 8;
+ break;
+ case 3:
+ text[0] = base32hex_enc[in[0] >> 3];
+ text[1] = base32hex_enc[(in[0] & 0x07) << 2 | in[1] >> 6];
+ text[2] = base32hex_enc[(in[1] & 0x3E) >> 1];
+ text[3] = base32hex_enc[(in[1] & 0x01) << 4 | in[2] >> 4];
+ text[4] = base32hex_enc[(in[2] & 0x0F) << 1];
+ text[5] = base32hex_pad;
+ text[6] = base32hex_pad;
+ text[7] = base32hex_pad;
+ text += 8;
+ break;
+ case 2:
+ text[0] = base32hex_enc[in[0] >> 3];
+ text[1] = base32hex_enc[(in[0] & 0x07) << 2 | in[1] >> 6];
+ text[2] = base32hex_enc[(in[1] & 0x3E) >> 1];
+ text[3] = base32hex_enc[(in[1] & 0x01) << 4];
+ text[4] = base32hex_pad;
+ text[5] = base32hex_pad;
+ text[6] = base32hex_pad;
+ text[7] = base32hex_pad;
+ text += 8;
+ break;
+ case 1:
+ text[0] = base32hex_enc[in[0] >> 3];
+ text[1] = base32hex_enc[(in[0] & 0x07) << 2];
+ text[2] = base32hex_pad;
+ text[3] = base32hex_pad;
+ text[4] = base32hex_pad;
+ text[5] = base32hex_pad;
+ text[6] = base32hex_pad;
+ text[7] = base32hex_pad;
+ text += 8;
+ break;
+ }
+
+ return (text - out);
+}
diff --git a/contrib/base32hex.h b/contrib/base32hex.h
new file mode 100644
index 0000000..2416786
--- /dev/null
+++ b/contrib/base32hex.h
@@ -0,0 +1,60 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+/*!
+ * \file
+ *
+ * \brief Base32hex implementation (RFC 4648).
+ *
+ * \note Input Base32hex string can contain a-v characters. These characters
+ * are considered as A-V equivalent.
+ *
+ * \addtogroup contrib
+ * @{
+ */
+
+#pragma once
+
+#include <stdint.h>
+
+/*!
+ * \brief Decodes text data using Base32hex.
+ *
+ * \note Input data needn't be terminated with '\0'.
+ *
+ * \note Input data must be continuous Base32hex string!
+ *
+ * \param in Input text data.
+ * \param in_len Length of input string.
+ * \param out Output data buffer.
+ * \param out_len Size of output buffer.
+ *
+ * \retval >=0 length of output data.
+ * \retval KNOT_E* if error.
+ */
+int32_t base32hex_decode(const uint8_t *in,
+ const uint32_t in_len,
+ uint8_t *out,
+ const uint32_t out_len);
+
+
+/*!
+ * \brief Encodes binary data using Base32hex. Lower case is used!
+ *
+ * \note Output data buffer contains Base32hex text string which isn't
+ * terminated with '\0'!
+ *
+ * \param in Input binary data.
+ * \param in_len Length of input data.
+ * \param out Output data buffer.
+ * \param out_len Size of output buffer.
+ *
+ * \retval >=0 length of output string.
+ * \retval <0 if error.
+ */
+int32_t base32hex_encode(const uint8_t *in,
+ const uint32_t in_len,
+ uint8_t *out,
+ const uint32_t out_len);
+
+/*! @} */
diff --git a/contrib/base32hex.spdx b/contrib/base32hex.spdx
new file mode 100644
index 0000000..7137645
--- /dev/null
+++ b/contrib/base32hex.spdx
@@ -0,0 +1,10 @@
+SPDXVersion: SPDX-2.1
+DataLicense: CC0-1.0
+SPDXID: SPDXRef-DOCUMENT
+DocumentName: knotdns-base32hex
+DocumentNamespace: http://spdx.org/spdxdocs/spdx-v2.1-4f29f08d-5fbf-4793-934c-9a6a2e6d5517
+
+PackageName: knotdns-base32hex
+PackageDownloadLocation: git+https://gitlab.nic.cz/knot/knot-dns.git@2b3c828a4cb8d9595318552483d4947345426c30#src/libknot/internal/base32hex.c
+PackageOriginator: Organization: Knot DNS contributors
+PackageLicenseDeclared: GPL-3.0-or-later
diff --git a/contrib/base64.c b/contrib/base64.c
new file mode 100644
index 0000000..e5c004e
--- /dev/null
+++ b/contrib/base64.c
@@ -0,0 +1,260 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#include "base64.h"
+#include "libknot/errcode.h"
+
+#include <stdlib.h>
+#include <stdint.h>
+
+/*! \brief Maximal length of binary input to Base64 encoding. */
+#define MAX_BIN_DATA_LEN ((INT32_MAX / 4) * 3)
+
+/*! \brief Base64 padding character. */
+static const uint8_t base64_pad = '=';
+/*! \brief Base64 alphabet. */
+static const uint8_t base64_enc[] =
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+/*! \brief Indicates bad Base64 character. */
+#define KO 255
+/*! \brief Indicates Base64 padding character. */
+#define PD 64
+
+/*! \brief Transformation and validation table for decoding Base64. */
+static const uint8_t base64_dec[256] = {
+ [ 0] = KO, ['+'] = 62, ['V'] = 21, [129] = KO, [172] = KO, [215] = KO,
+ [ 1] = KO, [ 44] = KO, ['W'] = 22, [130] = KO, [173] = KO, [216] = KO,
+ [ 2] = KO, [ 45] = KO, ['X'] = 23, [131] = KO, [174] = KO, [217] = KO,
+ [ 3] = KO, [ 46] = KO, ['Y'] = 24, [132] = KO, [175] = KO, [218] = KO,
+ [ 4] = KO, ['/'] = 63, ['Z'] = 25, [133] = KO, [176] = KO, [219] = KO,
+ [ 5] = KO, ['0'] = 52, [ 91] = KO, [134] = KO, [177] = KO, [220] = KO,
+ [ 6] = KO, ['1'] = 53, [ 92] = KO, [135] = KO, [178] = KO, [221] = KO,
+ [ 7] = KO, ['2'] = 54, [ 93] = KO, [136] = KO, [179] = KO, [222] = KO,
+ [ 8] = KO, ['3'] = 55, [ 94] = KO, [137] = KO, [180] = KO, [223] = KO,
+ [ 9] = KO, ['4'] = 56, [ 95] = KO, [138] = KO, [181] = KO, [224] = KO,
+ [ 10] = KO, ['5'] = 57, [ 96] = KO, [139] = KO, [182] = KO, [225] = KO,
+ [ 11] = KO, ['6'] = 58, ['a'] = 26, [140] = KO, [183] = KO, [226] = KO,
+ [ 12] = KO, ['7'] = 59, ['b'] = 27, [141] = KO, [184] = KO, [227] = KO,
+ [ 13] = KO, ['8'] = 60, ['c'] = 28, [142] = KO, [185] = KO, [228] = KO,
+ [ 14] = KO, ['9'] = 61, ['d'] = 29, [143] = KO, [186] = KO, [229] = KO,
+ [ 15] = KO, [ 58] = KO, ['e'] = 30, [144] = KO, [187] = KO, [230] = KO,
+ [ 16] = KO, [ 59] = KO, ['f'] = 31, [145] = KO, [188] = KO, [231] = KO,
+ [ 17] = KO, [ 60] = KO, ['g'] = 32, [146] = KO, [189] = KO, [232] = KO,
+ [ 18] = KO, ['='] = PD, ['h'] = 33, [147] = KO, [190] = KO, [233] = KO,
+ [ 19] = KO, [ 62] = KO, ['i'] = 34, [148] = KO, [191] = KO, [234] = KO,
+ [ 20] = KO, [ 63] = KO, ['j'] = 35, [149] = KO, [192] = KO, [235] = KO,
+ [ 21] = KO, [ 64] = KO, ['k'] = 36, [150] = KO, [193] = KO, [236] = KO,
+ [ 22] = KO, ['A'] = 0, ['l'] = 37, [151] = KO, [194] = KO, [237] = KO,
+ [ 23] = KO, ['B'] = 1, ['m'] = 38, [152] = KO, [195] = KO, [238] = KO,
+ [ 24] = KO, ['C'] = 2, ['n'] = 39, [153] = KO, [196] = KO, [239] = KO,
+ [ 25] = KO, ['D'] = 3, ['o'] = 40, [154] = KO, [197] = KO, [240] = KO,
+ [ 26] = KO, ['E'] = 4, ['p'] = 41, [155] = KO, [198] = KO, [241] = KO,
+ [ 27] = KO, ['F'] = 5, ['q'] = 42, [156] = KO, [199] = KO, [242] = KO,
+ [ 28] = KO, ['G'] = 6, ['r'] = 43, [157] = KO, [200] = KO, [243] = KO,
+ [ 29] = KO, ['H'] = 7, ['s'] = 44, [158] = KO, [201] = KO, [244] = KO,
+ [ 30] = KO, ['I'] = 8, ['t'] = 45, [159] = KO, [202] = KO, [245] = KO,
+ [ 31] = KO, ['J'] = 9, ['u'] = 46, [160] = KO, [203] = KO, [246] = KO,
+ [ 32] = KO, ['K'] = 10, ['v'] = 47, [161] = KO, [204] = KO, [247] = KO,
+ [ 33] = KO, ['L'] = 11, ['w'] = 48, [162] = KO, [205] = KO, [248] = KO,
+ [ 34] = KO, ['M'] = 12, ['x'] = 49, [163] = KO, [206] = KO, [249] = KO,
+ [ 35] = KO, ['N'] = 13, ['y'] = 50, [164] = KO, [207] = KO, [250] = KO,
+ [ 36] = KO, ['O'] = 14, ['z'] = 51, [165] = KO, [208] = KO, [251] = KO,
+ [ 37] = KO, ['P'] = 15, [123] = KO, [166] = KO, [209] = KO, [252] = KO,
+ [ 38] = KO, ['Q'] = 16, [124] = KO, [167] = KO, [210] = KO, [253] = KO,
+ [ 39] = KO, ['R'] = 17, [125] = KO, [168] = KO, [211] = KO, [254] = KO,
+ [ 40] = KO, ['S'] = 18, [126] = KO, [169] = KO, [212] = KO, [255] = KO,
+ [ 41] = KO, ['T'] = 19, [127] = KO, [170] = KO, [213] = KO,
+ [ 42] = KO, ['U'] = 20, [128] = KO, [171] = KO, [214] = KO,
+};
+
+int32_t kr_base64_encode(const uint8_t *in,
+ const uint32_t in_len,
+ uint8_t *out,
+ const uint32_t out_len)
+{
+ // Checking inputs.
+ if (in == NULL || out == NULL) {
+ return KNOT_EINVAL;
+ }
+ if (in_len > MAX_BIN_DATA_LEN || out_len < ((in_len + 2) / 3) * 4) {
+ return KNOT_ERANGE;
+ }
+
+ uint8_t rest_len = in_len % 3;
+ const uint8_t *stop = in + in_len - rest_len;
+ uint8_t *text = out;
+
+ // Encoding loop takes 3 bytes and creates 4 characters.
+ while (in < stop) {
+ text[0] = base64_enc[in[0] >> 2];
+ text[1] = base64_enc[(in[0] & 0x03) << 4 | in[1] >> 4];
+ text[2] = base64_enc[(in[1] & 0x0F) << 2 | in[2] >> 6];
+ text[3] = base64_enc[in[2] & 0x3F];
+ text += 4;
+ in += 3;
+ }
+
+ // Processing of padding, if any.
+ switch (rest_len) {
+ case 2:
+ text[0] = base64_enc[in[0] >> 2];
+ text[1] = base64_enc[(in[0] & 0x03) << 4 | in[1] >> 4];
+ text[2] = base64_enc[(in[1] & 0x0F) << 2];
+ text[3] = base64_pad;
+ text += 4;
+ break;
+ case 1:
+ text[0] = base64_enc[in[0] >> 2];
+ text[1] = base64_enc[(in[0] & 0x03) << 4];
+ text[2] = base64_pad;
+ text[3] = base64_pad;
+ text += 4;
+ break;
+ }
+
+ return (text - out);
+}
+
+int32_t kr_base64_encode_alloc(const uint8_t *in,
+ const uint32_t in_len,
+ uint8_t **out)
+{
+ // Checking inputs.
+ if (out == NULL) {
+ return KNOT_EINVAL;
+ }
+ if (in_len > MAX_BIN_DATA_LEN) {
+ return KNOT_ERANGE;
+ }
+
+ // Compute output buffer length.
+ uint32_t out_len = ((in_len + 2) / 3) * 4;
+
+ // Allocate output buffer.
+ *out = malloc(out_len);
+ if (*out == NULL) {
+ return KNOT_ENOMEM;
+ }
+
+ // Encode data.
+ int32_t ret = kr_base64_encode(in, in_len, *out, out_len);
+ if (ret < 0) {
+ free(*out);
+ *out = NULL;
+ }
+
+ return ret;
+}
+
+int32_t kr_base64_decode(const uint8_t *in,
+ const uint32_t in_len,
+ uint8_t *out,
+ const uint32_t out_len)
+{
+ // Checking inputs.
+ if (in == NULL || out == NULL) {
+ return KNOT_EINVAL;
+ }
+ if (in_len > INT32_MAX || out_len < ((in_len + 3) / 4) * 3) {
+ return KNOT_ERANGE;
+ }
+ if ((in_len % 4) != 0) {
+ return KNOT_BASE64_ESIZE;
+ }
+
+ const uint8_t *stop = in + in_len;
+ uint8_t *bin = out;
+ uint8_t pad_len = 0;
+ uint8_t c1, c2, c3, c4;
+
+ // Decoding loop takes 4 characters and creates 3 bytes.
+ while (in < stop) {
+ // Filling and transforming 4 Base64 chars.
+ c1 = base64_dec[in[0]];
+ c2 = base64_dec[in[1]];
+ c3 = base64_dec[in[2]];
+ c4 = base64_dec[in[3]];
+
+ // Check 4. char if is bad or padding.
+ if (c4 >= PD) {
+ if (c4 == PD && pad_len == 0) {
+ pad_len = 1;
+ } else {
+ return KNOT_BASE64_ECHAR;
+ }
+ }
+
+ // Check 3. char if is bad or padding.
+ if (c3 >= PD) {
+ if (c3 == PD && pad_len == 1) {
+ pad_len = 2;
+ } else {
+ return KNOT_BASE64_ECHAR;
+ }
+ }
+
+ // Check 1. and 2. chars if are not padding.
+ if (c2 >= PD || c1 >= PD) {
+ return KNOT_BASE64_ECHAR;
+ }
+
+ // Computing of output data based on padding length.
+ switch (pad_len) {
+ case 0:
+ bin[2] = (c3 << 6) + c4;
+ // FALLTHROUGH
+ case 1:
+ bin[1] = (c2 << 4) + (c3 >> 2);
+ // FALLTHROUGH
+ case 2:
+ bin[0] = (c1 << 2) + (c2 >> 4);
+ }
+
+ // Update output end.
+ switch (pad_len) {
+ case 0:
+ bin += 3;
+ break;
+ case 1:
+ bin += 2;
+ break;
+ case 2:
+ bin += 1;
+ break;
+ }
+
+ in += 4;
+ }
+
+ return (bin - out);
+}
+
+int32_t kr_base64_decode_alloc(const uint8_t *in,
+ const uint32_t in_len,
+ uint8_t **out)
+{
+ // Checking inputs.
+ if (out == NULL) {
+ return KNOT_EINVAL;
+ }
+
+ // Compute output buffer length.
+ uint32_t out_len = ((in_len + 3) / 4) * 3;
+
+ // Allocate output buffer.
+ *out = malloc(out_len);
+ if (*out == NULL) {
+ return KNOT_ENOMEM;
+ }
+
+ // Decode data.
+ int32_t ret = kr_base64_decode(in, in_len, *out, out_len);
+ if (ret < 0) {
+ free(*out);
+ *out = NULL;
+ }
+
+ return ret;
+}
diff --git a/contrib/base64.h b/contrib/base64.h
new file mode 100644
index 0000000..153aa72
--- /dev/null
+++ b/contrib/base64.h
@@ -0,0 +1,95 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+/*!
+ * \file
+ *
+ * \brief Base64 implementation (RFC 4648).
+ *
+ * \addtogroup contrib
+ * @{
+ */
+
+#pragma once
+
+#include <stdint.h>
+
+/*!
+ * \brief Encodes binary data using Base64.
+ *
+ * \note Output data buffer contains Base64 text string which isn't
+ * terminated with '\0'!
+ *
+ * \param in Input binary data.
+ * \param in_len Length of input data.
+ * \param out Output data buffer.
+ * \param out_len Size of output buffer.
+ *
+ * \retval >=0 length of output string.
+ * \retval KNOT_E* if error.
+ */
+int32_t kr_base64_encode(const uint8_t *in,
+ const uint32_t in_len,
+ uint8_t *out,
+ const uint32_t out_len);
+
+/*!
+ * \brief Encodes binary data using Base64 and output stores to own buffer.
+ *
+ * \note Output data buffer contains Base64 text string which isn't
+ * terminated with '\0'!
+ *
+ * \note Output buffer should be deallocated after use.
+ *
+ * \param in Input binary data.
+ * \param in_len Length of input data.
+ * \param out Output data buffer.
+ *
+ * \retval >=0 length of output string.
+ * \retval KNOT_E* if error.
+ */
+int32_t kr_base64_encode_alloc(const uint8_t *in,
+ const uint32_t in_len,
+ uint8_t **out);
+
+/*!
+ * \brief Decodes text data using Base64.
+ *
+ * \note Input data needn't be terminated with '\0'.
+ *
+ * \note Input data must be continuous Base64 string!
+ *
+ * \param in Input text data.
+ * \param in_len Length of input string.
+ * \param out Output data buffer.
+ * \param out_len Size of output buffer.
+ *
+ * \retval >=0 length of output data.
+ * \retval KNOT_E* if error.
+ */
+int32_t kr_base64_decode(const uint8_t *in,
+ const uint32_t in_len,
+ uint8_t *out,
+ const uint32_t out_len);
+
+/*!
+ * \brief Decodes text data using Base64 and output stores to own buffer.
+ *
+ * \note Input data needn't be terminated with '\0'.
+ *
+ * \note Input data must be continuous Base64 string!
+ *
+ * \note Output buffer should be deallocated after use.
+ *
+ * \param in Input text data.
+ * \param in_len Length of input string.
+ * \param out Output data buffer.
+ *
+ * \retval >=0 length of output data.
+ * \retval KNOT_E* if error.
+ */
+int32_t kr_base64_decode_alloc(const uint8_t *in,
+ const uint32_t in_len,
+ uint8_t **out);
+
+/*! @} */
diff --git a/contrib/base64.spdx b/contrib/base64.spdx
new file mode 100644
index 0000000..15ce10d
--- /dev/null
+++ b/contrib/base64.spdx
@@ -0,0 +1,10 @@
+SPDXVersion: SPDX-2.1
+DataLicense: CC0-1.0
+SPDXID: SPDXRef-DOCUMENT
+DocumentName: knotdns-base64
+DocumentNamespace: http://spdx.org/spdxdocs/spdx-v2.1-669dfa8c-3b50-425f-92fc-9b7ce18999f2
+
+PackageName: knotdns-base64
+PackageDownloadLocation: git+https://gitlab.nic.cz/knot/knot-dns.git@2b3c828a4cb8d9595318552483d4947345426c30#src/libknot/internal/base64.c
+PackageOriginator: Organization: Knot DNS contributors
+PackageLicenseDeclared: GPL-3.0-or-later
diff --git a/contrib/base64url.c b/contrib/base64url.c
new file mode 100644
index 0000000..b7c7d2b
--- /dev/null
+++ b/contrib/base64url.c
@@ -0,0 +1,287 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include "contrib/base64url.h"
+#include "libknot/errcode.h"
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <ctype.h>
+
+/*! \brief Maximal length of binary input to Base64url encoding. */
+#define MAX_BIN_DATA_LEN ((INT32_MAX / 4) * 3)
+
+/*! \brief Base64url padding character. */
+static const uint8_t base64url_pad = '\0';
+/*! \brief Base64 alphabet. */
+static const uint8_t base64url_enc[] =
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
+
+/*! \brief Indicates bad Base64 character. */
+#define KO 255
+/*! \brief Indicates Base64 padding character. */
+#define PD 64
+
+/*! \brief Transformation and validation table for decoding Base64. */
+static const uint8_t base64url_dec[256] = {
+ [ 0] = PD, [ 43] = KO, ['V'] = 21, [129] = KO, [172] = KO, [215] = KO,
+ [ 1] = KO, [ 44] = KO, ['W'] = 22, [130] = KO, [173] = KO, [216] = KO,
+ [ 2] = KO, ['-'] = 62, ['X'] = 23, [131] = KO, [174] = KO, [217] = KO,
+ [ 3] = KO, [ 46] = KO, ['Y'] = 24, [132] = KO, [175] = KO, [218] = KO,
+ [ 4] = KO, [ 47] = KO, ['Z'] = 25, [133] = KO, [176] = KO, [219] = KO,
+ [ 5] = KO, ['0'] = 52, [ 91] = KO, [134] = KO, [177] = KO, [220] = KO,
+ [ 6] = KO, ['1'] = 53, [ 92] = KO, [135] = KO, [178] = KO, [221] = KO,
+ [ 7] = KO, ['2'] = 54, [ 93] = KO, [136] = KO, [179] = KO, [222] = KO,
+ [ 8] = KO, ['3'] = 55, [ 94] = KO, [137] = KO, [180] = KO, [223] = KO,
+ [ 9] = KO, ['4'] = 56, ['_'] = 63, [138] = KO, [181] = KO, [224] = KO,
+ [ 10] = KO, ['5'] = 57, [ 96] = KO, [139] = KO, [182] = KO, [225] = KO,
+ [ 11] = KO, ['6'] = 58, ['a'] = 26, [140] = KO, [183] = KO, [226] = KO,
+ [ 12] = KO, ['7'] = 59, ['b'] = 27, [141] = KO, [184] = KO, [227] = KO,
+ [ 13] = KO, ['8'] = 60, ['c'] = 28, [142] = KO, [185] = KO, [228] = KO,
+ [ 14] = KO, ['9'] = 61, ['d'] = 29, [143] = KO, [186] = KO, [229] = KO,
+ [ 15] = KO, [ 58] = KO, ['e'] = 30, [144] = KO, [187] = KO, [230] = KO,
+ [ 16] = KO, [ 59] = KO, ['f'] = 31, [145] = KO, [188] = KO, [231] = KO,
+ [ 17] = KO, [ 60] = KO, ['g'] = 32, [146] = KO, [189] = KO, [232] = KO,
+ [ 18] = KO, [ 61] = KO, ['h'] = 33, [147] = KO, [190] = KO, [233] = KO,
+ [ 19] = KO, [ 62] = KO, ['i'] = 34, [148] = KO, [191] = KO, [234] = KO,
+ [ 20] = KO, [ 63] = KO, ['j'] = 35, [149] = KO, [192] = KO, [235] = KO,
+ [ 21] = KO, [ 64] = KO, ['k'] = 36, [150] = KO, [193] = KO, [236] = KO,
+ [ 22] = KO, ['A'] = 0, ['l'] = 37, [151] = KO, [194] = KO, [237] = KO,
+ [ 23] = KO, ['B'] = 1, ['m'] = 38, [152] = KO, [195] = KO, [238] = KO,
+ [ 24] = KO, ['C'] = 2, ['n'] = 39, [153] = KO, [196] = KO, [239] = KO,
+ [ 25] = KO, ['D'] = 3, ['o'] = 40, [154] = KO, [197] = KO, [240] = KO,
+ [ 26] = KO, ['E'] = 4, ['p'] = 41, [155] = KO, [198] = KO, [241] = KO,
+ [ 27] = KO, ['F'] = 5, ['q'] = 42, [156] = KO, [199] = KO, [242] = KO,
+ [ 28] = KO, ['G'] = 6, ['r'] = 43, [157] = KO, [200] = KO, [243] = KO,
+ [ 29] = KO, ['H'] = 7, ['s'] = 44, [158] = KO, [201] = KO, [244] = KO,
+ [ 30] = KO, ['I'] = 8, ['t'] = 45, [159] = KO, [202] = KO, [245] = KO,
+ [ 31] = KO, ['J'] = 9, ['u'] = 46, [160] = KO, [203] = KO, [246] = KO,
+ [ 32] = KO, ['K'] = 10, ['v'] = 47, [161] = KO, [204] = KO, [247] = KO,
+ [ 33] = KO, ['L'] = 11, ['w'] = 48, [162] = KO, [205] = KO, [248] = KO,
+ [ 34] = KO, ['M'] = 12, ['x'] = 49, [163] = KO, [206] = KO, [249] = KO,
+ [ 35] = KO, ['N'] = 13, ['y'] = 50, [164] = KO, [207] = KO, [250] = KO,
+ [ 36] = KO, ['O'] = 14, ['z'] = 51, [165] = KO, [208] = KO, [251] = KO,
+ ['%'] = KO, ['P'] = 15, [123] = KO, [166] = KO, [209] = KO, [252] = KO,
+ [ 38] = KO, ['Q'] = 16, [124] = KO, [167] = KO, [210] = KO, [253] = KO,
+ [ 39] = KO, ['R'] = 17, [125] = KO, [168] = KO, [211] = KO, [254] = KO,
+ [ 40] = KO, ['S'] = 18, [126] = KO, [169] = KO, [212] = KO, [255] = KO,
+ [ 41] = KO, ['T'] = 19, [127] = KO, [170] = KO, [213] = KO,
+ [ 42] = KO, ['U'] = 20, [128] = KO, [171] = KO, [214] = KO,
+};
+
+int32_t kr_base64url_encode(const uint8_t *in,
+ const uint32_t in_len,
+ uint8_t *out,
+ const uint32_t out_len)
+{
+ // Checking inputs.
+ if (in == NULL || out == NULL) {
+ return KNOT_EINVAL;
+ }
+ if (in_len > MAX_BIN_DATA_LEN || out_len < ((in_len + 2) / 3) * 4) {
+ return KNOT_ERANGE;
+ }
+
+ uint8_t rest_len = in_len % 3;
+ const uint8_t *stop = in + in_len - rest_len;
+ uint8_t *text = out;
+
+ // Encoding loop takes 3 bytes and creates 4 characters.
+ while (in < stop) {
+ text[0] = base64url_enc[in[0] >> 2];
+ text[1] = base64url_enc[(in[0] & 0x03) << 4 | in[1] >> 4];
+ text[2] = base64url_enc[(in[1] & 0x0F) << 2 | in[2] >> 6];
+ text[3] = base64url_enc[in[2] & 0x3F];
+ text += 4;
+ in += 3;
+ }
+
+ // Processing of padding, if any.
+ switch (rest_len) {
+ case 2:
+ text[0] = base64url_enc[in[0] >> 2];
+ text[1] = base64url_enc[(in[0] & 0x03) << 4 | in[1] >> 4];
+ text[2] = base64url_enc[(in[1] & 0x0F) << 2];
+ text[3] = base64url_pad;
+ text += 3;
+ break;
+ case 1:
+ text[0] = base64url_enc[in[0] >> 2];
+ text[1] = base64url_enc[(in[0] & 0x03) << 4];
+ text[2] = base64url_pad;
+ text[3] = base64url_pad;
+ text += 2;
+ break;
+ }
+ return (text - out);
+}
+
+int32_t kr_base64url_encode_alloc(const uint8_t *in,
+ const uint32_t in_len,
+ uint8_t **out)
+{
+ // Checking inputs.
+ if (out == NULL) {
+ return KNOT_EINVAL;
+ }
+ if (in_len > MAX_BIN_DATA_LEN) {
+ return KNOT_ERANGE;
+ }
+
+ // Compute output buffer length.
+ uint32_t out_len = ((in_len + 2) / 3) * 4;
+
+ // Allocate output buffer.
+ *out = malloc(out_len);
+ if (*out == NULL) {
+ return KNOT_ENOMEM;
+ }
+
+ // Encode data.
+ int32_t ret = kr_base64url_encode(in, in_len, *out, out_len);
+ if (ret < 0) {
+ free(*out);
+ *out = NULL;
+ }
+
+ return ret;
+}
+
+int32_t kr_base64url_decode(const uint8_t *in,
+ uint32_t in_len,
+ uint8_t *out,
+ const uint32_t out_len)
+{
+ // Checking inputs.
+ if (in == NULL || out == NULL) {
+ return KNOT_EINVAL;
+ }
+
+ // cut up to two "%3d" from the end of input
+ int pad3d = 0;
+ const uint8_t *end = in + in_len;
+ char *perc3d = "d3%d3%", *stop3d = perc3d + 6;
+ while (end != in && perc3d != stop3d && tolower(*--end) == *perc3d) {
+ if (*perc3d++ == '%') {
+ in_len -= 3;
+ pad3d++;
+ }
+ }
+
+ if (in_len > INT32_MAX || out_len < ((in_len + 3) / 4) * 3) {
+ return KNOT_ERANGE;
+ }
+
+ const uint8_t *stop = in + in_len;
+ uint8_t *bin = out;
+ uint8_t pad_len = 0;
+ uint8_t c1, c2, c3, c4;
+
+ // Decoding loop takes 4 characters and creates 3 bytes.
+ while (in < stop) {
+ // Filling and transforming 4 Base64 chars.
+ c1 = base64url_dec[in[0]] ;
+ c2 = base64url_dec[in[1]] ;
+ c3 = (in + 2 < stop) ? base64url_dec[in[2]] : PD;
+ c4 = (in + 3 < stop) ? base64url_dec[in[3]] : PD;
+
+ // Check 1. and 2. chars if are not padding
+ if (c1 >= PD || c2 >= PD) {
+ return KNOT_BASE64_ECHAR;
+ }
+ // Check 3. char if is bad or padding.
+ else if (c3 >= PD) {
+ if (c3 == PD) {
+ pad_len = 2;
+ } else {
+ return KNOT_BASE64_ECHAR;
+ }
+ }
+ // Check 3. char if is bad or padding.
+ else if (c4 >= PD) {
+ if (c4 == PD) {
+ pad_len = 1;
+ } else {
+ return KNOT_BASE64_ECHAR;
+ }
+ }
+
+ if (pad_len > 0 && in <= stop - 4) {
+ return KNOT_BASE64_ECHAR;
+ }
+
+ // Computing of output data based on padding length.
+ switch (pad_len) {
+ case 0:
+ bin[2] = (c3 << 6) + c4;
+ // FALLTHROUGH
+ case 1:
+ bin[1] = (c2 << 4) + (c3 >> 2);
+ // FALLTHROUGH
+ case 2:
+ bin[0] = (c1 << 2) + (c2 >> 4);
+ }
+
+ // Update output end.
+ switch (pad_len) {
+ case 0:
+ bin += 3;
+ break;
+ case 1:
+ bin += 2;
+ goto end;
+ case 2:
+ bin += 1;
+ goto end;
+ }
+
+ in += 4;
+ }
+
+end:
+ if (pad3d > pad_len) {
+ return KNOT_BASE64_ECHAR;
+ }
+ return (bin - out);
+}
+
+int32_t kr_base64url_decode_alloc(const uint8_t *in,
+ const uint32_t in_len,
+ uint8_t **out)
+{
+ // Checking inputs.
+ if (out == NULL) {
+ return KNOT_EINVAL;
+ }
+
+ // Compute output buffer length.
+ uint32_t out_len = ((in_len + 3) / 4) * 3;
+
+ // Allocate output buffer.
+ *out = malloc(out_len);
+ if (*out == NULL) {
+ return KNOT_ENOMEM;
+ }
+
+ // Decode data.
+ int32_t ret = kr_base64url_decode(in, in_len, *out, out_len);
+ if (ret < 0) {
+ free(*out);
+ *out = NULL;
+ }
+
+ return ret;
+}
diff --git a/contrib/base64url.h b/contrib/base64url.h
new file mode 100644
index 0000000..ad7c6e9
--- /dev/null
+++ b/contrib/base64url.h
@@ -0,0 +1,103 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+/*!
+ * \brief Base64url implementation (RFC 4648).
+ */
+
+#pragma once
+
+#include <stdint.h>
+
+/*!
+ * \brief Encodes binary data using Base64.
+ *
+ * \note Output data buffer contains Base64 text string which isn't
+ * terminated with '\0'!
+ *
+ * \param in Input binary data.
+ * \param in_len Length of input data.
+ * \param out Output data buffer.
+ * \param out_len Size of output buffer.
+ *
+ * \retval >=0 length of output string.
+ * \retval KNOT_E* if error.
+ */
+int32_t kr_base64url_encode(const uint8_t *in,
+ const uint32_t in_len,
+ uint8_t *out,
+ const uint32_t out_len);
+
+/*!
+ * \brief Encodes binary data using Base64 and output stores to own buffer.
+ *
+ * \note Output data buffer contains Base64 text string which isn't
+ * terminated with '\0'!
+ *
+ * \note Output buffer should be deallocated after use.
+ *
+ * \param in Input binary data.
+ * \param in_len Length of input data.
+ * \param out Output data buffer.
+ *
+ * \retval >=0 length of output string.
+ * \retval KNOT_E* if error.
+ */
+int32_t kr_base64url_encode_alloc(const uint8_t *in,
+ const uint32_t in_len,
+ uint8_t **out);
+
+/*!
+ * \brief Decodes text data using Base64.
+ *
+ * \note Input data needn't be terminated with '\0'.
+ *
+ * \note Input data must be continuous Base64 string!
+ *
+ * \param in Input text data.
+ * \param in_len Length of input string.
+ * \param out Output data buffer.
+ * \param out_len Size of output buffer.
+ *
+ * \retval >=0 length of output data.
+ * \retval KNOT_E* if error.
+ */
+int32_t kr_base64url_decode(const uint8_t *in,
+ uint32_t in_len,
+ uint8_t *out,
+ const uint32_t out_len);
+
+/*!
+ * \brief Decodes text data using Base64 and output stores to own buffer.
+ *
+ * \note Input data needn't be terminated with '\0'.
+ *
+ * \note Input data must be continuous Base64 string!
+ *
+ * \note Output buffer should be deallocated after use.
+ *
+ * \param in Input text data.
+ * \param in_len Length of input string.
+ * \param out Output data buffer.
+ *
+ * \retval >=0 length of output data.
+ * \retval KNOT_E* if error.
+ */
+int32_t kr_base64url_decode_alloc(const uint8_t *in,
+ const uint32_t in_len,
+ uint8_t **out);
+
+/*! @} */
diff --git a/contrib/ccan/asprintf/LICENSE b/contrib/ccan/asprintf/LICENSE
new file mode 120000
index 0000000..2354d12
--- /dev/null
+++ b/contrib/ccan/asprintf/LICENSE
@@ -0,0 +1 @@
+../../licenses/BSD-MIT \ No newline at end of file
diff --git a/contrib/ccan/asprintf/asprintf.c b/contrib/ccan/asprintf/asprintf.c
new file mode 100644
index 0000000..4077599
--- /dev/null
+++ b/contrib/ccan/asprintf/asprintf.c
@@ -0,0 +1,57 @@
+/* SPDX-License-Identifier: MIT
+ * Source: https://ccodearchive.net/info/asprintf.html */
+#include <ccan/asprintf/asprintf.h>
+#include <stdarg.h>
+#include <stdio.h>
+
+char *PRINTF_FMT(1, 2) afmt(const char *fmt, ...)
+{
+ va_list ap;
+ char *ptr;
+
+ va_start(ap, fmt);
+ /* The BSD version apparently sets ptr to NULL on fail. GNU loses. */
+ if (vasprintf(&ptr, fmt, ap) < 0)
+ ptr = NULL;
+ va_end(ap);
+ return ptr;
+}
+
+#if !HAVE_ASPRINTF
+#include <stdarg.h>
+#include <stdlib.h>
+
+int vasprintf(char **strp, const char *fmt, va_list ap)
+{
+ int len;
+ va_list ap_copy;
+
+ /* We need to make a copy of ap, since it's a use-once. */
+ va_copy(ap_copy, ap);
+ len = vsnprintf(NULL, 0, fmt, ap_copy);
+ va_end(ap_copy);
+
+ /* Until version 2.0.6 glibc would return -1 on truncated output.
+ * OTOH, they had asprintf. */
+ if (len < 0)
+ return -1;
+
+ *strp = malloc(len+1);
+ if (!*strp)
+ return -1;
+
+ return vsprintf(*strp, fmt, ap);
+}
+
+int asprintf(char **strp, const char *fmt, ...)
+{
+ va_list ap;
+ int len;
+
+ va_start(ap, fmt);
+ len = vasprintf(strp, fmt, ap);
+ va_end(ap);
+
+ return len;
+}
+#endif /* !HAVE_ASPRINTF */
diff --git a/contrib/ccan/asprintf/asprintf.h b/contrib/ccan/asprintf/asprintf.h
new file mode 100644
index 0000000..d4cc5ca
--- /dev/null
+++ b/contrib/ccan/asprintf/asprintf.h
@@ -0,0 +1,51 @@
+/* SPDX-License-Identifier: MIT
+ * Source: https://ccodearchive.net/info/asprintf.html */
+#ifndef CCAN_ASPRINTF_H
+#define CCAN_ASPRINTF_H
+#include "config.h"
+#include <ccan/compiler/compiler.h>
+
+/**
+ * afmt - allocate and populate a string with the given format.
+ * @fmt: printf-style format.
+ *
+ * This is a simplified asprintf interface. Returns NULL on error.
+ */
+char *PRINTF_FMT(1, 2) afmt(const char *fmt, ...);
+
+#if HAVE_ASPRINTF
+#include <stdio.h>
+#else
+#include <stdarg.h>
+/**
+ * asprintf - printf to a dynamically-allocated string.
+ * @strp: pointer to the string to allocate.
+ * @fmt: printf-style format.
+ *
+ * Returns -1 (and leaves @strp undefined) on an error. Otherwise returns
+ * number of bytes printed into @strp.
+ *
+ * Example:
+ * static char *greeting(const char *name)
+ * {
+ * char *str;
+ * int len = asprintf(&str, "Hello %s", name);
+ * if (len < 0)
+ * return NULL;
+ * return str;
+ * }
+ */
+int PRINTF_FMT(2, 3) asprintf(char **strp, const char *fmt, ...);
+
+/**
+ * vasprintf - vprintf to a dynamically-allocated string.
+ * @strp: pointer to the string to allocate.
+ * @fmt: printf-style format.
+ *
+ * Returns -1 (and leaves @strp undefined) on an error. Otherwise returns
+ * number of bytes printed into @strp.
+ */
+int vasprintf(char **strp, const char *fmt, va_list ap);
+#endif
+
+#endif /* CCAN_ASPRINTF_H */
diff --git a/contrib/ccan/asprintf/asprintf.spdx b/contrib/ccan/asprintf/asprintf.spdx
new file mode 100644
index 0000000..175078a
--- /dev/null
+++ b/contrib/ccan/asprintf/asprintf.spdx
@@ -0,0 +1,10 @@
+SPDXVersion: SPDX-2.1
+DataLicense: CC0-1.0
+SPDXID: SPDXRef-DOCUMENT
+DocumentName: ccan-asprintf
+DocumentNamespace: http://spdx.org/spdxdocs/spdx-v2.1-40d4b71d-00e9-4e75-b6da-559203e6b815
+
+PackageName: asprintf
+PackageDownloadLocation: git+https://github.com/rustyrussell/ccan@fb1dfd092940905883ea6473162f5f6e36624da2#ccan/asprintf
+PackageOriginator: Person: Rusty Russell (rusty@rustcorp.com.au)
+PackageLicenseDeclared: MIT
diff --git a/contrib/ccan/compiler/LICENSE b/contrib/ccan/compiler/LICENSE
new file mode 120000
index 0000000..b7951da
--- /dev/null
+++ b/contrib/ccan/compiler/LICENSE
@@ -0,0 +1 @@
+../../licenses/CC0 \ No newline at end of file
diff --git a/contrib/ccan/compiler/compiler.h b/contrib/ccan/compiler/compiler.h
new file mode 100644
index 0000000..7c4f955
--- /dev/null
+++ b/contrib/ccan/compiler/compiler.h
@@ -0,0 +1,232 @@
+/* SPDX-License-Identifier: CC0-1.0
+ * Source: https://ccodearchive.net/info/compiler.html */
+#ifndef CCAN_COMPILER_H
+#define CCAN_COMPILER_H
+#include "config.h"
+
+#ifndef COLD
+#if HAVE_ATTRIBUTE_COLD
+/**
+ * COLD - a function is unlikely to be called.
+ *
+ * Used to mark an unlikely code path and optimize appropriately.
+ * It is usually used on logging or error routines.
+ *
+ * Example:
+ * static void COLD moan(const char *reason)
+ * {
+ * fprintf(stderr, "Error: %s (%s)\n", reason, strerror(errno));
+ * }
+ */
+#define COLD __attribute__((__cold__))
+#else
+#define COLD
+#endif
+#endif
+
+#ifndef NORETURN
+#if HAVE_ATTRIBUTE_NORETURN
+/**
+ * NORETURN - a function does not return
+ *
+ * Used to mark a function which exits; useful for suppressing warnings.
+ *
+ * Example:
+ * static void NORETURN fail(const char *reason)
+ * {
+ * fprintf(stderr, "Error: %s (%s)\n", reason, strerror(errno));
+ * exit(1);
+ * }
+ */
+#define NORETURN __attribute__((__noreturn__))
+#else
+#define NORETURN
+#endif
+#endif
+
+#ifndef PRINTF_FMT
+#if HAVE_ATTRIBUTE_PRINTF
+/**
+ * PRINTF_FMT - a function takes printf-style arguments
+ * @nfmt: the 1-based number of the function's format argument.
+ * @narg: the 1-based number of the function's first variable argument.
+ *
+ * This allows the compiler to check your parameters as it does for printf().
+ *
+ * Example:
+ * void PRINTF_FMT(2,3) my_printf(const char *prefix, const char *fmt, ...);
+ */
+#define PRINTF_FMT(nfmt, narg) \
+ __attribute__((format(__printf__, nfmt, narg)))
+#else
+#define PRINTF_FMT(nfmt, narg)
+#endif
+#endif
+
+#ifndef CONST_FUNCTION
+#if HAVE_ATTRIBUTE_CONST
+/**
+ * CONST_FUNCTION - a function's return depends only on its argument
+ *
+ * This allows the compiler to assume that the function will return the exact
+ * same value for the exact same arguments. This implies that the function
+ * must not use global variables, or dereference pointer arguments.
+ */
+#define CONST_FUNCTION __attribute__((__const__))
+#else
+#define CONST_FUNCTION
+#endif
+
+#ifndef PURE_FUNCTION
+#if HAVE_ATTRIBUTE_PURE
+/**
+ * PURE_FUNCTION - a function is pure
+ *
+ * A pure function is one that has no side effects other than it's return value
+ * and uses no inputs other than it's arguments and global variables.
+ */
+#define PURE_FUNCTION __attribute__((__pure__))
+#else
+#define PURE_FUNCTION
+#endif
+#endif
+#endif
+
+#if HAVE_ATTRIBUTE_UNUSED
+#ifndef UNNEEDED
+/**
+ * UNNEEDED - a variable/function may not be needed
+ *
+ * This suppresses warnings about unused variables or functions, but tells
+ * the compiler that if it is unused it need not emit it into the source code.
+ *
+ * Example:
+ * // With some preprocessor options, this is unnecessary.
+ * static UNNEEDED int counter;
+ *
+ * // With some preprocessor options, this is unnecessary.
+ * static UNNEEDED void add_to_counter(int add)
+ * {
+ * counter += add;
+ * }
+ */
+#define UNNEEDED __attribute__((__unused__))
+#endif
+
+#ifndef NEEDED
+#if HAVE_ATTRIBUTE_USED
+/**
+ * NEEDED - a variable/function is needed
+ *
+ * This suppresses warnings about unused variables or functions, but tells
+ * the compiler that it must exist even if it (seems) unused.
+ *
+ * Example:
+ * // Even if this is unused, these are vital for debugging.
+ * static NEEDED int counter;
+ * static NEEDED void dump_counter(void)
+ * {
+ * printf("Counter is %i\n", counter);
+ * }
+ */
+#define NEEDED __attribute__((__used__))
+#else
+/* Before used, unused functions and vars were always emitted. */
+#define NEEDED __attribute__((__unused__))
+#endif
+#endif
+
+#ifndef UNUSED
+/**
+ * UNUSED - a parameter is unused
+ *
+ * Some compilers (eg. gcc with -W or -Wunused) warn about unused
+ * function parameters. This suppresses such warnings and indicates
+ * to the reader that it's deliberate.
+ *
+ * Example:
+ * // This is used as a callback, so needs to have this prototype.
+ * static int some_callback(void *unused UNUSED)
+ * {
+ * return 0;
+ * }
+ */
+#define UNUSED __attribute__((__unused__))
+#endif
+#else
+#ifndef UNNEEDED
+#define UNNEEDED
+#endif
+#ifndef NEEDED
+#define NEEDED
+#endif
+#ifndef UNUSED
+#define UNUSED
+#endif
+#endif
+
+#ifndef IS_COMPILE_CONSTANT
+#if HAVE_BUILTIN_CONSTANT_P
+/**
+ * IS_COMPILE_CONSTANT - does the compiler know the value of this expression?
+ * @expr: the expression to evaluate
+ *
+ * When an expression manipulation is complicated, it is usually better to
+ * implement it in a function. However, if the expression being manipulated is
+ * known at compile time, it is better to have the compiler see the entire
+ * expression so it can simply substitute the result.
+ *
+ * This can be done using the IS_COMPILE_CONSTANT() macro.
+ *
+ * Example:
+ * enum greek { ALPHA, BETA, GAMMA, DELTA, EPSILON };
+ *
+ * // Out-of-line version.
+ * const char *greek_name(enum greek greek);
+ *
+ * // Inline version.
+ * static inline const char *_greek_name(enum greek greek)
+ * {
+ * switch (greek) {
+ * case ALPHA: return "alpha";
+ * case BETA: return "beta";
+ * case GAMMA: return "gamma";
+ * case DELTA: return "delta";
+ * case EPSILON: return "epsilon";
+ * default: return "**INVALID**";
+ * }
+ * }
+ *
+ * // Use inline if compiler knows answer. Otherwise call function
+ * // to avoid copies of the same code everywhere.
+ * #define greek_name(g) \
+ * (IS_COMPILE_CONSTANT(greek) ? _greek_name(g) : greek_name(g))
+ */
+#define IS_COMPILE_CONSTANT(expr) __builtin_constant_p(expr)
+#else
+/* If we don't know, assume it's not. */
+#define IS_COMPILE_CONSTANT(expr) 0
+#endif
+#endif
+
+#ifndef WARN_UNUSED_RESULT
+#if HAVE_WARN_UNUSED_RESULT
+/**
+ * WARN_UNUSED_RESULT - warn if a function return value is unused.
+ *
+ * Used to mark a function where it is extremely unlikely that the caller
+ * can ignore the result, eg realloc().
+ *
+ * Example:
+ * // buf param may be freed by this; need return value!
+ * static char *WARN_UNUSED_RESULT enlarge(char *buf, unsigned *size)
+ * {
+ * return realloc(buf, (*size) *= 2);
+ * }
+ */
+#define WARN_UNUSED_RESULT __attribute__((__warn_unused_result__))
+#else
+#define WARN_UNUSED_RESULT
+#endif
+#endif
+#endif /* CCAN_COMPILER_H */
diff --git a/contrib/ccan/compiler/compiler.spdx b/contrib/ccan/compiler/compiler.spdx
new file mode 100644
index 0000000..45f19f4
--- /dev/null
+++ b/contrib/ccan/compiler/compiler.spdx
@@ -0,0 +1,10 @@
+SPDXVersion: SPDX-2.1
+DataLicense: CC0-1.0
+SPDXID: SPDXRef-DOCUMENT
+DocumentName: ccan-compiler
+DocumentNamespace: http://spdx.org/spdxdocs/spdx-v2.1-1569e849-880d-4ce7-ba3e-f4aaec8fce52
+
+PackageName: compiler
+PackageDownloadLocation: git+https://github.com/rustyrussell/ccan@23e96f89d54b8d5c4675284bbcd44fba68d8f826#ccan/compiler
+PackageOriginator: Person: Rusty Russell (rusty@rustcorp.com.au)
+PackageLicenseDeclared: CC0-1.0
diff --git a/contrib/ccan/json/LICENSE b/contrib/ccan/json/LICENSE
new file mode 120000
index 0000000..2354d12
--- /dev/null
+++ b/contrib/ccan/json/LICENSE
@@ -0,0 +1 @@
+../../licenses/BSD-MIT \ No newline at end of file
diff --git a/contrib/ccan/json/json.c b/contrib/ccan/json/json.c
new file mode 100644
index 0000000..a86c4db
--- /dev/null
+++ b/contrib/ccan/json/json.c
@@ -0,0 +1,1362 @@
+/* SPDX-License-Identifier: MIT
+ * Source: https://ccodearchive.net/info/json.html
+ * Copyright (C) 2011 Joseph A. Adams (joeyadams3.14159@gmail.com) */
+
+#include "json.h"
+
+#include <assert.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define out_of_memory() do { \
+ fprintf(stderr, "Out of memory.\n"); \
+ exit(EXIT_FAILURE); \
+ } while (0)
+
+/* Sadly, strdup is not portable. */
+static char *json_strdup(const char *str)
+{
+ char *ret = (char*) malloc(strlen(str) + 1);
+ if (ret == NULL)
+ out_of_memory();
+ strcpy(ret, str);
+ return ret;
+}
+
+/* String buffer */
+
+typedef struct
+{
+ char *cur;
+ char *end;
+ char *start;
+} SB;
+
+static void sb_init(SB *sb)
+{
+ sb->start = (char*) malloc(17);
+ if (sb->start == NULL)
+ out_of_memory();
+ sb->cur = sb->start;
+ sb->end = sb->start + 16;
+}
+
+/* sb and need may be evaluated multiple times. */
+#define sb_need(sb, need) do { \
+ if ((sb)->end - (sb)->cur < (need)) \
+ sb_grow(sb, need); \
+ } while (0)
+
+static void sb_grow(SB *sb, int need)
+{
+ size_t length = sb->cur - sb->start;
+ size_t alloc = sb->end - sb->start;
+
+ do {
+ alloc *= 2;
+ } while (alloc < length + need);
+
+ sb->start = (char*) realloc(sb->start, alloc + 1);
+ if (sb->start == NULL)
+ out_of_memory();
+ sb->cur = sb->start + length;
+ sb->end = sb->start + alloc;
+}
+
+static void sb_put(SB *sb, const char *bytes, int count)
+{
+ sb_need(sb, count);
+ memcpy(sb->cur, bytes, count);
+ sb->cur += count;
+}
+
+#define sb_putc(sb, c) do { \
+ if ((sb)->cur >= (sb)->end) \
+ sb_grow(sb, 1); \
+ *(sb)->cur++ = (c); \
+ } while (0)
+
+static void sb_puts(SB *sb, const char *str)
+{
+ sb_put(sb, str, strlen(str));
+}
+
+static char *sb_finish(SB *sb)
+{
+ *sb->cur = 0;
+ assert(sb->start <= sb->cur && strlen(sb->start) == (size_t)(sb->cur - sb->start));
+ return sb->start;
+}
+
+static void sb_free(SB *sb)
+{
+ free(sb->start);
+}
+
+/*
+ * Unicode helper functions
+ *
+ * These are taken from the ccan/charset module and customized a bit.
+ * Putting them here means the compiler can (choose to) inline them,
+ * and it keeps ccan/json from having a dependency.
+ */
+
+/*
+ * Type for Unicode codepoints.
+ * We need our own because wchar_t might be 16 bits.
+ */
+typedef uint32_t uchar_t;
+
+/*
+ * Validate a single UTF-8 character starting at @s.
+ * The string must be null-terminated.
+ *
+ * If it's valid, return its length (1 thru 4).
+ * If it's invalid or clipped, return 0.
+ *
+ * This function implements the syntax given in RFC3629, which is
+ * the same as that given in The Unicode Standard, Version 6.0.
+ *
+ * It has the following properties:
+ *
+ * * All codepoints U+0000..U+10FFFF may be encoded,
+ * except for U+D800..U+DFFF, which are reserved
+ * for UTF-16 surrogate pair encoding.
+ * * UTF-8 byte sequences longer than 4 bytes are not permitted,
+ * as they exceed the range of Unicode.
+ * * The sixty-six Unicode "non-characters" are permitted
+ * (namely, U+FDD0..U+FDEF, U+xxFFFE, and U+xxFFFF).
+ */
+static int utf8_validate_cz(const char *s)
+{
+ unsigned char c = *s++;
+
+ if (c <= 0x7F) { /* 00..7F */
+ return 1;
+ } else if (c <= 0xC1) { /* 80..C1 */
+ /* Disallow overlong 2-byte sequence. */
+ return 0;
+ } else if (c <= 0xDF) { /* C2..DF */
+ /* Make sure subsequent byte is in the range 0x80..0xBF. */
+ if (((unsigned char)*s++ & 0xC0) != 0x80)
+ return 0;
+
+ return 2;
+ } else if (c <= 0xEF) { /* E0..EF */
+ /* Disallow overlong 3-byte sequence. */
+ if (c == 0xE0 && (unsigned char)*s < 0xA0)
+ return 0;
+
+ /* Disallow U+D800..U+DFFF. */
+ if (c == 0xED && (unsigned char)*s > 0x9F)
+ return 0;
+
+ /* Make sure subsequent bytes are in the range 0x80..0xBF. */
+ if (((unsigned char)*s++ & 0xC0) != 0x80)
+ return 0;
+ if (((unsigned char)*s++ & 0xC0) != 0x80)
+ return 0;
+
+ return 3;
+ } else if (c <= 0xF4) { /* F0..F4 */
+ /* Disallow overlong 4-byte sequence. */
+ if (c == 0xF0 && (unsigned char)*s < 0x90)
+ return 0;
+
+ /* Disallow codepoints beyond U+10FFFF. */
+ if (c == 0xF4 && (unsigned char)*s > 0x8F)
+ return 0;
+
+ /* Make sure subsequent bytes are in the range 0x80..0xBF. */
+ if (((unsigned char)*s++ & 0xC0) != 0x80)
+ return 0;
+ if (((unsigned char)*s++ & 0xC0) != 0x80)
+ return 0;
+ if (((unsigned char)*s++ & 0xC0) != 0x80)
+ return 0;
+
+ return 4;
+ } else { /* F5..FF */
+ return 0;
+ }
+}
+
+/* Validate a null-terminated UTF-8 string. */
+static bool utf8_validate(const char *s)
+{
+ int len;
+
+ for (; *s != 0; s += len) {
+ len = utf8_validate_cz(s);
+ if (len == 0)
+ return false;
+ }
+
+ return true;
+}
+
+/*
+ * Read a single UTF-8 character starting at @s,
+ * returning the length, in bytes, of the character read.
+ *
+ * This function assumes input is valid UTF-8,
+ * and that there are enough characters in front of @s.
+ */
+static int utf8_read_char(const char *s, uchar_t *out)
+{
+ const unsigned char *c = (const unsigned char*) s;
+
+ assert(utf8_validate_cz(s));
+
+ if (c[0] <= 0x7F) {
+ /* 00..7F */
+ *out = c[0];
+ return 1;
+ } else if (c[0] <= 0xDF) {
+ /* C2..DF (unless input is invalid) */
+ *out = ((uchar_t)c[0] & 0x1F) << 6 |
+ ((uchar_t)c[1] & 0x3F);
+ return 2;
+ } else if (c[0] <= 0xEF) {
+ /* E0..EF */
+ *out = ((uchar_t)c[0] & 0xF) << 12 |
+ ((uchar_t)c[1] & 0x3F) << 6 |
+ ((uchar_t)c[2] & 0x3F);
+ return 3;
+ } else {
+ /* F0..F4 (unless input is invalid) */
+ *out = ((uchar_t)c[0] & 0x7) << 18 |
+ ((uchar_t)c[1] & 0x3F) << 12 |
+ ((uchar_t)c[2] & 0x3F) << 6 |
+ ((uchar_t)c[3] & 0x3F);
+ return 4;
+ }
+}
+
+/*
+ * Write a single UTF-8 character to @s,
+ * returning the length, in bytes, of the character written.
+ *
+ * @unicode must be U+0000..U+10FFFF, but not U+D800..U+DFFF.
+ *
+ * This function will write up to 4 bytes to @out.
+ */
+static int utf8_write_char(uchar_t unicode, char *out)
+{
+ unsigned char *o = (unsigned char*) out;
+
+ assert(unicode <= 0x10FFFF && !(unicode >= 0xD800 && unicode <= 0xDFFF));
+
+ if (unicode <= 0x7F) {
+ /* U+0000..U+007F */
+ *o++ = unicode;
+ return 1;
+ } else if (unicode <= 0x7FF) {
+ /* U+0080..U+07FF */
+ *o++ = 0xC0 | unicode >> 6;
+ *o++ = 0x80 | (unicode & 0x3F);
+ return 2;
+ } else if (unicode <= 0xFFFF) {
+ /* U+0800..U+FFFF */
+ *o++ = 0xE0 | unicode >> 12;
+ *o++ = 0x80 | (unicode >> 6 & 0x3F);
+ *o++ = 0x80 | (unicode & 0x3F);
+ return 3;
+ } else {
+ /* U+10000..U+10FFFF */
+ *o++ = 0xF0 | unicode >> 18;
+ *o++ = 0x80 | (unicode >> 12 & 0x3F);
+ *o++ = 0x80 | (unicode >> 6 & 0x3F);
+ *o++ = 0x80 | (unicode & 0x3F);
+ return 4;
+ }
+}
+
+/*
+ * Compute the Unicode codepoint of a UTF-16 surrogate pair.
+ *
+ * @uc should be 0xD800..0xDBFF, and @lc should be 0xDC00..0xDFFF.
+ * If they aren't, this function returns false.
+ */
+static bool from_surrogate_pair(uint16_t uc, uint16_t lc, uchar_t *unicode)
+{
+ if (uc >= 0xD800 && uc <= 0xDBFF && lc >= 0xDC00 && lc <= 0xDFFF) {
+ *unicode = 0x10000 + ((((uchar_t)uc & 0x3FF) << 10) | (lc & 0x3FF));
+ return true;
+ } else {
+ return false;
+ }
+}
+
+/*
+ * Construct a UTF-16 surrogate pair given a Unicode codepoint.
+ *
+ * @unicode must be U+10000..U+10FFFF.
+ */
+static void to_surrogate_pair(uchar_t unicode, uint16_t *uc, uint16_t *lc)
+{
+ uchar_t n;
+
+ assert(unicode >= 0x10000 && unicode <= 0x10FFFF);
+
+ n = unicode - 0x10000;
+ *uc = ((n >> 10) & 0x3FF) | 0xD800;
+ *lc = (n & 0x3FF) | 0xDC00;
+}
+
+#define is_space(c) ((c) == '\t' || (c) == '\n' || (c) == '\r' || (c) == ' ')
+#define is_digit(c) ((c) >= '0' && (c) <= '9')
+
+static bool parse_value (const char **sp, JsonNode **out);
+static bool parse_string (const char **sp, char **out);
+static bool parse_number (const char **sp, double *out);
+static bool parse_array (const char **sp, JsonNode **out);
+static bool parse_object (const char **sp, JsonNode **out);
+static bool parse_hex16 (const char **sp, uint16_t *out);
+
+static bool expect_literal (const char **sp, const char *str);
+static void skip_space (const char **sp);
+
+static void emit_value (SB *out, const JsonNode *node);
+static void emit_value_indented (SB *out, const JsonNode *node, const char *space, int indent_level);
+static void emit_string (SB *out, const char *str);
+static void emit_number (SB *out, double num);
+static void emit_array (SB *out, const JsonNode *array);
+static void emit_array_indented (SB *out, const JsonNode *array, const char *space, int indent_level);
+static void emit_object (SB *out, const JsonNode *object);
+static void emit_object_indented (SB *out, const JsonNode *object, const char *space, int indent_level);
+
+static int write_hex16(char *out, uint16_t val);
+
+static JsonNode *mknode(JsonTag tag);
+static void append_node(JsonNode *parent, JsonNode *child);
+static void prepend_node(JsonNode *parent, JsonNode *child);
+static void append_member(JsonNode *object, char *key, JsonNode *value);
+
+/* Assertion-friendly validity checks */
+static bool tag_is_valid(unsigned int tag);
+static bool number_is_valid(const char *num);
+
+JsonNode *json_decode(const char *json)
+{
+ const char *s = json;
+ JsonNode *ret;
+
+ skip_space(&s);
+ if (!parse_value(&s, &ret))
+ return NULL;
+
+ skip_space(&s);
+ if (*s != 0) {
+ json_delete(ret);
+ return NULL;
+ }
+
+ return ret;
+}
+
+char *json_encode(const JsonNode *node)
+{
+ return json_stringify(node, NULL);
+}
+
+char *json_encode_string(const char *str)
+{
+ SB sb;
+ sb_init(&sb);
+
+ emit_string(&sb, str);
+
+ return sb_finish(&sb);
+}
+
+char *json_stringify(const JsonNode *node, const char *space)
+{
+ SB sb;
+ sb_init(&sb);
+
+ if (space != NULL)
+ emit_value_indented(&sb, node, space, 0);
+ else
+ emit_value(&sb, node);
+
+ return sb_finish(&sb);
+}
+
+void json_delete(JsonNode *node)
+{
+ if (node != NULL) {
+ json_remove_from_parent(node);
+
+ switch (node->tag) {
+ case JSON_STRING:
+ free(node->string_);
+ break;
+ case JSON_ARRAY:
+ case JSON_OBJECT:
+ {
+ JsonNode *child, *next;
+ for (child = node->children.head; child != NULL; child = next) {
+ next = child->next;
+ json_delete(child);
+ }
+ break;
+ }
+ default:;
+ }
+
+ free(node);
+ }
+}
+
+bool json_validate(const char *json)
+{
+ const char *s = json;
+
+ skip_space(&s);
+ if (!parse_value(&s, NULL))
+ return false;
+
+ skip_space(&s);
+ if (*s != 0)
+ return false;
+
+ return true;
+}
+
+JsonNode *json_find_element(JsonNode *array, int index)
+{
+ JsonNode *element;
+ int i = 0;
+
+ if (array == NULL || array->tag != JSON_ARRAY)
+ return NULL;
+
+ json_foreach(element, array) {
+ if (i == index)
+ return element;
+ i++;
+ }
+
+ return NULL;
+}
+
+JsonNode *json_find_member(JsonNode *object, const char *name)
+{
+ JsonNode *member;
+
+ if (object == NULL || object->tag != JSON_OBJECT)
+ return NULL;
+
+ json_foreach(member, object)
+ if (strcmp(member->key, name) == 0)
+ return member;
+
+ return NULL;
+}
+
+JsonNode *json_first_child(const JsonNode *node)
+{
+ if (node != NULL && (node->tag == JSON_ARRAY || node->tag == JSON_OBJECT))
+ return node->children.head;
+ return NULL;
+}
+
+static JsonNode *mknode(JsonTag tag)
+{
+ JsonNode *ret = (JsonNode*) calloc(1, sizeof(JsonNode));
+ if (ret == NULL)
+ out_of_memory();
+ ret->tag = tag;
+ return ret;
+}
+
+JsonNode *json_mknull(void)
+{
+ return mknode(JSON_NULL);
+}
+
+JsonNode *json_mkbool(bool b)
+{
+ JsonNode *ret = mknode(JSON_BOOL);
+ ret->bool_ = b;
+ return ret;
+}
+
+static JsonNode *mkstring(char *s)
+{
+ JsonNode *ret = mknode(JSON_STRING);
+ ret->string_ = s;
+ return ret;
+}
+
+JsonNode *json_mkstring(const char *s)
+{
+ return mkstring(json_strdup(s));
+}
+
+JsonNode *json_mknumber(double n)
+{
+ JsonNode *node = mknode(JSON_NUMBER);
+ node->number_ = n;
+ return node;
+}
+
+JsonNode *json_mkarray(void)
+{
+ return mknode(JSON_ARRAY);
+}
+
+JsonNode *json_mkobject(void)
+{
+ return mknode(JSON_OBJECT);
+}
+
+static void append_node(JsonNode *parent, JsonNode *child)
+{
+ child->parent = parent;
+ child->prev = parent->children.tail;
+ child->next = NULL;
+
+ if (parent->children.tail != NULL)
+ parent->children.tail->next = child;
+ else
+ parent->children.head = child;
+ parent->children.tail = child;
+}
+
+static void prepend_node(JsonNode *parent, JsonNode *child)
+{
+ child->parent = parent;
+ child->prev = NULL;
+ child->next = parent->children.head;
+
+ if (parent->children.head != NULL)
+ parent->children.head->prev = child;
+ else
+ parent->children.tail = child;
+ parent->children.head = child;
+}
+
+static void append_member(JsonNode *object, char *key, JsonNode *value)
+{
+ value->key = key;
+ append_node(object, value);
+}
+
+void json_append_element(JsonNode *array, JsonNode *element)
+{
+ assert(array->tag == JSON_ARRAY);
+ assert(element->parent == NULL);
+
+ append_node(array, element);
+}
+
+void json_prepend_element(JsonNode *array, JsonNode *element)
+{
+ assert(array->tag == JSON_ARRAY);
+ assert(element->parent == NULL);
+
+ prepend_node(array, element);
+}
+
+void json_append_member(JsonNode *object, const char *key, JsonNode *value)
+{
+ assert(object->tag == JSON_OBJECT);
+ assert(value->parent == NULL);
+
+ append_member(object, json_strdup(key), value);
+}
+
+void json_prepend_member(JsonNode *object, const char *key, JsonNode *value)
+{
+ assert(object->tag == JSON_OBJECT);
+ assert(value->parent == NULL);
+
+ value->key = json_strdup(key);
+ prepend_node(object, value);
+}
+
+void json_remove_from_parent(JsonNode *node)
+{
+ JsonNode *parent = node->parent;
+
+ if (parent != NULL) {
+ if (node->prev != NULL)
+ node->prev->next = node->next;
+ else
+ parent->children.head = node->next;
+ if (node->next != NULL)
+ node->next->prev = node->prev;
+ else
+ parent->children.tail = node->prev;
+
+ free(node->key);
+
+ node->parent = NULL;
+ node->prev = node->next = NULL;
+ node->key = NULL;
+ }
+}
+
+static bool parse_value(const char **sp, JsonNode **out)
+{
+ const char *s = *sp;
+
+ switch (*s) {
+ case 'n':
+ if (expect_literal(&s, "null")) {
+ if (out)
+ *out = json_mknull();
+ *sp = s;
+ return true;
+ }
+ return false;
+
+ case 'f':
+ if (expect_literal(&s, "false")) {
+ if (out)
+ *out = json_mkbool(false);
+ *sp = s;
+ return true;
+ }
+ return false;
+
+ case 't':
+ if (expect_literal(&s, "true")) {
+ if (out)
+ *out = json_mkbool(true);
+ *sp = s;
+ return true;
+ }
+ return false;
+
+ case '"': {
+ char *str;
+ if (parse_string(&s, out ? &str : NULL)) {
+ if (out)
+ *out = mkstring(str);
+ *sp = s;
+ return true;
+ }
+ return false;
+ }
+
+ case '[':
+ if (parse_array(&s, out)) {
+ *sp = s;
+ return true;
+ }
+ return false;
+
+ case '{':
+ if (parse_object(&s, out)) {
+ *sp = s;
+ return true;
+ }
+ return false;
+
+ default: {
+ double num;
+ if (parse_number(&s, out ? &num : NULL)) {
+ if (out)
+ *out = json_mknumber(num);
+ *sp = s;
+ return true;
+ }
+ return false;
+ }
+ }
+}
+
+static bool parse_array(const char **sp, JsonNode **out)
+{
+ const char *s = *sp;
+ JsonNode *ret = out ? json_mkarray() : NULL;
+ JsonNode *element;
+
+ if (*s++ != '[')
+ goto failure;
+ skip_space(&s);
+
+ if (*s == ']') {
+ s++;
+ goto success;
+ }
+
+ for (;;) {
+ if (!parse_value(&s, out ? &element : NULL))
+ goto failure;
+ skip_space(&s);
+
+ if (out)
+ json_append_element(ret, element);
+
+ if (*s == ']') {
+ s++;
+ goto success;
+ }
+
+ if (*s++ != ',')
+ goto failure;
+ skip_space(&s);
+ }
+
+success:
+ *sp = s;
+ if (out)
+ *out = ret;
+ return true;
+
+failure:
+ json_delete(ret);
+ return false;
+}
+
+static bool parse_object(const char **sp, JsonNode **out)
+{
+ const char *s = *sp;
+ JsonNode *ret = out ? json_mkobject() : NULL;
+ char *key;
+ JsonNode *value;
+
+ if (*s++ != '{')
+ goto failure;
+ skip_space(&s);
+
+ if (*s == '}') {
+ s++;
+ goto success;
+ }
+
+ for (;;) {
+ if (!parse_string(&s, out ? &key : NULL))
+ goto failure;
+ skip_space(&s);
+
+ if (*s++ != ':')
+ goto failure_free_key;
+ skip_space(&s);
+
+ if (!parse_value(&s, out ? &value : NULL))
+ goto failure_free_key;
+ skip_space(&s);
+
+ if (out)
+ append_member(ret, key, value);
+
+ if (*s == '}') {
+ s++;
+ goto success;
+ }
+
+ if (*s++ != ',')
+ goto failure;
+ skip_space(&s);
+ }
+
+success:
+ *sp = s;
+ if (out)
+ *out = ret;
+ return true;
+
+failure_free_key:
+ if (out)
+ free(key);
+failure:
+ json_delete(ret);
+ return false;
+}
+
+bool parse_string(const char **sp, char **out)
+{
+ const char *s = *sp;
+ SB sb = { NULL, NULL, NULL };
+ char throwaway_buffer[4];
+ /* enough space for a UTF-8 character */
+ char *b;
+
+ if (*s++ != '"')
+ return false;
+
+ if (out) {
+ sb_init(&sb);
+ sb_need(&sb, 4);
+ b = sb.cur;
+ } else {
+ b = throwaway_buffer;
+ }
+
+ while (*s != '"') {
+ unsigned char c = *s++;
+
+ /* Parse next character, and write it to b. */
+ if (c == '\\') {
+ c = *s++;
+ switch (c) {
+ case '"':
+ case '\\':
+ case '/':
+ *b++ = c;
+ break;
+ case 'b':
+ *b++ = '\b';
+ break;
+ case 'f':
+ *b++ = '\f';
+ break;
+ case 'n':
+ *b++ = '\n';
+ break;
+ case 'r':
+ *b++ = '\r';
+ break;
+ case 't':
+ *b++ = '\t';
+ break;
+ case 'u':
+ {
+ uint16_t uc, lc;
+ uchar_t unicode;
+
+ if (!parse_hex16(&s, &uc))
+ goto failed;
+
+ if (uc >= 0xD800 && uc <= 0xDFFF) {
+ /* Handle UTF-16 surrogate pair. */
+ if (*s++ != '\\' || *s++ != 'u' || !parse_hex16(&s, &lc))
+ goto failed; /* Incomplete surrogate pair. */
+ if (!from_surrogate_pair(uc, lc, &unicode))
+ goto failed; /* Invalid surrogate pair. */
+ } else if (uc == 0) {
+ /* Disallow "\u0000". */
+ goto failed;
+ } else {
+ unicode = uc;
+ }
+
+ b += utf8_write_char(unicode, b);
+ break;
+ }
+ default:
+ /* Invalid escape */
+ goto failed;
+ }
+ } else if (c <= 0x1F) {
+ /* Control characters are not allowed in string literals. */
+ goto failed;
+ } else {
+ /* Validate and echo a UTF-8 character. */
+ int len;
+
+ s--;
+ len = utf8_validate_cz(s);
+ if (len == 0)
+ goto failed; /* Invalid UTF-8 character. */
+
+ while (len--)
+ *b++ = *s++;
+ }
+
+ /*
+ * Update sb to know about the new bytes,
+ * and set up b to write another character.
+ */
+ if (out) {
+ sb.cur = b;
+ sb_need(&sb, 4);
+ b = sb.cur;
+ } else {
+ b = throwaway_buffer;
+ }
+ }
+ s++;
+
+ if (out)
+ *out = sb_finish(&sb);
+ *sp = s;
+ return true;
+
+failed:
+ if (out)
+ sb_free(&sb);
+ return false;
+}
+
+/*
+ * The JSON spec says that a number shall follow this precise pattern
+ * (spaces and quotes added for readability):
+ * '-'? (0 | [1-9][0-9]*) ('.' [0-9]+)? ([Ee] [+-]? [0-9]+)?
+ *
+ * However, some JSON parsers are more liberal. For instance, PHP accepts
+ * '.5' and '1.'. JSON.parse accepts '+3'.
+ *
+ * This function takes the strict approach.
+ */
+bool parse_number(const char **sp, double *out)
+{
+ const char *s = *sp;
+
+ /* '-'? */
+ if (*s == '-')
+ s++;
+
+ /* (0 | [1-9][0-9]*) */
+ if (*s == '0') {
+ s++;
+ } else {
+ if (!is_digit(*s))
+ return false;
+ do {
+ s++;
+ } while (is_digit(*s));
+ }
+
+ /* ('.' [0-9]+)? */
+ if (*s == '.') {
+ s++;
+ if (!is_digit(*s))
+ return false;
+ do {
+ s++;
+ } while (is_digit(*s));
+ }
+
+ /* ([Ee] [+-]? [0-9]+)? */
+ if (*s == 'E' || *s == 'e') {
+ s++;
+ if (*s == '+' || *s == '-')
+ s++;
+ if (!is_digit(*s))
+ return false;
+ do {
+ s++;
+ } while (is_digit(*s));
+ }
+
+ if (out)
+ *out = strtod(*sp, NULL);
+
+ *sp = s;
+ return true;
+}
+
+static void skip_space(const char **sp)
+{
+ const char *s = *sp;
+ while (is_space(*s))
+ s++;
+ *sp = s;
+}
+
+static void emit_value(SB *out, const JsonNode *node)
+{
+ assert(tag_is_valid(node->tag));
+ switch (node->tag) {
+ case JSON_NULL:
+ sb_puts(out, "null");
+ break;
+ case JSON_BOOL:
+ sb_puts(out, node->bool_ ? "true" : "false");
+ break;
+ case JSON_STRING:
+ emit_string(out, node->string_);
+ break;
+ case JSON_NUMBER:
+ emit_number(out, node->number_);
+ break;
+ case JSON_ARRAY:
+ emit_array(out, node);
+ break;
+ case JSON_OBJECT:
+ emit_object(out, node);
+ break;
+ default:
+ assert(false);
+ }
+}
+
+void emit_value_indented(SB *out, const JsonNode *node, const char *space, int indent_level)
+{
+ assert(tag_is_valid(node->tag));
+ switch (node->tag) {
+ case JSON_NULL:
+ sb_puts(out, "null");
+ break;
+ case JSON_BOOL:
+ sb_puts(out, node->bool_ ? "true" : "false");
+ break;
+ case JSON_STRING:
+ emit_string(out, node->string_);
+ break;
+ case JSON_NUMBER:
+ emit_number(out, node->number_);
+ break;
+ case JSON_ARRAY:
+ emit_array_indented(out, node, space, indent_level);
+ break;
+ case JSON_OBJECT:
+ emit_object_indented(out, node, space, indent_level);
+ break;
+ default:
+ assert(false);
+ }
+}
+
+static void emit_array(SB *out, const JsonNode *array)
+{
+ const JsonNode *element;
+
+ sb_putc(out, '[');
+ json_foreach(element, array) {
+ emit_value(out, element);
+ if (element->next != NULL)
+ sb_putc(out, ',');
+ }
+ sb_putc(out, ']');
+}
+
+static void emit_array_indented(SB *out, const JsonNode *array, const char *space, int indent_level)
+{
+ const JsonNode *element = array->children.head;
+ int i;
+
+ if (element == NULL) {
+ sb_puts(out, "[]");
+ return;
+ }
+
+ sb_puts(out, "[\n");
+ while (element != NULL) {
+ for (i = 0; i < indent_level + 1; i++)
+ sb_puts(out, space);
+ emit_value_indented(out, element, space, indent_level + 1);
+
+ element = element->next;
+ sb_puts(out, element != NULL ? ",\n" : "\n");
+ }
+ for (i = 0; i < indent_level; i++)
+ sb_puts(out, space);
+ sb_putc(out, ']');
+}
+
+static void emit_object(SB *out, const JsonNode *object)
+{
+ const JsonNode *member;
+
+ sb_putc(out, '{');
+ json_foreach(member, object) {
+ emit_string(out, member->key);
+ sb_putc(out, ':');
+ emit_value(out, member);
+ if (member->next != NULL)
+ sb_putc(out, ',');
+ }
+ sb_putc(out, '}');
+}
+
+static void emit_object_indented(SB *out, const JsonNode *object, const char *space, int indent_level)
+{
+ const JsonNode *member = object->children.head;
+ int i;
+
+ if (member == NULL) {
+ sb_puts(out, "{}");
+ return;
+ }
+
+ sb_puts(out, "{\n");
+ while (member != NULL) {
+ for (i = 0; i < indent_level + 1; i++)
+ sb_puts(out, space);
+ emit_string(out, member->key);
+ sb_puts(out, ": ");
+ emit_value_indented(out, member, space, indent_level + 1);
+
+ member = member->next;
+ sb_puts(out, member != NULL ? ",\n" : "\n");
+ }
+ for (i = 0; i < indent_level; i++)
+ sb_puts(out, space);
+ sb_putc(out, '}');
+}
+
+void emit_string(SB *out, const char *str)
+{
+ bool escape_unicode = false;
+ const char *s = str;
+ char *b;
+
+ assert(utf8_validate(str));
+
+ /*
+ * 14 bytes is enough space to write up to two
+ * \uXXXX escapes and two quotation marks.
+ */
+ sb_need(out, 14);
+ b = out->cur;
+
+ *b++ = '"';
+ while (*s != 0) {
+ unsigned char c = *s++;
+
+ /* Encode the next character, and write it to b. */
+ switch (c) {
+ case '"':
+ *b++ = '\\';
+ *b++ = '"';
+ break;
+ case '\\':
+ *b++ = '\\';
+ *b++ = '\\';
+ break;
+ case '\b':
+ *b++ = '\\';
+ *b++ = 'b';
+ break;
+ case '\f':
+ *b++ = '\\';
+ *b++ = 'f';
+ break;
+ case '\n':
+ *b++ = '\\';
+ *b++ = 'n';
+ break;
+ case '\r':
+ *b++ = '\\';
+ *b++ = 'r';
+ break;
+ case '\t':
+ *b++ = '\\';
+ *b++ = 't';
+ break;
+ default: {
+ int len;
+
+ s--;
+ len = utf8_validate_cz(s);
+
+ if (len == 0) {
+ /*
+ * Handle invalid UTF-8 character gracefully in production
+ * by writing a replacement character (U+FFFD)
+ * and skipping a single byte.
+ *
+ * This should never happen when assertions are enabled
+ * due to the assertion at the beginning of this function.
+ */
+ assert(false);
+ if (escape_unicode) {
+ strcpy(b, "\\uFFFD");
+ b += 6;
+ } else {
+ *b++ = (char)0xEF;
+ *b++ = (char)0xBF;
+ *b++ = (char)0xBD;
+ }
+ s++;
+ } else if (c < 0x1F || (c >= 0x80 && escape_unicode)) {
+ /* Encode using \u.... */
+ uint32_t unicode;
+
+ s += utf8_read_char(s, &unicode);
+
+ if (unicode <= 0xFFFF) {
+ *b++ = '\\';
+ *b++ = 'u';
+ b += write_hex16(b, unicode);
+ } else {
+ /* Produce a surrogate pair. */
+ uint16_t uc, lc;
+ assert(unicode <= 0x10FFFF);
+ to_surrogate_pair(unicode, &uc, &lc);
+ *b++ = '\\';
+ *b++ = 'u';
+ b += write_hex16(b, uc);
+ *b++ = '\\';
+ *b++ = 'u';
+ b += write_hex16(b, lc);
+ }
+ } else {
+ /* Write the character directly. */
+ while (len--)
+ *b++ = *s++;
+ }
+
+ break;
+ }
+ }
+
+ /*
+ * Update *out to know about the new bytes,
+ * and set up b to write another encoded character.
+ */
+ out->cur = b;
+ sb_need(out, 14);
+ b = out->cur;
+ }
+ *b++ = '"';
+
+ out->cur = b;
+}
+
+static void emit_number(SB *out, double num)
+{
+ /*
+ * This isn't exactly how JavaScript renders numbers,
+ * but it should produce valid JSON for reasonable numbers
+ * preserve precision well enough, and avoid some oddities
+ * like 0.3 -> 0.299999999999999988898 .
+ */
+ char buf[64];
+ sprintf(buf, "%.16g", num);
+
+ if (number_is_valid(buf))
+ sb_puts(out, buf);
+ else
+ sb_puts(out, "null");
+}
+
+static bool tag_is_valid(unsigned int tag)
+{
+ return (/* tag >= JSON_NULL && */ tag <= JSON_OBJECT);
+}
+
+static bool number_is_valid(const char *num)
+{
+ return (parse_number(&num, NULL) && *num == '\0');
+}
+
+static bool expect_literal(const char **sp, const char *str)
+{
+ const char *s = *sp;
+
+ while (*str != '\0')
+ if (*s++ != *str++)
+ return false;
+
+ *sp = s;
+ return true;
+}
+
+/*
+ * Parses exactly 4 hex characters (capital or lowercase).
+ * Fails if any input chars are not [0-9A-Fa-f].
+ */
+static bool parse_hex16(const char **sp, uint16_t *out)
+{
+ const char *s = *sp;
+ uint16_t ret = 0;
+ uint16_t i;
+ uint16_t tmp;
+ char c;
+
+ for (i = 0; i < 4; i++) {
+ c = *s++;
+ if (c >= '0' && c <= '9')
+ tmp = c - '0';
+ else if (c >= 'A' && c <= 'F')
+ tmp = c - 'A' + 10;
+ else if (c >= 'a' && c <= 'f')
+ tmp = c - 'a' + 10;
+ else
+ return false;
+
+ ret <<= 4;
+ ret += tmp;
+ }
+
+ if (out)
+ *out = ret;
+ *sp = s;
+ return true;
+}
+
+/*
+ * Encodes a 16-bit number into hexadecimal,
+ * writing exactly 4 hex chars.
+ */
+static int write_hex16(char *out, uint16_t val)
+{
+ const char *hex = "0123456789ABCDEF";
+
+ *out++ = hex[(val >> 12) & 0xF];
+ *out++ = hex[(val >> 8) & 0xF];
+ *out++ = hex[(val >> 4) & 0xF];
+ *out++ = hex[ val & 0xF];
+
+ return 4;
+}
+
+bool json_check(const JsonNode *node, char errmsg[256])
+{
+ #define problem(...) do { \
+ if (errmsg != NULL) \
+ snprintf(errmsg, 256, __VA_ARGS__); \
+ return false; \
+ } while (0)
+
+ if (node->key != NULL && !utf8_validate(node->key))
+ problem("key contains invalid UTF-8");
+
+ if (!tag_is_valid(node->tag))
+ problem("tag is invalid (%u)", node->tag);
+
+ if (node->tag == JSON_BOOL) {
+ if (node->bool_ != false && node->bool_ != true)
+ problem("bool_ is neither false (%d) nor true (%d)", (int)false, (int)true);
+ } else if (node->tag == JSON_STRING) {
+ if (node->string_ == NULL)
+ problem("string_ is NULL");
+ if (!utf8_validate(node->string_))
+ problem("string_ contains invalid UTF-8");
+ } else if (node->tag == JSON_ARRAY || node->tag == JSON_OBJECT) {
+ JsonNode *head = node->children.head;
+ JsonNode *tail = node->children.tail;
+
+ if (head == NULL || tail == NULL) {
+ if (head != NULL)
+ problem("tail is NULL, but head is not");
+ if (tail != NULL)
+ problem("head is NULL, but tail is not");
+ } else {
+ JsonNode *child;
+ JsonNode *last = NULL;
+
+ if (head->prev != NULL)
+ problem("First child's prev pointer is not NULL");
+
+ for (child = head; child != NULL; last = child, child = child->next) {
+ if (child == node)
+ problem("node is its own child");
+ if (child->next == child)
+ problem("child->next == child (cycle)");
+ if (child->next == head)
+ problem("child->next == head (cycle)");
+
+ if (child->parent != node)
+ problem("child does not point back to parent");
+ if (child->next != NULL && child->next->prev != child)
+ problem("child->next does not point back to child");
+
+ if (node->tag == JSON_ARRAY && child->key != NULL)
+ problem("Array element's key is not NULL");
+ if (node->tag == JSON_OBJECT && child->key == NULL)
+ problem("Object member's key is NULL");
+
+ if (!json_check(child, errmsg))
+ return false;
+ }
+
+ if (last != tail)
+ problem("tail does not match pointer found by starting at head and following next links");
+ }
+ }
+
+ return true;
+
+ #undef problem
+}
diff --git a/contrib/ccan/json/json.h b/contrib/ccan/json/json.h
new file mode 100644
index 0000000..6eef48a
--- /dev/null
+++ b/contrib/ccan/json/json.h
@@ -0,0 +1,99 @@
+/* SPDX-License-Identifier: MIT
+ * Source: https://ccodearchive.net/info/json.html
+ * Copyright (C) 2011 Joseph A. Adams (joeyadams3.14159@gmail.com) */
+
+#ifndef CCAN_JSON_H
+#define CCAN_JSON_H
+
+#include <lib/defines.h>
+#include <stdbool.h>
+#include <stddef.h>
+
+typedef enum {
+ JSON_NULL,
+ JSON_BOOL,
+ JSON_STRING,
+ JSON_NUMBER,
+ JSON_ARRAY,
+ JSON_OBJECT,
+} JsonTag;
+
+typedef struct JsonNode JsonNode;
+
+struct JsonNode
+{
+ /* only if parent is an object or array (NULL otherwise) */
+ JsonNode *parent;
+ JsonNode *prev, *next;
+
+ /* only if parent is an object (NULL otherwise) */
+ char *key; /* Must be valid UTF-8. */
+
+ JsonTag tag;
+ union {
+ /* JSON_BOOL */
+ bool bool_;
+
+ /* JSON_STRING */
+ char *string_; /* Must be valid UTF-8. */
+
+ /* JSON_NUMBER */
+ double number_;
+
+ /* JSON_ARRAY */
+ /* JSON_OBJECT */
+ struct {
+ JsonNode *head, *tail;
+ } children;
+ };
+};
+
+/*** Encoding, decoding, and validation ***/
+
+KR_EXPORT JsonNode *json_decode (const char *json);
+KR_EXPORT char *json_encode (const JsonNode *node);
+KR_EXPORT char *json_encode_string (const char *str);
+KR_EXPORT char *json_stringify (const JsonNode *node, const char *space);
+KR_EXPORT void json_delete (JsonNode *node);
+
+KR_EXPORT bool json_validate (const char *json);
+
+/*** Lookup and traversal ***/
+
+KR_EXPORT JsonNode *json_find_element (JsonNode *array, int index);
+KR_EXPORT JsonNode *json_find_member (JsonNode *object, const char *key);
+
+KR_EXPORT JsonNode *json_first_child (const JsonNode *node);
+
+#define json_foreach(i, object_or_array) \
+ for ((i) = json_first_child(object_or_array); \
+ (i) != NULL; \
+ (i) = (i)->next)
+
+/*** Construction and manipulation ***/
+
+KR_EXPORT JsonNode *json_mknull(void);
+KR_EXPORT JsonNode *json_mkbool(bool b);
+KR_EXPORT JsonNode *json_mkstring(const char *s);
+KR_EXPORT JsonNode *json_mknumber(double n);
+KR_EXPORT JsonNode *json_mkarray(void);
+KR_EXPORT JsonNode *json_mkobject(void);
+
+KR_EXPORT void json_append_element(JsonNode *array, JsonNode *element);
+KR_EXPORT void json_prepend_element(JsonNode *array, JsonNode *element);
+KR_EXPORT void json_append_member(JsonNode *object, const char *key, JsonNode *value);
+KR_EXPORT void json_prepend_member(JsonNode *object, const char *key, JsonNode *value);
+
+KR_EXPORT void json_remove_from_parent(JsonNode *node);
+
+/*** Debugging ***/
+
+/*
+ * Look for structure and encoding problems in a JsonNode or its descendents.
+ *
+ * If a problem is detected, return false, writing a description of the problem
+ * to errmsg (unless errmsg is NULL).
+ */
+KR_EXPORT bool json_check(const JsonNode *node, char errmsg[256]);
+
+#endif
diff --git a/contrib/ccan/json/json.spdx b/contrib/ccan/json/json.spdx
new file mode 100644
index 0000000..9943583
--- /dev/null
+++ b/contrib/ccan/json/json.spdx
@@ -0,0 +1,10 @@
+SPDXVersion: SPDX-2.1
+DataLicense: CC0-1.0
+SPDXID: SPDXRef-DOCUMENT
+DocumentName: ccan-json
+DocumentNamespace: http://spdx.org/spdxdocs/spdx-v2.1-d9b4db4c-062f-4add-89b6-f603224f5a2c
+
+PackageName: json
+PackageDownloadLocation: git+https://github.com/rustyrussell/ccan@f4eb3a18caf946ee6cc2cb57e2a0c6a6f115157f#ccan/json
+PackageOriginator: Person: Joseph A. Adams (joeyadams3.14159@gmail.com)
+PackageLicenseDeclared: MIT
diff --git a/contrib/cleanup.h b/contrib/cleanup.h
new file mode 100644
index 0000000..c9d170a
--- /dev/null
+++ b/contrib/cleanup.h
@@ -0,0 +1,25 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+*/
+/**
+ * Cleanup attributes.
+ * @cond internal
+ */
+#pragma once
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+#define auto_free __attribute__((cleanup(_cleanup_free)))
+static inline void _cleanup_free(const void *p) {
+ free(*(char **)p);
+}
+#define auto_close __attribute__((cleanup(_cleanup_close)))
+static inline void _cleanup_close(int *p) {
+ if (*p != -1) close(*p);
+}
+#define auto_fclose __attribute__((cleanup(_cleanup_fclose)))
+static inline void _cleanup_fclose(FILE **p) {
+ if (*p) fclose(*p);
+}
+/* @endcond */
diff --git a/contrib/config.h b/contrib/config.h
new file mode 100644
index 0000000..336511f
--- /dev/null
+++ b/contrib/config.h
@@ -0,0 +1,7 @@
+/* Dummy file, no real configuration here
+ * SPDX-License-Identifier: GPL-3.0-or-later */
+#define HAVE_ATTRIBUTE_COLD 1
+#define HAVE_ATTRIBUTE_NORETURN 1
+#define HAVE_ATTRIBUTE_PURE 1
+#define HAVE_ATTRIBUTE_UNUSED 1
+#define HAVE_ATTRIBUTE_NONNULL 1
diff --git a/contrib/dynarray.h b/contrib/dynarray.h
new file mode 100644
index 0000000..7cbb686
--- /dev/null
+++ b/contrib/dynarray.h
@@ -0,0 +1,112 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+/*!
+ * \brief Simple write-once allocation-optimal dynamic array.
+ *
+ * Include it into your .c file
+ *
+ * prefix - identifier prefix, e.g. ptr -> struct ptr_dynarray, ptr_dynarray_add(), ...
+ * ntype - data type to be stored. Let it be a number, pointer or small struct
+ * initial_capacity - how many data items will be allocated on stack and copied with assignment
+ *
+ * prefix_dynarray_add() - add a data item
+ * prefix_dynarray_fix() - call EVERYTIME the array is copied from some already invalid stack
+ * prefix_dynarray_free() - call EVERYTIME you dismiss all copies of the array
+ *
+ */
+
+#include <stdlib.h>
+#include <assert.h>
+
+#pragma once
+
+#define DYNARRAY_VISIBILITY_STATIC static
+#define DYNARRAY_VISIBILITY_PUBLIC
+#define DYNARRAY_VISIBILITY_LIBRARY __public__
+
+#define dynarray_declare(prefix, ntype, visibility, initial_capacity) \
+ typedef struct prefix ## _dynarray { \
+ ssize_t capacity; \
+ ssize_t size; \
+ ntype *(*arr)(struct prefix ## _dynarray *dynarray); \
+ ntype init[initial_capacity]; \
+ ntype *_arr; \
+ } prefix ## _dynarray_t; \
+ \
+ visibility ntype *prefix ## _dynarray_arr(prefix ## _dynarray_t *dynarray); \
+ visibility void prefix ## _dynarray_add(prefix ## _dynarray_t *dynarray, \
+ ntype const *to_add); \
+ visibility void prefix ## _dynarray_free(prefix ## _dynarray_t *dynarray);
+
+#define dynarray_foreach(prefix, ntype, ptr, array) \
+ for (ntype *ptr = prefix ## _dynarray_arr(&(array)); \
+ ptr < prefix ## _dynarray_arr(&(array)) + (array).size; ptr++)
+
+#define dynarray_define(prefix, ntype, visibility) \
+ \
+ static void prefix ## _dynarray_free__(struct prefix ## _dynarray *dynarray) \
+ { \
+ if (dynarray->capacity > sizeof(dynarray->init) / sizeof(*dynarray->init)) { \
+ free(dynarray->_arr); \
+ } \
+ } \
+ \
+ __attribute__((unused)) \
+ visibility ntype *prefix ## _dynarray_arr(struct prefix ## _dynarray *dynarray) \
+ { \
+ assert(dynarray->size <= dynarray->capacity); \
+ return (dynarray->capacity <= sizeof(dynarray->init) / sizeof(*dynarray->init) ? \
+ dynarray->init : dynarray->_arr); \
+ } \
+ \
+ static ntype *prefix ## _dynarray_arr_init__(struct prefix ## _dynarray *dynarray) \
+ { \
+ assert(dynarray->capacity == sizeof(dynarray->init) / sizeof(*dynarray->init)); \
+ return dynarray->init; \
+ } \
+ \
+ static ntype *prefix ## _dynarray_arr_arr__(struct prefix ## _dynarray *dynarray) \
+ { \
+ assert(dynarray->capacity > sizeof(dynarray->init) / sizeof(*dynarray->init)); \
+ return dynarray->_arr; \
+ } \
+ \
+ __attribute__((unused)) \
+ visibility void prefix ## _dynarray_add(struct prefix ## _dynarray *dynarray, \
+ ntype const *to_add) \
+ { \
+ if (dynarray->capacity < 0) { \
+ return; \
+ } \
+ if (dynarray->capacity == 0) { \
+ dynarray->capacity = sizeof(dynarray->init) / sizeof(*dynarray->init); \
+ dynarray->arr = prefix ## _dynarray_arr_init__; \
+ } \
+ if (dynarray->size >= dynarray->capacity) { \
+ ssize_t new_capacity = dynarray->capacity * 2 + 1; \
+ ntype *new_arr = calloc(new_capacity, sizeof(ntype)); \
+ if (new_arr == NULL) { \
+ prefix ## _dynarray_free__(dynarray); \
+ dynarray->capacity = dynarray->size = -1; \
+ return; \
+ } \
+ if (dynarray->capacity > 0) { \
+ memcpy(new_arr, prefix ## _dynarray_arr(dynarray), \
+ dynarray->capacity * sizeof(ntype)); \
+ } \
+ prefix ## _dynarray_free__(dynarray); \
+ dynarray->_arr = new_arr; \
+ dynarray->capacity = new_capacity; \
+ dynarray->arr = prefix ## _dynarray_arr_arr__; \
+ } \
+ prefix ## _dynarray_arr(dynarray)[dynarray->size++] = *to_add; \
+ } \
+ \
+ __attribute__((unused)) \
+ visibility void prefix ## _dynarray_free(struct prefix ## _dynarray *dynarray) \
+ { \
+ prefix ## _dynarray_free__(dynarray); \
+ memset(dynarray, 0, sizeof(*dynarray)); \
+ }
diff --git a/contrib/dynarray.spdx b/contrib/dynarray.spdx
new file mode 100644
index 0000000..02911c9
--- /dev/null
+++ b/contrib/dynarray.spdx
@@ -0,0 +1,10 @@
+SPDXVersion: SPDX-2.1
+DataLicense: CC0-1.0
+SPDXID: SPDXRef-DOCUMENT
+DocumentName: knotdns-dynarray
+DocumentNamespace: http://spdx.org/spdxdocs/spdx-v2.1-ce6423dd-ac6a-4e78-90c3-5cbdef1e252c
+
+PackageName: knotdns-dynarray
+PackageDownloadLocation: git+https://gitlab.nic.cz/knot/knot-dns.git@48c8b4f38cf5f7bf505c79b56adf7580688f6d3d#src/contrib/dynarray.h
+PackageOriginator: Organization: Knot DNS contributors
+PackageLicenseDeclared: GPL-3.0-or-later
diff --git a/contrib/licenses/BSD-MIT b/contrib/licenses/BSD-MIT
new file mode 100644
index 0000000..6e50b00
--- /dev/null
+++ b/contrib/licenses/BSD-MIT
@@ -0,0 +1,21 @@
+SPDX-License-Identifier: MIT
+SPDX-URL: https://spdx.org/licenses/MIT.html
+License-Text:
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/contrib/licenses/CC0 b/contrib/licenses/CC0
new file mode 100644
index 0000000..937f712
--- /dev/null
+++ b/contrib/licenses/CC0
@@ -0,0 +1,32 @@
+SPDX-License-Identifier: CC0-1.0
+SPDX-URL: https://spdx.org/licenses/CC0-1.0.html
+License-Text:
+
+Statement of Purpose
+
+The laws of most jurisdictions throughout the world automatically confer exclusive Copyright and Related Rights (defined below) upon the creator and subsequent owner(s) (each and all, an "owner") of an original work of authorship and/or a database (each, a "Work").
+
+Certain owners wish to permanently relinquish those rights to a Work for the purpose of contributing to a commons of creative, cultural and scientific works ("Commons") that the public can reliably and without fear of later claims of infringement build upon, modify, incorporate in other works, reuse and redistribute as freely as possible in any form whatsoever and for any purposes, including without limitation commercial purposes. These owners may contribute to the Commons to promote the ideal of a free culture and the further production of creative, cultural and scientific works, or to gain reputation or greater distribution for their Work in part through the use and efforts of others.
+
+For these and/or other purposes and motivations, and without any expectation of additional consideration or compensation, the person associating CC0 with a Work (the "Affirmer"), to the extent that he or she is an owner of Copyright and Related Rights in the Work, voluntarily elects to apply CC0 to the Work and publicly distribute the Work under its terms, with knowledge of his or her Copyright and Related Rights in the Work and the meaning and intended legal effect of CC0 on those rights.
+
+1. Copyright and Related Rights. A Work made available under CC0 may be protected by copyright and related or neighboring rights ("Copyright and Related Rights"). Copyright and Related Rights include, but are not limited to, the following:
+
+ the right to reproduce, adapt, distribute, perform, display, communicate, and translate a Work;
+ moral rights retained by the original author(s) and/or performer(s);
+ publicity and privacy rights pertaining to a person's image or likeness depicted in a Work;
+ rights protecting against unfair competition in regards to a Work, subject to the limitations in paragraph 4(a), below;
+ rights protecting the extraction, dissemination, use and reuse of data in a Work;
+ database rights (such as those arising under Directive 96/9/EC of the European Parliament and of the Council of 11 March 1996 on the legal protection of databases, and under any national implementation thereof, including any amended or successor version of such directive); and
+ other similar, equivalent or corresponding rights throughout the world based on applicable law or treaty, and any national implementations thereof.
+
+2. Waiver. To the greatest extent permitted by, but not in contravention of, applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and unconditionally waives, abandons, and surrenders all of Affirmer's Copyright and Related Rights and associated claims and causes of action, whether now known or unknown (including existing as well as future claims and causes of action), in the Work (i) in all territories worldwide, (ii) for the maximum duration provided by applicable law or treaty (including future time extensions), (iii) in any current or future medium and for any number of copies, and (iv) for any purpose whatsoever, including without limitation commercial, advertising or promotional purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each member of the public at large and to the detriment of Affirmer's heirs and successors, fully intending that such Waiver shall not be subject to revocation, rescission, cancellation, termination, or any other legal or equitable action to disrupt the quiet enjoyment of the Work by the public as contemplated by Affirmer's express Statement of Purpose.
+
+3. Public License Fallback. Should any part of the Waiver for any reason be judged legally invalid or ineffective under applicable law, then the Waiver shall be preserved to the maximum extent permitted taking into account Affirmer's express Statement of Purpose. In addition, to the extent the Waiver is so judged Affirmer hereby grants to each affected person a royalty-free, non transferable, non sublicensable, non exclusive, irrevocable and unconditional license to exercise Affirmer's Copyright and Related Rights in the Work (i) in all territories worldwide, (ii) for the maximum duration provided by applicable law or treaty (including future time extensions), (iii) in any current or future medium and for any number of copies, and (iv) for any purpose whatsoever, including without limitation commercial, advertising or promotional purposes (the "License"). The License shall be deemed effective as of the date CC0 was applied by Affirmer to the Work. Should any part of the License for any reason be judged legally invalid or ineffective under applicable law, such partial invalidity or ineffectiveness shall not invalidate the remainder of the License, and in such case Affirmer hereby affirms that he or she will not (i) exercise any of his or her remaining Copyright and Related Rights in the Work or (ii) assert any associated claims and causes of action with respect to the Work, in either case contrary to Affirmer's express Statement of Purpose.
+
+4. Limitations and Disclaimers.
+
+ No trademark or patent rights held by Affirmer are waived, abandoned, surrendered, licensed or otherwise affected by this document.
+ Affirmer offers the Work as-is and makes no representations or warranties of any kind concerning the Work, express, implied, statutory or otherwise, including without limitation warranties of title, merchantability, fitness for a particular purpose, non infringement, or the absence of latent or other defects, accuracy, or the present or absence of errors, whether or not discoverable, all to the greatest extent permissible under applicable law.
+ Affirmer disclaims responsibility for clearing rights of other persons that may apply to the Work or any use thereof, including without limitation any person's Copyright and Related Rights in the Work. Further, Affirmer disclaims responsibility for obtaining any necessary consents, permissions or other rights required for any use of the Work.
+ Affirmer understands and acknowledges that Creative Commons is not a party to this document and has no duty or obligation with respect to this CC0 or use of the Work.
diff --git a/contrib/licenses/LGPL2 b/contrib/licenses/LGPL2
new file mode 100644
index 0000000..682170d
--- /dev/null
+++ b/contrib/licenses/LGPL2
@@ -0,0 +1,506 @@
+SPDX-License-Identifier: LGPL-2.1-or-later
+SPDX-URL: http://spdx.org/licenses/LGPL-2.1
+License-Text:
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+ When we speak of free software, we are referring to freedom of use,
+not price. Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the library's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+ <signature of Ty Coon>, 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
diff --git a/contrib/mempattern.c b/contrib/mempattern.c
new file mode 100644
index 0000000..6c237ea
--- /dev/null
+++ b/contrib/mempattern.c
@@ -0,0 +1,151 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <stdlib.h>
+
+#include "contrib/mempattern.h"
+#include "contrib/ucw/mempool.h"
+
+static void mm_nofree(void *p)
+{
+ /* nop */
+}
+
+static void *mm_malloc(void *ctx, size_t n)
+{
+ (void)ctx;
+ return malloc(n);
+}
+
+void *mm_alloc(knot_mm_t *mm, size_t size)
+{
+ if (mm) {
+ return mm->alloc(mm->ctx, size);
+ } else {
+ return malloc(size);
+ }
+}
+
+void *mm_calloc(knot_mm_t *mm, size_t nmemb, size_t size)
+{
+ if (nmemb == 0 || size == 0) {
+ return NULL;
+ }
+ if (mm) {
+ size_t total_size = nmemb * size;
+ if (total_size / nmemb != size) { // Overflow check
+ return NULL;
+ }
+ void *mem = mm_alloc(mm, total_size);
+ if (mem == NULL) {
+ return NULL;
+ }
+ return memset(mem, 0, total_size);
+ } else {
+ return calloc(nmemb, size);
+ }
+}
+
+void *mm_realloc(knot_mm_t *mm, void *what, size_t size, size_t prev_size)
+{
+ if (mm) {
+ void *p = mm->alloc(mm->ctx, size);
+ if (p == NULL) {
+ return NULL;
+ } else {
+ if (what) {
+ memcpy(p, what,
+ prev_size < size ? prev_size : size);
+ }
+ mm_free(mm, what);
+ return p;
+ }
+ } else {
+ return realloc(what, size);
+ }
+}
+
+char *mm_strdup(knot_mm_t *mm, const char *s)
+{
+ if (s == NULL) {
+ return NULL;
+ }
+ if (mm) {
+ size_t len = strlen(s) + 1;
+ void *mem = mm_alloc(mm, len);
+ if (mem == NULL) {
+ return NULL;
+ }
+ return memcpy(mem, s, len);
+ } else {
+ return strdup(s);
+ }
+}
+
+void mm_free(knot_mm_t *mm, void *what)
+{
+ if (mm) {
+ if (mm->free) {
+ mm->free(what);
+ }
+ } else {
+ free(what);
+ }
+}
+
+void mm_ctx_init(knot_mm_t *mm)
+{
+ mm->ctx = NULL;
+ mm->alloc = mm_malloc;
+ mm->free = free;
+}
+
+void mm_ctx_mempool(knot_mm_t *mm, size_t chunk_size)
+{
+ mm->ctx = mp_new(chunk_size);
+ mm->alloc = (knot_mm_alloc_t)mp_alloc;
+ mm->free = mm_nofree;
+}
+
+
+/* Code in addition to Knot's mempattern. */
+
+void *mm_malloc_aligned(void *ctx, size_t n)
+{
+ size_t alignment = (size_t)ctx;
+ void *res;
+ int err = posix_memalign(&res, alignment, n);
+ if (err == 0) {
+ return res;
+ } else {
+ assert(err == -1 && errno == ENOMEM);
+ return NULL;
+ }
+}
+
+knot_mm_t * mm_ctx_mempool2(size_t chunk_size)
+{
+ knot_mm_t pool_tmp;
+ mm_ctx_mempool(&pool_tmp, chunk_size);
+ knot_mm_t *pool = mm_alloc(&pool_tmp, sizeof(*pool));
+ if (!pool) {
+ mp_delete(pool_tmp.ctx);
+ return NULL;
+ }
+ memcpy(pool, &pool_tmp, sizeof(*pool));
+ return pool;
+}
+
diff --git a/contrib/mempattern.h b/contrib/mempattern.h
new file mode 100644
index 0000000..4db147a
--- /dev/null
+++ b/contrib/mempattern.h
@@ -0,0 +1,92 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+/*!
+ * \brief Memory allocation related functions.
+ */
+
+#pragma once
+
+#include <libknot/mm_ctx.h>
+#include "contrib/ucw/mempool.h"
+#include "lib/defines.h"
+#include <assert.h>
+#include <stdint.h>
+
+/*! \brief Default memory block size. */
+#define MM_DEFAULT_BLKSIZE 4096
+
+/*! \brief Allocs using 'mm' if any, uses system malloc() otherwise. */
+KR_EXPORT
+void *mm_alloc(knot_mm_t *mm, size_t size);
+
+/*! \brief Callocs using 'mm' if any, uses system calloc() otherwise. */
+void *mm_calloc(knot_mm_t *mm, size_t nmemb, size_t size);
+
+/*! \brief Reallocs using 'mm' if any, uses system realloc() otherwise. */
+KR_EXPORT
+void *mm_realloc(knot_mm_t *mm, void *what, size_t size, size_t prev_size);
+
+/*! \brief Strdups using 'mm' if any, uses system strdup() otherwise. */
+char *mm_strdup(knot_mm_t *mm, const char *s);
+
+/*! \brief Free using 'mm' if any, uses system free() otherwise. */
+KR_EXPORT
+void mm_free(knot_mm_t *mm, void *what);
+
+/*! \brief Initialize default memory allocation context. */
+void mm_ctx_init(knot_mm_t *mm);
+
+/*! \brief Memory pool context. */
+void mm_ctx_mempool(knot_mm_t *mm, size_t chunk_size);
+
+
+/* API in addition to Knot's mempattern. */
+
+/*! \brief New memory pool context, allocated on itself. */
+KR_EXPORT knot_mm_t * mm_ctx_mempool2(size_t chunk_size);
+
+/*! \brief Delete a memory pool. OK to call on a non-pool. */
+static inline void mm_ctx_delete(knot_mm_t *mm)
+{
+ /* The mp_alloc comparison bears a risk of missing the private symbol from knot. */
+ if (mm && mm->ctx && mm->alloc == (knot_mm_alloc_t)mp_alloc)
+ mp_delete(mm->ctx);
+}
+
+/*! \brief Readability: avoid const-casts in code. */
+static inline void free_const(const void *what)
+{
+ free((void *)what);
+}
+
+/*! \brief posix_memalign() wrapper. */
+void *mm_malloc_aligned(void *ctx, size_t n);
+
+/*! \brief Initialize mm with malloc+free with specified alignment (a power of two). */
+static inline void mm_ctx_init_aligned(knot_mm_t *mm, size_t alignment)
+{
+ assert(__builtin_popcount(alignment) == 1);
+ mm_ctx_init(mm);
+ mm->ctx = (uint8_t *)NULL + alignment; /*< roundabout to satisfy linters */
+ /* posix_memalign() doesn't allow alignment < sizeof(void*),
+ * and there's no point in using it for small values anyway,
+ * as plain malloc() guarantees at least max_align_t. */
+ if (alignment > sizeof(max_align_t)) {
+ mm->alloc = mm_malloc_aligned;
+ }
+}
+
diff --git a/contrib/meson.build b/contrib/meson.build
new file mode 100644
index 0000000..5d97e88
--- /dev/null
+++ b/contrib/meson.build
@@ -0,0 +1,28 @@
+# contrib
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+contrib_src = files([
+ 'ccan/asprintf/asprintf.c',
+ 'ccan/json/json.c',
+ 'ucw/mempool.c',
+ 'ucw/mempool-fmt.c',
+ 'mempattern.c',
+ 'murmurhash3/murmurhash3.c',
+ 'base32hex.c',
+ 'base64.c',
+ 'base64url.c'
+])
+
+contrib_inc = include_directories('.', '..')
+
+contrib_lib = static_library(
+ 'contrib',
+ contrib_src,
+ include_directories: contrib_inc,
+ dependencies: libknot,
+)
+
+contrib_dep = declare_dependency(
+ include_directories: contrib_inc,
+ link_with: contrib_lib,
+)
diff --git a/contrib/murmurhash3/LICENSE b/contrib/murmurhash3/LICENSE
new file mode 120000
index 0000000..fe25b01
--- /dev/null
+++ b/contrib/murmurhash3/LICENSE
@@ -0,0 +1 @@
+../licenses/CC0 \ No newline at end of file
diff --git a/contrib/murmurhash3/murmurhash3.c b/contrib/murmurhash3/murmurhash3.c
new file mode 100644
index 0000000..373c6ce
--- /dev/null
+++ b/contrib/murmurhash3/murmurhash3.c
@@ -0,0 +1,76 @@
+/* This is MurmurHash3. The original C++ code was placed in the public domain
+ * by its author, Austin Appleby.
+ *
+ * SPDX-License-Identifier: CC0-1.0
+ * Source: https://github.com/aappleby/smhasher/blob/master/src/MurmurHash3.cpp */
+
+#include "murmurhash3.h"
+#include "string.h"
+
+static inline uint32_t fmix(uint32_t h)
+{
+ h ^= h >> 16;
+ h *= 0x85ebca6b;
+ h ^= h >> 13;
+ h *= 0xc2b2ae35;
+ h ^= h >> 16;
+
+ return h;
+}
+
+static inline uint32_t rotl32(uint32_t x, int8_t r)
+{
+ return (x << r) | (x >> (32 - r));
+}
+
+uint32_t hash(const char* data, size_t len_)
+{
+ const int len = (int) len_;
+ const int nblocks = len / 4;
+
+ uint32_t h1 = 0xc062fb4a;
+
+ uint32_t c1 = 0xcc9e2d51;
+ uint32_t c2 = 0x1b873593;
+
+ //----------
+ // body
+
+ for(int i = 0; i < nblocks; ++i)
+ {
+ uint32_t k1;
+ memcpy(&k1, data + i * sizeof(k1), sizeof(k1));
+
+ k1 *= c1;
+ k1 = rotl32(k1, 15);
+ k1 *= c2;
+
+ h1 ^= k1;
+ h1 = rotl32(h1, 13);
+ h1 = h1*5+0xe6546b64;
+ }
+
+ //----------
+ // tail
+
+ const uint8_t * tail = (const uint8_t*)(data + nblocks*4);
+
+ uint32_t k1 = 0;
+
+ switch(len & 3)
+ {
+ case 3: k1 ^= tail[2] << 16;
+ case 2: k1 ^= tail[1] << 8;
+ case 1: k1 ^= tail[0];
+ k1 *= c1; k1 = rotl32(k1,15); k1 *= c2; h1 ^= k1;
+ }
+
+ //----------
+ // finalization
+
+ h1 ^= len;
+
+ h1 = fmix(h1);
+
+ return h1;
+}
diff --git a/contrib/murmurhash3/murmurhash3.h b/contrib/murmurhash3/murmurhash3.h
new file mode 100644
index 0000000..d849961
--- /dev/null
+++ b/contrib/murmurhash3/murmurhash3.h
@@ -0,0 +1,9 @@
+/* SPDX-License-Identifier: CC0-1.0
+ * Source: https://github.com/aappleby/smhasher/blob/master/src/MurmurHash3.cpp */
+
+#pragma once
+
+#include <stdlib.h>
+#include <stdint.h>
+
+uint32_t hash(const char* data, size_t len);
diff --git a/contrib/murmurhash3/murmurhash3.spdx b/contrib/murmurhash3/murmurhash3.spdx
new file mode 100644
index 0000000..7ce5a54
--- /dev/null
+++ b/contrib/murmurhash3/murmurhash3.spdx
@@ -0,0 +1,10 @@
+SPDXVersion: SPDX-2.1
+DataLicense: CC0-1.0
+SPDXID: SPDXRef-DOCUMENT
+DocumentName: ccan-json
+DocumentNamespace: http://spdx.org/spdxdocs/spdx-v2.1-d9b4db4c-062f-4add-89b6-f603224f5a2c
+
+PackageName: json
+PackageDownloadLocation: git+https://github.com/aappleby/smhasher.git@73e075b203d9c76cd1e20d6c8907c2983d653f33#MurmurHash3.cpp
+PackageOriginator: Person: Austin Appleby (aappleby@gmail.com)
+PackageLicenseDeclared: CC0-1.0
diff --git a/contrib/ucw/LICENSE b/contrib/ucw/LICENSE
new file mode 120000
index 0000000..0cb7f47
--- /dev/null
+++ b/contrib/ucw/LICENSE
@@ -0,0 +1 @@
+../licenses/LGPL2 \ No newline at end of file
diff --git a/contrib/ucw/alloc.h b/contrib/ucw/alloc.h
new file mode 100644
index 0000000..a6feadc
--- /dev/null
+++ b/contrib/ucw/alloc.h
@@ -0,0 +1,38 @@
+/*
+ * UCW Library -- Generic allocators
+ *
+ * (c) 2014 Martin Mares <mj@ucw.cz>
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ * Source: https://www.ucw.cz/libucw/
+ */
+
+#ifndef _UCW_ALLOC_H
+#define _UCW_ALLOC_H
+
+/**
+ * This structure describes a generic allocator. It provides pointers
+ * to three functions, which handle the actual (re)allocations.
+ **/
+struct ucw_allocator {
+ void * (*alloc)(struct ucw_allocator *alloc, size_t size);
+ void * (*realloc)(struct ucw_allocator *alloc, void *ptr, size_t old_size, size_t new_size);
+ void (*free)(struct ucw_allocator *alloc, void *ptr);
+};
+
+/* alloc-std.c */
+
+/**
+ * [[std]]
+ * This allocator uses <<basics:xmalloc()>>, <<basics:xrealloc()>> and <<basics:xfree()>>. The memory
+ * it allocates is left uninitialized.
+ **/
+extern struct ucw_allocator ucw_allocator_std;
+
+/**
+ * [[zeroing]]
+ * This allocator uses <<basics:xmalloc()>>, <<basics:xrealloc()>> and <<basics:xfree()>>. All memory
+ * is zeroed upon allocation.
+ **/
+extern struct ucw_allocator ucw_allocator_zeroed;
+
+#endif
diff --git a/contrib/ucw/config.h b/contrib/ucw/config.h
new file mode 100644
index 0000000..3c94104
--- /dev/null
+++ b/contrib/ucw/config.h
@@ -0,0 +1,58 @@
+/*
+ * UCW Library -- Configuration-Dependent Definitions
+ *
+ * (c) 1997--2012 Martin Mares <mj@ucw.cz>
+ * (c) 2006 Robert Spalek <robert@ucw.cz>
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ * Source: https://www.ucw.cz/libucw/
+ */
+
+#ifndef _UCW_CONFIG_H
+#define _UCW_CONFIG_H
+
+/* Default page size and pointer alignment */
+#ifndef CPU_PAGE_SIZE
+#define CPU_PAGE_SIZE 4096
+#endif
+#define CPU_STRUCT_ALIGN sizeof(void *)
+
+/* Tell libc we're going to use all extensions available */
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
+/* Types (based on standard C99 integers) */
+
+#include <stddef.h>
+#include <stdint.h>
+
+typedef uint8_t byte; /** Exactly 8 bits, unsigned **/
+typedef uint8_t u8; /** Exactly 8 bits, unsigned **/
+typedef int8_t s8; /** Exactly 8 bits, signed **/
+typedef uint16_t u16; /** Exactly 16 bits, unsigned **/
+typedef int16_t s16; /** Exactly 16 bits, signed **/
+typedef uint32_t u32; /** Exactly 32 bits, unsigned **/
+typedef int32_t s32; /** Exactly 32 bits, signed **/
+typedef uint64_t u64; /** Exactly 64 bits, unsigned **/
+typedef int64_t s64; /** Exactly 64 bits, signed **/
+
+
+#ifndef uint /* Redefining typedef is a C11 feature. */
+typedef unsigned int uint; /** A better pronounceable alias for `unsigned int` **/
+#define uint uint
+#endif
+
+typedef s64 timestamp_t; /** Milliseconds since an unknown epoch **/
+
+// FIXME: This should be removed soon
+typedef uint uns; /** Backwards compatible alias for `uint' ***/
+
+#ifdef CONFIG_UCW_LARGE_FILES
+typedef s64 ucw_off_t; /** File position (either 32- or 64-bit, depending on `CONFIG_UCW_LARGE_FILES`). **/
+#else
+typedef s32 ucw_off_t;
+#endif
+
+#endif
diff --git a/contrib/ucw/lib.h b/contrib/ucw/lib.h
new file mode 100644
index 0000000..89b3a20
--- /dev/null
+++ b/contrib/ucw/lib.h
@@ -0,0 +1,125 @@
+/*
+ * The UCW Library -- Miscellaneous Functions
+ *
+ * (c) 1997--2014 Martin Mares <mj@ucw.cz>
+ * (c) 2005--2014 Tomas Valla <tom@ucw.cz>
+ * (c) 2006 Robert Spalek <robert@ucw.cz>
+ * (c) 2007 Pavel Charvat <pchar@ucw.cz>
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ * Source: https://www.ucw.cz/libucw/
+ */
+
+#ifndef _UCW_LIB_H
+#define _UCW_LIB_H
+
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdlib.h>
+
+#ifdef CONFIG_UCW_CLEAN_ABI
+#define assert_failed ucw_assert_failed
+#define assert_failed_msg ucw_assert_failed_msg
+#define assert_failed_noinfo ucw_assert_failed_noinfo
+#define big_alloc ucw_big_alloc
+#define big_alloc_zero ucw_big_alloc_zero
+#define big_free ucw_big_free
+#define die ucw_die
+#define log_die_hook ucw_log_die_hook
+#define log_file ucw_log_file
+#define log_fork ucw_log_fork
+#define log_init ucw_log_init
+#define log_pid ucw_log_pid
+#define log_title ucw_log_title
+#define msg ucw_msg
+#define page_alloc ucw_page_alloc
+#define page_alloc_zero ucw_page_alloc_zero
+#define page_free ucw_page_free
+#define page_realloc ucw_page_realloc
+#define random_max ucw_random_max
+#define random_max_u64 ucw_random_max_u64
+#define random_u32 ucw_random_u32
+#define random_u64 ucw_random_u64
+#define vdie ucw_vdie
+#define vmsg ucw_vmsg
+#define xfree ucw_xfree
+#define xmalloc ucw_xmalloc
+#define xmalloc_zero ucw_xmalloc_zero
+#define xrealloc ucw_xrealloc
+#define xstrdup ucw_xstrdup
+#endif
+
+/*** === Macros for handling structures, offsets and alignment ***/
+
+#define CHECK_PTR_TYPE(x, type) ((x)-(type)(x) + (type)(x)) /** Check that a pointer @x is of type @type. Fail compilation if not. **/
+#define PTR_TO(s, i) &((s*)0)->i /** Return OFFSETOF() in form of a pointer. **/
+#define OFFSETOF(s, i) ((uint)offsetof(s, i)) /** Offset of item @i from the start of structure @s **/
+#define SKIP_BACK(s, i, p) ((s *)((char *)p - OFFSETOF(s, i))) /** Given a pointer @p to item @i of structure @s, return a pointer to the start of the struct. **/
+
+/** Align an integer @s to the nearest higher multiple of @a (which should be a power of two) **/
+#define ALIGN_TO(s, a) (((s)+a-1)&~(a-1))
+
+/** Align a pointer @p to the nearest higher multiple of @s. **/
+#define ALIGN_PTR(p, s) ((uintptr_t)(p) % (s) ? (typeof(p))((uintptr_t)(p) + (s) - (uintptr_t)(p) % (s)) : (p))
+
+#define UNALIGNED_PART(ptr, type) (((uintptr_t) (ptr)) % sizeof(type))
+
+/*** === Other utility macros ***/
+
+#define MIN(a,b) (((a)<(b))?(a):(b)) /** Minimum of two numbers **/
+#define MAX(a,b) (((a)>(b))?(a):(b)) /** Maximum of two numbers **/
+#define CLAMP(x,min,max) ({ typeof(x) _t=x; (_t < min) ? min : (_t > max) ? max : _t; }) /** Clip a number @x to interval [@min,@max] **/
+#define ABS(x) ((x) < 0 ? -(x) : (x)) /** Absolute value **/
+#define ARRAY_SIZE(a) (sizeof(a)/sizeof(*(a))) /** The number of elements of an array **/
+#define STRINGIFY(x) #x /** Convert macro parameter to a string **/
+#define STRINGIFY_EXPANDED(x) STRINGIFY(x) /** Convert an expanded macro parameter to a string **/
+#define GLUE(x,y) x##y /** Glue two tokens together **/
+#define GLUE_(x,y) x##_##y /** Glue two tokens together, separating them by an underscore **/
+
+#define COMPARE(x,y) do { if ((x)<(y)) return -1; if ((x)>(y)) return 1; } while(0) /** Numeric comparison function for qsort() **/
+#define REV_COMPARE(x,y) COMPARE(y,x) /** Reverse numeric comparison **/
+#define COMPARE_LT(x,y) do { if ((x)<(y)) return 1; if ((x)>(y)) return 0; } while(0)
+#define COMPARE_GT(x,y) COMPARE_LT(y,x)
+
+#define ROL(x, bits) (((x) << (bits)) | ((uint)(x) >> (sizeof(uint)*8 - (bits)))) /** Bitwise rotation of an unsigned int to the left **/
+#define ROR(x, bits) (((uint)(x) >> (bits)) | ((x) << (sizeof(uint)*8 - (bits)))) /** Bitwise rotation of an unsigned int to the right **/
+
+/*** === Shortcuts for GCC Extensions ***/
+
+#ifdef __GNUC__
+
+#include "ccan/compiler/compiler.h"
+#define FORMAT_CHECK(x,y,z) __attribute__((format(x,y,z))) /** Checking of printf-like format strings **/
+#define likely(x) __builtin_expect((x),1) /** Use `if (likely(@x))` if @x is almost always true **/
+#define unlikely(x) __builtin_expect((x),0) /** Use `if (unlikely(@x))` to hint that @x is almost always false **/
+
+#if __GNUC__ >= 4 || __GNUC__ == 3 && __GNUC_MINOR__ >= 3
+#define ALWAYS_INLINE inline __attribute__((always_inline)) /** Forcibly inline **/
+#define NO_INLINE __attribute__((noinline)) /** Forcibly uninline **/
+#else
+#define ALWAYS_INLINE inline
+#endif
+
+#if __GNUC__ >= 4
+#define LIKE_MALLOC __attribute__((malloc)) /** Function returns a "new" pointer **/
+#define SENTINEL_CHECK __attribute__((sentinel)) /** The last argument must be NULL **/
+#else
+#define LIKE_MALLOC
+#define SENTINEL_CHECK
+#endif
+
+#else
+#error This program requires the GNU C compiler.
+#endif
+
+/***
+ * [[logging]]
+ *
+ * === Basic logging functions (see <<log:,Logging>> and <ucw/log.h> for more)
+ ***/
+
+#define DBG(x, ...) do { } while(0)
+#define DBG_SPOT do { } while(0)
+#define ASSERT(x)
+
+#endif
diff --git a/contrib/ucw/libucw.spdx b/contrib/ucw/libucw.spdx
new file mode 100644
index 0000000..e18b2ea
--- /dev/null
+++ b/contrib/ucw/libucw.spdx
@@ -0,0 +1,10 @@
+SPDXVersion: SPDX-2.1
+DataLicense: CC0-1.0
+SPDXID: SPDXRef-DOCUMENT
+DocumentName: libucw
+DocumentNamespace: http://spdx.org/spdxdocs/spdx-v2.1-c3d39e26-6b71-46d4-88ea-e52750932ff3
+
+PackageName: libucw
+PackageDownloadLocation: git://git.ucw.cz/libucw.git@f1bde7104b04d5254d1d1d7dcc8de790a43a416f#ucw/
+PackageOriginator: Organization: United Computer Wizards
+PackageLicenseDeclared: LGPL-2.1-or-later
diff --git a/contrib/ucw/mempool-fmt.c b/contrib/ucw/mempool-fmt.c
new file mode 100644
index 0000000..22f3a50
--- /dev/null
+++ b/contrib/ucw/mempool-fmt.c
@@ -0,0 +1,99 @@
+/*
+ * UCW Library -- Memory Pools (Formatting)
+ *
+ * (c) 2005 Martin Mares <mj@ucw.cz>
+ * (c) 2007 Pavel Charvat <pchar@ucw.cz>
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ * Source: https://www.ucw.cz/libucw/
+ */
+
+#include <ucw/lib.h>
+#include <ucw/mempool.h>
+
+#include <stdio.h>
+#include <string.h>
+
+/* FIXME: migrate to Knot DNS version of mempools. */
+#pragma GCC diagnostic ignored "-Wpointer-arith"
+
+static char *
+mp_vprintf_at(struct mempool *mp, size_t ofs, const char *fmt, va_list args)
+{
+ char *ret = mp_grow(mp, ofs + 1) + ofs;
+ va_list args2;
+ va_copy(args2, args);
+ int cnt = vsnprintf(ret, mp_avail(mp) - ofs, fmt, args2);
+ va_end(args2);
+ if (cnt < 0)
+ {
+ /* Our C library doesn't support C99 return value of vsnprintf, so we need to iterate */
+ do
+ {
+ ret = mp_expand(mp) + ofs;
+ va_copy(args2, args);
+ cnt = vsnprintf(ret, mp_avail(mp) - ofs, fmt, args2);
+ va_end(args2);
+ }
+ while (cnt < 0);
+ }
+ else if ((uint)cnt >= mp_avail(mp) - ofs)
+ {
+ ret = mp_grow(mp, ofs + cnt + 1) + ofs;
+ va_copy(args2, args);
+ vsnprintf(ret, cnt + 1, fmt, args2);
+ va_end(args2);
+ }
+ mp_end(mp, ret + cnt + 1);
+ return ret - ofs;
+}
+
+char *
+mp_vprintf(struct mempool *mp, const char *fmt, va_list args)
+{
+ mp_start(mp, 1);
+ return mp_vprintf_at(mp, 0, fmt, args);
+}
+
+char *
+mp_printf(struct mempool *p, const char *fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+ char *res = mp_vprintf(p, fmt, args);
+ va_end(args);
+ return res;
+}
+
+char *
+mp_vprintf_append(struct mempool *mp, char *ptr, const char *fmt, va_list args)
+{
+ size_t ofs = mp_open(mp, ptr);
+ ASSERT(ofs && !ptr[ofs - 1]);
+ return mp_vprintf_at(mp, ofs - 1, fmt, args);
+}
+
+char *
+mp_printf_append(struct mempool *mp, char *ptr, const char *fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+ char *res = mp_vprintf_append(mp, ptr, fmt, args);
+ va_end(args);
+ return res;
+}
+
+#ifdef TEST
+
+int main(void)
+{
+ struct mempool *mp = mp_new(64);
+ char *x = mp_printf(mp, "<Hello, %s!>", "World");
+ fputs(x, stdout);
+ x = mp_printf_append(mp, x, "<Appended>");
+ fputs(x, stdout);
+ x = mp_printf(mp, "<Hello, %50s!>\n", "World");
+ fputs(x, stdout);
+ return 0;
+}
+
+#endif
diff --git a/contrib/ucw/mempool.c b/contrib/ucw/mempool.c
new file mode 100644
index 0000000..314b58e
--- /dev/null
+++ b/contrib/ucw/mempool.c
@@ -0,0 +1,601 @@
+/*
+ * UCW Library -- Memory Pools (One-Time Allocation)
+ *
+ * (c) 1997--2014 Martin Mares <mj@ucw.cz>
+ * (c) 2007--2015 Pavel Charvat <pchar@ucw.cz>
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ * Source: https://www.ucw.cz/libucw/
+ */
+
+#undef LOCAL_DEBUG
+
+#include <ucw/config.h>
+#include <ucw/lib.h>
+#include <ucw/alloc.h>
+#include <ucw/mempool.h>
+
+#include <string.h>
+#include <stdlib.h>
+
+/* FIXME: migrate to Knot DNS version of mempools. */
+#pragma GCC diagnostic ignored "-Wpointer-arith"
+
+#define MP_CHUNK_TAIL ALIGN_TO(sizeof(struct mempool_chunk), CPU_STRUCT_ALIGN)
+#define MP_SIZE_MAX (SIZE_MAX - MP_CHUNK_TAIL - CPU_PAGE_SIZE)
+
+struct mempool_chunk {
+#ifdef CONFIG_DEBUG
+ struct mempool *pool; // Can be useful when analysing coredump for memory leaks
+#endif
+ struct mempool_chunk *next;
+ size_t size;
+};
+
+static size_t
+mp_align_size(size_t size)
+{
+#ifdef CONFIG_UCW_POOL_IS_MMAP
+ size = MAX(size, 64 + MP_CHUNK_TAIL);
+ return ALIGN_TO(size, CPU_PAGE_SIZE) - MP_CHUNK_TAIL;
+#else
+ return ALIGN_TO(size, CPU_STRUCT_ALIGN);
+#endif
+}
+
+static void *mp_allocator_alloc(struct ucw_allocator *a, size_t size)
+{
+ struct mempool *mp = (struct mempool *) a;
+ return mp_alloc_fast(mp, size);
+}
+
+static void *mp_allocator_realloc(struct ucw_allocator *a, void *ptr, size_t old_size, size_t new_size)
+{
+ if (new_size <= old_size)
+ return ptr;
+
+ /*
+ * In the future, we might want to do something like mp_realloc(),
+ * but we have to check that it is indeed the last block in the pool.
+ */
+ struct mempool *mp = (struct mempool *) a;
+ void *new = mp_alloc_fast(mp, new_size);
+ memcpy(new, ptr, old_size);
+ return new;
+}
+
+static void mp_allocator_free(struct ucw_allocator *a UNUSED, void *ptr UNUSED)
+{
+ // Does nothing
+}
+
+void
+mp_init(struct mempool *pool, size_t chunk_size)
+{
+ chunk_size = mp_align_size(MAX(sizeof(struct mempool), chunk_size));
+ *pool = (struct mempool) {
+ .allocator = {
+ .alloc = mp_allocator_alloc,
+ .realloc = mp_allocator_realloc,
+ .free = mp_allocator_free,
+ },
+ .chunk_size = chunk_size,
+ .threshold = chunk_size >> 1,
+ .last_big = &pool->last_big
+ };
+}
+
+static void *
+mp_new_big_chunk(struct mempool *pool, size_t size)
+{
+ struct mempool_chunk *chunk;
+ chunk = malloc(size + MP_CHUNK_TAIL);
+ if (!chunk)
+ return NULL;
+ chunk = (struct mempool_chunk *)((char *)chunk + size);
+ chunk->size = size;
+ if (pool)
+ pool->total_size += size + MP_CHUNK_TAIL;
+ return chunk;
+}
+
+static void
+mp_free_big_chunk(struct mempool *pool, struct mempool_chunk *chunk)
+{
+ pool->total_size -= chunk->size + MP_CHUNK_TAIL;
+ free((void *)chunk - chunk->size);
+}
+
+static void *
+mp_new_chunk(struct mempool *pool, size_t size)
+{
+#ifdef CONFIG_UCW_POOL_IS_MMAP
+ struct mempool_chunk *chunk;
+ chunk = page_alloc(size + MP_CHUNK_TAIL) + size;
+ chunk->size = size;
+ if (pool)
+ pool->total_size += size + MP_CHUNK_TAIL;
+ return chunk;
+#else
+ return mp_new_big_chunk(pool, size);
+#endif
+}
+
+static void
+mp_free_chunk(struct mempool *pool, struct mempool_chunk *chunk)
+{
+#ifdef CONFIG_UCW_POOL_IS_MMAP
+ pool->total_size -= chunk->size + MP_CHUNK_TAIL;
+ page_free((void *)chunk - chunk->size, chunk->size + MP_CHUNK_TAIL);
+#else
+ mp_free_big_chunk(pool, chunk);
+#endif
+}
+
+struct mempool *
+mp_new(size_t chunk_size)
+{
+ chunk_size = mp_align_size(MAX(sizeof(struct mempool), chunk_size));
+ struct mempool_chunk *chunk = mp_new_chunk(NULL, chunk_size);
+ struct mempool *pool = (void *)chunk - chunk_size;
+ DBG("Creating mempool %p with %u bytes long chunks", pool, chunk_size);
+ chunk->next = NULL;
+#ifdef CONFIG_DEBUG
+ chunk->pool = pool;
+#endif
+ *pool = (struct mempool) {
+ .allocator = {
+ .alloc = mp_allocator_alloc,
+ .realloc = mp_allocator_realloc,
+ .free = mp_allocator_free,
+ },
+ .state = { .free = { chunk_size - sizeof(*pool) }, .last = { chunk } },
+ .chunk_size = chunk_size,
+ .threshold = chunk_size >> 1,
+ .last_big = &pool->last_big,
+ .total_size = chunk->size + MP_CHUNK_TAIL,
+ };
+ return pool;
+}
+
+static void
+mp_free_chain(struct mempool *pool, struct mempool_chunk *chunk)
+{
+ while (chunk)
+ {
+ struct mempool_chunk *next = chunk->next;
+ mp_free_chunk(pool, chunk);
+ chunk = next;
+ }
+}
+
+static void
+mp_free_big_chain(struct mempool *pool, struct mempool_chunk *chunk)
+{
+ while (chunk)
+ {
+ struct mempool_chunk *next = chunk->next;
+ mp_free_big_chunk(pool, chunk);
+ chunk = next;
+ }
+}
+
+void
+mp_delete(struct mempool *pool)
+{
+ DBG("Deleting mempool %p", pool);
+ mp_free_big_chain(pool, pool->state.last[1]);
+ mp_free_chain(pool, pool->unused);
+ mp_free_chain(pool, pool->state.last[0]); // can contain the mempool structure
+}
+
+void
+mp_flush(struct mempool *pool)
+{
+ mp_free_big_chain(pool, pool->state.last[1]);
+ struct mempool_chunk *chunk, *next;
+ for (chunk = pool->state.last[0]; chunk && (void *)chunk - chunk->size != pool; chunk = next)
+ {
+ next = chunk->next;
+ chunk->next = pool->unused;
+ pool->unused = chunk;
+ }
+ pool->state.last[0] = chunk;
+ pool->state.free[0] = chunk ? chunk->size - sizeof(*pool) : 0;
+ pool->state.last[1] = NULL;
+ pool->state.free[1] = 0;
+ pool->state.next = NULL;
+ pool->last_big = &pool->last_big;
+}
+
+static void
+mp_stats_chain(struct mempool *pool, struct mempool_chunk *chunk, struct mempool_stats *stats, uint idx)
+{
+ while (chunk)
+ {
+ stats->chain_size[idx] += chunk->size + MP_CHUNK_TAIL;
+ stats->chain_count[idx]++;
+ if (idx < 2)
+ {
+ stats->used_size += chunk->size;
+ if ((byte *)pool == (byte *)chunk - chunk->size)
+ stats->used_size -= sizeof(*pool);
+ }
+ chunk = chunk->next;
+ }
+ stats->total_size += stats->chain_size[idx];
+}
+
+void
+mp_stats(struct mempool *pool, struct mempool_stats *stats)
+{
+ bzero(stats, sizeof(*stats));
+ mp_stats_chain(pool, pool->state.last[0], stats, 0);
+ mp_stats_chain(pool, pool->state.last[1], stats, 1);
+ mp_stats_chain(pool, pool->unused, stats, 2);
+ stats->used_size -= pool->state.free[0] + pool->state.free[1];
+ ASSERT(stats->total_size == pool->total_size);
+ ASSERT(stats->used_size <= stats->total_size);
+}
+
+u64
+mp_total_size(struct mempool *pool)
+{
+ return pool->total_size;
+}
+
+void
+mp_shrink(struct mempool *pool, u64 min_total_size)
+{
+ while (1)
+ {
+ struct mempool_chunk *chunk = pool->unused;
+ if (!chunk || pool->total_size - (chunk->size + MP_CHUNK_TAIL) < min_total_size)
+ break;
+ pool->unused = chunk->next;
+ mp_free_chunk(pool, chunk);
+ }
+}
+
+void *
+mp_alloc_internal(struct mempool *pool, size_t size)
+{
+ struct mempool_chunk *chunk;
+ if (size <= pool->threshold)
+ {
+ pool->idx = 0;
+ if (pool->unused)
+ {
+ chunk = pool->unused;
+ pool->unused = chunk->next;
+ }
+ else
+ {
+ chunk = mp_new_chunk(pool, pool->chunk_size);
+#ifdef CONFIG_DEBUG
+ chunk->pool = pool;
+#endif
+ }
+ chunk->next = pool->state.last[0];
+ pool->state.last[0] = chunk;
+ pool->state.free[0] = pool->chunk_size - size;
+ return (void *)chunk - pool->chunk_size;
+ }
+ else if (likely(size <= MP_SIZE_MAX))
+ {
+ pool->idx = 1;
+ size_t aligned = ALIGN_TO(size, CPU_STRUCT_ALIGN);
+ chunk = mp_new_big_chunk(pool, aligned);
+ chunk->next = pool->state.last[1];
+#ifdef CONFIG_DEBUG
+ chunk->pool = pool;
+#endif
+ pool->state.last[1] = chunk;
+ pool->state.free[1] = aligned - size;
+ return pool->last_big = (void *)chunk - aligned;
+ }
+ else
+ return NULL;
+}
+
+void *
+mp_alloc(struct mempool *pool, size_t size)
+{
+ return mp_alloc_fast(pool, size);
+}
+
+void *
+mp_alloc_noalign(struct mempool *pool, size_t size)
+{
+ return mp_alloc_fast_noalign(pool, size);
+}
+
+void *
+mp_alloc_zero(struct mempool *pool, size_t size)
+{
+ void *ptr = mp_alloc_fast(pool, size);
+ bzero(ptr, size);
+ return ptr;
+}
+
+void *
+mp_start_internal(struct mempool *pool, size_t size)
+{
+ void *ptr = mp_alloc_internal(pool, size);
+ if (!ptr)
+ return NULL;
+ pool->state.free[pool->idx] += size;
+ return ptr;
+}
+
+void *
+mp_start(struct mempool *pool, size_t size)
+{
+ return mp_start_fast(pool, size);
+}
+
+void *
+mp_start_noalign(struct mempool *pool, size_t size)
+{
+ return mp_start_fast_noalign(pool, size);
+}
+
+void *
+mp_grow_internal(struct mempool *pool, size_t size)
+{
+ if (unlikely(size > MP_SIZE_MAX))
+ return NULL;
+ size_t avail = mp_avail(pool);
+ void *ptr = mp_ptr(pool);
+ if (pool->idx)
+ {
+ size_t amortized = likely(avail <= MP_SIZE_MAX / 2) ? avail * 2 : MP_SIZE_MAX;
+ amortized = MAX(amortized, size);
+ amortized = ALIGN_TO(amortized, CPU_STRUCT_ALIGN);
+ struct mempool_chunk *chunk = pool->state.last[1], *next = chunk->next;
+ pool->total_size = pool->total_size - chunk->size + amortized;
+ void *nptr = realloc(ptr, amortized + MP_CHUNK_TAIL);
+ if (!nptr)
+ return NULL;
+ ptr = nptr;
+ chunk = ptr + amortized;
+ chunk->next = next;
+ chunk->size = amortized;
+ pool->state.last[1] = chunk;
+ pool->state.free[1] = amortized;
+ pool->last_big = ptr;
+ return ptr;
+ }
+ else
+ {
+ void *p = mp_start_internal(pool, size);
+ memcpy(p, ptr, avail);
+ return p;
+ }
+}
+
+size_t
+mp_open(struct mempool *pool, void *ptr)
+{
+ return mp_open_fast(pool, ptr);
+}
+
+void *
+mp_realloc(struct mempool *pool, void *ptr, size_t size)
+{
+ return mp_realloc_fast(pool, ptr, size);
+}
+
+void *
+mp_realloc_zero(struct mempool *pool, void *ptr, size_t size)
+{
+ size_t old_size = mp_open_fast(pool, ptr);
+ ptr = mp_grow(pool, size);
+ if (size > old_size)
+ bzero(ptr + old_size, size - old_size);
+ mp_end(pool, ptr + size);
+ return ptr;
+}
+
+void *
+mp_spread_internal(struct mempool *pool, void *p, size_t size)
+{
+ void *old = mp_ptr(pool);
+ void *new = mp_grow_internal(pool, p-old+size);
+ if (!new) {
+ return NULL;
+ }
+ return p-old+new;
+}
+
+void
+mp_restore(struct mempool *pool, struct mempool_state *state)
+{
+ struct mempool_chunk *chunk, *next;
+ struct mempool_state s = *state;
+ for (chunk = pool->state.last[0]; chunk != s.last[0]; chunk = next)
+ {
+ next = chunk->next;
+ chunk->next = pool->unused;
+ pool->unused = chunk;
+ }
+ for (chunk = pool->state.last[1]; chunk != s.last[1]; chunk = next)
+ {
+ next = chunk->next;
+ mp_free_big_chunk(pool, chunk);
+ }
+ pool->state = s;
+ pool->last_big = &pool->last_big;
+}
+
+struct mempool_state *
+mp_push(struct mempool *pool)
+{
+ struct mempool_state state = pool->state;
+ struct mempool_state *p = mp_alloc_fast(pool, sizeof(*p));
+ *p = state;
+ pool->state.next = p;
+ return p;
+}
+
+void
+mp_pop(struct mempool *pool)
+{
+ ASSERT(pool->state.next);
+ mp_restore(pool, pool->state.next);
+}
+
+#ifdef TEST
+
+#include <ucw/getopt.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+
+static void
+fill(byte *ptr, uint len, uint magic)
+{
+ while (len--)
+ *ptr++ = (magic++ & 255);
+}
+
+static void
+check(byte *ptr, uint len, uint magic, uint align)
+{
+ ASSERT(!((uintptr_t)ptr & (align - 1)));
+ while (len--)
+ if (*ptr++ != (magic++ & 255))
+ ASSERT(0);
+}
+
+int main(int argc, char **argv)
+{
+ srand(time(NULL));
+ log_init(argv[0]);
+ cf_def_file = NULL;
+ if (cf_getopt(argc, argv, CF_SHORT_OPTS, CF_NO_LONG_OPTS, NULL) >= 0 || argc != optind)
+ die("Invalid usage");
+
+ uint max = 1000, n = 0, m = 0, can_realloc = 0;
+ void *ptr[max];
+ struct mempool_state *state[max];
+ uint len[max], num[max], align[max];
+ struct mempool *mp = mp_new(128), mp_static;
+
+ for (uint i = 0; i < 5000; i++)
+ {
+ for (uint j = 0; j < n; j++)
+ check(ptr[j], len[j], j, align[j]);
+#if 0
+ DBG("free_small=%u free_big=%u idx=%u chunk_size=%u last_big=%p", mp->state.free[0], mp->state.free[1], mp->idx, mp->chunk_size, mp->last_big);
+ for (struct mempool_chunk *ch = mp->state.last[0]; ch; ch = ch->next)
+ DBG("small %p %p %p %d", (byte *)ch - ch->size, ch, ch + 1, ch->size);
+ for (struct mempool_chunk *ch = mp->state.last[1]; ch; ch = ch->next)
+ DBG("big %p %p %p %d", (byte *)ch - ch->size, ch, ch + 1, ch->size);
+#endif
+ int r = random_max(100);
+ if ((r -= 1) < 0)
+ {
+ DBG("flush");
+ mp_flush(mp);
+ n = m = 0;
+ }
+ else if ((r -= 1) < 0)
+ {
+ DBG("delete & new");
+ mp_delete(mp);
+ if (random_max(2))
+ mp = mp_new(random_max(0x1000) + 1);
+ else
+ mp = &mp_static, mp_init(mp, random_max(512) + 1);
+ n = m = 0;
+ }
+ else if (n < max && (r -= 30) < 0)
+ {
+ len[n] = random_max(0x2000);
+ DBG("alloc(%u)", len[n]);
+ align[n] = random_max(2) ? CPU_STRUCT_ALIGN : 1;
+ ptr[n] = (align[n] == 1) ? mp_alloc_fast_noalign(mp, len[n]) : mp_alloc_fast(mp, len[n]);
+ DBG(" -> (%p)", ptr[n]);
+ fill(ptr[n], len[n], n);
+ n++;
+ can_realloc = 1;
+ }
+ else if (n < max && (r -= 20) < 0)
+ {
+ len[n] = random_max(0x2000);
+ DBG("start(%u)", len[n]);
+ align[n] = random_max(2) ? CPU_STRUCT_ALIGN : 1;
+ ptr[n] = (align[n] == 1) ? mp_start_fast_noalign(mp, len[n]) : mp_start_fast(mp, len[n]);
+ DBG(" -> (%p)", ptr[n]);
+ fill(ptr[n], len[n], n);
+ n++;
+ can_realloc = 1;
+ goto grow;
+ }
+ else if (can_realloc && n && (r -= 10) < 0)
+ {
+ if (mp_open(mp, ptr[n - 1]) != len[n - 1])
+ ASSERT(0);
+grow:
+ {
+ uint k = n - 1;
+ for (uint i = random_max(4); i--; )
+ {
+ uint l = len[k];
+ len[k] = random_max(0x2000);
+ DBG("grow(%u)", len[k]);
+ ptr[k] = mp_grow(mp, len[k]);
+ DBG(" -> (%p)", ptr[k]);
+ check(ptr[k], MIN(l, len[k]), k, align[k]);
+ fill(ptr[k], len[k], k);
+ }
+ mp_end(mp, ptr[k] + len[k]);
+ }
+ }
+ else if (can_realloc && n && (r -= 20) < 0)
+ {
+ uint i = n - 1, l = len[i];
+ DBG("realloc(%p, %u)", ptr[i], len[i]);
+ ptr[i] = mp_realloc(mp, ptr[i], len[i] = random_max(0x2000));
+ DBG(" -> (%p, %u)", ptr[i], len[i]);
+ check(ptr[i], MIN(len[i], l), i, align[i]);
+ fill(ptr[i], len[i], i);
+ }
+ else if (m < max && (r -= 5) < 0)
+ {
+ DBG("push(%u)", m);
+ num[m] = n;
+ state[m++] = mp_push(mp);
+ can_realloc = 0;
+ }
+ else if (m && (r -= 2) < 0)
+ {
+ m--;
+ DBG("pop(%u)", m);
+ mp_pop(mp);
+ n = num[m];
+ can_realloc = 0;
+ }
+ else if (m && (r -= 1) < 0)
+ {
+ uint i = random_max(m);
+ DBG("restore(%u)", i);
+ mp_restore(mp, state[i]);
+ n = num[m = i];
+ can_realloc = 0;
+ }
+ else if (can_realloc && n && (r -= 5) < 0)
+ ASSERT(mp_size(mp, ptr[n - 1]) == len[n - 1]);
+ else
+ {
+ struct mempool_stats stats;
+ mp_stats(mp, &stats);
+ }
+ }
+
+ mp_delete(mp);
+ return 0;
+}
+
+#endif
diff --git a/contrib/ucw/mempool.h b/contrib/ucw/mempool.h
new file mode 100644
index 0000000..0315138
--- /dev/null
+++ b/contrib/ucw/mempool.h
@@ -0,0 +1,572 @@
+/*
+ * UCW Library -- Memory Pools
+ *
+ * (c) 1997--2015 Martin Mares <mj@ucw.cz>
+ * (c) 2007 Pavel Charvat <pchar@ucw.cz>
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ * Source: https://www.ucw.cz/libucw/
+ */
+
+#ifndef _UCW_POOLS_H
+#define _UCW_POOLS_H
+
+#include "lib/defines.h"
+#include <ucw/alloc.h>
+#include <ucw/config.h>
+#include <ucw/lib.h>
+#include <string.h>
+
+#ifdef CONFIG_UCW_CLEAN_ABI
+#define mp_alloc ucw_mp_alloc
+#define mp_alloc_internal ucw_mp_alloc_internal
+#define mp_alloc_noalign ucw_mp_alloc_noalign
+#define mp_alloc_zero ucw_mp_alloc_zero
+#define mp_delete ucw_mp_delete
+#define mp_flush ucw_mp_flush
+#define mp_grow_internal ucw_mp_grow_internal
+#define mp_init ucw_mp_init
+#define mp_memdup ucw_mp_memdup
+#define mp_multicat ucw_mp_multicat
+#define mp_new ucw_mp_new
+#define mp_open ucw_mp_open
+#define mp_pop ucw_mp_pop
+#define mp_printf ucw_mp_printf
+#define mp_printf_append ucw_mp_printf_append
+#define mp_push ucw_mp_push
+#define mp_realloc ucw_mp_realloc
+#define mp_realloc_zero ucw_mp_realloc_zero
+#define mp_restore ucw_mp_restore
+#define mp_shrink ucw_mp_shrink
+#define mp_spread_internal ucw_mp_spread_internal
+#define mp_start ucw_mp_start
+#define mp_start_internal ucw_mp_start_internal
+#define mp_start_noalign ucw_mp_start_noalign
+#define mp_stats ucw_mp_stats
+#define mp_str_from_mem ucw_mp_str_from_mem
+#define mp_strdup ucw_mp_strdup
+#define mp_strjoin ucw_mp_strjoin
+#define mp_total_size ucw_mp_total_size
+#define mp_vprintf ucw_mp_vprintf
+#define mp_vprintf_append ucw_mp_vprintf_append
+#endif
+
+/***
+ * [[defs]]
+ * Definitions
+ * -----------
+ ***/
+
+/**
+ * Memory pool state (see @mp_push(), ...).
+ * You should use this one as an opaque handle only, the insides are internal.
+ **/
+struct mempool_state {
+ size_t free[2];
+ void *last[2];
+ struct mempool_state *next;
+};
+
+/**
+ * Memory pool.
+ * You should use this one as an opaque handle only, the insides are internal.
+ **/
+struct mempool {
+ struct ucw_allocator allocator; // This must be the first element
+ struct mempool_state state;
+ void *unused, *last_big;
+ size_t chunk_size, threshold;
+ uint idx;
+ u64 total_size;
+};
+
+struct mempool_stats { /** Mempool statistics. See @mp_stats(). **/
+ u64 total_size; /* Real allocated size in bytes */
+ u64 used_size; /* Estimated size allocated from mempool to application */
+ uint chain_count[3]; /* Number of allocated chunks in small/big/unused chains */
+ u64 chain_size[3]; /* Size of allocated chunks in small/big/unused chains */
+};
+
+/***
+ * [[basic]]
+ * Basic manipulation
+ * ------------------
+ ***/
+
+/**
+ * Initialize a given mempool structure.
+ * @chunk_size must be in the interval `[1, SIZE_MAX / 2]`.
+ * It will allocate memory by this large chunks and take
+ * memory to satisfy requests from them.
+ *
+ * Memory pools can be treated as <<trans:respools,resources>>, see <<trans:res_mempool()>>.
+ **/
+KR_EXPORT
+void mp_init(struct mempool *pool, size_t chunk_size);
+
+/**
+ * Allocate and initialize a new memory pool.
+ * See @mp_init() for @chunk_size limitations.
+ *
+ * The new mempool structure is allocated on the new mempool.
+ *
+ * Memory pools can be treated as <<trans:respools,resources>>, see <<trans:res_mempool()>>.
+ **/
+KR_EXPORT
+struct mempool *mp_new(size_t chunk_size);
+
+/**
+ * Cleanup mempool initialized by mp_init or mp_new.
+ * Frees all the memory allocated by this mempool and,
+ * if created by @mp_new(), the @pool itself.
+ **/
+KR_EXPORT
+void mp_delete(struct mempool *pool);
+
+/**
+ * Frees all data on a memory pool, but leaves it working.
+ * It can keep some of the chunks allocated to serve
+ * further allocation requests. Leaves the @pool alive,
+ * even if it was created with @mp_new().
+ **/
+KR_EXPORT
+void mp_flush(struct mempool *pool);
+
+/**
+ * Compute some statistics for debug purposes.
+ * See the definition of the <<struct_mempool_stats,mempool_stats structure>>.
+ * This function scans the chunk list, so it can be slow. If you are interested
+ * in total memory consumption only, mp_total_size() is faster.
+ **/
+void mp_stats(struct mempool *pool, struct mempool_stats *stats);
+
+/**
+ * Return how many bytes were allocated by the pool, including unused parts
+ * of chunks. This function runs in constant time.
+ **/
+u64 mp_total_size(struct mempool *pool);
+
+/**
+ * Release unused chunks of memory reserved for further allocation
+ * requests, but stop if mp_total_size() would drop below @min_total_size.
+ **/
+void mp_shrink(struct mempool *pool, u64 min_total_size);
+
+/***
+ * [[alloc]]
+ * Allocation routines
+ * -------------------
+ ***/
+
+/* For internal use only, do not call directly */
+void *mp_alloc_internal(struct mempool *pool, size_t size) LIKE_MALLOC;
+
+/**
+ * The function allocates new @size bytes on a given memory pool.
+ * If the @size is zero, the resulting pointer is undefined,
+ * but it may be safely reallocated or used as the parameter
+ * to other functions below.
+ *
+ * The resulting pointer is always aligned to a multiple of
+ * `CPU_STRUCT_ALIGN` bytes and this condition remains true also
+ * after future reallocations.
+ **/
+KR_EXPORT
+void *mp_alloc(struct mempool *pool, size_t size);
+
+/**
+ * The same as @mp_alloc(), but the result may be unaligned.
+ **/
+void *mp_alloc_noalign(struct mempool *pool, size_t size);
+
+/**
+ * The same as @mp_alloc(), but fills the newly allocated memory with zeroes.
+ **/
+void *mp_alloc_zero(struct mempool *pool, size_t size);
+
+/**
+ * Inlined version of @mp_alloc().
+ **/
+static inline void *mp_alloc_fast(struct mempool *pool, size_t size)
+{
+ size_t avail = pool->state.free[0] & ~(size_t)(CPU_STRUCT_ALIGN - 1);
+ if (size <= avail)
+ {
+ pool->state.free[0] = avail - size;
+ return (byte *)pool->state.last[0] - avail;
+ }
+ else
+ return mp_alloc_internal(pool, size);
+}
+
+/**
+ * Inlined version of @mp_alloc_noalign().
+ **/
+static inline void *mp_alloc_fast_noalign(struct mempool *pool, size_t size)
+{
+ if (size <= pool->state.free[0])
+ {
+ void *ptr = (byte *)pool->state.last[0] - pool->state.free[0];
+ pool->state.free[0] -= size;
+ return ptr;
+ }
+ else
+ return mp_alloc_internal(pool, size);
+}
+
+/**
+ * Return a generic allocator representing the given mempool.
+ **/
+static inline struct ucw_allocator *mp_get_allocator(struct mempool *mp)
+{
+ return &mp->allocator;
+}
+
+/***
+ * [[gbuf]]
+ * Growing buffers
+ * ---------------
+ *
+ * You do not need to know, how a buffer will need to be large,
+ * you can grow it incrementally to needed size. You can grow only
+ * one buffer at a time on a given mempool.
+ *
+ * Similar functionality is provided by <<growbuf:,growing buffers>> module.
+ ***/
+
+/* For internal use only, do not call directly */
+void *mp_start_internal(struct mempool *pool, size_t size) LIKE_MALLOC;
+void *mp_grow_internal(struct mempool *pool, size_t size);
+void *mp_spread_internal(struct mempool *pool, void *p, size_t size);
+
+static inline uint mp_idx(struct mempool *pool, void *ptr)
+{
+ return ptr == pool->last_big;
+}
+
+/**
+ * Open a new growing buffer (at least @size bytes long).
+ * If the @size is zero, the resulting pointer is undefined,
+ * but it may be safely reallocated or used as the parameter
+ * to other functions below.
+ *
+ * The resulting pointer is always aligned to a multiple of
+ * `CPU_STRUCT_ALIGN` bytes and this condition remains true also
+ * after future reallocations. There is an unaligned version as well.
+ *
+ * Keep in mind that you can't make any other pool allocations
+ * before you "close" the growing buffer with @mp_end().
+ */
+void *mp_start(struct mempool *pool, size_t size);
+void *mp_start_noalign(struct mempool *pool, size_t size);
+
+/**
+ * Inlined version of @mp_start().
+ **/
+static inline void *mp_start_fast(struct mempool *pool, size_t size)
+{
+ size_t avail = pool->state.free[0] & ~(size_t)(CPU_STRUCT_ALIGN - 1);
+ if (size <= avail)
+ {
+ pool->idx = 0;
+ pool->state.free[0] = avail;
+ return (byte *)pool->state.last[0] - avail;
+ }
+ else
+ return mp_start_internal(pool, size);
+}
+
+/**
+ * Inlined version of @mp_start_noalign().
+ **/
+static inline void *mp_start_fast_noalign(struct mempool *pool, size_t size)
+{
+ if (size <= pool->state.free[0])
+ {
+ pool->idx = 0;
+ return (byte *)pool->state.last[0] - pool->state.free[0];
+ }
+ else
+ return mp_start_internal(pool, size);
+}
+
+/**
+ * Return start pointer of the growing buffer allocated by latest @mp_start() or a similar function.
+ **/
+static inline void *mp_ptr(struct mempool *pool)
+{
+ return (byte *)pool->state.last[pool->idx] - pool->state.free[pool->idx];
+}
+
+/**
+ * Return the number of bytes available for extending the growing buffer.
+ * (Before a reallocation will be needed).
+ **/
+static inline size_t mp_avail(struct mempool *pool)
+{
+ return pool->state.free[pool->idx];
+}
+
+/**
+ * Grow the buffer allocated by @mp_start() to be at least @size bytes long
+ * (@size may be less than @mp_avail(), even zero). Reallocated buffer may
+ * change its starting position. The content will be unchanged to the minimum
+ * of the old and new sizes; newly allocated memory will be uninitialized.
+ * Multiple calls to mp_grow() have amortized linear cost wrt. the maximum value of @size. */
+static inline void *mp_grow(struct mempool *pool, size_t size)
+{
+ return (size <= mp_avail(pool)) ? mp_ptr(pool) : mp_grow_internal(pool, size);
+}
+
+/**
+ * Grow the buffer by at least one byte -- equivalent to <<mp_grow(),`mp_grow`>>`(@pool, @mp_avail(pool) + 1)`.
+ **/
+static inline void *mp_expand(struct mempool *pool)
+{
+ return mp_grow_internal(pool, mp_avail(pool) + 1);
+}
+
+/**
+ * Ensure that there is at least @size bytes free after @p,
+ * if not, reallocate and adjust @p.
+ **/
+static inline void *mp_spread(struct mempool *pool, void *p, size_t size)
+{
+ return (((size_t)((byte *)pool->state.last[pool->idx] - (byte *)p) >= size) ? p : mp_spread_internal(pool, p, size));
+}
+
+/**
+ * Append a character to the growing buffer. Called with @p pointing after
+ * the last byte in the buffer, returns a pointer after the last byte
+ * of the new (possibly reallocated) buffer.
+ **/
+static inline char *mp_append_char(struct mempool *pool, char *p, uint c)
+{
+ p = mp_spread(pool, p, 1);
+ *p++ = c;
+ return p;
+}
+
+/**
+ * Append a memory block to the growing buffer. Called with @p pointing after
+ * the last byte in the buffer, returns a pointer after the last byte
+ * of the new (possibly reallocated) buffer.
+ **/
+static inline void *mp_append_block(struct mempool *pool, void *p, const void *block, size_t size)
+{
+ char *q = mp_spread(pool, p, size);
+ memcpy(q, block, size);
+ return q + size;
+}
+
+/**
+ * Append a string to the growing buffer. Called with @p pointing after
+ * the last byte in the buffer, returns a pointer after the last byte
+ * of the new (possibly reallocated) buffer.
+ **/
+static inline void *mp_append_string(struct mempool *pool, void *p, const char *str)
+{
+ return mp_append_block(pool, p, str, strlen(str));
+}
+
+/**
+ * Close the growing buffer. The @end must point just behind the data, you want to keep
+ * allocated (so it can be in the interval `[@mp_ptr(@pool), @mp_ptr(@pool) + @mp_avail(@pool)]`).
+ * Returns a pointer to the beginning of the just closed block.
+ **/
+static inline void *mp_end(struct mempool *pool, void *end)
+{
+ void *p = mp_ptr(pool);
+ pool->state.free[pool->idx] = (byte *)pool->state.last[pool->idx] - (byte *)end;
+ return p;
+}
+
+/**
+ * Close the growing buffer as a string. That is, append a zero byte and call mp_end().
+ **/
+static inline char *mp_end_string(struct mempool *pool, void *end)
+{
+ end = mp_append_char(pool, end, 0);
+ return mp_end(pool, end);
+}
+
+/**
+ * Return size in bytes of the last allocated memory block (with @mp_alloc() or @mp_end()).
+ **/
+static inline size_t mp_size(struct mempool *pool, void *ptr)
+{
+ uint idx = mp_idx(pool, ptr);
+ return ((byte *)pool->state.last[idx] - (byte *)ptr) - pool->state.free[idx];
+}
+
+/**
+ * Open the last memory block (allocated with @mp_alloc() or @mp_end())
+ * for growing and return its size in bytes. The contents and the start pointer
+ * remain unchanged. Do not forget to call @mp_end() to close it.
+ **/
+size_t mp_open(struct mempool *pool, void *ptr);
+
+/**
+ * Inlined version of @mp_open().
+ **/
+static inline size_t mp_open_fast(struct mempool *pool, void *ptr)
+{
+ pool->idx = mp_idx(pool, ptr);
+ size_t size = ((byte *)pool->state.last[pool->idx] - (byte *)ptr) - pool->state.free[pool->idx];
+ pool->state.free[pool->idx] += size;
+ return size;
+}
+
+/**
+ * Reallocate the last memory block (allocated with @mp_alloc() or @mp_end())
+ * to the new @size. Behavior is similar to @mp_grow(), but the resulting
+ * block is closed.
+ **/
+void *mp_realloc(struct mempool *pool, void *ptr, size_t size);
+
+/**
+ * The same as @mp_realloc(), but fills the additional bytes (if any) with zeroes.
+ **/
+void *mp_realloc_zero(struct mempool *pool, void *ptr, size_t size);
+
+/**
+ * Inlined version of @mp_realloc().
+ **/
+static inline void *mp_realloc_fast(struct mempool *pool, void *ptr, size_t size)
+{
+ mp_open_fast(pool, ptr);
+ ptr = mp_grow(pool, size);
+ mp_end(pool, (byte *)ptr + size);
+ return ptr;
+}
+
+/***
+ * [[store]]
+ * Storing and restoring state
+ * ---------------------------
+ *
+ * Mempools can remember history of what was allocated and return back
+ * in time.
+ ***/
+
+/**
+ * Save the current state of a memory pool.
+ * Do not call this function with an opened growing buffer.
+ **/
+static inline void mp_save(struct mempool *pool, struct mempool_state *state)
+{
+ *state = pool->state;
+ pool->state.next = state;
+}
+
+/**
+ * Save the current state to a newly allocated mempool_state structure.
+ * Do not call this function with an opened growing buffer.
+ **/
+struct mempool_state *mp_push(struct mempool *pool);
+
+/**
+ * Restore the state saved by @mp_save() or @mp_push() and free all
+ * data allocated after that point (including the state structure itself).
+ * You can't reallocate the last memory block from the saved state.
+ **/
+void mp_restore(struct mempool *pool, struct mempool_state *state);
+
+/**
+ * Inlined version of @mp_restore().
+ **/
+static inline void mp_restore_fast(struct mempool *pool, struct mempool_state *state)
+{
+ if (pool->state.last[0] != state->last[0] || pool->state.last[1] != state->last[1])
+ mp_restore(pool, state);
+ else
+ {
+ pool->state = *state;
+ pool->last_big = &pool->last_big;
+ }
+}
+
+/**
+ * Restore the state saved by the last call to @mp_push().
+ * @mp_pop() and @mp_push() works as a stack so you can push more states safely.
+ **/
+void mp_pop(struct mempool *pool);
+
+
+/***
+ * [[string]]
+ * String operations
+ * -----------------
+ ***/
+
+char *mp_strdup(struct mempool *, const char *) LIKE_MALLOC; /** Makes a copy of a string on a mempool. Returns NULL for NULL string. **/
+void *mp_memdup(struct mempool *, const void *, size_t) LIKE_MALLOC; /** Makes a copy of a memory block on a mempool. **/
+/**
+ * Concatenates all passed strings. The last parameter must be NULL.
+ * This will concatenate two strings:
+ *
+ * char *message = mp_multicat(pool, "hello ", "world", NULL);
+ **/
+char *mp_multicat(struct mempool *, ...) LIKE_MALLOC SENTINEL_CHECK;
+/**
+ * Concatenates two strings and stores result on @mp.
+ */
+static inline char *LIKE_MALLOC mp_strcat(struct mempool *mp, const char *x, const char *y)
+{
+ return mp_multicat(mp, x, y, NULL);
+}
+/**
+ * Join strings and place @sep between each two neighboring.
+ * @p is the mempool to provide memory, @a is array of strings and @n
+ * tells how many there is of them.
+ **/
+char *mp_strjoin(struct mempool *p, char **a, uint n, uint sep) LIKE_MALLOC;
+/**
+ * Convert memory block to a string. Makes a copy of the given memory block
+ * in the mempool @p, adding an extra terminating zero byte at the end.
+ **/
+char *mp_str_from_mem(struct mempool *p, const void *mem, size_t len) LIKE_MALLOC;
+
+
+/***
+ * [[format]]
+ * Formatted output
+ * ---------------
+ ***/
+
+/**
+ * printf() into a in-memory string, allocated on the memory pool.
+ **/
+KR_EXPORT
+char *mp_printf(struct mempool *mp, const char *fmt, ...) FORMAT_CHECK(printf,2,3) LIKE_MALLOC;
+/**
+ * Like @mp_printf(), but uses `va_list` for parameters.
+ **/
+char *mp_vprintf(struct mempool *mp, const char *fmt, va_list args) LIKE_MALLOC;
+/**
+ * Like @mp_printf(), but it appends the data at the end of string
+ * pointed to by @ptr. The string is @mp_open()ed, so you have to
+ * provide something that can be.
+ *
+ * Returns pointer to the beginning of the string (the pointer may have
+ * changed due to reallocation).
+ *
+ * In some versions of LibUCW, this function was called mp_append_printf(). However,
+ * this name turned out to be confusing -- unlike other appending functions, this one is
+ * not called on an opened growing buffer. The old name will be preserved for backward
+ * compatibility for the time being.
+ **/
+KR_EXPORT
+char *mp_printf_append(struct mempool *mp, char *ptr, const char *fmt, ...) FORMAT_CHECK(printf,3,4);
+#define mp_append_printf mp_printf_append
+/**
+ * Like @mp_printf_append(), but uses `va_list` for parameters.
+ *
+ * In some versions of LibUCW, this function was called mp_append_vprintf(). However,
+ * this name turned out to be confusing -- unlike other appending functions, this one is
+ * not called on an opened growing buffer. The old name will be preserved for backward
+ * compatibility for the time being.
+ **/
+char *mp_vprintf_append(struct mempool *mp, char *ptr, const char *fmt, va_list args);
+#define mp_append_vprintf mp_vprintf_append
+
+#endif
diff --git a/daemon/.packaging/centos/7/builddeps b/daemon/.packaging/centos/7/builddeps
new file mode 100644
index 0000000..3247738
--- /dev/null
+++ b/daemon/.packaging/centos/7/builddeps
@@ -0,0 +1,13 @@
+gcc
+gcc-c++
+gnutls
+knot-libs
+knot-devel
+libcmocka-devel
+libedit-devel
+libcap-ng
+libuv-devel
+lmdb-devel
+luajit-devel
+meson
+systemd-devel
diff --git a/daemon/.packaging/centos/7/pre-build.sh b/daemon/.packaging/centos/7/pre-build.sh
new file mode 100755
index 0000000..d3a9503
--- /dev/null
+++ b/daemon/.packaging/centos/7/pre-build.sh
@@ -0,0 +1,9 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+yum update -y
+yum install -y wget epel-release
+
+# add build repository
+cd /etc/yum.repos.d/
+wget https://download.opensuse.org/repositories/home:CZ-NIC:knot-resolver-build/CentOS_7_EPEL/home:CZ-NIC:knot-resolver-build.repo
+
diff --git a/daemon/.packaging/centos/7/pre-run.sh b/daemon/.packaging/centos/7/pre-run.sh
new file mode 100755
index 0000000..ee15ec7
--- /dev/null
+++ b/daemon/.packaging/centos/7/pre-run.sh
@@ -0,0 +1,8 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+yum update -y
+yum install -y wget epel-release
+
+# add build repository
+cd /etc/yum.repos.d/
+wget https://download.opensuse.org/repositories/home:CZ-NIC:knot-resolver-latest/CentOS_7_EPEL/home:CZ-NIC:knot-resolver-latest.repo
diff --git a/daemon/.packaging/centos/7/rundeps b/daemon/.packaging/centos/7/rundeps
new file mode 100644
index 0000000..648501e
--- /dev/null
+++ b/daemon/.packaging/centos/7/rundeps
@@ -0,0 +1,6 @@
+knot-libs
+libedit
+libuv
+luajit
+lua-basexx
+lua-http
diff --git a/daemon/.packaging/centos/8/builddeps b/daemon/.packaging/centos/8/builddeps
new file mode 100644
index 0000000..984fa0b
--- /dev/null
+++ b/daemon/.packaging/centos/8/builddeps
@@ -0,0 +1,14 @@
+gcc
+gcc-c++
+meson
+"pkgconfig(cmocka)"
+"pkgconfig(gnutls)"
+"pkgconfig(libedit)"
+"pkgconfig(libknot)"
+"pkgconfig(libzscanner)"
+"pkgconfig(libdnssec)"
+"pkgconfig(libsystemd)"
+"pkgconfig(libcap-ng)"
+"pkgconfig(libuv)"
+"pkgconfig(lmdb)"
+"pkgconfig(luajit)"
diff --git a/daemon/.packaging/centos/8/pre-build.sh b/daemon/.packaging/centos/8/pre-build.sh
new file mode 100755
index 0000000..31398f8
--- /dev/null
+++ b/daemon/.packaging/centos/8/pre-build.sh
@@ -0,0 +1,9 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+dnf install -y wget 'dnf-command(config-manager)' epel-release centos-release
+
+dnf config-manager --enable PowerTools
+dnf config-manager --enable Devel
+dnf config-manager --add-repo https://download.opensuse.org/repositories/home:CZ-NIC:knot-resolver-build/CentOS_8_EPEL/home:CZ-NIC:knot-resolver-build.repo
+dnf install -y knot
+dnf upgrade -y
diff --git a/daemon/.packaging/centos/8/pre-run.sh b/daemon/.packaging/centos/8/pre-run.sh
new file mode 100755
index 0000000..94f8eb0
--- /dev/null
+++ b/daemon/.packaging/centos/8/pre-run.sh
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+dnf install -y wget 'dnf-command(config-manager)' epel-release centos-release
+
+dnf config-manager --enable PowerTools
+dnf config-manager --add-repo https://download.opensuse.org/repositories/home:CZ-NIC:knot-resolver-latest/CentOS_8_EPEL/home:CZ-NIC:knot-resolver-latest.repo
+dnf upgrade -y
diff --git a/daemon/.packaging/centos/8/rundeps b/daemon/.packaging/centos/8/rundeps
new file mode 100644
index 0000000..e3779ec
--- /dev/null
+++ b/daemon/.packaging/centos/8/rundeps
@@ -0,0 +1,6 @@
+libedit
+knot-libs
+libuv
+luajit
+lua5.1-basexx
+lua5.1-http
diff --git a/daemon/.packaging/debian/10/builddeps b/daemon/.packaging/debian/10/builddeps
new file mode 100644
index 0000000..604993c
--- /dev/null
+++ b/daemon/.packaging/debian/10/builddeps
@@ -0,0 +1,12 @@
+debhelper
+libcmocka-dev
+libedit-dev
+libgnutls28-dev
+libknot-dev
+liblmdb-dev
+luajit-5.1-dev
+libsystemd-dev
+libuv1-dev
+luajit
+pkg-config
+meson
diff --git a/daemon/.packaging/debian/10/pre-build.sh b/daemon/.packaging/debian/10/pre-build.sh
new file mode 100755
index 0000000..dc3b801
--- /dev/null
+++ b/daemon/.packaging/debian/10/pre-build.sh
@@ -0,0 +1,11 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# add debian build repository
+apt-get update
+apt-get install -y wget gnupg apt-utils
+echo 'deb http://download.opensuse.org/repositories/home:/CZ-NIC:/knot-resolver-build/Debian_10/ /' > /etc/apt/sources.list.d/home:CZ-NIC:knot-resolver-build.list
+wget -nv https://download.opensuse.org/repositories/home:CZ-NIC:knot-resolver-build/Debian_10/Release.key -O Release.key
+apt-key add - < Release.key
+
+apt-get update
+apt-get upgrade -y
diff --git a/daemon/.packaging/debian/10/pre-run.sh b/daemon/.packaging/debian/10/pre-run.sh
new file mode 100755
index 0000000..3a3906a
--- /dev/null
+++ b/daemon/.packaging/debian/10/pre-run.sh
@@ -0,0 +1,11 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+apt-get update
+apt-get install -y wget gnupg apt-utils
+
+echo 'deb http://download.opensuse.org/repositories/home:/CZ-NIC:/knot-resolver-latest/Debian_10/ /' > /etc/apt/sources.list.d/home:CZ-NIC:knot-resolver-latest.list
+wget -nv https://download.opensuse.org/repositories/home:CZ-NIC:knot-resolver-latest/Debian_10/Release.key -O Release.key
+apt-key add - < Release.key
+
+apt-get update
+apt-get upgrade -y
diff --git a/daemon/.packaging/debian/10/rundeps b/daemon/.packaging/debian/10/rundeps
new file mode 100644
index 0000000..a0f40c1
--- /dev/null
+++ b/daemon/.packaging/debian/10/rundeps
@@ -0,0 +1,15 @@
+adduser
+dns-root-data
+systemd
+libc6
+libdnssec7
+libedit2
+libgcc1
+libgnutls30
+libknot10
+liblmdb0
+libluajit-5.1-2
+libstdc++6
+libsystemd0
+libuv1
+libzscanner3
diff --git a/daemon/.packaging/debian/9/builddeps b/daemon/.packaging/debian/9/builddeps
new file mode 100644
index 0000000..604993c
--- /dev/null
+++ b/daemon/.packaging/debian/9/builddeps
@@ -0,0 +1,12 @@
+debhelper
+libcmocka-dev
+libedit-dev
+libgnutls28-dev
+libknot-dev
+liblmdb-dev
+luajit-5.1-dev
+libsystemd-dev
+libuv1-dev
+luajit
+pkg-config
+meson
diff --git a/daemon/.packaging/debian/9/pre-build.sh b/daemon/.packaging/debian/9/pre-build.sh
new file mode 100755
index 0000000..953025f
--- /dev/null
+++ b/daemon/.packaging/debian/9/pre-build.sh
@@ -0,0 +1,11 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# add debian build repository
+apt-get update
+apt-get install -y wget gnupg apt-utils
+echo 'deb http://download.opensuse.org/repositories/home:/CZ-NIC:/knot-resolver-build/Debian_9.0/ /' > /etc/apt/sources.list.d/home:CZ-NIC:knot-resolver-build.list
+wget -nv https://download.opensuse.org/repositories/home:CZ-NIC:knot-resolver-build/Debian_9.0/Release.key -O Release.key
+apt-key add - < Release.key
+
+apt-get update
+apt-get upgrade -y
diff --git a/daemon/.packaging/debian/9/pre-run.sh b/daemon/.packaging/debian/9/pre-run.sh
new file mode 100755
index 0000000..fa8d377
--- /dev/null
+++ b/daemon/.packaging/debian/9/pre-run.sh
@@ -0,0 +1,11 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+apt-get update
+apt-get install -y wget gnupg apt-utils
+
+echo 'deb http://download.opensuse.org/repositories/home:/CZ-NIC:/knot-resolver-latest/Debian_9.0/ /' > /etc/apt/sources.list.d/home:CZ-NIC:knot-resolver-latest.list
+wget -nv https://download.opensuse.org/repositories/home:CZ-NIC:knot-resolver-latest/Debian_9.0/Release.key -O Release.key
+apt-key add - < Release.key
+
+apt-get update
+apt-get upgrade -y
diff --git a/daemon/.packaging/debian/9/rundeps b/daemon/.packaging/debian/9/rundeps
new file mode 100644
index 0000000..a0f40c1
--- /dev/null
+++ b/daemon/.packaging/debian/9/rundeps
@@ -0,0 +1,15 @@
+adduser
+dns-root-data
+systemd
+libc6
+libdnssec7
+libedit2
+libgcc1
+libgnutls30
+libknot10
+liblmdb0
+libluajit-5.1-2
+libstdc++6
+libsystemd0
+libuv1
+libzscanner3
diff --git a/daemon/.packaging/fedora/31/builddeps b/daemon/.packaging/fedora/31/builddeps
new file mode 100644
index 0000000..984fa0b
--- /dev/null
+++ b/daemon/.packaging/fedora/31/builddeps
@@ -0,0 +1,14 @@
+gcc
+gcc-c++
+meson
+"pkgconfig(cmocka)"
+"pkgconfig(gnutls)"
+"pkgconfig(libedit)"
+"pkgconfig(libknot)"
+"pkgconfig(libzscanner)"
+"pkgconfig(libdnssec)"
+"pkgconfig(libsystemd)"
+"pkgconfig(libcap-ng)"
+"pkgconfig(libuv)"
+"pkgconfig(lmdb)"
+"pkgconfig(luajit)"
diff --git a/daemon/.packaging/fedora/31/pre-build.sh b/daemon/.packaging/fedora/31/pre-build.sh
new file mode 100755
index 0000000..7e279da
--- /dev/null
+++ b/daemon/.packaging/fedora/31/pre-build.sh
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+dnf install -y wget
+
+dnf config-manager --add-repo https://download.opensuse.org/repositories/home:CZ-NIC:knot-resolver-build/Fedora_31/home:CZ-NIC:knot-resolver-build.repo
+dnf install -y knot
+dnf upgrade -y
diff --git a/daemon/.packaging/fedora/31/pre-run.sh b/daemon/.packaging/fedora/31/pre-run.sh
new file mode 100755
index 0000000..b84b42d
--- /dev/null
+++ b/daemon/.packaging/fedora/31/pre-run.sh
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+dnf install -y wget
+
+dnf config-manager --add-repo https://download.opensuse.org/repositories/home:CZ-NIC:knot-resolver-latest/Fedora_31/home:CZ-NIC:knot-resolver-latest.repo
+dnf upgrade -y
diff --git a/daemon/.packaging/fedora/31/rundeps b/daemon/.packaging/fedora/31/rundeps
new file mode 100644
index 0000000..7517b6b
--- /dev/null
+++ b/daemon/.packaging/fedora/31/rundeps
@@ -0,0 +1,7 @@
+libedit
+knot-libs
+libuv
+luajit
+lua5.1-basexx
+lua5.1-psl
+lua5.1-http
diff --git a/daemon/.packaging/fedora/32/builddeps b/daemon/.packaging/fedora/32/builddeps
new file mode 100644
index 0000000..984fa0b
--- /dev/null
+++ b/daemon/.packaging/fedora/32/builddeps
@@ -0,0 +1,14 @@
+gcc
+gcc-c++
+meson
+"pkgconfig(cmocka)"
+"pkgconfig(gnutls)"
+"pkgconfig(libedit)"
+"pkgconfig(libknot)"
+"pkgconfig(libzscanner)"
+"pkgconfig(libdnssec)"
+"pkgconfig(libsystemd)"
+"pkgconfig(libcap-ng)"
+"pkgconfig(libuv)"
+"pkgconfig(lmdb)"
+"pkgconfig(luajit)"
diff --git a/daemon/.packaging/fedora/32/pre-build.sh b/daemon/.packaging/fedora/32/pre-build.sh
new file mode 100755
index 0000000..97caead
--- /dev/null
+++ b/daemon/.packaging/fedora/32/pre-build.sh
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+dnf install -y wget
+
+dnf config-manager --add-repo https://download.opensuse.org/repositories/home:CZ-NIC:knot-resolver-build/Fedora_32/home:CZ-NIC:knot-resolver-build.repo
+dnf install -y knot
+dnf upgrade -y
diff --git a/daemon/.packaging/fedora/32/pre-run.sh b/daemon/.packaging/fedora/32/pre-run.sh
new file mode 100755
index 0000000..b224b7e
--- /dev/null
+++ b/daemon/.packaging/fedora/32/pre-run.sh
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+dnf install -y wget
+
+dnf config-manager --add-repo https://download.opensuse.org/repositories/home:CZ-NIC:knot-resolver-latest/Fedora_32/home:CZ-NIC:knot-resolver-latest.repo
+dnf upgrade -y
diff --git a/daemon/.packaging/fedora/32/rundeps b/daemon/.packaging/fedora/32/rundeps
new file mode 100644
index 0000000..7517b6b
--- /dev/null
+++ b/daemon/.packaging/fedora/32/rundeps
@@ -0,0 +1,7 @@
+libedit
+knot-libs
+libuv
+luajit
+lua5.1-basexx
+lua5.1-psl
+lua5.1-http
diff --git a/daemon/.packaging/leap/15.2/builddeps b/daemon/.packaging/leap/15.2/builddeps
new file mode 100644
index 0000000..e568905
--- /dev/null
+++ b/daemon/.packaging/leap/15.2/builddeps
@@ -0,0 +1,14 @@
+gcc
+gcc-c++
+lmdb-devel
+meson
+"pkgconfig(cmocka)"
+"pkgconfig(gnutls)"
+"pkgconfig(libedit)"
+"pkgconfig(libknot)"
+"pkgconfig(libzscanner)"
+"pkgconfig(libdnssec)"
+"pkgconfig(libsystemd)"
+"pkgconfig(libcap-ng)"
+"pkgconfig(libuv)"
+"pkgconfig(luajit)"
diff --git a/daemon/.packaging/leap/15.2/pre-build.sh b/daemon/.packaging/leap/15.2/pre-build.sh
new file mode 100755
index 0000000..274931a
--- /dev/null
+++ b/daemon/.packaging/leap/15.2/pre-build.sh
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+zypper addrepo https://download.opensuse.org/repositories/home:CZ-NIC:knot-resolver-build/openSUSE_Leap_15.2/home:CZ-NIC:knot-resolver-build.repo
+zypper --no-gpg-checks refresh
+zypper install -y knot
+
diff --git a/daemon/.packaging/leap/15.2/pre-run.sh b/daemon/.packaging/leap/15.2/pre-run.sh
new file mode 100755
index 0000000..9b0b5da
--- /dev/null
+++ b/daemon/.packaging/leap/15.2/pre-run.sh
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+zypper addrepo https://download.opensuse.org/repositories/home:CZ-NIC:knot-resolver-latest/openSUSE_Leap_15.2/home:CZ-NIC:knot-resolver-latest.repo
+zypper --no-gpg-checks refresh
diff --git a/daemon/.packaging/leap/15.2/rundeps b/daemon/.packaging/leap/15.2/rundeps
new file mode 100644
index 0000000..3f601a0
--- /dev/null
+++ b/daemon/.packaging/leap/15.2/rundeps
@@ -0,0 +1,4 @@
+libedit0
+knot-libs
+libuv1
+libluajit-5_1-2
diff --git a/daemon/.packaging/leap/docker-image-name b/daemon/.packaging/leap/docker-image-name
new file mode 100644
index 0000000..388ed86
--- /dev/null
+++ b/daemon/.packaging/leap/docker-image-name
@@ -0,0 +1 @@
+opensuse/leap
diff --git a/daemon/.packaging/test.config b/daemon/.packaging/test.config
new file mode 100644
index 0000000..72ec48d
--- /dev/null
+++ b/daemon/.packaging/test.config
@@ -0,0 +1,2 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+quit()
diff --git a/daemon/.packaging/ubuntu/16.04/builddeps b/daemon/.packaging/ubuntu/16.04/builddeps
new file mode 100644
index 0000000..7b1d943
--- /dev/null
+++ b/daemon/.packaging/ubuntu/16.04/builddeps
@@ -0,0 +1,16 @@
+debhelper
+libcmocka-dev
+libedit-dev
+libgnutls28-dev
+libknot-dev
+liblmdb-dev
+libluajit-5.1-dev
+libsystemd-dev
+libuv1-dev
+luajit
+pkg-config
+meson
+doxygen
+python3-breathe
+python3-sphinx
+python3-sphinx-rtd-theme
diff --git a/daemon/.packaging/ubuntu/16.04/pre-build.sh b/daemon/.packaging/ubuntu/16.04/pre-build.sh
new file mode 100755
index 0000000..5af89ab
--- /dev/null
+++ b/daemon/.packaging/ubuntu/16.04/pre-build.sh
@@ -0,0 +1,12 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# add build repository
+apt-get update
+apt-get install -y wget gnupg apt-utils
+
+echo 'deb http://download.opensuse.org/repositories/home:/CZ-NIC:/knot-resolver-build/xUbuntu_16.04/ /' > /etc/apt/sources.list.d/home:CZ-NIC:knot-resolver-build.list
+wget -nv https://download.opensuse.org/repositories/home:CZ-NIC:knot-resolver-build/xUbuntu_16.04/Release.key -O Release.key
+apt-key add - < Release.key
+
+apt-get update
+apt-get upgrade -y
diff --git a/daemon/.packaging/ubuntu/16.04/pre-run.sh b/daemon/.packaging/ubuntu/16.04/pre-run.sh
new file mode 100755
index 0000000..bb81453
--- /dev/null
+++ b/daemon/.packaging/ubuntu/16.04/pre-run.sh
@@ -0,0 +1,12 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# add build repository
+apt-get update
+apt-get install -y wget gnupg apt-utils
+
+echo 'deb http://download.opensuse.org/repositories/home:/CZ-NIC:/knot-resolver-latest/xUbuntu_16.04/ /' > /etc/apt/sources.list.d/home:CZ-NIC:knot-resolver-latest.list
+wget -nv https://download.opensuse.org/repositories/home:CZ-NIC:knot-resolver-latest/xUbuntu_16.04/Release.key -O Release.key
+apt-key add - < Release.key
+
+apt-get update
+apt-get upgrade -y
diff --git a/daemon/.packaging/ubuntu/16.04/rundeps b/daemon/.packaging/ubuntu/16.04/rundeps
new file mode 100644
index 0000000..a0f40c1
--- /dev/null
+++ b/daemon/.packaging/ubuntu/16.04/rundeps
@@ -0,0 +1,15 @@
+adduser
+dns-root-data
+systemd
+libc6
+libdnssec7
+libedit2
+libgcc1
+libgnutls30
+libknot10
+liblmdb0
+libluajit-5.1-2
+libstdc++6
+libsystemd0
+libuv1
+libzscanner3
diff --git a/daemon/.packaging/ubuntu/18.04/builddeps b/daemon/.packaging/ubuntu/18.04/builddeps
new file mode 100644
index 0000000..7b1d943
--- /dev/null
+++ b/daemon/.packaging/ubuntu/18.04/builddeps
@@ -0,0 +1,16 @@
+debhelper
+libcmocka-dev
+libedit-dev
+libgnutls28-dev
+libknot-dev
+liblmdb-dev
+libluajit-5.1-dev
+libsystemd-dev
+libuv1-dev
+luajit
+pkg-config
+meson
+doxygen
+python3-breathe
+python3-sphinx
+python3-sphinx-rtd-theme
diff --git a/daemon/.packaging/ubuntu/18.04/pre-build.sh b/daemon/.packaging/ubuntu/18.04/pre-build.sh
new file mode 100755
index 0000000..77551b8
--- /dev/null
+++ b/daemon/.packaging/ubuntu/18.04/pre-build.sh
@@ -0,0 +1,12 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# add build repository
+apt-get update
+apt-get install -y wget gnupg apt-utils
+
+echo 'deb http://download.opensuse.org/repositories/home:/CZ-NIC:/knot-resolver-build/xUbuntu_18.04/ /' > /etc/apt/sources.list.d/home:CZ-NIC:knot-resolver-build.list
+wget -nv https://download.opensuse.org/repositories/home:CZ-NIC:knot-resolver-build/xUbuntu_18.04/Release.key -O Release.key
+apt-key add - < Release.key
+
+apt-get update
+apt-get upgrade -y
diff --git a/daemon/.packaging/ubuntu/18.04/pre-run.sh b/daemon/.packaging/ubuntu/18.04/pre-run.sh
new file mode 100755
index 0000000..71d2a32
--- /dev/null
+++ b/daemon/.packaging/ubuntu/18.04/pre-run.sh
@@ -0,0 +1,12 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# add build repository
+apt-get update
+apt-get install -y wget gnupg apt-utils
+
+echo 'deb http://download.opensuse.org/repositories/home:/CZ-NIC:/knot-resolver-latest/xUbuntu_18.04/ /' > /etc/apt/sources.list.d/home:CZ-NIC:knot-resolver-latest.list
+wget -nv https://download.opensuse.org/repositories/home:CZ-NIC:knot-resolver-latest/xUbuntu_18.04/Release.key -O Release.key
+apt-key add - < Release.key
+
+apt-get update
+apt-get upgrade -y
diff --git a/daemon/.packaging/ubuntu/18.04/rundeps b/daemon/.packaging/ubuntu/18.04/rundeps
new file mode 100644
index 0000000..a0f40c1
--- /dev/null
+++ b/daemon/.packaging/ubuntu/18.04/rundeps
@@ -0,0 +1,15 @@
+adduser
+dns-root-data
+systemd
+libc6
+libdnssec7
+libedit2
+libgcc1
+libgnutls30
+libknot10
+liblmdb0
+libluajit-5.1-2
+libstdc++6
+libsystemd0
+libuv1
+libzscanner3
diff --git a/daemon/.packaging/ubuntu/20.04/builddeps b/daemon/.packaging/ubuntu/20.04/builddeps
new file mode 100644
index 0000000..7b1d943
--- /dev/null
+++ b/daemon/.packaging/ubuntu/20.04/builddeps
@@ -0,0 +1,16 @@
+debhelper
+libcmocka-dev
+libedit-dev
+libgnutls28-dev
+libknot-dev
+liblmdb-dev
+libluajit-5.1-dev
+libsystemd-dev
+libuv1-dev
+luajit
+pkg-config
+meson
+doxygen
+python3-breathe
+python3-sphinx
+python3-sphinx-rtd-theme
diff --git a/daemon/.packaging/ubuntu/20.04/pre-build.sh b/daemon/.packaging/ubuntu/20.04/pre-build.sh
new file mode 100755
index 0000000..e55fba6
--- /dev/null
+++ b/daemon/.packaging/ubuntu/20.04/pre-build.sh
@@ -0,0 +1,12 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# add build repository
+apt-get update
+apt-get install -y wget gnupg apt-utils
+
+echo 'deb http://download.opensuse.org/repositories/home:/CZ-NIC:/knot-resolver-build/xUbuntu_20.04/ /' > /etc/apt/sources.list.d/home:CZ-NIC:knot-resolver-build.list
+wget -nv https://download.opensuse.org/repositories/home:CZ-NIC:knot-resolver-build/xUbuntu_20.04/Release.key -O Release.key
+apt-key add - < Release.key
+
+apt-get update
+apt-get upgrade -y
diff --git a/daemon/.packaging/ubuntu/20.04/pre-run.sh b/daemon/.packaging/ubuntu/20.04/pre-run.sh
new file mode 100755
index 0000000..75c32f8
--- /dev/null
+++ b/daemon/.packaging/ubuntu/20.04/pre-run.sh
@@ -0,0 +1,12 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# add build repository
+apt-get update
+apt-get install -y wget gnupg apt-utils
+
+echo 'deb http://download.opensuse.org/repositories/home:/CZ-NIC:/knot-resolver-latest/xUbuntu_20.04/ /' > /etc/apt/sources.list.d/home:CZ-NIC:knot-resolver-latest.list
+wget -nv https://download.opensuse.org/repositories/home:CZ-NIC:knot-resolver-latest/xUbuntu_20.04/Release.key -O Release.key
+apt-key add - < Release.key
+
+apt-get update
+apt-get upgrade -y
diff --git a/daemon/.packaging/ubuntu/20.04/rundeps b/daemon/.packaging/ubuntu/20.04/rundeps
new file mode 100644
index 0000000..a0f40c1
--- /dev/null
+++ b/daemon/.packaging/ubuntu/20.04/rundeps
@@ -0,0 +1,15 @@
+adduser
+dns-root-data
+systemd
+libc6
+libdnssec7
+libedit2
+libgcc1
+libgnutls30
+libknot10
+liblmdb0
+libluajit-5.1-2
+libstdc++6
+libsystemd0
+libuv1
+libzscanner3
diff --git a/daemon/bindings/api.h b/daemon/bindings/api.h
new file mode 100644
index 0000000..2b43385
--- /dev/null
+++ b/daemon/bindings/api.h
@@ -0,0 +1,12 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#include <lua.h>
+
+/** Make all the bindings accessible from the lua state,
+ * .i.e. define those lua tables. */
+void kr_bindings_register(lua_State *L);
+
diff --git a/daemon/bindings/cache.c b/daemon/bindings/cache.c
new file mode 100644
index 0000000..d42ff62
--- /dev/null
+++ b/daemon/bindings/cache.c
@@ -0,0 +1,382 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#include "daemon/bindings/impl.h"
+
+/** @internal return cache, or throw lua error if not open */
+static struct kr_cache * cache_assert_open(lua_State *L)
+{
+ struct kr_cache *cache = &the_worker->engine->resolver.cache;
+ if (kr_fails_assert(cache) || !kr_cache_is_open(cache))
+ lua_error_p(L, "no cache is open yet, use cache.open() or cache.size, etc.");
+ return cache;
+}
+
+/** Return available cached backends. */
+static int cache_backends(lua_State *L)
+{
+ struct engine *engine = the_worker->engine;
+
+ lua_newtable(L);
+ for (unsigned i = 0; i < engine->backends.len; ++i) {
+ const struct kr_cdb_api *api = engine->backends.at[i];
+ lua_pushboolean(L, api == engine->resolver.cache.api);
+ lua_setfield(L, -2, api->name);
+ }
+ return 1;
+}
+
+/** Return number of cached records. */
+static int cache_count(lua_State *L)
+{
+ struct kr_cache *cache = cache_assert_open(L);
+
+ int count = cache->api->count(cache->db, &cache->stats);
+ if (count >= 0) {
+ /* First key is a version counter, omit it if nonempty. */
+ lua_pushinteger(L, count ? count - 1 : 0);
+ return 1;
+ }
+ return 0;
+}
+
+/** Return time of last checkpoint, or re-set it if passed `true`. */
+static int cache_checkpoint(lua_State *L)
+{
+ struct kr_cache *cache = cache_assert_open(L);
+
+ if (lua_gettop(L) == 0) { /* Return the current value. */
+ lua_newtable(L);
+ lua_pushnumber(L, cache->checkpoint_monotime);
+ lua_setfield(L, -2, "monotime");
+ lua_newtable(L);
+ lua_pushnumber(L, cache->checkpoint_walltime.tv_sec);
+ lua_setfield(L, -2, "sec");
+ lua_pushnumber(L, cache->checkpoint_walltime.tv_usec);
+ lua_setfield(L, -2, "usec");
+ lua_setfield(L, -2, "walltime");
+ return 1;
+ }
+
+ if (lua_gettop(L) != 1 || !lua_isboolean(L, 1) || !lua_toboolean(L, 1))
+ lua_error_p(L, "cache.checkpoint() takes no parameters or a true value");
+
+ kr_cache_make_checkpoint(cache);
+ return 1;
+}
+
+/** Return cache statistics. */
+static int cache_stats(lua_State *L)
+{
+ struct kr_cache *cache = cache_assert_open(L);
+ lua_newtable(L);
+#define add_stat(name) \
+ lua_pushinteger(L, (cache->stats.name)); \
+ lua_setfield(L, -2, #name)
+ add_stat(open);
+ add_stat(close);
+ add_stat(count);
+ cache->stats.count_entries = cache->api->count(cache->db, &cache->stats);
+ add_stat(count_entries);
+ add_stat(clear);
+ add_stat(commit);
+ add_stat(read);
+ add_stat(read_miss);
+ add_stat(write);
+ add_stat(remove);
+ add_stat(remove_miss);
+ add_stat(match);
+ add_stat(match_miss);
+ add_stat(read_leq);
+ add_stat(read_leq_miss);
+ /* usage_percent statistics special case - double */
+ cache->stats.usage_percent = cache->api->usage_percent(cache->db);
+ lua_pushnumber(L, cache->stats.usage_percent);
+ lua_setfield(L, -2, "usage_percent");
+#undef add_stat
+
+ return 1;
+}
+
+static const struct kr_cdb_api *cache_select(struct engine *engine, const char **conf)
+{
+ /* Return default backend */
+ if (*conf == NULL || !strstr(*conf, "://")) {
+ return engine->backends.at[0];
+ }
+
+ /* Find storage backend from config prefix */
+ for (unsigned i = 0; i < engine->backends.len; ++i) {
+ const struct kr_cdb_api *api = engine->backends.at[i];
+ if (strncmp(*conf, api->name, strlen(api->name)) == 0) {
+ *conf += strlen(api->name) + strlen("://");
+ return api;
+ }
+ }
+
+ return NULL;
+}
+
+static int cache_max_ttl(lua_State *L)
+{
+ struct kr_cache *cache = cache_assert_open(L);
+
+ int n = lua_gettop(L);
+ if (n > 0) {
+ if (!lua_isnumber(L, 1) || n > 1)
+ lua_error_p(L, "expected 'max_ttl(number ttl)'");
+ uint32_t min = cache->ttl_min;
+ int64_t ttl = lua_tointeger(L, 1);
+ if (ttl < 1 || ttl < min || ttl > TTL_MAX_MAX) {
+ lua_error_p(L,
+ "max_ttl must be larger than minimum TTL, and in range <1, "
+ STR(TTL_MAX_MAX) ">'");
+ }
+ cache->ttl_max = ttl;
+ }
+ lua_pushinteger(L, cache->ttl_max);
+ return 1;
+}
+
+
+static int cache_min_ttl(lua_State *L)
+{
+ struct kr_cache *cache = cache_assert_open(L);
+
+ int n = lua_gettop(L);
+ if (n > 0) {
+ if (!lua_isnumber(L, 1))
+ lua_error_p(L, "expected 'min_ttl(number ttl)'");
+ uint32_t max = cache->ttl_max;
+ int64_t ttl = lua_tointeger(L, 1);
+ if (ttl < 0 || ttl > max || ttl > TTL_MAX_MAX) {
+ lua_error_p(L,
+ "min_ttl must be smaller than maximum TTL, and in range <0, "
+ STR(TTL_MAX_MAX) ">'");
+ }
+ cache->ttl_min = ttl;
+ }
+ lua_pushinteger(L, cache->ttl_min);
+ return 1;
+}
+
+/** Open cache */
+static int cache_open(lua_State *L)
+{
+ /* Check parameters */
+ int n = lua_gettop(L);
+ if (n < 1 || !lua_isnumber(L, 1))
+ lua_error_p(L, "expected 'open(number max_size, string config = \"\")'");
+
+ /* Select cache storage backend */
+ struct engine *engine = the_worker->engine;
+
+ lua_Integer csize_lua = lua_tointeger(L, 1);
+ if (!(csize_lua >= 8192 && csize_lua < SIZE_MAX)) { /* min. is basically arbitrary */
+ lua_error_p(L, "invalid cache size specified, it must be in range <8192, "
+ STR(SIZE_MAX) ">");
+ }
+ size_t cache_size = csize_lua;
+
+ const char *conf = n > 1 ? lua_tostring(L, 2) : NULL;
+ const char *uri = conf;
+ const struct kr_cdb_api *api = cache_select(engine, &conf);
+ if (!api)
+ lua_error_p(L, "unsupported cache backend");
+
+ /* Close if already open */
+ kr_cache_close(&engine->resolver.cache);
+
+ /* Reopen cache */
+ struct kr_cdb_opts opts = {
+ (conf && strlen(conf)) ? conf : ".",
+ cache_size
+ };
+ int ret = kr_cache_open(&engine->resolver.cache, api, &opts, engine->pool);
+ if (ret != 0) {
+ char cwd[PATH_MAX];
+ get_workdir(cwd, sizeof(cwd));
+ return luaL_error(L, "can't open cache path '%s'; working directory '%s'; %s",
+ opts.path, cwd, kr_strerror(ret));
+ }
+ /* Let's check_health() every five seconds to avoid keeping old cache alive
+ * even in case of not having any work to do. */
+ ret = kr_cache_check_health(&engine->resolver.cache, 5000);
+ if (ret != 0) {
+ kr_log_error(CACHE, "periodic health check failed (ignored): %s\n",
+ kr_strerror(ret));
+ }
+
+ /* Store current configuration */
+ lua_getglobal(L, "cache");
+ lua_pushstring(L, "current_size");
+ lua_pushnumber(L, cache_size);
+ lua_rawset(L, -3);
+ lua_pushstring(L, "current_storage");
+ lua_pushstring(L, uri);
+ lua_rawset(L, -3);
+ lua_pop(L, 1);
+
+ lua_pushboolean(L, 1);
+ return 1;
+}
+
+static int cache_close(lua_State *L)
+{
+ struct kr_cache *cache = &the_worker->engine->resolver.cache;
+ if (!kr_cache_is_open(cache)) {
+ return 0;
+ }
+
+ kr_cache_close(cache);
+ lua_getglobal(L, "cache");
+ lua_pushstring(L, "current_size");
+ lua_pushnumber(L, 0);
+ lua_rawset(L, -3);
+ lua_pop(L, 1);
+ lua_pushboolean(L, 1);
+ return 1;
+}
+
+#if 0
+/** @internal Prefix walk. */
+static int cache_prefixed(struct kr_cache *cache, const char *prefix, bool exact_name,
+ knot_db_val_t keyval[][2], int maxcount)
+{
+ /* Convert to domain name */
+ uint8_t buf[KNOT_DNAME_MAXLEN];
+ if (!knot_dname_from_str(buf, prefix, sizeof(buf))) {
+ return kr_error(EINVAL);
+ }
+ /* Start prefix search */
+ return kr_cache_match(cache, buf, exact_name, keyval, maxcount);
+}
+#endif
+
+/** Clear everything. */
+static int cache_clear_everything(lua_State *L)
+{
+ struct kr_cache *cache = cache_assert_open(L);
+
+ /* Clear records and packets. */
+ int ret = kr_cache_clear(cache);
+ lua_error_maybe(L, ret);
+
+ /* Clear reputation tables */
+ struct kr_context *ctx = &the_worker->engine->resolver;
+ lru_reset(ctx->cache_cookie);
+ lua_pushboolean(L, true);
+ return 1;
+}
+
+#if 0
+/** @internal Dump cache key into table on Lua stack. */
+static void cache_dump(lua_State *L, knot_db_val_t keyval[])
+{
+ knot_dname_t dname[KNOT_DNAME_MAXLEN];
+ char name[KNOT_DNAME_TXT_MAXLEN];
+ uint16_t type;
+
+ int ret = kr_unpack_cache_key(keyval[0], dname, &type);
+ if (ret < 0) {
+ return;
+ }
+
+ ret = !knot_dname_to_str(name, dname, sizeof(name));
+ if (kr_fails_assert(!ret)) return;
+
+ /* If name typemap doesn't exist yet, create it */
+ lua_getfield(L, -1, name);
+ if (lua_isnil(L, -1)) {
+ lua_pop(L, 1);
+ lua_newtable(L);
+ }
+ /* Append to typemap */
+ char type_buf[KR_RRTYPE_STR_MAXLEN] = { '\0' };
+ knot_rrtype_to_string(type, type_buf, sizeof(type_buf));
+ lua_pushboolean(L, true);
+ lua_setfield(L, -2, type_buf);
+ /* Set name typemap */
+ lua_setfield(L, -2, name);
+}
+
+/** Query cached records. TODO: fix caveats in ./README.rst documentation? */
+static int cache_get(lua_State *L)
+{
+ //struct kr_cache *cache = cache_assert_open(L); // to be fixed soon
+
+ /* Check parameters */
+ int n = lua_gettop(L);
+ if (n < 1 || !lua_isstring(L, 1))
+ lua_error_p(L, "expected 'cache.get(string key)'");
+
+ /* Retrieve set of keys */
+ const char *prefix = lua_tostring(L, 1);
+ knot_db_val_t keyval[100][2];
+ int ret = cache_prefixed(cache, prefix, false/*FIXME*/, keyval, 100);
+ lua_error_maybe(L, ret);
+ /* Format output */
+ lua_newtable(L);
+ for (int i = 0; i < ret; ++i) {
+ cache_dump(L, keyval[i]);
+ }
+ return 1;
+}
+#endif
+static int cache_get(lua_State *L)
+{
+ lua_error_maybe(L, ENOSYS);
+ return kr_error(ENOSYS); /* doesn't happen */
+}
+
+/** Set time interval for cleaning rtt cache.
+ * Servers with score >= KR_NS_TIMEOUT will be cleaned after
+ * this interval ended up, so that they will be able to participate
+ * in NS elections again. */
+static int cache_ns_tout(lua_State *L)
+{
+ struct kr_context *ctx = &the_worker->engine->resolver;
+
+ /* Check parameters */
+ int n = lua_gettop(L);
+ if (n < 1) {
+ lua_pushinteger(L, ctx->cache_rtt_tout_retry_interval);
+ return 1;
+ }
+
+ if (!lua_isnumber(L, 1))
+ lua_error_p(L, "expected 'cache.ns_tout(interval in ms)'");
+
+ lua_Integer interval_lua = lua_tointeger(L, 1);
+ if (!(interval_lua > 0 && interval_lua < UINT_MAX)) {
+ lua_error_p(L, "invalid interval specified, it must be in range > 0, < "
+ STR(UINT_MAX));
+ }
+
+ ctx->cache_rtt_tout_retry_interval = interval_lua;
+ lua_pushinteger(L, ctx->cache_rtt_tout_retry_interval);
+ return 1;
+}
+
+int kr_bindings_cache(lua_State *L)
+{
+ static const luaL_Reg lib[] = {
+ { "backends", cache_backends },
+ { "count", cache_count },
+ { "stats", cache_stats },
+ { "checkpoint", cache_checkpoint },
+ { "open", cache_open },
+ { "close", cache_close },
+ { "clear_everything", cache_clear_everything },
+ { "get", cache_get },
+ { "max_ttl", cache_max_ttl },
+ { "min_ttl", cache_min_ttl },
+ { "ns_tout", cache_ns_tout },
+ { NULL, NULL }
+ };
+
+ luaL_register(L, "cache", lib);
+ return 1;
+}
+
diff --git a/daemon/bindings/cache.rst b/daemon/bindings/cache.rst
new file mode 100644
index 0000000..36114d2
--- /dev/null
+++ b/daemon/bindings/cache.rst
@@ -0,0 +1,338 @@
+.. SPDX-License-Identifier: GPL-3.0-or-later
+
+Cache
+=====
+
+Cache in Knot Resolver is stored on disk and also shared between
+:ref:`systemd-multiple-instances` so resolver doesn't lose the cached data on
+restart or crash.
+
+To improve performance even further the resolver implements so-called aggressive caching
+for DNSSEC-validated data (:rfc:`8198`), which improves performance and also protects
+against some types of Random Subdomain Attacks.
+
+
+.. _`cache_sizing`:
+
+Sizing
+------
+
+For personal and small office use-cases cache size around 100 MB is more than enough.
+
+For large deployments we recommend to run Knot Resolver on a dedicated machine,
+and to allocate 90% of machine's free memory for resolver's cache.
+
+.. note:: Choosing a cache size that can fit into RAM is important even if the
+ cache is stored on disk (default). Otherwise, the extra I/O caused by disk
+ access for missing pages can cause performance issues.
+
+For example, imagine you have a machine with 16 GB of memory.
+After machine restart you use command ``free -m`` to determine
+amount of free memory (without swap):
+
+.. code-block:: bash
+
+ $ free -m
+ total used free
+ Mem: 15907 979 14928
+
+Now you can configure cache size to be 90% of the free memory 14 928 MB, i.e. 13 453 MB:
+
+.. code-block:: lua
+
+ -- 90 % of free memory after machine restart
+ cache.size = 13453 * MB
+
+It is also possible to set the cache size based on the file system size. This is useful
+if you use a dedicated partition for cache (e.g. non-persistent tmpfs). It is recommended
+to leave some free space for special files, such as locks.:
+
+.. code-block:: lua
+
+ cache.size = cache.fssize() - 10*MB
+
+.. note:: The :ref:`garbage-collector` can be used to periodically trim the
+ cache. It is enabled and configured by default when running kresd with
+ systemd integration.
+
+.. _`cache_persistence`:
+
+Persistence
+-----------
+.. tip:: Using tmpfs for cache improves performance and reduces disk I/O.
+
+By default the cache is saved on a persistent storage device
+so the content of the cache is persisted during system reboot.
+This usually leads to smaller latency after restart etc.,
+however in certain situations a non-persistent cache storage might be preferred, e.g.:
+
+ - Resolver handles high volume of queries and I/O performance to disk is too low.
+ - Threat model includes attacker getting access to disk content in power-off state.
+ - Disk has limited number of writes (e.g. flash memory in routers).
+
+If non-persistent cache is desired configure cache directory to be on
+tmpfs_ filesystem, a temporary in-memory file storage.
+The cache content will be saved in memory, and thus have faster access
+and will be lost on power-off or reboot.
+
+
+.. note:: In most of the Unix-like systems ``/tmp`` and ``/var/run`` are
+ commonly mounted as tmpfs. While it is technically possible to move the
+ cache to an existing tmpfs filesystem, it is *not recommended*, since the
+ path to cache is configured in multiple places.
+
+Mounting the cache directory as tmpfs_ is the recommended approach. Make sure
+to use appropriate ``size=`` option and don't forget to adjust the size in the
+config file as well.
+
+.. code-block:: none
+
+ # /etc/fstab
+ tmpfs /var/cache/knot-resolver tmpfs rw,size=2G,uid=knot-resolver,gid=knot-resolver,nosuid,nodev,noexec,mode=0700 0 0
+
+.. code-block:: lua
+
+ -- /etc/knot-resolver/kresd.conf
+ cache.size = cache.fssize() - 10*MB
+
+.. _tmpfs: https://en.wikipedia.org/wiki/Tmpfs
+
+Configuration reference
+-----------------------
+
+.. function:: cache.open(max_size[, config_uri])
+
+ :param number max_size: Maximum cache size in bytes.
+ :return: ``true`` if cache was opened
+
+ Open cache with a size limit. The cache will be reopened if already open.
+ Note that the max_size cannot be lowered, only increased due to how cache is implemented.
+
+ .. tip:: Use ``kB, MB, GB`` constants as a multiplier, e.g. ``100*MB``.
+
+ The URI ``lmdb://path`` allows you to change the cache directory.
+
+ Example:
+
+ .. code-block:: lua
+
+ cache.open(100 * MB, 'lmdb:///var/cache/knot-resolver')
+
+.. envvar:: cache.size
+
+ Set the cache maximum size in bytes. Note that this is only a hint to the backend,
+ which may or may not respect it. See :func:`cache.open()`.
+
+ .. code-block:: lua
+
+ cache.size = 100 * MB -- equivalent to `cache.open(100 * MB)`
+
+.. envvar:: cache.current_size
+
+ Get the maximum size in bytes.
+
+ .. code-block:: lua
+
+ print(cache.current_size)
+
+.. envvar:: cache.storage
+
+ Set the cache storage backend configuration, see :func:`cache.backends()` for
+ more information. If the new storage configuration is invalid, it is not set.
+
+ .. code-block:: lua
+
+ cache.storage = 'lmdb://.'
+
+.. envvar:: cache.current_storage
+
+ Get the storage backend configuration.
+
+ .. code-block:: lua
+
+ print(cache.current_storage)
+
+.. function:: cache.backends()
+
+ :return: map of backends
+
+ .. note:: For now there is only one backend implementation, even though the APIs are ready for different (synchronous) backends.
+
+ The cache supports runtime-changeable backends, using the optional :rfc:`3986` URI, where the scheme
+ represents backend protocol and the rest of the URI backend-specific configuration. By default, it
+ is a ``lmdb`` backend in working directory, i.e. ``lmdb://``.
+
+ Example output:
+
+ .. code-block:: lua
+
+ [lmdb://] => true
+
+.. function:: cache.count()
+
+ :return: Number of entries in the cache. Meaning of the number is an implementation detail and is subject of change.
+
+.. function:: cache.close()
+
+ :return: ``true`` if cache was closed
+
+ Close the cache.
+
+ .. note:: This may or may not clear the cache, depending on the cache backend.
+
+.. function:: cache.fssize()
+
+ :return: Partition size of cache storage.
+
+.. function:: cache.stats()
+
+ Return table with low-level statistics for internal cache operation and storage.
+ This counts each access to cache and does not directly map to individual
+ DNS queries or resource records.
+ For query-level statistics see :ref:`stats module <mod-stats>`.
+
+ Example:
+
+ .. code-block:: lua
+
+ > cache.stats()
+ [clear] => 0
+ [close] => 0
+ [commit] => 117
+ [count] => 2
+ [count_entries] => 6187
+ [match] => 21
+ [match_miss] => 2
+ [open] => 0
+ [read] => 4313
+ [read_leq] => 9
+ [read_leq_miss] => 4
+ [read_miss] => 1143
+ [remove] => 17
+ [remove_miss] => 0
+ [usage_percent] => 15.625
+ [write] => 189
+
+
+ Cache operation `read_leq` (*read less or equal*, i.e. range search) was requested 9 times,
+ and 4 out of 9 operations were finished with *cache miss*.
+ Cache contains 6187 internal entries which occupy 15.625 % cache size.
+
+
+.. function:: cache.max_ttl([ttl])
+
+ :param number ttl: maximum TTL in seconds (default: 1 day)
+
+ .. KR_CACHE_DEFAULT_TTL_MAX ^^
+
+ :return: current maximum TTL
+
+ Get or set upper TTL bound applied to all received records.
+
+ .. note:: The `ttl` value must be in range `(min_ttl, 2147483647)`.
+
+ .. code-block:: lua
+
+ -- Get maximum TTL
+ cache.max_ttl()
+ 518400
+ -- Set maximum TTL
+ cache.max_ttl(172800)
+ 172800
+
+.. function:: cache.min_ttl([ttl])
+
+ :param number ttl: minimum TTL in seconds (default: 5 seconds)
+
+ .. KR_CACHE_DEFAULT_TTL_MIN ^^
+
+ :return: current minimum TTL
+
+ Get or set lower TTL bound applied to all received records.
+ Forcing TTL higher than specified violates DNS standards, so use higher values with care.
+ TTL still won't be extended beyond expiration of the corresponding DNSSEC signature.
+
+ .. note:: The `ttl` value must be in range `<0, max_ttl)`.
+
+ .. code-block:: lua
+
+ -- Get minimum TTL
+ cache.min_ttl()
+ 0
+ -- Set minimum TTL
+ cache.min_ttl(5)
+ 5
+
+.. function:: cache.ns_tout([timeout])
+
+ :param number timeout: NS retry interval in milliseconds (default: :c:macro:`KR_NS_TIMEOUT_RETRY_INTERVAL`)
+ :return: current timeout
+
+ Get or set time interval for which a nameserver address will be ignored after determining that it doesn't return (useful) answers.
+ The intention is to avoid waiting if there's little hope; instead, kresd can immediately SERVFAIL or immediately use stale records (with :ref:`serve_stale <mod-serve_stale>` module).
+
+ .. warning:: This settings applies only to the current kresd process.
+
+.. function:: cache.get([domain])
+
+ This function is not implemented at this moment.
+ We plan to re-introduce it soon, probably with a slightly different API.
+
+.. function:: cache.clear([name], [exact_name], [rr_type], [chunk_size], [callback], [prev_state])
+
+ Purge cache records matching specified criteria. There are two specifics:
+
+ * To reliably remove **negative** cache entries you need to clear subtree with the whole zone. E.g. to clear negative cache entries for (formerly non-existing) record `www.example.com. A` you need to flush whole subtree starting at zone apex, e.g. `example.com.` [#]_.
+ * This operation is asynchronous and might not be yet finished when call to ``cache.clear()`` function returns. Return value indicates if clearing continues asynchronously or not.
+
+ :param string name: subtree to purge; if the name isn't provided, whole cache is purged
+ (and any other parameters are disregarded).
+ :param bool exact_name: if set to ``true``, only records with *the same* name are removed;
+ default: false.
+ :param kres.type rr_type: you may additionally specify the type to remove,
+ but that is only supported with ``exact_name == true``; default: nil.
+ :param integer chunk_size: the number of records to remove in one round; default: 100.
+ The purpose is not to block the resolver for long.
+ The default ``callback`` repeats the command after one millisecond
+ until all matching data are cleared.
+ :param function callback: a custom code to handle result of the underlying C call.
+ Its parameters are copies of those passed to `cache.clear()` with one additional
+ parameter ``rettable`` containing table with return value from current call.
+ ``count`` field contains a return code from :func:`kr_cache_remove_subtree()`.
+ :param table prev_state: return value from previous run (can be used by callback)
+
+ :rtype: table
+ :return: ``count`` key is always present. Other keys are optional and their presence indicate special conditions.
+
+ * **count** *(integer)* - number of items removed from cache by this call (can be 0 if no entry matched criteria)
+ * **not_apex** - cleared subtree is not cached as zone apex; proofs of non-existence were probably not removed
+ * **subtree** *(string)* - hint where zone apex lies (this is estimation from cache content and might not be accurate)
+ * **chunk_limit** - more than ``chunk_size`` items needs to be cleared, clearing will continue asynchronously
+
+
+ Examples:
+
+ .. code-block:: lua
+
+ -- Clear whole cache
+ > cache.clear()
+ [count] => 76
+
+ -- Clear records at and below 'com.'
+ > cache.clear('com.')
+ [chunk_limit] => chunk size limit reached; the default callback will continue asynchronously
+ [not_apex] => to clear proofs of non-existence call cache.clear('com.')
+ [count] => 100
+ [round] => 1
+ [subtree] => com.
+ > worker.sleep(0.1)
+ [cache] asynchronous cache.clear('com', false) finished
+
+ -- Clear only 'www.example.com.'
+ > cache.clear('www.example.com.', true)
+ [round] => 1
+ [count] => 1
+ [not_apex] => to clear proofs of non-existence call cache.clear('example.com.')
+ [subtree] => example.com.
+
+.. [#] This is a consequence of DNSSEC negative cache which relies on proofs of non-existence on various owner nodes. It is impossible to efficiently flush part of DNS zones signed with NSEC3.
diff --git a/daemon/bindings/event.c b/daemon/bindings/event.c
new file mode 100644
index 0000000..4cefa13
--- /dev/null
+++ b/daemon/bindings/event.c
@@ -0,0 +1,209 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#include "daemon/bindings/impl.h"
+
+#include <unistd.h>
+#include <uv.h>
+
+static void event_free(uv_timer_t *timer)
+{
+ lua_State *L = the_worker->engine->L;
+ int ref = (intptr_t) timer->data;
+ luaL_unref(L, LUA_REGISTRYINDEX, ref);
+ free(timer);
+}
+
+static void event_callback(uv_timer_t *timer)
+{
+ lua_State *L = the_worker->engine->L;
+
+ /* Retrieve callback and execute */
+ lua_rawgeti(L, LUA_REGISTRYINDEX, (intptr_t) timer->data);
+ lua_rawgeti(L, -1, 1);
+ lua_pushinteger(L, (intptr_t) timer->data);
+ int ret = execute_callback(L, 1);
+ /* Free callback if not recurrent or an error */
+ if (ret != 0 || (uv_timer_get_repeat(timer) == 0 && uv_is_active((uv_handle_t *)timer) == 0)) {
+ if (!uv_is_closing((uv_handle_t *)timer)) {
+ uv_close((uv_handle_t *)timer, (uv_close_cb) event_free);
+ }
+ }
+}
+
+static void event_fdcallback(uv_poll_t* handle, int status, int events)
+{
+ lua_State *L = the_worker->engine->L;
+
+ /* Retrieve callback and execute */
+ lua_rawgeti(L, LUA_REGISTRYINDEX, (intptr_t) handle->data);
+ lua_rawgeti(L, -1, 1);
+ lua_pushinteger(L, (intptr_t) handle->data);
+ lua_pushinteger(L, status);
+ lua_pushinteger(L, events);
+ int ret = execute_callback(L, 3);
+ /* Free callback if not recurrent or an error */
+ if (ret != 0) {
+ if (!uv_is_closing((uv_handle_t *)handle)) {
+ uv_close((uv_handle_t *)handle, (uv_close_cb) event_free);
+ }
+ }
+}
+
+static int event_sched(lua_State *L, unsigned timeout, unsigned repeat)
+{
+ uv_timer_t *timer = malloc(sizeof(*timer));
+ if (!timer)
+ lua_error_p(L, "out of memory");
+
+ /* Start timer with the reference */
+ uv_loop_t *loop = uv_default_loop();
+ uv_timer_init(loop, timer);
+ int ret = uv_timer_start(timer, event_callback, timeout, repeat);
+ if (ret != 0) {
+ free(timer);
+ lua_error_p(L, "couldn't start the event");
+ }
+
+ /* Save callback and timer in registry */
+ lua_newtable(L);
+ lua_pushvalue(L, 2);
+ lua_rawseti(L, -2, 1);
+ lua_pushpointer(L, timer);
+ lua_rawseti(L, -2, 2);
+ int ref = luaL_ref(L, LUA_REGISTRYINDEX);
+
+ /* Save reference to the timer */
+ timer->data = (void *) (intptr_t)ref;
+ lua_pushinteger(L, ref);
+ return 1;
+}
+
+static int event_after(lua_State *L)
+{
+ /* Check parameters */
+ int n = lua_gettop(L);
+ if (n < 2 || !lua_isnumber(L, 1) || !lua_isfunction(L, 2))
+ lua_error_p(L, "expected 'after(number timeout, function)'");
+
+ return event_sched(L, lua_tointeger(L, 1), 0);
+}
+
+static int event_recurrent(lua_State *L)
+{
+ /* Check parameters */
+ int n = lua_gettop(L);
+ if (n < 2 || !lua_isnumber(L, 1) || lua_tointeger(L, 1) == 0
+ || !lua_isfunction(L, 2))
+ lua_error_p(L, "expected 'recurrent(number interval, function)'");
+
+ return event_sched(L, 0, lua_tointeger(L, 1));
+}
+
+static int event_cancel(lua_State *L)
+{
+ int n = lua_gettop(L);
+ if (n < 1 || !lua_isnumber(L, 1))
+ lua_error_p(L, "expected 'cancel(number event)'");
+
+ /* Fetch event if it exists */
+ lua_rawgeti(L, LUA_REGISTRYINDEX, lua_tointeger(L, 1));
+ bool ok = lua_istable(L, -1);
+
+ /* Close the timer */
+ uv_handle_t **timer_pp = NULL;
+ if (ok) {
+ lua_rawgeti(L, -1, 2);
+ timer_pp = lua_touserdata(L, -1);
+ ok = timer_pp && *timer_pp;
+ /* That have been sufficient safety checks, hopefully. */
+ }
+ if (ok && !uv_is_closing(*timer_pp)) {
+ uv_close(*timer_pp, (uv_close_cb)event_free);
+ }
+ lua_pushboolean(L, ok);
+ return 1;
+}
+
+static int event_reschedule(lua_State *L)
+{
+ int n = lua_gettop(L);
+ if (n < 2 || !lua_isnumber(L, 1) || !lua_isnumber(L, 2))
+ lua_error_p(L, "expected 'reschedule(number event, number timeout)'");
+
+ /* Fetch event if it exists */
+ lua_rawgeti(L, LUA_REGISTRYINDEX, lua_tointeger(L, 1));
+ bool ok = lua_istable(L, -1);
+
+ /* Reschedule the timer */
+ uv_handle_t **timer_pp = NULL;
+ if (ok) {
+ lua_rawgeti(L, -1, 2);
+ timer_pp = lua_touserdata(L, -1);
+ ok = timer_pp && *timer_pp;
+ /* That have been sufficient safety checks, hopefully. */
+ }
+ if (ok && !uv_is_closing(*timer_pp)) {
+ int ret = uv_timer_start((uv_timer_t *)*timer_pp,
+ event_callback, lua_tointeger(L, 2), 0);
+ if (ret != 0) {
+ uv_close(*timer_pp, (uv_close_cb)event_free);
+ ok = false;
+ }
+ }
+ lua_pushboolean(L, ok);
+ return 1;
+}
+
+static int event_fdwatch(lua_State *L)
+{
+ /* Check parameters */
+ int n = lua_gettop(L);
+ if (n < 2 || !lua_isnumber(L, 1) || !lua_isfunction(L, 2))
+ lua_error_p(L, "expected 'socket(number fd, function)'");
+
+ uv_poll_t *handle = malloc(sizeof(*handle));
+ if (!handle)
+ lua_error_p(L, "out of memory");
+
+ /* Start timer with the reference */
+ int sock = lua_tointeger(L, 1);
+ uv_loop_t *loop = uv_default_loop();
+ int ret = uv_poll_init(loop, handle, sock);
+ if (ret == 0)
+ ret = uv_poll_start(handle, UV_READABLE, event_fdcallback);
+ if (ret != 0) {
+ free(handle);
+ lua_error_p(L, "couldn't start event poller");
+ }
+
+ /* Save callback and timer in registry */
+ lua_newtable(L);
+ lua_pushvalue(L, 2);
+ lua_rawseti(L, -2, 1);
+ lua_pushpointer(L, handle);
+ lua_rawseti(L, -2, 2);
+ int ref = luaL_ref(L, LUA_REGISTRYINDEX);
+
+ /* Save reference to the timer */
+ handle->data = (void *) (intptr_t)ref;
+ lua_pushinteger(L, ref);
+ return 1;
+}
+
+int kr_bindings_event(lua_State *L)
+{
+ static const luaL_Reg lib[] = {
+ { "after", event_after },
+ { "recurrent", event_recurrent },
+ { "cancel", event_cancel },
+ { "socket", event_fdwatch },
+ { "reschedule", event_reschedule },
+ { NULL, NULL }
+ };
+
+ luaL_register(L, "event", lib);
+ return 1;
+}
+
diff --git a/daemon/bindings/event.rst b/daemon/bindings/event.rst
new file mode 100644
index 0000000..a96f299
--- /dev/null
+++ b/daemon/bindings/event.rst
@@ -0,0 +1,139 @@
+.. SPDX-License-Identifier: GPL-3.0-or-later
+
+Timers and events reference
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The timer represents exactly the thing described in the examples - it allows you to execute closures_
+after specified time, or event recurrent events. Time is always described in milliseconds,
+but there are convenient variables that you can use - ``sec, minute, hour``.
+For example, ``5 * hour`` represents five hours, or 5*60*60*100 milliseconds.
+
+.. function:: event.after(time, function)
+
+ :return: event id
+
+ Execute function after the specified time has passed.
+ The first parameter of the callback is the event itself.
+
+ Example:
+
+ .. code-block:: lua
+
+ event.after(1 * minute, function() print('Hi!') end)
+
+.. function:: event.recurrent(interval, function)
+
+ :return: event id
+
+ Execute function immediately and then periodically after each ``interval``.
+
+ Example:
+
+ .. code-block:: lua
+
+ msg_count = 0
+ event.recurrent(5 * sec, function(e)
+ msg_count = msg_count + 1
+ print('Hi #'..msg_count)
+ end)
+
+.. function:: event.reschedule(event_id, timeout)
+
+ Reschedule a running event, it has no effect on canceled events.
+ New events may reuse the event_id, so the behaviour is undefined if the function
+ is called after another event is started.
+
+ Example:
+
+ .. code-block:: lua
+
+ local interval = 1 * minute
+ event.after(1 * minute, function (ev)
+ print('Good morning!')
+ -- Halve the interval for each iteration
+ interval = interval / 2
+ event.reschedule(ev, interval)
+ end)
+
+.. function:: event.cancel(event_id)
+
+ Cancel running event, it has no effect on already canceled events.
+ New events may reuse the event_id, so the behaviour is undefined if the function
+ is called after another event is started.
+
+ Example:
+
+ .. code-block:: lua
+
+ e = event.after(1 * minute, function() print('Hi!') end)
+ event.cancel(e)
+
+Watch for file descriptor activity. This allows embedding other event loops or simply
+firing events when a pipe endpoint becomes active. In another words, asynchronous
+notifications for daemon.
+
+.. function:: event.socket(fd, cb)
+
+ :param number fd: file descriptor to watch
+ :param cb: closure or callback to execute when fd becomes active
+ :return: event id
+
+ Execute function when there is activity on the file descriptor and calls a closure
+ with event id as the first parameter, status as second and number of events as third.
+
+ Example:
+
+ .. code-block:: lua
+
+ e = event.socket(0, function(e, status, nevents)
+ print('activity detected')
+ end)
+ e.cancel(e)
+
+Asynchronous function execution
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The `event` package provides a very basic mean for non-blocking execution - it allows running code when activity on a file descriptor is detected, and when a certain amount of time passes. It doesn't however provide an easy to use abstraction for non-blocking I/O. This is instead exposed through the `worker` package (if `cqueues` Lua package is installed in the system).
+
+.. function:: worker.coroutine(function)
+
+ Start a new coroutine with given function (closure). The function can do I/O or run timers without blocking the main thread. See cqueues_ for documentation of possible operations and synchronization primitives. The main limitation is that you can't wait for a finish of a coroutine from processing layers, because it's not currently possible to suspend and resume execution of processing layers.
+
+ Example:
+
+ .. code-block:: lua
+
+ worker.coroutine(function ()
+ for i = 0, 10 do
+ print('executing', i)
+ worker.sleep(1)
+ end
+ end)
+
+.. function:: worker.sleep(seconds)
+
+ Pause execution of current function (asynchronously if running inside a worker coroutine).
+
+Example:
+
+.. code-block:: lua
+
+ function async_print(testname, sleep)
+ log(testname .. ': system time before sleep' .. tostring(os.time())
+ worker.sleep(sleep) -- other coroutines continue execution now
+ log(testname .. ': system time AFTER sleep' .. tostring(os.time())
+ end
+
+ worker.coroutine(function() async_print('call #1', 5) end)
+ worker.coroutine(function() async_print('call #2', 3) end)
+
+Output from this example demonstrates that both calls to function ``async_print`` were executed asynchronously:
+
+
+.. code-block:: none
+
+ call #2: system time before sleep 1578065073
+ call #1: system time before sleep 1578065073
+ call #2: system time AFTER sleep 1578065076
+ call #1: system time AFTER sleep 1578065078
+
diff --git a/daemon/bindings/impl.c b/daemon/bindings/impl.c
new file mode 100644
index 0000000..8c48df8
--- /dev/null
+++ b/daemon/bindings/impl.c
@@ -0,0 +1,95 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#include <dirent.h>
+#include <lua.h>
+#include <lauxlib.h>
+#include <string.h>
+
+
+const char * lua_table_checkindices(lua_State *L, const char *keys[])
+{
+ /* Iterate over table at the top of the stack.
+ * http://www.lua.org/manual/5.1/manual.html#lua_next */
+ for (lua_pushnil(L); lua_next(L, -2); lua_pop(L, 1)) {
+ lua_pop(L, 1); /* we don't need the value */
+ /* We need to copy the key, as _tostring() confuses _next().
+ * https://www.lua.org/manual/5.1/manual.html#lua_tolstring */
+ lua_pushvalue(L, -1);
+ const char *key = lua_tostring(L, -1);
+ if (!key)
+ return "<NON-STRING_INDEX>";
+ for (const char **k = keys; ; ++k) {
+ if (*k == NULL)
+ return key;
+ if (strcmp(*k, key) == 0)
+ break;
+ }
+ }
+ return NULL;
+}
+
+/** Return table listing filenames in a given directory (ls -A). */
+static int kluautil_list_dir(lua_State *L)
+{
+ lua_newtable(L); // empty table even on errors
+
+ const char *path = lua_tolstring(L, 1, NULL);
+ if (!path) return 1;
+ DIR *dir = opendir(path);
+ if (!dir) return 1;
+
+ struct dirent *entry;
+ int lua_i = 1;
+ while ((entry = readdir(dir)) != NULL) {
+ if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0) {
+ lua_pushstring(L, entry->d_name);
+ lua_rawseti(L, -2, lua_i++);
+ }
+ }
+
+ closedir(dir);
+ return 1;
+}
+
+
+/* Each of these just creates the correspondingly named lua table of functions. */
+int kr_bindings_cache (lua_State *L); /* ./cache.c */
+int kr_bindings_event (lua_State *L); /* ./event.c */
+int kr_bindings_modules (lua_State *L); /* ./modules.c */
+int kr_bindings_net (lua_State *L); /* ./net.c */
+int kr_bindings_worker (lua_State *L); /* ./worker.c */
+
+void kr_bindings_register(lua_State *L)
+{
+ kr_bindings_cache(L);
+ kr_bindings_event(L);
+ kr_bindings_modules(L);
+ kr_bindings_net(L);
+ kr_bindings_worker(L);
+
+ /* Finally some lua utils *written in C*, not really a binding. */
+ lua_register(L, "kluautil_list_dir", kluautil_list_dir);
+}
+
+void lua_error_p(lua_State *L, const char *fmt, ...)
+{
+ /* Add a stack trace and throw the result as a lua error. */
+ luaL_traceback(L, L, "error occurred here (config filename:lineno is at the bottom, if config is involved):", 0);
+ /* Push formatted custom message, prepended with "ERROR: ". */
+ lua_pushliteral(L, "\nERROR: ");
+ {
+ va_list args;
+ va_start(args, fmt);
+ lua_pushvfstring(L, fmt, args);
+ va_end(args);
+ }
+ lua_concat(L, 3);
+ lua_error(L);
+ /* TODO: we might construct a little more friendly trace by using luaL_where().
+ * In particular, in case the error happens in a function that was called
+ * directly from a config file (the most common case), there isn't much need
+ * to format the trace in this heavy way. */
+}
+
diff --git a/daemon/bindings/impl.h b/daemon/bindings/impl.h
new file mode 100644
index 0000000..d522756
--- /dev/null
+++ b/daemon/bindings/impl.h
@@ -0,0 +1,90 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#include "daemon/engine.h"
+#include "daemon/worker.h" /* the_worker is often useful */
+
+#include <lua.h>
+#include <lauxlib.h>
+/* It may happen that include files are messed up and we're hitting a header
+ * e.g. from vanilla Lua. Even 5.1 won't work due to missing luaL_traceback() in <lauxlib.h>. */
+#if (LUA_VERSION_NUM) != 501 || !defined(LUA_LJDIR)
+ #error "Incorrect Lua version in #include <lua.h> - LuaJIT compatible with Lua 5.1 is required"
+#endif
+
+
+/** Useful to stringify macros into error strings. */
+#define STR(s) STRINGIFY_TOKEN(s)
+#define STRINGIFY_TOKEN(s) #s
+
+
+/** Check lua table at the top of the stack for allowed keys.
+ * \param keys NULL-terminated array of 0-terminated strings
+ * \return NULL if passed or the offending string (pushed on top of lua stack)
+ * \note Future work: if non-NULL is returned, there's extra stuff on the lua stack.
+ * \note Brute-force complexity: table length * summed length of keys.
+ */
+const char * lua_table_checkindices(lua_State *L, const char *keys[]);
+
+/** If the value at the top of the stack isn't a table, make it a single-element list. */
+static inline void lua_listify(lua_State *L)
+{
+ if (lua_istable(L, -1))
+ return;
+ lua_createtable(L, 1, 0);
+ lua_insert(L, lua_gettop(L) - 1); /* swap the top two stack elements */
+ lua_pushinteger(L, 1);
+ lua_insert(L, lua_gettop(L) - 1); /* swap the top two stack elements */
+ lua_settable(L, -3);
+}
+
+
+/** Throw a formatted lua error.
+ *
+ * The message will get prefixed by "ERROR: " and supplemented by stack trace.
+ * \return never! It calls lua_error().
+ *
+ * Example:
+ ERROR: not a valid pin_sha256: 'a1Z/3ek=', raw length 5 instead of 32
+ stack traceback:
+ [C]: in function 'tls_client'
+ /PathToPREFIX/lib/kdns_modules/policy.lua:175: in function 'TLS_FORWARD'
+ /PathToConfig.lua:46: in main chunk
+ */
+KR_PRINTF(2) KR_NORETURN KR_COLD
+void lua_error_p(lua_State *L, const char *fmt, ...);
+/** @internal Annotate for static checkers. */
+KR_NORETURN int lua_error(lua_State *L);
+
+/** Shortcut for common case. */
+static inline void lua_error_maybe(lua_State *L, int err)
+{
+ if (err) lua_error_p(L, "%s", kr_strerror(err));
+}
+
+static inline int execute_callback(lua_State *L, int argc)
+{
+ int ret = engine_pcall(L, argc);
+ if (ret != 0) {
+ kr_log_error(SYSTEM, "error: %s\n", lua_tostring(L, -1));
+ }
+ /* Clear the stack, there may be event a/o anything returned */
+ lua_settop(L, 0);
+ return ret;
+}
+
+/** Push a pointer as heavy/full userdata.
+ *
+ * It's useful as a replacement of lua_pushlightuserdata(),
+ * but note that it behaves differently in lua (converts to pointer-to-pointer).
+ */
+static inline void lua_pushpointer(lua_State *L, void *p)
+{
+ void **addr = lua_newuserdata(L, sizeof(void *));
+ kr_require(addr);
+ memcpy(addr, &p, sizeof(void *));
+}
+
diff --git a/daemon/bindings/modules.c b/daemon/bindings/modules.c
new file mode 100644
index 0000000..acae270
--- /dev/null
+++ b/daemon/bindings/modules.c
@@ -0,0 +1,77 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#include "daemon/bindings/impl.h"
+
+
+/** List loaded modules */
+static int mod_list(lua_State *L)
+{
+ const module_array_t * const modules = &the_worker->engine->modules;
+ lua_newtable(L);
+ for (unsigned i = 0; i < modules->len; ++i) {
+ struct kr_module *module = modules->at[i];
+ lua_pushstring(L, module->name);
+ lua_rawseti(L, -2, i + 1);
+ }
+ return 1;
+}
+
+/** Load module. */
+static int mod_load(lua_State *L)
+{
+ /* Check parameters */
+ int n = lua_gettop(L);
+ if (n != 1 || !lua_isstring(L, 1))
+ lua_error_p(L, "expected 'load(string name)'");
+ /* Parse precedence declaration */
+ char *declaration = strdup(lua_tostring(L, 1));
+ if (!declaration)
+ return kr_error(ENOMEM);
+ const char *name = strtok(declaration, " ");
+ const char *precedence = strtok(NULL, " ");
+ const char *ref = strtok(NULL, " ");
+ /* Load engine module */
+ int ret = engine_register(the_worker->engine, name, precedence, ref);
+ free(declaration);
+ if (ret != 0) {
+ if (ret == kr_error(EIDRM)) {
+ lua_error_p(L, "referenced module not found");
+ } else {
+ lua_error_maybe(L, ret);
+ }
+ }
+
+ lua_pushboolean(L, 1);
+ return 1;
+}
+
+/** Unload module. */
+static int mod_unload(lua_State *L)
+{
+ /* Check parameters */
+ int n = lua_gettop(L);
+ if (n != 1 || !lua_isstring(L, 1))
+ lua_error_p(L, "expected 'unload(string name)'");
+ /* Unload engine module */
+ int ret = engine_unregister(the_worker->engine, lua_tostring(L, 1));
+ lua_error_maybe(L, ret);
+
+ lua_pushboolean(L, 1);
+ return 1;
+}
+
+int kr_bindings_modules(lua_State *L)
+{
+ static const luaL_Reg lib[] = {
+ { "list", mod_list },
+ { "load", mod_load },
+ { "unload", mod_unload },
+ { NULL, NULL }
+ };
+
+ luaL_register(L, "modules", lib);
+ return 1;
+}
+
diff --git a/daemon/bindings/modules.rst b/daemon/bindings/modules.rst
new file mode 100644
index 0000000..09df6ff
--- /dev/null
+++ b/daemon/bindings/modules.rst
@@ -0,0 +1,43 @@
+.. SPDX-License-Identifier: GPL-3.0-or-later
+
+Modules
+=======
+
+Knot Resolver functionality consists of separate modules, which allow you
+to mix-and-match features you need without slowing down operation
+by features you do not use.
+
+This practically means that you need to load module before using features contained in it, for example:
+
+.. code-block:: lua
+
+ -- load module and make dnstap features available
+ modules.load('dnstap')
+ -- configure dnstap features
+ dnstap.config({
+ socket_path = "/tmp/dnstap.sock"
+ })
+
+Obviously ordering matters, so you have to load module first and configure it after it is loaded.
+
+Here is full reference manual for module configuration:
+
+
+.. function:: modules.list()
+
+ :return: List of loaded modules.
+
+.. function:: modules.load(name)
+
+ :param string name: Module name, e.g. "hints"
+ :return: ``true`` if modules was (or already is) loaded, error otherwise.
+
+ Load a module by name.
+
+.. function:: modules.unload(name)
+
+ :param string name: Module name, e.g. "detect_time_jump"
+ :return: ``true`` if modules was unloaded, error otherwise.
+
+ Unload a module by name. This is useful for unloading modules loaded by default, mainly for debugging purposes.
+
diff --git a/daemon/bindings/net.c b/daemon/bindings/net.c
new file mode 100644
index 0000000..f1fa6f3
--- /dev/null
+++ b/daemon/bindings/net.c
@@ -0,0 +1,1260 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#include "daemon/bindings/impl.h"
+
+#include "contrib/base64.h"
+#include "contrib/cleanup.h"
+#include "daemon/network.h"
+#include "daemon/tls.h"
+#include "lib/utils.h"
+
+#include <stdlib.h>
+
+#define PROXY_DATA_STRLEN (INET6_ADDRSTRLEN + 1 + 3 + 1)
+
+/** Table and next index on top of stack -> append entries for given endpoint_array_t. */
+static int net_list_add(const char *b_key, uint32_t key_len, trie_val_t *val, void *ext)
+{
+ endpoint_array_t *ep_array = *val;
+ lua_State *L = (lua_State *)ext;
+ lua_Integer i = lua_tointeger(L, -1);
+ for (int j = 0; j < ep_array->len; ++j) {
+ struct endpoint *ep = &ep_array->at[j];
+ lua_newtable(L); // connection tuple
+
+ if (ep->flags.kind) {
+ lua_pushstring(L, ep->flags.kind);
+ } else if (ep->flags.http && ep->flags.tls) {
+ lua_pushliteral(L, "doh2");
+ } else if (ep->flags.tls) {
+ lua_pushliteral(L, "tls");
+ } else if (ep->flags.xdp) {
+ lua_pushliteral(L, "xdp");
+ } else {
+ lua_pushliteral(L, "dns");
+ }
+ lua_setfield(L, -2, "kind");
+
+ lua_newtable(L); // "transport" table
+
+ switch (ep->family) {
+ case AF_INET:
+ lua_pushliteral(L, "inet4");
+ break;
+ case AF_INET6:
+ lua_pushliteral(L, "inet6");
+ break;
+ case AF_XDP:
+ lua_pushliteral(L, "inet4+inet6"); // both UDP ports at once
+ break;
+ case AF_UNIX:
+ lua_pushliteral(L, "unix");
+ break;
+ default:
+ kr_assert(false);
+ lua_pushliteral(L, "invalid");
+ }
+ lua_setfield(L, -2, "family");
+
+ const char *ip_str_const = network_endpoint_key_str((struct endpoint_key *) b_key);
+ kr_require(ip_str_const);
+ auto_free char *ip_str = strdup(ip_str_const);
+ kr_require(ip_str);
+ char *hm = strchr(ip_str, '#');
+ if (hm) /* Omit port */
+ *hm = '\0';
+ lua_pushstring(L, ip_str);
+
+ if (ep->family == AF_INET || ep->family == AF_INET6) {
+ lua_setfield(L, -2, "ip");
+ lua_pushboolean(L, ep->flags.freebind);
+ lua_setfield(L, -2, "freebind");
+ } else if (ep->family == AF_UNIX) {
+ lua_setfield(L, -2, "path");
+ } else if (ep->family == AF_XDP) {
+ lua_setfield(L, -2, "interface");
+ lua_pushinteger(L, ep->nic_queue);
+ lua_setfield(L, -2, "nic_queue");
+ }
+
+ if (ep->family != AF_UNIX) {
+ lua_pushinteger(L, ep->port);
+ lua_setfield(L, -2, "port");
+ }
+
+ if (ep->family == AF_UNIX) {
+ lua_pushliteral(L, "stream");
+ } else if (ep->flags.sock_type == SOCK_STREAM) {
+ lua_pushliteral(L, "tcp");
+ } else if (ep->flags.sock_type == SOCK_DGRAM) {
+ lua_pushliteral(L, "udp");
+ } else {
+ kr_assert(false);
+ lua_pushliteral(L, "invalid");
+ }
+ lua_setfield(L, -2, "protocol");
+
+ lua_setfield(L, -2, "transport");
+
+ lua_settable(L, -3);
+ i++;
+ lua_pushinteger(L, i);
+ }
+ return kr_ok();
+}
+
+/** List active endpoints. */
+static int net_list(lua_State *L)
+{
+ lua_newtable(L);
+ lua_pushinteger(L, 1);
+ trie_apply_with_key(the_worker->engine->net.endpoints, net_list_add, L);
+ lua_pop(L, 1);
+ return 1;
+}
+
+/** Listen on an address list represented by the top of lua stack.
+ * \note flags.kind ownership is not transferred, and flags.sock_type doesn't make sense
+ * \return success */
+static bool net_listen_addrs(lua_State *L, int port, endpoint_flags_t flags, int16_t nic_queue)
+{
+ if (kr_fails_assert(flags.xdp || nic_queue == -1))
+ return false;
+
+ /* Case: table with 'addr' field; only follow that field directly. */
+ lua_getfield(L, -1, "addr");
+ if (!lua_isnil(L, -1)) {
+ lua_replace(L, -2);
+ } else {
+ lua_pop(L, 1);
+ }
+
+ /* Case: string, representing a single address. */
+ const char *str = lua_tostring(L, -1);
+ if (str != NULL) {
+ struct network *net = &the_worker->engine->net;
+ const bool is_unix = str[0] == '/';
+ int ret = 0;
+ if (!flags.kind && !flags.tls) { /* normal UDP or XDP */
+ flags.sock_type = SOCK_DGRAM;
+ ret = network_listen(net, str, port, nic_queue, flags);
+ }
+ if (!flags.kind && !flags.xdp && ret == 0) { /* common for TCP, DoT and DoH (v2) */
+ flags.sock_type = SOCK_STREAM;
+ ret = network_listen(net, str, port, nic_queue, flags);
+ }
+ if (flags.kind) {
+ flags.kind = strdup(flags.kind);
+ flags.sock_type = SOCK_STREAM; /* TODO: allow to override this? */
+ ret = network_listen(net, str, (is_unix ? 0 : port), nic_queue, flags);
+ }
+ if (ret == 0) return true; /* success */
+
+ if (is_unix) {
+ kr_log_error(NETWORK, "bind to '%s' (UNIX): %s\n",
+ str, kr_strerror(ret));
+ } else if (flags.xdp) {
+ const char *err_str = knot_strerror(ret);
+ if (ret == KNOT_ELIMIT) {
+ if ((strcmp(str, "::") == 0 || strcmp(str, "0.0.0.0") == 0)) {
+ err_str = "wildcard addresses not supported with XDP";
+ } else {
+ err_str = "address matched multiple network interfaces";
+ }
+ } else if (ret == kr_error(ENODEV)) {
+ err_str = "invalid address or interface name";
+ }
+ /* Notable OK strerror: KNOT_EPERM Operation not permitted */
+
+ if (nic_queue == -1) {
+ kr_log_error(NETWORK, "failed to initialize XDP for '%s@%d'"
+ " (nic_queue = <auto>): %s\n",
+ str, port, err_str);
+ } else {
+ kr_log_error(NETWORK, "failed to initialize XDP for '%s@%d'"
+ " (nic_queue = %d): %s\n",
+ str, port, nic_queue, err_str);
+ }
+
+ } else {
+ const char *stype = flags.sock_type == SOCK_DGRAM ? "UDP" : "TCP";
+ kr_log_error(NETWORK, "bind to '%s@%d' (%s): %s\n",
+ str, port, stype, kr_strerror(ret));
+ }
+ return false; /* failure */
+ }
+
+ /* Last case: table where all entries are added recursively. */
+ if (!lua_istable(L, -1))
+ lua_error_p(L, "bad type for address");
+ lua_pushnil(L);
+ while (lua_next(L, -2)) {
+ if (!net_listen_addrs(L, port, flags, nic_queue))
+ return false;
+ lua_pop(L, 1);
+ }
+ return true;
+}
+
+static bool table_get_flag(lua_State *L, int index, const char *key, bool def)
+{
+ bool result = def;
+ lua_getfield(L, index, key);
+ if (lua_isboolean(L, -1)) {
+ result = lua_toboolean(L, -1);
+ }
+ lua_pop(L, 1);
+ return result;
+}
+
+/** Listen on endpoint. */
+static int net_listen(lua_State *L)
+{
+ /* Check parameters */
+ int n = lua_gettop(L);
+ if (n < 1 || n > 3) {
+ lua_error_p(L, "expected one to three arguments; usage:\n"
+ "net.listen(addresses, [port = " STR(KR_DNS_PORT)
+ ", flags = {tls = (port == " STR(KR_DNS_TLS_PORT) ")}])\n");
+ }
+
+ int port = KR_DNS_PORT;
+ if (n > 1) {
+ if (lua_isnumber(L, 2)) {
+ port = lua_tointeger(L, 2);
+ } else
+ if (!lua_isnil(L, 2)) {
+ lua_error_p(L, "wrong type of second parameter (port number)");
+ }
+ }
+
+ endpoint_flags_t flags = { 0 };
+ if (port == KR_DNS_TLS_PORT) {
+ flags.tls = true;
+ } else if (port == KR_DNS_DOH_PORT) {
+ flags.http = flags.tls = true;
+ }
+
+ int16_t nic_queue = -1;
+ if (n > 2 && !lua_isnil(L, 3)) {
+ if (!lua_istable(L, 3))
+ lua_error_p(L, "wrong type of third parameter (table expected)");
+ flags.tls = table_get_flag(L, 3, "tls", flags.tls);
+ flags.freebind = table_get_flag(L, 3, "freebind", false);
+
+ lua_getfield(L, 3, "kind");
+ const char *k = lua_tostring(L, -1);
+ if (k && strcasecmp(k, "dns") == 0) {
+ flags.tls = flags.http = false;
+ } else if (k && strcasecmp(k, "xdp") == 0) {
+ flags.tls = flags.http = false;
+ flags.xdp = true;
+ } else if (k && strcasecmp(k, "tls") == 0) {
+ flags.tls = true;
+ flags.http = false;
+ } else if (k && strcasecmp(k, "doh2") == 0) {
+ flags.tls = flags.http = true;
+ } else if (k) {
+ flags.kind = k;
+ if (strcasecmp(k, "doh") == 0) {
+ lua_error_p(L, "kind=\"doh\" was renamed to kind=\"doh_legacy\", switch to the new implementation with kind=\"doh2\" or update your config");
+ }
+ }
+
+ lua_getfield(L, 3, "nic_queue");
+ if (lua_isnumber(L, -1)) {
+ if (flags.xdp) {
+ nic_queue = lua_tointeger(L, -1);
+ } else {
+ lua_error_p(L, "nic_queue only supported with kind = 'xdp'");
+ }
+ } else if (!lua_isnil(L, -1)) {
+ lua_error_p(L, "wrong value of nic_queue (integer expected)");
+ }
+ }
+
+ /* Memory management of `kind` string is difficult due to longjmp etc.
+ * Pop will unreference the lua value, so we store it on C stack instead (!) */
+ const int kind_alen = flags.kind ? strlen(flags.kind) + 1 : 1 /* 0 length isn't C standard */;
+ char kind_buf[kind_alen];
+ if (flags.kind) {
+ memcpy(kind_buf, flags.kind, kind_alen);
+ flags.kind = kind_buf;
+ }
+
+ /* Now focus on the first argument. */
+ lua_settop(L, 1);
+ if (!net_listen_addrs(L, port, flags, nic_queue))
+ lua_error_p(L, "net.listen() failed to bind");
+ lua_pushboolean(L, true);
+ return 1;
+}
+
+/** Prints the specified `data` into the specified `dst` buffer. */
+static char *proxy_data_to_string(int af, const struct net_proxy_data *data,
+ char *dst, size_t size)
+{
+ kr_assert(size >= PROXY_DATA_STRLEN);
+ const void *in_addr = (af == AF_INET)
+ ? (void *) &data->addr.ip4
+ : (void *) &data->addr.ip6;
+ char *cur = dst;
+
+ const char *ret = inet_ntop(af, in_addr, cur, size);
+ if (!ret)
+ return NULL;
+
+ cur += strlen(cur); /*< advance cursor to after the address */
+ *(cur++) = '/';
+ int masklen = snprintf(cur, 3 + 1, "%u", data->netmask);
+ cur[masklen] = '\0';
+ return dst;
+}
+
+/** Put all IP addresses from `trie` into the table at the top of the Lua stack.
+ * For each address, increment the integer at `i`. All addresses in `trie` must
+ * be from the specified `family`. */
+static void net_proxy_addr_put(lua_State *L, int family, trie_t *trie, int *i)
+{
+ char addrbuf[PROXY_DATA_STRLEN];
+ const char *addr;
+ trie_it_t *it;
+ for (it = trie_it_begin(trie); !trie_it_finished(it); trie_it_next(it)) {
+ lua_pushinteger(L, *i);
+ struct net_proxy_data *data = *trie_it_val(it);
+ addr = proxy_data_to_string(family, data,
+ addrbuf, sizeof(addrbuf));
+ lua_pushstring(L, addr);
+ lua_settable(L, -3);
+ *i += 1;
+ }
+ trie_it_free(it);
+}
+
+/** Allow PROXYv2 headers for IP address. */
+static int net_proxy_allowed(lua_State *L)
+{
+ struct network *net = &the_worker->engine->net;
+ int n = lua_gettop(L);
+ int i = 1;
+ const char *addr;
+
+ /* Return current state */
+ if (n == 0) {
+ lua_newtable(L);
+ i = 1;
+
+ if (net->proxy_all4) {
+ lua_pushinteger(L, i);
+ lua_pushstring(L, "0.0.0.0/0");
+ lua_settable(L, -3);
+ i += 1;
+ } else {
+ net_proxy_addr_put(L, AF_INET, net->proxy_addrs4, &i);
+ }
+
+ if (net->proxy_all6) {
+ lua_pushinteger(L, i);
+ lua_pushstring(L, "::/0");
+ lua_settable(L, -3);
+ i += 1;
+ } else {
+ net_proxy_addr_put(L, AF_INET6, net->proxy_addrs6, &i);
+ }
+
+ return 1;
+ }
+
+ if (n != 1)
+ lua_error_p(L, "net.proxy_allowed() takes one parameter (string or table)");
+
+ if (!lua_istable(L, 1) && !lua_isstring(L, 1))
+ lua_error_p(L, "net.proxy_allowed() argument must be string or table");
+
+ /* Reset allowed proxy addresses */
+ network_proxy_reset(net);
+
+ /* Add new proxy addresses */
+ if (lua_istable(L, 1)) {
+ for (i = 1; !lua_isnil(L, -1); i++) {
+ lua_pushinteger(L, i);
+ lua_gettable(L, 1);
+ if (lua_isnil(L, -1)) /* missing value - end iteration */
+ break;
+ if (!lua_isstring(L, -1))
+ lua_error_p(L, "net.proxy_allowed() argument may only contain strings");
+ addr = lua_tostring(L, -1);
+ int ret = network_proxy_allow(net, addr);
+ if (ret)
+ lua_error_p(L, "invalid argument");
+ }
+ } else if (lua_isstring(L, 1)) {
+ addr = lua_tostring(L, 1);
+ int ret = network_proxy_allow(net, addr);
+ if (ret)
+ lua_error_p(L, "invalid argument");
+ }
+
+ return 0;
+}
+
+/** Close endpoint. */
+static int net_close(lua_State *L)
+{
+ /* Check parameters */
+ const int n = lua_gettop(L);
+ bool ok = (n == 1 || n == 2) && lua_isstring(L, 1);
+ const char *addr = lua_tostring(L, 1);
+ int port;
+ if (ok && (n < 2 || lua_isnil(L, 2))) {
+ port = -1;
+ } else if (ok) {
+ ok = lua_isnumber(L, 2);
+ port = lua_tointeger(L, 2);
+ ok = ok && port >= 0 && port <= 65535;
+ }
+ if (!ok)
+ lua_error_p(L, "expected 'close(string addr, [number port])'");
+
+ int ret = network_close(&the_worker->engine->net, addr, port);
+ lua_pushboolean(L, ret == 0);
+ return 1;
+}
+
+/** List available interfaces. */
+static int net_interfaces(lua_State *L)
+{
+ /* Retrieve interface list */
+ int count = 0;
+ char buf[INET6_ADDRSTRLEN]; /* https://tools.ietf.org/html/rfc4291 */
+ uv_interface_address_t *info = NULL;
+ uv_interface_addresses(&info, &count);
+ lua_newtable(L);
+ for (int i = 0; i < count; ++i) {
+ uv_interface_address_t iface = info[i];
+ lua_getfield(L, -1, iface.name);
+ if (lua_isnil(L, -1)) {
+ lua_pop(L, 1);
+ lua_newtable(L);
+ }
+
+ /* Address */
+ lua_getfield(L, -1, "addr");
+ if (lua_isnil(L, -1)) {
+ lua_pop(L, 1);
+ lua_newtable(L);
+ }
+ if (iface.address.address4.sin_family == AF_INET) {
+ uv_ip4_name(&iface.address.address4, buf, sizeof(buf));
+ } else if (iface.address.address4.sin_family == AF_INET6) {
+ uv_ip6_name(&iface.address.address6, buf, sizeof(buf));
+ } else {
+ buf[0] = '\0';
+ }
+
+ if (kr_sockaddr_link_local((struct sockaddr *) &iface.address)) {
+ /* Link-local IPv6: add %interface prefix */
+ auto_free char *str = NULL;
+ int ret = asprintf(&str, "%s%%%s", buf, iface.name);
+ kr_assert(ret > 0);
+ lua_pushstring(L, str);
+ } else {
+ lua_pushstring(L, buf);
+ }
+
+ lua_rawseti(L, -2, lua_objlen(L, -2) + 1);
+ lua_setfield(L, -2, "addr");
+
+ /* Hardware address. */
+ char *p = buf;
+ for (int k = 0; k < sizeof(iface.phys_addr); ++k) {
+ sprintf(p, "%.2x:", (uint8_t)iface.phys_addr[k]);
+ p += 3;
+ }
+ p[-1] = '\0';
+ lua_pushstring(L, buf);
+ lua_setfield(L, -2, "mac");
+
+ /* Push table */
+ lua_setfield(L, -2, iface.name);
+ }
+ uv_free_interface_addresses(info, count);
+
+ return 1;
+}
+
+/** Set UDP maximum payload size. */
+static int net_bufsize(lua_State *L)
+{
+ struct kr_context *ctx = &the_worker->engine->resolver;
+ const int argc = lua_gettop(L);
+ if (argc == 0) {
+ lua_pushinteger(L, knot_edns_get_payload(ctx->downstream_opt_rr));
+ lua_pushinteger(L, knot_edns_get_payload(ctx->upstream_opt_rr));
+ return 2;
+ }
+
+ if (argc == 1) {
+ int bufsize = lua_tointeger(L, 1);
+ if (bufsize < 512 || bufsize > UINT16_MAX)
+ lua_error_p(L, "bufsize must be within <512, " STR(UINT16_MAX) ">");
+ knot_edns_set_payload(ctx->downstream_opt_rr, (uint16_t)bufsize);
+ knot_edns_set_payload(ctx->upstream_opt_rr, (uint16_t)bufsize);
+ } else if (argc == 2) {
+ int bufsize_downstream = lua_tointeger(L, 1);
+ int bufsize_upstream = lua_tointeger(L, 2);
+ if (bufsize_downstream < 512 || bufsize_upstream < 512
+ || bufsize_downstream > UINT16_MAX || bufsize_upstream > UINT16_MAX) {
+ lua_error_p(L, "bufsize must be within <512, " STR(UINT16_MAX) ">");
+ }
+ knot_edns_set_payload(ctx->downstream_opt_rr, (uint16_t)bufsize_downstream);
+ knot_edns_set_payload(ctx->upstream_opt_rr, (uint16_t)bufsize_upstream);
+ }
+ return 0;
+}
+
+/** Set TCP pipelining size. */
+static int net_pipeline(lua_State *L)
+{
+ struct worker_ctx *worker = the_worker;
+ if (!worker) {
+ return 0;
+ }
+ if (!lua_isnumber(L, 1)) {
+ lua_pushinteger(L, worker->tcp_pipeline_max);
+ return 1;
+ }
+ int len = lua_tointeger(L, 1);
+ if (len < 0 || len > UINT16_MAX)
+ lua_error_p(L, "tcp_pipeline must be within <0, " STR(UINT16_MAX) ">");
+ worker->tcp_pipeline_max = len;
+ lua_pushinteger(L, len);
+ return 1;
+}
+
+static int net_tls(lua_State *L)
+{
+ struct network *net = &the_worker->engine->net;
+ if (!net) {
+ return 0;
+ }
+
+ /* Only return current credentials. */
+ if (lua_gettop(L) == 0) {
+ /* No credentials configured yet. */
+ if (!net->tls_credentials) {
+ return 0;
+ }
+ lua_newtable(L);
+ lua_pushstring(L, net->tls_credentials->tls_cert);
+ lua_setfield(L, -2, "cert_file");
+ lua_pushstring(L, net->tls_credentials->tls_key);
+ lua_setfield(L, -2, "key_file");
+ return 1;
+ }
+
+ if ((lua_gettop(L) != 2) || !lua_isstring(L, 1) || !lua_isstring(L, 2))
+ lua_error_p(L, "net.tls takes two parameters: (\"cert_file\", \"key_file\")");
+
+ int r = tls_certificate_set(net, lua_tostring(L, 1), lua_tostring(L, 2));
+ lua_error_maybe(L, r);
+
+ lua_pushboolean(L, true);
+ return 1;
+}
+
+/** Configure HTTP headers for DoH requests. */
+static int net_doh_headers(lua_State *L)
+{
+ doh_headerlist_t *headers = &the_worker->doh_qry_headers;
+ int i;
+ const char *name;
+
+ /* Only return current configuration. */
+ if (lua_gettop(L) == 0) {
+ lua_newtable(L);
+ for (i = 0; i < headers->len; i++) {
+ lua_pushinteger(L, i + 1);
+ name = headers->at[i];
+ lua_pushlstring(L, name, strlen(name));
+ lua_settable(L, -3);
+ }
+ return 1;
+ }
+
+ if (lua_gettop(L) != 1)
+ lua_error_p(L, "net.doh_headers() takes one parameter (string or table)");
+
+ if (!lua_istable(L, 1) && !lua_isstring(L, 1))
+ lua_error_p(L, "net.doh_headers() argument must be string or table");
+
+ /* Clear existing headers. */
+ for (i = 0; i < headers->len; i++)
+ free((void *)headers->at[i]);
+ array_clear(*headers);
+
+ if (lua_istable(L, 1)) {
+ for (i = 1; !lua_isnil(L, -1); i++) {
+ lua_pushinteger(L, i);
+ lua_gettable(L, 1);
+ if (lua_isnil(L, -1)) /* missing value - end iteration */
+ break;
+ if (!lua_isstring(L, -1))
+ lua_error_p(L, "net.doh_headers() argument table can only contain strings");
+ name = lua_tostring(L, -1);
+ array_push(*headers, strdup(name));
+ }
+ } else if (lua_isstring(L, 1)) {
+ name = lua_tostring(L, 1);
+ array_push(*headers, strdup(name));
+ }
+
+ return 0;
+}
+
+/** Return a lua table with TLS authentication parameters.
+ * The format is the same as passed to policy.TLS_FORWARD();
+ * more precisely, it's in a compatible canonical form. */
+static int tls_params2lua(lua_State *L, trie_t *params)
+{
+ lua_newtable(L);
+ if (!params) /* Allowed special case. */
+ return 1;
+ trie_it_t *it;
+ size_t list_index = 0;
+ for (it = trie_it_begin(params); !trie_it_finished(it); trie_it_next(it)) {
+ /* Prepare table for the current address
+ * and its index in the returned list. */
+ lua_pushinteger(L, ++list_index);
+ lua_createtable(L, 0, 2);
+
+ /* Get the "addr#port" string... */
+ size_t ia_len;
+ const char *key = trie_it_key(it, &ia_len);
+ int af = AF_UNSPEC;
+ if (ia_len == 2 + sizeof(struct in_addr)) {
+ af = AF_INET;
+ } else if (ia_len == 2 + sizeof(struct in6_addr)) {
+ af = AF_INET6;
+ }
+ if (kr_fails_assert(key && af != AF_UNSPEC))
+ lua_error_p(L, "internal error: bad IP address");
+ uint16_t port;
+ memcpy(&port, key, sizeof(port));
+ port = ntohs(port);
+ const char *ia = key + sizeof(port);
+ char str[INET6_ADDRSTRLEN + 1 + 5 + 1];
+ size_t len = sizeof(str);
+ if (kr_fails_assert(kr_ntop_str(af, ia, port, str, &len) == kr_ok()))
+ lua_error_p(L, "internal error: bad IP address conversion");
+ /* ...and push it as [1]. */
+ lua_pushinteger(L, 1);
+ lua_pushlstring(L, str, len - 1 /* len includes '\0' */);
+ lua_settable(L, -3);
+
+ const tls_client_param_t *e = *trie_it_val(it);
+ if (kr_fails_assert(e))
+ lua_error_p(L, "internal problem - NULL entry for %s", str);
+
+ /* .hostname = */
+ if (e->hostname) {
+ lua_pushstring(L, e->hostname);
+ lua_setfield(L, -2, "hostname");
+ }
+
+ /* .ca_files = */
+ if (e->ca_files.len) {
+ lua_createtable(L, e->ca_files.len, 0);
+ for (size_t i = 0; i < e->ca_files.len; ++i) {
+ lua_pushinteger(L, i + 1);
+ lua_pushstring(L, e->ca_files.at[i]);
+ lua_settable(L, -3);
+ }
+ lua_setfield(L, -2, "ca_files");
+ }
+
+ /* .pin_sha256 = ... ; keep sane indentation via goto. */
+ if (!e->pins.len) goto no_pins;
+ lua_createtable(L, e->pins.len, 0);
+ for (size_t i = 0; i < e->pins.len; ++i) {
+ uint8_t pin_base64[TLS_SHA256_BASE64_BUFLEN];
+ int err = kr_base64_encode(e->pins.at[i], TLS_SHA256_RAW_LEN,
+ pin_base64, sizeof(pin_base64));
+ if (kr_fails_assert(err >= 0))
+ lua_error_p(L,
+ "internal problem when converting pin_sha256: %s",
+ kr_strerror(err));
+ lua_pushinteger(L, i + 1);
+ lua_pushlstring(L, (const char *)pin_base64, err);
+ /* pin_base64 isn't 0-terminated ^^^ */
+ lua_settable(L, -3);
+ }
+ lua_setfield(L, -2, "pin_sha256");
+
+ no_pins:/* .insecure = */
+ if (e->insecure) {
+ lua_pushboolean(L, true);
+ lua_setfield(L, -2, "insecure");
+ }
+ /* Now the whole table is pushed atop the returned list. */
+ lua_settable(L, -3);
+ }
+ trie_it_free(it);
+ return 1;
+}
+
+static inline int cmp_sha256(const void *p1, const void *p2)
+{
+ return memcmp(*(char * const *)p1, *(char * const *)p2, TLS_SHA256_RAW_LEN);
+}
+static int net_tls_client(lua_State *L)
+{
+ /* TODO idea: allow starting the lua table with *multiple* IP targets,
+ * meaning the authentication config should be applied to each.
+ */
+ struct network *net = &the_worker->engine->net;
+ if (lua_gettop(L) == 0)
+ return tls_params2lua(L, net->tls_client_params);
+ /* Various basic sanity-checking. */
+ if (lua_gettop(L) != 1 || !lua_istable(L, 1))
+ lua_error_maybe(L, EINVAL);
+ /* check that only allowed keys are present */
+ {
+ const char *bad_key = lua_table_checkindices(L, (const char *[])
+ { "1", "hostname", "ca_file", "pin_sha256", "insecure", NULL });
+ if (bad_key)
+ lua_error_p(L, "found unexpected key '%s'", bad_key);
+ }
+
+ /**** Phase 1: get the parameter into a C struct, incl. parse of CA files,
+ * regardless of the address-pair having an entry already. */
+
+ tls_client_param_t *newcfg = tls_client_param_new();
+ if (!newcfg)
+ lua_error_p(L, "out of memory or something like that :-/");
+ /* Shortcut for cleanup actions needed from now on. */
+ #define ERROR(...) do { \
+ free(newcfg); \
+ lua_error_p(L, __VA_ARGS__); \
+ } while (false)
+
+ /* .hostname - always accepted. */
+ lua_getfield(L, 1, "hostname");
+ if (!lua_isnil(L, -1)) {
+ const char *hn_str = lua_tostring(L, -1);
+ /* Convert to lower-case dname and back, for checking etc. */
+ knot_dname_t dname[KNOT_DNAME_MAXLEN];
+ if (!hn_str || !knot_dname_from_str(dname, hn_str, sizeof(dname)))
+ ERROR("invalid hostname");
+ knot_dname_to_lower(dname);
+ char *h = knot_dname_to_str_alloc(dname);
+ if (!h)
+ ERROR("%s", kr_strerror(ENOMEM));
+ /* Strip the final dot produced by knot_dname_*() */
+ h[strlen(h) - 1] = '\0';
+ newcfg->hostname = h;
+ }
+ lua_pop(L, 1);
+
+ /* .ca_file - it can be a list of paths, contrary to the name. */
+ bool has_ca_file = false;
+ lua_getfield(L, 1, "ca_file");
+ if (!lua_isnil(L, -1)) {
+ if (!newcfg->hostname)
+ ERROR("missing hostname but specifying ca_file");
+ lua_listify(L);
+ array_init(newcfg->ca_files); /*< placate apparently confused scan-build */
+ if (array_reserve(newcfg->ca_files, lua_objlen(L, -1)) != 0) /*< optim. */
+ ERROR("%s", kr_strerror(ENOMEM));
+ /* Iterate over table at the top of the stack.
+ * http://www.lua.org/manual/5.1/manual.html#lua_next */
+ for (lua_pushnil(L); lua_next(L, -2); lua_pop(L, 1)) {
+ has_ca_file = true; /* deferred here so that {} -> false */
+ const char *ca_file = lua_tostring(L, -1);
+ if (!ca_file)
+ ERROR("ca_file contains a non-string");
+ /* Let gnutls process it immediately, so garbage gets detected. */
+ int ret = gnutls_certificate_set_x509_trust_file(
+ newcfg->credentials, ca_file, GNUTLS_X509_FMT_PEM);
+ if (ret < 0) {
+ ERROR("failed to import certificate file '%s': %s - %s\n",
+ ca_file, gnutls_strerror_name(ret),
+ gnutls_strerror(ret));
+ } else {
+ kr_log_debug(TLSCLIENT, "imported %d certs from file '%s'\n",
+ ret, ca_file);
+ }
+
+ ca_file = strdup(ca_file);
+ if (!ca_file || array_push(newcfg->ca_files, ca_file) < 0)
+ ERROR("%s", kr_strerror(ENOMEM));
+ }
+ /* Sort the strings for easier comparison later. */
+ if (newcfg->ca_files.len) {
+ qsort(&newcfg->ca_files.at[0], newcfg->ca_files.len,
+ sizeof(newcfg->ca_files.at[0]), strcmp_p);
+ }
+ }
+ lua_pop(L, 1);
+
+ /* .pin_sha256 */
+ lua_getfield(L, 1, "pin_sha256");
+ if (!lua_isnil(L, -1)) {
+ if (has_ca_file)
+ ERROR("mixing pin_sha256 with ca_file is not supported");
+ lua_listify(L);
+ array_init(newcfg->pins); /*< placate apparently confused scan-build */
+ if (array_reserve(newcfg->pins, lua_objlen(L, -1)) != 0) /*< optim. */
+ ERROR("%s", kr_strerror(ENOMEM));
+ /* Iterate over table at the top of the stack. */
+ for (lua_pushnil(L); lua_next(L, -2); lua_pop(L, 1)) {
+ const char *pin = lua_tostring(L, -1);
+ if (!pin)
+ ERROR("pin_sha256 is not a string");
+ uint8_t *pin_raw = malloc(TLS_SHA256_RAW_LEN);
+ /* Push the string early to simplify error processing. */
+ if (kr_fails_assert(pin_raw && array_push(newcfg->pins, pin_raw) >= 0)) {
+ free(pin_raw);
+ ERROR("%s", kr_strerror(ENOMEM));
+ }
+ int ret = kr_base64_decode((const uint8_t *)pin, strlen(pin),
+ pin_raw, TLS_SHA256_RAW_LEN + 8);
+ if (ret < 0) {
+ ERROR("not a valid pin_sha256: '%s' (length %d), %s\n",
+ pin, (int)strlen(pin), knot_strerror(ret));
+ } else if (ret != TLS_SHA256_RAW_LEN) {
+ ERROR("not a valid pin_sha256: '%s', "
+ "raw length %d instead of "
+ STR(TLS_SHA256_RAW_LEN)"\n",
+ pin, ret);
+ }
+ }
+ /* Sort the raw strings for easier comparison later. */
+ if (newcfg->pins.len) {
+ qsort(&newcfg->pins.at[0], newcfg->pins.len,
+ sizeof(newcfg->pins.at[0]), cmp_sha256);
+ }
+ }
+ lua_pop(L, 1);
+
+ /* .insecure */
+ lua_getfield(L, 1, "insecure");
+ if (lua_isnil(L, -1)) {
+ if (!newcfg->hostname && !newcfg->pins.len)
+ ERROR("no way to authenticate and not set as insecure");
+ } else if (lua_isboolean(L, -1) && lua_toboolean(L, -1)) {
+ newcfg->insecure = true;
+ if (has_ca_file || newcfg->pins.len)
+ ERROR("set as insecure but provided authentication config");
+ } else {
+ ERROR("incorrect value in the 'insecure' field");
+ }
+ lua_pop(L, 1);
+
+ /* Init CAs from system trust store, if needed. */
+ if (!newcfg->insecure && !newcfg->pins.len && !has_ca_file) {
+ int ret = gnutls_certificate_set_x509_system_trust(newcfg->credentials);
+ if (ret <= 0) {
+ ERROR("failed to use system CA certificate store: %s",
+ ret ? gnutls_strerror(ret) : kr_strerror(ENOENT));
+ } else {
+ kr_log_debug(TLSCLIENT, "imported %d certs from system store\n",
+ ret);
+ }
+ }
+ #undef ERROR
+
+ /**** Phase 2: deal with the C authentication "table". */
+ /* Parse address and port. */
+ lua_pushinteger(L, 1);
+ lua_gettable(L, 1);
+ const char *addr_str = lua_tostring(L, -1);
+ if (!addr_str)
+ lua_error_p(L, "address is not a string");
+ char buf[INET6_ADDRSTRLEN + 1];
+ uint16_t port = 853;
+ const struct sockaddr *addr = NULL;
+ if (kr_straddr_split(addr_str, buf, &port) == kr_ok())
+ addr = kr_straddr_socket(buf, port, NULL);
+ /* Add newcfg into the C map, saving the original into oldcfg. */
+ if (!addr)
+ lua_error_p(L, "address '%s' could not be converted", addr_str);
+ tls_client_param_t **oldcfgp = tls_client_param_getptr(
+ &net->tls_client_params, addr, true);
+ free_const(addr);
+ if (!oldcfgp)
+ lua_error_p(L, "internal error when extending tls_client_params map");
+ tls_client_param_t *oldcfg = *oldcfgp;
+ *oldcfgp = newcfg; /* replace old config in trie with the new one */
+ /* If there was no original entry, it's easy! */
+ if (!oldcfg)
+ return 0;
+
+ /* Check for equality (newcfg vs. oldcfg), and print a warning if not equal.*/
+ const bool ok_h = (!newcfg->hostname && !oldcfg->hostname)
+ || (newcfg->hostname && oldcfg->hostname && strcmp(newcfg->hostname, oldcfg->hostname) == 0);
+ bool ok_ca = newcfg->ca_files.len == oldcfg->ca_files.len;
+ for (int i = 0; ok_ca && i < newcfg->ca_files.len; ++i)
+ ok_ca = strcmp(newcfg->ca_files.at[i], oldcfg->ca_files.at[i]) == 0;
+ bool ok_pins = newcfg->pins.len == oldcfg->pins.len;
+ for (int i = 0; ok_pins && i < newcfg->pins.len; ++i)
+ ok_ca = memcmp(newcfg->pins.at[i], oldcfg->pins.at[i], TLS_SHA256_RAW_LEN) == 0;
+ const bool ok_insecure = newcfg->insecure == oldcfg->insecure;
+ if (!(ok_h && ok_ca && ok_pins && ok_insecure)) {
+ kr_log_warning(TLSCLIENT,
+ "warning: re-defining TLS authentication parameters for %s\n",
+ addr_str);
+ }
+ tls_client_param_unref(oldcfg);
+ return 0;
+}
+
+int net_tls_client_clear(lua_State *L)
+{
+ /* One parameter: address -> convert it to a struct sockaddr. */
+ if (lua_gettop(L) != 1 || !lua_isstring(L, 1))
+ lua_error_p(L, "net.tls_client_clear() requires one parameter (\"address\")");
+ const char *addr_str = lua_tostring(L, 1);
+ char buf[INET6_ADDRSTRLEN + 1];
+ uint16_t port = 853;
+ const struct sockaddr *addr = NULL;
+ if (kr_straddr_split(addr_str, buf, &port) == kr_ok())
+ addr = kr_straddr_socket(buf, port, NULL);
+ if (!addr)
+ lua_error_p(L, "invalid IP address");
+ /* Do the actual removal. */
+ struct network *net = &the_worker->engine->net;
+ int r = tls_client_param_remove(net->tls_client_params, addr);
+ free_const(addr);
+ lua_error_maybe(L, r);
+ lua_pushboolean(L, true);
+ return 1;
+}
+
+static int net_tls_padding(lua_State *L)
+{
+ struct kr_context *ctx = &the_worker->engine->resolver;
+
+ /* Only return current padding. */
+ if (lua_gettop(L) == 0) {
+ if (ctx->tls_padding < 0) {
+ lua_pushboolean(L, true);
+ return 1;
+ } else if (ctx->tls_padding == 0) {
+ lua_pushboolean(L, false);
+ return 1;
+ }
+ lua_pushinteger(L, ctx->tls_padding);
+ return 1;
+ }
+
+ const char *errstr = "net.tls_padding parameter has to be true, false,"
+ " or a number between <0, " STR(MAX_TLS_PADDING) ">";
+ if (lua_gettop(L) != 1)
+ lua_error_p(L, "%s", errstr);
+ if (lua_isboolean(L, 1)) {
+ bool x = lua_toboolean(L, 1);
+ if (x) {
+ ctx->tls_padding = -1;
+ } else {
+ ctx->tls_padding = 0;
+ }
+ } else if (lua_isnumber(L, 1)) {
+ int padding = lua_tointeger(L, 1);
+ if ((padding < 0) || (padding > MAX_TLS_PADDING))
+ lua_error_p(L, "%s", errstr);
+ ctx->tls_padding = padding;
+ } else {
+ lua_error_p(L, "%s", errstr);
+ }
+ lua_pushboolean(L, true);
+ return 1;
+}
+
+/** Shorter salt can't contain much entropy. */
+#define net_tls_sticket_MIN_SECRET_LEN 32
+
+static int net_tls_sticket_secret_string(lua_State *L)
+{
+ struct network *net = &the_worker->engine->net;
+
+ size_t secret_len;
+ const char *secret;
+
+ if (lua_gettop(L) == 0) {
+ /* Zero-length secret, implying random key. */
+ secret_len = 0;
+ secret = NULL;
+ } else {
+ if (lua_gettop(L) != 1 || !lua_isstring(L, 1)) {
+ lua_error_p(L,
+ "net.tls_sticket_secret takes one parameter: (\"secret string\")");
+ }
+ secret = lua_tolstring(L, 1, &secret_len);
+ if (secret_len < net_tls_sticket_MIN_SECRET_LEN || !secret) {
+ lua_error_p(L, "net.tls_sticket_secret - the secret is shorter than "
+ STR(net_tls_sticket_MIN_SECRET_LEN) " bytes");
+ }
+ }
+
+ tls_session_ticket_ctx_destroy(net->tls_session_ticket_ctx);
+ net->tls_session_ticket_ctx =
+ tls_session_ticket_ctx_create(net->loop, secret, secret_len);
+ if (net->tls_session_ticket_ctx == NULL) {
+ lua_error_p(L,
+ "net.tls_sticket_secret_string - can't create session ticket context");
+ }
+
+ lua_pushboolean(L, true);
+ return 1;
+}
+
+static int net_tls_sticket_secret_file(lua_State *L)
+{
+ if (lua_gettop(L) != 1 || !lua_isstring(L, 1)) {
+ lua_error_p(L,
+ "net.tls_sticket_secret_file takes one parameter: (\"file name\")");
+ }
+
+ const char *file_name = lua_tostring(L, 1);
+ if (strlen(file_name) == 0)
+ lua_error_p(L, "net.tls_sticket_secret_file - empty file name");
+
+ FILE *fp = fopen(file_name, "r");
+ if (fp == NULL) {
+ lua_error_p(L, "net.tls_sticket_secret_file - can't open file '%s': %s",
+ file_name, strerror(errno));
+ }
+
+ char secret_buf[TLS_SESSION_TICKET_SECRET_MAX_LEN];
+ const size_t secret_len = fread(secret_buf, 1, sizeof(secret_buf), fp);
+ int err = ferror(fp);
+ if (err) {
+ lua_error_p(L,
+ "net.tls_sticket_secret_file - error reading from file '%s': %s",
+ file_name, strerror(err));
+ }
+ if (secret_len < net_tls_sticket_MIN_SECRET_LEN) {
+ lua_error_p(L,
+ "net.tls_sticket_secret_file - file '%s' is shorter than "
+ STR(net_tls_sticket_MIN_SECRET_LEN) " bytes",
+ file_name);
+ }
+ fclose(fp);
+
+ struct network *net = &the_worker->engine->net;
+
+ tls_session_ticket_ctx_destroy(net->tls_session_ticket_ctx);
+ net->tls_session_ticket_ctx =
+ tls_session_ticket_ctx_create(net->loop, secret_buf, secret_len);
+ if (net->tls_session_ticket_ctx == NULL) {
+ lua_error_p(L,
+ "net.tls_sticket_secret_file - can't create session ticket context");
+ }
+ lua_pushboolean(L, true);
+ return 1;
+}
+
+static int net_outgoing(lua_State *L, int family)
+{
+ union kr_sockaddr *addr;
+ if (family == AF_INET)
+ addr = (union kr_sockaddr*)&the_worker->out_addr4;
+ else
+ addr = (union kr_sockaddr*)&the_worker->out_addr6;
+
+ if (lua_gettop(L) == 0) { /* Return the current value. */
+ if (addr->ip.sa_family == AF_UNSPEC) {
+ lua_pushnil(L);
+ return 1;
+ }
+ if (kr_fails_assert(addr->ip.sa_family == family))
+ lua_error_p(L, "bad address family");
+ char addr_buf[INET6_ADDRSTRLEN];
+ int err;
+ if (family == AF_INET)
+ err = uv_ip4_name(&addr->ip4, addr_buf, sizeof(addr_buf));
+ else
+ err = uv_ip6_name(&addr->ip6, addr_buf, sizeof(addr_buf));
+ lua_error_maybe(L, err);
+ lua_pushstring(L, addr_buf);
+ return 1;
+ }
+
+ if ((lua_gettop(L) != 1) || (!lua_isstring(L, 1) && !lua_isnil(L, 1)))
+ lua_error_p(L, "net.outgoing_vX takes one address string parameter or nil");
+
+ if (lua_isnil(L, 1)) {
+ addr->ip.sa_family = AF_UNSPEC;
+ return 1;
+ }
+
+ const char *addr_str = lua_tostring(L, 1);
+ int err;
+ if (family == AF_INET)
+ err = uv_ip4_addr(addr_str, 0, &addr->ip4);
+ else
+ err = uv_ip6_addr(addr_str, 0, &addr->ip6);
+ if (err)
+ lua_error_p(L, "net.outgoing_vX: failed to parse the address");
+ lua_pushboolean(L, true);
+ return 1;
+}
+
+static int net_outgoing_v4(lua_State *L) { return net_outgoing(L, AF_INET); }
+static int net_outgoing_v6(lua_State *L) { return net_outgoing(L, AF_INET6); }
+
+static int net_update_timeout(lua_State *L, uint64_t *timeout, const char *name)
+{
+ /* Only return current idle timeout. */
+ if (lua_gettop(L) == 0) {
+ lua_pushinteger(L, *timeout);
+ return 1;
+ }
+
+ if ((lua_gettop(L) != 1))
+ lua_error_p(L, "%s takes one parameter: (\"idle timeout\")", name);
+
+ if (lua_isnumber(L, 1)) {
+ int idle_timeout = lua_tointeger(L, 1);
+ if (idle_timeout <= 0)
+ lua_error_p(L, "%s parameter has to be positive number", name);
+ *timeout = idle_timeout;
+ } else {
+ lua_error_p(L, "%s parameter has to be positive number", name);
+ }
+ lua_pushboolean(L, true);
+ return 1;
+}
+
+static int net_tcp_in_idle(lua_State *L)
+{
+ struct network *net = &the_worker->engine->net;
+ return net_update_timeout(L, &net->tcp.in_idle_timeout, "net.tcp_in_idle");
+}
+
+static int net_tls_handshake_timeout(lua_State *L)
+{
+ struct network *net = &the_worker->engine->net;
+ return net_update_timeout(L, &net->tcp.tls_handshake_timeout, "net.tls_handshake_timeout");
+}
+
+static int net_bpf_set(lua_State *L)
+{
+ if (lua_gettop(L) != 1 || !lua_isnumber(L, 1)) {
+ lua_error_p(L, "net.bpf_set(fd) takes one parameter:"
+ " the open file descriptor of a loaded BPF program");
+ }
+
+#if __linux__
+
+ int progfd = lua_tointeger(L, 1);
+ if (progfd == 0) {
+ /* conversion error despite that fact
+ * that lua_isnumber(L, 1) has returned true.
+ * Real or stdin? */
+ lua_error_p(L, "failed to convert parameter");
+ }
+ lua_pop(L, 1);
+
+ if (network_set_bpf(&the_worker->engine->net, progfd) == 0) {
+ lua_error_p(L, "failed to attach BPF program to some networks: %s",
+ kr_strerror(errno));
+ }
+
+ lua_pushboolean(L, 1);
+ return 1;
+
+#endif
+ lua_error_p(L, "BPF is not supported on this operating system");
+}
+
+static int net_bpf_clear(lua_State *L)
+{
+ if (lua_gettop(L) != 0)
+ lua_error_p(L, "net.bpf_clear() does not take any parameters");
+
+#if __linux__
+
+ network_clear_bpf(&the_worker->engine->net);
+
+ lua_pushboolean(L, 1);
+ return 1;
+
+#endif
+ lua_error_p(L, "BPF is not supported on this operating system");
+}
+
+static int net_register_endpoint_kind(lua_State *L)
+{
+ const int param_count = lua_gettop(L);
+ if (param_count != 1 && param_count != 2)
+ lua_error_p(L, "expected one or two parameters");
+ if (!lua_isstring(L, 1)) {
+ lua_error_p(L, "incorrect kind '%s'", lua_tostring(L, 1));
+ }
+ size_t kind_len;
+ const char *kind = lua_tolstring(L, 1, &kind_len);
+ struct network *net = &the_worker->engine->net;
+
+ /* Unregistering */
+ if (param_count == 1) {
+ void *val;
+ if (trie_del(net->endpoint_kinds, kind, kind_len, &val) == KNOT_EOK) {
+ const int fun_id = (char *)val - (char *)NULL;
+ luaL_unref(L, LUA_REGISTRYINDEX, fun_id);
+ return 0;
+ }
+ lua_error_p(L, "attempt to unregister unknown kind '%s'\n", kind);
+ } /* else -> param_count == 2 */
+
+ /* Registering */
+ if (!lua_isfunction(L, 2)) {
+ lua_error_p(L, "second parameter: expected function but got %s\n",
+ lua_typename(L, lua_type(L, 2)));
+ }
+ const int fun_id = luaL_ref(L, LUA_REGISTRYINDEX);
+ /* ^^ The function is on top of the stack, incidentally. */
+ void **pp = trie_get_ins(net->endpoint_kinds, kind, kind_len);
+ if (!pp) lua_error_maybe(L, kr_error(ENOMEM));
+ if (*pp != NULL || !strcasecmp(kind, "dns") || !strcasecmp(kind, "tls"))
+ lua_error_p(L, "attempt to register known kind '%s'\n", kind);
+ *pp = (char *)NULL + fun_id;
+ /* We don't attempt to engage corresponding endpoints now.
+ * That's the job for network_engage_endpoints() later. */
+ return 0;
+}
+
+int kr_bindings_net(lua_State *L)
+{
+ static const luaL_Reg lib[] = {
+ { "list", net_list },
+ { "listen", net_listen },
+ { "proxy_allowed", net_proxy_allowed },
+ { "close", net_close },
+ { "interfaces", net_interfaces },
+ { "bufsize", net_bufsize },
+ { "tcp_pipeline", net_pipeline },
+ { "tls", net_tls },
+ { "tls_server", net_tls },
+ { "tls_client", net_tls_client },
+ { "tls_client_clear", net_tls_client_clear },
+ { "tls_padding", net_tls_padding },
+ { "tls_sticket_secret", net_tls_sticket_secret_string },
+ { "tls_sticket_secret_file", net_tls_sticket_secret_file },
+ { "outgoing_v4", net_outgoing_v4 },
+ { "outgoing_v6", net_outgoing_v6 },
+ { "tcp_in_idle", net_tcp_in_idle },
+ { "tls_handshake_timeout", net_tls_handshake_timeout },
+ { "bpf_set", net_bpf_set },
+ { "bpf_clear", net_bpf_clear },
+ { "register_endpoint_kind", net_register_endpoint_kind },
+ { "doh_headers", net_doh_headers },
+ { NULL, NULL }
+ };
+ luaL_register(L, "net", lib);
+ return 1;
+}
+
diff --git a/daemon/bindings/net_client.rst b/daemon/bindings/net_client.rst
new file mode 100644
index 0000000..34e6236
--- /dev/null
+++ b/daemon/bindings/net_client.rst
@@ -0,0 +1,34 @@
+.. SPDX-License-Identifier: GPL-3.0-or-later
+
+IPv4 and IPv6 usage
+-------------------
+
+Following settings affect client part of the resolver,
+i.e. communication between the resolver itself and other DNS servers.
+
+IPv4 and IPv6 protocols are used by default. For performance reasons it is
+recommended to explicitly disable protocols which are not available
+on your system, though the impact of IPv6 outage is lowered since release 5.3.0.
+
+.. envvar:: net.ipv4 = true|false
+
+ :return: boolean (default: true)
+
+ Enable/disable using IPv4 for contacting upstream nameservers.
+
+.. envvar:: net.ipv6 = true|false
+
+ :return: boolean (default: true)
+
+ Enable/disable using IPv6 for contacting upstream nameservers.
+
+.. function:: net.outgoing_v4([string address])
+
+ Get/set the IPv4 address used to perform queries.
+ The default is ``nil``, which lets the OS choose any address.
+
+.. function:: net.outgoing_v6([string address])
+
+ Get/set the IPv6 address used to perform queries.
+ The default is ``nil``, which lets the OS choose any address.
+
diff --git a/daemon/bindings/net_dns_tweaks.rst b/daemon/bindings/net_dns_tweaks.rst
new file mode 100644
index 0000000..4cfeba6
--- /dev/null
+++ b/daemon/bindings/net_dns_tweaks.rst
@@ -0,0 +1,35 @@
+.. SPDX-License-Identifier: GPL-3.0-or-later
+
+DNS protocol tweaks
+-------------------
+
+Following settings change low-level details of DNS protocol implementation.
+Default values should not be changed except for very special cases.
+
+.. function:: net.bufsize([udp_downstream_bufsize][, udp_upstream_bufsize])
+
+ Get/set maximum EDNS payload size advertised in DNS packets. Different values can be configured for communication downstream (towards clients) and upstream (towards other DNS servers). Set and also get operations use values in this order.
+
+ Default is 1232 bytes which was chosen to minimize risk of `issues caused by IP fragmentation <https://blog.apnic.net/2019/07/12/its-time-to-consider-avoiding-ip-fragmentation-in-the-dns/>`_. Further details can be found at `DNS Flag Day 2020 <https://www.dnsflagday.net/2020/>`_ web site.
+
+ Minimal value allowed by standard :rfc:`6891` is 512 bytes, which is equal to DNS packet size without Extension Mechanisms for DNS. Value 1220 bytes is minimum size required by DNSSEC standard :rfc:`4035`.
+
+ Example output:
+
+ .. code-block:: lua
+
+ -- set downstream and upstream bufsize to value 4096
+ > net.bufsize(4096)
+ -- get configured downstream and upstream bufsizes, respectively
+ > net.bufsize()
+ 4096 -- result # 1
+ 4096 -- result # 2
+
+ -- set downstream bufsize to 4096 and upstream bufsize to 1232
+ > net.bufsize(4096, 1232)
+ -- get configured downstream and upstream bufsizes, respectively
+ > net.bufsize()
+ 4096 -- result # 1
+ 1232 -- result # 2
+
+.. include:: ../modules/workarounds/README.rst
diff --git a/daemon/bindings/net_server.rst b/daemon/bindings/net_server.rst
new file mode 100644
index 0000000..f346aeb
--- /dev/null
+++ b/daemon/bindings/net_server.rst
@@ -0,0 +1,225 @@
+.. SPDX-License-Identifier: GPL-3.0-or-later
+
+Addresses and services
+----------------------
+
+Addresses, ports, protocols, and API calls available for clients communicating
+with resolver are configured using :func:`net.listen`.
+
+First you need to decide what service should be available on given IP address
++ port combination.
+
+.. csv-table::
+ :header: "Protocol/service", "net.listen *kind*"
+
+ "DNS (unencrypted UDP+TCP, :rfc:`1034`)","``dns``"
+ "DNS (unencrypted UDP, :ref:`using XDP Linux API <dns-over-xdp>`)","``xdp``"
+ ":ref:`dns-over-tls`","``tls``"
+ ":ref:`dns-over-https`","``doh2``"
+ ":ref:`Web management <mod-http-built-in-services>`","``webmgmt``"
+ ":ref:`Control socket <control-sockets>`","``control``"
+ ":ref:`mod-http-doh`","``doh_legacy``"
+
+.. note:: By default, **unencrypted DNS and DNS-over-TLS** are configured to **listen
+ on localhost**.
+
+ Control sockets are created either in
+ ``/run/knot-resolver/control/`` (when using systemd) or ``$PWD/control/``.
+
+.. function:: net.listen(addresses, [port = 53, { kind = 'dns', freebind = false }])
+
+ :return: ``true`` if port is bound, an error otherwise
+
+ Listen on addresses; port and flags are optional.
+ The addresses can be specified as a string or device.
+ Port 853 implies ``kind = 'tls'`` but it is always better to be explicit.
+ Freebind allows binding to a non-local or not yet available address.
+
+.. csv-table::
+ :header: "**Network protocol**", "**Configuration command**"
+
+ "DNS (UDP+TCP, :rfc:`1034`)","``net.listen('192.0.2.123', 53)``"
+ "DNS (UDP, :ref:`using XDP <dns-over-xdp>`)","``net.listen('192.0.2.123', 53, { kind = 'xdp' })``"
+ ":ref:`dns-over-tls`","``net.listen('192.0.2.123', 853, { kind = 'tls' })``"
+ ":ref:`dns-over-https`","``net.listen('192.0.2.123', 443, { kind = 'doh2' })``"
+ ":ref:`Web management <mod-http-built-in-services>`","``net.listen('192.0.2.123', 8453, { kind = 'webmgmt' })``"
+ ":ref:`Control socket <control-sockets>`","``net.listen('/tmp/kres.control', nil, { kind = 'control' })``"
+
+
+Examples:
+
+ .. code-block:: lua
+
+ net.listen('::1')
+ net.listen(net.lo, 53)
+ net.listen(net.eth0, 853, { kind = 'tls' })
+ net.listen('192.0.2.1', 53, { freebind = true })
+ net.listen({'127.0.0.1', '::1'}, 53, { kind = 'dns' })
+ net.listen('::', 443, { kind = 'doh2' })
+ net.listen('::', 8453, { kind = 'webmgmt' }) -- see http module
+ net.listen('/tmp/kresd-socket', nil, { kind = 'webmgmt' }) -- http module supports AF_UNIX
+ net.listen('eth0', 53, { kind = 'xdp' })
+ net.listen('192.0.2.123', 53, { kind = 'xdp', nic_queue = 0 })
+
+.. warning:: On machines with multiple IP addresses avoid listening on wildcards
+ ``0.0.0.0`` or ``::``. Knot Resolver could answer from different IP
+ addresses if the network address ranges overlap,
+ and clients would probably refuse such a response.
+
+.. _proxyv2:
+
+PROXYv2 protocol
+^^^^^^^^^^^^^^^^
+
+Knot Resolver supports proxies that utilize the `PROXYv2 protocol <https://www.haproxy.org/download/2.5/doc/proxy-protocol.txt>`_
+to identify clients.
+
+A PROXY header contains the IP address of the original client who sent a query.
+This allows the resolver to treat queries as if they actually came from
+the client's IP address rather than the address of the proxy they came through.
+For example, :ref:`Views and ACLs <mod-view>` are able to work properly when
+PROXYv2 is in use.
+
+Since allowing usage of the PROXYv2 protocol for all clients would be a security
+vulnerability, because clients would then be able to spoof their IP addresses via
+the PROXYv2 header, the resolver requires you to specify explicitly which clients
+are allowed to send PROXYv2 headers via the :func:`net.proxy_allowed` function.
+
+PROXYv2 queries from clients who are not explicitly allowed to use this protocol
+will be discarded.
+
+.. function:: net.proxy_allowed([addresses])
+
+ Allow usage of the PROXYv2 protocol headers by clients on the specified
+ ``addresses``. It is possible to permit whole networks to send PROXYv2 headers
+ by specifying the network mask using the CIDR notation
+ (e.g. ``172.22.0.0/16``). IPv4 as well as IPv6 addresses are supported.
+
+ If you wish to allow all clients to use PROXYv2 (e.g. because you have this
+ kind of security handled on another layer of your network infrastructure),
+ you can specify a netmask of ``/0``. Please note that this setting is
+ address-family-specific, so this needs to be applied to both IPv4 and IPv6
+ separately.
+
+ Subsequent calls to the function overwrite the effects of all previous calls.
+ Providing a table of strings as the function parameter allows multiple
+ distinct addresses to use the PROXYv2 protocol.
+
+ When called without arguments, ``net.proxy_allowed`` returns a table of all
+ addresses currently allowed to use the PROXYv2 protocol and does not change
+ the configuration.
+
+Examples:
+
+ .. code-block:: lua
+
+ net.proxy_allowed('172.22.0.1') -- allows '172.22.0.1' specifically
+ net.proxy_allowed('172.18.1.0/24') -- allows everyone at '172.18.1.*'
+ net.proxy_allowed({
+ '172.22.0.1', '172.18.1.0/24'
+ }) -- allows both of the above at once
+ net.proxy_allowed({ 'fe80::/10' } -- allows everyone at IPv6 link-local
+ net.proxy_allowed({
+ '::/0', '0.0.0.0/0'
+ }) -- allows everyone
+ net.proxy_allowed('::/0') -- allows all IPv6 (but no IPv4)
+ net.proxy_allowed({}) -- prevents everyone from using PROXYv2
+ net.proxy_allowed() -- returns a list of all currently allowed addresses
+
+Features for scripting
+^^^^^^^^^^^^^^^^^^^^^^
+Following configuration functions are useful mainly for scripting or :ref:`runtime-cfg`.
+
+.. function:: net.close(address, [port])
+
+ :return: boolean (at least one endpoint closed)
+
+ Close all endpoints listening on the specified address, optionally restricted by port as well.
+
+
+.. function:: net.list()
+
+ :return: Table of bound interfaces.
+
+ Example output:
+
+ .. code-block:: none
+
+ [1] => {
+ [kind] => tls
+ [transport] => {
+ [family] => inet4
+ [ip] => 127.0.0.1
+ [port] => 853
+ [protocol] => tcp
+ }
+ }
+ [2] => {
+ [kind] => dns
+ [transport] => {
+ [family] => inet6
+ [ip] => ::1
+ [port] => 53
+ [protocol] => udp
+ }
+ }
+ [3] => {
+ [kind] => dns
+ [transport] => {
+ [family] => inet6
+ [ip] => ::1
+ [port] => 53
+ [protocol] => tcp
+ }
+ }
+ [4] => {
+ [kind] => xdp
+ [transport] => {
+ [family] => inet4+inet6
+ [interface] => eth2
+ [nic_queue] => 0
+ [port] => 53
+ [protocol] => udp
+ }
+ }
+
+.. function:: net.interfaces()
+
+ :return: Table of available interfaces and their addresses.
+
+ Example output:
+
+ .. code-block:: none
+
+ [lo0] => {
+ [addr] => {
+ [1] => ::1
+ [2] => 127.0.0.1
+ }
+ [mac] => 00:00:00:00:00:00
+ }
+ [eth0] => {
+ [addr] => {
+ [1] => 192.168.0.1
+ }
+ [mac] => de:ad:be:ef:aa:bb
+ }
+
+ .. tip:: You can use ``net.<iface>`` as a shortcut for specific interface, e.g. ``net.eth0``
+
+.. function:: net.tcp_pipeline([len])
+
+ Get/set per-client TCP pipeline limit, i.e. the number of outstanding queries that a single client connection can make in parallel. Default is 100.
+
+ .. code-block:: lua
+
+ > net.tcp_pipeline()
+ 100
+ > net.tcp_pipeline(50)
+ 50
+
+ .. warning:: Please note that too large limit may have negative impact on performance and can lead to increased number of SERVFAIL answers.
+
+.. _`dnsproxy module`: https://www.knot-dns.cz/docs/2.7/html/modules.html#dnsproxy-tiny-dns-proxy
+
+
diff --git a/daemon/bindings/net_tlssrv.rst b/daemon/bindings/net_tlssrv.rst
new file mode 100644
index 0000000..f496cd7
--- /dev/null
+++ b/daemon/bindings/net_tlssrv.rst
@@ -0,0 +1,188 @@
+.. SPDX-License-Identifier: GPL-3.0-or-later
+
+.. _tls-server-config:
+
+DoT and DoH (encrypted DNS)
+---------------------------
+
+.. warning::
+
+ It is important to understand **limits of encrypting only DNS traffic**.
+ Relevant security analysis can be found in article
+ *Simran Patil and Nikita Borisov. 2019. What can you learn from an IP?*
+ See `slides <https://irtf.org/anrw/2019/slides-anrw19-final44.pdf>`_
+ or `the article itself <https://dl.acm.org/authorize?N687437>`_.
+
+DoT and DoH encrypt DNS traffic with Transport Layer Security (TLS) protocol
+and thus protects DNS traffic from certain types of attacks.
+
+You can learn more about DoT and DoH and their implementation in Knot Resolver
+in `this article
+<https://en.blog.nic.cz/2020/11/25/encrypted-dns-in-knot-resolver-dot-and-doh/>`_.
+
+.. _dns-over-tls:
+
+DNS-over-TLS (DoT)
+^^^^^^^^^^^^^^^^^^
+
+DNS-over-TLS server (:rfc:`7858`) can be configured using ``tls`` kind in
+:func:`net.listen()`. It is enabled on localhost by default.
+
+For certificate configuration, refer to :ref:`dot-doh-config-options`.
+
+.. _dns-over-https:
+
+DNS-over-HTTPS (DoH)
+^^^^^^^^^^^^^^^^^^^^
+
+.. note:: Knot Resolver currently offers two DoH implementations. It is
+ recommended to use this new implementation, which is more reliable, scalable
+ and has fewer dependencies. Make sure to use ``doh2`` kind in
+ :func:`net.listen()` to select this implementation.
+
+.. tip:: Independent information about political controversies around the
+ DoH deployment by default can be found in blog posts `DNS Privacy at IETF
+ 104 <http://www.potaroo.net/ispcol/2019-04/angst.html>`_ and `More DOH
+ <http://www.potaroo.net/ispcol/2019-04/moredoh.html>`_ by Geoff Huston and
+ `Centralised DoH is bad for Privacy, in 2019 and beyond
+ <https://labs.ripe.net/Members/bert_hubert/centralised-doh-is-bad-for-privacy-in-2019-and-beyond>`_
+ by Bert Hubert.
+
+DNS-over-HTTPS server (:rfc:`8484`) can be configured using ``doh2`` kind in
+:func:`net.listen()`.
+
+This implementation supports HTTP/2 (:rfc:`7540`). Queries can be sent to the
+``/dns-query`` endpoint, e.g.:
+
+.. code-block:: bash
+
+ $ kdig @127.0.0.1 +https www.knot-resolver.cz AAAA
+
+**Only TLS version 1.3 (or higher) is supported with DNS-over-HTTPS.** The
+additional considerations for TLS 1.2 required by HTTP/2 are not implemented
+(:rfc:`7540#section-9.2`).
+
+.. warning:: Take care when configuring your server to listen on well known
+ HTTPS port. If an unrelated HTTPS service is running on the same port with
+ REUSEPORT enabled, you will end up with both services malfunctioning.
+
+.. _dot-doh-config-options:
+
+HTTP status codes
+"""""""""""""""""
+
+As specified by :rfc:`8484`, the resolver responds with status **200 OK** whenever
+it can produce a valid DNS reply for a given query, even in cases where the DNS
+``rcode`` indicates an error (like ``NXDOMAIN``, ``SERVFAIL``, etc.).
+
+For DoH queries malformed at the HTTP level, the resolver may respond with
+the following status codes:
+
+ * **400 Bad Request** for a generally malformed query, like one not containing
+ a valid DNS packet
+ * **404 Not Found** when an incorrect HTTP endpoint is queried - the only
+ supported ones are ``/dns-query`` and ``/doh``
+ * **413 Payload Too Large** when the DNS query exceeds its maximum size
+ * **415 Unsupported Media Type** when the query's ``Content-Type`` header
+ is not ``application/dns-message``
+ * **431 Request Header Fields Too Large** when a header in the query is too
+ large to process
+ * **501 Not Implemented** when the query uses a method other than
+ ``GET``, ``POST``, or ``HEAD``
+
+Configuration options for DoT and DoH
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. note:: These settings affect both DNS-over-TLS and DNS-over-HTTPS (except
+ the legacy implementation).
+
+A self-signed certificate is generated by default. For serious deployments
+it is strongly recommended to configure your own TLS certificates signed
+by a trusted CA. This is done using function :c:func:`net.tls()`.
+
+.. function:: net.tls([cert_path], [key_path])
+
+ When called with path arguments, the function loads the server TLS
+ certificate and private key for DoT and DoH.
+
+ When called without arguments, the command returns the currently configured paths.
+
+ Example output:
+
+ .. code-block:: lua
+
+ > net.tls("/etc/knot-resolver/server-cert.pem", "/etc/knot-resolver/server-key.pem")
+ > net.tls() -- print configured paths
+ [cert_file] => '/etc/knot-resolver/server-cert.pem'
+ [key_file] => '/etc/knot-resolver/server-key.pem'
+
+ .. tip:: The certificate files aren't automatically reloaded on change. If
+ you update the certificate files, e.g. using ACME, you have to either
+ restart the service(s) or call this function again using
+ :ref:`control-sockets`.
+
+.. function:: net.tls_sticket_secret([string with pre-shared secret])
+
+ Set secret for TLS session resumption via tickets, by :rfc:`5077`.
+
+ The server-side key is rotated roughly once per hour.
+ By default or if called without secret, the key is random.
+ That is good for long-term forward secrecy, but multiple kresd instances
+ won't be able to resume each other's sessions.
+
+ If you provide the same secret to multiple instances, they will be able to resume
+ each other's sessions *without* any further communication between them.
+ This synchronization works only among instances having the same endianness
+ and time_t structure and size (`sizeof(time_t)`).
+
+.. _pfs: https://en.wikipedia.org/wiki/Forward_secrecy
+
+ **For good security** the secret must have enough entropy to be hard to guess,
+ and it should still be occasionally rotated manually and securely forgotten,
+ to reduce the scope of privacy leak in case the
+ `secret leaks eventually <pfs_>`_.
+
+ .. warning:: **Setting the secret is probably too risky with TLS <= 1.2 and
+ GnuTLS < 3.7.5**. GnuTLS 3.7.5 adds an option to disable resumption via
+ tickets for TLS <= 1.2, enabling them only for protocols that do guarantee
+ `PFS <pfs_>`_. Knot Resolver makes use of this new option when linked
+ against GnuTLS >= 3.7.5.
+
+.. function:: net.tls_sticket_secret_file([string with path to a file containing pre-shared secret])
+
+ The same as :func:`net.tls_sticket_secret`,
+ except the secret is read from a (binary) file.
+
+.. function:: net.tls_padding([true | false])
+
+ Get/set EDNS(0) padding of answers to queries that arrive over TLS
+ transport. If set to `true` (the default), it will use a sensible
+ default padding scheme, as implemented by libknot if available at
+ compile time. If set to a numeric value >= 2 it will pad the
+ answers to nearest *padding* boundary, e.g. if set to `64`, the
+ answer will have size of a multiple of 64 (64, 128, 192, ...). If
+ set to `false` (or a number < 2), it will disable padding entirely.
+
+Configuration options for DoH
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. function:: net.doh_headers([string or table of strings])
+
+ Selects the headers to be exposed. These headers and their values are
+ available in ``request.qsource.headers``. Comparison
+ is case-insensitive and pseudo-headers are supported as well.
+
+ The following snippet can be used in the lua module to access headers
+ ``:method`` and ``user-agent``:
+
+ .. code-block:: lua
+
+ net.doh_headers({':method', 'user-agent'})
+
+ ...
+
+ for i = 1, tonumber(req.qsource.headers.len) do
+ local name = ffi.string(req.qsource.headers.at[i - 1].name)
+ local value = ffi.string(req.qsource.headers.at[i - 1].value)
+ print(name, value)
+ end
diff --git a/daemon/bindings/net_xdpsrv.rst b/daemon/bindings/net_xdpsrv.rst
new file mode 100644
index 0000000..e3014fe
--- /dev/null
+++ b/daemon/bindings/net_xdpsrv.rst
@@ -0,0 +1,140 @@
+.. SPDX-License-Identifier: GPL-3.0-or-later
+
+.. _dns-over-xdp:
+
+XDP for higher UDP performance
+------------------------------
+
+.. warning::
+ As of version 5.2.0, XDP support in Knot Resolver is considered
+ experimental. The impact on overall throughput and performance may not
+ always be beneficial.
+
+Using XDP allows significant speedup of UDP packet processing in recent Linux kernels,
+especially with some network drivers that implement good support.
+The basic idea is that for selected packets the Linux networking stack is bypassed,
+and some drivers can even directly use the user-space buffers for reading and writing.
+
+.. TODO perhaps some hint/link about how significant speedup one might get? (link to some talk video?)
+
+Prerequisites
+^^^^^^^^^^^^^
+.. this is mostly copied from knot-dns doc/operations.rst
+
+.. warning::
+ Bypassing the network stack has significant implications, such as bypassing the firewall
+ and monitoring solutions.
+ Make sure you're familiar with the trade-offs before using this feature.
+ Read more in :ref:`dns-over-xdp_limitations`.
+
+* Linux kernel 4.18+ (5.x+ is recommended for optimal performance) compiled with
+ the `CONFIG_XDP_SOCKETS=y` option. XDP isn't supported in other operating systems.
+* libknot compiled with XDP support
+* **A multiqueue network card with native XDP support is highly recommended**,
+ otherwise the performance gain will be much lower and you may encounter
+ issues due to XDP emulation.
+ Successfully tested cards:
+
+ * Intel series 700 (driver `i40e`), maximum number of queues per interface is 64.
+ * Intel series 500 (driver `ixgbe`), maximum number of queues per interface is 64.
+ The number of CPUs available has to be at most 64!
+
+
+Set up
+^^^^^^
+.. first parts are mostly copied from knot-dns doc/operations.rst
+
+The server instances need additional Linux **capabilities** during startup.
+(Or you could start them as `root`.)
+Execute command
+
+.. code-block:: bash
+
+ systemctl edit kresd@.service
+
+And insert these lines:
+
+.. code-block:: ini
+
+ [Service]
+ CapabilityBoundingSet=CAP_NET_RAW CAP_NET_ADMIN CAP_SYS_ADMIN CAP_IPC_LOCK CAP_SYS_RESOURCE
+ AmbientCapabilities=CAP_NET_RAW CAP_NET_ADMIN CAP_SYS_ADMIN CAP_IPC_LOCK CAP_SYS_RESOURCE
+
+The ``CAP_SYS_RESOURCE`` is only needed on Linux < 5.11.
+
+.. TODO suggest some way for ethtool -L? Perhaps via systemd units?
+
+You want the same number of kresd instances and network **queues** on your card;
+you can use ``ethtool -L`` before the services start.
+With XDP this is more important than with vanilla UDP, as we only support one instance
+per queue and unclaimed queues will fall back to vanilla UDP.
+Ideally you can set these numbers as high as the number of CPUs that you want kresd to use.
+
+Modification of ``/etc/knot-resolver/kresd.conf`` may often be quite simple, for example:
+
+.. code-block:: lua
+
+ net.listen('eth2', 53, { kind = 'xdp' })
+ net.listen('203.0.113.53', 53, { kind = 'dns' })
+
+Note that you want to also keep the vanilla DNS line to service TCP
+and possibly any fallback UDP (e.g. from unclaimed queues).
+XDP listening is in principle done on queues of whole network interfaces
+and the target addresses of incoming packets aren't checked in any way,
+but you are still allowed to specify interface by an address
+(if it's unambiguous at that moment):
+
+.. code-block:: lua
+
+ net.listen('203.0.113.53', 53, { kind = 'xdp' })
+ net.listen('203.0.113.53', 53, { kind = 'dns' })
+
+The default selection of queues is tailored for the usual naming convention:
+``kresd@1.service``, ``kresd@2.service``, ...
+but you can still specify them explicitly, e.g. the default is effectively the same as:
+
+.. code-block:: lua
+
+ net.listen('eth2', 53, { kind = 'xdp', nic_queue = env.SYSTEMD_INSTANCE - 1 })
+
+
+Optimizations
+^^^^^^^^^^^^^
+.. this is basically copied from knot-dns doc/operations.rst
+
+Some helpful commands:
+
+.. code-block:: text
+
+ ethtool -N <interface> rx-flow-hash udp4 sdfn
+ ethtool -N <interface> rx-flow-hash udp6 sdfn
+ ethtool -L <interface> combined <queue-number>
+ ethtool -G <interface> rx <ring-size> tx <ring-size>
+ renice -n 19 -p $(pgrep '^ksoftirqd/[0-9]*$')
+
+.. TODO CPU affinities? `CPUAffinity=%i` in systemd unit sounds good.
+
+
+.. _dns-over-xdp_limitations:
+
+Limitations
+^^^^^^^^^^^
+.. this is basically copied from knot-dns doc/operations.rst
+
+* VLAN segmentation is not supported.
+* MTU higher than 1792 bytes is not supported.
+* Multiple BPF filters per one network device are not supported.
+* Symmetrical routing is required (query source MAC/IP addresses and
+ reply destination MAC/IP addresses are the same).
+* Systems with big-endian byte ordering require special recompilation of libknot.
+* IPv4 header and UDP checksums are not verified on received DNS messages.
+* DNS over XDP traffic is not visible to common system tools (e.g. firewall, tcpdump etc.).
+* BPF filter is not automatically unloaded from the network device. Manual filter unload::
+
+ ip link set dev <interface> xdp off
+
+* Knot Resolver only supports using XDP towards clients currently (not towards upstreams).
+* When starting up an XDP socket you may get a harmless warning::
+
+ libbpf: Kernel error message: XDP program already attached
+
diff --git a/daemon/bindings/worker.c b/daemon/bindings/worker.c
new file mode 100644
index 0000000..d985000
--- /dev/null
+++ b/daemon/bindings/worker.c
@@ -0,0 +1,81 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#include "daemon/bindings/impl.h"
+
+
+static inline double getseconds(uv_timeval_t *tv)
+{
+ return (double)tv->tv_sec + 0.000001*((double)tv->tv_usec);
+}
+
+/** Return worker statistics. */
+static int wrk_stats(lua_State *L)
+{
+ struct worker_ctx *worker = the_worker;
+ if (!worker) {
+ return 0;
+ }
+ lua_newtable(L);
+ lua_pushnumber(L, worker->stats.queries);
+ lua_setfield(L, -2, "queries");
+ lua_pushnumber(L, worker->stats.concurrent);
+ lua_setfield(L, -2, "concurrent");
+ lua_pushnumber(L, worker->stats.dropped);
+ lua_setfield(L, -2, "dropped");
+
+ lua_pushnumber(L, worker->stats.timeout);
+ lua_setfield(L, -2, "timeout");
+ lua_pushnumber(L, worker->stats.udp);
+ lua_setfield(L, -2, "udp");
+ lua_pushnumber(L, worker->stats.tcp);
+ lua_setfield(L, -2, "tcp");
+ lua_pushnumber(L, worker->stats.tls);
+ lua_setfield(L, -2, "tls");
+ lua_pushnumber(L, worker->stats.ipv4);
+ lua_setfield(L, -2, "ipv4");
+ lua_pushnumber(L, worker->stats.ipv6);
+ lua_setfield(L, -2, "ipv6");
+ lua_pushnumber(L, worker->stats.err_udp);
+ lua_setfield(L, -2, "err_udp");
+ lua_pushnumber(L, worker->stats.err_tcp);
+ lua_setfield(L, -2, "err_tcp");
+ lua_pushnumber(L, worker->stats.err_tls);
+ lua_setfield(L, -2, "err_tls");
+ lua_pushnumber(L, worker->stats.err_http);
+ lua_setfield(L, -2, "err_http");
+
+ /* Add subset of rusage that represents counters. */
+ uv_rusage_t rusage;
+ if (uv_getrusage(&rusage) == 0) {
+ lua_pushnumber(L, getseconds(&rusage.ru_utime));
+ lua_setfield(L, -2, "usertime");
+ lua_pushnumber(L, getseconds(&rusage.ru_stime));
+ lua_setfield(L, -2, "systime");
+ lua_pushnumber(L, rusage.ru_majflt);
+ lua_setfield(L, -2, "pagefaults");
+ lua_pushnumber(L, rusage.ru_nswap);
+ lua_setfield(L, -2, "swaps");
+ lua_pushnumber(L, rusage.ru_nvcsw + rusage.ru_nivcsw);
+ lua_setfield(L, -2, "csw");
+ }
+ /* Get RSS */
+ size_t rss = 0;
+ if (uv_resident_set_memory(&rss) == 0) {
+ lua_pushnumber(L, rss);
+ lua_setfield(L, -2, "rss");
+ }
+ return 1;
+}
+
+int kr_bindings_worker(lua_State *L)
+{
+ static const luaL_Reg lib[] = {
+ { "stats", wrk_stats },
+ { NULL, NULL }
+ };
+ luaL_register(L, "worker", lib);
+ return 1;
+}
+
diff --git a/daemon/bindings/worker.rst b/daemon/bindings/worker.rst
new file mode 100644
index 0000000..9dfcbe8
--- /dev/null
+++ b/daemon/bindings/worker.rst
@@ -0,0 +1,35 @@
+.. SPDX-License-Identifier: GPL-3.0-or-later
+
+Scripting worker
+^^^^^^^^^^^^^^^^
+
+Worker is a service over event loop that tracks and schedules outstanding queries,
+you can see the statistics or schedule new queries. It also contains information about
+specified worker count and process rank.
+
+.. envvar:: worker.id
+
+ Value from environment variable ``SYSTEMD_INSTANCE``,
+ or if it is not set, :envvar:`PID <worker.pid>` (string).
+
+.. envvar:: worker.pid
+
+ Current worker process PID (number).
+
+.. function:: worker.stats()
+
+ Return table of statistics. See member descriptions in :c:type:`worker_stats`.
+ A few fields are added, mainly from POSIX ``getrusage()``:
+
+ * ``usertime`` and ``systime`` -- CPU time used, in seconds
+ * ``pagefaults`` -- the number of hard page faults, i.e. those that required I/O activity
+ * ``swaps`` -- the number of times the process was “swapped†out of main memory; unused on Linux
+ * ``csw`` -- the number of context switches, both voluntary and involuntary
+ * ``rss`` -- current memory usage in bytes, including whole cache (resident set size)
+
+ Example:
+
+ .. code-block:: lua
+
+ print(worker.stats().concurrent)
+
diff --git a/daemon/cache.test/clear.test.lua b/daemon/cache.test/clear.test.lua
new file mode 100644
index 0000000..e1f6914
--- /dev/null
+++ b/daemon/cache.test/clear.test.lua
@@ -0,0 +1,215 @@
+-- unload modules which are not related to this test
+-- SPDX-License-Identifier: GPL-3.0-or-later
+
+if ta_signal_query then
+ modules.unload('ta_signal_query')
+end
+if priming then
+ modules.unload('priming')
+end
+if detect_time_skew then
+ modules.unload('detect_time_skew')
+end
+
+-- test. domain is used by some tests, allow it
+policy.add(policy.suffix(policy.PASS, {todname('test.')}))
+
+cache.size = 2*MB
+-- log_level('debug')
+
+-- Self-checks on globals
+assert(help() ~= nil)
+assert(worker.id ~= nil)
+-- Self-checks on facilities
+assert(cache.stats() ~= nil)
+assert(cache.backends() ~= nil)
+assert(worker.stats() ~= nil)
+assert(net.interfaces() ~= nil)
+-- Self-checks on loaded stuff
+assert(#modules.list() > 0)
+-- Self-check timers
+ev = event.recurrent(1 * sec, function () return 1 end)
+event.cancel(ev)
+ev = event.after(0, function () return 1 end)
+
+
+-- Import fake root zone; avoid interference with configured keyfile_default.
+trust_anchors.remove('.')
+trust_anchors.add('. IN DS 48409 8 2 3D63A0C25BCE86621DE63636F11B35B908EFE8E9381E0E3E9DEFD89EA952C27D')
+
+local check_answer = require('test_utils').check_answer
+
+-- do not attempt to contact outside world, operate only on cache
+net.ipv4 = false
+net.ipv6 = false
+-- do not listen, test is driven by config code
+env.KRESD_NO_LISTEN = true
+
+
+local function import_zone()
+ local import_res = require('ffi').C.zi_zone_import({ zone_file = 'testroot.zone' })
+ assert(import_res == 0)
+ -- beware that import takes at least 100 ms
+ worker.sleep(0.2) -- zimport is delayed by 100 ms from function call
+ -- sanity checks - cache must be filled in
+ ok(cache.count() > 0, 'cache is not empty after import')
+ check_answer('root apex is in cache',
+ '.', kres.type.NS, kres.rcode.NOERROR)
+ check_answer('deep subdomain is in cache',
+ 'a.b.subtree1.', kres.type.AAAA, kres.rcode.NOERROR)
+
+end
+
+local function test_exact_match_qtype()
+ nok(cache.clear('a.b.subtree1.', true, kres.type.A)['chunk_limit'],
+ 'single qname+qtype can be cleared at once')
+ check_answer('exact match on qname+qtype must flush RR from cache',
+ 'a.b.subtree1.', kres.type.A, kres.rcode.SERVFAIL)
+ check_answer('exact match on qname+qtype must not affect other RRs on the same node',
+ 'a.b.subtree1.', kres.type.AAAA, kres.rcode.NOERROR)
+ check_answer('exact match on qname must not affect parent',
+ 'b.subtree1.', kres.type.A, kres.rcode.NOERROR)
+end
+
+local function test_exact_match_qname()
+ res = cache.clear('a.b.SubTree1.')
+ is(res.count, 2, 'single qname can be cleared at once')
+ check_answer('exact match on qname must flush all RRs with the same owner from cache',
+ 'a.b.subtree1.', kres.type.AAAA, kres.rcode.SERVFAIL)
+ check_answer('exact match on qname must flush all RRs with the same owner from cache',
+ 'a.b.subtree1.', kres.type.A, kres.rcode.SERVFAIL)
+ check_answer('exact match on qname must flush all RRs with the same owner from cache',
+ 'a.b.subtree1.', kres.type.TXT, kres.rcode.SERVFAIL)
+ -- exact match for negative proofs is not implemented yet
+ --check_answer('exact match on qname must flush negative proofs for owner from cache',
+ -- 'a.b.subtree1.', kres.type.NULL, kres.rcode.SERVFAIL)
+ --check_answer('exact match on qname must not affect parent',
+ -- 'b.subtree1.', kres.type.A, kres.rcode.NOERROR)
+ -- same(cache.clear(), 0, 'full cache clear can be performed')
+ --check_answer('.', kres.type.NS, false)
+
+end
+
+local function test_subtree()
+ res = cache.clear('subtree1.')
+ nok(res.chunk_limit,
+ 'whole positive subtree must be flushed (does not include neg. proofs)')
+ ok(res.not_apex,
+ 'subtree clear below apex must be detected')
+ same(res.subtree, '.', 'detected apex must be returned')
+ check_answer('subtree variant must flush all RRs in subdomains from cache',
+ 'b.subtree1.', kres.type.A, kres.rcode.SERVFAIL)
+ check_answer('subtree variant must flush all RRs in subdomains from cache',
+ 'b.subtree1.', kres.type.TXT, kres.rcode.SERVFAIL)
+ check_answer('subtree variant must flush all RRs in subdomains from cache',
+ 'subtree1.', kres.type.TXT, kres.rcode.SERVFAIL)
+ check_answer('subtree variant must not affect parent',
+ '.', kres.type.NS, kres.rcode.NOERROR)
+ -- same(cache.clear(), 0, 'full cache clear can be performed')
+ --check_answer('.', kres.type.NS, false)
+
+end
+
+local function test_callback()
+ local test_name = '20r.subtree2.'
+ local test_exactname = true
+ local test_rrtype = nil
+ local test_chunksize = 1
+ local test_prev_state = { works = true }
+ local function check_callback(name, exact_name, rr_type, chunk_size, callback, prev_state, errors)
+ is(errors.count, 1, 'callback received correct # of removed records')
+ is(test_name, name, 'callback received subtree name')
+ is(test_exactname, exact_name, 'callback received exact_name')
+ is(test_rrtype, rr_type, 'callback received rr_type')
+ is(test_chunksize, chunk_size, 'callback received chunk_size')
+ is(check_callback, callback, 'callback received reference to itself')
+ is(type(errors), 'table', 'callback received table of errors')
+ same(test_prev_state, prev_state, 'callback received previous state')
+ return 666
+ end
+ same(cache.clear(test_name, test_exactname, test_rrtype, test_chunksize, check_callback, test_prev_state),
+ 666, 'first callback return value is passed to cache.clear() caller')
+ local cnt_before_wait = cache.count()
+ worker.sleep(0.2)
+ is(cnt_before_wait, cache.count(), 'custom callback can stop clearing')
+end
+
+local function test_subtree_limit() -- default limit = 100
+ res = cache.clear('subtree2.', false, nil)
+ ok(res.chunk_limit,
+ 'chunk_size limit must be respected')
+ is(res.count, 100,
+ 'chunk_size limit must match returned count')
+
+ -- callbacks are running in background so we can now wait
+ -- and later verify that everything was removed
+ -- 200 RRs, 100 was removed in first call
+ -- so the rest should be removed in single invocation of callback
+ -- hopefully the machine is not too slow ...
+ worker.sleep(0.1)
+ res = cache.clear('subtree2.', false, nil)
+ is(res.count, 0,
+ 'previous calls + callbacks must have removed everything')
+end
+
+local function test_apex()
+ check_answer('a negative proof is still present in cache',
+ 'aaaaa.b.subtree1.', kres.type.TXT, kres.rcode.NXDOMAIN)
+
+ local prev_count = cache.count()
+ ok(prev_count > 0, 'previous subtree clearing did not remove everything')
+ res = cache.clear('.', false, nil, 10000)
+ is(res.count, prev_count, 'clear on root removed everything including proofs')
+ check_answer('exact match on qname must flush negative proofs for owner from cache',
+ 'a.b.subtree1.', kres.type.NULL, kres.rcode.SERVFAIL)
+end
+
+local function test_root()
+ check_answer('root apex is still in cache',
+ '.', kres.type.NS, kres.rcode.NOERROR)
+ res = cache.clear('.', true)
+ check_answer('root apex is in no longer cache',
+ '.', kres.type.NS, kres.rcode.SERVFAIL)
+ check_answer('some other item is still in cache',
+ '16r.subtree2.', kres.type.A, kres.rcode.NOERROR)
+
+ local prev_count = cache.count()
+ res = cache.clear('.')
+ is(res.count, prev_count, 'full clear reports correct number of entries')
+ is(cache.count(), 0, 'clearing root clears everything')
+end
+
+local function test_complete_flush()
+ local prev_count = cache.count()
+ res = cache.clear()
+ is(res.count, prev_count, 'full clear reports correct number of entries')
+ is(cache.count(), 0, 'cache is empty after full clear')
+end
+
+local function test_cache_used(lower, upper)
+ return function()
+ local usage = cache.stats().usage_percent
+ ok(usage >= lower and usage <= upper,
+ string.format('cache percentage usage %.1f is between <%d, %d>', usage, lower, upper))
+ end
+end
+
+return {
+ test_cache_used(0, 1),
+ import_zone,
+ test_cache_used(9, 11),
+ test_exact_match_qtype,
+ test_exact_match_qname,
+ test_callback,
+ import_zone,
+ test_subtree,
+ test_cache_used(9, 11),
+ test_subtree_limit,
+ test_cache_used(5, 8),
+ test_apex,
+ import_zone,
+ test_root,
+ import_zone,
+ test_complete_flush,
+ test_cache_used(0, 1),
+}
diff --git a/daemon/cache.test/insert_ns.test.integr/deckard.yaml b/daemon/cache.test/insert_ns.test.integr/deckard.yaml
new file mode 100644
index 0000000..7f99679
--- /dev/null
+++ b/daemon/cache.test/insert_ns.test.integr/deckard.yaml
@@ -0,0 +1,14 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+programs:
+- name: kresd
+ binary: kresd
+ additional:
+ - --noninteractive
+ templates:
+ - daemon/cache.test/insert_ns.test.integr/kresd_config.j2
+ - tests/integration/hints_zone.j2
+ configs:
+ - config
+ - hints
+noclean: True
diff --git a/daemon/cache.test/insert_ns.test.integr/kresd_config.j2 b/daemon/cache.test/insert_ns.test.integr/kresd_config.j2
new file mode 100644
index 0000000..bf2165b
--- /dev/null
+++ b/daemon/cache.test/insert_ns.test.integr/kresd_config.j2
@@ -0,0 +1,89 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+
+{% for TAF in TRUST_ANCHOR_FILES %}
+trust_anchors.add_file('{{TAF}}')
+{% endfor %}
+
+{% raw %}
+-- insert NS record pointing to a non-delegated DNS server
+cache.open(1*MB)
+cache.clear()
+trust_anchors.remove('.')
+
+local ffi = require('ffi')
+local c = kres.context().cache
+ns_name = todname('ns.example.com')
+local ns_addr = '\1\2\3\4'
+local rr = kres.rrset(ns_name, kres.type.A, kres.class.IN, 2147483647)
+assert(rr:add_rdata(ns_addr, #ns_addr))
+assert(c:insert(rr, nil, ffi.C.KR_RANK_SECURE))
+
+rr_ns = kres.rrset(todname('example.com'), kres.type.NS, kres.class.IN, 3600)
+assert(rr_ns:add_rdata(ns_name, #ns_name))
+assert(c:insert(rr_ns, nil, bit.bor(ffi.C.KR_RANK_AUTH, ffi.C.KR_RANK_INSECURE)))
+
+c:commit()
+assert(cache.count() > 0)
+
+-- from now on queries for domain example.com should go directly to IP addr 1.2.3.4
+
+-- Disable RFC5011 TA update
+if ta_update then
+ modules.unload('ta_update')
+end
+
+-- Disable RFC8145 signaling, scenario doesn't provide expected answers
+if ta_signal_query then
+ modules.unload('ta_signal_query')
+end
+
+-- Disable RFC8109 priming, scenario doesn't provide expected answers
+if priming then
+ modules.unload('priming')
+end
+
+-- Disable this module because it makes one priming query
+if detect_time_skew then
+ modules.unload('detect_time_skew')
+end
+
+_hint_root_file('hints')
+log_level('debug')
+{% endraw %}
+
+net = { '{{SELF_ADDR}}' }
+
+{% if DO_IP6 == "true" %}
+net.ipv6 = true
+{% else %}
+net.ipv6 = false
+{% endif %}
+
+{% if DO_IP4 == "true" %}
+net.ipv4 = true
+{% else %}
+net.ipv4 = false
+{% endif %}
+
+{% if QMIN == "false" %}
+option('NO_MINIMIZE', true)
+{% else %}
+option('NO_MINIMIZE', false)
+{% endif %}
+
+
+-- Self-checks on globals
+assert(help() ~= nil)
+assert(worker.id ~= nil)
+-- Self-checks on facilities
+assert(cache.stats() ~= nil)
+assert(cache.backends() ~= nil)
+assert(worker.stats() ~= nil)
+assert(net.interfaces() ~= nil)
+-- Self-checks on loaded stuff
+assert(net.list()[1].transport.ip == '{{SELF_ADDR}}')
+assert(#modules.list() > 0)
+-- Self-check timers
+ev = event.recurrent(1 * sec, function (ev) return 1 end)
+event.cancel(ev)
+ev = event.after(0, function (ev) return 1 end)
diff --git a/daemon/cache.test/insert_ns.test.integr/nondelegated_auth.rpl b/daemon/cache.test/insert_ns.test.integr/nondelegated_auth.rpl
new file mode 100644
index 0000000..6a0a32a
--- /dev/null
+++ b/daemon/cache.test/insert_ns.test.integr/nondelegated_auth.rpl
@@ -0,0 +1,59 @@
+; SPDX-License-Identifier: GPL-3.0-or-later
+; config options
+; target-fetch-policy: "0 0 0 0 0"
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+ do-ip6: no
+CONFIG_END
+
+SCENARIO_BEGIN Delegation explicitly added into cache must be followed
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH flags rcode question
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+ENTRY_END
+
+SCENARIO_END
diff --git a/daemon/cache.test/testroot.zone b/daemon/cache.test/testroot.zone
new file mode 100644
index 0000000..2799d33
--- /dev/null
+++ b/daemon/cache.test/testroot.zone
@@ -0,0 +1,1257 @@
+; SPDX-License-Identifier: GPL-3.0-or-later
+; File written on Wed Aug 15 09:23:14 2018
+; dnssec_signzone version 9.13.0-dev
+. 86400 IN SOA rootns. you.test. 2017071101 1800 900 604800 86400
+. 86400 IN RRSIG SOA 8 0 86400 20460416024207 20180815062314 48409 . r3pIfvAMPJ8eHGU/OLKUCCRU2+u+1ah7fably80gtRVEgLeb207jQEAW MbNlTFJhUIomov3+ERdPAOZ9Kw0+k4d856sfMUUtgdX7BL9Zo0fIcpTu 7/ek7EELfKXb/vYfFlIP1lEOUvo7MB/YDo1zljPJ1Qh1BDsp5zyNaTgq O0PQg/nN1UmFXwjEVGmsn6uid6cJfxdO7UaluZ5c/alvOIx3tBAoDJ2j a4He6Rjlc63pEsKBYmAHz2Rdxq5d/+kqVFJUTyVVvMJ35apczpZ4S4gl BPJQZz15hB3OcpPt7GY1TwI83FjGXFaGiuTUqhvSIRoFimRPVOIGSkJX edKPBQ==
+; resign=20460416024207
+. 86400 IN NS rootns.
+. 86400 IN RRSIG NS 8 0 86400 20460416024207 20180815062314 48409 . lAwwTOgQuFowdXma1vVrHKz7qi4vaighh104/2vl6DlEpAFEEOz8y5Y3 9bjWfaNp+UDq0AyqnZ3ow7VN9/Hm8uUbicu2BrNSDhGQ/F66rvw8wZff eE5+w3Ihgm4/vK8zmxUnxRz5mwcbbuCyyTP13WQJ8N89wFgsgezkM2E8 s0qKw5ZyriPopd9X2uLFS1vapezFSSo6AN0khBdrUYWzgCRbE1zLHmKV AW1nWMcgV5zJNX1/9dxgC+yEM1nYhcN1Nhl7neO23pRk/vZ26SruzPdY s5j+fn7WyV0cQqAb7BJ7aTFYuD3kG1s3QUxjQolcCUjK7fCCJeYPINdK m2dLtw==
+; resign=20460416024207
+. 86400 IN NSEC rootns. NS SOA RRSIG NSEC DNSKEY
+. 86400 IN RRSIG NSEC 8 0 86400 20460416024207 20180815062314 48409 . aLdes4mtohdcKA7/kyOdDrCUA72c7DRuK86yxOl3p+5mDarjzBw2Q02b nXEgWoY2RdMJ+KlkxcU87Ojl/p3sIF9RwHlzvW09iXznPyLVTPwD/mnq /5onoMPW4dLbwVIIrFgjhuF/YfN+XCyKoKIJQgB2Qdoo4ppWqeUZXOgU byoPWpzuBupMmrwjownmJLO3bUFUHDaNkIXFi3KwdvhdYj28bP4Z9P4A 1RAKdmU4C24f0auTJDIVDFj4v0ENXzpvDKJyX/VOyLR5+EXwp4YtO1vl TjWueCrTREYDZzXYJgtYHvMDVNQ1uZ+6YCLE7wrgCTQYne9uNp6eAZH3 oFIPTw==
+; resign=20460416024207
+. 1814400 IN DNSKEY 257 3 8 AwEAAcliJP8Jh/RjL3c8eaUj8dzVdEksENKubqVA5FdrDJ2rC0O/bGG/ MVZt+WacE1o1mRVwTT/TrhhZUAzZ+qOcpB+IWxURsR4vVqVwakHMny7D 2aLXKoVXwTo/VhAQtHDw5G9bxGgwybPUtd5Vz6EIenUsmNYZ+Spde4l8 vpw7UISVL6q0C1mwHMN18P/1yfHmbkS19b6B1S9Y2aputccF1lso3yiF Ig7UNqqD4PNxSo4jByDnajQSP3qg/LSJSOnzBIumb8wc6svxgugy/pxr BFKgGGk4/JdJCKufdfU5jFX4fJ3HM37G/RccrtGhIf2Z1utoOyaILoa9 wT3O1WaYG/U=
+. 1814400 IN RRSIG DNSKEY 8 0 1814400 20460416024207 20180815062314 48409 . MiiRlBAgMnadkm6Y/IDLGiE9Y9xvGU0u9IYD1cAddUMpYAwGe5584lfj 1L/Pdg+OeJiGDfFSD7m3ppX18wIeo5eWHmdCO1/nEAdPl0u/XDB/avtj o3Q34szjOV/sA3s5a3Kc+DFrBiZiTA5BwMIHZX4vvITf2cEq2K4K39Iv Cg1blSathklWkpgYIPttpZIcIt5vxoe9e0aqar6FLOCWJ68noreCIenR XmzhMW+l7kOBoKOvkyv1lcDM0zWXI9r5lqAqJB0mWsCiR+VloxSbFii7 kjUDju8BqXu2G8YzM7y0vMytMafjfLsj7bHvQ1HefOht6Xzi1jRHblEh GGQ8UA==
+; resign=20460416024207
+100r.subtree2. 86400 IN A 192.0.2.1
+100r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . QMB4uw2u+kJ4Iic6G6fJ1B+LL5Jp0y/tPHwb9iW8mfAfZoaHuNxUFMdW nncNjZcjIXpeWiWcD3fzKr6DwJ20oWMpt9fxGthYyXp5DWhmeb6Pq6sS cWy5xhGEP6Cv1gBx4oZs0xmdmLsi/eK8x0E6DScwGeLu9v/lUGxnD7ug b4gl/9ABXhFVXW0qALF48dTpc5mMDsAIkPJevarbLDrg3CyOTrCcZtc1 v9DYSN2KGG7l3H7jAY9WNpwhTGXVNthSGHLvSUmzJ418ya8bU9L0Baoj +WBmdERcmFyx4KS+mwDcJxORwLPtEpRN1Kdg/X/z41cw/ViakoZ62ikq r2j8YA==
+; resign=20460416024207
+100r.subtree2. 86400 IN NSEC 101r.subtree2. A RRSIG NSEC
+100r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . EK+71G5XMyRg37UmfcnMxVl6RbkzUL5YLi+kL8LXYXrq5AEXCof2K26i EPVZlQqjaSSyCHDV1PGpUAbxmGu5JFJ17wksgJ5q+vkPMTJhU9gVQUGf 1Ymj8hOa+eYs1Of0/3O2mf5V5KOpQ/R/cONQelziCLQeJJvJ70AHJUx/ 3+guSkXehkZszxuVozy7AmguyRjAWtNOLmVR74HFaP5+PyosZhie7LZS rsGq0p+VzHc1Xl9BXLBg/WrBXEpcuEtvg1wc/gVkNAlC4NLr1zbWcmIw Hdf3/NFgfFkJ0gFRX7P3+zXCipUHjdpb/kxtFCopYlZpP5km0cOmrbq5 rPwwcw==
+; resign=20460416024207
+rootns. 86400 IN A 198.41.0.4
+rootns. 86400 IN RRSIG A 8 1 86400 20460416024207 20180815062314 48409 . wvg4r9R9qeCwgxxb+Hrit/Ag63lSAzB8SPyKAz61GHojJbES8sz1dvnN fpaFX6bd+8oYfLKK2m+xyNITXm7mzZU2lEg6eHih4E/PCQzEfi12VaQq Esyg46LKIYCMcazou0I3ot/BbXHokSlAnfyAA+2+7EKSFK6SZDVQwK5Q Y0w3ps+gevcrnSHSQuymyjkOUgAxGtGTEA/QvmfzS7f7Dc0vrTRHRmOU 0lJ6Epi8kajwMjtEkRWN0TUnwD2z1eNyaCaa+C9TTwIKGoQkZlMFoc/m 4hBCPDEA1/Z5qDVFnFdWNOE3CLon/P14ONTznSJr8lfqdPmRb4iXqIn3 yNRLaQ==
+; resign=20460416024207
+rootns. 86400 IN NSEC subtree1. A RRSIG NSEC
+rootns. 86400 IN RRSIG NSEC 8 1 86400 20460416024207 20180815062314 48409 . Kv4r9Utt5+TrzUuzXedmlJlJsjai7Ebs8Ldj2TfV7uktkOx1GTCTMIFs jmWBJDi/tm2CRP8VvNL6tSmxOQ2sNRXbyNmbgY+WujCuIA1hTiYC8cR5 p17K0MuR6LDu7UfcHVUAIiiucqQ+FHgnDN6DPyeGPMEqiRUG6KFtmQdz VcVHN9EeVwvru6l7M0NSg4onNGDUAd3Lzb4OVSdjcfCC5/TRxN/A04pm xIbag7nBTmx5T7/RRhywKycnbaPCmljmGtwd0+ikdNtIkQZa2/S82rOb 579vgx2cliVQszNmqei3PVRSHDoqTv26lHM27fTAkwdCGX2rBMDRLjQ3 Dk/etQ==
+; resign=20460416024207
+102r.subtree2. 86400 IN A 192.0.2.1
+102r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . AJoiUtB4aQsllEPMM4jYB8B5ZSJA3nAZnICi0lxmpJzhYUVnOKdj6B50 1U2TADwJ1SHs9tciZAuJvILJMwu1LapISmZ9692u7CR2gcTfifnY8iny +cZwEsFFbwdv/pHMIZhox+h2+H18ltSpa8Sad8vvnqtaePtUgnJdR3kp 2b5q77VrSxEwizLq6OkjCYiCPh7YrbfNfTesZwIbuKH80TSaJF9kTVar hh5yW23vEwq0tGyrYn4bYJR2OzZqukLHz+aSMIQ7BpQPHY0hMWPndb5p HLvaDHbmp7Mc/1bnhCVmqqECKouV/Y8omUUHOljyjZ8WlCol0pYWQm6L O/U4SQ==
+; resign=20460416024207
+102r.subtree2. 86400 IN NSEC 103r.subtree2. A RRSIG NSEC
+102r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . PE/1zyqvetDmu+d7yFhICfmNWl1AmSZ1K5tKtb04wz+I1aihwWkozCuC hLskRAIrhogNSFDjVqhM2F1HFYm3ACkr3vvWxsTAk4hnvIIw1TVj+iqU ZTpXNKnS7UarPxM8a5fctME2mgPSQnsAzJRlkInpT450Ls7qhTpqEREx wMAY7fQx+Y5zdg90rEINJBdKJgw7K8ES3bm1JwEIpkjw4I5NZhyAS026 2fW6x5UaTGWhV1Qa7YVwdXrEDxcsyb/FR/N0AofcP0JrQ8/UfPJNoO3U rtUigRA8tDapiQuSTFaYb1thtqMgGtrJqxjDRU82I75HBZnhhFilOGUD fcVq9g==
+; resign=20460416024207
+104r.subtree2. 86400 IN A 192.0.2.1
+104r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . lNhsi5Dvb6lFrzp8+A3j5DDY+sK8p+CbB9jRtxRoCh9TJsWs3V8tWfcJ qLN7PKgCchmLTfQryKsIERDBNgEvaFbygk9UO/YX4z0J5xVtXQ6lRz12 rcgR0EJ098ZoOtmHa25+YILXwwO9WqoBzx5VItYduOaRXqDJA6QcUUyx cnd14DkfJcD/MXKMkWS95SIIOg5KuOga0N6H7ATIxkrTCbqRfLwoj0Ne 52Mp4LSyVY9BN51s/jHmYOYiubLMtGYKVVffkmH1LtqUnY/kNK0YixT8 4zs1REuk6e3PAiyBOANvMqVm76FiBapaZgFnGJu/2S7foTC0yHfmLh5J NFTq8Q==
+; resign=20460416024207
+104r.subtree2. 86400 IN NSEC 105r.subtree2. A RRSIG NSEC
+104r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . BrGAn5NmHS74Ru+CcjBzjUamO6en8GaTg+fOuSaECpFNCx/rnFQziS/a gZs44Mlc3IdXLEeo3GI21Uqf/mNeGqfl+TCnUfnevy+1Gl2093dtma4/ LNHMd9BxDmXe94WQVp4xJOLbICv4aaKIhGD7w4ck9cMk1r8p4ngvsvoV kn9uLl1lx14yddufdS8B/NGvzeqRlJNdyfZJg47pQfghgg+qLbmmzqHr Rt+ke0Vge4Nur3PsNs/daYb02OWqWA5YLbljRaKqatEn95ohkrfl/CMe rZ3b3gcR6dowj9+dIkGODCQhrzqtk3v1QAEkYq5LJDPPnhXYduNWqsz/ 5F/m/g==
+; resign=20460416024207
+a.b.subtree1. 86400 IN A 192.0.2.3
+a.b.subtree1. 86400 IN RRSIG A 8 3 86400 20460416024207 20180815062314 48409 . BTJSG6mn5eRo2GDyw8lT3S7POU6BBrB2w3ULx8+BY8aoEHzak8Ul/abD fqneEji+subHFGpMwQXFtzKfnwTTRHyHS2P7FZQO3l7b+T2oDRZn9B0d mrmGQRmv5XrTDlO0WRYlRsWSMalkbUEul6L9q3koCCtXd4GCxDh20tk7 o27pKtuO0ALptDLIMXoVdhRhTBd+qARVJrg2u/XyUzlwqfgZTsY6SkyN mEYvK4UCM1RkhqCqo3NBNmR7islmWVPM3Ax8uTssCf5T+MUN+gNT6Co+ zRXX71qGw6hpQFxWe1dA9PCna4ZoWPIfx6A666blMrciwbYTQL8xUEPS 5RmRtw==
+; resign=20460416024207
+a.b.subtree1. 86400 IN TXT "txt exists"
+a.b.subtree1. 86400 IN RRSIG TXT 8 3 86400 20460416024207 20180815062314 48409 . gN77jXi+ntj3SeXk2WprymZGcwPEXY/0w1svtsP2RXijvXwOlWlpmsSK +SnZFtkSRKwJXEY1nSDW3UORaDzzZrraMxCtjtt2Vi77Uqi97PdaRmk+ +IRcJBNQ3PywGRdqw1MZuPlyKbmGe8B4PE96d6ya4fXtvL8tuMU4L7uP h2Wn4sB1eSFpH5rGrytPMyv6W4T7JubL6+R1YdmQBAARJXnIqN8WlOYM JiZtQl7kdnPOxxhHZCzlFOP1Ci934u9jh93ynJPbF9dJG75f74+sWw2k RHZUu7SkphoPsVR7nhulAHcPB805yxWPtmMC2Rsq+RGbLpfgFENPsnxv VZa5Wg==
+; resign=20460416024207
+a.b.subtree1. 86400 IN AAAA 2001:db8::
+a.b.subtree1. 86400 IN RRSIG AAAA 8 3 86400 20460416024207 20180815062314 48409 . cLipbUelm96/75NoXOJR3atJKr9fjYaz4lu4CQBREmQ7eUwkGfDGW7jj ar60VA2OSVT1Q3SxsvKjZ9OjSDLtPbhVeIabBKhDQWULy3c0rBgblMfc xIa++QItLiuxyfj3EiwGfwkIlwuM0jg4sByisvWBeUwsIv9+nHJYZERf p96DhsZXC4OTba5Tai2sJ8CmYINWQBu8GRb9wrtrEBGg2LyZifXRirTB RoTuXPOSScURU4VmzyJrVLuNipsd9V6Dnq6J4Yuc21ws9ZrB7nF1TYqr zmW1x86umJHM1Evw6NWrHX4rMgiTiwJR0ju4uc7FDZ8irdtmcPGr0C9F 3hycmg==
+; resign=20460416024207
+a.b.subtree1. 86400 IN NSEC 100r.subtree2. A TXT AAAA RRSIG NSEC
+a.b.subtree1. 86400 IN RRSIG NSEC 8 3 86400 20460416024207 20180815062314 48409 . ipRQluXZcAsYQqTMnV6VDykJym1bh4VujIFvWnM+oQxZEpsreqwl3hFM INUapADed66F8p7goYlC9oKdbOfqLAJSBvPyL2MJIPEifnTeFI5SiQe7 u2NxsNn1glotVBHGL37EOf55xvbO9N/y8fnIjtOD4g8kJBthaeyOCsc+ KbcOcBce9y9f/meoibQc9plyQSeGhXYtc/9jliNmnJehG+y4WUZpmeOc sy0NB3VDHMwNigxUJl4+ezSGlR7TLReeGXX7BGBSdtDigz8uDpi5vmXk Ebmxjr1gSVh++5cZV2l6IhA6l6/ZNWh8EnYWnydHZR/FdMZ/xnJP9fdK bN5Kcg==
+; resign=20460416024207
+105r.subtree2. 86400 IN A 192.0.2.1
+105r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . FBlsr7zNihecaykcv61PL0Huh8SECrXoZ/unuWxmT+ZqDKjmfFGxoG/v MgmmJ9r/sfZ29e9mMnfBtXj/xJLW1dbHYwFZSt4ZeGZ+W/ohgCKVW0Fb XJTZacoWJtXhgObs6gjoab5IPqle3dgqUsP6xNvzonReL1IW7+45QRh2 nWU+4j5OTL/eO1mNXU841PtvmmotwDamR6aSoNr3X99Hwd3/3yJtRIIW JYVAr5G49m+YickDVH2gvJ+JZkswzGfbQgXqThUiSMBfHw23LQk7A1ZH aStSqsRcJt/w1pTl5cEDpnq2yFelQdmCE1DqnUIOkSTRdemk4ObnXFOW FArXZw==
+; resign=20460416024207
+105r.subtree2. 86400 IN NSEC 106r.subtree2. A RRSIG NSEC
+105r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . uSMqXmIDnP/m7EW1gMGI7N8Wp6x142d8xTtJTFJ4mOPbyrKBRDDdzEEQ iiistwQThYUZkM6gWpiE0yfTvUI1pP4Aa6zASUExJoO0P+CEmHTmRJ9c 2sCqottCOirXivxfC2PoxXlIZ1nQketizjzMXErjKogU4/HaaaxiDLXh P56bAeFkIqGKujbdRhVMArugKvbbkjVjE1iXznG/bzKqOXldi7JNQbxx cc6+fZTs4Ahg2H+FtQLH+WFbD+JBLQzvc2WnjqvNq5MGTSKxcuGDA80O CLEFs/7zhEBSZYhBGoVXqywvDR4j4Lox02g5wUpWlXK10pnU0ppr6Asx bM4wLA==
+; resign=20460416024207
+106r.subtree2. 86400 IN A 192.0.2.1
+106r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . kIpw+6J1f7ByzuP9ynrP4bmQTZaXCF5CjRgDLWoIcU+mnqidsWwjZRHb 1q8OtXcUUEfwTNc6mqvUnWHXQHARTIjZ/xtQeAwfpq8ZGjmplXykmlDX Fl3p4cleG3QM+uhHnZRncbVSEXnOA8H9PFHpDSi9bBVLmqEHOot0evxA 4wfUkGQLGpa2MxzAXymWO6A1RdntuL+gBbRYgGlR0RnZycMMLtRNv+ou QhFEuPw/apF+fqmV82dX+XL8kEWPflDhOBbZqMO53sKFj5MG+gXBiPid G5VFgyFqsc4atV/PMk5RvQ+jRE8PgC2lWmdmnOL9D/RT0O4FjrXbq+4/ LEuBWg==
+; resign=20460416024207
+106r.subtree2. 86400 IN NSEC 107r.subtree2. A RRSIG NSEC
+106r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . OnRo2W1aBYVqzLQsgUF2zisHiaGnlbp1DIC3bcReDq3hKe1EqPtqffho 3UcvnzVOIp31qTjr1ntoWhNt8mOJMDzn2/UUSPQkAj8Laj1lOtSnLzm/ b8c1eFb45LTsZHic4DZoEwlhtwV3EmwKJWXMkDQZdV5x+g2RGGZ2W30t tCZllImuJbHLyCB7Mwy0ipGrVQ9iO2uCITURICTiDGKwyIox0Dr/0la6 7ZtknDiqG27PC4me5AASkGj3DaLo8ZmlBudYDG4sh/B+tryvdrhizgcK XoIrLqNjB18d9+CgKKVmRLZr6yY9aw7XSlP8euPJmQZv20CyCxhG5S+e dpCdAw==
+; resign=20460416024207
+107r.subtree2. 86400 IN A 192.0.2.1
+107r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . UyerZwNc/ZaXNSvYbxxB4CpWkGVntXXrSwtyqIeBY7LUSW1738rmg1Bj V66avt0M2HrlhDJioLvHCjI0xwKxaoLEzDcC3g6sqvvDW/42KKzMVAwy 3ARu0Fm4HNlbjuaqsC1h0WqvIjJBMHc+pK5etjSRJ1WqAq4YK7fh+DE+ Bb5NMXyqWTFe0aW2nia8v2oZQ5QlRICXBQ8pvvyiOUmiv+CuNHYOTJ5N kcvekf05R6QVjTAR7cIUn3/87V8psWcHuuV+qgTJ3eaQ1EWvuO+B6rOH eYLsvHfCi0EoE2+uNtloBTL1H8URJ8E5+XMMSoGEXFdq9A4M0JvhMfcZ EuCshw==
+; resign=20460416024207
+107r.subtree2. 86400 IN NSEC 108r.subtree2. A RRSIG NSEC
+107r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . B0lyCGkGFKCwmYXdbTUyanhQP1qlQltuiF8fcMyPVtlUcGdML69XWZ5s PqBiuEZ13avpCL8HTQckuTcR274hxGBsP0vcMGIwHJ8O5BqhN1Rp+0SQ aC+MFTsH4Q3DenHv5hkaS3FmdbEN0hQU3PSTvjTc6X1HSz311Qcc0EVc +dcnxa0F6nCwpuNU/cuVQ1Vo7iA/4iXiGDFnek4udqGAbxK3MuAYNqe4 YtQlnA2hOTrJ7nDe+n2Id1jPcRf0SRT08YM2hUrkMjiFi+eW3kD3jSIR 6O/Rmz8QpruQBsf3xPfv5zFeam6el6rca12lcSoFFWXq0WakDF3Lkqgr LF9WSg==
+; resign=20460416024207
+108r.subtree2. 86400 IN A 192.0.2.1
+108r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . Odwq4YxK4F2S2jUo8vMOFVoHOCsC2CdHRhdR2Z6WiGpk3CY4qD4uIAzy JW6vpL6fKgHavZHfg/YA1vyxvJ96lMx4RiHkoQhoeugyQ4nllh8Hrp4S IJEyjNq0OqtO9QjLBSMHvrEIwVVfN/sQHainyoLquY7bMQdJvm99fN5l W+pmxMlLVG0n6M2UA/o006q7AXorgUsVMot5lyZ6TCq/YFZyAkIYZdJC zaVS+WYcUOMRQqfOmWhameS4VjOSfBjPjdO7tIgZ/0N3YsSm2mwaDFYD rua6BIoriiXUurzPZIfaI2eo7JGPB+NM3cOZDDf9NIFY8xt5SDBUz5Mz ye/veg==
+; resign=20460416024207
+108r.subtree2. 86400 IN NSEC 109r.subtree2. A RRSIG NSEC
+108r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . mHx6mvjFhd/o6RvTuRmobVp6p8PC21Byq/Bah8RJnZ89E3uzgnw75PK1 Kv3UfGw33xK53ujjq2A3R5ik6ozJQTIF7CRQ3g8va3yKrCttyff+dckT qBtXpaDkZlm1JkgH/H1AQ6z+4l9GlLOIcrbfwv6ypAgxRME3lcOpHM/o xyIuIdHh1GntYzeyNWhsB7SOzpqAePNh0RVLyPslPGhm7BFGTv2MJbBp BayfaWNCgn6VISbj/9K33GCZMbbh0Usj7K3HIKHoVtyoNP/izDnNCXDJ 8cNXN1SrRl/9jIOw2Z7mIt0dzxvC4Ts3SNQBdgHd4JuZV+aasHt49+MS 0JdlTw==
+; resign=20460416024207
+109r.subtree2. 86400 IN A 192.0.2.1
+109r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . eI2rg6VV++ck7Ei4g/K4XH7CEKliDx4+a9xyYPDHpGZJ1FhKjI5wcJNf li4IQXP84I15EKHSyiA4CVn0oZ6GTGuJtEZWkOXndPzVTmRW0vyk1tm0 oVaYcBNfVvYd45qLYMJLTwWD0cooq/qHoFTofqKsqgW8Jxe+ziZnhqDH otRi/B6OZMmqG9ZPkAKWmC6eHyBSzHzBRZ4U5fSExkdzeqcMA9+sNkNO c1koeZKUFpbzIFNyFu0erZWaZuxgBlpkyCX5TvCNu5gxKHOMy9GsKymJ OCpg73ltfjAh057odKJd+5cZBt2sqgHTipPdK8OySn4l4H4ZiWt69SmG uoVlZw==
+; resign=20460416024207
+109r.subtree2. 86400 IN NSEC 10r.subtree2. A RRSIG NSEC
+109r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . Y3Dz809IO18mcCEk73sQJdCJteOpR+bH77aRQfSD9pXz6xwCmlcdnqe3 zvLJeBdRrN+wbn8TKleUIoPLQZcX+/K8eVrcrHtn+Myit3ojby3WBkqK GwMEy95fxFA+yB8EWqsVPyEFgcYLiawf5Y+d4CRp1YBF5C1iA2SYDEfT lzDQ24IeI2hKsUJSxBGzhzn334ghrwySQ/8XMqVBa0Az4VCcJL9Or/ZN a7+lw9v4afZtbMlaYNQ8V65u2oLaRXPfiY4gC8j0MiUxgdpmbFmB6x9P URY/jLmhclShe2VzRiHyir2Whcf2lRjs/o8Sp2HOqCC2K3XeG4B/6+X9 oTAYYQ==
+; resign=20460416024207
+10r.subtree2. 86400 IN A 192.0.2.1
+10r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . iAfz6tNv3K8iEbFfVH2M+Oj+tWLA0JK/yBWB4mERkTZaJW4Z5I5vBCYo 1TW5wj9b7QcDvMYGtgHwQ4UVZ2QZB4liQnazhqyV7OYr48yif5q6INFy NP6l9ZVh1axfw8dUmorOA9cEZQgI7PJkRckspp4uLg6NmQaaY9Z5NvvQ cRW+2zFITLKrZbtwHGYqHIpB+kdakBvPXemZfWBrMQ3VcOO//cXX/O3Z B4w1AsX3odnHQbLMGjs3tJc/cs5ClFoZxtOS9rNPJHvMs5YFyZz8O2cF jfIQwZcmIA+iuEkNP3N4zLJkzqRBnHXSWmSAIagvCrdfK7c0MBZa4jpr kVZ+9g==
+; resign=20460416024207
+10r.subtree2. 86400 IN NSEC 110r.subtree2. A RRSIG NSEC
+10r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . QEFhA6SbI156Bv/lxec5Og9S7gwCeTKzlToFV7UThfHykz3FA6GjemA6 3tsgTi0OzEWtEzK03a0ATPiwuleqcO4iY1m5jwh0gReKT0iDiCdVEMHL WQzL5eKXOu69G7qPxust4p51PlDqH51HhqTHWSiBIoIn5Keus7xdFxMQ IwGiyBIrAyIUZtO48FvZJLI3hNn3ChZJjVRZUmiK28Z1vkn3vYPbPalg VmMWgb+vGiHJPj/RuAfeMZ00keids2ICoV5YgYokzyO3hhr9kfF/sYQj Osnp9b3B4EC3Qm9bzTzt9CBcIAuvqQUb1+vrGssNDuAtVX68WBH/iL6C dPUpMg==
+; resign=20460416024207
+110r.subtree2. 86400 IN A 192.0.2.1
+110r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . Ou9f5KbvjA77eB+iAQ3OPRHwcUQrNfmR+H0RF6zInwO6fQbSP9q2jWMU 0l8Zt7GZN3rgoUpchhZBBbgGckw5qpLa+IiRBGphxeXmfeLOFMeUOTy+ Ge2yRz6Z+LhTWKUVk/vgEBxklx/OEmsM7/y+Bkiyt74+s17KLM70uKb7 AA/URH5lYCS638z7AZgAbxqblAlWqqz0WH4IB2yINUZxG3C9tZS+xByN Rc0+jL1owXuJkrNMjONcMRrPAfjTKYlZFIFoGs0BwahwTRNWlPSw/HsN X8FCtpkvL1w+3geku7eMUwokfHvJvvKBFE7c4WkL8dCxaBCbHXYDquNy AWrVSA==
+; resign=20460416024207
+110r.subtree2. 86400 IN NSEC 111r.subtree2. A RRSIG NSEC
+110r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . wtaj215QzpzCt3LTtSZaXxUo8wJmWo8tcjhsB5/f6VkZnxGJDZnqCAbt r4xsIMT/RUfwMX28v5qNonI2QHNoBmgOpsdiV6ZWuwpgLYrBpRkOpLDM XO3XH/5kdbQJXaRHKBRdHoHo7J1suISafFwxBgm6I+cTEIeJA5aZ6JOq r06Jb8GcqzW0MgqxRVuHcgv1n4/ZqCmJlJW9ZzCoC96lbXCmWpAs0zFz UM0IYUdyl0w/VqRIHetQlB/hf7tof4deq/rPyatxcYWPkiYEK6qmDEzA hHRWB4oFYegcQOYYuhj/gWGN1bF9UEVsPSQhHrFJpsMSQkhxd6lV/t5J oXBFNQ==
+; resign=20460416024207
+111r.subtree2. 86400 IN A 192.0.2.1
+111r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . Kvj8eksZMrSLThU8yas0K/Ep+k0LEZygkg9Nw/cvTpK3gKlDV0wXGtMM xEa6y+VnVmELbZg5205/haxo+diQ1+NDpNYD6GY/zgBQkIUT3MeHGdMG L4WHwZhqg6vHVz6XtQvNOkwq5IIvwZkOTnMmUwx1H3kZOO7HyazxmkY4 0ak9ggXRDBTvydarg27CX1UvAh3AI67/Jsy3LchaD0TUPtKIEK66MkkK ja8HXxAY2qiI4pc97ZvZOOjAh2Kj29AS58ben+pdY6B7d2Ea+04jeyCQ SbFP1YQGGzpI2/m39y+pcBJQIDa9aTtcL9/W7sn+pa8NTettHcpGfGzT Hww0Fw==
+; resign=20460416024207
+111r.subtree2. 86400 IN NSEC 112r.subtree2. A RRSIG NSEC
+111r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . w9XbWXOIjG9K+uiCTpq04S5a0ZXPK5eAQ9wZ9HWhBlNwLD9k0P+4Uami R3NoHd/ns/SqCdhQpbrR1SYnzhT/hezRzC/ahtipvsc20OCoqn5Cpmcx Kmh30VW6mxUVtV9KNumoM80FQq3jIu/q3r9I8oDG23TAXOPDc9K97Qxf 0Kt2RQgh0wYYCXfL/rlv9zUn/H73Ldj4N0gioOFwvU0SXbJVUfPG8UiO HV+BtY382maAOGMR9gRLHVX0TIKD07QIKcnkUugLRhLlgyJ1Knzetrbk O119Ti2FBOqVhvjEcm8v28bvo9XKuBTR2Guk9AzsXJQGC0juE6JJqiH2 XtXlLg==
+; resign=20460416024207
+112r.subtree2. 86400 IN A 192.0.2.1
+112r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . FvJNCOO1H1K0KHlXwdwyaFSQNPdUG0D76yZkyQMhOm7wxjC84dq6X5yi g1vNXp/vvovpRgLeJPuQqg+7O2MekQUTwNQSbzehtOnY2JoPXbGmllio +hqqk2gpqcj7bnIZpN9PkjcqM/EOL+TpmizPi1LRcVl9EHfsfQdIRUBj cMdfveDjOuyV8iWtNLwPUG0bP/gqoOPwkEJIoas7yMbQTiSjAZtV701Y 0gAoM6Kc9tINYlmydqvallSow3K9DE0otRVwaR0IFF0o7uSjWo76sYsf L6UyqK1/WDMkh6gS//IT4ZvwfcXbKi/WrFS4/AurH3XyTY2D1rvxZi/B K2UbGw==
+; resign=20460416024207
+112r.subtree2. 86400 IN NSEC 113r.subtree2. A RRSIG NSEC
+112r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . UDQGBNS8u+0VJLat16g21VS795ucpkMD/GucIPErSyF5zTiSke8jThPA TllPS+Ynx6hcljlUnye1ARb5pqcp1gV9DN2L6AFgQfSJ/gCtUe8Aanwd ajuQtENFgMPy94nkjEYteLvUJNP0x9mmnt0Y+Keyaehwz7ppI+1eJUfs qZvZMD+i/o2lKEb4KRo52ju8MGcMXOWmgcgDqwPf5EOH3tG89fVOE90J gMS+CQbB0f97fDGWea7lAou+V9HmIqxtQkUHguxwcxYot2rx3GKw+ACr dNY4hm04vseoULJm8MVoy4cEh19DGWmxOgCMW59B8EQd1+h81FDfszbx k2NdqQ==
+; resign=20460416024207
+113r.subtree2. 86400 IN A 192.0.2.1
+113r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . lMLx5WcSLY887gnXvV7zwS5GzmPas9qF7q6GI+9KOdJFcQnbRsmMZlXP 24p6Fz3qcXpH6aMKg7y5HuGxwcWfIMY5WBbdl7rJ8r4nu7UzqOXVQDIC z9Q0EVL7ZYUynzUCGlg1Twb+IUbNcCktySwbIXyt60yX87D0JX0xa0UG P4vlUz602aymQi2J2OCt9jDMjGoopvdy6D2dpr2rygeajpgPrn2XKbqO sdG4GLEnjwSFRWVgnajRM6D7ARaVp8HNElOwdQz4x97AoqtlmrE9XB1b CV8m45n17X4xXAlS8ibPPrs63Q8WLBAXPGiq4xjAubqCkWRJOaKsud7O Ovl6fg==
+; resign=20460416024207
+113r.subtree2. 86400 IN NSEC 114r.subtree2. A RRSIG NSEC
+113r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . XSQUXBwDasTlUvwGR7qmtItAd8IN2t5PEkp5WwyoakU2UerAOAlvWew5 jajLTb4P5g6hyqqeub+undk84ZgG5hrGK8qK8rf8EhjkPaQl/svow3eh x1tM5sL+CpKnG2CgEKmHdVEjSS5sJVOTE7qUJ1HG2+HYxaMkuNdANNuQ cAuLz/y0YPZ41c1ii10cH80+K/zP8NipEz8EJvDzU+r0NNghiFJI1leX wUeUNQ90svZjZ5XujNk2Q9lvoTI0xV0gIIdpTooTC3pDmAp7JbxXLAnV /IRHHgfX5/6SDpqtQUcRcIIAsDgEut4lktzYHmarfHVHZqeuNIardgt+ f9N09w==
+; resign=20460416024207
+114r.subtree2. 86400 IN A 192.0.2.1
+114r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . kmW55IQ6ZIl8D0E+Jh/ANLu3YzE0MgZPy51DVXHSjQBbNRZc9pGAUjA7 5yAZyPlySl3WOZaMDmVSquqBt6TG3mNo3nyweUKGupcNU/AaAZlKfR4T aloJ5oB60sDPPoMZtyet9dnrncNmfUJSiWackRcNPbgzySDmxbc55XWu 3du14PY6EaG6cgxmebFmOneffmKH26HyyA22Bum1qogLQVUGzidYgxQB 3M2GgGty/mHWp+dZpRoqh9gijN7w2dKbdW2fJgaxzrBTyL7bBYOaUFL8 pAs5bQtNE9kP3Ks3yQrVbn89hV+AC6RUNOcG7qp/YsiAFPHRi/RH0rwv cuWInw==
+; resign=20460416024207
+114r.subtree2. 86400 IN NSEC 115r.subtree2. A RRSIG NSEC
+114r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . qYqJCfeflaJz7SH9/hax1OVxNmdD4IlPeqyj6RcZDbZcoLea1YwCILCJ yKJiQhWJA2KbF/wgVrJPSZeNNFNgtsh24Rm/errWQVaGZs/eJOQATbxG FZhVHxlx2BguyWZkLfbrFdjkI4vONi5/LDF8ooYF1hC4go0EH3+MUWmr wfKJUFHZZ4iahun+RiYvLFtg2zlQEzAInLgMzngDOaVZ46XrFitcIo6O Wy4W6Hks96RdGAdOlmbsMmCmwhf5JFPDEu3xKgVC40IuU2Qd6oQSOtks hoGmOu0tW5by7tQXRhBB9g5t6DhMUplvwXxYF7noSCotVBAm0Gt7q8S7 YZpKeg==
+; resign=20460416024207
+115r.subtree2. 86400 IN A 192.0.2.1
+115r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . ozrkRqfwxLgosoEbVRsyZuuxUU4XmxY2CKPQMeqwEJmOfNxVyDmJgG4y wGTO+hRQTrwRFSem5918Up1MO4Vt3vLr+i/n5aXbl4rq2jvyQidKpQCV nXxF7BWOhyHO/v8ns/5hr57ciDbz5kPjfM/JI1W03XnhdHd7opEEiu6J zlb9i653+dod9pd3gvuy9gzlhVh05uSOgpVJxjIyvRrOW/DqYg1iOsHR Ew+1q7bZlFGDaUL/3bmFxP6G2C7WxSuB4a8Wmu/KC44yb1LwFe/bhARS J9NnKpTX3SBP5A0pK4e957YqtjXRCMA5gXjmQuadgzIx5wFF7WRm+Ga/ HtojnQ==
+; resign=20460416024207
+115r.subtree2. 86400 IN NSEC 116r.subtree2. A RRSIG NSEC
+115r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . MvMYm8VkU6wGeUYsGTXft4vmyuz7KK/0cQcw8il3uobixnhEwtwdr+6y 5BGDV6MLNaBKWptnfUn7s5gN1t75H+tlxOrQSn34i6LacDaWZQEdHHxb A7089FsPBL3SgWeKf1Dn80YllFlpdH4xWDI9dHQgO3CuUi2lEvZ61NjT 9J7pBZvqQbb8yTzxUwXgSKRfmgjYEIRsdk8Pg8AwVmeNxmbH1oQSo2RL gpTpNKigdnA569l+2D1THUSZsMxnIk2G5IBFFDoPzpnp8UOfPl6O4j/g nExRVrGcSsZRLTwHavYrmsbMGPKFYlub0VbM/jfPjXe36fW4sMbeoyvQ eUu7uA==
+; resign=20460416024207
+117r.subtree2. 86400 IN A 192.0.2.1
+117r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . FrC5ZQG8KQIopup7Ndzgh1LJCVYIUutqsK6+EeQDTBPZWEJYksRfjUMy iuaI3AzGKQEE+gBMwqXbPSYFDqj01ac6IXq3juiQXGpi5iGTgYTiict0 ggAt7UbKswuguW9w5WxL/+tHoqxtoVzojwT5L+NjgPtHKxdWjYcIoZDy Nm2YsJW+KNcEA2smFetqwdWc1bvlioE+FXAZInPrJ7dI8/5aKWiCCVqu jpOGiaTlAHGyl1Kn6psrsrptyaZbr4CseqDh3opLuTrLClA624lfbcr1 gnKvMDFFpkEIRtHDRt9h4/wJlcS8skVEUzrZna6K61U/H3ItL8rFPtnL 18L2aw==
+; resign=20460416024207
+117r.subtree2. 86400 IN NSEC 118r.subtree2. A RRSIG NSEC
+117r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . X4NPBF0M2VXoAw7t5OeWCIKig/KITQdBW6BxgFsidlrNacGLRYSXOlmT uFfslTO6h192MVUCjP7Nw5qXHII8vQ/joZUSO8diArhNI4rWZh5gO7De l9qpuy+Su2GzcCJ6/GltrpZDFSJo0PlCEcIiBQqZ9Tys6nHwwc7GYaGj l/biIrFJJDCv5UzYTob5Rb2zbHw3mHq0qh2FvmiYMZHo+vfCT48GRGjk Am5j8tQERyBGJ3HPOuXTif4wnQVYSHNrkMlCAfcsHQ/7FwPSyJMNQxMu EOlM+kjhmDYpiajVpcvZZ05oqw6iTwJM69N+zzuqvgcA2gQkhhg+VyP8 az9bfw==
+; resign=20460416024207
+118r.subtree2. 86400 IN A 192.0.2.1
+118r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . hIP4D5QN9rCph/6IgxToHbNJAssjLJuMq1zUZswcxRxUTHvShbPxNRon vCJwZscL0FbvYErydUK93+qrD7yU8Gohk7h0CDbDmRzgLbiZBWm/vkHu 1rYV+4ICCwAhlMlK/KyR1yZ5gvy0NKnd3pwapJD0EGVQ9V7AxAG1IHk6 N/8lQXbRkf/WGLCA5d3+nkBhoKZV6P6WTtI4OJt+XJjzJD9V9pFp3GUf VxHV17wKueFszQRblAn8vjYJwDihQGlyTcrJerZ62zm3yHRSW0m98T6N yHvNKNKvVHOoQQYtvm27/GC17GcQKjG8eQMJ3qGfzht1OEGtTSeaFLa2 lj2h6Q==
+; resign=20460416024207
+118r.subtree2. 86400 IN NSEC 119r.subtree2. A RRSIG NSEC
+118r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . ZubXMLN67Fh758fSx4K3nSLMgGsxOl6kBkJG+7aZImIXyw0W4GGSI63s VIG1DT1VvSShWiO04M7FES4J/1/OhCSANMnivntKq2nZtbEEkiBp9kXf WJ9L1cvEsD8C0ca/rYN6rjP2XUxMj1iO/8QfJSyF1iGoAofuVdlLeHoE DTFCd+MxHdslbGawtAdycxjTFF3aWDwnTbP7ID2v7wiJqySwsBYcqefd iTQh+XdrHI1bObZNIOiQB+C+wKCOLmwzhhqGuvOzGbmCq+ELaQMs1wse VEGqV7DTVDu++rMo/QZhTVsiBWy67YPP4UMtOm191i9aU7MWMIqgIt+i 2e96Mg==
+; resign=20460416024207
+119r.subtree2. 86400 IN A 192.0.2.1
+119r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . IU9wuoC0CDxaBfN1HGIAZh3pC6ld8UPeHGkVrUhe+PJbPw2ELLvYue+1 kw5ObQ1/sijjWZoD/N0xOt621jCSZfRYNDXutYY1QxffTAYwR2K4/8gl m2qFiq+GHyLTFhFej7m2ZW2wXSjmLtcDi/AEOg0ED3llb/IOzgXjn5ja eMhb3HA9likWIv6aK1lOq+7dwDApJNRmo+7haRLeBecV5HOP/0Y2EGrn POHfogNJyVPTGazoinlEmeOSRQ70u6GD1foOk7j3P21RjT2MM4G6NCYu JKwI3YjWhtnJt1W07bATknoYoBGgT7Q281waUZ30nDuM4nLaOCG/Ry7a BUbrqA==
+; resign=20460416024207
+119r.subtree2. 86400 IN NSEC 11r.subtree2. A RRSIG NSEC
+119r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . rcdQ1ziRoRpysd8OMNH0Fn4nmDBUcPHSpe5gltLYYZblPRFU7oQrsvmi OWhl4OrIiyXvzkIWmUwt4V+THLI1UJfoAQQB7L3MK6m+81jTgLQYXK/E tgLaZynLBZN12M+24PV4PKrNqNH5qfEXolxQBcbNsYrOwdapEUalg1Nu Ge0MECjpNbtVYAwZNAtuzR+MIVmDASohxKX0aL2IYERvf3oi/m+bUv8Z VImvX6QdTw2ROFiuh5Q/r13ZbrdYG6gclt/xv+OzErbvnZH9m4dpFjXk H6/3A24Z04GBMaS32y1u7TO6Vdr3OsMiMweEXXKG1WFq7a4re663DhE4 Z/VGlw==
+; resign=20460416024207
+11r.subtree2. 86400 IN A 192.0.2.1
+11r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . eFgY0mGVLLbLvDn9QvJ6Nnxp+zL1sggZhbFlIisWv75nY/5YI3TZGq4O gRwD/1TpUr1/VI99rUuKYTb30C/pFmOo79tUxuvREp5NlWzuv7sE6tWe rxmtIpSH1vQMbZkP28it4C1JW3vC4MrqhoIQnHeIDkutet9rCh/1xoa8 22c7Uhj2MsuAesVhQRJxRj/fi8moNVOS8f0d5dgqnJ2MikshkyoziJgo udYxlnQMurbqFYi4isFGujwZnOdgQNJ/ccf81JRCRKLoCGj3uTgCNI8Z MxcweQsWD/mwk83VmiyQpT2PCSwKHfSoppNi9cuRC868OfKOTOc3DllE uHHShw==
+; resign=20460416024207
+11r.subtree2. 86400 IN NSEC 120r.subtree2. A RRSIG NSEC
+11r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . OaQS/m+fnOUyNf7JUfUFaGBQJ30+qX+g/jZc5mN/Zm5RSmyobvpZepbw dWttsrQnaEA4glDvgde+au1hf5I4zXOeav+sFZa3JE6JqEUNpkrhTjEo bvYoS2myywt6987D3IZpmDysdCWs/kQZyS4hR+TG5zVagFa7ojXUuRtz 2y1Z925/7EPLWi3W5gKwlyQLRoA3M/OaGOFBDOEY/qlGT15HaVo/gB8X K4dvzpsIWZfgS517U2eHQWEoPs7+xnU1ifii2HsEc5XuAjdodWT5gCuR 4l2iS9JzKt9snfrps0oSI3feDLDrXpJywFZQWMwu6cHh5YrcmnuNc2KN dkvtKQ==
+; resign=20460416024207
+120r.subtree2. 86400 IN A 192.0.2.1
+120r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . sh22Z4R/Ui5KsGXDxWZmwaxBarP5topizqVI68KtI0WqWu/jerkmPiI/ SQ9AKpoERv/sALeoS7uO4eJBWAW7zgPh9XiuD2NtDG3rKW2zWcw2XKvu GHWduKuy/aB6G6eUUFwXsY62sXQTV5rLHhEQ9U39x9+M4FY10RLjMGkm qIKJXyc3IV4T4GsO9BDtnK5nfd0llyOYrHyV2prGrJy2e20u00XK7jMD KxAt4ET1vlcdgvCmNXLkuRVJgA3oIAHj2l0R+H4Z46NZFsAEtNS6eejy i4SAAEXHeX9p4ZQYVwAADMOrJI9xl/iYy+Arsn/ZGsfPa9Y5g2hgQ6Ic z4DyGw==
+; resign=20460416024207
+120r.subtree2. 86400 IN NSEC 121r.subtree2. A RRSIG NSEC
+120r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . HfhZ5uCo72oXqj4Gr6jsTLPR9ZnXoYvLwmDPCBb5+ILw1jWzhaJdSPvg 2Q+3C9DGvQhj1UykKzjYuoLU0Oglfn22RB9zcJ3SkuBRORO/PDzociwu TbSFzdMYQW/F7bBaImHQ/hBrZ+g515pYUF048KgO1SySr0Gcu/d3JXnU A7wTdOi8b7LqSHjHBBLxjKfR9QCE/Bqk5XHO89AiS2AsALGSBB4JPNfc nZxtDzX7KAqNf5ttPdrp4j7Mo752nj56wf/q4LWmOZOE4MMDHdLaOFiT jo/Syo192MH3jiTp7gd1w//MXwd6UQ5I/4pQ8X0Lmt9fxyqyN8Vrue5d jBIhFg==
+; resign=20460416024207
+116r.subtree2. 86400 IN A 192.0.2.1
+116r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . O0oUTgppI/Cs1Yy28L0iThbZ+kKNbD3k5m8Y+VFb76tJLMAGe8zxMgCE Qta2kIAGWfTX3GW9/POApn7R2N1JYl19TGWGHw8YU1HJnn25VwRs9kNf B6rujBxFY8erychMRuxX55I3KR6JGyKlYdXNKbECaPS2nG+ctIa1oGfD HxYbivqoTsJIUnB0LapVJYfdR30/UOABIq+S2VSncdnXCUzMdf6zBwOM ohXLwZtuBtQg+ZResG0ELYu5VLFlCzJ/z7D8KlV0S1wRkyvR8t5+lEs2 LD2OKlC+ap6n1aK3AhIAmNeVXTooCR+9rG7XqJ05kuo3j3S/Z7G32oi4 tLNJOA==
+; resign=20460416024207
+116r.subtree2. 86400 IN NSEC 117r.subtree2. A RRSIG NSEC
+116r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . CbWdqSUtXErQ00EU6Xr13vgGvgD5iZBsj2cwNYuPfMmsCkNMJJAgVMDg cjtHMD0qbDy+ETew1BRFjHc7SOFSuaHT8oq0rGkHxfXu9vRhZUfD//Ea qKCUDjoUPpPWeLoo1z6Dr/iJs5ZZxs2vfo5Bog8nxsPUdzAFfvU5jS9S PylFAYVpjpBhNfXvMVcPLnIhFSskuvc2O29HuI9QPCkrGiTx0S5h7jP/ O9noYtKNT7NOY6jf0FRSjIsqyraoMa+H4/kbPZR/bDpDG3/XdIBEgagp a8ezUQ9PYsS/HoB5+lZBZz+UROezw9eZ+OmMjBAUb1kWjEkvPcHXnVRF 8TzpfA==
+; resign=20460416024207
+122r.subtree2. 86400 IN A 192.0.2.1
+122r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . NB5NXBp0OPis8JwfJq6jZL8A5c4OrObjj5UhXHmfu3QnRNG77B8FWwe8 v8pm9bRUgpbEGeQNLf6CFx5LbRNSQBoLl32Sp4ydaNtVNikU8Ob/B7ek rvX4NTl5kh/rEbbX1BINXmKW7WKAE4Qjbl9ydjrJ1FmsVZHnnnpSG+Tq 40ABYF9hKp4uH2ngc9wAuAFMXCpwODcm3ZvDgMGxGRESEbZp0ydJnoY+ SpRNnlY25oKkBDP4KNOU8Z5mRlEtjch0l9tDgUXsuB/OTRGf2wGwGbSJ iC22Mafk1BPRih8Dtybp1wwHdLEf3Uh6G9maHspDGHL0SoCoC20pDH0p 4VPfXw==
+; resign=20460416024207
+122r.subtree2. 86400 IN NSEC 123r.subtree2. A RRSIG NSEC
+122r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . Q+RYhLVqKtiZG2gfNA5JJWs6UQHRD67thOVMP8kfXptrzCJ3zLDo4Ffw IFlkPM6BtBUI51fqnEL2Qjb5nXA1bX2p6IWOrINpPkSrhLXB4p66rNyw HyZXum6tKt6/4NMpyRPx4V0sU/2Z098s28bHo8AA7V4goC0m3NUr+JUn P47LYmK/cQ8xO0QFSTlfWOE2TC4kCY5vQju+OdfgRXPGFp2IMNUZs4jG 3snRf+xDjEGz4D2LyEHBu6YfEaaNvZGIR19uwGe8ATcINKD6hhHDZj4Q pIYzkvi3OocsZcu+dKhRE0Uq48S4mwq//YAfIBRRoiEXeYhqG6/KSIba DFR7+w==
+; resign=20460416024207
+123r.subtree2. 86400 IN A 192.0.2.1
+123r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . GndMmZXvK5RaihISXg8hCnuN+mkkP+YBlvZYTkB1L75ThSdhOzry+DcW Q2YiB5y2vfQceJ/7SiCCpYyOdhtlmm4kBBzEZNHkq5SHzFydYJ+RxU84 rbG6Zoa+QHNiL3W2EqsvtRdZSYmO6I3xTtpmfn0zGiWsXRpgRv+u+6Dr yhQ16FUHTKAYrh2/PReH/Mf13QnIPPMaguJ4HGM3YfOikrDPIEwx5Lmm JgAsHpSNGvgLgLrc8rew9C1DymzsXY7aa8rAMXXBOtvp5bqPOblxSQ9d 3JUXDRZPQYr0DXXNg9j5+FLX/JcPoCiFLr7OKVO/XxgIRZMYPI9pbZbX ZXdPog==
+; resign=20460416024207
+123r.subtree2. 86400 IN NSEC 124r.subtree2. A RRSIG NSEC
+123r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . ixCP9RE3d7Ha9aOp5SYR4JZGtUe5cm9w1NWDZWhjXuvMLFnbKzICYgbK +eEAK3HFzpcNraSUUQnZ9zrUa5tZJedqRE53JCht05gDWqOwV33qbg5q Owp9xfXhJRG7bQxxwHV8AwMBDsPe6+Ann8jDUzXKlGZUEMTRdnemd9bI JavE4R22mmUZalElWTUtOki9VdLlg+8WM+38/rE4IG+q4LP/rv8+8lrR AdUTPwHH09e4sRe24zowxIQUmdOkSMP+pXH6H6huIXwnQHjMInO557JQ sxu1jLgJa9sngEpV66d8LJ4R4HVI8WpXNoCr+YX6vf6Uru570idlTnNS QkUzkQ==
+; resign=20460416024207
+124r.subtree2. 86400 IN A 192.0.2.1
+124r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . XolYJ3fJxqmokb/kRF8S8moO3lo7bV8qA24kqaB/B2jXGlvuPYAhIYNJ sifNdJIW1Vet9LmRnb4H3LmojrtiWT4NkFfSoiZVISpCQw0yUXt/Etm7 7zS7HyFp1Hn8Oedhr1wQOeqHl0sRKGoTiZXXHcR3+b9LaDyivVt1T+On JCP7OV3uctr/FXqB8LFNsCNLyNTk99fz26qQTgGGXu2EiYrApUfoG2pu ERE/sMDZO6pd4Y8I58mu7wVihEFiSqQGa3uS+VJwnCgQWArvcAF6vcbv 7T4EIhFZ7b/8JQhRw/R6UlDP5JxQhhZezTw/ERMUMJv8KhL02VlsCFGr bvTDFQ==
+; resign=20460416024207
+124r.subtree2. 86400 IN NSEC 125r.subtree2. A RRSIG NSEC
+124r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . tO74Eo4FdyD/rOtjVjrfVxEe85sHbjlA0sKbvD8iLBs4J5lN61JtnZcy LR8K+/QXx8mTlVdIPT+AYzDUhzhdCtZp+4gNH7sM6WhfglOK1IHr4Hqn Bij6d4HoDvzqpgcczekMiPHl1CCztvzzdt/GujwtHOVmyTTQJTAL0lta vxEbQ5tsVkHjM8zVioEm8tH6H2CSZJSGtBCyHVhp40Bzi+D2hwAtwNGk Iql31PYVaeJj7KXM2oKYuSQHFmkvshwUk3EYstIVEc0ykBKHc922T9Qu I7a6//m3u+Y4k3VyoKlYNSVfNiih1V6pBT4VqUHpa0EYfmsJVR29iByd KuwJ8g==
+; resign=20460416024207
+subtree1. 86400 IN A 192.0.2.1
+subtree1. 86400 IN RRSIG A 8 1 86400 20460416024207 20180815062314 48409 . SPHvBQOqg5nWHvEkJvt5jcV3/glfVA/b6wI2gkPNgcXkoMAzBfzCa95a fG3PCJS/9sAQAgr6W7k5FiQq/PaCt1jMZBS3z+2zWsNdGOAGdKz//Sdy y8YHxI20Uroqntvm0+Cu1p4HMRZd7QyBOxJJKA82mCLkwmRrSmwP/tVf qFE8HU+kkloSbidPwmp8nmYXYjByANHQCRBY6xkV6sMK71X+/eYzBlFT uxPS4aLHVoOTS5cwdxI7LXHxlW22J7Oe98vom2Bf6kWHd1MGLYvdp1fP D3bRMU5HCdktc+4Tl+nRo/RivUhYdcQQXOZWEx1CY4fCWssR683IlcOM nLwV+g==
+; resign=20460416024207
+subtree1. 86400 IN TXT "txt exists"
+subtree1. 86400 IN RRSIG TXT 8 1 86400 20460416024207 20180815062314 48409 . Eq+g8WC5BonimGjapGkBlLxjpXeRI20dDx6l3e3iyL5WEzZF2jP5ERps IFD9q4h4SPizF8iu/5Rwkfvm4IxJ5aT+8Mrarsk0c1HdtNJOo0AHT2k2 KllWe8T7e4QD+nZ0nx6Qwml+AaPj7PdcAKtEKLXCJxnubQrPjLfn/cYf +lTep5kgOUfEcHK/8kxor5Z6OfOCnE3jBrfsiDXPHnoO6JBbonNTnRft VWRTnyV+kSnq3UmwU6diuhiPJpezZJhYcn3ycwTgr+1WY5na/hOYOBTD gDrf/slbSnGyzkEoedln14DROa+EsNUyNKMfkXzBgx52w4rop2hR9UOm 3Nfuiw==
+; resign=20460416024207
+subtree1. 86400 IN NSEC b.subtree1. A TXT RRSIG NSEC
+subtree1. 86400 IN RRSIG NSEC 8 1 86400 20460416024207 20180815062314 48409 . KONcjoRpLJQHvahE4t0Q5UlkxkQv3DT62MbAbR8xIDigv9x7K8LqrpxT 3vC6aoHLn2ERJAQAG6sWj2vizmHdo0ND5flI1GbFAJQAzELlxHnbl7aS siQRIdwxpAnkCV48jjhcPkNpOWDHmUl8U+OVChTOWaRgChTMsDxWZvOC zbO4xzvHECjfw6iZGESSCLnQz7/FVQEG9B78nigXkx3QutFlvHKjAr7G tbse6i6CfQQWD3HUxlXOpYR5ZyUNXNwEQQXvKvv8o3B9b1dXhVgNpP3s Qulk3xxuKcbeZlvfOr2vawfY97VQ43mJZ8DVs/IXYDj1xQIDvUaZ1eFm mAi9Pg==
+; resign=20460416024207
+b.subtree1. 86400 IN A 192.0.2.2
+b.subtree1. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . iZZnfKUQIy6LbOBnjzbnKgpbAuolfWnhyiVKRDC+u6iNMsX/g/YQ6eDp sfaORTwV9yvVwYAXfHk1T+cFcguF/uM+jsVeXKWJTiMb8UDpNGzM0h4L 3ZAZv7v5FyMf/JNpg87JwyWwO3HU0BHfiCS5S5X6yCdEdbKyXrUcUgi3 X2DA6jm2GhPFsycNQndc6uwEgTZOKE7cxfVd/rlYhC1gYMafyu6g+NZY WmFQ5IHGFSwGJiweVQoIsQfB410WH4OpqtQUhwTbnh4qCnHqwnUZDaYA bjL3jJbOlieakQ6XW6h8ehr2+on7fozcdAuUee8OKutiDn4eBhZiRC5o aIdkFw==
+; resign=20460416024207
+b.subtree1. 86400 IN TXT "txt exists"
+b.subtree1. 86400 IN RRSIG TXT 8 2 86400 20460416024207 20180815062314 48409 . XdoE/QvnjQ8FEwSKG9CuqQ2TdxGdcMjWLGOfIgOoHOEPoGZD+TAfITw6 NYICtiujV4/9XRTQ8h63nVwhUjVdsGO5D8JLPqca/7fOdLyQ42hNnAmf t2KawvzqC1Y9Z7yMrcW+QC4rT1GEEkQMu59F35tJAsWODMZAZXDL28z/ HVXcxTDU+bcP95OYEGhnknFqYjzdk11zWT3PaA2RPt0GlDh2WATCtEc7 nr2ZhsbYyyzlY1glQhXPpjnpBcZXFP01wMhKcNH/vcXZF0AIi6N6nIXJ TO6u/fsG2RflsdpiBym98ASuZXA1nGZzMQ6nO4IuWafaLRUQ1feBAJLH lst32w==
+; resign=20460416024207
+b.subtree1. 86400 IN NSEC a.b.subtree1. A TXT RRSIG NSEC
+b.subtree1. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . axjtB8r8jja6iKQfdd4Qt6aaobdM8kpXLYAeJg+R8BXv7D+2Q5ZeCikc gaYaomzhSTqA7cdyv3ov0W6T8yZZ3rkPLkN6rwVNHf7Lu/cbF7q8UuaP O7pyXJDxp953/T+i+hJ6Lq7HV+Be6K0Vgq0+w0xe5BoTNVcBRQFu3QN1 Nu2m8ZsVhouM0aD9QDs/PqrCPktLL57xLVMoU3SaVhbQdV8VYZy+t646 zkDMQU7ZgvnFxFA+qyvVM2n8TRYImr4xzrIcOncz/td+HCni/EbCS2by KpE/xHQWthuSbiiUMXC6Go0yN5WKvOO3Ef4c6Jejw04XCg7XxlMmIDTa /KcznQ==
+; resign=20460416024207
+126r.subtree2. 86400 IN A 192.0.2.1
+126r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . Y+oDiMv6emPFsvhyVOFd5w5OdHxWAcR7b8P6fHZEKWrgLspEBlkJJbCT Jg/0D0JgM2tSVw2G8qS8MdMEOrgrWukfy2H4gQn2GXd9oX+Q/SaYCxVZ AnnbX5duHLYKRUJ7aQ5S0BLUdqsQNzfjluNmAJAmrmqB/4qq3LqiOt4w rPe2NgsCDVx83d7lHEeLc9WY2iRHN6XEBVo0JuCH+n0qMItmnXAW2yRF 53tw9E3xzV7Ql8mZ8HfYkRxvs7LUnIBnWm4WTPxNFgW6sAuaovEHrCj+ S9edUSrKtFexYoj5NdYccEz2mVEnUgVkHbBGXBdplx3eiOAuH06S3+pn LAk2WQ==
+; resign=20460416024207
+126r.subtree2. 86400 IN NSEC 127r.subtree2. A RRSIG NSEC
+126r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . B4/GyQfnLIrgknDrWgMrRO++hKv8z1pFd5SovWqOXgfu3/pQ9F06vfL/ oo/w7OyQes22whJqZ5YHt7vj/ZcRQdzFyVUcIpAxCXV5vgFHhQtX4ctw XhW/HZFNeVEeJGjzVhOaSI92mACBdzMuywuqmFtRW6Flf7YyUZMchZOv KtR+SlKtXXjxtc4bIABPO7pf0jFBup42X6pv8KORhDSEq1gptuX7MrCE ZAT/6n2yk+2ilK+Gz5dKgxkwqKLg297jB1G3br/ja0dM5KPxXQxH6joH GmfgRn0YKOzKV97PklDjO36+eRSOXw+voQmSnAS0eOXCb3zvqevYdAg6 bXv+ug==
+; resign=20460416024207
+127r.subtree2. 86400 IN A 192.0.2.1
+127r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . bZQ3ozEF0PcebMQWveJURSLH/8S8Abntn84pBAuG1kCzElCGrNPXQg+m l5Oh0dM0cMoZUYOgpECLR3mKE0MOvZfgGEgRFHHJEb4M0PipuLn1GfWD jGaAKQ3pMAOptg85aRleMgcHKWaAmTxV2C9TftEpul5o1T37Pumybe8t F+LS+5KlSBxOmNpQzXDz6Ladd8FIzqeUpA/ARQK/adt/+L3fIbuQ40M/ RGIRBrjQ4kz2YJuVqcvhNcdQitJNhXdRILNYjGKvuj4ZHFp6KXWoRTzL x6S+PYH7shrIkTqVeCziDy3LVtAaKgto59Kbw8cq0m5Yldyl+z4WQIq0 t1guyQ==
+; resign=20460416024207
+127r.subtree2. 86400 IN NSEC 128r.subtree2. A RRSIG NSEC
+127r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . uKm1r0A0BuyTRsYGjGoDDGcNld1VXSck076HxHJ7mQNusuKQZ5lfNtRE b2/FjlXukHQyXEkfsQc5BJvUjL5WnnPUSDBTnPercSCf6lkB9PPWOeJT EuOHGjCZC+wCYSsuz3JIaEhHwsA8JE3Ufj4Ld1S5FLyt+Y/smxpKg+Ca Nj2Um+sX5H6OkgXJPHnQ1s7rF+fTuYbkz/iiRU0CnDc6sfyJJjoDF2/9 ahCnNTqdxUjSK00Mg1flt3+sJCJ6tHjYdYgyANUKc65ZusPUKdGPJM17 +oxSrzE5+biVZllfYRnDYopeayciU5CuyUNl7Swr6x0EI9TA5t/KVD4m F/wEtg==
+; resign=20460416024207
+128r.subtree2. 86400 IN A 192.0.2.1
+128r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . b7G4uESmTYUIboJyhjzJUIGJyzfwOMgtQRdhk3+hGC6p0lE9QIAHoTta bUk5VGHvhg1FTE/RaNelXK3z2WmsaHtZEtEM6IE3j/9w2d1OCX/K6esG N0dLxynR7w8ZWTTC+5HZTgNURHD25Z0gMWBkiFv28Qwr1zGPhURUG5JA s8dZhsSpA21I3bkNaz5AJDMFxTyUTtdXG5jc9SRFX3jgPUCzsyNjf5W4 H2c+4opkhGcydcUPcsc6tbocUGzXhQU83Im/8Updz0f7GY7uzdaDZoeW Fz6AveZ4EbTmzWRXSKm/EEJqEOyy0xxKAY+CHocz5J3QZfbNjbEN27aC xhzsIg==
+; resign=20460416024207
+128r.subtree2. 86400 IN NSEC 129r.subtree2. A RRSIG NSEC
+128r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . eJikYm6Eb+bJpCxqIgiOA66w+mJNtd0MeA+oXNgl5JZVHuBLx88g6UhL 6nxC1RFY86sujHTdWnXR8KeHUFASsyYVzY/KQbEeOik7oTLcXZp75s6X /22WIxq2ahvRAXm/PCB7UEiZb6HJNhdU0vTafcUznYahO7FbE0Nw9fDD 0MPgOdRl1wtApItW1ZG6hUq/UYUKCTQHS8jJY5cidOg359mQB+Ik/L2M HKpk3j8bTxbHE2NVBIoScDQT5xqd8rsQAbBrtAVBBvIVcqgrd1fabr0s HKWT3+21ucs+DLdsFiidV48rRuGAJIrYPsteDLOgtZRchZxoUGOpHWPJ YVGs9w==
+; resign=20460416024207
+129r.subtree2. 86400 IN A 192.0.2.1
+129r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . xvPIWkuZ/zQGallRWH2I0V4qyV2cN0a/A9j/IGhnrflC58PKTsjkDu8x 6qemDbBM9Xo2nkdI3G7YZZjB+fZ9SSr5SuSMtCvmoUQOWjx36x8ZBa3S Z97oOOptOJPQLWYK957QuwgEtS1/SiRMZPrXFoMWpPIBINTcHPrXTYNg 1jgoIxPsXjinZTuO7VXPyRjlhhK0Cf27yomKku3zBkrwDqBH8FpKajD7 zq0uFztSY1MkpVgvfmT+6mxuVPiuIB39h/A7k6/sV+5G6Yw0qaL/hzER 6TYIs9cFw2C9qgLHeLcPGEnFhCwgEuk3wCYtXJtzCBqq4nXRm6OKTypP E9kBVw==
+; resign=20460416024207
+129r.subtree2. 86400 IN NSEC 12r.subtree2. A RRSIG NSEC
+129r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . g8Ym8RVSbxNVY8D4c4iNmHRgm58PPUE0JBaapvJTrAtt9Zj4ho/QYgnH iJGvNzIdEySGYD86aGvWlWgXKdsubnRCihSd88CuRDK2CXuYE2Jw3sGN SFRBkY9hOH4BZ0Bms95ZZCmjCxzI+6jMfkwuKGhI7K23vIg3oVpE/yHV 5HKVs5WJr6K1gMQOF8XrwlsJbawHYNsOOMuG5Y3NZWUUW+3L0zwxMMK2 d03f1AJpS1K6lqfw08FvhYgAhFoVVx8unB18UqEW+L8x0a716o27kACG 4fqdWR8TKhSG+/i/HVMFulBaWqGKwi1g4UnM825aEQtVtoOUnMYHOvmQ u86UcA==
+; resign=20460416024207
+12r.subtree2. 86400 IN A 192.0.2.1
+12r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . RQTtb1xIPxf3rvjpYYw0q9RcPiRPlx+uXg/1O0SNrgL8sxb+QZuBjEjz mLgOioX+g1zheFDbftKswUTb3F1vyKukW/Y62jiClb85lezH8EjTcHAQ n47ZSUnNGA7jFRMkrOc9i2hRo3H8DkMTFa/d5RFA4ZvFe3/jj4zWJ3YI aXWW7qUgDutPnrJtcPixOAD//KK4uGRxKwgeo1j1E6wkjyht3A09klN/ hZtT7qN3xruTu0mF3WmX/9HEOQhU4wswVHKHTGOMwh9h11qQsEu6UBgZ PDbAIZytU4m5ZStKg2QqjruNlS0lU3g6VBpOQ0RlZpzssPkxyRdQTCCq c3FEBw==
+; resign=20460416024207
+12r.subtree2. 86400 IN NSEC 130r.subtree2. A RRSIG NSEC
+12r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . KZEpHmob+s8a7FK1vLvmKWB3SWcmUP+tWmMP2QxeeLjHY+hZKU01F4tV FlXAUqLpmjuM2hQPfhPFqhw+Dpgvh4VUHmwO867t2OE82TNGTb63PDAm Ri0zsb+IObCIG5n+pd0mhV1gn77KSA72Qf++5SD1TqQ4b3zu554nzsig 3uqkpXbzYGe65GY6yVOW5nRsdo6qOMfcZIRFyPCSb5xUg7u/OaoOTV0C BaYx1o0dpbz5/pfriBPHPHkL6SXnOdzI70nj5m0ZfRQpKMgLOP+UW9bf +pPD9NHjD+UEs5LBQgWjXwymgLy+GvoCWURlWaHfDvgHT9fmeh2PlTUP 2ExVyA==
+; resign=20460416024207
+130r.subtree2. 86400 IN A 192.0.2.1
+130r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . ZYhlWkQY1P62dVBDxos+9jRishojmYY/0wNvx4Zj2bHJIpuxAe6xvIrt YWlj58GQYlfB85sLp8K4/zwd+fahEjy1aZrmmfJJKVPLnQrUcYQBt9i1 RbTjR1smcSVoiIXu4FdDanbJc7sIuUpQOp3C27PImyfZa5qUMCnAxcLL SGhdvFLbii/ALAC5OKVxEqjAYtlJ7NuYZlxa/ZhruHnDRYBhh2QXSatx M19Mi9QboBMEd79U5ym2nK6HX6AcaFdimpK5Q6F4BWskUY+Qls5Y0PQH 5TPG2LiY998Pi5Pol+nnsfKMLJ+yX6bELy6AHeRHm92m19iu5Cbzg9SY wfRUTg==
+; resign=20460416024207
+130r.subtree2. 86400 IN NSEC 131r.subtree2. A RRSIG NSEC
+130r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . J+/kpBOiixw9TPfTRZXv8lkVS75TRukn57NKGPmp85uA6uGTsmAr+uMG gtAAqkxmkz4IeF++sjjaKxfK3afX+DrA+9ROUXqLeRBaut/abMocM5IK hJlMSweF6JLDSVkqFZ2lu/1yvTRTnIkL0XACrNfvbYfCDFAD8Rn3vXBB MkpsbfQ4mJVruag+OgP3lOyKDZPjMbjPR3l+rD5ywerfqfda744sWtRW A6xGpluhgUcJJzPvHGxrdpaDxKyJjWCN+JcP4yjfNrXX1YYJ8XZjErHr 5UHUMRZqEOxxNt8N7JdzHMieCRVrcQlB/oFMWZIoeiVVDe206seaV5cX 6hur1A==
+; resign=20460416024207
+131r.subtree2. 86400 IN A 192.0.2.1
+131r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . yDl5kzqQVeOBQANC2Hsb6WmN2W+Qul8r1L8LzquzWwYsjzYQOMeEKl7S ftHZSmLeVmEmARugRJxABJdwjzqfbOwHs0wAzKMrjp6W5naY3PH2Hehl vsi9nx7SHb2Q1bBMH4+OLfHfhG+E3tN5pJ/djdN2ksng+O0gSTAkYa1+ ym31BmIrtEBLUwLUUUvq6JWeU3Tw04JKeI0YXDL+Ve4Qjjwgrl/WhiId VGXRKgpGHy+GcB4pI/lJBpkQUWhjmd5IFkGbEImb1LDmAxsEmpLxTSEr dOlY57azlHqOfSVdSZVSiaYV/iCEvHW2a0+6hia3cFkcXBPzi16GiMEh CdbeNA==
+; resign=20460416024207
+131r.subtree2. 86400 IN NSEC 132r.subtree2. A RRSIG NSEC
+131r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . h9PV1OZUSaDHg6esVRA1903+gvl1LjuL9uqnmwfBwno/AeyGlG3H/UvD mGP0ktjftNcNdxLXOsKQ/bgoFT6771AtwpTqdBwcO0BPZwabh2tgUhLY UoMY/LufRyLs/3niI0rhBLURVvkG34aUJ9SIYa2vvxPZuaZevR8LrSrY etbkXWKiiCMeFb8y26xFjo/nYsbOoVs4RZr+24q8zSfEXEzeCPqe2uj4 NZtKOuSD14zP1qiWczlK3xOOFA9lU3MhOpyxXBv5mgVq72Q5CluugN48 9Jkp1bwZj3FPBRDdBJWkvJQhc3X1cdE1YQ1uLcvHyizdH0Cn3YqsRKh3 RlkIMw==
+; resign=20460416024207
+132r.subtree2. 86400 IN A 192.0.2.1
+132r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . bSSIZRLnCDmGki3LVPFKkSG7FMHn7NUEbIObjHsKYRoBDMu6Enjrd+1z Qrt3mGkQg9vFVsFrcVTKPn+7Sq8Bjuur9knI9XX33tOszxWUFBk+pdAl tVtFLGQ9arB+JB8sISnEZZzD3/LID3XnUwURuemjLjYdzKZ8YZYvUoq9 DQJMZdScCBs3NghCJRcJ+Z+faYaQDepnsznmXfFklVE2ZMFjkejJpJPb qCO2bsPppOI9scQ894SefP72sehSVER/Fq1C6eUZ59sTB68Dd65yS1aJ Ft6WTTqp3pwysKpTpNXpxHCLdarQP28T9aBp8tHUyQu59S0Ir32tosXi iafxpA==
+; resign=20460416024207
+132r.subtree2. 86400 IN NSEC 133r.subtree2. A RRSIG NSEC
+132r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . qY8oCvoTEvFhDw/i0KCNZJvrlj2d39i637X69WOZ9pAHcsgs/BWSoxcR Fg+wjMZ5T/rqVuBmlOZywtwt8W1RZGpqmBzZq6PgkE+QJ3HuI3L8nxgS gkmeNMLqDDOH/Yq64u6F/hsV4GMlqrLdPTSVApkCjAQCeYtbv/vX+LIS X8hKaUjzbjRjKRfV18VwXgHdN8k7CE1TG6c4MN61rDuG50/Bzj4FquSG XhKsznV0qd2MuE/O/Rk0Iezo6QFrqukb9remAz78HfseDp7UxZ3gvCOr 5ZgN4LnXqEW9NbMznyEFqZQi9C2UzcVOHX2WXVWuvphhhcMPor0QfEuy NC6/JQ==
+; resign=20460416024207
+133r.subtree2. 86400 IN A 192.0.2.1
+133r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . k8zlvNtimuoghUWTrivzYIHg2y5nj3zErrgjIza67br+wy6k3SfHCLUm eDBFoMptjFyasoN9lYYDaKFziT/xOK4YaQKlfZrj3RP1AyKHcVBlIeea ZgF5LFHZiX1RtaMs0mnIkRk2B4DbxuljX8fADLsJsmSozR++Fr+nv2wt xXHbtodiyT2lQUJ4A/rx/TMJjHxBmNPGeXOA42KoAV+fbQx5fcYtySsz WBy9KMNylpWl85zqrXAi93shwDVJc7AsOozXNPNQAtw9ivRiVKzJp/Ya AQanbB+t0GbuwJUsL+Iz1wdze1BdLzo9yi5DUqAb2FEhyRfcgHywpdXA 4NNT0g==
+; resign=20460416024207
+133r.subtree2. 86400 IN NSEC 134r.subtree2. A RRSIG NSEC
+133r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . r8Eu/Q4l9RjfZ7R9vBJ9h048xdZS+P7Bs5hrY/++5bmE6+nCBkGXiK6f M+iBCzMOAIjgCkNReix7a78+MpRoQkUJ+UiMB3KIuOfsRWUqAEQwm6Ss 3XuGvDLPG01iBPL3nY38XfORJT3e9TRXml0WsmoFOWLcJGmgaOYC9m+z 8RERNtyA4S6YhUGyVdTGZWcIDF9uQXzHaEV3rnYLJ4keayYr1Wz/8y+g TKHPqO4vpaj/ta6umfaFlsBh+ij+73mdnwPLORbNfjoelqTvac9ysSIE MittrRdOtebOa1bSnuMixp/M9JKDcVon7ng9YQ96koKyQAulMOZVukoH So9Eag==
+; resign=20460416024207
+134r.subtree2. 86400 IN A 192.0.2.1
+134r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . s7kYOZs5grqw/3bmKBJn53eCs5IfIwXHS2LAjRcZEt2NpfrFZstYLOR5 dGJaRAFBHgh0n+7d/Tk/iEhvHo7eA6AJflqhGAYaoe8jcGA+bheI/lXH nFA/2Ct7pE4LPF4kgxrg8GdOnAq/lA7mG4BU7PDxNHFCbBjJRrZAtbZt rPszgHcRty0i2FOmL3LsUlRJYJZaNLxw297zXEouQ4S9URMsqiFL4QBD ALDOUtEA5t30+0DfSIxbxgIv5ELZ1y8FN0DW7o0AXOlmVj7vcWQ+65/F w1UsIbAYmoMxd3GovKTjAl2VT4uZ8pSWn21YZSm+mxwEhj/KlXi3vyZP 5F4kJw==
+; resign=20460416024207
+134r.subtree2. 86400 IN NSEC 135r.subtree2. A RRSIG NSEC
+134r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . nn23Ag8vjOKtaGMdeng/lUWZgtPNjQh52KoiIKOHNjcwRPcg/ABw4766 x/DYK5A1VzCAHRiXHxjAQDCdESbrZDURPiVWJUsAVKYHegkuET8ehmSp v7o+l7YhJzLqnwvbKHNMnXq78j98FGt7PTroughRV3FY0OJswKuxM0eW QnUAWn/126Z4m38hw8Ec2PtTCxS5Q4g4RefL7QEN+7wrZBMaYKMYL+wW 78RLqWMhGomI94QUNG4bhLSZhl5M3amVnljugdNOT4WA5Lvy15fQ5yfM Y1Dhj1l6vR0WN1S97mCPb0vEJYnNkW2XQZ+edR46FzV5dlIzhZLBKx06 18aLmg==
+; resign=20460416024207
+135r.subtree2. 86400 IN A 192.0.2.1
+135r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . mEUP8TKOZC+6X3NmaRFiczENU9+KKIalrmRD3fgkAIvogcDUiNkwo/Ii +PiHdJ5fJubznQyo/dbMep44pPWe7ONAv3+dW50ibI63UNRzcJ8T8d5W FsZQ7FeNNS5QPQe4TMacttc5sj+09IMgCADDa+TP1hgEMfFOVcICacbS /ZcZ1zol82sbJIf6qVW7oKSGP9WGs38gaNH/DP+i9qKGycMFUK5L4oa/ lKXO2xgiOaBsC6s1VpyNbAkkk3xFEfqR4XOYMdyKSUApqGFubuLdocn+ KiMg3FonJt2oH2rZPEeubyanbKK3+gHvPjHAzH+FpTl4SJoBNKg7oqon DTwgUw==
+; resign=20460416024207
+135r.subtree2. 86400 IN NSEC 136r.subtree2. A RRSIG NSEC
+135r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . FEoC0LiOaR55lIqMML0Hb+Q5vkqLdpJTAFK2zKbOntA0uSNPDyF1+iO6 8c+Si9E1QeteSUa15I6tnxE06g3uUEkGp0+uxHlruYKaK/6UdI6cJBBC UPxBqMqJydDcPKPJdWsmiOp3rRjPdwbEcLPtUqclLWr7FgDxpvor+3lV b8Cmogud5PmTN7IAMdo0hXljS/+GU9K2VERd/6z55Yk1jcQI5ZDSooa1 oY0HtssSg95QKn0VFw6PfZisDAgMsXTd1qGaomI48q4M1Nozp3XIHhaD YYGu49N26jkG+WfQXzC9ND0r0YpR8/FKhDo5VHryUJoDxG5F3CyN6f32 S7PSlQ==
+; resign=20460416024207
+136r.subtree2. 86400 IN A 192.0.2.1
+136r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . UVkngBEk4LZEtH7qI6nNxKJUoiWD7maltLy8h78nxEndS6mWqW7xq4GP E2w1I0PEaZV8Lzss2y2Hnl36uJKLgx3iqL/r1ycRBZgniEbfMxe3K56b i2qsViHKDBqKxmaOWsAEd0YoYJyiXYQhGZGbJFrDav6kCMrz7TMgCx5r t7Ng5XCsW4XfEqT2AbPTQdaccc/mYoJoNQypAnm0KYLvMtI3K1GJQlJ6 b9pL4ctktvW5+l1qdKUEdQDYgzx6kIb7YrQcB+/Hq6EA+oQMCWclwKos byloRSKgAIJcZNiHiIFHvilqgi+LfCGtvd/VU+M5if/57Ad5IdzIqcBL BmytXA==
+; resign=20460416024207
+136r.subtree2. 86400 IN NSEC 137r.subtree2. A RRSIG NSEC
+136r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . N/CSs1q/X5rVNErYAvM+nB4xBEeS6D/muzFOfp8wT0iooCVL5B4AlasB eu95iD+Yqvj/2UPpTODjDqCwq0GNJMkin0/PakrLPvGVjqaGUTibwa3/ 0uffENpVohWee1G/AmN90qfYMrHdd1LMFmbV1zAlr7/i6TpgGeYgLnyJ kFQN9PvWpHJzgRf6w5Kfy9rAkb+VolLOtaGysjota+FhL+vZdbZExTKf YeoajRvALe+7mdTSJl+fq0CvJmHIMHLZQ53OBrLaSH4ArT5L43Qb0td1 9GFIcRbnMPQxRDGacqTayUtDl707LhoN3Zycn6PCFvgbuBfJZgpnEdfT kwzu8w==
+; resign=20460416024207
+138r.subtree2. 86400 IN A 192.0.2.1
+138r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . dd5AaIiOxGjLALDsWlu35xdOGnzmaqfT7dfUfV7swQEJJCI72xUttN3O bU66tRDNlGyPO9NF5FhGpqtlYde+cmkDsq9VicpbcRFGPzd7/iax9xkG NmRcss1SSqoShfTAobS9bmQNY769p9a29RxogqyW0ENHCuMyNrmnfDCq 2Ps28Mi7h8HhZkaweBq2E+K5jfvvdMpV5S0wGnXRItgsSulMltW0rAys 27cHbxeZruRKWwiF6TvXIRnFKmcDdJaB0wyHmGcbCp8yPP3cs1ucyL8T Jog8I9OODr9bkiNqR8hYe6Yb0Gjos9Jz+8sdg2j4GPTC799E7DQhDmTu P/IwbA==
+; resign=20460416024207
+138r.subtree2. 86400 IN NSEC 139r.subtree2. A RRSIG NSEC
+138r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . sYHaUjamI6bt1N7W4vexUPdzHO5kDj2xuG0E/3ASwpqwkMFdkPNLTKh5 368WZ9Jc7inXp96GY5UroJz+BvRuJQGW48R0XL3IZ6mxX7KIeS9srvxM +tjyc+ub6wrTXtmQLcv61+m0T5CNMmQ7LvwMmxOgtMgGOmBtTZ2sw5S5 3mvkZmtXihMDBnEH1/lJDgu67LtD72ULQLqMofHSjazdNWkxIjRkUQDi UWqQ1RHMf37UK/PA9U/y6x/VXR0IPHNDcEme2gsc8gS3nwbZee+eDyij cIl4l6+4E7ypn5s+PSUaaulzJ5r4SlQvsljyeoHd56X4fDld2X4NSYdJ Vqmt2w==
+; resign=20460416024207
+139r.subtree2. 86400 IN A 192.0.2.1
+139r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . daQs19zKjNtGzUILqvBev3gNBsGYSGPix4XW3KjPjJZRChxJ35FtZJD3 3J7zFUyGmvSMdqeu3SGUZPJQsjPfudn90nBQoixB7P1miaCP29VxUmw5 jhM4AeefB1N16Lu+e+XPWqjCjPmfwiUHvWLq4LSPG8h3vQwMwJqnAMCZ 5503rUtno791CZGGXAxAdJoJrYFoEgaDcdqk++0ls+xJLWgJkK49NW8b si/7eerweQHe6ugYU7jcpy+ZDOabHlmHD4/pg0oL9Iw5H8Ar+CYUhUgN uLjDgQlaw7lWco9vFLr2Aea26J+jOhKSRqLovm8hOl9yFv+M42QbUaHC TmHzGg==
+; resign=20460416024207
+139r.subtree2. 86400 IN NSEC 13r.subtree2. A RRSIG NSEC
+139r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . Dcf7I9Uh4Tbiwhz5s+8VlC1O32GhHbSxDqeiwDrrnxghi3luXUerBWg1 hdb0zNRWDxnKWSryWVf5z2ixnO1DVQqqkI9u822xc0Cg7MhdEKtIHO5o xNDSg538jIbcrpI3yOyyfPoS74n5Rxv4bpbltWTuZIzYm/lbN78t9PKM twTHlVykbw0teKLEIkkRMHrVziwqZ3OO5OYeWsxkaR5gaNgUnCAgg+gS tFAb6I4X6cB+yh1opulG+hEZga81CmgwS0iDBor+vD8kTFqeAnQsHU6C 7mmaqP/gNS+l9plTYs76yR2yCdsDhKulK4BWFTjrCfPVtacJs6mooSg8 hIwgVw==
+; resign=20460416024207
+101r.subtree2. 86400 IN A 192.0.2.1
+101r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . naTWHH2lrB8zSUEbz6CGNZty1Ugf9dIFewyFcZzC305e6XtCPW0JlUPZ 0jInSEJg8dVeVZmWB2/9IaKlCtTCdUw9PL2b6lBNKenQFbb5dtTgZHvL nscMdS5VhTiu82hUNnGOAgvvrPbL6sq48r4kYqon2aE4w6C1S7hiOjGZ Ba4j3lhwLIBVYm2dmn1h3rrr2n9ZJWMDQIjyApx6CrcawFLA9qfyCosC spm2qXEMa6ErnCNjwl/GXsGxW4Q74Kk/xxYEq/xQaudGsHdJfXZ5+7N0 CXcuzfVpXYDkRd+M53g/T/K0ZWhIm3r/wSBj8zkpsJ4k8wUDz0sMG97u iFZ6gg==
+; resign=20460416024207
+101r.subtree2. 86400 IN NSEC 102r.subtree2. A RRSIG NSEC
+101r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . V5zFg8xsuFrlbt67SRtfgtw0twyy+kSd9oLuyRikZ1gIzNwI6Arg9MmN pE29waWsmKEx/JLve2iV906CGdansOw/of71SZilPXH9L+q4w2zCJRkl 8fh3YjAv3B7fulp5UYc075f2vcxqHtqP11b+a7MS1ZaCGA7hfeMqzJez B8zPcxQ5qU35DUYHEfx6ixe91a5sf8t0kOZmliZ0LrXu7JF75x9mfI1Y y1+WWRh4MPBER/4y/CVvQF0Yf75xKdDVRu7nM7OqLzwiZZdFiGIEr6g6 2JCEYhZMdLJ+QIuaEpKF+gz8zfOqgZ4ziXen5o/Ob8OjmxAOI9/A/vGE Dm7sXg==
+; resign=20460416024207
+103r.subtree2. 86400 IN A 192.0.2.1
+103r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . pR8d/NmAtcsBFWTXaqsR5LMSiYHHYlFg7YrMef27Sms3rDDf4xVrFUpp jhBMaz7f7ZRmQ9s9QxMY+Kcgz3/cB6Ic3ku8avkYS1eRhWY0ouY6d+Wr AfK5dplkPq2rZG0q+2TwutSEYC8YbXsEBw0PUgrkJb+TX9PALgN88dXi fOvF4dLw+fP3rdltnWU8ha8EMcz95OtiuiMXD5LKJEs/55e/wdBh3L4U En1F+iBTlewF1a+/1SJ8Bf67HWH2vZUd0YHDNKoLaCfVDa0dFAXZjR/o suYLrC30Asnqvnn30tzoT6HRql9FX4y9a8npbAVGgHcFsnGbm7QGRlfr yPXE9g==
+; resign=20460416024207
+103r.subtree2. 86400 IN NSEC 104r.subtree2. A RRSIG NSEC
+103r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . li/pzRyR5qYV92PvcXGMraDHPpfS0aSwzjZb4b8TykvnDLj1ho0Sc3GP MQi6M7NZ1aqyxwDXlJFGBYOEOybSC/yH8tIqpOZG7cXQm6OOJ8rWVCHX sU0+h1Hxs0oban3jnbflJnqW7OCtOFBxLApqS1AI/Wbu9qStqCUGCyZ1 18j4sewPatQ4fQUcw+nXaiPNV45lKgR35fOfoq6CSKWjecboY9BvAn+w 7PXywU9g6mEfgDw4tIlB9LGtl7MSYagHJnQX8+NWidZyzLHCdhePDYYl 4PfspQ7TCZvsLcerU95ETtp1iLyOYgQNgbobY3i4Ner3yuf7gtrMxHcf 7GbW7g==
+; resign=20460416024207
+125r.subtree2. 86400 IN A 192.0.2.1
+125r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . h5fOzVZEq+smgW8etkQddwgA6/TmQ3CTPHkLng1xY9V0hJai/n58ORk7 nDgpuy1A09tvtRuMolQmQIDUmazniagyWYxvTg+VF/lQXmMASjLWchQH tlKAhmuu1JN1b+exsJn/vn6dZ5E1c13yd6c6GB/emtRyF5fbeHOedInT EbPJxBkhGDo3CQXHDN7Hx/4I2giTQz4jXduj3vt8LcN/JOX2uG2acPgE RRgP2UBb2sjVeOKcHkRQyh8YsUMIMgvfZZOYTJycEm9YlLZpafg/ICJX U6aiAYqp7IYKjU52bGs/vGG1kOMgG73YDDZOkjCV1TVQYOVBz70dYl5y CzXfTQ==
+; resign=20460416024207
+125r.subtree2. 86400 IN NSEC 126r.subtree2. A RRSIG NSEC
+125r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . xk3GwzP9UACMuUs/0waDDlPfeJ7dZyoRHCfVl9EH3FP2ff8H9ttXjZhK HA9uqRPKf9nQZ5SsSIH093JsdKOHTax1E1U0HaN8aUsZ6wffWXED1Sk3 nZ2jKrfFhOvsz0e8BbemHl+Sn4B60O+ie0IEvNX4qKypc4zbZjUXKq4C WDU7+LJilB4OoFOtic81ZRVA6rWVSLIxbehJ7mbaEA0risRAbF5mT6HW 4OPmOZ/NxDG+5JKPuYpos9lnSjNmeUFuBE4i8nfm79Eq9KTak+clNJSZ iXlCY3/OkGSx7Je+fMa+rXxIiULKEopAFVTPCb7TKw2UqVclAAAOwf8L v0Z72g==
+; resign=20460416024207
+140r.subtree2. 86400 IN A 192.0.2.1
+140r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . vPLnzmORrcydMv7m5Qs+8ppHJZSPRHjLMOYISRo7UAsEfCszaaVv4AVo H4hTLrq2H7YbklEI/WsCSCZI+cm1bD83siNoTRgTXorWj7srLKIZ1UAw 32ArfkG9RpWVAt7wmEYirWgIRFejrZSpHdIa9t7sFa75buxueNEhnGi2 gPDBeFJDlfLI+YqZsUmjJWGgM7C/JLhGVzcQCEHppjtLRmjwRVZ7Fwbq v8S+ESjoQCTw9DEYglqYPw8VrXbp5yFlMkq8O3sxC7S1+OP/bn6ipXkx P3L1gKaTfakSM+sc+FwyiNFKI4Cqxu8oIerJxBk+IiOhdi4+drf5PPPD KjH46Q==
+; resign=20460416024207
+140r.subtree2. 86400 IN NSEC 141r.subtree2. A RRSIG NSEC
+140r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . pxg9E6E+3OteP4DSEUmH3dJJIXp0kdLG20xEP35PH9TA3bLgLZs0Y4ny zFDFUiRoesKOmjVithOpbjbYu8Jm0jOK1MXWN/AItzqxpgC5it6ut3xH 9briU8VTGS4IW0XfLwl5jofHnZzeUCR++7vkK89BI8VG9nPzsjORKCzl MRJ1Skjq0KeNxTl/4k+uc1RhXSToL2EPW/7AgdqsOOQI/1+bZ+8ZmsdN xkq6kZTOsnLbvx4GM8IFKz+zfQVZWgptsbDf/RiprljqUOdPbeYl9cRt JElK6hvBcXvp6KFjodMk6YwzezbjyI+pmUy5BQFn317H36UGief0Rd7T t9lbxw==
+; resign=20460416024207
+141r.subtree2. 86400 IN A 192.0.2.1
+141r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . s0M9Sv/nxCRcj/+QW0pi0RbTpTdN19RejnoYY8KYiLJzzdThRyLmwGRg FOsEIS2IbA+zAYdiXejrGxqiGP8F6Djr9jULjVdrH9bfCnpqBv1HDB2n U+ma5apsAocchcyYJjkmP4QsDAoP0vUu+jhLh+fokPzG0lnAV0qOXZSD l8DJpzKtH0F+0vTEliF/21usW9DmOmvPKPFWjB2PvBq0lsoUjSc3v8/U oLiRuFlRnruUUgAMN5m1Oo847CJ5FV4S7b304PHHQicjlOxahhBbhBGJ nKv/wvCjnqyT2l5rkgZVHg1GIDDBt6riY9+oxoYiOkjIed8oRUySJqgg /VvARg==
+; resign=20460416024207
+141r.subtree2. 86400 IN NSEC 142r.subtree2. A RRSIG NSEC
+141r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . VCDQxwBmXbc3Xg0Dx7w/+Icjl9zLziJi68YVgJC9GqynePbBGv7Y8c9l JMETd133deacHm/KO/CTE385PKkg3hxV7icsZUi+9mYxuKMSebUcq0v5 fa+BoiwMGDHq1ypx+U8/T69dM0nB8WIVXXUY7h4EojABv+nceg2ctgdB E6Q8iFXZhQtRl7KkTYOSGYXwBgaiokx8xza90SgVInEk9RjsLrfEaQN8 yRuMD5QTOF6vx59rzd55ig88tgXO0lULDbUFwwTVfM/P/wro9t1EpN6Y lEIKzB2AG34M3d1Ff+oE1xmaKGfiM3OXaDJ9biWuHNKdmcqcVVN/QfQ8 kSBgyw==
+; resign=20460416024207
+121r.subtree2. 86400 IN A 192.0.2.1
+121r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . T49hjXWYhZI/lr9ElgAbuBilAsfDoautCeXeOEcD0lq95BqhW1IL7/Ma r7jxVviyQ8q0HjDVpbwlMTGDav/CG0Xsxh1I3fN2gRBEPauO7N6CQ6ym BEF+004dH1Zmk8NgjsggapWcitlzwmiXCxDIuVFSVTCiLQ73p/uFjBDC ML0qIy14B7RQLnMwGQN/7wFMqJTYZ8hnFnzJepzFw72ykQYqV9NhuYd9 iF74bU4q3KXb/ZxU517uRQ7Nz4k8ffuNOOankIFKjjjUu327rlycziR3 Jwy9TH9uShXbvEef2mhgisiAaNVFlYh7+i/AgDSBw22Fv0a95qyMlchs kTevBw==
+; resign=20460416024207
+121r.subtree2. 86400 IN NSEC 122r.subtree2. A RRSIG NSEC
+121r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . PB03mEoq3UU1YaNTWTv2WwJeV240u76occSIJ4ydGzmTQB5Y/K7GFlck O4vk444DRKXkq5JNLNGt26y481aXteR0g2FhWZIcR4G6ryNwio6XioO9 wB3FGZNe5w1D586Y5mSqNpAITV/kbTVB9HHM6BHNjrW58OUyT90Xyfkn uGU1EmwAIu1QXMwDpUbjqRa5hAbEhHYrLjYL7bvu8wQ1OiSQ0kbQK7B7 3/l4IcMywykDmPcXwV8gm+G3DOZ+Tr9j3vgmNs8w3K9EcRMENGo9zVEQ qlnt7w2e+P8W+avwdemx/2D1DiF48QYRnfFwvCWzVpB/Gl/JdsfDZzkC ry+bCg==
+; resign=20460416024207
+142r.subtree2. 86400 IN A 192.0.2.1
+142r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . M2+OjdCI8RU/X4ziIxBR/2aUAAXP1im94Zgp9e6clzNHs+3v5213RRsb Y3QTqGsB8O9+5B+yV1vGlit4N9Zu1Pksncx9Un5fa7pC0Cw7qmmLtFgf Uaue1NnHZPB+1ImCGJfnwHRksfA4SLaOkRKYcy4MlQDZ+kGWP9pT+PQZ onPrtYHluaoZgYSQMSItld25jomaWcjNtrAeU7SdzAWXcfwneX6sf6I/ igelmxGD+k1IfrJ2fAUcQuTR/JqDEQLWVaBLsB1D3WBC8BQif3MFY53Z 7/TizcH3ScG/qn6KMYjoyLW5k+02SA90Bfds7sbR0uD+sBHAu7Yp/L/D +J7Lww==
+; resign=20460416024207
+142r.subtree2. 86400 IN NSEC 143r.subtree2. A RRSIG NSEC
+142r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . dDa7tarIl6gdQtX/uOz66itjuyZtJ/GwxEXSUuxlqWvlI1PC8lYjlHsZ 0ss7xZRUfMv740xDDXY21r3n4inlm8OjTmMczfi/j3bbQmwENPoJKFeG 5JhQQOPuFS3PVjQnaiaVSyusmpJqCBuwPMOgmqKqoN4QWWKymrxYWWft SO0qEsb+K9UYIrhjvjmTUPUA9uerNZ8v6UW3lD+AkyzP3eH8pHP8KzUT EhH2lO4sVfX1aQpgGd6Gfeu4R12yzPqqH6epfS6N0DwGYGH6Je/b46jn bUf/tP9/3BAJw3xO+LKEg25sNJdQ4TzrdMY2gvyXYNkMTFxmO8bCeKGq I9ZoxQ==
+; resign=20460416024207
+144r.subtree2. 86400 IN A 192.0.2.1
+144r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . vouYlS0l2NOkfSjVK4qj62oRQprrUvs6Vh9oXGmlEqoN7qEyj06GAwz2 tQsR/Yuz1c1AKthS5mbbLYNVIRSvHcXwz+pPx6nrcnlcMqPLZxsq8XnZ GQfTiVOyIdxLDRqppaAflpz8NwxNcNiNrVkTc+mZnTZBhZlniebZxUPz UBexrWxUBTQShUu8G5q79PH1XK+4+ZBsT1zBXRTyekUHbIF/vkxvmE++ iBft5YCnNXyJG1aXOvVvFmpOXYMj6Q0i0Z2nghVvlBw7zU9Ms8nEwS2D GBNlux7k8bA8fyPb0x7Ktw611EZNoj9IUbnnYOcGzli9FdZRkQROrUU7 7gYw/Q==
+; resign=20460416024207
+144r.subtree2. 86400 IN NSEC 145r.subtree2. A RRSIG NSEC
+144r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . LXKaIEqlhXpgW3s2wCOozeOcuZZzd6EPP5ntrD/ZF0Ef28US1RsrOAm9 ffXeIrv7zZe3elJC3ZsMvrsGe7ue2CfdXRMHYp7X/DaZfo2BsDqxNn8j yUfvawyVfByQRzoBUa+sWx8YWZBPEwsYPj5cvg14lXi8KbMTWeT5Xtgp uacp/KfXAJo150QiCv6vJRJPuV4+OgfvG3MieJKqsykOrd1zpixwvvPd OKQ2WWcURPH8p5ozimacxdVdvxabCemQ33ksiDRWFlAHxMePkDLNP48w Nb1/Kf3Xfn6lQXAe7Sf63v1bjGPmHqNMLjiq9si9AOt6SN9/kPKFh+H0 OaGzkQ==
+; resign=20460416024207
+146r.subtree2. 86400 IN A 192.0.2.1
+146r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . FIf5murAK7JG32Aiquf9v1kti6C8uTHzO/zYOI+CPI5XlwD44OtViTgC FyQUu9ZGdyg7FFYKtmLXDD+irw8Rz1g86C7bBrFPHN2KntKLK6q2K7qH stsryYKqGbSyktkUU/owA5C34zzJ5ubX1kTJ6NY7GbFv6mlOTBb2vfaI xyiguxFl1Ic1XCvlkCrKE2oSesBtjAWGEAoPFYf+1oZgZbk0OB7tNpXL MreaemYoWvICTTVSPggiWOcmWyfwjzHCrtycFxK39b0s9bafKxzlwv44 GRx2sl1KvBhB5JO/Gz+KVuDyMpb9nhG6X5oOSqoNqQ4B+M/3dA7lcuDQ 8xCjOg==
+; resign=20460416024207
+146r.subtree2. 86400 IN NSEC 147r.subtree2. A RRSIG NSEC
+146r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . SrHI4fdyyLPVIbhzkzz5um2wT4eQXAEWCq13XnZcUQsn64lH+IYDQgcU wXt5PlKQBpB315hyAd6V6O7ZKBy+NWI6l+SSSIrSX1LXsgE2OfBocmlw f9hJqsD0Pt0KDODjeQ00mJF3uWz6VSASAWPeStKy1IYe4FuYWfD8vLZ4 1ZR6T8jAgP+O0TYZaTv3C2fCNiRc6PWJn5swmJydl0VYkX4nFmEdztlO yUNkmyAXDf5yjG3rd2qoX2di7x8Kk6eg1ANlPYmWhd8NpPmbTngb3tv/ c1bYg7Vo/w8EPOUmaAy1CW1GoPwXSqdXXmAPq2rXh8a7KCG/tOrz8Euv t3DDGg==
+; resign=20460416024207
+147r.subtree2. 86400 IN A 192.0.2.1
+147r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . itMxfwAPvB99xBemNGQ4wTq6q6hshfxjC4amZmFtNdOLXOVZhkwMlhMq IG2Wg36SYpEBmNSfagYxFj3ZTz9GdULbRgb4I7sMVM06lCVfumNcllUR nrvwOc6vsms3RWxntFkW19hG2x2kE4We5P5ztUitMwmVsy4ChprDyqls VRGEmqdEFv6xgmOxCeYhBsptwt5Tr3yCIvjYb4wO7F9ACmO1RUH6j//W eqm3DDZS/QGq/DjxhepWyIgbP4/CLUUPH33+NGbCTMxtwnP7V5/afLWX DSKr7hskDKDz++VLxmchw3OMzBRAHoRkRSJ26i3i711WHKOGs/kcMhIY T9xAqA==
+; resign=20460416024207
+147r.subtree2. 86400 IN NSEC 148r.subtree2. A RRSIG NSEC
+147r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . Qp5LV8mmTH/nad5/DRQ3Eja/JdZbBT7d7htQBL6DizIhdXw35fa4x+Lh eRRXtRh/HgmqRLKgyQvaLKqdwC7SeuCk8dezeJmvtFirrAcgXZlacOT+ b/3yS3xgStmfDlnpwxzuhuxoIADwyxonb0BDxZYKGjGZAiAihKVZJah+ ApVZkP0ikLvWfSRwUeMGtiC8HvpL4W4c45dNz1G0SubfktzPWaBDM+bD q151REswVl7b/TpqMNG/YjAgE09zCLoFtrt40XbDTrQLOCM70r2n46s5 JQBhoj23HUh2QidQdcwHdUvO+QZOom+pxhrBx5A876AGPr/on8r0Mi8H OYoLwg==
+; resign=20460416024207
+148r.subtree2. 86400 IN A 192.0.2.1
+148r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . f3UZIkgKRmT8OO71vS1xILRITsURjmYu7Ivf8fRv0EgTY6oM7DnpxP3b wizevoLNiopyD8+ZbpeaqcA/nvW5ue45oShQsCrhDXmzjz9JlK/4/o6p kBud56M3IDRFrEXIuaaY3WCDs7/RCs8USBMarUiB0F5QLSVz5HbPcFvE WPt8FKws95CkGXhEa5FiLW9PVpmEIcvMb82vcOMLg5WeMQtXH6aay3Ve 5gauH9e9xQD4zlW31VdyzTEoegmR4shKM+N1Jj/H/O3S3iioYbp42VWh XY7L4Dhq0O9K4h9RPk2YBsv9yXYl0ea6ONouQq6GBpvL4UtkCk5WxC/p f55mfQ==
+; resign=20460416024207
+148r.subtree2. 86400 IN NSEC 149r.subtree2. A RRSIG NSEC
+148r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . A/RNTWjoB4beOyWVfe5KIeF358CXU7QSDFSlq9NkQgM/hdOoWBoP7BfD 5i7shmE8HkH73YmlacF5dXEGXds/AoBFWxloxjwuF96+XPgeATgna+Ce fcpyfHJoSptoCUB3nlu8TE3GzUBFnHYNyRa2vOPTGAI+uaDrAbbw5vb3 ID0+ezMr2m3hHlFQ6MXfz+UwlEoURz2K0T1WlGdO+WDPXZys3yIRa+IG cYQE/iM6yPW1yorjPUCP48Bg2M49Q4L+H3HrJe+mGRxQnheZG1VENFZI D6P4PCeRTQxkeo8d5L9Lik0QmHD2/PHw58/ZVQO8tUkibo/wonIDwFRY kWFSEw==
+; resign=20460416024207
+149r.subtree2. 86400 IN A 192.0.2.1
+149r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . ALwPUCoxbaiFK7OZr0/LTavFs34CjElZw1KABbHPjlYcMJQ5N6bi0kdM TQxfw33vm2rCBR1hbMzYnsQqG9I5AWDnb687d9azCpN1+0jX84o4Ku2n YqRI5o/KO6MV0vhI9BZj7WFwBSXV1AMME244vDseoG957wJ0yyjTOyH9 SJZlmGewXdr6Ugy80/2/Z+S4s7sBMSe+dkLkh7ctzJuoGMHIJIDr6mrV TTGvhEV3C/Csl20SY/qzqNQMHCBui9CqPE3Hqs5ExdgNcQVH+VIcSrW0 tqaXUx9Ci4OwKZMDUuUWktKlSl058+qdfileGbSLINvIrewwZJyunPqi Kz+0Gw==
+; resign=20460416024207
+149r.subtree2. 86400 IN NSEC 14r.subtree2. A RRSIG NSEC
+149r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . xhBfQabVy2KIGOr1RLN0IT+GU3vhDaQr7fabs+VQJfLG6Z0xYzS5U5Ti 4BrhcRsIQzWQOPKnzUe08o/pNVCqkoP4djCziCx0eo3UOZd6GggXhqP7 U2EGA2YvbVuCXEScq6mEMBZNgTjEUVjWJ00zF4IJiChrfHCmK4H5Eijz h8wGd/hxMn2ZFpYGAGZ1nkrdzoJjsEF6xtUrptTUD2MT+tWKZtvDyl4A MNyj/rHOkOTpSTHotgWDXwdnmlRK7AC9LJPVwO7gebmMFZd7RAGVoLNR PJvpJY08exrpYwNnG1ub146zIS5HQuJDH128JGYaeksuJWczatJJ9OWa mrJemA==
+; resign=20460416024207
+14r.subtree2. 86400 IN A 192.0.2.1
+14r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . wAVrmJPhxufbdd1jzJXHSnYpQVYY4Wu3vlVNwqzRhi4dTEJcsWWO8SnA k9MXqNCnZKMB4KHMdr1XMqHc4swsSrzKyqOLSPlYBWR4YW5igEtgtNV+ VGkWNHBQsDGxA645mRVrOyFAFSL2GMK87IQ7TGXjFjssxUlYt7zoxt25 Mw4bwZi8oCi8ybd1q7IertVelqvWbhohKbKza9suVxArSFjayrThIedL HHd7yWncsKCwLLuK5+ZrFJ4LtETTbdPC5hybUGsJ+S5migqr7t4xyupe m2ZLmHOEVSlzexa5YuwK6UQDgCfUpBWeBT45gEjU5ULJ5H7YjFooaHZG 1Ao7AA==
+; resign=20460416024207
+14r.subtree2. 86400 IN NSEC 150r.subtree2. A RRSIG NSEC
+14r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . iClXhruzeEz+KZrnHBbaDf9Au0x/txCi2DbSSU7Kt6E8gFsrTg5mZdHW WPdJOC+vOGqoSusDlp6VAr4aZitRLXtFaNOBflAMogsgLz30hdzz4CXY jklN4ZYGYWAudbB5YHJtnSqqyjeuqeEL3yQTfX9LkFgz7tPVlQzbnMfZ mz1qQ3ZWFV75h0CTs5XlZgs+n4i+OqoiTTdf95kcwqxhDG27eo2WxJiX jVXWOPe/vSermIgYzTvgW3EiTS8H1sFgPL1kH0u4qSwk32oEQuYky8wV dLwlMvywvFK06hDWDJ3k7s986IOWenYxyKtusSnsnCAwknXlnoyc6AU6 EDpAlA==
+; resign=20460416024207
+150r.subtree2. 86400 IN A 192.0.2.1
+150r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . pML15hMe0UtCSkZozDf3GPKnCkEc1ZshVtv4K6xuxdf68H9ND/Wm8Nlz xKwJeuzOJKuesMGOP8iB4+JBuRNzP4ONCNbUqGdAoCZiznW7l1LwFjXG yzxg/JkrzAIMf+FrvGycU3m/hzQe7w3VzVrxfs2r5GbTwAnrvz8iJAp8 pqwHwsLtLb57ufLA/bQprhaEC9HmlRniBBIZBp2Sz8hWkTNySIgv4CuV tM+XDvI1l8wC7599BWdKa8aZ9N4kVUiJHb2vTuSKrgWJ5yxb6iGhhaAP J06+1IiBjF2JxyzrdDU5xUJjAIYREk6NCOsVTB7j3QApZTFRPc4lGrRe KzYLtw==
+; resign=20460416024207
+150r.subtree2. 86400 IN NSEC 151r.subtree2. A RRSIG NSEC
+150r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . t/yZAbAAQQ10vbM3j38zn8lNH0/hcFQ7cByPn1EoVu5SV5oLy0k1SRtO JdF23wXfENum3Y2S8lWKURLNPJBF3HFS0CQhhSLpQaLZgFR9L4iugiUD SssxUhKZEQNxCcRl8JXQyeVCqGhoKEJig7CoVmw8/V5zZgg6ifpLdfVD 1r5fbYg2VV7PQbcpK7QYEnfu++38XErQMOrN2vO6XUdPAVxQ3P52Bnf3 ICuklnSznX1cVWK+clEjMez5/GdI2DXmiLKOL4lcxm+RYx8JBroLgE7A tL6sk+DNlxi4DlfT80+QIBrIHRptJN/IKMolju37H7P/1kC3LL8LHF+v 10XgDg==
+; resign=20460416024207
+151r.subtree2. 86400 IN A 192.0.2.1
+151r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . D7loEcCxYOJXNKryeIFn4CwBWMRQ+n7z97b9Q2uBhhmWJm4jhjL/sDr1 eNLRRdIjWzHyZFt/iXEsN+CNsPw0iDvUQkeRPSeCpwXoY20twh4Ogb9z A6HyItif07zVVM5DAv0XjznRfC/VEQ40MvRWV7UvnFdpnRnl+6w8p+dg O+nBNCx2TlUEG4tFMxGitU8M8rD5P6G7HLRui1WeY72B3E0GfBR9DnxV 0kI0cdHp/hbQOviLYXmGsMB1GGVpN+ZNtn9sZhBjiXNLkelEgTX2f9Yx QcTy0ELv5BrtTut/L4DxCNhsu9lO6EwYc7G6pcBIwyWpZne5gYVePNKg ANfHBw==
+; resign=20460416024207
+151r.subtree2. 86400 IN NSEC 152r.subtree2. A RRSIG NSEC
+151r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . S2nBDfiRUi60h1AIMQEtzdQ3K6iCewWCSRByQVG3E37GqTXL5jt/rcyP tLYRr8pSpN5L8q2WTi3mtL+Wf9OIlaJmNpasyEscfeSGHvAoUionGMsE OK9WqFn+9JGfRLwkxUNa2SoqbZsegvUzxgFabreFncgQL4tSHaX1sI6L +bL4l25bc8vHXiyCQa6d4aSCBa/5fdlZUW4U95U6mKl17h7eLWJ73Mv1 07vZfOGXOxtA4yuz+YXTt6nRcZm6qj55j6bh2PUFiUTKFI7sGAiqzik3 MJ24wOLOHza8uydnkICFHsqBptAnlL5Y19N7IumoPzsR7OeK9DvHb1a5 lNl5Wg==
+; resign=20460416024207
+152r.subtree2. 86400 IN A 192.0.2.1
+152r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . m0jKSX1mH2X3H0FBaXx2Nm5JCiwEimWXKyxqDTagax69EdxLmpV03k47 CvDNu9TULfhzkcAn/aNRJ+0XiL29Y8DMhRuZW8AkegbR3HV2cSN/5Fgl QfOg4DDVAztIOij0PlKSQ4/nilPFgSsNTXM4AuDsW359t4iH93FeUvOj tNSVOdXh4JeVPQH7NYuhOSUXuFNMP2ScX34D6Bp1W4p2yWTRVLhSWsXE RJGtLXAjnFldVYaagXDse9Da7rSm9GjmY86skEv/kkzKtLK4px39U7bZ wYiQJ5ZnBQCbZNLpefWusnotjjF8C1xl2+MLtwUkI6hTe8+4VWZuf5+J ABrCmw==
+; resign=20460416024207
+152r.subtree2. 86400 IN NSEC 153r.subtree2. A RRSIG NSEC
+152r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . LZY2vg0maCCC4Fmm3kvxMl5gRyWkVwmtWeFfvnLwZy75QJyGZSxT+Rj9 aDU20CeOzsW9jlAUM3iB6Pcmn/smjgqaV/RJ1kcoIUh/f89UWFn4ZXjv XZKSqHaI06GABJXtnarsfiIli1W/bCsQIPng1LLqtl+mV4SEz0ZSMWIc WBsXfmnFWOj7oO59UQb+CYldaZNS/WfpdX75OA00u7sQbIvN4ASKa1iI /UZX4eyDZ8Z9dwQ8Rq8XRFFUb3wklURHA2jF8nCklcbjpcFOiq7cV9ka 9BD4fOrVnkYTqY4Aj7vR05iV+llc7dk5g0SXMC37OqHIrY1uxh5toDb/ cthv4Q==
+; resign=20460416024207
+153r.subtree2. 86400 IN A 192.0.2.1
+153r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . S0fTs2ZCGiI/bMHo9YzZgYIi8MDGOcr/844OdRhuFcxvoU0VcxU6Bhez AMjV8nbD6xH1iKx/4jhoUA6VJms+HxO0DHDjudNpZhLQWhS0UJPF2X3y vUG1XyAZC3T9g9FnOVNbEi6ORSSZ77ZYFQivlwYoIfr5PGJ6MkeOUvNb F8jSi/c+j1rAFXkPheXKFLJbHJ2PT2p3xqiwSOWX1lYfYTCzRlDrpnqb pjN1t726smKfUL+/snXV5r047AGqqvefqBIq8XmUda8Yewu978Ocs1OW ZrNrBDu0x8k3iQshitgSW7ivk/SDSw6mEJHLQhIBb/vyAt2czsHC6jfy wRAYbQ==
+; resign=20460416024207
+153r.subtree2. 86400 IN NSEC 154r.subtree2. A RRSIG NSEC
+153r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . gKkuOJf15J1G0qDffUAjjoSmp3ychacQyJw4YihvCfjZOWtvNJ44GGmw 69Z+dVjmFNlpARRVDRvMANZbZ8jQQ17OfH0ZYA7O3c9FdiCqibppR6Ai f2221EEOGjejgXxVpum2ERPPnlo5XD4OxM0mn7Kyi9gjsNVvYBvF1oo+ DmxRxuKvz/sjwhhYjE9sJU3yIR6EXj5uDEsaX0Vv9G1D9IfkKPqS2jxw tEIWPIxRQsssfZQd43qZxtIY9If+CnFVqvWmWOsmmpNdHLeMB9UmLWpd TFV5DuMiWQNWytdyEa/d4k/QaPcy1d7gDU3w7qXcsTru6+4mI3niq9FO JIlw4A==
+; resign=20460416024207
+154r.subtree2. 86400 IN A 192.0.2.1
+154r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . C1RSEI9k9LlntVROIpuZn9p4T7uMLcZtNQFacghr1qw4VeJFmziMCsww QYazrqkbIbwDufP8d+jHIajMtcYhXm+bz5GSGPSYFk41PzQbhnAmTk7k R79uIjGtdNg6tc3pzKC5+Op0TBLQPjGOzUkvGO8Z1VheCHdEumYBXw3H WmNxMvIICdmsfpN+CWfFk8INHhhw0AKSjW4mLYH4w6SY32D5km9SYXYQ 1q80fHtm4v6iNBUZlsYF2QmiIMXjgAnSbCwSYRv+9yt9gp7ADxpA4zmN gGLw7AG8xC01wYcDiziEkUQJKdPpiEcsTds3Kvc9UqjTYObEbXQelxCW DY1xew==
+; resign=20460416024207
+154r.subtree2. 86400 IN NSEC 155r.subtree2. A RRSIG NSEC
+154r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . GuFnrQeKviEGN7YtsNURisuq04tauVEnnOgAaAyAFX96WAH+pkAHeyPG 7hu1jbPkdEm9kA6j6uZEQXe9WolSlwuCfwsyhsnaXCNesrlRntlnBsRr 99wglXg1eerks4/uDub3DgZ2rtBg76hA6MVu3afBJ6xopvCDbCJjk7Kg PXX37PcCgOcKuj32dDn6GCNIhf1ZD80LB4kIZCS76r7KSj6Arq9ijWYp 7bqe+6rmfD8AgdICMYn3E5e+0C2hqSQLulrLNfQzY3zXkrLXXN94qbYf QiWW0EUcf/IHb8kZerQAYE+6o+hh/IuD1T9mWJ42ueEigd6kCdK40gBL 7ytzAg==
+; resign=20460416024207
+155r.subtree2. 86400 IN A 192.0.2.1
+155r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . gG82211egHdWycQMwsz6FtX2DrYeuaQ8mS0VCek7UIaARUhhdTfA0eQI LlF7aTFfT6kzn9VuRvhRFkeA4rVrGH4BWu6f9TfEBiq2C/VnV7j4eyD/ IOo0lLvOlBJtOooQiQ7INEhTF3vCbboZQJntm/i609vZXQFlSljnBoia uTJkeGn+B5wqVjwuKPCGrInUGy1L441B3ZV/eA3sxbNQXC+5PMf333zU N3puDUfMl6BAF307t9tBcv3LeDB063dER5uZkYHvmQilddssX5yL4jRd KR1VJ8Gb2NAQ+js0KsZ9M5/7yfIEQCmG2qHmsx/bz3niuHC8YCKSJPdn K0lAcA==
+; resign=20460416024207
+155r.subtree2. 86400 IN NSEC 156r.subtree2. A RRSIG NSEC
+155r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . UhDOIagmyaTiFRApGFkIYoKtM9/GDCRDVu4bAjbQqfuayyFE8y49piro zN0Of62liFjV8DQl4iCQ4uh7ENCe+bCefnnwKzTHgu0noDJz06AZ03vG A8USwN/NDKPuvdplGTjTxDc+07obzc6jHfwgdIIrmLdJwYk+fEMY/1qu JY4sdh+MklPZmSKQeaW52Re0cqX06/ChupapJzqTTIxS7j102vBi5Xmu yEz7YQ+j6FL0zsmdzq3t/wW6alNBRzW0HHs05PdhmUClK/PMj4NhFUyG Le2VvtAipHfjw+LLWvAWaR/BJn5WslGTZ2mHfCDegAG7/K3f0Fs9onc3 o3jsdg==
+; resign=20460416024207
+156r.subtree2. 86400 IN A 192.0.2.1
+156r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . exFzVr+RoPKSjpAmZAm1ANj8d0Aiu34YGyKvQ5j/IBUYzE3Zlx/fl8mN ABwh6JXp5nQMoRanVwNBP0JY1GzTxsWXLAfwW5LjJq+t7m0o8jXQp/0M dI4uA+6r29dAqHM7VpWPVNQGDFv6hicM249LU7VhPfd0UODvSEQFqPD+ vLj51gT8ch/gw6B5OlfY+eOLQ7OedWRnmwSJQP5gDCKPxutpmapm/MKY YjcONphDXIX+OINVGfewkq+fqSrjbqE0HTlaQMpwCvjFzk54MzI8J41u 5VCWFwVcEWAzU2Q8tDPOqNen9vVph8ltTSznqAsNDR2Ifzn113uS+jUZ jwuZfA==
+; resign=20460416024207
+156r.subtree2. 86400 IN NSEC 157r.subtree2. A RRSIG NSEC
+156r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . FHLCW/aHphFiJgzIrRrox8/5Y6jsYrhCtc0S91UAI4XXLwnNx/fOhiuB K6+z5GAF2GQiXR5O1EusZrtr5Wprp1vYOYaAZ8bzR58fgvvWAqie2FrU iinDTzDiS2dg5UDlJGts2P4kGc3XJq745EbpQSsicsELD0+XCHREv7vD 4AfohzG+RhZ2iGl+kBbsEaOPUY+3FmSShvmyjy1jq3dAcN0ygS/vHFmD ZHomYG6E7eFnWYB08cHOI2BFheyiDwTHoA7hXmxvMeK6yw9e7XoCGIf4 rliOKjRHabC/Q47kkegKUJYJvVWelvcCjTjF1BIEYQlcFQcmt1RMF41t iA4s6A==
+; resign=20460416024207
+157r.subtree2. 86400 IN A 192.0.2.1
+157r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . LqqdNvo9e+TrHcQFlW+GBbCcheSlWqNwfOhNH158MwhitwaFAdnVOTT5 N6KKCOGX/KzFmYWLBtI24agapHop0lei/wE+5UZkGTRM2OmDHm3rx8JR kHrhhmlPaNfvPl4xPKy+G/o3ddOaKAEsqW6FMTO6F/8AAKvQ6qmxBvBa lJFtz1YQMXnxIgzqfColBenWKroKlxOGW4WvdUTsfrGHCAl7daegoBuO LHp8b/3Okwz1Khm1USCp/G29H/bA4TFZ2AYJHFSsdZdrUSJGycQh+tdL DEx5Maw5pVRBP0sO4gha9VTL3+tEvCMVMeiojM3YuTuUhBUvQXwchbgE q/UoRw==
+; resign=20460416024207
+157r.subtree2. 86400 IN NSEC 158r.subtree2. A RRSIG NSEC
+157r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . fNbdH5MpGI4J7hSnqnNAVKG5WSCvRXQHZotkNbEQwShjwjgXkt9xx8OU fob5B8NKwpG3/+QADxCZRN4krLNCb13idukKvJ5I5w2GofTU/4gRz9fn kX7U6Af80+k1Uxo0APhaXD7d8HOagTg/vIXNmaEcgkNQpw7W0Ve82e3+ +y7g1Z/Z5Q62aHCHi+P4kTO9fCYmmeQ+usGeKdTu4S3LSwNb4xd77stl 4Kl8H4KnRaMZwpJqBBeZx8QDGh+yu0YfV4RTt5GG5MimOyO1hDkaO8QX bGwUYPEL7otH0HKv6EAKSZrX93UArwljjWKSOeK2pbaGJmlaVffwRpGY 10yZjg==
+; resign=20460416024207
+158r.subtree2. 86400 IN A 192.0.2.1
+158r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . GXms668xIDKeVeM6+2Fm/8TaRDcrZivaDUQvTtDjlbhB05fABVPpwUCV MSc27hvyxnVvAro8KgZuXrDUCvIVySR34c1hZRXeOt2U3BTLTHDlUdtg 9FBYobe0Rv4jrdueQXeTGgN1JrtAE3ujQwrFscebgckWC7ZqIOIH7OKw gCuvPZUdJFsy206TNEUjiTbZbNx6uHkvH8EfPI6qQektSTDvzDgBmaMD 33a7xIOAANmImj9KOKx00XeG8iokTKmEr3/B04UA2ToPf4BK+HVNjTwD TY06VSpfe1rA2eYLSX1dD6x4vjomrb7O5fmCQRM53OnvEyP2rRWYAdgt U5gFgg==
+; resign=20460416024207
+158r.subtree2. 86400 IN NSEC 159r.subtree2. A RRSIG NSEC
+158r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . Y8OI/fj5Ld8cr0vH5iv7l+0nX2faZoWoUBb+M0MMPorCJ8mX5K9MAxSg Pr2pPThIIbvX8oEvJl/1TwkEKxZXcdBXNje0vMoNjEJpgnRvKPgbuvrV aTw9gxh+M0Mde+nWnMZBvhwVmDPrtfIc7Pkbj2LhzENNzaLbOckQFT3D 4uK1Pv0ikgdMiA5m8Pi3kD+vF9wd4HaDio5Vfjggt0jrBHQ9Iw2s5bdQ dloEmcumOAD+r1c5ut690r9TrK1nAbgqNykg9QtxIU/rWQa2CQy/UrcA s9khzM0pxu0QbFNJ4Z3XCqpoS1X7Hctb8iaPYMhzdwmsrUg1PQ7Ay85O hHVTrw==
+; resign=20460416024207
+159r.subtree2. 86400 IN A 192.0.2.1
+159r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . HegookV2cV09h+mzSBG9UJZ0LbH/MtVnYfnHFKmSgebBi9K6ZZ3/926o sBYj9LrBRJgcsGh1l6h11uXN91cJfSFGfhQs2M7Ak4PYlz4LiV9GTIfa fJTz3kNWs4bu0ljx+heIwo6+2XF39y1rrMLPrrNDB6FYmbs6QKVZxPc+ MUEsorETFz0g++XsunkrtyV8YzNZPrfN8OYa3gmh1oxoBdoHDKe2/+g3 dR+GRHOHDHkqCeleuLUXQ+VN6lxN+CwZwuFqpG1dCDaBIMd0Y3dm0S57 D7txrPaO0qLZjXoe68r8AlgCEJX0+j+R+VEt2SmtLSj9zvxAWU3vxXXi ah73xw==
+; resign=20460416024207
+159r.subtree2. 86400 IN NSEC 15r.subtree2. A RRSIG NSEC
+159r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . bCW3CfR3gNTSI7PV1vTJZEqklFffX7Sd8SBaPVtdadTnD+G/hvpKz0qC na+aljGCxHX8qCrs5l9i+RJ5ppC+rTdf4gWS8D2Z0FK9xFvXELvjou2Z hfFmyOXwhsSejVLpPGhbbQe7Hc2zBrShIWRjNRfBbMC7DfpBVY6c26l3 7DpzSltrzJ+hs0wNlCa7fd1Mp2dMuAIf4zIVPNID89+LWNdOSPAmyev9 eeLvhvl+bCbV+JKsEFY+mBhH88iLnj0NX85+s9kUK0vnXbf7sSIolq4u 6m725ur/k3nNFTqg7F7pxd15Pa1LLwooDVgFGfCNRUvY0ScdhdklbTzT fBUL3Q==
+; resign=20460416024207
+15r.subtree2. 86400 IN A 192.0.2.1
+15r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . IVVUyvogfv20mvIHVFB4Qh2sRM/R4AGiJWllTZDYa3hvF5iFfzOTzNpN GilwUSnQ2pg/iHhJhAFdOtz6usAvOrfQGlWCnqyKbKpDX2IVNTz04CBQ VpK/nShPRTyAbmuoqGmxcyx9BU0gXsUBJMDqTNxllv7ngVgiRAr29uf7 xzGQA/3Xf9d2g1cqoZx6yzoc/OGyu0WCd0RuhxYE4Z4qh5WPfJ3Lf2xf uDg8RGQ52+H3TZPlbbEIt7zr0HBxNzfsOjK3oVZB7ep4qfeH7QMtlBLJ HEpvY82aoVyq2pXCG0hRiCZyvUPPgXvGdrxoARAA2dLk6fkHzXnhn1kD SsKtPw==
+; resign=20460416024207
+15r.subtree2. 86400 IN NSEC 160r.subtree2. A RRSIG NSEC
+15r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . NfFA7jC6LmcZFCe7r0lggnG3N4GQhOgfreE4KBeqjzEaubmJm5iDJh/5 lDoFrQvrXzIO9XCjBpBiTKh4/TymmiApdJs5yEtFo70SwB9aDwwlBznj 9aNtwPYRfr20jfqScBRS5dn5IyLv19jOsFZJ1ke9utWeVh8zJenOMNC3 vWcZuoYwKPJx5uvTIkECABNtNac9ruA82+Uyeq8s3EoUCY8rcc7I3MRI ePRmvxP3ftF+kNZAmuw+2/5V3IKTLAo3BZ1KhlJ7WZw8eeI/AmpZD91J +LT91MzlYJ8XOu3xmBmBhtnRZnWkTgIGqihSrVo8jFQj/qhoYUl6WBDc PJdoEw==
+; resign=20460416024207
+143r.subtree2. 86400 IN A 192.0.2.1
+143r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . KXET0omXBGMO+1GiBQdhTrTZx2rExg2l1uNCNOlKbo0XxZLdBNKmG0iy VEtRDM4AhUfLQ+kDSNWJIQkBIhLESjOSp+2+oe+xBlWvgmXaYxWmZmjj jPYxdPtJoxGFI8xH4QGp8hjR9al+gGeM25Fsk3RvAzwQTVGnIP2aAv0o Zn5Qt7533ahGBuFITJxu6UCATY96EuSIiColKcmrcQ/JBF3eOcBSWyW0 Jr9TM+SYJNtLsbVP0ixjvfDv8jKPh66BkPo6GwyJQ/rb0AzSR7balPNR GVaYWHPcgkx4g6S4h/PvYspYiSulfJ1JywTSDTXptzpOJgH/SVwwRz0o PIqGVg==
+; resign=20460416024207
+143r.subtree2. 86400 IN NSEC 144r.subtree2. A RRSIG NSEC
+143r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . t2j1ZAGhbldo2YnHOWPGBQR/xp3KjRqQtt683GTB0R1DePWatP4m0fyc HnwCk+1gqp7toWFip1s6M8df627pZJTAEehzjBY0KFsoFhfIYxUIO3ut jhbsoYr5N6CBRSDfpBCfHCQNc+Tv3IUQApP/4vbfxGVUIUf2r7rBQrnk WYOv5vEpU0TCm30bQBZVEoG8VUNY8mghazonDTHaqzc13ga6LSuv4Qib cpoJb90xj6QmOfxj/QB0KNaJ58BbM4JcJWOGDdwF8n8yRKFJbpr83EYL 28bgBI3yMp38ZkKjcUb9JDRj7YijWG+LF/nGT9VB9RvMFMz6Jt3D9GhR ISD5Qg==
+; resign=20460416024207
+161r.subtree2. 86400 IN A 192.0.2.1
+161r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . vlhrynsX4HUZcUpaYIUJEHnbofrhvlr6yAIa43KctslqB97zpfrZO+RO wg/z3HCXeylyUixDpXmYr8CMfKmARFbQtuBPJlDBhRpEi3V0QsqUjCFK FlK8VHfwwn6bF9eCPi9LRVdBRXSJj0ouT0mWrfg+yySBHZ/OBXtGIgA9 aCYvaBZPBVBG44TkuoDaJkRDP9asgc5CBOHX6V2FE6/iHYAe3VIE3bBQ cWBWH5IiBakzhJ9qRLIshEBNiGnXF8FEZLTZqc71FneY0+oL2gQ0cvyH RAoHeAMTJlqxDGd6jqyrHiC1yFTq8t8x0Q7Xyq11sV+QJu9TXZPoJv1S wlLUEA==
+; resign=20460416024207
+161r.subtree2. 86400 IN NSEC 162r.subtree2. A RRSIG NSEC
+161r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . EmhrDUGPlpEcrclo+ijJp8/ge5Em4gKy/5MmI7OcflL3ai/H5iSZdqGU n7+3eaM9gkFDQk6bDy5YnfvRZ+Z4LnhM3OYsDc/CjtpU5O7IaAjCneLV HuDuyqtWo6PZkBXRiE5013G30OZXNXOee+75aP+OBvHZxYUmQO5i61bu qhQ5bR4KOQ3/EALyBqTClbJHaYtrCZLL3D1CMK25zV6Oiybqaf85uUzU JpoEl11poqNhpbGvR5oWQUQl32GgtO5E9aMADkqM9vFPjTuG40wysV7s k1ehSfFajlN7sIibEIJaHSeYklMA4MdnoxZa25AErhlBqYfA5xsOMXj9 0ggkMg==
+; resign=20460416024207
+162r.subtree2. 86400 IN A 192.0.2.1
+162r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . KF/Dz/lWJfd94GoA9l7dI39358OyKmbPh5AU2FnmQah5UPIvMFzGer3E Is4KuzGgrpJ9mRnq6zb+OU1WWT/9uLVGks5F0nMldd0B+dIiA8jg6M8T vLz0RePiK0DloAvYb+4DKNGJXVfpgR5Hp4mKGRHaU/WifbG2m+LEN5k8 Bl4zw6a45IYygqBkFrXijamNjzuDgXQn8hl/D0Qmvp4GjqEQedjVVTu6 oFkYS1dClas6dgH4Pva2Q4bD6hoG5imtFnOBiDUc4PmhUQ2tIT+bunFM XzcnLocyOoJL8lFlp+qd7cM+bWO6ZgECTYQZTKVt4duvUZFF6PZ2a/uD q8vbDQ==
+; resign=20460416024207
+162r.subtree2. 86400 IN NSEC 163r.subtree2. A RRSIG NSEC
+162r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . S+jFQ8fn0f0qm7MQNk6YG3ySVgaFWO4syGDeGQ1DB2JwP5VwiCXu4yyd 0yDAH/L9DMIB4+cRenqaXAxk/XPLJvUaozJFhoD9TrhwQLLnvucOP8zU JKch0Ue0AqkVg9LhUbxSCU54ggB+nSnx/Ys+io17WDtksclnC7mum1LB y1ZC/k7OHToVSvyDfByGn2r3H1Q/7FInUM475v32BzjGq0wfHcScf0tS xZAfgGbYch/VbE624LpCXKHuS3J6L0RY4H0EgVI8nblmGPWRIDDWvBrS S0IQIWX7lxbL0PivCtoeNRE01WFum3GJ6bYD//aPKdJUkqzlhZ8c7Rfm skWoew==
+; resign=20460416024207
+163r.subtree2. 86400 IN A 192.0.2.1
+163r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . ryyFupS/F9mcMBwD1aJjXDGjREl0TzemgsTAipvPW5lY3o7Mt3k6Jmxe MGsKtrSMXWoDtFzJFEjkiNG6gMGMaJ0RSgZUotJdGZru/wK/W8uk2oKk 5mYBlSgGjt175B9zSYBcn9rot6M+7UKCY+bT02r6xhH2ckBw3HFjs3Ht ZEhj4kawEp1EaynuKHHH20ZklVAQwUBuqbSmoS9/HTwU1nS3f6b6OMGN BesHOKn6jQlSmjDvJ+a6cj74Waql9RLEEKA6HaZzfCm/vUo2NyxWROQh IleeFtokoFEkX8vWoliQ+6xfx2yfVEJaajcW5JLyBc6VI+GUiRuy54VK E2jFOw==
+; resign=20460416024207
+163r.subtree2. 86400 IN NSEC 164r.subtree2. A RRSIG NSEC
+163r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . lBd/dCiwqanWqm2GC3Jc2C3b4r6gsydAabLOjgrkZE2MyxhJofsxKl4b 2TBN4094x+OdNV7TvYmE3i+/rWJKMbGdPFyZNfn4naJBKvCyqgqT+z3p 7XdOzVfpQ7xWCG3RKRymbGWZuarPvaEHLLscOh5WVG3l2hJ24zfYmTQi 3sOtL7S8Y9BbmdziWHcclEKB3CFrrhiC9AhPLPzcuiP69kNZ/G41Zgl4 c8CRNck6S2OqQr/sysZVBVkfygfw6epX6KLfOrXh79Ouwp6IrpG90Sam a3g9OjHEduivMnQ7GjKPZo4xTmwtF8WqWlOo21tEW08BZG3Gb+hHlVS4 6K5JAw==
+; resign=20460416024207
+164r.subtree2. 86400 IN A 192.0.2.1
+164r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . TllI/FXJAkY746MaD3p6Zk+iJg6U05nR1USTnI4Gb/IcIJuP+W9X/ng8 e59kvV/wwH5qBBa637HBOWIsop2aneKobs3Dlg1rFuCVwgFIpjF3Lm7W jADJvNKmp+sds3kk9tCCsQ515lxtQKCr17+FhPV/qtsZHG1A/h6apCoF jYCGgyr/00b/cIPpn7SYLOfjKYx3LW1UZE+Ap1izUYzYkmXRcSY7EEbs C4Dok8Nxu2d+5rnV95mbMJ568RWyFpPiaGYLgf81mOLXQKy7zf4LERh3 /gTzA+RxxBgIV8xAj5OWoCxUe3fdApDFkHisAWc+7ybqskXTyvDHeW/V /npJRg==
+; resign=20460416024207
+164r.subtree2. 86400 IN NSEC 165r.subtree2. A RRSIG NSEC
+164r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . jl4i1uRBqCLOuG+nVhWrEVdqO2COoP4+1IwxGeYuwUogG6qaJfF1iPZQ DZx1cfl5OcyfCKSB4mvQcueU/9vpkHzHKAHmhQ1Qeu9/yKI8du/fizi+ xRsMljgrKWcAjCSrUwIlwghni1fMI8hUQeyQSEGpAl2X3KGQlNik2ijz q+yEIz56/kSNk9vb7gwT2MrFMCA5IRvHZbMXnmAQ9dSwvsdvMtFfWxv5 JKadYIgEw2LD8Wh6kmmR67l9wdzvh42ry+alKsjjsDD00v4wcDDasII2 HkVguKEFYhFQYiS4/Ww1H65cLcfk5jiyepLyzBUIcp/BesXJbcDq9A49 qfjFdw==
+; resign=20460416024207
+165r.subtree2. 86400 IN A 192.0.2.1
+165r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . XJq6gK7VZWwLlks73ujiv54rlxPRSavX6v8vI8BzE+DjgJKcnxmvMkuU thYSazPEq0awGUjDFthHXpRCzpn2KhKaOS/G5HfQmQ/IJpfv68usCpdF UQ2I0MXOb8vbawlG+v+F3BhKBH7eEK3M4tS+TLYK371n/v+PUfC8kmYj cR8LIH3TuHpUlIZenSv5gHJNs04ds+U0wpguOWi+Av2PZSuKMBD401s+ BaRSRe9B7l/eW7ZejuDB3NtIaxZuo4K3rlzBhI+FDKvLkTqUcYlnuKQ7 SANBCV3Bns9tb3vdze5gymVDpxjgbe+18JrZsznknNesmB3bmRpgEjrK fm011A==
+; resign=20460416024207
+165r.subtree2. 86400 IN NSEC 166r.subtree2. A RRSIG NSEC
+165r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . jLZzn94eAVa0f8gv+Vc13Q6qfYVnZIX6fU4YO7EtazZblPBbxT+zbdGn xNwlgMP57ulAgC4sPt5UwbDO25ulI+oUghsjDwUpvLyPtNF4KBqkj/Pt M1B37i387C/jrlMW/RLdW51E/qV60yHqmJdi/3rW46ybieYohFy7ql76 DTh2qfuOJGxTem/cBhtX5HlpRGDc/5+W+B7DtoxGyMFAX14qmjv9qjfG VzNXS5dCrxOo3JwfrKyIoI75oFTQhAj3gvUgpIAlNr1l0D5/+v/0XvA7 0ljGjLEgKTxR0yinJDwC4YM3PFT22ErsgE8lQw+jmEuGS4LNk8vs9O5G dmv4MA==
+; resign=20460416024207
+166r.subtree2. 86400 IN A 192.0.2.1
+166r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . gajJKxjgPg8BynOCkYsDhGTUZgXw58UR2cmtf2poKlsQcZEuCmznQIIX Y2lYKrggKMfljx6QUCfUh7y9G8RP0G5pE+//U9VuGdhoN3K0eaGhS1ti yTrFN1eO9ZHPpCBfAR6F4r8d5AsEFqDtXqJjvc2BsqaO5wHyF9pcUWWQ d3hdCgXYU7jGtGydEipIjDLmwMk00ab+it0N7fJOehkcfY0GzPyOGhP/ Ix1WhV+7PsMMevKoUYCMTo4k3ligZf5v9dOZ83OKJwRaJGpODSJhv7bP 6/KBHZf/iM8OWONfbynh8AsARuXQ1jJmy7tvwBXqGCs5EeCugDvXgupV 5GKBuA==
+; resign=20460416024207
+166r.subtree2. 86400 IN NSEC 167r.subtree2. A RRSIG NSEC
+166r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . oGhGxYrHGq0KwOvD0GJ39nK3n349p5PJwh1nc74njLxdSIK8dU9ohOqA +0MebFwkUgEI7gmv5YGsN6QQVFh/Cp/hxFR9sNcS65csNann4sH82Tto uXVEsNWgX7da+64CUvBYDeVPN5isUFoyApQMMohKWJPvDeR2Bs7ZEEY+ MJHbsFICYv2vh69a7yYXdQsVTRsVisWYkXQpyip8uhus5K3pLt1YsfPE 72lWzWHN+bQKEtOysHPCb3ioXDBSJMmS8G07n8bRcbCWB3qfe6LwAwzv HkhQP5rU7KLNPgVOHkHnLE1qTzhi6m4JtivDPvHhC8FMIFYjmXFnd0GL jW+Kyw==
+; resign=20460416024207
+167r.subtree2. 86400 IN A 192.0.2.1
+167r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . wclhILl4EoyJtbRXmxS31p52DjE8pzCVUyJS5TVcCSb6otcVJfabgonj A1YIPPE12usQoHq2yomquQEBB4t7pY1m3WMrp5zW88d0nwq7orbb5FgO iz9vgqsDsxnFbqnLNidDZTiWEhUiHVhvAfBhosdQwggnGM5f4J6b14eg 1QMbca/DOieXPRyHs7wUBza7RsYZWhMUqlRRjvVPxBlgFqck9lziz1j3 hOi8aZUfsiO8GGeOhj2smgR9hOBxqHxJscEYGD3t3oTSl1fP9gVuDKFc myOKmWJM3c6UrREEyzLWz+7SuNh/CbhCKLTh9I0H178nkiQk9EJa4ywI QugAKw==
+; resign=20460416024207
+167r.subtree2. 86400 IN NSEC 168r.subtree2. A RRSIG NSEC
+167r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . tFwQlrO7Nqpu3vU8jn9WXP5NdG6wC3IXY2tfLxRQELqpjRAXEBm/drRH s1MS+dNyF0F0lLucmtl9j2+Iu6h0hkXIIJIKWE3zbCAmYeQ3dQ8JJH/J Hg7gHBv7uqagkTFVrV94LJvaYcFkZBLHrPe0/2vOePO55q/AIvoXkegV A3gHXfOlktFEGRtXw1W4aN48jw8qZ5dLleaRS2k3S1ePInlyAwgNbpSf VDhIKbhucFodupo9MFWJ5NKfSI9NvwH9yl9G9pMeEPJTw/wIZ0oCW5EH LmTysBH1EMxkGW/FVPpD4BEkYn6ImEfdVj+z+b5aLU74N/GbB/qn9Q+T S56g3Q==
+; resign=20460416024207
+137r.subtree2. 86400 IN A 192.0.2.1
+137r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . am8+/B8ro58VTybls4aXEJuIZOJRkorAVvNIAAnoYsHJj0hrIYrZ2VmV hypJR3AOc1AXVEoEPCsTcCaDGGWI+7dnr10QTT2lq877DovzXc2WefJi 3kB90YlmMnz8t+k0GOg0iNby3iGlUT27+RSJXZ/vTjkMho92sVL6sZiq yb8nTkpC7ioZ2+so57bWch54MeX6QxN1Is9sCRqrbAFFNnW/pCFq/cYM 4qVFius3WxlURI5NXyLmfWI2ed8CwE/qUIg/GnBGb9mOFbQyYrDLc58z lIpxXvPHXyJqd4JxdG6aVfdz262ZduFlrjhhvwNo+pO160uo5qEHSWwD ZCDtjQ==
+; resign=20460416024207
+137r.subtree2. 86400 IN NSEC 138r.subtree2. A RRSIG NSEC
+137r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . Jbck/tyncGC0gkLR5c+N9WcR89t9ac9/xqqPdEQAdVHWDG4VItrikPI2 l3eGysPahtWA1+f7D94yJOng7sSbNWtEUdy6b4EZeOnQFh3YAKyntbIV 6grW/iZcrOP9mvX2cSlSokp+p+1tpv904mAlQ7+X7IM+4+ty22qWYgOR FYy6SeL5v8El8H1AU/ZFNCg+4zd7S4u4LOrxZqzDaQasKI/TDhbFSqNN vdc04thKMDGPhlp55MIBr8xWiG8TCpfExNMuge2VyJJwAAMHmczBB58C 2gB5VTgSgF5IEfZlhIOAyVcuN/UIQ/3s0NXWHDuCdoXUuli+jj6PcUVg sykt7g==
+; resign=20460416024207
+168r.subtree2. 86400 IN A 192.0.2.1
+168r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . XKYTQRQKJOYcN6HxS2q7mfUafsa9CPbT9Gfiw9iIL+a2ITwsSys+btaV xcvZzA5Nz+WH/rH7oO0od4NsBVz4pbdDlYwWNBQFmCwF8C9bK/A6LKH8 IGM94cIhp+h0z59pQASHDLckP0d2VCCNf78dCeXkd8X2cSWBoy+9liav l6KUfkxUrQermCyFw0HGRyFYD30/qPFM7AL2fAcWcWO55/YHz9CCkK+W 6kFY8c1vCg6YRnsJ4s1af4YtkgPuQpc4KeMVvERYdzoeQKe07JOQ93KK Z5uthbXXwBvIbTY4cX7I3P4aMJUWiivlvdqkva8AiykfrmEyzayX1swu OQDQYg==
+; resign=20460416024207
+168r.subtree2. 86400 IN NSEC 169r.subtree2. A RRSIG NSEC
+168r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . a4ct19ypRywi4oy0h4lxjgOV8ITjyKBSOOyx9DJXYDfE8Ncs1yp6xzRi vI+/2oyMim94OarZ2Wn21GC920//ZtYKWTvVjl/7EWLjhCSPE1DqfQuC SrWnx+OMUbvRwdk7RLIO67gVbDG0CHS0BWW2uPbflKO1oZacb5l9C+9q wyg660XowU8QN8MPXjvg/tEJgJ8quWetSPmvl/sGS0PnK8D+IQZtavwr H5r2n7cvPjrHyIQlkCrr3outwr8LoDs3tZrRKaI1P6Gxv762z1Uzbmlu X0bpbe+plnneMY8vaKSOkSHrI03fSKgpFoxqfdS16DrX3S8S92R7Q3Tr Ec/KKQ==
+; resign=20460416024207
+145r.subtree2. 86400 IN A 192.0.2.1
+145r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . Md3iiSliQq/6iYPsTtnWxvD6fnvDE668mCKL7aV490Ni3sqD9WSkXLC3 ph6zvb2QqZP8ekVoYQOHVnl0IwsDc9DPdWp5evjU4c2HnS9gIQ89keEL QcjP6aoUxL1N0VGyBBSdD1W0/jrcX3L/B9LykoVNyUfVLq3l9UMTGC0X d2LUwsDEPOwKRFt9pb8or/RXT3TieRAyaIGzE0boPqT5oHZ5o41ycsJD qPEhvFaz/Uo4QxYHAQ4/aobB4jn5N9mOGzopVf5EGv6EAt5UxR9PRY9d 5M7wngfrQQd627Kep5BOW32/zMmYuaT6TGkK9s5SdxHVP9SwgNx/xVWq tpcp6g==
+; resign=20460416024207
+145r.subtree2. 86400 IN NSEC 146r.subtree2. A RRSIG NSEC
+145r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . A7MVtDlGXMJG/qZa41htXBV3f7Nd5Dm7VNnuHi8R3rB06wUOddv/vNxL ZayYNiBe/yEiRfyQoY3sTP4YGfEvn8rr64q8+qIhVNQOzyxreQi5j07e lbjn4Pxd7Yj8BlQA4Pq9Kh/Gf3N85yaSXQEz52laU8DPS8t/LyEZFSRp Iq82toLyt+owNCGREyzfN4tpz+XYNqC4gNYOGYYWeGg/1OZCqcc/dp3o KEj6RHzkUFXsL9K5/SBXRlwjLYV1sti/HvKi5ydcqEC+9/CMva/xzo+Z MfMCjuSaoMKpkLMIa6gsQ32+wuqzo93+yL29ERIXm12MqXTeUxWPr4UF bLhGig==
+; resign=20460416024207
+16r.subtree2. 86400 IN A 192.0.2.1
+16r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . G4AP9+de7xsMvRzowfWmGOaCekdxocWnfuG/VJTEnC0/JB5zXwYGWG1f asn03gvGoVatG9lL5XAvHuML/ceZA7nx7/6A15maAXBsaNhgk8XFav2O h+s2XX0KoQtPliODw0VmwkwWweni/KNTNRCTr0P23dYp6w4jMv6BEIgi PB61Brz0jncB+HTri6VOLMQ3iFPXkEqDscsxjzTKoGxP5NBYoCnb/WJx RzZerXTUyNGS7hHCAqCU5GdJvZ23ZK9flyeDfguOr+1CtiPGaCguEeyY 3irZOasoidv0Nzh8EWEZBHyaqE5ungmOnXFpZ1OIsBcmpvEJK7C6gHUR Kbgqxg==
+; resign=20460416024207
+16r.subtree2. 86400 IN NSEC 170r.subtree2. A RRSIG NSEC
+16r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . Dxz4qBOcfOFrkjBahDF6DRVp/ZVBRs3PhONIr1abspr4oO1Mw5qsoTlO XB6T/S0W00xNqYS+hkbw/NbrXs+Wdxt3EyDDaPBj9UQmaVKpLVarAOPb uVPU3Bh903HjVNokRew1FQokt21MQNvf+3TA7oJhJO+r2jNYW6JPQ2DA lPzuVo7PLvF6aKyR0R1Q4IiCeG9u2r/TwE4cijzCF1Ks4nNDQQgRnf0z dKL+afAkZ3IGZaktGsVvhQbfYS4QK9HSq+O9rwC9KWHcmOptETlaWE4N mlgdf2PaEvdvkXh5P0P6X9lTsJ5v7jt7dRyY5JulCTf+3qxq2GQTiZKV lSJvVw==
+; resign=20460416024207
+170r.subtree2. 86400 IN A 192.0.2.1
+170r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . tWZDCsmC7lCG9c69zyDtiK253sdW5uB8sUg4ZAhCwqzXeOnja7fHd1Hw 6LXdF/BZAr+1TfWF1G2zlCZt2HgO2/ulc00ae7r9Gg0Lmc9xHwvrYUjW KkxCvlzB28xUytRHGLBjagYdIdQe4+O6GFUdpWm9UmfLhlZYySV9Q5Zk 7iJfNhRHEqALJxC/TB/mYBVapc8mODZUwvRVzxWJGoxzPYhdEQ/SsISj MrP91NojvPBeh3MnzPfTFwFIqmbTG1iNje6oY2JM4uFVchufF3jBRvBx HNkMb4IkdE4xCZdLKSZgtyG5drb/FuFi8u0GpaaJX9/PiojPbpFsoIXN Z5vbpg==
+; resign=20460416024207
+170r.subtree2. 86400 IN NSEC 171r.subtree2. A RRSIG NSEC
+170r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . B1GDYFzFdnB8bsoPCM16C3A4ij4kL7Ohc8AUXmgUnoPdowdAxU7+LiI6 lJqc75i9v/1Q3VfNMT9ztnk0S+XoopsjdGmU0+uj7pMGw9jroF8k6Q+7 Icjh5J5zlU7Z61N/P1qsgr3nLYI9ehaY35BBxPPYmHD6+tikAyUVTliO bk13vLSVM6h/hJKZo9WZ+lIiWtvonXcgST0nr20cahGjPw0t3xk7N7H0 yxwVqDTW6ZWREhQhXQmRJeaRieF0YSXs3TWpRjaNDOmA6/R5tIasCSPo ka1TAvAQsJLS1zGhyCBbtfTy+RzpZX5AFXA84JMx8sztR1KABJmyr5yL wjXPHQ==
+; resign=20460416024207
+171r.subtree2. 86400 IN A 192.0.2.1
+171r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . Px653LHulvqO8jOFEtBfBo7HOueJqdazMo0RyrGcGcJkeg/n+jfjisHK q1gQbBmbHSA6haP9kQ1vnNFrUgOfnpapB3IBHD07XxVE5arDlKzq4ibV 8+6FONagFSljXPBpLDS8e7b12IN54LhtJW53D8dnyGiyvIbnHMz8QkLj zfhG2kTVIsRPGTAiBHZ0tlH9P4y2HEcUba/Zjr15cnXwMWMY6IUur8Nr QrfwS/LFwoTFEa5NRJCAZB4Iqf+dzL1id2wlWWei7aRXUvqBEtWD8l3u ILQB+UZYUJaStVLgYd+ygvDhLukhRpQFryj5QcAnAXVf9vDQrze5ZXV8 myUJ8g==
+; resign=20460416024207
+171r.subtree2. 86400 IN NSEC 172r.subtree2. A RRSIG NSEC
+171r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . vW2qpOg6NUTT+BrwaXYqbtvgpY74qo1RWHkC0yN7eRILMu60O9cAowxP aenIu7c+7O4xtRumUOhH0P5K2XWdUtNvaA/jlKcwo8WoecaW7lagRj1P 0jz27/rtW7Mlr1lk5srSWFm1UopvGdAFw+3W4u0mvq6zukArkvDPvCVu UvGuFcHaXj7YLGxfWY7PNgs6gccQSapbmAgKkzc5EaJSzeY1kKzh1zXe tE1RFORiuiKNrDUBlaVm3UDABR6Q6566m7SrutnvhSDgOsbdMP6YKR9a oZtKwgcaSDdH9pJZSGttyR/Tdav9emt1hfh9Ty10VXEciKAJYUux/Uer EvVDxg==
+; resign=20460416024207
+172r.subtree2. 86400 IN A 192.0.2.1
+172r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . hbRpeJkC2TvCOHEBZsddt+NkbOjrzvKuUCD9u5n0wpXl6JhwMVXYkGuj CXIMEk6ytNNJRDCGtkrEtWdr4Ou2XROX3LY6t2R1vl2828n0hLpfSJk2 aJgyLb/9UO3LFb6l7BNHFWluQW/Ap2OgqQjY49BsoFS/ltYWqwRmyU44 bVyFyUUBuMGSXP4xtMw5sCCAHZz4ReCaJ7is0BH/vlLVwv70CYyXddAO Ak4ibfjX7drnWfZQ0D7ysHkAkFbeg7ryEWhAimQlykn7TTK5wsv/O72j 3r0xO/oI4LBupMgORamWuewuaNxk9zYoeMsfb2px5GZoUNwKhJPCnCta BYgsIQ==
+; resign=20460416024207
+172r.subtree2. 86400 IN NSEC 173r.subtree2. A RRSIG NSEC
+172r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . v/sTxRVW2njY0M0JGbSnnDQAW/o2G0z3YkdSKHFUJbsBGwC5eFzdbmE3 uLnQCfu9nXNv/DS1OZGcxjgNwcpZgrZ42MHn/QjcazQHlUEjvFUg1vEe nubJVc091esJ9NUS9+RPdYtGCHUXAwT0PerfCrW2l7JDSJuL2PIVrnvT DhNBKGH9hBlYtd0tRwYHGCSjk8G5ptAWjfQCwS1lrcVrF4EPAfxRya++ CXwivLvmPVoAMM946F0dPh0BSq2iF5BTEUNhNFroDg2XPsMUDm0eCoZD H4ByK01fNR0FiUUPuNYyC3aaFi8HQ3uhKjTQuA5p5F0VT50TTfFiBQas cUzswA==
+; resign=20460416024207
+173r.subtree2. 86400 IN A 192.0.2.1
+173r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . guKL6dmbL2dBabs2B/mMtO5qZ0LNyZbzdZ3i2zM/2AA3ipz9LhIPnhwb KiO5LY04IUboeV6d1q/QYJJvVWpZGVmosS8N232HK8+2/LYD0NoGZTlI QhYOC948qMmfnBbEaXfWQ9pyAvkmLgJAwQRi/Ei7x7DC8xx66R/ibF8t xcp45wcH4PMJNCxE1lNSmHLu5ZWzf+hKHo4H3w7Gof8LiuVZOEBXVs4/ j5yeExAILi+vXAnvOuNB2+6TbiLgVUOrj7ixoEaK9rvmhcAv6HeipPoW TbUjt4oGmeE7Zmro9rCPblHeEp07HAXdKyDfkRj0M9NRHedW1tLTamLi Yd/yxg==
+; resign=20460416024207
+173r.subtree2. 86400 IN NSEC 174r.subtree2. A RRSIG NSEC
+173r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . qgYaLUdwBspbKvhBBLxy7ieuMvegHlw3eYH250W+pmMyJHs9UGQq/Yv8 Ic13KxjYjkDai1fxwJjbZIvNQbFfXg+Fb0ZapVG6O0FtksnN6arKMfgh oXkhwSlp/xUBFHiVUAoSgPQHGhv+OmuNOQvomIuvWq0kBEFYnr2pYT3Y NTnEtf16t5Cw38t1T/WfepZeeqG9uNCJxXy6L6ALIQvoHy8nNjq+1n+/ nc1oee7Hf/zlKeirFMZKV5CuVlkjwC/n++JZN/LA77vew8uXk7jfDUpm taFXNclFyZHdWs3Wle3OTp9DMfIYx9AwiZGGjEW55VzyB2r7Kf5E9n5z Gz/UMQ==
+; resign=20460416024207
+174r.subtree2. 86400 IN A 192.0.2.1
+174r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . mpdvu0jUL9Zw2Na2Mm2Rh/D7elKhYU70IEwJokldQG1MjGz+uWA40EyE cfgrPF6NUQWIaOn8s0/zwwpXZ7tUZgUMpsaYTt8mHLgthPa4KoH4GuM2 bEZvtivUkmrMAEHk+hKt135f4COXeYynKYNnqs2tSoKQKcPVtWEqTnzo 66HG2B52C4xEQCkt/ZcmHpblUPyvz1WPx91oCOs6DNdUBKe5Txwp0Oks 2qTlEmXUPuPRI6vxG3HvxspkiVhEmOPSV+mds/A+hWSj8Vjg6rMSgloa 6d2hpDccnh4z9wifIcI/BtDV8hyV6cCu2eBw6asUzHDaVFHA21iTmT4S U+8Pbg==
+; resign=20460416024207
+174r.subtree2. 86400 IN NSEC 175r.subtree2. A RRSIG NSEC
+174r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . jM8a2D3Vs2ov8hKGWdijThYZx1fTS+0NGNUQP8Qp1+gSQ5GOJh6jvqGf 5RA0VDkg4wPozglhkJlnxcP/OrMU6A1Q4pC5VxBbYjWhZW7QjqW/E5AP coCpR72TbJh83DKNnSf+nYcA+Bp+FNjxFppVwwSaFIvEQi+NJqAqyn55 pjq/OXlZJ0IfxYlHxtSYeNeYAWfKRj5o70GNCJDSkrfVC6WgZatX/UlU EcuhzQ50GV+O37tTOTWf6JMhxlU3yGhMpXMkhVK2sO0p8H32ZXiDPD8Z ufaMrAORHbmGdRaZA3tQe1eyHAJxidKONX74/YfIJlB46mKPUKS2QHi3 w8xANw==
+; resign=20460416024207
+175r.subtree2. 86400 IN A 192.0.2.1
+175r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . utjEa8lBcuP5lS+jGFix4ZzVposyVZLmUFeeQsZwtwqMI32KQ0affOl9 fvid2qo8FlSmOwwB9RhZaAH/q3LD95clwvOrkROxGmOPuMeoCGo5d1jH S59+314ROpaiNyA/CC+Gt60wc+v8n9tZmhVAKKAhlE96PARCRG274bBh s7wc/W7Ip2V2aolDHUQst+rTlE7VfsC5OgzRBYe68ChrUu8F1ahpxytu EkBvfClukGDGWxpckG434mEfPVHcJL5QsorB8tDkWcSo41igSLDl6UMo 55/tXqQKS/KyNZ6+OE42tunoQSpVFXH2hUKpEra7cv8teuWmGTYHJn4p Dp7qhg==
+; resign=20460416024207
+175r.subtree2. 86400 IN NSEC 176r.subtree2. A RRSIG NSEC
+175r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . u/JMoUNzUyurSpl/q2TgTl/enDjpWoL2AqkCaKePgxaBNbyyokLUPxTR O2LRjFWEAo4gQtX2UAM+wfAKOmKioTjlSg/y0J3FAWnJUwguhjVZTSUY /vtUmI/xrBEG7eIezzIB7ibJqTwDQf+AV6Z5PPsl9yuT0t4hz1biraGM o/axt4o7nkoo53drcP5CnZ60RVkrJi2X32DDizzw3C0aCrMM1egggE5d /H26v8wUiFU1OVrNY+oW2OWB6UNNl0J/vwoRY9++uKzSE2janv2eRr68 Auz/RWlBgicvvjqKJX5dYR9C2j01IYdPzwGksLHFdMguWWFBDdyHlYbW u/FH/g==
+; resign=20460416024207
+176r.subtree2. 86400 IN A 192.0.2.1
+176r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . uaZHB8CPM6Qj8LeU0Uze9bf2AReNgfwt1MmkZ3u7i7HGrztentHGQrmY ONo6zKAUiL8ZCejno4aIPD1ma+PqFoeUWxh0QNA7hPQbQ9yjlBxUfhh2 3OkRfN1AKx7NWsCZ/F4nVro/VjF03GZFg89FqEt8cRHZvzE8EvlU7xVb YZu0f6CRL2/SIz3MWODZhJYpurQpuGi62G8LhCCmeaTYJb3EdXo3Rsmg SnhTGK1atKuawNAtwuTQgUD7Z0iUnUCEkaTtUGLuhs5qmhF37erjJWlj vuWCwEDWpftzXTQijxj7Rg30WE6iI/VB174xd6NpyxG7DZ/2HdOx9CM6 73Lwbw==
+; resign=20460416024207
+176r.subtree2. 86400 IN NSEC 177r.subtree2. A RRSIG NSEC
+176r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . AUDXf4nZuDxYVZHFkcegqpTtb0KfqdtlWBDu1i1IGwi5HID+7tSuPgzU 1mnKSMjT7CfgMzEDWL7R9i/aF5+f8OjwLo1J9EVxBvLyl8zXoojy7SvS ix7HHuoJIr4hkCLSA4YAdkVq1OeIEiH3cZMEsPSBopi55jcc+Ixbln+h XowJok5Q/cV0mT5PD95XScGLhFUKqV6B9DR+5ptltU63sgPkdEhXp31h +ywApZcqxRCWIaJ5bSUNeycLpNTmBmupDwNzFvgPmI2tufRQPKkwNeC5 7AVtfd9Y2uKKSgSakhdiIJ+lcOPNfoF+53V4i/u5CKvn/VylJp9mXNJu hIebEg==
+; resign=20460416024207
+177r.subtree2. 86400 IN A 192.0.2.1
+177r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . UxCDSPBVRcEDyJMsTe1B5Wj3i0B4ppCNpIutplRGK1TcWlCoaoZYKb7n 78C3wXFiICE1lbj4cnHTeqSKLnUTxI5XEL832lRZmu5qUR9W8nhcSxfs YzdmtMx1VOwcZAo25NM+0883J2hXkveuV3GjtkSvaZ2W1zqMARVi0dDQ z9RT83gHjwLEmL9zPbpSdmj0OOddw15qOQNmXEUJJzZzaIPMaWpkpQIZ pU5peA6EBti4LI/902HEzJeydwZdrMa89FCL6J/UIoxUYHrXIugsZkcE ptptgPQaW5WNizfKYqanNhN9JX/t+/u8JMM1mIk1zIejiwuKtpZpj3mQ WPeNFw==
+; resign=20460416024207
+177r.subtree2. 86400 IN NSEC 178r.subtree2. A RRSIG NSEC
+177r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . gZTPyJ00JsyjTV3HsyTnB5279LPKJIibVKXDdEwU5148kvBte/nxxN3F Df5x0mPXbuERbWv+DJ/9/7vZNFkXt6EDkU7Ec8JAdGtj2/HImn3TfNvh 131hgK2h0ynNlsLnLRncJqe3gs8CXXQur181y5gQs5fAKrWsVQByLINb tTUDtLOffOvP5520CmE2Aw2u4JBkxAXQOqX0wAHcEXKS9XhhJv0IqVJS 4UxYM7TefGTFq3uvYKdIR4FTGcRE+liwpl4yOIITQ+24ik9bQcyMikVc lCy5ukMUciKP525XqEAgfSpTCefmiFaf49yg/FJuft4GA6vDbnYkFOCa S947Ww==
+; resign=20460416024207
+178r.subtree2. 86400 IN A 192.0.2.1
+178r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . PqlL+UptlSvJyT0dD+Uwu6nKTXGPpX9lhRrAp4H49OhSMI5CU39Wa7TF wjRYe9TtjYKjWtu8vEqzYPg2jTY/ic76nv3l8BalRIPKvwtQULuLmZYl LBL8h9JheqSWi5MPbgwt6fm7RJ1rcrHNYe0oHmuPt6JPfTLGywQFh9U6 nWoCa8y3xuOFgu3n8uJ+aDCl+VwJp4MmJvXygP3rHevpC27AqBIQdFc7 x02xrkWClVlfXC3PLrRvWRAnrVYjNYzFyT8TIe5ABt5oJ0I3xI0d7wgh Ha9IZd81bhNPm1wLtcBcK/X+ioxpaprQgD4/1QWdnUywRORfgwXpAyRA H9DilQ==
+; resign=20460416024207
+178r.subtree2. 86400 IN NSEC 179r.subtree2. A RRSIG NSEC
+178r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . bMQIhE436QXSvlMOTipK1JC2iIZFmX9G53UkCiJtlSgsxSsdJNslyXy0 Ejv/MaJ7Ljh10OtZ6EKy/kv32WuQB3jvtbpVbrfcJAbzTF+rMI9O69Fp KZSZXBGKwX2hy6IyfCVXZS9dOQS9BXyfQH0RevNr0+rf+c8tBwJyqgiR xyj89eCBf7odNHzjVGGPuhgT4MDXGnrgqoM3y8AIy75CpX18PJK7FkS5 22KCVh0Cdp2eFowltyaJm5K6qIOnkYYGwXRK90pTgZmt+VYgEx214/Ge mZx7zaS3a6+/UWgcuAiLs84iT2kWmGERjeyWwURJZT13IK08EZ3/mzLy d2zl9w==
+; resign=20460416024207
+13r.subtree2. 86400 IN A 192.0.2.1
+13r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . sXsgdidETamVj3hMGclONQ3xs/5wp/1272MujPM3+3/gKvVNa5VEggXS r2pA5t+Mk4PWuUXLog2ihyAi9Us4UVNSbBMxvXnq3fAeISGPm2QonTsT O312FEmqWcWyVv12sv3BVt/AEUl3O1YlPICr5XXLHRmrj6KF7ITZPy+g DZd7bseKOArxNqqsU/Gkixz146yV/IkmYxD2fQmErDqN9CEYkZ966f6I NMhTyDACGAu7sYZObCw6ruBGHik6Y8R6S/R0viMq4yC4B9TZEAsjyj7O FS84crAXdKYj+zywq2BUllrMVup+m1TJOfioxtXT7O9MptZ/CZM1qErr +nAwTg==
+; resign=20460416024207
+13r.subtree2. 86400 IN NSEC 140r.subtree2. A RRSIG NSEC
+13r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . f0UIocyE7wUpGKh6HM0renbqeQXha9E0ILL8OU+9wW7Kc+we6u+GI8M9 y7FQAlGIhm4ThMWxZE06TgwudtU7deAhEfryJdsmWjW/gBLmnfkSkaLU 6XNQVrVpCwR+DcFXvH1zasDrYZaxGc14BOZVuh4/HP5RYm1cQBA/cYX4 VJDBI1IYP7iqJEJyeYCmPDvgUZLtoqw1i7rey0qv+0C2yJ0clqFHScBU 4S/A397GkHzge8i2gfn6L/5r3PEe12AoBLk/FUQH12jjqP6VljOQFSa5 1Nsz/nj3SvoSqNIWO3uQ/tT7WwKxcYGEwOSB4pXJUBGp7jsoWPHn8kWC yW33bg==
+; resign=20460416024207
+17r.subtree2. 86400 IN A 192.0.2.1
+17r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . qqay8a9aVj9bppnXSWbAAFQRl7FgyL1Pc5BQBktPBi9XV7W0eqee2kOR jL8/vmYe/EkXkc1xIgb3gonQV7mojtkHT2pDckw9T0cY1htyYxJ/nyZK 3Ny1/SvJHTe1WAPxTwd1ZkVZ/vkz5FXl/uTeJ+nCq4JAlPnPviKPk44q FTeRdSOdEF0An9H75DruvlQ6cGA831gEUoe2oXiDEQeQW5wM2wfSdmNa FG8tshu0EGp7Ss+FvJ+x61rg+Qv/B9V93Bc8g7YSl2ugalOZu7Mu+sw7 wGMAsnuw4IMWxX8L9dlpQQo+9/BvXmGsw8715njG1mw+EZL5hywUXG4B CILSSQ==
+; resign=20460416024207
+17r.subtree2. 86400 IN NSEC 180r.subtree2. A RRSIG NSEC
+17r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . AMLTNqKTOztHdQJE0gthIMmfuNJJNrbWyt6xUiY/1Q+SABIizXRCF6vA 9hbDuQ0uAHybELbw+ge7ebkYVubbucSU31ukzw+F/E3s1TeXcSr+V9R0 lft1YlBgoAwE8tqj8ZqM/4T0OdF7GoXFx/yi9blme/1o6dnRzLCy4uX8 qQ7G34k7c97H/a8BJPNFzuIZ1xhuiBpaC7qf0VS5ZklQJF9J5nczMtNC R7FI8OCKeq/+XAW+43vETW3p808VFwjVs7qBSCEYG/zCfUFINDe2SOVd LyvoI8cRpJ1pEuQsQkJT519FIlkBLXULpB/xjivT34vdGU4VsMOs9e8w IeMXuA==
+; resign=20460416024207
+180r.subtree2. 86400 IN A 192.0.2.1
+180r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . xq1SIKwFhr2vnPWv4roDf9O3ghr4e4zAc18fVMUqx9shSuP/a9WPFNGD OwVLzVC0/VZ3hsOBy5rAsI6aIplAKdhGL6PFMv2k44SSweu+dv7KsqfH qNm8ZeZY5prxBEe0V2/blXpvk1zfV4AP/ZBvYNtVf/tacbqa8UqfIUET 5vtj0LhwPQL9R6OeOlkBhekX1/4w8Ow9lDvsdcphPHwuQwLubRWdmdKN AdCAOsrjeI76BNfuRn4wB0tuIUWSCP1yTmc0vwvfAn1gCCXNyLzZwgR8 Aeff9SGrOpSHC6k3S1HP127J4F08R86As19PYX5q85EzO5J9X2lzVPdZ mXFxwg==
+; resign=20460416024207
+180r.subtree2. 86400 IN NSEC 181r.subtree2. A RRSIG NSEC
+180r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . ItEKZ07Ib/R69g7gIconfMxnTDiEkaPCnuJ+Ii6a4u6hJEckeRGeTkJk 59KtkxpBQvtWydPIJBOhPkahRa9Ru4dNb2cTeBCPeuAEXu0hLOOon+h2 uJSXdku6q0JBF3dNvV342F+9pZzWlYdKXzNPXy3YTJI3KPm7fGCNqDpR hsNLdjNfaTHZE/Y7x41bCw9ClETa0l+H7ToSNs5gJS4X3a7crxOAbPJo 3cFKbgwGJ6bbzvEWMlmurRlzzhLqbq/60wFM2dRjhY2Ras+c1klh1rG1 MuQTUsbNm7VRw6W+RsYudQURzJ4jvt3b5dYyePtmz17ClO9Aql3k16zO LaiSlw==
+; resign=20460416024207
+181r.subtree2. 86400 IN A 192.0.2.1
+181r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . QyvJ2cXDj9HwoqYzIB2Uy/ohHfRkbQEF7f+X1FPiVF5WUVNOi7PWuNNP c0ehr21bZXAp6ZdROatrkKdO++Ut8U8O0DfqYdlCBJNFNvuivf94W2AZ 6JnGDOHcOtvZq+vilxmdwXOxi5DMr6FstNS+qlUfgy8Y/PLnm2GKnZj4 n4cYCk9/KQNY6V7xB6remD4oqqJwDX+Q99VPjz7Pg1EW/GMu0Re5ri8Q AAhymV2j2ZgtmkxDZi7JMdIblR6Fv3sD3Sn4lmnV+8w+cH0oAX3Zw+U3 cr/SjGWyfzYpiAGs8XTO94GXpPSRHOwoU4bs052c8zrYSRrAfblejv5J gWZA2w==
+; resign=20460416024207
+181r.subtree2. 86400 IN NSEC 182r.subtree2. A RRSIG NSEC
+181r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . P7SN5d7c0OgaJ17/MVKultmuH02Y121rwRoJ3hqDo01Xv3T2JmiNhDid Ij8XiZb3Q/z9lvOjDY2WvrDsNMyLi06YfbQ1wYkibobkiz6qY7qPfI8P KB0LgEI19XFcTT7T3Swz407URR7nHipGfBeAoeWUiHThAdRD26xZzhJA IB9EbTs7a2kNyVMovaXxJPq+HA2lDxB8fo+buSdzwq+bFXhzZqpzY10G 785jT9iRz2jZY5vFApisqt2OAh9HefOfxcYOhicLvf2JxcGdPHt8YZhY i2Yjd3sekq/0hXOej+Up+sJ/1Tdkkxgbb2egVaFRgK3rN2XYSybJsXSB yvhgkg==
+; resign=20460416024207
+182r.subtree2. 86400 IN A 192.0.2.1
+182r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . SwcpMSUFgXG1DPNHv5BBBrxviDsdjj3P4ee2pDUNeKbLpsvbydpLari+ 2baprXJa35WreaHmz5lKbip0g7wlCePvmsfPe2Voa6Tc9ZGKi0Xtp91R gug3QL/PrFd1rjClMCyOdXyrrN5jRXVvEs4uY7CNS9qZVj+JzVJ0W0ap PYO50lYbAW+qNtYSSXhOJ3qlNqCCyYUMXaCmMvSI2JOC5pmxBUrhaqpW jAjt7NWi2GVVexj5+OUCCU01mdvLX6GwxWwAUJHq8cJzrjRag3p14Fj4 Lim0zf5fj+zBJavEN5TeW+2O4D/Wo2EcHP2XUbC4xrVzL2POSliPMbgk +QXSVA==
+; resign=20460416024207
+182r.subtree2. 86400 IN NSEC 183r.subtree2. A RRSIG NSEC
+182r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . pFiBdRGB6jTW4IvDdn/kM5mYzDQVKpCtk9X/zinOe8JHN2jdFV7voDfe dOu7jNE0Nh7VYlcIyJDp0SggthbNIcKZrkbeXTHiJz7svKMq0LMkGuCM p3QyKmyC0vBOgGrcTMpMEwP5dJJmk54WXMMXodekt2LiUpdo2R1p/Q83 z25wbZ0+UuoZ4EgaFPF5evLjX3TgNJqavhNwO+u5ldX7mUBOHTpG/O0F 8OKv8AoM+el69X+9irqklleF0LCuAlfac5yM8Ns82bZS1c8qnercNqUI CavjgGJAOtBpexVi0eH5Q6nLXf1OMXmc9lqtYkQ+CH75h7Hitbsfs4ja bMPkCA==
+; resign=20460416024207
+183r.subtree2. 86400 IN A 192.0.2.1
+183r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . wf0jrowwDmc4nXD+HHbB7zEnmSZrcJexZgD6pVG++RHkXx+LiEFwJr99 Y6x9D98pNC/o9+UpaZ/Os0oncS5RuXf0O6s+CqHIfAI3aKbFJfI5AoqG wV7YAPaSoW34IxPvDk/RRU0sJDxuT4W+6T3j/awaA753VxlgLKfvTmir S4XBaYPmwxk8EQlFpDOZFijwoP7/MdgKDc+w+0uOI3ASs8AY0Yd6Wh7E oT7iAn2y+iKeMzm0g/YIxPk9psgl048bKCnVFOtJq8T2BEMq8yhkr7/p F6RAF4d/VxTEUWFVbKWSK/6GSMaO52zp/pEgnf7ff3tifTokHBCq8xHb c+Ckfw==
+; resign=20460416024207
+183r.subtree2. 86400 IN NSEC 184r.subtree2. A RRSIG NSEC
+183r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . kSxsEXVu92hNUo16LnQ8x7Z0GgejAEgZtujfYXDBusVRxChY/QGAvzfa qCY87MGehyXc0dVGHJgKnOFEPS4knYQfoyAlyW90h/c0UMMD0za+VWZU 145m158hgCsqNiWoCWl2GKZZuA0ObNX0JcIT/7CsxrP+nlCdWuYCVgqq JCsX/WLcuzZu5mrPklK8dyYjZj3rZHqvFGkInJo/M1Ey7QB46KD58jHA kxw6YiK3tezmf92RTyHTv/kXM0dpgyBWZPM5D7ICc8MhOrv3B7V1T9ir q++8Z7/0jNhnjPkoH6zweCdRqI62PbKkqdnqfh8Mbe7xz4iIEAE33w/f ELq+mQ==
+; resign=20460416024207
+185r.subtree2. 86400 IN A 192.0.2.1
+185r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . fo8NvlBCCWNX5TQ2kfgtfnwS5HMDvww56htGU81xFLaRe5Vwh/8mqfQU Wy16sbwRGfqL+0OawZcKtuQvS2vSkeM7UI5LZkp8mYNeBozlPNO8sSI8 zVNegW07ykZtlftPnnnpjjMlmPnqBtFDxMKvjqBYJpiw00YD3qYPDbDt udI6j1cLhygruBDs0I0QPtZqUqlMxFES+jRtMF+pEK9XRF3N4Ibn1R9J 5ITbheM6zfLn3dU24raZQ/Q+sKM3ezr05qJMXewMDj2E9CV9ov166QLH v3cAH7o/dRJueMO+iUZ6YLGe8RsNCb5fhgdgp9ey5Rj1M0UbtVQOsbrg MYOXFQ==
+; resign=20460416024207
+185r.subtree2. 86400 IN NSEC 186r.subtree2. A RRSIG NSEC
+185r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . eWHh0SzUo4fWaYotGJ62oN1/on4/2os2nV6/EdEN2TMHcVI3JYT7Q66d /JjWJbyGB3UcfJXO02nyYcHDzS65DTdXOwcx+G4QJaXvsf1+3frSnqD3 RMm3PGrOxNe06dmPZOAWir1LJho4VjzV3aJQTmC10TE2vN0QcZryAeKe 5aFHva/DoclqvuMA4V7n3XOL/tnfZ+hK6LD38NetFwSUGAspJ/WSxQMC aqEDoP9XrmOJE1wgsIe0IFn7CRg5a84AJ56YIy0TXGgN/GFNSkembXDl latpUOlQw7XkdaxpXFfAAz1bmV6VTWMU4GtrspJSIlSIsYrcXVYgkFwj vKUIBg==
+; resign=20460416024207
+186r.subtree2. 86400 IN A 192.0.2.1
+186r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . w8I8vrnUjIPhi21ByPsk2oZ7ozJsrJoXDKSdsYj6+pq7bqrahW22IzR0 CmIxw8Kl+woQ+I6wui0lSJIqaPf4yr/eXL6fVHde3Clu7+1MPHAJZ2ss FxZxUuxuBXMTp2JzBYuGfZV3sE10Tg/DEISwC+ZM4GqALc9LlGPU0AUb EXcWBHpi2NeA6WKVR9ayZPZnG+mjWu2Lb8bcFtwilHadmooTDsEJX70e HmFZoixX54yjvkixWtNSmJcIveXYyevWTrXsF7orzi/WcsGsdCJbwLzc bALgvwxx7MuySed/M4AuN2L10su+jTeJfo5AX6tCoIdA03q9ATSDCES0 udG/zQ==
+; resign=20460416024207
+186r.subtree2. 86400 IN NSEC 187r.subtree2. A RRSIG NSEC
+186r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . OLNBPWMExsjmLeTQco5tvaZdupvyZhR9mT5O+6X9FRXz8srWXc0y7Vsl vk2B2YwzyJyXF3Lp5nUveE3XS7bPi5wxZi9dPa0MO5lVpmGfR9ju7Bzr R2NPMnEqdk0jk6plCqzTJBpT0Tx6g8RiR4Xp3O9UN3o/5zs7eiQtDjf4 npy6fAJihRP7xNd5qk5PwIv/cjx9j04L3HUXAh18oc143mplXBjUR8nw Zkmpk2hsZm6vYmGhz3GIGM9jXc+wzRkAVUj5NoMTa8hDIOEoe44E6+zd hboz+s5VPpjkTN5PymlCiAMqYN2vUfHmRhO+iGj+dwyLUzM+BCKTDWUa 9Zx57A==
+; resign=20460416024207
+187r.subtree2. 86400 IN A 192.0.2.1
+187r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . dIDIozfz1Bgm+ZML/5AzrX05Clt4mebu7ymZ+D+LHR4NOOhJ22gBnuwN LhVhUBi2zSopTmq8UxrL3CJzpbGBQFN60lFMLXt4RGTag7QCZZnTHXD5 3oK7VU67uGtjVp4EYAcrlIHh5NzHHyrZkydVvJogYMyG/KMsh+Gqi6hu +6RvtHInlxdzD0Rc1mq7bzd5iYMBB8dVFC3eFTEf3SBKIpFmLcJ2AnF+ 6AZEIzKg7D3zUi67A6Js2jJ1pIEX56KBmW0hHDfjSIkHLxECV9lRbx8+ p8qqhKFNqwk10TYj7QWcjWHfh3hi7UAQc3A7hnTFun44DHTybjojQ3ac 8Plu2g==
+; resign=20460416024207
+187r.subtree2. 86400 IN NSEC 188r.subtree2. A RRSIG NSEC
+187r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . WbioNojsR2o+n8tc+LYffEJFEmyq9W1uxT4R7pKwFH/ZJI7pqj06F4DA 4oRElc6NPKbwY95Au4d0Ys1Pt9zpeWIB5gzepDT300n6vne01CTtV/zn VA128Mywb0XsGkoKQpyOAXfApuNMwr+ehjsp8/oEITV0XyPtCOmsW+Rw ykopYhd0BbwwNBgiCsDrvWOvJCrRG1CNAOigKeMpln8SDCUwsA2XEXG0 YaSrnPGjJJqJzvPpJ3Ou13PRNGcyMCofqn9cNgxyKwwzthHoY+KBjrkz bz09228nhuICKDszvot9zI1HgWnVFAucdkfeCYLnQ2/gAbybsDIOOJqO rDOybQ==
+; resign=20460416024207
+188r.subtree2. 86400 IN A 192.0.2.1
+188r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . tbpdzGbYXHTgyeCDpJrZWppotY99N45bXmBtCPgcLLjdPcnpGlmyzEsG Ff1AIJpl7beUHJlforTD6aYPLVKNuFLIKnPti7lKHtd2sY5aRUIOfHrf 689gPeobI6fylrYlojmp1EO6W0aSy+AJrZf2vvmi4dmqc7WWn2qVSuQ5 1yw8fVa6C3GVvvVmia6wHyHIvTCqNjPANARSove1y5hVcU05c8/SOcwI rifwaYiarQ4PGYQwDJCGAfR6D9/VNmEoVH5RYlpeghHUOVphR9OEprR+ GxVaAi7xSuVzh+qsFvDaU2zsVMHC4WTIImxrsFufax0dAjYwCGTF0OVq LybCjQ==
+; resign=20460416024207
+188r.subtree2. 86400 IN NSEC 189r.subtree2. A RRSIG NSEC
+188r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . WtfODvpf3qTum3G8VHl+Cxtuhl8/oJ3g8HeUJwCF1FhDnKegjCjJV6qY rbP9N+mjqwi/CE1BvKAT1hsrWiEGk3TTWX2ss2D3GKjyH8p8Fvls0GzV X4+T3IwdPhFshoMCtOLb8DhxYp4l/tc91HgosTF+mJP5LHJcFbYcQEtn Qbwzs1HA4t4+8OHN6jVSDwbydSt8DbQidI99p3i2YM/Kg4PUPpMhuJD5 tEuUhxqDlk3tKGMh81WAk3XU9Aoz+AOu541Ko6agbUEs4d3Y2SddtAEK qOt6m1/vUPvDn3Q6BKn8X8oB+S9Msz430/vIPQoxqMZogc1hnZu7Rank tB/ceA==
+; resign=20460416024207
+189r.subtree2. 86400 IN A 192.0.2.1
+189r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . UL14E2kx6xvEAI55fX5qi4vnpfvk0XJ82EWo8hhs3hp25zNt5sd85jzg TlNr0x5dxbqFnxtdCT534ao/8Gw+zPvHxDmDWu7ygFpDTDQYub+zLVqQ PkUp/vZlpLkZ7OVjY/84x9tiQr8q5/5zGwEL+/LhUfn4ZbZo7YM5BnDu VhG0pjuSv1vbpwVIht5t9HVB/1mBsgI7Hy5AewNno8WytUzcfm3pt+Zp ns1bI7GDRvranS4y/cvcO3onmsshLmOmrWJjAMyZVHxHIUNt9RIlUJQC s0zJCcOu0yQxQnR6Za1KQBG8n7ZuWSvyRPLBZvd0OAWOJjKCBqtCof5D nqcRoA==
+; resign=20460416024207
+189r.subtree2. 86400 IN NSEC 18r.subtree2. A RRSIG NSEC
+189r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . cKcDMQGJXcf3v3RfLJF1zH1zleaK2ILfHWSb7+hB/Nm+mcLKm43KxWNZ rVJZu7EOUj8M2cHzm5NwEtmZm1SBvxa0NHASwavhNT6VfNswOxkbZy5P XanQBQ0TGc6PecbG2l8oeqhr8/9fDjyYmbN79Y73gZ2iIAIW/CFmLf2v GQ53Ct9L144s8KvxfsUnpDnob7pDnMBkM5GaMrbpgMXcdBgUnwRKoJJB uXxyE5yP5VFuWLGH8rOEIHWKdDRos5qlu/eM/ZZIf47nYy8G3rJqTjNj eCZumTPPOOdMI0jmXBJyGSkVaKQgcHjsnrfVTJqlOOy8dT/Yls6H8lV6 CBCXYQ==
+; resign=20460416024207
+18r.subtree2. 86400 IN A 192.0.2.1
+18r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . Bd3k5r5o8uJIV88DwRHdF1nLGzEQ59pHGw+1ieisxP9BG7yxyxZIJmJf ZLD/crYRWeFrVZmqIHtCRJDaR8C9Wz81qNbTC610Y7yKdBAT3aFLR9OE 7ooBv+oDBeIgaGGjcWLxEaoFKA1QdrbtH3uv++KRpcCQaD6sEi5wHn38 J9DQDVRnTot6CqJykLwUA7DKt/Jemr6hXhwAeMyHwfRZtcFrYbvC+To9 m4moJLnEvyRBu6cJ/VxjIRfagLlzaUlbzy2aMkcUYcWP11BCykigd9Q6 qC7eQoDO/Ydbg2QRrYOP/3fBjNzmiSTudV3uuMOjWAkMELoPikcP/WRB W+fEcQ==
+; resign=20460416024207
+18r.subtree2. 86400 IN NSEC 190r.subtree2. A RRSIG NSEC
+18r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . LyKx01F3d/M8i1Y+hZ9AbwPKJ8jonETPnZN7PzY9GflfmyUlizrkxK1D mO9FAFbEbCAFu6ZuAScQfU7kGeYqFCDgfiEe7JRQVJTIUXloyZ2a6LGv sJWk60omdN2BZrEEeeQllh4jUquLzsMKcei3NIYmpG4BpeLbNr9jfzhC y64lwOeYjvbqw4MhRrBEWjelLdk4AwvcbDrsk3QgMhtEqOul5jQZ4SOH 86RQOy+2bVQWv10J7F8jV9OzFQwgrctLB4fkcD85KL5Phd5naqLiaiYH Lig01cudq0HVr+nlpoaNvMUzAMcaNQ8tYv3R0wmUF+pATNHsYzjHTggW 8VLbNg==
+; resign=20460416024207
+190r.subtree2. 86400 IN A 192.0.2.1
+190r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . q6SCWjzJDoMY2aeYf1unyQQAtRNwqmMJp5inkrs/4kOydKi/tOBhQkCQ +f/hqn5xx0llx7HhAzfFp8GO0L3eGH9A1kCLidcPZ21BkcGWhJ9gmEpW I89vhCBR3GFz3dtnpenQOaLYgidEiRdeXZ9qKSWlGi6zTxy1QE/XSt4C EoD2DBcPHnLJxcKi7ZaWz9+HckvyDtkfOIiX8uiZe3TVXAyAX2z9n2nS 6xQ/dqclFwI/xnUV0roQ5xL7REpVXkCQmB4RY5cOXC84mq437ksPDrAE 9m8Mzy8UGg4pgBmH9zvTLHM9aP/lSa5jD5RXi2BFiKwMm3FZ0vKCLffh VGmYzA==
+; resign=20460416024207
+190r.subtree2. 86400 IN NSEC 191r.subtree2. A RRSIG NSEC
+190r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . jvrQXPmILWkgzAqmNBvUAfUaMOLhBBJnHHR1vwgt3i1y/ng9w5NeDny9 aqpcfH0rOD8EqjjE31DgetAldcmwv9QIAtCHj8kLQT4z8RUluXSanvTA Vc8Ql074dsIUUBAqBJdAKcCTyjBNkZ7SzXtNXE8+wAInXG3yvvoHRbN1 DjDjJVSTLxikgZtLBcmE3wOylSWFII4VOXXJglzA5BNxH1dCrD5hGDZu d3SZ4d9u8rkLvNbh2ltwWbeYb9l9PJvJYVtPP6BEIEcd9viFO9zY0ibx 1Te5jZFjiWj2XDQHpTAdIob3AHJy58wDO0eSh2yZSMzJy/N6Je6sF8Rx optODw==
+; resign=20460416024207
+191r.subtree2. 86400 IN A 192.0.2.1
+191r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . coAWozM2Sbwb9a+o3pnwXDoOjmsSQKehpw9mqmcsao2389X87OrlHor8 Sdu7H+Y1Dp+5WzTH4ZAaa3CzggEGqJMrTfyaeR7ClTJm+8a2fBlXQn3D etFXVBehookIDHiphRmHazWos4ztoHcUky9ck8l2TaoK7VD7woms2HKS K6PaeWZx0KXratCJNrwfQKbqOVayWOqTVfyr1V1mRC/e2omjVh5eeag2 V0H61uq3MW8/dhFAY6BvAxaZ0coGEHipJuafphpfy8d02pOGLjmwRM2b nVWLsc+DgxSkKzgWEtoGMu6B9f/X8IZANkMlf5FNR+gurAxH028BaRRs Be5cSw==
+; resign=20460416024207
+191r.subtree2. 86400 IN NSEC 192r.subtree2. A RRSIG NSEC
+191r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . Dltwr32CEvj1XDBLBckhHfu4uqW5V6+wWud6u7gJshlpaipvAnw0JFWO 0k+4a6N9aH9pWUjqXGHhnGXa+IDQtluAhljKfYNNngJ6yuPVnhDDN2yA ov34eFbGPlIw3yTxQ6ktZdyuMUyRB9nIS3+kmHcMWdOrVFc6QUDkbOa3 3HMGw4ow971BTpbqB16PHi8qPaEhDXVHUBxTIjJA0ekD0pFD8MYCKZxs /8eWWAzyjy0yVaXgMw7uecWPjARkvqq49CK7on8e537tkCT26faP5jD5 y/xWaDm+4dQpQVJCBjStO5cjCB9SNtFQlma3ZLqFLsrmRaHo6zJBQN8C ZLYFlw==
+; resign=20460416024207
+192r.subtree2. 86400 IN A 192.0.2.1
+192r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . bkaQetd2sGz+FIva3mtmf61a9UGb8EJF4Eyo9Ta9ahkxqDdG6RwI/ccT cd1pjd70uvxA74N5K5g15f3V2jJmJo/mSTiF3BJLT+mJffYGiWsX3rMB GGW/UmQMq/bL2uaijBKO5Z3WcOsE6E3rTL2X8haO3EmsM9y6MMwZ3R1p 6pq0jI+FsU6rSIhijYON3plaYhjOt68KidVHovRPYJzEpV3vVj9WGQBw APWTiX3QW8AHlDV/NJsMdQMUQhKGfdCPEIEYbW+JBoxylFygoPG+f+lP 2D310QFgOTPp5hzQ/QgcjvBfJLdVPmuB0rskxg5JPkJeSrbjW5fvu+Bn YJcM6g==
+; resign=20460416024207
+192r.subtree2. 86400 IN NSEC 193r.subtree2. A RRSIG NSEC
+192r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . XCkTY6jyHmhfZmlPhHlYopBPHUMI9u+PkLgF2iGChfVTheAGSc8vK+wr Ja2B/e6w0V2naN0BNu3aXPnZ/YvhaJymWnHDyFMK3fzMAHuD+qtsAmIr kmVwpM95vP2ZLXnoWKSoiJyCCszgKxnB//zMQAfHOuOyZ0c3KCkbIkLW DlHovVBEBYQZSA/LphEdzKDlOiVCfZ088KfUXgJnIf5Yz2B21he0G53B e2s32BF+z4wp0A9n4Oo9vMUozS2t12yg3pQtDh355oZF1f2l3gEWbyWo rjCqwGGPVwKmulbpkCfQDUaeNPl7TymYwKOiDoi8lARmpvRzVmwMemcb GeW5Lg==
+; resign=20460416024207
+193r.subtree2. 86400 IN A 192.0.2.1
+193r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . tUIiI0iSpJ8g9yeENn0D/ojKe4mqkc50dv3CESzrAD704LMx9JvhOHJg wX7Yw88Y1/6hquq44H0sJRHHKDPVBHpJ0P8tYW+pydJMbwDN3hs8intL oNJgJuH7G1p5rGanBfbXXEn2wZvnY/zZZr6a98JE21Lq6xEfO3XrRU82 BdQVJLjUpIQqW39gyXXGFNJqD72kfnHa94GlCYshKzygPTvN5dUoHih5 k6MRRZpYpHCPyxRwDKdjx4Z9rkCWcoGgV8+uvq8VhIKTv5C7WsCK6jAA 0zxsEd891ABw53m0+spPnXun7BfWqMg7IsIN60cfhuy31mu4obyw4KQj 4iF3rQ==
+; resign=20460416024207
+193r.subtree2. 86400 IN NSEC 194r.subtree2. A RRSIG NSEC
+193r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . IWMCS26Ec8KWZKOM3HQMPuW9gEEu9wSwQhIPK5zB/8P8jrS2RlCUyAzz cvYExkTzqMSs6PnwA9JNDcd+z2EDr90uCtvihrBA0i4wtIn6MYkTae0X Qwse+XoWYHHG7OFVX/iu5EBVUgO3Hu93rcSox9OUL/eAoGMBjGVoUutG xj55h2ntAfo+55oE3VoqmUswnThm4uECXgRD3uynjuTgJWPK6Kbvm7Od y+iWXpqleLDzXcFHqw7R6dzI2KB4I43DDhhDCUBoL4kccVLIkmqzuP1G kP6gH2vSGLqAO+LWbboA+c2hJpCN+dJgaX+qNF7QH0pkGYlaZz1Q4nW/ kKJeSw==
+; resign=20460416024207
+169r.subtree2. 86400 IN A 192.0.2.1
+169r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . si6aWmRP77c5v3LOogMFuTO9UwJ+tiiLWOAFT682h9kBLEp2mAnYXPUK I5GOLoxFV9R79alTP/k9QYATgttTnKYQt8FWq/o+dlPNqZh2fs48SBk/ yWlHeGW1trsDoAJS7m0aLtr/A3SaB7uLz0jmHHbdlui+h4ZaeNj8KAOW yDjiCqaOM7VEY4B8+iFCGS5Q9aXesMiKpky0aVQm4jh6r5Xvb4BNEy+O R/Tjv/X5j1UkQKwwe4mDe3wVP3UbFurPy7IUYpXvfx/S6LLrahhY3P3y tuhS4/G7y8QINVzS8ojAyuN6xxr4Y0ZCbSqe64QapDcsk68PcaaigJqh RXMG9g==
+; resign=20460416024207
+169r.subtree2. 86400 IN NSEC 16r.subtree2. A RRSIG NSEC
+169r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . bGKebx2uDgCnZArPh3h5Yk0FDylJOn1t4n5nxCXeD9kyIpOkPP6z/bka W7sRDSNa3ekqwg4ZHwtdnY7nMRbw83msh1CBcePQF8AIv6iHmoMBc+3p ++XgjyHVwQ3TbZ0sIRKmZwuKty2oSteOPZQSsDxQcgG0cmep90KWGE5h +xQJM92kah9uPJWCR/KF0wDRbwJgy4c/hSEaa5OiO2A9eRrXSy4TmyIF YNNVXl7uCDnRCUnH5M7ZNHpNVpUZzBxavmQgOOEPvaqxs+6/gpP2V+ys UKOOrDKz/7lsnr2zrq2XrCOoYs6tZ9n/wLTarYmL0gyg5mc1KjEYBYag vsLt6w==
+; resign=20460416024207
+194r.subtree2. 86400 IN A 192.0.2.1
+194r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . kJlB9dWd6vWbnvUV6uB+f8Oe5WnY9RUES9yQMdnYhZOQmWkc75KVpy9v sEEau+gisX5U2rpC6nNdWERMFhPMoCR0Wmc8xMWQKdNL0dpdFap4HI9a FqDswqAqjUlzSslZn6DKm/IErMzI4vIZPFe5lSooJDJtl+MM0qhhKmdk jww1Fb3x+VLKfLb+ry4+gAb3XXOhiBNdfKKaccpu11mfJsQ/GkqEszHW e84I7wFFwG1xj+O859GX8K50QD4EPzQCT1Y5N55m7iX31jogCxLmO1zi dN3l+Ul1FBxa9+rJXgjXp4DYCJ3G8Spgp+cpN6WLs00Q/E7WQ+RExD6j A4Thcw==
+; resign=20460416024207
+194r.subtree2. 86400 IN NSEC 195r.subtree2. A RRSIG NSEC
+194r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . q14OdHwGJ6MGHiL0xrXY68tPGX6HFIomOvKTYngIXz5LqlIqZJ6Ff+0S H+ONTRFR3Jt9Rl6N109MswOYWv3xLFUyqFJOGHyrGpKUpn5I1+CXEBcp Z2CG5ABHh2G2M08QjPYibrMhVX0ydt9U33LYVCukbrOyH2xkPnITmJ2T EHe4fCPACVEtPkBH8nAceaOLfajbpyBgHnXgeQqrujLoTPonTo0rRqr2 t7dp/48CxA3VQqvrsMajn39CH0xFJfcjHD5kAOn4L16XWkvyYVfn0BiA V3drHDaErhTeRoFkDlwWNxECrfkHqccqY/AWwcz3cSnISMAXWUVYd8ZQ GsU4oA==
+; resign=20460416024207
+160r.subtree2. 86400 IN A 192.0.2.1
+160r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . jb72zIgxTA12OlCMJwQuMC/YsMJGNqM8kTQB3QftDma03gPTFy8SbSkn Ewc4Suy6bC076FbaV5TBuX9mmxa2wQL1+Km+fJ9yiKw+FqrhFWmOcB8H Q1PZm83c+at5Yg7u8jvNF1O6QxF13dz6FbURpo7coH1Y8OBKHu+GwDfS +8yiHGsPqdrczCifDmYb3nDc8cslVYNP2AmytY5vbQdkPW6EumLrnTgd HR/vrDe2SLTNwuh+MNMSfS20oKzjYT4SPF8AHelhGqci096tRGJjKboz SpBmKUHQWyOWDiL+cSGGBlz6dMzD3P1iHAPprd+zaRREkVlmAwwvXx4N XscCxg==
+; resign=20460416024207
+160r.subtree2. 86400 IN NSEC 161r.subtree2. A RRSIG NSEC
+160r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . G0iabi6n6Lxce7Q8i6zYd20At1R9I2rybt7dkh0cx14cXIoq1mt4bqvw HaT5Mv3eqazO+/RNIaJ6urOsFxDr+g1uk4HCVwEA8JBs7jr8Gll6sFuj HF8Ig+kdjjIiIc4cjnygpW/vEd71TOqKeMj3zWtx7SEyLYHl9JaUKqHX ZKPJFA/25KdLvK/TImUgGWs5wTdsqWXgzYH0bGZZjWutToNbpL8a6r5Z smStITjxAxLbmqBdO01qVHufzlsGn5AnteSNie1lRsERhGgm7/QBDz0t 2nk/wsdBVyVJc24lgngL3fwypw0w1qJf25slT73wXayCiOIqRxGkzBg0 m4V89A==
+; resign=20460416024207
+196r.subtree2. 86400 IN A 192.0.2.1
+196r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . Uv46WzWSPSF7dUoIG5MEXEkf0DSXGDISkm3V+3Gv53VpzWb2nZ5UhLp/ jVSbCrBl3lST6UV5XyNphtkYBHRFq0/ACUtBSTWGFipOGFHVn9OUWMPg NkzKrEGrvWmACRAkea9qVKAFwcSLEvudQM5LeeKKPRonUGlUN3UAHr1K WA87BbQPJ7cvpkHUqvuKnkdS0HkUXAD3g5xH4lHY217wN5SPX936QdWd cyWKEvC4x+grc6hGvHniOk8/8AswsHF6bFJJdF+5tvvIN54Nn3wGdWh4 HxwAG32NW2u+BhP2KBPAHZr5PXtROXfk3x1aOIGuOwI4jQKLO3eH62Aq HlCKow==
+; resign=20460416024207
+196r.subtree2. 86400 IN NSEC 197r.subtree2. A RRSIG NSEC
+196r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . Vhyr8UxBBVv2bGlmO7vt9az5doR4DqsNL74WJU2vFDI3YF0oTOdJhl08 BaYUYQ0Fnq9YTaRAmTiwdmMKvbJWWw2e38tZwUUPmUmU8luVSBXcqGKd wtGr/Ys8zhj2SAY6yZL3K5XkpEFf4x+lJG6PQxGJpHPXmVxcfVdD+yiH IzUmPUTj4hOTwuqL/dJuggbED160MrzhsIcRInt2MM2z2rqkVVo//LS+ kKfTfYCjQSa57CwUrmiokBsiMqbZX8v0f3qfGW7TD03OrEGQNWrfNxkO OEgQp9bj89SeJ15xjog31LkVPILEnPA9Xb5eAjKs/GJP8Ltal8LWCXLe DrQfqw==
+; resign=20460416024207
+198r.subtree2. 86400 IN A 192.0.2.1
+198r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . Cffyp1+C01GAOk47wKdsqcqrOhXarX2w/VUS9NKTrCFv3E6CVyGKwqxO ddRx4jEE7XcZG3p849CDmnDBDaimzG5i7PbGAt/GGoH/2IGRtKRm2N9p reag4cFOELL1OgRRAZ/Qrvhp+jSiNJc5/uT15lEK5/2KQm7CP4AS5LM/ Do4VjCMQQ/rsXrqepw0fiBGoVU4fyGAzzsIH8mLxdiWMymOYWsF2fHfr fomzr3mPeRwIRDzVd/LLrZPqHjStcOkihua+c5KV4SA44criNpV3b3OD BIgEXumqakOb6J7Gld23peqd0I4h6m3KIY8pRT1BA61g7JfzR7s6XN98 qm3Sfg==
+; resign=20460416024207
+198r.subtree2. 86400 IN NSEC 199r.subtree2. A RRSIG NSEC
+198r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . riY9qitfYMNPsFQue3GSigjgNjIoJb5pu0SNRP66FH6FEJeIQlVKNBiJ 5psuMDKxJdC4KbvPJ+A4hcojeuAh4oKU1HcXArpo27OlTU2gA7aSYHc2 OJkIQUnl+yH1YUdXnzHV9W67bEGW6qh3DwdahfRBQoB+lZW+xdQomdp7 HlswZ0yn7ldfaJhc78JIcHGgZvZAI+Y0tnWFlQpxxeHyQOJa98IlD5CV 4XTnPgr/tAwypuWlKxhYRuOdLszqodpul1MqE6++x+4GnZ6cil+3cWy5 Z35lxQQkwEmvdxRmWqsL0wpTaEnQK5xpTHSjS3CkjeR3pYH06q1nGdI4 5ci5Aw==
+; resign=20460416024207
+199r.subtree2. 86400 IN A 192.0.2.1
+199r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . TBgjH7aBcIMs1KVULSMbahd5I1ltCHL7P1p/Oos4jxMsVrVmQ9edWty5 SFqDyUhgyMk4map0ssQWk/8NBSnv3WpPBIaQM8un1/S0vWZgnRXVY6EL aivSXchFMYOD7pE3wx3cce03aKlFOkORZ9yfGhyHL+8J/aQmfisx2ucS 7wm3qV8K5EFY+Faf5JZhyV2tnQhRJgrISiz/hVH29q7nGOMelhAIkVLe 7da8uVGaUrG9Us6AFmNkpI6+Q9tbF68h/zuk+4fAB014rpBCJAaREYMr Wh/4pk03BRtEIFJeknjhiVTBapmL6Ok2/4ztvYvy55l8ZAqxNSa8o5Rs 7Q7MFA==
+; resign=20460416024207
+199r.subtree2. 86400 IN NSEC 19r.subtree2. A RRSIG NSEC
+199r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . Iv/ytTUdTY8VWsqkOz7qvfKExoAky1y3HXaFCqSzwLY1fHHVnQPSoeBX o9TN19xMA9EyzV8rado66UKjAiOh5i+cG1pGBUatKQfpAOfeleGkY66M M0FfOu1RfO7kbyEcQaAwqx8/nyVoHfZskhrU1Ztpj4AzwqbO5WkH0CHI 7xQIcG+pNPjpQjOV88UpHlCYp4xaTzBZoMgKKwbS/abtGWw7Tg+bgi1g B0ItHaynIXDv45hbguEw/T+yio+4nIaGyEO9V/H+TjDxp3nbS+E7benA kZWjAK6m7BqAu6HSIRitwPR0JcCEdjT0LwUgDbj4komp11ZLl7FJlKoL Dmp+Sw==
+; resign=20460416024207
+19r.subtree2. 86400 IN A 192.0.2.1
+19r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . I90j4OdKnWqA+ogjg54CDQGIqisKOTQqEMrknuNreiCPOJTYubGFkTcm lFwWNy4ciQWpYdRBT8bZoV+KELLqWvD+ZMRnWo1kQ0/ewGdABuYVgB9n 3qSh+IkfnSla2zeqyYpVly1vYjFs1umXNVoIfHvHhB9w5+PnE65cQrnt 5Peci0x0iVS46TYH+jlrsy/6nicQV1JQ2cqKKo4EzVkgYw6w5hBZb/xl AurUO4v4NvffNV1fDjiGvDsrq5lWM72wwsZYG5Sn98afpTjfMiFqFzaM U4C/awi4sSKrvZ9mwQHDrs7mer6WLlj75OyuLRwuK49aKwDDWelNY1RJ BjUAqw==
+; resign=20460416024207
+19r.subtree2. 86400 IN NSEC 1r.subtree2. A RRSIG NSEC
+19r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . P3aASMLhQQIb7UGT/uKDap1pTt9RmqoleePeWFVYeLUZ2K9nnYxGaJE8 WS1W8tTzcVGkWqc4+P3LI5yDR8Dg3QtpAqGqvDt4qogXtTaopIdFdWub xIzxXqjT2SXRtpXlUu+KOldTQRFrQq8ttibDBcWQf9oQN3hNiyYy6nlL FGQ+Xa8+CAq8dI9nw5qd+AUxsDBqwi4qxb4SUM6RIOiDUZU2t2v+jX38 O8Ps5yZOs0DocS2PirrPwP1m/kZ1NR8RSw+vursZsbs8H/jkrQ9waCxv S/9yj5CC+Y6hTzE4jf8Q5Fbsv0wIFJTQ70lhjNhaSEQerO8C5l3y9crI Yn7sxA==
+; resign=20460416024207
+1r.subtree2. 86400 IN AAAA 2001:db8::
+1r.subtree2. 86400 IN RRSIG AAAA 8 2 86400 20460416024207 20180815062314 48409 . QPdm6umQ6hgZ12897PAoWH0w+doWTmMWyy6rehLtYI6aosZmdYba/IKf USQchPvSbbpRjZl3SyNc2DJXkmZIr6DBg/4UpTsZJgCKsregVJzo1vi4 iv2NeQ4IAoXFqkGqkOMVzZI7jrBtXQe3BCXtGMh5ydSyV5vkQPFO6VKg yfObVC2g8qpMzF4hGu/KOe41dmkuUKg6OMKkaxrxg6ppscYIa+8MZS+6 8TdNJZFKBk69PmKRsmSBwxAWyLg9gzN68vyiccKJxAYeIA3cZPPZTM+Y MYPwoBLBRxDJ2IvKpVkyYHqjljDjI/SUtBMlYrUHZcxa9JlzaNlaZT1Y P9WkzA==
+; resign=20460416024207
+1r.subtree2. 86400 IN NSEC 200r.subtree2. AAAA RRSIG NSEC
+1r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . bmKqaR1EKjjdKty7b+HJS9ZckeQaD6X6CV60Ly0zoWsWR+buhfO51Fm8 p4j7YuLohXqREy354p+gUq5bbSL1UXMtw0ABJkFlmP4fAvuWvIfhW3Mr ZIKDaDF0LilZyyGHa9HAQBMA/mO0xoKsMEtLwN/3zRpHm0A27Le7kQzl Tt4qjLfdhDnW47g+ISxVNceHHKgJXXmFxJGrnLUOzh85kUTYq9OECJQL luE7/+n2uDTcsHUnoDxcTupMU32nXMMSR1k/KFSGN+XGM0rkdD8gdLZS 8px8nU1PkH5UlwJem/08S5Wf3VJakKFeUBbFOYhHyCAZrP7oZwzZBcOR 7Hqr7A==
+; resign=20460416024207
+200r.subtree2. 86400 IN A 192.0.2.1
+200r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . AdCcd+Um++YcFuEPv4aM5EjXQMa9EEM8JfJzUSbtnNgbc2dkAuhtU9/y v+Fspg0RhVw/GZeqLvikGrkvIQliZv4CETszTJt6521PTrveFkQjJRjt XztatkTf0GtwvJepxitodztMAZK3aOyXQkYSjfQgybG5c6sCSAU+crqp IJxBhV1eKIJ91ZVMq6rvlhUmkKQg2nCrgLq+V8lbaZHANar0k7O3st3U ESLyCRJ88rYhlvITZzKtawgIFpZxl8ilF6dPIqZuz1JDnI7u1N8Yk8ec OHHJReEDhK3XhupK9Xqr//laHHWiy2CyEivZpZFnP9d5ePt2Fe1/xm5U WYZtdg==
+; resign=20460416024207
+200r.subtree2. 86400 IN NSEC 201r.subtree2. A RRSIG NSEC
+200r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . arMHmTLOYus38Fu2zrYqWz7IDdR1K+tkbUbUkQT0kUhD+9o2f2JOBKSF UHWGl/sLof7v9ZDNiO2YDRNqZqqfrbzVkZ5TkViJ25BbdpLyzHQmTWkD 0jA0Vc5bASOoNBArxKGLctrdG2xTlOzr4r8larjWmAdF82rSum2VQEzg RQW+32E+fi9P4/n9N0lL7LTgGax04Fk/rT41T/00A1FY7y0WYlex0KPk 6SG3366RsA/D+ci+rYcV+o1gowZWZ2EfcIY/dqjaaYKsPlkTdWKXMFKn e5tlur46qyl0ds2Sl8nzxWrym6MBtVEfGTONQiPymhxtvfy3+x8QxCP2 BxiZxA==
+; resign=20460416024207
+201r.subtree2. 86400 IN A 192.0.2.1
+201r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . WKRZCWCyCWWUcXSdPXGuiqNJr9fp2TBt5T2Gwd6gK4D8kzyr7fzyfkex QoR2lb6i5PC7DwxP2JdMz8DeT4x8TQmsNhlgRk5W1yEWie0SXdgtIGMm CrjZqktI8qtdqoRTXTf7wk+8E9QOcOnZIErQZOcs8GWkqU7PTteyHRFx FwPv/b+ynLks/GnzmiwIuKO/5ITbFByQgpT6cuIR6r+Xl/f1PZ0yThnO +FC8jBJQVZDYAmMgPt9wa8vQeLANdVgOqrEBi5dc8xHRVESw7Yo9aHOg MN7R1/HN/1wXe1U/IGXnAfIBQxZbdICy7Ht/GBMUW5d4EuIHHSIOwzv3 Xn12/g==
+; resign=20460416024207
+201r.subtree2. 86400 IN NSEC 20r.subtree2. A RRSIG NSEC
+201r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . ZDr+YoExEf+b009kZrDByKSO+NsyPNNizYUiEY6rr3+LTWvqQxghtU+N Udt9OjzETSWQxOKxTjpPr9PAcaPimpxztob4UxSdyyvhBey48AaMEHGI sYoFPaftUX4lwXDaaZRyzEaqe4nv55VJQUdg6JqTN5wvlSXWocKrKhGm gAxhfXbo6IYUp9AH41FRM6zv+AT+hqy2y+2rMpPXDy7SUafR/0hulVJ4 0JTxPIXVrhJGV7JxxWUfO4x3t0w/B3z0bCXgEro5ixke1iXz53+zGeKh RcIIwVUFx14XVgllzWkD8RaIdRLHiTOH9N4mxrw3bKje4iF+FC8XR1M2 Ao0uaQ==
+; resign=20460416024207
+20r.subtree2. 86400 IN A 192.0.2.1
+20r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . VElsKz86WloMD8ddFst3ZmP7o7rv85lui0GuD/cqc/HDHxNKlkegTzi+ RRdSCJw/XoGoLv0Gsc3oMffvX+YMombqctFWS58tK7msoKJAAxLNc4Eb IqSNI/shXP9IWLSqLMR6fCZSgNd85Q5DlvjY3ql4tRyn42299s3YCkXc PCurh+/LaePwqfj95nKD+gAj/c89stTFA8bfQza7mYEZPRXbnjKhKHoV KcWQmYVZIeJbydPLQ/dcUMbbYsRIQvzPmVGULcpCngTJQlsFG9E+nDto h9DOz4/DeMjN/1DRZP8FVVSx4b6QXJaw+lsEL3cRpA+FXzXOxFSyVxRi 0QeviQ==
+; resign=20460416024207
+20r.subtree2. 86400 IN NSEC 21r.subtree2. A RRSIG NSEC
+20r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . HKndM6ggvOdNXfO7/v20k3RwWsAKWxFGLM0o+EL1gvkw9vi1BSpGSH/6 OvRHlECyZ2zD5UZXquNy6pjP2sMtnSdNPDARm4MYAYDJQWool14QRSFF JHbEdXPBQB4Erq/NqdByq0RuEOykROi8tdiyW5o7pCWjpgm6YSmFvNFI 3jaLLYAZygTuonnJX9gXAalKo/QtAGw5blFA6X1GTDuhdMIK+ojOBDr1 QeZA2tNJAGKtkta9L/NrwZlPX+Ij+WPlPvCgzGonnYHfLGC4j0X82Ctm 5pNpzjal/ilPYBnhu+wOuNkjdrbPnjbA4q/o3zHAcTw1RHh561geSOfZ Htkbig==
+; resign=20460416024207
+21r.subtree2. 86400 IN A 192.0.2.1
+21r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . Ddwfe587CQAQmgV6aWxYN6fp6gBQu7ydmCThrOYl5yHcmH46RKLjP5e2 QBHtj3EJEGSh+H0ZRaYgmuX2QNR4nSfAPs3kI4cAr/cP4lyfASm1890f 03nc8NGeLcl1t9tJR6Nu2hy979252mREBWt0hKkAtnDhu3u/CCopMkFy qQzwcusRXU6cnf2GVMOOgSXJvC9hkK/LCAlTPR1SyIViXTIyMrrvR+0z O4s+SihfAt/0LzYGEFCB8UOTj8r8U1QWrAuVxZCVPYM70b0q2IzB5aRH QmU4fQ77HaNdDD976qFOFm0MSAA864S69yBmn048yRO18wc9T4xJbfzM Ua2O1w==
+; resign=20460416024207
+21r.subtree2. 86400 IN NSEC 22r.subtree2. A RRSIG NSEC
+21r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . V5B9ljXa86R+eOEozvkkKYRzr6WmwAYblhCZtfYoH+nEcuImDLOcKppv fgpmzY6LG8yzMt8V4Cbk41D1kIvCD+balhp35hpBsvCZdzuAEBqSB//y 7/4n5CUNaCa2ThJP/rVH6ktwja4Y1YE8dKgJ/BMDVMNx1sB9M+J+xiyv +jmDM6Cnc4ihRgt5+dHFG/AkGekG4LHSEYquAhc+0ZypNoY8stC4dDpP 9HTRusbvJR5Be7a7shOkfGgUP7CdZhZPTXGhC/etGAXzrVMpIg5+vQA7 cRzH8czwgpp11hQcMpbjHRiDggC0bkAhC8Se3MyrEL0l2wwWt3r+VVWP BTL4+g==
+; resign=20460416024207
+22r.subtree2. 86400 IN A 192.0.2.1
+22r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . tBL2RsmxH4sQBpS+lGED4ig0o/jHn1kEo7ctXl4F90EZrY9PE2VOY/8+ LCq0B+O9tRZaOwZ0H9/P1AdssmdaZDX1PajDuP8+WC9zjjA21sPpOW4l eOPXoE1200W3cX0maOp+/uA6vHy6FoC1d1/WeObc8NpN7J8mNXU/tzH+ xOlyeccMsxapQ4hXJFIpWeTGFfogB0eaNOxSMHinoLWEdAXYcF26B3Jj Xxagc9YQFn0hUuOK7CIc6OYuGXnEeteegZI94dKPUF0jfqLfJomibQlr d6vsz5EFvAbJw83Va93QT4+SHcPDzEgsraVYBFd56WHoXbPZ4NZiPL7o BsgOwA==
+; resign=20460416024207
+22r.subtree2. 86400 IN NSEC 23r.subtree2. A RRSIG NSEC
+22r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . mQ+h1nOcLbnohGMzdSxudqhZ5AJoV2l2i4wkAL+syqDiHnuGVG0Znxwe Uy0Qjf0Uza+XP81Y+q4MJonVYpfriJv0QJCY9D8/r7fBrmOTnz3pdptD 9ABo0FIDtIsNzMBdMTsVqNVHESmXRs3DaJcGza+SrRl5TChGU+jkTth4 i1yl0VO2wAfox9z39BKnkZ8+bXwU3LJeBKN4EasQV91X2SJDYLzvRB4J v9cYER1xX/+HLG9pBN8I2iVy5O7UBCb94KgYtwB22V2t+8i2RwcJ1a3x FdZCEyk9fTGow8NCmjCJSMTLCqLZgoCpWhReXTB7mlJ62eYyxD39gPFz FvuhAw==
+; resign=20460416024207
+23r.subtree2. 86400 IN A 192.0.2.1
+23r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . vt9Cxd3Qaaz2ioC4luCCwsjE2cD3ySiqfJEC4WySIs/ONMlWC3ZjKW5c yS9/R9FsXMQfqQ9tpqNpLDg09UDU7BRJPW0Ouf1NlS4sPc8yfC49v9pO 7sN+gcwIjehQuPLCweXFjuckZke92b3DTgEZJ1BxnvzIEfH9gQYmDk1K 1Ul1bmK20Q/sKA4TgJSIq7rQF5JaZ5L2xR/+hZTNDhT/ApX+0By6MPSa uEKvH2/SkPS46VfeeR4iUyJqCpzZzm4rruUq7pGItL28PPPefchebCUo +85TDv5eRVP2rRHDixhqYcBNG7HVu+G+2wmX9caZ5pEGwGYdOdhzebJQ p6ECKg==
+; resign=20460416024207
+23r.subtree2. 86400 IN NSEC 24r.subtree2. A RRSIG NSEC
+23r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . DAJWX9VaLiASU85yHGBARIl9kcBXWozpt5yQSxy6kYVY/AvG0j9SSEcY 7ThX/eC6hPgHj3MOpFfJBWfYGAIKxejnzr3ATtevOYC6xugBRoc95Uyb dYo5S17O6yzI1OU6d/ll5KDW+gX4e/1+10P6FmJLlS9AzhAjbzXXIdZQ 74dcDIQ8y/cSl7VoqlwUg3LwC4hYtXOaFsrkwId/a2Ly3k8qXNIIYw63 Phu17IuoKZBceXBDNyuQkeo0CX7EfU60M0SRtaF7vohv1vy35BVA/SW5 UPEbBDHGdy4ygJv8cCwFhcdqXm8O7aYjS3xGscKdRa+HfCl0rBAdBLdo UZ56OA==
+; resign=20460416024207
+24r.subtree2. 86400 IN A 192.0.2.1
+24r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . oREQ6/5Gy5CkKpd0m/7Nfu8dGqXe3PdR1wUrLjfmsbcx6I54VQ0l0L1l G1GjHM3ci/ngmAak+4Iy3NUiDEtUxPxXFfJHDac0QunCscGpwwDxDhRM VoyB+DnQ0DZcAPUcIiBSyS56ujIZkRvfAY2PnXH5WYR8V4CfgI7Lnq82 R431Lqz1TqkwX9XYTLcloD1D6uPez3xV/fdJ5jGoOQbQYPV+mjjDrMPm d0mqRw42ubDqrjf1wZ/s7sSKV8T2e7rnpjreoGcD/TBaGQ6JYNx6NZCG eOTGBLf2NdCkN5BacbZrXMUVCk9qmgPZJ/zlcbEwB4X4VgLjHfU6l83q p2dShA==
+; resign=20460416024207
+24r.subtree2. 86400 IN NSEC 25r.subtree2. A RRSIG NSEC
+24r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . w4jw5BOrRRbRs1yvVoAZDiW6AzBNZ9czQSIx0zbPEzOytGplgWurm7iG UyHCKSnOzB4TQ6hjh1OuuQXYm5x5iJifHpLD+o8aGRoae3hnpHBkGDn1 7zlPCmNpzPrRDCNKMwwMnvzaqsXu3bBfh718dVN1o/kiFF+AWEdDZaWE 3TkAHpDIa+UUQr+dA2IEdNMzTMnH/iezAQyejxHdQLw1/eYiWOmvjzvZ 5lRiihRfTCumJXtTeUko/FbqB3mdt6ioZm/RYbONw2ouZ8OTys4BOsqe Y4pE0QSxWHqKAU4pynCI3unZdE3ckTAiu1GxlcTwujge7ifjKu+JuBdJ ynGItA==
+; resign=20460416024207
+25r.subtree2. 86400 IN A 192.0.2.1
+25r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . R4hAmO+OLOqxjHBlu5r+I95+zNrbT5deDE4C7hoStCut873rs7GXs1Ti ICmud+4oWP6w22TD+Vc+cnt9GwtRY2oZFAomfaZVPyqiUrxDI5Abd57R Nc3C6la5u86Vh/rU4dTaVhOxCe0g5365DJba3x1TCJBh9MIlLXdZC2K5 jmxEgrYatyo7tDQv4EFPxXB+J4j1IK29llcEmCkdHosaNo81bEDeH/kZ l68+SG03Fq3mHkgd1EWPs6M1IYOXVxBKhoRQZ4e8K89TAUAsyscsOVje HEg7BhfOsWtuuyMPNqDq4NhYVEQR3VQIMzMDRhJQ1njIrJgVzrW9AyQO YPVKOQ==
+; resign=20460416024207
+25r.subtree2. 86400 IN NSEC 26r.subtree2. A RRSIG NSEC
+25r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . Tt14ZNNTv3ACWX5Qs41v7fB58iGZvKt4r8gDgQWSHYk0eefMrQOV7Qob LWZ+MQZXqcuNwmpbW+c0i3gsHywsU7wZTyXIJXhEHo3AKYURDf6FIjlQ VXTmLmaNvvA+51MuKzv9zyg64V58xIl44IClvNde+vEgOukzgH1UNkjL DdZKT3JpZfThPtPR5TPsuKwqKqtKsod9/D9JGNswow0ebFXLEA8X4qZG +4OfDIU0OoiGmN/5QXfor2p0RTeHHkhan2Nb365qEg+wdigmVTPjLFSv 8p2b/Mhkf9HYFv9M8/8PaXNhtAZ5whjySb+iRvTwcA5MyrXugI0nKqpH jDyBQw==
+; resign=20460416024207
+26r.subtree2. 86400 IN A 192.0.2.1
+26r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . aVWoA576Nhf/V7aCHPru31D675EVJHxtBqMA1jAutDOWtQIRnuz9CoS+ 6zG5mfywi+MPxMYHpcGYM+wxQkQjVMijBBkD6QBPE2Pf49VmYfD01AUZ R1CM/CdVZi81w7tjMDbKJT2XQs3EozsdsjyeUrWWqmtv4xnWgwPwSBcP NADFeuXyWhyJPeVIbR/S0lqPkS1e3XPZaUWn7ipe01e+dhHvMbZU1hZS y3h+EwHdeeTzG/0prP0EROMbRZflfUEdS94FAMehBDnG/2feQiKRJsTL rnrZ7y66yWvUvjHnfgW4XqAsDPq3LzEGApbvEOksdVTb87o3VBFmFpRy OZqQYQ==
+; resign=20460416024207
+26r.subtree2. 86400 IN NSEC 27r.subtree2. A RRSIG NSEC
+26r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . yBNyvINpDip6j5Pe8i2lmYd3MNeHXQrW4tfOgqzPgd3fIpc06kYSG264 FchLrX89Bsm4q6/ZlfZN5XpYHXYCwFzNWaC+CJJQh6Wj52S0UKfAsTRA 86jxe1Y8Ld6kFdjE94UW/j/l3VO3j6oZw96kpTj1RH6dqPtPxGOqhbWi BgdoMBmKV+TCGHXEhEK/MQ/InLrBD4nE40Ryr1kYhGmqvFq6OBrYwSX3 JN5R3NJQVqqkE1/cQxaUKhJlw515hucNar37ZaI3IF1G9xs5cny8HVdo mo/CSBBumcR/1ByIy3S8ZYqJGwtkTGj3E07JXVgvRo+04gxUS9aEBBD4 cLPf2A==
+; resign=20460416024207
+27r.subtree2. 86400 IN A 192.0.2.1
+27r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . xrpHpVUJTEBYfeJgoVXr3JDlXNT+v6G/S2sKYlYwpQO0w5/gloxDJFL4 0X9tEoUF0tvV5+zsqRxbZD8J5PWJlWMiee4CxzyfZtwOYRgq5Pq4hUQX T9n6jfNlL4xSKkvIFz5+upIzqfopZwFo0nd7LxUPLDakBdMMJHX+6xA1 ITBktxiCrm/smFzcIUCekMXDMBXrScntqdutctOYYmoAnLIerJLP5lcv yp+NSjZKaDCV77kV7jOf4yJr0LNpV9+TlVCQMFOUSlQiT+QtoydPoZ16 vLSKrs3jUkFNS5WgzIam2EG8KYAutFxD/f1p4mCcYtlD/axOi5lALldo UdAZAw==
+; resign=20460416024207
+27r.subtree2. 86400 IN NSEC 28r.subtree2. A RRSIG NSEC
+27r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . Sn1ACKuYHZBNOuLZVaKGDJKqcEQCcVBYjyNYdXez4uPCwD4YipOAjVk5 fNbse4YUxwokWGUMA2+vo6FPCNtL4aAUdbBlbdN+wso4C2vo38AljMRp Vta+yY1QNQwQ8iocX5njYJ3PNqCqzLaRvV1DPZLNgzwjHGD/5aUlQzPl nOUwspcOA5QRT1s2yx1WkDIqJjkYhNXFsp3Yy6FZR7CW2QFvBwlGVjGs nq0K82oZJfU2TAlnWU34hz+NvRYG00irQVdsd7M3OhVgbtaAykdse+pr PSYHbWTXFrrXwTY8RamnxUDPjGEBc92403m3r90OxNY1JPlbecKuGQti uSjiRA==
+; resign=20460416024207
+28r.subtree2. 86400 IN A 192.0.2.1
+28r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . U/xbcFOZhpchMwPGJFmpAJZkMVU+RkyUIlwrfRpDFBASPEFd4tron+eU 9lOWuwre3SwQk2Ul0q9rCZr78dj9Dg6Hh5OgwaP9pmebsg512O+4j2rO z+oj7b9sI2YVwDX62nTxv0v4buhPzFuDjY+L0z7EdKTaUrb0N+kYehze RXXUMeu8+xVg8vD6nBOClI2KjcjUaivCJsQ4KHtBrXN0T1CoQG1KT2uB SFT/YohxC+9sTmiS6wPplxolxg5vZBBgDV0l9ppV9y2dE1fQsC7N30ch 2mSSgPm4/nZSmEX7We3TnvLaiyEoi7gSTy9txaBRRyUhQNsPTT7TJ/pK UA/o1A==
+; resign=20460416024207
+28r.subtree2. 86400 IN NSEC 29r.subtree2. A RRSIG NSEC
+28r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . A0707dBFvfAGDrHniS9iR6Z4znuSifFb9yvIUQBEcT+1+u6gbtyAhABC w+tNCEgOnkkl5fB651d9znwAzp889bVZiAjQF828v77vcMS992OZ3bvy 9XseZbdzedr4TRo1HgcdBPmxXR7a1PezrhZS5NgZxeBj4nEPfXW/MzT7 I8W9KcnQoltu0woOrWHyiHCQGqBKQysUHnpz26XVnhJ/LpyEhYbHa9WV uksBUDDXkONgBdGSfiby+Kl32sW/PgjdqTdy4+GZHk+LWK3C/D98UPMg wzoz+Um6k7M+ZrkZHwHwQde+l83nNgn7WYDPUe2KU5MlVCoGbyWKSaIc s4PKrg==
+; resign=20460416024207
+29r.subtree2. 86400 IN A 192.0.2.1
+29r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . ilPHZ6aax0asJooMVb4cjhHUxgPo22Pn2Z6sXM3gEopb8Wy0K8Yds78P A0BUbioKG73l1PAXx5wM60Tx5Kvm88OiTKDhqUw55S2eUZ1h0X3W3Bgv +8+PKAWhp572gSbWlLcgDkwvXrl/evTapxgg0tvNGpXug8SYPUcxUmd0 6QqYDJIlUfAt2dMPT5WR0bdbNNGbsl4hz+G7KsBHTJxiHD+poQoxu/zK M90ZF+wJUPj6F+PZbPOxuP/bAnCA2oNHDQPNyUJr3SE51Iyp264vpgLx wtKV9nMNdSq8kyG84l4jf9EPGJsO3ZnNLe8kT2G8UE8TsS+cWmqHrw0t nTjrrw==
+; resign=20460416024207
+29r.subtree2. 86400 IN NSEC 2r.subtree2. A RRSIG NSEC
+29r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . ZfXwUkPRWGLLhYU9Sgnx/JeybjuPWlT0bptlRsFijYQyxik3q2JyO7Zj AKpc8z3L0dTMyQDHqmROsbYRI+F34Sck96waEV2XZj/IxnISHuxvlBL4 uGXtVuVaMlzaCPMJemhMY4Bw3uliaDpudR2cWB5Yrq8BAsp2fUnbfI4i zKJ1RMpzG73ot3ps0MxUNs9bpIKm/Bce27rMFZ3dYfVOwQAJC+Qqq4DY h4izq2abPYrJZ3QBV5AyMP6b2j763IfgO3IVVEnMqe6l3lDadfG3vX8M 87Ow9NEnGhYQYJu/egivp0N6Vkgcz/h03rRvcvj/ZEv9dj5zpfPbM0yh uMN81w==
+; resign=20460416024207
+2r.subtree2. 86400 IN AAAA 2001:db8::
+2r.subtree2. 86400 IN RRSIG AAAA 8 2 86400 20460416024207 20180815062314 48409 . Hprna6yPTc4fP0vehuoaUXSrarTYKQCWXuVR+qkmpziqh53a9hmM5R7p CtTYOGGJuAhdHxBoUimhyAeyBn9WgjdikDrH/UvtXzi66jur0CpCdP/M wD4w3agcjtkLebjqR7iUJxZOYshqnu9YZpr34Te893c3Glv1fShnqi6H uT+TyEs6a/mDb6b6t7+ezHaE+gM716oPArNN1k/8A3BA56huUBDqBZWi Fj8ootIjauKf06HpOCEYHOH2DT9juLH8Z5naaWj5vjXeUFhuk/X3EfGB clnZVm/rqLyYRdro3T9Kv11KjI8vUvQbOrEyYkkqIAsBSsfQAKUjOHXp IIF9bw==
+; resign=20460416024207
+2r.subtree2. 86400 IN NSEC 30r.subtree2. AAAA RRSIG NSEC
+2r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . AqoSPZuchYPArsyXg8tr1Et4yhuBpSO44EpMxMRDNDbkLkNKrr+OMGKD OClSp5vW4npgYykJ3gxs6TAvmoywYT442Hw/SDhbVEZ1qIeH6eZ1BU1L TAVdldT53PyPfxek7HjC0gZyHN78J555pJRzif48u7aqsTfVT4Q2N9i3 GIsozjrhUqsB1Y3ovhXFqmcR0bTKpZncWC3yByjgwhlLFrxhPWpGx0t5 wJza8ncTpWab0DzkAiVxd/ErBzqNe2oGrZPcCm9kZ4dI6RRPfk7ZY8nN ekp5YKa1LCWP2uE5Qr0IOhig/IUFr9ovOuM7j5gcF44JR8YuPmV7Naaq Vt4z7g==
+; resign=20460416024207
+30r.subtree2. 86400 IN A 192.0.2.1
+30r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . TAQ4R6EVK2GqE3WKZbkV7vCpq9LyUWNWhEMZAt9732aRhTdrCa7T6tIc cqKOeBk3NP0Nu2HqoXMSjiFTu7Sqt9bWheRWPQpa+tuuhT4FOYDOMQOR GHAGyg0vWllJioJnwAUbF25PAxSrT7pyU1j5EZ+svmbbUSp2LFzDNPno exbe3f6C8MobjlJnYq8dkS5x2IfnsZHrG+IBpCAaTCeBFL2lX0XgbkoW CIjSgU7akg+J1vbZZm/W03mY46U3A9KVepnxPX5koIHtlWrFzywdPpwm 3dJHQXz7azK3/ObzW7zBkF6q7qy6fwxQ4tnrOo9q8+owHBVIJkeoeSib jS/tfQ==
+; resign=20460416024207
+30r.subtree2. 86400 IN NSEC 31r.subtree2. A RRSIG NSEC
+30r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . wS4eVreFN8KNi72+TIjrs6mnNPKyetFgZa+XOXTBYomcpB/FfJTfwTxu sSNbWXPCPfB/ebMQy3hEU9dSmEfUjsjj8+walUzihYdB1zFD1Uu+JwqE /xJO9YIbnzw8yg80bzomeijhHQ84avfEsJR2Arekxl/OcPBJE087bKxH JYtM+atz6gyoYFF6HjwEOetotnIWjKGfD2cjFKjGpIWpcQQBSBb6jnh2 /aHxtZoZQy84xnh+eH1ATFnqo2Tg8803CSDIewbj0wmnKGBBpiEvjJF2 O4jVfcmO3NQuLvFCOe+UjGdwV6w3yrSOXsBV9r/YLyYEvpY/1D4ISruW SE9Gww==
+; resign=20460416024207
+32r.subtree2. 86400 IN A 192.0.2.1
+32r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . lqk6YrQbBT8MuA/E1BYoeyQz+FHQTLDtEVPCqCaZJv+wLfUMbEUAMP6/ kZrGfqjKSzVx1yGt1JiznUAmrR56TvGqt+f3XLVum/o19P3wgHgvMjF4 /l+68dbeFV0Voq5ZyYvjJJEXm52lYmJXMFIVnG9ReNWU2u5NHa3rq7F9 5jyXOkL4nf41DH+TYgMaInugLn2ILiv+xFdluunl32JQ+CRY6dJ9gGh1 2Ji2Z8exyiDTw0yzMy2d4Wx8CFVgq4bODj9HOvUaOrhkqdFWx6Oa6wSd U4ilIpiSo1jJtpXmkydJfJW2ktr6hXWYKrimR21N8Qx/x+AnfbuRDvLA ZtPSDQ==
+; resign=20460416024207
+32r.subtree2. 86400 IN NSEC 33r.subtree2. A RRSIG NSEC
+32r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . nlM0hf5RT5YJpc6bSoTlpxtdnDcEA8tn8zJdfqscAW1ryvgvromem+6t 6xqT3S6gsfc4VTyWDsQovcfo06pqJ6/MYGgIoxG2pz8KXwahAnCvpGvg FKb7tw6iTRH80Y5AI+05X+tRP84szyPora1Mslx+2hs3yU0Ksjxb4DWC GGxCREuhl1gcoVaoCwFLym/fo2dc05Aot3qWwQ73SlzkC9rLYIqSIr6o X1LTNhQhM88HnV05tMyqAFOwI3QBMwqAadUjFH0sTTKk/7rdxBp1r7KA Ovj3I5zA6kGvzEj8QEJ24QNy2de+muOgOyiBc2irKJiR6Hcs4WOq8S92 5bMyug==
+; resign=20460416024207
+179r.subtree2. 86400 IN A 192.0.2.1
+179r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . LrFGFdv8SxFduIWMEtdjxDERVMMcMOS9VBgCc8C9yytjbzMnOJMk87OE pDOAmeeQNPKrVWRm2hmj1+m2fJ1yYeIweC37OQsODBIlfNVGjGr1QjBL srhOzgO7944hDMcn+9ieyTsAVc2DN0wnMqMceYwc/gMUSmFZvLq2cWJ7 J9d7pcvPKuFB7pG7j3J5OC6qyLM1f84eCsJ4ACHHwq9yDOIDR0U4mPuw ENlaV7hYWbv8Z6ToDzSOUAaUWDU/ux+nJ5F9jyK4gpu4gBQDbPhpTU4N AfPUBDoX+bVOqfMvXezMtLlGAH6N+bJqqqhE+dnnPTa1cJdU6tRekdGG xTlKhA==
+; resign=20460416024207
+179r.subtree2. 86400 IN NSEC 17r.subtree2. A RRSIG NSEC
+179r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . RfqIuAFqyazXWw2CBSNtbcPHzXPGCx07mw9lZUYFupendhDzQvM66C79 60qWJZY9wZ6CK28Z2j9ga2mfqkR8yFFnYkEIuDNs+J/RCcPYT/CGYFXE COv6Khoi+EjNTWKMACXU7noHW/zPHrR97M0UnakDf/dv5TAhqbXrRZgz N7bxpEofHDAM65DbqcrLqUArGWVPz1Kv+qtFW0y7XvuR9hgvcf0iAV3w bnnuRmkntHXAY8sauP5VgM68pw2AVvD2Nv8ISSC5a9amSHaJ88IRjz8Y zM9vA7cfCdYEFSWl0+RFjI9SN9H2TOaWKx6eThr2+oZ31L8kg6+WvtZL MB6Avw==
+; resign=20460416024207
+33r.subtree2. 86400 IN A 192.0.2.1
+33r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . rT6kqQOhR1sFb7OBZj7I8waE84EkXeUERjRoqS2zaPmo2xcji3DzsykK Hn92fZGLnx0xqWKM7a2eaLZgd3UJqu0OMp9BqyqD6L2eHsr3RzP8I7fq 0Pg2R1eTmILdITobl49Ef2NB3e3pS8MQPFS1zBbPoOz4koltU0JedGLm TJcq8R7WAS4sVDzqBB10N5EkZw9f7qwZnYMCdwc+Kc5gbF3b8RDyuG2X /7cKUamFjOxa2vT6aZkciY2LlIjIo2Sov2q3GCKaZXO5gAjTZjx2zn6D /YVGwrQ2+2kXgodu4Jmz1DP0CPbntI9AS7MEU+pcwlsQsZeqBrIvshj6 ACU/hw==
+; resign=20460416024207
+33r.subtree2. 86400 IN NSEC 34r.subtree2. A RRSIG NSEC
+33r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . YWg57hOL7GY6L335NC6/SAKzYEN43au0NwkUbFaUqTlYtCFf2eOFjBvV tqkU+Ft9zXV4ATqoFm5dTLRHsye5Ahx+ie/Afm/XThUKtPwJ5KTJuPei eDH19gj63Jt9T1e2BnbBNlWTWWicRBbsc+18qnPYZjdxc7KKv9RMEWmE sGp4KdmSbPAXFSC97924oltJFQeQzSwrVj+NxbvwwKjLtSJziyF16wTR sCt2XGmun5dI6hwaFAydTSgGpjeSvuCJs8KwOmRJg+ofCOluXgPbFaaf 292CyrT1QhZG5/N7PHrsgsixc7YcUHQzmCpgWFCcW449MMPwPP/IteAX AK/r8A==
+; resign=20460416024207
+34r.subtree2. 86400 IN A 192.0.2.1
+34r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . qcimjAuT269n/yygTYNnWHtjvZHyXfBabyB3AWDCnW2v4Sku0tXD0Mzf Ps02oZFoE7lglN8TYoqDlucvghXTUCpdw/Xrf2ijSM+/ulsOWzq5Q5Kv P99kO+8cbaYyXPbwLIHTLiZrxxI91yfvThyDylw1bENWcU1RQIjLkIE2 5dMkVpi6OWIvjFVyOSR2/bFn3E5pe/qJsoKlQ1H9S09vEo/TD7zRI/zl hNBdp8HFpY+qkEOMCfGyG8+nbEXprxKbrH8mMBTM0e6HI95jBWbfM3yJ B+Z0TXRISYQN1my2RH/2W7PxJnaV97Z/+bT+tsb5p/Z1ihwDq/h1EamS gBPxtg==
+; resign=20460416024207
+34r.subtree2. 86400 IN NSEC 35r.subtree2. A RRSIG NSEC
+34r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . BK0DNEGbK/AHsdgiLxzm8JVE5PdwwyIwn5z3lLtZ3YrR2OTFmxYSEpdU DEPur+1XiIMxT+Sb2yoNTXxK+gwb6HGIQRdTh3o8k1v4QLh9RbaARvO0 i+/TzVnGBmE3K1mXq/PYaV9m66vkAJq2dIs8DV1fCbQNNowsrjYso1nT PvRL5grVwt2bYq3qxeHByYWJ/XSNqz7b+ze2ZLa/y3FYDCeLoEF/zaT3 AVnoRvFqo0nvl4mTpY4Lh5IDg5XbJRyqyYjg9Y4lHJXvXiGJaTN1yCOW K02dM14Yva4eGp0HQLiceaEzlNOzEbFnNrehZTme4TIfONYLVR7/xuVC X+vEVQ==
+; resign=20460416024207
+197r.subtree2. 86400 IN A 192.0.2.1
+197r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . TLip/k1giQhyMSwC1uCfuRILSHacd+aUA+0XhbEsh8qs39mgZv/DdY5E 4xJaoZ4MzjmkMHYPofxwh/hXo07b3KXyzbGZq7ujMSsuNUlZ+gjZbzUY 6aV3zYhG5ucsTAZmBX4qQdc3ENVkz/oVDA5SV6BXgK2+b401gwy3sV+3 uZu/g6TheRyt56xRZI4Kc8NRxyjqXFBsZLJ6qTz6+WLuE/c+toy6t825 yPZKW+ZVQJ+qz8SThKZ3Y7KSRUTE/F0DWb6flkenVrt8Nw92Jps2wTn3 tnzmkGjkYcw7pB+ZZPs07zLl5euy8XSsfaSbEgfAGEg49JRwtdEPfwkU m7/xuw==
+; resign=20460416024207
+197r.subtree2. 86400 IN NSEC 198r.subtree2. A RRSIG NSEC
+197r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . ACb3fWFqMV5squYz2Tscj7wvkUgL/T6OTb0dwFEBOqSqW765Dvu6qYEH fW0kZ3bbHgPNXwiEHBEa9R3QwBW7uBQtflGYy2OvuCMzh40KSE9L63rj uSpEzN/TkzncNO6U1UaGnYhc2BkfUCgWNZOLAZ9EzoFxb5aOaLMygrYI W27zzx0tG21v7WFlo1aSEpHHbIYTcq+JzhuFGDPSkeJarCif5ZzcEuJK 8OtqxTPj475hKBAv4WuC49wX9+n54koePs9KAyAI3qrkUksK4+JgSmB1 lJgW259pQahZTUrnZUC/HK8reOe+jlsYqKyynZ6lSI2VUUdbqvezz3Vq ZjiRBg==
+; resign=20460416024207
+35r.subtree2. 86400 IN A 192.0.2.1
+35r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . bi5mS4szw8tn/sWCtOn0l7C36ckESCPGT9F9ONJocCnFHLpLM4TRStGX I2tKmsj0n9uKcF4zrIGGdfGSnjiHSMwUFC6S2HIS1vwEStNUtB9M6M07 gHr9uzSYJ/3IqDAtbMUgvmzdPq3ZieuKLD9HqohgVbxJHll9wp8AKm82 M/5kVgj6z6igfL6WJh8b7kXaOjAodcLu2CO3yV0A75UxXejJhFEarGDE gOcz/WXC5EugWfo3tC4jWzUGTAUtZXmSblGRlwQlDxF8xMhNguTnmKi5 KdBOVK1Det/MmrevbIH+xPkM3jSj980VBgug51VjjYqffgfqNJa85PWA nmaGmw==
+; resign=20460416024207
+35r.subtree2. 86400 IN NSEC 36r.subtree2. A RRSIG NSEC
+35r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . DgvxjQQHnA3sEgn3bwFwS0AZchch1WLPt9p/HHEFj2ZPhV5lvHkLUGog 5Kwy1MIQBg13FA4ksthXrmrfHFKVbY/6hoJQZl17QD5Fcss/5BSmffrK NNFYoWSWZBnS1fIT5GZht1PJOJaW2Tgr6Znre5qvMTzuBmdjSg7XEw7J t11xkSVGMcjDeirVuSV6f/rGE5F6sOQFm+JjIUK/eHfJnhoiyV7xfDXz C5wO11z8zOYdtUiQL0swEG9gX8agnFifILSJhiJDKvCqweS5/dQbWw7i NA8kjolnA4/d2CXSwjMNgD0dtRcECrRVZlZPWpPIYqpnOY6yTsDoSc/V GG2q5w==
+; resign=20460416024207
+195r.subtree2. 86400 IN A 192.0.2.1
+195r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . RWYPW616aK8DqdJYrm2mwQPT7pbx6/XgT4CYEHnhHh0RZNidjGY5YV67 K2+PzglmTWR2Uzedd7p84lbyPO//1XNaJRqeOLd1omwtYqEiCjUEPbIe MH0Z18BR0GKPbzzy9DSRAAJZnOGvsrumu0XDUGg2Ea4FM+qAkFCZR+z7 cp0H0mhZZLQIGanjRC5q0qix6ZKSxfiwD2H5Y2XGTcqbcRcrd3vny5Of HYymaLjznirsznf303S0itFM4tulV4CqU5HUHWoLsVm7qYv1WdMisrUo M5UB/AVxOt8I1UCx1BJQth68oVYABV2aHbyohA19hv7QYKeZA0EJrejp tks0aw==
+; resign=20460416024207
+195r.subtree2. 86400 IN NSEC 196r.subtree2. A RRSIG NSEC
+195r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . D0VbTS60UMRR9Ty6w2HgDmIp643V3JjSt/MI+CrJwwPFYIfjDA+8v6T7 BIo9m2QZS1hPJdwQEz/PV5lrkU0l09WD73VjskWPr2hiAQmQGVylPENW 38v+BNya4V+6aEckU/ldwC7V0y8zoN51b1gBnDYb2Yj5Kd/KpcpTcHhI na/S7oeOsSl9UufRAh9lUkjaYw8Y3m8ino6SVbDS7ANF7CYCwlGlyyBp bf2cSZ3TeXSf/Y7GfzBr7PTTUOUMW9AH5cIcbnbG056/kzSNXvNl4K0b 0CEGBZt3FTuT1fX3zKOEfhxegDHSaaerHvF+/PkdexK4SZNODoRRTnaw 0IKjLA==
+; resign=20460416024207
+37r.subtree2. 86400 IN A 192.0.2.1
+37r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . WA9J4U4AzItlWmFpWAfw3oRmA8pLslxmkE+L3bOTkF6kYty2ofFU/zYs D4YwPNotnRFcKYsTbfaoW9RNztVwykFAS4ibQz9FFgg4pnXoE67DgTLL d+VCU/hQOOcDKmg3Huzmf9a94GY96e0fb51hcLcSZlPNgay+7KyeNMWD 8qhUDhbum9BuYccVf97GhnxFN/0n4DI6hBPjeU0POeTstCSafVayBQiq pWX8cr3TcjoX8HEdFDdBtTs4qdS8Pz0oBZY4zEkZO5NhuhFXRoFnbRQ2 z5NJwhVNrcfOvGsUkJlh4offEmFjTVEgq+ofZocRr3yl/jkQkwXdN4B6 Iesi/Q==
+; resign=20460416024207
+37r.subtree2. 86400 IN NSEC 38r.subtree2. A RRSIG NSEC
+37r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . dRmtxyE/pd3HrfPLz4z76U2BLf7nJaGrzQXHI5h6Sbsh/t9eaAImp8OU jQmBpzOvzg+8rvZ+TFuQZ0mYMaL6bN1t3+txBcSA65pueyJK8e5i20sl DzhVmEvEjqkOVTu2P2iiUGUf9TNbAMVELk9W8I77iK+utruxgTUrMqnV Z+U+Mxa67i+NEK3H8PQ78mrLReXici1TjJMwnZpm+BuZU50WY5vMH3Rw 4FTwTZWzgpTnz+Vu/8Qih4VT2MmzoUsZ5npCxfPxOnOYv54RLX0v7otk JhYbUBIfkVq68mParT9bJsQwSRr0pY4Gwq+4oZ5LGzfeX6JBqyx1k3l4 laI+jw==
+; resign=20460416024207
+38r.subtree2. 86400 IN A 192.0.2.1
+38r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . pblieozsh+O0C6VPPENu2oJ+lGA18ZeEC+jYDhklIgLltx5W+RcUgbjq eWj7gjecaZMrI9aJ76J2JGoairSj8UmIzZ737pSwWghRypW/pyins5fJ lcnTMzRmx2vxfwJLS93HcCu5/kHZS0NWtGzhOZmDVy1I1yCgsXF0jbVP YGSk19tfpYS/4VVRhVBB2waiS3pLFAxqe4svVDoTuoFQU3fNRhr2bJCe Maz4J9d8P76aZklq6ayJSbBkOMRUVYPJzCb+tXiNam4jbHQX5PXN32eC soG7hSvUMLkWHv5lh6qlL6UkbH6TvBIfWFWP1249JRCzVauyydy8w0oD cVd3bQ==
+; resign=20460416024207
+38r.subtree2. 86400 IN NSEC 39r.subtree2. A RRSIG NSEC
+38r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . fdUgsF+Ooo37b/16LwnzUT/siY3r2sYOZbmw8AzAY7pUGoOkBTtiS18N tFxfg1FLVEJVEI5RgFio+UVHCXqo4QHi7+pPVX1rJUE3l3W6jWXgorek du7ltSs+0lI7eNLsVK3QOr+tnrGDraYEPDMSdFSHP6ut7l50nhA0z011 T5cDlTBbZ0YoDmTzRJG6mfcBJImot2fjnaXfLj7dnTcTepPYymaD2DzI 5ehDBcIEfbDitLesT66hkfPZgEiFpBgesVuXWH0Gw6UKtzVzWWy+OjPO sdOjIQSCQOCmTjleyqNOYwyjPf5Gk9G63fp5gv5u8M2P0Zz2YsbYpaNy RudjMA==
+; resign=20460416024207
+39r.subtree2. 86400 IN A 192.0.2.1
+39r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . P2mN37IFjmvQJS8FOFI9YmH9A1Fya7Pssvowi8aqe/6/vxLh++kIgQwb Qpi0qZ+q7hQPXHNL4sW9nnnSUL5EtTNIw0W3XWG8Z2iHbO0fQiK7rid6 kBuexJGDg7nwm0URucUQAeF4kDTeLa+4KVzGd+YMph7QQ0quUvWNFhZD sW3dtWs6Nyq/5KNgcUHnMX+AEMwHDKl5bKjdXdO+oVWlClx30bTjw4Y5 PAuDcyZ1qIJ6U5C+9FF88paUF9pJBKBIJHuxD8FT1yxibw2tjy7cceH5 +aeEAzgCKBPlyaqa01i/V6OvjuiVHmWkbe5NaCi4MG5tbcPBmFz2BpYL 0ndKDw==
+; resign=20460416024207
+39r.subtree2. 86400 IN NSEC 3r.subtree2. A RRSIG NSEC
+39r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . fewCkslhKIV8nmOAHl+4sSZfpEtN/wMQv1J60LylOq9eTDO7P6UkgWrb Uhp0Kmy3rTkSMUASSf9rBF5Kvp0gy7tSyzB/63AmXLowfc6DqXrudUXA yY6SlmsRoMCnHh4ZOLi9QeDnkPJ+sR0Hy88IA2OOoFmwVPxInXUT44m5 xONo+R7vBJbJqChf3tZQ7DYreGstYtIsC+wa3Y6rJB1SVISgOrOF2Thu PfoFhOQSySS4fZWTcB8VNA/vh739FQfEgA6T8wrHco+GeIUPQ+VrQ7pM GuhjU22bwpMIUbJBPzVPPhsQX4U2qkBQBfoMaaiE8+hR2DM1+lmea4EX RW/e2Q==
+; resign=20460416024207
+3r.subtree2. 86400 IN AAAA 2001:db8::
+3r.subtree2. 86400 IN RRSIG AAAA 8 2 86400 20460416024207 20180815062314 48409 . sU3DOOce80mR6N3WVfsaf2Xg0Qo6QnGLeahMzLs4YjwYS9XBxUd61VH2 mIvtoGFTfhoC6gy8I4zP5gIWNe5NjiS0BPemHH12i8Lkb+1oCo7KnWsH JsN3fSB6eVnDxV/LxzTCWh6gbB6Bm8q8TlcfvWXJtU5hCAsy8HgWf0jr CgVWTzFt51+wNpIARB3FvZyLr726l1wS7KswNywDUe1MH6wa5w5nFiE+ l5X2K3T4T0JA7nwkl/are+vHOEG2t7vAr1BIdMeshVKctmlwhd5liAp0 hYchVGlSI6OPItTZmNyPRfeV3THnDGmnyQG5b0AFqoj7Te0l2zWjtY2l PG3iAA==
+; resign=20460416024207
+3r.subtree2. 86400 IN NSEC 40r.subtree2. AAAA RRSIG NSEC
+3r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . xKHuiecej9QlBaMSRUrJ6v/Ypf4uoW9QoHwOegu8smoNff72DEqPJqae D39SxdHR2ScYSMC//s7MJWYersa3kNnlYf3SBwptmJ2ujbRtE8wnhQCK 8FYKm7GlhI/GQucUQ2wdepnvK5pgb3kCBXjhdOU37qVm6n4qZlF8dhdM dOk+lQVYOPQO3Y9B8mjRg3mZQlMElalsy1po5SQ3zl61hXNnIBPnx9jA 0S60PGW4ld5U4x5iB1FEPPA8D+Sj4Ws9bFrqg1dCb3XIOd/YjqVLancF DfqM284ADkrafTJ5UPV50ZfwrQZFGBLHEoQKPOmrWOyDOxpy9vYHRG8m Yf3XfQ==
+; resign=20460416024207
+40r.subtree2. 86400 IN A 192.0.2.1
+40r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . A7xKECnu9zOgb4F2UURLoOyUheOxxKcktttx79i1yQUSurRNYk6Ysjkb Q0gT51XiNlSUff3wmFoouSfhLf4VZiss86KceBEhFMjjQBguGCYk1/S+ xqYJv0UJTyFWOM4or7seTziJc8TmD48m5kkwl6//mTBzocKrzx9TDQuT /we45WxJ6zuuXqr0ZuvPpmCL9KzkNb0HDyPVqkZxhhiIqWFTyUupJP2g bMKZTg8sFw8DZpW1K/u78Q6d4tYT/GgwSI9qa4O5wh0XQiTbjF3n15k+ ZmvIxf1GeWByPPtKwNEyC/aDqWKO5ItidUEot++m7eiOd9zEzaz7Je96 4wA8tw==
+; resign=20460416024207
+40r.subtree2. 86400 IN NSEC 41r.subtree2. A RRSIG NSEC
+40r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . MIaDOwIBq4PYeIy9D1ylPnQ5HxzEf4VanIQA/gMOPh7Z1fzL8GeQEtSY +EvdfhdoepD/uWdlYufsDI+LCJcPFi2FCn5yh75IzDUrQrZwIkjbu7rP 2gc5BLldsVXeyWYzE6bzIZLQMjrtzRNrabm8j8S7dugK1K4XEaypnZy+ mW0ChqV9+GjiO50cadKsDvVTl559vxnHwJ7bqPJUPFjU2c+frvnjIeb0 zIhcY04c3moujdA2n6s/7dJrw4OrzeolRCINFXw2t/tmErIiY/cmjj2R CXwAs1VVJJ9k8wInh2sUqIYMGHHw5gZw926waaf6VMSaOgDqGfbYrhLB ROhzlw==
+; resign=20460416024207
+41r.subtree2. 86400 IN A 192.0.2.1
+41r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . bsi86MRk/KpA19c6ZJzuyn45MfDYEASbGe7VST5/BBofJ8IbRyl0r801 vlQN9fR3dGhceYK8A/9TVctwQEJL3D2cOA5PC26GAQffdMhAWa0ymcKQ DjjIGc11IXrvHTD+m+WCpFoCEMXXjLXq7qizZMZgMH2cERe3gv5xKITn tFjGk54f0rPtz7D61Or1t+O3OK598ykTHerIuPtoBKl8jktGvuv4N0ef SLF3aGa/sVigDFX4BdMnoJ6JlLSISoEe2uPM3ErzF3emcK8cl922NrF6 HKpZN8DGaPrHHFrTST4/S7lrLshI9PI3WhAhZz4CaqgMD8rNM9CM19sv dbORgQ==
+; resign=20460416024207
+41r.subtree2. 86400 IN NSEC 42r.subtree2. A RRSIG NSEC
+41r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . LYwfi7/RPz55u29u6/IV1kcKwJ5kL7HLq5a6fy3jWyx5xgIEjNuiHbyT 6HnmsCqEEc5P5NJKd/LlOqRi5gFXdzj1oyXp1fzIjNCnG9Kwc/8PxusM eJ1COjg4FHxd9+ztUo6/PDaIrFC71pjPctc0GE3ZYO0q04mFd5XspZ5Z kEgmA0/BgeCGgOPfdoXQcgiSDUHxxVm++8zXwGBiPxoMHLFjZbSFWZUB GYyEF+v5L2bVIbUj1Bg0bCoNB6NjwRLC2i5uYp9UNIphsmL6cn84Mn4b 6rP2rZA3h6VYmthSyt9Ky9V25214UnSsjavwqwNGtye+Z70Jx+I9sG9k 5M6ZVA==
+; resign=20460416024207
+42r.subtree2. 86400 IN A 192.0.2.1
+42r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . qRnF+bZGZ00XSgjQKU4lCgVDrSJhVqGbS1Ol/V9qn8hvzCB4YfHWcA4C 56sQuaQ/KGIC+WmJyPNpvh9wgcBduHkS1hUlqPij0Da4dDGLMEMrUTFU RKK/2qzdUilH9Ults69x31CYWE/ezqcjevRqPbjn3cdManj97nJKhR5w EXB8ysIsctl2f33lp0RE/JPKUpazIZ4R0sWt4vv+CbR+KNiv5EPU0eWf 8CO89fy3elQNBVmPwERRkBwRunWpQpzbS014LeNg0xPn9nDAJf2Qe3i7 6ZO2zr4pHipvu5IGlxHXllgtj2XlWa4OTnzZlVeHk+28zHedGTaUFWR0 E3zolQ==
+; resign=20460416024207
+42r.subtree2. 86400 IN NSEC 43r.subtree2. A RRSIG NSEC
+42r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . UYhqKt3G81IiJlxhFCqv9bU40d5YJBIolLXs7LOF+nHQq+9gIIX6Bfff wbxMsKlSzJ9fJ1Y1+IxAXdh8Y/YlhrXR7UtoseUyq5VM6x0ocSkaWOOx N0+cRtQKZ6YhKJccGtkoNHHrri1uSoZ51J9j+LXxycJQ9HfRj/fDJNMo ymgX93WHDJSGh0avAWrr8Mb9MgGjXyFDsLR4cZNtTAUga6TGkajEyiuZ c6m1j9xP6K/KOolkcQ6kz4YK44PS8kOwmQs4/SXGPu+3MFEbRW4FxHMq p490lAFBaZJuVT5DcnOep1VRMjROIu0nsTYqp51ewyV2zkMJoUvCSnnn sM21eA==
+; resign=20460416024207
+43r.subtree2. 86400 IN A 192.0.2.1
+43r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . Kvr544ICf8eFbn71gsp1sXzvkI0Ex0iJdgwsOWol2RpMZQMy0uuDCgJ3 EqsMrOs2ur4X/iQGdl7KEzy4gb+geMX+PiSI/KRKL+5/FNRUSsWWlSGl LE9ZibQOCG0JBatP2pr2tWhCtafPg0FYi3YoM5/o8j3FpwARAE4WoLp2 44sIXy+gr43SxGO3t7tqM9et0R2ZXcIxm/DXDeA0HvmXTHNht2blIwMM al/hKWBnnv7nFL/tdcj3ObBQ7acQvLHG5UQEs0KDa2qgEg7uhC5X9XfO x1QRaHcWsRUVdg27nSbimjdkmQ3EeUos2m51bKWYofyunxzKsghz/tD3 o4Zrpg==
+; resign=20460416024207
+43r.subtree2. 86400 IN NSEC 44r.subtree2. A RRSIG NSEC
+43r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . Fn6k1x9T8zEmERcMIoy2xSkEAtktFQKwxssGawlCbMx3n6crJrP55izf MCX4XimmDGQhRo0m4qBJ7KHqwiD1+/WvAC/XTobA6MIaOXlufoX8pv5n 68DmKY51PeBVbXSNHUh8WYuH+6tJ30zGJvm6hjtq0+HuoG7ftfKOo2u/ 4CtdeJUHJZFHFe5fcWuG0Kw/myPHxOjnsG16u4Fi7VdVVBEPSsIjhrms fhOVNc7tmxboVqovy/pbWGF0OlkR8eWWSau2vfWObjz0tBCnvGpm23y8 qFiO4aE2C1U4Ih7NGTFuZTqjDqinXHDGUXqvJ7DV7GM61uR1da4Zcq05 qhXMfA==
+; resign=20460416024207
+184r.subtree2. 86400 IN A 192.0.2.1
+184r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . AoAoqS2lHHYIULSHCvxh8Ug4hHZH9jLaqQT7jp+xEo3U63ZZS/EU4oYn vafgLQVPT5mFOI5bqxewmLRJwypAom+B2dte17UwScQV/xdFRO4rEPyb p6evXP+LezVz7GxuOC4itvgqjv8l6nNGSNtelA/BmreFs4wMKk0+DHqC mOtutq8DU1wcBpqmY4DuRKoqtpa2qu51hQ2kEx0HaQvAb1UgI2Zw+uY/ nXER8wLzo+WKYhTGWjLDg6ESn8HpeJlkU16Pbs8A5kAv/sca5nj9TFw5 h+a9bSbQbD1aCWWEFjU72KynjkLMD1fZpw2PyqdviEaylyhf2AXgYhfm 2lH1Vg==
+; resign=20460416024207
+184r.subtree2. 86400 IN NSEC 185r.subtree2. A RRSIG NSEC
+184r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . OWD/nVsmu/buNCdLxqtVTdf3pMHPIed7KNxMYZR1rhMFeR4Bc0mEVmaz UXg5GY/eUhaQjehddrSCxkytGkwi4d1kwaaIrpoXvEIGAWBicYMmg/dM ZzYMfzayK+L1q49hjaitJy9k+sOQpqPY2dkKijHpjPf/hEE00SXVZxeH 93s7/CD8W6Eg4TvSGcVNaaugVqLkuOyeQ+tWK0Xln7nJvjv04OaQKKaP TaEWP+3aN+X7mHVQtL7HMA9+WrSS5XD/CZDiuhPozegtu9uHLhvdKtSV 1UcIuMTSwSwK5FjHbC9IYQ7OEq18g1xfp4eztDZgcB5Ol98WC6CqFesg Xkg/uw==
+; resign=20460416024207
+46r.subtree2. 86400 IN A 192.0.2.1
+46r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . VKFVihKX3Q+MWR6GdmeAUnl5GMsh3KB+fBEyvEEw19M7ynjMfZYzVbjH V+AG19Bv9yuh43xL8fHmEAQENB9Q9WBzjZtYEonjVgSw69S2v1R6+NYW PLtMpDaH2oOwiGZzLi2Qia2VmBt3Ahc+dGagb73ex1IOS6ufo5ypY6vO 8x1ASGTVbWXv5ohumDLHu0iS7D8Fy1uiufzozz1bacOurw7pujk9TD9l 64ez6AFWHC+nSP0XdojhZ8Ce90ovVKe/GCMTpx5OoSAMcjQtvX4Bg6J6 ujAmHyGyzm5hiDeiAvb8WVhazs2t06e2ydDpNCsI+X89HYYMcNqzFnuN QcDDtA==
+; resign=20460416024207
+46r.subtree2. 86400 IN NSEC 47r.subtree2. A RRSIG NSEC
+46r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . tx5Hn5ZIx9soDDoHxWHwU1jDu4gkXQAXTFA007LazLVO4n/egQY+dejh yA0zh6Y1G2f+sTlmlv8h9lh9ErNwjLmbAkkBDZabRRYzuypu3+94alFp MVyDHPOSycmJeqrJ60iMINk6rSMjK8W8YoPU08Nb6kuZzi961RXrUbh8 GmAQ1dkb956i4y0o/ziiJKqjytdxH1eioDRiM4Twq/Wf87kK/FeSq1XF S7naoPim1ByXoT5+/6iJU9eaCfGGKAnlvLo4KKpD1xoyGxkuB6qED5yM XhxYJC6XwyD+LG7DAAMW3om6pXIdyzvaJ9XAgzLTSBGa7FhjIA1IoUf7 3m71jA==
+; resign=20460416024207
+47r.subtree2. 86400 IN A 192.0.2.1
+47r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . A2e7UIuCTt7O/bwgjHxQRM+5g1QIqlSOGYUzIiEi1xrfvMS7Ap70D9PI uU/tRQJosxE8E6Hc07wesaBAAdXLuWKX2dXTJ6cjAMsZY//phpvn7u4y 18sRFci9QYkre5z4nYFL6Zgwxi1MM7NLM/J8lsTVzgoeOK2V3Ey6tpcc qH1BxUCBFgE0IWz1Xg5P/ZjIBdv0VMK/nGipatg2mj1b3szoT8h+fPO7 RqBAFU1PwBlzuc6bDi+KYqo6JIMF23qVR1ePTTXSkzgY67J7O5+/CO+G SXM3uoHBgQV13L8HUgcp2+KRYtwoAHupBCL2Y5UWoa6sB0i1fojPBdlK taE9Fg==
+; resign=20460416024207
+47r.subtree2. 86400 IN NSEC 48r.subtree2. A RRSIG NSEC
+47r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . VDLbZl5v/FtlQvH1xGkQBkx9eh98GJmAMBVCUx5x/tcesCBE68TJveyD AMS1uq8McnCk0x66Qlftp1bw1e1rK5HtMfXQEGENCBGEoXwCes8vpjpy uo85nAMUUsGvDnAsALGqe4DCuablB60Lt5OEn1pAMOun+DsBwFFlyw1G zbo06EHp0hzdaqNc0qcsjIpZDhUqen18KRUDoKfBNKpMe2IU+X3r108L G5kGMpWd3OlEFY5veK4t7V775oBdCE4CDfbSCpa+o2LZZDM4H0EEaDMt vFIYqnLoGO7wohqibFsbxYUOkeoPEod4CWZqPyHf/1Dgkx8J7yzLxiU8 1uCK6w==
+; resign=20460416024207
+48r.subtree2. 86400 IN A 192.0.2.1
+48r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . Ykkc/1flKPWBnPKjhiRWy4wz/LAh8Tt3yNRhGnOGuDBwOHO/9Tq89xDT CNeDVQTf/+pLL5r6R+MVT9nhHQqgKdaIGHAy/d9WBswp3Pcm7ByqgNgL gnYwtGpbLrc8yOEkHCWHSfwhonB24itU7+glSdb/y4mYnkNAxV9ueaXv RCHIXugid+yLFUTrhdhB96qQbtlxzRxQ/enxj2b5O5YHyJ2Rv2FlKatS RqFamOUdG7IDLkCMFi17CrxdxWJZ5DTrHlLcke/AegTK1Yc3l0Gxa/aO xUN7CBYuFsB22Q00pGEISNAmD7+pm5Dc5TYrEGyoraFtPD1MNMHoQNI5 9N7vLQ==
+; resign=20460416024207
+48r.subtree2. 86400 IN NSEC 49r.subtree2. A RRSIG NSEC
+48r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . QymfCKG4unijOqKrhyvBanMddtMkStDiIBh6CvK3Nhf8hhk4OSBkytpp 3M2Ttx+jgKSAgSTqznWIneoNDP5vVcbyIYmgXDEkYtfAPc1DptzbfpQq +vszKECAEmyVVWeqSZyypp57TrIYErFlnEWor4w/E/EtyErisCI2i+TK Sc8yXLp5PHfvT7EFh55IW4vtFABm/8naMNPcjFAmcH7fb8WG9IvfmXtf pZ6XpxDXDK8qpmmI3R+3A406Q+odh1i2H2ThhHqdqN6CHvdHDGsPgsSO 91dJXzO8vk8JKnV8Aqv0BeOS8ibDr4Qn82HfnRzVCDJo6LD0zNSxZQRa iIfUYg==
+; resign=20460416024207
+49r.subtree2. 86400 IN A 192.0.2.1
+49r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . ezm24FUxsSADHw205OzxUPFqiVQqmqU/ulXC8Zp0t3WyH6loCR7Zvkg8 J+qY+6UjHAsLsntIVsgbgdrz3hJyyMPNOv/S+xuxSVXsQtisEbLv36Pn JD9G8Bb9bKS/1jwHKG80/AHeEOWNMHp81XKw3Ed5rgygvtpN3qHsWU+2 eyEHgY0izOthVLETkAEbPXdz87+32GRunaNPExsd/yJuEB+y+55bXzzV zvABwWFPqujHtRiruqheAe/eb60YJigIESp4C8PKBgWoD+JEt1wyqssM VLG+M4itKZJamxhOkhcq13R517e1ojVBahJVN+ebGXPYu84KhThDqu4c FtHXNw==
+; resign=20460416024207
+49r.subtree2. 86400 IN NSEC 4r.subtree2. A RRSIG NSEC
+49r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . hdzkIuLtYPu/vNfcHDQKqNfpEZiya6TzbBl+TpkHVU3B6VhD56Vlu6rg j36ZBdTVBk8X6hB6rFjfBN0zFBz1IELsfrKIM0tQbceyZcvAtal07nCE bmDOjYBwKhgJAJpIm9FGHJp1NXj/QtKDaLgjjG0pDSieSb1GVBqVRurg D4F1Uu50O0BkvFSrtaNkPpvfnVoDl6jcXW7SxM+9AzNZVN8WXxGP5qkf 5zrAhV1AdpadSJRkCG/K2QE8s1ieNKnHunrbwZJddQmpI45GKqx6Y16m sujnAFuMhQVpbJu96ZJC+bAcDwZJq0k2yRRhouP7fGG8U59jDtdLrExp ombApQ==
+; resign=20460416024207
+4r.subtree2. 86400 IN A 192.0.2.1
+4r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . F9q3QcjC09ypEBWW24dfyAK7ir/MwOwPBmn+mJTDOV3yucmdddGJPIj1 VbkasV4bOfbAAZo995tpqOzajtv9GQXRJVnFPOXMhlsH0ivTTOpXNJUG uLIGE8LQ5bc9tBBFtsyKjmNzfi8wez7gD218BLsFcHjbvUtd9s4BKA8M bUQ8bmGWx/GXKQ4Y9M19kPq601BXdZsYgEgVSIR4BXnp6eN3Q0nI8SS0 7V38fkflVmkJ9bpNyd9RJ7n5uWLabp9zjYzeAKyEtYV9HEcwnfK6e4Rc zh6iCQwFzL1pGWj5JSf4kj7zmgFXDXtAl11cYQbN1dwFraA/omdhqCLF KuENQw==
+; resign=20460416024207
+4r.subtree2. 86400 IN NSEC 50r.subtree2. A RRSIG NSEC
+4r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . lWmq+K8ctJH9sOBT55z1Eezl4nH8cOiqOT/1NqOYueq37sasHFcaQjUF gQyI7y0yXjD28cV/qHp25Q628ykNdCI05QkFeZIRUTEp+VGtvsw4yz5j DdH8gju9y0eLgAbHz9KshK5mSAj/TkCkVs+nZIWlPNiphSS1v3o9bB+p iMW380SYckAzzcxMstgc6sjXnx7zyXyXOm5edpSbAKgg6l6x7/gjtriY VhwhVorMgUFCtVYlmaPMmTaLhVoZIBArnjAvJmjjCIgNqz7yCLxZjKKC k6HHFB00yEBM2I9AxoR28fIYuAfnjiAnzbjJPm55/ZMHdvHw7s+2vnbw pGOq6w==
+; resign=20460416024207
+50r.subtree2. 86400 IN A 192.0.2.1
+50r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . lLNbG28vWwUBWSYedEh/fKMmV8/Us4R8x9VI1mq3+I452myBhHOsJ3bl p+qOHv+cZEqo+xzpYDAUeUnNaobLBN/4j8kmfxNFuB1z/HkbRDXvJNr0 nbA6d6fTt7fJvnMql4fU3r5D6OitXeICpLCcbvQiwbneEohqtnHrwR+3 Q9WMazvhOw1a/2ByTejfZpc5sLON124g6FfVdMxC0XaRIEqYNM0nMAxF n26TYRn/IEuURr2eep1Tq7fptk5GzLyjKi6TayaTY0UEtcE0XNTAel+4 lv1F88cexbNZxjL2SHCknlMgqHHN9AS8z9A2gSBvsBm4jzRe7XkWuaKL FJA8tg==
+; resign=20460416024207
+50r.subtree2. 86400 IN NSEC 51r.subtree2. A RRSIG NSEC
+50r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . H3cmRJXJ4X45iOimYZCErjCfKfbHduVSaGI3YMtHJSogv8/Z1yFzmJ5I pn1GxWLz4vpi8QUCAZm9owO9yyTaswo/WW0gw8VLccV9GDLaKWFvycZ/ uHDXldXu3fc/Cm7PN3vfLMl+Uol4bfYFqeVZek9QfI6Ircx8yYzUGcpT LvnCHZybdEojzcrrvG0yk1LlZtRJNuGRw94hvDGLwnZ+a7bmLdcKUqEr MLN/TwNSnVql7gs5rbXVraf2aCoM63INfPn91lm2SpzwWmNac3nsBlaI r/5Hg/OsNoWGig+Rot7TgJjxtIv+VLY1+YN/hyHujzYpwyfQuIxigB8B TFQ1VA==
+; resign=20460416024207
+51r.subtree2. 86400 IN A 192.0.2.1
+51r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . gBNGIHyXcyLQ+ZU/0R3kRf3H2O8kb80etRU2/+5288n1fVE+nEXlM+Ya Oc2a9tl+XMRye0ZkATzgC1638pgnV0z5CSzFL9LyCMx7xe6W4gXeilG9 Aesrf02goUqc6UJ68OdplU5dcfdTT3Ij7Hl9uw+UQN1gD2D9CLSntQaK ME00tDN4Gyls3HdUOp/TlpqsD4ctntH1G/9L0Nls9YXVfFD3WMQNG4+M fmurYbS0pDBMKEqq9K61Yu8m0urSbg1PFueapf3873GefLT+4qzwGjta 9LOSfIuVKlQnWtWKRP96OLgTLOQABw1jP/p+DSH9AdNoN7BhHtJuQVBF D/fOJg==
+; resign=20460416024207
+51r.subtree2. 86400 IN NSEC 52r.subtree2. A RRSIG NSEC
+51r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . UEPbjqGh7XaADbhF0OL7V045Dzp5EpX2uqeEsXI9D/FO/yHaO0QJDVNP C7DqGiJN3MJtlFurpc83hrGf1SiTI6CADAGz+osDktqYVotn6hvXRKd3 0m3KUocCfbBucsL3sNQNGu0fBgEoVxvA0i02k5E00T+ltdWHLPsdSWMm SzdbjKpyE48Y2n2gfEtoaFKPonf5EmjjT3YdG+qW6CwhvhsfgDizXmWe y2vjBB5r8Ectcfk9RRYu4Ru7xRBioH3zQaG93RspAHfvcSACgastkBQy AP7fdnKq1LWCE4Kc/1zVnaS5CMPOw9vbVy2hr3geonnsRx3/+NXb7Q1G MSdvqg==
+; resign=20460416024207
+52r.subtree2. 86400 IN A 192.0.2.1
+52r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . ewHkfBF/8w9XGYELtXG6Fp+d7WeqJTTcd4zMIpYKBsYKxB4XBi/YQvnK 3uYzsBV0sK3OlSZf1jDqUQ34lrLfQ8nGBD+ljyyvy5OgXgQS6MBN0u5o 5kD1wnSLFQPcrAzKjwVhxOK/DbfxoVdtSFII7gh0PXrXfx5jKTMd7HDc BipWsAZIz2twp4QeFvaEI54iwds9rotagYWmPYOoc5QlKYlxu81siI1g m3EmMxtPJ09BcGhsQvBU+djGqeF7oVzrN/juUGeQ/JWlRQYOrlrdUvon VQgwgjnV1rpFNqzhZ6L4md/SGOE6Izg+rdyp2Q+tU627CJTz1scKFAzR M21J3g==
+; resign=20460416024207
+52r.subtree2. 86400 IN NSEC 53r.subtree2. A RRSIG NSEC
+52r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . BRSvHeJ6gloEmQhGqk2jSenQ6x2lfeJm9KT3rDuA9z2kAdoTAQ+Wg9eU DJ3ntqXBL8sBBcnHc7U8MHblkt/jGbSsvDJ/9T0AWNMuBpflemuCimT0 lNnmNcIzUbOaiwubIolpP1FhG2OSA8vbbgt35Ne45GYw247YDEbOTjvT hB8nnh8gQ5G72qjl+InXtCXoP5aGfEDAOQlenvFrYF7HI7PIykQThodW 5KjEnKo7pPA4feI7FwlTghtHBZzFzOaAfHVdxzrLwgh70WQPmyV9AxBS o9LXuCcrPRtNfCOvxK/j7LpWUP4R70t6T0zR/IZTlzCtERxPqwtzDuxn ivNLgw==
+; resign=20460416024207
+53r.subtree2. 86400 IN A 192.0.2.1
+53r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . FFU7L1h4L6Lioi1W8cu3Cp1/K1EJFvkv0zAZz5gykSQuqeOs1RY6eOQw qXndjRzl02Kel7QZK4j/Qy0rEaJ6ydwA3+c0YFOznWMngWiZiVmSlyRr m4PROgaZ22tMdYp7z0mdyquSD+CljiCf2k4PXqsD+C/NpKP2gUXe7agp rsuW3wP39QkqgbtBgbkezFWQDX3TOLeRcg8beXasRB3vsVIDW4VGWaKi lFJRBsLkZ64CC0yk6DXDQMSIeYmbOHVMneL2CIPDKFVJ67IMXg6IJnGC N+ADMuT3B7fpBZ4A59tl3tWDCYWniFxXsWkKVKDy3eZ1HXeJhMc2TpUd NXbwWg==
+; resign=20460416024207
+53r.subtree2. 86400 IN NSEC 54r.subtree2. A RRSIG NSEC
+53r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . PjP6fMBsBnPv9W/U21JDOZbPc+ZYfsmQPv1yhoS9mvIdJ9dvQ+fC+94o 1FHUp20e6LhIvtw59Yev7cqE7T+k2YLVS+7/WXDPbZbi8q5WILZWdFnR +D1pJL8c1AypOYPGEEcxi5tdyGJLPkenbLp2ItHY5qS/P7Wqq4GZYUp4 Hun+2aL53pb22DSbKYaB67as+MO65th+UM+RfR1yfcWJy2npxxrpq501 FAxFUKYBEpmav+nqb0EguHbrcIr1vuP8RN6P5h10ztS33Dm9z6QWSevU QRJKH0pibyjlx5/JUZW5dzJiB4KqwW3r7hW+VaimU+lgEX77WHCp9DiT tqsGhQ==
+; resign=20460416024207
+54r.subtree2. 86400 IN A 192.0.2.1
+54r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . BuAtQSYX7m9/L+aQNy+fGFjXRJXJneIsiDYy7pdQtzxzVGr3soBBZHjN fpjCCc6UhFWuTBnY6FAabq7foiZAMeEACFLG0vpSPyvIudRs0muhdFwG mh/BCddf4SKZO8tcdMmgqa+zsRDqGFiPf7HMcQtVVoNxZndRxP4/1Edw IPwk9KNFQH+N/QJkrrniEN1vGK3Zw0b9VRY9oUcItIhVmzeinA9a+60G Tt8MEZ+HQE/3yvuV4BtdHghwLW2w7Y7C8XRd3MZNdA0n4V9J+pQAFuaD 7JWPNC90jgrzIPqRVBCVLT3UtZcArGtrUsROQnL5OMdXFH+74OH5yCBj ioOZaQ==
+; resign=20460416024207
+54r.subtree2. 86400 IN NSEC 55r.subtree2. A RRSIG NSEC
+54r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . ND4W1IR/Lbxy7T5te9P4gAj67ils/qnhHvJDZ409BLe0/Mh+cdJNZaF+ zERJElLqu6e0IiJI4R26AYoWNFgccDzLIEQLJRbHU8I9i+GoA0iGxevn /gW1hoFiWFNLONkjL7948n3n0qcrcNtfXwDmqjWB2IsblMpy5lBqAXu/ SinsqHuwqD18ApZlWMrQHwRKd5qyE/nOGv4Jc8/+WqAII4ViI0CuGrGG LEnx9rpZ9JOBg02SolW5xZiZ8SmGggm3BwWNti3XLjBun12leVWdBjB0 0z2gbPXapoP8luwm88eSZa+h0MHJCVB/980yCZW0YXMP7dYpshqMcCy2 ROJqeQ==
+; resign=20460416024207
+55r.subtree2. 86400 IN A 192.0.2.1
+55r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . MxQe6tBY2obbRhjbQS29CMBTrdxeHthfPokgR/NVaS5oWQWw7QiLh8dG dZKMAYul5kLUx62vL/Alke7O0yX+T8ccpWW7adiU4P7WFBTJ+rsfNsDM 3pne/vQmjqvwwAAnhHkj7BjC0gvWo7JeVzl32IMu4Q1MLRJ1wCY3kGRS hZi7WZCT2U6+3Hm0JNAAOY6Ikr8m/daWE4i2g4xWiixCNCcWN+bT/vxM 9mRBGWMqipLS0jTufklwFcJtp9/4NbaEa6v7D6EhCOgRddzSyCrWaxlL y8DVjGCi5c6suEKnBuC3Re3EvQVuf7xgQ+UHe/9AZ6Wxbjcwr4vqQkwI i7XKbA==
+; resign=20460416024207
+55r.subtree2. 86400 IN NSEC 56r.subtree2. A RRSIG NSEC
+55r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . u3Bl5V2fXDU+BYUu3Qgj15EqHUGFQho3sH1QM0wIK4xEQEA0uV7jRHQi tet74jndvgk9oUbWNr7+9nFkgXzP1ZY2A/VS2anLRQNnvcvAX8KUFS4e C3v/0Mgyz/2B9Fu9/5Ak7Aa7SPZDyrOn8X7U7Y8WWdCzBuuS+5JIAgxR GSN7AWD9I/niNSfRej3YGWYRWk2JrHOgyKrzKivBn19y3fZagc6nRv7I 4fDWVHIXj+zzHZi4JQV0gLB6kqYbWhylAoamA7lIGw6PJbLgm3FYZoe1 CY/YNiTB5mGfnIxQBNB6Lp7FgU2DbiKyVLna3Ba8QGSkiZqN/61XRQX0 qlUriw==
+; resign=20460416024207
+56r.subtree2. 86400 IN A 192.0.2.1
+56r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . JiBnpUpcjruH0PMTIpYIqqjT1ICqbDzEVTcJqtvrh5mGJKefbNCe8NGX ISiEphy9ZC1XFXgOBBdzdXikndfppENnRCcIwubE5ovpF82iVkoibyOZ KGuUaexu4n6iD0W/Sj1E13q3fmsncaES1C1dKlQg4GVeSSteJJg22L2d qIgzd0E8PaszRRlKL+978P3x7CpXl0v88/32L4p7oNfGzBRnyGScke6r +2jMIKJrWOLj+XLDUb4L0FzdaJiX1ty1B3uLDy5PZY37ggzwLerXgGQR Pn23fz19xmnD8mi+9+hZarFGEwCXeId1TkZN8sBe2Fpnx/mYavdzV8n3 OIVe+A==
+; resign=20460416024207
+56r.subtree2. 86400 IN NSEC 57r.subtree2. A RRSIG NSEC
+56r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . pMB3cAyTKGdteiNe1aPMT7fVDy9u45vKPP5vYLzomve7cnwKg+tQsaFi zEm2ANNhPCjHdDWmVah6Iq2Y6U08gB5dGeKWb82l5p7aEMIVTNRHYrGy sCJOYC2ByzY/opPw931B09HA3h6Ir0t2wxCVYWORnZ+CmLeh6AI33v8x /vUxvw4UZTTgDUrIPcfiHnSSs5lhwJxe/xWPtzZpJWx8I6UFwX47L3Xf LY85ddZjetCtu219uMiXIKwtJ4YPm09tVSnoJbGgiDrA+KT+n3npiEuL 761Ijp7HSx4krixhAW4QXbSNQ3C+OFRkgda5lVw1Bsaynvw/rcExT5ZY R+cg0w==
+; resign=20460416024207
+57r.subtree2. 86400 IN A 192.0.2.1
+57r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . mH91kJhf7yPY2QEGu1ypSJU/gbNAB0xTEBDCC9KuW8LC0zs2anMU95vZ j4v4ul5/9AwPIGH9yrB204vUFK3Z9UZMNZxejhORKlV+0/rJa2CFxu6Y rJMmkbrZNvqgIjqFybdpH4ZrMq7WrFlYtZ8rl84pNRvboN0O8DdoSAzy KdneNy4GdpYYsbIaHsByOnVG0XC+2MbpokznzmjHAw5A9BADJL0nT3VP 6wsWEdHbHMuq0qcBWGcSj826XqHqXDgv54YJReG00lA4Kbz3x6j/7I71 fA5pZrSH7y5uU1v4Hgs59sY1hFO6xXMA6JMwUEKxNFvik2W8xoUfmvCY i6UcsQ==
+; resign=20460416024207
+57r.subtree2. 86400 IN NSEC 58r.subtree2. A RRSIG NSEC
+57r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . TMfDYSO6BPtor14f85ZOdKLZ9hMsi2H5HA0x89CqYxUDyKU+fiZeAATB TzibP8ssGduHQaUs9OFkAyW8Jgi7xUu2QnagqYsC2INgYBm9J8hM2zrW J4TC9IhBSTu6i9YNShT3rUozgiHmSJwZNtcBeNOXeXhJBSsItpDHztQj dAjEW806vgusYpK6//s+lgAIMQPsMZfbPk2z2SxBdUA63l71rGjp1fPN XkHkPP/PYCqGh/iwN+FpLRNxcgI4QxfHfQSrto9U7sMgD7ltLhuKhsqo 3nGyRyrxscqapciJkx4huPRZqfr/j/cbCPlAg2TPROiWVuAy3/OAnduF jWvrEA==
+; resign=20460416024207
+58r.subtree2. 86400 IN A 192.0.2.1
+58r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . lmJT/mzPmeQho/b6Fqr+A1QZYYlEIsblZbrfmeVPzSWjPMHzaA3SXfAm qjXgFaLmQ7TtwOQycPYgisJn5lHefqVTE2X6XjploIGOZvT23m5Vdn1i vTSio7L3Z107E17gVXE+CMGwOjYoCOTJGV7QLKS2glj5nKi+v3nSxTbG uNucWG1bBtzoYB7kAXxwokFoJCSJN4CssAKeIoxuqXggut6DifuLlhjI 38huZRDzOnU/1RA5GwqkhF2gYHU3bVLBByp9qjK66azRaqJK3QRTfWMD rpNri+seVFLSsCWQmIiGa+1urma+6oHLq4HF+Xw4CdxeHR6rEJSNEQV/ PPeCkA==
+; resign=20460416024207
+58r.subtree2. 86400 IN NSEC 59r.subtree2. A RRSIG NSEC
+58r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . aJzQ4RCaukrSPm4TzZfw9VYqlt2qOeJMBhZOdTwz+CkkQwCnXK2wo1Nf TPgyL+dP7pIN8v7Yjo/oL6l3bZaH59u5AIm9W8ycT5IPRXwAMeQJcReb 0wpV1SbBzCJTTDGzLMIZdPXD3s3dHjwbe6rzfbThPiUlVYGiJcmwaU7/ DjCcf+7xlw9R1n6z+wvMpu/FCCWqz6XCWIvrGv9BH2aAH+XdoBJ4zWdU EfrB17VYFydyXBmDyN+jqepiUNxvDzLDPRWXENid0ODq2iUGguVK3avZ O8jM5F6jCYCWnDwo6n9yfMzPWrAqrx0p26Me9a7obj8yLqB8fhKJ0I/k B9b6Dw==
+; resign=20460416024207
+59r.subtree2. 86400 IN A 192.0.2.1
+59r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . I96IVUAMZG2YTYz5RUx9wQdMbxWi1F3j/FAR1Zen3JjJiia2UNf+pUx1 +cR+Tpxzw8gBCB5hzP7CWaHi6DSTAtiiB3G9VbGpXNR8Peg5aZpdTuEv 6qwq2MkOcjq/e8mo9uEb6cFvz5QGWqVLGhw0FYnsInZrVSYNccCMo/5L As9fKgnTOblgzluR1mLj4COnoJrzQd6zsPgq0Y9XXvCjmH8QOqcBNpI6 5rRt2jH9Y5triFXc6ai0r6DJHLEG64ZoRwgX/gnMwk3/GPSR+/OP+VoQ 2uzzopnPFc6wPhMBy0PilNVk8NaNwKL+1Ib4kDokel83lWnRSQ1x6Kz6 XWS+xA==
+; resign=20460416024207
+59r.subtree2. 86400 IN NSEC 5r.subtree2. A RRSIG NSEC
+59r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . OAkAaJYQNOsjiPjZ2OKi0fHojtz7FsSb3kGCtRs54ALIhQGN+wvIP3ec PlxRB7cycfmfCueFuCOVkmIlg31zcHPoJgnFmOJ/tKcjn5WfEFu36wxu e13Zu3zKRAqqkRaghFvfn8IIP0OtxHToUGlDV4Y8BmqXv7roCHowaAkl KNTTjm+x6BGHyHfMwZGA7QS1rHhvqmKOBqIDUdSxJm/t90tRs7t9HHBl +XAMVfl5tub8VY32QVhb/eWXXgZyDeFevbcmAAi/bBXi/5AeLsUwjGfA QQBnw3MC99Te6XBoTxUgIgFzYZ/UdKKz+OVPrhV9OWHD5fTeaYRWl0Wy PFFk8w==
+; resign=20460416024207
+5r.subtree2. 86400 IN A 192.0.2.1
+5r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . egV6Vshc7lVwL6tKACT8y0f0N+Z4kTiImRmwJFddB+ykfYfR6Q6Lbec9 DkaFz4RZEaMekxZw7VSID4/UAojGDiOjJfMqZ9nPIYjDEcFLE1k9Shmm ZuIxyed1VpUM2dh1v+62dX/6Wg99Sx06ZUcePA90+fTKyWK9lGCEluCg CMe/7GaPsUkxne561YGoS6rlKRnlhOqsh+shzLYhr9Udk4sMHvdf0G3H S3UVitbkfTHj7XmV5h/zF2Eaxh2512jyNBPduNFdyyVDnkQ6gmyzq8Q2 br1TslWD0u6s8rVL/sojaVqNbnCGxpt1GWbN3EPRyV7BUdad+zkUYqPp 8eD3mQ==
+; resign=20460416024207
+5r.subtree2. 86400 IN NSEC 60r.subtree2. A RRSIG NSEC
+5r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . JJ2BbHVqRR5P15+oc6/RgTEjYkaTj3mjETcBuMqI6ivYQa7ygDxyBayU S+a7CiYPrX+J/GH24GDShf+WmvT9HJoFNj7tHrJrP7jpWqkzU/v8Z9Y7 NgKLENUDc9IeSk+1Zs9Bhsce/MPIiTCYZrOX/kbUqKeXZqlZVjdcC7r9 aPdOGzmXy2PsWMGh30N16nJJ1ZWzpC9ln7onxGzf3XTphncnkWsccAVq yt4U3RWVqnq1Xey37h40E/aADjleyDI1S33UO0UR9DKR0kt3N+I+FBUq SoTK9bomhqrnEggo1jDQk7EP0uk9ZOP/C4hEdB9eBzXCPCGs8Iao/2vi eBA/Fg==
+; resign=20460416024207
+60r.subtree2. 86400 IN A 192.0.2.1
+60r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . ZIoajgpZHkY1FbYMvAGK2dq0XRHaR6/PZuBM6Gz6gpF/1HxlcawMSdXx eyOf2+4v93XdalmCVWx0EFu9nW2o2cHymCyHmDuj56Sl8N5yC+a8JFoL US7CfweDgjHFs+4tc8V4IPo4Nwm4CjNI6D6ysfgIu6VI4rbul02YEFRT zdppfu5xxUuPunD4TtditBKA63+TVRU4W3I4ssPDgjBdFyPBqf31z5v0 itqVYFGpS9Rk/DEIqqQz+Gm+8sbvgGetWMbNUrVY4YS75cjdjqPu6B8v jVyAj52DtRIUHCYPKyC4MEKP8ZzCd1+2ke1yYdWQ9C35JV16SqkjLR8i QumDJQ==
+; resign=20460416024207
+60r.subtree2. 86400 IN NSEC 61r.subtree2. A RRSIG NSEC
+60r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . cefA/9TxZqQrYqdigonYLptj6AoACehR0l7LrglA/R+SYCDFIsEyRPfD igNgfaMetvxhfSK++eJGu3BAEgxOrSBMbgGkbNL7Pkebm4kF3YuRMcWi /aRTHpNNWuFwosI4gACavC7F/GnzhVk5JGRPW0kJ1sx6VJVejsIjnq1+ frCadVNUseK81rXuuVKfiT9X7Ol4Kplc/4soFLdB8HHAEWndmb2Y4INP w/FjXbvIDohkH7FlQc6VDCATHMki1IHIzt++wwa3J1K4A9eQxnzBXlQm GSZh2rGXXxSxk6ND5rXRQCNUoRPtiJd+1N39eo4xjzNfaVo7uqv3NTKx DWYPuQ==
+; resign=20460416024207
+61r.subtree2. 86400 IN A 192.0.2.1
+61r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . bHuRkXOHEvh4eGGHdXXzPYKjnLUG8eDGua0cGq7KU36z7GuaC2BKlSfM d6fRgrYFVA7p8nV+cGWzv6qFEc0wofoLhmaqWx5FsuxJZhPHfhERQ3zr PRqjeUrrpREHzEhb0NXF0jO2FKhtjILms1BRZJxtxhfffzB4tkl6yyGH MUVYAD3WaQO4Xt6NFR8M3J7VnTZn1CSk98grL6NvkFBJNifw8FEZaexw QSkApB1IZC0ZPl3mZNHQWhE3OKPdhrj1XT+OdBrKk8ogJUcRlw9YxbwR BhxB7r0m1LNxrjMSaL6AM89lsW6lVo1WUP0a2sldZA9QyDA5pK+qAkpw GqU3lQ==
+; resign=20460416024207
+61r.subtree2. 86400 IN NSEC 62r.subtree2. A RRSIG NSEC
+61r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . mnnAcqIn6fCsxbB7ZvqqNr59KzVVW+CA5FW3ZDZYCW94EZGw/2lUmQOv pgQk/XGkGWHWUvADK4yrSBo9AyklTfZMErsatVVgAkireKIYgigc/kvr MpMgYfu97LJgKJMJV9DQPKWW6E5/y6I8PL2KwnrTq7lCxPe2/SUe9ZIW pqyibjL+HFzLKLWlNm1FLEk+7gMTGWWYu+AmUQmBeTeKJeEizQ10yWdJ zdMMGjIRZv6eJy+g2K3pTuacpAZRECLQi1uqGvDhFi+Q9HVUDRLnkq0M wX//4OwUoUQR704UgyBqd5+88piLo4vk/V+O7ZgjN8eGs/YBWOYZRd8C tQXA/w==
+; resign=20460416024207
+62r.subtree2. 86400 IN A 192.0.2.1
+62r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . k/Oal0kT94HTQvOgFAcIgRt32IUiRqq0fxlHd8IWbx3f5IB5I/LM9Q9S eeIFFb4R4c2lhSTndjPmz0a/34bQkboNSdfRixHRLygN1ZRobTb8KOWH MZ1CKyq8KKZ0qWU5YfTq+ZrYRkXrcK4Z5V+yKyCppxi40vObZivcaN8r TRIYEBC0Ta6EuhHINZMvfGgxuls9K0tHdUUn90vPce5DQxVVp0CbPD5C 5Typj77qova2FQlJEw42C6D9TcFDHTeG7/3X99LOkij2CKqpbdmjqsCU 1RWXsmjTu6P/fdZLqMs34UgwQvEIuMfQcon7NyyydEj9vV5IX8hCTVw7 Oa/PMw==
+; resign=20460416024207
+62r.subtree2. 86400 IN NSEC 63r.subtree2. A RRSIG NSEC
+62r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . hZwtS+mGS0gICbQES7yt48A8h1eSbGTtfz3vj0HYUnnT732vPSjYjAqI FbKNlOdaP2thAhEE9twezzwaTJioYx1NJnBHuELBOFQsjWCQwt1hS/df SwAXkBk3Hfmy4oN4hr7UraXNQjGtrFoPUJjPypD2dfrF4CBiELY0joWp yTZM+aEkDRaotwgeIgEF3df5g46liP2V+GKIfdXpb5PuadG6XlAKyktv hi2jCZ2SSmrcirtjV4u2nZSLycRClgOj5MbXNVxKgMKvtfcVbsaaODcJ Y7pWKIkf0bUivmCy0nkY+ZeT0mnIp11PyaZoIYPSmCDSMWFh5mbibJV6 WKlviw==
+; resign=20460416024207
+63r.subtree2. 86400 IN A 192.0.2.1
+63r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . plZHoXjk91BPxauhgzc90PTZcJHKeIkZwB5PM2DcKDv6nnArJ29oMqek TExb13XrVtx44Ss/jHs9PdSlWIDy8NgLxfOnL2xYTj3/FRJ+/QAbCisD xINtFoFD4ozO+TJrbVAJ5lL1gTGFS/Gu/PBG0iN6TNkjCQ0tcjA7qAMp OVreYmVZSzbSE1W/oGQ50KnEm7ARPr/p0HqFxZNnV18MXbAkhcLA0tmt zush+sXq+d7RbhB4wXtrxbKntYH/WV/d7iIwprRoqE9LXGjZZMlN8hs4 CvgTdiPkP1cs0Aoucyv2SWYsS8HAwJx2pxhgFchOdoWwIeOch/ZHypL1 gULPqA==
+; resign=20460416024207
+63r.subtree2. 86400 IN NSEC 64r.subtree2. A RRSIG NSEC
+63r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . IlmuIR96rM8hkRBdmhMCTpVOkLz4Q6BAmlmWeY6AkFFnrfry4HjrpYXN nj+62rKC+l+micWTtCPzHVm3fshRKUG4klDtcMeNN2WJcMhApYoLCa1S HhmDut/Py7iGrkSYJbkJtUfVH5PobpcWjLvNBueBSped3RPFQcp+YHAF 1OgH4AKJNc/U8lO1xAHBp17IZsCOYzoUCpVH1VPQFA9eH821gBhIyScA l8tKLcb//OutsLlsG4cbC4unldVNj2EWllh4hz+KYXa038NsUhs3FoAk 626GPzzqE68+JCTl6kKvUAaz4OSSE7LLGEY9IUn4QvFFw8OeGV+luQ7f fvip5A==
+; resign=20460416024207
+64r.subtree2. 86400 IN A 192.0.2.1
+64r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . Z5DJ50ICaKG42eq93NThIuvUx6DmnQKuxxv8q9RxlNjqmoP+T9Bt15t8 QQHJFOacyxkhoPgsqIHFHyoB73Fl/9txgkyCTAeSTqB1YzoPzeZoMhrr PbLvCu0Z1Vj8r0Zytkz2V/QHxROfUV5gZzXqcgl18UNgb9WB0E82HBcy M1n6Z2ruawDuK6eBMf4K7t+ZsbdhCcOMx6D9foOzudWXR4Mn6FgNliQ2 JzhpY9t4X8rGU4HiRJuKDo6Rhk2WNLbyLDC2Jisb/FaK4q9gsao7bxYx VhYpvXNxaJeBDCa+WrnZ0QiPlKKWvPS3HYTyhX4KFl3gkWAumRelvNZA wWLfUw==
+; resign=20460416024207
+64r.subtree2. 86400 IN NSEC 65r.subtree2. A RRSIG NSEC
+64r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . ZfAJzw5oh8Z3bbkLC8yfBHa02Fd9T2xEnbejczgGFT/rmOqSDtXifrfh HG+/8vRjhCD5IFIp4RpRQ79GY4vkyQnlFfxPFhaWe3zvmiVwWELutyKN yTNoxeiIeWjdLAMe6pSTcnhlB0vADYTN6edEoTZuQZHsJX+VuiU4nbgf SvPFocHH2KNiZx+Bk5+MmL/ProrfurhRKxD9mQQ4+2NZxwmgtJQQS2hK hKXivLssOkNS23NmPAtiID/iZQpBM7RtYjMm7CgCFigubIRuB8MYav1G cxLw3KqbegoDAStgCXsuvXQ4uQOtHxs4gI32N8GVaxPOUh/STxaMYsdz 0sA50w==
+; resign=20460416024207
+65r.subtree2. 86400 IN A 192.0.2.1
+65r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . JsGyJzO9z96GwXyROW5ZuSHeAfgqPWonnJU7Fm+4kOagLkGHeliGc8R0 UbN+kERWF1uC7zyQr357oyY8tVcTXCsnFQ9lEJcPQz1SqcCD2AtVQBb4 MRMHDa51mpMUJNdzpGBKbgsuOoQGQm8/xmzQncu7IicGl66yuamENzZF vIcsZMrom5pEnqI0FICjvSUoKNdMvVZ4NIbSuX7PR4ttt3eJ5ZhSrRU3 24h/sFh3ThNT5LcGnAF34UO9+Kd5YN+n65koVkBbfkkiN2M6JRczWZTa 5ldsygCg67x9ac1+5FZ3PrCjkOXBzY5GihT4ZW08+WX9uBF8MEzdSJSY lnjD3g==
+; resign=20460416024207
+65r.subtree2. 86400 IN NSEC 66r.subtree2. A RRSIG NSEC
+65r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . FUXNUkNiHFjR2SghJr+q7OniASnAoQ7XQP641A+PDXJY85ehtQb1B8N2 ukt5TPp1K2YHaYfa5aLOHSyUVTVGaR0p+QPODoiwWtOnwIO6mA/W2CYQ lN+eRBFQaUzHnjrUqEUb1sn9ZHCN6acQKKCAeG0dSaJECzVtndDcAb36 JvAydLEnu9fPgLyDlbTsBJG9sg+Yssfqa57dmTc8UWGMTOlZbQMuehnl 3pgWPxxgOLwnNu/OBNV95OJaxR1QEK5GH8ZLy5A21w/V8guIrwop7Zxz j22Qfhno3KqUU8DwKmZOOVuyz8NZU6dJk21xR9LOGiR+hRBaFvvZd/m5 gGfowA==
+; resign=20460416024207
+66r.subtree2. 86400 IN A 192.0.2.1
+66r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . dH+wUC3mViU6hwRUsvRCawDXwb1qwxmsW3pTVi37882NXx5P05OehWdU chwiVN9tpOg3hibUiVa/xw2FwfO5gNVVinTAy53zbfmw3CUDx/njvMMr WaslVmRj6GLsZDaFZJW7lZHi6RKlzrDeKF9YiWPivbe5k5JqmWmEamVs YlxZCijW8TkCH6CX2x5xgqngLG4J9KsbHOasVj/MDWr5dV2HSAdsXoY5 oz12xzKAVdPBXD41Y3CfPW5Oje+G8KGUfcXDdit9Cofh0DnYS4WsGOCO ZwgTRZZ43JwkY2hk//N7ziNtcsefKV2NRbu9TtOAaUxg4AbOW2qS5YIB foLswg==
+; resign=20460416024207
+66r.subtree2. 86400 IN NSEC 67r.subtree2. A RRSIG NSEC
+66r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . FHLMEHAlqjdwmV2LFNE8V1zIQYPHTnMYsJyBBDg/x2V9USEK4wU61Hax dGXkgu3VoBhakpo959qpjr0tt9kGxCrifPbzpaE1UlABFyX3CaiPXQlO 3jIKgsnPUncvQXMgXV+Iz3T17PIVdv8HwYqeyc0aedH2wHXMkKJngbuI Tndi4n/flkoRsbK0F4U/DDtu9UK3EsxOz90yaELJryj5sxiIeDX6l5Z0 IJSjZLafZuhU5nunGdzmL/9GcKGT4sAN2PrYuK6S3Ipoq/QKSYPQNise ZTxcP58dTMX7qy+ylF8Lr8nxdJch2CuakEkudQsiVX0SEeuqwU8O8nkC M71ipA==
+; resign=20460416024207
+67r.subtree2. 86400 IN A 192.0.2.1
+67r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . dw6mT5uSGLyaGRn6Oks18wYldst+JVfz9T8/d0f8jSz84d18Wy1POhQ6 +dVL24qYWh/PAzepU29SU7IbWmidOk6/zPXQnxub04/tIwDbUyNFEU56 IwnCTS98Uvbfkceb8+bnZvJWezuNYEg1kzUWmxxZ5Ye6sUPiNutTRIkn 0kSfUZbjpymAs10qocTnBmKduktn27FbQyVMcJuQF19DK52VVNrQ88OC WV0cB6T1XAyzElVzzpHdtNR0H83EZlZ4xDjeJ+RsOMpAoEJvd7AKMnSr Cqar59tIBHyH/5tV+3IFdrs8HI86OS8WcTrqJZFbaGjnDwCHKAOOq72c kXATww==
+; resign=20460416024207
+67r.subtree2. 86400 IN NSEC 68r.subtree2. A RRSIG NSEC
+67r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . kMqkEJCyfCgq43uNAsv6evzEdAcNt9PTSRklcVm60lDRnyu9+bSfeGVy x0SKa5Wn+agDBxGX997L6kUh8748VFojBIVso+maRkXEONXwWBLdgWCm avRPmTL43nOX6xIKvW7U5fftK+mAFooqIdYbuuWSnfbuYQS+uyrTwmp3 CfHeFryjYtDwzJOovOZuYGyU/Ca3Gx6+GvQn8CHxERlXAqdw0JcKQM6M tRg3FRt/LvqnHQwS5KUncAtGZPriM0xGMvi47ofkHqAwKc4mzsbJbFtM 2Fwemo6x3RQedMkBj1d/YbPxvtxEyfJfl4lug5PrvIMRGxUjUbKW5nRd KsKwxQ==
+; resign=20460416024207
+68r.subtree2. 86400 IN A 192.0.2.1
+68r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . qcyNaFw7+PzaNI/3KRPc6SMT628TgH/hsC17lgRaCO1SbqC3y3WRDHu6 ZrH4CcK9EzG63tU89Vg5N8USl+V5wVYnrqWveZXTG6Kr78bSW9HKXoW1 Jjeb9BVgQtTaRKt9MlpuLVLr2TEHD8irJFGR4GQmsfpk4R+LEssjp/8Y 8ofOuWiUECvajXZnct0UkYrxHTFVhtxvDtaFA8+gzVHU5s7dGfdY52pO sEN7z8Dmgrb8V6JuYi0fVWRcFaMxSLiuIiy5+T6PwLFS6lyRVaicV/qb Fd+ZAspcRvOjFZMr2tagang6sU3LJhCO+QC8Ojj345QFFEMtv3dt91wJ 5m5tIQ==
+; resign=20460416024207
+68r.subtree2. 86400 IN NSEC 69r.subtree2. A RRSIG NSEC
+68r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . Px6K2z0p8+vmVihpeEomljipxs082D62eaX6iZ1UKWN301wf3C/OKJJW oURhL4BPoJzOGsjpo+//c+88b97uNAzmoFyHJAbc30tfkOHpgnR8Wsmb qfdkGXDiQMP4RVtTWwu1+PaUI+aHxiG9Ax4ldKi0ONTNzJXrqaYrgPJC EgYamDXS/kzx5C7vWTqUA9mE4zCW3R0MPm2P6pdU4AE6olcMAe56eKzo Z0TzF0l5VpXA1zSBKXuAdw5gNcAiNKA8oktpc/52xLbj2gB1pdJZvrSf /RqEdthnElT4HSwqgDH7Rp14fmzzpeEZ7SWpaWXUgk9LDV1MiEkt0TmA pWfezw==
+; resign=20460416024207
+31r.subtree2. 86400 IN A 192.0.2.1
+31r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . xASfmo7eeAQlDcnqUC2871BhPrLZo1RttsCBprJuqyzqI/U7IUwOLubB 9GUQBFC2h336R7goYUOvfkxItQdrKMHhtsE/5W/fkLIKfGQgKcWZ+o5M 0z94Oa+0dll+1B072+6qLTPJquFUGQcFTpc3To47tNvGCZrXw7rgIDv/ vpYPi8Di/djm/5nLKKgJjg9U42GnEG9sUyzGB4GOYlgixCAa/rGKKIpm AFYtLLBR4mjVzNywJ6EYVcAS9idC8hN1Dta4oni0t+3KMT5enk0ISmou xL8RqBQW01jc7WulRZEtMeoxedS4Dpnne4uiMkLxwE9KzNRgRewHMe9K MrzPZQ==
+; resign=20460416024207
+31r.subtree2. 86400 IN NSEC 32r.subtree2. A RRSIG NSEC
+31r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . f+5sionbddem8iXvDtoIt7I9805BerL/9diWmg2iqzoSgPFyhhtfXDps ++M+Y0iRvP6LRkF+zAA5OIOy+pSJbhj74ILZC3tvnnQuRk4jfT2mNqmt HmZJ5RcLCH17ifYj0bzfyp1+fUQ2yk1FEhT+zbOoVmNFyaAxzVOD8TpY kbW85FL4+Bic8w5o+j96Yf7sxqe2TLddzmEinKqE4JHNEEWdCfhZdq/7 nIm5b3pkRV+spJyRLMwRn5GVLQuMtJijljX3qzzgdCVXgs0WQAALoOzL AC6837pes52KTWOIoH3zKLKiiluZR9zBQLXMHacVapN9uUgmBWN6z+YB lMAMcg==
+; resign=20460416024207
+6r.subtree2. 86400 IN A 192.0.2.1
+6r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . DaE9dYZ9HhGJv/Sfw87tTCmdnWqfug3U/JEj/Q/7impFY6OPX3OYbwxu ga90xmO3xws75gGLMLUmlZSUWZeawsLQBmwlxSAD1GCsRgFEu/7GlCwD 23mHWYuHWtZ+8WyQrSKHmwpyjqaaFixIl+D0jzZ5sZYe2Wxpy3/IDDeo uWv3Du2W4ItR3PF5TV11sJTdta7Tl+5uS2iBxl5ohwtxM0t7Hk8tKr8x Gkfp4keCSNhs6j3KYh3Pjl5rObq4kt20icrm35nHyH6hElynADB+ZOxN Ei1XP1mj/WlH0GRejURI5/CmmdRT5oXYDY5R7k9Vwf0jz7+FJ5YxAdQm 75MQKw==
+; resign=20460416024207
+6r.subtree2. 86400 IN NSEC 70r.subtree2. A RRSIG NSEC
+6r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . L8pFJzoT7VeRfRgptXm62L1G7SGV0Kqrg6Ajx8j7HyN8EJia8hra/Xxe IqetVbiP6i65IdTciTeeKTcFQXJ+ZFYM1YmGFx9/7z5Y3Nu9KYHaNaBy nDJIuHrQAokLeqGetQmsZJWpLcTzNJjFMvXJ3gPxFpR9/NMi/Jd+XhXr xsVPiS5hlBw0lLtQ21kDWE84uthPXx4kFMbbnw337Cl5js2+tkSKV0bV NwySaZrR/cJdXvTY/xUlYm0MltX5j1BWL2x/2k44VUhcVxi6IJu6Byu1 AjD6kJaCtV6vGEbqmTk1GIfmrSsUgRhEt4mxc6jaP14ojBNI/Q1lcRRt ZkpvCg==
+; resign=20460416024207
+44r.subtree2. 86400 IN A 192.0.2.1
+44r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . qZMpq6KZ0gtpfR4vLChBPhzwwCJSCGNXkxKCrfdY/3ntM13NmxTL3pZd Eb2zyTPtqiE7EntPAXkRzr/Pg1+sFxSiPuF5rJhsh5AdT609Th3s0hf/ HFq0YfgoqWdfugIpox9HS85PfaHBouBGoV1kS9Mamch2D66CGMKCi/nE BlS/hnjaKeLHw+mKGuXLgUvwwZ7fCdVo/Rpq2UL/eNkN1wkslKU7LvgE sRRQMehCS6pjksYMSZBDm9nsjSuS9s3Sqn4XE47K4rS21Q1FHoiX7YHf lkAv3LS9Isip5HNFWw2QHXPNVNB6z7WUsdD+EHoV7lQjun0V290dC8JW nxDgsw==
+; resign=20460416024207
+44r.subtree2. 86400 IN NSEC 45r.subtree2. A RRSIG NSEC
+44r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . AztM2Ln9mLK2VNSlJbNxd2YUb9JzTDCj4uvJf9nf5HygpuJWd6tRvanr 9n0NAWeAP8ZIXLCerxYEBhtzDkz+WMinWE/vq4T4I9+9XtRXeqmKiNBe DAM8e4hMkZpZNb5CiLBHohm+rzDSg8wWKOxFB3bEgdomYtF0ajlkxKEf LIr5hccs04V2MT7IH04+mIw1I/a9PpOEz508Pn17KfKPyRxdCfirL/wk otbvIR2R0sLxgmN8FcooLQe5Afr7kviQDCHhTP/JCqxgRX/mZmXLkpUB 0T23BsrD+DclKwNEsMIX2wY9NXSHv0VKyn4/gMs9g/F3Kv25wOznk36E lGooww==
+; resign=20460416024207
+71r.subtree2. 86400 IN A 192.0.2.1
+71r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . xhl5CzYNam2ntB7v+jVddKUM3mgmZiuLR8M0cKHFt47F1bN/geVwDBXj F8VZisvz5YR0QeaG/EZGAW5wQYgCXbkNosRKnnamb4HSLlLn1vNkhJhk 8W+ZprTET/8mOimRW1K/VDPMSaRk2pObPGHt//wvvCp51xc60euq8zO0 olDmOrVnEV4LNTYS0IqQ/Zb4FKfcj2217laks4y8jpIA2RqsaMI9w+0O X3Umpw9KEKjWRz10UEW4gqv9uEm5E78e4ymClA/94y1tybxN6mymhrRv kMmDXpgTmVVRCU3UoqGTzNShXuWOY6j1GdZSav/ovIHrFmma+ijx0qnR GJHzKQ==
+; resign=20460416024207
+71r.subtree2. 86400 IN NSEC 72r.subtree2. A RRSIG NSEC
+71r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . ZdQ6w2ryMuWp7iTgw2JNo4ZCCVW0tYCNz90B7wJzU1Ncr/rU13TmS7Up b44C8q89ExonsWOhUkcokaSFbrt45R41O6k3X3Ic9sQhwvyj2vpD2os6 w3rBiI9EEiGW1DdVEl7CmiRcWlzMeoAq1NyphkhUQCUytU7FGVM7I+ex GTTUNUmcB4wkT6z1T0mJXkmHk4nLfiEfe0aPLu3QS+UxLl4SriymzVms yYXn57+KFnpTS6ElCYIOPhJOAfSxEbipg5rPNLjG1nc3V7XuuE8PvvZX xTObbcBmhdK5U2OGc6G6RuKgQ2po2IGSA20O1bEbT1k2fbciKBuGLkZZ /iSC9A==
+; resign=20460416024207
+72r.subtree2. 86400 IN A 192.0.2.1
+72r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . weoG03ur8jEy+A8T8jx4Z3gqrrTc6TEd+uoqmL1rRC2pYBrnz29T/Q7X PL9XxXXpFIhoRdqnaLfaNaqZ8lGP5iSpEzWyvRSDtMcFtzKMzBcLRll5 IzjuiRHAGF1D2rPOR1oxJ8UbhlthyNGO3nXqc5JZ+tIFmf2Uda0KWtB5 rR/Qog5l5EgSxSgEshzN70D8sZFbS2IuelXjXW2aLR3eMIaH2zxuqkxP iIVuTh9CobtBzPewz7ZW9zImW6W6CgI8u7AkHHwfJkxPVUVAIZSUuux3 wdkjxDx3c/a/7OqjKBnlOPu0JNSpRLiKRQUKrjs2YyUPyWQC72XiG4e0 YZpYtg==
+; resign=20460416024207
+72r.subtree2. 86400 IN NSEC 73r.subtree2. A RRSIG NSEC
+72r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . sZWRAR4iaXT01LPWoixa3v/X02/ABRcP74eqs/4Pd9RiQdPYJPZxQR54 fA3pTBlaiG9r/Q7tkO7aHW4Ll+Ei08Ry/A9l/+JrJKJePdANItCsLoTu juGr1UCLKS5uTAef//sh5tY0o7tZIh8xqlH304ypIiAFPsXEATZu8opG a03DA78/e0hjr8jHar9VZEms6Rd8P4ietnFm4bot54E5toeSLXWVa/tV v69xQD6JmpBeNIf0A9/x8tqnnG0v3cEvbka74xWNwXQ53NbNbV39Lt6q Uwx9I3/2qlaDCwpxQMRosI4emPnF+xQSQRoPvIwU+2o0uo6kqMtzj4mG nL07zw==
+; resign=20460416024207
+73r.subtree2. 86400 IN A 192.0.2.1
+73r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . ilUC40xFRAoBBb75GrehoJ9wqHjkwURrXN1RcqhoDE2/cVQPvvryXdK7 CUHTgTFznp14vLyqp055fNZgpDcXZJZ3ZhteIe/OZITv4p8yP1uxfjQ/ OCcP/0E8Qv3QF2p4BW8VeZ7ICjpB1LPtHpjsaVHex4KCYiVCpTPR0D9M 9/1TuerGWnS4AdOJA/MA7ZVxoulfTehHZ8Wkn8lhu0yMSU/UvkYDhDK6 jnYARY88vA+bw5FY4MOdK216/JWFZ064+qHnXw7BjxyTMWc20fCu0Y5a z9vo0mE46SHJ0zkS2IL4Ou8hzqDxf6O8UIGXASZh4gnZcUFM8WaxHIMj cznDJw==
+; resign=20460416024207
+73r.subtree2. 86400 IN NSEC 74r.subtree2. A RRSIG NSEC
+73r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . SKF5jm8SM52pUZ3i/U3U4ms8jLMWBbBLBAagxGcsFWZd5LGj0tRMO8P+ ZE7R9YSSgfYsNq4r9mJHqd1xwqzVin28OMuEw5USEfT8rSVm2sWnvk3a oDleBSjcL1V04JU0Rd/5fs2gwASqsAXZoP0ddzR8Fw+nKOw4wK4ah7D2 V/8hBzFoO8MTieiCE4iXB1Vr3+VZvduJdyoM1N1357axaQIIDg0G7PbA KUaiySfvkXNEHq8YNI6vNnVV/JUzZkKrjAsxyBtzHu7QiyO2q9y39qd3 l3BAyB4WZh2fsAo9KTqPLGoExS5JaPZ9LpHfzDlG7V+QxzbBRBLELr+Q Ipcnaw==
+; resign=20460416024207
+74r.subtree2. 86400 IN A 192.0.2.1
+74r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . hzCzNeHbVBD1gmpdxG1P2nVGK3YyoALpaoQ+az6+JRQBbal2E6cgwpgD Mw4jMTnBryhktpViSxcSjl8FXHovonJJFlQORxVEFAjhW40shnNHU4Ew ofPjNaeNn8Sxkpevncyv+/tRLqHJY9007GmVUyzPkW9nsFtmESNKiWVD 2IBZ3DEX9G++ExvxgC4pPxgeZY7vhj12sKaOuL+k3skcv+HOFBevfB2j dVfJMzQfHyYg+zoANGKnj7Eb0puXGL/lUIKvDES1voXhMMp+1zABItx/ vIRfMGAKd3fY6VO7/9XTq8uLNuSDCoBu+QvtbxB/sh0q9N7VWBhz/wQr jCGl7w==
+; resign=20460416024207
+74r.subtree2. 86400 IN NSEC 75r.subtree2. A RRSIG NSEC
+74r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . pSqVYdU0CflPEDRj0Mv6chdpOyxRdou1R0ltTBGAwH/HhkxUyH9bsVjT H3Pl93bDAQUU67PFMYcOHLzESUBgULyNnTH/ZIQhyanVCWxJdQXhumsQ bwaBjAbVvrVVLI3RwkcU1KOu5o7VCsX2pzJv/hbNiD9ZbSElpVUuKpWT rgr08bKQSSqgFEkWt7nlXBx94ufa2ryIiUd346q+U3FbGRcwW/YFaPsH nYykgmak+GJBWd5BouXIatxaDMXNUYpSY+z6X3fCItVO8JqoktmMeHK/ lXysyW56N5JgKtBqLUB/xIeGXC8kQj/K+YX48ZGCjlF2Wnuo6ZcnQd98 5qfaTQ==
+; resign=20460416024207
+75r.subtree2. 86400 IN A 192.0.2.1
+75r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . ungkHYJHjOJnWwKjnx1qYF6FBcwyGqaVUPUiJcwYXb+VT2pQsjcKzAVJ wka4Ur4uAT2JJycfAYgsYhLU8TWXerh2H+KPUDOVjtGBtfcyJ+V3/GAA 56dGGnisckMgJGzOKbDln70wRHVea65RAv3RHQEgnXe0pMtw3PzZiwEZ n1kEAF5HYgV1CkNefcSv2eA91OZxRS/o14Tode6/xvzroa+C10dPqjXM m2mFyvfJyQxBaVxuXGc4BrJOtDd3pgXJIVE9ka9oLczx9NoyfVKRFfHU gCUnSSb+e/XWrJsHnJe9NKO0KunDbmdpGvQ8T3qK5qunboIp1unl795p LyrDxA==
+; resign=20460416024207
+75r.subtree2. 86400 IN NSEC 76r.subtree2. A RRSIG NSEC
+75r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . MQ+mzRMD/whzQsiJFOZnyW7O96lhum/QQ5/7xKJKNGpktBX7jNvgdSzK swAA6tgI7umIV2u1l+tI5wpyn0GzCRlw/MxVv0BY8TQU/befsN4u17tp QZNqhnzSsauhvxpypW5QeG/Nnm8nqMGcNzRDfQ3adDnG0hiYZYdvtBCG 0Ygk7LbuG2Ra04betRCerxKcSs7sCYC5EE3daJWf8bR43hWoJaC9Fa6n NtsCL2bc4Z5UQlzjZgH14V6RdkmhIKsNG0f9tbza19A2nE7YgDr1GvMM F/DUTONHV42taRDfXizCEJDax4h+ZcJ4wO7/DBEtrpSqeja3bJ9DbSA9 3udeCQ==
+; resign=20460416024207
+76r.subtree2. 86400 IN A 192.0.2.1
+76r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . ifVnLFh/AL7XQnKzcxulNoe/CZgMEKm2UW8tb7JR89U8gUtuu45HKlOd SWFGE3VGylwEfSlt2VWL0dyAilSUZVcKXRqFRrDOrIjEIFkvdwgaTOGd u2foSS7ZdWGjRoNEo42kQnvis8eZ2CkHh2Oa53SYjD1GfX6Y0C+OCgwk zEyLleAhzUwdJbDpCfgKB8gKjXFjfLYltrHJkHlBStRt8Ec2+iX5oS6z FOccZSd1wb+Ch3EiYVxUAISyxv+riGh7U828SvgndU3B6xhthrdwiv2i W58xKvo0UQ/5hZSO5FFKzeWbruSE3BVYHsNb+uu8Rksa43FelX7R2Vzv vIGz2Q==
+; resign=20460416024207
+76r.subtree2. 86400 IN NSEC 77r.subtree2. A RRSIG NSEC
+76r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . ingv1Z39NH7Glaak5WrMae8DZAw5SOqHtz8ugsdTlLWgfNAMYFCkJyAu m1tEPPek3Dn6Mj8UUSscFdUHXZ6ykompfaCMZj0msfw8CIJxQWakzP73 kYzufEJH7+KjiUQf2nE1SKlmeP2Ul1NaYB+bvYUttvXZvr9LTy0iH8Ij YdDrwhc3CslU6cL2S+uoL/qvyiXvLIqj/OAnCjylRzlvkLYWf+ISRnPk dv0f18ATAFt8ZavXCfP5Epyc7+OpToLByGu1yXO8/SqVcy+KvtCqPg+k uST0RpolF1INiI8GdS9eet4DdtekUYheoerQS4yVWV2Zv49gna1hulCO yHx13w==
+; resign=20460416024207
+36r.subtree2. 86400 IN A 192.0.2.1
+36r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . fEpn/LasYKUd8XzHc/ZM7/89uBNlhB8sncsnT8sGohJQQ/JFDNFqiIag rRvs4QQQNcyFa2fe5LHFBderzEybjn38GNMCnQYm7z4RkATEZussmPQA ha8rETZxLa12iZvILktns9Z7wnMwIX9WsfrsK/NLmAL/Z2+2st+Cszb5 CVr0ZfKBfRod3Srl/1FsnA/Ku8M/u1d3t+b5Z9ZY9m+2/VAhoLIyEc7C zK+0asVM36vN+LiOV1TnNQfAcmDnBT8s3+nepf+6j1S5LCNhm8+gfLAR 8iHb4LrdhCeBxfR1cs6pT1DzcwLTCs4PXLdmElsSxuqyiCas3pyXKoGk Kuns8Q==
+; resign=20460416024207
+36r.subtree2. 86400 IN NSEC 37r.subtree2. A RRSIG NSEC
+36r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . r+J2IoJGE1EUUQ/xifkSKsK49QyQifBfeXX8L140XxpRw1PwiaPSc82g stB1h4lgb9UoNomh9ISjEYkKmVKFdNxYmgXZRUOX+3gRvTNIQgX+VNyr xeELj2I9unlYar9JUKvRMgoWi7KuuLeu9YtT91Pd/WgUcFO0ZaVawIbJ 6BrnvHq0cth/ADQIncTm0F7DUSJdjRBlnXqEhE7rWAcYBfiDnUt4/BCP bIVaNKkzHuvzGubzjk1NPuNHKoFwoXNtYtT3z2GOuPmPr7ux0rVtE8Dp x1AmjzxaNGPBrsJhAS+dwREXGHA7QrtmxAojKmw0rJXZ46HPsd/e6BBv JvL7OA==
+; resign=20460416024207
+78r.subtree2. 86400 IN A 192.0.2.1
+78r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . OrFFiWwbBW147VMD+1Azi9/2dDFdww1gAwef4WECpBZx4lB29o2XoSnf jW2BDFz6U9jScXuSUhyAb6E+5dfITo4Qhnpx4PT6cNqyaqhRbSGbQT89 BpBPzFnnNvu0k6R2eGr0RSqZjKalFi7Lvzr7utZiThvh3FqNJoA7C6fd WyOcBnF8HahJYdnigYP5lwfN0aj3/LbiVHmXvqq0l7BUVDRZ6gLUhGMa pr92um8V7mquo4/0ilniteNLFx5/66lu0AqU+71SXB6MFpxjkqgdsX45 a5dcODTv65oLvW5AbAXqRl3TP9MbCgTfEkVVBlDVLmHwNP3LGI7e46pR xa0nbw==
+; resign=20460416024207
+78r.subtree2. 86400 IN NSEC 79r.subtree2. A RRSIG NSEC
+78r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . va/PGpGKLsXut42f7ZlV+nRB1xkwno589u+AmiKY5Du9CYP/G/M29GUn TnY2MGdgcu0GifwTQb0x7EyqBdkdm///9zfPvt1iI1mc2V+1CbiZoR3+ Jpft0+FKTDffHBkCnSeebEbEblvLPKnGr5nZ1ZMTZV044gYL5LhUzLvW AwSyZix+dVAYJkIS/suBWjuez3q+DbNdnayKR8rnz4nXSD0hKkvB8dT2 9/MrJGHxoiE944u4U47lUxAuEim1ab/qgKGZ0mc0hGCQQDvM6/QufbX8 YEh9BEDVui8puMru2UqST+ADGM0QcfRXmF6rNmlLjCoBXMi/RXLOcYaP KLSVUQ==
+; resign=20460416024207
+79r.subtree2. 86400 IN A 192.0.2.1
+79r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . JDBZnOKR5vFA9Zj6h9wIKhM5/cmOAcHDhYeG2upJGRhuz2grB3OZAaaH fp395ebYHAatSV/Fyov1y1EhShVeIcnuhUqm70CMgXZu3cjBn5n5pvjd 6dKxMbLMiAmngcX6497JYCMisSBqoyEzqq6jfe5Wsz8GSFEoSTVXpM4W JPg2Qy80k4okw6IAlHHxap4wVZPgcTZ7nT1DDwCB3nSY4oUXG26UYbRy vM6feasqo217jAtz2SXiH5Z/XroSGdb/V81QN+g91uZeUI9nl879lYE2 aqGrSV8oC6C3Ww5HpPXk3iBWR/ngBbsPEgMI2nGWOKsyu0kf5lmrSvqv zdJbsA==
+; resign=20460416024207
+79r.subtree2. 86400 IN NSEC 7r.subtree2. A RRSIG NSEC
+79r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . XAPiDw+8tcohl5AAzbSvQxLi3IiLkmAOjlDrbuGEtdCBo5+JCUSSQP/l tHF+skvmVdk1j1h0G08i4J//FwkCNlUfhYxfeX3132hv3Q3Nv9iHTK8U Hrp86DG5cKG3Z8H1j0cQCXLaE0qk2FzCgt0H6MCnl9ClTWtWQyEjCCZA 2bZ6HKLHxAUMUMnhAVoH9QoBjJoDi4N1deYz3FDbTAN/IH0K1vSgmGoP ztbNyz3WI/3KuJ4AIyISfk8nS/RRYL/WRE6w/WnxCH0/Mu3xDup3RYgX 9EQZuJQAhw+IcN7xgcxfb7kbTXym5xrzp21WUGZL5XobXU6mVGmsxYnL EutNVA==
+; resign=20460416024207
+7r.subtree2. 86400 IN A 192.0.2.1
+7r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . gvDi/djf1jvbm4oPF4vZvf6mOVOC1bnhH9rLA7s7Zyr+m6iq9DN1cUVv 6aHZ1U8tqYVkZTVu1Pt4iIAZ3x719yKSpe3FY5yBMjNWKqxXXO2P21tz X9Fiwb38WDsSgICZ3VHt33BFOhAXQYFTIZ/7pwsnZupnQgzagSqpos+K s4MsG44CbVRmUvVEoBYUe9TuYV+vJRLQcI80UTUxAIlki13rw18ZoWb+ CEBPoxV2D2Al9vFeq28Cdopi3hsN1D+0+imdx7Gz5kKtib1gnkb+xciZ TIVoIBnhDnOWm/y/rfuvXbq2G3JSGIPl5o73KMq+F/Q7hF/WQSnfnzXS KcP+Mw==
+; resign=20460416024207
+7r.subtree2. 86400 IN NSEC 80r.subtree2. A RRSIG NSEC
+7r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . ve8kD8ZLjqZM0Ke1iTOLQ1GSrNPCXcfRwD1dkZjXYT/SXV8fLVeiyBXN fi1hqjlUD+Mhi5elUkduTKzfcrLPQ2BnDQexSc3wuFgGSZtir/vfODDN FrfKdo7c5alC8vIkHz7IEVpd5I0aiSSgrBIC8ooWNRod/sRIBV8Fc774 o9b/Ef0KbvI40aIRANVNihrT0aPhA2/RHtZLbTUUbWIRXOp9+yWqJYu6 z7ox44cEfHWGkSNRb2IPRm+l8QN2HMA949b7FlxY2Pn5i6mTaWD6Kil7 RotIOwm1fkR7Jgsii6Ra8OBGpAo4Pg0Fkx76wTZh/DF+CoqcPjoA0w3K 9bc24Q==
+; resign=20460416024207
+80r.subtree2. 86400 IN A 192.0.2.1
+80r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . biJy4joHJcSotexQhJB7Mb7u5fevXebKBeDlrMsj2d7VdBRzSExwmO9i c+yM5Ou1P2i/3EkBKT3mCwRT7OjdHrwObXizdRutel87JwXDkk1xlti9 wTp4OJBEQqBPbx8wuY/ykmU40qkhY0vtluldOtTU5ytTr5gBRR00vEws 0FhhSuW5Mlsr5DeX6o8MDHaEcQm4s1vLsmI9XV+kDLuwuSHSuhTELJA3 v02uGCJswKj+r/LZ5m43sTKm9f2/IimBjhpdDqq9yv+9910aUUaW3hft xqWkWkPzKfpwmRhyu0K9VhQjgdvHwHe2jJ4UHt9Pja1dblLZm/qtLzz5 mTd9+Q==
+; resign=20460416024207
+80r.subtree2. 86400 IN NSEC 81r.subtree2. A RRSIG NSEC
+80r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . inmrH5256TzB5VtNY3N+E9K2wmIWbW+9fNaR7wXgTzSQD067JHMgUqLz 5d/QY9IjZFjlRMtv4Cup4tZ9KEGcg84l2pXNUcDr7LX31Ak0RsVkKvNx FVFY5tXMMbW2XWNbZZDsnLHp6VOQD16lcO8/gYb0tkwRGm8fPpMJ4Njk S4lWiAQNUj4RAhmAJkMSaZWTSjI4GXfC8k4oOynt0pGB2P65ASbU3ZnH 6cZFEH+lbDIrS184PBuvtucjMdYXw1q0p5giKKoxiIhJ4lwGiA7JlY5z 0UfS77lpnqv2lECMrOtXZDMirgLrPHMP9eVUP2quVkVlQCjW3ixJWgR+ eZvdwA==
+; resign=20460416024207
+81r.subtree2. 86400 IN A 192.0.2.1
+81r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . eZ4kaFChRslI+Biw9JbT75zlO/1sxWMtjNZl+fbV6lK6pl4PtoqqejnL ig4m0aQscpUMPzgIHO6kRhAeUmOBeEymvYquQyWk95X9XmUjWHyvUanT PFrpX9fPuPCKpWDRvodO3G9Y/77rexa9QYi2ocNjpHmlKtSO0zqmzoc6 nKice7Vpt/Caw9d3LNR6pUelveEtGNPgUgWMO6lWkx/uFTg1KPoHbCa1 KmVOPpAywEH4hKKH2vhvaocwxs3VfOV+x3/L/aGVQvPbB3vlsNDxkP53 tVMwq432ypK3effOvHvmiXobMErRqrz2fxLMB2fluwFXGn5TDAEtV5X9 3VO9jQ==
+; resign=20460416024207
+81r.subtree2. 86400 IN NSEC 82r.subtree2. A RRSIG NSEC
+81r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . Tw3m1/C/lkX3o7qMo3jVb0NqBl9T3eISc3pRa5qZT47r/bG5UaUIj41u ZdVSFf1583ecSjAQCRhQFj+Obum3jkM9ZSqPQri8v4blXW4QNr3n6EVt rXNI2sYUPFdRT+lQw0L+LU9EWOCDVtXU3jjpujj2wKzD9FWbLXgi9S4a Zqi2UD7IwPVFmm/oGpqAEbhANJfH9pcxd6IQNsoELWw7f568BbR6qYsa EY5HWY135vtLBmALeDGhYYgxXa85J2jXqzOdsbSVexvVTuP4XiCTO+4w 8RN89br4vsHhkKXGompQ7Z7HQ07V05gLdxdj99TFbz4ILsshB01y2qWx Jr2zNg==
+; resign=20460416024207
+82r.subtree2. 86400 IN A 192.0.2.1
+82r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . U73fXbsssOg2Du/DqzXEL3GWHU79ZQ2RuWMuI5q9Dr1ymdN/8ZfI/M+H mgzet0FwhdwOtYPybBpzklJwUj1vduj7/lq3eSiApVTKbyURNX9FD70J QLb0tIujmQLAzewJHnXZTu0+gcTzw4BwPZv3od2Bfdv9LjdWtqFKzO5C 0ZlVkiM94X9rmLOlR7tZBvts9+AuC5M6LA9FCFBWfgUZk6f9sS6q9fuL /ApF9xG11D5z/zQ/UvQBO/rcFrkYNW8iery2MQbdqkh32iDSlMQe/N85 uUnHS59iLIzIHGLryWuPTNW4CPIJX7UyZ7OznP+NY+xZFXfE+BoAb+n7 KjgC7A==
+; resign=20460416024207
+82r.subtree2. 86400 IN NSEC 83r.subtree2. A RRSIG NSEC
+82r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . q+82SmeIWsbPXp34ti37GrX6R2ALUmf5LPwb7xtYuD3RtxtNnlXq5BAg LCIqW6lCsaIIu+mafCPj2unp7+sivYvn3Ts75oG+FMxHWL53S0zGKcnm p+m6uir8FvtsUrs3hBldo7NDJ3bJ8s/FzBXMVNgMHbvpqn5joNq8f33o 9nuOQ8yGH1+/m4oQDJMCnOmo/3ueS/PpfPdcnB0k3PFslkrQ6y3WflFH 2GXxbsF7ZugWrS/VVlxl3FLIiMbdxvkpLkVvzCefmuIhrQ48k6eG7713 dTWh24GetY96qacyLkZGtKd2ht9xDX2LM12kMGoytBs7F0dBuqcnIm5N PbnTkQ==
+; resign=20460416024207
+83r.subtree2. 86400 IN A 192.0.2.1
+83r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . V1hihHtRb0zh4uCzifwDQ9j9TfnG0RUuD8LU1VzRm4qBXri+aHMuMycH sT74f1xfClAAsfY4ws1NA+rkcoExm4yIrgfiOVBhoZNekG96JJRJRkQr Zid5VDAF2xUWFJhLImA5MDOmdYsaTfAMnvXqHX5LgHJT5D28fHZ8fFPy PfWgiBCf88dOgbjlx5JKs1Ou9GYsWQCqKbnwp2nFvAwpnCqK4Waa/n/E wJanXLd14GlyGvnRYh5ITkJTFf69FerBSS7zTTQ638jicwAo17hhdzol Q2642gt9iNpo4cr3IcQ4GBBXCFKv97/+YImANV7ahwOy+uVsqFiACt3N mYyVZQ==
+; resign=20460416024207
+83r.subtree2. 86400 IN NSEC 84r.subtree2. A RRSIG NSEC
+83r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . MSS+aIIC3ZvkhSN7PhPvDmLgXUMuViCgyXxkhW9KUkSkkpx4Eby38thp ZwhktiNXapsUO0URG2qZGs0S0lW3dTJdn2GauvXNkfzGKY1iWgZsVQvZ xnKU6Id5CSMgjXAPrfKuMqU6hYi1awsLqmYsNzdVxi4SVLPm8hvkx2jG OfeLeWGLWtfHr289viu7cWO1Yeh3AEqWoUteJNU6eugdsTvrWurnfqpB QQfidnh6OTAO18cyXcTsLCYCT3e4XVrBzpVUnaEacVG7J9MXcggOeKOB 6KvG3PlDpRjgU1HElR1XZdMWTU/c7vv8v30+q+i61cEauiyYRFAwBFvB BcCBHg==
+; resign=20460416024207
+84r.subtree2. 86400 IN A 192.0.2.1
+84r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . ICS4/eZuAoeN0YbfAnYLeOTHjqYgOi0CFeMkzO1bC669gbyyMA7tcM6j LvgDnLwyJ1UT9Nm+sNYmh86fEaDM1j2DerRoqA9QVHAWcnPIUtBDOY7x QGMoHxnqSmSWOp18s60xNaoJm2f0Xyd8v4oJvnP2D4Rl9oHtxOJ2226p WIducgaPGzvLeZK+Ug0N5DisRHOWiE/2YvKV5raAMzo+t1yhIyjC0+mR FNWes3UyVOV2mahCKUM60g91UUjkB8tHdcswnapnYc7X+KLhmXZMGbXx FSia2cpobZPl7PLKbI2DEDFOVwjyYELQI4g3dPZ4aY0mMpAEUkRSwp59 a5/fOA==
+; resign=20460416024207
+84r.subtree2. 86400 IN NSEC 85r.subtree2. A RRSIG NSEC
+84r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . i1COi8BjDNgls+2f/p9xV58rS/3HQVZAPEO7t74bm40MlsFz3zwFwwP6 5hZxQBuH37erv/MMNbhcJo4IrFzdxxCiAKTm9vy4+Od8mOsNM3wBPhgh 4q1wdZQgMVHt0ujSib0M4VvQoh+foFRFFJ9Yi8UHJp9yJUuL7nwtmNhr 4YxihkEcRv1uS2M9ycXY6Igmr8diND1ZLT7AzLtPHw2Kkk7k140KjkI1 G5UcWLI/emknTRlGrLIRb4yUHtFa9HxEX7vHmGNbffKOYZOUrQ6Weh18 +NTH7SdOt96KH7bO9DdjySEUx2k3uusYDAq69U65ZeUWJHh5CV/GIfrv i5DJjA==
+; resign=20460416024207
+70r.subtree2. 86400 IN A 192.0.2.1
+70r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . An/Ib6WiyjTOKXYc1z2GOhDsve5WSEstyynUiKtPzFzskx4DAUz3oJXu WmTWj0fjh8lcS6hc9v7OuxaIVjzgeYy/4I3aiioC3m0hvKoCXX/a89Dg RGU/pMValMERnOPHQFJNfnn6bnLJK2OcncKeG+9xI8zCZ12vXvRCDFHj Wb5LB+B7az/Zpei5QAxv/RKXwTW8Z+Czrd5Rf8ArNGjvI/n+iJDRR/BS zGMd72Sdyxfq3YrNrTbSgSfDE84PW9oAXd1JGvOqvBeVx3at8YRKA+OW +mDxxeWqyaYHrwfBT7K+PoEDnianVszY9xgsDSqutQ9Add9AuVXPAHss B4Ec/A==
+; resign=20460416024207
+70r.subtree2. 86400 IN NSEC 71r.subtree2. A RRSIG NSEC
+70r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . Aa1xQzeSjo2ddP5isYJnFrdxGIB41u5BfLPUcvC+C61s0XJBbh9qxs+G BwMfWWasjOD7eCE8Blpp8s02RFoLqcOZR2jfog/acgYBmke+NxPJb4Ga eJJltzGBD6pxrT8bwa2seocz/mZHRNEutTtRT6BBumsh9GHe4/j/7f6H 0JkKe2yrFmfeoAgiL+0QdYzvr228Drl5/Nd70xsLX/6Bp0ad9jVF9wqG 4+fdxgbVu5cYBl7TSBNfqGZZF2zH2s5XqS1W7kzy6k58NE0bHFmPsvt6 J4LBwzlJ9LuvVGUTt6DeEEKelpJi6rZDNOG4iBu9R4Upr/rxjD5uVOSu QEnv0Q==
+; resign=20460416024207
+45r.subtree2. 86400 IN A 192.0.2.1
+45r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . q5s21YBzlfcLpOiXVDIGCwm7vswz0+SKDguv3QQODUK7suHTq/nzPWgW E5qoFeZlsR2WmdNxT3DEWDW/b1LqnXqGvMIMKmtA5mJhU99qeaJ4Eqz0 5VXA5GCxc43iSofbOAHT4Cbx6pxJKY6uzetkMAz9j+8wZpG4doviPbw+ fHGr2X3Y8Cnikpw9sT9FD94evVVy/oDaIfqp12N3P91q5KkPNk7CroA7 y2RKP1L+xjYknTeiO37RBfkOoIHuIn/kj2T7s2tBiLBWdyqPMOHekP6V nNJLk+anPQF2ZSIgMgjVJsei/F+2RllGH+Gg4kNLZ8EXhg2XXgPnrU57 nb2Ndw==
+; resign=20460416024207
+45r.subtree2. 86400 IN NSEC 46r.subtree2. A RRSIG NSEC
+45r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . w/pT9IPEFwTRvgktRLWSCLiSVHQluPR+94ErsFy77t9CIVZ11Gf0m+mG 2QUtOg2yY1yBTPNIo999r+NiofSj82QGUQLl7BFi0jgfZgYHLMYwaAXr CkoVletffW8GFpA3Bw8bpqZugQdRGOQiNl2DvXqtlqexOS7af+3Ogcgt CDviGDcTFeO0AFAA/hD4dF7W/F6uPAQUQBj2wnxop8rAGnFl9XwFEq38 yvv0kl9ad2L3lzNZraNUq6Z/AsiSFsmDP5M8zVQda1okwPOZdzQivfmY 6k1WxCpxWqtVmiQ88Jp+2S7UhFgFsAWpjSPbYce7bkld0SU30z5nPfkZ W5DtjQ==
+; resign=20460416024207
+86r.subtree2. 86400 IN A 192.0.2.1
+86r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . FiG0vw+/0qkfx3ZkNHTrxsNQB6rfb7xyNV5Gj6N9foOgpvvdIrenSD+t wGhgf0YhwYhCbO+1MZ1E7ShoFoVG4AOtU5sOrLuVUKJUr32qwgjYZtPc ePnVGVXSbSfcOWmsdQaGRtADIHysR3wVMdy8z1GI2r1EuG7WLOhFSZYJ vedJ0c+Zd+LOlZAyQA2RO/R3sBf/fMKiaLKXBaKsk/4v8rkP0nEr2pKN CM4ylF2oEk4REvAHskmQBmUilFha6lqcE5AwSFigeqeJGNw0TVG3rnSn 5cIfAj0NxGNwK4MR1C8WLbLsaS5nq9lPfKuxDr5FRDaWzvmozdIXSeJW OBxF7A==
+; resign=20460416024207
+86r.subtree2. 86400 IN NSEC 87r.subtree2. A RRSIG NSEC
+86r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . W2aE201SZaLS1WZeR5va8Ql5bAWmmkgd+vRO0a1Tlg5keuCHo2e3lk60 oVP6KP5N7oVEnfAZAJNTTdfvnt0RVpZbsBmvh0o+m4oVTRWgMp6TIK2D K4vTjckBK1fGT4BHCV3QPepn0cFjfRz5N3HStg3scJRYczYvv/igkR2P MNj1tnx2Q4Kd8xThuc/b8AnvuUcVxYhR1SRlCHBTHqxsYlbRD/CrJXVb xDqLrN8cBLwDKwMPOQfUOnYq4LdjzbJJLrJNjRkB/ptYmSE2YdwTCY3i XEyW71hJUcya9QrSrSDLXfeO47yuCDxzuRe7ia+cWMh63YnVabuQLd0P hzUebQ==
+; resign=20460416024207
+88r.subtree2. 86400 IN A 192.0.2.1
+88r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . ECdyI5EKeFIu4Jj3tL4d7By5WXstfWxgjZ3Oa1V/8rkOa6KRE3yForzO +F4Ao6t5CjKM5ZsKoeC1ixWLPJ2pE7c0jEgRx2Pey5TJAzrf8wVQKoud fVe6XFU4by1wPNqTXU+0Asu/uRLSaqz1gOIH6/7Ozm7P3/3xPVDbcVLA 0EbxnMZnfcSOOa9sewySVp+4eVbF7mvOQ1FwoIcJlXc1HdDUcO1UPEHE BqEfE2l6NFp71oDWXsaSXetWx4yJtLrIg9EH0N70l74Kboxy4nWfydQE ywuA2v8pjIBu4pz+ZBxTFiPs3cydNUltOAnAvHkL4wI+PKL7SpHM+sx6 YTNtmA==
+; resign=20460416024207
+88r.subtree2. 86400 IN NSEC 89r.subtree2. A RRSIG NSEC
+88r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . XHdir6VyCMaQ1x+1rLuON1wW1B1AXXMynTL3O3z/nDSTGLCiL+AVTm2u Y/3B+go+MK2dWrsZq+l8esBlps8CXDqltYReyuEIKUgnLk/MCa4rBO8L lWS1SJ/xdB8VJ/830aR7a4YifkKaKncQT2qb99iESz/1EqUZbdCNdGTl aoKFGPQd2xI1J5x/RJwad9YGhpHZQ61Uvxv05VIuQIV21j0EnlWHbYPo KCtbgDZfpFx8XVd4qp6qai+lxozgqviYcsCqHJa31iPMTdpaUBtjEOiV 3Cz9PSJHqbWrTGGVEVX+k45qXWPtcABjob4Eb9mM6yDN+ON3QEfR8Vhn aU4V0g==
+; resign=20460416024207
+89r.subtree2. 86400 IN A 192.0.2.1
+89r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . LtLaFzg/aJ2onaZKr5khKLgVpJUJL12P0WD95k6o500NUZbnlmweGC0I JbIqQIqhUlrrQkCYsMCXhs499SNmmUZ0BsOypN/BDfMePbd09F+PZz0o JRHvkf/yGjkBK0kEtZ6Crorl5coSuASum8NwR/nw8h6skZX5cH0+aHgI SwWW9IAnjnQ/RNLnTtLN8Mr5WuhmGGSkje1UPe9oBOlVbWjMAyhX2lVw AU77h15R4bR/Rf18Cz+zC6n1SsTkCRs52j/IS55U/cuJnHv5IfmajHTc bZWcFkbIwX5PMcxkyjS/4oT7e8FRoJPxletIXWxLWwSW+8G+OYwBKlGx ATOMTg==
+; resign=20460416024207
+89r.subtree2. 86400 IN NSEC 8r.subtree2. A RRSIG NSEC
+89r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . IJAqvknmXRDy3ZD8gN2zhCLYkhvHljU3UISARe7YeDf4WBkRLwK+07u7 B6JjiAJWf/qJ7qcQl4bIYxPJ5iLmZuT7bXGyt5aPWcxwk1LluU+At8cE HFEEna0yZshXPWHQiSULtXj+KAjz+rDDD4I9sjoYIY0R925+OXibYpgp 3vDoPD6G+mS7VCl1zoMOU3gpPFpbFwjF3s0kzcJOfW739JFyg4Sxe15H LewmsStzmC5Dy7KWErFPzio1i+e8xbpMvGVjFVapzd/gAaL5Fsw63SYJ onDpQje2zIK7ysaiEXtuezF1mFm/d/HJR5cPu3F80xf35F+CrViR2zZZ zJjWEg==
+; resign=20460416024207
+8r.subtree2. 86400 IN A 192.0.2.1
+8r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . S9i6MWPelsjhrORy81ifXaJw+PpOHNWxa4UXaIa9cFskybm2wx5pGQhN 9Csz9v3P05lOwDXasBEHybrlodlSY7+49M3g5yqLEnLVWiqlgRdulLcP zgNkLAgW98FixbbR4WdweG0HYbYuq6yJoNERdLAJGRhz6MHPgjYTL8uI jvQ2UcBPdeeB/eJ5uL208LbFXrOgCPvCjSxz3DGXgrpH6JHRFm1i6yCs sjou+AsF4gX/AwcM9XUmxkh5lD7HN+Ey4RDtid/DNL+2WrnLoBwjh/YB DdiT123+lNg62J+TlQPgvr4Wdemz+MTzcWkSfkjemdyYZ6W06IU0altW /Ufr/Q==
+; resign=20460416024207
+8r.subtree2. 86400 IN NSEC 90r.subtree2. A RRSIG NSEC
+8r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . droP8BigHxGz/QAEBLOgYzSmdABokPM5BRluOKY/zr9Nh/z2dBiBW1EO 1cV5GPK8lcx8toqEfu0Zq9+aWzdcV3ofvRhZ5q+JndY05X8GutT/0P3W gRI+96ilRFksLKU7dS2uj6dpsopssqkSqGRl685YowNnn7O9bB4LyVHP hOlbhd1sXQ40+bvxYKMui0SU3FrotvjNuU3u1CtGormUj+vjFSbI5FoE XkWDg3C1QsTD3mEjXctQIfL5mv2TTWkJqrAbPoG11wTtAa8Dm0/RjoUK jvnJPMloW/gIiKTyif6PV9MLIyDHSXDdvxOwV4pAQhpUm3up0ZkAv3Pe HMSZFA==
+; resign=20460416024207
+90r.subtree2. 86400 IN A 192.0.2.1
+90r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . sguhfNWje/190bkCeJ3v/75CjfdICbh/bno4hsC2ApZbC6Nq7XVTA/VQ U35g7ln+fjiD03UwTAf/k4RzA8REfQanK02LNhj56zFNNhhdnzIsJPrg sDcyzQITp+SMy1boseShRjukdgSMMU8E9igqs3S456YC+dlp2Zn4WrbN p9noTXUxsVt3/TJH0RaZBy5azXgEU1+PiLO7YNamHrrvTdcj57RjyVxe M811Ge269l6RWfuLR6ssV0LNO8ZrLRHNnxvtg8RvkbJXSmOjom7dbqEJ Gg+GA4/vHqDl37nJdFuHkhwUnVSIV0ntcGDbaNBliEj4t663iLB69Fz1 FYbK/g==
+; resign=20460416024207
+90r.subtree2. 86400 IN NSEC 91r.subtree2. A RRSIG NSEC
+90r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . O6+LuRnl9i6Rt+pAl8e7rtkF3aACthkrEbTQ3eMHyiYeoTJsVpVyPArX PXFTtXJxYQjqwPHVGl4jukLnJtDJy+x/OXwhLea2UWmpo/APCO8K4xrp DjCiBBe/S2uYnkVRN30wu4t2UqdojBGnstmsBmaIF9+oyVRf67OSiHet QOzttz+g8DGbfJ8KUlzYhPCPvIUR3Dh3jEfeAfO8CVZ64gXZwTwGZblk HYNZzKQs2zgga+r/R9Dpp4mHxyDVH1x5USVXx51Y9sXZ+kNJeclyEibd zZMli/iDXH9PHBTCXbyHBgwMmZOtNMU17k8/oA8uwPZKN1owUmfWO7Ar psAbxw==
+; resign=20460416024207
+91r.subtree2. 86400 IN A 192.0.2.1
+91r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . dOrt/iu9d/CPmDnkLgGlI7bd1RDgVosMf0+Q3y1qg53EzrqtBCuIKZ+D /7a2RtYWTkZp3j+hyrhz+WHBTCfOr/KUtlHCsrOIExY7cpSTaYFSYA5c UR7qAkYsUNSBXBsnA/ucSyllfXoiFeBDlmO4wNnwnjI0F1hMJCxnn2Rf i5qliDwwlEojWPYMygYwzba0Rc1GMljsd1HLysjnRu2rslGNRx8dACRu QkqFNLOU/iqrJuWIAYCRmkvJTqdwNbV921oGOTxNJAtw3KWDNWMQ24hn sH1IDkyAq81FKDtI19BdnAlp9uDhBTWOGMJ32cooTWTig/ut3oMA/zqd gGp6zA==
+; resign=20460416024207
+91r.subtree2. 86400 IN NSEC 92r.subtree2. A RRSIG NSEC
+91r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . RRwaMaalChpe0eMu1K7oa/VKqUbOeXwhN4GwZLP8kANBVr2H+VEHkme7 2eTZfBZamuheOlACtuW8kwm/F4ZAtY1XTr0bFKTXV/J/X/eISDCj2JTW +a5iNuq1JHok+vCZmF6t6u4PVKM/hD/AttXrcjHHK2TfOdgO7rZ5gGaV 0cBjT7SeWbzB3RFYWH8imLOE7v469TGO7W7bGxDwdgyvEQ9ZCZV6z82e uQoKddHC2x3nwyrkJJ70Z2HzBJOiByQjXs6hCIetC128HEtLXoQ9ILKA s2gB1EEzT6+PxcARpK7TNNuOTNpIriDkw3vItpfp9AvTqaR6xRX5YwYC ufT4tg==
+; resign=20460416024207
+92r.subtree2. 86400 IN A 192.0.2.1
+92r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . elD3rVSaGOQbDjXtl1rMX3XtseJPSbIyVkORcBJffjom9JPkT2MenM5K 6d5ksiAlTgnSCcOf2gMI8AtSpJkSdmU6CBCADUc9p7rdF1x2K4tQ6WdY G4koQmAXGiojxihftE8z/N/xIt2r7oNMfwdfk7cxgKUBuJs/gabcJFLi 5UVgZcVqlWVlLmxKWk1zNbAY+LuCZrmnbP4nA1qQKqA/i/yMPnPcgdWq DZLGtpjFiSucVDxgaIoQQkobMGG6mMwwrWo5F11V1G1zmxx6NXvaKt+A 4u8pclsNxpDCQQcCPgg0znXPtLcyaQl8bkkg+lK5lXr7Ct9gPaWITzJE Z63S9g==
+; resign=20460416024207
+92r.subtree2. 86400 IN NSEC 93r.subtree2. A RRSIG NSEC
+92r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . IuwQACPEsgjR9yO0WItcJ7eyepFUEh9Dg44S7hIS4BmZPgcQrO4FeboD GzGTjbR2x/gP8nYarvTVmxK79kqQ9UATg2pPojyJMKWkoE6Cv03qJzKx nxHkAnyGFGYjIa6zFNJbPQfz+G7SX+o14ooHyVXZcKmAqwKbxxuAbYK3 oSWSMM6j+lk+Ak+GoPgm5zxrbh+aivtGqaZm7Xhg9A877a+w7TjVtOn+ WagIQB9FjG2Ilk3pGIiAskveIMrUM7NPr7bTeyvb0rmewheDfd6uJ8Ou ZirvOhuwv59rDoZ+Us6JaBQ5Y/SrsMQRe3bLwNjx6nuCQlUKedK4db4p N454kg==
+; resign=20460416024207
+93r.subtree2. 86400 IN A 192.0.2.1
+93r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . FfE3JvfkfdE56yTYiqu2CCMxMo2BUwBrjXf1XU9OZ2amya2aSGl8yAl1 yGXbm/FwLKgK6WIfZZTQHBr9Hm3UgwWNg79Z5OQj+RvIHfuIgpX0YgFR TlnLtuFWaufrxu+g+7AVRSB4RkVsN0b0i00o3RGS2pjAtAQ6S/h5R/Qo FlE/scsykd3dCPGyPICxRZdDzouk91aw9YZtxJFOESUHYdKFpqsnu0yf Sd1VQ2kFh3kgkk4Dw59L8hOmYXT8Uxi2gHOQsbb94NwpEJ45NyRAe+xI Vwu2vp+4P1talaWlrlEPqH7/eQ+2AiaAqklwZhKKkN4H9KMx8/T2lpDc ObhuJQ==
+; resign=20460416024207
+93r.subtree2. 86400 IN NSEC 94r.subtree2. A RRSIG NSEC
+93r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . DmsCcR5kIlhw7uLX5C9MiQUya6CWs5q7zTZg5n/r7XiEyV/gB9c2eFLp nTgJdbczL2ShCSEtkb0aYPRRjAvtqGF48JmGJf1NYFgWCmQj2Rei4Mfe besJvJrn36MIY6iOeGFlVGcSffsQxySISEf2+c9UcKOkqsV/O/GCPFHx dU1yIDu+bit8Szhrt7x3RhB4Uj7RWZW6pzeVA/KxBXHHFDSwl/51dygf j0KB7D1zZK5nfXqHtecwzFy9JuL9SkcvI65oPaAjcjS+AbqWZgiHpeXN djbNKhzqUDl4jP+R5wdxs3h1ONQ9WFQOT70fy8gB1Z4fTJLutbEOiMSZ n99gFg==
+; resign=20460416024207
+94r.subtree2. 86400 IN A 192.0.2.1
+94r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . CmTajnWkJnUVcGZzcokeDSqy/NnLUc4Odgi+zon5TrgSaAOEL66pm/zN BSkfK5nciTwptVSg9gpYPu2GMmFamytxizc2cu5YkC0zpcuuWDybGSAz YNw4iZBhLP8iowD1Ea/s7pDflgogShGzX24mNpnYJxVimqO2Hyhp045t xQTumsHzZQVWUlk1Hsa1OtcAOqY4JA9A1zn+gP4Fw59ytXTRPs1C2I3y F8WIOfTrWviN6NvcwFrii2tiQwC8BpI6OI/1wbdkIy2KbHT5IgXxsUh8 QgQjFg2W5pwcbUaAGBnljuAaH7ZL9EAQ70rIybJYNomSc1nEImShb7FZ 39TOSw==
+; resign=20460416024207
+94r.subtree2. 86400 IN NSEC 95r.subtree2. A RRSIG NSEC
+94r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . RcJXpMi5SCMM2tlHDYUwRpRf/BpCyhs3ZUx6hDWJZ9FkMZTJFG4/MWqA Amib2FehoHrhMHcWdsyo/nFQjni3EX28TKt4OlHUYMgo7Kw8p//R1IRA xM5YBsF29k+QZwup8RO/op4a3q2/1lsL+VedNeoJo0giTdfahq8phN1U MNszlAQZ3SuA1T3QM0EnEldKJ9I4HPXYLR/0tLKnjTkCOX6xSI976lAT 2fRGhRuDrhimzjhOWKFMzu+Is5vvAHEqNvqBO9jSIWihK/qoa5Lk+1Tm 96MWrzFMPkMgiJIm5Y6w0VIFFguN/8l+dLbyrzE7j/ytxoPgvWwItjmc gPI8Gg==
+; resign=20460416024207
+95r.subtree2. 86400 IN A 192.0.2.1
+95r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . dEvcbOlBNJYt35F+19pG6fuqzLKwxV8EKNYst0AiKnHxThDTBe6t5zTy j3BQqVaODnEl5nexcjfWigd3u1Fyp5V4U6kPDhe3Jy31FJxDZQPRPLlI hVf1iftkzse4iVx+NpYn6xDbacz/t84RNBcKQGAb2M0MXEbdTBSMI/dA AloyXIedaJAkMMMVTBCQ+b9+YJrCpFfq/uN4hI4kjWvh6hVuVj69CrHL mGD03WXdrURhmhl2mw+AXjUoIopCLGch5h0j1qEc3sAPIkTkmpcaZTvV ZaQTPypvkoK3exrlfgeOhfvHlbk7olrfLcoV6QgSJKRXO/MqRwOVagl8 xIF2Ww==
+; resign=20460416024207
+95r.subtree2. 86400 IN NSEC 96r.subtree2. A RRSIG NSEC
+95r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . E9OK+kEC4PuVEN+P7c+4KzNCAbR3Hsttzi8URw5yjixiGRPbUdS4BdV9 z618OxJzmJJ7M8mz0a5Ofp3fqeXGRmuWecSEMtzFcHJuY6e6Rr2GTXEg sXM3TZnSkEnVtzuCLa+n6nAB0pgEZVnaln3gOpMGZp3kUjfl/0dHE68e lUQ1mqyefoMMx6wsFELXdRXw8g863N8rnu13jx2RkTwufU9Ri7uxSzIw BZvLnGaGQhweCxme8mG7kXU4pZCD/CDYsUUB2trhvsr2f/6ZZkxrlgLe iDBAFB8aw0eQGlf6wPNrumye/LI9CLGwoe1Y3rR5+1O8qCnJYSIy4Bs2 q28nEQ==
+; resign=20460416024207
+96r.subtree2. 86400 IN A 192.0.2.1
+96r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . u1+d0AAtw7KTRsYrFqDlgNIWZUHG3DGvnS/OVOlLiaFrHjlJ8YMKGRoQ WB0cxJ061Hw783mmVZcIJXCXSpfZV6q/afki+b9ZwIO+0yK9jD5cY9vD H5CteywVmduCLoDs0uDYBWE4UbWcB3L8wqSgnDaY4dTB3lmj4oEA1qde a04/Y/R19ntlmDM3lS7tDjY5xRlzK9Q+e8EsxRfriI326px6HBRqdYew dn7RRxVjWbZR4H04nedDQ5jeBh0t0Jl9UUdv5rsYRczE58DR4hkeMrMD RsQv9aEMCCHZIblHS7Jo4O7T7mAjit+0n2n6HOqs8eistzURsErvZogl WvCZEA==
+; resign=20460416024207
+96r.subtree2. 86400 IN NSEC 97r.subtree2. A RRSIG NSEC
+96r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . A1rrt+oKmhhenoj0rBMlott7i5hJ4sKX6yTBi2sQWSCiJuZtPOVaZ6v/ AoOib4IgvSqYc6iIDxn600Xt116j/TWYM/skU/59bd430WbGhoDCCVpC IoNilVWmaDltDkqRsOOJygeJyt8MubUXry5v33MHjxRYywHUZk/nZz9T 05dYDB5IkPzQkUR1kpWBSmxbKhpTDMtOhVtg1oAjb9dOlIDcC6TWno8E hpW5NRJjSAihwOUScPKrubIG3pN4Wzj6yADVao0IBQ+sukm2l3BDdXnU tOI9Xsk2/f2JObVQNs7QqFgtnD6Ht0+9ZfnBCJJtPPcz3flaYIaNeGQ9 bA41rQ==
+; resign=20460416024207
+97r.subtree2. 86400 IN A 192.0.2.1
+97r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . gLTmSp8fhdoLKIOQVjqsqT08v7KC6sfuAPIUrLiauhLvDO06Tx0hIt8V i6An7KsOsaH0ELt2piRbGf6MS/aH2jHSuluFgGp2VIal74kT41A+YsL8 2CkgAcLSvD17HCtWAzxz76eplPJbA3+2nLnSooM04+qR/uckUNdP3Tnm MbZExofXSj9OG4b6U/kRZJ9H/gEbdktDCdtvnCBeJUoV6K9bQc8/RVhE cf/blPcGNm/KVf8XQZgoBTsr4t3S2f68WwpT2pyeoaqYxKr5m6k9jfWC FDRWjGXjtU5IEeKubH2EAjpgBWPLFaRUDAerTjFTqsnJneCMds2k9+gf cULClg==
+; resign=20460416024207
+97r.subtree2. 86400 IN NSEC 98r.subtree2. A RRSIG NSEC
+97r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . JenfHs6Shb7IxIUJK+cojyruYCbm9sBk6sdB7UzHDy/ezOnm3Y5tThi4 YKfvUKxT5/J0rapIIq+eIjs8SabokeG14EsVFDtOHD80xhqdaAukAy6B naSvzFhe9hod0MWx9lM1pOosoVvrA+Wv0/8DOcGxC0myK9TvOSrl3PKM Xr4y8Y9pthV960TM5g7y2GE+aXfpX2gOZiMGe0WOTqUheXQ8wC+etOdz DW5aRLV63qtwXnlY7UWC7balJ36EzELY8al2to5KVhwxwfjjdvak4rWv KH8dDTUY1gL1jX+GPMmY8uLRWMKTHtx6HA8s9AHVxLLjra0lERkbs0/m Y59/mg==
+; resign=20460416024207
+98r.subtree2. 86400 IN A 192.0.2.1
+98r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . uC88oukw3HlsaDfwK2REa9YSQ2wNlwkw3aQ/MBTHUdiOxhZ8cCjdAbLH Vrbn2zCUYcwcAyfYTNOQ51sG2xQ9IsQaclrKO6wUZTikr9vQdwk+/yYS 08o1K3dc0NUSacllCkJ277lekmq8WRhX/qLUKaLScOV2mzZpEVdfqR/7 eZYI1fjjsMiccOjjdKvQdrK63lZrR4JW8KkIlojguz7lNjIuPqV3srD5 psHZDPL8LfoMcFFV3BKr0X875JKdbCTWEeVcAlMmgfp+AZ9s++SggHix ALCBjBhrNJT5zeCTGwU/Y3dBfYYbzTX93fOMfRP60ER9LH+Ns2khIOCj 4siS1Q==
+; resign=20460416024207
+98r.subtree2. 86400 IN NSEC 99r.subtree2. A RRSIG NSEC
+98r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . JzxL54WUwM8cA11scDj5GOKD8AW9VgQT/XtJXKGhwejRMuNH9exj0uLx 6OPLNNN6gp3dgz/mu1LhcE0SiTr42AhmJlYzBJsmJuMZOJ1OGcWYX2yi Yl5udmTp4SJrGQPvH48KzSY4/te2ik4Y6lKdiKz1bd7aaH8cqExIVHMa DJEzXwjJqOQQCph2rq4d1XFfst19ghyoU2GJ1zX8iMZ1TDR/GppRaxd4 ZecfR9C9dzItIjnPo7Ky8JUeGTQY0+PvIriAIcNVTRkEm4x5+zNmLOXe fWTTnoeVhTXVJYki7sLjtKWvoe5jKdiVgJWqLN6Ps4JTJJgu3BHGJzbH fqKqxQ==
+; resign=20460416024207
+99r.subtree2. 86400 IN A 192.0.2.1
+99r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . NO/jA3/Fq6aB+mNCs5aejoZdHdH8MZ5waNKWmW6ba8Tsp58jiyMOAiIj aLiLBZ/A7vXj67NJcCgp0ffs0eE1xwtgcg8DwtsOFHey1I+zmQSjmmUI Gqi0Yi4F0G5V2URkNcZPfc0Ey6zXmpCrfVrKS0DktP8g/kjLkXilTd5F xfLZZzb4XvQA6r/UzNdWaQwe+IU1pYS9h7i4hezxDINj5RoemRykPbBa hm76bG51GX/iLcQ32SuJHM8AaQ6PnnKXLvB+LSkpMBTm9KshBLu0/Sju GeletOuG2sveR5BP6BpQR5STJ7upc5jZH0kOjBUwrV2UI0GPTg0aMl8Q jToNww==
+; resign=20460416024207
+99r.subtree2. 86400 IN NSEC 9r.subtree2. A RRSIG NSEC
+99r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . QHgZNdQItRkchoW2V8xGFn1CFeAwWEH3WlRNv5PTDopVoaOF5bZocWUC OTp+5SFJSqVZ2VZBSfCaqjurC+pwpGYviQQvxV7C31aiQFwoX+092XvU 7EM+YbOLDzg3u95z7YESo58o/ZVIti7p4+JPAp8IKPjGiPhUKUH3hArO TvoZja6adGCNpLkxbE5VFA6esI4ZTMv6IEhALBi9/IdI8ZRpv6WMG+Bn By1w9My++QCtPFQIFC1tLTqPKaIUknL/H5gqKMHmR5YteXpQ9jHtuwEN Lys7P3I/E2TVr2Jt35YyYkUUaxR/W/AMRYOu/cyzuR10nLgiQBLhc3xs 89k7Lw==
+; resign=20460416024207
+69r.subtree2. 86400 IN A 192.0.2.1
+69r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . H9e3SuKHH/ds/qxJExQwItamzQmLsoYnh4u8aAAIOHg1+LT2P0Sn/KGw ISMl/McYEeOXlFt2SGwC+3X96MlXC9GpsMxtPLy86Jt6p/O8gVdSpr7P y2bFB2Ioz1I64mGKTN+AAJtl85zeV5DbEeQcB1uCtHGdh3aGhgS/CT82 b0eFOAuLiIf45Wy5h5DFZz0n9XAUJGOCejUUqZlEdfSJ/9Y9KCjFPOf6 XDr1Ts6eJhukd2FnGImAVRsCeYuCtkm3GjSkxYG3QgqJNDUDpk++Xzw+ 5kNiOZgQ20y8d+VBfC5IJ7mZlEuUCO2Bw71EQC/BbHVkQdgDbKe1oFHn 39Gd6w==
+; resign=20460416024207
+69r.subtree2. 86400 IN NSEC 6r.subtree2. A RRSIG NSEC
+69r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . HUFhcEIpOw13gVwxCTqn4SkpOHHks/x+5qXR7zbMzeCWh3xH2e5V6xyd vh0gD4+qpb6BV0VtHTCWad0IvZADLo434fIAf1skmmkwXHK1P3s8hqeh K7iKTcKSwqE0Fx2vCpmmkutyKgNxokyzBmyhhMHk3kIbh5SqOl3Bl9wh G5WEuICCh+SxFaM+8eHOZl0iWIZAAD4EW0kVdU4Mi0GUI0rvufYL+Jv3 z2Scw+zxA3ZOBPLgHFWLrVd51zap6Sc+CpIE/E+le0TRcam/wV++Tpr/ 5tE7FN634aoVZlf0z5R9VE5rlVvrkzxeo/OYmLWaJ0JbirTMc2nUIOQF 7lFbdw==
+; resign=20460416024207
+9r.subtree2. 86400 IN A 192.0.2.1
+9r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . w3ZdS3SbdNZCYHTVb0iyxEhH6CsCcS3dzopqkxQLH1NhLlEC6zCD8vaZ 5iN3eBV55Kl751tEkmiHeCajXLRhDd6xZC71gZRLp9B8oouEX6DwofZ9 m00N7njjtUd5+ZAuqN5r4oZm4N9zVMA9xQjXszDGM5r91EjxzChohzUE lZ+b4aeOd2jA3z2nmygUq4bNYGFonmzCDhuxvhhrjw/dt/eXWGMWBxFN Rz6Z5ZTgcAgU6pjANijSQ/7Z/D1SZ9f1gDL9O/yK/et08jR5Vlt49McZ mTWcv6ZPOuzrcWSFzO14TR4ZWQEYBKWHcflACH0QRJeMoIrR7D97pPGl /nycqA==
+; resign=20460416024207
+9r.subtree2. 86400 IN NSEC . A RRSIG NSEC
+9r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . pMO6DJZKqSfiPHQjd3nRdxcwHgyDVAtSeTlLVZ5q3RBOQ1hxKa+b1DF/ lPNU/0YDsfEznEhkFPQj3ceWZtABhVLqj/tQNQy2TBkLBFVDTQuLHNWh wjSAwmg5SRUI/NG3t3c4142Sb3yc418XrRWTMu9SS147hUzqZsNls/19 6vkIX7GQLIyqhOULjedZplNFgOxpRmFa5zORTZ30ghBZj4yuH/DXKJyb POLV/h3OrXi3d6KzKkFH+ItRija8dlm3cNNvf5ibD9DsXoEDDm+xu4YM tJDHS5pcPschc99l4YzQPw3AUmOFmoDknzS3v4KSXcbb2olM24pqVb9P eAENJg==
+; resign=20460416024207
+85r.subtree2. 86400 IN A 192.0.2.1
+85r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . f3ogUidaXG4YfcQ1pk360EY2gIoH9khcvUAnb+suATWZgyBzhgzzFLcW r8hB+tF4uW7fpECLic2w+BmZUFX4yGWVDYldS0Nywvj0vApNWAnrn+3P RdNJ7zkI5/ZO1IZDGTGaRZlG1wkIv8KL4lXjRHjw/VU6vMgepld5cCNJ 5tYkhBdHKvltkBqsD3owQ1nCuvfDfIQp0z6H5gCx5EpoNsqKz2O9Z8Mr hjBvl/yVhDrvXRbN0d4o3pHdg1ozm2azNiwRllgCD/vxV48Uw7ZOkFUk Z/e0kgTOsKHCCGCV976OjH8ryFPiVwD2r7tAbzzrEctDtL3pgKocTknh aUSfsA==
+; resign=20460416024207
+85r.subtree2. 86400 IN NSEC 86r.subtree2. A RRSIG NSEC
+85r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . Nc2ArE889yWghwl7jvS5+GSHcYV7Of1aX+YDPThgr+DxZS68jKXwXhrQ NBVMGe/tPdCML/Ka7rggAUmgQJmrx4JY/s1tJMbm1GUJr/rVd23Qt2/3 5Y0OQF76JeNfKtyUfdr2K2nIKtvte0zPq4RlNa0NWm4Lmm53PES4PnO3 w5cnnxwePHMN8aQp5GucyFCdw+Ah8pRGZLRVbPJgj+iL+YhT4k4mQeI8 yoMuC46icqMRzg0lGHaBGeSE8uD1GVjbwOpngqWjB8vdYDmBX1vWNt4P dVII2ybrBIwfnqnGZptNqhs0roKaLGz2GA/0b05bwl1jHL9AhYZ5Zin2 Xz1JVw==
+; resign=20460416024207
+77r.subtree2. 86400 IN A 192.0.2.1
+77r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . QAc9wnWC//xMkla4VISWRiYme7K9/K1PJc+oLaJ+slJJSjbqqbqcqUCx EjDCw7V+a9FvnSTBs3tGpBvnQfGBT8LwbVzgrLA3p7Ad0JX2O5XlaYU7 tcbDatZdRoQkB/rxpUcPzEKe8t3mT4nzavyK+QTF6gbfrcGLRRrdADwh lUOmada+Hz/339BkLYHEvFHCdnmovmtBUOQPjgVpj2pFWPZ+cAOw5VJV 7/mLFwijuoe22Yq9E9WaI6YWJIeobu+Dht13FlUkiAgQeqyDAOCnmLjp Hf2VRjXvRktliYOHoM1gBG9c7qUHIHtOS4oXRT+0ElN9CBBovTzdIoo6 WML2DQ==
+; resign=20460416024207
+77r.subtree2. 86400 IN NSEC 78r.subtree2. A RRSIG NSEC
+77r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . jp+KYsenqjl2t7tBVdmg1VVQoq1eHgqnnGjLeVU3oGNLtwwvQWEl0fV0 MNMuBUzH5jhMw8L8VvmFihIa9RQga3PQDI+CnrvRH1YNM8OAXzaWWWrA Fs4cS/cCUo3dbfgL7bxxTYmYYG96N4QbTvBE6M/N8bvquMikTdWjsMBy rz3ZsMCoVC8CXr+i06vevOKZaqfJ08hYg/hbW8+h/XtgXaQZjLEGJ68X osO+20PkOHvRD7X3RTHVlDrT2ZZOjCokNEgl4/alp5t5xXi6A3hD0HfF T/tzTiBi8gVw/PXJRgPV8rE3BXCf7Cqwwtei/28Knkf13zHD8fOmrV08 PuQfKQ==
+; resign=20460416024207
+87r.subtree2. 86400 IN A 192.0.2.1
+87r.subtree2. 86400 IN RRSIG A 8 2 86400 20460416024207 20180815062314 48409 . fPXLpsy1AqCF8HpnyeICWkuMtVpa87akqhqWJdKTG6pKKVQR0swtNaYE e3aLriYm92PGuYzdIIrQLyBlRqfdsyNIbhcGSufBplGt0hUR6CCFP6eX wuOBqw2lhrNReC/GM+E1wjvZTfZ1qwc+JOA462jXX0t9PSrTTlFM5CEj /91mOZXJ8DTYHeDPy3jvPEjhR/137fC0WhHHrMNKI7wT0dNSObq49DXu IzqrtNpzEWtiDYQdhk37hraueb0BNFmVONLqve2Q51D320qi953XR3pz olGQ9UrI7Eeo4kbwSGLo8U7mIH2wS65RHzrO8+4U+W/pwHXLoGnQxiRw e1NfdQ==
+; resign=20460416024207
+87r.subtree2. 86400 IN NSEC 88r.subtree2. A RRSIG NSEC
+87r.subtree2. 86400 IN RRSIG NSEC 8 2 86400 20460416024207 20180815062314 48409 . JyZPoj5NUaz3hnlq+EoPq2mozjKk1VsVmD9Ipc7M8chTIxjiYLnyRVcx ZeE5p+M19oXK71RPwSdYH2UjiFCOa4cZntkIny972BYEDtezGdSYzz/z VMDf9r6XOBeECHiIAaF6q+ptR0K47188Q6+eTlcPZMNSDrckRFBfI/qT 9R99kCvDJ5WyBTY+2aT2qCP0+INJi/XQfOj3RuuJhxLh7UBbicdR43fb QW//otvC9Hb6RwxZFkrM283ddAcjA/0/L4bPmV5AQo1lGeO6e/5jmBay /uJD4HVAHwW3T7rbQyMOWjoIGyJreEaSiE2ykBptwscbgrBOygyOs2wX zZ8EEg==
+; resign=20460416024207
diff --git a/daemon/cache.test/testroot.zone.unsigned b/daemon/cache.test/testroot.zone.unsigned
new file mode 100644
index 0000000..c790cc4
--- /dev/null
+++ b/daemon/cache.test/testroot.zone.unsigned
@@ -0,0 +1,216 @@
+; SPDX-License-Identifier: GPL-3.0-or-later
+. 86400 SOA rootns. you.test. 2017071101 1800 900 604800 86400
+. 86400 NS rootns.
+rootns. 86400 A 198.41.0.4
+
+subtree1. 86400 TXT "txt exists"
+subtree1. 86400 A 192.0.2.1
+b.subtree1. 86400 TXT "txt exists"
+b.subtree1. 86400 A 192.0.2.2
+a.b.subtree1. 86400 TXT "txt exists"
+a.b.subtree1. 86400 A 192.0.2.3
+a.b.subtree1. 86400 AAAA 2001:db8::
+
+; subtree2. is empty non-terminal
+1r.subtree2. 86400 AAAA 2001:db8::
+2r.subtree2. 86400 AAAA 2001:db8::1
+2r.subtree2. 86400 AAAA 2001:db8::2
+3r.subtree2. 86400 AAAA 2001:db8::
+4r.subtree2. 86400 A 192.0.2.1
+5r.subtree2. 86400 A 192.0.2.1
+6r.subtree2. 86400 A 192.0.2.1
+7r.subtree2. 86400 A 192.0.2.1
+8r.subtree2. 86400 A 192.0.2.1
+9r.subtree2. 86400 A 192.0.2.1
+10r.subtree2. 86400 A 192.0.2.1
+11r.subtree2. 86400 A 192.0.2.1
+12r.subtree2. 86400 A 192.0.2.1
+13r.subtree2. 86400 A 192.0.2.1
+14r.subtree2. 86400 A 192.0.2.1
+15r.subtree2. 86400 A 192.0.2.1
+16r.subtree2. 86400 A 192.0.2.1
+17r.subtree2. 86400 A 192.0.2.1
+18r.subtree2. 86400 A 192.0.2.1
+19r.subtree2. 86400 A 192.0.2.1
+20r.subtree2. 86400 A 192.0.2.1
+21r.subtree2. 86400 A 192.0.2.1
+22r.subtree2. 86400 A 192.0.2.1
+23r.subtree2. 86400 A 192.0.2.1
+24r.subtree2. 86400 A 192.0.2.1
+25r.subtree2. 86400 A 192.0.2.1
+26r.subtree2. 86400 A 192.0.2.1
+27r.subtree2. 86400 A 192.0.2.1
+28r.subtree2. 86400 A 192.0.2.1
+29r.subtree2. 86400 A 192.0.2.1
+30r.subtree2. 86400 A 192.0.2.1
+31r.subtree2. 86400 A 192.0.2.1
+32r.subtree2. 86400 A 192.0.2.1
+33r.subtree2. 86400 A 192.0.2.1
+34r.subtree2. 86400 A 192.0.2.1
+35r.subtree2. 86400 A 192.0.2.1
+36r.subtree2. 86400 A 192.0.2.1
+37r.subtree2. 86400 A 192.0.2.1
+38r.subtree2. 86400 A 192.0.2.1
+39r.subtree2. 86400 A 192.0.2.1
+40r.subtree2. 86400 A 192.0.2.1
+41r.subtree2. 86400 A 192.0.2.1
+42r.subtree2. 86400 A 192.0.2.1
+43r.subtree2. 86400 A 192.0.2.1
+44r.subtree2. 86400 A 192.0.2.1
+45r.subtree2. 86400 A 192.0.2.1
+46r.subtree2. 86400 A 192.0.2.1
+47r.subtree2. 86400 A 192.0.2.1
+48r.subtree2. 86400 A 192.0.2.1
+49r.subtree2. 86400 A 192.0.2.1
+50r.subtree2. 86400 A 192.0.2.1
+51r.subtree2. 86400 A 192.0.2.1
+52r.subtree2. 86400 A 192.0.2.1
+53r.subtree2. 86400 A 192.0.2.1
+54r.subtree2. 86400 A 192.0.2.1
+55r.subtree2. 86400 A 192.0.2.1
+56r.subtree2. 86400 A 192.0.2.1
+57r.subtree2. 86400 A 192.0.2.1
+58r.subtree2. 86400 A 192.0.2.1
+59r.subtree2. 86400 A 192.0.2.1
+60r.subtree2. 86400 A 192.0.2.1
+61r.subtree2. 86400 A 192.0.2.1
+62r.subtree2. 86400 A 192.0.2.1
+63r.subtree2. 86400 A 192.0.2.1
+64r.subtree2. 86400 A 192.0.2.1
+65r.subtree2. 86400 A 192.0.2.1
+66r.subtree2. 86400 A 192.0.2.1
+67r.subtree2. 86400 A 192.0.2.1
+68r.subtree2. 86400 A 192.0.2.1
+69r.subtree2. 86400 A 192.0.2.1
+70r.subtree2. 86400 A 192.0.2.1
+71r.subtree2. 86400 A 192.0.2.1
+72r.subtree2. 86400 A 192.0.2.1
+73r.subtree2. 86400 A 192.0.2.1
+74r.subtree2. 86400 A 192.0.2.1
+75r.subtree2. 86400 A 192.0.2.1
+76r.subtree2. 86400 A 192.0.2.1
+77r.subtree2. 86400 A 192.0.2.1
+78r.subtree2. 86400 A 192.0.2.1
+79r.subtree2. 86400 A 192.0.2.1
+80r.subtree2. 86400 A 192.0.2.1
+81r.subtree2. 86400 A 192.0.2.1
+82r.subtree2. 86400 A 192.0.2.1
+83r.subtree2. 86400 A 192.0.2.1
+84r.subtree2. 86400 A 192.0.2.1
+85r.subtree2. 86400 A 192.0.2.1
+86r.subtree2. 86400 A 192.0.2.1
+87r.subtree2. 86400 A 192.0.2.1
+88r.subtree2. 86400 A 192.0.2.1
+89r.subtree2. 86400 A 192.0.2.1
+90r.subtree2. 86400 A 192.0.2.1
+91r.subtree2. 86400 A 192.0.2.1
+92r.subtree2. 86400 A 192.0.2.1
+93r.subtree2. 86400 A 192.0.2.1
+94r.subtree2. 86400 A 192.0.2.1
+95r.subtree2. 86400 A 192.0.2.1
+96r.subtree2. 86400 A 192.0.2.1
+97r.subtree2. 86400 A 192.0.2.1
+98r.subtree2. 86400 A 192.0.2.1
+99r.subtree2. 86400 A 192.0.2.1
+100r.subtree2. 86400 A 192.0.2.1
+101r.subtree2. 86400 A 192.0.2.1
+102r.subtree2. 86400 A 192.0.2.1
+103r.subtree2. 86400 A 192.0.2.1
+104r.subtree2. 86400 A 192.0.2.1
+105r.subtree2. 86400 A 192.0.2.1
+106r.subtree2. 86400 A 192.0.2.1
+107r.subtree2. 86400 A 192.0.2.1
+108r.subtree2. 86400 A 192.0.2.1
+109r.subtree2. 86400 A 192.0.2.1
+110r.subtree2. 86400 A 192.0.2.1
+111r.subtree2. 86400 A 192.0.2.1
+112r.subtree2. 86400 A 192.0.2.1
+113r.subtree2. 86400 A 192.0.2.1
+114r.subtree2. 86400 A 192.0.2.1
+115r.subtree2. 86400 A 192.0.2.1
+116r.subtree2. 86400 A 192.0.2.1
+117r.subtree2. 86400 A 192.0.2.1
+118r.subtree2. 86400 A 192.0.2.1
+119r.subtree2. 86400 A 192.0.2.1
+120r.subtree2. 86400 A 192.0.2.1
+121r.subtree2. 86400 A 192.0.2.1
+122r.subtree2. 86400 A 192.0.2.1
+123r.subtree2. 86400 A 192.0.2.1
+124r.subtree2. 86400 A 192.0.2.1
+125r.subtree2. 86400 A 192.0.2.1
+126r.subtree2. 86400 A 192.0.2.1
+127r.subtree2. 86400 A 192.0.2.1
+128r.subtree2. 86400 A 192.0.2.1
+129r.subtree2. 86400 A 192.0.2.1
+130r.subtree2. 86400 A 192.0.2.1
+131r.subtree2. 86400 A 192.0.2.1
+132r.subtree2. 86400 A 192.0.2.1
+133r.subtree2. 86400 A 192.0.2.1
+134r.subtree2. 86400 A 192.0.2.1
+135r.subtree2. 86400 A 192.0.2.1
+136r.subtree2. 86400 A 192.0.2.1
+137r.subtree2. 86400 A 192.0.2.1
+138r.subtree2. 86400 A 192.0.2.1
+139r.subtree2. 86400 A 192.0.2.1
+140r.subtree2. 86400 A 192.0.2.1
+141r.subtree2. 86400 A 192.0.2.1
+142r.subtree2. 86400 A 192.0.2.1
+143r.subtree2. 86400 A 192.0.2.1
+144r.subtree2. 86400 A 192.0.2.1
+145r.subtree2. 86400 A 192.0.2.1
+146r.subtree2. 86400 A 192.0.2.1
+147r.subtree2. 86400 A 192.0.2.1
+148r.subtree2. 86400 A 192.0.2.1
+149r.subtree2. 86400 A 192.0.2.1
+150r.subtree2. 86400 A 192.0.2.1
+151r.subtree2. 86400 A 192.0.2.1
+152r.subtree2. 86400 A 192.0.2.1
+153r.subtree2. 86400 A 192.0.2.1
+154r.subtree2. 86400 A 192.0.2.1
+155r.subtree2. 86400 A 192.0.2.1
+156r.subtree2. 86400 A 192.0.2.1
+157r.subtree2. 86400 A 192.0.2.1
+158r.subtree2. 86400 A 192.0.2.1
+159r.subtree2. 86400 A 192.0.2.1
+160r.subtree2. 86400 A 192.0.2.1
+161r.subtree2. 86400 A 192.0.2.1
+162r.subtree2. 86400 A 192.0.2.1
+163r.subtree2. 86400 A 192.0.2.1
+164r.subtree2. 86400 A 192.0.2.1
+165r.subtree2. 86400 A 192.0.2.1
+166r.subtree2. 86400 A 192.0.2.1
+167r.subtree2. 86400 A 192.0.2.1
+168r.subtree2. 86400 A 192.0.2.1
+169r.subtree2. 86400 A 192.0.2.1
+170r.subtree2. 86400 A 192.0.2.1
+171r.subtree2. 86400 A 192.0.2.1
+172r.subtree2. 86400 A 192.0.2.1
+173r.subtree2. 86400 A 192.0.2.1
+174r.subtree2. 86400 A 192.0.2.1
+175r.subtree2. 86400 A 192.0.2.1
+176r.subtree2. 86400 A 192.0.2.1
+177r.subtree2. 86400 A 192.0.2.1
+178r.subtree2. 86400 A 192.0.2.1
+179r.subtree2. 86400 A 192.0.2.1
+180r.subtree2. 86400 A 192.0.2.1
+181r.subtree2. 86400 A 192.0.2.1
+182r.subtree2. 86400 A 192.0.2.1
+183r.subtree2. 86400 A 192.0.2.1
+184r.subtree2. 86400 A 192.0.2.1
+185r.subtree2. 86400 A 192.0.2.1
+186r.subtree2. 86400 A 192.0.2.1
+187r.subtree2. 86400 A 192.0.2.1
+188r.subtree2. 86400 A 192.0.2.1
+189r.subtree2. 86400 A 192.0.2.1
+190r.subtree2. 86400 A 192.0.2.1
+191r.subtree2. 86400 A 192.0.2.1
+192r.subtree2. 86400 A 192.0.2.1
+193r.subtree2. 86400 A 192.0.2.1
+194r.subtree2. 86400 A 192.0.2.1
+195r.subtree2. 86400 A 192.0.2.1
+196r.subtree2. 86400 A 192.0.2.1
+197r.subtree2. 86400 A 192.0.2.1
+198r.subtree2. 86400 A 192.0.2.1
+199r.subtree2. 86400 A 192.0.2.1
+200r.subtree2. 86400 A 192.0.2.1
+201r.subtree2. 86400 A 192.0.2.1
diff --git a/daemon/engine.c b/daemon/engine.c
new file mode 100644
index 0000000..26c225f
--- /dev/null
+++ b/daemon/engine.c
@@ -0,0 +1,892 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#include <contrib/cleanup.h>
+#include <ccan/json/json.h>
+#include <ccan/asprintf/asprintf.h>
+#include <dlfcn.h>
+#include <uv.h>
+#include <unistd.h>
+#include <grp.h>
+#include <pwd.h>
+#include <sys/param.h>
+#include <libzscanner/scanner.h>
+#include <sys/un.h>
+
+#include <lua.h>
+#include <lualib.h>
+#include <lauxlib.h>
+#include "daemon/bindings/impl.h"
+
+#include "kresconfig.h"
+#include "daemon/engine.h"
+#include "daemon/ffimodule.h"
+#include "lib/selection.h"
+#include "lib/cache/api.h"
+#include "lib/defines.h"
+#include "lib/cache/cdb_lmdb.h"
+#include "lib/dnssec/ta.h"
+#include "lib/log.h"
+
+/* Magic defaults for the engine. */
+#ifndef LRU_RTT_SIZE
+#define LRU_RTT_SIZE 65536 /**< NS RTT cache size */
+#endif
+#ifndef LRU_REP_SIZE
+#define LRU_REP_SIZE (LRU_RTT_SIZE / 4) /**< NS reputation cache size */
+#endif
+#ifndef LRU_COOKIES_SIZE
+ #if ENABLE_COOKIES
+ #define LRU_COOKIES_SIZE LRU_RTT_SIZE /**< DNS cookies cache size. */
+ #else
+ #define LRU_COOKIES_SIZE LRU_ASSOC /* simpler than guards everywhere */
+ #endif
+#endif
+
+/**@internal Maximum number of incomplete TCP connections in queue.
+* Default is from empirical testing - in our case, more isn't necessarily better.
+* See https://gitlab.nic.cz/knot/knot-resolver/-/merge_requests/968
+* */
+#ifndef TCP_BACKLOG_DEFAULT
+#define TCP_BACKLOG_DEFAULT 128
+#endif
+
+/* Cleanup engine state every 5 minutes */
+const size_t CLEANUP_TIMER = 5*60*1000;
+
+/* Execute byte code */
+#define l_dobytecode(L, arr, len, name) \
+ (luaL_loadbuffer((L), (arr), (len), (name)) || lua_pcall((L), 0, LUA_MULTRET, 0))
+
+/*
+ * Global bindings.
+ */
+struct args *the_args;
+
+
+/** Print help and available commands. */
+static int l_help(lua_State *L)
+{
+ static const char *help_str =
+ "help()\n show this help\n"
+ "quit()\n quit\n"
+ "hostname()\n hostname\n"
+ "package_version()\n return package version\n"
+ "user(name[, group])\n change process user (and group)\n"
+ "log_level(level)\n logging level (crit, err, warning, notice, info or debug)\n"
+ "log_target(target)\n logging target (syslog, stderr, stdout)\n"
+ "log_groups(groups)\n turn on debug log for selected groups\n"
+ "option(opt[, new_val])\n get/set server option\n"
+ "mode(strict|normal|permissive)\n set resolver strictness level\n"
+ "reorder_RR([true|false])\n set/get reordering of RRs within RRsets\n"
+ "resolve(name, type[, class, flags, callback])\n resolve query, callback when it's finished\n"
+ "todname(name)\n convert name to wire format\n"
+ "tojson(val)\n convert value to JSON\n"
+ "net\n network configuration\n"
+ "cache\n network configuration\n"
+ "modules\n modules configuration\n"
+ "kres\n resolver services\n"
+ "trust_anchors\n configure trust anchors\n"
+ "debugging\n debugging configuration\n"
+ ;
+ lua_pushstring(L, help_str);
+ return 1;
+}
+
+static bool update_privileges(int uid, int gid)
+{
+ if ((gid_t)gid != getgid()) {
+ if (setregid(gid, gid) < 0) {
+ return false;
+ }
+ }
+ if ((uid_t)uid != getuid()) {
+ if (setreuid(uid, uid) < 0) {
+ return false;
+ }
+ }
+ return true;
+}
+
+/** Set process user/group. */
+static int l_setuser(lua_State *L)
+{
+ int n = lua_gettop(L);
+ if (n < 1 || !lua_isstring(L, 1))
+ lua_error_p(L, "user(user[, group])");
+
+ /* Fetch UID/GID based on string identifiers. */
+ struct passwd *user_pw = getpwnam(lua_tostring(L, 1));
+ if (!user_pw)
+ lua_error_p(L, "invalid user name");
+ int uid = user_pw->pw_uid;
+ int gid = getgid();
+ if (n > 1 && lua_isstring(L, 2)) {
+ struct group *group_pw = getgrnam(lua_tostring(L, 2));
+ if (!group_pw)
+ lua_error_p(L, "invalid group name");
+ gid = group_pw->gr_gid;
+ }
+ /* Drop privileges */
+ bool ret = update_privileges(uid, gid);
+ if (!ret) {
+ lua_error_maybe(L, errno);
+ }
+ lua_pushboolean(L, ret);
+ return 1;
+}
+
+/** Quit current executable. */
+static int l_quit(lua_State *L)
+{
+ engine_stop(the_worker->engine);
+ return 0;
+}
+
+/** Toggle verbose mode. */
+static int l_verbose(lua_State *L)
+{
+ kr_log_deprecate(SYSTEM, "use log_level() instead of verbose()\n");
+
+ if (lua_isboolean(L, 1) || lua_isnumber(L, 1)) {
+ kr_log_level_set(lua_toboolean(L, 1) == true ? LOG_DEBUG : LOG_DEFAULT_LEVEL);
+ }
+
+ lua_pushboolean(L, kr_log_level == LOG_DEBUG);
+ return 1;
+}
+
+static int l_log_level(lua_State *L)
+{
+ const int params = lua_gettop(L);
+ if (params > 1) {
+ goto bad_call;
+ } else if (params == 1) { // set
+ const char *lvl_str = lua_tostring(L, 1);
+ if (!lvl_str)
+ goto bad_call;
+ kr_log_level_t lvl = kr_log_name2level(lvl_str);
+ if (lvl < 0)
+ lua_error_p(L, "unknown log level '%s'", lvl_str);
+ kr_log_level_set(lvl);
+ }
+ // get
+ lua_pushstring(L, kr_log_level2name(kr_log_level));
+ return 1;
+bad_call:
+ lua_error_p(L, "takes one string parameter or nothing");
+}
+
+static int l_log_target(lua_State *L)
+{
+ const int params = lua_gettop(L);
+ if (params > 1)
+ goto bad_call;
+ // set
+ if (params == 1) {
+ const char *t_str = lua_tostring(L, 1);
+ if (!t_str)
+ goto bad_call;
+ kr_log_target_t t;
+ if (strcmp(t_str, "syslog") == 0) {
+ t = LOG_TARGET_SYSLOG;
+ } else if (strcmp(t_str, "stdout") == 0) {
+ t = LOG_TARGET_STDOUT;
+ } else if (strcmp(t_str, "stderr") == 0) {
+ t = LOG_TARGET_STDERR;
+ } else {
+ lua_error_p(L, "unknown log target '%s'", t_str);
+ }
+ kr_log_target_set(t);
+ }
+ // get
+ const char *t_str = NULL;
+ switch (kr_log_target) {
+ case LOG_TARGET_SYSLOG: t_str = "syslog"; break;
+ case LOG_TARGET_STDERR: t_str = "stderr"; break;
+ case LOG_TARGET_STDOUT: t_str = "stdout"; break;
+ } // -Wswitch-enum
+ lua_pushstring(L, t_str);
+ return 1;
+bad_call:
+ lua_error_p(L, "takes one string parameter or nothing");
+}
+
+static int l_log_groups(lua_State *L)
+{
+ const int params = lua_gettop(L);
+ if (params > 1)
+ goto bad_call;
+ if (params == 1) { // set
+ if (!lua_istable(L, 1))
+ goto bad_call;
+ kr_log_group_reset();
+
+ int idx = 1;
+ lua_pushnil(L);
+ while (lua_next(L, 1) != 0) {
+ const char *grp_str = lua_tostring(L, -1);
+ if (!grp_str)
+ goto bad_call;
+ enum kr_log_group grp = kr_log_name2grp(grp_str);
+ if (grp < 0)
+ lua_error_p(L, "unknown log group '%s'", lua_tostring(L, -1));
+
+ kr_log_group_add(grp);
+ ++idx;
+ lua_pop(L, 1);
+ }
+ }
+ // get
+ lua_newtable(L);
+ int i = 1;
+ for (enum kr_log_group grp = LOG_GRP_SYSTEM; grp < LOG_GRP_REQDBG; grp++) {
+ const char *name = kr_log_grp2name(grp);
+ if (kr_fails_assert(name))
+ continue;
+ if (kr_log_group_is_set(grp)) {
+ lua_pushinteger(L, i);
+ lua_pushstring(L, name);
+ lua_settable(L, -3);
+ i++;
+ }
+ }
+ return 1;
+bad_call:
+ lua_error_p(L, "takes a table of string groups as parameter or nothing");
+}
+
+char *engine_get_hostname(struct engine *engine) {
+ static char hostname_str[KNOT_DNAME_MAXLEN];
+ if (!engine) {
+ return NULL;
+ }
+
+ if (!engine->hostname) {
+ if (gethostname(hostname_str, sizeof(hostname_str)) != 0)
+ return NULL;
+ return hostname_str;
+ }
+ return engine->hostname;
+}
+
+int engine_set_hostname(struct engine *engine, const char *hostname) {
+ if (!engine || !hostname) {
+ return kr_error(EINVAL);
+ }
+
+ char *new_hostname = strdup(hostname);
+ if (!new_hostname) {
+ return kr_error(ENOMEM);
+ }
+ if (engine->hostname) {
+ free(engine->hostname);
+ }
+ engine->hostname = new_hostname;
+ network_new_hostname(&engine->net, engine);
+
+ return 0;
+}
+
+/** Return hostname. */
+static int l_hostname(lua_State *L)
+{
+ struct engine *engine = the_worker->engine;
+ if (lua_gettop(L) == 0) {
+ lua_pushstring(L, engine_get_hostname(engine));
+ return 1;
+ }
+ if ((lua_gettop(L) != 1) || !lua_isstring(L, 1))
+ lua_error_p(L, "hostname takes at most one parameter: (\"fqdn\")");
+
+ if (engine_set_hostname(engine, lua_tostring(L, 1)) != 0)
+ lua_error_p(L, "setting hostname failed");
+
+ lua_pushstring(L, engine_get_hostname(engine));
+ return 1;
+}
+
+/** Return server package version. */
+static int l_package_version(lua_State *L)
+{
+ lua_pushliteral(L, PACKAGE_VERSION);
+ return 1;
+}
+
+/** Load root hints from zonefile. */
+static int l_hint_root_file(lua_State *L)
+{
+ struct kr_context *ctx = &the_worker->engine->resolver;
+ const char *file = lua_tostring(L, 1);
+
+ const char *err = engine_hint_root_file(ctx, file);
+ if (err) {
+ if (!file) {
+ file = ROOTHINTS;
+ }
+ lua_error_p(L, "error when opening '%s': %s", file, err);
+ } else {
+ lua_pushboolean(L, true);
+ return 1;
+ }
+}
+
+/** @internal for engine_hint_root_file */
+static void roothints_add(zs_scanner_t *zs)
+{
+ struct kr_zonecut *hints = zs->process.data;
+ if (!hints) {
+ return;
+ }
+ if (zs->r_type == KNOT_RRTYPE_A || zs->r_type == KNOT_RRTYPE_AAAA) {
+ kr_zonecut_add(hints, zs->r_owner, zs->r_data, zs->r_data_length);
+ }
+}
+const char* engine_hint_root_file(struct kr_context *ctx, const char *file)
+{
+ if (!file) {
+ file = ROOTHINTS;
+ }
+ if (strlen(file) == 0 || !ctx) {
+ return "invalid parameters";
+ }
+ struct kr_zonecut *root_hints = &ctx->root_hints;
+
+ zs_scanner_t zs;
+ if (zs_init(&zs, ".", 1, 0) != 0) {
+ return "not enough memory";
+ }
+ if (zs_set_input_file(&zs, file) != 0) {
+ zs_deinit(&zs);
+ return "failed to open root hints file";
+ }
+
+ kr_zonecut_set(root_hints, (const uint8_t *)"");
+ zs_set_processing(&zs, roothints_add, NULL, root_hints);
+ zs_parse_all(&zs);
+ zs_deinit(&zs);
+ return NULL;
+}
+
+/** Unpack JSON object to table */
+static void l_unpack_json(lua_State *L, JsonNode *table)
+{
+ /* Unpack POD */
+ switch(table->tag) {
+ case JSON_STRING: lua_pushstring(L, table->string_); return;
+ case JSON_NUMBER: lua_pushnumber(L, table->number_); return;
+ case JSON_BOOL: lua_pushboolean(L, table->bool_); return;
+ default: break;
+ }
+ /* Unpack object or array into table */
+ lua_newtable(L);
+ JsonNode *node = NULL;
+ json_foreach(node, table) {
+ /* Push node value */
+ switch(node->tag) {
+ case JSON_OBJECT: /* as array */
+ case JSON_ARRAY: l_unpack_json(L, node); break;
+ case JSON_STRING: lua_pushstring(L, node->string_); break;
+ case JSON_NUMBER: lua_pushnumber(L, node->number_); break;
+ case JSON_BOOL: lua_pushboolean(L, node->bool_); break;
+ default: continue;
+ }
+ /* Set table key */
+ if (node->key) {
+ lua_setfield(L, -2, node->key);
+ } else {
+ lua_rawseti(L, -2, lua_objlen(L, -2) + 1);
+ }
+ }
+}
+
+/** @internal Recursive Lua/JSON serialization. */
+static JsonNode *l_pack_elem(lua_State *L, int top)
+{
+ switch(lua_type(L, top)) {
+ case LUA_TSTRING: return json_mkstring(lua_tostring(L, top));
+ case LUA_TNUMBER: return json_mknumber(lua_tonumber(L, top));
+ case LUA_TBOOLEAN: return json_mkbool(lua_toboolean(L, top));
+ case LUA_TTABLE: break; /* Table, iterate it. */
+ default: return json_mknull();
+ }
+ /* Use absolute indexes here, as the table may be nested. */
+ JsonNode *node = NULL;
+ lua_pushnil(L);
+ while(lua_next(L, top) != 0) {
+ bool is_array = false;
+ if (!node) {
+ is_array = (lua_type(L, top + 1) == LUA_TNUMBER);
+ node = is_array ? json_mkarray() : json_mkobject();
+ if (!node) {
+ return NULL;
+ }
+ } else {
+ is_array = node->tag == JSON_ARRAY;
+ }
+
+ /* Insert to array/table. */
+ JsonNode *val = l_pack_elem(L, top + 2);
+ if (is_array) {
+ json_append_element(node, val);
+ } else {
+ const char *key = lua_tostring(L, top + 1);
+ json_append_member(node, key, val);
+ }
+ lua_pop(L, 1);
+ }
+ /* Return empty object for empty tables. */
+ return node ? node : json_mkobject();
+}
+
+/** @internal Serialize to string */
+static char *l_pack_json(lua_State *L, int top)
+{
+ JsonNode *root = l_pack_elem(L, top);
+ if (!root) {
+ return NULL;
+ }
+ char *result = json_encode(root);
+ json_delete(root);
+ return result;
+}
+
+static int l_tojson(lua_State *L)
+{
+ auto_free char *json_str = l_pack_json(L, lua_gettop(L));
+ if (!json_str) {
+ return 0;
+ }
+ lua_pushstring(L, json_str);
+ return 1;
+}
+
+static int l_fromjson(lua_State *L)
+{
+ if (lua_gettop(L) != 1 || !lua_isstring(L, 1))
+ lua_error_p(L, "a JSON string is required");
+
+ const char *json_str = lua_tostring(L, 1);
+ JsonNode *root_node = json_decode(json_str);
+
+ if (!root_node)
+ lua_error_p(L, "invalid JSON string");
+ l_unpack_json(L, root_node);
+ json_delete(root_node);
+
+ return 1;
+}
+
+/*
+ * Engine API.
+ */
+
+static int init_resolver(struct engine *engine)
+{
+ /* Note: whole *engine had been zeroed by engine_init(). */
+ struct kr_context * const ctx = &engine->resolver;
+ /* Default options (request flags). */
+ ctx->options.REORDER_RR = true;
+
+ /* Open resolution context */
+ ctx->trust_anchors = trie_create(NULL);
+ ctx->negative_anchors = trie_create(NULL);
+ ctx->pool = engine->pool;
+ ctx->modules = &engine->modules;
+ ctx->cache_rtt_tout_retry_interval = KR_NS_TIMEOUT_RETRY_INTERVAL;
+ /* Create OPT RR */
+ ctx->downstream_opt_rr = mm_alloc(engine->pool, sizeof(knot_rrset_t));
+ ctx->upstream_opt_rr = mm_alloc(engine->pool, sizeof(knot_rrset_t));
+ if (!ctx->downstream_opt_rr || !ctx->upstream_opt_rr) {
+ return kr_error(ENOMEM);
+ }
+ knot_edns_init(ctx->downstream_opt_rr, KR_EDNS_PAYLOAD, 0, KR_EDNS_VERSION, engine->pool);
+ knot_edns_init(ctx->upstream_opt_rr, KR_EDNS_PAYLOAD, 0, KR_EDNS_VERSION, engine->pool);
+ /* Use default TLS padding */
+ ctx->tls_padding = -1;
+ /* Empty init; filled via ./lua/postconfig.lua */
+ kr_zonecut_init(&ctx->root_hints, (const uint8_t *)"", engine->pool);
+ lru_create(&ctx->cache_cookie, LRU_COOKIES_SIZE, NULL, NULL);
+
+ /* Load basic modules */
+ engine_register(engine, "iterate", NULL, NULL);
+ engine_register(engine, "validate", NULL, NULL);
+ engine_register(engine, "cache", NULL, NULL);
+
+ return array_push(engine->backends, kr_cdb_lmdb());
+}
+
+static int init_state(struct engine *engine)
+{
+ /* Initialize Lua state */
+ engine->L = luaL_newstate();
+ if (engine->L == NULL) {
+ return kr_error(ENOMEM);
+ }
+ /* Initialize used libraries. */
+ luaL_openlibs(engine->L);
+ /* Global functions */
+ lua_pushcfunction(engine->L, l_help);
+ lua_setglobal(engine->L, "help");
+ lua_pushcfunction(engine->L, l_quit);
+ lua_setglobal(engine->L, "quit");
+ lua_pushcfunction(engine->L, l_hostname);
+ lua_setglobal(engine->L, "hostname");
+ lua_pushcfunction(engine->L, l_package_version);
+ lua_setglobal(engine->L, "package_version");
+ lua_pushcfunction(engine->L, l_verbose);
+ lua_setglobal(engine->L, "verbose");
+ lua_pushcfunction(engine->L, l_log_level);
+ lua_setglobal(engine->L, "log_level");
+ lua_pushcfunction(engine->L, l_log_target);
+ lua_setglobal(engine->L, "log_target");
+ lua_pushcfunction(engine->L, l_log_groups);
+ lua_setglobal(engine->L, "log_groups");
+ lua_pushcfunction(engine->L, l_setuser);
+ lua_setglobal(engine->L, "user");
+ lua_pushcfunction(engine->L, l_hint_root_file);
+ lua_setglobal(engine->L, "_hint_root_file");
+ lua_pushliteral(engine->L, libknot_SONAME);
+ lua_setglobal(engine->L, "libknot_SONAME");
+ lua_pushliteral(engine->L, libzscanner_SONAME);
+ lua_setglobal(engine->L, "libzscanner_SONAME");
+ lua_pushcfunction(engine->L, l_tojson);
+ lua_setglobal(engine->L, "tojson");
+ lua_pushcfunction(engine->L, l_fromjson);
+ lua_setglobal(engine->L, "fromjson");
+ /* Random number generator */
+ lua_getfield(engine->L, LUA_GLOBALSINDEX, "math");
+ lua_getfield(engine->L, -1, "randomseed");
+ lua_remove(engine->L, -2);
+ lua_Number seed = kr_rand_bytes(sizeof(lua_Number));
+ lua_pushnumber(engine->L, seed);
+ lua_call(engine->L, 1, 0);
+ return kr_ok();
+}
+
+/**
+ * Start luacov measurement and store results to file specified by
+ * KRESD_COVERAGE_STATS environment variable.
+ * Do nothing if the variable is not set.
+ */
+static void init_measurement(struct engine *engine)
+{
+ const char * const statspath = getenv("KRESD_COVERAGE_STATS");
+ if (!statspath)
+ return;
+
+ char * snippet = NULL;
+ int ret = asprintf(&snippet,
+ "_luacov_runner = require('luacov.runner')\n"
+ "_luacov_runner.init({\n"
+ " statsfile = '%s',\n"
+ " exclude = {'test', 'tapered', 'lua/5.1'},\n"
+ "})\n"
+ "jit.off()\n", statspath
+ );
+ if (kr_fails_assert(ret > 0))
+ return;
+
+ ret = luaL_loadstring(engine->L, snippet);
+ if (kr_fails_assert(ret == 0)) {
+ free(snippet);
+ return;
+ }
+ lua_call(engine->L, 0, 0);
+ free(snippet);
+}
+
+int init_lua(struct engine *engine) {
+ if (!engine) {
+ return kr_error(EINVAL);
+ }
+
+ /* Use libdir path for including Lua scripts */
+ char l_paths[MAXPATHLEN] = { 0 };
+ #pragma GCC diagnostic push
+ #pragma GCC diagnostic ignored "-Wformat" /* %1$ is not in C standard */
+ /* Save original package.path to package._path */
+ snprintf(l_paths, MAXPATHLEN - 1,
+ "if package._path == nil then package._path = package.path end\n"
+ "package.path = '%1$s/?.lua;%1$s/?/init.lua;'..package._path\n"
+ "if package._cpath == nil then package._cpath = package.cpath end\n"
+ "package.cpath = '%1$s/?%2$s;'..package._cpath\n",
+ LIBDIR, LIBEXT);
+ #pragma GCC diagnostic pop
+
+ int ret = l_dobytecode(engine->L, l_paths, strlen(l_paths), "");
+ if (ret != 0) {
+ lua_pop(engine->L, 1);
+ return ret;
+ }
+ return 0;
+}
+
+
+int engine_init(struct engine *engine, knot_mm_t *pool)
+{
+ if (engine == NULL) {
+ return kr_error(EINVAL);
+ }
+
+ memset(engine, 0, sizeof(*engine));
+ engine->pool = pool;
+
+ /* Initialize state */
+ int ret = init_state(engine);
+ if (ret != 0) {
+ engine_deinit(engine);
+ return ret;
+ }
+ init_measurement(engine);
+ /* Initialize resolver */
+ ret = init_resolver(engine);
+ if (ret != 0) {
+ engine_deinit(engine);
+ return ret;
+ }
+ /* Initialize network */
+ network_init(&engine->net, uv_default_loop(), TCP_BACKLOG_DEFAULT);
+
+ /* Initialize lua */
+ ret = init_lua(engine);
+ if (ret != 0) {
+ engine_deinit(engine);
+ return ret;
+ }
+
+ return ret;
+}
+
+/** Unregister a (found) module */
+static void engine_unload(struct engine *engine, struct kr_module *module)
+{
+ auto_free char *name = module->name ? strdup(module->name) : NULL;
+ kr_module_unload(module); /* beware: lua/C mix, could be confusing */
+ /* Clear in Lua world, but not for embedded modules ('cache' in particular). */
+ if (name && !kr_module_get_embedded(name)) {
+ lua_pushnil(engine->L);
+ lua_setglobal(engine->L, name);
+ }
+ free(module);
+}
+
+void engine_deinit(struct engine *engine)
+{
+ if (!engine || kr_fails_assert(engine->L))
+ return;
+ /* Only close sockets and services; no need to clean up mempool. */
+
+ /* Network deinit is split up. We first need to stop listening,
+ * then we can unload modules during which we still want
+ * e.g. the endpoint kind registry to work (inside ->net),
+ * and this registry deinitialization uses the lua state. */
+ network_close_force(&engine->net);
+ for (size_t i = 0; i < engine->modules.len; ++i) {
+ engine_unload(engine, engine->modules.at[i]);
+ }
+ kr_zonecut_deinit(&engine->resolver.root_hints);
+ kr_cache_close(&engine->resolver.cache);
+
+ /* The LRUs are currently malloc-ated and need to be freed. */
+ lru_free(engine->resolver.cache_cookie);
+
+ network_deinit(&engine->net);
+ ffimodule_deinit(engine->L);
+ lua_close(engine->L);
+
+ /* Free data structures */
+ array_clear(engine->modules);
+ array_clear(engine->backends);
+ kr_ta_clear(engine->resolver.trust_anchors);
+ trie_free(engine->resolver.trust_anchors);
+ kr_ta_clear(engine->resolver.negative_anchors);
+ trie_free(engine->resolver.negative_anchors);
+ free(engine->hostname);
+}
+
+int engine_pcall(lua_State *L, int argc)
+{
+ return lua_pcall(L, argc, LUA_MULTRET, 0);
+}
+
+int engine_cmd(lua_State *L, const char *str, bool raw)
+{
+ if (L == NULL) {
+ return kr_error(ENOEXEC);
+ }
+
+ /* Evaluate results */
+ lua_getglobal(L, "eval_cmd");
+ lua_pushstring(L, str);
+ lua_pushboolean(L, raw);
+
+ /* Check result. */
+ return engine_pcall(L, 2);
+}
+
+int engine_load_sandbox(struct engine *engine)
+{
+ /* Init environment */
+ int ret = luaL_dofile(engine->L, LIBDIR "/sandbox.lua");
+ if (ret != 0) {
+ kr_log_error(SYSTEM, "error %s\n", lua_tostring(engine->L, -1));
+ lua_pop(engine->L, 1);
+ return kr_error(ENOEXEC);
+ }
+ ret = ffimodule_init(engine->L);
+ return ret;
+}
+
+int engine_loadconf(struct engine *engine, const char *config_path)
+{
+ if (kr_fails_assert(config_path))
+ return kr_error(EINVAL);
+
+ char cwd[PATH_MAX];
+ get_workdir(cwd, sizeof(cwd));
+ kr_log_debug(SYSTEM, "loading config '%s' (workdir '%s')\n", config_path, cwd);
+
+ int ret = luaL_dofile(engine->L, config_path);
+ if (ret != 0) {
+ kr_log_error(SYSTEM, "error while loading config: "
+ "%s (workdir '%s')\n", lua_tostring(engine->L, -1), cwd);
+ lua_pop(engine->L, 1);
+ }
+ return ret;
+}
+
+int engine_start(struct engine *engine)
+{
+ /* Clean up stack */
+ lua_settop(engine->L, 0);
+
+ return kr_ok();
+}
+
+void engine_stop(struct engine *engine)
+{
+ if (!engine) {
+ return;
+ }
+ uv_stop(uv_default_loop());
+}
+
+/** @internal Find matching module */
+static size_t module_find(module_array_t *mod_list, const char *name)
+{
+ size_t found = mod_list->len;
+ for (size_t i = 0; i < mod_list->len; ++i) {
+ struct kr_module *mod = mod_list->at[i];
+ if (strcmp(mod->name, name) == 0) {
+ found = i;
+ break;
+ }
+ }
+ return found;
+}
+
+int engine_register(struct engine *engine, const char *name, const char *precedence, const char* ref)
+{
+ if (kr_fails_assert(engine && name))
+ return kr_error(EINVAL);
+ /* Make sure module is unloaded */
+ (void) engine_unregister(engine, name);
+ /* Find the index of referenced module. */
+ module_array_t *mod_list = &engine->modules;
+ size_t ref_pos = mod_list->len;
+ if (precedence && ref) {
+ ref_pos = module_find(mod_list, ref);
+ if (ref_pos >= mod_list->len) {
+ return kr_error(EIDRM);
+ }
+ }
+ /* Attempt to load binary module */
+ struct kr_module *module = malloc(sizeof(*module));
+ if (!module) {
+ return kr_error(ENOMEM);
+ }
+ module->data = engine; /*< some outside modules may still use this value */
+
+ int ret = kr_module_load(module, name, LIBDIR "/kres_modules");
+ if (ret == 0) {
+ /* We have a C module, loaded and init() was called.
+ * Now we need to prepare the lua side. */
+ lua_State *L = engine->L;
+ lua_getglobal(L, "modules_create_table_for_c");
+ lua_pushpointer(L, module);
+ if (lua_isnil(L, -2)) {
+ /* When loading the three embedded modules, we don't
+ * have the "modules_*" lua function yet, but fortunately
+ * we don't need it there. Let's just check they're embedded.
+ * TODO: solve this better *without* breaking stuff. */
+ lua_pop(L, 2);
+ if (module->lib != RTLD_DEFAULT) {
+ ret = kr_error(1);
+ lua_pushliteral(L, "missing modules_create_table_for_c()");
+ }
+ } else {
+ ret = engine_pcall(L, 1);
+ }
+ if (kr_fails_assert(ret == 0)) { /* probably not critical, but weird */
+ kr_log_error(SYSTEM, "internal error when loading C module %s: %s\n",
+ module->name, lua_tostring(L, -1));
+ lua_pop(L, 1);
+ }
+
+ } else if (ret == kr_error(ENOENT)) {
+ /* No luck with C module, so try to load and .init() lua module. */
+ ret = ffimodule_register_lua(engine, module, name);
+ if (ret != 0) {
+ kr_log_error(SYSTEM, "failed to load module '%s'\n", name);
+ }
+
+ } else if (ret == kr_error(ENOTSUP)) {
+ /* Print a more helpful message when module is linked against an old resolver ABI. */
+ kr_log_error(SYSTEM, "module '%s' links to unsupported ABI, please rebuild it\n", name);
+ }
+
+ if (ret != 0) {
+ engine_unload(engine, module);
+ return ret;
+ }
+
+ /* Push to the right place in engine->modules */
+ if (array_push(engine->modules, module) < 0) {
+ engine_unload(engine, module);
+ return kr_error(ENOMEM);
+ }
+ if (precedence) {
+ struct kr_module **arr = mod_list->at;
+ size_t emplacement = mod_list->len;
+ if (strcasecmp(precedence, ">") == 0) {
+ if (ref_pos + 1 < mod_list->len)
+ emplacement = ref_pos + 1; /* Insert after target */
+ }
+ if (strcasecmp(precedence, "<") == 0) {
+ emplacement = ref_pos; /* Insert at target */
+ }
+ /* Move the tail if it has some elements. */
+ if (emplacement + 1 < mod_list->len) {
+ memmove(&arr[emplacement + 1], &arr[emplacement], sizeof(*arr) * (mod_list->len - (emplacement + 1)));
+ arr[emplacement] = module;
+ }
+ }
+
+ return kr_ok();
+}
+
+int engine_unregister(struct engine *engine, const char *name)
+{
+ module_array_t *mod_list = &engine->modules;
+ size_t found = module_find(mod_list, name);
+ if (found < mod_list->len) {
+ engine_unload(engine, mod_list->at[found]);
+ array_del(*mod_list, found);
+ return kr_ok();
+ }
+
+ return kr_error(ENOENT);
+}
+
diff --git a/daemon/engine.h b/daemon/engine.h
new file mode 100644
index 0000000..63accd3
--- /dev/null
+++ b/daemon/engine.h
@@ -0,0 +1,84 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+/*
+ * @internal These are forward decls to allow building modules with engine but without Lua.
+ */
+struct lua_State;
+
+#include "lib/utils.h"
+#include "lib/resolve.h"
+#include "daemon/network.h"
+
+struct engine {
+ struct kr_context resolver;
+ struct network net;
+ module_array_t modules;
+ array_t(const struct kr_cdb_api *) backends;
+ knot_mm_t *pool;
+ char *hostname;
+ struct lua_State *L;
+};
+
+int engine_init(struct engine *engine, knot_mm_t *pool);
+void engine_deinit(struct engine *engine);
+
+/** Perform a lua command within the sandbox.
+ *
+ * @return zero on success.
+ * The result will be returned on the lua stack - an error message in case of failure.
+ * http://www.lua.org/manual/5.1/manual.html#lua_pcall */
+int engine_cmd(struct lua_State *L, const char *str, bool raw);
+
+/** Execute current chunk in the sandbox */
+int engine_pcall(struct lua_State *L, int argc);
+
+int engine_load_sandbox(struct engine *engine);
+int engine_loadconf(struct engine *engine, const char *config_path);
+
+/** Start the lua engine and execute the config. */
+int engine_start(struct engine *engine);
+void engine_stop(struct engine *engine);
+int engine_register(struct engine *engine, const char *name, const char *precedence, const char* ref);
+int engine_unregister(struct engine *engine, const char *name);
+
+/** Set/get the per engine hostname */
+char *engine_get_hostname(struct engine *engine);
+int engine_set_hostname(struct engine *engine, const char *hostname);
+
+/** Load root hints from a zonefile (or config-time default if NULL).
+ *
+ * @return error message or NULL (statically allocated)
+ * @note exported to be usable from the hints module.
+ */
+KR_EXPORT
+const char* engine_hint_root_file(struct kr_context *ctx, const char *file);
+
+/* @internal Array of ip address shorthand. */
+typedef array_t(char*) addr_array_t;
+
+typedef array_t(const char*) config_array_t;
+
+typedef struct {
+ int fd;
+ endpoint_flags_t flags; /**< .sock_type isn't meaningful here */
+} flagged_fd_t;
+typedef array_t(flagged_fd_t) flagged_fd_array_t;
+
+struct args {
+ addr_array_t addrs, addrs_tls;
+ flagged_fd_array_t fds;
+ int control_fd;
+ int forks;
+ config_array_t config;
+ const char *rundir;
+ bool interactive;
+ bool quiet;
+ bool tty_binary_output;
+};
+
+/** Pointer to kresd arguments. */
+KR_EXPORT extern struct args *the_args;
diff --git a/daemon/ffimodule.c b/daemon/ffimodule.c
new file mode 100644
index 0000000..4206b4c
--- /dev/null
+++ b/daemon/ffimodule.c
@@ -0,0 +1,304 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#include <uv.h>
+#include <lua.h>
+#include <lauxlib.h>
+
+#include "daemon/bindings/impl.h"
+#include "daemon/engine.h"
+#include "daemon/ffimodule.h"
+#include "daemon/worker.h"
+#include "lib/module.h"
+#include "lib/layer.h"
+
+/** @internal Slots for layer callbacks.
+ * Each slot ID corresponds to Lua reference in module API. */
+enum {
+ SLOT_begin = 0,
+ SLOT_reset,
+ SLOT_finish,
+ SLOT_consume,
+ SLOT_produce,
+ SLOT_checkout,
+ SLOT_answer_finalize,
+ SLOT_count /* dummy, must be the last */
+};
+
+/** Lua registry indices for functions that wrap layer callbacks (shared by all lua modules). */
+static int l_ffi_wrap_slots[SLOT_count] = { 0 };
+
+/** @internal Continue with coroutine. */
+static void l_ffi_resume_cb(uv_idle_t *check)
+{
+ lua_State *L = check->data;
+ int status = lua_resume(L, 0);
+ if (status != LUA_YIELD) {
+ uv_idle_stop(check); /* Stop coroutine */
+ uv_close((uv_handle_t *)check, (uv_close_cb)free);
+ }
+ lua_pop(L, lua_gettop(L));
+}
+
+/** @internal Schedule deferred continuation. */
+static int l_ffi_defer(lua_State *L)
+{
+ uv_idle_t *check = malloc(sizeof(*check));
+ if (!check) {
+ return kr_error(ENOMEM);
+ }
+ uv_idle_init(uv_default_loop(), check);
+ check->data = L;
+ return uv_idle_start(check, l_ffi_resume_cb);
+}
+
+/** Common part of calling modname.(de)init in lua.
+ * The function to call should be on top of the stack and it gets popped. */
+static int l_ffi_modcb(lua_State *L, struct kr_module *module)
+{
+ if (lua_isnil(L, -1)) {
+ lua_pop(L, 1); /* .(de)init == nil, maybe even the module table doesn't exist */
+ return kr_ok();
+ }
+ lua_getglobal(L, "modules_ffi_wrap_modcb");
+ lua_insert(L, -2); /* swap with .(de)init */
+ lua_pushpointer(L, module);
+ if (lua_pcall(L, 2, 0, 0) == 0)
+ return kr_ok();
+ kr_log_error(SYSTEM, "error: %s\n", lua_tostring(L, -1));
+ lua_pop(L, 1);
+ return kr_error(1);
+}
+
+static int l_ffi_deinit(struct kr_module *module)
+{
+ /* Call .deinit(), if it exists. */
+ lua_State *L = the_worker->engine->L;
+ lua_getglobal(L, module->name);
+ lua_getfield(L, -1, "deinit");
+ const int ret = l_ffi_modcb(L, module);
+ lua_pop(L, 1); /* the module's table */
+
+ const kr_layer_api_t *api = module->layer;
+ if (!api) {
+ return ret;
+ }
+ /* Unregister layer callback references from registry. */
+ for (int si = 0; si < SLOT_count; ++si) {
+ if (api->cb_slots[si] > 0) {
+ luaL_unref(L, LUA_REGISTRYINDEX, api->cb_slots[si]);
+ }
+ }
+ free_const(api);
+ return ret;
+}
+
+kr_layer_t kr_layer_t_static;
+
+/** @internal Helper for calling a layer Lua function by e.g. SLOT_begin. */
+static int l_ffi_call_layer(kr_layer_t *ctx, int slot_ix)
+{
+ const int wrap_slot = l_ffi_wrap_slots[slot_ix];
+ const int cb_slot = ctx->api->cb_slots[slot_ix];
+ kr_require(wrap_slot > 0 && cb_slot > 0);
+ lua_State *L = the_worker->engine->L;
+ lua_rawgeti(L, LUA_REGISTRYINDEX, wrap_slot);
+ lua_rawgeti(L, LUA_REGISTRYINDEX, cb_slot);
+ /* We pass the content of *ctx via a global structure to avoid
+ * lua (full) userdata, as that's relatively expensive (GC-allocated).
+ * Performance: copying isn't ideal, but it's not visible in profiles. */
+ memcpy(&kr_layer_t_static, ctx, sizeof(*ctx));
+
+ int ret = lua_pcall(L, 1, 1, 0);
+ /* Handle result of the pcall.
+ * Default state: ctx->req->state seems safer than ctx->state,
+ * in case the pcall touched req->state. */
+ int state = ctx->req->state;
+ if (ret) { /* Exception or another lua problem. */
+ state = KR_STATE_FAIL;
+ kr_log_error(SYSTEM, "error: %s\n", lua_tostring(L, -1));
+
+ } else if (lua_isnumber(L, -1)) { /* Explicitly returned state. */
+ state = lua_tointeger(L, -1);
+ if (!kr_state_consistent(state)) {
+ kr_log_error(SYSTEM, "error: nonsense state returned from lua module layer: %d\n",
+ state);
+ state = KR_STATE_FAIL;
+ }
+
+ } else if (lua_isnil(L, -1)) { /* Don't change state. */
+
+ } else if (kr_fails_assert(!lua_isthread(L, -1))) { /* Continuations */
+ /* TODO: unused, possibly in a bad shape. Meant KR_STATE_YIELD? */
+ if (l_ffi_defer(lua_tothread(L, -1)) != 0)
+ state = KR_STATE_FAIL;
+
+ } else { /* Nonsense returned. */
+ state = KR_STATE_FAIL;
+ kr_log_error(SYSTEM, "error: nonsense returned from lua module layer: %s\n",
+ lua_tostring(L, -1));
+ /* Unfortunately we can't easily get name of the module/function here. */
+ }
+ lua_pop(L, 1);
+ return state;
+}
+
+static int l_ffi_layer_begin(kr_layer_t *ctx)
+{
+ return l_ffi_call_layer(ctx, SLOT_begin);
+}
+
+static int l_ffi_layer_reset(kr_layer_t *ctx)
+{
+ return l_ffi_call_layer(ctx, SLOT_reset);
+}
+
+static int l_ffi_layer_finish(kr_layer_t *ctx)
+{
+ ctx->pkt = ctx->req->answer;
+ return l_ffi_call_layer(ctx, SLOT_finish);
+}
+
+static int l_ffi_layer_consume(kr_layer_t *ctx, knot_pkt_t *pkt)
+{
+ if (ctx->state & KR_STATE_FAIL) {
+ return ctx->state; /* Already failed, skip */
+ }
+ ctx->pkt = pkt;
+ return l_ffi_call_layer(ctx, SLOT_consume);
+}
+
+static int l_ffi_layer_produce(kr_layer_t *ctx, knot_pkt_t *pkt)
+{
+ if (ctx->state & KR_STATE_FAIL) {
+ return ctx->state; /* Already failed, skip */
+ }
+ ctx->pkt = pkt;
+ return l_ffi_call_layer(ctx, SLOT_produce);
+}
+
+static int l_ffi_layer_checkout(kr_layer_t *ctx, knot_pkt_t *pkt,
+ struct sockaddr *dst, int type)
+{
+ if (ctx->state & KR_STATE_FAIL) {
+ return ctx->state; /* Already failed, skip */
+ }
+ ctx->pkt = pkt;
+ ctx->dst = dst;
+ ctx->is_stream = (type == SOCK_STREAM);
+ return l_ffi_call_layer(ctx, SLOT_checkout);
+}
+
+static int l_ffi_layer_answer_finalize(kr_layer_t *ctx)
+{
+ return l_ffi_call_layer(ctx, SLOT_answer_finalize);
+}
+
+int ffimodule_init(lua_State *L)
+{
+ /* Wrappers defined in ./lua/sandbox.lua */
+ /* for API: (int state, kr_request_t *req) */
+ lua_getglobal(L, "modules_ffi_layer_wrap1");
+ const int wrap1 = luaL_ref(L, LUA_REGISTRYINDEX);
+ /* for API: (int state, kr_request_t *req, knot_pkt_t *) */
+ lua_getglobal(L, "modules_ffi_layer_wrap2");
+ const int wrap2 = luaL_ref(L, LUA_REGISTRYINDEX);
+ lua_getglobal(L, "modules_ffi_layer_wrap_checkout");
+ const int wrap_checkout = luaL_ref(L, LUA_REGISTRYINDEX);
+ if (wrap1 == LUA_REFNIL || wrap2 == LUA_REFNIL || wrap_checkout == LUA_REFNIL) {
+ return kr_error(ENOENT);
+ }
+
+ const int slots[SLOT_count] = {
+ [SLOT_begin] = wrap1,
+ [SLOT_reset] = wrap1,
+ [SLOT_finish] = wrap2,
+ [SLOT_consume] = wrap2,
+ [SLOT_produce] = wrap2,
+ [SLOT_checkout] = wrap_checkout,
+ [SLOT_answer_finalize] = wrap1,
+ };
+ memcpy(l_ffi_wrap_slots, slots, sizeof(l_ffi_wrap_slots));
+ return kr_ok();
+}
+void ffimodule_deinit(lua_State *L)
+{
+ /* Unref each wrapper function from lua.
+ * It's probably useless, as we're about to destroy lua_State, but... */
+ const int wrapsIndices[] = {
+ SLOT_begin,
+ SLOT_consume,
+ SLOT_checkout,
+ };
+ for (int i = 0; i < sizeof(wrapsIndices) / sizeof(wrapsIndices[0]); ++i) {
+ luaL_unref(L, LUA_REGISTRYINDEX, l_ffi_wrap_slots[wrapsIndices[i]]);
+ }
+}
+
+/** @internal Conditionally register layer trampoline
+ * @warning Expects 'module.layer' to be on top of Lua stack. */
+#define LAYER_REGISTER(L, api, name) do { \
+ int *cb_slot = (api)->cb_slots + SLOT_ ## name; \
+ lua_getfield((L), -1, #name); \
+ if (!lua_isnil((L), -1)) { \
+ (api)->name = l_ffi_layer_ ## name; \
+ *cb_slot = luaL_ref((L), LUA_REGISTRYINDEX); \
+ } else { \
+ lua_pop((L), 1); \
+ } \
+} while(0)
+
+/** @internal Create C layer api wrapper. */
+static kr_layer_api_t *l_ffi_layer_create(lua_State *L, struct kr_module *module)
+{
+ /* Fabricate layer API wrapping the Lua functions
+ * reserve slots after it for references to Lua callbacks. */
+ const size_t api_length = offsetof(kr_layer_api_t, cb_slots)
+ + (SLOT_count * sizeof(module->layer->cb_slots[0]));
+ kr_layer_api_t *api = calloc(1, api_length);
+ if (api) {
+ LAYER_REGISTER(L, api, begin);
+ LAYER_REGISTER(L, api, finish);
+ LAYER_REGISTER(L, api, consume);
+ LAYER_REGISTER(L, api, produce);
+ LAYER_REGISTER(L, api, checkout);
+ LAYER_REGISTER(L, api, answer_finalize);
+ LAYER_REGISTER(L, api, reset);
+ }
+ return api;
+}
+
+#undef LAYER_REGISTER
+
+int ffimodule_register_lua(struct engine *engine, struct kr_module *module, const char *name)
+{
+ /* Register module in Lua */
+ lua_State *L = engine->L;
+ lua_getglobal(L, "require");
+ lua_pushfstring(L, "kres_modules.%s", name);
+ if (lua_pcall(L, 1, LUA_MULTRET, 0) != 0) {
+ kr_log_error(SYSTEM, "error: %s\n", lua_tostring(L, -1));
+ lua_pop(L, 1);
+ return kr_error(ENOENT);
+ }
+ lua_setglobal(L, name);
+ lua_getglobal(L, name);
+
+ /* Create FFI module with trampolined functions. */
+ memset(module, 0, sizeof(*module));
+ module->name = strdup(name);
+ module->deinit = &l_ffi_deinit;
+ /* Bake layer API if defined in module */
+ lua_getfield(L, -1, "layer");
+ if (!lua_isnil(L, -1)) {
+ module->layer = l_ffi_layer_create(L, module);
+ }
+ lua_pop(L, 1); /* .layer table */
+
+ /* Now call .init(), if it exists. */
+ lua_getfield(L, -1, "init");
+ const int ret = l_ffi_modcb(L, module);
+ lua_pop(L, 1); /* the module's table */
+ return ret;
+}
diff --git a/daemon/ffimodule.h b/daemon/ffimodule.h
new file mode 100644
index 0000000..beb1bf1
--- /dev/null
+++ b/daemon/ffimodule.h
@@ -0,0 +1,36 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#include "lib/defines.h"
+#include "lib/layer.h"
+#include <lua.h>
+struct engine;
+struct kr_module;
+
+/**
+ * Register Lua module as a FFI module.
+ * This fabricates a standard module interface,
+ * that trampolines to the Lua module methods.
+ *
+ * @note Lua module is loaded in it's own coroutine,
+ * so it's possible to yield and resume at arbitrary
+ * places except deinit()
+ *
+ * @param engine daemon engine
+ * @param module prepared module
+ * @param name module name
+ * @return 0 or an error
+ */
+int ffimodule_register_lua(struct engine *engine, struct kr_module *module, const char *name);
+
+int ffimodule_init(lua_State *L);
+void ffimodule_deinit(lua_State *L);
+
+/** Static storage for faster passing of layer function parameters to lua callbacks.
+ *
+ * We don't need to declare it in a header, but let's give it visibility. */
+KR_EXPORT extern kr_layer_t kr_layer_t_static;
+
diff --git a/daemon/http.c b/daemon/http.c
new file mode 100644
index 0000000..0c6f361
--- /dev/null
+++ b/daemon/http.c
@@ -0,0 +1,953 @@
+/*
+ * Copyright (C) CZ.NIC, z.s.p.o
+ *
+ * Initial Author: Jan Hák <jan.hak@nic.cz>
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#include <errno.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "daemon/io.h"
+#include "daemon/http.h"
+#include "daemon/worker.h"
+#include "daemon/session.h"
+#include "lib/layer/iterate.h" /* kr_response_classify */
+#include "lib/cache/util.h"
+#include "lib/generic/array.h"
+
+#include "contrib/cleanup.h"
+#include "contrib/base64url.h"
+
+/** Makes a `nghttp2_nv`. `K` is the key, `KS` is the key length,
+ * `V` is the value, `VS` is the value length. */
+#define MAKE_NV(K, KS, V, VS) \
+ (nghttp2_nv) { (uint8_t *)(K), (uint8_t *)(V), (KS), (VS), NGHTTP2_NV_FLAG_NONE }
+
+/** Makes a `nghttp2_nv` with static data. `K` is the key,
+ * `V` is the value. Both `K` and `V` MUST be string literals. */
+#define MAKE_STATIC_NV(K, V) \
+ MAKE_NV((K), sizeof(K) - 1, (V), sizeof(V) - 1)
+
+/** Makes a `nghttp2_nv` with a static key. `K` is the key,
+ * `V` is the value, `VS` is the value length. `K` MUST be a string literal. */
+#define MAKE_STATIC_KEY_NV(K, V, VS) \
+ MAKE_NV((K), sizeof(K) - 1, (V), (VS))
+
+/* Use same maximum as for tcp_pipeline_max. */
+#define HTTP_MAX_CONCURRENT_STREAMS UINT16_MAX
+
+#define HTTP_MAX_HEADER_IN_SIZE 1024
+
+#define HTTP_FRAME_HDLEN 9
+#define HTTP_FRAME_PADLEN 1
+
+#define MAX_DECIMAL_LENGTH(VT) ((CHAR_BIT * sizeof(VT) / 3) + 3)
+
+struct http_data {
+ uint8_t *buf;
+ size_t len;
+ size_t pos;
+ uint32_t ttl;
+ uv_write_cb on_write;
+ uv_write_t *req;
+};
+
+typedef array_t(nghttp2_nv) nghttp2_array_t;
+
+static int http_send_response(struct http_ctx *ctx, int32_t stream_id,
+ nghttp2_data_provider *prov, enum http_status status);
+static int http_send_response_rst_stream(struct http_ctx *ctx, int32_t stream_id,
+ nghttp2_data_provider *prov, enum http_status status);
+
+/** Checks if `status` has the correct `category`.
+ * E.g. status 200 has category 2, status 404 has category 4, 501 has category 5 etc. */
+static inline bool http_status_has_category(enum http_status status, int category)
+{
+ return status / 100 == category;
+}
+
+/*
+ * Write HTTP/2 protocol data to underlying transport layer.
+ */
+static ssize_t send_callback(nghttp2_session *h2, const uint8_t *data, size_t length,
+ int flags, void *user_data)
+{
+ struct http_ctx *ctx = (struct http_ctx *)user_data;
+ return ctx->send_cb(data, length, ctx->session);
+}
+
+/*
+ * Sets the HTTP status of the specified `context`, but only if its status has
+ * not already been changed to an unsuccessful one.
+ */
+static inline void set_status(struct http_ctx *ctx, enum http_status status)
+{
+ if (http_status_has_category(ctx->status, 2))
+ ctx->status = status;
+}
+
+/*
+ * Send padding length (if greater than zero).
+ */
+static int send_padlen(struct http_ctx *ctx, size_t padlen)
+{
+ int ret;
+ uint8_t buf;
+
+ if (padlen == 0)
+ return 0;
+
+ buf = (uint8_t)padlen;
+ ret = ctx->send_cb(&buf, HTTP_FRAME_PADLEN, ctx->session);
+ if (ret < 0)
+ return NGHTTP2_ERR_CALLBACK_FAILURE;
+
+ return 0;
+}
+
+/*
+ * Send HTTP/2 zero-byte padding.
+ *
+ * This sends only padlen-1 bytes of padding (if any), since padlen itself
+ * (already sent) is also considered padding. Refer to RFC7540, section 6.1
+ */
+static int send_padding(struct http_ctx *ctx, uint8_t padlen)
+{
+ static const uint8_t buf[UINT8_MAX];
+ int ret;
+
+ if (padlen <= 1)
+ return 0;
+
+ ret = ctx->send_cb(buf, padlen - 1, ctx->session);
+ if (ret < 0)
+ return NGHTTP2_ERR_CALLBACK_FAILURE;
+
+ return 0;
+}
+
+/*
+ * Write entire DATA frame to underlying transport layer.
+ *
+ * This function reads directly from data provider to avoid copying packet wire buffer.
+ */
+static int send_data_callback(nghttp2_session *h2, nghttp2_frame *frame, const uint8_t *framehd,
+ size_t length, nghttp2_data_source *source, void *user_data)
+{
+ struct http_data *data;
+ int ret;
+ struct http_ctx *ctx;
+
+ ctx = (struct http_ctx *)user_data;
+ data = (struct http_data*)source->ptr;
+
+ ret = ctx->send_cb(framehd, HTTP_FRAME_HDLEN, ctx->session);
+ if (ret < 0)
+ return NGHTTP2_ERR_CALLBACK_FAILURE;
+
+ ret = send_padlen(ctx, frame->data.padlen);
+ if (ret < 0)
+ return NGHTTP2_ERR_CALLBACK_FAILURE;
+
+ ret = ctx->send_cb(data->buf + data->pos, length, ctx->session);
+ if (ret < 0)
+ return NGHTTP2_ERR_CALLBACK_FAILURE;
+ data->pos += length;
+ if (kr_fails_assert(data->pos <= data->len))
+ return NGHTTP2_ERR_CALLBACK_FAILURE;
+
+ ret = send_padding(ctx, (uint8_t)frame->data.padlen);
+ if (ret < 0)
+ return NGHTTP2_ERR_CALLBACK_FAILURE;
+
+ return 0;
+}
+
+/*
+ * Check endpoint and uri path
+ */
+static int check_uri(const char* path)
+{
+ static const char *endpoints[] = {"dns-query", "doh"};
+ ssize_t endpoint_len;
+ ssize_t ret;
+
+ if (!path)
+ return kr_error(EINVAL);
+
+ char *query_mark = strstr(path, "?");
+
+ /* calculating of endpoint_len - for POST or GET method */
+ endpoint_len = (query_mark) ? query_mark - path - 1 : strlen(path) - 1;
+
+ /* check endpoint */
+ ret = -1;
+ for(int i = 0; i < sizeof(endpoints)/sizeof(*endpoints); i++)
+ {
+ if (strlen(endpoints[i]) != endpoint_len)
+ continue;
+ ret = strncmp(path + 1, endpoints[i], strlen(endpoints[i]));
+ if (!ret)
+ break;
+ }
+
+ return (ret) ? kr_error(ENOENT) : kr_ok();
+}
+
+static kr_http_header_array_t *headers_dup(kr_http_header_array_t *src)
+{
+ kr_http_header_array_t *dst = malloc(sizeof(kr_http_header_array_t));
+ kr_require(dst);
+ array_init(*dst);
+ for (size_t i = 0; i < src->len; i++) {
+ struct kr_http_header_array_entry *src_entry = &src->at[i];
+ struct kr_http_header_array_entry dst_entry = {
+ .name = strdup(src_entry->name),
+ .value = strdup(src_entry->value)
+ };
+ array_push(*dst, dst_entry);
+ }
+
+ return dst;
+}
+
+/*
+ * Process a query from URI path if there's base64url encoded dns variable.
+ */
+static int process_uri_path(struct http_ctx *ctx, const char* path, int32_t stream_id)
+{
+ if (!ctx || !path)
+ return kr_error(EINVAL);
+
+ static const char key[] = "dns=";
+ static const char *delim = "&";
+ char *beg, *end;
+ uint8_t *dest;
+ uint32_t remaining;
+
+ char *query_mark = strstr(path, "?");
+ if (!query_mark || strlen(query_mark) == 0) /* no parameters in path */
+ return kr_error(EINVAL);
+
+ /* go over key:value pair */
+ for (beg = strtok(query_mark + 1, delim); beg != NULL; beg = strtok(NULL, delim)) {
+ if (!strncmp(beg, key, 4)) /* dns variable in path found */
+ break;
+ }
+
+ if (!beg) /* no dns variable in path */
+ return kr_error(EINVAL);
+
+ beg += sizeof(key) - 1;
+ end = strchr(beg, '&');
+ if (end == NULL)
+ end = beg + strlen(beg);
+
+ ctx->buf_pos = sizeof(uint16_t); /* Reserve 2B for dnsmsg len. */
+ remaining = ctx->buf_size - ctx->submitted - ctx->buf_pos;
+ dest = ctx->buf + ctx->buf_pos;
+
+ /* Decode dns message from the parameter */
+ int ret = kr_base64url_decode((uint8_t*)beg, end - beg, dest, remaining);
+ if (ret < 0) {
+ ctx->buf_pos = 0;
+ kr_log_debug(DOH, "[%p] base64url decode failed %s\n", (void *)ctx->h2, kr_strerror(ret));
+ return ret;
+ }
+
+ ctx->buf_pos += ret;
+
+ struct http_stream stream = {
+ .id = stream_id,
+ .headers = headers_dup(ctx->headers)
+ };
+ queue_push(ctx->streams, stream);
+
+ return kr_ok();
+}
+
+static void refuse_stream(nghttp2_session *h2, int32_t stream_id)
+{
+ nghttp2_submit_rst_stream(
+ h2, NGHTTP2_FLAG_NONE, stream_id, NGHTTP2_REFUSED_STREAM);
+}
+
+void http_free_headers(kr_http_header_array_t *headers)
+{
+ if (headers == NULL)
+ return;
+
+ for (int i = 0; i < headers->len; i++) {
+ free(headers->at[i].name);
+ free(headers->at[i].value);
+ }
+ array_clear(*headers);
+ free(headers);
+}
+/* Return the http ctx into a pristine state in which no stream is being processed. */
+static void http_cleanup_stream(struct http_ctx *ctx)
+{
+ ctx->incomplete_stream = -1;
+ ctx->current_method = HTTP_METHOD_NONE;
+ free(ctx->uri_path);
+ ctx->uri_path = NULL;
+ http_free_headers(ctx->headers);
+ ctx->headers = NULL;
+}
+
+/*
+ * Save stream id from first header's frame.
+ *
+ * We don't support interweaving from different streams. To successfully parse
+ * multiple subsequent streams, each one must be fully received before processing
+ * a new stream.
+ */
+static int begin_headers_callback(nghttp2_session *h2, const nghttp2_frame *frame,
+ void *user_data)
+{
+ struct http_ctx *ctx = (struct http_ctx *)user_data;
+ int32_t stream_id = frame->hd.stream_id;
+
+ if (frame->hd.type != NGHTTP2_HEADERS ||
+ frame->headers.cat != NGHTTP2_HCAT_REQUEST) {
+ return 0;
+ }
+
+ if (ctx->incomplete_stream != -1) {
+ kr_log_debug(DOH, "[%p] stream %d incomplete, refusing (begin_headers_callback)\n",
+ (void *)h2, ctx->incomplete_stream);
+ refuse_stream(h2, stream_id);
+ } else {
+ http_cleanup_stream(ctx); // Free any leftover data and ensure pristine state
+ ctx->incomplete_stream = stream_id;
+ ctx->last_stream = stream_id;
+ ctx->headers = malloc(sizeof(kr_http_header_array_t));
+ array_init(*ctx->headers);
+ }
+ return 0;
+}
+
+/*
+ * Process a received header name-value pair.
+ *
+ * In DoH, GET requests contain the base64url-encoded query in dns variable present in path.
+ * This variable is parsed from :path pseudoheader.
+ */
+static int header_callback(nghttp2_session *h2, const nghttp2_frame *frame,
+ const uint8_t *name, size_t namelen, const uint8_t *value,
+ size_t valuelen, uint8_t flags, void *user_data)
+{
+ struct http_ctx *ctx = (struct http_ctx *)user_data;
+ int32_t stream_id = frame->hd.stream_id;
+
+ if (frame->hd.type != NGHTTP2_HEADERS)
+ return 0;
+
+ if (ctx->incomplete_stream != stream_id) {
+ kr_log_debug(DOH, "[%p] stream %d incomplete, refusing (header_callback)\n",
+ (void *)h2, ctx->incomplete_stream);
+ refuse_stream(h2, stream_id);
+ return 0;
+ }
+
+ /* Store chosen headers to pass them to kr_request. */
+ for (int i = 0; i < the_worker->doh_qry_headers.len; i++) {
+ if (!strcasecmp(the_worker->doh_qry_headers.at[i], (const char *)name)) {
+ kr_http_header_array_entry_t header;
+
+ /* Limit maximum value size to reduce attack surface. */
+ if (valuelen > HTTP_MAX_HEADER_IN_SIZE) {
+ kr_log_debug(DOH,
+ "[%p] stream %d: header too large (%zu B), refused\n",
+ (void *)h2, stream_id, valuelen);
+ set_status(ctx, HTTP_STATUS_REQUEST_HEADER_FIELDS_TOO_LARGE);
+ return 0;
+ }
+
+ /* Copy the user-provided header name to keep the original case. */
+ header.name = malloc(sizeof(*header.name) * (namelen + 1));
+ memcpy(header.name, the_worker->doh_qry_headers.at[i], namelen);
+ header.name[namelen] = '\0';
+
+ header.value = malloc(sizeof(*header.value) * (valuelen + 1));
+ memcpy(header.value, value, valuelen);
+ header.value[valuelen] = '\0';
+
+ array_push(*ctx->headers, header);
+ break;
+ }
+ }
+
+ if (!strcasecmp(":path", (const char *)name)) {
+ int uri_result = check_uri((const char *)value);
+ if (uri_result == kr_error(ENOENT)) {
+ set_status(ctx, HTTP_STATUS_NOT_FOUND);
+ return 0;
+ } else if (uri_result < 0) {
+ set_status(ctx, HTTP_STATUS_BAD_REQUEST);
+ return 0;
+ }
+
+ kr_assert(ctx->uri_path == NULL);
+ ctx->uri_path = malloc(sizeof(*ctx->uri_path) * (valuelen + 1));
+ if (!ctx->uri_path)
+ return kr_error(ENOMEM);
+ memcpy(ctx->uri_path, value, valuelen);
+ ctx->uri_path[valuelen] = '\0';
+ }
+
+ if (!strcasecmp(":method", (const char *)name)) {
+ if (!strcasecmp("get", (const char *)value)) {
+ ctx->current_method = HTTP_METHOD_GET;
+ } else if (!strcasecmp("post", (const char *)value)) {
+ ctx->current_method = HTTP_METHOD_POST;
+ } else if (!strcasecmp("head", (const char *)value)) {
+ ctx->current_method = HTTP_METHOD_HEAD;
+ } else {
+ ctx->current_method = HTTP_METHOD_NONE;
+ set_status(ctx, HTTP_STATUS_NOT_IMPLEMENTED);
+ return 0;
+ }
+ }
+
+ if (!strcasecmp("content-type", (const char *)name)) {
+ if (strcasecmp("application/dns-message", (const char *)value)) {
+ set_status(ctx, HTTP_STATUS_UNSUPPORTED_MEDIA_TYPE);
+ return 0;
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * Process DATA chunk sent by the client (by POST method).
+ *
+ * We use a single DNS message buffer for the entire connection. Therefore, we
+ * don't support interweaving DATA chunks from different streams. To successfully
+ * parse multiple subsequent streams, each one must be fully received before
+ * processing a new stream. See https://gitlab.nic.cz/knot/knot-resolver/-/issues/619
+ */
+static int data_chunk_recv_callback(nghttp2_session *h2, uint8_t flags, int32_t stream_id,
+ const uint8_t *data, size_t len, void *user_data)
+{
+ struct http_ctx *ctx = (struct http_ctx *)user_data;
+ ssize_t remaining;
+ ssize_t required;
+ bool is_first = queue_len(ctx->streams) == 0 || queue_tail(ctx->streams).id != ctx->incomplete_stream;
+
+ if (ctx->incomplete_stream != stream_id) {
+ kr_log_debug(DOH, "[%p] stream %d incomplete, refusing (data_chunk_recv_callback)\n",
+ (void *)h2, ctx->incomplete_stream);
+ refuse_stream(h2, stream_id);
+ ctx->incomplete_stream = -1;
+ return 0;
+ }
+
+ remaining = ctx->buf_size - ctx->submitted - ctx->buf_pos;
+ required = len;
+ /* First data chunk of the new stream */
+ if (is_first)
+ required += sizeof(uint16_t);
+
+ if (required > remaining) {
+ kr_log_error(DOH, "[%p] insufficient space in buffer\n", (void *)h2);
+ ctx->incomplete_stream = -1;
+ return NGHTTP2_ERR_CALLBACK_FAILURE;
+ }
+
+ if (is_first) {
+ /* FIXME: reserving the 2B length should be done elsewhere,
+ * ideally for both POST and GET at the same time. The right
+ * place would probably be after receiving HEADERS frame in
+ * on_frame_recv()
+ *
+ * queue_push() should be moved: see FIXME in
+ * submit_to_wirebuffer() */
+ ctx->buf_pos = sizeof(uint16_t); /* Reserve 2B for dnsmsg len. */
+ struct http_stream stream = {
+ .id = stream_id,
+ .headers = headers_dup(ctx->headers)
+ };
+ queue_push(ctx->streams, stream);
+ }
+
+ memmove(ctx->buf + ctx->buf_pos, data, len);
+ ctx->buf_pos += len;
+ return 0;
+}
+
+static int submit_to_wirebuffer(struct http_ctx *ctx)
+{
+ int ret = -1;
+ ssize_t len;
+
+ /* Free http_ctx's headers - by now the stream has obtained its own
+ * copy of the headers which it can operate on. */
+ /* FIXME: technically, transferring memory ownership should happen
+ * along with queue_push(ctx->streams) to avoid confusion of who owns
+ * what and when. Pushing to queue should be done AFTER we successfully
+ * finish this function. On error, we'd clean up and not push anything.
+ * However, queue's content is now also used to detect first DATA frame
+ * in stream, so it needs to be refactored first.
+ *
+ * For now, we assume memory is transferred even on error and the
+ * headers themselves get cleaned up during http_free() which is
+ * triggered after the error when session is closed.
+ *
+ * EDIT(2022-05-19): The original logic was causing occasional
+ * double-free conditions once status code support was extended.
+ *
+ * Currently, we are copying the headers from ctx instead of transferring
+ * ownership, which is still a dirty workaround and, ideally, the whole
+ * logic around header (de)allocation should be reworked to make
+ * the ownership situation clear. */
+ http_free_headers(ctx->headers);
+ ctx->headers = NULL;
+
+ len = ctx->buf_pos - sizeof(uint16_t);
+ if (len <= 0 || len > KNOT_WIRE_MAX_PKTSIZE) {
+ kr_log_debug(DOH, "[%p] invalid dnsmsg size: %zd B\n", (void *)ctx->h2, len);
+ set_status(ctx, (len <= 0)
+ ? HTTP_STATUS_BAD_REQUEST
+ : HTTP_STATUS_PAYLOAD_TOO_LARGE);
+ ret = 0;
+ goto cleanup;
+ }
+
+ /* Submit data to wirebuffer. */
+ knot_wire_write_u16(ctx->buf, len);
+ ctx->submitted += ctx->buf_pos;
+ ctx->buf += ctx->buf_pos;
+ ctx->buf_pos = 0;
+ ret = 0;
+cleanup:
+ http_cleanup_stream(ctx);
+ return ret;
+}
+
+/*
+ * Finalize existing buffer upon receiving the last frame in the stream.
+ *
+ * For GET, this would be HEADERS frame.
+ * For POST, it is a DATA frame.
+ *
+ * Unrelated frames (such as SETTINGS) are ignored (no data was buffered).
+ */
+static int on_frame_recv_callback(nghttp2_session *h2, const nghttp2_frame *frame, void *user_data)
+{
+ struct http_ctx *ctx = (struct http_ctx *)user_data;
+ int32_t stream_id = frame->hd.stream_id;
+ if(kr_fails_assert(stream_id != -1))
+ return NGHTTP2_ERR_CALLBACK_FAILURE;
+
+ if ((frame->hd.flags & NGHTTP2_FLAG_END_STREAM) && ctx->incomplete_stream == stream_id) {
+ ctx->streaming = false;
+
+ if (ctx->current_method == HTTP_METHOD_GET || ctx->current_method == HTTP_METHOD_HEAD) {
+ if (process_uri_path(ctx, ctx->uri_path, stream_id) < 0) {
+ /* End processing - don't submit to wirebuffer. */
+ set_status(ctx, HTTP_STATUS_BAD_REQUEST);
+ return 0;
+ }
+ }
+
+ if (submit_to_wirebuffer(ctx) < 0)
+ return NGHTTP2_ERR_CALLBACK_FAILURE;
+ }
+
+ return 0;
+}
+
+/*
+ * Call on_write() callback for written (or failed) packet data.
+ */
+static void on_pkt_write(struct http_data *data, int status)
+{
+ if (!data || !data->req || !data->on_write)
+ return;
+
+ data->on_write(data->req, status);
+ free(data);
+}
+
+static int stream_write_data_free_err(trie_val_t *val, void *null)
+{
+ on_pkt_write(*val, kr_error(EIO));
+ return 0;
+}
+
+/*
+ * Cleanup for closed streams.
+ */
+static int on_stream_close_callback(nghttp2_session *h2, int32_t stream_id,
+ uint32_t error_code, void *user_data)
+{
+ struct http_data *data;
+ struct http_ctx *ctx = (struct http_ctx *)user_data;
+ int ret;
+
+ /* Ensure connection state is cleaned up in case the stream gets
+ * unexpectedly closed, e.g. by PROTOCOL_ERROR issued from nghttp2. */
+ if (ctx->incomplete_stream == stream_id)
+ http_cleanup_stream(ctx);
+
+ ret = trie_del(ctx->stream_write_data, (char *)&stream_id, sizeof(stream_id), (trie_val_t*)&data);
+ if (ret == KNOT_EOK && data)
+ on_pkt_write(data, error_code == 0 ? 0 : kr_error(EIO));
+
+ return 0;
+}
+
+/*
+ * Setup and initialize connection with new HTTP/2 context.
+ */
+struct http_ctx* http_new(struct session *session, http_send_callback send_cb)
+{
+ if (!session || !send_cb)
+ return NULL;
+
+ nghttp2_session_callbacks *callbacks;
+ struct http_ctx *ctx = NULL;
+ static const nghttp2_settings_entry iv[] = {
+ { NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS, HTTP_MAX_CONCURRENT_STREAMS }
+ };
+
+ if (nghttp2_session_callbacks_new(&callbacks) < 0)
+ return ctx;
+ nghttp2_session_callbacks_set_send_callback(callbacks, send_callback);
+ nghttp2_session_callbacks_set_send_data_callback(callbacks, send_data_callback);
+ nghttp2_session_callbacks_set_on_header_callback(callbacks, header_callback);
+ nghttp2_session_callbacks_set_on_begin_headers_callback(callbacks, begin_headers_callback);
+ nghttp2_session_callbacks_set_on_data_chunk_recv_callback(
+ callbacks, data_chunk_recv_callback);
+ nghttp2_session_callbacks_set_on_frame_recv_callback(
+ callbacks, on_frame_recv_callback);
+ nghttp2_session_callbacks_set_on_stream_close_callback(
+ callbacks, on_stream_close_callback);
+
+ ctx = calloc(1UL, sizeof(struct http_ctx));
+ if (!ctx)
+ goto finish;
+
+ ctx->send_cb = send_cb;
+ ctx->session = session;
+ queue_init(ctx->streams);
+ ctx->stream_write_data = trie_create(NULL);
+ ctx->incomplete_stream = -1;
+ ctx->last_stream = -1;
+ ctx->submitted = 0;
+ ctx->streaming = true;
+ ctx->current_method = HTTP_METHOD_NONE;
+ ctx->uri_path = NULL;
+ ctx->status = HTTP_STATUS_OK;
+
+ nghttp2_session_server_new(&ctx->h2, callbacks, ctx);
+ nghttp2_submit_settings(ctx->h2, NGHTTP2_FLAG_NONE,
+ iv, sizeof(iv)/sizeof(*iv));
+
+ struct sockaddr *peer = session_get_peer(session);
+ kr_log_debug(DOH, "[%p] h2 session created for %s\n", (void *)ctx->h2, kr_straddr(peer));
+finish:
+ nghttp2_session_callbacks_del(callbacks);
+ return ctx;
+}
+
+/*
+ * Process inbound HTTP/2 data and return number of bytes read into session wire buffer.
+ *
+ * This function may trigger outgoing HTTP/2 data, such as stream resets, window updates etc.
+ *
+ * Returns 1 if stream has not ended yet, 0 if the stream has ended, or
+ * a negative value on error.
+ */
+int http_process_input_data(struct session *session, const uint8_t *buf, ssize_t nread,
+ ssize_t *out_submitted)
+{
+ struct http_ctx *ctx = session_http_get_server_ctx(session);
+ ssize_t ret = 0;
+
+ if (!ctx->h2)
+ return kr_error(ENOSYS);
+ if (kr_fails_assert(ctx->session == session))
+ return kr_error(EINVAL);
+
+ /* FIXME It is possible for the TLS/HTTP processing to be cut off at
+ * any point, waiting for more data. If we're using POST which is split
+ * into multiple DATA frames and such a stream is in the middle of
+ * processing, resetting buf_pos will corrupt its contents (and the
+ * query will be ignored). This may also be problematic in other
+ * cases. */
+ ctx->submitted = 0;
+ ctx->streaming = true;
+ ctx->buf = session_wirebuf_get_free_start(session);
+ ctx->buf_pos = 0;
+ ctx->buf_size = session_wirebuf_get_free_size(session);
+
+ ret = nghttp2_session_mem_recv(ctx->h2, buf, nread);
+ if (ret < 0) {
+ kr_log_debug(DOH, "[%p] nghttp2_session_mem_recv failed: %s (%zd)\n",
+ (void *)ctx->h2, nghttp2_strerror(ret), ret);
+ return kr_error(EIO);
+ }
+
+ ret = nghttp2_session_send(ctx->h2);
+ if (ret < 0) {
+ kr_log_debug(DOH, "[%p] nghttp2_session_send failed: %s (%zd)\n",
+ (void *)ctx->h2, nghttp2_strerror(ret), ret);
+ return kr_error(EIO);
+ }
+
+ if (!http_status_has_category(ctx->status, 2)) {
+ *out_submitted = 0;
+ http_send_status(session, ctx->status);
+ http_cleanup_stream(ctx);
+ return 0;
+ }
+
+ *out_submitted = ctx->submitted;
+ return ctx->streaming;
+}
+
+int http_send_status(struct session *session, enum http_status status)
+{
+ struct http_ctx *ctx = session_http_get_server_ctx(session);
+ if (ctx->last_stream >= 0)
+ return http_send_response_rst_stream(
+ ctx, ctx->last_stream, NULL, status);
+
+ return 0;
+}
+
+/*
+ * Provide data from buffer to HTTP/2 library.
+ *
+ * To avoid copying the packet wire buffer, we use NGHTTP2_DATA_FLAG_NO_COPY
+ * and take care of sending entire DATA frames ourselves with nghttp2_send_data_callback.
+ *
+ * See https://www.nghttp2.org/documentation/types.html#c.nghttp2_data_source_read_callback
+ */
+static ssize_t read_callback(nghttp2_session *h2, int32_t stream_id, uint8_t *buf,
+ size_t length, uint32_t *data_flags,
+ nghttp2_data_source *source, void *user_data)
+{
+ struct http_data *data;
+ size_t avail;
+ size_t send;
+
+ data = (struct http_data*)source->ptr;
+ avail = data->len - data->pos;
+ send = MIN(avail, length);
+
+ if (avail == send)
+ *data_flags |= NGHTTP2_DATA_FLAG_EOF;
+
+ *data_flags |= NGHTTP2_DATA_FLAG_NO_COPY;
+ return send;
+}
+
+/** Convenience function for pushing `nghttp2_nv` made with MAKE_*_NV into
+ * arrays. */
+static inline void push_nv(nghttp2_array_t *arr, nghttp2_nv nv)
+{
+ array_push(*arr, nv);
+}
+
+/*
+ * Send dns response provided by the HTTP/2 data provider.
+ *
+ * Data isn't guaranteed to be sent immediately due to underlying HTTP/2 flow control.
+ */
+static int http_send_response(struct http_ctx *ctx, int32_t stream_id,
+ nghttp2_data_provider *prov, enum http_status status)
+{
+ nghttp2_session *h2 = ctx->h2;
+ int ret;
+
+ nghttp2_array_t hdrs;
+ array_init(hdrs);
+ array_reserve(hdrs, 5);
+
+ auto_free char *status_str = NULL;
+ if (likely(status == HTTP_STATUS_OK)) {
+ push_nv(&hdrs, MAKE_STATIC_NV(":status", "200"));
+ } else {
+ int status_len = asprintf(&status_str, "%d", (int)status);
+ kr_require(status_len >= 0);
+ push_nv(&hdrs, MAKE_STATIC_KEY_NV(":status", status_str, status_len));
+ }
+ push_nv(&hdrs, MAKE_STATIC_NV("access-control-allow-origin", "*"));
+
+ struct http_data *data = NULL;
+ auto_free char *size = NULL;
+ auto_free char *max_age = NULL;
+
+ if (ctx->current_method == HTTP_METHOD_HEAD && prov) {
+ /* HEAD method is the same as GET but only returns headers,
+ * so let's clean up the data here as we don't need it. */
+ free(prov->source.ptr);
+ prov = NULL;
+ }
+
+ if (prov) {
+ data = (struct http_data*)prov->source.ptr;
+ const char *directive_max_age = "max-age=";
+ int max_age_len;
+ int size_len;
+
+ size_len = asprintf(&size, "%zu", data->len);
+ kr_require(size_len >= 0);
+ max_age_len = asprintf(&max_age, "%s%" PRIu32, directive_max_age, data->ttl);
+ kr_require(max_age_len >= 0);
+
+ push_nv(&hdrs, MAKE_STATIC_NV("content-type", "application/dns-message"));
+ push_nv(&hdrs, MAKE_STATIC_KEY_NV("content-length", size, size_len));
+ push_nv(&hdrs, MAKE_STATIC_KEY_NV("cache-control", max_age, max_age_len));
+ }
+
+ ret = nghttp2_submit_response(h2, stream_id, hdrs.at, hdrs.len, prov);
+ array_clear(hdrs);
+ if (ret != 0) {
+ kr_log_debug(DOH, "[%p] nghttp2_submit_response failed: %s\n", (void *)h2, nghttp2_strerror(ret));
+ free(data);
+ return kr_error(EIO);
+ }
+
+ /* Keep reference to data, since we need to free it later on.
+ * Due to HTTP/2 flow control, this stream data may be sent at a later point, or not at all.
+ */
+ trie_val_t *stream_data_p = trie_get_ins(ctx->stream_write_data, (char *)&stream_id, sizeof(stream_id));
+ if (kr_fails_assert(stream_data_p)) {
+ kr_log_debug(DOH, "[%p] failed to insert to stream_write_data\n", (void *)h2);
+ free(data);
+ return kr_error(EIO);
+ }
+ *stream_data_p = data;
+ ret = nghttp2_session_send(h2);
+ if(ret < 0) {
+ kr_log_debug(DOH, "[%p] nghttp2_session_send failed: %s\n", (void *)h2, nghttp2_strerror(ret));
+
+ /* At this point, there was an error in some nghttp2 callback. The on_pkt_write()
+ * callback which also calls free(data) may or may not have been called. Therefore,
+ * we must guarantee it will have been called by explicitly closing the stream.
+ * Afterwards, we have no option but to pretend this function was a success. If we
+ * returned an error, qr_task_send() logic would lead to a double-free because
+ * on_write() was already called. */
+ nghttp2_submit_rst_stream(h2, NGHTTP2_FLAG_NONE, stream_id, NGHTTP2_INTERNAL_ERROR);
+ return 0;
+ }
+
+ return 0;
+}
+
+/*
+ * Same as `http_send_response`, but resets the HTTP stream afterwards. Used
+ * for sending negative status messages.
+ */
+static int http_send_response_rst_stream(struct http_ctx *ctx, int32_t stream_id,
+ nghttp2_data_provider *prov, enum http_status status)
+{
+ int ret = http_send_response(ctx, stream_id, prov, status);
+ if (ret)
+ return ret;
+
+ ctx->last_stream = -1;
+ nghttp2_submit_rst_stream(ctx->h2, NGHTTP2_FLAG_NONE, stream_id, NGHTTP2_NO_ERROR);
+ ret = nghttp2_session_send(ctx->h2);
+ return ret;
+}
+
+
+/*
+ * Send HTTP/2 stream data created from packet's wire buffer.
+ *
+ * If this function returns an error, the on_write() callback isn't (and
+ * mustn't be!) called, since such errors are handled in an upper layer - in
+ * qr_task_step() in daemon/worker.
+ */
+static int http_write_pkt(struct http_ctx *ctx, knot_pkt_t *pkt, int32_t stream_id,
+ uv_write_t *req, uv_write_cb on_write)
+{
+ struct http_data *data;
+ nghttp2_data_provider prov;
+
+ data = malloc(sizeof(struct http_data));
+ if (!data)
+ return kr_error(ENOMEM);
+
+ data->buf = pkt->wire;
+ data->len = pkt->size;
+ data->pos = 0;
+ data->on_write = on_write;
+ data->req = req;
+ data->ttl = packet_ttl(pkt);
+
+ prov.source.ptr = data;
+ prov.read_callback = read_callback;
+
+ return http_send_response(ctx, stream_id, &prov, HTTP_STATUS_OK);
+}
+
+/*
+ * Write request to HTTP/2 stream.
+ *
+ * Packet wire buffer must stay valid until the on_write callback.
+ */
+int http_write(uv_write_t *req, uv_handle_t *handle, knot_pkt_t *pkt, int32_t stream_id,
+ uv_write_cb on_write)
+{
+ struct session *session;
+ struct http_ctx *ctx;
+ int ret;
+
+ if (!req || !pkt || !handle || !handle->data || stream_id < 0)
+ return kr_error(EINVAL);
+ req->handle = (uv_stream_t *)handle;
+
+ session = handle->data;
+ if (session_flags(session)->outgoing)
+ return kr_error(ENOSYS);
+
+ ctx = session_http_get_server_ctx(session);
+ if (!ctx || !ctx->h2)
+ return kr_error(EINVAL);
+
+ ret = http_write_pkt(ctx, pkt, stream_id, req, on_write);
+ if (ret < 0)
+ return ret;
+
+ return kr_ok();
+}
+
+/*
+ * Release HTTP/2 context.
+ */
+void http_free(struct http_ctx *ctx)
+{
+ if (!ctx)
+ return;
+
+ kr_log_debug(DOH, "[%p] h2 session freed\n", (void *)ctx->h2);
+
+ /* Clean up any headers whose ownership may not have been transferred.
+ * This may happen when connection is abruptly ended (e.g. due to errors while
+ * processing HTTP stream. */
+ while (queue_len(ctx->streams) > 0) {
+ struct http_stream stream = queue_head(ctx->streams);
+ http_free_headers(stream.headers);
+ queue_pop(ctx->streams);
+ }
+
+ trie_apply(ctx->stream_write_data, stream_write_data_free_err, NULL);
+ trie_free(ctx->stream_write_data);
+
+ http_cleanup_stream(ctx);
+ queue_deinit(ctx->streams);
+ nghttp2_session_del(ctx->h2);
+ free(ctx);
+}
diff --git a/daemon/http.h b/daemon/http.h
new file mode 100644
index 0000000..0749e3b
--- /dev/null
+++ b/daemon/http.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) CZ.NIC, z.s.p.o
+ *
+ * Initial Author: Jan Hák <jan.hak@nic.cz>
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#include <uv.h>
+#include <libknot/packet/pkt.h>
+
+#if ENABLE_DOH2
+#include <nghttp2/nghttp2.h>
+#endif
+
+#include "lib/generic/queue.h"
+#include "lib/generic/trie.h"
+
+/** Transport session (opaque). */
+struct session;
+
+typedef ssize_t(*http_send_callback)(const uint8_t *buffer,
+ const size_t buffer_len,
+ struct session *session);
+
+struct http_stream {
+ int32_t id;
+ kr_http_header_array_t *headers;
+};
+
+typedef queue_t(struct http_stream) queue_http_stream;
+
+typedef enum {
+ HTTP_METHOD_NONE = 0,
+ HTTP_METHOD_GET = 1,
+ HTTP_METHOD_POST = 2,
+ HTTP_METHOD_HEAD = 3, /**< Same as GET, except it does not return payload.
+ * Required to be implemented by RFC 7231. */
+} http_method_t;
+
+/** HTTP status codes returned by kresd.
+ * This is obviously non-exhaustive of all HTTP status codes, feel free to add
+ * more if needed. */
+enum http_status {
+ HTTP_STATUS_OK = 200,
+ HTTP_STATUS_BAD_REQUEST = 400,
+ HTTP_STATUS_NOT_FOUND = 404,
+ HTTP_STATUS_PAYLOAD_TOO_LARGE = 413,
+ HTTP_STATUS_UNSUPPORTED_MEDIA_TYPE = 415,
+ HTTP_STATUS_REQUEST_HEADER_FIELDS_TOO_LARGE = 431,
+ HTTP_STATUS_NOT_IMPLEMENTED = 501,
+};
+
+struct http_ctx {
+ struct nghttp2_session *h2;
+ http_send_callback send_cb;
+ struct session *session;
+ queue_http_stream streams; /* Streams present in the wire buffer. */
+ trie_t *stream_write_data; /* Dictionary of stream data that needs to be freed after write. */
+ int32_t incomplete_stream;
+ int32_t last_stream; /* The last used stream - mostly the same as incomplete_stream, but can be used after
+ completion for sending HTTP status codes. */
+ ssize_t submitted;
+ http_method_t current_method;
+ char *uri_path;
+ kr_http_header_array_t *headers;
+ uint8_t *buf; /* Part of the wire_buf that belongs to current HTTP/2 stream. */
+ ssize_t buf_pos;
+ ssize_t buf_size;
+ enum http_status status;
+ bool streaming; /* True: not all data in the stream has been received yet. */
+};
+
+#if ENABLE_DOH2
+struct http_ctx* http_new(struct session *session, http_send_callback send_cb);
+int http_process_input_data(struct session *session, const uint8_t *buf, ssize_t nread,
+ ssize_t *out_submitted);
+int http_send_status(struct session *session, enum http_status status);
+int http_write(uv_write_t *req, uv_handle_t *handle, knot_pkt_t* pkt, int32_t stream_id,
+ uv_write_cb on_write);
+void http_free(struct http_ctx *ctx);
+void http_free_headers(kr_http_header_array_t *headers);
+#endif
diff --git a/daemon/io.c b/daemon/io.c
new file mode 100644
index 0000000..48bfed3
--- /dev/null
+++ b/daemon/io.c
@@ -0,0 +1,1169 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#include "daemon/io.h"
+
+#include <contrib/ucw/lib.h>
+#include <contrib/ucw/mempool.h>
+#include <libknot/errcode.h>
+#include <string.h>
+#include <sys/resource.h>
+
+#if ENABLE_XDP
+ #include <libknot/xdp/eth.h>
+ #include <libknot/xdp/xdp.h>
+ #include <net/if.h>
+#endif
+
+#include "daemon/network.h"
+#include "daemon/proxyv2.h"
+#include "daemon/worker.h"
+#include "daemon/tls.h"
+#include "daemon/http.h"
+#include "daemon/session.h"
+#include "contrib/cleanup.h"
+#include "lib/utils.h"
+
+#define negotiate_bufsize(func, handle, bufsize_want) do { \
+ int bufsize = 0; (func)((handle), &bufsize); \
+ if (bufsize < (bufsize_want)) { \
+ bufsize = (bufsize_want); \
+ (func)((handle), &bufsize); \
+ } \
+} while (0)
+
+static void check_bufsize(uv_handle_t* handle)
+{
+ return; /* TODO: resurrect after https://github.com/libuv/libuv/issues/419 */
+ /* We want to buffer at least N waves in advance.
+ * This is magic presuming we can pull in a whole recvmmsg width in one wave.
+ * Linux will double this the bufsize wanted.
+ */
+ const int bufsize_want = 2 * sizeof( ((struct worker_ctx *)NULL)->wire_buf ) ;
+ negotiate_bufsize(uv_recv_buffer_size, handle, bufsize_want);
+ negotiate_bufsize(uv_send_buffer_size, handle, bufsize_want);
+}
+
+#undef negotiate_bufsize
+
+static void handle_getbuf(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf)
+{
+ /* UDP sessions use worker buffer for wire data,
+ * TCP sessions use session buffer for wire data
+ * (see session_set_handle()).
+ * TLS sessions use buffer from TLS context.
+ * The content of the worker buffer is
+ * guaranteed to be unchanged only for the duration of
+ * udp_read() and tcp_read().
+ */
+ struct session *s = handle->data;
+ if (!session_flags(s)->has_tls) {
+ buf->base = (char *) session_wirebuf_get_free_start(s);
+ buf->len = session_wirebuf_get_free_size(s);
+ } else {
+ struct tls_common_ctx *ctx = session_tls_get_common_ctx(s);
+ buf->base = (char *) ctx->recv_buf;
+ buf->len = sizeof(ctx->recv_buf);
+ }
+}
+
+void udp_recv(uv_udp_t *handle, ssize_t nread, const uv_buf_t *buf,
+ const struct sockaddr *comm_addr, unsigned flags)
+{
+ struct session *s = handle->data;
+ if (session_flags(s)->closing || nread <= 0 || comm_addr->sa_family == AF_UNSPEC)
+ return;
+
+ if (session_flags(s)->outgoing) {
+ const struct sockaddr *peer = session_get_peer(s);
+ if (kr_fails_assert(peer->sa_family != AF_UNSPEC))
+ return;
+ if (kr_sockaddr_cmp(peer, comm_addr) != 0) {
+ kr_log_debug(IO, "<= ignoring UDP from unexpected address '%s'\n",
+ kr_straddr(comm_addr));
+ return;
+ }
+ }
+
+ const uint8_t *data = (const uint8_t *)buf->base;
+ ssize_t data_len = nread;
+ const struct sockaddr *src_addr = comm_addr;
+ const struct sockaddr *dst_addr = NULL;
+ struct proxy_result proxy;
+ bool has_proxy = false;
+ if (!session_flags(s)->outgoing && proxy_header_present(data, data_len)) {
+ if (!proxy_allowed(&the_worker->engine->net, comm_addr)) {
+ kr_log_debug(IO, "<= ignoring PROXYv2 UDP from disallowed address '%s'\n",
+ kr_straddr(comm_addr));
+ return;
+ }
+
+ ssize_t trimmed = proxy_process_header(&proxy, s, data, data_len);
+ if (trimmed == KNOT_EMALF) {
+ if (kr_log_is_debug(IO, NULL)) {
+ kr_log_debug(IO, "<= ignoring malformed PROXYv2 UDP "
+ "from address '%s'\n",
+ kr_straddr(comm_addr));
+ }
+ return;
+ } else if (trimmed < 0) {
+ if (kr_log_is_debug(IO, NULL)) {
+ kr_log_debug(IO, "<= error processing PROXYv2 UDP "
+ "from address '%s', ignoring\n",
+ kr_straddr(comm_addr));
+ }
+ return;
+ }
+
+ if (proxy.command == PROXY2_CMD_PROXY && proxy.family != AF_UNSPEC) {
+ has_proxy = true;
+ src_addr = &proxy.src_addr.ip;
+ dst_addr = &proxy.dst_addr.ip;
+
+ if (kr_log_is_debug(IO, NULL)) {
+ kr_log_debug(IO, "<= UDP query from '%s'\n",
+ kr_straddr(src_addr));
+ kr_log_debug(IO, "<= proxied through '%s'\n",
+ kr_straddr(comm_addr));
+ }
+ }
+ data = session_wirebuf_get_free_start(s);
+ data_len = nread - trimmed;
+ }
+
+ ssize_t consumed = session_wirebuf_consume(s, data, data_len);
+ kr_assert(consumed == data_len);
+
+ struct io_comm_data comm = {
+ .src_addr = src_addr,
+ .comm_addr = comm_addr,
+ .dst_addr = dst_addr,
+ .proxy = (has_proxy) ? &proxy : NULL
+ };
+ session_wirebuf_process(s, &comm);
+ session_wirebuf_discard(s);
+ mp_flush(the_worker->pkt_pool.ctx);
+}
+
+static int family_to_freebind_option(sa_family_t sa_family, int *level, int *name)
+{
+#define LOG_NO_FB kr_log_error(NETWORK, "your system does not support 'freebind', " \
+ "please remove it from your configuration\n")
+ switch (sa_family) {
+ case AF_INET:
+ *level = IPPROTO_IP;
+#if defined(IP_FREEBIND)
+ *name = IP_FREEBIND;
+#elif defined(IP_BINDANY)
+ *name = IP_BINDANY;
+#else
+ LOG_NO_FB;
+ return kr_error(ENOTSUP);
+#endif
+ break;
+ case AF_INET6:
+#if defined(IP_FREEBIND)
+ *level = IPPROTO_IP;
+ *name = IP_FREEBIND;
+#elif defined(IPV6_BINDANY)
+ *level = IPPROTO_IPV6;
+ *name = IPV6_BINDANY;
+#else
+ LOG_NO_FB;
+ return kr_error(ENOTSUP);
+#endif
+ break;
+ default:
+ return kr_error(ENOTSUP);
+ }
+ return kr_ok();
+}
+
+int io_bind(const struct sockaddr *addr, int type, const endpoint_flags_t *flags)
+{
+ const int fd = socket(addr->sa_family, type, 0);
+ if (fd < 0) return kr_error(errno);
+
+ int yes = 1;
+ if (addr->sa_family == AF_INET || addr->sa_family == AF_INET6) {
+ if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes))) {
+ close(fd);
+ return kr_error(errno);
+ }
+
+#ifdef SO_REUSEPORT_LB
+ if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT_LB, &yes, sizeof(yes))) {
+ close(fd);
+ return kr_error(errno);
+ }
+#elif defined(SO_REUSEPORT) && defined(__linux__) /* different meaning on (Free)BSD */
+ if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &yes, sizeof(yes))) {
+ close(fd);
+ return kr_error(errno);
+ }
+#endif
+
+#ifdef IPV6_V6ONLY
+ if (addr->sa_family == AF_INET6
+ && setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &yes, sizeof(yes))) {
+ close(fd);
+ return kr_error(errno);
+ }
+#endif
+ if (flags != NULL && flags->freebind) {
+ int optlevel;
+ int optname;
+ int ret = family_to_freebind_option(addr->sa_family, &optlevel, &optname);
+ if (ret) {
+ close(fd);
+ return kr_error(ret);
+ }
+ if (setsockopt(fd, optlevel, optname, &yes, sizeof(yes))) {
+ close(fd);
+ return kr_error(errno);
+ }
+ }
+
+ /* Linux 3.15 has IP_PMTUDISC_OMIT which makes sockets
+ * ignore PMTU information and send packets with DF=0.
+ * This mitigates DNS fragmentation attacks by preventing
+ * forged PMTU information. FreeBSD already has same semantics
+ * without setting the option.
+ https://gitlab.nic.cz/knot/knot-dns/-/issues/640
+ */
+#if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_OMIT)
+ int omit = IP_PMTUDISC_OMIT;
+ if (type == SOCK_DGRAM && addr->sa_family == AF_INET
+ && setsockopt(fd, IPPROTO_IP, IP_MTU_DISCOVER, &omit, sizeof(omit))) {
+ kr_log_error(IO,
+ "failed to disable Path MTU discovery for %s UDP: %s\n",
+ kr_straddr(addr), strerror(errno));
+ }
+#endif
+ }
+
+ if (bind(fd, addr, kr_sockaddr_len(addr))) {
+ close(fd);
+ return kr_error(errno);
+ }
+
+ return fd;
+}
+
+int io_listen_udp(uv_loop_t *loop, uv_udp_t *handle, int fd)
+{
+ if (!handle) {
+ return kr_error(EINVAL);
+ }
+ int ret = uv_udp_init(loop, handle);
+ if (ret) return ret;
+
+ ret = uv_udp_open(handle, fd);
+ if (ret) return ret;
+
+ uv_handle_t *h = (uv_handle_t *)handle;
+ check_bufsize(h);
+ /* Handle is already created, just create context. */
+ struct session *s = session_new(h, false, false);
+ kr_require(s);
+ session_flags(s)->outgoing = false;
+
+ int socklen = sizeof(union kr_sockaddr);
+ ret = uv_udp_getsockname(handle, session_get_sockname(s), &socklen);
+ if (ret) {
+ kr_log_error(IO, "ERROR: getsockname failed: %s\n", uv_strerror(ret));
+ abort(); /* It might be nontrivial not to leak something here. */
+ }
+
+ return io_start_read(h);
+}
+
+void tcp_timeout_trigger(uv_timer_t *timer)
+{
+ struct session *s = timer->data;
+
+ if (kr_fails_assert(!session_flags(s)->closing))
+ return;
+
+ if (!session_tasklist_is_empty(s)) {
+ int finalized = session_tasklist_finalize_expired(s);
+ the_worker->stats.timeout += finalized;
+ /* session_tasklist_finalize_expired() may call worker_task_finalize().
+ * If session is a source session and there were IO errors,
+ * worker_task_finalize() can finalize all tasks and close session. */
+ if (session_flags(s)->closing) {
+ return;
+ }
+
+ }
+ if (!session_tasklist_is_empty(s)) {
+ uv_timer_stop(timer);
+ session_timer_start(s, tcp_timeout_trigger,
+ KR_RESOLVE_TIME_LIMIT / 2,
+ KR_RESOLVE_TIME_LIMIT / 2);
+ } else {
+ /* Normally it should not happen,
+ * but better to check if there anything in this list. */
+ while (!session_waitinglist_is_empty(s)) {
+ struct qr_task *t = session_waitinglist_pop(s, false);
+ worker_task_finalize(t, KR_STATE_FAIL);
+ worker_task_unref(t);
+ the_worker->stats.timeout += 1;
+ if (session_flags(s)->closing) {
+ return;
+ }
+ }
+ const struct network *net = &the_worker->engine->net;
+ uint64_t idle_in_timeout = net->tcp.in_idle_timeout;
+ uint64_t last_activity = session_last_activity(s);
+ uint64_t idle_time = kr_now() - last_activity;
+ if (idle_time < idle_in_timeout) {
+ idle_in_timeout -= idle_time;
+ uv_timer_stop(timer);
+ session_timer_start(s, tcp_timeout_trigger,
+ idle_in_timeout, idle_in_timeout);
+ } else {
+ struct sockaddr *peer = session_get_peer(s);
+ char *peer_str = kr_straddr(peer);
+ kr_log_debug(IO, "=> closing connection to '%s'\n",
+ peer_str ? peer_str : "");
+ if (session_flags(s)->outgoing) {
+ worker_del_tcp_waiting(the_worker, peer);
+ worker_del_tcp_connected(the_worker, peer);
+ }
+ session_close(s);
+ }
+ }
+}
+
+static void tcp_disconnect(struct session *s, int errcode)
+{
+ if (kr_log_is_debug(IO, NULL)) {
+ struct sockaddr *peer = session_get_peer(s);
+ char *peer_str = kr_straddr(peer);
+ kr_log_debug(IO, "=> connection to '%s' closed by peer (%s)\n",
+ peer_str ? peer_str : "",
+ uv_strerror(errcode));
+ }
+
+ if (!session_was_useful(s) && session_flags(s)->outgoing) {
+ /* We want to penalize the IP address, if a task is asking a query.
+ * It might not be the right task, but that doesn't matter so much
+ * for attributing the useless session to the IP address. */
+ struct qr_task *t = session_tasklist_get_first(s);
+ struct kr_query *qry = NULL;
+ if (t) {
+ struct kr_request *req = worker_task_request(t);
+ qry = array_tail(req->rplan.pending);
+ }
+ if (qry) /* We reuse the error for connection, as it's quite similar. */
+ qry->server_selection.error(qry, worker_task_get_transport(t),
+ KR_SELECTION_TCP_CONNECT_FAILED);
+ }
+ worker_end_tcp(s);
+}
+
+static void tcp_recv(uv_stream_t *handle, ssize_t nread, const uv_buf_t *buf)
+{
+ struct session *s = handle->data;
+ if (kr_fails_assert(s && session_get_handle(s) == (uv_handle_t *)handle && handle->type == UV_TCP))
+ return;
+
+ if (session_flags(s)->closing) {
+ return;
+ }
+
+ /* nread might be 0, which does not indicate an error or EOF.
+ * This is equivalent to EAGAIN or EWOULDBLOCK under read(2). */
+ if (nread == 0) {
+ return;
+ }
+
+ if (nread < 0 || !buf->base) {
+ tcp_disconnect(s, nread);
+ return;
+ }
+
+ const uint8_t *data = (const uint8_t *)buf->base;
+ ssize_t data_len = nread;
+ const struct sockaddr *src_addr = session_get_peer(s);
+ const struct sockaddr *dst_addr = NULL;
+ if (!session_flags(s)->outgoing && !session_flags(s)->no_proxy &&
+ proxy_header_present(data, data_len)) {
+ if (!proxy_allowed(&the_worker->engine->net, src_addr)) {
+ if (kr_log_is_debug(IO, NULL)) {
+ kr_log_debug(IO, "<= connection to '%s': PROXYv2 not allowed "
+ "for this peer, close\n",
+ kr_straddr(src_addr));
+ }
+ worker_end_tcp(s);
+ return;
+ }
+
+ struct proxy_result *proxy = session_proxy_create(s);
+ ssize_t trimmed = proxy_process_header(proxy, s, data, data_len);
+ if (trimmed < 0) {
+ if (kr_log_is_debug(IO, NULL)) {
+ if (trimmed == KNOT_EMALF) {
+ kr_log_debug(IO, "<= connection to '%s': "
+ "malformed PROXYv2 header, close\n",
+ kr_straddr(src_addr));
+ } else {
+ kr_log_debug(IO, "<= connection to '%s': "
+ "error processing PROXYv2 header, close\n",
+ kr_straddr(src_addr));
+ }
+ }
+ worker_end_tcp(s);
+ return;
+ } else if (trimmed == 0) {
+ return;
+ }
+
+ if (proxy->command != PROXY2_CMD_LOCAL && proxy->family != AF_UNSPEC) {
+ src_addr = &proxy->src_addr.ip;
+ dst_addr = &proxy->dst_addr.ip;
+
+ if (kr_log_is_debug(IO, NULL)) {
+ kr_log_debug(IO, "<= TCP stream from '%s'\n",
+ kr_straddr(src_addr));
+ kr_log_debug(IO, "<= proxied through '%s'\n",
+ kr_straddr(session_get_peer(s)));
+ }
+ }
+
+ data = session_wirebuf_get_free_start(s);
+ data_len = nread - trimmed;
+ }
+
+ session_flags(s)->no_proxy = true;
+
+ ssize_t consumed = 0;
+ if (session_flags(s)->has_tls) {
+ /* buf->base points to start of the tls receive buffer.
+ Decode data free space in session wire buffer. */
+ consumed = tls_process_input_data(s, data, data_len);
+ if (consumed < 0) {
+ if (kr_log_is_debug(IO, NULL)) {
+ char *peer_str = kr_straddr(src_addr);
+ kr_log_debug(IO, "=> connection to '%s': "
+ "error processing TLS data, close\n",
+ peer_str ? peer_str : "");
+ }
+ worker_end_tcp(s);
+ return;
+ } else if (consumed == 0) {
+ return;
+ }
+ data = session_wirebuf_get_free_start(s);
+ data_len = consumed;
+ }
+#if ENABLE_DOH2
+ int streaming = 1;
+ if (session_flags(s)->has_http) {
+ streaming = http_process_input_data(s, data, data_len,
+ &consumed);
+ if (streaming < 0) {
+ if (kr_log_is_debug(IO, NULL)) {
+ char *peer_str = kr_straddr(src_addr);
+ kr_log_debug(IO, "=> connection to '%s': "
+ "error processing HTTP data, close\n",
+ peer_str ? peer_str : "");
+ }
+ worker_end_tcp(s);
+ return;
+ }
+ if (consumed == 0) {
+ return;
+ }
+ data = session_wirebuf_get_free_start(s);
+ data_len = consumed;
+ }
+#endif
+
+ /* data points to start of the free space in session wire buffer.
+ Simple increase internal counter. */
+ consumed = session_wirebuf_consume(s, data, data_len);
+ kr_assert(consumed == data_len);
+
+ struct io_comm_data comm = {
+ .src_addr = src_addr,
+ .comm_addr = session_get_peer(s),
+ .dst_addr = dst_addr,
+ .proxy = session_proxy_get(s)
+ };
+ int ret = session_wirebuf_process(s, &comm);
+ if (ret < 0) {
+ /* An error has occurred, close the session. */
+ worker_end_tcp(s);
+ }
+ session_wirebuf_compress(s);
+ mp_flush(the_worker->pkt_pool.ctx);
+#if ENABLE_DOH2
+ if (session_flags(s)->has_http && streaming == 0 && ret == 0) {
+ ret = http_send_status(s, HTTP_STATUS_BAD_REQUEST);
+ if (ret) {
+ /* An error has occurred, close the session. */
+ worker_end_tcp(s);
+ }
+ }
+#endif
+}
+
+#if ENABLE_DOH2
+static ssize_t tls_send(const uint8_t *buf, const size_t len, struct session *session)
+{
+ struct tls_ctx *ctx = session_tls_get_server_ctx(session);
+ ssize_t sent = 0;
+ kr_require(ctx);
+
+ sent = gnutls_record_send(ctx->c.tls_session, buf, len);
+ if (sent < 0) {
+ kr_log_debug(DOH, "gnutls_record_send failed: %s (%zd)\n",
+ gnutls_strerror_name(sent), sent);
+ return kr_error(EIO);
+ }
+ return sent;
+}
+#endif
+
+static void _tcp_accept(uv_stream_t *master, int status, bool tls, bool http)
+{
+ if (status != 0) {
+ return;
+ }
+
+ struct worker_ctx *worker = the_worker;
+ uv_tcp_t *client = malloc(sizeof(uv_tcp_t));
+ if (!client) {
+ return;
+ }
+ int res = io_create(master->loop, (uv_handle_t *)client,
+ SOCK_STREAM, AF_UNSPEC, tls, http);
+ if (res) {
+ if (res == UV_EMFILE) {
+ worker->too_many_open = true;
+ worker->rconcurrent_highwatermark = worker->stats.rconcurrent;
+ }
+ /* Since res isn't OK struct session wasn't allocated \ borrowed.
+ * We must release client handle only.
+ */
+ free(client);
+ return;
+ }
+
+ /* struct session was allocated \ borrowed from memory pool. */
+ struct session *s = client->data;
+ kr_require(session_flags(s)->outgoing == false);
+ kr_require(session_flags(s)->has_tls == tls);
+
+ if (uv_accept(master, (uv_stream_t *)client) != 0) {
+ /* close session, close underlying uv handles and
+ * deallocate (or return to memory pool) memory. */
+ session_close(s);
+ return;
+ }
+
+ /* Get peer's and our address. We apparently get specific sockname here
+ * even if we listened on a wildcard address. */
+ struct sockaddr *sa = session_get_peer(s);
+ int sa_len = sizeof(struct sockaddr_in6);
+ int ret = uv_tcp_getpeername(client, sa, &sa_len);
+ if (ret || sa->sa_family == AF_UNSPEC) {
+ session_close(s);
+ return;
+ }
+ sa = session_get_sockname(s);
+ sa_len = sizeof(struct sockaddr_in6);
+ ret = uv_tcp_getsockname(client, sa, &sa_len);
+ if (ret || sa->sa_family == AF_UNSPEC) {
+ session_close(s);
+ return;
+ }
+
+ /* Set deadlines for TCP connection and start reading.
+ * It will re-check every half of a request time limit if the connection
+ * is idle and should be terminated, this is an educated guess. */
+
+ const struct network *net = &worker->engine->net;
+ uint64_t idle_in_timeout = net->tcp.in_idle_timeout;
+
+ uint64_t timeout = KR_CONN_RTT_MAX / 2;
+ if (tls) {
+ timeout += TLS_MAX_HANDSHAKE_TIME;
+ struct tls_ctx *ctx = session_tls_get_server_ctx(s);
+ if (!ctx) {
+ ctx = tls_new(worker);
+ if (!ctx) {
+ session_close(s);
+ return;
+ }
+ ctx->c.session = s;
+ ctx->c.handshake_state = TLS_HS_IN_PROGRESS;
+
+ /* Configure ALPN. */
+ gnutls_datum_t proto;
+ if (!http) {
+ proto.data = (unsigned char *)"dot";
+ proto.size = 3;
+ } else {
+ proto.data = (unsigned char *)"h2";
+ proto.size = 2;
+ }
+ unsigned int flags = 0;
+#if GNUTLS_VERSION_NUMBER >= 0x030500
+ /* Mandatory ALPN means the protocol must match if and
+ * only if ALPN extension is used by the client. */
+ flags |= GNUTLS_ALPN_MANDATORY;
+#endif
+ ret = gnutls_alpn_set_protocols(ctx->c.tls_session, &proto, 1, flags);
+ if (ret != GNUTLS_E_SUCCESS) {
+ session_close(s);
+ return;
+ }
+
+ session_tls_set_server_ctx(s, ctx);
+ }
+ }
+#if ENABLE_DOH2
+ if (http) {
+ struct http_ctx *ctx = session_http_get_server_ctx(s);
+ if (!ctx) {
+ if (!tls) { /* Plain HTTP is not supported. */
+ session_close(s);
+ return;
+ }
+ ctx = http_new(s, tls_send);
+ if (!ctx) {
+ session_close(s);
+ return;
+ }
+ session_http_set_server_ctx(s, ctx);
+ }
+ }
+#endif
+ session_timer_start(s, tcp_timeout_trigger, timeout, idle_in_timeout);
+ io_start_read((uv_handle_t *)client);
+}
+
+static void tcp_accept(uv_stream_t *master, int status)
+{
+ _tcp_accept(master, status, false, false);
+}
+
+static void tls_accept(uv_stream_t *master, int status)
+{
+ _tcp_accept(master, status, true, false);
+}
+
+#if ENABLE_DOH2
+static void https_accept(uv_stream_t *master, int status)
+{
+ _tcp_accept(master, status, true, true);
+}
+#endif
+
+int io_listen_tcp(uv_loop_t *loop, uv_tcp_t *handle, int fd, int tcp_backlog, bool has_tls, bool has_http)
+{
+ uv_connection_cb connection;
+
+ if (!handle) {
+ return kr_error(EINVAL);
+ }
+ int ret = uv_tcp_init(loop, handle);
+ if (ret) return ret;
+
+ if (has_tls && has_http) {
+#if ENABLE_DOH2
+ connection = https_accept;
+#else
+ kr_log_error(IO, "kresd was compiled without libnghttp2 support\n");
+ return kr_error(ENOPROTOOPT);
+#endif
+ } else if (has_tls) {
+ connection = tls_accept;
+ } else if (has_http) {
+ return kr_error(EPROTONOSUPPORT);
+ } else {
+ connection = tcp_accept;
+ }
+
+ ret = uv_tcp_open(handle, (uv_os_sock_t) fd);
+ if (ret) return ret;
+
+ int val; (void)val;
+ /* TCP_DEFER_ACCEPT delays accepting connections until there is readable data. */
+#ifdef TCP_DEFER_ACCEPT
+ val = KR_CONN_RTT_MAX/1000;
+ if (setsockopt(fd, IPPROTO_TCP, TCP_DEFER_ACCEPT, &val, sizeof(val))) {
+ kr_log_error(IO, "listen TCP (defer_accept): %s\n", strerror(errno));
+ }
+#endif
+
+ ret = uv_listen((uv_stream_t *)handle, tcp_backlog, connection);
+ if (ret != 0) {
+ return ret;
+ }
+
+ /* TCP_FASTOPEN enables 1 RTT connection resumptions. */
+#ifdef TCP_FASTOPEN
+ #ifdef __linux__
+ val = 16; /* Accepts queue length hint */
+ #else
+ val = 1; /* Accepts on/off */
+ #endif
+ if (setsockopt(fd, IPPROTO_TCP, TCP_FASTOPEN, &val, sizeof(val))) {
+ kr_log_error(IO, "listen TCP (fastopen): %s%s\n", strerror(errno),
+ (errno != EPERM ? "" :
+ ". This may be caused by TCP Fast Open being disabled in the OS."));
+ }
+#endif
+
+ handle->data = NULL;
+ return 0;
+}
+
+
+enum io_stream_mode {
+ io_mode_text = 0,
+ io_mode_binary = 1,
+};
+
+struct io_stream_data {
+ enum io_stream_mode mode;
+ size_t blen; ///< length of `buf`
+ char *buf; ///< growing buffer residing on `pool` (mp_append_*)
+ knot_mm_t *pool;
+};
+
+/**
+ * TTY control: process input and free() the buffer.
+ *
+ * For parameters see http://docs.libuv.org/en/v1.x/stream.html#c.uv_read_cb
+ *
+ * - This is just basic read-eval-print; libedit is supported through kresc;
+ */
+void io_tty_process_input(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf)
+{
+ auto_free char *commands = buf ? buf->base : NULL;
+
+ /* Set output streams */
+ FILE *out = stdout;
+ uv_os_fd_t stream_fd = -1;
+ struct args *args = the_args;
+ struct io_stream_data *data = (struct io_stream_data*) stream->data;
+ if (nread < 0 || uv_fileno((uv_handle_t *)stream, &stream_fd)) {
+ mp_delete(data->pool->ctx);
+ uv_close((uv_handle_t *)stream, (uv_close_cb) free);
+ return;
+ }
+ if (nread <= 0) {
+ return;
+ }
+ if (stream_fd != STDIN_FILENO) {
+ uv_os_fd_t dup_fd = dup(stream_fd);
+ if (dup_fd >= 0) {
+ out = fdopen(dup_fd, "w");
+ }
+ }
+
+ /** The current single command and the remaining command(s). */
+ char *cmd, *cmd_next = NULL;
+ bool incomplete_cmd = false;
+
+ if (!commands || nread <= 0) {
+ goto finish;
+ }
+
+ /* Execute */
+ if (commands[nread - 1] != '\n') {
+ incomplete_cmd = true;
+ }
+ /* Ensure commands is 0-terminated */
+ if (nread >= buf->len) { /* only equality should be possible */
+ char *newbuf = realloc(commands, nread + 1);
+ if (!newbuf)
+ goto finish;
+ commands = newbuf;
+ }
+ commands[nread] = '\0';
+
+ char *boundary = "\n\0";
+ cmd = strtok(commands, "\n");
+ /* strtok skip '\n' but we need process alone '\n' too */
+ if (commands[0] == '\n') {
+ cmd_next = cmd;
+ cmd = boundary;
+ } else {
+ cmd_next = strtok(NULL, "\n");
+ }
+
+ /** Moving pointer to end of buffer with incomplete command. */
+ char *pbuf = data->buf + data->blen;
+ lua_State *L = the_worker->engine->L;
+ while (cmd != NULL) {
+ /* Last command is incomplete - save it and execute later */
+ if (incomplete_cmd && cmd_next == NULL) {
+ pbuf = mp_append_string(data->pool->ctx, pbuf, cmd);
+ mp_append_char(data->pool->ctx, pbuf, '\0');
+ data->buf = mp_ptr(data->pool->ctx);
+ data->blen = data->blen + strlen(cmd);
+
+ /* There is new incomplete command */
+ if (commands[nread - 1] == '\n')
+ incomplete_cmd = false;
+ goto next_iter;
+ }
+
+ /* Process incomplete command from previously call */
+ if (data->blen > 0) {
+ if (commands[0] != '\n' && commands[0] != '\0') {
+ pbuf = mp_append_string(data->pool->ctx, pbuf, cmd);
+ mp_append_char(data->pool->ctx, pbuf, '\0');
+ data->buf = mp_ptr(data->pool->ctx);
+ cmd = data->buf;
+ } else {
+ cmd = data->buf;
+ }
+ data->blen = 0;
+ pbuf = data->buf;
+ }
+
+ /* Pseudo-command for switching to "binary output"; */
+ if (strcmp(cmd, "__binary") == 0) {
+ data->mode = io_mode_binary;
+ goto next_iter;
+ }
+
+ const bool cmd_failed = engine_cmd(L, cmd, false);
+ const char *message = NULL;
+ size_t len_s;
+ if (lua_gettop(L) > 0) {
+ message = lua_tolstring(L, -1, &len_s);
+ }
+
+ /* Send back the output, either in "binary" or normal mode. */
+ if (data->mode == io_mode_binary) {
+ /* Leader expects length field in all cases */
+ if (!message || len_s > UINT32_MAX) {
+ kr_log_error(IO, "unrepresentable response on control socket, "
+ "sending back empty block (command '%s')\n", cmd);
+ len_s = 0;
+ }
+ uint32_t len_n = htonl(len_s);
+ fwrite(&len_n, sizeof(len_n), 1, out);
+ if (len_s > 0)
+ fwrite(message, len_s, 1, out);
+ } else {
+ if (message)
+ fprintf(out, "%s", message);
+ if (message || !args->quiet)
+ fprintf(out, "\n");
+ if (!args->quiet)
+ fprintf(out, "> ");
+ }
+
+ /* Duplicate command and output to logs */
+ if (cmd_failed) {
+ kr_log_warning(CONTROL, "> %s\n", cmd);
+ if (message)
+ kr_log_warning(CONTROL, "%s\n", message);
+ } else {
+ kr_log_debug(CONTROL, "> %s\n", cmd);
+ if (message)
+ kr_log_debug(CONTROL, "%s\n", message);
+ }
+ next_iter:
+ lua_settop(L, 0); /* not required in some cases but harmless */
+ cmd = cmd_next;
+ cmd_next = strtok(NULL, "\n");
+ }
+
+finish:
+ /* Close if redirected */
+ if (stream_fd != STDIN_FILENO) {
+ fclose(out);
+ }
+}
+
+void io_tty_alloc(uv_handle_t *handle, size_t suggested, uv_buf_t *buf)
+{
+ buf->len = suggested;
+ buf->base = malloc(suggested);
+}
+
+struct io_stream_data *io_tty_alloc_data() {
+ knot_mm_t *pool = mm_ctx_mempool2(MM_DEFAULT_BLKSIZE);
+ if (!pool) {
+ return NULL;
+ }
+ struct io_stream_data *data = mm_alloc(pool, sizeof(struct io_stream_data));
+
+ data->buf = mp_start(pool->ctx, 512);
+ data->mode = io_mode_text;
+ data->blen = 0;
+ data->pool = pool;
+
+ return data;
+}
+
+void io_tty_accept(uv_stream_t *master, int status)
+{
+ /* We can't use any allocations after mp_start() and it's easier anyway. */
+ uv_pipe_t *client = malloc(sizeof(*client));
+ if (!client)
+ return;
+
+ struct io_stream_data *data = io_tty_alloc_data();
+ if (!data) {
+ free(client);
+ return;
+ }
+ client->data = data;
+
+ struct args *args = the_args;
+ uv_pipe_init(master->loop, client, 0);
+ if (uv_accept(master, (uv_stream_t *)client) != 0) {
+ mp_delete(data->pool->ctx);
+ return;
+ }
+ uv_read_start((uv_stream_t *)client, io_tty_alloc, io_tty_process_input);
+
+ /* Write command line */
+ if (!args->quiet) {
+ uv_buf_t buf = { "> ", 2 };
+ uv_try_write((uv_stream_t *)client, &buf, 1);
+ }
+}
+
+int io_listen_pipe(uv_loop_t *loop, uv_pipe_t *handle, int fd)
+{
+ if (!handle) {
+ return kr_error(EINVAL);
+ }
+ int ret = uv_pipe_init(loop, handle, 0);
+ if (ret) return ret;
+
+ ret = uv_pipe_open(handle, fd);
+ if (ret) return ret;
+
+ ret = uv_listen((uv_stream_t *)handle, 16, io_tty_accept);
+ if (ret) return ret;
+
+ handle->data = NULL;
+
+ return 0;
+}
+
+#if ENABLE_XDP
+static void xdp_rx(uv_poll_t* handle, int status, int events)
+{
+ const int XDP_RX_BATCH_SIZE = 64;
+ if (status < 0) {
+ kr_log_error(XDP, "poll status %d: %s\n", status, uv_strerror(status));
+ return;
+ }
+ if (events != UV_READABLE) {
+ kr_log_error(XDP, "poll unexpected events: %d\n", events);
+ return;
+ }
+
+ xdp_handle_data_t *xhd = handle->data;
+ kr_require(xhd && xhd->session && xhd->socket);
+ uint32_t rcvd;
+ knot_xdp_msg_t msgs[XDP_RX_BATCH_SIZE];
+ int ret = knot_xdp_recv(xhd->socket, msgs, XDP_RX_BATCH_SIZE, &rcvd
+ #if KNOT_VERSION_HEX >= 0x030100
+ , NULL
+ #endif
+ );
+
+ if (kr_fails_assert(ret == KNOT_EOK)) {
+ /* ATM other error codes can only be returned when called incorrectly */
+ kr_log_error(XDP, "knot_xdp_recv(): %d, %s\n", ret, knot_strerror(ret));
+ return;
+ }
+ kr_log_debug(XDP, "poll triggered, processing a batch of %d packets\n", (int)rcvd);
+ kr_require(rcvd <= XDP_RX_BATCH_SIZE);
+ for (int i = 0; i < rcvd; ++i) {
+ const knot_xdp_msg_t *msg = &msgs[i];
+ kr_require(msg->payload.iov_len <= KNOT_WIRE_MAX_PKTSIZE);
+ knot_pkt_t *kpkt = knot_pkt_new(msg->payload.iov_base, msg->payload.iov_len,
+ &the_worker->pkt_pool);
+ if (kpkt == NULL) {
+ ret = kr_error(ENOMEM);
+ } else {
+ struct io_comm_data comm = {
+ .src_addr = (const struct sockaddr *)&msg->ip_from,
+ .comm_addr = (const struct sockaddr *)&msg->ip_from,
+ .dst_addr = (const struct sockaddr *)&msg->ip_to
+ };
+ ret = worker_submit(xhd->session, &comm,
+ msg->eth_from, msg->eth_to, kpkt);
+ }
+ if (ret)
+ kr_log_debug(XDP, "worker_submit() == %d: %s\n", ret, kr_strerror(ret));
+ mp_flush(the_worker->pkt_pool.ctx);
+ }
+ knot_xdp_recv_finish(xhd->socket, msgs, rcvd);
+}
+/// Warn if the XDP program is running in emulated mode (XDP_SKB)
+static void xdp_warn_mode(const char *ifname)
+{
+ if (kr_fails_assert(ifname))
+ return;
+
+ const unsigned if_index = if_nametoindex(ifname);
+ if (!if_index) {
+ kr_log_warning(XDP, "warning: interface %s, unexpected error when converting its name: %s\n",
+ ifname, strerror(errno));
+ return;
+ }
+
+ const knot_xdp_mode_t mode = knot_eth_xdp_mode(if_index);
+ switch (mode) {
+ case KNOT_XDP_MODE_FULL:
+ return;
+ case KNOT_XDP_MODE_EMUL:
+ kr_log_warning(XDP, "warning: interface %s running only with XDP emulation\n",
+ ifname);
+ return;
+ case KNOT_XDP_MODE_NONE: // enum warnings from compiler
+ break;
+ }
+ kr_log_warning(XDP, "warning: interface %s running in unexpected XDP mode %d\n",
+ ifname, (int)mode);
+}
+int io_listen_xdp(uv_loop_t *loop, struct endpoint *ep, const char *ifname)
+{
+ if (!ep || !ep->handle) {
+ return kr_error(EINVAL);
+ }
+
+ // RLIMIT_MEMLOCK often needs raising when operating on BPF
+ static int ret_limit = 1;
+ if (ret_limit == 1) {
+ struct rlimit no_limit = { RLIM_INFINITY, RLIM_INFINITY };
+ ret_limit = setrlimit(RLIMIT_MEMLOCK, &no_limit)
+ ? kr_error(errno) : 0;
+ }
+ if (ret_limit) return ret_limit;
+
+ xdp_handle_data_t *xhd = malloc(sizeof(*xhd));
+ if (!xhd) return kr_error(ENOMEM);
+
+ xhd->socket = NULL; // needed for some reason
+
+ // This call is a libknot version hell, unfortunately.
+ int ret = knot_xdp_init(&xhd->socket, ifname, ep->nic_queue,
+ #if KNOT_VERSION_HEX < 0x030100
+ ep->port ? ep->port : KNOT_XDP_LISTEN_PORT_ALL,
+ KNOT_XDP_LOAD_BPF_MAYBE
+ #elif KNOT_VERSION_HEX < 0x030200
+ ep->port ? ep->port : (KNOT_XDP_LISTEN_PORT_PASS | 0),
+ KNOT_XDP_LOAD_BPF_MAYBE
+ #else
+ KNOT_XDP_FILTER_UDP | (ep->port ? 0 : KNOT_XDP_FILTER_PASS),
+ ep->port, 0/*quic_port*/,
+ KNOT_XDP_LOAD_BPF_MAYBE,
+ NULL/*xdp_config*/
+ #endif
+ );
+
+ if (!ret) xdp_warn_mode(ifname);
+
+ if (!ret) ret = uv_idle_init(loop, &xhd->tx_waker);
+ if (ret || kr_fails_assert(xhd->socket)) {
+ free(xhd);
+ return ret == 0 ? kr_error(EINVAL) : kr_error(ret);
+ }
+ xhd->tx_waker.data = xhd->socket;
+
+ ep->fd = knot_xdp_socket_fd(xhd->socket); // probably not useful
+ ret = uv_poll_init(loop, (uv_poll_t *)ep->handle, ep->fd);
+ if (ret) {
+ knot_xdp_deinit(xhd->socket);
+ free(xhd);
+ return kr_error(ret);
+ }
+
+ // beware: this sets poll_handle->data
+ xhd->session = session_new(ep->handle, false, false);
+ kr_require(!session_flags(xhd->session)->outgoing);
+ session_get_sockname(xhd->session)->sa_family = AF_XDP; // to have something in there
+
+ ep->handle->data = xhd;
+ ret = uv_poll_start((uv_poll_t *)ep->handle, UV_READABLE, xdp_rx);
+ return ret;
+}
+#endif
+
+
+int io_create(uv_loop_t *loop, uv_handle_t *handle, int type, unsigned family, bool has_tls, bool has_http)
+{
+ int ret = -1;
+ if (type == SOCK_DGRAM) {
+ ret = uv_udp_init(loop, (uv_udp_t *)handle);
+ } else if (type == SOCK_STREAM) {
+ ret = uv_tcp_init_ex(loop, (uv_tcp_t *)handle, family);
+ uv_tcp_nodelay((uv_tcp_t *)handle, 1);
+ }
+ if (ret != 0) {
+ return ret;
+ }
+ struct session *s = session_new(handle, has_tls, has_http);
+ if (s == NULL) {
+ ret = -1;
+ }
+ return ret;
+}
+
+static void io_deinit(uv_handle_t *handle)
+{
+ if (!handle || !handle->data) {
+ return;
+ }
+ if (handle->type != UV_POLL) {
+ session_free(handle->data);
+ } else {
+ #if ENABLE_XDP
+ xdp_handle_data_t *xhd = handle->data;
+ uv_idle_stop(&xhd->tx_waker);
+ uv_close((uv_handle_t *)&xhd->tx_waker, NULL);
+ session_free(xhd->session);
+ knot_xdp_deinit(xhd->socket);
+ free(xhd);
+ #else
+ kr_assert(false);
+ #endif
+ }
+}
+
+void io_free(uv_handle_t *handle)
+{
+ io_deinit(handle);
+ free(handle);
+}
+
+int io_start_read(uv_handle_t *handle)
+{
+ switch (handle->type) {
+ case UV_UDP:
+ return uv_udp_recv_start((uv_udp_t *)handle, &handle_getbuf, &udp_recv);
+ case UV_TCP:
+ return uv_read_start((uv_stream_t *)handle, &handle_getbuf, &tcp_recv);
+ default:
+ kr_assert(false);
+ return kr_error(EINVAL);
+ }
+}
+
+int io_stop_read(uv_handle_t *handle)
+{
+ if (handle->type == UV_UDP) {
+ return uv_udp_recv_stop((uv_udp_t *)handle);
+ } else {
+ return uv_read_stop((uv_stream_t *)handle);
+ }
+}
diff --git a/daemon/io.h b/daemon/io.h
new file mode 100644
index 0000000..0e88dc1
--- /dev/null
+++ b/daemon/io.h
@@ -0,0 +1,80 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#include <lua.h>
+#include <uv.h>
+#include <libknot/packet/pkt.h>
+#include <gnutls/gnutls.h>
+#include "lib/generic/array.h"
+#include "daemon/worker.h"
+#include "daemon/engine.h"
+
+struct tls_ctx;
+struct tls_client_ctx;
+struct io_stream_data;
+
+/** Communication data. */
+struct io_comm_data {
+ /** The original address the data came from. May be that of a proxied
+ * client, if they came through a proxy. May be `NULL` if
+ * the communication did not come from network. */
+ const struct sockaddr *src_addr;
+
+ /** The actual address the resolver is communicating with. May be
+ * the address of a proxy if the communication came through one,
+ * otherwise it will be the same as `src_addr`. May be `NULL` if
+ * the communication did not come from network. */
+ const struct sockaddr *comm_addr;
+
+ /** The original destination address. May be the resolver's address, or
+ * the address of a proxy if the communication came through one. May be
+ * `NULL` if the communication did not come from network. */
+ const struct sockaddr *dst_addr;
+
+ /** Data parsed from a PROXY header. May be `NULL` if the communication
+ * did not come through a proxy, or if the PROXYv2 protocol was not used. */
+ const struct proxy_result *proxy;
+};
+
+/** Bind address into a file-descriptor (only, no libuv). type is e.g. SOCK_DGRAM */
+int io_bind(const struct sockaddr *addr, int type, const endpoint_flags_t *flags);
+/** Initialize a UDP handle and start listening. */
+int io_listen_udp(uv_loop_t *loop, uv_udp_t *handle, int fd);
+/** Initialize a TCP handle and start listening. */
+int io_listen_tcp(uv_loop_t *loop, uv_tcp_t *handle, int fd, int tcp_backlog, bool has_tls, bool has_http);
+/** Initialize a pipe handle and start listening. */
+int io_listen_pipe(uv_loop_t *loop, uv_pipe_t *handle, int fd);
+/** Initialize a poll handle (ep->handle) and start listening over AF_XDP on ifname.
+ * Sets ep->session. */
+int io_listen_xdp(uv_loop_t *loop, struct endpoint *ep, const char *ifname);
+
+/** Control socket / TTY - related functions. */
+void io_tty_process_input(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf);
+void io_tty_alloc(uv_handle_t *handle, size_t suggested, uv_buf_t *buf);
+void io_tty_accept(uv_stream_t *master, int status);
+struct io_stream_data *io_tty_alloc_data(void);
+
+void tcp_timeout_trigger(uv_timer_t *timer);
+
+/** Initialize the handle, incl. ->data = struct session * instance.
+ * \param type = SOCK_*
+ * \param family = AF_*
+ * \param has_tls has meanings only when type is SOCK_STREAM */
+int io_create(uv_loop_t *loop, uv_handle_t *handle, int type,
+ unsigned family, bool has_tls, bool has_http);
+void io_free(uv_handle_t *handle);
+
+int io_start_read(uv_handle_t *handle);
+int io_stop_read(uv_handle_t *handle);
+
+/** When uv_handle_t::type == UV_POLL, ::data points to this malloc-ed helper.
+ * (Other cases store a direct struct session pointer in ::data.) */
+typedef struct {
+ struct knot_xdp_socket *socket;
+ struct session *session;
+ uv_idle_t tx_waker;
+} xdp_handle_data_t;
+
diff --git a/daemon/lua/controlsock.test.lua b/daemon/lua/controlsock.test.lua
new file mode 100644
index 0000000..0cce03d
--- /dev/null
+++ b/daemon/lua/controlsock.test.lua
@@ -0,0 +1,169 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+local cqsocket = require('cqueues.socket')
+local strerror = require('cqueues.errno').strerror
+local timeout = 5 -- seconds, per socket operation
+
+-- TODO: we get memory leaks from cqueues, but CI runs this without leak detection anyway
+
+local ctrl_sock_txt, ctrl_sock_bin, ctrl_sock_txt_longcmd, ctrl_sock_bin_longcmd
+local ctrl_sock_txt_partcmd, ctrl_sock_bin_partcmd
+
+local function onerr_fail(_, method, errno, stacklevel)
+ local errmsg = string.format('socket error: method %s error %d (%s)',
+ method, errno, strerror(errno))
+ fail(debug.traceback(errmsg, stacklevel))
+end
+
+
+local function switch_to_binary_mode(sock)
+ data = sock:xread(2, nil, timeout)
+ sock:xwrite('__binary\n', nil, timeout)
+ same(data, '> ', 'probably successful switch to binary mode')
+end
+
+local function socket_connect(path)
+ sock = cqsocket.connect({ path = path, nonblock = true })
+ sock:onerror(onerr_fail)
+ sock:setmode('bn', 'bn')
+
+ return sock
+end
+
+local function socket_fixture()
+ local path = worker.cwd..'/control/'..worker.pid
+ same(true, net.listen(path, nil, {kind = 'control'}), 'new control sockets were created')
+
+ ctrl_sock_txt = socket_connect(path)
+ ctrl_sock_txt_longcmd = socket_connect(path)
+ ctrl_sock_txt_partcmd = socket_connect(path)
+
+ ctrl_sock_bin = socket_connect(path)
+ switch_to_binary_mode(ctrl_sock_bin)
+ ctrl_sock_bin_longcmd = socket_connect(path)
+ switch_to_binary_mode(ctrl_sock_bin_longcmd)
+ ctrl_sock_bin_partcmd = socket_connect(path)
+ switch_to_binary_mode(ctrl_sock_bin_partcmd)
+end
+
+local function test_text_prompt()
+ data = ctrl_sock_txt:xread(2, nil, timeout)
+ same(data, '> ', 'text prompt looks like expected')
+end
+
+local function test_text_single_command()
+ local string = "this is test"
+ local input = string.format("'%s'\n", string)
+ local expect = input
+ ctrl_sock_txt:xwrite(input, nil, timeout)
+ data = ctrl_sock_txt:xread(#expect, nil, timeout)
+ same(data, expect,
+ 'text mode returns output in expected format')
+end
+
+local function binary_xread_len(sock)
+ data = sock:xread(4, nil, timeout)
+ local len = tonumber(data:byte(1))
+ for i=2,4 do
+ len = bit.bor(bit.lshift(len, 8), tonumber(data:byte(i)))
+ end
+
+ return len
+end
+
+local function test_binary_more_syscalls()
+ local len
+
+ ctrl_sock_bin:xwrite('worker.p', nil, timeout)
+ worker.sleep(0.01)
+ ctrl_sock_bin:xwrite('id\n', nil, timeout)
+ len = binary_xread_len(ctrl_sock_bin)
+ data = ctrl_sock_bin:xread(len, nil, timeout)
+ same(data, tostring(worker.pid),
+ 'binary mode returns number in expected format')
+
+ ctrl_sock_bin:xwrite('worker.p', nil, timeout)
+ worker.sleep(0.01)
+ ctrl_sock_bin:xwrite('id\nworker.id\n', nil, timeout)
+ len = binary_xread_len(ctrl_sock_bin)
+ data = ctrl_sock_bin:xread(len, nil, timeout)
+ same(data, tostring(worker.pid),
+ 'binary mode returns number in expected format')
+ len = binary_xread_len(ctrl_sock_bin)
+ data = ctrl_sock_bin:xread(len, nil, timeout)
+ same(data, string.format("'%s'", worker.id),
+ 'binary mode returns string in expected format')
+
+ ctrl_sock_bin:xwrite('worker.pid', nil, timeout)
+ worker.sleep(0.01)
+ ctrl_sock_bin:xwrite('\n', nil, timeout)
+ len = binary_xread_len(ctrl_sock_bin)
+ data = ctrl_sock_bin:xread(len, nil, timeout)
+ same(data, tostring(worker.pid),
+ 'binary mode returns output in expected format')
+
+ ctrl_sock_bin:xwrite('worker.pid', nil, timeout)
+ worker.sleep(0.01)
+ ctrl_sock_bin:xwrite('\nworker.id', nil, timeout)
+ worker.sleep(0.01)
+ ctrl_sock_bin:xwrite('\n', nil, timeout)
+ len = binary_xread_len(ctrl_sock_bin)
+ data = ctrl_sock_bin:xread(len, nil, timeout)
+ same(data, tostring(worker.pid),
+ 'binary mode returns number in expected format')
+ len = binary_xread_len(ctrl_sock_bin)
+ data = ctrl_sock_bin:xread(len, nil, timeout)
+ same(data, string.format("'%s'", worker.id),
+ 'binary mode returns string in expected format')
+
+ ctrl_sock_bin:xwrite('worker.pid\nworker.pid\nworker.pid\nworker.pid\n', nil, timeout)
+ len = binary_xread_len(ctrl_sock_bin)
+ data = ctrl_sock_bin:xread(len, nil, timeout)
+ same(data, tostring(worker.pid),
+ 'binary mode returns number in expected format')
+ len = binary_xread_len(ctrl_sock_bin)
+ data = ctrl_sock_bin:xread(len, nil, timeout)
+ same(data, tostring(worker.pid),
+ 'binary mode returns number in expected format')
+ len = binary_xread_len(ctrl_sock_bin)
+ data = ctrl_sock_bin:xread(len, nil, timeout)
+ same(data, tostring(worker.pid),
+ 'binary mode returns number in expected format')
+ len = binary_xread_len(ctrl_sock_bin)
+ data = ctrl_sock_bin:xread(len, nil, timeout)
+ same(data, tostring(worker.pid),
+ 'binary mode returns number in expected format')
+end
+
+local function test_close_incomplete_cmd()
+ ctrl_sock_txt_partcmd:xwrite('worker.p', nil, timeout)
+ ctrl_sock_txt_partcmd:close()
+ pass('close text socket with short incomplete command')
+
+ ctrl_sock_bin_partcmd:xwrite('worker.p', nil, timeout)
+ ctrl_sock_bin_partcmd:close()
+ pass('close binary socket with short incomplete command')
+end
+
+
+local function test_close_during_transfer()
+ ctrl_sock_txt_longcmd:xwrite(string.rep('a', 1024*1024*10), nil, timeout)
+ ctrl_sock_txt_longcmd:close()
+ pass('close text socket with long incomplete command')
+
+ ctrl_sock_bin_longcmd:xwrite(string.rep('a', 1024*1024*10), nil, timeout)
+ ctrl_sock_bin_longcmd:close()
+ pass('close binary socket with long incomplete command')
+end
+
+local tests = {
+ socket_fixture,
+ test_text_prompt, -- prompt after connect
+ test_text_single_command,
+ test_text_prompt, -- new prompt when command is finished
+ test_close_incomplete_cmd,
+ test_close_during_transfer,
+ test_binary_more_syscalls,
+ test_text_single_command, -- command in text mode after execute commands in binary mode
+ test_text_prompt, -- new prompt when command is finished
+}
+return tests
diff --git a/daemon/lua/distro-preconfig.lua.in b/daemon/lua/distro-preconfig.lua.in
new file mode 100644
index 0000000..df155c2
--- /dev/null
+++ b/daemon/lua/distro-preconfig.lua.in
@@ -0,0 +1,19 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+log_target('syslog') -- assume running as OS service
+
+local ffi = require('ffi')
+local id = os.getenv('SYSTEMD_INSTANCE')
+if not id then
+ log_warn(ffi.C.LOG_GRP_SYSTEM, 'environment variable $SYSTEMD_INSTANCE not set')
+else
+ -- Bind to control socket in run_dir
+ worker.control_path = '@run_dir@/control/'
+ local path = worker.control_path..id
+ local ok, err = pcall(net.listen, path, nil, { kind = 'control' })
+ if not ok then
+ log_warn(ffi.C.LOG_GRP_NETWORK, 'bind to '..path..' failed '..err)
+ end
+end
+
+-- Set cache location
+rawset(cache, 'current_storage', 'lmdb://@systemd_cache_dir@')
diff --git a/daemon/lua/kluautil.lua b/daemon/lua/kluautil.lua
new file mode 100644
index 0000000..d8569b9
--- /dev/null
+++ b/daemon/lua/kluautil.lua
@@ -0,0 +1,94 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+
+local ffi = require('ffi')
+local kluautil = {}
+
+-- Get length of table
+function kluautil.kr_table_len(t)
+ if type(t) ~= 'table' then
+ return nil
+ end
+
+ local len = 0
+ for _ in pairs(t) do
+ len = len + 1
+ end
+ return len
+end
+
+-- pack varargs including nil arguments into a table
+function kluautil.kr_table_pack(...)
+ local tab = {...}
+ tab.n = select('#', ...)
+ return tab
+end
+
+-- unpack table produced by kr_table_pack and including nil values
+function kluautil.kr_table_unpack(tab)
+ return unpack(tab, 1, tab.n)
+end
+
+-- Fetch over HTTPS
+function kluautil.kr_https_fetch(url, out_file, ca_file)
+ local http_ok, http_request = pcall(require, 'http.request')
+ local httptls_ok, http_tls = pcall(require, 'http.tls')
+ local openssl_ok, openssl_ctx = pcall(require, 'openssl.ssl.context')
+
+ if not http_ok or not httptls_ok or not openssl_ok then
+ return nil, 'error: lua-http and luaossl libraries are missing (but required)'
+ end
+ local cqerrno = require('cqueues.errno')
+
+ assert(string.match(url, '^https://'))
+
+ local req = http_request.new_from_uri(url)
+ req.tls = true
+ if ca_file then
+ req.ctx = openssl_ctx.new()
+ local store = req.ctx:getStore()
+ local load_ok, errmsg = pcall(store.add, store, ca_file)
+ if not load_ok then
+ return nil, errmsg
+ end
+ else -- use defaults
+ req.ctx = http_tls.new_client_context()
+ end
+
+ req.ctx:setVerify(openssl_ctx.VERIFY_PEER)
+
+ local headers, stream, errmsg = req:go()
+ if not headers then
+ errmsg = errmsg or 'unknown error'
+ if type(errmsg) == 'number' then
+ errmsg = cqerrno.strerror(errmsg) ..
+ ' (' .. tostring(errmsg) .. ')'
+ end
+ return nil, 'HTTP client library error: ' .. errmsg
+ end
+ if headers:get(':status') ~= "200" then
+ return nil, 'HTTP status != 200, got ' .. headers:get(':status')
+ end
+
+ local err
+ err, errmsg = stream:save_body_to_file(out_file)
+ if err == nil then
+ return nil, errmsg
+ end
+
+ out_file:seek('set', 0)
+
+ return true
+end
+
+-- Copy a lua string to C (to knot_mm_t or nil=malloc, zero-terminated).
+function kluautil.kr_string2c(str, mempool)
+ if str == nil then return nil end
+ local result = ffi.C.mm_realloc(mempool, nil, #str + 1, 0)
+ if result == nil then panic("not enough memory") end
+ ffi.copy(result, str)
+ return ffi.cast('const char *', result)
+end
+
+kluautil.list_dir = kluautil_list_dir
+
+return kluautil
diff --git a/daemon/lua/kres-gen-30.lua b/daemon/lua/kres-gen-30.lua
new file mode 100644
index 0000000..4353c5c
--- /dev/null
+++ b/daemon/lua/kres-gen-30.lua
@@ -0,0 +1,638 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+
+local ffi = require('ffi')
+--[[ This file is generated by ./kres-gen.sh ]] ffi.cdef[[
+typedef long time_t;
+typedef long __time_t;
+typedef long __suseconds_t;
+struct timeval {
+ __time_t tv_sec;
+ __suseconds_t tv_usec;
+};
+
+typedef struct knot_dump_style knot_dump_style_t;
+extern const knot_dump_style_t KR_DUMP_STYLE_DEFAULT;
+struct kr_cdb_api {};
+struct lru {};
+typedef enum {KNOT_ANSWER, KNOT_AUTHORITY, KNOT_ADDITIONAL} knot_section_t;
+typedef struct {
+ uint16_t pos;
+ uint16_t flags;
+ uint16_t compress_ptr[16];
+} knot_rrinfo_t;
+typedef unsigned char knot_dname_t;
+typedef struct {
+ uint16_t len;
+ uint8_t data[];
+} knot_rdata_t;
+typedef struct {
+ uint16_t count;
+ uint32_t size;
+ knot_rdata_t *rdata;
+} knot_rdataset_t;
+
+typedef struct knot_mm {
+ void *ctx, *alloc, *free;
+} knot_mm_t;
+
+typedef void *(*map_alloc_f)(void *, size_t);
+typedef void (*map_free_f)(void *baton, void *ptr);
+typedef void (*trace_log_f) (const struct kr_request *, const char *);
+typedef void (*trace_callback_f)(struct kr_request *);
+typedef uint8_t * (*alloc_wire_f)(struct kr_request *req, uint16_t *maxlen);
+typedef bool (*addr_info_f)(struct sockaddr*);
+typedef void (*zi_callback)(int state, void *param);
+typedef struct {
+ knot_dname_t *_owner;
+ uint32_t _ttl;
+ uint16_t type;
+ uint16_t rclass;
+ knot_rdataset_t rrs;
+ void *additional;
+} knot_rrset_t;
+
+struct kr_module;
+typedef char *(kr_prop_cb)(void *, struct kr_module *, const char *);
+typedef unsigned char knot_dname_storage_t[255];
+typedef struct knot_pkt knot_pkt_t;
+typedef struct {
+ uint8_t *ptr[15];
+} knot_edns_options_t;
+typedef struct {
+ knot_pkt_t *pkt;
+ uint16_t pos;
+ uint16_t count;
+} knot_pktsection_t;
+typedef struct knot_compr {
+ uint8_t *wire;
+ knot_rrinfo_t *rrinfo;
+ struct {
+ uint16_t pos;
+ uint8_t labels;
+ } suffix;
+} knot_compr_t;
+struct knot_pkt {
+ uint8_t *wire;
+ size_t size;
+ size_t max_size;
+ size_t parsed;
+ uint16_t reserved;
+ uint16_t qname_size;
+ uint16_t rrset_count;
+ uint16_t flags;
+ knot_rrset_t *opt_rr;
+ knot_rrset_t *tsig_rr;
+ knot_edns_options_t *edns_opts;
+ struct {
+ uint8_t *pos;
+ size_t len;
+ } tsig_wire;
+ knot_section_t current;
+ knot_pktsection_t sections[3];
+ size_t rrset_allocd;
+ knot_rrinfo_t *rr_info;
+ knot_rrset_t *rr;
+ knot_mm_t mm;
+ knot_compr_t compr;
+};
+typedef struct trie trie_t;
+struct kr_qflags {
+ _Bool NO_MINIMIZE : 1;
+ _Bool NO_IPV6 : 1;
+ _Bool NO_IPV4 : 1;
+ _Bool TCP : 1;
+ _Bool NO_ANSWER : 1;
+ _Bool RESOLVED : 1;
+ _Bool AWAIT_IPV4 : 1;
+ _Bool AWAIT_IPV6 : 1;
+ _Bool AWAIT_CUT : 1;
+ _Bool NO_EDNS : 1;
+ _Bool CACHED : 1;
+ _Bool NO_CACHE : 1;
+ _Bool EXPIRING : 1;
+ _Bool ALLOW_LOCAL : 1;
+ _Bool DNSSEC_WANT : 1;
+ _Bool DNSSEC_BOGUS : 1;
+ _Bool DNSSEC_INSECURE : 1;
+ _Bool DNSSEC_CD : 1;
+ _Bool STUB : 1;
+ _Bool ALWAYS_CUT : 1;
+ _Bool DNSSEC_WEXPAND : 1;
+ _Bool PERMISSIVE : 1;
+ _Bool STRICT : 1;
+ _Bool BADCOOKIE_AGAIN : 1;
+ _Bool CNAME : 1;
+ _Bool REORDER_RR : 1;
+ _Bool TRACE : 1;
+ _Bool NO_0X20 : 1;
+ _Bool DNSSEC_NODS : 1;
+ _Bool DNSSEC_OPTOUT : 1;
+ _Bool NONAUTH : 1;
+ _Bool FORWARD : 1;
+ _Bool DNS64_MARK : 1;
+ _Bool CACHE_TRIED : 1;
+ _Bool NO_NS_FOUND : 1;
+ _Bool PKT_IS_SANE : 1;
+ _Bool DNS64_DISABLE : 1;
+};
+typedef struct ranked_rr_array_entry {
+ uint32_t qry_uid;
+ uint8_t rank;
+ uint8_t revalidation_cnt;
+ _Bool cached : 1;
+ _Bool yielded : 1;
+ _Bool to_wire : 1;
+ _Bool expiring : 1;
+ _Bool in_progress : 1;
+ _Bool dont_cache : 1;
+ knot_rrset_t *rr;
+} ranked_rr_array_entry_t;
+typedef struct {
+ ranked_rr_array_entry_t **at;
+ size_t len;
+ size_t cap;
+} ranked_rr_array_t;
+typedef struct kr_http_header_array_entry {
+ char *name;
+ char *value;
+} kr_http_header_array_entry_t;
+typedef struct {
+ kr_http_header_array_entry_t *at;
+ size_t len;
+ size_t cap;
+} kr_http_header_array_t;
+typedef struct {
+ union kr_sockaddr *at;
+ size_t len;
+ size_t cap;
+} kr_sockaddr_array_t;
+struct kr_zonecut {
+ knot_dname_t *name;
+ knot_rrset_t *key;
+ knot_rrset_t *trust_anchor;
+ struct kr_zonecut *parent;
+ trie_t *nsset;
+ knot_mm_t *pool;
+};
+typedef struct {
+ struct kr_query **at;
+ size_t len;
+ size_t cap;
+} kr_qarray_t;
+struct kr_rplan {
+ kr_qarray_t pending;
+ kr_qarray_t resolved;
+ struct kr_query *initial;
+ struct kr_request *request;
+ knot_mm_t *pool;
+ uint32_t next_uid;
+};
+struct kr_request_qsource_flags {
+ _Bool tcp : 1;
+ _Bool tls : 1;
+ _Bool http : 1;
+ _Bool xdp : 1;
+};
+struct kr_extended_error {
+ int32_t info_code;
+ const char *extra_text;
+};
+struct kr_request {
+ struct kr_context *ctx;
+ knot_pkt_t *answer;
+ struct kr_query *current_query;
+ struct {
+ const struct sockaddr *addr;
+ const struct sockaddr *comm_addr;
+ const struct sockaddr *dst_addr;
+ const knot_pkt_t *packet;
+ struct kr_request_qsource_flags flags;
+ struct kr_request_qsource_flags comm_flags;
+ size_t size;
+ int32_t stream_id;
+ kr_http_header_array_t headers;
+ } qsource;
+ struct {
+ unsigned int rtt;
+ const struct kr_transport *transport;
+ } upstream;
+ struct kr_qflags options;
+ int state;
+ ranked_rr_array_t answ_selected;
+ ranked_rr_array_t auth_selected;
+ ranked_rr_array_t add_selected;
+ _Bool answ_validated;
+ _Bool auth_validated;
+ uint8_t rank;
+ struct kr_rplan rplan;
+ trace_log_f trace_log;
+ trace_callback_f trace_finish;
+ int vars_ref;
+ knot_mm_t pool;
+ unsigned int uid;
+ struct {
+ addr_info_f is_tls_capable;
+ addr_info_f is_tcp_connected;
+ addr_info_f is_tcp_waiting;
+ kr_sockaddr_array_t forwarding_targets;
+ } selection_context;
+ unsigned int count_no_nsaddr;
+ unsigned int count_fail_row;
+ alloc_wire_f alloc_wire_cb;
+ struct kr_extended_error extended_error;
+};
+enum kr_rank {KR_RANK_INITIAL, KR_RANK_OMIT, KR_RANK_TRY, KR_RANK_INDET = 4, KR_RANK_BOGUS, KR_RANK_MISMATCH, KR_RANK_MISSING, KR_RANK_INSECURE, KR_RANK_AUTH = 16, KR_RANK_SECURE = 32};
+typedef struct kr_cdb * kr_cdb_pt;
+struct kr_cdb_stats {
+ uint64_t open;
+ uint64_t close;
+ uint64_t count;
+ uint64_t count_entries;
+ uint64_t clear;
+ uint64_t commit;
+ uint64_t read;
+ uint64_t read_miss;
+ uint64_t write;
+ uint64_t remove;
+ uint64_t remove_miss;
+ uint64_t match;
+ uint64_t match_miss;
+ uint64_t read_leq;
+ uint64_t read_leq_miss;
+ double usage_percent;
+};
+typedef struct uv_timer_s uv_timer_t;
+struct kr_cache {
+ kr_cdb_pt db;
+ const struct kr_cdb_api *api;
+ struct kr_cdb_stats stats;
+ uint32_t ttl_min;
+ uint32_t ttl_max;
+ struct timeval checkpoint_walltime;
+ uint64_t checkpoint_monotime;
+ uv_timer_t *health_timer;
+};
+typedef struct kr_layer {
+ int state;
+ struct kr_request *req;
+ const struct kr_layer_api *api;
+ knot_pkt_t *pkt;
+ struct sockaddr *dst;
+ _Bool is_stream;
+} kr_layer_t;
+typedef struct kr_layer_api {
+ int (*begin)(kr_layer_t *);
+ int (*reset)(kr_layer_t *);
+ int (*finish)(kr_layer_t *);
+ int (*consume)(kr_layer_t *, knot_pkt_t *);
+ int (*produce)(kr_layer_t *, knot_pkt_t *);
+ int (*checkout)(kr_layer_t *, knot_pkt_t *, struct sockaddr *, int);
+ int (*answer_finalize)(kr_layer_t *);
+ void *data;
+ int cb_slots[];
+} kr_layer_api_t;
+struct kr_prop {
+ kr_prop_cb *cb;
+ const char *name;
+ const char *info;
+};
+struct kr_module {
+ char *name;
+ int (*init)(struct kr_module *);
+ int (*deinit)(struct kr_module *);
+ int (*config)(struct kr_module *, const char *);
+ const kr_layer_api_t *layer;
+ const struct kr_prop *props;
+ void *lib;
+ void *data;
+};
+struct kr_server_selection {
+ _Bool initialized;
+ void (*choose_transport)(struct kr_query *, struct kr_transport **);
+ void (*update_rtt)(struct kr_query *, const struct kr_transport *, unsigned int);
+ void (*error)(struct kr_query *, const struct kr_transport *, enum kr_selection_error);
+ struct local_state *local_state;
+};
+typedef int kr_log_level_t;
+enum kr_log_group {LOG_GRP_UNKNOWN = -1, LOG_GRP_SYSTEM = 1, LOG_GRP_CACHE, LOG_GRP_IO, LOG_GRP_NETWORK, LOG_GRP_TA, LOG_GRP_TLS, LOG_GRP_GNUTLS, LOG_GRP_TLSCLIENT, LOG_GRP_XDP, LOG_GRP_DOH, LOG_GRP_DNSSEC, LOG_GRP_HINT, LOG_GRP_PLAN, LOG_GRP_ITERATOR, LOG_GRP_VALIDATOR, LOG_GRP_RESOLVER, LOG_GRP_SELECTION, LOG_GRP_ZCUT, LOG_GRP_COOKIES, LOG_GRP_STATISTICS, LOG_GRP_REBIND, LOG_GRP_WORKER, LOG_GRP_POLICY, LOG_GRP_TASENTINEL, LOG_GRP_TASIGNALING, LOG_GRP_TAUPDATE, LOG_GRP_DAF, LOG_GRP_DETECTTIMEJUMP, LOG_GRP_DETECTTIMESKEW, LOG_GRP_GRAPHITE, LOG_GRP_PREFILL, LOG_GRP_PRIMING, LOG_GRP_SRVSTALE, LOG_GRP_WATCHDOG, LOG_GRP_NSID, LOG_GRP_DNSTAP, LOG_GRP_TESTS, LOG_GRP_DOTAUTH, LOG_GRP_HTTP, LOG_GRP_CONTROL, LOG_GRP_MODULE, LOG_GRP_DEVEL, LOG_GRP_RENUMBER, LOG_GRP_EDE, LOG_GRP_REQDBG};
+
+kr_layer_t kr_layer_t_static;
+_Bool kr_dbg_assertion_abort;
+int kr_dbg_assertion_fork;
+
+typedef int32_t (*kr_stale_cb)(int32_t ttl, const knot_dname_t *owner, uint16_t type,
+ const struct kr_query *qry);
+
+void kr_rrset_init(knot_rrset_t *rrset, knot_dname_t *owner,
+ uint16_t type, uint16_t rclass, uint32_t ttl);
+struct kr_query {
+ struct kr_query *parent;
+ knot_dname_t *sname;
+ uint16_t stype;
+ uint16_t sclass;
+ uint16_t id;
+ uint16_t reorder;
+ struct kr_qflags flags;
+ struct kr_qflags forward_flags;
+ uint32_t secret;
+ uint32_t uid;
+ uint64_t creation_time_mono;
+ uint64_t timestamp_mono;
+ struct timeval timestamp;
+ struct kr_zonecut zone_cut;
+ struct kr_layer_pickle *deferred;
+ int8_t cname_depth;
+ struct kr_query *cname_parent;
+ struct kr_request *request;
+ kr_stale_cb stale_cb;
+ struct kr_server_selection server_selection;
+};
+struct kr_context {
+ struct kr_qflags options;
+ knot_rrset_t *downstream_opt_rr;
+ knot_rrset_t *upstream_opt_rr;
+ trie_t *trust_anchors;
+ trie_t *negative_anchors;
+ struct kr_zonecut root_hints;
+ struct kr_cache cache;
+ unsigned int cache_rtt_tout_retry_interval;
+ char _stub[];
+};
+struct kr_transport {
+ knot_dname_t *ns_name;
+ /* beware: hidden stub, to avoid hardcoding sockaddr lengths */
+};
+const char *knot_strerror(int);
+knot_dname_t *knot_dname_copy(const knot_dname_t *, knot_mm_t *);
+knot_dname_t *knot_dname_from_str(uint8_t *, const char *, size_t);
+int knot_dname_in_bailiwick(const knot_dname_t *, const knot_dname_t *);
+_Bool knot_dname_is_equal(const knot_dname_t *, const knot_dname_t *);
+size_t knot_dname_labels(const uint8_t *, const uint8_t *);
+size_t knot_dname_size(const knot_dname_t *);
+void knot_dname_to_lower(knot_dname_t *);
+char *knot_dname_to_str(char *, const knot_dname_t *, size_t);
+knot_rdata_t *knot_rdataset_at(const knot_rdataset_t *, uint16_t);
+int knot_rdataset_merge(knot_rdataset_t *, const knot_rdataset_t *, knot_mm_t *);
+int knot_rrset_add_rdata(knot_rrset_t *, const uint8_t *, uint16_t, knot_mm_t *);
+void knot_rrset_free(knot_rrset_t *, knot_mm_t *);
+int knot_rrset_txt_dump(const knot_rrset_t *, char **, size_t *, const knot_dump_style_t *);
+int knot_rrset_txt_dump_data(const knot_rrset_t *, const size_t, char *, const size_t, const knot_dump_style_t *);
+size_t knot_rrset_size(const knot_rrset_t *);
+int knot_pkt_begin(knot_pkt_t *, knot_section_t);
+int knot_pkt_put_question(knot_pkt_t *, const knot_dname_t *, uint16_t, uint16_t);
+int knot_pkt_put_rotate(knot_pkt_t *, uint16_t, const knot_rrset_t *, uint16_t, uint16_t);
+knot_pkt_t *knot_pkt_new(void *, uint16_t, knot_mm_t *);
+void knot_pkt_free(knot_pkt_t *);
+int knot_pkt_parse(knot_pkt_t *, unsigned int);
+knot_rrset_t *kr_request_ensure_edns(struct kr_request *);
+knot_pkt_t *kr_request_ensure_answer(struct kr_request *);
+int kr_request_set_extended_error(struct kr_request *, int, const char *);
+struct kr_rplan *kr_resolve_plan(struct kr_request *);
+knot_mm_t *kr_resolve_pool(struct kr_request *);
+struct kr_query *kr_rplan_push(struct kr_rplan *, struct kr_query *, const knot_dname_t *, uint16_t, uint16_t);
+int kr_rplan_pop(struct kr_rplan *, struct kr_query *);
+struct kr_query *kr_rplan_resolved(struct kr_rplan *);
+struct kr_query *kr_rplan_last(struct kr_rplan *);
+int kr_forward_add_target(struct kr_request *, const struct sockaddr *);
+_Bool kr_log_is_debug_fun(enum kr_log_group, const struct kr_request *);
+void kr_log_req1(const struct kr_request * const, uint32_t, const unsigned int, enum kr_log_group, const char *, const char *, ...);
+void kr_log_q1(const struct kr_query * const, enum kr_log_group, const char *, const char *, ...);
+const char *kr_log_grp2name(enum kr_log_group);
+void kr_log_fmt(enum kr_log_group, kr_log_level_t, const char *, const char *, const char *, const char *, ...);
+int kr_make_query(struct kr_query *, knot_pkt_t *);
+void kr_pkt_make_auth_header(knot_pkt_t *);
+int kr_pkt_put(knot_pkt_t *, const knot_dname_t *, uint32_t, uint16_t, uint16_t, const uint8_t *, uint16_t);
+int kr_pkt_recycle(knot_pkt_t *);
+int kr_pkt_clear_payload(knot_pkt_t *);
+_Bool kr_pkt_has_wire(const knot_pkt_t *);
+_Bool kr_pkt_has_dnssec(const knot_pkt_t *);
+uint16_t kr_pkt_qclass(const knot_pkt_t *);
+uint16_t kr_pkt_qtype(const knot_pkt_t *);
+char *kr_pkt_text(const knot_pkt_t *);
+void kr_rnd_buffered(void *, unsigned int);
+uint32_t kr_rrsig_sig_inception(const knot_rdata_t *);
+uint32_t kr_rrsig_sig_expiration(const knot_rdata_t *);
+uint16_t kr_rrsig_type_covered(const knot_rdata_t *);
+const char *kr_inaddr(const struct sockaddr *);
+int kr_inaddr_family(const struct sockaddr *);
+int kr_inaddr_len(const struct sockaddr *);
+int kr_inaddr_str(const struct sockaddr *, char *, size_t *);
+int kr_sockaddr_cmp(const struct sockaddr *, const struct sockaddr *);
+int kr_sockaddr_len(const struct sockaddr *);
+uint16_t kr_inaddr_port(const struct sockaddr *);
+int kr_straddr_family(const char *);
+int kr_straddr_subnet(void *, const char *);
+int kr_bitcmp(const char *, const char *, int);
+int kr_family_len(int);
+struct sockaddr *kr_straddr_socket(const char *, int, knot_mm_t *);
+int kr_straddr_split(const char *, char * restrict, uint16_t *);
+_Bool kr_rank_test(uint8_t, uint8_t);
+int kr_ranked_rrarray_add(ranked_rr_array_t *, const knot_rrset_t *, uint8_t, _Bool, uint32_t, knot_mm_t *);
+int kr_ranked_rrarray_finalize(ranked_rr_array_t *, uint32_t, knot_mm_t *);
+void kr_qflags_set(struct kr_qflags *, struct kr_qflags);
+void kr_qflags_clear(struct kr_qflags *, struct kr_qflags);
+int kr_zonecut_add(struct kr_zonecut *, const knot_dname_t *, const void *, int);
+_Bool kr_zonecut_is_empty(struct kr_zonecut *);
+void kr_zonecut_set(struct kr_zonecut *, const knot_dname_t *);
+uint64_t kr_now();
+const char *kr_strptime_diff(const char *, const char *, const char *, double *);
+time_t kr_file_mtime(const char *);
+long long kr_fssize(const char *);
+const char *kr_dirent_name(const struct dirent *);
+void lru_free_items_impl(struct lru *);
+struct lru *lru_create_impl(unsigned int, unsigned int, knot_mm_t *, knot_mm_t *);
+void *lru_get_impl(struct lru *, const char *, unsigned int, unsigned int, _Bool, _Bool *);
+void *mm_realloc(knot_mm_t *, void *, size_t, size_t);
+knot_rrset_t *kr_ta_get(trie_t *, const knot_dname_t *);
+int kr_ta_add(trie_t *, const knot_dname_t *, uint16_t, uint32_t, const uint8_t *, uint16_t);
+int kr_ta_del(trie_t *, const knot_dname_t *);
+void kr_ta_clear(trie_t *);
+_Bool kr_dnssec_key_ksk(const uint8_t *);
+_Bool kr_dnssec_key_revoked(const uint8_t *);
+int kr_dnssec_key_tag(uint16_t, const uint8_t *, size_t);
+int kr_dnssec_key_match(const uint8_t *, size_t, const uint8_t *, size_t);
+int kr_cache_closest_apex(struct kr_cache *, const knot_dname_t *, _Bool, knot_dname_t **);
+int kr_cache_insert_rr(struct kr_cache *, const knot_rrset_t *, const knot_rrset_t *, uint8_t, uint32_t, _Bool);
+int kr_cache_remove(struct kr_cache *, const knot_dname_t *, uint16_t);
+int kr_cache_remove_subtree(struct kr_cache *, const knot_dname_t *, _Bool, int);
+int kr_cache_commit(struct kr_cache *);
+uint32_t packet_ttl(const knot_pkt_t *);
+typedef struct {
+ int sock_type;
+ _Bool tls;
+ _Bool http;
+ _Bool xdp;
+ _Bool freebind;
+ const char *kind;
+} endpoint_flags_t;
+typedef struct {
+ char **at;
+ size_t len;
+ size_t cap;
+} addr_array_t;
+typedef struct {
+ int fd;
+ endpoint_flags_t flags;
+} flagged_fd_t;
+typedef struct {
+ flagged_fd_t *at;
+ size_t len;
+ size_t cap;
+} flagged_fd_array_t;
+typedef struct {
+ const char **at;
+ size_t len;
+ size_t cap;
+} config_array_t;
+struct args {
+ addr_array_t addrs;
+ addr_array_t addrs_tls;
+ flagged_fd_array_t fds;
+ int control_fd;
+ int forks;
+ config_array_t config;
+ const char *rundir;
+ _Bool interactive;
+ _Bool quiet;
+ _Bool tty_binary_output;
+};
+typedef struct {
+ const char *zone_file;
+ const char *origin;
+ uint32_t ttl;
+ enum {ZI_STAMP_NOW, ZI_STAMP_MTIM} time_src;
+ _Bool downgrade;
+ _Bool zonemd;
+ const knot_rrset_t *ds;
+ zi_callback cb;
+ void *cb_param;
+} zi_config_t;
+struct args *the_args;
+struct endpoint {
+ void *handle;
+ int fd;
+ int family;
+ uint16_t port;
+ int16_t nic_queue;
+ _Bool engaged;
+ endpoint_flags_t flags;
+};
+struct request_ctx {
+ struct kr_request req;
+ struct worker_ctx *worker;
+ struct qr_task *task;
+ /* beware: hidden stub, to avoid hardcoding sockaddr lengths */
+};
+struct qr_task {
+ struct request_ctx *ctx;
+ /* beware: hidden stub, to avoid qr_tasklist_t */
+};
+int worker_resolve_exec(struct qr_task *, knot_pkt_t *);
+knot_pkt_t *worker_resolve_mk_pkt(const char *, uint16_t, uint16_t, const struct kr_qflags *);
+struct qr_task *worker_resolve_start(knot_pkt_t *, struct kr_qflags);
+int zi_zone_import(const zi_config_t);
+struct engine {
+ struct kr_context resolver;
+ char _stub[];
+};
+struct worker_ctx {
+ struct engine *engine;
+ char _stub[];
+};
+struct worker_ctx *the_worker;
+typedef struct {
+ uint8_t bitmap[32];
+ uint8_t length;
+} zs_win_t;
+typedef struct {
+ uint8_t excl_flag;
+ uint16_t addr_family;
+ uint8_t prefix_length;
+} zs_apl_t;
+typedef struct {
+ uint32_t d1;
+ uint32_t d2;
+ uint32_t m1;
+ uint32_t m2;
+ uint32_t s1;
+ uint32_t s2;
+ uint32_t alt;
+ uint64_t siz;
+ uint64_t hp;
+ uint64_t vp;
+ int8_t lat_sign;
+ int8_t long_sign;
+ int8_t alt_sign;
+} zs_loc_t;
+typedef enum {ZS_STATE_NONE, ZS_STATE_DATA, ZS_STATE_ERROR, ZS_STATE_INCLUDE, ZS_STATE_EOF, ZS_STATE_STOP} zs_state_t;
+typedef struct zs_scanner zs_scanner_t;
+typedef struct zs_scanner {
+ int cs;
+ int top;
+ int stack[16];
+ _Bool multiline;
+ uint64_t number64;
+ uint64_t number64_tmp;
+ uint32_t decimals;
+ uint32_t decimal_counter;
+ uint32_t item_length;
+ uint32_t item_length_position;
+ uint8_t *item_length_location;
+ uint32_t buffer_length;
+ uint8_t buffer[65535];
+ char include_filename[65535];
+ char *path;
+ zs_win_t windows[256];
+ int16_t last_window;
+ zs_apl_t apl;
+ zs_loc_t loc;
+ uint8_t addr[16];
+ _Bool long_string;
+ uint8_t *dname;
+ uint32_t *dname_length;
+ uint32_t dname_tmp_length;
+ uint32_t r_data_tail;
+ uint32_t zone_origin_length;
+ uint8_t zone_origin[318];
+ uint16_t default_class;
+ uint32_t default_ttl;
+ zs_state_t state;
+ struct {
+ _Bool automatic;
+ void (*record)(zs_scanner_t *);
+ void (*error)(zs_scanner_t *);
+ void (*comment)(zs_scanner_t *);
+ void *data;
+ } process;
+ struct {
+ const char *start;
+ const char *current;
+ const char *end;
+ _Bool eof;
+ _Bool mmaped;
+ } input;
+ struct {
+ char *name;
+ int descriptor;
+ } file;
+ struct {
+ int code;
+ uint64_t counter;
+ _Bool fatal;
+ } error;
+ uint64_t line_counter;
+ uint32_t r_owner_length;
+ uint8_t r_owner[318];
+ uint16_t r_class;
+ uint32_t r_ttl;
+ uint16_t r_type;
+ uint32_t r_data_length;
+ uint8_t r_data[65535];
+} zs_scanner_t;
+void zs_deinit(zs_scanner_t *);
+int zs_init(zs_scanner_t *, const char *, const uint16_t, const uint32_t);
+int zs_parse_record(zs_scanner_t *);
+int zs_set_input_file(zs_scanner_t *, const char *);
+int zs_set_input_string(zs_scanner_t *, const char *, size_t);
+const char *zs_strerror(const int);
+]]
diff --git a/daemon/lua/kres-gen-31.lua b/daemon/lua/kres-gen-31.lua
new file mode 100644
index 0000000..a68dd65
--- /dev/null
+++ b/daemon/lua/kres-gen-31.lua
@@ -0,0 +1,647 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+
+local ffi = require('ffi')
+--[[ This file is generated by ./kres-gen.sh ]] ffi.cdef[[
+typedef long time_t;
+typedef long __time_t;
+typedef long __suseconds_t;
+struct timeval {
+ __time_t tv_sec;
+ __suseconds_t tv_usec;
+};
+
+typedef struct knot_dump_style knot_dump_style_t;
+extern const knot_dump_style_t KR_DUMP_STYLE_DEFAULT;
+struct kr_cdb_api {};
+struct lru {};
+typedef enum {KNOT_ANSWER, KNOT_AUTHORITY, KNOT_ADDITIONAL} knot_section_t;
+typedef struct {
+ uint16_t pos;
+ uint16_t flags;
+ uint16_t compress_ptr[16];
+} knot_rrinfo_t;
+typedef unsigned char knot_dname_t;
+typedef struct {
+ uint16_t len;
+ uint8_t data[];
+} knot_rdata_t;
+typedef struct {
+ uint16_t count;
+ uint32_t size;
+ knot_rdata_t *rdata;
+} knot_rdataset_t;
+
+typedef struct knot_mm {
+ void *ctx, *alloc, *free;
+} knot_mm_t;
+
+typedef void *(*map_alloc_f)(void *, size_t);
+typedef void (*map_free_f)(void *baton, void *ptr);
+typedef void (*trace_log_f) (const struct kr_request *, const char *);
+typedef void (*trace_callback_f)(struct kr_request *);
+typedef uint8_t * (*alloc_wire_f)(struct kr_request *req, uint16_t *maxlen);
+typedef bool (*addr_info_f)(struct sockaddr*);
+typedef void (*zi_callback)(int state, void *param);
+typedef struct {
+ knot_dname_t *_owner;
+ uint32_t _ttl;
+ uint16_t type;
+ uint16_t rclass;
+ knot_rdataset_t rrs;
+ void *additional;
+} knot_rrset_t;
+
+struct kr_module;
+typedef char *(kr_prop_cb)(void *, struct kr_module *, const char *);
+typedef unsigned char knot_dname_storage_t[255];
+typedef struct knot_pkt knot_pkt_t;
+typedef struct {
+ uint8_t *ptr[18];
+} knot_edns_options_t;
+typedef struct {
+ knot_pkt_t *pkt;
+ uint16_t pos;
+ uint16_t count;
+} knot_pktsection_t;
+typedef struct knot_compr {
+ uint8_t *wire;
+ knot_rrinfo_t *rrinfo;
+ struct {
+ uint16_t pos;
+ uint8_t labels;
+ } suffix;
+} knot_compr_t;
+struct knot_pkt {
+ uint8_t *wire;
+ size_t size;
+ size_t max_size;
+ size_t parsed;
+ uint16_t reserved;
+ uint16_t qname_size;
+ uint16_t rrset_count;
+ uint16_t flags;
+ knot_rrset_t *opt_rr;
+ knot_rrset_t *tsig_rr;
+ knot_edns_options_t *edns_opts;
+ struct {
+ uint8_t *pos;
+ size_t len;
+ } tsig_wire;
+ knot_section_t current;
+ knot_pktsection_t sections[3];
+ size_t rrset_allocd;
+ knot_rrinfo_t *rr_info;
+ knot_rrset_t *rr;
+ knot_mm_t mm;
+ knot_compr_t compr;
+};
+typedef struct trie trie_t;
+struct kr_qflags {
+ _Bool NO_MINIMIZE : 1;
+ _Bool NO_IPV6 : 1;
+ _Bool NO_IPV4 : 1;
+ _Bool TCP : 1;
+ _Bool NO_ANSWER : 1;
+ _Bool RESOLVED : 1;
+ _Bool AWAIT_IPV4 : 1;
+ _Bool AWAIT_IPV6 : 1;
+ _Bool AWAIT_CUT : 1;
+ _Bool NO_EDNS : 1;
+ _Bool CACHED : 1;
+ _Bool NO_CACHE : 1;
+ _Bool EXPIRING : 1;
+ _Bool ALLOW_LOCAL : 1;
+ _Bool DNSSEC_WANT : 1;
+ _Bool DNSSEC_BOGUS : 1;
+ _Bool DNSSEC_INSECURE : 1;
+ _Bool DNSSEC_CD : 1;
+ _Bool STUB : 1;
+ _Bool ALWAYS_CUT : 1;
+ _Bool DNSSEC_WEXPAND : 1;
+ _Bool PERMISSIVE : 1;
+ _Bool STRICT : 1;
+ _Bool BADCOOKIE_AGAIN : 1;
+ _Bool CNAME : 1;
+ _Bool REORDER_RR : 1;
+ _Bool TRACE : 1;
+ _Bool NO_0X20 : 1;
+ _Bool DNSSEC_NODS : 1;
+ _Bool DNSSEC_OPTOUT : 1;
+ _Bool NONAUTH : 1;
+ _Bool FORWARD : 1;
+ _Bool DNS64_MARK : 1;
+ _Bool CACHE_TRIED : 1;
+ _Bool NO_NS_FOUND : 1;
+ _Bool PKT_IS_SANE : 1;
+ _Bool DNS64_DISABLE : 1;
+};
+typedef struct ranked_rr_array_entry {
+ uint32_t qry_uid;
+ uint8_t rank;
+ uint8_t revalidation_cnt;
+ _Bool cached : 1;
+ _Bool yielded : 1;
+ _Bool to_wire : 1;
+ _Bool expiring : 1;
+ _Bool in_progress : 1;
+ _Bool dont_cache : 1;
+ knot_rrset_t *rr;
+} ranked_rr_array_entry_t;
+typedef struct {
+ ranked_rr_array_entry_t **at;
+ size_t len;
+ size_t cap;
+} ranked_rr_array_t;
+typedef struct kr_http_header_array_entry {
+ char *name;
+ char *value;
+} kr_http_header_array_entry_t;
+typedef struct {
+ kr_http_header_array_entry_t *at;
+ size_t len;
+ size_t cap;
+} kr_http_header_array_t;
+typedef struct {
+ union kr_sockaddr *at;
+ size_t len;
+ size_t cap;
+} kr_sockaddr_array_t;
+struct kr_zonecut {
+ knot_dname_t *name;
+ knot_rrset_t *key;
+ knot_rrset_t *trust_anchor;
+ struct kr_zonecut *parent;
+ trie_t *nsset;
+ knot_mm_t *pool;
+};
+typedef struct {
+ struct kr_query **at;
+ size_t len;
+ size_t cap;
+} kr_qarray_t;
+struct kr_rplan {
+ kr_qarray_t pending;
+ kr_qarray_t resolved;
+ struct kr_query *initial;
+ struct kr_request *request;
+ knot_mm_t *pool;
+ uint32_t next_uid;
+};
+struct kr_request_qsource_flags {
+ _Bool tcp : 1;
+ _Bool tls : 1;
+ _Bool http : 1;
+ _Bool xdp : 1;
+};
+struct kr_extended_error {
+ int32_t info_code;
+ const char *extra_text;
+};
+struct kr_request {
+ struct kr_context *ctx;
+ knot_pkt_t *answer;
+ struct kr_query *current_query;
+ struct {
+ const struct sockaddr *addr;
+ const struct sockaddr *comm_addr;
+ const struct sockaddr *dst_addr;
+ const knot_pkt_t *packet;
+ struct kr_request_qsource_flags flags;
+ struct kr_request_qsource_flags comm_flags;
+ size_t size;
+ int32_t stream_id;
+ kr_http_header_array_t headers;
+ } qsource;
+ struct {
+ unsigned int rtt;
+ const struct kr_transport *transport;
+ } upstream;
+ struct kr_qflags options;
+ int state;
+ ranked_rr_array_t answ_selected;
+ ranked_rr_array_t auth_selected;
+ ranked_rr_array_t add_selected;
+ _Bool answ_validated;
+ _Bool auth_validated;
+ uint8_t rank;
+ struct kr_rplan rplan;
+ trace_log_f trace_log;
+ trace_callback_f trace_finish;
+ int vars_ref;
+ knot_mm_t pool;
+ unsigned int uid;
+ struct {
+ addr_info_f is_tls_capable;
+ addr_info_f is_tcp_connected;
+ addr_info_f is_tcp_waiting;
+ kr_sockaddr_array_t forwarding_targets;
+ } selection_context;
+ unsigned int count_no_nsaddr;
+ unsigned int count_fail_row;
+ alloc_wire_f alloc_wire_cb;
+ struct kr_extended_error extended_error;
+};
+enum kr_rank {KR_RANK_INITIAL, KR_RANK_OMIT, KR_RANK_TRY, KR_RANK_INDET = 4, KR_RANK_BOGUS, KR_RANK_MISMATCH, KR_RANK_MISSING, KR_RANK_INSECURE, KR_RANK_AUTH = 16, KR_RANK_SECURE = 32};
+typedef struct kr_cdb * kr_cdb_pt;
+struct kr_cdb_stats {
+ uint64_t open;
+ uint64_t close;
+ uint64_t count;
+ uint64_t count_entries;
+ uint64_t clear;
+ uint64_t commit;
+ uint64_t read;
+ uint64_t read_miss;
+ uint64_t write;
+ uint64_t remove;
+ uint64_t remove_miss;
+ uint64_t match;
+ uint64_t match_miss;
+ uint64_t read_leq;
+ uint64_t read_leq_miss;
+ double usage_percent;
+};
+typedef struct uv_timer_s uv_timer_t;
+struct kr_cache {
+ kr_cdb_pt db;
+ const struct kr_cdb_api *api;
+ struct kr_cdb_stats stats;
+ uint32_t ttl_min;
+ uint32_t ttl_max;
+ struct timeval checkpoint_walltime;
+ uint64_t checkpoint_monotime;
+ uv_timer_t *health_timer;
+};
+typedef struct kr_layer {
+ int state;
+ struct kr_request *req;
+ const struct kr_layer_api *api;
+ knot_pkt_t *pkt;
+ struct sockaddr *dst;
+ _Bool is_stream;
+} kr_layer_t;
+typedef struct kr_layer_api {
+ int (*begin)(kr_layer_t *);
+ int (*reset)(kr_layer_t *);
+ int (*finish)(kr_layer_t *);
+ int (*consume)(kr_layer_t *, knot_pkt_t *);
+ int (*produce)(kr_layer_t *, knot_pkt_t *);
+ int (*checkout)(kr_layer_t *, knot_pkt_t *, struct sockaddr *, int);
+ int (*answer_finalize)(kr_layer_t *);
+ void *data;
+ int cb_slots[];
+} kr_layer_api_t;
+struct kr_prop {
+ kr_prop_cb *cb;
+ const char *name;
+ const char *info;
+};
+struct kr_module {
+ char *name;
+ int (*init)(struct kr_module *);
+ int (*deinit)(struct kr_module *);
+ int (*config)(struct kr_module *, const char *);
+ const kr_layer_api_t *layer;
+ const struct kr_prop *props;
+ void *lib;
+ void *data;
+};
+struct kr_server_selection {
+ _Bool initialized;
+ void (*choose_transport)(struct kr_query *, struct kr_transport **);
+ void (*update_rtt)(struct kr_query *, const struct kr_transport *, unsigned int);
+ void (*error)(struct kr_query *, const struct kr_transport *, enum kr_selection_error);
+ struct local_state *local_state;
+};
+typedef int kr_log_level_t;
+enum kr_log_group {LOG_GRP_UNKNOWN = -1, LOG_GRP_SYSTEM = 1, LOG_GRP_CACHE, LOG_GRP_IO, LOG_GRP_NETWORK, LOG_GRP_TA, LOG_GRP_TLS, LOG_GRP_GNUTLS, LOG_GRP_TLSCLIENT, LOG_GRP_XDP, LOG_GRP_DOH, LOG_GRP_DNSSEC, LOG_GRP_HINT, LOG_GRP_PLAN, LOG_GRP_ITERATOR, LOG_GRP_VALIDATOR, LOG_GRP_RESOLVER, LOG_GRP_SELECTION, LOG_GRP_ZCUT, LOG_GRP_COOKIES, LOG_GRP_STATISTICS, LOG_GRP_REBIND, LOG_GRP_WORKER, LOG_GRP_POLICY, LOG_GRP_TASENTINEL, LOG_GRP_TASIGNALING, LOG_GRP_TAUPDATE, LOG_GRP_DAF, LOG_GRP_DETECTTIMEJUMP, LOG_GRP_DETECTTIMESKEW, LOG_GRP_GRAPHITE, LOG_GRP_PREFILL, LOG_GRP_PRIMING, LOG_GRP_SRVSTALE, LOG_GRP_WATCHDOG, LOG_GRP_NSID, LOG_GRP_DNSTAP, LOG_GRP_TESTS, LOG_GRP_DOTAUTH, LOG_GRP_HTTP, LOG_GRP_CONTROL, LOG_GRP_MODULE, LOG_GRP_DEVEL, LOG_GRP_RENUMBER, LOG_GRP_EDE, LOG_GRP_REQDBG};
+
+kr_layer_t kr_layer_t_static;
+_Bool kr_dbg_assertion_abort;
+int kr_dbg_assertion_fork;
+
+typedef int32_t (*kr_stale_cb)(int32_t ttl, const knot_dname_t *owner, uint16_t type,
+ const struct kr_query *qry);
+
+void kr_rrset_init(knot_rrset_t *rrset, knot_dname_t *owner,
+ uint16_t type, uint16_t rclass, uint32_t ttl);
+struct kr_query {
+ struct kr_query *parent;
+ knot_dname_t *sname;
+ uint16_t stype;
+ uint16_t sclass;
+ uint16_t id;
+ uint16_t reorder;
+ struct kr_qflags flags;
+ struct kr_qflags forward_flags;
+ uint32_t secret;
+ uint32_t uid;
+ uint64_t creation_time_mono;
+ uint64_t timestamp_mono;
+ struct timeval timestamp;
+ struct kr_zonecut zone_cut;
+ struct kr_layer_pickle *deferred;
+ int8_t cname_depth;
+ struct kr_query *cname_parent;
+ struct kr_request *request;
+ kr_stale_cb stale_cb;
+ struct kr_server_selection server_selection;
+};
+struct kr_context {
+ struct kr_qflags options;
+ knot_rrset_t *downstream_opt_rr;
+ knot_rrset_t *upstream_opt_rr;
+ trie_t *trust_anchors;
+ trie_t *negative_anchors;
+ struct kr_zonecut root_hints;
+ struct kr_cache cache;
+ unsigned int cache_rtt_tout_retry_interval;
+ char _stub[];
+};
+struct kr_transport {
+ knot_dname_t *ns_name;
+ /* beware: hidden stub, to avoid hardcoding sockaddr lengths */
+};
+const char *knot_strerror(int);
+knot_dname_t *knot_dname_copy(const knot_dname_t *, knot_mm_t *);
+knot_dname_t *knot_dname_from_str(uint8_t *, const char *, size_t);
+int knot_dname_in_bailiwick(const knot_dname_t *, const knot_dname_t *);
+_Bool knot_dname_is_equal(const knot_dname_t *, const knot_dname_t *);
+size_t knot_dname_labels(const uint8_t *, const uint8_t *);
+size_t knot_dname_size(const knot_dname_t *);
+void knot_dname_to_lower(knot_dname_t *);
+char *knot_dname_to_str(char *, const knot_dname_t *, size_t);
+knot_rdata_t *knot_rdataset_at(const knot_rdataset_t *, uint16_t);
+int knot_rdataset_merge(knot_rdataset_t *, const knot_rdataset_t *, knot_mm_t *);
+int knot_rrset_add_rdata(knot_rrset_t *, const uint8_t *, uint16_t, knot_mm_t *);
+void knot_rrset_free(knot_rrset_t *, knot_mm_t *);
+int knot_rrset_txt_dump(const knot_rrset_t *, char **, size_t *, const knot_dump_style_t *);
+int knot_rrset_txt_dump_data(const knot_rrset_t *, const size_t, char *, const size_t, const knot_dump_style_t *);
+size_t knot_rrset_size(const knot_rrset_t *);
+int knot_pkt_begin(knot_pkt_t *, knot_section_t);
+int knot_pkt_put_question(knot_pkt_t *, const knot_dname_t *, uint16_t, uint16_t);
+int knot_pkt_put_rotate(knot_pkt_t *, uint16_t, const knot_rrset_t *, uint16_t, uint16_t);
+knot_pkt_t *knot_pkt_new(void *, uint16_t, knot_mm_t *);
+void knot_pkt_free(knot_pkt_t *);
+int knot_pkt_parse(knot_pkt_t *, unsigned int);
+knot_rrset_t *kr_request_ensure_edns(struct kr_request *);
+knot_pkt_t *kr_request_ensure_answer(struct kr_request *);
+int kr_request_set_extended_error(struct kr_request *, int, const char *);
+struct kr_rplan *kr_resolve_plan(struct kr_request *);
+knot_mm_t *kr_resolve_pool(struct kr_request *);
+struct kr_query *kr_rplan_push(struct kr_rplan *, struct kr_query *, const knot_dname_t *, uint16_t, uint16_t);
+int kr_rplan_pop(struct kr_rplan *, struct kr_query *);
+struct kr_query *kr_rplan_resolved(struct kr_rplan *);
+struct kr_query *kr_rplan_last(struct kr_rplan *);
+int kr_forward_add_target(struct kr_request *, const struct sockaddr *);
+_Bool kr_log_is_debug_fun(enum kr_log_group, const struct kr_request *);
+void kr_log_req1(const struct kr_request * const, uint32_t, const unsigned int, enum kr_log_group, const char *, const char *, ...);
+void kr_log_q1(const struct kr_query * const, enum kr_log_group, const char *, const char *, ...);
+const char *kr_log_grp2name(enum kr_log_group);
+void kr_log_fmt(enum kr_log_group, kr_log_level_t, const char *, const char *, const char *, const char *, ...);
+int kr_make_query(struct kr_query *, knot_pkt_t *);
+void kr_pkt_make_auth_header(knot_pkt_t *);
+int kr_pkt_put(knot_pkt_t *, const knot_dname_t *, uint32_t, uint16_t, uint16_t, const uint8_t *, uint16_t);
+int kr_pkt_recycle(knot_pkt_t *);
+int kr_pkt_clear_payload(knot_pkt_t *);
+_Bool kr_pkt_has_wire(const knot_pkt_t *);
+_Bool kr_pkt_has_dnssec(const knot_pkt_t *);
+uint16_t kr_pkt_qclass(const knot_pkt_t *);
+uint16_t kr_pkt_qtype(const knot_pkt_t *);
+char *kr_pkt_text(const knot_pkt_t *);
+void kr_rnd_buffered(void *, unsigned int);
+uint32_t kr_rrsig_sig_inception(const knot_rdata_t *);
+uint32_t kr_rrsig_sig_expiration(const knot_rdata_t *);
+uint16_t kr_rrsig_type_covered(const knot_rdata_t *);
+const char *kr_inaddr(const struct sockaddr *);
+int kr_inaddr_family(const struct sockaddr *);
+int kr_inaddr_len(const struct sockaddr *);
+int kr_inaddr_str(const struct sockaddr *, char *, size_t *);
+int kr_sockaddr_cmp(const struct sockaddr *, const struct sockaddr *);
+int kr_sockaddr_len(const struct sockaddr *);
+uint16_t kr_inaddr_port(const struct sockaddr *);
+int kr_straddr_family(const char *);
+int kr_straddr_subnet(void *, const char *);
+int kr_bitcmp(const char *, const char *, int);
+int kr_family_len(int);
+struct sockaddr *kr_straddr_socket(const char *, int, knot_mm_t *);
+int kr_straddr_split(const char *, char * restrict, uint16_t *);
+_Bool kr_rank_test(uint8_t, uint8_t);
+int kr_ranked_rrarray_add(ranked_rr_array_t *, const knot_rrset_t *, uint8_t, _Bool, uint32_t, knot_mm_t *);
+int kr_ranked_rrarray_finalize(ranked_rr_array_t *, uint32_t, knot_mm_t *);
+void kr_qflags_set(struct kr_qflags *, struct kr_qflags);
+void kr_qflags_clear(struct kr_qflags *, struct kr_qflags);
+int kr_zonecut_add(struct kr_zonecut *, const knot_dname_t *, const void *, int);
+_Bool kr_zonecut_is_empty(struct kr_zonecut *);
+void kr_zonecut_set(struct kr_zonecut *, const knot_dname_t *);
+uint64_t kr_now();
+const char *kr_strptime_diff(const char *, const char *, const char *, double *);
+time_t kr_file_mtime(const char *);
+long long kr_fssize(const char *);
+const char *kr_dirent_name(const struct dirent *);
+void lru_free_items_impl(struct lru *);
+struct lru *lru_create_impl(unsigned int, unsigned int, knot_mm_t *, knot_mm_t *);
+void *lru_get_impl(struct lru *, const char *, unsigned int, unsigned int, _Bool, _Bool *);
+void *mm_realloc(knot_mm_t *, void *, size_t, size_t);
+knot_rrset_t *kr_ta_get(trie_t *, const knot_dname_t *);
+int kr_ta_add(trie_t *, const knot_dname_t *, uint16_t, uint32_t, const uint8_t *, uint16_t);
+int kr_ta_del(trie_t *, const knot_dname_t *);
+void kr_ta_clear(trie_t *);
+_Bool kr_dnssec_key_ksk(const uint8_t *);
+_Bool kr_dnssec_key_revoked(const uint8_t *);
+int kr_dnssec_key_tag(uint16_t, const uint8_t *, size_t);
+int kr_dnssec_key_match(const uint8_t *, size_t, const uint8_t *, size_t);
+int kr_cache_closest_apex(struct kr_cache *, const knot_dname_t *, _Bool, knot_dname_t **);
+int kr_cache_insert_rr(struct kr_cache *, const knot_rrset_t *, const knot_rrset_t *, uint8_t, uint32_t, _Bool);
+int kr_cache_remove(struct kr_cache *, const knot_dname_t *, uint16_t);
+int kr_cache_remove_subtree(struct kr_cache *, const knot_dname_t *, _Bool, int);
+int kr_cache_commit(struct kr_cache *);
+uint32_t packet_ttl(const knot_pkt_t *);
+typedef struct {
+ int sock_type;
+ _Bool tls;
+ _Bool http;
+ _Bool xdp;
+ _Bool freebind;
+ const char *kind;
+} endpoint_flags_t;
+typedef struct {
+ char **at;
+ size_t len;
+ size_t cap;
+} addr_array_t;
+typedef struct {
+ int fd;
+ endpoint_flags_t flags;
+} flagged_fd_t;
+typedef struct {
+ flagged_fd_t *at;
+ size_t len;
+ size_t cap;
+} flagged_fd_array_t;
+typedef struct {
+ const char **at;
+ size_t len;
+ size_t cap;
+} config_array_t;
+struct args {
+ addr_array_t addrs;
+ addr_array_t addrs_tls;
+ flagged_fd_array_t fds;
+ int control_fd;
+ int forks;
+ config_array_t config;
+ const char *rundir;
+ _Bool interactive;
+ _Bool quiet;
+ _Bool tty_binary_output;
+};
+typedef struct {
+ const char *zone_file;
+ const char *origin;
+ uint32_t ttl;
+ enum {ZI_STAMP_NOW, ZI_STAMP_MTIM} time_src;
+ _Bool downgrade;
+ _Bool zonemd;
+ const knot_rrset_t *ds;
+ zi_callback cb;
+ void *cb_param;
+} zi_config_t;
+struct args *the_args;
+struct endpoint {
+ void *handle;
+ int fd;
+ int family;
+ uint16_t port;
+ int16_t nic_queue;
+ _Bool engaged;
+ endpoint_flags_t flags;
+};
+struct request_ctx {
+ struct kr_request req;
+ struct worker_ctx *worker;
+ struct qr_task *task;
+ /* beware: hidden stub, to avoid hardcoding sockaddr lengths */
+};
+struct qr_task {
+ struct request_ctx *ctx;
+ /* beware: hidden stub, to avoid qr_tasklist_t */
+};
+int worker_resolve_exec(struct qr_task *, knot_pkt_t *);
+knot_pkt_t *worker_resolve_mk_pkt(const char *, uint16_t, uint16_t, const struct kr_qflags *);
+struct qr_task *worker_resolve_start(knot_pkt_t *, struct kr_qflags);
+int zi_zone_import(const zi_config_t);
+struct engine {
+ struct kr_context resolver;
+ char _stub[];
+};
+struct worker_ctx {
+ struct engine *engine;
+ char _stub[];
+};
+struct worker_ctx *the_worker;
+typedef struct {
+ uint8_t *params_position;
+ uint8_t *mandatory_position;
+ uint8_t *param_position;
+ int32_t last_key;
+} zs_svcb_t;
+typedef struct {
+ uint8_t bitmap[32];
+ uint8_t length;
+} zs_win_t;
+typedef struct {
+ uint8_t excl_flag;
+ uint16_t addr_family;
+ uint8_t prefix_length;
+} zs_apl_t;
+typedef struct {
+ uint32_t d1;
+ uint32_t d2;
+ uint32_t m1;
+ uint32_t m2;
+ uint32_t s1;
+ uint32_t s2;
+ uint32_t alt;
+ uint64_t siz;
+ uint64_t hp;
+ uint64_t vp;
+ int8_t lat_sign;
+ int8_t long_sign;
+ int8_t alt_sign;
+} zs_loc_t;
+typedef enum {ZS_STATE_NONE, ZS_STATE_DATA, ZS_STATE_ERROR, ZS_STATE_INCLUDE, ZS_STATE_EOF, ZS_STATE_STOP} zs_state_t;
+typedef struct zs_scanner zs_scanner_t;
+typedef struct zs_scanner {
+ int cs;
+ int top;
+ int stack[16];
+ _Bool multiline;
+ uint64_t number64;
+ uint64_t number64_tmp;
+ uint32_t decimals;
+ uint32_t decimal_counter;
+ uint32_t item_length;
+ uint32_t item_length_position;
+ uint8_t *item_length_location;
+ uint8_t *item_length2_location;
+ uint32_t buffer_length;
+ uint8_t buffer[65535];
+ char include_filename[65535];
+ char *path;
+ zs_win_t windows[256];
+ int16_t last_window;
+ zs_apl_t apl;
+ zs_loc_t loc;
+ zs_svcb_t svcb;
+ uint8_t addr[16];
+ _Bool long_string;
+ _Bool comma_list;
+ uint8_t *dname;
+ uint32_t *dname_length;
+ uint32_t dname_tmp_length;
+ uint32_t r_data_tail;
+ uint32_t zone_origin_length;
+ uint8_t zone_origin[318];
+ uint16_t default_class;
+ uint32_t default_ttl;
+ zs_state_t state;
+ struct {
+ _Bool automatic;
+ void (*record)(zs_scanner_t *);
+ void (*error)(zs_scanner_t *);
+ void (*comment)(zs_scanner_t *);
+ void *data;
+ } process;
+ struct {
+ const char *start;
+ const char *current;
+ const char *end;
+ _Bool eof;
+ _Bool mmaped;
+ } input;
+ struct {
+ char *name;
+ int descriptor;
+ } file;
+ struct {
+ int code;
+ uint64_t counter;
+ _Bool fatal;
+ } error;
+ uint64_t line_counter;
+ uint32_t r_owner_length;
+ uint8_t r_owner[318];
+ uint16_t r_class;
+ uint32_t r_ttl;
+ uint16_t r_type;
+ uint32_t r_data_length;
+ uint8_t r_data[65535];
+} zs_scanner_t;
+void zs_deinit(zs_scanner_t *);
+int zs_init(zs_scanner_t *, const char *, const uint16_t, const uint32_t);
+int zs_parse_record(zs_scanner_t *);
+int zs_set_input_file(zs_scanner_t *, const char *);
+int zs_set_input_string(zs_scanner_t *, const char *, size_t);
+const char *zs_strerror(const int);
+]]
diff --git a/daemon/lua/kres-gen-32.lua b/daemon/lua/kres-gen-32.lua
new file mode 100644
index 0000000..222891e
--- /dev/null
+++ b/daemon/lua/kres-gen-32.lua
@@ -0,0 +1,648 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+
+local ffi = require('ffi')
+--[[ This file is generated by ./kres-gen.sh ]] ffi.cdef[[
+typedef long time_t;
+typedef long __time_t;
+typedef long __suseconds_t;
+struct timeval {
+ __time_t tv_sec;
+ __suseconds_t tv_usec;
+};
+
+typedef struct knot_dump_style knot_dump_style_t;
+extern const knot_dump_style_t KR_DUMP_STYLE_DEFAULT;
+struct kr_cdb_api {};
+struct lru {};
+typedef enum {KNOT_ANSWER, KNOT_AUTHORITY, KNOT_ADDITIONAL} knot_section_t;
+typedef struct {
+ uint16_t pos;
+ uint16_t flags;
+ uint16_t compress_ptr[16];
+} knot_rrinfo_t;
+typedef unsigned char knot_dname_t;
+typedef struct {
+ uint16_t len;
+ uint8_t data[];
+} knot_rdata_t;
+typedef struct {
+ uint16_t count;
+ uint32_t size;
+ knot_rdata_t *rdata;
+} knot_rdataset_t;
+
+typedef struct knot_mm {
+ void *ctx, *alloc, *free;
+} knot_mm_t;
+
+typedef void *(*map_alloc_f)(void *, size_t);
+typedef void (*map_free_f)(void *baton, void *ptr);
+typedef void (*trace_log_f) (const struct kr_request *, const char *);
+typedef void (*trace_callback_f)(struct kr_request *);
+typedef uint8_t * (*alloc_wire_f)(struct kr_request *req, uint16_t *maxlen);
+typedef bool (*addr_info_f)(struct sockaddr*);
+typedef void (*zi_callback)(int state, void *param);
+typedef struct {
+ knot_dname_t *_owner;
+ uint32_t _ttl;
+ uint16_t type;
+ uint16_t rclass;
+ knot_rdataset_t rrs;
+ void *additional;
+} knot_rrset_t;
+
+struct kr_module;
+typedef char *(kr_prop_cb)(void *, struct kr_module *, const char *);
+typedef unsigned char knot_dname_storage_t[255];
+typedef struct knot_pkt knot_pkt_t;
+typedef struct {
+ uint8_t *ptr[18];
+} knot_edns_options_t;
+typedef struct {
+ knot_pkt_t *pkt;
+ uint16_t pos;
+ uint16_t count;
+} knot_pktsection_t;
+typedef struct knot_compr {
+ uint8_t *wire;
+ knot_rrinfo_t *rrinfo;
+ struct {
+ uint16_t pos;
+ uint8_t labels;
+ } suffix;
+} knot_compr_t;
+struct knot_pkt {
+ uint8_t *wire;
+ size_t size;
+ size_t max_size;
+ size_t parsed;
+ uint16_t reserved;
+ uint16_t qname_size;
+ uint16_t rrset_count;
+ uint16_t flags;
+ knot_rrset_t *opt_rr;
+ knot_rrset_t *tsig_rr;
+ knot_edns_options_t *edns_opts;
+ struct {
+ uint8_t *pos;
+ size_t len;
+ } tsig_wire;
+ knot_section_t current;
+ knot_pktsection_t sections[3];
+ size_t rrset_allocd;
+ knot_rrinfo_t *rr_info;
+ knot_rrset_t *rr;
+ knot_mm_t mm;
+ knot_compr_t compr;
+ knot_dname_storage_t lower_qname;
+};
+typedef struct trie trie_t;
+struct kr_qflags {
+ _Bool NO_MINIMIZE : 1;
+ _Bool NO_IPV6 : 1;
+ _Bool NO_IPV4 : 1;
+ _Bool TCP : 1;
+ _Bool NO_ANSWER : 1;
+ _Bool RESOLVED : 1;
+ _Bool AWAIT_IPV4 : 1;
+ _Bool AWAIT_IPV6 : 1;
+ _Bool AWAIT_CUT : 1;
+ _Bool NO_EDNS : 1;
+ _Bool CACHED : 1;
+ _Bool NO_CACHE : 1;
+ _Bool EXPIRING : 1;
+ _Bool ALLOW_LOCAL : 1;
+ _Bool DNSSEC_WANT : 1;
+ _Bool DNSSEC_BOGUS : 1;
+ _Bool DNSSEC_INSECURE : 1;
+ _Bool DNSSEC_CD : 1;
+ _Bool STUB : 1;
+ _Bool ALWAYS_CUT : 1;
+ _Bool DNSSEC_WEXPAND : 1;
+ _Bool PERMISSIVE : 1;
+ _Bool STRICT : 1;
+ _Bool BADCOOKIE_AGAIN : 1;
+ _Bool CNAME : 1;
+ _Bool REORDER_RR : 1;
+ _Bool TRACE : 1;
+ _Bool NO_0X20 : 1;
+ _Bool DNSSEC_NODS : 1;
+ _Bool DNSSEC_OPTOUT : 1;
+ _Bool NONAUTH : 1;
+ _Bool FORWARD : 1;
+ _Bool DNS64_MARK : 1;
+ _Bool CACHE_TRIED : 1;
+ _Bool NO_NS_FOUND : 1;
+ _Bool PKT_IS_SANE : 1;
+ _Bool DNS64_DISABLE : 1;
+};
+typedef struct ranked_rr_array_entry {
+ uint32_t qry_uid;
+ uint8_t rank;
+ uint8_t revalidation_cnt;
+ _Bool cached : 1;
+ _Bool yielded : 1;
+ _Bool to_wire : 1;
+ _Bool expiring : 1;
+ _Bool in_progress : 1;
+ _Bool dont_cache : 1;
+ knot_rrset_t *rr;
+} ranked_rr_array_entry_t;
+typedef struct {
+ ranked_rr_array_entry_t **at;
+ size_t len;
+ size_t cap;
+} ranked_rr_array_t;
+typedef struct kr_http_header_array_entry {
+ char *name;
+ char *value;
+} kr_http_header_array_entry_t;
+typedef struct {
+ kr_http_header_array_entry_t *at;
+ size_t len;
+ size_t cap;
+} kr_http_header_array_t;
+typedef struct {
+ union kr_sockaddr *at;
+ size_t len;
+ size_t cap;
+} kr_sockaddr_array_t;
+struct kr_zonecut {
+ knot_dname_t *name;
+ knot_rrset_t *key;
+ knot_rrset_t *trust_anchor;
+ struct kr_zonecut *parent;
+ trie_t *nsset;
+ knot_mm_t *pool;
+};
+typedef struct {
+ struct kr_query **at;
+ size_t len;
+ size_t cap;
+} kr_qarray_t;
+struct kr_rplan {
+ kr_qarray_t pending;
+ kr_qarray_t resolved;
+ struct kr_query *initial;
+ struct kr_request *request;
+ knot_mm_t *pool;
+ uint32_t next_uid;
+};
+struct kr_request_qsource_flags {
+ _Bool tcp : 1;
+ _Bool tls : 1;
+ _Bool http : 1;
+ _Bool xdp : 1;
+};
+struct kr_extended_error {
+ int32_t info_code;
+ const char *extra_text;
+};
+struct kr_request {
+ struct kr_context *ctx;
+ knot_pkt_t *answer;
+ struct kr_query *current_query;
+ struct {
+ const struct sockaddr *addr;
+ const struct sockaddr *comm_addr;
+ const struct sockaddr *dst_addr;
+ const knot_pkt_t *packet;
+ struct kr_request_qsource_flags flags;
+ struct kr_request_qsource_flags comm_flags;
+ size_t size;
+ int32_t stream_id;
+ kr_http_header_array_t headers;
+ } qsource;
+ struct {
+ unsigned int rtt;
+ const struct kr_transport *transport;
+ } upstream;
+ struct kr_qflags options;
+ int state;
+ ranked_rr_array_t answ_selected;
+ ranked_rr_array_t auth_selected;
+ ranked_rr_array_t add_selected;
+ _Bool answ_validated;
+ _Bool auth_validated;
+ uint8_t rank;
+ struct kr_rplan rplan;
+ trace_log_f trace_log;
+ trace_callback_f trace_finish;
+ int vars_ref;
+ knot_mm_t pool;
+ unsigned int uid;
+ struct {
+ addr_info_f is_tls_capable;
+ addr_info_f is_tcp_connected;
+ addr_info_f is_tcp_waiting;
+ kr_sockaddr_array_t forwarding_targets;
+ } selection_context;
+ unsigned int count_no_nsaddr;
+ unsigned int count_fail_row;
+ alloc_wire_f alloc_wire_cb;
+ struct kr_extended_error extended_error;
+};
+enum kr_rank {KR_RANK_INITIAL, KR_RANK_OMIT, KR_RANK_TRY, KR_RANK_INDET = 4, KR_RANK_BOGUS, KR_RANK_MISMATCH, KR_RANK_MISSING, KR_RANK_INSECURE, KR_RANK_AUTH = 16, KR_RANK_SECURE = 32};
+typedef struct kr_cdb * kr_cdb_pt;
+struct kr_cdb_stats {
+ uint64_t open;
+ uint64_t close;
+ uint64_t count;
+ uint64_t count_entries;
+ uint64_t clear;
+ uint64_t commit;
+ uint64_t read;
+ uint64_t read_miss;
+ uint64_t write;
+ uint64_t remove;
+ uint64_t remove_miss;
+ uint64_t match;
+ uint64_t match_miss;
+ uint64_t read_leq;
+ uint64_t read_leq_miss;
+ double usage_percent;
+};
+typedef struct uv_timer_s uv_timer_t;
+struct kr_cache {
+ kr_cdb_pt db;
+ const struct kr_cdb_api *api;
+ struct kr_cdb_stats stats;
+ uint32_t ttl_min;
+ uint32_t ttl_max;
+ struct timeval checkpoint_walltime;
+ uint64_t checkpoint_monotime;
+ uv_timer_t *health_timer;
+};
+typedef struct kr_layer {
+ int state;
+ struct kr_request *req;
+ const struct kr_layer_api *api;
+ knot_pkt_t *pkt;
+ struct sockaddr *dst;
+ _Bool is_stream;
+} kr_layer_t;
+typedef struct kr_layer_api {
+ int (*begin)(kr_layer_t *);
+ int (*reset)(kr_layer_t *);
+ int (*finish)(kr_layer_t *);
+ int (*consume)(kr_layer_t *, knot_pkt_t *);
+ int (*produce)(kr_layer_t *, knot_pkt_t *);
+ int (*checkout)(kr_layer_t *, knot_pkt_t *, struct sockaddr *, int);
+ int (*answer_finalize)(kr_layer_t *);
+ void *data;
+ int cb_slots[];
+} kr_layer_api_t;
+struct kr_prop {
+ kr_prop_cb *cb;
+ const char *name;
+ const char *info;
+};
+struct kr_module {
+ char *name;
+ int (*init)(struct kr_module *);
+ int (*deinit)(struct kr_module *);
+ int (*config)(struct kr_module *, const char *);
+ const kr_layer_api_t *layer;
+ const struct kr_prop *props;
+ void *lib;
+ void *data;
+};
+struct kr_server_selection {
+ _Bool initialized;
+ void (*choose_transport)(struct kr_query *, struct kr_transport **);
+ void (*update_rtt)(struct kr_query *, const struct kr_transport *, unsigned int);
+ void (*error)(struct kr_query *, const struct kr_transport *, enum kr_selection_error);
+ struct local_state *local_state;
+};
+typedef int kr_log_level_t;
+enum kr_log_group {LOG_GRP_UNKNOWN = -1, LOG_GRP_SYSTEM = 1, LOG_GRP_CACHE, LOG_GRP_IO, LOG_GRP_NETWORK, LOG_GRP_TA, LOG_GRP_TLS, LOG_GRP_GNUTLS, LOG_GRP_TLSCLIENT, LOG_GRP_XDP, LOG_GRP_DOH, LOG_GRP_DNSSEC, LOG_GRP_HINT, LOG_GRP_PLAN, LOG_GRP_ITERATOR, LOG_GRP_VALIDATOR, LOG_GRP_RESOLVER, LOG_GRP_SELECTION, LOG_GRP_ZCUT, LOG_GRP_COOKIES, LOG_GRP_STATISTICS, LOG_GRP_REBIND, LOG_GRP_WORKER, LOG_GRP_POLICY, LOG_GRP_TASENTINEL, LOG_GRP_TASIGNALING, LOG_GRP_TAUPDATE, LOG_GRP_DAF, LOG_GRP_DETECTTIMEJUMP, LOG_GRP_DETECTTIMESKEW, LOG_GRP_GRAPHITE, LOG_GRP_PREFILL, LOG_GRP_PRIMING, LOG_GRP_SRVSTALE, LOG_GRP_WATCHDOG, LOG_GRP_NSID, LOG_GRP_DNSTAP, LOG_GRP_TESTS, LOG_GRP_DOTAUTH, LOG_GRP_HTTP, LOG_GRP_CONTROL, LOG_GRP_MODULE, LOG_GRP_DEVEL, LOG_GRP_RENUMBER, LOG_GRP_EDE, LOG_GRP_REQDBG};
+
+kr_layer_t kr_layer_t_static;
+_Bool kr_dbg_assertion_abort;
+int kr_dbg_assertion_fork;
+
+typedef int32_t (*kr_stale_cb)(int32_t ttl, const knot_dname_t *owner, uint16_t type,
+ const struct kr_query *qry);
+
+void kr_rrset_init(knot_rrset_t *rrset, knot_dname_t *owner,
+ uint16_t type, uint16_t rclass, uint32_t ttl);
+struct kr_query {
+ struct kr_query *parent;
+ knot_dname_t *sname;
+ uint16_t stype;
+ uint16_t sclass;
+ uint16_t id;
+ uint16_t reorder;
+ struct kr_qflags flags;
+ struct kr_qflags forward_flags;
+ uint32_t secret;
+ uint32_t uid;
+ uint64_t creation_time_mono;
+ uint64_t timestamp_mono;
+ struct timeval timestamp;
+ struct kr_zonecut zone_cut;
+ struct kr_layer_pickle *deferred;
+ int8_t cname_depth;
+ struct kr_query *cname_parent;
+ struct kr_request *request;
+ kr_stale_cb stale_cb;
+ struct kr_server_selection server_selection;
+};
+struct kr_context {
+ struct kr_qflags options;
+ knot_rrset_t *downstream_opt_rr;
+ knot_rrset_t *upstream_opt_rr;
+ trie_t *trust_anchors;
+ trie_t *negative_anchors;
+ struct kr_zonecut root_hints;
+ struct kr_cache cache;
+ unsigned int cache_rtt_tout_retry_interval;
+ char _stub[];
+};
+struct kr_transport {
+ knot_dname_t *ns_name;
+ /* beware: hidden stub, to avoid hardcoding sockaddr lengths */
+};
+const char *knot_strerror(int);
+knot_dname_t *knot_dname_copy(const knot_dname_t *, knot_mm_t *);
+knot_dname_t *knot_dname_from_str(uint8_t *, const char *, size_t);
+int knot_dname_in_bailiwick(const knot_dname_t *, const knot_dname_t *);
+_Bool knot_dname_is_equal(const knot_dname_t *, const knot_dname_t *);
+size_t knot_dname_labels(const uint8_t *, const uint8_t *);
+size_t knot_dname_size(const knot_dname_t *);
+void knot_dname_to_lower(knot_dname_t *);
+char *knot_dname_to_str(char *, const knot_dname_t *, size_t);
+knot_rdata_t *knot_rdataset_at(const knot_rdataset_t *, uint16_t);
+int knot_rdataset_merge(knot_rdataset_t *, const knot_rdataset_t *, knot_mm_t *);
+int knot_rrset_add_rdata(knot_rrset_t *, const uint8_t *, uint16_t, knot_mm_t *);
+void knot_rrset_free(knot_rrset_t *, knot_mm_t *);
+int knot_rrset_txt_dump(const knot_rrset_t *, char **, size_t *, const knot_dump_style_t *);
+int knot_rrset_txt_dump_data(const knot_rrset_t *, const size_t, char *, const size_t, const knot_dump_style_t *);
+size_t knot_rrset_size(const knot_rrset_t *);
+int knot_pkt_begin(knot_pkt_t *, knot_section_t);
+int knot_pkt_put_question(knot_pkt_t *, const knot_dname_t *, uint16_t, uint16_t);
+int knot_pkt_put_rotate(knot_pkt_t *, uint16_t, const knot_rrset_t *, uint16_t, uint16_t);
+knot_pkt_t *knot_pkt_new(void *, uint16_t, knot_mm_t *);
+void knot_pkt_free(knot_pkt_t *);
+int knot_pkt_parse(knot_pkt_t *, unsigned int);
+knot_rrset_t *kr_request_ensure_edns(struct kr_request *);
+knot_pkt_t *kr_request_ensure_answer(struct kr_request *);
+int kr_request_set_extended_error(struct kr_request *, int, const char *);
+struct kr_rplan *kr_resolve_plan(struct kr_request *);
+knot_mm_t *kr_resolve_pool(struct kr_request *);
+struct kr_query *kr_rplan_push(struct kr_rplan *, struct kr_query *, const knot_dname_t *, uint16_t, uint16_t);
+int kr_rplan_pop(struct kr_rplan *, struct kr_query *);
+struct kr_query *kr_rplan_resolved(struct kr_rplan *);
+struct kr_query *kr_rplan_last(struct kr_rplan *);
+int kr_forward_add_target(struct kr_request *, const struct sockaddr *);
+_Bool kr_log_is_debug_fun(enum kr_log_group, const struct kr_request *);
+void kr_log_req1(const struct kr_request * const, uint32_t, const unsigned int, enum kr_log_group, const char *, const char *, ...);
+void kr_log_q1(const struct kr_query * const, enum kr_log_group, const char *, const char *, ...);
+const char *kr_log_grp2name(enum kr_log_group);
+void kr_log_fmt(enum kr_log_group, kr_log_level_t, const char *, const char *, const char *, const char *, ...);
+int kr_make_query(struct kr_query *, knot_pkt_t *);
+void kr_pkt_make_auth_header(knot_pkt_t *);
+int kr_pkt_put(knot_pkt_t *, const knot_dname_t *, uint32_t, uint16_t, uint16_t, const uint8_t *, uint16_t);
+int kr_pkt_recycle(knot_pkt_t *);
+int kr_pkt_clear_payload(knot_pkt_t *);
+_Bool kr_pkt_has_wire(const knot_pkt_t *);
+_Bool kr_pkt_has_dnssec(const knot_pkt_t *);
+uint16_t kr_pkt_qclass(const knot_pkt_t *);
+uint16_t kr_pkt_qtype(const knot_pkt_t *);
+char *kr_pkt_text(const knot_pkt_t *);
+void kr_rnd_buffered(void *, unsigned int);
+uint32_t kr_rrsig_sig_inception(const knot_rdata_t *);
+uint32_t kr_rrsig_sig_expiration(const knot_rdata_t *);
+uint16_t kr_rrsig_type_covered(const knot_rdata_t *);
+const char *kr_inaddr(const struct sockaddr *);
+int kr_inaddr_family(const struct sockaddr *);
+int kr_inaddr_len(const struct sockaddr *);
+int kr_inaddr_str(const struct sockaddr *, char *, size_t *);
+int kr_sockaddr_cmp(const struct sockaddr *, const struct sockaddr *);
+int kr_sockaddr_len(const struct sockaddr *);
+uint16_t kr_inaddr_port(const struct sockaddr *);
+int kr_straddr_family(const char *);
+int kr_straddr_subnet(void *, const char *);
+int kr_bitcmp(const char *, const char *, int);
+int kr_family_len(int);
+struct sockaddr *kr_straddr_socket(const char *, int, knot_mm_t *);
+int kr_straddr_split(const char *, char * restrict, uint16_t *);
+_Bool kr_rank_test(uint8_t, uint8_t);
+int kr_ranked_rrarray_add(ranked_rr_array_t *, const knot_rrset_t *, uint8_t, _Bool, uint32_t, knot_mm_t *);
+int kr_ranked_rrarray_finalize(ranked_rr_array_t *, uint32_t, knot_mm_t *);
+void kr_qflags_set(struct kr_qflags *, struct kr_qflags);
+void kr_qflags_clear(struct kr_qflags *, struct kr_qflags);
+int kr_zonecut_add(struct kr_zonecut *, const knot_dname_t *, const void *, int);
+_Bool kr_zonecut_is_empty(struct kr_zonecut *);
+void kr_zonecut_set(struct kr_zonecut *, const knot_dname_t *);
+uint64_t kr_now();
+const char *kr_strptime_diff(const char *, const char *, const char *, double *);
+time_t kr_file_mtime(const char *);
+long long kr_fssize(const char *);
+const char *kr_dirent_name(const struct dirent *);
+void lru_free_items_impl(struct lru *);
+struct lru *lru_create_impl(unsigned int, unsigned int, knot_mm_t *, knot_mm_t *);
+void *lru_get_impl(struct lru *, const char *, unsigned int, unsigned int, _Bool, _Bool *);
+void *mm_realloc(knot_mm_t *, void *, size_t, size_t);
+knot_rrset_t *kr_ta_get(trie_t *, const knot_dname_t *);
+int kr_ta_add(trie_t *, const knot_dname_t *, uint16_t, uint32_t, const uint8_t *, uint16_t);
+int kr_ta_del(trie_t *, const knot_dname_t *);
+void kr_ta_clear(trie_t *);
+_Bool kr_dnssec_key_ksk(const uint8_t *);
+_Bool kr_dnssec_key_revoked(const uint8_t *);
+int kr_dnssec_key_tag(uint16_t, const uint8_t *, size_t);
+int kr_dnssec_key_match(const uint8_t *, size_t, const uint8_t *, size_t);
+int kr_cache_closest_apex(struct kr_cache *, const knot_dname_t *, _Bool, knot_dname_t **);
+int kr_cache_insert_rr(struct kr_cache *, const knot_rrset_t *, const knot_rrset_t *, uint8_t, uint32_t, _Bool);
+int kr_cache_remove(struct kr_cache *, const knot_dname_t *, uint16_t);
+int kr_cache_remove_subtree(struct kr_cache *, const knot_dname_t *, _Bool, int);
+int kr_cache_commit(struct kr_cache *);
+uint32_t packet_ttl(const knot_pkt_t *);
+typedef struct {
+ int sock_type;
+ _Bool tls;
+ _Bool http;
+ _Bool xdp;
+ _Bool freebind;
+ const char *kind;
+} endpoint_flags_t;
+typedef struct {
+ char **at;
+ size_t len;
+ size_t cap;
+} addr_array_t;
+typedef struct {
+ int fd;
+ endpoint_flags_t flags;
+} flagged_fd_t;
+typedef struct {
+ flagged_fd_t *at;
+ size_t len;
+ size_t cap;
+} flagged_fd_array_t;
+typedef struct {
+ const char **at;
+ size_t len;
+ size_t cap;
+} config_array_t;
+struct args {
+ addr_array_t addrs;
+ addr_array_t addrs_tls;
+ flagged_fd_array_t fds;
+ int control_fd;
+ int forks;
+ config_array_t config;
+ const char *rundir;
+ _Bool interactive;
+ _Bool quiet;
+ _Bool tty_binary_output;
+};
+typedef struct {
+ const char *zone_file;
+ const char *origin;
+ uint32_t ttl;
+ enum {ZI_STAMP_NOW, ZI_STAMP_MTIM} time_src;
+ _Bool downgrade;
+ _Bool zonemd;
+ const knot_rrset_t *ds;
+ zi_callback cb;
+ void *cb_param;
+} zi_config_t;
+struct args *the_args;
+struct endpoint {
+ void *handle;
+ int fd;
+ int family;
+ uint16_t port;
+ int16_t nic_queue;
+ _Bool engaged;
+ endpoint_flags_t flags;
+};
+struct request_ctx {
+ struct kr_request req;
+ struct worker_ctx *worker;
+ struct qr_task *task;
+ /* beware: hidden stub, to avoid hardcoding sockaddr lengths */
+};
+struct qr_task {
+ struct request_ctx *ctx;
+ /* beware: hidden stub, to avoid qr_tasklist_t */
+};
+int worker_resolve_exec(struct qr_task *, knot_pkt_t *);
+knot_pkt_t *worker_resolve_mk_pkt(const char *, uint16_t, uint16_t, const struct kr_qflags *);
+struct qr_task *worker_resolve_start(knot_pkt_t *, struct kr_qflags);
+int zi_zone_import(const zi_config_t);
+struct engine {
+ struct kr_context resolver;
+ char _stub[];
+};
+struct worker_ctx {
+ struct engine *engine;
+ char _stub[];
+};
+struct worker_ctx *the_worker;
+typedef struct {
+ uint8_t *params_position;
+ uint8_t *mandatory_position;
+ uint8_t *param_position;
+ int32_t last_key;
+} zs_svcb_t;
+typedef struct {
+ uint8_t bitmap[32];
+ uint8_t length;
+} zs_win_t;
+typedef struct {
+ uint8_t excl_flag;
+ uint16_t addr_family;
+ uint8_t prefix_length;
+} zs_apl_t;
+typedef struct {
+ uint32_t d1;
+ uint32_t d2;
+ uint32_t m1;
+ uint32_t m2;
+ uint32_t s1;
+ uint32_t s2;
+ uint32_t alt;
+ uint64_t siz;
+ uint64_t hp;
+ uint64_t vp;
+ int8_t lat_sign;
+ int8_t long_sign;
+ int8_t alt_sign;
+} zs_loc_t;
+typedef enum {ZS_STATE_NONE, ZS_STATE_DATA, ZS_STATE_ERROR, ZS_STATE_INCLUDE, ZS_STATE_EOF, ZS_STATE_STOP} zs_state_t;
+typedef struct zs_scanner zs_scanner_t;
+typedef struct zs_scanner {
+ int cs;
+ int top;
+ int stack[16];
+ _Bool multiline;
+ uint64_t number64;
+ uint64_t number64_tmp;
+ uint32_t decimals;
+ uint32_t decimal_counter;
+ uint32_t item_length;
+ uint32_t item_length_position;
+ uint8_t *item_length_location;
+ uint8_t *item_length2_location;
+ uint32_t buffer_length;
+ uint8_t buffer[65535];
+ char include_filename[65535];
+ char *path;
+ zs_win_t windows[256];
+ int16_t last_window;
+ zs_apl_t apl;
+ zs_loc_t loc;
+ zs_svcb_t svcb;
+ uint8_t addr[16];
+ _Bool long_string;
+ _Bool comma_list;
+ uint8_t *dname;
+ uint32_t *dname_length;
+ uint32_t dname_tmp_length;
+ uint32_t r_data_tail;
+ uint32_t zone_origin_length;
+ uint8_t zone_origin[318];
+ uint16_t default_class;
+ uint32_t default_ttl;
+ zs_state_t state;
+ struct {
+ _Bool automatic;
+ void (*record)(zs_scanner_t *);
+ void (*error)(zs_scanner_t *);
+ void (*comment)(zs_scanner_t *);
+ void *data;
+ } process;
+ struct {
+ const char *start;
+ const char *current;
+ const char *end;
+ _Bool eof;
+ _Bool mmaped;
+ } input;
+ struct {
+ char *name;
+ int descriptor;
+ } file;
+ struct {
+ int code;
+ uint64_t counter;
+ _Bool fatal;
+ } error;
+ uint64_t line_counter;
+ uint32_t r_owner_length;
+ uint8_t r_owner[318];
+ uint16_t r_class;
+ uint32_t r_ttl;
+ uint16_t r_type;
+ uint32_t r_data_length;
+ uint8_t r_data[65535];
+} zs_scanner_t;
+void zs_deinit(zs_scanner_t *);
+int zs_init(zs_scanner_t *, const char *, const uint16_t, const uint32_t);
+int zs_parse_record(zs_scanner_t *);
+int zs_set_input_file(zs_scanner_t *, const char *);
+int zs_set_input_string(zs_scanner_t *, const char *, size_t);
+const char *zs_strerror(const int);
+]]
diff --git a/daemon/lua/kres-gen.sh b/daemon/lua/kres-gen.sh
new file mode 100755
index 0000000..70afb40
--- /dev/null
+++ b/daemon/lua/kres-gen.sh
@@ -0,0 +1,353 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# Run with "ninja kres-gen" to re-generate $1
+set -o pipefail -o errexit -o nounset
+
+cd "$(dirname ${0})"
+OUTNAME="$1"
+CDEFS="../../scripts/gen-cdefs.sh"
+LIBKRES="${MESON_BUILD_ROOT}/lib/libkres.so"
+KRESD="${MESON_BUILD_ROOT}/daemon/kresd"
+if [ ! -e "$LIBKRES" ]; then
+ # We probably use static libkres.
+ LIBKRES="$KRESD"
+fi
+
+for REQFILE in "$CDEFS" "$LIBKRES" "$KRESD"
+do
+ test '!' -s "$REQFILE" -a -r "$REQFILE" \
+ && echo "Required file $REQFILE cannot be read, did you build binaries and shared libraries?" \
+ && exit 1
+done
+
+# Write to "$OUTNAME" instead of stdout
+mv "$OUTNAME"{,.bak} ||:
+exec 5<&1- # move stdout into FD 5
+exec 1<>"$OUTNAME" # replace stdout with file
+
+restore() {
+ exec 1>&- # close stdout redirected into "$OUTNAME"
+ exec 1<&5- # restore original stdout
+ mv -v "$OUTNAME"{,.fail} ||:
+ mv -v "$OUTNAME"{.bak,} ||:
+ (>&2 echo "Failed to re-generate $OUTNAME! Missing debugsymbols? Missing shared library?")
+}
+trap restore ERR INT TERM
+
+### Dev's guide
+#
+# C declarations for lua are (mostly) generated to simplify maintenance.
+# (Avoid typos, accidental mismatches, etc.)
+#
+# To regenerate the C definitions for lua:
+# - you need to have debugging symbols for knot-dns and knot-resolver;
+# you get those by compiling with -g; for knot-dns it might be enough
+# to just install it with debugging symbols included (in your distro way)
+# - run ninja kres-gen
+# - the knot-dns libraries are found via pkg-config
+# - you also need gdb on $PATH
+
+printf -- "-- SPDX-License-Identifier: GPL-3.0-or-later\n\n"
+printf -- "local ffi = require('ffi')\n"
+printf -- "--[[ This file is generated by ./kres-gen.sh ]] ffi.cdef[[\n"
+
+# Some system dependencies. TODO: this generated part isn't perfectly portable.
+${CDEFS} ${LIBKRES} types <<-EOF
+ typedef time_t
+ __time_t
+ __suseconds_t
+ struct timeval
+EOF
+
+## Various types (mainly), from libknot and libkres
+
+printf "
+typedef struct knot_dump_style knot_dump_style_t;
+extern const knot_dump_style_t KR_DUMP_STYLE_DEFAULT;
+struct kr_cdb_api {};
+struct lru {};
+"
+
+${CDEFS} ${LIBKRES} types <<-EOF
+ knot_section_t
+ knot_rrinfo_t
+ knot_dname_t
+ knot_rdata_t
+ knot_rdataset_t
+EOF
+
+# The generator doesn't work well with typedefs of functions.
+printf "
+typedef struct knot_mm {
+ void *ctx, *alloc, *free;
+} knot_mm_t;
+
+typedef void *(*map_alloc_f)(void *, size_t);
+typedef void (*map_free_f)(void *baton, void *ptr);
+typedef void (*trace_log_f) (const struct kr_request *, const char *);
+typedef void (*trace_callback_f)(struct kr_request *);
+typedef uint8_t * (*alloc_wire_f)(struct kr_request *req, uint16_t *maxlen);
+typedef bool (*addr_info_f)(struct sockaddr*);
+typedef void (*zi_callback)(int state, void *param);
+"
+
+genResType() {
+ echo "$1" | ${CDEFS} ${LIBKRES} types
+}
+
+# No simple way to fixup this rename in ./kres.lua AFAIK.
+genResType "knot_rrset_t" | sed 's/\<owner\>/_owner/; s/\<ttl\>/_ttl/'
+
+printf "
+struct kr_module;
+typedef char *(kr_prop_cb)(void *, struct kr_module *, const char *);
+typedef unsigned char knot_dname_storage_t[255];
+"
+
+${CDEFS} ${LIBKRES} types <<-EOF
+ #knot_pkt_t contains indirect recursion
+ typedef knot_pkt_t
+ knot_edns_options_t
+ knot_pktsection_t
+ knot_compr_t
+ struct knot_pkt
+ #trie_t inside is private to libknot
+ typedef trie_t
+ # libkres
+ struct kr_qflags
+ ranked_rr_array_entry_t
+ ranked_rr_array_t
+ kr_http_header_array_entry_t
+ kr_http_header_array_t
+ kr_sockaddr_array_t
+ struct kr_zonecut
+ kr_qarray_t
+ struct kr_rplan
+ struct kr_request_qsource_flags
+ struct kr_extended_error
+ struct kr_request
+ enum kr_rank
+ typedef kr_cdb_pt
+ struct kr_cdb_stats
+ typedef uv_timer_t
+ struct kr_cache
+ # lib/layer.h
+ kr_layer_t
+ kr_layer_api_t
+ # lib/module.h
+ struct kr_prop
+ struct kr_module
+ struct kr_server_selection
+ kr_log_level_t
+ enum kr_log_group
+EOF
+
+# static variables; these lines might not be simple to generate
+printf "
+kr_layer_t kr_layer_t_static;
+_Bool kr_dbg_assertion_abort;
+int kr_dbg_assertion_fork;
+"
+
+printf "
+typedef int32_t (*kr_stale_cb)(int32_t ttl, const knot_dname_t *owner, uint16_t type,
+ const struct kr_query *qry);
+
+void kr_rrset_init(knot_rrset_t *rrset, knot_dname_t *owner,
+ uint16_t type, uint16_t rclass, uint32_t ttl);
+"
+
+## Some definitions would need too many deps, so shorten them.
+
+genResType "struct kr_query"
+
+genResType "struct kr_context" | sed '/module_array_t/,$ d'
+printf "\tchar _stub[];\n};\n"
+
+
+echo "struct kr_transport" | ${CDEFS} ${KRESD} types | sed '/union /,$ d'
+printf "\t/* beware: hidden stub, to avoid hardcoding sockaddr lengths */\n};\n"
+
+## libknot API
+${CDEFS} libknot functions <<-EOF
+# Utils
+ knot_strerror
+# Domain names
+ knot_dname_copy
+ knot_dname_from_str
+ knot_dname_in_bailiwick
+ knot_dname_is_equal
+ knot_dname_labels
+ knot_dname_size
+ knot_dname_to_lower
+ knot_dname_to_str
+# Resource records
+ knot_rdataset_at
+ knot_rdataset_merge
+ knot_rrset_add_rdata
+ knot_rrset_free
+ knot_rrset_txt_dump
+ knot_rrset_txt_dump_data
+ knot_rrset_size
+# Packet
+ knot_pkt_begin
+ knot_pkt_put_question
+ knot_pkt_put_rotate
+ knot_pkt_new
+ knot_pkt_free
+ knot_pkt_parse
+EOF
+
+## libkres API
+${CDEFS} ${LIBKRES} functions <<-EOF
+# Resolution request
+ kr_request_ensure_edns
+ kr_request_ensure_answer
+ kr_request_set_extended_error
+ kr_resolve_plan
+ kr_resolve_pool
+# Resolution plan
+ kr_rplan_push
+ kr_rplan_pop
+ kr_rplan_resolved
+ kr_rplan_last
+# Forwarding
+ kr_forward_add_target
+# Utils
+ kr_log_is_debug_fun
+ kr_log_req1
+ kr_log_q1
+ kr_log_grp2name
+ kr_log_fmt
+ kr_make_query
+ kr_pkt_make_auth_header
+ kr_pkt_put
+ kr_pkt_recycle
+ kr_pkt_clear_payload
+ kr_pkt_has_wire
+ kr_pkt_has_dnssec
+ kr_pkt_qclass
+ kr_pkt_qtype
+ kr_pkt_text
+ kr_rnd_buffered
+ kr_rrsig_sig_inception
+ kr_rrsig_sig_expiration
+ kr_rrsig_type_covered
+ kr_inaddr
+ kr_inaddr_family
+ kr_inaddr_len
+ kr_inaddr_str
+ kr_sockaddr_cmp
+ kr_sockaddr_len
+ kr_inaddr_port
+ kr_straddr_family
+ kr_straddr_subnet
+ kr_bitcmp
+ kr_family_len
+ kr_straddr_socket
+ kr_straddr_split
+ kr_rank_test
+ kr_ranked_rrarray_add
+ kr_ranked_rrarray_finalize
+ kr_qflags_set
+ kr_qflags_clear
+ kr_zonecut_add
+ kr_zonecut_is_empty
+ kr_zonecut_set
+ kr_now
+ kr_strptime_diff
+ kr_file_mtime
+ kr_fssize
+ kr_dirent_name
+ lru_free_items_impl
+ lru_create_impl
+ lru_get_impl
+ mm_realloc
+# Trust anchors
+ kr_ta_get
+ kr_ta_add
+ kr_ta_del
+ kr_ta_clear
+# DNSSEC
+ kr_dnssec_key_ksk
+ kr_dnssec_key_revoked
+ kr_dnssec_key_tag
+ kr_dnssec_key_match
+# Cache
+ kr_cache_closest_apex
+ kr_cache_insert_rr
+ kr_cache_remove
+ kr_cache_remove_subtree
+ kr_cache_commit
+ # FIXME: perhaps rename this exported symbol
+ packet_ttl
+EOF
+
+
+## kresd itself: worker stuff
+
+${CDEFS} ${KRESD} types <<-EOF
+ endpoint_flags_t
+ # struct args is a bit complex
+ addr_array_t
+ flagged_fd_t
+ flagged_fd_array_t
+ config_array_t
+ struct args
+ zi_config_t
+EOF
+echo "struct args *the_args;"
+
+echo "struct endpoint" | ${CDEFS} ${KRESD} types | sed 's/uv_handle_t \*/void */'
+echo "struct request_ctx" | ${CDEFS} ${KRESD} types | sed '/struct {/,$ d'
+printf "\t/* beware: hidden stub, to avoid hardcoding sockaddr lengths */\n};\n"
+
+echo "struct qr_task" | ${CDEFS} ${KRESD} types | sed '/pktbuf/,$ d'
+printf "\t/* beware: hidden stub, to avoid qr_tasklist_t */\n};\n"
+
+
+${CDEFS} ${KRESD} functions <<-EOF
+ worker_resolve_exec
+ worker_resolve_mk_pkt
+ worker_resolve_start
+ zi_zone_import
+EOF
+
+echo "struct engine" | ${CDEFS} ${KRESD} types | sed '/struct network/,$ d'
+printf "\tchar _stub[];\n};\n"
+
+echo "struct worker_ctx" | ${CDEFS} ${KRESD} types | sed '/uv_loop_t/,$ d'
+printf "\tchar _stub[];\n};\n"
+
+echo "struct worker_ctx *the_worker;"
+
+
+## libzscanner API for ./zonefile.lua
+if pkg-config libknot --atleast-version=3.1; then
+ echo "zs_svcb_t" | ${CDEFS} libzscanner types
+fi
+${CDEFS} libzscanner types <<-EOF
+ zs_win_t
+ zs_apl_t
+ zs_loc_t
+ zs_state_t
+ #zs_scanner_t contains recursion
+ typedef zs_scanner_t
+ zs_scanner_t
+EOF
+${CDEFS} libzscanner functions <<-EOF
+ zs_deinit
+ zs_init
+ zs_parse_record
+ zs_set_input_file
+ zs_set_input_string
+ zs_strerror
+EOF
+
+printf "]]\n"
+
+rm "$OUTNAME".bak ||:
+(>&2 echo "Successfully re-generated ${PWD}/$OUTNAME")
+
+exit 0
diff --git a/daemon/lua/kres.lua b/daemon/lua/kres.lua
new file mode 100644
index 0000000..4dc2b40
--- /dev/null
+++ b/daemon/lua/kres.lua
@@ -0,0 +1,1143 @@
+-- LuaJIT ffi bindings for libkres, a DNS resolver library.
+-- SPDX-License-Identifier: GPL-3.0-or-later
+--
+-- @note Since it's statically compiled, it expects to find the symbols in the C namespace.
+
+local kres -- the module
+
+local kluautil = require('kluautil')
+local ffi = require('ffi')
+local bit = require('bit')
+local bor = bit.bor
+local band = bit.band
+local C = ffi.C
+local knot = ffi.load(libknot_SONAME)
+
+-- Inverse table
+local function itable(t, tolower)
+ local it = {}
+ for k,v in pairs(t) do it[v] = tolower and string.lower(k) or k end
+ return it
+end
+
+-- Byte order conversions
+local function htonl(x) return x end
+local htons = htonl
+if ffi.abi('le') then
+ htonl = bit.bswap
+ function htons(x) return bit.rshift(htonl(x), 16) end
+end
+
+-- Basic types
+local u16_p = ffi.typeof('uint16_t *')
+
+-- Various declarations that are very stable.
+ffi.cdef[[
+/*
+ * Data structures
+ */
+
+struct sockaddr {
+ uint16_t sa_family;
+ uint8_t _stub[]; /* Do not touch */
+};
+
+struct knot_error {
+ int code;
+};
+
+/*
+ * libc APIs
+ */
+void * malloc(size_t size);
+void free(void *ptr);
+int inet_pton(int af, const char *src, void *dst);
+int gettimeofday(struct timeval *tv, struct timezone *tz);
+]]
+
+require('kres-gen')
+
+-- Error code representation
+local knot_error_t = ffi.typeof('struct knot_error')
+ffi.metatype(knot_error_t, {
+ -- Convert libknot error strings
+ __tostring = function(self)
+ return ffi.string(knot.knot_strerror(self.code))
+ end,
+});
+
+-- Constant tables
+local const_class = {
+ IN = 1,
+ CH = 3,
+ NONE = 254,
+ ANY = 255,
+}
+local const_type = {
+ A = 1,
+ NS = 2,
+ MD = 3,
+ MF = 4,
+ CNAME = 5,
+ SOA = 6,
+ MB = 7,
+ MG = 8,
+ MR = 9,
+ NULL = 10,
+ WKS = 11,
+ PTR = 12,
+ HINFO = 13,
+ MINFO = 14,
+ MX = 15,
+ TXT = 16,
+ RP = 17,
+ AFSDB = 18,
+ X25 = 19,
+ ISDN = 20,
+ RT = 21,
+ NSAP = 22,
+ ['NSAP-PTR'] = 23,
+ SIG = 24,
+ KEY = 25,
+ PX = 26,
+ GPOS = 27,
+ AAAA = 28,
+ LOC = 29,
+ NXT = 30,
+ EID = 31,
+ NIMLOC = 32,
+ SRV = 33,
+ ATMA = 34,
+ NAPTR = 35,
+ KX = 36,
+ CERT = 37,
+ A6 = 38,
+ DNAME = 39,
+ SINK = 40,
+ OPT = 41,
+ APL = 42,
+ DS = 43,
+ SSHFP = 44,
+ IPSECKEY = 45,
+ RRSIG = 46,
+ NSEC = 47,
+ DNSKEY = 48,
+ DHCID = 49,
+ NSEC3 = 50,
+ NSEC3PARAM = 51,
+ TLSA = 52,
+ SMIMEA = 53,
+ HIP = 55,
+ NINFO = 56,
+ RKEY = 57,
+ TALINK = 58,
+ CDS = 59,
+ CDNSKEY = 60,
+ OPENPGPKEY = 61,
+ CSYNC = 62,
+ ZONEMD = 63,
+ SVCB = 64,
+ HTTPS = 65,
+
+ SPF = 99,
+ UINFO = 100,
+ UID = 101,
+ GID = 102,
+ UNSPEC = 103,
+ NID = 104,
+ L32 = 105,
+ L64 = 106,
+ LP = 107,
+ EUI48 = 108,
+ EUI64 = 109,
+ TKEY = 249,
+ TSIG = 250,
+ IXFR = 251,
+ AXFR = 252,
+ MAILB = 253,
+ MAILA = 254,
+ ANY = 255,
+ URI = 256,
+ CAA = 257,
+ AVC = 258,
+ DOA = 259,
+ TA = 32768,
+ DLV = 32769,
+}
+local const_section = {
+ ANSWER = 0,
+ AUTHORITY = 1,
+ ADDITIONAL = 2,
+}
+local const_opcode = {
+ QUERY = 0,
+ IQUERY = 1,
+ STATUS = 2,
+ NOTIFY = 4,
+ UPDATE = 5,
+}
+local const_rcode = {
+ NOERROR = 0,
+ FORMERR = 1,
+ SERVFAIL = 2,
+ NXDOMAIN = 3,
+ NOTIMPL = 4,
+ REFUSED = 5,
+ YXDOMAIN = 6,
+ YXRRSET = 7,
+ NXRRSET = 8,
+ NOTAUTH = 9,
+ NOTZONE = 10,
+ BADVERS = 16,
+ BADCOOKIE = 23,
+}
+-- This corresponds to `enum kr_rank`, it's not possible to do this without introspection unfortunately
+local const_rank = {
+ INITIAL = 0,
+ OMIT = 1,
+ TRY = 2,
+ INDET = 4,
+ BOGUS = 5,
+ MISMATCH = 6,
+ MISSING = 7,
+ INSECURE = 8,
+ AUTH = 16,
+ SECURE = 32
+}
+local const_extended_error = {
+ NONE = -1,
+ OTHER = 0,
+ DNSKEY_ALG = 1,
+ DS_DIGEST = 2,
+ STALE = 3,
+ FORGED = 4,
+ INDETERMINATE = 5,
+ BOGUS = 6,
+ SIG_EXPIRED = 7,
+ SIG_NOTYET = 8,
+ DNSKEY_MISS = 9,
+ RRSIG_MISS = 10,
+ DNSKEY_BIT = 11,
+ NSEC_MISS = 12,
+ CACHED_ERR = 13,
+ NOT_READY = 14,
+ BLOCKED = 15,
+ CENSORED = 16,
+ FILTERED = 17,
+ PROHIBITED = 18,
+ STALE_NXD = 19,
+ NOTAUTH = 20,
+ NOTSUP = 21,
+ NREACH_AUTH = 22,
+ NETWORK = 23,
+ INV_DATA = 24,
+}
+
+-- Constant tables
+local const_class_str = itable(const_class)
+local const_type_str = itable(const_type)
+local const_rcode_str = itable(const_rcode)
+local const_opcode_str = itable(const_opcode)
+local const_section_str = itable(const_section)
+local const_rank_str = itable(const_rank)
+local const_extended_error_str = itable(const_extended_error)
+
+-- Metatype for RR types to allow anonymous types
+setmetatable(const_type, {
+ __index = function (t, k)
+ local v = rawget(t, k)
+ if v then return v end
+ -- Allow TYPE%d notation
+ if string.find(k, 'TYPE', 1, true) then
+ return tonumber(k:sub(5))
+ end
+ -- Unknown type
+ return
+ end
+})
+
+-- Metatype for RR types to allow anonymous string types
+setmetatable(const_type_str, {
+ __index = function (t, k)
+ local v = rawget(t, k)
+ if v then return v end
+ return string.format('TYPE%d', k)
+ end
+})
+
+-- Metatype for timeval
+local timeval_t = ffi.typeof('struct timeval')
+
+-- Metatype for sockaddr
+local addr_buf = ffi.new('char[16]')
+local str_addr_buf = ffi.new('char[46 + 1 + 6 + 1]') -- INET6_ADDRSTRLEN + #port + \0
+local str_addr_buf_len = ffi.sizeof(str_addr_buf)
+local sockaddr_t = ffi.typeof('struct sockaddr')
+ffi.metatype( sockaddr_t, {
+ __index = {
+ len = function(sa) return C.kr_inaddr_len(sa) end,
+ ip = function (sa) return C.kr_inaddr(sa) end,
+ family = function (sa) return C.kr_inaddr_family(sa) end,
+ port = function (sa) return C.kr_inaddr_port(sa) end,
+ },
+ __tostring = function(sa)
+ assert(ffi.istype(sockaddr_t, sa))
+ local len = ffi.new('size_t[1]', str_addr_buf_len)
+ local ret = C.kr_inaddr_str(sa, str_addr_buf, len)
+ if ret ~= 0 then
+ error('kr_inaddr_str failed: ' .. tostring(ret))
+ end
+ return ffi.string(str_addr_buf)
+ end,
+
+})
+
+-- Parametrized LRU table
+local typed_lru_t = 'struct { $ value_type[1]; struct lru * lru; }'
+
+-- Metatype for LRU
+local lru_metatype = {
+ -- Create a new LRU with given value type
+ -- By default the LRU will have a capacity of 65536 elements
+ -- Note: At the point the parametrized type must be finalized
+ __new = function (ct, max_slots, alignment)
+ -- {0} will make sure that the value is coercible to a number
+ local o = ffi.new(ct, {0}, C.lru_create_impl(max_slots or 65536, alignment or 1, nil, nil))
+ if o.lru == nil then
+ return
+ end
+ return o
+ end,
+ -- Destructor to clean allocated memory
+ __gc = function (self)
+ assert(self.lru ~= nil)
+ C.lru_free_items_impl(self.lru)
+ C.free(self.lru)
+ self.lru = nil
+ end,
+ __index = {
+ -- Look up key and return reference to current
+ -- Note: The key will be inserted if it doesn't exist
+ get_ref = function (self, key, key_len, allow_insert)
+ local insert = allow_insert and true or false
+ local ptr = C.lru_get_impl(self.lru, key, key_len or #key, ffi.sizeof(self.value_type[0]), insert, nil)
+ if ptr ~= nil then
+ return ffi.cast(self.value_type, ptr)
+ end
+ end,
+ -- Look up key and return current value
+ get = function (self, key, key_len)
+ local ref = self:get_ref(key, key_len, false)
+ if ref then
+ return ref[0]
+ end
+ end,
+ -- Set value for key to given value
+ set = function (self, key, value, key_len)
+ local ref = self:get_ref(key, key_len, true)
+ if ref then
+ ref[0] = value
+ return true
+ end
+ end,
+ },
+}
+
+-- Pretty print for domain name
+local function dname2str(dname)
+ if dname == nil then return end
+ local text_name = ffi.gc(C.knot_dname_to_str(nil, dname, 0), C.free)
+ if text_name ~= nil then
+ return ffi.string(text_name)
+ end
+end
+
+-- Convert dname pointer to wireformat string
+local function dname2wire(name)
+ if name == nil then return nil end
+ return ffi.string(name, knot.knot_dname_size(name))
+end
+
+-- Parse RDATA, from presentation to wire-format.
+-- in: a table of strings, each a line describing RRTYPE+RDATA
+-- out: a table of RDATA strings in wire-format
+local function parse_rdata(strs, nothing)
+ local zonefile = require('zonefile')
+ if type(strs) ~= 'table' or nothing ~= nil then -- accidents like forgetting braces
+ error('a table of string(s) is expected', 2)
+ end
+ local res = {}
+ for _, line in ipairs(strs) do
+ if type(line) ~= 'string' then
+ error('table must contain strings', 2)
+ end
+ local rrs = zonefile.string('. ' .. line)
+ if #rrs == 0 then error('failed to parse line: ' .. line, 2) end
+ for _, rr in ipairs(rrs) do
+ table.insert(res, rr.rdata)
+ end
+ end
+ return res
+end
+
+-- RR sets created in Lua must have a destructor to release allocated memory
+local function rrset_free(rr)
+ if rr._owner ~= nil then ffi.C.free(rr._owner) end
+ if rr:rdcount() > 0 then ffi.C.free(rr.rrs.rdata) end
+end
+
+-- Metatype for RR set. Beware, the indexing is 0-based (rdata, get, tostring).
+local rrset_buflen = (64 + 1) * 1024
+local rrset_buf = ffi.new('char[?]', rrset_buflen)
+local knot_rrset_pt = ffi.typeof('knot_rrset_t *')
+local knot_rrset_t = ffi.typeof('knot_rrset_t')
+ffi.metatype( knot_rrset_t, {
+ -- Create a new empty RR set object with an allocated owner and a destructor
+ __new = function (ct, owner, rrtype, rrclass, ttl)
+ local rr = ffi.new(ct)
+ C.kr_rrset_init(rr,
+ owner and knot.knot_dname_copy(owner, nil),
+ rrtype or 0,
+ rrclass or const_class.IN,
+ ttl or 0)
+ return ffi.gc(rr, rrset_free)
+ end,
+ -- BEWARE: `owner` and `rdata` are typed as a plain lua strings
+ -- and not the real types they represent.
+ __tostring = function(rr)
+ assert(ffi.istype(knot_rrset_t, rr))
+ return rr:txt_dump()
+ end,
+ __index = {
+ owner = function(rr)
+ assert(ffi.istype(knot_rrset_t, rr))
+ return dname2wire(rr._owner)
+ end,
+ ttl = function(rr)
+ assert(ffi.istype(knot_rrset_t, rr))
+ return tonumber(rr._ttl)
+ end,
+ class = function(rr, val)
+ assert(ffi.istype(knot_rrset_t, rr))
+ if val then
+ rr.rclass = val
+ end
+ return tonumber(rr.rclass)
+ end,
+ rdata_pt = function(rr, i)
+ assert(ffi.istype(knot_rrset_t, rr) and i >= 0 and i < rr:rdcount())
+ return knot.knot_rdataset_at(rr.rrs, i)
+ end,
+ rdata = function(rr, i)
+ assert(ffi.istype(knot_rrset_t, rr))
+ local rd = rr:rdata_pt(i)
+ return ffi.string(rd.data, rd.len)
+ end,
+ get = function(rr, i)
+ assert(ffi.istype(knot_rrset_t, rr) and i >= 0 and i < rr:rdcount())
+ return {owner = rr:owner(),
+ ttl = rr:ttl(),
+ class = tonumber(rr.rclass),
+ type = tonumber(rr.type),
+ rdata = rr:rdata(i)}
+ end,
+ tostring = function(rr, i)
+ assert(ffi.istype(knot_rrset_t, rr)
+ and (i == nil or (i >= 0 and i < rr:rdcount())) )
+ if rr:rdcount() > 0 then
+ local ret
+ if i ~= nil then
+ ret = knot.knot_rrset_txt_dump_data(rr, i, rrset_buf, rrset_buflen, C.KR_DUMP_STYLE_DEFAULT)
+ else
+ ret = -1
+ end
+ return ret >= 0 and ffi.string(rrset_buf)
+ end
+ end,
+
+ -- Dump the rrset in presentation format (dig-like).
+ txt_dump = function(rr, style)
+ assert(ffi.istype(knot_rrset_t, rr))
+ local bufsize = 1024
+ local dump = ffi.new('char *[1]', C.malloc(bufsize))
+ -- ^ one pointer to a string
+ local size = ffi.new('size_t[1]', { bufsize }) -- one size_t = bufsize
+
+ local ret = knot.knot_rrset_txt_dump(rr, dump, size,
+ style or C.KR_DUMP_STYLE_DEFAULT)
+ local result = nil
+ if ret >= 0 then
+ result = ffi.string(dump[0], ret)
+ end
+ C.free(dump[0])
+ return result
+ end,
+ txt_fields = function(rr, i)
+ assert(ffi.istype(knot_rrset_t, rr))
+ assert(i >= 0 and i < rr:rdcount())
+ local bufsize = 1024
+ local dump = ffi.new('char *', C.malloc(bufsize))
+ ffi.gc(dump, C.free)
+
+ local ret = knot.knot_rrset_txt_dump_data(rr, i, dump, 1024,
+ C.KR_DUMP_STYLE_DEFAULT)
+ if ret >= 0 then
+ local out = {}
+ out.owner = dname2str(rr:owner())
+ out.ttl = rr:ttl()
+ out.class = kres.tostring.class[rr:class()]
+ out.type = kres.tostring.type[rr.type]
+ out.rdata = ffi.string(dump, ret)
+ return out
+ else
+ panic('knot_rrset_txt_dump_data failure ' .. tostring(ret))
+ end
+ end,
+ -- Return RDATA count for this RR set
+ rdcount = function(rr)
+ assert(ffi.istype(knot_rrset_t, rr))
+ return tonumber(rr.rrs.count)
+ end,
+ -- Add binary RDATA to the RR set
+ add_rdata = function (rr, rdata, rdlen, no_ttl)
+ assert(ffi.istype(knot_rrset_t, rr))
+ assert(no_ttl == nil, 'add_rdata() can not accept TTL anymore')
+ local ret = knot.knot_rrset_add_rdata(rr, rdata, tonumber(rdlen), nil)
+ if ret ~= 0 then return nil, knot_error_t(ret) end
+ return true
+ end,
+ -- Merge data from another RR set into the current one
+ merge_rdata = function (rr, source)
+ assert(ffi.istype(knot_rrset_t, rr))
+ assert(ffi.istype(knot_rrset_t, source))
+ local ret = knot.knot_rdataset_merge(rr.rrs, source.rrs, nil)
+ if ret ~= 0 then return nil, knot_error_t(ret) end
+ return true
+ end,
+ -- Return type covered by this RRSIG
+ type_covered = function(rr, i)
+ i = i or 0
+ assert(ffi.istype(knot_rrset_t, rr) and i >= 0 and i < rr:rdcount())
+ if rr.type ~= const_type.RRSIG then return end
+ return tonumber(C.kr_rrsig_type_covered(knot.knot_rdataset_at(rr.rrs, i)))
+ end,
+ -- Check whether a RRSIG is covering current RR set
+ is_covered_by = function(rr, rrsig)
+ assert(ffi.istype(knot_rrset_t, rr))
+ assert(ffi.istype(knot_rrset_t, rrsig))
+ assert(rrsig.type == const_type.RRSIG)
+ return (rr.type == rrsig:type_covered() and rr:owner() == rrsig:owner())
+ end,
+ -- Return RR set wire size
+ wire_size = function(rr)
+ assert(ffi.istype(knot_rrset_t, rr))
+ return tonumber(knot.knot_rrset_size(rr))
+ end,
+ },
+})
+
+-- Destructor for packet accepts pointer to pointer
+local knot_pkt_t = ffi.typeof('knot_pkt_t')
+
+-- Helpers for reading/writing 16-bit numbers from packet wire
+local function pkt_u16(pkt, off, val)
+ assert(ffi.istype(knot_pkt_t, pkt))
+ local ptr = ffi.cast(u16_p, pkt.wire + off)
+ if val ~= nil then ptr[0] = htons(val) end
+ return (htons(ptr[0]))
+end
+
+-- Helpers for reading/writing message header flags
+local function pkt_bit(pkt, byteoff, bitmask, val)
+ -- If the value argument is passed, set/clear the desired bit
+ if val ~= nil then
+ if val then pkt.wire[byteoff] = bit.bor(pkt.wire[byteoff], bitmask)
+ else pkt.wire[byteoff] = bit.band(pkt.wire[byteoff], bit.bnot(bitmask)) end
+ return true
+ end
+ return (bit.band(pkt.wire[byteoff], bitmask) ~= 0)
+end
+
+local function knot_pkt_rr(section, i)
+ assert(section and ffi.istype('knot_pktsection_t', section)
+ and i >= 0 and i < section.count)
+ local ret = section.pkt.rr + section.pos + i
+ assert(ffi.istype(knot_rrset_pt, ret))
+ return ret
+end
+
+-- Metatype for packet
+ffi.metatype( knot_pkt_t, {
+ __new = function (_, size, wire)
+ if size < 12 or size > 65535 then
+ error('packet size must be <12, 65535>')
+ end
+
+ local pkt = knot.knot_pkt_new(nil, size, nil)
+ if pkt == nil then
+ error(string.format('failed to allocate a packet of size %d', size))
+ end
+ if wire == nil then
+ C.kr_rnd_buffered(pkt.wire, 2) -- randomize the query ID
+ else
+ assert(size <= #wire)
+ ffi.copy(pkt.wire, wire, size)
+ pkt.size = size
+ pkt.parsed = 0
+ end
+
+ return ffi.gc(pkt[0], knot.knot_pkt_free)
+ end,
+ __tostring = function(pkt)
+ return pkt:tostring()
+ end,
+ __len = function(pkt)
+ assert(ffi.istype(knot_pkt_t, pkt))
+ return tonumber(pkt.size)
+ end,
+ __ipairs = function(self)
+ return ipairs(self:section(const_section.ANSWER))
+ end,
+ __index = {
+ -- Header
+ id = function(pkt, val) return pkt_u16(pkt, 0, val) end,
+ qdcount = function(pkt, val) return pkt_u16(pkt, 4, val) end,
+ ancount = function(pkt, val) return pkt_u16(pkt, 6, val) end,
+ nscount = function(pkt, val) return pkt_u16(pkt, 8, val) end,
+ arcount = function(pkt, val) return pkt_u16(pkt, 10, val) end,
+ opcode = function (pkt, val)
+ assert(ffi.istype(knot_pkt_t, pkt))
+ pkt.wire[2] = (val) and bit.bor(bit.band(pkt.wire[2], 0x78), 8 * val) or pkt.wire[2]
+ return (bit.band(pkt.wire[2], 0x78) / 8)
+ end,
+ rcode = function (pkt, val)
+ assert(ffi.istype(knot_pkt_t, pkt))
+ pkt.wire[3] = (val) and bor(band(pkt.wire[3], 0xf0), val) or pkt.wire[3]
+ return band(pkt.wire[3], 0x0f)
+ end,
+ rd = function (pkt, val) return pkt_bit(pkt, 2, 0x01, val) end,
+ tc = function (pkt, val) return pkt_bit(pkt, 2, 0x02, val) end,
+ aa = function (pkt, val) return pkt_bit(pkt, 2, 0x04, val) end,
+ qr = function (pkt, val) return pkt_bit(pkt, 2, 0x80, val) end,
+ cd = function (pkt, val) return pkt_bit(pkt, 3, 0x10, val) end,
+ ad = function (pkt, val) return pkt_bit(pkt, 3, 0x20, val) end,
+ ra = function (pkt, val) return pkt_bit(pkt, 3, 0x80, val) end,
+ -- "do" is a reserved word in Lua; only getter
+ dobit = function(pkt, val)
+ assert(val == nil, 'dobit is getter only')
+ assert(ffi.istype(knot_pkt_t, pkt))
+ return C.kr_pkt_has_dnssec(pkt)
+ end,
+ -- Question
+ qname = function(pkt)
+ assert(ffi.istype(knot_pkt_t, pkt))
+ -- inlined knot_pkt_qname(), basically but not lower-cased
+ if pkt == nil or pkt.qname_size == 0 then return nil end
+ return ffi.string(pkt.wire + 12, pkt.qname_size)
+ end,
+ qclass = function(pkt)
+ assert(ffi.istype(knot_pkt_t, pkt))
+ return C.kr_pkt_qclass(pkt)
+ end,
+ qtype = function(pkt)
+ assert(ffi.istype(knot_pkt_t, pkt))
+ return C.kr_pkt_qtype(pkt)
+ end,
+ rrsets = function (pkt, section_id)
+ assert(ffi.istype(knot_pkt_t, pkt))
+ local records = {}
+ local section = pkt.sections + section_id
+ for i = 1, section.count do
+ local rrset = knot_pkt_rr(section, i - 1)
+ table.insert(records, rrset)
+ end
+ return records
+ end,
+ section = function (pkt, section_id)
+ assert(ffi.istype(knot_pkt_t, pkt))
+ local records = {}
+ local section = pkt.sections + section_id
+ for i = 1, section.count do
+ local rrset = knot_pkt_rr(section, i - 1)
+ for k = 1, rrset:rdcount() do
+ table.insert(records, rrset:get(k - 1))
+ end
+ end
+ return records
+ end,
+ begin = function (pkt, section)
+ assert(ffi.istype(knot_pkt_t, pkt))
+ assert(section >= pkt.current, 'cannot rewind to already written section')
+ assert(const_section_str[section], string.format('invalid section: %s', section))
+ local ret = knot.knot_pkt_begin(pkt, section)
+ if ret ~= 0 then return nil, knot_error_t(ret) end
+ return true
+ end,
+ put = function (pkt, owner, ttl, rclass, rtype, rdata)
+ assert(ffi.istype(knot_pkt_t, pkt))
+ local ret = C.kr_pkt_put(pkt, owner, ttl, rclass, rtype, rdata, #rdata)
+ if ret ~= 0 then return nil, knot_error_t(ret) end
+ return true
+ end,
+ -- Put an RR set in the packet
+ -- Note: the packet doesn't take ownership of the RR set
+ put_rr = function (pkt, rr, rotate, flags)
+ assert(ffi.istype(knot_pkt_t, pkt))
+ assert(ffi.istype(knot_rrset_t, rr))
+ local ret = C.knot_pkt_put_rotate(pkt, 0, rr, rotate or 0, flags or 0)
+ if ret ~= 0 then return nil, knot_error_t(ret) end
+ return true
+ end,
+ -- Checks whether the packet has a wire, i.e. the .size is not
+ -- equal to KR_PKT_SIZE_NOWIRE
+ has_wire = function (pkt)
+ assert(ffi.istype(knot_pkt_t, pkt))
+ return C.kr_pkt_has_wire(pkt)
+ end,
+ recycle = function (pkt)
+ assert(ffi.istype(knot_pkt_t, pkt))
+ local ret = C.kr_pkt_recycle(pkt)
+ if ret ~= 0 then return nil, knot_error_t(ret) end
+ return true
+ end,
+ clear_payload = function (pkt)
+ assert(ffi.istype(knot_pkt_t, pkt))
+ local ret = C.kr_pkt_clear_payload(pkt)
+ if ret ~= 0 then return nil, knot_error_t(ret) end
+ return true
+ end,
+ question = function(pkt, qname, qclass, qtype)
+ assert(ffi.istype(knot_pkt_t, pkt))
+ assert(qclass ~= nil, string.format('invalid class: %s', qclass))
+ assert(qtype ~= nil, string.format('invalid type: %s', qtype))
+ local ret = C.knot_pkt_put_question(pkt, qname, qclass, qtype)
+ if ret ~= 0 then return nil, knot_error_t(ret) end
+ return true
+ end,
+ towire = function (pkt)
+ assert(ffi.istype(knot_pkt_t, pkt))
+ return ffi.string(pkt.wire, pkt.size)
+ end,
+ tostring = function(pkt)
+ assert(ffi.istype(knot_pkt_t, pkt))
+ return ffi.string(ffi.gc(C.kr_pkt_text(pkt), C.free))
+ end,
+ -- Return number of remaining empty bytes in the packet
+ -- This is generally useful to check if there's enough space
+ remaining_bytes = function (pkt)
+ assert(ffi.istype(knot_pkt_t, pkt))
+ local occupied = pkt.size + pkt.reserved
+ assert(pkt.max_size >= occupied)
+ return tonumber(pkt.max_size - occupied)
+ end,
+ -- Packet manipulation
+ parse = function (pkt)
+ assert(ffi.istype(knot_pkt_t, pkt))
+ local ret = knot.knot_pkt_parse(pkt, 0)
+ if ret ~= 0 then return nil, knot_error_t(ret) end
+ return true
+ end,
+ -- Resize packet wire to a new size
+ resize = function (pkt, new_size)
+ assert(ffi.istype(knot_pkt_t, pkt))
+ local ptr = C.mm_realloc(pkt.mm, pkt.wire, new_size, pkt.max_size)
+ if ptr == nil then return end
+ pkt.wire = ptr
+ pkt.max_size = new_size
+ return true
+ end,
+ },
+})
+-- Metatype for query
+local kr_query_t = ffi.typeof('struct kr_query')
+ffi.metatype( kr_query_t, {
+ __index = {
+ -- Return query domain name
+ name = function(qry)
+ assert(ffi.istype(kr_query_t, qry))
+ return dname2wire(qry.sname)
+ end,
+ -- Write this query into packet
+ write = function(qry, pkt)
+ assert(ffi.istype(kr_query_t, qry))
+ assert(ffi.istype(knot_pkt_t, pkt))
+ local ret = C.kr_make_query(qry, pkt)
+ if ret ~= 0 then return nil, knot_error_t(ret) end
+ return true
+ end,
+ },
+})
+
+-- helper for trace_chain_callbacks
+-- ignores return values from successful calls but logs tracebacks for throws
+local function void_xpcall_log_tb(func, req, msg)
+ local ok, err = xpcall(func, debug.traceback, req, msg)
+ if not ok then
+ log_error(ffi.C.LOG_GRP_SYSTEM, 'callback %s req %s msg %s stack traceback:\n%s', func, req, msg, err)
+ end
+end
+
+local function void_xpcall_finish_tb(func, req)
+ local ok, err = xpcall(func, debug.traceback, req)
+ if not ok then
+ log_error(ffi.C.LOG_GRP_SYSTEM, 'callback %s req %s stack traceback:\n%s', func, req, err)
+ end
+end
+
+
+-- Metatype for request
+local kr_request_t = ffi.typeof('struct kr_request')
+ffi.metatype( kr_request_t, {
+ __index = {
+ -- makes sense only when request is finished
+ all_from_cache = function(req)
+ assert(ffi.istype(kr_request_t, req))
+ local rplan = ffi.C.kr_resolve_plan(req)
+ if tonumber(rplan.pending.len) > 0 then
+ -- an unresolved query,
+ -- i.e. something is missing from the cache
+ return false
+ end
+ for idx=0, tonumber(rplan.resolved.len) - 1 do
+ if not rplan.resolved.at[idx].flags.CACHED then
+ return false
+ end
+ end
+ return true
+ end,
+ current = function(req)
+ assert(ffi.istype(kr_request_t, req))
+ if req.current_query == nil then return nil end
+ return req.current_query
+ end,
+ -- returns the initial query that started the request
+ initial = function(req)
+ assert(ffi.istype(kr_request_t, req))
+ local rplan = C.kr_resolve_plan(req)
+ if rplan.initial == nil then return nil end
+ return rplan.initial
+ end,
+ -- Return last query on the resolution plan
+ last = function(req)
+ assert(ffi.istype(kr_request_t, req))
+ local query = C.kr_rplan_last(C.kr_resolve_plan(req))
+ if query == nil then return end
+ return query
+ end,
+ resolved = function(req)
+ assert(ffi.istype(kr_request_t, req))
+ local qry = C.kr_rplan_resolved(C.kr_resolve_plan(req))
+ if qry == nil then return nil end
+ return qry
+ end,
+ -- returns first resolved sub query for a request
+ first_resolved = function(req)
+ assert(ffi.istype(kr_request_t, req))
+ local rplan = C.kr_resolve_plan(req)
+ if not rplan or rplan.resolved.len < 1 then return nil end
+ return rplan.resolved.at[0]
+ end,
+ push = function(req, qname, qtype, qclass, flags, parent)
+ assert(ffi.istype(kr_request_t, req))
+ flags = kres.mk_qflags(flags) -- compatibility
+ local rplan = C.kr_resolve_plan(req)
+ local qry = C.kr_rplan_push(rplan, parent, qname, qclass, qtype)
+ if qry ~= nil and flags ~= nil then
+ C.kr_qflags_set(qry.flags, flags)
+ end
+ return qry
+ end,
+ pop = function(req, qry)
+ assert(ffi.istype(kr_request_t, req))
+ return C.kr_rplan_pop(C.kr_resolve_plan(req), qry)
+ end,
+ selected_tostring = function(req)
+ assert(ffi.istype(kr_request_t, req))
+ local buf = {}
+ if #req.answ_selected ~= 0 then
+ table.insert(buf, ';; selected from ANSWER sections:\n')
+ table.insert(buf, tostring(req.answ_selected))
+ end
+ if #req.auth_selected ~= 0 then
+ table.insert(buf, ';; selected from AUTHORITY sections:\n')
+ table.insert(buf, tostring(req.auth_selected))
+ end
+ if #req.add_selected ~= 0 then
+ table.insert(buf, ';; selected from ADDITIONAL sections:\n')
+ table.insert(buf, tostring(req.add_selected))
+ end
+ return table.concat(buf, '')
+ end,
+ set_extended_error = function(req, code, msg)
+ assert(ffi.istype(kr_request_t, req))
+ msg = kluautil.kr_string2c(msg, req.pool)
+ ffi.C.kr_request_set_extended_error(req, code, msg)
+ end,
+
+ -- chain new callbacks after the old ones
+ -- creates new wrapper functions as necessary
+ -- note: callbacks are FFI cdata pointers so tests must
+ -- use explicit "cb == nil", just "if cb" does not work
+ --
+ trace_chain_callbacks = function (req, new_log, new_finish)
+ local log_wrapper
+ if req.trace_log == nil then
+ req.trace_log = new_log
+ else
+ local old_log = req.trace_log
+ log_wrapper = ffi.cast('trace_log_f',
+ function(cbreq, msg)
+ jit.off(true, true) -- JIT for (C -> lua)^2 nesting isn't allowed
+ void_xpcall_log_tb(old_log, cbreq, msg)
+ void_xpcall_log_tb(new_log, cbreq, msg)
+ end)
+ req.trace_log = log_wrapper
+ end
+ local old_finish = req.trace_finish
+ if not (log_wrapper ~= nil or old_finish ~= nil) then
+ req.trace_finish = new_finish
+ else
+ local fin_wrapper
+ fin_wrapper = ffi.cast('trace_callback_f',
+ function(cbreq)
+ jit.off(true, true) -- JIT for (C -> lua)^2 nesting isn't allowed
+ if old_finish ~= nil then
+ void_xpcall_finish_tb(old_finish, cbreq)
+ end
+ if new_finish ~= nil then
+ void_xpcall_finish_tb(new_finish, cbreq)
+ end
+ -- beware: finish callbacks can call log callback
+ if log_wrapper ~= nil then
+ log_wrapper:free()
+ end
+ fin_wrapper:free()
+ end)
+ req.trace_finish = fin_wrapper
+ end
+ end,
+
+ -- Return per-request variable table
+ -- The request can store anything in this Lua table and it will be freed
+ -- when the request is closed, it doesn't have to worry about contents.
+ vars = function (req)
+ assert(ffi.istype(kr_request_t, req))
+ -- Return variable if it's already stored
+ local var = worker.vars[req.vars_ref]
+ if var then
+ return var
+ end
+ -- Either take a slot number from freelist
+ -- or find a first free slot (expand the table)
+ local ref = worker.vars[0]
+ if ref then
+ worker.vars[0] = worker.vars[ref]
+ else
+ ref = #worker.vars + 1
+ end
+ -- Create new variables table
+ var = {}
+ worker.vars[ref] = var
+ -- Save reference in the request
+ req.vars_ref = ref
+ return var
+ end,
+ -- Ensure that answer has EDNS if needed; can't fail.
+ ensure_edns = function (req)
+ assert(ffi.istype(kr_request_t, req))
+ return C.kr_request_ensure_edns(req)
+ end,
+ -- Ensure that answer exists and return it; can't fail.
+ ensure_answer = function (req)
+ assert(ffi.istype(kr_request_t, req))
+ return C.kr_request_ensure_answer(req)
+ end,
+ },
+})
+
+-- C array iterator
+local function c_array_iter(t, i)
+ i = i + 1
+ if i >= t.len then return end
+ return i, t.at[i][0]
+end
+
+-- Metatype for a single ranked record array entry (one RRset)
+local function rank_tostring(rank)
+ local names = {}
+ for name, value in pairs(const_rank) do
+ if ffi.C.kr_rank_test(rank, value) then
+ table.insert(names, string.lower(name))
+ end
+ end
+ table.sort(names) -- pairs() above doesn't give a stable ordering
+ return string.format('0%.2o (%s)', rank, table.concat(names, ' '))
+end
+
+local ranked_rr_array_entry_t = ffi.typeof('ranked_rr_array_entry_t')
+ffi.metatype(ranked_rr_array_entry_t, {
+ __tostring = function(self)
+ return string.format('; ranked rrset to_wire %s, rank %s, cached %s, qry_uid %s, revalidations %s\n%s',
+ self.to_wire, rank_tostring(self.rank), self.cached, self.qry_uid,
+ self.revalidation_cnt, string.format('%s', self.rr))
+ end
+})
+
+-- Metatype for ranked record array (array of RRsets)
+local ranked_rr_array_t = ffi.typeof('ranked_rr_array_t')
+ffi.metatype(ranked_rr_array_t, {
+ __len = function(self)
+ return tonumber(self.len)
+ end,
+ __ipairs = function (self)
+ return c_array_iter, self, -1
+ end,
+ __index = {
+ get = function (self, i)
+ if i < 0 or i > self.len then return nil end
+ return self.at[i][0]
+ end,
+ },
+ __tostring = function(self)
+ local buf = {}
+ for _, rrset in ipairs(self) do
+ table.insert(buf, tostring(rrset))
+ end
+ return table.concat(buf, '')
+ end
+})
+
+-- Cache metatype
+local kr_cache_t = ffi.typeof('struct kr_cache')
+ffi.metatype( kr_cache_t, {
+ __index = {
+ insert = function (self, rr, rrsig, rank, timestamp)
+ assert(ffi.istype(kr_cache_t, self))
+ assert(ffi.istype(knot_rrset_t, rr), 'RR must be a rrset type')
+ assert(not rrsig or ffi.istype(knot_rrset_t, rrsig), 'RRSIG must be nil or of the rrset type')
+ -- Get current timestamp
+ if not timestamp then
+ local now = timeval_t()
+ C.gettimeofday(now, nil)
+ timestamp = tonumber(now.tv_sec)
+ end
+ -- Insert record into cache
+ local ret = C.kr_cache_insert_rr(self, rr, rrsig, tonumber(rank or 0),
+ timestamp, true)
+ if ret ~= 0 then return nil, knot_error_t(ret) end
+ return true
+ end,
+ commit = function (self)
+ assert(ffi.istype(kr_cache_t, self))
+ local ret = C.kr_cache_commit(self)
+ if ret ~= 0 then return nil, knot_error_t(ret) end
+ return true
+ end,
+ },
+})
+
+-- Pretty-print a single RR (which is a table with .owner .ttl .type .rdata)
+-- Extension: append .comment if exists.
+local function rr2str(rr, style)
+ -- Construct a single-RR temporary set while minimizing copying.
+ local ret
+ do
+ local rrs = knot_rrset_t(rr.owner, rr.type, kres.class.IN, rr.ttl)
+ rrs:add_rdata(rr.rdata, #rr.rdata)
+ ret = rrs:txt_dump(style)
+ end
+
+ -- Trim the newline and append comment (optionally).
+ if ret then
+ if ret:byte(-1) == string.byte('\n', -1) then
+ ret = ret:sub(1, -2)
+ end
+ if rr.comment then
+ ret = ret .. ' ;' .. rr.comment
+ end
+ end
+ return ret
+end
+
+-- Module API
+kres = {
+ -- Constants
+ class = const_class,
+ type = const_type,
+ section = const_section,
+ rcode = const_rcode,
+ opcode = const_opcode,
+ rank = const_rank,
+ extended_error = const_extended_error,
+
+ -- Constants to strings
+ tostring = {
+ class = const_class_str,
+ type = const_type_str,
+ section = const_section_str,
+ rcode = const_rcode_str,
+ opcode = const_opcode_str,
+ rank = const_rank_str,
+ extended_eror = const_extended_error_str,
+ },
+
+ -- Create a struct kr_qflags from a single flag name or a list of names.
+ mk_qflags = function (names)
+ local kr_qflags = ffi.typeof('struct kr_qflags')
+ if names == 0 or names == nil then -- compatibility: nil is common in lua
+ names = {}
+ elseif type(names) == 'string' then
+ names = {names}
+ elseif ffi.istype(kr_qflags, names) then
+ return names
+ end
+
+ local fs = ffi.new(kr_qflags)
+ for _, name in pairs(names) do
+ fs[name] = true
+ end
+ return fs
+ end,
+
+ CONSUME = 1, PRODUCE = 2, DONE = 4, FAIL = 8, YIELD = 16,
+
+ -- Export types
+ rrset = knot_rrset_t,
+ packet = knot_pkt_t,
+ lru = function (max_size, value_type)
+ value_type = value_type or ffi.typeof('uint64_t')
+ local ct = ffi.typeof(typed_lru_t, value_type)
+ return ffi.metatype(ct, lru_metatype)(max_size, ffi.alignof(value_type))
+ end,
+
+ -- Metatypes. Beware that any pointer will be cast silently...
+ pkt_t = function (udata) return ffi.cast('knot_pkt_t *', udata) end,
+ request_t = function (udata) return ffi.cast('struct kr_request *', udata) end,
+ sockaddr_t = function (udata) return ffi.cast('struct sockaddr *', udata) end,
+
+ -- Global API functions
+ -- Convert a lua string to a lower-case wire format (inside GC-ed ffi.string).
+ str2dname = function(name)
+ if type(name) ~= 'string' then return end
+ local dname = ffi.gc(C.knot_dname_from_str(nil, name, 0), C.free)
+ if dname == nil then return nil end
+ ffi.C.knot_dname_to_lower(dname);
+ return dname2wire(dname)
+ end,
+ dname2str = dname2str,
+ dname2wire = dname2wire,
+ parse_rdata = parse_rdata,
+
+ rr2str = rr2str,
+ str2ip = function (ip)
+ local family = C.kr_straddr_family(ip)
+ local ret = C.inet_pton(family, ip, addr_buf)
+ if ret ~= 1 then return nil end
+ return ffi.string(addr_buf, C.kr_family_len(family))
+ end,
+ context = function () return ffi.C.the_worker.engine.resolver end,
+
+ knot_pkt_rr = knot_pkt_rr,
+}
+
+return kres
diff --git a/daemon/lua/krprint.lua b/daemon/lua/krprint.lua
new file mode 100644
index 0000000..dd25a9b
--- /dev/null
+++ b/daemon/lua/krprint.lua
@@ -0,0 +1,340 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+local base_class = {
+ cur_indent = 0,
+}
+
+-- shared constructor: use as serializer_class:new()
+function base_class.new(class, on_unrepresentable)
+ on_unrepresentable = on_unrepresentable or 'comment'
+ if on_unrepresentable ~= 'comment'
+ and on_unrepresentable ~= 'error' then
+ error('unsupported val2expr on_unrepresentable option '
+ .. tostring(on_unrepresentable))
+ end
+ local inst = {}
+ inst.on_unrepresentable = on_unrepresentable
+ inst.done = {}
+ inst.tab_key_path = {}
+ setmetatable(inst, class.__inst_mt)
+ return inst
+end
+
+-- format comment with leading/ending whitespace if needed
+function base_class.format_note(_, note, ws_prefix, ws_suffix)
+ if note == nil then
+ return ''
+ else
+ return string.format('%s--[[ %s ]]%s',
+ ws_prefix or '', note, ws_suffix or '')
+ end
+end
+
+function base_class.indent_head(self)
+ return string.rep(' ', self.cur_indent)
+end
+
+function base_class.indent_inc(self)
+ self.cur_indent = self.cur_indent + self.indent_step
+end
+
+function base_class.indent_dec(self)
+ self.cur_indent = self.cur_indent - self.indent_step
+end
+
+function base_class._fallback(self, val)
+ if self.on_unrepresentable == 'comment' then
+ return 'nil', string.format('missing %s', val)
+ elseif self.on_unrepresentable == 'error' then
+ local key_path_msg
+ if #self.tab_key_path > 0 then
+ local str_key_path = {}
+ for _, key in ipairs(self.tab_key_path) do
+ table.insert(str_key_path,
+ string.format('%s %s', type(key), self:string(tostring(key))))
+ end
+ local key_path = '[' .. table.concat(str_key_path, '][') .. ']'
+ key_path_msg = string.format(' (found at [%s])', key_path)
+ else
+ key_path_msg = ''
+ end
+ error(string.format('cannot serialize type %s%s', type(val), key_path_msg), 2)
+ end
+end
+
+function base_class.val2expr(self, val)
+ local val_type = type(val)
+ local val_repr = self[val_type]
+ if val_repr then
+ return val_repr(self, val)
+ else
+ return self:_fallback(val)
+ end
+end
+
+-- "nil" is a Lua keyword so assignment below is workaround to create
+-- function base_class.nil(self, val)
+base_class['nil'] = function(_, val)
+ assert(type(val) == 'nil')
+ return 'nil'
+end
+
+function base_class.number(_, val)
+ assert(type(val) == 'number')
+ if val == math.huge then
+ return 'math.huge'
+ elseif val == -math.huge then
+ return '-math.huge'
+ elseif tostring(val) == 'nan' then
+ return 'tonumber(\'nan\')'
+ else
+ return string.format("%.60f", val)
+ end
+end
+
+function base_class.char_is_printable(_, c)
+ -- ASCII (from space to ~) and not ' or \
+ return (c >= 0x20 and c < 0x7f)
+ and c ~= 0x27 and c ~= 0x5C
+end
+
+function base_class.string(self, val)
+ assert(type(val) == 'string')
+ local chars = {'\''}
+ for i = 1, #val do
+ local c = string.byte(val, i)
+ if self:char_is_printable(c) then
+ table.insert(chars, string.char(c))
+ else
+ table.insert(chars, string.format('\\%03d', c))
+ end
+ end
+ table.insert(chars, '\'')
+ return table.concat(chars)
+end
+
+function base_class.boolean(_, val)
+ assert(type(val) == 'boolean')
+ return tostring(val)
+end
+
+local function ordered_iter(unordered_tt)
+ local keys = {}
+ for k in pairs(unordered_tt) do
+ table.insert(keys, k)
+ end
+ table.sort(keys,
+ function (a, b)
+ if type(a) ~= type(b) then
+ return type(a) < type(b)
+ end
+ if type(a) == 'number' then
+ return a < b
+ else
+ return tostring(a) < tostring(b)
+ end
+ end)
+ local i = 0
+ return function()
+ i = i + 1
+ if keys[i] ~= nil then
+ return keys[i], unordered_tt[keys[i]]
+ end
+ end
+end
+
+function base_class.table(self, tab)
+ assert(type(tab) == 'table')
+ if self.done[tab] then
+ error('cyclic reference', 0)
+ end
+ self.done[tab] = true
+
+ local items = {'{'}
+ local previdx = 0
+ self:indent_inc()
+ for idx, val in ordered_iter(tab) do
+ local errors, valok, valexpr, valnote, idxok, idxexpr, idxnote
+ errors = {}
+ -- push current index onto key path stack to make it available to sub-printers
+ table.insert(self.tab_key_path, idx)
+
+ valok, valexpr, valnote = pcall(self.val2expr, self, val)
+ if not valok then
+ table.insert(errors, string.format('value: %s', valexpr))
+ end
+
+ local addidx
+ if previdx and type(idx) == 'number' and idx - 1 == previdx then
+ -- monotonic sequence, do not print key
+ previdx = idx
+ addidx = false
+ else
+ -- end of monotonic sequence
+ -- from now on print keys as well
+ previdx = nil
+ addidx = true
+ end
+
+ if addidx then
+ idxok, idxexpr, idxnote = pcall(self.val2expr, self, idx)
+ if not idxok or idxexpr == 'nil' then
+ table.insert(errors, string.format('key: not serializable', idxexpr))
+ end
+ end
+
+ local item = ''
+ if #errors == 0 then
+ -- finally serialize one [key=]?value expression
+ local indent = self:indent_head()
+ local note
+ if addidx then
+ note = self:format_note(idxnote, nil, self.key_val_sep)
+ item = string.format('%s%s[%s]%s=%s',
+ indent, note,
+ idxexpr, self.key_val_sep, self.key_val_sep)
+ indent = ''
+ end
+ note = self:format_note(valnote, nil, self.item_sep)
+ item = item .. string.format('%s%s%s,', indent, note, valexpr)
+ else
+ local errmsg = string.format('cannot print %s = %s (%s)',
+ self:string(tostring(idx)),
+ self:string(tostring(val)),
+ table.concat(errors, ', '))
+ if self.on_unrepresentable == 'error' then
+ error(errmsg, 0)
+ else
+ errmsg = string.format('--[[ missing %s ]]', errmsg)
+ item = errmsg
+ end
+ end
+ table.insert(items, item)
+ table.remove(self.tab_key_path) -- pop current index from key path stack
+ end -- one key+value
+ self:indent_dec()
+ table.insert(items, self:indent_head() .. '}')
+ return table.concat(items, self.item_sep), string.format('%s follows', tab)
+end
+
+-- machine readable variant, cannot represent all types and repeated references to a table
+local serializer_class = {
+ indent_step = 0,
+ item_sep = ' ',
+ key_val_sep = ' ',
+ __inst_mt = {}
+}
+-- inheritance form base class (for :new())
+setmetatable(serializer_class, { __index = base_class })
+-- class instances with following metatable inherit all class members
+serializer_class.__inst_mt.__index = serializer_class
+
+local function static_serializer(val, on_unrepresentable)
+ local inst = serializer_class:new(on_unrepresentable)
+ local expr, note = inst:val2expr(val)
+ return string.format('%s%s', inst:format_note(note, nil, inst.item_sep), expr)
+ end
+
+-- human friendly variant, not stable and not intended for machine consumption
+local pprinter_class = {
+ indent_step = 4,
+ item_sep = '\n',
+ key_val_sep = ' ',
+ __inst_mt = {},
+}
+
+-- should be always empty because pretty-printer has fallback for all types
+function pprinter_class.format_note()
+ return ''
+end
+
+function pprinter_class._fallback(self, val)
+ if self.on_unrepresentable == 'error' then
+ base_class._fallback(self, val)
+ end
+ return tostring(val)
+end
+
+function pprinter_class.char_is_printable(_, c)
+ -- ASCII (from space to ~) + tab or newline
+ -- and not ' or \
+ return ((c >= 0x20 and c < 0x7f)
+ or c == 0x09 or c == 0x0A)
+ and c ~= 0x27 and c ~= 0x5C
+end
+
+-- "function" is a Lua keyword so assignment below is workaround to create
+-- function pprinter_class.function(self, f)
+pprinter_class['function'] = function(self, f)
+-- thanks to AnandA777 from StackOverflow! Function funcsign is adapted version of
+-- https://stackoverflow.com/questions/51095022/inspect-function-signature-in-lua-5-1
+ assert(type(f) == 'function', "bad argument #1 to 'funcsign' (function expected)")
+ local debuginfo = debug.getinfo(f)
+ local func_args = {}
+ local args_str
+ if debuginfo.what == 'C' then -- names N/A
+ args_str = '(?)'
+ goto add_name
+ end
+
+ pcall(function()
+ local oldhook
+ local delay = 2
+ local function hook()
+ delay = delay - 1
+ if delay == 0 then -- call this only for the introspected function
+ -- stack depth 2 is the introspected function
+ for i = 1, debuginfo.nparams do
+ local k = debug.getlocal(2, i)
+ table.insert(func_args, k)
+ end
+ if debuginfo.isvararg then
+ table.insert(func_args, "...")
+ end
+ debug.sethook(oldhook)
+ error('aborting the call to introspected function')
+ end
+ end
+ oldhook = debug.sethook(hook, "c") -- invoke hook() on function call
+ f(unpack({})) -- huh?
+ end)
+ args_str = "(" .. table.concat(func_args, ", ") .. ")"
+ ::add_name::
+ local name
+ if #self.tab_key_path > 0 then
+ name = string.format('function %s', self.tab_key_path[#self.tab_key_path])
+ else
+ name = 'function '
+ end
+ return string.format('%s%s: %s', name, args_str, string.sub(tostring(f), 11))
+end
+
+-- default tostring method is better suited for human-intended output
+function pprinter_class.number(_, number)
+ return tostring(number)
+end
+
+local function deserialize_lua(serial)
+ assert(type(serial) == 'string')
+ local deserial_func = loadstring('return ' .. serial)
+ if type(deserial_func) ~= 'function' then
+ panic('input is not a valid Lua expression')
+ end
+ return deserial_func()
+end
+
+setmetatable(pprinter_class, { __index = base_class })
+pprinter_class.__inst_mt.__index = pprinter_class
+
+local function static_pprint(val, on_unrepresentable)
+ local inst = pprinter_class:new(on_unrepresentable)
+ local expr, note = inst:val2expr(val)
+ return string.format('%s%s', inst:format_note(note, nil, inst.item_sep), expr)
+end
+
+local M = {
+ serialize_lua = static_serializer,
+ deserialize_lua = deserialize_lua,
+ pprint = static_pprint
+}
+
+return M
diff --git a/daemon/lua/krprint.test.lua b/daemon/lua/krprint.test.lua
new file mode 100644
index 0000000..9218052
--- /dev/null
+++ b/daemon/lua/krprint.test.lua
@@ -0,0 +1,292 @@
+local serialize_lua = require('krprint').serialize_lua
+local deserialize_lua = require('krprint').deserialize_lua
+
+local function gen_string(maxlen)
+ maxlen = maxlen or 100
+ local len = math.random(0, maxlen)
+ local buf = {}
+ for _=1,len do
+ table.insert(buf, string.char(math.random(0, 255)))
+ end
+ return table.concat(buf)
+end
+
+local function test_de_serialization(orig_val, desc)
+ local serial = serialize_lua(orig_val)
+ ok(type(serial) == 'string' and #serial > 0,
+ 'serialization returns non-empty string: ' .. desc)
+ local deserial_val = deserialize_lua(serial)
+ same(type(orig_val), type(deserial_val),
+ 'deserialized value has the same type: ' .. desc)
+ if type(orig_val) == 'number' then
+ -- nan cannot be compared using == operator
+ if tostring(orig_val) == 'nan' and tostring(deserial_val) == 'nan' then
+ pass('nan value serialized and deserialized')
+ elseif orig_val ~= math.huge and orig_val ~= -math.huge then
+ -- tolerance measured experimentally on x86_64 LuaJIT 2.1.0-beta3
+ local tolerance = 1e-14
+ ok(math.abs(orig_val - deserial_val) <= tolerance,
+ 'deserialized number is within tolerance ' .. tolerance)
+ else
+ same(orig_val, deserial_val, 'deserialization returns the same infinity:' .. desc)
+ end
+ else
+ same(orig_val, deserial_val,
+ 'deserialization returns the same value: ' .. desc)
+ end
+end
+
+local function test_de_serialization_autodesc(orig_val)
+ test_de_serialization(orig_val, tostring(orig_val))
+end
+
+local function test_bool()
+ test_de_serialization_autodesc(true)
+ same('true', table_print(true), 'table_print handles true')
+ test_de_serialization_autodesc(false)
+ same('false', table_print(false), 'table_print handles false')
+end
+
+local function test_nil()
+ test_de_serialization_autodesc(nil)
+ same('nil', table_print(nil), 'table_print handles nil')
+end
+
+local function gen_number_int()
+ local number
+ -- make "small" numbers more likely so they actually happen
+ if math.random() < 0.5 then
+ number = math.random(-2^32, 2^32)
+ else
+ number = math.random(-2^48, 2^48)
+ end
+ return number
+end
+
+local function gen_number_float()
+ return math.random()
+end
+
+local function test_number()
+ test_de_serialization_autodesc(0)
+ same('0', table_print(0), 'table_print handles 0')
+ test_de_serialization_autodesc(-math.huge)
+ same('-inf', table_print(-math.huge), 'table_print handles -infinity')
+ test_de_serialization_autodesc(math.huge)
+ same('inf', table_print(math.huge), 'table_print handles +infinity')
+ test_de_serialization_autodesc(tonumber('nan'))
+ same('nan', table_print(tonumber('nan')), 'table_print handles nan')
+ for _=1,20 do -- integers
+ test_de_serialization_autodesc(gen_number_int())
+ -- bigger numbers might end up with non-exact representation
+ local smallnumber = math.random(-2^32, 2^32)
+ same(tostring(smallnumber), table_print(smallnumber),
+ 'table_print handles small numbers')
+ end
+ for _=1,20 do -- floats
+ local float = math.random()
+ same(tostring(float), table_print(float),
+ 'table_print handles floats')
+ test_de_serialization_autodesc(gen_number_float())
+ end
+end
+
+local function test_string()
+ test_de_serialization('', 'empty string')
+ for _=1,20 do
+ local str = gen_string(1024*10)
+ test_de_serialization(str, 'random string length ' .. #str)
+ end
+end
+
+local function gen_number()
+ -- pure random would not produce special cases often enough
+ local generators = {
+ function() return 0 end,
+ function() return -math.huge end,
+ function() return math.huge end,
+ gen_number_int,
+ gen_number_float,
+ }
+ return generators[math.random(1, #generators)]()
+end
+
+local function gen_boolean()
+ local options = {true, false}
+ return options[math.random(1, #options)]
+end
+
+local function gen_table_atomic()
+ -- nil keys or values are not allowed
+ -- nested tables are handled elsewhere
+ local supported_types = {
+ gen_number,
+ gen_string,
+ gen_boolean,
+ }
+ val = supported_types[math.random(1, #supported_types)]()
+ return val
+end
+
+local function gen_test_tables_supported(level)
+ level = level or 1
+ local max_level = 5
+ local max_items_per_table = 20
+ local t = {}
+ for _=1, math.random(0, max_items_per_table) do
+ local val_as_table = (level <= max_level) and math.random() < 0.1
+ local key, val
+ -- tapered.same method cannot compare keys with type table
+ key = gen_table_atomic()
+ if val_as_table then
+ val = gen_test_tables_supported(level + 1)
+ else
+ val = gen_table_atomic()
+ end
+ t[key] = val
+ end
+ return t
+end
+
+local marker = 'this string must be present somewhere in output'
+local function gen_marker()
+ return marker
+end
+
+local kluautil = require('kluautil')
+local function random_modify_table(t, always, generator)
+ assert(generator)
+ local tab_len = kluautil.kr_table_len(t)
+ local modified = false
+ -- modify some values
+ for key, val in pairs(t) do
+ if math.random(1, tab_len) == 1 then
+ if type(val) == 'table' then
+ modified = modified or random_modify_table(val, false, generator)
+ else
+ t[key] = generator()
+ modified = true
+ end
+ end
+ end
+ if always and not modified then
+ -- fallback, add an unsupported key
+ t[generator()] = true
+ modified = true
+ end
+ return modified
+end
+
+local function test_table_supported()
+ for i=1,10 do
+ local t = gen_test_tables_supported()
+ test_de_serialization(t, 'random table no. ' .. i)
+ assert(random_modify_table(t, true, gen_marker))
+ local str = table_print(t)
+ ok(string.find(str, marker, 1, true),
+ 'table_print works on complex serializable tables')
+ end
+end
+
+local ffi = require('ffi')
+local const_func = tostring
+local const_thread = coroutine.create(tostring)
+local const_userdata = ffi.C
+local const_cdata = ffi.new('int')
+
+local function gen_unsupported_atomic()
+ -- nested tables are handled elsewhere
+ local unsupported_types = {
+ const_func,
+ const_thread,
+ const_userdata,
+ const_cdata
+ }
+ val = unsupported_types[math.random(1, #unsupported_types)]
+ return val
+end
+
+local function test_unsupported(val, desc)
+ desc = desc or string.format('unsupported %s', type(val))
+ return function()
+ boom(serialize_lua, { val, 'error' }, string.format(
+ 'attempt to serialize %s in error mode '
+ .. 'causes error', desc))
+ local output = serialize_lua(val, 'comment')
+ same('string', type(output),
+ string.format('attempt to serialize %s in '
+ .. 'comment mode returned a string',
+ desc))
+ ok(string.find(output, '--', 1, true),
+ 'returned string contains a comment')
+ output = table_print(val)
+ same('string', type(output),
+ string.format('table_print can stringify %s', desc))
+ if type(val) ~= 'table' then
+ ok(string.find(output, type(val), 1, true),
+ 'exotic type is mentioned in table_print output')
+ end
+ end
+end
+
+local function gen_test_tables_unsupported()
+ local t = gen_test_tables_supported()
+ random_modify_table(t, true, gen_unsupported_atomic)
+ return t
+end
+
+local function test_unsupported_table()
+ for i=1,10 do
+ local t = gen_test_tables_unsupported()
+ test_unsupported(t, 'random unsupported table no. ' .. i)()
+ assert(random_modify_table(t, true, gen_marker))
+ local str = table_print(t)
+ ok(string.find(str, marker, 1, true),
+ 'table_print works on complex unserializable tables')
+ end
+end
+
+local function func_2vararg_5ret(arg1, arg2, ...)
+ return select('#', ...), nil, arg1 + arg2, false, nil
+end
+local function func_ret_nil() return nil end
+local function func_ret_nothing() return end
+
+local function test_pprint_func()
+ local t = { [false] = func_2vararg_5ret }
+ local output = table_print(t)
+ ok(string.find(output, 'function false(arg1, arg2, ...)', 1, true),
+ 'function parameters are pretty printed')
+end
+
+local function test_pprint_func_ret()
+ local output = table_print(func_2vararg_5ret(1, 2, 'bla'))
+ local exp = [[
+1 -- result # 1
+nil -- result # 2
+3 -- result # 3
+false -- result # 4
+nil -- result # 5]]
+ same(output, exp, 'multiple return values are pretty printed')
+
+ output = table_print(func_ret_nil())
+ same(output, 'nil', 'single return value does not have extra comments')
+
+ output = table_print(func_ret_nothing())
+ same(output, nil, 'no return values to be printed cause nil output')
+end
+
+return {
+ test_bool,
+ test_nil,
+ test_number,
+ test_string,
+ test_table_supported,
+ test_unsupported(const_func),
+ test_unsupported(const_thread),
+ test_unsupported(const_userdata),
+ test_unsupported(const_cdata),
+ test_unsupported_table,
+ test_pprint_func,
+ test_pprint_func_ret,
+}
diff --git a/daemon/lua/log.test.lua b/daemon/lua/log.test.lua
new file mode 100644
index 0000000..197aa74
--- /dev/null
+++ b/daemon/lua/log.test.lua
@@ -0,0 +1,42 @@
+local function test_log_level()
+ same(log_level(), 'notice', 'default level is notice')
+ same(verbose(), false, 'verbose is not set by default')
+ same(log_level('crit'), 'crit', '"crit" level can be set')
+ same(log_level('err'), 'err', '"err" level can be set')
+ same(log_level('warning'), 'warning', '"warning" level can be set')
+ same(log_level('notice'), 'notice', '"notice" level can be set')
+ same(log_level('info'), 'info', '"info" level can be set')
+ same(log_level('debug'), 'debug', '"debug" level can be set')
+ same(verbose(), true, 'verbose is active when debug level is set')
+ same(verbose(false), false, 'verbose can be used to turn off debug level')
+ same(log_level(), 'notice', 'verbose returns log level to notice')
+ boom(log_level, { 'xxx' }, "unknown level can't be used")
+ boom(log_level, { 7 }, "numbered levels aren't supported")
+ boom(log_level, { 1, 2 }, "level doesn't take multiple arguments")
+end
+
+local function test_log_target()
+ same(log_target(), 'stderr', 'default target is stderr')
+ same(log_target('stdout'), 'stdout', 'stdout target can be set')
+ same(log_target('syslog'), 'syslog', 'syslog target can be set')
+ same(log_target('stderr'), 'stderr', 'stderr target can be set')
+ boom(log_level, { 'xxx' }, "unknown target can't be used")
+ boom(log_level, { 'stderr', 'syslog' }, "target doesn't take multiple arguments")
+end
+
+local function test_log_groups()
+ same(log_groups(), {}, 'no groups are logged by default')
+ same(log_groups({'system'}), {'system'}, 'configure "system" group')
+ same(log_groups({'devel'}), {'devel'}, 'another call overrides previously set groups')
+ same(log_groups({'devel', 'system'}), {'system', 'devel'}, 'configure multiple groups')
+ same(log_groups({}), {}, 'clear groups with empty table')
+ boom(log_groups, { 'string' }, "group argument can't be string")
+ boom(log_groups, { {'nonexistent'} }, "nonexistent group can't be added")
+ boom(log_groups, { 1, 2 }, "group doesn't take multiple arguments")
+end
+
+return {
+ test_log_level,
+ test_log_target,
+ test_log_groups,
+}
diff --git a/daemon/lua/map.test.integr/deckard.yaml b/daemon/lua/map.test.integr/deckard.yaml
new file mode 100644
index 0000000..2fe920d
--- /dev/null
+++ b/daemon/lua/map.test.integr/deckard.yaml
@@ -0,0 +1,38 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+programs:
+- name: kresd3
+ binary: kresd
+ additional:
+ - --noninteractive
+ templates:
+ - daemon/lua/map.test.integr/kresd_config.j2
+ - tests/integration/hints_zone.j2
+ - tests/config/tapered/src/tapered.lua
+ configs:
+ - config
+ - hints
+ - tapered.lua
+- name: kresd2
+ binary: kresd
+ additional:
+ - --noninteractive
+ templates:
+ - daemon/lua/map.test.integr/kresd_config.j2
+ - tests/integration/hints_zone.j2
+ - tests/config/tapered/src/tapered.lua
+ configs:
+ - config
+ - hints
+ - tapered.lua
+- name: kresd1
+ binary: kresd
+ additional:
+ - --noninteractive
+ templates:
+ - daemon/lua/map.test.integr/kresd_config.j2
+ - tests/integration/hints_zone.j2
+ - tests/config/tapered/src/tapered.lua
+ configs:
+ - config
+ - hints
+ - tapered.lua
diff --git a/daemon/lua/map.test.integr/kresd_config.j2 b/daemon/lua/map.test.integr/kresd_config.j2
new file mode 100644
index 0000000..ae403c7
--- /dev/null
+++ b/daemon/lua/map.test.integr/kresd_config.j2
@@ -0,0 +1,193 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+local ffi = require('ffi')
+log_info(ffi.C.LOG_GRP_TESTS, 'my PID = %d', worker.pid)
+
+trust_anchors.remove('.')
+
+cache.size = 2*MB
+
+net = { '{{SELF_ADDR}}' }
+
+{% if QMIN == "false" %}
+option('NO_MINIMIZE', true)
+{% else %}
+option('NO_MINIMIZE', false)
+{% endif %}
+
+-- Self-checks on globals
+assert(help() ~= nil)
+assert(worker.id ~= nil)
+-- Self-checks on facilities
+assert(cache.count() == 0)
+assert(cache.stats() ~= nil)
+assert(cache.backends() ~= nil)
+assert(worker.stats() ~= nil)
+assert(net.interfaces() ~= nil)
+-- Self-checks on loaded stuff
+assert(#modules.list() > 0)
+-- Self-check timers
+ev = event.recurrent(1 * sec, function (ev) return 1 end)
+event.cancel(ev)
+
+local kluautil = require('kluautil')
+local tap = require('tapered')
+local checks_total = 16
+local n_instances = 3 -- must match deckard.yaml
+
+worker.control_path = worker.cwd .. '/../kresd3/control/'
+net.listen(worker.control_path .. worker.pid, nil, {kind = 'control'})
+assert(#net.list() >= 3) -- UDP, TCP, control
+
+-- debug, kept for future use
+--log_level("debug")
+log_debug(ffi.C.LOG_GRP_TESTS, '%s', worker.control_path)
+log_debug(ffi.C.LOG_GRP_TESTS, '%s', table_print(net.list()))
+
+function wait_for_sockets()
+ log_info(ffi.C.LOG_GRP_TESTS, 'waiting for control sockets')
+ local timeout = 5000 -- ms
+ local start_time = tonumber(ffi.C.kr_now())
+ local now
+ while true do
+ now = tonumber(ffi.C.kr_now())
+ if now > start_time + timeout then
+ log_info(ffi.C.LOG_GRP_TESTS, 'timeout while waiting for control sockets to appear')
+ os.exit(3)
+ end
+ local pids = kluautil.list_dir(worker.control_path)
+ if #pids == n_instances then
+ -- debug, kept for future use
+ log_debug(ffi.C.LOG_GRP_TESTS, 'got control sockets:')
+ log_debug(ffi.C.LOG_GRP_TESTS, table_print(pids))
+ break
+ else
+ worker.sleep(0.1)
+ end
+ end
+ log_info(ffi.C.LOG_GRP_TESTS, 'PIDs are visible now (waiting took %d ms)', now - start_time)
+end
+
+-- expression should throw Lua error:
+-- wrap it in a function which runs the expression on leader and follower
+-- separately so we can guarantee both cases are covered
+function boom_follower_and_leader(boom_expr, desc)
+ local variants = {leader = '~=', follower = '=='}
+ for name, operator in pairs(variants) do
+ -- beware, newline is not allowed in expr
+ local full_expr = string.format(
+ 'if (worker.pid %s %s) then return true '
+ .. 'else return %s end',
+ operator, worker.pid, boom_expr)
+ local full_desc = name .. ': '
+ if desc then
+ full_desc = full_desc .. desc .. ' (' .. boom_expr .. ')'
+ else
+ full_desc = full_desc .. boom_expr
+ end
+ tap.boom(map, {full_expr}, full_desc)
+ end
+end
+
+function tests()
+ -- add delay to each test to force scheduler to interleave tests and DNS queries
+ local test_delay = 20 / 1000 -- seconds
+ log_info(ffi.C.LOG_GRP_TESTS, 'starting map() tests now')
+
+ tap.boom(map, {'1 ++ 1'}, 'syntax error in command is detected')
+ worker.sleep(test_delay)
+
+ -- array of integers
+ local pids = map('worker.pid')
+ tap.same(pids.n, n_instances, 'all pids were obtained')
+ table.sort(pids)
+ worker.sleep(test_delay)
+
+ -- expression produces array of integers
+ local pids_plus_one = map('worker.pid + 1')
+ tap.same(pids_plus_one.n, n_instances, 'all pids were obtained')
+ table.sort(pids_plus_one)
+ for idx=1,n_instances do
+ tap.same(pids[idx] + 1, pids_plus_one[idx],
+ 'increment expression worked')
+ end
+ worker.sleep(test_delay)
+
+ -- error detection
+ boom_follower_and_leader('error("explosion")')
+ worker.sleep(test_delay)
+
+ -- unsupported number of return values
+ boom_follower_and_leader('1, 2')
+ worker.sleep(test_delay)
+ boom_follower_and_leader('unpack({})')
+ worker.sleep(test_delay)
+
+ -- unsupported return type
+ boom_follower_and_leader(
+ 'function() print("this cannot be serialized") end')
+ worker.sleep(test_delay)
+
+ tap.same({n = n_instances}, map('nil'),
+ 'nil values are counted as returned')
+ worker.sleep(test_delay)
+
+ local exp = {n = n_instances}
+ for i=1,n_instances do
+ table.insert(exp, {nil, 2, nil, n=3})
+ end
+ local got = map('require("kluautil").kr_table_pack(nil, 2, nil)')
+ tap.same(got, exp, 'kr_table_pack handles nil values')
+ worker.sleep(test_delay)
+end
+
+local started = false
+function tests_start()
+ -- just in case, duplicates should not happen
+ if started then
+ log_info(ffi.C.LOG_GRP_TESTS, 'huh? duplicate test invocation ignored, a retransmit?')
+ return
+ end
+ started = true
+ log_info(ffi.C.LOG_GRP_TESTS, 'start query triggered, scheduling tests')
+
+ -- DNS queries and map() commands must be serviced while sleep is running
+ worker.coroutine(function() worker.sleep(3600) end)
+
+ worker.coroutine(tests)
+end
+-- Deckard query will trigger tests
+policy.add(policy.suffix(tests_start, {'\5start\0'}))
+
+function tests_done()
+ print('final query triggered')
+ event.after(0, function()
+ tap.done(checks_total)
+ end)
+end
+-- Deckard query will execute tap.done() which will call os.exit()
+-- i.e. this callback has to be called only after answer to Deckard was sent
+policy.add(policy.suffix(tests_done, {'\4done\0'}), true)
+
+-- add delay to each query to force scheduler to interleave tests and DNS queries
+policy.add(policy.all(
+ function()
+ local delay = 10 -- ms
+ log_info(ffi.C.LOG_GRP_TESTS, 'packet delayed by %d ms', delay)
+ worker.sleep(delay / 1000)
+ end))
+
+wait_for_sockets()
+
+{% if DAEMON_NAME == "kresd1" %}
+
+-- forward to Deckard test server
+policy.add(policy.all(policy.FORWARD('192.0.2.1')))
+
+{% else %}
+
+-- forward to next kresd instance in chain
+{# find out IP address of kresd instance with lower number,
+ i.e. kresd2 forwards to kresd1 #}
+policy.add(policy.all(policy.FORWARD('{{ PROGRAMS[ "kresd" ~ (DAEMON_NAME[-1]|int() - 1)]["address"] }}')))
+
+{% endif %}
diff --git a/daemon/lua/map.test.integr/query-while-map-is-running.rpl b/daemon/lua/map.test.integr/query-while-map-is-running.rpl
new file mode 100644
index 0000000..8590fc8
--- /dev/null
+++ b/daemon/lua/map.test.integr/query-while-map-is-running.rpl
@@ -0,0 +1,312 @@
+; does not make any practical difference so we limit ourselves to single test run
+query-minimization: off
+CONFIG_END
+
+SCENARIO_BEGIN Empty answers to any query - forwarding without validation
+
+; forwarding target
+RANGE_BEGIN 1 1000000
+ ADDRESS 192.0.2.1
+
+; NODATA to everything
+ENTRY_BEGIN
+MATCH opcode
+ADJUST copy_id copy_query
+REPLY NOERROR QR
+SECTION QUESTION
+. IN SOA
+SECTION ANSWER
+. 86400 IN SOA rootns. you.test. 2017071100 1800 900 604800 86400
+ENTRY_END
+RANGE_END
+
+STEP 10 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+start. IN TXT
+ENTRY_END
+
+STEP 11 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY NOERROR QR RD RA
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+start. IN TXT
+SECTION ANSWER
+ENTRY_END
+
+
+STEP 1001 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+test1001. IN TXT
+ENTRY_END
+
+STEP 1002 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY NOERROR QR RD RA
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test1001. IN TXT
+SECTION ANSWER
+ENTRY_END
+
+STEP 1003 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+test1003. IN TXT
+ENTRY_END
+
+STEP 1004 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY NOERROR QR RD RA
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test1003. IN TXT
+SECTION ANSWER
+ENTRY_END
+
+STEP 1005 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+test1005. IN TXT
+ENTRY_END
+
+STEP 1006 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY NOERROR QR RD RA
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test1005. IN TXT
+SECTION ANSWER
+ENTRY_END
+
+STEP 1007 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+test1007. IN TXT
+ENTRY_END
+
+STEP 1008 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY NOERROR QR RD RA
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test1007. IN TXT
+SECTION ANSWER
+ENTRY_END
+
+STEP 1009 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+test1009. IN TXT
+ENTRY_END
+
+STEP 1010 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY NOERROR QR RD RA
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test1009. IN TXT
+SECTION ANSWER
+ENTRY_END
+
+STEP 1011 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+test1011. IN TXT
+ENTRY_END
+
+STEP 1012 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY NOERROR QR RD RA
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test1011. IN TXT
+SECTION ANSWER
+ENTRY_END
+
+STEP 1013 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+test1013. IN TXT
+ENTRY_END
+
+STEP 1014 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY NOERROR QR RD RA
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test1013. IN TXT
+SECTION ANSWER
+ENTRY_END
+
+STEP 1015 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+test1015. IN TXT
+ENTRY_END
+
+STEP 1016 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY NOERROR QR RD RA
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test1015. IN TXT
+SECTION ANSWER
+ENTRY_END
+
+STEP 1017 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+test1017. IN TXT
+ENTRY_END
+
+STEP 1018 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY NOERROR QR RD RA
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test1017. IN TXT
+SECTION ANSWER
+ENTRY_END
+
+STEP 1019 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+test1019. IN TXT
+ENTRY_END
+
+STEP 1020 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY NOERROR QR RD RA
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test1019. IN TXT
+SECTION ANSWER
+ENTRY_END
+
+STEP 1021 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+test1021. IN TXT
+ENTRY_END
+
+STEP 1022 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY NOERROR QR RD RA
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test1021. IN TXT
+SECTION ANSWER
+ENTRY_END
+
+STEP 1023 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+test1023. IN TXT
+ENTRY_END
+
+STEP 1024 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY NOERROR QR RD RA
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test1023. IN TXT
+SECTION ANSWER
+ENTRY_END
+
+STEP 1025 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+test1025. IN TXT
+ENTRY_END
+
+STEP 1026 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY NOERROR QR RD RA
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test1025. IN TXT
+SECTION ANSWER
+ENTRY_END
+
+STEP 1027 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+test1027. IN TXT
+ENTRY_END
+
+STEP 1028 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY NOERROR QR RD RA
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test1027. IN TXT
+SECTION ANSWER
+ENTRY_END
+
+STEP 1029 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+test1029. IN TXT
+ENTRY_END
+
+STEP 1030 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY NOERROR QR RD RA
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test1029. IN TXT
+SECTION ANSWER
+ENTRY_END
+
+STEP 1031 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+test1031. IN TXT
+ENTRY_END
+
+STEP 1032 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY NOERROR QR RD RA
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test1031. IN TXT
+SECTION ANSWER
+ENTRY_END
+
+STEP 1033 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+done. IN TXT
+ENTRY_END
+
+STEP 1034 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY NOERROR QR RD RA
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+done. IN TXT
+SECTION ANSWER
+ENTRY_END
+
+SCENARIO_END
diff --git a/daemon/lua/meson.build b/daemon/lua/meson.build
new file mode 100644
index 0000000..b19777c
--- /dev/null
+++ b/daemon/lua/meson.build
@@ -0,0 +1,118 @@
+# daemon: lua modules
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+config_tests += [
+ ['controlsock', files('controlsock.test.lua')],
+ ['krprint', files('krprint.test.lua')],
+ ['log', files('log.test.lua')],
+ ['ta', files('trust_anchors.test/ta.test.lua')],
+ ['ta_bootstrap', files('trust_anchors.test/bootstrap.test.lua'), ['y2k38']],
+]
+
+integr_tests += [
+ ['map', meson.current_source_dir() / 'map.test.integr'],
+]
+
+lua_config = configuration_data()
+lua_config.set('keyfile_default', keyfile_default)
+lua_config.set('etc_dir', etc_dir)
+lua_config.set('run_dir', run_dir)
+lua_config.set('systemd_cache_dir', systemd_cache_dir)
+lua_config.set('unmanaged', managed_ta ? 'false' : 'true')
+
+trust_anchors = configure_file(
+ input: 'trust_anchors.lua.in',
+ output: 'trust_anchors.lua',
+ configuration: lua_config,
+)
+
+sandbox = configure_file(
+ input: 'sandbox.lua.in',
+ output: 'sandbox.lua',
+ configuration: lua_config,
+)
+
+distro_preconfig = configure_file(
+ input: 'distro-preconfig.lua.in',
+ output: 'distro-preconfig.lua',
+ configuration: lua_config,
+)
+
+# Unfortunately the different ABI implies different contents of 'kres-gen.lua'.
+if libknot.version().version_compare('>= 3.2')
+ kres_gen_fname = 'kres-gen-32.lua'
+elif libknot.version().version_compare('>= 3.1')
+ kres_gen_fname = 'kres-gen-31.lua'
+else
+ kres_gen_fname = 'kres-gen-30.lua'
+endif
+
+kres_gen_lua = configure_file(
+ input: kres_gen_fname,
+ output: 'kres-gen.lua',
+ copy: true,
+)
+
+run_target( # run manually to re-generate kres-gen.lua
+ 'kres-gen',
+ command: [ find_program('./kres-gen.sh'), kres_gen_fname ],
+)
+
+# A simple config test: check that sizes of some structures match
+# in C and pre-generated lua bindings.
+# The point is that regeneration is quite expensive in time and dependencies,
+# but this basic sanity check could be ran always, except for cross compilation,
+# as we *run* luajit to find out the real sizes.
+if get_option('kres_gen_test') and not meson.is_cross_build()
+ types_to_check = [
+ { 'tname': 'time_t', 'incl': '#include <sys/time.h>' },
+ { 'tname': 'struct timeval', 'incl' : '#include <sys/time.h>' },
+ { 'tname': 'zs_scanner_t', 'incl': '#include <libzscanner/scanner.h>', 'dep': libzscanner },
+ { 'tname': 'knot_pkt_t', 'incl' : '#include <libknot/packet/pkt.h>', 'dep': libknot },
+ ]
+ # Construct the lua tester as a meson string.
+ kres_gen_test_luastr = '''
+ dofile('@0@')
+ local ffi = require('ffi')
+ '''.format(meson.current_source_dir() / kres_gen_fname)
+ foreach ttc: types_to_check
+ # We're careful with adding just includes; otherwise it's more fragile (e.g. linking flags).
+ if 'dep' in ttc
+ dep = ttc.get('dep').partial_dependency(includes: true, compile_args: true)
+ else
+ dep = []
+ endif
+ tsize = meson.get_compiler('c').sizeof(ttc.get('tname'), prefix: ttc.get('incl'),
+ dependencies: dep)
+ kres_gen_test_luastr += '''
+ assert(ffi.sizeof(ffi.typeof('@0@')) == @1@,
+ 'Lua binding for C type ' .. '@0@' .. ' has incorrect size: '
+ .. ffi.sizeof(ffi.typeof('@0@'))
+ )
+ '''.format(ttc.get('tname'), tsize)
+ endforeach
+ # Now feed it directly into luajit.
+ kres_gen_test = run_command(find_program('luajit'), '-e', kres_gen_test_luastr, check: false)
+ if kres_gen_test.returncode() != 0
+ error('if you use released Knot* versions, please contact us: https://www.knot-resolver.cz/contact/\n'
+ + kres_gen_test.stderr().strip())
+ endif
+endif
+
+lua_src = [
+ files('postconfig.lua'),
+ files('kres.lua'),
+ kres_gen_lua,
+ sandbox,
+ trust_anchors,
+ files('zonefile.lua'),
+ files('kluautil.lua'),
+ files('krprint.lua'),
+ distro_preconfig,
+]
+
+# install daemon lua sources
+install_data(
+ lua_src,
+ install_dir: lib_dir,
+)
diff --git a/daemon/lua/postconfig.lua b/daemon/lua/postconfig.lua
new file mode 100644
index 0000000..ac71660
--- /dev/null
+++ b/daemon/lua/postconfig.lua
@@ -0,0 +1,70 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+
+local ffi = require('ffi')
+local C = ffi.C
+
+local function count_sockets()
+ local dns_socks = 0
+ local control_socks = 0
+ for _, socket in ipairs(net.list()) do
+ if socket.kind == 'control' then
+ control_socks = control_socks + 1
+ elseif (socket.kind == 'dns' or
+ socket.kind == 'xdp' or
+ socket.kind == 'tls' or
+ socket.kind == 'doh_legacy' or
+ socket.kind == 'doh2') then
+ dns_socks = dns_socks + 1
+ end
+ end
+ return dns_socks, control_socks
+end
+
+local n_dns_socks, n_control_socks = count_sockets()
+
+-- Check and set control sockets path
+worker.control_path = worker.control_path or (worker.cwd .. '/control/')
+
+-- Bind to control socket by default
+if n_control_socks == 0 and not env.KRESD_NO_LISTEN then
+ local path = worker.control_path..worker.pid
+ local ok, err = pcall(net.listen, path, nil, { kind = 'control' })
+ if not ok then
+ log_warn(C.LOG_GRP_NETWORK, 'bind to '..path..' failed '..err)
+ end
+end
+
+-- Listen on localhost
+if n_dns_socks == 0 and not env.KRESD_NO_LISTEN then
+ local ok, err = pcall(net.listen, '127.0.0.1')
+ if not ok then
+ error('bind to 127.0.0.1@53 '..err)
+ end
+ -- Binding to other ifaces may fail
+ ok, err = pcall(net.listen, '127.0.0.1', 853)
+ if not ok then
+ log_info(ffi.C.LOG_GRP_NETWORK, 'bind to 127.0.0.1@853 '..err)
+ end
+ ok, err = pcall(net.listen, '::1')
+ if not ok then
+ log_info(ffi.C.LOG_GRP_NETWORK, 'bind to ::1@53 '..err)
+ end
+ ok, err = pcall(net.listen, '::1', 853)
+ if not ok then
+ log_info(ffi.C.LOG_GRP_NETWORK, 'bind to ::1@853 '..err)
+ end
+ -- Exit when kresd isn't listening on any interfaces
+ n_dns_socks, _ = count_sockets()
+ if n_dns_socks == 0 then
+ panic('not listening on any interface, exiting...')
+ end
+end
+-- Open cache if not set/disabled
+if not cache.current_size then
+ cache.size = 100 * MB
+end
+
+-- If no addresses for root servers are set, load them from the default file
+if C.kr_zonecut_is_empty(kres.context().root_hints) then
+ _hint_root_file()
+end
diff --git a/daemon/lua/sandbox.lua.in b/daemon/lua/sandbox.lua.in
new file mode 100644
index 0000000..7c6a818
--- /dev/null
+++ b/daemon/lua/sandbox.lua.in
@@ -0,0 +1,833 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+
+local debug = require('debug')
+local ffi = require('ffi')
+local kluautil = require('kluautil')
+local krprint = require("krprint")
+
+-- Units
+kB = 1024
+MB = 1024*kB
+GB = 1024*MB
+-- Time
+sec = 1000
+second = sec
+minute = 60 * sec
+min = minute
+hour = 60 * minute
+day = 24 * hour
+
+-- Logging
+
+-- from syslog.h
+LOG_CRIT = 2
+LOG_ERR = 3
+LOG_WARNING = 4
+LOG_NOTICE = 5
+LOG_INFO = 6
+LOG_DEBUG = 7
+
+local function curr_file() return debug.getinfo(4,'S').source end
+local function curr_line() return debug.getinfo(4,'l').currentline end
+
+local function log_fmt(grp, level, fmt, ...)
+ ffi.C.kr_log_fmt(grp, level,
+ 'CODE_FILE='..curr_file(), 'CODE_LINE='..curr_line(), 'CODE_FUNC=',
+ '[%-6s] %s\n', ffi.C.kr_log_grp2name(grp), string.format(fmt, ...))
+end
+
+function log_req(req, qry_uid, indent, grp, fmt, ...)
+ ffi.C.kr_log_req1(req, qry_uid, indent, grp, ffi.C.kr_log_grp2name(grp),
+ '%s\n', string.format(fmt, ...))
+end
+
+function log_qry(qry, grp, fmt, ...)
+ ffi.C.kr_log_q1(qry, grp, ffi.C.kr_log_grp2name(grp),
+ '%s\n', string.format(fmt, ...))
+end
+
+function panic(fmt, ...)
+ print(debug.traceback('error occurred here (config filename:lineno is '
+ .. 'at the bottom, if config is involved):', 2))
+ error(string.format('ERROR: '.. fmt, ...), 0)
+end
+
+function log_error(grp, fmt, ...)
+ log_fmt(grp, LOG_ERR, fmt, ...)
+end
+
+function log_warn(grp, fmt, ...)
+ log_fmt(grp, LOG_WARNING, fmt, ...)
+end
+
+function log_notice(grp, fmt, ...)
+ log_fmt(grp, LOG_NOTICE, fmt, ...)
+end
+
+function log_info(grp, fmt, ...)
+ log_fmt(grp, LOG_INFO, fmt, ...)
+end
+
+function log_debug(grp, fmt, ...)
+ log_fmt(grp, LOG_DEBUG, fmt, ...)
+end
+
+function log(fmt, ...)
+ log_notice(ffi.C.LOG_GRP_MODULE, fmt, ...)
+end
+
+-- Resolver bindings
+kres = require('kres')
+if rawget(kres, 'str2dname') ~= nil then
+ todname = kres.str2dname
+end
+
+worker.resolve_pkt = function (pkt, options, finish, init)
+ options = kres.mk_qflags(options)
+ local task = ffi.C.worker_resolve_start(pkt, options)
+
+ -- Deal with finish and init callbacks
+ if finish ~= nil then
+ local finish_cb
+ finish_cb = ffi.cast('trace_callback_f',
+ function (req)
+ jit.off(true, true) -- JIT for (C -> lua)^2 nesting isn't allowed
+ finish(req.answer, req)
+ finish_cb:free()
+ end)
+ task.ctx.req.trace_finish = finish_cb
+ end
+ if init ~= nil then
+ init(task.ctx.req)
+ end
+
+ return ffi.C.worker_resolve_exec(task, pkt) == 0
+end
+
+worker.resolve = function (qname, qtype, qclass, options, finish, init)
+ -- Alternatively use named arguments
+ if type(qname) == 'table' then
+ local t = qname
+ qname = t.name
+ qtype = t.type
+ qclass = t.class
+ options = t.options
+ finish = t.finish
+ init = t.init
+ end
+ qtype = qtype or kres.type.A
+ qclass = qclass or kres.class.IN
+ options = kres.mk_qflags(options)
+ -- LATER: nicer errors for rubbish in qname, qtype, qclass?
+ local pkt = ffi.C.worker_resolve_mk_pkt(qname, qtype, qclass, options)
+ if pkt == nil then
+ panic('failure in worker.resolve(); probably invalid qname "%s"', qname)
+ end
+ local ret = worker.resolve_pkt(pkt, options, finish, init)
+ ffi.C.knot_pkt_free(pkt);
+ return ret
+end
+resolve = worker.resolve
+
+-- Shorthand for aggregated per-worker information
+worker.info = function ()
+ local t = worker.stats()
+ t.pid = worker.pid
+ return t
+end
+
+-- Resolver mode of operation
+local current_mode = 'normal'
+local mode_table = { normal=0, strict=1, permissive=2 }
+function mode(m)
+ if not m then return current_mode end
+ if not mode_table[m] then error('unsupported mode: '..m) end
+ -- Update current operation mode
+ current_mode = m
+ option('STRICT', current_mode == 'strict')
+ option('PERMISSIVE', current_mode == 'permissive')
+ return true
+end
+
+-- Trivial option alias
+function reorder_RR(val)
+ return option('REORDER_RR', val)
+end
+
+-- Get/set resolver options via name (string)
+function option(name, val)
+ local flags = kres.context().options;
+ -- Note: no way to test existence of flags[name] but we want error anyway.
+ name = string.upper(name) -- convenience
+ if val ~= nil then
+ if (val ~= true) and (val ~= false) then
+ panic('invalid option value: ' .. tostring(val))
+ end
+ flags[name] = val;
+ end
+ return flags[name];
+end
+
+-- Function aliases
+-- `env.VAR returns os.getenv(VAR)`
+env = {}
+setmetatable(env, {
+ __index = function (_, k) return os.getenv(k) end
+})
+
+debugging = {}
+setmetatable(debugging, {
+ __index = function(_, k)
+ if k == 'assertion_abort' then return ffi.C.kr_dbg_assertion_abort
+ elseif k == 'assertion_fork' then return ffi.C.kr_dbg_assertion_fork
+ else panic('invalid debugging option: ' .. tostring(k))
+ end
+ end,
+ __newindex = function(_, k, v)
+ if k == 'assertion_abort' then ffi.C.kr_dbg_assertion_abort = v
+ elseif k == 'assertion_fork' then ffi.C.kr_dbg_assertion_fork = v
+ else panic('invalid debugging option: ' .. tostring(k))
+ end
+ end
+})
+
+-- Quick access to interfaces
+-- `net.<iface>` => `net.interfaces()[iface]`
+-- `net = {addr1, ..}` => `net.listen(name, addr1)`
+-- `net.ipv{4,6} = {true, false}` => enable/disable IPv{4,6}
+setmetatable(net, {
+ __index = function (t, k)
+ local v = rawget(t, k)
+ if v then return v
+ elseif k == 'ipv6' then return not option('NO_IPV6')
+ elseif k == 'ipv4' then return not option('NO_IPV4')
+ else return net.interfaces()[k]
+ end
+ end,
+ __newindex = function (t,k,v)
+ if k == 'ipv6' then return option('NO_IPV6', not v)
+ elseif k == 'ipv4' then return option('NO_IPV4', not v)
+ else
+ local iname = rawget(net.interfaces(), v)
+ if iname then t.listen(iname)
+ else t.listen(v)
+ end
+ end
+ end
+})
+
+-- Syntactic sugar for module loading
+-- `modules.<name> = <config>`
+setmetatable(modules, {
+ __newindex = function (_, k, v)
+ if type(k) == 'number' then
+ k, v = v, nil
+ end
+ if not rawget(_G, k) then
+ modules.load(k)
+ k = string.match(k, '[%w_]+')
+ local mod = _G[k]
+ local config = mod and rawget(mod, 'config')
+ if mod ~= nil and config ~= nil then
+ if k ~= v then config(v)
+ else config()
+ end
+ end
+ end
+ end
+})
+
+-- Set up lua table for a C module. (Internal function.)
+function modules_create_table_for_c(kr_module_ud)
+ local kr_module = ffi.cast('struct kr_module **', kr_module_ud)[0]
+ --- Set up the global table named according to the module.
+ if kr_module.config == nil and kr_module.props == nil then
+ return
+ end
+ local module = {}
+ local module_name = ffi.string(kr_module.name)
+ _G[module_name] = module
+
+ --- Construct lua functions for properties.
+ if kr_module.props ~= nil then
+ local i = 0
+ while true do
+ local prop = kr_module.props[i]
+ local cb = prop.cb
+ if cb == nil then break; end
+ module[ffi.string(prop.name)] =
+ function (arg) -- lua wrapper around kr_prop_cb function typedef
+ local arg_conv
+ if type(arg) == 'table' or type(arg) == 'boolean' then
+ arg_conv = tojson(arg)
+ elseif arg ~= nil then
+ arg_conv = tostring(arg)
+ end
+ local ret_cstr = cb(ffi.C.the_worker.engine, kr_module, arg_conv)
+ if ret_cstr == nil then
+ return nil
+ end
+ -- LATER(optim.): superfluous copying
+ local ret_str = ffi.string(ret_cstr)
+ -- This is a bit ugly, but the API is that invalid JSON
+ -- should be just returned as string :-(
+ local status, ret = pcall(fromjson, ret_str)
+ if not status then ret = ret_str end
+ ffi.C.free(ret_cstr)
+ return ret
+ end
+ i = i + 1
+ end
+ end
+
+ --- Construct lua function for config().
+ if kr_module.config ~= nil then
+ module.config =
+ function (arg)
+ local arg_conv
+ if type(arg) == 'table' or type(arg) == 'boolean' then
+ arg_conv = tojson(arg)
+ elseif arg ~= nil then
+ arg_conv = tostring(arg)
+ end
+ return kr_module.config(kr_module, arg_conv)
+ end
+ end
+
+ --- Add syntactic sugar for get() and set() properties.
+ --- That also "catches" any commands like `moduleName.foo = bar`.
+ local m_index, m_newindex
+ local get_f = rawget(module, 'get')
+ if get_f ~= nil then
+ m_index = function (_, key)
+ return get_f(key)
+ end
+ else
+ m_index = function ()
+ error('module ' .. module_name .. ' does not support indexing syntax sugar')
+ end
+ end
+ local set_f = rawget(module, 'set')
+ if set_f ~= nil then
+ m_newindex = function (_, key, value)
+ -- This will produce a nasty error on some non-string parameters.
+ -- Still, we already use it with integer values, e.g. in predict module :-/
+ return set_f(key .. ' ' .. value)
+ end
+ else
+ m_newindex = function ()
+ error('module ' .. module_name .. ' does not support assignment syntax sugar')
+ end
+ end
+ setmetatable(module, {
+ -- note: the two functions only get called for *missing* indices
+ __index = m_index,
+ __newindex = m_newindex,
+ })
+end
+
+local layer_ctx = ffi.C.kr_layer_t_static
+-- Utilities internal for lua layer glue; see ../ffimodule.c
+modules_ffi_layer_wrap1 = function (layer_cb)
+ return layer_cb(layer_ctx.state, layer_ctx.req)
+end
+modules_ffi_layer_wrap2 = function (layer_cb)
+ return layer_cb(layer_ctx.state, layer_ctx.req, layer_ctx.pkt)
+end
+modules_ffi_layer_wrap_checkout = function (layer_cb)
+ return layer_cb(layer_ctx.state, layer_ctx.req, layer_ctx.pkt,
+ layer_ctx.dst, layer_ctx.is_stream)
+end
+modules_ffi_wrap_modcb = function (cb, kr_module_ud) -- this one isn't for layer
+ local kr_module = ffi.cast('struct kr_module **', kr_module_ud)[0]
+ return cb(kr_module)
+end
+
+-- Return filesystem size where the cache resides.
+cache.fssize = function ()
+ local path = cache.current_storage or '.'
+ -- As it is now, `path` may or may not include the lmdb:// prefix.
+ if string.sub(path, 1, 7) == 'lmdb://' then
+ path = string.sub(path, 8)
+ end
+ if #path == 0 then
+ path = '.'
+ end
+ local size = tonumber(ffi.C.kr_fssize(path))
+ if size < 0 then
+ panic('cache.fssize(): %s', ffi.string(ffi.C.knot_strerror(size)))
+ else
+ return size
+ end
+end
+
+cache.clear = function (name, exact_name, rr_type, chunk_size, callback, prev_state)
+ if name == nil or (name == '.' and not exact_name) then
+ -- keep same output format as for 'standard' clear
+ local total_count = cache.count()
+ if not cache.clear_everything() then
+ error('unable to clear everything')
+ end
+ return {count = total_count}
+ end
+ -- Check parameters, in order, and set defaults if missing.
+ local dname = kres.str2dname(name)
+ if not dname then error('cache.clear(): incorrect name passed') end
+ if exact_name == nil then exact_name = false end
+ if type(exact_name) ~= 'boolean'
+ then error('cache.clear(): incorrect exact_name passed') end
+
+ local cach = kres.context().cache;
+ local rettable = {}
+ -- Apex warning. If the caller passes a custom callback,
+ -- we assume they are advanced enough not to need the check.
+ -- The point is to avoid repeating the check in each callback iteration.
+ if callback == nil then
+ local apex_array = ffi.new('knot_dname_t *[1]') -- C: dname **apex_array
+ local ret = ffi.C.kr_cache_closest_apex(cach, dname, false, apex_array)
+ if ret < 0 then
+ error(ffi.string(ffi.C.knot_strerror(ret))) end
+ if not ffi.C.knot_dname_is_equal(apex_array[0], dname) then
+ local apex_str = kres.dname2str(apex_array[0])
+ rettable.not_apex = 'to clear proofs of non-existence call '
+ .. 'cache.clear(\'' .. tostring(apex_str) ..'\')'
+ rettable.subtree = apex_str
+ end
+ ffi.C.free(apex_array[0])
+ end
+
+ if rr_type ~= nil then
+ -- Special case, without any subtree searching.
+ if not exact_name
+ then error('cache.clear(): specifying rr_type only supported with exact_name') end
+ if chunk_size or callback
+ then error('cache.clear(): chunk_size and callback parameters not supported with rr_type') end
+ local ret = ffi.C.kr_cache_remove(cach, dname, rr_type)
+ if ret < 0 then error(ffi.string(ffi.C.knot_strerror(ret))) end
+ return {count = 1}
+ end
+
+ if chunk_size == nil then chunk_size = 100 end
+ if type(chunk_size) ~= 'number' or chunk_size <= 0
+ then error('cache.clear(): chunk_size has to be a positive integer') end
+
+ -- Do the C call, and add chunk_size warning.
+ rettable.count = ffi.C.kr_cache_remove_subtree(cach, dname, exact_name, chunk_size)
+ if rettable.count == chunk_size then
+ local msg_extra = ''
+ if callback == nil then
+ msg_extra = '; the default callback will continue asynchronously'
+ end
+ rettable.chunk_limit = 'chunk size limit reached' .. msg_extra
+ end
+
+ -- Default callback function: repeat after 1ms
+ if callback == nil then callback =
+ function (cbname, cbexact_name, cbrr_type, cbchunk_size, cbself, cbprev_state, cbrettable)
+ if cbrettable.count < 0 then error(ffi.string(ffi.C.knot_strerror(cbrettable.count))) end
+ if cbprev_state == nil then cbprev_state = { round = 0 } end
+ if type(cbprev_state) ~= 'table'
+ then error('cache.clear() callback: incorrect prev_state passed') end
+ cbrettable.round = cbprev_state.round + 1
+ if (cbrettable.count == cbchunk_size) then
+ event.after(1, function ()
+ cache.clear(cbname, cbexact_name, cbrr_type, cbchunk_size, cbself, cbrettable)
+ end)
+ elseif cbrettable.round > 1 then
+ log_info(ffi.C.LOG_GRP_CACHE, 'asynchronous cache.clear(\'' .. cbname .. '\', '
+ .. tostring(cbexact_name) .. ') finished')
+ end
+ return cbrettable
+ end
+ end
+ return callback(name, exact_name, rr_type, chunk_size, callback, prev_state, rettable)
+end
+-- Syntactic sugar for cache
+-- `cache[x] -> cache.get(x)`
+-- `cache.{size|storage} = value`
+setmetatable(cache, {
+ __index = function (t, k)
+ local res = rawget(t, k)
+ if not res and not rawget(t, 'current_size') then return res end
+ -- Beware: t.get returns empty table on failure to find.
+ -- That would be confusing here (breaking kresc), so return nil instead.
+ res = t.get(k)
+ if res and next(res) ~= nil then return res else return nil end
+ end,
+ __newindex = function (t,k,v)
+ -- Defaults
+ local storage = rawget(t, 'current_storage')
+ if not storage then storage = 'lmdb://' end
+ local size = rawget(t, 'current_size')
+ if not size then size = 10*MB end
+ -- Declarative interface for cache
+ if k == 'size' then t.open(v, storage)
+ elseif k == 'storage' then t.open(size, v) end
+ end
+})
+
+-- Make sandboxed environment
+local function make_sandbox(defined)
+ local __protected = {
+ worker = true, env = true, debugging = true, modules = true,
+ cache = true, net = true, trust_anchors = true
+ }
+
+ -- Compute and export the list of top-level names (hidden otherwise)
+ local nl = ""
+ for n in pairs(defined) do
+ nl = nl .. n .. "\n"
+ end
+
+ return setmetatable({ __orig_name_list = nl }, {
+ __index = defined,
+ __newindex = function (_, k, v)
+ if __protected[k] then
+ for k2,v2 in pairs(v) do
+ defined[k][k2] = v2
+ end
+ else
+ defined[k] = v
+ end
+ end
+ })
+end
+
+-- Compatibility sandbox
+_G = make_sandbox(getfenv(0))
+setfenv(0, _G)
+
+-- Load default modules
+trust_anchors = require('trust_anchors')
+modules.load('ta_update')
+modules.load('ta_signal_query')
+modules.load('policy')
+modules.load('priming')
+modules.load('detect_time_skew')
+modules.load('detect_time_jump')
+modules.load('ta_sentinel')
+modules.load('edns_keepalive')
+modules.load('refuse_nord')
+modules.load('watchdog')
+modules.load('extended_error')
+
+-- Load keyfile_default
+trust_anchors.add_file('@keyfile_default@', @unmanaged@)
+
+local function eval_cmd_compile(line, raw)
+ -- Compatibility sandbox code loading
+ local function load_code(code)
+ if getfenv then -- Lua 5.1
+ return loadstring(code)
+ else -- Lua 5.2+
+ return load(code, nil, 't', _ENV)
+ end
+ end
+ local err, chunk
+ chunk, err = load_code(raw and 'return '..line or 'return table_print('..line..')')
+ if err then
+ chunk, err = load_code(line)
+ end
+ return chunk, err
+end
+
+-- Interactive command evaluation
+function eval_cmd(line, raw)
+ local chunk, err = eval_cmd_compile(line, raw)
+ if not err then
+ return chunk()
+ else
+ error(err)
+ end
+end
+
+-- Pretty printing
+local pprint = require('krprint').pprint
+function table_print(...)
+ local strs = {}
+ local nargs = select('#', ...)
+ if nargs == 0 then
+ return nil
+ end
+ for n=1,nargs do
+ local arg = select(n, ...)
+ local arg_str = pprint(arg)
+ if nargs > 1 then
+ table.insert(strs, string.format("%s\t-- result # %d", arg_str, n))
+ else
+ table.insert(strs, arg_str)
+ end
+ end
+ return table.concat(strs, '\n')
+end
+
+-- This extends the worker module to allow asynchronous execution of functions and nonblocking I/O.
+-- The current implementation combines cqueues for Lua interface, and event.socket() in order to not
+-- block resolver engine while waiting for I/O or timers.
+--
+local has_cqueues, cqueues = pcall(require, 'cqueues')
+if has_cqueues then
+
+ -- Export the asynchronous sleep function
+ worker.sleep = cqueues.sleep
+
+ -- Create metatable for workers to define the API
+ -- It can schedule multiple cqueues and yield execution when there's a wait for blocking I/O or timer
+ local asynchronous_worker_mt = {
+ work = function (self)
+ local ok, err, _, co = self.cq:step(0)
+ if not ok then
+ log_warn(ffi.C.LOG_GRP_SYSTEM, '%s error: %s %s', self.name or 'worker', err, debug.traceback(co))
+ end
+ -- Reschedule timeout or create new one
+ local timeout = self.cq:timeout()
+ if timeout then
+ -- Throttle timeouts to avoid too frequent wakeups
+ if timeout == 0 then timeout = 0.00001 end
+ -- Convert from seconds to duration
+ timeout = timeout * sec
+ if not self.next_timeout then
+ self.next_timeout = event.after(timeout, self.on_step)
+ else
+ event.reschedule(self.next_timeout, timeout)
+ end
+ else -- Cancel running timeout when there is no next deadline
+ if self.next_timeout then
+ event.cancel(self.next_timeout)
+ self.next_timeout = nil
+ end
+ end
+ end,
+ wrap = function (self, f)
+ self.cq:wrap(f)
+ end,
+ loop = function (self)
+ self.on_step = function () self:work() end
+ self.event_fd = event.socket(self.cq:pollfd(), self.on_step)
+ end,
+ close = function (self)
+ if self.event_fd then
+ event.cancel(self.event_fd)
+ self.event_fd = nil
+ end
+ end,
+ }
+
+ -- Implement the coroutine worker with cqueues
+ local function worker_new (name)
+ return setmetatable({name = name, cq = cqueues.new()}, { __index = asynchronous_worker_mt })
+ end
+
+ -- Create a default background worker
+ worker.bg_worker = worker_new('worker.background')
+ worker.bg_worker:loop()
+
+ -- Wrap a function for asynchronous execution
+ function worker.coroutine (f)
+ worker.bg_worker:wrap(f)
+ end
+else
+ -- Disable asynchronous execution
+ local function disabled ()
+ error('Lua library cqueues is required for asynchronous execution (luaJIT requires library for Lua 5.1)')
+ end
+ worker.sleep = disabled
+ worker.map = disabled
+ worker.coroutine = disabled
+ worker.bg_worker = setmetatable({}, { __index = disabled })
+end
+
+-- Global commands for map()
+
+-- must be public because it is called from eval_cmd()
+-- when map() commands are read from control socket
+function _map_luaobj_call_wrapper(cmd)
+ local func = eval_cmd_compile(cmd, true)
+ local ret = kluautil.kr_table_pack(xpcall(func, debug.traceback))
+ local ok, serial = pcall(krprint.serialize_lua, ret, 'error')
+ if not ok then
+ log_error(ffi.C.LOG_GRP_SYSTEM, 'failed to serialize map() response %s (%s)',
+ table_print(ret), serial)
+ return krprint.serialize_lua(
+ kluautil.kr_table_pack(false, "returned values cannot be serialized: "
+ .. serial))
+ else
+ return serial
+ end
+end
+
+local function _sock_errmsg(path, desc)
+ return string.format(
+ 'map() error while communicating with %s: %s',
+ path, desc)
+end
+
+local function _sock_check(sock, call, params, path, desc)
+ local errprefix = _sock_errmsg(path, desc) .. ': '
+ local retvals = kluautil.kr_table_pack(pcall(call, unpack(params)))
+ local ok = retvals[1]
+ if not ok then
+ error(errprefix .. tostring(retvals[2]))
+ end
+ local rerr, werr = sock:error()
+ if rerr or werr then
+ error(string.format('%sread error %s; write error %s', errprefix, rerr, werr))
+ end
+ if retvals[2] == nil then
+ error(errprefix .. 'unexpected nil result')
+ end
+ return unpack(retvals, 2, retvals.n)
+end
+
+local function _sock_assert(condition, path, desc)
+ if not condition then
+ error(_sock_errmsg(path, desc))
+ end
+end
+
+local function map_send_recv(cmd, path)
+ local bit = require('bit')
+ local socket = require('cqueues.socket')
+ local s = socket.connect({ path = path })
+ s:setmaxerrs(0)
+ s:setmode('bn', 'bn')
+ local status, err = pcall(s.connect, s)
+ if not status then
+ log_error(ffi.C.LOG_GRP_NETWORK, 'map() error while connecting to control socket %s: '
+ .. '%s (ignoring this socket)', path, err)
+ return nil
+ end
+ local ret = _sock_check(s, s.write, {s, '__binary\n'}, path,
+ 'write __binary')
+ _sock_assert(ret, path,
+ 'write __binary result')
+ local recv = _sock_check(s, s.read, {s, 2}, path,
+ 'read reply to __binary')
+ _sock_assert(recv and recv == '> ', path,
+ 'unexpected reply to __binary')
+ _sock_check(s, s.write, {s, cmd..'\n'}, path,
+ 'command write')
+ recv = _sock_check(s, s.read, {s, 4}, path,
+ 'response length read')
+ _sock_assert(recv and #recv == 4, path,
+ 'length of response length preamble does not match')
+ local len = tonumber(recv:byte(1))
+ for i=2,4 do
+ len = bit.bor(bit.lshift(len, 8), tonumber(recv:byte(i)))
+ end
+ ret = _sock_check(s, s.read, {s, len}, path,
+ 'read response')
+ _sock_assert(ret and #ret == len, path,
+ 'actual response length does not match length in preamble')
+ s:close()
+ return ret
+end
+
+-- internal use only
+-- Call cmd on each instance via control sockets.
+-- @param format - "luaobj" if individual results should be Lua objects
+-- - "strings" for eval_cmd output for each instance
+-- @returns table with results, one item per instance + key n=number of instances
+-- (order of return values is undefined)
+-- @throws Lua error if:
+-- - communication failed in the middle of transaction
+-- - a result is not serializable
+-- - individual call throws an error
+-- - number of return values != 1 per instance per call
+-- - cmd execution state is undefined after an error
+-- Connection errors at the beginning are ignored to paper over leftover dead sockets.
+function map(cmd, format)
+ local local_sockets = {}
+ local results = {}
+
+ if (type(cmd) ~= 'string') then
+ panic('map() command must be a string') end
+ if string.find(cmd, '\n', 1, true) then
+ panic('map() command cannot contain literal \\n, escape it with \\010') end
+ if (#cmd <= 0) then
+ panic('map() command must be non-empty') end
+ -- syntax check on input command to detect typos early
+ local chunk, err = eval_cmd_compile(cmd, false)
+ if not chunk then
+ panic('failure when compiling map() command: %s', err)
+ end
+
+ format = format or 'luaobj'
+ if (format ~= 'luaobj' and format ~= 'strings') then
+ panic('map() output format must be luaobj or strings') end
+ if format == 'luaobj' then
+ cmd = '_map_luaobj_call_wrapper([=====[' .. cmd .. ']=====])'
+ end
+
+ -- find out control socket paths
+ for _,v in pairs(net.list()) do
+ if (v['kind'] == 'control') and (v['transport']['family'] == 'unix') then
+ table.insert(local_sockets, string.match(v['transport']['path'], '^.*/([^/]+)$'))
+ end
+ end
+ local filetab = kluautil.list_dir(worker.control_path)
+ if next(filetab) == nil then
+ panic('no control sockets found in directory %s',
+ worker.control_path)
+ end
+
+ local result_count = 0
+ -- finally execute it on all instances
+ for _, file in ipairs(filetab) do
+ local local_exec = false
+ for _, lsoc in ipairs(local_sockets) do
+ if file == lsoc then
+ local_exec = true
+ end
+ end
+ local path = worker.control_path..file
+ local path_name = (local_exec and 'this instance') or path
+ log_info(ffi.C.LOG_GRP_SYSTEM, 'executing map() on %s: command %s', path_name, cmd)
+ local ret
+ if local_exec then
+ ret = eval_cmd(cmd)
+ else
+ ret = map_send_recv(cmd, path)
+ -- skip dead sockets (leftovers from dead instances)
+ if ret == nil then
+ goto continue
+ end
+ end
+ result_count = result_count + 1
+ -- return value is output from eval_cmd
+ -- i.e. string including "quotes" and Lua escaping in between
+ assert(type(ret) == 'string', 'map() protocol error, '
+ .. 'string not retured by follower')
+ assert(#ret >= 2 and
+ string.sub(ret, 1, 1) == "'"
+ and string.sub(ret, -1, -1) == "'",
+ 'map() protocol error, value returned by follower does '
+ .. 'not look like a string')
+ -- deserialize string: remove "quotes" and de-escape bytes
+ ret = krprint.deserialize_lua(ret)
+ if format == 'luaobj' then
+ -- ret should be table with xpcall results serialized into string
+ ret = krprint.deserialize_lua(ret)
+ assert(type(ret) == 'table', 'map() protocol error, '
+ .. 'table with results not retured by follower')
+ if (ret.n ~= 2) then
+ log_error(ffi.C.LOG_GRP_SYSTEM, 'got unsupported map() response: %s', table_print(ret))
+ panic('unexpected number of return values in map() response: '
+ .. 'only single return value is allowed, '
+ .. 'use kluautil.kr_table_pack() helper')
+ end
+ local ok, retval = ret[1], ret[2]
+ if ok == false then
+ panic('error when executing map() command on control socket %s: '
+ .. '%s. command execution state is now undefined!',
+ path, retval)
+ end
+ -- drop wrapper table and return only the actual return value
+ ret = retval
+ end
+ results[result_count] = ret
+ ::continue::
+ end
+ results.n = result_count
+ return results
+end
diff --git a/daemon/lua/trust_anchors.lua.in b/daemon/lua/trust_anchors.lua.in
new file mode 100644
index 0000000..56a7f95
--- /dev/null
+++ b/daemon/lua/trust_anchors.lua.in
@@ -0,0 +1,532 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+
+-- Load the module
+local ffi = require 'ffi'
+local kres = require('kres')
+local C = ffi.C
+
+local trust_anchors -- the public pseudo-module, exported as global variable
+
+-- RFC5011 state table
+local key_state = {
+ Start = 'Start', AddPend = 'AddPend', Valid = 'Valid',
+ Missing = 'Missing', Revoked = 'Revoked', Removed = 'Removed'
+}
+
+local function upgrade_required(msg)
+ if msg then
+ msg = msg .. '\n'
+ else
+ msg = ''
+ end
+ panic('Configuration upgrade required: ' .. msg .. 'Please refer to ' ..
+ 'https://knot-resolver.readthedocs.io/en/stable/upgrading.html')
+end
+
+-- TODO: Move bootstrap to a separate module or even its own binary
+-- remove UTC timezone specification if present or throw error
+local function time2utc(orig_timespec)
+ local patterns = {'[+-]00:00$', 'Z$'}
+ for _, pattern in ipairs(patterns) do
+ local timespec, removals = string.gsub(orig_timespec, pattern, '')
+ if removals == 1 then
+ return timespec
+ end
+ end
+ error(string.format('unsupported time specification: %s', orig_timespec))
+end
+
+local function keydigest_is_valid(valid_from, valid_until)
+ local format = '%Y-%m-%dT%H:%M:%S'
+ local time_now = os.date('!%Y-%m-%dT%H:%M:%S') -- ! forces UTC
+ local time_diff = ffi.new('double[1]')
+ local err = ffi.C.kr_strptime_diff(
+ format, time_now, time2utc(valid_from), time_diff)
+ if (err ~= nil) then
+ error(string.format('failed to process "validFrom" constraint: %s',
+ ffi.string(err)))
+ end
+ local from_ok = time_diff[0] > 0
+
+ -- optional attribute
+ local until_ok = true
+ if valid_until then
+ err = ffi.C.kr_strptime_diff(
+ format, time_now, time2utc(valid_until), time_diff)
+ if (err ~= nil) then
+ error(string.format('failed to process "validUntil" constraint: %s',
+ ffi.string(err)))
+ end
+ until_ok = time_diff[0] < 0
+ end
+ return from_ok and until_ok
+end
+
+local function parse_xml_keydigest(attrs, inside, output)
+ local fields = {}
+ local _, n = string.gsub(attrs, "([%w]+)=\"([^\"]*)\"", function (k, v) fields[k] = v end)
+ assert(n >= 1,
+ string.format('cannot parse XML attributes from "%s"', attrs))
+ assert(fields['validFrom'],
+ string.format('mandatory KeyDigest XML attribute validFrom ' ..
+ 'not found in "%s"', attrs))
+ local valid_attrs = {id = true, validFrom = true, validUntil = true}
+ for key, _ in pairs(fields) do
+ assert(valid_attrs[key],
+ string.format('unsupported KeyDigest attribute "%s" found in "%s"',
+ key, attrs))
+ end
+
+ _, n = string.gsub(inside, "<([%w]+).->([^<]+)</[%w]+>", function (k, v) fields[k] = v end)
+ assert(n >= 1,
+ string.format('error parsing KeyDigest XML elements from "%s"',
+ inside))
+ local mandatory_elements = {'KeyTag', 'Algorithm', 'DigestType', 'Digest'}
+ for _, key in ipairs(mandatory_elements) do
+ assert(fields[key],
+ string.format('mandatory element %s is missing in "%s"',
+ key, inside))
+ end
+ assert(n == 4, string.format('found %d elements but expected 4 in %s', n, inside))
+ table.insert(output, fields) -- append to list of parsed keydigests
+end
+
+local function generate_ds(keydigests)
+ local rrset = ''
+ for _, fields in ipairs(keydigests) do
+ local rr = string.format(
+ '. 0 IN DS %s %s %s %s',
+ fields.KeyTag, fields.Algorithm, fields.DigestType, fields.Digest)
+ if keydigest_is_valid(fields['validFrom'], fields['validUntil']) then
+ rrset = rrset .. '\n' .. rr
+ else
+ log_info(ffi.C.LOG_GRP_TA, 'skipping trust anchor "%s" ' ..
+ 'because it is outside of validity range', rr)
+ end
+ end
+ return rrset
+end
+
+local function assert_str_match(str, pattern, expected)
+ local count = 0
+ for _ in string.gmatch(str, pattern) do
+ count = count + 1
+ end
+ assert(count == expected,
+ string.format('expected %d occurences of "%s" but got %d in "%s"',
+ expected, pattern, count, str))
+end
+
+-- Fetch root anchors in XML over HTTPS, returning a zone-file-style string
+-- or false in case of error, and a message.
+local function bootstrap(url, ca)
+ local kluautil = require('kluautil')
+ local file = io.tmpfile()
+ -- RFC 7958, sec. 2, but we don't do precise XML parsing.
+ -- @todo ICANN certificate is verified against current CA
+ -- this is not ideal, as it should rather verify .xml signature which
+ -- is signed by ICANN long-lived cert, but luasec has no PKCS7
+ local rcode, errmsg = kluautil.kr_https_fetch(url, file, ca)
+ if rcode == nil then
+ file:close()
+ return false, string.format('[ ta ] fetch of "%s" failed: %s', url, errmsg)
+ end
+
+ local xml = file:read("*a")
+ file:close()
+
+ -- we support only minimal subset of https://tools.ietf.org/html/rfc7958
+ assert_str_match(xml, '<?xml version="1%.0" encoding="UTF%-8"%?>', 1)
+ assert_str_match(xml, '<TrustAnchor ', 1)
+ assert_str_match(xml, '<Zone>.</Zone>', 1)
+ assert_str_match(xml, '</TrustAnchor>', 1)
+
+ -- Parse root trust anchor, one digest at a time, converting to a zone-file-style string.
+ local keydigests = {}
+ string.gsub(xml, "<KeyDigest([^>]*)>(.-)</KeyDigest>", function(attrs, inside)
+ parse_xml_keydigest(attrs, inside, keydigests)
+ end)
+ local rrset = generate_ds(keydigests)
+ if rrset == '' then
+ return false, string.format('[ ta ] no valid trust anchors found at "%s"', url)
+ end
+ local msg = '[ ta ] Root trust anchors bootstrapped over https with pinned certificate.\n'
+ .. ' You SHOULD verify them manually against original source:\n'
+ .. ' https://www.iana.org/dnssec/files\n'
+ .. '[ ta ] Bootstrapped root trust anchors are:'
+ .. rrset
+ return rrset, msg
+end
+
+local function bootstrap_write(rrstr, filename)
+ local fname_tmp = filename .. '.lock.' .. tostring(worker.pid);
+ local file = assert(io.open(fname_tmp, 'w'))
+ file:write(rrstr)
+ file:close()
+ assert(os.rename(fname_tmp, filename))
+end
+-- Bootstrap end
+
+-- Update ta.comment and return decorated line representing the RR
+-- This is meant to be in zone-file format.
+local function ta_rr_str(ta)
+ ta.comment = ' ' .. ta.state .. ':' .. (ta.timer or '')
+ .. ' ; KeyTag:' .. ta.key_tag -- the tag is just for humans
+ local rr_str = kres.rr2str(ta) .. '\n'
+ if ta.state ~= key_state.Valid and ta.state ~= key_state.Missing then
+ rr_str = '; '..rr_str -- Invalidate key string (for older kresd versions)
+ end
+ return rr_str
+end
+
+-- Write keyset to a file. States and timers are stored in comments.
+local function keyset_write(keyset)
+ if not keyset.managed then -- not to be persistent, this is an error!
+ panic('internal error: keyset_write called for an unmanaged TA')
+ end
+ local fname_tmp = keyset.filename .. '.lock.' .. tostring(worker.pid);
+ local file = assert(io.open(fname_tmp, 'w'))
+ for i = 1, #keyset do
+ file:write(ta_rr_str(keyset[i]))
+ end
+ file:close()
+ assert(os.rename(fname_tmp, keyset.filename))
+end
+
+-- Search the values of a table and return the corresponding key (or nil).
+local function table_search(t, val)
+ for k, v in pairs(t) do
+ if v == val then
+ return k
+ end
+ end
+ return nil
+end
+
+-- For each RR, parse .state and .timer from .comment.
+local function keyset_parse_comments(tas, default_state)
+ for _, ta in pairs(tas) do
+ ta.state = default_state
+ if ta.comment then
+ string.gsub(ta.comment, '^%s*(%a+):(%d*)', function (state, time)
+ if table_search(key_state, state) then
+ ta.state = state
+ end
+ ta.timer = tonumber(time) -- nil on failure
+ end)
+ ta.comment = nil
+ end
+ end
+ return tas
+end
+
+-- Read keyset from a file xor a string. (This includes the key states and timers.)
+local function keyset_read(path, str)
+ if (path == nil) == (str == nil) then -- exactly one of them must be nil
+ return nil, "internal ERROR: incorrect call to TA's keyset_read"
+ end
+ -- First load the regular entries, trusting them.
+ local zonefile = require('zonefile')
+ local tas, err
+ if path ~= nil then
+ tas, err = zonefile.file(path)
+ else
+ tas, err = zonefile.string(str)
+ end
+ if not tas then
+ return tas, err
+ end
+ keyset_parse_comments(tas, key_state.Valid)
+
+ -- The untrusted keys are commented out but important to load.
+ local line_iter
+ if path ~= nil then
+ line_iter = io.lines(path)
+ else
+ line_iter = string.gmatch(str, "[^\n]+")
+ end
+ for line in line_iter do
+ if line:sub(1, 2) == '; ' then
+ -- Ignore the line if it fails to parse including recognized .state.
+ local l_set = zonefile.string(line:sub(3))
+ if l_set and l_set[1] then
+ keyset_parse_comments(l_set)
+ if l_set[1].state then
+ table.insert(tas, l_set[1])
+ end
+ end
+ end
+ end
+
+ -- Fill tas[*].key_tag
+ for _, ta in pairs(tas) do
+ local ta_keytag = C.kr_dnssec_key_tag(ta.type, ta.rdata, #ta.rdata)
+ if not (ta_keytag >= 0 and ta_keytag <= 65535) then
+ return nil, string.format('invalid key: "%s": %s',
+ kres.rr2str(ta), ffi.string(C.knot_strerror(ta_keytag)))
+ end
+ ta.key_tag = ta_keytag
+ end
+
+ -- Fill tas.owner
+ if not tas[1] then
+ return nil, "empty TA set"
+ end
+ local owner = tas[1].owner
+ for _, ta in ipairs(tas) do
+ if ta.owner ~= owner then
+ return nil, string.format("do not mix %s and %s TAs in single file/string",
+ kres.dname2str(ta.owner), kres.dname2str(owner))
+ end
+ end
+ tas.owner = owner
+
+ return tas
+end
+
+-- Replace current TAs for given owner by the "trusted" ones from passed keyset.
+-- Return true iff no TA errored out and at least one is in VALID state.
+local function keyset_publish(keyset)
+ local store = kres.context().trust_anchors
+ local count = 0
+ local has_error = false
+ C.kr_ta_del(store, keyset.owner)
+ for _, ta in ipairs(keyset) do
+ -- Key MAY be used as a TA only in these two states (RFC5011, 4.2)
+ if ta.state == key_state.Valid or ta.state == key_state.Missing then
+ if C.kr_ta_add(store, ta.owner, ta.type, ta.ttl, ta.rdata, #ta.rdata) == 0 then
+ count = count + 1
+ else
+ ta.state = 'ERROR'
+ has_error = true
+ end
+ end
+ end
+ if count == 0 then
+ log_error(ffi.C.LOG_GRP_TA, 'ERROR: no anchors are trusted for ' ..
+ kres.dname2str(keyset.owner) .. ' !')
+ end
+ return count > 0 and not has_error
+end
+
+local function add_file(path, unmanaged)
+ local managed = not unmanaged
+ if not ta_update then
+ modules.load('ta_update')
+ end
+ if managed then
+ if not io.open(path .. '.lock', 'w') then
+ error("[ ta ] ERROR: write access needed to keyfile dir '"..path.."'")
+ end
+ os.remove(path .. ".lock")
+ end
+
+ -- Bootstrap TA for root zone if keyfile doesn't exist
+ if managed and not io.open(path, 'r') then
+ if trust_anchors.keysets['\0'] then
+ error(string.format(
+ "[ ta ] keyfile '%s' doesn't exist and root key is already installed, "
+ .. "cannot bootstrap; provide a path to valid file with keys", path))
+ end
+ log_info(ffi.C.LOG_GRP_TA, "keyfile '%s': doesn't exist, bootstrapping", path);
+ local rrstr, msg = bootstrap(trust_anchors.bootstrap_url, trust_anchors.bootstrap_ca)
+ if not rrstr then
+ msg = msg .. '\n'
+ .. '[ ta ] Failed to bootstrap root trust anchors!'
+ error(msg)
+ end
+ print(msg)
+ bootstrap_write(rrstr, path)
+ -- continue as if the keyfile was there
+ end
+
+ -- Parse the file and check its sanity
+ local keyset, err = keyset_read(path)
+ if not keyset then
+ panic("[ ta ] ERROR: failed to read anchors from '%s' (%s)", path, err)
+ end
+ keyset.filename = path
+ keyset.managed = managed
+
+ local owner = keyset.owner
+ local owner_str = kres.dname2str(owner)
+ local keyset_orig = trust_anchors.keysets[owner]
+ if keyset_orig then
+ log_warn(ffi.C.LOG_GRP_TA, 'warning: overriding previously set trust anchors for ' .. owner_str)
+ if keyset_orig.managed and ta_update then
+ ta_update.stop(owner)
+ end
+ end
+ trust_anchors.keysets[owner] = keyset
+
+ -- Replace the TA store used for validation
+ if keyset_publish(keyset) then
+ log_info(ffi.C.LOG_GRP_TA, 'installed trust anchors for domain ' .. owner_str .. ' are:\n'
+ .. trust_anchors.summary(owner))
+ end
+ -- TODO: if failed and for root, try to rebootstrap?
+
+ ta_update.start(owner, managed)
+end
+
+local function remove(zname)
+ local owner = kres.str2dname(zname)
+ if not trust_anchors.keysets[owner] then
+ return false
+ end
+
+ if ta_update then
+ ta_update.stop(owner)
+ end
+ trust_anchors.keysets[owner] = nil
+ local store = kres.context().trust_anchors
+ C.kr_ta_del(store, owner)
+ return true
+end
+
+local function ta_str(owner)
+ local owner_str = kres.dname2str(owner) .. ' '
+ local msg = ''
+ for _, nta in pairs(trust_anchors.insecure) do
+ if owner == kres.str2dname(nta) then
+ msg = owner_str .. 'is negative trust anchor\n'
+ end
+ end
+ if not trust_anchors.keysets[owner] then
+ if #msg > 0 then -- it is normal that NTA does not have explicit TA
+ return msg
+ else
+ return owner_str .. 'has no explicit trust anchors\n'
+ end
+ end
+ if #msg > 0 then
+ msg = msg .. 'WARNING! negative trust anchor also has an explicit TA\n'
+ end
+ for _, ta in ipairs(trust_anchors.keysets[owner]) do
+ msg = msg .. ta_rr_str(ta)
+ end
+ return msg
+end
+
+-- TA store management, for user docs see ../README.rst
+trust_anchors = {
+ -- [internal] table indexed by dname;
+ -- each item is a list of RRs and additionally contains:
+ -- - owner - that dname (for simplicity)
+ -- - [optional] filename in which to persist the state,
+ -- implying unmanaged TA if nil
+ -- The RR tables also contain some additional TA-specific fields.
+ keysets = {},
+
+ -- Documented properties:
+ insecure = {},
+
+ bootstrap_url = 'https://data.iana.org/root-anchors/root-anchors.xml',
+ bootstrap_ca = '@etc_dir@/icann-ca.pem',
+
+ -- Load keys from a file, 5011-managed by default.
+ -- If managed and the file doesn't exist, try bootstrapping the root into it.
+ add_file = add_file,
+ config = function() upgrade_required('trust_anchors.config was removed, use trust_anchors.add_file()') end,
+ remove = remove,
+
+ keyset_publish = keyset_publish,
+ keyset_write = keyset_write,
+ key_state = key_state,
+
+ -- Add DS/DNSKEY record(s) (unmanaged)
+ add = function (keystr)
+ local keyset, err = keyset_read(nil, keystr)
+ if keyset ~= nil then
+ local owner = keyset.owner
+ local owner_str = kres.dname2str(owner)
+ local keyset_orig = trust_anchors.keysets[owner]
+ -- Set up trust_anchors.keysets[owner]
+ if keyset_orig then
+ if keyset_orig.managed then
+ panic('[ ta ] it is impossible to add an unmanaged TA for zone '
+ .. owner_str .. ' which already has a managed TA')
+ end
+ log_warn(ffi.C.LOG_GRP_TA, 'warning: extending previously set trust anchors for '
+ .. owner_str)
+ for _, ta in ipairs(keyset) do
+ table.insert(keyset_orig, ta)
+ end
+ end
+ -- Replace the TA store used for validation
+ if not keyset_publish(keyset) then
+ err = "when publishing the TA set"
+ -- trust_anchors.keysets[owner] was already updated to the
+ -- (partially) failing state, but I'm not sure how much to improve this
+ end
+ keyset.managed = false
+ trust_anchors.keysets[owner] = keyset
+
+ end
+ log_info(ffi.C.LOG_GRP_TA, 'New TA state:\n' .. trust_anchors.summary())
+ if err then
+ panic('[ ta ] .add() failed: ' .. err)
+ end
+ end,
+
+ -- Negative TA management
+ set_insecure = function (list)
+ assert(type(list) == 'table', 'parameter must be list of domain names (e.g. {"a.test", "b.example"})')
+ local store = kres.context().negative_anchors
+ for i = 1, #list do
+ local dname = kres.str2dname(list[i])
+ if trust_anchors.keysets[dname] then
+ error('cannot add NTA '..list[i]..' because it is TA. Use trust_anchors.remove() instead')
+ end
+ end
+
+ C.kr_ta_clear(store)
+ for i = 1, #list do
+ local dname = kres.str2dname(list[i])
+ C.kr_ta_add(store, dname, kres.type.DS, 0, nil, 0)
+ end
+ trust_anchors.insecure = list
+ end,
+ -- Return textual representation of all TAs (incl. negative)
+ -- It's meant for human consumption.
+ summary = function (single_owner)
+ if single_owner then -- single domain
+ return ta_str(single_owner)
+ end
+
+ -- all domains
+ local msg = ''
+ local ta_count = 0
+ local seen = {}
+ for _, nta_str in pairs(trust_anchors.insecure) do
+ local owner = kres.str2dname(nta_str)
+ seen[owner] = true
+ msg = msg .. ta_str(owner)
+ end
+ for owner, _ in pairs(trust_anchors.keysets) do
+ if not seen[owner] then
+ ta_count = ta_count + 1
+ msg = msg .. ta_str(owner)
+ end
+ end
+ if ta_count == 0 then
+ msg = msg .. 'No valid trust anchors, DNSSEC validation is disabled\n'
+ end
+ return msg
+ end,
+}
+
+-- Syntactic sugar for TA store
+setmetatable(trust_anchors, {
+ __newindex = function (t,k,v)
+ if k == 'file' then
+ upgrade_required('trust_anchors.file was removed, use trust_anchors.add_file()')
+ elseif k == 'negative' then
+ upgrade_required('trust_anchors.negative was removed, use trust_anchors.set_insecure()')
+ elseif k == 'keyfile_default' then
+ upgrade_required('trust_anchors.keyfile_default is now compiled in, see trust_anchors.remove()')
+ else rawset(t, k, v) end
+ end,
+})
+
+return trust_anchors
diff --git a/daemon/lua/trust_anchors.rst b/daemon/lua/trust_anchors.rst
new file mode 100644
index 0000000..40f79b6
--- /dev/null
+++ b/daemon/lua/trust_anchors.rst
@@ -0,0 +1,123 @@
+.. SPDX-License-Identifier: GPL-3.0-or-later
+
+.. warning:: Options in this section are intended only for expert users and
+ normally should not be needed.
+
+Since version 4.0, **DNSSEC validation is enabled by default**.
+If you really need to turn DNSSEC off and are okay with lowering security of your
+system by doing so, add the following snippet to your configuration file.
+
+.. code-block:: lua
+
+ -- turns off DNSSEC validation
+ trust_anchors.remove('.')
+
+The resolver supports DNSSEC including :rfc:`5011` automated DNSSEC TA updates
+and :rfc:`7646` negative trust anchors. Depending on your distribution, DNSSEC
+trust anchors should be either maintained in accordance with the distro-wide
+policy, or automatically maintained by the resolver itself.
+
+In practice this means that you can forget about it and your favorite Linux
+distribution will take care of it for you.
+
+Following functions allow to modify DNSSEC configuration *if you really have to*:
+
+
+.. function:: trust_anchors.add_file(keyfile[, readonly = false])
+
+ :param string keyfile: path to the file.
+ :param readonly: if true, do not attempt to update the file.
+
+ The format is standard zone file, though additional information may be persisted in comments.
+ Either DS or DNSKEY records can be used for TAs.
+ If the file does not exist, bootstrapping of *root* TA will be attempted.
+ If you want to use bootstrapping, install `lua-http`_ library.
+
+ Each file can only contain records for a single domain.
+ The TAs will be updated according to :rfc:`5011` and persisted in the file (if allowed).
+
+ Example output:
+
+ .. code-block:: lua
+
+ > trust_anchors.add_file('root.key')
+ [ ta ] new state of trust anchors for a domain:
+ . 165488 DS 19036 8 2 49AAC11D7B6F6446702E54A1607371607A1A41855200FD2CE1CDDE32F24E8FB5
+ nil
+
+ [ ta ] key: 19036 state: Valid
+
+.. function:: trust_anchors.remove(zonename)
+
+ Remove specified trust anchor from trusted key set. Removing trust anchor for the root zone effectively disables DNSSEC validation (unless you configured another trust anchor).
+
+ .. code-block:: lua
+
+ > trust_anchors.remove('.')
+ true
+
+ If you want to disable DNSSEC validation for a particular domain but keep it enabled for the rest of DNS tree, use :func:`trust_anchors.set_insecure`.
+
+.. envvar:: trust_anchors.hold_down_time = 30 * day
+
+ :return: int (default: 30 * day)
+
+ Modify RFC5011 hold-down timer to given value. Intended only for testing purposes. Example: ``30 * sec``
+
+.. envvar:: trust_anchors.refresh_time = nil
+
+ :return: int (default: nil)
+
+ Modify RFC5011 refresh timer to given value (not set by default), this will force trust anchors
+ to be updated every N seconds periodically instead of relying on RFC5011 logic and TTLs.
+ Intended only for testing purposes.
+ Example: ``10 * sec``
+
+.. envvar:: trust_anchors.keep_removed = 0
+
+ :return: int (default: 0)
+
+ How many ``Removed`` keys should be held in history (and key file) before being purged.
+ Note: all ``Removed`` keys will be purged from key file after restarting the process.
+
+
+.. function:: trust_anchors.set_insecure(nta_set)
+
+ :param table nta_list: List of domain names (text format) representing NTAs.
+
+ When you use a domain name as an *negative trust anchor* (NTA), DNSSEC validation will be turned off at/below these names.
+ Each function call replaces the previous NTA set. You can find the current active set in ``trust_anchors.insecure`` variable.
+ If you want to disable DNSSEC validation completely use :func:`trust_anchors.remove` function instead.
+
+ Example output:
+
+ .. code-block:: lua
+
+ > trust_anchors.set_insecure({ 'bad.boy', 'example.com' })
+ > trust_anchors.insecure
+ [1] => bad.boy
+ [2] => example.com
+
+ .. warning:: If you set NTA on a name that is not a zone cut,
+ it may not always affect names not separated from the NTA by a zone cut.
+
+.. function:: trust_anchors.add(rr_string)
+
+ :param string rr_string: DS/DNSKEY records in presentation format (e.g. ``. 3600 IN DS 19036 8 2 49AAC11...``)
+
+ Inserts DS/DNSKEY record(s) into current keyset. These will not be managed or updated, use it only for testing
+ or if you have a specific use case for not using a keyfile.
+
+ .. note:: Static keys are very error-prone and should not be used in production. Use :func:`trust_anchors.add_file` instead.
+
+ Example output:
+
+ .. code-block:: lua
+
+ > trust_anchors.add('. 3600 IN DS 19036 8 2 49AAC11...')
+
+.. function:: trust_anchors.summary()
+
+ Return string with summary of configured DNSSEC trust anchors, including negative TAs.
+
+.. _lua-http: https://luarocks.org/modules/daurnimator/http
diff --git a/daemon/lua/trust_anchors.test/bootstrap.test.lua b/daemon/lua/trust_anchors.test/bootstrap.test.lua
new file mode 100644
index 0000000..7dd248b
--- /dev/null
+++ b/daemon/lua/trust_anchors.test/bootstrap.test.lua
@@ -0,0 +1,112 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+modules.load('ta_update')
+
+-- check prerequisites
+local has_http = pcall(require, 'kres_modules.http') and pcall(require, 'http.request')
+if not has_http then
+ -- skipping bootstrap tests because http module is not not installed
+ os.exit(77)
+end
+
+local cqueues = require("cqueues")
+local socket = require("cqueues.socket")
+
+-- unload modules which are not related to this test
+if ta_signal_query then
+ modules.unload('ta_signal_query')
+end
+if priming then
+ modules.unload('priming')
+end
+if detect_time_skew then
+ modules.unload('detect_time_skew')
+end
+
+-- Self-checks on globals
+assert(help() ~= nil)
+assert(worker.id ~= nil)
+-- Self-checks on facilities
+assert(worker.stats() ~= nil)
+assert(net.interfaces() ~= nil)
+-- Self-checks on loaded stuff
+assert(#modules.list() > 0)
+-- Self-check timers
+ev = event.recurrent(1 * sec, function () return 1 end)
+event.cancel(ev)
+ev = event.after(0, function () return 1 end)
+
+
+-- do not attempt to contact outside world using DNS, operate only on cache
+net.ipv4 = false
+net.ipv6 = false
+-- do not listen, test is driven by config code
+env.KRESD_NO_LISTEN = true
+
+-- start test webserver
+local function start_webserver()
+ -- srvout = io.popen('luajit webserv.lua')
+ -- TODO
+ os.execute('luajit webserv.lua >/dev/null 2>&1 &')
+ -- assert(srvout, 'failed to start webserver')
+end
+
+local function wait_for_webserver()
+ local starttime = os.time()
+ local connected = false
+ while not connected and os.difftime(os.time(), starttime) < 10 do
+ local con = socket.connect("localhost", 8080)
+ connected, msg = pcall(con.connect, con, 3)
+ cqueues.sleep (0.3)
+ end
+ assert(connected, string.format('unable to connect to web server: %s', msg))
+end
+
+local host = 'https://localhost:8080/'
+-- avoid interference with configured keyfile_default
+trust_anchors.remove('.')
+
+local function test_err_cert()
+ trust_anchors.bootstrap_ca = 'x509/wrongca.pem'
+ trust_anchors.bootstrap_url = host .. 'ok1.xml'
+ boom(trust_anchors.add_file, {'ok1.keys'},
+ 'fake server certificate is detected')
+end
+
+local function test_err_xml(testname, testdesc)
+ return function()
+ trust_anchors.bootstrap_ca = 'x509/ca.pem'
+ trust_anchors.bootstrap_url = host .. testname .. '.xml'
+ boom(trust_anchors.add_file, {testname .. '.keys'}, testdesc)
+ end
+end
+
+-- dumb test, right now it cannot check content of keys because
+-- it does not get written until refresh fetches DNSKEY from network
+-- (and bypassing network using policy bypasses also validation
+-- so it does not test anything)
+local function test_ok_xml(testname, testdesc)
+ return function()
+ trust_anchors.bootstrap_url = host .. testname .. '.xml'
+ trust_anchors.remove('.')
+ same(trust_anchors.add_file(testname .. '.keys'), nil, testdesc)
+ end
+end
+
+return {
+ start_webserver,
+ wait_for_webserver,
+ test_err_cert,
+ test_err_xml('err_attr_extra_attr', 'bogus TA XML with an extra attribute'),
+ test_err_xml('err_attr_validfrom_invalid', 'bogus TA XML with invalid validFrom value'),
+ test_err_xml('err_attr_validfrom_missing', 'bogus TA XML without mandatory validFrom attribute'),
+ test_err_xml('err_elem_extra', 'bogus TA XML with an extra element'),
+ test_err_xml('err_elem_missing', 'bogus TA XML without mandatory element'),
+ test_err_xml('err_multi_ta', 'bogus TA XML with multiple TAs'),
+ test_err_xml('unsupp_nonroot', 'unsupported TA XML for non-root zone'),
+ test_err_xml('unsupp_xml_v11', 'unsupported TA XML with XML v1.1'),
+ test_err_xml('ok0_badtimes', 'TA XML with no valid keys'),
+ test_ok_xml('ok1_expired1', 'TA XML with 1 valid and 1 expired key'),
+ test_ok_xml('ok1_notyet1', 'TA XML with 1 valid and 1 not yet valid key'),
+ test_ok_xml('ok1', 'TA XML with 1 valid key'),
+ test_ok_xml('ok2', 'TA XML with 2 valid keys'),
+}
diff --git a/daemon/lua/trust_anchors.test/err_attr_extra_attr.xml b/daemon/lua/trust_anchors.test/err_attr_extra_attr.xml
new file mode 100644
index 0000000..2a87957
--- /dev/null
+++ b/daemon/lua/trust_anchors.test/err_attr_extra_attr.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<TrustAnchor id="FC4A93EC-9F4E-4597-A766-AD6723E4A56E" source="https://localhost/err_attr_extra_attr.xml">
+<Zone>.</Zone>
+<KeyDigest unknownattr="test" id="Kjqmt7v" validFrom="2010-07-15T00:00:00+00:00" validUntil="2019-01-11T00:00:00+00:00">
+<KeyTag>19036</KeyTag>
+<Algorithm>8</Algorithm>
+<DigestType>2</DigestType>
+<Digest>49AAC11D7B6F6446702E54A1607371607A1A41855200FD2CE1CDDE32F24E8FB5</Digest>
+</KeyDigest>
+<KeyDigest id="Klajeyz" validFrom="2017-02-02T00:00:00+00:00">
+<KeyTag>20326</KeyTag>
+<Algorithm>8</Algorithm>
+<DigestType>2</DigestType>
+<Digest>E06D44B80B8F1D39A95C0B0D7C65D08458E880409BBC683457104237C7F8EC8D</Digest>
+</KeyDigest>
+</TrustAnchor>
diff --git a/daemon/lua/trust_anchors.test/err_attr_validfrom_invalid.xml b/daemon/lua/trust_anchors.test/err_attr_validfrom_invalid.xml
new file mode 100644
index 0000000..5a4c68c
--- /dev/null
+++ b/daemon/lua/trust_anchors.test/err_attr_validfrom_invalid.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<TrustAnchor id="ABD668AB-52DF-4A59-80E3-16CE6341BC55" source="https://localhost/err_attr_validfrom_invalid.xml">
+<Zone>.</Zone>
+<KeyDigest id="Kjqmt7v" validFrom="2010-07-32T00:00:00+00:00" validUntil="2019-01-11T00:00:00+00:00">
+<KeyTag>19036</KeyTag>
+<Algorithm>8</Algorithm>
+<DigestType>2</DigestType>
+<Digest>49AAC11D7B6F6446702E54A1607371607A1A41855200FD2CE1CDDE32F24E8FB5</Digest>
+</KeyDigest>
+<KeyDigest id="Klajeyz" validFrom="2017-02-02T00:00:00+00:00">
+<KeyTag>20326</KeyTag>
+<Algorithm>8</Algorithm>
+<DigestType>2</DigestType>
+<Digest>E06D44B80B8F1D39A95C0B0D7C65D08458E880409BBC683457104237C7F8EC8D</Digest>
+</KeyDigest>
+</TrustAnchor>
diff --git a/daemon/lua/trust_anchors.test/err_attr_validfrom_missing.xml b/daemon/lua/trust_anchors.test/err_attr_validfrom_missing.xml
new file mode 100644
index 0000000..1261b09
--- /dev/null
+++ b/daemon/lua/trust_anchors.test/err_attr_validfrom_missing.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<TrustAnchor id="3513058C-4041-40CC-AF0A-D3CCD70F962B" source="https://localhost/err_attr_validfrom_missing.xml">
+<Zone>.</Zone>
+<KeyDigest id="Kjqmt7v" validUntil="2019-01-11T00:00:00+00:00">
+<KeyTag>19036</KeyTag>
+<Algorithm>8</Algorithm>
+<DigestType>2</DigestType>
+<Digest>49AAC11D7B6F6446702E54A1607371607A1A41855200FD2CE1CDDE32F24E8FB5</Digest>
+</KeyDigest>
+<KeyDigest id="Klajeyz" validFrom="2017-02-02T00:00:00+00:00">
+<KeyTag>20326</KeyTag>
+<Algorithm>8</Algorithm>
+<DigestType>2</DigestType>
+<Digest>E06D44B80B8F1D39A95C0B0D7C65D08458E880409BBC683457104237C7F8EC8D</Digest>
+</KeyDigest>
+</TrustAnchor>
diff --git a/daemon/lua/trust_anchors.test/err_elem_extra.xml b/daemon/lua/trust_anchors.test/err_elem_extra.xml
new file mode 100644
index 0000000..150a3b1
--- /dev/null
+++ b/daemon/lua/trust_anchors.test/err_elem_extra.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<TrustAnchor id="B1854D58-1867-4FA7-872F-0099D394114D" source="https://localhost/err_elem_extra.xml">
+<Zone>.</Zone>
+<KeyDigest id="Kjqmt7v" validFrom="2010-07-15T00:00:00+00:00" validUntil="2019-01-11T00:00:00+00:00">
+<KeyTag>19036</KeyTag>
+<Algorithm>8</Algorithm>
+<DigestType>2</DigestType>
+<Digest>49AAC11D7B6F6446702E54A1607371607A1A41855200FD2CE1CDDE32F24E8FB5</Digest>
+</KeyDigest>
+<KeyDigest id="Klajeyz" validFrom="2017-02-02T00:00:00+00:00">
+<KeyTag>20326</KeyTag>
+<Algorithm>8</Algorithm>
+<DigestType>2</DigestType>
+<Digest>E06D44B80B8F1D39A95C0B0D7C65D08458E880409BBC683457104237C7F8EC8D</Digest>
+<UnknownElement>E06D44B80B8F1D39A95C0B0D7C65D08458E880409BBC683457104237C7F8EC8D</UnknownElement>
+</KeyDigest>
+</TrustAnchor>
diff --git a/daemon/lua/trust_anchors.test/err_elem_missing.xml b/daemon/lua/trust_anchors.test/err_elem_missing.xml
new file mode 100644
index 0000000..899e1d0
--- /dev/null
+++ b/daemon/lua/trust_anchors.test/err_elem_missing.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<TrustAnchor id="BB074095-3A42-4B13-9CC1-CFFF644D4D54" source="https://localhost/err_elem_missing.xml">
+<Zone>.</Zone>
+<KeyDigest id="Kjqmt7v" validFrom="2010-07-15T00:00:00+00:00" validUntil="2019-01-11T00:00:00+00:00">
+<KeyTag>19036</KeyTag>
+<Algorithm>8</Algorithm>
+<DigestType>2</DigestType>
+<Digest>49AAC11D7B6F6446702E54A1607371607A1A41855200FD2CE1CDDE32F24E8FB5</Digest>
+</KeyDigest>
+<KeyDigest id="Klajeyz" validFrom="2017-02-02T00:00:00+00:00">
+<KeyTag>20326</KeyTag>
+<Algorithm>8</Algorithm>
+<!-- this element is missing: DigestType>2</DigestType-->
+<Digest>E06D44B80B8F1D39A95C0B0D7C65D08458E880409BBC683457104237C7F8EC8D</Digest>
+</KeyDigest>
+</TrustAnchor>
diff --git a/daemon/lua/trust_anchors.test/err_multi_ta.xml b/daemon/lua/trust_anchors.test/err_multi_ta.xml
new file mode 100644
index 0000000..20cd73f
--- /dev/null
+++ b/daemon/lua/trust_anchors.test/err_multi_ta.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<TrustAnchor id="9DCE46E1-FC78-48E1-81B5-94E328790BB5" source="https://localhost/err_multi_ta.xml">
+<Zone>.</Zone>
+<KeyDigest id="1" validFrom="2000-02-02T00:00:00+00:00">
+<KeyTag>2</KeyTag>
+<Algorithm>8</Algorithm>
+<DigestType>2</DigestType>
+<Digest>1111111111111111111111111111111111111111111111111111111111111111</Digest>
+</KeyDigest>
+</TrustAnchor>
+<TrustAnchor id="9DCE46E1-FC78-48E1-81B5-94E328790BB5" source="https://localhost/err_multi_ta.xml">
+<Zone>test.</Zone>
+<KeyDigest id="2" validFrom="2000-02-02T00:00:00+00:00">
+<KeyTag>2</KeyTag>
+<Algorithm>8</Algorithm>
+<DigestType>2</DigestType>
+<Digest>1111111111111111111111111111111111111111111111111111111111111111</Digest>
+</KeyDigest>
+</TrustAnchor>
diff --git a/daemon/lua/trust_anchors.test/ok0_badtimes.xml b/daemon/lua/trust_anchors.test/ok0_badtimes.xml
new file mode 100644
index 0000000..4535a41
--- /dev/null
+++ b/daemon/lua/trust_anchors.test/ok0_badtimes.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<TrustAnchor id="EDEDAA08-D2A0-421E-81DC-AF11F5A0CDCD" source="https://localhost/ok0_badtimes.xml">
+<Zone>.</Zone>
+<KeyDigest id="E" validFrom="2000-01-01T00:00:00+00:00" validUntil="2000-01-01T00:00:00+00:00">
+<KeyTag>1</KeyTag>
+<Algorithm>8</Algorithm>
+<DigestType>2</DigestType>
+<Digest>EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE</Digest>
+</KeyDigest>
+<KeyDigest id="F" validFrom="2001-01-01T00:00:00+00:00" validUntil="2001-01-01T00:00:00+00:00">
+<KeyTag>2</KeyTag>
+<Algorithm>8</Algorithm>
+<DigestType>2</DigestType>
+<Digest>FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF</Digest>
+</KeyDigest>
+</TrustAnchor>
diff --git a/daemon/lua/trust_anchors.test/ok1.xml b/daemon/lua/trust_anchors.test/ok1.xml
new file mode 100644
index 0000000..117495c
--- /dev/null
+++ b/daemon/lua/trust_anchors.test/ok1.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<TrustAnchor id="82E6CB77-12DF-4E61-BF49-367FB95A8BAA" source="https://localhost/ok1.xml">
+<Zone>.</Zone>
+<KeyDigest id="2" validFrom="2000-02-02T00:00:00+00:00">
+<KeyTag>2</KeyTag>
+<Algorithm>8</Algorithm>
+<DigestType>2</DigestType>
+<Digest>1111111111111111111111111111111111111111111111111111111111111111</Digest>
+</KeyDigest>
+</TrustAnchor>
diff --git a/daemon/lua/trust_anchors.test/ok1_expired1.xml b/daemon/lua/trust_anchors.test/ok1_expired1.xml
new file mode 100644
index 0000000..f1269da
--- /dev/null
+++ b/daemon/lua/trust_anchors.test/ok1_expired1.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<TrustAnchor id="68463155-A857-4C7E-BCA6-2F6CC2EAC1BE" source="https://localhost/ok1_expired1.xml">
+<Zone>.</Zone>
+<KeyDigest id="F" validFrom="1990-01-01T00:00:00+00:00" validUntil="2000-01-01T00:00:00+00:00">
+<KeyTag>1</KeyTag>
+<Algorithm>8</Algorithm>
+<DigestType>2</DigestType>
+<Digest>FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF</Digest>
+</KeyDigest>
+<KeyDigest id="1" validFrom="2000-01-01T00:00:00+00:00">
+<KeyTag>2</KeyTag>
+<Algorithm>8</Algorithm>
+<DigestType>2</DigestType>
+<Digest>1111111111111111111111111111111111111111111111111111111111111111</Digest>
+</KeyDigest>
+</TrustAnchor>
diff --git a/daemon/lua/trust_anchors.test/ok1_notyet1.xml b/daemon/lua/trust_anchors.test/ok1_notyet1.xml
new file mode 100644
index 0000000..7b5881b
--- /dev/null
+++ b/daemon/lua/trust_anchors.test/ok1_notyet1.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<TrustAnchor id="507B39D5-049E-467C-9E9A-F5BE597C9DDA" source="https://localhost/ok1_notyet1.xml">
+<Zone>.</Zone>
+<KeyDigest id="1" validFrom="2010-07-15T00:00:00+00:00">
+<KeyTag>1</KeyTag>
+<Algorithm>8</Algorithm>
+<DigestType>2</DigestType>
+<Digest>1111111111111111111111111111111111111111111111111111111111111111</Digest>
+</KeyDigest>
+<KeyDigest id="2" validFrom="2050-12-31T23:59:59+00:00">
+<KeyTag>2</KeyTag>
+<Algorithm>8</Algorithm>
+<DigestType>2</DigestType>
+<Digest>FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF</Digest>
+</KeyDigest>
+</TrustAnchor>
diff --git a/daemon/lua/trust_anchors.test/ok2.xml b/daemon/lua/trust_anchors.test/ok2.xml
new file mode 100644
index 0000000..149f6b5
--- /dev/null
+++ b/daemon/lua/trust_anchors.test/ok2.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<TrustAnchor id="1DECEB91-0591-44A1-95CF-1788337514B8" source="https://localhost/ok2.xml">
+<Zone>.</Zone>
+<KeyDigest id="K1" validFrom="2010-07-15T00:00:00+00:00">
+<KeyTag>1</KeyTag>
+<Algorithm>8</Algorithm>
+<DigestType>2</DigestType>
+<Digest>1111111111111111111111111111111111111111111111111111111111111111</Digest>
+</KeyDigest>
+<KeyDigest id="K2" validFrom="2011-02-02T00:00:00+00:00">
+<KeyTag>2</KeyTag>
+<Algorithm>8</Algorithm>
+<DigestType>2</DigestType>
+<Digest>2222222222222222222222222222222222222222222222222222222222222222</Digest>
+</KeyDigest>
+</TrustAnchor>
diff --git a/daemon/lua/trust_anchors.test/regen.sh b/daemon/lua/trust_anchors.test/regen.sh
new file mode 100755
index 0000000..9e7dac1
--- /dev/null
+++ b/daemon/lua/trust_anchors.test/regen.sh
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+for F in *.xml; do sed -i "s/TrustAnchor id=\"[^\"]*\"/TrustAnchor id=\"$(uuidgen | tr '[[:lower:]]' '[[:upper:]]')\"/" $F; done
+for F in *.xml; do sed -i "s#source=\"[^\"]*\"#source=\"https://localhost/$F\"#" $F; done
diff --git a/daemon/lua/trust_anchors.test/root.keys b/daemon/lua/trust_anchors.test/root.keys
new file mode 100644
index 0000000..e292b5a
--- /dev/null
+++ b/daemon/lua/trust_anchors.test/root.keys
@@ -0,0 +1 @@
+. IN DS 20326 8 2 E06D44B80B8F1D39A95C0B0D7C65D08458E880409BBC683457104237C7F8EC8D
diff --git a/daemon/lua/trust_anchors.test/ta.test.lua b/daemon/lua/trust_anchors.test/ta.test.lua
new file mode 100644
index 0000000..b977bc9
--- /dev/null
+++ b/daemon/lua/trust_anchors.test/ta.test.lua
@@ -0,0 +1,85 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+
+trust_anchors.remove('.')
+
+local ffi = require('ffi')
+
+-- count warning messages
+warn_msg = {}
+overriding_msg="warning: overriding previously set trust anchors for ."
+warn_msg[overriding_msg] = 0
+function log_warn(grp, fmt, ...) --luacheck: no unused args
+ msg = string.format(fmt, ...)
+ if warn_msg[msg] ~= nil then
+ warn_msg[msg] = warn_msg[msg] + 1
+ end
+end
+
+-- Test that adding a revoked DNSKEY is refused.
+local function test_revoked_key()
+ local ta_c = kres.context().trust_anchors
+ same(ffi.C.kr_ta_del(ta_c, '\0'), 0, 'remove root TAs if any')
+ -- same() doesn't consider nil and typed NULL pointer equal, so we work around:
+ same(ffi.C.kr_ta_get(ta_c, '\0') == nil, true, 'no TA for root is used')
+ local key_crypto = 'AwEAAagAIKlVZrpC6Ia7gEzahOR+9W29euxhJhVVLOyQbSEW0O8gcCjFFV'
+ .. 'QUTf6v58fLjwBd0YI0EzrAcQqBGCzh/RStIoO8g0NfnfL2MTJRkxoXbfDaUeVPQuYEhg37'
+ .. 'NZWAJQ9VnMVDxP/VHL496M/QZxkjf5/Efucp2gaDX6RS6CXpoY68LsvPVjR0ZSwzz1apAz'
+ .. 'vN9dlzEheX7ICJBBtuA6G3LQpzW5hOA2hzCTMjJPJ8LbqF6dsV6DoBQzgul0sGIcGOYl7O'
+ .. 'yQdXfZ57relSQageu+ipAdTTJ25AsRTAoub8ONGcLmqrAmRLKBP1dfwhYB4N7knNnulqQxA+Uk1ihz0='
+ boom(trust_anchors.add, { '. 3600 DNSKEY 385 3 8 ' .. key_crypto }, 'refuse revoked key')
+ same(ffi.C.kr_ta_get(ta_c, '\0') == nil, true, 'no TA for root is used')
+ -- Test that we don't have another problem in the key
+ trust_anchors.add('. 3600 DNSKEY 257 3 8 ' .. key_crypto)
+ local root_ta = ffi.C.kr_ta_get(ta_c, '\0')
+ same(root_ta == nil, false, 'we got non-NULL TA RRset')
+ same(root_ta.rrs.count, 1, 'the root TA set contains one RR')
+end
+
+local function test_remove()
+ -- uses root key from the previous test
+ assert(trust_anchors.keysets['\0'], 'root key must be there from previous test')
+ local ta_c = kres.context().trust_anchors
+ local root_ta = ffi.C.kr_ta_get(ta_c, '\0')
+ assert(root_ta ~= nil, 'we got non-NULL TA RRset')
+ assert(root_ta.rrs.count, 1, 'we have a root TA set to be deleted')
+
+ trust_anchors.remove('.')
+
+ same(trust_anchors.keysets['\0'], nil, 'Lua interface does not have the removed key')
+ root_ta = ffi.C.kr_ta_get(ta_c, '\0')
+ same(root_ta == nil, true, 'C interface does not have the removed key')
+end
+
+local function test_add_file()
+ boom(trust_anchors.add_file, {'nonwriteable/root.keys', false},
+ "Managed trust anchor in non-writeable directory")
+
+ boom(trust_anchors.add_file, {'nonexistent.keys', true},
+ "Nonexistent unmanaged trust anchor file")
+
+ is(warn_msg[overriding_msg], 0, "No override warning messages at start of test")
+ trust_anchors.add_file('root.keys', true)
+ trust_anchors.add_file('root.keys', true)
+ is(warn_msg[overriding_msg], 1, "Warning message when override trust anchors")
+
+ is(trust_anchors.keysets['\0'][1].key_tag, 20326,
+ "Loaded KeyTag from root.keys")
+end
+
+local function test_nta()
+ assert(trust_anchors.keysets['\0'], 'root key must be there from previous tests')
+
+ trust_anchors.set_insecure({'example.com'})
+ is(trust_anchors.insecure[1], 'example.com', 'Add example.com to NTA list')
+ boom(trust_anchors.set_insecure, {{'.'}}, 'Got error when adding TA . to NTA list')
+ is(#trust_anchors.insecure, 1, 'Check one item in NTA list')
+ is(trust_anchors.insecure[1], 'example.com', 'Check previous NTA list')
+end
+
+return {
+ test_revoked_key,
+ test_remove,
+ test_add_file,
+ test_nta,
+}
+
diff --git a/daemon/lua/trust_anchors.test/unsupp_nonroot.xml b/daemon/lua/trust_anchors.test/unsupp_nonroot.xml
new file mode 100644
index 0000000..51b3c0a
--- /dev/null
+++ b/daemon/lua/trust_anchors.test/unsupp_nonroot.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<TrustAnchor id="8449BFB8-FD6C-4082-B0FE-1A3E3399203B" source="https://localhost/unsupp_nonroot.xml">
+<Zone>test.</Zone>
+<KeyDigest id="2" validFrom="2000-02-02T00:00:00+00:00">
+<KeyTag>2</KeyTag>
+<Algorithm>8</Algorithm>
+<DigestType>2</DigestType>
+<Digest>1111111111111111111111111111111111111111111111111111111111111111</Digest>
+</KeyDigest>
+</TrustAnchor>
diff --git a/daemon/lua/trust_anchors.test/unsupp_xml_v11.xml b/daemon/lua/trust_anchors.test/unsupp_xml_v11.xml
new file mode 100644
index 0000000..87a4b57
--- /dev/null
+++ b/daemon/lua/trust_anchors.test/unsupp_xml_v11.xml
@@ -0,0 +1,10 @@
+<?xml version="1.1" encoding="UTF-8"?>
+<TrustAnchor id="3612AE1C-E8F3-4FD8-B8CD-96C7FDACC7A5" source="https://localhost/unsupp_xml_v11.xml">
+<Zone>.</Zone>
+<KeyDigest id="2" validFrom="2000-02-02T00:00:00+00:00">
+<KeyTag>2</KeyTag>
+<Algorithm>8</Algorithm>
+<DigestType>2</DigestType>
+<Digest>1111111111111111111111111111111111111111111111111111111111111111</Digest>
+</KeyDigest>
+</TrustAnchor>
diff --git a/daemon/lua/trust_anchors.test/webserv.lua b/daemon/lua/trust_anchors.test/webserv.lua
new file mode 100644
index 0000000..c108bba
--- /dev/null
+++ b/daemon/lua/trust_anchors.test/webserv.lua
@@ -0,0 +1,236 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+
+-- This is a module that does the heavy lifting to provide an HTTP/2 enabled
+-- server that supports TLS by default and provides endpoint for other modules
+-- in order to enable them to export restful APIs and websocket streams.
+-- One example is statistics module that can stream live metrics on the website,
+-- or publish metrics on request for Prometheus scraper.
+local http_server = require('http.server')
+local http_headers = require('http.headers')
+local http_websocket = require('http.websocket')
+local http_util = require "http.util"
+local x509, pkey = require('openssl.x509'), require('openssl.pkey')
+
+-- Module declaration
+local M = {}
+
+-- Export HTTP service endpoints
+M.endpoints = {
+ ['/'] = {'text/html', 'test'},
+}
+
+-- Serve known requests, for methods other than GET
+-- the endpoint must be a closure and not a preloaded string
+local function serve(endpoints, h, stream)
+ local hsend = http_headers.new()
+ local path = h:get(':path')
+ local entry = endpoints[path]
+ if not entry then -- Accept top-level path match
+ entry = endpoints[path:match '^/[^/?]*']
+ end
+ -- Unpack MIME and data
+ local data, mime, ttl, err
+ if entry then
+ mime = entry[1]
+ data = entry[2]
+ ttl = entry[4]
+ end
+ -- Get string data out of service endpoint
+ if type(data) == 'function' then
+ local set_mime, set_ttl
+ data, err, set_mime, set_ttl = data(h, stream)
+ -- Override default endpoint mime/TTL
+ if set_mime then mime = set_mime end
+ if set_ttl then ttl = set_ttl end
+ -- Handler doesn't provide any data
+ if data == false then return end
+ if type(data) == 'number' then return tostring(data), err end
+ -- Methods other than GET require handler to be closure
+ elseif h:get(':method') ~= 'GET' then
+ return '501', ''
+ end
+ if not mime or type(data) ~= 'string' then
+ return '404', ''
+ else
+ -- Serve content type appropriately
+ hsend:append(':status', '200')
+ hsend:append('content-type', mime)
+ hsend:append('content-length', tostring(#data))
+ if ttl then
+ hsend:append('cache-control', string.format('max-age=%d', ttl))
+ end
+ assert(stream:write_headers(hsend, false))
+ assert(stream:write_chunk(data, true))
+ end
+end
+
+-- Web server service closure
+local function route(endpoints)
+ return function (_, stream)
+ -- HTTP/2: We're only permitted to send in open/half-closed (remote)
+ local connection = stream.connection
+ if connection.version >= 2 then
+ if stream.state ~= 'open' and stream.state ~= 'half closed (remote)' then
+ return
+ end
+ end
+ -- Start reading headers
+ local h = assert(stream:get_headers())
+ local m = h:get(':method')
+ local path = h:get(':path')
+ -- Upgrade connection to WebSocket
+ local ws = http_websocket.new_from_stream(stream, h)
+ if ws then
+ assert(ws:accept { protocols = {'json'} })
+ -- Continue streaming results to client
+ local ep = endpoints[path]
+ local cb = ep[3]
+ if cb then
+ cb(h, ws)
+ end
+ ws:close()
+ return
+ else
+ local ok, err, reason = http_util.yieldable_pcall(serve, endpoints, h, stream)
+ if not ok or err then
+ print(string.format('%s err %s %s: %s (%s)', os.date(), m, path, err or '500', reason))
+ -- Method is not supported
+ local hsend = http_headers.new()
+ hsend:append(':status', err or '500')
+ if reason then
+ assert(stream:write_headers(hsend, false))
+ assert(stream:write_chunk(reason, true))
+ else
+ assert(stream:write_headers(hsend, true))
+ end
+ else
+ print(string.format('%s ok %s %s', os.date(), m, path))
+ end
+ end
+ end
+end
+
+-- @function Prefer HTTP/2 or HTTP/1.1
+local function alpnselect(_, protos)
+ for _, proto in ipairs(protos) do
+ if proto == 'h2' or proto == 'http/1.1' then
+ return proto
+ end
+ end
+ return nil
+end
+
+-- @function Create TLS context
+local function tlscontext(crt, key)
+ local http_tls = require('http.tls')
+ local ctx = http_tls.new_server_context()
+ if ctx.setAlpnSelect then
+ ctx:setAlpnSelect(alpnselect)
+ end
+ assert(ctx:setPrivateKey(key))
+ assert(ctx:setCertificate(crt))
+ return ctx
+end
+
+-- @function Listen on given HTTP(s) host
+function M.add_interface(conf)
+ local crt, key
+ if conf.tls ~= false then
+ assert(conf.cert, 'cert missing')
+ assert(conf.key, 'private key missing')
+ -- Check if a cert file was specified
+ -- Read x509 certificate
+ local f = io.open(conf.cert, 'r')
+ if f then
+ crt = assert(x509.new(f:read('*all')))
+ f:close()
+ -- Continue reading key file
+ if crt then
+ f = io.open(conf.key, 'r')
+ key = assert(pkey.new(f:read('*all')))
+ f:close()
+ end
+ end
+ -- Check loaded certificate
+ assert(crt and key,
+ string.format('failed to load certificate "%s"', conf.cert))
+ end
+ -- Compose server handler
+ local routes = route(conf.endpoints or M.endpoints)
+ -- Check if UNIX socket path is used
+ local addr_str
+ if not conf.path then
+ conf.host = conf.host or 'localhost'
+ conf.port = conf.port or 8453
+ addr_str = string.format('%s@%d', conf.host, conf.port)
+ else
+ if conf.host or conf.port then
+ error('either "path", or "host" and "port" must be provided')
+ end
+ addr_str = conf.path
+ end
+ -- Create TLS context and start listening
+ local s, err = http_server.listen {
+ -- cq = worker.bg_worker.cq,
+ host = conf.host,
+ port = conf.port,
+ path = conf.path,
+ v6only = conf.v6only,
+ unlink = conf.unlink,
+ reuseaddr = conf.reuseaddr,
+ reuseport = conf.reuseport,
+ client_timeout = conf.client_timeout or 5,
+ ctx = crt and tlscontext(crt, key),
+ tls = conf.tls,
+ onstream = routes,
+ -- Log errors, but do not throw
+ onerror = function(myserver, context, op, err, errno) -- luacheck: ignore 212
+ local msg = '[http] ' .. op .. ' on ' .. tostring(context) .. ' failed'
+ if err then
+ msg = msg .. ': ' .. tostring(err)
+ end
+ print(msg)
+ end,
+ }
+ -- Manually call :listen() so that we are bound before calling :localname()
+ if s then
+ err = select(2, s:listen())
+ end
+ assert(not err, string.format('failed to listen on %s: %s', addr_str, err))
+ return s
+end
+
+-- init
+local files = {
+ 'ok0_badtimes.xml',
+ 'ok1.xml',
+ 'ok1_expired1.xml',
+ 'ok1_notyet1.xml',
+ 'ok2.xml',
+ 'err_attr_validfrom_missing.xml',
+ 'err_attr_validfrom_invalid.xml',
+ 'err_attr_extra_attr.xml',
+ 'err_elem_missing.xml',
+ 'err_elem_extra.xml',
+ 'err_multi_ta.xml',
+ 'unsupp_nonroot.xml',
+ 'unsupp_xml_v11.xml'
+}
+
+-- Export static pages specified at command line
+for _, name in ipairs(files) do
+ local fd = io.open(name)
+ assert(fd, string.format('unable to open file "%s"', name))
+ M.endpoints['/' .. name] = { 'text/xml', fd:read('*a') }
+ fd:close()
+end
+
+local server = M.add_interface({
+ host = 'localhost',
+ port = 8080,
+ tls = true,
+ cert = 'x509/server.pem',
+ key = 'x509/server-key.pem'
+ })
+
+server:loop()
diff --git a/daemon/lua/trust_anchors.test/x509/ca-key.pem b/daemon/lua/trust_anchors.test/x509/ca-key.pem
new file mode 100644
index 0000000..2e95b23
--- /dev/null
+++ b/daemon/lua/trust_anchors.test/x509/ca-key.pem
@@ -0,0 +1,182 @@
+Public Key Info:
+ Public Key Algorithm: RSA
+ Key Security Level: High (3072 bits)
+
+modulus:
+ 00:9e:ee:f2:d8:41:ae:2c:93:8a:01:1f:88:5b:d6:85
+ 29:2f:91:9d:37:fc:35:88:7f:53:71:87:fc:17:71:e7
+ 15:57:06:2d:54:fb:19:98:80:82:ec:1a:99:2d:57:cb
+ 5f:dd:28:26:d8:95:fb:65:b2:be:e1:11:86:69:14:7e
+ 32:5c:c0:02:0b:5d:11:78:69:50:20:25:3e:15:fb:8a
+ 46:d1:83:f9:3b:84:46:9c:69:21:44:d5:09:1d:7a:04
+ cc:f3:6a:ea:4c:1b:da:7c:40:dd:1c:6f:f6:85:b4:ea
+ 75:98:34:79:11:fb:cf:d3:18:70:64:25:33:8a:31:b6
+ 93:67:d4:32:67:61:1c:d0:7b:85:61:54:c6:fb:51:b6
+ 87:1d:d4:b8:58:40:a9:c5:32:ce:e0:b9:90:37:0d:58
+ e4:33:70:c5:c5:91:f2:18:f5:e0:08:ad:17:8b:cf:72
+ f1:26:6c:9c:88:d2:9e:06:4c:02:5d:4e:7c:93:af:8d
+ 72:93:75:1d:60:0c:f7:34:09:a8:e6:f2:80:4a:14:81
+ 24:40:4b:45:19:85:2e:ad:8e:97:4c:ff:ec:d0:9f:e6
+ a0:b7:c0:a9:a0:ad:d2:02:2d:13:55:f3:df:f8:f9:f1
+ f3:3e:35:e9:08:2b:db:11:93:57:13:55:c6:ba:c6:d7
+ ff:7d:e1:fa:8c:47:5d:da:bf:31:56:80:aa:34:97:43
+ bb:9e:ff:d3:e6:13:a9:c2:99:49:c2:1e:da:f2:c7:d2
+ d6:f7:5f:70:36:91:2f:ea:36:e9:88:44:08:a3:1a:0a
+ c0:e0:4b:48:82:9a:c9:72:29:9c:09:24:63:b3:c2:9f
+ 2a:f6:e8:3a:c4:46:03:8d:70:ae:14:bb:3a:d6:c6:62
+ 93:24:7f:bc:0a:c8:a2:20:53:3c:9f:5c:15:45:05:3d
+ 1b:38:17:d4:fe:6b:6a:c2:16:f3:14:73:c2:c3:c7:36
+ e3:f1:f8:e5:28:84:4e:37:d4:68:e8:82:70:20:53:fc
+ 01:
+
+public exponent:
+ 01:00:01:
+
+private exponent:
+ 44:4a:68:0e:84:2a:52:fd:12:4f:69:3d:2e:38:fe:fe
+ b3:71:de:1c:30:42:d0:63:e5:76:e2:f7:6f:1b:82:2f
+ a9:34:fe:45:85:9f:79:e7:be:59:b5:14:1c:67:9c:fb
+ 94:0b:ac:a5:63:cc:a1:e6:2c:1e:89:69:37:bd:96:7c
+ 0d:5e:73:82:6e:7b:13:42:2d:2b:a2:d5:0a:9d:0a:cd
+ 63:39:51:de:40:f8:16:3d:16:0e:7d:7b:6d:2f:00:e1
+ 0f:b6:e0:f5:d3:02:0e:61:d0:a0:67:7b:85:f8:36:c6
+ 50:a0:3b:65:7e:cd:cd:e6:b2:64:55:97:cf:c9:8c:a9
+ c9:f3:63:b5:08:05:59:8f:b9:c0:18:ad:67:4f:b5:1e
+ 59:b3:0d:82:de:46:14:75:c0:6e:cf:4d:28:5a:93:d7
+ 7a:42:fa:b7:e9:fe:1c:bb:89:88:30:d7:ed:3b:36:28
+ 68:5a:42:e8:87:97:5f:1d:49:e6:cd:d2:b9:a2:b5:23
+ d8:df:5d:cf:c6:98:9a:e0:99:7a:33:52:75:22:ce:ca
+ 85:eb:d9:92:6a:d5:49:c0:cb:df:b1:a2:98:b5:6c:37
+ 85:c2:e1:6a:13:48:22:72:02:a7:e2:e0:f3:f3:0c:ed
+ 42:f6:83:ba:71:f0:ef:8f:ce:6a:59:30:be:9d:5f:23
+ 06:c3:0e:49:5c:8f:6a:8d:c2:c3:c5:07:45:55:78:f0
+ bd:29:01:cb:ac:ec:b1:40:7d:78:cc:4d:cb:f9:60:a4
+ a2:f5:aa:21:0b:3e:da:1b:d9:f0:99:19:44:57:21:09
+ ba:0f:f9:05:8e:ee:59:4f:59:08:b1:67:51:02:80:4e
+ 34:c7:5d:25:79:8c:84:f7:be:15:02:28:9c:f9:b9:ca
+ fc:6a:ed:d0:5f:df:be:ce:c4:96:63:23:2e:db:e1:85
+ 1e:45:16:2c:24:b0:5e:7a:62:bf:36:00:8b:c8:90:61
+ c2:68:4b:95:b0:ce:41:77:a3:a0:5d:09:72:01:a0:01
+
+
+prime1:
+ 00:ca:fe:eb:14:07:13:a9:ef:b6:d5:6c:52:02:39:b6
+ 6e:55:b6:dd:70:fc:c6:04:7c:07:81:9b:98:a4:da:db
+ f1:66:b8:33:91:fd:00:15:6e:72:0d:ab:0b:6f:be:34
+ c8:d9:82:58:7e:09:7f:e4:6f:c0:70:99:53:68:c7:53
+ d2:8f:97:22:f5:e8:e4:be:5f:e1:29:0f:27:a7:66:74
+ b2:cc:96:a1:d2:ca:2a:40:4b:70:cc:7a:16:4f:c9:4f
+ 49:16:11:d5:f8:da:f6:92:06:1c:45:c3:f8:17:c4:1d
+ 65:9a:2a:3f:33:be:33:f8:84:03:26:49:d8:52:25:f8
+ 19:ce:31:00:c0:b6:55:71:74:03:53:e8:0c:ef:85:64
+ 54:d4:8f:68:08:87:da:cb:9b:55:6a:2e:2b:c2:95:36
+ c4:dd:09:62:c0:6f:9e:e9:cc:ea:96:4e:e6:2d:6c:72
+ c1:54:92:11:29:91:af:4d:cd:08:7c:f8:6f:28:9d:ca
+ c5:
+
+prime2:
+ 00:c8:6e:b7:af:c3:c6:b9:df:49:ad:ea:b8:62:b7:43
+ e6:04:d9:5a:df:c3:f9:a3:0d:b5:e6:2d:9d:f7:c4:ff
+ 38:c0:cb:03:9c:c1:d1:6f:b4:fb:cf:81:c4:9e:94:2a
+ d5:e2:a1:77:a8:7b:8f:d1:34:7a:c2:f5:38:ec:0d:35
+ a0:5e:3c:af:e9:2d:f4:f9:32:ae:da:c1:1e:62:74:e5
+ ab:3d:3b:3d:d0:88:fc:53:59:0f:21:30:ed:24:ac:a7
+ 5a:a5:b7:f4:cc:5a:96:ad:79:a3:41:74:56:ad:39:14
+ 0a:27:a4:10:18:19:33:f2:1a:aa:b4:36:9d:fa:3f:fc
+ 71:42:1e:a0:96:8e:0f:de:46:87:ba:6c:38:17:d0:7e
+ c8:4a:cb:4a:29:1c:44:b9:88:29:c7:6f:b7:4f:3f:00
+ cd:0c:6b:0f:77:a1:5a:f1:80:21:91:b3:68:ca:0d:b5
+ c9:6d:04:f4:98:94:9f:09:f9:a8:58:ea:34:9c:d8:f0
+ 0d:
+
+coefficient:
+ 00:bf:7b:93:68:64:ea:5e:b5:f4:b6:8c:91:49:aa:2b
+ b0:a5:74:40:73:45:23:b6:74:ae:7a:55:ae:9d:8a:bb
+ 3b:6d:3a:7d:c4:7a:c0:82:7f:0e:ef:57:1c:86:e2:56
+ 30:5b:0c:d9:d1:52:cf:df:10:4f:c8:4a:75:b1:b8:b1
+ 59:9b:01:02:a2:4d:29:aa:63:e5:11:0a:17:ae:1e:79
+ ed:5d:10:fc:f0:8a:8d:f6:77:f8:78:17:1e:07:ee:d1
+ de:59:ed:d7:fb:94:bf:c9:7c:f7:f3:a0:8d:66:d3:94
+ 9a:7f:d1:7a:89:87:71:17:96:90:4e:be:7b:54:5e:51
+ 03:c6:35:af:5f:ea:5d:cc:31:ab:56:4b:75:6a:14:b6
+ c0:1a:bf:fb:e9:54:ba:ad:c3:52:e9:85:03:db:b2:e8
+ 0b:18:60:37:19:f9:07:87:e7:b2:d8:3a:0d:c9:d5:f0
+ f0:73:60:fc:9e:e0:9e:b1:ea:52:71:c7:fd:27:0a:22
+ 42:
+
+exp1:
+ 04:a5:69:04:00:55:76:e2:41:b1:08:d5:a7:af:62:79
+ 8c:04:af:74:d2:94:45:ae:01:0d:fa:5d:b8:08:3a:58
+ 80:1d:5f:30:cc:35:a0:47:f2:dc:55:39:e1:c8:dc:b4
+ 6c:26:0b:98:76:e7:32:77:4c:54:47:6e:1d:4b:d2:a3
+ 53:1e:06:72:d2:6d:c9:dd:af:ed:9c:a7:2f:b1:ac:a2
+ 1b:04:a7:97:87:81:08:0f:b1:f9:3c:22:1e:99:60:f3
+ 2f:4a:21:37:9c:eb:5f:d4:3b:f9:6c:ce:d4:dc:6c:3f
+ d3:13:7c:76:d6:b7:a1:cc:83:b5:f0:a2:be:de:97:9b
+ 1f:99:07:87:61:a4:fa:ff:c8:c3:b6:df:f4:eb:7c:ac
+ 64:61:13:e4:7e:17:87:e9:7a:3e:ff:e7:88:80:99:cc
+ 4f:b2:d3:4b:cc:42:3a:df:b1:ce:d6:e7:75:ca:b1:a5
+ b3:25:d4:b6:ba:da:e4:50:f9:0c:c3:32:e8:1f:14:71
+
+
+exp2:
+ 00:9d:9d:bb:a3:63:b0:96:20:8a:5f:52:f2:b6:e6:69
+ 65:ac:30:84:ee:ec:bd:16:45:44:e3:02:c2:73:c2:9d
+ f5:b2:5e:b3:b3:85:13:3e:e6:33:13:66:78:09:40:79
+ 43:03:5a:78:af:ac:a3:57:20:0e:dd:db:5b:6c:fd:a2
+ 4b:3f:70:37:e1:85:fb:5c:30:48:22:cc:b5:29:35:c6
+ 1a:58:27:8b:1f:bf:69:b5:dd:96:31:42:b9:6a:1a:bf
+ ec:5f:df:7e:89:69:3f:8e:a1:d6:09:36:04:a7:69:f8
+ 61:57:f5:03:96:ff:d2:c2:b3:c7:c3:ba:23:97:54:d4
+ 1e:f8:a0:ff:26:06:07:62:83:52:5e:fe:95:49:dc:f2
+ a6:6d:72:da:19:e4:1a:03:50:99:92:35:3f:10:f9:79
+ 96:c6:0a:36:fa:9b:8f:d9:d4:2a:11:da:e5:2f:e7:82
+ 2a:29:2a:39:72:f7:84:ed:a2:3f:89:d4:7b:95:50:5f
+ cd:
+
+
+Public Key PIN:
+ pin-sha256:u7TPTyh/innOijbJFG3Y4pWghApErLvhCQUZNXBlVFU=
+Public Key ID:
+ sha256:bbb4cf4f287f8a79ce8a36c9146dd8e295a0840a44acbbe10905193570655455
+ sha1:92b7d0c4d107e2a73f827b87866aef9ff4379cc8
+
+-----BEGIN RSA PRIVATE KEY-----
+MIIG5AIBAAKCAYEAnu7y2EGuLJOKAR+IW9aFKS+RnTf8NYh/U3GH/Bdx5xVXBi1U
++xmYgILsGpktV8tf3Sgm2JX7ZbK+4RGGaRR+MlzAAgtdEXhpUCAlPhX7ikbRg/k7
+hEacaSFE1QkdegTM82rqTBvafEDdHG/2hbTqdZg0eRH7z9MYcGQlM4oxtpNn1DJn
+YRzQe4VhVMb7UbaHHdS4WECpxTLO4LmQNw1Y5DNwxcWR8hj14AitF4vPcvEmbJyI
+0p4GTAJdTnyTr41yk3UdYAz3NAmo5vKAShSBJEBLRRmFLq2Ol0z/7NCf5qC3wKmg
+rdICLRNV89/4+fHzPjXpCCvbEZNXE1XGusbX/33h+oxHXdq/MVaAqjSXQ7ue/9Pm
+E6nCmUnCHtryx9LW919wNpEv6jbpiEQIoxoKwOBLSIKayXIpnAkkY7PCnyr26DrE
+RgONcK4UuzrWxmKTJH+8CsiiIFM8n1wVRQU9GzgX1P5rasIW8xRzwsPHNuPx+OUo
+hE431GjognAgU/wBAgMBAAECggGAREpoDoQqUv0ST2k9Ljj+/rNx3hwwQtBj5Xbi
+928bgi+pNP5FhZ95575ZtRQcZ5z7lAuspWPMoeYsHolpN72WfA1ec4JuexNCLSui
+1QqdCs1jOVHeQPgWPRYOfXttLwDhD7bg9dMCDmHQoGd7hfg2xlCgO2V+zc3msmRV
+l8/JjKnJ82O1CAVZj7nAGK1nT7UeWbMNgt5GFHXAbs9NKFqT13pC+rfp/hy7iYgw
+1+07NihoWkLoh5dfHUnmzdK5orUj2N9dz8aYmuCZejNSdSLOyoXr2ZJq1UnAy9+x
+opi1bDeFwuFqE0gicgKn4uDz8wztQvaDunHw74/Oalkwvp1fIwbDDklcj2qNwsPF
+B0VVePC9KQHLrOyxQH14zE3L+WCkovWqIQs+2hvZ8JkZRFchCboP+QWO7llPWQix
+Z1ECgE40x10leYyE974VAiic+bnK/Grt0F/fvs7ElmMjLtvhhR5FFiwksF56Yr82
+AIvIkGHCaEuVsM5Bd6OgXQlyAaABAoHBAMr+6xQHE6nvttVsUgI5tm5Vtt1w/MYE
+fAeBm5ik2tvxZrgzkf0AFW5yDasLb740yNmCWH4Jf+RvwHCZU2jHU9KPlyL16OS+
+X+EpDyenZnSyzJah0soqQEtwzHoWT8lPSRYR1fja9pIGHEXD+BfEHWWaKj8zvjP4
+hAMmSdhSJfgZzjEAwLZVcXQDU+gM74VkVNSPaAiH2subVWouK8KVNsTdCWLAb57p
+zOqWTuYtbHLBVJIRKZGvTc0IfPhvKJ3KxQKBwQDIbrevw8a530mt6rhit0PmBNla
+38P5ow215i2d98T/OMDLA5zB0W+0+8+BxJ6UKtXioXeoe4/RNHrC9TjsDTWgXjyv
+6S30+TKu2sEeYnTlqz07PdCI/FNZDyEw7SSsp1qlt/TMWpateaNBdFatORQKJ6QQ
+GBkz8hqqtDad+j/8cUIeoJaOD95Gh7psOBfQfshKy0opHES5iCnHb7dPPwDNDGsP
+d6Fa8YAhkbNoyg21yW0E9JiUnwn5qFjqNJzY8A0CgcAEpWkEAFV24kGxCNWnr2J5
+jASvdNKURa4BDfpduAg6WIAdXzDMNaBH8txVOeHI3LRsJguYducyd0xUR24dS9Kj
+Ux4GctJtyd2v7ZynL7GsohsEp5eHgQgPsfk8Ih6ZYPMvSiE3nOtf1Dv5bM7U3Gw/
+0xN8dta3ocyDtfCivt6Xmx+ZB4dhpPr/yMO23/TrfKxkYRPkfheH6Xo+/+eIgJnM
+T7LTS8xCOt+xztbndcqxpbMl1La62uRQ+QzDMugfFHECgcEAnZ27o2OwliCKX1Ly
+tuZpZawwhO7svRZFROMCwnPCnfWyXrOzhRM+5jMTZngJQHlDA1p4r6yjVyAO3dtb
+bP2iSz9wN+GF+1wwSCLMtSk1xhpYJ4sfv2m13ZYxQrlqGr/sX99+iWk/jqHWCTYE
+p2n4YVf1A5b/0sKzx8O6I5dU1B74oP8mBgdig1Je/pVJ3PKmbXLaGeQaA1CZkjU/
+EPl5lsYKNvqbj9nUKhHa5S/ngiopKjly94Ttoj+J1HuVUF/NAoHBAL97k2hk6l61
+9LaMkUmqK7CldEBzRSO2dK56Va6dirs7bTp9xHrAgn8O71cchuJWMFsM2dFSz98Q
+T8hKdbG4sVmbAQKiTSmqY+URCheuHnntXRD88IqN9nf4eBceB+7R3lnt1/uUv8l8
+9/OgjWbTlJp/0XqJh3EXlpBOvntUXlEDxjWvX+pdzDGrVkt1ahS2wBq/++lUuq3D
+UumFA9uy6AsYYDcZ+QeH57LYOg3J1fDwc2D8nuCesepSccf9JwoiQg==
+-----END RSA PRIVATE KEY-----
diff --git a/daemon/lua/trust_anchors.test/x509/ca.pem b/daemon/lua/trust_anchors.test/x509/ca.pem
new file mode 100644
index 0000000..e3c3ca2
--- /dev/null
+++ b/daemon/lua/trust_anchors.test/x509/ca.pem
@@ -0,0 +1,24 @@
+-----BEGIN CERTIFICATE-----
+MIIEGTCCAoGgAwIBAgIUXWsAXOOaZw+h37N9gUc/XLw3KHwwDQYJKoZIhvcNAQEL
+BQAwIzEhMB8GA1UEAxMYS25vdCBSZXNvbHZlciB0ZXN0aW5nIENBMCAXDTIwMDEw
+NzA5MzQwOVoYDzk5OTkxMjMxMjM1OTU5WjAjMSEwHwYDVQQDExhLbm90IFJlc29s
+dmVyIHRlc3RpbmcgQ0EwggGiMA0GCSqGSIb3DQEBAQUAA4IBjwAwggGKAoIBgQCe
+7vLYQa4sk4oBH4hb1oUpL5GdN/w1iH9TcYf8F3HnFVcGLVT7GZiAguwamS1Xy1/d
+KCbYlftlsr7hEYZpFH4yXMACC10ReGlQICU+FfuKRtGD+TuERpxpIUTVCR16BMzz
+aupMG9p8QN0cb/aFtOp1mDR5EfvP0xhwZCUzijG2k2fUMmdhHNB7hWFUxvtRtocd
+1LhYQKnFMs7guZA3DVjkM3DFxZHyGPXgCK0Xi89y8SZsnIjSngZMAl1OfJOvjXKT
+dR1gDPc0Cajm8oBKFIEkQEtFGYUurY6XTP/s0J/moLfAqaCt0gItE1Xz3/j58fM+
+NekIK9sRk1cTVca6xtf/feH6jEdd2r8xVoCqNJdDu57/0+YTqcKZScIe2vLH0tb3
+X3A2kS/qNumIRAijGgrA4EtIgprJcimcCSRjs8KfKvboOsRGA41wrhS7OtbGYpMk
+f7wKyKIgUzyfXBVFBT0bOBfU/mtqwhbzFHPCw8c24/H45SiETjfUaOiCcCBT/AEC
+AwEAAaNDMEEwDwYDVR0TAQH/BAUwAwEB/zAPBgNVHQ8BAf8EBQMDBwQAMB0GA1Ud
+DgQWBBSSt9DE0Qfipz+Ce4eGau+f9DecyDANBgkqhkiG9w0BAQsFAAOCAYEAA45p
+Ak7ebzk2ss5FHhJDvHrhoTZG2/esNEQhtv70nuRPnm3j8UGDxYyydwjf4+W9DT1v
+53QNfvbOIPcOUsGArAItmI7K6ltkBSS6ymO8T1ZY4vYw+77jJZ1EeYS6kjdan7dK
+f2Zz23CVbuq8BOc/Ob6ChepEq/MIb3g/Y6FowuWqeC85s61GW9MKr5GeG0oSyYAO
+UZdFnwa8QLCZ2IzQcwnolkAw2A/5TDxovINy9Lb5U3kyphC9vhjPqr8PJ5q/KVuK
+vcHvEsrsSNPvW/WcxkziV1oJTnjvr/69mwAme8+xjjF90GhrNaQF1YOoijuZuQaS
+Q+0qmwZbsMtcqAABKQALHfLGsGAA5MKip49khIQWuIAS8P2vb+hzbqQRLjq1uW7B
+dEGvBHF0QebDZOXJeXEYK/b7btWa9kNedD2FvBx5c9QNiWwh7jZENkICKnhI7E+n
+d5/gsKVa1glKwbMagZBSJgFtjZe/eo/LcoK82m4VuOUCJSe0Kd0McrSZ7XZX
+-----END CERTIFICATE-----
diff --git a/daemon/lua/trust_anchors.test/x509/ca.tmpl b/daemon/lua/trust_anchors.test/x509/ca.tmpl
new file mode 100644
index 0000000..ed801af
--- /dev/null
+++ b/daemon/lua/trust_anchors.test/x509/ca.tmpl
@@ -0,0 +1,4 @@
+cn = Knot Resolver testing CA
+ca
+cert_signing_key
+expiration_days = -1
diff --git a/daemon/lua/trust_anchors.test/x509/gen.sh b/daemon/lua/trust_anchors.test/x509/gen.sh
new file mode 100755
index 0000000..7251f12
--- /dev/null
+++ b/daemon/lua/trust_anchors.test/x509/gen.sh
@@ -0,0 +1,13 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# CA
+certtool --generate-privkey > ca-key.pem
+certtool --generate-self-signed --load-privkey ca-key.pem --template ca.tmpl --outfile ca.pem
+
+# server cert signed by CA above
+certtool --generate-privkey > server-key.pem
+certtool --generate-certificate --load-privkey server-key.pem --load-ca-certificate ca.pem --load-ca-privkey ca-key.pem --template server.tmpl --outfile server.pem
+
+# wrong CA - unrelated to others
+certtool --generate-privkey > wrongca-key.pem
+certtool --generate-self-signed --load-privkey wrongca-key.pem --template wrongca.tmpl --outfile wrongca.pem
diff --git a/daemon/lua/trust_anchors.test/x509/server-key.pem b/daemon/lua/trust_anchors.test/x509/server-key.pem
new file mode 100644
index 0000000..9eaef8a
--- /dev/null
+++ b/daemon/lua/trust_anchors.test/x509/server-key.pem
@@ -0,0 +1,182 @@
+Public Key Info:
+ Public Key Algorithm: RSA
+ Key Security Level: High (3072 bits)
+
+modulus:
+ 00:c3:46:2a:27:c8:39:e4:de:fa:24:45:6c:00:26:80
+ 61:ca:dd:a1:24:34:1b:93:1c:13:c8:5a:cf:af:6a:ef
+ 34:b9:89:83:02:76:51:ad:67:bf:ed:39:ee:0a:15:57
+ 91:6e:fa:68:60:78:22:62:fa:0a:55:12:03:b3:0c:8e
+ b4:ca:cd:2b:9d:a2:43:b5:5a:48:a0:3d:4a:1f:77:a4
+ a6:d4:87:eb:79:99:df:d4:b4:a3:cf:91:03:a0:c5:82
+ 39:f5:75:20:4b:90:b9:3b:72:65:a7:75:39:a6:62:58
+ 65:b0:9c:40:5c:c7:c4:4c:d3:1e:cc:74:18:74:15:23
+ 44:fd:51:59:b2:b7:70:95:6b:a0:be:d5:e4:72:59:2b
+ df:a5:a2:06:c8:e1:bd:17:80:25:b3:cf:8e:e8:ad:b2
+ f7:04:b1:9e:b8:72:0b:c5:dc:cd:a5:b6:f5:c9:1a:eb
+ 63:78:75:9c:5d:c5:03:a9:4b:7b:d6:cd:5c:5f:8d:2e
+ d0:b4:0d:96:55:c7:1e:c7:ac:13:46:b8:ec:9c:36:b9
+ 6a:1d:f0:7c:41:00:c6:bd:1f:81:7e:1d:48:1d:59:bc
+ e2:61:a6:d1:2d:52:10:3f:63:93:a9:14:d8:03:27:21
+ b0:d4:07:24:78:04:2b:86:c8:2b:0f:eb:a7:b3:3e:e2
+ 81:62:2a:4a:07:d9:fd:f6:77:7f:50:88:ee:bb:7d:31
+ 53:a8:97:bf:30:07:37:41:e9:52:16:15:74:a8:64:ed
+ 93:46:38:56:b4:89:d9:0c:62:4b:64:a9:64:ff:fc:9a
+ d6:19:a7:84:98:28:04:b4:95:76:ac:4a:42:6a:fb:67
+ 5b:b4:37:e6:e6:e2:52:d3:e9:38:8b:76:10:55:f1:e6
+ 8e:d8:73:eb:17:d1:54:41:d4:5b:76:2d:70:7f:f5:0d
+ 7d:d2:d6:f8:05:33:18:ab:dd:10:8a:5b:21:ee:3d:78
+ 9d:cd:c9:c0:c6:98:4e:a6:0a:41:f0:97:91:83:c2:c8
+ 4b:
+
+public exponent:
+ 01:00:01:
+
+private exponent:
+ 23:88:1f:e1:8f:40:61:91:e5:28:36:6d:99:75:68:04
+ e3:5a:02:99:48:d5:ff:a5:ab:3f:d8:ae:53:b7:fc:80
+ b6:85:fc:0d:b5:a3:d5:0e:bc:d0:98:aa:e4:b0:cf:77
+ 4a:1f:4c:60:c9:5b:50:71:38:f2:13:ce:12:85:65:6e
+ 26:3c:c1:03:f4:e3:a7:1b:1f:7d:f0:c9:0d:02:c3:36
+ 0c:14:13:57:d4:14:f3:6a:4f:28:54:b5:b9:4a:57:10
+ de:c6:0a:33:55:c9:2e:b4:f9:24:48:63:4e:10:35:0f
+ 83:dc:5a:a5:c7:3f:c3:ce:e2:9a:c7:41:2f:d6:2c:cd
+ bf:de:4e:99:03:61:fb:fe:52:88:86:f9:03:89:90:3f
+ 28:af:5b:d6:af:a4:ad:a3:06:b9:3a:3a:41:c2:61:7f
+ 2b:1e:7a:c8:0b:10:73:57:63:20:15:33:91:fd:50:f9
+ 8f:90:ae:fc:2c:fe:26:8e:f2:a0:ba:4b:65:a3:95:f1
+ d8:30:d4:fa:8d:12:1b:8b:58:1d:66:10:cd:41:22:1e
+ b0:7a:f4:e6:0f:76:3f:0a:0f:9c:44:e2:19:cf:c6:4d
+ de:3a:f4:96:70:c7:e6:2d:98:27:0e:ac:3b:32:41:37
+ 4e:05:b2:22:af:7b:38:92:16:40:fb:5c:96:b0:86:da
+ 96:c6:77:c3:66:78:07:80:5c:2a:46:dc:9a:bf:fc:0c
+ 2f:ee:f7:a1:b3:77:b4:50:75:a2:b7:36:9d:28:73:ee
+ 7a:ab:a6:0c:f6:92:18:8f:ff:16:28:90:7f:16:4f:f1
+ 6d:77:99:dd:a6:46:95:6a:6c:7a:15:48:53:b3:17:0b
+ 30:aa:0d:c8:68:33:2b:4d:40:da:74:cf:9b:73:1b:cd
+ 5d:f0:a9:d1:00:6f:db:de:55:ec:d4:24:96:bb:da:50
+ b4:d5:e1:87:35:5c:d4:50:c3:03:d5:d5:ee:03:65:4b
+ 68:9c:07:5c:59:28:78:bd:d1:4b:cb:8d:85:8b:5b:c1
+
+
+prime1:
+ 00:cc:8d:55:38:2d:57:cb:d2:4b:57:5b:3f:a2:6d:91
+ 4b:9c:54:29:98:9d:1d:bb:36:a6:e8:ba:e9:50:db:83
+ cf:c1:45:24:16:70:e5:51:40:eb:23:6b:fa:be:d5:d5
+ 00:27:ed:99:c7:7c:6b:16:79:77:0b:f3:ff:58:35:4e
+ 6c:58:68:51:d3:20:3c:57:b7:7d:bc:6b:fd:a7:c3:38
+ 9a:f2:7a:8a:b6:71:a1:6e:5e:64:7e:a8:c5:7c:58:70
+ fb:8d:63:b3:27:cc:1a:97:1e:04:da:d5:34:b5:d1:aa
+ f1:96:39:89:5e:cb:e7:75:ab:7e:ac:8c:fe:62:3e:cc
+ 93:66:88:d7:cd:c6:2d:db:9e:2f:f7:d1:6e:96:99:d2
+ 32:61:f4:9b:f5:48:fe:e7:90:b7:a2:ab:89:90:c1:ae
+ 67:5d:18:7a:c1:a3:84:97:09:47:13:df:d2:85:46:46
+ c7:77:3b:9f:b5:74:5c:f6:ec:a0:a7:66:0e:d1:d7:a4
+ e1:
+
+prime2:
+ 00:f4:63:70:fa:dd:7e:3d:1a:2b:5b:47:79:56:e9:c7
+ 7f:6b:50:41:60:45:af:59:e0:77:b2:76:4e:40:ff:f8
+ 55:9d:77:3b:c1:00:6a:c6:84:6a:09:a5:45:e6:fc:e6
+ e6:92:72:32:fc:93:8f:93:d9:db:fc:8c:43:d2:7a:ea
+ 4b:0e:ee:1d:dc:e0:27:08:83:16:aa:de:37:59:39:c0
+ 21:26:b5:34:49:f2:1f:7b:0c:d4:3c:0f:e5:06:ac:23
+ 7b:85:b1:39:35:44:ec:70:48:c5:10:86:02:ea:36:4a
+ f1:20:a2:b2:c9:8d:d3:f6:5a:86:72:4b:8b:28:07:04
+ 39:8d:01:fa:75:3a:35:40:c2:21:c3:ac:50:da:2f:3e
+ 30:ee:ab:f7:7d:81:a3:77:5e:b7:03:be:52:fb:a4:70
+ 92:5d:fd:09:ae:52:33:b8:7b:9c:e2:2a:77:f7:23:4d
+ c5:4b:82:f1:fb:0a:09:62:e6:5f:32:1e:7b:c7:c6:66
+ ab:
+
+coefficient:
+ 00:c3:2d:d8:18:32:30:a1:fa:2c:23:d0:ea:b4:60:0f
+ 29:67:50:4a:5a:61:aa:6d:15:0e:4b:66:43:35:ee:39
+ 4c:e7:8d:31:73:b0:bb:04:4d:e5:bc:28:ea:dc:77:81
+ 35:bb:f7:80:13:96:04:4c:45:9c:43:6f:64:e0:a3:51
+ 4b:7e:6c:b6:7d:c2:a6:e0:94:e6:6c:34:4e:62:71:ea
+ c0:c0:ab:30:30:c1:3a:39:0e:cd:f0:cc:0e:31:b5:fc
+ 61:64:1e:29:1c:cd:fc:69:c0:02:7c:2a:fe:86:d5:e2
+ 7b:8d:fe:ae:3d:3a:6c:1b:b3:b4:0d:b1:1b:d1:4d:37
+ 36:ea:d7:15:f3:6e:02:b1:86:98:51:02:fc:62:df:30
+ f2:de:9f:03:6d:27:45:d7:c7:a8:04:ba:76:18:01:09
+ 34:d2:57:f9:10:50:ea:ae:0e:ae:c6:a4:cd:f9:fd:b1
+ 25:b2:45:20:bc:50:2d:9b:80:c1:39:08:97:d2:75:9b
+ f7:
+
+exp1:
+ 00:8a:b8:6a:8b:cf:8c:54:08:c8:d9:74:63:82:67:25
+ fb:0e:08:b1:b0:f3:14:7f:ab:3f:a4:63:65:e9:55:05
+ 5e:36:a7:0a:23:41:ea:f2:a0:c1:16:63:9b:48:22:41
+ f2:7a:21:93:81:8a:ea:20:f2:bc:fe:59:39:d8:fb:45
+ b5:0a:7b:ac:ca:2e:79:5d:cf:6d:b1:03:d7:a1:17:2e
+ e3:3e:00:46:e4:15:c9:b1:cc:c8:00:71:ba:84:6a:82
+ 2c:c6:a5:4f:91:74:c4:af:a9:47:07:95:41:ca:f0:67
+ 2a:b1:83:51:9a:fd:53:7a:24:94:a2:b6:77:a9:ef:06
+ d4:0b:dc:4f:e6:18:39:6f:50:27:1d:bc:65:70:32:df
+ 2f:15:e9:4a:7f:1d:42:e9:8d:e6:4b:a6:63:83:cd:25
+ d6:a9:76:f9:81:2a:c0:b7:a1:2e:17:d7:59:b0:d2:89
+ 1b:aa:cb:bf:b2:d2:38:5d:a8:fa:06:ac:9a:ee:4a:7d
+ 61:
+
+exp2:
+ 00:92:66:af:db:d8:ac:33:36:66:1a:bc:6a:78:22:7c
+ 1c:5c:d1:2b:18:dd:25:fa:95:79:9f:33:38:15:c0:41
+ a8:28:38:b1:57:21:44:d5:bf:a5:36:3a:07:f2:24:36
+ be:91:a4:4f:de:f7:16:df:df:76:e5:87:b1:69:79:b0
+ b9:5e:2c:4f:3f:6e:18:74:04:f3:a3:50:93:9f:a3:f4
+ f0:e7:1b:4e:43:ae:04:25:d6:bd:9d:6d:78:29:d3:1d
+ 3e:76:0c:80:d4:e4:81:2f:92:a8:5b:09:ac:dd:59:c0
+ f3:4a:35:ad:1d:09:15:9d:53:05:8f:9a:a9:b6:44:dd
+ c7:0c:2d:cf:38:42:b2:7c:24:cf:cd:44:80:fa:f3:aa
+ 31:ee:08:9e:ae:54:e6:f4:2f:8d:3b:74:dc:89:5b:2d
+ 04:c1:c1:3f:f7:69:cf:0a:09:23:26:69:82:8c:4e:5d
+ dc:7f:2b:e6:82:18:b5:1e:c6:1a:e9:0f:51:df:8f:7f
+ 19:
+
+
+Public Key PIN:
+ pin-sha256:pFSHHHovr50DJ04K3wEJcyxth+nszZdClOet/CRN9cU=
+Public Key ID:
+ sha256:a454871c7a2faf9d03274e0adf0109732c6d87e9eccd974294e7adfc244df5c5
+ sha1:5137ef343399ccf38d6566803ddce123da640553
+
+-----BEGIN RSA PRIVATE KEY-----
+MIIG5QIBAAKCAYEAw0YqJ8g55N76JEVsACaAYcrdoSQ0G5McE8haz69q7zS5iYMC
+dlGtZ7/tOe4KFVeRbvpoYHgiYvoKVRIDswyOtMrNK52iQ7VaSKA9Sh93pKbUh+t5
+md/UtKPPkQOgxYI59XUgS5C5O3Jlp3U5pmJYZbCcQFzHxEzTHsx0GHQVI0T9UVmy
+t3CVa6C+1eRyWSvfpaIGyOG9F4Als8+O6K2y9wSxnrhyC8XczaW29cka62N4dZxd
+xQOpS3vWzVxfjS7QtA2WVccex6wTRrjsnDa5ah3wfEEAxr0fgX4dSB1ZvOJhptEt
+UhA/Y5OpFNgDJyGw1AckeAQrhsgrD+unsz7igWIqSgfZ/fZ3f1CI7rt9MVOol78w
+BzdB6VIWFXSoZO2TRjhWtInZDGJLZKlk//ya1hmnhJgoBLSVdqxKQmr7Z1u0N+bm
+4lLT6TiLdhBV8eaO2HPrF9FUQdRbdi1wf/UNfdLW+AUzGKvdEIpbIe49eJ3NycDG
+mE6mCkHwl5GDwshLAgMBAAECggGAI4gf4Y9AYZHlKDZtmXVoBONaAplI1f+lqz/Y
+rlO3/IC2hfwNtaPVDrzQmKrksM93Sh9MYMlbUHE48hPOEoVlbiY8wQP046cbH33w
+yQ0CwzYMFBNX1BTzak8oVLW5SlcQ3sYKM1XJLrT5JEhjThA1D4PcWqXHP8PO4prH
+QS/WLM2/3k6ZA2H7/lKIhvkDiZA/KK9b1q+kraMGuTo6QcJhfyseesgLEHNXYyAV
+M5H9UPmPkK78LP4mjvKguktlo5Xx2DDU+o0SG4tYHWYQzUEiHrB69OYPdj8KD5xE
+4hnPxk3eOvSWcMfmLZgnDqw7MkE3TgWyIq97OJIWQPtclrCG2pbGd8NmeAeAXCpG
+3Jq//Awv7vehs3e0UHWitzadKHPuequmDPaSGI//FiiQfxZP8W13md2mRpVqbHoV
+SFOzFwswqg3IaDMrTUDadM+bcxvNXfCp0QBv295V7NQklrvaULTV4Yc1XNRQwwPV
+1e4DZUtonAdcWSh4vdFLy42Fi1vBAoHBAMyNVTgtV8vSS1dbP6JtkUucVCmYnR27
+NqbouulQ24PPwUUkFnDlUUDrI2v6vtXVACftmcd8axZ5dwvz/1g1TmxYaFHTIDxX
+t328a/2nwzia8nqKtnGhbl5kfqjFfFhw+41jsyfMGpceBNrVNLXRqvGWOYley+d1
+q36sjP5iPsyTZojXzcYt254v99FulpnSMmH0m/VI/ueQt6KriZDBrmddGHrBo4SX
+CUcT39KFRkbHdzuftXRc9uygp2YO0dek4QKBwQD0Y3D63X49GitbR3lW6cd/a1BB
+YEWvWeB3snZOQP/4VZ13O8EAasaEagmlReb85uaScjL8k4+T2dv8jEPSeupLDu4d
+3OAnCIMWqt43WTnAISa1NEnyH3sM1DwP5QasI3uFsTk1ROxwSMUQhgLqNkrxIKKy
+yY3T9lqGckuLKAcEOY0B+nU6NUDCIcOsUNovPjDuq/d9gaN3XrcDvlL7pHCSXf0J
+rlIzuHuc4ip39yNNxUuC8fsKCWLmXzIee8fGZqsCgcEAirhqi8+MVAjI2XRjgmcl
++w4IsbDzFH+rP6RjZelVBV42pwojQeryoMEWY5tIIkHyeiGTgYrqIPK8/lk52PtF
+tQp7rMoueV3PbbED16EXLuM+AEbkFcmxzMgAcbqEaoIsxqVPkXTEr6lHB5VByvBn
+KrGDUZr9U3oklKK2d6nvBtQL3E/mGDlvUCcdvGVwMt8vFelKfx1C6Y3mS6Zjg80l
+1ql2+YEqwLehLhfXWbDSiRuqy7+y0jhdqPoGrJruSn1hAoHBAJJmr9vYrDM2Zhq8
+angifBxc0SsY3SX6lXmfMzgVwEGoKDixVyFE1b+lNjoH8iQ2vpGkT973Ft/fduWH
+sWl5sLleLE8/bhh0BPOjUJOfo/Tw5xtOQ64EJda9nW14KdMdPnYMgNTkgS+SqFsJ
+rN1ZwPNKNa0dCRWdUwWPmqm2RN3HDC3POEKyfCTPzUSA+vOqMe4Inq5U5vQvjTt0
+3IlbLQTBwT/3ac8KCSMmaYKMTl3cfyvmghi1HsYa6Q9R349/GQKBwQDDLdgYMjCh
++iwj0Oq0YA8pZ1BKWmGqbRUOS2ZDNe45TOeNMXOwuwRN5bwo6tx3gTW794ATlgRM
+RZxDb2Tgo1FLfmy2fcKm4JTmbDROYnHqwMCrMDDBOjkOzfDMDjG1/GFkHikczfxp
+wAJ8Kv6G1eJ7jf6uPTpsG7O0DbEb0U03NurXFfNuArGGmFEC/GLfMPLenwNtJ0XX
+x6gEunYYAQk00lf5EFDqrg6uxqTN+f2xJbJFILxQLZuAwTkIl9J1m/c=
+-----END RSA PRIVATE KEY-----
diff --git a/daemon/lua/trust_anchors.test/x509/server.pem b/daemon/lua/trust_anchors.test/x509/server.pem
new file mode 100644
index 0000000..b42f07e
--- /dev/null
+++ b/daemon/lua/trust_anchors.test/x509/server.pem
@@ -0,0 +1,27 @@
+-----BEGIN CERTIFICATE-----
+MIIEfTCCAuWgAwIBAgIUIREQSLx52Sc9PFWI6Nwe3YzRp3MwDQYJKoZIhvcNAQEL
+BQAwIzEhMB8GA1UEAxMYS25vdCBSZXNvbHZlciB0ZXN0aW5nIENBMCAXDTIwMDEw
+NzA5MzQwOVoYDzk5OTkxMjMxMjM1OTU5WjA8MRIwEAYDVQQDEwlsb2NhbGhvc3Qx
+JjAkBgNVBAoTHUZha2UgRE5TIHJvb3Qgb3JnIHRlc3Qgc2VydmVyMIIBojANBgkq
+hkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAw0YqJ8g55N76JEVsACaAYcrdoSQ0G5Mc
+E8haz69q7zS5iYMCdlGtZ7/tOe4KFVeRbvpoYHgiYvoKVRIDswyOtMrNK52iQ7Va
+SKA9Sh93pKbUh+t5md/UtKPPkQOgxYI59XUgS5C5O3Jlp3U5pmJYZbCcQFzHxEzT
+Hsx0GHQVI0T9UVmyt3CVa6C+1eRyWSvfpaIGyOG9F4Als8+O6K2y9wSxnrhyC8Xc
+zaW29cka62N4dZxdxQOpS3vWzVxfjS7QtA2WVccex6wTRrjsnDa5ah3wfEEAxr0f
+gX4dSB1ZvOJhptEtUhA/Y5OpFNgDJyGw1AckeAQrhsgrD+unsz7igWIqSgfZ/fZ3
+f1CI7rt9MVOol78wBzdB6VIWFXSoZO2TRjhWtInZDGJLZKlk//ya1hmnhJgoBLSV
+dqxKQmr7Z1u0N+bm4lLT6TiLdhBV8eaO2HPrF9FUQdRbdi1wf/UNfdLW+AUzGKvd
+EIpbIe49eJ3NycDGmE6mCkHwl5GDwshLAgMBAAGjgY0wgYowDAYDVR0TAQH/BAIw
+ADAUBgNVHREEDTALgglsb2NhbGhvc3QwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDwYD
+VR0PAQH/BAUDAwegADAdBgNVHQ4EFgQUUTfvNDOZzPONZWaAPdzhI9pkBVMwHwYD
+VR0jBBgwFoAUkrfQxNEH4qc/gnuHhmrvn/Q3nMgwDQYJKoZIhvcNAQELBQADggGB
+AFfFgv5J1eb8h33tnvDJ/dLBSA7Soz1NXK8iha18CH1uxW2lo+6iJl7g191WD/3W
+m/LdpRU3h5ewbD6An3FSA0I25cYQD1vlH7vdI+xu3hIuFhQVnkxGbwISzlM5vat8
+1Ry7z/RpHmQA4V4z4R/PuYcQHQG5tINMPySmbfHBK/Ju+nnmSTJ/p3Z7sVaSCfNN
+l37me0w197QU3ovNtA61xHa77VUSJeaAC+zOOXUBZ8Rc5PqhYOf6AJbIBk7tPNei
+XH5Yyg3UT0i7V09vUViXK8EXbMX1VWsw59Et4Ro1YouS6TN34i2w8FtKg1+amQLr
+UXmQW1lkzx23FdGG4T0fFPtWuJCL6ioc0J6vS7xt0xkbrri9U2thC7gvrKLGCJ6J
+hWTGoKwjcBHpoLsT62XogHlctagkyXfjJ1Piik7k2JjqvmyteFlDDkOToLQmaCuI
+LIBmOnO9mEig3y7T72cnL8QM+nb+c70cssfCW3LBTHb893J4QAOt5RN6LQUlFc49
+sQ==
+-----END CERTIFICATE-----
diff --git a/daemon/lua/trust_anchors.test/x509/server.tmpl b/daemon/lua/trust_anchors.test/x509/server.tmpl
new file mode 100644
index 0000000..8021616
--- /dev/null
+++ b/daemon/lua/trust_anchors.test/x509/server.tmpl
@@ -0,0 +1,7 @@
+organization = Fake DNS root org test server
+cn = localhost
+tls_www_server
+encryption_key
+signing_key
+dns_name = localhost
+expiration_days = -1
diff --git a/daemon/lua/trust_anchors.test/x509/wrongca-key.pem b/daemon/lua/trust_anchors.test/x509/wrongca-key.pem
new file mode 100644
index 0000000..1ddc1ad
--- /dev/null
+++ b/daemon/lua/trust_anchors.test/x509/wrongca-key.pem
@@ -0,0 +1,182 @@
+Public Key Info:
+ Public Key Algorithm: RSA
+ Key Security Level: High (3072 bits)
+
+modulus:
+ 00:bb:d7:47:1f:55:ed:c0:08:af:1d:32:d2:69:ef:77
+ d2:f3:f6:86:7e:f3:97:e2:35:72:d4:0a:87:1e:75:76
+ bf:59:29:be:cd:e6:ad:6d:7d:62:47:19:fb:ed:24:94
+ 7f:2b:d6:0c:68:cf:cd:ee:f3:5e:b2:db:11:44:4b:7f
+ 30:ce:d2:a7:75:a7:37:83:c0:41:d6:a1:87:22:48:fa
+ ef:d1:15:ed:c9:d2:73:ab:e1:7c:94:4d:b2:96:80:cf
+ 5a:5c:7e:96:f6:02:fa:a4:8b:b1:05:b0:27:f5:d7:38
+ bd:20:37:ed:12:c0:22:07:a9:a6:5e:47:bd:1d:33:27
+ a2:cd:4c:0c:70:ba:6e:d9:13:6f:7b:a1:72:e8:f4:be
+ e3:86:1b:a2:b3:a1:07:cf:93:e8:3a:26:51:3e:af:bc
+ da:80:b1:92:56:8b:21:e7:1d:d9:f9:0c:a9:68:b7:04
+ d8:6d:1f:6f:98:90:fb:fb:35:18:71:3c:50:73:b1:45
+ b1:e7:ee:7b:84:5d:57:95:33:37:b0:0f:eb:85:8f:8d
+ b0:7f:10:17:80:03:99:1b:62:0c:1d:72:6f:e5:77:38
+ c8:75:96:61:36:4b:28:ae:17:a4:f9:81:90:4d:4b:85
+ 61:39:be:6c:ca:c0:a9:cd:4e:45:27:47:84:82:3d:7f
+ c6:a7:00:d7:90:64:7c:a5:e9:f8:f6:92:d2:72:54:a7
+ 95:5f:fc:93:1d:c9:1a:78:6e:3a:1a:1f:8f:a2:41:d2
+ 04:5c:19:32:54:16:f2:97:6f:7c:f9:24:d7:a6:e2:07
+ cf:9f:9e:64:27:81:5f:5a:77:65:4f:7b:b2:81:78:3f
+ a3:22:17:d3:ba:06:71:d5:09:6a:c2:85:ba:35:f7:71
+ 01:b4:63:c7:70:62:98:58:80:a2:40:27:c0:e2:d5:fd
+ 60:e0:5a:7a:9c:bf:7b:e6:34:78:f1:16:e8:28:d9:92
+ dc:e6:2e:b6:d7:1a:83:4b:86:92:d6:81:ce:8e:50:0a
+ d5:
+
+public exponent:
+ 01:00:01:
+
+private exponent:
+ 7a:27:5e:66:1f:60:54:60:91:58:80:a3:5b:26:d2:9a
+ 89:f2:88:b6:68:3d:1e:6b:39:b8:70:fc:3b:af:91:c0
+ 90:00:58:c7:d7:ba:72:98:76:5f:dc:a2:fb:2d:ad:b0
+ 21:d6:ba:0d:33:0e:2d:d5:70:81:09:7b:6a:19:5a:a6
+ 67:e9:8f:e3:30:12:27:08:d1:07:fd:d5:3e:53:8d:74
+ 85:59:28:60:f6:0e:28:f9:a3:25:62:7d:bf:e8:16:70
+ 21:f4:64:c1:a9:60:4b:bf:58:28:65:cd:26:cf:86:63
+ 5f:5f:5f:39:b1:5e:af:f3:00:71:11:60:07:6c:2b:db
+ 70:7c:83:1e:8f:ee:e4:16:02:8a:b8:8c:5c:b8:44:a6
+ fb:a0:5f:27:47:92:27:c8:7c:dd:cb:eb:4b:c3:c7:21
+ a5:4d:54:e8:18:e4:bc:42:aa:6c:8e:72:60:d9:9c:3a
+ 0e:84:c1:f2:ca:5e:43:97:dc:c4:4e:bf:d6:ec:b2:70
+ 08:41:13:01:48:bc:36:a2:eb:5e:67:b6:6a:a4:b6:4a
+ 24:fa:fd:6d:ef:5b:77:bc:0c:7d:95:9a:84:ec:3f:97
+ aa:7c:07:76:80:f5:3a:49:f4:99:ee:cf:17:12:83:e8
+ db:ef:22:60:67:62:f8:3e:f9:bc:18:2b:84:fc:a9:82
+ 95:8d:91:27:8e:ba:87:15:65:1e:9f:b3:95:5f:dc:40
+ 2f:15:eb:7e:0a:d7:69:80:7b:8a:e2:29:89:3a:2e:eb
+ a9:05:c1:1e:5d:23:0d:a0:d7:c4:95:4d:09:85:8c:af
+ 90:23:36:04:66:a9:16:d7:d4:e2:aa:5a:6d:44:5a:6c
+ c8:e8:a0:08:fa:de:19:20:5f:e3:06:17:e5:65:c6:55
+ ef:0f:0d:ff:3e:1c:c5:98:ee:34:d3:07:81:11:fe:e9
+ 15:87:e6:9a:76:44:bd:cb:a0:38:63:9a:af:d1:7c:a7
+ db:26:e2:cd:4a:a2:8a:7f:b8:dc:7a:55:00:4c:20:c1
+
+
+prime1:
+ 00:c9:f5:14:59:49:3b:95:1f:15:b0:0c:83:cb:f4:6a
+ 48:60:2a:af:8b:d5:83:16:aa:71:5a:af:11:63:c6:c1
+ 0a:91:af:5b:bd:6e:9c:cb:d7:eb:bf:c7:31:9f:22:46
+ 01:cf:3b:3c:cb:ba:7d:ad:e5:bb:d8:7c:d2:5d:52:20
+ 14:ea:70:08:9e:29:98:31:20:78:9e:b6:3e:90:e8:ef
+ c8:2f:45:d4:35:04:71:a1:84:18:50:a9:a5:12:b7:14
+ 4e:42:3e:93:50:9d:2f:c1:bd:45:f3:4e:86:61:0b:bc
+ 3b:ed:78:c7:2b:ba:4b:a0:ef:e6:0e:a9:9a:f4:aa:73
+ 23:b8:51:c7:d3:dd:fd:a7:1c:c1:69:32:ea:26:32:6d
+ 40:b0:0a:cd:0d:fa:b4:f4:56:ed:e8:d4:96:08:80:fd
+ 43:44:8c:fb:bb:af:81:d7:bb:71:c6:7c:3a:d2:a7:83
+ e6:28:2d:2f:00:05:82:d7:cc:59:db:d9:e5:4f:a4:67
+ 05:
+
+prime2:
+ 00:ee:1b:2a:48:37:fa:7c:94:35:36:ac:83:5f:2c:98
+ e3:07:43:d1:2c:80:0e:a2:b8:7a:eb:e2:70:f6:49:77
+ b3:42:05:fe:06:cf:3f:ca:0f:0d:44:1c:74:0a:77:f7
+ 31:9f:30:fb:d9:44:71:11:e6:4a:ff:ef:ae:77:98:3e
+ 73:a0:77:21:a6:e0:66:9a:cf:5f:eb:3b:39:62:0b:ba
+ 1b:9b:1a:a5:58:4c:7e:17:fc:64:61:93:89:f0:c0:0f
+ ce:55:18:7e:d4:33:87:32:0e:53:51:5f:03:b4:05:4a
+ 5c:e7:5b:10:e5:b7:88:e5:04:b2:53:45:98:2f:9d:fb
+ 32:f5:2f:d9:59:54:ce:91:83:4c:37:ee:ab:5a:05:40
+ 85:05:03:ae:b4:3d:96:c2:67:6b:28:25:91:87:ed:d1
+ 3a:0f:4b:38:a5:81:b3:5b:6f:3e:33:27:1e:9a:4a:e6
+ 3c:7c:be:9f:45:72:5b:eb:e3:dd:6c:73:ae:0d:07:bd
+ 91:
+
+coefficient:
+ 45:53:87:ab:71:9c:14:af:6c:00:44:bb:de:d5:72:ed
+ e9:21:f2:19:e5:4d:30:92:8e:9b:b7:f6:db:9e:ea:71
+ b3:c2:89:01:4a:49:1f:2e:f8:34:57:e0:36:9a:20:84
+ a8:b0:8a:0b:2a:d6:da:36:22:c2:ac:a2:85:99:f7:5d
+ 3f:2e:71:ab:e5:f7:bd:b2:8c:6f:44:33:aa:2d:cf:38
+ 8c:d6:77:c7:d5:68:88:f1:f9:80:c2:e2:b8:58:26:bd
+ de:d6:8d:d5:c9:43:dc:e2:af:2e:d3:c5:19:4e:d5:14
+ 33:bc:15:58:6f:05:eb:8d:0d:fa:40:a3:b7:77:24:4b
+ 30:a7:c2:8b:89:08:24:4d:fb:2e:3c:ad:ff:e3:d7:8b
+ 9c:f2:07:0d:79:3c:5e:f5:83:94:32:e2:16:dc:a9:22
+ b4:f4:09:6a:f6:af:7d:9c:41:dc:be:23:7e:c4:6d:d6
+ f9:e6:8e:3c:2d:00:fa:ac:d2:c8:6e:c5:6d:52:74:cd
+
+
+exp1:
+ 4d:20:f9:2d:84:47:6a:13:1e:10:47:27:4a:8c:44:ce
+ f1:53:3c:09:d6:78:22:fe:e3:1d:b4:00:9b:2f:7b:e8
+ 12:6d:7b:46:e4:68:a3:7d:09:ff:0b:0f:0b:6c:66:7a
+ 28:6f:c2:2f:38:40:e9:59:f4:9c:a0:47:22:f6:cb:63
+ d1:89:09:f1:85:87:27:33:f4:7d:00:b2:f2:5a:d3:c0
+ 8b:35:4a:ef:18:8c:61:17:f6:c5:4f:94:c8:89:fd:0a
+ 4a:48:65:b0:82:e7:8b:41:42:e6:c2:15:96:18:8a:42
+ 04:d6:7c:92:59:aa:aa:83:14:44:83:47:b7:ab:25:1f
+ fe:33:d5:72:37:b4:b8:ce:c5:9a:ec:a3:fa:04:86:2f
+ 0f:4c:80:b5:97:0a:e6:ca:10:40:3c:78:34:35:37:04
+ 2a:b9:01:26:d3:c7:6d:e1:9b:79:27:56:bb:be:d8:23
+ dd:32:2c:62:00:b8:d0:bb:ad:91:c6:2c:ca:76:ca:15
+
+
+exp2:
+ 30:d8:19:c0:5e:db:5f:9a:f7:9f:93:9c:0f:76:12:96
+ df:f2:a5:82:3f:72:c1:26:9e:f0:ac:af:07:96:e2:9b
+ 3f:3c:03:74:5a:27:77:c7:c6:ac:e6:39:57:bc:6c:55
+ 1d:96:ea:d3:13:1b:2e:d4:d3:25:d5:81:30:bf:66:70
+ 49:c6:a6:7c:99:23:f3:35:ff:33:3e:1e:f3:61:fc:77
+ 95:45:ce:0d:63:03:aa:df:f7:a7:9c:a0:7b:66:aa:d7
+ 64:d5:75:8f:0a:52:fd:8d:ba:c1:c2:7f:fb:f9:e9:db
+ 4d:0a:7d:58:e2:61:8e:b9:7b:eb:61:27:6a:fd:39:7e
+ a6:95:7e:3c:b9:0c:f7:04:bc:29:ed:27:f1:7b:8a:54
+ bf:46:96:1c:1b:56:45:e2:f9:34:6f:20:7f:85:e5:99
+ c7:71:62:d9:70:d5:de:37:df:c6:96:8b:cc:92:f8:d0
+ 07:b7:02:ed:38:1c:6b:33:7f:44:b4:26:4c:3d:fe:41
+
+
+
+Public Key PIN:
+ pin-sha256:UOonm3sEw21t/nC/tr24q9sX/HPV9mo0/M3Ya8rAwLs=
+Public Key ID:
+ sha256:50ea279b7b04c36d6dfe70bfb6bdb8abdb17fc73d5f66a34fccdd86bcac0c0bb
+ sha1:b963cfb8eb202ccad2bb988dfa9e00cc52c1a4ba
+
+-----BEGIN RSA PRIVATE KEY-----
+MIIG4gIBAAKCAYEAu9dHH1XtwAivHTLSae930vP2hn7zl+I1ctQKhx51dr9ZKb7N
+5q1tfWJHGfvtJJR/K9YMaM/N7vNestsRREt/MM7Sp3WnN4PAQdahhyJI+u/RFe3J
+0nOr4XyUTbKWgM9aXH6W9gL6pIuxBbAn9dc4vSA37RLAIgeppl5HvR0zJ6LNTAxw
+um7ZE297oXLo9L7jhhuis6EHz5PoOiZRPq+82oCxklaLIecd2fkMqWi3BNhtH2+Y
+kPv7NRhxPFBzsUWx5+57hF1XlTM3sA/rhY+NsH8QF4ADmRtiDB1yb+V3OMh1lmE2
+SyiuF6T5gZBNS4VhOb5sysCpzU5FJ0eEgj1/xqcA15BkfKXp+PaS0nJUp5Vf/JMd
+yRp4bjoaH4+iQdIEXBkyVBbyl298+STXpuIHz5+eZCeBX1p3ZU97soF4P6MiF9O6
+BnHVCWrChbo193EBtGPHcGKYWICiQCfA4tX9YOBaepy/e+Y0ePEW6CjZktzmLrbX
+GoNLhpLWgc6OUArVAgMBAAECggGAeideZh9gVGCRWICjWybSmonyiLZoPR5rObhw
+/DuvkcCQAFjH17pymHZf3KL7La2wIda6DTMOLdVwgQl7ahlapmfpj+MwEicI0Qf9
+1T5TjXSFWShg9g4o+aMlYn2/6BZwIfRkwalgS79YKGXNJs+GY19fXzmxXq/zAHER
+YAdsK9twfIMej+7kFgKKuIxcuESm+6BfJ0eSJ8h83cvrS8PHIaVNVOgY5LxCqmyO
+cmDZnDoOhMHyyl5Dl9zETr/W7LJwCEETAUi8NqLrXme2aqS2SiT6/W3vW3e8DH2V
+moTsP5eqfAd2gPU6SfSZ7s8XEoPo2+8iYGdi+D75vBgrhPypgpWNkSeOuocVZR6f
+s5Vf3EAvFet+CtdpgHuK4imJOi7rqQXBHl0jDaDXxJVNCYWMr5AjNgRmqRbX1OKq
+Wm1EWmzI6KAI+t4ZIF/jBhflZcZV7w8N/z4cxZjuNNMHgRH+6RWH5pp2RL3LoDhj
+mq/RfKfbJuLNSqKKf7jcelUATCDBAoHBAMn1FFlJO5UfFbAMg8v0akhgKq+L1YMW
+qnFarxFjxsEKka9bvW6cy9frv8cxnyJGAc87PMu6fa3lu9h80l1SIBTqcAieKZgx
+IHietj6Q6O/IL0XUNQRxoYQYUKmlErcUTkI+k1CdL8G9RfNOhmELvDvteMcrukug
+7+YOqZr0qnMjuFHH0939pxzBaTLqJjJtQLAKzQ36tPRW7ejUlgiA/UNEjPu7r4HX
+u3HGfDrSp4PmKC0vAAWC18xZ29nlT6RnBQKBwQDuGypIN/p8lDU2rINfLJjjB0PR
+LIAOorh66+Jw9kl3s0IF/gbPP8oPDUQcdAp39zGfMPvZRHER5kr/7653mD5zoHch
+puBmms9f6zs5Ygu6G5sapVhMfhf8ZGGTifDAD85VGH7UM4cyDlNRXwO0BUpc51sQ
+5beI5QSyU0WYL537MvUv2VlUzpGDTDfuq1oFQIUFA660PZbCZ2soJZGH7dE6D0s4
+pYGzW28+MycemkrmPHy+n0VyW+vj3Wxzrg0HvZECgcBNIPkthEdqEx4QRydKjETO
+8VM8CdZ4Iv7jHbQAmy976BJte0bkaKN9Cf8LDwtsZnoob8IvOEDpWfScoEci9stj
+0YkJ8YWHJzP0fQCy8lrTwIs1Su8YjGEX9sVPlMiJ/QpKSGWwgueLQULmwhWWGIpC
+BNZ8klmqqoMURINHt6slH/4z1XI3tLjOxZrso/oEhi8PTIC1lwrmyhBAPHg0NTcE
+KrkBJtPHbeGbeSdWu77YI90yLGIAuNC7rZHGLMp2yhUCgcAw2BnAXttfmvefk5wP
+dhKW3/Klgj9ywSae8KyvB5bimz88A3RaJ3fHxqzmOVe8bFUdlurTExsu1NMl1YEw
+v2ZwScamfJkj8zX/Mz4e82H8d5VFzg1jA6rf96ecoHtmqtdk1XWPClL9jbrBwn/7
++enbTQp9WOJhjrl762Enav05fqaVfjy5DPcEvCntJ/F7ilS/RpYcG1ZF4vk0byB/
+heWZx3Fi2XDV3jffxpaLzJL40Ae3Au04HGszf0S0Jkw9/kECgcBFU4ercZwUr2wA
+RLve1XLt6SHyGeVNMJKOm7f2257qcbPCiQFKSR8u+DRX4DaaIISosIoLKtbaNiLC
+rKKFmfddPy5xq+X3vbKMb0Qzqi3POIzWd8fVaIjx+YDC4rhYJr3e1o3VyUPc4q8u
+08UZTtUUM7wVWG8F640N+kCjt3ckSzCnwouJCCRN+y48rf/j14uc8gcNeTxe9YOU
+MuIW3KkitPQJavavfZxB3L4jfsRt1vnmjjwtAPqs0shuxW1SdM0=
+-----END RSA PRIVATE KEY-----
diff --git a/daemon/lua/trust_anchors.test/x509/wrongca.pem b/daemon/lua/trust_anchors.test/x509/wrongca.pem
new file mode 100644
index 0000000..fc3e43f
--- /dev/null
+++ b/daemon/lua/trust_anchors.test/x509/wrongca.pem
@@ -0,0 +1,24 @@
+-----BEGIN CERTIFICATE-----
+MIIEETCCAnmgAwIBAgIUNVTN+if8IQU0I1n4qyVF9qqhuo0wDQYJKoZIhvcNAQEL
+BQAwHzEdMBsGA1UEAxMUQW5vdGhlciB1bnJlbGF0ZWQgQ0EwIBcNMjAwMTA3MDkz
+NDA5WhgPOTk5OTEyMzEyMzU5NTlaMB8xHTAbBgNVBAMTFEFub3RoZXIgdW5yZWxh
+dGVkIENBMIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAu9dHH1XtwAiv
+HTLSae930vP2hn7zl+I1ctQKhx51dr9ZKb7N5q1tfWJHGfvtJJR/K9YMaM/N7vNe
+stsRREt/MM7Sp3WnN4PAQdahhyJI+u/RFe3J0nOr4XyUTbKWgM9aXH6W9gL6pIux
+BbAn9dc4vSA37RLAIgeppl5HvR0zJ6LNTAxwum7ZE297oXLo9L7jhhuis6EHz5Po
+OiZRPq+82oCxklaLIecd2fkMqWi3BNhtH2+YkPv7NRhxPFBzsUWx5+57hF1XlTM3
+sA/rhY+NsH8QF4ADmRtiDB1yb+V3OMh1lmE2SyiuF6T5gZBNS4VhOb5sysCpzU5F
+J0eEgj1/xqcA15BkfKXp+PaS0nJUp5Vf/JMdyRp4bjoaH4+iQdIEXBkyVBbyl298
++STXpuIHz5+eZCeBX1p3ZU97soF4P6MiF9O6BnHVCWrChbo193EBtGPHcGKYWICi
+QCfA4tX9YOBaepy/e+Y0ePEW6CjZktzmLrbXGoNLhpLWgc6OUArVAgMBAAGjQzBB
+MA8GA1UdEwEB/wQFMAMBAf8wDwYDVR0PAQH/BAUDAwcEADAdBgNVHQ4EFgQUuWPP
+uOsgLMrSu5iN+p4AzFLBpLowDQYJKoZIhvcNAQELBQADggGBAEobHXRbd6wfUmyf
+P5v6qdJQMqtNGlU8eYzizEyuyovSlL+g9wgQ/91RAYK26FXzOuRz9Cg/ZWYVHqiG
+rRWWwcfzY7qHo3HGkpDSIjD53TAoK46ICD4+EreG+JBvy1P3Ij/VX7M07swIg8Ff
+6O4CnJpKAFaSr9wT8Ac3oCu+vymgLajMocNYV/UFVND+TLi6sx0zcMfCgW2vhSWk
+PRulxL76xq97vjWoveqDiFS41cPOAghd4hUmzRFByX6XPBx6YZddSUF+QZt92K4Z
+YEU4UbKqhbiBoZMGaQ8DzM2T44WPISrRZ0QpeS+pXwVjbDfoUbBWYAjFA8EHhPOi
+oewIIYnarItI3z3iccErOeKPPVQh5QW3/CwO4XSnvTEBkhf2EjG25UAHZ8LZy0t8
+Sw1raGJPYJV/qNVeIzLKd3tYmNpcmddYqS+ei2yBOoO5UPdbYaH1gTAZ4BbOhOml
+BJKJWcekpJrZAVTBNRectxsMXB8fHYL65Wa+w3cRqsZRjTbTEg==
+-----END CERTIFICATE-----
diff --git a/daemon/lua/trust_anchors.test/x509/wrongca.tmpl b/daemon/lua/trust_anchors.test/x509/wrongca.tmpl
new file mode 100644
index 0000000..0e8491b
--- /dev/null
+++ b/daemon/lua/trust_anchors.test/x509/wrongca.tmpl
@@ -0,0 +1,4 @@
+cn = Another unrelated CA
+ca
+cert_signing_key
+expiration_days = -1
diff --git a/daemon/lua/zonefile.lua b/daemon/lua/zonefile.lua
new file mode 100644
index 0000000..8ea3a08
--- /dev/null
+++ b/daemon/lua/zonefile.lua
@@ -0,0 +1,93 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+
+-- LuaJIT ffi bindings for zscanner, a DNS zone parser.
+-- Author: Marek Vavrusa <marek.vavrusa@nic.cz>
+
+local ffi = require('ffi')
+local libzscanner = ffi.load(libzscanner_SONAME)
+
+-- Wrap scanner context
+local zs_scanner_t = ffi.typeof('zs_scanner_t')
+ffi.metatype( zs_scanner_t, {
+ __gc = function(zs) return libzscanner.zs_deinit(zs) end,
+ __new = function(ct, origin, class, ttl)
+ if not class then class = 1 end
+ if not ttl then ttl = 3600 end
+ local parser = ffi.new(ct)
+ libzscanner.zs_init(parser, origin, class, ttl)
+ return parser
+ end,
+ __index = {
+ open = function (zs, file)
+ assert(ffi.istype(zs, zs_scanner_t))
+ local ret = libzscanner.zs_set_input_file(zs, file)
+ if ret ~= 0 then return false, zs:strerr() end
+ return true
+ end,
+ parse = function(zs, input)
+ assert(ffi.istype(zs, zs_scanner_t))
+ if input ~= nil then libzscanner.zs_set_input_string(zs, input, #input) end
+ local ret = libzscanner.zs_parse_record(zs)
+ -- Return current state only when parsed correctly, otherwise return error
+ if ret == 0 and zs.state ~= "ZS_STATE_ERROR" then
+ return zs.state == "ZS_STATE_DATA"
+ else
+ return false, zs:strerr()
+ end
+ end,
+ current_rr = function(zs)
+ assert(ffi.istype(zs, zs_scanner_t))
+ return {
+ owner = ffi.string(zs.r_owner, zs.r_owner_length),
+ ttl = tonumber(zs.r_ttl),
+ class = tonumber(zs.r_class),
+ type = tonumber(zs.r_type),
+ rdata = ffi.string(zs.r_data, zs.r_data_length),
+ comment = zs:current_comment(),
+ }
+ end,
+ strerr = function(zs)
+ assert(ffi.istype(zs, zs_scanner_t))
+ return ffi.string(libzscanner.zs_strerror(zs.error.code))
+ end,
+ current_comment = function(zs)
+ if zs.buffer_length > 0 then
+ return ffi.string(zs.buffer, zs.buffer_length - 1)
+ else
+ return nil
+ end
+ end
+ },
+})
+
+-- Module API
+local rrparser = {
+ new = zs_scanner_t,
+
+ -- Parse a file into a list of RRs
+ file = function (path)
+ local zs = zs_scanner_t()
+ local ok, err = zs:open(path)
+ if not ok then
+ return ok, err
+ end
+ local results = {}
+ while zs:parse() do
+ table.insert(results, zs:current_rr())
+ end
+ return results
+ end,
+
+ -- Parse a string into a list of RRs.
+ string = function (input)
+ local zs = zs_scanner_t()
+ local results = {}
+ local ok = zs:parse(input)
+ while ok do
+ table.insert(results, zs:current_rr())
+ ok = zs:parse()
+ end
+ return results
+ end,
+}
+return rrparser
diff --git a/daemon/main.c b/daemon/main.c
new file mode 100644
index 0000000..41a55ad
--- /dev/null
+++ b/daemon/main.c
@@ -0,0 +1,613 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#include "kresconfig.h"
+
+#include "contrib/ucw/mempool.h"
+#include "daemon/engine.h"
+#include "daemon/io.h"
+#include "daemon/network.h"
+#include "daemon/udp_queue.h"
+#include "daemon/worker.h"
+#include "lib/defines.h"
+#include "lib/dnssec.h"
+#include "lib/log.h"
+
+#include <arpa/inet.h>
+#include <getopt.h>
+#include <libgen.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/resource.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#if ENABLE_CAP_NG
+#include <cap-ng.h>
+#endif
+
+#include <lua.h>
+#include <uv.h>
+#if ENABLE_LIBSYSTEMD
+#include <systemd/sd-daemon.h>
+#endif
+#include <libknot/error.h>
+
+#if ENABLE_JEMALLOC
+/* Make the jemalloc library needed.
+ *
+ * The problem is with --as-needed for linker which is added by default by meson.
+ * If we don't use any jemalloc-specific calls, linker will decide that
+ * it is not needed and won't link it. Making it needed seems better than
+ * trying to override the flag which might be useful in some other cases, etc.
+ *
+ * Exporting the function is a very easy way of ensuring that it's not optimized out.
+ */
+#include <jemalloc/jemalloc.h>
+KR_EXPORT void kr_jemalloc_unused(void)
+{
+ malloc_stats_print(NULL, NULL, NULL);
+}
+/* We don't use threads (or rarely in some parts), so multiple arenas don't make sense.
+ https://jemalloc.net/jemalloc.3.html
+ */
+KR_EXPORT const char *malloc_conf = "narenas:1";
+#endif
+
+struct args the_args_value; /** Static allocation for the_args singleton. */
+
+static void signal_handler(uv_signal_t *handle, int signum)
+{
+ switch (signum) {
+ case SIGINT: /* Fallthrough. */
+ case SIGTERM:
+ uv_stop(uv_default_loop());
+ uv_signal_stop(handle);
+ break;
+ case SIGCHLD:
+ /* Wait for all dead processes. */
+ while (waitpid(-1, NULL, WNOHANG) > 0);
+ break;
+ default:
+ kr_log_error(SYSTEM, "unhandled signal: %d\n", signum);
+ break;
+ }
+}
+
+/** SIGBUS -> attempt to remove the overflowing cache file and abort. */
+static void sigbus_handler(int sig, siginfo_t *siginfo, void *ptr)
+{
+ /* We can't safely assume that printf-like functions work, but write() is OK.
+ * See POSIX for the safe functions, e.g. 2017 version just above this link:
+ * http://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_04_04
+ */
+ #define WRITE_ERR(err_charray) \
+ (void)write(STDERR_FILENO, err_charray, sizeof(err_charray))
+ /* Unfortunately, void-cast on the write isn't enough to avoid the warning. */
+ #pragma GCC diagnostic push
+ #pragma GCC diagnostic ignored "-Wunused-result"
+ const char msg_typical[] =
+ "\nSIGBUS received; this is most likely due to filling up the filesystem where cache resides.\n",
+ msg_unknown[] = "\nSIGBUS received, cause unknown.\n",
+ msg_deleted[] = "Cache file deleted.\n",
+ msg_del_fail[] = "Cache file deletion failed.\n",
+ msg_final[] = "kresd can not recover reliably by itself, exiting.\n";
+ if (siginfo->si_code != BUS_ADRERR) {
+ WRITE_ERR(msg_unknown);
+ goto end;
+ }
+ WRITE_ERR(msg_typical);
+ if (!kr_cache_emergency_file_to_remove) goto end;
+ if (unlink(kr_cache_emergency_file_to_remove)) {
+ WRITE_ERR(msg_del_fail);
+ } else {
+ WRITE_ERR(msg_deleted);
+ }
+end:
+ WRITE_ERR(msg_final);
+ _exit(128 - sig); /*< regular return from OS-raised SIGBUS can't work anyway */
+ #undef WRITE_ERR
+ #pragma GCC diagnostic pop
+}
+
+
+/*
+ * Server operation.
+ */
+
+static int fork_workers(int forks)
+{
+ /* Fork subprocesses if requested */
+ while (--forks > 0) {
+ int pid = fork();
+ if (pid < 0) {
+ perror("[system] fork");
+ return kr_error(errno);
+ }
+
+ /* Forked process */
+ if (pid == 0) {
+ return forks;
+ }
+ }
+ return 0;
+}
+
+static void help(int argc, char *argv[])
+{
+ printf("Usage: %s [parameters] [rundir]\n", argv[0]);
+ printf("\nParameters:\n"
+ " -a, --addr=[addr] Server address (default: localhost@53).\n"
+ " -t, --tls=[addr] Server address for TLS (default: off).\n"
+ " -S, --fd=[fd:kind] Listen on given fd (handed out by supervisor, :kind is optional).\n"
+ " -c, --config=[path] Config file path (relative to [rundir]) (default: config).\n"
+ " -n, --noninteractive Don't start the read-eval-print loop for stdin+stdout.\n"
+ " -q, --quiet No command prompt in interactive mode.\n"
+ " -v, --verbose Increase logging to debug level.\n"
+ " -V, --version Print version of the server.\n"
+ " -h, --help Print help and usage.\n"
+ "Options:\n"
+ " [rundir] Path to the working directory (default: .)\n");
+}
+
+/** \return exit code for main() */
+static int run_worker(uv_loop_t *loop, struct engine *engine, bool leader, struct args *args)
+{
+ /* Only some kinds of stdin work with uv_pipe_t.
+ * Otherwise we would abort() from libuv e.g. with </dev/null */
+ if (args->interactive) switch (uv_guess_handle(0)) {
+ case UV_TTY: /* standard terminal */
+ /* TODO: it has worked OK so far, but we'd better use uv_tty_*
+ * for this case instead of uv_pipe_*. */
+ case UV_NAMED_PIPE: /* echo 'quit()' | kresd ... */
+ break;
+ default:
+ kr_log_error(SYSTEM,
+ "error: standard input is not a terminal or pipe; "
+ "use '-n' if you want non-interactive mode. "
+ "Commands can be simply added to your configuration file or sent over the control socket.\n"
+ );
+ return EXIT_FAILURE;
+ }
+
+ /* Control sockets or TTY */
+ uv_pipe_t *pipe = malloc(sizeof(*pipe));
+ if (!pipe)
+ return EXIT_FAILURE;
+ uv_pipe_init(loop, pipe, 0);
+ if (args->interactive) {
+ if (!args->quiet)
+ printf("Interactive mode:\n" "> ");
+ pipe->data = io_tty_alloc_data();
+ uv_pipe_open(pipe, 0);
+ uv_read_start((uv_stream_t*)pipe, io_tty_alloc, io_tty_process_input);
+ } else if (args->control_fd != -1 && uv_pipe_open(pipe, args->control_fd) == 0) {
+ uv_listen((uv_stream_t *)pipe, 16, io_tty_accept);
+ }
+
+ /* Notify supervisor. */
+#if ENABLE_LIBSYSTEMD
+ sd_notify(0, "READY=1");
+#endif
+ /* Run event loop */
+ uv_run(loop, UV_RUN_DEFAULT);
+ /* Free pipe's data. Seems OK even on the stopped loop.
+ * In interactive case it may have been done in callbacks already (single leak). */
+ if (!args->interactive) {
+ uv_close((uv_handle_t *)pipe, NULL);
+ free(pipe);
+ }
+ return EXIT_SUCCESS;
+}
+
+static void args_init(struct args *args)
+{
+ memset(args, 0, sizeof(struct args));
+ /* Zeroed arrays are OK. */
+ args->forks = 1;
+ args->control_fd = -1;
+ args->interactive = true;
+ args->quiet = false;
+}
+
+/* Free pointed-to resources. */
+static void args_deinit(struct args *args)
+{
+ array_clear(args->addrs);
+ array_clear(args->addrs_tls);
+ for (int i = 0; i < args->fds.len; ++i)
+ free_const(args->fds.at[i].flags.kind);
+ array_clear(args->fds);
+ array_clear(args->config);
+}
+
+/** Process arguments into struct args.
+ * @return >=0 if main() should be exited immediately.
+ */
+static int parse_args(int argc, char **argv, struct args *args)
+{
+ /* Long options. */
+ int c = 0, li = 0;
+ struct option opts[] = {
+ {"addr", required_argument, 0, 'a'},
+ {"tls", required_argument, 0, 't'},
+ {"config", required_argument, 0, 'c'},
+ {"forks", required_argument, 0, 'f'},
+ {"noninteractive", no_argument, 0, 'n'},
+ {"verbose", no_argument, 0, 'v'},
+ {"quiet", no_argument, 0, 'q'},
+ {"version", no_argument, 0, 'V'},
+ {"help", no_argument, 0, 'h'},
+ {"fd", required_argument, 0, 'S'},
+ {0, 0, 0, 0}
+ };
+ while ((c = getopt_long(argc, argv, "a:t:c:f:nvqVhS:", opts, &li)) != -1) {
+ switch (c)
+ {
+ case 'a':
+ kr_require(optarg);
+ array_push(args->addrs, optarg);
+ break;
+ case 't':
+ kr_require(optarg);
+ array_push(args->addrs_tls, optarg);
+ break;
+ case 'c':
+ kr_require(optarg);
+ array_push(args->config, optarg);
+ break;
+ case 'f':
+ kr_require(optarg);
+ args->forks = strtol(optarg, NULL, 10);
+ if (args->forks == 1) {
+ kr_log_deprecate(SYSTEM, "use --noninteractive instead of --forks=1\n");
+ } else {
+ kr_log_deprecate(SYSTEM, "support for running multiple --forks will be removed\n");
+ }
+ if (args->forks <= 0) {
+ kr_log_error(SYSTEM, "error '-f' requires a positive"
+ " number, not '%s'\n", optarg);
+ return EXIT_FAILURE;
+ }
+ /* fall through */
+ case 'n':
+ args->interactive = false;
+ break;
+ case 'v':
+ kr_log_level_set(LOG_DEBUG);
+ break;
+ case 'q':
+ args->quiet = true;
+ break;
+ case 'V':
+ printf("Knot Resolver, version %s\n", PACKAGE_VERSION);
+ return EXIT_SUCCESS;
+ case 'h':
+ case '?':
+ help(argc, argv);
+ return EXIT_SUCCESS;
+ default:
+ help(argc, argv);
+ return EXIT_FAILURE;
+ case 'S':
+ kr_require(optarg);
+ flagged_fd_t ffd = { 0 };
+ char *endptr;
+ ffd.fd = strtol(optarg, &endptr, 10);
+ if (endptr != optarg && endptr[0] == '\0') {
+ /* Plain DNS */
+ ffd.flags.tls = false;
+ } else if (endptr[0] == ':' && strcasecmp(endptr + 1, "tls") == 0) {
+ /* DoT */
+ ffd.flags.tls = true;
+ /* We know what .sock_type should be but it wouldn't help. */
+ } else if (endptr[0] == ':' && endptr[1] != '\0') {
+ /* Some other kind; no checks here. */
+ ffd.flags.kind = strdup(endptr + 1);
+ } else {
+ kr_log_error(SYSTEM, "incorrect value passed to '-S/--fd': %s\n",
+ optarg);
+ return EXIT_FAILURE;
+ }
+ array_push(args->fds, ffd);
+ break;
+ }
+ }
+ if (optind < argc) {
+ args->rundir = argv[optind];
+ }
+ return -1;
+}
+
+/** Just convert addresses to file-descriptors; clear *addrs on success.
+ * @note AF_UNIX is supported (starting with '/').
+ * @return zero or exit code for main()
+ */
+static int bind_sockets(addr_array_t *addrs, bool tls, flagged_fd_array_t *fds)
+{
+ bool has_error = false;
+ for (size_t i = 0; i < addrs->len; ++i) {
+ /* Get port and separate address string. */
+ uint16_t port = tls ? KR_DNS_TLS_PORT : KR_DNS_PORT;
+ char addr_buf[INET6_ADDRSTRLEN + 1];
+ int ret;
+ const char *addr_str;
+ const int family = kr_straddr_family(addrs->at[i]);
+ if (family == AF_UNIX) {
+ ret = 0;
+ addr_str = addrs->at[i];
+ } else { /* internet socket (or garbage) */
+ ret = kr_straddr_split(addrs->at[i], addr_buf, &port);
+ addr_str = addr_buf;
+ }
+ /* Get sockaddr. */
+ struct sockaddr *sa = NULL;
+ if (ret == 0) {
+ sa = kr_straddr_socket(addr_str, port, NULL);
+ if (!sa) ret = kr_error(EINVAL); /* could be ENOMEM but unlikely */
+ }
+ flagged_fd_t ffd = { .flags = { .tls = tls } };
+ if (ret == 0 && !tls && family != AF_UNIX) {
+ /* AF_UNIX can do SOCK_DGRAM, but let's not support that *here*. */
+ ffd.fd = io_bind(sa, SOCK_DGRAM, NULL);
+ if (ffd.fd < 0)
+ ret = ffd.fd;
+ else if (array_push(*fds, ffd) < 0)
+ ret = kr_error(ENOMEM);
+ }
+ if (ret == 0) { /* common for TCP and TLS, including AF_UNIX cases */
+ ffd.fd = io_bind(sa, SOCK_STREAM, NULL);
+ if (ffd.fd < 0)
+ ret = ffd.fd;
+ else if (array_push(*fds, ffd) < 0)
+ ret = kr_error(ENOMEM);
+ }
+ free(sa);
+ if (ret != 0) {
+ kr_log_error(NETWORK, "bind to '%s'%s: %s\n",
+ addrs->at[i], tls ? " (TLS)" : "", kr_strerror(ret));
+ has_error = true;
+ }
+ }
+ array_clear(*addrs);
+ return has_error ? EXIT_FAILURE : kr_ok();
+}
+
+static int start_listening(struct network *net, flagged_fd_array_t *fds) {
+ int some_bad_ret = 0;
+ for (size_t i = 0; i < fds->len; ++i) {
+ flagged_fd_t *ffd = &fds->at[i];
+ int ret = network_listen_fd(net, ffd->fd, ffd->flags);
+ if (ret != 0) {
+ some_bad_ret = ret;
+ /* TODO: try logging address@port. It's not too important,
+ * because typical problems happen during binding already.
+ * (invalid address, permission denied) */
+ kr_log_error(NETWORK, "listen on fd=%d: %s\n",
+ ffd->fd, kr_strerror(ret));
+ /* Continue printing all of these before exiting. */
+ } else {
+ ffd->flags.kind = NULL; /* ownership transferred */
+ }
+ }
+ return some_bad_ret;
+}
+
+/* Drop POSIX 1003.1e capabilities. */
+static void drop_capabilities(void)
+{
+#if ENABLE_CAP_NG
+ /* Drop all capabilities when running under non-root user. */
+ if (geteuid() == 0) {
+ kr_log_debug(SYSTEM, "running as root, no capabilities dropped\n");
+ return;
+ }
+ if (capng_have_capability(CAPNG_EFFECTIVE, CAP_SETPCAP)) {
+ capng_clear(CAPNG_SELECT_BOTH);
+
+ /* Apply. */
+ if (capng_apply(CAPNG_SELECT_BOTH) < 0) {
+ kr_log_error(SYSTEM, "failed to set process capabilities: %s\n",
+ strerror(errno));
+ } else {
+ kr_log_debug(SYSTEM, "all capabilities dropped\n");
+ }
+ } else {
+ /* If user() was called, the capabilities were already dropped along with SETPCAP. */
+ kr_log_debug(SYSTEM, "process not allowed to set capabilities, skipping\n");
+ }
+#endif /* ENABLE_CAP_NG */
+}
+
+int main(int argc, char **argv)
+{
+ kr_log_group_reset();
+ if (setvbuf(stdout, NULL, _IONBF, 0) || setvbuf(stderr, NULL, _IONBF, 0)) {
+ kr_log_error(SYSTEM, "failed to to set output buffering (ignored): %s\n",
+ strerror(errno));
+ fflush(stderr);
+ }
+ if (strcmp("linux", OPERATING_SYSTEM) != 0)
+ kr_log_warning(SYSTEM, "Knot Resolver is tested on Linux, other platforms might exhibit bugs.\n"
+ "Please report issues to https://gitlab.nic.cz/knot/knot-resolver/issues/\n"
+ "Thank you for your time and interest!\n");
+
+ the_args = &the_args_value;
+ args_init(the_args);
+ int ret = parse_args(argc, argv, the_args);
+ if (ret >= 0) goto cleanup_args;
+
+ ret = bind_sockets(&the_args->addrs, false, &the_args->fds);
+ if (ret) goto cleanup_args;
+ ret = bind_sockets(&the_args->addrs_tls, true, &the_args->fds);
+ if (ret) goto cleanup_args;
+
+ /* Switch to rundir. */
+ if (the_args->rundir != NULL) {
+ /* FIXME: access isn't a good way if we start as root and drop privileges later */
+ if (access(the_args->rundir, W_OK) != 0
+ || chdir(the_args->rundir) != 0) {
+ kr_log_error(SYSTEM, "rundir '%s': %s\n",
+ the_args->rundir, strerror(errno));
+ return EXIT_FAILURE;
+ }
+ }
+
+ /* Select which config files to load and verify they are read-able. */
+ bool load_defaults = true;
+ size_t i = 0;
+ while (i < the_args->config.len) {
+ const char *config = the_args->config.at[i];
+ if (strcmp(config, "-") == 0) {
+ load_defaults = false;
+ array_del(the_args->config, i);
+ continue; /* don't increment i */
+ } else if (access(config, R_OK) != 0) {
+ char cwd[PATH_MAX];
+ get_workdir(cwd, sizeof(cwd));
+ kr_log_error(SYSTEM, "config '%s' (workdir '%s'): %s\n",
+ config, cwd, strerror(errno));
+ return EXIT_FAILURE;
+ }
+ i++;
+ }
+ if (the_args->config.len == 0 && access("config", R_OK) == 0)
+ array_push(the_args->config, "config");
+ if (load_defaults)
+ array_push(the_args->config, LIBDIR "/postconfig.lua");
+
+ /* File-descriptor count limit: soft->hard. */
+ struct rlimit rlim;
+ ret = getrlimit(RLIMIT_NOFILE, &rlim);
+ if (ret == 0 && rlim.rlim_cur != rlim.rlim_max) {
+ kr_log_debug(SYSTEM, "increasing file-descriptor limit: %ld -> %ld\n",
+ (long)rlim.rlim_cur, (long)rlim.rlim_max);
+ rlim.rlim_cur = rlim.rlim_max;
+ ret = setrlimit(RLIMIT_NOFILE, &rlim);
+ }
+ if (ret) {
+ kr_log_error(SYSTEM, "failed to get or set file-descriptor limit: %s\n",
+ strerror(errno));
+ } else if (rlim.rlim_cur < 512*1024) {
+ kr_log_warning(SYSTEM, "warning: hard limit for number of file-descriptors is only %ld but recommended value is 524288\n",
+ (long)rlim.rlim_cur);
+ }
+
+ /* Fork subprocesses if requested */
+ int fork_id = fork_workers(the_args->forks);
+ if (fork_id < 0) {
+ return EXIT_FAILURE;
+ }
+
+ kr_crypto_init();
+
+ /* Create a server engine. */
+ knot_mm_t pool;
+ mm_ctx_mempool(&pool, MM_DEFAULT_BLKSIZE);
+ static struct engine engine;
+ ret = engine_init(&engine, &pool);
+ if (ret != 0) {
+ kr_log_error(SYSTEM, "failed to initialize engine: %s\n", kr_strerror(ret));
+ return EXIT_FAILURE;
+ }
+ /* Initialize the worker */
+ ret = worker_init(&engine, the_args->forks);
+ if (ret != 0) {
+ kr_log_error(SYSTEM, "failed to initialize worker: %s\n", kr_strerror(ret));
+ return EXIT_FAILURE;
+ }
+
+ uv_loop_t *loop = uv_default_loop();
+ /* Catch some signals. */
+ uv_signal_t sigint, sigterm, sigchld;
+ if (true) ret = uv_signal_init(loop, &sigint);
+ if (!ret) ret = uv_signal_init(loop, &sigterm);
+ if (!ret) ret = uv_signal_init(loop, &sigchld);
+ if (!ret) ret = uv_signal_start(&sigint, signal_handler, SIGINT);
+ if (!ret) ret = uv_signal_start(&sigterm, signal_handler, SIGTERM);
+ if (!ret) ret = uv_signal_start(&sigchld, signal_handler, SIGCHLD);
+ /* Block SIGPIPE; see https://github.com/libuv/libuv/issues/45 */
+ if (!ret && signal(SIGPIPE, SIG_IGN) == SIG_ERR) ret = errno;
+ if (!ret) {
+ /* Catching SIGBUS via uv_signal_* can't work; see:
+ * https://github.com/libuv/libuv/pull/1987 */
+ struct sigaction sa;
+ memset(&sa, 0, sizeof(sa));
+ sa.sa_sigaction = sigbus_handler;
+ sa.sa_flags = SA_SIGINFO;
+ if (sigaction(SIGBUS, &sa, NULL)) {
+ ret = errno;
+ }
+ }
+ if (ret) {
+ kr_log_error(SYSTEM, "failed to set up signal handlers: %s\n",
+ strerror(abs(errno)));
+ ret = EXIT_FAILURE;
+ goto cleanup;
+ }
+ /* Profiling: avoid SIGPROF waking up the event loop. Otherwise the profiles
+ * (of the usual type) may skew results, e.g. epoll_pwait() taking lots of time. */
+ ret = uv_loop_configure(loop, UV_LOOP_BLOCK_SIGNAL, SIGPROF);
+ if (ret) {
+ kr_log_info(SYSTEM, "failed to block SIGPROF in event loop, ignoring: %s\n",
+ uv_strerror(ret));
+ }
+
+ /* Start listening, in the sense of network_listen_fd(). */
+ if (start_listening(&engine.net, &the_args->fds) != 0) {
+ ret = EXIT_FAILURE;
+ goto cleanup;
+ }
+
+ ret = udp_queue_init_global(loop);
+ if (ret) {
+ kr_log_error(SYSTEM, "failed to initialize UDP queue: %s\n",
+ kr_strerror(ret));
+ ret = EXIT_FAILURE;
+ goto cleanup;
+ }
+
+ /* Start the scripting engine */
+ if (engine_load_sandbox(&engine) != 0) {
+ ret = EXIT_FAILURE;
+ goto cleanup;
+ }
+
+ for (i = 0; i < the_args->config.len; ++i) {
+ const char *config = the_args->config.at[i];
+ if (engine_loadconf(&engine, config) != 0) {
+ ret = EXIT_FAILURE;
+ goto cleanup;
+ }
+ lua_settop(engine.L, 0);
+ }
+
+ drop_capabilities();
+
+ if (engine_start(&engine) != 0) {
+ ret = EXIT_FAILURE;
+ goto cleanup;
+ }
+
+ if (network_engage_endpoints(&engine.net)) {
+ ret = EXIT_FAILURE;
+ goto cleanup;
+ }
+
+ /* Run the event loop */
+ ret = run_worker(loop, &engine, fork_id == 0, the_args);
+
+cleanup:/* Cleanup. */
+ engine_deinit(&engine);
+ worker_deinit();
+ if (loop != NULL) {
+ uv_loop_close(loop);
+ }
+ mp_delete(pool.ctx);
+cleanup_args:
+ args_deinit(the_args);
+ kr_crypto_cleanup();
+ return ret;
+}
diff --git a/daemon/meson.build b/daemon/meson.build
new file mode 100644
index 0000000..68a2646
--- /dev/null
+++ b/daemon/meson.build
@@ -0,0 +1,68 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+# daemon
+
+kresd_src = files([
+ 'bindings/cache.c',
+ 'bindings/event.c',
+ 'bindings/impl.c',
+ 'bindings/modules.c',
+ 'bindings/net.c',
+ 'bindings/worker.c',
+ 'engine.c',
+ 'ffimodule.c',
+ 'io.c',
+ 'main.c',
+ 'network.c',
+ 'proxyv2.c',
+ 'session.c',
+ 'tls.c',
+ 'tls_ephemeral_credentials.c',
+ 'tls_session_ticket-srv.c',
+ 'udp_queue.c',
+ 'worker.c',
+ 'zimport.c',
+])
+if nghttp2.found()
+ kresd_src += files(['http.c'])
+endif
+
+c_src_lint += kresd_src
+
+config_tests += [
+ ['cache.clear', files('cache.test/clear.test.lua')],
+ ['zimport', files('zimport.test/zimport.test.lua')],
+]
+
+integr_tests += [
+ ['cache_insert_ns', meson.current_source_dir() / 'cache.test' / 'insert_ns.test.integr'],
+ ['proxyv2', meson.current_source_dir() / 'proxyv2.test']
+]
+
+kresd_deps = [
+ contrib_dep,
+ kresconfig_dep,
+ libkres_dep,
+ libknot,
+ libzscanner,
+ libdnssec,
+ libuv,
+ luajit,
+ gnutls,
+ libsystemd,
+ capng,
+ nghttp2,
+ malloc,
+]
+
+
+subdir('lua')
+
+
+kresd = executable(
+ 'kresd',
+ kresd_src,
+ dependencies: kresd_deps,
+ export_dynamic: true,
+ install: true,
+ install_dir: get_option('sbindir'),
+)
diff --git a/daemon/network.c b/daemon/network.c
new file mode 100644
index 0000000..a20b1e4
--- /dev/null
+++ b/daemon/network.c
@@ -0,0 +1,928 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#include "daemon/network.h"
+
+#include "contrib/cleanup.h"
+#include "daemon/bindings/impl.h"
+#include "daemon/io.h"
+#include "daemon/tls.h"
+#include "daemon/worker.h"
+#include "lib/utils.h"
+
+#if ENABLE_XDP
+ #include <libknot/xdp/eth.h>
+#endif
+
+#include <libgen.h>
+#include <net/if.h>
+#include <sys/un.h>
+#include <unistd.h>
+
+/** Determines the type of `struct endpoint_key`. */
+enum endpoint_key_type
+{
+ ENDPOINT_KEY_SOCKADDR = 1,
+ ENDPOINT_KEY_IFNAME = 2,
+};
+
+/** Used as a key in the `struct network::endpoints` trie. */
+struct endpoint_key {
+ enum endpoint_key_type type;
+ char data[];
+};
+
+struct __attribute__((packed)) endpoint_key_sockaddr {
+ enum endpoint_key_type type;
+ struct kr_sockaddr_key_storage sa_key;
+};
+
+struct __attribute__((packed)) endpoint_key_ifname {
+ enum endpoint_key_type type;
+ char ifname[128];
+};
+
+/** Used for reserving enough storage for `endpoint_key`. */
+struct endpoint_key_storage {
+ union {
+ enum endpoint_key_type type;
+ struct endpoint_key_sockaddr sa;
+ struct endpoint_key_ifname ifname;
+ char bytes[1]; /* for easier casting */
+ };
+};
+
+static_assert(_Alignof(struct endpoint_key) <= 4, "endpoint_key must be aligned to <=4");
+static_assert(_Alignof(struct endpoint_key_sockaddr) <= 4, "endpoint_key must be aligned to <=4");
+static_assert(_Alignof(struct endpoint_key_ifname) <= 4, "endpoint_key must be aligned to <=4");
+
+void network_init(struct network *net, uv_loop_t *loop, int tcp_backlog)
+{
+ if (net != NULL) {
+ net->loop = loop;
+ net->endpoints = trie_create(NULL);
+ net->endpoint_kinds = trie_create(NULL);
+ net->proxy_all4 = false;
+ net->proxy_all6 = false;
+ net->proxy_addrs4 = trie_create(NULL);
+ net->proxy_addrs6 = trie_create(NULL);
+ net->tls_client_params = NULL;
+ net->tls_session_ticket_ctx = /* unsync. random, by default */
+ tls_session_ticket_ctx_create(loop, NULL, 0);
+ net->tcp.in_idle_timeout = 10000;
+ net->tcp.tls_handshake_timeout = TLS_MAX_HANDSHAKE_TIME;
+ net->tcp_backlog = tcp_backlog;
+ }
+}
+
+/** Notify the registered function about endpoint getting open.
+ * If log_port < 1, don't log it. */
+static int endpoint_open_lua_cb(struct network *net, struct endpoint *ep,
+ const char *log_addr)
+{
+ const bool ok = ep->flags.kind && !ep->handle && !ep->engaged && ep->fd != -1;
+ if (kr_fails_assert(ok))
+ return kr_error(EINVAL);
+ /* First find callback in the endpoint registry. */
+ lua_State *L = the_worker->engine->L;
+ void **pp = trie_get_try(net->endpoint_kinds, ep->flags.kind,
+ strlen(ep->flags.kind));
+ if (!pp && net->missing_kind_is_error) {
+ kr_log_error(NETWORK, "error: network socket kind '%s' not handled when opening '%s",
+ ep->flags.kind, log_addr);
+ if (ep->family != AF_UNIX)
+ kr_log_error(NETWORK, "#%d", ep->port);
+ kr_log_error(NETWORK, "'\n");
+ return kr_error(ENOENT);
+ }
+ if (!pp) return kr_ok();
+
+ /* Now execute the callback. */
+ const int fun_id = (char *)*pp - (char *)NULL;
+ lua_rawgeti(L, LUA_REGISTRYINDEX, fun_id);
+ lua_pushboolean(L, true /* open */);
+ lua_pushpointer(L, ep);
+ if (ep->family == AF_UNIX) {
+ lua_pushstring(L, log_addr);
+ } else {
+ lua_pushfstring(L, "%s#%d", log_addr, ep->port);
+ }
+ if (lua_pcall(L, 3, 0, 0)) {
+ kr_log_error(NETWORK, "error opening %s: %s\n", log_addr, lua_tostring(L, -1));
+ return kr_error(ENOSYS); /* TODO: better value? */
+ }
+ ep->engaged = true;
+ return kr_ok();
+}
+
+static int engage_endpoint_array(const char *b_key, uint32_t key_len, trie_val_t *val, void *net)
+{
+ const char *log_addr = network_endpoint_key_str((struct endpoint_key *) b_key);
+ if (!log_addr)
+ log_addr = "[unknown]";
+
+ endpoint_array_t *eps = *val;
+ for (int i = 0; i < eps->len; ++i) {
+ struct endpoint *ep = &eps->at[i];
+ const bool match = !ep->engaged && ep->flags.kind;
+ if (!match) continue;
+ int ret = endpoint_open_lua_cb(net, ep, log_addr);
+ if (ret) return ret;
+ }
+ return 0;
+}
+
+int network_engage_endpoints(struct network *net)
+{
+ if (net->missing_kind_is_error)
+ return kr_ok(); /* maybe weird, but let's make it idempotent */
+ net->missing_kind_is_error = true;
+ int ret = trie_apply_with_key(net->endpoints, engage_endpoint_array, net);
+ if (ret) {
+ net->missing_kind_is_error = false; /* avoid the same errors when closing */
+ return ret;
+ }
+ return kr_ok();
+}
+
+const char *network_endpoint_key_str(const struct endpoint_key *key)
+{
+ switch (key->type)
+ {
+ case ENDPOINT_KEY_SOCKADDR:;
+ const struct endpoint_key_sockaddr *sa_key =
+ (struct endpoint_key_sockaddr *) key;
+ struct sockaddr_storage sa_storage;
+ struct sockaddr *sa = kr_sockaddr_from_key(&sa_storage, (const char *) &sa_key->sa_key);
+ return kr_straddr(sa);
+ case ENDPOINT_KEY_IFNAME:;
+ const struct endpoint_key_ifname *if_key =
+ (struct endpoint_key_ifname *) key;
+ return if_key->ifname;
+ default:
+ kr_assert(false);
+ return NULL;
+ }
+}
+
+/** Notify the registered function about endpoint about to be closed. */
+static void endpoint_close_lua_cb(struct network *net, struct endpoint *ep)
+{
+ lua_State *L = the_worker->engine->L;
+ void **pp = trie_get_try(net->endpoint_kinds, ep->flags.kind,
+ strlen(ep->flags.kind));
+ if (!pp && net->missing_kind_is_error) {
+ kr_log_error(NETWORK, "internal error: missing kind '%s' in endpoint registry\n",
+ ep->flags.kind);
+ return;
+ }
+ if (!pp) return;
+
+ const int fun_id = (char *)*pp - (char *)NULL;
+ lua_rawgeti(L, LUA_REGISTRYINDEX, fun_id);
+ lua_pushboolean(L, false /* close */);
+ lua_pushpointer(L, ep);
+ lua_pushstring(L, "FIXME:endpoint-identifier");
+ if (lua_pcall(L, 3, 0, 0)) {
+ kr_log_error(NETWORK, "failed to close FIXME:endpoint-identifier: %s\n",
+ lua_tostring(L, -1));
+ }
+}
+
+static void endpoint_close(struct network *net, struct endpoint *ep, bool force)
+{
+ const bool is_control = ep->flags.kind && strcmp(ep->flags.kind, "control") == 0;
+ const bool is_xdp = ep->family == AF_XDP;
+
+ if (ep->family == AF_UNIX) { /* The FS name would be left behind. */
+ /* Extract local address for this socket. */
+ struct sockaddr_un sa;
+ sa.sun_path[0] = '\0'; /*< probably only for lint:scan-build */
+ socklen_t addr_len = sizeof(sa);
+ if (getsockname(ep->fd, (struct sockaddr *)&sa, &addr_len)
+ || unlink(sa.sun_path)) {
+ kr_log_error(NETWORK, "error (ignored) when closing unix socket (fd = %d): %s\n",
+ ep->fd, strerror(errno));
+ return;
+ }
+ }
+
+ if (ep->flags.kind && !is_control && !is_xdp) {
+ kr_assert(!ep->handle);
+ /* Special lua-handled endpoint. */
+ if (ep->engaged) {
+ endpoint_close_lua_cb(net, ep);
+ }
+ if (ep->fd > 0) {
+ close(ep->fd); /* nothing to do with errors */
+ }
+ free_const(ep->flags.kind);
+ return;
+ }
+
+ free_const(ep->flags.kind); /* needed if (is_control) */
+ kr_require(ep->handle);
+ if (force) { /* Force close if event loop isn't running. */
+ if (ep->fd >= 0) {
+ close(ep->fd);
+ }
+ if (ep->handle) {
+ ep->handle->loop = NULL;
+ io_free(ep->handle);
+ }
+ } else { /* Asynchronous close */
+ uv_close(ep->handle, io_free);
+ }
+}
+
+/** Endpoint visitor (see @file trie.h) */
+static int close_key(trie_val_t *val, void* net)
+{
+ endpoint_array_t *ep_array = *val;
+ for (int i = 0; i < ep_array->len; ++i) {
+ endpoint_close(net, &ep_array->at[i], true);
+ }
+ return 0;
+}
+
+static int free_key(trie_val_t *val, void* ext)
+{
+ endpoint_array_t *ep_array = *val;
+ array_clear(*ep_array);
+ free(ep_array);
+ return kr_ok();
+}
+
+int kind_unregister(trie_val_t *tv, void *L)
+{
+ int fun_id = (char *)*tv - (char *)NULL;
+ luaL_unref(L, LUA_REGISTRYINDEX, fun_id);
+ return 0;
+}
+
+void network_close_force(struct network *net)
+{
+ if (net != NULL) {
+ trie_apply(net->endpoints, close_key, net);
+ trie_apply(net->endpoints, free_key, NULL);
+ trie_clear(net->endpoints);
+ }
+}
+
+/** Frees all the `struct net_proxy_data` in the specified trie. */
+void network_proxy_free_addr_data(trie_t* trie)
+{
+ trie_it_t *it;
+ for (it = trie_it_begin(trie); !trie_it_finished(it); trie_it_next(it)) {
+ struct net_proxy_data *data = *trie_it_val(it);
+ free(data);
+ }
+ trie_it_free(it);
+}
+
+void network_deinit(struct network *net)
+{
+ if (net != NULL) {
+ network_close_force(net);
+ trie_apply(net->endpoint_kinds, kind_unregister, the_worker->engine->L);
+ trie_free(net->endpoint_kinds);
+ trie_free(net->endpoints);
+ network_proxy_free_addr_data(net->proxy_addrs4);
+ trie_free(net->proxy_addrs4);
+ network_proxy_free_addr_data(net->proxy_addrs6);
+ trie_free(net->proxy_addrs6);
+
+ tls_credentials_free(net->tls_credentials);
+ tls_client_params_free(net->tls_client_params);
+ tls_session_ticket_ctx_destroy(net->tls_session_ticket_ctx);
+ #ifndef NDEBUG
+ memset(net, 0, sizeof(*net));
+ #endif
+ }
+}
+
+/** Creates an endpoint key for use with a `trie_t` and stores it into `dst`.
+ * Returns the actual length of the generated key. */
+static ssize_t endpoint_key_create(struct endpoint_key_storage *dst,
+ const char *addr_str,
+ const struct sockaddr *sa)
+{
+ memset(dst, 0, sizeof(*dst));
+ if (sa) {
+ struct endpoint_key_sockaddr *key = &dst->sa;
+ key->type = ENDPOINT_KEY_SOCKADDR;
+ ssize_t keylen = kr_sockaddr_key(&key->sa_key, sa);
+ if (keylen < 0)
+ return keylen;
+ return sizeof(struct endpoint_key) + keylen;
+ } else {
+ struct endpoint_key_ifname *key = &dst->ifname;
+ key->type = ENDPOINT_KEY_IFNAME;
+
+ /* The subtractions and additions of 1 are here to account for
+ * null-terminators. */
+ strncpy(key->ifname, addr_str, sizeof(key->ifname) - 1);
+ return sizeof(struct endpoint_key) + strlen(key->ifname) + 1;
+ }
+}
+
+/** Fetch or create endpoint array and insert endpoint (shallow memcpy). */
+static int insert_endpoint(struct network *net, const char *addr_str,
+ const struct sockaddr *addr, struct endpoint *ep)
+{
+ /* Fetch or insert address into map */
+ struct endpoint_key_storage key;
+ ssize_t keylen = endpoint_key_create(&key, addr_str, addr);
+ if (keylen < 0)
+ return keylen;
+ trie_val_t *val = trie_get_ins(net->endpoints, key.bytes, keylen);
+ endpoint_array_t *ep_array;
+ if (*val) {
+ ep_array = *val;
+ } else {
+ ep_array = malloc(sizeof(*ep_array));
+ kr_require(ep_array);
+ array_init(*ep_array);
+ *val = ep_array;
+ }
+
+ if (array_reserve(*ep_array, ep_array->len + 1)) {
+ return kr_error(ENOMEM);
+ }
+ memcpy(&ep_array->at[ep_array->len++], ep, sizeof(*ep));
+ return kr_ok();
+}
+
+/** Open endpoint protocols. ep->flags were pre-set.
+ * \p addr_str is only used for logging or for XDP "address". */
+static int open_endpoint(struct network *net, const char *addr_str,
+ struct endpoint *ep, const struct sockaddr *sa)
+{
+ const bool is_control = ep->flags.kind && strcmp(ep->flags.kind, "control") == 0;
+ const bool is_xdp = ep->family == AF_XDP;
+ bool ok = (!is_xdp)
+ || (sa == NULL && ep->fd == -1 && ep->nic_queue >= 0
+ && ep->flags.sock_type == SOCK_DGRAM && !ep->flags.tls);
+ if (kr_fails_assert(ok))
+ return kr_error(EINVAL);
+ if (ep->handle) {
+ return kr_error(EEXIST);
+ }
+
+ if (sa && ep->fd == -1) {
+ if (sa->sa_family == AF_UNIX) {
+ struct sockaddr_un *sun = (struct sockaddr_un*)sa;
+ char *dirc = strdup(sun->sun_path);
+ char *dname = dirname(dirc);
+ (void)unlink(sun->sun_path); /** Attempt to unlink if socket path exists. */
+ (void)mkdir(dname, S_IRWXU|S_IRWXG); /** Attempt to create dir. */
+ free(dirc);
+ }
+ ep->fd = io_bind(sa, ep->flags.sock_type, &ep->flags);
+ if (ep->fd < 0) return ep->fd;
+ }
+ if (ep->flags.kind && !is_control && !is_xdp) {
+ /* This EP isn't to be managed internally after binding. */
+ return endpoint_open_lua_cb(net, ep, addr_str);
+ } else {
+ ep->engaged = true;
+ /* .engaged seems not really meaningful in this case, but... */
+ }
+
+ int ret;
+ if (is_control) {
+ uv_pipe_t *ep_handle = malloc(sizeof(uv_pipe_t));
+ ep->handle = (uv_handle_t *)ep_handle;
+ ret = !ep->handle ? ENOMEM
+ : io_listen_pipe(net->loop, ep_handle, ep->fd);
+ goto finish_ret;
+ }
+
+ if (ep->family == AF_UNIX) {
+ /* Some parts of connection handling would need more work,
+ * so let's support AF_UNIX only with .kind != NULL for now. */
+ kr_log_error(NETWORK, "AF_UNIX only supported with set { kind = '...' }\n");
+ ret = EAFNOSUPPORT;
+ goto finish_ret;
+ /*
+ uv_pipe_t *ep_handle = malloc(sizeof(uv_pipe_t));
+ */
+ }
+
+ if (is_xdp) {
+ #if ENABLE_XDP
+ uv_poll_t *ep_handle = malloc(sizeof(uv_poll_t));
+ ep->handle = (uv_handle_t *)ep_handle;
+ ret = !ep->handle ? ENOMEM
+ : io_listen_xdp(net->loop, ep, addr_str);
+ #else
+ ret = ESOCKTNOSUPPORT;
+ #endif
+ goto finish_ret;
+ } /* else */
+
+ if (ep->flags.sock_type == SOCK_DGRAM) {
+ if (kr_fails_assert(!ep->flags.tls))
+ return kr_error(EINVAL);
+ uv_udp_t *ep_handle = malloc(sizeof(uv_udp_t));
+ ep->handle = (uv_handle_t *)ep_handle;
+ ret = !ep->handle ? ENOMEM
+ : io_listen_udp(net->loop, ep_handle, ep->fd);
+ goto finish_ret;
+ } /* else */
+
+ if (ep->flags.sock_type == SOCK_STREAM) {
+ uv_tcp_t *ep_handle = malloc(sizeof(uv_tcp_t));
+ ep->handle = (uv_handle_t *)ep_handle;
+ ret = !ep->handle ? ENOMEM
+ : io_listen_tcp(net->loop, ep_handle, ep->fd,
+ net->tcp_backlog, ep->flags.tls, ep->flags.http);
+ goto finish_ret;
+ } /* else */
+
+ kr_assert(false);
+ return kr_error(EINVAL);
+finish_ret:
+ if (!ret) return ret;
+ free(ep->handle);
+ ep->handle = NULL;
+ return kr_error(ret);
+}
+
+/** @internal Fetch a pointer to endpoint of given parameters (or NULL).
+ * Beware that there might be multiple matches, though that's not common.
+ * The matching isn't really precise in the sense that it might not find
+ * and endpoint that would *collide* the passed one. */
+static struct endpoint * endpoint_get(struct network *net,
+ const char *addr_str,
+ const struct sockaddr *sa,
+ endpoint_flags_t flags)
+{
+ struct endpoint_key_storage key;
+ ssize_t keylen = endpoint_key_create(&key, addr_str, sa);
+ if (keylen < 0)
+ return NULL;
+ trie_val_t *val = trie_get_try(net->endpoints, key.bytes, keylen);
+ if (!val)
+ return NULL;
+ endpoint_array_t *ep_array = *val;
+
+ uint16_t port = kr_inaddr_port(sa);
+ for (int i = 0; i < ep_array->len; ++i) {
+ struct endpoint *ep = &ep_array->at[i];
+ if ((flags.xdp || ep->port == port) && endpoint_flags_eq(ep->flags, flags)) {
+ return ep;
+ }
+ }
+ return NULL;
+}
+
+/** \note pass (either sa != NULL xor ep.fd != -1) or XDP case (neither sa nor ep.fd)
+ * \note in XDP case addr_str is interface name
+ * \note ownership of ep.flags.* is taken on success. */
+static int create_endpoint(struct network *net, const char *addr_str,
+ struct endpoint *ep, const struct sockaddr *sa)
+{
+ int ret = open_endpoint(net, addr_str, ep, sa);
+ if (ret == 0) {
+ ret = insert_endpoint(net, addr_str, sa, ep);
+ }
+ if (ret != 0 && ep->handle) {
+ endpoint_close(net, ep, false);
+ }
+ return ret;
+}
+
+int network_listen_fd(struct network *net, int fd, endpoint_flags_t flags)
+{
+ if (kr_fails_assert(!flags.xdp))
+ return kr_error(EINVAL);
+ /* Extract fd's socket type. */
+ socklen_t len = sizeof(flags.sock_type);
+ int ret = getsockopt(fd, SOL_SOCKET, SO_TYPE, &flags.sock_type, &len);
+ if (ret != 0)
+ return kr_error(errno);
+ const bool is_dtls = flags.sock_type == SOCK_DGRAM && !flags.kind && flags.tls;
+ if (kr_fails_assert(!is_dtls))
+ return kr_error(EINVAL); /* Perhaps DTLS some day. */
+ if (flags.sock_type != SOCK_DGRAM && flags.sock_type != SOCK_STREAM)
+ return kr_error(EBADF);
+
+ /* Extract local address for this socket. */
+ struct sockaddr_storage ss = { .ss_family = AF_UNSPEC };
+ socklen_t addr_len = sizeof(ss);
+ ret = getsockname(fd, (struct sockaddr *)&ss, &addr_len);
+ if (ret != 0)
+ return kr_error(errno);
+
+ struct endpoint ep = {
+ .flags = flags,
+ .family = ss.ss_family,
+ .fd = fd,
+ };
+ /* Extract address string and port. */
+ char addr_buf[INET6_ADDRSTRLEN]; /* https://tools.ietf.org/html/rfc4291 */
+ const char *addr_str;
+ switch (ep.family) {
+ case AF_INET:
+ ret = uv_ip4_name((const struct sockaddr_in*)&ss, addr_buf, sizeof(addr_buf));
+ addr_str = addr_buf;
+ ep.port = ntohs(((struct sockaddr_in *)&ss)->sin_port);
+ break;
+ case AF_INET6:
+ ret = uv_ip6_name((const struct sockaddr_in6*)&ss, addr_buf, sizeof(addr_buf));
+ addr_str = addr_buf;
+ ep.port = ntohs(((struct sockaddr_in6 *)&ss)->sin6_port);
+ break;
+ case AF_UNIX:
+ /* No SOCK_DGRAM with AF_UNIX support, at least for now. */
+ ret = flags.sock_type == SOCK_STREAM ? kr_ok() : kr_error(EAFNOSUPPORT);
+ addr_str = ((struct sockaddr_un *)&ss)->sun_path;
+ break;
+ default:
+ ret = kr_error(EAFNOSUPPORT);
+ }
+ if (ret) return ret;
+
+ /* always create endpoint for supervisor supplied fd
+ * even if addr+port is not unique */
+ return create_endpoint(net, addr_str, &ep, (struct sockaddr *) &ss);
+}
+
+/** Try selecting XDP queue automatically. */
+static int16_t nic_queue_auto(void)
+{
+ const char *inst_str = getenv("SYSTEMD_INSTANCE");
+ if (!inst_str)
+ return 0; // should work OK for simple (single-kresd) deployments
+ char *endp;
+ errno = 0; // strtol() is special in this respect
+ long inst = strtol(inst_str, &endp, 10);
+ if (!errno && *endp == '\0' && inst > 0 && inst < UINT16_MAX)
+ return inst - 1; // 1-based vs. 0-based indexing conventions
+ return -1;
+}
+
+int network_listen(struct network *net, const char *addr, uint16_t port,
+ int16_t nic_queue, endpoint_flags_t flags)
+{
+ if (kr_fails_assert(net != NULL && addr != 0 && nic_queue >= -1))
+ return kr_error(EINVAL);
+
+ if (flags.xdp && nic_queue < 0) {
+ nic_queue = nic_queue_auto();
+ if (nic_queue < 0) {
+ return kr_error(EINVAL);
+ }
+ }
+
+ // Try parsing the address.
+ const struct sockaddr *sa = kr_straddr_socket(addr, port, NULL);
+ if (!sa && !flags.xdp) { // unusable address spec
+ return kr_error(EINVAL);
+ }
+ char ifname_buf[64] UNUSED;
+ if (sa && flags.xdp) { // auto-detection: address -> interface
+ #if ENABLE_XDP
+ int ret = knot_eth_name_from_addr((const struct sockaddr_storage *)sa,
+ ifname_buf, sizeof(ifname_buf));
+ // even on success we don't want to pass `sa` on
+ free_const(sa);
+ sa = NULL;
+ if (ret) {
+ return kr_error(ret);
+ }
+ addr = ifname_buf;
+ #else
+ return kr_error(ESOCKTNOSUPPORT);
+ #endif
+ }
+ // XDP: if addr failed to parse as address, we assume it's an interface name.
+
+ if (endpoint_get(net, addr, sa, flags)) {
+ return kr_error(EADDRINUSE); // Already listening
+ }
+
+ struct endpoint ep = { 0 };
+ ep.flags = flags;
+ ep.fd = -1;
+ ep.port = port;
+ ep.family = flags.xdp ? AF_XDP : sa->sa_family;
+ ep.nic_queue = nic_queue;
+
+ int ret = create_endpoint(net, addr, &ep, sa);
+
+ // Error reporting: more precision.
+ if (ret == KNOT_EINVAL && !sa && flags.xdp && ENABLE_XDP) {
+ if (!if_nametoindex(addr) && errno == ENODEV) {
+ ret = kr_error(ENODEV);
+ }
+ }
+
+ free_const(sa);
+ return ret;
+}
+
+int network_proxy_allow(struct network *net, const char* addr)
+{
+ if (kr_fails_assert(net != NULL && addr != NULL))
+ return kr_error(EINVAL);
+
+ int family = kr_straddr_family(addr);
+ if (family < 0) {
+ kr_log_error(NETWORK, "Wrong address format for proxy_allowed: %s\n",
+ addr);
+ return kr_error(EINVAL);
+ } else if (family == AF_UNIX) {
+ kr_log_error(NETWORK, "Unix sockets not supported for proxy_allowed: %s\n",
+ addr);
+ return kr_error(EINVAL);
+ }
+
+ union kr_in_addr ia;
+ int netmask = kr_straddr_subnet(&ia, addr);
+ if (netmask < 0) {
+ kr_log_error(NETWORK, "Wrong netmask format for proxy_allowed: %s\n", addr);
+ return kr_error(EINVAL);
+ } else if (netmask == 0) {
+ /* Netmask is zero: allow all addresses to use PROXYv2 */
+ switch (family) {
+ case AF_INET:
+ net->proxy_all4 = true;
+ break;
+ case AF_INET6:
+ net->proxy_all6 = true;
+ break;
+ default:
+ kr_assert(false);
+ return kr_error(EINVAL);
+ }
+
+ return kr_ok();
+ }
+
+ size_t addr_length;
+ trie_t *trie;
+ switch (family) {
+ case AF_INET:
+ addr_length = sizeof(ia.ip4);
+ trie = net->proxy_addrs4;
+ break;
+ case AF_INET6:
+ addr_length = sizeof(ia.ip6);
+ trie = net->proxy_addrs6;
+ break;
+ default:
+ kr_assert(false);
+ return kr_error(EINVAL);
+ }
+
+ kr_bitmask((unsigned char *) &ia, addr_length, netmask);
+ trie_val_t *val = trie_get_ins(trie, (char *) &ia, addr_length);
+ if (!val)
+ return kr_error(ENOMEM);
+
+ struct net_proxy_data *data = *val;
+ if (!data) {
+ /* Allocate data if the entry is new in the trie */
+ *val = malloc(sizeof(struct net_proxy_data));
+ data = *val;
+ data->netmask = 0;
+ }
+
+ if (data->netmask == 0) {
+ memcpy(&data->addr, &ia, addr_length);
+ data->netmask = netmask;
+ } else if (data->netmask > netmask) {
+ /* A more relaxed netmask configured - replace it */
+ data->netmask = netmask;
+ }
+
+ return kr_ok();
+}
+
+void network_proxy_reset(struct network *net)
+{
+ net->proxy_all4 = false;
+ network_proxy_free_addr_data(net->proxy_addrs4);
+ trie_clear(net->proxy_addrs4);
+ net->proxy_all6 = false;
+ network_proxy_free_addr_data(net->proxy_addrs6);
+ trie_clear(net->proxy_addrs6);
+}
+
+static int endpoints_close(struct network *net,
+ struct endpoint_key_storage *key, ssize_t keylen,
+ endpoint_array_t *ep_array, int port)
+{
+ size_t i = 0;
+ bool matched = false; /*< at least one match */
+ while (i < ep_array->len) {
+ struct endpoint *ep = &ep_array->at[i];
+ if (port < 0 || ep->port == port) {
+ endpoint_close(net, ep, false);
+ array_del(*ep_array, i);
+ matched = true;
+ /* do not advance i */
+ } else {
+ ++i;
+ }
+ }
+ if (!matched) {
+ return kr_error(ENOENT);
+ }
+
+ return kr_ok();
+}
+
+static bool endpoint_key_addr_matches(struct endpoint_key_storage *key_a,
+ struct endpoint_key_storage *key_b)
+{
+ if (key_a->type != key_b->type)
+ return false;
+
+ if (key_a->type == ENDPOINT_KEY_IFNAME)
+ return strncmp(key_a->ifname.ifname,
+ key_b->ifname.ifname,
+ sizeof(key_a->ifname.ifname)) == 0;
+
+ if (key_a->type == ENDPOINT_KEY_SOCKADDR) {
+ return kr_sockaddr_key_same_addr(
+ key_a->sa.sa_key.bytes, key_b->sa.sa_key.bytes);
+ }
+
+ kr_assert(false);
+ return kr_error(EINVAL);
+}
+
+struct endpoint_key_with_len {
+ struct endpoint_key_storage key;
+ size_t keylen;
+};
+typedef array_t(struct endpoint_key_with_len) endpoint_key_array_t;
+
+struct endpoint_close_wildcard_context {
+ struct network *net;
+ struct endpoint_key_storage *match_key;
+ endpoint_key_array_t del;
+ int ret;
+};
+
+static int endpoints_close_wildcard(const char *s_key, uint32_t keylen, trie_val_t *val, void *baton)
+{
+ struct endpoint_close_wildcard_context *ctx = baton;
+ struct endpoint_key_storage *key = (struct endpoint_key_storage *)s_key;
+
+ if (!endpoint_key_addr_matches(key, ctx->match_key))
+ return kr_ok();
+
+ endpoint_array_t *ep_array = *val;
+ int ret = endpoints_close(ctx->net, key, keylen, ep_array, -1);
+ if (ret)
+ ctx->ret = ret;
+
+ if (ep_array->len == 0) {
+ struct endpoint_key_with_len to_del = {
+ .key = *key,
+ .keylen = keylen
+ };
+ array_push(ctx->del, to_del);
+ }
+
+ return kr_ok();
+}
+
+int network_close(struct network *net, const char *addr_str, int port)
+{
+ auto_free struct sockaddr *addr = kr_straddr_socket(addr_str, port, NULL);
+ struct endpoint_key_storage key;
+ ssize_t keylen = endpoint_key_create(&key, addr_str, addr);
+ if (keylen < 0)
+ return keylen;
+
+ if (port < 0) {
+ struct endpoint_close_wildcard_context ctx = {
+ .net = net,
+ .match_key = &key
+ };
+ array_init(ctx.del);
+ trie_apply_with_key(net->endpoints, endpoints_close_wildcard, &ctx);
+ for (size_t i = 0; i < ctx.del.len; i++) {
+ trie_val_t val;
+ trie_del(net->endpoints,
+ ctx.del.at[i].key.bytes, ctx.del.at[i].keylen,
+ &val);
+ if (val) {
+ array_clear(*(endpoint_array_t *) val);
+ free(val);
+ }
+ }
+ return ctx.ret;
+ }
+
+ trie_val_t *val = trie_get_try(net->endpoints, key.bytes, keylen);
+ if (!val)
+ return kr_error(ENOENT);
+ endpoint_array_t *ep_array = *val;
+ int ret = endpoints_close(net, &key, keylen, ep_array, port);
+
+ /* Collapse key if it has no endpoint. */
+ if (ep_array->len == 0) {
+ array_clear(*ep_array);
+ free(ep_array);
+ trie_del(net->endpoints, key.bytes, keylen, NULL);
+ }
+
+ return ret;
+}
+
+void network_new_hostname(struct network *net, struct engine *engine)
+{
+ if (net->tls_credentials &&
+ net->tls_credentials->ephemeral_servicename) {
+ struct tls_credentials *newcreds;
+ newcreds = tls_get_ephemeral_credentials(engine);
+ if (newcreds) {
+ tls_credentials_release(net->tls_credentials);
+ net->tls_credentials = newcreds;
+ kr_log_info(TLS, "Updated ephemeral X.509 cert with new hostname\n");
+ } else {
+ kr_log_error(TLS, "Failed to update ephemeral X.509 cert with new hostname, using existing one\n");
+ }
+ }
+}
+
+#ifdef SO_ATTACH_BPF
+static int set_bpf_cb(trie_val_t *val, void *ctx)
+{
+ endpoint_array_t *endpoints = *val;
+ int *bpffd = (int *)ctx;
+ if (kr_fails_assert(endpoints && bpffd))
+ return kr_error(EINVAL);
+
+ for (size_t i = 0; i < endpoints->len; i++) {
+ struct endpoint *endpoint = &endpoints->at[i];
+ uv_os_fd_t sockfd = -1;
+ if (endpoint->handle != NULL)
+ uv_fileno(endpoint->handle, &sockfd);
+ kr_require(sockfd != -1);
+
+ if (setsockopt(sockfd, SOL_SOCKET, SO_ATTACH_BPF, bpffd, sizeof(int)) != 0) {
+ return 1; /* return error (and stop iterating over net->endpoints) */
+ }
+ }
+ return 0; /* OK */
+}
+#endif
+
+int network_set_bpf(struct network *net, int bpf_fd)
+{
+#ifdef SO_ATTACH_BPF
+ if (trie_apply(net->endpoints, set_bpf_cb, &bpf_fd) != 0) {
+ /* set_bpf_cb() has returned error. */
+ network_clear_bpf(net);
+ return 0;
+ }
+#else
+ kr_log_error(NETWORK, "SO_ATTACH_BPF socket option doesn't supported\n");
+ (void)net;
+ (void)bpf_fd;
+ return 0;
+#endif
+ return 1;
+}
+
+#ifdef SO_DETACH_BPF
+static int clear_bpf_cb(trie_val_t *val, void *ctx)
+{
+ endpoint_array_t *endpoints = *val;
+ if (kr_fails_assert(endpoints))
+ return kr_error(EINVAL);
+
+ for (size_t i = 0; i < endpoints->len; i++) {
+ struct endpoint *endpoint = &endpoints->at[i];
+ uv_os_fd_t sockfd = -1;
+ if (endpoint->handle != NULL)
+ uv_fileno(endpoint->handle, &sockfd);
+ kr_require(sockfd != -1);
+
+ if (setsockopt(sockfd, SOL_SOCKET, SO_DETACH_BPF, NULL, 0) != 0) {
+ kr_log_error(NETWORK, "failed to clear SO_DETACH_BPF socket option\n");
+ }
+ /* Proceed even if setsockopt() failed,
+ * as we want to process all opened sockets. */
+ }
+ return 0;
+}
+#endif
+
+void network_clear_bpf(struct network *net)
+{
+#ifdef SO_DETACH_BPF
+ trie_apply(net->endpoints, clear_bpf_cb, NULL);
+#else
+ kr_log_error(NETWORK, "SO_DETACH_BPF socket option doesn't supported\n");
+ (void)net;
+#endif
+}
diff --git a/daemon/network.h b/daemon/network.h
new file mode 100644
index 0000000..e21651f
--- /dev/null
+++ b/daemon/network.h
@@ -0,0 +1,162 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#include "daemon/tls.h"
+
+#include "lib/generic/array.h"
+#include "lib/generic/trie.h"
+
+#include <uv.h>
+#include <stdbool.h>
+
+#include <sys/socket.h>
+#ifndef AF_XDP
+#define AF_XDP 44
+#endif
+
+struct engine;
+struct session;
+
+/** Ways to listen on a socket (which may exist already). */
+typedef struct {
+ int sock_type; /**< SOCK_DGRAM or SOCK_STREAM */
+ bool tls; /**< only used together with .kind == NULL and SOCK_STREAM */
+ bool http; /**< DoH2, implies .tls (in current implementation) */
+ bool xdp; /**< XDP is special (not a normal socket, in particular) */
+ bool freebind; /**< used for binding to non-local address */
+ const char *kind; /**< tag for other types: "control" or module-handled kinds */
+} endpoint_flags_t;
+
+struct endpoint_key;
+
+static inline bool endpoint_flags_eq(endpoint_flags_t f1, endpoint_flags_t f2)
+{
+ if (f1.sock_type != f2.sock_type)
+ return false;
+ if (f1.kind && f2.kind)
+ return strcasecmp(f1.kind, f2.kind);
+ else
+ return f1.tls == f2.tls && f1.kind == f2.kind;
+}
+
+/** Wrapper for a single socket to listen on.
+ * There are two types: normal have handle, special have flags.kind (and never both).
+ *
+ * LATER: .family might be unexpected for IPv4-in-IPv6 addresses.
+ * ATM AF_UNIX is only supported with flags.kind != NULL
+ */
+struct endpoint {
+ /** uv_{udp,tcp,poll}_t (poll for XDP);
+ * NULL in case of endpoints that are to be handled by modules. */
+ uv_handle_t *handle;
+ int fd; /**< POSIX file-descriptor; always used. */
+ int family; /**< AF_INET or AF_INET6 or AF_UNIX or AF_XDP */
+ uint16_t port; /**< TCP/UDP port. Meaningless with AF_UNIX. */
+ int16_t nic_queue; /**< -1 or queue number of the interface for AF_XDP use. */
+ bool engaged; /**< to some module or internally */
+ endpoint_flags_t flags;
+};
+
+/** @cond internal Array of endpoints */
+typedef array_t(struct endpoint) endpoint_array_t;
+/* @endcond */
+
+struct net_tcp_param {
+ uint64_t in_idle_timeout;
+ uint64_t tls_handshake_timeout;
+};
+
+/** Information about an address that is allowed to use PROXYv2. */
+struct net_proxy_data {
+ union kr_in_addr addr;
+ uint8_t netmask; /**< Number of bits to be matched */
+};
+
+struct network {
+ uv_loop_t *loop;
+
+ /** Map: address string -> endpoint_array_t.
+ * \note even same address-port-flags tuples may appear. */
+ trie_t *endpoints;
+
+ /** Registry of callbacks for special endpoint kinds (for opening/closing).
+ * Map: kind (lowercased) -> lua function ID converted to void *
+ * The ID is the usual: raw int index in the LUA_REGISTRYINDEX table. */
+ trie_t *endpoint_kinds;
+ /** See network_engage_endpoints() */
+ bool missing_kind_is_error : 1;
+
+ /** True: All IPv4 addresses are allowed to use the PROXYv2 protocol */
+ bool proxy_all4 : 1;
+ /** True: All IPv6 addresses are allowed to use the PROXYv2 protocol */
+ bool proxy_all6 : 1;
+
+ /** IPv4 addresses and networks allowed to use the PROXYv2 protocol */
+ trie_t *proxy_addrs4;
+ /** IPv6 addresses and networks allowed to use the PROXYv2 protocol */
+ trie_t *proxy_addrs6;
+
+ struct tls_credentials *tls_credentials;
+ tls_client_params_t *tls_client_params; /**< Use tls_client_params_*() functions. */
+ struct tls_session_ticket_ctx *tls_session_ticket_ctx;
+ struct net_tcp_param tcp;
+ int tcp_backlog;
+};
+
+void network_init(struct network *net, uv_loop_t *loop, int tcp_backlog);
+void network_deinit(struct network *net);
+
+/** Start listening on addr#port with flags.
+ * \note if we did listen on that combination already,
+ * nothing is done and kr_error(EADDRINUSE) is returned.
+ * \note there's no short-hand to listen both on UDP and TCP.
+ * \note ownership of flags.* is taken on success. TODO: non-success?
+ * \param nic_queue == -1 for auto-selection or non-XDP.
+ * \note In XDP mode, addr may be also interface name, so kr_error(ENODEV)
+ * is returned if some nonsense is passed
+ */
+int network_listen(struct network *net, const char *addr, uint16_t port,
+ int16_t nic_queue, endpoint_flags_t flags);
+
+/** Allow the specified address to send the PROXYv2 header.
+ * \note the address may be specified with a netmask
+ */
+int network_proxy_allow(struct network *net, const char* addr);
+
+/** Reset all addresses allowed to send the PROXYv2 header. No addresses will
+ * be allowed to send PROXYv2 headers from the point of calling this function
+ * until re-allowed via network_proxy_allow again.
+ */
+void network_proxy_reset(struct network *net);
+
+/** Start listening on an open file-descriptor.
+ * \note flags.sock_type isn't meaningful here.
+ * \note ownership of flags.* is taken on success. TODO: non-success?
+ */
+int network_listen_fd(struct network *net, int fd, endpoint_flags_t flags);
+
+/** Stop listening on all endpoints with matching addr#port.
+ * port < 0 serves as a wild-card.
+ * \return kr_error(ENOENT) if nothing matched. */
+int network_close(struct network *net, const char *addr, int port);
+
+/** Close all endpoints immediately (no waiting for UV loop). */
+void network_close_force(struct network *net);
+
+/** Enforce that all endpoints are registered from now on.
+ * This only does anything with struct endpoint::flags.kind != NULL. */
+int network_engage_endpoints(struct network *net);
+
+/** Returns a string representation of the specified endpoint key.
+ *
+ * The result points into key or is on static storage like for kr_straddr() */
+const char *network_endpoint_key_str(const struct endpoint_key *key);
+
+int network_set_tls_cert(struct network *net, const char *cert);
+int network_set_tls_key(struct network *net, const char *key);
+void network_new_hostname(struct network *net, struct engine *engine);
+int network_set_bpf(struct network *net, int bpf_fd);
+void network_clear_bpf(struct network *net);
diff --git a/daemon/proxyv2.c b/daemon/proxyv2.c
new file mode 100644
index 0000000..f977ccb
--- /dev/null
+++ b/daemon/proxyv2.c
@@ -0,0 +1,290 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#include "daemon/proxyv2.h"
+
+#include "lib/generic/trie.h"
+
+const char PROXY2_SIGNATURE[12] = {
+ 0x0D, 0x0A, 0x0D, 0x0A, 0x00, 0x0D, 0x0A, 0x51, 0x55, 0x49, 0x54, 0x0A
+};
+
+#define PROXY2_IP6_ADDR_SIZE 16
+#define PROXY2_UNIX_ADDR_SIZE 108
+
+#define TLV_TYPE_SSL 0x20
+
+enum proxy2_family {
+ PROXY2_AF_UNSPEC = 0x0,
+ PROXY2_AF_INET = 0x1,
+ PROXY2_AF_INET6 = 0x2,
+ PROXY2_AF_UNIX = 0x3
+};
+
+enum proxy2_protocol {
+ PROXY2_PROTOCOL_UNSPEC = 0x0,
+ PROXY2_PROTOCOL_STREAM = 0x1,
+ PROXY2_PROTOCOL_DGRAM = 0x2
+};
+
+/** PROXYv2 protocol header section */
+struct proxy2_header {
+ uint8_t signature[sizeof(PROXY2_SIGNATURE)];
+ uint8_t version_command;
+ uint8_t family_protocol;
+ uint16_t length; /**< Length of the address section */
+};
+
+/** PROXYv2 additional information in Type-Length-Value (TLV) format. */
+struct proxy2_tlv {
+ uint8_t type;
+ uint8_t length_hi;
+ uint8_t length_lo;
+ uint8_t value[];
+};
+
+/** PROXYv2 protocol address section */
+union proxy2_address {
+ struct {
+ uint32_t src_addr;
+ uint32_t dst_addr;
+ uint16_t src_port;
+ uint16_t dst_port;
+ } ipv4_addr;
+ struct {
+ uint8_t src_addr[PROXY2_IP6_ADDR_SIZE];
+ uint8_t dst_addr[PROXY2_IP6_ADDR_SIZE];
+ uint16_t src_port;
+ uint16_t dst_port;
+ } ipv6_addr;
+ struct {
+ uint8_t src_addr[PROXY2_UNIX_ADDR_SIZE];
+ uint8_t dst_addr[PROXY2_UNIX_ADDR_SIZE];
+ } unix_addr;
+};
+
+
+/** Gets protocol version from the specified PROXYv2 header. */
+static inline unsigned char proxy2_header_version(const struct proxy2_header* h)
+{
+ return (h->version_command & 0xF0) >> 4;
+}
+
+/** Gets command from the specified PROXYv2 header. */
+static inline enum proxy2_command proxy2_header_command(const struct proxy2_header *h)
+{
+ return h->version_command & 0x0F;
+}
+
+/** Gets address family from the specified PROXYv2 header. */
+static inline enum proxy2_family proxy2_header_family(const struct proxy2_header *h)
+{
+ return (h->family_protocol & 0xF0) >> 4;
+}
+
+/** Gets transport protocol from the specified PROXYv2 header. */
+static inline enum proxy2_family proxy2_header_protocol(const struct proxy2_header *h)
+{
+ return h->family_protocol & 0x0F;
+}
+
+static inline union proxy2_address *proxy2_get_address(const struct proxy2_header *h)
+{
+ return (union proxy2_address *) ((uint8_t *) h + sizeof(struct proxy2_header));
+}
+
+static inline struct proxy2_tlv *get_tlvs(const struct proxy2_header *h, size_t addr_len)
+{
+ return (struct proxy2_tlv *) ((uint8_t *) proxy2_get_address(h) + addr_len);
+}
+
+/** Gets the length of the TLV's `value` attribute. */
+static inline uint16_t proxy2_tlv_length(const struct proxy2_tlv *tlv)
+{
+ return ((uint16_t) tlv->length_hi << 16) | tlv->length_lo;
+}
+
+static inline bool has_tlv(const struct proxy2_header *h,
+ const struct proxy2_tlv *tlv)
+{
+ uint64_t addr_length = ntohs(h->length);
+ ptrdiff_t hdr_len = sizeof(struct proxy2_header) + addr_length;
+
+ uint8_t *tlv_hdr_end = (uint8_t *) tlv + sizeof(struct proxy2_tlv);
+ ptrdiff_t distance = tlv_hdr_end - (uint8_t *) h;
+ if (hdr_len < distance)
+ return false;
+
+ uint8_t *tlv_end = tlv_hdr_end + proxy2_tlv_length(tlv);
+ distance = tlv_end - (uint8_t *) h;
+ return hdr_len >= distance;
+}
+
+static inline void next_tlv(struct proxy2_tlv **tlv)
+{
+ uint8_t *next = ((uint8_t *) *tlv + sizeof(struct proxy2_tlv) + proxy2_tlv_length(*tlv));
+ *tlv = (struct proxy2_tlv *) next;
+}
+
+
+bool proxy_allowed(const struct network *net, const struct sockaddr *saddr)
+{
+ union kr_in_addr addr;
+ trie_t *trie;
+ size_t addr_size;
+ switch (saddr->sa_family) {
+ case AF_INET:
+ if (net->proxy_all4)
+ return true;
+
+ trie = net->proxy_addrs4;
+ addr_size = sizeof(addr.ip4);
+ addr.ip4 = ((struct sockaddr_in *) saddr)->sin_addr;
+ break;
+ case AF_INET6:
+ if (net->proxy_all6)
+ return true;
+
+ trie = net->proxy_addrs6;
+ addr_size = sizeof(addr.ip6);
+ addr.ip6 = ((struct sockaddr_in6 *) saddr)->sin6_addr;
+ break;
+ default:
+ kr_assert(false); // Only IPv4 and IPv6 proxy addresses supported
+ return false;
+ }
+
+ trie_val_t *val;
+ int ret = trie_get_leq(trie, (char *) &addr, addr_size, &val);
+ if (ret != kr_ok() && ret != 1)
+ return false;
+
+ kr_assert(val);
+ const struct net_proxy_data *found = *val;
+ kr_assert(found);
+ return kr_bitcmp((char *) &addr, (char *) &found->addr, found->netmask) == 0;
+}
+
+ssize_t proxy_process_header(struct proxy_result *out, struct session *s,
+ const void *buf, const ssize_t nread)
+{
+ if (!buf)
+ return kr_error(EINVAL);
+
+ const struct proxy2_header *hdr = (struct proxy2_header *) buf;
+
+ uint64_t content_length = ntohs(hdr->length);
+ ssize_t hdr_len = sizeof(struct proxy2_header) + content_length;
+
+ /* PROXYv2 requires the header to be received all at once */
+ if (nread < hdr_len) {
+ return kr_error(KNOT_EMALF);
+ }
+
+ unsigned char version = proxy2_header_version(hdr);
+ if (version != 2) {
+ /* Version MUST be 2 for PROXYv2 protocol */
+ return kr_error(KNOT_EMALF);
+ }
+
+ enum proxy2_command command = proxy2_header_command(hdr);
+ if (command == PROXY2_CMD_LOCAL) {
+ /* Addresses for LOCAL are to be discarded */
+ *out = (struct proxy_result) { .command = PROXY2_CMD_LOCAL };
+ goto fill_wirebuf;
+ }
+
+ if (command != PROXY2_CMD_PROXY) {
+ /* PROXYv2 prohibits values other than LOCAL and PROXY */
+ return kr_error(KNOT_EMALF);
+ }
+
+ *out = (struct proxy_result) { .command = PROXY2_CMD_PROXY };
+
+ /* Parse flags */
+ enum proxy2_family family = proxy2_header_family(hdr);
+ switch(family) {
+ case PROXY2_AF_UNSPEC:
+ case PROXY2_AF_UNIX: /* UNIX is unsupported, fall back to UNSPEC */
+ out->family = AF_UNSPEC;
+ break;
+ case PROXY2_AF_INET:
+ out->family = AF_INET;
+ break;
+ case PROXY2_AF_INET6:
+ out->family = AF_INET6;
+ break;
+ default: /* PROXYv2 prohibits other values */
+ return kr_error(KNOT_EMALF);
+ }
+
+ enum proxy2_family protocol = proxy2_header_protocol(hdr);
+ switch (protocol) {
+ case PROXY2_PROTOCOL_DGRAM:
+ out->protocol = SOCK_DGRAM;
+ break;
+ case PROXY2_PROTOCOL_STREAM:
+ out->protocol = SOCK_STREAM;
+ break;
+ default: /* PROXYv2 prohibits other values */
+ return kr_error(KNOT_EMALF);
+ }
+
+ /* Parse addresses */
+ union proxy2_address* addr = proxy2_get_address(hdr);
+ size_t addr_length = 0;
+ switch(out->family) {
+ case AF_INET:
+ addr_length = sizeof(addr->ipv4_addr);
+ if (content_length < addr_length)
+ return kr_error(KNOT_EMALF);
+
+ out->src_addr.ip4 = (struct sockaddr_in) {
+ .sin_family = AF_INET,
+ .sin_addr = { .s_addr = addr->ipv4_addr.src_addr },
+ .sin_port = addr->ipv4_addr.src_port,
+ };
+ out->dst_addr.ip4 = (struct sockaddr_in) {
+ .sin_family = AF_INET,
+ .sin_addr = { .s_addr = addr->ipv4_addr.dst_addr },
+ .sin_port = addr->ipv4_addr.dst_port,
+ };
+ break;
+ case AF_INET6:
+ addr_length = sizeof(addr->ipv6_addr);
+ if (content_length < addr_length)
+ return kr_error(KNOT_EMALF);
+
+ out->src_addr.ip6 = (struct sockaddr_in6) {
+ .sin6_family = AF_INET6,
+ .sin6_port = addr->ipv6_addr.src_port
+ };
+ memcpy(
+ &out->src_addr.ip6.sin6_addr.s6_addr,
+ &addr->ipv6_addr.src_addr,
+ sizeof(out->src_addr.ip6.sin6_addr.s6_addr));
+ out->dst_addr.ip6 = (struct sockaddr_in6) {
+ .sin6_family = AF_INET6,
+ .sin6_port = addr->ipv6_addr.dst_port
+ };
+ memcpy(
+ &out->dst_addr.ip6.sin6_addr.s6_addr,
+ &addr->ipv6_addr.dst_addr,
+ sizeof(out->dst_addr.ip6.sin6_addr.s6_addr));
+ break;
+ }
+
+ /* Process additional information */
+ for (struct proxy2_tlv *tlv = get_tlvs(hdr, addr_length); has_tlv(hdr, tlv); next_tlv(&tlv)) {
+ switch (tlv->type) {
+ case TLV_TYPE_SSL:
+ out->has_tls = true;
+ break;
+ /* TODO: add more TLV types if needed */
+ }
+ }
+
+fill_wirebuf:
+ return session_wirebuf_trim(s, hdr_len);
+}
diff --git a/daemon/proxyv2.h b/daemon/proxyv2.h
new file mode 100644
index 0000000..2d57744
--- /dev/null
+++ b/daemon/proxyv2.h
@@ -0,0 +1,50 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#include <stdint.h>
+
+#include "daemon/session.h"
+#include "daemon/network.h"
+#include "lib/utils.h"
+
+extern const char PROXY2_SIGNATURE[12];
+
+#define PROXY2_MIN_SIZE 16
+
+enum proxy2_command {
+ PROXY2_CMD_LOCAL = 0x0,
+ PROXY2_CMD_PROXY = 0x1
+};
+
+/** Parsed result of the PROXY protocol */
+struct proxy_result {
+ enum proxy2_command command; /**< Proxy command - PROXY or LOCAL. */
+ int family; /**< Address family from netinet library (e.g. AF_INET6). */
+ int protocol; /**< Protocol type from socket library (e.g. SOCK_STREAM). */
+ union kr_sockaddr src_addr; /**< Parsed source address and port. */
+ union kr_sockaddr dst_addr; /**< Parsed destination address and port. */
+ bool has_tls : 1; /**< `true` = client has used TLS with the proxy.
+ If TLS padding is enabled, it will be used even if
+ the proxy did not use TLS with kresd. */
+};
+
+/** Checks for a PROXY protocol version 2 signature in the specified buffer. */
+static inline bool proxy_header_present(const void* buf, const ssize_t nread)
+{
+ return nread >= PROXY2_MIN_SIZE &&
+ memcmp(buf, PROXY2_SIGNATURE, sizeof(PROXY2_SIGNATURE)) == 0;
+}
+
+/** Checks whether the use of PROXYv2 protocol is allowed for the specified
+ * address. */
+bool proxy_allowed(const struct network *net, const struct sockaddr *saddr);
+
+/** Parses the PROXYv2 header from buf of size nread and writes the result into
+ * out. The rest of the buffer is moved to free bytes of the specified session's
+ * wire buffer. The function assumes that the PROXYv2 signature is present
+ * and has been already checked by the caller (like `udp_recv` or `tcp_recv`). */
+ssize_t proxy_process_header(struct proxy_result *out, struct session *s,
+ const void *buf, ssize_t nread);
diff --git a/daemon/proxyv2.test/deckard.yaml b/daemon/proxyv2.test/deckard.yaml
new file mode 100644
index 0000000..8eb2fa6
--- /dev/null
+++ b/daemon/proxyv2.test/deckard.yaml
@@ -0,0 +1,25 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+programs:
+ - name: dnsdist
+ binary: dnsdist
+ additional:
+ - --verbose
+ - --supervised
+ - --config
+ - dnsdist.conf
+ ignore_exit_code: True
+ templates:
+ - daemon/proxyv2.test/dnsdist_config.j2
+ configs:
+ - dnsdist.conf
+ - name: kresd
+ binary: kresd
+ additional:
+ - --noninteractive
+ templates:
+ - daemon/proxyv2.test/kresd_config.j2
+ - tests/integration/hints_zone.j2
+ configs:
+ - config
+ - hints
diff --git a/daemon/proxyv2.test/dnsdist_config.j2 b/daemon/proxyv2.test/dnsdist_config.j2
new file mode 100644
index 0000000..0bd4a55
--- /dev/null
+++ b/daemon/proxyv2.test/dnsdist_config.j2
@@ -0,0 +1,11 @@
+-- vim:syntax=lua
+setLocal('{{SELF_ADDR}}')
+setVerboseHealthChecks(true)
+setServerPolicy(firstAvailable)
+
+local server = newServer({
+ address="{{PROGRAMS['kresd']['address']}}",
+ useProxyProtocol=true,
+ checkName="example.cz."
+})
+server:setUp()
diff --git a/daemon/proxyv2.test/kresd_config.j2 b/daemon/proxyv2.test/kresd_config.j2
new file mode 100644
index 0000000..e7cbf63
--- /dev/null
+++ b/daemon/proxyv2.test/kresd_config.j2
@@ -0,0 +1,63 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+{% raw %}
+modules.load('view < policy')
+view:addr("127.127.0.0", policy.suffix(policy.DENY_MSG("addr 127.127.0.0 matched com"),{"\3com\0"}))
+-- policy.add(policy.all(policy.FORWARD('1.2.3.4')))
+
+-- make sure DNSSEC is turned off for tests
+trust_anchors.remove('.')
+
+-- Disable RFC5011 TA update
+if ta_update then
+ modules.unload('ta_update')
+end
+
+-- Disable RFC8145 signaling, scenario doesn't provide expected answers
+if ta_signal_query then
+ modules.unload('ta_signal_query')
+end
+
+-- Disable RFC8109 priming, scenario doesn't provide expected answers
+if priming then
+ modules.unload('priming')
+end
+
+-- Disable this module because it make one priming query
+if detect_time_skew then
+ modules.unload('detect_time_skew')
+end
+
+_hint_root_file('hints')
+cache.size = 2*MB
+log_level('debug')
+{% endraw %}
+
+-- Allow PROXYv2 from dnsdist's address
+--net.proxy_allowed("{{PROGRAMS['dnsdist']['address']}}")
+net.proxy_allowed("127.127.0.0/16")
+
+net = { '{{SELF_ADDR}}' }
+
+{% if QMIN == "false" %}
+option('NO_MINIMIZE', true)
+{% else %}
+option('NO_MINIMIZE', false)
+{% endif %}
+
+
+-- Self-checks on globals
+assert(help() ~= nil)
+assert(worker.id ~= nil)
+-- Self-checks on facilities
+assert(cache.count() == 0)
+assert(cache.stats() ~= nil)
+assert(cache.backends() ~= nil)
+assert(worker.stats() ~= nil)
+assert(net.interfaces() ~= nil)
+-- Self-checks on loaded stuff
+assert(net.list()[1].transport.ip == '{{SELF_ADDR}}')
+assert(#modules.list() > 0)
+-- Self-check timers
+ev = event.recurrent(1 * sec, function (ev) return 1 end)
+event.cancel(ev)
+ev = event.after(0, function (ev) return 1 end)
diff --git a/daemon/proxyv2.test/proxyv2_valid.rpl b/daemon/proxyv2.test/proxyv2_valid.rpl
new file mode 100644
index 0000000..ada8a37
--- /dev/null
+++ b/daemon/proxyv2.test/proxyv2_valid.rpl
@@ -0,0 +1,72 @@
+; SPDX-License-Identifier: GPL-3.0-or-later
+; config options
+ stub-addr: 1.2.3.4
+ query-minimization: off
+CONFIG_END
+
+SCENARIO_BEGIN proxyv2:valid test
+
+RANGE_BEGIN 0 110
+ ADDRESS 1.2.3.4
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+example.cz. IN A
+SECTION ANSWER
+example.cz. IN A 5.6.7.8
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+k.root-servers.net. IN AAAA
+SECTION ANSWER
+k.root-servers.net. IN AAAA ::1
+ENTRY_END
+
+RANGE_END
+
+; query with PROXYv2 header - not blocked
+STEP 10 QUERY
+ENTRY_BEGIN
+ADJUST raw_id
+REPLY RD
+SECTION QUESTION
+example.cz. IN A
+ENTRY_END
+
+STEP 20 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH flags rcode question answer
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+example.cz. IN A
+SECTION ANSWER
+example.cz. IN A 5.6.7.8
+ENTRY_END
+
+; query with PROXYv2 header - blocked by view:addr
+; NXDOMAIN expected
+STEP 30 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+example.com. IN A
+ENTRY_END
+
+STEP 31 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH opcode question rcode additional
+REPLY QR RD RA AA NXDOMAIN
+SECTION QUESTION
+example.com. IN A
+SECTION ADDITIONAL
+explanation.invalid. 10800 IN TXT "addr 127.127.0.0 matched com"
+ENTRY_END
+
+SCENARIO_END
diff --git a/daemon/scripting.rst b/daemon/scripting.rst
new file mode 100644
index 0000000..1950a2b
--- /dev/null
+++ b/daemon/scripting.rst
@@ -0,0 +1,398 @@
+.. SPDX-License-Identifier: GPL-3.0-or-later
+
+.. _runtime-cfg:
+
+Run-time reconfiguration
+========================
+
+Knot Resolver offers several ways to modify its configuration at run-time:
+
+ - Using control socket driven by an external system
+ - Using Lua program embedded in Resolver's configuration file
+
+Both ways can also be combined: For example the configuration file can contain
+a little Lua function which gathers statistics and returns them in JSON string.
+This can be used by an external system which uses control socket to call this
+user-defined function and to retrieve its results.
+
+
+.. _control-sockets:
+
+Control sockets
+---------------
+Control socket acts like "an interactive configuration file" so all actions
+available in configuration file can be executed interactively using the control
+socket. One possible use-case is reconfiguring the resolver instances from
+another program, e.g. a maintenance script.
+
+.. note:: Each instance of Knot Resolver exposes its own control socket. Take
+ that into account when scripting deployments with
+ :ref:`systemd-multiple-instances`.
+
+When Knot Resolver is started using Systemd (see section
+:ref:`quickstart-startup`) it creates a control socket in path
+``/run/knot-resolver/control/$ID``. Connection to the socket can
+be made from command line using e.g. ``socat``:
+
+.. code-block:: bash
+
+ $ socat - UNIX-CONNECT:/run/knot-resolver/control/1
+
+When successfully connected to a socket, the command line should change to
+something like ``>``. Then you can interact with kresd to see configuration or
+set a new one. There are some basic commands to start with.
+
+.. code-block:: lua
+
+ > help() -- shows help
+ > net.interfaces() -- lists available interfaces
+ > net.list() -- lists running network services
+
+
+The *direct output* of commands sent over socket is captured and sent back,
+which gives you an immediate response on the outcome of your command.
+The commands and their output are also logged in ``contrl`` group,
+on ``debug`` level if successful or ``warning`` level if failed
+(see around :func:`log_level`).
+
+Control sockets are also a way to enumerate and test running instances, the
+list of sockets corresponds to the list of processes, and you can test the
+process for liveliness by connecting to the UNIX socket.
+
+.. function:: map(lua_snippet)
+
+ Executes the provided string as lua code on every running resolver instance
+ and returns the results as a table.
+
+ Key ``n`` is always present in the returned table and specifies the total
+ number of instances the command was executed on. The table also contains
+ results from each instance accessible through keys ``1`` to ``n``
+ (inclusive). If any instance returns ``nil``, it is not explicitly part of
+ the table, but you can detect it by iterating through ``1`` to ``n``.
+
+ .. code-block:: lua
+
+ > map('worker.id') -- return an ID of every active instance
+ {
+ '2',
+ '1',
+ ['n'] = 2,
+ }
+ > map('worker.id == "1" or nil') -- example of `nil` return value
+ {
+ [2] = true,
+ ['n'] = 2,
+ }
+
+ The order of instances isn't guaranteed or stable. When you need to identify
+ the instances, you may use ``kluautil.kr_table_pack()`` function to return multiple
+ values as a table. It uses similar semantics with ``n`` as described above
+ to allow ``nil`` values.
+
+ .. code-block:: lua
+
+ > map('require("kluautil").kr_table_pack(worker.id, stats.get("answer.total"))')
+ {
+ {
+ '2',
+ 42,
+ ['n'] = 2,
+ },
+ {
+ '1',
+ 69,
+ ['n'] = 2,
+ },
+ ['n'] = 2,
+ }
+
+ If the command fails on any instance, an error is returned and the execution
+ is in an undefined state (the command might not have been executed on all
+ instances). When using the ``map()`` function to execute any code that might
+ fail, your code should be wrapped in `pcall()
+ <https://www.lua.org/manual/5.1/manual.html#pdf-pcall>`_ to avoid this
+ issue.
+
+ .. code-block:: lua
+
+ > map('require("kluautil").kr_table_pack(pcall(net.tls, "cert.pem", "key.pem"))')
+ {
+ {
+ true, -- function succeeded
+ true, -- function return value(s)
+ ['n'] = 2,
+ },
+ {
+ false, -- function failed
+ 'error occurred...', -- the returned error message
+ ['n'] = 2,
+ },
+ ['n'] = 2,
+ }
+
+
+Lua scripts
+-----------
+
+As it was mentioned in section :ref:`config-syntax`, Resolver's configuration
+file contains program in Lua programming language. This allows you to write
+dynamic rules and helps you to avoid repetitive templating that is unavoidable
+with static configuration. For example parts of configuration can depend on
+:func:`hostname` of the machine:
+
+.. code-block:: lua
+
+ if hostname() == 'hidden' then
+ net.listen(net.eth0, 5353)
+ else
+ net.listen('127.0.0.1')
+ net.listen(net.eth1.addr[1])
+ end
+
+Another example would show how it is possible to bind to all interfaces, using
+iteration.
+
+.. code-block:: lua
+
+ for name, addr_list in pairs(net.interfaces()) do
+ net.listen(addr_list)
+ end
+
+.. tip:: Some users observed a considerable, close to 100%, performance gain in
+ Docker containers when they bound the daemon to a single interface:ip
+ address pair. One may expand the aforementioned example with browsing
+ available addresses as:
+
+ .. code-block:: lua
+
+ addrpref = env.EXPECTED_ADDR_PREFIX
+ for k, v in pairs(addr_list["addr"]) do
+ if string.sub(v,1,string.len(addrpref)) == addrpref then
+ net.listen(v)
+ ...
+
+You can also use third-party Lua libraries (available for example through
+LuaRocks_) as on this example to download cache from parent,
+to avoid cold-cache start.
+
+.. code-block:: lua
+
+ local http = require('socket.http')
+ local ltn12 = require('ltn12')
+
+ local cache_size = 100*MB
+ local cache_path = '/var/cache/knot-resolver'
+ cache.open(cache_size, 'lmdb://' .. cache_path)
+ if cache.count() == 0 then
+ cache.close()
+ -- download cache from parent
+ http.request {
+ url = 'http://parent/data.mdb',
+ sink = ltn12.sink.file(io.open(cache_path .. '/data.mdb', 'w'))
+ }
+ -- reopen cache with 100M limit
+ cache.open(cache_size, 'lmdb://' .. cache_path)
+ end
+
+Helper functions
+^^^^^^^^^^^^^^^^
+Following built-in functions are useful for scripting:
+
+.. envvar:: env (table)
+
+ Retrieve environment variables.
+
+ Example:
+
+ .. code-block:: lua
+
+ env.USER -- equivalent to $USER in shell
+
+.. function:: fromjson(JSONstring)
+
+ :return: Lua representation of data in JSON string.
+
+ Example:
+
+ .. code-block:: lua
+
+ > fromjson('{"key1": "value1", "key2": {"subkey1": 1, "subkey2": 2}}')
+ [key1] => value1
+ [key2] => {
+ [subkey1] => 1
+ [subkey2] => 2
+ }
+
+
+.. function:: hostname([fqdn])
+
+ :return: Machine hostname.
+
+ If called with a parameter, it will set kresd's internal
+ hostname. If called without a parameter, it will return kresd's
+ internal hostname, or the system's POSIX hostname (see
+ gethostname(2)) if kresd's internal hostname is unset.
+
+ This also affects ephemeral (self-signed) certificates generated by kresd
+ for DNS over TLS.
+
+.. function:: package_version()
+
+ :return: Current package version as string.
+
+ Example:
+
+ .. code-block:: lua
+
+ > package_version()
+ 2.1.1
+
+.. function:: resolve(name, type[, class = kres.class.IN, options = {}, finish = nil, init = nil])
+
+ :param string name: Query name (e.g. 'com.')
+ :param number type: Query type (e.g. ``kres.type.NS``)
+ :param number class: Query class *(optional)* (e.g. ``kres.class.IN``)
+ :param strings options: Resolution options (see :c:type:`kr_qflags`)
+ :param function finish: Callback to be executed when resolution completes (e.g. `function cb (pkt, req) end`). The callback gets a packet containing the final answer and doesn't have to return anything.
+ :param function init: Callback to be executed with the :c:type:`kr_request` before resolution starts.
+ :return: boolean, ``true`` if resolution was started
+
+ The function can also be executed with a table of arguments instead. This is
+ useful if you'd like to skip some arguments, for example:
+
+ .. code-block:: lua
+
+ resolve {
+ name = 'example.com',
+ type = kres.type.AAAA,
+ init = function (req)
+ end,
+ }
+
+ Example:
+
+ .. code-block:: lua
+
+ -- Send query for root DNSKEY, ignore cache
+ resolve('.', kres.type.DNSKEY, kres.class.IN, 'NO_CACHE')
+
+ -- Query for AAAA record
+ resolve('example.com', kres.type.AAAA, kres.class.IN, 0,
+ function (pkt, req)
+ -- Check answer RCODE
+ if pkt:rcode() == kres.rcode.NOERROR then
+ -- Print matching records
+ local records = pkt:section(kres.section.ANSWER)
+ for i = 1, #records do
+ local rr = records[i]
+ if rr.type == kres.type.AAAA then
+ print ('record:', kres.rr2str(rr))
+ end
+ end
+ else
+ print ('rcode: ', pkt:rcode())
+ end
+ end)
+
+
+.. function:: tojson(object)
+
+ :return: JSON text representation of `object`.
+
+ Example:
+
+ .. code-block:: lua
+
+ > testtable = { key1 = "value1", "key2" = { subkey1 = 1, subkey2 = 2 } }
+ > tojson(testtable)
+ {"key1":"value1","key2":{"subkey1":1,"subkey2":2}}
+
+
+.. _async-events:
+
+Asynchronous events
+-------------------
+
+Lua language used in configuration file allows you to script actions upon
+various events, for example publish statistics each minute. Following example
+uses built-in function :func:`event.recurrent()` which calls user-supplied
+anonymous function:
+
+.. code-block:: lua
+
+ local ffi = require('ffi')
+ modules.load('stats')
+
+ -- log statistics every second
+ local stat_id = event.recurrent(1 * second, function(evid)
+ log_info(ffi.C.LOG_GRP_STATISTICS, table_print(stats.list()))
+ end)
+
+ -- stop printing statistics after first minute
+ event.after(1 * minute, function(evid)
+ event.cancel(stat_id)
+ end)
+
+
+Note that each scheduled event is identified by a number valid for the duration
+of the event, you may use it to cancel the event at any time.
+
+To persist state between two invocations of a function Lua uses concept called
+closures_. In the following example function ``speed_monitor()`` is a closure
+function, which provides persistent variable called ``previous``.
+
+.. code-block:: lua
+
+ local ffi = require('ffi')
+ modules.load('stats')
+
+ -- make a closure, encapsulating counter
+ function speed_monitor()
+ local previous = stats.list()
+ -- monitoring function
+ return function(evid)
+ local now = stats.list()
+ local total_increment = now['answer.total'] - previous['answer.total']
+ local slow_increment = now['answer.slow'] - previous['answer.slow']
+ if slow_increment / total_increment > 0.05 then
+ log_warn(ffi.C.LOG_GRP_STATISTICS, 'WARNING! More than 5 %% of queries was slow!')
+ end
+ previous = now -- store current value in closure
+ end
+ end
+
+ -- monitor every minute
+ local monitor_id = event.recurrent(1 * minute, speed_monitor())
+
+Another type of actionable event is activity on a file descriptor. This allows
+you to embed other event loops or monitor open files and then fire a callback
+when an activity is detected. This allows you to build persistent services
+like monitoring probes that cooperate well with the daemon internal operations.
+See :func:`event.socket()`.
+
+Filesystem watchers are possible with :func:`worker.coroutine()` and cqueues_,
+see the cqueues documentation for more information. Here is an simple example:
+
+.. code-block:: lua
+
+ local notify = require('cqueues.notify')
+ local watcher = notify.opendir('/etc')
+ watcher:add('hosts')
+
+ -- Watch changes to /etc/hosts
+ worker.coroutine(function ()
+ for flags, name in watcher:changes() do
+ for flag in notify.flags(flags) do
+ -- print information about the modified file
+ print(name, notify[flag])
+ end
+ end
+ end)
+
+.. include:: ../daemon/bindings/event.rst
+
+.. include:: ../modules/etcd/README.rst
+
+.. _closures: https://www.lua.org/pil/6.1.html
+.. _cqueues: https://25thandclement.com/~william/projects/cqueues.html
+.. _LuaRocks: https://luarocks.org/
diff --git a/daemon/session.c b/daemon/session.c
new file mode 100644
index 0000000..a1f2207
--- /dev/null
+++ b/daemon/session.c
@@ -0,0 +1,834 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#include <libknot/packet/pkt.h>
+
+#include "lib/defines.h"
+#include "daemon/session.h"
+#include "daemon/tls.h"
+#include "daemon/http.h"
+#include "daemon/worker.h"
+#include "daemon/io.h"
+#include "daemon/proxyv2.h"
+#include "lib/generic/queue.h"
+
+#define TLS_CHUNK_SIZE (16 * 1024)
+
+/* Initial max frame size: https://tools.ietf.org/html/rfc7540#section-6.5.2 */
+#define HTTP_MAX_FRAME_SIZE 16384
+
+/* Per-socket (TCP or UDP) persistent structure.
+ *
+ * In particular note that for UDP clients it's just one session (per socket)
+ * shared for all clients. For TCP/TLS it's also for the connection-specific socket,
+ * i.e one session per connection.
+ *
+ * LATER(optim.): the memory here is used a bit wastefully.
+ */
+struct session {
+ struct session_flags sflags; /**< miscellaneous flags. */
+ union kr_sockaddr peer; /**< address of peer; not for UDP clients (downstream) */
+ union kr_sockaddr sockname; /**< our local address; for UDP it may be a wildcard */
+ uv_handle_t *handle; /**< libuv handle for IO operations. */
+ uv_timer_t timeout; /**< libuv handle for timer. */
+
+ struct tls_ctx *tls_ctx; /**< server side tls-related data. */
+ struct tls_client_ctx *tls_client_ctx; /**< client side tls-related data. */
+
+ struct proxy_result *proxy; /**< PROXYv2 data for TCP. May be `NULL` if not proxied. */
+
+#if ENABLE_DOH2
+ struct http_ctx *http_ctx; /**< server side http-related data. */
+#endif
+
+ trie_t *tasks; /**< list of tasks associated with given session. */
+ queue_t(struct qr_task *) waiting; /**< list of tasks waiting for sending to upstream. */
+
+ uint8_t *wire_buf; /**< Buffer for DNS message, except for XDP. */
+ ssize_t wire_buf_size; /**< Buffer size. */
+ ssize_t wire_buf_start_idx; /**< Data start offset in wire_buf. */
+ ssize_t wire_buf_end_idx; /**< Data end offset in wire_buf. */
+ uint64_t last_activity; /**< Time of last IO activity (if any occurs).
+ * Otherwise session creation time. */
+ bool was_useful; /**< I.e. produced a DNS message at some point. */
+};
+
+static void on_session_close(uv_handle_t *handle)
+{
+ struct session *session = handle->data;
+ kr_require(session->handle == handle);
+ io_free(handle);
+}
+
+static void on_session_timer_close(uv_handle_t *timer)
+{
+ struct session *session = timer->data;
+ uv_handle_t *handle = session->handle;
+ kr_require(handle && handle->data == session);
+ kr_require(session->sflags.outgoing || handle->type == UV_TCP);
+ if (!uv_is_closing(handle)) {
+ uv_close(handle, on_session_close);
+ }
+}
+
+void session_free(struct session *session)
+{
+ if (session) {
+ session_clear(session);
+ free(session);
+ }
+}
+
+void session_clear(struct session *session)
+{
+ kr_require(session_is_empty(session));
+ if (session->handle && session->handle->type == UV_TCP) {
+ free(session->wire_buf);
+ }
+ free(session->proxy);
+#if ENABLE_DOH2
+ http_free(session->http_ctx);
+#endif
+ trie_clear(session->tasks);
+ trie_free(session->tasks);
+ queue_deinit(session->waiting);
+ tls_free(session->tls_ctx);
+ tls_client_ctx_free(session->tls_client_ctx);
+ memset(session, 0, sizeof(*session));
+}
+
+void session_close(struct session *session)
+{
+ kr_require(session_is_empty(session));
+ if (session->sflags.closing) {
+ return;
+ }
+
+ uv_handle_t *handle = session->handle;
+ io_stop_read(handle);
+ session->sflags.closing = true;
+
+ if (!uv_is_closing((uv_handle_t *)&session->timeout)) {
+ uv_timer_stop(&session->timeout);
+ if (session->tls_client_ctx) {
+ tls_client_close(session->tls_client_ctx);
+ }
+ if (session->tls_ctx) {
+ tls_close(&session->tls_ctx->c);
+ }
+
+ session->timeout.data = session;
+ uv_close((uv_handle_t *)&session->timeout, on_session_timer_close);
+ }
+}
+
+bool session_was_useful(const struct session *session)
+{
+ return session->was_useful;
+}
+
+int session_start_read(struct session *session)
+{
+ return io_start_read(session->handle);
+}
+
+int session_stop_read(struct session *session)
+{
+ return io_stop_read(session->handle);
+}
+
+int session_waitinglist_push(struct session *session, struct qr_task *task)
+{
+ queue_push(session->waiting, task);
+ worker_task_ref(task);
+ return kr_ok();
+}
+
+struct qr_task *session_waitinglist_get(const struct session *session)
+{
+ return (queue_len(session->waiting) > 0) ? (queue_head(session->waiting)) : NULL;
+}
+
+struct qr_task *session_waitinglist_pop(struct session *session, bool deref)
+{
+ struct qr_task *t = session_waitinglist_get(session);
+ queue_pop(session->waiting);
+ if (deref) {
+ worker_task_unref(t);
+ }
+ return t;
+}
+
+int session_tasklist_add(struct session *session, struct qr_task *task)
+{
+ trie_t *t = session->tasks;
+ uint16_t task_msg_id = 0;
+ const char *key = NULL;
+ size_t key_len = 0;
+ if (session->sflags.outgoing) {
+ knot_pkt_t *pktbuf = worker_task_get_pktbuf(task);
+ task_msg_id = knot_wire_get_id(pktbuf->wire);
+ key = (const char *)&task_msg_id;
+ key_len = sizeof(task_msg_id);
+ } else {
+ key = (const char *)&task;
+ key_len = sizeof(char *);
+ }
+ trie_val_t *v = trie_get_ins(t, key, key_len);
+ if (kr_fails_assert(v))
+ return kr_error(ENOMEM);
+ if (*v == NULL) {
+ *v = task;
+ worker_task_ref(task);
+ } else if (kr_fails_assert(*v == task)) {
+ return kr_error(EINVAL);
+ }
+ return kr_ok();
+}
+
+int session_tasklist_del(struct session *session, struct qr_task *task)
+{
+ trie_t *t = session->tasks;
+ uint16_t task_msg_id = 0;
+ const char *key = NULL;
+ size_t key_len = 0;
+ trie_val_t val;
+ if (session->sflags.outgoing) {
+ knot_pkt_t *pktbuf = worker_task_get_pktbuf(task);
+ task_msg_id = knot_wire_get_id(pktbuf->wire);
+ key = (const char *)&task_msg_id;
+ key_len = sizeof(task_msg_id);
+ } else {
+ key = (const char *)&task;
+ key_len = sizeof(char *);
+ }
+ int ret = trie_del(t, key, key_len, &val);
+ if (ret == KNOT_EOK) {
+ kr_require(val == task);
+ worker_task_unref(val);
+ }
+ return ret;
+}
+
+struct qr_task *session_tasklist_get_first(struct session *session)
+{
+ trie_val_t *val = trie_get_first(session->tasks, NULL, NULL);
+ return val ? (struct qr_task *) *val : NULL;
+}
+
+struct qr_task *session_tasklist_del_first(struct session *session, bool deref)
+{
+ trie_val_t val = NULL;
+ int res = trie_del_first(session->tasks, NULL, NULL, &val);
+ if (res != KNOT_EOK) {
+ val = NULL;
+ } else if (deref) {
+ worker_task_unref(val);
+ }
+ return (struct qr_task *)val;
+}
+struct qr_task* session_tasklist_del_msgid(const struct session *session, uint16_t msg_id)
+{
+ if (kr_fails_assert(session->sflags.outgoing))
+ return NULL;
+ trie_t *t = session->tasks;
+ struct qr_task *ret = NULL;
+ const char *key = (const char *)&msg_id;
+ size_t key_len = sizeof(msg_id);
+ trie_val_t val;
+ int res = trie_del(t, key, key_len, &val);
+ if (res == KNOT_EOK) {
+ if (worker_task_numrefs(val) > 1) {
+ ret = val;
+ }
+ worker_task_unref(val);
+ }
+ return ret;
+}
+
+struct qr_task* session_tasklist_find_msgid(const struct session *session, uint16_t msg_id)
+{
+ if (kr_fails_assert(session->sflags.outgoing))
+ return NULL;
+ trie_t *t = session->tasks;
+ struct qr_task *ret = NULL;
+ trie_val_t *val = trie_get_try(t, (char *)&msg_id, sizeof(msg_id));
+ if (val) {
+ ret = *val;
+ }
+ return ret;
+}
+
+struct session_flags *session_flags(struct session *session)
+{
+ return &session->sflags;
+}
+
+struct sockaddr *session_get_peer(struct session *session)
+{
+ return &session->peer.ip;
+}
+
+struct sockaddr *session_get_sockname(struct session *session)
+{
+ return &session->sockname.ip;
+}
+
+struct tls_ctx *session_tls_get_server_ctx(const struct session *session)
+{
+ return session->tls_ctx;
+}
+
+void session_tls_set_server_ctx(struct session *session, struct tls_ctx *ctx)
+{
+ session->tls_ctx = ctx;
+}
+
+struct tls_client_ctx *session_tls_get_client_ctx(const struct session *session)
+{
+ return session->tls_client_ctx;
+}
+
+void session_tls_set_client_ctx(struct session *session, struct tls_client_ctx *ctx)
+{
+ session->tls_client_ctx = ctx;
+}
+
+struct tls_common_ctx *session_tls_get_common_ctx(const struct session *session)
+{
+ struct tls_common_ctx *tls_ctx = session->sflags.outgoing ? &session->tls_client_ctx->c :
+ &session->tls_ctx->c;
+ return tls_ctx;
+}
+
+#if ENABLE_DOH2
+struct http_ctx *session_http_get_server_ctx(const struct session *session)
+{
+ return session->http_ctx;
+}
+
+void session_http_set_server_ctx(struct session *session, struct http_ctx *ctx)
+{
+ session->http_ctx = ctx;
+}
+#endif
+
+uv_handle_t *session_get_handle(struct session *session)
+{
+ return session->handle;
+}
+
+struct session *session_get(uv_handle_t *h)
+{
+ return h->data;
+}
+
+struct session *session_new(uv_handle_t *handle, bool has_tls, bool has_http)
+{
+ if (!handle) {
+ return NULL;
+ }
+ struct session *session = calloc(1, sizeof(struct session));
+ if (!session) {
+ return NULL;
+ }
+
+ queue_init(session->waiting);
+ session->tasks = trie_create(NULL);
+ if (handle->type == UV_TCP) {
+ size_t wire_buffer_size = KNOT_WIRE_MAX_PKTSIZE;
+ if (has_tls) {
+ /* When decoding large packets,
+ * gnutls gives the application chunks of size 16 kb each. */
+ wire_buffer_size += TLS_CHUNK_SIZE;
+ session->sflags.has_tls = true;
+ }
+#if ENABLE_DOH2
+ if (has_http) {
+ /* When decoding large packets,
+ * HTTP/2 frames can be up to 16 KB by default. */
+ wire_buffer_size += HTTP_MAX_FRAME_SIZE;
+ session->sflags.has_http = true;
+ }
+#endif
+ uint8_t *wire_buf = malloc(wire_buffer_size);
+ if (!wire_buf) {
+ free(session);
+ return NULL;
+ }
+ session->wire_buf = wire_buf;
+ session->wire_buf_size = wire_buffer_size;
+ } else if (handle->type == UV_UDP) {
+ /* We use the singleton buffer from worker for all UDP (!)
+ * libuv documentation doesn't really guarantee this is OK,
+ * but the implementation for unix systems does not hold
+ * the buffer (both UDP and TCP) - always makes a NON-blocking
+ * syscall that fills the buffer and immediately calls
+ * the callback, whatever the result of the operation.
+ * We still need to keep in mind to only touch the buffer
+ * in this callback... */
+ kr_require(the_worker);
+ session->wire_buf = the_worker->wire_buf;
+ session->wire_buf_size = sizeof(the_worker->wire_buf);
+ } else {
+ kr_assert(handle->type == UV_POLL/*XDP*/);
+ /* - wire_buf* are left zeroed, as they make no sense
+ * - timer is unused but OK for simplicity (server-side sessions are few)
+ */
+ }
+
+ uv_timer_init(handle->loop, &session->timeout);
+
+ session->handle = handle;
+ handle->data = session;
+ session->timeout.data = session;
+ session_touch(session);
+
+ return session;
+}
+
+size_t session_tasklist_get_len(const struct session *session)
+{
+ return trie_weight(session->tasks);
+}
+
+size_t session_waitinglist_get_len(const struct session *session)
+{
+ return queue_len(session->waiting);
+}
+
+bool session_tasklist_is_empty(const struct session *session)
+{
+ return session_tasklist_get_len(session) == 0;
+}
+
+bool session_waitinglist_is_empty(const struct session *session)
+{
+ return session_waitinglist_get_len(session) == 0;
+}
+
+bool session_is_empty(const struct session *session)
+{
+ return session_tasklist_is_empty(session) &&
+ session_waitinglist_is_empty(session);
+}
+
+bool session_has_tls(const struct session *session)
+{
+ return session->sflags.has_tls;
+}
+
+void session_set_has_tls(struct session *session, bool has_tls)
+{
+ session->sflags.has_tls = has_tls;
+}
+
+void session_waitinglist_retry(struct session *session, bool increase_timeout_cnt)
+{
+ while (!session_waitinglist_is_empty(session)) {
+ struct qr_task *task = session_waitinglist_pop(session, false);
+ if (increase_timeout_cnt) {
+ worker_task_timeout_inc(task);
+ }
+ worker_task_step(task, &session->peer.ip, NULL);
+ worker_task_unref(task);
+ }
+}
+
+void session_waitinglist_finalize(struct session *session, int status)
+{
+ while (!session_waitinglist_is_empty(session)) {
+ struct qr_task *t = session_waitinglist_pop(session, false);
+ worker_task_finalize(t, status);
+ worker_task_unref(t);
+ }
+}
+
+struct proxy_result *session_proxy_create(struct session *session)
+{
+ if (!kr_fails_assert(!session->proxy)) {
+ session->proxy = calloc(1, sizeof(struct proxy_result));
+ kr_require(session->proxy);
+ }
+
+ return session->proxy;
+}
+
+struct proxy_result *session_proxy_get(struct session *session)
+{
+ return session->proxy;
+}
+
+void session_tasklist_finalize(struct session *session, int status)
+{
+ while (session_tasklist_get_len(session) > 0) {
+ struct qr_task *t = session_tasklist_del_first(session, false);
+ kr_require(worker_task_numrefs(t) > 0);
+ worker_task_finalize(t, status);
+ worker_task_unref(t);
+ }
+}
+
+int session_tasklist_finalize_expired(struct session *session)
+{
+ int ret = 0;
+ queue_t(struct qr_task *) q;
+ uint64_t now = kr_now();
+ trie_t *t = session->tasks;
+ trie_it_t *it;
+ queue_init(q);
+ for (it = trie_it_begin(t); !trie_it_finished(it); trie_it_next(it)) {
+ trie_val_t *v = trie_it_val(it);
+ struct qr_task *task = (struct qr_task *)*v;
+ if ((now - worker_task_creation_time(task)) >= KR_RESOLVE_TIME_LIMIT) {
+ struct kr_request *req = worker_task_request(task);
+ if (!kr_fails_assert(req))
+ kr_query_inform_timeout(req, req->current_query);
+ queue_push(q, task);
+ worker_task_ref(task);
+ }
+ }
+ trie_it_free(it);
+
+ struct qr_task *task = NULL;
+ uint16_t msg_id = 0;
+ char *key = (char *)&task;
+ int32_t keylen = sizeof(struct qr_task *);
+ if (session->sflags.outgoing) {
+ key = (char *)&msg_id;
+ keylen = sizeof(msg_id);
+ }
+ while (queue_len(q) > 0) {
+ task = queue_head(q);
+ if (session->sflags.outgoing) {
+ knot_pkt_t *pktbuf = worker_task_get_pktbuf(task);
+ msg_id = knot_wire_get_id(pktbuf->wire);
+ }
+ int res = trie_del(t, key, keylen, NULL);
+ if (!worker_task_finished(task)) {
+ /* task->pending_count must be zero,
+ * but there are can be followers,
+ * so run worker_task_subreq_finalize() to ensure retrying
+ * for all the followers. */
+ worker_task_subreq_finalize(task);
+ worker_task_finalize(task, KR_STATE_FAIL);
+ }
+ if (res == KNOT_EOK) {
+ worker_task_unref(task);
+ }
+ queue_pop(q);
+ worker_task_unref(task);
+ ++ret;
+ }
+
+ queue_deinit(q);
+ return ret;
+}
+
+int session_timer_start(struct session *session, uv_timer_cb cb,
+ uint64_t timeout, uint64_t repeat)
+{
+ uv_timer_t *timer = &session->timeout;
+ // Session might be closing and get here e.g. through a late on_send callback.
+ const bool is_closing = uv_is_closing((uv_handle_t *)timer);
+ if (is_closing || kr_fails_assert(is_closing == session->sflags.closing))
+ return kr_error(EINVAL);
+
+ if (kr_fails_assert(timer->data == session))
+ return kr_error(EINVAL);
+ int ret = uv_timer_start(timer, cb, timeout, repeat);
+ if (ret != 0) {
+ uv_timer_stop(timer);
+ return kr_error(ret);
+ }
+ return kr_ok();
+}
+
+int session_timer_restart(struct session *session)
+{
+ kr_require(!uv_is_closing((uv_handle_t *)&session->timeout));
+ return uv_timer_again(&session->timeout);
+}
+
+int session_timer_stop(struct session *session)
+{
+ return uv_timer_stop(&session->timeout);
+}
+
+ssize_t session_wirebuf_consume(struct session *session, const uint8_t *data, ssize_t len)
+{
+ if (kr_fails_assert(data == &session->wire_buf[session->wire_buf_end_idx]))
+ return kr_error(EINVAL);
+ if (kr_fails_assert(len >= 0))
+ return kr_error(EINVAL);
+ if (kr_fails_assert(session->wire_buf_end_idx + len <= session->wire_buf_size))
+ return kr_error(EINVAL);
+
+ session->wire_buf_end_idx += len;
+ return len;
+}
+
+ssize_t session_wirebuf_trim(struct session *session, ssize_t len)
+{
+ if (kr_fails_assert(len >= 0))
+ return kr_error(EINVAL);
+ if (kr_fails_assert(session->wire_buf_start_idx + len <= session->wire_buf_size))
+ return kr_error(EINVAL);
+
+ session->wire_buf_start_idx += len;
+ if (session->wire_buf_start_idx > session->wire_buf_end_idx)
+ session->wire_buf_end_idx = session->wire_buf_start_idx;
+ return len;
+}
+
+knot_pkt_t *session_produce_packet(struct session *session, knot_mm_t *mm)
+{
+ session->sflags.wirebuf_error = false;
+ if (session->wire_buf_end_idx == 0) {
+ return NULL;
+ }
+
+ if (session->wire_buf_start_idx == session->wire_buf_end_idx) {
+ session->wire_buf_start_idx = 0;
+ session->wire_buf_end_idx = 0;
+ return NULL;
+ }
+
+ if (session->wire_buf_start_idx > session->wire_buf_end_idx) {
+ session->sflags.wirebuf_error = true;
+ session->wire_buf_start_idx = 0;
+ session->wire_buf_end_idx = 0;
+ return NULL;
+ }
+
+ const uv_handle_t *handle = session->handle;
+ uint8_t *msg_start = &session->wire_buf[session->wire_buf_start_idx];
+ ssize_t wirebuf_msg_data_size = session->wire_buf_end_idx - session->wire_buf_start_idx;
+ uint16_t msg_size = 0;
+
+ if (!handle) {
+ session->sflags.wirebuf_error = true;
+ return NULL;
+ } else if (handle->type == UV_TCP) {
+ if (wirebuf_msg_data_size < 2) {
+ return NULL;
+ }
+ msg_size = knot_wire_read_u16(msg_start);
+ if (msg_size >= session->wire_buf_size) {
+ session->sflags.wirebuf_error = true;
+ return NULL;
+ }
+ if (msg_size + 2 > wirebuf_msg_data_size) {
+ return NULL;
+ }
+ if (msg_size == 0) {
+ session->sflags.wirebuf_error = true;
+ return NULL;
+ }
+ msg_start += 2;
+ } else if (wirebuf_msg_data_size < UINT16_MAX) {
+ msg_size = wirebuf_msg_data_size;
+ } else {
+ session->sflags.wirebuf_error = true;
+ return NULL;
+ }
+
+ session->was_useful = true;
+ knot_pkt_t *pkt = knot_pkt_new(msg_start, msg_size, mm);
+ session->sflags.wirebuf_error = (pkt == NULL);
+ return pkt;
+}
+
+int session_discard_packet(struct session *session, const knot_pkt_t *pkt)
+{
+ uv_handle_t *handle = session->handle;
+ /* Pointer to data start in wire_buf */
+ uint8_t *wirebuf_data_start = &session->wire_buf[session->wire_buf_start_idx];
+ /* Number of data bytes in wire_buf */
+ size_t wirebuf_data_size = session->wire_buf_end_idx - session->wire_buf_start_idx;
+ /* Pointer to message start in wire_buf */
+ uint8_t *wirebuf_msg_start = wirebuf_data_start;
+ /* Number of message bytes in wire_buf.
+ * For UDP it is the same number as wirebuf_data_size. */
+ size_t wirebuf_msg_size = wirebuf_data_size;
+ /* Wire data from parsed packet. */
+ uint8_t *pkt_msg_start = pkt->wire;
+ /* Number of bytes in packet wire buffer. */
+ size_t pkt_msg_size = pkt->size;
+ if (knot_pkt_has_tsig(pkt)) {
+ pkt_msg_size += pkt->tsig_wire.len;
+ }
+
+ session->sflags.wirebuf_error = true;
+
+ if (!handle) {
+ return kr_error(EINVAL);
+ } else if (handle->type == UV_TCP) {
+ /* wire_buf contains TCP DNS message. */
+ if (kr_fails_assert(wirebuf_data_size >= 2)) {
+ /* TCP message length field isn't in buffer, must not happen. */
+ session->wire_buf_start_idx = 0;
+ session->wire_buf_end_idx = 0;
+ return kr_error(EINVAL);
+ }
+ wirebuf_msg_size = knot_wire_read_u16(wirebuf_msg_start);
+ wirebuf_msg_start += 2;
+ if (kr_fails_assert(wirebuf_msg_size + 2 <= wirebuf_data_size)) {
+ /* TCP message length field is greater then
+ * number of bytes in buffer, must not happen. */
+ session->wire_buf_start_idx = 0;
+ session->wire_buf_end_idx = 0;
+ return kr_error(EINVAL);
+ }
+ }
+
+ if (kr_fails_assert(wirebuf_msg_start == pkt_msg_start)) {
+ /* packet wirebuf must be located at the beginning
+ * of the session wirebuf, must not happen. */
+ session->wire_buf_start_idx = 0;
+ session->wire_buf_end_idx = 0;
+ return kr_error(EINVAL);
+ }
+
+ if (kr_fails_assert(wirebuf_msg_size >= pkt_msg_size)) {
+ /* Message length field is lesser then packet size,
+ * must not happen. */
+ session->wire_buf_start_idx = 0;
+ session->wire_buf_end_idx = 0;
+ return kr_error(EINVAL);
+ }
+
+ if (handle->type == UV_TCP) {
+ session->wire_buf_start_idx += wirebuf_msg_size + 2;
+ } else {
+ session->wire_buf_start_idx += pkt_msg_size;
+ }
+ session->sflags.wirebuf_error = false;
+
+ wirebuf_data_size = session->wire_buf_end_idx - session->wire_buf_start_idx;
+ if (wirebuf_data_size == 0) {
+ session_wirebuf_discard(session);
+ } else if (wirebuf_data_size < KNOT_WIRE_HEADER_SIZE) {
+ session_wirebuf_compress(session);
+ }
+
+ return kr_ok();
+}
+
+void session_wirebuf_discard(struct session *session)
+{
+ session->wire_buf_start_idx = 0;
+ session->wire_buf_end_idx = 0;
+}
+
+void session_wirebuf_compress(struct session *session)
+{
+ if (session->wire_buf_start_idx == 0) {
+ return;
+ }
+ uint8_t *wirebuf_data_start = &session->wire_buf[session->wire_buf_start_idx];
+ size_t wirebuf_data_size = session->wire_buf_end_idx - session->wire_buf_start_idx;
+ if (session->wire_buf_start_idx < wirebuf_data_size) {
+ memmove(session->wire_buf, wirebuf_data_start, wirebuf_data_size);
+ } else {
+ memcpy(session->wire_buf, wirebuf_data_start, wirebuf_data_size);
+ }
+ session->wire_buf_start_idx = 0;
+ session->wire_buf_end_idx = wirebuf_data_size;
+}
+
+bool session_wirebuf_error(struct session *session)
+{
+ return session->sflags.wirebuf_error;
+}
+
+uint8_t *session_wirebuf_get_start(struct session *session)
+{
+ return session->wire_buf;
+}
+
+size_t session_wirebuf_get_size(struct session *session)
+{
+ return session->wire_buf_size;
+}
+
+uint8_t *session_wirebuf_get_free_start(struct session *session)
+{
+ return &session->wire_buf[session->wire_buf_end_idx];
+}
+
+size_t session_wirebuf_get_free_size(struct session *session)
+{
+ return session->wire_buf_size - session->wire_buf_end_idx;
+}
+
+void session_poison(struct session *session)
+{
+ kr_asan_poison(session, sizeof(*session));
+}
+
+void session_unpoison(struct session *session)
+{
+ kr_asan_unpoison(session, sizeof(*session));
+}
+
+int session_wirebuf_process(struct session *session, struct io_comm_data *comm)
+{
+ int ret = 0;
+ if (session->wire_buf_start_idx == session->wire_buf_end_idx)
+ return ret;
+
+ size_t wirebuf_data_size = session->wire_buf_end_idx - session->wire_buf_start_idx;
+ uint32_t max_iterations = (wirebuf_data_size /
+ (KNOT_WIRE_HEADER_SIZE + KNOT_WIRE_QUESTION_MIN_SIZE)) + 1;
+ knot_pkt_t *pkt = NULL;
+
+ while (((pkt = session_produce_packet(session, &the_worker->pkt_pool)) != NULL) &&
+ (ret < max_iterations)) {
+ if (kr_fails_assert(!session_wirebuf_error(session)))
+ return -1;
+ int res = worker_submit(session, comm, NULL, NULL, pkt);
+ /* Errors from worker_submit() are intentionally *not* handled in order to
+ * ensure the entire wire buffer is processed. */
+ if (res == kr_ok())
+ ret += 1;
+ if (session_discard_packet(session, pkt) < 0) {
+ /* Packet data isn't stored in memory as expected.
+ * something went wrong, normally should not happen. */
+ break;
+ }
+ }
+
+ /* worker_submit() may cause the session to close (e.g. due to IO
+ * write error when the packet triggers an immediate answer). This is
+ * an error state, as well as any wirebuf error. */
+ if (session->sflags.closing || session_wirebuf_error(session))
+ ret = -1;
+
+ return ret;
+}
+
+void session_kill_ioreq(struct session *session, struct qr_task *task)
+{
+ if (!session || session->sflags.closing)
+ return;
+ if (kr_fails_assert(session->sflags.outgoing && session->handle))
+ return;
+ session_tasklist_del(session, task);
+ if (session->handle->type == UV_UDP) {
+ session_close(session);
+ return;
+ }
+}
+
+/** Update timestamp */
+void session_touch(struct session *session)
+{
+ session->last_activity = kr_now();
+}
+
+uint64_t session_last_activity(struct session *session)
+{
+ return session->last_activity;
+}
diff --git a/daemon/session.h b/daemon/session.h
new file mode 100644
index 0000000..603d7cb
--- /dev/null
+++ b/daemon/session.h
@@ -0,0 +1,165 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#include <libknot/packet/pkt.h>
+
+#include <stdbool.h>
+#include <uv.h>
+#include "lib/defines.h"
+
+struct qr_task;
+struct worker_ctx;
+struct session;
+struct io_comm_data;
+struct proxy_result;
+
+struct session_flags {
+ bool outgoing : 1; /**< True: to upstream; false: from a client. */
+ bool throttled : 1; /**< True: data reading from peer is temporarily stopped. */
+ bool has_tls : 1; /**< True: given session uses TLS. */
+ bool has_http : 1; /**< True: given session uses HTTP. */
+ bool connected : 1; /**< True: TCP connection is established. */
+ bool no_proxy : 1; /**< True: TCP has gotten some data - PROXYv2 header
+ * disallowed. Proxy headers are only expected at
+ * the very start of a stream. */
+ bool closing : 1; /**< True: session close sequence is in progress. */
+ bool wirebuf_error : 1; /**< True: last operation with wirebuf ended up with an error. */
+};
+
+/** Allocate new session for a libuv handle.
+ * If handle->type isn't UV_TCP, has_* parameters will be ignored. */
+struct session *session_new(uv_handle_t *handle, bool has_tls, bool has_http);
+/** Clear and free given session. */
+void session_free(struct session *session);
+/** Clear session. */
+void session_clear(struct session *session);
+/** Close session. */
+void session_close(struct session *session);
+/** Start reading from underlying libuv IO handle. */
+int session_start_read(struct session *session);
+/** Stop reading from underlying libuv IO handle. */
+int session_stop_read(struct session *session);
+
+/** List of tasks been waiting for IO. */
+/** Check if list is empty. */
+bool session_waitinglist_is_empty(const struct session *session);
+/** Add task to the end of the list. */
+int session_waitinglist_push(struct session *session, struct qr_task *task);
+/** Get the first element. */
+struct qr_task *session_waitinglist_get(const struct session *session);
+/** Get the first element and remove it from the list. */
+struct qr_task *session_waitinglist_pop(struct session *session, bool deref);
+/** Get the list length. */
+size_t session_waitinglist_get_len(const struct session *session);
+/** Retry resolution for each task in the list. */
+void session_waitinglist_retry(struct session *session, bool increase_timeout_cnt);
+/** Finalize all tasks in the list. */
+void session_waitinglist_finalize(struct session *session, int status);
+
+/** PROXYv2 data. */
+/** Creates zero-initialized PROXYv2 data for the session. Should only be called
+ * once per session. */
+struct proxy_result *session_proxy_create(struct session *session);
+/** Gets the session's PROXYv2 data, if it exists. If it does not, returns `NULL`. */
+struct proxy_result *session_proxy_get(struct session *session);
+
+/** List of tasks associated with session. */
+/** Check if list is empty. */
+bool session_tasklist_is_empty(const struct session *session);
+/** Get the first element. */
+struct qr_task *session_tasklist_get_first(struct session *session);
+/** Get the first element and remove it from the list. */
+struct qr_task *session_tasklist_del_first(struct session *session, bool deref);
+/** Get the list length. */
+size_t session_tasklist_get_len(const struct session *session);
+/** Add task to the list. */
+int session_tasklist_add(struct session *session, struct qr_task *task);
+/** Remove task from the list. */
+int session_tasklist_del(struct session *session, struct qr_task *task);
+/** Remove task with given msg_id, session_flags(session)->outgoing must be true. */
+struct qr_task* session_tasklist_del_msgid(const struct session *session, uint16_t msg_id);
+/** Find task with given msg_id */
+struct qr_task* session_tasklist_find_msgid(const struct session *session, uint16_t msg_id);
+/** Finalize all tasks in the list. */
+void session_tasklist_finalize(struct session *session, int status);
+/** Finalize all expired tasks in the list. */
+int session_tasklist_finalize_expired(struct session *session);
+
+/** Both of task lists (associated & waiting). */
+/** Check if empty. */
+bool session_is_empty(const struct session *session);
+/** Return whether session seems to have done something useful. */
+bool session_was_useful(const struct session *session);
+/** Get pointer to session flags */
+struct session_flags *session_flags(struct session *session);
+/** Get pointer to peer address. */
+struct sockaddr *session_get_peer(struct session *session);
+/** Get pointer to sockname (address of our end, not meaningful for UDP downstream). */
+struct sockaddr *session_get_sockname(struct session *session);
+/** Get pointer to server-side tls-related data. */
+struct tls_ctx *session_tls_get_server_ctx(const struct session *session);
+/** Set pointer to server-side tls-related data. */
+void session_tls_set_server_ctx(struct session *session, struct tls_ctx *ctx);
+/** Get pointer to client-side tls-related data. */
+struct tls_client_ctx *session_tls_get_client_ctx(const struct session *session);
+/** Set pointer to client-side tls-related data. */
+void session_tls_set_client_ctx(struct session *session, struct tls_client_ctx *ctx);
+/** Get pointer to that part of tls-related data which has common structure for
+ * server and client. */
+struct tls_common_ctx *session_tls_get_common_ctx(const struct session *session);
+
+#if ENABLE_DOH2
+/** Get pointer to server-side http-related data. */
+struct http_ctx *session_http_get_server_ctx(const struct session *session);
+/** Set pointer to server-side http-related data. */
+void session_http_set_server_ctx(struct session *session, struct http_ctx *ctx);
+#endif
+
+/** Get pointer to underlying libuv handle for IO operations. */
+KR_EXPORT uv_handle_t *session_get_handle(struct session *session);
+struct session *session_get(uv_handle_t *h);
+
+/** Start session timer. */
+int session_timer_start(struct session *session, uv_timer_cb cb,
+ uint64_t timeout, uint64_t repeat);
+/** Restart session timer without changing it parameters. */
+int session_timer_restart(struct session *session);
+/** Stop session timer. */
+int session_timer_stop(struct session *session);
+
+/** Get pointer to the beginning of session wirebuffer. */
+uint8_t *session_wirebuf_get_start(struct session *session);
+/** Get size of session wirebuffer. */
+size_t session_wirebuf_get_size(struct session *session);
+/** Get pointer to the beginning of free space in session wirebuffer. */
+uint8_t *session_wirebuf_get_free_start(struct session *session);
+/** Get amount of free space in session wirebuffer. */
+size_t session_wirebuf_get_free_size(struct session *session);
+/** Discard all data in session wirebuffer. */
+void session_wirebuf_discard(struct session *session);
+/** Move all data to the beginning of the buffer. */
+void session_wirebuf_compress(struct session *session);
+int session_wirebuf_process(struct session *session, struct io_comm_data *comm);
+ssize_t session_wirebuf_consume(struct session *session,
+ const uint8_t *data, ssize_t len);
+/** Trims `len` bytes from the start of the session's wire buffer.
+ * If this operation makes the buffer's end appear before the start, it gets
+ * nudged to the same position as the start. */
+ssize_t session_wirebuf_trim(struct session *session, ssize_t len);
+/** poison session structure with ASAN. */
+void session_poison(struct session *session);
+/** unpoison session structure with ASAN. */
+void session_unpoison(struct session *session);
+
+knot_pkt_t *session_produce_packet(struct session *session, knot_mm_t *mm);
+int session_discard_packet(struct session *session, const knot_pkt_t *pkt);
+
+void session_kill_ioreq(struct session *session, struct qr_task *task);
+/** Update timestamp */
+void session_touch(struct session *session);
+/** Returns either creation time or time of last IO activity if any occurs. */
+/* Used for TCP timeout calculation. */
+uint64_t session_last_activity(struct session *session);
diff --git a/daemon/tls.c b/daemon/tls.c
new file mode 100644
index 0000000..9637369
--- /dev/null
+++ b/daemon/tls.c
@@ -0,0 +1,1214 @@
+/*
+ * Copyright (C) 2016 American Civil Liberties Union (ACLU)
+ * Copyright (C) CZ.NIC, z.s.p.o
+ *
+ * Initial Author: Daniel Kahn Gillmor <dkg@fifthhorseman.net>
+ * Ondřej Surý <ondrej@sury.org>
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#include <gnutls/abstract.h>
+#include <gnutls/crypto.h>
+#include <gnutls/gnutls.h>
+#include <gnutls/x509.h>
+#include <uv.h>
+
+#include <errno.h>
+#include <stdlib.h>
+
+#include "contrib/ucw/lib.h"
+#include "contrib/base64.h"
+#include "daemon/tls.h"
+#include "daemon/worker.h"
+#include "daemon/session.h"
+
+#define EPHEMERAL_CERT_EXPIRATION_SECONDS_RENEW_BEFORE (60*60*24*7)
+#define GNUTLS_PIN_MIN_VERSION 0x030400
+
+#define VERBOSE_MSG(cl_side, ...)\
+ if (cl_side) \
+ kr_log_debug(TLSCLIENT, __VA_ARGS__); \
+ else \
+ kr_log_debug(TLS, __VA_ARGS__);
+
+/** @internal Debugging facility. */
+#ifdef DEBUG
+#define DEBUG_MSG(...) kr_log_debug(TLS, __VA_ARGS__)
+#else
+#define DEBUG_MSG(...)
+#endif
+
+struct async_write_ctx {
+ uv_write_t write_req;
+ struct tls_common_ctx *t;
+ char buf[];
+};
+
+static int client_verify_certificate(gnutls_session_t tls_session);
+
+/**
+ * Set mandatory security settings from
+ * https://tools.ietf.org/html/draft-ietf-dprive-dtls-and-tls-profiles-11#section-9
+ * Performance optimizations are not implemented at the moment.
+ */
+static int kres_gnutls_set_priority(gnutls_session_t session) {
+ static const char * const priorities =
+ "NORMAL:" /* GnuTLS defaults */
+ "-VERS-TLS1.0:-VERS-TLS1.1:" /* TLS 1.2 and higher */
+ /* Some distros by default allow features that are considered
+ * too insecure nowadays, so let's disable them explicitly. */
+ "-VERS-SSL3.0:-ARCFOUR-128:-COMP-ALL:+COMP-NULL";
+ const char *errpos = NULL;
+ int err = gnutls_priority_set_direct(session, priorities, &errpos);
+ if (err != GNUTLS_E_SUCCESS) {
+ kr_log_error(TLS, "setting priority '%s' failed at character %zd (...'%s') with %s (%d)\n",
+ priorities, errpos - priorities, errpos, gnutls_strerror_name(err), err);
+ }
+ return err;
+}
+
+static ssize_t kres_gnutls_pull(gnutls_transport_ptr_t h, void *buf, size_t len)
+{
+ struct tls_common_ctx *t = (struct tls_common_ctx *)h;
+ if (kr_fails_assert(t)) {
+ errno = EFAULT;
+ return -1;
+ }
+
+ ssize_t avail = t->nread - t->consumed;
+ DEBUG_MSG("[%s] pull wanted: %zu available: %zu\n",
+ t->client_side ? "tls_client" : "tls", len, avail);
+ if (t->nread <= t->consumed) {
+ errno = EAGAIN;
+ return -1;
+ }
+
+ ssize_t transfer = MIN(avail, len);
+ memcpy(buf, t->buf + t->consumed, transfer);
+ t->consumed += transfer;
+ return transfer;
+}
+
+static void on_write_complete(uv_write_t *req, int status)
+{
+ if (kr_fails_assert(req->data))
+ return;
+ struct async_write_ctx *async_ctx = (struct async_write_ctx *)req->data;
+ struct tls_common_ctx *t = async_ctx->t;
+ if (t->write_queue_size)
+ t->write_queue_size -= 1;
+ else
+ kr_assert(false);
+ free(req->data);
+}
+
+static bool stream_queue_is_empty(struct tls_common_ctx *t)
+{
+ return (t->write_queue_size == 0);
+}
+
+static ssize_t kres_gnutls_vec_push(gnutls_transport_ptr_t h, const giovec_t * iov, int iovcnt)
+{
+ struct tls_common_ctx *t = (struct tls_common_ctx *)h;
+ if (kr_fails_assert(t)) {
+ errno = EFAULT;
+ return -1;
+ }
+
+ if (iovcnt == 0) {
+ return 0;
+ }
+
+ if (kr_fails_assert(t->session)) {
+ errno = EFAULT;
+ return -1;
+ }
+ uv_stream_t *handle = (uv_stream_t *)session_get_handle(t->session);
+ if (kr_fails_assert(handle && handle->type == UV_TCP)) {
+ errno = EFAULT;
+ return -1;
+ }
+
+ /*
+ * This is a little bit complicated. There are two different writes:
+ * 1. Immediate, these don't need to own the buffered data and return immediately
+ * 2. Asynchronous, these need to own the buffers until the write completes
+ * In order to avoid copying the buffer, an immediate write is tried first if possible.
+ * If it isn't possible to write the data without queueing, an asynchronous write
+ * is created (with copied buffered data).
+ */
+
+ size_t total_len = 0;
+ uv_buf_t uv_buf[iovcnt];
+ for (int i = 0; i < iovcnt; ++i) {
+ uv_buf[i].base = iov[i].iov_base;
+ uv_buf[i].len = iov[i].iov_len;
+ total_len += iov[i].iov_len;
+ }
+
+ /* Try to perform the immediate write first to avoid copy */
+ int ret = 0;
+ if (stream_queue_is_empty(t)) {
+ ret = uv_try_write(handle, uv_buf, iovcnt);
+ DEBUG_MSG("[%s] push %zu <%p> = %d\n",
+ t->client_side ? "tls_client" : "tls", total_len, h, ret);
+ /* from libuv documentation -
+ uv_try_write will return either:
+ > 0: number of bytes written (can be less than the supplied buffer size).
+ < 0: negative error code (UV_EAGAIN is returned if no data can be sent immediately).
+ */
+ if (ret == total_len) {
+ /* All the data were buffered by libuv.
+ * Return. */
+ return ret;
+ }
+
+ if (ret < 0 && ret != UV_EAGAIN) {
+ /* uv_try_write() has returned error code other then UV_EAGAIN.
+ * Return. */
+ VERBOSE_MSG(t->client_side, "uv_try_write error: %s\n",
+ uv_strerror(ret));
+ ret = -1;
+ errno = EIO;
+ return ret;
+ }
+ /* Since we are here expression below is true
+ * (ret != total_len) && (ret >= 0 || ret == UV_EAGAIN)
+ * or the same
+ * (ret != total_len && ret >= 0) || (ret != total_len && ret == UV_EAGAIN)
+ * i.e. either occurs partial write or UV_EAGAIN.
+ * Proceed and copy data amount to owned memory and perform async write.
+ */
+ if (ret == UV_EAGAIN) {
+ /* No data were buffered, so we must buffer all the data. */
+ ret = 0;
+ }
+ }
+
+ /* Fallback when the queue is full, and it's not possible to do an immediate write */
+ char *p = malloc(sizeof(struct async_write_ctx) + total_len - ret);
+ if (p != NULL) {
+ struct async_write_ctx *async_ctx = (struct async_write_ctx *)p;
+ /* Save pointer to session tls context */
+ async_ctx->t = t;
+ char *buf = async_ctx->buf;
+ /* Skip data written in the partial write */
+ size_t to_skip = ret;
+ /* Copy the buffer into owned memory */
+ size_t off = 0;
+ for (int i = 0; i < iovcnt; ++i) {
+ if (to_skip > 0) {
+ /* Ignore current buffer if it's all skipped */
+ if (to_skip >= uv_buf[i].len) {
+ to_skip -= uv_buf[i].len;
+ continue;
+ }
+ /* Skip only part of the buffer */
+ uv_buf[i].base += to_skip;
+ uv_buf[i].len -= to_skip;
+ to_skip = 0;
+ }
+ memcpy(buf + off, uv_buf[i].base, uv_buf[i].len);
+ off += uv_buf[i].len;
+ }
+ uv_buf[0].base = buf;
+ uv_buf[0].len = off;
+
+ /* Create an asynchronous write request */
+ uv_write_t *write_req = &async_ctx->write_req;
+ memset(write_req, 0, sizeof(uv_write_t));
+ write_req->data = p;
+
+ /* Perform an asynchronous write with a callback */
+ if (uv_write(write_req, handle, uv_buf, 1, on_write_complete) == 0) {
+ ret = total_len;
+ t->write_queue_size += 1;
+ } else {
+ free(p);
+ VERBOSE_MSG(t->client_side, "uv_write error: %s\n",
+ uv_strerror(ret));
+ errno = EIO;
+ ret = -1;
+ }
+ } else {
+ errno = ENOMEM;
+ ret = -1;
+ }
+
+ DEBUG_MSG("[%s] queued %zu <%p> = %d\n",
+ t->client_side ? "tls_client" : "tls", total_len, h, ret);
+
+ return ret;
+}
+
+/** Perform TLS handshake and handle error codes according to the documentation.
+ * See See https://gnutls.org/manual/html_node/TLS-handshake.html#TLS-handshake
+ * The function returns kr_ok() or success or non fatal error, kr_error(EAGAIN) on blocking, or kr_error(EIO) on fatal error.
+ */
+static int tls_handshake(struct tls_common_ctx *ctx, tls_handshake_cb handshake_cb) {
+ struct session *session = ctx->session;
+
+ int err = gnutls_handshake(ctx->tls_session);
+ if (err == GNUTLS_E_SUCCESS) {
+ /* Handshake finished, return success */
+ ctx->handshake_state = TLS_HS_DONE;
+ struct sockaddr *peer = session_get_peer(session);
+ VERBOSE_MSG(ctx->client_side, "TLS handshake with %s has completed\n",
+ kr_straddr(peer));
+ if (handshake_cb) {
+ if (handshake_cb(session, 0) != kr_ok()) {
+ return kr_error(EIO);
+ }
+ }
+ } else if (err == GNUTLS_E_AGAIN) {
+ return kr_error(EAGAIN);
+ } else if (gnutls_error_is_fatal(err)) {
+ /* Fatal errors, return error as it's not recoverable */
+ VERBOSE_MSG(ctx->client_side, "gnutls_handshake failed: %s (%d)\n",
+ gnutls_strerror_name(err), err);
+ /* Notify the peer about handshake failure via an alert. */
+ gnutls_alert_send_appropriate(ctx->tls_session, err);
+ if (handshake_cb) {
+ handshake_cb(session, -1);
+ }
+ return kr_error(EIO);
+ } else if (err == GNUTLS_E_WARNING_ALERT_RECEIVED) {
+ /* Handle warning when in verbose mode */
+ const char *alert_name = gnutls_alert_get_name(gnutls_alert_get(ctx->tls_session));
+ if (alert_name != NULL) {
+ struct sockaddr *peer = session_get_peer(session);
+ VERBOSE_MSG(ctx->client_side, "TLS alert from %s received: %s\n",
+ kr_straddr(peer), alert_name);
+ }
+ }
+ return kr_ok();
+}
+
+
+struct tls_ctx *tls_new(struct worker_ctx *worker)
+{
+ if (kr_fails_assert(worker && worker->engine))
+ return NULL;
+
+ struct network *net = &worker->engine->net;
+ if (!net->tls_credentials) {
+ net->tls_credentials = tls_get_ephemeral_credentials(worker->engine);
+ if (!net->tls_credentials) {
+ kr_log_error(TLS, "X.509 credentials are missing, and ephemeral credentials failed; no TLS\n");
+ return NULL;
+ }
+ kr_log_info(TLS, "Using ephemeral TLS credentials\n");
+ tls_credentials_log_pins(net->tls_credentials);
+ }
+
+ time_t now = time(NULL);
+ if (net->tls_credentials->valid_until != GNUTLS_X509_NO_WELL_DEFINED_EXPIRATION) {
+ if (net->tls_credentials->ephemeral_servicename) {
+ /* ephemeral cert: refresh if due to expire within a week */
+ if (now >= net->tls_credentials->valid_until - EPHEMERAL_CERT_EXPIRATION_SECONDS_RENEW_BEFORE) {
+ struct tls_credentials *newcreds = tls_get_ephemeral_credentials(worker->engine);
+ if (newcreds) {
+ tls_credentials_release(net->tls_credentials);
+ net->tls_credentials = newcreds;
+ kr_log_info(TLS, "Renewed expiring ephemeral X.509 cert\n");
+ } else {
+ kr_log_error(TLS, "Failed to renew expiring ephemeral X.509 cert, using existing one\n");
+ }
+ }
+ } else {
+ /* non-ephemeral cert: warn once when certificate expires */
+ if (now >= net->tls_credentials->valid_until) {
+ kr_log_error(TLS, "X.509 certificate has expired!\n");
+ net->tls_credentials->valid_until = GNUTLS_X509_NO_WELL_DEFINED_EXPIRATION;
+ }
+ }
+ }
+
+ struct tls_ctx *tls = calloc(1, sizeof(struct tls_ctx));
+ if (tls == NULL) {
+ kr_log_error(TLS, "failed to allocate TLS context\n");
+ return NULL;
+ }
+
+ int flags = GNUTLS_SERVER | GNUTLS_NONBLOCK;
+#if GNUTLS_VERSION_NUMBER >= 0x030705
+ if (gnutls_check_version("3.7.5"))
+ flags |= GNUTLS_NO_TICKETS_TLS12;
+#endif
+ int err = gnutls_init(&tls->c.tls_session, flags);
+ if (err != GNUTLS_E_SUCCESS) {
+ kr_log_error(TLS, "gnutls_init(): %s (%d)\n", gnutls_strerror_name(err), err);
+ tls_free(tls);
+ return NULL;
+ }
+ tls->credentials = tls_credentials_reserve(net->tls_credentials);
+ err = gnutls_credentials_set(tls->c.tls_session, GNUTLS_CRD_CERTIFICATE,
+ tls->credentials->credentials);
+ if (err != GNUTLS_E_SUCCESS) {
+ kr_log_error(TLS, "gnutls_credentials_set(): %s (%d)\n", gnutls_strerror_name(err), err);
+ tls_free(tls);
+ return NULL;
+ }
+ if (kres_gnutls_set_priority(tls->c.tls_session) != GNUTLS_E_SUCCESS) {
+ tls_free(tls);
+ return NULL;
+ }
+
+ tls->c.worker = worker;
+ tls->c.client_side = false;
+
+ gnutls_transport_set_pull_function(tls->c.tls_session, kres_gnutls_pull);
+ gnutls_transport_set_vec_push_function(tls->c.tls_session, kres_gnutls_vec_push);
+ gnutls_transport_set_ptr(tls->c.tls_session, tls);
+
+ if (net->tls_session_ticket_ctx) {
+ tls_session_ticket_enable(net->tls_session_ticket_ctx,
+ tls->c.tls_session);
+ }
+
+ return tls;
+}
+
+void tls_close(struct tls_common_ctx *ctx)
+{
+ if (ctx == NULL || ctx->tls_session == NULL || kr_fails_assert(ctx->session))
+ return;
+
+ if (ctx->handshake_state == TLS_HS_DONE) {
+ const struct sockaddr *peer = session_get_peer(ctx->session);
+ VERBOSE_MSG(ctx->client_side, "closing tls connection to `%s`\n",
+ kr_straddr(peer));
+ ctx->handshake_state = TLS_HS_CLOSING;
+ gnutls_bye(ctx->tls_session, GNUTLS_SHUT_RDWR);
+ }
+}
+
+void tls_client_close(struct tls_client_ctx *ctx)
+{
+ /* Store the current session data for potential resumption of this session */
+ if (ctx->params) {
+ gnutls_free(ctx->params->session_data.data);
+ ctx->params->session_data.data = NULL;
+ ctx->params->session_data.size = 0;
+ gnutls_session_get_data2(ctx->c.tls_session, &ctx->params->session_data);
+ }
+
+ tls_close(&ctx->c);
+}
+
+void tls_free(struct tls_ctx *tls)
+{
+ if (!tls) {
+ return;
+ }
+
+ if (tls->c.tls_session) {
+ /* Don't terminate TLS connection, just tear it down */
+ gnutls_deinit(tls->c.tls_session);
+ tls->c.tls_session = NULL;
+ }
+
+ tls_credentials_release(tls->credentials);
+ free(tls);
+}
+
+int tls_write(uv_write_t *req, uv_handle_t *handle, knot_pkt_t *pkt, uv_write_cb cb)
+{
+ if (!pkt || !handle || !handle->data) {
+ return kr_error(EINVAL);
+ }
+
+ struct session *s = handle->data;
+ struct tls_common_ctx *tls_ctx = session_tls_get_common_ctx(s);
+
+ if (kr_fails_assert(tls_ctx && session_flags(s)->outgoing == tls_ctx->client_side))
+ return kr_error(EINVAL);
+
+ const uint16_t pkt_size = htons(pkt->size);
+ gnutls_session_t tls_session = tls_ctx->tls_session;
+
+ gnutls_record_cork(tls_session);
+ ssize_t count = 0;
+ if ((count = gnutls_record_send(tls_session, &pkt_size, sizeof(pkt_size)) < 0) ||
+ (count = gnutls_record_send(tls_session, pkt->wire, pkt->size) < 0)) {
+ VERBOSE_MSG(tls_ctx->client_side, "gnutls_record_send failed: %s (%zd)\n",
+ gnutls_strerror_name(count), count);
+ return kr_error(EIO);
+ }
+
+ const ssize_t submitted = sizeof(pkt_size) + pkt->size;
+
+ int ret = gnutls_record_uncork(tls_session, GNUTLS_RECORD_WAIT);
+ if (ret < 0) {
+ if (!gnutls_error_is_fatal(ret)) {
+ return kr_error(EAGAIN);
+ } else {
+ VERBOSE_MSG(tls_ctx->client_side, "gnutls_record_uncork failed: %s (%d)\n",
+ gnutls_strerror_name(ret), ret);
+ return kr_error(EIO);
+ }
+ }
+
+ if (ret != submitted) {
+ kr_log_error(TLS, "gnutls_record_uncork didn't send all data (%d of %zd)\n", ret, submitted);
+ return kr_error(EIO);
+ }
+
+ /* The data is now accepted in gnutls internal buffers, the message can be treated as sent */
+ req->handle = (uv_stream_t *)handle;
+ cb(req, 0);
+
+ return kr_ok();
+}
+
+ssize_t tls_process_input_data(struct session *s, const uint8_t *buf, ssize_t nread)
+{
+ struct tls_common_ctx *tls_p = session_tls_get_common_ctx(s);
+ if (!tls_p) {
+ return kr_error(ENOSYS);
+ }
+
+ if (kr_fails_assert(tls_p->session == s))
+ return kr_error(EINVAL);
+ const bool ok = tls_p->recv_buf == buf && nread <= sizeof(tls_p->recv_buf);
+ if (kr_fails_assert(ok)) /* don't risk overflowing the buffer if we have a mistake somewhere */
+ return kr_error(EINVAL);
+
+ tls_p->buf = buf;
+ tls_p->nread = nread >= 0 ? nread : 0;
+ tls_p->consumed = 0;
+
+ /* Ensure TLS handshake is performed before receiving data.
+ * See https://www.gnutls.org/manual/html_node/TLS-handshake.html */
+ while (tls_p->handshake_state <= TLS_HS_IN_PROGRESS) {
+ int err = tls_handshake(tls_p, tls_p->handshake_cb);
+ if (err == kr_error(EAGAIN)) {
+ return 0; /* Wait for more data */
+ } else if (err != kr_ok()) {
+ return err;
+ }
+ }
+
+ /* See https://gnutls.org/manual/html_node/Data-transfer-and-termination.html#Data-transfer-and-termination */
+ ssize_t submitted = 0;
+ uint8_t *wire_buf = session_wirebuf_get_free_start(s);
+ size_t wire_buf_size = session_wirebuf_get_free_size(s);
+ while (true) {
+ ssize_t count = gnutls_record_recv(tls_p->tls_session, wire_buf, wire_buf_size);
+ if (count == GNUTLS_E_AGAIN) {
+ if (tls_p->consumed == tls_p->nread) {
+ /* See https://www.gnutls.org/manual/html_node/Asynchronous-operation.html */
+ break; /* No more data available in this libuv buffer */
+ }
+ continue;
+ } else if (count == GNUTLS_E_INTERRUPTED) {
+ continue;
+ } else if (count == GNUTLS_E_REHANDSHAKE) {
+ /* See https://www.gnutls.org/manual/html_node/Re_002dauthentication.html */
+ struct sockaddr *peer = session_get_peer(s);
+ VERBOSE_MSG(tls_p->client_side, "TLS rehandshake with %s has started\n",
+ kr_straddr(peer));
+ tls_set_hs_state(tls_p, TLS_HS_IN_PROGRESS);
+ int err = kr_ok();
+ while (tls_p->handshake_state <= TLS_HS_IN_PROGRESS) {
+ err = tls_handshake(tls_p, tls_p->handshake_cb);
+ if (err == kr_error(EAGAIN)) {
+ break;
+ } else if (err != kr_ok()) {
+ return err;
+ }
+ }
+ if (err == kr_error(EAGAIN)) {
+ /* pull function is out of data */
+ break;
+ }
+ /* There are can be data available, check it. */
+ continue;
+ } else if (count < 0) {
+ VERBOSE_MSG(tls_p->client_side, "gnutls_record_recv failed: %s (%zd)\n",
+ gnutls_strerror_name(count), count);
+ return kr_error(EIO);
+ } else if (count == 0) {
+ break;
+ }
+ DEBUG_MSG("[%s] received %zd data\n", tls_p->client_side ? "tls_client" : "tls", count);
+ wire_buf += count;
+ wire_buf_size -= count;
+ submitted += count;
+ if (wire_buf_size == 0 && tls_p->consumed != tls_p->nread) {
+ /* session buffer is full
+ * whereas not all the data were consumed */
+ return kr_error(ENOSPC);
+ }
+ }
+ /* Here all data must be consumed. */
+ if (tls_p->consumed != tls_p->nread) {
+ /* Something went wrong, better return error.
+ * This is most probably due to gnutls_record_recv() did not
+ * consume all available network data by calling kres_gnutls_pull().
+ * TODO assess the need for buffering of data amount.
+ */
+ return kr_error(ENOSPC);
+ }
+ return submitted;
+}
+
+#if TLS_CAN_USE_PINS
+/*
+ DNS-over-TLS Out of band key-pinned authentication profile uses the
+ same form of pins as HPKP:
+
+ e.g. pin-sha256="FHkyLhvI0n70E47cJlRTamTrnYVcsYdjUGbr79CfAVI="
+
+ DNS-over-TLS OOB key-pins: https://tools.ietf.org/html/rfc7858#appendix-A
+ HPKP pin reference: https://tools.ietf.org/html/rfc7469#appendix-A
+*/
+#define PINLEN ((((32) * 8 + 4)/6) + 3 + 1)
+
+/* Compute pin_sha256 for the certificate.
+ * It may be in raw format - just TLS_SHA256_RAW_LEN bytes without termination,
+ * or it may be a base64 0-terminated string requiring up to
+ * TLS_SHA256_BASE64_BUFLEN bytes.
+ * \return error code */
+static int get_oob_key_pin(gnutls_x509_crt_t crt, char *outchar, ssize_t outchar_len, bool raw)
+{
+ if (kr_fails_assert(!raw || outchar_len >= TLS_SHA256_RAW_LEN)) {
+ return kr_error(ENOSPC);
+ /* With !raw we have check inside kr_base64_encode. */
+ }
+ gnutls_pubkey_t key;
+ int err = gnutls_pubkey_init(&key);
+ if (err != GNUTLS_E_SUCCESS) return err;
+
+ gnutls_datum_t datum = { .data = NULL, .size = 0 };
+ err = gnutls_pubkey_import_x509(key, crt, 0);
+ if (err != GNUTLS_E_SUCCESS) goto leave;
+
+ err = gnutls_pubkey_export2(key, GNUTLS_X509_FMT_DER, &datum);
+ if (err != GNUTLS_E_SUCCESS) goto leave;
+
+ char raw_pin[TLS_SHA256_RAW_LEN]; /* TMP buffer if raw == false */
+ err = gnutls_hash_fast(GNUTLS_DIG_SHA256, datum.data, datum.size,
+ (raw ? outchar : raw_pin));
+ if (err != GNUTLS_E_SUCCESS || raw/*success*/)
+ goto leave;
+ /* Convert to non-raw. */
+ err = kr_base64_encode((uint8_t *)raw_pin, sizeof(raw_pin),
+ (uint8_t *)outchar, outchar_len);
+ if (err >= 0 && err < outchar_len) {
+ err = GNUTLS_E_SUCCESS;
+ outchar[err] = '\0'; /* kr_base64_encode() doesn't do it */
+ } else if (kr_fails_assert(err < 0)) {
+ err = kr_error(ENOSPC); /* base64 fits but '\0' doesn't */
+ outchar[outchar_len - 1] = '\0';
+ }
+leave:
+ gnutls_free(datum.data);
+ gnutls_pubkey_deinit(key);
+ return err;
+}
+
+void tls_credentials_log_pins(struct tls_credentials *tls_credentials)
+{
+ for (int index = 0;; index++) {
+ gnutls_x509_crt_t *certs = NULL;
+ unsigned int cert_count = 0;
+ int err = gnutls_certificate_get_x509_crt(tls_credentials->credentials,
+ index, &certs, &cert_count);
+ if (err != GNUTLS_E_SUCCESS) {
+ if (err != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
+ kr_log_error(TLS, "could not get X.509 certificates (%d) %s\n",
+ err, gnutls_strerror_name(err));
+ }
+ return;
+ }
+
+ for (int i = 0; i < cert_count; i++) {
+ char pin[TLS_SHA256_BASE64_BUFLEN] = { 0 };
+ err = get_oob_key_pin(certs[i], pin, sizeof(pin), false);
+ if (err != GNUTLS_E_SUCCESS) {
+ kr_log_error(TLS, "could not calculate RFC 7858 OOB key-pin from cert %d (%d) %s\n",
+ i, err, gnutls_strerror_name(err));
+ } else {
+ kr_log_info(TLS, "RFC 7858 OOB key-pin (%d): pin-sha256=\"%s\"\n",
+ i, pin);
+ }
+ gnutls_x509_crt_deinit(certs[i]);
+ }
+ gnutls_free(certs);
+ }
+}
+#else
+void tls_credentials_log_pins(struct tls_credentials *tls_credentials)
+{
+ kr_log_debug(TLS, "could not calculate RFC 7858 OOB key-pin; GnuTLS 3.4.0+ required\n");
+}
+#endif
+
+static int str_replace(char **where_ptr, const char *with)
+{
+ char *copy = with ? strdup(with) : NULL;
+ if (with && !copy) {
+ return kr_error(ENOMEM);
+ }
+
+ free(*where_ptr);
+ *where_ptr = copy;
+ return kr_ok();
+}
+
+static time_t _get_end_entity_expiration(gnutls_certificate_credentials_t creds)
+{
+ gnutls_datum_t data;
+ gnutls_x509_crt_t cert = NULL;
+ int err;
+ time_t ret = GNUTLS_X509_NO_WELL_DEFINED_EXPIRATION;
+
+ if ((err = gnutls_certificate_get_crt_raw(creds, 0, 0, &data)) != GNUTLS_E_SUCCESS) {
+ kr_log_error(TLS, "failed to get cert to check expiration: (%d) %s\n",
+ err, gnutls_strerror_name(err));
+ goto done;
+ }
+ if ((err = gnutls_x509_crt_init(&cert)) != GNUTLS_E_SUCCESS) {
+ kr_log_error(TLS, "failed to initialize cert: (%d) %s\n",
+ err, gnutls_strerror_name(err));
+ goto done;
+ }
+ if ((err = gnutls_x509_crt_import(cert, &data, GNUTLS_X509_FMT_DER)) != GNUTLS_E_SUCCESS) {
+ kr_log_error(TLS, "failed to construct cert while checking expiration: (%d) %s\n",
+ err, gnutls_strerror_name(err));
+ goto done;
+ }
+
+ ret = gnutls_x509_crt_get_expiration_time (cert);
+ done:
+ /* do not free data; g_c_get_crt_raw() says to treat it as
+ * constant. */
+ gnutls_x509_crt_deinit(cert);
+ return ret;
+}
+
+int tls_certificate_set(struct network *net, const char *tls_cert, const char *tls_key)
+{
+ if (!net) {
+ return kr_error(EINVAL);
+ }
+
+ struct tls_credentials *tls_credentials = calloc(1, sizeof(*tls_credentials));
+ if (tls_credentials == NULL) {
+ return kr_error(ENOMEM);
+ }
+
+ int err = 0;
+ if ((err = gnutls_certificate_allocate_credentials(&tls_credentials->credentials)) != GNUTLS_E_SUCCESS) {
+ kr_log_error(TLS, "gnutls_certificate_allocate_credentials() failed: (%d) %s\n",
+ err, gnutls_strerror_name(err));
+ tls_credentials_free(tls_credentials);
+ return kr_error(ENOMEM);
+ }
+ if ((err = gnutls_certificate_set_x509_system_trust(tls_credentials->credentials)) < 0) {
+ if (err != GNUTLS_E_UNIMPLEMENTED_FEATURE) {
+ kr_log_warning(TLS, "warning: gnutls_certificate_set_x509_system_trust() failed: (%d) %s\n",
+ err, gnutls_strerror_name(err));
+ tls_credentials_free(tls_credentials);
+ return err;
+ }
+ }
+
+ if ((str_replace(&tls_credentials->tls_cert, tls_cert) != 0) ||
+ (str_replace(&tls_credentials->tls_key, tls_key) != 0)) {
+ tls_credentials_free(tls_credentials);
+ return kr_error(ENOMEM);
+ }
+
+ if ((err = gnutls_certificate_set_x509_key_file(tls_credentials->credentials,
+ tls_cert, tls_key, GNUTLS_X509_FMT_PEM)) != GNUTLS_E_SUCCESS) {
+ tls_credentials_free(tls_credentials);
+ kr_log_error(TLS, "gnutls_certificate_set_x509_key_file(%s,%s) failed: %d (%s)\n",
+ tls_cert, tls_key, err, gnutls_strerror_name(err));
+ return kr_error(EINVAL);
+ }
+ /* record the expiration date: */
+ tls_credentials->valid_until = _get_end_entity_expiration(tls_credentials->credentials);
+
+ /* Exchange the x509 credentials */
+ struct tls_credentials *old_credentials = net->tls_credentials;
+
+ /* Start using the new x509_credentials */
+ net->tls_credentials = tls_credentials;
+ tls_credentials_log_pins(net->tls_credentials);
+
+ if (old_credentials) {
+ err = tls_credentials_release(old_credentials);
+ if (err != kr_error(EBUSY)) {
+ return err;
+ }
+ }
+
+ return kr_ok();
+}
+
+struct tls_credentials *tls_credentials_reserve(struct tls_credentials *tls_credentials) {
+ if (!tls_credentials) {
+ return NULL;
+ }
+ tls_credentials->count++;
+ return tls_credentials;
+}
+
+int tls_credentials_release(struct tls_credentials *tls_credentials) {
+ if (!tls_credentials) {
+ return kr_error(EINVAL);
+ }
+ if (--tls_credentials->count < 0) {
+ tls_credentials_free(tls_credentials);
+ } else {
+ return kr_error(EBUSY);
+ }
+ return kr_ok();
+}
+
+void tls_credentials_free(struct tls_credentials *tls_credentials) {
+ if (!tls_credentials) {
+ return;
+ }
+
+ if (tls_credentials->credentials) {
+ gnutls_certificate_free_credentials(tls_credentials->credentials);
+ }
+ if (tls_credentials->tls_cert) {
+ free(tls_credentials->tls_cert);
+ }
+ if (tls_credentials->tls_key) {
+ free(tls_credentials->tls_key);
+ }
+ if (tls_credentials->ephemeral_servicename) {
+ free(tls_credentials->ephemeral_servicename);
+ }
+ free(tls_credentials);
+}
+
+void tls_client_param_unref(tls_client_param_t *entry)
+{
+ if (!entry || kr_fails_assert(entry->refs)) return;
+ --(entry->refs);
+ if (entry->refs) return;
+
+ DEBUG_MSG("freeing TLS parameters %p\n", (void *)entry);
+
+ for (int i = 0; i < entry->ca_files.len; ++i) {
+ free_const(entry->ca_files.at[i]);
+ }
+ array_clear(entry->ca_files);
+
+ free_const(entry->hostname);
+
+ for (int i = 0; i < entry->pins.len; ++i) {
+ free_const(entry->pins.at[i]);
+ }
+ array_clear(entry->pins);
+
+ if (entry->credentials) {
+ gnutls_certificate_free_credentials(entry->credentials);
+ }
+
+ if (entry->session_data.data) {
+ gnutls_free(entry->session_data.data);
+ }
+
+ free(entry);
+}
+static int param_free(void **param, void *null)
+{
+ if (kr_fails_assert(param && *param))
+ return -1;
+ tls_client_param_unref(*param);
+ return 0;
+}
+void tls_client_params_free(tls_client_params_t *params)
+{
+ if (!params) return;
+ trie_apply(params, param_free, NULL);
+ trie_free(params);
+}
+
+tls_client_param_t * tls_client_param_new()
+{
+ tls_client_param_t *e = calloc(1, sizeof(*e));
+ if (kr_fails_assert(e))
+ return NULL;
+ /* Note: those array_t don't need further initialization. */
+ e->refs = 1;
+ int ret = gnutls_certificate_allocate_credentials(&e->credentials);
+ if (ret != GNUTLS_E_SUCCESS) {
+ kr_log_error(TLSCLIENT, "error: gnutls_certificate_allocate_credentials() fails (%s)\n",
+ gnutls_strerror_name(ret));
+ free(e);
+ return NULL;
+ }
+ gnutls_certificate_set_verify_function(e->credentials, client_verify_certificate);
+ return e;
+}
+
+/**
+ * Convert an IP address and port number to binary key.
+ *
+ * \precond buffer \param key must have sufficient size
+ * \param addr[in]
+ * \param len[out] output length
+ * \param key[out] output buffer
+ */
+static bool construct_key(const union kr_sockaddr *addr, uint32_t *len, char *key)
+{
+ switch (addr->ip.sa_family) {
+ case AF_INET:
+ memcpy(key, &addr->ip4.sin_port, sizeof(addr->ip4.sin_port));
+ memcpy(key + sizeof(addr->ip4.sin_port), &addr->ip4.sin_addr,
+ sizeof(addr->ip4.sin_addr));
+ *len = sizeof(addr->ip4.sin_port) + sizeof(addr->ip4.sin_addr);
+ return true;
+ case AF_INET6:
+ memcpy(key, &addr->ip6.sin6_port, sizeof(addr->ip6.sin6_port));
+ memcpy(key + sizeof(addr->ip6.sin6_port), &addr->ip6.sin6_addr,
+ sizeof(addr->ip6.sin6_addr));
+ *len = sizeof(addr->ip6.sin6_port) + sizeof(addr->ip6.sin6_addr);
+ return true;
+ default:
+ kr_assert(!EINVAL);
+ return false;
+ }
+}
+tls_client_param_t ** tls_client_param_getptr(tls_client_params_t **params,
+ const struct sockaddr *addr, bool do_insert)
+{
+ if (kr_fails_assert(params && addr))
+ return NULL;
+ /* We accept NULL for empty map; ensure the map exists if needed. */
+ if (!*params) {
+ if (!do_insert) return NULL;
+ *params = trie_create(NULL);
+ if (kr_fails_assert(*params))
+ return NULL;
+ }
+ /* Construct the key. */
+ const union kr_sockaddr *ia = (const union kr_sockaddr *)addr;
+ char key[sizeof(ia->ip6.sin6_port) + sizeof(ia->ip6.sin6_addr)];
+ uint32_t len;
+ if (!construct_key(ia, &len, key))
+ return NULL;
+ /* Get the entry. */
+ return (tls_client_param_t **)
+ (do_insert ? trie_get_ins : trie_get_try)(*params, key, len);
+}
+
+int tls_client_param_remove(tls_client_params_t *params, const struct sockaddr *addr)
+{
+ const union kr_sockaddr *ia = (const union kr_sockaddr *)addr;
+ char key[sizeof(ia->ip6.sin6_port) + sizeof(ia->ip6.sin6_addr)];
+ uint32_t len;
+ if (!construct_key(ia, &len, key))
+ return kr_error(EINVAL);
+ trie_val_t param_ptr;
+ int ret = trie_del(params, key, len, &param_ptr);
+ if (ret != KNOT_EOK)
+ return kr_error(ret);
+ tls_client_param_unref(param_ptr);
+ return kr_ok();
+}
+
+/**
+ * Verify that at least one certificate in the certificate chain matches
+ * at least one certificate pin in the non-empty params->pins array.
+ * \returns GNUTLS_E_SUCCESS if pin matches, any other value is an error
+ */
+static int client_verify_pin(const unsigned int cert_list_size,
+ const gnutls_datum_t *cert_list,
+ tls_client_param_t *params)
+{
+ if (kr_fails_assert(params->pins.len > 0))
+ return GNUTLS_E_CERTIFICATE_ERROR;
+#if TLS_CAN_USE_PINS
+ for (int i = 0; i < cert_list_size; i++) {
+ gnutls_x509_crt_t cert;
+ int ret = gnutls_x509_crt_init(&cert);
+ if (ret != GNUTLS_E_SUCCESS) {
+ return ret;
+ }
+
+ ret = gnutls_x509_crt_import(cert, &cert_list[i], GNUTLS_X509_FMT_DER);
+ if (ret != GNUTLS_E_SUCCESS) {
+ gnutls_x509_crt_deinit(cert);
+ return ret;
+ }
+
+ #ifdef DEBUG
+ if (kr_log_is_debug(TLS, NULL)) {
+ char pin_base64[TLS_SHA256_BASE64_BUFLEN];
+ /* DEBUG: additionally compute and print the base64 pin.
+ * Not very efficient, but that's OK for DEBUG. */
+ ret = get_oob_key_pin(cert, pin_base64, sizeof(pin_base64), false);
+ if (ret == GNUTLS_E_SUCCESS) {
+ DEBUG_MSG("[tls_client] received pin: %s\n", pin_base64);
+ } else {
+ DEBUG_MSG("[tls_client] failed to convert received pin\n");
+ /* Now we hope that `ret` below can't differ. */
+ }
+ }
+ #endif
+ char cert_pin[TLS_SHA256_RAW_LEN];
+ /* Get raw pin and compare. */
+ ret = get_oob_key_pin(cert, cert_pin, sizeof(cert_pin), true);
+ gnutls_x509_crt_deinit(cert);
+ if (ret != GNUTLS_E_SUCCESS) {
+ return ret;
+ }
+ for (size_t j = 0; j < params->pins.len; ++j) {
+ const uint8_t *pin = params->pins.at[j];
+ if (memcmp(cert_pin, pin, TLS_SHA256_RAW_LEN) != 0)
+ continue; /* mismatch */
+ DEBUG_MSG("[tls_client] matched a configured pin no. %zd\n", j);
+ return GNUTLS_E_SUCCESS;
+ }
+ DEBUG_MSG("[tls_client] none of %zd configured pin(s) matched\n",
+ params->pins.len);
+ }
+
+ kr_log_error(TLSCLIENT, "no pin matched: %zu pins * %d certificates\n",
+ params->pins.len, cert_list_size);
+ return GNUTLS_E_CERTIFICATE_ERROR;
+
+#else /* TLS_CAN_USE_PINS */
+ kr_log_error(TLSCLIENT, "internal inconsistency: TLS_CAN_USE_PINS\n");
+ kr_assert(false);
+ return GNUTLS_E_CERTIFICATE_ERROR;
+#endif
+}
+
+/**
+ * Verify that \param tls_session contains a valid X.509 certificate chain
+ * with given hostname.
+ *
+ * \returns GNUTLS_E_SUCCESS if certificate chain is valid, any other value is an error
+ */
+static int client_verify_certchain(gnutls_session_t tls_session, const char *hostname)
+{
+ if (kr_fails_assert(hostname)) {
+ kr_log_error(TLSCLIENT, "internal config inconsistency: no hostname set\n");
+ return GNUTLS_E_CERTIFICATE_ERROR;
+ }
+
+ unsigned int status;
+ int ret = gnutls_certificate_verify_peers3(tls_session, hostname, &status);
+ if ((ret == GNUTLS_E_SUCCESS) && (status == 0)) {
+ return GNUTLS_E_SUCCESS;
+ }
+
+ if (ret == GNUTLS_E_SUCCESS) {
+ gnutls_datum_t msg;
+ ret = gnutls_certificate_verification_status_print(
+ status, gnutls_certificate_type_get(tls_session), &msg, 0);
+ if (ret == GNUTLS_E_SUCCESS) {
+ kr_log_error(TLSCLIENT, "failed to verify peer certificate: "
+ "%s\n", msg.data);
+ gnutls_free(msg.data);
+ } else {
+ kr_log_error(TLSCLIENT, "failed to verify peer certificate: "
+ "unable to print reason: %s (%s)\n",
+ gnutls_strerror(ret), gnutls_strerror_name(ret));
+ } /* gnutls_certificate_verification_status_print end */
+ } else {
+ kr_log_error(TLSCLIENT, "failed to verify peer certificate: "
+ "gnutls_certificate_verify_peers3 error: %s (%s)\n",
+ gnutls_strerror(ret), gnutls_strerror_name(ret));
+ } /* gnutls_certificate_verify_peers3 end */
+ return GNUTLS_E_CERTIFICATE_ERROR;
+}
+
+/**
+ * Verify that actual TLS security parameters of \param tls_session
+ * match requirements provided by user in tls_session->params.
+ * \returns GNUTLS_E_SUCCESS if requirements were met, any other value is an error
+ */
+static int client_verify_certificate(gnutls_session_t tls_session)
+{
+ struct tls_client_ctx *ctx = gnutls_session_get_ptr(tls_session);
+ if (kr_fails_assert(ctx->params))
+ return GNUTLS_E_CERTIFICATE_ERROR;
+
+ if (ctx->params->insecure) {
+ return GNUTLS_E_SUCCESS;
+ }
+
+ gnutls_certificate_type_t cert_type = gnutls_certificate_type_get(tls_session);
+ if (cert_type != GNUTLS_CRT_X509) {
+ kr_log_error(TLSCLIENT, "invalid certificate type %i has been received\n",
+ cert_type);
+ return GNUTLS_E_CERTIFICATE_ERROR;
+ }
+ unsigned int cert_list_size = 0;
+ const gnutls_datum_t *cert_list =
+ gnutls_certificate_get_peers(tls_session, &cert_list_size);
+ if (cert_list == NULL || cert_list_size == 0) {
+ kr_log_error(TLSCLIENT, "empty certificate list\n");
+ return GNUTLS_E_CERTIFICATE_ERROR;
+ }
+
+ if (ctx->params->pins.len > 0)
+ /* check hash of the certificate but ignore everything else */
+ return client_verify_pin(cert_list_size, cert_list, ctx->params);
+ else
+ return client_verify_certchain(ctx->c.tls_session, ctx->params->hostname);
+}
+
+struct tls_client_ctx *tls_client_ctx_new(tls_client_param_t *entry,
+ struct worker_ctx *worker)
+{
+ struct tls_client_ctx *ctx = calloc(1, sizeof (struct tls_client_ctx));
+ if (!ctx) {
+ return NULL;
+ }
+ unsigned int flags = GNUTLS_CLIENT | GNUTLS_NONBLOCK
+#ifdef GNUTLS_ENABLE_FALSE_START
+ | GNUTLS_ENABLE_FALSE_START
+#endif
+ ;
+#if GNUTLS_VERSION_NUMBER >= 0x030705
+ if (gnutls_check_version("3.7.5"))
+ flags |= GNUTLS_NO_TICKETS_TLS12;
+#endif
+ int ret = gnutls_init(&ctx->c.tls_session, flags);
+ if (ret != GNUTLS_E_SUCCESS) {
+ tls_client_ctx_free(ctx);
+ return NULL;
+ }
+
+ ret = kres_gnutls_set_priority(ctx->c.tls_session);
+ if (ret != GNUTLS_E_SUCCESS) {
+ tls_client_ctx_free(ctx);
+ return NULL;
+ }
+
+ /* Must take a reference on parameters as the credentials are owned by it
+ * and must not be freed while the session is active. */
+ ++(entry->refs);
+ ctx->params = entry;
+
+ ret = gnutls_credentials_set(ctx->c.tls_session, GNUTLS_CRD_CERTIFICATE,
+ entry->credentials);
+ if (ret == GNUTLS_E_SUCCESS && entry->hostname) {
+ ret = gnutls_server_name_set(ctx->c.tls_session, GNUTLS_NAME_DNS,
+ entry->hostname, strlen(entry->hostname));
+ kr_log_debug(TLSCLIENT, "set hostname, ret = %d\n", ret);
+ } else if (!entry->hostname) {
+ kr_log_debug(TLSCLIENT, "no hostname\n");
+ }
+ if (ret != GNUTLS_E_SUCCESS) {
+ tls_client_ctx_free(ctx);
+ return NULL;
+ }
+
+ ctx->c.worker = worker;
+ ctx->c.client_side = true;
+
+ gnutls_transport_set_pull_function(ctx->c.tls_session, kres_gnutls_pull);
+ gnutls_transport_set_vec_push_function(ctx->c.tls_session, kres_gnutls_vec_push);
+ gnutls_transport_set_ptr(ctx->c.tls_session, ctx);
+ return ctx;
+}
+
+void tls_client_ctx_free(struct tls_client_ctx *ctx)
+{
+ if (ctx == NULL) {
+ return;
+ }
+
+ if (ctx->c.tls_session != NULL) {
+ gnutls_deinit(ctx->c.tls_session);
+ ctx->c.tls_session = NULL;
+ }
+
+ /* Must decrease the refcount for referenced parameters */
+ tls_client_param_unref(ctx->params);
+
+ free (ctx);
+}
+
+int tls_pull_timeout_func(gnutls_transport_ptr_t h, unsigned int ms)
+{
+ struct tls_common_ctx *t = (struct tls_common_ctx *)h;
+ if (kr_fails_assert(t)) {
+ errno = EFAULT;
+ return -1;
+ }
+ ssize_t avail = t->nread - t->consumed;
+ DEBUG_MSG("[%s] timeout check: available: %zu\n",
+ t->client_side ? "tls_client" : "tls", avail);
+ if (avail <= 0) {
+ errno = EAGAIN;
+ return -1;
+ }
+ return avail;
+}
+
+int tls_client_connect_start(struct tls_client_ctx *client_ctx,
+ struct session *session,
+ tls_handshake_cb handshake_cb)
+{
+ if (session == NULL || client_ctx == NULL)
+ return kr_error(EINVAL);
+
+ if (kr_fails_assert(session_flags(session)->outgoing && session_get_handle(session)->type == UV_TCP))
+ return kr_error(EINVAL);
+
+ struct tls_common_ctx *ctx = &client_ctx->c;
+
+ gnutls_session_set_ptr(ctx->tls_session, client_ctx);
+ gnutls_handshake_set_timeout(ctx->tls_session, ctx->worker->engine->net.tcp.tls_handshake_timeout);
+ gnutls_transport_set_pull_timeout_function(ctx->tls_session, tls_pull_timeout_func);
+ session_tls_set_client_ctx(session, client_ctx);
+ ctx->handshake_cb = handshake_cb;
+ ctx->handshake_state = TLS_HS_IN_PROGRESS;
+ ctx->session = session;
+
+ tls_client_param_t *tls_params = client_ctx->params;
+ if (tls_params->session_data.data != NULL) {
+ gnutls_session_set_data(ctx->tls_session, tls_params->session_data.data,
+ tls_params->session_data.size);
+ }
+
+ /* See https://www.gnutls.org/manual/html_node/Asynchronous-operation.html */
+ while (ctx->handshake_state <= TLS_HS_IN_PROGRESS) {
+ int ret = tls_handshake(ctx, handshake_cb);
+ if (ret != kr_ok()) {
+ return ret;
+ }
+ }
+ return kr_ok();
+}
+
+tls_hs_state_t tls_get_hs_state(const struct tls_common_ctx *ctx)
+{
+ return ctx->handshake_state;
+}
+
+int tls_set_hs_state(struct tls_common_ctx *ctx, tls_hs_state_t state)
+{
+ if (state >= TLS_HS_LAST) {
+ return kr_error(EINVAL);
+ }
+ ctx->handshake_state = state;
+ return kr_ok();
+}
+
+int tls_client_ctx_set_session(struct tls_client_ctx *ctx, struct session *session)
+{
+ if (!ctx) {
+ return kr_error(EINVAL);
+ }
+ ctx->c.session = session;
+ return kr_ok();
+}
+
+#undef DEBUG_MSG
+#undef VERBOSE_MSG
diff --git a/daemon/tls.h b/daemon/tls.h
new file mode 100644
index 0000000..76985d6
--- /dev/null
+++ b/daemon/tls.h
@@ -0,0 +1,235 @@
+/* Copyright (C) 2016 American Civil Liberties Union (ACLU)
+ * Copyright (C) CZ.NIC, z.s.p.o
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#include <uv.h>
+#include <gnutls/gnutls.h>
+#include <libknot/packet/pkt.h>
+#include "lib/defines.h"
+#include "lib/generic/array.h"
+#include "lib/generic/trie.h"
+#include "lib/utils.h"
+
+#define MAX_TLS_PADDING KR_EDNS_PAYLOAD
+#define TLS_MAX_UNCORK_RETRIES 100
+
+/* rfc 5476, 7.3 - handshake Protocol overview
+ * https://tools.ietf.org/html/rfc5246#page-33
+ * Message flow for a full handshake (only mandatory messages)
+ * ClientHello -------->
+ ServerHello
+ <-------- ServerHelloDone
+ ClientKeyExchange
+ Finished -------->
+ <-------- Finished
+ *
+ * See also https://blog.cloudflare.com/keyless-ssl-the-nitty-gritty-technical-details/
+ * So it takes 2 RTT.
+ * As we use session tickets, there are additional messages, add one RTT mode.
+ */
+ #define TLS_MAX_HANDSHAKE_TIME (KR_CONN_RTT_MAX * 3)
+
+/** Transport session (opaque). */
+struct session;
+
+struct tls_ctx;
+struct tls_client_ctx;
+struct tls_credentials {
+ int count;
+ char *tls_cert;
+ char *tls_key;
+ gnutls_certificate_credentials_t credentials;
+ time_t valid_until;
+ char *ephemeral_servicename;
+};
+
+
+#define TLS_SHA256_RAW_LEN 32 /* gnutls_hash_get_len(GNUTLS_DIG_SHA256) */
+/** Required buffer length for pin_sha256, including the zero terminator. */
+#define TLS_SHA256_BASE64_BUFLEN (((TLS_SHA256_RAW_LEN * 8 + 4) / 6) + 3 + 1)
+
+#if GNUTLS_VERSION_NUMBER >= 0x030400
+ #define TLS_CAN_USE_PINS 1
+#else
+ #define TLS_CAN_USE_PINS 0
+#endif
+
+
+/** TLS authentication parameters for a single address-port pair. */
+typedef struct {
+ uint32_t refs; /**< Reference count; consider TLS sessions in progress. */
+ bool insecure; /**< Use no authentication. */
+ const char *hostname; /**< Server name for SNI and certificate check, lowercased. */
+ array_t(const char *) ca_files; /**< Paths to certificate files; not really used. */
+ array_t(const uint8_t *) pins; /**< Certificate pins as raw unterminated strings.*/
+ gnutls_certificate_credentials_t credentials; /**< CA creds. in gnutls format. */
+ gnutls_datum_t session_data; /**< Session-resumption data gets stored here. */
+} tls_client_param_t;
+/** Holds configuration for TLS authentication for all potential servers.
+ * Special case: NULL pointer also means empty. */
+typedef trie_t tls_client_params_t;
+
+/** Get a pointer-to-pointer to TLS auth params.
+ * If it didn't exist, it returns NULL (if !do_insert) or pointer to NULL. */
+tls_client_param_t ** tls_client_param_getptr(tls_client_params_t **params,
+ const struct sockaddr *addr, bool do_insert);
+
+/** Get a pointer to TLS auth params or NULL. */
+static inline tls_client_param_t *
+ tls_client_param_get(tls_client_params_t *params, const struct sockaddr *addr)
+{
+ tls_client_param_t **pe = tls_client_param_getptr(&params, addr, false);
+ return pe ? *pe : NULL;
+}
+
+/** Allocate and initialize the structure (with ->ref = 1). */
+tls_client_param_t * tls_client_param_new();
+/** Reference-counted free(); any inside data is freed alongside. */
+void tls_client_param_unref(tls_client_param_t *entry);
+
+int tls_client_param_remove(tls_client_params_t *params, const struct sockaddr *addr);
+/** Free TLS authentication parameters. */
+void tls_client_params_free(tls_client_params_t *params);
+
+
+struct worker_ctx;
+struct qr_task;
+struct network;
+struct engine;
+
+typedef enum tls_client_hs_state {
+ TLS_HS_NOT_STARTED = 0,
+ TLS_HS_IN_PROGRESS,
+ TLS_HS_DONE,
+ TLS_HS_CLOSING,
+ TLS_HS_LAST
+} tls_hs_state_t;
+
+typedef int (*tls_handshake_cb) (struct session *session, int status);
+
+
+struct tls_common_ctx {
+ bool client_side;
+ gnutls_session_t tls_session;
+ tls_hs_state_t handshake_state;
+ struct session *session;
+ /* for reading from the network */
+ const uint8_t *buf;
+ ssize_t nread;
+ ssize_t consumed;
+ uint8_t recv_buf[16384];
+ tls_handshake_cb handshake_cb;
+ struct worker_ctx *worker;
+ size_t write_queue_size;
+};
+
+struct tls_ctx {
+ /*
+ * Since pointer to tls_ctx needs to be casted
+ * to tls_ctx_common in some functions,
+ * this field must be always at first position
+ */
+ struct tls_common_ctx c;
+ struct tls_credentials *credentials;
+};
+
+struct tls_client_ctx {
+ /*
+ * Since pointer to tls_client_ctx needs to be casted
+ * to tls_ctx_common in some functions,
+ * this field must be always at first position
+ */
+ struct tls_common_ctx c;
+ tls_client_param_t *params; /**< It's reference-counted. */
+};
+
+/*! Create an empty TLS context in query context */
+struct tls_ctx* tls_new(struct worker_ctx *worker);
+
+/*! Close a TLS context (call gnutls_bye()) */
+void tls_close(struct tls_common_ctx *ctx);
+
+/*! Close a TLS client context (call gnutls_bye()), storing its session data
+ * for potential resumption. */
+void tls_client_close(struct tls_client_ctx *ctx);
+
+/*! Release a TLS context */
+void tls_free(struct tls_ctx* tls);
+
+/*! Push new data to TLS context for sending */
+int tls_write(uv_write_t *req, uv_handle_t* handle, knot_pkt_t * pkt, uv_write_cb cb);
+
+/*! Unwrap incoming data from a TLS stream and pass them to TCP session.
+ * @return the number of newly-completed requests (>=0) or an error code
+ */
+ssize_t tls_process_input_data(struct session *s, const uint8_t *buf, ssize_t nread);
+
+/*! Set TLS certificate and key from files. */
+int tls_certificate_set(struct network *net, const char *tls_cert, const char *tls_key);
+
+/*! Borrow TLS credentials for context. */
+struct tls_credentials *tls_credentials_reserve(struct tls_credentials *tls_credentials);
+
+/*! Release TLS credentials for context (decrements refcount or frees). */
+int tls_credentials_release(struct tls_credentials *tls_credentials);
+
+/*! Free TLS credentials, must not be called if it holds positive refcount. */
+void tls_credentials_free(struct tls_credentials *tls_credentials);
+
+/*! Log DNS-over-TLS OOB key-pin form of current credentials:
+ * https://tools.ietf.org/html/rfc7858#appendix-A */
+void tls_credentials_log_pins(struct tls_credentials *tls_credentials);
+
+/*! Generate new ephemeral TLS credentials. */
+struct tls_credentials * tls_get_ephemeral_credentials(struct engine *engine);
+
+/*! Get TLS handshake state. */
+tls_hs_state_t tls_get_hs_state(const struct tls_common_ctx *ctx);
+
+/*! Set TLS handshake state. */
+int tls_set_hs_state(struct tls_common_ctx *ctx, tls_hs_state_t state);
+
+
+/*! Allocate new client TLS context */
+struct tls_client_ctx *tls_client_ctx_new(tls_client_param_t *entry,
+ struct worker_ctx *worker);
+
+/*! Free client TLS context */
+void tls_client_ctx_free(struct tls_client_ctx *ctx);
+
+int tls_client_connect_start(struct tls_client_ctx *client_ctx,
+ struct session *session,
+ tls_handshake_cb handshake_cb);
+
+int tls_client_ctx_set_session(struct tls_client_ctx *ctx, struct session *session);
+
+
+/* Session tickets, server side. Implementation in ./tls_session_ticket-srv.c */
+
+/*! Opaque struct used by tls_session_ticket_* functions. */
+struct tls_session_ticket_ctx;
+
+/*! Suggested maximum reasonable secret length. */
+#define TLS_SESSION_TICKET_SECRET_MAX_LEN 1024
+
+/*! Create a session ticket context and initialize it (secret gets copied inside).
+ *
+ * Passing zero-length secret implies using a random key, i.e. not synchronized
+ * between multiple instances.
+ *
+ * Beware that knowledge of the secret (if nonempty) breaks forward secrecy,
+ * so you should rotate the secret regularly and securely erase all past secrets.
+ * With TLS < 1.3 it's probably too risky to set nonempty secret.
+ */
+struct tls_session_ticket_ctx * tls_session_ticket_ctx_create(
+ uv_loop_t *loop, const char *secret, size_t secret_len);
+
+/*! Try to enable session tickets for a server session. */
+void tls_session_ticket_enable(struct tls_session_ticket_ctx *ctx, gnutls_session_t session);
+
+/*! Free all resources of the session ticket context. NULL is accepted as well. */
+void tls_session_ticket_ctx_destroy(struct tls_session_ticket_ctx *ctx);
+
diff --git a/daemon/tls_ephemeral_credentials.c b/daemon/tls_ephemeral_credentials.c
new file mode 100644
index 0000000..48e8d4a
--- /dev/null
+++ b/daemon/tls_ephemeral_credentials.c
@@ -0,0 +1,237 @@
+/*
+ * Copyright (C) 2016 American Civil Liberties Union (ACLU)
+ * Copyright (C) CZ.NIC, z.s.p.o.
+ *
+ * Initial Author: Daniel Kahn Gillmor <dkg@fifthhorseman.net>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#include <sys/file.h>
+#include <unistd.h>
+#include <gnutls/gnutls.h>
+#include <gnutls/x509.h>
+#include <gnutls/crypto.h>
+
+#include "daemon/engine.h"
+#include "daemon/tls.h"
+
+#define EPHEMERAL_PRIVKEY_FILENAME "ephemeral_key.pem"
+#define INVALID_HOSTNAME "dns-over-tls.invalid"
+#define EPHEMERAL_CERT_EXPIRATION_SECONDS (60*60*24*90)
+
+/* This is an attempt to grab an exclusive, advisory, non-blocking
+ * lock based on a filename. At the moment it's POSIX-only, but it
+ * should be abstract enough of an interface to make an implementation
+ * for non-posix systems if anyone cares. */
+typedef int lock_t;
+static bool _lock_is_invalid(lock_t lock)
+{
+ return lock == -1;
+}
+/* a blocking lock on a given filename */
+static lock_t _lock_filename(const char *fname)
+{
+ lock_t lockfd = open(fname, O_RDONLY|O_CREAT, 0400);
+ if (lockfd == -1)
+ return lockfd;
+ /* this should be a non-blocking lock */
+ if (flock(lockfd, LOCK_EX | LOCK_NB) != 0) {
+ close(lockfd);
+ return -1;
+ }
+ return lockfd; /* for cleanup later */
+}
+static void _lock_unlock(lock_t *lock, const char *fname)
+{
+ if (lock && !_lock_is_invalid(*lock)) {
+ flock(*lock, LOCK_UN);
+ close(*lock);
+ *lock = -1;
+ unlink(fname); /* ignore errors */
+ }
+}
+
+static gnutls_x509_privkey_t get_ephemeral_privkey ()
+{
+ gnutls_x509_privkey_t privkey = NULL;
+ int err;
+ gnutls_datum_t data = { .data = NULL, .size = 0 };
+ lock_t lock;
+ int datafd = -1;
+
+ /* Take a lock to ensure that two daemons started concurrently
+ * with a shared cache don't both create the same privkey: */
+ lock = _lock_filename(EPHEMERAL_PRIVKEY_FILENAME ".lock");
+ if (_lock_is_invalid(lock)) {
+ kr_log_error(TLS, "unable to lock lockfile " EPHEMERAL_PRIVKEY_FILENAME ".lock\n");
+ goto done;
+ }
+
+ if ((err = gnutls_x509_privkey_init (&privkey)) < 0) {
+ kr_log_error(TLS, "gnutls_x509_privkey_init() failed: %d (%s)\n",
+ err, gnutls_strerror_name(err));
+ goto done;
+ }
+
+ /* read from cache file (we assume that we've chdir'ed
+ * already, so we're just looking for the file in the
+ * cachedir. */
+ datafd = open(EPHEMERAL_PRIVKEY_FILENAME, O_RDONLY);
+ if (datafd != -1) {
+ struct stat stat;
+ ssize_t bytes_read;
+ if (fstat(datafd, &stat)) {
+ kr_log_error(TLS, "unable to stat ephemeral private key " EPHEMERAL_PRIVKEY_FILENAME "\n");
+ goto bad_data;
+ }
+ data.data = gnutls_malloc(stat.st_size);
+ if (data.data == NULL) {
+ kr_log_error(TLS, "unable to allocate memory for reading ephemeral private key\n");
+ goto bad_data;
+ }
+ data.size = stat.st_size;
+ bytes_read = read(datafd, data.data, stat.st_size);
+ if (bytes_read != stat.st_size) {
+ kr_log_error(TLS, "unable to read ephemeral private key\n");
+ goto bad_data;
+ }
+ if ((err = gnutls_x509_privkey_import (privkey, &data, GNUTLS_X509_FMT_PEM)) < 0) {
+ kr_log_error(TLS, "gnutls_x509_privkey_import() failed: %d (%s)\n",
+ err, gnutls_strerror_name(err));
+ /* goto bad_data; */
+ bad_data:
+ close(datafd);
+ datafd = -1;
+ }
+ if (data.data != NULL) {
+ gnutls_free(data.data);
+ data.data = NULL;
+ }
+ }
+ if (datafd == -1) {
+ /* if loading failed, then generate ... */
+#if GNUTLS_VERSION_NUMBER >= 0x030500
+ if ((err = gnutls_x509_privkey_generate(privkey, GNUTLS_PK_ECDSA, GNUTLS_CURVE_TO_BITS(GNUTLS_ECC_CURVE_SECP256R1), 0)) < 0) {
+#else
+ if ((err = gnutls_x509_privkey_generate(privkey, GNUTLS_PK_RSA, gnutls_sec_param_to_pk_bits(GNUTLS_PK_RSA, GNUTLS_SEC_PARAM_MEDIUM), 0)) < 0) {
+#endif
+ kr_log_error(TLS, "gnutls_x509_privkey_init() failed: %d (%s)\n",
+ err, gnutls_strerror_name(err));
+ gnutls_x509_privkey_deinit(privkey);
+ goto done;
+ }
+ /* ... and save */
+ kr_log_info(TLS, "Stashing ephemeral private key in " EPHEMERAL_PRIVKEY_FILENAME "\n");
+ if ((err = gnutls_x509_privkey_export2(privkey, GNUTLS_X509_FMT_PEM, &data)) < 0) {
+ kr_log_error(TLS, "gnutls_x509_privkey_export2() failed: %d (%s), not storing\n",
+ err, gnutls_strerror_name(err));
+ } else {
+ datafd = open(EPHEMERAL_PRIVKEY_FILENAME, O_WRONLY|O_CREAT, 0600);
+ if (datafd == -1) {
+ kr_log_error(TLS, "failed to open " EPHEMERAL_PRIVKEY_FILENAME " to store the ephemeral key\n");
+ } else {
+ ssize_t bytes_written;
+ bytes_written = write(datafd, data.data, data.size);
+ if (bytes_written != data.size)
+ kr_log_error(TLS, "failed to write %d octets to "
+ EPHEMERAL_PRIVKEY_FILENAME
+ " (%zd written)\n",
+ data.size, bytes_written);
+ }
+ }
+ }
+ done:
+ _lock_unlock(&lock, EPHEMERAL_PRIVKEY_FILENAME ".lock");
+ if (datafd != -1) {
+ close(datafd);
+ }
+ if (data.data != NULL) {
+ gnutls_free(data.data);
+ }
+ return privkey;
+}
+
+static gnutls_x509_crt_t get_ephemeral_cert(gnutls_x509_privkey_t privkey, const char *servicename, time_t invalid_before, time_t valid_until)
+{
+ gnutls_x509_crt_t cert = NULL;
+ int err;
+ /* need a random buffer of bytes */
+ uint8_t serial[16];
+ gnutls_rnd(GNUTLS_RND_NONCE, serial, sizeof(serial));
+ /* clear the left-most bit to avoid signedness confusion: */
+ serial[0] &= 0x8f;
+ size_t namelen = strlen(servicename);
+
+#define gtx(fn, ...) \
+ if ((err = fn ( __VA_ARGS__ )) != GNUTLS_E_SUCCESS) { \
+ kr_log_error(TLS, #fn "() failed: %d (%s)\n", \
+ err, gnutls_strerror_name(err)); \
+ goto bad; }
+
+ gtx(gnutls_x509_crt_init, &cert);
+ gtx(gnutls_x509_crt_set_activation_time, cert, invalid_before);
+ gtx(gnutls_x509_crt_set_ca_status, cert, 0);
+ gtx(gnutls_x509_crt_set_expiration_time, cert, valid_until);
+ gtx(gnutls_x509_crt_set_key, cert, privkey);
+ gtx(gnutls_x509_crt_set_key_purpose_oid, cert, GNUTLS_KP_TLS_WWW_CLIENT, 0);
+ gtx(gnutls_x509_crt_set_key_purpose_oid, cert, GNUTLS_KP_TLS_WWW_SERVER, 0);
+ gtx(gnutls_x509_crt_set_key_usage, cert, GNUTLS_KEY_DIGITAL_SIGNATURE);
+ gtx(gnutls_x509_crt_set_serial, cert, serial, sizeof(serial));
+ gtx(gnutls_x509_crt_set_subject_alt_name, cert, GNUTLS_SAN_DNSNAME, servicename, namelen, GNUTLS_FSAN_SET);
+ gtx(gnutls_x509_crt_set_dn_by_oid,cert, GNUTLS_OID_X520_COMMON_NAME, 0, servicename, namelen);
+ gtx(gnutls_x509_crt_set_version, cert, 3);
+ gtx(gnutls_x509_crt_sign2,cert, cert, privkey, GNUTLS_DIG_SHA256, 0); /* self-sign, since it doesn't look like we can just stub-sign */
+#undef gtx
+
+ return cert;
+bad:
+ gnutls_x509_crt_deinit(cert);
+ return NULL;
+}
+
+struct tls_credentials * tls_get_ephemeral_credentials(struct engine *engine)
+{
+ struct tls_credentials *creds = NULL;
+ gnutls_x509_privkey_t privkey = NULL;
+ gnutls_x509_crt_t cert = NULL;
+ int err;
+ time_t now = time(NULL);
+
+ creds = calloc(1, sizeof(*creds));
+ if (!creds) {
+ kr_log_error(TLS, "failed to allocate memory for ephemeral credentials\n");
+ return NULL;
+ }
+ if ((err = gnutls_certificate_allocate_credentials(&(creds->credentials))) < 0) {
+ kr_log_error(TLS, "failed to allocate memory for ephemeral credentials\n");
+ goto failure;
+ }
+
+ creds->valid_until = now + EPHEMERAL_CERT_EXPIRATION_SECONDS;
+ creds->ephemeral_servicename = strdup(engine_get_hostname(engine));
+ if (creds->ephemeral_servicename == NULL) {
+ kr_log_error(TLS, "could not get server's hostname, using '" INVALID_HOSTNAME "' instead\n");
+ if ((creds->ephemeral_servicename = strdup(INVALID_HOSTNAME)) == NULL) {
+ kr_log_error(TLS, "failed to allocate memory for ephemeral credentials\n");
+ goto failure;
+ }
+ }
+ if ((privkey = get_ephemeral_privkey()) == NULL) {
+ goto failure;
+ }
+ if ((cert = get_ephemeral_cert(privkey, creds->ephemeral_servicename, now - 60*15, creds->valid_until)) == NULL) {
+ goto failure;
+ }
+ if ((err = gnutls_certificate_set_x509_key(creds->credentials, &cert, 1, privkey)) < 0) {
+ kr_log_error(TLS, "failed to set up ephemeral credentials\n");
+ goto failure;
+ }
+ gnutls_x509_privkey_deinit(privkey);
+ gnutls_x509_crt_deinit(cert);
+ return creds;
+ failure:
+ gnutls_x509_privkey_deinit(privkey);
+ gnutls_x509_crt_deinit(cert);
+ tls_credentials_free(creds);
+ return NULL;
+}
diff --git a/daemon/tls_session_ticket-srv.c b/daemon/tls_session_ticket-srv.c
new file mode 100644
index 0000000..b198903
--- /dev/null
+++ b/daemon/tls_session_ticket-srv.c
@@ -0,0 +1,245 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#include <inttypes.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/time.h>
+
+#include <gnutls/gnutls.h>
+#include <gnutls/crypto.h>
+#include <uv.h>
+
+#include "lib/utils.h"
+
+/* Style: "local/static" identifiers are usually named tst_* */
+
+/** The number of seconds between synchronized rotation of TLS session ticket key. */
+#define TST_KEY_LIFETIME 4096
+
+/** Value from gnutls:lib/ext/session_ticket.c
+ * Beware: changing this needs to change the hashing implementation. */
+#define SESSION_KEY_SIZE 64
+
+/** Compile-time support for setting the secret. */
+/* This is not secure with TLS <= 1.2 but TLS 1.3 and secure configuration
+ * is not available in GnuTLS yet. See https://gitlab.com/gnutls/gnutls/issues/477 */
+#define TLS_SESSION_RESUMPTION_SYNC (GNUTLS_VERSION_NUMBER >= 0x030603)
+#if TLS_SESSION_RESUMPTION_SYNC
+ #define TST_HASH GNUTLS_DIG_SHA3_512
+#else
+ #define TST_HASH abort()
+#endif
+
+#if GNUTLS_VERSION_NUMBER < 0x030400
+ /* It's of little use anyway. We may get the secret through lua,
+ * which creates a copy outside of our control. */
+ #define gnutls_memset memset
+#endif
+
+/** Fields are internal to tst_key_* functions. */
+typedef struct tls_session_ticket_ctx {
+ uv_timer_t timer; /**< timer for rotation of the key */
+ unsigned char key[SESSION_KEY_SIZE]; /**< the key itself */
+ bool has_secret; /**< false -> key is random for each epoch */
+ uint16_t hash_len; /**< length of `hash_data` */
+ char hash_data[]; /**< data to hash to obtain `key`;
+ * it's `time_t epoch` and then the secret string */
+} tst_ctx_t;
+
+/** Check invariants, based on gnutls version. */
+static bool tst_key_invariants(void)
+{
+ static int result = 0; /*< cache for multiple invocations */
+ if (result) return result > 0;
+ bool ok = true;
+ #if TLS_SESSION_RESUMPTION_SYNC
+ /* SHA3-512 output size may never change, but let's check it anyway :-) */
+ ok = ok && gnutls_hash_get_len(TST_HASH) == SESSION_KEY_SIZE;
+ #endif
+ /* The ticket key size might change in a different gnutls version. */
+ gnutls_datum_t key = { 0, 0 };
+ ok = ok && gnutls_session_ticket_key_generate(&key) == 0
+ && key.size == SESSION_KEY_SIZE;
+ free(key.data);
+ result = ok ? 1 : -1;
+ return ok;
+}
+
+/** Create the internal structures and copy the secret. Beware: secret must be kept secure. */
+static tst_ctx_t * tst_key_create(const char *secret, size_t secret_len, uv_loop_t *loop)
+{
+ const size_t hash_len = sizeof(time_t) + secret_len;
+ if (kr_fails_assert(!secret_len || (secret && hash_len >= secret_len && hash_len <= UINT16_MAX))) {
+ return NULL;
+ /* reasonable secret_len is best enforced in config API */
+ }
+ if (kr_fails_assert(tst_key_invariants()))
+ return NULL;
+ #if !TLS_SESSION_RESUMPTION_SYNC
+ if (secret_len) {
+ kr_log_error(TLS, "session ticket: secrets were not enabled at compile-time (your GnuTLS version is not supported)\n");
+ return NULL; /* ENOTSUP */
+ }
+ #endif
+
+ tst_ctx_t *ctx = malloc(sizeof(*ctx) + hash_len); /* can be slightly longer */
+ if (!ctx) return NULL;
+ ctx->has_secret = secret_len > 0;
+ ctx->hash_len = hash_len;
+ if (secret_len) {
+ memcpy(ctx->hash_data + sizeof(time_t), secret, secret_len);
+ }
+
+ if (uv_timer_init(loop, &ctx->timer) != 0) {
+ free(ctx);
+ return NULL;
+ }
+ ctx->timer.data = ctx;
+ return ctx;
+}
+
+/** Random variant of secret rotation: generate into key_tmp and copy. */
+static int tst_key_get_random(tst_ctx_t *ctx)
+{
+ gnutls_datum_t key_tmp = { NULL, 0 };
+ int err = gnutls_session_ticket_key_generate(&key_tmp);
+ if (err) return kr_error(err);
+ if (kr_fails_assert(key_tmp.size == SESSION_KEY_SIZE))
+ return kr_error(EFAULT);
+ memcpy(ctx->key, key_tmp.data, SESSION_KEY_SIZE);
+ gnutls_memset(key_tmp.data, 0, SESSION_KEY_SIZE);
+ free(key_tmp.data);
+ return kr_ok();
+}
+
+/** Recompute the session ticket key, if epoch has changed or forced. */
+static int tst_key_update(tst_ctx_t *ctx, time_t epoch, bool force_update)
+{
+ if (kr_fails_assert(ctx && ctx->hash_len >= sizeof(epoch)))
+ return kr_error(EINVAL);
+ /* documented limitation: time_t and endianness must match
+ * on instances sharing a secret */
+ if (!force_update && memcmp(ctx->hash_data, &epoch, sizeof(epoch)) == 0) {
+ return kr_ok(); /* we are up to date */
+ }
+ memcpy(ctx->hash_data, &epoch, sizeof(epoch));
+
+ if (!ctx->has_secret) {
+ return tst_key_get_random(ctx);
+ }
+ /* Otherwise, deterministic variant of secret rotation, if supported. */
+ #if !TLS_SESSION_RESUMPTION_SYNC
+ kr_assert(!ENOTSUP);
+ return kr_error(ENOTSUP);
+ #else
+ int err = gnutls_hash_fast(TST_HASH, ctx->hash_data,
+ ctx->hash_len, ctx->key);
+ return err == 0 ? kr_ok() : kr_error(err);
+ #endif
+}
+
+/** Free all resources of the key (securely). */
+static void tst_key_destroy(uv_handle_t *timer)
+{
+ if (kr_fails_assert(timer))
+ return;
+ tst_ctx_t *ctx = timer->data;
+ if (kr_fails_assert(ctx))
+ return;
+ gnutls_memset(ctx, 0, offsetof(tst_ctx_t, hash_data) + ctx->hash_len);
+ free(ctx);
+}
+
+static void tst_key_check(uv_timer_t *timer, bool force_update);
+static void tst_timer_callback(uv_timer_t *timer)
+{
+ tst_key_check(timer, false);
+}
+
+/** Update the ST key if needed and reschedule itself via the timer. */
+static void tst_key_check(uv_timer_t *timer, bool force_update)
+{
+ tst_ctx_t *stst = (tst_ctx_t *)timer->data;
+ /* Compute the current epoch. */
+ struct timeval now;
+ if (gettimeofday(&now, NULL)) {
+ kr_log_error(TLS, "session ticket: gettimeofday failed, %s\n",
+ strerror(errno));
+ return;
+ }
+ uv_update_time(timer->loop); /* to have sync. between real and mono time */
+ const time_t epoch = now.tv_sec / TST_KEY_LIFETIME;
+ /* Update the key; new sessions will fetch it from the location.
+ * Old ones hopefully can't get broken by that; documentation
+ * for gnutls_session_ticket_enable_server() doesn't say. */
+ int err = tst_key_update(stst, epoch, force_update);
+ if (err) {
+ kr_log_error(TLS, "session ticket: failed rotation, %s\n",
+ kr_strerror(err));
+ if (kr_fails_assert(err != kr_error(EINVAL)))
+ return;
+ }
+ /* Reschedule. */
+ const time_t tv_sec_next = (epoch + 1) * TST_KEY_LIFETIME;
+ const uint64_t ms_until_second = 1000 - (now.tv_usec + 501) / 1000;
+ const uint64_t remain_ms = (tv_sec_next - now.tv_sec - 1) * (uint64_t)1000
+ + ms_until_second + 1;
+ /* ^ +1 because we don't want to wake up half a millisecond before the epoch! */
+ if (kr_fails_assert(remain_ms < (TST_KEY_LIFETIME + 1 /*rounding tolerance*/) * 1000))
+ return;
+ kr_log_debug(TLS, "session ticket: epoch %"PRIu64
+ ", scheduling rotation check in %"PRIu64" ms\n",
+ (uint64_t)epoch, remain_ms);
+ err = uv_timer_start(timer, &tst_timer_callback, remain_ms, 0);
+ if (kr_fails_assert(err == 0)) {
+ kr_log_error(TLS, "session ticket: failed to schedule, %s\n",
+ uv_strerror(err));
+ return;
+ }
+}
+
+/* Implementation for prototypes from ./tls.h */
+
+void tls_session_ticket_enable(struct tls_session_ticket_ctx *ctx, gnutls_session_t session)
+{
+ if (kr_fails_assert(ctx && session))
+ return;
+ const gnutls_datum_t gd = {
+ .size = SESSION_KEY_SIZE,
+ .data = ctx->key,
+ };
+ int err = gnutls_session_ticket_enable_server(session, &gd);
+ if (err) {
+ kr_log_error(TLS, "failed to enable session tickets: %s (%d)\n",
+ gnutls_strerror_name(err), err);
+ /* but continue without tickets */
+ }
+}
+
+tst_ctx_t * tls_session_ticket_ctx_create(uv_loop_t *loop, const char *secret,
+ size_t secret_len)
+{
+ if (kr_fails_assert(loop && (!secret_len || secret)))
+ return NULL;
+ #if GNUTLS_VERSION_NUMBER < 0x030500
+ /* We would need different SESSION_KEY_SIZE; avoid an error. */
+ return NULL;
+ #endif
+ tst_ctx_t *ctx = tst_key_create(secret, secret_len, loop);
+ if (ctx) {
+ tst_key_check(&ctx->timer, true);
+ }
+ return ctx;
+}
+
+void tls_session_ticket_ctx_destroy(tst_ctx_t *ctx)
+{
+ if (ctx == NULL) {
+ return;
+ }
+ uv_close((uv_handle_t *)&ctx->timer, &tst_key_destroy);
+}
+
diff --git a/daemon/udp_queue.c b/daemon/udp_queue.c
new file mode 100644
index 0000000..7460e04
--- /dev/null
+++ b/daemon/udp_queue.c
@@ -0,0 +1,145 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#include "kresconfig.h"
+#include "daemon/udp_queue.h"
+
+#include "daemon/worker.h"
+#include "lib/generic/array.h"
+#include "lib/utils.h"
+
+struct qr_task;
+
+#include <sys/socket.h>
+
+
+#if !ENABLE_SENDMMSG
+int udp_queue_init_global(uv_loop_t *loop)
+{
+ return 0;
+}
+/* Appease the linker in case this unused call isn't optimized out. */
+void udp_queue_push(int fd, struct kr_request *req, struct qr_task *task)
+{
+ abort();
+}
+#else
+
+/* LATER: it might be useful to have this configurable during runtime,
+ * but the structures below would have to change a little (broken up). */
+#define UDP_QUEUE_LEN 64
+
+/** A queue of up to UDP_QUEUE_LEN messages, meant for the same socket. */
+typedef struct {
+ int len; /**< The number of messages in the queue: 0..UDP_QUEUE_LEN */
+ struct mmsghdr msgvec[UDP_QUEUE_LEN]; /**< Parameter for sendmmsg() */
+ struct {
+ struct qr_task *task; /**< Links for completion callbacks. */
+ struct iovec msg_iov[1]; /**< storage for .msgvec[i].msg_iov */
+ } items[UDP_QUEUE_LEN];
+} udp_queue_t;
+
+static udp_queue_t * udp_queue_create()
+{
+ udp_queue_t *q = calloc(1, sizeof(*q));
+ kr_require(q != NULL);
+
+ for (int i = 0; i < UDP_QUEUE_LEN; ++i) {
+ struct msghdr *mhi = &q->msgvec[i].msg_hdr;
+ /* These shall remain always the same. */
+ mhi->msg_iov = q->items[i].msg_iov;
+ mhi->msg_iovlen = 1;
+ /* msg_name and msg_namelen will be per-call,
+ * and the rest is OK to remain zeroed all the time. */
+ }
+ return q;
+}
+
+/** Global state for udp_queue_*. Note: we never free the pointed-to memory. */
+struct {
+ /** Singleton map: fd -> udp_queue_t, as a simple array of pointers. */
+ udp_queue_t **udp_queues;
+ int udp_queues_len;
+
+ /** List of FD numbers that might have a non-empty queue. */
+ array_t(int) waiting_fds;
+
+ uv_check_t check_handle;
+} static state = {0};
+
+/** Empty the given queue. The queue is assumed to exist (but may be empty). */
+static void udp_queue_send(int fd)
+{
+ udp_queue_t *const q = state.udp_queues[fd];
+ if (!q->len) return;
+ int sent_len = sendmmsg(fd, q->msgvec, q->len, 0);
+ /* ATM we don't really do anything about failures. */
+ int err = sent_len < 0 ? errno : EAGAIN /* unknown error, really */;
+ for (int i = 0; i < q->len; ++i) {
+ qr_task_on_send(q->items[i].task, NULL, i < sent_len ? 0 : err);
+ worker_task_unref(q->items[i].task);
+ }
+ q->len = 0;
+}
+
+/** Periodical callback to send all queued packets. */
+static void udp_queue_check(uv_check_t *handle)
+{
+ for (int i = 0; i < state.waiting_fds.len; ++i) {
+ udp_queue_send(state.waiting_fds.at[i]);
+ }
+ state.waiting_fds.len = 0;
+}
+
+int udp_queue_init_global(uv_loop_t *loop)
+{
+ int ret = uv_check_init(loop, &state.check_handle);
+ if (!ret) ret = uv_check_start(&state.check_handle, udp_queue_check);
+ return ret;
+}
+
+void udp_queue_push(int fd, struct kr_request *req, struct qr_task *task)
+{
+ if (fd < 0) {
+ kr_log_error(SYSTEM, "ERROR: called udp_queue_push(fd = %d, ...)\n", fd);
+ abort();
+ }
+ worker_task_ref(task);
+ /* Get a valid correct queue. */
+ if (fd >= state.udp_queues_len) {
+ const int new_len = fd + 1;
+ state.udp_queues = realloc(state.udp_queues,
+ sizeof(state.udp_queues[0]) * new_len);
+ if (!state.udp_queues) abort();
+ memset(state.udp_queues + state.udp_queues_len, 0,
+ sizeof(state.udp_queues[0]) * (new_len - state.udp_queues_len));
+ state.udp_queues_len = new_len;
+ }
+ if (unlikely(state.udp_queues[fd] == NULL))
+ state.udp_queues[fd] = udp_queue_create();
+ udp_queue_t *const q = state.udp_queues[fd];
+
+ /* Append to the queue */
+ struct sockaddr *sa = (struct sockaddr *)/*const-cast*/req->qsource.comm_addr;
+ q->msgvec[q->len].msg_hdr.msg_name = sa;
+ q->msgvec[q->len].msg_hdr.msg_namelen = kr_sockaddr_len(sa);
+ q->items[q->len].task = task;
+ q->items[q->len].msg_iov[0] = (struct iovec){
+ .iov_base = req->answer->wire,
+ .iov_len = req->answer->size,
+ };
+ if (q->len == 0)
+ array_push(state.waiting_fds, fd);
+ ++(q->len);
+
+ if (q->len >= UDP_QUEUE_LEN) {
+ kr_assert(q->len == UDP_QUEUE_LEN);
+ udp_queue_send(fd);
+ /* We don't need to search state.waiting_fds;
+ * anyway, it's more efficient to let the hook do that. */
+ }
+}
+
+#endif
+
diff --git a/daemon/udp_queue.h b/daemon/udp_queue.h
new file mode 100644
index 0000000..f4a1ae1
--- /dev/null
+++ b/daemon/udp_queue.h
@@ -0,0 +1,16 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#include <uv.h>
+struct kr_request;
+struct qr_task;
+
+/** Initialize the global state for udp_queue. */
+int udp_queue_init_global(uv_loop_t *loop);
+
+/** Send req->answer via UDP, possibly not immediately. */
+void udp_queue_push(int fd, struct kr_request *req, struct qr_task *task);
+
diff --git a/daemon/worker.c b/daemon/worker.c
new file mode 100644
index 0000000..8b6b49e
--- /dev/null
+++ b/daemon/worker.c
@@ -0,0 +1,2252 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#include "kresconfig.h"
+#include "daemon/worker.h"
+
+#include <uv.h>
+#include <lua.h>
+#include <lauxlib.h>
+#include <libknot/packet/pkt.h>
+#include <libknot/descriptor.h>
+#include <contrib/cleanup.h>
+#include <contrib/ucw/lib.h>
+#include <contrib/ucw/mempool.h>
+#if defined(__GLIBC__) && defined(_GNU_SOURCE)
+#include <malloc.h>
+#endif
+#include <sys/types.h>
+#include <unistd.h>
+#include <gnutls/gnutls.h>
+
+#if ENABLE_XDP
+ #include <libknot/xdp/xdp.h>
+#endif
+
+#include "daemon/bindings/api.h"
+#include "daemon/engine.h"
+#include "daemon/io.h"
+#include "daemon/proxyv2.h"
+#include "daemon/session.h"
+#include "daemon/tls.h"
+#include "daemon/http.h"
+#include "daemon/udp_queue.h"
+#include "lib/layer.h"
+#include "lib/utils.h"
+
+
+/* Magic defaults for the worker. */
+#ifndef MAX_PIPELINED
+#define MAX_PIPELINED 100
+#endif
+
+#define VERBOSE_MSG(qry, ...) kr_log_q(qry, WORKER, __VA_ARGS__)
+
+/** Client request state. */
+struct request_ctx
+{
+ struct kr_request req;
+
+ struct worker_ctx *worker;
+ struct qr_task *task;
+ struct {
+ /** NULL if the request didn't come over network. */
+ struct session *session;
+ /** Requestor's address; separate because of UDP session "sharing". */
+ union kr_sockaddr addr;
+ /** Request communication address; if not from a proxy, same as addr. */
+ union kr_sockaddr comm_addr;
+ /** Local address. For AF_XDP we couldn't use session's,
+ * as the address might be different every time. */
+ union kr_sockaddr dst_addr;
+ /** MAC addresses - ours [0] and router's [1], in case of AF_XDP socket. */
+ uint8_t eth_addrs[2][6];
+ } source;
+};
+
+/** Query resolution task. */
+struct qr_task
+{
+ struct request_ctx *ctx;
+ knot_pkt_t *pktbuf;
+ qr_tasklist_t waiting;
+ struct session *pending[MAX_PENDING];
+ uint16_t pending_count;
+ uint16_t timeouts;
+ uint16_t iter_count;
+ uint32_t refs;
+ bool finished : 1;
+ bool leading : 1;
+ uint64_t creation_time;
+ uint64_t send_time;
+ uint64_t recv_time;
+ struct kr_transport *transport;
+};
+
+
+/* Convenience macros */
+#define qr_task_ref(task) \
+ do { ++(task)->refs; } while(0)
+#define qr_task_unref(task) \
+ do { \
+ if (task) \
+ kr_require((task)->refs > 0); \
+ if ((task) && --(task)->refs == 0) \
+ qr_task_free((task)); \
+ } while (0)
+
+/* Forward decls */
+static void qr_task_free(struct qr_task *task);
+static int qr_task_step(struct qr_task *task,
+ const struct sockaddr *packet_source,
+ knot_pkt_t *packet);
+static int qr_task_send(struct qr_task *task, struct session *session,
+ const struct sockaddr *addr, knot_pkt_t *pkt);
+static int qr_task_finalize(struct qr_task *task, int state);
+static void qr_task_complete(struct qr_task *task);
+struct session* worker_find_tcp_connected(struct worker_ctx *worker,
+ const struct sockaddr *addr);
+static int worker_add_tcp_waiting(struct worker_ctx *worker,
+ const struct sockaddr *addr,
+ struct session *session);
+struct session* worker_find_tcp_waiting(struct worker_ctx *worker,
+ const struct sockaddr *addr);
+static void on_tcp_connect_timeout(uv_timer_t *timer);
+static void on_udp_timeout(uv_timer_t *timer);
+static void subreq_finalize(struct qr_task *task, const struct sockaddr *packet_source, knot_pkt_t *pkt);
+
+
+struct worker_ctx the_worker_value; /**< Static allocation is suitable for the singleton. */
+struct worker_ctx *the_worker = NULL;
+
+/*! @internal Create a UDP/TCP handle for an outgoing AF_INET* connection.
+ * socktype is SOCK_* */
+static uv_handle_t *ioreq_spawn(struct worker_ctx *worker,
+ int socktype, sa_family_t family, bool has_tls,
+ bool has_http)
+{
+ bool precond = (socktype == SOCK_DGRAM || socktype == SOCK_STREAM)
+ && (family == AF_INET || family == AF_INET6);
+ if (kr_fails_assert(precond)) {
+ kr_log_debug(WORKER, "ioreq_spawn: pre-condition failed\n");
+ return NULL;
+ }
+
+ /* Create connection for iterative query */
+ uv_handle_t *handle = malloc(socktype == SOCK_DGRAM
+ ? sizeof(uv_udp_t) : sizeof(uv_tcp_t));
+ if (!handle) {
+ return NULL;
+ }
+ int ret = io_create(worker->loop, handle, socktype, family, has_tls, has_http);
+ if (ret) {
+ if (ret == UV_EMFILE) {
+ worker->too_many_open = true;
+ worker->rconcurrent_highwatermark = worker->stats.rconcurrent;
+ }
+ free(handle);
+ return NULL;
+ }
+
+ /* Bind to outgoing address, according to IP v4/v6. */
+ union kr_sockaddr *addr;
+ if (family == AF_INET) {
+ addr = (union kr_sockaddr *)&worker->out_addr4;
+ } else {
+ addr = (union kr_sockaddr *)&worker->out_addr6;
+ }
+ if (addr->ip.sa_family != AF_UNSPEC) {
+ if (kr_fails_assert(addr->ip.sa_family == family)) {
+ io_free(handle);
+ return NULL;
+ }
+ if (socktype == SOCK_DGRAM) {
+ uv_udp_t *udp = (uv_udp_t *)handle;
+ ret = uv_udp_bind(udp, &addr->ip, 0);
+ } else if (socktype == SOCK_STREAM){
+ uv_tcp_t *tcp = (uv_tcp_t *)handle;
+ ret = uv_tcp_bind(tcp, &addr->ip, 0);
+ }
+ }
+
+ if (ret != 0) {
+ io_free(handle);
+ return NULL;
+ }
+
+ /* Set current handle as a subrequest type. */
+ struct session *session = handle->data;
+ session_flags(session)->outgoing = true;
+ /* Connect or issue query datagram */
+ return handle;
+}
+
+static void ioreq_kill_pending(struct qr_task *task)
+{
+ for (uint16_t i = 0; i < task->pending_count; ++i) {
+ session_kill_ioreq(task->pending[i], task);
+ }
+ task->pending_count = 0;
+}
+
+/** Get a mempool. */
+static inline struct mempool *pool_borrow(struct worker_ctx *worker)
+{
+ /* The implementation used to have extra caching layer,
+ * but it didn't work well. Now it's very simple. */
+ return mp_new(16 * 1024);
+}
+/** Return a mempool. */
+static inline void pool_release(struct worker_ctx *worker, struct mempool *mp)
+{
+ mp_delete(mp);
+}
+
+/** Create a key for an outgoing subrequest: qname, qclass, qtype.
+ * @param key Destination buffer for key size, MUST be SUBREQ_KEY_LEN or larger.
+ * @return key length if successful or an error
+ */
+static const size_t SUBREQ_KEY_LEN = KR_RRKEY_LEN;
+static int subreq_key(char *dst, knot_pkt_t *pkt)
+{
+ kr_require(pkt);
+ return kr_rrkey(dst, knot_pkt_qclass(pkt), knot_pkt_qname(pkt),
+ knot_pkt_qtype(pkt), knot_pkt_qtype(pkt));
+}
+
+#if ENABLE_XDP
+static uint8_t *alloc_wire_cb(struct kr_request *req, uint16_t *maxlen)
+{
+ if (kr_fails_assert(maxlen))
+ return NULL;
+ struct request_ctx *ctx = (struct request_ctx *)req;
+ /* We know it's an AF_XDP socket; otherwise this CB isn't assigned. */
+ uv_handle_t *handle = session_get_handle(ctx->source.session);
+ if (kr_fails_assert(handle->type == UV_POLL))
+ return NULL;
+ xdp_handle_data_t *xhd = handle->data;
+ knot_xdp_msg_t out;
+ bool ipv6 = ctx->source.comm_addr.ip.sa_family == AF_INET6;
+ int ret = knot_xdp_send_alloc(xhd->socket,
+ #if KNOT_VERSION_HEX >= 0x030100
+ ipv6 ? KNOT_XDP_MSG_IPV6 : 0, &out);
+ #else
+ ipv6, &out, NULL);
+ #endif
+ if (ret != KNOT_EOK) {
+ kr_assert(ret == KNOT_ENOMEM);
+ *maxlen = 0;
+ return NULL;
+ }
+ *maxlen = MIN(*maxlen, out.payload.iov_len);
+#if KNOT_VERSION_HEX < 0x030100
+ /* It's most convenient to fill the MAC addresses at this point. */
+ memcpy(out.eth_from, &ctx->source.eth_addrs[0], 6);
+ memcpy(out.eth_to, &ctx->source.eth_addrs[1], 6);
+#endif
+ return out.payload.iov_base;
+}
+static void free_wire(const struct request_ctx *ctx)
+{
+ if (kr_fails_assert(ctx->req.alloc_wire_cb == alloc_wire_cb))
+ return;
+ knot_pkt_t *ans = ctx->req.answer;
+ if (unlikely(ans == NULL)) /* dropped */
+ return;
+ if (likely(ans->wire == NULL)) /* sent most likely */
+ return;
+ /* We know it's an AF_XDP socket; otherwise alloc_wire_cb isn't assigned. */
+ uv_handle_t *handle = session_get_handle(ctx->source.session);
+ if (kr_fails_assert(handle->type == UV_POLL))
+ return;
+ xdp_handle_data_t *xhd = handle->data;
+ /* Freeing is done by sending an empty packet (the API won't really send it). */
+ knot_xdp_msg_t out;
+ out.payload.iov_base = ans->wire;
+ out.payload.iov_len = 0;
+ uint32_t sent = 0;
+#if KNOT_VERSION_HEX >= 0x030100
+ int ret = 0;
+ knot_xdp_send_free(xhd->socket, &out, 1);
+#else
+ int ret = knot_xdp_send(xhd->socket, &out, 1, &sent);
+#endif
+ kr_assert(ret == KNOT_EOK && sent == 0);
+ kr_log_debug(XDP, "freed unsent buffer, ret = %d\n", ret);
+}
+#endif
+/* Helper functions for transport selection */
+static inline bool is_tls_capable(struct sockaddr *address) {
+ tls_client_param_t *tls_entry = tls_client_param_get(the_worker->engine->net.tls_client_params, address);
+ return tls_entry;
+}
+
+static inline bool is_tcp_connected(struct sockaddr *address) {
+ return worker_find_tcp_connected(the_worker, address);
+}
+
+static inline bool is_tcp_waiting(struct sockaddr *address) {
+ return worker_find_tcp_waiting(the_worker, address);
+}
+
+/** Create and initialize a request_ctx (on a fresh mempool).
+ *
+ * session and addr point to the source of the request, and they are NULL
+ * in case the request didn't come from network.
+ */
+static struct request_ctx *request_create(struct worker_ctx *worker,
+ struct session *session,
+ struct io_comm_data *comm,
+ const uint8_t *eth_from,
+ const uint8_t *eth_to,
+ uint32_t uid)
+{
+ knot_mm_t pool = {
+ .ctx = pool_borrow(worker),
+ .alloc = (knot_mm_alloc_t) mp_alloc
+ };
+
+ /* Create request context */
+ struct request_ctx *ctx = mm_calloc(&pool, 1, sizeof(*ctx));
+ if (!ctx) {
+ pool_release(worker, pool.ctx);
+ return NULL;
+ }
+
+ /* TODO Relocate pool to struct request */
+ ctx->worker = worker;
+ if (session && kr_fails_assert(session_flags(session)->outgoing == false)) {
+ pool_release(worker, pool.ctx);
+ return NULL;
+ }
+ ctx->source.session = session;
+ if (kr_fails_assert(!!eth_to == !!eth_from)) {
+ pool_release(worker, pool.ctx);
+ return NULL;
+ }
+ const bool is_xdp = eth_to != NULL;
+ if (is_xdp) {
+ #if ENABLE_XDP
+ if (kr_fails_assert(session)) {
+ pool_release(worker, pool.ctx);
+ return NULL;
+ }
+ memcpy(&ctx->source.eth_addrs[0], eth_to, sizeof(ctx->source.eth_addrs[0]));
+ memcpy(&ctx->source.eth_addrs[1], eth_from, sizeof(ctx->source.eth_addrs[1]));
+ ctx->req.alloc_wire_cb = alloc_wire_cb;
+ #else
+ kr_assert(!EINVAL);
+ pool_release(worker, pool.ctx);
+ return NULL;
+ #endif
+ }
+
+ struct kr_request *req = &ctx->req;
+ req->pool = pool;
+ req->vars_ref = LUA_NOREF;
+ req->uid = uid;
+ req->qsource.comm_flags.xdp = is_xdp;
+ kr_request_set_extended_error(req, KNOT_EDNS_EDE_NONE, NULL);
+ array_init(req->qsource.headers);
+ if (session) {
+ kr_require(comm);
+
+ const struct sockaddr *src_addr = comm->src_addr;
+ const struct sockaddr *comm_addr = comm->comm_addr;
+ const struct sockaddr *dst_addr = comm->dst_addr;
+ const struct proxy_result *proxy = comm->proxy;
+
+ req->qsource.comm_flags.tcp = session_get_handle(session)->type == UV_TCP;
+ req->qsource.comm_flags.tls = session_flags(session)->has_tls;
+ req->qsource.comm_flags.http = session_flags(session)->has_http;
+
+ req->qsource.flags = req->qsource.comm_flags;
+ if (proxy) {
+ req->qsource.flags.tcp = proxy->protocol == SOCK_STREAM;
+ req->qsource.flags.tls = proxy->has_tls;
+ }
+
+ req->qsource.stream_id = -1;
+#if ENABLE_DOH2
+ if (req->qsource.comm_flags.http) {
+ struct http_ctx *http_ctx = session_http_get_server_ctx(session);
+ struct http_stream stream = queue_head(http_ctx->streams);
+ req->qsource.stream_id = stream.id;
+ if (stream.headers) {
+ req->qsource.headers = *stream.headers;
+ free(stream.headers);
+ stream.headers = NULL;
+ }
+ }
+#endif
+ /* We need to store a copy of peer address. */
+ memcpy(&ctx->source.addr.ip, src_addr, kr_sockaddr_len(src_addr));
+ req->qsource.addr = &ctx->source.addr.ip;
+
+ if (!comm_addr)
+ comm_addr = src_addr;
+ memcpy(&ctx->source.comm_addr.ip, comm_addr, kr_sockaddr_len(comm_addr));
+ req->qsource.comm_addr = &ctx->source.comm_addr.ip;
+
+ if (!dst_addr) /* We wouldn't have to copy in this case, but for consistency. */
+ dst_addr = session_get_sockname(session);
+ memcpy(&ctx->source.dst_addr.ip, dst_addr, kr_sockaddr_len(dst_addr));
+ req->qsource.dst_addr = &ctx->source.dst_addr.ip;
+ }
+
+ req->selection_context.is_tls_capable = is_tls_capable;
+ req->selection_context.is_tcp_connected = is_tcp_connected;
+ req->selection_context.is_tcp_waiting = is_tcp_waiting;
+ array_init(req->selection_context.forwarding_targets);
+ array_reserve_mm(req->selection_context.forwarding_targets, 1, kr_memreserve, &req->pool);
+
+ worker->stats.rconcurrent += 1;
+
+ return ctx;
+}
+
+/** More initialization, related to the particular incoming query/packet. */
+static int request_start(struct request_ctx *ctx, knot_pkt_t *query)
+{
+ if (kr_fails_assert(query && ctx))
+ return kr_error(EINVAL);
+
+ struct kr_request *req = &ctx->req;
+ req->qsource.size = query->size;
+ if (knot_pkt_has_tsig(query)) {
+ req->qsource.size += query->tsig_wire.len;
+ }
+
+ knot_pkt_t *pkt = knot_pkt_new(NULL, req->qsource.size, &req->pool);
+ if (!pkt) {
+ return kr_error(ENOMEM);
+ }
+
+ int ret = knot_pkt_copy(pkt, query);
+ if (ret != KNOT_EOK && ret != KNOT_ETRAIL) {
+ return kr_error(ENOMEM);
+ }
+ req->qsource.packet = pkt;
+
+ /* Start resolution */
+ struct worker_ctx *worker = ctx->worker;
+ struct engine *engine = worker->engine;
+ kr_resolve_begin(req, &engine->resolver);
+ worker->stats.queries += 1;
+ return kr_ok();
+}
+
+static void request_free(struct request_ctx *ctx)
+{
+ struct worker_ctx *worker = ctx->worker;
+ /* Dereference any Lua vars table if exists */
+ if (ctx->req.vars_ref != LUA_NOREF) {
+ lua_State *L = worker->engine->L;
+ /* Get worker variables table */
+ lua_rawgeti(L, LUA_REGISTRYINDEX, worker->vars_table_ref);
+ /* Get next free element (position 0) and store it under current reference (forming a list) */
+ lua_rawgeti(L, -1, 0);
+ lua_rawseti(L, -2, ctx->req.vars_ref);
+ /* Set current reference as the next free element */
+ lua_pushinteger(L, ctx->req.vars_ref);
+ lua_rawseti(L, -2, 0);
+ lua_pop(L, 1);
+ ctx->req.vars_ref = LUA_NOREF;
+ }
+ /* Free HTTP/2 headers for DoH requests. */
+ for(int i = 0; i < ctx->req.qsource.headers.len; i++) {
+ free(ctx->req.qsource.headers.at[i].name);
+ free(ctx->req.qsource.headers.at[i].value);
+ }
+ array_clear(ctx->req.qsource.headers);
+
+ /* Make sure to free XDP buffer in case it wasn't sent. */
+ if (ctx->req.alloc_wire_cb) {
+ #if ENABLE_XDP
+ free_wire(ctx);
+ #else
+ kr_assert(!EINVAL);
+ #endif
+ }
+ /* Return mempool to ring or free it if it's full */
+ pool_release(worker, ctx->req.pool.ctx);
+ /* @note The 'task' is invalidated from now on. */
+ worker->stats.rconcurrent -= 1;
+}
+
+static struct qr_task *qr_task_create(struct request_ctx *ctx)
+{
+ /* Choose (initial) pktbuf size. As it is now, pktbuf can be used
+ * for UDP answers from upstream *and* from cache
+ * and for sending queries upstream */
+ uint16_t pktbuf_max = KR_EDNS_PAYLOAD;
+ const knot_rrset_t *opt_our = ctx->worker->engine->resolver.upstream_opt_rr;
+ if (opt_our) {
+ pktbuf_max = MAX(pktbuf_max, knot_edns_get_payload(opt_our));
+ }
+
+ /* Create resolution task */
+ struct qr_task *task = mm_calloc(&ctx->req.pool, 1, sizeof(*task));
+ if (!task) {
+ return NULL;
+ }
+
+ /* Create packet buffers for answer and subrequests */
+ knot_pkt_t *pktbuf = knot_pkt_new(NULL, pktbuf_max, &ctx->req.pool);
+ if (!pktbuf) {
+ mm_free(&ctx->req.pool, task);
+ return NULL;
+ }
+ pktbuf->size = 0;
+
+ task->ctx = ctx;
+ task->pktbuf = pktbuf;
+ array_init(task->waiting);
+ task->refs = 0;
+ kr_assert(ctx->task == NULL);
+ ctx->task = task;
+ /* Make the primary reference to task. */
+ qr_task_ref(task);
+ task->creation_time = kr_now();
+ ctx->worker->stats.concurrent += 1;
+ return task;
+}
+
+/* This is called when the task refcount is zero, free memory. */
+static void qr_task_free(struct qr_task *task)
+{
+ struct request_ctx *ctx = task->ctx;
+
+ if (kr_fails_assert(ctx))
+ return;
+
+ struct worker_ctx *worker = ctx->worker;
+
+ if (ctx->task == NULL) {
+ request_free(ctx);
+ }
+
+ /* Update stats */
+ worker->stats.concurrent -= 1;
+}
+
+/*@ Register new qr_task within session. */
+static int qr_task_register(struct qr_task *task, struct session *session)
+{
+ if (kr_fails_assert(!session_flags(session)->outgoing && session_get_handle(session)->type == UV_TCP))
+ return kr_error(EINVAL);
+
+ session_tasklist_add(session, task);
+
+ struct request_ctx *ctx = task->ctx;
+ if (kr_fails_assert(ctx && (ctx->source.session == NULL || ctx->source.session == session)))
+ return kr_error(EINVAL);
+ ctx->source.session = session;
+ /* Soft-limit on parallel queries, there is no "slow down" RCODE
+ * that we could use to signalize to client, but we can stop reading,
+ * an in effect shrink TCP window size. To get more precise throttling,
+ * we would need to copy remainder of the unread buffer and reassemble
+ * when resuming reading. This is NYI. */
+ if (session_tasklist_get_len(session) >= task->ctx->worker->tcp_pipeline_max &&
+ !session_flags(session)->throttled && !session_flags(session)->closing) {
+ session_stop_read(session);
+ session_flags(session)->throttled = true;
+ }
+
+ return 0;
+}
+
+static void qr_task_complete(struct qr_task *task)
+{
+ struct request_ctx *ctx = task->ctx;
+
+ /* Kill pending I/O requests */
+ ioreq_kill_pending(task);
+ kr_require(task->waiting.len == 0);
+ kr_require(task->leading == false);
+
+ struct session *s = ctx->source.session;
+ if (s) {
+ kr_require(!session_flags(s)->outgoing && session_waitinglist_is_empty(s));
+ ctx->source.session = NULL;
+ session_tasklist_del(s, task);
+ }
+
+ /* Release primary reference to task. */
+ if (ctx->task == task) {
+ ctx->task = NULL;
+ qr_task_unref(task);
+ }
+}
+
+/* This is called when we send subrequest / answer */
+int qr_task_on_send(struct qr_task *task, const uv_handle_t *handle, int status)
+{
+ if (task->finished) {
+ kr_require(task->leading == false);
+ qr_task_complete(task);
+ }
+
+ if (!handle || kr_fails_assert(handle->data))
+ return status;
+ struct session* s = handle->data;
+
+ if (handle->type == UV_UDP && session_flags(s)->outgoing) {
+ // This should ensure that we are only dealing with our question to upstream
+ if (kr_fails_assert(!knot_wire_get_qr(task->pktbuf->wire)))
+ return status;
+ // start the timer
+ struct kr_query *qry = array_tail(task->ctx->req.rplan.pending);
+ if (kr_fails_assert(qry && task->transport))
+ return status;
+ size_t timeout = task->transport->timeout;
+ int ret = session_timer_start(s, on_udp_timeout, timeout, 0);
+ /* Start next step with timeout, fatal if can't start a timer. */
+ if (ret != 0) {
+ subreq_finalize(task, &task->transport->address.ip, task->pktbuf);
+ qr_task_finalize(task, KR_STATE_FAIL);
+ }
+ }
+
+ if (handle->type == UV_TCP) {
+ if (status != 0) { // session probably not usable anymore; typically: ECONNRESET
+ const struct kr_request *req = &task->ctx->req;
+ if (kr_log_is_debug(WORKER, req)) {
+ const char *peer_str = NULL;
+ if (!session_flags(s)->outgoing) {
+ peer_str = "hidden"; // avoid logging downstream IPs
+ } else if (task->transport) {
+ peer_str = kr_straddr(&task->transport->address.ip);
+ }
+ if (!peer_str)
+ peer_str = "unknown"; // probably shouldn't happen
+ kr_log_req(req, 0, 0, WORKER,
+ "=> disconnected from '%s': %s\n",
+ peer_str, uv_strerror(status));
+ }
+ worker_end_tcp(s);
+ return status;
+ }
+
+ if (session_flags(s)->outgoing || session_flags(s)->closing)
+ return status;
+
+ struct worker_ctx *worker = task->ctx->worker;
+ if (session_flags(s)->throttled &&
+ session_tasklist_get_len(s) < worker->tcp_pipeline_max/2) {
+ /* Start reading again if the session is throttled and
+ * the number of outgoing requests is below watermark. */
+ session_start_read(s);
+ session_flags(s)->throttled = false;
+ }
+ }
+
+ return status;
+}
+
+static void on_send(uv_udp_send_t *req, int status)
+{
+ struct qr_task *task = req->data;
+ uv_handle_t *h = (uv_handle_t *)req->handle;
+ qr_task_on_send(task, h, status);
+ qr_task_unref(task);
+ free(req);
+}
+
+static void on_write(uv_write_t *req, int status)
+{
+ struct qr_task *task = req->data;
+ uv_handle_t *h = (uv_handle_t *)req->handle;
+ qr_task_on_send(task, h, status);
+ qr_task_unref(task);
+ free(req);
+}
+
+static int qr_task_send(struct qr_task *task, struct session *session,
+ const struct sockaddr *addr, knot_pkt_t *pkt)
+{
+ if (!session)
+ return qr_task_on_send(task, NULL, kr_error(EIO));
+
+ int ret = 0;
+ struct request_ctx *ctx = task->ctx;
+
+ uv_handle_t *handle = session_get_handle(session);
+ if (kr_fails_assert(handle && handle->data == session))
+ return qr_task_on_send(task, NULL, kr_error(EINVAL));
+ const bool is_stream = handle->type == UV_TCP;
+ kr_require(is_stream || handle->type == UV_UDP);
+
+ if (addr == NULL)
+ addr = session_get_peer(session);
+
+ if (pkt == NULL)
+ pkt = worker_task_get_pktbuf(task);
+
+ if (session_flags(session)->outgoing && handle->type == UV_TCP) {
+ size_t try_limit = session_tasklist_get_len(session) + 1;
+ uint16_t msg_id = knot_wire_get_id(pkt->wire);
+ size_t try_count = 0;
+ while (session_tasklist_find_msgid(session, msg_id) &&
+ try_count <= try_limit) {
+ ++msg_id;
+ ++try_count;
+ }
+ if (try_count > try_limit)
+ return kr_error(ENOENT);
+ worker_task_pkt_set_msgid(task, msg_id);
+ }
+
+ struct worker_ctx *worker = ctx->worker;
+ /* Note time for upstream RTT */
+ task->send_time = kr_now();
+ task->recv_time = 0; // task structure is being reused so we have to zero this out here
+ /* Send using given protocol */
+ if (kr_fails_assert(!session_flags(session)->closing))
+ return qr_task_on_send(task, NULL, kr_error(EIO));
+
+ uv_handle_t *ioreq = malloc(is_stream ? sizeof(uv_write_t) : sizeof(uv_udp_send_t));
+ if (!ioreq)
+ return qr_task_on_send(task, handle, kr_error(ENOMEM));
+
+ /* Pending ioreq on current task */
+ qr_task_ref(task);
+
+ if (session_flags(session)->has_http) {
+#if ENABLE_DOH2
+ uv_write_t *write_req = (uv_write_t *)ioreq;
+ write_req->data = task;
+ ret = http_write(write_req, handle, pkt, ctx->req.qsource.stream_id, &on_write);
+#else
+ ret = kr_error(ENOPROTOOPT);
+#endif
+ } else if (session_flags(session)->has_tls) {
+ uv_write_t *write_req = (uv_write_t *)ioreq;
+ write_req->data = task;
+ ret = tls_write(write_req, handle, pkt, &on_write);
+ } else if (handle->type == UV_UDP) {
+ uv_udp_send_t *send_req = (uv_udp_send_t *)ioreq;
+ uv_buf_t buf = { (char *)pkt->wire, pkt->size };
+ send_req->data = task;
+ ret = uv_udp_send(send_req, (uv_udp_t *)handle, &buf, 1, addr, &on_send);
+ } else if (handle->type == UV_TCP) {
+ uv_write_t *write_req = (uv_write_t *)ioreq;
+ /* We need to write message length in native byte order,
+ * but we don't have a convenient place to store those bytes.
+ * The problem is that all memory referenced from buf[] MUST retain
+ * its contents at least until on_write() is called, and I currently
+ * can't see any convenient place outside the `pkt` structure.
+ * So we use directly the *individual* bytes in pkt->size.
+ * The call to htonl() and the condition will probably be inlinable. */
+ int lsbi, slsbi; /* (second) least significant byte index */
+ if (htonl(1) == 1) { /* big endian */
+ lsbi = sizeof(pkt->size) - 1;
+ slsbi = sizeof(pkt->size) - 2;
+ } else {
+ lsbi = 0;
+ slsbi = 1;
+ }
+ uv_buf_t buf[3] = {
+ { (char *)&pkt->size + slsbi, 1 },
+ { (char *)&pkt->size + lsbi, 1 },
+ { (char *)pkt->wire, pkt->size },
+ };
+ write_req->data = task;
+ ret = uv_write(write_req, (uv_stream_t *)handle, buf, 3, &on_write);
+ } else {
+ kr_assert(false);
+ }
+
+ if (ret == 0) {
+ session_touch(session);
+ if (session_flags(session)->outgoing) {
+ session_tasklist_add(session, task);
+ }
+ if (worker->too_many_open &&
+ worker->stats.rconcurrent <
+ worker->rconcurrent_highwatermark - 10) {
+ worker->too_many_open = false;
+ }
+ } else {
+ free(ioreq);
+ qr_task_unref(task);
+ if (ret == UV_EMFILE) {
+ worker->too_many_open = true;
+ worker->rconcurrent_highwatermark = worker->stats.rconcurrent;
+ ret = kr_error(UV_EMFILE);
+ }
+
+ if (session_flags(session)->has_http)
+ worker->stats.err_http += 1;
+ else if (session_flags(session)->has_tls)
+ worker->stats.err_tls += 1;
+ else if (handle->type == UV_UDP)
+ worker->stats.err_udp += 1;
+ else
+ worker->stats.err_tcp += 1;
+ }
+
+ /* Update outgoing query statistics */
+ if (session_flags(session)->outgoing && addr) {
+ if (session_flags(session)->has_tls)
+ worker->stats.tls += 1;
+ else if (handle->type == UV_UDP)
+ worker->stats.udp += 1;
+ else
+ worker->stats.tcp += 1;
+
+ if (addr->sa_family == AF_INET6)
+ worker->stats.ipv6 += 1;
+ else if (addr->sa_family == AF_INET)
+ worker->stats.ipv4 += 1;
+ }
+ return ret;
+}
+
+static struct kr_query *task_get_last_pending_query(struct qr_task *task)
+{
+ if (!task || task->ctx->req.rplan.pending.len == 0) {
+ return NULL;
+ }
+
+ return array_tail(task->ctx->req.rplan.pending);
+}
+
+static int session_tls_hs_cb(struct session *session, int status)
+{
+ if (kr_fails_assert(session_flags(session)->outgoing))
+ return kr_error(EINVAL);
+ struct sockaddr *peer = session_get_peer(session);
+ int deletion_res = worker_del_tcp_waiting(the_worker, peer);
+ int ret = kr_ok();
+
+ if (status) {
+ struct qr_task *task = session_waitinglist_get(session);
+ if (task) {
+ // TLS handshake failed, report it to server selection
+ struct kr_query *qry = array_tail(task->ctx->req.rplan.pending);
+ qry->server_selection.error(qry, task->transport, KR_SELECTION_TLS_HANDSHAKE_FAILED);
+ }
+#ifndef NDEBUG
+ else {
+ /* Task isn't in the list of tasks
+ * waiting for connection to upstream.
+ * So that it MUST be unsuccessful rehandshake.
+ * Check it. */
+ kr_require(deletion_res != 0);
+ struct kr_sockaddr_key_storage key;
+ ssize_t keylen = kr_sockaddr_key(&key, peer);
+ if (keylen < 0)
+ return keylen;
+ trie_val_t *val;
+ kr_require((val = trie_get_try(the_worker->tcp_connected, key.bytes, keylen)) && *val);
+ }
+#endif
+ return ret;
+ }
+
+ /* handshake was completed successfully */
+ struct tls_client_ctx *tls_client_ctx = session_tls_get_client_ctx(session);
+ tls_client_param_t *tls_params = tls_client_ctx->params;
+ gnutls_session_t tls_session = tls_client_ctx->c.tls_session;
+ if (gnutls_session_is_resumed(tls_session) != 0) {
+ kr_log_debug(TLSCLIENT, "TLS session has resumed\n");
+ } else {
+ kr_log_debug(TLSCLIENT, "TLS session has not resumed\n");
+ /* session wasn't resumed, delete old session data ... */
+ if (tls_params->session_data.data != NULL) {
+ gnutls_free(tls_params->session_data.data);
+ tls_params->session_data.data = NULL;
+ tls_params->session_data.size = 0;
+ }
+ /* ... and get the new session data */
+ gnutls_datum_t tls_session_data = { NULL, 0 };
+ ret = gnutls_session_get_data2(tls_session, &tls_session_data);
+ if (ret == 0) {
+ tls_params->session_data = tls_session_data;
+ }
+ }
+
+ struct session *s = worker_find_tcp_connected(the_worker, peer);
+ ret = kr_ok();
+ if (deletion_res == kr_ok()) {
+ /* peer was in the waiting list, add to the connected list. */
+ if (s) {
+ /* Something went wrong,
+ * peer already is in the connected list. */
+ ret = kr_error(EINVAL);
+ } else {
+ ret = worker_add_tcp_connected(the_worker, peer, session);
+ }
+ } else {
+ /* peer wasn't in the waiting list.
+ * It can be
+ * 1) either successful rehandshake; in this case peer
+ * must be already in the connected list.
+ * 2) or successful handshake with session, which was timed out
+ * by on_tcp_connect_timeout(); after successful tcp connection;
+ * in this case peer isn't in the connected list.
+ **/
+ if (!s || s != session) {
+ ret = kr_error(EINVAL);
+ }
+ }
+ if (ret == kr_ok()) {
+ while (!session_waitinglist_is_empty(session)) {
+ struct qr_task *t = session_waitinglist_get(session);
+ ret = qr_task_send(t, session, NULL, NULL);
+ if (ret != 0) {
+ break;
+ }
+ session_waitinglist_pop(session, true);
+ }
+ } else {
+ ret = kr_error(EINVAL);
+ }
+
+ if (ret != kr_ok()) {
+ /* Something went wrong.
+ * Either addition to the list of connected sessions
+ * or write to upstream failed. */
+ worker_del_tcp_connected(the_worker, peer);
+ session_waitinglist_finalize(session, KR_STATE_FAIL);
+ session_tasklist_finalize(session, KR_STATE_FAIL);
+ session_close(session);
+ } else {
+ session_timer_stop(session);
+ session_timer_start(session, tcp_timeout_trigger,
+ MAX_TCP_INACTIVITY, MAX_TCP_INACTIVITY);
+ }
+ return kr_ok();
+}
+
+static int send_waiting(struct session *session)
+{
+ int ret = 0;
+ while (!session_waitinglist_is_empty(session)) {
+ struct qr_task *t = session_waitinglist_get(session);
+ ret = qr_task_send(t, session, NULL, NULL);
+ if (ret != 0) {
+ struct worker_ctx *worker = t->ctx->worker;
+ struct sockaddr *peer = session_get_peer(session);
+ session_waitinglist_finalize(session, KR_STATE_FAIL);
+ session_tasklist_finalize(session, KR_STATE_FAIL);
+ worker_del_tcp_connected(worker, peer);
+ session_close(session);
+ break;
+ }
+ session_waitinglist_pop(session, true);
+ }
+ return ret;
+}
+
+static void on_connect(uv_connect_t *req, int status)
+{
+ struct worker_ctx *worker = the_worker;
+ kr_require(worker);
+ uv_stream_t *handle = req->handle;
+ struct session *session = handle->data;
+ struct sockaddr *peer = session_get_peer(session);
+ free(req);
+
+ if (kr_fails_assert(session_flags(session)->outgoing))
+ return;
+
+ if (session_flags(session)->closing) {
+ worker_del_tcp_waiting(worker, peer);
+ kr_assert(session_is_empty(session));
+ return;
+ }
+
+ const bool log_debug = kr_log_is_debug(WORKER, NULL);
+
+ /* Check if the connection is in the waiting list.
+ * If no, most likely this is timed out connection
+ * which was removed from waiting list by
+ * on_tcp_connect_timeout() callback. */
+ struct session *s = worker_find_tcp_waiting(worker, peer);
+ if (!s || s != session) {
+ /* session isn't on the waiting list.
+ * it's timed out session. */
+ if (log_debug) {
+ const char *peer_str = kr_straddr(peer);
+ kr_log_debug(WORKER, "=> connected to '%s', but session "
+ "is already timed out, close\n",
+ peer_str ? peer_str : "");
+ }
+ kr_assert(session_tasklist_is_empty(session));
+ session_waitinglist_retry(session, false);
+ session_close(session);
+ return;
+ }
+
+ s = worker_find_tcp_connected(worker, peer);
+ if (s) {
+ /* session already in the connected list.
+ * Something went wrong, it can be due to races when kresd has tried
+ * to reconnect to upstream after unsuccessful attempt. */
+ if (log_debug) {
+ const char *peer_str = kr_straddr(peer);
+ kr_log_debug(WORKER, "=> connected to '%s', but peer "
+ "is already connected, close\n",
+ peer_str ? peer_str : "");
+ }
+ kr_assert(session_tasklist_is_empty(session));
+ session_waitinglist_retry(session, false);
+ session_close(session);
+ return;
+ }
+
+ if (status != 0) {
+ if (log_debug) {
+ const char *peer_str = kr_straddr(peer);
+ kr_log_debug(WORKER, "=> connection to '%s' failed (%s), flagged as 'bad'\n",
+ peer_str ? peer_str : "", uv_strerror(status));
+ }
+ worker_del_tcp_waiting(worker, peer);
+ struct qr_task *task = session_waitinglist_get(session);
+ if (task && status != UV_ETIMEDOUT) {
+ /* Penalize upstream.
+ * In case of UV_ETIMEDOUT upstream has been
+ * already penalized in on_tcp_connect_timeout() */
+ struct kr_query *qry = array_tail(task->ctx->req.rplan.pending);
+ qry->server_selection.error(qry, task->transport, KR_SELECTION_TCP_CONNECT_FAILED);
+ }
+ kr_assert(session_tasklist_is_empty(session));
+ session_waitinglist_retry(session, false);
+ session_close(session);
+ return;
+ }
+
+ if (!session_flags(session)->has_tls) {
+ /* if there is a TLS, session still waiting for handshake,
+ * otherwise remove it from waiting list */
+ if (worker_del_tcp_waiting(worker, peer) != 0) {
+ /* session isn't in list of waiting queries, *
+ * something gone wrong */
+ session_waitinglist_finalize(session, KR_STATE_FAIL);
+ kr_assert(session_tasklist_is_empty(session));
+ session_close(session);
+ return;
+ }
+ }
+
+ if (log_debug) {
+ const char *peer_str = kr_straddr(peer);
+ kr_log_debug(WORKER, "=> connected to '%s'\n", peer_str ? peer_str : "");
+ }
+
+ session_flags(session)->connected = true;
+ session_start_read(session);
+
+ int ret = kr_ok();
+ if (session_flags(session)->has_tls) {
+ struct tls_client_ctx *tls_ctx = session_tls_get_client_ctx(session);
+ ret = tls_client_connect_start(tls_ctx, session, session_tls_hs_cb);
+ if (ret == kr_error(EAGAIN)) {
+ session_timer_stop(session);
+ session_timer_start(session, tcp_timeout_trigger,
+ MAX_TCP_INACTIVITY, MAX_TCP_INACTIVITY);
+ return;
+ }
+ } else {
+ worker_add_tcp_connected(worker, peer, session);
+ }
+
+ ret = send_waiting(session);
+ if (ret != 0) {
+ return;
+ }
+
+ session_timer_stop(session);
+ session_timer_start(session, tcp_timeout_trigger,
+ MAX_TCP_INACTIVITY, MAX_TCP_INACTIVITY);
+}
+
+static void on_tcp_connect_timeout(uv_timer_t *timer)
+{
+ struct session *session = timer->data;
+
+ uv_timer_stop(timer);
+ struct worker_ctx *worker = the_worker;
+ kr_require(worker);
+
+ kr_assert(session_tasklist_is_empty(session));
+
+ struct sockaddr *peer = session_get_peer(session);
+ worker_del_tcp_waiting(worker, peer);
+
+ struct qr_task *task = session_waitinglist_get(session);
+ if (!task) {
+ /* Normally shouldn't happen. */
+ const char *peer_str = kr_straddr(peer);
+ VERBOSE_MSG(NULL, "=> connection to '%s' failed (internal timeout), empty waitinglist\n",
+ peer_str ? peer_str : "");
+ return;
+ }
+
+ struct kr_query *qry = task_get_last_pending_query(task);
+ if (kr_log_is_debug_qry(WORKER, qry)) {
+ const char *peer_str = kr_straddr(peer);
+ VERBOSE_MSG(qry, "=> connection to '%s' failed (internal timeout)\n",
+ peer_str ? peer_str : "");
+ }
+
+ qry->server_selection.error(qry, task->transport, KR_SELECTION_TCP_CONNECT_TIMEOUT);
+
+ worker->stats.timeout += session_waitinglist_get_len(session);
+ session_waitinglist_retry(session, true);
+ kr_assert(session_tasklist_is_empty(session));
+ /* uv_cancel() doesn't support uv_connect_t request,
+ * so that we can't cancel it.
+ * There still exists possibility of successful connection
+ * for this request.
+ * So connection callback (on_connect()) must check
+ * if connection is in the list of waiting connection.
+ * If no, most likely this is timed out connection even if
+ * it was successful. */
+}
+
+/* This is called when I/O timeouts */
+static void on_udp_timeout(uv_timer_t *timer)
+{
+ struct session *session = timer->data;
+ kr_assert(session_get_handle(session)->data == session);
+ kr_assert(session_tasklist_get_len(session) == 1);
+ kr_assert(session_waitinglist_is_empty(session));
+
+ uv_timer_stop(timer);
+
+ struct qr_task *task = session_tasklist_get_first(session);
+ if (!task)
+ return;
+ struct worker_ctx *worker = task->ctx->worker;
+
+ if (task->leading && task->pending_count > 0) {
+ struct kr_query *qry = array_tail(task->ctx->req.rplan.pending);
+ qry->server_selection.error(qry, task->transport, KR_SELECTION_QUERY_TIMEOUT);
+ }
+
+ task->timeouts += 1;
+ worker->stats.timeout += 1;
+ qr_task_step(task, NULL, NULL);
+}
+
+static uv_handle_t *transmit(struct qr_task *task)
+{
+ uv_handle_t *ret = NULL;
+
+ if (task) {
+ struct kr_transport* transport = task->transport;
+
+ struct sockaddr_in6 *choice = (struct sockaddr_in6 *)&transport->address;
+
+ if (!choice) {
+ return ret;
+ }
+ if (task->pending_count >= MAX_PENDING) {
+ return ret;
+ }
+ /* Checkout answer before sending it */
+ struct request_ctx *ctx = task->ctx;
+ if (kr_resolve_checkout(&ctx->req, NULL, transport, task->pktbuf) != 0) {
+ return ret;
+ }
+ ret = ioreq_spawn(ctx->worker, SOCK_DGRAM, choice->sin6_family, false, false);
+ if (!ret) {
+ return ret;
+ }
+ struct sockaddr *addr = (struct sockaddr *)choice;
+ struct session *session = ret->data;
+ struct sockaddr *peer = session_get_peer(session);
+ kr_assert(peer->sa_family == AF_UNSPEC && session_flags(session)->outgoing);
+ kr_require(addr->sa_family == AF_INET || addr->sa_family == AF_INET6);
+ memcpy(peer, addr, kr_sockaddr_len(addr));
+ if (qr_task_send(task, session, (struct sockaddr *)choice,
+ task->pktbuf) != 0) {
+ session_close(session);
+ ret = NULL;
+ } else {
+ task->pending[task->pending_count] = session;
+ task->pending_count += 1;
+ session_start_read(session); /* Start reading answer */
+ }
+ }
+ return ret;
+}
+
+
+static void subreq_finalize(struct qr_task *task, const struct sockaddr *packet_source, knot_pkt_t *pkt)
+{
+ if (!task || task->finished) {
+ return;
+ }
+ /* Close pending timer */
+ ioreq_kill_pending(task);
+ /* Clear from outgoing table. */
+ if (!task->leading)
+ return;
+ char key[SUBREQ_KEY_LEN];
+ const int klen = subreq_key(key, task->pktbuf);
+ if (klen > 0) {
+ void *val_deleted;
+ int ret = trie_del(task->ctx->worker->subreq_out, key, klen, &val_deleted);
+ kr_assert(ret == KNOT_EOK && val_deleted == task);
+ }
+ /* Notify waiting tasks. */
+ struct kr_query *leader_qry = array_tail(task->ctx->req.rplan.pending);
+ for (size_t i = task->waiting.len; i > 0; i--) {
+ struct qr_task *follower = task->waiting.at[i - 1];
+ /* Reuse MSGID and 0x20 secret */
+ if (follower->ctx->req.rplan.pending.len > 0) {
+ struct kr_query *qry = array_tail(follower->ctx->req.rplan.pending);
+ qry->id = leader_qry->id;
+ qry->secret = leader_qry->secret;
+
+ // Note that this transport may not be present in `leader_qry`'s server selection
+ follower->transport = task->transport;
+ if(follower->transport) {
+ follower->transport->deduplicated = true;
+ }
+ leader_qry->secret = 0; /* Next will be already decoded */
+ }
+ qr_task_step(follower, packet_source, pkt);
+ qr_task_unref(follower);
+ }
+ task->waiting.len = 0;
+ task->leading = false;
+}
+
+static void subreq_lead(struct qr_task *task)
+{
+ if (kr_fails_assert(task))
+ return;
+ char key[SUBREQ_KEY_LEN];
+ const int klen = subreq_key(key, task->pktbuf);
+ if (klen < 0)
+ return;
+ struct qr_task **tvp = (struct qr_task **)
+ trie_get_ins(task->ctx->worker->subreq_out, key, klen);
+ if (unlikely(!tvp))
+ return; /*ENOMEM*/
+ if (kr_fails_assert(*tvp == NULL))
+ return;
+ *tvp = task;
+ task->leading = true;
+}
+
+static bool subreq_enqueue(struct qr_task *task)
+{
+ if (kr_fails_assert(task))
+ return false;
+ char key[SUBREQ_KEY_LEN];
+ const int klen = subreq_key(key, task->pktbuf);
+ if (klen < 0)
+ return false;
+ struct qr_task **leader = (struct qr_task **)
+ trie_get_try(task->ctx->worker->subreq_out, key, klen);
+ if (!leader /*ENOMEM*/ || !*leader)
+ return false;
+ /* Enqueue itself to leader for this subrequest. */
+ int ret = array_push_mm((*leader)->waiting, task,
+ kr_memreserve, &(*leader)->ctx->req.pool);
+ if (unlikely(ret < 0)) /*ENOMEM*/
+ return false;
+ qr_task_ref(task);
+ return true;
+}
+
+#if ENABLE_XDP
+static void xdp_tx_waker(uv_idle_t *handle)
+{
+ int ret = knot_xdp_send_finish(handle->data);
+ if (ret != KNOT_EAGAIN && ret != KNOT_EOK)
+ kr_log_error(XDP, "check: ret = %d, %s\n", ret, knot_strerror(ret));
+ /* Apparently some drivers need many explicit wake-up calls
+ * even if we push no additional packets (in case they accumulated a lot) */
+ if (ret != KNOT_EAGAIN)
+ uv_idle_stop(handle);
+ knot_xdp_send_prepare(handle->data);
+ /* LATER(opt.): it _might_ be better for performance to do these two steps
+ * at different points in time */
+}
+#endif
+/** Send an answer packet over XDP. */
+static int xdp_push(struct qr_task *task, const uv_handle_t *src_handle)
+{
+#if ENABLE_XDP
+ struct request_ctx *ctx = task->ctx;
+ xdp_handle_data_t *xhd = src_handle->data;
+ if (kr_fails_assert(xhd && xhd->socket && xhd->session == ctx->source.session))
+ return qr_task_on_send(task, src_handle, kr_error(EINVAL));
+
+ knot_xdp_msg_t msg;
+#if KNOT_VERSION_HEX >= 0x030100
+ /* We don't have a nice way of preserving the _msg_t from frame allocation,
+ * so we manually redo all other parts of knot_xdp_send_alloc() */
+ memset(&msg, 0, sizeof(msg));
+ bool ipv6 = ctx->source.addr.ip.sa_family == AF_INET6;
+ msg.flags = ipv6 ? KNOT_XDP_MSG_IPV6 : 0;
+ memcpy(msg.eth_from, &ctx->source.eth_addrs[0], 6);
+ memcpy(msg.eth_to, &ctx->source.eth_addrs[1], 6);
+#endif
+ const struct sockaddr *ip_from = &ctx->source.dst_addr.ip;
+ const struct sockaddr *ip_to = &ctx->source.comm_addr.ip;
+ memcpy(&msg.ip_from, ip_from, kr_sockaddr_len(ip_from));
+ memcpy(&msg.ip_to, ip_to, kr_sockaddr_len(ip_to));
+ msg.payload.iov_base = ctx->req.answer->wire;
+ msg.payload.iov_len = ctx->req.answer->size;
+
+ uint32_t sent;
+ int ret = knot_xdp_send(xhd->socket, &msg, 1, &sent);
+ ctx->req.answer->wire = NULL; /* it's been freed */
+
+ uv_idle_start(&xhd->tx_waker, xdp_tx_waker);
+ kr_log_debug(XDP, "pushed a packet, ret = %d\n", ret);
+
+ return qr_task_on_send(task, src_handle, ret);
+#else
+ kr_assert(!EINVAL);
+ return kr_error(EINVAL);
+#endif
+}
+
+static int qr_task_finalize(struct qr_task *task, int state)
+{
+ kr_require(task && task->leading == false);
+ if (task->finished) {
+ return kr_ok();
+ }
+ struct request_ctx *ctx = task->ctx;
+ struct session *source_session = ctx->source.session;
+ kr_resolve_finish(&ctx->req, state);
+
+ task->finished = true;
+ if (source_session == NULL) {
+ (void) qr_task_on_send(task, NULL, kr_error(EIO));
+ return state == KR_STATE_DONE ? kr_ok() : kr_error(EIO);
+ }
+
+ /* meant to be dropped */
+ if (unlikely(ctx->req.answer == NULL || ctx->req.options.NO_ANSWER)) {
+ /* For NO_ANSWER, a well-behaved layer should set the state to FAIL */
+ kr_assert(!ctx->req.options.NO_ANSWER || (ctx->req.state & KR_STATE_FAIL));
+
+ (void) qr_task_on_send(task, NULL, kr_ok());
+ return kr_ok();
+ }
+
+ if (session_flags(source_session)->closing ||
+ ctx->source.addr.ip.sa_family == AF_UNSPEC)
+ return kr_error(EINVAL);
+
+ /* Reference task as the callback handler can close it */
+ qr_task_ref(task);
+
+ /* Send back answer */
+ int ret;
+ const uv_handle_t *src_handle = session_get_handle(source_session);
+ if (kr_fails_assert(src_handle->type == UV_UDP || src_handle->type == UV_TCP
+ || src_handle->type == UV_POLL)) {
+ ret = kr_error(EINVAL);
+ } else if (src_handle->type == UV_POLL) {
+ ret = xdp_push(task, src_handle);
+ } else if (src_handle->type == UV_UDP && ENABLE_SENDMMSG) {
+ int fd;
+ ret = uv_fileno(src_handle, &fd);
+ if (ret == 0)
+ udp_queue_push(fd, &ctx->req, task);
+ else
+ kr_assert(false);
+ } else {
+ ret = qr_task_send(task, source_session, &ctx->source.comm_addr.ip, ctx->req.answer);
+ }
+
+ if (ret != kr_ok()) {
+ (void) qr_task_on_send(task, NULL, kr_error(EIO));
+ /* Since source session is erroneous detach all tasks. */
+ while (!session_tasklist_is_empty(source_session)) {
+ struct qr_task *t = session_tasklist_del_first(source_session, false);
+ struct request_ctx *c = t->ctx;
+ kr_assert(c->source.session == source_session);
+ c->source.session = NULL;
+ /* Don't finalize them as there can be other tasks
+ * waiting for answer to this particular task.
+ * (ie. task->leading is true) */
+ worker_task_unref(t);
+ }
+ session_close(source_session);
+ }
+
+ qr_task_unref(task);
+
+ if (ret != kr_ok() || state != KR_STATE_DONE)
+ return kr_error(EIO);
+ return kr_ok();
+}
+
+static int udp_task_step(struct qr_task *task,
+ const struct sockaddr *packet_source, knot_pkt_t *packet)
+{
+ /* If there is already outgoing query, enqueue to it. */
+ if (subreq_enqueue(task)) {
+ return kr_ok(); /* Will be notified when outgoing query finishes. */
+ }
+ /* Start transmitting */
+ uv_handle_t *handle = transmit(task);
+ if (handle == NULL) {
+ subreq_finalize(task, packet_source, packet);
+ return qr_task_finalize(task, KR_STATE_FAIL);
+ }
+
+ /* Announce and start subrequest.
+ * @note Only UDP can lead I/O as it doesn't touch 'task->pktbuf' for reassembly.
+ */
+ subreq_lead(task);
+
+ return kr_ok();
+}
+
+static int tcp_task_waiting_connection(struct session *session, struct qr_task *task)
+{
+ if (kr_fails_assert(session_flags(session)->outgoing && !session_flags(session)->closing))
+ return kr_error(EINVAL);
+ /* Add task to the end of list of waiting tasks.
+ * It will be notified in on_connect() or qr_task_on_send(). */
+ int ret = session_waitinglist_push(session, task);
+ if (ret < 0) {
+ return kr_error(EINVAL);
+ }
+ return kr_ok();
+}
+
+static int tcp_task_existing_connection(struct session *session, struct qr_task *task)
+{
+ if (kr_fails_assert(session_flags(session)->outgoing && !session_flags(session)->closing))
+ return kr_error(EINVAL);
+ struct request_ctx *ctx = task->ctx;
+ struct worker_ctx *worker = ctx->worker;
+
+ /* If there are any unsent queries, send it first. */
+ int ret = send_waiting(session);
+ if (ret != 0) {
+ return kr_error(EINVAL);
+ }
+
+ /* No unsent queries at that point. */
+ if (session_tasklist_get_len(session) >= worker->tcp_pipeline_max) {
+ /* Too many outstanding queries, answer with SERVFAIL, */
+ return kr_error(EINVAL);
+ }
+
+ /* Send query to upstream. */
+ ret = qr_task_send(task, session, NULL, NULL);
+ if (ret != 0) {
+ /* Error, finalize task with SERVFAIL and
+ * close connection to upstream. */
+ session_tasklist_finalize(session, KR_STATE_FAIL);
+ worker_del_tcp_connected(worker, session_get_peer(session));
+ session_close(session);
+ return kr_error(EINVAL);
+ }
+
+ return kr_ok();
+}
+
+static int tcp_task_make_connection(struct qr_task *task, const struct sockaddr *addr)
+{
+ struct request_ctx *ctx = task->ctx;
+ struct worker_ctx *worker = ctx->worker;
+
+ /* Check if there must be TLS */
+ struct tls_client_ctx *tls_ctx = NULL;
+ struct network *net = &worker->engine->net;
+ tls_client_param_t *entry = tls_client_param_get(net->tls_client_params, addr);
+ if (entry) {
+ /* Address is configured to be used with TLS.
+ * We need to allocate auxiliary data structure. */
+ tls_ctx = tls_client_ctx_new(entry, worker);
+ if (!tls_ctx) {
+ return kr_error(EINVAL);
+ }
+ }
+
+ uv_connect_t *conn = malloc(sizeof(uv_connect_t));
+ if (!conn) {
+ tls_client_ctx_free(tls_ctx);
+ return kr_error(EINVAL);
+ }
+ bool has_http = false;
+ bool has_tls = (tls_ctx != NULL);
+ uv_handle_t *client = ioreq_spawn(worker, SOCK_STREAM, addr->sa_family, has_tls, has_http);
+ if (!client) {
+ tls_client_ctx_free(tls_ctx);
+ free(conn);
+ return kr_error(EINVAL);
+ }
+ struct session *session = client->data;
+ if (kr_fails_assert(session_flags(session)->has_tls == has_tls)) {
+ tls_client_ctx_free(tls_ctx);
+ free(conn);
+ return kr_error(EINVAL);
+ }
+ if (has_tls) {
+ tls_client_ctx_set_session(tls_ctx, session);
+ session_tls_set_client_ctx(session, tls_ctx);
+ }
+
+ /* Add address to the waiting list.
+ * Now it "is waiting to be connected to." */
+ int ret = worker_add_tcp_waiting(worker, addr, session);
+ if (ret < 0) {
+ free(conn);
+ session_close(session);
+ return kr_error(EINVAL);
+ }
+
+ conn->data = session;
+ /* Store peer address for the session. */
+ struct sockaddr *peer = session_get_peer(session);
+ memcpy(peer, addr, kr_sockaddr_len(addr));
+
+ /* Start watchdog to catch eventual connection timeout. */
+ ret = session_timer_start(session, on_tcp_connect_timeout,
+ KR_CONN_RTT_MAX, 0);
+ if (ret != 0) {
+ worker_del_tcp_waiting(worker, addr);
+ free(conn);
+ session_close(session);
+ return kr_error(EINVAL);
+ }
+
+ struct kr_query *qry = task_get_last_pending_query(task);
+ if (kr_log_is_debug_qry(WORKER, qry)) {
+ const char *peer_str = kr_straddr(peer);
+ VERBOSE_MSG(qry, "=> connecting to: '%s'\n", peer_str ? peer_str : "");
+ }
+
+ /* Start connection process to upstream. */
+ ret = uv_tcp_connect(conn, (uv_tcp_t *)client, addr , on_connect);
+ if (ret != 0) {
+ session_timer_stop(session);
+ worker_del_tcp_waiting(worker, addr);
+ free(conn);
+ session_close(session);
+ qry->server_selection.error(qry, task->transport, KR_SELECTION_TCP_CONNECT_FAILED);
+ return kr_error(EAGAIN);
+ }
+
+ /* Add task to the end of list of waiting tasks.
+ * Will be notified either in on_connect() or in qr_task_on_send(). */
+ ret = session_waitinglist_push(session, task);
+ if (ret < 0) {
+ session_timer_stop(session);
+ worker_del_tcp_waiting(worker, addr);
+ free(conn);
+ session_close(session);
+ return kr_error(EINVAL);
+ }
+
+ return kr_ok();
+}
+
+static int tcp_task_step(struct qr_task *task,
+ const struct sockaddr *packet_source, knot_pkt_t *packet)
+{
+ if (kr_fails_assert(task->pending_count == 0)) {
+ subreq_finalize(task, packet_source, packet);
+ return qr_task_finalize(task, KR_STATE_FAIL);
+ }
+
+ /* target */
+ const struct sockaddr *addr = &task->transport->address.ip;
+ if (addr->sa_family == AF_UNSPEC) {
+ /* Target isn't defined. Finalize task with SERVFAIL.
+ * Although task->pending_count is zero, there are can be followers,
+ * so we need to call subreq_finalize() to handle them properly. */
+ subreq_finalize(task, packet_source, packet);
+ return qr_task_finalize(task, KR_STATE_FAIL);
+ }
+ /* Checkout task before connecting */
+ struct request_ctx *ctx = task->ctx;
+ if (kr_resolve_checkout(&ctx->req, NULL, task->transport, task->pktbuf) != 0) {
+ subreq_finalize(task, packet_source, packet);
+ return qr_task_finalize(task, KR_STATE_FAIL);
+ }
+ int ret;
+ struct session* session = NULL;
+ if ((session = worker_find_tcp_waiting(ctx->worker, addr)) != NULL) {
+ /* Connection is in the list of waiting connections.
+ * It means that connection establishing is coming right now. */
+ ret = tcp_task_waiting_connection(session, task);
+ } else if ((session = worker_find_tcp_connected(ctx->worker, addr)) != NULL) {
+ /* Connection has been already established. */
+ ret = tcp_task_existing_connection(session, task);
+ } else {
+ /* Make connection. */
+ ret = tcp_task_make_connection(task, addr);
+ }
+
+ if (ret != kr_ok()) {
+ subreq_finalize(task, addr, packet);
+ if (ret == kr_error(EAGAIN)) {
+ ret = qr_task_step(task, addr, NULL);
+ } else {
+ ret = qr_task_finalize(task, KR_STATE_FAIL);
+ }
+ }
+
+ return ret;
+}
+
+static int qr_task_step(struct qr_task *task,
+ const struct sockaddr *packet_source, knot_pkt_t *packet)
+{
+ /* No more steps after we're finished. */
+ if (!task || task->finished) {
+ return kr_error(ESTALE);
+ }
+
+ /* Close pending I/O requests */
+ subreq_finalize(task, packet_source, packet);
+ if ((kr_now() - worker_task_creation_time(task)) >= KR_RESOLVE_TIME_LIMIT) {
+ struct kr_request *req = worker_task_request(task);
+ if (!kr_fails_assert(req))
+ kr_query_inform_timeout(req, req->current_query);
+ return qr_task_finalize(task, KR_STATE_FAIL);
+ }
+
+ /* Consume input and produce next query */
+ struct request_ctx *ctx = task->ctx;
+ if (kr_fails_assert(ctx))
+ return qr_task_finalize(task, KR_STATE_FAIL);
+ struct kr_request *req = &ctx->req;
+ struct worker_ctx *worker = ctx->worker;
+
+ if (worker->too_many_open) {
+ /* */
+ struct kr_rplan *rplan = &req->rplan;
+ if (worker->stats.rconcurrent <
+ worker->rconcurrent_highwatermark - 10) {
+ worker->too_many_open = false;
+ } else {
+ if (packet && kr_rplan_empty(rplan)) {
+ /* new query; TODO - make this detection more obvious */
+ kr_resolve_consume(req, &task->transport, packet);
+ }
+ return qr_task_finalize(task, KR_STATE_FAIL);
+ }
+ }
+
+ // Report network RTT back to server selection
+ if (packet && task->send_time && task->recv_time) {
+ struct kr_query *qry = array_tail(req->rplan.pending);
+ qry->server_selection.update_rtt(qry, task->transport, task->recv_time - task->send_time);
+ }
+
+ int state = kr_resolve_consume(req, &task->transport, packet);
+
+ task->transport = NULL;
+ while (state == KR_STATE_PRODUCE) {
+ state = kr_resolve_produce(req, &task->transport, task->pktbuf);
+ if (unlikely(++task->iter_count > KR_ITER_LIMIT ||
+ task->timeouts >= KR_TIMEOUT_LIMIT)) {
+
+ struct kr_rplan *rplan = &req->rplan;
+ struct kr_query *last = kr_rplan_last(rplan);
+ if (task->iter_count > KR_ITER_LIMIT) {
+ char *msg = "cancelling query due to exceeded iteration count limit";
+ VERBOSE_MSG(last, "%s of %d\n", msg, KR_ITER_LIMIT);
+ kr_request_set_extended_error(req, KNOT_EDNS_EDE_OTHER,
+ "OGHD: exceeded iteration count limit");
+ }
+ if (task->timeouts >= KR_TIMEOUT_LIMIT) {
+ char *msg = "cancelling query due to exceeded timeout retries limit";
+ VERBOSE_MSG(last, "%s of %d\n", msg, KR_TIMEOUT_LIMIT);
+ kr_request_set_extended_error(req, KNOT_EDNS_EDE_NREACH_AUTH, "QLPL");
+ }
+
+ return qr_task_finalize(task, KR_STATE_FAIL);
+ }
+ }
+
+ /* We're done, no more iterations needed */
+ if (state & (KR_STATE_DONE|KR_STATE_FAIL)) {
+ return qr_task_finalize(task, state);
+ } else if (!task->transport || !task->transport->protocol) {
+ return qr_task_step(task, NULL, NULL);
+ }
+
+ switch (task->transport->protocol)
+ {
+ case KR_TRANSPORT_UDP:
+ return udp_task_step(task, packet_source, packet);
+ case KR_TRANSPORT_TCP: // fall through
+ case KR_TRANSPORT_TLS:
+ return tcp_task_step(task, packet_source, packet);
+ default:
+ kr_assert(!EINVAL);
+ return kr_error(EINVAL);
+ }
+}
+
+int worker_submit(struct session *session, struct io_comm_data *comm,
+ const uint8_t *eth_from, const uint8_t *eth_to, knot_pkt_t *pkt)
+{
+ if (!session || !pkt)
+ return kr_error(EINVAL);
+
+ uv_handle_t *handle = session_get_handle(session);
+ if (!handle || !handle->loop->data)
+ return kr_error(EINVAL);
+
+ const bool is_query = pkt->size > KNOT_WIRE_OFFSET_FLAGS1
+ && knot_wire_get_qr(pkt->wire) == 0;
+ const bool is_outgoing = session_flags(session)->outgoing;
+
+ int ret = 0;
+ if (is_query == is_outgoing)
+ ret = KNOT_ENOENT;
+
+ // For responses from upstream, try to find associated task and query.
+ // In case of errors, at least try to guess.
+ struct qr_task *task = NULL;
+ bool task_matched_id = false;
+ if (is_outgoing && pkt->size >= 2) {
+ const uint16_t id = knot_wire_get_id(pkt->wire);
+ task = session_tasklist_del_msgid(session, id);
+ task_matched_id = task != NULL;
+ if (task_matched_id) // Note receive time for RTT calculation
+ task->recv_time = kr_now();
+ if (!task_matched_id) {
+ ret = KNOT_ENOENT;
+ VERBOSE_MSG(NULL, "=> DNS message with mismatching ID %d\n",
+ (int)id);
+ }
+ }
+ if (!task && is_outgoing && handle->type == UV_TCP) {
+ // Source address of the reply got somewhat validated,
+ // so we try to at least guess which query, for error reporting.
+ task = session_tasklist_get_first(session);
+ }
+ struct kr_query *qry = NULL;
+ if (task)
+ qry = array_tail(task->ctx->req.rplan.pending);
+
+ // Parse the packet, unless it's useless anyway.
+ if (ret == 0) {
+ ret = knot_pkt_parse(pkt, 0);
+ if (ret == KNOT_ETRAIL && is_outgoing
+ && !kr_fails_assert(pkt->parsed < pkt->size)) {
+ // We deal with this later, so that RCODE takes priority.
+ ret = 0;
+ }
+ if (ret && kr_log_is_debug_qry(WORKER, qry)) {
+ VERBOSE_MSG(qry, "=> DNS message failed to parse, %s\n",
+ knot_strerror(ret));
+ }
+ }
+
+ struct http_ctx *http_ctx = NULL;
+#if ENABLE_DOH2
+ http_ctx = session_http_get_server_ctx(session);
+
+ /* Badly formed query when using DoH leads to a Bad Request */
+ if (http_ctx && !is_outgoing && ret) {
+ http_send_status(session, HTTP_STATUS_BAD_REQUEST);
+ return kr_error(ret);
+ }
+#endif
+
+ if (!is_outgoing && http_ctx && queue_len(http_ctx->streams) <= 0)
+ return kr_error(ENOENT);
+
+ const struct sockaddr *addr = comm ? comm->src_addr : NULL;
+
+ /* Ignore badly formed queries. */
+ if (ret) {
+ if (is_outgoing && qry) // unusuable response from somewhat validated IP
+ qry->server_selection.error(qry, task->transport, KR_SELECTION_MALFORMED);
+ if (!is_outgoing)
+ the_worker->stats.dropped += 1;
+ if (task_matched_id) // notify task that answer won't be coming anymore
+ qr_task_step(task, addr, NULL);
+ return kr_error(EILSEQ);
+ }
+
+ /* Start new task on listening sockets,
+ * or resume if this is subrequest */
+ if (!is_outgoing) { /* request from a client */
+ struct request_ctx *ctx =
+ request_create(the_worker, session, comm, eth_from,
+ eth_to, knot_wire_get_id(pkt->wire));
+ if (http_ctx)
+ queue_pop(http_ctx->streams);
+ if (!ctx)
+ return kr_error(ENOMEM);
+
+ ret = request_start(ctx, pkt);
+ if (ret != 0) {
+ request_free(ctx);
+ return kr_error(ENOMEM);
+ }
+
+ task = qr_task_create(ctx);
+ if (!task) {
+ request_free(ctx);
+ return kr_error(ENOMEM);
+ }
+
+ if (handle->type == UV_TCP && qr_task_register(task, session)) {
+ return kr_error(ENOMEM);
+ }
+ } else { /* response from upstream */
+ if (task == NULL) {
+ return kr_error(ENOENT);
+ }
+ if (kr_fails_assert(!session_flags(session)->closing))
+ return kr_error(EINVAL);
+ }
+ if (kr_fails_assert(!uv_is_closing(session_get_handle(session))))
+ return kr_error(EINVAL);
+
+ /* Packet was successfully parsed.
+ * Task was created (found). */
+ session_touch(session);
+
+ /* Consume input and produce next message */
+ return qr_task_step(task, addr, pkt);
+}
+
+static int trie_add_tcp_session(trie_t *trie, const struct sockaddr *addr,
+ struct session *session)
+{
+ if (kr_fails_assert(trie && addr))
+ return kr_error(EINVAL);
+ struct kr_sockaddr_key_storage key;
+ ssize_t keylen = kr_sockaddr_key(&key, addr);
+ if (keylen < 0)
+ return keylen;
+ trie_val_t *val = trie_get_ins(trie, key.bytes, keylen);
+ if (kr_fails_assert(*val == NULL))
+ return kr_error(EINVAL);
+ *val = session;
+ return kr_ok();
+}
+
+static int trie_del_tcp_session(trie_t *trie, const struct sockaddr *addr)
+{
+ if (kr_fails_assert(trie && addr))
+ return kr_error(EINVAL);
+ struct kr_sockaddr_key_storage key;
+ ssize_t keylen = kr_sockaddr_key(&key, addr);
+ if (keylen < 0)
+ return keylen;
+ int ret = trie_del(trie, key.bytes, keylen, NULL);
+ return ret ? kr_error(ENOENT) : kr_ok();
+}
+
+static struct session *trie_find_tcp_session(trie_t *trie,
+ const struct sockaddr *addr)
+{
+ if (kr_fails_assert(trie && addr))
+ return NULL;
+ struct kr_sockaddr_key_storage key;
+ ssize_t keylen = kr_sockaddr_key(&key, addr);
+ if (keylen < 0)
+ return NULL;
+ trie_val_t *val = trie_get_try(trie, key.bytes, keylen);
+ return val ? *val : NULL;
+}
+
+int worker_add_tcp_connected(struct worker_ctx *worker,
+ const struct sockaddr* addr,
+ struct session *session)
+{
+ return trie_add_tcp_session(worker->tcp_connected, addr, session);
+}
+
+int worker_del_tcp_connected(struct worker_ctx *worker,
+ const struct sockaddr* addr)
+{
+ return trie_del_tcp_session(worker->tcp_connected, addr);
+}
+
+struct session* worker_find_tcp_connected(struct worker_ctx *worker,
+ const struct sockaddr* addr)
+{
+ return trie_find_tcp_session(worker->tcp_connected, addr);
+}
+
+static int worker_add_tcp_waiting(struct worker_ctx *worker,
+ const struct sockaddr* addr,
+ struct session *session)
+{
+ return trie_add_tcp_session(worker->tcp_waiting, addr, session);
+}
+
+int worker_del_tcp_waiting(struct worker_ctx *worker,
+ const struct sockaddr* addr)
+{
+ return trie_del_tcp_session(worker->tcp_waiting, addr);
+}
+
+struct session* worker_find_tcp_waiting(struct worker_ctx *worker,
+ const struct sockaddr* addr)
+{
+ return trie_find_tcp_session(worker->tcp_waiting, addr);
+}
+
+int worker_end_tcp(struct session *session)
+{
+ if (!session)
+ return kr_error(EINVAL);
+
+ session_timer_stop(session);
+
+ struct sockaddr *peer = session_get_peer(session);
+
+ worker_del_tcp_waiting(the_worker, peer);
+ worker_del_tcp_connected(the_worker, peer);
+ session_flags(session)->connected = false;
+
+ struct tls_client_ctx *tls_client_ctx = session_tls_get_client_ctx(session);
+ if (tls_client_ctx) {
+ /* Avoid gnutls_bye() call */
+ tls_set_hs_state(&tls_client_ctx->c, TLS_HS_NOT_STARTED);
+ }
+
+ struct tls_ctx *tls_ctx = session_tls_get_server_ctx(session);
+ if (tls_ctx) {
+ /* Avoid gnutls_bye() call */
+ tls_set_hs_state(&tls_ctx->c, TLS_HS_NOT_STARTED);
+ }
+
+ while (!session_waitinglist_is_empty(session)) {
+ struct qr_task *task = session_waitinglist_pop(session, false);
+ kr_assert(task->refs > 1);
+ session_tasklist_del(session, task);
+ if (session_flags(session)->outgoing) {
+ if (task->ctx->req.options.FORWARD) {
+ /* We are in TCP_FORWARD mode.
+ * To prevent failing at kr_resolve_consume()
+ * qry.flags.TCP must be cleared.
+ * TODO - refactoring is needed. */
+ struct kr_request *req = &task->ctx->req;
+ struct kr_rplan *rplan = &req->rplan;
+ struct kr_query *qry = array_tail(rplan->pending);
+ qry->flags.TCP = false;
+ }
+ qr_task_step(task, NULL, NULL);
+ } else {
+ kr_assert(task->ctx->source.session == session);
+ task->ctx->source.session = NULL;
+ }
+ worker_task_unref(task);
+ }
+ while (!session_tasklist_is_empty(session)) {
+ struct qr_task *task = session_tasklist_del_first(session, false);
+ if (session_flags(session)->outgoing) {
+ if (task->ctx->req.options.FORWARD) {
+ struct kr_request *req = &task->ctx->req;
+ struct kr_rplan *rplan = &req->rplan;
+ struct kr_query *qry = array_tail(rplan->pending);
+ qry->flags.TCP = false;
+ }
+ qr_task_step(task, NULL, NULL);
+ } else {
+ kr_assert(task->ctx->source.session == session);
+ task->ctx->source.session = NULL;
+ }
+ worker_task_unref(task);
+ }
+ session_close(session);
+ return kr_ok();
+}
+
+knot_pkt_t *worker_resolve_mk_pkt_dname(knot_dname_t *qname, uint16_t qtype, uint16_t qclass,
+ const struct kr_qflags *options)
+{
+ knot_pkt_t *pkt = knot_pkt_new(NULL, KNOT_EDNS_MAX_UDP_PAYLOAD, NULL);
+ if (!pkt)
+ return NULL;
+ knot_pkt_put_question(pkt, qname, qclass, qtype);
+ knot_wire_set_rd(pkt->wire);
+ knot_wire_set_ad(pkt->wire);
+
+ /* Add OPT RR, including wire format so modules can see both representations.
+ * knot_pkt_put() copies the outside; we need to duplicate the inside manually. */
+ knot_rrset_t *opt = knot_rrset_copy(the_worker->engine->resolver.downstream_opt_rr, NULL);
+ if (!opt) {
+ knot_pkt_free(pkt);
+ return NULL;
+ }
+ if (options->DNSSEC_WANT) {
+ knot_edns_set_do(opt);
+ }
+ knot_pkt_begin(pkt, KNOT_ADDITIONAL);
+ int ret = knot_pkt_put(pkt, KNOT_COMPR_HINT_NONE, opt, KNOT_PF_FREE);
+ if (ret == KNOT_EOK) {
+ free(opt); /* inside is owned by pkt now */
+ } else {
+ knot_rrset_free(opt, NULL);
+ knot_pkt_free(pkt);
+ return NULL;
+ }
+
+ if (options->DNSSEC_CD) {
+ knot_wire_set_cd(pkt->wire);
+ }
+
+ return pkt;
+}
+
+knot_pkt_t *worker_resolve_mk_pkt(const char *qname_str, uint16_t qtype, uint16_t qclass,
+ const struct kr_qflags *options)
+{
+ uint8_t qname[KNOT_DNAME_MAXLEN];
+ if (!knot_dname_from_str(qname, qname_str, sizeof(qname)))
+ return NULL;
+ return worker_resolve_mk_pkt_dname(qname, qtype, qclass, options);
+}
+
+struct qr_task *worker_resolve_start(knot_pkt_t *query, struct kr_qflags options)
+{
+ struct worker_ctx *worker = the_worker;
+ if (kr_fails_assert(worker && query))
+ return NULL;
+
+
+ struct request_ctx *ctx = request_create(worker, NULL, NULL, NULL, NULL,
+ worker->next_request_uid);
+ if (!ctx)
+ return NULL;
+
+ /* Create task */
+ struct qr_task *task = qr_task_create(ctx);
+ if (!task) {
+ request_free(ctx);
+ return NULL;
+ }
+
+ /* Start task */
+ int ret = request_start(ctx, query);
+ if (ret != 0) {
+ /* task is attached to request context,
+ * so dereference (and deallocate) it first */
+ ctx->task = NULL;
+ qr_task_unref(task);
+ request_free(ctx);
+ return NULL;
+ }
+
+ worker->next_request_uid += 1;
+ if (worker->next_request_uid == 0)
+ worker->next_request_uid = UINT16_MAX + 1;
+
+ /* Set options late, as qr_task_start() -> kr_resolve_begin() rewrite it. */
+ kr_qflags_set(&task->ctx->req.options, options);
+ return task;
+}
+
+int worker_resolve_exec(struct qr_task *task, knot_pkt_t *query)
+{
+ if (!task)
+ return kr_error(EINVAL);
+ return qr_task_step(task, NULL, query);
+}
+
+int worker_task_numrefs(const struct qr_task *task)
+{
+ return task->refs;
+}
+
+struct kr_request *worker_task_request(struct qr_task *task)
+{
+ if (!task || !task->ctx)
+ return NULL;
+
+ return &task->ctx->req;
+}
+
+int worker_task_finalize(struct qr_task *task, int state)
+{
+ return qr_task_finalize(task, state);
+}
+
+ int worker_task_step(struct qr_task *task, const struct sockaddr *packet_source,
+ knot_pkt_t *packet)
+ {
+ return qr_task_step(task, packet_source, packet);
+ }
+
+void worker_task_complete(struct qr_task *task)
+{
+ qr_task_complete(task);
+}
+
+void worker_task_ref(struct qr_task *task)
+{
+ qr_task_ref(task);
+}
+
+void worker_task_unref(struct qr_task *task)
+{
+ qr_task_unref(task);
+}
+
+void worker_task_timeout_inc(struct qr_task *task)
+{
+ task->timeouts += 1;
+}
+
+knot_pkt_t *worker_task_get_pktbuf(const struct qr_task *task)
+{
+ return task->pktbuf;
+}
+
+struct request_ctx *worker_task_get_request(struct qr_task *task)
+{
+ return task->ctx;
+}
+
+struct kr_transport *worker_task_get_transport(struct qr_task *task)
+{
+ return task->transport;
+}
+
+struct session *worker_request_get_source_session(const struct kr_request *req)
+{
+ static_assert(offsetof(struct request_ctx, req) == 0,
+ "Bad struct request_ctx definition.");
+ return ((struct request_ctx *)req)->source.session;
+}
+
+uint16_t worker_task_pkt_get_msgid(struct qr_task *task)
+{
+ knot_pkt_t *pktbuf = worker_task_get_pktbuf(task);
+ uint16_t msg_id = knot_wire_get_id(pktbuf->wire);
+ return msg_id;
+}
+
+void worker_task_pkt_set_msgid(struct qr_task *task, uint16_t msgid)
+{
+ knot_pkt_t *pktbuf = worker_task_get_pktbuf(task);
+ knot_wire_set_id(pktbuf->wire, msgid);
+ struct kr_query *q = task_get_last_pending_query(task);
+ q->id = msgid;
+}
+
+uint64_t worker_task_creation_time(struct qr_task *task)
+{
+ return task->creation_time;
+}
+
+void worker_task_subreq_finalize(struct qr_task *task)
+{
+ subreq_finalize(task, NULL, NULL);
+}
+
+bool worker_task_finished(struct qr_task *task)
+{
+ return task->finished;
+}
+
+/** Reserve worker buffers. We assume worker's been zeroed. */
+static int worker_reserve(struct worker_ctx *worker)
+{
+ worker->tcp_connected = trie_create(NULL);
+ worker->tcp_waiting = trie_create(NULL);
+ worker->subreq_out = trie_create(NULL);
+
+ mm_ctx_mempool(&worker->pkt_pool, 4 * sizeof(knot_pkt_t));
+
+ return kr_ok();
+}
+
+void worker_deinit(void)
+{
+ struct worker_ctx *worker = the_worker;
+ if (kr_fails_assert(worker))
+ return;
+ trie_free(worker->tcp_connected);
+ trie_free(worker->tcp_waiting);
+ trie_free(worker->subreq_out);
+ worker->subreq_out = NULL;
+
+ for (int i = 0; i < worker->doh_qry_headers.len; i++)
+ free((void *)worker->doh_qry_headers.at[i]);
+ array_clear(worker->doh_qry_headers);
+
+ mp_delete(worker->pkt_pool.ctx);
+ worker->pkt_pool.ctx = NULL;
+
+ the_worker = NULL;
+}
+
+int worker_init(struct engine *engine, int worker_count)
+{
+ if (kr_fails_assert(engine && engine->L && the_worker == NULL))
+ return kr_error(EINVAL);
+ kr_bindings_register(engine->L);
+
+ /* Create main worker. */
+ struct worker_ctx *worker = &the_worker_value;
+ memset(worker, 0, sizeof(*worker));
+ worker->engine = engine;
+
+ uv_loop_t *loop = uv_default_loop();
+ worker->loop = loop;
+
+ worker->count = worker_count;
+
+ /* Register table for worker per-request variables */
+ lua_newtable(engine->L);
+ lua_setfield(engine->L, -2, "vars");
+ lua_getfield(engine->L, -1, "vars");
+ worker->vars_table_ref = luaL_ref(engine->L, LUA_REGISTRYINDEX);
+ lua_pop(engine->L, 1);
+
+ worker->tcp_pipeline_max = MAX_PIPELINED;
+ worker->out_addr4.sin_family = AF_UNSPEC;
+ worker->out_addr6.sin6_family = AF_UNSPEC;
+
+ array_init(worker->doh_qry_headers);
+
+ int ret = worker_reserve(worker);
+ if (ret) return ret;
+ worker->next_request_uid = UINT16_MAX + 1;
+
+ /* Set some worker.* fields in Lua */
+ lua_getglobal(engine->L, "worker");
+ pid_t pid = getpid();
+
+ auto_free char *pid_str = NULL;
+ const char *inst_name = getenv("SYSTEMD_INSTANCE");
+ if (inst_name) {
+ lua_pushstring(engine->L, inst_name);
+ } else {
+ ret = asprintf(&pid_str, "%ld", (long)pid);
+ kr_assert(ret > 0);
+ lua_pushstring(engine->L, pid_str);
+ }
+ lua_setfield(engine->L, -2, "id");
+
+ lua_pushnumber(engine->L, pid);
+ lua_setfield(engine->L, -2, "pid");
+ lua_pushnumber(engine->L, worker_count);
+ lua_setfield(engine->L, -2, "count");
+
+ char cwd[PATH_MAX];
+ get_workdir(cwd, sizeof(cwd));
+ lua_pushstring(engine->L, cwd);
+ lua_setfield(engine->L, -2, "cwd");
+
+ the_worker = worker;
+ loop->data = the_worker;
+ /* ^^^^ Now this shouldn't be used anymore, but it's hard to be 100% sure. */
+ return kr_ok();
+}
+
+#undef VERBOSE_MSG
diff --git a/daemon/worker.h b/daemon/worker.h
new file mode 100644
index 0000000..fd9b1f3
--- /dev/null
+++ b/daemon/worker.h
@@ -0,0 +1,195 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#include "daemon/engine.h"
+#include "lib/generic/array.h"
+#include "lib/generic/trie.h"
+
+
+/** Query resolution task (opaque). */
+struct qr_task;
+/** Worker state (opaque). */
+struct worker_ctx;
+/** Transport session (opaque). */
+struct session;
+/** Zone import context (opaque). */
+struct zone_import_ctx;
+/** Data about the communication (defined in io.h). */
+struct io_comm_data;
+
+/** Pointer to the singleton worker. NULL if not initialized. */
+KR_EXPORT extern struct worker_ctx *the_worker;
+
+/** Create and initialize the worker.
+ * \return error code (ENOMEM) */
+int worker_init(struct engine *engine, int worker_count);
+
+/** Destroy the worker (free memory). */
+void worker_deinit(void);
+
+/**
+ * Process an incoming packet (query from a client or answer from upstream).
+ *
+ * @param session session the packet came from, or NULL (not from network)
+ * @param comm IO communication data (see `struct io_comm_data` docs)
+ * @param eth_* MAC addresses or NULL (they're useful for XDP)
+ * @param pkt the packet, or NULL (an error from the transport layer)
+ * @return 0 or an error code
+ */
+int worker_submit(struct session *session, struct io_comm_data *comm,
+ const uint8_t *eth_from, const uint8_t *eth_to, knot_pkt_t *pkt);
+
+/**
+ * End current DNS/TCP session, this disassociates pending tasks from this session
+ * which may be freely closed afterwards.
+ */
+int worker_end_tcp(struct session *session);
+
+KR_EXPORT knot_pkt_t *worker_resolve_mk_pkt_dname(knot_dname_t *qname, uint16_t qtype, uint16_t qclass,
+ const struct kr_qflags *options);
+
+/**
+ * Create a packet suitable for worker_resolve_start(). All in malloc() memory.
+ */
+KR_EXPORT knot_pkt_t *
+worker_resolve_mk_pkt(const char *qname_str, uint16_t qtype, uint16_t qclass,
+ const struct kr_qflags *options);
+
+/**
+ * Start query resolution with given query.
+ *
+ * @return task or NULL
+ */
+KR_EXPORT struct qr_task *
+worker_resolve_start(knot_pkt_t *query, struct kr_qflags options);
+
+/**
+ * Execute a request with given query.
+ * It expects task to be created with \fn worker_resolve_start.
+ *
+ * @return 0 or an error code
+ */
+KR_EXPORT int worker_resolve_exec(struct qr_task *task, knot_pkt_t *query);
+
+/** @return struct kr_request associated with opaque task */
+struct kr_request *worker_task_request(struct qr_task *task);
+
+int worker_task_step(struct qr_task *task, const struct sockaddr *packet_source,
+ knot_pkt_t *packet);
+
+int worker_task_numrefs(const struct qr_task *task);
+
+/** Finalize given task */
+int worker_task_finalize(struct qr_task *task, int state);
+
+void worker_task_complete(struct qr_task *task);
+
+void worker_task_ref(struct qr_task *task);
+
+void worker_task_unref(struct qr_task *task);
+
+void worker_task_timeout_inc(struct qr_task *task);
+
+int worker_add_tcp_connected(struct worker_ctx *worker,
+ const struct sockaddr *addr,
+ struct session *session);
+int worker_del_tcp_connected(struct worker_ctx *worker,
+ const struct sockaddr *addr);
+int worker_del_tcp_waiting(struct worker_ctx *worker,
+ const struct sockaddr* addr);
+struct session* worker_find_tcp_waiting(struct worker_ctx *worker,
+ const struct sockaddr* addr);
+struct session* worker_find_tcp_connected(struct worker_ctx *worker,
+ const struct sockaddr* addr);
+knot_pkt_t *worker_task_get_pktbuf(const struct qr_task *task);
+
+struct request_ctx *worker_task_get_request(struct qr_task *task);
+
+struct kr_transport *worker_task_get_transport(struct qr_task *task);
+
+/** Note: source session is NULL in case the request hasn't come over network. */
+KR_EXPORT struct session *worker_request_get_source_session(const struct kr_request *req);
+
+uint16_t worker_task_pkt_get_msgid(struct qr_task *task);
+void worker_task_pkt_set_msgid(struct qr_task *task, uint16_t msgid);
+uint64_t worker_task_creation_time(struct qr_task *task);
+void worker_task_subreq_finalize(struct qr_task *task);
+bool worker_task_finished(struct qr_task *task);
+
+/** To be called after sending a DNS message. It mainly deals with cleanups. */
+int qr_task_on_send(struct qr_task *task, const uv_handle_t *handle, int status);
+
+/** Various worker statistics. Sync with wrk_stats() */
+struct worker_stats {
+ size_t queries; /**< Total number of requests (from clients and internal ones). */
+ size_t concurrent; /**< The number of requests currently in processing. */
+ size_t rconcurrent; /*< TODO: remove? I see no meaningful difference from .concurrent. */
+ size_t dropped; /**< The number of requests dropped due to being badly formed. See #471. */
+
+ size_t timeout; /**< Number of outbound queries that timed out. */
+ size_t udp; /**< Number of outbound queries over UDP. */
+ size_t tcp; /**< Number of outbound queries over TCP (excluding TLS). */
+ size_t tls; /**< Number of outbound queries over TLS. */
+ size_t ipv4; /**< Number of outbound queries over IPv4.*/
+ size_t ipv6; /**< Number of outbound queries over IPv6. */
+
+ size_t err_udp; /**< Total number of write errors for UDP transport. */
+ size_t err_tcp; /**< Total number of write errors for TCP transport. */
+ size_t err_tls; /**< Total number of write errors for TLS transport. */
+ size_t err_http; /**< Total number of write errors for HTTP(S) transport. */
+};
+
+/** @cond internal */
+
+/** Number of request within timeout window. */
+#define MAX_PENDING 4
+
+/** Maximum response time from TCP upstream, milliseconds */
+#define MAX_TCP_INACTIVITY (KR_RESOLVE_TIME_LIMIT + KR_CONN_RTT_MAX)
+
+#ifndef RECVMMSG_BATCH /* see check_bufsize() */
+#define RECVMMSG_BATCH 1
+#endif
+
+/** List of query resolution tasks. */
+typedef array_t(struct qr_task *) qr_tasklist_t;
+
+/** List of HTTP header names. */
+typedef array_t(const char *) doh_headerlist_t;
+
+/** \details Worker state is meant to persist during the whole life of daemon. */
+struct worker_ctx {
+ struct engine *engine;
+ uv_loop_t *loop;
+ int count; /** unreliable, does not count systemd instance, do not use */
+ int vars_table_ref;
+ unsigned tcp_pipeline_max;
+
+ /** Addresses to bind for outgoing connections or AF_UNSPEC. */
+ struct sockaddr_in out_addr4;
+ struct sockaddr_in6 out_addr6;
+
+ uint8_t wire_buf[RECVMMSG_BATCH * KNOT_WIRE_MAX_PKTSIZE];
+
+ struct worker_stats stats;
+
+ bool too_many_open;
+ size_t rconcurrent_highwatermark;
+ /** List of active outbound TCP sessions */
+ trie_t *tcp_connected;
+ /** List of outbound TCP sessions waiting to be accepted */
+ trie_t *tcp_waiting;
+ /** Subrequest leaders (struct qr_task*), indexed by qname+qtype+qclass. */
+ trie_t *subreq_out;
+ knot_mm_t pkt_pool;
+ unsigned int next_request_uid;
+
+ /* HTTP Headers for DoH. */
+ doh_headerlist_t doh_qry_headers;
+};
+
+/** @endcond */
+
diff --git a/daemon/zimport.c b/daemon/zimport.c
new file mode 100644
index 0000000..af21a15
--- /dev/null
+++ b/daemon/zimport.c
@@ -0,0 +1,741 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+/* Module is intended to import resource records from file into resolver's cache.
+ * File supposed to be a standard DNS zone file
+ * which contains text representations of resource records.
+ * For now only root zone import is supported.
+ *
+ * Import process consists of two stages.
+ * 1) Zone file parsing and (optionally) ZONEMD verification.
+ * 2) DNSSEC validation and storage in cache.
+ *
+ * These stages are implemented as two separate functions
+ * (zi_zone_import and zi_zone_process) which run sequentially with a
+ * pause between them. This is done because resolver is a single-threaded
+ * application, so it can't process user's requests during the whole import
+ * process. Separation into two stages allows to reduce the
+ * continuous time interval when resolver can't serve user requests.
+ * Since root zone isn't large, it is imported as single chunk.
+ */
+
+#include "daemon/zimport.h"
+
+#include <inttypes.h> /* PRIu64 */
+#include <limits.h>
+#include <math.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <uv.h>
+
+#include <libknot/rrset.h>
+#include <libzscanner/scanner.h>
+
+#include <libknot/version.h>
+#define ENABLE_ZONEMD (KNOT_VERSION_HEX >= 0x030100)
+#if ENABLE_ZONEMD
+ #include <libdnssec/digest.h>
+
+ #if KNOT_VERSION_HEX < 0x030200
+ #define KNOT_ZONEMD_ALGORITHM_SHA384 KNOT_ZONEMD_ALORITHM_SHA384
+ #define KNOT_ZONEMD_ALGORITHM_SHA512 KNOT_ZONEMD_ALORITHM_SHA512
+ #endif
+#endif
+
+#include "daemon/worker.h"
+#include "lib/dnssec/ta.h"
+#include "lib/dnssec.h"
+#include "lib/generic/trie.h"
+#include "lib/utils.h"
+
+/* Pause between parse and import stages, milliseconds. */
+#define ZONE_IMPORT_PAUSE 100
+
+// NAN normally comes from <math.h> but it's not guaranteed.
+#ifndef NAN
+ #define NAN nan("")
+#endif
+
+struct zone_import_ctx {
+ knot_mm_t *pool; /// memory pool for all allocations (including struct itself)
+ knot_dname_t *origin;
+ uv_timer_t timer;
+
+ // from zi_config_t
+ zi_callback cb;
+ void *cb_param;
+
+ trie_t *rrsets; /// map: key_get() -> knot_rrset_t*, in ZONEMD order
+ uint32_t timestamp_rr; /// stamp of when RR data arrived (seconds since epoch)
+
+ struct kr_svldr_ctx *svldr; /// DNSSEC validator; NULL iff we don't validate
+ const knot_dname_t *last_cut; /// internal to zi_rrset_import()
+
+#if ENABLE_ZONEMD
+ uint8_t *digest_buf; /// temporary buffer for digest computation (on pool)
+ #define DIGEST_BUF_SIZE (64*1024 - 1)
+ #define DIGEST_ALG_COUNT 2
+ struct {
+ bool active; /// whether we want it computed
+ dnssec_digest_ctx_t *ctx;
+ const uint8_t *expected; /// expected digest (inside zonemd on pool)
+ } digests[DIGEST_ALG_COUNT]; /// we use indices 0 and 1 for SHA 384 and 512
+#endif
+};
+
+typedef struct zone_import_ctx zone_import_ctx_t;
+
+
+#define KEY_LEN (KNOT_DNAME_MAXLEN + 1 + 2 + 2)
+/** Construct key for name, type and signed type (if type == RRSIG).
+ *
+ * Return negative error code in asserted cases.
+ */
+static int key_get(char buf[KEY_LEN], const knot_dname_t *name,
+ uint16_t type, uint16_t type_maysig, char **key_p)
+{
+ char *lf = (char *)knot_dname_lf(name, (uint8_t *)buf);
+ if (kr_fails_assert(lf && key_p))
+ return kr_error(EINVAL);
+ int len = lf[0];
+ lf++; // point to start of data
+ *key_p = lf;
+ // Check that LF is right-aligned to KNOT_DNAME_MAXLEN in buf.
+ if (kr_fails_assert(lf + len == buf + KNOT_DNAME_MAXLEN))
+ return kr_error(EINVAL);
+ buf[KNOT_DNAME_MAXLEN] = 0; // this ensures correct ZONEMD order
+ memcpy(buf + KNOT_DNAME_MAXLEN + 1, &type, sizeof(type));
+ len += 1 + sizeof(type);
+ if (type == KNOT_RRTYPE_RRSIG) {
+ memcpy(buf + KNOT_DNAME_MAXLEN + 1 + sizeof(type),
+ &type_maysig, sizeof(type_maysig));
+ len += sizeof(type_maysig);
+ }
+ return len;
+}
+
+/** Simple helper to retreive from zone_import_ctx_t::rrsets */
+static knot_rrset_t * rrset_get(trie_t *rrsets, const knot_dname_t *name,
+ uint16_t type, uint16_t type_maysig)
+{
+ char key_buf[KEY_LEN], *key;
+ const int len = key_get(key_buf, name, type, type_maysig, &key);
+ if (len < 0)
+ return NULL;
+ const trie_val_t *rrsig_p = trie_get_try(rrsets, key, len);
+ if (!rrsig_p)
+ return NULL;
+ kr_assert(*rrsig_p);
+ return *rrsig_p;
+}
+
+#if ENABLE_ZONEMD
+static int digest_rrset(trie_val_t *rr_p, void *z_import_v)
+{
+ zone_import_ctx_t *z_import = z_import_v;
+ const knot_rrset_t *rr = *rr_p;
+
+ // ignore apex ZONEMD or its RRSIG, and also out of bailiwick records
+ const int origin_bailiwick = knot_dname_in_bailiwick(rr->owner, z_import->origin);
+ const bool is_apex = origin_bailiwick == 0;
+ if (is_apex && kr_rrset_type_maysig(rr) == KNOT_RRTYPE_ZONEMD)
+ return KNOT_EOK;
+ if (unlikely(origin_bailiwick < 0))
+ return KNOT_EOK;
+
+ const int len = knot_rrset_to_wire_extra(rr, z_import->digest_buf, DIGEST_BUF_SIZE,
+ 0, NULL, KNOT_PF_ORIGTTL);
+ if (len < 0)
+ return kr_error(len);
+
+ // digest serialized RRSet
+ for (int i = 0; i < DIGEST_ALG_COUNT; ++i) {
+ if (!z_import->digests[i].active)
+ continue;
+ dnssec_binary_t bufbin = { len, z_import->digest_buf };
+ int ret = dnssec_digest(z_import->digests[i].ctx, &bufbin);
+ if (ret != KNOT_EOK)
+ return kr_error(ret);
+ }
+ return KNOT_EOK;
+}
+
+/** Verify ZONEMD in the stored zone, and return error code.
+ *
+ * ZONEMD signature is verified iff z_import->svldr != NULL
+ https://www.rfc-editor.org/rfc/rfc8976.html#name-verifying-zone-digest
+ */
+static int zonemd_verify(zone_import_ctx_t *z_import)
+{
+ bool zonemd_is_valid = false;
+ // Find ZONEMD RR + RRSIG
+ knot_rrset_t * const rr_zonemd
+ = rrset_get(z_import->rrsets, z_import->origin, KNOT_RRTYPE_ZONEMD, 0);
+ if (!rr_zonemd) {
+ // no zonemd; let's compute the shorter digest and print info later
+ z_import->digests[KNOT_ZONEMD_ALGORITHM_SHA384 - 1].active = true;
+ goto do_digest;
+ }
+ // Validate ZONEMD RRSIG, if desired
+ if (z_import->svldr) {
+ const knot_rrset_t *rrsig_zonemd
+ = rrset_get(z_import->rrsets, z_import->origin,
+ KNOT_RRTYPE_RRSIG, KNOT_RRTYPE_ZONEMD);
+ int ret = rrsig_zonemd
+ ? kr_svldr_rrset(rr_zonemd, &rrsig_zonemd->rrs, z_import->svldr)
+ : kr_error(ENOENT);
+ zonemd_is_valid = (ret == kr_ok());
+
+ if (!rrsig_zonemd) {
+ kr_log_error(PREFILL, "ZONEMD signature missing\n");
+ } else if (!zonemd_is_valid) {
+ kr_log_error(PREFILL, "ZONEMD signature failed to validate\n");
+ }
+ }
+
+ // Get SOA serial
+ const knot_rrset_t *soa = rrset_get(z_import->rrsets, z_import->origin,
+ KNOT_RRTYPE_SOA, 0);
+ if (!soa) {
+ kr_log_error(PREFILL, "SOA record not found\n");
+ return kr_error(ENOENT);
+ }
+ if (soa->rrs.count != 1) {
+ kr_log_error(PREFILL, "the SOA RR set is weird\n");
+ return kr_error(EINVAL);
+ } // length is checked by parser already
+ const uint32_t soa_serial = knot_soa_serial(soa->rrs.rdata);
+
+ // Figure out SOA+ZONEMD RR contents.
+ bool some_active = false;
+ knot_rdata_t *rd = rr_zonemd->rrs.rdata;
+ for (int i = 0; i < rr_zonemd->rrs.count; ++i, rd = knot_rdataset_next(rd)) {
+ if (rd->len < 6 || knot_zonemd_scheme(rd) != KNOT_ZONEMD_SCHEME_SIMPLE
+ || knot_zonemd_soa_serial(rd) != soa_serial)
+ continue;
+ const int algo = knot_zonemd_algorithm(rd);
+ if (algo != KNOT_ZONEMD_ALGORITHM_SHA384 && algo != KNOT_ZONEMD_ALGORITHM_SHA512)
+ continue;
+ if (rd->len != 6 + knot_zonemd_digest_size(rd)) {
+ kr_log_error(PREFILL, "ZONEMD record has incorrect digest length\n");
+ return kr_error(EINVAL);
+ }
+ if (z_import->digests[algo - 1].active) {
+ kr_log_error(PREFILL, "multiple clashing ZONEMD records found\n");
+ return kr_error(EINVAL);
+ }
+ some_active = true;
+ z_import->digests[algo - 1].active = true;
+ z_import->digests[algo - 1].expected = knot_zonemd_digest(rd);
+ }
+ if (!some_active) {
+ kr_log_error(PREFILL, "ZONEMD record(s) found but none were usable\n");
+ return kr_error(ENOENT);
+ }
+do_digest:
+ // Init memory, etc.
+ if (!z_import->digest_buf) {
+ z_import->digest_buf = mm_alloc(z_import->pool, DIGEST_BUF_SIZE);
+ if (!z_import->digest_buf)
+ return kr_error(ENOMEM);
+ }
+ for (int i = 0; i < DIGEST_ALG_COUNT; ++i) {
+ const int algo = i + 1;
+ if (!z_import->digests[i].active)
+ continue;
+ int ret = dnssec_digest_init(algo, &z_import->digests[i].ctx);
+ if (ret != KNOT_EOK) {
+ // free previous successful _ctx, if applicable
+ dnssec_binary_t digest = { 0 };
+ while (--i >= 0) {
+ if (z_import->digests[i].active)
+ dnssec_digest_finish(z_import->digests[i].ctx,
+ &digest);
+ }
+ return kr_error(ENOMEM);
+ }
+ }
+ // Actually compute the digest(s).
+ int ret = trie_apply(z_import->rrsets, digest_rrset, z_import);
+ dnssec_binary_t digs[DIGEST_ALG_COUNT] = { { 0 } };
+ for (int i = 0; i < DIGEST_ALG_COUNT; ++i) {
+ if (!z_import->digests[i].active)
+ continue;
+ int ret2 = dnssec_digest_finish(z_import->digests[i].ctx, &digs[i]);
+ if (ret == DNSSEC_EOK)
+ ret = ret2;
+ // we need to keep going to free all digests[*].ctx
+ }
+ if (ret != DNSSEC_EOK) {
+ for (int i = 0; i < DIGEST_ALG_COUNT; ++i)
+ free(digs[i].data);
+ kr_log_error(PREFILL, "error when computing digest: %s\n",
+ kr_strerror(ret));
+ return kr_error(ret);
+ }
+ // Now only check that one of the hashes match.
+ bool has_match = false;
+ for (int i = 0; i < DIGEST_ALG_COUNT; ++i) {
+ if (!z_import->digests[i].active)
+ continue;
+ // hexdump the hash for logging
+ char hash_str[digs[i].size * 2 + 1];
+ for (ssize_t j = 0; j < digs[i].size; ++j)
+ sprintf(hash_str + 2*j, "%02x", digs[i].data[j]);
+
+ if (!z_import->digests[i].expected) {
+ kr_log_error(PREFILL, "no ZONEMD found; computed hash: %s\n",
+ hash_str);
+ } else if (memcmp(z_import->digests[i].expected, digs[i].data,
+ digs[i].size) != 0) {
+ kr_log_error(PREFILL, "ZONEMD hash mismatch; computed hash: %s\n",
+ hash_str);
+ } else {
+ kr_log_debug(PREFILL, "ZONEMD hash matches\n");
+ has_match = true;
+ continue;
+ }
+ }
+
+ for (int i = 0; i < DIGEST_ALG_COUNT; ++i)
+ free(digs[i].data);
+ bool ok = has_match && (zonemd_is_valid || !z_import->svldr);
+ return ok ? kr_ok() : kr_error(ENOENT);
+}
+#endif
+
+
+/**
+ * @internal Import given rrset to cache.
+ *
+ * @return error code; we could've chosen to keep importing even if some RRset fails,
+ * but it would be harder to ensure that we don't generate too many logs
+ * and that we pass an error to the finishing callback.
+ */
+static int zi_rrset_import(trie_val_t *rr_p, void *z_import_v)
+{
+ zone_import_ctx_t *z_import = z_import_v;
+ knot_rrset_t *rr = *rr_p;
+
+ if (rr->type == KNOT_RRTYPE_RRSIG)
+ return 0; // we do RRSIGs at once with their types
+
+ const int origin_bailiwick = knot_dname_in_bailiwick(rr->owner, z_import->origin);
+ if (unlikely(origin_bailiwick < 0)) {
+ KR_DNAME_GET_STR(owner_str, rr->owner);
+ kr_log_warning(PREFILL, "ignoring out of bailiwick record(s) on %s\n",
+ owner_str);
+ return 0; // well, let's continue without error
+ }
+
+ // Determine if this RRset is authoritative.
+ // We utilize that iteration happens in canonical order.
+ bool is_auth;
+ const int kdib = knot_dname_in_bailiwick(rr->owner, z_import->last_cut);
+ if (kdib == 0 && (rr->type == KNOT_RRTYPE_DS || rr->type == KNOT_RRTYPE_NSEC
+ || rr->type == KNOT_RRTYPE_NSEC3)) {
+ // parent side of the zone cut (well, presumably in case of NSEC*)
+ is_auth = true;
+ } else if (kdib >= 0) {
+ // inside non-auth subtree
+ is_auth = false;
+ } else if (rr->type == KNOT_RRTYPE_NS && origin_bailiwick > 0) {
+ // entering non-auth subtree
+ z_import->last_cut = rr->owner;
+ is_auth = false;
+ } else {
+ // outside non-auth subtree
+ is_auth = true;
+ z_import->last_cut = NULL; // so that the next _in_bailiwick() is faster
+ }
+ // Rare case: `A` exactly on zone cut would be misdetected and fail validation;
+ // it's the only type ordered before NS.
+ if (unlikely(is_auth && rr->type < KNOT_RRTYPE_NS)) {
+ if (rrset_get(z_import->rrsets, rr->owner, KNOT_RRTYPE_NS, 0))
+ is_auth = false;
+ }
+
+ // Get and validate the corresponding RRSIGs, if authoritative.
+ const knot_rrset_t *rrsig = NULL;
+ if (is_auth) {
+ rrsig = rrset_get(z_import->rrsets, rr->owner, KNOT_RRTYPE_RRSIG, rr->type);
+ if (unlikely(!rrsig && z_import->svldr)) {
+ KR_DNAME_GET_STR(owner_str, rr->owner);
+ KR_RRTYPE_GET_STR(type_str, rr->type);
+ kr_log_error(PREFILL, "no records found for %s RRSIG %s\n",
+ owner_str, type_str);
+ return kr_error(ENOENT);
+ }
+ }
+ if (is_auth && z_import->svldr) {
+ int ret = kr_svldr_rrset(rr, &rrsig->rrs, z_import->svldr);
+ if (unlikely(ret)) {
+ KR_DNAME_GET_STR(owner_str, rr->owner);
+ KR_RRTYPE_GET_STR(type_str, rr->type);
+ kr_log_error(PREFILL, "validation failed for %s %s: %s\n",
+ owner_str, type_str, kr_strerror(ret));
+ return kr_error(ret);
+ }
+ }
+
+ uint8_t rank;
+ if (!is_auth) {
+ rank = KR_RANK_OMIT;
+ } else if (z_import->svldr) {
+ rank = KR_RANK_AUTH|KR_RANK_SECURE;
+ } else {
+ rank = KR_RANK_AUTH|KR_RANK_INSECURE;
+ }
+
+ int ret = kr_cache_insert_rr(&the_worker->engine->resolver.cache, rr, rrsig,
+ rank, z_import->timestamp_rr,
+ // Optim.: only stash NSEC* params at the apex.
+ origin_bailiwick == 0);
+ if (ret) {
+ kr_log_error(PREFILL, "caching an RRset failed: %s\n",
+ kr_strerror(ret));
+ return kr_error(ret);
+ }
+ return 0; // success
+}
+
+static void ctx_delete(zone_import_ctx_t *z_import)
+{
+ if (kr_fails_assert(z_import)) return;
+ kr_svldr_free_ctx(z_import->svldr);
+
+ /* Free `z_import`'s pool, including `z_import` itself, because it is
+ * allocated inside said pool. */
+ mm_ctx_delete(z_import->pool);
+}
+static void timer_close(uv_handle_t *handle)
+{
+ ctx_delete(handle->data);
+}
+
+/** @internal Iterate over parsed rrsets and try to import each of them. */
+static void zi_zone_process(uv_timer_t *timer)
+{
+ zone_import_ctx_t *z_import = timer->data;
+
+ kr_timer_t stopwatch;
+ kr_timer_start(&stopwatch);
+
+ int ret = trie_apply(z_import->rrsets, zi_rrset_import, z_import);
+ (void)kr_cache_commit(&the_worker->engine->resolver.cache); // RW transaction open
+ if (ret == 0) {
+ kr_log_info(PREFILL, "performance: validating and caching took %.3lf s\n",
+ kr_timer_elapsed(&stopwatch));
+ }
+
+ if (z_import->cb)
+ z_import->cb(kr_error(ret), z_import->cb_param);
+ uv_close((uv_handle_t *)timer, timer_close);
+}
+
+/** @internal Store rrset that has been imported to zone import context memory pool.
+ * @return -1 if failed; 0 if success. */
+static int zi_record_store(zs_scanner_t *s)
+{
+ if (s->r_data_length > UINT16_MAX) {
+ /* Due to knot_rrset_add_rdata(..., const uint16_t size, ...); */
+ kr_log_error(PREFILL, "line %"PRIu64": rdata is too long\n",
+ s->line_counter);
+ return -1;
+ }
+
+ if (knot_dname_size(s->r_owner) != strlen((const char *)(s->r_owner)) + 1) {
+ kr_log_error(PREFILL, "line %"PRIu64
+ ": owner name contains zero byte, skip\n",
+ s->line_counter);
+ return 0;
+ }
+
+ zone_import_ctx_t *z_import = (zone_import_ctx_t *)s->process.data;
+
+ knot_rrset_t *new_rr = knot_rrset_new(s->r_owner, s->r_type, s->r_class,
+ s->r_ttl, z_import->pool);
+ if (!new_rr) {
+ kr_log_error(PREFILL, "line %"PRIu64": error creating rrset\n",
+ s->line_counter);
+ return -1;
+ }
+ int res = knot_rrset_add_rdata(new_rr, s->r_data, s->r_data_length,
+ z_import->pool);
+ if (res != KNOT_EOK) {
+ kr_log_error(PREFILL, "line %"PRIu64": error adding rdata to rrset\n",
+ s->line_counter);
+ return -1;
+ }
+ /* zscanner itself does not canonize - neither owner nor insides */
+ res = knot_rrset_rr_to_canonical(new_rr);
+ if (res != KNOT_EOK) {
+ kr_log_error(PREFILL, "line %"PRIu64": error when canonizing: %s\n",
+ s->line_counter, knot_strerror(res));
+ return -1;
+ }
+
+ /* Records in zone file may not be grouped by name and RR type.
+ * Use map to create search key and
+ * avoid ineffective searches across all the imported records. */
+ char key_buf[KEY_LEN], *key;
+ const int len = key_get(key_buf, new_rr->owner, new_rr->type,
+ kr_rrset_type_maysig(new_rr), &key);
+ if (len < 0) {
+ kr_log_error(PREFILL, "line %"PRIu64": error constructing rrkey\n",
+ s->line_counter);
+ return -1;
+ }
+ trie_val_t *rr_p = trie_get_ins(z_import->rrsets, key, len);
+ if (!rr_p)
+ return -1; // ENOMEM
+ if (*rr_p) {
+ knot_rrset_t *rr = *rr_p;
+ res = knot_rdataset_merge(&rr->rrs, &new_rr->rrs, z_import->pool);
+ } else {
+ *rr_p = new_rr;
+ }
+ if (res != 0) {
+ kr_log_error(PREFILL, "line %"PRIu64": error saving parsed rrset\n",
+ s->line_counter);
+ return -1;
+ }
+
+ return 0;
+}
+
+static int zi_state_parsing(zs_scanner_t *s)
+{
+ bool empty = true;
+ while (zs_parse_record(s) == 0) {
+ switch (s->state) {
+ case ZS_STATE_DATA:
+ if (zi_record_store(s) != 0) {
+ return -1;
+ }
+ zone_import_ctx_t *z_import = (zone_import_ctx_t *) s->process.data;
+ empty = false;
+ if (s->r_type == KNOT_RRTYPE_SOA) {
+ z_import->origin = knot_dname_copy(s->r_owner,
+ z_import->pool);
+ }
+ break;
+ case ZS_STATE_ERROR:
+ kr_log_error(PREFILL, "line: %"PRIu64
+ ": parse error; code: %i ('%s')\n",
+ s->line_counter, s->error.code,
+ zs_strerror(s->error.code));
+ return -1;
+ case ZS_STATE_INCLUDE:
+ kr_log_error(PREFILL, "line: %"PRIu64
+ ": INCLUDE is not supported\n",
+ s->line_counter);
+ return -1;
+ case ZS_STATE_EOF:
+ case ZS_STATE_STOP:
+ if (empty) {
+ kr_log_error(PREFILL, "empty zone file\n");
+ return -1;
+ }
+ if (!((zone_import_ctx_t *) s->process.data)->origin) {
+ kr_log_error(PREFILL, "zone file doesn't contain SOA record\n");
+ return -1;
+ }
+ return (s->error.counter == 0) ? 0 : -1;
+ default:
+ kr_log_error(PREFILL, "line: %"PRIu64
+ ": unexpected parse state: %i\n",
+ s->line_counter, s->state);
+ return -1;
+ }
+ }
+
+ return -1;
+}
+
+int zi_zone_import(const zi_config_t config)
+{
+ const zi_config_t *c = &config;
+ if (kr_fails_assert(c && c->zone_file))
+ return kr_error(EINVAL);
+
+ knot_mm_t *pool = mm_ctx_mempool2(1024 * 1024);
+ zone_import_ctx_t *z_import = mm_calloc(pool, 1, sizeof(*z_import));
+ if (!z_import) return kr_error(ENOMEM);
+ z_import->pool = pool;
+
+ z_import->cb = c->cb;
+ z_import->cb_param = c->cb_param;
+ z_import->rrsets = trie_create(z_import->pool);
+
+ kr_timer_t stopwatch;
+ kr_timer_start(&stopwatch);
+
+ //// Parse the whole zone file into z_import->rrsets.
+ zs_scanner_t s_storage, *s = &s_storage;
+ /* zs_init(), zs_set_input_file(), zs_set_processing() returns -1 in case of error,
+ * so don't print error code as it meaningless. */
+ int ret = zs_init(s, c->origin, KNOT_CLASS_IN, c->ttl);
+ if (ret != 0) {
+ kr_log_error(PREFILL, "error initializing zone scanner instance, error: %i (%s)\n",
+ s->error.code, zs_strerror(s->error.code));
+ goto fail;
+ }
+
+ ret = zs_set_input_file(s, c->zone_file);
+ if (ret != 0) {
+ kr_log_error(PREFILL, "error opening zone file `%s`, error: %i (%s)\n",
+ c->zone_file, s->error.code, zs_strerror(s->error.code));
+ zs_deinit(s);
+ goto fail;
+ }
+
+ /* Don't set processing and error callbacks as we don't use automatic parsing.
+ * Parsing as well error processing will be performed in zi_state_parsing().
+ * Store pointer to zone import context for further use. */
+ ret = zs_set_processing(s, NULL, NULL, (void *)z_import);
+ if (ret != 0) {
+ kr_log_error(PREFILL, "zs_set_processing() failed for zone file `%s`, "
+ "error: %i (%s)\n",
+ c->zone_file, s->error.code, zs_strerror(s->error.code));
+ zs_deinit(s);
+ goto fail;
+ }
+
+ ret = zi_state_parsing(s);
+ zs_deinit(s);
+ const double time_parse = kr_timer_elapsed(&stopwatch);
+ if (ret != 0) {
+ kr_log_error(PREFILL, "error parsing zone file `%s`\n", c->zone_file);
+ goto fail;
+ }
+ kr_log_debug(PREFILL, "import started for zone file `%s`\n", c->zone_file);
+
+ KR_DNAME_GET_STR(zone_name_str, z_import->origin);
+
+ //// Choose timestamp_rr, according to config.
+ struct timespec now;
+ if (clock_gettime(CLOCK_REALTIME, &now)) {
+ ret = kr_error(errno);
+ kr_log_error(PREFILL, "failed to get current time: %s\n", kr_strerror(ret));
+ goto fail;
+ }
+ if (config.time_src == ZI_STAMP_NOW) {
+ z_import->timestamp_rr = now.tv_sec;
+ } else if (config.time_src == ZI_STAMP_MTIM) {
+ struct stat st;
+ if (stat(c->zone_file, &st) != 0) {
+ kr_log_debug(PREFILL, "failed to stat file `%s`: %s\n",
+ c->zone_file, strerror(errno));
+ goto fail;
+ }
+ z_import->timestamp_rr = st.st_mtime;
+ } else {
+ ret = kr_error(EINVAL);
+ goto fail;
+ }
+ //// Some sanity checks
+ const knot_rrset_t *soa = rrset_get(z_import->rrsets, z_import->origin,
+ KNOT_RRTYPE_SOA, 0);
+ if (z_import->timestamp_rr > now.tv_sec) {
+ kr_log_warning(PREFILL, "zone file `%s` comes from future\n", c->zone_file);
+ } else if (!soa) {
+ kr_log_warning(PREFILL, "missing %s SOA\n", zone_name_str);
+ } else if ((int64_t)z_import->timestamp_rr + soa->ttl < now.tv_sec) {
+ kr_log_warning(PREFILL, "%s SOA already expired\n", zone_name_str);
+ }
+
+ //// Initialize validator context with the DNSKEY.
+ if (c->downgrade)
+ goto zonemd;
+ struct kr_context *resolver = &the_worker->engine->resolver;
+ const knot_rrset_t * const ds = c->ds ? c->ds :
+ kr_ta_get(resolver->trust_anchors, z_import->origin);
+ if (!ds) {
+ if (!kr_ta_closest(resolver, z_import->origin, KNOT_RRTYPE_DNSKEY))
+ goto zonemd; // our TAs say we're insecure
+ kr_log_error(PREFILL, "no DS found for `%s`, fail\n", zone_name_str);
+ ret = kr_error(ENOENT);
+ goto fail;
+ }
+ if (!knot_dname_is_equal(ds->owner, z_import->origin)) {
+ kr_log_error(PREFILL, "mismatching DS owner, fail\n");
+ ret = kr_error(EINVAL);
+ goto fail;
+ }
+
+ knot_rrset_t * const dnskey = rrset_get(z_import->rrsets, z_import->origin,
+ KNOT_RRTYPE_DNSKEY, 0);
+ if (!dnskey) {
+ kr_log_error(PREFILL, "no DNSKEY found for `%s`, fail\n", zone_name_str);
+ ret = kr_error(ENOENT);
+ goto fail;
+ }
+ knot_rrset_t * const dnskey_sigs = rrset_get(z_import->rrsets, z_import->origin,
+ KNOT_RRTYPE_RRSIG, KNOT_RRTYPE_DNSKEY);
+ if (!dnskey_sigs) {
+ kr_log_error(PREFILL, "no RRSIGs for DNSKEY found for `%s`, fail\n",
+ zone_name_str);
+ ret = kr_error(ENOENT);
+ goto fail;
+ }
+
+ kr_rrset_validation_ctx_t err_ctx;
+ z_import->svldr = kr_svldr_new_ctx(ds, dnskey, &dnskey_sigs->rrs,
+ z_import->timestamp_rr, &err_ctx);
+ if (!z_import->svldr) {
+ // log RRSIG stats; very similar to log_bogus_rrsig()
+ kr_log_error(PREFILL, "failed to validate DNSKEY for `%s` "
+ "(%u matching RRSIGs, %u expired, %u not yet valid, "
+ "%u invalid signer, %u invalid label count, %u invalid key, "
+ "%u invalid crypto, %u invalid NSEC)\n",
+ zone_name_str,
+ err_ctx.rrs_counters.matching_name_type,
+ err_ctx.rrs_counters.expired, err_ctx.rrs_counters.notyet,
+ err_ctx.rrs_counters.signer_invalid,
+ err_ctx.rrs_counters.labels_invalid,
+ err_ctx.rrs_counters.key_invalid,
+ err_ctx.rrs_counters.crypto_invalid,
+ err_ctx.rrs_counters.nsec_invalid);
+ ret = kr_error(ENOENT);
+ goto fail;
+ }
+
+ //// Do all ZONEMD processing, if desired.
+zonemd: (void)0; // C can't have a variable definition following a label
+ double time_zonemd = NAN;
+ if (c->zonemd) {
+ #if ENABLE_ZONEMD
+ kr_timer_start(&stopwatch);
+ ret = zonemd_verify(z_import);
+ time_zonemd = kr_timer_elapsed(&stopwatch);
+ #else
+ kr_log_error(PREFILL,
+ "ZONEMD check requested but not supported, fail\n");
+ ret = kr_error(ENOSYS);
+ #endif
+ } else {
+ ret = kr_ok();
+ }
+ kr_log_info(PREFILL, "performance: parsing took %.3lf s, hashing took %.3lf s\n",
+ time_parse, time_zonemd);
+ if (ret) goto fail;
+
+ //// Phase two, after a pause. Validate and import all the remaining records.
+ ret = uv_timer_init(the_worker->loop, &z_import->timer);
+ if (ret) goto fail;
+ z_import->timer.data = z_import;
+ ret = uv_timer_start(&z_import->timer, zi_zone_process, ZONE_IMPORT_PAUSE, 0);
+ if (ret) goto fail;
+
+ return kr_ok();
+fail:
+ if (z_import->cb)
+ z_import->cb(kr_error(ret), z_import->cb_param);
+ if (kr_fails_assert(ret))
+ ret = ENOENT;
+ ctx_delete(z_import);
+ return kr_error(ret);
+}
+
diff --git a/daemon/zimport.h b/daemon/zimport.h
new file mode 100644
index 0000000..5bbd992
--- /dev/null
+++ b/daemon/zimport.h
@@ -0,0 +1,48 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#include <stdbool.h>
+#include <libknot/rrset.h>
+#include "lib/defines.h"
+
+/**
+ * Completion callback
+ *
+ * @param state 0 for OK completion, < 0 for errors (unfinished)
+ * @param param pointer to user data
+ */
+typedef void (*zi_callback)(int state, void *param);
+typedef struct {
+ /* Parser, see zs_init() */
+ const char *zone_file;
+ const char *origin;
+ uint32_t ttl;
+
+ /// Source of time: current real time, or file modification time.
+ enum { ZI_STAMP_NOW = 0, ZI_STAMP_MTIM } time_src;
+
+ /* Validator */
+ bool downgrade; /// true -> disable validation
+ bool zonemd; /// true -> verify zonemd
+ const knot_rrset_t *ds; /// NULL -> use trust anchors
+
+ zi_callback cb;
+ void *cb_param;
+} zi_config_t;
+
+/** Import zone from a file.
+ *
+ * Error can be directly returned in the first phase (parsing + ZONEMD);
+ * otherwise it will be kr_ok() and config->cb gets (optionally) called finally.
+ *
+ * Large zone would pause other processing for longer time;
+ * that's generally not advisable.
+ *
+ * Zone origin is detected from SOA, but it's certainly not perfect now.
+ */
+KR_EXPORT
+int zi_zone_import(const zi_config_t config);
+
diff --git a/daemon/zimport.test/tz-rfc-a1-bad.zone b/daemon/zimport.test/tz-rfc-a1-bad.zone
new file mode 100644
index 0000000..593489a
--- /dev/null
+++ b/daemon/zimport.test/tz-rfc-a1-bad.zone
@@ -0,0 +1,14 @@
+$ORIGIN example.
+example. 86400 IN SOA ns1 admin 2018031900 (
+ 1800 900 604800 86400 )
+ 86400 IN NS ns1
+ 86400 IN NS ns2
+ 86400 IN ZONEMD 2018031900 1 1 (
+ BAAAAAAADa7aed71
+ 6bc459f9340e3d7c
+ 1370d4d24b7e2fc3
+ a1ddc0b9a87153b9
+ a9713b3c9ae5cc27
+ 777f98b8e730044c )
+ns1 3600 IN A 203.0.113.63
+ns2 3600 IN AAAA 2001:db8::63
diff --git a/daemon/zimport.test/tz-rfc-a1.zone b/daemon/zimport.test/tz-rfc-a1.zone
new file mode 100644
index 0000000..5c43ec0
--- /dev/null
+++ b/daemon/zimport.test/tz-rfc-a1.zone
@@ -0,0 +1,14 @@
+$ORIGIN example.
+example. 86400 IN SOA ns1 admin 2018031900 (
+ 1800 900 604800 86400 )
+ 86400 IN NS ns1
+ 86400 IN NS ns2
+ 86400 IN ZONEMD 2018031900 1 1 (
+ c68090d90a7aed71
+ 6bc459f9340e3d7c
+ 1370d4d24b7e2fc3
+ a1ddc0b9a87153b9
+ a9713b3c9ae5cc27
+ 777f98b8e730044c )
+ns1 3600 IN A 203.0.113.63
+ns2 3600 IN AAAA 2001:db8::63
diff --git a/daemon/zimport.test/tz-rfc-a2.zone b/daemon/zimport.test/tz-rfc-a2.zone
new file mode 100644
index 0000000..5ae7f36
--- /dev/null
+++ b/daemon/zimport.test/tz-rfc-a2.zone
@@ -0,0 +1,35 @@
+$ORIGIN example.
+example. 86400 IN SOA ns1 admin 2018031900 (
+ 1800 900 604800 86400 )
+ 86400 IN NS ns1
+ 86400 IN NS ns2
+ 86400 IN ZONEMD 2018031900 1 1 (
+ a3b69bad980a3504
+ e1cffcb0fd6397f9
+ 3848071c93151f55
+ 2ae2f6b1711d4bd2
+ d8b39808226d7b9d
+ b71e34b72077f8fe )
+ns1 3600 IN A 203.0.113.63
+NS2 3600 IN AAAA 2001:db8::63
+occluded.sub 7200 IN TXT "I'm occluded but must be digested"
+sub 7200 IN NS ns1
+duplicate 300 IN TXT "I must be digested just once"
+duplicate 300 IN TXT "I must be digested just once"
+foo.test. 555 IN TXT "out-of-zone data must be excluded"
+UPPERCASE 3600 IN TXT "canonicalize uppercase owner names"
+* 777 IN PTR dont-forget-about-wildcards
+mail 3600 IN MX 20 MAIL1
+mail 3600 IN MX 10 Mail2.Example.
+sortme 3600 IN AAAA 2001:db8::5:61
+sortme 3600 IN AAAA 2001:db8::3:62
+sortme 3600 IN AAAA 2001:db8::4:63
+sortme 3600 IN AAAA 2001:db8::1:65
+sortme 3600 IN AAAA 2001:db8::2:64
+non-apex 900 IN ZONEMD 2018031900 1 1 (
+ 616c6c6f77656420
+ 6275742069676e6f
+ 7265642e20616c6c
+ 6f77656420627574
+ 2069676e6f726564
+ 2e20616c6c6f7765 )
diff --git a/daemon/zimport.test/tz-rfc-a3.zone b/daemon/zimport.test/tz-rfc-a3.zone
new file mode 100644
index 0000000..961dba9
--- /dev/null
+++ b/daemon/zimport.test/tz-rfc-a3.zone
@@ -0,0 +1,31 @@
+$ORIGIN example.
+example. 86400 IN SOA ns1 admin 2018031900 (
+ 1800 900 604800 86400 )
+example. 86400 IN NS ns1.example.
+example. 86400 IN NS ns2.example.
+example. 86400 IN ZONEMD 2018031900 1 1 (
+ 62e6cf51b02e54b9
+ b5f967d547ce4313
+ 6792901f9f88e637
+ 493daaf401c92c27
+ 9dd10f0edb1c56f8
+ 080211f8480ee306 )
+example. 86400 IN ZONEMD 2018031900 1 2 (
+ 08cfa1115c7b948c
+ 4163a901270395ea
+ 226a930cd2cbcf2f
+ a9a5e6eb85f37c8a
+ 4e114d884e66f176
+ eab121cb02db7d65
+ 2e0cc4827e7a3204
+ f166b47e5613fd27 )
+example. 86400 IN ZONEMD 2018031900 1 240 (
+ e2d523f654b9422a
+ 96c5a8f44607bbee )
+example. 86400 IN ZONEMD 2018031900 241 1 (
+ e1846540e33a9e41
+ 89792d18d5d131f6
+ 05fc283e )
+ns1.example. 3600 IN A 203.0.113.63
+ns2.example. 86400 IN TXT "This example has multiple digests"
+NS2.EXAMPLE. 3600 IN AAAA 2001:db8::63
diff --git a/daemon/zimport.test/tz-rfc-a4.zone b/daemon/zimport.test/tz-rfc-a4.zone
new file mode 100644
index 0000000..19d89d6
--- /dev/null
+++ b/daemon/zimport.test/tz-rfc-a4.zone
@@ -0,0 +1,37 @@
+$ORIGIN example.
+;; White-space had to be changed from the RFC, as libzscanner only allows spaces in base64 on some places.
+uri.arpa. 3600 IN SOA sns.dns.icann.org. noc.dns.icann.org. 2018100702 10800 3600 1209600 3600
+uri.arpa. 3600 IN RRSIG SOA 8 2 3600 20210217232440 20210120232440 37444 uri.arpa. GzQw+QzwLDJr13REPGVmpEChjD1D2XlX0ie1DnWHpgaEw1E/dhs3lCN3 +BmHd4Kx3tffTRgiyq65HxR6feQ5v7VmAifjyXUYB1DZur1eP5q0Ms2y gCB3byoeMgCNsFS1oKZ2LdzNBRpy3oace8xQn1SpmHGfyrsgg+WbHKCT 1dY=
+uri.arpa. 86400 IN NS a.iana-servers.net.
+uri.arpa. 86400 IN NS b.iana-servers.net.
+uri.arpa. 86400 IN NS c.iana-servers.net.
+uri.arpa. 86400 IN NS ns2.lacnic.net.
+uri.arpa. 86400 IN NS sec3.apnic.net.
+uri.arpa. 86400 IN RRSIG NS 8 2 86400 20210217232440 20210120232440 37444 uri.arpa. M+Iei2lcewWGaMtkPlrhM9FpUAHXFkCHTVpeyrjxjEONeNgKtHZor5e4 V4qJBOzNqo8go/qJpWlFBm+T5Hn3asaBZVstFIYky38/C8UeRLPKq1hT THARYUlFrexr5fMtSUAVOgOQPSBfH3xBq/BgSccTdRb9clD+HE7djpqr LS4=
+uri.arpa. 600 IN MX 10 pechora.icann.org.
+uri.arpa. 600 IN RRSIG MX 8 2 600 20210217232440 20210120232440 37444 uri.arpa. kQAJQivmv6A5hqYBK8h6Z13ESY69gmosXwKI6WE09I8RFetfrxr24ecd nYd0lpnDtgNNSoHkYRSOoB+C4+zuJsoyAAzGo9uoWMWj97/2xeGhf3PT C9meQ9Ohi6hul9By7OR76XYmGhdWX8PBi60RUmZ1guslFBfQ8izwPqzu phs=
+uri.arpa. 3600 IN NSEC ftp.uri.arpa. NS SOA MX RRSIG NSEC DNSKEY ZONEMD
+uri.arpa. 3600 IN RRSIG NSEC 8 2 3600 20210217232440 20210120232440 37444 uri.arpa. dU/rXLM/naWd1+1PiWiYVaNJyCkiuyZJSccr91pJI673T8r3685B4ODM YFafZRboVgwnl3ZrXddY6xOhZL3n9V9nxXZwjLJ2HJUojFoKcXTlpnUy YUYvVQ2kj4GHAo6fcGCEp5QFJ2KbCpeJoS+PhKGRRx28icCiNT4/uXQv O2E=
+uri.arpa. 3600 IN DNSKEY 256 3 8 AwEAAbMxuFuLeVDuOwIMzYOTD/bTREjLflo7wOi6ieIJhqltEzgjNzmW Jf9kGwwDmzxU7kbthMEhBNBZNn84zmcyRSCMzuStWveL7xmqqUlE3swL 8kLOvdZvc75XnmpHrk3ndTyEb6eZM7slh2C63Oh6K8VR5VkiZAkEGg0u ZIT3NjsF
+uri.arpa. 3600 IN DNSKEY 257 3 8 AwEAAdkTaWkZtZuRh7/OobBUFxM+ytTst+bCu0r9w+rEwXD7GbDs0pIM hMenrZzoAvmv1fQxw2MGs6Ri6yPKfNULcFOSt9l8i6BVBLI+SKTY6XXe DUQpSEmSaxohHeRPMQFzpysfjxINp/L2rGtZ7yPmxY/XRiFPSO0myqwG Ja9r06Zw9CHM5UDHKWV/E+zxPFq/I7CfPbrrzbUotBX7Z6Vh3Sarllbe 8cGUB2UFNaTRgwB0TwDBPRD5ER3w2Dzbry9NhbElTr7vVfhaGWeOGuqA UXwlXEg6CrNkmJXJ2F1Rzr9WHUzhp7uWxhAbmJREGfi2dEyPAbUAyCjB qhFaqglknvc=
+uri.arpa. 3600 IN DNSKEY 257 3 8 AwEAAenQaBoFmDmvRT+/H5oNbm0Tr5FmNRNDEun0Jpj/ELkzeUrTWhNp QmZeIMC8I0kZ185tEvOnRvn8OvV39B17QIdrvvKGIh2HlgeDRCLolhao jfn2QM0DStjF/WWHpxJOmE6CIuvhqYEU37yoJscGAPpPVPzNvnL1HhYT aao1VRYWQ/maMrJ+bfHg+YX1N6M/8MnRjIKBif1FWjbCKvsn6dnuGGL9 oCWYUFJ3DwofXuhgPyZMkzPc88YkJj5EMvbMH4wtelbCwC+ivx732l0w /rXJn0ciQSOgoeVvDio8dIJmWQITWQAuP+q/ZHFEFHPlrP3gvQh5mcVS 48eLX71Bq7c=
+uri.arpa. 3600 IN RRSIG DNSKEY 8 2 3600 20210217232440 20210120232440 12670 uri.arpa. DBE2gkKAoxJCfz47KKxzoImN/0AKArhIVHE7TyTwy0DdRPo44V5R+vL6 thUxlQ1CJi2Rw0jwAXymx5Y3Q873pOEllH+4bJoIT4dmoBmPXfYWW7Cl vw9UPKHRP0igKHmCVwIeBYDTU3gfLcMTbR4nEWPDN0GxlL1Mf7ITaC2I oabo79Ip3M/MR8I3Vx/xZ4ZKKPHtLn3xUuJluPNanqJrED2gTslL2xWZ 1tqjsAjJv7JnJo2HJ8XVRB5zBto0IaJ2oBlqcjdcQ/0VlyoM8uOy1pDw HQ2BJl7322gNMHBP9HSiUPIOaIDNUCwW8eUcW6DIUk+s9u3GN1uTqwWz sYB/rA==
+uri.arpa. 3600 IN RRSIG DNSKEY 8 2 3600 20210217232440 20210120232440 30577 uri.arpa. Kx6HwP4UlkGc1UZ7SERXtQjPajOF4iUvkwDj7MEG1xbQFB1KoJiEb/ei W0qmSWdIhMDv8myhgauejRLyJxwxz8HDRV4xOeHWnRGfWBk4XGYwkejV zOHzoIArVdUVRbr2JKigcTOoyFN+uu52cNB7hRYu7dH5y1hlc6UbOnzR pMtGxcgVyKQ+/ARbIqGG3pegdEOvV49wTPWEiyY65P2urqhvnRg5ok/j zwAdMx4XGshiib7Ojq0sRVl2ZIzj4rFgY/qsSO8SEXEhMo2VuSkoJNio fVzYoqpxEeGnANkIT7Tx2xJL1BWyJxyc7E8Wr2QSgCcc+rYL6IkHDtJG Hy7TaQ==
+uri.arpa. 3600 IN ZONEMD 2018100702 1 1 0DBC3C4DBFD75777C12CA19C337854B1577799901307C482E9D91D5D 15CD934D16319D98E30C4201CF25A1D5A0254960
+uri.arpa. 3600 IN RRSIG ZONEMD 8 2 3600 20210217232440 20210120232440 37444 uri.arpa. QDo4XZcL3HMyn8aAHyCUsu/Tqj4Gkth8xY1EqByOb8XOTwVtA4ZNQORE 1siqNqjtJUbeJPtJSbLNqCL7rCq0CzNNnBscv6IIf4gnqJZjlGtHO30o hXtKvEc4z7SU3IASsi6bB3nLmEAyERdYSeU6UBfx8vatQDIRhkgEnnWU Th4=
+ftp.uri.arpa. 604800 IN NAPTR 0 0 "" "" "!^ftp://([^:/?#]*).*$!\\1!i" .
+ftp.uri.arpa. 604800 IN RRSIG NAPTR 8 3 604800 20210217232440 20210120232440 37444 uri.arpa. EygekDgl+Lyyq4NMSEpPyOrOywYf9Y3FAB4v1DT44J3R5QGidaH8l7ZF jHoYFI8sY64iYOCV4sBnX/dh6C1L5NgpY+8l5065Xu3vvjyzbtuJ2k6Y YwJrrCbvl5DDn53zAhhO2hL9uLgyLraZGi9i7TFGd0sm3zNyUF/EVL0C cxU=
+ftp.uri.arpa. 3600 IN NSEC http.uri.arpa. NAPTR RRSIG NSEC
+ftp.uri.arpa. 3600 IN RRSIG NSEC 8 3 3600 20210217232440 20210120232440 37444 uri.arpa. pbP4KxevPXCu/bDqcvXiuBppXyFEmtHyiy0eAN5gS7mi6mp9Z9bWFjx/ LdH9+6oFGYa5vGmJ5itu/4EDMe8iQeZbI8yrpM4TquB7RR/MGfBnTd8S +sjyQtlRYG7yqEu77Vd78Fme22BKPJ+MVqjS0JHMUE/YUGomPkAjLJJw wGw=
+http.uri.arpa. 604800 IN NAPTR 0 0 "" "" "!^http://([^:/?#]*).*$!\\1!i" .
+http.uri.arpa. 604800 IN RRSIG NAPTR 8 3 604800 20210217232440 20210120232440 37444 uri.arpa. eTqbWvt1GvTeXozuvm4ebaAfkXFQKrtdu0cEiExto80sHIiCbO0WL8UD a/J3cDivtQca7LgUbOb6c17NESsrsVkc6zNPx5RK2tG7ZQYmhYmtqtfg 1oU5BRdHZ5TyqIXcHlw9Blo2pir1Y9IQgshhD7UOGkbkEmvB1Lrd0aHh AAg=
+http.uri.arpa. 3600 IN NSEC mailto.uri.arpa. NAPTR RRSIG NSEC
+http.uri.arpa. 3600 IN RRSIG NSEC 8 3 3600 20210217232440 20210120232440 37444 uri.arpa. R9rlNzw1CVz2N08q6DhULzcsuUm0UKcPaGAWEU40tr81jEDHsFHNM+kh CdOI8nDstzA42aee4rwCEgijxJpRCcY9hrO1Ysrrr2fdqNz60JikMdar vU5O0p0VXeaaJDfJQT44+o+YXaBwI7Qod3FTMx7aRib8i7istvPm1Rr7 ixA=
+mailto.uri.arpa. 604800 IN NAPTR 0 0 "" "" "!^mailto:(.*)@(.*)$!\\2!i" .
+mailto.uri.arpa. 604800 IN RRSIG NAPTR 8 3 604800 20210217232440 20210120232440 37444 uri.arpa. Ch2zTG2F1plEvQPyIH4Yd80XXLjXOPvMbiqDjpJBcnCJsV8QF7kr0wTL nUT3dB+asQudOjPyzaHGwFlMzmrrAsszN4XAMJ6htDtFJdsgTMP/NkHh YRSmVv6rLeAhd+mVfObY12M//b/GGVTjeUI/gJaLW0fLVZxr1Fp5U5CR jyw=
+mailto.uri.arpa. 3600 IN NSEC urn.uri.arpa. NAPTR RRSIG NSEC
+mailto.uri.arpa. 3600 IN RRSIG NSEC 8 3 3600 20210217232440 20210120232440 37444 uri.arpa. fQUbSIE6E7JDi2rosah4SpCOTrKufeszFyj5YEavbQuYlQ5cNFvtm8Ku E2xXMRgRI4RGvM2leVqcoDw5hS3m2pOJLxH8l2WE72YjYvWhvnwc5Rof e/8yB/vaSK9WCnqN8y2q6Vmy73AGP0fuiwmuBra7LlkOiqmyx3amSFiz wms=
+urn.uri.arpa. 604800 IN NAPTR 0 0 "" "" "/urn:([^:]+)/\\1/i" .
+urn.uri.arpa. 604800 IN RRSIG NAPTR 8 3 604800 20210217232440 20210120232440 37444 uri.arpa. CVt2Tgz0e5ZmaSXqRfNys/8OtVCk9nfP0zhezhN8Bo6MDt6yyKZ2kEEW JPjkN7PCYHjO8fGjnUn0AHZI2qBNv7PKHcpR42VY03q927q85a65weOO 1YE0vPYMzACpua9TOtfNnynM2Ws0uN9URxUyvYkXBdqOC81N3sx1dVEL cwc=
+urn.uri.arpa. 3600 IN NSEC uri.arpa. NAPTR RRSIG NSEC
+urn.uri.arpa. 3600 IN RRSIG NSEC 8 3 3600 20210217232440 20210120232440 37444 uri.arpa. JuKkMiC3/j9iM3V8/izcouXWAVGnSZjkOgEgFPhutMqoylQNRcSkbEZQ zFK8B/PIVdzZF0Y5xkO6zaKQjOzz6OkSaNPIo1a7Vyyl3wDY/uLCRRAH RJfpknuY7O+AUNXvVVIEYJqZggd4kl/Rjh1GTzPYZTRrVi5eQidI1LqC Oeg=
diff --git a/daemon/zimport.test/tz-rfc-a5.zone b/daemon/zimport.test/tz-rfc-a5.zone
new file mode 100644
index 0000000..246f5e2
--- /dev/null
+++ b/daemon/zimport.test/tz-rfc-a5.zone
@@ -0,0 +1,48 @@
+root-servers.net. 3600000 IN SOA a.root-servers.net. (
+ nstld.verisign-grs.com. 2018091100 14400 7200 1209600 3600000 )
+root-servers.net. 3600000 IN NS a.root-servers.net.
+root-servers.net. 3600000 IN NS b.root-servers.net.
+root-servers.net. 3600000 IN NS c.root-servers.net.
+root-servers.net. 3600000 IN NS d.root-servers.net.
+root-servers.net. 3600000 IN NS e.root-servers.net.
+root-servers.net. 3600000 IN NS f.root-servers.net.
+root-servers.net. 3600000 IN NS g.root-servers.net.
+root-servers.net. 3600000 IN NS h.root-servers.net.
+root-servers.net. 3600000 IN NS i.root-servers.net.
+root-servers.net. 3600000 IN NS j.root-servers.net.
+root-servers.net. 3600000 IN NS k.root-servers.net.
+root-servers.net. 3600000 IN NS l.root-servers.net.
+root-servers.net. 3600000 IN NS m.root-servers.net.
+a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30
+a.root-servers.net. 3600000 IN A 198.41.0.4
+b.root-servers.net. 3600000 IN MX 20 mail.isi.edu.
+b.root-servers.net. 3600000 IN AAAA 2001:500:200::b
+b.root-servers.net. 3600000 IN A 199.9.14.201
+c.root-servers.net. 3600000 IN AAAA 2001:500:2::c
+c.root-servers.net. 3600000 IN A 192.33.4.12
+d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d
+d.root-servers.net. 3600000 IN A 199.7.91.13
+e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e
+e.root-servers.net. 3600000 IN A 192.203.230.10
+f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f
+f.root-servers.net. 3600000 IN A 192.5.5.241
+g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d
+g.root-servers.net. 3600000 IN A 192.112.36.4
+h.root-servers.net. 3600000 IN AAAA 2001:500:1::53
+h.root-servers.net. 3600000 IN A 198.97.190.53
+i.root-servers.net. 3600000 IN MX 10 mx.i.root-servers.org.
+i.root-servers.net. 3600000 IN AAAA 2001:7fe::53
+i.root-servers.net. 3600000 IN A 192.36.148.17
+j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30
+j.root-servers.net. 3600000 IN A 192.58.128.30
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+k.root-servers.net. 3600000 IN A 193.0.14.129
+l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42
+l.root-servers.net. 3600000 IN A 199.7.83.42
+m.root-servers.net. 3600000 IN AAAA 2001:dc3::35
+m.root-servers.net. 3600000 IN A 202.12.27.33
+root-servers.net. 3600000 IN SOA a.root-servers.net. (
+ nstld.verisign-grs.com. 2018091100 14400 7200 1209600 3600000 )
+root-servers.net. 3600000 IN ZONEMD 2018091100 1 1 (
+ f1ca0ccd91bd5573d9f431c00ee0101b2545c97602be0a97
+ 8a3b11dbfc1c776d5b3e86ae3d973d6b5349ba7f04340f79 )
diff --git a/daemon/zimport.test/zimport.test.lua b/daemon/zimport.test/zimport.test.lua
new file mode 100644
index 0000000..f6abc02
--- /dev/null
+++ b/daemon/zimport.test/zimport.test.lua
@@ -0,0 +1,47 @@
+-- unload modules which are not related to this test
+-- SPDX-License-Identifier: GPL-3.0-or-later
+
+if ta_signal_query then
+ modules.unload('ta_signal_query')
+end
+if priming then
+ modules.unload('priming')
+end
+if detect_time_skew then
+ modules.unload('detect_time_skew')
+end
+
+-- do not listen, test is driven by config code
+env.KRESD_NO_LISTEN = true
+
+
+cache.size = 5*MB
+log_groups({'prefil'})
+
+--[[ This test checks ZONEMD computation on some model cases. (no DNSSEC validation)
+ https://www.rfc-editor.org/rfc/rfc8976.html#name-example-zones-with-digests
+--]]
+
+
+local function test_zone(file_name, success) return function()
+ local import_res = require('ffi').C.zi_zone_import({
+ zone_file = file_name,
+ zonemd = true,
+ downgrade = true,
+ })
+ if success == nil or success then
+ is(import_res, 0, 'zone import should start OK for file ' .. file_name)
+ else
+ isnt(import_res, 0, 'zone import should fail for file ' .. file_name)
+ end
+ worker.sleep(0.2) -- zimport is delayed by 100 ms from function call
+end end
+
+return {
+ test_zone('tz-rfc-a1.zone'),
+ test_zone('tz-rfc-a1-bad.zone', false),
+ test_zone('tz-rfc-a2.zone'),
+ test_zone('tz-rfc-a3.zone'),
+ test_zone('tz-rfc-a4.zone'),
+ test_zone('tz-rfc-a5.zone'),
+}
diff --git a/distro/config/apkg.toml b/distro/config/apkg.toml
new file mode 100644
index 0000000..378179d
--- /dev/null
+++ b/distro/config/apkg.toml
@@ -0,0 +1,12 @@
+[project]
+name = "knot-resolver"
+# needed for make-archive
+make_archive_script = "scripts/make-archive.sh"
+
+[upstream]
+# needed for get-archive
+archive_url = "https://secure.nic.cz/files/knot-resolver/knot-resolver-{{ version }}.tar.xz"
+signature_url = "https://secure.nic.cz/files/knot-resolver/knot-resolver-{{ version }}.tar.xz.asc"
+
+[apkg]
+compat = 2
diff --git a/distro/pkg/arch/PKGBUILD b/distro/pkg/arch/PKGBUILD
new file mode 100644
index 0000000..7eea556
--- /dev/null
+++ b/distro/pkg/arch/PKGBUILD
@@ -0,0 +1,71 @@
+# Maintainer: Tomas Krizek <tomas.krizek@nic.cz>
+# Contributor: Ondřej Surý <ondrej@sury.org>
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+pkgname=knot-resolver
+pkgver={{ version }}
+pkgrel={{ release }}
+pkgdesc='Caching DNSSEC-validating DNS resolver'
+arch=('x86_64' 'armv7h')
+url='https://www.knot-resolver.cz/'
+license=('GPL3')
+depends=(
+ 'dnssec-anchors'
+ 'gnutls'
+ 'knot'
+ 'libedit'
+ 'libuv'
+ 'lmdb'
+ 'luajit'
+ 'systemd'
+ 'libcap-ng'
+ 'libnghttp2'
+ 'jemalloc'
+)
+makedepends=(
+ 'cmocka'
+ 'meson'
+ 'systemd-libs'
+)
+optdepends=(
+ 'lua51-basexx: experimental_dot_auth module'
+ 'lua51-cqueues: http and dns64 module, policy.rpz() function'
+ 'lua51-http: http and prefill modules, trust_anchors bootstrap'
+ 'lua51-psl: policy.slice_randomize_psl() function'
+)
+backup=('etc/knot-resolver/kresd.conf')
+options=(debug strip)
+source=("knot-resolver-${pkgver}.tar.xz")
+sha256sums=('SKIP')
+
+build() {
+ cd "${srcdir}/${pkgname}-${pkgver}"
+ meson build \
+ --buildtype=release \
+ --prefix=/usr \
+ --sbindir=bin \
+ -D keyfile_default=/etc/trusted-key.key \
+ -D systemd_files=enabled \
+ -D client=enabled \
+ -D install_kresd_conf=enabled \
+ -D malloc=jemalloc \
+ -D unit_tests=enabled
+ ninja -C build
+}
+
+check() {
+ cd "${srcdir}/${pkgname}-${pkgver}"
+ meson test -C build
+}
+
+package() {
+ cd "${srcdir}/${pkgname}-${pkgver}"
+ DESTDIR=${pkgdir} ninja -C build install
+
+ # add kresd.target to multi-user.target.wants to support enabling kresd services
+ install -d -m 0755 "${pkgdir}/usr/lib/systemd/system/multi-user.target.wants"
+ ln -s ../kresd.target "${pkgdir}/usr/lib/systemd/system/multi-user.target.wants/kresd.target"
+
+ # remove modules with missing dependencies
+ rm "${pkgdir}/usr/lib/knot-resolver/kres_modules/etcd.lua"
+}
diff --git a/distro/pkg/deb/changelog b/distro/pkg/deb/changelog
new file mode 100644
index 0000000..e1e7de9
--- /dev/null
+++ b/distro/pkg/deb/changelog
@@ -0,0 +1,6 @@
+knot-resolver ({{ version }}-cznic.{{ release }}) unstable; urgency=medium
+
+ * upstream package
+ * see NEWS or https://knot-resolver.cz
+
+ -- Jakub RužiÄka <jakub.ruzicka@nic.cz> {{ now }}
diff --git a/distro/pkg/deb/clean b/distro/pkg/deb/clean
new file mode 100644
index 0000000..3c2f3ba
--- /dev/null
+++ b/distro/pkg/deb/clean
@@ -0,0 +1,3 @@
+build_deb/
+doc/doxyxml/
+doc/html/
diff --git a/distro/pkg/deb/compat b/distro/pkg/deb/compat
new file mode 100644
index 0000000..ec63514
--- /dev/null
+++ b/distro/pkg/deb/compat
@@ -0,0 +1 @@
+9
diff --git a/distro/pkg/deb/control b/distro/pkg/deb/control
new file mode 100644
index 0000000..1f9964d
--- /dev/null
+++ b/distro/pkg/deb/control
@@ -0,0 +1,140 @@
+Source: knot-resolver
+Section: net
+Priority: optional
+Maintainer: Knot Resolver <knot-resolver@labs.nic.cz>
+Build-Depends:
+ debhelper (>= 9~),
+ libcmocka-dev (>= 1.0.0),
+ libedit-dev,
+ libfstrm-dev,
+ libgnutls28-dev,
+ libknot-dev (>= 3.0.2),
+ liblmdb-dev,
+ libluajit-5.1-dev,
+ libnghttp2-dev,
+ libprotobuf-c-dev,
+ libsystemd-dev (>= 227) [linux-any],
+ libcap-ng-dev,
+ libuv1-dev,
+ libjemalloc-dev,
+ luajit,
+ pkg-config,
+ meson (>= 0.49),
+ doxygen,
+ protobuf-c-compiler,
+ python3-breathe,
+ python3-sphinx,
+ python3-sphinx-rtd-theme,
+ texinfo,
+ libssl-dev,
+Homepage: https://www.knot-resolver.cz/
+
+Package: knot-resolver
+Architecture: any
+Depends:
+ adduser,
+ dns-root-data,
+ systemd,
+ ${misc:Depends},
+ ${shlibs:Depends},
+Replaces:
+ libkres9 (<< 3.2.1-2),
+Breaks:
+ libkres9 (<< 3.2.1-2),
+Recommends:
+ lua-basexx,
+ lua-cqueues,
+ lua-http,
+ lua-psl,
+Suggests:
+ knot-resolver-module-http,
+Description: caching, DNSSEC-validating DNS resolver
+ The Knot Resolver is a caching full resolver implementation
+ written in C and LuaJIT, including both a resolver library and a
+ daemon. Modular architecture of the library keeps the core tiny and
+ efficient, and provides a state-machine like API for
+ extensions. There are three built-in modules - iterator, cache,
+ validator, and many external.
+ .
+ The Lua modules, switchable and shareable cache, and fast FFI
+ bindings makes it great to tap into resolution process, or be used
+ for your recursive DNS service. It's the OpenResty of DNS.
+ .
+ The server adopts a different scaling strategy than the rest of the
+ DNS recursors - no threading, shared-nothing architecture (except
+ MVCC cache that may be shared). You can start and stop additional
+ nodes depending on the contention without downtime.
+
+Package: knot-resolver-dbg
+Architecture: any
+Depends: knot-resolver (= ${binary:Version}),
+ ${misc:Depends}
+Recommends: gdb
+Section: debug
+Priority: extra
+Description: Debug symbols for Knot Resolver
+ This package provides the debug symbols for Knot Resolver needed
+ for properly debugging errors in Knot Resolver with gdb.
+
+Package: knot-resolver-module-dnstap
+Architecture: any
+Multi-Arch: same
+Depends:
+ knot-resolver (= ${binary:Version}),
+ libfstrm0,
+ libprotobuf-c1,
+ ${misc:Depends},
+ ${shlibs:Depends},
+Description: dnstap module for Knot Resolver
+ The Knot Resolver is a caching full resolver implementation
+ written in C and LuaJIT, including both a resolver library and a
+ daemon. Modular architecture of the library keeps the core tiny and
+ efficient, and provides a state-machine like API for
+ extensions. There are three built-in modules - iterator, cache,
+ validator, and many external.
+ .
+ This package contains dnstap module for logging DNS responses
+ to a unix socket in dnstap format.
+
+Package: knot-resolver-module-http
+Architecture: all
+Depends:
+ knot-resolver (= ${binary:Version}),
+ libjs-bootstrap,
+ libjs-d3,
+ libjs-jquery,
+ lua-cqueues (>= 20171014),
+ lua-http,
+ lua-mmdb,
+ systemd,
+ ${misc:Depends},
+ ${shlibs:Depends},
+Breaks:
+ knot-resolver-module-tinyweb (<< 1.1.0~git20160713-1~),
+Description: HTTP module for Knot Resolver
+ The Knot Resolver is a caching full resolver implementation
+ written in C and LuaJIT, including both a resolver library and a
+ daemon. Modular architecture of the library keeps the core tiny and
+ efficient, and provides a state-machine like API for
+ extensions. There are three built-in modules - iterator, cache,
+ validator, and many external.
+ .
+ This package contains HTTP/2 module for local visualization of the
+ resolver cache and queries.
+
+Package: knot-resolver-doc
+Architecture: all
+Section: doc
+Depends:
+ libjs-jquery,
+ libjs-underscore,
+ ${misc:Depends},
+Description: Documentation for Knot Resolver
+ The Knot Resolver is a caching full resolver implementation
+ written in C and LuaJIT, including both a resolver library and a
+ daemon. Modular architecture of the library keeps the core tiny and
+ efficient, and provides a state-machine like API for
+ extensions. There are three built-in modules - iterator, cache,
+ validator, and many external.
+ .
+ This package contains Knot Resolver Documentation.
diff --git a/distro/pkg/deb/copyright b/distro/pkg/deb/copyright
new file mode 100644
index 0000000..96e23ca
--- /dev/null
+++ b/distro/pkg/deb/copyright
@@ -0,0 +1,440 @@
+Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
+Upstream-Name: knot-resolver
+Source: https://www.knot-resolver.cz/
+
+Files: *
+Copyright: CZ.NIC
+License: GPL-3.0+
+
+Files: contrib/ccan/asprintf/*
+Copyright: Rusty Russell
+License: Expat
+
+Files: contrib/ccan/compiler/*
+Copyright: Rusty Russell
+License: CC0
+
+Files: tests/config/tapered/*
+Copyright: 2012-2017, Peter Aronoff
+License: BSD-3-clause
+
+Files: contrib/lmdb/*
+Copyright: 1999-2003 The OpenLDAP Foundation
+License: OpenLDAP
+
+Files: tests/deckard/contrib/libfaketime/*
+Copyright: 2003-2017 Wolfgang Hommel
+License: GPL-2
+
+Files: tests/deckard/contrib/libswrap/*
+Copyright: 2005,2008 Jelmer Vernooij <jelmer@samba.org>
+ 2006-2009 Stefan Metzmacher <metze@samba.org>
+ 2013 Andreas Schneider <asn@samba.org>
+License: BSD-3-clause
+
+Files: contrib/murmurhash3/*
+Copyright: Austin Appleby
+License: CC0-1.0
+
+Files: debian/missing-sources/dygraph-combined.js
+ modules/http/static/dygraph-combined.js
+Copyright: 2006-2014 Dan Vanderkam <danvdk@gmail.com>
+ 2016 Paul Miller
+ 2011 Robert Konigsberg <konigsberg@google.com>
+ 2013 David Eberlein <david.eberlein@ch.sauter-bc.com>
+License: MIT
+
+Files: contrib/ucw/*
+Copyright: 1997-2015 Martin Mares
+ 2005-2014 Tomas Valla
+ 2006 Robert Spalek
+ 2007-2015 Pavel Charvat
+License: LGPL-2.1
+
+Files: contrib/ccan/json/*
+Copyright: 2011 Joey Adams
+License: Expat
+
+Files: modules/policy/lua-aho-corasick/*
+Copyright: 2013 CloudFlare, Inc.
+License: BSD-3-CloudFlare
+
+Files: modules/http/static/jquery.js
+Copyright: 2005-2011 John Resig, Brandon Aaron & Jörn Zaefferer
+License: GPL-2 or Expat
+
+Files: modules/http/static/d3.js
+ modules/http/static/topojson.js
+Copyright: 2010-2015 Michael Bostock
+License: BSD-3-clause
+
+Files: modules/http/static/epoch.*
+ debian/missing-sources/epoch/*
+ debian/missing-sources/epoch.*
+Copyright: 2014 Fastly, Inc.
+License: Expat
+
+Files: modules/http/static/datamaps.world.min.js
+Copyright: 2012 Mark DiMarco
+License: Expat
+
+Files: modules/http/static/bootstrap.min.css
+ modules/http/static/bootstrap.min.js
+ modules/http/static/bootstrap-theme.min.css
+ modules/http/static/glyphicons-halflings-regular.woff2
+Copyright: 2012-2016 Thomas Park
+ 2011-2015 Twitter, Inc.
+License: Expat
+
+Files: modules/http/static/selectize.bootstrap3.min.css
+ modules/http/static/selectize.min.css
+ modules/http/static/selectize.min.js
+Copyright: 2013–2015 Brian Reavis & contributors
+License: Apache-2.0
+
+Files: debian/*
+Copyright: 2015 Ondřej Surý <ondrej@debian.org>
+License: GPL-3.0+
+
+License: LGPL-2.1
+ This library is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of the
+ License, or (at your option) any later version.
+ .
+ This library is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+ .
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library. If not, see <https://www.gnu.org/licenses/>.
+ .
+ On Debian systems, the complete text of the GNU General
+ Public License version 3 can be found in "/usr/share/common-licenses/LGPL-2.1".
+
+License: GPL-3.0+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+ .
+ This package is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+ .
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
+ .
+ On Debian systems, the complete text of the GNU General
+ Public License version 3 can be found in "/usr/share/common-licenses/GPL-3".
+
+License: Expat
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+ .
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+ .
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ SOFTWARE.
+
+License: CC0
+ Statement of Purpose
+ .
+ The laws of most jurisdictions throughout the world automatically
+ confer exclusive Copyright and Related Rights (defined below) upon
+ the creator and subsequent owner(s) (each and all, an "owner") of an
+ original work of authorship and/or a database (each, a "Work").
+ .
+ Certain owners wish to permanently relinquish those rights to a Work
+ for the purpose of contributing to a commons of creative, cultural
+ and scientific works ("Commons") that the public can reliably and
+ without fear of later claims of infringement build upon, modify,
+ incorporate in other works, reuse and redistribute as freely as
+ possible in any form whatsoever and for any purposes, including
+ without limitation commercial purposes. These owners may contribute
+ to the Commons to promote the ideal of a free culture and the further
+ production of creative, cultural and scientific works, or to gain
+ reputation or greater distribution for their Work in part through the
+ use and efforts of others.
+ .
+ For these and/or other purposes and motivations, and without any
+ expectation of additional consideration or compensation, the person
+ associating CC0 with a Work (the "Affirmer"), to the extent that he
+ or she is an owner of Copyright and Related Rights in the Work,
+ voluntarily elects to apply CC0 to the Work and publicly distribute
+ the Work under its terms, with knowledge of his or her Copyright and
+ Related Rights in the Work and the meaning and intended legal effect
+ of CC0 on those rights.
+ .
+ 1. Copyright and Related Rights. A Work made available under CC0 may
+ be protected by copyright and related or neighboring rights
+ ("Copyright and Related Rights"). Copyright and Related Rights
+ include, but are not limited to, the following:
+ .
+ i. the right to reproduce, adapt, distribute, perform, display,
+ communicate, and translate a Work;
+ ii. moral rights retained by the original author(s) and/or
+ performer(s);
+ iii. publicity and privacy rights pertaining to a person's image or
+ likeness depicted in a Work;
+ iv. rights protecting against unfair competition in regards to a
+ Work, subject to the limitations in paragraph 4(a), below;
+ v. rights protecting the extraction, dissemination, use and reuse
+ of data in a Work;
+ vi. database rights (such as those arising under Directive 96/9/EC
+ of the European Parliament and of the Council of 11 March 1996
+ on the legal protection of databases, and under any national
+ implementation thereof, including any amended or successor
+ version of such directive); and
+ vii. other similar, equivalent or corresponding rights throughout
+ the world based on applicable law or treaty, and any national
+ implementations thereof.
+ .
+ 2. Waiver. To the greatest extent permitted by, but not in
+ contravention of, applicable law, Affirmer hereby overtly, fully,
+ permanently, irrevocably and unconditionally waives, abandons, and
+ surrenders all of Affirmer's Copyright and Related Rights and
+ associated claims and causes of action, whether now known or
+ unknown (including existing as well as future claims and causes of
+ action), in the Work (i) in all territories worldwide, (ii) for
+ the maximum duration provided by applicable law or treaty
+ (including future time extensions), (iii) in any current or future
+ medium and for any number of copies, and (iv) for any purpose
+ whatsoever, including without limitation commercial, advertising
+ or promotional purposes (the "Waiver"). Affirmer makes the Waiver
+ for the benefit of each member of the public at large and to the
+ detriment of Affirmer's heirs and successors, fully intending that
+ such Waiver shall not be subject to revocation, rescission,
+ cancellation, termination, or any other legal or equitable action
+ to disrupt the quiet enjoyment of the Work by the public as
+ contemplated by Affirmer's express Statement of Purpose.
+ .
+ 3. Public License Fallback. Should any part of the Waiver for any
+ reason be judged legally invalid or ineffective under applicable
+ law, then the Waiver shall be preserved to the maximum extent
+ permitted taking into account Affirmer's express Statement of
+ Purpose. In addition, to the extent the Waiver is so judged
+ Affirmer hereby grants to each affected person a royalty-free, non
+ transferable, non sublicensable, non exclusive, irrevocable and
+ unconditional license to exercise Affirmer's Copyright and Related
+ Rights in the Work (i) in all territories worldwide, (ii) for the
+ maximum duration provided by applicable law or treaty (including
+ future time extensions), (iii) in any current or future medium and
+ for any number of copies, and (iv) for any purpose whatsoever,
+ including without limitation commercial, advertising or
+ promotional purposes (the "License"). The License shall be deemed
+ effective as of the date CC0 was applied by Affirmer to the
+ Work. Should any part of the License for any reason be judged
+ legally invalid or ineffective under applicable law, such partial
+ invalidity or ineffectiveness shall not invalidate the remainder
+ of the License, and in such case Affirmer hereby affirms that he
+ or she will not (i) exercise any of his or her remaining Copyright
+ and Related Rights in the Work or (ii) assert any associated
+ claims and causes of action with respect to the Work, in either
+ case contrary to Affirmer's express Statement of Purpose.
+ .
+ 4. Limitations and Disclaimers.
+ .
+ a. No trademark or patent rights held by Affirmer are waived,
+ abandoned, surrendered, licensed or otherwise affected by this
+ document.
+ b. Affirmer offers the Work as-is and makes no representations or
+ warranties of any kind concerning the Work, express, implied,
+ statutory or otherwise, including without limitation warranties
+ of title, merchantability, fitness for a particular purpose, non
+ infringement, or the absence of latent or other defects,
+ accuracy, or the present or absence of errors, whether or not
+ discoverable, all to the greatest extent permissible under
+ applicable law.
+ c. Affirmer disclaims responsibility for clearing rights of other
+ persons that may apply to the Work or any use thereof, including
+ without limitation any person's Copyright and Related Rights in
+ the Work. Further, Affirmer disclaims responsibility for
+ obtaining any necessary consents, permissions or other rights
+ required for any use of the Work.
+ d. Affirmer understands and acknowledges that Creative Commons is
+ not a party to this document and has no duty or obligation with
+ respect to this CC0 or use of the Work.
+
+License: BSD-3-CloudFlare
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ .
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ .
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ .
+ 3. Neither the name of CloudFlare, Inc. nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+ .
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+License: BSD-3-clause
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ .
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ .
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ .
+ 3. Neither the name of the author nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+ .
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+
+
+License: GPL-2
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+ .
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+ .
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ .
+ On Debian systems, the complete text of the GNU General Public
+ License version 2 can be found in "/usr/share/common-licenses/GPL-2".
+
+License: Apache-2.0
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+ .
+ https://www.apache.org/licenses/LICENSE-2.0
+ .
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ .
+ On Debian systems, the full text of the Apache Software License version 2 can
+ be found in the file `/usr/share/common-licenses/Apache-2.0'.
+
+License: MIT
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+ .
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+ .
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ SOFTWARE.
+
+License: OpenLDAP
+ Redistribution and use of this software and associated documentation
+ ("Software"), with or without modification, are permitted provided
+ that the following conditions are met:
+ .
+ 1. Redistributions in source form must retain copyright statements
+ and notices,
+ .
+ 2. Redistributions in binary form must reproduce applicable copyright
+ statements and notices, this list of conditions, and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution, and
+ .
+ 3. Redistributions must contain a verbatim copy of this document.
+ .
+ The OpenLDAP Foundation may revise this license from time to time.
+ Each revision is distinguished by a version number. You may use
+ this Software under terms of this license revision or under the
+ terms of any subsequent revision of the license.
+ .
+ THIS SOFTWARE IS PROVIDED BY THE OPENLDAP FOUNDATION AND ITS
+ CONTRIBUTORS ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ SHALL THE OPENLDAP FOUNDATION, ITS CONTRIBUTORS, OR THE AUTHOR(S)
+ OR OWNER(S) OF THE SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+ .
+ The names of the authors and copyright holders must not be used in
+ advertising or otherwise to promote the sale, use or other dealing
+ in this Software without specific, written prior permission. Title
+ to copyright in this Software shall at all times remain with copyright
+ holders.
+ .
+ OpenLDAP is a registered trademark of the OpenLDAP Foundation.
+
+License: CC0-1.0
+ This work is licensed under the "Creative Commons Zero" license.
+ .
+ On debian systems, a copy of the Creative Commons Zero license may be
+ found at /usr/share/common-licenses/CC0-1.0.
+
+License: public-domain
+ This work has been released into the public domain. The map
+ implementation builds off of prior public domain work from Dan
+ Bernstein (qhasm) and Adam Langley (critbit).
diff --git a/distro/pkg/deb/knot-resolver-doc.doc-base b/distro/pkg/deb/knot-resolver-doc.doc-base
new file mode 100644
index 0000000..9cd0fdf
--- /dev/null
+++ b/distro/pkg/deb/knot-resolver-doc.doc-base
@@ -0,0 +1,11 @@
+Document: knot-resolver
+Title: Knot Resolver documentation
+Author: CZ.NIC labs
+Abstract: Documentation for the Knot Resolver,
+ including building from source, using the library,
+ and configuration and operation of the daemon.
+Section: Network/Communication
+
+Format: HTML
+Index: /usr/share/doc/knot-resolver/html/index.html
+Files: /usr/share/doc/knot-resolver/html/*.html
diff --git a/distro/pkg/deb/knot-resolver-doc.docs b/distro/pkg/deb/knot-resolver-doc.docs
new file mode 100644
index 0000000..baa81f7
--- /dev/null
+++ b/distro/pkg/deb/knot-resolver-doc.docs
@@ -0,0 +1 @@
+debian/tmp/usr/share/doc/knot-resolver/html/*
diff --git a/distro/pkg/deb/knot-resolver-doc.info b/distro/pkg/deb/knot-resolver-doc.info
new file mode 100644
index 0000000..2283d88
--- /dev/null
+++ b/distro/pkg/deb/knot-resolver-doc.info
@@ -0,0 +1,2 @@
+debian/tmp/usr/share/info/knot-resolver.info
+debian/tmp/usr/share/info/knot-resolver-figures/*
diff --git a/distro/pkg/deb/knot-resolver-doc.links b/distro/pkg/deb/knot-resolver-doc.links
new file mode 100644
index 0000000..25e9584
--- /dev/null
+++ b/distro/pkg/deb/knot-resolver-doc.links
@@ -0,0 +1,2 @@
+usr/share/javascript/jquery/jquery.min.js usr/share/doc/knot-resolver/html/_static/jquery.js
+usr/share/javascript/underscore/underscore.min.js usr/share/doc/knot-resolver/html/_static/underscore.js
diff --git a/distro/pkg/deb/knot-resolver-module-dnstap.install b/distro/pkg/deb/knot-resolver-module-dnstap.install
new file mode 100644
index 0000000..ae5404e
--- /dev/null
+++ b/distro/pkg/deb/knot-resolver-module-dnstap.install
@@ -0,0 +1 @@
+usr/lib/knot-resolver/kres_modules/dnstap.so
diff --git a/distro/pkg/deb/knot-resolver-module-http.install b/distro/pkg/deb/knot-resolver-module-http.install
new file mode 100644
index 0000000..ffa04d0
--- /dev/null
+++ b/distro/pkg/deb/knot-resolver-module-http.install
@@ -0,0 +1,7 @@
+usr/lib/knot-resolver/kres_modules/http*.lua
+usr/lib/knot-resolver/kres_modules/prometheus.lua
+usr/lib/knot-resolver/kres_modules/http/*.css
+usr/lib/knot-resolver/kres_modules/http/*.ico
+usr/lib/knot-resolver/kres_modules/http/*.js
+usr/lib/knot-resolver/kres_modules/http/*.tpl
+usr/lib/knot-resolver/kres_modules/http/*.woff2
diff --git a/distro/pkg/deb/knot-resolver-module-http.links b/distro/pkg/deb/knot-resolver-module-http.links
new file mode 100644
index 0000000..4963c5c
--- /dev/null
+++ b/distro/pkg/deb/knot-resolver-module-http.links
@@ -0,0 +1,5 @@
+usr/share/javascript/bootstrap/css/bootstrap-theme.min.css usr/lib/knot-resolver/kres_modules/http/bootstrap-theme.min.css
+usr/share/javascript/bootstrap/css/bootstrap.min.css usr/lib/knot-resolver/kres_modules/http/bootstrap.min.css
+usr/share/javascript/bootstrap/js/bootstrap.min.js usr/lib/knot-resolver/kres_modules/http/bootstrap.min.js
+usr/share/javascript/d3/d3.min.js usr/lib/knot-resolver/kres_modules/http/d3.js
+usr/share/javascript/jquery/jquery.min.js usr/lib/knot-resolver/kres_modules/http/jquery.js
diff --git a/distro/pkg/deb/knot-resolver-module-http.preinst b/distro/pkg/deb/knot-resolver-module-http.preinst
new file mode 100644
index 0000000..c2bd87d
--- /dev/null
+++ b/distro/pkg/deb/knot-resolver-module-http.preinst
@@ -0,0 +1,26 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-3.0-or-later
+set -e
+
+# upgrade-4-to-5
+if [ -f /lib/systemd/system/kresd-doh.socket ] ; then
+ export UPG_DIR=/var/lib/knot-resolver/.upgrade-4-to-5
+ mkdir -p ${UPG_DIR}
+ touch ${UPG_DIR}/.unfinished
+
+ for sock in kresd-webmgmt.socket kresd-doh.socket ; do
+ if systemctl is-enabled ${sock} 2>/dev/null | grep -qv masked ; then
+ systemctl show ${sock} -p Listen > ${UPG_DIR}/${sock}
+ case "$(systemctl show ${sock} -p BindIPv6Only)" in
+ *ipv6-only)
+ touch ${UPG_DIR}/${sock}.v6only
+ ;;
+ *default)
+ if cat /proc/sys/net/ipv6/bindv6only | grep -q 1 ; then
+ touch ${UPG_DIR}/${sock}.v6only
+ fi
+ ;;
+ esac
+ fi
+ done
+fi
diff --git a/distro/pkg/deb/knot-resolver.dirs b/distro/pkg/deb/knot-resolver.dirs
new file mode 100644
index 0000000..f8981d8
--- /dev/null
+++ b/distro/pkg/deb/knot-resolver.dirs
@@ -0,0 +1,2 @@
+/var/lib/knot-resolver
+/var/cache/knot-resolver
diff --git a/distro/pkg/deb/knot-resolver.docs b/distro/pkg/deb/knot-resolver.docs
new file mode 100644
index 0000000..8e919d0
--- /dev/null
+++ b/distro/pkg/deb/knot-resolver.docs
@@ -0,0 +1,4 @@
+debian/tmp/usr/share/doc/knot-resolver/AUTHORS
+debian/tmp/usr/share/doc/knot-resolver/COPYING
+debian/tmp/usr/share/doc/knot-resolver/NEWS
+debian/tmp/usr/share/doc/knot-resolver/examples
diff --git a/distro/pkg/deb/knot-resolver.install b/distro/pkg/deb/knot-resolver.install
new file mode 100644
index 0000000..7e4af15
--- /dev/null
+++ b/distro/pkg/deb/knot-resolver.install
@@ -0,0 +1,38 @@
+etc/knot-resolver/kresd.conf
+usr/lib/systemd/system/kresd@.service lib/systemd/system/
+usr/lib/systemd/system/kres-cache-gc.service lib/systemd/system/
+usr/lib/systemd/system/kresd.target lib/systemd/system/
+usr/lib/*.so.*
+usr/lib/tmpfiles.d/knot-resolver.conf
+usr/lib/knot-resolver/*.so
+usr/lib/knot-resolver/*.lua
+usr/lib/knot-resolver/kres_modules/bogus_log.so
+usr/lib/knot-resolver/kres_modules/edns_keepalive.so
+usr/lib/knot-resolver/kres_modules/extended_error.so
+usr/lib/knot-resolver/kres_modules/hints.so
+usr/lib/knot-resolver/kres_modules/nsid.so
+usr/lib/knot-resolver/kres_modules/refuse_nord.so
+usr/lib/knot-resolver/kres_modules/stats.so
+usr/lib/knot-resolver/kres_modules/daf.lua
+usr/lib/knot-resolver/kres_modules/daf/*
+usr/lib/knot-resolver/kres_modules/detect_time_jump.lua
+usr/lib/knot-resolver/kres_modules/detect_time_skew.lua
+usr/lib/knot-resolver/kres_modules/dns64.lua
+usr/lib/knot-resolver/kres_modules/experimental_dot_auth.lua
+usr/lib/knot-resolver/kres_modules/graphite.lua
+usr/lib/knot-resolver/kres_modules/policy.lua
+usr/lib/knot-resolver/kres_modules/predict.lua
+usr/lib/knot-resolver/kres_modules/prefill.lua
+usr/lib/knot-resolver/kres_modules/priming.lua
+usr/lib/knot-resolver/kres_modules/rebinding.lua
+usr/lib/knot-resolver/kres_modules/renumber.lua
+usr/lib/knot-resolver/kres_modules/serve_stale.lua
+usr/lib/knot-resolver/kres_modules/ta_sentinel.lua
+usr/lib/knot-resolver/kres_modules/ta_signal_query.lua
+usr/lib/knot-resolver/kres_modules/ta_update.lua
+usr/lib/knot-resolver/kres_modules/view.lua
+usr/lib/knot-resolver/kres_modules/watchdog.lua
+usr/lib/knot-resolver/kres_modules/workarounds.lua
+usr/sbin/kresc
+usr/sbin/kresd
+usr/sbin/kres-cache-gc
diff --git a/distro/pkg/deb/knot-resolver.links b/distro/pkg/deb/knot-resolver.links
new file mode 100644
index 0000000..8196524
--- /dev/null
+++ b/distro/pkg/deb/knot-resolver.links
@@ -0,0 +1,2 @@
+dev/null lib/systemd/system/kresd.service
+lib/systemd/system/kresd.target lib/systemd/system/multi-user.target.wants/kresd.target
diff --git a/distro/pkg/deb/knot-resolver.manpages b/distro/pkg/deb/knot-resolver.manpages
new file mode 100644
index 0000000..101a4ac
--- /dev/null
+++ b/distro/pkg/deb/knot-resolver.manpages
@@ -0,0 +1,2 @@
+debian/tmp/usr/share/man/man8/kresd.8*
+debian/tmp/usr/share/man/man7/kresd.systemd.7*
diff --git a/distro/pkg/deb/knot-resolver.postinst b/distro/pkg/deb/knot-resolver.postinst
new file mode 100644
index 0000000..fb2bce2
--- /dev/null
+++ b/distro/pkg/deb/knot-resolver.postinst
@@ -0,0 +1,38 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-3.0-or-later
+set -e
+
+# upgrade-4-to-5
+export UPG_DIR=/var/lib/knot-resolver/.upgrade-4-to-5
+if [ -f ${UPG_DIR}/.unfinished ] ; then
+ rm -f ${UPG_DIR}/.unfinished
+ kresd -c /usr/lib/knot-resolver/upgrade-4-to-5.lua >/dev/null 2>/dev/null
+ echo "\n !!! WARNING !!!"
+ echo "Knot Resolver configuration file requires manual upgrade.\n"
+ cat ${UPG_DIR}/kresd.conf.net 2>/dev/null
+fi
+
+if [ "$1" = "configure" ]; then
+ adduser --quiet --system --group --no-create-home --home /var/cache/knot-resolver knot-resolver
+fi
+
+# Restart any running kresd instances if the root key is updated.
+# Note: if knot-resolver upstream watches this file and reloads it
+# upon a change, we can and should remove this trigger.
+if [ "$1" = "triggered" ]; then
+ if [ "$2" = "/usr/share/dns/root.key" ]; then
+ # use daemon-reload to load any unit changes
+ systemctl daemon-reload || true
+ # systemctl of the sub-services is the preferred method to restart
+ systemctl try-restart 'kresd@*.service' kres-cache-gc.service || true
+ fi
+ exit 0
+fi
+
+if [ "$1" = "configure" ] || [ "$1" = "abort-upgrade" ] || [ "$1" = "abort-deconfigure" ] || [ "$1" = "abort-remove" ] ; then
+ systemctl daemon-reload || true
+ systemd-tmpfiles --create /usr/lib/tmpfiles.d/knot-resolver.conf
+ systemctl try-restart 'kresd@*.service' kres-cache-gc.service || true
+fi
+
+#DEBHELPER#
diff --git a/distro/pkg/deb/knot-resolver.postrm b/distro/pkg/deb/knot-resolver.postrm
new file mode 100644
index 0000000..4c8a1ea
--- /dev/null
+++ b/distro/pkg/deb/knot-resolver.postrm
@@ -0,0 +1,9 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-3.0-or-later
+set -e
+
+if [ "$1" = "remove" ]; then
+ systemctl stop system-kresd.slice || true
+fi
+
+#DEBHELPER#
diff --git a/distro/pkg/deb/knot-resolver.preinst b/distro/pkg/deb/knot-resolver.preinst
new file mode 100644
index 0000000..1f8f589
--- /dev/null
+++ b/distro/pkg/deb/knot-resolver.preinst
@@ -0,0 +1,26 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-3.0-or-later
+set -e
+
+# upgrade-4-to-5
+if [ -f /lib/systemd/system/kresd.socket ] ; then
+ export UPG_DIR=/var/lib/knot-resolver/.upgrade-4-to-5
+ mkdir -p ${UPG_DIR}
+ touch ${UPG_DIR}/.unfinished
+
+ for sock in kresd.socket kresd-tls.socket ; do
+ if systemctl is-enabled ${sock} 2>/dev/null | grep -qv masked ; then
+ systemctl show ${sock} -p Listen > ${UPG_DIR}/${sock}
+ case "$(systemctl show ${sock} -p BindIPv6Only)" in
+ *ipv6-only)
+ touch ${UPG_DIR}/${sock}.v6only
+ ;;
+ *default)
+ if cat /proc/sys/net/ipv6/bindv6only | grep -q 1 ; then
+ touch ${UPG_DIR}/${sock}.v6only
+ fi
+ ;;
+ esac
+ fi
+ done
+fi
diff --git a/distro/pkg/deb/knot-resolver.triggers b/distro/pkg/deb/knot-resolver.triggers
new file mode 100644
index 0000000..e8d8246
--- /dev/null
+++ b/distro/pkg/deb/knot-resolver.triggers
@@ -0,0 +1 @@
+interest-noawait /usr/share/dns/root.key
diff --git a/distro/pkg/deb/not-installed b/distro/pkg/deb/not-installed
new file mode 100644
index 0000000..f527e79
--- /dev/null
+++ b/distro/pkg/deb/not-installed
@@ -0,0 +1,7 @@
+usr/lib/knot-resolver/kres_modules/http/LICENSE
+usr/lib/knot-resolver/kres_modules/etcd.lua
+debian/tmp/usr/share/doc/knot-resolver/html/.buildinfo
+usr/include/libkres/*.h
+usr/lib/*.so
+usr/lib/pkgconfig/libkres.pc
+usr/lib/sysusers.d/knot-resolver.conf
diff --git a/distro/pkg/deb/rules b/distro/pkg/deb/rules
new file mode 100755
index 0000000..c577476
--- /dev/null
+++ b/distro/pkg/deb/rules
@@ -0,0 +1,51 @@
+#!/usr/bin/make -f
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# see FEATURE AREAS in dpkg-buildflags(1)
+export DEB_BUILD_MAINT_OPTIONS = hardening=+all,-pie
+
+# see ENVIRONMENT in dpkg-buildflags(1)
+# package maintainers to append CFLAGS
+export DEB_CFLAGS_MAINT_APPEND = -Wall -pedantic -fno-omit-frame-pointer
+# package maintainers to append LDFLAGS
+export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed
+
+# see EXAMPLES in dpkg-buildflags(1) and read /usr/share/dpkg/*
+DPKG_EXPORT_BUILDFLAGS = 1
+include /usr/share/dpkg/default.mk
+
+export ARCH=$(DEB_HOST_GNU_CPU)
+
+%:
+ dh $@
+
+override_dh_auto_build:
+ meson build_deb \
+ --buildtype=plain \
+ --prefix=/usr \
+ --libdir=lib \
+ -Ddoc=enabled \
+ -Dsystemd_files=enabled \
+ -Dclient=enabled \
+ -Ddnstap=enabled \
+ -Dkeyfile_default=/usr/share/dns/root.key \
+ -Droot_hints=/usr/share/dns/root.hints \
+ -Dinstall_kresd_conf=enabled \
+ -Dunit_tests=enabled \
+ -Dmalloc=jemalloc \
+ -Dc_args="$${CFLAGS}" \
+ -Dc_link_args="$${LDFLAGS}"
+ ninja -v -C build_deb
+ ninja -v -C build_deb doc
+
+override_dh_auto_install:
+ DESTDIR="${PWD}/debian/tmp" ninja -v -C build_deb install
+
+override_dh_auto_test:
+ meson test -C build_deb
+
+override_dh_missing:
+ dh_missing --fail-missing
+
+override_dh_strip:
+ dh_strip --dbg-package=knot-resolver-dbg
diff --git a/distro/pkg/deb/source/format b/distro/pkg/deb/source/format
new file mode 100644
index 0000000..163aaf8
--- /dev/null
+++ b/distro/pkg/deb/source/format
@@ -0,0 +1 @@
+3.0 (quilt)
diff --git a/distro/pkg/nix/default.nix b/distro/pkg/nix/default.nix
new file mode 100644
index 0000000..16c66d0
--- /dev/null
+++ b/distro/pkg/nix/default.nix
@@ -0,0 +1,126 @@
+{ lib, stdenv, fetchurl
+# native deps.
+, runCommand, pkg-config, meson, ninja, makeWrapper
+# build+runtime deps.
+, knot-dns, luajitPackages, libuv, gnutls, lmdb
+, jemalloc, systemd, libcap_ng, dns-root-data, nghttp2 # optionals, in principle
+# test-only deps.
+, cmocka, which, cacert
+, extraFeatures ? false /* catch-all if defaults aren't enough */
+}:
+let # un-indented, over the whole file
+
+result = if extraFeatures then wrapped-full else unwrapped;
+
+inherit (lib) optional optionals optionalString;
+lua = luajitPackages;
+
+unwrapped = stdenv.mkDerivation rec {
+ pname = "knot-resolver";
+ version = "{{ version }}";
+
+ src = fetchurl {
+ url = "https://secure.nic.cz/files/knot-resolver/${pname}-${version}.tar.xz";
+ sha256 = "{{ src_hash }}";
+ };
+
+ outputs = [ "out" "dev" ];
+
+ # Path fixups for the NixOS service.
+ postPatch = ''
+ patch meson.build <<EOF
+ @@ -50,2 +50,2 @@
+ -systemd_work_dir = prefix / get_option('localstatedir') / 'lib' / 'knot-resolver'
+ -systemd_cache_dir = prefix / get_option('localstatedir') / 'cache' / 'knot-resolver'
+ +systemd_work_dir = '/var/lib/knot-resolver'
+ +systemd_cache_dir = '/var/cache/knot-resolver'
+ EOF
+
+ # ExecStart can't be overwritten in overrides.
+ # We need that to use wrapped executable and correct config file.
+ sed '/^ExecStart=/d' -i systemd/kresd@.service.in
+ ''
+ # some tests have issues with network sandboxing, apparently
+ + optionalString doInstallCheck ''
+ echo 'os.exit(77)' > daemon/lua/trust_anchors.test/bootstrap.test.lua
+ sed -E '/^[[:blank:]]*test_(dstaddr|headers),?$/d' -i \
+ tests/config/doh2.test.lua modules/http/http_doh.test.lua
+ '';
+
+ preConfigure = ''
+ patchShebangs scripts/
+ '';
+
+ nativeBuildInputs = [ pkg-config meson ninja ];
+
+ # http://knot-resolver.readthedocs.io/en/latest/build.html#requirements
+ buildInputs = [ knot-dns lua.lua libuv gnutls lmdb ]
+ ++ optionals stdenv.isLinux [ systemd libcap_ng ]
+ ++ [ jemalloc nghttp2 ]
+ ## optional dependencies; TODO: dnstap
+ ;
+
+ mesonFlags = [
+ "-Dkeyfile_default=${dns-root-data}/root.ds"
+ "-Droot_hints=${dns-root-data}/root.hints"
+ "-Dinstall_kresd_conf=disabled" # not really useful; examples are inside share/doc/
+ "-Dmalloc=jemalloc"
+ "--default-library=static" # not used by anyone
+ ]
+ ++ optional doInstallCheck "-Dunit_tests=enabled"
+ ++ optional (doInstallCheck && !stdenv.isDarwin) "-Dconfig_tests=enabled"
+ ++ optional stdenv.isLinux "-Dsystemd_files=enabled" # used by NixOS service
+ #"-Dextra_tests=enabled" # not suitable as in-distro tests; many deps, too.
+ ;
+
+ postInstall = ''
+ rm "$out"/lib/libkres.a
+ rm "$out"/lib/knot-resolver/upgrade-4-to-5.lua # not meaningful on NixOS
+ '' + optionalString stdenv.targetPlatform.isLinux ''
+ rm -r "$out"/lib/sysusers.d/ # ATM more likely to harm than help
+ '';
+
+ doInstallCheck = with stdenv; hostPlatform == buildPlatform
+ && !(isDarwin && isAarch64); # avoid luarocks, as it's broken ATM on the platform
+ installCheckInputs = [ cmocka which cacert lua.cqueues lua.basexx lua.http ];
+ installCheckPhase = ''
+ meson test --print-errorlogs
+ '';
+
+ meta = with lib; {
+ description = "Caching validating DNS resolver, from .cz domain registry";
+ homepage = "https://knot-resolver.cz";
+ license = licenses.gpl3Plus;
+ platforms = platforms.unix;
+ maintainers = [ maintainers.vcunat /* upstream developer */ ];
+ };
+};
+
+wrapped-full = runCommand unwrapped.name
+ {
+ nativeBuildInputs = [ makeWrapper ];
+ buildInputs = with luajitPackages; [
+ # For http module, prefill module, trust anchor bootstrap.
+ # It brings lots of deps; some are useful elsewhere (e.g. cqueues).
+ http
+ # psl isn't in nixpkgs yet, but policy.slice_randomize_psl() seems not important.
+ ];
+ preferLocalBuild = true;
+ allowSubstitutes = false;
+ }
+ ''
+ mkdir -p "$out"/bin
+ makeWrapper '${unwrapped}/bin/kresd' "$out"/bin/kresd \
+ --set LUA_PATH "$LUA_PATH" \
+ --set LUA_CPATH "$LUA_CPATH"
+
+ ln -sr '${unwrapped}/share' "$out"/
+ ln -sr '${unwrapped}/lib' "$out"/ # useful in NixOS service
+ ln -sr "$out"/{bin,sbin}
+
+ echo "Checking that 'http' module loads, i.e. lua search paths work:"
+ echo "modules.load('http')" > test-http.lua
+ echo -e 'quit()' | env -i "$out"/bin/kresd -a 127.0.0.1#53535 -c test-http.lua
+ '';
+
+in result
diff --git a/distro/pkg/nix/top-level.nix b/distro/pkg/nix/top-level.nix
new file mode 100644
index 0000000..bdd3360
--- /dev/null
+++ b/distro/pkg/nix/top-level.nix
@@ -0,0 +1,12 @@
+with import <nixpkgs> {};
+
+(callPackage ./. {
+}).overrideAttrs (attrs: {
+ src = ./knot-resolver-{{ version }}.tar.xz;
+
+ # This just breaks in our GitLab CI (not locally and not on hydra.nixos.org)
+ installCheckPhase = ''
+ meson test --print-errorlogs --no-suite snowflake
+ '';
+})
+
diff --git a/distro/pkg/rpm/knot-resolver.spec b/distro/pkg/rpm/knot-resolver.spec
new file mode 100644
index 0000000..0a7e283
--- /dev/null
+++ b/distro/pkg/rpm/knot-resolver.spec
@@ -0,0 +1,384 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+%global _hardened_build 1
+%{!?_pkgdocdir: %global _pkgdocdir %{_docdir}/%{name}}
+
+%define GPG_CHECK 0
+%define repodir %{_builddir}/%{name}-%{version}
+%define NINJA ninja-build
+
+Name: knot-resolver
+Version: {{ version }}
+Release: cznic.{{ release }}%{?dist}
+Summary: Caching full DNS Resolver
+
+License: GPL-3.0-or-later
+URL: https://www.knot-resolver.cz/
+Source0: knot-resolver-%{version}.tar.xz
+
+# LuaJIT only on these arches
+%if 0%{?rhel} == 7
+# RHEL 7 does not have aarch64 LuaJIT
+ExclusiveArch: %{ix86} x86_64
+%else
+ExclusiveArch: %{arm} aarch64 %{ix86} x86_64
+%endif
+
+%if 0%{GPG_CHECK}
+Source1: knot-resolver-%{version}.tar.xz.asc
+# PGP keys used to sign upstream releases
+# Export with --armor using command from https://fedoraproject.org/wiki/PackagingDrafts:GPGSignatures
+# Don't forget to update %%prep section when adding/removing keys
+# This key is from: https://secure.nic.cz/files/knot-resolver/kresd-keyblock.asc
+Source100: kresd-keyblock.asc
+BuildRequires: gnupg2
+%endif
+
+BuildRequires: gcc
+BuildRequires: gcc-c++
+BuildRequires: meson
+BuildRequires: pkgconfig(cmocka)
+BuildRequires: pkgconfig(gnutls)
+BuildRequires: pkgconfig(libedit)
+BuildRequires: pkgconfig(libknot) >= 3.0.2
+BuildRequires: pkgconfig(libzscanner) >= 3.0.2
+BuildRequires: pkgconfig(libdnssec) >= 3.0.2
+BuildRequires: pkgconfig(libnghttp2)
+BuildRequires: pkgconfig(libsystemd)
+BuildRequires: pkgconfig(libcap-ng)
+BuildRequires: pkgconfig(libuv)
+BuildRequires: pkgconfig(luajit) >= 2.0
+BuildRequires: jemalloc-devel
+
+Requires: systemd
+Requires(post): systemd
+
+# dnstap module dependencies
+# SUSE is missing protoc-c protobuf compiler
+%if "x%{?suse_version}" == "x"
+BuildRequires: pkgconfig(libfstrm)
+BuildRequires: pkgconfig(libprotobuf-c)
+%endif
+
+# Distro-dependent dependencies
+%if 0%{?rhel} == 7
+BuildRequires: lmdb-devel
+# Lua 5.1 version of the libraries have different package names
+Requires: lua-basexx
+Requires: lua-psl
+Requires: lua-http
+Requires(pre): shadow-utils
+%endif
+%if 0%{?fedora} || 0%{?rhel} > 7
+BuildRequires: pkgconfig(lmdb)
+BuildRequires: python3-sphinx
+Requires: lua5.1-basexx
+Requires: lua5.1-cqueues
+Requires: lua5.1-http
+Recommends: lua5.1-psl
+Requires(pre): shadow-utils
+%endif
+
+# we do not build HTTP module on SuSE so the build requires is not needed
+%if "x%{?suse_version}" == "x"
+BuildRequires: openssl-devel
+%endif
+
+%if 0%{?suse_version}
+%define NINJA ninja
+BuildRequires: lmdb-devel
+BuildRequires: python3-Sphinx
+Requires(pre): shadow
+%endif
+
+%if "x%{?rhel}" == "x"
+# dependencies for doc package
+# NOTE: doc isn't possible to build on CentOS 7, 8
+# python2-sphinx is too old and python36-breathe is broken on CentOS 7
+# python3-breathe isn't available for CentOS 8 (yet? rhbz#1808766)
+BuildRequires: doxygen
+BuildRequires: python3-breathe
+BuildRequires: python3-sphinx_rtd_theme
+BuildRequires: texinfo
+%endif
+
+%description
+The Knot Resolver is a DNSSEC-enabled caching full resolver implementation
+written in C and LuaJIT, including both a resolver library and a daemon.
+Modular architecture of the library keeps the core tiny and efficient, and
+provides a state-machine like API for extensions.
+
+The package is pre-configured as local caching resolver.
+To start using it, start a single kresd instance:
+$ systemctl start kresd@1.service
+
+%package devel
+Summary: Development headers for Knot Resolver
+Requires: %{name}%{?_isa} = %{version}-%{release}
+
+%description devel
+The package contains development headers for Knot Resolver.
+
+%if "x%{?rhel}" == "x"
+%package doc
+Summary: Documentation for Knot Resolver
+BuildArch: noarch
+Requires: %{name} = %{version}-%{release}
+
+%description doc
+Documentation for Knot Resolver
+%endif
+
+%if "x%{?suse_version}" == "x"
+%package module-dnstap
+Summary: dnstap module for Knot Resolver
+Requires: %{name} = %{version}-%{release}
+
+%description module-dnstap
+dnstap module for Knot Resolver supports logging DNS responses to a unix socket
+in dnstap format using fstrm framing library. This logging is useful if you
+need effectively log all DNS traffic.
+%endif
+
+%if "x%{?suse_version}" == "x"
+%package module-http
+Summary: HTTP module for Knot Resolver
+Requires: %{name} = %{version}-%{release}
+%if 0%{?fedora} || 0%{?rhel} > 7
+Requires: lua5.1-http
+Requires: lua5.1-mmdb
+%else
+Requires: lua-http
+Requires: lua-mmdb
+%endif
+
+%description module-http
+HTTP module for Knot Resolver can serve as API endpoint for other modules or
+provide a web interface for local visualization of the resolver cache and
+queries. It can also serve DNS-over-HTTPS, but it is deprecated in favor of
+native C implementation, which doesn't require this package.
+%endif
+
+%prep
+%if 0%{GPG_CHECK}
+export GNUPGHOME=./gpg-keyring
+mkdir -m 700 ${GNUPGHOME}
+gpg2 --import %{SOURCE100}
+gpg2 --verify %{SOURCE1} %{SOURCE0}
+%endif
+%setup -q -n %{name}-%{version}
+
+%build
+CFLAGS="%{optflags}" LDFLAGS="%{?__global_ldflags}" meson build_rpm \
+%if "x%{?rhel}" == "x"
+ -Ddoc=enabled \
+%endif
+ -Dsystemd_files=enabled \
+ -Dclient=enabled \
+%if "x%{?suse_version}" == "x"
+ -Ddnstap=enabled \
+%endif
+ -Dunit_tests=enabled \
+ -Dmanaged_ta=enabled \
+ -Dkeyfile_default="%{_sharedstatedir}/knot-resolver/root.keys" \
+ -Dinstall_root_keys=enabled \
+ -Dinstall_kresd_conf=enabled \
+ -Dmalloc=jemalloc \
+ --buildtype=plain \
+ --prefix="%{_prefix}" \
+ --sbindir="%{_sbindir}" \
+ --libdir="%{_libdir}" \
+ --includedir="%{_includedir}" \
+ --sysconfdir="%{_sysconfdir}" \
+
+%{NINJA} -v -C build_rpm
+%if "x%{?rhel}" == "x"
+%{NINJA} -v -C build_rpm doc
+%endif
+
+%check
+meson test -C build_rpm
+
+%install
+DESTDIR="${RPM_BUILD_ROOT}" %{NINJA} -v -C build_rpm install
+
+# add kresd.target to multi-user.target.wants to support enabling kresd services
+install -m 0755 -d %{buildroot}%{_unitdir}/multi-user.target.wants
+ln -s ../kresd.target %{buildroot}%{_unitdir}/multi-user.target.wants/kresd.target
+
+# remove modules with missing dependencies
+rm %{buildroot}%{_libdir}/knot-resolver/kres_modules/etcd.lua
+
+# remove unused sysusers
+rm %{buildroot}%{_prefix}/lib/sysusers.d/knot-resolver.conf
+
+%if 0%{?suse_version}
+rm %{buildroot}%{_libdir}/knot-resolver/kres_modules/experimental_dot_auth.lua
+rm -r %{buildroot}%{_libdir}/knot-resolver/kres_modules/http
+rm %{buildroot}%{_libdir}/knot-resolver/kres_modules/http*.lua
+rm %{buildroot}%{_libdir}/knot-resolver/kres_modules/prometheus.lua
+%endif
+
+# rename doc directory for centos 7, opensuse
+%if 0%{?suse_version} || 0%{?rhel} == 7
+install -m 755 -d %{buildroot}/%{_pkgdocdir}
+mv %{buildroot}/%{_datadir}/doc/%{name}/* %{buildroot}/%{_pkgdocdir}/
+%endif
+
+%pre
+getent group knot-resolver >/dev/null || groupadd -r knot-resolver
+getent passwd knot-resolver >/dev/null || useradd -r -g knot-resolver -d %{_sysconfdir}/knot-resolver -s /sbin/nologin -c "Knot Resolver" knot-resolver
+
+%if "x%{?rhel}" == "x"
+# upgrade-4-to-5
+if [ -f %{_unitdir}/kresd.socket ] ; then
+ export UPG_DIR=%{_sharedstatedir}/knot-resolver/.upgrade-4-to-5
+ mkdir -p ${UPG_DIR}
+ touch ${UPG_DIR}/.unfinished
+
+ for sock in kresd.socket kresd-tls.socket kresd-webmgmt.socket kresd-doh.socket ; do
+ if systemctl is-enabled ${sock} 2>/dev/null | grep -qv masked ; then
+ systemctl show ${sock} -p Listen > ${UPG_DIR}/${sock}
+ case "$(systemctl show ${sock} -p BindIPv6Only)" in
+ *ipv6-only)
+ touch ${UPG_DIR}/${sock}.v6only
+ ;;
+ *default)
+ if cat /proc/sys/net/ipv6/bindv6only | grep -q 1 ; then
+ touch ${UPG_DIR}/${sock}.v6only
+ fi
+ ;;
+ esac
+ fi
+ done
+fi
+%endif
+
+
+%post
+# upgrade-4-to-5
+%if "x%{?rhel}" == "x"
+export UPG_DIR=%{_sharedstatedir}/knot-resolver/.upgrade-4-to-5
+if [ -f ${UPG_DIR}/.unfinished ] ; then
+ rm -f ${UPG_DIR}/.unfinished
+ kresd -c %{_libdir}/knot-resolver/upgrade-4-to-5.lua &>/dev/null
+ echo -e "\n !!! WARNING !!!"
+ echo -e "Knot Resolver configuration file requires manual upgrade.\n"
+ cat ${UPG_DIR}/kresd.conf.net 2>/dev/null
+fi
+%endif
+
+# 5.0.1 fix to force restart of kres-cache-gc.service, which was missing in systemd_postun_with_restart
+# TODO: remove once most users upgrade to 5.0.1+
+systemctl daemon-reload >/dev/null 2>&1 || :
+if [ $1 -ge 2 ] ; then
+ systemctl try-restart kres-cache-gc.service >/dev/null 2>&1 || :
+fi
+
+# systemd_post macro is not needed for anything (calls systemctl preset)
+%tmpfiles_create %{_tmpfilesdir}/knot-resolver.conf
+%if "x%{?fedora}" == "x"
+/sbin/ldconfig
+%endif
+
+%preun
+%systemd_preun kres-cache-gc.service kresd.target
+
+%postun
+%systemd_postun_with_restart 'kresd@*.service' kres-cache-gc.service
+%if "x%{?fedora}" == "x"
+/sbin/ldconfig
+%endif
+
+%files
+%dir %{_pkgdocdir}
+%license %{_pkgdocdir}/COPYING
+%doc %{_pkgdocdir}/AUTHORS
+%doc %{_pkgdocdir}/NEWS
+%doc %{_pkgdocdir}/examples
+%dir %{_sysconfdir}/knot-resolver
+%config(noreplace) %{_sysconfdir}/knot-resolver/kresd.conf
+%config(noreplace) %{_sysconfdir}/knot-resolver/root.hints
+%{_sysconfdir}/knot-resolver/icann-ca.pem
+%attr(750,knot-resolver,knot-resolver) %dir %{_sharedstatedir}/knot-resolver
+%attr(640,knot-resolver,knot-resolver) %{_sharedstatedir}/knot-resolver/root.keys
+%{_unitdir}/kresd@.service
+%{_unitdir}/kres-cache-gc.service
+%{_unitdir}/kresd.target
+%dir %{_unitdir}/multi-user.target.wants
+%{_unitdir}/multi-user.target.wants/kresd.target
+%{_mandir}/man7/kresd.systemd.7.gz
+%{_tmpfilesdir}/knot-resolver.conf
+%ghost /run/%{name}
+%ghost %{_localstatedir}/cache/%{name}
+%attr(750,knot-resolver,knot-resolver) %dir %{_libdir}/%{name}
+%{_sbindir}/kresd
+%{_sbindir}/kresc
+%{_sbindir}/kres-cache-gc
+%{_libdir}/libkres.so.*
+%dir %{_libdir}/knot-resolver
+%{_libdir}/knot-resolver/*.so
+%{_libdir}/knot-resolver/*.lua
+%dir %{_libdir}/knot-resolver/kres_modules
+%{_libdir}/knot-resolver/kres_modules/bogus_log.so
+%{_libdir}/knot-resolver/kres_modules/edns_keepalive.so
+%{_libdir}/knot-resolver/kres_modules/extended_error.so
+%{_libdir}/knot-resolver/kres_modules/hints.so
+%{_libdir}/knot-resolver/kres_modules/nsid.so
+%{_libdir}/knot-resolver/kres_modules/refuse_nord.so
+%{_libdir}/knot-resolver/kres_modules/stats.so
+%{_libdir}/knot-resolver/kres_modules/daf
+%{_libdir}/knot-resolver/kres_modules/daf.lua
+%{_libdir}/knot-resolver/kres_modules/detect_time_jump.lua
+%{_libdir}/knot-resolver/kres_modules/detect_time_skew.lua
+%{_libdir}/knot-resolver/kres_modules/dns64.lua
+%if "x%{?suse_version}" == "x"
+%{_libdir}/knot-resolver/kres_modules/experimental_dot_auth.lua
+%endif
+%{_libdir}/knot-resolver/kres_modules/graphite.lua
+%{_libdir}/knot-resolver/kres_modules/policy.lua
+%{_libdir}/knot-resolver/kres_modules/predict.lua
+%{_libdir}/knot-resolver/kres_modules/prefill.lua
+%{_libdir}/knot-resolver/kres_modules/priming.lua
+%{_libdir}/knot-resolver/kres_modules/rebinding.lua
+%{_libdir}/knot-resolver/kres_modules/renumber.lua
+%{_libdir}/knot-resolver/kres_modules/serve_stale.lua
+%{_libdir}/knot-resolver/kres_modules/ta_sentinel.lua
+%{_libdir}/knot-resolver/kres_modules/ta_signal_query.lua
+%{_libdir}/knot-resolver/kres_modules/ta_update.lua
+%{_libdir}/knot-resolver/kres_modules/view.lua
+%{_libdir}/knot-resolver/kres_modules/watchdog.lua
+%{_libdir}/knot-resolver/kres_modules/workarounds.lua
+%{_mandir}/man8/kresd.8.gz
+
+%files devel
+%{_includedir}/libkres
+%{_libdir}/pkgconfig/libkres.pc
+%{_libdir}/libkres.so
+
+%if "x%{?rhel}" == "x"
+%files doc
+%dir %{_pkgdocdir}
+%doc %{_pkgdocdir}/html
+%doc %{_datadir}/info/knot-resolver.info*
+%dir %{_datadir}/info/knot-resolver-figures
+%doc %{_datadir}/info/knot-resolver-figures/*
+%endif
+
+%if "x%{?suse_version}" == "x"
+%files module-dnstap
+%{_libdir}/knot-resolver/kres_modules/dnstap.so
+%endif
+
+%if "x%{?suse_version}" == "x"
+%files module-http
+%{_libdir}/knot-resolver/debug_opensslkeylog.so
+%{_libdir}/knot-resolver/kres_modules/http
+%{_libdir}/knot-resolver/kres_modules/http*.lua
+%{_libdir}/knot-resolver/kres_modules/prometheus.lua
+%endif
+
+%changelog
+* {{ now }} Jakub RužiÄka <jakub.ruzicka@nic.cz> - {{ version }}-{{ release }}
+- upstream package
+- see NEWS or https://www.knot-resolver.cz/
diff --git a/distro/tests/.ansible.cfg b/distro/tests/.ansible.cfg
new file mode 100644
index 0000000..eef2015
--- /dev/null
+++ b/distro/tests/.ansible.cfg
@@ -0,0 +1,8 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+[defaults]
+
+# additional paths to search for roles in, colon separated
+roles_path = ../ansible-roles
+interpreter_python = auto
+stdout_callback=debug
diff --git a/distro/tests/README.md b/distro/tests/README.md
new file mode 100644
index 0000000..a1a5e96
--- /dev/null
+++ b/distro/tests/README.md
@@ -0,0 +1,42 @@
+Requirements
+------------
+
+- ansible
+- vagrant
+- libvirt (+vagrant-libvirt) / virtualbox
+
+Usage
+-----
+
+`vagrant up` command is configured to trigger ansible provisioning
+which configures OBS repository, installs the knot-resolver package,
+starts the kresd@1 service and finally attempts to use it to resolve
+a domain name. It also tests that DNSSEC validation is turned on.
+
+By default, the *knot-resolver-devel* repo (for knot-resolver) along
+with *knot-resolver-latest* (for knot) is used. To test only the
+*knot-resolver-latest* repo, set it in `repos.yaml` (or use the
+test-distro.sh script which overwrites this file). If you're running
+tests in parallel, they all HAVE TO use the same repo(s).
+
+Run the following command for every distro (aka directory with
+Vagrantfile):
+
+```
+./test-distro.sh knot-resolver-devel debian9
+```
+
+or
+
+```
+./test-distro.sh knot-resolver-testing debian9
+```
+
+or
+
+```
+./test-distro.sh knot-resolver-latest debian9
+```
+
+At the end of the test, the package version that was tested is
+printed out. Make sure you're testing what you intended to.
diff --git a/distro/tests/ansible-roles/knot_resolver/defaults/main.yaml b/distro/tests/ansible-roles/knot_resolver/defaults/main.yaml
new file mode 100644
index 0000000..0860c26
--- /dev/null
+++ b/distro/tests/ansible-roles/knot_resolver/defaults/main.yaml
@@ -0,0 +1,6 @@
+---
+# SPDX-License-Identifier: GPL-3.0-or-later
+repos:
+ - knot-resolver-latest
+distro: "{{ ansible_distribution | replace(' ', '_') }}"
+update_packages: false
diff --git a/distro/tests/ansible-roles/knot_resolver/tasks/configure_dnstap.yaml b/distro/tests/ansible-roles/knot_resolver/tasks/configure_dnstap.yaml
new file mode 100644
index 0000000..817b117
--- /dev/null
+++ b/distro/tests/ansible-roles/knot_resolver/tasks/configure_dnstap.yaml
@@ -0,0 +1,10 @@
+---
+# SPDX-License-Identifier: GPL-3.0-or-later
+- name: dnstap_config set up kresd.conf
+ blockinfile:
+ marker: -- {mark} ANSIBLE MANAGED BLOCK
+ block: |
+ modules.load('dnstap')
+ assert(dnstap)
+ path: /etc/knot-resolver/kresd.conf
+ insertbefore: BOF
diff --git a/distro/tests/ansible-roles/knot_resolver/tasks/configure_doh.yaml b/distro/tests/ansible-roles/knot_resolver/tasks/configure_doh.yaml
new file mode 100644
index 0000000..cd4e749
--- /dev/null
+++ b/distro/tests/ansible-roles/knot_resolver/tasks/configure_doh.yaml
@@ -0,0 +1,10 @@
+---
+# SPDX-License-Identifier: GPL-3.0-or-later
+- name: doh_config set up kresd.conf
+ blockinfile:
+ marker: -- {mark} ANSIBLE MANAGED BLOCK
+ block: |
+ net.listen('127.0.0.1', 44353, { kind = 'doh_legacy' })
+ modules.load('http')
+ path: /etc/knot-resolver/kresd.conf
+ insertbefore: BOF
diff --git a/distro/tests/ansible-roles/knot_resolver/tasks/configure_doh2.yaml b/distro/tests/ansible-roles/knot_resolver/tasks/configure_doh2.yaml
new file mode 100644
index 0000000..eebca20
--- /dev/null
+++ b/distro/tests/ansible-roles/knot_resolver/tasks/configure_doh2.yaml
@@ -0,0 +1,8 @@
+---
+# SPDX-License-Identifier: GPL-3.0-or-later
+- name: doh2_config set up kresd.conf
+ blockinfile:
+ marker: -- {mark} ANSIBLE MANAGED BLOCK
+ block: |
+ net.listen('127.0.0.1', 44354, { kind = 'doh2' })
+ path: /etc/knot-resolver/kresd.conf
diff --git a/distro/tests/ansible-roles/knot_resolver/tasks/main.yaml b/distro/tests/ansible-roles/knot_resolver/tasks/main.yaml
new file mode 100644
index 0000000..8d683c8
--- /dev/null
+++ b/distro/tests/ansible-roles/knot_resolver/tasks/main.yaml
@@ -0,0 +1,71 @@
+---
+# SPDX-License-Identifier: GPL-3.0-or-later
+- name: Include distribution specific vars
+ include_vars: "{{ distro }}.yaml"
+
+- name: Update all packages
+ package:
+ name: '*'
+ state: latest
+ when: update_packages|bool
+
+- name: Install packages
+ package:
+ name: "{{ packages }}"
+ state: latest
+ # knot-utils may be missing on opensuse (depending on upstream vs downstream pkg)
+ failed_when: false
+
+- name: Always print package version at the end
+ block:
+
+ - include: restart_kresd.yaml
+
+ - include: test_udp.yaml
+ - include: test_tcp.yaml
+ - include: test_tls.yaml
+ - include: test_dnssec.yaml
+
+ - include: test_kres_cache_gc.yaml
+
+ - name: Test DoH (new implementation)
+ block:
+ - include: configure_doh2.yaml
+ - include: restart_kresd.yaml
+ - include: test_doh2.yaml
+
+ - name: Test DoH (legacy)
+ block:
+ - name: Install knot-resolver-module-http
+ package:
+ name: knot-resolver-module-http
+ state: latest
+
+ - include: configure_doh.yaml
+ when: ansible_distribution in ["CentOS", "Rocky", "Fedora", "Debian", "Ubuntu"]
+
+ - include: restart_kresd.yaml
+ - include: test_doh.yaml
+ when: distro in ["Fedora", "Debian", "CentOS", "Rocky"] or (distro == "Ubuntu" and ansible_distribution_major_version|int >= 18)
+
+ - name: Test dnstap module
+ block:
+ - name: Install knot-resolver-module-dnstap
+ package:
+ name: knot-resolver-module-dnstap
+ state: latest
+ - include: configure_dnstap.yaml
+ - include: restart_kresd.yaml
+ when: distro in ["Fedora", "Debian", "CentOS", "Rocky", "Ubuntu"]
+
+ always:
+
+ - name: Get installed package version
+ shell: "{{ show_package_version }}"
+ args:
+ warn: false
+ register: package_version
+
+ - name: Show installed version
+ debug:
+ var: package_version.stdout
diff --git a/distro/tests/ansible-roles/knot_resolver/tasks/restart_kresd.yaml b/distro/tests/ansible-roles/knot_resolver/tasks/restart_kresd.yaml
new file mode 100644
index 0000000..00dbf5d
--- /dev/null
+++ b/distro/tests/ansible-roles/knot_resolver/tasks/restart_kresd.yaml
@@ -0,0 +1,16 @@
+---
+# SPDX-License-Identifier: GPL-3.0-or-later
+- block:
+ - name: Restart kresd@1.service
+ service:
+ name: kresd@1.service
+ state: restarted
+ rescue:
+ - name: Get kresd@1.service journal
+ shell: journalctl -u kresd@1 --since -20s
+ register: journal
+ - name: Print journal
+ debug:
+ var: journal
+ - name: Restart kresd@*.service failed, see log above
+ shell: /bin/false
diff --git a/distro/tests/ansible-roles/knot_resolver/tasks/test_dnssec.yaml b/distro/tests/ansible-roles/knot_resolver/tasks/test_dnssec.yaml
new file mode 100644
index 0000000..1cc6ea3
--- /dev/null
+++ b/distro/tests/ansible-roles/knot_resolver/tasks/test_dnssec.yaml
@@ -0,0 +1,15 @@
+---
+# SPDX-License-Identifier: GPL-3.0-or-later
+- name: dnssec_test rhybar.cz. +cd returns NOERROR
+ tags:
+ - test
+ shell: kdig +cd @127.0.0.1 rhybar.cz.
+ register: res
+ failed_when: '"status: NOERROR" not in res.stdout'
+
+- name: dnssec_test rhybar.cz. returns SERVFAIL
+ tags:
+ - test
+ shell: kdig +timeout=16 @127.0.0.1 rhybar.cz.
+ register: res
+ failed_when: '"status: SERVFAIL" not in res.stdout'
diff --git a/distro/tests/ansible-roles/knot_resolver/tasks/test_doh.yaml b/distro/tests/ansible-roles/knot_resolver/tasks/test_doh.yaml
new file mode 100644
index 0000000..2c200e1
--- /dev/null
+++ b/distro/tests/ansible-roles/knot_resolver/tasks/test_doh.yaml
@@ -0,0 +1,9 @@
+---
+# SPDX-License-Identifier: GPL-3.0-or-later
+- name: doh_test query localhost. A
+ get_url:
+ url: https://127.0.0.1:44353/doh?dns=1Y0BAAABAAAAAAAACWxvY2FsaG9zdAAAAQAB
+ sha256sum: e5c2710e6ecb78c089ab608ad5861b87be0d1c623c4d58b4eee3b21c06aa2008
+ dest: /tmp/doh_test
+ mode: 0644
+ validate_certs: false
diff --git a/distro/tests/ansible-roles/knot_resolver/tasks/test_doh2.yaml b/distro/tests/ansible-roles/knot_resolver/tasks/test_doh2.yaml
new file mode 100644
index 0000000..32cf295
--- /dev/null
+++ b/distro/tests/ansible-roles/knot_resolver/tasks/test_doh2.yaml
@@ -0,0 +1,24 @@
+---
+# SPDX-License-Identifier: GPL-3.0-or-later
+- name: doh2_test check kdig https support
+ shell: kdig --help | grep -q '+\S*https'
+ register: kdig_https
+ ignore_errors: true
+
+- name: doh2_test query localhost. A
+ # use curl instead of ansible builtins (get_url/uri)
+ # because they currently use unsupported HTTP/1.1
+ shell: |
+ curl -k -o /tmp/doh_test https://127.0.0.1:44354/doh?dns=1Y0BAAABAAAAAAAACWxvY2FsaG9zdAAAAQAB
+ echo "e5c2710e6ecb78c089ab608ad5861b87be0d1c623c4d58b4eee3b21c06aa2008 /tmp/doh_test" > /tmp/doh_test.sha256
+ sha256sum --check /tmp/doh_test.sha256
+ args:
+ # disable warning about using curl - we know what we're doing
+ warn: false
+ when: kdig_https is failed
+
+- name: doh2_test kdig localhost. A
+ shell: |
+ kdig @127.0.0.1 -p 44354 +https nic.cz || exit 1
+ kdig @127.0.0.1 -p 44354 +https-get nic.cz || exit 2
+ when: kdig_https is succeeded
diff --git a/distro/tests/ansible-roles/knot_resolver/tasks/test_kres_cache_gc.yaml b/distro/tests/ansible-roles/knot_resolver/tasks/test_kres_cache_gc.yaml
new file mode 100644
index 0000000..3a7c9c9
--- /dev/null
+++ b/distro/tests/ansible-roles/knot_resolver/tasks/test_kres_cache_gc.yaml
@@ -0,0 +1,4 @@
+---
+# SPDX-License-Identifier: GPL-3.0-or-later
+- name: check kres-cache-gc.service is active
+ shell: systemctl is-active -q kres-cache-gc.service
diff --git a/distro/tests/ansible-roles/knot_resolver/tasks/test_tcp.yaml b/distro/tests/ansible-roles/knot_resolver/tasks/test_tcp.yaml
new file mode 100644
index 0000000..1af18fd
--- /dev/null
+++ b/distro/tests/ansible-roles/knot_resolver/tasks/test_tcp.yaml
@@ -0,0 +1,8 @@
+---
+# SPDX-License-Identifier: GPL-3.0-or-later
+- name: tcp_test resolve nic.cz
+ tags:
+ - test
+ shell: kdig +tcp @127.0.0.1 nic.cz
+ register: res
+ failed_when: '"status: NOERROR" not in res.stdout'
diff --git a/distro/tests/ansible-roles/knot_resolver/tasks/test_tls.yaml b/distro/tests/ansible-roles/knot_resolver/tasks/test_tls.yaml
new file mode 100644
index 0000000..c780657
--- /dev/null
+++ b/distro/tests/ansible-roles/knot_resolver/tasks/test_tls.yaml
@@ -0,0 +1,8 @@
+---
+# SPDX-License-Identifier: GPL-3.0-or-later
+- name: tls_test resolve nic.cz
+ tags:
+ - test
+ shell: kdig +tls @127.0.0.1 nic.cz
+ register: res
+ failed_when: '"status: NOERROR" not in res.stdout'
diff --git a/distro/tests/ansible-roles/knot_resolver/tasks/test_udp.yaml b/distro/tests/ansible-roles/knot_resolver/tasks/test_udp.yaml
new file mode 100644
index 0000000..64023ff
--- /dev/null
+++ b/distro/tests/ansible-roles/knot_resolver/tasks/test_udp.yaml
@@ -0,0 +1,8 @@
+---
+# SPDX-License-Identifier: GPL-3.0-or-later
+- name: udp_test resolve nic.cz
+ tags:
+ - test
+ shell: kdig @127.0.0.1 nic.cz
+ register: res
+ failed_when: '"status: NOERROR" not in res.stdout'
diff --git a/distro/tests/ansible-roles/knot_resolver/vars/CentOS.yaml b/distro/tests/ansible-roles/knot_resolver/vars/CentOS.yaml
new file mode 100644
index 0000000..d69cb13
--- /dev/null
+++ b/distro/tests/ansible-roles/knot_resolver/vars/CentOS.yaml
@@ -0,0 +1,6 @@
+---
+# SPDX-License-Identifier: GPL-3.0-or-later
+show_package_version: rpm -qi knot-resolver | grep '^Version'
+packages:
+ - knot-resolver
+ - knot-utils
diff --git a/distro/tests/ansible-roles/knot_resolver/vars/Debian.yaml b/distro/tests/ansible-roles/knot_resolver/vars/Debian.yaml
new file mode 100644
index 0000000..bcdc37a
--- /dev/null
+++ b/distro/tests/ansible-roles/knot_resolver/vars/Debian.yaml
@@ -0,0 +1,6 @@
+---
+# SPDX-License-Identifier: GPL-3.0-or-later
+show_package_version: dpkg -s knot-resolver | grep '^Version'
+packages:
+ - knot-resolver
+ - knot-dnsutils
diff --git a/distro/tests/ansible-roles/knot_resolver/vars/Fedora.yaml b/distro/tests/ansible-roles/knot_resolver/vars/Fedora.yaml
new file mode 100644
index 0000000..d69cb13
--- /dev/null
+++ b/distro/tests/ansible-roles/knot_resolver/vars/Fedora.yaml
@@ -0,0 +1,6 @@
+---
+# SPDX-License-Identifier: GPL-3.0-or-later
+show_package_version: rpm -qi knot-resolver | grep '^Version'
+packages:
+ - knot-resolver
+ - knot-utils
diff --git a/distro/tests/ansible-roles/knot_resolver/vars/Rocky.yaml b/distro/tests/ansible-roles/knot_resolver/vars/Rocky.yaml
new file mode 100644
index 0000000..d69cb13
--- /dev/null
+++ b/distro/tests/ansible-roles/knot_resolver/vars/Rocky.yaml
@@ -0,0 +1,6 @@
+---
+# SPDX-License-Identifier: GPL-3.0-or-later
+show_package_version: rpm -qi knot-resolver | grep '^Version'
+packages:
+ - knot-resolver
+ - knot-utils
diff --git a/distro/tests/ansible-roles/knot_resolver/vars/Ubuntu.yaml b/distro/tests/ansible-roles/knot_resolver/vars/Ubuntu.yaml
new file mode 100644
index 0000000..bcdc37a
--- /dev/null
+++ b/distro/tests/ansible-roles/knot_resolver/vars/Ubuntu.yaml
@@ -0,0 +1,6 @@
+---
+# SPDX-License-Identifier: GPL-3.0-or-later
+show_package_version: dpkg -s knot-resolver | grep '^Version'
+packages:
+ - knot-resolver
+ - knot-dnsutils
diff --git a/distro/tests/ansible-roles/knot_resolver/vars/openSUSE_Leap.yaml b/distro/tests/ansible-roles/knot_resolver/vars/openSUSE_Leap.yaml
new file mode 100644
index 0000000..d69cb13
--- /dev/null
+++ b/distro/tests/ansible-roles/knot_resolver/vars/openSUSE_Leap.yaml
@@ -0,0 +1,6 @@
+---
+# SPDX-License-Identifier: GPL-3.0-or-later
+show_package_version: rpm -qi knot-resolver | grep '^Version'
+packages:
+ - knot-resolver
+ - knot-utils
diff --git a/distro/tests/ansible-roles/knot_resolver/vars/openSUSE_Tumbleweed.yaml b/distro/tests/ansible-roles/knot_resolver/vars/openSUSE_Tumbleweed.yaml
new file mode 100644
index 0000000..39d5ef0
--- /dev/null
+++ b/distro/tests/ansible-roles/knot_resolver/vars/openSUSE_Tumbleweed.yaml
@@ -0,0 +1,7 @@
+---
+# SPDX-License-Identifier: GPL-3.0-or-later
+show_package_version: rpm -qi knot-resolver | grep '^Version'
+update_packages: true
+packages:
+ - knot-resolver
+ - knot-utils
diff --git a/distro/tests/ansible-roles/obs_repos/defaults/main.yaml b/distro/tests/ansible-roles/obs_repos/defaults/main.yaml
new file mode 100644
index 0000000..05ffcb6
--- /dev/null
+++ b/distro/tests/ansible-roles/obs_repos/defaults/main.yaml
@@ -0,0 +1,4 @@
+---
+# SPDX-License-Identifier: GPL-3.0-or-later
+obs_distro: "{{ ansible_distribution | replace(' ', '_') }}"
+obs_repofile_url: "https://download.opensuse.org/repositories/home:CZ-NIC:{{ item }}/{{ obs_repo_version }}/home:CZ-NIC:{{ item }}.repo"
diff --git a/distro/tests/ansible-roles/obs_repos/tasks/CentOS.yaml b/distro/tests/ansible-roles/obs_repos/tasks/CentOS.yaml
new file mode 100644
index 0000000..2333a95
--- /dev/null
+++ b/distro/tests/ansible-roles/obs_repos/tasks/CentOS.yaml
@@ -0,0 +1,18 @@
+---
+# SPDX-License-Identifier: GPL-3.0-or-later
+- name: update CA certificates
+ yum:
+ name: ca-certificates
+ state: latest
+
+- name: Install EPEL
+ yum:
+ name: epel-release
+ state: present
+
+- name: Download repo file(s)
+ get_url:
+ url: "{{ obs_repofile_url }}"
+ dest: /etc/yum.repos.d/home:CZ-NIC:{{ item }}.repo
+ mode: 0644
+ with_items: "{{ repos }}"
diff --git a/distro/tests/ansible-roles/obs_repos/tasks/Debian.yaml b/distro/tests/ansible-roles/obs_repos/tasks/Debian.yaml
new file mode 100644
index 0000000..6220f89
--- /dev/null
+++ b/distro/tests/ansible-roles/obs_repos/tasks/Debian.yaml
@@ -0,0 +1,15 @@
+---
+# SPDX-License-Identifier: GPL-3.0-or-later
+- name: Add upstream package signing key
+ get_url:
+ url: https://gitlab.nic.cz/knot/knot-resolver-release/raw/master/cznic-obs.gpg.asc
+ dest: /etc/apt/trusted.gpg.d/cznic-obs.gpg.asc
+ mode: 0644
+
+- name: Add OBS repo(s)
+ apt_repository:
+ repo: >
+ deb http://download.opensuse.org/repositories/home:/CZ-NIC:/{{ item }}/{{ obs_repo_version }}/ /
+ state: present
+ update_cache: true
+ with_items: "{{ repos }}"
diff --git a/distro/tests/ansible-roles/obs_repos/tasks/Fedora.yaml b/distro/tests/ansible-roles/obs_repos/tasks/Fedora.yaml
new file mode 100644
index 0000000..520e057
--- /dev/null
+++ b/distro/tests/ansible-roles/obs_repos/tasks/Fedora.yaml
@@ -0,0 +1,8 @@
+---
+# SPDX-License-Identifier: GPL-3.0-or-later
+- name: Download repo file(s)
+ get_url:
+ url: "{{ obs_repofile_url }}"
+ dest: "/etc/yum.repos.d/home:CZ-NIC:{{ item }}.repo"
+ mode: 0644
+ with_items: "{{ repos }}"
diff --git a/distro/tests/ansible-roles/obs_repos/tasks/Rocky.yaml b/distro/tests/ansible-roles/obs_repos/tasks/Rocky.yaml
new file mode 100644
index 0000000..fecfbea
--- /dev/null
+++ b/distro/tests/ansible-roles/obs_repos/tasks/Rocky.yaml
@@ -0,0 +1,13 @@
+---
+# SPDX-License-Identifier: GPL-3.0-or-later
+- name: Install EPEL
+ yum:
+ name: epel-release
+ state: present
+
+- name: Download repo file(s)
+ get_url:
+ url: "{{ obs_repofile_url }}"
+ dest: /etc/yum.repos.d/home:CZ-NIC:{{ item }}.repo
+ mode: 0644
+ with_items: "{{ repos }}"
diff --git a/distro/tests/ansible-roles/obs_repos/tasks/Ubuntu.yaml b/distro/tests/ansible-roles/obs_repos/tasks/Ubuntu.yaml
new file mode 100644
index 0000000..ba424c4
--- /dev/null
+++ b/distro/tests/ansible-roles/obs_repos/tasks/Ubuntu.yaml
@@ -0,0 +1,14 @@
+---
+# SPDX-License-Identifier: GPL-3.0-or-later
+- name: Add upstream package signing key
+ apt_key:
+ url: https://gitlab.nic.cz/knot/knot-resolver-release/raw/master/cznic-obs.gpg.asc
+ state: present
+
+- name: Add OBS repo(s)
+ apt_repository:
+ repo: >
+ deb http://download.opensuse.org/repositories/home:/CZ-NIC:/{{ item }}/{{ obs_repo_version }}/ /
+ state: present
+ update_cache: true
+ with_items: "{{ repos }}"
diff --git a/distro/tests/ansible-roles/obs_repos/tasks/main.yaml b/distro/tests/ansible-roles/obs_repos/tasks/main.yaml
new file mode 100644
index 0000000..6bae001
--- /dev/null
+++ b/distro/tests/ansible-roles/obs_repos/tasks/main.yaml
@@ -0,0 +1,12 @@
+---
+# SPDX-License-Identifier: GPL-3.0-or-later
+- name: Include Debian specific vars
+ include_vars: "{{ obs_distro }}_{{ ansible_distribution_major_version }}.yaml"
+ when: obs_distro == "Debian"
+
+- name: Include distribution specific vars
+ include_vars: "{{ obs_distro }}.yaml"
+ when: obs_distro != "Debian"
+
+- name: Configure upstream repositories
+ include: "{{ obs_distro }}.yaml"
diff --git a/distro/tests/ansible-roles/obs_repos/tasks/openSUSE_Leap.yaml b/distro/tests/ansible-roles/obs_repos/tasks/openSUSE_Leap.yaml
new file mode 100644
index 0000000..84ab5a9
--- /dev/null
+++ b/distro/tests/ansible-roles/obs_repos/tasks/openSUSE_Leap.yaml
@@ -0,0 +1,19 @@
+---
+# SPDX-License-Identifier: GPL-3.0-or-later
+- name: Install python-xml dependency for zypper_repository
+ shell: zypper install -y python-xml
+ args:
+ warn: false
+
+- name: Add upstream repo(s)
+ zypper_repository:
+ repo: "{{ obs_repofile_url }}"
+ state: present
+ disable_gpg_check: true # auto_import_keys is broken
+ with_items: "{{ repos }}"
+
+- name: Refresh all repositories
+ zypper_repository:
+ repo: '*'
+ runrefresh: true
+ failed_when: false
diff --git a/distro/tests/ansible-roles/obs_repos/tasks/openSUSE_Tumbleweed.yaml b/distro/tests/ansible-roles/obs_repos/tasks/openSUSE_Tumbleweed.yaml
new file mode 100644
index 0000000..c063014
--- /dev/null
+++ b/distro/tests/ansible-roles/obs_repos/tasks/openSUSE_Tumbleweed.yaml
@@ -0,0 +1,13 @@
+---
+# SPDX-License-Identifier: GPL-3.0-or-later
+- name: Add upstream repo(s)
+ zypper_repository:
+ repo: "{{ obs_repofile_url }}"
+ state: present
+ disable_gpg_check: true # auto_import_keys is broken
+ with_items: "{{ repos }}"
+
+- name: Refresh all repositories
+ zypper_repository:
+ repo: '*'
+ runrefresh: true
diff --git a/distro/tests/ansible-roles/obs_repos/vars/CentOS.yaml b/distro/tests/ansible-roles/obs_repos/vars/CentOS.yaml
new file mode 100644
index 0000000..22b4795
--- /dev/null
+++ b/distro/tests/ansible-roles/obs_repos/vars/CentOS.yaml
@@ -0,0 +1,3 @@
+---
+# SPDX-License-Identifier: GPL-3.0-or-later
+obs_repo_version: "{{ obs_distro }}_{{ ansible_distribution_major_version }}_EPEL"
diff --git a/distro/tests/ansible-roles/obs_repos/vars/Debian_10.yaml b/distro/tests/ansible-roles/obs_repos/vars/Debian_10.yaml
new file mode 100644
index 0000000..5db857e
--- /dev/null
+++ b/distro/tests/ansible-roles/obs_repos/vars/Debian_10.yaml
@@ -0,0 +1,3 @@
+---
+# SPDX-License-Identifier: GPL-3.0-or-later
+obs_repo_version: "{{ obs_distro }}_{{ ansible_distribution_major_version }}"
diff --git a/distro/tests/ansible-roles/obs_repos/vars/Debian_11.yaml b/distro/tests/ansible-roles/obs_repos/vars/Debian_11.yaml
new file mode 120000
index 0000000..4babdf4
--- /dev/null
+++ b/distro/tests/ansible-roles/obs_repos/vars/Debian_11.yaml
@@ -0,0 +1 @@
+Debian_10.yaml \ No newline at end of file
diff --git a/distro/tests/ansible-roles/obs_repos/vars/Debian_9.yaml b/distro/tests/ansible-roles/obs_repos/vars/Debian_9.yaml
new file mode 100644
index 0000000..21cce25
--- /dev/null
+++ b/distro/tests/ansible-roles/obs_repos/vars/Debian_9.yaml
@@ -0,0 +1,3 @@
+---
+# SPDX-License-Identifier: GPL-3.0-or-later
+obs_repo_version: "{{ obs_distro }}_{{ ansible_distribution_major_version }}.0"
diff --git a/distro/tests/ansible-roles/obs_repos/vars/Fedora.yaml b/distro/tests/ansible-roles/obs_repos/vars/Fedora.yaml
new file mode 100644
index 0000000..5db857e
--- /dev/null
+++ b/distro/tests/ansible-roles/obs_repos/vars/Fedora.yaml
@@ -0,0 +1,3 @@
+---
+# SPDX-License-Identifier: GPL-3.0-or-later
+obs_repo_version: "{{ obs_distro }}_{{ ansible_distribution_major_version }}"
diff --git a/distro/tests/ansible-roles/obs_repos/vars/Rocky.yaml b/distro/tests/ansible-roles/obs_repos/vars/Rocky.yaml
new file mode 100644
index 0000000..b8b5274
--- /dev/null
+++ b/distro/tests/ansible-roles/obs_repos/vars/Rocky.yaml
@@ -0,0 +1,3 @@
+---
+# SPDX-License-Identifier: GPL-3.0-or-later
+obs_repo_version: "CentOS_{{ ansible_distribution_major_version }}_EPEL"
diff --git a/distro/tests/ansible-roles/obs_repos/vars/Ubuntu.yaml b/distro/tests/ansible-roles/obs_repos/vars/Ubuntu.yaml
new file mode 100644
index 0000000..4e5cd2c
--- /dev/null
+++ b/distro/tests/ansible-roles/obs_repos/vars/Ubuntu.yaml
@@ -0,0 +1,3 @@
+---
+# SPDX-License-Identifier: GPL-3.0-or-later
+obs_repo_version: "x{{ obs_distro }}_{{ ansible_distribution_version }}"
diff --git a/distro/tests/ansible-roles/obs_repos/vars/openSUSE_Leap.yaml b/distro/tests/ansible-roles/obs_repos/vars/openSUSE_Leap.yaml
new file mode 100644
index 0000000..7dbd7d8
--- /dev/null
+++ b/distro/tests/ansible-roles/obs_repos/vars/openSUSE_Leap.yaml
@@ -0,0 +1,3 @@
+---
+# SPDX-License-Identifier: GPL-3.0-or-later
+obs_repo_version: "{{ obs_distro }}_{{ ansible_distribution_version }}"
diff --git a/distro/tests/ansible-roles/obs_repos/vars/openSUSE_Tumbleweed.yaml b/distro/tests/ansible-roles/obs_repos/vars/openSUSE_Tumbleweed.yaml
new file mode 100644
index 0000000..d875db7
--- /dev/null
+++ b/distro/tests/ansible-roles/obs_repos/vars/openSUSE_Tumbleweed.yaml
@@ -0,0 +1,3 @@
+---
+# SPDX-License-Identifier: GPL-3.0-or-later
+obs_repo_version: "{{ obs_distro }}"
diff --git a/distro/tests/centos7/Vagrantfile b/distro/tests/centos7/Vagrantfile
new file mode 100644
index 0000000..2358be3
--- /dev/null
+++ b/distro/tests/centos7/Vagrantfile
@@ -0,0 +1,30 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+# -*- mode: ruby -*-
+# vi: set ft=ruby :
+#
+
+Vagrant.configure(2) do |config|
+
+ config.vm.box = "centos/7"
+ config.vm.synced_folder ".", "/vagrant", disabled: true
+
+ config.vm.define "centos7_knot-resolver" do |machine|
+ machine.vm.provision "ansible" do |ansible|
+ ansible.playbook = "../knot-resolver-pkgtest.yaml"
+ ansible.extra_vars = {
+ ansible_python_interpreter: "/usr/bin/python2"
+ }
+ end
+ end
+
+ config.vm.provider :libvirt do |libvirt|
+ libvirt.cpus = 1
+ libvirt.memory = 1024
+ end
+
+ config.vm.provider :virtualbox do |vbox|
+ vbox.cpus = 1
+ vbox.memory = 1024
+ end
+
+end
diff --git a/distro/tests/centos7/ansible.cfg b/distro/tests/centos7/ansible.cfg
new file mode 120000
index 0000000..f80698e
--- /dev/null
+++ b/distro/tests/centos7/ansible.cfg
@@ -0,0 +1 @@
+../.ansible.cfg \ No newline at end of file
diff --git a/distro/tests/debian10/Vagrantfile b/distro/tests/debian10/Vagrantfile
new file mode 100644
index 0000000..7f51f1a
--- /dev/null
+++ b/distro/tests/debian10/Vagrantfile
@@ -0,0 +1,28 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+# -*- mode: ruby -*-
+# vi: set ft=ruby :
+#
+
+Vagrant.configure(2) do |config|
+
+ # debian/buster64 requires manual intervention for apt update as of 2019-07-18
+ config.vm.box = "generic/debian10"
+ config.vm.synced_folder ".", "/vagrant", disabled: true
+
+ config.vm.define "debian10_knot-resolver" do |machine|
+ machine.vm.provision "ansible" do |ansible|
+ ansible.playbook = "../knot-resolver-pkgtest.yaml"
+ end
+ end
+
+ config.vm.provider :libvirt do |libvirt|
+ libvirt.cpus = 1
+ libvirt.memory = 1024
+ end
+
+ config.vm.provider :virtualbox do |vbox|
+ vbox.cpus = 1
+ vbox.memory = 1024
+ end
+
+end
diff --git a/distro/tests/debian10/ansible.cfg b/distro/tests/debian10/ansible.cfg
new file mode 120000
index 0000000..f80698e
--- /dev/null
+++ b/distro/tests/debian10/ansible.cfg
@@ -0,0 +1 @@
+../.ansible.cfg \ No newline at end of file
diff --git a/distro/tests/debian11/Vagrantfile b/distro/tests/debian11/Vagrantfile
new file mode 100644
index 0000000..1ca31a6
--- /dev/null
+++ b/distro/tests/debian11/Vagrantfile
@@ -0,0 +1,27 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+# -*- mode: ruby -*-
+# vi: set ft=ruby :
+#
+
+Vagrant.configure(2) do |config|
+
+ config.vm.box = "generic/debian11"
+ config.vm.synced_folder ".", "/vagrant", disabled: true
+
+ config.vm.define "debian11_knot-resolver" do |machine|
+ machine.vm.provision "ansible" do |ansible|
+ ansible.playbook = "../knot-resolver-pkgtest.yaml"
+ end
+ end
+
+ config.vm.provider :libvirt do |libvirt|
+ libvirt.cpus = 1
+ libvirt.memory = 1024
+ end
+
+ config.vm.provider :virtualbox do |vbox|
+ vbox.cpus = 1
+ vbox.memory = 1024
+ end
+
+end
diff --git a/distro/tests/debian11/ansible.cfg b/distro/tests/debian11/ansible.cfg
new file mode 120000
index 0000000..f80698e
--- /dev/null
+++ b/distro/tests/debian11/ansible.cfg
@@ -0,0 +1 @@
+../.ansible.cfg \ No newline at end of file
diff --git a/distro/tests/debian9/Vagrantfile b/distro/tests/debian9/Vagrantfile
new file mode 100644
index 0000000..c4b6a24
--- /dev/null
+++ b/distro/tests/debian9/Vagrantfile
@@ -0,0 +1,27 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+# -*- mode: ruby -*-
+# vi: set ft=ruby :
+#
+
+Vagrant.configure(2) do |config|
+
+ config.vm.box = "debian/stretch64"
+ config.vm.synced_folder ".", "/vagrant", disabled: true
+
+ config.vm.define "debian9_knot-resolver" do |machine|
+ machine.vm.provision "ansible" do |ansible|
+ ansible.playbook = "../knot-resolver-pkgtest.yaml"
+ end
+ end
+
+ config.vm.provider :libvirt do |libvirt|
+ libvirt.cpus = 1
+ libvirt.memory = 1024
+ end
+
+ config.vm.provider :virtualbox do |vbox|
+ vbox.cpus = 1
+ vbox.memory = 1024
+ end
+
+end
diff --git a/distro/tests/debian9/ansible.cfg b/distro/tests/debian9/ansible.cfg
new file mode 120000
index 0000000..f80698e
--- /dev/null
+++ b/distro/tests/debian9/ansible.cfg
@@ -0,0 +1 @@
+../.ansible.cfg \ No newline at end of file
diff --git a/distro/tests/fedora35/Vagrantfile b/distro/tests/fedora35/Vagrantfile
new file mode 100644
index 0000000..1fe18ec
--- /dev/null
+++ b/distro/tests/fedora35/Vagrantfile
@@ -0,0 +1,30 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+# -*- mode: ruby -*-
+# vi: set ft=ruby :
+#
+
+Vagrant.configure(2) do |config|
+
+ config.vm.box = "fedora/35-cloud-base"
+ config.vm.synced_folder ".", "/vagrant", disabled: true
+
+ config.vm.define "fedora35_knot-resolver" do |machine|
+ machine.vm.provision "ansible" do |ansible|
+ ansible.playbook = "../knot-resolver-pkgtest.yaml"
+ ansible.extra_vars = {
+ ansible_python_interpreter: "/usr/bin/python3",
+ }
+ end
+ end
+
+ config.vm.provider :libvirt do |libvirt|
+ libvirt.cpus = 1
+ libvirt.memory = 1024
+ end
+
+ config.vm.provider :virtualbox do |vbox|
+ vbox.cpus = 1
+ vbox.memory = 1024
+ end
+
+end
diff --git a/distro/tests/fedora35/ansible.cfg b/distro/tests/fedora35/ansible.cfg
new file mode 120000
index 0000000..f80698e
--- /dev/null
+++ b/distro/tests/fedora35/ansible.cfg
@@ -0,0 +1 @@
+../.ansible.cfg \ No newline at end of file
diff --git a/distro/tests/fedora36/Vagrantfile b/distro/tests/fedora36/Vagrantfile
new file mode 100644
index 0000000..56659e5
--- /dev/null
+++ b/distro/tests/fedora36/Vagrantfile
@@ -0,0 +1,30 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+# -*- mode: ruby -*-
+# vi: set ft=ruby :
+#
+
+Vagrant.configure(2) do |config|
+
+ config.vm.box = "fedora/36-cloud-base"
+ config.vm.synced_folder ".", "/vagrant", disabled: true
+
+ config.vm.define "fedora36_knot-resolver" do |machine|
+ machine.vm.provision "ansible" do |ansible|
+ ansible.playbook = "../knot-resolver-pkgtest.yaml"
+ ansible.extra_vars = {
+ ansible_python_interpreter: "/usr/bin/python3",
+ }
+ end
+ end
+
+ config.vm.provider :libvirt do |libvirt|
+ libvirt.cpus = 1
+ libvirt.memory = 1024
+ end
+
+ config.vm.provider :virtualbox do |vbox|
+ vbox.cpus = 1
+ vbox.memory = 1024
+ end
+
+end
diff --git a/distro/tests/fedora36/ansible.cfg b/distro/tests/fedora36/ansible.cfg
new file mode 120000
index 0000000..f80698e
--- /dev/null
+++ b/distro/tests/fedora36/ansible.cfg
@@ -0,0 +1 @@
+../.ansible.cfg \ No newline at end of file
diff --git a/distro/tests/knot-resolver-pkgtest.yaml b/distro/tests/knot-resolver-pkgtest.yaml
new file mode 100644
index 0000000..83545bb
--- /dev/null
+++ b/distro/tests/knot-resolver-pkgtest.yaml
@@ -0,0 +1,13 @@
+---
+# SPDX-License-Identifier: GPL-3.0-or-later
+- hosts: all
+
+ remote_user: root
+ become: true
+
+ vars_files:
+ - repos.yaml
+
+ roles:
+ - obs_repos
+ - knot_resolver
diff --git a/distro/tests/leap15/Vagrantfile b/distro/tests/leap15/Vagrantfile
new file mode 100644
index 0000000..a2f7646
--- /dev/null
+++ b/distro/tests/leap15/Vagrantfile
@@ -0,0 +1,29 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+# -*- mode: ruby -*-
+# vi: set ft=ruby :
+#
+
+Vagrant.configure(2) do |config|
+
+ config.vm.box = "generic/opensuse15"
+
+ config.vm.synced_folder ".", "/vagrant", disabled: true
+
+ config.vm.define "leap15_knot-resolver" do |machine|
+ machine.vm.provision "ansible" do |ansible|
+ ansible.playbook = "../knot-resolver-pkgtest.yaml"
+ end
+ end
+
+ config.vm.provider :libvirt do |libvirt|
+ libvirt.cpus = 1
+ libvirt.memory = 1024
+ libvirt.disk_bus = "sata"
+ end
+
+ config.vm.provider :virtualbox do |vbox|
+ vbox.cpus = 1
+ vbox.memory = 1024
+ end
+
+end
diff --git a/distro/tests/leap15/ansible.cfg b/distro/tests/leap15/ansible.cfg
new file mode 120000
index 0000000..f80698e
--- /dev/null
+++ b/distro/tests/leap15/ansible.cfg
@@ -0,0 +1 @@
+../.ansible.cfg \ No newline at end of file
diff --git a/distro/tests/repos.yaml b/distro/tests/repos.yaml
new file mode 100644
index 0000000..bd4bedd
--- /dev/null
+++ b/distro/tests/repos.yaml
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+repos:
+ - knot-resolver-latest
+ - knot-resolver-devel
diff --git a/distro/tests/rocky8/Vagrantfile b/distro/tests/rocky8/Vagrantfile
new file mode 100644
index 0000000..f82c194
--- /dev/null
+++ b/distro/tests/rocky8/Vagrantfile
@@ -0,0 +1,30 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+# -*- mode: ruby -*-
+# vi: set ft=ruby :
+#
+
+Vagrant.configure(2) do |config|
+
+ config.vm.box = "generic/rocky8"
+ config.vm.synced_folder ".", "/vagrant", disabled: true
+
+ config.vm.define "rocky8_knot-resolver" do |machine|
+ machine.vm.provision "ansible" do |ansible|
+ ansible.playbook = "../knot-resolver-pkgtest.yaml"
+ ansible.extra_vars = {
+ ansible_python_interpreter: "/usr/libexec/platform-python"
+ }
+ end
+ end
+
+ config.vm.provider :libvirt do |libvirt|
+ libvirt.cpus = 1
+ libvirt.memory = 1024
+ end
+
+ config.vm.provider :virtualbox do |vbox|
+ vbox.cpus = 1
+ vbox.memory = 1024
+ end
+
+end
diff --git a/distro/tests/rocky8/ansible.cfg b/distro/tests/rocky8/ansible.cfg
new file mode 120000
index 0000000..f80698e
--- /dev/null
+++ b/distro/tests/rocky8/ansible.cfg
@@ -0,0 +1 @@
+../.ansible.cfg \ No newline at end of file
diff --git a/distro/tests/test-distro.sh b/distro/tests/test-distro.sh
new file mode 100755
index 0000000..55b75d0
--- /dev/null
+++ b/distro/tests/test-distro.sh
@@ -0,0 +1,26 @@
+#!/bin/bash -x
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# ./test-distro.sh {obs_repo} {distro}
+# Example usage: ./test-distro.sh knot-resolver-devel debian9
+
+pkgtestdir="$(dirname ${0})"
+repofile="$pkgtestdir/repos.yaml"
+
+distro=$2
+repo=$1
+
+# Select repos
+echo -e "repos:\n - $repo" > $repofile
+if [ "$repo" == "knot-resolver-devel" ]; then
+ # get Knot DNS from knot-resolver-latest
+ echo -e ' - knot-resolver-latest' >> $repofile
+fi
+
+pushd "$pkgtestdir/$distro"
+vagrant destroy -f &>/dev/null
+vagrant up
+ret=$?
+vagrant destroy -f &>/dev/null
+popd
+exit $ret
diff --git a/distro/tests/ubuntu1804/Vagrantfile b/distro/tests/ubuntu1804/Vagrantfile
new file mode 100644
index 0000000..5c53895
--- /dev/null
+++ b/distro/tests/ubuntu1804/Vagrantfile
@@ -0,0 +1,30 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+# -*- mode: ruby -*-
+# vi: set ft=ruby :
+#
+
+Vagrant.configure(2) do |config|
+
+ config.vm.box = "generic/ubuntu1804"
+ config.vm.synced_folder ".", "/vagrant", disabled: true
+
+ config.vm.define "ubuntu1804_knot-resolver" do |machine|
+ machine.vm.provision "ansible" do |ansible|
+ ansible.playbook = "../knot-resolver-pkgtest.yaml"
+ ansible.extra_vars = {
+ ansible_python_interpreter: "/usr/bin/python3"
+ }
+ end
+ end
+
+ config.vm.provider :libvirt do |libvirt|
+ libvirt.cpus = 1
+ libvirt.memory = 1024
+ end
+
+ config.vm.provider :virtualbox do |vbox|
+ vbox.cpus = 1
+ vbox.memory = 1024
+ end
+
+end
diff --git a/distro/tests/ubuntu1804/ansible.cfg b/distro/tests/ubuntu1804/ansible.cfg
new file mode 120000
index 0000000..f80698e
--- /dev/null
+++ b/distro/tests/ubuntu1804/ansible.cfg
@@ -0,0 +1 @@
+../.ansible.cfg \ No newline at end of file
diff --git a/distro/tests/ubuntu2004/Vagrantfile b/distro/tests/ubuntu2004/Vagrantfile
new file mode 100644
index 0000000..3d5c40a
--- /dev/null
+++ b/distro/tests/ubuntu2004/Vagrantfile
@@ -0,0 +1,30 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+# -*- mode: ruby -*-
+# vi: set ft=ruby :
+#
+
+Vagrant.configure(2) do |config|
+
+ config.vm.box = "generic/ubuntu2004"
+ config.vm.synced_folder ".", "/vagrant", disabled: true
+
+ config.vm.define "ubuntu2004_knot-resolver" do |machine|
+ machine.vm.provision "ansible" do |ansible|
+ ansible.playbook = "../knot-resolver-pkgtest.yaml"
+ ansible.extra_vars = {
+ ansible_python_interpreter: "/usr/bin/python3"
+ }
+ end
+ end
+
+ config.vm.provider :libvirt do |libvirt|
+ libvirt.cpus = 1
+ libvirt.memory = 1024
+ end
+
+ config.vm.provider :virtualbox do |vbox|
+ vbox.cpus = 1
+ vbox.memory = 1024
+ end
+
+end
diff --git a/distro/tests/ubuntu2004/ansible.cfg b/distro/tests/ubuntu2004/ansible.cfg
new file mode 120000
index 0000000..f80698e
--- /dev/null
+++ b/distro/tests/ubuntu2004/ansible.cfg
@@ -0,0 +1 @@
+../.ansible.cfg \ No newline at end of file
diff --git a/distro/tests/ubuntu2204/Vagrantfile b/distro/tests/ubuntu2204/Vagrantfile
new file mode 100644
index 0000000..e2b9750
--- /dev/null
+++ b/distro/tests/ubuntu2204/Vagrantfile
@@ -0,0 +1,30 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+# -*- mode: ruby -*-
+# vi: set ft=ruby :
+#
+
+Vagrant.configure(2) do |config|
+
+ config.vm.box = "generic/ubuntu2204"
+ config.vm.synced_folder ".", "/vagrant", disabled: true
+
+ config.vm.define "ubuntu2204_knot-resolver" do |machine|
+ machine.vm.provision "ansible" do |ansible|
+ ansible.playbook = "../knot-resolver-pkgtest.yaml"
+ ansible.extra_vars = {
+ ansible_python_interpreter: "/usr/bin/python3"
+ }
+ end
+ end
+
+ config.vm.provider :libvirt do |libvirt|
+ libvirt.cpus = 1
+ libvirt.memory = 1024
+ end
+
+ config.vm.provider :virtualbox do |vbox|
+ vbox.cpus = 1
+ vbox.memory = 1024
+ end
+
+end
diff --git a/distro/tests/ubuntu2204/ansible.cfg b/distro/tests/ubuntu2204/ansible.cfg
new file mode 120000
index 0000000..f80698e
--- /dev/null
+++ b/distro/tests/ubuntu2204/ansible.cfg
@@ -0,0 +1 @@
+../.ansible.cfg \ No newline at end of file
diff --git a/doc/.packaging/centos/7/NOTSUPPORTED b/doc/.packaging/centos/7/NOTSUPPORTED
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/doc/.packaging/centos/7/NOTSUPPORTED
diff --git a/doc/.packaging/centos/8/NOTSUPPORTED b/doc/.packaging/centos/8/NOTSUPPORTED
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/doc/.packaging/centos/8/NOTSUPPORTED
diff --git a/doc/.packaging/debian/10/build.sh b/doc/.packaging/debian/10/build.sh
new file mode 100755
index 0000000..e6084df
--- /dev/null
+++ b/doc/.packaging/debian/10/build.sh
@@ -0,0 +1,19 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-3.0-or-later
+[ -d /root/kresd/build_packaging ] && rm -rf /root/kresd/build_packaging/;
+CFLAGS="$CFLAGS -Wall -pedantic -fno-omit-frame-pointer"
+LDFLAGS="$LDFLAGS -Wl,--as-needed"
+meson build_packaging \
+ --buildtype=plain \
+ --prefix=/root/kresd/install_packaging \
+ --libdir=lib \
+ --default-library=static \
+ -Ddoc=enabled \
+ -Dsystemd_files=enabled \
+ -Dclient=enabled \
+ -Dkeyfile_default=/usr/share/dns/root.key \
+ -Droot_hints=/usr/share/dns/root.hints \
+ -Dinstall_kresd_conf=enabled \
+ -Dunit_tests=enabled \
+ -Dc_args="${CFLAGS}" \
+ -Dc_link_args="${LDFLAGS}";
diff --git a/doc/.packaging/debian/10/builddeps b/doc/.packaging/debian/10/builddeps
new file mode 100644
index 0000000..81b7a5b
--- /dev/null
+++ b/doc/.packaging/debian/10/builddeps
@@ -0,0 +1,4 @@
+doxygen
+python3-sphinx
+python3-breathe
+python3-sphinx-rtd-theme
diff --git a/doc/.packaging/debian/10/install.sh b/doc/.packaging/debian/10/install.sh
new file mode 100755
index 0000000..3422d68
--- /dev/null
+++ b/doc/.packaging/debian/10/install.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-3.0-or-later
+ninja -C build_packaging doc
diff --git a/doc/.packaging/debian/9/build.sh b/doc/.packaging/debian/9/build.sh
new file mode 100755
index 0000000..e6084df
--- /dev/null
+++ b/doc/.packaging/debian/9/build.sh
@@ -0,0 +1,19 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-3.0-or-later
+[ -d /root/kresd/build_packaging ] && rm -rf /root/kresd/build_packaging/;
+CFLAGS="$CFLAGS -Wall -pedantic -fno-omit-frame-pointer"
+LDFLAGS="$LDFLAGS -Wl,--as-needed"
+meson build_packaging \
+ --buildtype=plain \
+ --prefix=/root/kresd/install_packaging \
+ --libdir=lib \
+ --default-library=static \
+ -Ddoc=enabled \
+ -Dsystemd_files=enabled \
+ -Dclient=enabled \
+ -Dkeyfile_default=/usr/share/dns/root.key \
+ -Droot_hints=/usr/share/dns/root.hints \
+ -Dinstall_kresd_conf=enabled \
+ -Dunit_tests=enabled \
+ -Dc_args="${CFLAGS}" \
+ -Dc_link_args="${LDFLAGS}";
diff --git a/doc/.packaging/debian/9/builddeps b/doc/.packaging/debian/9/builddeps
new file mode 100644
index 0000000..81b7a5b
--- /dev/null
+++ b/doc/.packaging/debian/9/builddeps
@@ -0,0 +1,4 @@
+doxygen
+python3-sphinx
+python3-breathe
+python3-sphinx-rtd-theme
diff --git a/doc/.packaging/debian/9/install.sh b/doc/.packaging/debian/9/install.sh
new file mode 100755
index 0000000..3422d68
--- /dev/null
+++ b/doc/.packaging/debian/9/install.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-3.0-or-later
+ninja -C build_packaging doc
diff --git a/doc/.packaging/fedora/31/build.sh b/doc/.packaging/fedora/31/build.sh
new file mode 100755
index 0000000..68ea49e
--- /dev/null
+++ b/doc/.packaging/fedora/31/build.sh
@@ -0,0 +1,20 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-3.0-or-later
+[ -d /root/kresd/build_packaging ] && rm -rf /root/kresd/build_packaging/;
+CFLAGS="$CFLAGS -Wall -pedantic -fno-omit-frame-pointer"
+LDFLAGS="$LDFLAGS -Wl,--as-needed"
+meson build_packaging \
+ --buildtype=plain \
+ --prefix=/root/kresd/install_packaging \
+ --sbindir=sbin \
+ --libdir=lib \
+ --includedir=include \
+ --sysconfdir=etc \
+ -Ddoc=enabled \
+ -Dsystemd_files=enabled \
+ -Dclient=enabled \
+ -Dunit_tests=enabled \
+ -Dmanaged_ta=enabled \
+ -Dkeyfile_default=/var/lib/knot-resolver/root.keys \
+ -Dinstall_root_keys=enabled \
+ -Dinstall_kresd_conf=enabled;
diff --git a/doc/.packaging/fedora/31/builddeps b/doc/.packaging/fedora/31/builddeps
new file mode 100644
index 0000000..0a4b886
--- /dev/null
+++ b/doc/.packaging/fedora/31/builddeps
@@ -0,0 +1,4 @@
+doxygen
+python3-sphinx
+python3-breathe
+python3-sphinx_rtd_theme
diff --git a/doc/.packaging/fedora/31/install.sh b/doc/.packaging/fedora/31/install.sh
new file mode 100755
index 0000000..3422d68
--- /dev/null
+++ b/doc/.packaging/fedora/31/install.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-3.0-or-later
+ninja -C build_packaging doc
diff --git a/doc/.packaging/fedora/32/30/build.sh b/doc/.packaging/fedora/32/30/build.sh
new file mode 100755
index 0000000..68ea49e
--- /dev/null
+++ b/doc/.packaging/fedora/32/30/build.sh
@@ -0,0 +1,20 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-3.0-or-later
+[ -d /root/kresd/build_packaging ] && rm -rf /root/kresd/build_packaging/;
+CFLAGS="$CFLAGS -Wall -pedantic -fno-omit-frame-pointer"
+LDFLAGS="$LDFLAGS -Wl,--as-needed"
+meson build_packaging \
+ --buildtype=plain \
+ --prefix=/root/kresd/install_packaging \
+ --sbindir=sbin \
+ --libdir=lib \
+ --includedir=include \
+ --sysconfdir=etc \
+ -Ddoc=enabled \
+ -Dsystemd_files=enabled \
+ -Dclient=enabled \
+ -Dunit_tests=enabled \
+ -Dmanaged_ta=enabled \
+ -Dkeyfile_default=/var/lib/knot-resolver/root.keys \
+ -Dinstall_root_keys=enabled \
+ -Dinstall_kresd_conf=enabled;
diff --git a/doc/.packaging/fedora/32/30/builddeps b/doc/.packaging/fedora/32/30/builddeps
new file mode 100644
index 0000000..0a4b886
--- /dev/null
+++ b/doc/.packaging/fedora/32/30/builddeps
@@ -0,0 +1,4 @@
+doxygen
+python3-sphinx
+python3-breathe
+python3-sphinx_rtd_theme
diff --git a/doc/.packaging/fedora/32/30/install.sh b/doc/.packaging/fedora/32/30/install.sh
new file mode 100755
index 0000000..3422d68
--- /dev/null
+++ b/doc/.packaging/fedora/32/30/install.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-3.0-or-later
+ninja -C build_packaging doc
diff --git a/doc/.packaging/fedora/32/build.sh b/doc/.packaging/fedora/32/build.sh
new file mode 100755
index 0000000..68ea49e
--- /dev/null
+++ b/doc/.packaging/fedora/32/build.sh
@@ -0,0 +1,20 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-3.0-or-later
+[ -d /root/kresd/build_packaging ] && rm -rf /root/kresd/build_packaging/;
+CFLAGS="$CFLAGS -Wall -pedantic -fno-omit-frame-pointer"
+LDFLAGS="$LDFLAGS -Wl,--as-needed"
+meson build_packaging \
+ --buildtype=plain \
+ --prefix=/root/kresd/install_packaging \
+ --sbindir=sbin \
+ --libdir=lib \
+ --includedir=include \
+ --sysconfdir=etc \
+ -Ddoc=enabled \
+ -Dsystemd_files=enabled \
+ -Dclient=enabled \
+ -Dunit_tests=enabled \
+ -Dmanaged_ta=enabled \
+ -Dkeyfile_default=/var/lib/knot-resolver/root.keys \
+ -Dinstall_root_keys=enabled \
+ -Dinstall_kresd_conf=enabled;
diff --git a/doc/.packaging/fedora/32/builddeps b/doc/.packaging/fedora/32/builddeps
new file mode 100644
index 0000000..0a4b886
--- /dev/null
+++ b/doc/.packaging/fedora/32/builddeps
@@ -0,0 +1,4 @@
+doxygen
+python3-sphinx
+python3-breathe
+python3-sphinx_rtd_theme
diff --git a/doc/.packaging/fedora/32/install.sh b/doc/.packaging/fedora/32/install.sh
new file mode 100755
index 0000000..3422d68
--- /dev/null
+++ b/doc/.packaging/fedora/32/install.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-3.0-or-later
+ninja -C build_packaging doc
diff --git a/doc/.packaging/leap/15.2/build.sh b/doc/.packaging/leap/15.2/build.sh
new file mode 100755
index 0000000..68ea49e
--- /dev/null
+++ b/doc/.packaging/leap/15.2/build.sh
@@ -0,0 +1,20 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-3.0-or-later
+[ -d /root/kresd/build_packaging ] && rm -rf /root/kresd/build_packaging/;
+CFLAGS="$CFLAGS -Wall -pedantic -fno-omit-frame-pointer"
+LDFLAGS="$LDFLAGS -Wl,--as-needed"
+meson build_packaging \
+ --buildtype=plain \
+ --prefix=/root/kresd/install_packaging \
+ --sbindir=sbin \
+ --libdir=lib \
+ --includedir=include \
+ --sysconfdir=etc \
+ -Ddoc=enabled \
+ -Dsystemd_files=enabled \
+ -Dclient=enabled \
+ -Dunit_tests=enabled \
+ -Dmanaged_ta=enabled \
+ -Dkeyfile_default=/var/lib/knot-resolver/root.keys \
+ -Dinstall_root_keys=enabled \
+ -Dinstall_kresd_conf=enabled;
diff --git a/doc/.packaging/leap/15.2/builddeps b/doc/.packaging/leap/15.2/builddeps
new file mode 100644
index 0000000..60daf9c
--- /dev/null
+++ b/doc/.packaging/leap/15.2/builddeps
@@ -0,0 +1,4 @@
+doxygen
+python3-Sphinx
+python3-breathe
+python3-sphinx_rtd_theme
diff --git a/doc/.packaging/leap/15.2/install.sh b/doc/.packaging/leap/15.2/install.sh
new file mode 100755
index 0000000..3422d68
--- /dev/null
+++ b/doc/.packaging/leap/15.2/install.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-3.0-or-later
+ninja -C build_packaging doc
diff --git a/doc/.packaging/test.sh b/doc/.packaging/test.sh
new file mode 100755
index 0000000..33bf175
--- /dev/null
+++ b/doc/.packaging/test.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-3.0-or-later
+test -e ../doc/html/index.html
diff --git a/doc/.packaging/ubuntu/16.04/build.sh b/doc/.packaging/ubuntu/16.04/build.sh
new file mode 100755
index 0000000..e6084df
--- /dev/null
+++ b/doc/.packaging/ubuntu/16.04/build.sh
@@ -0,0 +1,19 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-3.0-or-later
+[ -d /root/kresd/build_packaging ] && rm -rf /root/kresd/build_packaging/;
+CFLAGS="$CFLAGS -Wall -pedantic -fno-omit-frame-pointer"
+LDFLAGS="$LDFLAGS -Wl,--as-needed"
+meson build_packaging \
+ --buildtype=plain \
+ --prefix=/root/kresd/install_packaging \
+ --libdir=lib \
+ --default-library=static \
+ -Ddoc=enabled \
+ -Dsystemd_files=enabled \
+ -Dclient=enabled \
+ -Dkeyfile_default=/usr/share/dns/root.key \
+ -Droot_hints=/usr/share/dns/root.hints \
+ -Dinstall_kresd_conf=enabled \
+ -Dunit_tests=enabled \
+ -Dc_args="${CFLAGS}" \
+ -Dc_link_args="${LDFLAGS}";
diff --git a/doc/.packaging/ubuntu/16.04/builddeps b/doc/.packaging/ubuntu/16.04/builddeps
new file mode 100644
index 0000000..81b7a5b
--- /dev/null
+++ b/doc/.packaging/ubuntu/16.04/builddeps
@@ -0,0 +1,4 @@
+doxygen
+python3-sphinx
+python3-breathe
+python3-sphinx-rtd-theme
diff --git a/doc/.packaging/ubuntu/16.04/install.sh b/doc/.packaging/ubuntu/16.04/install.sh
new file mode 100755
index 0000000..3422d68
--- /dev/null
+++ b/doc/.packaging/ubuntu/16.04/install.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-3.0-or-later
+ninja -C build_packaging doc
diff --git a/doc/.packaging/ubuntu/18.04/build.sh b/doc/.packaging/ubuntu/18.04/build.sh
new file mode 100755
index 0000000..e6084df
--- /dev/null
+++ b/doc/.packaging/ubuntu/18.04/build.sh
@@ -0,0 +1,19 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-3.0-or-later
+[ -d /root/kresd/build_packaging ] && rm -rf /root/kresd/build_packaging/;
+CFLAGS="$CFLAGS -Wall -pedantic -fno-omit-frame-pointer"
+LDFLAGS="$LDFLAGS -Wl,--as-needed"
+meson build_packaging \
+ --buildtype=plain \
+ --prefix=/root/kresd/install_packaging \
+ --libdir=lib \
+ --default-library=static \
+ -Ddoc=enabled \
+ -Dsystemd_files=enabled \
+ -Dclient=enabled \
+ -Dkeyfile_default=/usr/share/dns/root.key \
+ -Droot_hints=/usr/share/dns/root.hints \
+ -Dinstall_kresd_conf=enabled \
+ -Dunit_tests=enabled \
+ -Dc_args="${CFLAGS}" \
+ -Dc_link_args="${LDFLAGS}";
diff --git a/doc/.packaging/ubuntu/18.04/builddeps b/doc/.packaging/ubuntu/18.04/builddeps
new file mode 100644
index 0000000..81b7a5b
--- /dev/null
+++ b/doc/.packaging/ubuntu/18.04/builddeps
@@ -0,0 +1,4 @@
+doxygen
+python3-sphinx
+python3-breathe
+python3-sphinx-rtd-theme
diff --git a/doc/.packaging/ubuntu/18.04/install.sh b/doc/.packaging/ubuntu/18.04/install.sh
new file mode 100755
index 0000000..3422d68
--- /dev/null
+++ b/doc/.packaging/ubuntu/18.04/install.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-3.0-or-later
+ninja -C build_packaging doc
diff --git a/doc/.packaging/ubuntu/20.04/build.sh b/doc/.packaging/ubuntu/20.04/build.sh
new file mode 100755
index 0000000..e6084df
--- /dev/null
+++ b/doc/.packaging/ubuntu/20.04/build.sh
@@ -0,0 +1,19 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-3.0-or-later
+[ -d /root/kresd/build_packaging ] && rm -rf /root/kresd/build_packaging/;
+CFLAGS="$CFLAGS -Wall -pedantic -fno-omit-frame-pointer"
+LDFLAGS="$LDFLAGS -Wl,--as-needed"
+meson build_packaging \
+ --buildtype=plain \
+ --prefix=/root/kresd/install_packaging \
+ --libdir=lib \
+ --default-library=static \
+ -Ddoc=enabled \
+ -Dsystemd_files=enabled \
+ -Dclient=enabled \
+ -Dkeyfile_default=/usr/share/dns/root.key \
+ -Droot_hints=/usr/share/dns/root.hints \
+ -Dinstall_kresd_conf=enabled \
+ -Dunit_tests=enabled \
+ -Dc_args="${CFLAGS}" \
+ -Dc_link_args="${LDFLAGS}";
diff --git a/doc/.packaging/ubuntu/20.04/builddeps b/doc/.packaging/ubuntu/20.04/builddeps
new file mode 100644
index 0000000..81b7a5b
--- /dev/null
+++ b/doc/.packaging/ubuntu/20.04/builddeps
@@ -0,0 +1,4 @@
+doxygen
+python3-sphinx
+python3-breathe
+python3-sphinx-rtd-theme
diff --git a/doc/.packaging/ubuntu/20.04/install.sh b/doc/.packaging/ubuntu/20.04/install.sh
new file mode 100755
index 0000000..3422d68
--- /dev/null
+++ b/doc/.packaging/ubuntu/20.04/install.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-3.0-or-later
+ninja -C build_packaging doc
diff --git a/doc/Doxyfile b/doc/Doxyfile
new file mode 100644
index 0000000..d2f4c5b
--- /dev/null
+++ b/doc/Doxyfile
@@ -0,0 +1,23 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+PROJECT_NAME = Knot Resolver library
+GENERATE_HTML = NO
+GENERATE_XML = YES
+GENERATE_LATEX = NO
+GENERATE_MAN = NO
+GENERATE_RTF = NO
+CASE_SENSE_NAMES = NO
+INPUT = ../lib ../daemon
+FILE_PATTERNS = *.h
+QUIET = YES
+RECURSIVE = YES
+JAVADOC_AUTOBRIEF = YES
+AUTOLINK_SUPPORT = YES
+XML_OUTPUT = doxyxml
+HIDE_UNDOC_MEMBERS = YES
+HIDE_UNDOC_CLASSES = YES
+OPTIMIZE_OUTPUT_FOR_C = YES
+ENABLE_PREPROCESSING = YES
+MACRO_EXPANSION = YES
+EXPAND_ONLY_PREDEF = YES
+PREDEFINED = NDEBUG KR_CONST= KR_EXPORT= KR_PURE= lru_t(type)=see_source_code KR_PRINTF(n)= KR_COLD= array_t(type)=see_source_code __attribute__(x)=
+EXCLUDE_SYMBOLS = static_assert uint set_walk_cb module_api_cb kr_prop_cb kr_straddr_split
diff --git a/doc/NEWS.rst b/doc/NEWS.rst
new file mode 100644
index 0000000..596484a
--- /dev/null
+++ b/doc/NEWS.rst
@@ -0,0 +1,36 @@
+.. SPDX-License-Identifier: GPL-3.0-or-later
+
+.. _release_notes:
+
+*************
+Release notes
+*************
+
+Version numbering
+=================
+Version number format is ``major.minor.patch``.
+Knot Resolver does not use semantic versioning even though the version number looks similar.
+
+Leftmost number which was changed signalizes what to expect when upgrading:
+
+Major version
+ * Manual upgrade steps might be necessary, please follow instructions in :ref:`Upgrading` section.
+ * Major releases may contain significant changes including changes to configuration format.
+ * We might release a new major also when internal implementation details change significantly.
+
+Minor version
+ * Configuration stays compatible with the previous version, except for undocumented or very obscure options.
+ * Upgrade should be seamless for users who use modules shipped as part of Knot Resolver distribution.
+ * Incompatible changes in internal APIs are allowed in minor versions. Users who develop or use custom modules
+ (i.e. modules not distributed together with Knot Resolver) need to double check their modules for incompatibilities.
+ :ref:`Upgrading` section should contain hints for module authors.
+
+Patch version
+ * Everything should be compatible with the previous version.
+ * API for modules should be stable on best effort basis, i.e. API is very unlikely to break in patch releases.
+ * Custom modules might need to be recompiled, i.e. ABI compatibility is not guaranteed.
+
+This definition is not applicable to versions older than 5.2.0.
+
+.. include:: ../NEWS
+
diff --git a/doc/README.md b/doc/README.md
new file mode 100644
index 0000000..6860672
--- /dev/null
+++ b/doc/README.md
@@ -0,0 +1,27 @@
+## Documentation
+
+Each directory contains a README.md with the basic information, examples and usage.
+It does not however contain API documentation, which is built separately in this directory.
+
+### Requirements
+
+The code is documented with [Doxygen][doxygen] JavaDoc style, a prettified documentation
+also requires [breathe][breathe] and [Sphinx][sphinx] for building sane documentation pages.
+It is not however required.
+
+[doxygen]:https://www.stack.nl/~dimitri/doxygen/manual/index.html
+[breathe]: https://github.com/michaeljones/breathe
+[sphinx]: http://sphinx-doc.org/
+
+You can get the extra dependencies with pip:
+
+```sh
+pip install -U Sphinx breathe
+# Alternatively
+pip -r doc/requirements.txt
+```
+
+### Building documentation
+
+If you satisfy the requirements, it's as easy as `make doc`, which builds the documentation in this folder.
+
diff --git a/doc/_static/.gitignore b/doc/_static/.gitignore
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/doc/_static/.gitignore
diff --git a/doc/_static/css/custom.css b/doc/_static/css/custom.css
new file mode 100644
index 0000000..e9ec794
--- /dev/null
+++ b/doc/_static/css/custom.css
@@ -0,0 +1,6 @@
+/* SPDX-License-Identifier: GPL-3.0-or-later */
+@import "theme.css";
+
+table.docutils blockquote {
+ margin-left: 0;
+}
diff --git a/doc/_static/logo-negativ.svg b/doc/_static/logo-negativ.svg
new file mode 100644
index 0000000..ec6c90f
--- /dev/null
+++ b/doc/_static/logo-negativ.svg
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 23.0.6, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<svg version="1.1" id="Vrstva_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 600 161" style="enable-background:new 0 0 600 161;" xml:space="preserve" width="200" height="54">
+<style type="text/css">
+ .st0{fill:#FFFFFF;}
+</style>
+<path class="st0" d="M158.6,80.6c0,24.2-10.7,45.8-27.7,60.4c1-4.9,1.5-9.9,1.5-15.1c0-15.8-4.7-30.5-12.7-42.9
+ c-3.2,4.4-6.8,8.5-10.7,12.1c5.1,9.1,8,19.6,8,30.8c0,4.5-0.5,8.9-1.4,13.2c-0.1,0.5-0.2,0.9-0.3,1.4c-0.1,0.4-0.2,0.9-0.3,1.4
+ c-0.5-0.1-0.9-0.2-1.4-0.4c-0.4-0.1-0.9-0.3-1.3-0.4c-14.6-4.8-26.9-14.7-34.8-27.6c-0.2-0.4-0.5-0.8-0.7-1.3
+ c-0.3-0.4-0.5-0.8-0.7-1.2c-2.5-4.5-4.4-9.4-5.7-14.4c-0.1-0.5-0.2-0.9-0.3-1.4c-0.1-0.4-0.2-0.9-0.3-1.4c-0.9-4.3-1.4-8.7-1.4-13.2
+ c0-4.5,0.5-8.9,1.4-13.2c-4.9-1.4-10-2.1-15.3-2.2c-1,5-1.5,10.1-1.5,15.4c0,5.3,0.5,10.4,1.5,15.4c0.1,0.5,0.2,0.9,0.3,1.4
+ c0.1,0.5,0.2,1,0.3,1.4c1.2,5.3,3,10.3,5.3,15.2c0.2,0.4,0.4,0.9,0.6,1.3c0.2,0.5,0.4,0.9,0.7,1.4c9.3,18.1,25.4,32.1,44.9,38.8
+ c-8.6,3.2-17.9,4.9-27.6,4.9c-39.6,0-72.5-28.8-78.7-66.7c0.3,0.3,0.7,0.6,1.1,0.9c13.9,12.2,32.2,19.7,52.1,19.7
+ c1.3,0,2.6,0,3.9-0.1c-2.2-4.9-4-10-5.2-15.4c-15.8-0.3-30.3-6.4-41.2-16.3c-0.4-0.3-0.7-0.6-1-1c-0.3-0.3-0.7-0.7-1-1
+ c0.3-0.3,0.7-0.7,1-1c0.3-0.3,0.7-0.7,1-1c11-9.9,25.4-16,41.2-16.3c0.4,0,0.8,0,1.2,0h0.2c0.5,0,1,0,1.5,0
+ c5.3,0.1,10.4,0.9,15.4,2.3c0.4,0.1,0.9,0.3,1.3,0.4c0.5,0.1,0.9,0.3,1.3,0.4c8.5,2.8,16.3,7.3,22.8,13.2c3.7-3.6,6.9-7.7,9.6-12.1
+ c-7.7-6.8-16.7-12.1-26.7-15.4c-0.4-0.2-0.9-0.3-1.3-0.4c-0.5-0.2-0.9-0.3-1.4-0.4c-5.1-1.5-10.3-2.6-15.8-3c-0.5-0.1-1-0.1-1.5-0.1
+ c-0.5,0-1-0.1-1.5-0.1c-1.3-0.1-2.6-0.1-3.9-0.1c-19.9,0-38.2,7.4-52.1,19.6c-0.4,0.3-0.7,0.6-1.1,0.9C6.4,29.6,39.2,0.8,78.8,0.8
+ c9.7,0,19,1.7,27.6,4.9c0,0,0,0,0,0C87,12.3,70.9,26.4,61.5,44.5c5.5,0.6,10.8,1.6,15.9,3.2c7.8-12.9,20.2-22.9,34.8-27.6
+ c0.4-0.1,0.9-0.3,1.3-0.4c0.5-0.1,0.9-0.3,1.4-0.4c0.1,0.4,0.2,0.9,0.3,1.4c0.1,0.5,0.2,0.9,0.3,1.4c0.9,4.3,1.4,8.7,1.4,13.2
+ c0,11.1-2.9,21.6-7.9,30.7c-0.2,0.4-0.5,0.8-0.7,1.2c-0.2,0.4-0.5,0.8-0.7,1.2c-2.7,4.4-6,8.5-9.7,12.1c-0.3,0.3-0.7,0.7-1,1
+ c-0.3,0.3-0.7,0.7-1,1C89.3,88.4,81.5,92.9,73,95.7c1.3,5.1,3.3,9.9,5.8,14.4c9.9-3.4,18.9-8.7,26.7-15.5c0.4-0.3,0.7-0.6,1.1-1
+ c0.4-0.3,0.7-0.6,1-1C111.4,89,115,85,118,80.6c0.3-0.4,0.6-0.8,0.9-1.2c0.3-0.4,0.6-0.8,0.8-1.3c8-12.4,12.7-27.1,12.7-42.9
+ c0-5.2-0.5-10.2-1.5-15.1C147.9,34.8,158.6,56.4,158.6,80.6 M244.6,76.6L218,45.2l25.1-26.8h-17.6L204.6,42h-0.2V18.3h-13.8v58.3
+ h13.8V49.8h0.2l21.7,26.8H244.6z M304.6,76.6V18.3h-13.7l0.3,38H291l-23.4-38h-16.1v58.3h13.7l-0.3-38.1h0.2l23.5,38.1H304.6z
+ M376.4,47.2c0-18.7-13.5-30.5-31.8-30.5c-18.2,0-31.7,11.8-31.7,30.5c0,18.4,13.5,31,31.7,31C362.9,78.2,376.4,65.7,376.4,47.2z
+ M361.3,47.2c0,10.5-6.9,18.1-16.7,18.1c-9.8,0-16.6-7.6-16.6-18.1c0-10.2,6.8-17.8,16.6-17.8C354.5,29.4,361.3,37,361.3,47.2z
+ M425.3,30.3v-12h-47v12h16.5v46.3h14.1V30.3H425.3z M238.2,142.8l-15.2-25c7.5-2.3,12.1-7.9,12.1-15.7c0-13.3-11.1-17.6-22.3-17.6
+ h-22.2v58.3h13.8v-23.1h4.8l12.6,23.1H238.2z M221.2,102.4c0,5.9-5.7,7.1-10.2,7.1h-6.7V95.9h7.5C216,95.9,221.2,97,221.2,102.4z
+ M284.8,142.8v-12h-27.1v-12.1h24.2v-11.3h-24.2v-11h25.6V84.5h-39.2v58.3H284.8z M333.7,90.2c-5.1-4.7-12.5-7.2-19.1-7.2
+ c-10.9,0-22.6,5.4-22.6,18.3c0,10.5,7.5,14.3,14.9,16.7c7.7,2.5,12.1,3.9,12.1,8.3c0,4.7-3.8,6.3-8.1,6.3c-4.6,0-9.8-2.6-12.6-6.2
+ l-9.2,9.4c5.1,5.4,13.5,8.4,21.8,8.4c11.5,0,22.3-6,22.3-19.4c0-11.6-10.2-15-18.1-17.5c-5.5-1.7-9-3-9-6.8c0-4.6,4.5-5.8,8.2-5.8
+ c3.6,0,8,2,10.4,5L333.7,90.2z M401.5,113.4c0-18.7-13.5-30.5-31.8-30.5c-18.2,0-31.7,11.8-31.7,30.5c0,18.4,13.5,31,31.7,31
+ C388,144.4,401.5,131.9,401.5,113.4z M386.5,113.4c0,10.5-6.9,18.1-16.7,18.1c-9.8,0-16.6-7.6-16.6-18.1c0-10.2,6.8-17.8,16.6-17.8
+ S386.5,103.2,386.5,113.4z M446.6,142.8v-12.3H424v-46h-14.2v58.3H446.6z M498.2,84.5h-15.6l-13.4,41.3h-0.3l-13.5-41.3h-15.8
+ l22.1,58.3h14.1L498.2,84.5z M543.3,142.8v-12h-27.1v-12.1h24.2v-11.3h-24.2v-11h25.6V84.5h-39.2v58.3H543.3z M600,142.8l-15.2-25
+ c7.5-2.3,12.1-7.9,12.1-15.7c0-13.3-11.1-17.6-22.3-17.6h-22.2v58.3h13.8v-23.1h4.8l12.6,23.1H600z M583,102.4
+ c0,5.9-5.7,7.1-10.2,7.1h-6.7V95.9h7.5C577.8,95.9,583,97,583,102.4z"/>
+</svg>
diff --git a/doc/build.rst b/doc/build.rst
new file mode 100644
index 0000000..09b314d
--- /dev/null
+++ b/doc/build.rst
@@ -0,0 +1,291 @@
+.. SPDX-License-Identifier: GPL-3.0-or-later
+
+.. _build:
+
+Building from sources
+=====================
+
+.. note:: Latest up-to-date packages for various distribution can be obtained
+ from web `<https://knot-resolver.cz/download/>`_.
+
+Knot Resolver is written for UNIX-like systems using modern C standards.
+Beware that some 64-bit systems with LuaJIT 2.1 may be affected by
+`a problem <https://github.com/LuaJIT/LuaJIT/blob/v2.1.0-beta3/doc/status.html#L100>`_
+-- Linux on x86_64 is unaffected but `Linux on aarch64 is
+<https://gitlab.nic.cz/knot/knot-resolver/issues/216>`_.
+
+.. code-block:: bash
+
+ $ git clone --recursive https://gitlab.nic.cz/knot/knot-resolver.git
+
+Dependencies
+------------
+
+.. note:: This section lists basic requirements. Individual modules
+ might have additional build or runtime dependencies.
+
+The following dependencies are needed to build and run Knot Resolver:
+
+.. csv-table::
+ :header: "Requirement", "Notes"
+
+ "ninja", "*build only*"
+ "meson >= 0.49", "*build only* [#]_"
+ "C and C++ compiler", "*build only* [#]_"
+ "`pkg-config`_", "*build only* [#]_"
+ "libknot_ 3.0.2+", "Knot DNS libraries"
+ "LuaJIT_ 2.0+", "Embedded scripting language"
+ "libuv_ 1.7+", "Multiplatform I/O and services"
+ "lmdb", "Memory-mapped database for cache"
+ "GnuTLS", "TLS"
+
+There are also *optional* packages that enable specific functionality in Knot
+Resolver:
+
+.. TODO cqueues is really used on multiple places, sometimes indirectly
+
+.. csv-table::
+ :header: "Optional", "Needed for", "Notes"
+
+ "jemalloc_", "``daemon``", "Improve long-term memory consumption."
+ "nghttp2_", "``daemon``", "DNS over HTTPS support."
+ "libsystemd_", "``daemon``", "Systemd watchdog support."
+ "`libcap-ng`_", "``daemon``", "Linux capabilities: support dropping them."
+ "`lua-basexx`_", "``config tests``", "Number base encoding/decoding for Lua."
+ "`lua-http`_", "``modules/http``", "HTTP/2 client/server for Lua."
+ "`lua-cqueues`_", "some lua modules", ""
+ "cmocka_", "``unit tests``", "Unit testing framework."
+ "dnsdist_", "``proxyv2 test``", "DNS proxy server"
+ "Doxygen_", "``documentation``", "Generating API documentation."
+ "Sphinx_ and sphinx_rtd_theme_", "``documentation``", "Building this
+ documentation."
+ "Texinfo_", "``documentation``", "Generating this documentation in Info
+ format."
+ "breathe_", "``documentation``", "Exposing Doxygen API doc to Sphinx."
+ "libprotobuf_ 3.0+", "``modules/dnstap``", "Protocol Buffers support for
+ dnstap_."
+ "`libprotobuf-c`_ 1.0+", "``modules/dnstap``", "C bindings for Protobuf."
+ "libfstrm_ 0.2+", "``modules/dnstap``", "Frame Streams data transport
+ protocol."
+ "luacheck_", "``lint-lua``", "Syntax and static analysis checker for Lua."
+ "`clang-tidy`_", "``lint-c``", "Syntax and static analysis checker for C."
+ "luacov_", "``check-config``", "Code coverage analysis for Lua modules."
+
+.. [#] If ``meson >= 0.49`` isn't available for your distro, check backports
+ repository or use python pip to install it.
+.. [#] Requires ``__attribute__((cleanup))`` and ``-MMD -MP`` for
+ dependency file generation. We test GCC and Clang, and ICC is likely to work as well.
+.. [#] You can use variables ``<dependency>_CFLAGS`` and ``<dependency>_LIBS``
+ to configure dependencies manually (i.e. ``libknot_CFLAGS`` and
+ ``libknot_LIBS``).
+
+Packaged dependencies
+~~~~~~~~~~~~~~~~~~~~~
+
+.. note:: Some build dependencies can be found in
+ `home:CZ-NIC:knot-resolver-build
+ <https://build.opensuse.org/project/show/home:CZ-NIC:knot-resolver-build>`_.
+
+On reasonably new systems most of the dependencies can be resolved from packages,
+here's an overview for several platforms.
+
+* **Debian/Ubuntu** - Current stable doesn't have new enough Meson
+ and libknot. Use repository above or build them yourself. Fresh list of dependencies can be found in `Debian control file in our repo <https://gitlab.nic.cz/knot/knot-resolver/blob/master/distro/deb/control>`_, search for "Build-Depends".
+
+* **CentOS/Fedora/RHEL/openSUSE** - Fresh list of dependencies can be found in `RPM spec file in our repo <https://gitlab.nic.cz/knot/knot-resolver/blob/master/distro/rpm/knot-resolver.spec>`_, search for "BuildRequires".
+
+* **FreeBSD** - when installing from ports, all dependencies will install
+ automatically, corresponding to the selected options.
+* **Mac OS X** - the dependencies can be obtained from `Homebrew formula <https://formulae.brew.sh/formula/knot-resolver>`_.
+
+Compilation
+-----------
+
+.. note::
+
+ Knot Resolver uses `Meson Build system <https://mesonbuild.com/>`_.
+ Shell snippets below should be sufficient for basic usage
+ but users unfamiliar with Meson Build might want to read introductory
+ article `Using Meson <https://mesonbuild.com/Quick-guide.html>`_.
+
+Following example script will:
+
+ - create new build directory named ``build_dir``
+ - configure installation path ``/tmp/kr``
+ - enable static build (to allow installation to non-standard path)
+ - build Knot Resolver
+ - install it into the previously configured path
+
+.. code-block:: bash
+
+ $ meson setup build_dir --prefix=/tmp/kr --default-library=static
+ $ ninja -C build_dir
+ $ ninja install -C build_dir
+
+At this point you can execute the newly installed binary using path ``/tmp/kr/sbin/kresd``.
+
+.. note:: When compiling on OS X, creating a shared library is currently not
+ possible when using luajit package from Homebrew due to `#37169
+ <https://github.com/Homebrew/homebrew-core/issues/37169>`_.
+
+Build options
+~~~~~~~~~~~~~
+
+It's possible to change the compilation with build options. These are useful to
+packagers or developers who wish to customize the daemon behaviour, run
+extended test suites etc. By default, these are all set to sensible values.
+
+For complete list of build options create a build directory and run:
+
+.. code-block:: bash
+
+ $ meson setup build_dir
+ $ meson configure build_dir
+
+To customize project build options, use ``-Doption=value`` when creating
+a build directory:
+
+.. code-block:: bash
+
+ $ meson setup build_dir -Ddoc=enabled
+
+... or change options in an already existing build directory:
+
+.. code-block:: bash
+
+ $ meson configure build_dir -Ddoc=enabled
+
+
+.. _build-custom-flags:
+
+Customizing compiler flags
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+If you'd like to use customize the build, see meson's `built-in options
+<https://mesonbuild.com/Builtin-options.html>`_. For hardening, see ``b_pie``.
+
+For complete control over the build flags, use ``--buildtype=plain`` and set
+``CFLAGS``, ``LDFLAGS`` when creating the build directory with ``meson``
+command.
+
+.. include:: ../tests/README.rst
+
+.. _build-html-doc:
+
+Documentation
+-------------
+
+To check for documentation dependencies and allow its installation, use
+``-Ddoc=enabled``. The documentation doesn't build automatically. Instead,
+target ``doc`` must be called explicitly.
+
+.. code-block:: bash
+
+ $ meson configure build_dir -Ddoc=enabled
+ $ ninja -C build_dir doc
+
+Tarball
+-------
+
+Released tarballs are available from `<https://knot-resolver.cz/download/>`_
+
+To make a release tarball from git, use the following command. The
+
+.. code-block:: bash
+
+ $ ninja -C build_dir dist
+
+It's also possible to make a development snapshot tarball:
+
+.. code-block:: bash
+
+ $ ./scripts/make-archive.sh
+
+.. _packaging:
+
+Packaging
+---------
+
+Recommended build options for packagers:
+
+* ``--buildtype=release`` for default flags (optimization, asserts, ...). For complete control over flags, use ``plain`` and see :ref:`build-custom-flags`.
+* ``--prefix=/usr`` to customize
+ prefix, other directories can be set in a similar fashion, see ``meson setup
+ --help``
+* ``-Dsystemd_files=enabled`` for systemd unit files
+* ``-Ddoc=enabled`` for offline documentation (see :ref:`build-html-doc`)
+* ``-Dinstall_kresd_conf=enabled`` to install default config file
+* ``-Dclient=enabled`` to force build of kresc
+* ``-Dunit_tests=enabled`` to force build of unit tests
+
+Systemd
+~~~~~~~
+
+It's recommended to use the upstream system unit files. If any customizations
+are required, drop-in files should be used, instead of patching/changing the
+unit files themselves.
+
+To install systemd unit files, use the ``-Dsystemd_files=enabled`` build option.
+
+To support enabling services after boot, you must also link ``kresd.target`` to
+``multi-user.target.wants``:
+
+.. code-block:: bash
+
+ ln -s ../kresd.target /usr/lib/systemd/system/multi-user.target.wants/kresd.target
+
+Trust anchors
+~~~~~~~~~~~~~
+
+If the target distro has externally managed (read-only) DNSSEC trust anchors
+or root hints use this:
+
+* ``-Dkeyfile_default=/usr/share/dns/root.key``
+* ``-Droot_hints=/usr/share/dns/root.hints``
+* ``-Dmanaged_ta=disabled``
+
+In case you want to have automatically managed DNSSEC trust anchors instead,
+set ``-Dmanaged_ta=enabled`` and make sure both ``keyfile_default`` file and
+its parent directories are writable by kresd process (after package installation!).
+
+Docker image
+------------
+
+Visit `hub.docker.com/r/cznic/knot-resolver
+<https://hub.docker.com/r/cznic/knot-resolver/>`_ for instructions how to run
+the container.
+
+For development, it's possible to build the container directly from your git tree:
+
+.. code-block:: bash
+
+ $ docker build -t knot-resolver .
+
+
+.. _jemalloc: https://jemalloc.net
+.. _libuv: https://github.com/libuv/libuv
+.. _LuaJIT: http://luajit.org/luajit.html
+.. _Doxygen: https://www.doxygen.nl/manual/index.html
+.. _breathe: https://github.com/michaeljones/breathe
+.. _Sphinx: http://sphinx-doc.org/
+.. _sphinx_rtd_theme: https://pypi.python.org/pypi/sphinx_rtd_theme
+.. _Texinfo: https://www.gnu.org/software/texinfo/
+.. _pkg-config: https://www.freedesktop.org/wiki/Software/pkg-config/
+.. _libknot: https://gitlab.nic.cz/knot/knot-dns
+.. _cmocka: https://cmocka.org/
+.. _dnsdist: https://dnsdist.org/
+.. _lua-basexx: https://github.com/aiq/basexx
+.. _lua-http: https://luarocks.org/modules/daurnimator/http
+.. _lua-cqueues: https://25thandclement.com/~william/projects/cqueues.html
+.. _deckard: https://gitlab.nic.cz/knot/deckard
+.. _nghttp2: https://nghttp2.org/
+.. _libsystemd: https://www.freedesktop.org/wiki/Software/systemd/
+.. _`libcap-ng`: https://people.redhat.com/sgrubb/libcap-ng/
+.. _dnstap: http://dnstap.info/
+.. _libprotobuf: https://developers.google.com/protocol-buffers/
+.. _libprotobuf-c: https://github.com/protobuf-c/protobuf-c/wiki
+.. _libfstrm: https://github.com/farsightsec/fstrm
+.. _luacheck: http://luacheck.readthedocs.io
+.. _clang-tidy: http://clang.llvm.org/extra/clang-tidy/index.html
+.. _luacov: https://lunarmodules.github.io/luacov/
+.. _lcov: http://ltp.sourceforge.net/coverage/lcov.php
diff --git a/doc/conf.py b/doc/conf.py
new file mode 100644
index 0000000..53e5e38
--- /dev/null
+++ b/doc/conf.py
@@ -0,0 +1,95 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+# -*- coding: utf-8 -*-
+
+import os
+import re
+import subprocess
+
+import sphinx_rtd_theme
+
+# -- General configuration -----------------------------------------------------
+
+if os.environ.get('READTHEDOCS', None) == 'True':
+ subprocess.call('doxygen')
+
+# Add any Sphinx extension module names here, as strings.
+extensions = ['sphinx.ext.todo', 'sphinx.ext.viewcode', 'breathe']
+
+# Breathe configuration
+breathe_projects = {"libkres": "doxyxml"}
+breathe_default_project = "libkres"
+breathe_domain_by_extension = {"h": "c"}
+
+# The suffix of source filenames.
+source_suffix = '.rst'
+master_doc = 'index'
+
+# General information about the project.
+project = u'Knot Resolver'
+copyright = u'CZ.NIC labs'
+with open('../meson.build') as f:
+ for line in f:
+ match = re.match(r"\s*version\s*:\s*'([^']+)'.*", line)
+ if match is not None:
+ version = match.groups()[0]
+release = version
+
+# List of patterns, relative to source directory, that match files and
+# directories to ignore when looking for source files.
+exclude_patterns = ['_build']
+
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = 'sphinx'
+highlight_language = 'c'
+primary_domain = 'py'
+
+# -- Options for HTML output ---------------------------------------------------
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+html_static_path = ['_static']
+
+# Output file base name for HTML help builder.
+htmlhelp_basename = 'apidoc'
+
+# Theme
+html_theme = 'sphinx_rtd_theme'
+html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]
+
+html_theme_options = {
+ 'logo_only': True, # if we have a html_logo below, this shows only the logo with no title text
+ # ToC options
+ 'collapse_navigation': False,
+ 'sticky_navigation': True,
+}
+html_logo = '_static/logo-negativ.svg'
+html_style = 'css/custom.css'
+
+# -- Options for LaTeX output --------------------------------------------------
+
+# Grouping the document tree into LaTeX files. List of tuples
+# (source start file, target name, title, author, documentclass [howto/manual]).
+latex_documents = [
+ ('index', 'format.tex', u'Knot Resolver',
+ u'CZ.NIC Labs', 'manual'),
+]
+
+# -- Options for manual page output --------------------------------------------
+
+# One entry per manual page. List of tuples
+# (source start file, name, description, authors, manual section).
+man_pages = [
+ ('index', 'libkres', u'libkres documentation',
+ [u'CZ.NIC Labs'], 1)
+]
+
+# -- Options for Texinfo output ------------------------------------------------
+
+# Grouping the document tree into Texinfo files. List of tuples
+# (source start file, target name, title, author,
+# dir menu entry, description, category)
+texinfo_documents = [
+ ('index', 'knot-resolver', u'Knot Resolver', u'CZ.NIC Labs',
+ 'Knot Resolver', 'Caching DNS resolver.', 'Network services'),
+]
diff --git a/doc/config-answer-reordering.rst b/doc/config-answer-reordering.rst
new file mode 100644
index 0000000..624e7d4
--- /dev/null
+++ b/doc/config-answer-reordering.rst
@@ -0,0 +1,17 @@
+.. SPDX-License-Identifier: GPL-3.0-or-later
+
+Answer reordering
+=================
+Certain clients are "dumb" and always connect to first IP address or name found
+in a DNS answer received from resolver instead of picking randomly.
+As a workaround for such broken clients it is possible to randomize
+order of records in DNS answers sent by resolver:
+
+.. function:: reorder_RR([true | false])
+
+ :param boolean new_value: ``true`` to enable or ``false`` to disable randomization *(optional)*
+ :return: The (new) value of the option
+
+ If set, resolver will vary the order of resource records within RR sets.
+ It is enabled by default since 5.3.0.
+
diff --git a/doc/config-debugging.rst b/doc/config-debugging.rst
new file mode 100644
index 0000000..520c2db
--- /dev/null
+++ b/doc/config-debugging.rst
@@ -0,0 +1,35 @@
+.. SPDX-License-Identifier: GPL-3.0-or-later
+
+Debugging options
+=================
+
+In case the resolver crashes, it is often helpful to collect a coredump from
+the crashed process. Configuring the system to collect coredump from crashed
+process is out of the scope of this documentation, but some tips can be found
+`here <https://lists.nic.cz/hyperkitty/list/knot-resolver-users@lists.nic.cz/message/GUHW4JSDXZ6SZUAYYQ3U2WWOZEIVVF2S/>`_.
+
+Kresd uses its own mechanism for assertions. They are checks that should always
+pass and indicate some weird or unexpected state if they don't. In such cases,
+they show up in the log as errors. By default, the process recovers from those
+states if possible, but the behaviour can be changed with the following options
+to aid further debugging.
+
+.. envvar:: debugging.assertion_abort = false|true
+
+ :return: boolean (default: false in meson's release mode, true otherwise)
+
+ Allow the process to be aborted in case it encounters a failed assertion.
+ (Some critical conditions always lead to abortion, regardless of settings.)
+
+.. envvar:: debugging.assertion_fork = milliseconds
+
+ :return: int (default: 5 minutes in meson's release mode, 0 otherwise)
+
+ If a process should be aborted, it can be done in two ways. When this is
+ set to nonzero (default), a child is forked and aborted to obtain a coredump,
+ while the parent process recovers and keeps running. This can be useful to
+ debug a rare issue that occurs in production, since it doesn't affect the
+ main process.
+
+ As the dumping can be costly, the value is a lower bound on delay between
+ consecutive coredumps of each process. It is randomized by +-25% each time.
diff --git a/doc/config-dnssec.rst b/doc/config-dnssec.rst
new file mode 100644
index 0000000..f20e2b3
--- /dev/null
+++ b/doc/config-dnssec.rst
@@ -0,0 +1,17 @@
+.. SPDX-License-Identifier: GPL-3.0-or-later
+
+.. _dnssec-config:
+
+*************************
+DNSSEC, data verification
+*************************
+
+Good news! Knot Resolver uses secure configuration by default, and this configuration
+should not be changed unless absolutely necessary, so feel free to skip over this section.
+
+.. include:: ../daemon/lua/trust_anchors.rst
+
+DNSSEC is main technology to protect data, but it is also possible to change how strictly
+resolver checks data from insecure DNS zones:
+
+.. include:: ../lib/layer/mode.rst
diff --git a/doc/config-experimental.rst b/doc/config-experimental.rst
new file mode 100644
index 0000000..f709c1c
--- /dev/null
+++ b/doc/config-experimental.rst
@@ -0,0 +1,14 @@
+.. SPDX-License-Identifier: GPL-3.0-or-later
+
+*********************
+Experimental features
+*********************
+
+Following functionality and APIs are in continuous development.
+Features in this section may changed, replaced or dropped in any release.
+
+.. toctree::
+ :maxdepth: 1
+
+ daemon-scripting
+ modules-experimental_dot_auth
diff --git a/doc/config-logging-header.rst b/doc/config-logging-header.rst
new file mode 100644
index 0000000..551b1be
--- /dev/null
+++ b/doc/config-logging-header.rst
@@ -0,0 +1,9 @@
+.. SPDX-License-Identifier: GPL-3.0-or-later
+
+Logging API
+===========
+
+.. _config_log_groups:
+
+.. doxygenfile:: lib/log.h
+ :project: libkres
diff --git a/doc/config-logging-monitoring.rst b/doc/config-logging-monitoring.rst
new file mode 100644
index 0000000..8a2a25b
--- /dev/null
+++ b/doc/config-logging-monitoring.rst
@@ -0,0 +1,101 @@
+.. SPDX-License-Identifier: GPL-3.0-or-later
+
+********************************
+Logging, monitoring, diagnostics
+********************************
+
+To read service logs use commands usual for your distribution.
+E.g. on distributions using systemd-journald use command ``journalctl -u kresd@* -f``.
+
+Knot Resolver supports 6 logging levels - ``crit``, ``err``, ``warning``,
+``notice``, ``info``, ``debug``. All levels with the same meaning as is defined
+in ``syslog.h``. It is possible change logging level using
+:func:`log_level` function.
+
+.. code-block:: lua
+
+ log_level('debug') -- too verbose for normal usage
+
+Logging level ``notice`` is set after start by default,
+so logs from Knot Resolver should contain only couple lines a day.
+For debugging purposes it is possible to use the very verbose ``debug`` level,
+but that is generally not usable unless restricted in some way (see below).
+
+In addition to levels, logging is also divided into the
+:ref:`groups <config_log_groups>`. All groups
+are logged by default, but you can enable ``debug`` level for selected groups using
+:func:`log_groups` function. Other groups are logged to the log level
+set by :func:`log_level`.
+
+It is also possible to enable ``debug`` logging level for particular requests,
+with :ref:`policies <mod-policy-logging>` or as :ref:`an HTTP service <mod-http-trace>`.
+
+Less verbose logging for DNSSEC validation errors can be enabled by using :ref:`mod-bogus_log` module.
+
+.. py:function:: log_level([level])
+
+ :param: string ``'crit'``, ``'err'``, ``'warning'``, ``'notice'``,
+ ``'info'`` or ``'debug'``
+ :return: string Current logging level.
+
+ Pass a string to set the global logging level.
+
+ .. py:function:: verbose([true | false])
+
+ .. deprecated:: 5.4.0
+ Use :func:`log_level` instead.
+
+ :param: ``true`` enable ``debug`` level, ``false`` switch to default level (``notice``).
+ :return: boolean ``true`` when ``debug`` level is enabled.
+
+ Toggle between ``debug`` and ``notice`` log level. Use only for debugging purposes.
+ On busy systems verbose logging can produce several MB of logs per
+ second and will slow down operation.
+
+.. py:function:: log_target(target)
+
+ :param: string ``'syslog'``, ``'stderr'``, ``'stdout'``
+ :return: string Current logging target.
+
+ Knot Resolver logs to standard error stream by default,
+ but typical systemd units change that to ``'syslog'``.
+ That setting logs directly through systemd's facilities
+ (if available) to preserve more meta-data.
+
+.. py:function:: log_groups([table])
+
+ :param: table of string(s) representing :ref:`log groups <config_log_groups>`
+ :return: table of string with currently set log groups
+
+ Use to turn-on debug logging for the selected groups regardless of the global
+ log level. Calling with no argument lists the currently active log groups. To
+ remove all log groups, call the function with an empty table.
+
+ .. code-block:: lua
+
+ log_groups({'io', 'tls'} -- turn on debug logging for io and tls groups
+ log_groups() -- list active log groups
+ log_groups({}) -- remove all log groups
+
+Various statistics for monitoring purposes are available in :ref:`mod-stats` module, including export to central systems like Graphite, Metronome, InfluxDB, or Prometheus format.
+
+Resolver :ref:`mod-watchdog` is tool to detect and recover from potential bugs that cause the resolver to stop responding properly to queries.
+
+Additional monitoring and debugging methods are described below. If none of these options fits your deployment or if you have special needs you can configure your own checks and exports using :ref:`async-events`.
+
+.. toctree::
+ :maxdepth: 1
+
+ modules-bogus_log
+ modules-stats
+ daemon-bindings-worker
+ modules-nsid
+ modules-http-trace
+ modules-watchdog
+ modules-dnstap
+ modules-ta_sentinel
+ modules-ta_signal_query
+ modules-detect_time_skew
+ modules-detect_time_jump
+ config-debugging
+ config-logging-header
diff --git a/doc/config-network-forwarding.rst b/doc/config-network-forwarding.rst
new file mode 100644
index 0000000..1da0997
--- /dev/null
+++ b/doc/config-network-forwarding.rst
@@ -0,0 +1,38 @@
+.. SPDX-License-Identifier: GPL-3.0-or-later
+
+Forwarding
+----------
+
+*Forwarding* configuration instructs resolver to forward cache-miss queries from clients to manually specified DNS resolvers *(upstream servers)*. In other words the *forwarding* mode does exact opposite of the default *recursive* mode because resolver in *recursive* mode automatically selects which servers to ask.
+
+Main use-cases are:
+
+ - Building a tree structure of DNS resolvers to improve performance (by improving cache hit rate).
+ - Accessing domains which are not available using recursion (e.g. if internal company servers return different answers than public ones).
+ - Forwarding through a central DNS traffic filter.
+
+Forwarding implementation in Knot Resolver has following properties:
+
+ - Answers from *upstream* servers are cached.
+ - Answers from *upstream* servers are locally DNSSEC-validated, unless :func:`policy.STUB` is used.
+ - Resolver automatically selects which IP address from given set of IP addresses will be used (based on performance characteristics).
+ - Forwarding can use either unencrypted DNS protocol, or :ref:`tls-forwarding`.
+
+.. warning::
+
+ We strongly discourage use of "fake top-level domains" like ``corp.`` because these made-up domains are indistinguishable from an attack, so DNSSEC validation will prevent such domains from working. If you *really* need a variant of forwarding which does not DNSSEC-validate received data please see chapter :ref:`dns-graft`. In long-term it is better to migrate data into a legitimate, properly delegated domains which do not suffer from these security problems.
+
+
+Simple examples for **unencrypted** forwarding:
+
+.. code-block:: lua
+
+ -- forward all traffic to specified IP addresses (selected automatically)
+ policy.add(policy.all(policy.FORWARD({'2001:db8::1', '192.0.2.1'})))
+
+ -- forward only queries for names under domain example.com to a single IP address
+ policy.add(policy.suffix(policy.FORWARD('192.0.2.1'), {todname('example.com.')}))
+
+To configure encrypted version please see chapter :ref:`tls-forwarding`.
+
+Forwarding is documented in depth together with rest of :ref:`mod-policy`.
diff --git a/doc/config-network.rst b/doc/config-network.rst
new file mode 100644
index 0000000..2faac0e
--- /dev/null
+++ b/doc/config-network.rst
@@ -0,0 +1,64 @@
+.. SPDX-License-Identifier: GPL-3.0-or-later
+
+.. _network-configuration:
+
+************************
+Networking and protocols
+************************
+
+This section describes configuration of network interfaces
+and protocols. Please keep in mind that DNS resolvers act
+as *DNS server* and *DNS client* at the same time,
+and that these roles require different configuration.
+
+This picture illustrates different actors involved DNS resolution process,
+supported protocols, and clarifies what we call *server configuration*
+and *client configuration*.
+
+.. image:: server_terminology.svg
+
+*Attribution: Icons by Bernar Novalyi from the Noun Project*
+
+For *resolver's clients* the resolver itself acts as a DNS server.
+
+After receiving a query the resolver will attempt to find
+answer in its cache. If the data requested by resolver's
+client is not available in resolver's cache (so-called *cache-miss*)
+the resolver will attempt to obtain the data from servers *upstream*
+(closer to the source of information), so at this point the resolver
+itself acts like a DNS client and will send DNS query to other servers.
+
+By default the Knot Resolver works in recursive mode, i.e.
+the resolver will contact authoritative servers on the Internet.
+Optionally it can be configured in forwarding mode,
+where cache-miss queries are *forwarded to another DNS resolver*
+for processing.
+
+Server (communication with clients)
+===================================
+
+.. toctree::
+ :maxdepth: 2
+
+ daemon-bindings-net_server
+ daemon-bindings-net_tlssrv
+ modules-http
+
+Client (retrieving answers from servers)
+========================================
+
+Following chapters describe basic configuration of how resolver retrieves data from other *(upstream)* servers. Data processing is also affected by configured policies, see chapter :ref:`policies` for more advanced usage.
+
+.. toctree::
+ :maxdepth: 2
+
+ daemon-bindings-net_client
+ config-network-forwarding
+
+DNS protocol tweaks
+===================
+
+.. toctree::
+ :maxdepth: 2
+
+ daemon-bindings-net_dns_tweaks
diff --git a/doc/config-no-systemd-privileges.rst b/doc/config-no-systemd-privileges.rst
new file mode 100644
index 0000000..e2c2ab9
--- /dev/null
+++ b/doc/config-no-systemd-privileges.rst
@@ -0,0 +1,65 @@
+.. SPDX-License-Identifier: GPL-3.0-or-later
+
+Privileges and capabilities
+===========================
+
+The kresd daemon requires privileges when it is configured to bind to
+well-known ports. There are multiple ways to achieve this.
+
+Using capabilities
+^^^^^^^^^^^^^^^^^^
+
+The most secure and recommended way is to use capabilities and execute kresd as
+an unprivileged user.
+
+* ``CAP_NET_BIND_SERVICE`` is required to bind to well-known ports.
+* ``CAP_SETPCAP`` when this capability is available, kresd drops any extra
+ capabilities after the daemon successfully starts when running as
+ a non-root user.
+
+Running as non-privileged user
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Another possibility is to start the process as privileged user and then switch
+to a non-privileged user after binding to network interfaces.
+
+.. function:: user(name, [group])
+
+ :param string name: user name
+ :param string group: group name (optional)
+ :return: boolean
+
+ Drop privileges and start running as given user (and group, if provided).
+
+ .. tip:: Note that you should bind to required network addresses before
+ changing user. At the same time, you should open the cache **AFTER** you
+ change the user (so it remains accessible). A good practice is to divide
+ configuration in two parts:
+
+ .. code-block:: lua
+
+ -- privileged
+ net.listen('127.0.0.1')
+ net.listen('::1')
+ user('knot-resolver', 'netgrp')
+ -- unprivileged
+ cache.size = 100*MB
+
+ Example output:
+
+ .. code-block:: lua
+
+ > user('baduser')
+ invalid user name
+ > user('knot-resolver', 'netgrp')
+ true
+ > user('root')
+ Operation not permitted
+
+Running as root
+^^^^^^^^^^^^^^^
+
+.. warning:: Executing processes as root is generally insecure, as these
+ processes have unconstrained access to the complete system at runtime.
+
+While not recommended, it is also possible to run kresd directly as root.
diff --git a/doc/config-no-systemd-processes.rst b/doc/config-no-systemd-processes.rst
new file mode 100644
index 0000000..59aed1b
--- /dev/null
+++ b/doc/config-no-systemd-processes.rst
@@ -0,0 +1,25 @@
+.. SPDX-License-Identifier: GPL-3.0-or-later
+
+Process management
+==================
+
+There following should be taken into consideration when running without systemd:
+
+* To utilize multiple CPUs, kresd has to be executed as several independent
+ processes.
+* Maintenance daemon(s) have to be executed separately.
+* If a process crashes, it might be useful to restart it.
+* Using some mechanism similar to :ref:`mod-watchdog` might be desirable to
+ recover in case a process becomes unresponsive.
+
+Please note, systemd isn't the only process manager and other solutions exist,
+such as supervisord_. Configuring these is out of the scope of this
+document. Please refer to their respective documentations.
+
+It is also possible to use kresd without any process management at all, which
+may be suitable for some purposes (such as low-traffic local / home network resolver,
+testing, development or debugging).
+
+.. include:: ../utils/cache_gc/README.rst
+
+.. _`supervisord`: http://supervisord.org/
diff --git a/doc/config-no-systemd.rst b/doc/config-no-systemd.rst
new file mode 100644
index 0000000..a8cbb09
--- /dev/null
+++ b/doc/config-no-systemd.rst
@@ -0,0 +1,37 @@
+.. SPDX-License-Identifier: GPL-3.0-or-later
+
+.. _usage-without-systemd:
+
+*********************
+Usage without systemd
+*********************
+
+.. tip:: Our upstream packages use systemd integration, which is the recommended
+ way to run kresd. This section is only relevant if you choose to use kresd
+ without systemd integration.
+
+Knot Resolver is designed to be a single process without the use of threads.
+While the cache is shared, the individual processes are independent. This
+approach has several benefits, but it also comes with a few downsides, in
+particular:
+
+* Without the use of threads or forking (deprecated, see `#529`_), multiple
+ processes aren't managed in any way by kresd.
+* There is no maintenance thread and these tasks have to be handled by separate
+ daemon(s) (such as :ref:`garbage-collector`).
+
+To offset these these disadvantages without implementing process management in
+kresd (and reinventing the wheel), Knot Resolver provides integration with
+systemd, which is widely used across GNU/Linux distributions.
+
+If your use-case doesn't support systemd (e.g. using macOS, FreeBSD, Docker,
+OpenWrt, Turris), this section describes the differences and things to keep in
+mind when configuring and running kresd without systemd integration.
+
+.. toctree::
+ :maxdepth: 2
+
+ config-no-systemd-processes
+ config-no-systemd-privileges
+
+.. _`#529`: https://gitlab.nic.cz/knot/knot-resolver/issues/529
diff --git a/doc/config-overview.rst b/doc/config-overview.rst
new file mode 100644
index 0000000..0aec51c
--- /dev/null
+++ b/doc/config-overview.rst
@@ -0,0 +1,98 @@
+.. SPDX-License-Identifier: GPL-3.0-or-later
+
+**********************
+Configuration Overview
+**********************
+
+Configuration file is named ``/etc/knot-resolver/kresd.conf`` and is read when
+you execute Knot Resolver using systemd commands described in section
+:ref:`quickstart-startup`. [#]_
+
+.. _config-syntax:
+
+Syntax
+======
+
+The configuration file syntax allows you to specify different kinds of data:
+
+ - ``group.option = 123456``
+ - ``group.option = "string value"``
+ - ``group.command(123456, "string value")``
+ - ``group.command({ key1 = "value1", key2 = 222, key3 = "third value" })``
+ - ``globalcommand(a_parameter_1, a_parameter_2, a_parameter_3, etc)``
+ - ``-- any text after -- sign is ignored till end of line``
+
+Following **configuration file snippet** starts listening for unencrypted and also encrypted DNS queries on IP address 192.0.2.1, and sets cache size.
+
+.. code-block:: lua
+
+ -- this is a comment: listen for unencrypted queries
+ net.listen('192.0.2.1')
+ -- another comment: listen for queries encrypted using TLS on port 853
+ net.listen('192.0.2.1', 853, { kind = 'tls' })
+ -- 10 MB cache is suitable for a very small deployment
+ cache.size = 10 * MB
+
+.. tip::
+ When copy&pasting examples from this manual please pay close
+ attention to brackets and also line ordering - order of lines matters.
+
+ The configuration language is in fact Lua script, so you can use full power
+ of this programming language. See article
+ `Learn Lua in 15 minutes`_ for a syntax overview.
+
+When you modify configuration file on disk restart resolver process to get
+changes into effect. See chapter :ref:`systemd-zero-downtime-restarts` if even short
+outages are not acceptable for your deployment.
+
+.. [#] If you decide to run binary ``/usr/sbin/kresd`` manually (instead of
+ using systemd) do not forget to specify ``-c`` option with path to
+ configuration file, otherwise ``kresd`` will read file named ``config`` from
+ its current working directory.
+
+Documentation Conventions
+=========================
+
+Besides text configuration file, Knot Resolver also supports interactive and dynamic configuration using scripts or external systems, which is described in chapter :ref:`runtime-cfg`. Through this manual we present examples for both usage types - static configuration in a text file (see above) and also the interactive mode.
+
+The **interactive prompt** is denoted by ``>``, so all examples starting with ``>`` character are transcripts of user (or script) interaction with Knot Resolver and resolver's responses. For example:
+
+.. code-block:: lua
+
+ > -- this is a comment entered into interactive prompt
+ > -- comments have no effect here
+ > -- the next line shows a command entered interactively and its output
+ > log_level()
+ 'notice'
+ > -- the previous line without > character is output from log_level() command
+
+Following example demonstrates how to interactively list all currently loaded modules, and includes multi-line output:
+
+.. code-block:: lua
+
+ > modules.list()
+ {
+ 'iterate',
+ 'validate',
+ 'cache',
+ 'ta_update',
+ 'ta_signal_query',
+ 'policy',
+ 'priming',
+ 'detect_time_skew',
+ 'detect_time_jump',
+ 'ta_sentinel',
+ 'edns_keepalive',
+ 'refuse_nord',
+ 'watchdog',
+ }
+
+
+Before we dive into configuring features, let us explain modularization basics.
+
+.. include:: ../daemon/bindings/modules.rst
+
+Now you know what configuration file to modify, how to read examples and what modules are so you are ready for a real configuration work!
+
+.. _`Learn Lua in 15 minutes`: http://tylerneylon.com/a/learn-lua/
+
diff --git a/doc/config-performance.rst b/doc/config-performance.rst
new file mode 100644
index 0000000..9df0f93
--- /dev/null
+++ b/doc/config-performance.rst
@@ -0,0 +1,36 @@
+.. SPDX-License-Identifier: GPL-3.0-or-later
+
+.. _performance:
+
+**************************
+Performance and resiliency
+**************************
+
+For DNS resolvers, the most important parameter from performance perspective
+is cache hit rate, i.e. percentage of queries answered from resolver's cache.
+Generally the higher cache hit rate the better.
+
+Performance tunning should start with cache :ref:`cache_sizing`
+and :ref:`cache_persistence`.
+
+It is also recommended to run :ref:`systemd-multiple-instances` (even on a
+single machine!) because it allows to utilize multiple CPU threads and
+increases overall resiliency.
+
+Other features described in this section can be used for fine-tunning
+performance and resiliency of the resolver but generally have much smaller
+impact than cache settings and number of instances.
+
+.. toctree::
+ :maxdepth: 1
+
+ daemon-bindings-cache
+ systemd-multiinst
+ modules-predict
+ modules-prefill
+ modules-serve_stale
+ modules-rfc7706
+ modules-priming
+ modules-edns_keepalive
+ daemon-bindings-net_xdpsrv
+
diff --git a/doc/config-policy.rst b/doc/config-policy.rst
new file mode 100644
index 0000000..2b34a54
--- /dev/null
+++ b/doc/config-policy.rst
@@ -0,0 +1,41 @@
+.. SPDX-License-Identifier: GPL-3.0-or-later
+
+.. _policies:
+
+*****************************************
+Policy, access control, data manipulation
+*****************************************
+
+Features in this section allow to configure what clients can get access to what
+DNS data, i.e. DNS data filtering and manipulation.
+
+:ref:`mod-policy` specify global policies applicable to all requests,
+e.g. for blocking access to particular domain. :ref:`mod-view` allow
+to specify per-client policies, e.g. block or unblock access
+to a domain only for subset of clients.
+
+It is also possible to modify data returned to clients, either by providing
+:ref:`mod-hints` (answers with statically configured IP addresses),
+:ref:`mod-dns64` translation, or :ref:`mod-renumber`.
+
+Additional modules offer protection against various DNS-based attacks,
+see :ref:`mod-rebinding` and :ref:`mod-refuse_nord`.
+
+At the very end, module :ref:`mod-daf` provides HTTP API for run-time policy
+modification, and generally just offers different interface for previously
+mentioned features.
+
+
+.. toctree::
+ :maxdepth: 1
+
+ modules-policy
+ modules-view
+ modules-hints
+ modules-dns64
+ modules-renumber
+ config-answer-reordering
+ modules-rebinding
+ modules-refuse_nord
+ modules-daf
+
diff --git a/doc/daemon-bindings-cache.rst b/doc/daemon-bindings-cache.rst
new file mode 120000
index 0000000..d5d3ee7
--- /dev/null
+++ b/doc/daemon-bindings-cache.rst
@@ -0,0 +1 @@
+../daemon/bindings/cache.rst \ No newline at end of file
diff --git a/doc/daemon-bindings-net_client.rst b/doc/daemon-bindings-net_client.rst
new file mode 120000
index 0000000..c96fc76
--- /dev/null
+++ b/doc/daemon-bindings-net_client.rst
@@ -0,0 +1 @@
+../daemon/bindings/net_client.rst \ No newline at end of file
diff --git a/doc/daemon-bindings-net_dns_tweaks.rst b/doc/daemon-bindings-net_dns_tweaks.rst
new file mode 120000
index 0000000..ee7e98a
--- /dev/null
+++ b/doc/daemon-bindings-net_dns_tweaks.rst
@@ -0,0 +1 @@
+../daemon/bindings/net_dns_tweaks.rst \ No newline at end of file
diff --git a/doc/daemon-bindings-net_server.rst b/doc/daemon-bindings-net_server.rst
new file mode 120000
index 0000000..b6cf46c
--- /dev/null
+++ b/doc/daemon-bindings-net_server.rst
@@ -0,0 +1 @@
+../daemon/bindings/net_server.rst \ No newline at end of file
diff --git a/doc/daemon-bindings-net_tlssrv.rst b/doc/daemon-bindings-net_tlssrv.rst
new file mode 120000
index 0000000..2e38daa
--- /dev/null
+++ b/doc/daemon-bindings-net_tlssrv.rst
@@ -0,0 +1 @@
+../daemon/bindings/net_tlssrv.rst \ No newline at end of file
diff --git a/doc/daemon-bindings-net_xdpsrv.rst b/doc/daemon-bindings-net_xdpsrv.rst
new file mode 120000
index 0000000..da7870b
--- /dev/null
+++ b/doc/daemon-bindings-net_xdpsrv.rst
@@ -0,0 +1 @@
+../daemon/bindings/net_xdpsrv.rst \ No newline at end of file
diff --git a/doc/daemon-bindings-worker.rst b/doc/daemon-bindings-worker.rst
new file mode 120000
index 0000000..3ea3e61
--- /dev/null
+++ b/doc/daemon-bindings-worker.rst
@@ -0,0 +1 @@
+../daemon/bindings/worker.rst \ No newline at end of file
diff --git a/doc/daemon-scripting.rst b/doc/daemon-scripting.rst
new file mode 120000
index 0000000..482b759
--- /dev/null
+++ b/doc/daemon-scripting.rst
@@ -0,0 +1 @@
+../daemon/scripting.rst \ No newline at end of file
diff --git a/doc/flowcharts/io_and_worker.dia b/doc/flowcharts/io_and_worker.dia
new file mode 100644
index 0000000..8c5a755
--- /dev/null
+++ b/doc/flowcharts/io_and_worker.dia
Binary files differ
diff --git a/doc/flowcharts/task_ERD.dia b/doc/flowcharts/task_ERD.dia
new file mode 100644
index 0000000..2bc065b
--- /dev/null
+++ b/doc/flowcharts/task_ERD.dia
Binary files differ
diff --git a/doc/flowcharts/tcp_task.dia b/doc/flowcharts/tcp_task.dia
new file mode 100644
index 0000000..6ad58f3
--- /dev/null
+++ b/doc/flowcharts/tcp_task.dia
Binary files differ
diff --git a/doc/flowcharts/udp_task.dia b/doc/flowcharts/udp_task.dia
new file mode 100644
index 0000000..6fb8628
--- /dev/null
+++ b/doc/flowcharts/udp_task.dia
Binary files differ
diff --git a/doc/index.rst b/doc/index.rst
new file mode 100644
index 0000000..f5d9d42
--- /dev/null
+++ b/doc/index.rst
@@ -0,0 +1,63 @@
+.. SPDX-License-Identifier: GPL-3.0-or-later
+
+#############
+Knot Resolver
+#############
+
+Knot Resolver is a minimalistic implementation of a caching validating DNS resolver.
+Modular architecture keeps the core tiny and efficient,
+and it provides a state-machine like API for extensions.
+
+.. toctree::
+ :caption: Quick Start
+ :name: quickstart
+ :maxdepth: 1
+
+ quickstart-install
+ quickstart-startup
+ quickstart-config
+
+.. _configuration-chapter:
+
+.. toctree::
+ :caption: Configuration
+ :name: users
+ :maxdepth: 3
+
+ config-overview
+ config-network
+ config-performance
+ config-policy
+ config-logging-monitoring
+ config-dnssec
+ config-experimental
+ config-no-systemd
+
+.. _operation-chapter:
+
+.. toctree::
+ :caption: Operation
+ :maxdepth: 1
+
+ upgrading
+ NEWS
+
+.. toctree::
+ :caption: Developers
+ :name: developers
+ :maxdepth: 2
+
+ build
+ modules-http-custom-services
+ lib
+ modules_api
+ worker_api
+
+
+Indices and tables
+==================
+
+* :ref:`genindex`
+* :ref:`modindex`
+* :ref:`search`
+
diff --git a/doc/kresd.8.in b/doc/kresd.8.in
new file mode 100644
index 0000000..b052a5a
--- /dev/null
+++ b/doc/kresd.8.in
@@ -0,0 +1,122 @@
+.TH "kresd" "8" "@date@" "CZ.NIC" "Knot Resolver @version@"
+.\"
+.\" kresd.8 -- kresd daemon manpage
+.\"
+.\" Copyright (c) CZ.NIC. All rights reserved.
+.\"
+.\" SPDX-License-Identifier: GPL-3.0-or-later
+.\"
+.\"
+.SH "NAME"
+.B kresd
+\- full caching DNSSEC-enabled Knot Resolver @version@.
+.SH "SYNOPSIS"
+.B kresd
+.RB [ \-a | \-\-addr
+.IR addr[@port] ]
+.RB [ \-t | \-\-tls
+.IR addr[@port] ]
+.RB [ \-S | \-\-fd
+.IR fd ]
+.RB [ \-T | \-\-tlsfd
+.IR fd ]
+.RB [ \-c | \-\-config
+.IR config ]
+.RB [ \-n | \-\-noninteractive ]
+.RB [ \-q | \-\-quiet ]
+.RB [ \-v | \-\-verbose ]
+.RB [ \-V | \-\-version ]
+.RB [ \-h | \-\-help ]
+.IR [rundir]
+.SH "DESCRIPTION"
+.B Knot Resolver is a DNSSEC-enabled full caching resolver.
+.P
+Default mode of operation: when it receives a DNS query it iteratively
+asks authoritative nameservers starting from root zone (.) and ending
+with a nameservers authoritative for queried name. Automatic DNSSEC means
+verification of integrity of authoritative responses by following
+keys and signatures starting from root. Root trust anchor is automatically
+bootstrapped from IANA, or you can provide a file with root trust anchors
+(same format as Unbound or BIND9 root keys file).
+
+The daemon also caches intermediate answers into cache, which by default
+uses LMDB memory-mapped database. This has a significant advantage over
+in-memory caches as the process may be stopped and restarted without
+loss of cache entries. In multi-user scenario a shared cache
+is potential privacy/security issue, with kresd each user can have resolver cache
+in their private directory and use it in similar fashion to keychain.
+
+.P
+To use a locally running
+.B kresd
+for resolving put
+.sp
+.RS 6n
+nameserver 127.0.0.1
+.RE
+.sp
+into
+.IR resolv.conf (5)
+and start
+.B kresd
+
+.P
+The daemon may be configured also as a plain forwarder using query policies.
+This requires using a config file. Please refer to documentation for
+configuration file options. It is available at
+\fIhttps://knot-resolver.readthedocs.io\fR or in package documentation
+(available as knot-resolver-doc package in most distributions).
+
+The available CLI options are:
+.TP
+.B \-a\fI addr[@port]\fR, \fB\-\-addr=\fI<addr[@port]>
+Listen on given address (and port) pair. If no port is given, \fI53\fR is used as a default.
+Option may be passed multiple times to listen on more addresses.
+.TP
+.B \-t\fI addr[@port]\fR, \fB\-\-tls=\fI<addr[@port]>
+Listen using TLS on given address (and port) pair. If no port is
+given, \fI853\fR is used as a default. Option may be passed multiple
+times to listen on more addresses.
+.TP
+.B \-S\fI fd\fR, \fB\-\-fd=\fI<fd>
+Listen on given file descriptor(s), passed by supervisor.
+Option may be passed multiple times to listen on more file descriptors.
+.TP
+.B \-T\fI fd\fR, \-\-tlsfd=\fI<fd>
+Listen using TLS on given file descriptor(s), passed by supervisor.
+Option may be passed multiple times to listen on more file descriptors.
+.TP
+.B \-c\fI config\fR, \fB\-\-config=\fI<config>
+Set the config file with settings for kresd to read instead of reading the
+file at the default location (\fIconfig\fR).
+.TP
+.B \-f\fI N\fR, \fB\-\-forks=\fI<N>
+This option is deprecated since 5.0.0!
+
+With this option, the daemon is started in non-interactive mode and instead creates a
+UNIX socket in \fIrundir\fR that the operator can connect to for interactive session.
+A number greater than 1 forks the daemon N times, all forks will bind to same addresses
+and the kernel will load-balance between them on Linux with \fISO_REUSEPORT\fR support.
+
+If you want multiple concurrent processes supervised in this way,
+they should be supervised independently (see \fBkresd.systemd(7)\fR).
+.TP
+.B \-n\fR, \fB\-\-noninteractive
+Daemon will refrain from entering into read-eval-print loop for stdin+stdout.
+.TP
+.B \-q\fR, \fB\-\-quiet
+Daemon will refrain from printing the command prompt.
+.TP
+.B \-v\fR, \fB\-\-verbose
+Increase logging to debug level.
+.TP
+.B \-h
+Show short command-line option help.
+.TP
+.B \-V
+Show the version.
+.SH "SEE ALSO"
+@man_seealso_systemd@\fIhttps://knot-resolver.readthedocs.io/en/v@version@/\fR
+.SH "AUTHORS"
+.B kresd
+developers are mentioned in the AUTHORS file in the distribution.
diff --git a/doc/lib.rst b/doc/lib.rst
new file mode 100644
index 0000000..33e2ff3
--- /dev/null
+++ b/doc/lib.rst
@@ -0,0 +1,70 @@
+.. SPDX-License-Identifier: GPL-3.0-or-later
+
+.. _lib_index:
+
+.. include:: ../lib/README.rst
+
+API reference
+=============
+
+.. warning:: This section is generated with doxygen and breathe. Due to their
+ limitations, some symbols may be incorrectly described or missing entirely.
+ For exhaustive and accurate reference, refer to the header files instead.
+
+.. contents::
+ :depth: 1
+ :local:
+
+.. _lib_api_rplan:
+
+Name resolution
+---------------
+
+.. doxygenfile:: resolve.h
+ :project: libkres
+.. doxygenfile:: rplan.h
+ :project: libkres
+
+.. _lib_api_cache:
+
+Cache
+-----
+
+.. doxygenfile:: cache/api.h
+ :project: libkres
+
+.. doxygenfile:: cache/impl.h
+ :project: libkres
+
+.. _lib_api_nameservers:
+
+Nameservers
+-----------
+
+.. doxygenfile:: selection.h
+ :project: libkres
+.. doxygenfile:: zonecut.h
+ :project: libkres
+
+.. _lib_api_modules:
+
+Modules
+-------
+
+.. doxygenfile:: module.h
+ :project: libkres
+
+.. doxygenfile:: layer.h
+ :project: libkres
+
+Utilities
+---------
+
+.. doxygenfile:: utils.h
+ :project: libkres
+.. doxygenfile:: defines.h
+ :project: libkres
+
+.. _lib_generics:
+
+.. include:: ../lib/generic/README.rst
diff --git a/doc/meson.build b/doc/meson.build
new file mode 100644
index 0000000..72a8a7b
--- /dev/null
+++ b/doc/meson.build
@@ -0,0 +1,79 @@
+# documentation
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# man page
+man_config = configuration_data()
+man_config.set('version', meson.project_version())
+man_config.set('date', run_command('../scripts/get-date.sh', check: true).stdout())
+
+man_config.set('man_seealso_systemd', '')
+if systemd_files == 'enabled'
+ man_config.set('man_seealso_systemd', '\\fIkresd.systemd(7)\\fR, ')
+endif
+
+man_kresd = configure_file(
+ input: 'kresd.8.in',
+ output: 'kresd.8',
+ configuration: man_config,
+)
+install_man(man_kresd)
+
+
+# html and info documentation
+if get_option('doc') == 'enabled'
+ message('--- doc dependencies ---')
+ doxygen = find_program('doxygen')
+ sphinx_build = find_program('sphinx-build-3', required: false)
+ if not sphinx_build.found()
+ sphinx_build = find_program('sphinx-build')
+ endif
+ makeinfo = find_program('makeinfo', required: false)
+
+ # python dependencies: breathe, sphinx_rtd_theme
+ python_breathe = run_command('python3', '-c', 'import breathe', check: false)
+ if python_breathe.returncode() != 0
+ # some distros might use python2 sphinx
+ python_breathe = run_command('python2', '-c', 'import breathe', check: false)
+ if python_breathe.returncode() != 0
+ error('missing doc dependency: python breathe')
+ else
+ python_sphinx_rtd_theme = run_command('python2', '-c', 'import sphinx_rtd_theme', check: false)
+ if python_sphinx_rtd_theme.returncode() != 0
+ error('missing doc dependency: python sphinx_rtd_theme')
+ endif
+ endif
+ else
+ python_sphinx_rtd_theme = run_command('python3', '-c', 'import sphinx_rtd_theme', check: false)
+ if python_sphinx_rtd_theme.returncode() != 0
+ error('missing doc dependency: python sphinx_rtd_theme')
+ endif
+ endif
+ message('------------------------')
+
+ # install html docs
+ install_subdir(
+ meson.current_source_dir() / 'html',
+ install_dir: doc_dir,
+ )
+
+ if makeinfo.found()
+ # install info docs
+ install_subdir(
+ meson.current_source_dir() / 'texinfo' / '.install',
+ strip_directory: true,
+ install_dir: info_dir,
+ )
+ endif
+endif
+
+make_doc = find_program('../scripts/make-doc.sh')
+run_target(
+ 'doc',
+ command: make_doc,
+)
+
+
+run_target(
+ 'doc-strict',
+ command: [make_doc, '-W'],
+)
diff --git a/doc/modules-bogus_log.rst b/doc/modules-bogus_log.rst
new file mode 120000
index 0000000..61ead50
--- /dev/null
+++ b/doc/modules-bogus_log.rst
@@ -0,0 +1 @@
+../modules/bogus_log/README.rst \ No newline at end of file
diff --git a/doc/modules-daf.rst b/doc/modules-daf.rst
new file mode 120000
index 0000000..7715ed6
--- /dev/null
+++ b/doc/modules-daf.rst
@@ -0,0 +1 @@
+../modules/daf/README.rst \ No newline at end of file
diff --git a/doc/modules-detect_time_jump.rst b/doc/modules-detect_time_jump.rst
new file mode 120000
index 0000000..2821482
--- /dev/null
+++ b/doc/modules-detect_time_jump.rst
@@ -0,0 +1 @@
+../modules/detect_time_jump/README.rst \ No newline at end of file
diff --git a/doc/modules-detect_time_skew.rst b/doc/modules-detect_time_skew.rst
new file mode 120000
index 0000000..f0c0d14
--- /dev/null
+++ b/doc/modules-detect_time_skew.rst
@@ -0,0 +1 @@
+../modules/detect_time_skew/README.rst \ No newline at end of file
diff --git a/doc/modules-dns64.rst b/doc/modules-dns64.rst
new file mode 120000
index 0000000..792753a
--- /dev/null
+++ b/doc/modules-dns64.rst
@@ -0,0 +1 @@
+../modules/dns64/README.rst \ No newline at end of file
diff --git a/doc/modules-dnstap.rst b/doc/modules-dnstap.rst
new file mode 120000
index 0000000..f77d78e
--- /dev/null
+++ b/doc/modules-dnstap.rst
@@ -0,0 +1 @@
+../modules/dnstap/README.rst \ No newline at end of file
diff --git a/doc/modules-edns_keepalive.rst b/doc/modules-edns_keepalive.rst
new file mode 120000
index 0000000..ec7a358
--- /dev/null
+++ b/doc/modules-edns_keepalive.rst
@@ -0,0 +1 @@
+../modules/edns_keepalive/README.rst \ No newline at end of file
diff --git a/doc/modules-experimental_dot_auth.rst b/doc/modules-experimental_dot_auth.rst
new file mode 120000
index 0000000..c5bbfdc
--- /dev/null
+++ b/doc/modules-experimental_dot_auth.rst
@@ -0,0 +1 @@
+../modules/experimental_dot_auth/README.rst \ No newline at end of file
diff --git a/doc/modules-hints.rst b/doc/modules-hints.rst
new file mode 120000
index 0000000..1606310
--- /dev/null
+++ b/doc/modules-hints.rst
@@ -0,0 +1 @@
+../modules/hints/README.rst \ No newline at end of file
diff --git a/doc/modules-http-custom-services.rst b/doc/modules-http-custom-services.rst
new file mode 120000
index 0000000..5cbc7ec
--- /dev/null
+++ b/doc/modules-http-custom-services.rst
@@ -0,0 +1 @@
+../modules/http/custom_services.rst \ No newline at end of file
diff --git a/doc/modules-http-trace.rst b/doc/modules-http-trace.rst
new file mode 120000
index 0000000..c11fca0
--- /dev/null
+++ b/doc/modules-http-trace.rst
@@ -0,0 +1 @@
+../modules/http/trace.rst \ No newline at end of file
diff --git a/doc/modules-http.rst b/doc/modules-http.rst
new file mode 120000
index 0000000..3fc5fec
--- /dev/null
+++ b/doc/modules-http.rst
@@ -0,0 +1 @@
+../modules/http/README.rst \ No newline at end of file
diff --git a/doc/modules-nsid.rst b/doc/modules-nsid.rst
new file mode 120000
index 0000000..7ea4cc7
--- /dev/null
+++ b/doc/modules-nsid.rst
@@ -0,0 +1 @@
+../modules/nsid/README.rst \ No newline at end of file
diff --git a/doc/modules-policy.rst b/doc/modules-policy.rst
new file mode 120000
index 0000000..690a2b5
--- /dev/null
+++ b/doc/modules-policy.rst
@@ -0,0 +1 @@
+../modules/policy/README.rst \ No newline at end of file
diff --git a/doc/modules-predict.rst b/doc/modules-predict.rst
new file mode 120000
index 0000000..a4a8424
--- /dev/null
+++ b/doc/modules-predict.rst
@@ -0,0 +1 @@
+../modules/predict/README.rst \ No newline at end of file
diff --git a/doc/modules-prefill.rst b/doc/modules-prefill.rst
new file mode 120000
index 0000000..cfa8384
--- /dev/null
+++ b/doc/modules-prefill.rst
@@ -0,0 +1 @@
+../modules/prefill/README.rst \ No newline at end of file
diff --git a/doc/modules-priming.rst b/doc/modules-priming.rst
new file mode 120000
index 0000000..a36c3bf
--- /dev/null
+++ b/doc/modules-priming.rst
@@ -0,0 +1 @@
+../modules/priming/README.rst \ No newline at end of file
diff --git a/doc/modules-rebinding.rst b/doc/modules-rebinding.rst
new file mode 120000
index 0000000..a8e9d01
--- /dev/null
+++ b/doc/modules-rebinding.rst
@@ -0,0 +1 @@
+../modules/rebinding/README.rst \ No newline at end of file
diff --git a/doc/modules-refuse_nord.rst b/doc/modules-refuse_nord.rst
new file mode 120000
index 0000000..22e585c
--- /dev/null
+++ b/doc/modules-refuse_nord.rst
@@ -0,0 +1 @@
+../modules/refuse_nord/README.rst \ No newline at end of file
diff --git a/doc/modules-renumber.rst b/doc/modules-renumber.rst
new file mode 120000
index 0000000..1764c78
--- /dev/null
+++ b/doc/modules-renumber.rst
@@ -0,0 +1 @@
+../modules/renumber/README.rst \ No newline at end of file
diff --git a/doc/modules-rfc7706.rst b/doc/modules-rfc7706.rst
new file mode 120000
index 0000000..11b5c3d
--- /dev/null
+++ b/doc/modules-rfc7706.rst
@@ -0,0 +1 @@
+../modules/rfc7706.rst \ No newline at end of file
diff --git a/doc/modules-serve_stale.rst b/doc/modules-serve_stale.rst
new file mode 120000
index 0000000..98fa531
--- /dev/null
+++ b/doc/modules-serve_stale.rst
@@ -0,0 +1 @@
+../modules/serve_stale/README.rst \ No newline at end of file
diff --git a/doc/modules-stats.rst b/doc/modules-stats.rst
new file mode 120000
index 0000000..c8c5583
--- /dev/null
+++ b/doc/modules-stats.rst
@@ -0,0 +1 @@
+../modules/stats/README.rst \ No newline at end of file
diff --git a/doc/modules-ta_sentinel.rst b/doc/modules-ta_sentinel.rst
new file mode 120000
index 0000000..669e5a4
--- /dev/null
+++ b/doc/modules-ta_sentinel.rst
@@ -0,0 +1 @@
+../modules/ta_sentinel/README.rst \ No newline at end of file
diff --git a/doc/modules-ta_signal_query.rst b/doc/modules-ta_signal_query.rst
new file mode 120000
index 0000000..15e5d67
--- /dev/null
+++ b/doc/modules-ta_signal_query.rst
@@ -0,0 +1 @@
+../modules/ta_signal_query/README.rst \ No newline at end of file
diff --git a/doc/modules-view.rst b/doc/modules-view.rst
new file mode 120000
index 0000000..da22833
--- /dev/null
+++ b/doc/modules-view.rst
@@ -0,0 +1 @@
+../modules/view/README.rst \ No newline at end of file
diff --git a/doc/modules-watchdog.rst b/doc/modules-watchdog.rst
new file mode 120000
index 0000000..ac7d547
--- /dev/null
+++ b/doc/modules-watchdog.rst
@@ -0,0 +1 @@
+../modules/watchdog/README.rst \ No newline at end of file
diff --git a/doc/modules_api.rst b/doc/modules_api.rst
new file mode 100644
index 0000000..05f7407
--- /dev/null
+++ b/doc/modules_api.rst
@@ -0,0 +1,6 @@
+.. SPDX-License-Identifier: GPL-3.0-or-later
+
+.. _modules:
+
+.. include:: ../modules/README.rst
+
diff --git a/doc/quickstart-config.rst b/doc/quickstart-config.rst
new file mode 100644
index 0000000..df0fed4
--- /dev/null
+++ b/doc/quickstart-config.rst
@@ -0,0 +1,209 @@
+.. SPDX-License-Identifier: GPL-3.0-or-later
+
+.. _quickstart-config:
+
+*************
+Configuration
+*************
+
+.. contents::
+ :depth: 1
+ :local:
+
+.. note::
+
+ When copy&pasting examples from this manual please pay close
+ attention to brackets and also line ordering - order of lines matters.
+
+ The configuration language is in fact Lua script, so you can use full power
+ of this programming language. See article
+ `Learn Lua in 15 minutes`_ for a syntax overview.
+
+Easiest way to configure Knot Resolver is to paste your configuration into
+configuration file ``/etc/knot-resolver/kresd.conf``.
+Complete configurations files for examples in this chapter
+can be found `here <https://gitlab.nic.cz/knot/knot-resolver/tree/master/etc/config>`_.
+The example configuration files are also installed as documentation files, typically in directory ``/usr/share/doc/knot-resolver/examples/`` (their location may be different based on your Linux distribution).
+Detailed configuration of daemon and implemented modules can be found in configuration reference:
+
+
+Listening on network interfaces
+===============================
+
+Network interfaces to listen on and supported protocols are configured using :func:`net.listen()` function.
+
+The following configuration instructs Knot Resolver to receive standard unencrypted DNS queries on IP addresses `192.0.2.1` and `2001:db8::1`. Encrypted DNS queries are accepted using DNS-over-TLS protocol on all IP addresses configured on network interface `eth0`, TCP port 853.
+
+.. code-block:: lua
+
+ -- unencrypted DNS on port 53 is default
+ net.listen('192.0.2.1')
+ net.listen('2001:db8::1')
+ net.listen(net.eth0, 853, { kind = 'tls' })
+
+.. warning::
+
+ On machines with multiple IP addresses on the same interface avoid listening on wildcards ``0.0.0.0`` or ``::``.
+ Knot Resolver could answer from different IP addresses if the network address ranges
+ overlap, and clients would refuse such a response.
+
+
+Scenario: Internal Resolver
+===========================
+
+This is an example of typical configuration for company-internal resolver which is not accessible from outside of company network.
+
+Internal-only domains
+^^^^^^^^^^^^^^^^^^^^^
+
+An internal-only domain is a domain not accessible from the public Internet.
+In order to resolve internal-only domains a query policy has to be added to forward queries to a correct internal server.
+This configuration will forward two listed domains to a DNS server with IP address ``192.0.2.44``.
+
+.. code-block:: lua
+
+ -- define list of internal-only domains
+ internalDomains = policy.todnames({'company.example', 'internal.example'})
+
+ -- forward all queries belonging to domains in the list above to IP address '192.0.2.44'
+ policy.add(policy.suffix(policy.FLAGS({'NO_CACHE'}), internalDomains))
+ policy.add(policy.suffix(policy.STUB({'192.0.2.44'}), internalDomains))
+
+See chapter :ref:`dns-graft` for more details.
+
+
+.. _ispresolver:
+
+Scenario: ISP Resolver
+======================
+
+The following configuration is typical for Internet Service Providers who offer DNS resolver
+service to their own clients in their own network. Please note that running a *public DNS resolver*
+is more complicated and not covered by this quick start guide.
+
+Limiting client access
+^^^^^^^^^^^^^^^^^^^^^^
+With exception of public resolvers, a DNS resolver should resolve only queries sent by clients in its own network. This restriction limits attack surface on the resolver itself and also for the rest of the Internet.
+
+In a situation where access to DNS resolver is not limited using IP firewall, you can implement access restrictions using the :ref:`view module <mod-view>` which combines query source information with :ref:`policy rules <mod-policy>`.
+Following configuration allows only queries from clients in subnet 192.0.2.0/24 and refuses all the rest.
+
+.. code-block:: lua
+
+ modules.load('view')
+
+ -- whitelist queries identified by subnet
+ view:addr('192.0.2.0/24', policy.all(policy.PASS))
+
+ -- drop everything that hasn't matched
+ view:addr('0.0.0.0/0', policy.all(policy.DROP))
+
+TLS server configuration
+^^^^^^^^^^^^^^^^^^^^^^^^
+Today clients are demanding secure transport for DNS queries between client machine and DNS resolver. The recommended way to achieve this is to start DNS-over-TLS server and accept also encrypted queries.
+
+First step is to enable TLS on listening interfaces:
+
+.. code-block:: lua
+
+ net.listen('192.0.2.1', 853, { kind = 'tls' })
+ net.listen('2001::db8:1', 853, { kind = 'tls' })
+
+By default a self-signed certificate is generated.
+Second step is then obtaining and configuring your own TLS certificates
+signed by a trusted CA. Once the certificate was obtained a path to certificate files can be specified using function :func:`net.tls()`:
+
+.. code-block:: lua
+
+ net.tls("/etc/knot-resolver/server-cert.pem", "/etc/knot-resolver/server-key.pem")
+
+
+Mandatory domain blocking
+^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Some jurisdictions mandate blocking access to certain domains. This can be achieved using following :ref:`policy rule <mod-policy>`:
+
+.. code-block:: lua
+
+ policy.add(
+ policy.suffix(policy.DENY,
+ policy.todnames({'example.com.', 'blocked.example.net.'})))
+
+
+
+.. _personalresolver:
+
+Scenario: Personal Resolver
+===========================
+
+DNS queries can be used to gather data about user behavior.
+Knot Resolver can be configured to forward DNS queries elsewhere,
+and to protect them from eavesdropping by TLS encryption.
+
+.. warning::
+
+ Latest research has proven that encrypting DNS traffic is not sufficient to protect privacy of users.
+ For this reason we recommend all users to use full VPN instead of encrypting *just* DNS queries.
+ Following configuration is provided **only for users who cannot encrypt all their traffic**.
+ For more information please see following articles:
+
+ - Simran Patil and Nikita Borisov. 2019. What can you learn from an IP? (`slides <https://irtf.org/anrw/2019/slides-anrw19-final44.pdf>`_, `the article itself <https://dl.acm.org/authorize?N687437>`_)
+ - `Bert Hubert. 2019. Centralised DoH is bad for Privacy, in 2019 and beyond <https://labs.ripe.net/Members/bert_hubert/centralised-doh-is-bad-for-privacy-in-2019-and-beyond>`_
+
+
+Forwarding over TLS protocol (DNS-over-TLS)
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+Forwarding over TLS protocol protects DNS queries sent out by resolver.
+It can be configured using :ref:`policy.TLS_FORWARD <tls-forwarding>` function which provides methods for authentication.
+See list of `DNS Privacy Test Servers`_ supporting DNS-over-TLS to test your configuration.
+
+Read more on :ref:`tls-forwarding`.
+
+
+Forwarding to multiple targets
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+With the use of :any:`policy.slice` function, it is possible to split the
+entire DNS namespace into distinct "slices". When used in conjunction with
+:ref:`policy.TLS_FORWARD <tls-forwarding>`, it's possible to forward different queries to different
+remote resolvers. As a result no single remote resolver will get complete list
+of all queries performed by this client.
+
+.. warning::
+
+ Beware that this method has not been scientifically tested and there might be
+ types of attacks which will allow remote resolvers to infer more information about the client.
+ Again: If possible encrypt **all** your traffic and not just DNS queries!
+
+.. code-block:: lua
+
+ policy.add(policy.slice(
+ policy.slice_randomize_psl(),
+ policy.TLS_FORWARD({{'192.0.2.1', hostname='res.example.com'}}),
+ policy.TLS_FORWARD({
+ -- multiple servers can be specified for a single slice
+ -- the one with lowest round-trip time will be used
+ {'193.17.47.1', hostname='odvr.nic.cz'},
+ {'185.43.135.1', hostname='odvr.nic.cz'},
+ })
+ ))
+
+Non-persistent cache
+^^^^^^^^^^^^^^^^^^^^
+Knot Resolver's cache contains data clients queried for.
+If you are concerned about attackers who are able to get access to your
+computer system in power-off state and your storage device is not secured by
+encryption you can move the cache to tmpfs_.
+See chapter :ref:`cache_persistence`.
+
+
+.. raw:: html
+
+ <h2>Next steps</h2>
+
+Congratulations! Your resolver is now up and running and ready for queries. For
+serious deployments do not forget to read :ref:`configuration-chapter` and
+:ref:`operation-chapter` chapters.
+
+.. _`Learn Lua in 15 minutes`: http://tylerneylon.com/a/learn-lua/
+.. _`DNS Privacy Test Servers`: https://dnsprivacy.org/wiki/display/DP/DNS+Privacy+Test+Servers
+.. _tmpfs: https://en.wikipedia.org/wiki/Tmpfs
diff --git a/doc/quickstart-install.rst b/doc/quickstart-install.rst
new file mode 100644
index 0000000..329fb63
--- /dev/null
+++ b/doc/quickstart-install.rst
@@ -0,0 +1,73 @@
+.. SPDX-License-Identifier: GPL-3.0-or-later
+
+.. _quickstart-intro:
+
+Welcome to Knot Resolver Quick Start Guide! This chapter will guide you through first installation and basic setup recommended for your use-case.
+
+Before we start let us explain basic conventions used in this text:
+
+This is Linux/Unix shell command to be executed and an output from this command:
+
+.. code-block:: bash
+
+ $ echo "This is output!"
+ This is output!
+ $ echo "We use sudo to execute commands as root:"
+ We use sudo to execute commands as root:
+ $ sudo id
+ uid=0(root) gid=0(root) groups=0(root)
+
+Snippets from Knot Resolver's configuration file **do not start with $ sign** and look like this:
+
+.. code-block:: lua
+
+ -- this is a comment
+ -- following line will start listening on IP address 192.0.2.1 port 53
+ net.listen('192.0.2.1')
+
+
+.. _quickstart-install:
+
+************
+Installation
+************
+
+As a first step, configure your system to use upstream repositories which have
+the **latest version** of Knot Resolver. Follow the instructions below for your
+distribution.
+
+**Debian/Ubuntu**
+
+.. note:: Please note that the packages available in distribution repositories
+ of Debian and Ubuntu are outdated. Make sure to follow these steps to use
+ our upstream repositories.
+
+.. code-block:: bash
+
+ $ wget https://secure.nic.cz/files/knot-resolver/knot-resolver-release.deb
+ $ sudo dpkg -i knot-resolver-release.deb
+ $ sudo apt update
+ $ sudo apt install -y knot-resolver
+
+**CentOS 7+**
+
+.. code-block:: bash
+
+ $ sudo yum install -y epel-release
+ $ sudo yum install -y knot-resolver
+
+**Fedora**
+
+.. code-block:: bash
+
+ $ sudo dnf install -y knot-resolver
+
+**Arch Linux**
+
+.. code-block:: bash
+
+ $ sudo pacman -S knot-resolver
+
+
+**openSUSE Leap / Tumbleweed**
+Add the `OBS <https://en.opensuse.org/Portal:Build_Service>`_ package repository `home:CZ-NIC:knot-resolver-latest <https://software.opensuse.org/download.html?project=home%3ACZ-NIC%3Aknot-resolver-latest&package=knot-resolver>`_ to your system.
diff --git a/doc/quickstart-startup.rst b/doc/quickstart-startup.rst
new file mode 100644
index 0000000..5a381a3
--- /dev/null
+++ b/doc/quickstart-startup.rst
@@ -0,0 +1,47 @@
+.. SPDX-License-Identifier: GPL-3.0-or-later
+
+.. _quickstart-startup:
+
+*******
+Startup
+*******
+
+The simplest way to run single instance of
+Knot Resolver is to use provided Knot Resolver's Systemd integration:
+
+.. code-block:: bash
+
+ $ sudo systemctl start kresd@1.service
+
+See logs and status of running instance with ``systemctl status kresd@1.service`` command. For more information about Systemd integration see ``man kresd.systemd``.
+
+.. warning::
+
+ ``kresd@*.service`` is not enabled by default, thus Knot Resolver won't start automatically after reboot.
+ To start and enable service in one command use ``systemctl enable --now kresd@1.service``
+
+First DNS query
+===============
+After installation and first startup, Knot Resolver's default configuration accepts queries on loopback interface. This allows you to test that the installation and service startup were successful before continuing with configuration.
+
+For instance, you can use DNS lookup utility ``kdig`` to send DNS queries. The ``kdig`` command is provided by following packages:
+
+============ =================
+Distribution package with kdig
+============ =================
+Arch knot
+CentOS knot-utils
+Debian knot-dnsutils
+Fedora knot-utils
+OpenSUSE knot-utils
+Ubuntu knot-dnsutils
+============ =================
+
+The following query should return list of Root Name Servers:
+
+.. code-block:: bash
+
+ $ kdig +short @localhost . NS
+ a.root-servers.net.
+ ...
+ m.root-servers.net.
diff --git a/doc/requirements.txt b/doc/requirements.txt
new file mode 100644
index 0000000..3da3c23
--- /dev/null
+++ b/doc/requirements.txt
@@ -0,0 +1,2 @@
+Sphinx>=3.0.0
+breathe
diff --git a/doc/resolution.png b/doc/resolution.png
new file mode 100644
index 0000000..65d5027
--- /dev/null
+++ b/doc/resolution.png
Binary files differ
diff --git a/doc/server_terminology.fodg b/doc/server_terminology.fodg
new file mode 100644
index 0000000..8fecf02
--- /dev/null
+++ b/doc/server_terminology.fodg
@@ -0,0 +1,869 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<office:document xmlns:officeooo="http://openoffice.org/2009/office" xmlns:anim="urn:oasis:names:tc:opendocument:xmlns:animation:1.0" xmlns:smil="urn:oasis:names:tc:opendocument:xmlns:smil-compatible:1.0" xmlns:presentation="urn:oasis:names:tc:opendocument:xmlns:presentation:1.0" xmlns:grddl="http://www.w3.org/2003/g/data-view#" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xforms="http://www.w3.org/2002/xforms" xmlns:dom="http://www.w3.org/2001/xml-events" xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0" xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0" xmlns:math="http://www.w3.org/1998/Math/MathML" xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:formx="urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:ooo="http://openoffice.org/2004/office" xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0" xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:field="urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" xmlns:config="urn:oasis:names:tc:opendocument:xmlns:config:1.0" xmlns:calcext="urn:org:documentfoundation:names:experimental:calc:xmlns:calcext:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" xmlns:of="urn:oasis:names:tc:opendocument:xmlns:of:1.2" xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0" xmlns:rpt="http://openoffice.org/2005/report" xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" xmlns:css3t="http://www.w3.org/TR/css3-text/" xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" xmlns:ooow="http://openoffice.org/2004/writer" xmlns:oooc="http://openoffice.org/2004/calc" xmlns:tableooo="http://openoffice.org/2009/table" xmlns:drawooo="http://openoffice.org/2010/draw" office:version="1.2" office:mimetype="application/vnd.oasis.opendocument.graphics">
+ <office:meta><meta:initial-creator>Petr Å paÄek</meta:initial-creator><meta:creation-date>2020-01-09T14:38:06.406215825</meta:creation-date><meta:editing-cycles>18</meta:editing-cycles><meta:editing-duration>PT27M21S</meta:editing-duration><dc:date>2020-02-14T17:28:07.033132897</dc:date><dc:creator>Petr Å paÄek</dc:creator><meta:generator>LibreOffice/6.4.0.3$Linux_X86_64 LibreOffice_project/40$Build-3</meta:generator><dc:title>Basic DNS terminology</dc:title><dc:description>SPDX-License-Identifier: GPL-3.0-or-later</dc:description><meta:document-statistic meta:object-count="25"/></office:meta>
+ <office:settings>
+ <config:config-item-set config:name="ooo:view-settings">
+ <config:config-item config:name="VisibleAreaTop" config:type="int">2884</config:config-item>
+ <config:config-item config:name="VisibleAreaLeft" config:type="int">-318</config:config-item>
+ <config:config-item config:name="VisibleAreaWidth" config:type="int">23019</config:config-item>
+ <config:config-item config:name="VisibleAreaHeight" config:type="int">23865</config:config-item>
+ <config:config-item-map-indexed config:name="Views">
+ <config:config-item-map-entry>
+ <config:config-item config:name="ViewId" config:type="string">view1</config:config-item>
+ <config:config-item config:name="GridIsVisible" config:type="boolean">false</config:config-item>
+ <config:config-item config:name="GridIsFront" config:type="boolean">false</config:config-item>
+ <config:config-item config:name="IsSnapToGrid" config:type="boolean">true</config:config-item>
+ <config:config-item config:name="IsSnapToPageMargins" config:type="boolean">true</config:config-item>
+ <config:config-item config:name="IsSnapToSnapLines" config:type="boolean">false</config:config-item>
+ <config:config-item config:name="IsSnapToObjectFrame" config:type="boolean">false</config:config-item>
+ <config:config-item config:name="IsSnapToObjectPoints" config:type="boolean">false</config:config-item>
+ <config:config-item config:name="IsPlusHandlesAlwaysVisible" config:type="boolean">false</config:config-item>
+ <config:config-item config:name="IsFrameDragSingles" config:type="boolean">true</config:config-item>
+ <config:config-item config:name="EliminatePolyPointLimitAngle" config:type="int">1500</config:config-item>
+ <config:config-item config:name="IsEliminatePolyPoints" config:type="boolean">false</config:config-item>
+ <config:config-item config:name="VisibleLayers" config:type="base64Binary">Hw==</config:config-item>
+ <config:config-item config:name="PrintableLayers" config:type="base64Binary">Hw==</config:config-item>
+ <config:config-item config:name="LockedLayers" config:type="base64Binary"/>
+ <config:config-item config:name="NoAttribs" config:type="boolean">false</config:config-item>
+ <config:config-item config:name="NoColors" config:type="boolean">true</config:config-item>
+ <config:config-item config:name="RulerIsVisible" config:type="boolean">true</config:config-item>
+ <config:config-item config:name="PageKind" config:type="short">0</config:config-item>
+ <config:config-item config:name="SelectedPage" config:type="short">0</config:config-item>
+ <config:config-item config:name="IsLayerMode" config:type="boolean">true</config:config-item>
+ <config:config-item config:name="IsDoubleClickTextEdit" config:type="boolean">true</config:config-item>
+ <config:config-item config:name="IsClickChangeRotation" config:type="boolean">true</config:config-item>
+ <config:config-item config:name="SlidesPerRow" config:type="short">4</config:config-item>
+ <config:config-item config:name="EditMode" config:type="int">0</config:config-item>
+ <config:config-item config:name="VisibleAreaTop" config:type="int">2884</config:config-item>
+ <config:config-item config:name="VisibleAreaLeft" config:type="int">-318</config:config-item>
+ <config:config-item config:name="VisibleAreaWidth" config:type="int">23020</config:config-item>
+ <config:config-item config:name="VisibleAreaHeight" config:type="int">23866</config:config-item>
+ <config:config-item config:name="GridCoarseWidth" config:type="int">1000</config:config-item>
+ <config:config-item config:name="GridCoarseHeight" config:type="int">1000</config:config-item>
+ <config:config-item config:name="GridFineWidth" config:type="int">100</config:config-item>
+ <config:config-item config:name="GridFineHeight" config:type="int">100</config:config-item>
+ <config:config-item config:name="GridSnapWidthXNumerator" config:type="int">100</config:config-item>
+ <config:config-item config:name="GridSnapWidthXDenominator" config:type="int">1</config:config-item>
+ <config:config-item config:name="GridSnapWidthYNumerator" config:type="int">100</config:config-item>
+ <config:config-item config:name="GridSnapWidthYDenominator" config:type="int">1</config:config-item>
+ <config:config-item config:name="IsAngleSnapEnabled" config:type="boolean">false</config:config-item>
+ <config:config-item config:name="SnapAngle" config:type="int">1500</config:config-item>
+ <config:config-item config:name="ZoomOnPage" config:type="boolean">false</config:config-item>
+ <config:config-item config:name="AnchoredTextOverflowLegacy" config:type="boolean">false</config:config-item>
+ </config:config-item-map-entry>
+ </config:config-item-map-indexed>
+ </config:config-item-set>
+ <config:config-item-set config:name="ooo:configuration-settings">
+ <config:config-item config:name="ApplyUserData" config:type="boolean">true</config:config-item>
+ <config:config-item config:name="BitmapTableURL" config:type="string">$(brandbaseurl)/share/palette%3B$(user)/config/standard.sob</config:config-item>
+ <config:config-item config:name="CharacterCompressionType" config:type="short">0</config:config-item>
+ <config:config-item config:name="ColorTableURL" config:type="string">$(brandbaseurl)/share/palette%3B$(user)/config/standard.soc</config:config-item>
+ <config:config-item config:name="DashTableURL" config:type="string">$(brandbaseurl)/share/palette%3B$(user)/config/standard.sod</config:config-item>
+ <config:config-item config:name="DefaultTabStop" config:type="int">1250</config:config-item>
+ <config:config-item config:name="EmbedAsianScriptFonts" config:type="boolean">true</config:config-item>
+ <config:config-item config:name="EmbedComplexScriptFonts" config:type="boolean">true</config:config-item>
+ <config:config-item config:name="EmbedFonts" config:type="boolean">false</config:config-item>
+ <config:config-item config:name="EmbedLatinScriptFonts" config:type="boolean">true</config:config-item>
+ <config:config-item config:name="EmbedOnlyUsedFonts" config:type="boolean">false</config:config-item>
+ <config:config-item-map-indexed config:name="ForbiddenCharacters">
+ <config:config-item-map-entry>
+ <config:config-item config:name="Language" config:type="string">cs</config:config-item>
+ <config:config-item config:name="Country" config:type="string">CZ</config:config-item>
+ <config:config-item config:name="Variant" config:type="string"/>
+ <config:config-item config:name="BeginLine" config:type="string"/>
+ <config:config-item config:name="EndLine" config:type="string"/>
+ </config:config-item-map-entry>
+ </config:config-item-map-indexed>
+ <config:config-item config:name="GradientTableURL" config:type="string">$(brandbaseurl)/share/palette%3B$(user)/config/standard.sog</config:config-item>
+ <config:config-item config:name="HatchTableURL" config:type="string">$(brandbaseurl)/share/palette%3B$(user)/config/standard.soh</config:config-item>
+ <config:config-item config:name="IsKernAsianPunctuation" config:type="boolean">false</config:config-item>
+ <config:config-item config:name="IsPrintBooklet" config:type="boolean">false</config:config-item>
+ <config:config-item config:name="IsPrintBookletBack" config:type="boolean">true</config:config-item>
+ <config:config-item config:name="IsPrintBookletFront" config:type="boolean">true</config:config-item>
+ <config:config-item config:name="IsPrintDate" config:type="boolean">false</config:config-item>
+ <config:config-item config:name="IsPrintFitPage" config:type="boolean">false</config:config-item>
+ <config:config-item config:name="IsPrintHiddenPages" config:type="boolean">true</config:config-item>
+ <config:config-item config:name="IsPrintPageName" config:type="boolean">false</config:config-item>
+ <config:config-item config:name="IsPrintTilePage" config:type="boolean">false</config:config-item>
+ <config:config-item config:name="IsPrintTime" config:type="boolean">false</config:config-item>
+ <config:config-item config:name="LineEndTableURL" config:type="string">$(brandbaseurl)/share/palette%3B$(user)/config/standard.soe</config:config-item>
+ <config:config-item config:name="LoadReadonly" config:type="boolean">false</config:config-item>
+ <config:config-item config:name="MeasureUnit" config:type="short">3</config:config-item>
+ <config:config-item config:name="PageNumberFormat" config:type="int">4</config:config-item>
+ <config:config-item config:name="ParagraphSummation" config:type="boolean">false</config:config-item>
+ <config:config-item config:name="PrintQuality" config:type="int">0</config:config-item>
+ <config:config-item config:name="PrinterIndependentLayout" config:type="string">low-resolution</config:config-item>
+ <config:config-item config:name="PrinterName" config:type="string">HP_LaserJet_M2727nf_MFP</config:config-item>
+ <config:config-item config:name="PrinterPaperFromSetup" config:type="boolean">false</config:config-item>
+ <config:config-item config:name="PrinterSetup" config:type="base64Binary">1wH+/0hQX0xhc2VySmV0X00yNzI3bmZfTUZQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQ1VQUzpIUF9MYXNlckpldF9NMjcyN25mX01GUAAAAAAWAAMA8wAAAAAAAAAEAAhSAAAEdAAASm9iRGF0YSAxCnByaW50ZXI9SFBfTGFzZXJKZXRfTTI3MjduZl9NRlAKb3JpZW50YXRpb249UG9ydHJhaXQKY29waWVzPTEKY29sbGF0ZT1mYWxzZQptYXJnaW5kYWp1c3RtZW50PTAsMCwwLDAKY29sb3JkZXB0aD0yNApwc2xldmVsPTAKcGRmZGV2aWNlPTEKY29sb3JkZXZpY2U9MApQUERDb250ZXhEYXRhClBhZ2VTaXplOkE0AER1cGxleDpEdXBsZXhOb1R1bWJsZQBIUEVjb25vTW9kZTpGYWxzZQBJbnB1dFNsb3Q6QXV0bwAAEgBDT01QQVRfRFVQTEVYX01PREUUAER1cGxleE1vZGU6OkxvbmdFZGdl</config:config-item>
+ <config:config-item config:name="SaveThumbnail" config:type="boolean">true</config:config-item>
+ <config:config-item config:name="SaveVersionOnClose" config:type="boolean">false</config:config-item>
+ <config:config-item config:name="ScaleDenominator" config:type="int">1</config:config-item>
+ <config:config-item config:name="ScaleNumerator" config:type="int">1</config:config-item>
+ <config:config-item config:name="UpdateFromTemplate" config:type="boolean">true</config:config-item>
+ </config:config-item-set>
+ </office:settings>
+ <office:scripts>
+ <office:script script:language="ooo:Basic">
+ <ooo:libraries xmlns:ooo="http://openoffice.org/2004/office" xmlns:xlink="http://www.w3.org/1999/xlink">
+ <ooo:library-embedded ooo:name="Standard"/>
+ </ooo:libraries>
+ </office:script>
+ </office:scripts>
+ <office:font-face-decls>
+ <style:font-face style:name="Liberation Sans" svg:font-family="&apos;Liberation Sans&apos;" style:font-family-generic="roman" style:font-pitch="variable"/>
+ <style:font-face style:name="Liberation Serif" svg:font-family="&apos;Liberation Serif&apos;" style:font-family-generic="roman" style:font-pitch="variable"/>
+ <style:font-face style:name="Noto Sans" svg:font-family="&apos;Noto Sans&apos;" style:font-family-generic="roman" style:font-pitch="variable"/>
+ <style:font-face style:name="DejaVu Sans" svg:font-family="&apos;DejaVu Sans&apos;" style:font-family-generic="system" style:font-pitch="variable"/>
+ <style:font-face style:name="Liberation Sans1" svg:font-family="&apos;Liberation Sans&apos;" style:font-family-generic="system" style:font-pitch="variable"/>
+ </office:font-face-decls>
+ <office:styles>
+ <draw:gradient draw:name="Filled" draw:style="linear" draw:start-color="#ffffff" draw:end-color="#cccccc" draw:start-intensity="100%" draw:end-intensity="100%" draw:angle="300" draw:border="0%"/>
+ <draw:gradient draw:name="Filled_20_Blue" draw:display-name="Filled Blue" draw:style="linear" draw:start-color="#729fcf" draw:end-color="#355269" draw:start-intensity="100%" draw:end-intensity="100%" draw:angle="300" draw:border="0%"/>
+ <draw:gradient draw:name="Filled_20_Green" draw:display-name="Filled Green" draw:style="linear" draw:start-color="#77bc65" draw:end-color="#127622" draw:start-intensity="100%" draw:end-intensity="100%" draw:angle="300" draw:border="0%"/>
+ <draw:gradient draw:name="Filled_20_Red" draw:display-name="Filled Red" draw:style="linear" draw:start-color="#ff6d6d" draw:end-color="#c9211e" draw:start-intensity="100%" draw:end-intensity="100%" draw:angle="300" draw:border="0%"/>
+ <draw:gradient draw:name="Filled_20_Yellow" draw:display-name="Filled Yellow" draw:style="linear" draw:start-color="#ffde59" draw:end-color="#b47804" draw:start-intensity="100%" draw:end-intensity="100%" draw:angle="300" draw:border="0%"/>
+ <draw:gradient draw:name="Shapes" draw:style="rectangular" draw:cx="50%" draw:cy="50%" draw:start-color="#cccccc" draw:end-color="#ffffff" draw:start-intensity="100%" draw:end-intensity="100%" draw:angle="0" draw:border="0%"/>
+ <draw:marker draw:name="Arrow" svg:viewBox="0 0 20 30" svg:d="M10 0l-10 30h20z"/>
+ <draw:stroke-dash draw:name="Dashed_20__28_var_29_" draw:display-name="Dashed (var)" draw:style="rect" draw:dots1="1" draw:dots1-length="197%" draw:distance="127%"/>
+ <draw:stroke-dash draw:name="Fine_20_Dashed" draw:display-name="Fine Dashed" draw:style="rect" draw:dots1="1" draw:dots1-length="197%" draw:distance="197%"/>
+ <style:default-style style:family="graphic">
+ <style:graphic-properties svg:stroke-color="#3465a4" draw:fill-color="#729fcf" fo:wrap-option="no-wrap"/>
+ <style:paragraph-properties style:text-autospace="ideograph-alpha" style:punctuation-wrap="simple" style:line-break="strict" style:font-independent-line-spacing="false">
+ <style:tab-stops/>
+ </style:paragraph-properties>
+ <style:text-properties style:use-window-font-color="true" style:font-name="Liberation Serif" fo:font-size="24pt" fo:language="cs" fo:country="CZ" style:font-name-asian="DejaVu Sans" style:font-size-asian="24pt" style:language-asian="zh" style:country-asian="CN" style:font-name-complex="Liberation Sans1" style:font-size-complex="24pt" style:language-complex="hi" style:country-complex="IN"/>
+ </style:default-style>
+ <style:style style:name="standard" style:family="graphic">
+ <style:graphic-properties draw:stroke="solid" svg:stroke-width="0cm" svg:stroke-color="#3465a4" draw:marker-start-width="0.2cm" draw:marker-start-center="false" draw:marker-end-width="0.2cm" draw:marker-end-center="false" draw:fill="solid" draw:fill-color="#729fcf" draw:textarea-horizontal-align="justify" fo:padding-top="0.125cm" fo:padding-bottom="0.125cm" fo:padding-left="0.25cm" fo:padding-right="0.25cm" draw:shadow="hidden" draw:shadow-offset-x="0.2cm" draw:shadow-offset-y="0.2cm" draw:shadow-color="#808080">
+ <text:list-style style:name="standard">
+ <text:list-level-style-bullet text:level="1" text:bullet-char="â—">
+ <style:list-level-properties text:min-label-width="0.6cm"/>
+ <style:text-properties fo:font-family="StarSymbol" style:use-window-font-color="true" fo:font-size="45%"/>
+ </text:list-level-style-bullet>
+ <text:list-level-style-bullet text:level="2" text:bullet-char="â—">
+ <style:list-level-properties text:space-before="0.6cm" text:min-label-width="0.6cm"/>
+ <style:text-properties fo:font-family="StarSymbol" style:use-window-font-color="true" fo:font-size="45%"/>
+ </text:list-level-style-bullet>
+ <text:list-level-style-bullet text:level="3" text:bullet-char="â—">
+ <style:list-level-properties text:space-before="1.2cm" text:min-label-width="0.6cm"/>
+ <style:text-properties fo:font-family="StarSymbol" style:use-window-font-color="true" fo:font-size="45%"/>
+ </text:list-level-style-bullet>
+ <text:list-level-style-bullet text:level="4" text:bullet-char="â—">
+ <style:list-level-properties text:space-before="1.8cm" text:min-label-width="0.6cm"/>
+ <style:text-properties fo:font-family="StarSymbol" style:use-window-font-color="true" fo:font-size="45%"/>
+ </text:list-level-style-bullet>
+ <text:list-level-style-bullet text:level="5" text:bullet-char="â—">
+ <style:list-level-properties text:space-before="2.4cm" text:min-label-width="0.6cm"/>
+ <style:text-properties fo:font-family="StarSymbol" style:use-window-font-color="true" fo:font-size="45%"/>
+ </text:list-level-style-bullet>
+ <text:list-level-style-bullet text:level="6" text:bullet-char="â—">
+ <style:list-level-properties text:space-before="3cm" text:min-label-width="0.6cm"/>
+ <style:text-properties fo:font-family="StarSymbol" style:use-window-font-color="true" fo:font-size="45%"/>
+ </text:list-level-style-bullet>
+ <text:list-level-style-bullet text:level="7" text:bullet-char="â—">
+ <style:list-level-properties text:space-before="3.6cm" text:min-label-width="0.6cm"/>
+ <style:text-properties fo:font-family="StarSymbol" style:use-window-font-color="true" fo:font-size="45%"/>
+ </text:list-level-style-bullet>
+ <text:list-level-style-bullet text:level="8" text:bullet-char="â—">
+ <style:list-level-properties text:space-before="4.2cm" text:min-label-width="0.6cm"/>
+ <style:text-properties fo:font-family="StarSymbol" style:use-window-font-color="true" fo:font-size="45%"/>
+ </text:list-level-style-bullet>
+ <text:list-level-style-bullet text:level="9" text:bullet-char="â—">
+ <style:list-level-properties text:space-before="4.8cm" text:min-label-width="0.6cm"/>
+ <style:text-properties fo:font-family="StarSymbol" style:use-window-font-color="true" fo:font-size="45%"/>
+ </text:list-level-style-bullet>
+ <text:list-level-style-bullet text:level="10" text:bullet-char="â—">
+ <style:list-level-properties text:space-before="5.4cm" text:min-label-width="0.6cm"/>
+ <style:text-properties fo:font-family="StarSymbol" style:use-window-font-color="true" fo:font-size="45%"/>
+ </text:list-level-style-bullet>
+ </text:list-style>
+ </style:graphic-properties>
+ <style:paragraph-properties fo:margin-left="0cm" fo:margin-right="0cm" fo:margin-top="0cm" fo:margin-bottom="0cm" fo:line-height="100%" fo:text-indent="0cm"/>
+ <style:text-properties fo:font-variant="normal" fo:text-transform="none" style:use-window-font-color="true" style:text-outline="false" style:text-line-through-style="none" style:text-line-through-type="none" style:font-name="Liberation Sans" fo:font-family="&apos;Liberation Sans&apos;" style:font-family-generic="roman" style:font-pitch="variable" fo:font-size="18pt" fo:font-style="normal" fo:text-shadow="none" style:text-underline-style="none" fo:font-weight="normal" style:letter-kerning="true" style:font-name-asian="Liberation Sans1" style:font-family-asian="&apos;Liberation Sans&apos;" style:font-family-generic-asian="system" style:font-pitch-asian="variable" style:font-size-asian="18pt" style:font-style-asian="normal" style:font-weight-asian="normal" style:font-name-complex="Liberation Sans1" style:font-family-complex="&apos;Liberation Sans&apos;" style:font-family-generic-complex="system" style:font-pitch-complex="variable" style:font-size-complex="18pt" style:font-style-complex="normal" style:font-weight-complex="normal" style:text-emphasize="none" style:font-relief="none" style:text-overline-style="none" style:text-overline-color="font-color"/>
+ </style:style>
+ <style:style style:name="objectwithoutfill" style:family="graphic" style:parent-style-name="standard"/>
+ <style:style style:name="Object_20_with_20_no_20_fill_20_and_20_no_20_line" style:display-name="Object with no fill and no line" style:family="graphic" style:parent-style-name="standard">
+ <style:graphic-properties draw:stroke="none" draw:fill="none"/>
+ </style:style>
+ <style:style style:name="Text" style:family="graphic">
+ <style:graphic-properties draw:stroke="solid" svg:stroke-color="#cccccc" draw:fill="solid" draw:fill-color="#eeeeee"/>
+ <style:text-properties style:font-name="Noto Sans" fo:font-family="&apos;Noto Sans&apos;" style:font-family-generic="roman" style:font-pitch="variable"/>
+ </style:style>
+ <style:style style:name="A4" style:family="graphic" style:parent-style-name="Text">
+ <style:graphic-properties draw:fill="none"/>
+ <style:text-properties fo:font-size="18pt"/>
+ </style:style>
+ <style:style style:name="Title_20_A4" style:display-name="Title A4" style:family="graphic" style:parent-style-name="A4">
+ <style:graphic-properties draw:stroke="none"/>
+ <style:text-properties fo:font-size="44pt"/>
+ </style:style>
+ <style:style style:name="Heading_20_A4" style:display-name="Heading A4" style:family="graphic" style:parent-style-name="A4">
+ <style:graphic-properties draw:stroke="none"/>
+ <style:text-properties fo:font-size="24pt"/>
+ </style:style>
+ <style:style style:name="Text_20_A4" style:display-name="Text A4" style:family="graphic" style:parent-style-name="A4">
+ <style:graphic-properties draw:stroke="none"/>
+ </style:style>
+ <style:style style:name="A4" style:family="graphic" style:parent-style-name="Text">
+ <style:graphic-properties draw:fill="none"/>
+ <style:text-properties fo:font-size="18pt"/>
+ </style:style>
+ <style:style style:name="Title_20_A0" style:display-name="Title A0" style:family="graphic" style:parent-style-name="A4">
+ <style:graphic-properties draw:stroke="none"/>
+ <style:text-properties fo:font-size="96pt"/>
+ </style:style>
+ <style:style style:name="Heading_20_A0" style:display-name="Heading A0" style:family="graphic" style:parent-style-name="A4">
+ <style:graphic-properties draw:stroke="none"/>
+ <style:text-properties fo:font-size="72pt"/>
+ </style:style>
+ <style:style style:name="Text_20_A0" style:display-name="Text A0" style:family="graphic" style:parent-style-name="A4">
+ <style:graphic-properties draw:stroke="none"/>
+ </style:style>
+ <style:style style:name="Graphic" style:family="graphic">
+ <style:graphic-properties draw:fill="solid" draw:fill-color="#ffffff"/>
+ <style:text-properties style:font-name="Liberation Sans" fo:font-family="&apos;Liberation Sans&apos;" style:font-family-generic="roman" style:font-pitch="variable" fo:font-size="18pt"/>
+ </style:style>
+ <style:style style:name="Shapes" style:family="graphic" style:parent-style-name="Graphic">
+ <style:graphic-properties draw:stroke="none" draw:fill="gradient" draw:fill-gradient-name="Shapes"/>
+ <style:text-properties fo:font-size="14pt" fo:font-weight="bold"/>
+ </style:style>
+ <style:style style:name="Filled" style:family="graphic" style:parent-style-name="Shapes">
+ <style:graphic-properties draw:fill="gradient" draw:fill-gradient-name="Filled"/>
+ </style:style>
+ <style:style style:name="Filled_20_Blue" style:display-name="Filled Blue" style:family="graphic" style:parent-style-name="Filled">
+ <style:graphic-properties draw:fill-gradient-name="Filled_20_Blue"/>
+ <style:text-properties fo:color="#ffffff"/>
+ </style:style>
+ <style:style style:name="Filled_20_Green" style:display-name="Filled Green" style:family="graphic" style:parent-style-name="Filled">
+ <style:graphic-properties draw:fill-gradient-name="Filled_20_Green"/>
+ <style:text-properties fo:color="#ffffff" style:font-name="Liberation Sans" fo:font-family="&apos;Liberation Sans&apos;" style:font-family-generic="roman" style:font-pitch="variable"/>
+ </style:style>
+ <style:style style:name="Filled_20_Red" style:display-name="Filled Red" style:family="graphic" style:parent-style-name="Filled">
+ <style:graphic-properties draw:fill-gradient-name="Filled_20_Red"/>
+ <style:text-properties fo:color="#ffffff"/>
+ </style:style>
+ <style:style style:name="Filled_20_Yellow" style:display-name="Filled Yellow" style:family="graphic" style:parent-style-name="Filled">
+ <style:graphic-properties draw:fill-gradient-name="Filled_20_Yellow"/>
+ <style:text-properties fo:color="#ffffff"/>
+ </style:style>
+ <style:style style:name="Outlined" style:family="graphic" style:parent-style-name="Shapes">
+ <style:graphic-properties draw:stroke="solid" svg:stroke-width="0.081cm" svg:stroke-color="#000000" draw:fill="none"/>
+ </style:style>
+ <style:style style:name="Outlined_20_Blue" style:display-name="Outlined Blue" style:family="graphic" style:parent-style-name="Outlined">
+ <style:graphic-properties svg:stroke-color="#355269"/>
+ <style:text-properties fo:color="#355269"/>
+ </style:style>
+ <style:style style:name="Outlined_20_Green" style:display-name="Outlined Green" style:family="graphic" style:parent-style-name="Outlined">
+ <style:graphic-properties svg:stroke-color="#127622"/>
+ <style:text-properties fo:color="#127622"/>
+ </style:style>
+ <style:style style:name="Outlined_20_Red" style:display-name="Outlined Red" style:family="graphic" style:parent-style-name="Outlined">
+ <style:graphic-properties svg:stroke-color="#c9211e"/>
+ <style:text-properties fo:color="#c9211e"/>
+ </style:style>
+ <style:style style:name="Outlined_20_Yellow" style:display-name="Outlined Yellow" style:family="graphic" style:parent-style-name="Outlined">
+ <style:graphic-properties draw:stroke="solid" svg:stroke-color="#b47804"/>
+ <style:text-properties fo:color="#b47804"/>
+ </style:style>
+ <style:style style:name="Lines" style:family="graphic" style:parent-style-name="Graphic">
+ <style:graphic-properties draw:stroke="solid" svg:stroke-color="#000000" draw:fill="none"/>
+ </style:style>
+ <style:style style:name="Arrow_20_Line" style:display-name="Arrow Line" style:family="graphic" style:parent-style-name="Lines">
+ <style:graphic-properties draw:marker-start="Arrow" draw:marker-start-width="0.2cm" draw:marker-end="Arrow" draw:marker-end-width="0.2cm" draw:show-unit="true"/>
+ </style:style>
+ <style:style style:name="Arrow_20_Dashed" style:display-name="Arrow Dashed" style:family="graphic" style:parent-style-name="Lines">
+ <style:graphic-properties draw:stroke="dash"/>
+ </style:style>
+ </office:styles>
+ <office:automatic-styles>
+ <style:page-layout style:name="PM0">
+ <style:page-layout-properties fo:margin-top="1cm" fo:margin-bottom="1cm" fo:margin-left="1cm" fo:margin-right="1cm" fo:page-width="21cm" fo:page-height="29.7cm" style:print-orientation="portrait"/>
+ </style:page-layout>
+ <style:style style:name="dp1" style:family="drawing-page">
+ <style:drawing-page-properties draw:background-size="border" draw:fill="none"/>
+ </style:style>
+ <style:style style:name="dp2" style:family="drawing-page"/>
+ <style:style style:name="gr1" style:family="graphic" style:parent-style-name="Object_20_with_20_no_20_fill_20_and_20_no_20_line">
+ <style:graphic-properties draw:stroke="none" draw:fill="none" draw:textarea-horizontal-align="center" draw:textarea-vertical-align="middle" draw:color-mode="standard" draw:luminance="0%" draw:contrast="0%" draw:gamma="100%" draw:red="0%" draw:green="0%" draw:blue="0%" fo:clip="rect(0cm, 0cm, 0cm, 0cm)" draw:image-opacity="100%" style:mirror="none"/>
+ </style:style>
+ <style:style style:name="gr2" style:family="graphic" style:parent-style-name="standard">
+ <style:graphic-properties draw:stroke="none" svg:stroke-color="#000000" draw:fill="none" draw:fill-color="#ffffff" draw:textarea-horizontal-align="left" draw:auto-grow-height="true" draw:auto-grow-width="true" fo:min-height="1.423cm" fo:min-width="3.452cm"/>
+ <style:paragraph-properties style:writing-mode="lr-tb"/>
+ </style:style>
+ <style:style style:name="gr3" style:family="graphic" style:parent-style-name="standard">
+ <style:graphic-properties draw:stroke="none" svg:stroke-color="#000000" draw:fill="none" draw:fill-color="#ffffff" draw:textarea-horizontal-align="left" draw:auto-grow-height="true" draw:auto-grow-width="false" fo:min-height="0.712cm" fo:min-width="3.981cm"/>
+ <style:paragraph-properties style:writing-mode="lr-tb"/>
+ </style:style>
+ <style:style style:name="gr4" style:family="graphic" style:parent-style-name="standard">
+ <style:graphic-properties draw:stroke="none" svg:stroke-color="#000000" draw:fill="none" draw:fill-color="#ffffff" draw:textarea-horizontal-align="left" draw:auto-grow-height="true" draw:auto-grow-width="true" fo:min-height="1.423cm" fo:min-width="2.644cm"/>
+ <style:paragraph-properties style:writing-mode="lr-tb"/>
+ </style:style>
+ <style:style style:name="gr5" style:family="graphic" style:parent-style-name="standard">
+ <style:graphic-properties draw:stroke="none" svg:stroke-color="#000000" draw:fill="none" draw:fill-color="#ffffff" draw:textarea-horizontal-align="left" draw:auto-grow-height="true" draw:auto-grow-width="true" fo:min-height="0.712cm" fo:min-width="1.479cm"/>
+ <style:paragraph-properties style:writing-mode="lr-tb"/>
+ </style:style>
+ <style:style style:name="gr6" style:family="graphic" style:parent-style-name="objectwithoutfill">
+ <style:graphic-properties svg:stroke-width="0.1cm" svg:stroke-color="#000000" draw:marker-start-width="0.35cm" draw:marker-end="Arrow" draw:marker-end-width="0.45cm" draw:fill="solid" draw:textarea-vertical-align="middle" fo:padding-top="0.175cm" fo:padding-bottom="0.175cm" fo:padding-left="0.3cm" fo:padding-right="0.3cm"/>
+ </style:style>
+ <style:style style:name="gr7" style:family="graphic" style:parent-style-name="objectwithoutfill">
+ <style:graphic-properties draw:stroke="dash" draw:stroke-dash="Dashed_20__28_var_29_" svg:stroke-width="0.1cm" svg:stroke-color="#000000" draw:marker-start-width="0.35cm" draw:marker-end="Arrow" draw:marker-end-width="0.45cm" draw:fill="solid" draw:textarea-vertical-align="middle" fo:padding-top="0.175cm" fo:padding-bottom="0.175cm" fo:padding-left="0.3cm" fo:padding-right="0.3cm"/>
+ </style:style>
+ <style:style style:name="gr8" style:family="graphic" style:parent-style-name="standard">
+ <style:graphic-properties draw:stroke="none" svg:stroke-color="#000000" draw:fill="none" draw:fill-color="#ffffff" draw:textarea-horizontal-align="left" draw:auto-grow-height="true" draw:auto-grow-width="true" fo:min-height="2.134cm" fo:min-width="5.12cm"/>
+ <style:paragraph-properties style:writing-mode="lr-tb"/>
+ </style:style>
+ <style:style style:name="gr9" style:family="graphic" style:parent-style-name="standard">
+ <style:graphic-properties draw:stroke="none" draw:fill="none" fo:min-height="3.556cm"/>
+ <style:paragraph-properties style:writing-mode="lr-tb"/>
+ </style:style>
+ <style:style style:name="gr10" style:family="graphic" style:parent-style-name="standard">
+ <style:graphic-properties draw:stroke="none" svg:stroke-color="#000000" draw:fill="none" draw:fill-color="#ffffff" draw:textarea-horizontal-align="left" draw:auto-grow-height="true" draw:auto-grow-width="false" fo:min-height="0.712cm" fo:min-width="2.893cm"/>
+ <style:paragraph-properties style:writing-mode="lr-tb"/>
+ </style:style>
+ <style:style style:name="gr11" style:family="graphic" style:parent-style-name="standard">
+ <style:graphic-properties draw:stroke="none" svg:stroke-color="#000000" draw:fill="none" draw:fill-color="#ffffff" draw:textarea-horizontal-align="left" draw:auto-grow-height="true" draw:auto-grow-width="true" fo:min-height="3.556cm" fo:min-width="7.029cm"/>
+ <style:paragraph-properties style:writing-mode="lr-tb"/>
+ </style:style>
+ <style:style style:name="gr12" style:family="graphic" style:parent-style-name="objectwithoutfill">
+ <style:graphic-properties draw:stroke="dash" draw:stroke-dash="Fine_20_Dashed" svg:stroke-width="0.1cm" svg:stroke-color="#666666" draw:marker-start-width="0.35cm" draw:marker-end="" draw:marker-end-width="0.45cm" draw:fill="solid" draw:textarea-vertical-align="middle" fo:padding-top="0.175cm" fo:padding-bottom="0.175cm" fo:padding-left="0.3cm" fo:padding-right="0.3cm"/>
+ </style:style>
+ <style:style style:name="gr13" style:family="graphic" style:parent-style-name="standard">
+ <style:graphic-properties draw:stroke="none" svg:stroke-color="#000000" draw:fill="none" draw:fill-color="#ffffff" draw:textarea-horizontal-align="left" draw:auto-grow-height="true" draw:auto-grow-width="true" fo:min-height="0.712cm" fo:min-width="3.101cm"/>
+ <style:paragraph-properties style:writing-mode="lr-tb"/>
+ </style:style>
+ <style:style style:name="gr14" style:family="graphic" style:parent-style-name="standard">
+ <style:graphic-properties draw:stroke="none" svg:stroke-color="#000000" draw:fill="none" draw:fill-color="#ffffff" draw:textarea-horizontal-align="left" draw:auto-grow-height="true" draw:auto-grow-width="true" fo:min-height="0.712cm" fo:min-width="2.817cm"/>
+ <style:paragraph-properties style:writing-mode="lr-tb"/>
+ </style:style>
+ <style:style style:name="P1" style:family="paragraph">
+ <loext:graphic-properties draw:fill="none"/>
+ <style:paragraph-properties fo:text-align="center"/>
+ </style:style>
+ <style:style style:name="P2" style:family="paragraph">
+ <style:paragraph-properties fo:text-align="center"/>
+ </style:style>
+ <style:style style:name="P3" style:family="paragraph">
+ <loext:graphic-properties draw:fill="none" draw:fill-color="#ffffff"/>
+ <style:paragraph-properties fo:text-align="center" style:writing-mode="lr-tb"/>
+ </style:style>
+ <style:style style:name="P4" style:family="paragraph">
+ <loext:graphic-properties draw:fill="none" draw:fill-color="#ffffff"/>
+ <style:paragraph-properties style:writing-mode="lr-tb"/>
+ </style:style>
+ <style:style style:name="P5" style:family="paragraph">
+ <loext:graphic-properties draw:fill="solid"/>
+ <style:paragraph-properties fo:text-align="center"/>
+ </style:style>
+ <style:style style:name="P6" style:family="paragraph">
+ <loext:graphic-properties draw:fill="none"/>
+ <style:paragraph-properties style:writing-mode="lr-tb"/>
+ </style:style>
+ <style:style style:name="P7" style:family="paragraph">
+ <loext:graphic-properties draw:fill="none" draw:fill-color="#ffffff"/>
+ <style:paragraph-properties style:writing-mode="lr-tb"/>
+ <style:text-properties fo:font-style="italic" style:font-style-asian="italic" style:font-style-complex="italic"/>
+ </style:style>
+ <style:style style:name="T1" style:family="text">
+ <style:text-properties fo:font-weight="bold" style:font-weight-asian="bold" style:font-weight-complex="bold"/>
+ </style:style>
+ <style:style style:name="T2" style:family="text">
+ <style:text-properties fo:font-style="italic" fo:font-weight="normal" style:font-style-asian="italic" style:font-weight-asian="normal" style:font-style-complex="italic" style:font-weight-complex="normal"/>
+ </style:style>
+ <style:style style:name="T3" style:family="text">
+ <style:text-properties fo:font-variant="normal" fo:text-transform="none" style:use-window-font-color="true" style:text-outline="false" style:text-line-through-style="none" style:text-line-through-type="none" style:font-name="Liberation Sans" fo:font-size="18pt" fo:font-style="normal" fo:text-shadow="none" style:text-underline-style="none" fo:font-weight="normal" style:letter-kerning="true" style:font-name-asian="Liberation Sans1" style:font-size-asian="18pt" style:font-style-asian="normal" style:font-weight-asian="normal" style:font-name-complex="Liberation Sans1" style:font-size-complex="18pt" style:font-style-complex="normal" style:font-weight-complex="normal" style:text-emphasize="none" style:font-relief="none" style:text-overline-style="none" style:text-overline-color="font-color"/>
+ </style:style>
+ <style:style style:name="T4" style:family="text">
+ <style:text-properties fo:font-style="italic" style:font-style-asian="italic" style:font-style-complex="italic"/>
+ </style:style>
+ <text:list-style style:name="L1">
+ <text:list-level-style-bullet text:level="1" text:bullet-char="â—">
+ <style:list-level-properties text:min-label-width="0.6cm"/>
+ <style:text-properties fo:font-family="StarSymbol" style:use-window-font-color="true" fo:font-size="45%"/>
+ </text:list-level-style-bullet>
+ <text:list-level-style-bullet text:level="2" text:bullet-char="â—">
+ <style:list-level-properties text:space-before="0.6cm" text:min-label-width="0.6cm"/>
+ <style:text-properties fo:font-family="StarSymbol" style:use-window-font-color="true" fo:font-size="45%"/>
+ </text:list-level-style-bullet>
+ <text:list-level-style-bullet text:level="3" text:bullet-char="â—">
+ <style:list-level-properties text:space-before="1.2cm" text:min-label-width="0.6cm"/>
+ <style:text-properties fo:font-family="StarSymbol" style:use-window-font-color="true" fo:font-size="45%"/>
+ </text:list-level-style-bullet>
+ <text:list-level-style-bullet text:level="4" text:bullet-char="â—">
+ <style:list-level-properties text:space-before="1.8cm" text:min-label-width="0.6cm"/>
+ <style:text-properties fo:font-family="StarSymbol" style:use-window-font-color="true" fo:font-size="45%"/>
+ </text:list-level-style-bullet>
+ <text:list-level-style-bullet text:level="5" text:bullet-char="â—">
+ <style:list-level-properties text:space-before="2.4cm" text:min-label-width="0.6cm"/>
+ <style:text-properties fo:font-family="StarSymbol" style:use-window-font-color="true" fo:font-size="45%"/>
+ </text:list-level-style-bullet>
+ <text:list-level-style-bullet text:level="6" text:bullet-char="â—">
+ <style:list-level-properties text:space-before="3cm" text:min-label-width="0.6cm"/>
+ <style:text-properties fo:font-family="StarSymbol" style:use-window-font-color="true" fo:font-size="45%"/>
+ </text:list-level-style-bullet>
+ <text:list-level-style-bullet text:level="7" text:bullet-char="â—">
+ <style:list-level-properties text:space-before="3.6cm" text:min-label-width="0.6cm"/>
+ <style:text-properties fo:font-family="StarSymbol" style:use-window-font-color="true" fo:font-size="45%"/>
+ </text:list-level-style-bullet>
+ <text:list-level-style-bullet text:level="8" text:bullet-char="â—">
+ <style:list-level-properties text:space-before="4.2cm" text:min-label-width="0.6cm"/>
+ <style:text-properties fo:font-family="StarSymbol" style:use-window-font-color="true" fo:font-size="45%"/>
+ </text:list-level-style-bullet>
+ <text:list-level-style-bullet text:level="9" text:bullet-char="â—">
+ <style:list-level-properties text:space-before="4.8cm" text:min-label-width="0.6cm"/>
+ <style:text-properties fo:font-family="StarSymbol" style:use-window-font-color="true" fo:font-size="45%"/>
+ </text:list-level-style-bullet>
+ <text:list-level-style-bullet text:level="10" text:bullet-char="â—">
+ <style:list-level-properties text:space-before="5.4cm" text:min-label-width="0.6cm"/>
+ <style:text-properties fo:font-family="StarSymbol" style:use-window-font-color="true" fo:font-size="45%"/>
+ </text:list-level-style-bullet>
+ </text:list-style>
+ </office:automatic-styles>
+ <office:master-styles>
+ <draw:layer-set>
+ <draw:layer draw:name="layout"/>
+ <draw:layer draw:name="background"/>
+ <draw:layer draw:name="backgroundobjects"/>
+ <draw:layer draw:name="controls"/>
+ <draw:layer draw:name="measurelines"/>
+ </draw:layer-set>
+ <style:master-page style:name="Default" style:page-layout-name="PM0" draw:style-name="dp1"/>
+ </office:master-styles>
+ <office:body>
+ <office:drawing>
+ <draw:page draw:name="page1" draw:style-name="dp2" draw:master-page-name="Default">
+ <draw:g>
+ <draw:frame draw:name="noun_Server_1653064.svg" draw:style-name="gr1" draw:text-style-name="P1" draw:layer="layout" svg:width="1.67cm" svg:height="2.35cm" svg:x="14.641cm" svg:y="21.55cm">
+ <draw:image loext:mime-type="image/svg+xml">
+ <office:binary-data>PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+
+ CjxzdmcKICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgog
+ ICB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIgogICB4bWxuczpy
+ ZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiCiAgIHht
+ bG5zOnN2Zz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciCiAgIHhtbG5zPSJodHRwOi8v
+ d3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgeG1sbnM6c29kaXBvZGk9Imh0dHA6Ly9zb2RpcG9k
+ aS5zb3VyY2Vmb3JnZS5uZXQvRFREL3NvZGlwb2RpLTAuZHRkIgogICB4bWxuczppbmtzY2Fw
+ ZT0iaHR0cDovL3d3dy5pbmtzY2FwZS5vcmcvbmFtZXNwYWNlcy9pbmtzY2FwZSIKICAgZGF0
+ YS1uYW1lPSJMYXllciAxIgogICB2aWV3Qm94PSIwIDAgNjAgODUiCiAgIHg9IjBweCIKICAg
+ eT0iMHB4IgogICB2ZXJzaW9uPSIxLjEiCiAgIGlkPSJzdmc0MCIKICAgc29kaXBvZGk6ZG9j
+ bmFtZT0ibm91bl9TZXJ2ZXJfMTY1MzA2NC5zdmciCiAgIHdpZHRoPSI2MCIKICAgaGVpZ2h0
+ PSI4NSIKICAgaW5rc2NhcGU6dmVyc2lvbj0iMC45Mi40IDVkYTY4OWMzMTMsIDIwMTktMDEt
+ MTQiPgogIDxtZXRhZGF0YQogICAgIGlkPSJtZXRhZGF0YTQ2Ij4KICAgIDxyZGY6UkRGPgog
+ ICAgICA8Y2M6V29yawogICAgICAgICByZGY6YWJvdXQ9IiI+CiAgICAgICAgPGRjOmZvcm1h
+ dD5pbWFnZS9zdmcreG1sPC9kYzpmb3JtYXQ+CiAgICAgICAgPGRjOnR5cGUKICAgICAgICAg
+ ICByZGY6cmVzb3VyY2U9Imh0dHA6Ly9wdXJsLm9yZy9kYy9kY21pdHlwZS9TdGlsbEltYWdl
+ IiAvPgogICAgICAgIDxkYzp0aXRsZT5kYXRhLCBzZXJ2ZXIsIGRhdGFiYXNlLCByb3V0ZXIs
+ IGhhcmR3YXJlPC9kYzp0aXRsZT4KICAgICAgPC9jYzpXb3JrPgogICAgPC9yZGY6UkRGPgog
+ IDwvbWV0YWRhdGE+CiAgPGRlZnMKICAgICBpZD0iZGVmczQ0IiAvPgogIDxzb2RpcG9kaTpu
+ YW1lZHZpZXcKICAgICBwYWdlY29sb3I9IiNmZmZmZmYiCiAgICAgYm9yZGVyY29sb3I9IiM2
+ NjY2NjYiCiAgICAgYm9yZGVyb3BhY2l0eT0iMSIKICAgICBvYmplY3R0b2xlcmFuY2U9IjEw
+ IgogICAgIGdyaWR0b2xlcmFuY2U9IjEwIgogICAgIGd1aWRldG9sZXJhbmNlPSIxMCIKICAg
+ ICBpbmtzY2FwZTpwYWdlb3BhY2l0eT0iMCIKICAgICBpbmtzY2FwZTpwYWdlc2hhZG93PSIy
+ IgogICAgIGlua3NjYXBlOndpbmRvdy13aWR0aD0iOTU2IgogICAgIGlua3NjYXBlOndpbmRv
+ dy1oZWlnaHQ9IjEwNTQiCiAgICAgaWQ9Im5hbWVkdmlldzQyIgogICAgIHNob3dncmlkPSJm
+ YWxzZSIKICAgICBmaXQtbWFyZ2luLXRvcD0iMCIKICAgICBmaXQtbWFyZ2luLWxlZnQ9IjAi
+ CiAgICAgZml0LW1hcmdpbi1yaWdodD0iMCIKICAgICBmaXQtbWFyZ2luLWJvdHRvbT0iMCIK
+ ICAgICBpbmtzY2FwZTp6b29tPSIxLjg4OCIKICAgICBpbmtzY2FwZTpjeD0iLTE0LjY0NjAx
+ MyIKICAgICBpbmtzY2FwZTpjeT0iMjkuNSIKICAgICBpbmtzY2FwZTp3aW5kb3cteD0iOTYy
+ IgogICAgIGlua3NjYXBlOndpbmRvdy15PSIyIgogICAgIGlua3NjYXBlOndpbmRvdy1tYXhp
+ bWl6ZWQ9IjEiCiAgICAgaW5rc2NhcGU6Y3VycmVudC1sYXllcj0ic3ZnNDAiIC8+CiAgPHRp
+ dGxlCiAgICAgaWQ9InRpdGxlMiI+ZGF0YSwgc2VydmVyLCBkYXRhYmFzZSwgcm91dGVyLCBo
+ YXJkd2FyZTwvdGl0bGU+CiAgPHJlY3QKICAgICB4PSIxMCIKICAgICB5PSIzNiIKICAgICB3
+ aWR0aD0iNCIKICAgICBoZWlnaHQ9IjYiCiAgICAgaWQ9InJlY3Q0IiAvPgogIDxyZWN0CiAg
+ ICAgeD0iMTgiCiAgICAgeT0iMzYiCiAgICAgd2lkdGg9IjQiCiAgICAgaGVpZ2h0PSI2Igog
+ ICAgIGlkPSJyZWN0NiIgLz4KICA8cmVjdAogICAgIHg9IjI2IgogICAgIHk9IjM2IgogICAg
+ IHdpZHRoPSI0IgogICAgIGhlaWdodD0iNiIKICAgICBpZD0icmVjdDgiIC8+CiAgPHJlY3QK
+ ICAgICB4PSIzNCIKICAgICB5PSIzNiIKICAgICB3aWR0aD0iNCIKICAgICBoZWlnaHQ9IjYi
+ CiAgICAgaWQ9InJlY3QxMCIgLz4KICA8Y2lyY2xlCiAgICAgY3g9IjQ4IgogICAgIGN5PSIz
+ OSIKICAgICByPSIyIgogICAgIGlkPSJjaXJjbGUxMiIgLz4KICA8cGF0aAogICAgIGQ9Im0g
+ NTUsMjQgYSA1LDUgMCAwIDAgNSwtNSBWIDUgQSA1LDUgMCAwIDAgNTUsMCBIIDUgQSA1LDUg
+ MCAwIDAgMCw1IHYgMTQgYSA1LDUgMCAwIDAgNSw1IGggMSB2IDMgSCA1IGEgNSw1IDAgMCAw
+ IC01LDUgdiAxNCBhIDUsNSAwIDAgMCA1LDUgaCAxIHYgMyBIIDUgYSA1LDUgMCAwIDAgLTUs
+ NSB2IDE0IGEgNSw1IDAgMCAwIDUsNSBoIDEgdiA3IGggNDggdiAtNyBoIDEgYSA1LDUgMCAw
+ IDAgNSwtNSBWIDU5IGEgNSw1IDAgMCAwIC01LC01IGggLTEgdiAtMyBoIDEgYSA1LDUgMCAw
+ IDAgNSwtNSBWIDMyIEEgNSw1IDAgMCAwIDU1LDI3IEggNTQgViAyNCBaIE0gNTAsODEgSCAx
+ MCB2IC0zIGggNDAgeiBtIDUsLTIzIGEgMSwxIDAgMCAxIDEsMSB2IDE0IGEgMSwxIDAgMCAx
+ IC0xLDEgSCA1IEEgMSwxIDAgMCAxIDQsNzMgViA1OSBBIDEsMSAwIDAgMSA1LDU4IFogTSAx
+ MCw1NCB2IC0zIGggNDAgdiAzIHogTSA1NSwzMSBhIDEsMSAwIDAgMSAxLDEgdiAxNCBhIDEs
+ MSAwIDAgMSAtMSwxIEggNSBBIDEsMSAwIDAgMSA0LDQ2IFYgMzIgQSAxLDEgMCAwIDEgNSwz
+ MSBaIE0gMTAsMjcgdiAtMyBoIDQwIHYgMyB6IE0gNSwyMCBBIDEsMSAwIDAgMSA0LDE5IFYg
+ NSBBIDEsMSAwIDAgMSA1LDQgaCA1MCBhIDEsMSAwIDAgMSAxLDEgdiAxNCBhIDEsMSAwIDAg
+ MSAtMSwxIHoiCiAgICAgaWQ9InBhdGgxNCIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3Vy
+ dmF0dXJlPSIwIiAvPgogIDxyZWN0CiAgICAgeD0iMTAiCiAgICAgeT0iOSIKICAgICB3aWR0
+ aD0iNCIKICAgICBoZWlnaHQ9IjYiCiAgICAgaWQ9InJlY3QxNiIgLz4KICA8cmVjdAogICAg
+ IHg9IjE4IgogICAgIHk9IjkiCiAgICAgd2lkdGg9IjQiCiAgICAgaGVpZ2h0PSI2IgogICAg
+ IGlkPSJyZWN0MTgiIC8+CiAgPHJlY3QKICAgICB4PSIyNiIKICAgICB5PSI5IgogICAgIHdp
+ ZHRoPSI0IgogICAgIGhlaWdodD0iNiIKICAgICBpZD0icmVjdDIwIiAvPgogIDxyZWN0CiAg
+ ICAgeD0iMzQiCiAgICAgeT0iOSIKICAgICB3aWR0aD0iNCIKICAgICBoZWlnaHQ9IjYiCiAg
+ ICAgaWQ9InJlY3QyMiIgLz4KICA8Y2lyY2xlCiAgICAgY3g9IjQ4IgogICAgIGN5PSIxMiIK
+ ICAgICByPSIyIgogICAgIGlkPSJjaXJjbGUyNCIgLz4KICA8cmVjdAogICAgIHg9IjEwIgog
+ ICAgIHk9IjYzIgogICAgIHdpZHRoPSI0IgogICAgIGhlaWdodD0iNiIKICAgICBpZD0icmVj
+ dDI2IiAvPgogIDxyZWN0CiAgICAgeD0iMTgiCiAgICAgeT0iNjMiCiAgICAgd2lkdGg9IjQi
+ CiAgICAgaGVpZ2h0PSI2IgogICAgIGlkPSJyZWN0MjgiIC8+CiAgPHJlY3QKICAgICB4PSIy
+ NiIKICAgICB5PSI2MyIKICAgICB3aWR0aD0iNCIKICAgICBoZWlnaHQ9IjYiCiAgICAgaWQ9
+ InJlY3QzMCIgLz4KICA8cmVjdAogICAgIHg9IjM0IgogICAgIHk9IjYzIgogICAgIHdpZHRo
+ PSI0IgogICAgIGhlaWdodD0iNiIKICAgICBpZD0icmVjdDMyIiAvPgogIDxjaXJjbGUKICAg
+ ICBjeD0iNDgiCiAgICAgY3k9IjY2IgogICAgIHI9IjIiCiAgICAgaWQ9ImNpcmNsZTM0IiAv
+ Pgo8L3N2Zz4K
+ </office:binary-data>
+ <text:p/>
+ </draw:image>
+ <draw:image loext:mime-type="image/png">
+ <office:binary-data>iVBORw0KGgoAAAANSUhEUgAAAD0AAABWCAYAAAB8UZ5wAAABO0lEQVR4nO2Z7Q6CMAxFJeH9
+ XxmtyUzFgRtf2t5zfikjccduDnvHaZpuaoz+zTAMab+BR3GH8volnVnYML8iPpYLv53SNRTx
+ sTbol0Jklor5IZ1F2DCXmni10tlBWoVm6fnemO/9s8ePhEpHw6+OnpURWnorSEdj649ds/S3
+ Dzh7/EhCV3orSKuAtKHQUKDSKjyllzoM2XhrDPoLhSv/6h1Bz3x1l7cazUdWtD1f5ltb5ulj
+ nZo8sU52iHU8WYQNYh0H0ioQ66gQWlou1tnzQBVWek/jI6y0QazTQehKbwVpFZA2FBoKVFoF
+ Yh1/A7FOMpA2iHUSQKxDrDPj34+nVoh1HBxZKiC9BrFOcEJLE+t0EFaaWKcTYh0VkFYBaUOh
+ oUClVSDW8TcQ6yQD6TUy7XkqrQLSnn8/ovZwB2IfDVe+8hdvAAAAAElFTkSuQmCC
+ </office:binary-data>
+ </draw:image>
+ <svg:title>data, server, database, router, hardware</svg:title>
+ </draw:frame>
+ <draw:frame draw:style-name="gr2" draw:text-style-name="P3" draw:layer="layout" svg:width="3.952cm" svg:height="1.673cm" svg:x="13.5cm" svg:y="23.9cm">
+ <draw:text-box>
+ <text:p text:style-name="P2">authoritative<text:line-break/>server</text:p>
+ </draw:text-box>
+ </draw:frame>
+ </draw:g>
+ <draw:g>
+ <draw:frame draw:style-name="gr1" draw:text-style-name="P1" draw:layer="layout" svg:width="2.32cm" svg:height="2.35cm" svg:x="8.886cm" svg:y="13.438cm">
+ <draw:image loext:mime-type="image/svg+xml">
+ <office:binary-data>PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPCEtLSBHZW5lcmF0b3I6
+ IEFkb2JlIElsbHVzdHJhdG9yIDIzLjAuNiwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZl
+ cnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPgo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IlZyc3R2
+ YV8xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJo
+ dHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB4PSIwcHgiIHk9IjBweCIKCSB2aWV3Qm94
+ PSIwIDAgMjA2IDIwOSIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgMjA2IDIw
+ OTsiIHhtbDpzcGFjZT0icHJlc2VydmUiPgo8c3R5bGUgdHlwZT0idGV4dC9jc3MiPgoJLnN0
+ MHtmaWxsOiMwMEEyRTI7fQo8L3N0eWxlPgo8cGF0aCBjbGFzcz0ic3QwIiBkPSJNMjA2LDEw
+ NC42YzAsMzEuNC0xMy45LDU5LjUtMzYsNzguNmMxLjItNi4zLDEuOS0xMi45LDEuOS0xOS42
+ YzAtMjAuNS02LjEtMzkuNy0xNi41LTU1LjgKCWMtNC4xLDUuNy04LjgsMTEtMTMuOSwxNS44
+ YzYuNiwxMS44LDEwLjMsMjUuNSwxMC4zLDQwYzAsNS45LTAuNiwxMS42LTEuOCwxNy4yYy0w
+ LjEsMC42LTAuMywxLjItMC40LDEuOGMtMC4xLDAuNi0wLjMsMS4yLTAuNCwxLjgKCWMtMC42
+ LTAuMi0xLjItMC4zLTEuOC0wLjVjLTAuNi0wLjItMS4yLTAuMy0xLjctMC42Yy0xOS02LjIt
+ MzUtMTkuMS00NS4yLTM1LjljLTAuMy0wLjUtMC42LTEuMS0xLTEuNmMtMC4zLTAuNS0wLjYt
+ MS4xLTAuOS0xLjYKCWMtMy4yLTUuOS01LjctMTIuMi03LjQtMTguOGMtMC4xLTAuNi0wLjMt
+ MS4yLTAuNC0xLjhjLTAuMi0wLjYtMC4zLTEuMi0wLjQtMS44Yy0xLjItNS41LTEuOC0xMS4z
+ LTEuOC0xNy4yczAuNi0xMS42LDEuOC0xNy4yCgljLTYuMy0xLjgtMTMtMi44LTE5LjktMi45
+ Yy0xLjMsNi41LTIsMTMuMi0yLDIwYzAsNi45LDAuNywxMy42LDIsMjAuMWMwLjEsMC42LDAu
+ MiwxLjIsMC40LDEuOGMwLjEsMC42LDAuMywxLjIsMC40LDEuOAoJYzEuNiw2LjgsMy45LDEz
+ LjQsNi45LDE5LjdjMC4zLDAuNiwwLjUsMS4yLDAuOCwxLjdjMC4zLDAuNiwwLjYsMS4yLDAu
+ OSwxLjhjMTIuMSwyMy41LDMzLDQxLjgsNTguNCw1MC40CgljLTExLjIsNC4xLTIzLjMsNi40
+ LTM1LjksNi40Yy01MS41LDAtOTQuMi0zNy41LTEwMi4zLTg2LjdjMC41LDAuNCwwLjksMC44
+ LDEuNCwxLjJjMTguMSwxNS45LDQxLjgsMjUuNSw2Ny43LDI1LjUKCWMxLjcsMCwzLjQsMCw1
+ LjEtMC4xYy0yLjktNi40LTUuMS0xMy02LjctMjBjLTIwLjYtMC40LTM5LjMtOC4zLTUzLjYt
+ MjEuMmMtMC41LTAuNC0wLjktMC44LTEuNC0xLjJjLTAuNS0wLjQtMC45LTAuOC0xLjMtMS4z
+ CgljMC40LTAuNCwwLjgtMC45LDEuMy0xLjNjMC40LTAuNCwwLjktMC44LDEuMy0xLjJjMTQu
+ My0xMi45LDMzLTIwLjgsNTMuNi0yMS4yYzAuNSwwLDEuMSwwLDEuNiwwaDAuM2MwLjYsMCwx
+ LjMsMCwxLjksMAoJYzYuOSwwLjIsMTMuNiwxLjIsMjAsM2MwLjYsMC4yLDEuMiwwLjMsMS43
+ LDAuNWMwLjYsMC4yLDEuMiwwLjQsMS43LDAuNWMxMS4xLDMuNiwyMS4yLDkuNSwyOS42LDE3
+ LjJjNC44LTQuNyw5LTEwLDEyLjUtMTUuOAoJYy0xMC04LjgtMjEuOC0xNS43LTM0LjctMjAu
+ MWMtMC42LTAuMi0xLjItMC40LTEuNy0wLjZjLTAuNi0wLjItMS4yLTAuNC0xLjgtMC42Yy02
+ LjYtMi0xMy40LTMuMy0yMC41LTMuOQoJYy0wLjYtMC4xLTEuMy0wLjEtMS45LTAuMmMtMC43
+ LDAtMS4zLTAuMS0yLTAuMWMtMS43LTAuMS0zLjQtMC4xLTUuMS0wLjFjLTI1LjksMC00OS42
+ LDkuNi02Ny43LDI1LjVjLTAuNSwwLjQtMC45LDAuOC0xLjQsMS4yCglDOC4xLDM4LjQsNTAu
+ OCwwLjksMTAyLjMsMC45YzEyLjYsMCwyNC43LDIuMywzNS45LDYuNGMwLDAsMCwwLDAsMEMx
+ MTIuOCwxNS45LDkyLDM0LjEsNzkuOCw1Ny42YzcuMSwwLjcsMTQsMi4xLDIwLjcsNC4yCglj
+ MTAuMi0xNi44LDI2LjItMjkuNyw0NS4yLTM1LjljMC42LTAuMiwxLjItMC40LDEuNy0wLjZj
+ MC42LTAuMiwxLjItMC4zLDEuOC0wLjVjMC4xLDAuNiwwLjMsMS4yLDAuNCwxLjhjMC4xLDAu
+ NiwwLjMsMS4yLDAuNCwxLjgKCWMxLjIsNS41LDEuOCwxMS4zLDEuOCwxNy4yYzAsMTQuNS0z
+ LjcsMjguMS0xMC4zLDQwYy0wLjMsMC41LTAuNiwxLjEtMC45LDEuNmMtMC4zLDAuNS0wLjYs
+ MS4xLTEsMS42Yy0zLjUsNS43LTcuOCwxMS4xLTEyLjYsMTUuOAoJYy0wLjQsMC40LTAuOSww
+ LjktMS4zLDEuM2MtMC40LDAuNC0wLjksMC44LTEuMywxLjJjLTguNSw3LjYtMTguNiwxMy41
+ LTI5LjcsMTcuMmMxLjcsNi42LDQuMiwxMi45LDcuNSwxOC43CgljMTIuOS00LjQsMjQuNi0x
+ MS4zLDM0LjYtMjAuMWMwLjUtMC40LDAuOS0wLjgsMS40LTEuMmMwLjUtMC40LDAuOS0wLjgs
+ MS40LTEuM2M1LjEtNC44LDkuNy0xMC4xLDEzLjctMTUuOAoJYzAuNC0wLjUsMC43LTEuMSwx
+ LjEtMS42YzAuNC0wLjUsMC43LTEuMSwxLjEtMS42YzEwLjQtMTYuMSwxNi41LTM1LjIsMTYu
+ NS01NS43YzAtNi43LTAuNi0xMy4zLTEuOS0xOS42CglDMTkyLDQ1LDIwNiw3My4yLDIwNiwx
+ MDQuNiIvPgo8L3N2Zz4K
+ </office:binary-data>
+ <text:p/>
+ </draw:image>
+ <draw:image loext:mime-type="image/png">
+ <office:binary-data>iVBORw0KGgoAAAANSUhEUgAAAM4AAADRCAYAAACEn42KAAAKW0lEQVR4nO2dW3LkNgxFPVXe
+ RpaW1WVpWYhTmik6sppQUyQeF+A9n1NTbjaAI0BsPT6/vr4+CCHP+IxeAPn4+PXPv0NHr6+/
+ //plvRYyBsUxZlQKrb9FuXygOApoyrHK3VoolR4UZxIkWUa5rpkizUNxHpBRljt634cyjUFx
+ bqgmygjsSmNQnAs7ynLHEQ/K8wrF+aAsEhRGZltxKEsfyjLGduJQmD4U5hnbiENh+lCYOUqL
+ Q1lkKMwaJcWhMH0oix5lxKEsMhRGn/TiUBgZCmNHanEojQylsSWtOJRGhtLYk1IcStOHwviR
+ ShwKI0NpfEkjDqWRoTT+pBCH0vShMHFAi0NhZChNLLDiUBoZShMPpDiUpg+FwQFOHErTJ4M0
+ LXcZ1roKjDgURga9EK+52+F2awhxKI0McgF65g1NxnBxKI0MUqE0IvOFJE+oOJRGBqVAGii5
+ QpEnTByURCCCUBgNxDwhyBMiDmIyUIguiAPE/BxxOa8rWh53cRCTgkK0NNlyEymPqzjZEuNJ
+ NWm8ijpKHjdxKI1MpDQV8hIhj4s4FZJjBaXRwVsec3EqJUebKGmq5sRTHlNxqiZIA0pjg5c8
+ ZuJUT9AKEdLslA8PeUzE2SlJT6E0PljLoy7OjkkahdL4YilP+EWexI5q0lyvHhjBSh5Vcaol
+ ShPvboOQi+jLYixREwchUajsKA0SFgJzVCsGpfFBRRwmS8az2zAPMtpdZ1kcJkuG0mChKQ9H
+ tQJQGn+WxGHCZLy6DXPwDK2uMy0OEyZDaf5QdSv6gKNaUtClQUaj60yJw6TJeN31aP0Z5J7H
+ 4jBpsTD+Oqx2HY5qilh3m92lQXouwiNxdk/cHZVPhMkr7DhJ4EHLhtmuMywOEyfDEe2V6h2Y
+ HWcRSpOfma5DcRbpFXb1o21FnsozJA6Pes94F6/RBDHuuLDjBHAWQpKI0vjzpOu8Fad6AjXG
+ qpUY9SSqHvMKlO44Xucavc+ZKX4Kk4dbcTIkEvVEXEumjFjkxCt2o+Nayo6DKss7dpapGinE
+ ySrKCJQpJ6I4kcmrLMoI3CSIZWRcg+k4u8vS4xwTSoRFVxyvJFGWcbJ0ocwbA08I6TgUZp4s
+ AmXn3bjmJg5l0YVjXCwv4mgngcLYg9KFdsq1WcfZKYgooAhUhbtxTVUcyoJBpTEOdf0/xJld
+ JIXBxasL7VYDSx1nt2BlZuZtZkQe16bFoTT5sJLHqhaQRZ8Sh9LkhRsIOnyLMxJIClMHjm7j
+ 9Ma14Y5DaeqhIc+OY9rBkDiUpi4c3ea4FaeiMKhH2GiQRjeUdZy5jmuf7R+v/zFjgXgE/O4z
+ MsbszFN5sn/fFV46TrZgIB2dKhyAOLqN8UOcLEnOlFRpreixjhrdsuT2sy0UPZHeAbV+FkCG
+ uN/Jg7xuD353HNQgoB19LB5diy4Q0qZBNOcNgk/EhGVP1Ey3GnksbgSe522Z8g7zsI6DTIGz
+ BKULVdjssAJCHArTJ1Ig75xkq4EwcZADhXZU9R7juCHwHndxkIXJQFQXsvy8jDXhJk7G4CBj
+ JRDPa8YwF4fC2DL71mTpb13/je847WMqTtagZENDHl4lMEaLtZk4GYOSmZXRjZsBzzERh9L8
+ xDMeT7tPlDTZa0RdnOwBqcDq6MZO8x41cSgMFiPyRO2gVagVFXEqBKIid+c93HZeY1mcatJU
+ LJ5r94nMWZV6WRKnShB24F2uKh4wrDhiOS0OpamDlzSVauaxOJW+PKE0szwSp9qX3x1KM88j
+ cXgbLSF/eDyqUZ78eG4EVK2VpbcVVA1KVbx3zirXx/KLpSoHpxKURpflH0ApDz4Iv9FUmlLU
+ biuoJI/mjWHRRH2Pay1UiecZtYs8K8lTAVRpqtSJyevaKwQmM6jSVMLkRrYqR5WMZCjWCvVh
+ dut0heBo4RGLaGF26jYHpg/roDw+RBfpjDTZa8P88VA877ElozTn/5utLr7fVuD9gdkChUq0
+ MAe7jWdn3B+BS4HWQClOLWkydp2DsIeuo9zKmwEUWRrMF8hrPtC6EMrVAwhruGLxkI+MXQdC
+ nAaaQFEgCnPAJ+P8D5Q4jR0FQi9Aa2mydR3ot05XOg+SCgMx7mf4XOk+ny2hKHO9RCWJGsjx
+ PvCOM3rXOefrx6iGLk+jokRojLwlO0OtWPFyjoM8uvWwksijMBCLL/pAhN51Gr/F6S0WManv
+ GFlvZFLQiwJ5bWjc7qpllOcdM0/w34GZ712xPkZ5ux2dbXTTZIdxDfFAgdiZrzka/h0nOsFV
+ QCoKlHVk5FuckYTu0H2QCtsSre9odUBFz8PUlQM7dZ9q4xpyMaLSy83Saz52kUebqKNpNmmQ
+ u47Ki6UoED6WBbjjQfSHOLOGVxco87iGesTOgpQT1aujqwjk9VQaq8+IGgOz5/0JJrcVVBHI
+ m9Xiq9hdUM9zXsTRXGglgSyOqFqxRiysCtzl2+VGtowCoR7pGohr22lcc70DNKNA1lwFfVd8
+ iMLsSFcc66NtVoEifyWnML68y3PoMwfOxYAoEX+ofA7yuaAmojjei814P74miMVBZCCfctNA
+ eMTq03MQkp+R/EKLc2X3rkRwuBUnw/hwtz5KRaxI1XGeMiL9zLtcdr0HZZTMGwSj634rTpVk
+ SqB9t+rxrkLpjmOJ5SYB5cFnSBwm0h/G3J8nB0J2nAW4NV2Hp3mkOItwZNuTYXGYRBnKk5uZ
+ 3LHjJCCjPNXH2EfiZEygF9ULpSqzOWPHUYQjWy5WcvVYHCYwjt1jj/T9pzoO0hdAw3pkY+x1
+ WM0RR7WEUJ54psVh8mQ8NgoY/3k0crPUcZg8GcqDudOotR6OaslBl6cqy+IwcTJeR1zmYAzN
+ XKh0HCZOhvLUhKNaISiPjPbBS00cJk3G8ySZeXjFIvaqHYdJk6E8teCoVhQEeRC2oq3WoC4O
+ QsJQ8f5do31WlXw8/R6WsTbpOJRHJuJHwR3zYR1js1Ftx2SNEiVP+2zPz43AI7am5ziURybq
+ cpTqOfGKqfnmQPVErRApT/t878+2xDOWLrtqlEcm8kLISnnxjqHbdnSlJGkTLU9bQ8TnaxAR
+ O9ffcSiPTPQl+FlzExUz9x9AsybIAwR52jq0/pYlkbEKuXKA8shEy3OAOL4hvJ3vTNglN5RH
+ BkGeg/MakHKFEJvQa9UojwyKPA2ULoQSk/CLPCmPDJo8B5ECIcUiXJwDyiODKM+B9xiHFgMI
+ cQ5QRgFEUOVp7HjggxGnsWMSRsggT/QaPIET54Dy9Gkx2a1IEYEU54DyyKB3nx2AFeeA5z0y
+ lCcWaHEa7D59OLrFkUKcA8ojw+7jTxpxDji6yVAeX1KJ02D36cPRzY+U4hxQHhl2H3vSinNA
+ eWQojy2pxTngeY8MRzc70ovTQL13BAEKpE8Zcc6wC/U5x4MSrVFSnAYFkmEXWqO0OA2OcTIU
+ aI4txDnDLtSHAj1jO3Ea7EJ9eB40xrbinKFEfdiFZCjOBUr0E0rTh+LcsKtElOU9FGeQazFV
+ E4myPIPiTJK9G1GUNSiOAndFiCQVZdGD4hgzUqwrclGGGCgOACz+fPwHwrxYlCRUiFQAAAAA
+ SUVORK5CYII=
+ </office:binary-data>
+ </draw:image>
+ </draw:frame>
+ <draw:frame draw:style-name="gr3" draw:text-style-name="P4" draw:layer="layout" svg:width="4.481cm" svg:height="0.962cm" svg:x="7.806cm" svg:y="15.838cm">
+ <draw:text-box>
+ <text:p>Knot Resolver</text:p>
+ </draw:text-box>
+ </draw:frame>
+ </draw:g>
+ <draw:g>
+ <draw:frame draw:name="noun_servers_1653083.svg" draw:style-name="gr1" draw:text-style-name="P1" draw:layer="layout" svg:width="2.43cm" svg:height="2.35cm" svg:x="3.4cm" svg:y="21.55cm">
+ <draw:image loext:mime-type="image/svg+xml">
+ <office:binary-data>PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+
+ CjxzdmcKICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgog
+ ICB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIgogICB4bWxuczpy
+ ZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiCiAgIHht
+ bG5zOnN2Zz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciCiAgIHhtbG5zPSJodHRwOi8v
+ d3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgeG1sbnM6c29kaXBvZGk9Imh0dHA6Ly9zb2RpcG9k
+ aS5zb3VyY2Vmb3JnZS5uZXQvRFREL3NvZGlwb2RpLTAuZHRkIgogICB4bWxuczppbmtzY2Fw
+ ZT0iaHR0cDovL3d3dy5pbmtzY2FwZS5vcmcvbmFtZXNwYWNlcy9pbmtzY2FwZSIKICAgZGF0
+ YS1uYW1lPSJMYXllciAxIgogICB2aWV3Qm94PSIwIDAgODggODUuMDAwMDAzIgogICB4PSIw
+ cHgiCiAgIHk9IjBweCIKICAgdmVyc2lvbj0iMS4xIgogICBpZD0ic3ZnMTIzIgogICBzb2Rp
+ cG9kaTpkb2NuYW1lPSJub3VuX3NlcnZlcnNfMTY1MzA4My5zdmciCiAgIHdpZHRoPSI4OCIK
+ ICAgaGVpZ2h0PSI4NSIKICAgaW5rc2NhcGU6dmVyc2lvbj0iMC45Mi40IDVkYTY4OWMzMTMs
+ IDIwMTktMDEtMTQiPgogIDxtZXRhZGF0YQogICAgIGlkPSJtZXRhZGF0YTEyOSI+CiAgICA8
+ cmRmOlJERj4KICAgICAgPGNjOldvcmsKICAgICAgICAgcmRmOmFib3V0PSIiPgogICAgICAg
+ IDxkYzpmb3JtYXQ+aW1hZ2Uvc3ZnK3htbDwvZGM6Zm9ybWF0PgogICAgICAgIDxkYzp0eXBl
+ CiAgICAgICAgICAgcmRmOnJlc291cmNlPSJodHRwOi8vcHVybC5vcmcvZGMvZGNtaXR5cGUv
+ U3RpbGxJbWFnZSIgLz4KICAgICAgICA8ZGM6dGl0bGU+ZGF0YSwgc2VydmVyLCBkYXRhYmFz
+ ZSxkYiwgaG9zdGluZzwvZGM6dGl0bGU+CiAgICAgIDwvY2M6V29yaz4KICAgIDwvcmRmOlJE
+ Rj4KICA8L21ldGFkYXRhPgogIDxkZWZzCiAgICAgaWQ9ImRlZnMxMjciIC8+CiAgPHNvZGlw
+ b2RpOm5hbWVkdmlldwogICAgIHBhZ2Vjb2xvcj0iI2ZmZmZmZiIKICAgICBib3JkZXJjb2xv
+ cj0iIzY2NjY2NiIKICAgICBib3JkZXJvcGFjaXR5PSIxIgogICAgIG9iamVjdHRvbGVyYW5j
+ ZT0iMTAiCiAgICAgZ3JpZHRvbGVyYW5jZT0iMTAiCiAgICAgZ3VpZGV0b2xlcmFuY2U9IjEw
+ IgogICAgIGlua3NjYXBlOnBhZ2VvcGFjaXR5PSIwIgogICAgIGlua3NjYXBlOnBhZ2VzaGFk
+ b3c9IjIiCiAgICAgaW5rc2NhcGU6d2luZG93LXdpZHRoPSI2MzYiCiAgICAgaW5rc2NhcGU6
+ d2luZG93LWhlaWdodD0iMTA1NCIKICAgICBpZD0ibmFtZWR2aWV3MTI1IgogICAgIHNob3dn
+ cmlkPSJmYWxzZSIKICAgICBmaXQtbWFyZ2luLXRvcD0iMCIKICAgICBmaXQtbWFyZ2luLWxl
+ ZnQ9IjAiCiAgICAgZml0LW1hcmdpbi1yaWdodD0iMCIKICAgICBmaXQtbWFyZ2luLWJvdHRv
+ bT0iMCIKICAgICBpbmtzY2FwZTp6b29tPSIxLjg4OCIKICAgICBpbmtzY2FwZTpjeD0iNDQi
+ CiAgICAgaW5rc2NhcGU6Y3k9IjMwLjUwMDAwNCIKICAgICBpbmtzY2FwZTp3aW5kb3cteD0i
+ NjQyIgogICAgIGlua3NjYXBlOndpbmRvdy15PSIyIgogICAgIGlua3NjYXBlOndpbmRvdy1t
+ YXhpbWl6ZWQ9IjEiCiAgICAgaW5rc2NhcGU6Y3VycmVudC1sYXllcj0ic3ZnMTIzIiAvPgog
+ IDx0aXRsZQogICAgIGlkPSJ0aXRsZTk3Ij5kYXRhLCBzZXJ2ZXIsIGRhdGFiYXNlLGRiLCBo
+ b3N0aW5nPC90aXRsZT4KICA8cmVjdAogICAgIHg9IjEwIgogICAgIHk9IjkiCiAgICAgd2lk
+ dGg9IjQiCiAgICAgaGVpZ2h0PSI2IgogICAgIGlkPSJyZWN0OTkiIC8+CiAgPHJlY3QKICAg
+ ICB4PSIxOCIKICAgICB5PSI5IgogICAgIHdpZHRoPSI0IgogICAgIGhlaWdodD0iNiIKICAg
+ ICBpZD0icmVjdDEwMSIgLz4KICA8cmVjdAogICAgIHg9IjI2IgogICAgIHk9IjkiCiAgICAg
+ d2lkdGg9IjQiCiAgICAgaGVpZ2h0PSI2IgogICAgIGlkPSJyZWN0MTAzIiAvPgogIDxyZWN0
+ CiAgICAgeD0iMTAiCiAgICAgeT0iMzYiCiAgICAgd2lkdGg9IjQiCiAgICAgaGVpZ2h0PSI2
+ IgogICAgIGlkPSJyZWN0MTA1IiAvPgogIDxyZWN0CiAgICAgeD0iMTgiCiAgICAgeT0iMzYi
+ CiAgICAgd2lkdGg9IjQiCiAgICAgaGVpZ2h0PSI2IgogICAgIGlkPSJyZWN0MTA3IiAvPgog
+ IDxyZWN0CiAgICAgeD0iMjYiCiAgICAgeT0iMzYiCiAgICAgd2lkdGg9IjQiCiAgICAgaGVp
+ Z2h0PSI2IgogICAgIGlkPSJyZWN0MTA5IiAvPgogIDxyZWN0CiAgICAgeD0iMTAiCiAgICAg
+ eT0iNjMiCiAgICAgd2lkdGg9IjQiCiAgICAgaGVpZ2h0PSI2IgogICAgIGlkPSJyZWN0MTEx
+ IiAvPgogIDxyZWN0CiAgICAgeD0iMTgiCiAgICAgeT0iNjMiCiAgICAgd2lkdGg9IjQiCiAg
+ ICAgaGVpZ2h0PSI2IgogICAgIGlkPSJyZWN0MTEzIiAvPgogIDxyZWN0CiAgICAgeD0iMjYi
+ CiAgICAgeT0iNjMiCiAgICAgd2lkdGg9IjQiCiAgICAgaGVpZ2h0PSI2IgogICAgIGlkPSJy
+ ZWN0MTE1IiAvPgogIDxwYXRoCiAgICAgZD0iTSA2MS41LDcgSCA2MCBWIDUgQSA1LDUgMCAw
+ IDAgNTUsMCBIIDUgQSA1LDUgMCAwIDAgMCw1IHYgMTQgYSA1LDUgMCAwIDAgNSw1IGggMSB2
+ IDMgSCA1IGEgNSw1IDAgMCAwIC01LDUgdiAxNCBhIDUsNSAwIDAgMCA1LDUgaCAxIHYgMyBI
+ IDUgYSA1LDUgMCAwIDAgLTUsNSB2IDE0IGEgNSw1IDAgMCAwIDUsNSBoIDEgdiA3IGggNDgg
+ diAtNyBoIDEgYSA1LDUgMCAwIDAgNSwtNSB2IC0xIGggMS41IEMgNzQuMjYsNzIgODgsNjku
+ MDkgODgsNjIuNzEgdiAtNDYuODEgMCBDIDg3Ljg0LDkuNzkgNzQuMTksNyA2MS41LDcgWiBN
+ IDUsMjAgQSAxLDEgMCAwIDEgNCwxOSBWIDUgQSAxLDEgMCAwIDEgNSw0IGggNTAgYSAxLDEg
+ MCAwIDEgMSwxIFYgNy4xOCBDIDQ1LjE1LDcuODcgMzUuMTMsMTAuNjcgMzUsMTUuOSB2IDAg
+ NC4xIHogbSAzMCw0IHYgMyBIIDEwIFYgMjQgWiBNIDUsNDcgQSAxLDEgMCAwIDEgNCw0NiBW
+ IDMyIGEgMSwxIDAgMCAxIDEsLTEgaCAzMCB2IDE2IHogbSAzMCw0IHYgMyBIIDEwIFYgNTEg
+ WiBNIDUwLDgxIEggMTAgdiAtMyBoIDQwIHogbSA2LC04IGEgMSwxIDAgMCAxIC0xLDEgSCA1
+ IEEgMSwxIDAgMCAxIDQsNzMgViA1OSBhIDEsMSAwIDAgMSAxLC0xIGggMzAgdiA0LjcxIGMg
+ MCw1LjQ3IDEwLjA4LDguMzggMjEsOS4xMSB6IE0gODQsNjIuNzEgQyA4NCw2NC4yOSA3Ni4z
+ NCw2OCA2MS41LDY4IDQ2LjY2LDY4IDM5LDY0LjI5IDM5LDYyLjcxIFYgNTIuOSBDIDQ0LDU1
+ LjY5IDUzLDU3IDYxLjUsNTcgNzAsNTcgNzksNTUuNjkgODQsNTIuOSBaIE0gODQsNDcuNjQg
+ QyA4NCw0OS4yNSA3Ni4zNCw1MyA2MS41LDUzIDQ2LjY2LDUzIDM5LDQ5LjI1IDM5LDQ3LjY0
+ IFYgMzcgYyA1LDIuNzEgMTQsNCAyMi41LDQgQyA3MCw0MSA3OSwzOS43MiA4NCwzNyBaIE0g
+ ODQsMzEuODkgQyA4NCwzMy4zNyA3Ni4xMiwzNyA2MS41LDM3IDQ2Ljg4LDM3IDM5LDMzLjM3
+ IDM5LDMxLjg5IFYgMjEuMDYgQyA0NCwyMy43NCA1MywyNSA2MS41LDI1IDcwLDI1IDc5LDIz
+ Ljc0IDg0LDIxLjA2IFogTSA2MS41LDIxIEMgNDYsMjEgMzksMTcuMTYgMzksMTYgMzksMTQu
+ ODQgNDYsMTEgNjEuNSwxMSA3NywxMSA4NCwxNC44NCA4NCwxNiBjIDAsMS4xNiAtNyw1IC0y
+ Mi41LDUgeiIKICAgICBpZD0icGF0aDExNyIKICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3Vy
+ dmF0dXJlPSIwIiAvPgo8L3N2Zz4K
+ </office:binary-data>
+ <text:p/>
+ </draw:image>
+ <draw:image loext:mime-type="image/png">
+ <office:binary-data>iVBORw0KGgoAAAANSUhEUgAAAFkAAABWCAYAAACkXTp6AAACgUlEQVR4nO2d0Y6EIAwAz8T/
+ /+Xd44GNIYIg2E5r5+2yd2sZK0JtvP3z+fwFz7Iff9i2za3x/2TatI79k+xZcCKNT0v0ngPQ
+ OLg0WqL32geal9cqKMlzKtmD4EQaB0F0NZODdbxOciuzn7qCXUq+O0X0/N2dEzEkuQyiPODs
+ 5zOxSHF23KtxmMhkws2rRY6vJhsveYXg3itm9lg12WjJvYNedcO6+p7eeMpND1ZybUCaa/iz
+ Y9fiPIpGSr5zc9Eix9XK8iHJVwOd/TxhSfCRs91lzmZkJh+xIDhT28bjJWuWKEepTRl4yYmr
+ dag2V6sOE5IzK3eMK+O44lQyfYeVOcb5tPAZJ6YyuQU5MfCSe9ahBFpx7vkXrAwioxnv6NT0
+ y+SeLaPEjWZlveLOiXhijPjpYgbKks+1ZApDSzj6vE3lNW1amrymTUuTV7VpaYFr0/J4wl23
+ aVHAL+GinixE1JMFcVVP7v1yzTat8vuiniyA9qrkstRJ5pih2iJLeq8evOQjBOGPt86SiHoy
+ BMqSD9em5RHXmUwhJAsQkgUIyQKYbtOyQmSyAHjJburJ9DYtN/VkC21ar6gn04h6sjDa091w
+ PZnUpkUob9a4VU+mDaKEIHyqnkwXXGKunmxNcC+UJV+0aQkQbVoCuFnCkQnJAoRkAUy3aVkB
+ l8llRdByqRP9epwSN6VOErX6NmW6GX0TIlJyoudBArXUaeq9cCNPbAg7xSVvONRo06I/Gku4
+ eFcn6TUMmZGEMSG5pDXAp07AzJxvUnIL4gbInWQi0aYlQGSyACFZABNtWqtQ/bdEtQAId+Ze
+ yLHGdCFASBZg6slI0EdksgAhWYCQLEBTMmkZZJkvMtHRb/cyBPsAAAAASUVORK5CYII=
+ </office:binary-data>
+ </draw:image>
+ <svg:title>data, server, database,db, hosting</svg:title>
+ </draw:frame>
+ <draw:frame draw:style-name="gr4" draw:text-style-name="P3" draw:layer="layout" svg:width="3.144cm" svg:height="1.673cm" svg:x="3.043cm" svg:y="23.9cm">
+ <draw:text-box>
+ <text:p text:style-name="P2">upstream<text:line-break/>resolver</text:p>
+ </draw:text-box>
+ </draw:frame>
+ </draw:g>
+ <draw:g>
+ <draw:frame draw:style-name="gr5" draw:text-style-name="P3" draw:layer="layout" svg:width="1.979cm" svg:height="0.962cm" svg:x="9.057cm" svg:y="3.827cm">
+ <draw:text-box>
+ <text:p text:style-name="P2">client</text:p>
+ </draw:text-box>
+ </draw:frame>
+ <draw:frame draw:name="noun_terminal_1653060.svg" draw:style-name="gr1" draw:text-style-name="P1" draw:layer="layout" svg:width="2.49cm" svg:height="2.35cm" svg:x="8.801cm" svg:y="4.9cm">
+ <draw:image loext:mime-type="image/svg+xml">
+ <office:binary-data>PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+
+ CjxzdmcKICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgog
+ ICB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIgogICB4bWxuczpy
+ ZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiCiAgIHht
+ bG5zOnN2Zz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciCiAgIHhtbG5zPSJodHRwOi8v
+ d3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgeG1sbnM6c29kaXBvZGk9Imh0dHA6Ly9zb2RpcG9k
+ aS5zb3VyY2Vmb3JnZS5uZXQvRFREL3NvZGlwb2RpLTAuZHRkIgogICB4bWxuczppbmtzY2Fw
+ ZT0iaHR0cDovL3d3dy5pbmtzY2FwZS5vcmcvbmFtZXNwYWNlcy9pbmtzY2FwZSIKICAgZGF0
+ YS1uYW1lPSJMYXllciAxIgogICB2aWV3Qm94PSIwIDAgNzAgNjYiCiAgIHg9IjBweCIKICAg
+ eT0iMHB4IgogICB2ZXJzaW9uPSIxLjEiCiAgIGlkPSJzdmcxNDEiCiAgIHNvZGlwb2RpOmRv
+ Y25hbWU9Im5vdW5fdGVybWluYWxfMTY1MzA2MC5zdmciCiAgIHdpZHRoPSI3MCIKICAgaGVp
+ Z2h0PSI2NiIKICAgaW5rc2NhcGU6dmVyc2lvbj0iMC45Mi40IDVkYTY4OWMzMTMsIDIwMTkt
+ MDEtMTQiPgogIDxtZXRhZGF0YQogICAgIGlkPSJtZXRhZGF0YTE0NyI+CiAgICA8cmRmOlJE
+ Rj4KICAgICAgPGNjOldvcmsKICAgICAgICAgcmRmOmFib3V0PSIiPgogICAgICAgIDxkYzpm
+ b3JtYXQ+aW1hZ2Uvc3ZnK3htbDwvZGM6Zm9ybWF0PgogICAgICAgIDxkYzp0eXBlCiAgICAg
+ ICAgICAgcmRmOnJlc291cmNlPSJodHRwOi8vcHVybC5vcmcvZGMvZGNtaXR5cGUvU3RpbGxJ
+ bWFnZSIgLz4KICAgICAgICA8ZGM6dGl0bGU+ZGF0YSwgc2VydmVyLCBkYXRhYmFzZSwgbW9u
+ aXRvciwgdGVybWluYWw8L2RjOnRpdGxlPgogICAgICA8L2NjOldvcms+CiAgICA8L3JkZjpS
+ REY+CiAgPC9tZXRhZGF0YT4KICA8ZGVmcwogICAgIGlkPSJkZWZzMTQ1IiAvPgogIDxzb2Rp
+ cG9kaTpuYW1lZHZpZXcKICAgICBwYWdlY29sb3I9IiNmZmZmZmYiCiAgICAgYm9yZGVyY29s
+ b3I9IiM2NjY2NjYiCiAgICAgYm9yZGVyb3BhY2l0eT0iMSIKICAgICBvYmplY3R0b2xlcmFu
+ Y2U9IjEwIgogICAgIGdyaWR0b2xlcmFuY2U9IjEwIgogICAgIGd1aWRldG9sZXJhbmNlPSIx
+ MCIKICAgICBpbmtzY2FwZTpwYWdlb3BhY2l0eT0iMCIKICAgICBpbmtzY2FwZTpwYWdlc2hh
+ ZG93PSIyIgogICAgIGlua3NjYXBlOndpbmRvdy13aWR0aD0iOTU2IgogICAgIGlua3NjYXBl
+ OndpbmRvdy1oZWlnaHQ9IjEwNTQiCiAgICAgaWQ9Im5hbWVkdmlldzE0MyIKICAgICBzaG93
+ Z3JpZD0iZmFsc2UiCiAgICAgZml0LW1hcmdpbi10b3A9IjAiCiAgICAgZml0LW1hcmdpbi1s
+ ZWZ0PSIwIgogICAgIGZpdC1tYXJnaW4tcmlnaHQ9IjAiCiAgICAgZml0LW1hcmdpbi1ib3R0
+ b209IjAiCiAgICAgaW5rc2NhcGU6em9vbT0iNy41NTIiCiAgICAgaW5rc2NhcGU6Y3g9IjUy
+ LjIwNTQ4OCIKICAgICBpbmtzY2FwZTpjeT0iMzMuODcwMTc2IgogICAgIGlua3NjYXBlOndp
+ bmRvdy14PSI5NjIiCiAgICAgaW5rc2NhcGU6d2luZG93LXk9IjIiCiAgICAgaW5rc2NhcGU6
+ d2luZG93LW1heGltaXplZD0iMSIKICAgICBpbmtzY2FwZTpjdXJyZW50LWxheWVyPSJzdmcx
+ NDEiIC8+CiAgPHRpdGxlCiAgICAgaWQ9InRpdGxlMTMxIj5kYXRhLCBzZXJ2ZXIsIGRhdGFi
+ YXNlLCBtb25pdG9yLCB0ZXJtaW5hbDwvdGl0bGU+CiAgPHBhdGgKICAgICBkPSJNIDgsMzkg
+ SCA2MiBWIDggSCA4IFogTSAxMiwxMiBIIDU4IFYgMzUgSCAxMiBaIgogICAgIGlkPSJwYXRo
+ MTMzIgogICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiIC8+CiAgPHBhdGgK
+ ICAgICBkPSJtIDAsMCB2IDQ3IGggMjggdiA3LjA4IGMgLTMuNDQwOTI3LDAuNDk2NjUzIC01
+ Ljk5NTkyNSwzLjQ0MzQxOCAtNiw2LjkyIHYgNSBIIDQ4IFYgNjEgQyA0Ny45OTU5LDU3LjUy
+ MzQxOCA0NS40NDA5MjcsNTQuNTc2NjUzIDQyLDU0LjA4IFYgNDcgSCA3MCBWIDAgTSA0NCw2
+ MSB2IDEgSCAyNiB2IC0xIGMgMCwtMS42NTY4NTQgMS4zNDMxNDYsLTMgMywtMyBoIDEyIGMg
+ MS42NTY4NTQsMCAzLDEuMzQzMTQ2IDMsMyB6IE0gMzIsNTQgdiAtNyBoIDYgdiA3IHogTSA3
+ MCw1LjU5IFYgMCBNIDQsNDMgViA0IGggNjIgdiAzOSB6IgogICAgIGlkPSJwYXRoMTM1Igog
+ ICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgc29kaXBvZGk6bm9k
+ ZXR5cGVzPSJjY2NjY2NjY2NjY2NzY2Nzc3NzY2NjY2NjY2NjY2NjIiAvPgo8L3N2Zz4K
+ </office:binary-data>
+ <text:p/>
+ </draw:image>
+ <draw:image loext:mime-type="image/png">
+ <office:binary-data>iVBORw0KGgoAAAANSUhEUgAAAEcAAABDCAYAAADOIRgJAAABJklEQVR4nO3ZyRKCMBAAUVPF
+ //8yGk8WhGadJGD3wZO4PMcQimEcx5eVG/JDSkmhSZ+hSUPrD9Fz4kAznDxOLT5I60pLi5MD
+ iQOJA63iPPU0v2VtdXIgcSBxoN04d90HHVk7nRxIHEgcSBxIHEgcSBxIHEgcSBxIHEgcSBxI
+ HEgcSBxIHEgcSBxIHEgcSBxoN85Tbw+XcnIgcSBxoFWcu97+vSInBxIHEgea4fzTPmYtJwcS
+ BxIH+uLU3MtM17Sl9976vMicHEgcSBxIHEgcSByoOU7PlytVcc5A5GNr73Wq4Fw1Hb+vUwMq
+ HCfqb1NjkkJxSjBHv1CLtanqmnPml87HToGipycMJ+LCsQQUWfNTec9Vw+l5P7OUkwOJA4kD
+ heE84TbyGynKUBIg/xD7AAAAAElFTkSuQmCC
+ </office:binary-data>
+ </draw:image>
+ <svg:title>data, server, database, monitor, terminal</svg:title>
+ </draw:frame>
+ </draw:g>
+ <draw:line draw:style-name="gr6" draw:text-style-name="P5" draw:layer="layout" svg:x1="11.214cm" svg:y1="16.7cm" svg:x2="14.644cm" svg:y2="21.5cm">
+ <text:p/>
+ </draw:line>
+ <draw:line draw:style-name="gr7" draw:text-style-name="P5" draw:layer="layout" svg:x1="8.89cm" svg:y1="16.7cm" svg:x2="5.46cm" svg:y2="21.5cm">
+ <text:p/>
+ </draw:line>
+ <draw:line draw:style-name="gr6" draw:text-style-name="P5" draw:layer="layout" svg:x1="10.046cm" svg:y1="7.5cm" svg:x2="10.046cm" svg:y2="13.2cm">
+ <text:p/>
+ </draw:line>
+ <draw:frame draw:style-name="gr8" draw:text-style-name="P4" draw:layer="layout" svg:width="5.62cm" svg:height="2.384cm" svg:x="12.694cm" svg:y="16.726cm">
+ <draw:text-box>
+ <text:p><text:span text:style-name="T1"><text:line-break/></text:span><text:span text:style-name="T1">recursion</text:span></text:p>
+ <text:p>unencrypted DNS</text:p>
+ </draw:text-box>
+ </draw:frame>
+ <draw:frame draw:style-name="gr9" draw:text-style-name="P6" draw:layer="layout" svg:width="5.5cm" svg:height="3.806cm" svg:x="1.9cm" svg:y="16.726cm">
+ <draw:text-box>
+ <text:p><text:span text:style-name="T2">(optional)</text:span></text:p>
+ <text:p><text:span text:style-name="T1">forwarding</text:span></text:p>
+ <text:p>unencrypted DNS</text:p>
+ <text:p>DNS-over-TLS</text:p>
+ </draw:text-box>
+ </draw:frame>
+ <draw:g>
+ <draw:line draw:style-name="gr7" draw:text-style-name="P5" draw:layer="layout" svg:x1="6.246cm" svg:y1="22.9cm" svg:x2="14.246cm" svg:y2="22.9cm">
+ <text:p/>
+ </draw:line>
+ <draw:frame draw:style-name="gr10" draw:text-style-name="P4" draw:layer="layout" svg:width="3.393cm" svg:height="0.962cm" svg:x="8.55cm" svg:y="22.9cm">
+ <draw:text-box>
+ <text:p><text:span text:style-name="T1">recursion</text:span></text:p>
+ </draw:text-box>
+ </draw:frame>
+ </draw:g>
+ <draw:frame draw:style-name="gr11" draw:text-style-name="P4" draw:layer="layout" svg:width="7.529cm" svg:height="3.806cm" svg:x="10.188cm" svg:y="8.447cm">
+ <draw:text-box>
+ <text:p><text:span text:style-name="T1">client asking </text:span><text:span text:style-name="T1">questions</text:span></text:p>
+ <text:p><text:span text:style-name="T3">unencrypted DNS</text:span><text:span text:style-name="T3"><text:line-break/></text:span><text:span text:style-name="T3">DNS-over-TLS</text:span><text:span text:style-name="T3"><text:line-break/></text:span>DNS-over-HTTPS</text:p>
+ <text:p>HTTP management API</text:p>
+ </draw:text-box>
+ </draw:frame>
+ <draw:line draw:style-name="gr12" draw:text-style-name="P5" draw:layer="layout" svg:x1="11.4cm" svg:y1="14.6cm" svg:x2="18.45cm" svg:y2="14.6cm">
+ <text:p/>
+ </draw:line>
+ <draw:line draw:style-name="gr12" draw:text-style-name="P5" draw:layer="layout" svg:x1="1.8cm" svg:y1="14.6cm" svg:x2="8.85cm" svg:y2="14.6cm">
+ <text:p/>
+ </draw:line>
+ <draw:frame draw:style-name="gr13" draw:text-style-name="P7" draw:layer="layout" svg:width="3.821cm" svg:height="0.962cm" svg:x="11.2cm" svg:y="13.6cm">
+ <draw:text-box>
+ <text:p><text:span text:style-name="T4">... as server</text:span></text:p>
+ </draw:text-box>
+ </draw:frame>
+ <draw:frame draw:style-name="gr14" draw:text-style-name="P7" draw:layer="layout" svg:width="3.537cm" svg:height="0.962cm" svg:x="11.2cm" svg:y="14.6cm">
+ <draw:text-box>
+ <text:p><text:span text:style-name="T4">... as client</text:span></text:p>
+ </draw:text-box>
+ </draw:frame>
+ </draw:page>
+ </office:drawing>
+ </office:body>
+</office:document> \ No newline at end of file
diff --git a/doc/server_terminology.svg b/doc/server_terminology.svg
new file mode 100644
index 0000000..07502d2
--- /dev/null
+++ b/doc/server_terminology.svg
@@ -0,0 +1,1106 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ style="fill-rule:evenodd;stroke-width:28.22200012;stroke-linejoin:round"
+ id="svg687"
+ xml:space="preserve"
+ preserveAspectRatio="xMidYMid"
+ viewBox="0 0 16750.999 21747"
+ height="217.47mm"
+ width="167.50999mm"
+ version="1.2"><metadata
+ id="metadata691"><rdf:RDF><cc:Work
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title><cc:license
+ rdf:resource="SPDX-License-Identifier: GPL-3.0-or-later" /></cc:Work></rdf:RDF></metadata>
+ <defs
+ id="defs8"
+ class="ClipPathGroup"><clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="presentation_clip_path">
+ <rect
+ id="rect2"
+ height="29700"
+ width="21000"
+ y="0"
+ x="0" />
+ </clipPath></defs>
+ <defs
+ id="defs77" />
+ <defs
+ id="defs116" />
+ <defs
+ id="defs159" />
+ <defs
+ id="defs163"
+ class="TextShapeIndex" />
+ <defs
+ id="defs195"
+ class="EmbeddedBulletChars" />
+ <g
+ transform="translate(-1750,-3827)"
+ id="g200">
+ <g
+ class="Master_Slide"
+ id="id2">
+ <g
+ class="Background"
+ id="bg-id2" />
+ <g
+ class="BackgroundObjects"
+ id="bo-id2" />
+ </g>
+ </g>
+ <g
+ transform="translate(-1750,-3827)"
+ id="g685"
+ class="SlideGroup">
+ <g
+ id="g683">
+ <g
+ id="container-id1">
+ <g
+ clip-path="url(#presentation_clip_path)"
+ class="Slide"
+ id="id1">
+ <g
+ id="g679"
+ class="Page">
+ <g
+ id="g258"
+ class="Group">
+ <g
+ id="g239"
+ class="Graphic">
+ <title
+ id="title202">data, server, database, router, hardware
+ </title>
+ <g
+ id="id3">
+ <rect
+ style="fill:none;stroke:none"
+ id="rect204"
+ height="2351"
+ width="1671"
+ y="21550"
+ x="14641"
+ class="BoundingBox" />
+ <path
+ style="fill:#000000;stroke:none"
+ id="path206"
+ d="m 14983,22711 h -55 v -164 h 110 v 164 z" />
+ <path
+ style="fill:#000000;stroke:none"
+ id="path208"
+ d="m 15202,22711 h -55 v -164 h 110 v 164 z" />
+ <path
+ style="fill:#000000;stroke:none"
+ id="path210"
+ d="m 15421,22711 h -55 v -164 h 110 v 164 z" />
+ <path
+ style="fill:#000000;stroke:none"
+ id="path212"
+ d="m 15640,22711 h -54 v -164 h 109 v 164 z" />
+ <path
+ style="fill:#000000;stroke:none"
+ id="path214"
+ d="m 16024,22629 c 0,10 -3,19 -8,28 -5,8 -12,15 -20,20 -8,4 -18,7 -27,7 -10,0 -19,-3 -28,-7 -8,-5 -15,-12 -20,-20 -4,-9 -7,-18 -7,-28 0,-9 3,-19 7,-27 5,-8 12,-15 20,-20 9,-5 18,-7 28,-7 9,0 19,2 27,7 8,5 15,12 20,20 5,8 8,18 8,27 z" />
+ <path
+ style="fill:#000000;stroke:none"
+ id="path216"
+ d="m 16160,22219 c 24,0 48,-6 69,-18 21,-12 38,-29 50,-50 12,-21 18,-44 18,-68 v -383 c 0,-24 -6,-47 -18,-68 -12,-21 -29,-38 -50,-50 -21,-12 -45,-18 -69,-18 h -1368 c -24,0 -48,6 -69,18 -21,12 -38,29 -50,50 -12,21 -18,44 -18,68 v 383 c 0,24 6,47 18,68 12,21 29,38 50,50 21,12 45,18 69,18 h 27 v 82 h -27 c -24,0 -48,7 -69,19 -21,12 -38,29 -50,50 -12,21 -18,44 -18,68 v 383 c 0,24 6,47 18,68 12,21 29,38 50,50 21,12 45,18 69,18 h 27 v 82 h -27 c -24,0 -48,7 -69,19 -21,12 -38,29 -50,50 -12,20 -18,44 -18,68 v 382 c 0,24 6,48 18,69 12,21 29,38 50,50 21,12 45,18 69,18 h 27 v 191 h 1314 v -191 h 27 c 24,0 48,-6 69,-18 21,-12 38,-29 50,-50 12,-21 18,-45 18,-69 v -382 c 0,-24 -6,-48 -18,-68 -12,-21 -29,-38 -50,-50 -21,-12 -45,-19 -69,-19 h -27 v -82 h 27 c 24,0 48,-6 69,-18 21,-12 38,-29 50,-50 12,-21 18,-44 18,-68 v -383 c 0,-24 -6,-47 -18,-68 -12,-21 -29,-38 -50,-50 -21,-12 -45,-19 -69,-19 h -27 v -82 z m -136,1558 h -1096 v -82 h 1096 z m 136,-628 c 5,0 10,1 14,3 4,3 8,6 10,10 3,4 4,9 4,14 v 382 c 0,5 -1,10 -4,14 -2,4 -6,8 -10,10 -4,2 -9,4 -14,4 h -1368 c -5,0 -10,-2 -14,-4 -4,-2 -8,-6 -10,-10 -3,-4 -4,-9 -4,-14 v -382 c 0,-5 1,-10 4,-14 2,-4 6,-7 10,-10 4,-2 9,-3 14,-3 z m -1232,-110 v -82 h 1096 v 82 z m 1232,-628 c 5,0 10,1 14,3 4,3 8,6 10,10 3,5 4,9 4,14 v 383 c 0,4 -1,9 -4,13 -2,4 -6,8 -10,10 -4,3 -9,4 -14,4 h -1368 c -5,0 -10,-1 -14,-4 -4,-2 -8,-6 -10,-10 -3,-4 -4,-9 -4,-13 v -383 c 0,-5 1,-9 4,-14 2,-4 6,-7 10,-10 4,-2 9,-3 14,-3 z m -1232,-110 v -82 h 1096 v 82 z m -136,-191 c -5,0 -10,-1 -14,-3 -4,-3 -8,-6 -10,-10 -3,-5 -4,-9 -4,-14 v -383 c 0,-5 1,-9 4,-13 2,-5 6,-8 10,-10 4,-3 9,-4 14,-4 h 1368 c 5,0 10,1 14,4 4,2 8,5 10,10 3,4 4,8 4,13 v 383 c 0,5 -1,9 -4,14 -2,4 -6,7 -10,10 -4,2 -9,3 -14,3 z" />
+ <path
+ style="fill:#000000;stroke:none"
+ id="path218"
+ d="m 14983,21974 h -55 v -164 h 110 v 164 z" />
+ <path
+ style="fill:#000000;stroke:none"
+ id="path220"
+ d="m 15202,21974 h -55 v -164 h 110 v 164 z" />
+ <path
+ style="fill:#000000;stroke:none"
+ id="path222"
+ d="m 15421,21974 h -55 v -164 h 110 v 164 z" />
+ <path
+ style="fill:#000000;stroke:none"
+ id="path224"
+ d="m 15640,21974 h -54 v -164 h 109 v 164 z" />
+ <path
+ style="fill:#000000;stroke:none"
+ id="path226"
+ d="m 16024,21892 c 0,9 -3,19 -8,27 -5,8 -12,15 -20,20 -8,5 -18,7 -27,7 -10,0 -19,-2 -28,-7 -8,-5 -15,-12 -20,-20 -4,-8 -7,-18 -7,-27 0,-10 3,-19 7,-28 5,-8 12,-15 20,-20 9,-5 18,-7 28,-7 9,0 19,2 27,7 8,5 15,12 20,20 5,9 8,18 8,28 z" />
+ <path
+ style="fill:#000000;stroke:none"
+ id="path228"
+ d="m 14983,23449 h -55 v -164 h 110 v 164 z" />
+ <path
+ style="fill:#000000;stroke:none"
+ id="path230"
+ d="m 15202,23449 h -55 v -164 h 110 v 164 z" />
+ <path
+ style="fill:#000000;stroke:none"
+ id="path232"
+ d="m 15421,23449 h -55 v -164 h 110 v 164 z" />
+ <path
+ style="fill:#000000;stroke:none"
+ id="path234"
+ d="m 15640,23449 h -54 v -164 h 109 v 164 z" />
+ <path
+ style="fill:#000000;stroke:none"
+ id="path236"
+ d="m 16024,23367 c 0,10 -3,19 -8,27 -5,9 -12,16 -20,20 -8,5 -18,8 -27,8 -10,0 -19,-3 -28,-8 -8,-4 -15,-11 -20,-20 -4,-8 -7,-17 -7,-27 0,-9 3,-19 7,-27 5,-8 12,-15 20,-20 9,-5 18,-7 28,-7 9,0 19,2 27,7 8,5 15,12 20,20 5,8 8,18 8,27 z" />
+ </g>
+ </g>
+ <g
+ id="g256"
+ class="com.sun.star.drawing.TextShape">
+ <g
+ id="id4">
+ <rect
+ style="fill:none;stroke:none"
+ id="rect241"
+ height="1674"
+ width="3953"
+ y="23900"
+ x="13500"
+ class="BoundingBox" />
+ <text
+ id="text253"
+ class="TextShape"><tspan
+ style="font-weight:400;font-size:635px;font-family:'Liberation Sans', sans-serif"
+ id="tspan251"
+ font-weight="400"
+ font-size="635px"
+ class="TextParagraph"><tspan
+ id="tspan245"
+ y="24601"
+ x="13750"
+ class="TextPosition"><tspan
+ style="fill:#000000;stroke:none"
+ id="tspan243">authoritative</tspan></tspan><tspan
+ id="tspan249"
+ y="25312"
+ x="14595"
+ class="TextPosition"><tspan
+ style="fill:#000000;stroke:none"
+ id="tspan247">server</tspan></tspan></tspan></text>
+
+ </g>
+ </g>
+ </g>
+ <g
+ id="g287"
+ class="Group">
+ <g
+ id="g272"
+ class="Graphic">
+ <g
+ id="id5">
+ <rect
+ style="fill:none;stroke:none"
+ id="rect260"
+ height="2351"
+ width="2321"
+ y="13438"
+ x="8886"
+ class="BoundingBox" />
+ <defs
+ id="defs265"><clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clip_path_1">
+ <path
+ id="path262"
+ d="m 8886,13438 h 2320 v 2350 H 8886 Z" />
+ </clipPath></defs>
+ <g
+ id="g269"
+ clip-path="url(#clip_path_1)">
+ <path
+ style="fill:#00a2e2;stroke:none"
+ id="path267"
+ d="m 11206,14614 c 0,353 -157,669 -405,884 13,-71 21,-145 21,-220 0,-231 -69,-447 -186,-628 -46,64 -99,124 -156,178 74,132 116,286 116,450 0,66 -7,130 -21,193 -1,7 -3,13 -4,20 -1,7 -4,14 -5,20 -6,-2 -13,-3 -20,-5 -7,-2 -13,-4 -19,-7 -214,-70 -394,-215 -509,-404 -4,-5 -7,-12 -11,-18 -4,-5 -7,-12 -11,-18 -36,-66 -64,-137 -83,-211 -1,-7 -3,-13 -4,-20 -3,-7 -4,-14 -5,-20 -13,-62 -20,-128 -20,-194 0,-66 7,-130 20,-193 -71,-21 -146,-32 -224,-33 -15,73 -23,149 -23,225 0,78 8,153 23,226 1,7 2,13 4,20 2,7 4,14 5,20 18,77 44,151 78,222 3,7 5,13 9,19 3,7 6,14 10,20 136,265 371,470 658,567 -127,46 -263,72 -405,72 -580,0 -1061,-422 -1152,-975 6,5 10,9 16,14 204,178 471,286 762,286 19,0 39,0 58,-1 -33,-72 -58,-146 -76,-225 -232,-4 -442,-93 -603,-238 -6,-5 -10,-9 -16,-14 -6,-4 -10,-9 -15,-14 5,-5 9,-10 15,-15 4,-4 10,-9 15,-13 161,-145 371,-234 603,-239 6,0 13,0 18,0 h 4 c 6,0 14,0 21,0 78,3 153,14 225,34 7,2 14,3 19,6 7,2 14,4 20,5 125,41 238,107 333,194 54,-53 101,-113 141,-178 -113,-99 -246,-176 -391,-226 -7,-2 -14,-4 -19,-7 -7,-2 -14,-4 -21,-6 -74,-23 -150,-37 -230,-44 -7,-1 -15,-1 -22,-2 -8,0 -14,-2 -22,-2 -19,-1 -39,-1 -58,-1 -291,0 -558,108 -762,287 -6,4 -10,9 -16,13 91,-548 572,-970 1152,-970 142,0 278,26 404,72 v 0 c -286,97 -520,301 -657,566 80,8 157,23 233,47 115,-189 295,-334 509,-404 7,-2 13,-4 19,-7 7,-2 14,-3 20,-5 1,7 4,13 5,20 1,7 3,14 4,20 14,62 21,127 21,194 0,163 -42,316 -116,449 -4,6 -7,13 -11,18 -3,6 -6,13 -11,18 -39,65 -88,125 -142,178 -4,5 -10,10 -14,15 -5,4 -10,9 -15,13 -96,86 -209,152 -334,194 19,74 47,145 84,210 145,-50 277,-127 390,-226 5,-5 10,-9 15,-14 6,-4 11,-9 16,-14 58,-54 109,-114 154,-178 5,-5 8,-12 13,-18 4,-5 8,-12 12,-18 117,-181 186,-396 186,-626 0,-75 -7,-150 -21,-221 246,213 404,530 404,883 z" />
+ </g>
+ </g>
+ </g>
+ <g
+ id="g285"
+ class="com.sun.star.drawing.TextShape">
+ <g
+ id="id6">
+ <rect
+ style="fill:none;stroke:none"
+ id="rect274"
+ height="963"
+ width="4482"
+ y="15838"
+ x="7806"
+ class="BoundingBox" />
+ <text
+ id="text282"
+ class="TextShape"><tspan
+ style="font-weight:400;font-size:635px;font-family:'Liberation Sans', sans-serif"
+ id="tspan280"
+ font-weight="400"
+ font-size="635px"
+ class="TextParagraph"><tspan
+ id="tspan278"
+ y="16539"
+ x="8056"
+ class="TextPosition"><tspan
+ style="fill:#000000;stroke:none"
+ id="tspan276">Knot Resolver</tspan></tspan></tspan></text>
+
+ </g>
+ </g>
+ </g>
+ <g
+ id="g333"
+ class="Group">
+ <g
+ id="g314"
+ class="Graphic">
+ <title
+ id="title289">data, server, database,db, hosting
+ </title>
+ <g
+ id="id7">
+ <rect
+ style="fill:none;stroke:none"
+ id="rect291"
+ height="2351"
+ width="2431"
+ y="21550"
+ x="3400"
+ class="BoundingBox" />
+ <path
+ style="fill:#000000;stroke:none"
+ id="path293"
+ d="m 3741,21974 h -54 v -164 h 109 v 164 z" />
+ <path
+ style="fill:#000000;stroke:none"
+ id="path295"
+ d="m 3960,21974 h -55 v -164 h 109 v 164 z" />
+ <path
+ style="fill:#000000;stroke:none"
+ id="path297"
+ d="m 4178,21974 h -54 v -164 h 109 v 164 z" />
+ <path
+ style="fill:#000000;stroke:none"
+ id="path299"
+ d="m 3741,22711 h -54 v -164 h 109 v 164 z" />
+ <path
+ style="fill:#000000;stroke:none"
+ id="path301"
+ d="m 3960,22711 h -55 v -164 h 109 v 164 z" />
+ <path
+ style="fill:#000000;stroke:none"
+ id="path303"
+ d="m 4178,22711 h -54 v -164 h 109 v 164 z" />
+ <path
+ style="fill:#000000;stroke:none"
+ id="path305"
+ d="m 3741,23449 h -54 v -164 h 109 v 164 z" />
+ <path
+ style="fill:#000000;stroke:none"
+ id="path307"
+ d="m 3960,23449 h -55 v -164 h 109 v 164 z" />
+ <path
+ style="fill:#000000;stroke:none"
+ id="path309"
+ d="m 4178,23449 h -54 v -164 h 109 v 164 z" />
+ <path
+ style="fill:#000000;stroke:none"
+ id="path311"
+ d="m 5093,21755 h -41 v -55 c 0,-24 -6,-47 -18,-68 -12,-21 -30,-38 -50,-50 -21,-12 -45,-18 -69,-18 H 3550 c -24,0 -47,6 -68,18 -21,12 -38,29 -50,50 -12,21 -18,44 -18,68 v 383 c 0,24 6,47 18,68 12,21 29,38 50,50 21,12 44,18 68,18 h 27 v 82 h -27 c -24,0 -47,7 -68,19 -21,12 -38,29 -50,50 -12,21 -18,44 -18,68 v 383 c 0,24 6,47 18,68 12,21 29,38 50,50 21,12 44,18 68,18 h 27 v 82 h -27 c -24,0 -47,7 -68,19 -21,12 -38,29 -50,50 -12,20 -18,44 -18,68 v 382 c 0,24 6,48 18,69 12,21 29,38 50,50 21,12 44,18 68,18 h 27 v 191 h 1311 v -191 h 27 c 24,0 48,-6 69,-18 20,-12 38,-29 50,-50 12,-21 18,-45 18,-69 v -27 h 41 c 348,0 723,-79 723,-254 v -1279 c -4,-167 -377,-243 -723,-243 z m -1543,355 c -5,0 -9,-1 -13,-3 -5,-3 -8,-6 -10,-10 -3,-5 -4,-9 -4,-14 v -383 c 0,-5 1,-9 4,-13 2,-5 5,-8 10,-10 4,-3 8,-4 13,-4 h 1365 c 5,0 10,1 14,4 4,2 8,5 10,10 2,4 4,8 4,13 v 60 c -297,19 -570,95 -574,238 v 112 z m 819,109 v 82 h -682 v -82 z m -819,629 c -5,0 -9,-1 -13,-4 -5,-2 -8,-6 -10,-10 -3,-4 -4,-9 -4,-13 v -383 c 0,-5 1,-9 4,-14 2,-4 5,-7 10,-10 4,-2 8,-3 13,-3 h 819 v 437 z m 819,109 v 82 h -682 v -82 z m 410,820 H 3687 v -82 h 1092 z m 164,-219 c 0,5 -2,10 -4,14 -2,4 -6,8 -10,10 -4,2 -9,4 -14,4 H 3550 c -5,0 -9,-2 -13,-4 -5,-2 -8,-6 -10,-10 -3,-4 -4,-9 -4,-14 v -382 c 0,-5 1,-10 4,-14 2,-4 5,-7 10,-10 4,-2 8,-3 13,-3 h 819 v 128 c 0,150 275,229 574,249 z m 764,-281 c 0,43 -209,145 -614,145 -405,0 -615,-102 -615,-145 v -268 c 137,76 383,112 615,112 232,0 478,-36 614,-112 z m 0,-412 c 0,44 -209,147 -614,147 -405,0 -615,-103 -615,-147 v -290 c 137,74 383,109 615,109 232,0 478,-35 614,-109 z m 0,-430 c 0,41 -215,140 -614,140 -399,0 -615,-99 -615,-140 v -296 c 137,73 383,108 615,108 232,0 478,-35 614,-108 z m -614,-298 c -423,0 -615,-104 -615,-136 0,-32 192,-137 615,-137 423,0 614,105 614,137 0,32 -191,136 -614,136 z" />
+ </g>
+ </g>
+ <g
+ id="g331"
+ class="com.sun.star.drawing.TextShape">
+ <g
+ id="id8">
+ <rect
+ style="fill:none;stroke:none"
+ id="rect316"
+ height="1674"
+ width="3145"
+ y="23900"
+ x="3043"
+ class="BoundingBox" />
+ <text
+ id="text328"
+ class="TextShape"><tspan
+ style="font-weight:400;font-size:635px;font-family:'Liberation Sans', sans-serif"
+ id="tspan326"
+ font-weight="400"
+ font-size="635px"
+ class="TextParagraph"><tspan
+ id="tspan320"
+ y="24601"
+ x="3293"
+ class="TextPosition"><tspan
+ style="fill:#000000;stroke:none"
+ id="tspan318">upstream</tspan></tspan><tspan
+ id="tspan324"
+ y="25312"
+ x="3329"
+ class="TextPosition"><tspan
+ style="fill:#000000;stroke:none"
+ id="tspan322">resolvers</tspan></tspan></tspan></text>
+
+ </g>
+ </g>
+ </g>
+ <g
+ id="g359"
+ class="Group">
+ <g
+ id="g346"
+ class="com.sun.star.drawing.TextShape">
+ <g
+ id="id9">
+ <rect
+ style="fill:none;stroke:none"
+ id="rect335"
+ height="963"
+ width="2298"
+ y="3827"
+ x="8898"
+ class="BoundingBox" />
+ <text
+ id="text343"
+ class="TextShape"><tspan
+ style="font-weight:400;font-size:635px;font-family:'Liberation Sans', sans-serif"
+ id="tspan341"
+ font-weight="400"
+ font-size="635px"
+ class="TextParagraph"><tspan
+ id="tspan339"
+ y="4528"
+ x="9148"
+ class="TextPosition"><tspan
+ style="fill:#000000;stroke:none"
+ id="tspan337">clients</tspan></tspan></tspan></text>
+
+ </g>
+ </g>
+ <g
+ id="g357"
+ class="Graphic">
+ <title
+ id="title348">data, server, database, monitor, terminal
+ </title>
+ <g
+ id="id10">
+ <rect
+ style="fill:none;stroke:none"
+ id="rect350"
+ height="2351"
+ width="2491"
+ y="4900"
+ x="8801"
+ class="BoundingBox" />
+ <path
+ style="fill:#000000;stroke:none"
+ id="path352"
+ d="m 9099,6285 h 1894 V 5198 H 9099 Z m 140,-947 h 1614 v 807 H 9239 Z" />
+ <path
+ style="fill:#000000;stroke:none"
+ id="path354"
+ d="m 8819,4918 v 1648 h 982 v 248 c -121,18 -211,121 -211,243 v 175 h 912 v -175 c 0,-122 -90,-225 -211,-243 v -248 h 982 V 4918 Z m 1543,2139 v 35 h -632 v -35 c 0,-58 47,-105 106,-105 h 420 c 59,0 106,47 106,105 z m -421,-245 v -246 h 210 v 246 z M 8959,6426 V 5058 h 2174 v 1368 z" />
+ </g>
+ </g>
+ </g>
+ <g
+ id="g368"
+ class="com.sun.star.drawing.LineShape">
+ <g
+ id="id11">
+ <rect
+ style="fill:none;stroke:none"
+ id="rect361"
+ height="4851"
+ width="3481"
+ y="16650"
+ x="11164"
+ class="BoundingBox" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:100;stroke-linejoin:round"
+ id="path363"
+ d="m 11214,16700 3055,4275" />
+ <path
+ style="fill:#000000;stroke:none"
+ id="path365"
+ d="m 14644,21500 -209,-680 -367,262 z" />
+ </g>
+ </g>
+ <g
+ id="g409"
+ class="com.sun.star.drawing.LineShape">
+ <g
+ id="id12">
+ <rect
+ style="fill:none;stroke:none"
+ id="rect370"
+ height="4851"
+ width="3481"
+ y="16650"
+ x="5460"
+ class="BoundingBox" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:100;stroke-linejoin:round"
+ id="path372"
+ d="m 8890,16700 -115,160" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:100;stroke-linejoin:round"
+ id="path374"
+ d="m 8702,16964 -115,160" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:100;stroke-linejoin:round"
+ id="path376"
+ d="m 8513,17227 -114,161" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:100;stroke-linejoin:round"
+ id="path378"
+ d="m 8325,17491 -115,160" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:100;stroke-linejoin:round"
+ id="path380"
+ d="m 8137,17754 -115,161" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:100;stroke-linejoin:round"
+ id="path382"
+ d="m 7948,18018 -114,160" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:100;stroke-linejoin:round"
+ id="path384"
+ d="m 7760,18282 -115,160" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:100;stroke-linejoin:round"
+ id="path386"
+ d="m 7571,18545 -114,161" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:100;stroke-linejoin:round"
+ id="path388"
+ d="m 7383,18809 -115,160" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:100;stroke-linejoin:round"
+ id="path390"
+ d="m 7195,19073 -115,160" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:100;stroke-linejoin:round"
+ id="path392"
+ d="m 7006,19336 -114,160" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:100;stroke-linejoin:round"
+ id="path394"
+ d="m 6818,19600 -115,160" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:100;stroke-linejoin:round"
+ id="path396"
+ d="m 6630,19863 -115,161" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:100;stroke-linejoin:round"
+ id="path398"
+ d="m 6441,20127 -114,160" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:100;stroke-linejoin:round"
+ id="path400"
+ d="m 6253,20391 -115,160" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:100;stroke-linejoin:round"
+ id="path402"
+ d="m 6064,20654 -114,160" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:100;stroke-linejoin:round"
+ id="path404"
+ d="m 5876,20918 -41,57" />
+ <path
+ style="fill:#000000;stroke:none"
+ id="path406"
+ d="m 5460,21500 576,-418 -367,-262 z" />
+ </g>
+ </g>
+ <g
+ id="g418"
+ class="com.sun.star.drawing.LineShape">
+ <g
+ id="id13">
+ <rect
+ style="fill:none;stroke:none"
+ id="rect411"
+ height="5751"
+ width="451"
+ y="7450"
+ x="9821"
+ class="BoundingBox" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:100;stroke-linejoin:round"
+ id="path413"
+ d="m 10046,7500 v 5055" />
+ <path
+ style="fill:#000000;stroke:none"
+ id="path415"
+ d="m 10046,13200 225,-675 h -450 z" />
+ </g>
+ </g>
+ <g
+ id="g437"
+ class="com.sun.star.drawing.TextShape">
+ <g
+ id="id14">
+ <rect
+ style="fill:none;stroke:none"
+ id="rect420"
+ height="2385"
+ width="5621"
+ y="16726"
+ x="12694"
+ class="BoundingBox" />
+ <text
+ id="text434"
+ class="TextShape"><tspan
+ style="font-weight:700;font-size:635px;font-family:'Liberation Sans', sans-serif"
+ id="tspan426"
+ font-weight="700"
+ font-size="635px"
+ class="TextParagraph"><tspan
+ id="tspan424"
+ y="18138"
+ x="12944"
+ class="TextPosition"><tspan
+ style="fill:#000000;stroke:none"
+ id="tspan422">recursion</tspan></tspan></tspan><tspan
+ style="font-weight:400;font-size:635px;font-family:'Liberation Sans', sans-serif"
+ id="tspan432"
+ font-weight="400"
+ font-size="635px"
+ class="TextParagraph"><tspan
+ id="tspan430"
+ y="18849"
+ x="12944"
+ class="TextPosition"><tspan
+ style="fill:#000000;stroke:none"
+ id="tspan428">unencrypted DNS</tspan></tspan></tspan></text>
+
+ </g>
+ </g>
+ <g
+ id="g468"
+ class="com.sun.star.drawing.TextShape">
+ <g
+ id="id15">
+ <rect
+ style="fill:none;stroke:none"
+ id="rect439"
+ height="3807"
+ width="5501"
+ y="16726"
+ x="1900"
+ class="BoundingBox" />
+ <text
+ id="text465"
+ class="TextShape"><tspan
+ style="font-style:italic;font-weight:400;font-size:635px;font-family:'Liberation Sans', sans-serif"
+ id="tspan445"
+ font-weight="400"
+ font-style="italic"
+ font-size="635px"
+ class="TextParagraph"><tspan
+ id="tspan443"
+ y="17427"
+ x="2150"
+ class="TextPosition"><tspan
+ style="fill:#000000;stroke:none"
+ id="tspan441">(optional)</tspan></tspan></tspan><tspan
+ style="font-weight:700;font-size:635px;font-family:'Liberation Sans', sans-serif"
+ id="tspan451"
+ font-weight="700"
+ font-size="635px"
+ class="TextParagraph"><tspan
+ id="tspan449"
+ y="18138"
+ x="2150"
+ class="TextPosition"><tspan
+ style="fill:#000000;stroke:none"
+ id="tspan447">forwarding</tspan></tspan></tspan><tspan
+ style="font-weight:400;font-size:635px;font-family:'Liberation Sans', sans-serif"
+ id="tspan457"
+ font-weight="400"
+ font-size="635px"
+ class="TextParagraph"><tspan
+ id="tspan455"
+ y="18849"
+ x="2150"
+ class="TextPosition"><tspan
+ style="fill:#000000;stroke:none"
+ id="tspan453">unencrypted DNS</tspan></tspan></tspan><tspan
+ style="font-weight:400;font-size:635px;font-family:'Liberation Sans', sans-serif"
+ id="tspan463"
+ font-weight="400"
+ font-size="635px"
+ class="TextParagraph"><tspan
+ id="tspan461"
+ y="19560"
+ x="2150"
+ class="TextPosition"><tspan
+ style="fill:#000000;stroke:none"
+ id="tspan459">DNS-over-TLS</tspan></tspan></tspan></text>
+
+ </g>
+ </g>
+ <g
+ id="g536"
+ class="Group">
+ <g
+ id="g521"
+ class="com.sun.star.drawing.LineShape">
+ <g
+ id="id16">
+ <rect
+ style="fill:none;stroke:none"
+ id="rect470"
+ height="451"
+ width="8051"
+ y="22675"
+ x="6196"
+ class="BoundingBox" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:100;stroke-linejoin:round"
+ id="path472"
+ d="m 6246,22900 h 197" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:100;stroke-linejoin:round"
+ id="path474"
+ d="m 6570,22900 h 197" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:100;stroke-linejoin:round"
+ id="path476"
+ d="m 6894,22900 h 197" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:100;stroke-linejoin:round"
+ id="path478"
+ d="m 7218,22900 h 197" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:100;stroke-linejoin:round"
+ id="path480"
+ d="m 7542,22900 h 197" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:100;stroke-linejoin:round"
+ id="path482"
+ d="m 7866,22900 h 197" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:100;stroke-linejoin:round"
+ id="path484"
+ d="m 8190,22900 h 197" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:100;stroke-linejoin:round"
+ id="path486"
+ d="m 8514,22900 h 197" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:100;stroke-linejoin:round"
+ id="path488"
+ d="m 8838,22900 h 197" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:100;stroke-linejoin:round"
+ id="path490"
+ d="m 9162,22900 h 197" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:100;stroke-linejoin:round"
+ id="path492"
+ d="m 9486,22900 h 197" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:100;stroke-linejoin:round"
+ id="path494"
+ d="m 9810,22900 h 197" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:100;stroke-linejoin:round"
+ id="path496"
+ d="m 10134,22900 h 197" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:100;stroke-linejoin:round"
+ id="path498"
+ d="m 10458,22900 h 197" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:100;stroke-linejoin:round"
+ id="path500"
+ d="m 10782,22900 h 197" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:100;stroke-linejoin:round"
+ id="path502"
+ d="m 11106,22900 h 197" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:100;stroke-linejoin:round"
+ id="path504"
+ d="m 11430,22900 h 197" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:100;stroke-linejoin:round"
+ id="path506"
+ d="m 11754,22900 h 197" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:100;stroke-linejoin:round"
+ id="path508"
+ d="m 12078,22900 h 197" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:100;stroke-linejoin:round"
+ id="path510"
+ d="m 12402,22900 h 197" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:100;stroke-linejoin:round"
+ id="path512"
+ d="m 12726,22900 h 197" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:100;stroke-linejoin:round"
+ id="path514"
+ d="m 13050,22900 h 197" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:100;stroke-linejoin:round"
+ id="path516"
+ d="m 13374,22900 h 197" />
+ <path
+ style="fill:#000000;stroke:none"
+ id="path518"
+ d="m 14246,22900 -675,-225 v 450 z" />
+ </g>
+ </g>
+ <g
+ id="g534"
+ class="com.sun.star.drawing.TextShape">
+ <g
+ id="id17">
+ <rect
+ style="fill:none;stroke:none"
+ id="rect523"
+ height="963"
+ width="3394"
+ y="22900"
+ x="8550"
+ class="BoundingBox" />
+ <text
+ id="text531"
+ class="TextShape"><tspan
+ style="font-weight:700;font-size:635px;font-family:'Liberation Sans', sans-serif"
+ id="tspan529"
+ font-weight="700"
+ font-size="635px"
+ class="TextParagraph"><tspan
+ id="tspan527"
+ y="23601"
+ x="8800"
+ class="TextPosition"><tspan
+ style="fill:#000000;stroke:none"
+ id="tspan525">recursion</tspan></tspan></tspan></text>
+
+ </g>
+ </g>
+ </g>
+ <g
+ id="g569"
+ class="com.sun.star.drawing.TextShape">
+ <g
+ id="id18">
+ <rect
+ style="fill:none;stroke:none"
+ id="rect538"
+ height="4518"
+ width="8113"
+ y="8447"
+ x="10188"
+ class="BoundingBox" />
+ <text
+ id="text566"
+ class="TextShape"><tspan
+ style="font-weight:700;font-size:635px;font-family:'Liberation Sans', sans-serif"
+ id="tspan544"
+ font-weight="700"
+ font-size="635px"
+ class="TextParagraph"><tspan
+ id="tspan542"
+ y="9148"
+ x="10438"
+ class="TextPosition"><tspan
+ style="fill:#000000;stroke:none"
+ id="tspan540">clients asking questions</tspan></tspan></tspan><tspan
+ style="font-weight:400;font-size:635px;font-family:'Liberation Sans', sans-serif"
+ id="tspan558"
+ font-weight="400"
+ font-size="635px"
+ class="TextParagraph"><tspan
+ id="tspan548"
+ y="9859"
+ x="10438"
+ class="TextPosition"><tspan
+ style="fill:#000000;stroke:none"
+ id="tspan546">unencrypted DNS</tspan></tspan><tspan
+ id="tspan552"
+ y="10570"
+ x="10438"
+ class="TextPosition"><tspan
+ style="fill:#000000;stroke:none"
+ id="tspan550">DNS-over-TLS</tspan></tspan><tspan
+ id="tspan556"
+ y="11281"
+ x="10438"
+ class="TextPosition"><tspan
+ style="fill:#000000;stroke:none"
+ id="tspan554">DNS-over-HTTPS</tspan></tspan></tspan><tspan
+ style="font-weight:400;font-size:635px;font-family:'Liberation Sans', sans-serif"
+ id="tspan564"
+ font-weight="400"
+ font-size="635px"
+ class="TextParagraph"><tspan
+ id="tspan562"
+ y="11992"
+ x="10438"
+ class="TextPosition"><tspan
+ style="fill:#000000;stroke:none"
+ id="tspan560">HTTP management API</tspan></tspan></tspan></text>
+
+ </g>
+ </g>
+ <g
+ id="g610"
+ class="com.sun.star.drawing.LineShape">
+ <g
+ id="id19">
+ <rect
+ style="fill:none;stroke:none"
+ id="rect571"
+ height="101"
+ width="7151"
+ y="14550"
+ x="11350"
+ class="BoundingBox" />
+ <path
+ style="fill:none;stroke:#666666;stroke-width:100;stroke-linejoin:round"
+ id="path573"
+ d="m 11400,14600 h 197" />
+ <path
+ style="fill:none;stroke:#666666;stroke-width:100;stroke-linejoin:round"
+ id="path575"
+ d="m 11794,14600 h 197" />
+ <path
+ style="fill:none;stroke:#666666;stroke-width:100;stroke-linejoin:round"
+ id="path577"
+ d="m 12188,14600 h 197" />
+ <path
+ style="fill:none;stroke:#666666;stroke-width:100;stroke-linejoin:round"
+ id="path579"
+ d="m 12582,14600 h 197" />
+ <path
+ style="fill:none;stroke:#666666;stroke-width:100;stroke-linejoin:round"
+ id="path581"
+ d="m 12976,14600 h 197" />
+ <path
+ style="fill:none;stroke:#666666;stroke-width:100;stroke-linejoin:round"
+ id="path583"
+ d="m 13370,14600 h 197" />
+ <path
+ style="fill:none;stroke:#666666;stroke-width:100;stroke-linejoin:round"
+ id="path585"
+ d="m 13764,14600 h 197" />
+ <path
+ style="fill:none;stroke:#666666;stroke-width:100;stroke-linejoin:round"
+ id="path587"
+ d="m 14158,14600 h 197" />
+ <path
+ style="fill:none;stroke:#666666;stroke-width:100;stroke-linejoin:round"
+ id="path589"
+ d="m 14552,14600 h 197" />
+ <path
+ style="fill:none;stroke:#666666;stroke-width:100;stroke-linejoin:round"
+ id="path591"
+ d="m 14946,14600 h 197" />
+ <path
+ style="fill:none;stroke:#666666;stroke-width:100;stroke-linejoin:round"
+ id="path593"
+ d="m 15340,14600 h 197" />
+ <path
+ style="fill:none;stroke:#666666;stroke-width:100;stroke-linejoin:round"
+ id="path595"
+ d="m 15734,14600 h 197" />
+ <path
+ style="fill:none;stroke:#666666;stroke-width:100;stroke-linejoin:round"
+ id="path597"
+ d="m 16128,14600 h 197" />
+ <path
+ style="fill:none;stroke:#666666;stroke-width:100;stroke-linejoin:round"
+ id="path599"
+ d="m 16522,14600 h 197" />
+ <path
+ style="fill:none;stroke:#666666;stroke-width:100;stroke-linejoin:round"
+ id="path601"
+ d="m 16916,14600 h 197" />
+ <path
+ style="fill:none;stroke:#666666;stroke-width:100;stroke-linejoin:round"
+ id="path603"
+ d="m 17310,14600 h 197" />
+ <path
+ style="fill:none;stroke:#666666;stroke-width:100;stroke-linejoin:round"
+ id="path605"
+ d="m 17704,14600 h 197" />
+ <path
+ style="fill:none;stroke:#666666;stroke-width:100;stroke-linejoin:round"
+ id="path607"
+ d="m 18098,14600 h 197" />
+ </g>
+ </g>
+ <g
+ id="g651"
+ class="com.sun.star.drawing.LineShape">
+ <g
+ id="id20">
+ <rect
+ style="fill:none;stroke:none"
+ id="rect612"
+ height="101"
+ width="7151"
+ y="14550"
+ x="1750"
+ class="BoundingBox" />
+ <path
+ style="fill:none;stroke:#666666;stroke-width:100;stroke-linejoin:round"
+ id="path614"
+ d="m 1800,14600 h 197" />
+ <path
+ style="fill:none;stroke:#666666;stroke-width:100;stroke-linejoin:round"
+ id="path616"
+ d="m 2194,14600 h 197" />
+ <path
+ style="fill:none;stroke:#666666;stroke-width:100;stroke-linejoin:round"
+ id="path618"
+ d="m 2588,14600 h 197" />
+ <path
+ style="fill:none;stroke:#666666;stroke-width:100;stroke-linejoin:round"
+ id="path620"
+ d="m 2982,14600 h 197" />
+ <path
+ style="fill:none;stroke:#666666;stroke-width:100;stroke-linejoin:round"
+ id="path622"
+ d="m 3376,14600 h 197" />
+ <path
+ style="fill:none;stroke:#666666;stroke-width:100;stroke-linejoin:round"
+ id="path624"
+ d="m 3770,14600 h 197" />
+ <path
+ style="fill:none;stroke:#666666;stroke-width:100;stroke-linejoin:round"
+ id="path626"
+ d="m 4164,14600 h 197" />
+ <path
+ style="fill:none;stroke:#666666;stroke-width:100;stroke-linejoin:round"
+ id="path628"
+ d="m 4558,14600 h 197" />
+ <path
+ style="fill:none;stroke:#666666;stroke-width:100;stroke-linejoin:round"
+ id="path630"
+ d="m 4952,14600 h 197" />
+ <path
+ style="fill:none;stroke:#666666;stroke-width:100;stroke-linejoin:round"
+ id="path632"
+ d="m 5346,14600 h 197" />
+ <path
+ style="fill:none;stroke:#666666;stroke-width:100;stroke-linejoin:round"
+ id="path634"
+ d="m 5740,14600 h 197" />
+ <path
+ style="fill:none;stroke:#666666;stroke-width:100;stroke-linejoin:round"
+ id="path636"
+ d="m 6134,14600 h 197" />
+ <path
+ style="fill:none;stroke:#666666;stroke-width:100;stroke-linejoin:round"
+ id="path638"
+ d="m 6528,14600 h 197" />
+ <path
+ style="fill:none;stroke:#666666;stroke-width:100;stroke-linejoin:round"
+ id="path640"
+ d="m 6922,14600 h 197" />
+ <path
+ style="fill:none;stroke:#666666;stroke-width:100;stroke-linejoin:round"
+ id="path642"
+ d="m 7316,14600 h 197" />
+ <path
+ style="fill:none;stroke:#666666;stroke-width:100;stroke-linejoin:round"
+ id="path644"
+ d="m 7710,14600 h 197" />
+ <path
+ style="fill:none;stroke:#666666;stroke-width:100;stroke-linejoin:round"
+ id="path646"
+ d="m 8104,14600 h 197" />
+ <path
+ style="fill:none;stroke:#666666;stroke-width:100;stroke-linejoin:round"
+ id="path648"
+ d="m 8498,14600 h 197" />
+ </g>
+ </g>
+ <g
+ id="g664"
+ class="com.sun.star.drawing.TextShape">
+ <g
+ id="id21">
+ <rect
+ style="fill:none;stroke:none"
+ id="rect653"
+ height="963"
+ width="3822"
+ y="13600"
+ x="11200"
+ class="BoundingBox" />
+ <text
+ id="text661"
+ class="TextShape"><tspan
+ style="font-style:italic;font-weight:400;font-size:635px;font-family:'Liberation Sans', sans-serif"
+ id="tspan659"
+ font-weight="400"
+ font-style="italic"
+ font-size="635px"
+ class="TextParagraph"><tspan
+ id="tspan657"
+ y="14301"
+ x="11450"
+ class="TextPosition"><tspan
+ style="fill:#000000;stroke:none"
+ id="tspan655">... as server</tspan></tspan></tspan></text>
+
+ </g>
+ </g>
+ <g
+ id="g677"
+ class="com.sun.star.drawing.TextShape">
+ <g
+ id="id22">
+ <rect
+ style="fill:none;stroke:none"
+ id="rect666"
+ height="963"
+ width="3538"
+ y="14600"
+ x="11200"
+ class="BoundingBox" />
+ <text
+ id="text674"
+ class="TextShape"><tspan
+ style="font-style:italic;font-weight:400;font-size:635px;font-family:'Liberation Sans', sans-serif"
+ id="tspan672"
+ font-weight="400"
+ font-style="italic"
+ font-size="635px"
+ class="TextParagraph"><tspan
+ id="tspan670"
+ y="15301"
+ x="11450"
+ class="TextPosition"><tspan
+ style="fill:#000000;stroke:none"
+ id="tspan668">... as client</tspan></tspan></tspan></text>
+
+ </g>
+ </g>
+ </g>
+ </g>
+ </g>
+ </g>
+ </g>
+</svg> \ No newline at end of file
diff --git a/doc/systemd-multiinst.rst b/doc/systemd-multiinst.rst
new file mode 120000
index 0000000..2f53270
--- /dev/null
+++ b/doc/systemd-multiinst.rst
@@ -0,0 +1 @@
+../systemd/multiinst.rst \ No newline at end of file
diff --git a/doc/upgrading.rst b/doc/upgrading.rst
new file mode 100644
index 0000000..56655fa
--- /dev/null
+++ b/doc/upgrading.rst
@@ -0,0 +1,332 @@
+.. SPDX-License-Identifier: GPL-3.0-or-later
+
+.. _upgrading:
+
+*********
+Upgrading
+*********
+
+This section summarizes steps required when upgrading to newer Knot Resolver versions.
+We advise users to also read :ref:`release_notes` for respective versions.
+Section *Module changes* is relevant only for users who develop or use third-party modules.
+
+
+Upcoming changes
+================
+
+Following section provides information about selected changes in not-yet-released versions.
+We advise users to prepare for these changes sooner rather than later to make it easier to upgrade to
+newer versions when they are released.
+
+* Command line option ``--forks`` (``-f``) `is deprecated and will be eventually removed
+ <https://gitlab.nic.cz/knot/knot-resolver/-/issues/631>`_.
+ Preferred way to manage :ref:`systemd-multiple-instances` is to use a process manager,
+ e.g. systemd_ or supervisord_.
+* Function :func:`verbose` is deprecated and will be eventually removed.
+ Prefered way to change logging level is use to :func:`log_level`.
+
+.. _`systemd`: https://systemd.io/
+.. _`supervisord`: http://supervisord.org/
+
+
+5.4 to 5.5
+==========
+
+Packagers & Developers
+----------------------
+
+* Knot DNS >= 3.0.2 is required.
+
+Module API changes
+------------------
+* Function `cache.zone_import` was removed;
+ you can use `ffi.C.zi_zone_import` instead (different API).
+* When using :ref:`proxyv2`, the meaning of ``qsource.flags`` and ``qsource.comm_flags``
+ in :c:member:`kr_request` changes so that ``flags`` describes the original client
+ communicating with the proxy, while ``comm_flags`` describes the proxy communicating
+ with the resolver. When there is no proxy, ``flags`` and ``comm_flags`` are the same.
+
+
+5.3 to 5.4
+==========
+
+Configuration file
+------------------
+
+* ``kind='doh'`` in :func:`net.listen` was renamed to ``kind='doh_legacy'``. It is recommended to switch to the new DoH implementation with ``kind='doh2'``.
+* :func:`verbose` has been deprecated. In case you want to change logging level,
+ there is new function :func:`log_level`.
+
+Packagers & Developers
+----------------------
+
+* meson option ``verbose_log`` was removed.
+
+Module changes
+--------------
+
+* lua function ``warn()`` was removed, use ``log_warn()`` instead. The new function takes a log group number as the first argument.
+* C functions ``kr_log_req()`` and ``kr_log_q()`` were replaced by ``kr_log_req1()`` and ``kr_log_q1()`` respectively. The new function have slightly different API.
+
+
+5.2 to 5.3
+==========
+
+Configuration file
+------------------
+
+* Module ``dnstap``: option ``log_responses`` has been moved inside a new ``client`` section. Refer to the configuration example in :ref:`mod-dnstap`.
+
+Packagers & Developers
+----------------------
+
+* Knot DNS >= 2.9 is required.
+
+5.1 to 5.2
+==========
+
+Users
+-----
+
+* DoH over HTTP/1 and unencrypted transports is still available in
+ :ref:`legacy http module <mod-http-doh>` (``kind='doh'``).
+ This module will not receive receive any more bugfixes and will be eventually removed.
+* Users of :ref:`control-sockets` API need to terminate each command sent to resolver with newline
+ character (ASCII ``\n``). Correct usage: ``cache.stats()\n``.
+ Newline terminated commands are accepted by all resolver versions >= 1.0.0.
+* `DNS Flag Day 2020 <https://www.dnsflagday.net/2020/>`_ is now effective and Knot Resolver uses
+ maximum size of UDP answer to 1232 bytes. Please double-check your firewall,
+ it has to allow DNS traffic on UDP and **also TCP** port 53.
+* Human readable output in interactive mode and from :ref:`control-sockets` was improved and
+ as consequence slightly changed its format. Users who need machine readable output for scripts
+ should use Lua function ``tojson()`` to convert Lua values into standard JSON format instead
+ of attempting to parse the human readable output.
+ For example API call ``tojson(cache.stats())\n`` will return JSON string with ``cache.stats()``
+ results represented as dictionary.
+ Function ``tojson()`` is available in all resolver versions >= 1.0.0.
+
+Configuration file
+------------------
+
+* Statistics exporter :ref:`mod-graphite` now uses default prefix which combines
+ :func:`hostname()` and :envvar:`worker.id` instead of bare :func:`hostname()`.
+ This prevents :ref:`systemd-multiple-instances` from sending
+ conflicting statistics to server. In case you want to continue in previous time series you
+ can manually set the old values using option ``prefix``
+ in :ref:`Graphite configuration <mod-graphite>`.
+ Beware that non-default values require careful
+ :ref:`instance-specific-configuration` to avoid conflicting names.
+* Lua variable :envvar:`worker.id` is now a string with either Systemd instance name or PID
+ (instead of number). If your custom configuration uses :envvar:`worker.id` value please
+ check your scripts.
+
+Module changes
+--------------
+* Reply packet :c:type:`kr_request.answer`
+ `is not allocated <https://gitlab.nic.cz/knot/knot-resolver/-/merge_requests/985>`_
+ immediately when the request comes.
+ See the new :c:func:`kr_request_ensure_answer` function,
+ wrapped for lua as ``req:ensure_answer()``.
+
+
+5.0 to 5.1
+==========
+
+Module changes
+--------------
+
+* Modules which use :c:type:`kr_request.trace_log` handler need update to modified handler API. Example migration is `modules/watchdog/watchdog.lua <https://gitlab.nic.cz/knot/knot-resolver/-/merge_requests/957/diffs#6831501329bbf9e494048fe269c6b02944fc227c>`_.
+* Modules which were using logger :c:func:`kr_log_qverbose_impl` need migration to new logger :c:func:`kr_log_q`. Example migration is `modules/rebinding/rebinding.lua <https://gitlab.nic.cz/knot/knot-resolver/-/merge_requests/957/diffs#6c74dcae147221ca64286a3ed028057adb6813b9>`_.
+* Modules which were using :c:func:`kr_ranked_rrarray_add` should note that on success it no longer returns exclusively zero but index into the array (non-negative). Error states are unchanged (negative).
+
+
+4.x to 5.x
+==========
+
+Users
+-----
+
+* Control socket location has changed
+
+ .. csv-table::
+ :header: "","4.x location","5.x location"
+
+ "with systemd","``/run/knot-resolver/control@$ID``","``/run/knot-resolver/control/$ID``"
+ "without systemd","``$PWD/tty/$PID``","``$PWD/control/$PID``"
+
+* ``-f`` / ``--forks`` command-line option is deprecated.
+ In case you just want to trigger non-interactive mode, there's new ``-n`` / ``--noninteractive``.
+ This forking style `was not ergonomic <https://gitlab.nic.cz/knot/knot-resolver/issues/529>`_;
+ with independent kresd processes you can better utilize a process manager (e.g. systemd).
+
+
+Configuration file
+------------------
+
+* Network interface are now configured in ``kresd.conf`` with
+ :func:`net.listen` instead of systemd sockets (`#485
+ <https://gitlab.nic.cz/knot/knot-resolver/issues/485>`_). See
+ the following examples.
+
+ .. tip:: You can find suggested network interface settings based on your
+ previous systemd socket configuration in
+ ``/var/lib/knot-resolver/.upgrade-4-to-5/kresd.conf.net`` which is created
+ during the package update to version 5.x.
+
+ .. csv-table::
+ :header: "4.x - systemd socket file", "5.x - kresd.conf"
+
+ "kresd.socket
+ | [Socket]
+ | ListenDatagram=127.0.0.1:53
+ | ListenStream=127.0.0.1:53","| ``net.listen('127.0.0.1', 53, { kind = 'dns' })``"
+ "kresd.socket
+ | [Socket]
+ | FreeBind=true
+ | BindIPv6Only=both
+ | ListenDatagram=[::1]:53
+ | ListenStream=[::1]:53
+ "," | ``net.listen('127.0.0.1', 53, { kind = 'dns', freebind = true })``
+ | ``net.listen('::1', 53, { kind = 'dns', freebind = true })``"
+ "kresd-tls.socket
+ | [Socket]
+ | ListenStream=127.0.0.1:853","| ``net.listen('127.0.0.1', 853, { kind = 'tls' })``"
+ "kresd-doh.socket
+ | [Socket]
+ | ListenStream=127.0.0.1:443","| ``net.listen('127.0.0.1', 443, { kind = 'doh' })``"
+ "kresd-webmgmt.socket
+ | [Socket]
+ | ListenStream=127.0.0.1:8453","| ``net.listen('127.0.0.1', 8453, { kind = 'webmgmt' })``"
+
+* :func:`net.listen` throws an error if it fails to bind. Use ``freebind=true`` option
+ to bind to nonlocal addresses.
+
+
+4.2.2 to 4.3+
+=============
+
+Module changes
+--------------
+
+* In case you wrote your own module which directly calls function
+ ``kr_ranked_rrarray_add()``, you need to additionally call function
+ ``kr_ranked_rrarray_finalize()`` after each batch (before changing
+ the added memory regions). For a specific example see `changes in dns64 module
+ <https://gitlab.nic.cz/knot/knot-resolver/commit/edb8ffef7fbe48befeb3f7164d38079dd0be3302#1fe36e8ac0729b279645f7237b7122b1c457a982>`_.
+
+.. _upgrade-from-3-to-4:
+
+4.x to 4.2.1+
+=============
+
+Users
+-----
+
+* If you have previously installed ``knot-resolver-dbgsym`` package on Debian,
+ please remove it and install ``knot-resolver-dbg`` instead.
+
+3.x to 4.x
+==========
+
+Users
+-----
+
+* DNSSEC validation is now turned on by default. If you need to disable it, see
+ :ref:`dnssec-config`.
+* ``-k/--keyfile`` and ``-K/--keyfile-ro`` daemon options were removed. If needed,
+ use ``trust_anchors.add_file()`` in configuration file instead.
+* Configuration for :ref:`HTTP module <mod-http>` changed significantly as result of
+ adding :ref:`mod-http-doh` support. Please see examples below.
+* In case you are using your own custom modules, move them to the new module
+ location. The exact location depends on your distribution. Generally, modules previously
+ in ``/usr/lib/kdns_modules`` should be moved to ``/usr/lib/knot-resolver/kres_modules``.
+
+Configuration file
+~~~~~~~~~~~~~~~~~~
+
+* ``trust_anchors.file``, ``trust_anchors.config()`` and ``trust_anchors.negative``
+ aliases were removed to avoid duplicity and confusion. Migration table:
+
+ .. csv-table::
+ :header: "3.x configuration", "4.x configuration"
+
+ "``trust_anchors.file = path``", "``trust_anchors.add_file(path)``"
+ "``trust_anchors.config(path, readonly)``", "``trust_anchors.add_file(path, readonly)``"
+ "``trust_anchors.negative = nta_set``", "``trust_anchors.set_insecure(nta_set)``"
+
+* ``trust_anchors.keyfile_default`` is no longer accessible and is can be set
+ only at compile time. To turn off DNSSEC, use :func:`trust_anchors.remove()`.
+
+ .. csv-table::
+ :header: "3.x configuration", "4.x configuration"
+
+ "``trust_anchors.keyfile_default = nil``", "``trust_anchors.remove('.')``"
+
+* Network for HTTP endpoints is now configured using same mechanism as for normal DNS endpoints,
+ please refer to chapter :ref:`network-configuration`. Migration table:
+
+ .. csv-table::
+ :header: "3.x configuration", "4.x configuration"
+
+ "``modules = { http = { host = '192.0.2.1', port = 443 }}``","see chapter :ref:`network-configuration`"
+ "``http.config({ host = '192.0.2.1', port = 443 })``","see chapter :ref:`network-configuration`"
+ "``modules = { http = { endpoints = ... }}``","see chapter :ref:`mod-http-custom-endpoint`"
+ "``http.config({ endpoints = ... })``","see chapter :ref:`mod-http-custom-endpoint`"
+
+Packagers & Developers
+----------------------
+
+* Knot DNS >= 2.8 is required.
+* meson >= 0.46 and ninja is required.
+* meson build system is now used for compiling the project. For instructions, see
+ the :ref:`build`. Packagers should pay attention to section :ref:`packaging`
+ for information about systemd unit files and trust anchors.
+* Embedding LMDB is no longer supported, lmdb is now required as an external dependency.
+* Trust anchors file from upstream is installed and used as default unless you
+ override ``keyfile_default`` during build.
+
+Module changes
+~~~~~~~~~~~~~~
+
+* Default module location has changed from ``{libdir}/kdns_modules`` to
+ ``{libdir}/knot-resolver/kres_modules``. Modules are now in the lua namespace
+ ``kres_modules.*``.
+* ``kr_straddr_split()`` API has changed.
+
+* C modules defining ``*_layer`` or ``*_props`` symbols need to use a different style, but it's typically a trivial change.
+ Instead of exporting the corresponding symbols, the module should assign pointers to its static structures inside its ``*_init()`` function. Example migration:
+ `bogus_log module <https://gitlab.nic.cz/knot/knot-resolver/commit/2875a3970#9fa69cdc6ee1903dc22e3262f58996395acab364>`_.
+
+.. _upgrade-from-2-to-3:
+
+2.x to 3.x
+==========
+
+Users
+-----
+
+* Module :ref:`mod-hints` has option :func:`hints.use_nodata` enabled by default,
+ which is what most users expect. Add ``hints.use_nodata(false)`` to your config
+ to revert to the old behavior.
+* Modules ``cookie`` and ``version`` were removed.
+ Please remove relevant configuration lines with ``modules.load()`` and ``modules =``
+ from configuration file.
+* Valid configuration must open cache using ``cache.open()`` or ``cache.size =``
+ before executing cache operations like ``cache.clear()``.
+ (Older versions were silently ignoring such cache operations.)
+
+Packagers & Developers
+----------------------
+
+* Knot DNS >= 2.7.2 is required.
+
+Module changes
+~~~~~~~~~~~~~~
+
+* API for Lua modules was refactored, please see :ref:`significant-lua-changes`.
+* New layer was added: ``answer_finalize``.
+* ``kr_request`` keeps ``::qsource.packet`` beyond the ``begin`` layer.
+* ``kr_request::qsource.tcp`` renamed to ``::qsource.flags.tcp``.
+* ``kr_request::has_tls`` renamed to ``::qsource.flags.tls``.
+* ``kr_zonecut_add()``, ``kr_zonecut_del()`` and ``kr_nsrep_sort()`` changed
+ parameters slightly.
diff --git a/doc/worker_api.rst b/doc/worker_api.rst
new file mode 100644
index 0000000..ea971f4
--- /dev/null
+++ b/doc/worker_api.rst
@@ -0,0 +1,7 @@
+.. SPDX-License-Identifier: GPL-3.0-or-later
+
+Worker API reference
+====================
+
+.. doxygenfile:: daemon/worker.h
+
diff --git a/etc/config/config.cluster b/etc/config/config.cluster
new file mode 100644
index 0000000..3bd12dd
--- /dev/null
+++ b/etc/config/config.cluster
@@ -0,0 +1,36 @@
+-- SPDX-License-Identifier: CC0-1.0
+-- vim:syntax=lua:set ts=4 sw=4:
+-- Config file example useable for larger resolver farms
+-- In this case cache should be made as large as possible, and prefetching turned off
+-- as the resolver is busy most of the time.
+-- Alternative is using `etcd` as a configuration backend.
+-- Refer to manual: https://knot-resolver.readthedocs.io/en/stable/
+
+-- Network interface configuration
+net.listen('127.0.0.1', 53, { kind = 'dns' })
+net.listen('::1', 53, { kind = 'dns'})
+net.listen('127.0.0.1', 853, { kind = 'tls' })
+net.listen('::1', 853, { kind = 'tls' })
+net.listen('127.0.0.1', 443, { kind = 'doh2' })
+net.listen('::1', 443, { kind = 'doh2'})
+
+-- Refer to manual for optimal cache size
+cache.size = 16 * GB
+
+-- Load Useful modules
+modules = {
+ 'hints > iterate', -- Allow loading /etc/hosts or custom root hints
+ 'stats', -- Track internal statistics
+ graphite = { -- Send statistics to local InfluxDB
+ -- Address of the Graphite/InfluxDB server
+ host = '192.168.1.2',
+ },
+}
+
+-- Use local root server copy for performance reasons
+hints.root({
+ ['j.root-servers.net.'] = { '192.168.1.4', '2001:503:c27::2:30', '192.58.128.30' }
+})
+
+-- Apply RPZ for all clients, default rule is DENY
+policy.add(policy.rpz(policy.DENY, 'blacklist.rpz'))
diff --git a/etc/config/config.docker b/etc/config/config.docker
new file mode 100644
index 0000000..f631a54
--- /dev/null
+++ b/etc/config/config.docker
@@ -0,0 +1,97 @@
+-- SPDX-License-Identifier: CC0-1.0
+-- vim:syntax=lua:set ts=4 sw=4:
+-- Refer to manual: https://knot-resolver.readthedocs.io/en/stable/
+print('Knot Resolver ' .. package_version())
+
+-- Smaller cache size
+cache.size = 10 * MB
+
+local ffi = require('ffi')
+
+function interactive_mode()
+ -- Listen on all interfaces (localhost would not work in Docker)
+ net.listen('0.0.0.0', 53, { kind = 'dns' })
+ net.listen('0.0.0.0', 853, { kind = 'tls' })
+ net.listen('0.0.0.0', 443, { kind = 'doh2' })
+ net.listen('0.0.0.0', 8453, { kind = 'webmgmt' })
+
+ -- Load Useful modules
+ modules = {
+ 'stats', -- Track internal statistics
+ 'http',
+ }
+
+ function print_help()
+ print('\nUsage\n'
+ .. '=====\n'
+ .. 'Run this container using command:\n'
+ .. '$ docker run -Pti cznic/knot-resolver\n'
+ .. '\n'
+ .. 'Docker will map ports 53, 443, 853, and 8453 to some other numbers, see\n'
+ .. '$ docker ps\n'
+ .. '(column PORTS)\n'
+ .. '53 -> DNS protocol over UDP and TCP\n'
+ .. '443 -> DNS-over-HTTPS protocol\n'
+ .. '853 -> DNS-over-TLS protocol\n'
+ .. '8453 -> web interface\n'
+ .. '\n'
+ .. 'For verbose logging enter following command to prompt below:\n'
+ .. 'log_level("debug")\n')
+ end
+ print_help()
+end
+
+function debug_mode(qname, qtype)
+ event.after(20*sec, function()
+ print('ERROR: timeout which cannot happen actually happened, exiting')
+ os.exit(1)
+ end)
+ env.KRESD_NO_LISTEN = 1
+
+ -- limit noise in verbose logs
+ modules.unload('detect_time_skew')
+ modules.unload('priming')
+ modules.unload('ta_signal_query')
+ modules.unload('ta_update')
+
+ -- always empty cache so this config works reliably outside Docker
+ cache.clear()
+
+ local cqueues = require('cqueues')
+
+ -- execute query right after start up and exit when the query is finished
+ event.after(0, function()
+ log_level('info')
+ policy.add(policy.all(policy.DEBUG_ALWAYS))
+ log_info(ffi.C.LOG_GRP_RESOLVER, 'starting DNS query for %s %s', qname, kres.tostring.type[qtype])
+ local starttime = cqueues.monotime()
+ resolve({
+ name = qname,
+ type = qtype,
+ options = {'DNSSEC_WANT'},
+ finish = function(pkt)
+ -- delay exit after packet is finished
+ -- to prevent us from losing policy.DEBUG finish callback
+ event.after(1, -- millisecond
+ function()
+ local endtime = cqueues.monotime()
+ log_info(ffi.C.LOG_GRP_RESOLVER, 'request finished in %f ms', (endtime - starttime) * 1000)
+ os.exit()
+ end)
+ end
+ })
+ end)
+end
+
+local qname = os.getenv('QNAME')
+local qtype = os.getenv('QTYPE')
+if qname and qtype then
+ qtypenum = kres.type[qtype]
+ if not qtypenum then
+ log_error(ffi.C.LOG_GRP_RESOLVER, 'ERROR: unsupported query type "%s", use TYPE12345 notation', qtype)
+ os.exit()
+ end
+ debug_mode(qname, qtypenum)
+else
+ interactive_mode()
+end
diff --git a/etc/config/config.internal b/etc/config/config.internal
new file mode 100644
index 0000000..46bbf17
--- /dev/null
+++ b/etc/config/config.internal
@@ -0,0 +1,18 @@
+-- SPDX-License-Identifier: CC0-1.0
+-- vim:syntax=lua:set ts=4 sw=4:
+-- Config file example usable for multi-user ISP resolver
+-- Refer to manual: https://knot-resolver.readthedocs.io/en/stable/
+
+-- Network interface configuration
+net.listen('127.0.0.1', 53, { kind = 'dns' })
+net.listen('::1', 53, { kind = 'dns'})
+net.listen('127.0.0.1', 853, { kind = 'tls' })
+net.listen('::1', 853, { kind = 'tls' })
+net.listen('127.0.0.1', 443, { kind = 'doh2' })
+net.listen('::1', 443, { kind = 'doh2' })
+
+-- define list of internal-only domains
+internalDomains = policy.todnames({'company.example', 'internal.example'})
+
+-- forward all queries below 'internalDomains' to '192.168.1.2'
+policy.add(policy.suffix(policy.FORWARD({'192.168.1.2'}), internalDomains))
diff --git a/etc/config/config.isp b/etc/config/config.isp
new file mode 100644
index 0000000..d4e2f9a
--- /dev/null
+++ b/etc/config/config.isp
@@ -0,0 +1,64 @@
+-- SPDX-License-Identifier: CC0-1.0
+-- vim:syntax=lua:set ts=4 sw=4:
+-- Config file example usable for ISP resolver
+-- Refer to manual: https://knot-resolver.readthedocs.io/en/stable/
+
+-- Network interface configuration
+net.listen('127.0.0.1', 53, { kind = 'dns' })
+net.listen('::1', 53, { kind = 'dns'})
+net.listen('127.0.0.1', 853, { kind = 'tls' })
+net.listen('::1', 853, { kind = 'tls' })
+net.listen('127.0.0.1', 443, { kind = 'doh2' })
+net.listen('::1', 443, { kind = 'doh2' })
+
+-- Refer to manual for optimal cache size
+cache.size = 4 * GB
+
+-- load modules
+modules = {
+ 'view',
+ 'stats'
+}
+
+local ffi = require('ffi')
+
+-- log statistics every second
+local stat_id = event.recurrent(1 * second, function(evid)
+ log_info(ffi.C.LOG_GRP_STATISTICS, table_print(stats.list()))
+end)
+
+-- stop printing statistics after first minute
+event.after(1 * minute, function(evid)
+ event.cancel(stat_id)
+end)
+
+-- speed_monitor definition
+-- prints warning if more than 5% of total answers was slow
+function speed_monitor()
+ local previous = stats.list() -- store statistics in persistent variable
+ return function(evid)
+ local now = stats.list() -- save actual statistics to variable
+ -- number of total answers between 'now' and 'previous' states
+ local total_increment = now['answer.total'] - previous['answer.total']
+ -- number of slow answers between 'now' and 'previous' states
+ local slow_increment = now['answer.slow'] - previous['answer.slow']
+ -- if percentage of slow answers is bigger than 5%, print warning
+ if slow_increment / total_increment > 0.05 then
+ log_warn(ffi.C.LOG_GRP_STATISTICS, 'WARNING! More than 5 %% of queries was slow!')
+ end
+ previous = now
+ end
+end
+
+-- execute speed_monitor every minute
+local monitor_id = event.recurrent(1 * minute, speed_monitor())
+
+-- apply RPZ for all clients, default rule is DENY
+policy.add(policy.rpz(policy.DENY, 'blacklist.rpz'))
+
+-- whitelist queries identified by subnet
+view:addr(''192.168.1.0/24'', policy.all(policy.PASS))
+
+-- drop everything that hasn't matched
+view:addr('0.0.0.0/0', policy.all(policy.DROP))
+
diff --git a/etc/config/config.personal b/etc/config/config.personal
new file mode 100644
index 0000000..961a2f6
--- /dev/null
+++ b/etc/config/config.personal
@@ -0,0 +1,21 @@
+-- SPDX-License-Identifier: CC0-1.0
+-- vim:syntax=lua:set ts=4 sw=4:
+-- Refer to manual: https://knot-resolver.readthedocs.org/en/stable/
+
+-- Network interface configuration
+net.listen('127.0.0.1', 53, { kind = 'dns' })
+net.listen('127.0.0.1', 853, { kind = 'tls' })
+--net.listen('127.0.0.1', 443, { kind = 'doh2' })
+net.listen('::1', 53, { kind = 'dns', freebind = true })
+net.listen('::1', 853, { kind = 'tls', freebind = true })
+--net.listen('::1', 443, { kind = 'doh2' })
+
+-- Load useful modules
+modules = {
+ 'hints > iterate', -- Allow loading /etc/hosts or custom root hints
+ 'stats', -- Track internal statistics
+ 'predict', -- Prefetch expiring/frequent records
+}
+
+-- Cache size
+cache.size = 100 * MB
diff --git a/etc/config/config.privacy b/etc/config/config.privacy
new file mode 100644
index 0000000..6c14d74
--- /dev/null
+++ b/etc/config/config.privacy
@@ -0,0 +1,36 @@
+-- SPDX-License-Identifier: CC0-1.0
+-- vim:syntax=lua:set ts=4 sw=4:
+-- Config file example usable for privacy-preserving resolver
+-- Refer to manual: https://knot-resolver.readthedocs.io/en/stable/
+
+-- Network interface configuration
+net.listen('127.0.0.1', 53, { kind = 'dns' })
+net.listen('::1', 53, { kind = 'dns'})
+net.listen('127.0.0.1', 853, { kind = 'tls' })
+net.listen('::1', 853, { kind = 'tls' })
+net.listen('127.0.0.1', 443, { kind = 'doh2' })
+net.listen('::1', 443, { kind = 'doh2' })
+
+-- TLS server configuration
+-- use this to configure your TLS certificates
+-- net.tls("/etc/knot-resolver/server-cert.pem", "/etc/knot-resolver/server-key.pem")
+
+-- Refer to manual if you would like to use non-persistent cache
+
+-- forwarding to multiple targets
+-- splits the entire DNS namespace into distinct slices
+policy.add(policy.slice(
+ -- slicing function
+ policy.slice_randomize_psl(),
+ -- forward over TLS
+ policy.TLS_FORWARD({
+ {'2001:DB8::d0c', hostname='res.example.com'},
+ {'192.0.2.1', pin_sha256={'YQ=='}},
+ }),
+ policy.TLS_FORWARD({
+ -- multiple servers can be specified for a single slice
+ -- the one with lowest round-trip time will be used
+ {'193.17.47.1', hostname='odvr.nic.cz'},
+ {'185.43.135.1', hostname='odvr.nic.cz'},
+ })
+))
diff --git a/etc/config/config.splitview b/etc/config/config.splitview
new file mode 100644
index 0000000..a8a9344
--- /dev/null
+++ b/etc/config/config.splitview
@@ -0,0 +1,30 @@
+-- SPDX-License-Identifier: CC0-1.0
+-- vim:syntax=lua:set ts=4 sw=4:
+-- Config file with split-view for internal zone
+-- Refer to manual: https://knot-resolver.readthedocs.io/en/stable/
+
+-- Network interface configuration
+net.listen('127.0.0.1', 53, { kind = 'dns' })
+net.listen('::1', 53, { kind = 'dns'})
+net.listen('127.0.0.1', 853, { kind = 'tls' })
+net.listen('::1', 853, { kind = 'tls' })
+net.listen('127.0.0.1', 443, { kind = 'doh2' })
+net.listen('::1', 443, { kind = 'doh2' })
+
+-- Load Useful modules
+modules = {
+ 'hints > iterate', -- Allow loading /etc/hosts or custom root hints
+ 'stats', -- Track internal statistics
+ graphite = { -- Send statistics to local InfluxDB
+ -- Address of the Graphite/InfluxDB server
+ host = '192.168.1.2',
+ },
+ -- Use DNS64 with specified NAT64 address
+ dns64 = 'fe80::21b:77ff:0:0',
+}
+
+-- Refer to manual for optimal cache size
+cache.size = 4 * GB
+
+-- Forward everything below `company.cz` to `192.168.1.3`
+policy.add(policy.suffix(policy.FORWARD('192.168.1.3'), {todname('company.cz')}))
diff --git a/etc/config/meson.build b/etc/config/meson.build
new file mode 100644
index 0000000..ca88808
--- /dev/null
+++ b/etc/config/meson.build
@@ -0,0 +1,35 @@
+# etc: config examples
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# Install config examples
+example_configs = [
+ 'config.cluster',
+ 'config.docker',
+ 'config.isp',
+ 'config.internal',
+ 'config.privacy',
+ 'config.personal',
+ 'config.splitview',
+]
+
+install_data(
+ sources: example_configs,
+ install_dir: examples_dir,
+)
+
+
+# kresd.conf
+install_kresd_conf = get_option('install_kresd_conf') == 'enabled'
+if get_option('install_kresd_conf') == 'auto'
+ if run_command(['test', '-r', etc_dir / 'kresd.conf'], check: false).returncode() == 1
+ install_kresd_conf = true
+ endif
+endif
+
+if install_kresd_conf
+ install_data(
+ sources: 'config.personal',
+ rename: 'kresd.conf',
+ install_dir: etc_dir,
+ )
+endif
diff --git a/etc/icann-ca.pem b/etc/icann-ca.pem
new file mode 100644
index 0000000..0ae28d6
--- /dev/null
+++ b/etc/icann-ca.pem
@@ -0,0 +1,82 @@
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ 08:3b:e0:56:90:42:46:b1:a1:75:6a:c9:59:91:c7:4a
+ Signature Algorithm: sha1WithRSAEncryption
+ Issuer: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Global Root CA
+ Validity
+ Not Before: Nov 10 00:00:00 2006 GMT
+ Not After : Nov 10 00:00:00 2031 GMT
+ Subject: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Global Root CA
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ RSA Public Key: (2048 bit)
+ Modulus (2048 bit):
+ 00:e2:3b:e1:11:72:de:a8:a4:d3:a3:57:aa:50:a2:
+ 8f:0b:77:90:c9:a2:a5:ee:12:ce:96:5b:01:09:20:
+ cc:01:93:a7:4e:30:b7:53:f7:43:c4:69:00:57:9d:
+ e2:8d:22:dd:87:06:40:00:81:09:ce:ce:1b:83:bf:
+ df:cd:3b:71:46:e2:d6:66:c7:05:b3:76:27:16:8f:
+ 7b:9e:1e:95:7d:ee:b7:48:a3:08:da:d6:af:7a:0c:
+ 39:06:65:7f:4a:5d:1f:bc:17:f8:ab:be:ee:28:d7:
+ 74:7f:7a:78:99:59:85:68:6e:5c:23:32:4b:bf:4e:
+ c0:e8:5a:6d:e3:70:bf:77:10:bf:fc:01:f6:85:d9:
+ a8:44:10:58:32:a9:75:18:d5:d1:a2:be:47:e2:27:
+ 6a:f4:9a:33:f8:49:08:60:8b:d4:5f:b4:3a:84:bf:
+ a1:aa:4a:4c:7d:3e:cf:4f:5f:6c:76:5e:a0:4b:37:
+ 91:9e:dc:22:e6:6d:ce:14:1a:8e:6a:cb:fe:cd:b3:
+ 14:64:17:c7:5b:29:9e:32:bf:f2:ee:fa:d3:0b:42:
+ d4:ab:b7:41:32:da:0c:d4:ef:f8:81:d5:bb:8d:58:
+ 3f:b5:1b:e8:49:28:a2:70:da:31:04:dd:f7:b2:16:
+ f2:4c:0a:4e:07:a8:ed:4a:3d:5e:b5:7f:a3:90:c3:
+ af:27
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Key Usage: critical
+ Digital Signature, Certificate Sign, CRL Sign
+ X509v3 Basic Constraints: critical
+ CA:TRUE
+ X509v3 Subject Key Identifier:
+ 03:DE:50:35:56:D1:4C:BB:66:F0:A3:E2:1B:1B:C3:97:B2:3D:D1:55
+ X509v3 Authority Key Identifier:
+ keyid:03:DE:50:35:56:D1:4C:BB:66:F0:A3:E2:1B:1B:C3:97:B2:3D:D1:55
+
+ Signature Algorithm: sha1WithRSAEncryption
+ cb:9c:37:aa:48:13:12:0a:fa:dd:44:9c:4f:52:b0:f4:df:ae:
+ 04:f5:79:79:08:a3:24:18:fc:4b:2b:84:c0:2d:b9:d5:c7:fe:
+ f4:c1:1f:58:cb:b8:6d:9c:7a:74:e7:98:29:ab:11:b5:e3:70:
+ a0:a1:cd:4c:88:99:93:8c:91:70:e2:ab:0f:1c:be:93:a9:ff:
+ 63:d5:e4:07:60:d3:a3:bf:9d:5b:09:f1:d5:8e:e3:53:f4:8e:
+ 63:fa:3f:a7:db:b4:66:df:62:66:d6:d1:6e:41:8d:f2:2d:b5:
+ ea:77:4a:9f:9d:58:e2:2b:59:c0:40:23:ed:2d:28:82:45:3e:
+ 79:54:92:26:98:e0:80:48:a8:37:ef:f0:d6:79:60:16:de:ac:
+ e8:0e:cd:6e:ac:44:17:38:2f:49:da:e1:45:3e:2a:b9:36:53:
+ cf:3a:50:06:f7:2e:e8:c4:57:49:6c:61:21:18:d5:04:ad:78:
+ 3c:2c:3a:80:6b:a7:eb:af:15:14:e9:d8:89:c1:b9:38:6c:e2:
+ 91:6c:8a:ff:64:b9:77:25:57:30:c0:1b:24:a3:e1:dc:e9:df:
+ 47:7c:b5:b4:24:08:05:30:ec:2d:bd:0b:bf:45:bf:50:b9:a9:
+ f3:eb:98:01:12:ad:c8:88:c6:98:34:5f:8d:0a:3c:c6:e9:d5:
+ 95:95:6d:de
+-----BEGIN CERTIFICATE-----
+MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh
+MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
+d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD
+QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT
+MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j
+b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG
+9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB
+CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97
+nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt
+43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P
+T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4
+gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO
+BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR
+TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw
+DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr
+hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg
+06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF
+PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls
+YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk
+CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4=
+-----END CERTIFICATE-----
diff --git a/etc/meson.build b/etc/meson.build
new file mode 100644
index 0000000..31859ba
--- /dev/null
+++ b/etc/meson.build
@@ -0,0 +1,37 @@
+# etc
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+etc_files = []
+
+if install_root_hints
+ etc_files += 'root.hints'
+endif
+
+if managed_ta
+ etc_files += 'icann-ca.pem'
+endif
+
+if install_root_keys
+ root_keys_path = keyfile_default.split('/')
+ root_keys_filename = root_keys_path[-1]
+ root_keys_dir = []
+ foreach el : root_keys_path
+ if el != root_keys_filename
+ root_keys_dir += el
+ endif
+ endforeach
+ install_data(
+ sources: 'root.keys',
+ rename: root_keys_filename,
+ install_dir: '/'.join(root_keys_dir)
+ )
+endif
+
+
+subdir('config')
+
+
+install_data(
+ sources: etc_files,
+ install_dir: etc_dir
+)
diff --git a/etc/root.hints b/etc/root.hints
new file mode 100644
index 0000000..e4d8d99
--- /dev/null
+++ b/etc/root.hints
@@ -0,0 +1,92 @@
+; This file holds the information on root name servers needed to
+; initialize cache of Internet domain name servers
+; (e.g. reference this file in the "cache . <file>"
+; configuration file of BIND domain name servers).
+;
+; This file is made available by InterNIC
+; under anonymous FTP as
+; file /domain/named.cache
+; on server FTP.INTERNIC.NET
+; -OR- RS.INTERNIC.NET
+;
+; last update: October 24, 2017
+; related version of root zone: 2017102400
+;
+; FORMERLY NS.INTERNIC.NET
+;
+. 3600000 NS A.ROOT-SERVERS.NET.
+A.ROOT-SERVERS.NET. 3600000 A 198.41.0.4
+A.ROOT-SERVERS.NET. 3600000 AAAA 2001:503:ba3e::2:30
+;
+; FORMERLY NS1.ISI.EDU
+;
+. 3600000 NS B.ROOT-SERVERS.NET.
+B.ROOT-SERVERS.NET. 3600000 A 199.9.14.201
+B.ROOT-SERVERS.NET. 3600000 AAAA 2001:500:200::b
+;
+; FORMERLY C.PSI.NET
+;
+. 3600000 NS C.ROOT-SERVERS.NET.
+C.ROOT-SERVERS.NET. 3600000 A 192.33.4.12
+C.ROOT-SERVERS.NET. 3600000 AAAA 2001:500:2::c
+;
+; FORMERLY TERP.UMD.EDU
+;
+. 3600000 NS D.ROOT-SERVERS.NET.
+D.ROOT-SERVERS.NET. 3600000 A 199.7.91.13
+D.ROOT-SERVERS.NET. 3600000 AAAA 2001:500:2d::d
+;
+; FORMERLY NS.NASA.GOV
+;
+. 3600000 NS E.ROOT-SERVERS.NET.
+E.ROOT-SERVERS.NET. 3600000 A 192.203.230.10
+E.ROOT-SERVERS.NET. 3600000 AAAA 2001:500:a8::e
+;
+; FORMERLY NS.ISC.ORG
+;
+. 3600000 NS F.ROOT-SERVERS.NET.
+F.ROOT-SERVERS.NET. 3600000 A 192.5.5.241
+F.ROOT-SERVERS.NET. 3600000 AAAA 2001:500:2f::f
+;
+; FORMERLY NS.NIC.DDN.MIL
+;
+. 3600000 NS G.ROOT-SERVERS.NET.
+G.ROOT-SERVERS.NET. 3600000 A 192.112.36.4
+G.ROOT-SERVERS.NET. 3600000 AAAA 2001:500:12::d0d
+;
+; FORMERLY AOS.ARL.ARMY.MIL
+;
+. 3600000 NS H.ROOT-SERVERS.NET.
+H.ROOT-SERVERS.NET. 3600000 A 198.97.190.53
+H.ROOT-SERVERS.NET. 3600000 AAAA 2001:500:1::53
+;
+; FORMERLY NIC.NORDU.NET
+;
+. 3600000 NS I.ROOT-SERVERS.NET.
+I.ROOT-SERVERS.NET. 3600000 A 192.36.148.17
+I.ROOT-SERVERS.NET. 3600000 AAAA 2001:7fe::53
+;
+; OPERATED BY VERISIGN, INC.
+;
+. 3600000 NS J.ROOT-SERVERS.NET.
+J.ROOT-SERVERS.NET. 3600000 A 192.58.128.30
+J.ROOT-SERVERS.NET. 3600000 AAAA 2001:503:c27::2:30
+;
+; OPERATED BY RIPE NCC
+;
+. 3600000 NS K.ROOT-SERVERS.NET.
+K.ROOT-SERVERS.NET. 3600000 A 193.0.14.129
+K.ROOT-SERVERS.NET. 3600000 AAAA 2001:7fd::1
+;
+; OPERATED BY ICANN
+;
+. 3600000 NS L.ROOT-SERVERS.NET.
+L.ROOT-SERVERS.NET. 3600000 A 199.7.83.42
+L.ROOT-SERVERS.NET. 3600000 AAAA 2001:500:9f::42
+;
+; OPERATED BY WIDE
+;
+. 3600000 NS M.ROOT-SERVERS.NET.
+M.ROOT-SERVERS.NET. 3600000 A 202.12.27.33
+M.ROOT-SERVERS.NET. 3600000 AAAA 2001:dc3::35
+; End of file \ No newline at end of file
diff --git a/etc/root.keys b/etc/root.keys
new file mode 100644
index 0000000..e292b5a
--- /dev/null
+++ b/etc/root.keys
@@ -0,0 +1 @@
+. IN DS 20326 8 2 E06D44B80B8F1D39A95C0B0D7C65D08458E880409BBC683457104237C7F8EC8D
diff --git a/lib/README.rst b/lib/README.rst
new file mode 100644
index 0000000..1c8cf7b
--- /dev/null
+++ b/lib/README.rst
@@ -0,0 +1,313 @@
+.. SPDX-License-Identifier: GPL-3.0-or-later
+
+*********************
+Knot Resolver library
+*********************
+
+Requirements
+============
+
+* libknot_ 2.0 (Knot DNS high-performance DNS library.)
+
+For users
+=========
+
+The library as described provides basic services for name resolution, which should cover the usage,
+examples are in the :ref:`resolve API <lib_api_rplan>` documentation.
+
+.. tip:: If you're migrating from ``getaddrinfo()``, see *"synchronous"* API, but the library offers iterative API as well to plug it into your event loop for example.
+
+.. _lib-layers:
+
+For developers
+==============
+
+The resolution process starts with the functions in :ref:`resolve.c <lib_api_rplan>`, they are responsible for:
+
+* reacting to state machine state (i.e. calling consume layers if we have an answer ready)
+* interacting with the library user (i.e. asking caller for I/O, accepting queries)
+* fetching assets needed by layers (i.e. zone cut)
+
+This is the *driver*. The driver is not meant to know *"how"* the query resolves, but rather *"when"* to execute *"what"*.
+
+.. image:: ../doc/resolution.png
+ :align: center
+
+On the other side are *layers*. They are responsible for dissecting the packets and informing the driver about the results. For example, a *produce* layer generates query, a *consume* layer validates answer.
+
+.. tip:: Layers are executed asynchronously by the driver. If you need some asset beforehand, you can signalize the driver using returning state or current query flags. For example, setting a flag ``AWAIT_CUT`` forces driver to fetch zone cut information before the packet is consumed; setting a ``RESOLVED`` flag makes it pop a query after the current set of layers is finished; returning ``FAIL`` state makes it fail current query.
+
+Layers can also change course of resolution, for example by appending additional queries.
+
+.. code-block:: lua
+
+ consume = function (state, req, answer)
+ if answer:qtype() == kres.type.NS then
+ local qry = req:push(answer:qname(), kres.type.SOA, kres.class.IN)
+ qry.flags.AWAIT_CUT = true
+ end
+ return state
+ end
+
+This **doesn't** block currently processed query, and the newly created sub-request will start as soon as driver finishes processing current. In some cases you might need to issue sub-request and process it **before** continuing with the current, i.e. validator may need a DNSKEY before it can validate signatures. In this case, layers can yield and resume afterwards.
+
+.. code-block:: lua
+
+ consume = function (state, req, answer)
+ if state == kres.YIELD then
+ print('continuing yielded layer')
+ return kres.DONE
+ else
+ if answer:qtype() == kres.type.NS then
+ local qry = req:push(answer:qname(), kres.type.SOA, kres.class.IN)
+ qry.flags.AWAIT_CUT = true
+ print('planned SOA query, yielding')
+ return kres.YIELD
+ end
+ return state
+ end
+ end
+
+The ``YIELD`` state is a bit special. When a layer returns it, it interrupts current walk through the layers. When the layer receives it,
+it means that it yielded before and now it is resumed. This is useful in a situation where you need a sub-request to determine whether current answer is valid or not.
+
+Writing layers
+==============
+
+.. warning:: FIXME: this dev-docs section is outdated! Better see comments in files instead, for now.
+
+The resolver :ref:`library <lib_index>` leverages the processing API from the libknot to separate packet processing code into layers.
+
+.. note:: This is only crash-course in the library internals, see the resolver :ref:`library <lib_index>` documentation for the complete overview of the services.
+
+The library offers following services:
+
+- :ref:`Cache <lib_api_cache>` - MVCC cache interface for retrieving/storing resource records.
+- :ref:`Resolution plan <lib_api_rplan>` - Query resolution plan, a list of partial queries (with hierarchy) sent in order to satisfy original query. This contains information about the queries, nameserver choice, timing information, answer and its class.
+- :ref:`Nameservers <lib_api_nameservers>` - Reputation database of nameservers, this serves as an aid for nameserver choice.
+
+A processing layer is going to be called by the query resolution driver for each query,
+so you're going to work with :ref:`struct kr_request <lib_api_rplan>` as your per-query context.
+This structure contains pointers to resolution context, resolution plan and also the final answer.
+
+.. code-block:: c
+
+ int consume(kr_layer_t *ctx, knot_pkt_t *pkt)
+ {
+ struct kr_request *req = ctx->req;
+ struct kr_query *qry = req->current_query;
+ }
+
+This is only passive processing of the incoming answer. If you want to change the course of resolution, say satisfy a query from a local cache before the library issues a query to the nameserver, you can use states (see the :ref:`Static hints <mod-hints>` for example).
+
+.. code-block:: c
+
+ int produce(kr_layer_t *ctx, knot_pkt_t *pkt)
+ {
+ struct kr_request *req = ctx->req;
+ struct kr_query *qry = req->current_query;
+
+ /* Query can be satisfied locally. */
+ if (can_satisfy(qry)) {
+ /* This flag makes the resolver move the query
+ * to the "resolved" list. */
+ qry->flags.RESOLVED = true;
+ return KR_STATE_DONE;
+ }
+
+ /* Pass-through. */
+ return ctx->state;
+ }
+
+It is possible to not only act during the query resolution, but also to view the complete resolution plan afterwards. This is useful for analysis-type tasks, or *"per answer"* hooks.
+
+.. code-block:: c
+
+ int finish(kr_layer_t *ctx)
+ {
+ struct kr_request *req = ctx->req;
+ struct kr_rplan *rplan = req->rplan;
+
+ /* Print the query sequence with start time. */
+ char qname_str[KNOT_DNAME_MAXLEN];
+ struct kr_query *qry = NULL
+ WALK_LIST(qry, rplan->resolved) {
+ knot_dname_to_str(qname_str, qry->sname, sizeof(qname_str));
+ printf("%s at %u\n", qname_str, qry->timestamp);
+ }
+
+ return ctx->state;
+ }
+
+APIs in Lua
+===========
+
+The APIs in Lua world try to mirror the C APIs using LuaJIT FFI, with several differences and enhancements.
+There is not comprehensive guide on the API yet, but you can have a look at the bindings_ file.
+
+Elementary types and constants
+------------------------------
+
+* States are directly in ``kres`` table, e.g. ``kres.YIELD, kres.CONSUME, kres.PRODUCE, kres.DONE, kres.FAIL``.
+* DNS classes are in ``kres.class`` table, e.g. ``kres.class.IN`` for Internet class.
+* DNS types are in ``kres.type`` table, e.g. ``kres.type.AAAA`` for AAAA type.
+* DNS rcodes types are in ``kres.rcode`` table, e.g. ``kres.rcode.NOERROR``.
+* Extended DNS error codes are in ``kres.extended_error`` table, e.g. ``kres.extended_error.BLOCKED``.
+* Packet sections (QUESTION, ANSWER, AUTHORITY, ADDITIONAL) are in the ``kres.section`` table.
+
+Working with domain names
+-------------------------
+
+The internal API usually works with domain names in label format, you can convert between text and wire freely.
+
+.. code-block:: lua
+
+ local dname = kres.str2dname('business.se')
+ local strname = kres.dname2str(dname)
+
+Working with resource records
+-----------------------------
+
+Resource records are stored as tables.
+
+.. code-block:: lua
+
+ local rr = { owner = kres.str2dname('owner'),
+ ttl = 0,
+ class = kres.class.IN,
+ type = kres.type.CNAME,
+ rdata = kres.str2dname('someplace') }
+ print(kres.rr2str(rr))
+
+RRSets in packet can be accessed using FFI, you can easily fetch single records.
+
+.. code-block:: lua
+
+ local rrset = { ... }
+ local rr = rrset:get(0) -- Return first RR
+ print(kres.dname2str(rr:owner()))
+ print(rr:ttl())
+ print(kres.rr2str(rr))
+
+Working with packets
+--------------------
+
+Packet is the data structure that you're going to see in layers very often. They consists of a header, and four sections: QUESTION, ANSWER, AUTHORITY, ADDITIONAL. The first section is special, as it contains the query name, type, and class; the rest of the sections contain RRSets.
+
+First you need to convert it to a type known to FFI and check basic properties. Let's start with a snippet of a *consume* layer.
+
+.. code-block:: lua
+
+ consume = function (state, req, pkt)
+ print('rcode:', pkt:rcode())
+ print('query:', kres.dname2str(pkt:qname()), pkt:qclass(), pkt:qtype())
+ if pkt:rcode() ~= kres.rcode.NOERROR then
+ print('error response')
+ end
+ end
+
+You can enumerate records in the sections.
+
+.. code-block:: lua
+
+ local records = pkt:section(kres.section.ANSWER)
+ for i = 1, #records do
+ local rr = records[i]
+ if rr.type == kres.type.AAAA then
+ print(kres.rr2str(rr))
+ end
+ end
+
+During *produce* or *begin*, you might want to want to write to packet. Keep in mind that you have to write packet sections in sequence,
+e.g. you can't write to ANSWER after writing AUTHORITY, it's like stages where you can't go back.
+
+.. code-block:: lua
+
+ pkt:rcode(kres.rcode.NXDOMAIN)
+ -- Clear answer and write QUESTION
+ pkt:recycle()
+ pkt:question('\7blocked', kres.class.IN, kres.type.SOA)
+ -- Start writing data
+ pkt:begin(kres.section.ANSWER)
+ -- Nothing in answer
+ pkt:begin(kres.section.AUTHORITY)
+ local soa = { owner = '\7blocked', ttl = 900, class = kres.class.IN, type = kres.type.SOA, rdata = '...' }
+ pkt:put(soa.owner, soa.ttl, soa.class, soa.type, soa.rdata)
+
+Working with requests
+---------------------
+
+The request holds information about currently processed query, enabled options, cache, and other extra data.
+You primarily need to retrieve currently processed query.
+
+.. code-block:: lua
+
+ consume = function (state, req, pkt)
+ print(req.options)
+ print(req.state)
+
+ -- Print information about current query
+ local current = req:current()
+ print(kres.dname2str(current.owner))
+ print(current.stype, current.sclass, current.id, current.flags)
+ end
+
+In layers that either begin or finalize, you can walk the list of resolved queries.
+
+.. code-block:: lua
+
+ local last = req:resolved()
+ print(last.stype)
+
+As described in the layers, you can not only retrieve information about current query, but also push new ones or pop old ones.
+
+.. code-block:: lua
+
+ -- Push new query
+ local qry = req:push(pkt:qname(), kres.type.SOA, kres.class.IN)
+ qry.flags.AWAIT_CUT = true
+
+ -- Pop the query, this will erase it from resolution plan
+ req:pop(qry)
+
+
+.. _libknot: https://gitlab.nic.cz/knot/knot-dns/tree/master/src/libknot
+.. _bindings: https://gitlab.nic.cz/knot/knot-resolver/blob/master/daemon/lua/kres.lua
+
+
+.. _significant-lua-changes:
+
+Significant Lua API changes
+---------------------------
+
+Incompatible changes since 3.0.0
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+In the main ``kres.*`` lua binding, there was only change in struct knot_rrset_t:
+
+- constructor now accepts TTL as additional parameter (defaulting to zero)
+- add_rdata() doesn't accept TTL anymore (and will throw an error if passed)
+
+In case you used knot_* functions and structures bound to lua:
+
+- knot_dname_is_sub(a, b): knot_dname_in_bailiwick(a, b) > 0
+- knot_rdata_rdlen(): knot_rdataset_at().len
+- knot_rdata_data(): knot_rdataset_at().data
+- knot_rdata_array_size(): offsetof(struct knot_data_t, data) + knot_rdataset_at().len
+- struct knot_rdataset: field names were renamed to .count and .rdata
+- some functions got inlined from headers, but you can use their kr_* clones:
+ kr_rrsig_sig_inception(), kr_rrsig_sig_expiration(), kr_rrsig_type_covered().
+ Note that these functions now accept knot_rdata_t* instead of a pair
+ knot_rdataset_t* and size_t - you can use knot_rdataset_at() for that.
+
+- knot_rrset_add_rdata() doesn't take TTL parameter anymore
+- knot_rrset_init_empty() was inlined, but in lua you can use the constructor
+- knot_rrset_ttl() was inlined, but in lua you can use :ttl() method instead
+
+- knot_pkt_qname(), _qtype(), _qclass(), _rr(), _section() were inlined,
+ but in lua you can use methods instead, e.g. myPacket:qname()
+- knot_pkt_free() takes knot_pkt_t* instead of knot_pkt_t**, but from lua
+ you probably didn't want to use that; constructor ensures garbage collection.
+
+
+.. |---| unicode:: U+02014 .. em dash
diff --git a/lib/cache/README.rst b/lib/cache/README.rst
new file mode 100644
index 0000000..767c4c0
--- /dev/null
+++ b/lib/cache/README.rst
@@ -0,0 +1,69 @@
+.. SPDX-License-Identifier: GPL-3.0-or-later
+
+.. _cache_sizing:
+
+Cache sizing
+------------
+
+For personal use-cases and small deployments cache size around 100 MB is more than enough.
+
+For large deployments we recommend to run Knot Resolver on a dedicated machine, and to allocate 90% of machine's free memory for resolver's cache.
+
+For example, imagine you have a machine with 16 GB of memory.
+After machine restart you use command ``free -m`` to determine amount of free memory (without swap):
+
+.. code-block:: bash
+
+ $ free -m
+ total used free
+ Mem: 15907 979 14928
+
+Now you can configure cache size to be 90% of the free memory 14 928 MB, i.e. 13 453 MB:
+
+.. code-block:: lua
+
+ -- 90 % of free memory after machine restart
+ cache.size = 13453 * MB
+
+.. _cache_persistence:
+
+Cache persistence
+-----------------
+.. tip:: Using tmpfs for cache improves performance and reduces disk I/O.
+
+By default the cache is saved on a persistent storage device
+so the content of the cache is persisted during system reboot.
+This usually leads to smaller latency after restart etc.,
+however in certain situations a non-persistent cache storage might be preferred, e.g.:
+
+ - Resolver handles high volume of queries and I/O performance to disk is too low.
+ - Threat model includes attacker getting access to disk content in power-off state.
+ - Disk has limited number of writes (e.g. flash memory in routers).
+
+If non-persistent cache is desired configure cache directory to be on
+tmpfs_ filesystem, a temporary in-memory file storage.
+The cache content will be saved in memory, and thus have faster access
+and will be lost on power-off or reboot.
+
+
+.. note:: In most of the Unix-like systems ``/tmp`` and ``/var/run`` are commonly mounted to tmpfs.
+ While it is technically possible to move the cache to an existing
+ tmpfs filesystem, it is *not recommended*: The path to cache is specified in
+ multiple systemd units, and a shared tmpfs space could be used up by other
+ applications, leading to ``SIGBUS`` errors during runtime.
+
+Mounting the cache directory as tmpfs_ is recommended approach.
+Make sure to use appropriate ``size=`` option and don't forget to adjust the
+size in the config file as well.
+
+.. code-block::
+
+ # /etc/fstab
+ tmpfs /var/cache/knot-resolver tmpfs rw,size=2G,uid=knot-resolver,gid=knot-resolver,nosuid,nodev,noexec,mode=0700 0 0
+
+.. code-block:: lua
+
+ # /etc/knot-resolver/config
+ cache.size = 2 * GB
+
+.. _tmpfs: https://en.wikipedia.org/wiki/Tmpfs
diff --git a/lib/cache/api.c b/lib/cache/api.c
new file mode 100644
index 0000000..116d775
--- /dev/null
+++ b/lib/cache/api.c
@@ -0,0 +1,1029 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#include <errno.h>
+#include <limits.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <time.h>
+#include <unistd.h>
+
+#include <libknot/descriptor.h>
+#include <libknot/dname.h>
+#include <libknot/errcode.h>
+#include <libknot/rrtype/rrsig.h>
+
+#include <uv.h>
+
+#include "contrib/base32hex.h"
+#include "contrib/cleanup.h"
+#include "contrib/ucw/lib.h"
+#include "lib/cache/api.h"
+#include "lib/cache/cdb_lmdb.h"
+#include "lib/defines.h"
+#include "lib/dnssec/nsec3.h"
+#include "lib/generic/trie.h"
+#include "lib/resolve.h"
+#include "lib/rplan.h"
+#include "lib/utils.h"
+
+#include "lib/cache/impl.h"
+
+/* TODO:
+ * - Reconsider when RRSIGs are put in and retrieved from the cache.
+ * Currently it's always done, which _might_ be spurious, depending
+ * on how kresd will use the returned result.
+ * There's also the "problem" that kresd ATM does _not_ ask upstream
+ * with DO bit in some cases.
+ */
+
+
+/** Cache version */
+static const uint16_t CACHE_VERSION = 6;
+/** Key size */
+#define KEY_HSIZE (sizeof(uint8_t) + sizeof(uint16_t))
+#define KEY_SIZE (KEY_HSIZE + KNOT_DNAME_MAXLEN)
+
+
+/** @internal Forward declarations of the implementation details
+ * \param needs_pkt[out] optionally set *needs_pkt = true;
+ * We do that when some RRset wasn't stashed to aggressive cache,
+ * even though it might have taken part in a successful DNSSEC proof:
+ * 1. any opt-out NSEC3, as they typically aren't much use aggressively anyway
+ * 2. some kinds of minimal NSEC* ranges, as they'd seem more trouble than worth:
+ * - extremely short range of covered names limits the benefits severely
+ * - the type-set is often a lie, either a working lie, e.g. CloudFlare's
+ * black lies, or even a non-working lie, e.g. DVE-2018-0003
+ * 3. some kinds of "weird" RRsets, to get at least some caching on them
+ */
+static ssize_t stash_rrset(struct kr_cache *cache, const struct kr_query *qry,
+ const knot_rrset_t *rr, const knot_rrset_t *rr_sigs, uint32_t timestamp,
+ uint8_t rank, trie_t *nsec_pmap, knot_mm_t *pool, bool *needs_pkt);
+/** Preliminary checks before stash_rrset(). Don't call if returns <= 0. */
+static int stash_rrset_precond(const knot_rrset_t *rr, const struct kr_query *qry/*logs*/);
+
+/** @internal Ensure the cache version is right, possibly by clearing it. */
+static int assert_right_version(struct kr_cache *cache)
+{
+ /* Check cache ABI version. */
+ /* CACHE_KEY_DEF: to avoid collisions with kr_cache_match(). */
+ uint8_t key_str[4] = "VERS";
+ knot_db_val_t key = { .data = key_str, .len = sizeof(key_str) };
+ knot_db_val_t val = { NULL, 0 };
+ int ret = cache_op(cache, read, &key, &val, 1);
+ if (ret == 0 && val.len == sizeof(CACHE_VERSION)
+ && memcmp(val.data, &CACHE_VERSION, sizeof(CACHE_VERSION)) == 0) {
+ ret = kr_ok();
+ } else {
+ int oldret = ret;
+ /* Version doesn't match or we were unable to read it, possibly because DB is empty.
+ * Recreate cache and write version key. */
+ ret = cache_op(cache, count);
+ if (ret != 0) { /* Log for non-empty cache to limit noise on fresh start. */
+ kr_log_info(CACHE, "incompatible cache database detected, purging\n");
+ if (oldret) {
+ kr_log_debug(CACHE, "reading version returned: %d\n", oldret);
+ } else if (val.len != sizeof(CACHE_VERSION)) {
+ kr_log_debug(CACHE, "version has bad length: %d\n", (int)val.len);
+ } else {
+ uint16_t ver;
+ memcpy(&ver, val.data, sizeof(ver));
+ kr_log_debug(CACHE, "version has bad value: %d instead of %d\n",
+ (int)ver, (int)CACHE_VERSION);
+ }
+ }
+ ret = cache_op(cache, clear);
+ }
+ /* Rewrite the entry even if it isn't needed. Because of cache-size-changing
+ * possibility it's good to always perform some write during opening of cache. */
+ if (ret == 0) {
+ /* Key/Val is invalidated by cache purge, recreate it */
+ val.data = /*const-cast*/(void *)&CACHE_VERSION;
+ val.len = sizeof(CACHE_VERSION);
+ ret = cache_op(cache, write, &key, &val, 1);
+ }
+ kr_cache_commit(cache);
+ return ret;
+}
+
+int kr_cache_open(struct kr_cache *cache, const struct kr_cdb_api *api, struct kr_cdb_opts *opts, knot_mm_t *mm)
+{
+ if (kr_fails_assert(cache))
+ return kr_error(EINVAL);
+ memset(cache, 0, sizeof(*cache));
+ /* Open cache */
+ if (!api)
+ api = kr_cdb_lmdb();
+ cache->api = api;
+ int ret = cache->api->open(&cache->db, &cache->stats, opts, mm);
+ if (ret == 0) {
+ ret = assert_right_version(cache);
+ // The included write also committed maxsize increase to the file.
+ }
+ if (ret == 0 && opts->maxsize) {
+ /* If some maxsize is requested and it's smaller than in-file maxsize,
+ * LMDB only restricts our env without changing the in-file maxsize.
+ * That is worked around by reopening (found no other reliable way). */
+ cache->api->close(cache->db, &cache->stats);
+ struct kr_cdb_opts opts2;
+ memcpy(&opts2, opts, sizeof(opts2));
+ opts2.maxsize = 0;
+ ret = cache->api->open(&cache->db, &cache->stats, &opts2, mm);
+ }
+
+ char *fpath = kr_absolutize_path(opts->path, "data.mdb");
+ if (kr_fails_assert(fpath)) {
+ /* non-critical, but still */
+ fpath = "<ENOMEM>";
+ } else {
+ kr_cache_emergency_file_to_remove = fpath;
+ }
+
+ if (ret == 0 && opts->maxsize) {
+ size_t maxsize = cache->api->get_maxsize(cache->db);
+ if (maxsize > opts->maxsize) kr_log_warning(CACHE,
+ "Warning: real cache size is %zu instead of the requested %zu bytes."
+ " To reduce the size you need to remove the file '%s' by hand.\n",
+ maxsize, opts->maxsize, fpath);
+ }
+ if (ret != 0)
+ return ret;
+ cache->ttl_min = KR_CACHE_DEFAULT_TTL_MIN;
+ cache->ttl_max = KR_CACHE_DEFAULT_TTL_MAX;
+ kr_cache_make_checkpoint(cache);
+ return 0;
+}
+
+const char *kr_cache_emergency_file_to_remove = NULL;
+
+
+#define cache_isvalid(cache) ((cache) && (cache)->api && (cache)->db)
+
+void kr_cache_close(struct kr_cache *cache)
+{
+ kr_cache_check_health(cache, -1);
+ if (cache_isvalid(cache)) {
+ cache_op(cache, close);
+ cache->db = NULL;
+ }
+ free(/*const-cast*/(char*)kr_cache_emergency_file_to_remove);
+ kr_cache_emergency_file_to_remove = NULL;
+}
+
+int kr_cache_commit(struct kr_cache *cache)
+{
+ if (!cache_isvalid(cache)) {
+ return kr_error(EINVAL);
+ }
+ if (cache->api->commit) {
+ return cache_op(cache, commit);
+ }
+ return kr_ok();
+}
+
+int kr_cache_clear(struct kr_cache *cache)
+{
+ if (!cache_isvalid(cache)) {
+ return kr_error(EINVAL);
+ }
+ int ret = cache_op(cache, clear);
+ if (ret == 0) {
+ kr_cache_make_checkpoint(cache);
+ ret = assert_right_version(cache);
+ }
+ return ret;
+}
+
+/* When going stricter, BEWARE of breaking entry_h_consistent_NSEC() */
+struct entry_h * entry_h_consistent_E(knot_db_val_t data, uint16_t type)
+{
+ (void) type; /* unused, for now */
+ if (!data.data) return NULL;
+ /* Length checks. */
+ if (data.len < offsetof(struct entry_h, data))
+ return NULL;
+ const struct entry_h *eh = data.data;
+ if (eh->is_packet) {
+ uint16_t pkt_len;
+ if (data.len < offsetof(struct entry_h, data) + sizeof(pkt_len)) {
+ return NULL;
+ }
+ memcpy(&pkt_len, eh->data, sizeof(pkt_len));
+ if (data.len < offsetof(struct entry_h, data) + sizeof(pkt_len)
+ + pkt_len) {
+ return NULL;
+ }
+ }
+
+ bool ok = true;
+ ok = ok && kr_rank_check(eh->rank);
+ ok = ok && (!kr_rank_test(eh->rank, KR_RANK_BOGUS)
+ || eh->is_packet);
+ ok = ok && (eh->is_packet || !eh->has_optout);
+
+ return ok ? /*const-cast*/(struct entry_h *)eh : NULL;
+}
+
+int32_t get_new_ttl(const struct entry_h *entry, const struct kr_query *qry,
+ const knot_dname_t *owner, uint16_t type, uint32_t now)
+{
+ int32_t diff = now - entry->time;
+ if (diff < 0) {
+ /* We may have obtained the record *after* the request started. */
+ diff = 0;
+ }
+ int32_t res = entry->ttl - diff;
+ if (res < 0 && owner && qry && qry->stale_cb) {
+ /* Stale-serving decision, delegated to a callback. */
+ int res_stale = qry->stale_cb(res, owner, type, qry);
+ if (res_stale >= 0) {
+ VERBOSE_MSG(qry, "responding with stale answer\n");
+ /* LATER: Perhaps we could use a more specific Stale
+ * NXDOMAIN Answer code for applicable responses. */
+ kr_request_set_extended_error(qry->request, KNOT_EDNS_EDE_STALE, "6Q6X");
+ return res_stale;
+ }
+ }
+ return res;
+}
+
+int32_t kr_cache_ttl(const struct kr_cache_p *peek, const struct kr_query *qry,
+ const knot_dname_t *name, uint16_t type)
+{
+ const struct entry_h *eh = peek->raw_data;
+ return get_new_ttl(eh, qry, name, type, qry->timestamp.tv_sec);
+}
+
+/** Check that no label contains a zero character, incl. a log trace.
+ *
+ * We refuse to work with those, as LF and our cache keys might become ambiguous.
+ * Assuming uncompressed name, as usual.
+ * CACHE_KEY_DEF
+ */
+static bool check_dname_for_lf(const knot_dname_t *n, const struct kr_query *qry/*logging*/)
+{
+ const bool ret = knot_dname_size(n) == strlen((const char *)n) + 1;
+ if (!ret && kr_log_is_debug_qry(CACHE, qry)) {
+ auto_free char *n_str = kr_dname_text(n);
+ VERBOSE_MSG(qry, "=> skipping zero-containing name %s\n", n_str);
+ }
+ return ret;
+}
+
+/** Return false on types to be ignored. Meant both for sname and direct cache requests. */
+static bool check_rrtype(uint16_t type, const struct kr_query *qry/*logging*/)
+{
+ const bool ret = !knot_rrtype_is_metatype(type)
+ && type != KNOT_RRTYPE_RRSIG;
+ if (!ret && kr_log_is_debug_qry(CACHE, qry)) {
+ auto_free char *type_str = kr_rrtype_text(type);
+ VERBOSE_MSG(qry, "=> skipping RR type %s\n", type_str);
+ }
+ return ret;
+}
+
+/** Like key_exact_type() but omits a couple checks not holding for pkt cache. */
+knot_db_val_t key_exact_type_maypkt(struct key *k, uint16_t type)
+{
+ if (kr_fails_assert(check_rrtype(type, NULL)))
+ return (knot_db_val_t){ NULL, 0 };
+ switch (type) {
+ case KNOT_RRTYPE_RRSIG: /* no RRSIG query caching, at least for now */
+ kr_assert(false);
+ return (knot_db_val_t){ NULL, 0 };
+ /* xNAME lumped into NS. */
+ case KNOT_RRTYPE_CNAME:
+ case KNOT_RRTYPE_DNAME:
+ type = KNOT_RRTYPE_NS;
+ default:
+ break;
+ }
+
+ int name_len = k->buf[0];
+ k->buf[name_len + 1] = 0; /* make sure different names can never match */
+ k->buf[name_len + 2] = 'E'; /* tag for exact name+type matches */
+ memcpy(k->buf + name_len + 3, &type, 2);
+ k->type = type;
+ /* CACHE_KEY_DEF: key == dname_lf + '\0' + 'E' + RRTYPE */
+ return (knot_db_val_t){ k->buf + 1, name_len + 4 };
+}
+
+
+/** The inside for cache_peek(); implementation separated to ./peek.c */
+int peek_nosync(kr_layer_t *ctx, knot_pkt_t *pkt);
+/** function for .produce phase */
+int cache_peek(kr_layer_t *ctx, knot_pkt_t *pkt)
+{
+ struct kr_request *req = ctx->req;
+ struct kr_query *qry = req->current_query;
+ /* We first check various exit-conditions and then call the _real function. */
+
+ if (!kr_cache_is_open(&req->ctx->cache)
+ || ctx->state & (KR_STATE_FAIL|KR_STATE_DONE) || qry->flags.NO_CACHE
+ || (qry->flags.CACHE_TRIED && !qry->stale_cb)
+ || !check_rrtype(qry->stype, qry) /* LATER: some other behavior for some of these? */
+ || qry->sclass != KNOT_CLASS_IN) {
+ return ctx->state; /* Already resolved/failed or already tried, etc. */
+ }
+ /* ATM cache only peeks for qry->sname and that would be useless
+ * to repeat on every iteration, so disable it from now on.
+ * LATER(optim.): assist with more precise QNAME minimization. */
+ qry->flags.CACHE_TRIED = true;
+
+ if (qry->stype == KNOT_RRTYPE_NSEC) {
+ VERBOSE_MSG(qry, "=> skipping stype NSEC\n");
+ return ctx->state;
+ }
+ if (!check_dname_for_lf(qry->sname, qry)) {
+ return ctx->state;
+ }
+
+ int ret = peek_nosync(ctx, pkt);
+ kr_cache_commit(&req->ctx->cache);
+ return ret;
+}
+
+
+
+/** It's simply inside of cycle taken out to decrease indentation. \return error code. */
+static int stash_rrarray_entry(ranked_rr_array_t *arr, int arr_i,
+ const struct kr_query *qry, struct kr_cache *cache,
+ int *unauth_cnt, trie_t *nsec_pmap, bool *needs_pkt);
+/** Stash a single nsec_p. \return 0 (errors are ignored). */
+static int stash_nsec_p(const knot_dname_t *dname, const char *nsec_p_v,
+ struct kr_cache *cache, uint32_t timestamp, knot_mm_t *pool,
+ const struct kr_query *qry/*logging*/);
+
+/** The whole .consume phase for the cache module. */
+int cache_stash(kr_layer_t *ctx, knot_pkt_t *pkt)
+{
+ struct kr_request *req = ctx->req;
+ struct kr_query *qry = req->current_query;
+ struct kr_cache *cache = &req->ctx->cache;
+
+ /* Note: we cache even in KR_STATE_FAIL. For example,
+ * BOGUS answer can go to +cd cache even without +cd request. */
+ if (!kr_cache_is_open(cache) || !qry
+ || qry->flags.CACHED || !check_rrtype(knot_pkt_qtype(pkt), qry)
+ || qry->sclass != KNOT_CLASS_IN) {
+ return ctx->state;
+ }
+ /* Do not cache truncated answers, at least for now. LATER */
+ if (knot_wire_get_tc(pkt->wire)) {
+ return ctx->state;
+ }
+ int unauth_cnt = 0;
+ bool needs_pkt = false;
+ if (qry->flags.STUB) {
+ needs_pkt = true;
+ goto stash_packet;
+ }
+
+ /* Stash individual records. */
+ ranked_rr_array_t *selected[] = kr_request_selected(req);
+ trie_t *nsec_pmap = trie_create(&req->pool);
+ if (kr_fails_assert(nsec_pmap))
+ goto finally;
+ for (int psec = KNOT_ANSWER; psec <= KNOT_ADDITIONAL; ++psec) {
+ ranked_rr_array_t *arr = selected[psec];
+ /* uncached entries are located at the end */
+ for (ssize_t i = arr->len - 1; i >= 0; --i) {
+ ranked_rr_array_entry_t *entry = arr->at[i];
+ if (entry->qry_uid != qry->uid || entry->dont_cache) {
+ continue;
+ /* TODO: probably safe to break on uid mismatch but maybe not worth it */
+ }
+ int ret = stash_rrarray_entry(
+ arr, i, qry, cache, &unauth_cnt, nsec_pmap,
+ /* ADDITIONAL RRs are considered non-essential
+ * in our (resolver) answers */
+ (psec == KNOT_ADDITIONAL ? NULL : &needs_pkt));
+ if (ret) {
+ VERBOSE_MSG(qry, "=> stashing RRs errored out\n");
+ goto finally;
+ }
+ /* LATER(optim.): maybe filter out some type-rank combinations
+ * that won't be useful as separate RRsets. */
+ }
+ }
+
+ trie_it_t *it;
+ for (it = trie_it_begin(nsec_pmap); !trie_it_finished(it); trie_it_next(it)) {
+ stash_nsec_p((const knot_dname_t *)trie_it_key(it, NULL),
+ (const char *)*trie_it_val(it),
+ cache, qry->timestamp.tv_sec, &req->pool, req->current_query);
+ }
+ trie_it_free(it);
+ /* LATER(optim.): typically we also have corresponding NS record in the list,
+ * so we might save a cache operation. */
+stash_packet:
+ if (qry->flags.PKT_IS_SANE && check_dname_for_lf(knot_pkt_qname(pkt), qry)) {
+ stash_pkt(pkt, qry, req, needs_pkt);
+ }
+
+finally:
+ if (unauth_cnt) {
+ VERBOSE_MSG(qry, "=> stashed also %d nonauth RRsets\n", unauth_cnt);
+ };
+ kr_cache_commit(cache);
+ return ctx->state; /* we ignore cache-stashing errors */
+}
+
+/** Preliminary checks before stash_rrset(). Don't call if returns <= 0. */
+static int stash_rrset_precond(const knot_rrset_t *rr, const struct kr_query *qry/*logs*/)
+{
+ if (kr_fails_assert(rr && rr->rclass == KNOT_CLASS_IN))
+ return kr_error(EINVAL);
+ if (!check_rrtype(rr->type, qry))
+ return kr_ok();
+ if (!check_dname_for_lf(rr->owner, qry))
+ return kr_ok();
+ return 1/*proceed*/;
+}
+
+/** Return true on some cases of NSEC* RRsets covering minimal ranges.
+ * Also include some abnormal RR cases; qry is just for logging. */
+static bool rrset_has_min_range_or_weird(const knot_rrset_t *rr, const struct kr_query *qry)
+{
+ if (rr->rrs.count != 1) {
+ kr_assert(rr->rrs.count > 0);
+ if (rr->type == KNOT_RRTYPE_NSEC || rr->type == KNOT_RRTYPE_NSEC3
+ || rr->rrs.count == 0) {
+ return true; /*< weird */
+ }
+ }
+ bool ret; /**< NOT used for the weird cases */
+ if (rr->type == KNOT_RRTYPE_NSEC) {
+ if (!check_dname_for_lf(rr->owner, qry))
+ return true; /*< weird, probably filtered even before this point */
+ ret = !check_dname_for_lf(knot_nsec_next(rr->rrs.rdata), qry);
+ /* ^^ Zero inside the next-name label means it's probably a minimal range,
+ * and anyway it's problematic for our aggressive cache (comparisons).
+ * Real-life examples covered:
+ * NSEC: name -> \000.name (e.g. typical foobar.CloudFlare.net)
+ * NSEC: name -> name\000 (CloudFlare on delegations)
+ */
+ } else if (rr->type == KNOT_RRTYPE_NSEC3) {
+ if (knot_nsec3_next_len(rr->rrs.rdata) != NSEC3_HASH_LEN
+ || *rr->owner != NSEC3_HASH_TXT_LEN) {
+ return true; /*< weird */
+ }
+ /* Let's work on the binary hashes. Find if they "differ by one",
+ * by constructing the owner hash incremented by one and comparing. */
+ uint8_t owner_hash[NSEC3_HASH_LEN];
+ if (base32hex_decode(rr->owner + 1, NSEC3_HASH_TXT_LEN,
+ owner_hash, NSEC3_HASH_LEN) != NSEC3_HASH_LEN) {
+ return true; /*< weird */
+ }
+ for (int i = NSEC3_HASH_LEN - 1; i >= 0; --i) {
+ if (++owner_hash[i] != 0) break;
+ }
+ const uint8_t *next_hash = knot_nsec3_next(rr->rrs.rdata);
+ ret = memcmp(owner_hash, next_hash, NSEC3_HASH_LEN) == 0;
+ } else {
+ return false;
+ }
+ if (ret) VERBOSE_MSG(qry, "=> minimized NSEC* range detected\n");
+ return ret;
+}
+
+static ssize_t stash_rrset(struct kr_cache *cache, const struct kr_query *qry,
+ const knot_rrset_t *rr, const knot_rrset_t *rr_sigs, uint32_t timestamp,
+ uint8_t rank, trie_t *nsec_pmap, knot_mm_t *pool, bool *needs_pkt)
+{
+ if (kr_rank_test(rank, KR_RANK_BOGUS)) {
+ WITH_VERBOSE(qry) {
+ auto_free char *type_str = kr_rrtype_text(rr->type);
+ VERBOSE_MSG(qry, "=> skipping bogus RR set %s\n", type_str);
+ }
+ return kr_ok();
+ }
+ if (rr->type == KNOT_RRTYPE_NSEC3 && rr->rrs.count
+ && knot_nsec3_iters(rr->rrs.rdata) > KR_NSEC3_MAX_ITERATIONS) {
+ /* This shouldn't happen often, thanks to downgrades during validation. */
+ VERBOSE_MSG(qry, "=> skipping NSEC3 with too many iterations\n");
+ return kr_ok();
+ }
+ if (kr_fails_assert(cache && stash_rrset_precond(rr, qry) > 0))
+ return kr_error(EINVAL);
+
+ int ret = kr_ok();
+ if (rrset_has_min_range_or_weird(rr, qry))
+ goto return_needs_pkt;
+ const int wild_labels = rr_sigs == NULL ? 0 :
+ knot_dname_labels(rr->owner, NULL) - knot_rrsig_labels(rr_sigs->rrs.rdata);
+ if (wild_labels < 0)
+ goto return_needs_pkt;
+ const knot_dname_t *encloser = rr->owner; /**< the closest encloser name */
+ for (int i = 0; i < wild_labels; ++i) {
+ encloser = knot_wire_next_label(encloser, NULL);
+ }
+
+ /* Construct the key under which RRs will be stored,
+ * and add corresponding nsec_pmap item (if necessary). */
+ struct key k_storage, *k = &k_storage;
+ knot_db_val_t key;
+ switch (rr->type) {
+ case KNOT_RRTYPE_NSEC3:
+ /* Skip opt-out NSEC3 sets. */
+ if (KNOT_NSEC3_FLAG_OPT_OUT & knot_nsec3_flags(rr->rrs.rdata))
+ goto return_needs_pkt;
+ /* fall through */
+ case KNOT_RRTYPE_NSEC:
+ /* Skip any NSEC*s that aren't validated or are suspicious. */
+ if (!kr_rank_test(rank, KR_RANK_SECURE) || rr->rrs.count != 1)
+ goto return_needs_pkt;
+ if (kr_fails_assert(rr_sigs && rr_sigs->rrs.count && rr_sigs->rrs.rdata)) {
+ ret = kr_error(EINVAL);
+ goto return_needs_pkt;
+ }
+ const knot_dname_t *signer = knot_rrsig_signer_name(rr_sigs->rrs.rdata);
+ const int signer_size = knot_dname_size(signer);
+ k->zlf_len = signer_size - 1;
+
+ void **npp = NULL;
+ if (nsec_pmap) {
+ npp = trie_get_ins(nsec_pmap, (const char *)signer, signer_size);
+ if (kr_fails_assert(npp))
+ return kr_error(ENOMEM);
+ }
+ if (rr->type == KNOT_RRTYPE_NSEC) {
+ key = key_NSEC1(k, encloser, wild_labels);
+ break;
+ }
+
+ kr_require(rr->type == KNOT_RRTYPE_NSEC3);
+ const knot_rdata_t * const rdata = rr->rrs.rdata;
+ if (rdata->len <= 4) {
+ ret = kr_error(EILSEQ); /*< data from outside; less trust */
+ goto return_needs_pkt;
+ }
+ const int np_dlen = nsec_p_rdlen(rdata->data);
+ if (np_dlen > rdata->len) {
+ ret = kr_error(EILSEQ);
+ goto return_needs_pkt;
+ }
+ key = key_NSEC3(k, encloser, nsec_p_mkHash(rdata->data));
+ if (npp && !*npp) {
+ *npp = mm_alloc(pool, np_dlen);
+ if (kr_fails_assert(*npp))
+ break;
+ memcpy(*npp, rdata->data, np_dlen);
+ }
+ break;
+ default:
+ ret = kr_dname_lf(k->buf, encloser, wild_labels);
+ if (kr_fails_assert(ret == 0))
+ goto return_needs_pkt;
+ key = key_exact_type(k, rr->type);
+ }
+
+ /* Compute in-cache size for the new data. */
+ const knot_rdataset_t *rds_sigs = rr_sigs ? &rr_sigs->rrs : NULL;
+ const int rr_ssize = rdataset_dematerialize_size(&rr->rrs);
+ if (kr_fails_assert(rr_ssize == to_even(rr_ssize)))
+ return kr_error(EINVAL);
+ knot_db_val_t val_new_entry = {
+ .data = NULL,
+ .len = offsetof(struct entry_h, data) + rr_ssize
+ + rdataset_dematerialize_size(rds_sigs),
+ };
+
+ /* Prepare raw memory for the new entry. */
+ ret = entry_h_splice(&val_new_entry, rank, key, k->type, rr->type,
+ rr->owner, qry, cache, timestamp);
+ if (ret) return kr_ok(); /* some aren't really errors */
+ if (kr_fails_assert(val_new_entry.data))
+ return kr_error(EFAULT);
+
+ /* Write the entry itself. */
+ struct entry_h *eh = val_new_entry.data;
+ memset(eh, 0, offsetof(struct entry_h, data));
+ eh->time = timestamp;
+ eh->ttl = rr->ttl;
+ eh->rank = rank;
+ rdataset_dematerialize(&rr->rrs, eh->data);
+ rdataset_dematerialize(rds_sigs, eh->data + rr_ssize);
+ if (kr_fails_assert(entry_h_consistent_E(val_new_entry, rr->type)))
+ return kr_error(EINVAL);
+
+ #if 0 /* Occasionally useful when debugging some kinds of changes. */
+ {
+ kr_cache_commit(cache);
+ knot_db_val_t val = { NULL, 0 };
+ ret = cache_op(cache, read, &key, &val, 1);
+ if (ret != kr_error(ENOENT)) { // ENOENT might happen in some edge case, I guess
+ kr_assert(!ret);
+ entry_list_t el;
+ entry_list_parse(val, el);
+ }
+ }
+ #endif
+
+ /* Verbose-log some not-too-common cases. */
+ WITH_VERBOSE(qry) { if (kr_rank_test(rank, KR_RANK_AUTH)
+ || rr->type == KNOT_RRTYPE_NS) {
+ auto_free char *type_str = kr_rrtype_text(rr->type),
+ *encl_str = kr_dname_text(encloser);
+ VERBOSE_MSG(qry, "=> stashed %s%s %s, rank 0%.2o, "
+ "%d B total, incl. %d RRSIGs\n",
+ (wild_labels ? "*." : ""), encl_str, type_str, rank,
+ (int)val_new_entry.len, (rr_sigs ? rr_sigs->rrs.count : 0)
+ );
+ } }
+
+ return (ssize_t) val_new_entry.len;
+return_needs_pkt:
+ if (needs_pkt) *needs_pkt = true;
+ return ret;
+}
+
+static int stash_rrarray_entry(ranked_rr_array_t *arr, int arr_i,
+ const struct kr_query *qry, struct kr_cache *cache,
+ int *unauth_cnt, trie_t *nsec_pmap, bool *needs_pkt)
+{
+ ranked_rr_array_entry_t *entry = arr->at[arr_i];
+ if (entry->cached) {
+ return kr_ok();
+ }
+ const knot_rrset_t *rr = entry->rr;
+ if (rr->type == KNOT_RRTYPE_RRSIG) {
+ return kr_ok(); /* reduce verbose logging from the following call */
+ }
+ int ret = stash_rrset_precond(rr, qry);
+ if (ret <= 0) {
+ return ret;
+ }
+
+ /* Try to find corresponding signatures, always. LATER(optim.): speed. */
+ ranked_rr_array_entry_t *entry_rrsigs = NULL;
+ const knot_rrset_t *rr_sigs = NULL;
+ for (ssize_t j = arr->len - 1; j >= 0; --j) {
+ /* TODO: ATM we assume that some properties are the same
+ * for all RRSIGs in the set (esp. label count). */
+ ranked_rr_array_entry_t *e = arr->at[j];
+ if (kr_fails_assert(!e->in_progress))
+ return kr_error(EINVAL);
+ bool ok = e->qry_uid == qry->uid && !e->cached
+ && e->rr->type == KNOT_RRTYPE_RRSIG
+ && knot_rrsig_type_covered(e->rr->rrs.rdata) == rr->type
+ && knot_dname_is_equal(rr->owner, e->rr->owner);
+ if (!ok) continue;
+ entry_rrsigs = e;
+ rr_sigs = e->rr;
+ break;
+ }
+
+ ssize_t written = stash_rrset(cache, qry, rr, rr_sigs, qry->timestamp.tv_sec,
+ entry->rank, nsec_pmap, &qry->request->pool, needs_pkt);
+ if (written < 0) {
+ kr_log_error(CACHE, "[%05u.%02u] stash failed, ret = %d\n", qry->request->uid,
+ qry->uid, ret);
+ return (int) written;
+ }
+
+ if (written > 0) {
+ /* Mark entry as cached for the rest of the query processing */
+ entry->cached = true;
+ if (entry_rrsigs) {
+ entry_rrsigs->cached = true;
+ }
+ if (!kr_rank_test(entry->rank, KR_RANK_AUTH) && rr->type != KNOT_RRTYPE_NS) {
+ *unauth_cnt += 1;
+ }
+ }
+
+ return kr_ok();
+}
+
+static int stash_nsec_p(const knot_dname_t *dname, const char *nsec_p_v,
+ struct kr_cache *cache, uint32_t timestamp, knot_mm_t *pool,
+ const struct kr_query *qry/*logging*/)
+{
+ uint32_t valid_until = timestamp + cache->ttl_max;
+ /* LATER(optim.): be more precise here ^^ and reduce calls. */
+ static const int32_t ttl_margin = 3600;
+ const uint8_t *nsec_p = (const uint8_t *)nsec_p_v;
+ int data_stride = sizeof(valid_until) + nsec_p_rdlen(nsec_p);
+
+ unsigned int log_hash = 0xFeeeFeee; /* this type is simpler for printf args */
+ auto_free char *log_dname = NULL;
+ WITH_VERBOSE(qry) {
+ log_hash = nsec_p_v ? nsec_p_mkHash((const uint8_t *)nsec_p_v) : 0;
+ log_dname = kr_dname_text(dname);
+ }
+ /* Find what's in the cache. */
+ struct key k_storage, *k = &k_storage;
+ int ret = kr_dname_lf(k->buf, dname, false);
+ if (ret) return kr_error(ret);
+ knot_db_val_t key = key_exact_type(k, KNOT_RRTYPE_NS);
+ knot_db_val_t val_orig = { NULL, 0 };
+ ret = cache_op(cache, read, &key, &val_orig, 1);
+ if (ret && ret != -ABS(ENOENT)) {
+ VERBOSE_MSG(qry, "=> EL read failed (ret: %d)\n", ret);
+ return kr_ok();
+ }
+ /* Prepare new entry_list_t so we can just write at el[0]. */
+ entry_list_t el;
+ int log_refresh_by = 0;
+ if (ret == -ABS(ENOENT)) {
+ memset(el, 0, sizeof(el));
+ } else {
+ ret = entry_list_parse(val_orig, el);
+ if (ret) {
+ VERBOSE_MSG(qry, "=> EL parse failed (ret: %d)\n", ret);
+ return kr_error(0);
+ }
+ /* Find the index to replace. */
+ int i_replace = ENTRY_APEX_NSECS_CNT - 1;
+ for (int i = 0; i < ENTRY_APEX_NSECS_CNT; ++i) {
+ if (el[i].len != data_stride) continue;
+ if (nsec_p && memcmp(nsec_p, (uint8_t *)el[i].data + sizeof(uint32_t),
+ data_stride - sizeof(uint32_t)) != 0) {
+ continue;
+ }
+ /* Save a cache operation if TTL extended only a little. */
+ uint32_t valid_orig;
+ memcpy(&valid_orig, el[i].data, sizeof(valid_orig));
+ const int32_t ttl_extended_by = valid_until - valid_orig;
+ if (ttl_extended_by < ttl_margin) {
+ VERBOSE_MSG(qry,
+ "=> nsec_p stash for %s skipped (extra TTL: %d, hash: %x)\n",
+ log_dname, ttl_extended_by, log_hash);
+ return kr_ok();
+ }
+ i_replace = i;
+ log_refresh_by = ttl_extended_by;
+ break;
+ }
+ /* Shift the other indices: move the first `i_replace` blocks
+ * by one position. */
+ if (i_replace) {
+ memmove(&el[1], &el[0], sizeof(el[0]) * i_replace);
+ }
+ }
+ /* Prepare old data into a buffer. See entry_h_splice() for why. LATER(optim.) */
+ el[0].len = data_stride;
+ el[0].data = NULL;
+ knot_db_val_t val;
+ val.len = entry_list_serial_size(el),
+ val.data = mm_alloc(pool, val.len),
+ entry_list_memcpy(val.data, el);
+ /* Prepare the new data chunk */
+ memcpy(el[0].data, &valid_until, sizeof(valid_until));
+ if (nsec_p) {
+ memcpy((uint8_t *)el[0].data + sizeof(valid_until), nsec_p,
+ data_stride - sizeof(valid_until));
+ }
+ /* Write it all to the cache */
+ ret = cache_op(cache, write, &key, &val, 1);
+ mm_free(pool, val.data);
+ if (ret || !val.data) {
+ VERBOSE_MSG(qry, "=> EL write failed (ret: %d)\n", ret);
+ return kr_ok();
+ }
+ if (log_refresh_by) {
+ VERBOSE_MSG(qry, "=> nsec_p stashed for %s (refresh by %d, hash: %x)\n",
+ log_dname, log_refresh_by, log_hash);
+ } else {
+ VERBOSE_MSG(qry, "=> nsec_p stashed for %s (new, hash: %x)\n",
+ log_dname, log_hash);
+ }
+ return kr_ok();
+}
+
+int kr_cache_insert_rr(struct kr_cache *cache,
+ const knot_rrset_t *rr, const knot_rrset_t *rrsig,
+ uint8_t rank, uint32_t timestamp, bool ins_nsec_p)
+{
+ int err = stash_rrset_precond(rr, NULL);
+ if (err <= 0) {
+ return kr_ok();
+ }
+
+ trie_t *nsec_pmap = NULL;
+ knot_mm_t *pool = NULL;
+ if (ins_nsec_p && (rr->type == KNOT_RRTYPE_NSEC || rr->type == KNOT_RRTYPE_NSEC3)) {
+ pool = mm_ctx_mempool2(4096);
+ nsec_pmap = trie_create(pool);
+ kr_assert(pool && nsec_pmap);
+ }
+
+ ssize_t written = stash_rrset(cache, NULL, rr, rrsig, timestamp, rank,
+ nsec_pmap, pool, NULL);
+
+ if (nsec_pmap) {
+ trie_it_t *it;
+ for (it = trie_it_begin(nsec_pmap); !trie_it_finished(it); trie_it_next(it)) {
+ stash_nsec_p((const knot_dname_t *)trie_it_key(it, NULL),
+ (const char *)*trie_it_val(it),
+ cache, timestamp, pool, NULL);
+ }
+ trie_it_free(it);
+ mm_ctx_delete(pool);
+ }
+
+ if (written >= 0) {
+ return kr_ok();
+ }
+
+ return (int) written;
+}
+
+static int peek_exact_real(struct kr_cache *cache, const knot_dname_t *name, uint16_t type,
+ struct kr_cache_p *peek)
+{
+ if (!check_rrtype(type, NULL) || !check_dname_for_lf(name, NULL)) {
+ return kr_error(ENOTSUP);
+ }
+ struct key k_storage, *k = &k_storage;
+
+ int ret = kr_dname_lf(k->buf, name, false);
+ if (ret) return kr_error(ret);
+
+ knot_db_val_t key = key_exact_type(k, type);
+ knot_db_val_t val = { NULL, 0 };
+ ret = cache_op(cache, read, &key, &val, 1);
+ if (!ret) ret = entry_h_seek(&val, type);
+ if (ret) return kr_error(ret);
+
+ const struct entry_h *eh = entry_h_consistent_E(val, type);
+ if (!eh || eh->is_packet) {
+ // TODO: no packets, but better get rid of whole kr_cache_peek_exact().
+ return kr_error(ENOENT);
+ }
+ *peek = (struct kr_cache_p){
+ .time = eh->time,
+ .ttl = eh->ttl,
+ .rank = eh->rank,
+ .raw_data = val.data,
+ .raw_bound = knot_db_val_bound(val),
+ };
+ return kr_ok();
+}
+int kr_cache_peek_exact(struct kr_cache *cache, const knot_dname_t *name, uint16_t type,
+ struct kr_cache_p *peek)
+{ /* Just wrap with extra verbose logging. */
+ const int ret = peek_exact_real(cache, name, type, peek);
+ if (false && kr_log_is_debug(CACHE, NULL)) { /* too noisy for usual --verbose */
+ auto_free char *type_str = kr_rrtype_text(type),
+ *name_str = kr_dname_text(name);
+ const char *result_str = (ret == kr_ok() ? "hit" :
+ (ret == kr_error(ENOENT) ? "miss" : "error"));
+ VERBOSE_MSG(NULL, "_peek_exact: %s %s %s (ret: %d)",
+ type_str, name_str, result_str, ret);
+ }
+ return ret;
+}
+
+int kr_cache_remove(struct kr_cache *cache, const knot_dname_t *name, uint16_t type)
+{
+ if (!cache_isvalid(cache)) {
+ return kr_error(EINVAL);
+ }
+ if (!cache->api->remove) {
+ return kr_error(ENOSYS);
+ }
+ struct key k_storage, *k = &k_storage;
+ int ret = kr_dname_lf(k->buf, name, false);
+ if (ret) return kr_error(ret);
+
+ knot_db_val_t key = key_exact_type(k, type);
+ return cache_op(cache, remove, &key, 1);
+}
+
+int kr_cache_match(struct kr_cache *cache, const knot_dname_t *name,
+ bool exact_name, knot_db_val_t keyval[][2], int maxcount)
+{
+ if (!cache_isvalid(cache)) {
+ return kr_error(EINVAL);
+ }
+ if (!cache->api->match) {
+ return kr_error(ENOSYS);
+ }
+
+ struct key k_storage, *k = &k_storage;
+
+ int ret = kr_dname_lf(k->buf, name, false);
+ if (ret) return kr_error(ret);
+
+ // use a mock type
+ knot_db_val_t key = key_exact_type(k, KNOT_RRTYPE_A);
+ /* CACHE_KEY_DEF */
+ key.len -= sizeof(uint16_t); /* the type */
+ if (!exact_name) {
+ key.len -= 2; /* '\0' 'E' */
+ if (name[0] == '\0') ++key.len; /* the root name is special ATM */
+ }
+ return cache_op(cache, match, &key, keyval, maxcount);
+}
+
+int kr_unpack_cache_key(knot_db_val_t key, knot_dname_t *buf, uint16_t *type)
+{
+ if (key.data == NULL || buf == NULL || type == NULL) {
+ return kr_error(EINVAL);
+ }
+
+ int len = -1;
+ const char *tag, *key_data = key.data;
+ for (tag = key_data + 1; tag < key_data + key.len; ++tag) {
+ /* CACHE_KEY_DEF */
+ if (tag[-1] == '\0' && (tag == key_data + 1 || tag[-2] == '\0')) {
+ if (tag[0] != 'E') return kr_error(EINVAL);
+ len = tag - 1 - key_data;
+ break;
+ }
+ }
+
+ if (len == -1 || len > KNOT_DNAME_MAXLEN) {
+ return kr_error(EINVAL);
+ }
+
+ int ret = knot_dname_lf2wire(buf, len, key.data);
+ if (ret < 0) {
+ return kr_error(ret);
+ }
+
+ /* CACHE_KEY_DEF: jump over "\0 E/1" */
+ memcpy(type, tag + 1, sizeof(uint16_t));
+
+ return kr_ok();
+}
+
+
+int kr_cache_remove_subtree(struct kr_cache *cache, const knot_dname_t *name,
+ bool exact_name, int maxcount)
+{
+ if (!cache_isvalid(cache)) {
+ return kr_error(EINVAL);
+ }
+
+ knot_db_val_t keyval[maxcount][2], keys[maxcount];
+ int ret = kr_cache_match(cache, name, exact_name, keyval, maxcount);
+ if (ret <= 0) { /* ENOENT -> nothing to remove */
+ return (ret == KNOT_ENOENT) ? 0 : ret;
+ }
+ const int count = ret;
+ /* Duplicate the key strings, as deletion may invalidate the pointers. */
+ int i;
+ for (i = 0; i < count; ++i) {
+ keys[i].len = keyval[i][0].len;
+ keys[i].data = malloc(keys[i].len);
+ if (!keys[i].data) {
+ ret = kr_error(ENOMEM);
+ goto cleanup;
+ }
+ memcpy(keys[i].data, keyval[i][0].data, keys[i].len);
+ }
+ ret = cache_op(cache, remove, keys, count);
+cleanup:
+ kr_cache_commit(cache); /* Sync even after just kr_cache_match(). */
+ /* Free keys */
+ while (--i >= 0) {
+ free(keys[i].data);
+ }
+ return ret;
+}
+
+static void health_timer_cb(uv_timer_t *health_timer)
+{
+ struct kr_cache *cache = health_timer->data;
+ if (cache)
+ cache_op(cache, check_health);
+ /* We don't do anything with the return code. For example, in some situations
+ * the file may not exist (temporarily), and we just expect to be more lucky
+ * when the timer fires again. */
+}
+
+int kr_cache_check_health(struct kr_cache *cache, int interval)
+{
+ if (interval == 0)
+ return cache_op(cache, check_health);
+ if (interval < 0) {
+ if (!cache->health_timer)
+ return kr_ok(); // tolerate stopping a "stopped" timer
+ uv_close((uv_handle_t *)cache->health_timer, (uv_close_cb)free);
+ cache->health_timer->data = NULL;
+ cache->health_timer = NULL;
+ return kr_ok();
+ }
+
+ if (!cache->health_timer) {
+ /* We avoid depending on daemon's symbols by using uv_default_loop. */
+ cache->health_timer = malloc(sizeof(*cache->health_timer));
+ if (!cache->health_timer) return kr_error(ENOMEM);
+ uv_loop_t *loop = uv_default_loop();
+ kr_require(loop);
+ int ret = uv_timer_init(loop, cache->health_timer);
+ if (ret) {
+ free(cache->health_timer);
+ cache->health_timer = NULL;
+ return kr_error(ret);
+ }
+ cache->health_timer->data = cache;
+ }
+ kr_assert(cache->health_timer->data);
+ return kr_error(uv_timer_start(cache->health_timer, health_timer_cb, interval, interval));
+}
+
diff --git a/lib/cache/api.h b/lib/cache/api.h
new file mode 100644
index 0000000..0abe920
--- /dev/null
+++ b/lib/cache/api.h
@@ -0,0 +1,194 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#include <libknot/consts.h>
+#include <libknot/rrset.h>
+#include <sys/time.h>
+#include "lib/cache/cdb_api.h"
+#include "lib/defines.h"
+#include "contrib/ucw/config.h" /*uint*/
+
+#include "lib/module.h"
+/* Prototypes for the 'cache' module implementation. */
+int cache_peek(kr_layer_t *ctx, knot_pkt_t *pkt);
+int cache_stash(kr_layer_t *ctx, knot_pkt_t *pkt);
+
+
+/**
+ * Cache structure, keeps API, instance and metadata.
+ */
+struct kr_cache
+{
+ kr_cdb_pt db; /**< Storage instance */
+ const struct kr_cdb_api *api; /**< Storage engine */
+ struct kr_cdb_stats stats;
+ uint32_t ttl_min, ttl_max; /**< TTL limits; enforced primarily in iterator actually. */
+
+ /* A pair of stamps for detection of real-time shifts during runtime. */
+ struct timeval checkpoint_walltime; /**< Wall time on the last check-point. */
+ uint64_t checkpoint_monotime; /**< Monotonic milliseconds on the last check-point. */
+
+ uv_timer_t *health_timer; /**< Timer used for kr_cache_check_health() */
+};
+// https://datatracker.ietf.org/doc/html/rfc2181#section-8
+#define TTL_MAX_MAX ((1u << 31) - 1)
+
+/**
+ * Open/create cache with provided storage options.
+ * @param cache cache structure to be initialized
+ * @param api storage engine API
+ * @param opts storage-specific options (may be NULL for default)
+ * @param mm memory context.
+ * @return 0 or an error code
+ */
+KR_EXPORT
+int kr_cache_open(struct kr_cache *cache, const struct kr_cdb_api *api, struct kr_cdb_opts *opts, knot_mm_t *mm);
+
+/**
+ * Path to cache file to remove on critical out-of-space error. (do NOT modify it)
+ */
+KR_EXPORT extern
+const char *kr_cache_emergency_file_to_remove;
+
+/**
+ * Close persistent cache.
+ * @note This doesn't clear the data, just closes the connection to the database.
+ * @param cache structure
+ */
+KR_EXPORT
+void kr_cache_close(struct kr_cache *cache);
+
+/** Run after a row of operations to release transaction/lock if needed. */
+KR_EXPORT
+int kr_cache_commit(struct kr_cache *cache);
+
+/**
+ * Return true if cache is open and enabled.
+ */
+static inline bool kr_cache_is_open(struct kr_cache *cache)
+{
+ return cache->db != NULL;
+}
+
+/** (Re)set the time pair to the current values. */
+static inline void kr_cache_make_checkpoint(struct kr_cache *cache)
+{
+ cache->checkpoint_monotime = kr_now();
+ gettimeofday(&cache->checkpoint_walltime, NULL);
+}
+
+/**
+ * Insert RRSet into cache, replacing any existing data.
+ * @param cache cache structure
+ * @param rr inserted RRSet
+ * @param rrsig RRSIG for inserted RRSet (optional)
+ * @param rank rank of the data
+ * @param timestamp current time (as-if; if the RR are older, their timestamp is appropriate)
+ * @param ins_nsec_p update NSEC* parameters if applicable
+ * @return 0 or an errcode
+ */
+KR_EXPORT
+int kr_cache_insert_rr(struct kr_cache *cache,
+ const knot_rrset_t *rr, const knot_rrset_t *rrsig,
+ uint8_t rank, uint32_t timestamp, bool ins_nsec_p);
+
+/**
+ * Clear all items from the cache.
+ * @param cache cache structure
+ * @return if nonzero is returned, there's a big problem - you probably want to abort(),
+ * perhaps except for kr_error(EAGAIN) which probably indicates transient errors.
+ */
+KR_EXPORT
+int kr_cache_clear(struct kr_cache *cache);
+
+
+/* ** This interface is temporary. ** */
+
+struct kr_cache_p {
+ uint32_t time; /**< The time of inception. */
+ uint32_t ttl; /**< TTL at inception moment. Assuming it fits into int32_t ATM. */
+ uint8_t rank; /**< See enum kr_rank */
+ struct {
+ /* internal: pointer to eh struct */
+ void *raw_data, *raw_bound;
+ };
+};
+KR_EXPORT
+int kr_cache_peek_exact(struct kr_cache *cache, const knot_dname_t *name, uint16_t type,
+ struct kr_cache_p *peek);
+/* Parameters (qry, name, type) are used for timestamp and stale-serving decisions. */
+KR_EXPORT
+int32_t kr_cache_ttl(const struct kr_cache_p *peek, const struct kr_query *qry,
+ const knot_dname_t *name, uint16_t type);
+
+KR_EXPORT
+int kr_cache_materialize(knot_rdataset_t *dst, const struct kr_cache_p *ref,
+ knot_mm_t *pool);
+
+
+/**
+ * Remove an entry from cache.
+ * @param cache cache structure
+ * @param name dname
+ * @param type rr type
+ * @return number of deleted records, or negative error code
+ * @note only "exact hits" are considered ATM, and
+ * some other information may be removed alongside.
+ */
+KR_EXPORT
+int kr_cache_remove(struct kr_cache *cache, const knot_dname_t *name, uint16_t type);
+
+/**
+ * Get keys matching a dname lf prefix
+ * @param cache cache structure
+ * @param name dname
+ * @param exact_name whether to only consider exact name matches
+ * @param keyval matched key-value pairs
+ * @param maxcount limit on the number of returned key-value pairs
+ * @return result count or an errcode
+ * @note the cache keys are matched by prefix, i.e. it very much depends
+ * on their structure; CACHE_KEY_DEF.
+ */
+KR_EXPORT
+int kr_cache_match(struct kr_cache *cache, const knot_dname_t *name,
+ bool exact_name, knot_db_val_t keyval[][2], int maxcount);
+
+/**
+ * Remove a subtree in cache. It's like _match but removing them instead of returning.
+ * @return number of deleted entries or an errcode
+ */
+KR_EXPORT
+int kr_cache_remove_subtree(struct kr_cache *cache, const knot_dname_t *name,
+ bool exact_name, int maxcount);
+
+/**
+ * Find the closest cached zone apex for a name (in cache).
+ * @param is_DS start searching one name higher
+ * @return the number of labels to remove from the name, or negative error code
+ * @note timestamp is found by a syscall, and stale-serving is not considered
+ */
+KR_EXPORT
+int kr_cache_closest_apex(struct kr_cache *cache, const knot_dname_t *name, bool is_DS,
+ knot_dname_t **apex);
+
+/**
+ * Unpack dname and type from db key
+ * @param key db key representation
+ * @param buf output buffer of domain name in dname format
+ * @param type output for type
+ * @return length of dname or an errcode
+ * @note only "exact hits" are considered ATM, moreover xNAME records
+ * are "hidden" as NS. (see comments in struct entry_h)
+ */
+KR_EXPORT
+int kr_unpack_cache_key(knot_db_val_t key, knot_dname_t *buf, uint16_t *type);
+
+/** Periodic kr_cdb_api::check_health().
+ * @param interval in milliseconds. 0 for one-time check, -1 to stop the checks.
+ * @return see check_health() for one-time check; otherwise normal kr_error() code. */
+KR_EXPORT
+int kr_cache_check_health(struct kr_cache *cache, int interval);
+
diff --git a/lib/cache/cdb_api.h b/lib/cache/cdb_api.h
new file mode 100644
index 0000000..fcca8a9
--- /dev/null
+++ b/lib/cache/cdb_api.h
@@ -0,0 +1,97 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+*/
+
+#pragma once
+
+#include <stdint.h>
+
+#include <libknot/db/db.h>
+
+/* Cache options. */
+struct kr_cdb_opts {
+ const char *path; /*!< Cache URI path. */
+ size_t maxsize; /*!< Suggested cache size in bytes; pass 0 to keep unchanged/default. */
+};
+
+struct kr_cdb_stats {
+ uint64_t open;
+ uint64_t close;
+ uint64_t count;
+ uint64_t count_entries;
+ uint64_t clear;
+ uint64_t commit;
+ uint64_t read;
+ uint64_t read_miss;
+ uint64_t write;
+ uint64_t remove;
+ uint64_t remove_miss;
+ uint64_t match;
+ uint64_t match_miss;
+ uint64_t read_leq;
+ uint64_t read_leq_miss;
+ double usage_percent;
+};
+
+/*! Pointer to a cache structure.
+ *
+ * This struct is opaque and never defined; the purpose is to get better
+ * type safety than with void *.
+ */
+typedef struct kr_cdb *kr_cdb_pt;
+
+/*! Cache database API.
+ * This is a simplified version of generic DB API from libknot,
+ * that is tailored to caching purposes.
+ */
+struct kr_cdb_api {
+ const char *name;
+
+ /* Context operations */
+
+ int (*open)(kr_cdb_pt *db, struct kr_cdb_stats *stat, struct kr_cdb_opts *opts, knot_mm_t *mm);
+ void (*close)(kr_cdb_pt db, struct kr_cdb_stats *stat);
+ int (*count)(kr_cdb_pt db, struct kr_cdb_stats *stat);
+ int (*clear)(kr_cdb_pt db, struct kr_cdb_stats *stat);
+
+ /** Run after a row of operations to release transaction/lock if needed. */
+ int (*commit)(kr_cdb_pt db, struct kr_cdb_stats *stat);
+
+ /* Data access */
+
+ int (*read)(kr_cdb_pt db, struct kr_cdb_stats *stat,
+ const knot_db_val_t *key, knot_db_val_t *val, int maxcount);
+ int (*write)(kr_cdb_pt db, struct kr_cdb_stats *stat, const knot_db_val_t *key,
+ knot_db_val_t *val, int maxcount);
+
+ /** Remove maxcount keys.
+ * \returns the number of successfully removed keys or the first error code
+ * It returns on first error, but ENOENT is not considered an error. */
+ int (*remove)(kr_cdb_pt db, struct kr_cdb_stats *stat,
+ knot_db_val_t keys[], int maxcount);
+
+ /* Specialised operations */
+
+ /** Find key-value pairs that are prefixed by the given key, limited by maxcount.
+ * \return the number of pairs or negative error. */
+ int (*match)(kr_cdb_pt db, struct kr_cdb_stats *stat,
+ knot_db_val_t *key, knot_db_val_t keyval[][2], int maxcount);
+
+ /** Less-or-equal search (lexicographic ordering).
+ * On successful return, key->data and val->data point to DB-owned data.
+ * return: 0 for equality, > 0 for less, < 0 kr_error */
+ int (*read_leq)(kr_cdb_pt db, struct kr_cdb_stats *stat,
+ knot_db_val_t *key, knot_db_val_t *val);
+
+ /** Return estimated space usage (0--100). */
+ double (*usage_percent)(kr_cdb_pt db);
+
+ /** Return the current cache size limit in bytes; could be cached by check_health(). */
+ size_t (*get_maxsize)(kr_cdb_pt db);
+
+ /** Perform maintenance.
+ * In LMDB case it checks whether data.mdb is still the same
+ * and reopens it if it isn't; it errors out if the file doesn't exist anymore.
+ * \return 0 if OK, 1 if reopened OK, < 0 kr_error */
+ int (*check_health)(kr_cdb_pt db, struct kr_cdb_stats *stat);
+};
diff --git a/lib/cache/cdb_lmdb.c b/lib/cache/cdb_lmdb.c
new file mode 100644
index 0000000..80c7372
--- /dev/null
+++ b/lib/cache/cdb_lmdb.c
@@ -0,0 +1,868 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+*/
+
+#include <fcntl.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <lmdb.h>
+
+#include "contrib/cleanup.h"
+#include "contrib/ucw/lib.h"
+#include "lib/cache/cdb_lmdb.h"
+#include "lib/cache/cdb_api.h"
+#include "lib/utils.h"
+
+
+/* Defines */
+#define LMDB_DIR_MODE 0770
+#define LMDB_FILE_MODE 0660
+
+/* TODO: we rely on mirrors of these two structs not changing layout
+ * in libknot and knot resolver! */
+struct lmdb_env
+{
+ size_t mapsize;
+ MDB_dbi dbi;
+ MDB_env *env;
+
+ /** Cached transactions
+ *
+ * - only one of (ro,rw) may be active at once
+ * - non-NULL .ro may be active or reset
+ * - non-NULL .rw is always active
+ */
+ struct {
+ bool ro_active, ro_curs_active;
+ MDB_txn *ro, *rw;
+ MDB_cursor *ro_curs;
+ } txn;
+
+ /* Cached part of struct stat for data.mdb. */
+ dev_t st_dev;
+ ino_t st_ino;
+ off_t st_size;
+ const char *mdb_data_path; /**< path to data.mdb, for convenience */
+};
+
+struct libknot_lmdb_env {
+ bool shared;
+ unsigned dbi;
+ void *env;
+ knot_mm_t *pool;
+};
+
+/** Type-safe conversion helper.
+ *
+ * We keep lmdb_env as a separate type from kr_db_pt, as different implementation of API
+ * would need to define the contents differently.
+ */
+static inline struct lmdb_env * db2env(kr_cdb_pt db)
+{
+ return (struct lmdb_env *)db;
+}
+static inline kr_cdb_pt env2db(struct lmdb_env *env)
+{
+ return (kr_cdb_pt)env;
+}
+
+static int cdb_commit(kr_cdb_pt db, struct kr_cdb_stats *stats);
+
+/** @brief Convert LMDB error code. */
+static int lmdb_error(int error)
+{
+ switch (error) {
+ case MDB_SUCCESS:
+ return kr_ok();
+ case MDB_NOTFOUND:
+ return kr_error(ENOENT);
+ case ENOSPC:
+ case MDB_MAP_FULL:
+ case MDB_TXN_FULL:
+ return kr_error(ENOSPC);
+ default:
+ kr_log_error(CACHE, "LMDB error: %s\n", mdb_strerror(error));
+ return kr_error(error);
+ }
+}
+
+/** Conversion between knot and lmdb structs for values. */
+static inline knot_db_val_t val_mdb2knot(MDB_val v)
+{
+ return (knot_db_val_t){ .len = v.mv_size, .data = v.mv_data };
+}
+static inline MDB_val val_knot2mdb(knot_db_val_t v)
+{
+ return (MDB_val){ .mv_size = v.len, .mv_data = v.data };
+}
+
+/** Refresh mapsize value from file, including env->mapsize.
+ * It's much lighter than reopen_env(). */
+static int refresh_mapsize(struct lmdb_env *env)
+{
+ int ret = cdb_commit(env2db(env), NULL);
+ if (!ret) ret = lmdb_error(mdb_env_set_mapsize(env->env, 0));
+ if (ret) return ret;
+
+ MDB_envinfo info;
+ ret = lmdb_error(mdb_env_info(env->env, &info));
+ if (ret) return ret;
+
+ env->mapsize = info.me_mapsize;
+ if (env->mapsize != env->st_size) {
+ kr_log_info(CACHE, "suspicious size of cache file '%s'"
+ ": file size %zu != LMDB map size %zu\n",
+ env->mdb_data_path, (size_t)env->st_size, env->mapsize);
+ }
+ return kr_ok();
+}
+
+static void clear_stale_readers(struct lmdb_env *env)
+{
+ int cleared;
+ int ret = mdb_reader_check(env->env, &cleared);
+ if (ret != MDB_SUCCESS) {
+ kr_log_error(CACHE, "failed to clear stale reader locks: "
+ "LMDB error %d %s\n", ret, mdb_strerror(ret));
+ } else if (cleared != 0) {
+ kr_log_info(CACHE, "cleared %d stale reader locks\n", cleared);
+ }
+}
+
+#define FLAG_RENEW (2*MDB_RDONLY)
+/** mdb_txn_begin or _renew + handle retries in some situations
+ *
+ * The retrying logic is so ugly that it has its own function.
+ * \note this assumes no transactions are active
+ * \return MDB_ errcode, not usual kr_error(...)
+ */
+static int txn_get_noresize(struct lmdb_env *env, unsigned int flag, MDB_txn **txn)
+{
+ if (kr_fails_assert(!env->txn.rw && (!env->txn.ro || !env->txn.ro_active)))
+ return kr_error(1);
+ int attempts = 0;
+ int ret;
+retry:
+ /* Do a few attempts in case we encounter multiple issues at once. */
+ if (++attempts > 2)
+ return kr_error(1);
+
+ if (flag == FLAG_RENEW) {
+ ret = mdb_txn_renew(*txn);
+ } else {
+ ret = mdb_txn_begin(env->env, NULL, flag, txn);
+ }
+
+ if (unlikely(ret == MDB_MAP_RESIZED)) {
+ kr_log_info(CACHE, "detected size increased by another process\n");
+ ret = refresh_mapsize(env);
+ if (ret == 0)
+ goto retry;
+ } else if (unlikely(ret == MDB_READERS_FULL)) {
+ clear_stale_readers(env);
+ goto retry;
+ }
+ return ret;
+}
+
+/** Obtain a transaction. (they're cached in env->txn) */
+static int txn_get(struct lmdb_env *env, MDB_txn **txn, bool rdonly)
+{
+ if (kr_fails_assert(env && txn))
+ return kr_error(EINVAL);
+ if (env->txn.rw) {
+ /* Reuse the *open* RW txn even if only reading is requested.
+ * We leave the management of this to the cdb_commit command.
+ * The user may e.g. want to do some reads between the writes. */
+ *txn = env->txn.rw;
+ return kr_ok();
+ }
+
+ if (!rdonly) {
+ /* avoid two active transactions */
+ if (env->txn.ro && env->txn.ro_active) {
+ mdb_txn_reset(env->txn.ro);
+ env->txn.ro_active = false;
+ env->txn.ro_curs_active = false;
+ }
+ int ret = txn_get_noresize(env, 0/*RW*/, &env->txn.rw);
+ if (ret == MDB_SUCCESS) {
+ *txn = env->txn.rw;
+ kr_assert(*txn);
+ }
+ return lmdb_error(ret);
+ }
+
+ /* Get an active RO txn and return it. */
+ int ret = MDB_SUCCESS;
+ if (!env->txn.ro) { //:unlikely
+ ret = txn_get_noresize(env, MDB_RDONLY, &env->txn.ro);
+ } else if (!env->txn.ro_active) {
+ ret = txn_get_noresize(env, FLAG_RENEW, &env->txn.ro);
+ }
+ if (ret != MDB_SUCCESS) {
+ return lmdb_error(ret);
+ }
+ env->txn.ro_active = true;
+ *txn = env->txn.ro;
+ kr_assert(*txn);
+ return kr_ok();
+}
+
+static int cdb_commit(kr_cdb_pt db, struct kr_cdb_stats *stats)
+{
+ struct lmdb_env *env = db2env(db);
+ int ret = kr_ok();
+ if (env->txn.rw) {
+ if (stats) stats->commit++;
+ ret = lmdb_error(mdb_txn_commit(env->txn.rw));
+ env->txn.rw = NULL; /* the transaction got freed even in case of errors */
+ } else if (env->txn.ro && env->txn.ro_active) {
+ mdb_txn_reset(env->txn.ro);
+ env->txn.ro_active = false;
+ env->txn.ro_curs_active = false;
+ }
+ return ret;
+}
+
+/** Obtain a read-only cursor (and a read-only transaction). */
+static int txn_curs_get(struct lmdb_env *env, MDB_cursor **curs, struct kr_cdb_stats *stats)
+{
+ if (kr_fails_assert(env && curs))
+ return kr_error(EINVAL);
+ if (env->txn.ro_curs_active)
+ goto success;
+ /* Only in a read-only txn; TODO: it's a bit messy/coupled */
+ if (env->txn.rw) {
+ int ret = cdb_commit(env2db(env), stats);
+ if (ret) return ret;
+ }
+ MDB_txn *txn = NULL;
+ int ret = txn_get(env, &txn, true);
+ if (ret) return ret;
+
+ if (env->txn.ro_curs) {
+ ret = mdb_cursor_renew(txn, env->txn.ro_curs);
+ } else {
+ ret = mdb_cursor_open(txn, env->dbi, &env->txn.ro_curs);
+ }
+ if (ret) return lmdb_error(ret);
+ env->txn.ro_curs_active = true;
+success:
+ kr_assert(env->txn.ro_curs_active && env->txn.ro && env->txn.ro_active
+ && !env->txn.rw);
+ *curs = env->txn.ro_curs;
+ kr_assert(*curs);
+ return kr_ok();
+}
+
+static void txn_free_ro(struct lmdb_env *env)
+{
+ if (env->txn.ro_curs) {
+ mdb_cursor_close(env->txn.ro_curs);
+ env->txn.ro_curs = NULL;
+ }
+ if (env->txn.ro) {
+ mdb_txn_abort(env->txn.ro);
+ env->txn.ro = NULL;
+ }
+}
+
+/** Abort all transactions.
+ *
+ * This is useful after an error happens, as those (always?) require abortion.
+ * It's possible that _reset() would suffice and marking cursor inactive,
+ * but these errors should be rare so let's close them completely. */
+static void txn_abort(struct lmdb_env *env)
+{
+ txn_free_ro(env);
+ if (env->txn.rw) {
+ mdb_txn_abort(env->txn.rw);
+ env->txn.rw = NULL; /* the transaction got freed even in case of errors */
+ }
+}
+
+/*! \brief Close the database. */
+static void cdb_close_env(struct lmdb_env *env, struct kr_cdb_stats *stats)
+{
+ if (kr_fails_assert(env && env->env))
+ return;
+
+ /* Get rid of any transactions. */
+ txn_free_ro(env);
+ cdb_commit(env2db(env), stats);
+
+ mdb_env_sync(env->env, 1);
+ stats->close++;
+ mdb_dbi_close(env->env, env->dbi);
+ mdb_env_close(env->env);
+ free_const(env->mdb_data_path);
+ memset(env, 0, sizeof(*env));
+}
+
+/** We assume that *env is zeroed and we return it zeroed on errors. */
+static int cdb_open_env(struct lmdb_env *env, const char *path, const size_t mapsize,
+ struct kr_cdb_stats *stats)
+{
+ int ret = mkdir(path, LMDB_DIR_MODE);
+ if (ret && errno != EEXIST) return kr_error(errno);
+
+ stats->open++;
+ ret = mdb_env_create(&env->env);
+ if (ret != MDB_SUCCESS) return lmdb_error(ret);
+
+ env->mdb_data_path = kr_absolutize_path(path, "data.mdb");
+ if (!env->mdb_data_path) {
+ ret = ENOMEM;
+ goto error_sys;
+ }
+
+ /* Set map size, rounded to page size. */
+ errno = 0;
+ const long pagesize = sysconf(_SC_PAGESIZE);
+ if (errno) {
+ ret = errno;
+ goto error_sys;
+ }
+
+ const bool size_requested = mapsize;
+ if (size_requested) {
+ env->mapsize = (mapsize / pagesize) * pagesize;
+ ret = mdb_env_set_mapsize(env->env, env->mapsize);
+ if (ret != MDB_SUCCESS) goto error_mdb;
+ }
+
+ /* Cache doesn't require durability, we can be
+ * loose with the requirements as a tradeoff for speed. */
+ const unsigned flags = MDB_WRITEMAP | MDB_MAPASYNC | MDB_NOTLS;
+ ret = mdb_env_open(env->env, path, flags, LMDB_FILE_MODE);
+ if (ret != MDB_SUCCESS) goto error_mdb;
+
+ mdb_filehandle_t fd = -1;
+ ret = mdb_env_get_fd(env->env, &fd);
+ if (ret != MDB_SUCCESS) goto error_mdb;
+
+ struct stat st;
+ if (fstat(fd, &st)) {
+ ret = errno;
+ goto error_sys;
+ }
+ env->st_dev = st.st_dev;
+ env->st_ino = st.st_ino;
+ env->st_size = st.st_size;
+
+ /* Get the real mapsize. Shrinking can be restricted, etc.
+ * Unfortunately this is only reliable when not setting the size explicitly. */
+ if (!size_requested) {
+ ret = refresh_mapsize(env);
+ if (ret) goto error_sys;
+ }
+
+ /* Open the database. */
+ MDB_txn *txn = NULL;
+ ret = mdb_txn_begin(env->env, NULL, 0, &txn);
+ if (ret != MDB_SUCCESS) goto error_mdb;
+
+ ret = mdb_dbi_open(txn, NULL, 0, &env->dbi);
+ if (ret != MDB_SUCCESS) {
+ mdb_txn_abort(txn);
+ goto error_mdb;
+ }
+
+#if !defined(__MACOSX__) && !(defined(__APPLE__) && defined(__MACH__))
+ if (size_requested) {
+ ret = posix_fallocate(fd, 0, MAX(env->mapsize, env->st_size));
+ } else {
+ ret = 0;
+ }
+ if (ret == EINVAL || ret == EOPNOTSUPP) {
+ /* POSIX says this can happen when the feature isn't supported by the FS.
+ * We haven't seen this happen on Linux+glibc but it was reported on
+ * Linux+musl and FreeBSD. */
+ kr_log_info(CACHE, "space pre-allocation failed and ignored; "
+ "your (file)system probably doesn't support it.\n");
+ } else if (ret != 0) {
+ mdb_txn_abort(txn);
+ goto error_sys;
+ }
+#endif
+
+ stats->commit++;
+ ret = mdb_txn_commit(txn);
+ if (ret != MDB_SUCCESS) goto error_mdb;
+
+ /* Stale RO transactions could have been left behind by a cashing process
+ * (e.g. one whose termination lead to spawning the current one).
+ * According to docs they might hold onto some space until we clear them. */
+ clear_stale_readers(env);
+
+ return kr_ok();
+
+error_mdb:
+ ret = lmdb_error(ret);
+error_sys:
+ free_const(env->mdb_data_path);
+ stats->close++;
+ mdb_env_close(env->env);
+ memset(env, 0, sizeof(*env));
+ return kr_error(ret);
+}
+
+static int cdb_init(kr_cdb_pt *db, struct kr_cdb_stats *stats,
+ struct kr_cdb_opts *opts, knot_mm_t *pool)
+{
+ if (!db || !stats || !opts) {
+ return kr_error(EINVAL);
+ }
+
+ /* Open the database. */
+ struct lmdb_env *env = calloc(1, sizeof(*env));
+ if (!env) {
+ return kr_error(ENOMEM);
+ }
+ int ret = cdb_open_env(env, opts->path, opts->maxsize, stats);
+ if (ret != 0) {
+ free(env);
+ return ret;
+ }
+
+ *db = env2db(env);
+ return 0;
+}
+
+static void cdb_deinit(kr_cdb_pt db, struct kr_cdb_stats *stats)
+{
+ cdb_close_env(db2env(db), stats);
+ free(db);
+}
+
+static int cdb_count(kr_cdb_pt db, struct kr_cdb_stats *stats)
+{
+ struct lmdb_env *env = db2env(db);
+ MDB_txn *txn = NULL;
+ int ret = txn_get(env, &txn, true);
+ if (ret != 0) {
+ return ret;
+ }
+
+ MDB_stat stat;
+ stats->count++;
+ ret = mdb_stat(txn, env->dbi, &stat);
+
+ if (ret == MDB_SUCCESS) {
+ return stat.ms_entries;
+ } else {
+ txn_abort(env);
+ return lmdb_error(ret);
+ }
+}
+
+static int reopen_env(struct lmdb_env *env, struct kr_cdb_stats *stats, const size_t mapsize)
+{
+ /* Keep copy as it points to current handle internals. */
+ const char *path;
+ int ret = mdb_env_get_path(env->env, &path);
+ if (ret != MDB_SUCCESS) {
+ return lmdb_error(ret);
+ }
+ auto_free char *path_copy = strdup(path);
+ cdb_close_env(env, stats);
+ return cdb_open_env(env, path_copy, mapsize, stats);
+}
+
+static int cdb_check_health(kr_cdb_pt db, struct kr_cdb_stats *stats)
+{
+ struct lmdb_env *env = db2env(db);
+
+ struct stat st;
+ if (stat(env->mdb_data_path, &st)) {
+ int ret = errno;
+ return kr_error(ret);
+ }
+
+ if (st.st_dev != env->st_dev || st.st_ino != env->st_ino) {
+ kr_log_debug(CACHE, "cache file has been replaced, reopening\n");
+ int ret = reopen_env(env, stats, 0); // we accept mapsize from the new file
+ return ret == 0 ? 1 : ret;
+ }
+
+ /* Cache check through file size works OK without reopening,
+ * contrary to methods based on mdb_env_info(). */
+ if (st.st_size == env->st_size)
+ return kr_ok();
+ kr_log_info(CACHE, "detected size change (by another instance?) of file '%s'"
+ ": file size %zu -> file size %zu\n",
+ env->mdb_data_path, (size_t)env->st_size, (size_t)st.st_size);
+ env->st_size = st.st_size; // avoid retrying in cycle even if we fail
+ return refresh_mapsize(env);
+}
+
+/** Obtain exclusive (advisory) lock by creating a file, returning FD or negative kr_error().
+ * The lock is auto-released by OS in case the process finishes in any way (file remains). */
+static int lockfile_get(const char *path)
+{
+ if (kr_fails_assert(path))
+ return kr_error(EINVAL);
+ const int fd = open(path, O_CREAT|O_RDWR, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP);
+ if (fd < 0)
+ return kr_error(errno);
+
+ struct flock lock_info;
+ memset(&lock_info, 0, sizeof(lock_info));
+ lock_info.l_type = F_WRLCK;
+ lock_info.l_whence = SEEK_SET;
+ lock_info.l_start = 0;
+ lock_info.l_len = 1; // it's OK for locks to extend beyond the end of the file
+ int err;
+ do {
+ err = fcntl(fd, F_SETLK, &lock_info);
+ } while (err == -1 && errno == EINTR);
+ if (err) {
+ close(fd);
+ return kr_error(errno);
+ }
+ return fd;
+}
+
+/** Release and remove lockfile created by lockfile_get(). Return kr_error(). */
+static int lockfile_release(int fd)
+{
+ if (kr_fails_assert(fd > 0)) // fd == 0 is surely a mistake, in our case at least
+ return kr_error(EINVAL);
+ if (close(fd)) {
+ return kr_error(errno);
+ } else {
+ return kr_ok();
+ }
+}
+
+static int cdb_clear(kr_cdb_pt db, struct kr_cdb_stats *stats)
+{
+ struct lmdb_env *env = db2env(db);
+ stats->clear++;
+ /* First try mdb_drop() to clear the DB; this may fail with ENOSPC. */
+ {
+ MDB_txn *txn = NULL;
+ int ret = txn_get(env, &txn, false);
+ if (ret == kr_ok()) {
+ ret = lmdb_error(mdb_drop(txn, env->dbi, 0));
+ if (ret == kr_ok()) {
+ ret = cdb_commit(db, stats);
+ }
+ if (ret == kr_ok()) {
+ return ret;
+ }
+ }
+ kr_log_info(CACHE, "clearing error, falling back\n");
+ }
+ /* Fallback: we'll remove the database files and reopen.
+ * Other instances can continue to use the removed lmdb,
+ * though it's best for them to reopen soon. */
+
+ /* We are about to switch to a different file, so end all txns, to be sure. */
+ txn_free_ro(env);
+ (void) cdb_commit(db, stats);
+
+ const char *path = NULL;
+ int ret = mdb_env_get_path(env->env, &path);
+ if (ret != MDB_SUCCESS) {
+ return lmdb_error(ret);
+ }
+ auto_free char *mdb_lockfile = kr_strcatdup(2, path, "/lock.mdb");
+ auto_free char *lockfile = kr_strcatdup(2, path, "/krcachelock");
+ if (!mdb_lockfile || !lockfile) {
+ return kr_error(ENOMEM);
+ }
+
+ /* Find if we get a lock on lockfile. */
+ const int lockfile_fd = lockfile_get(lockfile);
+ if (lockfile_fd < 0) {
+ kr_log_error(CACHE, "clearing failed to get ./krcachelock (%s); retry later\n",
+ kr_strerror(lockfile_fd));
+ /* As we're out of space (almost certainly - mdb_drop didn't work),
+ * we will retry on the next failing write operation. */
+ return kr_error(EAGAIN);
+ }
+
+ /* We acquired lockfile. Now find whether *.mdb are what we have open now.
+ * If they are not we don't want to remove them; most likely they have been
+ * cleaned by another instance. */
+ ret = cdb_check_health(db, stats);
+ if (ret != 0) {
+ if (ret == 1) // file changed and reopened successfully
+ ret = kr_ok();
+ // else pass some other error
+ } else {
+ kr_log_debug(CACHE, "clear: identical files, unlinking\n");
+ // coverity[toctou]
+ unlink(env->mdb_data_path);
+ unlink(mdb_lockfile);
+ ret = reopen_env(env, stats, env->mapsize);
+ }
+
+ /* Environment updated, release lockfile. */
+ int lrerr = lockfile_release(lockfile_fd);
+ if (lrerr) {
+ kr_log_error(CACHE, "failed to release ./krcachelock: %s\n",
+ kr_strerror(lrerr));
+ }
+ return ret;
+}
+
+static int cdb_readv(kr_cdb_pt db, struct kr_cdb_stats *stats,
+ const knot_db_val_t *key, knot_db_val_t *val, int maxcount)
+{
+ struct lmdb_env *env = db2env(db);
+ MDB_txn *txn = NULL;
+ int ret = txn_get(env, &txn, true);
+ if (ret) {
+ return ret;
+ }
+
+ for (int i = 0; i < maxcount; ++i) {
+ /* Convert key structs */
+ MDB_val _key = val_knot2mdb(key[i]);
+ MDB_val _val = val_knot2mdb(val[i]);
+ stats->read++;
+ ret = mdb_get(txn, env->dbi, &_key, &_val);
+ if (ret != MDB_SUCCESS) {
+ if (ret == MDB_NOTFOUND) {
+ stats->read_miss++;
+ } else {
+ txn_abort(env);
+ }
+ ret = lmdb_error(ret);
+ if (ret == kr_error(ENOSPC)) {
+ /* we're likely to be forced to cache clear anyway */
+ ret = kr_error(ENOENT);
+ }
+ return ret;
+ }
+ /* Update the result. */
+ val[i] = val_mdb2knot(_val);
+ }
+ return kr_ok();
+}
+
+static int cdb_write(struct lmdb_env *env, MDB_txn **txn, const knot_db_val_t *key,
+ knot_db_val_t *val, unsigned flags,
+ struct kr_cdb_stats *stats)
+{
+ /* Convert key structs and write */
+ MDB_val _key = val_knot2mdb(*key);
+ MDB_val _val = val_knot2mdb(*val);
+ stats->write++;
+ int ret = mdb_put(*txn, env->dbi, &_key, &_val, flags);
+
+ /* We don't try to recover from MDB_TXN_FULL. */
+ if (ret != MDB_SUCCESS) {
+ txn_abort(env);
+ return lmdb_error(ret);
+ }
+
+ /* Update the result. */
+ val->data = _val.mv_data;
+ val->len = _val.mv_size;
+ return kr_ok();
+}
+
+static int cdb_writev(kr_cdb_pt db, struct kr_cdb_stats *stats,
+ const knot_db_val_t *key, knot_db_val_t *val, int maxcount)
+{
+ struct lmdb_env *env = db2env(db);
+ MDB_txn *txn = NULL;
+ int ret = txn_get(env, &txn, false);
+
+ for (int i = 0; ret == kr_ok() && i < maxcount; ++i) {
+ /* This is LMDB specific optimisation,
+ * if caller specifies value with NULL data and non-zero length,
+ * LMDB will preallocate the entry for caller and leave write
+ * transaction open, caller is responsible for syncing thus committing transaction.
+ */
+ unsigned mdb_flags = 0;
+ if (val[i].len > 0 && val[i].data == NULL) {
+ mdb_flags |= MDB_RESERVE;
+ }
+ ret = cdb_write(env, &txn, &key[i], &val[i], mdb_flags, stats);
+ }
+
+ return ret;
+}
+
+static int cdb_remove(kr_cdb_pt db, struct kr_cdb_stats *stats,
+ knot_db_val_t keys[], int maxcount)
+{
+ struct lmdb_env *env = db2env(db);
+ MDB_txn *txn = NULL;
+ int ret = txn_get(env, &txn, false);
+ int deleted = 0;
+
+ for (int i = 0; ret == kr_ok() && i < maxcount; ++i) {
+ MDB_val _key = val_knot2mdb(keys[i]);
+ MDB_val val = { 0, NULL };
+ stats->remove++;
+ ret = lmdb_error(mdb_del(txn, env->dbi, &_key, &val));
+ if (ret == kr_ok())
+ deleted++;
+ else if (ret == KNOT_ENOENT) {
+ stats->remove_miss++;
+ ret = kr_ok(); /* skip over non-existing entries */
+ } else {
+ txn_abort(env);
+ break;
+ }
+ }
+
+ return ret < 0 ? ret : deleted;
+}
+
+static int cdb_match(kr_cdb_pt db, struct kr_cdb_stats *stats,
+ knot_db_val_t *key, knot_db_val_t keyval[][2], int maxcount)
+{
+ struct lmdb_env *env = db2env(db);
+ MDB_txn *txn = NULL;
+ int ret = txn_get(env, &txn, true);
+ if (ret != 0) {
+ return ret;
+ }
+
+ /* LATER(optim.): use txn_curs_get() instead, to save resources. */
+ MDB_cursor *cur = NULL;
+ ret = mdb_cursor_open(txn, env->dbi, &cur);
+ if (ret != 0) {
+ txn_abort(env);
+ return lmdb_error(ret);
+ }
+
+ MDB_val cur_key = val_knot2mdb(*key);
+ MDB_val cur_val = { 0, NULL };
+ stats->match++;
+ ret = mdb_cursor_get(cur, &cur_key, &cur_val, MDB_SET_RANGE);
+ if (ret != MDB_SUCCESS) {
+ mdb_cursor_close(cur);
+ if (ret != MDB_NOTFOUND) {
+ txn_abort(env);
+ }
+ return lmdb_error(ret);
+ }
+
+ int results = 0;
+ while (ret == MDB_SUCCESS) {
+ /* Retrieve current key and compare with prefix */
+ if (cur_key.mv_size < key->len || memcmp(cur_key.mv_data, key->data, key->len) != 0) {
+ break;
+ }
+ /* Add to result set */
+ if (results < maxcount) {
+ keyval[results][0] = val_mdb2knot(cur_key);
+ keyval[results][1] = val_mdb2knot(cur_val);
+ ++results;
+ } else {
+ break;
+ }
+ stats->match++;
+ ret = mdb_cursor_get(cur, &cur_key, &cur_val, MDB_NEXT);
+ }
+
+ mdb_cursor_close(cur);
+ if (ret != MDB_SUCCESS && ret != MDB_NOTFOUND) {
+ txn_abort(env);
+ return lmdb_error(ret);
+ } else if (results == 0) {
+ stats->match_miss++;
+ }
+ return results;
+}
+
+
+static int cdb_read_leq(kr_cdb_pt db, struct kr_cdb_stats *stats,
+ knot_db_val_t *key, knot_db_val_t *val)
+{
+ if (kr_fails_assert(db && key && key->data && val))
+ return kr_error(EINVAL);
+ struct lmdb_env *env = db2env(db);
+ MDB_cursor *curs = NULL;
+ int ret = txn_curs_get(env, &curs, stats);
+ if (ret) return ret;
+
+ MDB_val key2_m = val_knot2mdb(*key);
+ MDB_val val2_m = { 0, NULL };
+ stats->read_leq++;
+ ret = mdb_cursor_get(curs, &key2_m, &val2_m, MDB_SET_RANGE);
+ if (ret) goto failure;
+ /* test for equality //:unlikely */
+ if (key2_m.mv_size == key->len
+ && memcmp(key2_m.mv_data, key->data, key->len) == 0) {
+ ret = 0; /* equality */
+ goto success;
+ }
+ stats->read_leq_miss++;
+
+ /* we must be greater than key; do one step to smaller */
+ stats->read_leq++;
+ ret = mdb_cursor_get(curs, &key2_m, &val2_m, MDB_PREV);
+ if (ret) goto failure;
+ ret = 1;
+success:
+ /* finalize the output */
+ *key = val_mdb2knot(key2_m);
+ *val = val_mdb2knot(val2_m);
+ return ret;
+failure:
+ if (ret == MDB_NOTFOUND) {
+ stats->read_leq_miss++;
+ } else {
+ txn_abort(env);
+ }
+ return lmdb_error(ret);
+}
+
+static double cdb_usage_percent(kr_cdb_pt db)
+{
+ knot_db_t *kdb = kr_cdb_pt2knot_db_t(db);
+ const size_t db_size = knot_db_lmdb_get_mapsize(kdb);
+ const size_t db_usage_abs = knot_db_lmdb_get_usage(kdb);
+ const double db_usage = (double)db_usage_abs / db_size * 100.0;
+ free(kdb);
+ return db_usage;
+}
+
+static size_t cdb_get_maxsize(kr_cdb_pt db)
+{
+ return db2env(db)->mapsize;
+}
+
+/** Conversion between knot and lmdb structs. */
+knot_db_t *kr_cdb_pt2knot_db_t(kr_cdb_pt db)
+{
+ /* this is struct lmdb_env as in resolver/cdb_lmdb.c */
+ const struct lmdb_env *kres_db = db2env(db);
+ struct libknot_lmdb_env *libknot_db = malloc(sizeof(*libknot_db));
+ if (libknot_db != NULL) {
+ libknot_db->shared = false;
+ libknot_db->pool = NULL;
+ libknot_db->env = kres_db->env;
+ libknot_db->dbi = kres_db->dbi;
+ }
+ return libknot_db;
+}
+
+const struct kr_cdb_api *kr_cdb_lmdb(void)
+{
+ static const struct kr_cdb_api api = {
+ "lmdb",
+ cdb_init, cdb_deinit, cdb_count, cdb_clear, cdb_commit,
+ cdb_readv, cdb_writev, cdb_remove,
+ cdb_match,
+ cdb_read_leq,
+ cdb_usage_percent,
+ cdb_get_maxsize,
+ cdb_check_health,
+ };
+
+ return &api;
+}
diff --git a/lib/cache/cdb_lmdb.h b/lib/cache/cdb_lmdb.h
new file mode 100644
index 0000000..988fccf
--- /dev/null
+++ b/lib/cache/cdb_lmdb.h
@@ -0,0 +1,16 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+*/
+
+#pragma once
+
+#include "lib/cache/cdb_api.h"
+#include "lib/defines.h"
+
+KR_EXPORT KR_CONST
+const struct kr_cdb_api *kr_cdb_lmdb(void);
+
+/** Create a pointer for knot_db_lmdb_api. You free() it to release it. */
+KR_EXPORT
+knot_db_t *kr_cdb_pt2knot_db_t(kr_cdb_pt db);
+
diff --git a/lib/cache/entry_list.c b/lib/cache/entry_list.c
new file mode 100644
index 0000000..4dced2f
--- /dev/null
+++ b/lib/cache/entry_list.c
@@ -0,0 +1,301 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+/** @file
+ * Implementation of chaining in struct entry_h. Prototypes in ./impl.h
+ */
+
+#include "lib/cache/impl.h"
+#include "lib/utils.h"
+
+
+static int entry_h_len(knot_db_val_t val);
+
+
+void entry_list_memcpy(struct entry_apex *ea, entry_list_t list)
+{
+ if (kr_fails_assert(ea))
+ return;
+ memset(ea, 0, offsetof(struct entry_apex, data));
+ ea->has_ns = list[EL_NS ].len;
+ ea->has_cname = list[EL_CNAME ].len;
+ ea->has_dname = list[EL_DNAME ].len;
+ for (int i = 0; i < ENTRY_APEX_NSECS_CNT; ++i) {
+ ea->nsecs[i] = list[i].len == 0 ? 0 :
+ (list[i].len == 4 ? 1 : 3);
+ }
+ uint8_t *it = ea->data;
+ for (int i = 0; i < EL_LENGTH; ++i) {
+ if (list[i].data) {
+ memcpy(it, list[i].data, list[i].len);
+ /* LATER(optim.): coalesce consecutive writes? */
+ } else {
+ list[i].data = it;
+ }
+ it += to_even(list[i].len);
+ }
+}
+
+int entry_list_parse(const knot_db_val_t val, entry_list_t list)
+{
+ if (kr_fails_assert(val.data && val.len && list))
+ return kr_error(EINVAL);
+ /* Parse the apex itself (nsec parameters). */
+ const struct entry_apex *ea = entry_apex_consistent(val);
+ if (!ea) {
+ return kr_error(EILSEQ);
+ }
+ const uint8_t *it = ea->data,
+ *it_bound = knot_db_val_bound(val);
+ for (int i = 0; i < ENTRY_APEX_NSECS_CNT; ++i) {
+ if (it > it_bound) {
+ return kr_error(EILSEQ);
+ }
+ list[i].data = (void *)it;
+ switch (ea->nsecs[i]) {
+ case 0:
+ list[i].len = 0;
+ break;
+ case 1:
+ list[i].len = sizeof(uint32_t); /* just timestamp */
+ break;
+ case 3: { /* timestamp + NSEC3PARAM wire */
+ if (it + sizeof(uint32_t) + 4 > it_bound) {
+ return kr_error(EILSEQ);
+ }
+ list[i].len = sizeof(uint32_t)
+ + nsec_p_rdlen(it + sizeof(uint32_t));
+ break;
+ }
+ default:
+ return kr_error(EILSEQ);
+ };
+ it += to_even(list[i].len);
+ }
+ /* Parse every entry_h. */
+ for (int i = ENTRY_APEX_NSECS_CNT; i < EL_LENGTH; ++i) {
+ list[i].data = (void *)it;
+ bool has_type;
+ switch (i) {
+ case EL_NS: has_type = ea->has_ns; break;
+ case EL_CNAME: has_type = ea->has_cname; break;
+ case EL_DNAME: has_type = ea->has_dname; break;
+ default:
+ kr_assert(!EINVAL);
+ return kr_error(EINVAL); /* something very bad */
+ }
+ if (!has_type) {
+ list[i].len = 0;
+ continue;
+ }
+ if (kr_fails_assert(it < it_bound))
+ return kr_error(EILSEQ);
+ const int len = entry_h_len(
+ (knot_db_val_t){ .data = (void *)it, .len = it_bound - it });
+ if (kr_fails_assert(len >= 0))
+ return kr_error(len);
+ list[i].len = len;
+ it += to_even(len);
+ }
+ if (kr_fails_assert(it == it_bound)) /* better not use it; might be "damaged" */
+ return kr_error(EILSEQ);
+ return kr_ok();
+}
+
+/** Given a valid entry header, find its length (i.e. offset of the next entry).
+ * \param val The beginning of the data and the bound (read only).
+ */
+static int entry_h_len(const knot_db_val_t val)
+{
+ const bool ok = val.data && ((ssize_t)val.len) > 0;
+ if (!ok) return kr_error(EINVAL);
+ const struct entry_h *eh = val.data;
+ const uint8_t *d = eh->data; /* iterates over the data in entry */
+ const uint8_t *data_bound = knot_db_val_bound(val);
+ if (d >= data_bound) return kr_error(EILSEQ);
+ if (!eh->is_packet) { /* Positive RRset + its RRsig set (may be empty). */
+ int sets = 2;
+ while (sets-- > 0) {
+ d += KR_CACHE_RR_COUNT_SIZE + rdataset_dematerialized_size(d, NULL);
+ if (kr_fails_assert(d <= data_bound))
+ return kr_error(EILSEQ);
+ }
+ } else { /* A "packet" (opaque ATM). */
+ uint16_t len;
+ if (d + sizeof(len) > data_bound) return kr_error(EILSEQ);
+ memcpy(&len, d, sizeof(len));
+ d += 2 + to_even(len);
+ }
+ if (kr_fails_assert(d <= data_bound))
+ return kr_error(EILSEQ);
+ return d - (uint8_t *)val.data;
+}
+
+struct entry_apex * entry_apex_consistent(knot_db_val_t val)
+{
+ //XXX: check lengths, etc.
+ return val.data;
+}
+
+/* See the header file. */
+int entry_h_seek(knot_db_val_t *val, uint16_t type)
+{
+ int i = -1;
+ switch (type) {
+ case KNOT_RRTYPE_NS: i = EL_NS; break;
+ case KNOT_RRTYPE_CNAME: i = EL_CNAME; break;
+ case KNOT_RRTYPE_DNAME: i = EL_DNAME; break;
+ default: return kr_ok();
+ }
+
+ entry_list_t el;
+ int ret = entry_list_parse(*val, el);
+ if (ret) return ret;
+ *val = el[i];
+ return val->len ? kr_ok() : kr_error(ENOENT);
+}
+
+static int cache_write_or_clear(struct kr_cache *cache, const knot_db_val_t *key,
+ knot_db_val_t *val, const struct kr_query *qry)
+{
+ static uint64_t ignoring_errors_until = 0; /// zero or a timestamp
+ int ret = cache_op(cache, write, key, val, 1);
+ if (!ret) {
+ ignoring_errors_until = 0;
+ return kr_ok();
+ }
+ VERBOSE_MSG(qry, "=> failed backend write, ret = %d\n", ret);
+
+ if (ret == kr_error(ENOSPC) && cache->api->usage_percent(cache->db) > 90) {
+ // Cache seems overfull. Maybe kres-cache-gc service doesn't work.
+ goto recovery;
+ }
+
+ /* If we get ENOSPC with usage < 90% (especially just above 80% when GC fires),
+ * it most likely isn't real overfull state but some LMDB bug related
+ * to transactions. Upstream seems unlikely to address it:
+ https://lists.openldap.org/hyperkitty/list/openldap-technical@openldap.org/thread/QHOTE2Y3WZ6E7J27OOKI44P344ETUOSF/
+ *
+ * In real life we see all processes getting a LMDB failure
+ * but it should recover after the transactions get reopened.
+ *
+ * Fortunately the kresd cache can afford to be slightly lossy,
+ * so we ignore this and other errors for a short while.
+ */
+ const uint64_t now = kr_now();
+ if (!ignoring_errors_until) { // First error after a success.
+ kr_log_info(CACHE, "LMDB refusing writes (ignored for 5-9s): %s\n",
+ kr_strerror(ret));
+ ignoring_errors_until = now + 5000 + kr_rand_bytes(2)/16;
+ return kr_error(ret);
+ }
+ if (now < ignoring_errors_until)
+ return kr_error(ret);
+ // We've lost patience with cache writes not working continuously.
+
+recovery: // Try to recover by clearing cache.
+ ret = kr_cache_clear(cache);
+ switch (ret) {
+ default:
+ kr_log_crit(CACHE, "CRITICAL: clearing cache failed: %s; fatal error, aborting\n",
+ kr_strerror(ret));
+ abort();
+ case 0:
+ kr_log_info(CACHE, "stuck cache cleared\n");
+ ignoring_errors_until = 0;
+ case -EAGAIN: // fall-through; krcachelock race -> retry later
+ return kr_error(ENOSPC);
+ }
+}
+
+
+/* See the header file. */
+int entry_h_splice(
+ knot_db_val_t *val_new_entry, uint8_t rank,
+ const knot_db_val_t key, const uint16_t ktype, const uint16_t type,
+ const knot_dname_t *owner/*log only*/,
+ const struct kr_query *qry, struct kr_cache *cache, uint32_t timestamp)
+{
+ //TODO: another review, perhaps including the API
+ if (kr_fails_assert(val_new_entry && val_new_entry->len > 0))
+ return kr_error(EINVAL);
+
+ int i_type;
+ switch (type) {
+ case KNOT_RRTYPE_NS: i_type = EL_NS; break;
+ case KNOT_RRTYPE_CNAME: i_type = EL_CNAME; break;
+ case KNOT_RRTYPE_DNAME: i_type = EL_DNAME; break;
+ default: i_type = 0;
+ }
+
+ /* Get eh_orig (original entry), and also el list if multi-entry case. */
+ const struct entry_h *eh_orig = NULL;
+ entry_list_t el;
+ int ret = -1;
+ if (!kr_rank_test(rank, KR_RANK_SECURE) || ktype == KNOT_RRTYPE_NS) {
+ knot_db_val_t val;
+ ret = cache_op(cache, read, &key, &val, 1);
+ if (i_type) {
+ if (!ret) ret = entry_list_parse(val, el);
+ if (ret) memset(el, 0, sizeof(el));
+ val = el[i_type];
+ }
+ /* val is on the entry, in either case (or error) */
+ if (!ret) {
+ eh_orig = entry_h_consistent_E(val, type);
+ }
+ } else {
+ /* We want to fully overwrite the entry, so don't even read it. */
+ memset(el, 0, sizeof(el));
+ }
+
+ if (!kr_rank_test(rank, KR_RANK_SECURE) && eh_orig) {
+ /* If equal rank was accepted, spoofing a *single* answer would be
+ * enough to e.g. override NS record in AUTHORITY section.
+ * This way they would have to hit the first answer
+ * (whenever TTL nears expiration).
+ * Stale-serving is NOT considered, but TTL 1 would be considered
+ * as expiring anyway, ... */
+ int32_t old_ttl = get_new_ttl(eh_orig, qry, NULL, 0, timestamp);
+ if (old_ttl > 0 && !is_expiring(eh_orig->ttl, old_ttl)
+ && rank <= eh_orig->rank) {
+ WITH_VERBOSE(qry) {
+ auto_free char *type_str = kr_rrtype_text(type),
+ *owner_str = kr_dname_text(owner);
+ VERBOSE_MSG(qry, "=> not overwriting %s %s\n",
+ type_str, owner_str);
+ }
+ return kr_error(EEXIST);
+ }
+ }
+
+ if (!i_type) {
+ /* The non-list types are trivial now. */
+ return cache_write_or_clear(cache, &key, val_new_entry, qry);
+ }
+ /* Now we're in trouble. In some cases, parts of data to be written
+ * is an lmdb entry that may be invalidated by our write request.
+ * (lmdb does even in-place updates!) Therefore we copy all into a buffer.
+ * LATER(optim.): do this only when necessary, or perhaps another approach.
+ * This is also complicated by the fact that the val_new_entry part
+ * is to be written *afterwards* by the caller.
+ */
+ el[i_type] = (knot_db_val_t){
+ .len = val_new_entry->len,
+ .data = NULL, /* perhaps unclear in the entry_h_splice() API */
+ };
+ knot_db_val_t val = {
+ .len = entry_list_serial_size(el),
+ .data = NULL,
+ };
+ uint8_t buf[val.len];
+ entry_list_memcpy((struct entry_apex *)buf, el);
+ ret = cache_write_or_clear(cache, &key, &val, qry);
+ if (ret) return kr_error(ret);
+ memcpy(val.data, buf, val.len); /* we also copy the "empty" space, but well... */
+ val_new_entry->data = (uint8_t *)val.data
+ + ((uint8_t *)el[i_type].data - buf);
+ return kr_ok();
+}
+
diff --git a/lib/cache/entry_pkt.c b/lib/cache/entry_pkt.c
new file mode 100644
index 0000000..884bfaa
--- /dev/null
+++ b/lib/cache/entry_pkt.c
@@ -0,0 +1,206 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+/** @file
+ * Implementation of packet-caching. Prototypes in ./impl.h
+ *
+ * The packet is stashed in entry_h::data as uint16_t length + full packet wire format.
+ */
+
+#include "lib/utils.h"
+#include "lib/layer/iterate.h" /* kr_response_classify */
+#include "lib/cache/impl.h"
+
+
+/** Compute TTL for a packet. It's minimum TTL or zero. (You can apply limits.) */
+KR_EXPORT
+uint32_t packet_ttl(const knot_pkt_t *pkt)
+{
+ bool has_ttl = false;
+ uint32_t ttl = TTL_MAX_MAX;
+ for (knot_section_t i = KNOT_ANSWER; i <= KNOT_ADDITIONAL; ++i) {
+ const knot_pktsection_t *sec = knot_pkt_section(pkt, i);
+ for (unsigned k = 0; k < sec->count; ++k) {
+ const knot_rrset_t *rr = knot_pkt_rr(sec, k);
+ ttl = MIN(ttl, rr->ttl);
+ has_ttl = true;
+ }
+ }
+ return has_ttl ? ttl : 0;
+}
+
+
+void stash_pkt(const knot_pkt_t *pkt, const struct kr_query *qry,
+ const struct kr_request *req, const bool needs_pkt)
+{
+ /* In some cases, stash also the packet. */
+ const bool is_negative = kr_response_classify(pkt)
+ & (PKT_NODATA|PKT_NXDOMAIN);
+ const struct kr_qflags * const qf = &qry->flags;
+ const bool want_negative = qf->DNSSEC_INSECURE || !qf->DNSSEC_WANT;
+ const bool want_pkt = qf->DNSSEC_BOGUS /*< useful for +cd answers */
+ || (is_negative && want_negative) || needs_pkt;
+
+ if (!want_pkt || !knot_wire_get_aa(pkt->wire)
+ || pkt->parsed != pkt->size /*< malformed packet; still can't detect KNOT_EFEWDATA */
+ ) {
+ return;
+ }
+
+ /* Compute rank. If cd bit is set or we got answer via non-validated
+ * forwarding, make the rank bad; otherwise it depends on flags.
+ * TODO: probably make validator attempt validation even with +cd. */
+ uint8_t rank = KR_RANK_AUTH;
+ const bool risky_vldr = is_negative && qf->FORWARD && qf->CNAME;
+ /* ^^ CNAME'ed NXDOMAIN answer in forwarding mode can contain
+ * unvalidated records; original commit: d6e22f476. */
+ if (knot_wire_get_cd(req->qsource.packet->wire) || qf->STUB || risky_vldr) {
+ kr_rank_set(&rank, KR_RANK_OMIT);
+ } else {
+ if (qf->DNSSEC_BOGUS) {
+ kr_rank_set(&rank, KR_RANK_BOGUS);
+ } else if (qf->DNSSEC_INSECURE) {
+ kr_rank_set(&rank, KR_RANK_INSECURE);
+ } else if (!qf->DNSSEC_WANT) {
+ /* no TAs at all, leave _RANK_AUTH */
+ } else if (needs_pkt) {
+ /* All bad cases should be filtered above,
+ * at least the same way as pktcache in kresd 1.5.x. */
+ kr_rank_set(&rank, KR_RANK_SECURE);
+ } else kr_assert(false);
+ }
+
+ const uint16_t pkt_type = knot_pkt_qtype(pkt);
+ const knot_dname_t *owner = knot_pkt_qname(pkt); /* qname can't be compressed */
+
+ // LATER: nothing exists under NXDOMAIN. Implement that (optionally)?
+#if 0
+ if (knot_wire_get_rcode(pkt->wire) == KNOT_RCODE_NXDOMAIN
+ /* && !qf->DNSSEC_INSECURE */ ) {
+ pkt_type = KNOT_RRTYPE_NS;
+ }
+#endif
+
+ /* Construct the key under which the pkt will be stored. */
+ struct key k_storage, *k = &k_storage;
+ knot_db_val_t key;
+ int ret = kr_dname_lf(k->buf, owner, false);
+ if (ret) {
+ /* A server might (incorrectly) reply with QDCOUNT=0. */
+ kr_assert(owner == NULL);
+ return;
+ }
+ key = key_exact_type_maypkt(k, pkt_type);
+
+ /* For now we stash the full packet byte-exactly as it came from upstream. */
+ const uint16_t pkt_size = pkt->size;
+ knot_db_val_t val_new_entry = {
+ .data = NULL,
+ .len = offsetof(struct entry_h, data) + sizeof(pkt_size) + pkt->size,
+ };
+ /* Prepare raw memory for the new entry and fill it. */
+ struct kr_cache *cache = &req->ctx->cache;
+ ret = entry_h_splice(&val_new_entry, rank, key, k->type, pkt_type,
+ owner, qry, cache, qry->timestamp.tv_sec);
+ if (ret || kr_fails_assert(val_new_entry.data)) return; /* some aren't really errors */
+ struct entry_h *eh = val_new_entry.data;
+ memset(eh, 0, offsetof(struct entry_h, data));
+ eh->time = qry->timestamp.tv_sec;
+ eh->ttl = MAX(MIN(packet_ttl(pkt), cache->ttl_max), cache->ttl_min);
+ eh->rank = rank;
+ eh->is_packet = true;
+ eh->has_optout = qf->DNSSEC_OPTOUT;
+ memcpy(eh->data, &pkt_size, sizeof(pkt_size));
+ memcpy(eh->data + sizeof(pkt_size), pkt->wire, pkt_size);
+
+ WITH_VERBOSE(qry) {
+ auto_free char *type_str = kr_rrtype_text(pkt_type),
+ *owner_str = kr_dname_text(owner);
+ VERBOSE_MSG(qry, "=> stashed packet: rank 0%.2o, TTL %d, "
+ "%s %s (%d B)\n",
+ eh->rank, eh->ttl,
+ type_str, owner_str, (int)val_new_entry.len);
+ }
+}
+
+
+int answer_from_pkt(kr_layer_t *ctx, knot_pkt_t *pkt, uint16_t type,
+ const struct entry_h *eh, const void *eh_bound, uint32_t new_ttl)
+{
+ struct kr_request *req = ctx->req;
+ struct kr_query *qry = req->current_query;
+
+ const uint16_t msgid = knot_wire_get_id(pkt->wire);
+
+ /* Ensure the wire buffer is large enough. Strategy: fit and at least double. */
+ uint16_t pkt_len;
+ memcpy(&pkt_len, eh->data, sizeof(pkt_len));
+ if (pkt_len > pkt->max_size) {
+ pkt->max_size = MIN(KNOT_WIRE_MAX_PKTSIZE,
+ MAX(pkt->max_size * 2, pkt_len));
+ mm_free(&ctx->req->pool, pkt->wire); /* no-op, but... */
+ pkt->wire = mm_alloc(&ctx->req->pool, pkt->max_size);
+ pkt->compr.wire = pkt->wire;
+ /* TODO: ^^ nicer way how to replace knot_pkt_t::wire ? */
+ }
+ kr_require(pkt->max_size >= pkt_len);
+
+ /* Copy answer and reparse it, but keep the original message id. */
+ knot_pkt_clear(pkt);
+ memcpy(pkt->wire, eh->data + 2, pkt_len);
+ pkt->size = pkt_len;
+ int ret = knot_pkt_parse(pkt, 0);
+ if (ret == KNOT_EFEWDATA || ret == KNOT_EMALF) {
+ return kr_error(ENOENT);
+ /* LATER(opt): try harder to avoid stashing such packets */
+ }
+ if (kr_fails_assert(ret == KNOT_EOK))
+ return kr_error(ret);
+ knot_wire_set_id(pkt->wire, msgid);
+
+ /* Add rank into the additional field. */
+ for (size_t i = 0; i < pkt->rrset_count; ++i) {
+ kr_assert(!pkt->rr[i].additional);
+ uint8_t *rr_rank = mm_alloc(&pkt->mm, sizeof(*rr_rank));
+ if (!rr_rank) {
+ return kr_error(ENOMEM);
+ }
+ *rr_rank = eh->rank;
+ pkt->rr[i].additional = rr_rank;
+ }
+
+ /* Adjust TTL in each record. */
+ const uint32_t drift = eh->ttl - new_ttl;
+ for (knot_section_t i = KNOT_ANSWER; i <= KNOT_ADDITIONAL; ++i) {
+ const knot_pktsection_t *sec = knot_pkt_section(pkt, i);
+ for (unsigned k = 0; k < sec->count; ++k) {
+ knot_rrset_t *rrs = // vv FIXME??
+ /*const-cast*/(knot_rrset_t *)knot_pkt_rr(sec, k);
+ /* We need to be careful: due to enforcing minimum TTL
+ * on packet, some records may be below that value.
+ * We keep those records at TTL 0. */
+ if (rrs->ttl >= drift) {
+ rrs->ttl -= drift;
+ } else {
+ rrs->ttl = 0;
+ }
+ }
+ }
+
+ /* Finishing touches. TODO: perhaps factor out */
+ struct kr_qflags * const qf = &qry->flags;
+ qf->EXPIRING = is_expiring(eh->ttl, new_ttl);
+ qf->CACHED = true;
+ qf->NO_MINIMIZE = true;
+ qf->DNSSEC_INSECURE = kr_rank_test(eh->rank, KR_RANK_INSECURE);
+ qf->DNSSEC_BOGUS = kr_rank_test(eh->rank, KR_RANK_BOGUS);
+ if (qf->DNSSEC_INSECURE || qf->DNSSEC_BOGUS) {
+ qf->DNSSEC_WANT = false;
+ }
+ qf->DNSSEC_OPTOUT = eh->has_optout;
+ VERBOSE_MSG(qry, "=> satisfied by exact packet: rank 0%.2o, new TTL %d\n",
+ eh->rank, new_ttl);
+ return kr_ok();
+}
+
diff --git a/lib/cache/entry_rr.c b/lib/cache/entry_rr.c
new file mode 100644
index 0000000..3239e7e
--- /dev/null
+++ b/lib/cache/entry_rr.c
@@ -0,0 +1,115 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+/** @file
+ * Implementation of RRset (de)materialization, i.e. (de)serialization to storage
+ * format used in cache (some repeated fields are omitted). Prototypes in ./impl.h
+ */
+
+#include "lib/cache/impl.h"
+
+void rdataset_dematerialize(const knot_rdataset_t *rds, uint8_t * restrict data)
+{
+ /* FIXME: either give up on even alignment and thus direct usability
+ * of rdatasets as they are in lmdb, or align inside cdb_* functions
+ * (request sizes one byte longer and shift iff on an odd address). */
+ //if ((size_t)data & 1) VERBOSE_MSG(NULL, "dematerialize: odd address\n");
+ //const uint8_t *data0 = data;
+ kr_require(data);
+ const uint16_t rr_count = rds ? rds->count : 0;
+ memcpy(data, &rr_count, sizeof(rr_count));
+ data += sizeof(rr_count);
+ if (rr_count) {
+ memcpy(data, rds->rdata, rds->size);
+ data += rds->size;
+ }
+ //VERBOSE_MSG(NULL, "dematerialized to %d B\n", (int)(data - data0));
+ (void)data; // silence analyzers
+}
+
+/** Materialize a knot_rdataset_t from cache with given TTL.
+ * Return the number of bytes consumed or an error code.
+ */
+static int rdataset_materialize(knot_rdataset_t * restrict rds, const uint8_t * const data,
+ const uint8_t *data_bound, knot_mm_t *pool)
+{
+ if (kr_fails_assert(rds && data && data_bound && data_bound > data && !rds->rdata
+ /*&& !((size_t)data & 1)*/))
+ return kr_error(EINVAL);
+ kr_assert(pool); /* not required, but that's our current usage; guard leaks */
+ const uint8_t *d = data; /* iterates over the cache data */
+ /* First sum up the sizes for wire format length. */
+ /* TODO: we might overrun here already, but we need to trust cache anyway...*/
+ rds->size = rdataset_dematerialized_size(d, &rds->count);
+ d += KR_CACHE_RR_COUNT_SIZE;
+ if (d + rds->size > data_bound) {
+ VERBOSE_MSG(NULL, "materialize: EILSEQ!\n");
+ return kr_error(EILSEQ);
+ }
+ if (!rds->count) { /* avoid mm_alloc(pool, 0); etc. */
+ rds->rdata = NULL;
+ return d - data;
+ }
+ rds->rdata = mm_alloc(pool, rds->size);
+ if (!rds->rdata) {
+ return kr_error(ENOMEM);
+ }
+ memcpy(rds->rdata, d, rds->size);
+ d += rds->size;
+ //VERBOSE_MSG(NULL, "materialized from %d B\n", (int)(d - data));
+ return d - data;
+}
+
+int kr_cache_materialize(knot_rdataset_t *dst, const struct kr_cache_p *ref,
+ knot_mm_t *pool)
+{
+ struct entry_h *eh = ref->raw_data;
+ return rdataset_materialize(dst, eh->data, ref->raw_bound, pool);
+}
+
+
+int entry2answer(struct answer *ans, int id,
+ const struct entry_h *eh, const uint8_t *eh_bound,
+ const knot_dname_t *owner, uint16_t type, uint32_t new_ttl)
+{
+ /* We assume it's zeroed. Do basic sanity check. */
+ const bool not_ok = ans->rrsets[id].set.rr || ans->rrsets[id].sig_rds.rdata
+ || (type == KNOT_RRTYPE_NSEC && ans->nsec_p.raw)
+ || (type == KNOT_RRTYPE_NSEC3 && !ans->nsec_p.raw);
+ if (kr_fails_assert(!not_ok))
+ return kr_error(EINVAL);
+ /* Materialize the base RRset. */
+ knot_rrset_t *rr = ans->rrsets[id].set.rr
+ = knot_rrset_new(owner, type, KNOT_CLASS_IN, new_ttl, ans->mm);
+ if (kr_fails_assert(rr))
+ return kr_error(ENOMEM);
+ int ret = rdataset_materialize(&rr->rrs, eh->data, eh_bound, ans->mm);
+ if (kr_fails_assert(ret >= 0)) goto fail;
+ size_t data_off = ret;
+ ans->rrsets[id].set.rank = eh->rank;
+ ans->rrsets[id].set.expiring = is_expiring(eh->ttl, new_ttl);
+ /* Materialize the RRSIG RRset for the answer in (pseudo-)packet. */
+ bool want_rrsigs = true; /* LATER(optim.): might be omitted in some cases. */
+ if (want_rrsigs) {
+ ret = rdataset_materialize(&ans->rrsets[id].sig_rds, eh->data + data_off,
+ eh_bound, ans->mm);
+ if (kr_fails_assert(ret >= 0)) goto fail;
+ /* Sanity check: we consumed exactly all data. */
+ int unused_bytes = eh_bound - (uint8_t *)eh->data - data_off - ret;
+ if (kr_fails_assert(unused_bytes == 0)) {
+ kr_log_error(CACHE, "entry2answer ERROR: unused bytes: %d\n",
+ unused_bytes);
+ ret = kr_error(EILSEQ);
+ goto fail; /* to be on the safe side */
+ }
+ }
+ return kr_ok();
+fail:
+ /* Cleanup the item that we might've (partially) written to. */
+ knot_rrset_free(ans->rrsets[id].set.rr, ans->mm);
+ knot_rdataset_clear(&ans->rrsets[id].sig_rds, ans->mm);
+ memset(&ans->rrsets[id], 0, sizeof(ans->rrsets[id]));
+ return kr_error(ret);
+}
+
diff --git a/lib/cache/impl.h b/lib/cache/impl.h
new file mode 100644
index 0000000..305f36e
--- /dev/null
+++ b/lib/cache/impl.h
@@ -0,0 +1,439 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+/** @file
+ * Header internal for cache implementation(s).
+ * Only LMDB works for now.
+ */
+#pragma once
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#include <libdnssec/error.h>
+#include <libdnssec/nsec.h>
+#include <libknot/consts.h>
+#include <libknot/db/db.h>
+#include <libknot/dname.h>
+
+#include "contrib/cleanup.h"
+#include "contrib/murmurhash3/murmurhash3.h" /* hash() for nsec_p_hash() */
+#include "lib/cache/cdb_api.h"
+#include "lib/resolve.h"
+
+/* Cache entry values - binary layout.
+ *
+ * It depends on type which is recognizable by the key.
+ * Code depending on the contents of the key is marked by CACHE_KEY_DEF.
+ *
+ * 'E' entry (exact hit):
+ * - ktype == NS: struct entry_apex - multiple types inside (NS and xNAME);
+ * - ktype != NS: struct entry_h
+ * * is_packet: uint16_t length, the rest is opaque and handled by ./entry_pkt.c
+ * * otherwise RRset + its RRSIG set (possibly empty).
+ * '1' or '3' entry (NSEC or NSEC3)
+ * - struct entry_h, contents is the same as for exact hit
+ * - flags don't make sense there
+ */
+
+struct entry_h {
+ uint32_t time; /**< The time of inception. */
+ uint32_t ttl; /**< TTL at inception moment. Assuming it fits into int32_t ATM. */
+ uint8_t rank : 6; /**< See enum kr_rank */
+ bool is_packet : 1; /**< Negative-answer packet for insecure/bogus name. */
+ bool has_optout : 1; /**< Only for packets; persisted DNSSEC_OPTOUT. */
+ uint8_t _pad; /**< We need even alignment for data now. */
+ uint8_t data[];
+/* Well, we don't really need packing or alignment changes,
+ * but due to LMDB the whole structure may not be stored at an aligned address,
+ * and we need compilers (for non-x86) to know it to avoid SIGBUS (test: UBSAN). */
+} __attribute__ ((packed,aligned(1)));
+struct entry_apex;
+
+/** Check basic consistency of entry_h for 'E' entries, not looking into ->data.
+ * (for is_packet the length of data is checked)
+ */
+KR_EXPORT
+struct entry_h * entry_h_consistent_E(knot_db_val_t data, uint16_t type);
+
+struct entry_apex * entry_apex_consistent(knot_db_val_t val);
+
+/** Consistency check, ATM common for NSEC and NSEC3. */
+static inline struct entry_h * entry_h_consistent_NSEC(knot_db_val_t data)
+{
+ /* ATM it's enough to just extend the checks for exact entries. */
+ const struct entry_h *eh = entry_h_consistent_E(data, KNOT_RRTYPE_NSEC);
+ bool ok = eh != NULL;
+ ok = ok && !eh->is_packet && !eh->has_optout;
+ return ok ? /*const-cast*/(struct entry_h *)eh : NULL;
+}
+
+static inline struct entry_h * entry_h_consistent(knot_db_val_t data, uint16_t type)
+{
+ switch (type) {
+ case KNOT_RRTYPE_NSEC:
+ case KNOT_RRTYPE_NSEC3:
+ return entry_h_consistent_NSEC(data);
+ default:
+ return entry_h_consistent_E(data, type);
+ }
+}
+
+/* nsec_p* - NSEC* chain parameters */
+
+static inline int nsec_p_rdlen(const uint8_t *rdata)
+{
+ //TODO: do we really need the zero case?
+ return rdata ? 5 + rdata[4] : 0; /* rfc5155 4.2 and 3.2. */
+}
+static const int NSEC_P_MAXLEN = sizeof(uint32_t) + 5 + 255; // TODO: remove??
+
+/** Hash of NSEC3 parameters, used as a tag to separate different chains for same zone. */
+typedef uint32_t nsec_p_hash_t;
+static inline nsec_p_hash_t nsec_p_mkHash(const uint8_t *nsec_p)
+{
+ kr_require(nsec_p && !(KNOT_NSEC3_FLAG_OPT_OUT & nsec_p[1]));
+ return hash((const char *)nsec_p, nsec_p_rdlen(nsec_p));
+}
+
+/** NSEC* parameters for the chain. */
+struct nsec_p {
+ const uint8_t *raw; /**< Pointer to raw NSEC3 parameters; NULL for NSEC. */
+ nsec_p_hash_t hash; /**< Hash of `raw`, used for cache keys. */
+ dnssec_nsec3_params_t libknot; /**< Format for libknot; owns malloced memory! */
+};
+
+
+
+/** LATER(optim.): this is overshot, but struct key usage should be cheap ATM. */
+#define KR_CACHE_KEY_MAXLEN (KNOT_DNAME_MAXLEN + 100) /* CACHE_KEY_DEF */
+
+struct key {
+ const knot_dname_t *zname; /**< current zone name (points within qry->sname) */
+ uint8_t zlf_len; /**< length of current zone's lookup format */
+
+ /** Corresponding key type; e.g. NS for CNAME.
+ * Note: NSEC type is ambiguous (exact and range key). */
+ uint16_t type;
+ /** The key data start at buf+1, and buf[0] contains some length.
+ * For details see key_exact* and key_NSEC* functions. */
+ uint8_t buf[KR_CACHE_KEY_MAXLEN];
+ /* LATER(opt.): ^^ probably change the anchoring, so that kr_dname_lf()
+ * doesn't need to move data after knot_dname_lf(). */
+};
+
+static inline size_t key_nwz_off(const struct key *k)
+{
+ /* CACHE_KEY_DEF: zone name lf + 0 ('1' or '3').
+ * NSEC '1' case continues just with the name within zone. */
+ return k->zlf_len + 2;
+}
+static inline size_t key_nsec3_hash_off(const struct key *k)
+{
+ /* CACHE_KEY_DEF NSEC3: tag (nsec_p_hash_t) + 20 bytes NSEC3 name hash) */
+ return key_nwz_off(k) + sizeof(nsec_p_hash_t);
+}
+/** Hash is always SHA1; I see no plans to standardize anything else.
+ * https://www.iana.org/assignments/dnssec-nsec3-parameters/dnssec-nsec3-parameters.xhtml#dnssec-nsec3-parameters-3
+ */
+static const int NSEC3_HASH_LEN = 20,
+ NSEC3_HASH_TXT_LEN = 32;
+
+/** Finish constructing string key for for exact search.
+ * It's assumed that kr_dname_lf(k->buf, owner, *) had been ran.
+ */
+knot_db_val_t key_exact_type_maypkt(struct key *k, uint16_t type);
+
+/** Like key_exact_type_maypkt but with extra checks if used for RRs only. */
+static inline knot_db_val_t key_exact_type(struct key *k, uint16_t type)
+{
+ switch (type) {
+ /* Sanity check: forbidden types represented in other way(s). */
+ case KNOT_RRTYPE_NSEC:
+ case KNOT_RRTYPE_NSEC3:
+ kr_assert(false);
+ return (knot_db_val_t){ NULL, 0 };
+ }
+ return key_exact_type_maypkt(k, type);
+}
+
+
+/* entry_h chaining; implementation in ./entry_list.c */
+
+enum { ENTRY_APEX_NSECS_CNT = 2 };
+
+/** Header of 'E' entry with ktype == NS. Inside is private to ./entry_list.c
+ *
+ * We store xNAME at NS type to lower the number of searches in closest_NS().
+ * CNAME is only considered for equal name, of course.
+ * We also store NSEC* parameters at NS type.
+ */
+struct entry_apex {
+ /* ENTRY_H_FLAGS */
+ bool has_ns : 1;
+ bool has_cname : 1;
+ bool has_dname : 1;
+
+ uint8_t pad_; /**< 1 byte + 2 bytes + x bytes would be weird; let's do 2+2+x. */
+
+ /** We have two slots for NSEC* parameters.
+ *
+ * This array describes how they're filled;
+ * values: 0: none, 1: NSEC, 3: NSEC3.
+ *
+ * Two slots are a compromise to smoothly handle normal rollovers
+ * (either changing NSEC3 parameters or between NSEC and NSEC3). */
+ int8_t nsecs[ENTRY_APEX_NSECS_CNT];
+ uint8_t data[];
+ /* XXX: if not first, stamp of last being the first?
+ * Purpose: save cache operations if rolled the algo/params long ago. */
+};
+
+/** Indices for decompressed entry_list_t. */
+enum EL {
+ EL_NS = ENTRY_APEX_NSECS_CNT,
+ EL_CNAME,
+ EL_DNAME,
+ EL_LENGTH
+};
+/** Decompressed entry_apex. It's an array of unparsed entry_h references.
+ * Note: arrays are passed "by reference" to functions (in C99). */
+typedef knot_db_val_t entry_list_t[EL_LENGTH];
+
+static inline uint16_t EL2RRTYPE(enum EL i)
+{
+ switch (i) {
+ case EL_NS: return KNOT_RRTYPE_NS;
+ case EL_CNAME: return KNOT_RRTYPE_CNAME;
+ case EL_DNAME: return KNOT_RRTYPE_DNAME;
+ default: kr_assert(false); return 0;
+ }
+}
+
+/** There may be multiple entries within, so rewind `val` to the one we want.
+ *
+ * ATM there are multiple types only for the NS ktype - it also accommodates xNAMEs.
+ * \note `val->len` represents the bound of the whole list, not of a single entry.
+ * \note in case of ENOENT, `val` is still rewound to the beginning of the next entry.
+ * \return error code
+ * TODO: maybe get rid of this API?
+ */
+int entry_h_seek(knot_db_val_t *val, uint16_t type);
+
+/** Prepare space to insert an entry.
+ *
+ * Some checks are performed (rank, TTL), the current entry in cache is copied
+ * with a hole ready for the new entry (old one of the same type is cut out).
+ *
+ * \param val_new_entry The only changing parameter; ->len is read, ->data written.
+ * \return error code
+ */
+int entry_h_splice(
+ knot_db_val_t *val_new_entry, uint8_t rank,
+ const knot_db_val_t key, const uint16_t ktype, const uint16_t type,
+ const knot_dname_t *owner/*log only*/,
+ const struct kr_query *qry, struct kr_cache *cache, uint32_t timestamp);
+
+/** Parse an entry_apex into individual items. @return error code. */
+KR_EXPORT int entry_list_parse(const knot_db_val_t val, entry_list_t list);
+
+static inline size_t to_even(size_t n)
+{
+ return n + (n & 1);
+}
+
+static inline int entry_list_serial_size(const entry_list_t list)
+{
+ int size = offsetof(struct entry_apex, data);
+ for (int i = 0; i < EL_LENGTH; ++i) {
+ size += to_even(list[i].len);
+ }
+ return size;
+}
+
+/** Fill contents of an entry_apex.
+ *
+ * @note NULL pointers are overwritten - caller may like to fill the space later.
+ */
+void entry_list_memcpy(struct entry_apex *ea, entry_list_t list);
+
+
+
+/* Packet caching; implementation in ./entry_pkt.c */
+
+/** Stash the packet into cache (if suitable, etc.)
+ * \param needs_pkt we need the packet due to not stashing some RRs;
+ * see stash_rrset() for details
+ * It assumes check_dname_for_lf(). */
+void stash_pkt(const knot_pkt_t *pkt, const struct kr_query *qry,
+ const struct kr_request *req, bool needs_pkt);
+
+/** Try answering from packet cache, given an entry_h.
+ *
+ * This assumes the TTL is OK and entry_h_consistent, but it may still return error.
+ * On success it handles all the rest, incl. qry->flags.
+ */
+int answer_from_pkt(kr_layer_t *ctx, knot_pkt_t *pkt, uint16_t type,
+ const struct entry_h *eh, const void *eh_bound, uint32_t new_ttl);
+
+
+/** Record is expiring if it has less than 1% TTL (or less than 5s) */
+static inline bool is_expiring(uint32_t orig_ttl, uint32_t new_ttl)
+{
+ int64_t nttl = new_ttl; /* avoid potential over/under-flow */
+ return 100 * (nttl - 5) < orig_ttl;
+}
+
+/** Returns signed result so you can inspect how much stale the RR is.
+ *
+ * @param owner name for stale-serving decisions. You may pass NULL to disable stale.
+ * @note: NSEC* uses zone name ATM; for NSEC3 the owner may not even be knowable.
+ * @param type for stale-serving.
+ */
+int32_t get_new_ttl(const struct entry_h *entry, const struct kr_query *qry,
+ const knot_dname_t *owner, uint16_t type, uint32_t now);
+
+
+/* RRset (de)materialization; implementation in ./entry_rr.c */
+
+/** Size of the RR count field */
+#define KR_CACHE_RR_COUNT_SIZE sizeof(uint16_t)
+
+/** Compute size of serialized rdataset. NULL is accepted as empty set. */
+static inline int rdataset_dematerialize_size(const knot_rdataset_t *rds)
+{
+ return KR_CACHE_RR_COUNT_SIZE + (rds == NULL ? 0 : rds->size);
+}
+
+/** Analyze the length of a dematerialized rdataset.
+ * Note that in the data it's KR_CACHE_RR_COUNT_SIZE and then this returned size. */
+static inline int rdataset_dematerialized_size(const uint8_t *data, uint16_t *rdataset_count)
+{
+ uint16_t count;
+ static_assert(sizeof(count) == KR_CACHE_RR_COUNT_SIZE,
+ "Unexpected KR_CACHE_RR_COUNT_SIZE.");
+ memcpy(&count, data, sizeof(count));
+ const uint8_t *rdata = data + sizeof(count);
+ if (rdataset_count) // memcpy is safe for unaligned case (on non-x86)
+ memcpy(rdataset_count, &count, sizeof(count));
+ for (int i = 0; i < count; ++i) {
+ __typeof__(((knot_rdata_t *)NULL)->len) len; // memcpy as above
+ memcpy(&len, rdata + offsetof(knot_rdata_t, len), sizeof(len));
+ rdata += knot_rdata_size(len);
+ }
+ return rdata - (data + sizeof(count));
+}
+
+/** Serialize an rdataset. It may be NULL as short-hand for empty. */
+void rdataset_dematerialize(const knot_rdataset_t *rds, uint8_t * restrict data);
+
+
+/** Partially constructed answer when gathering RRsets from cache. */
+struct answer {
+ int rcode; /**< PKT_NODATA, etc. */
+ struct nsec_p nsec_p; /**< Don't mix different NSEC* parameters in one answer. */
+ knot_mm_t *mm; /**< Allocator for rrsets */
+ struct answer_rrset {
+ ranked_rr_array_entry_t set; /**< set+rank for the main data */
+ knot_rdataset_t sig_rds; /**< RRSIG data, if any */
+ } rrsets[1+1+3]; /**< see AR_ANSWER and friends; only required records are filled */
+};
+enum {
+ AR_ANSWER = 0, /**< Positive answer record. It might be wildcard-expanded. */
+ AR_SOA, /**< SOA record. */
+ AR_NSEC, /**< NSEC* covering or matching the SNAME (next closer name in NSEC3 case). */
+ AR_WILD, /**< NSEC* covering or matching the source of synthesis. */
+ AR_CPE, /**< NSEC3 matching the closest provable encloser. */
+};
+
+/** Materialize RRset + RRSIGs into ans->rrsets[id].
+ * LATER(optim.): it's slightly wasteful that we allocate knot_rrset_t for the packet
+ *
+ * \return error code. They are all bad conditions and "guarded" by kresd's assertions.
+ */
+int entry2answer(struct answer *ans, int id,
+ const struct entry_h *eh, const uint8_t *eh_bound,
+ const knot_dname_t *owner, uint16_t type, uint32_t new_ttl);
+
+
+/* Preparing knot_pkt_t for cache answer from RRs; implementation in ./knot_pkt.c */
+
+/** Prepare answer packet to be filled by RRs (without RR data in wire). */
+int pkt_renew(knot_pkt_t *pkt, const knot_dname_t *name, uint16_t type);
+
+/** Append RRset + its RRSIGs into the current section (*shallow* copy), with given rank.
+ *
+ * \note it works with empty set as well (skipped)
+ * \note pkt->wire is not updated in any way
+ * \note KNOT_CLASS_IN is assumed
+ * \note Whole RRsets are put into the pseudo-packet;
+ * normal parsed packets would only contain single-RR sets.
+ */
+int pkt_append(knot_pkt_t *pkt, const struct answer_rrset *rrset, uint8_t rank);
+
+
+
+/* NSEC (1) stuff. Implementation in ./nsec1.c */
+
+/** Construct a string key for for NSEC (1) predecessor-search.
+ * \param add_wildcard Act as if the name was extended by "*."
+ * \note k->zlf_len is assumed to have been correctly set */
+knot_db_val_t key_NSEC1(struct key *k, const knot_dname_t *name, bool add_wildcard);
+
+/** Closest encloser check for NSEC (1).
+ * To understand the interface, see the call point.
+ * \param k space to store key + input: zname and zlf_len
+ * \return 0: success; >0: try other (NSEC3); <0: exit cache immediately. */
+int nsec1_encloser(struct key *k, struct answer *ans,
+ const int sname_labels, int *clencl_labels,
+ knot_db_val_t *cover_low_kwz, knot_db_val_t *cover_hi_kwz,
+ const struct kr_query *qry, struct kr_cache *cache);
+
+/** Source of synthesis (SS) check for NSEC (1).
+ * To understand the interface, see the call point.
+ * \return 0: continue; <0: exit cache immediately;
+ * AR_SOA: skip to adding SOA (SS was covered or matched for NODATA). */
+int nsec1_src_synth(struct key *k, struct answer *ans, const knot_dname_t *clencl_name,
+ knot_db_val_t cover_low_kwz, knot_db_val_t cover_hi_kwz,
+ const struct kr_query *qry, struct kr_cache *cache);
+
+
+/* NSEC3 stuff. Implementation in ./nsec3.c */
+
+/** Construct a string key for for NSEC3 predecessor-search, from an NSEC3 name.
+ * \note k->zlf_len is assumed to have been correctly set */
+knot_db_val_t key_NSEC3(struct key *k, const knot_dname_t *nsec3_name,
+ const nsec_p_hash_t nsec_p_hash);
+
+/** TODO. See nsec1_encloser(...) */
+int nsec3_encloser(struct key *k, struct answer *ans,
+ const int sname_labels, int *clencl_labels,
+ const struct kr_query *qry, struct kr_cache *cache);
+
+/** TODO. See nsec1_src_synth(...) */
+int nsec3_src_synth(struct key *k, struct answer *ans, const knot_dname_t *clencl_name,
+ const struct kr_query *qry, struct kr_cache *cache);
+
+
+
+#define VERBOSE_MSG(qry, ...) kr_log_q((qry), CACHE, ## __VA_ARGS__)
+#define WITH_VERBOSE(qry) if (kr_log_is_debug_qry(CACHE, (qry)))
+
+/** Shorthand for operations on cache backend */
+#define cache_op(cache, op, ...) (cache)->api->op((cache)->db, &(cache)->stats, ## __VA_ARGS__)
+
+
+static inline uint16_t get_uint16(const void *address)
+{
+ uint16_t tmp;
+ memcpy(&tmp, address, sizeof(tmp));
+ return tmp;
+}
+
+/** Useful pattern, especially as void-pointer arithmetic isn't standard-compliant. */
+static inline uint8_t * knot_db_val_bound(knot_db_val_t val)
+{
+ return (uint8_t *)val.data + val.len;
+}
+
diff --git a/lib/cache/knot_pkt.c b/lib/cache/knot_pkt.c
new file mode 100644
index 0000000..31fa7e9
--- /dev/null
+++ b/lib/cache/knot_pkt.c
@@ -0,0 +1,94 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+/** @file
+ * Implementation of preparing knot_pkt_t for filling with RRs.
+ * Prototypes in ./impl.h
+ */
+
+#include "lib/cache/impl.h"
+
+int pkt_renew(knot_pkt_t *pkt, const knot_dname_t *name, uint16_t type)
+{
+ /* Update packet question if needed. */
+ if (!knot_dname_is_equal(knot_pkt_qname(pkt), name)
+ || knot_pkt_qtype(pkt) != type || knot_pkt_qclass(pkt) != KNOT_CLASS_IN) {
+ int ret = kr_pkt_recycle(pkt);
+ if (ret) return kr_error(ret);
+ ret = knot_pkt_put_question(pkt, name, KNOT_CLASS_IN, type);
+ if (ret) return kr_error(ret);
+ }
+
+ pkt->parsed = pkt->size = KR_PKT_SIZE_NOWIRE;
+ knot_wire_set_qr(pkt->wire);
+ knot_wire_set_aa(pkt->wire);
+ return kr_ok();
+}
+
+/** Reserve space for additional `count` RRsets.
+ * \note pkt->rr_info gets correct length but is always zeroed
+ */
+static int pkt_alloc_space(knot_pkt_t *pkt, int count)
+{
+ size_t allocd_orig = pkt->rrset_allocd;
+ if (pkt->rrset_count + count <= allocd_orig) {
+ return kr_ok();
+ }
+ /* A simple growth strategy, amortized O(count). */
+ pkt->rrset_allocd = MAX(
+ pkt->rrset_count + count,
+ pkt->rrset_count + allocd_orig);
+
+ pkt->rr = mm_realloc(&pkt->mm, pkt->rr,
+ sizeof(pkt->rr[0]) * pkt->rrset_allocd,
+ sizeof(pkt->rr[0]) * allocd_orig);
+ if (!pkt->rr) {
+ return kr_error(ENOMEM);
+ }
+ /* Allocate pkt->rr_info to be certain, but just leave it zeroed. */
+ mm_free(&pkt->mm, pkt->rr_info);
+ pkt->rr_info = mm_calloc(&pkt->mm, pkt->rrset_allocd, sizeof(pkt->rr_info[0]));
+ if (!pkt->rr_info) {
+ return kr_error(ENOMEM);
+ }
+ return kr_ok();
+}
+
+int pkt_append(knot_pkt_t *pkt, const struct answer_rrset *rrset, uint8_t rank)
+{
+ /* allocate space, to be sure */
+ int rrset_cnt = (rrset->set.rr->rrs.count > 0) + (rrset->sig_rds.count > 0);
+ int ret = pkt_alloc_space(pkt, rrset_cnt);
+ if (ret) return kr_error(ret);
+ /* write both sets */
+ const knot_rdataset_t *rdss[2] = { &rrset->set.rr->rrs, &rrset->sig_rds };
+ for (int i = 0; i < rrset_cnt; ++i) {
+ if (kr_fails_assert(rdss[i]->count))
+ return kr_error(EINVAL);
+ /* allocate rank */
+ uint8_t *rr_rank = mm_alloc(&pkt->mm, sizeof(*rr_rank));
+ if (!rr_rank) return kr_error(ENOMEM);
+ *rr_rank = (i == 0) ? rank : (KR_RANK_OMIT | KR_RANK_AUTH);
+ /* rank for RRSIGs isn't really useful: ^^ */
+ if (i == 0) {
+ pkt->rr[pkt->rrset_count] = *rrset->set.rr;
+ pkt->rr[pkt->rrset_count].additional = rr_rank;
+ } else {
+ /* append the RR array */
+ pkt->rr[pkt->rrset_count] = (knot_rrset_t){
+ .owner = knot_dname_copy(rrset->set.rr->owner, &pkt->mm),
+ /* ^^ well, another copy isn't really needed */
+ .ttl = rrset->set.rr->ttl,
+ .type = KNOT_RRTYPE_RRSIG,
+ .rclass = KNOT_CLASS_IN,
+ .rrs = *rdss[i],
+ .additional = rr_rank,
+ };
+ }
+ ++pkt->rrset_count;
+ ++(pkt->sections[pkt->current].count);
+ }
+ return kr_ok();
+}
+
diff --git a/lib/cache/nsec1.c b/lib/cache/nsec1.c
new file mode 100644
index 0000000..4554303
--- /dev/null
+++ b/lib/cache/nsec1.c
@@ -0,0 +1,488 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+/** @file
+ * Implementation of NSEC (1) handling. Prototypes in ./impl.h
+ */
+
+#include "lib/cache/impl.h"
+#include "lib/dnssec/nsec.h"
+#include "lib/layer/iterate.h"
+
+
+/** Reconstruct a name into a buffer (assuming length at least KNOT_DNAME_MAXLEN).
+ * \return kr_ok() or error code (<0). */
+static int dname_wire_reconstruct(knot_dname_t *buf, const struct key *k,
+ knot_db_val_t kwz)
+{
+ /* Reconstruct from key: first the ending, then zone name. */
+ int ret = knot_dname_lf2wire(buf, kwz.len, kwz.data);
+ if (kr_fails_assert(ret >= 0)) {
+ VERBOSE_MSG(NULL, "=> NSEC: LF2wire ret = %d\n", ret);
+ return ret;
+ }
+ /* The last written byte is the zero label for root -> overwrite. */
+ knot_dname_t *zone_start = buf + ret - 1;
+ if (kr_fails_assert(*zone_start == '\0'))
+ return kr_error(EFAULT);
+ ret = knot_dname_to_wire(zone_start, k->zname, KNOT_DNAME_MAXLEN - kwz.len);
+ if (kr_fails_assert(ret == k->zlf_len + 1))
+ return ret < 0 ? ret : kr_error(EILSEQ);
+ return kr_ok();
+}
+
+
+knot_db_val_t key_NSEC1(struct key *k, const knot_dname_t *name, bool add_wildcard)
+{
+ /* we basically need dname_lf with two bytes added
+ * on a correct place within the name (the cut) */
+ int ret;
+ const bool ok = k && name
+ && !(ret = kr_dname_lf(k->buf, name, add_wildcard));
+ if (kr_fails_assert(ok))
+ return (knot_db_val_t){ NULL, 0 };
+
+ uint8_t *begin = k->buf + 1 + k->zlf_len; /* one byte after zone's zero */
+ uint8_t *end = k->buf + 1 + k->buf[0]; /* we don't use the final zero in key,
+ * but move it anyway */
+ if (kr_fails_assert(end >= begin))
+ return (knot_db_val_t){ NULL, 0 };
+ int key_len;
+ if (end > begin) {
+ memmove(begin + 2, begin, end - begin);
+ key_len = k->buf[0] + 1;
+ } else {
+ key_len = k->buf[0] + 2;
+ }
+ /* CACHE_KEY_DEF: key == zone's dname_lf + '\0' + '1' + dname_lf
+ * of the name within the zone without the final 0. Iff the latter is empty,
+ * there's no zero to cut and thus the key_len difference.
+ */
+ begin[0] = 0;
+ begin[1] = '1'; /* tag for NSEC1 */
+ k->type = KNOT_RRTYPE_NSEC;
+
+ /*
+ VERBOSE_MSG(NULL, "<> key_NSEC1; name: ");
+ kr_dname_print(name, add_wildcard ? "*." : "" , " ");
+ kr_log_debug(CACHE, "(zone name LF length: %d; total key length: %d)\n",
+ k->zlf_len, key_len);
+ */
+
+ return (knot_db_val_t){ k->buf + 1, key_len };
+}
+
+
+/** Assuming that k1 < k4, find where k2 is. (Considers DNS wrap-around.)
+ *
+ * \return Intuition: position of k2 among kX.
+ * 0: k2 < k1; 1: k1 == k2; 2: k1 is a prefix of k2 < k4;
+ * 3: k1 < k2 < k4 (and not 2); 4: k2 == k4; 5: k2 > k4
+ * \note k1.data may be NULL, meaning assumption that k1 < k2 and not a prefix
+ * (i.e. return code will be > 2)
+ */
+static int kwz_between(knot_db_val_t k1, knot_db_val_t k2, knot_db_val_t k4)
+{
+ kr_require(k2.data && k4.data);
+ /* CACHE_KEY_DEF; we need to beware of one key being a prefix of another */
+ int ret_maybe; /**< result, assuming we confirm k2 < k4 */
+ if (k1.data) {
+ const int cmp12 = memcmp(k1.data, k2.data, MIN(k1.len, k2.len));
+ if (cmp12 == 0 && k1.len == k2.len) /* iff k1 == k2 */
+ return 1;
+ if (cmp12 > 0 || (cmp12 == 0 && k1.len > k2.len)) /* iff k1 > k2 */
+ return 0;
+ ret_maybe = cmp12 == 0 ? 2 : 3;
+ } else {
+ ret_maybe = 3;
+ }
+ if (k4.len == 0) { /* wrap-around */
+ return k2.len > 0 ? ret_maybe : 4;
+ } else {
+ const int cmp24 = memcmp(k2.data, k4.data, MIN(k2.len, k4.len));
+ if (cmp24 == 0 && k2.len == k4.len) /* iff k2 == k4 */
+ return 4;
+ if (cmp24 > 0 || (cmp24 == 0 && k2.len > k4.len)) /* iff k2 > k4 */
+ return 5;
+ return ret_maybe;
+ }
+}
+
+
+/** NSEC1 range search.
+ *
+ * \param key Pass output of key_NSEC1(k, ...)
+ * \param value[out] The raw data of the NSEC cache record (optional; consistency checked).
+ * \param exact_match[out] Whether the key was matched exactly or just covered (optional).
+ * \param kwz_low[out] Output the low end of covering NSEC, pointing within DB (optional).
+ * \param kwz_high[in,out] Storage for the high end of covering NSEC (optional).
+ * It's only set if !exact_match.
+ * \param new_ttl[out] New TTL of the NSEC (optional).
+ * \return Error message or NULL.
+ * \note The function itself does *no* bitmap checks, e.g. RFC 6840 sec. 4.
+ */
+static const char * find_leq_NSEC1(struct kr_cache *cache, const struct kr_query *qry,
+ const knot_db_val_t key, const struct key *k, knot_db_val_t *value,
+ bool *exact_match, knot_db_val_t *kwz_low, knot_db_val_t *kwz_high,
+ uint32_t *new_ttl)
+{
+ /* Do the cache operation. */
+ const size_t nwz_off = key_nwz_off(k);
+ if (kr_fails_assert(key.data && key.len >= nwz_off))
+ return "range search ERROR";
+ knot_db_val_t key_nsec = key;
+ knot_db_val_t val = { NULL, 0 };
+ int ret = cache_op(cache, read_leq, &key_nsec, &val);
+ if (ret < 0) {
+ if (kr_fails_assert(ret == kr_error(ENOENT))) {
+ return "range search ERROR";
+ } else {
+ return "range search miss";
+ }
+ }
+ if (value) {
+ *value = val;
+ }
+ /* Check consistency, TTL, rank. */
+ const bool is_exact = (ret == 0);
+ if (exact_match) {
+ *exact_match = is_exact;
+ }
+ const struct entry_h *eh = entry_h_consistent_NSEC(val);
+ if (!eh) {
+ /* This might be just finding something else than NSEC1 entry,
+ * in case we searched before the very first one in the zone. */
+ return "range search found inconsistent entry";
+ }
+ /* Passing just zone name instead of owner, as we don't
+ * have it reconstructed at this point. */
+ int32_t new_ttl_ = get_new_ttl(eh, qry, k->zname, KNOT_RRTYPE_NSEC,
+ qry->timestamp.tv_sec);
+ if (new_ttl_ < 0 || !kr_rank_test(eh->rank, KR_RANK_SECURE)) {
+ return "range search found stale or insecure entry";
+ /* TODO: remove the stale record *and* retry,
+ * in case we haven't run off. Perhaps start by in_zone check. */
+ }
+ if (new_ttl) {
+ *new_ttl = new_ttl_;
+ }
+ if (kwz_low) {
+ *kwz_low = (knot_db_val_t){
+ .data = (uint8_t *)key_nsec.data + nwz_off,
+ .len = key_nsec.len - nwz_off,
+ }; /* CACHE_KEY_DEF */
+ }
+ if (is_exact) {
+ /* Nothing else to do. */
+ return NULL;
+ }
+ /* The NSEC starts strictly before our target name;
+ * now check that it still belongs into that zone. */
+ const bool nsec_in_zone = key_nsec.len >= nwz_off
+ /* CACHE_KEY_DEF */
+ && memcmp(key.data, key_nsec.data, nwz_off) == 0;
+ if (!nsec_in_zone) {
+ return "range search miss (!nsec_in_zone)";
+ }
+ /* We know it starts before sname, so let's check the other end.
+ * 1. construct the key for the next name - kwz_hi. */
+ /* it's *full* name ATM */
+ /* Technical complication: memcpy is safe for unaligned case (on non-x86) */
+ __typeof__(((knot_rdata_t *)NULL)->len) next_len;
+ const uint8_t *next_data;
+ { /* next points to knot_rdata_t but possibly unaligned */
+ const uint8_t *next = eh->data + KR_CACHE_RR_COUNT_SIZE;
+ memcpy(&next_len, next + offsetof(knot_rdata_t, len), sizeof(next_len));
+ next_data = next + offsetof(knot_rdata_t, data);
+ }
+ if (kr_fails_assert(KR_CACHE_RR_COUNT_SIZE == 2 && get_uint16(eh->data) != 0)) {
+ return "ERROR"; /* TODO: more checks? */
+ }
+ /*
+ WITH_VERBOSE {
+ VERBOSE_MSG(qry, "=> NSEC: next name: ");
+ kr_dname_print(next, "", "\n");
+ }
+ */
+ knot_dname_t ch_buf[KNOT_DNAME_MAXLEN];
+ knot_dname_t *chs = kwz_high ? kwz_high->data : ch_buf;
+ if (kr_fails_assert(chs))
+ return "EINVAL";
+
+ {
+ /* Lower-case chs; see also RFC 6840 5.1.
+ * LATER(optim.): we do lots of copying etc. */
+ knot_dname_t lower_buf[KNOT_DNAME_MAXLEN];
+ ret = knot_dname_to_wire(lower_buf, next_data,
+ MIN(next_len, KNOT_DNAME_MAXLEN));
+ if (ret < 0) { /* _ESPACE */
+ return "range search found record with incorrect contents";
+ }
+ knot_dname_to_lower(lower_buf);
+ ret = kr_dname_lf(chs, lower_buf, false);
+ }
+
+ if (kr_fails_assert(ret == 0))
+ return "ERROR";
+ knot_db_val_t kwz_hi = { /* skip the zone name */
+ .data = chs + 1 + k->zlf_len,
+ .len = chs[0] - k->zlf_len,
+ };
+ if (kr_fails_assert((ssize_t)(kwz_hi.len) >= 0))
+ return "ERROR";
+ /* 2. do the actual range check. */
+ const knot_db_val_t kwz_sname = {
+ .data = (void *)/*const-cast*/(k->buf + 1 + nwz_off),
+ .len = k->buf[0] - k->zlf_len,
+ };
+ if (kr_fails_assert((ssize_t)(kwz_sname.len) >= 0))
+ return "ERROR";
+ bool covers = /* we know for sure that the low end is before kwz_sname */
+ 3 == kwz_between((knot_db_val_t){ NULL, 0 }, kwz_sname, kwz_hi);
+ if (!covers) {
+ return "range search miss (!covers)";
+ }
+ if (kwz_high) {
+ *kwz_high = kwz_hi;
+ }
+ return NULL;
+}
+
+
+int nsec1_encloser(struct key *k, struct answer *ans,
+ const int sname_labels, int *clencl_labels,
+ knot_db_val_t *cover_low_kwz, knot_db_val_t *cover_hi_kwz,
+ const struct kr_query *qry, struct kr_cache *cache)
+{
+ static const int ESKIP = ABS(ENOENT);
+ /* Basic sanity check. */
+ const bool ok = k && ans && clencl_labels && cover_low_kwz && cover_hi_kwz
+ && qry && cache;
+ if (kr_fails_assert(ok))
+ return kr_error(EINVAL);
+
+ /* Find a previous-or-equal name+NSEC in cache covering the QNAME,
+ * checking TTL etc. */
+ knot_db_val_t key = key_NSEC1(k, qry->sname, false);
+ knot_db_val_t val = { NULL, 0 };
+ bool exact_match;
+ uint32_t new_ttl;
+ const char *err = find_leq_NSEC1(cache, qry, key, k, &val,
+ &exact_match, cover_low_kwz, cover_hi_kwz, &new_ttl);
+ if (err) {
+ VERBOSE_MSG(qry, "=> NSEC sname: %s\n", err);
+ return ESKIP;
+ }
+
+ /* Get owner name of the record. */
+ const knot_dname_t *owner;
+ knot_dname_t owner_buf[KNOT_DNAME_MAXLEN];
+ if (exact_match) {
+ owner = qry->sname;
+ } else {
+ int ret = dname_wire_reconstruct(owner_buf, k, *cover_low_kwz);
+ if (unlikely(ret)) return ESKIP;
+ owner = owner_buf;
+ }
+ /* Basic checks OK -> materialize data. */
+ {
+ const struct entry_h *nsec_eh = val.data;
+ int ret = entry2answer(ans, AR_NSEC, nsec_eh, knot_db_val_bound(val),
+ owner, KNOT_RRTYPE_NSEC, new_ttl);
+ if (ret) return kr_error(ret);
+ }
+
+ /* Final checks, split for matching vs. covering our sname. */
+ const knot_rrset_t *nsec_rr = ans->rrsets[AR_NSEC].set.rr;
+ const uint8_t *bm = knot_nsec_bitmap(nsec_rr->rrs.rdata);
+ uint16_t bm_size = knot_nsec_bitmap_len(nsec_rr->rrs.rdata);
+ if (kr_fails_assert(bm))
+ return kr_error(EFAULT);
+
+ if (exact_match) {
+ if (kr_nsec_bitmap_nodata_check(bm, bm_size, qry->stype, nsec_rr->owner) != 0) {
+ VERBOSE_MSG(qry,
+ "=> NSEC sname: match but failed type check\n");
+ return ESKIP;
+ }
+ /* NODATA proven; just need to add SOA+RRSIG later */
+ VERBOSE_MSG(qry, "=> NSEC sname: match proved NODATA, new TTL %d\n",
+ new_ttl);
+ ans->rcode = PKT_NODATA;
+ return kr_ok();
+ } /* else */
+
+ /* Inexact match. First check if sname is delegated by that NSEC. */
+ const int nsec_matched = knot_dname_matched_labels(nsec_rr->owner, qry->sname);
+ const bool is_sub = nsec_matched == knot_dname_labels(nsec_rr->owner, NULL);
+ if (is_sub && kr_nsec_children_in_zone_check(bm, bm_size) != 0) {
+ VERBOSE_MSG(qry, "=> NSEC sname: covered but delegated (or error)\n");
+ return ESKIP;
+ }
+ /* NXDOMAIN proven *except* for wildcards. */
+ WITH_VERBOSE(qry) {
+ auto_free char *owner_str = kr_dname_text(nsec_rr->owner),
+ *next_str = kr_dname_text(knot_nsec_next(nsec_rr->rrs.rdata));
+ VERBOSE_MSG(qry, "=> NSEC sname: covered by: %s -> %s, new TTL %d\n",
+ owner_str, next_str, new_ttl);
+ }
+
+ /* Find label count of the closest encloser.
+ * Both endpoints in an NSEC do exist (though possibly in a child zone)
+ * and any prefixes of those names as well (empty non-terminals),
+ * but nothing else exists inside this "triangle".
+ *
+ * Note that we have to lower-case the next name for comparison,
+ * even though we have canonicalized NSEC already; see RFC 6840 5.1.
+ * LATER(optim.): it might be faster to use the LFs we already have.
+ */
+ knot_dname_t next[KNOT_DNAME_MAXLEN];
+ int ret = knot_dname_to_wire(next, knot_nsec_next(nsec_rr->rrs.rdata), sizeof(next));
+ if (kr_fails_assert(ret >= 0))
+ return kr_error(ret);
+ knot_dname_to_lower(next);
+ *clencl_labels = MAX(
+ nsec_matched,
+ knot_dname_matched_labels(qry->sname, next)
+ );
+
+ /* Empty non-terminals don't need to have
+ * a matching NSEC record. */
+ if (sname_labels == *clencl_labels) {
+ ans->rcode = PKT_NODATA;
+ VERBOSE_MSG(qry,
+ "=> NSEC sname: empty non-terminal by the same RR\n");
+ } else {
+ ans->rcode = PKT_NXDOMAIN;
+ }
+ return kr_ok();
+}
+
+/** Verify non-existence after kwz_between() call. */
+static bool nonexistence_ok(int cmp, const knot_rrset_t *rrs)
+{
+ if (cmp == 3) {
+ return true;
+ }
+ if (cmp != 2) {
+ return false;
+ }
+ const uint8_t *bm = knot_nsec_bitmap(rrs->rrs.rdata);
+ uint16_t bm_size = knot_nsec_bitmap_len(rrs->rrs.rdata);
+ return kr_nsec_children_in_zone_check(bm, bm_size) != 0;
+}
+
+int nsec1_src_synth(struct key *k, struct answer *ans, const knot_dname_t *clencl_name,
+ knot_db_val_t cover_low_kwz, knot_db_val_t cover_hi_kwz,
+ const struct kr_query *qry, struct kr_cache *cache)
+{
+ /* Construct key for the source of synthesis. */
+ knot_db_val_t key = key_NSEC1(k, clencl_name, true);
+ const size_t nwz_off = key_nwz_off(k);
+ if (kr_fails_assert(key.data && key.len >= nwz_off))
+ return kr_error(1);
+ /* Check if our sname-covering NSEC also covers/matches SS. */
+ knot_db_val_t kwz = {
+ .data = (uint8_t *)key.data + nwz_off,
+ .len = key.len - nwz_off,
+ };
+ if (kr_fails_assert((ssize_t)(kwz.len) >= 0))
+ return kr_error(EINVAL);
+ const int cmp = kwz_between(cover_low_kwz, kwz, cover_hi_kwz);
+ if (nonexistence_ok(cmp, ans->rrsets[AR_NSEC].set.rr)) {
+ VERBOSE_MSG(qry, "=> NSEC wildcard: covered by the same RR\n");
+ return AR_SOA;
+ }
+ const knot_rrset_t *nsec_rr = NULL; /**< the wildcard proof NSEC */
+ bool exact_match; /**< whether it matches the source of synthesis */
+ if (cmp == 1) {
+ exact_match = true;
+ nsec_rr = ans->rrsets[AR_NSEC].set.rr;
+ } else {
+ /* Try to find the NSEC for SS. */
+ knot_db_val_t val = { NULL, 0 };
+ knot_db_val_t wild_low_kwz = { NULL, 0 };
+ uint32_t new_ttl;
+ const char *err = find_leq_NSEC1(cache, qry, key, k, &val,
+ &exact_match, &wild_low_kwz, NULL, &new_ttl);
+ if (err) {
+ VERBOSE_MSG(qry, "=> NSEC wildcard: %s\n", err);
+ return kr_ok();
+ }
+ /* Materialize the record into answer (speculatively). */
+ knot_dname_t owner[KNOT_DNAME_MAXLEN];
+ int ret = dname_wire_reconstruct(owner, k, wild_low_kwz);
+ if (ret) return kr_error(ret);
+ const struct entry_h *nsec_eh = val.data;
+ ret = entry2answer(ans, AR_WILD, nsec_eh, knot_db_val_bound(val),
+ owner, KNOT_RRTYPE_NSEC, new_ttl);
+ if (ret) return kr_error(ret);
+ nsec_rr = ans->rrsets[AR_WILD].set.rr;
+ }
+
+ if (kr_fails_assert(nsec_rr))
+ return kr_error(EFAULT);
+ const uint8_t *bm = knot_nsec_bitmap(nsec_rr->rrs.rdata);
+ uint16_t bm_size = knot_nsec_bitmap_len(nsec_rr->rrs.rdata);
+ int ret;
+ struct answer_rrset * const arw = &ans->rrsets[AR_WILD];
+ if (kr_fails_assert(bm)) {
+ ret = kr_error(EFAULT);
+ goto clean_wild;
+ }
+ if (!exact_match) {
+ /* Finish verification that the source of synthesis doesn't exist. */
+ const int nsec_matched =
+ knot_dname_matched_labels(nsec_rr->owner, clencl_name);
+ /* we don't need to use the full source of synthesis ^ */
+ const bool is_sub =
+ nsec_matched == knot_dname_labels(nsec_rr->owner, NULL);
+ if (is_sub && kr_nsec_children_in_zone_check(bm, bm_size) != 0) {
+ VERBOSE_MSG(qry,
+ "=> NSEC wildcard: covered but delegated (or error)\n");
+ ret = kr_ok();
+ goto clean_wild;
+ }
+ /* We have a record proving wildcard non-existence. */
+ WITH_VERBOSE(qry) {
+ auto_free char *owner_str = kr_dname_text(nsec_rr->owner),
+ *next_str = kr_dname_text(knot_nsec_next(nsec_rr->rrs.rdata));
+ VERBOSE_MSG(qry, "=> NSEC wildcard: covered by: %s -> %s, new TTL %d\n",
+ owner_str, next_str, nsec_rr->ttl);
+ }
+ return AR_SOA;
+ }
+
+ /* The wildcard exists. Find if it's NODATA - check type bitmap. */
+ if (kr_nsec_bitmap_nodata_check(bm, bm_size, qry->stype, nsec_rr->owner) == 0) {
+ /* NODATA proven; just need to add SOA+RRSIG later */
+ WITH_VERBOSE(qry) {
+ const char *msg_start = "=> NSEC wildcard: match proved NODATA";
+ if (arw->set.rr) {
+ auto_free char *owner_str = kr_dname_text(nsec_rr->owner);
+ VERBOSE_MSG(qry, "%s: %s, new TTL %d\n",
+ msg_start, owner_str, nsec_rr->ttl);
+ } else {
+ /* don't repeat the RR if it's the same */
+ VERBOSE_MSG(qry, "%s, by the same RR\n", msg_start);
+ }
+ }
+ ans->rcode = PKT_NODATA;
+ return AR_SOA;
+
+ } /* else */
+ /* The data probably exists -> don't add this NSEC
+ * and (later) try to find the real wildcard data */
+ VERBOSE_MSG(qry, "=> NSEC wildcard: should exist (or error)\n");
+ ans->rcode = PKT_NOERROR;
+ ret = kr_ok();
+clean_wild:
+ if (arw->set.rr) { /* we may have matched AR_NSEC */
+ knot_rrset_free(arw->set.rr, ans->mm);
+ arw->set.rr = NULL;
+ knot_rdataset_clear(&arw->sig_rds, ans->mm);
+ }
+ return ret;
+}
+
diff --git a/lib/cache/nsec3.c b/lib/cache/nsec3.c
new file mode 100644
index 0000000..0b70775
--- /dev/null
+++ b/lib/cache/nsec3.c
@@ -0,0 +1,481 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+/** @file
+ * Implementation of NSEC3 handling. Prototypes in ./impl.h
+ */
+
+#include "lib/cache/impl.h"
+
+#include "contrib/base32hex.h"
+#include "lib/dnssec/nsec.h"
+#include "lib/dnssec/nsec3.h"
+#include "lib/layer/iterate.h"
+
+#include <libknot/rrtype/nsec3.h>
+
+static const knot_db_val_t VAL_EMPTY = { NULL, 0 };
+
+/** Common part: write all but the NSEC3 hash. */
+static knot_db_val_t key_NSEC3_common(struct key *k, const knot_dname_t *zname,
+ const nsec_p_hash_t nsec_p_hash)
+{
+ if (kr_fails_assert(k && zname && !kr_dname_lf(k->buf, zname, false)))
+ return VAL_EMPTY;
+
+ /* CACHE_KEY_DEF: key == zone's dname_lf + '\0' + '3' + nsec_p hash (4B)
+ * + NSEC3 hash (20B == NSEC3_HASH_LEN binary!)
+ * LATER(optim.) nsec_p hash: perhaps 2B would give a sufficient probability
+ * of avoiding collisions.
+ */
+ uint8_t *begin = k->buf + 1 + k->zlf_len; /* one byte after zone's zero */
+ begin[0] = 0;
+ begin[1] = '3'; /* tag for NSEC3 */
+ k->type = KNOT_RRTYPE_NSEC3;
+ memcpy(begin + 2, &nsec_p_hash, sizeof(nsec_p_hash));
+ return (knot_db_val_t){
+ .data = k->buf + 1,
+ .len = begin + 2 + sizeof(nsec_p_hash) - (k->buf + 1),
+ };
+}
+
+knot_db_val_t key_NSEC3(struct key *k, const knot_dname_t *nsec3_name,
+ const nsec_p_hash_t nsec_p_hash)
+{
+ knot_db_val_t val = key_NSEC3_common(k, nsec3_name /*only zname required*/,
+ nsec_p_hash);
+ if (!val.data) return val;
+ int len = base32hex_decode(nsec3_name + 1, nsec3_name[0],
+ knot_db_val_bound(val), KR_CACHE_KEY_MAXLEN - val.len);
+ if (len != NSEC3_HASH_LEN) {
+ return VAL_EMPTY;
+ }
+ val.len += len;
+ return val;
+}
+
+/** Construct a string key for for NSEC3 predecessor-search, from an non-NSEC3 name.
+ * \note k->zlf_len and k->zname are assumed to have been correctly set */
+static knot_db_val_t key_NSEC3_name(struct key *k, const knot_dname_t *name,
+ const bool add_wildcard, const struct nsec_p *nsec_p)
+{
+ bool ok = k && name && nsec_p && nsec_p->raw;
+ if (!ok) return VAL_EMPTY;
+ knot_db_val_t val = key_NSEC3_common(k, k->zname, nsec_p->hash);
+ if (!val.data) return val;
+
+ /* Make `name` point to correctly wildcarded owner name. */
+ uint8_t buf[KNOT_DNAME_MAXLEN];
+ int name_len;
+ if (add_wildcard) {
+ buf[0] = '\1';
+ buf[1] = '*';
+ name_len = knot_dname_to_wire(buf + 2, name, sizeof(buf) - 2);
+ if (name_len < 0) return VAL_EMPTY; /* wants wildcard but doesn't fit */
+ name = buf;
+ name_len += 2;
+ } else {
+ name_len = knot_dname_size(name);
+ }
+ /* Append the NSEC3 hash. */
+ const dnssec_binary_t dname = {
+ .size = name_len,
+ .data = (uint8_t *)/*const-cast*/name,
+ };
+
+ if (kr_fails_assert(nsec_p->libknot.iterations <= KR_NSEC3_MAX_ITERATIONS)) {
+ /* This is mainly defensive; it shouldn't happen thanks to downgrades. */
+ return VAL_EMPTY;
+ }
+ #if 0 // LATER(optim.): this requires a patched libdnssec - tries to realloc()
+ dnssec_binary_t hash = {
+ .size = KR_CACHE_KEY_MAXLEN - val.len,
+ .data = val.data + val.len,
+ };
+ int ret = dnssec_nsec3_hash(&dname, &nsec_p->libknot, &hash);
+ if (ret != DNSSEC_EOK) return VAL_EMPTY;
+ if (kr_fails_assert(hash.size == NSEC3_HASH_LEN))
+ return VAL_EMPTY;
+
+ #else
+ dnssec_binary_t hash = { .size = 0, .data = NULL };
+ int ret = dnssec_nsec3_hash(&dname, &nsec_p->libknot, &hash);
+ if (ret != DNSSEC_EOK) return VAL_EMPTY;
+ if (kr_fails_assert(hash.size == NSEC3_HASH_LEN && hash.data))
+ return VAL_EMPTY;
+ memcpy(knot_db_val_bound(val), hash.data, NSEC3_HASH_LEN);
+ free(hash.data);
+ #endif
+
+ val.len += hash.size;
+ return val;
+}
+
+/** Return h1 < h2, semantically on NSEC3 hashes. */
+static inline bool nsec3_hash_ordered(const uint8_t *h1, const uint8_t *h2)
+{
+ return memcmp(h1, h2, NSEC3_HASH_LEN) < 0;
+}
+
+/** NSEC3 range search.
+ *
+ * \param key Pass output of key_NSEC3(k, ...)
+ * \param nsec_p Restrict to this NSEC3 parameter-set.
+ * \param value[out] The raw data of the NSEC3 cache record (optional; consistency checked).
+ * \param exact_match[out] Whether the key was matched exactly or just covered (optional).
+ * \param hash_low[out] Output the low end hash of covering NSEC3, pointing within DB (optional).
+ * \param new_ttl[out] New TTL of the NSEC3 (optional).
+ * \return Error message or NULL.
+ * \note The function itself does *no* bitmap checks, e.g. RFC 6840 sec. 4.
+ */
+static const char * find_leq_NSEC3(struct kr_cache *cache, const struct kr_query *qry,
+ const knot_db_val_t key, const struct key *k, const struct nsec_p *nsec_p,
+ knot_db_val_t *value, bool *exact_match, const uint8_t **hash_low,
+ uint32_t *new_ttl)
+{
+ /* Do the cache operation. */
+ const size_t hash_off = key_nsec3_hash_off(k);
+ if (kr_fails_assert(key.data && key.len >= hash_off))
+ return "range search ERROR";
+ knot_db_val_t key_found = key;
+ knot_db_val_t val = { NULL, 0 };
+ int ret = cache_op(cache, read_leq, &key_found, &val);
+ /* ^^ LATER(optim.): incrementing key and doing less-than search
+ * would probably be slightly more efficient with LMDB,
+ * but the code complexity would grow considerably. */
+ if (ret < 0) {
+ if (kr_fails_assert(ret == kr_error(ENOENT))) {
+ return "range search ERROR";
+ } else {
+ return "range search miss";
+ }
+ }
+ if (value) {
+ *value = val;
+ }
+ /* Check consistency, TTL, rank. */
+ const bool is_exact = (ret == 0);
+ if (exact_match) {
+ *exact_match = is_exact;
+ }
+ const struct entry_h *eh = entry_h_consistent_NSEC(val);
+ if (!eh) {
+ /* This might be just finding something else than NSEC3 entry,
+ * in case we searched before the very first one in the zone. */
+ return "range search found inconsistent entry";
+ }
+ /* Passing just zone name instead of owner. */
+ int32_t new_ttl_ = get_new_ttl(eh, qry, k->zname, KNOT_RRTYPE_NSEC3,
+ qry->timestamp.tv_sec);
+ if (new_ttl_ < 0 || !kr_rank_test(eh->rank, KR_RANK_SECURE)) {
+ return "range search found stale or insecure entry";
+ /* TODO: remove the stale record *and* retry,
+ * in case we haven't run off. Perhaps start by in_zone check. */
+ }
+ if (new_ttl) {
+ *new_ttl = new_ttl_;
+ }
+ if (hash_low) {
+ *hash_low = (uint8_t *)key_found.data + hash_off;
+ }
+ if (is_exact) {
+ /* Nothing else to do. */
+ return NULL;
+ }
+ /* The NSEC3 starts strictly before our target name;
+ * now check that it still belongs into that zone and chain. */
+ const uint8_t *nsec_p_raw = eh->data + KR_CACHE_RR_COUNT_SIZE
+ + 2 /* RDLENGTH from rfc1034 */;
+ const int nsec_p_len = nsec_p_rdlen(nsec_p_raw);
+ const bool same_chain = key_found.len == hash_off + NSEC3_HASH_LEN
+ /* CACHE_KEY_DEF */
+ && memcmp(key.data, key_found.data, hash_off) == 0
+ /* exact comparison of NSEC3 parameters */
+ && nsec_p_len == nsec_p_rdlen(nsec_p->raw)
+ && memcmp(nsec_p_raw, nsec_p->raw, nsec_p_len) == 0;
+ if (!same_chain) {
+ return "range search miss (!same_chain)";
+ }
+ /* We know it starts before sname, so let's check the other end.
+ * A. find the next hash and check its length. */
+ if (kr_fails_assert(KR_CACHE_RR_COUNT_SIZE == 2 && get_uint16(eh->data) != 0))
+ return "ERROR"; /* TODO: more checks? Also, `next` computation is kinda messy. */
+ const uint8_t *hash_next = nsec_p_raw + nsec_p_len
+ + sizeof(uint8_t) /* hash length from rfc5155 */;
+ if (hash_next[-1] != NSEC3_HASH_LEN) {
+ return "unexpected next hash length";
+ }
+ /* B. do the actual range check. */
+ const uint8_t * const hash_searched = (uint8_t *)key.data + hash_off;
+ bool covers = /* we know for sure that the low end is before the searched name */
+ nsec3_hash_ordered(hash_searched, hash_next)
+ /* and the wrap-around case */
+ || nsec3_hash_ordered(hash_next, (const uint8_t *)key_found.data + hash_off);
+ if (!covers) {
+ return "range search miss (!covers)";
+ }
+ return NULL;
+}
+
+/** Extract textual representation of NSEC3 hash from a cache key.
+ * \param text must have length at least NSEC3_HASH_TXT_LEN+1 (will get 0-terminated). */
+static void key_NSEC3_hash2text(const knot_db_val_t key, char *text)
+{
+ kr_require(key.data && key.len > NSEC3_HASH_LEN);
+ const uint8_t *hash_raw = knot_db_val_bound(key) - NSEC3_HASH_LEN;
+ /* CACHE_KEY_DEF ^^ */
+ int len = base32hex_encode(hash_raw, NSEC3_HASH_LEN, (uint8_t *)text,
+ NSEC3_HASH_TXT_LEN);
+ kr_assert(len == NSEC3_HASH_TXT_LEN);
+ text[NSEC3_HASH_TXT_LEN] = '\0';
+}
+
+/** Reconstruct a name into a buffer (assuming length at least KNOT_DNAME_MAXLEN).
+ * \return kr_ok() or error code (<0). */
+static int dname_wire_reconstruct(knot_dname_t *buf, const knot_dname_t *zname,
+ const uint8_t *hash_raw)
+{
+ int len = base32hex_encode(hash_raw, NSEC3_HASH_LEN, buf + 1, NSEC3_HASH_TXT_LEN);
+ if (kr_fails_assert(len == NSEC3_HASH_TXT_LEN))
+ return kr_error(EINVAL);
+ buf[0] = len;
+ int ret = knot_dname_to_wire(buf + 1 + len, zname, KNOT_DNAME_MAXLEN - 1 - len);
+ return ret < 0 ? kr_error(ret) : kr_ok();
+}
+
+static void nsec3_hash2text(const knot_dname_t *owner, char *text)
+{
+ kr_require(owner[0] == NSEC3_HASH_TXT_LEN);
+ memcpy(text, owner + 1, MIN(owner[0], NSEC3_HASH_TXT_LEN));
+ text[NSEC3_HASH_TXT_LEN] = '\0';
+}
+
+int nsec3_encloser(struct key *k, struct answer *ans,
+ const int sname_labels, int *clencl_labels,
+ const struct kr_query *qry, struct kr_cache *cache)
+{
+ static const int ESKIP = ABS(ENOENT);
+ /* Basic sanity check. */
+ const bool ok = k && k->zname && ans && clencl_labels
+ && qry && cache;
+ if (kr_fails_assert(ok))
+ return kr_error(EINVAL);
+
+ /*** Find the closest encloser - cycle: name starting at sname,
+ * proceeding while longer than zname, shortening by one label on step.
+ * We need a pair where a name doesn't exist *and* its parent does. */
+ /* LATER(optim.): perhaps iterate in the other order - that
+ * should help significantly against deep queries where we have
+ * a shallow proof in the cache. We can also optimize by using
+ * only exact search unless we had a match in the previous iteration. */
+ const int zname_labels = knot_dname_labels(k->zname, NULL);
+ int last_nxproven_labels = -1;
+ const knot_dname_t *name = qry->sname;
+ for (int name_labels = sname_labels; name_labels >= zname_labels;
+ --name_labels, name += 1 + name[0]) {
+ /* Find a previous-or-equal NSEC3 in cache covering the name,
+ * checking TTL etc. */
+ const knot_db_val_t key = key_NSEC3_name(k, name, false, &ans->nsec_p);
+ if (!key.data) continue;
+ WITH_VERBOSE(qry) {
+ char hash_txt[NSEC3_HASH_TXT_LEN + 1];
+ key_NSEC3_hash2text(key, hash_txt);
+ VERBOSE_MSG(qry, "=> NSEC3 depth %d: hash %s\n",
+ name_labels - zname_labels, hash_txt);
+ }
+ knot_db_val_t val = { NULL, 0 };
+ bool exact_match;
+ uint32_t new_ttl;
+ const uint8_t *hash_low;
+ const char *err = find_leq_NSEC3(cache, qry, key, k, &ans->nsec_p, &val,
+ &exact_match, &hash_low, &new_ttl);
+ if (err) {
+ WITH_VERBOSE(qry) {
+ auto_free char *name_str = kr_dname_text(name);
+ VERBOSE_MSG(qry, "=> NSEC3 encloser error for %s: %s\n",
+ name_str, err);
+ }
+ continue;
+ }
+ if (exact_match && name_labels != sname_labels
+ && name_labels + 1 != last_nxproven_labels) {
+ /* This name exists (checked rank and TTL), and it's
+ * neither of the two interesting cases, so we do not
+ * keep searching for non-existence above this name. */
+ VERBOSE_MSG(qry,
+ "=> NSEC3 encloser: only found existence of an ancestor\n");
+ return ESKIP;
+ }
+ /* Optimization: avoid the rest of the last iteration if pointless. */
+ if (!exact_match && name_labels == zname_labels
+ && last_nxproven_labels != name_labels + 1) {
+ break;
+ }
+
+ /* Basic checks OK -> materialize data, cleaning any previous
+ * records on that answer index (unsuccessful attempts). */
+ knot_dname_t owner[KNOT_DNAME_MAXLEN];
+ {
+ int ret = dname_wire_reconstruct(owner, k->zname, hash_low);
+ if (unlikely(ret)) continue;
+ }
+ const int ans_id = (exact_match && name_labels + 1 == last_nxproven_labels)
+ ? AR_CPE : AR_NSEC;
+ {
+ const struct entry_h *nsec_eh = val.data;
+ memset(&ans->rrsets[ans_id], 0, sizeof(ans->rrsets[ans_id]));
+ int ret = entry2answer(ans, ans_id, nsec_eh, knot_db_val_bound(val),
+ owner, KNOT_RRTYPE_NSEC3, new_ttl);
+ if (ret) return kr_error(ret);
+ }
+
+ if (!exact_match) {
+ /* Non-existence proven, but we don't know if `name`
+ * is the next closer name.
+ * Note: we don't need to check for the sname being
+ * delegated away by this record, as with NSEC3 only
+ * *exact* match on an ancestor could do that. */
+ last_nxproven_labels = name_labels;
+ WITH_VERBOSE(qry) {
+ char hash_low_txt[NSEC3_HASH_TXT_LEN + 1];
+ nsec3_hash2text(owner, hash_low_txt);
+ VERBOSE_MSG(qry,
+ "=> NSEC3 depth %d: covered by %s -> TODO, new TTL %d\n",
+ name_labels - zname_labels, hash_low_txt, new_ttl);
+ }
+ continue;
+ }
+
+ /* Exactly matched NSEC3: two cases, one after another. */
+ const knot_rrset_t *nsec_rr = ans->rrsets[ans_id].set.rr;
+ const uint8_t *bm = knot_nsec3_bitmap(nsec_rr->rrs.rdata);
+ uint16_t bm_size = knot_nsec3_bitmap_len(nsec_rr->rrs.rdata);
+ if (kr_fails_assert(bm))
+ return kr_error(EFAULT);
+ if (name_labels == sname_labels) {
+ if (kr_nsec_bitmap_nodata_check(bm, bm_size, qry->stype,
+ nsec_rr->owner) != 0) {
+ VERBOSE_MSG(qry,
+ "=> NSEC3 sname: match but failed type check\n");
+ return ESKIP;
+ }
+ /* NODATA proven; just need to add SOA+RRSIG later */
+ VERBOSE_MSG(qry,
+ "=> NSEC3 sname: match proved NODATA, new TTL %d\n",
+ new_ttl);
+ ans->rcode = PKT_NODATA;
+ return kr_ok();
+
+ } /* else */
+
+ if (kr_fails_assert(name_labels + 1 == last_nxproven_labels))
+ return kr_error(EINVAL);
+ if (kr_nsec_children_in_zone_check(bm, bm_size) != 0) {
+ VERBOSE_MSG(qry,
+ "=> NSEC3 encloser: found but delegated (or error)\n");
+ return ESKIP;
+ }
+ /* NXDOMAIN proven *except* for wildcards. */
+ WITH_VERBOSE(qry) {
+ auto_free char *name_str = kr_dname_text(name);
+ VERBOSE_MSG(qry,
+ "=> NSEC3 encloser: confirmed as %s, new TTL %d\n",
+ name_str, new_ttl);
+ }
+ *clencl_labels = name_labels;
+ ans->rcode = PKT_NXDOMAIN;
+ /* Avoid repeated NSEC3 - remove either if the hashes match.
+ * This is very unlikely in larger zones: 1/size (per attempt).
+ * Well, deduplication would happen anyway when the answer
+ * from cache is read by kresd (internally). */
+ if (unlikely(0 == memcmp(ans->rrsets[AR_NSEC].set.rr->owner + 1,
+ ans->rrsets[AR_CPE ].set.rr->owner + 1,
+ NSEC3_HASH_LEN))) {
+ memset(&ans->rrsets[AR_CPE], 0, sizeof(ans->rrsets[AR_CPE]));
+ /* LATER(optim.): perhaps check this earlier and avoid some work? */
+ }
+ return kr_ok();
+ }
+
+ /* We've ran out of options. */
+ if (last_nxproven_labels > 0) {
+ /* We didn't manage to prove existence of the closest encloser,
+ * meaning the only chance left is a *positive* wildcard record. */
+ *clencl_labels = last_nxproven_labels - 1;
+ ans->rcode = PKT_NXDOMAIN;
+ /* FIXME: review */
+ }
+ return ESKIP;
+}
+
+int nsec3_src_synth(struct key *k, struct answer *ans, const knot_dname_t *clencl_name,
+ const struct kr_query *qry, struct kr_cache *cache)
+{
+ /* Find a previous-or-equal NSEC3 in cache covering or matching
+ * the source of synthesis, checking TTL etc. */
+ const knot_db_val_t key = key_NSEC3_name(k, clencl_name, true, &ans->nsec_p);
+ if (!key.data) return kr_error(1);
+ WITH_VERBOSE(qry) {
+ char hash_txt[NSEC3_HASH_TXT_LEN + 1];
+ key_NSEC3_hash2text(key, hash_txt);
+ VERBOSE_MSG(qry, "=> NSEC3 wildcard: hash %s\n", hash_txt);
+ }
+ knot_db_val_t val = { NULL, 0 };
+ bool exact_match;
+ uint32_t new_ttl;
+ const uint8_t *hash_low;
+ const char *err = find_leq_NSEC3(cache, qry, key, k, &ans->nsec_p, &val,
+ &exact_match, &hash_low, &new_ttl);
+ if (err) {
+ VERBOSE_MSG(qry, "=> NSEC3 wildcard: %s\n", err);
+ return kr_ok();
+ }
+
+ /* LATER(optim.): avoid duplicities in answer. */
+
+ /* Basic checks OK -> materialize the data (speculatively). */
+ knot_dname_t owner[KNOT_DNAME_MAXLEN];
+ {
+ int ret = dname_wire_reconstruct(owner, k->zname, hash_low);
+ if (unlikely(ret)) return kr_ok();
+ const struct entry_h *nsec_eh = val.data;
+ ret = entry2answer(ans, AR_WILD, nsec_eh, knot_db_val_bound(val),
+ owner, KNOT_RRTYPE_NSEC3, new_ttl);
+ if (ret) return kr_error(ret);
+ }
+ const knot_rrset_t *nsec_rr = ans->rrsets[AR_WILD].set.rr;
+
+ if (!exact_match) {
+ /* The record proves wildcard non-existence. */
+ WITH_VERBOSE(qry) {
+ char hash_low_txt[NSEC3_HASH_TXT_LEN + 1];
+ nsec3_hash2text(owner, hash_low_txt);
+ VERBOSE_MSG(qry,
+ "=> NSEC3 wildcard: covered by %s -> TODO, new TTL %d\n",
+ hash_low_txt, new_ttl);
+ }
+ return AR_SOA;
+ }
+
+ /* The wildcard exists. Find if it's NODATA - check type bitmap. */
+ const uint8_t *bm = knot_nsec3_bitmap(nsec_rr->rrs.rdata);
+ uint16_t bm_size = knot_nsec3_bitmap_len(nsec_rr->rrs.rdata);
+ if (kr_fails_assert(bm))
+ return kr_error(EFAULT);
+ if (kr_nsec_bitmap_nodata_check(bm, bm_size, qry->stype, nsec_rr->owner) == 0) {
+ /* NODATA proven; just need to add SOA+RRSIG later */
+ VERBOSE_MSG(qry, "=> NSEC3 wildcard: match proved NODATA, new TTL %d\n",
+ new_ttl);
+ ans->rcode = PKT_NODATA;
+ return AR_SOA;
+
+ } /* else */
+ /* The data probably exists -> don't add this NSEC3
+ * and (later) try to find the real wildcard data */
+ VERBOSE_MSG(qry, "=> NSEC3 wildcard: should exist (or error)\n");
+ ans->rcode = PKT_NOERROR;
+ memset(&ans->rrsets[AR_WILD], 0, sizeof(ans->rrsets[AR_WILD]));
+ return kr_ok();
+}
+
diff --git a/lib/cache/overflow.test.integr/deckard.yaml b/lib/cache/overflow.test.integr/deckard.yaml
new file mode 100644
index 0000000..61032fb
--- /dev/null
+++ b/lib/cache/overflow.test.integr/deckard.yaml
@@ -0,0 +1,22 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+programs:
+- name: kresd1
+ binary: kresd
+ additional:
+ - -n
+ templates:
+ - lib/cache/overflow.test.integr/kresd_config.j2
+ - tests/config/test_dns_generators.lua
+ configs:
+ - config
+ - dns_gen.lua
+- name: kresd2
+ binary: kresd
+ additional:
+ - -n
+ templates:
+ - lib/cache/overflow.test.integr/kresd_config.j2
+ - tests/config/test_dns_generators.lua
+ configs:
+ - config
+ - dns_gen.lua
diff --git a/lib/cache/overflow.test.integr/kresd_config.j2 b/lib/cache/overflow.test.integr/kresd_config.j2
new file mode 100644
index 0000000..63841ff
--- /dev/null
+++ b/lib/cache/overflow.test.integr/kresd_config.j2
@@ -0,0 +1,91 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+
+trust_anchors.remove('.')
+{% for TAF in TRUST_ANCHOR_FILES %}
+trust_anchors.add_file('{{TAF}}')
+{% endfor %}
+
+modules.load("hints")
+hints.root({['{{ROOT_NAME}}'] = '{{ROOT_ADDR}}'})
+
+{% raw %}
+-- Disable RFC5011 TA update
+if ta_update then
+ modules.unload('ta_update')
+end
+
+-- Disable RFC8145 signaling, scenario doesn't provide expected answers
+if ta_signal_query then
+ modules.unload('ta_signal_query')
+end
+
+-- Disable RFC8109 priming, scenario doesn't provide expected answers
+if priming then
+ modules.unload('priming')
+end
+
+-- Disable this module because it make one priming query
+if detect_time_skew then
+ modules.unload('detect_time_skew')
+end
+
+log_level('debug')
+policy.add(policy.all(policy.DEBUG_ALWAYS))
+
+cache.open(1*MB)
+
+{% endraw %}
+
+{% if DO_IP6 == "true" %}
+net.ipv6 = true
+{% else %}
+net.ipv6 = false
+{% endif %}
+
+{% if DO_IP4 == "true" %}
+net.ipv4 = true
+{% else %}
+net.ipv4 = false
+{% endif %}
+
+-- both instances listen on both addresses
+-- so queries get distributed between them randomly
+net.listen('{{programs[0]["address"]}}')
+net.listen('{{programs[1]["address"]}}')
+
+{% raw %}
+-- Self-checks on globals
+assert(help() ~= nil)
+assert(worker.id ~= nil)
+-- Self-checks on facilities
+assert(cache.stats() ~= nil)
+assert(cache.backends() ~= nil)
+assert(worker.stats() ~= nil)
+assert(net.interfaces() ~= nil)
+-- Self-checks on loaded stuff
+{% endraw %}
+
+assert(net.list()[1].transport.ip == '{{programs[0]["address"]}}')
+
+{% raw %}
+assert(#modules.list() > 0)
+-- Self-check timers
+ev = event.recurrent(1 * sec, function (ev) return 1 end)
+event.cancel(ev)
+ev = event.after(0, function (ev) return 1 end)
+
+local ffi = require('ffi')
+local kr_cach = kres.context().cache
+
+-- canary for cache overflow
+local kr_rrset = kres.rrset(
+ todname('www.example.com'),
+ kres.type.A,
+ kres.class.IN,
+ 604800)
+assert(kr_rrset:add_rdata('\192\000\002\001', 4))
+assert(kr_cach:insert(kr_rrset, nil, ffi.C.KR_RANK_SECURE))
+
+local generators = dofile('./dns_gen.lua')
+event.after(0, generators.gen_batch)
+{% endraw %}
diff --git a/lib/cache/overflow.test.integr/world_cz_vutbr_www.rpl b/lib/cache/overflow.test.integr/world_cz_vutbr_www.rpl
new file mode 100644
index 0000000..eddfbd0
--- /dev/null
+++ b/lib/cache/overflow.test.integr/world_cz_vutbr_www.rpl
@@ -0,0 +1,298 @@
+do-ip4: no
+
+; test with real world Internet data
+; attempt to resolve www.vutbr.cz. A leads to CNAME piranha.ro.vutbr.cz.
+; sub-trees vutbr.cz and ro.vutbr.cz. are in separate zones
+; hosted on the same servers with different DNSKEYs
+
+val-override-date: 20170124180319
+trust-anchor: ". 172800 IN DS 19036 8 2 49aac11d7b6f6446702e54a1607371607a1a41855200fd2ce1cdde32f24e8fb5"
+stub-addr: 2001:dc3::35
+CONFIG_END
+
+SCENARIO_BEGIN www.vutbr.cz. CNAME kresd issue #130
+
+; DNS root ; M.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 2001:dc3::35
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA DO NOERROR
+SECTION QUESTION
+. IN DNSKEY
+SECTION ANSWER
+. 16567 IN DNSKEY 257 3 8 AwEAAagAIKlVZrpC6Ia7gEzahOR+9W29euxhJhVVLOyQbSEW0O8gcCjF FVQUTf6v58fLjwBd0YI0EzrAcQqBGCzh/RStIoO8g0NfnfL2MTJRkxoX bfDaUeVPQuYEhg37NZWAJQ9VnMVDxP/VHL496M/QZxkjf5/Efucp2gaD X6RS6CXpoY68LsvPVjR0ZSwzz1apAzvN9dlzEheX7ICJBBtuA6G3LQpz W5hOA2hzCTMjJPJ8LbqF6dsV6DoBQzgul0sGIcGOYl7OyQdXfZ57relS Qageu+ipAdTTJ25AsRTAoub8ONGcLmqrAmRLKBP1dfwhYB4N7knNnulq QxA+Uk1ihz0=
+. 16567 IN DNSKEY 256 3 8 AwEAAYvgWbYkpeGgdPKaKTJU3Us4YSTRgy7+dzvfArIhi2tKoZ/WR1Df w883SOU6Uw7tpVRkLarN0oIMK/xbOBD1DcXnyfElBwKsz4sVVWmfyr/x +igD/UjrcJ5zEBUrUmVtHyjar7ccaVc1/3ntkhZjI1hcungAlOhPhHlk MeX+5Azx6GdX//An5OgrdyH3o/JmOPMDX1mt806JI/hf0EwAp1pBwo5e 8SrSuR1tD3sgNjr6IzCdrKSgqi92z49zcdis3EaY199WFW60DCS7ydu+ +T5Xa+GyOw1quagwf/JUC/mEpeBQYWrnpkBbpDB3sy4+P2i8iCvavehb RyVm9U0MlIc=
+. 16567 IN RRSIG DNSKEY 8 0 172800 20170201000000 20170111000000 19036 . Sh+EpofvZgk3J9szMD2B94FxFgyIUKz3hkbCjgWSTqPQyhqNgqVU8QlS EtOo8YLmS4AX98eit5Gmmb2ObpkGoXBmAzu5w/Qt5WsGsWzLQhYrsy9s lDmFQ2JKUoCyfdwqhlJ8VxjzdFdMUiVl+/GPnv4yjxjM8Ke3VAtBkn6n BO7JkcxxOfcgZdZ4MuvSr40K/SenZE+JlLLL1LF4TMCGqaZTTdOx6kFF KSSgy2AS884htWcK0tnwRc630g6nAI2wdvjlRLBeisbfXanI4v8iiPyT FnMmnV7wJGWJ4gtRJ0UH3u5RWXUPZ+s1tKytk3slXbLyQ9xkEDveuD+h b659gQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR DO NOERROR
+SECTION QUESTION
+cz. IN NS
+SECTION AUTHORITY
+cz. 172800 IN NS d.ns.nic.cz.
+cz. 172800 IN NS a.ns.nic.cz.
+cz. 172800 IN NS c.ns.nic.cz.
+cz. 172800 IN NS b.ns.nic.cz.
+cz. 86400 IN DS 54576 10 2 397E50C85EDE9CDE33F363A9E66FD1B216D788F8DD438A57A423A386 869C8F06
+cz. 86400 IN RRSIG DS 8 1 86400 20170202170000 20170120160000 61045 . ig2BBmA1kOuTqhVogqLciH40Ina7BCrG/fcaNARSWoaFHGOcC/7KsBZO uMttn/hKDJkH3RPsed2Oswl9bXZ+zrhjeXluUqC0zmsUJDBkS+AkiFJL HCpMSIZaXu/w1ZMADGfyQXl7XWCRbl+eyXi2eTG0SdLtRHNhm3CGJP3C xjzVuOTr9oPEyL0U81jhhlJPCFe8xDD441wLLzpEuVX8VP9N2S1QnIjO BhCEE9OTkPgpS7fMPEl0Yq2gfpRl+DCw1Dd0VB3Hh5M3hmrXuFqNYZQK b0JqDFGYhzvcpUs3EiB9IG7rJt51n6pxCTek1M2w+s6mLYzawVfq+b1Q uQD98A==
+SECTION ADDITIONAL
+a.ns.nic.cz. 172800 IN A 194.0.12.1
+b.ns.nic.cz. 172800 IN A 194.0.13.1
+c.ns.nic.cz. 172800 IN A 194.0.14.1
+d.ns.nic.cz. 172800 IN A 193.29.206.1
+a.ns.nic.cz. 172800 IN AAAA 2001:678:f::1
+b.ns.nic.cz. 172800 IN AAAA 2001:678:10::1
+c.ns.nic.cz. 172800 IN AAAA 2001:678:11::1
+d.ns.nic.cz. 172800 IN AAAA 2001:678:1::1
+ENTRY_END
+; end of M.ROOT-SERVERS.NET.
+RANGE_END
+
+
+; domains: cz. ; ?.ns.nic.cz.
+RANGE_BEGIN 0 100
+ ADDRESS 194.0.12.1
+ ADDRESS 194.0.13.1
+ ADDRESS 194.0.14.1
+ ADDRESS 193.29.206.1
+ ADDRESS 2001:678:f::1
+ ADDRESS 2001:678:10::1
+ ADDRESS 2001:678:11::1
+ ADDRESS 2001:678:1::1
+
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+cz. IN DNSKEY
+SECTION ANSWER
+cz. 18000 IN DNSKEY 256 3 10 AwEAAc9e2YFnG56xtTXu42GLGAkwsrFOBBwOZphNat7HQdBmfi0CbmDf oywCUsaSkObNmm+Zu9MYLNJDHsD+vxsZbtHClpYaSEhMEmHrbnj0BMPV A6hwY6YDGFhKudJ62RmB/rmhQ3iwmICsEdRn2w5fu1rHZv8UJOUMkeWd 6GA48mW3
+cz. 18000 IN DNSKEY 256 3 10 AwEAAdWL2Br92Vx0dLEOOB8y02ss8LtKIyGlLJ2ymJ02WqR3AAEEZN0f NPKF77kdKsjlG8DlzmSIOR12aa9EhpXqyHOwWI0kHOMJVnn6ZKFIAl71 JP/dYIcshYUxKZZMe+zEAUrVtzlLVDtM6cDOPDuBNa1ujYec3eJl9Ipq eUEG6gAH
+cz. 18000 IN DNSKEY 257 3 10 AwEAAay0hi4HN2r/BqMQTpIPIVDyjmyF+9ZWvr5Lewx+q+947o/GrRv4 FGFfkZxf9CFfYVUf0jG5Yq4i06pGVNwJl81HS9Ux2oeHRXUvgtLnl5He RVLL+zgI5byx9HSNr4bPO8ZEn5OjoayhkNyGSFr4VWrzQk/K02vLP4d1 cCEzUQy30eyZto2/tG5ZwCU/iRkS1PJOcOW98hiFIfFDZv1XjbEpqEYh T2PATs6rt+BKwSHKGISmg1PNdg+y0rItemYMWr1f9BGAdtTWoPCPCYPj OZMPoIyA4tMscD+ww54Jf/QNoHccY4hO1yHiuAXG7SUn8jo0IKQ9W7JJ xES0aqFCX/0=
+cz. 18000 IN RRSIG DNSKEY 10 1 18000 20170127000000 20170120000000 54576 cz. Fdl//hMdLoZq8//gLt/+3a7LfWqB5/psW9YR3AWNPQGfvrEAcKRBcah+ ikbSCmpAZ6j834xZP1zPd5xMoN33PGXf23iqcgjHvUn50Uq48KRBVYwU H885xNJBl/Po0N8STeG0WNZz2mbUbBbPCGN7CI5yl08usvqOvf2fV8+D 0m//+Fa1cWaqMXpHc6OnhWZ+BN4VdcxxwNbGhH2TZxyiGEMMscEGoIxn yL1pVY8T93LOMwQmuFJ71f8Scij3vYouW/mNuEma/UUZM1bEn8vR1UrP /6JTGPGTG+snHvCxiVtAxCNnqoIJDD+xuonpZLeKN5XU7UDMZPDTtSgX vtzjww==
+cz. 18000 IN RRSIG DNSKEY 10 1 18000 20170205002523 20170123080953 58211 cz. MZ6KTtQisTde4iOBH6oasl7bVrRM5ly7Yxdv2l+2gk1YYk4zX6L3m6oB P26SKi+fj8pM77775bRK7uCI9FlyqXa3MJclLU/GmnRANm6T4sSdz0zs F3FK4UfUmHnzdnWXWTnueDfIZr44yF1y1+4I3E96/9/nEYGO+xsifvIj iks=
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR DO NOERROR
+SECTION QUESTION
+vutbr.cz. IN NS
+SECTION AUTHORITY
+vutbr.cz. 18000 IN NS pipit.cis.vutbr.cz.
+vutbr.cz. 18000 IN NS rhino.cis.vutbr.cz.
+vutbr.cz. 18000 IN DS 5512 5 2 78510F9433A4D536A5B9099193E9D58EE5B5CF71F14D983B4DA2EB16 29CFA1E9
+vutbr.cz. 18000 IN RRSIG DS 10 2 18000 20170204213601 20170123080953 58211 cz. lXNBswz/r/1NY7VQq+BlisC+1yqFmUBIaF30L8XDAbiHLcj/AIj0dEy6 PlBlkEeDAi4W9DvR0jo9LjHvFFJLs54cuEEd3pHTdlw8x0dLd1X7Zkh7 cezfAt2EEqdux/ce/sc86lUKOpLnDtry2piWwVf2EqFg9NlW4cHTm78U gsY=
+SECTION ADDITIONAL
+pipit.cis.vutbr.cz. 18000 IN A 77.93.219.110
+rhino.cis.vutbr.cz. 18000 IN A 147.229.3.10
+pipit.cis.vutbr.cz. 18000 IN AAAA 2a01:430:120::4d5d:db6e
+rhino.cis.vutbr.cz. 18000 IN AAAA 2001:67c:1220:e000::93e5:30a
+ENTRY_END
+
+; end of domain cz.: servers ?.ns.nic.cz.
+RANGE_END
+
+
+; domains: vutbr.cz. + ro.vutbr.cz.
+; servers: pipit.cis.vutbr.cz. + rhino.cis.vutbr.cz. + shark.ro.vutbr.cz.
+; shark.ro.vutbr.cz. in fact serves both domains but is listed only in ro.vutbr.cz NS
+RANGE_BEGIN 0 100
+ ADDRESS 77.93.219.110
+ ADDRESS 147.229.3.10
+ ADDRESS 147.229.2.59
+ ADDRESS 2a01:430:120::4d5d:db6e
+ ADDRESS 2001:67c:1220:e000::93e5:30a
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA DO
+SECTION QUESTION
+vutbr.cz. IN NS
+SECTION ANSWER
+vutbr.cz. 28800 IN NS rhino.cis.vutbr.cz.
+vutbr.cz. 28800 IN NS pipit.cis.vutbr.cz.
+vutbr.cz. 28800 IN RRSIG NS 5 2 28800 20170216060902 20170117060902 39756 vutbr.cz. y6Jj5vfvdlLeecB/++/qyhjCzfnFJyY1sX1Ja+wV0ulq3laeCVV7ICXh PKG+CjHUu/nDOrzT9QJP4qxYDCANneI0yxI82XKhhoTN5O/TxyWH/DyT k8JarRoMooHv2RwKd8jtLIxvj1SaJ+AvlP0pOPraaVgbHtn1SJ4ubxQD cFc=
+SECTION ADDITIONAL
+pipit.cis.vutbr.cz. 86400 IN A 77.93.219.110
+pipit.cis.vutbr.cz. 86400 IN AAAA 2a01:430:120::4d5d:db6e
+rhino.cis.vutbr.cz. 86400 IN A 147.229.3.10
+rhino.cis.vutbr.cz. 86400 IN AAAA 2001:67c:1220:e000::93e5:30a
+pipit.cis.vutbr.cz. 86400 IN RRSIG A 5 4 86400 20170204080646 20170105080646 28257 cis.vutbr.cz. Cz9etHnEOQTzu+6rYJEqx/SQ1tQgPOCyf8HSj4KOsx89jtgiHNC6pep6 ZE0SphMGAs3jC/uGIhlaFNZ3i38OQIMuqwacbz+XZyW5bByvV3QZrhqh dFxMDfmPuNiCAT3crFpUkvVW1OE3YfGHzZGXX7JP5wb1b8A3X6Qih7fV +nQ=
+pipit.cis.vutbr.cz. 86400 IN RRSIG AAAA 5 4 86400 20170204080646 20170105080646 28257 cis.vutbr.cz. piafjh6my2fooZRrzwCu9RQ95gYaMQkhIkDaGX/fT6wXzSdmgFZkS1Nl EMIKdDCQaPrLGMG3p32ptMkAm4esPekeyNtLSMBtXwZyUkgEGn6h1QM2 Yr3TOo8cixfk5nmRRdlYadf5krLb8yI9exiqeymgEQLa1YNRz/bWArlX bn8=
+rhino.cis.vutbr.cz. 86400 IN RRSIG A 5 4 86400 20170204080646 20170105080646 28257 cis.vutbr.cz. X/tDf8e3JEV0LxiItfpQnBzeaRIq693VG8d30iCH4/1I0uqyCfxboWmm /CBpn9A8MCJu9NEEv+4+povNlfUfqi2yjsqJEVj8ztHxD4g9cc284Cv6 ySjxrSZ9axVqoaopEXujiTwwWJUFcgF6pxqyXVksW7sgKJrboM4VSlQD +Sw=
+rhino.cis.vutbr.cz. 86400 IN RRSIG AAAA 5 4 86400 20170204080646 20170105080646 28257 cis.vutbr.cz. T3Yf5PAkSeJtoOH90ea9zZBG9FC3iFhiCSerDn6d9up8GRfzxDsavYJC zQu+3vnOySySn+3TMzQSSFcWdJC2iO7ulaDGr177Gof9QJbKSVSMW7jt YDE2f4/R4Go3NZVwjk/HfpCInoR6pHNA1s/9hMnWtiVopmBdfzyd3/sW YOU=
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA DO
+SECTION QUESTION
+vutbr.cz. IN DNSKEY
+SECTION ANSWER
+vutbr.cz. 28800 IN DNSKEY 256 3 5 AwEAAfwRRuGjpt9v4fzuIWFA9MtGfxDrIKhoFA7DNq6B+iCOoQb6t0HZ I9lGDUSR5DRswDGP569NJ/uVD4tJxGnaK2SBQVxIu+bEP1Ouzk+O43iO 8odw50NBWetljjNDP32B3zHpgJRpxyEqzDQaQ6B4Zer6sDZm9wo5SVJe r9LjJV9p
+vutbr.cz. 28800 IN DNSKEY 257 3 5 AwEAAfhR+s/4SLZZNA+kD2u1UgYBUu+X3Avi60QCaE1o2STterM405s8 mWMWJOlZGtjjIky3TEMxQ0+ZtMbEeJu2wNDLdV/XglX+pJAjyy728WJH 4u2/gJR8ZWsEIc0Jwb4FjwmBiF2Koz0SGVvrzEZ9T1H7dHq2X6f8KzYB otJyrAIWr9tZi/9tHrngZJ5wXELmMPWCfEFapdQMoKWoNvzrMYFli17R Mz7gJzCmNxMRV8/WkjsNPgYsTKpsAT8qEsXiTN9987AIKPHvc5j+/njq +fTXdOqGVpIgSiso+qJMddEMBcu/MBBYVFOwRQe1ez2tMwIX7y5mwDvK 0wsmyRvHugfFuxSnfiJvQr05kSnj0wxD9s9LNhrF4PocrcYqnBN/lBx9 D6633jJ3zT3T5Foe/Vj9A/X7F2oN6FOkdwO+YSEUot980pJQut6DR22U P4bLakyDMiTdOQ31c/dRIoTsccxw+838pXFyEPgiqOHRSeN/w9km6BID cl+32Xq97kXSMQH6AxOUsx9/Mxdj7ISwbS4utaAWoP460+TMcnfJfWfB NEWhuFvnfB9l63ZjZToB2PUVhrTxRwKUlfMLegSJKoZfiae82kK1pN4x FYyquKSykm/oXsM2w4OQvpqGcTwAXzZ5s95J45f7PsCap0bscGKumxsH cDswWpUz/UVosIrr
+vutbr.cz. 28800 IN RRSIG DNSKEY 5 2 28800 20170216060902 20170117060902 5512 vutbr.cz. QHw07MAjA4NFi3On8zaMw/q4IuADXVp4TODfK5PHb8OUIX2Yy+bKLrSX /Cc9ClWUpE69x80F9dFEeRZGJiYOwstNQGQVeq/EKNytm1XmhS8cp3SW CYHBpLjZGPrlhvqPhWd0S4vqPNiD8hDzgFAgaCNfwXDDKXhF2/qtpQ0V pDnytMP6pNPLPMpF2hzaLfCMzABShxcEOAr7+KTbxbffOik4YneG8seu XDtBvCVjP8lJcSU+q+UbotLnjyOgn8vV8pliTNqcvRsJTdtvTlJKHu8B iLkFeCE1DpRhyrVT5zC9NSOcoIv7tau2NE2oUPgtRzK76el6i9L9LcSs G+59j02AINefpAtc6W2khmTnGthibeOy/F9FuFkXUy6AmqIdNszMAj++ 8Mzv3A1OHfsfpIS3tLmC4drhdSHr2ab0Pe0lYQq2a9FSeQzSk6s9gwwZ gMVPVQHbouyvn6BCHaRVDjTV8GPKlk3C8GNaHcHb1hAGSPpw3kqL41dd K92Un4tLIoOYomxUYoyMtyxxwddXyR7ivToUHF7e/yv8MACMEo72N9sf y4zLEqkL1mJ1pCp3csI1bKaaA/c7sqb7PX93iqvoY06k55Pd7kT+lAF1 7QvXGg4U1kDrwytQPyocN8wmsX3//CpWUD07v8fCUqKOcIrVNGnoPmPC PpNe3AtpJoE=
+vutbr.cz. 28800 IN RRSIG DNSKEY 5 2 28800 20170216060902 20170117060902 39756 vutbr.cz. CNDE7Ht7xm8Jo9tuOlJ8N9+vI/Htfpk53MI0HG7B1EZJws/yEV7YFOOL SIAt3rzu1OHjaxr4CG/baqGRPtsaWSBHuLSdSduivxXw8xiQcMKzP6Cz 7xhJkQZxzDJ4oO5L2K2zWHcAJ8lfP1/3NHHoH1p2RATLN5sI7ofQE//W +ck=
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA DO
+SECTION QUESTION
+www.vutbr.cz. IN A
+SECTION ANSWER
+www.vutbr.cz. 300 IN CNAME piranha.ro.vutbr.cz.
+www.vutbr.cz. 300 IN RRSIG CNAME 5 3 300 20170216060902 20170117060902 39756 vutbr.cz. 9B3UC5SOEw1+yKlYlOTINEuNq0Kdglywc5IYJwzeSzQ3ykptzZo3ABSy bYhTqImVkhm/4NFM9/4HWMHPDzTmrWS0mCI/ljCd/oe/PxW/uESvo4P5 EQzlcuH6xBzc1KdEFAJOSmRzFjj3vyK1QN3k/c+1y2oMFOYOR2oOzCw+ MIE=
+piranha.ro.vutbr.cz. 3600 IN A 147.229.2.90
+piranha.ro.vutbr.cz. 3600 IN RRSIG A 5 4 3600 20170222120032 20170123120032 12150 ro.vutbr.cz. Jz8bcAADQjCKTCcF70IK1aHGQlM4ukyN0myABlxoPaqid1mHX5jwR91b kdQmUAh2xDitlgRLbFjbUUgmjSPzQ5Qt7GAFUsVmqxvjbOLZjqHER1dh zmiWO0fDvvP647Osv3RiAP822rNUJcJrUBZU9LmeP05gwIHcpJrhdVBT b7I=
+SECTION AUTHORITY
+ro.vutbr.cz. 86400 IN NS shark.ro.vutbr.cz.
+ro.vutbr.cz. 86400 IN NS rhino.cis.vutbr.cz.
+ro.vutbr.cz. 86400 IN NS pipit.cis.vutbr.cz.
+ro.vutbr.cz. 86400 IN RRSIG NS 5 3 86400 20170222120032 20170123120032 12150 ro.vutbr.cz. HAQ8A+QNsS1WIXdW/fbT3jP+IxObBBvgUmvzsmJBXo8HMtnMAcuCQGmB 2JBQsQethQXsdyLnMK8to/5A9VRkqkAa7edxUoy7SdDi/mzGeLAVhF+5 kXSPD6t1vjiNdnIYAMpiOQbodCGxAnq6jnNyrjEzffdq3qw+5IkFNdG4 7Pw=
+SECTION ADDITIONAL
+rhino.cis.vutbr.cz. 83217 IN A 147.229.3.10
+rhino.cis.vutbr.cz. 83217 IN AAAA 2001:67c:1220:e000::93e5:30a
+shark.ro.vutbr.cz. 3600 IN A 147.229.2.59
+pipit.cis.vutbr.cz. 14794 IN A 77.93.219.110
+pipit.cis.vutbr.cz. 14794 IN AAAA 2a01:430:120::4d5d:db6e
+rhino.cis.vutbr.cz. 83217 IN RRSIG A 5 4 86400 20170204080646 20170105080646 28257 cis.vutbr.cz. X/tDf8e3JEV0LxiItfpQnBzeaRIq693VG8d30iCH4/1I0uqyCfxboWmm /CBpn9A8MCJu9NEEv+4+povNlfUfqi2yjsqJEVj8ztHxD4g9cc284Cv6 ySjxrSZ9axVqoaopEXujiTwwWJUFcgF6pxqyXVksW7sgKJrboM4VSlQD +Sw=
+rhino.cis.vutbr.cz. 83217 IN RRSIG AAAA 5 4 86400 20170204080646 20170105080646 28257 cis.vutbr.cz. T3Yf5PAkSeJtoOH90ea9zZBG9FC3iFhiCSerDn6d9up8GRfzxDsavYJC zQu+3vnOySySn+3TMzQSSFcWdJC2iO7ulaDGr177Gof9QJbKSVSMW7jt YDE2f4/R4Go3NZVwjk/HfpCInoR6pHNA1s/9hMnWtiVopmBdfzyd3/sW YOU=
+shark.ro.vutbr.cz. 3600 IN RRSIG A 5 4 3600 20170222120032 20170123120032 12150 ro.vutbr.cz. SmhgyF48yX/6yH7AdSmGX60NL/xaiKH/oAzB0rnPfQZ6j+UfV57ginVV lj798K9A8jjucUpqE8ua2mZ6/aOhpqlV2iI0CZXG44zOupsCY1/OXBDx YNetBcjoXDQCBQRLLLEUL5FerDVxqT74ngdLdKubwRdrB0TLQlvpBr+F Tc8=
+pipit.cis.vutbr.cz. 85923 IN RRSIG A 5 4 86400 20170204080646 20170105080646 28257 cis.vutbr.cz. Cz9etHnEOQTzu+6rYJEqx/SQ1tQgPOCyf8HSj4KOsx89jtgiHNC6pep6 ZE0SphMGAs3jC/uGIhlaFNZ3i38OQIMuqwacbz+XZyW5bByvV3QZrhqh dFxMDfmPuNiCAT3crFpUkvVW1OE3YfGHzZGXX7JP5wb1b8A3X6Qih7fV +nQ=
+pipit.cis.vutbr.cz. 85923 IN RRSIG AAAA 5 4 86400 20170204080646 20170105080646 28257 cis.vutbr.cz. piafjh6my2fooZRrzwCu9RQ95gYaMQkhIkDaGX/fT6wXzSdmgFZkS1Nl EMIKdDCQaPrLGMG3p32ptMkAm4esPekeyNtLSMBtXwZyUkgEGn6h1QM2 Yr3TOo8cixfk5nmRRdlYadf5krLb8yI9exiqeymgEQLa1YNRz/bWArlX bn8=
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA DO
+SECTION QUESTION
+ro.vutbr.cz. IN NS
+SECTION ANSWER
+ro.vutbr.cz. 86400 IN NS pipit.cis.vutbr.cz.
+ro.vutbr.cz. 86400 IN NS rhino.cis.vutbr.cz.
+ro.vutbr.cz. 86400 IN NS shark.ro.vutbr.cz.
+ro.vutbr.cz. 86400 IN RRSIG NS 5 3 86400 20170222120032 20170123120032 12150 ro.vutbr.cz. HAQ8A+QNsS1WIXdW/fbT3jP+IxObBBvgUmvzsmJBXo8HMtnMAcuCQGmB 2JBQsQethQXsdyLnMK8to/5A9VRkqkAa7edxUoy7SdDi/mzGeLAVhF+5 kXSPD6t1vjiNdnIYAMpiOQbodCGxAnq6jnNyrjEzffdq3qw+5IkFNdG4 7Pw=
+SECTION ADDITIONAL
+rhino.cis.vutbr.cz. 86400 IN A 147.229.3.10
+rhino.cis.vutbr.cz. 86400 IN AAAA 2001:67c:1220:e000::93e5:30a
+shark.ro.vutbr.cz. 3600 IN A 147.229.2.59
+pipit.cis.vutbr.cz. 86400 IN A 77.93.219.110
+pipit.cis.vutbr.cz. 86400 IN AAAA 2a01:430:120::4d5d:db6e
+rhino.cis.vutbr.cz. 86400 IN RRSIG A 5 4 86400 20170204080646 20170105080646 28257 cis.vutbr.cz. X/tDf8e3JEV0LxiItfpQnBzeaRIq693VG8d30iCH4/1I0uqyCfxboWmm /CBpn9A8MCJu9NEEv+4+povNlfUfqi2yjsqJEVj8ztHxD4g9cc284Cv6 ySjxrSZ9axVqoaopEXujiTwwWJUFcgF6pxqyXVksW7sgKJrboM4VSlQD +Sw=
+rhino.cis.vutbr.cz. 86400 IN RRSIG AAAA 5 4 86400 20170204080646 20170105080646 28257 cis.vutbr.cz. T3Yf5PAkSeJtoOH90ea9zZBG9FC3iFhiCSerDn6d9up8GRfzxDsavYJC zQu+3vnOySySn+3TMzQSSFcWdJC2iO7ulaDGr177Gof9QJbKSVSMW7jt YDE2f4/R4Go3NZVwjk/HfpCInoR6pHNA1s/9hMnWtiVopmBdfzyd3/sW YOU=
+shark.ro.vutbr.cz. 3600 IN RRSIG A 5 4 3600 20170222120032 20170123120032 12150 ro.vutbr.cz. SmhgyF48yX/6yH7AdSmGX60NL/xaiKH/oAzB0rnPfQZ6j+UfV57ginVV lj798K9A8jjucUpqE8ua2mZ6/aOhpqlV2iI0CZXG44zOupsCY1/OXBDx YNetBcjoXDQCBQRLLLEUL5FerDVxqT74ngdLdKubwRdrB0TLQlvpBr+F Tc8=
+pipit.cis.vutbr.cz. 86400 IN RRSIG A 5 4 86400 20170204080646 20170105080646 28257 cis.vutbr.cz. Cz9etHnEOQTzu+6rYJEqx/SQ1tQgPOCyf8HSj4KOsx89jtgiHNC6pep6 ZE0SphMGAs3jC/uGIhlaFNZ3i38OQIMuqwacbz+XZyW5bByvV3QZrhqh dFxMDfmPuNiCAT3crFpUkvVW1OE3YfGHzZGXX7JP5wb1b8A3X6Qih7fV +nQ=
+pipit.cis.vutbr.cz. 86400 IN RRSIG AAAA 5 4 86400 20170204080646 20170105080646 28257 cis.vutbr.cz. piafjh6my2fooZRrzwCu9RQ95gYaMQkhIkDaGX/fT6wXzSdmgFZkS1Nl EMIKdDCQaPrLGMG3p32ptMkAm4esPekeyNtLSMBtXwZyUkgEGn6h1QM2 Yr3TOo8cixfk5nmRRdlYadf5krLb8yI9exiqeymgEQLa1YNRz/bWArlX bn8=
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA DO
+SECTION QUESTION
+ro.vutbr.cz. IN DS
+SECTION ANSWER
+ro.vutbr.cz. 28800 IN DS 16627 5 2 1AEE56EAF9D01A51C8C524E55A7FAE0E27207911F0FA6126052CE5B3 39335FC8
+ro.vutbr.cz. 28800 IN DS 16627 5 1 BFDFD0FB1EDFCEBFB9ECB13C93F9CA65755217BA
+ro.vutbr.cz. 28800 IN RRSIG DS 5 3 28800 20170216060902 20170117060902 39756 vutbr.cz. OOJfGI14bRHqeWhRLMOa75pfHo+clR4rMJpvO3PPjmheownqy2awA7u3 xR5FJko7A6e+difoJdAWCMzN7x1qcrd1htOOKOc7wtcb+QC2JH8B/e0G 0gNPw2UKsFL1Qw9HQkSqxyIaCGg3nMLO1hh3AVccZadw2f/jLpAzw5/1 pLA=
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA DO
+SECTION QUESTION
+ro.vutbr.cz. IN DNSKEY
+SECTION ANSWER
+ro.vutbr.cz. 3600 IN DNSKEY 256 3 5 AwEAAb4tyN4pqltB48s1xQS3ZPXnTZJMvgXxiouXU9xtzj4wnhjhZp45 H7ozslWuksrwQWhZ8AASAD5kPFbQRbwpQ7xbEb3xdKHaWCFpyRCTkrqa ZQZQy4gaVqO+oRW42dIQ9K08A/WfvRuRDtw3VWDATp9pUkgpvb1n6+lp 71YK19RX
+ro.vutbr.cz. 3600 IN DNSKEY 257 3 5 AwEAAef6bqTAl94KddNHvit41gw6QBKkiYjUeS+UP58VHybV29RC7sSE +rYmkXabaMOLmoqMQRMepBEaUdM5OoZBWibHrPAbG0Wf+vlMOoWD5+EC 2mCxrUntIlOuS4XpMTh22+l0k1xSPiMGKjY0BDR95Iu3dDezCVl9PkPp tHj/rAnRTH7Q0fH9Mip8sigosd/CmsoY03I0AcZT4z1+XpGsq5Npxwtj 7cz0SRTI/eV5nynNYK+vr6kOfU1fw7p8/wxIfXkks0Xy8ktXa26DFdw1 RoqVlTS1s1diFyF5niCOT6Ei2kAlf0fggZJBypwoK+6J42wwD2OhORX+ lKrhooaN4TU9AcHwgv25XTXhUq4tYh+veazdXNWDjEb3ZyLM8fKERCa9 YtDBFoHM7yFOHbsOhHKMn8F6T2Boi73hU/+wspjL/n8taKevyyygGg+U g4ugo2pTIouAs5DNnv+nUrpctcKZ5nMEUVl+3XBsXplIyz9QEKHWdFzL gyfIZEok8WdYHebcIy1vJrxzqCNw9ixnTn+OK1lwlMToVH1AGpvRKRPo wGSFaIrDyXxKul34j2jEhP9TWRcJqncy166Ueu3c0BKmclM29N8jeWbP 3TqRJ3RRxNj/vk6c/UGmmrHEz8YdNp2L0hv3JgItr2GujCvPApUvLNPW C7DSErQ3JsjV3gah
+ro.vutbr.cz. 3600 IN RRSIG DNSKEY 5 3 3600 20170222120032 20170123120032 12150 ro.vutbr.cz. pN+8YElj24dhtnOQ20sjWxJTjx+FLTMrPms1lWIJKZtp2evQBG5AnAep 6w0QeMUTIh9ter58Dh6wu2IN4uA1h3ThxnSgwLraOChUFBtPTO8h5y8J mAq4KXSfqbEcHzZO/nBAtxSUk7aUz7yWf09xE+iozW3ORRWIXovMYci5 eEw=
+ro.vutbr.cz. 3600 IN RRSIG DNSKEY 5 3 3600 20170222120032 20170123120032 16627 ro.vutbr.cz. DSaIAl+iyToM8+ai9xuRVcRshYyI66XHWkOz0XEbIAwbc8aEMEeFCA91 1vpuBb6H92MXvM8hYsBhZHNIA0ApoIE4bdyEGZY05XN3GYgJ4BEhXJVM RR+inJf+vGGqdlRP6F2sPO+rCqfxWBvSoUFU7DpCpkl7hz2Ex0Clm9C9 YnWgL+tGmAH33s2Y8lTA3hG/0W0NxD5zy1LiyDa8Ls3vV4MC6gVxyloT Capd8FkDL9PmgW0gMRNtIWmc5Hw+j/HRMoy+oRCe8PIfUL/Dpx3iTAH8 iN3wV8apV2uPa0L8QgpixK4Tc87aSainCopVY+NOc5t0HErUzj8i7qA9 J/cRtQvlUzln5vBsrQsVIzIeNV4o8/cM3zFyfdKkHh1tWYKLJKkjfXc5 +7VMvF8PnoHceT/Zr2gCc8tnygRobypzgqy3p69bRJqiT0/eCAgpGusV 1DCOJY0sdiGDZEtpqeINbAgGKAMmmNwjIwYSFowRzdawip1wNd+90RhI +8hvx8Sc5+K5Mom2BF2wGHf/2Kv/ArzyXxqqcNozM61L1AjxIsBHjnLZ TzPlLntmiHUVaqET9Yc3G0K/RdsIpqz4M79N0BX66a58x2a3fLqQdrEC QshZPNxk2S4eCsrVRjHvU4a7e74Rbf/zXp89Y+jmwBbDMdnp+2/h9s6U J0sEBCYyo9M=
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA DO
+SECTION QUESTION
+piranha.ro.vutbr.cz. IN A
+SECTION ANSWER
+piranha.ro.vutbr.cz. 3600 IN A 147.229.2.90
+piranha.ro.vutbr.cz. 3600 IN RRSIG A 5 4 3600 20170222120032 20170123120032 12150 ro.vutbr.cz. Jz8bcAADQjCKTCcF70IK1aHGQlM4ukyN0myABlxoPaqid1mHX5jwR91b kdQmUAh2xDitlgRLbFjbUUgmjSPzQ5Qt7GAFUsVmqxvjbOLZjqHER1dh zmiWO0fDvvP647Osv3RiAP822rNUJcJrUBZU9LmeP05gwIHcpJrhdVBT b7I=
+SECTION AUTHORITY
+ro.vutbr.cz. 86400 IN NS shark.ro.vutbr.cz.
+ro.vutbr.cz. 86400 IN NS rhino.cis.vutbr.cz.
+ro.vutbr.cz. 86400 IN NS pipit.cis.vutbr.cz.
+ro.vutbr.cz. 86400 IN RRSIG NS 5 3 86400 20170222120032 20170123120032 12150 ro.vutbr.cz. HAQ8A+QNsS1WIXdW/fbT3jP+IxObBBvgUmvzsmJBXo8HMtnMAcuCQGmB 2JBQsQethQXsdyLnMK8to/5A9VRkqkAa7edxUoy7SdDi/mzGeLAVhF+5 kXSPD6t1vjiNdnIYAMpiOQbodCGxAnq6jnNyrjEzffdq3qw+5IkFNdG4 7Pw=
+SECTION ADDITIONAL
+rhino.cis.vutbr.cz. 86400 IN A 147.229.3.10
+rhino.cis.vutbr.cz. 86400 IN AAAA 2001:67c:1220:e000::93e5:30a
+shark.ro.vutbr.cz. 3600 IN A 147.229.2.59
+pipit.cis.vutbr.cz. 86400 IN A 77.93.219.110
+pipit.cis.vutbr.cz. 86400 IN AAAA 2a01:430:120::4d5d:db6e
+rhino.cis.vutbr.cz. 86400 IN RRSIG A 5 4 86400 20170204080646 20170105080646 28257 cis.vutbr.cz. X/tDf8e3JEV0LxiItfpQnBzeaRIq693VG8d30iCH4/1I0uqyCfxboWmm /CBpn9A8MCJu9NEEv+4+povNlfUfqi2yjsqJEVj8ztHxD4g9cc284Cv6 ySjxrSZ9axVqoaopEXujiTwwWJUFcgF6pxqyXVksW7sgKJrboM4VSlQD +Sw=
+rhino.cis.vutbr.cz. 86400 IN RRSIG AAAA 5 4 86400 20170204080646 20170105080646 28257 cis.vutbr.cz. T3Yf5PAkSeJtoOH90ea9zZBG9FC3iFhiCSerDn6d9up8GRfzxDsavYJC zQu+3vnOySySn+3TMzQSSFcWdJC2iO7ulaDGr177Gof9QJbKSVSMW7jt YDE2f4/R4Go3NZVwjk/HfpCInoR6pHNA1s/9hMnWtiVopmBdfzyd3/sW YOU=
+shark.ro.vutbr.cz. 3600 IN RRSIG A 5 4 3600 20170222120032 20170123120032 12150 ro.vutbr.cz. SmhgyF48yX/6yH7AdSmGX60NL/xaiKH/oAzB0rnPfQZ6j+UfV57ginVV lj798K9A8jjucUpqE8ua2mZ6/aOhpqlV2iI0CZXG44zOupsCY1/OXBDx YNetBcjoXDQCBQRLLLEUL5FerDVxqT74ngdLdKubwRdrB0TLQlvpBr+F Tc8=
+pipit.cis.vutbr.cz. 86400 IN RRSIG A 5 4 86400 20170204080646 20170105080646 28257 cis.vutbr.cz. Cz9etHnEOQTzu+6rYJEqx/SQ1tQgPOCyf8HSj4KOsx89jtgiHNC6pep6 ZE0SphMGAs3jC/uGIhlaFNZ3i38OQIMuqwacbz+XZyW5bByvV3QZrhqh dFxMDfmPuNiCAT3crFpUkvVW1OE3YfGHzZGXX7JP5wb1b8A3X6Qih7fV +nQ=
+pipit.cis.vutbr.cz. 86400 IN RRSIG AAAA 5 4 86400 20170204080646 20170105080646 28257 cis.vutbr.cz. piafjh6my2fooZRrzwCu9RQ95gYaMQkhIkDaGX/fT6wXzSdmgFZkS1Nl EMIKdDCQaPrLGMG3p32ptMkAm4esPekeyNtLSMBtXwZyUkgEGn6h1QM2 Yr3TOo8cixfk5nmRRdlYadf5krLb8yI9exiqeymgEQLa1YNRz/bWArlX bn8=
+ENTRY_END
+
+; end of pipit.cis.vutbr.cz. & rhino.cis.vutbr.cz.
+RANGE_END
+
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.vutbr.cz. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH flags rcode question answer
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.vutbr.cz. IN A
+SECTION ANSWER
+www.vutbr.cz. IN CNAME piranha.ro.vutbr.cz.
+piranha.ro.vutbr.cz. IN A 147.229.2.90
+ENTRY_END
+
+STEP 20 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.vutbr.cz. IN A
+ENTRY_END
+
+STEP 21 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH flags rcode question answer
+REPLY QR RD RA AD NOERROR
+SECTION QUESTION
+www.vutbr.cz. IN A
+SECTION ANSWER
+www.vutbr.cz. IN CNAME piranha.ro.vutbr.cz.
+www.vutbr.cz. IN RRSIG CNAME 5 3 300 20170216060902 20170117060902 39756 vutbr.cz. 9B3UC5SOEw1+yKlYlOTINEuNq0Kdglywc5IYJwzeSzQ3ykptzZo3ABSy bYhTqImVkhm/4NFM9/4HWMHPDzTmrWS0mCI/ljCd/oe/PxW/uESvo4P5 EQzlcuH6xBzc1KdEFAJOSmRzFjj3vyK1QN3k/c+1y2oMFOYOR2oOzCw+ MIE=
+piranha.ro.vutbr.cz. IN A 147.229.2.90
+piranha.ro.vutbr.cz. 3600 IN RRSIG A 5 4 3600 20170222120032 20170123120032 12150 ro.vutbr.cz. Jz8bcAADQjCKTCcF70IK1aHGQlM4ukyN0myABlxoPaqid1mHX5jwR91b kdQmUAh2xDitlgRLbFjbUUgmjSPzQ5Qt7GAFUsVmqxvjbOLZjqHER1dh zmiWO0fDvvP647Osv3RiAP822rNUJcJrUBZU9LmeP05gwIHcpJrhdVBT b7I=
+ENTRY_END
+
+SCENARIO_END
diff --git a/lib/cache/peek.c b/lib/cache/peek.c
new file mode 100644
index 0000000..e1901ac
--- /dev/null
+++ b/lib/cache/peek.c
@@ -0,0 +1,774 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#include "lib/cache/impl.h"
+
+#include "lib/dnssec/ta.h"
+#include "lib/layer/iterate.h"
+
+/* The whole file only exports peek_nosync().
+ * Forwards for larger chunks of code: */
+
+static int found_exact_hit(kr_layer_t *ctx, knot_pkt_t *pkt, knot_db_val_t val,
+ uint8_t lowest_rank);
+static int closest_NS(struct kr_cache *cache, struct key *k, entry_list_t el,
+ struct kr_query *qry, bool only_NS, bool is_DS);
+static int answer_simple_hit(kr_layer_t *ctx, knot_pkt_t *pkt, uint16_t type,
+ const struct entry_h *eh, const void *eh_bound, uint32_t new_ttl);
+static int answer_dname_hit(kr_layer_t *ctx, knot_pkt_t *pkt, const knot_dname_t *dname_owner,
+ const struct entry_h *eh, const void *eh_bound, uint32_t new_ttl);
+static int try_wild(struct key *k, struct answer *ans, const knot_dname_t *clencl_name,
+ uint16_t type, uint8_t lowest_rank,
+ const struct kr_query *qry, struct kr_cache *cache);
+
+static int peek_encloser(
+ struct key *k, struct answer *ans, int sname_labels,
+ uint8_t lowest_rank, const struct kr_query *qry, struct kr_cache *cache);
+
+
+static int nsec_p_init(struct nsec_p *nsec_p, knot_db_val_t nsec_p_entry, bool with_knot)
+{
+ const size_t stamp_len = sizeof(uint32_t);
+ if (nsec_p_entry.len <= stamp_len) { /* plain NSEC if equal */
+ nsec_p->raw = NULL;
+ nsec_p->hash = 0;
+ return kr_ok();
+ }
+ nsec_p->raw = (uint8_t *)nsec_p_entry.data + stamp_len;
+ nsec_p->hash = nsec_p_mkHash(nsec_p->raw);
+ if (!with_knot) return kr_ok();
+ /* Convert NSEC3 params to another format. */
+ const dnssec_binary_t rdata = {
+ .size = nsec_p_rdlen(nsec_p->raw),
+ .data = (uint8_t *)/*const-cast*/nsec_p->raw,
+ };
+ int ret = dnssec_nsec3_params_from_rdata(&nsec_p->libknot, &rdata);
+ return ret == DNSSEC_EOK ? kr_ok() : kr_error(ret);
+}
+
+static void nsec_p_cleanup(struct nsec_p *nsec_p)
+{
+ dnssec_binary_free(&nsec_p->libknot.salt);
+ /* We don't really need to clear it, but it's not large. (`salt` zeroed above) */
+ memset(nsec_p, 0, sizeof(*nsec_p));
+}
+
+/** Compute new TTL for nsec_p entry, using SOA serial arith.
+ * \param new_ttl (optionally) write the new TTL (even if negative)
+ * \return error code, e.g. kr_error(ESTALE) */
+static int nsec_p_ttl(knot_db_val_t entry, const uint32_t timestamp, int32_t *new_ttl)
+{
+ if (kr_fails_assert(entry.data))
+ return kr_error(EINVAL);
+ uint32_t stamp;
+ if (!entry.len)
+ return kr_error(ENOENT);
+ if (kr_fails_assert(entry.len >= sizeof(stamp)))
+ return kr_error(EILSEQ);
+ memcpy(&stamp, entry.data, sizeof(stamp));
+ int32_t newttl = stamp - timestamp;
+ if (new_ttl) *new_ttl = newttl;
+ return newttl < 0 ? kr_error(ESTALE) : kr_ok();
+}
+
+static uint8_t get_lowest_rank(const struct kr_query *qry, const knot_dname_t *name, const uint16_t type)
+{
+ /* Shut up linters. */
+ kr_require(qry && qry->request);
+ /* TODO: move rank handling into the iterator (DNSSEC_* flags)? */
+ const bool allow_unverified =
+ knot_wire_get_cd(qry->request->qsource.packet->wire) || qry->flags.STUB;
+ /* in stub mode we don't trust RRs anyway ^^ */
+ if (qry->flags.NONAUTH) {
+ return KR_RANK_INITIAL;
+ /* Note: there's little sense in validation status for non-auth records.
+ * In case of using NONAUTH to get NS IPs, knowing that you ask correct
+ * IP doesn't matter much for security; it matters whether you can
+ * validate the answers from the NS.
+ */
+ } else if (!allow_unverified) {
+ /* Records not present under any TA don't have their security
+ * verified at all, so we also accept low ranks in that case. */
+ const bool ta_covers = kr_ta_closest(qry->request->ctx, name, type);
+ /* ^ TODO: performance? TODO: stype - call sites */
+ if (ta_covers) {
+ return KR_RANK_INSECURE | KR_RANK_AUTH;
+ } /* else fallthrough */
+ }
+ return KR_RANK_INITIAL | KR_RANK_AUTH;
+}
+
+
+/** Almost whole .produce phase for the cache module.
+ * \note we don't transition to KR_STATE_FAIL even in case of "unexpected errors".
+ */
+int peek_nosync(kr_layer_t *ctx, knot_pkt_t *pkt)
+{
+ struct kr_request *req = ctx->req;
+ struct kr_query *qry = req->current_query;
+ struct kr_cache *cache = &req->ctx->cache;
+
+ struct key k_storage, *k = &k_storage;
+ int ret = kr_dname_lf(k->buf, qry->sname, false);
+ if (kr_fails_assert(ret == 0))
+ return ctx->state;
+
+ const uint8_t lowest_rank = get_lowest_rank(qry, qry->sname, qry->stype);
+
+ /**** 1. find the name or the closest (available) zone, not considering wildcards
+ **** 1a. exact name+type match (can be negative, mainly in insecure zones) */
+ {
+ knot_db_val_t key = key_exact_type_maypkt(k, qry->stype);
+ knot_db_val_t val = { NULL, 0 };
+ ret = cache_op(cache, read, &key, &val, 1);
+ if (!ret) {
+ /* found an entry: test conditions, materialize into pkt, etc. */
+ ret = found_exact_hit(ctx, pkt, val, lowest_rank);
+ }
+ }
+ if (!ret) {
+ return KR_STATE_DONE;
+ } else if (kr_fails_assert(ret == kr_error(ENOENT))) {
+ VERBOSE_MSG(qry, "=> exact hit error: %d %s\n", ret, kr_strerror(ret));
+ return ctx->state;
+ }
+
+ /* Avoid aggressive answers in STUB mode.
+ * As STUB mode doesn't validate, it wouldn't save the necessary records.
+ * Moreover, this special case avoids unintentional NXDOMAIN on grafted subtrees. */
+ if (qry->flags.STUB)
+ return ctx->state;
+
+ /**** 1b. otherwise, find the longest prefix zone/xNAME (with OK time+rank). [...] */
+ k->zname = qry->sname;
+ ret = kr_dname_lf(k->buf, k->zname, false); /* LATER(optim.): probably remove */
+ if (kr_fails_assert(ret == 0))
+ return ctx->state;
+ entry_list_t el;
+ ret = closest_NS(cache, k, el, qry, false, qry->stype == KNOT_RRTYPE_DS);
+ if (ret) {
+ if (kr_fails_assert(ret == kr_error(ENOENT)) || !el[0].len) {
+ return ctx->state;
+ }
+ }
+ switch (k->type) {
+ case KNOT_RRTYPE_CNAME: {
+ const knot_db_val_t v = el[EL_CNAME];
+ if (kr_fails_assert(v.data && v.len))
+ return ctx->state;
+ const int32_t new_ttl = get_new_ttl(v.data, qry, qry->sname,
+ KNOT_RRTYPE_CNAME, qry->timestamp.tv_sec);
+ ret = answer_simple_hit(ctx, pkt, KNOT_RRTYPE_CNAME, v.data,
+ knot_db_val_bound(v), new_ttl);
+ return ret == kr_ok() ? KR_STATE_DONE : ctx->state;
+ }
+ case KNOT_RRTYPE_DNAME: {
+ const knot_db_val_t v = el[EL_DNAME];
+ if (kr_fails_assert(v.data && v.len))
+ return ctx->state;
+ /* TTL: for simplicity, we just ask for TTL of the generated CNAME. */
+ const int32_t new_ttl = get_new_ttl(v.data, qry, qry->sname,
+ KNOT_RRTYPE_CNAME, qry->timestamp.tv_sec);
+ ret = answer_dname_hit(ctx, pkt, k->zname, v.data,
+ knot_db_val_bound(v), new_ttl);
+ return ret == kr_ok() ? KR_STATE_DONE : ctx->state;
+ }
+ }
+
+ /* We have to try proving from NSEC*. */
+ auto_free char *log_zname = NULL;
+ WITH_VERBOSE(qry) {
+ log_zname = kr_dname_text(k->zname);
+ if (!el[0].len) {
+ VERBOSE_MSG(qry, "=> no NSEC* cached for zone: %s\n", log_zname);
+ }
+ }
+
+#if 0
+ if (!eh) { /* fall back to root hints? */
+ ret = kr_zonecut_set_sbelt(req->ctx, &qry->zone_cut);
+ if (ret) return ctx->state;
+ kr_assert(!qry->zone_cut.parent);
+
+ //VERBOSE_MSG(qry, "=> using root hints\n");
+ //qry->flags.AWAIT_CUT = false;
+ return ctx->state;
+ }
+
+ /* Now `eh` points to the closest NS record that we've found,
+ * and that's the only place to start - we may either find
+ * a negative proof or we may query upstream from that point. */
+ kr_zonecut_set(&qry->zone_cut, k->zname);
+ ret = kr_make_query(qry, pkt); // TODO: probably not yet - qname minimization
+ if (ret) return ctx->state;
+#endif
+
+ /** Structure for collecting multiple NSEC* + RRSIG records,
+ * in preparation for the answer, and for tracking the progress. */
+ struct answer ans;
+ memset(&ans, 0, sizeof(ans));
+ ans.mm = &pkt->mm;
+ const int sname_labels = knot_dname_labels(qry->sname, NULL);
+
+ /* Try the NSEC* parameters in order, until success.
+ * Let's not mix different parameters for NSEC* RRs in a single proof. */
+ for (int i = 0; ;) {
+ int32_t log_new_ttl = -123456789; /* visually recognizable value */
+ ret = nsec_p_ttl(el[i], qry->timestamp.tv_sec, &log_new_ttl);
+ if (!ret || kr_log_is_debug_qry(CACHE, qry)) {
+ nsec_p_init(&ans.nsec_p, el[i], !ret);
+ }
+ if (ret) {
+ VERBOSE_MSG(qry, "=> skipping zone: %s, %s, hash %x;"
+ "new TTL %d, ret %d\n",
+ log_zname, (ans.nsec_p.raw ? "NSEC3" : "NSEC"),
+ (unsigned)ans.nsec_p.hash, (int)log_new_ttl, ret);
+ /* no need for nsec_p_cleanup() in this case */
+ goto cont;
+ }
+ VERBOSE_MSG(qry, "=> trying zone: %s, %s, hash %x\n",
+ log_zname, (ans.nsec_p.raw ? "NSEC3" : "NSEC"),
+ (unsigned)ans.nsec_p.hash);
+ /**** 2. and 3. inside */
+ ret = peek_encloser(k, &ans, sname_labels,
+ lowest_rank, qry, cache);
+ nsec_p_cleanup(&ans.nsec_p);
+ if (!ret) break;
+ if (ret < 0) return ctx->state;
+ cont:
+ /* Otherwise we try another nsec_p, if available. */
+ if (++i == ENTRY_APEX_NSECS_CNT) return ctx->state;
+ /* clear possible partial answers in `ans` (no need to deallocate) */
+ ans.rcode = 0;
+ memset(&ans.rrsets, 0, sizeof(ans.rrsets));
+ }
+
+ /**** 4. add SOA iff needed */
+ if (ans.rcode != PKT_NOERROR) {
+ /* Assuming k->buf still starts with zone's prefix,
+ * look up the SOA in cache. */
+ k->buf[0] = k->zlf_len;
+ knot_db_val_t key = key_exact_type(k, KNOT_RRTYPE_SOA);
+ knot_db_val_t val = { NULL, 0 };
+ ret = cache_op(cache, read, &key, &val, 1);
+ const struct entry_h *eh;
+ if (ret || !(eh = entry_h_consistent_E(val, KNOT_RRTYPE_SOA))) {
+ kr_assert(ret); /* only want to catch `eh` failures */
+ VERBOSE_MSG(qry, "=> SOA missed\n");
+ return ctx->state;
+ }
+ /* Check if the record is OK. */
+ int32_t new_ttl = get_new_ttl(eh, qry, k->zname, KNOT_RRTYPE_SOA,
+ qry->timestamp.tv_sec);
+ if (new_ttl < 0 || eh->rank < lowest_rank || eh->is_packet) {
+ VERBOSE_MSG(qry, "=> SOA unfit %s: rank 0%.2o, new TTL %d\n",
+ (eh->is_packet ? "packet" : "RR"),
+ eh->rank, new_ttl);
+ return ctx->state;
+ }
+ /* Add the SOA into the answer. */
+ ret = entry2answer(&ans, AR_SOA, eh, knot_db_val_bound(val),
+ k->zname, KNOT_RRTYPE_SOA, new_ttl);
+ if (ret) return ctx->state;
+ }
+
+ /* Find our target RCODE. */
+ int real_rcode;
+ switch (ans.rcode) {
+ case PKT_NODATA:
+ case PKT_NOERROR: /* positive wildcarded response */
+ real_rcode = KNOT_RCODE_NOERROR;
+ break;
+ case PKT_NXDOMAIN:
+ real_rcode = KNOT_RCODE_NXDOMAIN;
+ break;
+ default:
+ kr_assert(false);
+ case 0: /* i.e. nothing was found */
+ /* LATER(optim.): zone cut? */
+ VERBOSE_MSG(qry, "=> cache miss\n");
+ return ctx->state;
+ }
+
+ if (pkt_renew(pkt, qry->sname, qry->stype)
+ || knot_pkt_begin(pkt, KNOT_ANSWER)
+ ) {
+ kr_assert(false);
+ return ctx->state;
+ }
+ knot_wire_set_rcode(pkt->wire, real_rcode);
+
+ bool expiring = false; // TODO
+ for (int i = 0; i < sizeof(ans.rrsets) / sizeof(ans.rrsets[0]); ++i) {
+ if (i == 1) knot_pkt_begin(pkt, KNOT_AUTHORITY);
+ if (!ans.rrsets[i].set.rr) continue;
+ expiring = expiring || ans.rrsets[i].set.expiring;
+ ret = pkt_append(pkt, &ans.rrsets[i], ans.rrsets[i].set.rank);
+ if (kr_fails_assert(ret == 0))
+ return ctx->state;
+ }
+
+ /* Finishing touches. */
+ struct kr_qflags * const qf = &qry->flags;
+ qf->EXPIRING = expiring;
+ qf->CACHED = true;
+ qf->NO_MINIMIZE = true;
+
+ return KR_STATE_DONE;
+}
+
+/**
+ * This is where the high-level "business logic" of aggressive cache is.
+ * \return 0: success (may need SOA); >0: try other nsec_p; <0: exit cache immediately.
+ */
+static int peek_encloser(
+ struct key *k, struct answer *ans, const int sname_labels,
+ uint8_t lowest_rank, const struct kr_query *qry, struct kr_cache *cache)
+{
+ /** Start of NSEC* covering the sname;
+ * it's part of key - the one within zone (read only) */
+ knot_db_val_t cover_low_kwz = { NULL, 0 };
+ knot_dname_t cover_hi_storage[KNOT_DNAME_MAXLEN];
+ /** End of NSEC* covering the sname. */
+ knot_db_val_t cover_hi_kwz = {
+ .data = cover_hi_storage,
+ .len = sizeof(cover_hi_storage),
+ };
+
+ /**** 2. Find a closest (provable) encloser (of sname). */
+ int clencl_labels = -1;
+ bool clencl_is_tentative = false;
+ if (!ans->nsec_p.raw) { /* NSEC */
+ int ret = nsec1_encloser(k, ans, sname_labels, &clencl_labels,
+ &cover_low_kwz, &cover_hi_kwz, qry, cache);
+ if (ret) return ret;
+ } else {
+ int ret = nsec3_encloser(k, ans, sname_labels, &clencl_labels,
+ qry, cache);
+ clencl_is_tentative = ret == ABS(ENOENT) && clencl_labels >= 0;
+ /* ^^ Last chance: *positive* wildcard record under this clencl. */
+ if (ret && !clencl_is_tentative) return ret;
+ }
+
+ /* We should have either a match or a cover at this point. */
+ if (kr_fails_assert(ans->rcode == PKT_NODATA || ans->rcode == PKT_NXDOMAIN))
+ return kr_error(EINVAL);
+ const bool ncloser_covered = ans->rcode == PKT_NXDOMAIN;
+
+ /** Name of the closest (provable) encloser. */
+ const knot_dname_t *clencl_name = qry->sname;
+ for (int l = sname_labels; l > clencl_labels; --l)
+ clencl_name = knot_wire_next_label(clencl_name, NULL);
+
+ /**** 3. source of synthesis checks, in case the next closer name was covered.
+ **** 3a. We want to query for NSEC* of source of synthesis (SS) or its
+ * predecessor, providing us with a proof of its existence or non-existence. */
+ if (ncloser_covered && !ans->nsec_p.raw) {
+ int ret = nsec1_src_synth(k, ans, clencl_name,
+ cover_low_kwz, cover_hi_kwz, qry, cache);
+ if (ret == AR_SOA) return 0;
+ kr_assert(ret <= 0);
+ if (ret) return ret;
+
+ } else if (ncloser_covered && ans->nsec_p.raw && !clencl_is_tentative) {
+ int ret = nsec3_src_synth(k, ans, clencl_name, qry, cache);
+ if (ret == AR_SOA) return 0;
+ kr_assert(ret <= 0);
+ if (ret) return ret;
+
+ } /* else (!ncloser_covered) so no wildcard checks needed,
+ * as we proved that sname exists. */
+
+ /**** 3b. find wildcarded answer, if next closer name was covered
+ * and we don't have a full proof yet. (common for NSEC*) */
+ if (!ncloser_covered)
+ return kr_ok(); /* decrease indentation */
+ /* Construct key for exact qry->stype + source of synthesis. */
+ int ret = kr_dname_lf(k->buf, clencl_name, true);
+ if (kr_fails_assert(ret == 0))
+ return kr_error(ret);
+ const uint16_t types[] = { qry->stype, KNOT_RRTYPE_CNAME };
+ for (int i = 0; i < (2 - (qry->stype == KNOT_RRTYPE_CNAME)); ++i) {
+ ret = try_wild(k, ans, clencl_name, types[i],
+ lowest_rank, qry, cache);
+ if (ret == kr_ok()) {
+ return kr_ok();
+ } else if (kr_fails_assert(ret == kr_error(ENOENT) || ret == kr_error(ESTALE))) {
+ return kr_error(ret);
+ }
+ /* else continue */
+ }
+ /* Neither attempt succeeded, but the NSEC* proofs were found,
+ * so skip trying other parameters, as it seems very unlikely
+ * to turn out differently than by the same wildcard search. */
+ return kr_error(ENOENT);
+}
+
+static void answer_simple_qflags(struct kr_qflags *qf, const struct entry_h *eh,
+ uint32_t new_ttl)
+{
+ /* Finishing touches. */
+ qf->EXPIRING = is_expiring(eh->ttl, new_ttl);
+ qf->CACHED = true;
+ qf->NO_MINIMIZE = true;
+ qf->DNSSEC_INSECURE = kr_rank_test(eh->rank, KR_RANK_INSECURE);
+ if (qf->DNSSEC_INSECURE) {
+ qf->DNSSEC_WANT = false;
+ }
+}
+
+#define CHECK_RET(ret) do { \
+ if (kr_fails_assert((ret) >= 0)) return kr_error((ret)); \
+} while (false)
+
+static int answer_simple_hit(kr_layer_t *ctx, knot_pkt_t *pkt, uint16_t type,
+ const struct entry_h *eh, const void *eh_bound, uint32_t new_ttl)
+{
+ struct kr_request *req = ctx->req;
+ struct kr_query *qry = req->current_query;
+
+ /* All OK, so start constructing the (pseudo-)packet. */
+ int ret = pkt_renew(pkt, qry->sname, qry->stype);
+ CHECK_RET(ret);
+
+ /* Materialize the sets for the answer in (pseudo-)packet. */
+ struct answer ans;
+ memset(&ans, 0, sizeof(ans));
+ ans.mm = &pkt->mm;
+ ret = entry2answer(&ans, AR_ANSWER, eh, eh_bound,
+ qry->sname, type, new_ttl);
+ CHECK_RET(ret);
+ /* Put links to the materialized data into the pkt. */
+ ret = pkt_append(pkt, &ans.rrsets[AR_ANSWER], eh->rank);
+ CHECK_RET(ret);
+
+ answer_simple_qflags(&qry->flags, eh, new_ttl);
+
+ VERBOSE_MSG(qry, "=> satisfied by exact %s: rank 0%.2o, new TTL %d\n",
+ (type == KNOT_RRTYPE_CNAME ? "CNAME" : "RRset"),
+ eh->rank, new_ttl);
+ return kr_ok();
+}
+
+static int answer_dname_hit(kr_layer_t *ctx, knot_pkt_t *pkt, const knot_dname_t *dname_owner,
+ const struct entry_h *eh, const void *eh_bound, uint32_t new_ttl)
+{
+ struct kr_request *req = ctx->req;
+ struct kr_query *qry = req->current_query;
+
+ /* All OK, so start constructing the (pseudo-)packet. */
+ int ret = pkt_renew(pkt, qry->sname, qry->stype);
+ CHECK_RET(ret);
+
+ /* Materialize the DNAME for the answer in (pseudo-)packet. */
+ struct answer ans;
+ memset(&ans, 0, sizeof(ans));
+ ans.mm = &pkt->mm;
+ ret = entry2answer(&ans, AR_ANSWER, eh, eh_bound,
+ dname_owner, KNOT_RRTYPE_DNAME, new_ttl);
+ CHECK_RET(ret);
+ /* Put link to the RRset into the pkt. */
+ ret = pkt_append(pkt, &ans.rrsets[AR_ANSWER], eh->rank);
+ CHECK_RET(ret);
+ const knot_dname_t *dname_target =
+ knot_dname_target(ans.rrsets[AR_ANSWER].set.rr->rrs.rdata);
+
+ /* Generate CNAME RRset for the answer in (pseudo-)packet. */
+ const int AR_CNAME = AR_SOA;
+ knot_rrset_t *rr = ans.rrsets[AR_CNAME].set.rr
+ = knot_rrset_new(qry->sname, KNOT_RRTYPE_CNAME, KNOT_CLASS_IN,
+ new_ttl, ans.mm);
+ CHECK_RET(rr ? kr_ok() : -ENOMEM);
+ const knot_dname_t *cname_target = knot_dname_replace_suffix(qry->sname,
+ knot_dname_labels(dname_owner, NULL), dname_target, ans.mm);
+ CHECK_RET(cname_target ? kr_ok() : -ENOMEM);
+ const int rdata_len = knot_dname_size(cname_target);
+
+ if (rdata_len <= KNOT_DNAME_MAXLEN
+ && knot_dname_labels(cname_target, NULL) <= KNOT_DNAME_MAXLABELS) {
+ /* Normal case: the target name fits. */
+ rr->rrs.count = 1;
+ rr->rrs.size = knot_rdata_size(rdata_len);
+ rr->rrs.rdata = mm_alloc(ans.mm, rr->rrs.size);
+ CHECK_RET(rr->rrs.rdata ? kr_ok() : -ENOMEM);
+ knot_rdata_init(rr->rrs.rdata, rdata_len, cname_target);
+ /* Put link to the RRset into the pkt. */
+ ret = pkt_append(pkt, &ans.rrsets[AR_CNAME], eh->rank);
+ CHECK_RET(ret);
+ } else {
+ /* Note that it's basically a successful answer; name just doesn't fit. */
+ knot_wire_set_rcode(pkt->wire, KNOT_RCODE_YXDOMAIN);
+ }
+
+ answer_simple_qflags(&qry->flags, eh, new_ttl);
+ VERBOSE_MSG(qry, "=> satisfied by DNAME+CNAME: rank 0%.2o, new TTL %d\n",
+ eh->rank, new_ttl);
+ return kr_ok();
+}
+
+#undef CHECK_RET
+
+/** TODO: description; see the single call site for now. */
+static int found_exact_hit(kr_layer_t *ctx, knot_pkt_t *pkt, knot_db_val_t val,
+ uint8_t lowest_rank)
+{
+ struct kr_request *req = ctx->req;
+ struct kr_query *qry = req->current_query;
+
+ int ret = entry_h_seek(&val, qry->stype);
+ if (ret) return ret;
+ const struct entry_h *eh = entry_h_consistent_E(val, qry->stype);
+ if (kr_fails_assert(eh))
+ return kr_error(ENOENT);
+ // LATER: recovery in case of error, perhaps via removing the entry?
+ // LATER(optim): perhaps optimize the zone cut search
+
+ int32_t new_ttl = get_new_ttl(eh, qry, qry->sname, qry->stype,
+ qry->timestamp.tv_sec);
+ if (new_ttl < 0 || eh->rank < lowest_rank) {
+ /* Positive record with stale TTL or bad rank.
+ * LATER(optim.): It's unlikely that we find a negative one,
+ * so we might theoretically skip all the cache code. */
+
+ VERBOSE_MSG(qry, "=> skipping exact %s: rank 0%.2o (min. 0%.2o), new TTL %d\n",
+ eh->is_packet ? "packet" : "RR", eh->rank, lowest_rank, new_ttl);
+ return kr_error(ENOENT);
+ }
+
+ const uint8_t *eh_bound = knot_db_val_bound(val);
+ if (eh->is_packet) {
+ /* Note: we answer here immediately, even if it's (theoretically)
+ * possible that we could generate a higher-security negative proof.
+ * Rank is high-enough so we take it to save time searching;
+ * in practice this also helps in some incorrect zones (live-signed). */
+ return answer_from_pkt (ctx, pkt, qry->stype, eh, eh_bound, new_ttl);
+ } else {
+ return answer_simple_hit(ctx, pkt, qry->stype, eh, eh_bound, new_ttl);
+ }
+}
+
+
+/** Try to satisfy via wildcard (positively). See the single call site. */
+static int try_wild(struct key *k, struct answer *ans, const knot_dname_t *clencl_name,
+ const uint16_t type, const uint8_t lowest_rank,
+ const struct kr_query *qry, struct kr_cache *cache)
+{
+ knot_db_val_t key = key_exact_type(k, type);
+ /* Find the record. */
+ knot_db_val_t val = { NULL, 0 };
+ int ret = cache_op(cache, read, &key, &val, 1);
+ if (!ret) {
+ ret = entry_h_seek(&val, type);
+ }
+ if (ret) {
+ if (kr_fails_assert(ret == kr_error(ENOENT)))
+ VERBOSE_MSG(qry, "=> wildcard: hit error %d %s\n",
+ ret, strerror(abs(ret)));
+ WITH_VERBOSE(qry) {
+ auto_free char *clencl_str = kr_dname_text(clencl_name),
+ *type_str = kr_rrtype_text(type);
+ VERBOSE_MSG(qry, "=> wildcard: not found: *.%s %s\n",
+ clencl_str, type_str);
+ }
+ return ret;
+ }
+ /* Check if the record is OK. */
+ const struct entry_h *eh = entry_h_consistent_E(val, type);
+ if (kr_fails_assert(eh))
+ return kr_error(ret);
+ // LATER: recovery in case of error, perhaps via removing the entry?
+ int32_t new_ttl = get_new_ttl(eh, qry, qry->sname, type, qry->timestamp.tv_sec);
+ /* ^^ here we use the *expanded* wildcard name */
+ if (new_ttl < 0 || eh->rank < lowest_rank || eh->is_packet) {
+ /* Wildcard record with stale TTL, bad rank or packet. */
+ VERBOSE_MSG(qry, "=> wildcard: skipping %s, rank 0%.2o, new TTL %d\n",
+ eh->is_packet ? "packet" : "RR", eh->rank, new_ttl);
+ return kr_error(ESTALE);
+ }
+ /* Add the RR into the answer. */
+ ret = entry2answer(ans, AR_ANSWER, eh, knot_db_val_bound(val),
+ qry->sname, type, new_ttl);
+ VERBOSE_MSG(qry, "=> wildcard: answer expanded, ret = %d, new TTL %d\n",
+ ret, (int)new_ttl);
+ if (ret) return kr_error(ret);
+ ans->rcode = PKT_NOERROR;
+ return kr_ok();
+}
+
+int kr_cache_closest_apex(struct kr_cache *cache, const knot_dname_t *name, bool is_DS,
+ knot_dname_t ** apex)
+{
+ if (kr_fails_assert(cache && cache->db && name && apex && *apex == NULL))
+ return kr_error(EINVAL);
+ struct key k_storage, *k = &k_storage;
+ int ret = kr_dname_lf(k->buf, name, false);
+ if (ret)
+ return kr_error(ret);
+ entry_list_t el_;
+ k->zname = name;
+ ret = closest_NS(cache, k, el_, NULL, true, is_DS);
+ if (ret && ret != -abs(ENOENT))
+ return ret;
+ *apex = knot_dname_copy(k->zname, NULL);
+ if (!*apex)
+ return kr_error(ENOMEM);
+ return kr_ok();
+}
+
+/** \internal for closest_NS. Check suitability of a single entry, setting k->type if OK.
+ * \return error code, negative iff whole list should be skipped.
+ */
+static int check_NS_entry(struct key *k, knot_db_val_t entry, int i,
+ bool exact_match, bool is_DS,
+ const struct kr_query *qry, uint32_t timestamp);
+
+/**
+ * Find the longest prefix zone/xNAME (with OK time+rank), starting at k->*.
+ *
+ * The found type is returned via k->type; the values are returned in el.
+ * \note we use k->type = KNOT_RRTYPE_NS also for the nsec_p result.
+ * \param qry can be NULL (-> gettimeofday(), but you lose the stale-serve hook)
+ * \param only_NS don't consider xNAMEs
+ * \return error code
+ */
+static int closest_NS(struct kr_cache *cache, struct key *k, entry_list_t el,
+ struct kr_query *qry, const bool only_NS, const bool is_DS)
+{
+ /* get the current timestamp */
+ uint32_t timestamp;
+ if (qry) {
+ timestamp = qry->timestamp.tv_sec;
+ } else {
+ struct timeval tv;
+ if (gettimeofday(&tv, NULL)) return kr_error(errno);
+ timestamp = tv.tv_sec;
+ }
+
+ int zlf_len = k->buf[0];
+
+ // LATER(optim): if stype is NS, we check the same value again
+ bool exact_match = true;
+ bool need_zero = true;
+ /* Inspect the NS/xNAME entries, shortening by a label on each iteration. */
+ do {
+ k->buf[0] = zlf_len;
+ knot_db_val_t key = key_exact_type(k, KNOT_RRTYPE_NS);
+ knot_db_val_t val;
+ int ret = cache_op(cache, read, &key, &val, 1);
+ if (ret == kr_error(ENOENT)) goto next_label;
+ if (kr_fails_assert(ret == 0)) {
+ if (need_zero) memset(el, 0, sizeof(entry_list_t));
+ return kr_error(ret);
+ }
+
+ /* Check consistency, find any type;
+ * using `goto` for shortening by another label. */
+ ret = entry_list_parse(val, el);
+ if (kr_fails_assert(ret == 0)) // do something about it?
+ goto next_label;
+ need_zero = false;
+ /* More types are possible; try in order.
+ * For non-fatal failures just "continue;" to try the next type. */
+ /* Now a complication - we need to try EL_DNAME before NSEC*
+ * (Unfortunately that's not easy to write very nicely.) */
+ if (!only_NS) {
+ const int i = EL_DNAME;
+ ret = check_NS_entry(k, el[i], i, exact_match, is_DS,
+ qry, timestamp);
+ if (ret < 0) goto next_label; else
+ if (!ret) {
+ /* We found our match. */
+ k->zlf_len = zlf_len;
+ return kr_ok();
+ }
+ }
+ const int el_count = only_NS ? EL_NS + 1 : EL_LENGTH;
+ for (int i = 0; i < el_count; ++i) {
+ if (i == EL_DNAME) continue;
+ ret = check_NS_entry(k, el[i], i, exact_match, is_DS,
+ qry, timestamp);
+ if (ret < 0) goto next_label; else
+ if (!ret) {
+ /* We found our match. */
+ k->zlf_len = zlf_len;
+ return kr_ok();
+ }
+ }
+
+ next_label:
+ /* remove one more label */
+ exact_match = false;
+ if (k->zname[0] == 0) {
+ /* We miss root NS in cache, but let's at least assume it exists. */
+ k->type = KNOT_RRTYPE_NS;
+ k->zlf_len = zlf_len;
+ kr_assert(zlf_len == 0);
+ if (need_zero) memset(el, 0, sizeof(entry_list_t));
+ return kr_error(ENOENT);
+ }
+ zlf_len -= (k->zname[0] + 1);
+ k->zname += (k->zname[0] + 1);
+ k->buf[zlf_len + 1] = 0;
+ } while (true);
+}
+
+static int check_NS_entry(struct key *k, const knot_db_val_t entry, const int i,
+ const bool exact_match, const bool is_DS,
+ const struct kr_query *qry, uint32_t timestamp)
+{
+ const int ESKIP = ABS(ENOENT);
+ if (!entry.len
+ /* On a zone cut we want DS from the parent zone. */
+ || (exact_match && is_DS)
+ /* CNAME is interesting only if we
+ * directly hit the name that was asked.
+ * Note that we want it even in the DS case. */
+ || (i == EL_CNAME && !exact_match)
+ /* DNAME is interesting only if we did NOT
+ * directly hit the name that was asked. */
+ || (i == EL_DNAME && exact_match)
+ ) {
+ return ESKIP;
+ }
+
+ uint16_t type;
+ if (i < ENTRY_APEX_NSECS_CNT) {
+ type = KNOT_RRTYPE_NS;
+ int32_t log_new_ttl = -123456789; /* visually recognizable value */
+ const int err = nsec_p_ttl(entry, timestamp, &log_new_ttl);
+ if (err) {
+ VERBOSE_MSG(qry,
+ "=> skipping unfit nsec_p: new TTL %d, error %d\n",
+ (int)log_new_ttl, err);
+ return ESKIP;
+ }
+ } else {
+ type = EL2RRTYPE(i);
+ /* Find the entry for the type, check positivity, TTL */
+ const struct entry_h *eh = entry_h_consistent_E(entry, type);
+ if (kr_fails_assert(eh)) {
+ VERBOSE_MSG(qry, "=> EH not consistent\n");
+ return kr_error(EILSEQ);
+ }
+ const int32_t log_new_ttl = get_new_ttl(eh, qry, k->zname, type, timestamp);
+
+ const bool ok = /* Not interested in negative bogus or outdated RRs. */
+ !eh->is_packet && log_new_ttl >= 0
+ /* For NS any kr_rank is accepted, as insecure or even nonauth is OK */
+ && (type == KNOT_RRTYPE_NS
+ || eh->rank >= get_lowest_rank(qry, k->zname, type));
+
+ WITH_VERBOSE(qry) { if (!ok) {
+ auto_free char *type_str = kr_rrtype_text(type);
+ const char *packet_str = eh->is_packet ? "packet" : "RR";
+ VERBOSE_MSG(qry,
+ "=> skipping unfit %s %s: rank 0%.2o, new TTL %d\n",
+ type_str, packet_str, eh->rank, (int)log_new_ttl);
+ } }
+ if (!ok) return ESKIP;
+ }
+ k->type = type;
+ return kr_ok();
+}
+
diff --git a/lib/cache/test.integr/cache_minimal_nsec3.rpl b/lib/cache/test.integr/cache_minimal_nsec3.rpl
new file mode 100644
index 0000000..7c4a5cf
--- /dev/null
+++ b/lib/cache/test.integr/cache_minimal_nsec3.rpl
@@ -0,0 +1,4120 @@
+; SPDX-License-Identifier: GPL-3.0-or-later
+ trust-anchor: ". IN DS 20326 8 2 E06D44B80B8F1D39A95C0B0D7C65D08458E880409BBC683457104237C7F8EC8D"
+ val-override-date: 20190625160934
+ stub-addr: 2001:503:ba3e::2:30
+CONFIG_END
+
+SCENARIO_BEGIN Test that minimal NSEC3 range does not trigger agressive cache (workaround for buggy auths, optimization to improve cache hit rate on correct auths using black lies)
+
+; Group's zones:
+; .
+; root-servers.net.
+; Server names:
+; f.root-servers.net.
+; a.root-servers.net.
+; j.root-servers.net.
+; e.root-servers.net.
+; i.root-servers.net.
+; d.root-servers.net.
+; m.root-servers.net.
+; h.root-servers.net.
+; c.root-servers.net.
+; l.root-servers.net.
+; g.root-servers.net.
+; b.root-servers.net.
+; k.root-servers.net.
+RANGE_BEGIN 0 1000
+ ADDRESS 2001:500:2f::f
+ ADDRESS 2001:503:ba3e::2:30
+ ADDRESS 2001:500:12::d0d
+ ADDRESS 202.12.27.33
+ ADDRESS 2001:7fd::1
+ ADDRESS 2001:503:c27::2:30
+ ADDRESS 2001:500:200::b
+ ADDRESS 198.97.190.53
+ ADDRESS 192.58.128.30
+ ADDRESS 198.41.0.4
+ ADDRESS 199.7.91.13
+ ADDRESS 2001:dc3::35
+ ADDRESS 192.36.148.17
+ ADDRESS 192.203.230.10
+ ADDRESS 192.5.5.241
+ ADDRESS 199.9.14.201
+ ADDRESS 193.0.14.129
+ ADDRESS 2001:7fe::53
+ ADDRESS 2001:500:9f::42
+ ADDRESS 2001:500:a8::e
+ ADDRESS 2001:500:2d::d
+ ADDRESS 192.112.36.4
+ ADDRESS 2001:500:2::c
+ ADDRESS 192.33.4.12
+ ADDRESS 199.7.83.42
+ ADDRESS 2001:500:1::53
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+i.root-servers.net. IN AAAA
+SECTION ANSWER
+i.root-servers.net. 3600000 IN AAAA 2001:7fe::53
+SECTION AUTHORITY
+root-servers.net. 3600000 IN NS a.root-servers.net.
+root-servers.net. 3600000 IN NS b.root-servers.net.
+root-servers.net. 3600000 IN NS c.root-servers.net.
+root-servers.net. 3600000 IN NS d.root-servers.net.
+root-servers.net. 3600000 IN NS e.root-servers.net.
+root-servers.net. 3600000 IN NS f.root-servers.net.
+root-servers.net. 3600000 IN NS g.root-servers.net.
+root-servers.net. 3600000 IN NS h.root-servers.net.
+root-servers.net. 3600000 IN NS i.root-servers.net.
+root-servers.net. 3600000 IN NS j.root-servers.net.
+root-servers.net. 3600000 IN NS k.root-servers.net.
+root-servers.net. 3600000 IN NS l.root-servers.net.
+root-servers.net. 3600000 IN NS m.root-servers.net.
+SECTION ADDITIONAL
+a.root-servers.net. 3600000 IN A 198.41.0.4
+a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30
+b.root-servers.net. 3600000 IN A 199.9.14.201
+b.root-servers.net. 3600000 IN AAAA 2001:500:200::b
+c.root-servers.net. 3600000 IN A 192.33.4.12
+c.root-servers.net. 3600000 IN AAAA 2001:500:2::c
+d.root-servers.net. 3600000 IN A 199.7.91.13
+d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d
+e.root-servers.net. 3600000 IN A 192.203.230.10
+e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e
+f.root-servers.net. 3600000 IN A 192.5.5.241
+f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f
+g.root-servers.net. 3600000 IN A 192.112.36.4
+g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d
+h.root-servers.net. 3600000 IN A 198.97.190.53
+h.root-servers.net. 3600000 IN AAAA 2001:500:1::53
+i.root-servers.net. 3600000 IN A 192.36.148.17
+j.root-servers.net. 3600000 IN A 192.58.128.30
+j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+l.root-servers.net. 3600000 IN A 199.7.83.42
+l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42
+m.root-servers.net. 3600000 IN A 202.12.27.33
+m.root-servers.net. 3600000 IN AAAA 2001:dc3::35
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+g.root-servers.net. IN NS
+SECTION AUTHORITY
+root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2019061700 14400 7200 1209600 3600000
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+e.root-servers.net. IN A
+SECTION ANSWER
+e.root-servers.net. 3600000 IN A 192.203.230.10
+SECTION AUTHORITY
+root-servers.net. 3600000 IN NS a.root-servers.net.
+root-servers.net. 3600000 IN NS b.root-servers.net.
+root-servers.net. 3600000 IN NS c.root-servers.net.
+root-servers.net. 3600000 IN NS d.root-servers.net.
+root-servers.net. 3600000 IN NS e.root-servers.net.
+root-servers.net. 3600000 IN NS f.root-servers.net.
+root-servers.net. 3600000 IN NS g.root-servers.net.
+root-servers.net. 3600000 IN NS h.root-servers.net.
+root-servers.net. 3600000 IN NS i.root-servers.net.
+root-servers.net. 3600000 IN NS j.root-servers.net.
+root-servers.net. 3600000 IN NS k.root-servers.net.
+root-servers.net. 3600000 IN NS l.root-servers.net.
+root-servers.net. 3600000 IN NS m.root-servers.net.
+SECTION ADDITIONAL
+a.root-servers.net. 3600000 IN A 198.41.0.4
+a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30
+b.root-servers.net. 3600000 IN A 199.9.14.201
+b.root-servers.net. 3600000 IN AAAA 2001:500:200::b
+c.root-servers.net. 3600000 IN A 192.33.4.12
+c.root-servers.net. 3600000 IN AAAA 2001:500:2::c
+d.root-servers.net. 3600000 IN A 199.7.91.13
+d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d
+e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e
+f.root-servers.net. 3600000 IN A 192.5.5.241
+f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f
+g.root-servers.net. 3600000 IN A 192.112.36.4
+g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d
+h.root-servers.net. 3600000 IN A 198.97.190.53
+h.root-servers.net. 3600000 IN AAAA 2001:500:1::53
+i.root-servers.net. 3600000 IN A 192.36.148.17
+i.root-servers.net. 3600000 IN AAAA 2001:7fe::53
+j.root-servers.net. 3600000 IN A 192.58.128.30
+j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+l.root-servers.net. 3600000 IN A 199.7.83.42
+l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42
+m.root-servers.net. 3600000 IN A 202.12.27.33
+m.root-servers.net. 3600000 IN AAAA 2001:dc3::35
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+f.root-servers.net. IN NS
+SECTION AUTHORITY
+root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2019061700 14400 7200 1209600 3600000
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+i.root-servers.net. IN A
+SECTION ANSWER
+i.root-servers.net. 3600000 IN A 192.36.148.17
+SECTION AUTHORITY
+root-servers.net. 3600000 IN NS a.root-servers.net.
+root-servers.net. 3600000 IN NS b.root-servers.net.
+root-servers.net. 3600000 IN NS c.root-servers.net.
+root-servers.net. 3600000 IN NS d.root-servers.net.
+root-servers.net. 3600000 IN NS e.root-servers.net.
+root-servers.net. 3600000 IN NS f.root-servers.net.
+root-servers.net. 3600000 IN NS g.root-servers.net.
+root-servers.net. 3600000 IN NS h.root-servers.net.
+root-servers.net. 3600000 IN NS i.root-servers.net.
+root-servers.net. 3600000 IN NS j.root-servers.net.
+root-servers.net. 3600000 IN NS k.root-servers.net.
+root-servers.net. 3600000 IN NS l.root-servers.net.
+root-servers.net. 3600000 IN NS m.root-servers.net.
+SECTION ADDITIONAL
+a.root-servers.net. 3600000 IN A 198.41.0.4
+a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30
+b.root-servers.net. 3600000 IN A 199.9.14.201
+b.root-servers.net. 3600000 IN AAAA 2001:500:200::b
+c.root-servers.net. 3600000 IN A 192.33.4.12
+c.root-servers.net. 3600000 IN AAAA 2001:500:2::c
+d.root-servers.net. 3600000 IN A 199.7.91.13
+d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d
+e.root-servers.net. 3600000 IN A 192.203.230.10
+e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e
+f.root-servers.net. 3600000 IN A 192.5.5.241
+f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f
+g.root-servers.net. 3600000 IN A 192.112.36.4
+g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d
+h.root-servers.net. 3600000 IN A 198.97.190.53
+h.root-servers.net. 3600000 IN AAAA 2001:500:1::53
+i.root-servers.net. 3600000 IN AAAA 2001:7fe::53
+j.root-servers.net. 3600000 IN A 192.58.128.30
+j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+l.root-servers.net. 3600000 IN A 199.7.83.42
+l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42
+m.root-servers.net. 3600000 IN A 202.12.27.33
+m.root-servers.net. 3600000 IN AAAA 2001:dc3::35
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+c.root-servers.net. IN NS
+SECTION AUTHORITY
+root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2019061700 14400 7200 1209600 3600000
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+root-servers.net. IN DS
+SECTION AUTHORITY
+root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2019061700 14400 7200 1209600 3600000
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+c.root-servers.net. IN A
+SECTION ANSWER
+c.root-servers.net. 3600000 IN A 192.33.4.12
+SECTION AUTHORITY
+root-servers.net. 3600000 IN NS a.root-servers.net.
+root-servers.net. 3600000 IN NS b.root-servers.net.
+root-servers.net. 3600000 IN NS c.root-servers.net.
+root-servers.net. 3600000 IN NS d.root-servers.net.
+root-servers.net. 3600000 IN NS e.root-servers.net.
+root-servers.net. 3600000 IN NS f.root-servers.net.
+root-servers.net. 3600000 IN NS g.root-servers.net.
+root-servers.net. 3600000 IN NS h.root-servers.net.
+root-servers.net. 3600000 IN NS i.root-servers.net.
+root-servers.net. 3600000 IN NS j.root-servers.net.
+root-servers.net. 3600000 IN NS k.root-servers.net.
+root-servers.net. 3600000 IN NS l.root-servers.net.
+root-servers.net. 3600000 IN NS m.root-servers.net.
+SECTION ADDITIONAL
+a.root-servers.net. 3600000 IN A 198.41.0.4
+a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30
+b.root-servers.net. 3600000 IN A 199.9.14.201
+b.root-servers.net. 3600000 IN AAAA 2001:500:200::b
+c.root-servers.net. 3600000 IN AAAA 2001:500:2::c
+d.root-servers.net. 3600000 IN A 199.7.91.13
+d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d
+e.root-servers.net. 3600000 IN A 192.203.230.10
+e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e
+f.root-servers.net. 3600000 IN A 192.5.5.241
+f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f
+g.root-servers.net. 3600000 IN A 192.112.36.4
+g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d
+h.root-servers.net. 3600000 IN A 198.97.190.53
+h.root-servers.net. 3600000 IN AAAA 2001:500:1::53
+i.root-servers.net. 3600000 IN A 192.36.148.17
+i.root-servers.net. 3600000 IN AAAA 2001:7fe::53
+j.root-servers.net. 3600000 IN A 192.58.128.30
+j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+l.root-servers.net. 3600000 IN A 199.7.83.42
+l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42
+m.root-servers.net. 3600000 IN A 202.12.27.33
+m.root-servers.net. 3600000 IN AAAA 2001:dc3::35
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+d.root-servers.net. IN A
+SECTION ANSWER
+d.root-servers.net. 3600000 IN A 199.7.91.13
+SECTION AUTHORITY
+root-servers.net. 3600000 IN NS a.root-servers.net.
+root-servers.net. 3600000 IN NS b.root-servers.net.
+root-servers.net. 3600000 IN NS c.root-servers.net.
+root-servers.net. 3600000 IN NS d.root-servers.net.
+root-servers.net. 3600000 IN NS e.root-servers.net.
+root-servers.net. 3600000 IN NS f.root-servers.net.
+root-servers.net. 3600000 IN NS g.root-servers.net.
+root-servers.net. 3600000 IN NS h.root-servers.net.
+root-servers.net. 3600000 IN NS i.root-servers.net.
+root-servers.net. 3600000 IN NS j.root-servers.net.
+root-servers.net. 3600000 IN NS k.root-servers.net.
+root-servers.net. 3600000 IN NS l.root-servers.net.
+root-servers.net. 3600000 IN NS m.root-servers.net.
+SECTION ADDITIONAL
+a.root-servers.net. 3600000 IN A 198.41.0.4
+a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30
+b.root-servers.net. 3600000 IN A 199.9.14.201
+b.root-servers.net. 3600000 IN AAAA 2001:500:200::b
+c.root-servers.net. 3600000 IN A 192.33.4.12
+c.root-servers.net. 3600000 IN AAAA 2001:500:2::c
+d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d
+e.root-servers.net. 3600000 IN A 192.203.230.10
+e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e
+f.root-servers.net. 3600000 IN A 192.5.5.241
+f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f
+g.root-servers.net. 3600000 IN A 192.112.36.4
+g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d
+h.root-servers.net. 3600000 IN A 198.97.190.53
+h.root-servers.net. 3600000 IN AAAA 2001:500:1::53
+i.root-servers.net. 3600000 IN A 192.36.148.17
+i.root-servers.net. 3600000 IN AAAA 2001:7fe::53
+j.root-servers.net. 3600000 IN A 192.58.128.30
+j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+l.root-servers.net. 3600000 IN A 199.7.83.42
+l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42
+m.root-servers.net. 3600000 IN A 202.12.27.33
+m.root-servers.net. 3600000 IN AAAA 2001:dc3::35
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+f.root-servers.net. IN AAAA
+SECTION ANSWER
+f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. 518400 IN NS a.root-servers.net.
+. 518400 IN NS b.root-servers.net.
+. 518400 IN NS c.root-servers.net.
+. 518400 IN NS d.root-servers.net.
+. 518400 IN NS e.root-servers.net.
+. 518400 IN NS f.root-servers.net.
+. 518400 IN NS g.root-servers.net.
+. 518400 IN NS h.root-servers.net.
+. 518400 IN NS i.root-servers.net.
+. 518400 IN NS j.root-servers.net.
+. 518400 IN NS k.root-servers.net.
+. 518400 IN NS l.root-servers.net.
+. 518400 IN NS m.root-servers.net.
+. 518400 IN RRSIG NS 8 0 518400 20190708050000 20190625040000 25266 . IwbmJVqFUjJz5WwRbYqOWejRck85QWW8 eIGID2J+Qhw89iUDDz2lgvysed4WQfks 8Y2XZu79T0+RJF+mj1UUiE+Y6RdOmFDU Qx3ovGkYwOXcr1anreBD+Wn5tv1WW6El NbKf40pXdtDX6Ad1qx6hCHHR4hieQPww psNHmrGDg+Eog+VqYjwwRj9EaYEms5dU PRJmiHiACe85DZMCjxl6f+kp7ZXyFD/L coLi7QzXiRWYOPHhWKk3pqYGD1j7I7YB Oq7UujK+jPscWCDuArGmZwlhAtAPaPLe 5TZHIGE39c6eYpuXwSXZ1EPM545/9WsI HihzUQ75ltuiPXwjv0OpQg==
+SECTION ADDITIONAL
+a.root-servers.net. 3600000 IN A 198.41.0.4
+a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30
+b.root-servers.net. 3600000 IN A 199.9.14.201
+b.root-servers.net. 3600000 IN AAAA 2001:500:200::b
+c.root-servers.net. 3600000 IN A 192.33.4.12
+c.root-servers.net. 3600000 IN AAAA 2001:500:2::c
+d.root-servers.net. 3600000 IN A 199.7.91.13
+d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d
+e.root-servers.net. 3600000 IN A 192.203.230.10
+e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e
+f.root-servers.net. 3600000 IN A 192.5.5.241
+f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f
+g.root-servers.net. 3600000 IN A 192.112.36.4
+g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d
+h.root-servers.net. 3600000 IN A 198.97.190.53
+h.root-servers.net. 3600000 IN AAAA 2001:500:1::53
+i.root-servers.net. 3600000 IN A 192.36.148.17
+i.root-servers.net. 3600000 IN AAAA 2001:7fe::53
+j.root-servers.net. 3600000 IN A 192.58.128.30
+j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+l.root-servers.net. 3600000 IN A 199.7.83.42
+l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42
+m.root-servers.net. 3600000 IN A 202.12.27.33
+m.root-servers.net. 3600000 IN AAAA 2001:dc3::35
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+j.root-servers.net. IN NS
+SECTION AUTHORITY
+root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2019061700 14400 7200 1209600 3600000
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+a.root-servers.net. IN A
+SECTION ANSWER
+a.root-servers.net. 3600000 IN A 198.41.0.4
+SECTION AUTHORITY
+root-servers.net. 3600000 IN NS a.root-servers.net.
+root-servers.net. 3600000 IN NS b.root-servers.net.
+root-servers.net. 3600000 IN NS c.root-servers.net.
+root-servers.net. 3600000 IN NS d.root-servers.net.
+root-servers.net. 3600000 IN NS e.root-servers.net.
+root-servers.net. 3600000 IN NS f.root-servers.net.
+root-servers.net. 3600000 IN NS g.root-servers.net.
+root-servers.net. 3600000 IN NS h.root-servers.net.
+root-servers.net. 3600000 IN NS i.root-servers.net.
+root-servers.net. 3600000 IN NS j.root-servers.net.
+root-servers.net. 3600000 IN NS k.root-servers.net.
+root-servers.net. 3600000 IN NS l.root-servers.net.
+root-servers.net. 3600000 IN NS m.root-servers.net.
+SECTION ADDITIONAL
+a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30
+b.root-servers.net. 3600000 IN A 199.9.14.201
+b.root-servers.net. 3600000 IN AAAA 2001:500:200::b
+c.root-servers.net. 3600000 IN A 192.33.4.12
+c.root-servers.net. 3600000 IN AAAA 2001:500:2::c
+d.root-servers.net. 3600000 IN A 199.7.91.13
+d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d
+e.root-servers.net. 3600000 IN A 192.203.230.10
+e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e
+f.root-servers.net. 3600000 IN A 192.5.5.241
+f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f
+g.root-servers.net. 3600000 IN A 192.112.36.4
+g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d
+h.root-servers.net. 3600000 IN A 198.97.190.53
+h.root-servers.net. 3600000 IN AAAA 2001:500:1::53
+i.root-servers.net. 3600000 IN A 192.36.148.17
+i.root-servers.net. 3600000 IN AAAA 2001:7fe::53
+j.root-servers.net. 3600000 IN A 192.58.128.30
+j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+l.root-servers.net. 3600000 IN A 199.7.83.42
+l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42
+m.root-servers.net. 3600000 IN A 202.12.27.33
+m.root-servers.net. 3600000 IN AAAA 2001:dc3::35
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+h.root-servers.net. IN NS
+SECTION AUTHORITY
+root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2019061700 14400 7200 1209600 3600000
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+g.root-servers.net. IN A
+SECTION ANSWER
+g.root-servers.net. 3600000 IN A 192.112.36.4
+SECTION AUTHORITY
+root-servers.net. 3600000 IN NS a.root-servers.net.
+root-servers.net. 3600000 IN NS b.root-servers.net.
+root-servers.net. 3600000 IN NS c.root-servers.net.
+root-servers.net. 3600000 IN NS d.root-servers.net.
+root-servers.net. 3600000 IN NS e.root-servers.net.
+root-servers.net. 3600000 IN NS f.root-servers.net.
+root-servers.net. 3600000 IN NS g.root-servers.net.
+root-servers.net. 3600000 IN NS h.root-servers.net.
+root-servers.net. 3600000 IN NS i.root-servers.net.
+root-servers.net. 3600000 IN NS j.root-servers.net.
+root-servers.net. 3600000 IN NS k.root-servers.net.
+root-servers.net. 3600000 IN NS l.root-servers.net.
+root-servers.net. 3600000 IN NS m.root-servers.net.
+SECTION ADDITIONAL
+a.root-servers.net. 3600000 IN A 198.41.0.4
+a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30
+b.root-servers.net. 3600000 IN A 199.9.14.201
+b.root-servers.net. 3600000 IN AAAA 2001:500:200::b
+c.root-servers.net. 3600000 IN A 192.33.4.12
+c.root-servers.net. 3600000 IN AAAA 2001:500:2::c
+d.root-servers.net. 3600000 IN A 199.7.91.13
+d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d
+e.root-servers.net. 3600000 IN A 192.203.230.10
+e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e
+f.root-servers.net. 3600000 IN A 192.5.5.241
+f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f
+g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d
+h.root-servers.net. 3600000 IN A 198.97.190.53
+h.root-servers.net. 3600000 IN AAAA 2001:500:1::53
+i.root-servers.net. 3600000 IN A 192.36.148.17
+i.root-servers.net. 3600000 IN AAAA 2001:7fe::53
+j.root-servers.net. 3600000 IN A 192.58.128.30
+j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+l.root-servers.net. 3600000 IN A 199.7.83.42
+l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42
+m.root-servers.net. 3600000 IN A 202.12.27.33
+m.root-servers.net. 3600000 IN AAAA 2001:dc3::35
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+k.root-servers.net. IN A
+SECTION ANSWER
+k.root-servers.net. 3600000 IN A 193.0.14.129
+SECTION AUTHORITY
+root-servers.net. 3600000 IN NS a.root-servers.net.
+root-servers.net. 3600000 IN NS b.root-servers.net.
+root-servers.net. 3600000 IN NS c.root-servers.net.
+root-servers.net. 3600000 IN NS d.root-servers.net.
+root-servers.net. 3600000 IN NS e.root-servers.net.
+root-servers.net. 3600000 IN NS f.root-servers.net.
+root-servers.net. 3600000 IN NS g.root-servers.net.
+root-servers.net. 3600000 IN NS h.root-servers.net.
+root-servers.net. 3600000 IN NS i.root-servers.net.
+root-servers.net. 3600000 IN NS j.root-servers.net.
+root-servers.net. 3600000 IN NS k.root-servers.net.
+root-servers.net. 3600000 IN NS l.root-servers.net.
+root-servers.net. 3600000 IN NS m.root-servers.net.
+SECTION ADDITIONAL
+a.root-servers.net. 3600000 IN A 198.41.0.4
+a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30
+b.root-servers.net. 3600000 IN A 199.9.14.201
+b.root-servers.net. 3600000 IN AAAA 2001:500:200::b
+c.root-servers.net. 3600000 IN A 192.33.4.12
+c.root-servers.net. 3600000 IN AAAA 2001:500:2::c
+d.root-servers.net. 3600000 IN A 199.7.91.13
+d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d
+e.root-servers.net. 3600000 IN A 192.203.230.10
+e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e
+f.root-servers.net. 3600000 IN A 192.5.5.241
+f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f
+g.root-servers.net. 3600000 IN A 192.112.36.4
+g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d
+h.root-servers.net. 3600000 IN A 198.97.190.53
+h.root-servers.net. 3600000 IN AAAA 2001:500:1::53
+i.root-servers.net. 3600000 IN A 192.36.148.17
+i.root-servers.net. 3600000 IN AAAA 2001:7fe::53
+j.root-servers.net. 3600000 IN A 192.58.128.30
+j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+l.root-servers.net. 3600000 IN A 199.7.83.42
+l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42
+m.root-servers.net. 3600000 IN A 202.12.27.33
+m.root-servers.net. 3600000 IN AAAA 2001:dc3::35
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+m.root-servers.net. IN AAAA
+SECTION ANSWER
+m.root-servers.net. 3600000 IN AAAA 2001:dc3::35
+SECTION AUTHORITY
+root-servers.net. 3600000 IN NS a.root-servers.net.
+root-servers.net. 3600000 IN NS b.root-servers.net.
+root-servers.net. 3600000 IN NS c.root-servers.net.
+root-servers.net. 3600000 IN NS d.root-servers.net.
+root-servers.net. 3600000 IN NS e.root-servers.net.
+root-servers.net. 3600000 IN NS f.root-servers.net.
+root-servers.net. 3600000 IN NS g.root-servers.net.
+root-servers.net. 3600000 IN NS h.root-servers.net.
+root-servers.net. 3600000 IN NS i.root-servers.net.
+root-servers.net. 3600000 IN NS j.root-servers.net.
+root-servers.net. 3600000 IN NS k.root-servers.net.
+root-servers.net. 3600000 IN NS l.root-servers.net.
+root-servers.net. 3600000 IN NS m.root-servers.net.
+SECTION ADDITIONAL
+a.root-servers.net. 3600000 IN A 198.41.0.4
+a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30
+b.root-servers.net. 3600000 IN A 199.9.14.201
+b.root-servers.net. 3600000 IN AAAA 2001:500:200::b
+c.root-servers.net. 3600000 IN A 192.33.4.12
+c.root-servers.net. 3600000 IN AAAA 2001:500:2::c
+d.root-servers.net. 3600000 IN A 199.7.91.13
+d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d
+e.root-servers.net. 3600000 IN A 192.203.230.10
+e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e
+f.root-servers.net. 3600000 IN A 192.5.5.241
+f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f
+g.root-servers.net. 3600000 IN A 192.112.36.4
+g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d
+h.root-servers.net. 3600000 IN A 198.97.190.53
+h.root-servers.net. 3600000 IN AAAA 2001:500:1::53
+i.root-servers.net. 3600000 IN A 192.36.148.17
+i.root-servers.net. 3600000 IN AAAA 2001:7fe::53
+j.root-servers.net. 3600000 IN A 192.58.128.30
+j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+l.root-servers.net. 3600000 IN A 199.7.83.42
+l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42
+m.root-servers.net. 3600000 IN A 202.12.27.33
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+. IN DNSKEY
+SECTION ANSWER
+. 172800 IN DNSKEY 256 3 8 AwEAAcTQyaIe6nt3xSPOG2L/YfwBkOVT JN6mlnZ249O5Rtt3ZSRQHxQSW61AODYw 6bvgxrrGq8eeOuenFjcSYgNAMcBYoEYY mKDW6e9EryW4ZaT/MCq+8Am06oR40xAA 3fClOM6QjRcT85tP41Go946AicBGP8XO P/Aj1aI/oPRGzRnboUPUok/AzTNnW5np BU69+BuiIwYE7mQOiNBFePyvjQBdoiuY bmuD3Py0IyjlBxzZUXbqLsRL9gYFkCqe TY29Ik7usuzMTa+JRSLz6KGS5RSJ7CTS MjZg8aNaUbN2dvGhakJPh92HnLvMA3Te fFgbKJphFNPA3BWSKLZ02cRWXqM=
+. 172800 IN DNSKEY 256 3 8 AwEAAeVDC34GZILwsQJy97K2Fst4P3XY ZrXLyrkausYzSqEjSUulgh+iLgHg0y7F IF890+sIjXsk7KLJUmCOWfYWPorNKEOK Lk5Zx/4M6D3IHZE3O3m/Eahrc28qQzmT LxiMZAW65MvR2UO3LxVtYOPBEBiDgAQD 47x2JLsJYtavCzNL5WiUk59OgvHmDqmc C7VXYBhK8V8Tic089XJgExGeplKWUt9y yc31ra1swJX51XsOaQz17+vyLVH8AZP2 6KvKFiZeoRbaq6vl+hc8HQnI2ug5rA2z oz3MsSQBvP1f/HvqsWxLqwXXKyDD1QM6 39U+XzVB8CYigyscRP22QCnwKIU=
+. 172800 IN DNSKEY 257 3 8 AwEAAaz/tAm8yTn4Mfeh5eyI96WSVexT BAvkMgJzkKTOiW1vkIbzxeF3+/4RgWOq 7HrxRixHlFlExOLAJr5emLvN7SWXgnLh 4+B5xQlNVz8Og8kvArMtNROxVQuCaSnI DdD5LKyWbRd2n9WGe2R8PzgCmr3EgVLr jyBxWezF0jLHwVN8efS3rCj/EWgvIWgb 9tarpVUDK/b58Da+sqqls3eNbuv7pr+e oZG+SrDK6nWeL3c6H5Apxz7LjVc1uTId sIXxuOLYA4/ilBmSVIzuDWfdRUfhHdY6 +cn8HFRm+2hM8AnXGXws9555KrUB5qih ylGa8subX2Nn6UwNR1AkUTV74bU=
+. 172800 IN RRSIG DNSKEY 8 0 172800 20190711000000 20190620000000 20326 . LeNUOIxGGe+xAKxr13YIXNqMAxVH7RuD XQyVclUuxA9aENp0+yYkeIL+/lkTteEh dHXNVZqYch8QrvcsuCpDN2gKx5D5M04g KAjR5ywgvEdsZHr9DhjCZ3uvXKvbPsi6 14QpjYCxxvtq/ZZE6dhm59K3N3T8Mhm5 l36b6w+fR1F3Kc+eeJqy2ZjVxNe9CClE 4Qy6q78Yu6rS1vZkuzG1l2AT9Gko72St WbdsU2Ry9fBk+uCJOLxej37z5Rfi5EAz FcnfwQYryqCRt2go9PuD0/AulqG8wmTV z23tnwnaxowkYKxFH2yE0d7pDiFjvOyU HdGPXYwl/+GDmjrQsN6JPQ==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+b.root-servers.net. IN NS
+SECTION AUTHORITY
+root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2019061700 14400 7200 1209600 3600000
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+k.root-servers.net. IN NS
+SECTION AUTHORITY
+root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2019061700 14400 7200 1209600 3600000
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+. IN DS
+SECTION AUTHORITY
+. 86400 IN NSEC aaa. NS SOA RRSIG NSEC DNSKEY
+. 86400 IN RRSIG NSEC 8 0 86400 20190708050000 20190625040000 25266 . fAYegvNXOW8j+x++y5EWtNQlie56/WO+ w6PlDWJ87oZPgUJuYPxqCIpoKJttfUBR o1nOzZaUlxQeOE0Daep/fnlo8OtAfauK w5J+l5rZqcaM6C9MA7cB7ZswPVd1p609 rPqgGoxSvuNuX/iFPBqPQhRw5JyiVuwF Q4PSB3Etq85BXUEhlpfcQAt6z3scHlLa ARoZoea3/u9z/xuB+296IgZHOQkp3WJL zJivnrQFisO7vQ7o01t0x6WxtskBwbf3 GXwHg/2DbHY/7QJ4hVWO0/L+tdeJciTM 92+RC/U7GkUPDb0rvfOfntB2MKz0rZhU g5m+qJOJYpG8HGN69f4dyQ==
+. 86400 IN RRSIG SOA 8 0 86400 20190708050000 20190625040000 25266 . kYJsFlFDsY3FO94BM5DRROo34/8EZODz iOXejYh397rIJqr5bjx315WJabGoAf3p gtQ5U6QXDJnrKnuZYK/4b+mYyef722if vfNdKclJxKp5vwdDGKLEu7Z2Ey09K4WD MPeyemaIIlbDw3F7lYzz0ZiZubagtrZu OeD2CUOJO4qauzUpGtXf4cx0r+aQJkPq 4eXQyBQ4gg6Mdh4iBNgjGhYB9SLFNMtb eRMNpJG2ifhjP+pNWd27+TGHOhHTu082 osz2lNYKibuMoEfQeHNlINGIU+8oTa/K 3O7IlOAp1APvDmbKnLgy9FFf+6yCMo5y r+A0RVMZheQA3iEXBGug+g==
+. 86400 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2019062500 1800 900 604800 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+c.root-servers.net. IN AAAA
+SECTION ANSWER
+c.root-servers.net. 3600000 IN AAAA 2001:500:2::c
+SECTION AUTHORITY
+root-servers.net. 3600000 IN NS a.root-servers.net.
+root-servers.net. 3600000 IN NS b.root-servers.net.
+root-servers.net. 3600000 IN NS c.root-servers.net.
+root-servers.net. 3600000 IN NS d.root-servers.net.
+root-servers.net. 3600000 IN NS e.root-servers.net.
+root-servers.net. 3600000 IN NS f.root-servers.net.
+root-servers.net. 3600000 IN NS g.root-servers.net.
+root-servers.net. 3600000 IN NS h.root-servers.net.
+root-servers.net. 3600000 IN NS i.root-servers.net.
+root-servers.net. 3600000 IN NS j.root-servers.net.
+root-servers.net. 3600000 IN NS k.root-servers.net.
+root-servers.net. 3600000 IN NS l.root-servers.net.
+root-servers.net. 3600000 IN NS m.root-servers.net.
+SECTION ADDITIONAL
+a.root-servers.net. 3600000 IN A 198.41.0.4
+a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30
+b.root-servers.net. 3600000 IN A 199.9.14.201
+b.root-servers.net. 3600000 IN AAAA 2001:500:200::b
+c.root-servers.net. 3600000 IN A 192.33.4.12
+d.root-servers.net. 3600000 IN A 199.7.91.13
+d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d
+e.root-servers.net. 3600000 IN A 192.203.230.10
+e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e
+f.root-servers.net. 3600000 IN A 192.5.5.241
+f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f
+g.root-servers.net. 3600000 IN A 192.112.36.4
+g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d
+h.root-servers.net. 3600000 IN A 198.97.190.53
+h.root-servers.net. 3600000 IN AAAA 2001:500:1::53
+i.root-servers.net. 3600000 IN A 192.36.148.17
+i.root-servers.net. 3600000 IN AAAA 2001:7fe::53
+j.root-servers.net. 3600000 IN A 192.58.128.30
+j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+l.root-servers.net. 3600000 IN A 199.7.83.42
+l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42
+m.root-servers.net. 3600000 IN A 202.12.27.33
+m.root-servers.net. 3600000 IN AAAA 2001:dc3::35
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+l.root-servers.net. IN NS
+SECTION AUTHORITY
+root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2019061700 14400 7200 1209600 3600000
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+b.root-servers.net. IN A
+SECTION ANSWER
+b.root-servers.net. 3600000 IN A 199.9.14.201
+SECTION AUTHORITY
+root-servers.net. 3600000 IN NS a.root-servers.net.
+root-servers.net. 3600000 IN NS b.root-servers.net.
+root-servers.net. 3600000 IN NS c.root-servers.net.
+root-servers.net. 3600000 IN NS d.root-servers.net.
+root-servers.net. 3600000 IN NS e.root-servers.net.
+root-servers.net. 3600000 IN NS f.root-servers.net.
+root-servers.net. 3600000 IN NS g.root-servers.net.
+root-servers.net. 3600000 IN NS h.root-servers.net.
+root-servers.net. 3600000 IN NS i.root-servers.net.
+root-servers.net. 3600000 IN NS j.root-servers.net.
+root-servers.net. 3600000 IN NS k.root-servers.net.
+root-servers.net. 3600000 IN NS l.root-servers.net.
+root-servers.net. 3600000 IN NS m.root-servers.net.
+SECTION ADDITIONAL
+a.root-servers.net. 3600000 IN A 198.41.0.4
+a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30
+b.root-servers.net. 3600000 IN AAAA 2001:500:200::b
+c.root-servers.net. 3600000 IN A 192.33.4.12
+c.root-servers.net. 3600000 IN AAAA 2001:500:2::c
+d.root-servers.net. 3600000 IN A 199.7.91.13
+d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d
+e.root-servers.net. 3600000 IN A 192.203.230.10
+e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e
+f.root-servers.net. 3600000 IN A 192.5.5.241
+f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f
+g.root-servers.net. 3600000 IN A 192.112.36.4
+g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d
+h.root-servers.net. 3600000 IN A 198.97.190.53
+h.root-servers.net. 3600000 IN AAAA 2001:500:1::53
+i.root-servers.net. 3600000 IN A 192.36.148.17
+i.root-servers.net. 3600000 IN AAAA 2001:7fe::53
+j.root-servers.net. 3600000 IN A 192.58.128.30
+j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+l.root-servers.net. 3600000 IN A 199.7.83.42
+l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42
+m.root-servers.net. 3600000 IN A 202.12.27.33
+m.root-servers.net. 3600000 IN AAAA 2001:dc3::35
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+m.root-servers.net. IN NS
+SECTION AUTHORITY
+root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2019061700 14400 7200 1209600 3600000
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR RD NOERROR
+SECTION QUESTION
+csas.cz. IN DS
+SECTION AUTHORITY
+cz. 172800 IN NS a.ns.nic.cz.
+cz. 172800 IN NS b.ns.nic.cz.
+cz. 172800 IN NS c.ns.nic.cz.
+cz. 172800 IN NS d.ns.nic.cz.
+cz. 86400 IN DS 20237 13 2 cff0f3ecdbc529c1f0031ba1840bfb835853b9209ed1e508fff48451d7b778e2
+cz. 86400 IN RRSIG DS 8 1 86400 20190708050000 20190625040000 25266 . r7Lxqu4C80oW46tP7BNfJWrXs2K5YEqn IkEKfzXSFqur0cSfnj630EPQfokTYO2Q RCOT/JaNpbUi69MS+d81xFZb5efzzoYE tL3tCE8axm39kzuHKhk2EOSIN8sQPCTC isLppgCbLRPbzKima8Jk5kGs7pV+FK9K vCExdukQ4aB7MYvIZaKzHKP8NAOgKdVk x/BrrGl8IV0T+YvUDo9e8gpdcbhLFXoN w+qZ9xVNIvhSsjzzL1fxrkjJIEdTPzrS HXdUjK8v56KppQJ0pr+XSq2CicRbcn5b ur5HQz4yKfIr2q7aH9CMGuwbMLNDWnjO G+iHdA/ekKLYQ5afWOxaqw==
+SECTION ADDITIONAL
+a.ns.nic.cz. 172800 IN A 194.0.12.1
+a.ns.nic.cz. 172800 IN AAAA 2001:678:f::1
+b.ns.nic.cz. 172800 IN A 194.0.13.1
+b.ns.nic.cz. 172800 IN AAAA 2001:678:10::1
+c.ns.nic.cz. 172800 IN A 194.0.14.1
+c.ns.nic.cz. 172800 IN AAAA 2001:678:11::1
+d.ns.nic.cz. 172800 IN A 193.29.206.1
+d.ns.nic.cz. 172800 IN AAAA 2001:678:1::1
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+a.root-servers.net. IN NS
+SECTION AUTHORITY
+root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2019061700 14400 7200 1209600 3600000
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+g.root-servers.net. IN AAAA
+SECTION ANSWER
+g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d
+SECTION AUTHORITY
+root-servers.net. 3600000 IN NS a.root-servers.net.
+root-servers.net. 3600000 IN NS b.root-servers.net.
+root-servers.net. 3600000 IN NS c.root-servers.net.
+root-servers.net. 3600000 IN NS d.root-servers.net.
+root-servers.net. 3600000 IN NS e.root-servers.net.
+root-servers.net. 3600000 IN NS f.root-servers.net.
+root-servers.net. 3600000 IN NS g.root-servers.net.
+root-servers.net. 3600000 IN NS h.root-servers.net.
+root-servers.net. 3600000 IN NS i.root-servers.net.
+root-servers.net. 3600000 IN NS j.root-servers.net.
+root-servers.net. 3600000 IN NS k.root-servers.net.
+root-servers.net. 3600000 IN NS l.root-servers.net.
+root-servers.net. 3600000 IN NS m.root-servers.net.
+SECTION ADDITIONAL
+a.root-servers.net. 3600000 IN A 198.41.0.4
+a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30
+b.root-servers.net. 3600000 IN A 199.9.14.201
+b.root-servers.net. 3600000 IN AAAA 2001:500:200::b
+c.root-servers.net. 3600000 IN A 192.33.4.12
+c.root-servers.net. 3600000 IN AAAA 2001:500:2::c
+d.root-servers.net. 3600000 IN A 199.7.91.13
+d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d
+e.root-servers.net. 3600000 IN A 192.203.230.10
+e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e
+f.root-servers.net. 3600000 IN A 192.5.5.241
+f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f
+g.root-servers.net. 3600000 IN A 192.112.36.4
+h.root-servers.net. 3600000 IN A 198.97.190.53
+h.root-servers.net. 3600000 IN AAAA 2001:500:1::53
+i.root-servers.net. 3600000 IN A 192.36.148.17
+i.root-servers.net. 3600000 IN AAAA 2001:7fe::53
+j.root-servers.net. 3600000 IN A 192.58.128.30
+j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+l.root-servers.net. 3600000 IN A 199.7.83.42
+l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42
+m.root-servers.net. 3600000 IN A 202.12.27.33
+m.root-servers.net. 3600000 IN AAAA 2001:dc3::35
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+cz. IN DS
+SECTION ANSWER
+cz. 86400 IN DS 20237 13 2 cff0f3ecdbc529c1f0031ba1840bfb835853b9209ed1e508fff48451d7b778e2
+cz. 86400 IN RRSIG DS 8 1 86400 20190708050000 20190625040000 25266 . r7Lxqu4C80oW46tP7BNfJWrXs2K5YEqn IkEKfzXSFqur0cSfnj630EPQfokTYO2Q RCOT/JaNpbUi69MS+d81xFZb5efzzoYE tL3tCE8axm39kzuHKhk2EOSIN8sQPCTC isLppgCbLRPbzKima8Jk5kGs7pV+FK9K vCExdukQ4aB7MYvIZaKzHKP8NAOgKdVk x/BrrGl8IV0T+YvUDo9e8gpdcbhLFXoN w+qZ9xVNIvhSsjzzL1fxrkjJIEdTPzrS HXdUjK8v56KppQJ0pr+XSq2CicRbcn5b ur5HQz4yKfIr2q7aH9CMGuwbMLNDWnjO G+iHdA/ekKLYQ5afWOxaqw==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+j.root-servers.net. IN AAAA
+SECTION ANSWER
+j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30
+SECTION AUTHORITY
+root-servers.net. 3600000 IN NS a.root-servers.net.
+root-servers.net. 3600000 IN NS b.root-servers.net.
+root-servers.net. 3600000 IN NS c.root-servers.net.
+root-servers.net. 3600000 IN NS d.root-servers.net.
+root-servers.net. 3600000 IN NS e.root-servers.net.
+root-servers.net. 3600000 IN NS f.root-servers.net.
+root-servers.net. 3600000 IN NS g.root-servers.net.
+root-servers.net. 3600000 IN NS h.root-servers.net.
+root-servers.net. 3600000 IN NS i.root-servers.net.
+root-servers.net. 3600000 IN NS j.root-servers.net.
+root-servers.net. 3600000 IN NS k.root-servers.net.
+root-servers.net. 3600000 IN NS l.root-servers.net.
+root-servers.net. 3600000 IN NS m.root-servers.net.
+SECTION ADDITIONAL
+a.root-servers.net. 3600000 IN A 198.41.0.4
+a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30
+b.root-servers.net. 3600000 IN A 199.9.14.201
+b.root-servers.net. 3600000 IN AAAA 2001:500:200::b
+c.root-servers.net. 3600000 IN A 192.33.4.12
+c.root-servers.net. 3600000 IN AAAA 2001:500:2::c
+d.root-servers.net. 3600000 IN A 199.7.91.13
+d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d
+e.root-servers.net. 3600000 IN A 192.203.230.10
+e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e
+f.root-servers.net. 3600000 IN A 192.5.5.241
+f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f
+g.root-servers.net. 3600000 IN A 192.112.36.4
+g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d
+h.root-servers.net. 3600000 IN A 198.97.190.53
+h.root-servers.net. 3600000 IN AAAA 2001:500:1::53
+i.root-servers.net. 3600000 IN A 192.36.148.17
+i.root-servers.net. 3600000 IN AAAA 2001:7fe::53
+j.root-servers.net. 3600000 IN A 192.58.128.30
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+l.root-servers.net. 3600000 IN A 199.7.83.42
+l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42
+m.root-servers.net. 3600000 IN A 202.12.27.33
+m.root-servers.net. 3600000 IN AAAA 2001:dc3::35
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+d.root-servers.net. IN AAAA
+SECTION ANSWER
+d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d
+SECTION AUTHORITY
+root-servers.net. 3600000 IN NS a.root-servers.net.
+root-servers.net. 3600000 IN NS b.root-servers.net.
+root-servers.net. 3600000 IN NS c.root-servers.net.
+root-servers.net. 3600000 IN NS d.root-servers.net.
+root-servers.net. 3600000 IN NS e.root-servers.net.
+root-servers.net. 3600000 IN NS f.root-servers.net.
+root-servers.net. 3600000 IN NS g.root-servers.net.
+root-servers.net. 3600000 IN NS h.root-servers.net.
+root-servers.net. 3600000 IN NS i.root-servers.net.
+root-servers.net. 3600000 IN NS j.root-servers.net.
+root-servers.net. 3600000 IN NS k.root-servers.net.
+root-servers.net. 3600000 IN NS l.root-servers.net.
+root-servers.net. 3600000 IN NS m.root-servers.net.
+SECTION ADDITIONAL
+a.root-servers.net. 3600000 IN A 198.41.0.4
+a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30
+b.root-servers.net. 3600000 IN A 199.9.14.201
+b.root-servers.net. 3600000 IN AAAA 2001:500:200::b
+c.root-servers.net. 3600000 IN A 192.33.4.12
+c.root-servers.net. 3600000 IN AAAA 2001:500:2::c
+d.root-servers.net. 3600000 IN A 199.7.91.13
+e.root-servers.net. 3600000 IN A 192.203.230.10
+e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e
+f.root-servers.net. 3600000 IN A 192.5.5.241
+f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f
+g.root-servers.net. 3600000 IN A 192.112.36.4
+g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d
+h.root-servers.net. 3600000 IN A 198.97.190.53
+h.root-servers.net. 3600000 IN AAAA 2001:500:1::53
+i.root-servers.net. 3600000 IN A 192.36.148.17
+i.root-servers.net. 3600000 IN AAAA 2001:7fe::53
+j.root-servers.net. 3600000 IN A 192.58.128.30
+j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+l.root-servers.net. 3600000 IN A 199.7.83.42
+l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42
+m.root-servers.net. 3600000 IN A 202.12.27.33
+m.root-servers.net. 3600000 IN AAAA 2001:dc3::35
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+l.root-servers.net. IN AAAA
+SECTION ANSWER
+l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42
+SECTION AUTHORITY
+root-servers.net. 3600000 IN NS a.root-servers.net.
+root-servers.net. 3600000 IN NS b.root-servers.net.
+root-servers.net. 3600000 IN NS c.root-servers.net.
+root-servers.net. 3600000 IN NS d.root-servers.net.
+root-servers.net. 3600000 IN NS e.root-servers.net.
+root-servers.net. 3600000 IN NS f.root-servers.net.
+root-servers.net. 3600000 IN NS g.root-servers.net.
+root-servers.net. 3600000 IN NS h.root-servers.net.
+root-servers.net. 3600000 IN NS i.root-servers.net.
+root-servers.net. 3600000 IN NS j.root-servers.net.
+root-servers.net. 3600000 IN NS k.root-servers.net.
+root-servers.net. 3600000 IN NS l.root-servers.net.
+root-servers.net. 3600000 IN NS m.root-servers.net.
+SECTION ADDITIONAL
+a.root-servers.net. 3600000 IN A 198.41.0.4
+a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30
+b.root-servers.net. 3600000 IN A 199.9.14.201
+b.root-servers.net. 3600000 IN AAAA 2001:500:200::b
+c.root-servers.net. 3600000 IN A 192.33.4.12
+c.root-servers.net. 3600000 IN AAAA 2001:500:2::c
+d.root-servers.net. 3600000 IN A 199.7.91.13
+d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d
+e.root-servers.net. 3600000 IN A 192.203.230.10
+e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e
+f.root-servers.net. 3600000 IN A 192.5.5.241
+f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f
+g.root-servers.net. 3600000 IN A 192.112.36.4
+g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d
+h.root-servers.net. 3600000 IN A 198.97.190.53
+h.root-servers.net. 3600000 IN AAAA 2001:500:1::53
+i.root-servers.net. 3600000 IN A 192.36.148.17
+i.root-servers.net. 3600000 IN AAAA 2001:7fe::53
+j.root-servers.net. 3600000 IN A 192.58.128.30
+j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+l.root-servers.net. 3600000 IN A 199.7.83.42
+m.root-servers.net. 3600000 IN A 202.12.27.33
+m.root-servers.net. 3600000 IN AAAA 2001:dc3::35
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+a.root-servers.net. IN AAAA
+SECTION ANSWER
+a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30
+SECTION AUTHORITY
+root-servers.net. 3600000 IN NS a.root-servers.net.
+root-servers.net. 3600000 IN NS b.root-servers.net.
+root-servers.net. 3600000 IN NS c.root-servers.net.
+root-servers.net. 3600000 IN NS d.root-servers.net.
+root-servers.net. 3600000 IN NS e.root-servers.net.
+root-servers.net. 3600000 IN NS f.root-servers.net.
+root-servers.net. 3600000 IN NS g.root-servers.net.
+root-servers.net. 3600000 IN NS h.root-servers.net.
+root-servers.net. 3600000 IN NS i.root-servers.net.
+root-servers.net. 3600000 IN NS j.root-servers.net.
+root-servers.net. 3600000 IN NS k.root-servers.net.
+root-servers.net. 3600000 IN NS l.root-servers.net.
+root-servers.net. 3600000 IN NS m.root-servers.net.
+SECTION ADDITIONAL
+a.root-servers.net. 3600000 IN A 198.41.0.4
+b.root-servers.net. 3600000 IN A 199.9.14.201
+b.root-servers.net. 3600000 IN AAAA 2001:500:200::b
+c.root-servers.net. 3600000 IN A 192.33.4.12
+c.root-servers.net. 3600000 IN AAAA 2001:500:2::c
+d.root-servers.net. 3600000 IN A 199.7.91.13
+d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d
+e.root-servers.net. 3600000 IN A 192.203.230.10
+e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e
+f.root-servers.net. 3600000 IN A 192.5.5.241
+f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f
+g.root-servers.net. 3600000 IN A 192.112.36.4
+g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d
+h.root-servers.net. 3600000 IN A 198.97.190.53
+h.root-servers.net. 3600000 IN AAAA 2001:500:1::53
+i.root-servers.net. 3600000 IN A 192.36.148.17
+i.root-servers.net. 3600000 IN AAAA 2001:7fe::53
+j.root-servers.net. 3600000 IN A 192.58.128.30
+j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+l.root-servers.net. 3600000 IN A 199.7.83.42
+l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42
+m.root-servers.net. 3600000 IN A 202.12.27.33
+m.root-servers.net. 3600000 IN AAAA 2001:dc3::35
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+e.root-servers.net. IN AAAA
+SECTION ANSWER
+e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e
+SECTION AUTHORITY
+root-servers.net. 3600000 IN NS a.root-servers.net.
+root-servers.net. 3600000 IN NS b.root-servers.net.
+root-servers.net. 3600000 IN NS c.root-servers.net.
+root-servers.net. 3600000 IN NS d.root-servers.net.
+root-servers.net. 3600000 IN NS e.root-servers.net.
+root-servers.net. 3600000 IN NS f.root-servers.net.
+root-servers.net. 3600000 IN NS g.root-servers.net.
+root-servers.net. 3600000 IN NS h.root-servers.net.
+root-servers.net. 3600000 IN NS i.root-servers.net.
+root-servers.net. 3600000 IN NS j.root-servers.net.
+root-servers.net. 3600000 IN NS k.root-servers.net.
+root-servers.net. 3600000 IN NS l.root-servers.net.
+root-servers.net. 3600000 IN NS m.root-servers.net.
+SECTION ADDITIONAL
+a.root-servers.net. 3600000 IN A 198.41.0.4
+a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30
+b.root-servers.net. 3600000 IN A 199.9.14.201
+b.root-servers.net. 3600000 IN AAAA 2001:500:200::b
+c.root-servers.net. 3600000 IN A 192.33.4.12
+c.root-servers.net. 3600000 IN AAAA 2001:500:2::c
+d.root-servers.net. 3600000 IN A 199.7.91.13
+d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d
+e.root-servers.net. 3600000 IN A 192.203.230.10
+f.root-servers.net. 3600000 IN A 192.5.5.241
+f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f
+g.root-servers.net. 3600000 IN A 192.112.36.4
+g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d
+h.root-servers.net. 3600000 IN A 198.97.190.53
+h.root-servers.net. 3600000 IN AAAA 2001:500:1::53
+i.root-servers.net. 3600000 IN A 192.36.148.17
+i.root-servers.net. 3600000 IN AAAA 2001:7fe::53
+j.root-servers.net. 3600000 IN A 192.58.128.30
+j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+l.root-servers.net. 3600000 IN A 199.7.83.42
+l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42
+m.root-servers.net. 3600000 IN A 202.12.27.33
+m.root-servers.net. 3600000 IN AAAA 2001:dc3::35
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+j.root-servers.net. IN A
+SECTION ANSWER
+j.root-servers.net. 3600000 IN A 192.58.128.30
+SECTION AUTHORITY
+root-servers.net. 3600000 IN NS a.root-servers.net.
+root-servers.net. 3600000 IN NS b.root-servers.net.
+root-servers.net. 3600000 IN NS c.root-servers.net.
+root-servers.net. 3600000 IN NS d.root-servers.net.
+root-servers.net. 3600000 IN NS e.root-servers.net.
+root-servers.net. 3600000 IN NS f.root-servers.net.
+root-servers.net. 3600000 IN NS g.root-servers.net.
+root-servers.net. 3600000 IN NS h.root-servers.net.
+root-servers.net. 3600000 IN NS i.root-servers.net.
+root-servers.net. 3600000 IN NS j.root-servers.net.
+root-servers.net. 3600000 IN NS k.root-servers.net.
+root-servers.net. 3600000 IN NS l.root-servers.net.
+root-servers.net. 3600000 IN NS m.root-servers.net.
+SECTION ADDITIONAL
+a.root-servers.net. 3600000 IN A 198.41.0.4
+a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30
+b.root-servers.net. 3600000 IN A 199.9.14.201
+b.root-servers.net. 3600000 IN AAAA 2001:500:200::b
+c.root-servers.net. 3600000 IN A 192.33.4.12
+c.root-servers.net. 3600000 IN AAAA 2001:500:2::c
+d.root-servers.net. 3600000 IN A 199.7.91.13
+d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d
+e.root-servers.net. 3600000 IN A 192.203.230.10
+e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e
+f.root-servers.net. 3600000 IN A 192.5.5.241
+f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f
+g.root-servers.net. 3600000 IN A 192.112.36.4
+g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d
+h.root-servers.net. 3600000 IN A 198.97.190.53
+h.root-servers.net. 3600000 IN AAAA 2001:500:1::53
+i.root-servers.net. 3600000 IN A 192.36.148.17
+i.root-servers.net. 3600000 IN AAAA 2001:7fe::53
+j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+l.root-servers.net. 3600000 IN A 199.7.83.42
+l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42
+m.root-servers.net. 3600000 IN A 202.12.27.33
+m.root-servers.net. 3600000 IN AAAA 2001:dc3::35
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+i.root-servers.net. IN NS
+SECTION AUTHORITY
+root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2019061700 14400 7200 1209600 3600000
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+k.root-servers.net. IN AAAA
+SECTION ANSWER
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+SECTION AUTHORITY
+root-servers.net. 3600000 IN NS a.root-servers.net.
+root-servers.net. 3600000 IN NS b.root-servers.net.
+root-servers.net. 3600000 IN NS c.root-servers.net.
+root-servers.net. 3600000 IN NS d.root-servers.net.
+root-servers.net. 3600000 IN NS e.root-servers.net.
+root-servers.net. 3600000 IN NS f.root-servers.net.
+root-servers.net. 3600000 IN NS g.root-servers.net.
+root-servers.net. 3600000 IN NS h.root-servers.net.
+root-servers.net. 3600000 IN NS i.root-servers.net.
+root-servers.net. 3600000 IN NS j.root-servers.net.
+root-servers.net. 3600000 IN NS k.root-servers.net.
+root-servers.net. 3600000 IN NS l.root-servers.net.
+root-servers.net. 3600000 IN NS m.root-servers.net.
+SECTION ADDITIONAL
+a.root-servers.net. 3600000 IN A 198.41.0.4
+a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30
+b.root-servers.net. 3600000 IN A 199.9.14.201
+b.root-servers.net. 3600000 IN AAAA 2001:500:200::b
+c.root-servers.net. 3600000 IN A 192.33.4.12
+c.root-servers.net. 3600000 IN AAAA 2001:500:2::c
+d.root-servers.net. 3600000 IN A 199.7.91.13
+d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d
+e.root-servers.net. 3600000 IN A 192.203.230.10
+e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e
+f.root-servers.net. 3600000 IN A 192.5.5.241
+f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f
+g.root-servers.net. 3600000 IN A 192.112.36.4
+g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d
+h.root-servers.net. 3600000 IN A 198.97.190.53
+h.root-servers.net. 3600000 IN AAAA 2001:500:1::53
+i.root-servers.net. 3600000 IN A 192.36.148.17
+i.root-servers.net. 3600000 IN AAAA 2001:7fe::53
+j.root-servers.net. 3600000 IN A 192.58.128.30
+j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30
+k.root-servers.net. 3600000 IN A 193.0.14.129
+l.root-servers.net. 3600000 IN A 199.7.83.42
+l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42
+m.root-servers.net. 3600000 IN A 202.12.27.33
+m.root-servers.net. 3600000 IN AAAA 2001:dc3::35
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+net. IN DS
+SECTION ANSWER
+net. 86400 IN DS 35886 8 2 7862b27f5f516ebe19680444d4ce5e762981931842c465f00236401d8bd973ee
+net. 86400 IN RRSIG DS 8 1 86400 20190708050000 20190625040000 25266 . EK4wI33V5RQyA5SAxBfX1oTiDeGfOzXr u0OA6KaXALQOMELkugzUD3NipvVpzO7B 0ZYSsnNn+Kk1h0qJBE/ZWpHHZyvZCg1o zo+kq1Z7gGJvlV4Y9XfuwIGPZKL0tlkm LBVSBd36yQy/x4gFyBKvRgIDd1IyKrjT xJYENyNwvtj3MkrT+Njsg1NWXP5ORRx1 r0zVlq2snbJsp8ze+sLYrSqVXbihg4mq JoMe7NB4M9EYEMfBOUcWo8Wrj73jiYRx 0uJ3HfvOHBqBgVFyhMcr4FeCiN9F9V6C xTQBQnL3lQF1TnOhN//Z7h7TvLulxHRu DeKEsZDcoC4el8u1Fx7t/w==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+f.root-servers.net. IN A
+SECTION ANSWER
+f.root-servers.net. 3600000 IN A 192.5.5.241
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+f.root-servers.net. IN A
+SECTION ANSWER
+f.root-servers.net. 3600000 IN A 192.5.5.241
+SECTION AUTHORITY
+root-servers.net. 3600000 IN NS a.root-servers.net.
+root-servers.net. 3600000 IN NS b.root-servers.net.
+root-servers.net. 3600000 IN NS c.root-servers.net.
+root-servers.net. 3600000 IN NS d.root-servers.net.
+root-servers.net. 3600000 IN NS e.root-servers.net.
+root-servers.net. 3600000 IN NS f.root-servers.net.
+root-servers.net. 3600000 IN NS g.root-servers.net.
+root-servers.net. 3600000 IN NS h.root-servers.net.
+root-servers.net. 3600000 IN NS i.root-servers.net.
+root-servers.net. 3600000 IN NS j.root-servers.net.
+root-servers.net. 3600000 IN NS k.root-servers.net.
+root-servers.net. 3600000 IN NS l.root-servers.net.
+root-servers.net. 3600000 IN NS m.root-servers.net.
+SECTION ADDITIONAL
+a.root-servers.net. 3600000 IN A 198.41.0.4
+a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30
+b.root-servers.net. 3600000 IN A 199.9.14.201
+b.root-servers.net. 3600000 IN AAAA 2001:500:200::b
+c.root-servers.net. 3600000 IN A 192.33.4.12
+c.root-servers.net. 3600000 IN AAAA 2001:500:2::c
+d.root-servers.net. 3600000 IN A 199.7.91.13
+d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d
+e.root-servers.net. 3600000 IN A 192.203.230.10
+e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e
+f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f
+g.root-servers.net. 3600000 IN A 192.112.36.4
+g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d
+h.root-servers.net. 3600000 IN A 198.97.190.53
+h.root-servers.net. 3600000 IN AAAA 2001:500:1::53
+i.root-servers.net. 3600000 IN A 192.36.148.17
+i.root-servers.net. 3600000 IN AAAA 2001:7fe::53
+j.root-servers.net. 3600000 IN A 192.58.128.30
+j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+l.root-servers.net. 3600000 IN A 199.7.83.42
+l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42
+m.root-servers.net. 3600000 IN A 202.12.27.33
+m.root-servers.net. 3600000 IN AAAA 2001:dc3::35
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+f.root-servers.net. IN AAAA
+SECTION ANSWER
+f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f
+SECTION AUTHORITY
+root-servers.net. 3600000 IN NS a.root-servers.net.
+root-servers.net. 3600000 IN NS b.root-servers.net.
+root-servers.net. 3600000 IN NS c.root-servers.net.
+root-servers.net. 3600000 IN NS d.root-servers.net.
+root-servers.net. 3600000 IN NS e.root-servers.net.
+root-servers.net. 3600000 IN NS f.root-servers.net.
+root-servers.net. 3600000 IN NS g.root-servers.net.
+root-servers.net. 3600000 IN NS h.root-servers.net.
+root-servers.net. 3600000 IN NS i.root-servers.net.
+root-servers.net. 3600000 IN NS j.root-servers.net.
+root-servers.net. 3600000 IN NS k.root-servers.net.
+root-servers.net. 3600000 IN NS l.root-servers.net.
+root-servers.net. 3600000 IN NS m.root-servers.net.
+SECTION ADDITIONAL
+a.root-servers.net. 3600000 IN A 198.41.0.4
+a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30
+b.root-servers.net. 3600000 IN A 199.9.14.201
+b.root-servers.net. 3600000 IN AAAA 2001:500:200::b
+c.root-servers.net. 3600000 IN A 192.33.4.12
+c.root-servers.net. 3600000 IN AAAA 2001:500:2::c
+d.root-servers.net. 3600000 IN A 199.7.91.13
+d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d
+e.root-servers.net. 3600000 IN A 192.203.230.10
+e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e
+f.root-servers.net. 3600000 IN A 192.5.5.241
+g.root-servers.net. 3600000 IN A 192.112.36.4
+g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d
+h.root-servers.net. 3600000 IN A 198.97.190.53
+h.root-servers.net. 3600000 IN AAAA 2001:500:1::53
+i.root-servers.net. 3600000 IN A 192.36.148.17
+i.root-servers.net. 3600000 IN AAAA 2001:7fe::53
+j.root-servers.net. 3600000 IN A 192.58.128.30
+j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+l.root-servers.net. 3600000 IN A 199.7.83.42
+l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42
+m.root-servers.net. 3600000 IN A 202.12.27.33
+m.root-servers.net. 3600000 IN AAAA 2001:dc3::35
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+h.root-servers.net. IN AAAA
+SECTION ANSWER
+h.root-servers.net. 3600000 IN AAAA 2001:500:1::53
+SECTION AUTHORITY
+root-servers.net. 3600000 IN NS a.root-servers.net.
+root-servers.net. 3600000 IN NS b.root-servers.net.
+root-servers.net. 3600000 IN NS c.root-servers.net.
+root-servers.net. 3600000 IN NS d.root-servers.net.
+root-servers.net. 3600000 IN NS e.root-servers.net.
+root-servers.net. 3600000 IN NS f.root-servers.net.
+root-servers.net. 3600000 IN NS g.root-servers.net.
+root-servers.net. 3600000 IN NS h.root-servers.net.
+root-servers.net. 3600000 IN NS i.root-servers.net.
+root-servers.net. 3600000 IN NS j.root-servers.net.
+root-servers.net. 3600000 IN NS k.root-servers.net.
+root-servers.net. 3600000 IN NS l.root-servers.net.
+root-servers.net. 3600000 IN NS m.root-servers.net.
+SECTION ADDITIONAL
+a.root-servers.net. 3600000 IN A 198.41.0.4
+a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30
+b.root-servers.net. 3600000 IN A 199.9.14.201
+b.root-servers.net. 3600000 IN AAAA 2001:500:200::b
+c.root-servers.net. 3600000 IN A 192.33.4.12
+c.root-servers.net. 3600000 IN AAAA 2001:500:2::c
+d.root-servers.net. 3600000 IN A 199.7.91.13
+d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d
+e.root-servers.net. 3600000 IN A 192.203.230.10
+e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e
+f.root-servers.net. 3600000 IN A 192.5.5.241
+f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f
+g.root-servers.net. 3600000 IN A 192.112.36.4
+g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d
+h.root-servers.net. 3600000 IN A 198.97.190.53
+i.root-servers.net. 3600000 IN A 192.36.148.17
+i.root-servers.net. 3600000 IN AAAA 2001:7fe::53
+j.root-servers.net. 3600000 IN A 192.58.128.30
+j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+l.root-servers.net. 3600000 IN A 199.7.83.42
+l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42
+m.root-servers.net. 3600000 IN A 202.12.27.33
+m.root-servers.net. 3600000 IN AAAA 2001:dc3::35
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+e.root-servers.net. IN NS
+SECTION AUTHORITY
+root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2019061700 14400 7200 1209600 3600000
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+b.root-servers.net. IN AAAA
+SECTION ANSWER
+b.root-servers.net. 3600000 IN AAAA 2001:500:200::b
+SECTION AUTHORITY
+root-servers.net. 3600000 IN NS a.root-servers.net.
+root-servers.net. 3600000 IN NS b.root-servers.net.
+root-servers.net. 3600000 IN NS c.root-servers.net.
+root-servers.net. 3600000 IN NS d.root-servers.net.
+root-servers.net. 3600000 IN NS e.root-servers.net.
+root-servers.net. 3600000 IN NS f.root-servers.net.
+root-servers.net. 3600000 IN NS g.root-servers.net.
+root-servers.net. 3600000 IN NS h.root-servers.net.
+root-servers.net. 3600000 IN NS i.root-servers.net.
+root-servers.net. 3600000 IN NS j.root-servers.net.
+root-servers.net. 3600000 IN NS k.root-servers.net.
+root-servers.net. 3600000 IN NS l.root-servers.net.
+root-servers.net. 3600000 IN NS m.root-servers.net.
+SECTION ADDITIONAL
+a.root-servers.net. 3600000 IN A 198.41.0.4
+a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30
+b.root-servers.net. 3600000 IN A 199.9.14.201
+c.root-servers.net. 3600000 IN A 192.33.4.12
+c.root-servers.net. 3600000 IN AAAA 2001:500:2::c
+d.root-servers.net. 3600000 IN A 199.7.91.13
+d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d
+e.root-servers.net. 3600000 IN A 192.203.230.10
+e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e
+f.root-servers.net. 3600000 IN A 192.5.5.241
+f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f
+g.root-servers.net. 3600000 IN A 192.112.36.4
+g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d
+h.root-servers.net. 3600000 IN A 198.97.190.53
+h.root-servers.net. 3600000 IN AAAA 2001:500:1::53
+i.root-servers.net. 3600000 IN A 192.36.148.17
+i.root-servers.net. 3600000 IN AAAA 2001:7fe::53
+j.root-servers.net. 3600000 IN A 192.58.128.30
+j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+l.root-servers.net. 3600000 IN A 199.7.83.42
+l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42
+m.root-servers.net. 3600000 IN A 202.12.27.33
+m.root-servers.net. 3600000 IN AAAA 2001:dc3::35
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR RD NOERROR
+SECTION QUESTION
+gtld-servers.net. IN DS
+SECTION AUTHORITY
+net. 172800 IN NS a.gtld-servers.net.
+net. 172800 IN NS b.gtld-servers.net.
+net. 172800 IN NS c.gtld-servers.net.
+net. 172800 IN NS d.gtld-servers.net.
+net. 172800 IN NS e.gtld-servers.net.
+net. 172800 IN NS f.gtld-servers.net.
+net. 172800 IN NS g.gtld-servers.net.
+net. 172800 IN NS h.gtld-servers.net.
+net. 172800 IN NS i.gtld-servers.net.
+net. 172800 IN NS j.gtld-servers.net.
+net. 172800 IN NS k.gtld-servers.net.
+net. 172800 IN NS l.gtld-servers.net.
+net. 172800 IN NS m.gtld-servers.net.
+net. 86400 IN DS 35886 8 2 7862b27f5f516ebe19680444d4ce5e762981931842c465f00236401d8bd973ee
+net. 86400 IN RRSIG DS 8 1 86400 20190708050000 20190625040000 25266 . EK4wI33V5RQyA5SAxBfX1oTiDeGfOzXr u0OA6KaXALQOMELkugzUD3NipvVpzO7B 0ZYSsnNn+Kk1h0qJBE/ZWpHHZyvZCg1o zo+kq1Z7gGJvlV4Y9XfuwIGPZKL0tlkm LBVSBd36yQy/x4gFyBKvRgIDd1IyKrjT xJYENyNwvtj3MkrT+Njsg1NWXP5ORRx1 r0zVlq2snbJsp8ze+sLYrSqVXbihg4mq JoMe7NB4M9EYEMfBOUcWo8Wrj73jiYRx 0uJ3HfvOHBqBgVFyhMcr4FeCiN9F9V6C xTQBQnL3lQF1TnOhN//Z7h7TvLulxHRu DeKEsZDcoC4el8u1Fx7t/w==
+SECTION ADDITIONAL
+a.gtld-servers.net. 172800 IN A 192.5.6.30
+a.gtld-servers.net. 172800 IN AAAA 2001:503:a83e::2:30
+b.gtld-servers.net. 172800 IN A 192.33.14.30
+b.gtld-servers.net. 172800 IN AAAA 2001:503:231d::2:30
+c.gtld-servers.net. 172800 IN A 192.26.92.30
+c.gtld-servers.net. 172800 IN AAAA 2001:503:83eb::30
+d.gtld-servers.net. 172800 IN A 192.31.80.30
+d.gtld-servers.net. 172800 IN AAAA 2001:500:856e::30
+e.gtld-servers.net. 172800 IN A 192.12.94.30
+e.gtld-servers.net. 172800 IN AAAA 2001:502:1ca1::30
+f.gtld-servers.net. 172800 IN A 192.35.51.30
+f.gtld-servers.net. 172800 IN AAAA 2001:503:d414::30
+g.gtld-servers.net. 172800 IN A 192.42.93.30
+g.gtld-servers.net. 172800 IN AAAA 2001:503:eea3::30
+h.gtld-servers.net. 172800 IN A 192.54.112.30
+h.gtld-servers.net. 172800 IN AAAA 2001:502:8cc::30
+i.gtld-servers.net. 172800 IN A 192.43.172.30
+i.gtld-servers.net. 172800 IN AAAA 2001:503:39c1::30
+j.gtld-servers.net. 172800 IN A 192.48.79.30
+j.gtld-servers.net. 172800 IN AAAA 2001:502:7094::30
+k.gtld-servers.net. 172800 IN A 192.52.178.30
+k.gtld-servers.net. 172800 IN AAAA 2001:503:d2d::30
+l.gtld-servers.net. 172800 IN A 192.41.162.30
+l.gtld-servers.net. 172800 IN AAAA 2001:500:d937::30
+m.gtld-servers.net. 172800 IN A 192.55.83.30
+m.gtld-servers.net. 172800 IN AAAA 2001:501:b1f9::30
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR RD NOERROR
+SECTION QUESTION
+nstld.com. IN DS
+SECTION AUTHORITY
+com. 172800 IN NS a.gtld-servers.net.
+com. 172800 IN NS b.gtld-servers.net.
+com. 172800 IN NS c.gtld-servers.net.
+com. 172800 IN NS d.gtld-servers.net.
+com. 172800 IN NS e.gtld-servers.net.
+com. 172800 IN NS f.gtld-servers.net.
+com. 172800 IN NS g.gtld-servers.net.
+com. 172800 IN NS h.gtld-servers.net.
+com. 172800 IN NS i.gtld-servers.net.
+com. 172800 IN NS j.gtld-servers.net.
+com. 172800 IN NS k.gtld-servers.net.
+com. 172800 IN NS l.gtld-servers.net.
+com. 172800 IN NS m.gtld-servers.net.
+com. 86400 IN DS 30909 8 2 e2d3c916f6deeac73294e8268fb5885044a833fc5459588f4a9184cfc41a5766
+com. 86400 IN RRSIG DS 8 1 86400 20190708050000 20190625040000 25266 . h8CYVMqouUO2IAPlG4Iqf06ykpl07wny KuM2dRGhrfx5hQbF0CpzGRwT2B6i2drI td9i7BSA4GVKLlTYr9n3Xd+BcAHKwywv 44A2WmTAo3xWMv4THwowwu29B4bAKe0V WQKDfmZ92m1yn8T3MCNZWtuGGaLcY6+g fKgyuHu5fEakVn2GFMdAMayBBFTF0bp4 hVFuNSJBe/1EnFZMcxU9aNuCyC8xup25 7K3x1rcM0hthHr8o0Vevpima1YXsWDGb RDIkDyStPDIQ1c0C9LHMaaGR+MA+fxoL 2x4w2lwOptCK//zpfyPvj11oIyouwgdh Fe3PCf9hS03Y1FsiY+mtWw==
+SECTION ADDITIONAL
+a.gtld-servers.net. 172800 IN A 192.5.6.30
+a.gtld-servers.net. 172800 IN AAAA 2001:503:a83e::2:30
+b.gtld-servers.net. 172800 IN A 192.33.14.30
+b.gtld-servers.net. 172800 IN AAAA 2001:503:231d::2:30
+c.gtld-servers.net. 172800 IN A 192.26.92.30
+c.gtld-servers.net. 172800 IN AAAA 2001:503:83eb::30
+d.gtld-servers.net. 172800 IN A 192.31.80.30
+d.gtld-servers.net. 172800 IN AAAA 2001:500:856e::30
+e.gtld-servers.net. 172800 IN A 192.12.94.30
+e.gtld-servers.net. 172800 IN AAAA 2001:502:1ca1::30
+f.gtld-servers.net. 172800 IN A 192.35.51.30
+f.gtld-servers.net. 172800 IN AAAA 2001:503:d414::30
+g.gtld-servers.net. 172800 IN A 192.42.93.30
+g.gtld-servers.net. 172800 IN AAAA 2001:503:eea3::30
+h.gtld-servers.net. 172800 IN A 192.54.112.30
+h.gtld-servers.net. 172800 IN AAAA 2001:502:8cc::30
+i.gtld-servers.net. 172800 IN A 192.43.172.30
+i.gtld-servers.net. 172800 IN AAAA 2001:503:39c1::30
+j.gtld-servers.net. 172800 IN A 192.48.79.30
+j.gtld-servers.net. 172800 IN AAAA 2001:502:7094::30
+k.gtld-servers.net. 172800 IN A 192.52.178.30
+k.gtld-servers.net. 172800 IN AAAA 2001:503:d2d::30
+l.gtld-servers.net. 172800 IN A 192.41.162.30
+l.gtld-servers.net. 172800 IN AAAA 2001:500:d937::30
+m.gtld-servers.net. 172800 IN A 192.55.83.30
+m.gtld-servers.net. 172800 IN AAAA 2001:501:b1f9::30
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+m.root-servers.net. IN A
+SECTION ANSWER
+m.root-servers.net. 3600000 IN A 202.12.27.33
+SECTION AUTHORITY
+root-servers.net. 3600000 IN NS a.root-servers.net.
+root-servers.net. 3600000 IN NS b.root-servers.net.
+root-servers.net. 3600000 IN NS c.root-servers.net.
+root-servers.net. 3600000 IN NS d.root-servers.net.
+root-servers.net. 3600000 IN NS e.root-servers.net.
+root-servers.net. 3600000 IN NS f.root-servers.net.
+root-servers.net. 3600000 IN NS g.root-servers.net.
+root-servers.net. 3600000 IN NS h.root-servers.net.
+root-servers.net. 3600000 IN NS i.root-servers.net.
+root-servers.net. 3600000 IN NS j.root-servers.net.
+root-servers.net. 3600000 IN NS k.root-servers.net.
+root-servers.net. 3600000 IN NS l.root-servers.net.
+root-servers.net. 3600000 IN NS m.root-servers.net.
+SECTION ADDITIONAL
+a.root-servers.net. 3600000 IN A 198.41.0.4
+a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30
+b.root-servers.net. 3600000 IN A 199.9.14.201
+b.root-servers.net. 3600000 IN AAAA 2001:500:200::b
+c.root-servers.net. 3600000 IN A 192.33.4.12
+c.root-servers.net. 3600000 IN AAAA 2001:500:2::c
+d.root-servers.net. 3600000 IN A 199.7.91.13
+d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d
+e.root-servers.net. 3600000 IN A 192.203.230.10
+e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e
+f.root-servers.net. 3600000 IN A 192.5.5.241
+f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f
+g.root-servers.net. 3600000 IN A 192.112.36.4
+g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d
+h.root-servers.net. 3600000 IN A 198.97.190.53
+h.root-servers.net. 3600000 IN AAAA 2001:500:1::53
+i.root-servers.net. 3600000 IN A 192.36.148.17
+i.root-servers.net. 3600000 IN AAAA 2001:7fe::53
+j.root-servers.net. 3600000 IN A 192.58.128.30
+j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+l.root-servers.net. 3600000 IN A 199.7.83.42
+l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42
+m.root-servers.net. 3600000 IN AAAA 2001:dc3::35
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+h.root-servers.net. IN A
+SECTION ANSWER
+h.root-servers.net. 3600000 IN A 198.97.190.53
+SECTION AUTHORITY
+root-servers.net. 3600000 IN NS a.root-servers.net.
+root-servers.net. 3600000 IN NS b.root-servers.net.
+root-servers.net. 3600000 IN NS c.root-servers.net.
+root-servers.net. 3600000 IN NS d.root-servers.net.
+root-servers.net. 3600000 IN NS e.root-servers.net.
+root-servers.net. 3600000 IN NS f.root-servers.net.
+root-servers.net. 3600000 IN NS g.root-servers.net.
+root-servers.net. 3600000 IN NS h.root-servers.net.
+root-servers.net. 3600000 IN NS i.root-servers.net.
+root-servers.net. 3600000 IN NS j.root-servers.net.
+root-servers.net. 3600000 IN NS k.root-servers.net.
+root-servers.net. 3600000 IN NS l.root-servers.net.
+root-servers.net. 3600000 IN NS m.root-servers.net.
+SECTION ADDITIONAL
+a.root-servers.net. 3600000 IN A 198.41.0.4
+a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30
+b.root-servers.net. 3600000 IN A 199.9.14.201
+b.root-servers.net. 3600000 IN AAAA 2001:500:200::b
+c.root-servers.net. 3600000 IN A 192.33.4.12
+c.root-servers.net. 3600000 IN AAAA 2001:500:2::c
+d.root-servers.net. 3600000 IN A 199.7.91.13
+d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d
+e.root-servers.net. 3600000 IN A 192.203.230.10
+e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e
+f.root-servers.net. 3600000 IN A 192.5.5.241
+f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f
+g.root-servers.net. 3600000 IN A 192.112.36.4
+g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d
+h.root-servers.net. 3600000 IN AAAA 2001:500:1::53
+i.root-servers.net. 3600000 IN A 192.36.148.17
+i.root-servers.net. 3600000 IN AAAA 2001:7fe::53
+j.root-servers.net. 3600000 IN A 192.58.128.30
+j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+l.root-servers.net. 3600000 IN A 199.7.83.42
+l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42
+m.root-servers.net. 3600000 IN A 202.12.27.33
+m.root-servers.net. 3600000 IN AAAA 2001:dc3::35
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+com. IN DS
+SECTION ANSWER
+com. 86400 IN DS 30909 8 2 e2d3c916f6deeac73294e8268fb5885044a833fc5459588f4a9184cfc41a5766
+com. 86400 IN RRSIG DS 8 1 86400 20190708050000 20190625040000 25266 . h8CYVMqouUO2IAPlG4Iqf06ykpl07wny KuM2dRGhrfx5hQbF0CpzGRwT2B6i2drI td9i7BSA4GVKLlTYr9n3Xd+BcAHKwywv 44A2WmTAo3xWMv4THwowwu29B4bAKe0V WQKDfmZ92m1yn8T3MCNZWtuGGaLcY6+g fKgyuHu5fEakVn2GFMdAMayBBFTF0bp4 hVFuNSJBe/1EnFZMcxU9aNuCyC8xup25 7K3x1rcM0hthHr8o0Vevpima1YXsWDGb RDIkDyStPDIQ1c0C9LHMaaGR+MA+fxoL 2x4w2lwOptCK//zpfyPvj11oIyouwgdh Fe3PCf9hS03Y1FsiY+mtWw==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR RD NOERROR
+SECTION QUESTION
+nic.cz. IN DS
+SECTION AUTHORITY
+cz. 172800 IN NS a.ns.nic.cz.
+cz. 172800 IN NS b.ns.nic.cz.
+cz. 172800 IN NS c.ns.nic.cz.
+cz. 172800 IN NS d.ns.nic.cz.
+cz. 86400 IN DS 20237 13 2 cff0f3ecdbc529c1f0031ba1840bfb835853b9209ed1e508fff48451d7b778e2
+cz. 86400 IN RRSIG DS 8 1 86400 20190708050000 20190625040000 25266 . r7Lxqu4C80oW46tP7BNfJWrXs2K5YEqn IkEKfzXSFqur0cSfnj630EPQfokTYO2Q RCOT/JaNpbUi69MS+d81xFZb5efzzoYE tL3tCE8axm39kzuHKhk2EOSIN8sQPCTC isLppgCbLRPbzKima8Jk5kGs7pV+FK9K vCExdukQ4aB7MYvIZaKzHKP8NAOgKdVk x/BrrGl8IV0T+YvUDo9e8gpdcbhLFXoN w+qZ9xVNIvhSsjzzL1fxrkjJIEdTPzrS HXdUjK8v56KppQJ0pr+XSq2CicRbcn5b ur5HQz4yKfIr2q7aH9CMGuwbMLNDWnjO G+iHdA/ekKLYQ5afWOxaqw==
+SECTION ADDITIONAL
+a.ns.nic.cz. 172800 IN A 194.0.12.1
+a.ns.nic.cz. 172800 IN AAAA 2001:678:f::1
+b.ns.nic.cz. 172800 IN A 194.0.13.1
+b.ns.nic.cz. 172800 IN AAAA 2001:678:10::1
+c.ns.nic.cz. 172800 IN A 194.0.14.1
+c.ns.nic.cz. 172800 IN AAAA 2001:678:11::1
+d.ns.nic.cz. 172800 IN A 193.29.206.1
+d.ns.nic.cz. 172800 IN AAAA 2001:678:1::1
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+l.root-servers.net. IN A
+SECTION ANSWER
+l.root-servers.net. 3600000 IN A 199.7.83.42
+SECTION AUTHORITY
+root-servers.net. 3600000 IN NS a.root-servers.net.
+root-servers.net. 3600000 IN NS b.root-servers.net.
+root-servers.net. 3600000 IN NS c.root-servers.net.
+root-servers.net. 3600000 IN NS d.root-servers.net.
+root-servers.net. 3600000 IN NS e.root-servers.net.
+root-servers.net. 3600000 IN NS f.root-servers.net.
+root-servers.net. 3600000 IN NS g.root-servers.net.
+root-servers.net. 3600000 IN NS h.root-servers.net.
+root-servers.net. 3600000 IN NS i.root-servers.net.
+root-servers.net. 3600000 IN NS j.root-servers.net.
+root-servers.net. 3600000 IN NS k.root-servers.net.
+root-servers.net. 3600000 IN NS l.root-servers.net.
+root-servers.net. 3600000 IN NS m.root-servers.net.
+SECTION ADDITIONAL
+a.root-servers.net. 3600000 IN A 198.41.0.4
+a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30
+b.root-servers.net. 3600000 IN A 199.9.14.201
+b.root-servers.net. 3600000 IN AAAA 2001:500:200::b
+c.root-servers.net. 3600000 IN A 192.33.4.12
+c.root-servers.net. 3600000 IN AAAA 2001:500:2::c
+d.root-servers.net. 3600000 IN A 199.7.91.13
+d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d
+e.root-servers.net. 3600000 IN A 192.203.230.10
+e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e
+f.root-servers.net. 3600000 IN A 192.5.5.241
+f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f
+g.root-servers.net. 3600000 IN A 192.112.36.4
+g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d
+h.root-servers.net. 3600000 IN A 198.97.190.53
+h.root-servers.net. 3600000 IN AAAA 2001:500:1::53
+i.root-servers.net. 3600000 IN A 192.36.148.17
+i.root-servers.net. 3600000 IN AAAA 2001:7fe::53
+j.root-servers.net. 3600000 IN A 192.58.128.30
+j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42
+m.root-servers.net. 3600000 IN A 202.12.27.33
+m.root-servers.net. 3600000 IN AAAA 2001:dc3::35
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+d.root-servers.net. IN NS
+SECTION AUTHORITY
+root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2019061700 14400 7200 1209600 3600000
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH subdomain
+ADJUST copy_id copy_query
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+root-servers.net. IN NS
+SECTION ANSWER
+root-servers.net. 3600000 IN NS a.root-servers.net.
+root-servers.net. 3600000 IN NS b.root-servers.net.
+root-servers.net. 3600000 IN NS c.root-servers.net.
+root-servers.net. 3600000 IN NS d.root-servers.net.
+root-servers.net. 3600000 IN NS e.root-servers.net.
+root-servers.net. 3600000 IN NS f.root-servers.net.
+root-servers.net. 3600000 IN NS g.root-servers.net.
+root-servers.net. 3600000 IN NS h.root-servers.net.
+root-servers.net. 3600000 IN NS i.root-servers.net.
+root-servers.net. 3600000 IN NS j.root-servers.net.
+root-servers.net. 3600000 IN NS k.root-servers.net.
+root-servers.net. 3600000 IN NS l.root-servers.net.
+root-servers.net. 3600000 IN NS m.root-servers.net.
+SECTION ADDITIONAL
+a.root-servers.net. 3600000 IN A 198.41.0.4
+a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30
+b.root-servers.net. 3600000 IN A 199.9.14.201
+b.root-servers.net. 3600000 IN AAAA 2001:500:200::b
+c.root-servers.net. 3600000 IN A 192.33.4.12
+c.root-servers.net. 3600000 IN AAAA 2001:500:2::c
+d.root-servers.net. 3600000 IN A 199.7.91.13
+d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d
+e.root-servers.net. 3600000 IN A 192.203.230.10
+e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e
+f.root-servers.net. 3600000 IN A 192.5.5.241
+f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f
+g.root-servers.net. 3600000 IN A 192.112.36.4
+g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d
+h.root-servers.net. 3600000 IN A 198.97.190.53
+h.root-servers.net. 3600000 IN AAAA 2001:500:1::53
+i.root-servers.net. 3600000 IN A 192.36.148.17
+i.root-servers.net. 3600000 IN AAAA 2001:7fe::53
+j.root-servers.net. 3600000 IN A 192.58.128.30
+j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+l.root-servers.net. 3600000 IN A 199.7.83.42
+l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42
+m.root-servers.net. 3600000 IN A 202.12.27.33
+m.root-servers.net. 3600000 IN AAAA 2001:dc3::35
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH subdomain
+ADJUST copy_id copy_query
+REPLY QR RD NOERROR
+SECTION QUESTION
+cz. IN NS
+SECTION AUTHORITY
+cz. 172800 IN NS a.ns.nic.cz.
+cz. 172800 IN NS b.ns.nic.cz.
+cz. 172800 IN NS c.ns.nic.cz.
+cz. 172800 IN NS d.ns.nic.cz.
+cz. 86400 IN DS 20237 13 2 cff0f3ecdbc529c1f0031ba1840bfb835853b9209ed1e508fff48451d7b778e2
+cz. 86400 IN RRSIG DS 8 1 86400 20190708050000 20190625040000 25266 . r7Lxqu4C80oW46tP7BNfJWrXs2K5YEqn IkEKfzXSFqur0cSfnj630EPQfokTYO2Q RCOT/JaNpbUi69MS+d81xFZb5efzzoYE tL3tCE8axm39kzuHKhk2EOSIN8sQPCTC isLppgCbLRPbzKima8Jk5kGs7pV+FK9K vCExdukQ4aB7MYvIZaKzHKP8NAOgKdVk x/BrrGl8IV0T+YvUDo9e8gpdcbhLFXoN w+qZ9xVNIvhSsjzzL1fxrkjJIEdTPzrS HXdUjK8v56KppQJ0pr+XSq2CicRbcn5b ur5HQz4yKfIr2q7aH9CMGuwbMLNDWnjO G+iHdA/ekKLYQ5afWOxaqw==
+SECTION ADDITIONAL
+a.ns.nic.cz. 172800 IN A 194.0.12.1
+a.ns.nic.cz. 172800 IN AAAA 2001:678:f::1
+b.ns.nic.cz. 172800 IN A 194.0.13.1
+b.ns.nic.cz. 172800 IN AAAA 2001:678:10::1
+c.ns.nic.cz. 172800 IN A 194.0.14.1
+c.ns.nic.cz. 172800 IN AAAA 2001:678:11::1
+d.ns.nic.cz. 172800 IN A 193.29.206.1
+d.ns.nic.cz. 172800 IN AAAA 2001:678:1::1
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH subdomain
+ADJUST copy_id copy_query
+REPLY QR RD NOERROR
+SECTION QUESTION
+net. IN NS
+SECTION AUTHORITY
+net. 172800 IN NS a.gtld-servers.net.
+net. 172800 IN NS b.gtld-servers.net.
+net. 172800 IN NS c.gtld-servers.net.
+net. 172800 IN NS d.gtld-servers.net.
+net. 172800 IN NS e.gtld-servers.net.
+net. 172800 IN NS f.gtld-servers.net.
+net. 172800 IN NS g.gtld-servers.net.
+net. 172800 IN NS h.gtld-servers.net.
+net. 172800 IN NS i.gtld-servers.net.
+net. 172800 IN NS j.gtld-servers.net.
+net. 172800 IN NS k.gtld-servers.net.
+net. 172800 IN NS l.gtld-servers.net.
+net. 172800 IN NS m.gtld-servers.net.
+net. 86400 IN DS 35886 8 2 7862b27f5f516ebe19680444d4ce5e762981931842c465f00236401d8bd973ee
+net. 86400 IN RRSIG DS 8 1 86400 20190708050000 20190625040000 25266 . EK4wI33V5RQyA5SAxBfX1oTiDeGfOzXr u0OA6KaXALQOMELkugzUD3NipvVpzO7B 0ZYSsnNn+Kk1h0qJBE/ZWpHHZyvZCg1o zo+kq1Z7gGJvlV4Y9XfuwIGPZKL0tlkm LBVSBd36yQy/x4gFyBKvRgIDd1IyKrjT xJYENyNwvtj3MkrT+Njsg1NWXP5ORRx1 r0zVlq2snbJsp8ze+sLYrSqVXbihg4mq JoMe7NB4M9EYEMfBOUcWo8Wrj73jiYRx 0uJ3HfvOHBqBgVFyhMcr4FeCiN9F9V6C xTQBQnL3lQF1TnOhN//Z7h7TvLulxHRu DeKEsZDcoC4el8u1Fx7t/w==
+SECTION ADDITIONAL
+a.gtld-servers.net. 172800 IN A 192.5.6.30
+a.gtld-servers.net. 172800 IN AAAA 2001:503:a83e::2:30
+b.gtld-servers.net. 172800 IN A 192.33.14.30
+b.gtld-servers.net. 172800 IN AAAA 2001:503:231d::2:30
+c.gtld-servers.net. 172800 IN A 192.26.92.30
+c.gtld-servers.net. 172800 IN AAAA 2001:503:83eb::30
+d.gtld-servers.net. 172800 IN A 192.31.80.30
+d.gtld-servers.net. 172800 IN AAAA 2001:500:856e::30
+e.gtld-servers.net. 172800 IN A 192.12.94.30
+e.gtld-servers.net. 172800 IN AAAA 2001:502:1ca1::30
+f.gtld-servers.net. 172800 IN A 192.35.51.30
+f.gtld-servers.net. 172800 IN AAAA 2001:503:d414::30
+g.gtld-servers.net. 172800 IN A 192.42.93.30
+g.gtld-servers.net. 172800 IN AAAA 2001:503:eea3::30
+h.gtld-servers.net. 172800 IN A 192.54.112.30
+h.gtld-servers.net. 172800 IN AAAA 2001:502:8cc::30
+i.gtld-servers.net. 172800 IN A 192.43.172.30
+i.gtld-servers.net. 172800 IN AAAA 2001:503:39c1::30
+j.gtld-servers.net. 172800 IN A 192.48.79.30
+j.gtld-servers.net. 172800 IN AAAA 2001:502:7094::30
+k.gtld-servers.net. 172800 IN A 192.52.178.30
+k.gtld-servers.net. 172800 IN AAAA 2001:503:d2d::30
+l.gtld-servers.net. 172800 IN A 192.41.162.30
+l.gtld-servers.net. 172800 IN AAAA 2001:500:d937::30
+m.gtld-servers.net. 172800 IN A 192.55.83.30
+m.gtld-servers.net. 172800 IN AAAA 2001:501:b1f9::30
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH subdomain
+ADJUST copy_id copy_query
+REPLY QR RD NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION AUTHORITY
+com. 172800 IN NS a.gtld-servers.net.
+com. 172800 IN NS b.gtld-servers.net.
+com. 172800 IN NS c.gtld-servers.net.
+com. 172800 IN NS d.gtld-servers.net.
+com. 172800 IN NS e.gtld-servers.net.
+com. 172800 IN NS f.gtld-servers.net.
+com. 172800 IN NS g.gtld-servers.net.
+com. 172800 IN NS h.gtld-servers.net.
+com. 172800 IN NS i.gtld-servers.net.
+com. 172800 IN NS j.gtld-servers.net.
+com. 172800 IN NS k.gtld-servers.net.
+com. 172800 IN NS l.gtld-servers.net.
+com. 172800 IN NS m.gtld-servers.net.
+com. 86400 IN DS 30909 8 2 e2d3c916f6deeac73294e8268fb5885044a833fc5459588f4a9184cfc41a5766
+com. 86400 IN RRSIG DS 8 1 86400 20190708050000 20190625040000 25266 . h8CYVMqouUO2IAPlG4Iqf06ykpl07wny KuM2dRGhrfx5hQbF0CpzGRwT2B6i2drI td9i7BSA4GVKLlTYr9n3Xd+BcAHKwywv 44A2WmTAo3xWMv4THwowwu29B4bAKe0V WQKDfmZ92m1yn8T3MCNZWtuGGaLcY6+g fKgyuHu5fEakVn2GFMdAMayBBFTF0bp4 hVFuNSJBe/1EnFZMcxU9aNuCyC8xup25 7K3x1rcM0hthHr8o0Vevpima1YXsWDGb RDIkDyStPDIQ1c0C9LHMaaGR+MA+fxoL 2x4w2lwOptCK//zpfyPvj11oIyouwgdh Fe3PCf9hS03Y1FsiY+mtWw==
+SECTION ADDITIONAL
+a.gtld-servers.net. 172800 IN A 192.5.6.30
+a.gtld-servers.net. 172800 IN AAAA 2001:503:a83e::2:30
+b.gtld-servers.net. 172800 IN A 192.33.14.30
+b.gtld-servers.net. 172800 IN AAAA 2001:503:231d::2:30
+c.gtld-servers.net. 172800 IN A 192.26.92.30
+c.gtld-servers.net. 172800 IN AAAA 2001:503:83eb::30
+d.gtld-servers.net. 172800 IN A 192.31.80.30
+d.gtld-servers.net. 172800 IN AAAA 2001:500:856e::30
+e.gtld-servers.net. 172800 IN A 192.12.94.30
+e.gtld-servers.net. 172800 IN AAAA 2001:502:1ca1::30
+f.gtld-servers.net. 172800 IN A 192.35.51.30
+f.gtld-servers.net. 172800 IN AAAA 2001:503:d414::30
+g.gtld-servers.net. 172800 IN A 192.42.93.30
+g.gtld-servers.net. 172800 IN AAAA 2001:503:eea3::30
+h.gtld-servers.net. 172800 IN A 192.54.112.30
+h.gtld-servers.net. 172800 IN AAAA 2001:502:8cc::30
+i.gtld-servers.net. 172800 IN A 192.43.172.30
+i.gtld-servers.net. 172800 IN AAAA 2001:503:39c1::30
+j.gtld-servers.net. 172800 IN A 192.48.79.30
+j.gtld-servers.net. 172800 IN AAAA 2001:502:7094::30
+k.gtld-servers.net. 172800 IN A 192.52.178.30
+k.gtld-servers.net. 172800 IN AAAA 2001:503:d2d::30
+l.gtld-servers.net. 172800 IN A 192.41.162.30
+l.gtld-servers.net. 172800 IN AAAA 2001:500:d937::30
+m.gtld-servers.net. 172800 IN A 192.55.83.30
+m.gtld-servers.net. 172800 IN AAAA 2001:501:b1f9::30
+ENTRY_END
+
+
+
+
+RANGE_END
+
+
+
+; Group's zones:
+; cz.
+; nic.cz.
+; Server names:
+; a.ns.nic.cz.
+; b.ns.nic.cz.
+; c.ns.nic.cz.
+; d.ns.nic.cz.
+RANGE_BEGIN 0 1000
+ ADDRESS 194.0.14.1
+ ADDRESS 194.0.13.1
+ ADDRESS 193.29.206.1
+ ADDRESS 2001:678:1::1
+ ADDRESS 2001:678:11::1
+ ADDRESS 2001:678:10::1
+ ADDRESS 2001:678:f::1
+ ADDRESS 194.0.12.1
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+ns.nic.cz. IN NS
+SECTION AUTHORITY
+jnp2uc34hha9de64l3rjf6ulp4pra74n.nic.cz. 7200 IN NSEC3 1 0 10 879ec89c91d874a8 jsdlj2k5hipr7eb12ne8bads7lshvo1k
+jnp2uc34hha9de64l3rjf6ulp4pra74n.nic.cz. 7200 IN RRSIG NSEC3 13 3 7200 20190707164247 20190624124001 10486 nic.cz. lrFJPPGpHyoC5l4uM8l94ye/HG1kTVw7 dR98um06iG+2XK82Dib+wnzqoNNIqbaA FeaAkjfqgCHA8kDySAP+5g==
+nic.cz. 1800 IN RRSIG SOA 13 2 1800 20190708100906 20190624124001 10486 nic.cz. 1mDJpihqjobv42BXF8H1dT0/vLtPTpb/ k7flS9wr8tEPe57o6GrkimcSWZlS/lm5 OyhvjIpvU9Da8n2ezGiGHw==
+nic.cz. 1800 IN SOA a.ns.nic.cz. hostmaster.nic.cz. 1561383601 10800 3600 1209600 7200
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+b.ns.nic.cz. IN A
+SECTION ANSWER
+b.ns.nic.cz. 1800 IN A 194.0.13.1
+b.ns.nic.cz. 1800 IN RRSIG A 13 4 1800 20190708030702 20190624124001 10486 nic.cz. bV+9iqB6KDNUCZrcoo9fXj3X1BHhCpgh MGSXx8q4JWJ9mm9Hz6h63UfXTWPthvJy +J18PantZQVPScwMoXVzuw==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+nic.cz. IN DNSKEY
+SECTION ANSWER
+nic.cz. 1800 IN DNSKEY 256 3 13 SmMYG4VjCgj4rAxB4sqgvIzcGtESoX1H m7Dsoekap6HJwj8WOEiFciSg537caOPl 4+7Dyp/b5JwkBemxQQRL9Q==
+nic.cz. 1800 IN DNSKEY 257 3 13 LM4zvjUgZi2XZKsYooDE0HFYGfWp242f KB+O8sLsuox8S6MJTowY8lBDjZD7JKbm aNot3+1H8zU9TrDzWmmHwQ==
+nic.cz. 1800 IN RRSIG DNSKEY 13 2 1800 20190707163411 20190624124001 61281 nic.cz. ggHlmuzLOTZOCYcbZ8TrNoTXOAg7xJ9N B+QLdmZYyny53ODMkRfDv28SSMkwtuc1 rZXfC+/c7oArzsBbbncTRA==
+nic.cz. 1800 IN RRSIG DNSKEY 13 2 1800 20190708092836 20190624124001 10486 nic.cz. lFYLLcm5ICS0BSdB0+dA8m7XxdRbB49+ 5N1w8AHOaPNDTWp9GlXA935IUk18C2to 1ghYmP2RZaNOTchSVRgWzA==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+b.ns.nic.cz. IN A
+SECTION ANSWER
+b.ns.nic.cz. 1800 IN A 194.0.13.1
+b.ns.nic.cz. 1800 IN RRSIG A 13 4 1800 20190708030702 20190624124001 10486 nic.cz. bV+9iqB6KDNUCZrcoo9fXj3X1BHhCpgh MGSXx8q4JWJ9mm9Hz6h63UfXTWPthvJy +J18PantZQVPScwMoXVzuw==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+b.ns.nic.cz. IN AAAA
+SECTION ANSWER
+b.ns.nic.cz. 1800 IN AAAA 2001:678:10::1
+b.ns.nic.cz. 1800 IN RRSIG AAAA 13 4 1800 20190707133636 20190624124001 10486 nic.cz. OuH2sPy1tH6CENbjioxaaYzCB8yxB1sP FyQXAcY4VpNmLnqthfGKTn5dONZuG4UD I9ihrEaPsV3RsDse0GpMqg==
+SECTION AUTHORITY
+nic.cz. 1800 IN NS a.ns.nic.cz.
+nic.cz. 1800 IN NS b.ns.nic.cz.
+nic.cz. 1800 IN NS d.ns.nic.cz.
+nic.cz. 1800 IN RRSIG NS 13 2 1800 20190707221726 20190624124001 10486 nic.cz. JhCrQB0nVFkti/j3weaalBPxqDG7PyiC KLV7hj61SLdRGcue9/fI9IN7lIanFWhL A1b7/L5DYejIY7WpHVU3Jg==
+SECTION ADDITIONAL
+a.ns.nic.cz. 1800 IN A 194.0.12.1
+a.ns.nic.cz. 1800 IN AAAA 2001:678:f::1
+a.ns.nic.cz. 1800 IN RRSIG A 13 4 1800 20190708050633 20190624124001 10486 nic.cz. 18u1P3Wvg0xoz3fTRtqVNlTHiZPOuGW7 C8nsMIBTCTT9mPYN0z+CcBDfRwVLNnfJ eNTfHXA9zERxbAT3WCHEXg==
+a.ns.nic.cz. 1800 IN RRSIG AAAA 13 4 1800 20190707232622 20190624124001 10486 nic.cz. qY1Rm171qERHJwykmMYDKXlIGUnHdMhX gYlvOZPGONNuapbsqzTQos9Vd7v4IQfp k6j8sVTjSId1/q/75D4vNQ==
+b.ns.nic.cz. 1800 IN A 194.0.13.1
+b.ns.nic.cz. 1800 IN RRSIG A 13 4 1800 20190708030702 20190624124001 10486 nic.cz. bV+9iqB6KDNUCZrcoo9fXj3X1BHhCpgh MGSXx8q4JWJ9mm9Hz6h63UfXTWPthvJy +J18PantZQVPScwMoXVzuw==
+d.ns.nic.cz. 1800 IN A 193.29.206.1
+d.ns.nic.cz. 1800 IN AAAA 2001:678:1::1
+d.ns.nic.cz. 1800 IN RRSIG A 13 4 1800 20190708114823 20190624124001 10486 nic.cz. p2nhRTWBo56GXRdL19wT+y/XyNb6wjrz Oy3AndSR2/L9BDZrX/mkGYh20x5KpdUV +r+DPy9XFXEmvGrwAD5meA==
+d.ns.nic.cz. 1800 IN RRSIG AAAA 13 4 1800 20190708121635 20190624124001 10486 nic.cz. QeqTWoaOuL+L+QdiGOIne/WCi+D0V6EH 0h96aDuMs2eySLXSWPC54ICz28gwudmh wX4oEdQf1nYVneO7iEDFew==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+c.ns.nic.cz. IN A
+SECTION ANSWER
+c.ns.nic.cz. 1800 IN A 194.0.14.1
+c.ns.nic.cz. 1800 IN RRSIG A 13 4 1800 20190708123232 20190624124001 10486 nic.cz. ln7Q9H73Ba6dEbIrhA6QrK3OMMEIu4QA h4fJ3xeUIW4US+XU21wylj09Zaf6ALE+ V3E9jTWdPfo1UTGnuW1VUw==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+d.ns.nic.cz. IN AAAA
+SECTION ANSWER
+d.ns.nic.cz. 1800 IN AAAA 2001:678:1::1
+d.ns.nic.cz. 1800 IN RRSIG AAAA 13 4 1800 20190708121635 20190624124001 10486 nic.cz. QeqTWoaOuL+L+QdiGOIne/WCi+D0V6EH 0h96aDuMs2eySLXSWPC54ICz28gwudmh wX4oEdQf1nYVneO7iEDFew==
+SECTION AUTHORITY
+nic.cz. 1800 IN NS a.ns.nic.cz.
+nic.cz. 1800 IN NS b.ns.nic.cz.
+nic.cz. 1800 IN NS d.ns.nic.cz.
+nic.cz. 1800 IN RRSIG NS 13 2 1800 20190707221726 20190624124001 10486 nic.cz. JhCrQB0nVFkti/j3weaalBPxqDG7PyiC KLV7hj61SLdRGcue9/fI9IN7lIanFWhL A1b7/L5DYejIY7WpHVU3Jg==
+SECTION ADDITIONAL
+a.ns.nic.cz. 1800 IN A 194.0.12.1
+a.ns.nic.cz. 1800 IN AAAA 2001:678:f::1
+a.ns.nic.cz. 1800 IN RRSIG A 13 4 1800 20190708050633 20190624124001 10486 nic.cz. 18u1P3Wvg0xoz3fTRtqVNlTHiZPOuGW7 C8nsMIBTCTT9mPYN0z+CcBDfRwVLNnfJ eNTfHXA9zERxbAT3WCHEXg==
+a.ns.nic.cz. 1800 IN RRSIG AAAA 13 4 1800 20190707232622 20190624124001 10486 nic.cz. qY1Rm171qERHJwykmMYDKXlIGUnHdMhX gYlvOZPGONNuapbsqzTQos9Vd7v4IQfp k6j8sVTjSId1/q/75D4vNQ==
+b.ns.nic.cz. 1800 IN A 194.0.13.1
+b.ns.nic.cz. 1800 IN AAAA 2001:678:10::1
+b.ns.nic.cz. 1800 IN RRSIG A 13 4 1800 20190708030702 20190624124001 10486 nic.cz. bV+9iqB6KDNUCZrcoo9fXj3X1BHhCpgh MGSXx8q4JWJ9mm9Hz6h63UfXTWPthvJy +J18PantZQVPScwMoXVzuw==
+b.ns.nic.cz. 1800 IN RRSIG AAAA 13 4 1800 20190707133636 20190624124001 10486 nic.cz. OuH2sPy1tH6CENbjioxaaYzCB8yxB1sP FyQXAcY4VpNmLnqthfGKTn5dONZuG4UD I9ihrEaPsV3RsDse0GpMqg==
+d.ns.nic.cz. 1800 IN A 193.29.206.1
+d.ns.nic.cz. 1800 IN RRSIG A 13 4 1800 20190708114823 20190624124001 10486 nic.cz. p2nhRTWBo56GXRdL19wT+y/XyNb6wjrz Oy3AndSR2/L9BDZrX/mkGYh20x5KpdUV +r+DPy9XFXEmvGrwAD5meA==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+b.ns.nic.cz. IN AAAA
+SECTION ANSWER
+b.ns.nic.cz. 1800 IN AAAA 2001:678:10::1
+b.ns.nic.cz. 1800 IN RRSIG AAAA 13 4 1800 20190707133636 20190624124001 10486 nic.cz. OuH2sPy1tH6CENbjioxaaYzCB8yxB1sP FyQXAcY4VpNmLnqthfGKTn5dONZuG4UD I9ihrEaPsV3RsDse0GpMqg==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+a.ns.nic.cz. IN NS
+SECTION AUTHORITY
+51npp2qit2otcucer39ql8d4q4h9mr5d.nic.cz. 7200 IN NSEC3 1 0 10 879ec89c91d874a8 52jm0s7pifluesur7b9p840f8fkcpcsi A AAAA RRSIG
+51npp2qit2otcucer39ql8d4q4h9mr5d.nic.cz. 7200 IN RRSIG NSEC3 13 3 7200 20190708102945 20190624124001 10486 nic.cz. ScbUA0IlzL0o1h34t007ViOD53YFHe+V zn2ge8gqiNeT29FW/sCwiyVsrUpMZ7nW O9gmXfdNjjtmyTA7iWbVTA==
+nic.cz. 1800 IN RRSIG SOA 13 2 1800 20190708100906 20190624124001 10486 nic.cz. 1mDJpihqjobv42BXF8H1dT0/vLtPTpb/ k7flS9wr8tEPe57o6GrkimcSWZlS/lm5 OyhvjIpvU9Da8n2ezGiGHw==
+nic.cz. 1800 IN SOA a.ns.nic.cz. hostmaster.nic.cz. 1561383601 10800 3600 1209600 7200
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+c.ns.nic.cz. IN A
+SECTION ANSWER
+c.ns.nic.cz. 1800 IN A 194.0.14.1
+c.ns.nic.cz. 1800 IN RRSIG A 13 4 1800 20190708123232 20190624124001 10486 nic.cz. ln7Q9H73Ba6dEbIrhA6QrK3OMMEIu4QA h4fJ3xeUIW4US+XU21wylj09Zaf6ALE+ V3E9jTWdPfo1UTGnuW1VUw==
+SECTION AUTHORITY
+nic.cz. 1800 IN NS a.ns.nic.cz.
+nic.cz. 1800 IN NS b.ns.nic.cz.
+nic.cz. 1800 IN NS d.ns.nic.cz.
+nic.cz. 1800 IN RRSIG NS 13 2 1800 20190707221726 20190624124001 10486 nic.cz. JhCrQB0nVFkti/j3weaalBPxqDG7PyiC KLV7hj61SLdRGcue9/fI9IN7lIanFWhL A1b7/L5DYejIY7WpHVU3Jg==
+SECTION ADDITIONAL
+a.ns.nic.cz. 1800 IN A 194.0.12.1
+a.ns.nic.cz. 1800 IN AAAA 2001:678:f::1
+a.ns.nic.cz. 1800 IN RRSIG A 13 4 1800 20190708050633 20190624124001 10486 nic.cz. 18u1P3Wvg0xoz3fTRtqVNlTHiZPOuGW7 C8nsMIBTCTT9mPYN0z+CcBDfRwVLNnfJ eNTfHXA9zERxbAT3WCHEXg==
+a.ns.nic.cz. 1800 IN RRSIG AAAA 13 4 1800 20190707232622 20190624124001 10486 nic.cz. qY1Rm171qERHJwykmMYDKXlIGUnHdMhX gYlvOZPGONNuapbsqzTQos9Vd7v4IQfp k6j8sVTjSId1/q/75D4vNQ==
+b.ns.nic.cz. 1800 IN A 194.0.13.1
+b.ns.nic.cz. 1800 IN AAAA 2001:678:10::1
+b.ns.nic.cz. 1800 IN RRSIG A 13 4 1800 20190708030702 20190624124001 10486 nic.cz. bV+9iqB6KDNUCZrcoo9fXj3X1BHhCpgh MGSXx8q4JWJ9mm9Hz6h63UfXTWPthvJy +J18PantZQVPScwMoXVzuw==
+b.ns.nic.cz. 1800 IN RRSIG AAAA 13 4 1800 20190707133636 20190624124001 10486 nic.cz. OuH2sPy1tH6CENbjioxaaYzCB8yxB1sP FyQXAcY4VpNmLnqthfGKTn5dONZuG4UD I9ihrEaPsV3RsDse0GpMqg==
+d.ns.nic.cz. 1800 IN A 193.29.206.1
+d.ns.nic.cz. 1800 IN AAAA 2001:678:1::1
+d.ns.nic.cz. 1800 IN RRSIG A 13 4 1800 20190708114823 20190624124001 10486 nic.cz. p2nhRTWBo56GXRdL19wT+y/XyNb6wjrz Oy3AndSR2/L9BDZrX/mkGYh20x5KpdUV +r+DPy9XFXEmvGrwAD5meA==
+d.ns.nic.cz. 1800 IN RRSIG AAAA 13 4 1800 20190708121635 20190624124001 10486 nic.cz. QeqTWoaOuL+L+QdiGOIne/WCi+D0V6EH 0h96aDuMs2eySLXSWPC54ICz28gwudmh wX4oEdQf1nYVneO7iEDFew==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+nic.cz. IN DS
+SECTION ANSWER
+nic.cz. 3600 IN DS 61281 13 2 4104d40c8fe2030bf7a09a199fcf37b36f7ec8ddd16f5a84f2e61c248d3afd0f
+nic.cz. 3600 IN RRSIG DS 13 2 3600 20190705064642 20190622210528 6318 cz. h4tSy9MopxkbCg2mPu0s/CoE+DtoKUTL 5iw1cpQZOF1MJMZhTYo3yZjYiIkIrih8 xigA0UNFXtZEAxzsqI6omA==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+c.ns.nic.cz. IN AAAA
+SECTION ANSWER
+c.ns.nic.cz. 1800 IN AAAA 2001:678:11::1
+c.ns.nic.cz. 1800 IN RRSIG AAAA 13 4 1800 20190707153808 20190624124001 10486 nic.cz. 2n+SYd+Eh6pFujzSb5u/ZFbJkfHGB3aB wo5vSKAp+s8RgEtwMawcs54psA6LWKc5 swrxP1C1xVyMLQ6L7eifGA==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+a.ns.nic.cz. IN AAAA
+SECTION ANSWER
+a.ns.nic.cz. 1800 IN AAAA 2001:678:f::1
+a.ns.nic.cz. 1800 IN RRSIG AAAA 13 4 1800 20190707232622 20190624124001 10486 nic.cz. qY1Rm171qERHJwykmMYDKXlIGUnHdMhX gYlvOZPGONNuapbsqzTQos9Vd7v4IQfp k6j8sVTjSId1/q/75D4vNQ==
+SECTION AUTHORITY
+nic.cz. 1800 IN NS a.ns.nic.cz.
+nic.cz. 1800 IN NS b.ns.nic.cz.
+nic.cz. 1800 IN NS d.ns.nic.cz.
+nic.cz. 1800 IN RRSIG NS 13 2 1800 20190707221726 20190624124001 10486 nic.cz. JhCrQB0nVFkti/j3weaalBPxqDG7PyiC KLV7hj61SLdRGcue9/fI9IN7lIanFWhL A1b7/L5DYejIY7WpHVU3Jg==
+SECTION ADDITIONAL
+a.ns.nic.cz. 1800 IN A 194.0.12.1
+a.ns.nic.cz. 1800 IN RRSIG A 13 4 1800 20190708050633 20190624124001 10486 nic.cz. 18u1P3Wvg0xoz3fTRtqVNlTHiZPOuGW7 C8nsMIBTCTT9mPYN0z+CcBDfRwVLNnfJ eNTfHXA9zERxbAT3WCHEXg==
+b.ns.nic.cz. 1800 IN A 194.0.13.1
+b.ns.nic.cz. 1800 IN AAAA 2001:678:10::1
+b.ns.nic.cz. 1800 IN RRSIG A 13 4 1800 20190708030702 20190624124001 10486 nic.cz. bV+9iqB6KDNUCZrcoo9fXj3X1BHhCpgh MGSXx8q4JWJ9mm9Hz6h63UfXTWPthvJy +J18PantZQVPScwMoXVzuw==
+b.ns.nic.cz. 1800 IN RRSIG AAAA 13 4 1800 20190707133636 20190624124001 10486 nic.cz. OuH2sPy1tH6CENbjioxaaYzCB8yxB1sP FyQXAcY4VpNmLnqthfGKTn5dONZuG4UD I9ihrEaPsV3RsDse0GpMqg==
+d.ns.nic.cz. 1800 IN A 193.29.206.1
+d.ns.nic.cz. 1800 IN AAAA 2001:678:1::1
+d.ns.nic.cz. 1800 IN RRSIG A 13 4 1800 20190708114823 20190624124001 10486 nic.cz. p2nhRTWBo56GXRdL19wT+y/XyNb6wjrz Oy3AndSR2/L9BDZrX/mkGYh20x5KpdUV +r+DPy9XFXEmvGrwAD5meA==
+d.ns.nic.cz. 1800 IN RRSIG AAAA 13 4 1800 20190708121635 20190624124001 10486 nic.cz. QeqTWoaOuL+L+QdiGOIne/WCi+D0V6EH 0h96aDuMs2eySLXSWPC54ICz28gwudmh wX4oEdQf1nYVneO7iEDFew==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+c.ns.nic.cz. IN NS
+SECTION AUTHORITY
+CNTVMLLA2O27TCBC4MEP7IV9P54L7FLE.nic.cz. 7200 IN NSEC3 1 0 10 879ec89c91d874a8 co07u5iiiqhl96t3hlmgkchj3203eqqj A AAAA RRSIG
+CNTVMLLA2O27TCBC4MEP7IV9P54L7FLE.nic.cz. 7200 IN RRSIG NSEC3 13 3 7200 20190707155010 20190624124001 10486 nic.cz. osfB/CgwWbwa/BX/fYo+gzrImuam0bhT bD9xmAH6w+acJ8GrCNHNcCgFdimdacEA rSx2ztVVWCiALLlqzFP1WQ==
+nic.cz. 1800 IN RRSIG SOA 13 2 1800 20190708100906 20190624124001 10486 nic.cz. 1mDJpihqjobv42BXF8H1dT0/vLtPTpb/ k7flS9wr8tEPe57o6GrkimcSWZlS/lm5 OyhvjIpvU9Da8n2ezGiGHw==
+nic.cz. 1800 IN SOA a.ns.nic.cz. hostmaster.nic.cz. 1561383601 10800 3600 1209600 7200
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+d.ns.nic.cz. IN A
+SECTION ANSWER
+d.ns.nic.cz. 1800 IN A 193.29.206.1
+d.ns.nic.cz. 1800 IN RRSIG A 13 4 1800 20190708114823 20190624124001 10486 nic.cz. p2nhRTWBo56GXRdL19wT+y/XyNb6wjrz Oy3AndSR2/L9BDZrX/mkGYh20x5KpdUV +r+DPy9XFXEmvGrwAD5meA==
+SECTION AUTHORITY
+nic.cz. 1800 IN NS a.ns.nic.cz.
+nic.cz. 1800 IN NS b.ns.nic.cz.
+nic.cz. 1800 IN NS d.ns.nic.cz.
+nic.cz. 1800 IN RRSIG NS 13 2 1800 20190707221726 20190624124001 10486 nic.cz. JhCrQB0nVFkti/j3weaalBPxqDG7PyiC KLV7hj61SLdRGcue9/fI9IN7lIanFWhL A1b7/L5DYejIY7WpHVU3Jg==
+SECTION ADDITIONAL
+a.ns.nic.cz. 1800 IN A 194.0.12.1
+a.ns.nic.cz. 1800 IN AAAA 2001:678:f::1
+a.ns.nic.cz. 1800 IN RRSIG A 13 4 1800 20190708050633 20190624124001 10486 nic.cz. 18u1P3Wvg0xoz3fTRtqVNlTHiZPOuGW7 C8nsMIBTCTT9mPYN0z+CcBDfRwVLNnfJ eNTfHXA9zERxbAT3WCHEXg==
+a.ns.nic.cz. 1800 IN RRSIG AAAA 13 4 1800 20190707232622 20190624124001 10486 nic.cz. qY1Rm171qERHJwykmMYDKXlIGUnHdMhX gYlvOZPGONNuapbsqzTQos9Vd7v4IQfp k6j8sVTjSId1/q/75D4vNQ==
+b.ns.nic.cz. 1800 IN A 194.0.13.1
+b.ns.nic.cz. 1800 IN AAAA 2001:678:10::1
+b.ns.nic.cz. 1800 IN RRSIG A 13 4 1800 20190708030702 20190624124001 10486 nic.cz. bV+9iqB6KDNUCZrcoo9fXj3X1BHhCpgh MGSXx8q4JWJ9mm9Hz6h63UfXTWPthvJy +J18PantZQVPScwMoXVzuw==
+b.ns.nic.cz. 1800 IN RRSIG AAAA 13 4 1800 20190707133636 20190624124001 10486 nic.cz. OuH2sPy1tH6CENbjioxaaYzCB8yxB1sP FyQXAcY4VpNmLnqthfGKTn5dONZuG4UD I9ihrEaPsV3RsDse0GpMqg==
+d.ns.nic.cz. 1800 IN AAAA 2001:678:1::1
+d.ns.nic.cz. 1800 IN RRSIG AAAA 13 4 1800 20190708121635 20190624124001 10486 nic.cz. QeqTWoaOuL+L+QdiGOIne/WCi+D0V6EH 0h96aDuMs2eySLXSWPC54ICz28gwudmh wX4oEdQf1nYVneO7iEDFew==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+nic.cz. IN DNSKEY
+SECTION ANSWER
+nic.cz. 1800 IN DNSKEY 256 3 13 SmMYG4VjCgj4rAxB4sqgvIzcGtESoX1H m7Dsoekap6HJwj8WOEiFciSg537caOPl 4+7Dyp/b5JwkBemxQQRL9Q==
+nic.cz. 1800 IN DNSKEY 257 3 13 LM4zvjUgZi2XZKsYooDE0HFYGfWp242f KB+O8sLsuox8S6MJTowY8lBDjZD7JKbm aNot3+1H8zU9TrDzWmmHwQ==
+nic.cz. 1800 IN RRSIG DNSKEY 13 2 1800 20190707163411 20190624124001 61281 nic.cz. ggHlmuzLOTZOCYcbZ8TrNoTXOAg7xJ9N B+QLdmZYyny53ODMkRfDv28SSMkwtuc1 rZXfC+/c7oArzsBbbncTRA==
+nic.cz. 1800 IN RRSIG DNSKEY 13 2 1800 20190708092836 20190624124001 10486 nic.cz. lFYLLcm5ICS0BSdB0+dA8m7XxdRbB49+ 5N1w8AHOaPNDTWp9GlXA935IUk18C2to 1ghYmP2RZaNOTchSVRgWzA==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+c.ns.nic.cz. IN NS
+SECTION AUTHORITY
+cntvmlla2o27tcbc4mep7iv9p54l7fle.nic.cz. 7200 IN NSEC3 1 0 10 879ec89c91d874a8 co07u5iiiqhl96t3hlmgkchj3203eqqj A AAAA RRSIG
+cntvmlla2o27tcbc4mep7iv9p54l7fle.nic.cz. 7200 IN RRSIG NSEC3 13 3 7200 20190707155010 20190624124001 10486 nic.cz. osfB/CgwWbwa/BX/fYo+gzrImuam0bhT bD9xmAH6w+acJ8GrCNHNcCgFdimdacEA rSx2ztVVWCiALLlqzFP1WQ==
+nic.cz. 1800 IN RRSIG SOA 13 2 1800 20190708100906 20190624124001 10486 nic.cz. 1mDJpihqjobv42BXF8H1dT0/vLtPTpb/ k7flS9wr8tEPe57o6GrkimcSWZlS/lm5 OyhvjIpvU9Da8n2ezGiGHw==
+nic.cz. 1800 IN SOA a.ns.nic.cz. hostmaster.nic.cz. 1561383601 10800 3600 1209600 7200
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+b.ns.nic.cz. IN NS
+SECTION AUTHORITY
+cu82t3qracdj063olk907dv20ine9dea.nic.cz. 7200 IN NSEC3 1 0 10 879ec89c91d874a8 d2749lueihj9moq02lt0k9i8tnbgest1 A AAAA RRSIG
+cu82t3qracdj063olk907dv20ine9dea.nic.cz. 7200 IN RRSIG NSEC3 13 3 7200 20190708122905 20190624124001 10486 nic.cz. fg5ypFDXqZlnzSbndkPm2VjZieL0t5NT zKu0cfcWHu4TlWB/OxxuaD4C2oGx5nki Pchj+FQNobNZJfCXKOa4ug==
+nic.cz. 1800 IN RRSIG SOA 13 2 1800 20190708100906 20190624124001 10486 nic.cz. 1mDJpihqjobv42BXF8H1dT0/vLtPTpb/ k7flS9wr8tEPe57o6GrkimcSWZlS/lm5 OyhvjIpvU9Da8n2ezGiGHw==
+nic.cz. 1800 IN SOA a.ns.nic.cz. hostmaster.nic.cz. 1561383601 10800 3600 1209600 7200
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+csas.cz. IN DS
+SECTION ANSWER
+csas.cz. 3600 IN DS 8196 7 2 c5c7974e1dc3bf036f8744a4d919e03ef01d8d6167db6201940ca87059558ee3
+csas.cz. 3600 IN RRSIG DS 13 2 3600 20190706080140 20190622110535 6318 cz. 5V0ZvjpT8zWMsVwPpyhsMc9DRFVMQtP2 D2o7S/dLbZ7YL4Mqd8P9n+o+4NQgaqQw 7VPBHnN3VzVDYvWjmr+rfw==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+ns.nic.cz. IN NS
+SECTION AUTHORITY
+JNP2UC34HHA9DE64L3RJF6ULP4PRA74N.nic.cz. 7200 IN NSEC3 1 0 10 879ec89c91d874a8 jsdlj2k5hipr7eb12ne8bads7lshvo1k
+JNP2UC34HHA9DE64L3RJF6ULP4PRA74N.nic.cz. 7200 IN RRSIG NSEC3 13 3 7200 20190707164247 20190624124001 10486 nic.cz. lrFJPPGpHyoC5l4uM8l94ye/HG1kTVw7 dR98um06iG+2XK82Dib+wnzqoNNIqbaA FeaAkjfqgCHA8kDySAP+5g==
+nic.cz. 1800 IN RRSIG SOA 13 2 1800 20190708100906 20190624124001 10486 nic.cz. 1mDJpihqjobv42BXF8H1dT0/vLtPTpb/ k7flS9wr8tEPe57o6GrkimcSWZlS/lm5 OyhvjIpvU9Da8n2ezGiGHw==
+nic.cz. 1800 IN SOA a.ns.nic.cz. hostmaster.nic.cz. 1561383601 10800 3600 1209600 7200
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+d.ns.nic.cz. IN NS
+SECTION AUTHORITY
+nic.cz. 1800 IN RRSIG SOA 13 2 1800 20190708100906 20190624124001 10486 nic.cz. 1mDJpihqjobv42BXF8H1dT0/vLtPTpb/ k7flS9wr8tEPe57o6GrkimcSWZlS/lm5 OyhvjIpvU9Da8n2ezGiGHw==
+nic.cz. 1800 IN SOA a.ns.nic.cz. hostmaster.nic.cz. 1561383601 10800 3600 1209600 7200
+on20qsre8qs9a2asfdatp5cs6g2i5ssq.nic.cz. 7200 IN NSEC3 1 0 10 879ec89c91d874a8 onv9qnjm1krm9qdk0n6o6o23doo5jfug A AAAA RRSIG
+on20qsre8qs9a2asfdatp5cs6g2i5ssq.nic.cz. 7200 IN RRSIG NSEC3 13 3 7200 20190708041440 20190624124001 10486 nic.cz. WkMEKZUDwPTv5Y3KG/C9LTVTynACPb16 1OuoxTij1reZR4LzHVoGQKDf0Dbj2Rau 9LrBW5PI5PSDQ6BmUKRj6A==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+a.ns.nic.cz. IN AAAA
+SECTION ANSWER
+a.ns.nic.cz. 1800 IN AAAA 2001:678:f::1
+a.ns.nic.cz. 1800 IN RRSIG AAAA 13 4 1800 20190707232622 20190624124001 10486 nic.cz. qY1Rm171qERHJwykmMYDKXlIGUnHdMhX gYlvOZPGONNuapbsqzTQos9Vd7v4IQfp k6j8sVTjSId1/q/75D4vNQ==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+a.ns.nic.cz. IN A
+SECTION ANSWER
+a.ns.nic.cz. 1800 IN A 194.0.12.1
+a.ns.nic.cz. 1800 IN RRSIG A 13 4 1800 20190708050633 20190624124001 10486 nic.cz. 18u1P3Wvg0xoz3fTRtqVNlTHiZPOuGW7 C8nsMIBTCTT9mPYN0z+CcBDfRwVLNnfJ eNTfHXA9zERxbAT3WCHEXg==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+cz. IN DS
+SECTION AUTHORITY
+cz. 3600 IN RRSIG SOA 13 1 3600 20190707192652 20190625123528 6318 cz. BYXtAj/BIXIb5xlT6TBQYaFhbloeuo0H RqJTdPu9gVVyuBKbvV6YmQbS4BBMM4qA Cp2Vw7yBK9+dONHp9JAmuA==
+cz. 3600 IN SOA a.ns.nic.cz. hostmaster.nic.cz. 1561469728 900 300 604800 900
+fu65o5n6kmh8a04mps1e4a73s37jr72u.cz. 900 IN NSEC3 1 0 10 357dda080afe0ef8 fu677p5qqp6ihbeeloacm3sr4ieklu7m NS SOA RRSIG DNSKEY NSEC3PARAM
+fu65o5n6kmh8a04mps1e4a73s37jr72u.cz. 900 IN RRSIG NSEC3 13 2 900 20190706134746 20190622170523 6318 cz. EsElag8LQ5TcunX40efTh35IN3GoQnPq XAZZ0cSPHT6GOohzp8iD1LSLLbwZUiNE yB4hCp1yqEi0pINRoHglNA==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+cz. IN DNSKEY
+SECTION ANSWER
+cz. 18000 IN DNSKEY 256 3 13 7t+ZoZGIrV27M/PEAH8OKSjEXVAJhV6O o5ESS+Vry5ZhfoWogIKAXzvda/qY/WTA L09BEk+ko16oGRRktvzWEw==
+cz. 18000 IN DNSKEY 257 3 13 nqzH7xP1QU5UOVy/VvxFSlrB/XgX9JDJ zj51PzIj35TXjZTyalTlAT/f7PAfaSD5 mEG1N8Vk9NmI2nxgQqhzDQ==
+cz. 18000 IN RRSIG DNSKEY 13 1 18000 20190705000000 20190621000000 20237 cz. kJ1zRR76FpPS4SLyFuLbrQBvVnq6GY+x 5sOV2ayq6rt4D1sjpxROufFfBfi/6wAv qo3VZ0iUJSB03djeX8gk5A==
+cz. 18000 IN RRSIG DNSKEY 13 1 18000 20190709092856 20190625123528 6318 cz. Lpz5UZi8lVH1TCdz6DyjWvoUciOVqA4Z d+3TVxNF2GsLzM15nwc34FnaQF3dxhJZ mdf6dET7iOUmy2SN3majVg==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+c.ns.nic.cz. IN AAAA
+SECTION ANSWER
+c.ns.nic.cz. 1800 IN AAAA 2001:678:11::1
+c.ns.nic.cz. 1800 IN RRSIG AAAA 13 4 1800 20190707153808 20190624124001 10486 nic.cz. 2n+SYd+Eh6pFujzSb5u/ZFbJkfHGB3aB wo5vSKAp+s8RgEtwMawcs54psA6LWKc5 swrxP1C1xVyMLQ6L7eifGA==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+d.ns.nic.cz. IN A
+SECTION ANSWER
+d.ns.nic.cz. 1800 IN A 193.29.206.1
+d.ns.nic.cz. 1800 IN RRSIG A 13 4 1800 20190708114823 20190624124001 10486 nic.cz. p2nhRTWBo56GXRdL19wT+y/XyNb6wjrz Oy3AndSR2/L9BDZrX/mkGYh20x5KpdUV +r+DPy9XFXEmvGrwAD5meA==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+d.ns.nic.cz. IN AAAA
+SECTION ANSWER
+d.ns.nic.cz. 1800 IN AAAA 2001:678:1::1
+d.ns.nic.cz. 1800 IN RRSIG AAAA 13 4 1800 20190708121635 20190624124001 10486 nic.cz. QeqTWoaOuL+L+QdiGOIne/WCi+D0V6EH 0h96aDuMs2eySLXSWPC54ICz28gwudmh wX4oEdQf1nYVneO7iEDFew==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH subdomain
+ADJUST copy_id copy_query
+REPLY QR RD NOERROR
+SECTION QUESTION
+csas.cz. IN NS
+SECTION AUTHORITY
+csas.cz. 3600 IN DS 8196 7 2 c5c7974e1dc3bf036f8744a4d919e03ef01d8d6167db6201940ca87059558ee3
+csas.cz. 3600 IN NS ddnsa.csas.cz.
+csas.cz. 3600 IN NS ddnsb.csas.cz.
+csas.cz. 3600 IN RRSIG DS 13 2 3600 20190706080140 20190622110535 6318 cz. 5V0ZvjpT8zWMsVwPpyhsMc9DRFVMQtP2 D2o7S/dLbZ7YL4Mqd8P9n+o+4NQgaqQw 7VPBHnN3VzVDYvWjmr+rfw==
+SECTION ADDITIONAL
+ddnsa.csas.cz. 3600 IN A 194.50.240.64
+ddnsb.csas.cz. 3600 IN A 194.50.240.192
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH subdomain
+ADJUST copy_id copy_query
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+nic.cz. IN NS
+SECTION ANSWER
+nic.cz. 1800 IN NS a.ns.nic.cz.
+nic.cz. 1800 IN NS b.ns.nic.cz.
+nic.cz. 1800 IN NS d.ns.nic.cz.
+nic.cz. 1800 IN RRSIG NS 13 2 1800 20190707221726 20190624124001 10486 nic.cz. JhCrQB0nVFkti/j3weaalBPxqDG7PyiC KLV7hj61SLdRGcue9/fI9IN7lIanFWhL A1b7/L5DYejIY7WpHVU3Jg==
+SECTION ADDITIONAL
+a.ns.nic.cz. 1800 IN A 194.0.12.1
+a.ns.nic.cz. 1800 IN AAAA 2001:678:f::1
+a.ns.nic.cz. 1800 IN RRSIG A 13 4 1800 20190708050633 20190624124001 10486 nic.cz. 18u1P3Wvg0xoz3fTRtqVNlTHiZPOuGW7 C8nsMIBTCTT9mPYN0z+CcBDfRwVLNnfJ eNTfHXA9zERxbAT3WCHEXg==
+a.ns.nic.cz. 1800 IN RRSIG AAAA 13 4 1800 20190707232622 20190624124001 10486 nic.cz. qY1Rm171qERHJwykmMYDKXlIGUnHdMhX gYlvOZPGONNuapbsqzTQos9Vd7v4IQfp k6j8sVTjSId1/q/75D4vNQ==
+b.ns.nic.cz. 1800 IN A 194.0.13.1
+b.ns.nic.cz. 1800 IN AAAA 2001:678:10::1
+b.ns.nic.cz. 1800 IN RRSIG A 13 4 1800 20190708030702 20190624124001 10486 nic.cz. bV+9iqB6KDNUCZrcoo9fXj3X1BHhCpgh MGSXx8q4JWJ9mm9Hz6h63UfXTWPthvJy +J18PantZQVPScwMoXVzuw==
+b.ns.nic.cz. 1800 IN RRSIG AAAA 13 4 1800 20190707133636 20190624124001 10486 nic.cz. OuH2sPy1tH6CENbjioxaaYzCB8yxB1sP FyQXAcY4VpNmLnqthfGKTn5dONZuG4UD I9ihrEaPsV3RsDse0GpMqg==
+d.ns.nic.cz. 1800 IN A 193.29.206.1
+d.ns.nic.cz. 1800 IN AAAA 2001:678:1::1
+d.ns.nic.cz. 1800 IN RRSIG A 13 4 1800 20190708114823 20190624124001 10486 nic.cz. p2nhRTWBo56GXRdL19wT+y/XyNb6wjrz Oy3AndSR2/L9BDZrX/mkGYh20x5KpdUV +r+DPy9XFXEmvGrwAD5meA==
+d.ns.nic.cz. 1800 IN RRSIG AAAA 13 4 1800 20190708121635 20190624124001 10486 nic.cz. QeqTWoaOuL+L+QdiGOIne/WCi+D0V6EH 0h96aDuMs2eySLXSWPC54ICz28gwudmh wX4oEdQf1nYVneO7iEDFew==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH subdomain
+ADJUST copy_id copy_query
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+cz. IN NS
+SECTION ANSWER
+cz. 3600 IN NS a.ns.nic.cz.
+cz. 3600 IN NS b.ns.nic.cz.
+cz. 3600 IN NS c.ns.nic.cz.
+cz. 3600 IN NS d.ns.nic.cz.
+cz. 3600 IN RRSIG NS 13 1 3600 20190705184721 20190622030526 6318 cz. SzhZGIFskUTnlxipSleB+IghUpyhS1eV PubDzCU/CC0LmDBoAVwfiY8zKWdPSu0X 5544N2KzZ5JrPoasQkOLzg==
+SECTION ADDITIONAL
+a.ns.nic.cz. 3600 IN A 194.0.12.1
+a.ns.nic.cz. 3600 IN AAAA 2001:678:f::1
+b.ns.nic.cz. 3600 IN A 194.0.13.1
+b.ns.nic.cz. 3600 IN AAAA 2001:678:10::1
+d.ns.nic.cz. 3600 IN A 193.29.206.1
+d.ns.nic.cz. 3600 IN AAAA 2001:678:1::1
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH subdomain
+ADJUST copy_id copy_query
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+cz. IN NS
+SECTION ANSWER
+cz. 3600 IN NS a.ns.nic.cz.
+cz. 3600 IN NS b.ns.nic.cz.
+cz. 3600 IN NS c.ns.nic.cz.
+cz. 3600 IN NS d.ns.nic.cz.
+cz. 3600 IN RRSIG NS 13 1 3600 20190705184721 20190622030526 6318 cz. SzhZGIFskUTnlxipSleB+IghUpyhS1eV PubDzCU/CC0LmDBoAVwfiY8zKWdPSu0X 5544N2KzZ5JrPoasQkOLzg==
+ENTRY_END
+
+
+
+
+RANGE_END
+
+
+
+; Group's zones:
+; csas.cz.
+; Server names:
+; ddnsa.csas.cz.
+; ddnsb.csas.cz.
+; ddnsc.csas.cz.
+; ddnsd.csas.cz.
+RANGE_BEGIN 0 1000
+ ADDRESS 194.50.240.64
+ ADDRESS 194.50.240.192
+ ADDRESS 194.50.240.194
+ ADDRESS 194.50.240.66
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+ddnsd.csas.cz. IN NS
+SECTION AUTHORITY
+csas.cz. 120 IN RRSIG SOA 7 2 120 20190630054550 20190623054550 26663 csas.cz. c/sxvp5WLJOsDGgnhxPOk9oBwXRtsUXa enyWg5rd8yBcquHqfFKQu1v8wEPjJjAH B6joG1tJXq99nxtCN4jlDipPKLIzWxba aYIxE8Pab199qiHrR5vxO4KgPxRXbg5d gzIVrrhB+h23DZDacQ+l+kQWSAcycjPh xFvNjAZrH4obU/F+jHt4ix5XqEVuDrPQ YTGBGEUpl7YbcyaROzVP3dtCQZamkfaB CQYoNAJlNw6YFG1qulPm3pn3jJHhu88f dFgCisWfp7TjMYn7Id7aYJtliagE47xu ASnhOtaeXAVxDGUIkOI5u8uUCC/jAiHr MgARE5rcqh2AIZeSv0BiMQ==
+csas.cz. 120 IN SOA ddnsa.csas.cz. domainservices.csas.cz. 2019061320 28800 1800 2592000 120
+gfr9qt699hmcloa9radenpk7pqeikiu8.csas.cz. 120 IN NSEC3 1 0 1 31245099125aedf7 gfr9qt699hmcloa9radenpk7pqeikiu9 TXT
+gfr9qt699hmcloa9radenpk7pqeikiu8.csas.cz. 120 IN RRSIG NSEC3 7 3 120 20190702130338 20190625130338 26663 csas.cz. OWtiEsmO7VnUV2MQp3gZJmOAQw4n81DH 9c5FFJW6MBE3afaIqGTvWYCgRipEEvZF qPBVxGpptVsMbuELagewwZYtR+EEh2A/ qMf/wVC//t2c67YFIxMILi9ijleYS5y8 m5Mu+logobk2Resxs0kC47kwNP9KSh7s gm3SFjK1LXRXg19UmiabMIINoOoAE1M0 XePGhiaqhFwros32p++2JrCdaYrPXLWy VuENN0chZ/hE55ic4M7KpxZ12+oPzigk tIeh9sqTaKpGJBZk4vlJQLq2zfL/gnKZ CRRN8bJQ/ZsSZG//rL0nqZcgyxQqXI9w As8TBPtQ9IQWq2K5MxjKHg==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+csas.cz. IN AAAA
+SECTION AUTHORITY
+8b6896cv5m6qpdd29hb4s12lagep7utq.csas.cz. 120 IN NSEC3 1 0 1 31245099125aedf7 8b6896cv5m6qpdd29hb4s12lagep7utr NS SOA RRSIG DNSKEY NSEC3PARAM
+8b6896cv5m6qpdd29hb4s12lagep7utq.csas.cz. 120 IN RRSIG NSEC3 7 3 120 20190702130338 20190625130338 26663 csas.cz. SNkUAfA3do4t3pyNw1I0zfdiGnWufjIW S4DnHV7Sz+LNOfbe36ipmpUevus+12DG qgG+fQNzxAbCByk7e5fqieyXLVyGfRla 1H9UwCj42/TWATKqDQUFADVEaZ4nHrnN E2yZWkaNNW3jBX7LTIvgwHHVXuM5HQwd Q3/be9B6oz92QLs7ds2zhtjB1NYCUeFD OwYOxSekxZV/ePEfytrXbw1NPcji9GsO v6+HLgYLLy2qIQKMS5xavb4+4/eDMsq4 vJ+uvrmc66JHL7rFyrwd/x1NNsHXwqac czV+GifY3m8svOydXETd9tTC8sTsiU9x ZFTAOcTlxlo211UwuHnwkA==
+csas.cz. 120 IN RRSIG SOA 7 2 120 20190630054550 20190623054550 26663 csas.cz. c/sxvp5WLJOsDGgnhxPOk9oBwXRtsUXa enyWg5rd8yBcquHqfFKQu1v8wEPjJjAH B6joG1tJXq99nxtCN4jlDipPKLIzWxba aYIxE8Pab199qiHrR5vxO4KgPxRXbg5d gzIVrrhB+h23DZDacQ+l+kQWSAcycjPh xFvNjAZrH4obU/F+jHt4ix5XqEVuDrPQ YTGBGEUpl7YbcyaROzVP3dtCQZamkfaB CQYoNAJlNw6YFG1qulPm3pn3jJHhu88f dFgCisWfp7TjMYn7Id7aYJtliagE47xu ASnhOtaeXAVxDGUIkOI5u8uUCC/jAiHr MgARE5rcqh2AIZeSv0BiMQ==
+csas.cz. 120 IN SOA ddnsa.csas.cz. domainservices.csas.cz. 2019061320 28800 1800 2592000 120
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+ddnsc.csas.cz. IN NS
+SECTION AUTHORITY
+c1c03am0n36kncp4iqb4buoqo1ectql4.csas.cz. 120 IN NSEC3 1 0 1 31245099125aedf7 c1c03am0n36kncp4iqb4buoqo1ectql5 TXT
+c1c03am0n36kncp4iqb4buoqo1ectql4.csas.cz. 120 IN RRSIG NSEC3 7 3 120 20190702130338 20190625130338 26663 csas.cz. FKjWbcw5aP2HzHFy2t+M462dxM1ph0FW 02Tohh/aJQOp1iKQOi6u1V2tI3H9CMXW xeIAktZ+xiUDRYLX50fNuJZMaSsn7r5A LYjVAKGzwMPncIf6IlEDYkj1I1rdp6z8 LvWsWNO1wfIPq1Dw2geN60bcz3D7r/sY WfjU/7jO9f0nekZZXI2qFsMSYd9Dkaq7 mlpP0NrWnUbCjL+BfuLFNebh8g3D8f5w Tq3R9czwW5YTVXUquBIrjiZ0Ko9INgQ/ 4pvJqJ1bsTpmzdODfAssEtpu+es4wLwt ZTe8Ll9VeDB20RqEnAyHZwQRXXVF2t+F vdJU7Desbpu6rElA7IXwRw==
+csas.cz. 120 IN RRSIG SOA 7 2 120 20190630054550 20190623054550 26663 csas.cz. c/sxvp5WLJOsDGgnhxPOk9oBwXRtsUXa enyWg5rd8yBcquHqfFKQu1v8wEPjJjAH B6joG1tJXq99nxtCN4jlDipPKLIzWxba aYIxE8Pab199qiHrR5vxO4KgPxRXbg5d gzIVrrhB+h23DZDacQ+l+kQWSAcycjPh xFvNjAZrH4obU/F+jHt4ix5XqEVuDrPQ YTGBGEUpl7YbcyaROzVP3dtCQZamkfaB CQYoNAJlNw6YFG1qulPm3pn3jJHhu88f dFgCisWfp7TjMYn7Id7aYJtliagE47xu ASnhOtaeXAVxDGUIkOI5u8uUCC/jAiHr MgARE5rcqh2AIZeSv0BiMQ==
+csas.cz. 120 IN SOA ddnsa.csas.cz. domainservices.csas.cz. 2019061320 28800 1800 2592000 120
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+ddnsd.csas.cz. IN AAAA
+SECTION AUTHORITY
+csas.cz. 120 IN RRSIG SOA 7 2 120 20190630054550 20190623054550 26663 csas.cz. c/sxvp5WLJOsDGgnhxPOk9oBwXRtsUXa enyWg5rd8yBcquHqfFKQu1v8wEPjJjAH B6joG1tJXq99nxtCN4jlDipPKLIzWxba aYIxE8Pab199qiHrR5vxO4KgPxRXbg5d gzIVrrhB+h23DZDacQ+l+kQWSAcycjPh xFvNjAZrH4obU/F+jHt4ix5XqEVuDrPQ YTGBGEUpl7YbcyaROzVP3dtCQZamkfaB CQYoNAJlNw6YFG1qulPm3pn3jJHhu88f dFgCisWfp7TjMYn7Id7aYJtliagE47xu ASnhOtaeXAVxDGUIkOI5u8uUCC/jAiHr MgARE5rcqh2AIZeSv0BiMQ==
+csas.cz. 120 IN SOA ddnsa.csas.cz. domainservices.csas.cz. 2019061320 28800 1800 2592000 120
+gfr9qt699hmcloa9radenpk7pqeikiu8.csas.cz. 120 IN NSEC3 1 0 1 31245099125aedf7 gfr9qt699hmcloa9radenpk7pqeikiu9 TXT
+gfr9qt699hmcloa9radenpk7pqeikiu8.csas.cz. 120 IN RRSIG NSEC3 7 3 120 20190702130338 20190625130338 26663 csas.cz. OWtiEsmO7VnUV2MQp3gZJmOAQw4n81DH 9c5FFJW6MBE3afaIqGTvWYCgRipEEvZF qPBVxGpptVsMbuELagewwZYtR+EEh2A/ qMf/wVC//t2c67YFIxMILi9ijleYS5y8 m5Mu+logobk2Resxs0kC47kwNP9KSh7s gm3SFjK1LXRXg19UmiabMIINoOoAE1M0 XePGhiaqhFwros32p++2JrCdaYrPXLWy VuENN0chZ/hE55ic4M7KpxZ12+oPzigk tIeh9sqTaKpGJBZk4vlJQLq2zfL/gnKZ CRRN8bJQ/ZsSZG//rL0nqZcgyxQqXI9w As8TBPtQ9IQWq2K5MxjKHg==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+csas.cz. IN DNSKEY
+SECTION ANSWER
+csas.cz. 7200 IN DNSKEY 256 3 7 AwEAAaNjFdWEB091Zv/uWznXJXbFaDYD cG4GvutyTPMM1nWDLu1ZTR/ujYhwEoWM 1DYyq8QkIFJS7PVnu312O8pkiWcvV9Fl hVv9AYJ8OCbixXjSrwXL1yfBhhzJxxjA RXi49Xn/NTPNiTeK6lVed2QMLbwucpTy 4GEduAcXWDi7/OnDD3UmaFtxXQ2LKc7d +of4okGQWYdka9b+KeyJtXwhDuuzGf/v m8E3Tdjt5ldgOpofh/BO5lifl6mAXgnW E6z+p0fb1ksyq1hGu9ssizxr8A10amUa repR+zcOFoDJNv5IxGWi5rriAvBW4NAl U1wy1P6BSDgMZuc8JBj3VikbI6U=
+csas.cz. 7200 IN DNSKEY 256 3 7 AwEAAbk21ZXai9JsSCmuW8InRPINGI+o 2vxokpQ0imk6iDPHqF3QhJSs5QcFG+Hq yZ3mWLkb5cT/u0zKZ+Onri0s2zSm4ASk /A86BQSEaPXG90GiD+waH7qF5vorF5Gx 1BvzdtLz9vtbsQ0G1GfdbvlouvlU05t2 GlSuAXqsj6RI5WaWHejKJ1fcOtR7hQTt tH5+oir5t1eJ1riQsOyPzC2y9V+Q28Tf cD5F6oxghhn9+YieAIqMMp5r7txouxp0 DFG+oVMbTmt07B9MIClXOMMTOYDTOj0c fpdx5/WHoigkgNdcUh5ulsva9OK9EWZX WkicdtzfYfe7fi3LqFxWc0DMiY0=
+csas.cz. 7200 IN DNSKEY 257 3 7 AwEAAcMXtJYlvIshn+O541gOW48wNlgh szwYVFeSUd+qB+BfejKueV+4vo9IY1A8 cKxfLcOwT0F/XyEZXhpigZPXf2OQrLWi R6aK0cDErhLUp30AWdEwB/T8QnfePzM1 LX30rgAP5JhGLckrfoVbSZi28S6vvuxA GbFmgEpGkKVgMg9pKAcjrRUd/bmyNaQR yECq40cwgHFaDm9SPeAavgMxn1l88dAv qIwKDvpN2Er+K/Gl5GRApDFxSt9x+7rt NIrpFV4Apl/j81Rcxyj7v7HXEu3P8BNQ 6s0cVg8RmtY+R0J59sTsZyJGI2krq5Ap k2K1S2RA7QZxHQCMKx+caRyLwk6KqjmF EYMILxpYWER+iPddpeo5w0AYJNxDYYeE 2cUYuBXNi7SM4UZGDbMZ+j2xlzGNyAsE mWXlrR4qCgYKO7JxK0Yw3otZzNyrcJhS fT1E0tNvDv3zH/j8riqIyW36EK1yjVav dcI3a+GGSh5oylb/7SuLFNKEW0g2fo5q W+rITI77k+MRR798XNXqSKTT19LNiqWc xhlA4aGzHzKZieEWR4d6FHhOKzNoo+Ce j7b00rg5v2hwSAEEHcC3lwuStya1J5IX g6sfdNxWqJ0yydI/PGOn0ZgakX2oEE4b zGJchx/aHKogs2L+bZJfi7N1OmU7AU0D mY6kTxEYC1lBFb1h
+csas.cz. 7200 IN DNSKEY 257 3 7 AwEAAcoflVKUA6KreqNnC7qYr0B+UiYS Fqoja50or7jBmrrmxok5mR9Ea+L3D0PK ynffMxFMMQm1JekaJYH66eUGgWWqTHRQ nAKVQchHCv37Bf0nFEetKo/qf4KJbdDD Ar3sXjfkClaQQlqMPDeCQQbfxSWpdvQo ip7pX35KsatTObINwqnMsl3tsvsugybw 6+xujlYWOpmJcjHri7cdZA5NSx3k3Sdb 16/GEpcwFe0Z8Oi4TgbcVEaAziyOm0zC to1SW1L4VovdZkadAa3RMQ7QpyR/wIOr TjqS/weDkOyKgGNnbVL5l8dUAD8rk/Do cXhQuXxNqHB9PVNxBCsfnVVj6fbk09eo 6stXAdJbwoa1NoPBlHsCV5+EN65XXsGO eLZneUt213RDGkphcKTWaF3dvIRXtWbt Rz2bCrxs12ADhhXisyH2EGntyI3LX3zY ISbKaZnRzbU1nKIdcNzFJ1p8aoUPgzX7 YhpXVkhfcaB8aAG38Ys6EXvcACFdoqma V7b0VnvU1tPsI9bAesU4d5K4EjCNrana yfvFgakYdmoi3GrpWeHim7CDK9s5yrh3 Dou59pU7a/1xugGvuCkDllo8Z70hWzJq tVNFrSv7jwLA7+77pRKBF7Vl88Y0i/6h zUkllh7mBCMilyU50AX9bGJsd6PFJn6P iZ8x+XoCel0oZqz3
+csas.cz. 7200 IN RRSIG DNSKEY 7 2 7200 20190630181024 20190623181024 26663 csas.cz. cPZVp/k5lPxsjnRhCc8zXkKGf2VQjg93 Rwyrwjm6wPg/B7n3iTzLA+TUROwMgcAB rlEru/TNaySpWR36rDQdg/w8JZsB17Wf HIO0t1GxjQdEjPYD9T4x0b5u/Ra/ienZ XgHwuto1tQCghttwv7ioECzf1+52asf+ oxe8il1W4HdMH8/wiEyOyPm8n9ou6siX tcVjqbRTy0xLcPoFm/ATvUBMGBrbMedy hGWn88cLoIQA4IPm4zAIAWunPV8sFNKY l12HDNzQlfrO6ukJqtFTjQREeTWFC0qP KXWSPJeX9fTfrT6zHfyV/YQd3tGRP0J8 KTzXmUMYi2vrVbeagR00Vg==
+csas.cz. 7200 IN RRSIG DNSKEY 7 2 7200 20190630181024 20190623181024 8196 csas.cz. t8HaIHf6FCi91a3ppWC4bAiN+WvZPdbf ESinQ+iYFSWk7NlCw45eT/0SpRWNQ5jQ fvWkkvBDDuHDv9FVdmqkvAuMCf0/GgnM 2bdOQt/q2Hp3E91eFpHW1fx7YtQabj+r 9Ww30ewUplDE2v6JlHnJzm53mYsbUUum l+rAtq+QJnb8sjjn2JceDtQLBkZaLsLe vUuFL/Hz/WvvMgjYUyuxbK4xxJByiymo hZIDxA8TWcaoFFyiP+Rv4leqaxVLXun4 VsWsCE2YYtOqrYRaq2UJvbSIFAPdix5Q EL44TXYlJ00NbngD480tJ8TwyNTm4CLp 8Z85xtmpYfKO3VFAycL0zV/7fOJRkoPQ LrBxClIbeQJlQapm1FMQQK/FFfHKSVRq 659VLfDbxfbTU/yWOmlUldaB8r7y6BhD iq4u/IZqIU5eTIbeoMd3HBerKREo0vOy UPCoW4OJ3Q9/WQ18cPsVW+BKjkKRrV4T VQKc52jwkPufUq8fNuVeuZ+8cvgIaUfD 8Xie+N2Trlh5tfaAAg9etgu0EmoEAP8V 1mTzT54losWySfSh5JNx5fDtUaxZI/q3 2+mbgnO4QlGB9eAhoA6JRHByWf+Gf9rR hEktuZqg2Uw4ifOebJsQE4atFr8Tr910 xihtrgtx/y6HwpB9nIr7V91ewn6lKMEz d4ordmuS+1Q=
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+ddnsa.csas.cz. IN A
+SECTION ANSWER
+ddnsa.csas.cz. 7200 IN A 194.50.240.64
+ddnsa.csas.cz. 7200 IN RRSIG A 7 3 7200 20190630180929 20190623180929 26663 csas.cz. QJCNptf+bgoFFzW6vh6lMnevBqaHq1Qk p7UB7hJZfqewhVJsf4/aZlUJg9Ulq990 xe1K+Vw2H7zFKRmS+BhLL0NVS6F/uo3g VWU7UkiLCUdICMNmBlUfv6dTJmovHydF DeCtS8eunKTYKnvSklmr/aLKnFFEaeoi SUF8hkHM2fADZekxqTEMS2ATjlY0rbTb biDd4c1tZdSDeUV7z4B4pHVdgVFBOi6+ kL4MtMM2AY4o9h31jOUGFnfA0cJPmxNN Cx+qgBAl0zKL9+uFrBqB6nYgmd0a1pRa UEQCcVVKkSjDX3gWHtO/nqflFmyDNV4Y OlVLcHVCDNqRtwIRwucUOg==
+SECTION AUTHORITY
+csas.cz. 7200 IN NS ddnsa.csas.cz.
+csas.cz. 7200 IN NS ddnsb.csas.cz.
+csas.cz. 7200 IN NS ddnsc.csas.cz.
+csas.cz. 7200 IN NS ddnsd.csas.cz.
+csas.cz. 7200 IN RRSIG NS 7 2 7200 20190630180929 20190623180929 26663 csas.cz. PLqM9UHNFbb8GmE+SlzSCjAEKYsklbgt CnWf9G26HkwtacOyJkIHe+T0m94rJZTd 6Mnn32Sw/at6idSvVNGQfE6DIKr2rtK6 lJNe0HPMxYWC9Tr5zpzW1/SjLVooMw6n m8K+18RBI33PBI69UgXyuePnWefdTYOJ g4SK3rR2wUlFxnELEFGfYkytZ6tLi1Cd bTgch93lDnXNBRZ2t/mu5jPyv4NTdKCo WgIMJJcuFdPr/YRVRaemkVEup7qVYImk pa4n+7MMERTL/dw+GxtnZ2YKqyxcepYo rPib3FSTaOFZjEPqNPDNfXXYW+bPmWFP 9ESqUtgmvZ1rMDZbr8lbgQ==
+SECTION ADDITIONAL
+ddnsb.csas.cz. 7200 IN A 194.50.240.192
+ddnsb.csas.cz. 7200 IN RRSIG A 7 3 7200 20190630180929 20190623180929 26663 csas.cz. CXelkXBmt3nR60+gTwRcTXTVH1OBpfAE McYGfcEmxk8t+wFwLrCfM+6mJUWbV3a8 cIggoBHU8gJxarnIX4K5bXNel2QRzlTa +qTTPPTxH5LwHayDwoo5edk6c2HkCrY3 qChg5SyjuNxxsF4ybqvqIU0d/kM6wqG7 pKPmplD9BNJmzVIVQ8aTBMhdrvIcqK/f 81TGgNxMqJxfpTYKmnA8vVqpJ3C1kbfn no+ux39NY7Wj58NwI+UIcDlmBj414MSz Z4wEfYSgtVnEA8fO+ufZ3jaxjk6NClz+ XMP1gYj/y08bj0h5ACIKJqci2uqPujoi TNBYzQWn6LVPqNIM8O7eSg==
+ddnsc.csas.cz. 7200 IN A 194.50.240.66
+ddnsc.csas.cz. 7200 IN RRSIG A 7 3 7200 20190630180929 20190623180929 26663 csas.cz. AHQJp3i/UzKmjm/hhmEM1mhV7gPAq2rX 0z4ZOF+ZDyL57nXSHnzGqz4sdd3Q0E1H pmGENdgiOR1Grabo6X3QIp7mZbuAR14T 5TQYHSDoTZ+aTOkqvxCxfUCpEYLVHlbP whE+ntazt0gmkko3eGUBMefMv+JVmuwy tirS7pxlNL1VRnKtbfDsWJ2zmJuur/WK wGzHCMybt4fITB0Og/I9pnwMwykdxhpF bo/MQAa35oTefzvWsD3uFKOhrAc7CP2N MyqDFzv0QDN00s0yFXHHxNg3QFXLAg16 4khZaKT076k+F5N/ufsoIeU/AbByx82T PxpLg8NCh9nNvzgqoCEccw==
+ddnsd.csas.cz. 7200 IN A 194.50.240.194
+ddnsd.csas.cz. 7200 IN RRSIG A 7 3 7200 20190630180929 20190623180929 26663 csas.cz. nsWIVa/SusXOatYzHtX8IPkETOBo90yd Zz8ce1PQhUawbQamihm1di90qJSQJ/i4 QCdL5ulxKJdMv8jLBjIBGe1H08d43luD OmLwkiBNoROZ1apKKabSQAmJTuwIxZCD sqYti2+rEbmOaRC1n96fIH2HWL9pYAnn C0GrvoWEDeVkSHI70Ei9CUCpUNOrPzhS BZc3PrB0DhojkzlXj359e4OhO1gH2QDp 2Uj05suhlIEzQf3lsvvIRUOrMPG2i6Fh j3yThN21+kuVyasrsN5Pv6Dp52U1k60l Y7AuwQwMUXrsdrK3/15DyxSS+pHenpsq cBI3Rb8P4Z6uVxZv9sQ4rQ==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+ddnsb.csas.cz. IN AAAA
+SECTION AUTHORITY
+csas.cz. 120 IN RRSIG SOA 7 2 120 20190630054550 20190623054550 26663 csas.cz. c/sxvp5WLJOsDGgnhxPOk9oBwXRtsUXa enyWg5rd8yBcquHqfFKQu1v8wEPjJjAH B6joG1tJXq99nxtCN4jlDipPKLIzWxba aYIxE8Pab199qiHrR5vxO4KgPxRXbg5d gzIVrrhB+h23DZDacQ+l+kQWSAcycjPh xFvNjAZrH4obU/F+jHt4ix5XqEVuDrPQ YTGBGEUpl7YbcyaROzVP3dtCQZamkfaB CQYoNAJlNw6YFG1qulPm3pn3jJHhu88f dFgCisWfp7TjMYn7Id7aYJtliagE47xu ASnhOtaeXAVxDGUIkOI5u8uUCC/jAiHr MgARE5rcqh2AIZeSv0BiMQ==
+csas.cz. 120 IN SOA ddnsa.csas.cz. domainservices.csas.cz. 2019061320 28800 1800 2592000 120
+kl8ko9vcu5os0r0marmli019btprhvdr.csas.cz. 120 IN NSEC3 1 0 1 31245099125aedf7 kl8ko9vcu5os0r0marmli019btprhvds TXT
+kl8ko9vcu5os0r0marmli019btprhvdr.csas.cz. 120 IN RRSIG NSEC3 7 3 120 20190702130338 20190625130338 26663 csas.cz. ebbykapJt+h+uDJlz84Yu4rpx7spx8aY bbR/BCMIVJ6HjziYnwwbBQuyyd6t281+ pdn+2Dxo5tUJ0Kw4oatMPVhID8Psasd3 2Za8bZrouTk8RcQislJCj1jPi2HMIQUI dvJ1aCMC6vn1vI++ZMvcxfptxgmWyL46 i4P3xZAwtrB6hCVrctQ0dbbp1nswh1go YFIf3Hzxu2NHfXZYMdXXb1cLuOZ5L17g UZlqqgcrudLORc2cHj0NcjVT2PscMeoy a/jFNJwCHmkfI3nCAeXmemz/txQUY01u SxBNjkd/y2DVSIgvDPY/Zz0dW4gYdcMG 4T4D43oBTG6w06CgBg1QQw==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+csas.cz. IN A
+SECTION ANSWER
+csas.cz. 120 IN A 194.50.240.198
+csas.cz. 120 IN A 194.50.240.70
+csas.cz. 120 IN RRSIG A 7 2 120 20190701063211 20190624063211 26663 csas.cz. UXxlRUL6nBVmcrcP4kkryr7lfVxnQHs4 z2WahLZEIaQdf56Iw/+bxddThPD9l3a0 rBCwURI8QMspgPks+7UprWN5TESIifiP W9qJLDuvtD+sVoLgunBAwgi1sE8KfRas asbiISaRpot+3IqJYzYi9X9O5JMdYCuS H9nfayDebVlbC4ChAo5Rcdpkzfb7DwFp gDFKdn+Lmp7IdImSlvJQQT2Mqxpew+gd vMBr5ZN82G8zlsrrHz4n2/kF/SqCYTCG q1WLZUsMvLsP+ha3TAR1t/iG9ayw5Mll 8N2c+AejB2lMwTIlBX+zLlJYT0MoNCyF cMNoCxwjENtDMbq9QZKowA==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+ddnsc.csas.cz. IN A
+SECTION ANSWER
+ddnsc.csas.cz. 7200 IN A 194.50.240.66
+ddnsc.csas.cz. 7200 IN RRSIG A 7 3 7200 20190630180929 20190623180929 26663 csas.cz. AHQJp3i/UzKmjm/hhmEM1mhV7gPAq2rX 0z4ZOF+ZDyL57nXSHnzGqz4sdd3Q0E1H pmGENdgiOR1Grabo6X3QIp7mZbuAR14T 5TQYHSDoTZ+aTOkqvxCxfUCpEYLVHlbP whE+ntazt0gmkko3eGUBMefMv+JVmuwy tirS7pxlNL1VRnKtbfDsWJ2zmJuur/WK wGzHCMybt4fITB0Og/I9pnwMwykdxhpF bo/MQAa35oTefzvWsD3uFKOhrAc7CP2N MyqDFzv0QDN00s0yFXHHxNg3QFXLAg16 4khZaKT076k+F5N/ufsoIeU/AbByx82T PxpLg8NCh9nNvzgqoCEccw==
+SECTION AUTHORITY
+csas.cz. 7200 IN NS ddnsa.csas.cz.
+csas.cz. 7200 IN NS ddnsb.csas.cz.
+csas.cz. 7200 IN NS ddnsc.csas.cz.
+csas.cz. 7200 IN NS ddnsd.csas.cz.
+csas.cz. 7200 IN RRSIG NS 7 2 7200 20190630180929 20190623180929 26663 csas.cz. PLqM9UHNFbb8GmE+SlzSCjAEKYsklbgt CnWf9G26HkwtacOyJkIHe+T0m94rJZTd 6Mnn32Sw/at6idSvVNGQfE6DIKr2rtK6 lJNe0HPMxYWC9Tr5zpzW1/SjLVooMw6n m8K+18RBI33PBI69UgXyuePnWefdTYOJ g4SK3rR2wUlFxnELEFGfYkytZ6tLi1Cd bTgch93lDnXNBRZ2t/mu5jPyv4NTdKCo WgIMJJcuFdPr/YRVRaemkVEup7qVYImk pa4n+7MMERTL/dw+GxtnZ2YKqyxcepYo rPib3FSTaOFZjEPqNPDNfXXYW+bPmWFP 9ESqUtgmvZ1rMDZbr8lbgQ==
+SECTION ADDITIONAL
+ddnsa.csas.cz. 7200 IN A 194.50.240.64
+ddnsa.csas.cz. 7200 IN RRSIG A 7 3 7200 20190630180929 20190623180929 26663 csas.cz. QJCNptf+bgoFFzW6vh6lMnevBqaHq1Qk p7UB7hJZfqewhVJsf4/aZlUJg9Ulq990 xe1K+Vw2H7zFKRmS+BhLL0NVS6F/uo3g VWU7UkiLCUdICMNmBlUfv6dTJmovHydF DeCtS8eunKTYKnvSklmr/aLKnFFEaeoi SUF8hkHM2fADZekxqTEMS2ATjlY0rbTb biDd4c1tZdSDeUV7z4B4pHVdgVFBOi6+ kL4MtMM2AY4o9h31jOUGFnfA0cJPmxNN Cx+qgBAl0zKL9+uFrBqB6nYgmd0a1pRa UEQCcVVKkSjDX3gWHtO/nqflFmyDNV4Y OlVLcHVCDNqRtwIRwucUOg==
+ddnsb.csas.cz. 7200 IN A 194.50.240.192
+ddnsb.csas.cz. 7200 IN RRSIG A 7 3 7200 20190630180929 20190623180929 26663 csas.cz. CXelkXBmt3nR60+gTwRcTXTVH1OBpfAE McYGfcEmxk8t+wFwLrCfM+6mJUWbV3a8 cIggoBHU8gJxarnIX4K5bXNel2QRzlTa +qTTPPTxH5LwHayDwoo5edk6c2HkCrY3 qChg5SyjuNxxsF4ybqvqIU0d/kM6wqG7 pKPmplD9BNJmzVIVQ8aTBMhdrvIcqK/f 81TGgNxMqJxfpTYKmnA8vVqpJ3C1kbfn no+ux39NY7Wj58NwI+UIcDlmBj414MSz Z4wEfYSgtVnEA8fO+ufZ3jaxjk6NClz+ XMP1gYj/y08bj0h5ACIKJqci2uqPujoi TNBYzQWn6LVPqNIM8O7eSg==
+ddnsd.csas.cz. 7200 IN A 194.50.240.194
+ddnsd.csas.cz. 7200 IN RRSIG A 7 3 7200 20190630180929 20190623180929 26663 csas.cz. nsWIVa/SusXOatYzHtX8IPkETOBo90yd Zz8ce1PQhUawbQamihm1di90qJSQJ/i4 QCdL5ulxKJdMv8jLBjIBGe1H08d43luD OmLwkiBNoROZ1apKKabSQAmJTuwIxZCD sqYti2+rEbmOaRC1n96fIH2HWL9pYAnn C0GrvoWEDeVkSHI70Ei9CUCpUNOrPzhS BZc3PrB0DhojkzlXj359e4OhO1gH2QDp 2Uj05suhlIEzQf3lsvvIRUOrMPG2i6Fh j3yThN21+kuVyasrsN5Pv6Dp52U1k60l Y7AuwQwMUXrsdrK3/15DyxSS+pHenpsq cBI3Rb8P4Z6uVxZv9sQ4rQ==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NXDOMAIN
+SECTION QUESTION
+csas.cz. IN DS
+SECTION AUTHORITY
+cz. 60 IN SOA cecf53-ant-MS2A-1.csin.cz. hostmaster.cecf53-ant-MS2A-1.csin.cz. 2019061307 10800 3600 604800 60
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+ddnsb.csas.cz. IN NS
+SECTION AUTHORITY
+csas.cz. 120 IN RRSIG SOA 7 2 120 20190630054550 20190623054550 26663 csas.cz. c/sxvp5WLJOsDGgnhxPOk9oBwXRtsUXa enyWg5rd8yBcquHqfFKQu1v8wEPjJjAH B6joG1tJXq99nxtCN4jlDipPKLIzWxba aYIxE8Pab199qiHrR5vxO4KgPxRXbg5d gzIVrrhB+h23DZDacQ+l+kQWSAcycjPh xFvNjAZrH4obU/F+jHt4ix5XqEVuDrPQ YTGBGEUpl7YbcyaROzVP3dtCQZamkfaB CQYoNAJlNw6YFG1qulPm3pn3jJHhu88f dFgCisWfp7TjMYn7Id7aYJtliagE47xu ASnhOtaeXAVxDGUIkOI5u8uUCC/jAiHr MgARE5rcqh2AIZeSv0BiMQ==
+csas.cz. 120 IN SOA ddnsa.csas.cz. domainservices.csas.cz. 2019061320 28800 1800 2592000 120
+kl8ko9vcu5os0r0marmli019btprhvdr.csas.cz. 120 IN NSEC3 1 0 1 31245099125aedf7 kl8ko9vcu5os0r0marmli019btprhvds TXT
+kl8ko9vcu5os0r0marmli019btprhvdr.csas.cz. 120 IN RRSIG NSEC3 7 3 120 20190702130338 20190625130338 26663 csas.cz. ebbykapJt+h+uDJlz84Yu4rpx7spx8aY bbR/BCMIVJ6HjziYnwwbBQuyyd6t281+ pdn+2Dxo5tUJ0Kw4oatMPVhID8Psasd3 2Za8bZrouTk8RcQislJCj1jPi2HMIQUI dvJ1aCMC6vn1vI++ZMvcxfptxgmWyL46 i4P3xZAwtrB6hCVrctQ0dbbp1nswh1go YFIf3Hzxu2NHfXZYMdXXb1cLuOZ5L17g UZlqqgcrudLORc2cHj0NcjVT2PscMeoy a/jFNJwCHmkfI3nCAeXmemz/txQUY01u SxBNjkd/y2DVSIgvDPY/Zz0dW4gYdcMG 4T4D43oBTG6w06CgBg1QQw==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+ddnsb.csas.cz. IN A
+SECTION ANSWER
+ddnsb.csas.cz. 7200 IN A 194.50.240.192
+ddnsb.csas.cz. 7200 IN RRSIG A 7 3 7200 20190630180929 20190623180929 26663 csas.cz. CXelkXBmt3nR60+gTwRcTXTVH1OBpfAE McYGfcEmxk8t+wFwLrCfM+6mJUWbV3a8 cIggoBHU8gJxarnIX4K5bXNel2QRzlTa +qTTPPTxH5LwHayDwoo5edk6c2HkCrY3 qChg5SyjuNxxsF4ybqvqIU0d/kM6wqG7 pKPmplD9BNJmzVIVQ8aTBMhdrvIcqK/f 81TGgNxMqJxfpTYKmnA8vVqpJ3C1kbfn no+ux39NY7Wj58NwI+UIcDlmBj414MSz Z4wEfYSgtVnEA8fO+ufZ3jaxjk6NClz+ XMP1gYj/y08bj0h5ACIKJqci2uqPujoi TNBYzQWn6LVPqNIM8O7eSg==
+SECTION AUTHORITY
+csas.cz. 7200 IN NS ddnsa.csas.cz.
+csas.cz. 7200 IN NS ddnsb.csas.cz.
+csas.cz. 7200 IN NS ddnsc.csas.cz.
+csas.cz. 7200 IN NS ddnsd.csas.cz.
+csas.cz. 7200 IN RRSIG NS 7 2 7200 20190630180929 20190623180929 26663 csas.cz. PLqM9UHNFbb8GmE+SlzSCjAEKYsklbgt CnWf9G26HkwtacOyJkIHe+T0m94rJZTd 6Mnn32Sw/at6idSvVNGQfE6DIKr2rtK6 lJNe0HPMxYWC9Tr5zpzW1/SjLVooMw6n m8K+18RBI33PBI69UgXyuePnWefdTYOJ g4SK3rR2wUlFxnELEFGfYkytZ6tLi1Cd bTgch93lDnXNBRZ2t/mu5jPyv4NTdKCo WgIMJJcuFdPr/YRVRaemkVEup7qVYImk pa4n+7MMERTL/dw+GxtnZ2YKqyxcepYo rPib3FSTaOFZjEPqNPDNfXXYW+bPmWFP 9ESqUtgmvZ1rMDZbr8lbgQ==
+SECTION ADDITIONAL
+ddnsa.csas.cz. 7200 IN A 194.50.240.64
+ddnsa.csas.cz. 7200 IN RRSIG A 7 3 7200 20190630180929 20190623180929 26663 csas.cz. QJCNptf+bgoFFzW6vh6lMnevBqaHq1Qk p7UB7hJZfqewhVJsf4/aZlUJg9Ulq990 xe1K+Vw2H7zFKRmS+BhLL0NVS6F/uo3g VWU7UkiLCUdICMNmBlUfv6dTJmovHydF DeCtS8eunKTYKnvSklmr/aLKnFFEaeoi SUF8hkHM2fADZekxqTEMS2ATjlY0rbTb biDd4c1tZdSDeUV7z4B4pHVdgVFBOi6+ kL4MtMM2AY4o9h31jOUGFnfA0cJPmxNN Cx+qgBAl0zKL9+uFrBqB6nYgmd0a1pRa UEQCcVVKkSjDX3gWHtO/nqflFmyDNV4Y OlVLcHVCDNqRtwIRwucUOg==
+ddnsc.csas.cz. 7200 IN A 194.50.240.66
+ddnsc.csas.cz. 7200 IN RRSIG A 7 3 7200 20190630180929 20190623180929 26663 csas.cz. AHQJp3i/UzKmjm/hhmEM1mhV7gPAq2rX 0z4ZOF+ZDyL57nXSHnzGqz4sdd3Q0E1H pmGENdgiOR1Grabo6X3QIp7mZbuAR14T 5TQYHSDoTZ+aTOkqvxCxfUCpEYLVHlbP whE+ntazt0gmkko3eGUBMefMv+JVmuwy tirS7pxlNL1VRnKtbfDsWJ2zmJuur/WK wGzHCMybt4fITB0Og/I9pnwMwykdxhpF bo/MQAa35oTefzvWsD3uFKOhrAc7CP2N MyqDFzv0QDN00s0yFXHHxNg3QFXLAg16 4khZaKT076k+F5N/ufsoIeU/AbByx82T PxpLg8NCh9nNvzgqoCEccw==
+ddnsd.csas.cz. 7200 IN A 194.50.240.194
+ddnsd.csas.cz. 7200 IN RRSIG A 7 3 7200 20190630180929 20190623180929 26663 csas.cz. nsWIVa/SusXOatYzHtX8IPkETOBo90yd Zz8ce1PQhUawbQamihm1di90qJSQJ/i4 QCdL5ulxKJdMv8jLBjIBGe1H08d43luD OmLwkiBNoROZ1apKKabSQAmJTuwIxZCD sqYti2+rEbmOaRC1n96fIH2HWL9pYAnn C0GrvoWEDeVkSHI70Ei9CUCpUNOrPzhS BZc3PrB0DhojkzlXj359e4OhO1gH2QDp 2Uj05suhlIEzQf3lsvvIRUOrMPG2i6Fh j3yThN21+kuVyasrsN5Pv6Dp52U1k60l Y7AuwQwMUXrsdrK3/15DyxSS+pHenpsq cBI3Rb8P4Z6uVxZv9sQ4rQ==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+ddnsd.csas.cz. IN A
+SECTION ANSWER
+ddnsd.csas.cz. 7200 IN A 194.50.240.194
+ddnsd.csas.cz. 7200 IN RRSIG A 7 3 7200 20190630180929 20190623180929 26663 csas.cz. nsWIVa/SusXOatYzHtX8IPkETOBo90yd Zz8ce1PQhUawbQamihm1di90qJSQJ/i4 QCdL5ulxKJdMv8jLBjIBGe1H08d43luD OmLwkiBNoROZ1apKKabSQAmJTuwIxZCD sqYti2+rEbmOaRC1n96fIH2HWL9pYAnn C0GrvoWEDeVkSHI70Ei9CUCpUNOrPzhS BZc3PrB0DhojkzlXj359e4OhO1gH2QDp 2Uj05suhlIEzQf3lsvvIRUOrMPG2i6Fh j3yThN21+kuVyasrsN5Pv6Dp52U1k60l Y7AuwQwMUXrsdrK3/15DyxSS+pHenpsq cBI3Rb8P4Z6uVxZv9sQ4rQ==
+SECTION AUTHORITY
+csas.cz. 7200 IN NS ddnsa.csas.cz.
+csas.cz. 7200 IN NS ddnsb.csas.cz.
+csas.cz. 7200 IN NS ddnsc.csas.cz.
+csas.cz. 7200 IN NS ddnsd.csas.cz.
+csas.cz. 7200 IN RRSIG NS 7 2 7200 20190630180929 20190623180929 26663 csas.cz. PLqM9UHNFbb8GmE+SlzSCjAEKYsklbgt CnWf9G26HkwtacOyJkIHe+T0m94rJZTd 6Mnn32Sw/at6idSvVNGQfE6DIKr2rtK6 lJNe0HPMxYWC9Tr5zpzW1/SjLVooMw6n m8K+18RBI33PBI69UgXyuePnWefdTYOJ g4SK3rR2wUlFxnELEFGfYkytZ6tLi1Cd bTgch93lDnXNBRZ2t/mu5jPyv4NTdKCo WgIMJJcuFdPr/YRVRaemkVEup7qVYImk pa4n+7MMERTL/dw+GxtnZ2YKqyxcepYo rPib3FSTaOFZjEPqNPDNfXXYW+bPmWFP 9ESqUtgmvZ1rMDZbr8lbgQ==
+SECTION ADDITIONAL
+ddnsa.csas.cz. 7200 IN A 194.50.240.64
+ddnsa.csas.cz. 7200 IN RRSIG A 7 3 7200 20190630180929 20190623180929 26663 csas.cz. QJCNptf+bgoFFzW6vh6lMnevBqaHq1Qk p7UB7hJZfqewhVJsf4/aZlUJg9Ulq990 xe1K+Vw2H7zFKRmS+BhLL0NVS6F/uo3g VWU7UkiLCUdICMNmBlUfv6dTJmovHydF DeCtS8eunKTYKnvSklmr/aLKnFFEaeoi SUF8hkHM2fADZekxqTEMS2ATjlY0rbTb biDd4c1tZdSDeUV7z4B4pHVdgVFBOi6+ kL4MtMM2AY4o9h31jOUGFnfA0cJPmxNN Cx+qgBAl0zKL9+uFrBqB6nYgmd0a1pRa UEQCcVVKkSjDX3gWHtO/nqflFmyDNV4Y OlVLcHVCDNqRtwIRwucUOg==
+ddnsb.csas.cz. 7200 IN A 194.50.240.192
+ddnsb.csas.cz. 7200 IN RRSIG A 7 3 7200 20190630180929 20190623180929 26663 csas.cz. CXelkXBmt3nR60+gTwRcTXTVH1OBpfAE McYGfcEmxk8t+wFwLrCfM+6mJUWbV3a8 cIggoBHU8gJxarnIX4K5bXNel2QRzlTa +qTTPPTxH5LwHayDwoo5edk6c2HkCrY3 qChg5SyjuNxxsF4ybqvqIU0d/kM6wqG7 pKPmplD9BNJmzVIVQ8aTBMhdrvIcqK/f 81TGgNxMqJxfpTYKmnA8vVqpJ3C1kbfn no+ux39NY7Wj58NwI+UIcDlmBj414MSz Z4wEfYSgtVnEA8fO+ufZ3jaxjk6NClz+ XMP1gYj/y08bj0h5ACIKJqci2uqPujoi TNBYzQWn6LVPqNIM8O7eSg==
+ddnsc.csas.cz. 7200 IN A 194.50.240.66
+ddnsc.csas.cz. 7200 IN RRSIG A 7 3 7200 20190630180929 20190623180929 26663 csas.cz. AHQJp3i/UzKmjm/hhmEM1mhV7gPAq2rX 0z4ZOF+ZDyL57nXSHnzGqz4sdd3Q0E1H pmGENdgiOR1Grabo6X3QIp7mZbuAR14T 5TQYHSDoTZ+aTOkqvxCxfUCpEYLVHlbP whE+ntazt0gmkko3eGUBMefMv+JVmuwy tirS7pxlNL1VRnKtbfDsWJ2zmJuur/WK wGzHCMybt4fITB0Og/I9pnwMwykdxhpF bo/MQAa35oTefzvWsD3uFKOhrAc7CP2N MyqDFzv0QDN00s0yFXHHxNg3QFXLAg16 4khZaKT076k+F5N/ufsoIeU/AbByx82T PxpLg8NCh9nNvzgqoCEccw==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+ddnsa.csas.cz. IN AAAA
+SECTION AUTHORITY
+csas.cz. 120 IN RRSIG SOA 7 2 120 20190630054550 20190623054550 26663 csas.cz. c/sxvp5WLJOsDGgnhxPOk9oBwXRtsUXa enyWg5rd8yBcquHqfFKQu1v8wEPjJjAH B6joG1tJXq99nxtCN4jlDipPKLIzWxba aYIxE8Pab199qiHrR5vxO4KgPxRXbg5d gzIVrrhB+h23DZDacQ+l+kQWSAcycjPh xFvNjAZrH4obU/F+jHt4ix5XqEVuDrPQ YTGBGEUpl7YbcyaROzVP3dtCQZamkfaB CQYoNAJlNw6YFG1qulPm3pn3jJHhu88f dFgCisWfp7TjMYn7Id7aYJtliagE47xu ASnhOtaeXAVxDGUIkOI5u8uUCC/jAiHr MgARE5rcqh2AIZeSv0BiMQ==
+csas.cz. 120 IN SOA ddnsa.csas.cz. domainservices.csas.cz. 2019061320 28800 1800 2592000 120
+j0hp68elhot3j046r6mr0tnqlns1dbc7.csas.cz. 120 IN NSEC3 1 0 1 31245099125aedf7 j0hp68elhot3j046r6mr0tnqlns1dbc8 TXT
+j0hp68elhot3j046r6mr0tnqlns1dbc7.csas.cz. 120 IN RRSIG NSEC3 7 3 120 20190702130338 20190625130338 26663 csas.cz. gUyltGyzdD2L6M29xgqWXMO834aavtFc Si2oAbET0rEJZ5w9ewhEJdVT65MMUUlK wvVX239N7PtsyL+fQvxu5TZ8du0ML8Oi KBp3gao/stajg/lZFd6zVvDWliC3+psL 7PFmD5au5qcrYc6HLc8m8D4hHFPREyd6 1tLGA98RevbQGfrDYODXi6G28vwbxoYU POn4mo82MnVVTZhh58cu7nKRRvKAtay6 VZVWZBOuxy8u+LNsrj3vpDbaOIiWzHd0 pRACsv3LqGpxQNH8avSalWLBvLWchAHj 0T2M+doO8UVaCsyFo/3wF2TXdgFcOAr3 xDIdhHCCoanRVFZ+gFAwIw==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+ddnsa.csas.cz. IN NS
+SECTION AUTHORITY
+csas.cz. 120 IN RRSIG SOA 7 2 120 20190630054550 20190623054550 26663 csas.cz. c/sxvp5WLJOsDGgnhxPOk9oBwXRtsUXa enyWg5rd8yBcquHqfFKQu1v8wEPjJjAH B6joG1tJXq99nxtCN4jlDipPKLIzWxba aYIxE8Pab199qiHrR5vxO4KgPxRXbg5d gzIVrrhB+h23DZDacQ+l+kQWSAcycjPh xFvNjAZrH4obU/F+jHt4ix5XqEVuDrPQ YTGBGEUpl7YbcyaROzVP3dtCQZamkfaB CQYoNAJlNw6YFG1qulPm3pn3jJHhu88f dFgCisWfp7TjMYn7Id7aYJtliagE47xu ASnhOtaeXAVxDGUIkOI5u8uUCC/jAiHr MgARE5rcqh2AIZeSv0BiMQ==
+csas.cz. 120 IN SOA ddnsa.csas.cz. domainservices.csas.cz. 2019061320 28800 1800 2592000 120
+j0hp68elhot3j046r6mr0tnqlns1dbc7.csas.cz. 120 IN NSEC3 1 0 1 31245099125aedf7 j0hp68elhot3j046r6mr0tnqlns1dbc8 TXT
+j0hp68elhot3j046r6mr0tnqlns1dbc7.csas.cz. 120 IN RRSIG NSEC3 7 3 120 20190702130338 20190625130338 26663 csas.cz. gUyltGyzdD2L6M29xgqWXMO834aavtFc Si2oAbET0rEJZ5w9ewhEJdVT65MMUUlK wvVX239N7PtsyL+fQvxu5TZ8du0ML8Oi KBp3gao/stajg/lZFd6zVvDWliC3+psL 7PFmD5au5qcrYc6HLc8m8D4hHFPREyd6 1tLGA98RevbQGfrDYODXi6G28vwbxoYU POn4mo82MnVVTZhh58cu7nKRRvKAtay6 VZVWZBOuxy8u+LNsrj3vpDbaOIiWzHd0 pRACsv3LqGpxQNH8avSalWLBvLWchAHj 0T2M+doO8UVaCsyFo/3wF2TXdgFcOAr3 xDIdhHCCoanRVFZ+gFAwIw==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+ddnsc.csas.cz. IN AAAA
+SECTION AUTHORITY
+c1c03am0n36kncp4iqb4buoqo1ectql4.csas.cz. 120 IN NSEC3 1 0 1 31245099125aedf7 c1c03am0n36kncp4iqb4buoqo1ectql5 TXT
+c1c03am0n36kncp4iqb4buoqo1ectql4.csas.cz. 120 IN RRSIG NSEC3 7 3 120 20190702130338 20190625130338 26663 csas.cz. FKjWbcw5aP2HzHFy2t+M462dxM1ph0FW 02Tohh/aJQOp1iKQOi6u1V2tI3H9CMXW xeIAktZ+xiUDRYLX50fNuJZMaSsn7r5A LYjVAKGzwMPncIf6IlEDYkj1I1rdp6z8 LvWsWNO1wfIPq1Dw2geN60bcz3D7r/sY WfjU/7jO9f0nekZZXI2qFsMSYd9Dkaq7 mlpP0NrWnUbCjL+BfuLFNebh8g3D8f5w Tq3R9czwW5YTVXUquBIrjiZ0Ko9INgQ/ 4pvJqJ1bsTpmzdODfAssEtpu+es4wLwt ZTe8Ll9VeDB20RqEnAyHZwQRXXVF2t+F vdJU7Desbpu6rElA7IXwRw==
+csas.cz. 120 IN RRSIG SOA 7 2 120 20190630054550 20190623054550 26663 csas.cz. c/sxvp5WLJOsDGgnhxPOk9oBwXRtsUXa enyWg5rd8yBcquHqfFKQu1v8wEPjJjAH B6joG1tJXq99nxtCN4jlDipPKLIzWxba aYIxE8Pab199qiHrR5vxO4KgPxRXbg5d gzIVrrhB+h23DZDacQ+l+kQWSAcycjPh xFvNjAZrH4obU/F+jHt4ix5XqEVuDrPQ YTGBGEUpl7YbcyaROzVP3dtCQZamkfaB CQYoNAJlNw6YFG1qulPm3pn3jJHhu88f dFgCisWfp7TjMYn7Id7aYJtliagE47xu ASnhOtaeXAVxDGUIkOI5u8uUCC/jAiHr MgARE5rcqh2AIZeSv0BiMQ==
+csas.cz. 120 IN SOA ddnsa.csas.cz. domainservices.csas.cz. 2019061320 28800 1800 2592000 120
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH subdomain
+ADJUST copy_id copy_query
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+csas.cz. IN NS
+SECTION ANSWER
+csas.cz. 7200 IN NS ddnsa.csas.cz.
+csas.cz. 7200 IN NS ddnsb.csas.cz.
+csas.cz. 7200 IN NS ddnsc.csas.cz.
+csas.cz. 7200 IN NS ddnsd.csas.cz.
+csas.cz. 7200 IN RRSIG NS 7 2 7200 20190630180929 20190623180929 26663 csas.cz. PLqM9UHNFbb8GmE+SlzSCjAEKYsklbgt CnWf9G26HkwtacOyJkIHe+T0m94rJZTd 6Mnn32Sw/at6idSvVNGQfE6DIKr2rtK6 lJNe0HPMxYWC9Tr5zpzW1/SjLVooMw6n m8K+18RBI33PBI69UgXyuePnWefdTYOJ g4SK3rR2wUlFxnELEFGfYkytZ6tLi1Cd bTgch93lDnXNBRZ2t/mu5jPyv4NTdKCo WgIMJJcuFdPr/YRVRaemkVEup7qVYImk pa4n+7MMERTL/dw+GxtnZ2YKqyxcepYo rPib3FSTaOFZjEPqNPDNfXXYW+bPmWFP 9ESqUtgmvZ1rMDZbr8lbgQ==
+SECTION ADDITIONAL
+ddnsa.csas.cz. 7200 IN A 194.50.240.64
+ddnsa.csas.cz. 7200 IN RRSIG A 7 3 7200 20190630180929 20190623180929 26663 csas.cz. QJCNptf+bgoFFzW6vh6lMnevBqaHq1Qk p7UB7hJZfqewhVJsf4/aZlUJg9Ulq990 xe1K+Vw2H7zFKRmS+BhLL0NVS6F/uo3g VWU7UkiLCUdICMNmBlUfv6dTJmovHydF DeCtS8eunKTYKnvSklmr/aLKnFFEaeoi SUF8hkHM2fADZekxqTEMS2ATjlY0rbTb biDd4c1tZdSDeUV7z4B4pHVdgVFBOi6+ kL4MtMM2AY4o9h31jOUGFnfA0cJPmxNN Cx+qgBAl0zKL9+uFrBqB6nYgmd0a1pRa UEQCcVVKkSjDX3gWHtO/nqflFmyDNV4Y OlVLcHVCDNqRtwIRwucUOg==
+ddnsb.csas.cz. 7200 IN A 194.50.240.192
+ddnsb.csas.cz. 7200 IN RRSIG A 7 3 7200 20190630180929 20190623180929 26663 csas.cz. CXelkXBmt3nR60+gTwRcTXTVH1OBpfAE McYGfcEmxk8t+wFwLrCfM+6mJUWbV3a8 cIggoBHU8gJxarnIX4K5bXNel2QRzlTa +qTTPPTxH5LwHayDwoo5edk6c2HkCrY3 qChg5SyjuNxxsF4ybqvqIU0d/kM6wqG7 pKPmplD9BNJmzVIVQ8aTBMhdrvIcqK/f 81TGgNxMqJxfpTYKmnA8vVqpJ3C1kbfn no+ux39NY7Wj58NwI+UIcDlmBj414MSz Z4wEfYSgtVnEA8fO+ufZ3jaxjk6NClz+ XMP1gYj/y08bj0h5ACIKJqci2uqPujoi TNBYzQWn6LVPqNIM8O7eSg==
+ddnsc.csas.cz. 7200 IN A 194.50.240.66
+ddnsc.csas.cz. 7200 IN RRSIG A 7 3 7200 20190630180929 20190623180929 26663 csas.cz. AHQJp3i/UzKmjm/hhmEM1mhV7gPAq2rX 0z4ZOF+ZDyL57nXSHnzGqz4sdd3Q0E1H pmGENdgiOR1Grabo6X3QIp7mZbuAR14T 5TQYHSDoTZ+aTOkqvxCxfUCpEYLVHlbP whE+ntazt0gmkko3eGUBMefMv+JVmuwy tirS7pxlNL1VRnKtbfDsWJ2zmJuur/WK wGzHCMybt4fITB0Og/I9pnwMwykdxhpF bo/MQAa35oTefzvWsD3uFKOhrAc7CP2N MyqDFzv0QDN00s0yFXHHxNg3QFXLAg16 4khZaKT076k+F5N/ufsoIeU/AbByx82T PxpLg8NCh9nNvzgqoCEccw==
+ddnsd.csas.cz. 7200 IN A 194.50.240.194
+ddnsd.csas.cz. 7200 IN RRSIG A 7 3 7200 20190630180929 20190623180929 26663 csas.cz. nsWIVa/SusXOatYzHtX8IPkETOBo90yd Zz8ce1PQhUawbQamihm1di90qJSQJ/i4 QCdL5ulxKJdMv8jLBjIBGe1H08d43luD OmLwkiBNoROZ1apKKabSQAmJTuwIxZCD sqYti2+rEbmOaRC1n96fIH2HWL9pYAnn C0GrvoWEDeVkSHI70Ei9CUCpUNOrPzhS BZc3PrB0DhojkzlXj359e4OhO1gH2QDp 2Uj05suhlIEzQf3lsvvIRUOrMPG2i6Fh j3yThN21+kuVyasrsN5Pv6Dp52U1k60l Y7AuwQwMUXrsdrK3/15DyxSS+pHenpsq cBI3Rb8P4Z6uVxZv9sQ4rQ==
+ENTRY_END
+
+
+
+
+RANGE_END
+
+
+
+; Group's zones:
+; com.
+; net.
+; Server names:
+; a.gtld-servers.net.
+; j.gtld-servers.net.
+; e.gtld-servers.net.
+; i.gtld-servers.net.
+; d.gtld-servers.net.
+; m.gtld-servers.net.
+; h.gtld-servers.net.
+; c.gtld-servers.net.
+; l.gtld-servers.net.
+; g.gtld-servers.net.
+; b.gtld-servers.net.
+; k.gtld-servers.net.
+; f.gtld-servers.net.
+RANGE_BEGIN 0 1000
+ ADDRESS 2001:502:8cc::30
+ ADDRESS 2001:503:eea3::30
+ ADDRESS 192.5.6.30
+ ADDRESS 192.33.14.30
+ ADDRESS 192.43.172.30
+ ADDRESS 192.12.94.30
+ ADDRESS 192.48.79.30
+ ADDRESS 2001:502:1ca1::30
+ ADDRESS 192.54.112.30
+ ADDRESS 2001:500:856e::30
+ ADDRESS 2001:503:a83e::2:30
+ ADDRESS 192.52.178.30
+ ADDRESS 2001:503:d2d::30
+ ADDRESS 192.26.92.30
+ ADDRESS 192.41.162.30
+ ADDRESS 192.31.80.30
+ ADDRESS 2001:503:83eb::30
+ ADDRESS 192.42.93.30
+ ADDRESS 2001:503:39c1::30
+ ADDRESS 2001:503:231d::2:30
+ ADDRESS 192.35.51.30
+ ADDRESS 2001:500:d937::30
+ ADDRESS 2001:503:d414::30
+ ADDRESS 2001:502:7094::30
+ ADDRESS 2001:501:b1f9::30
+ ADDRESS 192.55.83.30
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+nstld.com. IN DS
+SECTION AUTHORITY
+5V12UURISSGGLPAS52GE1V3R0V7KR5BS.com. 86400 IN NSEC3 1 1 0 - 5v13q049b9ittui4fbdtm34dtev47bgj NS DS RRSIG
+5V12UURISSGGLPAS52GE1V3R0V7KR5BS.com. 86400 IN RRSIG NSEC3 8 2 86400 20190630044250 20190623033250 3800 com. NlBOkX84YgGooJJ2vp+Z/O16Vkz6z1gC Jy1Va3fJyEXfZr/GIm8J3KJ6Eq+xxp1A x3ZWxwUjNH3TGUEme7pDrmusqRpx/TZF Za3dVAYIvsaVgIWtDCn4BLBPrg0HXcon HE60KLgWGQmezzFKrNsy5Tzz9TajUSgQ uOTQHB7TFDg=
+CK0POJMG874LJREF7EFN8430QVIT8BSM.com. 86400 IN NSEC3 1 1 0 - ck0q1gin43n1arrc9osm6qpqr81h5m9a NS SOA RRSIG DNSKEY NSEC3PARAM
+CK0POJMG874LJREF7EFN8430QVIT8BSM.com. 86400 IN RRSIG NSEC3 8 2 86400 20190702044530 20190625033530 3800 com. BMWhk6USUrb7TNJ3dSObn8QEPWvpzedW kP9i4RRPz7V9c2yVPmHSPt29QKsHOYTg iF4uyHt+K8RK8DBIziB19nrOjbb8iRDY 7m5koEj/OrS2peMuF6rqRRmkI6SY/ACy XHb/hRGE4tZd2gThNb7evZkk02IVuhEo njO3NBjCrsw=
+com. 900 IN RRSIG SOA 8 1 900 20190702140912 20190625125912 3800 com. c6kEiaL24fAOXZf4AexmGfQejNxB+Na5 Omftkar0u1SFkd7I03ieGTsJt/aiFVND ucQklNtxUqTC4SQpGLmNYlzIDRvb2vYC GL7tSomPB/Tt4xYczPvNIOJKQOtFAjoL hJn5hj1jCo56iBD5OmbLwQcq8XI/W7xs yvTMfjKpeEQ=
+com. 900 IN SOA a.gtld-servers.net. nstld.verisign-grs.com. 1561471752 1800 900 604800 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+root-servers.net. IN DS
+SECTION AUTHORITY
+A1RT98BS5QGC9NFI51S9HCI47ULJG6JH.net. 86400 IN NSEC3 1 1 0 - a1ruuffjkct2q54p78f8ejgj8jbk7i8b NS SOA RRSIG DNSKEY NSEC3PARAM
+A1RT98BS5QGC9NFI51S9HCI47ULJG6JH.net. 86400 IN RRSIG NSEC3 8 2 86400 20190702055539 20190625044539 2129 net. KgEWjLXuYdPBhlNh2epfnKU879hg4GGf F4m4Fo7ZW+S3uhNqq8pF7sMJCvSs8ZZA Ctcm88XThCeIAxDxLZ5moOlMIWaweVX3 7B7s3mw+3K0cnkYF6J4FqBO8o7x6J3i2 c6kxI3q0DKub23GcXpWZu3x2yIkWuN0I ZgceikGAPpM=
+T2UF21DR03E0BNPB42UQMVUF38P2TA8D.net. 86400 IN NSEC3 1 1 0 - t2ukct9k5i0uhv7b3m3na6jaigdjm0gr NS DS RRSIG
+T2UF21DR03E0BNPB42UQMVUF38P2TA8D.net. 86400 IN RRSIG NSEC3 8 2 86400 20190630054523 20190623043523 2129 net. adpeQf+K6Hr5amhmF9DNK56LVWWnfGHK Dz9t9e7swG/P+4clc4yMKmUvK0OF9aTA kBzDwnzeB+FT+nsg1cWdibs4559AKQCL RtNErPhZRMojUFo6TLM9lQoXhv9i5rZB AJGmirHgSwiAvaUK7tgxX3nr1Atahyew iwHDQIVPhw4=
+net. 900 IN RRSIG SOA 8 1 900 20190702140916 20190625125916 2129 net. cMaAZOeBq2v9urE/L5RZEBRSTmY4/MMJ ADm+GUhaqP3FQ0RD3fO6IU7qdP3jCmlZ QmCl68ZVaMyZvVIcNcv7fokWbqTm9r4j 2NB0W9j/B/ZIOzCV4myDqaylU62tNTUA okGZMzclPCSd2n8ZDHZ3RysudhiZ/8WG FVdsHHtp67c=
+net. 900 IN SOA a.gtld-servers.net. nstld.verisign-grs.com. 1561471756 1800 900 604800 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+net. IN DS
+SECTION AUTHORITY
+A1RT98BS5QGC9NFI51S9HCI47ULJG6JH.net. 86400 IN NSEC3 1 1 0 - a1ruuffjkct2q54p78f8ejgj8jbk7i8b NS SOA RRSIG DNSKEY NSEC3PARAM
+A1RT98BS5QGC9NFI51S9HCI47ULJG6JH.net. 86400 IN RRSIG NSEC3 8 2 86400 20190702055539 20190625044539 2129 net. KgEWjLXuYdPBhlNh2epfnKU879hg4GGf F4m4Fo7ZW+S3uhNqq8pF7sMJCvSs8ZZA Ctcm88XThCeIAxDxLZ5moOlMIWaweVX3 7B7s3mw+3K0cnkYF6J4FqBO8o7x6J3i2 c6kxI3q0DKub23GcXpWZu3x2yIkWuN0I ZgceikGAPpM=
+net. 900 IN RRSIG SOA 8 1 900 20190702140916 20190625125916 2129 net. cMaAZOeBq2v9urE/L5RZEBRSTmY4/MMJ ADm+GUhaqP3FQ0RD3fO6IU7qdP3jCmlZ QmCl68ZVaMyZvVIcNcv7fokWbqTm9r4j 2NB0W9j/B/ZIOzCV4myDqaylU62tNTUA okGZMzclPCSd2n8ZDHZ3RysudhiZ/8WG FVdsHHtp67c=
+net. 900 IN SOA a.gtld-servers.net. nstld.verisign-grs.com. 1561471756 1800 900 604800 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+com. IN DS
+SECTION AUTHORITY
+CK0POJMG874LJREF7EFN8430QVIT8BSM.com. 86400 IN NSEC3 1 1 0 - ck0q1gin43n1arrc9osm6qpqr81h5m9a NS SOA RRSIG DNSKEY NSEC3PARAM
+CK0POJMG874LJREF7EFN8430QVIT8BSM.com. 86400 IN RRSIG NSEC3 8 2 86400 20190702044530 20190625033530 3800 com. BMWhk6USUrb7TNJ3dSObn8QEPWvpzedW kP9i4RRPz7V9c2yVPmHSPt29QKsHOYTg iF4uyHt+K8RK8DBIziB19nrOjbb8iRDY 7m5koEj/OrS2peMuF6rqRRmkI6SY/ACy XHb/hRGE4tZd2gThNb7evZkk02IVuhEo njO3NBjCrsw=
+com. 900 IN RRSIG SOA 8 1 900 20190702140912 20190625125912 3800 com. c6kEiaL24fAOXZf4AexmGfQejNxB+Na5 Omftkar0u1SFkd7I03ieGTsJt/aiFVND ucQklNtxUqTC4SQpGLmNYlzIDRvb2vYC GL7tSomPB/Tt4xYczPvNIOJKQOtFAjoL hJn5hj1jCo56iBD5OmbLwQcq8XI/W7xs yvTMfjKpeEQ=
+com. 900 IN SOA a.gtld-servers.net. nstld.verisign-grs.com. 1561471752 1800 900 604800 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+net. IN DNSKEY
+SECTION ANSWER
+net. 86400 IN DNSKEY 256 3 8 AQPB6mADOfWU6hTegl+pTl1wtjTll+Zn WIuRb8+cU9XNWNPpc3mX+rUqPeiw0RpK kD4QkTqTefWjMqjXMvYn2TxX4V4FMQXY MJr0bgiZXGosA9C9Aa7RgYyt4GJCToXq lM+mTqBjXDkh7yBa8I2X3p6Tt/PoKhiq CtmNl6sggTanJw==
+net. 86400 IN DNSKEY 257 3 8 AQOYBnzqWXIEj6mlgXg4LWC0HP2n8eK8 XqgHlmJ/69iuIHsa1TrHDG6TcOra/pye GKwH0nKZhTmXSuUFGh9BCNiwVDuyyb6O BGy2Nte9Kr8NwWg4q+zhSoOf4D+gC9dE zg0yFdwT0DKEvmNPt0K4jbQDS4Yimb+u PKuF6yieWWrPYYCrv8C9KC8JMze2uT6N uWBfsl2fDUoV4l65qMww06D7n+p7Rbdw WkAZ0fA63mXVXBZF6kpDtsYD7SUB9jhh fLQE/r85bvg3FaSs5Wi2BaqN06SzGWI1 DHu7axthIOeHwg00zxlhTpoYCH0ldoQz +S65zWYi/fRJiyLSBb6JZOvn
+net. 86400 IN RRSIG DNSKEY 8 1 86400 20190704153857 20190619153357 35886 net. T0Dcg9EVsoYzu+hywAW4mW11X/+oW/zt 0tQ8TdsKgY/5+/RL0tZCoU1EqbkBfM5h PxZgupQ0SQ//haveGagTgXOAOpa2nmUa o26dJC0xyZRTHuViy5708DONc88JZt+U pAgFcmJYjTXLu2QNywtyCXhcjnCuYAVG lTrarCn0rzW7PZp94xyGTCegkK9TysCt aqnIS0z/LVA2PjF+5etoEl7nWxCa1iUY 7as3zQ8CYlSDLwf7Sx4pUA/4hLZftwdO gNvb/pUdy7Zy/+6SGS3K4CPFkWG9kfs/ /76iMG6GkV2loGJApIFtYlui5iFaNfIM YBTD29dqC2I9ofe4WJnmpg==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+com. IN DNSKEY
+SECTION ANSWER
+com. 86400 IN DNSKEY 256 3 8 AQOcWJruwENIaapq3h3lKJlflLx6rWJz 2aKRBV6CBJRTxZu4ge2iDX164dQ7Hpc9 b8C9z2gqWyx1XyjvbQisgSid24voeUHQ gD0weedVDQjD6B9By7zMI6Yz+cM/w6H8 zB8ZRn6qZuWZAxFOjKvzoz+3vf32tyZE 7QmLFnXDgQpFxw==
+com. 86400 IN DNSKEY 257 3 8 AQPDzldNmMvZFX4NcNJ0uEnKDg7tmv/F 3MyQR0lpBmVcNcsIszxNFxsBfKNW9JYC Yqpik8366LE7VbIcNRzfp2h9OO8HRl+H +E08zauK8k7evWEmu/6od+2boggPoiEf GNyvNPaSI7FOIroDsnw/taggzHRX1Z7S OiOiPWPNIwSUyWOZ79VmcQ1GLkC6NlYv G3HwYmynQv6oFwGv/KELSw7ZSdrbTQ0H XvZbqMUI7BaMskmvgm1G7oKZ1YiF7O9i oVNc0+7ASbqmZN7Z98EGU/Qh2K/BgUe8 Hs0XVcdPKrtyYnoQHd2ynKPcMMlTEih2 /2HDHjRPJ2aywIpKNnv4oPo/
+com. 86400 IN RRSIG DNSKEY 8 1 86400 20190706182533 20190621182033 30909 com. v4xbl08Oyis8hHQ/7k9DuSLa75uMshqc V4783gXEEq1+dbgwBct8I2Td4+9mjIql fD1UO6Wu6VSYUtef39VQe4DuIWqtRrh/ WA/EOrrEY5Qieem9LTPL/zHWGQiILaHz CUHk1iUGFyZy4IRnZPkigTYKm1M7ZRXv qTTYSLemVZsna2/siDVYAdAhXWvJHQGl DkT3WDAvryFPpuEOrhUWkfhWAGy/ZsmD 87OiTX50TG/3ISEqFyzow/GZjViZnG5C tBmwdX/E8CIN6lVJV3LU3bMRYmuAHYEE lM+lVKAEyooxuRBNOdtZHD9tM8V6cfyd t89aE9LaiSn1DsFjUqFu/A==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+gtld-servers.net. IN DS
+SECTION AUTHORITY
+5QDO29Q2PS5ARBKHB6R0BRN6NDSTSN90.net. 86400 IN NSEC3 1 1 0 - 5qdppotuk27kkp9ligtrb0k1cbvm9cim NS DS RRSIG
+5QDO29Q2PS5ARBKHB6R0BRN6NDSTSN90.net. 86400 IN RRSIG NSEC3 8 2 86400 20190629054715 20190622043715 2129 net. fvRKJkn9D2H3DFGE0zpk/tAkyjaoEZY4 4TkN6XtCAibjzQS8R0SCaXmZlQQujnjG wp0Rjhy0gMQaFUrJ8QuUbJSDZQaicAl7 pCESVKd95GZOSgi07BXSKwdUMAPROSjz gDkYGzHcUB5Kfe23gkL2eQ05YVigHYhI l0YCHui1wHE=
+A1RT98BS5QGC9NFI51S9HCI47ULJG6JH.net. 86400 IN NSEC3 1 1 0 - a1ruuffjkct2q54p78f8ejgj8jbk7i8b NS SOA RRSIG DNSKEY NSEC3PARAM
+A1RT98BS5QGC9NFI51S9HCI47ULJG6JH.net. 86400 IN RRSIG NSEC3 8 2 86400 20190702055539 20190625044539 2129 net. KgEWjLXuYdPBhlNh2epfnKU879hg4GGf F4m4Fo7ZW+S3uhNqq8pF7sMJCvSs8ZZA Ctcm88XThCeIAxDxLZ5moOlMIWaweVX3 7B7s3mw+3K0cnkYF6J4FqBO8o7x6J3i2 c6kxI3q0DKub23GcXpWZu3x2yIkWuN0I ZgceikGAPpM=
+net. 900 IN RRSIG SOA 8 1 900 20190702140916 20190625125916 2129 net. cMaAZOeBq2v9urE/L5RZEBRSTmY4/MMJ ADm+GUhaqP3FQ0RD3fO6IU7qdP3jCmlZ QmCl68ZVaMyZvVIcNcv7fokWbqTm9r4j 2NB0W9j/B/ZIOzCV4myDqaylU62tNTUA okGZMzclPCSd2n8ZDHZ3RysudhiZ/8WG FVdsHHtp67c=
+net. 900 IN SOA a.gtld-servers.net. nstld.verisign-grs.com. 1561471756 1800 900 604800 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH subdomain
+ADJUST copy_id copy_query
+REPLY QR RD NOERROR
+SECTION QUESTION
+gtld-servers.net. IN NS
+SECTION AUTHORITY
+5QDO29Q2PS5ARBKHB6R0BRN6NDSTSN90.net. 86400 IN NSEC3 1 1 0 - 5qdppotuk27kkp9ligtrb0k1cbvm9cim NS DS RRSIG
+5QDO29Q2PS5ARBKHB6R0BRN6NDSTSN90.net. 86400 IN RRSIG NSEC3 8 2 86400 20190629054715 20190622043715 2129 net. fvRKJkn9D2H3DFGE0zpk/tAkyjaoEZY4 4TkN6XtCAibjzQS8R0SCaXmZlQQujnjG wp0Rjhy0gMQaFUrJ8QuUbJSDZQaicAl7 pCESVKd95GZOSgi07BXSKwdUMAPROSjz gDkYGzHcUB5Kfe23gkL2eQ05YVigHYhI l0YCHui1wHE=
+A1RT98BS5QGC9NFI51S9HCI47ULJG6JH.net. 86400 IN NSEC3 1 1 0 - a1ruuffjkct2q54p78f8ejgj8jbk7i8b NS SOA RRSIG DNSKEY NSEC3PARAM
+A1RT98BS5QGC9NFI51S9HCI47ULJG6JH.net. 86400 IN RRSIG NSEC3 8 2 86400 20190702055539 20190625044539 2129 net. KgEWjLXuYdPBhlNh2epfnKU879hg4GGf F4m4Fo7ZW+S3uhNqq8pF7sMJCvSs8ZZA Ctcm88XThCeIAxDxLZ5moOlMIWaweVX3 7B7s3mw+3K0cnkYF6J4FqBO8o7x6J3i2 c6kxI3q0DKub23GcXpWZu3x2yIkWuN0I ZgceikGAPpM=
+gtld-servers.net. 172800 IN NS av1.nstld.com.
+gtld-servers.net. 172800 IN NS av2.nstld.com.
+gtld-servers.net. 172800 IN NS av3.nstld.com.
+gtld-servers.net. 172800 IN NS av4.nstld.com.
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH subdomain
+ADJUST copy_id copy_query
+REPLY QR RD NOERROR
+SECTION QUESTION
+root-servers.net. IN NS
+SECTION AUTHORITY
+A1RT98BS5QGC9NFI51S9HCI47ULJG6JH.net. 86400 IN NSEC3 1 1 0 - a1ruuffjkct2q54p78f8ejgj8jbk7i8b NS SOA RRSIG DNSKEY NSEC3PARAM
+A1RT98BS5QGC9NFI51S9HCI47ULJG6JH.net. 86400 IN RRSIG NSEC3 8 2 86400 20190702055539 20190625044539 2129 net. KgEWjLXuYdPBhlNh2epfnKU879hg4GGf F4m4Fo7ZW+S3uhNqq8pF7sMJCvSs8ZZA Ctcm88XThCeIAxDxLZ5moOlMIWaweVX3 7B7s3mw+3K0cnkYF6J4FqBO8o7x6J3i2 c6kxI3q0DKub23GcXpWZu3x2yIkWuN0I ZgceikGAPpM=
+T2UF21DR03E0BNPB42UQMVUF38P2TA8D.net. 86400 IN NSEC3 1 1 0 - t2ukct9k5i0uhv7b3m3na6jaigdjm0gr NS DS RRSIG
+T2UF21DR03E0BNPB42UQMVUF38P2TA8D.net. 86400 IN RRSIG NSEC3 8 2 86400 20190630054523 20190623043523 2129 net. adpeQf+K6Hr5amhmF9DNK56LVWWnfGHK Dz9t9e7swG/P+4clc4yMKmUvK0OF9aTA kBzDwnzeB+FT+nsg1cWdibs4559AKQCL RtNErPhZRMojUFo6TLM9lQoXhv9i5rZB AJGmirHgSwiAvaUK7tgxX3nr1Atahyew iwHDQIVPhw4=
+root-servers.net. 172800 IN NS a.root-servers.net.
+root-servers.net. 172800 IN NS b.root-servers.net.
+root-servers.net. 172800 IN NS c.root-servers.net.
+root-servers.net. 172800 IN NS d.root-servers.net.
+root-servers.net. 172800 IN NS e.root-servers.net.
+root-servers.net. 172800 IN NS f.root-servers.net.
+root-servers.net. 172800 IN NS g.root-servers.net.
+root-servers.net. 172800 IN NS h.root-servers.net.
+root-servers.net. 172800 IN NS i.root-servers.net.
+root-servers.net. 172800 IN NS j.root-servers.net.
+root-servers.net. 172800 IN NS k.root-servers.net.
+root-servers.net. 172800 IN NS l.root-servers.net.
+root-servers.net. 172800 IN NS m.root-servers.net.
+SECTION ADDITIONAL
+a.root-servers.net. 172800 IN A 198.41.0.4
+a.root-servers.net. 172800 IN AAAA 2001:503:ba3e::2:30
+b.root-servers.net. 172800 IN A 199.9.14.201
+b.root-servers.net. 172800 IN AAAA 2001:500:200::b
+c.root-servers.net. 172800 IN A 192.33.4.12
+c.root-servers.net. 172800 IN AAAA 2001:500:2::c
+d.root-servers.net. 172800 IN A 199.7.91.13
+d.root-servers.net. 172800 IN AAAA 2001:500:2d::d
+e.root-servers.net. 172800 IN A 192.203.230.10
+e.root-servers.net. 172800 IN AAAA 2001:500:a8::e
+f.root-servers.net. 172800 IN A 192.5.5.241
+f.root-servers.net. 172800 IN AAAA 2001:500:2f::f
+g.root-servers.net. 172800 IN A 192.112.36.4
+g.root-servers.net. 172800 IN AAAA 2001:500:12::d0d
+h.root-servers.net. 172800 IN A 198.97.190.53
+h.root-servers.net. 172800 IN AAAA 2001:500:1::53
+i.root-servers.net. 172800 IN A 192.36.148.17
+i.root-servers.net. 172800 IN AAAA 2001:7fe::53
+j.root-servers.net. 172800 IN A 192.58.128.30
+j.root-servers.net. 172800 IN AAAA 2001:503:c27::2:30
+k.root-servers.net. 172800 IN A 193.0.14.129
+k.root-servers.net. 172800 IN AAAA 2001:7fd::1
+l.root-servers.net. 172800 IN A 199.7.83.42
+l.root-servers.net. 172800 IN AAAA 2001:500:9f::42
+m.root-servers.net. 172800 IN A 202.12.27.33
+m.root-servers.net. 172800 IN AAAA 2001:dc3::35
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH subdomain
+ADJUST copy_id copy_query
+REPLY QR RD NOERROR
+SECTION QUESTION
+nstld.com. IN NS
+SECTION AUTHORITY
+5V12UURISSGGLPAS52GE1V3R0V7KR5BS.com. 86400 IN NSEC3 1 1 0 - 5v13q049b9ittui4fbdtm34dtev47bgj NS DS RRSIG
+5V12UURISSGGLPAS52GE1V3R0V7KR5BS.com. 86400 IN RRSIG NSEC3 8 2 86400 20190630044250 20190623033250 3800 com. NlBOkX84YgGooJJ2vp+Z/O16Vkz6z1gC Jy1Va3fJyEXfZr/GIm8J3KJ6Eq+xxp1A x3ZWxwUjNH3TGUEme7pDrmusqRpx/TZF Za3dVAYIvsaVgIWtDCn4BLBPrg0HXcon HE60KLgWGQmezzFKrNsy5Tzz9TajUSgQ uOTQHB7TFDg=
+CK0POJMG874LJREF7EFN8430QVIT8BSM.com. 86400 IN NSEC3 1 1 0 - ck0q1gin43n1arrc9osm6qpqr81h5m9a NS SOA RRSIG DNSKEY NSEC3PARAM
+CK0POJMG874LJREF7EFN8430QVIT8BSM.com. 86400 IN RRSIG NSEC3 8 2 86400 20190702044530 20190625033530 3800 com. BMWhk6USUrb7TNJ3dSObn8QEPWvpzedW kP9i4RRPz7V9c2yVPmHSPt29QKsHOYTg iF4uyHt+K8RK8DBIziB19nrOjbb8iRDY 7m5koEj/OrS2peMuF6rqRRmkI6SY/ACy XHb/hRGE4tZd2gThNb7evZkk02IVuhEo njO3NBjCrsw=
+nstld.com. 172800 IN NS av1.nstld.com.
+nstld.com. 172800 IN NS av2.nstld.com.
+nstld.com. 172800 IN NS av3.nstld.com.
+nstld.com. 172800 IN NS av4.nstld.com.
+SECTION ADDITIONAL
+av1.nstld.com. 172800 IN A 192.42.177.30
+av1.nstld.com. 172800 IN AAAA 2001:500:124::30
+av2.nstld.com. 172800 IN A 192.42.178.30
+av2.nstld.com. 172800 IN AAAA 2001:500:125::30
+av3.nstld.com. 172800 IN A 192.82.133.30
+av3.nstld.com. 172800 IN AAAA 2001:500:126::30
+av4.nstld.com. 172800 IN A 192.82.134.30
+av4.nstld.com. 172800 IN AAAA 2001:500:127::30
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH subdomain
+ADJUST copy_id copy_query
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+net. IN NS
+SECTION ANSWER
+net. 172800 IN NS a.gtld-servers.net.
+net. 172800 IN NS b.gtld-servers.net.
+net. 172800 IN NS c.gtld-servers.net.
+net. 172800 IN NS d.gtld-servers.net.
+net. 172800 IN NS e.gtld-servers.net.
+net. 172800 IN NS f.gtld-servers.net.
+net. 172800 IN NS g.gtld-servers.net.
+net. 172800 IN NS h.gtld-servers.net.
+net. 172800 IN NS i.gtld-servers.net.
+net. 172800 IN NS j.gtld-servers.net.
+net. 172800 IN NS k.gtld-servers.net.
+net. 172800 IN NS l.gtld-servers.net.
+net. 172800 IN NS m.gtld-servers.net.
+net. 172800 IN RRSIG NS 8 1 172800 20190630055417 20190623044417 2129 net. WUAzfzoslC7YpzfY7qJ+vPaYpL/TN1fq Ak97qaEsQbPEka9AfUyL/ZKgGucOrDmB e0GK55jGT1B1XXiQasdlB8/SThSPm+Oc V/aQ8zUopPJ6gzCCRfEZOWCRvRbXa3am f6apMdig+NSxXgYQpVjZmka8XX8xDJar 3c4G5gZS9rA=
+SECTION ADDITIONAL
+a.gtld-servers.net. 172800 IN A 192.5.6.30
+a.gtld-servers.net. 172800 IN AAAA 2001:503:a83e::2:30
+b.gtld-servers.net. 172800 IN A 192.33.14.30
+b.gtld-servers.net. 172800 IN AAAA 2001:503:231d::2:30
+c.gtld-servers.net. 172800 IN A 192.26.92.30
+c.gtld-servers.net. 172800 IN AAAA 2001:503:83eb::30
+d.gtld-servers.net. 172800 IN A 192.31.80.30
+d.gtld-servers.net. 172800 IN AAAA 2001:500:856e::30
+e.gtld-servers.net. 172800 IN A 192.12.94.30
+e.gtld-servers.net. 172800 IN AAAA 2001:502:1ca1::30
+f.gtld-servers.net. 172800 IN A 192.35.51.30
+f.gtld-servers.net. 172800 IN AAAA 2001:503:d414::30
+g.gtld-servers.net. 172800 IN A 192.42.93.30
+g.gtld-servers.net. 172800 IN AAAA 2001:503:eea3::30
+h.gtld-servers.net. 172800 IN A 192.54.112.30
+h.gtld-servers.net. 172800 IN AAAA 2001:502:8cc::30
+i.gtld-servers.net. 172800 IN A 192.43.172.30
+i.gtld-servers.net. 172800 IN AAAA 2001:503:39c1::30
+j.gtld-servers.net. 172800 IN A 192.48.79.30
+j.gtld-servers.net. 172800 IN AAAA 2001:502:7094::30
+k.gtld-servers.net. 172800 IN A 192.52.178.30
+k.gtld-servers.net. 172800 IN AAAA 2001:503:d2d::30
+l.gtld-servers.net. 172800 IN A 192.41.162.30
+l.gtld-servers.net. 172800 IN AAAA 2001:500:d937::30
+m.gtld-servers.net. 172800 IN A 192.55.83.30
+m.gtld-servers.net. 172800 IN AAAA 2001:501:b1f9::30
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH subdomain
+ADJUST copy_id copy_query
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. 172800 IN NS a.gtld-servers.net.
+com. 172800 IN NS b.gtld-servers.net.
+com. 172800 IN NS c.gtld-servers.net.
+com. 172800 IN NS d.gtld-servers.net.
+com. 172800 IN NS e.gtld-servers.net.
+com. 172800 IN NS f.gtld-servers.net.
+com. 172800 IN NS g.gtld-servers.net.
+com. 172800 IN NS h.gtld-servers.net.
+com. 172800 IN NS i.gtld-servers.net.
+com. 172800 IN NS j.gtld-servers.net.
+com. 172800 IN NS k.gtld-servers.net.
+com. 172800 IN NS l.gtld-servers.net.
+com. 172800 IN NS m.gtld-servers.net.
+com. 172800 IN RRSIG NS 8 1 172800 20190702044530 20190625033530 3800 com. F4MEGl13z9h8iv22sko8S8/JjSskipqt COrmfpx4p5XeRutUOpr/6wAEdSXWJ7yu 5Z/PMTBDjTo37WxfEhyvvYyiOLTzYOf+ AvFeeGDAxdOAlfjQ+6etggDPz1bsqIhE 2FX5i7dhfk0WYshBIUqCJmmPMdnVgLNN Bh4zYoT5irQ=
+SECTION ADDITIONAL
+a.gtld-servers.net. 172800 IN A 192.5.6.30
+a.gtld-servers.net. 172800 IN AAAA 2001:503:a83e::2:30
+b.gtld-servers.net. 172800 IN A 192.33.14.30
+b.gtld-servers.net. 172800 IN AAAA 2001:503:231d::2:30
+c.gtld-servers.net. 172800 IN A 192.26.92.30
+c.gtld-servers.net. 172800 IN AAAA 2001:503:83eb::30
+d.gtld-servers.net. 172800 IN A 192.31.80.30
+d.gtld-servers.net. 172800 IN AAAA 2001:500:856e::30
+e.gtld-servers.net. 172800 IN A 192.12.94.30
+e.gtld-servers.net. 172800 IN AAAA 2001:502:1ca1::30
+f.gtld-servers.net. 172800 IN A 192.35.51.30
+f.gtld-servers.net. 172800 IN AAAA 2001:503:d414::30
+g.gtld-servers.net. 172800 IN A 192.42.93.30
+g.gtld-servers.net. 172800 IN AAAA 2001:503:eea3::30
+h.gtld-servers.net. 172800 IN A 192.54.112.30
+h.gtld-servers.net. 172800 IN AAAA 2001:502:8cc::30
+i.gtld-servers.net. 172800 IN A 192.43.172.30
+i.gtld-servers.net. 172800 IN AAAA 2001:503:39c1::30
+j.gtld-servers.net. 172800 IN A 192.48.79.30
+j.gtld-servers.net. 172800 IN AAAA 2001:502:7094::30
+k.gtld-servers.net. 172800 IN A 192.52.178.30
+k.gtld-servers.net. 172800 IN AAAA 2001:503:d2d::30
+l.gtld-servers.net. 172800 IN A 192.41.162.30
+l.gtld-servers.net. 172800 IN AAAA 2001:500:d937::30
+m.gtld-servers.net. 172800 IN A 192.55.83.30
+m.gtld-servers.net. 172800 IN AAAA 2001:501:b1f9::30
+ENTRY_END
+
+
+
+
+RANGE_END
+
+
+
+; Group's zones:
+; gtld-servers.net.
+; nstld.com.
+; Server names:
+; av1.nstld.com.
+; av2.nstld.com.
+; av3.nstld.com.
+; av4.nstld.com.
+RANGE_BEGIN 0 1000
+ ADDRESS 192.42.178.30
+ ADDRESS 2001:500:125::30
+ ADDRESS 192.82.133.30
+ ADDRESS 192.42.177.30
+ ADDRESS 2001:500:124::30
+ ADDRESS 192.82.134.30
+ ADDRESS 2001:500:126::30
+ ADDRESS 2001:500:127::30
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+h.gtld-servers.net. IN A
+SECTION ANSWER
+h.gtld-servers.net. 86400 IN A 192.54.112.30
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN NS av1.nstld.com.
+gtld-servers.net. 86400 IN NS av2.nstld.com.
+gtld-servers.net. 86400 IN NS av3.nstld.com.
+gtld-servers.net. 86400 IN NS av4.nstld.com.
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+i.gtld-servers.net. IN AAAA
+SECTION ANSWER
+i.gtld-servers.net. 86400 IN AAAA 2001:503:39c1::30
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN NS av1.nstld.com.
+gtld-servers.net. 86400 IN NS av2.nstld.com.
+gtld-servers.net. 86400 IN NS av3.nstld.com.
+gtld-servers.net. 86400 IN NS av4.nstld.com.
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+av3.nstld.com. IN A
+SECTION ANSWER
+av3.nstld.com. 300 IN A 192.82.133.30
+SECTION AUTHORITY
+nstld.com. 86400 IN NS av1.nstld.com.
+nstld.com. 86400 IN NS av2.nstld.com.
+nstld.com. 86400 IN NS av3.nstld.com.
+nstld.com. 86400 IN NS av4.nstld.com.
+SECTION ADDITIONAL
+av1.nstld.com. 300 IN A 192.42.177.30
+av1.nstld.com. 300 IN AAAA 2001:500:124::30
+av2.nstld.com. 300 IN A 192.42.178.30
+av2.nstld.com. 300 IN AAAA 2001:500:125::30
+av3.nstld.com. 300 IN AAAA 2001:500:126::30
+av4.nstld.com. 300 IN A 192.82.134.30
+av4.nstld.com. 300 IN AAAA 2001:500:127::30
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+av1.nstld.com. IN A
+SECTION ANSWER
+av1.nstld.com. 300 IN A 192.42.177.30
+SECTION AUTHORITY
+nstld.com. 86400 IN NS av1.nstld.com.
+nstld.com. 86400 IN NS av2.nstld.com.
+nstld.com. 86400 IN NS av3.nstld.com.
+nstld.com. 86400 IN NS av4.nstld.com.
+SECTION ADDITIONAL
+av1.nstld.com. 300 IN AAAA 2001:500:124::30
+av2.nstld.com. 300 IN A 192.42.178.30
+av2.nstld.com. 300 IN AAAA 2001:500:125::30
+av3.nstld.com. 300 IN A 192.82.133.30
+av3.nstld.com. 300 IN AAAA 2001:500:126::30
+av4.nstld.com. 300 IN A 192.82.134.30
+av4.nstld.com. 300 IN AAAA 2001:500:127::30
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+j.gtld-servers.net. IN AAAA
+SECTION ANSWER
+j.gtld-servers.net. 86400 IN AAAA 2001:502:7094::30
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN NS av1.nstld.com.
+gtld-servers.net. 86400 IN NS av2.nstld.com.
+gtld-servers.net. 86400 IN NS av3.nstld.com.
+gtld-servers.net. 86400 IN NS av4.nstld.com.
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+av2.nstld.com. IN AAAA
+SECTION ANSWER
+av2.nstld.com. 300 IN AAAA 2001:500:125::30
+SECTION AUTHORITY
+nstld.com. 86400 IN NS av1.nstld.com.
+nstld.com. 86400 IN NS av2.nstld.com.
+nstld.com. 86400 IN NS av3.nstld.com.
+nstld.com. 86400 IN NS av4.nstld.com.
+SECTION ADDITIONAL
+av1.nstld.com. 300 IN A 192.42.177.30
+av1.nstld.com. 300 IN AAAA 2001:500:124::30
+av2.nstld.com. 300 IN A 192.42.178.30
+av3.nstld.com. 300 IN A 192.82.133.30
+av3.nstld.com. 300 IN AAAA 2001:500:126::30
+av4.nstld.com. 300 IN A 192.82.134.30
+av4.nstld.com. 300 IN AAAA 2001:500:127::30
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+k.gtld-servers.net. IN AAAA
+SECTION ANSWER
+k.gtld-servers.net. 86400 IN AAAA 2001:503:d2d::30
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN NS av1.nstld.com.
+gtld-servers.net. 86400 IN NS av2.nstld.com.
+gtld-servers.net. 86400 IN NS av3.nstld.com.
+gtld-servers.net. 86400 IN NS av4.nstld.com.
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+av1.nstld.com. IN NS
+SECTION AUTHORITY
+nstld.com. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2018073100 7200 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+f.gtld-servers.net. IN AAAA
+SECTION ANSWER
+f.gtld-servers.net. 86400 IN AAAA 2001:503:d414::30
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN NS av1.nstld.com.
+gtld-servers.net. 86400 IN NS av2.nstld.com.
+gtld-servers.net. 86400 IN NS av3.nstld.com.
+gtld-servers.net. 86400 IN NS av4.nstld.com.
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+j.gtld-servers.net. IN NS
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+c.gtld-servers.net. IN NS
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+l.gtld-servers.net. IN AAAA
+SECTION ANSWER
+l.gtld-servers.net. 86400 IN AAAA 2001:500:d937::30
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN NS av1.nstld.com.
+gtld-servers.net. 86400 IN NS av2.nstld.com.
+gtld-servers.net. 86400 IN NS av3.nstld.com.
+gtld-servers.net. 86400 IN NS av4.nstld.com.
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+b.gtld-servers.net. IN NS
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+f.gtld-servers.net. IN A
+SECTION ANSWER
+f.gtld-servers.net. 86400 IN A 192.35.51.30
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN NS av1.nstld.com.
+gtld-servers.net. 86400 IN NS av2.nstld.com.
+gtld-servers.net. 86400 IN NS av3.nstld.com.
+gtld-servers.net. 86400 IN NS av4.nstld.com.
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+e.gtld-servers.net. IN NS
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+i.gtld-servers.net. IN A
+SECTION ANSWER
+i.gtld-servers.net. 86400 IN A 192.43.172.30
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN NS av1.nstld.com.
+gtld-servers.net. 86400 IN NS av2.nstld.com.
+gtld-servers.net. 86400 IN NS av3.nstld.com.
+gtld-servers.net. 86400 IN NS av4.nstld.com.
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+d.gtld-servers.net. IN AAAA
+SECTION ANSWER
+d.gtld-servers.net. 86400 IN AAAA 2001:500:856e::30
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN NS av1.nstld.com.
+gtld-servers.net. 86400 IN NS av2.nstld.com.
+gtld-servers.net. 86400 IN NS av3.nstld.com.
+gtld-servers.net. 86400 IN NS av4.nstld.com.
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+m.gtld-servers.net. IN NS
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+av3.nstld.com. IN NS
+SECTION AUTHORITY
+nstld.com. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2018073100 7200 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+g.gtld-servers.net. IN A
+SECTION ANSWER
+g.gtld-servers.net. 86400 IN A 192.42.93.30
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN NS av1.nstld.com.
+gtld-servers.net. 86400 IN NS av2.nstld.com.
+gtld-servers.net. 86400 IN NS av3.nstld.com.
+gtld-servers.net. 86400 IN NS av4.nstld.com.
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+j.gtld-servers.net. IN A
+SECTION ANSWER
+j.gtld-servers.net. 86400 IN A 192.48.79.30
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN NS av1.nstld.com.
+gtld-servers.net. 86400 IN NS av2.nstld.com.
+gtld-servers.net. 86400 IN NS av3.nstld.com.
+gtld-servers.net. 86400 IN NS av4.nstld.com.
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+f.gtld-servers.net. IN NS
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+av2.nstld.com. IN NS
+SECTION AUTHORITY
+nstld.com. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2018073100 7200 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+h.gtld-servers.net. IN NS
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+d.gtld-servers.net. IN NS
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+av1.nstld.com. IN AAAA
+SECTION ANSWER
+av1.nstld.com. 300 IN AAAA 2001:500:124::30
+SECTION AUTHORITY
+nstld.com. 86400 IN NS av1.nstld.com.
+nstld.com. 86400 IN NS av2.nstld.com.
+nstld.com. 86400 IN NS av3.nstld.com.
+nstld.com. 86400 IN NS av4.nstld.com.
+SECTION ADDITIONAL
+av1.nstld.com. 300 IN A 192.42.177.30
+av2.nstld.com. 300 IN A 192.42.178.30
+av2.nstld.com. 300 IN AAAA 2001:500:125::30
+av3.nstld.com. 300 IN A 192.82.133.30
+av3.nstld.com. 300 IN AAAA 2001:500:126::30
+av4.nstld.com. 300 IN A 192.82.134.30
+av4.nstld.com. 300 IN AAAA 2001:500:127::30
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+k.gtld-servers.net. IN A
+SECTION ANSWER
+k.gtld-servers.net. 86400 IN A 192.52.178.30
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN NS av1.nstld.com.
+gtld-servers.net. 86400 IN NS av2.nstld.com.
+gtld-servers.net. 86400 IN NS av3.nstld.com.
+gtld-servers.net. 86400 IN NS av4.nstld.com.
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+h.gtld-servers.net. IN AAAA
+SECTION ANSWER
+h.gtld-servers.net. 86400 IN AAAA 2001:502:8cc::30
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN NS av1.nstld.com.
+gtld-servers.net. 86400 IN NS av2.nstld.com.
+gtld-servers.net. 86400 IN NS av3.nstld.com.
+gtld-servers.net. 86400 IN NS av4.nstld.com.
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+a.gtld-servers.net. IN AAAA
+SECTION ANSWER
+a.gtld-servers.net. 86400 IN AAAA 2001:503:a83e::2:30
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN NS av1.nstld.com.
+gtld-servers.net. 86400 IN NS av2.nstld.com.
+gtld-servers.net. 86400 IN NS av3.nstld.com.
+gtld-servers.net. 86400 IN NS av4.nstld.com.
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+l.gtld-servers.net. IN NS
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+b.gtld-servers.net. IN AAAA
+SECTION ANSWER
+b.gtld-servers.net. 86400 IN AAAA 2001:503:231d::2:30
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN NS av1.nstld.com.
+gtld-servers.net. 86400 IN NS av2.nstld.com.
+gtld-servers.net. 86400 IN NS av3.nstld.com.
+gtld-servers.net. 86400 IN NS av4.nstld.com.
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+l.gtld-servers.net. IN A
+SECTION ANSWER
+l.gtld-servers.net. 86400 IN A 192.41.162.30
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN NS av1.nstld.com.
+gtld-servers.net. 86400 IN NS av2.nstld.com.
+gtld-servers.net. 86400 IN NS av3.nstld.com.
+gtld-servers.net. 86400 IN NS av4.nstld.com.
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+d.gtld-servers.net. IN A
+SECTION ANSWER
+d.gtld-servers.net. 86400 IN A 192.31.80.30
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN NS av1.nstld.com.
+gtld-servers.net. 86400 IN NS av2.nstld.com.
+gtld-servers.net. 86400 IN NS av3.nstld.com.
+gtld-servers.net. 86400 IN NS av4.nstld.com.
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+e.gtld-servers.net. IN AAAA
+SECTION ANSWER
+e.gtld-servers.net. 86400 IN AAAA 2001:502:1ca1::30
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN NS av1.nstld.com.
+gtld-servers.net. 86400 IN NS av2.nstld.com.
+gtld-servers.net. 86400 IN NS av3.nstld.com.
+gtld-servers.net. 86400 IN NS av4.nstld.com.
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+k.gtld-servers.net. IN NS
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+av3.nstld.com. IN AAAA
+SECTION ANSWER
+av3.nstld.com. 300 IN AAAA 2001:500:126::30
+SECTION AUTHORITY
+nstld.com. 86400 IN NS av1.nstld.com.
+nstld.com. 86400 IN NS av2.nstld.com.
+nstld.com. 86400 IN NS av3.nstld.com.
+nstld.com. 86400 IN NS av4.nstld.com.
+SECTION ADDITIONAL
+av1.nstld.com. 300 IN A 192.42.177.30
+av1.nstld.com. 300 IN AAAA 2001:500:124::30
+av2.nstld.com. 300 IN A 192.42.178.30
+av2.nstld.com. 300 IN AAAA 2001:500:125::30
+av3.nstld.com. 300 IN A 192.82.133.30
+av4.nstld.com. 300 IN A 192.82.134.30
+av4.nstld.com. 300 IN AAAA 2001:500:127::30
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+a.gtld-servers.net. IN A
+SECTION ANSWER
+a.gtld-servers.net. 86400 IN A 192.5.6.30
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN NS av1.nstld.com.
+gtld-servers.net. 86400 IN NS av2.nstld.com.
+gtld-servers.net. 86400 IN NS av3.nstld.com.
+gtld-servers.net. 86400 IN NS av4.nstld.com.
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+av4.nstld.com. IN AAAA
+SECTION ANSWER
+av4.nstld.com. 300 IN AAAA 2001:500:127::30
+SECTION AUTHORITY
+nstld.com. 86400 IN NS av1.nstld.com.
+nstld.com. 86400 IN NS av2.nstld.com.
+nstld.com. 86400 IN NS av3.nstld.com.
+nstld.com. 86400 IN NS av4.nstld.com.
+SECTION ADDITIONAL
+av1.nstld.com. 300 IN A 192.42.177.30
+av1.nstld.com. 300 IN AAAA 2001:500:124::30
+av2.nstld.com. 300 IN A 192.42.178.30
+av2.nstld.com. 300 IN AAAA 2001:500:125::30
+av3.nstld.com. 300 IN A 192.82.133.30
+av3.nstld.com. 300 IN AAAA 2001:500:126::30
+av4.nstld.com. 300 IN A 192.82.134.30
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+g.gtld-servers.net. IN AAAA
+SECTION ANSWER
+g.gtld-servers.net. 86400 IN AAAA 2001:503:eea3::30
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN NS av1.nstld.com.
+gtld-servers.net. 86400 IN NS av2.nstld.com.
+gtld-servers.net. 86400 IN NS av3.nstld.com.
+gtld-servers.net. 86400 IN NS av4.nstld.com.
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+c.gtld-servers.net. IN A
+SECTION ANSWER
+c.gtld-servers.net. 86400 IN A 192.26.92.30
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN NS av1.nstld.com.
+gtld-servers.net. 86400 IN NS av2.nstld.com.
+gtld-servers.net. 86400 IN NS av3.nstld.com.
+gtld-servers.net. 86400 IN NS av4.nstld.com.
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+av4.nstld.com. IN NS
+SECTION AUTHORITY
+nstld.com. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2018073100 7200 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+a.gtld-servers.net. IN NS
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+m.gtld-servers.net. IN AAAA
+SECTION ANSWER
+m.gtld-servers.net. 86400 IN AAAA 2001:501:b1f9::30
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN NS av1.nstld.com.
+gtld-servers.net. 86400 IN NS av2.nstld.com.
+gtld-servers.net. 86400 IN NS av3.nstld.com.
+gtld-servers.net. 86400 IN NS av4.nstld.com.
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+m.gtld-servers.net. IN A
+SECTION ANSWER
+m.gtld-servers.net. 86400 IN A 192.55.83.30
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN NS av1.nstld.com.
+gtld-servers.net. 86400 IN NS av2.nstld.com.
+gtld-servers.net. 86400 IN NS av3.nstld.com.
+gtld-servers.net. 86400 IN NS av4.nstld.com.
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+i.gtld-servers.net. IN NS
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+g.gtld-servers.net. IN NS
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+c.gtld-servers.net. IN AAAA
+SECTION ANSWER
+c.gtld-servers.net. 86400 IN AAAA 2001:503:83eb::30
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN NS av1.nstld.com.
+gtld-servers.net. 86400 IN NS av2.nstld.com.
+gtld-servers.net. 86400 IN NS av3.nstld.com.
+gtld-servers.net. 86400 IN NS av4.nstld.com.
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+av2.nstld.com. IN A
+SECTION ANSWER
+av2.nstld.com. 300 IN A 192.42.178.30
+SECTION AUTHORITY
+nstld.com. 86400 IN NS av1.nstld.com.
+nstld.com. 86400 IN NS av2.nstld.com.
+nstld.com. 86400 IN NS av3.nstld.com.
+nstld.com. 86400 IN NS av4.nstld.com.
+SECTION ADDITIONAL
+av1.nstld.com. 300 IN A 192.42.177.30
+av1.nstld.com. 300 IN AAAA 2001:500:124::30
+av2.nstld.com. 300 IN AAAA 2001:500:125::30
+av3.nstld.com. 300 IN A 192.82.133.30
+av3.nstld.com. 300 IN AAAA 2001:500:126::30
+av4.nstld.com. 300 IN A 192.82.134.30
+av4.nstld.com. 300 IN AAAA 2001:500:127::30
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+av4.nstld.com. IN A
+SECTION ANSWER
+av4.nstld.com. 300 IN A 192.82.134.30
+SECTION AUTHORITY
+nstld.com. 86400 IN NS av1.nstld.com.
+nstld.com. 86400 IN NS av2.nstld.com.
+nstld.com. 86400 IN NS av3.nstld.com.
+nstld.com. 86400 IN NS av4.nstld.com.
+SECTION ADDITIONAL
+av1.nstld.com. 300 IN A 192.42.177.30
+av1.nstld.com. 300 IN AAAA 2001:500:124::30
+av2.nstld.com. 300 IN A 192.42.178.30
+av2.nstld.com. 300 IN AAAA 2001:500:125::30
+av3.nstld.com. 300 IN A 192.82.133.30
+av3.nstld.com. 300 IN AAAA 2001:500:126::30
+av4.nstld.com. 300 IN AAAA 2001:500:127::30
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+b.gtld-servers.net. IN A
+SECTION ANSWER
+b.gtld-servers.net. 86400 IN A 192.33.14.30
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN NS av1.nstld.com.
+gtld-servers.net. 86400 IN NS av2.nstld.com.
+gtld-servers.net. 86400 IN NS av3.nstld.com.
+gtld-servers.net. 86400 IN NS av4.nstld.com.
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+e.gtld-servers.net. IN A
+SECTION ANSWER
+e.gtld-servers.net. 86400 IN A 192.12.94.30
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN NS av1.nstld.com.
+gtld-servers.net. 86400 IN NS av2.nstld.com.
+gtld-servers.net. 86400 IN NS av3.nstld.com.
+gtld-servers.net. 86400 IN NS av4.nstld.com.
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH subdomain
+ADJUST copy_id copy_query
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+gtld-servers.net. IN NS
+SECTION ANSWER
+gtld-servers.net. 86400 IN NS av1.nstld.com.
+gtld-servers.net. 86400 IN NS av2.nstld.com.
+gtld-servers.net. 86400 IN NS av3.nstld.com.
+gtld-servers.net. 86400 IN NS av4.nstld.com.
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH subdomain
+ADJUST copy_id copy_query
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+nstld.com. IN NS
+SECTION ANSWER
+nstld.com. 86400 IN NS av1.nstld.com.
+nstld.com. 86400 IN NS av2.nstld.com.
+nstld.com. 86400 IN NS av3.nstld.com.
+nstld.com. 86400 IN NS av4.nstld.com.
+SECTION ADDITIONAL
+av1.nstld.com. 300 IN A 192.42.177.30
+av1.nstld.com. 300 IN AAAA 2001:500:124::30
+av2.nstld.com. 300 IN A 192.42.178.30
+av2.nstld.com. 300 IN AAAA 2001:500:125::30
+av3.nstld.com. 300 IN A 192.82.133.30
+av3.nstld.com. 300 IN AAAA 2001:500:126::30
+av4.nstld.com. 300 IN A 192.82.134.30
+av4.nstld.com. 300 IN AAAA 2001:500:127::30
+ENTRY_END
+
+
+
+
+RANGE_END
+
+
+
+
+
+; Sequence of queries made by browser
+
+; 1st query for AAAA
+STEP 10 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+csas.cz. IN AAAA
+ENTRY_END
+
+; answer for AAAA contains minimally covering NSEC3 answer with incorrect bitmap
+; it claims that csas.cz A RR is not present
+STEP 11 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH opcode flags rcode question answer
+REPLY QR RD RA AD NOERROR
+SECTION QUESTION
+csas.cz. IN AAAA
+SECTION AUTHORITY
+csas.cz. 119 IN SOA ddnsa.csas.cz. domainservices.csas.cz. 2019061320 28800 1800 2592000 120
+ENTRY_END
+
+; 2nd query for A
+STEP 21 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+csas.cz. IN A
+ENTRY_END
+
+; check that A query gets an IP address
+; this answer would be empty
+; if minimally covering NSEC3 was not exempt from aggressive caching
+STEP 22 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH opcode flags rcode question answer
+REPLY QR RD RA AD NOERROR
+SECTION QUESTION
+csas.cz. IN A
+SECTION ANSWER
+csas.cz. 120 IN A 194.50.240.198
+csas.cz. 120 IN A 194.50.240.70
+ENTRY_END
+
+SCENARIO_END
diff --git a/lib/cache/test.integr/deckard.yaml b/lib/cache/test.integr/deckard.yaml
new file mode 100644
index 0000000..df88f83
--- /dev/null
+++ b/lib/cache/test.integr/deckard.yaml
@@ -0,0 +1,13 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+programs:
+- name: kresd
+ binary: kresd
+ additional:
+ - --noninteractive
+ templates:
+ - lib/cache/test.integr/kresd_config.j2
+ - tests/integration/hints_zone.j2
+ configs:
+ - config
+ - hints
+noclean: True
diff --git a/lib/cache/test.integr/kresd_config.j2 b/lib/cache/test.integr/kresd_config.j2
new file mode 100644
index 0000000..c4c286f
--- /dev/null
+++ b/lib/cache/test.integr/kresd_config.j2
@@ -0,0 +1,69 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+{% for TAF in TRUST_ANCHOR_FILES %}
+-- trust_anchors.add_file('{{TAF}}')
+{% endfor %}
+
+{% raw %}
+-- Disable RFC5011 TA update
+if ta_update then
+ modules.unload('ta_update')
+end
+
+-- Disable RFC8145 signaling, scenario doesn't provide expected answers
+if ta_signal_query then
+ modules.unload('ta_signal_query')
+end
+
+-- Disable RFC8109 priming, scenario doesn't provide expected answers
+if priming then
+ modules.unload('priming')
+end
+
+-- Disable this module because it make one priming query
+if detect_time_skew then
+ modules.unload('detect_time_skew')
+end
+
+_hint_root_file('hints')
+cache.size = 2*MB
+log_level('debug')
+policy.add(policy.all(policy.DEBUG_ALWAYS))
+{% endraw %}
+
+net = { '{{SELF_ADDR}}' }
+
+{% if DO_IP6 == "true" %}
+net.ipv6 = true
+{% else %}
+net.ipv6 = false
+{% endif %}
+
+{% if DO_IP4 == "true" %}
+net.ipv4 = true
+{% else %}
+net.ipv4 = false
+{% endif %}
+
+{% if QMIN == "false" %}
+option('NO_MINIMIZE', true)
+{% else %}
+option('NO_MINIMIZE', false)
+{% endif %}
+
+
+-- Self-checks on globals
+assert(help() ~= nil)
+assert(worker.id ~= nil)
+-- Self-checks on facilities
+assert(cache.count() == 0)
+assert(cache.stats() ~= nil)
+assert(cache.backends() ~= nil)
+assert(worker.stats() ~= nil)
+assert(net.interfaces() ~= nil)
+-- Self-checks on loaded stuff
+assert(net.list()[1].transport.ip == '{{SELF_ADDR}}')
+assert(#modules.list() > 0)
+-- Self-check timers
+ev = event.recurrent(1 * sec, function (ev) return 1 end)
+event.cancel(ev)
+ev = event.after(0, function (ev) return 1 end)
diff --git a/lib/cache/util.h b/lib/cache/util.h
new file mode 100644
index 0000000..3f81830
--- /dev/null
+++ b/lib/cache/util.h
@@ -0,0 +1,4 @@
+/* SPDX-License-Identifier: GPL-3.0-or-later */
+#include <libknot/packet/pkt.h>
+
+uint32_t packet_ttl(const knot_pkt_t *pkt);
diff --git a/lib/cookies/alg_containers.c b/lib/cookies/alg_containers.c
new file mode 100644
index 0000000..1da0bda
--- /dev/null
+++ b/lib/cookies/alg_containers.c
@@ -0,0 +1,59 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#include <stdint.h>
+#include <stdlib.h>
+
+#include <libknot/cookies/alg-fnv64.h>
+
+#include "lib/cookies/alg_containers.h"
+#include "lib/cookies/alg_sha.h"
+
+const struct knot_cc_alg *kr_cc_alg_get(int id)
+{
+ /*
+ * Client algorithm identifiers are used to index this array of
+ * pointers.
+ */
+ static const struct knot_cc_alg *const cc_algs[] = {
+ /* 0 */ &knot_cc_alg_fnv64,
+ /* 1 */ &knot_cc_alg_hmac_sha256_64
+ };
+
+ if (id >= 0 && id < 2) {
+ return cc_algs[id];
+ }
+
+ return NULL;
+}
+
+const knot_lookup_t kr_cc_alg_names[] = {
+ { 0, "FNV-64" },
+ { 1, "HMAC-SHA256-64" },
+ { -1, NULL }
+};
+
+const struct knot_sc_alg *kr_sc_alg_get(int id)
+{
+ /*
+ * Server algorithm identifiers are used to index this array of
+ * pointers.
+ */
+ static const struct knot_sc_alg *const sc_algs[] = {
+ /* 0 */ &knot_sc_alg_fnv64,
+ /* 1 */ &knot_sc_alg_hmac_sha256_64
+ };
+
+ if (id >= 0 && id < 2) {
+ return sc_algs[id];
+ }
+
+ return NULL;
+}
+
+const knot_lookup_t kr_sc_alg_names[] = {
+ { 0, "FNV-64" },
+ { 1, "HMAC-SHA256-64" },
+ { -1, NULL }
+};
diff --git a/lib/cookies/alg_containers.h b/lib/cookies/alg_containers.h
new file mode 100644
index 0000000..5764c28
--- /dev/null
+++ b/lib/cookies/alg_containers.h
@@ -0,0 +1,37 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#include <libknot/cookies/client.h>
+#include <libknot/cookies/server.h>
+#include <libknot/lookup.h>
+
+#include "lib/defines.h"
+
+/**
+ * @brief Returns pointer to client cookie algorithm.
+ *
+ * @param id algorithm identifier as defined by lookup table
+ * @return pointer to algorithm structure with given id or NULL on error
+ */
+KR_EXPORT
+const struct knot_cc_alg *kr_cc_alg_get(int id);
+
+/** Binds client algorithm identifiers onto names. */
+KR_EXPORT
+extern const knot_lookup_t kr_cc_alg_names[];
+
+/**
+ * @brief Returns pointer to server cookie algorithm.
+ *
+ * @param id algorithm identifier as defined by lookup table
+ * @return pointer to algorithm structure with given id or NULL on error
+ */
+KR_EXPORT
+const struct knot_sc_alg *kr_sc_alg_get(int id);
+
+/** Binds server algorithm identifiers onto names. */
+KR_EXPORT
+extern const knot_lookup_t kr_sc_alg_names[];
diff --git a/lib/cookies/alg_sha.c b/lib/cookies/alg_sha.c
new file mode 100644
index 0000000..34e79c3
--- /dev/null
+++ b/lib/cookies/alg_sha.c
@@ -0,0 +1,110 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#include <nettle/hmac.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+#include <libknot/errcode.h>
+#include <libknot/rrtype/opt-cookie.h>
+
+#include "lib/cookies/alg_sha.h"
+#include "lib/utils.h"
+
+/**
+ * @brief Update hash value.
+ *
+ * @param ctx HMAC-SHA256 context to be updated.
+ * @param sa Socket address.
+ */
+static inline void update_hash(struct hmac_sha256_ctx *ctx,
+ const struct sockaddr *sa)
+{
+ if (kr_fails_assert(ctx && sa))
+ return;
+
+ int addr_len = kr_inaddr_len(sa);
+ const uint8_t *addr = (uint8_t *)kr_inaddr(sa);
+
+ if (addr && addr_len > 0) {
+ hmac_sha256_update(ctx, addr_len, addr);
+ }
+}
+
+/**
+ * @brief Compute client cookie using HMAC-SHA256-64.
+ * @note At least one of the arguments must be non-null.
+ * @param input input parameters
+ * @param cc_out buffer for computed client cookie
+ * @param cc_len buffer size
+ * @return Non-zero size of written data on success, 0 in case of a failure.
+ */
+static uint16_t cc_gen_hmac_sha256_64(const struct knot_cc_input *input,
+ uint8_t *cc_out, uint16_t cc_len)
+{
+ if (!knot_cc_input_is_valid(input) ||
+ !cc_out || cc_len < KNOT_OPT_COOKIE_CLNT) {
+ return 0;
+ }
+
+ struct hmac_sha256_ctx ctx;
+ hmac_sha256_set_key(&ctx, input->secret_len, input->secret_data);
+
+ if (input->clnt_sockaddr) {
+ update_hash(&ctx, input->clnt_sockaddr);
+ }
+
+ if (input->srvr_sockaddr) {
+ update_hash(&ctx, input->srvr_sockaddr);
+ }
+
+ /* KNOT_OPT_COOKIE_CLNT <= SHA256_DIGEST_SIZE */
+
+ hmac_sha256_digest(&ctx, KNOT_OPT_COOKIE_CLNT, cc_out);
+
+ return KNOT_OPT_COOKIE_CLNT;
+}
+
+#define SRVR_HMAC_SHA256_64_HASH_SIZE 8
+
+/**
+ * @brief Compute server cookie hash using HMAC-SHA256-64).
+ * @note Server cookie = nonce | time | HMAC-SHA256-64( server secret, client cookie | nonce| time | client IP )
+ * @param input data to compute cookie from
+ * @param hash_out hash output buffer
+ * @param hash_len buffer size
+ * @return Non-zero size of written data on success, 0 in case of a failure.
+ */
+static uint16_t sc_gen_hmac_sha256_64(const struct knot_sc_input *input,
+ uint8_t *hash_out, uint16_t hash_len)
+{
+ if (!knot_sc_input_is_valid(input) ||
+ !hash_out || hash_len < SRVR_HMAC_SHA256_64_HASH_SIZE) {
+ return 0;
+ }
+
+ struct hmac_sha256_ctx ctx;
+ hmac_sha256_set_key(&ctx, input->srvr_data->secret_len,
+ input->srvr_data->secret_data);
+
+ hmac_sha256_update(&ctx, input->cc_len, input->cc);
+
+ if (input->nonce && input->nonce_len) {
+ hmac_sha256_update(&ctx, input->nonce_len, input->nonce);
+ }
+
+ if (input->srvr_data->clnt_sockaddr) {
+ update_hash(&ctx, input->srvr_data->clnt_sockaddr);
+ }
+
+ /* SRVR_HMAC_SHA256_64_HASH_SIZE < SHA256_DIGEST_SIZE */
+
+ hmac_sha256_digest(&ctx, SRVR_HMAC_SHA256_64_HASH_SIZE, hash_out);
+
+ return SRVR_HMAC_SHA256_64_HASH_SIZE;
+}
+
+const struct knot_cc_alg knot_cc_alg_hmac_sha256_64 = { KNOT_OPT_COOKIE_CLNT, cc_gen_hmac_sha256_64 };
+
+const struct knot_sc_alg knot_sc_alg_hmac_sha256_64 = { SRVR_HMAC_SHA256_64_HASH_SIZE, sc_gen_hmac_sha256_64 };
diff --git a/lib/cookies/alg_sha.h b/lib/cookies/alg_sha.h
new file mode 100644
index 0000000..e97972a
--- /dev/null
+++ b/lib/cookies/alg_sha.h
@@ -0,0 +1,18 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#include <libknot/cookies/client.h>
+#include <libknot/cookies/server.h>
+
+#include "lib/defines.h"
+
+/* These structures are not meant to be part of public interface. */
+
+/** HMAC-SHA256-64 client cookie algorithm. */
+extern const struct knot_cc_alg knot_cc_alg_hmac_sha256_64;
+
+/** HMAC-SHA256-64 server cookie algorithm. */
+extern const struct knot_sc_alg knot_sc_alg_hmac_sha256_64;
diff --git a/lib/cookies/control.h b/lib/cookies/control.h
new file mode 100644
index 0000000..475b3fd
--- /dev/null
+++ b/lib/cookies/control.h
@@ -0,0 +1,37 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+#include "lib/defines.h"
+
+/** Holds secret quantity. */
+struct kr_cookie_secret {
+ size_t size; /*!< Secret quantity size. */
+ uint8_t data[]; /*!< Secret quantity data. */
+};
+
+/** Holds settings that have direct influence on cookie values computation. */
+struct kr_cookie_comp {
+ struct kr_cookie_secret *secr; /*!< Secret data. */
+ int alg_id; /*!< Cookie algorithm identifier. */
+};
+
+/** Holds settings that control client/server cookie behaviour. */
+struct kr_cookie_settings {
+ bool enabled; /**< Enable/disables DNS cookies functionality. */
+
+ struct kr_cookie_comp current; /**< Current cookie settings. */
+ struct kr_cookie_comp recent; /**< Recent cookie settings. */
+};
+
+/** DNS cookies controlling structure. */
+struct kr_cookie_ctx {
+ struct kr_cookie_settings clnt; /**< Client settings. */
+ struct kr_cookie_settings srvr; /**< Server settings. */
+};
diff --git a/lib/cookies/helper.c b/lib/cookies/helper.c
new file mode 100644
index 0000000..4867817
--- /dev/null
+++ b/lib/cookies/helper.c
@@ -0,0 +1,268 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#include <libknot/rrtype/opt.h>
+#include <libknot/rrtype/opt-cookie.h>
+
+#include "lib/cookies/helper.h"
+#include "lib/defines.h"
+
+/**
+ * @brief Check whether there is a cached cookie that matches the current
+ * client cookie.
+ */
+static const uint8_t *peek_and_check_cc(kr_cookie_lru_t *cache, const void *sa,
+ const uint8_t *cc, uint16_t cc_len)
+{
+ if (kr_fails_assert(cache && sa && cc && cc_len))
+ return NULL;
+
+ const uint8_t *cached_opt = kr_cookie_lru_get(cache, sa);
+ if (!cached_opt)
+ return NULL;
+
+ const uint8_t *cached_cc = knot_edns_opt_get_data((uint8_t *) cached_opt);
+
+ if (cc_len == KNOT_OPT_COOKIE_CLNT &&
+ 0 == memcmp(cc, cached_cc, cc_len)) {
+ return cached_opt;
+ }
+
+ return NULL;
+}
+
+/**
+ * @brief Put a client cookie into the RR Set.
+ */
+static int opt_rr_put_cookie(knot_rrset_t *opt_rr, uint8_t *data,
+ uint16_t data_len, knot_mm_t *mm)
+{
+ if (kr_fails_assert(opt_rr && data && data_len > 0))
+ return kr_error(EINVAL);
+
+ const uint8_t *cc = NULL, *sc = NULL;
+ uint16_t cc_len = 0, sc_len = 0;
+
+ int ret = knot_edns_opt_cookie_parse(data, data_len, &cc, &cc_len,
+ &sc, &sc_len);
+ if (ret != KNOT_EOK)
+ return kr_error(EINVAL);
+ if (kr_fails_assert(data_len == cc_len + sc_len))
+ return kr_error(EINVAL);
+
+ uint16_t cookies_size = data_len;
+ uint8_t *cookies_data = NULL;
+
+ ret = knot_edns_reserve_unique_option(opt_rr, KNOT_EDNS_OPTION_COOKIE,
+ cookies_size, &cookies_data, mm);
+ if (ret != KNOT_EOK)
+ return kr_error(EINVAL);
+ if (kr_fails_assert(cookies_data))
+ return kr_error(EINVAL);
+
+ cookies_size = knot_edns_opt_cookie_write(cc, cc_len, sc, sc_len,
+ cookies_data, cookies_size);
+ if (cookies_size == 0)
+ return kr_error(EINVAL);
+ if (kr_fails_assert(cookies_size == data_len))
+ return kr_error(EINVAL);
+
+ return kr_ok();
+}
+
+/**
+ * @brief Puts entire EDNS option into the RR Set.
+ */
+static int opt_rr_put_cookie_opt(knot_rrset_t *opt_rr, uint8_t *option, knot_mm_t *mm)
+{
+ if (kr_fails_assert(opt_rr && option))
+ return kr_error(EINVAL);
+
+ uint16_t opt_code = knot_edns_opt_get_code(option);
+ if (opt_code != KNOT_EDNS_OPTION_COOKIE)
+ return kr_error(EINVAL);
+
+ uint16_t opt_len = knot_edns_opt_get_length(option);
+ uint8_t *opt_data = knot_edns_opt_get_data(option);
+ if (!opt_data || opt_len == 0)
+ return kr_error(EINVAL);
+
+ return opt_rr_put_cookie(opt_rr, opt_data, opt_len, mm);
+}
+
+int kr_request_put_cookie(const struct kr_cookie_comp *clnt_comp,
+ kr_cookie_lru_t *cookie_cache,
+ const struct sockaddr *clnt_sa,
+ const struct sockaddr *srvr_sa,
+ struct kr_request *req)
+{
+ if (!clnt_comp || !req)
+ return kr_error(EINVAL);
+
+ if (!req->ctx->opt_rr)
+ return kr_ok();
+
+ if (!clnt_comp->secr || (clnt_comp->alg_id < 0) || !cookie_cache)
+ return kr_error(EINVAL);
+
+ /*
+ * Generate client cookie from client address, server address and
+ * secret quantity.
+ */
+ struct knot_cc_input input = {
+ .clnt_sockaddr = clnt_sa,
+ .srvr_sockaddr = srvr_sa,
+ .secret_data = clnt_comp->secr->data,
+ .secret_len = clnt_comp->secr->size
+ };
+ uint8_t cc[KNOT_OPT_COOKIE_CLNT];
+ uint16_t cc_len = KNOT_OPT_COOKIE_CLNT;
+ const struct knot_cc_alg *cc_alg = kr_cc_alg_get(clnt_comp->alg_id);
+ if (!cc_alg)
+ return kr_error(EINVAL);
+ if (kr_fails_assert(cc_alg->gen_func))
+ return kr_error(EINVAL);
+ cc_len = cc_alg->gen_func(&input, cc, cc_len);
+ if (cc_len != KNOT_OPT_COOKIE_CLNT)
+ return kr_error(EINVAL);
+
+ const uint8_t *cached_cookie = peek_and_check_cc(cookie_cache,
+ srvr_sa, cc, cc_len);
+
+ /* Add cookie option. */
+ int ret;
+ if (cached_cookie) {
+ ret = opt_rr_put_cookie_opt(req->ctx->opt_rr,
+ (uint8_t *)cached_cookie,
+ req->ctx->pool);
+ } else {
+ ret = opt_rr_put_cookie(req->ctx->opt_rr, cc, cc_len,
+ req->ctx->pool);
+ }
+
+ return ret;
+}
+
+int kr_answer_write_cookie(struct knot_sc_input *sc_input,
+ const struct kr_nonce_input *nonce,
+ const struct knot_sc_alg *alg, knot_pkt_t *pkt)
+{
+ if (!sc_input || !sc_input->cc || sc_input->cc_len == 0)
+ return kr_error(EINVAL);
+
+ if (!sc_input->srvr_data || !sc_input->srvr_data->clnt_sockaddr ||
+ !sc_input->srvr_data->secret_data ||
+ !sc_input->srvr_data->secret_len) {
+ return kr_error(EINVAL);
+ }
+
+ if (!nonce)
+ return kr_error(EINVAL);
+
+ if (!alg || !alg->hash_size || !alg->hash_func)
+ return kr_error(EINVAL);
+
+ if (!pkt || !pkt->opt_rr)
+ return kr_error(EINVAL);
+
+ uint16_t nonce_len = KR_NONCE_LEN;
+ uint16_t hash_len = alg->hash_size;
+
+ /*
+ * Space for cookie is reserved inside the EDNS OPT RR of
+ * the answer packet.
+ */
+ uint8_t *cookie = NULL;
+ uint16_t cookie_len = knot_edns_opt_cookie_data_len(sc_input->cc_len,
+ nonce_len + hash_len);
+ if (cookie_len == 0)
+ return kr_error(EINVAL);
+
+ int ret = knot_edns_reserve_unique_option(pkt->opt_rr,
+ KNOT_EDNS_OPTION_COOKIE,
+ cookie_len, &cookie,
+ &pkt->mm);
+ if (ret != KNOT_EOK)
+ return kr_error(ENOMEM);
+ if (kr_fails_assert(cookie))
+ return kr_error(EFAULT);
+
+ /*
+ * Function knot_edns_opt_cookie_data_len() returns the sum of its
+ * parameters or zero. Anyway, let's check again.
+ */
+ if (cookie_len < (sc_input->cc_len + nonce_len + hash_len))
+ return kr_error(EINVAL);
+
+ /* Copy client cookie data portion. */
+ memcpy(cookie, sc_input->cc, sc_input->cc_len);
+
+ if (nonce_len) {
+ /* Write nonce data portion. */
+ kr_nonce_write_wire(cookie + sc_input->cc_len, nonce_len,
+ nonce);
+ /* Adjust input for written nonce value. */
+ sc_input->nonce = cookie + sc_input->cc_len;
+ sc_input->nonce_len = nonce_len;
+ }
+
+ hash_len = alg->hash_func(sc_input,
+ cookie + sc_input->cc_len + nonce_len,
+ hash_len);
+ /* Zero nonce values. */
+ sc_input->nonce = NULL;
+ sc_input->nonce_len = 0;
+
+ return (hash_len != 0) ? kr_ok() : kr_error(EINVAL);
+}
+
+int kr_pkt_set_ext_rcode(knot_pkt_t *pkt, uint16_t whole_rcode)
+{
+ /*
+ * RFC6891 6.1.3 -- extended RCODE forms the upper 8 bits of whole
+ * 12-bit RCODE (together with the 4 bits of 'normal' RCODE).
+ *
+ * | 11 10 09 08 07 06 05 04 | 03 02 01 00 |
+ * | 12-bit whole RCODE |
+ * | 8-bit extended RCODE | 4-bit RCODE |
+ */
+
+ if (!pkt || !knot_pkt_has_edns(pkt))
+ return kr_error(EINVAL);
+
+ uint8_t rcode = whole_rcode & 0x0f;
+ uint8_t ext_rcode = whole_rcode >> 4;
+ knot_wire_set_rcode(pkt->wire, rcode);
+ knot_edns_set_ext_rcode(pkt->opt_rr, ext_rcode);
+
+ return kr_ok();
+}
+
+uint8_t *kr_no_question_cookie_query(const knot_pkt_t *pkt)
+{
+ if (!pkt || knot_wire_get_qdcount(pkt->wire) > 0)
+ return false;
+
+ if (knot_wire_get_qr(pkt->wire) != 0 || !pkt->opt_rr)
+ return false;
+
+ return knot_edns_get_option(pkt->opt_rr, KNOT_EDNS_OPTION_COOKIE);
+}
+
+int kr_parse_cookie_opt(uint8_t *cookie_opt, struct knot_dns_cookies *cookies)
+{
+ if (!cookie_opt || !cookies)
+ return kr_error(EINVAL);
+
+ const uint8_t *cookie_data = knot_edns_opt_get_data(cookie_opt);
+ uint16_t cookie_len = knot_edns_opt_get_length(cookie_opt);
+ if (!cookie_data || cookie_len == 0)
+ return kr_error(EINVAL);
+
+ int ret = knot_edns_opt_cookie_parse(cookie_data, cookie_len,
+ &cookies->cc, &cookies->cc_len,
+ &cookies->sc, &cookies->sc_len);
+
+ return (ret == KNOT_EOK) ? kr_ok() : kr_error(EINVAL);
+}
diff --git a/lib/cookies/helper.h b/lib/cookies/helper.h
new file mode 100644
index 0000000..dfde90e
--- /dev/null
+++ b/lib/cookies/helper.h
@@ -0,0 +1,74 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#include <libknot/packet/pkt.h>
+
+#include "lib/cookies/alg_containers.h"
+#include "lib/cookies/control.h"
+#include "lib/cookies/lru_cache.h"
+#include "lib/cookies/nonce.h"
+#include "lib/defines.h"
+#include "lib/resolve.h"
+
+/**
+ * @brief Updates DNS cookie in the request EDNS options.
+ * @note This function must be called before the request packet is finalised.
+ * @param clnt_comp client cookie control structure
+ * @param cookie_cache cookie cache
+ * @param clnt_sa client socket address
+ * @param srvr_sa server socket address
+ * @param req name resolution request
+ * @return kr_ok() or error code
+ */
+KR_EXPORT
+int kr_request_put_cookie(const struct kr_cookie_comp *clnt_comp,
+ kr_cookie_lru_t *cookie_cache,
+ const struct sockaddr *clnt_sa,
+ const struct sockaddr *srvr_sa,
+ struct kr_request *req);
+
+/**
+ * @brief Inserts a cookie option into the OPT RR. It does not write any
+ * wire data.
+ * @note The content of @a sc_input is modified. Any pre-set nonce value is
+ * ignored. After retuning its nonce value will be null.
+ * @param sc_input data needed to compute server cookie, nonce is ignored
+ * @param nonce nonce value that is actually used
+ * @param alg hash algorithm
+ * @param pkt DNS response packet
+ */
+KR_EXPORT
+int kr_answer_write_cookie(struct knot_sc_input *sc_input,
+ const struct kr_nonce_input *nonce,
+ const struct knot_sc_alg *alg, knot_pkt_t *pkt);
+
+/**
+ * @brief Set RCODE and extended RCODE.
+ * @param pkt DNS packet
+ * @param whole_rcode RCODE value
+ * @return kr_ok() or error code
+ */
+KR_EXPORT
+int kr_pkt_set_ext_rcode(knot_pkt_t *pkt, uint16_t whole_rcode);
+
+/**
+ * @brief Check whether packet is a server cookie request according to
+ * RFC7873 5.4.
+ * @param pkt Packet to be examined.
+ * @return Pointer to entire cookie option if is a server cookie query, NULL on
+ * errors or if packet doesn't contain cookies or if QDCOUNT > 0.
+ */
+KR_EXPORT
+uint8_t *kr_no_question_cookie_query(const knot_pkt_t *pkt);
+
+/**
+ * @brief Parse cookies from cookie option.
+ * @param cookie_opt Cookie option.
+ * @param cookies Cookie structure to be set.
+ * @return kr_ok() on success, error if cookies are malformed.
+ */
+KR_EXPORT
+int kr_parse_cookie_opt(uint8_t *cookie_opt, struct knot_dns_cookies *cookies);
diff --git a/lib/cookies/lru_cache.c b/lib/cookies/lru_cache.c
new file mode 100644
index 0000000..245d1c3
--- /dev/null
+++ b/lib/cookies/lru_cache.c
@@ -0,0 +1,58 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#include <libknot/rrtype/opt.h>
+#include <string.h>
+
+#include "lib/cookies/lru_cache.h"
+#include "lib/utils.h"
+
+const uint8_t *kr_cookie_lru_get(kr_cookie_lru_t *cache,
+ const struct sockaddr *sa)
+{
+ if (!cache || !sa) {
+ return NULL;
+ }
+
+ int addr_len = kr_inaddr_len(sa);
+ const char *addr = kr_inaddr(sa);
+ if (!addr || addr_len <= 0) {
+ return NULL;
+ }
+
+ struct cookie_opt_data *cached = lru_get_try(cache, addr, addr_len);
+ return cached ? cached->opt_data : NULL;
+}
+
+int kr_cookie_lru_set(kr_cookie_lru_t *cache, const struct sockaddr *sa,
+ uint8_t *opt)
+{
+ if (!cache || !sa) {
+ return kr_error(EINVAL);
+ }
+
+ if (!opt) {
+ return kr_ok();
+ }
+
+ int addr_len = kr_inaddr_len(sa);
+ const char *addr = kr_inaddr(sa);
+ if (!addr || addr_len <= 0) {
+ return kr_error(EINVAL);
+ }
+
+ uint16_t opt_size = KNOT_EDNS_OPTION_HDRLEN +
+ knot_edns_opt_get_length(opt);
+
+ if (opt_size > KR_COOKIE_OPT_MAX_LEN) {
+ return kr_error(EINVAL);
+ }
+
+ struct cookie_opt_data *cached = lru_get_new(cache, addr, addr_len, NULL);
+ if (cached) {
+ memcpy(cached->opt_data, opt, opt_size);
+ }
+
+ return kr_ok();
+}
diff --git a/lib/cookies/lru_cache.h b/lib/cookies/lru_cache.h
new file mode 100644
index 0000000..a0f6cab
--- /dev/null
+++ b/lib/cookies/lru_cache.h
@@ -0,0 +1,57 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#include <netinet/in.h>
+#include <stdint.h>
+
+#if ENABLE_COOKIES
+#include <libknot/rrtype/opt.h>
+#include <libknot/rrtype/opt-cookie.h>
+#else
+#define KNOT_OPT_COOKIE_CLNT 8
+#define KNOT_OPT_COOKIE_SRVR_MAX 32
+#endif /* ENABLE_COOKIES */
+
+#include "lib/defines.h"
+#include "lib/generic/lru.h"
+
+/** Maximal size of a cookie option. */
+#define KR_COOKIE_OPT_MAX_LEN (KNOT_EDNS_OPTION_HDRLEN + KNOT_OPT_COOKIE_CLNT + KNOT_OPT_COOKIE_SRVR_MAX)
+
+/**
+ * Cookie option entry.
+ */
+struct cookie_opt_data {
+ uint8_t opt_data[KR_COOKIE_OPT_MAX_LEN];
+};
+
+/**
+ * DNS cookies tracking.
+ */
+typedef lru_t(struct cookie_opt_data) kr_cookie_lru_t;
+
+/**
+ * @brief Obtain LRU cache entry.
+ *
+ * @param cache cookie LRU cache
+ * @param sa socket address serving as key
+ * @return pointer to cached option or NULL if not found or error occurred
+ */
+KR_EXPORT
+const uint8_t *kr_cookie_lru_get(kr_cookie_lru_t *cache,
+ const struct sockaddr *sa);
+
+/**
+ * @brief Stores cookie option into LRU cache.
+ *
+ * @param cache cookie LRU cache
+ * @param sa socket address serving as key
+ * @param opt cookie option to be stored
+ * @return kr_ok() or error code
+ */
+KR_EXPORT
+int kr_cookie_lru_set(kr_cookie_lru_t *cache, const struct sockaddr *sa,
+ uint8_t *opt);
diff --git a/lib/cookies/nonce.c b/lib/cookies/nonce.c
new file mode 100644
index 0000000..1b50d87
--- /dev/null
+++ b/lib/cookies/nonce.c
@@ -0,0 +1,20 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#include <libknot/wire.h>
+#include "lib/cookies/nonce.h"
+
+uint16_t kr_nonce_write_wire(uint8_t *buf, uint16_t buf_len,
+ const struct kr_nonce_input *input)
+{
+ if (!buf || buf_len < KR_NONCE_LEN || !input) {
+ return 0;
+ }
+
+ knot_wire_write_u32(buf, input->rand);
+ knot_wire_write_u32(buf + sizeof(uint32_t), input->time);
+ buf_len = 2 * sizeof(uint32_t);
+
+ return buf_len;
+}
diff --git a/lib/cookies/nonce.h b/lib/cookies/nonce.h
new file mode 100644
index 0000000..6c2970f
--- /dev/null
+++ b/lib/cookies/nonce.h
@@ -0,0 +1,31 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#include "lib/defines.h"
+
+/* RFC7873 Appendix B.2 mentions an algorithm using two values before the
+ * actual server cookie hash. */
+
+/** Nonce value length. */
+#define KR_NONCE_LEN 8
+
+/** Input data to generate nonce from. */
+struct kr_nonce_input {
+ uint32_t rand; /**< some random value */
+ uint32_t time; /**< time stamp */
+};
+
+/**
+ * @brief Writes server cookie nonce value into given buffer.
+ *
+ * @param buf buffer to write nonce data in wire format into
+ * @param buf_len buffer size
+ * @param input data to generate wire data from
+ * @return non-zero size of written data on success, 0 on failure
+ */
+KR_EXPORT
+uint16_t kr_nonce_write_wire(uint8_t *buf, uint16_t buf_len,
+ const struct kr_nonce_input *input);
diff --git a/lib/defines.h b/lib/defines.h
new file mode 100644
index 0000000..6b6dac5
--- /dev/null
+++ b/lib/defines.h
@@ -0,0 +1,106 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#include <errno.h>
+#include <libknot/errcode.h>
+#include <libknot/dname.h>
+#include <libknot/rrset.h>
+#include <libknot/version.h>
+
+/* Function attributes */
+#if __GNUC__ >= 4
+#define KR_EXPORT __attribute__ ((visibility ("default")))
+#define KR_CONST __attribute__((__const__))
+#define KR_PURE __attribute__((__pure__))
+#define KR_NORETURN __attribute__((__noreturn__))
+#define KR_COLD __attribute__((__cold__))
+#define KR_PRINTF(n) __attribute__((format (printf, n, (n+1))))
+#else
+#define KR_EXPORT
+#define KR_CONST
+#define KR_PURE
+#define KR_NORETURN
+#define KR_COLD
+#define KR_PRINTF(n)
+#endif
+
+typedef unsigned int uint;
+
+/*
+ * Error codes.
+ */
+#define kr_ok() 0
+/* Mark as cold to mark all branches as unlikely. */
+static inline int KR_COLD kr_error(int x) {
+ return x <= 0 ? x : -x;
+}
+#define kr_strerror(x) strerror(abs(x))
+
+/* We require C11 but want to avoid including the standard assertion header
+ * so we alias it ourselves. */
+#define static_assert _Static_assert
+
+/*
+ * Connection limits.
+ * @cond internal
+ */
+#define KR_CONN_RTT_MAX 2000 /* Timeout for network activity */
+#define KR_CONN_RETRY 200 /* Retry interval for network activity */
+#define KR_ITER_LIMIT 100 /* Built-in iterator limit */
+#define KR_RESOLVE_TIME_LIMIT 10000 /* Upper limit for resolution time of single query, ms */
+#define KR_CNAME_CHAIN_LIMIT 13 /* Built-in maximum CNAME chain length */
+#define KR_TIMEOUT_LIMIT 10 /* Maximum number of retries after timeout. */
+#define KR_QUERY_NSRETRY_LIMIT 4 /* Maximum number of retries per query. */
+#define KR_COUNT_NO_NSADDR_LIMIT 5
+#define KR_CONSUME_FAIL_ROW_LIMIT 3 /* Maximum number of KR_STATE_FAIL in a row. */
+
+/*
+ * Defines.
+ */
+#define KR_DNS_PORT 53
+#define KR_DNS_DOH_PORT 443
+#define KR_DNS_TLS_PORT 853
+#define KR_EDNS_VERSION 0
+#define KR_EDNS_PAYLOAD 1232 /* Default UDP payload; see https://www.dnsflagday.net/2020/ */
+#define KR_CACHE_DEFAULT_TTL_MIN (5) /* avoid bursts of queries */
+#define KR_CACHE_DEFAULT_TTL_MAX (1 * 24 * 3600) /* one day seems enough; fits prefill module */
+
+#define KR_DNAME_STR_MAXLEN (KNOT_DNAME_TXT_MAXLEN + 1)
+#define KR_RRTYPE_STR_MAXLEN (16 + 1)
+
+/* Compatibility with libknot<3.1.0 */
+#if KNOT_VERSION_HEX < 0x030100
+#define KNOT_EDNS_EDE_NONE (-1)
+#endif
+
+/*
+ * Address sanitizer hints.
+ */
+#if !defined(__SANITIZE_ADDRESS__) && defined(__has_feature)
+# if __has_feature(address_sanitizer)
+# define __SANITIZE_ADDRESS__ 1
+# endif
+#endif
+#if defined(__SANITIZE_ADDRESS__)
+void __asan_poison_memory_region(void const volatile *addr, size_t size);
+void __asan_unpoison_memory_region(void const volatile *addr, size_t size);
+#define kr_asan_poison(addr, size) __asan_poison_memory_region((addr), (size))
+#define kr_asan_unpoison(addr, size) __asan_unpoison_memory_region((addr), (size))
+#define kr_asan_custom_poison(fn, addr) fn ##_poison((addr))
+#define kr_asan_custom_unpoison(fn, addr) fn ##_unpoison((addr))
+#else
+#define kr_asan_poison(addr, size)
+#define kr_asan_unpoison(addr, size)
+#define kr_asan_custom_poison(fn, addr)
+#define kr_asan_custom_unpoison(fn, addr)
+#endif
+
+#if defined(__SANITIZE_ADDRESS__) && defined(_FORTIFY_SOURCE)
+ #error "You can't use address sanitizer with _FORTIFY_SOURCE"
+ // https://github.com/google/sanitizers/issues/247
+#endif
+
+/* @endcond */
diff --git a/lib/dnssec.c b/lib/dnssec.c
new file mode 100644
index 0000000..d6ae3cc
--- /dev/null
+++ b/lib/dnssec.c
@@ -0,0 +1,601 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#include <libdnssec/binary.h>
+#include <libdnssec/crypto.h>
+#include <libdnssec/error.h>
+#include <libdnssec/key.h>
+#include <libdnssec/sign.h>
+#include <libknot/descriptor.h>
+#include <libknot/packet/wire.h>
+#include <libknot/rdataset.h>
+#include <libknot/rrset.h>
+#include <libknot/rrtype/dnskey.h>
+#include <libknot/rrtype/nsec.h>
+#include <libknot/rrtype/rrsig.h>
+
+#include "contrib/cleanup.h"
+#include "lib/defines.h"
+#include "lib/dnssec/nsec.h"
+#include "lib/dnssec/nsec3.h"
+#include "lib/dnssec/signature.h"
+#include "lib/dnssec.h"
+#include "lib/resolve.h"
+
+/* forward */
+static int kr_rrset_validate_with_key(kr_rrset_validation_ctx_t *vctx,
+ knot_rrset_t *covered, size_t key_pos, const struct dnssec_key *key);
+
+void kr_crypto_init(void)
+{
+ dnssec_crypto_init();
+}
+
+void kr_crypto_cleanup(void)
+{
+ dnssec_crypto_cleanup();
+}
+
+void kr_crypto_reinit(void)
+{
+ dnssec_crypto_reinit();
+}
+
+#define FLG_WILDCARD_EXPANSION 0x01 /**< Possibly generated by using wildcard expansion. */
+
+/**
+ * Check the RRSIG RR validity according to RFC4035 5.3.1 .
+ * @param flags The flags are going to be set according to validation result.
+ * @param cov_labels Covered RRSet owner label count.
+ * @param rrsigs rdata containing the signatures.
+ * @param key_alg DNSKEY's algorithm.
+ * @param keytag Used key tag.
+ * @param vctx->zone_name The name of the zone cut (and the DNSKEY).
+ * @param vctx->timestamp Validation time.
+ */
+static int validate_rrsig_rr(int *flags, int cov_labels,
+ const knot_rdata_t *rrsigs,
+ uint8_t key_alg,
+ uint16_t keytag,
+ kr_rrset_validation_ctx_t *vctx)
+{
+ if (kr_fails_assert(flags && rrsigs && vctx && vctx->zone_name)) {
+ return kr_error(EINVAL);
+ }
+ /* bullet 5 */
+ if (knot_rrsig_sig_expiration(rrsigs) < vctx->timestamp) {
+ vctx->rrs_counters.expired++;
+ return kr_error(EINVAL);
+ }
+ /* bullet 6 */
+ if (knot_rrsig_sig_inception(rrsigs) > vctx->timestamp) {
+ vctx->rrs_counters.notyet++;
+ return kr_error(EINVAL);
+ }
+ /* bullet 2 */
+ const knot_dname_t *signer_name = knot_rrsig_signer_name(rrsigs);
+ if (!signer_name || !knot_dname_is_equal(signer_name, vctx->zone_name)) {
+ vctx->rrs_counters.signer_invalid++;
+ return kr_error(EAGAIN);
+ }
+ /* bullet 4 */
+ {
+ int rrsig_labels = knot_rrsig_labels(rrsigs);
+ if (rrsig_labels > cov_labels) {
+ vctx->rrs_counters.labels_invalid++;
+ return kr_error(EINVAL);
+ }
+ if (rrsig_labels < cov_labels) {
+ *flags |= FLG_WILDCARD_EXPANSION;
+ }
+ }
+
+ /* bullet 7
+ * Part checked elsewhere: key owner matching the zone_name. */
+ if (key_alg != knot_rrsig_alg(rrsigs) || keytag != knot_rrsig_key_tag(rrsigs)) {
+ vctx->rrs_counters.key_invalid++;
+ return kr_error(EINVAL);
+ }
+ /* bullet 8 */
+ /* Checked somewhere else. */
+ /* bullet 9 and 10 */
+ /* One of the requirements should be always fulfilled. */
+
+ return kr_ok();
+}
+
+/**
+ * Returns the number of labels that have been added by wildcard expansion.
+ * @param expanded Expanded wildcard.
+ * @param rrsigs RRSet containing the signatures.
+ * @param sig_pos Specifies the signature within the RRSIG RRSet.
+ * @return Number of added labels, -1 on error.
+ */
+static inline int wildcard_radix_len_diff(const knot_dname_t *expanded,
+ const knot_rdata_t *rrsig)
+{
+ if (!expanded || !rrsig) {
+ return -1;
+ }
+
+ return knot_dname_labels(expanded, NULL) - knot_rrsig_labels(rrsig);
+}
+
+int kr_rrset_validate(kr_rrset_validation_ctx_t *vctx, knot_rrset_t *covered)
+{
+ if (!vctx) {
+ return kr_error(EINVAL);
+ }
+ if (!vctx->pkt || !covered || !vctx->keys || !vctx->zone_name) {
+ return kr_error(EINVAL);
+ }
+
+ memset(&vctx->rrs_counters, 0, sizeof(vctx->rrs_counters));
+ for (unsigned i = 0; i < vctx->keys->rrs.count; ++i) {
+ int ret = kr_rrset_validate_with_key(vctx, covered, i, NULL);
+ if (ret == 0) {
+ return ret;
+ }
+ }
+
+ return kr_error(ENOENT);
+}
+
+/** Assuming `rrs` was validated with `sig`, trim its TTL in case it's over-extended. */
+static bool trim_ttl(knot_rrset_t *rrs, const knot_rdata_t *sig,
+ const kr_rrset_validation_ctx_t *vctx)
+{
+ /* The trimming logic is a bit complicated.
+ *
+ * We respect configured ttl_min over the (signed) original TTL,
+ * but we very much want to avoid TTLs over signature expiration,
+ * as that could cause serious issues with downstream validators.
+ */
+ const uint32_t ttl_max = MIN(
+ MAX(knot_rrsig_original_ttl(sig), vctx->ttl_min),
+ knot_rrsig_sig_expiration(sig) - vctx->timestamp
+ );
+ if (likely(rrs->ttl <= ttl_max))
+ return false;
+ if (kr_log_is_debug_qry(VALIDATOR, vctx->log_qry)) {
+ auto_free char *name_str = kr_dname_text(rrs->owner),
+ *type_str = kr_rrtype_text(rrs->type);
+ kr_log_q(vctx->log_qry, VALIDATOR, "trimming TTL of %s %s: %d -> %d\n",
+ name_str, type_str, (int)rrs->ttl, (int)ttl_max);
+ }
+ rrs->ttl = ttl_max;
+ return true;
+}
+
+
+typedef struct {
+ struct dnssec_key *key;
+ uint8_t alg;
+ uint16_t tag;
+} kr_svldr_key_t;
+
+struct kr_svldr_ctx {
+ kr_rrset_validation_ctx_t vctx;
+ array_t(kr_svldr_key_t) keys; // owned(malloc), also insides via svldr_key_*
+};
+
+static int svldr_key_new(const knot_rdata_t *rdata, const knot_dname_t *owner,
+ kr_svldr_key_t *result)
+{
+ result->alg = knot_dnskey_alg(rdata);
+ result->key = NULL; // just silence analyzers
+ int ret = kr_dnssec_key_from_rdata(&result->key, owner, rdata->data, rdata->len);
+ if (likely(ret == 0))
+ result->tag = dnssec_key_get_keytag(result->key);
+ return ret;
+}
+static inline void svldr_key_del(kr_svldr_key_t *skey)
+{
+ kr_dnssec_key_free(&skey->key);
+}
+
+void kr_svldr_free_ctx(struct kr_svldr_ctx *ctx)
+{
+ if (!ctx) return;
+ for (ssize_t i = 0; i < ctx->keys.len; ++i)
+ svldr_key_del(&ctx->keys.at[i]);
+ array_clear(ctx->keys);
+ free_const(ctx->vctx.zone_name);
+ free(ctx);
+}
+struct kr_svldr_ctx * kr_svldr_new_ctx(const knot_rrset_t *ds, knot_rrset_t *dnskey,
+ const knot_rdataset_t *dnskey_sigs, uint32_t timestamp,
+ kr_rrset_validation_ctx_t *err_ctx)
+{
+ // Basic init.
+ struct kr_svldr_ctx *ctx = calloc(1, sizeof(*ctx));
+ if (unlikely(!ctx))
+ return NULL;
+ ctx->vctx.timestamp = timestamp; // .ttl_min is implicitly zero
+ ctx->vctx.zone_name = knot_dname_copy(ds->owner, NULL);
+ if (unlikely(!ctx->vctx.zone_name))
+ goto fail;
+ // Validate the DNSKEY set.
+ ctx->vctx.keys = dnskey;
+ if (kr_dnskeys_trusted(&ctx->vctx, dnskey_sigs, ds) != 0)
+ goto fail;
+ // Put usable DNSKEYs into ctx->keys. (Some duplication of work happens, but OK.)
+ array_init(ctx->keys);
+ array_reserve(ctx->keys, dnskey->rrs.count);
+ knot_rdata_t *krr = dnskey->rrs.rdata;
+ for (int i = 0; i < dnskey->rrs.count; ++i, krr = knot_rdataset_next(krr)) {
+ if (!kr_dnssec_key_zsk(krr->data) || kr_dnssec_key_revoked(krr->data))
+ continue; // key not usable for this
+ kr_svldr_key_t key;
+ if (unlikely(svldr_key_new(krr, NULL/*seems OK here*/, &key) != 0))
+ goto fail;
+ array_push(ctx->keys, key);
+ }
+ return ctx;
+fail:
+ if (err_ctx)
+ memcpy(err_ctx, &ctx->vctx, sizeof(*err_ctx));
+ kr_svldr_free_ctx(ctx);
+ return NULL;
+}
+
+static int kr_svldr_rrset_with_key(knot_rrset_t *rrs, const knot_rdataset_t *rrsigs,
+ kr_rrset_validation_ctx_t *vctx, const kr_svldr_key_t *key)
+{
+ const int covered_labels = knot_dname_labels(rrs->owner, NULL)
+ - knot_dname_is_wildcard(rrs->owner);
+ knot_rdata_t *rdata_j = rrsigs->rdata;
+ for (uint16_t j = 0; j < rrsigs->count; ++j, rdata_j = knot_rdataset_next(rdata_j)) {
+ if (kr_fails_assert(knot_rrsig_type_covered(rdata_j) == rrs->type))
+ continue; //^^ not a problem but no reason to allow them in the API
+ int val_flgs = 0;
+ int retv = validate_rrsig_rr(&val_flgs, covered_labels, rdata_j,
+ key->alg, key->tag, vctx);
+ if (retv == kr_error(EAGAIN)) {
+ vctx->result = retv;
+ return vctx->result;
+ } else if (retv != 0) {
+ continue;
+ }
+ // We only expect non-expanded wildcard records in input;
+ // that also means we don't need to perform non-existence proofs.
+ const int trim_labels = (val_flgs & FLG_WILDCARD_EXPANSION) ? 1 : 0;
+ if (kr_check_signature(rdata_j, key->key, rrs, trim_labels) == 0) {
+ trim_ttl(rrs, rdata_j, vctx);
+ vctx->result = kr_ok();
+ return vctx->result;
+ } else {
+ vctx->rrs_counters.crypto_invalid++;
+ }
+ }
+ vctx->result = kr_error(ENOENT);
+ return vctx->result;
+}
+/* The implementation basically performs "parts of" kr_rrset_validate(). */
+int kr_svldr_rrset(knot_rrset_t *rrs, const knot_rdataset_t *rrsigs,
+ struct kr_svldr_ctx *ctx)
+{
+ if (knot_dname_in_bailiwick(rrs->owner, ctx->vctx.zone_name) < 0) {
+ ctx->vctx.result = kr_error(EAGAIN);
+ return ctx->vctx.result;
+ }
+ for (ssize_t i = 0; i < ctx->keys.len; ++i) {
+ kr_svldr_rrset_with_key(rrs, rrsigs, &ctx->vctx, &ctx->keys.at[i]);
+ if (ctx->vctx.result == 0)
+ break;
+ }
+ return ctx->vctx.result;
+}
+
+
+/**
+ * Validate RRSet using a specific key.
+ * @param vctx Pointer to validation context.
+ * @param covered RRSet covered by a signature. It must be in canonical format.
+ * TTL may get lowered.
+ * @param key_pos Position of the key to be validated with.
+ * @param key Key to be used to validate.
+ * If NULL, then key from DNSKEY RRSet is used.
+ * @return 0 or error code, same as vctx->result.
+ */
+static int kr_rrset_validate_with_key(kr_rrset_validation_ctx_t *vctx,
+ knot_rrset_t *covered,
+ size_t key_pos, const struct dnssec_key *key)
+{
+ const knot_pkt_t *pkt = vctx->pkt;
+ const knot_rrset_t *keys = vctx->keys;
+ const knot_dname_t *zone_name = vctx->zone_name;
+ bool has_nsec3 = vctx->has_nsec3;
+ struct dnssec_key *created_key = NULL;
+
+ if (!knot_dname_is_equal(keys->owner, zone_name)
+ /* It's just caller's approximation that the RR is in that particular zone,
+ * so we verify that in the following condition.
+ * We MUST guard against attempts of zones signing out-of-bailiwick records. */
+ || knot_dname_in_bailiwick(covered->owner, zone_name) < 0) {
+ vctx->result = kr_error(ENOENT);
+ return vctx->result;
+ }
+
+ const knot_rdata_t *key_rdata = knot_rdataset_at(&keys->rrs, key_pos);
+ if (key == NULL) {
+ int ret = kr_dnssec_key_from_rdata(&created_key, keys->owner,
+ key_rdata->data, key_rdata->len);
+ if (ret != 0) {
+ vctx->result = ret;
+ return vctx->result;
+ }
+ key = created_key;
+ }
+ uint16_t keytag = dnssec_key_get_keytag(key);
+ const uint8_t key_alg = knot_dnskey_alg(key_rdata);
+ /* The asterisk does not count, RFC4034 3.1.3, paragraph 3. */
+ const int covered_labels = knot_dname_labels(covered->owner, NULL)
+ - knot_dname_is_wildcard(covered->owner);
+
+ for (uint16_t i = 0; i < vctx->rrs->len; ++i) {
+ /* Consider every RRSIG that matches and comes from the same query. */
+ const knot_rrset_t *rrsig = vctx->rrs->at[i]->rr;
+ const bool ok = vctx->rrs->at[i]->qry_uid == vctx->qry_uid
+ && rrsig->type == KNOT_RRTYPE_RRSIG
+ && rrsig->rclass == covered->rclass
+ && knot_dname_is_equal(rrsig->owner, covered->owner);
+ if (!ok)
+ continue;
+
+ knot_rdata_t *rdata_j = rrsig->rrs.rdata;
+ for (uint16_t j = 0; j < rrsig->rrs.count; ++j, rdata_j = knot_rdataset_next(rdata_j)) {
+ int val_flgs = 0;
+ int trim_labels = 0;
+ if (knot_rrsig_type_covered(rdata_j) != covered->type) {
+ continue;
+ }
+ kr_rank_set(&vctx->rrs->at[i]->rank, KR_RANK_BOGUS); /* defensive style */
+ vctx->rrs_counters.matching_name_type++;
+ int retv = validate_rrsig_rr(&val_flgs, covered_labels, rdata_j,
+ key_alg, keytag, vctx);
+ if (retv == kr_error(EAGAIN)) {
+ kr_dnssec_key_free(&created_key);
+ vctx->result = retv;
+ return retv;
+ } else if (retv != 0) {
+ continue;
+ }
+ if (val_flgs & FLG_WILDCARD_EXPANSION) {
+ trim_labels = wildcard_radix_len_diff(covered->owner, rdata_j);
+ if (trim_labels < 0) {
+ break;
+ }
+ }
+ if (kr_check_signature(rdata_j, key, covered, trim_labels) != 0) {
+ vctx->rrs_counters.crypto_invalid++;
+ continue;
+ }
+ if (val_flgs & FLG_WILDCARD_EXPANSION) {
+ int ret = 0;
+ if (!has_nsec3) {
+ ret = kr_nsec_wildcard_answer_response_check(pkt, KNOT_AUTHORITY, covered->owner);
+ } else {
+ ret = kr_nsec3_wildcard_answer_response_check(pkt, KNOT_AUTHORITY, covered->owner, trim_labels - 1);
+ if (ret == kr_error(KNOT_ERANGE)) {
+ ret = 0;
+ vctx->flags |= KR_DNSSEC_VFLG_OPTOUT;
+ }
+ }
+ if (ret != 0) {
+ vctx->rrs_counters.nsec_invalid++;
+ continue;
+ }
+ vctx->flags |= KR_DNSSEC_VFLG_WEXPAND;
+ }
+
+ trim_ttl(covered, rdata_j, vctx);
+
+ kr_dnssec_key_free(&created_key);
+ vctx->result = kr_ok();
+ kr_rank_set(&vctx->rrs->at[i]->rank, KR_RANK_SECURE); /* upgrade from bogus */
+ return vctx->result;
+ }
+ }
+ /* No applicable key found, cannot be validated. */
+ kr_dnssec_key_free(&created_key);
+ vctx->result = kr_error(ENOENT);
+ return vctx->result;
+}
+
+bool kr_ds_algo_support(const knot_rrset_t *ta)
+{
+ if (kr_fails_assert(ta && ta->type == KNOT_RRTYPE_DS && ta->rclass == KNOT_CLASS_IN))
+ return false;
+ /* Check if at least one DS has a usable algorithm pair. */
+ knot_rdata_t *rdata_i = ta->rrs.rdata;
+ for (uint16_t i = 0; i < ta->rrs.count;
+ ++i, rdata_i = knot_rdataset_next(rdata_i)) {
+ if (dnssec_algorithm_digest_support(knot_ds_digest_type(rdata_i))
+ && dnssec_algorithm_key_support(knot_ds_alg(rdata_i))) {
+ return true;
+ }
+ }
+ return false;
+}
+
+int kr_dnskeys_trusted(kr_rrset_validation_ctx_t *vctx, const knot_rdataset_t *sigs,
+ const knot_rrset_t *ta)
+{
+ knot_rrset_t *keys = vctx->keys;
+ const bool ok = keys && ta && ta->rrs.count && ta->rrs.rdata
+ && ta->type == KNOT_RRTYPE_DS
+ && knot_dname_is_equal(ta->owner, keys->owner);
+ if (kr_fails_assert(ok))
+ return kr_error(EINVAL);
+
+ /* RFC4035 5.2, bullet 1
+ * The supplied DS record has been authenticated.
+ * It has been validated or is part of a configured trust anchor.
+ */
+ knot_rdata_t *krr = keys->rrs.rdata;
+ for (int i = 0; i < keys->rrs.count; ++i, krr = knot_rdataset_next(krr)) {
+ /* RFC4035 5.3.1, bullet 8 */ /* ZSK */
+ if (!kr_dnssec_key_zsk(krr->data) || kr_dnssec_key_revoked(krr->data))
+ continue;
+
+ kr_svldr_key_t key;
+ if (svldr_key_new(krr, keys->owner, &key) != 0)
+ continue; // it might e.g. be malformed
+
+ int ret = kr_authenticate_referral(ta, key.key);
+ if (ret == 0)
+ ret = kr_svldr_rrset_with_key(keys, sigs, vctx, &key);
+ svldr_key_del(&key);
+ if (ret == 0) {
+ kr_assert(vctx->result == 0);
+ return vctx->result;
+ }
+ }
+
+ /* No useable key found */
+ vctx->result = kr_error(ENOENT);
+ return vctx->result;
+}
+
+bool kr_dnssec_key_zsk(const uint8_t *dnskey_rdata)
+{
+ return knot_wire_read_u16(dnskey_rdata) & 0x0100;
+}
+
+bool kr_dnssec_key_ksk(const uint8_t *dnskey_rdata)
+{
+ return knot_wire_read_u16(dnskey_rdata) & 0x0001;
+}
+
+/** Return true if the DNSKEY is revoked. */
+bool kr_dnssec_key_revoked(const uint8_t *dnskey_rdata)
+{
+ return knot_wire_read_u16(dnskey_rdata) & 0x0080;
+}
+
+int kr_dnssec_key_tag(uint16_t rrtype, const uint8_t *rdata, size_t rdlen)
+{
+ if (!rdata || rdlen == 0 || (rrtype != KNOT_RRTYPE_DS && rrtype != KNOT_RRTYPE_DNSKEY)) {
+ return kr_error(EINVAL);
+ }
+ if (rrtype == KNOT_RRTYPE_DS) {
+ return knot_wire_read_u16(rdata);
+ } else if (rrtype == KNOT_RRTYPE_DNSKEY) {
+ struct dnssec_key *key = NULL;
+ int ret = kr_dnssec_key_from_rdata(&key, NULL, rdata, rdlen);
+ if (ret != 0) {
+ return ret;
+ }
+ uint16_t keytag = dnssec_key_get_keytag(key);
+ kr_dnssec_key_free(&key);
+ return keytag;
+ } else {
+ return kr_error(EINVAL);
+ }
+}
+
+int kr_dnssec_key_match(const uint8_t *key_a_rdata, size_t key_a_rdlen,
+ const uint8_t *key_b_rdata, size_t key_b_rdlen)
+{
+ dnssec_key_t *key_a = NULL, *key_b = NULL;
+ int ret = kr_dnssec_key_from_rdata(&key_a, NULL, key_a_rdata, key_a_rdlen);
+ if (ret != 0) {
+ return ret;
+ }
+ ret = kr_dnssec_key_from_rdata(&key_b, NULL, key_b_rdata, key_b_rdlen);
+ if (ret != 0) {
+ dnssec_key_free(key_a);
+ return ret;
+ }
+ /* If the algorithm and the public key match, we can be sure
+ * that they are the same key. */
+ ret = kr_error(ENOENT);
+ dnssec_binary_t pk_a, pk_b;
+ if (dnssec_key_get_algorithm(key_a) == dnssec_key_get_algorithm(key_b) &&
+ dnssec_key_get_pubkey(key_a, &pk_a) == DNSSEC_EOK &&
+ dnssec_key_get_pubkey(key_b, &pk_b) == DNSSEC_EOK) {
+ if (pk_a.size == pk_b.size && memcmp(pk_a.data, pk_b.data, pk_a.size) == 0) {
+ ret = 0;
+ }
+ }
+ dnssec_key_free(key_a);
+ dnssec_key_free(key_b);
+ return ret;
+}
+
+int kr_dnssec_key_from_rdata(struct dnssec_key **key, const knot_dname_t *kown, const uint8_t *rdata, size_t rdlen)
+{
+ if (!key || !rdata || rdlen == 0) {
+ return kr_error(EINVAL);
+ }
+
+ dnssec_key_t *new_key = NULL;
+ const dnssec_binary_t binary_key = {
+ .size = rdlen,
+ .data = (uint8_t *)rdata
+ };
+
+ int ret = dnssec_key_new(&new_key);
+ if (ret != DNSSEC_EOK) {
+ return kr_error(ENOMEM);
+ }
+ ret = dnssec_key_set_rdata(new_key, &binary_key);
+ if (ret != DNSSEC_EOK) {
+ dnssec_key_free(new_key);
+ return kr_error(ret);
+ }
+ if (kown) {
+ ret = dnssec_key_set_dname(new_key, kown);
+ if (ret != DNSSEC_EOK) {
+ dnssec_key_free(new_key);
+ return kr_error(ENOMEM);
+ }
+ }
+
+ *key = new_key;
+ return kr_ok();
+}
+
+void kr_dnssec_key_free(struct dnssec_key **key)
+{
+ if (kr_fails_assert(key))
+ return;
+
+ dnssec_key_free(*key);
+ *key = NULL;
+}
+
+int kr_dnssec_matches_name_and_type(const ranked_rr_array_t *rrs, uint32_t qry_uid,
+ const knot_dname_t *name, uint16_t type)
+{
+ int ret = kr_error(ENOENT);
+ for (size_t i = 0; i < rrs->len; ++i) {
+ const ranked_rr_array_entry_t *entry = rrs->at[i];
+ if (kr_fails_assert(!entry->in_progress))
+ return kr_error(EINVAL);
+ const knot_rrset_t *nsec = entry->rr;
+ if (entry->qry_uid != qry_uid || entry->yielded) {
+ continue;
+ }
+ if (nsec->type != KNOT_RRTYPE_NSEC &&
+ nsec->type != KNOT_RRTYPE_NSEC3) {
+ continue;
+ }
+ if (!kr_rank_test(entry->rank, KR_RANK_SECURE)) {
+ continue;
+ }
+ if (nsec->type == KNOT_RRTYPE_NSEC) {
+ ret = kr_nsec_matches_name_and_type(nsec, name, type);
+ } else {
+ ret = kr_nsec3_matches_name_and_type(nsec, name, type);
+ }
+ if (ret == kr_ok()) {
+ return kr_ok();
+ } else if (ret != kr_error(ENOENT)) {
+ return ret;
+ }
+ }
+ return ret;
+}
diff --git a/lib/dnssec.h b/lib/dnssec.h
new file mode 100644
index 0000000..0fbd47c
--- /dev/null
+++ b/lib/dnssec.h
@@ -0,0 +1,191 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#include "lib/defines.h"
+#include "lib/utils.h"
+#include <libknot/packet/pkt.h>
+
+/**
+ * Initialise cryptographic back-end.
+ */
+KR_EXPORT
+void kr_crypto_init(void);
+
+/**
+ * De-initialise cryptographic back-end.
+ */
+KR_EXPORT
+void kr_crypto_cleanup(void);
+
+/**
+ * Re-initialise cryptographic back-end.
+ * @note Must be called after fork() in the child.
+ */
+KR_EXPORT
+void kr_crypto_reinit(void);
+
+#define KR_DNSSEC_VFLG_WEXPAND 0x01
+#define KR_DNSSEC_VFLG_OPTOUT 0x02
+
+/** DNSSEC validation context. */
+struct kr_rrset_validation_ctx {
+ const knot_pkt_t *pkt; /*!< Packet to be validated. */
+ ranked_rr_array_t *rrs; /*!< List of preselected RRs to be validated. */
+ knot_section_t section_id; /*!< Section to work with. */
+ knot_rrset_t *keys; /*!< DNSKEY RRSet; TTLs may get lowered when validating this set. */
+ const knot_dname_t *zone_name; /*!< Name of the zone containing the RRSIG RRSet. */
+ uint32_t timestamp; /*!< Validation time. */
+ uint32_t ttl_min; /*!< See trim_ttl() for details. */
+ bool has_nsec3; /*!< Whether to use NSEC3 validation. */
+ uint32_t qry_uid; /*!< Current query uid. */
+ uint32_t flags; /*!< Output - Flags. */
+ uint32_t err_cnt; /*!< Output - Number of validation failures. */
+ uint32_t cname_norrsig_cnt; /*!< Output - Number of CNAMEs missing RRSIGs. */
+
+ /** Validation result: kr_error() code.
+ *
+ * ENOENT: the usual, no suitable signature found
+ * EAGAIN: encountered a different signer name
+ * +others
+ */
+ int result;
+ const struct kr_query *log_qry; /*!< The query; just for logging purposes. */
+ struct {
+ unsigned int matching_name_type; /*!< Name + type matches */
+ unsigned int expired;
+ unsigned int notyet;
+ unsigned int signer_invalid; /*!< Signer is not zone apex */
+ unsigned int labels_invalid; /*!< Number of labels in RRSIG */
+ unsigned int key_invalid; /*!< Algorithm/keytag/key owner */
+ unsigned int crypto_invalid;
+ unsigned int nsec_invalid;
+ } rrs_counters; /*!< Error counters for single RRset validation. */
+};
+
+typedef struct kr_rrset_validation_ctx kr_rrset_validation_ctx_t;
+
+/**
+ * Validate RRSet.
+ * @param vctx Pointer to validation context.
+ * @param covered RRSet covered by a signature. It must be in canonical format.
+ * Its TTL may get lowered.
+ * @return 0 or kr_error() code, same as vctx->result (see its docs).
+ */
+int kr_rrset_validate(kr_rrset_validation_ctx_t *vctx, knot_rrset_t *covered);
+
+/**
+ * Return true iff the RRset contains at least one usable DS. See RFC6840 5.2.
+ */
+KR_EXPORT KR_PURE
+bool kr_ds_algo_support(const knot_rrset_t *ta);
+
+/**
+ * Check whether the DNSKEY rrset matches the supplied trust anchor RRSet.
+ *
+ * @param vctx Pointer to validation context. Note that TTL of vctx->keys may get lowered.
+ * @param sigs RRSIGs for this DNSKEY set
+ * @param ta Trusted DS RRSet against which to validate the DNSKEY RRSet.
+ * @return 0 or error code, same as vctx->result.
+ */
+int kr_dnskeys_trusted(kr_rrset_validation_ctx_t *vctx, const knot_rdataset_t *sigs,
+ const knot_rrset_t *ta);
+
+/** Return true if the DNSKEY can be used as a ZSK. */
+KR_EXPORT KR_PURE
+bool kr_dnssec_key_zsk(const uint8_t *dnskey_rdata);
+
+/** Return true if the DNSKEY indicates being KSK (=> has SEP). */
+KR_EXPORT KR_PURE
+bool kr_dnssec_key_ksk(const uint8_t *dnskey_rdata);
+
+/** Return true if the DNSKEY is revoked. */
+KR_EXPORT KR_PURE
+bool kr_dnssec_key_revoked(const uint8_t *dnskey_rdata);
+
+/** Return DNSKEY tag.
+ * @param rrtype RR type (either DS or DNSKEY are supported)
+ * @param rdata Key/digest RDATA.
+ * @param rdlen RDATA length.
+ * @return Key tag (positive number), or an error code
+ */
+KR_EXPORT KR_PURE
+int kr_dnssec_key_tag(uint16_t rrtype, const uint8_t *rdata, size_t rdlen);
+
+/** Return 0 if the two keys are identical.
+ * @note This compares RDATA only, algorithm and public key must match.
+ * @param key_a_rdata First key RDATA
+ * @param key_a_rdlen First key RDATA length
+ * @param key_b_rdata Second key RDATA
+ * @param key_b_rdlen Second key RDATA length
+ * @return 0 if they match or an error code
+ */
+KR_EXPORT KR_PURE
+int kr_dnssec_key_match(const uint8_t *key_a_rdata, size_t key_a_rdlen,
+ const uint8_t *key_b_rdata, size_t key_b_rdlen);
+
+/* Opaque DNSSEC key struct; forward declaration from libdnssec. */
+struct dnssec_key;
+
+/**
+ * Construct a DNSSEC key.
+ * @param key Pointer to be set to newly created DNSSEC key.
+ * @param kown DNSKEY owner name.
+ * @param rdata DNSKEY RDATA
+ * @param rdlen DNSKEY RDATA length
+ * @return 0 or error code; in particular: DNSSEC_INVALID_KEY_ALGORITHM
+ */
+int kr_dnssec_key_from_rdata(struct dnssec_key **key, const knot_dname_t *kown, const uint8_t *rdata, size_t rdlen);
+
+/**
+ * Frees the DNSSEC key.
+ * @param key Pointer to freed key.
+ */
+void kr_dnssec_key_free(struct dnssec_key **key);
+
+/**
+ * Checks whether NSEC/NSEC3 RR selected by iterator matches the supplied name and type.
+ * @param rrs Records selected by iterator.
+ * @param qry_uid Query unique identifier where NSEC/NSEC3 belongs to.
+ * @param name Name to be checked.
+ * @param type Type to be checked.
+ * @return 0 or error code.
+ */
+int kr_dnssec_matches_name_and_type(const ranked_rr_array_t *rrs, uint32_t qry_uid,
+ const knot_dname_t *name, uint16_t type);
+
+
+/* Simple validator API. Main use case: prefill module, i.e. RRs from a zone file. */
+
+/** Opaque context for simple validator. */
+struct kr_svldr_ctx;
+/**
+ * Create new context for validating within a given zone.
+ *
+ * - `ds` is assumed to be trusted, and it's used to validate `dnskey+dnskey_sigs`.
+ * - The TTL of `dnskey` may get trimmed.
+ * - The insides are placed on malloc heap (use _free_ctx).
+ * - `err_ctx` is optional, for use when error happens (but avoid the inside pointers)
+ */
+KR_EXPORT
+struct kr_svldr_ctx * kr_svldr_new_ctx(const knot_rrset_t *ds, knot_rrset_t *dnskey,
+ const knot_rdataset_t *dnskey_sigs, uint32_t timestamp,
+ kr_rrset_validation_ctx_t *err_ctx);
+/** Free the context. Passing NULL is OK. */
+KR_EXPORT
+void kr_svldr_free_ctx(struct kr_svldr_ctx *ctx);
+/**
+ * Validate an RRset with the associated signatures; assume no wildcard expansions.
+ *
+ * - It's caller's responsibility that rrsigs have matching owner, class and type.
+ * - The TTL of `rrs` may get trimmed.
+ * - If it's a wildcard other than in its simple `*.` form, it may fail to validate.
+ * - More generally, non-existence proofs are not supported.
+ * @return 0 or kr_error() code, same as kr_rrset_validation_ctx::result (see its docs).
+ */
+KR_EXPORT
+int kr_svldr_rrset(knot_rrset_t *rrs, const knot_rdataset_t *rrsigs,
+ struct kr_svldr_ctx *ctx);
+
diff --git a/lib/dnssec/nsec.c b/lib/dnssec/nsec.c
new file mode 100644
index 0000000..8b17247
--- /dev/null
+++ b/lib/dnssec/nsec.c
@@ -0,0 +1,315 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#include <stdlib.h>
+
+#include <libknot/descriptor.h>
+#include <libknot/dname.h>
+#include <libknot/packet/wire.h>
+#include <libknot/rrset.h>
+#include <libknot/rrtype/nsec.h>
+#include <libknot/rrtype/rrsig.h>
+#include <libdnssec/error.h>
+#include <libdnssec/nsec.h>
+
+#include "lib/defines.h"
+#include "lib/dnssec/nsec.h"
+#include "lib/utils.h"
+#include "resolve.h"
+
+int kr_nsec_children_in_zone_check(const uint8_t *bm, uint16_t bm_size)
+{
+ if (kr_fails_assert(bm))
+ return kr_error(EINVAL);
+ const bool parent_side =
+ dnssec_nsec_bitmap_contains(bm, bm_size, KNOT_RRTYPE_DNAME)
+ || (dnssec_nsec_bitmap_contains(bm, bm_size, KNOT_RRTYPE_NS)
+ && !dnssec_nsec_bitmap_contains(bm, bm_size, KNOT_RRTYPE_SOA)
+ );
+ return parent_side ? abs(ENOENT) : kr_ok();
+ /* LATER: after refactoring, probably also check if signer name equals owner,
+ * but even without that it's not possible to attack *correctly* signed zones.
+ */
+}
+
+/* This block of functions implements a "safe" version of knot_dname_cmp(),
+ * until that one handles in-label zero bytes correctly. */
+static int lf_cmp(const uint8_t *lf1, const uint8_t *lf2)
+{
+ /* Compare common part. */
+ uint8_t common = lf1[0];
+ if (common > lf2[0]) {
+ common = lf2[0];
+ }
+ int ret = memcmp(lf1 + 1, lf2 + 1, common);
+ if (ret != 0) {
+ return ret;
+ }
+
+ /* If they match, compare lengths. */
+ if (lf1[0] < lf2[0]) {
+ return -1;
+ } else if (lf1[0] > lf2[0]) {
+ return 1;
+ } else {
+ return 0;
+ }
+}
+static void dname_reverse(const knot_dname_t *src, size_t src_len, knot_dname_t *dst)
+{
+ knot_dname_t *idx = dst + src_len - 1;
+ kr_require(src[src_len - 1] == '\0');
+ *idx = '\0';
+
+ while (*src) {
+ uint16_t len = *src + 1;
+ idx -= len;
+ memcpy(idx, src, len);
+ src += len;
+ }
+ kr_require(idx == dst);
+}
+static int dname_cmp(const knot_dname_t *d1, const knot_dname_t *d2)
+{
+ size_t d1_len = knot_dname_size(d1);
+ size_t d2_len = knot_dname_size(d2);
+
+ knot_dname_t d1_rev_arr[d1_len], d2_rev_arr[d2_len];
+ const knot_dname_t *d1_rev = d1_rev_arr, *d2_rev = d2_rev_arr;
+
+ dname_reverse(d1, d1_len, d1_rev_arr);
+ dname_reverse(d2, d2_len, d2_rev_arr);
+
+ int res = 0;
+ while (res == 0 && d1_rev != NULL) {
+ res = lf_cmp(d1_rev, d2_rev);
+ d1_rev = knot_wire_next_label(d1_rev, NULL);
+ d2_rev = knot_wire_next_label(d2_rev, NULL);
+ }
+
+ kr_require(res != 0 || d2_rev == NULL);
+ return res;
+}
+
+
+/**
+ * Check whether this nsec proves that there is no closer match for sname.
+ *
+ * @param nsec NSEC RRSet.
+ * @param sname Searched name.
+ * @return 0 if proves, >0 if not (abs(ENOENT) or abs(EEXIST)), or error code (<0).
+ */
+static int nsec_covers(const knot_rrset_t *nsec, const knot_dname_t *sname)
+{
+ if (kr_fails_assert(nsec && sname))
+ return kr_error(EINVAL);
+ const int cmp = dname_cmp(sname, nsec->owner);
+ if (cmp < 0) return abs(ENOENT); /* 'sname' before 'owner', so can't be covered */
+ if (cmp == 0) return abs(EEXIST); /* matched, not covered */
+
+ /* We have to lower-case 'next' with libknot >= 2.7; see also RFC 6840 5.1. */
+ knot_dname_t next[KNOT_DNAME_MAXLEN];
+ int ret = knot_dname_to_wire(next, knot_nsec_next(nsec->rrs.rdata), sizeof(next));
+ if (kr_fails_assert(ret >= 0))
+ return kr_error(ret);
+ knot_dname_to_lower(next);
+
+ /* If NSEC 'owner' >= 'next', it means that there is nothing after 'owner' */
+ const bool is_last_nsec = dname_cmp(nsec->owner, next) >= 0;
+ const bool in_range = is_last_nsec || dname_cmp(sname, next) < 0;
+ if (!in_range)
+ return abs(ENOENT);
+ /* Before returning kr_ok(), we have to check a special case:
+ * sname might be under delegation from owner and thus
+ * not in the zone of this NSEC at all.
+ */
+ if (knot_dname_in_bailiwick(sname, nsec->owner) <= 0)
+ return kr_ok();
+ const uint8_t *bm = knot_nsec_bitmap(nsec->rrs.rdata);
+ uint16_t bm_size = knot_nsec_bitmap_len(nsec->rrs.rdata);
+
+ return kr_nsec_children_in_zone_check(bm, bm_size);
+}
+
+int kr_nsec_bitmap_nodata_check(const uint8_t *bm, uint16_t bm_size, uint16_t type, const knot_dname_t *owner)
+{
+ const int NO_PROOF = abs(ENOENT);
+ if (!bm || !owner)
+ return kr_error(EINVAL);
+ if (dnssec_nsec_bitmap_contains(bm, bm_size, type))
+ return NO_PROOF;
+
+ if (type != KNOT_RRTYPE_CNAME
+ && dnssec_nsec_bitmap_contains(bm, bm_size, KNOT_RRTYPE_CNAME)) {
+ return NO_PROOF;
+ }
+ /* Special behavior around zone cuts. */
+ switch (type) {
+ case KNOT_RRTYPE_DS:
+ /* Security feature: in case of DS also check for SOA
+ * non-existence to be more certain that we don't hold
+ * a child-side NSEC by some mistake (e.g. when forwarding).
+ * See RFC4035 5.2, next-to-last paragraph.
+ * This doesn't apply for root DS as it doesn't exist in DNS hierarchy.
+ */
+ if (owner[0] != '\0' && dnssec_nsec_bitmap_contains(bm, bm_size, KNOT_RRTYPE_SOA))
+ return NO_PROOF;
+ break;
+ case KNOT_RRTYPE_CNAME:
+ /* Exception from the `default` rule. It's perhaps disputable,
+ * but existence of CNAME at zone apex is not allowed, so we
+ * consider a parent-side record to be enough to prove non-existence. */
+ break;
+ default:
+ /* Parent-side delegation record isn't authoritative for non-DS;
+ * see RFC6840 4.1. */
+ if (dnssec_nsec_bitmap_contains(bm, bm_size, KNOT_RRTYPE_NS)
+ && !dnssec_nsec_bitmap_contains(bm, bm_size, KNOT_RRTYPE_SOA)) {
+ return NO_PROOF;
+ }
+ /* LATER(opt): perhaps short-circuit test if we repeat it here. */
+ }
+
+ return kr_ok();
+}
+
+/// Convenience wrapper for kr_nsec_bitmap_nodata_check()
+static int no_data_response_check_rrtype(const knot_rrset_t *nsec, uint16_t type)
+{
+ if (kr_fails_assert(nsec && nsec->type == KNOT_RRTYPE_NSEC))
+ return kr_error(EINVAL);
+ const uint8_t *bm = knot_nsec_bitmap(nsec->rrs.rdata);
+ uint16_t bm_size = knot_nsec_bitmap_len(nsec->rrs.rdata);
+ return kr_nsec_bitmap_nodata_check(bm, bm_size, type, nsec->owner);
+}
+
+int kr_nsec_wildcard_answer_response_check(const knot_pkt_t *pkt, knot_section_t section_id,
+ const knot_dname_t *sname)
+{
+ const knot_pktsection_t *sec = knot_pkt_section(pkt, section_id);
+ if (!sec || !sname)
+ return kr_error(EINVAL);
+
+ for (unsigned i = 0; i < sec->count; ++i) {
+ const knot_rrset_t *rrset = knot_pkt_rr(sec, i);
+ if (rrset->type != KNOT_RRTYPE_NSEC)
+ continue;
+ if (nsec_covers(rrset, sname) == 0)
+ return kr_ok();
+ }
+
+ return kr_error(ENOENT);
+}
+
+int kr_nsec_negative(const ranked_rr_array_t *rrrs, uint32_t qry_uid,
+ const knot_dname_t *sname, uint16_t stype)
+{
+ // We really only consider the (canonically) first NSEC in each RRset.
+ // Using same owner with differing content probably isn't useful for NSECs anyway.
+ // Many other parts of code do the same, too.
+ if (kr_fails_assert(rrrs && sname))
+ return kr_error(EINVAL);
+
+ // Terminology: https://datatracker.ietf.org/doc/html/rfc4592#section-3.3.1
+ int clencl_labels = -1; // the label count of the closest encloser of sname
+ for (int i = rrrs->len - 1; i >= 0; --i) { // NSECs near the end typically
+ const knot_rrset_t *nsec = rrrs->at[i]->rr;
+ bool ok = rrrs->at[i]->qry_uid == qry_uid
+ && nsec->type == KNOT_RRTYPE_NSEC
+ && kr_rank_test(rrrs->at[i]->rank, KR_RANK_SECURE);
+ if (!ok) continue;
+ const int covers = nsec_covers(nsec, sname);
+ if (covers == abs(EEXIST)
+ && no_data_response_check_rrtype(nsec, stype) == 0) {
+ return PKT_NODATA; // proven NODATA by matching NSEC
+ }
+ if (covers != 0) continue;
+
+ // We have to lower-case 'next' with libknot >= 2.7; see also RFC 6840 5.1.
+ // LATER(optim.): it's duplicate work with the nsec_covers() call.
+ knot_dname_t next[KNOT_DNAME_MAXLEN];
+ int ret = knot_dname_to_wire(next, knot_nsec_next(nsec->rrs.rdata), sizeof(next));
+ if (kr_fails_assert(ret >= 0))
+ return kr_error(ret);
+ knot_dname_to_lower(next);
+
+ clencl_labels = MAX(knot_dname_matched_labels(nsec->owner, sname),
+ knot_dname_matched_labels(sname, next));
+ break; // reduce indentation again
+ }
+
+ if (clencl_labels < 0)
+ return kr_error(ENOENT);
+ const int sname_labels = knot_dname_labels(sname, NULL);
+ if (sname_labels == clencl_labels)
+ return PKT_NODATA; // proven NODATA; sname is an empty non-terminal
+
+ // Explicitly construct name for the corresponding source of synthesis.
+ knot_dname_t ssynth[KNOT_DNAME_MAXLEN + 2];
+ ssynth[0] = 1;
+ ssynth[1] = '*';
+ const knot_dname_t *clencl = sname;
+ for (int l = sname_labels; l > clencl_labels; --l)
+ clencl = knot_wire_next_label(clencl, NULL);
+ (void)!!knot_dname_store(&ssynth[2], clencl);
+
+ // Try to (dis)prove the source of synthesis by a covering or matching NSEC.
+ for (int i = rrrs->len - 1; i >= 0; --i) { // NSECs near the end typically
+ const knot_rrset_t *nsec = rrrs->at[i]->rr;
+ bool ok = rrrs->at[i]->qry_uid == qry_uid
+ && nsec->type == KNOT_RRTYPE_NSEC
+ && kr_rank_test(rrrs->at[i]->rank, KR_RANK_SECURE);
+ if (!ok) continue;
+ const int covers = nsec_covers(nsec, ssynth);
+ if (covers == abs(EEXIST)) {
+ int ret = no_data_response_check_rrtype(nsec, stype);
+ if (ret == 0) return PKT_NODATA; // proven NODATA by wildcard NSEC
+ // TODO: also try expansion? Or at least a different return code?
+ } else if (covers == 0) {
+ return PKT_NXDOMAIN | PKT_NODATA;
+ }
+ }
+ return kr_error(ENOENT);
+}
+
+int kr_nsec_ref_to_unsigned(const ranked_rr_array_t *rrrs, uint32_t qry_uid,
+ const knot_dname_t *sname)
+{
+ for (int i = rrrs->len - 1; i >= 0; --i) { // NSECs near the end typically
+ const knot_rrset_t *nsec = rrrs->at[i]->rr;
+ bool ok = rrrs->at[i]->qry_uid == qry_uid
+ && nsec->type == KNOT_RRTYPE_NSEC
+ && kr_rank_test(rrrs->at[i]->rank, KR_RANK_SECURE)
+ // avoid any possibility of getting tricked in deeper zones
+ && knot_dname_in_bailiwick(sname, nsec->owner) >= 0;
+ if (!ok) continue;
+
+ kr_assert(nsec->rrs.rdata);
+ const uint8_t *bm = knot_nsec_bitmap(nsec->rrs.rdata);
+ uint16_t bm_size = knot_nsec_bitmap_len(nsec->rrs.rdata);
+ ok = ok && dnssec_nsec_bitmap_contains(bm, bm_size, KNOT_RRTYPE_NS)
+ && !dnssec_nsec_bitmap_contains(bm, bm_size, KNOT_RRTYPE_DS)
+ && !dnssec_nsec_bitmap_contains(bm, bm_size, KNOT_RRTYPE_SOA);
+ if (ok) return kr_ok();
+ }
+ return kr_error(DNSSEC_NOT_FOUND);
+}
+
+int kr_nsec_matches_name_and_type(const knot_rrset_t *nsec,
+ const knot_dname_t *name, uint16_t type)
+{
+ /* It's not secure enough to just check a single bit for (some) other types,
+ * but we (currently) only use this API for NS. See RFC 6840 sec. 4. */
+ if (kr_fails_assert(type == KNOT_RRTYPE_NS && nsec && nsec->rrs.rdata && name))
+ return kr_error(EINVAL);
+ if (!knot_dname_is_equal(nsec->owner, name))
+ return kr_error(ENOENT);
+ const uint8_t *bm = knot_nsec_bitmap(nsec->rrs.rdata);
+ uint16_t bm_size = knot_nsec_bitmap_len(nsec->rrs.rdata);
+ if (dnssec_nsec_bitmap_contains(bm, bm_size, type)) {
+ return kr_ok();
+ } else {
+ return kr_error(ENOENT);
+ }
+}
diff --git a/lib/dnssec/nsec.h b/lib/dnssec/nsec.h
new file mode 100644
index 0000000..a173fa5
--- /dev/null
+++ b/lib/dnssec/nsec.h
@@ -0,0 +1,69 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#include <libknot/packet/pkt.h>
+
+#include "lib/layer/iterate.h"
+
+/**
+ * Check bitmap that child names are contained in the same zone.
+ * @note see RFC6840 4.1.
+ * @param bm Bitmap from NSEC or NSEC3.
+ * @param bm_size Bitmap size.
+ * @return 0 if they are, >0 if not (abs(ENOENT)), <0 on error.
+ */
+int kr_nsec_children_in_zone_check(const uint8_t *bm, uint16_t bm_size);
+
+/**
+ * Check an NSEC or NSEC3 bitmap for NODATA for a type.
+ * @param bm Bitmap.
+ * @param bm_size Bitmap size.
+ * @param type RR type to check.
+ * @param owner NSEC record owner.
+ * @note This includes special checks for zone cuts, e.g. from RFC 6840 sec. 4.
+ * @return 0, abs(ENOENT) (no proof), kr_error(EINVAL)
+ */
+int kr_nsec_bitmap_nodata_check(const uint8_t *bm, uint16_t bm_size, uint16_t type, const knot_dname_t *owner);
+
+/**
+ * Wildcard answer response check (RFC4035 3.1.3.3).
+ * @param pkt Packet structure to be processed.
+ * @param section_id Packet section to be processed.
+ * @param sname Name to be checked.
+ * @return 0 or error code.
+ */
+int kr_nsec_wildcard_answer_response_check(const knot_pkt_t *pkt, knot_section_t section_id,
+ const knot_dname_t *sname);
+
+/**
+ * Search for a negative proof for sname+stype among validated NSECs.
+ *
+ * @param rrrs list of RRs to search; typically kr_request::auth_selected
+ * @param qry_uid only consider NSECs from this packet, for better efficiency
+ * @return negative error code, or PKT_NXDOMAIN | PKT_NODATA (both for NXDOMAIN)
+ */
+int kr_nsec_negative(const ranked_rr_array_t *rrrs, uint32_t qry_uid,
+ const knot_dname_t *sname, uint16_t stype);
+
+/**
+ * Referral to unsigned subzone check (RFC4035 5.2).
+ *
+ * @param rrrs list of RRs to search; typically kr_request::auth_selected
+ * @param qry_uid only consider NSECs from this packet, for better efficiency
+ * @return 0 or negative error code, in particular DNSSEC_NOT_FOUND
+ */
+int kr_nsec_ref_to_unsigned(const ranked_rr_array_t *rrrs, uint32_t qry_uid,
+ const knot_dname_t *sname);
+
+/**
+ * Checks whether supplied NSEC RR matches the supplied name and type.
+ * @param nsec NSEC RR.
+ * @param name Name to be checked.
+ * @param type Type to be checked. Only use with NS! TODO (+copy&paste NSEC3)
+ * @return 0 or error code.
+ */
+int kr_nsec_matches_name_and_type(const knot_rrset_t *nsec,
+ const knot_dname_t *name, uint16_t type);
diff --git a/lib/dnssec/nsec3.c b/lib/dnssec/nsec3.c
new file mode 100644
index 0000000..037d5bd
--- /dev/null
+++ b/lib/dnssec/nsec3.c
@@ -0,0 +1,722 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#include <string.h>
+
+#include <libdnssec/binary.h>
+#include <libdnssec/error.h>
+#include <libdnssec/nsec.h>
+#include <libknot/descriptor.h>
+#include <contrib/base32hex.h>
+#include <libknot/rrset.h>
+#include <libknot/rrtype/nsec3.h>
+
+#include "lib/defines.h"
+#include "lib/dnssec/nsec.h"
+#include "lib/dnssec/nsec3.h"
+#include "lib/utils.h"
+
+#define OPT_OUT_BIT 0x01
+
+//#define FLG_CLOSEST_ENCLOSER (1 << 0)
+#define FLG_CLOSEST_PROVABLE_ENCLOSER (1 << 1)
+#define FLG_NAME_COVERED (1 << 2)
+#define FLG_NAME_MATCHED (1 << 3)
+#define FLG_TYPE_BIT_MISSING (1 << 4)
+#define FLG_CNAME_BIT_MISSING (1 << 5)
+
+/**
+ * Obtains NSEC3 parameters from RR.
+ * @param params NSEC3 parameters structure to be set.
+ * @param nsec3 NSEC3 RR containing the parameters.
+ * @return 0 or error code.
+ */
+static int nsec3_parameters(dnssec_nsec3_params_t *params, const knot_rrset_t *nsec3)
+{
+ if (kr_fails_assert(params && nsec3))
+ return kr_error(EINVAL);
+
+ const knot_rdata_t *rr = knot_rdataset_at(&nsec3->rrs, 0);
+ if (kr_fails_assert(rr))
+ return kr_error(EINVAL);
+
+ /* Every NSEC3 RR contains data from NSEC3PARAMS. */
+ const size_t SALT_OFFSET = 5; /* First 5 octets contain { Alg, Flags, Iterations, Salt length } */
+ dnssec_binary_t rdata = {
+ .size = SALT_OFFSET + (size_t)knot_nsec3_salt_len(nsec3->rrs.rdata),
+ .data = /*const-cast*/(uint8_t *)rr->data,
+ };
+ if (rdata.size > rr->len)
+ return kr_error(EMSGSIZE);
+
+ int ret = dnssec_nsec3_params_from_rdata(params, &rdata);
+ if (ret != DNSSEC_EOK)
+ return kr_error(EINVAL);
+
+ return kr_ok();
+}
+
+/**
+ * Computes a hash of a given domain name.
+ * @param hash Resulting hash, must be freed.
+ * @param params NSEC3 parameters.
+ * @param name Domain name to be hashed.
+ * @return 0 or error code.
+ */
+static int hash_name(dnssec_binary_t *hash, const dnssec_nsec3_params_t *params,
+ const knot_dname_t *name)
+{
+ if (kr_fails_assert(hash && params))
+ return kr_error(EINVAL);
+ if (!name)
+ return kr_error(EINVAL);
+ if (kr_fails_assert(params->iterations <= KR_NSEC3_MAX_ITERATIONS)) {
+ /* This if is mainly defensive; it shouldn't happen. */
+ return kr_error(EINVAL);
+ }
+
+ dnssec_binary_t dname = {
+ .size = knot_dname_size(name),
+ .data = (uint8_t *) name,
+ };
+
+ int ret = dnssec_nsec3_hash(&dname, params, hash);
+ if (ret != DNSSEC_EOK) {
+ return kr_error(EINVAL);
+ }
+
+ return kr_ok();
+}
+
+/**
+ * Read hash from NSEC3 owner name and store its binary form.
+ * @param hash Buffer to be written.
+ * @param max_hash_size Maximal has size.
+ * @param nsec3 NSEC3 RR.
+ * @return 0 or error code.
+ */
+static int read_owner_hash(dnssec_binary_t *hash, size_t max_hash_size, const knot_rrset_t *nsec3)
+{
+ if (kr_fails_assert(hash && nsec3 && hash->data))
+ return kr_error(EINVAL);
+
+ int32_t ret = base32hex_decode(nsec3->owner + 1, nsec3->owner[0], hash->data, max_hash_size);
+ if (ret < 0)
+ return kr_error(EILSEQ);
+ hash->size = ret;
+
+ return kr_ok();
+}
+
+#define MAX_HASH_BYTES 64
+/**
+ * Closest (provable) encloser match (RFC5155 7.2.1, bullet 1).
+ * @param flags Flags to be set according to check outcome.
+ * @param nsec3 NSEC3 RR.
+ * @param name Name to be checked.
+ * @param skipped Number of skipped labels to find closest (provable) match.
+ * @return 0 or error code.
+ */
+static int closest_encloser_match(int *flags, const knot_rrset_t *nsec3,
+ const knot_dname_t *name, unsigned *skipped)
+{
+ if (kr_fails_assert(flags && nsec3 && name && skipped))
+ return kr_error(EINVAL);
+
+ uint8_t hash_data[MAX_HASH_BYTES] = {0, };
+ dnssec_binary_t owner_hash = { 0, hash_data };
+ dnssec_nsec3_params_t params = { 0, };
+ dnssec_binary_t name_hash = { 0, };
+
+ int ret = read_owner_hash(&owner_hash, MAX_HASH_BYTES, nsec3);
+ if (ret != 0)
+ goto fail;
+
+ ret = nsec3_parameters(&params, nsec3);
+ if (ret != 0)
+ goto fail;
+
+ /* Root label has no encloser */
+ if (!name[0]) {
+ ret = kr_error(ENOENT);
+ goto fail;
+ }
+
+ const knot_dname_t *encloser = knot_wire_next_label(name, NULL);
+ *skipped = 1;
+
+ while(encloser) {
+ ret = hash_name(&name_hash, &params, encloser);
+ if (ret != 0)
+ goto fail;
+
+ if ((owner_hash.size == name_hash.size) &&
+ (memcmp(owner_hash.data, name_hash.data, owner_hash.size) == 0)) {
+ dnssec_binary_free(&name_hash);
+ *flags |= FLG_CLOSEST_PROVABLE_ENCLOSER;
+ break;
+ }
+
+ dnssec_binary_free(&name_hash);
+
+ if (!encloser[0])
+ break;
+ encloser = knot_wire_next_label(encloser, NULL);
+ ++(*skipped);
+ }
+
+ ret = kr_ok();
+
+fail:
+ if (params.salt.data)
+ dnssec_nsec3_params_free(&params);
+ if (name_hash.data)
+ dnssec_binary_free(&name_hash);
+ return ret;
+}
+
+/**
+ * Checks whether NSEC3 RR covers the supplied name (RFC5155 7.2.1, bullet 2).
+ * @param flags Flags to be set according to check outcome.
+ * @param nsec3 NSEC3 RR.
+ * @param name Name to be checked.
+ * @return 0 or error code.
+ */
+static int covers_name(int *flags, const knot_rrset_t *nsec3, const knot_dname_t *name)
+{
+ if (kr_fails_assert(flags && nsec3 && name))
+ return kr_error(EINVAL);
+
+ uint8_t hash_data[MAX_HASH_BYTES] = { 0, };
+ dnssec_binary_t owner_hash = { 0, hash_data };
+ dnssec_nsec3_params_t params = { 0, };
+ dnssec_binary_t name_hash = { 0, };
+
+ int ret = read_owner_hash(&owner_hash, MAX_HASH_BYTES, nsec3);
+ if (ret != 0)
+ goto fail;
+
+ ret = nsec3_parameters(&params, nsec3);
+ if (ret != 0)
+ goto fail;
+
+ ret = hash_name(&name_hash, &params, name);
+ if (ret != 0)
+ goto fail;
+
+ uint8_t next_size = knot_nsec3_next_len(nsec3->rrs.rdata);
+ const uint8_t *next_hash = knot_nsec3_next(nsec3->rrs.rdata);
+
+ if ((next_size > 0) && (owner_hash.size == next_size) && (name_hash.size == next_size)) {
+ /* All hash lengths must be same. */
+ const uint8_t *ownerd = owner_hash.data;
+ const uint8_t *nextd = next_hash;
+ int covered = 0;
+ int greater_then_owner = (memcmp(ownerd, name_hash.data, next_size) < 0);
+ int less_then_next = (memcmp(name_hash.data, nextd, next_size) < 0);
+ if (memcmp(ownerd, nextd, next_size) < 0) {
+ /*
+ * 0 (...) owner ... next (...) MAX
+ * ^
+ * name
+ * ==>
+ * (owner < name) && (name < next)
+ */
+ covered = ((greater_then_owner) && (less_then_next));
+ } else {
+ /*
+ * owner ... MAX, 0 ... next
+ * ^ ^ ^
+ * name name name
+ * =>
+ * (owner < name) || (name < next)
+ */
+ covered = ((greater_then_owner) || (less_then_next));
+ }
+
+ if (covered) {
+ *flags |= FLG_NAME_COVERED;
+
+ uint8_t nsec3_flags = knot_nsec3_flags(nsec3->rrs.rdata);
+ if (nsec3_flags & ~OPT_OUT_BIT) {
+ /* RFC5155 3.1.2 */
+ ret = kr_error(EINVAL);
+ } else {
+ ret = kr_ok();
+ }
+ }
+ }
+
+fail:
+ if (params.salt.data)
+ dnssec_nsec3_params_free(&params);
+ if (name_hash.data)
+ dnssec_binary_free(&name_hash);
+ return ret;
+}
+
+/**
+ * Checks whether NSEC3 RR has the opt-out bit set.
+ * @param flags Flags to be set according to check outcome.
+ * @param nsec3 NSEC3 RR.
+ * @param name Name to be checked.
+ * @return 0 or error code.
+ */
+static bool has_optout(const knot_rrset_t *nsec3)
+{
+ if (!nsec3)
+ return false;
+
+ uint8_t nsec3_flags = knot_nsec3_flags(nsec3->rrs.rdata);
+ if (nsec3_flags & ~OPT_OUT_BIT) {
+ /* RFC5155 3.1.2 */
+ return false;
+ }
+
+ return nsec3_flags & OPT_OUT_BIT;
+}
+
+/**
+ * Checks whether NSEC3 RR matches the supplied name.
+ * @param flags Flags to be set according to check outcome.
+ * @param nsec3 NSEC3 RR.
+ * @param name Name to be checked.
+ * @return 0 if matching, >0 if not (abs(ENOENT)), or error code (<0).
+ */
+static int matches_name(const knot_rrset_t *nsec3, const knot_dname_t *name)
+{
+ if (kr_fails_assert(nsec3 && name))
+ return kr_error(EINVAL);
+
+ uint8_t hash_data[MAX_HASH_BYTES] = { 0, };
+ dnssec_binary_t owner_hash = { 0, hash_data };
+ dnssec_nsec3_params_t params = { 0, };
+ dnssec_binary_t name_hash = { 0, };
+
+ int ret = read_owner_hash(&owner_hash, MAX_HASH_BYTES, nsec3);
+ if (ret != 0)
+ goto fail;
+
+ ret = nsec3_parameters(&params, nsec3);
+ if (ret != 0)
+ goto fail;
+
+ ret = hash_name(&name_hash, &params, name);
+ if (ret != 0)
+ goto fail;
+
+ if ((owner_hash.size == name_hash.size) &&
+ (memcmp(owner_hash.data, name_hash.data, owner_hash.size) == 0)) {
+ ret = kr_ok();
+ } else {
+ ret = abs(ENOENT);
+ }
+
+fail:
+ if (params.salt.data)
+ dnssec_nsec3_params_free(&params);
+ if (name_hash.data)
+ dnssec_binary_free(&name_hash);
+ return ret;
+}
+#undef MAX_HASH_BYTES
+
+/**
+ * Prepends an asterisk label to given name.
+ *
+ * @param tgt Target buffer to write domain name into.
+ * @param name Name to be added to the asterisk.
+ * @return Size of the resulting name or error code.
+ */
+static int prepend_asterisk(uint8_t *tgt, size_t maxlen, const knot_dname_t *name)
+{
+ if (kr_fails_assert(maxlen >= 3))
+ return kr_error(EINVAL);
+ memcpy(tgt, "\1*", 3);
+ return knot_dname_to_wire(tgt + 2, name, maxlen - 2);
+}
+
+/**
+ * Closest encloser proof (RFC5155 7.2.1).
+ * @note No RRSIGs are validated.
+ * @param pkt Packet structure to be processed.
+ * @param section_id Packet section to be processed.
+ * @param sname Name to be checked.
+ * @param encloser_name Returned matching encloser name, if found.
+ * @param matching_encloser_nsec3 Pointer to matching encloser NSEC RRSet.
+ * @param covering_next_nsec3 Pointer to covering next closer NSEC3 RRSet.
+ * @return 0 or error code.
+ */
+static int closest_encloser_proof(const knot_pkt_t *pkt,
+ knot_section_t section_id,
+ const knot_dname_t *sname,
+ const knot_dname_t **encloser_name,
+ const knot_rrset_t **matching_encloser_nsec3,
+ const knot_rrset_t **covering_next_nsec3)
+{
+ const knot_pktsection_t *sec = knot_pkt_section(pkt, section_id);
+ if (!sec || !sname)
+ return kr_error(EINVAL);
+
+ const knot_rrset_t *matching = NULL;
+ const knot_rrset_t *covering = NULL;
+
+ int flags = 0;
+ const knot_dname_t *next_closer = NULL;
+ for (unsigned i = 0; i < sec->count; ++i) {
+ const knot_rrset_t *rrset = knot_pkt_rr(sec, i);
+ if (rrset->type != KNOT_RRTYPE_NSEC3)
+ continue;
+ /* Also skip the NSEC3-to-match an ancestor of sname if it's
+ * a parent-side delegation, as that would mean the owner
+ * does not really exist (authoritatively in this zone,
+ * even in case of opt-out).
+ */
+ const uint8_t *bm = knot_nsec3_bitmap(rrset->rrs.rdata);
+ uint16_t bm_size = knot_nsec3_bitmap_len(rrset->rrs.rdata);
+ if (kr_nsec_children_in_zone_check(bm, bm_size) != 0)
+ continue; /* no fatal errors from bad RRs */
+ /* Match the NSEC3 to sname or one of its ancestors. */
+ unsigned skipped = 0;
+ flags = 0;
+ int ret = closest_encloser_match(&flags, rrset, sname, &skipped);
+ if (ret != 0)
+ return ret;
+ if (!(flags & FLG_CLOSEST_PROVABLE_ENCLOSER))
+ continue;
+ matching = rrset;
+ /* Construct the next closer name and try to cover it. */
+ --skipped;
+ next_closer = sname;
+ for (unsigned j = 0; j < skipped; ++j) {
+ if (kr_fails_assert(next_closer[0]))
+ return kr_error(EINVAL);
+ next_closer = knot_wire_next_label(next_closer, NULL);
+ }
+ for (unsigned j = 0; j < sec->count; ++j) {
+ const knot_rrset_t *rrset_j = knot_pkt_rr(sec, j);
+ if (rrset_j->type != KNOT_RRTYPE_NSEC3)
+ continue;
+ ret = covers_name(&flags, rrset_j, next_closer);
+ if (ret != 0)
+ return ret;
+ if (flags & FLG_NAME_COVERED) {
+ covering = rrset_j;
+ break;
+ }
+ }
+ if (flags & FLG_NAME_COVERED)
+ break;
+ flags = 0; //
+ }
+
+ if ((flags & FLG_CLOSEST_PROVABLE_ENCLOSER) && (flags & FLG_NAME_COVERED) && next_closer) {
+ if (encloser_name && next_closer[0])
+ *encloser_name = knot_wire_next_label(next_closer, NULL);
+ if (matching_encloser_nsec3)
+ *matching_encloser_nsec3 = matching;
+ if (covering_next_nsec3)
+ *covering_next_nsec3 = covering;
+ return kr_ok();
+ }
+
+ return kr_error(ENOENT);
+}
+
+/**
+ * Check whether any NSEC3 RR covers a wildcard RR at the closer encloser.
+ * @param pkt Packet structure to be processed.
+ * @param section_id Packet section to be processed.
+ * @param encloser Closest (provable) encloser domain name.
+ * @return 0 or error code:
+ * KNOT_ERANGE - NSEC3 RR (that covers a wildcard)
+ * has been found, but has opt-out flag set;
+ * otherwise - error.
+ */
+static int covers_closest_encloser_wildcard(const knot_pkt_t *pkt, knot_section_t section_id,
+ const knot_dname_t *encloser)
+{
+ const knot_pktsection_t *sec = knot_pkt_section(pkt, section_id);
+ if (!sec || !encloser)
+ return kr_error(EINVAL);
+
+ uint8_t wildcard[KNOT_DNAME_MAXLEN];
+ wildcard[0] = 1;
+ wildcard[1] = '*';
+ int encloser_len = knot_dname_size(encloser);
+ if (encloser_len < 0)
+ return encloser_len;
+ memcpy(wildcard + 2, encloser, encloser_len);
+
+ int flags = 0;
+ for (unsigned i = 0; i < sec->count; ++i) {
+ const knot_rrset_t *rrset = knot_pkt_rr(sec, i);
+ if (rrset->type != KNOT_RRTYPE_NSEC3)
+ continue;
+ int ret = covers_name(&flags, rrset, wildcard);
+ if (ret != 0)
+ return ret;
+ if (flags & FLG_NAME_COVERED) {
+ return has_optout(rrset) ?
+ kr_error(KNOT_ERANGE) : kr_ok();
+ }
+ }
+
+ return kr_error(ENOENT);
+}
+
+int kr_nsec3_name_error_response_check(const knot_pkt_t *pkt, knot_section_t section_id,
+ const knot_dname_t *sname)
+{
+ const knot_dname_t *encloser = NULL;
+ const knot_rrset_t *covering_next_nsec3 = NULL;
+ int ret = closest_encloser_proof(pkt, section_id, sname,
+ &encloser, NULL, &covering_next_nsec3);
+ if (ret != 0)
+ return ret;
+ ret = covers_closest_encloser_wildcard(pkt, section_id, encloser);
+ if (ret != 0) {
+ /* OK, but NSEC3 for wildcard at encloser has opt-out;
+ * or error */
+ return ret;
+ }
+ /* Closest encloser proof is OK and
+ * NSEC3 for wildcard has been found and optout flag is not set.
+ * Now check if NSEC3 that covers next closer name has opt-out. */
+ return has_optout(covering_next_nsec3) ?
+ kr_error(KNOT_ERANGE) : kr_ok();
+}
+
+/**
+ * Search the packet section for a matching NSEC3 with nodata-proving bitmap.
+ * @param pkt Packet structure to be processed.
+ * @param section_id Packet section to be processed.
+ * @param sname Name to be checked.
+ * @param stype Type to be checked.
+ * @return 0 or error code.
+ * @note This does NOT check the opt-out case if type is DS;
+ * see RFC 5155 8.6.
+ */
+static int nodata_find(const knot_pkt_t *pkt, knot_section_t section_id,
+ const knot_dname_t *name, const uint16_t type)
+{
+ const knot_pktsection_t *sec = knot_pkt_section(pkt, section_id);
+ if (!sec || !name)
+ return kr_error(EINVAL);
+
+ for (unsigned i = 0; i < sec->count; ++i) {
+ const knot_rrset_t *nsec3 = knot_pkt_rr(sec, i);
+ /* Records causing any errors are simply skipped. */
+ if (nsec3->type != KNOT_RRTYPE_NSEC3
+ || matches_name(nsec3, name) != kr_ok()) {
+ continue;
+ /* LATER(optim.): we repeatedly recompute the hash of `name` */
+ }
+
+ const uint8_t *bm = knot_nsec3_bitmap(nsec3->rrs.rdata);
+ uint16_t bm_size = knot_nsec3_bitmap_len(nsec3->rrs.rdata);
+ if (kr_nsec_bitmap_nodata_check(bm, bm_size, type, nsec3->owner) == kr_ok())
+ return kr_ok();
+ }
+
+ return kr_error(ENOENT);
+}
+
+/**
+ * Check whether NSEC3 RR matches a wildcard at the closest encloser and has given type bit missing.
+ * @param pkt Packet structure to be processed.
+ * @param section_id Packet section to be processed.
+ * @param encloser Closest (provable) encloser domain name.
+ * @param stype Type to be checked.
+ * @return 0 or error code.
+ */
+static int matches_closest_encloser_wildcard(const knot_pkt_t *pkt, knot_section_t section_id,
+ const knot_dname_t *encloser, uint16_t stype)
+{
+ const knot_pktsection_t *sec = knot_pkt_section(pkt, section_id);
+ if (!sec || !encloser)
+ return kr_error(EINVAL);
+
+ uint8_t wildcard[KNOT_DNAME_MAXLEN]; /**< the source of synthesis */
+ int ret = prepend_asterisk(wildcard, sizeof(wildcard), encloser);
+ if (ret < 0)
+ return ret;
+ kr_require(ret >= 3);
+ return nodata_find(pkt, section_id, wildcard, stype);
+}
+
+int kr_nsec3_wildcard_answer_response_check(const knot_pkt_t *pkt, knot_section_t section_id,
+ const knot_dname_t *sname, int trim_to_next)
+{
+ const knot_pktsection_t *sec = knot_pkt_section(pkt, section_id);
+ if (!sec || !sname)
+ return kr_error(EINVAL);
+
+ /* Compute the next closer name. */
+ for (int i = 0; i < trim_to_next; ++i) {
+ if (kr_fails_assert(sname[0]))
+ return kr_error(EINVAL);
+ sname = knot_wire_next_label(sname, NULL);
+ }
+
+ int flags = 0;
+ for (unsigned i = 0; i < sec->count; ++i) {
+ const knot_rrset_t *rrset = knot_pkt_rr(sec, i);
+ if (rrset->type != KNOT_RRTYPE_NSEC3)
+ continue;
+ if (knot_nsec3_iters(rrset->rrs.rdata) > KR_NSEC3_MAX_ITERATIONS) {
+ /* Avoid hashing with too many iterations.
+ * If we get here, the `sname` wildcard probably ends up bogus,
+ * but it gets downgraded to KR_RANK_INSECURE when validator
+ * gets to verifying one of these over-limit NSEC3 RRs. */
+ continue;
+ }
+ int ret = covers_name(&flags, rrset, sname);
+ if (ret != 0)
+ return ret;
+ if (flags & FLG_NAME_COVERED) {
+ return has_optout(rrset) ?
+ kr_error(KNOT_ERANGE) : kr_ok();
+ }
+ }
+
+ return kr_error(ENOENT);
+}
+
+
+int kr_nsec3_no_data(const knot_pkt_t *pkt, knot_section_t section_id,
+ const knot_dname_t *sname, uint16_t stype)
+{
+ /* DS record may be also matched by an existing NSEC3 RR. */
+ int ret = nodata_find(pkt, section_id, sname, stype);
+ if (ret == 0) {
+ /* Satisfies RFC5155 8.5 and 8.6, both first paragraph. */
+ return ret;
+ }
+
+ /* Find closest provable encloser. */
+ const knot_dname_t *encloser_name = NULL;
+ const knot_rrset_t *covering_next_nsec3 = NULL;
+ ret = closest_encloser_proof(pkt, section_id, sname, &encloser_name,
+ NULL, &covering_next_nsec3);
+ if (ret != 0)
+ return ret;
+
+ if (kr_fails_assert(encloser_name && covering_next_nsec3))
+ return kr_error(EFAULT);
+ ret = matches_closest_encloser_wildcard(pkt, section_id,
+ encloser_name, stype);
+ if (ret == 0) {
+ /* Satisfies RFC5155 8.7 */
+ if (has_optout(covering_next_nsec3)) {
+ /* Opt-out is detected.
+ * Despite the fact that all records
+ * in the packet can be properly signed,
+ * AD bit must not be set due to rfc5155 9.2.
+ * Return appropriate code to the caller */
+ ret = kr_error(KNOT_ERANGE);
+ }
+ return ret;
+ }
+
+ if (!has_optout(covering_next_nsec3)) {
+ /* Bogus */
+ ret = kr_error(ENOENT);
+ } else {
+ /*
+ * Satisfies RFC5155 8.6 (QTYPE == DS), 2nd paragraph.
+ * Also satisfies ERRATA 3441 8.5 (QTYPE != DS), 3rd paragraph.
+ * - (wildcard) empty nonterminal
+ * derived from insecure delegation.
+ * Denial of existence can not be proven.
+ * Set error code to proceed insecure.
+ */
+ ret = kr_error(KNOT_ERANGE);
+ }
+
+ return ret;
+}
+
+int kr_nsec3_ref_to_unsigned(const knot_pkt_t *pkt)
+{
+ const knot_pktsection_t *sec = knot_pkt_section(pkt, KNOT_AUTHORITY);
+ if (!sec)
+ return kr_error(EINVAL);
+ for (unsigned i = 0; i < sec->count; ++i) {
+ const knot_rrset_t *ns = knot_pkt_rr(sec, i);
+ if (ns->type == KNOT_RRTYPE_DS)
+ return kr_error(EEXIST);
+ if (ns->type != KNOT_RRTYPE_NS)
+ continue;
+
+ bool nsec3_found = false;
+ for (unsigned j = 0; j < sec->count; ++j) {
+ const knot_rrset_t *nsec3 = knot_pkt_rr(sec, j);
+ if (nsec3->type == KNOT_RRTYPE_DS)
+ return kr_error(EEXIST);
+ if (nsec3->type != KNOT_RRTYPE_NSEC3)
+ continue;
+ nsec3_found = true;
+ /* nsec3 found, check if owner name matches the delegation name.
+ * Just skip in case of *any* errors. */
+ if (matches_name(nsec3, ns->owner) != kr_ok())
+ continue;
+
+ const uint8_t *bm = knot_nsec3_bitmap(nsec3->rrs.rdata);
+ uint16_t bm_size = knot_nsec3_bitmap_len(nsec3->rrs.rdata);
+ if (!bm)
+ return kr_error(EINVAL);
+ if (dnssec_nsec_bitmap_contains(bm, bm_size,
+ KNOT_RRTYPE_NS) &&
+ !dnssec_nsec_bitmap_contains(bm, bm_size,
+ KNOT_RRTYPE_DS) &&
+ !dnssec_nsec_bitmap_contains(bm, bm_size,
+ KNOT_RRTYPE_SOA)) {
+ /* Satisfies rfc5155, 8.9. paragraph 2 */
+ return kr_ok();
+ }
+ }
+ if (!nsec3_found)
+ return kr_error(DNSSEC_NOT_FOUND);
+ /* nsec3 that matches the delegation was not found.
+ * Check rfc5155, 8.9. paragraph 4.
+ * Find closest provable encloser.
+ */
+ const knot_dname_t *encloser_name = NULL;
+ const knot_rrset_t *covering_next_nsec3 = NULL;
+ int ret = closest_encloser_proof(pkt, KNOT_AUTHORITY, ns->owner,
+ &encloser_name, NULL, &covering_next_nsec3);
+ if (ret != 0)
+ return kr_error(EINVAL);
+
+ if (has_optout(covering_next_nsec3)) {
+ return kr_error(KNOT_ERANGE);
+ } else {
+ return kr_error(EINVAL);
+ }
+ }
+ return kr_error(EINVAL);
+}
+
+int kr_nsec3_matches_name_and_type(const knot_rrset_t *nsec3,
+ const knot_dname_t *name, uint16_t type)
+{
+ /* It's not secure enough to just check a single bit for (some) other types,
+ * but we don't (currently) only use this API for NS. See RFC 6840 sec. 4.
+ */
+ if (kr_fails_assert(type == KNOT_RRTYPE_NS))
+ return kr_error(EINVAL);
+ int ret = matches_name(nsec3, name);
+ if (ret)
+ return kr_error(ret);
+ const uint8_t *bm = knot_nsec3_bitmap(nsec3->rrs.rdata);
+ uint16_t bm_size = knot_nsec3_bitmap_len(nsec3->rrs.rdata);
+ if (!bm)
+ return kr_error(EINVAL);
+ if (dnssec_nsec_bitmap_contains(bm, bm_size, type)) {
+ return kr_ok();
+ } else {
+ return kr_error(ENOENT);
+ }
+}
diff --git a/lib/dnssec/nsec3.h b/lib/dnssec/nsec3.h
new file mode 100644
index 0000000..eb0bd39
--- /dev/null
+++ b/lib/dnssec/nsec3.h
@@ -0,0 +1,83 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#include <libknot/packet/pkt.h>
+
+/** High numbers in NSEC3 iterations don't really help security
+ *
+ * ...so we avoid doing all the work. The value is a current compromise;
+ * zones shooting over get downgraded to insecure status.
+ *
+ * Original restriction wasn't that strict:
+ https://datatracker.ietf.org/doc/html/rfc5155#section-10.3
+ * but there is discussion about officially lowering the limits:
+ https://tools.ietf.org/id/draft-hardaker-dnsop-nsec3-guidance-02.html#section-2.3
+ */
+#define KR_NSEC3_MAX_ITERATIONS 150
+
+/**
+ * Name error response check (RFC5155 7.2.2).
+ * @note No RRSIGs are validated.
+ * @param pkt Packet structure to be processed.
+ * @param section_id Packet section to be processed.
+ * @param sname Name to be checked.
+ * @return 0 or error code.
+ */
+int kr_nsec3_name_error_response_check(const knot_pkt_t *pkt, knot_section_t section_id,
+ const knot_dname_t *sname);
+
+/**
+ * Wildcard answer response check (RFC5155 7.2.6).
+ * @param pkt Packet structure to be processed.
+ * @param section_id Packet section to be processed.
+ * @param sname Name to be checked.
+ * @param trim_to_next Number of labels to remove to obtain next closer name.
+ * @return 0 or error code:
+ * KNOT_ERANGE - NSEC3 RR that covers a wildcard
+ * has been found, but has opt-out flag set;
+ * otherwise - error.
+ * Records over KR_NSEC3_MAX_ITERATIONS are skipped, so you probably get kr_error(ENOENT).
+ */
+int kr_nsec3_wildcard_answer_response_check(const knot_pkt_t *pkt, knot_section_t section_id,
+ const knot_dname_t *sname, int trim_to_next);
+
+/**
+ * Authenticated denial of existence according to RFC5155 8.5 and 8.7.
+ * @note No RRSIGs are validated.
+ * @param pkt Packet structure to be processed.
+ * @param section_id Packet section to be processed.
+ * @param sname Queried domain name.
+ * @param stype Queried type.
+ * @return 0 or error code:
+ * DNSSEC_NOT_FOUND - neither ds nor nsec records
+ * were not found.
+ * KNOT_ERANGE - denial of existence can't be proven
+ * due to opt-out, otherwise - bogus.
+ */
+int kr_nsec3_no_data(const knot_pkt_t *pkt, knot_section_t section_id,
+ const knot_dname_t *sname, uint16_t stype);
+
+/**
+ * Referral to unsigned subzone check (RFC5155 8.9).
+ * @note No RRSIGs are validated.
+ * @param pkt Packet structure to be processed.
+ * @return 0 or error code:
+ * KNOT_ERANGE - denial of existence can't be proven
+ * due to opt-out.
+ * EEXIST - ds record was found.
+ * EINVAL - bogus.
+ */
+int kr_nsec3_ref_to_unsigned(const knot_pkt_t *pkt);
+
+/**
+ * Checks whether supplied NSEC3 RR matches the supplied name and NS type.
+ * @param nsec3 NSEC3 RR.
+ * @param name Name to be checked.
+ * @param type Type to be checked. Only use with NS! TODO
+ * @return 0 or error code.
+ */
+int kr_nsec3_matches_name_and_type(const knot_rrset_t *nsec3,
+ const knot_dname_t *name, uint16_t type);
diff --git a/lib/dnssec/signature.c b/lib/dnssec/signature.c
new file mode 100644
index 0000000..aadb5cb
--- /dev/null
+++ b/lib/dnssec/signature.c
@@ -0,0 +1,304 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#include <arpa/inet.h>
+#include <string.h>
+
+#include <libdnssec/error.h>
+#include <libdnssec/key.h>
+#include <libdnssec/sign.h>
+#include <libknot/descriptor.h>
+#include <libknot/packet/rrset-wire.h>
+#include <libknot/packet/wire.h>
+#include <libknot/rrset.h>
+#include <libknot/rrtype/rrsig.h>
+#include <libknot/rrtype/ds.h>
+#include <libknot/wire.h>
+
+#include "lib/defines.h"
+#include "lib/utils.h"
+#include "lib/dnssec/signature.h"
+
+static int authenticate_ds(const dnssec_key_t *key, dnssec_binary_t *ds_rdata, uint8_t digest_type)
+{
+ /* Compute DS RDATA from the DNSKEY. */
+ dnssec_binary_t computed_ds = { 0, };
+ int ret = dnssec_key_create_ds(key, digest_type, &computed_ds);
+ if (ret != DNSSEC_EOK)
+ goto fail;
+
+ /* DS records contain algorithm, key tag and the digest.
+ * Therefore the comparison of the two DS is sufficient.
+ */
+ ret = (ds_rdata->size == computed_ds.size) &&
+ (memcmp(ds_rdata->data, computed_ds.data, ds_rdata->size) == 0);
+ ret = ret ? kr_ok() : kr_error(ENOENT);
+
+fail:
+ dnssec_binary_free(&computed_ds);
+ return kr_error(ret);
+}
+
+int kr_authenticate_referral(const knot_rrset_t *ref, const dnssec_key_t *key)
+{
+ if (kr_fails_assert(ref && key))
+ return kr_error(EINVAL);
+ if (ref->type != KNOT_RRTYPE_DS)
+ return kr_error(EINVAL);
+
+ /* Determine whether to ignore SHA1 digests, because:
+ https://datatracker.ietf.org/doc/html/rfc4509#section-3
+ * Now, the RFCs seem to only mention SHA1 and SHA256 (e.g. no SHA384),
+ * but the most natural extension is to make any other algorithm trump SHA1.
+ * (Note that the old GOST version is already unsupported by libdnssec.) */
+ bool skip_sha1 = false;
+ knot_rdata_t *rd = ref->rrs.rdata;
+ for (int i = 0; i < ref->rrs.count; ++i, rd = knot_rdataset_next(rd)) {
+ const uint8_t algo = knot_ds_digest_type(rd);
+ if (algo != DNSSEC_KEY_DIGEST_SHA1 && dnssec_algorithm_digest_support(algo)) {
+ skip_sha1 = true;
+ break;
+ }
+ }
+ /* But otherwise try all possible DS records. */
+ int ret = 0;
+ rd = ref->rrs.rdata;
+ for (int i = 0; i < ref->rrs.count; ++i, rd = knot_rdataset_next(rd)) {
+ const uint8_t algo = knot_ds_digest_type(rd);
+ if (skip_sha1 && algo == DNSSEC_KEY_DIGEST_SHA1)
+ continue;
+ dnssec_binary_t ds_rdata = {
+ .size = rd->len,
+ .data = rd->data
+ };
+ ret = authenticate_ds(key, &ds_rdata, algo);
+ if (ret == 0) /* Found a good DS */
+ return kr_ok();
+ }
+
+ return kr_error(ret);
+}
+
+/**
+ * Adjust TTL in wire format.
+ * @param wire RR Set in wire format.
+ * @param wire_size Size of the wire data portion.
+ * @param new_ttl TTL value to be set for all RRs.
+ * @return 0 or error code.
+ */
+static int adjust_wire_ttl(uint8_t *wire, size_t wire_size, uint32_t new_ttl)
+{
+ if (kr_fails_assert(wire))
+ return kr_error(EINVAL);
+ static_assert(sizeof(uint16_t) == 2, "uint16_t must be exactly 2 bytes");
+ static_assert(sizeof(uint32_t) == 4, "uint32_t must be exactly 4 bytes");
+ uint16_t rdlen;
+
+ int ret;
+
+ new_ttl = htonl(new_ttl);
+
+ size_t i = 0;
+ /* RR wire format in RFC1035 3.2.1 */
+ while(i < wire_size) {
+ ret = knot_dname_size(wire + i);
+ if (ret < 0)
+ return ret;
+ i += ret + 4;
+ memcpy(wire + i, &new_ttl, sizeof(uint32_t));
+ i += sizeof(uint32_t);
+
+ memcpy(&rdlen, wire + i, sizeof(uint16_t));
+ rdlen = ntohs(rdlen);
+ i += sizeof(uint16_t) + rdlen;
+
+ if (kr_fails_assert(i <= wire_size))
+ return kr_error(EINVAL);
+ }
+
+ return kr_ok();
+}
+
+/*!
+ * \brief Add RRSIG RDATA without signature to signing context.
+ *
+ * Requires signer name in RDATA in canonical form.
+ *
+ * \param ctx Signing context.
+ * \param rdata Pointer to RRSIG RDATA.
+ *
+ * \return Error code, KNOT_EOK if successful.
+ */
+#define RRSIG_RDATA_SIGNER_OFFSET 18
+static int sign_ctx_add_self(dnssec_sign_ctx_t *ctx, const uint8_t *rdata)
+{
+ if (kr_fails_assert(ctx && rdata))
+ return kr_error(EINVAL);
+
+ int result;
+
+ // static header
+
+ dnssec_binary_t header = {
+ .data = (uint8_t *)rdata,
+ .size = RRSIG_RDATA_SIGNER_OFFSET,
+ };
+
+ result = dnssec_sign_add(ctx, &header);
+ if (result != DNSSEC_EOK)
+ return result;
+
+ // signer name
+
+ const uint8_t *rdata_signer = rdata + RRSIG_RDATA_SIGNER_OFFSET;
+ dnssec_binary_t signer = { 0 };
+ signer.data = knot_dname_copy(rdata_signer, NULL);
+ signer.size = knot_dname_size(signer.data);
+
+ result = dnssec_sign_add(ctx, &signer);
+ free(signer.data);
+
+ return result;
+}
+#undef RRSIG_RDATA_SIGNER_OFFSET
+
+/*!
+ * \brief Add covered RRs to signing context.
+ *
+ * Requires all DNAMEs in canonical form and all RRs ordered canonically.
+ *
+ * \param ctx Signing context.
+ * \param covered Covered RRs.
+ *
+ * \return Error code, KNOT_EOK if successful.
+ */
+static int sign_ctx_add_records(dnssec_sign_ctx_t *ctx, const knot_rrset_t *covered,
+ uint32_t orig_ttl, int trim_labels)
+{
+ if (!ctx || !covered || trim_labels < 0)
+ return kr_error(EINVAL);
+
+ // huge block of rrsets can be optionally created
+ static uint8_t wire_buffer[KNOT_WIRE_MAX_PKTSIZE];
+ int written = knot_rrset_to_wire(covered, wire_buffer, sizeof(wire_buffer), NULL);
+ if (written < 0)
+ return written;
+
+ /* Set original ttl. */
+ int ret = adjust_wire_ttl(wire_buffer, written, orig_ttl);
+ if (ret != 0)
+ return ret;
+
+ if (!trim_labels) {
+ const dnssec_binary_t wire_binary = {
+ .size = written,
+ .data = wire_buffer
+ };
+ return dnssec_sign_add(ctx, &wire_binary);
+ }
+
+ /* RFC4035 5.3.2
+ * Remove leftmost labels and replace them with '*.'
+ * for each RR in covered.
+ */
+ uint8_t *beginp = wire_buffer;
+ for (uint16_t i = 0; i < covered->rrs.count; ++i) {
+ /* RR(i) = name | type | class | OrigTTL | RDATA length | RDATA */
+ for (int j = 0; j < trim_labels; ++j) {
+ if (kr_fails_assert(beginp[0]))
+ return kr_error(EINVAL);
+ beginp = (uint8_t *) knot_wire_next_label(beginp, NULL);
+ if (kr_fails_assert(beginp))
+ return kr_error(EFAULT);
+ }
+ *(--beginp) = '*';
+ *(--beginp) = 1;
+ const size_t rdatalen_offset = knot_dname_size(beginp) + /* name */
+ sizeof(uint16_t) + /* type */
+ sizeof(uint16_t) + /* class */
+ sizeof(uint32_t); /* OrigTTL */
+ const uint8_t *rdatalen_ptr = beginp + rdatalen_offset;
+ const uint16_t rdata_size = knot_wire_read_u16(rdatalen_ptr);
+ const size_t rr_size = rdatalen_offset +
+ sizeof(uint16_t) + /* RDATA length */
+ rdata_size; /* RDATA */
+ const dnssec_binary_t wire_binary = {
+ .size = rr_size,
+ .data = beginp
+ };
+ ret = dnssec_sign_add(ctx, &wire_binary);
+ if (ret != 0)
+ break;
+ beginp += rr_size;
+ }
+ return ret;
+}
+
+/*!
+ * \brief Add all data covered by signature into signing context.
+ *
+ * RFC 4034: The signature covers RRSIG RDATA field (excluding the signature)
+ * and all matching RR records, which are ordered canonically.
+ *
+ * Requires all DNAMEs in canonical form and all RRs ordered canonically.
+ *
+ * \param ctx Signing context.
+ * \param rrsig_rdata RRSIG RDATA with populated fields except signature.
+ * \param covered Covered RRs.
+ *
+ * \return Error code, KNOT_EOK if successful.
+ */
+/* TODO -- Taken from knot/src/knot/dnssec/rrset-sign.c. Re-write for better fit needed. */
+static int sign_ctx_add_data(dnssec_sign_ctx_t *ctx, const uint8_t *rrsig_rdata,
+ const knot_rrset_t *covered, uint32_t orig_ttl, int trim_labels)
+{
+ int result = sign_ctx_add_self(ctx, rrsig_rdata);
+ if (result != KNOT_EOK)
+ return result;
+
+ return sign_ctx_add_records(ctx, covered, orig_ttl, trim_labels);
+}
+
+int kr_check_signature(const knot_rdata_t *rrsig,
+ const dnssec_key_t *key, const knot_rrset_t *covered,
+ int trim_labels)
+{
+ if (!rrsig || !key || !dnssec_key_can_verify(key))
+ return kr_error(EINVAL);
+
+ int ret = 0;
+ dnssec_sign_ctx_t *sign_ctx = NULL;
+ dnssec_binary_t signature = {
+ .data = /*const-cast*/(uint8_t*)knot_rrsig_signature(rrsig),
+ .size = knot_rrsig_signature_len(rrsig),
+ };
+ if (!signature.data || !signature.size) {
+ ret = kr_error(EINVAL);
+ goto fail;
+ }
+
+ if (dnssec_sign_new(&sign_ctx, key) != 0) {
+ ret = kr_error(ENOMEM);
+ goto fail;
+ }
+
+ uint32_t orig_ttl = knot_rrsig_original_ttl(rrsig);
+
+ if (sign_ctx_add_data(sign_ctx, rrsig->data, covered, orig_ttl, trim_labels) != 0) {
+ ret = kr_error(ENOMEM);
+ goto fail;
+ }
+
+ ret = dnssec_sign_verify(sign_ctx, false, &signature);
+ if (ret != 0) {
+ ret = kr_error(EBADMSG);
+ goto fail;
+ }
+
+ ret = kr_ok();
+
+fail:
+ dnssec_sign_free(sign_ctx);
+ return ret;
+}
diff --git a/lib/dnssec/signature.h b/lib/dnssec/signature.h
new file mode 100644
index 0000000..1cc6c8f
--- /dev/null
+++ b/lib/dnssec/signature.h
@@ -0,0 +1,29 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#include <libdnssec/key.h>
+#include <libknot/rrset.h>
+
+/**
+ * Performs referral authentication according to RFC4035 5.2, bullet 2
+ * @param ref Referral RRSet. Currently only DS can be used.
+ * @param key Already parsed key.
+ * @return 0 or error code. In particular: DNSSEC_INVALID_DS_ALGORITHM
+ * in case *all* DSs in ref use an unimplemented algorithm.
+ */
+int kr_authenticate_referral(const knot_rrset_t *ref, const dnssec_key_t *key);
+
+/**
+ * Check the signature of the supplied RRSet.
+ * @param rrsig A single signature.
+ * @param key Key to be used to validate the signature.
+ * @param covered The covered RRSet.
+ * @param trim_labels Number of the leftmost labels to be removed and replaced with '*.'.
+ * @return 0 if signature valid, error code else.
+ */
+int kr_check_signature(const knot_rdata_t *rrsig,
+ const dnssec_key_t *key, const knot_rrset_t *covered,
+ int trim_labels);
diff --git a/lib/dnssec/ta.c b/lib/dnssec/ta.c
new file mode 100644
index 0000000..becf7d8
--- /dev/null
+++ b/lib/dnssec/ta.c
@@ -0,0 +1,154 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#include <contrib/cleanup.h>
+#include <libknot/descriptor.h>
+#include <libknot/rdataset.h>
+#include <libknot/rrset.h>
+#include <libknot/packet/wire.h>
+#include <libdnssec/key.h>
+#include <libdnssec/error.h>
+
+#include "lib/defines.h"
+#include "lib/dnssec.h"
+#include "lib/dnssec/ta.h"
+#include "lib/resolve.h"
+#include "lib/utils.h"
+
+knot_rrset_t *kr_ta_get(trie_t *trust_anchors, const knot_dname_t *name)
+{
+ trie_val_t *val = trie_get_try(trust_anchors, (const char *)name, strlen((const char *)name));
+ return (val) ? *val : NULL;
+}
+
+const knot_dname_t * kr_ta_closest(const struct kr_context *ctx, const knot_dname_t *name,
+ const uint16_t type)
+{
+ kr_require(ctx && name);
+ if (type == KNOT_RRTYPE_DS && name[0] != '\0') {
+ /* DS is parent-side record, so the parent name needs to be covered. */
+ name = knot_wire_next_label(name, NULL);
+ }
+ while (name) {
+ struct kr_context *ctx_nc = (struct kr_context *)/*const-cast*/ctx;
+ if (kr_ta_get(ctx_nc->trust_anchors, name)) {
+ return name;
+ }
+ if (kr_ta_get(ctx_nc->negative_anchors, name)) {
+ return NULL;
+ }
+ name = knot_wire_next_label(name, NULL);
+ }
+ return NULL;
+}
+
+/* @internal Create DS from DNSKEY, caller MUST free dst if successful. */
+static int dnskey2ds(dnssec_binary_t *dst, const knot_dname_t *owner, const uint8_t *rdata, uint16_t rdlen)
+{
+ dnssec_key_t *key = NULL;
+ int ret = dnssec_key_new(&key);
+ if (ret) goto cleanup;
+ /* Create DS from DNSKEY and reinsert */
+ const dnssec_binary_t key_data = { .size = rdlen, .data = (uint8_t *)rdata };
+ ret = dnssec_key_set_rdata(key, &key_data);
+ if (ret) goto cleanup;
+ /* Accept only keys with Zone and SEP flags that aren't revoked,
+ * as a precaution. RFC 5011 also utilizes these flags.
+ * TODO: kr_dnssec_key_* names are confusing. */
+ const bool flags_ok = kr_dnssec_key_zsk(rdata) && !kr_dnssec_key_revoked(rdata);
+ if (!flags_ok) {
+ auto_free char *owner_str = kr_dname_text(owner);
+ kr_log_error(TA, "refusing to trust %s DNSKEY because of flags %d\n",
+ owner_str, dnssec_key_get_flags(key));
+ ret = kr_error(EILSEQ);
+ goto cleanup;
+ } else if (!kr_dnssec_key_ksk(rdata)) {
+ auto_free char *owner_str = kr_dname_text(owner);
+ int flags = dnssec_key_get_flags(key);
+ kr_log_warning(TA, "warning: %s DNSKEY is missing the SEP bit; "
+ "flags %d instead of %d\n",
+ owner_str, flags, flags + 1/*a little ugly*/);
+ }
+ ret = dnssec_key_set_dname(key, owner);
+ if (ret) goto cleanup;
+ ret = dnssec_key_create_ds(key, DNSSEC_KEY_DIGEST_SHA256, dst);
+cleanup:
+ dnssec_key_free(key);
+ return kr_error(ret);
+}
+
+/* @internal Insert new TA to trust anchor set, rdata MUST be of DS type. */
+static int insert_ta(trie_t *trust_anchors, const knot_dname_t *name,
+ uint32_t ttl, const uint8_t *rdata, uint16_t rdlen)
+{
+ bool is_new_key = false;
+ knot_rrset_t *ta_rr = kr_ta_get(trust_anchors, name);
+ if (!ta_rr) {
+ ta_rr = knot_rrset_new(name, KNOT_RRTYPE_DS, KNOT_CLASS_IN, ttl, NULL);
+ is_new_key = true;
+ }
+ /* Merge-in new key data */
+ if (!ta_rr || (rdlen > 0 && knot_rrset_add_rdata(ta_rr, rdata, rdlen, NULL) != 0)) {
+ knot_rrset_free(ta_rr, NULL);
+ return kr_error(ENOMEM);
+ }
+ if (is_new_key) {
+ trie_val_t *val = trie_get_ins(trust_anchors, (const char *)name, strlen((const char *)name));
+ if (kr_fails_assert(val))
+ return kr_error(EINVAL);
+ *val = ta_rr;
+ }
+ return kr_ok();
+}
+
+int kr_ta_add(trie_t *trust_anchors, const knot_dname_t *name, uint16_t type,
+ uint32_t ttl, const uint8_t *rdata, uint16_t rdlen)
+{
+ if (!trust_anchors || !name) {
+ return kr_error(EINVAL);
+ }
+
+ /* DS/DNSKEY types are accepted, for DNSKEY we
+ * need to compute a DS digest. */
+ if (type == KNOT_RRTYPE_DS) {
+ return insert_ta(trust_anchors, name, ttl, rdata, rdlen);
+ } else if (type == KNOT_RRTYPE_DNSKEY) {
+ dnssec_binary_t ds_rdata = { 0, };
+ int ret = dnskey2ds(&ds_rdata, name, rdata, rdlen);
+ if (ret != 0) {
+ return ret;
+ }
+ ret = insert_ta(trust_anchors, name, ttl, ds_rdata.data, ds_rdata.size);
+ dnssec_binary_free(&ds_rdata);
+ return ret;
+ } else { /* Invalid type for TA */
+ return kr_error(EINVAL);
+ }
+}
+
+/* Delete record data */
+static int del_record(trie_val_t *v, void *ext)
+{
+ knot_rrset_t *ta_rr = *v;
+ if (ta_rr) {
+ knot_rrset_free(ta_rr, NULL);
+ }
+ return 0;
+}
+
+int kr_ta_del(trie_t *trust_anchors, const knot_dname_t *name)
+{
+ knot_rrset_t *ta_rr;
+ int ret = trie_del(trust_anchors, (const char *)name, strlen((const char *)name),
+ (trie_val_t *) &ta_rr);
+ if (ret == KNOT_EOK && ta_rr)
+ knot_rrset_free(ta_rr, NULL);
+ return kr_ok();
+}
+
+void kr_ta_clear(trie_t *trust_anchors)
+{
+ trie_apply(trust_anchors, del_record, NULL);
+ trie_clear(trust_anchors);
+}
diff --git a/lib/dnssec/ta.h b/lib/dnssec/ta.h
new file mode 100644
index 0000000..1eb1dd9
--- /dev/null
+++ b/lib/dnssec/ta.h
@@ -0,0 +1,61 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#include "lib/defines.h"
+#include "lib/generic/trie.h"
+#include <libknot/rrset.h>
+
+/**
+ * Find TA RRSet by name.
+ * @param trust_anchors trust store
+ * @param name name of the TA
+ * @return non-empty RRSet or NULL
+ */
+KR_EXPORT
+knot_rrset_t *kr_ta_get(trie_t *trust_anchors, const knot_dname_t *name);
+
+/**
+ * Add TA to trust store. DS or DNSKEY types are supported.
+ * @param trust_anchors trust store
+ * @param name name of the TA
+ * @param type RR type of the TA (DS or DNSKEY)
+ * @param ttl
+ * @param rdata
+ * @param rdlen
+ * @return 0 or an error
+ */
+KR_EXPORT
+int kr_ta_add(trie_t *trust_anchors, const knot_dname_t *name, uint16_t type,
+ uint32_t ttl, const uint8_t *rdata, uint16_t rdlen);
+
+struct kr_context;
+
+/**
+ * Return pointer to the name of the closest positive trust anchor or NULL.
+ *
+ * "Closest" means on path towards root. Closer negative anchor results into NULL.
+ * @param type serves as a shorthand because DS needs to start one level higher.
+ */
+KR_EXPORT KR_PURE
+const knot_dname_t * kr_ta_closest(const struct kr_context *ctx, const knot_dname_t *name,
+ const uint16_t type);
+
+/**
+ * Remove TA from trust store.
+ * @param trust_anchors trust store
+ * @param name name of the TA
+ * @return 0 or an error
+ */
+KR_EXPORT
+int kr_ta_del(trie_t *trust_anchors, const knot_dname_t *name);
+
+/**
+ * Clear trust store.
+ * @param trust_anchors trust store
+ */
+KR_EXPORT
+void kr_ta_clear(trie_t *trust_anchors);
+
diff --git a/lib/generic/README.rst b/lib/generic/README.rst
new file mode 100644
index 0000000..dae0b7e
--- /dev/null
+++ b/lib/generic/README.rst
@@ -0,0 +1,48 @@
+.. SPDX-License-Identifier: GPL-3.0-or-later
+
+Generics library
+----------------
+
+This small collection of "generics" was born out of frustration that I couldn't find no
+such thing for C. It's either bloated, has poor interface, null-checking is absent or
+doesn't allow custom allocation scheme. BSD-licensed (or compatible) code is allowed here,
+as long as it comes with a test case in `tests/test_generics.c`.
+
+* array_ - a set of simple macros to make working with dynamic arrays easier.
+* queue_ - a FIFO + LIFO queue.
+* pack_ - length-prefixed list of objects (i.e. array-list).
+* lru_ - LRU-like hash table
+* trie_ - a trie-based key-value map, taken from knot-dns
+
+array
+~~~~~
+
+.. doxygenfile:: array.h
+ :project: libkres
+
+queue
+~~~~~
+
+.. doxygenfile:: queue.h
+ :project: libkres
+
+pack
+~~~~
+
+.. doxygenfile:: pack.h
+ :project: libkres
+
+lru
+~~~
+
+.. doxygenfile:: lru.h
+ :project: libkres
+
+trie
+~~~~
+
+.. doxygenfile:: trie.h
+ :project: libkres
+
+
+.. _`Crit-bit tree`: https://cr.yp.to/critbit.html
diff --git a/lib/generic/array.h b/lib/generic/array.h
new file mode 100644
index 0000000..9f35118
--- /dev/null
+++ b/lib/generic/array.h
@@ -0,0 +1,157 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+/**
+ *
+ * @file array.h
+ * @brief A set of simple macros to make working with dynamic arrays easier.
+ *
+ * @note The C has no generics, so it is implemented mostly using macros.
+ * Be aware of that, as direct usage of the macros in the evaluating macros
+ * may lead to different expectations:
+ *
+ * @code{.c}
+ * MIN(array_push(arr, val), other)
+ * @endcode
+ *
+ * May evaluate the code twice, leading to unexpected behaviour.
+ * This is a price to pay for the absence of proper generics.
+ *
+ * # Example usage:
+ *
+ * @code{.c}
+ * array_t(const char*) arr;
+ * array_init(arr);
+ *
+ * // Reserve memory in advance
+ * if (array_reserve(arr, 2) < 0) {
+ * return ENOMEM;
+ * }
+ *
+ * // Already reserved, cannot fail
+ * array_push(arr, "princess");
+ * array_push(arr, "leia");
+ *
+ * // Not reserved, may fail
+ * if (array_push(arr, "han") < 0) {
+ * return ENOMEM;
+ * }
+ *
+ * // It does not hide what it really is
+ * for (size_t i = 0; i < arr.len; ++i) {
+ * printf("%s\n", arr.at[i]);
+ * }
+ *
+ * // Random delete
+ * array_del(arr, 0);
+ * @endcode
+ * \addtogroup generics
+ * @{
+ */
+
+#pragma once
+#include <stdlib.h>
+
+/** Choose array length when it overflows. */
+static inline size_t array_next_count(size_t elm_size, size_t want, size_t have)
+{
+ if (want >= have * 2) // We amortized enough and maybe more won't be needed.
+ return want;
+ const size_t want_b = want * elm_size;
+ if (want_b < 64) // Short arrays are cheap to copy; get just one extra.
+ return want + 1;
+ if (want_b < 1024) // 50% growth amortizes to roughly 3 copies per element.
+ return want + want / 2;
+ return want * 2; // Doubling growth amortizes to roughly 2 copies per element.
+}
+
+/** @internal Incremental memory reservation */
+static inline int array_std_reserve(void *baton, void **mem, size_t elm_size, size_t want, size_t *have)
+{
+ if (*have >= want) {
+ return 0;
+ }
+ /* Simplified Qt containers growth strategy */
+ size_t next_size = array_next_count(elm_size, want, *have);
+ void *mem_new = realloc(*mem, next_size * elm_size);
+ if (mem_new != NULL) {
+ *mem = mem_new;
+ *have = next_size;
+ return 0;
+ }
+ return -1;
+}
+
+/** @internal Wrapper for stdlib free. */
+static inline void array_std_free(void *baton, void *p)
+{
+ free(p);
+}
+
+/** Declare an array structure. */
+#define array_t(type) struct {type * at; size_t len; size_t cap; }
+
+/** Zero-initialize the array. */
+#define array_init(array) ((array).at = NULL, (array).len = (array).cap = 0)
+
+/** Free and zero-initialize the array (plain malloc/free). */
+#define array_clear(array) \
+ array_clear_mm(array, array_std_free, NULL)
+
+/** Make the array empty and free pointed-to memory.
+ * Mempool usage: pass mm_free and a knot_mm_t* . */
+#define array_clear_mm(array, free, baton) \
+ (free)((baton), (array).at), array_init(array)
+
+/** Reserve capacity for at least n elements.
+ * @return 0 if success, <0 on failure */
+#define array_reserve(array, n) \
+ array_reserve_mm(array, n, array_std_reserve, NULL)
+
+/** Reserve capacity for at least n elements.
+ * Mempool usage: pass kr_memreserve and a knot_mm_t* .
+ * @return 0 if success, <0 on failure */
+#define array_reserve_mm(array, n, reserve, baton) \
+ (reserve)((baton), (void **) &(array).at, sizeof((array).at[0]), (n), &(array).cap)
+
+/**
+ * Push value at the end of the array, resize it if necessary.
+ * Mempool usage: pass kr_memreserve and a knot_mm_t* .
+ * @note May fail if the capacity is not reserved.
+ * @return element index on success, <0 on failure
+ */
+#define array_push_mm(array, val, reserve, baton) \
+ (int)((array).len < (array).cap ? ((array).at[(array).len] = val, (array).len++) \
+ : (array_reserve_mm(array, ((array).cap + 1), reserve, baton) < 0 ? -1 \
+ : ((array).at[(array).len] = val, (array).len++)))
+
+/**
+ * Push value at the end of the array, resize it if necessary (plain malloc/free).
+ * @note May fail if the capacity is not reserved.
+ * @return element index on success, <0 on failure
+ */
+#define array_push(array, val) \
+ array_push_mm(array, val, array_std_reserve, NULL)
+
+/**
+ * Pop value from the end of the array.
+ */
+#define array_pop(array) \
+ (array).len -= 1
+
+/**
+ * Remove value at given index.
+ * @return 0 on success, <0 on failure
+ */
+#define array_del(array, i) \
+ (int)((i) < (array).len ? ((array).len -= 1,(array).at[i] = (array).at[(array).len], 0) : -1)
+
+/**
+ * Return last element of the array.
+ * @warning Undefined if the array is empty.
+ */
+#define array_tail(array) \
+ (array).at[(array).len - 1]
+
+/** @} */
diff --git a/lib/generic/lru.c b/lib/generic/lru.c
new file mode 100644
index 0000000..857b20b
--- /dev/null
+++ b/lib/generic/lru.c
@@ -0,0 +1,249 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#include "lib/generic/lru.h"
+#include "contrib/murmurhash3/murmurhash3.h"
+#include "contrib/ucw/mempool.h"
+
+typedef struct lru_group lru_group_t;
+
+struct lru_item {
+ uint16_t key_len, val_len; /**< Two bytes should be enough for our purposes. */
+ char data[];
+ /**< Place for both key and value.
+ *
+ * We use "char" to satisfy the C99+ aliasing rules.
+ * See C99 section 6.5 Expressions, paragraph 7.
+ * Any type can be accessed through char-pointer,
+ * so we can use a common struct definition
+ * for all types being held.
+ *
+ * The value address is restricted by val_alignment.
+ * Approach: require slightly larger sizes from the allocator
+ * and shift value on the closest address with val_alignment.
+ */
+};
+
+/** @brief Round the value up to a multiple of mul (a power of two). */
+static inline size_t round_power(size_t size, size_t mult)
+{
+ kr_require(__builtin_popcount(mult) == 1);
+ size_t res = ((size - 1) & ~(mult - 1)) + mult;
+ kr_require(__builtin_ctz(res) >= __builtin_ctz(mult));
+ kr_require(size <= res && res < size + mult);
+ return res;
+}
+
+/** @internal Compute the allocation size for an lru_item. */
+static uint item_size(const struct lru *lru, uint key_len, uint val_len)
+{
+ uint key_end = offsetof(struct lru_item, data) + key_len;
+ return key_end + (lru->val_alignment - 1) + val_len;
+ /* ^^^ worst-case padding length
+ * Well, we might compute the bound a bit more precisely,
+ * as we know that lru_item will get alignment at least
+ * some sizeof(void*) and we know all the lengths,
+ * but let's not complicate it, as the gain would be small anyway. */
+}
+
+/** @internal Return pointer to value in an lru_item. */
+static void * item_val(const struct lru *lru, struct lru_item *it)
+{
+ size_t key_end = it->data + it->key_len - (char *)NULL;
+ size_t val_begin = round_power(key_end, lru->val_alignment);
+ return (char *)NULL + val_begin;
+}
+
+/** @internal Free each item. */
+KR_EXPORT void lru_free_items_impl(struct lru *lru)
+{
+ if (kr_fails_assert(lru))
+ return;
+ for (size_t i = 0; i < (1 << (size_t)lru->log_groups); ++i) {
+ lru_group_t *g = &lru->groups[i];
+ for (int j = 0; j < LRU_ASSOC; ++j)
+ mm_free(lru->mm, g->items[j]);
+ }
+}
+
+/** @internal See lru_apply. */
+KR_EXPORT void lru_apply_impl(struct lru *lru, lru_apply_fun f, void *baton)
+{
+ if (kr_fails_assert(lru && f))
+ return;
+ for (size_t i = 0; i < (1 << (size_t)lru->log_groups); ++i) {
+ lru_group_t *g = &lru->groups[i];
+ for (uint j = 0; j < LRU_ASSOC; ++j) {
+ struct lru_item *it = g->items[j];
+ if (!it)
+ continue;
+ enum lru_apply_do ret =
+ f(it->data, it->key_len, item_val(lru, it), baton);
+ switch(ret) {
+ case LRU_APPLY_DO_EVICT: // evict
+ mm_free(lru->mm, it);
+ g->items[j] = NULL;
+ g->counts[j] = 0;
+ g->hashes[j] = 0;
+ break;
+ default:
+ kr_assert(ret == LRU_APPLY_DO_NOTHING);
+ }
+ }
+ }
+}
+
+/** @internal See lru_create. */
+KR_EXPORT struct lru * lru_create_impl(uint max_slots, uint val_alignment,
+ knot_mm_t *mm_array, knot_mm_t *mm)
+{
+ if (kr_fails_assert(max_slots && __builtin_popcount(val_alignment) == 1))
+ return NULL;
+ // let lru->log_groups = ceil(log2(max_slots / (float) assoc))
+ // without trying for efficiency
+ uint group_count = (max_slots - 1) / LRU_ASSOC + 1;
+ uint log_groups = 0;
+ for (uint s = group_count - 1; s; s /= 2)
+ ++log_groups;
+ group_count = 1 << log_groups;
+ if (kr_fails_assert(max_slots <= group_count * LRU_ASSOC && group_count * LRU_ASSOC < 2 * max_slots))
+ return NULL;
+
+ /* Get a sufficiently aligning mm_array if NULL is passed. */
+ if (!mm_array) {
+ static knot_mm_t mm_array_default = { 0 };
+ if (!mm_array_default.ctx)
+ mm_ctx_init_aligned(&mm_array_default, alignof(struct lru));
+ mm_array = &mm_array_default;
+ }
+ if (kr_fails_assert(mm_array->alloc && mm_array->alloc != (knot_mm_alloc_t)mp_alloc))
+ return NULL;
+
+ size_t size = offsetof(struct lru, groups[group_count]);
+ struct lru *lru = mm_alloc(mm_array, size);
+ if (unlikely(lru == NULL))
+ return NULL;
+ *lru = (struct lru){
+ .mm = mm,
+ .mm_array = mm_array,
+ .log_groups = log_groups,
+ .val_alignment = val_alignment,
+ };
+ // zeros are a good init
+ memset(lru->groups, 0, size - offsetof(struct lru, groups));
+ return lru;
+}
+
+/** @internal Decrement all counters within a group. */
+static void group_dec_counts(lru_group_t *g) {
+ g->counts[LRU_TRACKED] = LRU_TRACKED;
+ for (uint i = 0; i < LRU_TRACKED + 1; ++i)
+ if (likely(g->counts[i]))
+ --g->counts[i];
+}
+
+/** @internal Increment a counter within a group. */
+static void group_inc_count(lru_group_t *g, int i) {
+ if (likely(++(g->counts[i])))
+ return;
+ g->counts[i] = -1;
+ // We could've decreased or halved all of them, but let's keep the max.
+}
+
+/** @internal Implementation of both getting and insertion.
+ * Note: val_len is only meaningful if do_insert.
+ * *is_new is only meaningful when return value isn't NULL, contains
+ * true when returned lru entry has been allocated right now
+ * if return value is NULL, *is_new remains untouched.
+ */
+KR_EXPORT void * lru_get_impl(struct lru *lru, const char *key, uint key_len,
+ uint val_len, bool do_insert, bool *is_new)
+{
+ bool ok = lru && (key || !key_len) && key_len <= UINT16_MAX
+ && (!do_insert || val_len <= UINT16_MAX);
+ if (kr_fails_assert(ok))
+ return NULL; // reasonable fallback when not debugging
+ bool is_new_entry = false;
+ // find the right group
+ uint32_t khash = hash(key, key_len);
+ uint16_t khash_top = khash >> 16;
+ lru_group_t *g = &lru->groups[khash & ((1 << lru->log_groups) - 1)];
+ struct lru_item *it = NULL;
+ uint i;
+ // scan the *stored* elements in the group
+ for (i = 0; i < LRU_ASSOC; ++i) {
+ if (g->hashes[i] == khash_top) {
+ it = g->items[i];
+ if (likely(it && it->key_len == key_len
+ && (key_len == 0 || memcmp(it->data, key, key_len) == 0))) {
+ /* Found a key, but trying to insert a value larger than available
+ * space in the allocated slot, so the entry must be resized to fit. */
+ if (unlikely(do_insert && val_len > it->val_len)) {
+ goto insert;
+ } else {
+ goto found; // to reduce huge nesting depth
+ }
+ }
+ }
+ }
+ // key not found; first try an empty/counted-out place to insert
+ if (do_insert)
+ for (i = 0; i < LRU_ASSOC; ++i)
+ if (g->items[i] == NULL || g->counts[i] == 0)
+ goto insert;
+ // check if we track key's count at least
+ for (i = LRU_ASSOC; i < LRU_TRACKED; ++i) {
+ if (g->hashes[i] == khash_top) {
+ group_inc_count(g, i);
+ if (!do_insert)
+ return NULL;
+ // check if we trumped some stored key
+ for (uint j = 0; j < LRU_ASSOC; ++j)
+ if (unlikely(g->counts[i] > g->counts[j])) {
+ // evict key j, i.e. swap with i
+ --g->counts[i]; // we increment it below
+ SWAP(g->counts[i], g->counts[j]);
+ SWAP(g->hashes[i], g->hashes[j]);
+ i = j;
+ goto insert;
+ }
+ return NULL;
+ }
+ }
+ // not found at all: decrement all counts but only on every LRU_TRACKED occasion
+ if (g->counts[LRU_TRACKED])
+ --g->counts[LRU_TRACKED];
+ else
+ group_dec_counts(g);
+ return NULL;
+insert: // insert into position i (incl. key)
+ if (kr_fails_assert(i < LRU_ASSOC))
+ return NULL;
+ g->hashes[i] = khash_top;
+ it = g->items[i];
+ uint new_size = item_size(lru, key_len, val_len);
+ if (it == NULL || new_size != item_size(lru, it->key_len, it->val_len)) {
+ // (re)allocate
+ mm_free(lru->mm, it);
+ it = g->items[i] = mm_alloc(lru->mm, new_size);
+ if (it == NULL)
+ return NULL;
+ }
+ it->key_len = key_len;
+ it->val_len = val_len;
+ if (key_len > 0) {
+ memcpy(it->data, key, key_len);
+ }
+ memset(item_val(lru, it), 0, val_len); // clear the value
+ is_new_entry = true;
+found: // key and hash OK on g->items[i]; now update stamps
+ if (kr_fails_assert(i < LRU_ASSOC))
+ return NULL;
+ group_inc_count(g, i);
+ if (is_new) {
+ *is_new = is_new_entry;
+ }
+ return item_val(lru, g->items[i]);
+}
+
diff --git a/lib/generic/lru.h b/lib/generic/lru.h
new file mode 100644
index 0000000..448c1b9
--- /dev/null
+++ b/lib/generic/lru.h
@@ -0,0 +1,240 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+/**
+ * @file lru.h
+ * @brief A lossy cache.
+ *
+ * @note The implementation tries to keep frequent keys and avoid others,
+ * even if "used recently", so it may refuse to store it on lru_get_new().
+ * It uses hashing to split the problem pseudo-randomly into smaller groups,
+ * and within each it tries to approximate relative usage counts of several
+ * most frequent keys/hashes. This tracking is done for *more* keys than
+ * those that are actually stored.
+ *
+ * Example usage:
+ * @code{.c}
+ * // Define new LRU type
+ * typedef lru_t(int) lru_int_t;
+ *
+ * // Create LRU
+ * lru_int_t *lru;
+ * lru_create(&lru, 5, NULL, NULL);
+ *
+ * // Insert some values
+ * int *pi = lru_get_new(lru, "luke", strlen("luke"), NULL);
+ * if (pi)
+ * *pi = 42;
+ * pi = lru_get_new(lru, "leia", strlen("leia"), NULL);
+ * if (pi)
+ * *pi = 24;
+ *
+ * // Retrieve values
+ * int *ret = lru_get_try(lru, "luke", strlen("luke"), NULL);
+ * if (!ret) printf("luke dropped out!\n");
+ * else printf("luke's number is %d\n", *ret);
+ *
+ * char *enemies[] = {"goro", "raiden", "subzero", "scorpion"};
+ * for (int i = 0; i < 4; ++i) {
+ * int *val = lru_get_new(lru, enemies[i], strlen(enemies[i]), NULL);
+ * if (val)
+ * *val = i;
+ * }
+ *
+ * // We're done
+ * lru_free(lru);
+ * @endcode
+ *
+ * \addtogroup generics
+ * @{
+ */
+
+#pragma once
+
+#include <stdalign.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#include "contrib/ucw/lib.h"
+#include "lib/utils.h"
+#include "libknot/mm_ctx.h"
+
+/* ================================ Interface ================================ */
+
+/** @brief The type for LRU, parametrized by value type. */
+#define lru_t(type) \
+ union { \
+ type *pdata_t; /* only the *type* information is used */ \
+ struct lru lru; \
+ }
+
+/**
+ * @brief Allocate and initialize an LRU with default associativity.
+ *
+ * The real limit on the number of slots can be a bit larger but less than double.
+ *
+ * @param ptable pointer to a pointer to the LRU
+ * @param max_slots number of slots
+ * @param mm_ctx_array memory context to use for the huge array, NULL for default
+ * If you pass your own, it needs to produce CACHE_ALIGNED allocations (ubsan).
+ * @param mm_ctx memory context to use for individual key-value pairs, NULL for default
+ *
+ * @note The pointers to memory contexts need to remain valid
+ * during the whole life of the structure (or be NULL).
+ */
+/* Pragmas: C11 only standardizes alignof on type names, not on expressions.
+ * That's a GNU extension; in clang it's supported but may generate warnings.
+ * It seems hard to disable warnings that are only supported by some compilers. */
+#define lru_create(ptable, max_slots, mm_ctx_array, mm_ctx) do { \
+ (void)(((__typeof__((*(ptable))->pdata_t))0) == (void *)0); /* typecheck lru_t */ \
+ _Pragma("GCC diagnostic push") \
+ _Pragma("GCC diagnostic ignored \"-Wpragmas\"") \
+ _Pragma("GCC diagnostic ignored \"-Wunknown-pragmas\"") \
+ _Pragma("GCC diagnostic ignored \"-Wgnu-alignof-expression\"") \
+ *(ptable) = (__typeof__(*(ptable))) \
+ lru_create_impl((max_slots), alignof(*( (*(ptable))->pdata_t )), \
+ (mm_ctx_array), (mm_ctx)); \
+ _Pragma("GCC diagnostic pop") \
+ } while (false)
+
+/** @brief Free an LRU created by lru_create (it can be NULL). */
+#define lru_free(table) \
+ lru_free_impl(&(table)->lru)
+
+/** @brief Reset an LRU to the empty state (but preserve any settings). */
+#define lru_reset(table) \
+ lru_reset_impl(&(table)->lru)
+
+/**
+ * @brief Find key in the LRU and return pointer to the corresponding value.
+ *
+ * @param table pointer to LRU
+ * @param key_ lookup key
+ * @param len_ key length
+ * @return pointer to data or NULL if not found
+ */
+#define lru_get_try(table, key_, len_) \
+ (__typeof__((table)->pdata_t)) \
+ lru_get_impl(&(table)->lru, (key_), (len_), -1, false, NULL)
+
+/**
+ * @brief Return pointer to value, inserting if needed (zeroed).
+ *
+ * @param table pointer to LRU
+ * @param key_ lookup key
+ * @param len_ key lengthkeys
+ * @param is_new pointer to bool to store result of operation
+ * (true if entry is newly added, false otherwise; can be NULL).
+ * @return pointer to data or NULL (can be even if memory could be allocated!)
+ */
+#define lru_get_new(table, key_, len_, is_new) \
+ (__typeof__((table)->pdata_t)) \
+ lru_get_impl(&(table)->lru, (key_), (len_), \
+ sizeof(*(table)->pdata_t), true, is_new)
+
+/**
+ * @brief Apply a function to every item in LRU.
+ *
+ * @param table pointer to LRU
+ * @param function enum lru_apply_do (*function)(const char *key, uint len, val_type *val, void *baton)
+ * See enum lru_apply_do for the return type meanings.
+ * @param baton extra pointer passed to each function invocation
+ */
+#define lru_apply(table, function, baton) do { \
+ lru_apply_fun_g(fun_dummy, __typeof__(*(table)->pdata_t)) = 0; \
+ (void)(fun_dummy == (function)); /* produce a warning with incompatible function type */ \
+ lru_apply_impl(&(table)->lru, (lru_apply_fun)(function), (baton)); \
+ } while (false)
+
+/** @brief Possible actions to do with an element. */
+enum lru_apply_do {
+ LRU_APPLY_DO_NOTHING,
+ LRU_APPLY_DO_EVICT,
+ /* maybe more in future*/
+};
+
+/**
+ * @brief Return the real capacity - maximum number of keys holdable within.
+ *
+ * @param table pointer to LRU
+ */
+#define lru_capacity(table) lru_capacity_impl(&(table)->lru)
+
+
+
+/* ======================== Inlined part of implementation ======================== */
+/** @cond internal */
+
+#define lru_apply_fun_g(name, val_type) \
+ enum lru_apply_do (*(name))(const char *key, uint len, val_type *val, void *baton)
+typedef lru_apply_fun_g(lru_apply_fun, void);
+
+#if __GNUC__ >= 4
+ #define CACHE_ALIGNED __attribute__((aligned(64)))
+#else
+ #define CACHE_ALIGNED
+#endif
+
+struct lru;
+void lru_free_items_impl(struct lru *lru);
+struct lru * lru_create_impl(uint max_slots, uint val_alignment,
+ knot_mm_t *mm_array, knot_mm_t *mm);
+void * lru_get_impl(struct lru *lru, const char *key, uint key_len,
+ uint val_len, bool do_insert, bool *is_new);
+void lru_apply_impl(struct lru *lru, lru_apply_fun f, void *baton);
+
+struct lru_item;
+
+#if SIZE_MAX > (1 << 32)
+ /** @internal The number of keys stored within each group. */
+ #define LRU_ASSOC 3
+#else
+ #define LRU_ASSOC 4
+#endif
+/** @internal The number of hashes tracked within each group: 10-1 or 12-1. */
+#define LRU_TRACKED ((64 - sizeof(size_t) * LRU_ASSOC) / 4 - 1)
+
+struct lru_group {
+ uint16_t counts[LRU_TRACKED+1]; /*!< Occurrence counters; the last one is special. */
+ uint16_t hashes[LRU_TRACKED+1]; /*!< Top halves of hashes; the last one is unused. */
+ struct lru_item *items[LRU_ASSOC]; /*!< The full items. */
+} CACHE_ALIGNED;
+
+/* The sizes are chosen so lru_group just fits into a single x86 cache line. */
+static_assert(64 == sizeof(struct lru_group)
+ && 64 == LRU_ASSOC * sizeof(void*) + (LRU_TRACKED+1) * 4,
+ "bad sizing for your sizeof(void*)");
+
+struct lru {
+ struct knot_mm *mm, /**< Memory context to use for keys. */
+ *mm_array; /**< Memory context to use for this structure itself. */
+ uint log_groups; /**< Logarithm of the number of LRU groups. */
+ uint val_alignment; /**< Alignment for the values. */
+ struct lru_group groups[] CACHE_ALIGNED; /**< The groups of items. */
+};
+
+/** @internal See lru_free. */
+static inline void lru_free_impl(struct lru *lru)
+{
+ if (!lru)
+ return;
+ lru_free_items_impl(lru);
+ mm_free(lru->mm_array, lru);
+}
+
+/** @internal See lru_reset. */
+static inline void lru_reset_impl(struct lru *lru)
+{
+ lru_free_items_impl(lru);
+ memset(lru->groups, 0, sizeof(lru->groups[0]) * (1 << lru->log_groups));
+}
+
+/** @internal See lru_capacity. */
+static inline uint lru_capacity_impl(struct lru *lru)
+{
+ kr_require(lru);
+ return (1 << lru->log_groups) * LRU_ASSOC;
+}
+
+/** @endcond */
+/** @} (addtogroup generics) */
diff --git a/lib/generic/pack.h b/lib/generic/pack.h
new file mode 100644
index 0000000..18d57db
--- /dev/null
+++ b/lib/generic/pack.h
@@ -0,0 +1,221 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+/**
+ * @file pack.h
+ * @brief A length-prefixed list of objects, also an array list.
+ *
+ * Each object is prefixed by item length, unlike array this structure
+ * permits variable-length data. It is also equivalent to forward-only list
+ * backed by an array.
+ *
+ * @note Maximum object size is 2^16 bytes, see ::pack_objlen_t
+ * @todo If some mistake happens somewhere, the access may end up in an infinite loop.
+ * (equality comparison on pointers)
+ *
+ * # Example usage:
+ *
+ * @code{.c}
+ * pack_t pack;
+ * pack_init(pack);
+ *
+ * // Reserve 2 objects, 6 bytes total
+ * pack_reserve(pack, 2, 4 + 2);
+ *
+ * // Push 2 objects
+ * pack_obj_push(pack, U8("jedi"), 4)
+ * pack_obj_push(pack, U8("\xbe\xef"), 2);
+ *
+ * // Iterate length-value pairs
+ * uint8_t *it = pack_head(pack);
+ * while (it != pack_tail(pack)) {
+ * uint8_t *val = pack_obj_val(it);
+ * it = pack_obj_next(it);
+ * }
+ *
+ * // Remove object
+ * pack_obj_del(pack, U8("jedi"), 4);
+ *
+ * pack_clear(pack);
+ * @endcode
+ *
+ * \addtogroup generics
+ * @{
+ */
+
+#pragma once
+
+#include <stdint.h>
+#include <string.h>
+#include "array.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Packed object length type. */
+typedef uint16_t pack_objlen_t;
+
+/** Pack is defined as an array of bytes */
+typedef array_t(uint8_t) pack_t;
+
+/** Zero-initialize the pack. */
+#define pack_init(pack) \
+ array_init(pack)
+
+/** Make the pack empty and free pointed-to memory (plain malloc/free). */
+#define pack_clear(pack) \
+ array_clear(pack)
+
+/** Make the pack empty and free pointed-to memory.
+ * Mempool usage: pass mm_free and a knot_mm_t* . */
+#define pack_clear_mm(pack, free, baton) \
+ array_clear_mm((pack), (free), (baton))
+
+/** Reserve space for *additional* objects in the pack (plain malloc/free).
+ * @return 0 if success, <0 on failure */
+#define pack_reserve(pack, objs_count, objs_len) \
+ pack_reserve_mm((pack), (objs_count), (objs_len), array_std_reserve, NULL)
+
+/** Reserve space for *additional* objects in the pack.
+ * Mempool usage: pass kr_memreserve and a knot_mm_t* .
+ * @return 0 if success, <0 on failure */
+#define pack_reserve_mm(pack, objs_count, objs_len, reserve, baton) \
+ array_reserve_mm((pack), (pack).len + (sizeof(pack_objlen_t)*(objs_count) + (objs_len)), (reserve), (baton))
+
+/** Return pointer to first packed object.
+ *
+ * Recommended way to iterate:
+ * for (uint8_t *it = pack_head(pack); it != pack_tail(pack); it = pack_obj_next(it))
+ */
+#define pack_head(pack) \
+ ((pack).len > 0 ? &((pack).at[0]) : NULL)
+
+/** Return pack end pointer. */
+#define pack_tail(pack) \
+ ((pack).len > 0 ? &((pack).at[(pack).len]) : NULL)
+
+/** Return packed object length. */
+static inline pack_objlen_t pack_obj_len(uint8_t *it)
+{
+ pack_objlen_t len = 0;
+ if (it != NULL)
+ memcpy(&len, it, sizeof(len));
+ return len;
+}
+
+/** Return packed object value. */
+static inline uint8_t *pack_obj_val(uint8_t *it)
+{
+ if (kr_fails_assert(it))
+ return NULL;
+ return it + sizeof(pack_objlen_t);
+}
+
+/** Return pointer to next packed object. */
+static inline uint8_t *pack_obj_next(uint8_t *it)
+{
+ if (kr_fails_assert(it))
+ return NULL;
+ return pack_obj_val(it) + pack_obj_len(it);
+}
+
+/** Return pointer to the last packed object. */
+static inline uint8_t *pack_last(pack_t pack)
+{
+ if (pack.len == 0)
+ return NULL;
+ uint8_t *it = pack_head(pack);
+ uint8_t *tail = pack_tail(pack);
+ while (true) {
+ uint8_t *next = pack_obj_next(it);
+ if (next == tail)
+ return it;
+ it = next;
+ }
+}
+
+/** Push object to the end of the pack
+ * @return 0 on success, negative number on failure
+ */
+static inline int pack_obj_push(pack_t *pack, const uint8_t *obj, pack_objlen_t len)
+{
+ if (kr_fails_assert(pack && obj))
+ return kr_error(EINVAL);
+ size_t packed_len = len + sizeof(len);
+ if (pack->len + packed_len > pack->cap)
+ return kr_error(ENOSPC);
+
+ uint8_t *endp = pack->at + pack->len;
+ memcpy(endp, (char *)&len, sizeof(len));
+ memcpy(endp + sizeof(len), obj, len);
+ pack->len += packed_len;
+ return 0;
+}
+
+/** Returns a pointer to packed object.
+ * @return pointer to packed object or NULL
+ */
+static inline uint8_t *pack_obj_find(pack_t *pack, const uint8_t *obj, pack_objlen_t len)
+{
+ if (!pack || kr_fails_assert(obj))
+ return NULL;
+ uint8_t *endp = pack_tail(*pack);
+ uint8_t *it = pack_head(*pack);
+ while (it != endp) {
+ uint8_t *val = pack_obj_val(it);
+ if (pack_obj_len(it) == len && memcmp(obj, val, len) == 0)
+ return it;
+ it = pack_obj_next(it);
+ }
+ return NULL;
+}
+
+/** Delete object from the pack
+ * @return 0 on success, negative number on failure
+ */
+static inline int pack_obj_del(pack_t *pack, const uint8_t *obj, pack_objlen_t len)
+{
+ if (!pack || kr_fails_assert(obj))
+ return kr_error(EINVAL);
+ uint8_t *endp = pack_tail(*pack);
+ uint8_t *it = pack_obj_find(pack, obj, len);
+ if (it) {
+ size_t packed_len = len + sizeof(len);
+ memmove(it, it + packed_len, endp - it - packed_len);
+ pack->len -= packed_len;
+ return 0;
+ }
+ return -1;
+}
+
+/** Clone a pack, replacing destination pack; (*dst == NULL) is valid input.
+ * @return kr_error(ENOMEM) on allocation failure. */
+static inline int pack_clone(pack_t **dst, const pack_t *src, knot_mm_t *pool)
+{
+ if (kr_fails_assert(dst && src))
+ return kr_error(EINVAL);
+ /* Get a valid pack_t. */
+ if (!*dst) {
+ *dst = mm_alloc(pool, sizeof(pack_t));
+ if (!*dst) return kr_error(ENOMEM);
+ pack_init(**dst);
+ /* Clone data only if needed */
+ if (src->len == 0) return kr_ok();
+ }
+ /* Replace the contents of the pack_t. */
+ int ret = array_reserve_mm(**dst, src->len, kr_memreserve, pool);
+ if (ret < 0) {
+ return kr_error(ENOMEM);
+ }
+ memcpy((*dst)->at, src->at, src->len);
+ (*dst)->len = src->len;
+ return kr_ok();
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/** @} */
diff --git a/lib/generic/queue.c b/lib/generic/queue.c
new file mode 100644
index 0000000..5bed153
--- /dev/null
+++ b/lib/generic/queue.c
@@ -0,0 +1,140 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#include "lib/generic/queue.h"
+#include <string.h>
+
+extern inline void * queue_head_impl(const struct queue *q);
+
+void queue_init_impl(struct queue *q, size_t item_size)
+{
+ q->len = 0;
+ q->item_size = item_size;
+ q->head = q->tail = NULL;
+ /* Take 128 B (two x86 cache lines), except a small margin
+ * that the allocator can use for its overhead.
+ * Normally (64-bit pointers) this means 16 B header + 13*8 B data. */
+ q->chunk_cap = (128 - offsetof(struct queue_chunk, data)
+ - sizeof(size_t)
+ ) / item_size;
+ if (!q->chunk_cap) q->chunk_cap = 1; /* item_size big enough by itself */
+}
+
+void queue_deinit_impl(struct queue *q)
+{
+ if (kr_fails_assert(q))
+ return;
+ struct queue_chunk *p = q->head;
+ while (p != NULL) {
+ struct queue_chunk *pf = p;
+ p = p->next;
+ free(pf);
+ }
+#ifndef NDEBUG
+ memset(q, 0, sizeof(*q));
+#endif
+}
+
+static struct queue_chunk * queue_chunk_new(const struct queue *q)
+{
+ /* size_t cast is to avoid unintended sign-extension */
+ struct queue_chunk *c = malloc(offsetof(struct queue_chunk, data)
+ + (size_t) q->chunk_cap * (size_t) q->item_size);
+ if (unlikely(!c)) abort(); // simplify stuff
+ memset(c, 0, offsetof(struct queue_chunk, data));
+ c->cap = q->chunk_cap;
+ /* ->begin and ->end are zero, i.e. we optimize for _push
+ * and not _push_head, by default. */
+ return c;
+}
+
+/* Return pointer to the space for the new element. */
+void * queue_push_impl(struct queue *q)
+{
+ kr_require(q);
+ struct queue_chunk *t = q->tail; // shorthand
+ if (unlikely(!t)) {
+ kr_require(!q->head && !q->len);
+ q->head = q->tail = t = queue_chunk_new(q);
+ } else
+ if (t->end == t->cap) {
+ if (t->begin * 2 >= t->cap) {
+ /* Utilization is below 50%, so let's shift (no overlap).
+ * (size_t cast is to avoid unintended sign-extension) */
+ memcpy(t->data, t->data + t->begin * q->item_size,
+ (size_t) (t->end - t->begin) * (size_t) q->item_size);
+ t->end -= t->begin;
+ t->begin = 0;
+ } else {
+ /* Let's grow the tail by another chunk. */
+ kr_require(!t->next);
+ t->next = queue_chunk_new(q);
+ t = q->tail = t->next;
+ }
+ }
+ kr_require(t->end < t->cap);
+ ++(q->len);
+ ++(t->end);
+ return t->data + q->item_size * (t->end - 1);
+}
+
+/* Return pointer to the space for the new element. */
+void * queue_push_head_impl(struct queue *q)
+{
+ /* When we have choice, we optimize for further _push_head,
+ * i.e. when shifting or allocating a chunk,
+ * we store items on the tail-end of the chunk. */
+ kr_require(q);
+ struct queue_chunk *h = q->head; // shorthand
+ if (unlikely(!h)) {
+ kr_require(!q->tail && !q->len);
+ h = q->head = q->tail = queue_chunk_new(q);
+ h->begin = h->end = h->cap;
+ } else
+ if (h->begin == 0) {
+ if (h->end * 2 <= h->cap) {
+ /* Utilization is below 50%, so let's shift (no overlap).
+ * Computations here are simplified due to h->begin == 0.
+ * (size_t cast is to avoid unintended sign-extension) */
+ const int cnt = h->end;
+ memcpy(h->data + (h->cap - cnt) * q->item_size, h->data,
+ (size_t) cnt * (size_t) q->item_size);
+ h->begin = h->cap - cnt;
+ h->end = h->cap;
+ } else {
+ /* Let's grow the head by another chunk. */
+ h = queue_chunk_new(q);
+ h->next = q->head;
+ q->head = h;
+ h->begin = h->end = h->cap;
+ }
+ }
+ kr_require(h->begin > 0);
+ --(h->begin);
+ ++(q->len);
+ return h->data + q->item_size * h->begin;
+}
+
+void queue_pop_impl(struct queue *q)
+{
+ kr_require(q);
+ struct queue_chunk *h = q->head;
+ kr_require(h && h->end > h->begin);
+ if (h->end - h->begin == 1) {
+ /* removing the last element in the chunk */
+ kr_require((q->len == 1) == (q->head == q->tail));
+ if (q->len == 1) {
+ q->tail = NULL;
+ kr_require(!h->next);
+ } else {
+ kr_require(h->next);
+ }
+ q->head = h->next;
+ free(h);
+ } else {
+ ++(h->begin);
+ }
+ --(q->len);
+}
+
diff --git a/lib/generic/queue.h b/lib/generic/queue.h
new file mode 100644
index 0000000..3fa52ce
--- /dev/null
+++ b/lib/generic/queue.h
@@ -0,0 +1,230 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+/**
+ * @file queue.h
+ * @brief A queue, usable for FIFO and LIFO simultaneously.
+ *
+ * Both the head and tail of the queue can be accessed and pushed to,
+ * but only the head can be popped from.
+ *
+ * @note The implementation uses a singly linked list of blocks ("chunks")
+ * where each block stores an array of values (for better efficiency).
+ *
+ * Example usage:
+ * @code{.c}
+ // define new queue type, and init a new queue instance
+ typedef queue_t(int) queue_int_t;
+ queue_int_t q;
+ queue_init(q);
+ // do some operations
+ queue_push(q, 1);
+ queue_push(q, 2);
+ queue_push(q, 3);
+ queue_push(q, 4);
+ queue_pop(q);
+ kr_require(queue_head(q) == 2);
+ kr_require(queue_tail(q) == 4);
+
+ // you may iterate
+ typedef queue_it_t(int) queue_it_int_t;
+ for (queue_it_int_t it = queue_it_begin(q); !queue_it_finished(it);
+ queue_it_next(it)) {
+ ++queue_it_val(it);
+ }
+ kr_require(queue_tail(q) == 5);
+
+ queue_push_head(q, 0);
+ ++queue_tail(q);
+ kr_require(queue_tail(q) == 6);
+ // free it up
+ queue_deinit(q);
+
+ // you may use dynamic allocation for the type itself
+ queue_int_t *qm = malloc(sizeof(queue_int_t));
+ queue_init(*qm);
+ queue_deinit(*qm);
+ free(qm);
+ * @endcode
+ *
+ * \addtogroup generics
+ * @{
+ */
+
+#pragma once
+
+#include "lib/defines.h"
+#include "lib/utils.h"
+#include "contrib/ucw/lib.h"
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+/** @brief The type for queue, parametrized by value type. */
+#define queue_t(type) \
+ union { \
+ type *pdata_t; /* only the *type* information is used */ \
+ struct queue queue; \
+ }
+
+/** @brief Initialize a queue. You can malloc() it the usual way. */
+#define queue_init(q) do { \
+ (void)(((__typeof__(((q).pdata_t)))0) == (void *)0); /* typecheck queue_t */ \
+ queue_init_impl(&(q).queue, sizeof(*(q).pdata_t)); \
+ } while (false)
+
+/** @brief De-initialize a queue: make it invalid and free any inner allocations. */
+#define queue_deinit(q) \
+ queue_deinit_impl(&(q).queue)
+
+/** @brief Push data to queue's tail. (Type-safe version; use _impl() otherwise.) */
+#define queue_push(q, data) \
+ *((__typeof__((q).pdata_t)) queue_push_impl(&(q).queue)) = data
+
+/** @brief Push data to queue's head. (Type-safe version; use _impl() otherwise.) */
+#define queue_push_head(q, data) \
+ *((__typeof__((q).pdata_t)) queue_push_head_impl(&(q).queue)) = data
+
+/** @brief Remove the element at the head.
+ * The queue must not be empty. */
+#define queue_pop(q) \
+ queue_pop_impl(&(q).queue)
+
+/** @brief Return a "reference" to the element at the head (it's an L-value).
+ * The queue must not be empty. */
+#define queue_head(q) \
+ ( *(__typeof__((q).pdata_t)) queue_head_impl(&(q).queue) )
+
+/** @brief Return a "reference" to the element at the tail (it's an L-value).
+ * The queue must not be empty. */
+#define queue_tail(q) \
+ ( *(__typeof__((q).pdata_t)) queue_tail_impl(&(q).queue) )
+
+/** @brief Return the number of elements in the queue (very efficient). */
+#define queue_len(q) \
+ ((const size_t)(q).queue.len)
+
+
+/** @brief Type for queue iterator, parametrized by value type.
+ * It's a simple structure that owns no other resources.
+ * You may NOT use it after doing any push or pop (without _begin again). */
+#define queue_it_t(type) \
+ union { \
+ type *pdata_t; /* only the *type* information is used */ \
+ struct queue_it iter; \
+ }
+
+/** @brief Initialize a queue iterator at the head of the queue.
+ * If you use this in assignment (instead of initialization),
+ * you will unfortunately need to add corresponding type-cast in front.
+ * Beware: there's no type-check between queue and iterator! */
+#define queue_it_begin(q) \
+ { .iter = queue_it_begin_impl(&(q).queue) }
+
+/** @brief Return a "reference" to the current element (it's an L-value) . */
+#define queue_it_val(it) \
+ ( *(__typeof__((it).pdata_t)) queue_it_val_impl(&(it).iter) )
+
+/** @brief Test if the iterator has gone past the last element.
+ * If it has, you may not use _val or _next. */
+#define queue_it_finished(it) \
+ queue_it_finished_impl(&(it).iter)
+
+/** @brief Advance the iterator to the next element. */
+#define queue_it_next(it) \
+ queue_it_next_impl(&(it).iter)
+
+
+
+/* ====================== Internal for the implementation ================== */
+/** @cond internal */
+
+struct queue;
+/* Non-inline functions are exported to be usable from daemon. */
+KR_EXPORT void queue_init_impl(struct queue *q, size_t item_size);
+KR_EXPORT void queue_deinit_impl(struct queue *q);
+KR_EXPORT void * queue_push_impl(struct queue *q);
+KR_EXPORT void * queue_push_head_impl(struct queue *q);
+KR_EXPORT void queue_pop_impl(struct queue *q);
+
+struct queue_chunk;
+struct queue {
+ size_t len; /**< the current number of items in queue */
+ uint16_t chunk_cap; /**< max. number of items in each chunk */
+ uint16_t item_size; /**< sizeof() each item */
+ struct queue_chunk *head, *tail; /*< first and last chunk (or NULLs) */
+};
+
+struct queue_chunk {
+ struct queue_chunk *next; /*< *head -> ... -> *tail; each is non-empty */
+ int16_t begin, end, cap, pad_; /*< indices: zero is closest to head */
+ /*< We could fit into uint8_t for example, but the choice of (3+1)*2 bytes
+ * is a compromise between wasting space and getting a good alignment.
+ * In particular, queue_t(type*) will store the pointers on addresses
+ * aligned to the pointer size, on both 64-bit and 32-bit platforms.
+ */
+ char data[];
+ /**< The item data. We use "char" to satisfy the C99+ aliasing rules.
+ * See C99 section 6.5 Expressions, paragraph 7.
+ * Any type can be accessed through char-pointer,
+ * so we can use a common struct definition
+ * for all types being held.
+ */
+};
+
+KR_EXPORT inline void * queue_head_impl(const struct queue *q)
+{
+ kr_require(q);
+ struct queue_chunk *h = q->head;
+ kr_require(h && h->end > h->begin);
+ return h->data + h->begin * q->item_size;
+}
+
+static inline void * queue_tail_impl(const struct queue *q)
+{
+ kr_require(q);
+ struct queue_chunk *t = q->tail;
+ kr_require(t && t->end > t->begin);
+ return t->data + (t->end - 1) * q->item_size;
+}
+
+struct queue_it {
+ struct queue_chunk *chunk;
+ int16_t pos, item_size;
+};
+
+static inline struct queue_it queue_it_begin_impl(struct queue *q)
+{
+ kr_require(q);
+ return (struct queue_it){
+ .chunk = q->head,
+ .pos = q->head ? q->head->begin : -1,
+ .item_size = q->item_size,
+ };
+}
+
+static inline bool queue_it_finished_impl(struct queue_it *it)
+{
+ return it->chunk == NULL || it->pos >= it->chunk->end;
+}
+
+static inline void * queue_it_val_impl(struct queue_it *it)
+{
+ kr_require(!queue_it_finished_impl(it));
+ return it->chunk->data + it->pos * it->item_size;
+}
+
+static inline void queue_it_next_impl(struct queue_it *it)
+{
+ kr_require(!queue_it_finished_impl(it));
+ ++(it->pos);
+ if (it->pos < it->chunk->end)
+ return;
+ it->chunk = it->chunk->next;
+ it->pos = it->chunk ? it->chunk->begin : -1;
+}
+
+/** @endcond (internal) */
+/** @} (addtogroup generics) */
+
diff --git a/lib/generic/test_array.c b/lib/generic/test_array.c
new file mode 100644
index 0000000..3e95b49
--- /dev/null
+++ b/lib/generic/test_array.c
@@ -0,0 +1,99 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#include "tests/unit/test.h"
+#include "lib/generic/array.h"
+
+knot_mm_t global_mm;
+
+static void test_array(void **state)
+{
+ int ret = 0;
+ array_t(int) arr;
+ array_init(arr);
+
+ /* Basic access */
+ assert_int_equal(arr.len, 0);
+ assert_int_equal(array_push(arr, 5), 0);
+ assert_int_equal(arr.at[0], 5);
+ assert_int_equal(array_tail(arr), 5);
+ array_clear(arr);
+
+ /* Reserve capacity and fill. */
+ assert_true(array_reserve(arr, 5) >= 0);
+ for (unsigned i = 0; i < 100; ++i) {
+ ret = array_push(arr, i);
+ assert_true(ret >= 0);
+ }
+
+ /* Make sure reservation holds. */
+ assert_true(array_reserve(arr, 5) >= 0);
+
+ /* Delete elements. */
+ array_del(arr, 0);
+ while (arr.len > 0) {
+ array_pop(arr);
+ }
+
+ /* Overfill. */
+ for (unsigned i = 0; i < 4096; ++i) {
+ ret = array_push(arr, i);
+ assert_true(ret >= 0);
+ }
+
+ array_clear(arr);
+}
+
+/** Reservation through tracked memory allocator. */
+static int test_reserve(void *baton, void **mem, size_t elm_size, size_t want, size_t *have)
+{
+ if (want > *have) {
+ void *new_mem = mm_alloc(baton, elm_size * want);
+ if (*mem != NULL) {
+ memcpy(new_mem, *mem, (*have) * elm_size);
+ mm_free(baton, *mem);
+ }
+ *mem = new_mem;
+ *have = want;
+ }
+
+ return 0;
+}
+
+/** Reservation through fake memory allocator. */
+static int fake_reserve(void *baton, void **mem, size_t elm_size, size_t want, size_t *have)
+{
+ return -1;
+}
+
+static void test_array_mm(void **state)
+{
+ array_t(int) arr;
+ array_init(arr);
+
+ /* Reserve using fake memory allocator. */
+ assert_false(array_reserve_mm(arr, 5, fake_reserve, NULL) >= 0);
+
+ /* Reserve capacity and fill. */
+ assert_true(array_reserve_mm(arr, 100, test_reserve, &global_mm) >= 0);
+ for (unsigned i = 0; i < 100; ++i) {
+ int ret = array_push(arr, i);
+ assert_true(ret >= 0);
+ }
+
+ array_clear_mm(arr, mm_free, &global_mm);
+
+}
+
+int main(void)
+{
+ test_mm_ctx_init(&global_mm);
+
+ const UnitTest tests[] = {
+ unit_test(test_array),
+ unit_test(test_array_mm)
+ };
+
+ return run_tests(tests);
+}
diff --git a/lib/generic/test_lru.c b/lib/generic/test_lru.c
new file mode 100644
index 0000000..7c2f11f
--- /dev/null
+++ b/lib/generic/test_lru.c
@@ -0,0 +1,111 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "tests/unit/test.h"
+#include "lib/generic/lru.h"
+
+typedef lru_t(int) lru_int_t;
+#define HASH_SIZE 1024
+#define KEY_LEN(x) (strlen(x) + 1)
+
+/*
+ * Sample dictionary
+ */
+static const char *dict[] = {
+ "catagmatic", "prevaricator", "statoscope", "workhand", "benzamide",
+ "alluvia", "fanciful", "bladish", "Tarsius", "unfast", "appropriative",
+ "seraphically", "monkeypod", "deflectometer", "tanglesome", "zodiacal",
+ "physiologically", "economizer", "forcepslike", "betrumpet",
+ "Danization", "broadthroat", "randir", "usherette", "nephropyosis",
+ "hematocyanin", "chrysohermidin", "uncave", "mirksome", "podophyllum",
+ "siphonognathous", "indoor", "featheriness", "forwardation",
+ "archruler", "soricoid", "Dailamite", "carmoisin", "controllability",
+ "unpragmatical", "childless", "transumpt", "productive",
+ "thyreotoxicosis", "oversorrow", "disshadow", "osse", "roar",
+ "pantomnesia", "talcer", "hydrorrhoea", "Satyridae", "undetesting",
+ "smoothbored", "widower", "sivathere", "pendle", "saltation",
+ "autopelagic", "campfight", "unexplained", "Macrorhamphosus",
+ "absconsa", "counterflory", "interdependent", "triact", "reconcentration",
+ "oversharpness", "sarcoenchondroma", "superstimulate", "assessory",
+ "pseudepiscopacy", "telescopically", "ventriloque", "politicaster",
+ "Caesalpiniaceae", "inopportunity", "Helion", "uncompatible",
+ "cephaloclasia", "oversearch", "Mahayanistic", "quarterspace",
+ "bacillogenic", "hamartite", "polytheistical", "unescapableness",
+ "Pterophorus", "cradlemaking", "Hippoboscidae", "overindustrialize",
+ "perishless", "cupidity", "semilichen", "gadge", "detrimental",
+ "misencourage", "toparchia", "lurchingly", "apocatastasis"
+};
+
+static void test_insert(void **state)
+{
+ lru_int_t *lru = *state;
+ int dict_size = sizeof(dict) / sizeof(const char *);
+ int i;
+
+ for (i = 0; i < dict_size; i++) {
+ int *data = lru_get_new(lru, dict[i], KEY_LEN(dict[i]), NULL);
+ if (!data) {
+ continue;
+ }
+ *data = i;
+ assert_true(*lru_get_try(lru, dict[i], KEY_LEN(dict[i])) == i);
+ }
+}
+
+static void test_missing(void **state)
+{
+ lru_int_t *lru = *state;
+ const char *notin = "not in lru";
+ assert_true(lru_get_try(lru, notin, KEY_LEN(notin)) == NULL);
+}
+
+static void test_eviction(void **state)
+{
+ lru_int_t *lru = *state;
+ char key[16];
+ for (unsigned i = 0; i < HASH_SIZE; ++i) {
+ test_randstr(key, sizeof(key));
+ int *data = lru_get_new(lru, key, sizeof(key), NULL);
+ if (!data) {
+ continue;
+ }
+ *data = i;
+ if (*lru_get_try(lru, key, sizeof(key)) != i) {
+ assert_true(0);
+ }
+ }
+}
+
+static void test_init(void **state)
+{
+ lru_int_t *lru;
+ lru_create(&lru, HASH_SIZE, NULL, NULL);
+ assert_non_null(lru);
+ *state = lru;
+}
+
+static void test_deinit(void **state)
+{
+ lru_int_t *lru = *state;
+ lru_free(lru);
+}
+
+/* Program entry point */
+int main(int argc, char **argv)
+{
+ const UnitTest tests[] = {
+ group_test_setup(test_init),
+ unit_test(test_insert),
+ unit_test(test_missing),
+ unit_test(test_eviction),
+ group_test_teardown(test_deinit)
+ };
+
+ return run_group_tests(tests);
+}
diff --git a/lib/generic/test_pack.c b/lib/generic/test_pack.c
new file mode 100644
index 0000000..e1c1ab5
--- /dev/null
+++ b/lib/generic/test_pack.c
@@ -0,0 +1,68 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#include "tests/unit/test.h"
+#include "lib/generic/pack.h"
+
+#define U8(x) (const uint8_t *)(x)
+knot_mm_t global_mm;
+
+static void test_pack_std(void **state)
+{
+ int ret = 0;
+ pack_t pack;
+ pack_init(pack);
+ assert_int_equal(pack.len, 0);
+
+ /* Test that iterator on empty pack works */
+ assert_null(pack_head(pack));
+ assert_null(pack_tail(pack));
+ assert_null(pack_obj_find(&pack, U8(""), 1));
+ assert_int_equal(pack_obj_len(pack_head(pack)), 0);
+ assert_int_equal(pack_obj_del(&pack, U8(""), 1), -1);
+
+ /* Push/delete without reservation. */
+ assert_int_not_equal(pack_obj_push(&pack, U8(""), 1), 0);
+ assert_int_not_equal(pack_obj_del(&pack, U8(""), 1), 0);
+
+ /* Reserve capacity and fill. */
+ assert_true(pack_reserve(pack, 10, 10 * 2) >= 0);
+ for (unsigned i = 0; i < 10; ++i) {
+ ret = pack_obj_push(&pack, U8("de"), 2);
+ assert_true(ret >= 0);
+ }
+
+ /* Iterate */
+ uint8_t *it = pack_head(pack);
+ assert_non_null(it);
+ while (it != pack_tail(pack)) {
+ assert_int_equal(pack_obj_len(it), 2);
+ assert_true(memcmp(pack_obj_val(it), "de", 2) == 0);
+ it = pack_obj_next(it);
+ }
+
+ /* Find */
+ it = pack_obj_find(&pack, U8("de"), 2);
+ assert_non_null(it);
+ it = pack_obj_find(&pack, U8("ed"), 2);
+ assert_null(it);
+
+ /* Delete */
+ assert_int_not_equal(pack_obj_del(&pack, U8("be"), 2), 0);
+ assert_int_equal(pack_obj_del(&pack, U8("de"), 2), 0);
+ assert_int_equal(pack.len, 9*(2+2)); /* 9 objects, length=2 */
+
+ pack_clear(pack);
+}
+
+int main(void)
+{
+ test_mm_ctx_init(&global_mm);
+
+ const UnitTest tests[] = {
+ unit_test(test_pack_std),
+ };
+
+ return run_tests(tests);
+}
diff --git a/lib/generic/test_queue.c b/lib/generic/test_queue.c
new file mode 100644
index 0000000..eb26b01
--- /dev/null
+++ b/lib/generic/test_queue.c
@@ -0,0 +1,71 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#include "tests/unit/test.h"
+#include "lib/generic/queue.h"
+
+/* The main intention is to use queues with pointers, so we test the same-sized int. */
+typedef queue_t(ptrdiff_t) queue_int_t;
+typedef queue_it_t(int) queue_int_it_t;
+
+static void test_int(void **state_)
+{
+ queue_int_t q;
+ queue_init(q);
+
+ /* Case of emptying the queue (and using again) has been broken for a long time. */
+ queue_push(q, 2);
+ queue_pop(q);
+ queue_push(q, 4);
+ queue_pop(q);
+
+ queue_push_head(q, 2);
+ queue_push_head(q, 1);
+ queue_push_head(q, 0);
+ for (int i = 0; i < 100; ++i) {
+ assert_int_equal(queue_head(q), i);
+ queue_push(q, i + 3);
+ queue_pop(q);
+ }
+ assert_int_equal(queue_len(q), 3);
+ for (int i = 99; i > 0; --i) {
+ assert_int_equal(queue_head(q), i + 1);
+ queue_push_head(q, i);
+ }
+ assert_int_equal(queue_len(q), 3 + 99);
+
+ /* Basic iterator test. */
+ {
+ int i = 0;
+ for (queue_int_it_t it = queue_it_begin(q); !queue_it_finished(it);
+ queue_it_next(it)) {
+ ++queue_it_val(it);
+ ++i;
+ }
+ assert_int_equal(queue_len(q), i);
+ }
+
+ queue_deinit(q);
+ queue_init(q);
+
+ for (int i = 0; i < 100; ++i) {
+ queue_push(q, 2*i);
+ queue_push(q, 2*i + 1);
+ assert_int_equal(queue_head(q), i);
+ queue_pop(q);
+ }
+
+ queue_deinit(q);
+}
+
+
+int main(void)
+{
+ const UnitTest tests[] = {
+ unit_test(test_int),
+ };
+
+ return run_tests(tests);
+}
+
diff --git a/lib/generic/test_trie.c b/lib/generic/test_trie.c
new file mode 100644
index 0000000..9ecd67c
--- /dev/null
+++ b/lib/generic/test_trie.c
@@ -0,0 +1,154 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#include "lib/generic/trie.h"
+#include "tests/unit/test.h"
+
+static const char *dict[] = {
+ "catagmatic", "prevaricator", "statoscope", "workhand", "benzamide",
+ "work", "workhands", // have some keys that are prefixes of each other
+ "alluvia", "fanciful", "bladish", "Tarsius", "unfast", "appropriative",
+ "seraphically", "monkeypod", "deflectometer", "tanglesome", "zodiacal",
+ "physiologically", "economizer", "forcepslike", "betrumpet",
+ "Danization", "broadthroat", "randir", "usherette", "nephropyosis",
+ "hematocyanin", "chrysohermidin", "uncave", "mirksome", "podophyllum",
+ "siphonognathous", "indoor", "featheriness", "forwardation",
+ "archruler", "soricoid", "Dailamite", "carmoisin", "controllability",
+ "unpragmatical", "childless", "transumpt", "productive",
+ "thyreotoxicosis", "oversorrow", "disshadow", "osse", "roar",
+ "pantomnesia", "talcer", "hydrorrhoea", "Satyridae", "undetesting",
+ "smoothbored", "widower", "sivathere", "pendle", "saltation",
+ "autopelagic", "campfight", "unexplained", "Macrorhamphosus",
+ "absconsa", "counterflory", "interdependent", "triact", "reconcentration",
+ "oversharpness", "sarcoenchondroma", "superstimulate", "assessory",
+ "pseudepiscopacy", "telescopically", "ventriloque", "politicaster",
+ "Caesalpiniaceae", "inopportunity", "Helion", "uncompatible",
+ "cephaloclasia", "oversearch", "Mahayanistic", "quarterspace",
+ "bacillogenic", "hamartite", "polytheistical", "unescapableness",
+ "Pterophorus", "cradlemaking", "Hippoboscidae", "overindustrialize",
+ "perishless", "cupidity", "semilichen", "gadge", "detrimental",
+ "misencourage", "toparchia", "lurchingly", "apocatastasis"
+};
+#define KEY_LEN(x) (strlen(x) + 1)
+static const int dict_size = sizeof(dict) / sizeof(const char *);
+
+static void test_init(void **state)
+{
+ trie_t *t = trie_create(NULL);
+ assert_non_null(t);
+ *state = t;
+}
+
+static void test_insert(void **state)
+{
+ trie_t *t = *state;
+
+ for (int i = 0; i < dict_size; ++i) {
+ trie_val_t *data = trie_get_ins(t, dict[i], KEY_LEN(dict[i]));
+ assert_non_null(data);
+ assert_null(*data);
+ *data = (char *)NULL + i; // yes, ugly
+ assert_ptr_equal(trie_get_try(t, dict[i], KEY_LEN(dict[i])), data);
+ }
+ assert_int_equal(trie_weight(t), dict_size);
+}
+
+static void test_missing(void **state)
+{
+ trie_t *t = *state;
+ const char *notin = "p";
+ assert_null(trie_get_try(t, notin, KEY_LEN(notin)));
+}
+
+static int cmpstringp(const void *p1, const void *p2)
+{
+ return strcmp(* (char * const *) p1, * (char * const *) p2);
+}
+
+static void test_iter(void **state)
+{
+ // prepare sorted dictionary
+ char *dict_sorted[dict_size];
+ memcpy(dict_sorted, dict, sizeof(dict));
+ qsort(dict_sorted, dict_size, sizeof(dict[0]), cmpstringp);
+
+ // iterate and check the order is consistent
+ trie_t *t = *state;
+ trie_it_t *it = trie_it_begin(t);
+ for (int i = 0; i < dict_size; ++i, trie_it_next(it)) {
+ assert_false(trie_it_finished(it));
+ size_t len;
+ const char *key = trie_it_key(it, &len);
+ assert_int_equal(KEY_LEN(key), len);
+ assert_string_equal(key, dict_sorted[i]);
+ assert_ptr_equal(dict[(char *)*trie_it_val(it) - (char *)NULL],
+ dict_sorted[i]);
+ }
+ assert_true(trie_it_finished(it));
+ trie_it_free(it);
+}
+
+static void test_queue(void **state)
+{
+ trie_t *t = *state;
+ // remove all the elements in ascending order
+ for (int i = 0; i < dict_size; ++i) {
+ char *key;
+ uint32_t len;
+ trie_val_t *data = trie_get_first(t, &key, &len);
+ assert_non_null(key);
+ assert_int_equal(len, KEY_LEN(key));
+ assert_non_null(data);
+ ptrdiff_t key_i = (char *)*data - (char *)NULL;
+ assert_string_equal(key, dict[key_i]);
+
+ len = 30;
+ char key_buf[len];
+ ptrdiff_t key_i_new;
+ int ret = trie_del_first(t, key_buf, &len, (trie_val_t *)&key_i_new);
+ assert_int_equal(ret, KNOT_EOK);
+ assert_int_equal(KEY_LEN(key_buf), len);
+ assert_int_equal(key_i, key_i_new);
+ assert_string_equal(dict[key_i], key_buf);
+ }
+}
+
+static void test_leq_bug(void **state)
+{
+ /* We use different contents of the trie,
+ * so that the particular bug would've been triggered. */
+ trie_t *t = trie_create(NULL);
+ char key = 'a';
+ trie_get_ins(t, &key, sizeof(key));
+
+ key = (char)0xff;
+ trie_val_t *val;
+ int ret = trie_get_leq(t, &key, sizeof(key), &val);
+ assert_int_equal(ret, 1);
+ trie_free(t);
+}
+
+static void test_deinit(void **state)
+{
+ trie_t *t = *state;
+ trie_free(t);
+ *state = NULL;
+}
+
+/* Program entry point */
+int main(int argc, char **argv)
+{
+ const UnitTest tests[] = {
+ group_test_setup(test_init),
+ unit_test(test_insert),
+ unit_test(test_leq_bug),
+ unit_test(test_missing),
+ unit_test(test_iter),
+ unit_test(test_queue),
+ group_test_teardown(test_deinit)
+ };
+
+ return run_group_tests(tests);
+}
+
diff --git a/lib/generic/trie.c b/lib/generic/trie.c
new file mode 100644
index 0000000..f9aceda
--- /dev/null
+++ b/lib/generic/trie.c
@@ -0,0 +1,923 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+
+ The code originated from https://github.com/fanf2/qp/blob/master/qp.c
+ at revision 5f6d93753.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "lib/generic/trie.h"
+#include "lib/utils.h"
+#include "contrib/ucw/lib.h"
+
+#if defined(__i386) || defined(__x86_64) || defined(_M_IX86) \
+ || (defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN) \
+ && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
+
+ /*!
+ * \brief Use a pointer alignment hack to save memory.
+ *
+ * When on, isbranch() relies on the fact that in leaf_t the first pointer
+ * is aligned on multiple of 4 bytes and that the flags bitfield is
+ * overlaid over the lowest two bits of that pointer.
+ * Neither is really guaranteed by the C standards; the second part should
+ * be OK with x86_64 ABI and most likely any other little-endian platform.
+ * It would be possible to manipulate the right bits portably, but it would
+ * complicate the code nontrivially. C++ doesn't even guarantee type-punning.
+ * In debug mode we check this works OK when creating a new trie instance.
+ */
+ #define FLAGS_HACK 1
+#else
+ #define FLAGS_HACK 0
+#endif
+
+typedef unsigned char byte;
+#ifndef uint
+typedef unsigned int uint;
+#define uint uint
+#endif
+typedef uint bitmap_t; /*! Bit-maps, using the range of 1<<0 to 1<<16 (inclusive). */
+
+typedef struct {
+ uint32_t len; // 32 bits are enough for key lengths; probably even 16 bits would be.
+ char chars[];
+} tkey_t;
+
+/*! \brief Leaf of trie. */
+typedef struct {
+ #if !FLAGS_HACK
+ byte flags;
+ #endif
+ tkey_t *key; /*!< The pointer must be aligned to 4-byte multiples! */
+ trie_val_t val;
+} leaf_t;
+
+/*! \brief A trie node is either leaf_t or branch_t. */
+typedef union node node_t;
+
+/*!
+ * \brief Branch node of trie.
+ *
+ * - The flags distinguish whether the node is a leaf_t (0), or a branch
+ * testing the more-important nibble (1) or the less-important one (2).
+ * - It stores the index of the byte that the node tests. The combined
+ * value (index*4 + flags) increases in branch nodes as you go deeper
+ * into the trie. All the keys below a branch are identical up to the
+ * nibble identified by the branch. Indices have to be stored because
+ * we skip any branch nodes that would have a single child.
+ * (Consequently, the skipped parts of key have to be validated in a leaf.)
+ * - The bitmap indicates which subtries are present. The present child nodes
+ * are stored in the twigs array (with no holes between them).
+ * - To simplify storing keys that are prefixes of each other, the end-of-string
+ * position is treated as another nibble value, ordered before all others.
+ * That affects the bitmap and twigs fields.
+ *
+ * \note The branch nodes are never allocated individually, but they are
+ * always part of either the root node or the twigs array of the parent.
+ */
+typedef struct {
+ #if FLAGS_HACK
+ uint32_t flags : 2,
+ bitmap : 17; /*!< The first bitmap bit is for end-of-string child. */
+ #else
+ byte flags;
+ uint32_t bitmap;
+ #endif
+ uint32_t index;
+ node_t *twigs;
+} branch_t;
+
+union node {
+ leaf_t leaf;
+ branch_t branch;
+};
+
+struct trie {
+ node_t root; // undefined when weight == 0, see empty_root()
+ size_t weight;
+ knot_mm_t mm;
+};
+
+/*! \brief Make the root node empty (debug-only). */
+static inline void empty_root(node_t *root) {
+#ifndef NDEBUG
+ *root = (node_t){ .branch = {
+ .flags = 3, // invalid value that fits
+ .bitmap = 0,
+ .index = -1,
+ .twigs = NULL
+ } };
+#endif
+}
+
+/*! \brief Check that unportable code works OK (debug-only). */
+static void assert_portability(void) {
+#if FLAGS_HACK
+ kr_require(((union node){ .leaf = {
+ .key = (tkey_t *)(((uint8_t *)NULL) + 1),
+ .val = NULL
+ } }).branch.flags == 1);
+#endif
+}
+
+/*! \brief Propagate error codes. */
+#define ERR_RETURN(x) \
+ do { \
+ int err_code_ = x; \
+ if (unlikely(err_code_ != KNOT_EOK)) \
+ return err_code_; \
+ } while (false)
+
+/*!
+ * \brief Count the number of set bits.
+ *
+ * \TODO This implementation may be relatively slow on some HW.
+ */
+static uint bitmap_weight(bitmap_t w)
+{
+ kr_require((w & ~((1 << 17) - 1)) == 0); // using the least-important 17 bits
+ return __builtin_popcount(w);
+}
+
+/*! \brief Only keep the lowest bit in the bitmap (least significant -> twigs[0]). */
+static bitmap_t bitmap_lowest_bit(bitmap_t w)
+{
+ kr_require((w & ~((1 << 17) - 1)) == 0); // using the least-important 17 bits
+ return 1 << __builtin_ctz(w);
+}
+
+/*! \brief Test flags to determine type of this node. */
+static bool isbranch(const node_t *t)
+{
+ uint f = t->branch.flags;
+ kr_require(f <= 2);
+ return f != 0;
+}
+
+/*! \brief Make a bitmask for testing a branch bitmap. */
+static bitmap_t nibbit(byte k, uint flags)
+{
+ uint shift = (2 - flags) << 2;
+ uint nibble = (k >> shift) & 0xf;
+ return 1 << (nibble + 1/*because of prefix keys*/);
+}
+
+/*! \brief Extract a nibble from a key and turn it into a bitmask. */
+static bitmap_t twigbit(const node_t *t, const char *key, uint32_t len)
+{
+ kr_require(isbranch(t));
+ uint i = t->branch.index;
+
+ if (i >= len)
+ return 1 << 0; // leaf position
+
+ return nibbit((byte)key[i], t->branch.flags);
+}
+
+/*! \brief Test if a branch node has a child indicated by a bitmask. */
+static bool hastwig(const node_t *t, bitmap_t bit)
+{
+ kr_require(isbranch(t));
+ return t->branch.bitmap & bit;
+}
+
+/*! \brief Compute offset of an existing child in a branch node. */
+static uint twigoff(const node_t *t, bitmap_t b)
+{
+ kr_require(isbranch(t));
+ return bitmap_weight(t->branch.bitmap & (b - 1));
+}
+
+/*! \brief Get pointer to a particular child of a branch node. */
+static node_t* twig(node_t *t, uint i)
+{
+ kr_require(isbranch(t));
+ return &t->branch.twigs[i];
+}
+
+/*!
+ * \brief For a branch nod, compute offset of a child and child count.
+ *
+ * Having this separate might be meaningful for performance optimization.
+ */
+#define TWIGOFFMAX(off, max, t, b) do { \
+ (off) = twigoff((t), (b)); \
+ (max) = bitmap_weight((t)->branch.bitmap);\
+ } while(0)
+
+/*! \brief Simple string comparator. */
+static int key_cmp(const char *k1, uint32_t k1_len, const char *k2, uint32_t k2_len)
+{
+ int ret = memcmp(k1, k2, MIN(k1_len, k2_len));
+ if (ret != 0) {
+ return ret;
+ }
+
+ /* Key string is equal, compare lengths. */
+ if (k1_len == k2_len) {
+ return 0;
+ } else if (k1_len < k2_len) {
+ return -1;
+ } else {
+ return 1;
+ }
+}
+
+trie_t* trie_create(knot_mm_t *mm)
+{
+ assert_portability();
+ trie_t *trie = mm_alloc(mm, sizeof(trie_t));
+ if (trie != NULL) {
+ empty_root(&trie->root);
+ trie->weight = 0;
+ if (mm != NULL)
+ trie->mm = *mm;
+ else
+ mm_ctx_init(&trie->mm);
+ }
+ return trie;
+}
+
+/*! \brief Free anything under the trie node, except for the passed pointer itself. */
+static void clear_trie(node_t *trie, knot_mm_t *mm)
+{
+ if (!isbranch(trie)) {
+ mm_free(mm, trie->leaf.key);
+ } else {
+ branch_t *b = &trie->branch;
+ int len = bitmap_weight(b->bitmap);
+ for (int i = 0; i < len; ++i)
+ clear_trie(b->twigs + i, mm);
+ mm_free(mm, b->twigs);
+ }
+}
+
+void trie_free(trie_t *tbl)
+{
+ if (tbl == NULL)
+ return;
+ if (tbl->weight)
+ clear_trie(&tbl->root, &tbl->mm);
+ mm_free(&tbl->mm, tbl);
+}
+
+void trie_clear(trie_t *tbl)
+{
+ if (kr_fails_assert(tbl))
+ return;
+ if (!tbl->weight)
+ return;
+ clear_trie(&tbl->root, &tbl->mm);
+ empty_root(&tbl->root);
+ tbl->weight = 0;
+}
+
+size_t trie_weight(const trie_t *tbl)
+{
+ kr_require(tbl);
+ return tbl->weight;
+}
+
+struct found {
+ leaf_t *l; /**< the found leaf (NULL if not found) */
+ branch_t *p; /**< the leaf's parent (if exists) */
+ bitmap_t b; /**< bit-mask with a single bit marking l under p */
+};
+/** Search trie for an item with the given key (equality only). */
+static struct found find_equal(trie_t *tbl, const char *key, uint32_t len)
+{
+ kr_require(tbl);
+ struct found ret0;
+ memset(&ret0, 0, sizeof(ret0));
+ if (!tbl->weight)
+ return ret0;
+ /* Current node and parent while descending (returned values basically). */
+ node_t *t = &tbl->root;
+ branch_t *p = NULL;
+ bitmap_t b = 0;
+ while (isbranch(t)) {
+ __builtin_prefetch(t->branch.twigs);
+ b = twigbit(t, key, len);
+ if (!hastwig(t, b))
+ return ret0;
+ p = &t->branch;
+ t = twig(t, twigoff(t, b));
+ }
+ if (key_cmp(key, len, t->leaf.key->chars, t->leaf.key->len) != 0)
+ return ret0;
+ return (struct found) {
+ .l = &t->leaf,
+ .p = p,
+ .b = b,
+ };
+}
+/** Find item with the first key (lexicographical order). */
+static struct found find_first(trie_t *tbl)
+{
+ kr_require(tbl);
+ if (!tbl->weight) {
+ struct found ret0;
+ memset(&ret0, 0, sizeof(ret0));
+ return ret0;
+ }
+ /* Current node and parent while descending (returned values basically). */
+ node_t *t = &tbl->root;
+ branch_t *p = NULL;
+ while (isbranch(t)) {
+ p = &t->branch;
+ t = &p->twigs[0];
+ }
+ return (struct found) {
+ .l = &t->leaf,
+ .p = p,
+ .b = p ? bitmap_lowest_bit(p->bitmap) : 0,
+ };
+}
+
+trie_val_t* trie_get_try(trie_t *tbl, const char *key, uint32_t len)
+{
+ struct found found = find_equal(tbl, key, len);
+ return found.l ? &found.l->val : NULL;
+}
+
+trie_val_t* trie_get_first(trie_t *tbl, char **key, uint32_t *len)
+{
+ struct found found = find_first(tbl);
+ if (!found.l)
+ return NULL;
+ if (key)
+ *key = found.l->key->chars;
+ if (len)
+ *len = found.l->key->len;
+ return &found.l->val;
+}
+
+/** Delete the found element (if any) and return value (unless NULL is passed) */
+static int del_found(trie_t *tbl, struct found found, trie_val_t *val)
+{
+ if (!found.l)
+ return KNOT_ENOENT;
+ mm_free(&tbl->mm, found.l->key);
+ if (val != NULL)
+ *val = found.l->val; // we return trie_val_t directly when deleting
+ --tbl->weight;
+ branch_t * const p = found.p; // short-hand
+ if (unlikely(!p)) { // whole trie was a single leaf
+ kr_require(tbl->weight == 0);
+ empty_root(&tbl->root);
+ return KNOT_EOK;
+ }
+ // remove leaf t as child of p; get child index via pointer arithmetic
+ int ci = ((union node *)found.l) - p->twigs,
+ cc = bitmap_weight(p->bitmap); // child count
+ kr_require(ci >= 0 && ci < cc);
+
+ if (cc == 2) { // collapse binary node p: move the other child to this node
+ node_t *twigs = p->twigs;
+ (*(union node *)p) = twigs[1 - ci]; // it might be a leaf or branch
+ mm_free(&tbl->mm, twigs);
+ return KNOT_EOK;
+ }
+ memmove(p->twigs + ci, p->twigs + ci + 1, sizeof(node_t) * (cc - ci - 1));
+ p->bitmap &= ~found.b;
+ node_t *twigs = mm_realloc(&tbl->mm, p->twigs, sizeof(node_t) * (cc - 1),
+ sizeof(node_t) * cc);
+ if (likely(twigs != NULL))
+ p->twigs = twigs;
+ /* We can ignore mm_realloc failure, only beware that next time
+ * the prev_size passed to it wouldn't be correct; TODO? */
+ return KNOT_EOK;
+}
+
+int trie_del(trie_t *tbl, const char *key, uint32_t len, trie_val_t *val)
+{
+ struct found found = find_equal(tbl, key, len);
+ return del_found(tbl, found, val);
+}
+
+int trie_del_first(trie_t *tbl, char *key, uint32_t *len, trie_val_t *val)
+{
+ struct found found = find_first(tbl);
+ if (!found.l)
+ return KNOT_ENOENT;
+ if (key) {
+ if (!len)
+ return KNOT_EINVAL;
+ if (*len < found.l->key->len)
+ return kr_error(ENOSPC);
+ memcpy(key, found.l->key->chars, found.l->key->len);
+ }
+ if (len) { // makes sense even with key == NULL
+ *len = found.l->key->len;
+ }
+ return del_found(tbl, found, val);
+}
+
+/*!
+ * \brief Stack of nodes, storing a path down a trie.
+ *
+ * The structure also serves directly as the public trie_it_t type,
+ * in which case it always points to the current leaf, unless we've finished
+ * (i.e. it->len == 0).
+ */
+typedef struct trie_it {
+ node_t* *stack; /*!< The stack; malloc is used directly instead of mm. */
+ uint32_t len; /*!< Current length of the stack. */
+ uint32_t alen; /*!< Allocated/available length of the stack. */
+ /*! \brief Initial storage for \a stack; it should fit in many use cases. */
+ node_t* stack_init[60];
+} nstack_t;
+
+/*! \brief Create a node stack containing just the root (or empty). */
+static void ns_init(nstack_t *ns, trie_t *tbl)
+{
+ kr_require(tbl);
+ ns->stack = ns->stack_init;
+ ns->alen = sizeof(ns->stack_init) / sizeof(ns->stack_init[0]);
+ if (tbl->weight) {
+ ns->len = 1;
+ ns->stack[0] = &tbl->root;
+ } else {
+ ns->len = 0;
+ }
+}
+
+/*! \brief Free inside of the stack, i.e. not the passed pointer itself. */
+static void ns_cleanup(nstack_t *ns)
+{
+ if (kr_fails_assert(ns && ns->stack))
+ return;
+ if (likely(ns->stack == ns->stack_init))
+ return;
+ free(ns->stack);
+ #ifndef NDEBUG
+ ns->stack = NULL;
+ ns->alen = 0;
+ #endif
+}
+
+/*! \brief Allocate more space for the stack. */
+static int ns_longer_alloc(nstack_t *ns)
+{
+ ns->alen *= 2;
+ size_t new_size = sizeof(nstack_t) + ns->alen * sizeof(node_t *);
+ node_t **st;
+ if (ns->stack == ns->stack_init) {
+ st = malloc(new_size);
+ if (st != NULL)
+ memcpy(st, ns->stack, ns->len * sizeof(node_t *));
+ } else {
+ st = realloc(ns->stack, new_size);
+ }
+ if (st == NULL)
+ return KNOT_ENOMEM;
+ ns->stack = st;
+ return KNOT_EOK;
+}
+
+/*! \brief Ensure the node stack can be extended by one. */
+static inline int ns_longer(nstack_t *ns)
+{
+ // get a longer stack if needed
+ if (likely(ns->len < ns->alen))
+ return KNOT_EOK;
+ return ns_longer_alloc(ns); // hand-split the part suitable for inlining
+}
+
+/*!
+ * \brief Find the "branching point" as if searching for a key.
+ *
+ * The whole path to the point is kept on the passed stack;
+ * always at least the root will remain on the top of it.
+ * Beware: the precise semantics of this function is rather tricky.
+ * The top of the stack will contain: the corresponding leaf if exact match is found;
+ * or the immediate node below a branching-point-on-edge or the branching-point itself.
+ *
+ * \param info Set position of the point of first mismatch (in index and flags).
+ * \param first Set the value of the first non-matching character (from trie),
+ * optionally; end-of-string character has value -256 (that's why it's int).
+ * Note: the character is converted to *unsigned* char (i.e. 0..255),
+ * as that's the ordering used in the trie.
+ *
+ * \return KNOT_EOK or KNOT_ENOMEM.
+ */
+static int ns_find_branch(nstack_t *ns, const char *key, uint32_t len,
+ branch_t *info, int *first)
+{
+ kr_require(ns && ns->len && info);
+ // First find some leaf with longest matching prefix.
+ while (isbranch(ns->stack[ns->len - 1])) {
+ ERR_RETURN(ns_longer(ns));
+ node_t *t = ns->stack[ns->len - 1];
+ __builtin_prefetch(t->branch.twigs);
+ bitmap_t b = twigbit(t, key, len);
+ // Even if our key is missing from this branch we need to
+ // keep iterating down to a leaf. It doesn't matter which
+ // twig we choose since the keys are all the same up to this
+ // index. Note that blindly using twigoff(t, b) can cause
+ // an out-of-bounds index if it equals twigmax(t).
+ uint i = hastwig(t, b) ? twigoff(t, b) : 0;
+ ns->stack[ns->len++] = twig(t, i);
+ }
+ tkey_t *lkey = ns->stack[ns->len-1]->leaf.key;
+ // Find index of the first char that differs.
+ uint32_t index = 0;
+ while (index < MIN(len,lkey->len)) {
+ if (key[index] != lkey->chars[index])
+ break;
+ else
+ ++index;
+ }
+ info->index = index;
+ if (first)
+ *first = lkey->len > index ? (unsigned char)lkey->chars[index] : -256;
+ // Find flags: which half-byte has matched.
+ uint flags;
+ if (index == len && len == lkey->len) { // found equivalent key
+ info->flags = flags = 0;
+ goto success;
+ }
+ if (likely(index < MIN(len,lkey->len))) {
+ byte k2 = (byte)lkey->chars[index];
+ byte k1 = (byte)key[index];
+ flags = ((k1 ^ k2) & 0xf0) ? 1 : 2;
+ } else { // one is prefix of another
+ flags = 1;
+ }
+ info->flags = flags;
+ // now go up the trie from the current leaf
+ branch_t *t;
+ do {
+ if (unlikely(ns->len == 1))
+ goto success; // only the root stays on the stack
+ t = (branch_t*)ns->stack[ns->len - 2];
+ if (t->index < index || (t->index == index && t->flags < flags))
+ goto success;
+ --ns->len;
+ } while (true);
+success:
+ #ifndef NDEBUG // invariants on successful return
+ kr_require(ns->len);
+ if (isbranch(ns->stack[ns->len - 1])) {
+ t = &ns->stack[ns->len - 1]->branch;
+ kr_require(t->index > index || (t->index == index && t->flags >= flags));
+ }
+ if (ns->len > 1) {
+ t = &ns->stack[ns->len - 2]->branch;
+ kr_require(t->index < index || (t->index == index
+ && (t->flags < flags || (t->flags == 1 && flags == 0))));
+ }
+ #endif
+ return KNOT_EOK;
+}
+
+/*!
+ * \brief Advance the node stack to the last leaf in the subtree.
+ *
+ * \return KNOT_EOK or KNOT_ENOMEM.
+ */
+static int ns_last_leaf(nstack_t *ns)
+{
+ kr_require(ns);
+ do {
+ ERR_RETURN(ns_longer(ns));
+ node_t *t = ns->stack[ns->len - 1];
+ if (!isbranch(t))
+ return KNOT_EOK;
+ int lasti = bitmap_weight(t->branch.bitmap) - 1;
+ kr_require(lasti >= 0);
+ ns->stack[ns->len++] = twig(t, lasti);
+ } while (true);
+}
+
+/*!
+ * \brief Advance the node stack to the first leaf in the subtree.
+ *
+ * \return KNOT_EOK or KNOT_ENOMEM.
+ */
+static int ns_first_leaf(nstack_t *ns)
+{
+ kr_require(ns && ns->len);
+ do {
+ ERR_RETURN(ns_longer(ns));
+ node_t *t = ns->stack[ns->len - 1];
+ if (!isbranch(t))
+ return KNOT_EOK;
+ ns->stack[ns->len++] = twig(t, 0);
+ } while (true);
+}
+
+/*!
+ * \brief Advance the node stack to the leaf that is previous to the current node.
+ *
+ * \note Prefix leaf under the current node DOES count (if present; perhaps questionable).
+ * \return KNOT_EOK on success, KNOT_ENOENT on not-found, or possibly KNOT_ENOMEM.
+ */
+static int ns_prev_leaf(nstack_t *ns)
+{
+ kr_require(ns && ns->len > 0);
+
+ node_t *t = ns->stack[ns->len - 1];
+ if (hastwig(t, 1 << 0)) { // the prefix leaf
+ t = twig(t, 0);
+ ERR_RETURN(ns_longer(ns));
+ ns->stack[ns->len++] = t;
+ return KNOT_EOK;
+ }
+
+ do {
+ if (ns->len < 2)
+ return KNOT_ENOENT; // root without empty key has no previous leaf
+ t = ns->stack[ns->len - 1];
+ node_t *p = ns->stack[ns->len - 2];
+ int pindex = t - p->branch.twigs; // index in parent via pointer arithmetic
+ kr_require(pindex >= 0 && pindex <= 16);
+ if (pindex > 0) { // t isn't the first child -> go down the previous one
+ ns->stack[ns->len - 1] = twig(p, pindex - 1);
+ return ns_last_leaf(ns);
+ }
+ // we've got to go up again
+ --ns->len;
+ } while (true);
+}
+
+/*!
+ * \brief Advance the node stack to the leaf that is successor to the current node.
+ *
+ * \note Prefix leaf or anything else under the current node DOES count.
+ * \return KNOT_EOK on success, KNOT_ENOENT on not-found, or possibly KNOT_ENOMEM.
+ */
+static int ns_next_leaf(nstack_t *ns)
+{
+ kr_require(ns && ns->len > 0);
+
+ node_t *t = ns->stack[ns->len - 1];
+ if (isbranch(t))
+ return ns_first_leaf(ns);
+ do {
+ if (ns->len < 2)
+ return KNOT_ENOENT; // not found, as no more parent is available
+ t = ns->stack[ns->len - 1];
+ node_t *p = ns->stack[ns->len - 2];
+ int pindex = t - p->branch.twigs; // index in parent via pointer arithmetic
+ kr_require(pindex >= 0 && pindex <= 16);
+ int pcount = bitmap_weight(p->branch.bitmap);
+ if (pindex + 1 < pcount) { // t isn't the last child -> go down the next one
+ ns->stack[ns->len - 1] = twig(p, pindex + 1);
+ return ns_first_leaf(ns);
+ }
+ // we've got to go up again
+ --ns->len;
+ } while (true);
+}
+
+int trie_get_leq(trie_t *tbl, const char *key, uint32_t len, trie_val_t **val)
+{
+ kr_require(tbl && val);
+ *val = NULL; // so on failure we can just return;
+ if (tbl->weight == 0)
+ return KNOT_ENOENT;
+ { // Intentionally un-indented; until end of function, to bound cleanup attr.
+ // First find a key with longest-matching prefix
+ __attribute__((cleanup(ns_cleanup)))
+ nstack_t ns_local;
+ ns_init(&ns_local, tbl);
+ nstack_t *ns = &ns_local;
+ branch_t bp;
+ int un_leaf; // first unmatched character in the leaf
+ ERR_RETURN(ns_find_branch(ns, key, len, &bp, &un_leaf));
+ int un_key = bp.index < len ? (unsigned char)key[bp.index] : -256;
+ node_t *t = ns->stack[ns->len - 1];
+ if (bp.flags == 0) { // found exact match
+ *val = &t->leaf.val;
+ return KNOT_EOK;
+ }
+ // Get t: the last node on matching path
+ if (isbranch(t) && t->branch.index == bp.index && t->branch.flags == bp.flags) {
+ // t is OK
+ } else {
+ // the top of the stack was the first unmatched node -> step up
+ if (ns->len == 1) {
+ // root was unmatched already
+ if (un_key < un_leaf)
+ return KNOT_ENOENT;
+ ERR_RETURN(ns_last_leaf(ns));
+ goto success;
+ }
+ --ns->len;
+ t = ns->stack[ns->len - 1];
+ }
+ // Now we re-do the first "non-matching" step in the trie
+ // but try the previous child if key was less (it may not exist)
+ bitmap_t b = twigbit(t, key, len);
+ int i = hastwig(t, b)
+ ? twigoff(t, b) - (un_key < un_leaf)
+ : twigoff(t, b) - 1 /*twigoff returns successor when !hastwig*/;
+ if (i >= 0) {
+ ERR_RETURN(ns_longer(ns));
+ ns->stack[ns->len++] = twig(t, i);
+ ERR_RETURN(ns_last_leaf(ns));
+ } else {
+ ERR_RETURN(ns_prev_leaf(ns));
+ }
+success:
+ kr_require(!isbranch(ns->stack[ns->len - 1]));
+ *val = &ns->stack[ns->len - 1]->leaf.val;
+ return 1;
+ }
+}
+
+/*! \brief Initialize a new leaf, copying the key, and returning failure code. */
+static int mk_leaf(node_t *leaf, const char *key, uint32_t len, knot_mm_t *mm)
+{
+ tkey_t *k = mm_alloc(mm, sizeof(tkey_t) + len);
+ #if FLAGS_HACK
+ kr_require(((uintptr_t)k) % 4 == 0); // we need an aligned pointer
+ #endif
+ if (unlikely(!k))
+ return KNOT_ENOMEM;
+ k->len = len;
+ memcpy(k->chars, key, len);
+ leaf->leaf = (leaf_t){
+ #if !FLAGS_HACK
+ .flags = 0,
+ #endif
+ .val = NULL,
+ .key = k
+ };
+ return KNOT_EOK;
+}
+
+trie_val_t* trie_get_ins(trie_t *tbl, const char *key, uint32_t len)
+{
+ if (kr_fails_assert(tbl))
+ return NULL;
+ // First leaf in an empty tbl?
+ if (unlikely(!tbl->weight)) {
+ if (unlikely(mk_leaf(&tbl->root, key, len, &tbl->mm)))
+ return NULL;
+ ++tbl->weight;
+ return &tbl->root.leaf.val;
+ }
+ { // Intentionally un-indented; until end of function, to bound cleanup attr.
+ // Find the branching-point
+ __attribute__((cleanup(ns_cleanup)))
+ nstack_t ns_local;
+ ns_init(&ns_local, tbl);
+ nstack_t *ns = &ns_local;
+ branch_t bp; // branch-point: index and flags signifying the longest common prefix
+ int k2; // the first unmatched character in the leaf
+ if (unlikely(ns_find_branch(ns, key, len, &bp, &k2)))
+ return NULL;
+ node_t *t = ns->stack[ns->len - 1];
+ if (bp.flags == 0) // the same key was already present
+ return &t->leaf.val;
+ node_t leaf;
+ if (unlikely(mk_leaf(&leaf, key, len, &tbl->mm)))
+ return NULL;
+
+ if (isbranch(t) && bp.index == t->branch.index && bp.flags == t->branch.flags) {
+ // The node t needs a new leaf child.
+ bitmap_t b1 = twigbit(t, key, len);
+ kr_require(!hastwig(t, b1));
+ uint s, m; TWIGOFFMAX(s, m, t, b1); // new child position and original child count
+ node_t *twigs = mm_realloc(&tbl->mm, t->branch.twigs,
+ sizeof(node_t) * (m + 1), sizeof(node_t) * m);
+ if (unlikely(!twigs))
+ goto err_leaf;
+ memmove(twigs + s + 1, twigs + s, sizeof(node_t) * (m - s));
+ twigs[s] = leaf;
+ t->branch.twigs = twigs;
+ t->branch.bitmap |= b1;
+ ++tbl->weight;
+ return &twigs[s].leaf.val;
+ } else {
+ // We need to insert a new binary branch with leaf at *t.
+ // Note: it works the same for the case where we insert above root t.
+ #ifndef NDEBUG
+ if (ns->len > 1) {
+ node_t *pt = ns->stack[ns->len - 2];
+ kr_require(hastwig(pt, twigbit(pt, key, len)));
+ }
+ #endif
+ node_t *twigs = mm_alloc(&tbl->mm, sizeof(node_t) * 2);
+ if (unlikely(!twigs))
+ goto err_leaf;
+ node_t t2 = *t; // Save before overwriting t.
+ t->branch.flags = bp.flags;
+ t->branch.index = bp.index;
+ t->branch.twigs = twigs;
+ bitmap_t b1 = twigbit(t, key, len);
+ bitmap_t b2 = unlikely(k2 == -256) ? (1 << 0) : nibbit(k2, bp.flags);
+ t->branch.bitmap = b1 | b2;
+ *twig(t, twigoff(t, b1)) = leaf;
+ *twig(t, twigoff(t, b2)) = t2;
+ ++tbl->weight;
+ return &twig(t, twigoff(t, b1))->leaf.val;
+ };
+err_leaf:
+ mm_free(&tbl->mm, leaf.leaf.key);
+ return NULL;
+ }
+}
+
+/*! \brief Apply a function to every trie_val_t*, in order; a recursive solution. */
+static int apply_trie(node_t *t, int (*f)(trie_val_t *, void *), void *d)
+{
+ kr_require(t);
+ if (!isbranch(t))
+ return f(&t->leaf.val, d);
+ int child_count = bitmap_weight(t->branch.bitmap);
+ for (int i = 0; i < child_count; ++i)
+ ERR_RETURN(apply_trie(twig(t, i), f, d));
+ return KNOT_EOK;
+}
+
+int trie_apply(trie_t *tbl, int (*f)(trie_val_t *, void *), void *d)
+{
+ kr_require(tbl && f);
+ if (!tbl->weight)
+ return KNOT_EOK;
+ return apply_trie(&tbl->root, f, d);
+}
+
+/*! \brief Apply a function to every key + trie_val_t*, in order; a recursive solution. */
+static int apply_trie_with_key(node_t *t, int (*f)(const char *, uint32_t, trie_val_t *, void *), void *d)
+{
+ kr_require(t);
+ if (!isbranch(t))
+ return f(t->leaf.key->chars, t->leaf.key->len, &t->leaf.val, d);
+ int child_count = bitmap_weight(t->branch.bitmap);
+ for (int i = 0; i < child_count; ++i)
+ ERR_RETURN(apply_trie_with_key(twig(t, i), f, d));
+ return KNOT_EOK;
+}
+
+int trie_apply_with_key(trie_t *tbl, int (*f)(const char *, uint32_t, trie_val_t *, void *), void *d)
+{
+ kr_require(tbl && f);
+ if (!tbl->weight)
+ return KNOT_EOK;
+ return apply_trie_with_key(&tbl->root, f, d);
+}
+
+/* These are all thin wrappers around static Tns* functions. */
+trie_it_t* trie_it_begin(trie_t *tbl)
+{
+ if (kr_fails_assert(tbl))
+ return NULL;
+ trie_it_t *it = malloc(sizeof(nstack_t));
+ if (!it)
+ return NULL;
+ ns_init(it, tbl);
+ if (it->len == 0) // empty tbl
+ return it;
+ if (ns_first_leaf(it)) {
+ ns_cleanup(it);
+ free(it);
+ return NULL;
+ }
+ return it;
+}
+
+void trie_it_next(trie_it_t *it)
+{
+ kr_require(it && it->len);
+ if (ns_next_leaf(it) != KNOT_EOK)
+ it->len = 0;
+}
+
+bool trie_it_finished(trie_it_t *it)
+{
+ kr_require(it);
+ return it->len == 0;
+}
+
+void trie_it_free(trie_it_t *it)
+{
+ if (!it)
+ return;
+ ns_cleanup(it);
+ free(it);
+}
+
+const char* trie_it_key(trie_it_t *it, size_t *len)
+{
+ kr_require(it && it->len);
+ node_t *t = it->stack[it->len - 1];
+ kr_require(!isbranch(t));
+ tkey_t *key = t->leaf.key;
+ if (len)
+ *len = key->len;
+ return key->chars;
+}
+
+trie_val_t* trie_it_val(trie_it_t *it)
+{
+ kr_require(it && it->len);
+ node_t *t = it->stack[it->len - 1];
+ kr_require(!isbranch(t));
+ return &t->leaf.val;
+}
diff --git a/lib/generic/trie.h b/lib/generic/trie.h
new file mode 100644
index 0000000..a5f0347
--- /dev/null
+++ b/lib/generic/trie.h
@@ -0,0 +1,150 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#include <libknot/mm_ctx.h>
+#include "lib/defines.h"
+
+/*!
+ * \brief Native API of QP-tries:
+ *
+ * - keys are char strings, not necessarily zero-terminated,
+ * the structure copies the contents of the passed keys
+ * - values are void* pointers, typically you get an ephemeral pointer to it
+ * - key lengths are limited by 2^32-1 ATM
+ *
+ * XXX EDITORS: trie.{h,c} are synced from
+ * https://gitlab.nic.cz/knot/knot-dns/tree/68352fc969/src/contrib/qp-trie
+ * only with simple adjustments, mostly include lines, KR_EXPORT and assertions.
+ */
+
+/*! \brief Element value. */
+typedef void* trie_val_t;
+
+/*! \brief Opaque structure holding a QP-trie. */
+typedef struct trie trie_t;
+
+/*! \brief Opaque type for holding a QP-trie iterator. */
+typedef struct trie_it trie_it_t;
+
+/*! \brief Create a trie instance. Pass NULL to use malloc+free. */
+KR_EXPORT
+trie_t* trie_create(knot_mm_t *mm);
+
+/*! \brief Free a trie instance. */
+KR_EXPORT
+void trie_free(trie_t *tbl);
+
+/*! \brief Clear a trie instance (make it empty). */
+KR_EXPORT
+void trie_clear(trie_t *tbl);
+
+/*! \brief Return the number of keys in the trie. */
+KR_EXPORT
+size_t trie_weight(const trie_t *tbl);
+
+/*! \brief Search the trie, returning NULL on failure. */
+KR_EXPORT
+trie_val_t* trie_get_try(trie_t *tbl, const char *key, uint32_t len);
+
+/*!
+ * \brief Return pointer to the minimum. Optionally with key and its length. */
+KR_EXPORT
+trie_val_t* trie_get_first(trie_t *tbl, char **key, uint32_t *len);
+
+/*! \brief Search the trie, inserting NULL trie_val_t on failure. */
+KR_EXPORT
+trie_val_t* trie_get_ins(trie_t *tbl, const char *key, uint32_t len);
+
+/*!
+ * \brief Search for less-or-equal element.
+ *
+ * \param tbl Trie.
+ * \param key Searched key.
+ * \param len Key length.
+ * \param val Must be valid; it will be set to NULL if not found or errored.
+ * \return KNOT_EOK for exact match, 1 for previous, KNOT_ENOENT for not-found,
+ * or KNOT_E*.
+ */
+KR_EXPORT
+int trie_get_leq(trie_t *tbl, const char *key, uint32_t len, trie_val_t **val);
+
+/*!
+ * \brief Apply a function to every trie_val_t, in order.
+ *
+ * \param d Parameter passed as the second argument to f().
+ * \return First nonzero from f() or zero (i.e. KNOT_EOK).
+ */
+KR_EXPORT
+int trie_apply(trie_t *tbl, int (*f)(trie_val_t *, void *), void *d);
+
+/*!
+ * \brief Apply a function to every trie_val_t, in order.
+ *
+ * It's like trie_apply() but additionally passes keys and their lengths.
+ *
+ * \param d Parameter passed as the second argument to f().
+ * \return First nonzero from f() or zero (i.e. KNOT_EOK).
+ */
+KR_EXPORT
+int trie_apply_with_key(trie_t *tbl, int (*f)(const char *, uint32_t, trie_val_t *, void *), void *d);
+
+/*!
+ * \brief Remove an item, returning KNOT_EOK if succeeded or KNOT_ENOENT if not found.
+ *
+ * If val!=NULL and deletion succeeded, the deleted value is set.
+ */
+KR_EXPORT
+int trie_del(trie_t *tbl, const char *key, uint32_t len, trie_val_t *val);
+
+/*!
+ * \brief Remove the first item, returning KNOT_EOK on success.
+ *
+ * You may optionally get the key and/or value.
+ * The key is copied, so you need to pass sufficient len,
+ * otherwise kr_error(ENOSPC) is returned.
+ */
+KR_EXPORT
+int trie_del_first(trie_t *tbl, char *key, uint32_t *len, trie_val_t *val);
+
+/*! \brief Create a new iterator pointing to the first element (if any). */
+KR_EXPORT
+trie_it_t* trie_it_begin(trie_t *tbl);
+
+/*!
+ * \brief Advance the iterator to the next element.
+ *
+ * Iteration is in ascending lexicographical order.
+ * In particular, the empty string would be considered as the very first.
+ *
+ * \note You may not use this function if the trie's key-set has been modified
+ * during the lifetime of the iterator (modifying values only is OK).
+ */
+KR_EXPORT
+void trie_it_next(trie_it_t *it);
+
+/*! \brief Test if the iterator has gone past the last element. */
+KR_EXPORT
+bool trie_it_finished(trie_it_t *it);
+
+/*! \brief Free any resources of the iterator. It's OK to call it on NULL. */
+KR_EXPORT
+void trie_it_free(trie_it_t *it);
+
+/*!
+ * \brief Return pointer to the key of the current element.
+ *
+ * \note The optional len is uint32_t internally but size_t is better for our usage,
+ * as it is without an additional type conversion.
+ */
+KR_EXPORT
+const char* trie_it_key(trie_it_t *it, size_t *len);
+
+/*! \brief Return pointer to the value of the current element (writable). */
+KR_EXPORT
+trie_val_t* trie_it_val(trie_it_t *it);
diff --git a/lib/generic/trie.spdx b/lib/generic/trie.spdx
new file mode 100644
index 0000000..e8d52f2
--- /dev/null
+++ b/lib/generic/trie.spdx
@@ -0,0 +1,10 @@
+SPDXVersion: SPDX-2.1
+DataLicense: CC0-1.0
+SPDXID: SPDXRef-DOCUMENT
+DocumentName: knotdns-trie
+DocumentNamespace: http://spdx.org/spdxdocs/spdx-v2.1-f99c0e11-6afb-46ce-af96-0955a83957bb
+
+PackageName: knotdns-trie
+PackageDownloadLocation: git+https://gitlab.nic.cz/knot/knot-dns.git@68352fc969bc04aa4aa8203e113ce747d887f410#src/contrib/qp-trie/trie.c
+PackageOriginator: Organization: Knot DNS contributors
+PackageLicenseDeclared: GPL-3.0-or-later
diff --git a/lib/layer.h b/lib/layer.h
new file mode 100644
index 0000000..7721560
--- /dev/null
+++ b/lib/layer.h
@@ -0,0 +1,107 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#include "kresconfig.h"
+#include "lib/defines.h"
+#include "lib/utils.h"
+
+/** Layer processing states. Only one value at a time (but see TODO).
+ *
+ * Each state represents the state machine transition,
+ * and determines readiness for the next action.
+ * See struct kr_layer_api for the actions.
+ *
+ * TODO: the cookie module sometimes sets (_FAIL | _DONE) on purpose (!)
+ */
+enum kr_layer_state {
+ KR_STATE_CONSUME = 1 << 0, /*!< Consume data. */
+ KR_STATE_PRODUCE = 1 << 1, /*!< Produce data. */
+
+ /*! Finished successfully or a special case: in CONSUME phase this can
+ * be used (by iterator) to do a transition to PRODUCE phase again,
+ * in which case the packet wasn't accepted for some reason. */
+ KR_STATE_DONE = 1 << 2,
+
+ KR_STATE_FAIL = 1 << 3, /*!< Error. */
+ KR_STATE_YIELD = 1 << 4, /*!< Paused, waiting for a sub-query. */
+};
+
+/** Check that a kr_layer_state makes sense. We're not very strict ATM. */
+static inline bool kr_state_consistent(enum kr_layer_state s)
+{
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wtautological-constant-out-of-range-compare"
+#pragma clang diagnostic ignored "-Wtautological-unsigned-enum-zero-compare"
+#endif
+ return s >= 0 && s < (1 << 5);
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+}
+
+/* Forward declarations. */
+struct kr_layer_api;
+
+/** Packet processing context. */
+typedef struct kr_layer {
+ int state; /*!< The current state; bitmap of enum kr_layer_state. */
+ struct kr_request *req; /*!< The corresponding request. */
+ const struct kr_layer_api *api;
+ knot_pkt_t *pkt; /*!< In glue for lua kr_layer_api it's used to pass the parameter. */
+ struct sockaddr *dst; /*!< In glue for checkout layer it's used to pass the parameter. */
+ bool is_stream; /*!< In glue for checkout layer it's used to pass the parameter. */
+} kr_layer_t;
+
+/** Packet processing module API. All functions return the new kr_layer_state.
+ *
+ * Lua modules are allowed to return nil/nothing, meaning the state shall not change.
+ */
+struct kr_layer_api {
+ /** Start of processing the DNS request. */
+ int (*begin)(kr_layer_t *ctx);
+
+ int (*reset)(kr_layer_t *ctx);
+
+ /** Paired to begin, called both on successes and failures. */
+ int (*finish)(kr_layer_t *ctx);
+
+ /** Process an answer from upstream or from cache.
+ * Lua API: call is omitted iff (state & KR_STATE_FAIL). */
+ int (*consume)(kr_layer_t *ctx, knot_pkt_t *pkt);
+
+ /** Produce either an answer to the request or a query for upstream (or fail).
+ * Lua API: call is omitted iff (state & KR_STATE_FAIL). */
+ int (*produce)(kr_layer_t *ctx, knot_pkt_t *pkt);
+
+ /** Finalises the outbound query packet with the knowledge of the IP addresses.
+ * The checkout layer doesn't persist the state, so canceled subrequests
+ * don't affect the resolution or rest of the processing.
+ * Lua API: call is omitted iff (state & KR_STATE_FAIL). */
+ int (*checkout)(kr_layer_t *ctx, knot_pkt_t *packet, struct sockaddr *dst, int type);
+
+ /** Finalises the answer.
+ * Last chance to affect what will get into the answer, including EDNS.
+ * Not called if the packet is being dropped. */
+ int (*answer_finalize)(kr_layer_t *ctx);
+
+ /** The C module can store anything in here. */
+ void *data;
+
+ /** Internal to ./daemon/ffimodule.c. */
+ int cb_slots[];
+};
+
+typedef struct kr_layer_api kr_layer_api_t;
+
+/** Pickled layer state (api, input, state). */
+struct kr_layer_pickle {
+ struct kr_layer_pickle *next;
+ const struct kr_layer_api *api;
+ knot_pkt_t *pkt;
+ unsigned state;
+};
+
diff --git a/lib/layer/cache.c b/lib/layer/cache.c
new file mode 100644
index 0000000..2f1ba60
--- /dev/null
+++ b/lib/layer/cache.c
@@ -0,0 +1,20 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#include "lib/module.h"
+#include "lib/cache/api.h"
+
+/** Module implementation. */
+int cache_init(struct kr_module *self)
+{
+ static const kr_layer_api_t layer = {
+ .produce = &cache_peek,
+ .consume = &cache_stash,
+ };
+ self->layer = &layer;
+ return kr_ok();
+}
+
+KR_MODULE_EXPORT(cache) /* useless for builtin module, but let's be consistent */
+
diff --git a/lib/layer/iterate.c b/lib/layer/iterate.c
new file mode 100644
index 0000000..edc666e
--- /dev/null
+++ b/lib/layer/iterate.c
@@ -0,0 +1,1235 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+/** @file iterate.c
+ *
+ * This builtin module is mainly active in the consume phase.
+ * Primary responsibilities:
+ * - Classify the packet as auth/nonauth and change its AA flag accordingly.
+ * - Pick interesting RRs to kr_request::answ_selected and ::auth_selected,
+ * NEW: and classify their rank, except for validation status.
+ * - Update kr_query::zone_cut (in case of referral).
+ * - Interpret CNAMEs.
+ * - Prepare the followup query - either inline or as another kr_query
+ * (CNAME jumps create a new "sibling" query).
+ */
+
+#include <sys/time.h>
+#include <arpa/inet.h>
+
+#include <contrib/cleanup.h>
+#include <libknot/descriptor.h>
+#include <libknot/rrtype/rdname.h>
+#include <libknot/rrtype/rrsig.h>
+
+#include "lib/layer/iterate.h"
+#include "lib/resolve.h"
+#include "lib/rplan.h"
+#include "lib/defines.h"
+#include "lib/selection.h"
+#include "lib/module.h"
+#include "lib/dnssec/ta.h"
+
+#define VERBOSE_MSG(...) kr_log_q(req->current_query, ITERATOR, __VA_ARGS__)
+#define QVERBOSE_MSG(qry, ...) kr_log_q(qry, ITERATOR, __VA_ARGS__)
+#define WITH_VERBOSE(qry) if (kr_log_is_debug_qry(ITERATOR, (qry)))
+
+/* Iterator often walks through packet section, this is an abstraction. */
+typedef int (*rr_callback_t)(const knot_rrset_t *, unsigned, struct kr_request *);
+
+/** Return minimized QNAME/QTYPE for current zone cut. */
+static const knot_dname_t *minimized_qname(struct kr_query *query, uint16_t *qtype)
+{
+ /* Minimization disabled. */
+ const knot_dname_t *qname = query->sname;
+ if (qname[0] == '\0' || query->flags.NO_MINIMIZE || query->flags.STUB) {
+ return qname;
+ }
+
+ /* Minimize name to contain current zone cut + 1 label. */
+ int cut_labels = knot_dname_labels(query->zone_cut.name, NULL);
+ int qname_labels = knot_dname_labels(qname, NULL);
+ while(qname[0] && qname_labels > cut_labels + 1) {
+ qname = knot_wire_next_label(qname, NULL);
+ qname_labels -= 1;
+ }
+
+ /* Hide QTYPE if minimized. */
+ if (qname != query->sname) {
+ *qtype = KNOT_RRTYPE_NS;
+ }
+
+ return qname;
+}
+
+/** Answer is paired to query. */
+static bool is_paired_to_query(const knot_pkt_t *answer, struct kr_query *query)
+{
+ uint16_t qtype = query->stype;
+ const knot_dname_t *qname = minimized_qname(query, &qtype);
+
+ /* ID should already match, thanks to session_tasklist_del_msgid()
+ * in worker_submit(), but it won't hurt to check again. */
+ return query->id == knot_wire_get_id(answer->wire) &&
+ knot_wire_get_qdcount(answer->wire) == 1 &&
+ query->sclass == knot_pkt_qclass(answer) &&
+ qtype == knot_pkt_qtype(answer) &&
+ /* qry->secret had been xor-applied to answer already,
+ * so this also checks for correctness of case randomization */
+ knot_dname_is_equal(qname, kr_pkt_qname_raw(answer));
+}
+
+/** Relaxed rule for AA, either AA=1 or SOA matching zone cut is required. */
+static bool is_authoritative(const knot_pkt_t *answer, struct kr_query *query)
+{
+ if (knot_wire_get_aa(answer->wire)) {
+ return true;
+ }
+
+ const knot_pktsection_t *ns = knot_pkt_section(answer, KNOT_AUTHORITY);
+ for (unsigned i = 0; i < ns->count; ++i) {
+ const knot_rrset_t *rr = knot_pkt_rr(ns, i);
+ if (rr->type == KNOT_RRTYPE_SOA
+ && knot_dname_in_bailiwick(rr->owner, query->zone_cut.name) >= 0) {
+ return true;
+ }
+ }
+
+#ifndef STRICT_MODE
+ /* Last resort to work around broken auths, if the zone cut is at the QNAME. */
+ if (knot_dname_is_equal(query->zone_cut.name, knot_pkt_qname(answer))) {
+ return true;
+ }
+#endif
+
+ /* Some authoritative servers are hopelessly broken, allow lame answers in permissive mode. */
+ if (query->flags.PERMISSIVE) {
+ return true;
+ }
+
+ return false;
+}
+
+int kr_response_classify(const knot_pkt_t *pkt)
+{
+ const knot_pktsection_t *an = knot_pkt_section(pkt, KNOT_ANSWER);
+ switch (knot_wire_get_rcode(pkt->wire)) {
+ case KNOT_RCODE_NOERROR:
+ return (an->count == 0) ? PKT_NODATA : PKT_NOERROR;
+ case KNOT_RCODE_NXDOMAIN:
+ return PKT_NXDOMAIN;
+ case KNOT_RCODE_REFUSED:
+ return PKT_REFUSED;
+ default:
+ return PKT_ERROR;
+ }
+}
+
+/** @internal Filter ANY or loopback addresses. */
+static bool is_valid_addr(const uint8_t *addr, size_t len)
+{
+ if (len == sizeof(struct in_addr)) {
+ /* Filter ANY and 127.0.0.0/8 */
+ uint32_t ip_host; /* Memcpy is safe for unaligned case (on non-x86) */
+ memcpy(&ip_host, addr, sizeof(ip_host));
+ ip_host = ntohl(ip_host);
+ if (ip_host == 0 || (ip_host & 0xff000000) == 0x7f000000) {
+ return false;
+ }
+ } else if (len == sizeof(struct in6_addr)) {
+ struct in6_addr ip6_mask;
+ memset(&ip6_mask, 0, sizeof(ip6_mask));
+ /* All except last byte are zeroed, last byte defines ANY/::1 */
+ if (memcmp(addr, ip6_mask.s6_addr, sizeof(ip6_mask.s6_addr) - 1) == 0) {
+ return (addr[len - 1] > 1);
+ }
+ }
+ return true;
+}
+
+/** @internal Update NS address from record \a rr. Return _FAIL on error. */
+static int update_nsaddr(const knot_rrset_t *rr, struct kr_query *query, int *glue_cnt)
+{
+ if (rr->type == KNOT_RRTYPE_A || rr->type == KNOT_RRTYPE_AAAA) {
+ const knot_rdata_t *rdata = rr->rrs.rdata;
+ const int a_len = rr->type == KNOT_RRTYPE_A
+ ? sizeof(struct in_addr) : sizeof(struct in6_addr);
+ if (a_len != rdata->len) {
+ QVERBOSE_MSG(query, "<= ignoring invalid glue, length %d != %d\n",
+ (int)rdata->len, a_len);
+ return KR_STATE_FAIL;
+ }
+ char name_str[KR_DNAME_STR_MAXLEN];
+ char addr_str[INET6_ADDRSTRLEN];
+ WITH_VERBOSE(query) {
+ const int af = (rr->type == KNOT_RRTYPE_A) ? AF_INET : AF_INET6;
+ knot_dname_to_str(name_str, rr->owner, sizeof(name_str));
+ name_str[sizeof(name_str) - 1] = 0;
+ inet_ntop(af, rdata->data, addr_str, sizeof(addr_str));
+ }
+ if (!(query->flags.ALLOW_LOCAL) &&
+ !is_valid_addr(rdata->data, rdata->len)) {
+ QVERBOSE_MSG(query, "<= ignoring invalid glue for "
+ "'%s': '%s'\n", name_str, addr_str);
+ return KR_STATE_CONSUME; /* Ignore invalid addresses */
+ }
+ int ret = kr_zonecut_add(&query->zone_cut, rr->owner, rdata->data, rdata->len);
+ if (ret != 0) {
+ return KR_STATE_FAIL;
+ }
+
+ ++*glue_cnt; /* reduced verbosity */
+ /* QVERBOSE_MSG(query, "<= using glue for "
+ "'%s': '%s'\n", name_str, addr_str);
+ */
+ }
+ return KR_STATE_CONSUME;
+}
+
+enum { GLUE_COUNT_THROTTLE = 26 };
+
+/** @internal From \a pkt, fetch glue records for name \a ns, and update the cut etc.
+ *
+ * \param glue_cnt the number of accepted addresses (to be incremented)
+ */
+static void fetch_glue(knot_pkt_t *pkt, const knot_dname_t *ns, bool in_bailiwick,
+ struct kr_request *req, const struct kr_query *qry, int *glue_cnt)
+{
+ ranked_rr_array_t *selected[] = kr_request_selected(req);
+ for (knot_section_t i = KNOT_ANSWER; i <= KNOT_ADDITIONAL; ++i) {
+ const knot_pktsection_t *sec = knot_pkt_section(pkt, i);
+ for (unsigned k = 0; k < sec->count; ++k) {
+ const knot_rrset_t *rr = knot_pkt_rr(sec, k);
+ if (!knot_dname_is_equal(ns, rr->owner)) {
+ continue;
+ }
+ if ((rr->type != KNOT_RRTYPE_A) &&
+ (rr->type != KNOT_RRTYPE_AAAA)) {
+ continue;
+ }
+
+ uint8_t rank = (in_bailiwick && i == KNOT_ANSWER)
+ ? (KR_RANK_INITIAL | KR_RANK_AUTH) : KR_RANK_OMIT;
+ (void) kr_ranked_rrarray_add(selected[i], rr, rank,
+ false, qry->uid, &req->pool);
+
+ if ((rr->type == KNOT_RRTYPE_A) &&
+ (req->ctx->options.NO_IPV4)) {
+ QVERBOSE_MSG(qry, "<= skipping IPv4 glue due to network settings\n");
+ continue;
+ }
+ if ((rr->type == KNOT_RRTYPE_AAAA) &&
+ (req->ctx->options.NO_IPV6)) {
+ QVERBOSE_MSG(qry, "<= skipping IPv6 glue due to network settings\n");
+ continue;
+ }
+ (void) update_nsaddr(rr, req->current_query, glue_cnt);
+ /* If we reach limit on total glue addresses,
+ * we only load the first one per NS name (the one just above). */
+ if (*glue_cnt > GLUE_COUNT_THROTTLE)
+ break;
+ }
+ }
+}
+
+/** Attempt to find glue for given nameserver name (best effort). */
+static bool has_glue(knot_pkt_t *pkt, const knot_dname_t *ns)
+{
+ for (knot_section_t i = KNOT_ANSWER; i <= KNOT_ADDITIONAL; ++i) {
+ const knot_pktsection_t *sec = knot_pkt_section(pkt, i);
+ for (unsigned k = 0; k < sec->count; ++k) {
+ const knot_rrset_t *rr = knot_pkt_rr(sec, k);
+ if (knot_dname_is_equal(ns, rr->owner) &&
+ (rr->type == KNOT_RRTYPE_A || rr->type == KNOT_RRTYPE_AAAA)) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+/** @internal Update the cut with another NS(+glue) record.
+ * @param current_cut is cut name before this packet.
+ * @return _DONE if cut->name changes, _FAIL on error, and _CONSUME otherwise. */
+static int update_cut(knot_pkt_t *pkt, const knot_rrset_t *rr,
+ struct kr_request *req, const knot_dname_t *current_cut,
+ int *glue_cnt)
+{
+ struct kr_query *qry = req->current_query;
+ struct kr_zonecut *cut = &qry->zone_cut;
+ int state = KR_STATE_CONSUME;
+
+ /* New authority MUST be at/below the authority of the current cut;
+ * also qname must be below new authority;
+ * otherwise it's a possible cache injection attempt. */
+ const bool ok = knot_dname_in_bailiwick(rr->owner, current_cut) >= 0
+ && knot_dname_in_bailiwick(qry->sname, rr->owner) >= 0;
+ if (!ok) {
+ VERBOSE_MSG("<= authority: ns outside bailiwick\n");
+ qry->server_selection.error(qry, req->upstream.transport, KR_SELECTION_LAME_DELEGATION);
+#ifdef STRICT_MODE
+ return KR_STATE_FAIL;
+#else
+ /* Workaround: ignore out-of-bailiwick NSs for authoritative answers,
+ * but fail for referrals. This is important to detect lame answers. */
+ if (knot_pkt_section(pkt, KNOT_ANSWER)->count == 0) {
+ state = KR_STATE_FAIL;
+ }
+ return state;
+#endif
+ }
+
+ /* Update zone cut name */
+ if (!knot_dname_is_equal(rr->owner, cut->name)) {
+ /* Remember parent cut and descend to new (keep keys and TA). */
+ struct kr_zonecut *parent = mm_alloc(&req->pool, sizeof(*parent));
+ if (parent) {
+ memcpy(parent, cut, sizeof(*parent));
+ kr_zonecut_init(cut, rr->owner, &req->pool);
+ cut->key = parent->key;
+ cut->trust_anchor = parent->trust_anchor;
+ cut->parent = parent;
+ } else {
+ kr_zonecut_set(cut, rr->owner);
+ }
+ state = KR_STATE_DONE;
+ }
+
+ /* Fetch glue for each NS */
+ knot_rdata_t *rdata_i = rr->rrs.rdata;
+ for (unsigned i = 0; i < rr->rrs.count;
+ ++i, rdata_i = knot_rdataset_next(rdata_i)) {
+ const knot_dname_t *ns_name = knot_ns_name(rdata_i);
+ /* Glue is mandatory for NS below zone */
+ if (knot_dname_in_bailiwick(ns_name, rr->owner) >= 0
+ && !has_glue(pkt, ns_name)) {
+ const char *msg =
+ "<= authority: missing mandatory glue, skipping NS";
+ WITH_VERBOSE(qry) {
+ auto_free char *ns_str = kr_dname_text(ns_name);
+ VERBOSE_MSG("%s %s\n", msg, ns_str);
+ }
+ continue;
+ }
+ int ret = kr_zonecut_add(cut, ns_name, NULL, 0);
+ kr_assert(!ret);
+
+ /* Choose when to use glue records. */
+ const bool in_bailiwick =
+ knot_dname_in_bailiwick(ns_name, current_cut) >= 0;
+ bool do_fetch;
+ if (qry->flags.PERMISSIVE) {
+ do_fetch = true;
+ } else if (qry->flags.STRICT) {
+ /* Strict mode uses only mandatory glue. */
+ do_fetch = knot_dname_in_bailiwick(ns_name, cut->name) >= 0;
+ } else {
+ /* Normal mode uses in-bailiwick glue. */
+ do_fetch = in_bailiwick;
+ }
+ if (do_fetch) {
+ fetch_glue(pkt, ns_name, in_bailiwick, req, qry, glue_cnt);
+ }
+ }
+
+ return state;
+}
+
+/** Compute rank appropriate for RRs present in the packet.
+ * @param answer whether the RR is from answer or authority section
+ * @param is_nonauth: from referral or forwarding (etc.) */
+static uint8_t get_initial_rank(const knot_rrset_t *rr, const struct kr_query *qry,
+ const bool answer, const bool is_nonauth)
+{
+ /* For RRSIGs, ensure the KR_RANK_AUTH flag corresponds to the signed RR. */
+ uint16_t type = kr_rrset_type_maysig(rr);
+
+ if (qry->flags.CACHED) {
+ return rr->additional ? *(uint8_t *)rr->additional : KR_RANK_OMIT;
+ /* ^^ Current use case for "cached" RRs without rank: hints module. */
+ }
+ if (answer || type == KNOT_RRTYPE_DS
+ || type == KNOT_RRTYPE_SOA /* needed for aggressive negative caching */
+ || type == KNOT_RRTYPE_NSEC || type == KNOT_RRTYPE_NSEC3) {
+ /* We almost always want these validated, and it should be possible. */
+ return KR_RANK_INITIAL | KR_RANK_AUTH;
+ }
+ /* Be aggressive: try to validate anything else (almost never extra latency). */
+ return KR_RANK_TRY;
+ /* TODO: this classifier of authoritativity may not be perfect yet. */
+}
+
+static int pick_authority(knot_pkt_t *pkt, struct kr_request *req, bool to_wire)
+{
+ struct kr_query *qry = req->current_query;
+ const knot_pktsection_t *ns = knot_pkt_section(pkt, KNOT_AUTHORITY);
+
+ const knot_dname_t *zonecut_name = qry->zone_cut.name;
+ bool referral = !knot_wire_get_aa(pkt->wire);
+ if (referral) {
+ /* zone cut already updated by process_authority()
+ * use parent zonecut name */
+ zonecut_name = qry->zone_cut.parent ? qry->zone_cut.parent->name : qry->zone_cut.name;
+ to_wire = false;
+ }
+
+ for (unsigned i = 0; i < ns->count; ++i) {
+ const knot_rrset_t *rr = knot_pkt_rr(ns, i);
+ if (rr->rclass != KNOT_CLASS_IN
+ || knot_dname_in_bailiwick(rr->owner, zonecut_name) < 0) {
+ continue;
+ }
+ uint8_t rank = get_initial_rank(rr, qry, false,
+ qry->flags.FORWARD || referral);
+ int ret = kr_ranked_rrarray_add(&req->auth_selected, rr,
+ rank, to_wire, qry->uid, &req->pool);
+ if (ret < 0) {
+ return ret;
+ }
+ }
+
+ return kr_ok();
+}
+
+static int process_authority(knot_pkt_t *pkt, struct kr_request *req)
+{
+ struct kr_query *qry = req->current_query;
+ if (kr_fails_assert(!qry->flags.STUB))
+ return KR_STATE_FAIL;
+
+ int result = KR_STATE_CONSUME;
+ if (qry->flags.FORWARD) {
+ return result;
+ }
+
+ const knot_pktsection_t *ns = knot_pkt_section(pkt, KNOT_AUTHORITY);
+ const knot_pktsection_t *an = knot_pkt_section(pkt, KNOT_ANSWER);
+
+#ifdef STRICT_MODE
+ /* AA, terminate resolution chain. */
+ if (knot_wire_get_aa(pkt->wire)) {
+ return KR_STATE_CONSUME;
+ }
+#else
+ /* Work around servers sending back CNAME with different delegation and no AA. */
+ if (an->count > 0 && ns->count > 0) {
+ const knot_rrset_t *rr = knot_pkt_rr(an, 0);
+ if (rr->type == KNOT_RRTYPE_CNAME) {
+ return KR_STATE_CONSUME;
+ }
+ /* Work around for these NSs which are authoritative both for
+ * parent and child and mixes data from both zones in single answer */
+ if (knot_wire_get_aa(pkt->wire) &&
+ (rr->type == qry->stype) &&
+ (knot_dname_is_equal(rr->owner, qry->sname))) {
+ return KR_STATE_CONSUME;
+ }
+ }
+#endif
+ /* Remember current bailiwick for NS processing. */
+ const knot_dname_t *current_zone_cut = qry->zone_cut.name;
+ bool ns_record_exists = false;
+ int glue_cnt = 0;
+ int ns_count = 0;
+ /* Update zone cut information. */
+ for (unsigned i = 0; i < ns->count; ++i) {
+ const knot_rrset_t *rr = knot_pkt_rr(ns, i);
+ if (rr->type == KNOT_RRTYPE_NS) {
+ ns_record_exists = true;
+ int state = update_cut(pkt, rr, req, current_zone_cut, &glue_cnt);
+ switch(state) {
+ case KR_STATE_DONE: result = state; break;
+ case KR_STATE_FAIL: return state; break;
+ default: /* continue */ break;
+ }
+
+ if (++ns_count >= 13) {
+ VERBOSE_MSG("<= authority: many glue NSs, skipping the rest\n");
+ break;
+ }
+ } else if (rr->type == KNOT_RRTYPE_SOA
+ && knot_dname_in_bailiwick(rr->owner, qry->zone_cut.name) > 0) {
+ /* SOA below cut in authority indicates different authority,
+ * but same NS set. */
+ qry->zone_cut.name = knot_dname_copy(rr->owner, &req->pool);
+ }
+ }
+
+ /* Nameserver is authoritative for both parent side and the child side of the
+ * delegation may respond with an NS record in the answer section, and still update
+ * the zone cut (this e.g. happens on the `nrl.navy.mil.` zone cut).
+ * By updating the zone cut, we can continue with QNAME minimization,
+ * as the current code is only able to minimize one label below a zone cut. */
+ if (!ns_record_exists && knot_wire_get_aa(pkt->wire)) {
+ for (unsigned i = 0; i < an->count; ++i) {
+ const knot_rrset_t *rr = knot_pkt_rr(an, i);
+ if (rr->type == KNOT_RRTYPE_NS
+ && knot_dname_in_bailiwick(rr->owner, qry->zone_cut.name) > 0
+ /* "confusing" NS records can happen e.g. on a CNAME chain */
+ && knot_dname_in_bailiwick(qry->sname, rr->owner) >= 0) {
+ /* NS below cut in authority indicates different authority,
+ * but same NS set. */
+ qry->zone_cut.name = knot_dname_copy(rr->owner, &req->pool);
+ }
+ }
+ }
+
+ if (glue_cnt) {
+ VERBOSE_MSG("<= loaded %d glue addresses\n", glue_cnt);
+ }
+ if (glue_cnt > GLUE_COUNT_THROTTLE) {
+ VERBOSE_MSG("<= (some may have been omitted due to being too many)\n");
+ }
+
+
+ if ((qry->flags.DNSSEC_WANT) && (result == KR_STATE_CONSUME)) {
+ if (knot_wire_get_aa(pkt->wire) == 0 &&
+ knot_wire_get_ancount(pkt->wire) == 0 &&
+ ns_record_exists) {
+ /* Unhelpful referral
+ Prevent from validating as an authoritative answer */
+ result = KR_STATE_DONE;
+ }
+ }
+
+ /* CONSUME => Unhelpful referral.
+ * DONE => Zone cut updated. */
+ return result;
+}
+
+static int finalize_answer(knot_pkt_t *pkt, struct kr_request *req)
+{
+ /* Finalize header */
+ knot_pkt_t *answer = kr_request_ensure_answer(req);
+ if (answer) {
+ knot_wire_set_rcode(answer->wire, knot_wire_get_rcode(pkt->wire));
+ req->state = KR_STATE_DONE;
+ }
+ return req->state;
+}
+
+static int unroll_cname(knot_pkt_t *pkt, struct kr_request *req, bool referral, const knot_dname_t **cname_ret)
+{
+ struct kr_query *query = req->current_query;
+ if (kr_fails_assert(!query->flags.STUB))
+ return KR_STATE_FAIL;
+ /* Process answer type */
+ const knot_pktsection_t *an = knot_pkt_section(pkt, KNOT_ANSWER);
+ const knot_dname_t *cname = NULL;
+ const knot_dname_t *pending_cname = query->sname;
+ bool is_final = (query->parent == NULL);
+ bool strict_mode = (query->flags.STRICT);
+
+ query->cname_depth = query->cname_parent ? query->cname_parent->cname_depth : 1;
+
+ do {
+ /* CNAME was found at previous iteration, but records may not follow the correct order.
+ * Try to find records for pending_cname owner from section start. */
+ cname = pending_cname;
+ size_t cname_answ_selected_i = -1;
+ bool cname_is_occluded = false; /* whether `cname` is in a DNAME's bailiwick */
+ pending_cname = NULL;
+ const int cname_labels = knot_dname_labels(cname, NULL);
+ for (unsigned i = 0; i < an->count; ++i) {
+ const knot_rrset_t *rr = knot_pkt_rr(an, i);
+
+ /* Skip the RR if its owner+type doesn't interest us. */
+ const uint16_t type = kr_rrset_type_maysig(rr);
+ const bool type_OK = rr->type == query->stype || type == query->stype
+ || type == KNOT_RRTYPE_CNAME;
+ if (rr->rclass != KNOT_CLASS_IN
+ || knot_dname_in_bailiwick(rr->owner, query->zone_cut.name) < 0) {
+ continue;
+ }
+ const bool all_OK = type_OK && knot_dname_is_equal(rr->owner, cname);
+
+ const bool to_wire = is_final && !referral;
+
+ if (!all_OK && type == KNOT_RRTYPE_DNAME
+ && knot_dname_in_bailiwick(cname, rr->owner) >= 1) {
+ /* This DNAME (or RRSIGs) cover the current target (`cname`),
+ * so it is interesting and will occlude its CNAME.
+ * We rely on CNAME being sent along with DNAME
+ * (mandatory unless YXDOMAIN). */
+ cname_is_occluded = true;
+ uint8_t rank = get_initial_rank(rr, query, true,
+ query->flags.FORWARD || referral);
+ int ret = kr_ranked_rrarray_add(&req->answ_selected, rr,
+ rank, to_wire, query->uid, &req->pool);
+ if (ret < 0) {
+ return KR_STATE_FAIL;
+ }
+ }
+ if (!all_OK) {
+ continue;
+ }
+
+ if (rr->type == KNOT_RRTYPE_RRSIG) {
+ int rrsig_labels = knot_rrsig_labels(rr->rrs.rdata);
+ if (rrsig_labels > cname_labels) {
+ /* clearly wrong RRSIG, don't pick it.
+ * don't fail immediately,
+ * let validator work. */
+ continue;
+ }
+ if (rrsig_labels < cname_labels) {
+ query->flags.DNSSEC_WEXPAND = true;
+ }
+ }
+
+ /* Process records matching current SNAME */
+ if (!is_final) {
+ int cnt_ = 0;
+ int state = update_nsaddr(rr, query->parent, &cnt_);
+ if (state & KR_STATE_FAIL) {
+ return state;
+ }
+ }
+ uint8_t rank = get_initial_rank(rr, query, true,
+ query->flags.FORWARD || referral);
+ int ret = kr_ranked_rrarray_add(&req->answ_selected, rr,
+ rank, to_wire, query->uid, &req->pool);
+ if (ret < 0) {
+ return KR_STATE_FAIL;
+ }
+ cname_answ_selected_i = ret;
+
+ /* Select the next CNAME target, but don't jump immediately.
+ * There can be records for "old" cname (RRSIGs are interesting);
+ * more importantly there might be a DNAME for `cname_is_occluded`. */
+ if (query->stype != KNOT_RRTYPE_CNAME && rr->type == KNOT_RRTYPE_CNAME) {
+ pending_cname = knot_cname_name(rr->rrs.rdata);
+ if (!pending_cname) {
+ break;
+ }
+ }
+ }
+ if (!pending_cname) {
+ break;
+ }
+ if (cname_is_occluded) {
+ req->answ_selected.at[cname_answ_selected_i]->dont_cache = true;
+ }
+ if (++(query->cname_depth) > KR_CNAME_CHAIN_LIMIT) {
+ VERBOSE_MSG("<= error: CNAME chain exceeded max length %d\n",
+ /* people count objects from 0, no CNAME = 0 */
+ (int)KR_CNAME_CHAIN_LIMIT - 1);
+ return KR_STATE_FAIL;
+ }
+
+ if (knot_dname_is_equal(cname, pending_cname)) {
+ VERBOSE_MSG("<= error: CNAME chain loop detected\n");
+ return KR_STATE_FAIL;
+ }
+ /* In strict mode, explicitly fetch each CNAME target. */
+ if (strict_mode) {
+ cname = pending_cname;
+ break;
+ }
+ /* Information outside bailiwick is not trusted. */
+ if (knot_dname_in_bailiwick(pending_cname, query->zone_cut.name) < 0) {
+ cname = pending_cname;
+ break;
+ }
+ /* The validator still can't handle multiple zones in one answer,
+ * so we only follow if a single label is replaced.
+ * Forwarding appears to be even more sensitive to this.
+ * TODO: iteration can probably handle the remaining cases,
+ * but overall it would be better to have a smarter validator
+ * (and thus save roundtrips).*/
+ const int pending_labels = knot_dname_labels(pending_cname, NULL);
+ if (pending_labels != cname_labels) {
+ cname = pending_cname;
+ break;
+ }
+ if (knot_dname_matched_labels(pending_cname, cname) != cname_labels - 1
+ || query->flags.FORWARD) {
+ cname = pending_cname;
+ break;
+ }
+ } while (true);
+ *cname_ret = cname;
+ return kr_ok();
+}
+
+static int process_referral_answer(knot_pkt_t *pkt, struct kr_request *req)
+{
+ const knot_dname_t *cname = NULL;
+ int state = unroll_cname(pkt, req, true, &cname);
+ struct kr_query *query = req->current_query;
+ if (state != kr_ok()) {
+ query->server_selection.error(query, req->upstream.transport, KR_SELECTION_BAD_CNAME);
+ return KR_STATE_FAIL;
+ }
+ if (!(query->flags.CACHED)) {
+ /* If not cached (i.e. got from upstream)
+ * make sure that this is not an authoritative answer
+ * (even with AA=1) for other layers.
+ * There can be answers with AA=1,
+ * empty answer section and NS in authority.
+ * Clearing of AA prevents them from
+ * caching in the packet cache.
+ * If packet already cached, don't touch him. */
+ knot_wire_clear_aa(pkt->wire);
+ }
+ state = pick_authority(pkt, req, false);
+ return state == kr_ok() ? KR_STATE_DONE : KR_STATE_FAIL;
+}
+
+static int process_final(knot_pkt_t *pkt, struct kr_request *req,
+ const knot_dname_t *cname)
+{
+ const int pkt_class = kr_response_classify(pkt);
+ struct kr_query *query = req->current_query;
+ ranked_rr_array_t *array = &req->answ_selected;
+ for (size_t i = 0; i < array->len; ++i) {
+ const knot_rrset_t *rr = array->at[i]->rr;
+ if (!knot_dname_is_equal(rr->owner, cname)) {
+ continue;
+ }
+ if ((rr->rclass != query->sclass) ||
+ (rr->type != query->stype)) {
+ continue;
+ }
+ const bool to_wire = ((pkt_class & (PKT_NXDOMAIN|PKT_NODATA)) != 0);
+ const int state = pick_authority(pkt, req, to_wire);
+ if (state != kr_ok()) {
+ return KR_STATE_FAIL;
+ }
+ if (!array->at[i]->to_wire) {
+ const size_t last_idx = array->len - 1;
+ size_t j = i;
+ ranked_rr_array_entry_t *entry = array->at[i];
+ /* Relocate record to the end, after current cname */
+ while (j < last_idx) {
+ array->at[j] = array->at[j + 1];
+ ++j;
+ }
+ array->at[last_idx] = entry;
+ entry->to_wire = true;
+ }
+ return finalize_answer(pkt, req);
+ }
+ return kr_ok();
+}
+
+static int process_answer(knot_pkt_t *pkt, struct kr_request *req)
+{
+ struct kr_query *query = req->current_query;
+
+ /* Response for minimized QNAME. Note that current iterator's minimization
+ * is only able ask one label below a zone cut.
+ * NODATA => may be empty non-terminal, retry (found zone cut)
+ * NOERROR => found zone cut, retry, except the case described below
+ * NXDOMAIN => parent is zone cut, retry as a workaround for bad authoritatives
+ */
+ const bool is_final = (query->parent == NULL);
+ const int pkt_class = kr_response_classify(pkt);
+ const knot_dname_t * pkt_qname = knot_pkt_qname(pkt);
+ if (!knot_dname_is_equal(pkt_qname, query->sname) &&
+ (pkt_class & (PKT_NOERROR|PKT_NXDOMAIN|PKT_REFUSED|PKT_NODATA))) {
+ /* Check for parent server that is authoritative for child zone,
+ * several CCTLDs where the SLD and TLD have the same name servers */
+ const knot_pktsection_t *ans = knot_pkt_section(pkt, KNOT_ANSWER);
+ if ((pkt_class & (PKT_NOERROR)) && ans->count > 0 &&
+ knot_dname_is_equal(pkt_qname, query->zone_cut.name)) {
+ VERBOSE_MSG("<= continuing with qname minimization\n");
+ } else {
+ /* fall back to disabling minimization */
+ VERBOSE_MSG("<= retrying with non-minimized name\n");
+ query->flags.NO_MINIMIZE = true;
+ }
+ return KR_STATE_CONSUME;
+ }
+
+ /* This answer didn't improve resolution chain, therefore must be authoritative (relaxed to negative). */
+ if (!is_authoritative(pkt, query)) {
+ if (!(query->flags.FORWARD) &&
+ pkt_class & (PKT_NXDOMAIN|PKT_NODATA)) {
+ query->server_selection.error(query, req->upstream.transport, KR_SELECTION_LAME_DELEGATION);
+ VERBOSE_MSG("<= lame response: non-auth sent negative response\n");
+ return KR_STATE_FAIL;
+ }
+ }
+
+ const knot_dname_t *cname = NULL;
+ /* Process answer type */
+ int state = unroll_cname(pkt, req, false, &cname);
+ if (state != kr_ok()) {
+ query->server_selection.error(query, req->upstream.transport, KR_SELECTION_BAD_CNAME);
+ return state;
+ }
+ /* Make sure that this is an authoritative answer (even with AA=0) for other layers */
+ knot_wire_set_aa(pkt->wire);
+ /* Either way it resolves current query. */
+ query->flags.RESOLVED = true;
+ /* Follow canonical name as next SNAME. */
+ if (!knot_dname_is_equal(cname, query->sname)) {
+ /* Check if target record has been already copied */
+ query->flags.CNAME = true;
+ if (is_final) {
+ state = process_final(pkt, req, cname);
+ if (state != kr_ok()) {
+ return state;
+ }
+ } else if ((query->flags.FORWARD) &&
+ ((query->stype == KNOT_RRTYPE_DS) ||
+ (query->stype == KNOT_RRTYPE_NS))) {
+ /* CNAME'ed answer for DS or NS subquery.
+ * Treat it as proof of zonecut nonexistence. */
+ return KR_STATE_DONE;
+ }
+ VERBOSE_MSG("<= cname chain, following\n");
+ /* Check if the same query was followed in the same CNAME chain. */
+ for (const struct kr_query *q = query->cname_parent; q != NULL;
+ q = q->cname_parent) {
+ if (q->sclass == query->sclass &&
+ q->stype == query->stype &&
+ knot_dname_is_equal(q->sname, cname)) {
+ VERBOSE_MSG("<= cname chain loop\n");
+ query->server_selection.error(query, req->upstream.transport, KR_SELECTION_BAD_CNAME);
+ return KR_STATE_FAIL;
+ }
+ }
+ struct kr_query *next = kr_rplan_push(&req->rplan, query->parent, cname, query->sclass, query->stype);
+ if (!next) {
+ return KR_STATE_FAIL;
+ }
+ next->flags.AWAIT_CUT = true;
+
+ /* Copy transitive flags from original query to CNAME followup. */
+ next->flags.TRACE = query->flags.TRACE;
+ next->flags.ALWAYS_CUT = query->flags.ALWAYS_CUT;
+
+ /* Original query might have turned minimization off, revert. */
+ next->flags.NO_MINIMIZE = req->options.NO_MINIMIZE;
+
+ if (query->flags.FORWARD) {
+ next->forward_flags.CNAME = true;
+ }
+ next->cname_parent = query;
+ /* Want DNSSEC if and only if it's possible to secure
+ * this name (i.e. iff it is covered by a TA) */
+ if (kr_ta_closest(req->ctx, cname, query->stype)) {
+ next->flags.DNSSEC_WANT = true;
+ } else {
+ next->flags.DNSSEC_WANT = false;
+ }
+ if (!(query->flags.FORWARD) ||
+ (query->flags.DNSSEC_WEXPAND)) {
+ state = pick_authority(pkt, req, false);
+ if (state != kr_ok()) {
+ return KR_STATE_FAIL;
+ }
+ }
+ } else if (!query->parent) {
+ /* Answer for initial query */
+ const bool to_wire = ((pkt_class & (PKT_NXDOMAIN|PKT_NODATA)) != 0);
+ state = pick_authority(pkt, req, to_wire);
+ if (state != kr_ok()) {
+ return KR_STATE_FAIL;
+ }
+ return finalize_answer(pkt, req);
+ } else {
+ /* Answer for sub-query; DS, IP for NS etc.
+ * It may contains NSEC \ NSEC3 records for
+ * data non-existence or wc expansion proving.
+ * If yes, they must be validated by validator.
+ * If no, authority section is unuseful.
+ * dnssec\nsec.c & dnssec\nsec3.c use
+ * rrsets from incoming packet.
+ * validator uses answer_selected & auth_selected.
+ * So, if nsec\nsec3 records are present in authority,
+ * pick_authority() must be called.
+ * TODO refactor nsec\nsec3 modules to work with
+ * answer_selected & auth_selected instead of incoming pkt. */
+ bool auth_is_unuseful = true;
+ const knot_pktsection_t *ns = knot_pkt_section(pkt, KNOT_AUTHORITY);
+ for (unsigned i = 0; i < ns->count; ++i) {
+ const knot_rrset_t *rr = knot_pkt_rr(ns, i);
+ if (rr->type == KNOT_RRTYPE_NSEC ||
+ rr->type == KNOT_RRTYPE_NSEC3) {
+ auth_is_unuseful = false;
+ break;
+ }
+ }
+ if (!auth_is_unuseful) {
+ state = pick_authority(pkt, req, false);
+ if (state != kr_ok()) {
+ return KR_STATE_FAIL;
+ }
+ }
+ }
+ return KR_STATE_DONE;
+}
+
+/** @internal like process_answer() but for the STUB mode. */
+static int process_stub(knot_pkt_t *pkt, struct kr_request *req)
+{
+ struct kr_query *query = req->current_query;
+ if (kr_fails_assert(query->flags.STUB))
+ return KR_STATE_FAIL;
+ /* Pick all answer RRs. */
+ const knot_pktsection_t *an = knot_pkt_section(pkt, KNOT_ANSWER);
+ for (unsigned i = 0; i < an->count; ++i) {
+ const knot_rrset_t *rr = knot_pkt_rr(an, i);
+ int err = kr_ranked_rrarray_add(&req->answ_selected, rr,
+ KR_RANK_OMIT | KR_RANK_AUTH, true, query->uid, &req->pool);
+ /* KR_RANK_AUTH: we don't have the records directly from
+ * an authoritative source, but we do trust the server and it's
+ * supposed to only send us authoritative records. */
+ if (err < 0) {
+ return KR_STATE_FAIL;
+ }
+ }
+
+ knot_wire_set_aa(pkt->wire);
+ query->flags.RESOLVED = true;
+ /* Pick authority RRs. */
+ int pkt_class = kr_response_classify(pkt);
+ const bool to_wire = ((pkt_class & (PKT_NXDOMAIN|PKT_NODATA)) != 0);
+ int err = pick_authority(pkt, req, to_wire);
+ if (err != kr_ok()) {
+ return KR_STATE_FAIL;
+ }
+
+ return finalize_answer(pkt, req);
+}
+
+/* State-less single resolution iteration step, not needed. */
+static int reset(kr_layer_t *ctx) { return KR_STATE_PRODUCE; }
+
+/* Set resolution context and parameters. */
+static int begin(kr_layer_t *ctx)
+{
+ if (ctx->state & (KR_STATE_DONE|KR_STATE_FAIL)) {
+ return ctx->state;
+ }
+ /*
+ * RFC7873 5.4 extends the QUERY operation code behaviour in order to
+ * be able to generate requests for server cookies. Such requests have
+ * QDCOUNT equal to zero and must contain a cookie option.
+ * Server cookie queries must be handled by the cookie module/layer
+ * before this layer.
+ */
+ const knot_pkt_t *pkt = ctx->req->qsource.packet;
+ if (!pkt || knot_wire_get_qdcount(pkt->wire) == 0) {
+ return KR_STATE_FAIL;
+ }
+
+ struct kr_query *qry = ctx->req->current_query;
+ /* Avoid any other classes, and avoid any meta-types ~~except for ANY~~. */
+ if (qry->sclass != KNOT_CLASS_IN
+ || (knot_rrtype_is_metatype(qry->stype)
+ /* && qry->stype != KNOT_RRTYPE_ANY hmm ANY seems broken ATM */)) {
+ knot_pkt_t *ans = kr_request_ensure_answer(ctx->req);
+ if (!ans) return ctx->req->state;
+ knot_wire_set_rcode(ans->wire, KNOT_RCODE_NOTIMPL);
+ return KR_STATE_FAIL;
+ }
+
+ return reset(ctx);
+}
+
+int kr_make_query(struct kr_query *query, knot_pkt_t *pkt)
+{
+ /* Minimize QNAME (if possible). */
+ uint16_t qtype = query->stype;
+ const knot_dname_t *qname = minimized_qname(query, &qtype);
+
+ /* Form a query for the authoritative. */
+ knot_pkt_clear(pkt);
+ int ret = knot_pkt_put_question(pkt, qname, query->sclass, qtype);
+ if (ret != KNOT_EOK) {
+ return ret;
+ }
+
+ /* Query built, expect answer. */
+ query->id = kr_rand_bytes(2);
+ /* We must respect https://tools.ietf.org/html/rfc7766#section-6.2.1
+ * - When sending multiple queries over a TCP connection, clients MUST NOT
+ * reuse the DNS Message ID of an in-flight query on that connection.
+ *
+ * So, if query is going to be sent over TCP connection
+ * this id can be changed to avoid duplication with query that already was sent
+ * but didn't receive answer yet.
+ */
+ knot_wire_set_id(pkt->wire, query->id);
+ pkt->parsed = pkt->size;
+
+ return kr_ok();
+}
+
+static int prepare_query(kr_layer_t *ctx, knot_pkt_t *pkt)
+{
+ if (kr_fails_assert(pkt && ctx))
+ return KR_STATE_FAIL;
+ struct kr_request *req = ctx->req;
+ struct kr_query *query = req->current_query;
+ if (!query || ctx->state & (KR_STATE_DONE|KR_STATE_FAIL)) {
+ return ctx->state;
+ }
+
+ /* Make query */
+ int ret = kr_make_query(query, pkt);
+ if (ret != 0) {
+ return KR_STATE_FAIL;
+ }
+
+ WITH_VERBOSE(query) {
+ KR_DNAME_GET_STR(name_str, query->sname);
+ KR_RRTYPE_GET_STR(type_str, query->stype);
+ QVERBOSE_MSG(query, "'%s' type '%s' new uid was assigned .%02u, parent uid .%02u\n",
+ name_str, type_str, req->rplan.next_uid,
+ query->parent ? query->parent->uid : 0);
+ }
+
+ query->uid = req->rplan.next_uid;
+ req->rplan.next_uid += 1;
+ query->flags.CACHED = false; // in case it got left from earlier (unknown edge case)
+
+ return KR_STATE_CONSUME;
+}
+
+static bool satisfied_by_additional(const struct kr_query *qry)
+{
+ const bool prereq = !qry->flags.STUB && !qry->flags.FORWARD && qry->flags.NONAUTH;
+ if (!prereq)
+ return false;
+ const struct kr_request *req = qry->request;
+ for (ssize_t i = req->add_selected.len - 1; i >= 0; --i) {
+ ranked_rr_array_entry_t *entry = req->add_selected.at[i];
+ if (entry->qry_uid != qry->uid)
+ break;
+ if (entry->rr->type == qry->stype
+ && knot_dname_is_equal(entry->rr->owner, qry->sname)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+/** Restrict all RRset TTLs to the specified bounds (if matching qry_uid). */
+static void bound_ttls(ranked_rr_array_t *array, uint32_t qry_uid,
+ uint32_t ttl_min, uint32_t ttl_max)
+{
+ for (ssize_t i = 0; i < array->len; ++i) {
+ if (array->at[i]->qry_uid != qry_uid)
+ continue;
+ uint32_t *ttl = &array->at[i]->rr->ttl;
+ if (*ttl < ttl_min) {
+ *ttl = ttl_min;
+ } else if (*ttl > ttl_max) {
+ *ttl = ttl_max;
+ }
+ }
+}
+
+/** Resolve input query or continue resolution with followups.
+ *
+ * This roughly corresponds to RFC1034, 5.3.3 4a-d.
+ */
+static int resolve(kr_layer_t *ctx, knot_pkt_t *pkt)
+{
+ if (kr_fails_assert(pkt && ctx))
+ return KR_STATE_FAIL;
+ struct kr_request *req = ctx->req;
+ struct kr_query *query = req->current_query;
+ if (!query) {
+ return ctx->state;
+ }
+ query->flags.PKT_IS_SANE = false;
+
+ WITH_VERBOSE(query) {
+ if (query->flags.TRACE) {
+ auto_free char *pkt_text = kr_pkt_text(pkt);
+ VERBOSE_MSG("<= answer received:\n%s\n", pkt_text);
+ }
+ }
+
+ if (query->flags.RESOLVED || query->flags.BADCOOKIE_AGAIN) {
+ return ctx->state;
+ }
+
+ /* Check for packet processing errors first.
+ * Note - we *MUST* check if it has at least a QUESTION,
+ * otherwise it would crash on accessing QNAME. */
+ /* TODO: some of these erros are probably unreachable
+ * thanks to getting caught earlier, in particular in worker_submit() */
+ if (pkt->parsed <= KNOT_WIRE_HEADER_SIZE) {
+ if (pkt->parsed == KNOT_WIRE_HEADER_SIZE && knot_wire_get_rcode(pkt->wire) == KNOT_RCODE_FORMERR) {
+ /* This is a special case where we get valid header with FORMERR and nothing else.
+ * This happens on some authoritatives which don't support EDNS and don't
+ * bother copying the SECTION QUESTION. */
+ query->server_selection.error(query, req->upstream.transport, KR_SELECTION_FORMERR);
+ return KR_STATE_FAIL;
+ }
+ VERBOSE_MSG("<= malformed response (parsed %d)\n", (int)pkt->parsed);
+ query->server_selection.error(query, req->upstream.transport, KR_SELECTION_MALFORMED);
+ return KR_STATE_FAIL;
+ } else if (!is_paired_to_query(pkt, query)) {
+ WITH_VERBOSE(query) {
+ const char *ns_str =
+ req->upstream.transport ? kr_straddr(&req->upstream.transport->address.ip) : "(internal)";
+ VERBOSE_MSG("<= ignoring mismatching response from %s\n",
+ ns_str ? ns_str : "(kr_straddr failed)");
+ }
+ query->server_selection.error(query, req->upstream.transport, KR_SELECTION_MISMATCHED);
+ return KR_STATE_FAIL;
+ } else if (knot_wire_get_tc(pkt->wire)) {
+ VERBOSE_MSG("<= truncated response, failover to TCP\n");
+ if (query) {
+ /* Fail if already on TCP. */
+ if (req->upstream.transport->protocol != KR_TRANSPORT_UDP) {
+ VERBOSE_MSG("<= TC=1 with TCP, bailing out\n");
+ query->server_selection.error(query, req->upstream.transport, KR_SELECTION_TRUNCATED);
+ return KR_STATE_FAIL;
+ }
+ query->server_selection.error(query, req->upstream.transport, KR_SELECTION_TRUNCATED);
+ }
+ return KR_STATE_CONSUME;
+ }
+
+ /* If exiting above here, there's no sense to put it into packet cache.
+ * Having "extra bytes" at the end of DNS message is considered SANE here.
+ * The most important part is to check for spoofing: is_paired_to_query() */
+ query->flags.PKT_IS_SANE = true;
+
+ const knot_lookup_t *rcode = // just for logging but cheaper than a condition
+ knot_lookup_by_id(knot_rcode_names, knot_wire_get_rcode(pkt->wire));
+
+ // We can't return directly from the switch because we have to give feedback to server selection first
+ int ret = 0;
+ int selection_error = KR_SELECTION_OK;
+
+ /* Check response code. */
+ switch(knot_wire_get_rcode(pkt->wire)) {
+ case KNOT_RCODE_NOERROR:
+ case KNOT_RCODE_NXDOMAIN:
+ break; /* OK */
+ case KNOT_RCODE_YXDOMAIN: /* Basically a successful answer; name just doesn't fit. */
+ if (!kr_request_ensure_answer(req)) {
+ ret = req->state;
+ }
+ knot_wire_set_rcode(req->answer->wire, KNOT_RCODE_YXDOMAIN);
+ break;
+ case KNOT_RCODE_REFUSED:
+ if (query->flags.STUB) {
+ /* just pass answer through if in stub mode */
+ break;
+ }
+ ret = KR_STATE_FAIL;
+ selection_error = KR_SELECTION_REFUSED;
+ break;
+ case KNOT_RCODE_SERVFAIL:
+ if (query->flags.STUB) {
+ /* just pass answer through if in stub mode */
+ break;
+ }
+ ret = KR_STATE_FAIL;
+ selection_error = KR_SELECTION_SERVFAIL;
+ break;
+ case KNOT_RCODE_FORMERR:
+ ret = KR_STATE_FAIL;
+ if (knot_pkt_has_edns(pkt)) {
+ selection_error = KR_SELECTION_FORMERR_EDNS;
+ } else {
+ selection_error = KR_SELECTION_FORMERR;
+ }
+ break;
+ case KNOT_RCODE_NOTIMPL:
+ ret = KR_STATE_FAIL;
+ selection_error = KR_SELECTION_NOTIMPL;
+ break;
+ default:
+ ret = KR_STATE_FAIL;
+ selection_error = KR_SELECTION_OTHER_RCODE;
+ break;
+ }
+
+ /* Check for "extra bytes" is deferred, so that RCODE-based failures take priority. */
+ if (ret != KR_STATE_FAIL && pkt->parsed < pkt->size) {
+ VERBOSE_MSG("<= malformed response with %zu extra bytes\n",
+ pkt->size - pkt->parsed);
+ ret = KR_STATE_FAIL;
+ if (selection_error == KR_SELECTION_OK)
+ selection_error = KR_SELECTION_MALFORMED;
+ }
+
+ if (query->server_selection.initialized) {
+ query->server_selection.error(query, req->upstream.transport, selection_error);
+ }
+
+ if (ret) {
+ VERBOSE_MSG("<= rcode: %s\n", rcode ? rcode->name : "??");
+ return ret;
+ }
+
+ int state;
+ /* Forwarding/stub mode is special. */
+ if (query->flags.STUB) {
+ state = process_stub(pkt, req);
+ goto rrarray_finalize;
+ }
+
+ /* Resolve authority to see if it's referral or authoritative. */
+ state = process_authority(pkt, req);
+ switch(state) {
+ case KR_STATE_CONSUME: /* Not referral, process answer. */
+ VERBOSE_MSG("<= rcode: %s\n", rcode ? rcode->name : "??");
+ state = process_answer(pkt, req);
+ break;
+ case KR_STATE_DONE: /* Referral */
+ state = process_referral_answer(pkt,req);
+ if (satisfied_by_additional(query)) { /* This is a little hacky.
+ * We found sufficient information in ADDITIONAL section
+ * and it was selected for caching in this CONSUME round.
+ * To make iterator accept the record in a simple way,
+ * we trigger another cache *reading* attempt
+ * for the subsequent PRODUCE round.
+ */
+ kr_assert(query->flags.NONAUTH);
+ query->flags.CACHE_TRIED = false;
+ VERBOSE_MSG("<= referral response, but cache should stop us short now\n");
+ } else {
+ VERBOSE_MSG("<= referral response, follow\n");
+ }
+ break;
+ default:
+ break;
+ }
+
+rrarray_finalize:
+ /* Finish construction of libknot-format RRsets.
+ * We do this even if dropping the answer, though it's probably useless. */
+ (void)0;
+ const struct kr_cache *cache = &req->ctx->cache;
+ ranked_rr_array_t *selected[] = kr_request_selected(req);
+ for (knot_section_t i = KNOT_ANSWER; i <= KNOT_ADDITIONAL; ++i) {
+ ret = kr_ranked_rrarray_finalize(selected[i], query->uid, &req->pool);
+ if (unlikely(ret))
+ return KR_STATE_FAIL;
+ if (!query->flags.CACHED)
+ bound_ttls(selected[i], query->uid, cache->ttl_min, cache->ttl_max);
+ }
+
+ return state;
+}
+
+/** Module implementation. */
+int iterate_init(struct kr_module *self)
+{
+ static const kr_layer_api_t layer = {
+ .begin = &begin,
+ .reset = &reset,
+ .consume = &resolve,
+ .produce = &prepare_query
+ };
+ self->layer = &layer;
+ return kr_ok();
+}
+
+KR_MODULE_EXPORT(iterate) /* useless for builtin module, but let's be consistent */
+
+#undef VERBOSE_MSG
diff --git a/lib/layer/iterate.h b/lib/layer/iterate.h
new file mode 100644
index 0000000..4ea4351
--- /dev/null
+++ b/lib/layer/iterate.h
@@ -0,0 +1,25 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#include "lib/layer.h"
+#include "lib/rplan.h"
+
+/* Packet classification. */
+enum {
+ PKT_NOERROR = 1 << 0, /* Positive response */
+ PKT_NODATA = 1 << 1, /* No data response */
+ PKT_NXDOMAIN = 1 << 2, /* Negative response */
+ PKT_REFUSED = 1 << 3, /* Refused response */
+ PKT_ERROR = 1 << 4 /* Bad message */
+};
+
+/** Classify response by type. */
+KR_EXPORT
+int kr_response_classify(const knot_pkt_t *pkt);
+
+/** Make next iterative query. */
+KR_EXPORT
+int kr_make_query(struct kr_query *query, knot_pkt_t *pkt);
diff --git a/lib/layer/mode.rst b/lib/layer/mode.rst
new file mode 100644
index 0000000..d64257e
--- /dev/null
+++ b/lib/layer/mode.rst
@@ -0,0 +1,26 @@
+.. SPDX-License-Identifier: GPL-3.0-or-later
+
+.. function:: mode(['strict' | 'normal' | 'permissive'])
+
+ :param: New checking level specified as string (*optional*).
+ :return: Current checking level.
+
+ Get or change resolver strictness checking level.
+
+ By default, resolver runs in *normal* mode. There are possibly many small adjustments
+ hidden behind the mode settings, but the main idea is that in *permissive* mode, the resolver
+ tries to resolve a name with as few lookups as possible, while in *strict* mode it spends much
+ more effort resolving and checking referral path. However, if majority of the traffic is covered
+ by DNSSEC, some of the strict checking actions are counter-productive.
+
+ .. csv-table::
+ :header: "Glue type", "Modes when it is accepted", "Example glue [#example_glue]_"
+
+ "mandatory glue", "strict, normal, permissive", "ns1.example.org"
+ "in-bailiwick glue", "normal, permissive", "ns1.example2.org"
+ "any glue records", "permissive", "ns1.example3.net"
+
+ .. [#example_glue] The examples show glue records acceptable from servers
+ authoritative for `org` zone when delegating to `example.org` zone.
+ Unacceptable or missing glue records trigger resolution of names listed
+ in NS records before following respective delegation.
diff --git a/lib/layer/test.integr/deckard.yaml b/lib/layer/test.integr/deckard.yaml
new file mode 100644
index 0000000..d2d62d0
--- /dev/null
+++ b/lib/layer/test.integr/deckard.yaml
@@ -0,0 +1,13 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+programs:
+- name: kresd
+ binary: kresd
+ additional:
+ - --noninteractive
+ templates:
+ - lib/layer/test.integr/kresd_config.j2
+ - tests/integration/hints_zone.j2
+ configs:
+ - config
+ - hints
+noclean: True
diff --git a/lib/layer/test.integr/iter_cname_length.rpl b/lib/layer/test.integr/iter_cname_length.rpl
new file mode 100644
index 0000000..39f48a8
--- /dev/null
+++ b/lib/layer/test.integr/iter_cname_length.rpl
@@ -0,0 +1,226 @@
+do-ip6: no
+; config options
+; SPDX-License-Identifier: GPL-3.0-or-later
+ stub-addr: 193.0.14.129 # k.root-servers.net.
+CONFIG_END
+
+SCENARIO_BEGIN Test restriction on CNAME chain length.
+
+
+; k.root-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+n1.tld. IN NS
+SECTION ANSWER
+n1.tld. IN CNAME n2.tld.
+n2.tld. IN CNAME n3.tld.
+n3.tld. IN CNAME n4.tld.
+n4.tld. IN CNAME n5.tld.
+n5.tld. IN CNAME n6.tld.
+n6.tld. IN CNAME n7.sub.
+SECTION AUTHORITY
+sub. IN NS ns.sub.
+SECTION ADDITIONAL
+ns.sub. IN A 194.0.14.1
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+n2.tld. IN NS
+SECTION ANSWER
+n2.tld. IN CNAME n3.tld.
+n3.tld. IN CNAME n4.tld.
+n4.tld. IN CNAME n5.tld.
+n5.tld. IN CNAME n6.tld.
+n6.tld. IN CNAME n7.sub.
+SECTION AUTHORITY
+sub. IN NS ns.sub.
+SECTION ADDITIONAL
+ns.sub. IN A 194.0.14.1
+ENTRY_END
+
+
+; empty non-terminal for query name minimization
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR AA NOERROR
+SECTION QUESTION
+tld. IN NS
+SECTION ANSWER
+ENTRY_END
+
+
+
+; sub. subdomains
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+sub. IN NS
+SECTION AUTHORITY
+sub. IN NS ns.sub.
+SECTION ADDITIONAL
+ns.sub. IN A 194.0.14.1
+ENTRY_END
+
+RANGE_END
+
+
+; ns.sub.
+RANGE_BEGIN 0 100
+ ADDRESS 194.0.14.1
+
+ENTRY_BEGIN
+MATCH opcode qname qtype
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns.sub. IN A
+SECTION ANSWER
+ns.sub. IN A 194.0.14.1
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname qtype
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns.sub. IN AAAA
+SECTION ANSWER
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname qtype
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+n7.sub. IN A
+SECTION ANSWER
+n7.sub. IN CNAME n8.sub.
+n8.sub. IN CNAME n9.sub.
+n9.sub. IN CNAME n10.sub.
+n10.sub. IN CNAME n11.sub.
+n11.sub. IN CNAME n12.sub.
+n12.sub. IN CNAME n13.sub.
+n13.sub. IN CNAME n14.sub.
+n14.sub. IN A 198.18.0.1
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname qtype
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+loop7.sub. IN A
+SECTION ANSWER
+loop7.sub. IN CNAME loop8.sub.
+loop8.sub. IN CNAME loop9.sub.
+loop9.sub. IN CNAME loop10.sub.
+loop10.sub. IN CNAME loop11.sub.
+; loop11 -> loop7 -> ... -> loop11
+loop11.sub. IN CNAME loop7.sub.
+loop12.sub. IN CNAME loop13.sub.
+loop13.sub. IN CNAME loop14.sub.
+loop14.sub. IN A 198.18.0.1
+ENTRY_END
+
+RANGE_END
+
+; maximum allowed chain length
+STEP 10 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+n2.tld. IN A
+ENTRY_END
+
+STEP 11 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+n2.tld. IN A
+SECTION ANSWER
+n2.tld. IN CNAME n3.tld.
+n3.tld. IN CNAME n4.tld.
+n4.tld. IN CNAME n5.tld.
+n5.tld. IN CNAME n6.tld.
+n6.tld. IN CNAME n7.sub.
+n7.sub. IN CNAME n8.sub.
+n8.sub. IN CNAME n9.sub.
+n9.sub. IN CNAME n10.sub.
+n10.sub. IN CNAME n11.sub.
+n11.sub. IN CNAME n12.sub.
+n12.sub. IN CNAME n13.sub.
+n13.sub. IN CNAME n14.sub.
+n14.sub. IN A 198.18.0.1
+ENTRY_END
+
+
+; too long CNAME chain across two zones
+STEP 20 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+n1.tld. IN A
+ENTRY_END
+
+STEP 21 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA SERVFAIL
+SECTION QUESTION
+n1.tld. IN A
+SECTION ANSWER
+n1.tld. IN CNAME n2.tld.
+n2.tld. IN CNAME n3.tld.
+n3.tld. IN CNAME n4.tld.
+n4.tld. IN CNAME n5.tld.
+n5.tld. IN CNAME n6.tld.
+n6.tld. IN CNAME n7.sub.
+n7.sub. IN CNAME n8.sub.
+n8.sub. IN CNAME n9.sub.
+n9.sub. IN CNAME n10.sub.
+n10.sub. IN CNAME n11.sub.
+n11.sub. IN CNAME n12.sub.
+n12.sub. IN CNAME n13.sub.
+n13.sub. IN CNAME n14.sub.
+; This chain is too long (> 13):
+; n14.sub. IN A 198.18.0.1
+ENTRY_END
+
+
+; CNAME loop detection
+STEP 30 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+loop7.sub. IN A
+ENTRY_END
+
+STEP 31 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA SERVFAIL
+SECTION QUESTION
+loop7.sub. IN A
+SECTION ANSWER
+loop7.sub. IN CNAME loop8.sub.
+loop8.sub. IN CNAME loop9.sub.
+loop9.sub. IN CNAME loop10.sub.
+loop10.sub. IN CNAME loop11.sub.
+loop11.sub. IN CNAME loop7.sub.
+ENTRY_END
+
+SCENARIO_END
diff --git a/lib/layer/test.integr/iter_limit_bad_glueless.rpl b/lib/layer/test.integr/iter_limit_bad_glueless.rpl
new file mode 100644
index 0000000..73d4627
--- /dev/null
+++ b/lib/layer/test.integr/iter_limit_bad_glueless.rpl
@@ -0,0 +1,220 @@
+do-ip6: no
+; config options
+; target-fetch-policy: "0 0 0 0 0"
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test resolution with lame reply looks like nodata with noSOA
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+; com
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+; net
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+net. IN NS
+SECTION AUTHORITY
+net. IN NS e.gtld-servers.net.
+SECTION ADDITIONAL
+e.gtld-servers.net. IN A 192.12.94.30
+ENTRY_END
+
+RANGE_END
+
+; a.gtld-servers.net. - com
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+victim.com. IN NS
+SECTION AUTHORITY
+victim.com. IN NS ns.victim.com.
+SECTION ADDITIONAL
+ns.victim.com. IN A 1.2.3.55
+ENTRY_END
+RANGE_END
+
+; e.gtld-servers.net. - net
+RANGE_BEGIN 0 100
+ ADDRESS 192.12.94.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+net. IN NS
+SECTION ANSWER
+net. IN NS e.gtld-servers.net.
+SECTION ADDITIONAL
+e.gtld-servers.net. IN A 192.12.94.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+attacker.net. IN NS
+SECTION AUTHORITY
+attacker.net. IN NS ns.attacker.net.
+SECTION ADDITIONAL
+ns.attacker.net. IN A 1.2.3.44
+ENTRY_END
+RANGE_END
+
+; ns.attacker.net.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.44
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+attacker.net. IN NS
+SECTION ANSWER
+attacker.net. IN NS ns.attacker.net.
+SECTION ADDITIONAL
+ns.attacker.net. IN A 1.2.3.44
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.attacker.net. IN A
+SECTION ANSWER
+ns.attacker.net. IN A 1.2.3.44
+SECTION AUTHORITY
+attacker.net. IN NS ns.attacker.net.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.attacker.net. IN AAAA
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+sub.attacker.net. IN NS
+SECTION AUTHORITY
+sub.attacker.net. IN NS ns1.victim.com.
+sub.attacker.net. IN NS ns2.victim.com.
+sub.attacker.net. IN NS ns3.victim.com.
+sub.attacker.net. IN NS ns4.victim.com.
+sub.attacker.net. IN NS ns5.victim.com.
+sub.attacker.net. IN NS ns6.victim.com.
+sub.attacker.net. IN NS ns7.victim.com.
+sub.attacker.net. IN NS ns8.victim.com.
+sub.attacker.net. IN NS ns9.victim.com.
+ENTRY_END
+RANGE_END
+
+; ns.victim.com.
+; returns NXDOMAIN for all queries (attacker generated NS names are not present)
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.55
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NXDOMAIN
+SECTION QUESTION
+victim.com. IN NS
+SECTION AUTHORITY
+victim.com. 0 IN SOA . . 1 1 1 1 1
+SECTION ADDITIONAL
+ENTRY_END
+RANGE_END
+
+
+STEP 10 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.sub.attacker.net. IN A
+ENTRY_END
+
+; in any case we must get SERVFAIL, no deleation works
+STEP 11 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA SERVFAIL
+SECTION QUESTION
+www.sub.attacker.net. IN A
+SECTION ANSWER
+ENTRY_END
+
+; recursion happens here
+STEP 20 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+glueless.trigger.check.max.number.of.upstream.queries. IN TXT
+ENTRY_END
+
+STEP 21 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR AA RD RA NOERROR
+SECTION QUESTION
+glueless.trigger.check.max.number.of.upstream.queries. IN TXT
+SECTION ANSWER
+glueless.trigger.check.max.number.of.upstream.queries. IN TXT "pass"
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+
+SCENARIO_END
diff --git a/lib/layer/test.integr/iter_limit_refuse.rpl b/lib/layer/test.integr/iter_limit_refuse.rpl
new file mode 100644
index 0000000..285b5af
--- /dev/null
+++ b/lib/layer/test.integr/iter_limit_refuse.rpl
@@ -0,0 +1,150 @@
+do-ip6: no
+; config options
+;server:
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Outrageous number of auth servers return REFUSED. Simulates NXNSAttack misusing wildcard which points to victim's DNS server. Lua config checks if number of outgoing queries is within limits.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns10.example.com.
+example.com. IN NS ns11.example.com.
+example.com. IN NS ns12.example.com.
+example.com. IN NS ns13.example.com.
+example.com. IN NS ns14.example.com.
+example.com. IN NS ns15.example.com.
+example.com. IN NS ns16.example.com.
+example.com. IN NS ns17.example.com.
+example.com. IN NS ns18.example.com.
+example.com. IN NS ns19.example.com.
+SECTION ADDITIONAL
+ns10.example.com. IN A 1.2.3.10
+ns11.example.com. IN A 1.2.3.11
+ns12.example.com. IN A 1.2.3.12
+ns13.example.com. IN A 1.2.3.13
+ns14.example.com. IN A 1.2.3.14
+ns15.example.com. IN A 1.2.3.15
+ns16.example.com. IN A 1.2.3.16
+ns17.example.com. IN A 1.2.3.17
+ns18.example.com. IN A 1.2.3.18
+ns19.example.com. IN A 1.2.3.19
+
+ENTRY_END
+RANGE_END
+
+; ns1.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.10
+ ADDRESS 1.2.3.11
+ ADDRESS 1.2.3.12
+ ADDRESS 1.2.3.13
+ ADDRESS 1.2.3.14
+ ADDRESS 1.2.3.15
+ ADDRESS 1.2.3.16
+ ADDRESS 1.2.3.17
+ ADDRESS 1.2.3.18
+ ADDRESS 1.2.3.19
+ENTRY_BEGIN
+MANDATORY
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA REFUSED
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+RANGE_END
+
+
+; recursion happens here
+STEP 10 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+; in any case we must get SERVFAIL, no auth works
+STEP 11 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA DO SERVFAIL
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+; recursion happens here
+STEP 20 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+refused.trigger.check.max.number.of.upstream.queries. IN TXT
+ENTRY_END
+
+STEP 21 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR AA RD RA NOERROR
+SECTION QUESTION
+refused.trigger.check.max.number.of.upstream.queries. IN TXT
+SECTION ANSWER
+refused.trigger.check.max.number.of.upstream.queries. IN TXT "pass"
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+SCENARIO_END
diff --git a/lib/layer/test.integr/kresd_config.j2 b/lib/layer/test.integr/kresd_config.j2
new file mode 100644
index 0000000..dc18a1b
--- /dev/null
+++ b/lib/layer/test.integr/kresd_config.j2
@@ -0,0 +1,107 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+
+local ffi = require('ffi')
+
+-- hook for iter_refuse_toomany.rpl
+local function check_max_number_of_upstream_queries(maxcnt)
+ return function (state, req)
+ local vals = worker.stats()
+ local upstream_packets = vals.ipv4 + vals.ipv6
+ log_info(ffi.C.LOG_GRP_TESTS, '%d packets sent to upstream', upstream_packets)
+ local answ_f
+ if upstream_packets > maxcnt then -- . + com. + ????
+ answ_f = policy.ANSWER(
+ { [kres.type.TXT] = { ttl=300, rdata='\4fail' } })
+
+ else
+ answ_f = policy.ANSWER(
+ { [kres.type.TXT] = { ttl=300, rdata='\4pass' } })
+ end
+ return answ_f(state, req)
+ end
+end
+
+policy.add(
+ policy.suffix(check_max_number_of_upstream_queries(8),
+ policy.todnames({'refused.trigger.check.max.number.of.upstream.queries.'})
+ )
+)
+policy.add(
+ policy.suffix(check_max_number_of_upstream_queries(16),
+ policy.todnames({'glueless.trigger.check.max.number.of.upstream.queries.'})
+ )
+)
+
+-- hook end iter_refuse_toomany.rpl
+
+
+trust_anchors.remove('.')
+{% for TAF in TRUST_ANCHOR_FILES %}
+-- trust_anchors.add_file('{{TAF}}')
+{% endfor %}
+
+{% raw %}
+-- Disable RFC5011 TA update
+if ta_update then
+ modules.unload('ta_update')
+end
+
+-- Disable RFC8145 signaling, scenario doesn't provide expected answers
+if ta_signal_query then
+ modules.unload('ta_signal_query')
+end
+
+-- Disable RFC8109 priming, scenario doesn't provide expected answers
+if priming then
+ modules.unload('priming')
+end
+
+-- Disable this module because it make one priming query
+if detect_time_skew then
+ modules.unload('detect_time_skew')
+end
+
+_hint_root_file('hints')
+cache.size = 2*MB
+log_level('debug')
+policy.add(policy.all(policy.DEBUG_ALWAYS))
+{% endraw %}
+
+net = { '{{SELF_ADDR}}' }
+
+{% if DO_IP6 == "true" %}
+net.ipv6 = true
+{% else %}
+net.ipv6 = false
+{% endif %}
+
+{% if DO_IP4 == "true" %}
+net.ipv4 = true
+{% else %}
+net.ipv4 = false
+{% endif %}
+
+
+{% if QMIN == "false" %}
+option('NO_MINIMIZE', true)
+{% else %}
+option('NO_MINIMIZE', false)
+{% endif %}
+
+
+-- Self-checks on globals
+assert(help() ~= nil)
+assert(worker.id ~= nil)
+-- Self-checks on facilities
+assert(cache.count() == 0)
+assert(cache.stats() ~= nil)
+assert(cache.backends() ~= nil)
+assert(worker.stats() ~= nil)
+assert(net.interfaces() ~= nil)
+-- Self-checks on loaded stuff
+assert(net.list()[1].transport.ip == '{{SELF_ADDR}}')
+assert(#modules.list() > 0)
+-- Self-check timers
+ev = event.recurrent(1 * sec, function (ev) return 1 end)
+event.cancel(ev)
+ev = event.after(0, function (ev) return 1 end)
diff --git a/lib/layer/validate.c b/lib/layer/validate.c
new file mode 100644
index 0000000..93f1d4f
--- /dev/null
+++ b/lib/layer/validate.c
@@ -0,0 +1,1366 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#include <errno.h>
+#include <sys/time.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <contrib/cleanup.h>
+#include <libknot/packet/wire.h>
+#include <libknot/rrtype/rdname.h>
+#include <libknot/rrtype/rrsig.h>
+#include <libdnssec/error.h>
+
+#include "lib/dnssec/nsec.h"
+#include "lib/dnssec/nsec3.h"
+#include "lib/dnssec/ta.h"
+#include "lib/dnssec.h"
+#include "lib/layer.h"
+#include "lib/resolve.h"
+#include "lib/rplan.h"
+#include "lib/utils.h"
+#include "lib/defines.h"
+#include "lib/module.h"
+#include "lib/selection.h"
+
+#define VERBOSE_MSG(qry, ...) kr_log_q(qry, VALIDATOR, __VA_ARGS__)
+
+#define MAX_REVALIDATION_CNT 2
+
+/**
+ * Search in section for given type.
+ * @param sec Packet section.
+ * @param type Type to search for.
+ * @return True if found.
+ */
+static bool section_has_type(const knot_pktsection_t *sec, uint16_t type)
+{
+ if (!sec) {
+ return false;
+ }
+
+ for (unsigned i = 0; i < sec->count; ++i) {
+ const knot_rrset_t *rr = knot_pkt_rr(sec, i);
+ if (rr->type == type) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+static bool pkt_has_type(const knot_pkt_t *pkt, uint16_t type)
+{
+ if (!pkt) {
+ return false;
+ }
+
+ if (section_has_type(knot_pkt_section(pkt, KNOT_ANSWER), type)) {
+ return true;
+ }
+ if (section_has_type(knot_pkt_section(pkt, KNOT_AUTHORITY), type)) {
+ return true;
+ }
+ return section_has_type(knot_pkt_section(pkt, KNOT_ADDITIONAL), type);
+}
+
+static void log_bogus_rrsig(kr_rrset_validation_ctx_t *vctx,
+ const knot_rrset_t *rr, const char *msg) {
+ if (kr_log_is_debug_qry(VALIDATOR, vctx->log_qry)) {
+ auto_free char *name_text = kr_dname_text(rr->owner);
+ auto_free char *type_text = kr_rrtype_text(rr->type);
+ VERBOSE_MSG(vctx->log_qry, ">< %s: %s %s "
+ "(%u matching RRSIGs, %u expired, %u not yet valid, "
+ "%u invalid signer, %u invalid label count, %u invalid key, "
+ "%u invalid crypto, %u invalid NSEC)\n",
+ msg, name_text, type_text, vctx->rrs_counters.matching_name_type,
+ vctx->rrs_counters.expired, vctx->rrs_counters.notyet,
+ vctx->rrs_counters.signer_invalid, vctx->rrs_counters.labels_invalid,
+ vctx->rrs_counters.key_invalid, vctx->rrs_counters.crypto_invalid,
+ vctx->rrs_counters.nsec_invalid);
+ }
+}
+
+/** Check that given CNAME could be generated by given DNAME (no DNSSEC validation). */
+static bool cname_matches_dname(const knot_rrset_t *rr_cn, const knot_rrset_t *rr_dn)
+{
+ if (kr_fails_assert(rr_cn->type == KNOT_RRTYPE_CNAME && rr_dn->type == KNOT_RRTYPE_DNAME))
+ return false;
+ /* When DNAME substitution happens, let's consider the "prefix"
+ * that is carried over and the "suffix" that is replaced.
+ * (Here we consider the label order used in wire and presentation.) */
+ const int prefix_labels = knot_dname_in_bailiwick(rr_cn->owner, rr_dn->owner);
+ if (prefix_labels < 1)
+ return false;
+ const knot_dname_t *cn_target = knot_cname_name(rr_cn->rrs.rdata);
+ const knot_dname_t *dn_target = knot_dname_target(rr_dn->rrs.rdata);
+ /* ^ We silently use the first RR in each RRset. Could be e.g. logged. */
+ /* Check that the suffixes are correct - and even prefix label counts. */
+ if (knot_dname_in_bailiwick(cn_target, dn_target) != prefix_labels)
+ return false;
+ /* Check that prefixes match. Find end of the first one and compare. */
+ const knot_dname_t *cn_se = rr_cn->owner;
+ for (int i = 0; i < prefix_labels; ++i)
+ cn_se += 1 + *cn_se;
+ return strncmp((const char *)rr_cn->owner, (const char *)cn_target,
+ cn_se - rr_cn->owner) == 0;
+ /* ^ We use the fact that dnames are always zero-terminated
+ * to avoid any possible over-read in cn_target. */
+}
+
+static void mark_insecure_parents(const struct kr_query *qry);
+static void rank_records(struct kr_query *qry, bool any_rank, enum kr_rank rank_to_set,
+ const knot_dname_t *bailiwick);
+
+static bool maybe_downgrade_nsec3(const ranked_rr_array_entry_t *e, struct kr_query *qry,
+ const kr_rrset_validation_ctx_t *vctx)
+{
+ bool required_conditions =
+ e->rr->type == KNOT_RRTYPE_NSEC3
+ && kr_rank_test(e->rank, KR_RANK_SECURE)
+ // extra careful: avoid downgrade if SNAME isn't in bailiwick of signer
+ && knot_dname_in_bailiwick(qry->sname, vctx->zone_name) >= 0;
+ if (!required_conditions)
+ return false;
+
+ const knot_rdataset_t *rrs = &e->rr->rrs;
+ knot_rdata_t *rd = rrs->rdata;
+ for (int j = 0; j < rrs->count; ++j, rd = knot_rdataset_next(rd)) {
+ if (knot_nsec3_iters(rd) > KR_NSEC3_MAX_ITERATIONS)
+ goto do_downgrade;
+ }
+ return false;
+
+do_downgrade: // we do this deep inside calls because of having signer name available
+ VERBOSE_MSG(qry, "<= DNSSEC downgraded due to NSEC3 iterations %d > %d\n",
+ (int)knot_nsec3_iters(rd), (int)KR_NSEC3_MAX_ITERATIONS);
+ qry->flags.DNSSEC_WANT = false;
+ qry->flags.DNSSEC_INSECURE = true;
+ rank_records(qry, true, KR_RANK_INSECURE, vctx->zone_name);
+ mark_insecure_parents(qry);
+ return true;
+}
+
+#define KNOT_EDOWNGRADED (KNOT_ERROR_MIN - 1)
+
+static int validate_section(kr_rrset_validation_ctx_t *vctx, struct kr_query *qry,
+ knot_mm_t *pool)
+{
+ struct kr_request *req = qry->request;
+ if (!vctx) {
+ return kr_error(EINVAL);
+ }
+
+ /* Can't use qry->zone_cut.name directly, as this name can
+ * change when updating cut information before validation.
+ */
+ vctx->zone_name = vctx->keys ? vctx->keys->owner : NULL;
+
+ for (ssize_t i = 0; i < vctx->rrs->len; ++i) {
+ ranked_rr_array_entry_t *entry = vctx->rrs->at[i];
+ knot_rrset_t * const rr = entry->rr;
+
+ if (entry->yielded || vctx->qry_uid != entry->qry_uid) {
+ continue;
+ }
+
+ if (kr_rank_test(entry->rank, KR_RANK_OMIT)
+ || kr_rank_test(entry->rank, KR_RANK_SECURE)) {
+ continue; /* these are already OK */
+ }
+
+ if (!knot_dname_is_equal(qry->zone_cut.name, rr->owner)/*optim.*/
+ && !kr_ta_closest(qry->request->ctx, rr->owner, rr->type)) {
+ /* We have NTA "between" our (perceived) zone cut and the RR. */
+ kr_rank_set(&entry->rank, KR_RANK_INSECURE);
+ continue;
+ }
+
+ if (rr->type == KNOT_RRTYPE_RRSIG) {
+ const knot_dname_t *signer_name = knot_rrsig_signer_name(rr->rrs.rdata);
+ if (!knot_dname_is_equal(vctx->zone_name, signer_name)) {
+ kr_rank_set(&entry->rank, KR_RANK_MISMATCH);
+ vctx->err_cnt += 1;
+ break;
+ }
+ if (!kr_rank_test(entry->rank, KR_RANK_BOGUS))
+ kr_rank_set(&entry->rank, KR_RANK_OMIT);
+ continue;
+ }
+
+ uint8_t rank_orig = entry->rank;
+ int validation_result = kr_rrset_validate(vctx, rr);
+
+ /* Handle the case of CNAMEs synthesized from DNAMEs (they don't have RRSIGs). */
+ if (rr->type == KNOT_RRTYPE_CNAME && validation_result == kr_error(ENOENT)) {
+ for (ssize_t j = 0; j < vctx->rrs->len; ++j) {
+ ranked_rr_array_entry_t *e_dname = vctx->rrs->at[j];
+ if ((e_dname->rr->type == KNOT_RRTYPE_DNAME)
+ /* If the order is wrong, we will need two passes. */
+ && kr_rank_test(e_dname->rank, KR_RANK_SECURE)
+ && cname_matches_dname(rr, e_dname->rr)) {
+ /* Now we believe the CNAME is OK. */
+ validation_result = kr_ok();
+ break;
+ }
+ }
+ if (validation_result != kr_ok()) {
+ vctx->cname_norrsig_cnt += 1;
+ }
+ }
+
+ if (validation_result == kr_ok()) {
+ kr_rank_set(&entry->rank, KR_RANK_SECURE);
+
+ /* Downgrade zone to insecure if certain NSEC3 record occurs. */
+ if (unlikely(maybe_downgrade_nsec3(entry, qry, vctx)))
+ return kr_error(KNOT_EDOWNGRADED);
+
+ } else if (kr_rank_test(rank_orig, KR_RANK_TRY)) {
+ /* RFC 4035 section 2.2:
+ * NS RRsets that appear at delegation points (...)
+ * MUST NOT be signed */
+ if (vctx->rrs_counters.matching_name_type > 0)
+ log_bogus_rrsig(vctx, rr,
+ "found unexpected signatures for non-authoritative data which failed to validate, continuing");
+ vctx->result = kr_ok();
+ kr_rank_set(&entry->rank, KR_RANK_TRY);
+ /* ^^ BOGUS would be more accurate, but it might change
+ * to MISMATCH on revalidation, e.g. in test val_referral_nods :-/
+ */
+
+ } else if (validation_result == kr_error(ENOENT)
+ && vctx->rrs_counters.matching_name_type == 0) {
+ /* no RRSIGs found */
+ kr_rank_set(&entry->rank, KR_RANK_MISSING);
+ vctx->err_cnt += 1;
+ kr_request_set_extended_error(req, KNOT_EDNS_EDE_RRSIG_MISS, "JZAJ");
+ log_bogus_rrsig(vctx, rr, "no valid RRSIGs found");
+ } else {
+ kr_rank_set(&entry->rank, KR_RANK_BOGUS);
+ vctx->err_cnt += 1;
+ if (vctx->rrs_counters.expired > 0)
+ kr_request_set_extended_error(req, KNOT_EDNS_EDE_SIG_EXPIRED, "YFJ2");
+ else if (vctx->rrs_counters.notyet > 0)
+ kr_request_set_extended_error(req, KNOT_EDNS_EDE_SIG_NOTYET, "UBBS");
+ else
+ kr_request_set_extended_error(req, KNOT_EDNS_EDE_BOGUS, "I74V");
+ log_bogus_rrsig(vctx, rr, "bogus signatures");
+ }
+ }
+ return kr_ok();
+}
+
+static int validate_records(struct kr_request *req, knot_pkt_t *answer, knot_mm_t *pool, bool has_nsec3)
+{
+ struct kr_query *qry = req->current_query;
+ if (!qry->zone_cut.key) {
+ VERBOSE_MSG(qry, "<= no DNSKEY, can't validate\n");
+ return kr_error(EBADMSG);
+ }
+
+ kr_rrset_validation_ctx_t vctx = {
+ .pkt = answer,
+ .rrs = &req->answ_selected,
+ .section_id = KNOT_ANSWER,
+ .keys = qry->zone_cut.key,
+ .zone_name = qry->zone_cut.name,
+ .timestamp = qry->timestamp.tv_sec,
+ .ttl_min = req->ctx->cache.ttl_min,
+ .qry_uid = qry->uid,
+ .has_nsec3 = has_nsec3,
+ .flags = 0,
+ .err_cnt = 0,
+ .cname_norrsig_cnt = 0,
+ .result = 0,
+ .log_qry = qry,
+ };
+
+ int ret = validate_section(&vctx, qry, pool);
+ if (vctx.err_cnt && vctx.err_cnt == vctx.cname_norrsig_cnt) {
+ VERBOSE_MSG(qry, ">< all validation errors are missing RRSIGs on CNAMES, trying again in hope for DNAMEs\n");
+ vctx.err_cnt = vctx.cname_norrsig_cnt = vctx.result = 0;
+ ret = validate_section(&vctx, qry, pool);
+ }
+ req->answ_validated = (vctx.err_cnt == 0);
+ if (ret != kr_ok()) {
+ return ret;
+ }
+
+ uint32_t an_flags = vctx.flags;
+ vctx.rrs = &req->auth_selected;
+ vctx.section_id = KNOT_AUTHORITY;
+ vctx.flags = 0;
+ vctx.err_cnt = 0;
+ vctx.result = 0;
+
+ ret = validate_section(&vctx, qry, pool);
+ req->auth_validated = (vctx.err_cnt == 0);
+ if (ret != kr_ok()) {
+ return ret;
+ }
+
+ /* Records were validated.
+ * If there is wildcard expansion in answer,
+ * or optout - flag the query.
+ */
+ if (an_flags & KR_DNSSEC_VFLG_WEXPAND) {
+ qry->flags.DNSSEC_WEXPAND = true;
+ }
+ if (an_flags & KR_DNSSEC_VFLG_OPTOUT) {
+ qry->flags.DNSSEC_OPTOUT = true;
+ }
+
+ return ret;
+}
+
+static int validate_keyset(struct kr_request *req, knot_pkt_t *answer, bool has_nsec3)
+{
+ /* Merge DNSKEY records from answer that are below/at current cut. */
+ struct kr_query *qry = req->current_query;
+ bool updated_key = false;
+ const knot_pktsection_t *an = knot_pkt_section(answer, KNOT_ANSWER);
+ for (unsigned i = 0; i < an->count; ++i) {
+ const knot_rrset_t *rr = knot_pkt_rr(an, i);
+ if (rr->type != KNOT_RRTYPE_DNSKEY
+ || knot_dname_in_bailiwick(rr->owner, qry->zone_cut.name) < 0) {
+ continue;
+ }
+ /* Merge with zone cut (or replace ancestor key). */
+ if (!qry->zone_cut.key || !knot_dname_is_equal(qry->zone_cut.key->owner, rr->owner)) {
+ qry->zone_cut.key = knot_rrset_copy(rr, qry->zone_cut.pool);
+ if (!qry->zone_cut.key) {
+ return kr_error(ENOMEM);
+ }
+ updated_key = true;
+ } else {
+ int ret = knot_rdataset_merge(&qry->zone_cut.key->rrs,
+ &rr->rrs, qry->zone_cut.pool);
+ if (ret != 0) {
+ knot_rrset_free(qry->zone_cut.key, qry->zone_cut.pool);
+ qry->zone_cut.key = NULL;
+ return ret;
+ }
+ updated_key = true;
+ }
+ }
+
+ /* Check if there's a key for current TA. */
+ if (updated_key && !(qry->flags.CACHED)) {
+ /* Find signatures for the DNSKEY; selected by iterator from ANSWER. */
+ int sig_index = -1;
+ for (int i = req->answ_selected.len - 1; i >= 0; --i) {
+ const knot_rrset_t *rrsig = req->answ_selected.at[i]->rr;
+ const bool ok = req->answ_selected.at[i]->qry_uid == qry->uid
+ && rrsig->type == KNOT_RRTYPE_RRSIG
+ && knot_rrsig_type_covered(rrsig->rrs.rdata)
+ == KNOT_RRTYPE_DNSKEY
+ && rrsig->rclass == KNOT_CLASS_IN
+ && knot_dname_is_equal(rrsig->owner,
+ qry->zone_cut.key->owner);
+ if (ok) {
+ sig_index = i;
+ break;
+ }
+ }
+ if (sig_index < 0) {
+ kr_request_set_extended_error(req, KNOT_EDNS_EDE_RRSIG_MISS, "EZDC");
+ return kr_error(ENOENT);
+ }
+ const knot_rdataset_t *sig_rds = &req->answ_selected.at[sig_index]->rr->rrs;
+
+ kr_rrset_validation_ctx_t vctx = {
+ .pkt = answer,
+ .rrs = &req->answ_selected,
+ .section_id = KNOT_ANSWER,
+ .keys = qry->zone_cut.key,
+ .zone_name = qry->zone_cut.name,
+ .timestamp = qry->timestamp.tv_sec,
+ .ttl_min = req->ctx->cache.ttl_min,
+ .qry_uid = qry->uid,
+ .has_nsec3 = has_nsec3,
+ .flags = 0,
+ .result = 0,
+ .log_qry = qry,
+ };
+ int ret = kr_dnskeys_trusted(&vctx, sig_rds, qry->zone_cut.trust_anchor);
+ /* Set rank of the RRSIG. This may be needed, but I don't know why.
+ * In particular, black_ent.rpl may get broken otherwise. */
+ kr_rank_set(&req->answ_selected.at[sig_index]->rank,
+ ret == 0 ? KR_RANK_SECURE : KR_RANK_BOGUS);
+
+ if (ret != 0) {
+ log_bogus_rrsig(&vctx, qry->zone_cut.key, "bogus key");
+ knot_rrset_free(qry->zone_cut.key, qry->zone_cut.pool);
+ qry->zone_cut.key = NULL;
+ if (vctx.rrs_counters.expired > 0)
+ kr_request_set_extended_error(req, KNOT_EDNS_EDE_SIG_EXPIRED, "6GJV");
+ else if (vctx.rrs_counters.notyet > 0)
+ kr_request_set_extended_error(req, KNOT_EDNS_EDE_SIG_NOTYET, "4DJQ");
+ else
+ kr_request_set_extended_error(req, KNOT_EDNS_EDE_BOGUS, "EXRU");
+ return ret;
+ }
+
+ if (vctx.flags & KR_DNSSEC_VFLG_WEXPAND) {
+ qry->flags.DNSSEC_WEXPAND = true;
+ }
+ if (vctx.flags & KR_DNSSEC_VFLG_OPTOUT) {
+ qry->flags.DNSSEC_OPTOUT = true;
+ }
+
+ }
+ return kr_ok();
+}
+
+static knot_rrset_t *update_ds(struct kr_zonecut *cut, const knot_pktsection_t *sec)
+{
+ /* Aggregate DS records (if using multiple keys) */
+ knot_rrset_t *new_ds = NULL;
+ for (unsigned i = 0; i < sec->count; ++i) {
+ const knot_rrset_t *rr = knot_pkt_rr(sec, i);
+ if (rr->type != KNOT_RRTYPE_DS) {
+ continue;
+ }
+ int ret = 0;
+ if (new_ds) {
+ ret = knot_rdataset_merge(&new_ds->rrs, &rr->rrs, cut->pool);
+ } else {
+ new_ds = knot_rrset_copy(rr, cut->pool);
+ if (!new_ds) {
+ return NULL;
+ }
+ }
+ if (ret != 0) {
+ knot_rrset_free(new_ds, cut->pool);
+ return NULL;
+ }
+ }
+ return new_ds;
+}
+
+static void mark_insecure_parents(const struct kr_query *qry)
+{
+ /* If there is a chain of DS queries mark all of them,
+ * then mark first non-DS parent.
+ * Stop if parent is waiting for ns address.
+ * NS can be located at unsigned zone, but still will return
+ * valid DNSSEC records for initial query. */
+ struct kr_query *parent = qry->parent;
+ while (parent && !parent->flags.AWAIT_IPV4 && !parent->flags.AWAIT_IPV6) {
+ parent->flags.DNSSEC_WANT = false;
+ parent->flags.DNSSEC_INSECURE = true;
+ if (parent->stype != KNOT_RRTYPE_DS &&
+ parent->stype != KNOT_RRTYPE_RRSIG) {
+ break;
+ }
+ parent = parent->parent;
+ }
+}
+
+static int update_parent_keys(struct kr_request *req, uint16_t answer_type)
+{
+ struct kr_query *qry = req->current_query;
+ struct kr_query *parent = qry->parent;
+ if (kr_fails_assert(parent))
+ return KR_STATE_FAIL;
+ switch(answer_type) {
+ case KNOT_RRTYPE_DNSKEY:
+ VERBOSE_MSG(qry, "<= parent: updating DNSKEY\n");
+ parent->zone_cut.key = knot_rrset_copy(qry->zone_cut.key, parent->zone_cut.pool);
+ if (!parent->zone_cut.key) {
+ return KR_STATE_FAIL;
+ }
+ break;
+ case KNOT_RRTYPE_DS:
+ VERBOSE_MSG(qry, "<= parent: updating DS\n");
+ if (qry->flags.DNSSEC_INSECURE) { /* DS non-existence proven. */
+ mark_insecure_parents(qry);
+ } else if (qry->flags.DNSSEC_NODS && !qry->flags.FORWARD) {
+ if (qry->flags.DNSSEC_OPTOUT) {
+ mark_insecure_parents(qry);
+ } else {
+ int ret = kr_dnssec_matches_name_and_type(&req->auth_selected, qry->uid,
+ qry->sname, KNOT_RRTYPE_NS);
+ if (ret == kr_ok()) {
+ mark_insecure_parents(qry);
+ }
+ }
+ } else if (qry->flags.DNSSEC_NODS && qry->flags.FORWARD) {
+ int ret = kr_dnssec_matches_name_and_type(&req->auth_selected, qry->uid,
+ qry->sname, KNOT_RRTYPE_NS);
+ if (ret == kr_ok()) {
+ mark_insecure_parents(qry);
+ }
+ } else { /* DS existence proven. */
+ parent->zone_cut.trust_anchor = knot_rrset_copy(qry->zone_cut.trust_anchor, parent->zone_cut.pool);
+ if (!parent->zone_cut.trust_anchor) {
+ return KR_STATE_FAIL;
+ }
+ }
+ break;
+ default: break;
+ }
+ return kr_ok();
+}
+
+static int update_delegation(struct kr_request *req, struct kr_query *qry, knot_pkt_t *answer, bool has_nsec3)
+{
+ struct kr_zonecut *cut = &qry->zone_cut;
+
+ /* RFC4035 3.1.4. authoritative must send either DS or proof of non-existence.
+ * If it contains neither, resolver must query the parent for the DS (RFC4035 5.2.).
+ * If DS exists, the referral is OK,
+ * otherwise referral is bogus (or an attempted downgrade attack).
+ */
+
+
+ unsigned section = KNOT_ANSWER;
+ const bool referral = !knot_wire_get_aa(answer->wire);
+ if (referral) {
+ section = KNOT_AUTHORITY;
+ } else if (knot_pkt_qtype(answer) == KNOT_RRTYPE_DS &&
+ !(qry->flags.CNAME) &&
+ (knot_wire_get_rcode(answer->wire) != KNOT_RCODE_NXDOMAIN)) {
+ section = KNOT_ANSWER;
+ } else { /* N/A */
+ return kr_ok();
+ }
+
+ int ret = 0;
+ const knot_dname_t *proved_name = knot_pkt_qname(answer);
+ /* Aggregate DS records (if using multiple keys) */
+ knot_rrset_t *new_ds = update_ds(cut, knot_pkt_section(answer, section));
+ if (!new_ds) {
+ /* No DS provided, check for proof of non-existence. */
+ if (!has_nsec3) {
+ if (referral) {
+ /* Check if it is referral to unsigned, rfc4035 5.2 */
+ ret = kr_nsec_ref_to_unsigned(&req->auth_selected,
+ qry->uid, proved_name);
+ } else {
+ /* No-data answer */
+ ret = kr_nsec_negative(&req->auth_selected, qry->uid,
+ proved_name, KNOT_RRTYPE_DS);
+ if (ret >= 0) {
+ if (ret == PKT_NODATA) {
+ ret = kr_ok();
+ } else {
+ ret = kr_error(ENOENT); // suspicious
+ }
+ }
+ }
+ } else {
+ if (referral) {
+ /* Check if it is referral to unsigned, rfc5155 8.9 */
+ ret = kr_nsec3_ref_to_unsigned(answer);
+ } else {
+ /* No-data answer, QTYPE is DS, rfc5155 8.6 */
+ ret = kr_nsec3_no_data(answer, KNOT_AUTHORITY, proved_name, KNOT_RRTYPE_DS);
+ }
+ if (ret == kr_error(KNOT_ERANGE)) {
+ /* Not bogus, going insecure due to optout */
+ ret = 0;
+ }
+ }
+
+ if (referral && qry->stype != KNOT_RRTYPE_DS &&
+ ret == DNSSEC_NOT_FOUND) {
+ /* referral,
+ * qtype is not KNOT_RRTYPE_DS, NSEC\NSEC3 were not found.
+ * Check if DS already was fetched. */
+ knot_rrset_t *ta = cut->trust_anchor;
+ if (knot_dname_is_equal(cut->name, ta->owner)) {
+ /* DS is OK */
+ ret = 0;
+ }
+ } else if (ret != 0) {
+ VERBOSE_MSG(qry, "<= bogus proof of DS non-existence\n");
+ kr_request_set_extended_error(req, KNOT_EDNS_EDE_BOGUS, "Z4I6");
+ qry->flags.DNSSEC_BOGUS = true;
+ } else if (proved_name[0] != '\0') { /* don't go to insecure for . DS */
+ qry->flags.DNSSEC_NODS = true;
+ /* Rank the corresponding nonauth NS as insecure. */
+ for (int i = 0; i < req->auth_selected.len; ++i) {
+ ranked_rr_array_entry_t *ns = req->auth_selected.at[i];
+ if (ns->qry_uid != qry->uid
+ || !ns->rr
+ || ns->rr->type != KNOT_RRTYPE_NS) {
+ continue;
+ }
+ if (!referral && !knot_dname_is_equal(qry->sname, ns->rr->owner)) {
+ continue;
+ }
+ /* Found the record. Note: this is slightly fragile
+ * in case there were more NS records in the packet.
+ * As it is now for referrals, kr_nsec*_ref_to_unsigned consider
+ * (only) the first NS record in the packet. */
+ if (!kr_rank_test(ns->rank, KR_RANK_AUTH)) { /* sanity */
+ ns->rank = KR_RANK_INSECURE;
+ }
+ break;
+ }
+ }
+ return ret;
+ } else if (qry->flags.FORWARD && qry->parent) {
+ struct kr_query *parent = qry->parent;
+ parent->zone_cut.name = knot_dname_copy(qry->sname, parent->zone_cut.pool);
+ }
+
+ /* Extend trust anchor */
+ VERBOSE_MSG(qry, "<= DS: OK\n");
+ cut->trust_anchor = new_ds;
+ return ret;
+}
+
+static const knot_dname_t *find_first_signer(ranked_rr_array_t *arr, struct kr_query *qry)
+{
+ for (size_t i = 0; i < arr->len; ++i) {
+ ranked_rr_array_entry_t *entry = arr->at[i];
+ const knot_rrset_t *rr = entry->rr;
+ if (entry->yielded ||
+ (!kr_rank_test(entry->rank, KR_RANK_INITIAL) &&
+ !kr_rank_test(entry->rank, KR_RANK_TRY) &&
+ !kr_rank_test(entry->rank, KR_RANK_MISMATCH))) {
+ continue;
+ }
+ if (rr->type != KNOT_RRTYPE_RRSIG) {
+ continue;
+ }
+ const knot_dname_t *signame = knot_rrsig_signer_name(rr->rrs.rdata);
+ if (knot_dname_in_bailiwick(rr->owner, signame) >= 0) {
+ return signame;
+ } else {
+ /* otherwise it's some nonsense, so we skip it */
+ kr_log_q(qry, VALIDATOR, "protocol violation: "
+ "out-of-bailiwick RRSIG signer, skipping\n");
+ }
+ }
+ return NULL;
+}
+
+static const knot_dname_t *signature_authority(struct kr_request *req)
+{
+ const knot_dname_t *signer_name = find_first_signer(&req->answ_selected, req->current_query);
+ if (!signer_name) {
+ signer_name = find_first_signer(&req->auth_selected, req->current_query);
+ }
+ return signer_name;
+}
+
+static int rrsig_not_found(const kr_layer_t * const ctx, const knot_pkt_t * const pkt,
+ const knot_rrset_t * const rr)
+{
+ /* Signatures are missing. There might be a zone cut that we've skipped
+ * and transitions to insecure. That can commonly happen when iterating
+ * and both sides of that cut are served by the same IP address(es).
+ * We'll try proving that the name truly is insecure - by spawning
+ * a DS sub-query on a suitable QNAME.
+ */
+ struct kr_request * const req = ctx->req;
+ struct kr_query * const qry = req->current_query;
+
+ if (qry->flags.FORWARD || qry->flags.STUB) {
+ /* Undiscovered signed cuts can't happen in the current forwarding
+ * algorithm, so this function shouldn't be able to help. */
+ return KR_STATE_FAIL;
+ }
+
+ /* Find cut_next: the name at which to try finding the "missing" zone cut. */
+ const knot_dname_t * const cut_top = qry->zone_cut.name;
+ const int next_depth = knot_dname_in_bailiwick(rr->owner, cut_top);
+ if (next_depth <= 0) {
+ return KR_STATE_FAIL; // shouldn't happen, I think
+ }
+ /* Add one extra label to cur_top, i.e. descend one level below current zone cut */
+ const knot_dname_t * const cut_next = rr->owner +
+ knot_dname_prefixlen(rr->owner, next_depth - 1, NULL);
+
+ /* Spawn that DS sub-query. */
+ struct kr_query * const next = kr_rplan_push(&req->rplan, qry, cut_next,
+ rr->rclass, KNOT_RRTYPE_DS);
+ if (!next) {
+ return KR_STATE_FAIL;
+ }
+ kr_zonecut_init(&next->zone_cut, qry->zone_cut.name, &req->pool);
+ kr_zonecut_copy(&next->zone_cut, &qry->zone_cut);
+ kr_zonecut_copy_trust(&next->zone_cut, &qry->zone_cut);
+ next->flags.DNSSEC_WANT = true;
+ return KR_STATE_YIELD;
+}
+
+static int check_validation_result(kr_layer_t *ctx, const knot_pkt_t *pkt, ranked_rr_array_t *arr)
+{
+ int ret = KR_STATE_DONE;
+ struct kr_request *req = ctx->req;
+ struct kr_query *qry = req->current_query;
+ ranked_rr_array_entry_t *invalid_entry = NULL;
+ for (size_t i = 0; i < arr->len; ++i) {
+ ranked_rr_array_entry_t *entry = arr->at[i];
+ if (entry->yielded || entry->qry_uid != qry->uid) {
+ continue;
+ }
+ if (kr_rank_test(entry->rank, KR_RANK_MISMATCH)) {
+ invalid_entry = entry;
+ break;
+ } else if (kr_rank_test(entry->rank, KR_RANK_MISSING) &&
+ !invalid_entry) {
+ invalid_entry = entry;
+ } else if (kr_rank_test(entry->rank, KR_RANK_OMIT)) {
+ continue;
+ } else if (!kr_rank_test(entry->rank, KR_RANK_SECURE) &&
+ !invalid_entry) {
+ invalid_entry = entry;
+ }
+ }
+
+ if (!invalid_entry) {
+ return ret;
+ }
+
+ if (!kr_rank_test(invalid_entry->rank, KR_RANK_SECURE) &&
+ (++(invalid_entry->revalidation_cnt) > MAX_REVALIDATION_CNT)) {
+ VERBOSE_MSG(qry, "<= continuous revalidation, fails\n");
+ kr_request_set_extended_error(req, KNOT_EDNS_EDE_OTHER,
+ "4T4L: continuous revalidation");
+ qry->flags.DNSSEC_BOGUS = true;
+ return KR_STATE_FAIL;
+ }
+
+ const knot_rrset_t *rr = invalid_entry->rr;
+ if (kr_rank_test(invalid_entry->rank, KR_RANK_MISMATCH)) {
+ const knot_dname_t *signer_name = knot_rrsig_signer_name(rr->rrs.rdata);
+ if (knot_dname_in_bailiwick(signer_name, qry->zone_cut.name) > 0) {
+ qry->zone_cut.name = knot_dname_copy(signer_name, &req->pool);
+ qry->flags.AWAIT_CUT = true;
+ } else if (!knot_dname_is_equal(signer_name, qry->zone_cut.name)) {
+ if (qry->zone_cut.parent) {
+ memcpy(&qry->zone_cut, qry->zone_cut.parent, sizeof(qry->zone_cut));
+ } else {
+ qry->flags.AWAIT_CUT = true;
+ }
+ qry->zone_cut.name = knot_dname_copy(signer_name, &req->pool);
+ }
+ VERBOSE_MSG(qry, ">< cut changed (new signer), needs revalidation\n");
+ ret = KR_STATE_YIELD;
+ } else if (kr_rank_test(invalid_entry->rank, KR_RANK_MISSING)) {
+ ret = rrsig_not_found(ctx, pkt, rr);
+ } else if (!kr_rank_test(invalid_entry->rank, KR_RANK_SECURE)) {
+ kr_request_set_extended_error(req, KNOT_EDNS_EDE_BOGUS, "NXJA");
+ qry->flags.DNSSEC_BOGUS = true;
+ ret = KR_STATE_FAIL;
+ }
+
+ return ret;
+}
+
+static bool check_empty_answer(kr_layer_t *ctx, knot_pkt_t *pkt)
+{
+ struct kr_request *req = ctx->req;
+ struct kr_query *qry = req->current_query;
+ ranked_rr_array_t *arr = &req->answ_selected;
+ size_t num_entries = 0;
+ for (size_t i = 0; i < arr->len; ++i) {
+ ranked_rr_array_entry_t *entry = arr->at[i];
+ const knot_rrset_t *rr = entry->rr;
+ if (rr->type == KNOT_RRTYPE_RRSIG && qry->stype != KNOT_RRTYPE_RRSIG) {
+ continue;
+ }
+ if (entry->qry_uid == qry->uid) {
+ ++num_entries;
+ }
+ }
+ const knot_pktsection_t *an = knot_pkt_section(pkt, KNOT_ANSWER);
+ return ((an->count != 0) && (num_entries == 0)) ? false : true;
+}
+
+static int unsigned_forward(kr_layer_t *ctx, knot_pkt_t *pkt)
+{
+ struct kr_request *req = ctx->req;
+ struct kr_query *qry = req->current_query;
+ const uint16_t qtype = knot_pkt_qtype(pkt);
+ const uint8_t pkt_rcode = knot_wire_get_rcode(pkt->wire);
+ bool nods = false;
+ bool ns_exist = true;
+ for (int i = 0; i < req->rplan.resolved.len; ++i) {
+ struct kr_query *q = req->rplan.resolved.at[i];
+ if (q->sclass == qry->sclass &&
+ q->stype == KNOT_RRTYPE_DS &&
+ knot_dname_is_equal(q->sname, qry->sname)) {
+ nods = true;
+ if (!(q->flags.DNSSEC_OPTOUT)) {
+ int ret = kr_dnssec_matches_name_and_type(&req->auth_selected, q->uid,
+ qry->sname, KNOT_RRTYPE_NS);
+ ns_exist = (ret == kr_ok());
+ }
+ }
+ }
+
+ if (nods && ns_exist && qtype == KNOT_RRTYPE_NS) {
+ qry->flags.DNSSEC_WANT = false;
+ qry->flags.DNSSEC_INSECURE = true;
+ if (qry->forward_flags.CNAME) {
+ if (kr_fails_assert(qry->cname_parent))
+ return KR_STATE_FAIL;
+ qry->cname_parent->flags.DNSSEC_WANT = false;
+ qry->cname_parent->flags.DNSSEC_INSECURE = true;
+ } else if (pkt_rcode == KNOT_RCODE_NOERROR && qry->parent != NULL) {
+ const knot_pktsection_t *sec = knot_pkt_section(pkt, KNOT_ANSWER);
+ const knot_rrset_t *rr = knot_pkt_rr(sec, 0);
+ if (rr->type == KNOT_RRTYPE_NS) {
+ qry->parent->zone_cut.name = knot_dname_copy(rr->owner, &req->pool);
+ qry->parent->flags.DNSSEC_WANT = false;
+ qry->parent->flags.DNSSEC_INSECURE = true;
+ }
+ }
+ while (qry->parent) {
+ qry = qry->parent;
+ qry->flags.DNSSEC_WANT = false;
+ qry->flags.DNSSEC_INSECURE = true;
+ if (qry->forward_flags.CNAME) {
+ if (kr_fails_assert(qry->cname_parent))
+ return KR_STATE_FAIL;
+ qry->cname_parent->flags.DNSSEC_WANT = false;
+ qry->cname_parent->flags.DNSSEC_INSECURE = true;
+ }
+ }
+ return KR_STATE_DONE;
+ }
+
+ if (ctx->state == KR_STATE_YIELD) {
+ return KR_STATE_DONE;
+ }
+
+ if (!nods && qtype != KNOT_RRTYPE_DS) {
+ struct kr_rplan *rplan = &req->rplan;
+ struct kr_query *next = kr_rplan_push(rplan, qry, qry->sname, qry->sclass, KNOT_RRTYPE_DS);
+ if (!next) {
+ return KR_STATE_FAIL;
+ }
+ kr_zonecut_set(&next->zone_cut, qry->zone_cut.name);
+ kr_zonecut_copy_trust(&next->zone_cut, &qry->zone_cut);
+ next->flags.DNSSEC_WANT = true;
+ }
+
+ return KR_STATE_YIELD;
+}
+
+static int check_signer(kr_layer_t *ctx, knot_pkt_t *pkt)
+{
+ struct kr_request *req = ctx->req;
+ struct kr_query *qry = req->current_query;
+ const knot_dname_t *ta_name = qry->zone_cut.trust_anchor ? qry->zone_cut.trust_anchor->owner : NULL;
+ const knot_dname_t *signer = signature_authority(req);
+ if (ta_name && (!signer || !knot_dname_is_equal(ta_name, signer))) {
+ /* check all newly added RRSIGs */
+ if (!signer) {
+ if (qry->flags.FORWARD) {
+ return unsigned_forward(ctx, pkt);
+ }
+ /* Not a DNSSEC-signed response. */
+ if (ctx->state == KR_STATE_YIELD) {
+ /* Already yielded for revalidation.
+ * It means that trust chain is OK and
+ * transition to INSECURE hasn't occurred.
+ * Let the validation logic ask about RRSIG. */
+ return KR_STATE_DONE;
+ }
+ /* Ask parent for DS
+ * to prove transition to INSECURE. */
+ const uint16_t qtype = knot_pkt_qtype(pkt);
+ const knot_dname_t *qname = knot_pkt_qname(pkt);
+ if (qtype == KNOT_RRTYPE_NS &&
+ knot_dname_in_bailiwick(qname, qry->zone_cut.name) > 0) {
+ /* Server is authoritative
+ * for both parent and child,
+ * and child zone is not signed. */
+ qry->zone_cut.name = knot_dname_copy(qname, &req->pool);
+ }
+ } else if (knot_dname_in_bailiwick(signer, qry->zone_cut.name) > 0) {
+ if (!(qry->flags.FORWARD)) {
+ /* Key signer is below current cut, advance and refetch keys. */
+ qry->zone_cut.name = knot_dname_copy(signer, &req->pool);
+ } else {
+ /* Check if DS does not exist. */
+ struct kr_query *q = kr_rplan_find_resolved(&req->rplan, NULL,
+ signer, qry->sclass, KNOT_RRTYPE_DS);
+ if (q && q->flags.DNSSEC_NODS) {
+ qry->flags.DNSSEC_WANT = false;
+ qry->flags.DNSSEC_INSECURE = true;
+ if (qry->parent) {
+ qry->parent->flags.DNSSEC_WANT = false;
+ qry->parent->flags.DNSSEC_INSECURE = true;
+ }
+ } else if (qry->stype != KNOT_RRTYPE_DS) {
+ struct kr_rplan *rplan = &req->rplan;
+ struct kr_query *next = kr_rplan_push(rplan, qry, qry->sname,
+ qry->sclass, KNOT_RRTYPE_DS);
+ if (!next) {
+ return KR_STATE_FAIL;
+ }
+ kr_zonecut_set(&next->zone_cut, qry->zone_cut.name);
+ kr_zonecut_copy_trust(&next->zone_cut, &qry->zone_cut);
+ next->flags.DNSSEC_WANT = true;
+ }
+ }
+ } else if (!knot_dname_is_equal(signer, qry->zone_cut.name)) {
+ /* Key signer is above the current cut, so we can't validate it. This happens when
+ a server is authoritative for both grandparent, parent and child zone.
+ Ascend to parent cut, and refetch authority for signer. */
+ if (qry->zone_cut.parent) {
+ memcpy(&qry->zone_cut, qry->zone_cut.parent, sizeof(qry->zone_cut));
+ } else {
+ qry->flags.AWAIT_CUT = true;
+ }
+ qry->zone_cut.name = knot_dname_copy(signer, &req->pool);
+ }
+
+ /* zone cut matches, but DS/DNSKEY doesn't => refetch. */
+ VERBOSE_MSG(qry, ">< cut changed, needs revalidation\n");
+ if ((qry->flags.FORWARD) && qry->stype != KNOT_RRTYPE_DS) {
+ struct kr_rplan *rplan = &req->rplan;
+ struct kr_query *next = kr_rplan_push(rplan, qry, signer,
+ qry->sclass, KNOT_RRTYPE_DS);
+ if (!next) {
+ return KR_STATE_FAIL;
+ }
+ kr_zonecut_set(&next->zone_cut, qry->zone_cut.name);
+ kr_zonecut_copy_trust(&next->zone_cut, &qry->zone_cut);
+ next->flags.DNSSEC_WANT = true;
+ return KR_STATE_YIELD;
+ }
+ if (!(qry->flags.FORWARD)) {
+ return KR_STATE_YIELD;
+ }
+ }
+ return KR_STATE_DONE;
+}
+
+/** Change ranks of RRs from this single iteration:
+ * _INITIAL or _TRY or _MISSING -> rank_to_set. Or any rank, if any_rank == true.
+ *
+ * Optionally do this only in a `bailiwick` (if not NULL).
+ * Iterator shouldn't have selected such records, but we check to be sure. */
+static void rank_records(struct kr_query *qry, bool any_rank, enum kr_rank rank_to_set,
+ const knot_dname_t *bailiwick)
+{
+ struct kr_request *req = qry->request;
+ ranked_rr_array_t *ptrs[2] = { &req->answ_selected, &req->auth_selected };
+ for (size_t i = 0; i < 2; ++i) {
+ ranked_rr_array_t *arr = ptrs[i];
+ for (size_t j = 0; j < arr->len; ++j) {
+ ranked_rr_array_entry_t *entry = arr->at[j];
+ if (entry->qry_uid != qry->uid) {
+ continue;
+ }
+ if (bailiwick && knot_dname_in_bailiwick(entry->rr->owner,
+ bailiwick) < 0) {
+ continue;
+ }
+ if (any_rank
+ || kr_rank_test(entry->rank, KR_RANK_INITIAL)
+ || kr_rank_test(entry->rank, KR_RANK_TRY)
+ || kr_rank_test(entry->rank, KR_RANK_MISSING)) {
+ kr_rank_set(&entry->rank, rank_to_set);
+ }
+ }
+ }
+}
+
+static void check_wildcard(kr_layer_t *ctx)
+{
+ struct kr_request *req = ctx->req;
+ struct kr_query *qry = req->current_query;
+ ranked_rr_array_t *ptrs[2] = { &req->answ_selected, &req->auth_selected };
+
+ for (int i = 0; i < 2; ++i) {
+ ranked_rr_array_t *arr = ptrs[i];
+ for (ssize_t j = 0; j < arr->len; ++j) {
+ ranked_rr_array_entry_t *entry = arr->at[j];
+ const knot_rrset_t *rrsigs = entry->rr;
+
+ if (qry->uid != entry->qry_uid) {
+ continue;
+ }
+
+ if (rrsigs->type != KNOT_RRTYPE_RRSIG) {
+ continue;
+ }
+
+ int owner_labels = knot_dname_labels(rrsigs->owner, NULL);
+
+ knot_rdata_t *rdata_k = rrsigs->rrs.rdata;
+ for (int k = 0; k < rrsigs->rrs.count;
+ ++k, rdata_k = knot_rdataset_next(rdata_k)) {
+ if (knot_rrsig_labels(rdata_k) != owner_labels) {
+ qry->flags.DNSSEC_WEXPAND = true;
+ }
+ }
+ }
+ }
+}
+
+/** Just for wildcard_adjust_to_wire() */
+static bool rr_is_for_wildcard(const ranked_rr_array_entry_t *entry)
+{
+ switch (kr_rrset_type_maysig(entry->rr)) {
+ case KNOT_RRTYPE_NSEC:
+ case KNOT_RRTYPE_NSEC3:
+ return true;
+ default:
+ return false;
+ }
+}
+/** In case of wildcard expansion, mark required authority RRs by to_wire. */
+static int wildcard_adjust_to_wire(struct kr_request *req, const struct kr_query *qry)
+{
+ if (!qry->parent && qry->flags.DNSSEC_WEXPAND) {
+ return kr_ranked_rrarray_set_wire(&req->auth_selected, true,
+ qry->uid, true, &rr_is_for_wildcard);
+ }
+ return kr_ok();
+}
+
+static int validate(kr_layer_t *ctx, knot_pkt_t *pkt)
+{
+ int ret = 0;
+ struct kr_request *req = ctx->req;
+ struct kr_query *qry = req->current_query;
+
+ /* Ignore faulty or unprocessed responses. */
+ if (ctx->state & (KR_STATE_FAIL|KR_STATE_CONSUME)) {
+ return ctx->state;
+ }
+
+ /* Pass-through if user doesn't want secure answer or stub. */
+ if (qry->flags.STUB) {
+ rank_records(qry, false, KR_RANK_OMIT, NULL);
+ return ctx->state;
+ }
+ uint8_t pkt_rcode = knot_wire_get_rcode(pkt->wire);
+ if ((qry->flags.FORWARD) &&
+ pkt_rcode != KNOT_RCODE_NOERROR &&
+ pkt_rcode != KNOT_RCODE_NXDOMAIN) {
+ do {
+ qry->flags.DNSSEC_BOGUS = true;
+ if (qry->cname_parent) {
+ qry->cname_parent->flags.DNSSEC_BOGUS = true;
+ }
+ qry = qry->parent;
+ } while (qry);
+ ctx->state = KR_STATE_DONE;
+ return ctx->state;
+ }
+
+ if (!(qry->flags.DNSSEC_WANT)) {
+ const bool is_insec = qry->flags.CACHED && qry->flags.DNSSEC_INSECURE;
+ if ((qry->flags.DNSSEC_INSECURE)) {
+ rank_records(qry, true, KR_RANK_INSECURE, qry->zone_cut.name);
+ }
+ if (is_insec && qry->parent != NULL) {
+ /* We have got insecure answer from cache.
+ * Mark parent(s) as insecure. */
+ mark_insecure_parents(qry);
+ VERBOSE_MSG(qry, "<= cached insecure response, going insecure\n");
+ ctx->state = KR_STATE_DONE;
+ } else if (ctx->state == KR_STATE_YIELD) {
+ /* Transition to insecure state
+ occurred during revalidation.
+ if state remains YIELD, answer will not be cached.
+ Let cache layers to work. */
+ ctx->state = KR_STATE_DONE;
+ }
+ return ctx->state;
+ }
+
+ /* Pass-through if CD bit is set. */
+ if (knot_wire_get_cd(req->qsource.packet->wire)) {
+ check_wildcard(ctx);
+ wildcard_adjust_to_wire(req, qry);
+ rank_records(qry, false, KR_RANK_OMIT, NULL);
+ return ctx->state;
+ }
+ /* Answer for RRSIG may not set DO=1, but all records MUST still validate. */
+ bool use_signatures = (knot_pkt_qtype(pkt) != KNOT_RRTYPE_RRSIG);
+ if (!(qry->flags.CACHED) && !knot_pkt_has_dnssec(pkt) && !use_signatures) {
+ VERBOSE_MSG(qry, "<= got insecure response\n");
+ kr_request_set_extended_error(req, KNOT_EDNS_EDE_BOGUS, "MISQ");
+ qry->flags.DNSSEC_BOGUS = true;
+ return KR_STATE_FAIL;
+ }
+
+ /* Check if this is a DNSKEY answer, check trust chain and store. */
+ uint16_t qtype = knot_pkt_qtype(pkt);
+ bool has_nsec3 = pkt_has_type(pkt, KNOT_RRTYPE_NSEC3);
+ const knot_pktsection_t *an = knot_pkt_section(pkt, KNOT_ANSWER);
+ const bool referral = (an->count == 0 && !knot_wire_get_aa(pkt->wire));
+
+ if (!(qry->flags.CACHED) && knot_wire_get_aa(pkt->wire)) {
+ /* Check if answer if not empty,
+ * but iterator has not selected any records. */
+ if (!check_empty_answer(ctx, pkt)) {
+ VERBOSE_MSG(qry, "<= no useful RR in authoritative answer\n");
+ kr_request_set_extended_error(req, KNOT_EDNS_EDE_BOGUS, "MJX6");
+ qry->flags.DNSSEC_BOGUS = true;
+ return KR_STATE_FAIL;
+ }
+ /* Track difference between current TA and signer name.
+ * This indicates that the NS is auth for both parent-child,
+ * and we must update DS/DNSKEY to validate it.
+ */
+ ret = check_signer(ctx, pkt);
+ if (ret != KR_STATE_DONE) {
+ return ret;
+ }
+ if (qry->flags.FORWARD && qry->flags.DNSSEC_INSECURE) {
+ return KR_STATE_DONE;
+ }
+ }
+
+ if (knot_wire_get_aa(pkt->wire) && qtype == KNOT_RRTYPE_DNSKEY) {
+ const knot_rrset_t *ds = qry->zone_cut.trust_anchor;
+ if (ds && !kr_ds_algo_support(ds)) {
+ VERBOSE_MSG(qry, ">< all DS entries use unsupported algorithm pairs, going insecure\n");
+ /* ^ the message is a bit imprecise to avoid being too verbose */
+ kr_request_set_extended_error(req, KNOT_EDNS_EDE_OTHER, "LSLC: unsupported digest/key");
+ qry->flags.DNSSEC_WANT = false;
+ qry->flags.DNSSEC_INSECURE = true;
+ rank_records(qry, true, KR_RANK_INSECURE, qry->zone_cut.name);
+ mark_insecure_parents(qry);
+ return KR_STATE_DONE;
+ }
+
+ ret = validate_keyset(req, pkt, has_nsec3);
+ if (ret == kr_error(EAGAIN)) {
+ VERBOSE_MSG(qry, ">< cut changed, needs revalidation\n");
+ return KR_STATE_YIELD;
+ } else if (ret != 0) {
+ VERBOSE_MSG(qry, "<= bad keys, broken trust chain\n");
+ /* EDE code already set in validate_keyset() */
+ qry->flags.DNSSEC_BOGUS = true;
+ return KR_STATE_FAIL;
+ }
+ }
+
+ /* Validate all records, fail as bogus if it doesn't match.
+ * Do not revalidate data from cache, as it's already trusted.
+ * TTLs of RRsets may get lowered. */
+ if (!(qry->flags.CACHED)) {
+ ret = validate_records(req, pkt, req->rplan.pool, has_nsec3);
+ if (ret == KNOT_EDOWNGRADED) {
+ return KR_STATE_DONE;
+ } else if (ret != 0) {
+ /* something exceptional - no DNS key, empty pointers etc
+ * normally it shouldn't happen */
+ VERBOSE_MSG(qry, "<= couldn't validate RRSIGs\n");
+ kr_request_set_extended_error(req, KNOT_EDNS_EDE_OTHER,
+ "O4TP: couldn't validate RRSIGs");
+ qry->flags.DNSSEC_BOGUS = true;
+ return KR_STATE_FAIL;
+ }
+ /* check validation state and spawn subrequests */
+ if (!req->answ_validated) {
+ ret = check_validation_result(ctx, pkt, &req->answ_selected);
+ if (ret != KR_STATE_DONE) {
+ return ret;
+ }
+ }
+ if (!req->auth_validated) {
+ ret = check_validation_result(ctx, pkt, &req->auth_selected);
+ if (ret != KR_STATE_DONE) {
+ return ret;
+ }
+ }
+ }
+
+ /* Validate non-existence proof if not positive answer.
+ * In case of CNAME, iterator scheduled a sibling query for the target,
+ * so we just drop the negative piece of information and don't try to prove it.
+ * TODO: not ideal; with aggressive cache we'll at least avoid the extra packet. */
+ if (!qry->flags.CACHED && pkt_rcode == KNOT_RCODE_NXDOMAIN && !qry->flags.CNAME) {
+ /* @todo If knot_pkt_qname(pkt) is used instead of qry->sname then the tests crash. */
+ if (!has_nsec3) {
+ ret = kr_nsec_negative(&req->auth_selected, qry->uid,
+ qry->sname, KNOT_RRTYPE_NULL);
+ if (ret >= 0) {
+ if (ret & PKT_NXDOMAIN) {
+ ret = kr_ok();
+ } else {
+ ret = kr_error(ENOENT); // probably proved NODATA
+ }
+ }
+ } else {
+ ret = kr_nsec3_name_error_response_check(pkt, KNOT_AUTHORITY, qry->sname);
+ }
+ if (has_nsec3 && (ret == kr_error(KNOT_ERANGE))) {
+ /* NXDOMAIN proof is OK,
+ * but NSEC3 that covers next closer name
+ * (or wildcard at next closer name) has opt-out flag.
+ * RFC5155 9.2; AD flag can not be set */
+ qry->flags.DNSSEC_OPTOUT = true;
+ VERBOSE_MSG(qry, "<= can't prove NXDOMAIN due to optout, going insecure\n");
+ } else if (ret != 0) {
+ VERBOSE_MSG(qry, "<= bad NXDOMAIN proof\n");
+ kr_request_set_extended_error(req, KNOT_EDNS_EDE_NSEC_MISS, "3WKM");
+ qry->flags.DNSSEC_BOGUS = true;
+ return KR_STATE_FAIL;
+ }
+ }
+
+ /* @todo WTH, this needs API that just tries to find a proof and the caller
+ * doesn't have to worry about NSEC/NSEC3
+ * @todo rework this
+ * CNAME: same as the NXDOMAIN case above */
+ if (!qry->flags.CACHED && pkt_rcode == KNOT_RCODE_NOERROR && !qry->flags.CNAME) {
+ bool no_data = (an->count == 0 && knot_wire_get_aa(pkt->wire));
+ if (no_data) {
+ /* @todo
+ * ? quick mechanism to determine which check to preform first
+ * ? merge the functionality together to share code/resources
+ */
+ if (!has_nsec3) {
+ ret = kr_nsec_negative(&req->auth_selected, qry->uid,
+ knot_pkt_qname(pkt), knot_pkt_qtype(pkt));
+ if (ret >= 0) {
+ if (ret == PKT_NODATA) {
+ ret = kr_ok();
+ } else {
+ ret = kr_error(ENOENT); // suspicious
+ }
+ }
+ } else {
+ ret = kr_nsec3_no_data(pkt, KNOT_AUTHORITY, knot_pkt_qname(pkt), knot_pkt_qtype(pkt));
+ }
+ if (ret != 0) {
+ if (has_nsec3 && (ret == kr_error(KNOT_ERANGE))) {
+ VERBOSE_MSG(qry, "<= can't prove NODATA due to optout, going insecure\n");
+ qry->flags.DNSSEC_OPTOUT = true;
+ /* Could not return from here,
+ * we must continue, validate NSEC\NSEC3 and
+ * call update_parent_keys() to mark
+ * parent queries as insecure */
+ } else {
+ VERBOSE_MSG(qry, "<= bad NODATA proof\n");
+ kr_request_set_extended_error(req, KNOT_EDNS_EDE_NSEC_MISS, "AHXI");
+ qry->flags.DNSSEC_BOGUS = true;
+ return KR_STATE_FAIL;
+ }
+ }
+ }
+ }
+
+ wildcard_adjust_to_wire(req, qry);
+
+ /* Check and update current delegation point security status. */
+ ret = update_delegation(req, qry, pkt, has_nsec3);
+ if (ret == DNSSEC_NOT_FOUND && qry->stype != KNOT_RRTYPE_DS) {
+ if (ctx->state == KR_STATE_YIELD) {
+ VERBOSE_MSG(qry, "<= can't validate referral\n");
+ kr_request_set_extended_error(req, KNOT_EDNS_EDE_BOGUS, "XLE4");
+ qry->flags.DNSSEC_BOGUS = true;
+ return KR_STATE_FAIL;
+ } else {
+ /* Check the trust chain and query DS\DNSKEY if needed. */
+ VERBOSE_MSG(qry, "<= DS\\NSEC was not found, querying for DS\n");
+ return KR_STATE_YIELD;
+ }
+ } else if (ret != 0) {
+ return KR_STATE_FAIL;
+ } else if (pkt_rcode == KNOT_RCODE_NOERROR &&
+ referral &&
+ ((!qry->flags.DNSSEC_WANT && qry->flags.DNSSEC_INSECURE) ||
+ (qry->flags.DNSSEC_NODS))) {
+ /* referral with proven DS non-existence */
+ qtype = KNOT_RRTYPE_DS;
+ }
+ /* Update parent query zone cut */
+ if (qry->parent) {
+ if (update_parent_keys(req, qtype) != 0) {
+ return KR_STATE_FAIL;
+ }
+ }
+
+ if (qry->flags.FORWARD && qry->parent) {
+ if (pkt_rcode == KNOT_RCODE_NXDOMAIN) {
+ qry->parent->forward_flags.NO_MINIMIZE = true;
+ }
+ }
+ VERBOSE_MSG(qry, "<= answer valid, OK\n");
+ return KR_STATE_DONE;
+}
+
+/** Hide RRsets which did not validate from clients. */
+static int hide_bogus(kr_layer_t *ctx) {
+ if (knot_wire_get_cd(ctx->req->qsource.packet->wire)) {
+ return ctx->state;
+ }
+ /* We don't want to send bogus answers to clients, not even in SERVFAIL
+ * answers, but we cannot drop whole sections. If a CNAME chain
+ * SERVFAILs somewhere, the steps that were OK should be put into
+ * answer.
+ *
+ * There is one specific issue: currently we follow CNAME *before*
+ * we validate it, because... iterator comes before validator.
+ * Therefore some rrsets might be added into req->*_selected before
+ * we detected failure in validator.
+ * TODO: better approach, probably during work on parallel queries.
+ */
+ const ranked_rr_array_t *sel[] = kr_request_selected(ctx->req);
+ for (knot_section_t sect = KNOT_ANSWER; sect <= KNOT_ADDITIONAL; ++sect) {
+ for (size_t i = 0; i < sel[sect]->len; ++i) {
+ ranked_rr_array_entry_t *e = sel[sect]->at[i];
+ e->to_wire = e->to_wire
+ && !kr_rank_test(e->rank, KR_RANK_INDET)
+ && !kr_rank_test(e->rank, KR_RANK_BOGUS)
+ && !kr_rank_test(e->rank, KR_RANK_MISMATCH)
+ && !kr_rank_test(e->rank, KR_RANK_MISSING);
+ }
+ }
+ return ctx->state;
+}
+
+static int validate_wrapper(kr_layer_t *ctx, knot_pkt_t *pkt) {
+ // Wrapper for now.
+ int ret = validate(ctx, pkt);
+ struct kr_request *req = ctx->req;
+ struct kr_query *qry = req->current_query;
+ if (ret & KR_STATE_FAIL && qry->flags.DNSSEC_BOGUS)
+ qry->server_selection.error(qry, req->upstream.transport, KR_SELECTION_DNSSEC_ERROR);
+ if (ret & KR_STATE_DONE && !qry->flags.DNSSEC_BOGUS) {
+ /* Don't report extended DNS errors related to validation
+ * when it managed to succeed (e.g. by trying different auth). */
+ switch (req->extended_error.info_code) {
+ case KNOT_EDNS_EDE_BOGUS:
+ case KNOT_EDNS_EDE_NSEC_MISS:
+ case KNOT_EDNS_EDE_RRSIG_MISS:
+ case KNOT_EDNS_EDE_SIG_EXPIRED:
+ case KNOT_EDNS_EDE_SIG_NOTYET:
+ kr_request_set_extended_error(req, KNOT_EDNS_EDE_NONE, NULL);
+ break;
+ case KNOT_EDNS_EDE_DNSKEY_MISS:
+ case KNOT_EDNS_EDE_DNSKEY_BIT:
+ kr_assert(false); /* These EDE codes aren't used. */
+ break;
+ default: break; /* Remaining codes don't indicate hard DNSSEC failure. */
+ }
+ }
+ return ret;
+}
+
+
+/** Module implementation. */
+int validate_init(struct kr_module *self)
+{
+ static const kr_layer_api_t layer = {
+ .consume = &validate_wrapper,
+ .answer_finalize = &hide_bogus,
+ };
+ self->layer = &layer;
+ return kr_ok();
+}
+
+KR_MODULE_EXPORT(validate) /* useless for builtin module, but let's be consistent */
+
+#undef VERBOSE_MSG
diff --git a/lib/layer/validate.test.integr/deckard.yaml b/lib/layer/validate.test.integr/deckard.yaml
new file mode 100644
index 0000000..aac7b20
--- /dev/null
+++ b/lib/layer/validate.test.integr/deckard.yaml
@@ -0,0 +1,10 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+programs:
+- name: kresd
+ binary: kresd
+ additional:
+ - -n
+ templates:
+ - lib/layer/validate.test.integr/kresd_config.j2
+ configs:
+ - config
diff --git a/lib/layer/validate.test.integr/fwd_insecure_but_rrsig_signer_invalid.rpl b/lib/layer/validate.test.integr/fwd_insecure_but_rrsig_signer_invalid.rpl
new file mode 100644
index 0000000..3cc0968
--- /dev/null
+++ b/lib/layer/validate.test.integr/fwd_insecure_but_rrsig_signer_invalid.rpl
@@ -0,0 +1,294 @@
+; SPDX-License-Identifier: GPL-3.0-or-later
+ val-override-date: "20200722144207"
+ trust-anchor: ". IN DS 20326 8 2 E06D44B80B8F1D39A95C0B0D7C65D08458E880409BBC683457104237C7F8EC8D"
+CONFIG_END
+
+SCENARIO_BEGIN Forwarding: forwarder sent RRSIGs with invalid signed for an insecure zone, it should not cause SERVFAIL because the zone is insecure
+
+
+; forwarder
+RANGE_BEGIN 0 100
+ ADDRESS 8.8.8.8
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR RD RA AD CD NOERROR
+SECTION QUESTION
+. IN DNSKEY
+SECTION ANSWER
+. 86913 IN DNSKEY 256 3 8 AwEAAdauOGxLhfAKFTTZwGhBXbk793QK dWIQRjiSftWdusCwkPhNyJrIjwtNffCW XGLlZAbpcs414RE3oS1qVwV+AdXsO92S Bu5haGlxMUk0NqZO7Xlf84/wrzGZVRRo uPo5pNX/CKS8Mv9UOi0olKGCu31dNfh8 qCszWZcloLDgeLzSnQSkvFoGe69vNCfh 7feESKedkBC2qRz0BZv9+oJI0IY/3D7W EnV0NOlf8gSHozhfJFJ/ZAKtvw/Q3ogr VJFk0LyVaU/NVtVA5FM4pVMIRID7pfrP i78aAzG7b/Wh/Pce4jPAIpS3dApq25Yk vMuPvfB91NMf9FemKwlp78PBVcM=
+. 86913 IN DNSKEY 257 3 8 AwEAAaz/tAm8yTn4Mfeh5eyI96WSVexT BAvkMgJzkKTOiW1vkIbzxeF3+/4RgWOq 7HrxRixHlFlExOLAJr5emLvN7SWXgnLh 4+B5xQlNVz8Og8kvArMtNROxVQuCaSnI DdD5LKyWbRd2n9WGe2R8PzgCmr3EgVLr jyBxWezF0jLHwVN8efS3rCj/EWgvIWgb 9tarpVUDK/b58Da+sqqls3eNbuv7pr+e oZG+SrDK6nWeL3c6H5Apxz7LjVc1uTId sIXxuOLYA4/ilBmSVIzuDWfdRUfhHdY6 +cn8HFRm+2hM8AnXGXws9555KrUB5qih ylGa8subX2Nn6UwNR1AkUTV74bU=
+. 86913 IN RRSIG DNSKEY 8 0 172800 20200811000000 20200721000000 20326 . IcMH/yNRoNKkCPmOo8MDcMEZO4sF8p0A 8xgASRnD1c0t+VSU5NRzh05eME7RJrRP 31T/E4eUh+jyI18Gz/O5Lg02Zu1wmcOy Mnkr+bfU+Al7pCztj+6aGTUl34HFyWtM cChKkeJQDeJoBtyVDVa4oL1FQs4Ml6HC OOjzoOKIHakrfCLyaktN82G+uNFXt0CB SGR2xQSWDKnzqSJqCep9X8NtNjjAFus2 g8weAXomG2+gRlrNfQAFqcGPjLHeVtZv yco3u0u8ZOp+8PC8fnlLhtpJ3DBXgwFp wY3V7uM7Zfabcio64st79wu4zNwZR5uf IEpKciMtUh8J8LfVWFM62w==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR RD RA AD CD NXDOMAIN
+SECTION QUESTION
+_TA-4f66. IN NULL
+SECTION AUTHORITY
+. 86161 IN NSEC aaa. NS SOA RRSIG NSEC DNSKEY
+. 86161 IN RRSIG NSEC 8 0 86400 20200804050000 20200722040000 46594 . zNoDySatAPoT5YV6XmQcz3qs60+GxuEo yITrzrWMEU1keQNU+6663BM6N/F6G2nd b5Bj5cY5m7MN7iZnBFN/cXQd7EWjdLTC Fw7FxBPc3J51vqShIaM2xxpm9RRdpaB/ vfei+x2e+4YRCJJdw81qmrUBBohANyNW 119JAEufoTgAVY9jPd8699lJ4svMY10E avFAL+PTfC/la9KKNPlOgDgbVRjpUZcU wLeooyqggterm4kXcnWahk3PtG3tmB7A zz1qccY6rOeQALloUQ3Im1Wl9s6pbExZ XI/6qBXYetdexB6DpebnsAk1P4wTprhQ iIxvZpHCppz/jMAx/KDRjQ==
+. 86161 IN RRSIG SOA 8 0 86400 20200804050000 20200722040000 46594 . qI98OcNtjSzHbTbiNg6MZRopwcTAW0Cm JiHKdcEOzGY+Tabxyl76YDeVWEZuKrYG pzeqFLKC05W+4nQrUKTmCoI89YHFNdAc f8uO7zbSEM6dFlS4ksCZFkZZHb2hjp4g KI1MEkI56EsojYqEDa1fXakpytEucvKO 2qJgcqPVkb29lk2lePIicO4YIddI38M4 BNdKsCnEhdMYC76lKls7EYMfJeHAr+FX c3SZIAG/r3ov2KR0u/CNqDDlKcfsGCVt wRCWE/EYUMuZbCNW7/cZ8fCWps1Xn7fu I8N7YLgMTqAsAmXx4I86zf8TAUTslgYN 5IR69n16/l2h6QP9vJPS3g==
+. 86161 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2020072200 1800 900 604800 86400
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR RD RA AD CD NOERROR
+SECTION QUESTION
+fi. IN DS
+SECTION ANSWER
+fi. 48962 IN DS 44855 8 2 80cd184a31c50d5dc44b4f98811f298315986b44edcc0666455c6aef7dbd997e
+fi. 48962 IN RRSIG DS 8 1 86400 20200803200000 20200721190000 46594 . HhKwynZK3BYIdOYlwFp6wLacu8uci+ig va3NggxT/LdJqCXlIpuBV5EBGFnEowA9 dYJMdJkkbizYmqkTLbAqaomS5nH3Juz4 5rvjtqi2/viyZjy9VfIPtWx5T5+xfSHH tLac4rJk8ieKSxhpjcc9tITGFT0cnU7U kpWD8OO/0toJF94diLleqS7M/uCDIYyj zgvwIuvx0WxwgxG6bG45EvwfWQbIMRTi R2XSzKtOTRSBbXtI0XKoGrTblOkVxCei uQka3Jqpm/HvmFa9rsspylXTC/6VkKwC u+/TogoJ9vobAr9vXpLx0LiYTkh3GKzZ QL0uw/36jcqplPHlddICPg==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR RD RA AD CD NOERROR
+SECTION QUESTION
+fi. IN DNSKEY
+SECTION ANSWER
+fi. 793 IN DNSKEY 256 3 8 AwEAAbfXUBTwb2oWNVvv3kCwgaER6vZ6 76rm5DsLmQjOuClDEHXRtH4JmX+nbjmX yFfeNRBasI0jr2sLIYSPB2TF7ctF/FLB a4zgEKIOTiwM2Q58bBxzUhXtU2KAgqEo V5X7kHYau899uJSW+CUJhKAPYpb/sb41 VqSUrsxkACf5ocZ4k4K57H81B2OKZSHC u6C6h4h7D59l8fwYg7F+RAr2vJENfbSM EjHfIWt54x7WfDuCKGDYvpoKmdgg/ACg 6CyLMttbml5dCZ9XJyWyFbs7eJZYGOgN Uw/3ezxmouChVSqqOeVzZAwfsUAsjb1l 1GSSj3YSiRVY4FWewrdw7XL09v0=
+fi. 793 IN DNSKEY 257 3 8 AwEAAb9AMR4NV2YxZH9E6ELMFY5DOszk dTd5AxhSg1YZWi8B9cruHXjghFCmApd1 VfUyQ4MX3DZbskfML/ToxumeSv9OhfA4 I6Fao9bN9UxsBbFlkqwqhAGmuJapSgNu yMWArSoUG4XB/dykPNdyFt+3t1dEH/S3 hS5JmZccSI6YAjnUfG+Pd45R8ljO8ERI 1wSa0IJjDArkuFaLcGrtjR9GJluVmM15 0gWVUIiUkBfDUz8pFjqAWewk0QY9TX22 Z8gfl3yKhO9TYPVHN1oMHTydVqjQKbdb s/BvGXx/GPh63OOxE2ICmxXcz2Ma+082 eA0DfwKLo86PFOre8YK7pEWuw4U=
+fi. 793 IN RRSIG DNSKEY 8 1 900 20200805163544 20200722030600 44855 fi. p9isNtIsiD4yhCQkiVeyfPva4iXV8+oE hhU/SEec2ykGjs22yiscFKppV/4s738y Tl58F682IXAq5jolf/6ShAMOUqxzMD1j 5nphLZ62O5B/r6Ah9JiJf9l748mXHCAW kOnwep4IpkEJkiS1lOHgcxd0hw/rsRNZ QAAgiDhYBGcTIWLw6FFsWL/sMJTEnMim 4QzkDLrF4MlFRduQSffC2N7mBbtQpwYt BFS38tZHQZ7w48or3GGJw7ejwR7IQQQJ VYO7yWr13eLZiGPnne51tvltO7LVeDbl cskxbGWYdtTaB+klcukrVlApqUopqjbT mgzA60/IMKe4PXk+QnzZeA==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR RD RA CD NOERROR
+SECTION QUESTION
+dIGiTrAnSIT.FI. IN DS
+SECTION AUTHORITY
+FI. 1334 IN SOA a.FI. fi-domain-tech.ficora.FI. 2020072239 3605 1800 2419200 86400
+FI. 21134 IN RRSIG SOA 8 1 86400 20200805082122 20200722074635 20436 fi. mXyNMPJRTLMLOKDjZ2ET/z1SOO9g0a8o o1dsHchts2X0uPvYu6Hc8quBCmUbmjhe qu9dRDiDtjCyddFScwn9FTI9CRMJKytB 1LVcrlBrbuWFlmDilRLkhrK2gmm6MOYU /VGgj+kgEtIQE7NSGF35NQHTJfDw1Jmo FxGAo7I//QBAHJemx5Q4YmbVMDiyTBjz FCLSdAjCGouJTRU9jFgweoEivGk+yD+H vsaaG7NTumzK4miU3SL4sMPb9NYr+HIR 2j+6pUjD05x9UOKAfIQzFnRcToDB1KUo ZZr8teWnLH3fbHCq9JGfz338Eju0wdfe 0E2CGL6Cc77+VThotyTrAg==
+es7p5jquq6ng6hd9vn5q3el38s2vuoqh.FI. 21134 IN NSEC3 1 1 5 7298d6895c6c0415 escp8o5mqifge1u5itme7ju27k5hf19a NS DS RRSIG
+es7p5jquq6ng6hd9vn5q3el38s2vuoqh.FI. 21134 IN RRSIG NSEC3 8 2 86400 20200805124944 20200722030600 20436 fi. S/DGd4jI4zndv50oMGp2BmB/aH9/M3AX /My9hwZ4zi2r88DrYiNyd2ghyuUvZO9a lvY2NcB9cX9sjAdQAM/xmoHsoraB5YWV v53YBTJDF+kY7BzO5mqImNWmkpe/Kcxt Mpp9Gz02ySpPp37dot4FbdK9A0RWERVw XkoEaFvLkHRf3QGMJUBnCjKJ7r448axs OAKdHIIQb6aG6OATML6mJx6xHOeI8CFl giTrgixGOR/qGP92i9ErcP9iQ2lvHlfK A7SuOLi6uSPBYWIgZzkqGJOpJ0o+cPHV 69QX/SP7m0qr00shV+rxfyppHCLUpKBx iXacRghILlVV5mUgV/25lw==
+ml0llbvj7rbbtgbp31q2j3d3qv89643r.FI. 21134 IN NSEC3 1 1 5 7298d6895c6c0415 ml0mjk4qs3b070682obd52l1p9v07cl6 NS SOA TXT RRSIG DNSKEY NSEC3PARAM
+ml0llbvj7rbbtgbp31q2j3d3qv89643r.FI. 21134 IN RRSIG NSEC3 8 2 86400 20200804210456 20200722030600 20436 fi. bLLvaTmn2WXk8RxKz7Kb28FoDSgNuIoj ZPrpnwyYVRltfYvOe8wOtzzPQtDYj9F8 bqZgPmZFIAQfsKJk86NMsEWvArGYhX8z 1w6z4qkfpgXpLGeV6fNjLMi/YHZRHQJn cELLNcxh/U9e+xuURCr55XzgzpVVnXpk fm2848LbLO/9p2ZltOGd+GWcyQxxt/aK FlSHUHz2Zp27/9wNCxRyQ8EKtR4eIic8 T9p4kgu5w6302GPSAlfbFCX8Yf+ikMvE Fy7XdbLiE+Uyt0PjEnayT51kqxL2DJFe vtY6Y+MSKazC5xBJudtB6S3owmCDd4PL OhOtxu8lwuuU/FVLteZwvg==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR RD RA CD NOERROR
+SECTION QUESTION
+diGITrANsiT.fI. IN NS
+SECTION ANSWER
+diGITrANsiT.fI. 3134 IN NS dns1.ficora.fI.
+diGITrANsiT.fI. 3134 IN NS dns2.ficora.fI.
+diGITrANsiT.fI. 3134 IN NS ns-secondary.funet.fI.
+diGITrANsiT.fI. 3134 IN NS ns1.z.fI.
+diGITrANsiT.fI. 3134 IN NS ns2.z.fI.
+; following RRSIG signer is out-of-bailiwick, i.e. nonsense
+diGITrANsiT.fI. 3134 IN RRSIG NS 10 2 3600 20190517083644 20190117083646 28100 droneinfo.fi. XFNrVGseG3exPEFC58o3tgRckNghA9+G Psc8w8lUgJW7NGPuWHM4aSuhgMWL3nxk kCqTYI60RerzNV1PNxFLlfyBzuwi6rqe dOjpud7Nr9giKQc2r2YsOSLrSfcRN4Wq KGllqTVXZAYIbF5+QYA+2x3sY1StATQS mb2qqYPPB6iR/EPuHOn/1DA9gzJKXdQS wWwRWSuzBtO89q/e/zhSlCsWhk96POR7 du1KpJb58wPdNm6+Jznwj7E7KphZaTID mexL5S9Sf6VwDNDHkSOGT9x182tjIXTs kZcpFZgJTDgrR+vwVwjXmvAs/CKQmMax D0ZuRbMjvgvaMkCsBRjtDQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR RD RA CD NOERROR
+SECTION QUESTION
+Api.dIGiTRaNsit.Fi. IN A
+SECTION ANSWER
+Api.dIGiTRaNsit.Fi. 3357 IN CNAME digitransit-prod.trafficmanager.net.
+digitransit-aks.westeurope.cloudapp.azure.com. 9 IN A 40.119.148.209
+digitransit-prod.trafficmanager.net. 299 IN CNAME digitransit-aks.westeurope.cloudapp.azure.com.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR RD RA AD CD NOERROR
+SECTION QUESTION
+nET. IN DS
+SECTION ANSWER
+nET. 56393 IN DS 35886 8 2 7862b27f5f516ebe19680444d4ce5e762981931842c465f00236401d8bd973ee
+nET. 56393 IN RRSIG DS 8 1 86400 20200803200000 20200721190000 46594 . PtZ4PuUSHtwvVksquoCtgL5ylNkYaBJk uXVY0Xx4FOyJ8U5kJwlQzScXS8/W7/4m NMLRJWvDIfEMTwpRtFpgd71THg5w3M+O He4GoQ5dGaaSuREvpYCHY+O6aeO/t3DX P3mTcps+CJlIOJckiRirvv3V1u7jmTGB t4jZ6Gn27CX9lPXGUkhWrDx9EOW1p7ky ZYtFGtkVxGmqnMqoNMSz+JaFmN43uaJU grJt6B8aKFIw3MR1Z4xCX3oYzd5jDdQt sS1h8frflyyN/dF/aIl5BW58sc8qkgGS kv8iUgHW1/E24chcMQFngnOuAAF6hjaA K4SJCdrCXUNiduL8H9Q5MQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR RD RA AD CD NOERROR
+SECTION QUESTION
+nEt. IN DNSKEY
+SECTION ANSWER
+nEt. 21146 IN DNSKEY 256 3 8 AQPeYYme8NvhAl+0XjyGqHVep4Y1T2Or RmO+L3QGULBlOe571PnxI+gRyXCQmtN7 WpoJxzALFSVBPsggqwOP+wnmCx8DZ49N HrfS7WbMtoYHTtiaIvHTjZZ88leuCtNL qfIH8N1Ax68Xnf4uKobYFgZXj0M2Zi7Y I84iFkCpIyZk6VIiJpvpNgyCK5mWetPF 2zmO2jXC8M045JIPam38reXD
+nEt. 21146 IN DNSKEY 257 3 8 AQOYBnzqWXIEj6mlgXg4LWC0HP2n8eK8 XqgHlmJ/69iuIHsa1TrHDG6TcOra/pye GKwH0nKZhTmXSuUFGh9BCNiwVDuyyb6O BGy2Nte9Kr8NwWg4q+zhSoOf4D+gC9dE zg0yFdwT0DKEvmNPt0K4jbQDS4Yimb+u PKuF6yieWWrPYYCrv8C9KC8JMze2uT6N uWBfsl2fDUoV4l65qMww06D7n+p7Rbdw WkAZ0fA63mXVXBZF6kpDtsYD7SUB9jhh fLQE/r85bvg3FaSs5Wi2BaqN06SzGWI1 DHu7axthIOeHwg00zxlhTpoYCH0ldoQz +S65zWYi/fRJiyLSBb6JZOvn
+nEt. 21146 IN RRSIG DNSKEY 8 1 86400 20200728162830 20200713162330 35886 net. BsxHqTUrVNqYdQdv5uriiUd/p+Dh5F12 /01oniA3F1keMZU1V+pbELcih+1gfLs3 i+f88p/9r3kM8gghxQtInzyJl3lPdeBM 7LjWuonQR5CzvfnM4WAgkVZZxmFB7l6b bj+ey9mwocAMR1ht9502MgB4eQLOHVve 3mdCXYuilxwQ9vOrVsFDLiELVoCDVtQi csatJy3Z/LU31IWtR8c6Ta/ItApgqsWg fU8Br3uyHesiDbA2FSfBb9qWFfGcNrDJ ZGF9dLCxvMeHSU5AKpEwX8flOKWKRVwM nB/+LB1owMmcyao82yJlL7y7vxfrQDb0 V0uJaQMEiQl7XGBsT+8Hgg==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR RD RA CD NOERROR
+SECTION QUESTION
+TRAFficManaGer.NEt. IN DS
+SECTION AUTHORITY
+A1RT98BS5QGC9NFI51S9HCI47ULJG6JH.NEt. 21540 IN NSEC3 1 1 0 - a1ruuffjkct2q54p78f8ejgj8jbk7i8b NS SOA RRSIG DNSKEY NSEC3PARAM
+A1RT98BS5QGC9NFI51S9HCI47ULJG6JH.NEt. 21540 IN RRSIG NSEC3 8 2 86400 20200728064417 20200721053417 56519 net. B4N1ZLUcMCAkfgGNrmJfXylkUAbPnqxO 31ZQ5ZwU0AecyChOkGGTelH/87eM7RtG M7mqrM6zU9CnGwsgheqg2HCbpX7n5Fvl 1AclnJZBuFlF0hvejSO99rrLrLRaTWQt LyJwVQJWkMfgztCO5Mh2ngJfK6ZB1PLS xOFqVz0j5MTYYp9QwdL1PvLIaBAw0kTg cm3o476wB0glMo6yzDbK2A==
+CS431SS8CTI7M6JHMN592GRLI9T17OK7.NEt. 21540 IN NSEC3 1 1 0 - cs49egn3atpo6m7fblhased3j00k92nb NS DS RRSIG
+CS431SS8CTI7M6JHMN592GRLI9T17OK7.NEt. 21540 IN RRSIG NSEC3 8 2 86400 20200727063544 20200720052544 56519 net. FB73aPYNlR3FqN1gmxYeIccL+ybiv+8A ymQkJDevhRITdI76YqbobqbvAKQg9Knm lSe5OtWZEmI6h+qbYXtXfnAGl+GayzbL LsSyUABJdWp8ZuGooatayzGqjWUpIGZr qgAZIK+twkCKUicgi2XhCztnVr1wVf2z L0tRuctiZQRdoDlcRfFzXBsg21Kn3eVy ivjnZUzp93vL1ZrBhhZfMg==
+NEt. 840 IN RRSIG SOA 8 1 900 20200729095953 20200722084953 56519 net. GEY1baT1zShB6uxFAyHlg6EPfEbCxp3E 3C2l8OeVCBwgzBdP9TwDeXH+//RcfT9w Q++Wan2q/0W5I9fJRWZKGDPkdmhOcvh9 VjJRlb3DwZdJEeDc3Rj3dip3MvL7OyZt 8lfv42/WoBYHXeduQwGknz0KbNpeSqU0 BjV4C9O/w5rUSjvk3z6Qka7jz3/0sz7H 4FfXqv5CxkUCKYyl9PzxuA==
+NEt. 840 IN SOA a.gtld-servers.NEt. nstld.verisign-grs.com. 1595411993 1800 900 604800 86400
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR RD RA CD NOERROR
+SECTION QUESTION
+TrAfFicMANAger.net. IN NS
+SECTION ANSWER
+TrAfFicMANAger.net. 21041 IN NS tm1.dns-tm.com.
+TrAfFicMANAger.net. 21041 IN NS tm1.edgedns-tm.info.
+TrAfFicMANAger.net. 21041 IN NS tm2.dns-tm.com.
+TrAfFicMANAger.net. 21041 IN NS tm2.edgedns-tm.info.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR RD RA CD NOERROR
+SECTION QUESTION
+Api.dIGiTRaNsit.Fi. IN A
+SECTION ANSWER
+Api.dIGiTRaNsit.Fi. 3585 IN CNAME digitransit-prod.trafficmanager.net.
+digitransit-aks.westeurope.cloudapp.azure.com. 9 IN A 40.119.148.209
+digitransit-prod.trafficmanager.net. 285 IN CNAME digitransit-aks.westeurope.cloudapp.azure.com.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR RD RA CD NOERROR
+SECTION QUESTION
+DigiTranSiT-pROd.tRaffiCmanAgeR.Net. IN A
+SECTION ANSWER
+DigiTranSiT-pROd.tRaffiCmanAgeR.Net. 299 IN CNAME digitransit-aks.westeurope.cloudapp.azure.com.
+digitransit-aks.westeurope.cloudapp.azure.com. 9 IN A 40.119.148.209
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR RD RA CD NOERROR
+SECTION QUESTION
+DigiTranSiT-pROd.tRaffiCmanAgeR.Net. IN A
+SECTION ANSWER
+DigiTranSiT-pROd.tRaffiCmanAgeR.Net. 299 IN CNAME digitransit-aks.westeurope.cloudapp.azure.com.
+digitransit-aks.westeurope.cloudapp.azure.com. 9 IN A 40.119.148.209
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR RD RA AD CD NOERROR
+SECTION QUESTION
+coM. IN DS
+SECTION ANSWER
+coM. 86251 IN DS 30909 8 2 e2d3c916f6deeac73294e8268fb5885044a833fc5459588f4a9184cfc41a5766
+coM. 86251 IN RRSIG DS 8 1 86400 20200803200000 20200721190000 46594 . F3sngBM8xYQ10Z3iIVWUqlMFLvecizXH 2d5kM4iguQL088Cv6xz1Ep3d4wUVEzlL YBBrsCQB627WztctcVPFiXUn22cWwzky 7yxjII8YY72V2x2/758hmZMCSHdSzJph By9Wv5Av5O8qqLt1QyYq8r6cZK7352Vk ICENa/OhKWX3dUvQ+EQe+3JUN5q/Xfeb WnCiuG2LgaWIgl/f+yjpMEkg808EUCCz 41Dbe81gwIadN+vvpjvpb3j5cBfozwqk thyCWlXt2+ZUUH4aSr5q5WsS8nD4gb70 6YC+A08woNmeYms8t40irruVMdlUzrXC Fz7+azz0zCEAc046A9v5fQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR RD RA AD CD NOERROR
+SECTION QUESTION
+coM. IN DNSKEY
+SECTION ANSWER
+coM. 20944 IN DNSKEY 256 3 8 AwEAAdVECVAFFKnwlH7lDYpsSvv50Z7E JP518luWdiN7X5igYJo6dLij/noOhYO0 ppmTghphtSqHn75/qMmETK9NiUfLW4M9 X8j/IvIr1xrTPEb6+dipDE9xKjhMGFUu fOeXHiBoMQiKLNzlssYuz90oQrEwCKpa 5R4cYYFiZaoeezi2NQeIAY82dh/8auvF zqCOewWx/J2zVh8YHqfkGeXyzsM=
+coM. 20944 IN DNSKEY 257 3 8 AQPDzldNmMvZFX4NcNJ0uEnKDg7tmv/F 3MyQR0lpBmVcNcsIszxNFxsBfKNW9JYC Yqpik8366LE7VbIcNRzfp2h9OO8HRl+H +E08zauK8k7evWEmu/6od+2boggPoiEf GNyvNPaSI7FOIroDsnw/taggzHRX1Z7S OiOiPWPNIwSUyWOZ79VmcQ1GLkC6NlYv G3HwYmynQv6oFwGv/KELSw7ZSdrbTQ0H XvZbqMUI7BaMskmvgm1G7oKZ1YiF7O9i oVNc0+7ASbqmZN7Z98EGU/Qh2K/BgUe8 Hs0XVcdPKrtyYnoQHd2ynKPcMMlTEih2 /2HDHjRPJ2aywIpKNnv4oPo/
+coM. 20944 IN RRSIG DNSKEY 8 1 86400 20200729182421 20200714181921 30909 com. kWt6r1qzHb1LABToPGz61aVgRBHMIkS+ x1FbuHxh+Ha9nYtlnl1AOju4CjMC6gje qBXYhhwpZWC4VFSE+hVXuI2NNEPvtcD1 Om9eu69KEK8d1rXmho+PBzJyzXSSUpM6 KtapTL0NDdjg+uCt6YmWNli/e3QdRAoI u5eNnmFBK5viaGcnIP5l8/QdXH+dBmfi qrrs+z0oJv89euCCjH0UeMfVJUetHTox MLiB4GlMyQnPWsNXNZPzQEWk8CeLEhVu e8QVvMQmq+GfcvRF/jFnTsL9ILTMYiJR 8gYp5YnFtBgtrqPoekmAaJ0dig2bXFVV /x8RzR/wFd8yUHTaT+AWkA==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR RD RA CD NOERROR
+SECTION QUESTION
+AZURe.com. IN DS
+SECTION AUTHORITY
+2VPE4QITM4PLV486G56AB7OUDVIO1U3D.com. 21574 IN NSEC3 1 1 0 - 2vpf134m9p90k8k9jmtdjemi4anqnsaf NS DS RRSIG
+2VPE4QITM4PLV486G56AB7OUDVIO1U3D.com. 21574 IN RRSIG NSEC3 8 2 86400 20200726043358 20200719032358 24966 com. SpLKFkZ534rLzf6WTHf+JdBCanfiUhX1 BbmjpFQRI+l1qRN9po9mtA95jfw8AGjw S0n36LK9MBNF4pRo4zcmxny3/K7lfDwf 6HhDlNMp3KQGtLMGcSCqw7StxA3b3qsg 0NhxPtHl818RsBKueIR88LPX88x5jkzC Gr11WJoVlq682pCJlmkVOze2JCmRvjYY m/mUHv4y5+mh3h2AbHc+zA==
+CK0POJMG874LJREF7EFN8430QVIT8BSM.com. 21574 IN NSEC3 1 1 0 - ck0q1gin43n1arrc9osm6qpqr81h5m9a NS SOA RRSIG DNSKEY NSEC3PARAM
+CK0POJMG874LJREF7EFN8430QVIT8BSM.com. 21574 IN RRSIG NSEC3 8 2 86400 20200728044213 20200721033213 24966 com. qoAss2VVxsBWG9+MAQ3giAmCnzf4dz7G ppZsQfkt3b7cFIVgO3TiWPWkusb3BEbp sma2Q+x/TBLeeHYm6l1HWXMIl7zcYLsA XY0ZzoWaqNPTPH6YNDAreZYP21UekBL7 g710cndRk4oaJUNz5t8sGi3JaOJF046Q cUz6gGg7NLMvyGlJWzmftGbxgp9ovdOg wmirddESGOj33kuCfSJvWA==
+com. 874 IN RRSIG SOA 8 1 900 20200729100807 20200722085807 24966 com. kDvHo8x7ut5Lu66MSUOUTPvxfYJLXMcu aKPCu9I+jTYZOzAH4KquPm+765a/gnp5 2okPhEUJTO2JYumhfkjyG04kE4HCnqfR bWtjjfIyqXo34km+CR8rG8RGZ6QilLWZ 0yxux5+izvuji4L4KLeTxPwUJQFgAmVA 59unj2IqysGWRc2ETSofHOPFrydduuyc DJdQLN6Dq1fMFh849Qr6nw==
+com. 874 IN SOA a.gtld-servers.net. nstld.verisign-grs.com. 1595412487 1800 900 604800 86400
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR RD RA CD NOERROR
+SECTION QUESTION
+AZURe.COM. IN NS
+SECTION ANSWER
+AZURe.COM. 21462 IN NS ns1-205.azure-dns.COM.
+AZURe.COM. 21462 IN NS ns2-205.azure-dns.net.
+AZURe.COM. 21462 IN NS ns3-205.azure-dns.org.
+AZURe.COM. 21462 IN NS ns4-205.azure-dns.info.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR RD RA CD NOERROR
+SECTION QUESTION
+DigitRaNsit-aKS.WESTEuROPe.CloUDApp.aZuRe.cOm. IN A
+SECTION ANSWER
+DigitRaNsit-aKS.WESTEuROPe.CloUDApp.aZuRe.cOm. 9 IN A 40.119.148.209
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+api.digitransit.fi. IN A
+SECTION ANSWER
+api.digitransit.fi. 3357 IN CNAME digitransit-prod.trafficmanager.net.
+digitransit-aks.westeurope.cloudapp.azure.com. 9 IN A 40.119.148.209
+digitransit-prod.trafficmanager.net. 299 IN CNAME digitransit-aks.westeurope.cloudapp.azure.com.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR RD RA CD NOERROR
+SECTION QUESTION
+DigitRaNsit-aKS.WESTEuROPe.CloUDApp.aZuRe.cOm. IN A
+SECTION ANSWER
+DigitRaNsit-aKS.WESTEuROPe.CloUDApp.aZuRe.cOm. 9 IN A 40.119.148.209
+ENTRY_END
+
+RANGE_END
+
+
+STEP 10 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+api.digitransit.fi. IN A
+ENTRY_END
+
+STEP 11 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+api.digitransit.fi. IN A
+SECTION ANSWER
+api.digitransit.fi. IN CNAME digitransit-prod.trafficmanager.net.
+digitransit-prod.trafficmanager.net. IN CNAME digitransit-aks.westeurope.cloudapp.azure.com.
+digitransit-aks.westeurope.cloudapp.azure.com. IN A 40.119.148.209
+ENTRY_END
+
+SCENARIO_END
diff --git a/lib/layer/validate.test.integr/kresd_config.j2 b/lib/layer/validate.test.integr/kresd_config.j2
new file mode 100644
index 0000000..cc0dbd5
--- /dev/null
+++ b/lib/layer/validate.test.integr/kresd_config.j2
@@ -0,0 +1,52 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+
+trust_anchors.remove('.')
+{% for TAF in TRUST_ANCHOR_FILES %}
+trust_anchors.add_file('{{TAF}}')
+{% endfor %}
+
+{% raw %}
+-- Disable RFC5011 TA update
+if ta_update then
+ modules.unload('ta_update')
+end
+
+-- Disable RFC8145 signaling, scenario doesn't provide expected answers
+if ta_signal_query then
+ modules.unload('ta_signal_query')
+end
+
+-- Disable RFC8109 priming, scenario doesn't provide expected answers
+if priming then
+ modules.unload('priming')
+end
+
+-- Disable this module because it make one priming query
+if detect_time_skew then
+ modules.unload('detect_time_skew')
+end
+
+cache.size = 2*MB
+log_level('debug')
+policy.add(policy.all(policy.DEBUG_ALWAYS))
+policy.add(policy.all(policy.FORWARD('8.8.8.8')))
+{% endraw %}
+
+net = { '{{SELF_ADDR}}' }
+
+-- Self-checks on globals
+assert(help() ~= nil)
+assert(worker.id ~= nil)
+-- Self-checks on facilities
+assert(cache.count() == 0)
+assert(cache.stats() ~= nil)
+assert(cache.backends() ~= nil)
+assert(worker.stats() ~= nil)
+assert(net.interfaces() ~= nil)
+-- Self-checks on loaded stuff
+assert(net.list()[1].transport.ip == '{{SELF_ADDR}}')
+assert(#modules.list() > 0)
+-- Self-check timers
+ev = event.recurrent(1 * sec, function (ev) return 1 end)
+event.cancel(ev)
+ev = event.after(0, function (ev) return 1 end)
diff --git a/lib/log.c b/lib/log.c
new file mode 100644
index 0000000..1a3d715
--- /dev/null
+++ b/lib/log.c
@@ -0,0 +1,328 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#include "kresconfig.h"
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <gnutls/gnutls.h>
+#include "contrib/ucw/mempool.h"
+#include "lib/log.h"
+#include "lib/resolve.h"
+
+#if ENABLE_LIBSYSTEMD
+#include <stdlib.h>
+#include <systemd/sd-daemon.h>
+#include <systemd/sd-journal.h>
+bool use_journal = false;
+#else
+#define use_journal false
+#endif
+
+kr_log_level_t kr_log_level = LOG_DEFAULT_LEVEL;
+kr_log_target_t kr_log_target = LOG_TARGET_DEFAULT;
+
+/** Set of log-groups that are on debug level. It's a bitmap over 1 << enum kr_log_group. */
+static uint64_t kr_log_groups = 0;
+
+typedef struct {
+ const char *g_name;
+ enum kr_log_group g_val;
+} log_group_names_t;
+
+#define GRP_NAME_ITEM(grp) { grp ## _TAG, grp }
+
+const log_group_names_t log_group_names[] = {
+ GRP_NAME_ITEM(LOG_GRP_SYSTEM),
+ GRP_NAME_ITEM(LOG_GRP_CACHE),
+ GRP_NAME_ITEM(LOG_GRP_IO),
+ GRP_NAME_ITEM(LOG_GRP_NETWORK),
+ GRP_NAME_ITEM(LOG_GRP_TA),
+ GRP_NAME_ITEM(LOG_GRP_TLS),
+ GRP_NAME_ITEM(LOG_GRP_GNUTLS),
+ GRP_NAME_ITEM(LOG_GRP_TLSCLIENT),
+ GRP_NAME_ITEM(LOG_GRP_XDP),
+ GRP_NAME_ITEM(LOG_GRP_DOH),
+ GRP_NAME_ITEM(LOG_GRP_DNSSEC),
+ GRP_NAME_ITEM(LOG_GRP_HINT),
+ GRP_NAME_ITEM(LOG_GRP_PLAN),
+ GRP_NAME_ITEM(LOG_GRP_ITERATOR),
+ GRP_NAME_ITEM(LOG_GRP_VALIDATOR),
+ GRP_NAME_ITEM(LOG_GRP_RESOLVER),
+ GRP_NAME_ITEM(LOG_GRP_SELECTION),
+ GRP_NAME_ITEM(LOG_GRP_ZCUT),
+ GRP_NAME_ITEM(LOG_GRP_COOKIES),
+ GRP_NAME_ITEM(LOG_GRP_STATISTICS),
+ GRP_NAME_ITEM(LOG_GRP_REBIND),
+ GRP_NAME_ITEM(LOG_GRP_WORKER),
+ GRP_NAME_ITEM(LOG_GRP_POLICY),
+ GRP_NAME_ITEM(LOG_GRP_TASENTINEL),
+ GRP_NAME_ITEM(LOG_GRP_TASIGNALING),
+ GRP_NAME_ITEM(LOG_GRP_TAUPDATE),
+ GRP_NAME_ITEM(LOG_GRP_DAF),
+ GRP_NAME_ITEM(LOG_GRP_DETECTTIMEJUMP),
+ GRP_NAME_ITEM(LOG_GRP_DETECTTIMESKEW),
+ GRP_NAME_ITEM(LOG_GRP_GRAPHITE),
+ GRP_NAME_ITEM(LOG_GRP_PREFILL),
+ GRP_NAME_ITEM(LOG_GRP_PRIMING),
+ GRP_NAME_ITEM(LOG_GRP_SRVSTALE),
+ GRP_NAME_ITEM(LOG_GRP_WATCHDOG),
+ GRP_NAME_ITEM(LOG_GRP_NSID),
+ GRP_NAME_ITEM(LOG_GRP_DNSTAP),
+ GRP_NAME_ITEM(LOG_GRP_TESTS),
+ GRP_NAME_ITEM(LOG_GRP_DOTAUTH),
+ GRP_NAME_ITEM(LOG_GRP_HTTP),
+ GRP_NAME_ITEM(LOG_GRP_CONTROL),
+ GRP_NAME_ITEM(LOG_GRP_MODULE),
+ GRP_NAME_ITEM(LOG_GRP_DEVEL),
+ GRP_NAME_ITEM(LOG_GRP_RENUMBER),
+ GRP_NAME_ITEM(LOG_GRP_EDE),
+ GRP_NAME_ITEM(LOG_GRP_REQDBG),
+ { NULL, LOG_GRP_UNKNOWN },
+};
+static_assert(LOG_GRP_REQDBG <= 8 * sizeof(kr_log_groups), "Too many log groups.");
+
+bool kr_log_group_is_set(enum kr_log_group group)
+{
+ if (kr_fails_assert(group >= 0))
+ return false;
+
+ return kr_log_groups & (1ULL << group);
+}
+
+void kr_log_fmt(enum kr_log_group group, kr_log_level_t level, const char *file,
+ const char *line, const char *func, const char *fmt, ...)
+{
+ va_list args;
+
+ if (!(KR_LOG_LEVEL_IS(level) || kr_log_group_is_set(group)))
+ return;
+
+ if (kr_log_target == LOG_TARGET_SYSLOG) {
+ if (kr_log_group_is_set(group))
+ setlogmask(LOG_UPTO(LOG_DEBUG));
+
+ va_start(args, fmt);
+ if (use_journal) {
+ #if ENABLE_LIBSYSTEMD
+ sd_journal_printv_with_location(level, file, line, func, fmt, args);
+ #endif
+ } else {
+ vsyslog(level, fmt, args);
+ }
+ va_end(args);
+
+ if (kr_log_group_is_set(group))
+ setlogmask(LOG_UPTO(kr_log_level));
+ } else {
+ FILE *stream;
+ switch(kr_log_target) {
+ case LOG_TARGET_STDOUT: stream = stdout; break;
+ default: kr_assert(false); // fall through
+ case LOG_TARGET_STDERR: stream = stderr; break;
+ }
+
+ va_start(args, fmt);
+ vfprintf(stream, fmt, args);
+ va_end(args);
+ }
+}
+
+static void kres_gnutls_log(int level, const char *message)
+{
+ kr_log_debug(GNUTLS, "(%d) %s", level, message);
+}
+
+
+struct log_level_name {
+ const char *name;
+ kr_log_level_t level;
+};
+const struct log_level_name level_names[] = {
+ { "alert", LOG_ALERT },
+ { "crit", LOG_CRIT },
+ { "debug", LOG_DEBUG },
+ { "emerg", LOG_EMERG },
+ { "err", LOG_ERR },
+ { "info", LOG_INFO },
+ { "notice", LOG_NOTICE },
+ { "warning", LOG_WARNING },
+ { NULL, -1 },
+};
+
+const char *kr_log_level2name(kr_log_level_t level)
+{
+ for (int i = 0; level_names[i].name; ++i)
+ {
+ if (level_names[i].level == level)
+ return level_names[i].name;
+ }
+
+ return NULL;
+}
+
+kr_log_level_t kr_log_name2level(const char *name)
+{
+ if (kr_fails_assert(name))
+ return LOG_UNKNOWN_LEVEL;
+
+ for (int i = 0; level_names[i].name; ++i)
+ {
+ if (strcmp(level_names[i].name, name) == 0)
+ return level_names[i].level;
+ }
+
+ return LOG_UNKNOWN_LEVEL;
+}
+
+const char *kr_log_grp2name(enum kr_log_group group)
+{
+ for (int i = 0; log_group_names[i].g_name; ++i)
+ {
+ if (log_group_names[i].g_val == group)
+ return log_group_names[i].g_name;
+ }
+
+ return NULL;
+}
+
+enum kr_log_group kr_log_name2grp(const char *name)
+{
+ if (kr_fails_assert(name))
+ return LOG_GRP_UNKNOWN;
+
+ for (int i = 0; log_group_names[i].g_name; ++i)
+ {
+ if (strcmp(log_group_names[i].g_name, name) == 0)
+ return log_group_names[i].g_val;
+ }
+
+ return LOG_GRP_UNKNOWN;
+}
+
+
+
+static void kr_gnutls_log_level_set()
+{
+ /* gnutls logs messages related to our TLS and also libdnssec,
+ * and the logging is set up in a global way only */
+ if (KR_LOG_LEVEL_IS(LOG_DEBUG) || kr_log_group_is_set(LOG_GRP_GNUTLS)) {
+ gnutls_global_set_log_function(kres_gnutls_log);
+ gnutls_global_set_log_level(LOG_GNUTLS_LEVEL);
+ } else {
+ gnutls_global_set_log_level(0);
+ }
+}
+
+void kr_log_level_set(kr_log_level_t level)
+{
+ if (level < LOG_CRIT || level > LOG_DEBUG) {
+ kr_log_warning(SYSTEM, "invalid log level\n");
+ return;
+ }
+
+ kr_log_level = level;
+ setlogmask(LOG_UPTO(kr_log_level));
+
+ kr_gnutls_log_level_set();
+}
+
+void kr_log_group_add(enum kr_log_group group)
+{
+ if (kr_fails_assert(group >= 0))
+ return;
+
+ kr_log_groups |= (1ULL << group);
+ if (group == LOG_GRP_GNUTLS)
+ kr_gnutls_log_level_set();
+}
+
+void kr_log_group_reset()
+{
+ bool had_gnutls = kr_log_group_is_set(LOG_GRP_GNUTLS);
+ kr_log_groups = 0;
+ kr_log_group_add(LOG_GRP_REQDBG);
+ if (had_gnutls)
+ kr_gnutls_log_level_set();
+}
+
+void kr_log_target_set(kr_log_target_t target)
+{
+ kr_log_target = target;
+ if (target != LOG_TARGET_SYSLOG)
+ return;
+
+ int ret = 0;
+#if ENABLE_LIBSYSTEMD
+ ret = sd_booted();
+ use_journal = ret > 0;
+#endif
+ if (!use_journal)
+ openlog(NULL, LOG_PID, LOG_DAEMON);
+ if (ret < 0)
+ kr_log_error(SYSTEM, "failed test for systemd presence: %s\n",
+ strerror(abs(ret)));
+}
+
+static inline bool req_has_trace_log(const struct kr_request *req)
+{
+ return unlikely(req && req->trace_log);
+}
+
+static void kr_vlog_req(
+ const struct kr_request * const req, uint32_t qry_uid,
+ const unsigned int indent, enum kr_log_group group, const char *tag, const char *fmt,
+ va_list args)
+{
+ struct mempool *mp = mp_new(512);
+
+ const uint32_t req_uid = req ? req->uid : 0;
+ char *msg = mp_printf(mp, "[%-6s][%05u.%02u] %*s",
+ tag, req_uid, qry_uid, indent, "");
+
+ msg = mp_vprintf_append(mp, msg, fmt, args);
+
+ if (req_has_trace_log(req))
+ req->trace_log(req, msg);
+
+ kr_log_fmt(group, LOG_DEBUG, SD_JOURNAL_METADATA, "%s", msg);
+
+ mp_delete(mp);
+}
+
+void kr_log_req1(const struct kr_request * const req, uint32_t qry_uid,
+ const unsigned int indent, enum kr_log_group group, const char *tag, const char *fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+ kr_vlog_req(req, qry_uid, indent, group, tag, fmt, args);
+ va_end(args);
+}
+
+bool kr_log_is_debug_fun(enum kr_log_group group, const struct kr_request *req)
+{
+ return req_has_trace_log(req)
+ || kr_log_group_is_set(group)
+ || KR_LOG_LEVEL_IS(LOG_DEBUG);
+}
+
+void kr_log_q1(const struct kr_query * const qry,
+ enum kr_log_group group, const char *tag, const char *fmt, ...)
+{
+ // Optimize: this is probably quite a hot path.
+ const struct kr_request *req = likely(qry != NULL) ? qry->request : NULL;
+ if (likely(!kr_log_is_debug_fun(group, req)))
+ return;
+
+ unsigned ind = 0;
+ for (const struct kr_query *q = qry; q; q = q->parent)
+ ind += 2;
+ const uint32_t qry_uid = qry ? qry->uid : 0;
+
+ va_list args;
+ va_start(args, fmt);
+ kr_vlog_req(req, qry_uid, ind, group, tag, fmt, args);
+ va_end(args);
+}
+
diff --git a/lib/log.h b/lib/log.h
new file mode 100644
index 0000000..1a0237a
--- /dev/null
+++ b/lib/log.h
@@ -0,0 +1,278 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#include <syslog.h>
+#include "lib/defines.h"
+
+#define LOG_UNKNOWN_LEVEL -1 /**< Negative error value. */
+#define LOG_GNUTLS_LEVEL 5 /**< GnuTLS level is 5. */
+
+/* Targets */
+
+typedef enum {
+ LOG_TARGET_SYSLOG = 0,
+ LOG_TARGET_STDERR = 1,
+ LOG_TARGET_STDOUT = 2,
+ /* The default also applies *before* configuration changes it. */
+ LOG_TARGET_DEFAULT = LOG_TARGET_STDERR,
+} kr_log_target_t;
+
+/** Current logging target. Read only, please. */
+KR_EXPORT extern
+kr_log_target_t kr_log_target;
+
+/** Set the current logging target. */
+KR_EXPORT
+void kr_log_target_set(kr_log_target_t target);
+
+
+/* Groups */
+
+/* Don't forget add *_TAG below, log_group_names[] item (log.c) and generate
+ * new kres-gen.lua */
+enum kr_log_group {
+ LOG_GRP_UNKNOWN = -1,
+ LOG_GRP_SYSTEM = 1, /* Must be first in enum. */
+ LOG_GRP_CACHE,
+ LOG_GRP_IO,
+ LOG_GRP_NETWORK,
+ LOG_GRP_TA,
+ LOG_GRP_TLS,
+ LOG_GRP_GNUTLS,
+ LOG_GRP_TLSCLIENT,
+ LOG_GRP_XDP,
+ LOG_GRP_DOH,
+ LOG_GRP_DNSSEC,
+ LOG_GRP_HINT,
+ LOG_GRP_PLAN,
+ LOG_GRP_ITERATOR,
+ LOG_GRP_VALIDATOR,
+ LOG_GRP_RESOLVER,
+ LOG_GRP_SELECTION,
+ LOG_GRP_ZCUT,
+ LOG_GRP_COOKIES,
+ LOG_GRP_STATISTICS,
+ LOG_GRP_REBIND,
+ LOG_GRP_WORKER,
+ LOG_GRP_POLICY,
+ LOG_GRP_TASENTINEL,
+ LOG_GRP_TASIGNALING,
+ LOG_GRP_TAUPDATE,
+ LOG_GRP_DAF,
+ LOG_GRP_DETECTTIMEJUMP,
+ LOG_GRP_DETECTTIMESKEW,
+ LOG_GRP_GRAPHITE,
+ LOG_GRP_PREFILL,
+ LOG_GRP_PRIMING,
+ LOG_GRP_SRVSTALE,
+ LOG_GRP_WATCHDOG,
+ LOG_GRP_NSID,
+ LOG_GRP_DNSTAP,
+ LOG_GRP_TESTS,
+ LOG_GRP_DOTAUTH,
+ LOG_GRP_HTTP,
+ LOG_GRP_CONTROL,
+ LOG_GRP_MODULE,
+ LOG_GRP_DEVEL,
+ LOG_GRP_RENUMBER,
+ LOG_GRP_EDE,
+ /* ^^ Add new log groups above ^^. */
+ LOG_GRP_REQDBG, /* Must be first non-displayed entry in enum! */
+};
+
+/**
+ * @name Group names
+ */
+///@{
+#define LOG_GRP_SYSTEM_TAG "system" /**< ``system``: catch-all log for generic messages*/
+#define LOG_GRP_CACHE_TAG "cache" /**< ``cache``: operations related to cache */
+#define LOG_GRP_IO_TAG "io" /**< ``io``: input/output operations */
+#define LOG_GRP_NETWORK_TAG "net" /**< ``net``: network configuration and operation */
+#define LOG_GRP_TA_TAG "ta" /**< ``ta``: basic log for trust anchors (TA) */
+#define LOG_GRP_TASENTINEL_TAG "tasent" /**< ``tasent``: TA sentinel */
+#define LOG_GRP_TASIGNALING_TAG "tasign" /**< ``tasign``: TA signal query */
+#define LOG_GRP_TAUPDATE_TAG "taupd" /**< ``taupd``: TA update */
+#define LOG_GRP_TLS_TAG "tls" /**< ``tls``: TLS encryption layer */
+#define LOG_GRP_GNUTLS_TAG "gnutls" /**< ``gnutls``: low-level logs from GnuTLS */
+#define LOG_GRP_TLSCLIENT_TAG "tls_cl" /**< ``tls_cl``: TLS client messages (used for TLS forwarding) */
+#define LOG_GRP_XDP_TAG "xdp" /**< ``xdp``: operations related to XDP */
+#define LOG_GRP_DOH_TAG "doh" /**< ``doh``: DNS-over-HTTPS logger (doh2 implementation) */
+#define LOG_GRP_DNSSEC_TAG "dnssec" /**< ``dnssec``: operations related to DNSSEC */
+#define LOG_GRP_HINT_TAG "hint" /**< ``hint``: operations related to static hints */
+#define LOG_GRP_PLAN_TAG "plan" /**< ``plan``: operations related to resolution plan */
+#define LOG_GRP_ITERATOR_TAG "iterat" /**< ``iterat``: operations related to iterate layer */
+#define LOG_GRP_VALIDATOR_TAG "valdtr" /**< ``valdtr``: operations related to validate layer */
+#define LOG_GRP_RESOLVER_TAG "resolv" /**< ``resolv``: operations related to resolving */
+#define LOG_GRP_SELECTION_TAG "select" /**< ``select``: operations related to server selection */
+#define LOG_GRP_ZCUT_TAG "zoncut" /**< ``zonecut``: operations related to zone cut */
+#define LOG_GRP_COOKIES_TAG "cookie" /**< ``cookie``: operations related to cookies */
+#define LOG_GRP_STATISTICS_TAG "statis" /**< ``statis``: operations related to statistics */
+#define LOG_GRP_REBIND_TAG "rebind" /**< ``rebind``: operations related to rebinding */
+#define LOG_GRP_WORKER_TAG "worker" /**< ``worker``: operations related to worker layer */
+#define LOG_GRP_POLICY_TAG "policy" /**< ``policy``: operations related to policy */
+#define LOG_GRP_DAF_TAG "daf" /**< ``daf``: operations related to DAF module */
+#define LOG_GRP_DETECTTIMEJUMP_TAG "timejm" /**< ``timejm``: operations related to time jump */
+#define LOG_GRP_DETECTTIMESKEW_TAG "timesk" /**< ``timesk``: operations related to time skew */
+#define LOG_GRP_GRAPHITE_TAG "graphi" /**< ``graphi``: operations related to graphite */
+#define LOG_GRP_PREFILL_TAG "prefil" /**< ``prefil``: operations related to prefill */
+#define LOG_GRP_PRIMING_TAG "primin" /**< ``primin``: operations related to priming */
+#define LOG_GRP_SRVSTALE_TAG "srvstl" /**< ``srvstl``: operations related to serve stale */
+#define LOG_GRP_WATCHDOG_TAG "wtchdg" /**< ``wtchdg``: operations related to watchdog */
+#define LOG_GRP_NSID_TAG "nsid" /**< ``nsid``: operations related to NSID */
+#define LOG_GRP_DNSTAP_TAG "dnstap" /**< ``dnstap``: operations related to dnstap */
+#define LOG_GRP_TESTS_TAG "tests" /**< ``tests``: operations related to tests */
+#define LOG_GRP_DOTAUTH_TAG "dotaut" /**< ``dotaut``: DNS-over-TLS against authoritative servers */
+#define LOG_GRP_HTTP_TAG "http" /**< ``http``: http module, its web interface and legacy DNS-over-HTTPS */
+#define LOG_GRP_CONTROL_TAG "contrl" /**< ``contrl``: TTY control sockets*/
+#define LOG_GRP_MODULE_TAG "module" /**< ``module``: suitable for user-defined modules */
+#define LOG_GRP_DEVEL_TAG "devel" /**< ``devel``: for development purposes */
+#define LOG_GRP_RENUMBER_TAG "renum" /**< ``renum``: operation related to renumber */
+#define LOG_GRP_EDE_TAG "exterr" /**< ``exterr``: extended error module */
+#define LOG_GRP_REQDBG_TAG "reqdbg" /**< ``reqdbg``: debug logs enabled by policy actions */
+///@}
+
+KR_EXPORT
+bool kr_log_group_is_set(enum kr_log_group group);
+KR_EXPORT
+void kr_log_group_add(enum kr_log_group group);
+KR_EXPORT
+void kr_log_group_reset();
+KR_EXPORT
+const char *kr_log_grp2name(enum kr_log_group group);
+KR_EXPORT
+enum kr_log_group kr_log_name2grp(const char *name);
+
+
+/* Levels */
+
+typedef int kr_log_level_t;
+
+/** Current logging level. Read only, please. */
+KR_EXPORT extern
+kr_log_level_t kr_log_level;
+
+/** Set the current logging level. */
+KR_EXPORT
+void kr_log_level_set(kr_log_level_t level);
+
+KR_EXPORT
+const char *kr_log_level2name(kr_log_level_t level);
+
+/** Return negative on error. */
+KR_EXPORT
+kr_log_level_t kr_log_name2level(const char *name);
+
+#define KR_LOG_LEVEL_IS(exp) ((kr_log_level >= (exp)) ? true : false)
+
+/**
+ * @name Logging levels
+ *
+ * We stick very close to POSIX syslog.h
+ */
+/// @{
+
+/** Debugging message. Can be very verbose.
+ * The level is most often used through VERBOSE_MSG. */
+#define kr_log_debug(grp, fmt, ...) \
+ kr_log_fmt(LOG_GRP_ ## grp, LOG_DEBUG, SD_JOURNAL_METADATA, \
+ "[%-6s] " fmt, LOG_GRP_ ## grp ## _TAG, ## __VA_ARGS__)
+
+#define kr_log_info(grp, fmt, ...) \
+ kr_log_fmt(LOG_GRP_ ## grp, LOG_INFO, SD_JOURNAL_METADATA, \
+ "[%-6s] " fmt, LOG_GRP_ ## grp ## _TAG, ## __VA_ARGS__)
+
+#define kr_log_notice(grp, fmt, ...) \
+ kr_log_fmt(LOG_GRP_ ## grp, LOG_NOTICE, SD_JOURNAL_METADATA, \
+ "[%-6s] " fmt, LOG_GRP_ ## grp ## _TAG, ## __VA_ARGS__)
+
+/** Levels less severe than ``notice`` are not logged by default. */
+#define LOG_DEFAULT_LEVEL LOG_NOTICE
+
+#define kr_log_warning(grp, fmt, ...) \
+ kr_log_fmt(LOG_GRP_ ## grp, LOG_WARNING, SD_JOURNAL_METADATA, \
+ "[%-6s] " fmt, LOG_GRP_ ## grp ## _TAG, ## __VA_ARGS__)
+
+/** Significant error. The process continues, except for configuration errors during startup. */
+#define kr_log_error(grp, fmt, ...) \
+ kr_log_fmt(LOG_GRP_ ## grp, LOG_ERR, SD_JOURNAL_METADATA, \
+ "[%-6s] " fmt, LOG_GRP_ ## grp ## _TAG, ## __VA_ARGS__)
+
+/** Critical condition. The process dies. Bad configuration should not cause this. */
+#define kr_log_crit(grp, fmt, ...) \
+ kr_log_fmt(LOG_GRP_ ## grp, LOG_CRIT, SD_JOURNAL_METADATA, \
+ "[%-6s] " fmt, LOG_GRP_ ## grp ## _TAG, ## __VA_ARGS__)
+
+#define kr_log_deprecate(grp, fmt, ...) \
+ kr_log_fmt(LOG_GRP_ ## grp, LOG_WARNING, SD_JOURNAL_METADATA, \
+ "[%-6s] deprecation WARNING: " fmt, LOG_GRP_ ## grp ## _TAG, ## __VA_ARGS__)
+
+/**
+ * Logging function for user modules. Uses group LOG_GRP_MODULE and ``info`` level.
+ * @param fmt Format string
+ */
+#define kr_log(fmt, ...) \
+ kr_log_fmt(LOG_GRP_MODULE, LOG_INFO, SD_JOURNAL_METADATA, \
+ "[%-6s] " fmt, LOG_GRP_MODULE_TAG, ## __VA_ARGS__)
+
+/// @}
+
+struct kr_request;
+struct kr_query;
+
+/**
+ * Log a debug-level message from a kr_request. Typically we call kr_log_q() instead.
+ *
+ * @param qry_uid query ID to append to request ID, 0 means "no query"
+ * @param indent level of indentation between [group ][req.qry] and message
+ * @param grp GROUP_NAME (without the LOG_GRP_ prefix)
+ * @param fmt printf-like format string
+ */
+#define kr_log_req(req, qry_id, indent, grp, fmt, ...) \
+ kr_log_req1(req, qry_id, indent, LOG_GRP_ ## grp, LOG_GRP_ ## grp ## _TAG, fmt, ## __VA_ARGS__)
+KR_EXPORT KR_PRINTF(6)
+void kr_log_req1(const struct kr_request * const req, uint32_t qry_uid,
+ const unsigned int indent, enum kr_log_group group, const char *tag, const char *fmt, ...);
+
+/**
+ * Log a debug-level message from a kr_query.
+ *
+ * @param qry current query
+ * @param grp GROUP_NAME (without the LOG_GRP_ prefix)
+ * @param fmt printf-like format string
+ */
+#define kr_log_q(qry, grp, fmt, ...) kr_log_q1(qry, LOG_GRP_ ## grp, LOG_GRP_ ## grp ## _TAG, fmt, ## __VA_ARGS__)
+KR_EXPORT KR_PRINTF(4)
+void kr_log_q1(const struct kr_query *qry, enum kr_log_group group, const char *tag, const char *fmt, ...);
+
+/**
+ * Return whether a particular log group in a request is in debug/verbose mode.
+ *
+ * Typically you use this as condition to compute some data to be logged,
+ * in case that's considered too expensive to do unless it really gets logged.
+ *
+ * The request can be NULL, and there's a _qry() shorthand to specify query instead.
+ */
+#define kr_log_is_debug(grp, req) \
+ __builtin_expect(kr_log_is_debug_fun(LOG_GRP_ ## grp, (req)), false)
+#define kr_log_is_debug_qry(grp, qry) kr_log_is_debug(grp, (qry) ? (qry)->request : NULL)
+KR_EXPORT
+bool kr_log_is_debug_fun(enum kr_log_group group, const struct kr_request *req);
+
+
+/* Helpers "internal" to log.* */
+
+/** @internal
+ *
+ * If you don't have location, pass ("CODE_FILE=", "CODE_LINE=", "CODE_FUNC=")
+ * Others than systemd don't utilize these metadata.
+ */
+KR_EXPORT KR_PRINTF(6)
+void kr_log_fmt(enum kr_log_group group, kr_log_level_t level, const char *file, const char *line,
+ const char *func, const char *fmt, ...);
+
+#define KR_LOG_SJM_STR(x) #x
+#define SD_JOURNAL_METADATA "CODE_FILE=" __FILE__, "CODE_LINE=" KR_LOG_SJM_STR(__LINE__), ""
+
diff --git a/lib/meson.build b/lib/meson.build
new file mode 100644
index 0000000..ec11da9
--- /dev/null
+++ b/lib/meson.build
@@ -0,0 +1,121 @@
+# libkres
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+libkres_src = files([
+ 'cache/api.c',
+ 'cache/cdb_lmdb.c',
+ 'cache/entry_list.c',
+ 'cache/entry_pkt.c',
+ 'cache/entry_rr.c',
+ 'cache/knot_pkt.c',
+ 'cache/nsec1.c',
+ 'cache/nsec3.c',
+ 'cache/peek.c',
+ 'dnssec.c',
+ 'dnssec/nsec.c',
+ 'dnssec/nsec3.c',
+ 'dnssec/signature.c',
+ 'dnssec/ta.c',
+ 'generic/lru.c',
+ 'generic/queue.c',
+ 'generic/trie.c',
+ 'layer/cache.c',
+ 'layer/iterate.c',
+ 'layer/validate.c',
+ 'log.c',
+ 'module.c',
+ 'resolve.c',
+ 'rplan.c',
+ 'selection.c',
+ 'selection_forward.c',
+ 'selection_iter.c',
+ 'utils.c',
+ 'zonecut.c',
+])
+c_src_lint += libkres_src
+
+libkres_headers = files([
+ 'cache/api.h',
+ 'cache/cdb_api.h',
+ 'cache/cdb_lmdb.h',
+ 'cache/impl.h',
+ 'defines.h',
+ 'dnssec.h',
+ 'dnssec/nsec.h',
+ 'dnssec/nsec3.h',
+ 'dnssec/signature.h',
+ 'dnssec/ta.h',
+ 'generic/array.h',
+ 'generic/lru.h',
+ 'generic/pack.h',
+ 'generic/queue.h',
+ 'generic/trie.h',
+ 'layer.h',
+ 'layer/iterate.h',
+ 'log.h',
+ 'module.h',
+ 'resolve.h',
+ 'rplan.h',
+ 'selection.h',
+ 'selection_forward.h',
+ 'selection_iter.h',
+ 'utils.h',
+ 'zonecut.h',
+])
+
+unit_tests += [
+ ['array', files('generic/test_array.c')],
+ ['lru', files('generic/test_lru.c')],
+ ['pack', files('generic/test_pack.c')],
+ ['queue', files('generic/test_queue.c')],
+ ['trie', files('generic/test_trie.c')],
+ ['module', files('test_module.c')],
+ ['rplan', files('test_rplan.c')],
+ ['utils', files('test_utils.c')],
+ ['zonecut', files('test_zonecut.c')],
+]
+
+integr_tests += [
+ ['cache_overflow', meson.current_source_dir() / 'cache' / 'overflow.test.integr'],
+ ['cache_minimal_nsec', meson.current_source_dir() / 'cache' / 'test.integr'],
+ ['iter_limits' , meson.current_source_dir() / 'layer' / 'test.integr'],
+ ['validate' , meson.current_source_dir() / 'layer' / 'validate.test.integr'],
+]
+
+libkres_inc = include_directories('..')
+
+libkres_lib = library('kres',
+ libkres_src,
+ soversion: libkres_soversion,
+ include_directories: libkres_inc,
+ dependencies: [
+ contrib_dep,
+ kresconfig_dep,
+ libuv,
+ lmdb,
+ libknot,
+ libdnssec,
+ gnutls,
+ luajit,
+ libsystemd,
+ ],
+ install: true,
+)
+
+libkres_dep = declare_dependency(
+ include_directories: libkres_inc,
+ link_with: libkres_lib
+)
+
+install_headers(
+ libkres_headers,
+ subdir: 'libkres',
+)
+
+pkgconfig = import('pkgconfig')
+pkgconfig.generate(
+ name: 'libkres',
+ description: 'Knot Resolver library',
+ url: 'https://knot-resolver.cz/',
+ libraries: [libkres_lib],
+)
diff --git a/lib/module.c b/lib/module.c
new file mode 100644
index 0000000..83ae773
--- /dev/null
+++ b/lib/module.c
@@ -0,0 +1,148 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#include <stdlib.h>
+#include <dlfcn.h>
+#include <contrib/cleanup.h>
+
+#include "kresconfig.h"
+#include "lib/defines.h"
+#include "lib/utils.h"
+#include "lib/module.h"
+
+
+/* List of embedded modules. These aren't (un)loaded. */
+int iterate_init(struct kr_module *self);
+int validate_init(struct kr_module *self);
+int cache_init(struct kr_module *self);
+kr_module_init_cb kr_module_get_embedded(const char *name)
+{
+ if (strcmp(name, "iterate") == 0)
+ return iterate_init;
+ if (strcmp(name, "validate") == 0)
+ return validate_init;
+ if (strcmp(name, "cache") == 0)
+ return cache_init;
+ return NULL;
+}
+
+/** Load prefixed symbol. */
+static void *load_symbol(void *lib, const char *prefix, const char *name)
+{
+ auto_free char *symbol = kr_strcatdup(2, prefix, name);
+ return dlsym(lib, symbol);
+}
+
+static int load_library(struct kr_module *module, const char *name, const char *path)
+{
+ if (kr_fails_assert(module && name && path))
+ return kr_error(EINVAL);
+ /* Absolute or relative path (then only library search path is used). */
+ auto_free char *lib_path = kr_strcatdup(4, path, "/", name, LIBEXT);
+ if (lib_path == NULL) {
+ return kr_error(ENOMEM);
+ }
+
+ /* Workaround for buggy _fini/__attribute__((destructor)) and dlclose(),
+ * this keeps the library mapped until the program finishes though. */
+ module->lib = dlopen(lib_path, RTLD_NOW | RTLD_NODELETE);
+ if (module->lib) {
+ return kr_ok();
+ }
+
+ return kr_error(ENOENT);
+}
+
+/** Load C module symbols. */
+static int load_sym_c(struct kr_module *module, uint32_t api_required)
+{
+ module->init = kr_module_get_embedded(module->name);
+ if (module->init) {
+ return kr_ok();
+ }
+ #pragma GCC diagnostic push
+ #pragma GCC diagnostic ignored "-Wpedantic" /* casts after load_symbol() */
+ /* Check if it's embedded first */
+ /* Load dynamic library module */
+ auto_free char *m_prefix = kr_strcatdup(2, module->name, "_");
+
+ /* Check ABI version, return error on mismatch. */
+ module_api_cb *api = load_symbol(module->lib, m_prefix, "api");
+ if (api == NULL) {
+ return kr_error(ENOENT);
+ }
+ if (api() != api_required) {
+ return kr_error(ENOTSUP);
+ }
+
+ /* Load ABI by symbol names. */
+ #define ML(symname) module->symname = \
+ load_symbol(module->lib, m_prefix, #symname)
+ ML(init);
+ ML(deinit);
+ ML(config);
+ #undef ML
+ if (load_symbol(module->lib, m_prefix, "layer")
+ || load_symbol(module->lib, m_prefix, "props")) {
+ /* In case someone re-compiled against new kresd
+ * but haven't actually changed the symbols. */
+ kr_log_error(SYSTEM, "module %s requires upgrade. Please refer to "
+ "https://knot-resolver.readthedocs.io/en/stable/upgrading.html",
+ module->name);
+ return kr_error(ENOTSUP);
+ }
+
+ return kr_ok();
+ #pragma GCC diagnostic pop
+}
+
+int kr_module_load(struct kr_module *module, const char *name, const char *path)
+{
+ if (module == NULL || name == NULL) {
+ return kr_error(EINVAL);
+ }
+
+ /* Initialize, keep userdata */
+ void *data = module->data;
+ memset(module, 0, sizeof(struct kr_module));
+ module->data = data;
+ module->name = strdup(name);
+ if (module->name == NULL) {
+ return kr_error(ENOMEM);
+ }
+
+ /* Search for module library. */
+ if (!path || load_library(module, name, path) != 0) {
+ module->lib = RTLD_DEFAULT;
+ }
+
+ /* Try to load module ABI. */
+ int ret = load_sym_c(module, KR_MODULE_API);
+ if (ret == 0 && module->init) {
+ ret = module->init(module);
+ }
+ if (ret != 0) {
+ kr_module_unload(module);
+ }
+
+ return ret;
+}
+
+void kr_module_unload(struct kr_module *module)
+{
+ if (module == NULL) {
+ return;
+ }
+
+ if (module->deinit) {
+ module->deinit(module);
+ }
+
+ if (module->lib && module->lib != RTLD_DEFAULT) {
+ dlclose(module->lib);
+ }
+
+ free(module->name);
+ memset(module, 0, sizeof(struct kr_module));
+}
diff --git a/lib/module.h b/lib/module.h
new file mode 100644
index 0000000..7548803
--- /dev/null
+++ b/lib/module.h
@@ -0,0 +1,112 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+/** @file
+ * Module API definition and functions for (un)loading modules.
+ */
+
+#pragma once
+
+#include "lib/defines.h"
+#include "lib/utils.h"
+#include "lib/layer.h"
+
+struct kr_module;
+struct kr_prop;
+
+
+/**
+ * Export module API version (place this at the end of your module).
+ *
+ * @param module module name (e.g. policy)
+ */
+#define KR_MODULE_EXPORT(module) \
+ KR_EXPORT uint32_t module ## _api() { return KR_MODULE_API; }
+#define KR_MODULE_API ((uint32_t) 0x20210125)
+
+typedef uint32_t (module_api_cb)(void);
+
+
+/**
+ * Module representation.
+ *
+ * The five symbols (init, ...) may be defined by the module as name_init(), etc;
+ * all are optional and missing symbols are represented as NULLs;
+ */
+struct kr_module {
+ char *name;
+
+ /** Constructor. Called after loading the module. @return error code.
+ * Lua modules: not populated, called via lua directly. */
+ int (*init)(struct kr_module *self);
+
+ /** Destructor. Called before unloading the module. @return error code. */
+ int (*deinit)(struct kr_module *self);
+
+ /** Configure with encoded JSON (NULL if missing). @return error code.
+ * Lua modules: not used and not useful from C.
+ * When called from lua, input is JSON, like for kr_prop_cb. */
+ int (*config)(struct kr_module *self, const char *input);
+
+ /** Packet processing API specs. May be NULL. See docs on that type.
+ * Owned by the module code. */
+ const kr_layer_api_t *layer;
+
+ /** List of properties. May be NULL. Terminated by { NULL, NULL, NULL }.
+ * Lua modules: not used and not useful. */
+ const struct kr_prop *props;
+
+ /** dlopen() handle; RTLD_DEFAULT for embedded modules; NULL for lua modules. */
+ void *lib;
+ void *data; /**< Custom data context. */
+};
+
+/**
+ * Module property callback. Input and output is passed via a JSON encoded in a string.
+ *
+ * @param env pointer to the lua engine, i.e. struct engine *env (TODO: explicit type)
+ * @param input parameter (NULL if missing/nil on lua level)
+ * @return a free-form JSON output (malloc-ated)
+ * @note see modules_create_table_for_c() implementation for details
+ * about the input/output conversion.
+ */
+typedef char *(kr_prop_cb)(void *env, struct kr_module *self, const char *input);
+
+/**
+ * Module property (named callable).
+ */
+struct kr_prop {
+ kr_prop_cb *cb;
+ const char *name;
+ const char *info;
+};
+
+
+/**
+ * Load a C module instance into memory. And call its init().
+ *
+ * @param module module structure. Will be overwritten except for ->data on success.
+ * @param name module name
+ * @param path module search path
+ * @return 0 or an error
+ */
+KR_EXPORT
+int kr_module_load(struct kr_module *module, const char *name, const char *path);
+
+/**
+ * Unload module instance.
+ *
+ * @param module module structure
+ * @note currently used even for lua modules
+ */
+KR_EXPORT
+void kr_module_unload(struct kr_module *module);
+
+typedef int (*kr_module_init_cb)(struct kr_module *);
+/**
+ * Get embedded module's init function by name (or NULL).
+ */
+KR_EXPORT
+kr_module_init_cb kr_module_get_embedded(const char *name);
+
diff --git a/lib/resolve.c b/lib/resolve.c
new file mode 100644
index 0000000..aa3d521
--- /dev/null
+++ b/lib/resolve.c
@@ -0,0 +1,1695 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#include <ctype.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <arpa/inet.h>
+#include <libknot/rrtype/rdname.h>
+#include <libknot/descriptor.h>
+#include <ucw/mempool.h>
+#include <sys/socket.h>
+#include "lib/resolve.h"
+#include "lib/layer.h"
+#include "lib/rplan.h"
+#include "lib/layer/iterate.h"
+#include "lib/dnssec/ta.h"
+#include "lib/dnssec.h"
+#if ENABLE_COOKIES
+#include "lib/cookies/control.h"
+#include "lib/cookies/helper.h"
+#include "lib/cookies/nonce.h"
+#else /* Define compatibility macros */
+#define KNOT_EDNS_OPTION_COOKIE 10
+#endif /* ENABLE_COOKIES */
+
+#define VERBOSE_MSG(qry, ...) kr_log_q((qry), RESOLVER, __VA_ARGS__)
+
+bool kr_rank_check(uint8_t rank)
+{
+ switch (rank & ~KR_RANK_AUTH) {
+ case KR_RANK_INITIAL:
+ case KR_RANK_OMIT:
+ case KR_RANK_TRY:
+ case KR_RANK_INDET:
+ case KR_RANK_BOGUS:
+ case KR_RANK_MISMATCH:
+ case KR_RANK_MISSING:
+ case KR_RANK_INSECURE:
+ case KR_RANK_SECURE:
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool kr_rank_test(uint8_t rank, uint8_t kr_flag)
+{
+ if (kr_fails_assert(kr_rank_check(rank) && kr_rank_check(kr_flag)))
+ return false;
+ if (kr_flag == KR_RANK_AUTH) {
+ return rank & KR_RANK_AUTH;
+ }
+ if (kr_fails_assert(!(kr_flag & KR_RANK_AUTH)))
+ return false;
+ /* The rest are exclusive values - exactly one has to be set. */
+ return (rank & ~KR_RANK_AUTH) == kr_flag;
+}
+
+/** @internal Set @a yielded to all RRs with matching @a qry_uid. */
+static void set_yield(ranked_rr_array_t *array, const uint32_t qry_uid, const bool yielded)
+{
+ for (unsigned i = 0; i < array->len; ++i) {
+ ranked_rr_array_entry_t *entry = array->at[i];
+ if (entry->qry_uid == qry_uid) {
+ entry->yielded = yielded;
+ }
+ }
+}
+
+/**
+ * @internal Defer execution of current query.
+ * The current layer state and input will be pushed to a stack and resumed on next iteration.
+ */
+static int consume_yield(kr_layer_t *ctx, knot_pkt_t *pkt)
+{
+ struct kr_request *req = ctx->req;
+ size_t pkt_size = pkt->size;
+ if (knot_pkt_has_tsig(pkt)) {
+ pkt_size += pkt->tsig_wire.len;
+ }
+ knot_pkt_t *pkt_copy = knot_pkt_new(NULL, pkt_size, &req->pool);
+ struct kr_layer_pickle *pickle = mm_alloc(&req->pool, sizeof(*pickle));
+ if (pickle && pkt_copy && knot_pkt_copy(pkt_copy, pkt) == 0) {
+ struct kr_query *qry = req->current_query;
+ pickle->api = ctx->api;
+ pickle->state = ctx->state;
+ pickle->pkt = pkt_copy;
+ pickle->next = qry->deferred;
+ qry->deferred = pickle;
+ set_yield(&req->answ_selected, qry->uid, true);
+ set_yield(&req->auth_selected, qry->uid, true);
+ return kr_ok();
+ }
+ return kr_error(ENOMEM);
+}
+static int begin_yield(kr_layer_t *ctx) { return kr_ok(); }
+static int reset_yield(kr_layer_t *ctx) { return kr_ok(); }
+static int finish_yield(kr_layer_t *ctx) { return kr_ok(); }
+static int produce_yield(kr_layer_t *ctx, knot_pkt_t *pkt) { return kr_ok(); }
+static int checkout_yield(kr_layer_t *ctx, knot_pkt_t *packet, struct sockaddr *dst, int type) { return kr_ok(); }
+static int answer_finalize_yield(kr_layer_t *ctx) { return kr_ok(); }
+
+/** @internal Macro for iterating module layers. */
+#define RESUME_LAYERS(from, r, qry, func, ...) \
+ (r)->current_query = (qry); \
+ for (size_t i = (from); i < (r)->ctx->modules->len; ++i) { \
+ struct kr_module *mod = (r)->ctx->modules->at[i]; \
+ if (mod->layer) { \
+ struct kr_layer layer = {.state = (r)->state, .api = mod->layer, .req = (r)}; \
+ if (layer.api && layer.api->func) { \
+ (r)->state = layer.api->func(&layer, ##__VA_ARGS__); \
+ /* It's an easy mistake to return error code, for example. */ \
+ /* (though we could allow such an overload later) */ \
+ if (kr_fails_assert(kr_state_consistent((r)->state))) { \
+ (r)->state = KR_STATE_FAIL; \
+ } else \
+ if ((r)->state == KR_STATE_YIELD) { \
+ func ## _yield(&layer, ##__VA_ARGS__); \
+ break; \
+ } \
+ } \
+ } \
+ } /* Invalidate current query. */ \
+ (r)->current_query = NULL
+
+/** @internal Macro for starting module iteration. */
+#define ITERATE_LAYERS(req, qry, func, ...) RESUME_LAYERS(0, req, qry, func, ##__VA_ARGS__)
+
+/** @internal Find layer id matching API. */
+static inline size_t layer_id(struct kr_request *req, const struct kr_layer_api *api) {
+ module_array_t *modules = req->ctx->modules;
+ for (size_t i = 0; i < modules->len; ++i) {
+ if (modules->at[i]->layer == api) {
+ return i;
+ }
+ }
+ return 0; /* Not found, try all. */
+}
+
+/* @internal We don't need to deal with locale here */
+KR_CONST static inline bool isletter(unsigned chr)
+{ return (chr | 0x20 /* tolower */) - 'a' <= 'z' - 'a'; }
+
+/* Randomize QNAME letter case.
+ * This adds 32 bits of randomness at maximum, but that's more than an average domain name length.
+ * https://tools.ietf.org/html/draft-vixie-dnsext-dns0x20-00
+ */
+static void randomized_qname_case(knot_dname_t * restrict qname, uint32_t secret)
+{
+ if (secret == 0)
+ return;
+ if (kr_fails_assert(qname))
+ return;
+ const int len = knot_dname_size(qname) - 2; /* Skip first, last label. First is length, last is always root */
+ for (int i = 0; i < len; ++i) {
+ /* Note: this relies on the fact that correct label lengths
+ * can't pass the isletter() test (by "luck"). */
+ if (isletter(*++qname)) {
+ *qname ^= ((secret >> (i & 31)) & 1) * 0x20;
+ }
+ }
+}
+
+/** This turns of QNAME minimisation if there is a non-terminal between current zone cut, and name target.
+ * It save several minimization steps, as the zone cut is likely final one.
+ */
+static void check_empty_nonterms(struct kr_query *qry, knot_pkt_t *pkt, struct kr_cache *cache, uint32_t timestamp)
+{
+ // FIXME cleanup, etc.
+#if 0
+ if (qry->flags.NO_MINIMIZE) {
+ return;
+ }
+
+ const knot_dname_t *target = qry->sname;
+ const knot_dname_t *cut_name = qry->zone_cut.name;
+ if (!target || !cut_name)
+ return;
+
+ struct kr_cache_entry *entry = NULL;
+ /* @note: The non-terminal must be direct child of zone cut (e.g. label distance <= 2),
+ * otherwise this would risk leaking information to parent if the NODATA TTD > zone cut TTD. */
+ int labels = knot_dname_labels(target, NULL) - knot_dname_labels(cut_name, NULL);
+ while (target[0] && labels > 2) {
+ target = knot_wire_next_label(target, NULL);
+ --labels;
+ }
+ for (int i = 0; i < labels; ++i) {
+ int ret = kr_cache_peek(cache, KR_CACHE_PKT, target, KNOT_RRTYPE_NS, &entry, &timestamp);
+ if (ret == 0) { /* Either NXDOMAIN or NODATA, start here. */
+ /* @todo We could stop resolution here for NXDOMAIN, but we can't because of broken CDNs */
+ qry->flags.NO_MINIMIZE = true;
+ kr_make_query(qry, pkt);
+ break;
+ }
+ kr_assert(target[0]);
+ target = knot_wire_next_label(target, NULL);
+ }
+ kr_cache_commit(cache);
+#endif
+}
+
+static int ns_fetch_cut(struct kr_query *qry, const knot_dname_t *requested_name,
+ struct kr_request *req, knot_pkt_t *pkt)
+{
+ /* It can occur that here parent query already have
+ * provably insecure zonecut which not in the cache yet. */
+ struct kr_qflags pflags;
+ if (qry->parent) {
+ pflags = qry->parent->flags;
+ }
+ const bool is_insecure = qry->parent != NULL
+ && !(pflags.AWAIT_IPV4 || pflags.AWAIT_IPV6)
+ && (pflags.DNSSEC_INSECURE || pflags.DNSSEC_NODS);
+
+ /* Want DNSSEC if it's possible to secure this name
+ * (e.g. is covered by any TA) */
+ if (is_insecure) {
+ /* If parent is insecure we don't want DNSSEC
+ * even if cut name is covered by TA. */
+ qry->flags.DNSSEC_WANT = false;
+ qry->flags.DNSSEC_INSECURE = true;
+ VERBOSE_MSG(qry, "=> going insecure because parent query is insecure\n");
+ } else if (kr_ta_closest(req->ctx, qry->zone_cut.name, KNOT_RRTYPE_NS)) {
+ qry->flags.DNSSEC_WANT = true;
+ } else {
+ qry->flags.DNSSEC_WANT = false;
+ VERBOSE_MSG(qry, "=> going insecure because there's no covering TA\n");
+ }
+
+ struct kr_zonecut cut_found;
+ kr_zonecut_init(&cut_found, requested_name, req->rplan.pool);
+ /* Cut that has been found can differs from cut that has been requested.
+ * So if not already insecure,
+ * try to fetch ta & keys even if initial cut name not covered by TA */
+ bool secure = !is_insecure;
+ int ret = kr_zonecut_find_cached(req->ctx, &cut_found, requested_name,
+ qry, &secure);
+ if (ret == kr_error(ENOENT)) {
+ /* No cached cut found, start from SBELT
+ * and issue priming query. */
+ kr_zonecut_deinit(&cut_found);
+ ret = kr_zonecut_set_sbelt(req->ctx, &qry->zone_cut);
+ if (ret != 0) {
+ return KR_STATE_FAIL;
+ }
+ VERBOSE_MSG(qry, "=> using root hints\n");
+ qry->flags.AWAIT_CUT = false;
+ return KR_STATE_DONE;
+ } else if (ret != kr_ok()) {
+ kr_zonecut_deinit(&cut_found);
+ return KR_STATE_FAIL;
+ }
+
+ /* Find out security status.
+ * Go insecure if the zone cut is provably insecure */
+ if ((qry->flags.DNSSEC_WANT) && !secure) {
+ VERBOSE_MSG(qry, "=> NS is provably without DS, going insecure\n");
+ qry->flags.DNSSEC_WANT = false;
+ qry->flags.DNSSEC_INSECURE = true;
+ }
+ /* Zonecut name can change, check it again
+ * to prevent unnecessary DS & DNSKEY queries */
+ if (!(qry->flags.DNSSEC_INSECURE) &&
+ kr_ta_closest(req->ctx, cut_found.name, KNOT_RRTYPE_NS)) {
+ qry->flags.DNSSEC_WANT = true;
+ } else {
+ qry->flags.DNSSEC_WANT = false;
+ }
+ /* Check if any DNSKEY found for cached cut */
+ if (qry->flags.DNSSEC_WANT && cut_found.key == NULL &&
+ kr_zonecut_is_empty(&cut_found)) {
+ /* Cut found and there are no proofs of zone insecurity.
+ * But no DNSKEY found and no glue fetched.
+ * We have got circular dependency - must fetch A\AAAA
+ * from authoritative, but we have no key to verify it. */
+ kr_zonecut_deinit(&cut_found);
+ if (requested_name[0] != '\0' ) {
+ /* If not root - try next label */
+ return KR_STATE_CONSUME;
+ }
+ /* No cached cut & keys found, start from SBELT */
+ ret = kr_zonecut_set_sbelt(req->ctx, &qry->zone_cut);
+ if (ret != 0) {
+ return KR_STATE_FAIL;
+ }
+ VERBOSE_MSG(qry, "=> using root hints\n");
+ qry->flags.AWAIT_CUT = false;
+ return KR_STATE_DONE;
+ }
+ /* Use the found zone cut. */
+ kr_zonecut_move(&qry->zone_cut, &cut_found);
+ /* Check if there's a non-terminal between target and current cut. */
+ struct kr_cache *cache = &req->ctx->cache;
+ check_empty_nonterms(qry, pkt, cache, qry->timestamp.tv_sec);
+ /* Cut found */
+ return KR_STATE_PRODUCE;
+}
+
+static int edns_put(knot_pkt_t *pkt, bool reclaim)
+{
+ if (!pkt->opt_rr) {
+ return kr_ok();
+ }
+ if (reclaim) {
+ /* Reclaim reserved size. */
+ int ret = knot_pkt_reclaim(pkt, knot_edns_wire_size(pkt->opt_rr));
+ if (ret != 0) {
+ return ret;
+ }
+ }
+ /* Write to packet. */
+ if (kr_fails_assert(pkt->current == KNOT_ADDITIONAL))
+ return kr_error(EINVAL);
+ return knot_pkt_put(pkt, KNOT_COMPR_HINT_NONE, pkt->opt_rr, KNOT_PF_FREE);
+}
+
+/** Removes last EDNS OPT RR written to the packet. */
+static int edns_erase_and_reserve(knot_pkt_t *pkt)
+{
+ /* Nothing to be done. */
+ if (!pkt || !pkt->opt_rr) {
+ return 0;
+ }
+
+ /* Fail if the data are located elsewhere than at the end of packet. */
+ if (pkt->current != KNOT_ADDITIONAL ||
+ pkt->opt_rr != &pkt->rr[pkt->rrset_count - 1]) {
+ return -1;
+ }
+
+ size_t len = knot_rrset_size(pkt->opt_rr);
+ int16_t rr_removed = pkt->opt_rr->rrs.count;
+ /* Decrease rrset counters. */
+ pkt->rrset_count -= 1;
+ pkt->sections[pkt->current].count -= 1;
+ pkt->size -= len;
+ knot_wire_add_arcount(pkt->wire, -rr_removed); /* ADDITIONAL */
+
+ pkt->opt_rr = NULL;
+
+ /* Reserve the freed space. */
+ return knot_pkt_reserve(pkt, len);
+}
+
+static inline size_t edns_padding_option_size(int32_t tls_padding)
+{
+ if (tls_padding == -1)
+ /* FIXME: we do not know how to reserve space for the
+ * default padding policy, since we can't predict what
+ * it will select. So i'm just guessing :/ */
+ return KNOT_EDNS_OPTION_HDRLEN + 512;
+ if (tls_padding >= 2)
+ return KNOT_EDNS_OPTION_HDRLEN + tls_padding;
+
+ return 0;
+}
+
+static int edns_create(knot_pkt_t *pkt, const struct kr_request *req)
+{
+ pkt->opt_rr = knot_rrset_copy(req->ctx->upstream_opt_rr, &pkt->mm);
+ size_t wire_size = knot_edns_wire_size(pkt->opt_rr);
+#if ENABLE_COOKIES
+ if (req->ctx->cookie_ctx.clnt.enabled ||
+ req->ctx->cookie_ctx.srvr.enabled) {
+ wire_size += KR_COOKIE_OPT_MAX_LEN;
+ }
+#endif /* ENABLE_COOKIES */
+ if (req->qsource.flags.tls || req->qsource.comm_flags.tls) {
+ wire_size += edns_padding_option_size(req->ctx->tls_padding);
+ }
+ return knot_pkt_reserve(pkt, wire_size);
+}
+
+/**
+ * @param all_secure optionally &&-combine security of written RRs into its value.
+ * (i.e. if you pass a pointer to false, it will always remain)
+ * @param all_cname optionally output if all written RRs are CNAMEs and RRSIGs of CNAMEs
+ * @return error code, ignoring if forced to truncate the packet.
+ */
+static int write_extra_ranked_records(const ranked_rr_array_t *arr, uint16_t reorder,
+ knot_pkt_t *answer, bool *all_secure, bool *all_cname)
+{
+ const bool has_dnssec = knot_pkt_has_dnssec(answer);
+ bool all_sec = true;
+ bool all_cn = (all_cname != NULL); /* optim.: init as false if not needed */
+ int err = kr_ok();
+
+ for (size_t i = 0; i < arr->len; ++i) {
+ ranked_rr_array_entry_t * entry = arr->at[i];
+ kr_assert(!entry->in_progress);
+ if (!entry->to_wire) {
+ continue;
+ }
+ knot_rrset_t *rr = entry->rr;
+ if (!has_dnssec) {
+ if (rr->type != knot_pkt_qtype(answer) && knot_rrtype_is_dnssec(rr->type)) {
+ continue;
+ }
+ }
+ err = knot_pkt_put_rotate(answer, 0, rr, reorder, 0);
+ if (err != KNOT_EOK) {
+ if (err == KNOT_ESPACE) {
+ err = kr_ok();
+ }
+ break;
+ }
+
+ if (rr->type != KNOT_RRTYPE_RRSIG) {
+ all_sec = all_sec && kr_rank_test(entry->rank, KR_RANK_SECURE);
+ }
+ all_cn = all_cn && kr_rrset_type_maysig(entry->rr) == KNOT_RRTYPE_CNAME;
+ }
+
+ if (all_secure) {
+ *all_secure = *all_secure && all_sec;
+ }
+ if (all_cname) {
+ *all_cname = all_cn;
+ }
+ return err;
+}
+
+static int pkt_padding(knot_pkt_t *packet, int32_t padding)
+{
+ knot_rrset_t *opt_rr = packet->opt_rr;
+ int32_t pad_bytes = -1;
+
+ if (padding == -1) { /* use the default padding policy from libknot */
+ pad_bytes = knot_pkt_default_padding_size(packet, opt_rr);
+ }
+ if (padding >= 2) {
+ int32_t max_pad_bytes = knot_edns_get_payload(opt_rr) - (packet->size + knot_rrset_size(opt_rr));
+ pad_bytes = MIN(knot_edns_alignment_size(packet->size, knot_rrset_size(opt_rr), padding),
+ max_pad_bytes);
+ }
+
+ if (pad_bytes >= 0) {
+ uint8_t zeros[MAX(1, pad_bytes)];
+ memset(zeros, 0, sizeof(zeros));
+ int r = knot_edns_add_option(opt_rr, KNOT_EDNS_OPTION_PADDING,
+ pad_bytes, zeros, &packet->mm);
+ if (r != KNOT_EOK) {
+ knot_rrset_clear(opt_rr, &packet->mm);
+ return kr_error(r);
+ }
+ }
+ return kr_ok();
+}
+
+/** @internal Add an EDNS padding RR into the answer if requested and required. */
+static int answer_padding(struct kr_request *request)
+{
+ if (kr_fails_assert(request && request->answer && request->ctx))
+ return kr_error(EINVAL);
+ if (!request->qsource.flags.tls && !request->qsource.comm_flags.tls) {
+ /* Not meaningful to pad without encryption. */
+ return kr_ok();
+ }
+ return pkt_padding(request->answer, request->ctx->tls_padding);
+}
+
+/* Make a clean SERVFAIL answer. */
+static void answer_fail(struct kr_request *request)
+{
+ /* Note: OPT in SERVFAIL response is still useful for cookies/additional info. */
+ if (kr_log_is_debug(RESOLVER, request)) /* logging optimization */
+ kr_log_req(request, 0, 0, RESOLVER,
+ "request failed, answering with empty SERVFAIL\n");
+ knot_pkt_t *answer = request->answer;
+ knot_rrset_t *opt_rr = answer->opt_rr; /* it gets NULLed below */
+ int ret = kr_pkt_clear_payload(answer);
+ knot_wire_clear_ad(answer->wire);
+ knot_wire_clear_aa(answer->wire);
+ knot_wire_set_rcode(answer->wire, KNOT_RCODE_SERVFAIL);
+ if (ret == 0 && opt_rr) {
+ knot_pkt_begin(answer, KNOT_ADDITIONAL);
+ answer->opt_rr = opt_rr;
+ answer_padding(request); /* Ignore failed padding in SERVFAIL answer. */
+ edns_put(answer, false);
+ }
+}
+
+/* Append EDNS records into the answer. */
+static int answer_append_edns(struct kr_request *request)
+{
+ knot_pkt_t *answer = request->answer;
+ if (!answer->opt_rr)
+ return kr_ok();
+ int ret = answer_padding(request);
+ if (!ret) ret = knot_pkt_begin(answer, KNOT_ADDITIONAL);
+ if (!ret) ret = knot_pkt_put(answer, KNOT_COMPR_HINT_NONE,
+ answer->opt_rr, KNOT_PF_FREE);
+ return ret;
+}
+
+static void answer_finalize(struct kr_request *request)
+{
+ struct kr_rplan *rplan = &request->rplan;
+ knot_pkt_t *answer = request->answer;
+ const uint8_t *q_wire = request->qsource.packet->wire;
+
+ if (answer->rrset_count != 0) {
+ /* Non-standard: we assume the answer had been constructed.
+ * Let's check we don't have a "collision". */
+ const ranked_rr_array_t *selected[] = kr_request_selected(request);
+ for (int psec = KNOT_ANSWER; psec <= KNOT_ADDITIONAL; ++psec) {
+ const ranked_rr_array_t *arr = selected[psec];
+ for (ssize_t i = 0; i < arr->len; ++i) {
+ if (kr_fails_assert(!arr->at[i]->to_wire)) {
+ answer_fail(request);
+ return;
+ }
+ }
+ }
+ /* We only add EDNS, and we even assume AD bit was correct. */
+ if (answer_append_edns(request)) {
+ answer_fail(request);
+ return;
+ }
+ return;
+ }
+
+ struct kr_query *const last =
+ rplan->resolved.len > 0 ? array_tail(rplan->resolved) : NULL;
+ /* TODO ^^^^ this is slightly fragile */
+
+ if (!last) {
+ /* Suspicious: no kr_query got resolved (not even from cache),
+ * so let's (defensively) SERVFAIL the request.
+ * ATM many checks below depend on `last` anyway,
+ * so this helps to avoid surprises. */
+ answer_fail(request);
+ return;
+ }
+ /* TODO: clean this up in !660 or followup, and it isn't foolproof anyway. */
+ if (last->flags.DNSSEC_BOGUS
+ || (rplan->pending.len > 0 && array_tail(rplan->pending)->flags.DNSSEC_BOGUS)) {
+ if (!knot_wire_get_cd(q_wire)) {
+ answer_fail(request);
+ return;
+ }
+ }
+
+ /* AD flag. We can only change `secure` from true to false.
+ * Be conservative. Primary approach: check ranks of all RRs in wire.
+ * Only "negative answers" need special handling. */
+ bool secure = request->state == KR_STATE_DONE /*< suspicious otherwise */
+ && knot_pkt_qtype(answer) != KNOT_RRTYPE_RRSIG;
+ if (last->flags.STUB) {
+ secure = false; /* don't trust forwarding for now */
+ }
+ if (last->flags.DNSSEC_OPTOUT) {
+ VERBOSE_MSG(last, "insecure because of opt-out\n");
+ secure = false; /* the last answer is insecure due to opt-out */
+ }
+
+ /* Write all RRsets meant for the answer. */
+ bool answ_all_cnames = false/*arbitrary*/;
+ if (knot_pkt_begin(answer, KNOT_ANSWER)
+ || write_extra_ranked_records(&request->answ_selected, last->reorder,
+ answer, &secure, &answ_all_cnames)
+ || knot_pkt_begin(answer, KNOT_AUTHORITY)
+ || write_extra_ranked_records(&request->auth_selected, last->reorder,
+ answer, &secure, NULL)
+ || knot_pkt_begin(answer, KNOT_ADDITIONAL)
+ || write_extra_ranked_records(&request->add_selected, last->reorder,
+ answer, NULL/*not relevant to AD*/, NULL)
+ || answer_append_edns(request)
+ )
+ {
+ answer_fail(request);
+ return;
+ }
+
+ /* AD: "negative answers" need more handling. */
+ if (kr_response_classify(answer) != PKT_NOERROR
+ /* Additionally check for CNAME chains that "end in NODATA",
+ * as those would also be PKT_NOERROR. */
+ || (answ_all_cnames && knot_pkt_qtype(answer) != KNOT_RRTYPE_CNAME)) {
+
+ secure = secure && last->flags.DNSSEC_WANT
+ && !last->flags.DNSSEC_BOGUS && !last->flags.DNSSEC_INSECURE;
+ }
+
+ if (secure) {
+ struct kr_query *cname_parent = last->cname_parent;
+ while (cname_parent != NULL) {
+ if (cname_parent->flags.DNSSEC_OPTOUT) {
+ secure = false;
+ break;
+ }
+ cname_parent = cname_parent->cname_parent;
+ }
+ }
+
+ /* No detailed analysis ATM, just _SECURE or not.
+ * LATER: request->rank might better be computed in validator's finish phase. */
+ VERBOSE_MSG(last, "AD: request%s classified as SECURE\n", secure ? "" : " NOT");
+ request->rank = secure ? KR_RANK_SECURE : KR_RANK_INITIAL;
+
+ /* Set AD if secure and AD bit "was requested". */
+ if (secure && !knot_wire_get_cd(q_wire)
+ && (knot_pkt_has_dnssec(answer) || knot_wire_get_ad(q_wire))) {
+ knot_wire_set_ad(answer->wire);
+ }
+}
+
+static int query_finalize(struct kr_request *request, struct kr_query *qry, knot_pkt_t *pkt)
+{
+ knot_pkt_begin(pkt, KNOT_ADDITIONAL);
+ if (qry->flags.NO_EDNS)
+ return kr_ok();
+ /* Remove any EDNS records from any previous iteration. */
+ int ret = edns_erase_and_reserve(pkt);
+ if (ret) return ret;
+ ret = edns_create(pkt, request);
+ if (ret) return ret;
+ if (qry->flags.STUB) {
+ /* Stub resolution */
+ knot_wire_set_rd(pkt->wire);
+ if (knot_wire_get_cd(request->qsource.packet->wire)) {
+ knot_wire_set_cd(pkt->wire);
+ }
+ } else {
+ /* Full resolution (ask for +cd and +do) */
+ knot_edns_set_do(pkt->opt_rr);
+ knot_wire_set_cd(pkt->wire);
+ if (qry->flags.FORWARD) {
+ knot_wire_set_rd(pkt->wire);
+ }
+ }
+ return kr_ok();
+}
+
+int kr_resolve_begin(struct kr_request *request, struct kr_context *ctx)
+{
+ /* Initialize request */
+ request->ctx = ctx;
+ request->answer = NULL;
+ request->options = ctx->options;
+ request->state = KR_STATE_CONSUME;
+ request->current_query = NULL;
+ array_init(request->answ_selected);
+ array_init(request->auth_selected);
+ array_init(request->add_selected);
+ request->answ_validated = false;
+ request->auth_validated = false;
+ request->rank = KR_RANK_INITIAL;
+ request->trace_log = NULL;
+ request->trace_finish = NULL;
+
+ /* Expect first query */
+ kr_rplan_init(&request->rplan, request, &request->pool);
+ return KR_STATE_CONSUME;
+}
+
+static int resolve_query(struct kr_request *request, const knot_pkt_t *packet)
+{
+ struct kr_rplan *rplan = &request->rplan;
+ const knot_dname_t *qname = knot_pkt_qname(packet);
+ uint16_t qclass = knot_pkt_qclass(packet);
+ uint16_t qtype = knot_pkt_qtype(packet);
+ struct kr_query *qry = NULL;
+ struct kr_context *ctx = request->ctx;
+ struct kr_cookie_ctx *cookie_ctx = ctx ? &ctx->cookie_ctx : NULL;
+
+ if (qname != NULL) {
+ qry = kr_rplan_push(rplan, NULL, qname, qclass, qtype);
+ } else if (cookie_ctx && cookie_ctx->srvr.enabled &&
+ knot_wire_get_qdcount(packet->wire) == 0 &&
+ knot_pkt_has_edns(packet) &&
+ knot_pkt_edns_option(packet, KNOT_EDNS_OPTION_COOKIE)) {
+ /* Plan empty query only for cookies. */
+ qry = kr_rplan_push_empty(rplan, NULL);
+ }
+ if (!qry) {
+ return KR_STATE_FAIL;
+ }
+
+ if (qname != NULL) {
+ /* Deferred zone cut lookup for this query. */
+ qry->flags.AWAIT_CUT = true;
+ /* Want DNSSEC if it's possible to secure this name (e.g. is covered by any TA) */
+ if ((knot_wire_get_ad(packet->wire) || knot_pkt_has_dnssec(packet)) &&
+ kr_ta_closest(request->ctx, qry->sname, qtype)) {
+ qry->flags.DNSSEC_WANT = true;
+ }
+ }
+
+ /* Expect answer, pop if satisfied immediately */
+ ITERATE_LAYERS(request, qry, begin);
+ if ((request->state & KR_STATE_DONE) != 0) {
+ kr_rplan_pop(rplan, qry);
+ } else if (qname == NULL) {
+ /* it is an empty query which must be resolved by
+ `begin` layer of cookie module.
+ If query isn't resolved, fail. */
+ request->state = KR_STATE_FAIL;
+ }
+ return request->state;
+}
+
+knot_rrset_t* kr_request_ensure_edns(struct kr_request *request)
+{
+ kr_require(request && request->answer && request->qsource.packet && request->ctx);
+ knot_pkt_t* answer = request->answer;
+ bool want_edns = knot_pkt_has_edns(request->qsource.packet);
+ if (!want_edns) {
+ kr_assert(!answer->opt_rr);
+ return answer->opt_rr;
+ } else if (answer->opt_rr) {
+ return answer->opt_rr;
+ }
+
+ kr_assert(request->ctx->downstream_opt_rr);
+ answer->opt_rr = knot_rrset_copy(request->ctx->downstream_opt_rr, &answer->mm);
+ if (!answer->opt_rr)
+ return NULL;
+ if (knot_pkt_has_dnssec(request->qsource.packet))
+ knot_edns_set_do(answer->opt_rr);
+ return answer->opt_rr;
+}
+
+knot_pkt_t *kr_request_ensure_answer(struct kr_request *request)
+{
+ if (request->options.NO_ANSWER) {
+ kr_assert(request->state & KR_STATE_FAIL);
+ return NULL;
+ }
+ if (request->answer)
+ return request->answer;
+
+ const knot_pkt_t *qs_pkt = request->qsource.packet;
+ if (kr_fails_assert(qs_pkt))
+ goto fail;
+ // Find answer_max: limit on DNS wire length.
+ uint16_t answer_max;
+ const struct kr_request_qsource_flags *qs_flags = &request->qsource.flags;
+ const struct kr_request_qsource_flags *qs_cflags = &request->qsource.comm_flags;
+ if (kr_fails_assert(!(qs_flags->tls || qs_cflags->tls || qs_cflags->http) || qs_flags->tcp))
+ goto fail;
+ if (!request->qsource.addr || qs_flags->tcp || qs_cflags->tcp) {
+ // not on UDP
+ answer_max = KNOT_WIRE_MAX_PKTSIZE;
+ } else if (knot_pkt_has_edns(qs_pkt)) {
+ // UDP with EDNS
+ answer_max = MIN(knot_edns_get_payload(qs_pkt->opt_rr),
+ knot_edns_get_payload(request->ctx->downstream_opt_rr));
+ answer_max = MAX(answer_max, KNOT_WIRE_MIN_PKTSIZE);
+ } else {
+ // UDP without EDNS
+ answer_max = KNOT_WIRE_MIN_PKTSIZE;
+ }
+
+ // Allocate the packet.
+ uint8_t *wire = NULL;
+ if (request->alloc_wire_cb) {
+ wire = request->alloc_wire_cb(request, &answer_max);
+ if (!wire)
+ goto enomem;
+ }
+ knot_pkt_t *answer = request->answer =
+ knot_pkt_new(wire, answer_max, &request->pool);
+ if (!answer || knot_pkt_init_response(answer, qs_pkt) != 0) {
+ kr_assert(!answer); // otherwise we messed something up
+ goto enomem;
+ }
+ if (!wire)
+ wire = answer->wire;
+
+ // Much was done by knot_pkt_init_response()
+ knot_wire_set_ra(wire);
+ knot_wire_set_rcode(wire, KNOT_RCODE_NOERROR);
+ if (knot_wire_get_cd(qs_pkt->wire)) {
+ knot_wire_set_cd(wire);
+ }
+
+ // Prepare EDNS if required.
+ if (knot_pkt_has_edns(qs_pkt) && kr_fails_assert(kr_request_ensure_edns(request)))
+ goto enomem; // answer is on mempool, so "leak" is OK
+
+ return request->answer;
+enomem:
+fail:
+ request->state = KR_STATE_FAIL; // TODO: really combine with another flag?
+ return request->answer = NULL;
+}
+
+int kr_resolve_consume(struct kr_request *request, struct kr_transport **transport, knot_pkt_t *packet)
+{
+ struct kr_rplan *rplan = &request->rplan;
+
+ /* Empty resolution plan, push packet as the new query */
+ if (packet && kr_rplan_empty(rplan)) {
+ return resolve_query(request, packet);
+ }
+
+ /* Different processing for network error */
+ struct kr_query *qry = array_tail(rplan->pending);
+ /* Check overall resolution time */
+ if (kr_now() - qry->creation_time_mono >= KR_RESOLVE_TIME_LIMIT) {
+ kr_query_inform_timeout(request, qry);
+ return KR_STATE_FAIL;
+ }
+ bool tried_tcp = (qry->flags.TCP);
+ if (!packet || packet->size == 0)
+ return KR_STATE_PRODUCE;
+
+ /* Packet cleared, derandomize QNAME. */
+ knot_dname_t *qname_raw = kr_pkt_qname_raw(packet);
+ if (qname_raw && qry->secret != 0) {
+ randomized_qname_case(qname_raw, qry->secret);
+ }
+ request->state = KR_STATE_CONSUME;
+ if (qry->flags.CACHED) {
+ ITERATE_LAYERS(request, qry, consume, packet);
+ } else {
+ /* Fill in source and latency information. */
+ request->upstream.rtt = kr_now() - qry->timestamp_mono;
+ request->upstream.transport = transport ? *transport : NULL;
+ ITERATE_LAYERS(request, qry, consume, packet);
+ /* Clear temporary information */
+ request->upstream.transport = NULL;
+ request->upstream.rtt = 0;
+ }
+
+ if (transport && !qry->flags.CACHED) {
+ if (!(request->state & KR_STATE_FAIL)) {
+ /* Do not complete NS address resolution on soft-fail. */
+ const int rcode = knot_wire_get_rcode(packet->wire);
+ if (rcode != KNOT_RCODE_SERVFAIL && rcode != KNOT_RCODE_REFUSED) {
+ qry->flags.AWAIT_IPV6 = false;
+ qry->flags.AWAIT_IPV4 = false;
+ }
+ }
+ }
+
+ if (request->state & KR_STATE_FAIL) {
+ qry->flags.RESOLVED = false;
+ }
+
+ if (!qry->flags.CACHED) {
+ if (request->state & KR_STATE_FAIL) {
+ if (++request->count_fail_row > KR_CONSUME_FAIL_ROW_LIMIT) {
+ if (kr_log_is_debug(RESOLVER, request)) { /* logging optimization */
+ kr_log_req(request, 0, 2, RESOLVER,
+ "=> too many failures in a row, "
+ "bail out (mitigation for NXNSAttack "
+ "CVE-2020-12667)\n");
+ }
+ if (!qry->flags.NO_NS_FOUND) {
+ qry->flags.NO_NS_FOUND = true;
+ return KR_STATE_PRODUCE;
+ }
+ return KR_STATE_FAIL;
+ }
+ } else {
+ request->count_fail_row = 0;
+ }
+ }
+
+ /* Pop query if resolved. */
+ if (request->state == KR_STATE_YIELD) {
+ return KR_STATE_PRODUCE; /* Requery */
+ } else if (qry->flags.RESOLVED) {
+ kr_rplan_pop(rplan, qry);
+ } else if (!tried_tcp && (qry->flags.TCP)) {
+ return KR_STATE_PRODUCE; /* Requery over TCP */
+ } else { /* Clear query flags for next attempt */
+ qry->flags.CACHED = false;
+ if (!request->options.TCP) {
+ qry->flags.TCP = false;
+ }
+ }
+
+ ITERATE_LAYERS(request, qry, reset);
+
+ /* Do not finish with bogus answer. */
+ if (qry->flags.DNSSEC_BOGUS) {
+ if (qry->flags.FORWARD || qry->flags.STUB) {
+ return KR_STATE_FAIL;
+ }
+ /* Other servers might not have broken DNSSEC. */
+ qry->flags.DNSSEC_BOGUS = false;
+ return KR_STATE_PRODUCE;
+ }
+
+ return kr_rplan_empty(&request->rplan) ? KR_STATE_DONE : KR_STATE_PRODUCE;
+}
+
+/** @internal Spawn subrequest in current zone cut (no minimization or lookup). */
+static struct kr_query *zone_cut_subreq(struct kr_rplan *rplan, struct kr_query *parent,
+ const knot_dname_t *qname, uint16_t qtype)
+{
+ struct kr_query *next = kr_rplan_push(rplan, parent, qname, parent->sclass, qtype);
+ if (!next) {
+ return NULL;
+ }
+ kr_zonecut_set(&next->zone_cut, parent->zone_cut.name);
+ if (kr_zonecut_copy(&next->zone_cut, &parent->zone_cut) != 0 ||
+ kr_zonecut_copy_trust(&next->zone_cut, &parent->zone_cut) != 0) {
+ return NULL;
+ }
+ next->flags.NO_MINIMIZE = true;
+ if (parent->flags.DNSSEC_WANT) {
+ next->flags.DNSSEC_WANT = true;
+ }
+ return next;
+}
+
+static int forward_trust_chain_check(struct kr_request *request, struct kr_query *qry, bool resume)
+{
+ struct kr_rplan *rplan = &request->rplan;
+ trie_t *trust_anchors = request->ctx->trust_anchors;
+ trie_t *negative_anchors = request->ctx->negative_anchors;
+
+ if (qry->parent != NULL &&
+ !(qry->forward_flags.CNAME) &&
+ !(qry->flags.DNS64_MARK) &&
+ knot_dname_in_bailiwick(qry->zone_cut.name, qry->parent->zone_cut.name) >= 0) {
+ return KR_STATE_PRODUCE;
+ }
+
+ if (kr_fails_assert(qry->flags.FORWARD))
+ return KR_STATE_FAIL;
+
+ if (!trust_anchors) {
+ qry->flags.AWAIT_CUT = false;
+ return KR_STATE_PRODUCE;
+ }
+
+ if (qry->flags.DNSSEC_INSECURE) {
+ qry->flags.AWAIT_CUT = false;
+ return KR_STATE_PRODUCE;
+ }
+
+ if (qry->forward_flags.NO_MINIMIZE) {
+ qry->flags.AWAIT_CUT = false;
+ return KR_STATE_PRODUCE;
+ }
+
+ const knot_dname_t *start_name = qry->sname;
+ if ((qry->flags.AWAIT_CUT) && !resume) {
+ qry->flags.AWAIT_CUT = false;
+ const knot_dname_t *longest_ta = kr_ta_closest(request->ctx, qry->sname, qry->stype);
+ if (longest_ta) {
+ start_name = longest_ta;
+ qry->zone_cut.name = knot_dname_copy(start_name, qry->zone_cut.pool);
+ qry->flags.DNSSEC_WANT = true;
+ } else {
+ qry->flags.DNSSEC_WANT = false;
+ return KR_STATE_PRODUCE;
+ }
+ }
+
+ bool has_ta = (qry->zone_cut.trust_anchor != NULL);
+ knot_dname_t *ta_name = (has_ta ? qry->zone_cut.trust_anchor->owner : NULL);
+ bool refetch_ta = (!has_ta || !knot_dname_is_equal(qry->zone_cut.name, ta_name));
+ bool is_dnskey_subreq = kr_rplan_satisfies(qry, ta_name, KNOT_CLASS_IN, KNOT_RRTYPE_DNSKEY);
+ bool refetch_key = has_ta && (!qry->zone_cut.key || !knot_dname_is_equal(ta_name, qry->zone_cut.key->owner));
+ if (refetch_key && !is_dnskey_subreq) {
+ struct kr_query *next = zone_cut_subreq(rplan, qry, ta_name, KNOT_RRTYPE_DNSKEY);
+ if (!next) {
+ return KR_STATE_FAIL;
+ }
+ return KR_STATE_DONE;
+ }
+
+ int name_offset = 1;
+ const knot_dname_t *wanted_name;
+ bool nods, ds_req, ns_req, minimized, ns_exist;
+ do {
+ wanted_name = start_name;
+ ds_req = false;
+ ns_req = false;
+ ns_exist = true;
+
+ int cut_labels = knot_dname_labels(qry->zone_cut.name, NULL);
+ int wanted_name_labels = knot_dname_labels(wanted_name, NULL);
+ while (wanted_name[0] && wanted_name_labels > cut_labels + name_offset) {
+ wanted_name = knot_wire_next_label(wanted_name, NULL);
+ wanted_name_labels -= 1;
+ }
+ minimized = (wanted_name != qry->sname);
+
+ for (int i = 0; i < request->rplan.resolved.len; ++i) {
+ struct kr_query *q = request->rplan.resolved.at[i];
+ if (q->parent == qry &&
+ q->sclass == qry->sclass &&
+ (q->stype == KNOT_RRTYPE_DS || q->stype == KNOT_RRTYPE_NS) &&
+ knot_dname_is_equal(q->sname, wanted_name)) {
+ if (q->stype == KNOT_RRTYPE_DS) {
+ ds_req = true;
+ if (q->flags.CNAME) {
+ ns_exist = false;
+ } else if (!(q->flags.DNSSEC_OPTOUT)) {
+ int ret = kr_dnssec_matches_name_and_type(&request->auth_selected, q->uid,
+ wanted_name, KNOT_RRTYPE_NS);
+ ns_exist = (ret == kr_ok());
+ }
+ } else {
+ if (q->flags.CNAME) {
+ ns_exist = false;
+ }
+ ns_req = true;
+ }
+ }
+ }
+
+ if (ds_req && ns_exist && !ns_req && (minimized || resume)) {
+ struct kr_query *next = zone_cut_subreq(rplan, qry, wanted_name,
+ KNOT_RRTYPE_NS);
+ if (!next) {
+ return KR_STATE_FAIL;
+ }
+ return KR_STATE_DONE;
+ }
+
+ if (qry->parent == NULL && (qry->flags.CNAME) &&
+ ds_req && ns_req) {
+ return KR_STATE_PRODUCE;
+ }
+
+ /* set `nods` */
+ if ((qry->stype == KNOT_RRTYPE_DS) &&
+ knot_dname_is_equal(wanted_name, qry->sname)) {
+ nods = true;
+ } else if (resume && !ds_req) {
+ nods = false;
+ } else if (!minimized && qry->stype != KNOT_RRTYPE_DNSKEY) {
+ nods = true;
+ } else {
+ nods = ds_req;
+ }
+ name_offset += 1;
+ } while (ds_req && (ns_req || !ns_exist) && minimized);
+
+ /* Disable DNSSEC if it enters NTA. */
+ if (kr_ta_get(negative_anchors, wanted_name)){
+ VERBOSE_MSG(qry, ">< negative TA, going insecure\n");
+ qry->flags.DNSSEC_WANT = false;
+ }
+
+ /* Enable DNSSEC if enters a new island of trust. */
+ bool want_secure = (qry->flags.DNSSEC_WANT) &&
+ !knot_wire_get_cd(request->qsource.packet->wire);
+ if (!(qry->flags.DNSSEC_WANT) &&
+ !knot_wire_get_cd(request->qsource.packet->wire) &&
+ kr_ta_get(trust_anchors, wanted_name)) {
+ qry->flags.DNSSEC_WANT = true;
+ want_secure = true;
+ if (kr_log_is_debug_qry(RESOLVER, qry)) {
+ KR_DNAME_GET_STR(qname_str, wanted_name);
+ VERBOSE_MSG(qry, ">< TA: '%s'\n", qname_str);
+ }
+ }
+
+ if (want_secure && !qry->zone_cut.trust_anchor) {
+ knot_rrset_t *ta_rr = kr_ta_get(trust_anchors, wanted_name);
+ if (!ta_rr) {
+ char name[] = "\0";
+ ta_rr = kr_ta_get(trust_anchors, (knot_dname_t*)name);
+ }
+ if (ta_rr) {
+ qry->zone_cut.trust_anchor = knot_rrset_copy(ta_rr, qry->zone_cut.pool);
+ }
+ }
+
+ has_ta = (qry->zone_cut.trust_anchor != NULL);
+ ta_name = (has_ta ? qry->zone_cut.trust_anchor->owner : NULL);
+ refetch_ta = (!has_ta || !knot_dname_is_equal(wanted_name, ta_name));
+ if (!nods && want_secure && refetch_ta) {
+ struct kr_query *next = zone_cut_subreq(rplan, qry, wanted_name,
+ KNOT_RRTYPE_DS);
+ if (!next) {
+ return KR_STATE_FAIL;
+ }
+ return KR_STATE_DONE;
+ }
+
+ /* Try to fetch missing DNSKEY.
+ * Do not fetch if this is a DNSKEY subrequest to avoid circular dependency. */
+ is_dnskey_subreq = kr_rplan_satisfies(qry, ta_name, KNOT_CLASS_IN, KNOT_RRTYPE_DNSKEY);
+ refetch_key = has_ta && (!qry->zone_cut.key || !knot_dname_is_equal(ta_name, qry->zone_cut.key->owner));
+ if (want_secure && refetch_key && !is_dnskey_subreq) {
+ struct kr_query *next = zone_cut_subreq(rplan, qry, ta_name, KNOT_RRTYPE_DNSKEY);
+ if (!next) {
+ return KR_STATE_FAIL;
+ }
+ return KR_STATE_DONE;
+ }
+
+ return KR_STATE_PRODUCE;
+}
+
+/* @todo: Validator refactoring, keep this in driver for now. */
+static int trust_chain_check(struct kr_request *request, struct kr_query *qry)
+{
+ struct kr_rplan *rplan = &request->rplan;
+ trie_t *trust_anchors = request->ctx->trust_anchors;
+ trie_t *negative_anchors = request->ctx->negative_anchors;
+
+ /* Disable DNSSEC if it enters NTA. */
+ if (kr_ta_get(negative_anchors, qry->zone_cut.name)){
+ VERBOSE_MSG(qry, ">< negative TA, going insecure\n");
+ qry->flags.DNSSEC_WANT = false;
+ qry->flags.DNSSEC_INSECURE = true;
+ }
+ if (qry->flags.DNSSEC_NODS) {
+ /* This is the next query iteration with minimized qname.
+ * At previous iteration DS non-existence has been proven */
+ VERBOSE_MSG(qry, "<= DS doesn't exist, going insecure\n");
+ qry->flags.DNSSEC_NODS = false;
+ qry->flags.DNSSEC_WANT = false;
+ qry->flags.DNSSEC_INSECURE = true;
+ }
+ /* Enable DNSSEC if entering a new (or different) island of trust,
+ * and update the TA RRset if required. */
+ const bool has_cd = knot_wire_get_cd(request->qsource.packet->wire);
+ knot_rrset_t *ta_rr = kr_ta_get(trust_anchors, qry->zone_cut.name);
+ if (!has_cd && ta_rr) {
+ qry->flags.DNSSEC_WANT = true;
+ if (qry->zone_cut.trust_anchor == NULL
+ || !knot_dname_is_equal(qry->zone_cut.trust_anchor->owner, qry->zone_cut.name)) {
+ mm_free(qry->zone_cut.pool, qry->zone_cut.trust_anchor);
+ qry->zone_cut.trust_anchor = knot_rrset_copy(ta_rr, qry->zone_cut.pool);
+
+ if (kr_log_is_debug_qry(RESOLVER, qry)) {
+ KR_DNAME_GET_STR(qname_str, ta_rr->owner);
+ VERBOSE_MSG(qry, ">< TA: '%s'\n", qname_str);
+ }
+ }
+ }
+
+ /* Try to fetch missing DS (from above the cut). */
+ const bool has_ta = (qry->zone_cut.trust_anchor != NULL);
+ const knot_dname_t *ta_name = (has_ta ? qry->zone_cut.trust_anchor->owner : NULL);
+ const bool refetch_ta = !has_ta || !knot_dname_is_equal(qry->zone_cut.name, ta_name);
+ const bool want_secure = qry->flags.DNSSEC_WANT && !has_cd;
+ if (want_secure && refetch_ta) {
+ /* @todo we could fetch the information from the parent cut, but we don't remember that now */
+ struct kr_query *next = kr_rplan_push(rplan, qry, qry->zone_cut.name, qry->sclass, KNOT_RRTYPE_DS);
+ if (!next) {
+ return KR_STATE_FAIL;
+ }
+ next->flags.AWAIT_CUT = true;
+ next->flags.DNSSEC_WANT = true;
+ return KR_STATE_DONE;
+ }
+ /* Try to fetch missing DNSKEY (either missing or above current cut).
+ * Do not fetch if this is a DNSKEY subrequest to avoid circular dependency. */
+ const bool is_dnskey_subreq = kr_rplan_satisfies(qry, ta_name, KNOT_CLASS_IN, KNOT_RRTYPE_DNSKEY);
+ const bool refetch_key = has_ta && (!qry->zone_cut.key || !knot_dname_is_equal(ta_name, qry->zone_cut.key->owner));
+ if (want_secure && refetch_key && !is_dnskey_subreq) {
+ struct kr_query *next = zone_cut_subreq(rplan, qry, ta_name, KNOT_RRTYPE_DNSKEY);
+ if (!next) {
+ return KR_STATE_FAIL;
+ }
+ return KR_STATE_DONE;
+ }
+
+ return KR_STATE_PRODUCE;
+}
+
+/** @internal Check current zone cut status and credibility, spawn subrequests if needed. */
+static int zone_cut_check(struct kr_request *request, struct kr_query *qry, knot_pkt_t *packet)
+/* TODO: using cache on this point in this way just isn't nice; remove in time */
+{
+ /* Stub mode, just forward and do not solve cut. */
+ if (qry->flags.STUB) {
+ return KR_STATE_PRODUCE;
+ }
+
+ /* Forwarding to upstream resolver mode.
+ * Since forwarding targets already are in qry->ns -
+ * cut fetching is not needed. */
+ if (qry->flags.FORWARD) {
+ return forward_trust_chain_check(request, qry, false);
+ }
+ if (!(qry->flags.AWAIT_CUT)) {
+ /* The query was resolved from cache.
+ * Spawn DS \ DNSKEY requests if needed and exit */
+ return trust_chain_check(request, qry);
+ }
+
+ /* The query wasn't resolved from cache,
+ * now it's the time to look up closest zone cut from cache. */
+ struct kr_cache *cache = &request->ctx->cache;
+ if (!kr_cache_is_open(cache)) {
+ int ret = kr_zonecut_set_sbelt(request->ctx, &qry->zone_cut);
+ if (ret != 0) {
+ return KR_STATE_FAIL;
+ }
+ VERBOSE_MSG(qry, "=> no cache open, using root hints\n");
+ qry->flags.AWAIT_CUT = false;
+ return KR_STATE_DONE;
+ }
+
+ const knot_dname_t *requested_name = qry->sname;
+ /* If at/subdomain of parent zone cut, start from its encloser.
+ * This is for case when we get to a dead end
+ * (and need glue from parent), or DS refetch. */
+ if (qry->parent) {
+ const knot_dname_t *parent = qry->parent->zone_cut.name;
+ if (parent[0] != '\0'
+ && knot_dname_in_bailiwick(qry->sname, parent) >= 0) {
+ requested_name = knot_wire_next_label(parent, NULL);
+ }
+ } else if ((qry->stype == KNOT_RRTYPE_DS) && (qry->sname[0] != '\0')) {
+ /* If this is explicit DS query, start from encloser too. */
+ requested_name = knot_wire_next_label(requested_name, NULL);
+ }
+
+ int state = KR_STATE_FAIL;
+ do {
+ state = ns_fetch_cut(qry, requested_name, request, packet);
+ if (state == KR_STATE_DONE || (state & KR_STATE_FAIL)) {
+ return state;
+ } else if (state == KR_STATE_CONSUME) {
+ requested_name = knot_wire_next_label(requested_name, NULL);
+ }
+ } while (state == KR_STATE_CONSUME);
+
+ /* Update minimized QNAME if zone cut changed */
+ if (qry->zone_cut.name && qry->zone_cut.name[0] != '\0' && !(qry->flags.NO_MINIMIZE)) {
+ if (kr_make_query(qry, packet) != 0) {
+ return KR_STATE_FAIL;
+ }
+ }
+ qry->flags.AWAIT_CUT = false;
+
+ /* Check trust chain */
+ return trust_chain_check(request, qry);
+}
+
+
+static int ns_resolve_addr(struct kr_query *qry, struct kr_request *param, struct kr_transport *transport, uint16_t next_type)
+{
+ struct kr_rplan *rplan = &param->rplan;
+ struct kr_context *ctx = param->ctx;
+
+
+ /* Start NS queries from root, to avoid certain cases
+ * where a NS drops out of cache and the rest is unavailable,
+ * this would lead to dependency loop in current zone cut.
+ */
+
+ /* Bail out if the query is already pending or dependency loop. */
+ if (!next_type || kr_rplan_satisfies(qry->parent, transport->ns_name, KNOT_CLASS_IN, next_type)) {
+ /* Fall back to SBELT if root server query fails. */
+ if (!next_type && qry->zone_cut.name[0] == '\0') {
+ VERBOSE_MSG(qry, "=> fallback to root hints\n");
+ kr_zonecut_set_sbelt(ctx, &qry->zone_cut);
+ return kr_error(EAGAIN);
+ }
+ /* No IPv4 nor IPv6, flag server as unusable. */
+ VERBOSE_MSG(qry, "=> unresolvable NS address, bailing out\n");
+ kr_zonecut_del_all(&qry->zone_cut, transport->ns_name);
+ return kr_error(EHOSTUNREACH);
+ }
+ /* Push new query to the resolution plan */
+ struct kr_query *next =
+ kr_rplan_push(rplan, qry, transport->ns_name, KNOT_CLASS_IN, next_type);
+ if (!next) {
+ return kr_error(ENOMEM);
+ }
+ next->flags.NONAUTH = true;
+
+ /* At the root level with no NS addresses, add SBELT subrequest. */
+ int ret = 0;
+ if (qry->zone_cut.name[0] == '\0') {
+ ret = kr_zonecut_set_sbelt(ctx, &next->zone_cut);
+ if (ret == 0) { /* Copy TA and key since it's the same cut to avoid lookup. */
+ kr_zonecut_copy_trust(&next->zone_cut, &qry->zone_cut);
+ kr_zonecut_set_sbelt(ctx, &qry->zone_cut); /* Add SBELT to parent in case query fails. */
+ }
+ } else {
+ next->flags.AWAIT_CUT = true;
+ }
+
+ if (ret == 0) {
+ if (next_type == KNOT_RRTYPE_AAAA) {
+ qry->flags.AWAIT_IPV6 = true;
+ } else {
+ qry->flags.AWAIT_IPV4 = true;
+ }
+ }
+
+ return ret;
+}
+
+int kr_resolve_produce(struct kr_request *request, struct kr_transport **transport, knot_pkt_t *packet)
+{
+ struct kr_rplan *rplan = &request->rplan;
+
+ /* No query left for resolution */
+ if (kr_rplan_empty(rplan)) {
+ return KR_STATE_FAIL;
+ }
+
+ struct kr_query *qry = array_tail(rplan->pending);
+
+ /* Initialize server selection */
+ if (!qry->server_selection.initialized) {
+ kr_server_selection_init(qry);
+ }
+
+ /* If we have deferred answers, resume them. */
+ if (qry->deferred != NULL) {
+ /* @todo: Refactoring validator, check trust chain before resuming. */
+ int state = 0;
+ if (((qry->flags.FORWARD) == 0) ||
+ ((qry->stype == KNOT_RRTYPE_DS) && (qry->flags.CNAME))) {
+ state = trust_chain_check(request, qry);
+ } else {
+ state = forward_trust_chain_check(request, qry, true);
+ }
+
+ switch(state) {
+ case KR_STATE_FAIL: return KR_STATE_FAIL;
+ case KR_STATE_DONE: return KR_STATE_PRODUCE;
+ default: break;
+ }
+ VERBOSE_MSG(qry, "=> resuming yielded answer\n");
+ struct kr_layer_pickle *pickle = qry->deferred;
+ request->state = KR_STATE_YIELD;
+ set_yield(&request->answ_selected, qry->uid, false);
+ set_yield(&request->auth_selected, qry->uid, false);
+ RESUME_LAYERS(layer_id(request, pickle->api), request, qry, consume, pickle->pkt);
+ if (request->state != KR_STATE_YIELD) {
+ /* No new deferred answers, take the next */
+ qry->deferred = pickle->next;
+ }
+ } else {
+ /* Caller is interested in always tracking a zone cut, even if the answer is cached
+ * this is normally not required, and incurs another cache lookups for cached answer. */
+ if (qry->flags.ALWAYS_CUT) {
+ if (!(qry->flags.STUB)) {
+ switch(zone_cut_check(request, qry, packet)) {
+ case KR_STATE_FAIL: return KR_STATE_FAIL;
+ case KR_STATE_DONE: return KR_STATE_PRODUCE;
+ default: break;
+ }
+ }
+ }
+ /* Resolve current query and produce dependent or finish */
+ request->state = KR_STATE_PRODUCE;
+ ITERATE_LAYERS(request, qry, produce, packet);
+ if (!(request->state & KR_STATE_FAIL) && knot_wire_get_qr(packet->wire)) {
+ /* Produced an answer from cache, consume it. */
+ qry->secret = 0;
+ request->state = KR_STATE_CONSUME;
+ ITERATE_LAYERS(request, qry, consume, packet);
+ }
+ }
+ switch(request->state) {
+ case KR_STATE_FAIL: return request->state;
+ case KR_STATE_CONSUME: break;
+ case KR_STATE_DONE:
+ default: /* Current query is done */
+ if (qry->flags.RESOLVED && request->state != KR_STATE_YIELD) {
+ kr_rplan_pop(rplan, qry);
+ }
+ ITERATE_LAYERS(request, qry, reset);
+ return kr_rplan_empty(rplan) ? KR_STATE_DONE : KR_STATE_PRODUCE;
+ }
+
+
+ /* This query has RD=0 or is ANY, stop here. */
+ if (qry->stype == KNOT_RRTYPE_ANY ||
+ !knot_wire_get_rd(request->qsource.packet->wire)) {
+ VERBOSE_MSG(qry, "=> qtype is ANY or RD=0, bail out\n");
+ return KR_STATE_FAIL;
+ }
+
+ /* Update zone cut, spawn new subrequests. */
+ if (!(qry->flags.STUB)) {
+ int state = zone_cut_check(request, qry, packet);
+ switch(state) {
+ case KR_STATE_FAIL: return KR_STATE_FAIL;
+ case KR_STATE_DONE: return KR_STATE_PRODUCE;
+ default: break;
+ }
+ }
+
+
+ const struct kr_qflags qflg = qry->flags;
+ const bool retry = qflg.TCP || qflg.BADCOOKIE_AGAIN;
+ if (!qflg.FORWARD && !qflg.STUB && !retry) { /* Keep NS when requerying/stub/badcookie. */
+ /* Root DNSKEY must be fetched from the hints to avoid chicken and egg problem. */
+ if (qry->sname[0] == '\0' && qry->stype == KNOT_RRTYPE_DNSKEY) {
+ kr_zonecut_set_sbelt(request->ctx, &qry->zone_cut);
+ }
+ }
+
+ qry->server_selection.choose_transport(qry, transport);
+
+ if (*transport == NULL) {
+ /* Properly signal to serve_stale module. */
+ if (qry->flags.NO_NS_FOUND) {
+ ITERATE_LAYERS(request, qry, reset);
+ kr_rplan_pop(rplan, qry);
+ return KR_STATE_FAIL;
+ } else {
+ /* FIXME: This is probably quite inefficient:
+ * we go through the whole qr_task_step loop just because of the serve_stale
+ * module which might not even be loaded. */
+ qry->flags.NO_NS_FOUND = true;
+ return KR_STATE_PRODUCE;
+ }
+ }
+
+ if ((*transport)->protocol == KR_TRANSPORT_RESOLVE_A || (*transport)->protocol == KR_TRANSPORT_RESOLVE_AAAA) {
+ uint16_t type = (*transport)->protocol == KR_TRANSPORT_RESOLVE_A ? KNOT_RRTYPE_A : KNOT_RRTYPE_AAAA;
+ ns_resolve_addr(qry, qry->request, *transport, type);
+ ITERATE_LAYERS(request, qry, reset);
+ return KR_STATE_PRODUCE;
+ }
+
+ /* Randomize query case (if not in not turned off) */
+ qry->secret = qry->flags.NO_0X20 ? 0 : kr_rand_bytes(sizeof(qry->secret));
+ knot_dname_t *qname_raw = kr_pkt_qname_raw(packet);
+ randomized_qname_case(qname_raw, qry->secret);
+
+ /*
+ * Additional query is going to be finalized when calling
+ * kr_resolve_checkout().
+ */
+ qry->timestamp_mono = kr_now();
+ return request->state;
+}
+
+#if ENABLE_COOKIES
+/** Update DNS cookie data in packet. */
+static bool outbound_request_update_cookies(struct kr_request *req,
+ const struct sockaddr *src,
+ const struct sockaddr *dst)
+{
+ if (kr_fails_assert(req))
+ return false;
+
+ /* RFC7873 4.1 strongly requires server address. */
+ if (!dst)
+ return false;
+
+ struct kr_cookie_settings *clnt_sett = &req->ctx->cookie_ctx.clnt;
+
+ /* Cookies disabled or packet has no EDNS section. */
+ if (!clnt_sett->enabled)
+ return true;
+
+ /*
+ * RFC7873 4.1 recommends using also the client address. The matter is
+ * also discussed in section 6.
+ */
+
+ kr_request_put_cookie(&clnt_sett->current, req->ctx->cache_cookie,
+ src, dst, req);
+
+ return true;
+}
+#endif /* ENABLE_COOKIES */
+
+int kr_resolve_checkout(struct kr_request *request, const struct sockaddr *src,
+ struct kr_transport *transport, knot_pkt_t *packet)
+{
+ /* @todo: Update documentation if this function becomes approved. */
+
+ struct kr_rplan *rplan = &request->rplan;
+
+ if (knot_wire_get_qr(packet->wire) != 0) {
+ return kr_ok();
+ }
+
+ /* No query left for resolution */
+ if (kr_rplan_empty(rplan)) {
+ return kr_error(EINVAL);
+ }
+ struct kr_query *qry = array_tail(rplan->pending);
+
+#if ENABLE_COOKIES
+ /* Update DNS cookies in request. */
+ if (type == SOCK_DGRAM) { /* @todo: Add cookies also over TCP? */
+ /*
+ * The actual server IP address is needed before generating the
+ * actual cookie. If we don't know the server address then we
+ * also don't know the actual cookie size.
+ */
+ if (!outbound_request_update_cookies(request, src, &transport->address.ip)) {
+ return kr_error(EINVAL);
+ }
+ }
+#endif /* ENABLE_COOKIES */
+
+ int ret = query_finalize(request, qry, packet);
+ if (ret != 0) {
+ return kr_error(EINVAL);
+ }
+
+ /* Track changes in minimization secret to enable/disable minimization */
+ uint32_t old_minimization_secret = qry->secret;
+
+ /* Run the checkout layers and cancel on failure.
+ * The checkout layer doesn't persist the state, so canceled subrequests
+ * don't affect the resolution or rest of the processing. */
+ int type = -1;
+ switch(transport->protocol) {
+ case KR_TRANSPORT_UDP:
+ type = SOCK_DGRAM;
+ break;
+ case KR_TRANSPORT_TCP:
+ case KR_TRANSPORT_TLS:
+ type = SOCK_STREAM;
+ break;
+ default:
+ kr_assert(false);
+ }
+ int state = request->state;
+ ITERATE_LAYERS(request, qry, checkout, packet, &transport->address.ip, type);
+ if (request->state & KR_STATE_FAIL) {
+ request->state = state; /* Restore */
+ return kr_error(ECANCELED);
+ }
+
+ /* Randomize query case (if secret changed) */
+ knot_dname_t *qname_raw = kr_pkt_qname_raw(packet);
+ if (qry->secret != old_minimization_secret) {
+ randomized_qname_case(qname_raw, qry->secret);
+ }
+
+ /* Write down OPT unless in safemode */
+ if (!(qry->flags.NO_EDNS)) {
+ /* TLS padding */
+ if (transport->protocol == KR_TRANSPORT_TLS) {
+ size_t padding_size = edns_padding_option_size(request->ctx->tls_padding);
+ ret = knot_pkt_reserve(packet, padding_size);
+ if (ret)
+ return kr_error(EINVAL);
+ ret = pkt_padding(packet, request->ctx->tls_padding);
+ if (ret)
+ return kr_error(EINVAL);
+ }
+
+ ret = edns_put(packet, true);
+ if (ret != 0) {
+ return kr_error(EINVAL);
+ }
+ }
+
+ if (kr_log_is_debug_qry(RESOLVER, qry)) {
+ KR_DNAME_GET_STR(qname_str, knot_pkt_qname(packet));
+ KR_DNAME_GET_STR(ns_name, transport->ns_name);
+ KR_DNAME_GET_STR(zonecut_str, qry->zone_cut.name);
+ KR_RRTYPE_GET_STR(type_str, knot_pkt_qtype(packet));
+ const char *ns_str = kr_straddr(&transport->address.ip);
+
+ VERBOSE_MSG(qry,
+ "=> id: '%05u' querying: '%s'@'%s' zone cut: '%s' "
+ "qname: '%s' qtype: '%s' proto: '%s'\n",
+ qry->id, ns_name, ns_str ? ns_str : "", zonecut_str,
+ qname_str, type_str, (qry->flags.TCP) ? "tcp" : "udp");
+ }
+
+ return kr_ok();
+}
+
+int kr_resolve_finish(struct kr_request *request, int state)
+{
+ request->state = state;
+ /* Finalize answer and construct whole wire-format (unless dropping). */
+ knot_pkt_t *answer = kr_request_ensure_answer(request);
+ if (answer) {
+ ITERATE_LAYERS(request, NULL, answer_finalize);
+ answer_finalize(request);
+
+ /* Defensive style, in case someone has forgotten.
+ * Beware: non-empty answers do make sense even with SERVFAIL case, etc. */
+ if (request->state != KR_STATE_DONE) {
+ uint8_t *wire = answer->wire;
+ switch (knot_wire_get_rcode(wire)) {
+ case KNOT_RCODE_NOERROR:
+ case KNOT_RCODE_NXDOMAIN:
+ knot_wire_clear_ad(wire);
+ knot_wire_clear_aa(wire);
+ knot_wire_set_rcode(wire, KNOT_RCODE_SERVFAIL);
+ }
+ }
+ }
+
+ ITERATE_LAYERS(request, NULL, finish);
+
+ struct kr_rplan *rplan = &request->rplan;
+ struct kr_query *last = kr_rplan_last(rplan);
+ VERBOSE_MSG(last, "finished in state: %d, queries: %zu, mempool: %zu B\n",
+ request->state, rplan->resolved.len, (size_t) mp_total_size(request->pool.ctx));
+
+ /* Trace request finish */
+ if (request->trace_finish) {
+ request->trace_finish(request);
+ }
+
+ /* Uninstall all tracepoints */
+ request->trace_finish = NULL;
+ request->trace_log = NULL;
+
+ return KR_STATE_DONE;
+}
+
+struct kr_rplan *kr_resolve_plan(struct kr_request *request)
+{
+ if (request) {
+ return &request->rplan;
+ }
+ return NULL;
+}
+
+knot_mm_t *kr_resolve_pool(struct kr_request *request)
+{
+ if (request) {
+ return &request->pool;
+ }
+ return NULL;
+}
+
+static int ede_priority(int info_code)
+{
+ switch(info_code) {
+ case KNOT_EDNS_EDE_DNSKEY_BIT:
+ case KNOT_EDNS_EDE_DNSKEY_MISS:
+ case KNOT_EDNS_EDE_SIG_EXPIRED:
+ case KNOT_EDNS_EDE_SIG_NOTYET:
+ case KNOT_EDNS_EDE_RRSIG_MISS:
+ case KNOT_EDNS_EDE_NSEC_MISS:
+ return 900; /* Specific DNSSEC failures */
+ case KNOT_EDNS_EDE_BOGUS:
+ return 800; /* Generic DNSSEC failure */
+ case KNOT_EDNS_EDE_FORGED:
+ case KNOT_EDNS_EDE_FILTERED:
+ return 700; /* Considered hard fail by firefox */
+ case KNOT_EDNS_EDE_PROHIBITED:
+ case KNOT_EDNS_EDE_BLOCKED:
+ case KNOT_EDNS_EDE_CENSORED:
+ return 600; /* Policy related */
+ case KNOT_EDNS_EDE_DNSKEY_ALG:
+ case KNOT_EDNS_EDE_DS_DIGEST:
+ return 500; /* Non-critical DNSSEC issues */
+ case KNOT_EDNS_EDE_STALE:
+ case KNOT_EDNS_EDE_STALE_NXD:
+ return 300; /* Serve-stale answers. */
+ case KNOT_EDNS_EDE_INDETERMINATE:
+ case KNOT_EDNS_EDE_CACHED_ERR:
+ case KNOT_EDNS_EDE_NOT_READY:
+ case KNOT_EDNS_EDE_NOTAUTH:
+ case KNOT_EDNS_EDE_NOTSUP:
+ case KNOT_EDNS_EDE_NREACH_AUTH:
+ case KNOT_EDNS_EDE_NETWORK:
+ case KNOT_EDNS_EDE_INV_DATA:
+ return 200; /* Assorted codes */
+ case KNOT_EDNS_EDE_OTHER:
+ return 100; /* Most generic catch-all error */
+ case KNOT_EDNS_EDE_NONE:
+ return 0; /* No error - allow overriding */
+ default:
+ kr_assert(false); /* Unknown info_code */
+ return 50;
+ }
+}
+
+int kr_request_set_extended_error(struct kr_request *request, int info_code, const char *extra_text)
+{
+ if (kr_fails_assert(request))
+ return KNOT_EDNS_EDE_NONE;
+
+ struct kr_extended_error *ede = &request->extended_error;
+
+ /* Clear any previously set error. */
+ if (info_code == KNOT_EDNS_EDE_NONE) {
+ kr_assert(extra_text == NULL);
+ ede->info_code = KNOT_EDNS_EDE_NONE;
+ ede->extra_text = NULL;
+ return KNOT_EDNS_EDE_NONE;
+ }
+
+ if (ede_priority(info_code) >= ede_priority(ede->info_code)) {
+ ede->info_code = info_code;
+ ede->extra_text = extra_text;
+ }
+
+ return ede->info_code;
+}
+
+#undef VERBOSE_MSG
diff --git a/lib/resolve.h b/lib/resolve.h
new file mode 100644
index 0000000..97ba07b
--- /dev/null
+++ b/lib/resolve.h
@@ -0,0 +1,420 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <libknot/packet/pkt.h>
+
+#include "lib/cookies/control.h"
+#include "lib/cookies/lru_cache.h"
+#include "lib/layer.h"
+#include "lib/generic/array.h"
+#include "lib/selection.h"
+#include "lib/rplan.h"
+#include "lib/module.h"
+#include "lib/cache/api.h"
+
+/**
+ * @file resolve.h
+ * @brief The API provides an API providing a "consumer-producer"-like interface to enable
+ * user to plug it into existing event loop or I/O code.
+ *
+ * # Example usage of the iterative API:
+ *
+ * @code{.c}
+ *
+ * // Create request and its memory pool
+ * struct kr_request req = {
+ * .pool = {
+ * .ctx = mp_new (4096),
+ * .alloc = (mm_alloc_t) mp_alloc
+ * }
+ * };
+ *
+ * // Setup and provide input query
+ * int state = kr_resolve_begin(&req, ctx);
+ * state = kr_resolve_consume(&req, query);
+ *
+ * // Generate answer
+ * while (state == KR_STATE_PRODUCE) {
+ *
+ * // Additional query generate, do the I/O and pass back answer
+ * state = kr_resolve_produce(&req, &addr, &type, query);
+ * while (state == KR_STATE_CONSUME) {
+ * int ret = sendrecv(addr, proto, query, resp);
+ *
+ * // If I/O fails, make "resp" empty
+ * state = kr_resolve_consume(&request, addr, resp);
+ * knot_pkt_clear(resp);
+ * }
+ * knot_pkt_clear(query);
+ * }
+ *
+ * // "state" is either DONE or FAIL
+ * kr_resolve_finish(&request, state);
+ *
+ * @endcode
+ */
+
+
+struct kr_request;
+/** Allocate buffer for answer's wire (*maxlen may get lowered).
+ *
+ * Motivation: XDP wire allocation is an overlap of library and daemon:
+ * - it needs to be called from the library
+ * - it needs to rely on some daemon's internals
+ * - the library (currently) isn't allowed to directly use symbols from daemon
+ * (contrary to modules), e.g. some of our lib-using tests run without daemon
+ *
+ * Note: after we obtain the wire, we're obliged to send it out.
+ * (So far there's no use case to allow cancelling at that point.)
+ */
+typedef uint8_t * (*alloc_wire_f)(struct kr_request *req, uint16_t *maxlen);
+
+/**
+ * RRset rank - for cache and ranked_rr_*.
+ *
+ * The rank meaning consists of one independent flag - KR_RANK_AUTH,
+ * and the rest have meaning of values where only one can hold at any time.
+ * You can use one of the enums as a safe initial value, optionally | KR_RANK_AUTH;
+ * otherwise it's best to manipulate ranks via the kr_rank_* functions.
+ *
+ * @note The representation is complicated by restrictions on integer comparison:
+ * - AUTH must be > than !AUTH
+ * - AUTH INSECURE must be > than AUTH (because it attempted validation)
+ * - !AUTH SECURE must be > than AUTH (because it's valid)
+ *
+ * See also:
+ * https://tools.ietf.org/html/rfc2181#section-5.4.1
+ * https://tools.ietf.org/html/rfc4035#section-4.3
+ */
+enum kr_rank {
+ /* Initial-like states. No validation has been attempted (yet). */
+ KR_RANK_INITIAL = 0, /**< Did not attempt to validate. It's assumed
+ compulsory to validate (or prove insecure). */
+ KR_RANK_OMIT, /**< Do not attempt to validate.
+ (And don't consider it a validation failure.) */
+ KR_RANK_TRY, /**< Attempt to validate, but failures are non-fatal. */
+
+ /* Failure states. These have higher value because they have more information. */
+ KR_RANK_INDET = 4, /**< Unable to determine whether it should be secure. */
+ KR_RANK_BOGUS, /**< Ought to be secure but isn't. */
+ KR_RANK_MISMATCH,
+ KR_RANK_MISSING, /**< No RRSIG found for that owner+type combination. */
+
+ /** Proven to be insecure, i.e. we have a chain of trust from TAs
+ * that cryptographically denies the possibility of existence
+ * of a positive chain of trust from the TAs to the record.
+ * Or it may be covered by a closer negative TA. */
+ KR_RANK_INSECURE = 8,
+
+ /** Authoritative data flag; the chain of authority was "verified".
+ * Even if not set, only in-bailiwick stuff is acceptable,
+ * i.e. almost authoritative (example: mandatory glue and its NS RR). */
+ KR_RANK_AUTH = 16,
+
+ KR_RANK_SECURE = 32, /**< Verified whole chain of trust from the closest TA. */
+ /* @note Rank must not exceed 6 bits */
+};
+
+/** Check that a rank value is valid. Meant for assertions. */
+bool kr_rank_check(uint8_t rank) KR_PURE;
+
+/** Test the presence of any flag/state in a rank, i.e. including KR_RANK_AUTH. */
+bool kr_rank_test(uint8_t rank, uint8_t kr_flag) KR_PURE KR_EXPORT;
+
+/** Set the rank state. The _AUTH flag is kept as it was. */
+static inline void kr_rank_set(uint8_t *rank, uint8_t kr_flag)
+{
+ if (kr_fails_assert(rank && kr_rank_check(*rank)))
+ return;
+ if (kr_fails_assert(kr_rank_check(kr_flag) && !(kr_flag & KR_RANK_AUTH)))
+ return;
+ *rank = kr_flag | (*rank & KR_RANK_AUTH);
+}
+
+
+/** @cond internal Array of modules. */
+typedef array_t(struct kr_module *) module_array_t;
+/* @endcond */
+
+/**
+ * Name resolution context.
+ *
+ * Resolution context provides basic services like cache, configuration and options.
+ *
+ * @note This structure is persistent between name resolutions and may
+ * be shared between threads.
+ */
+struct kr_context
+{
+ /** Default kr_request flags. For startup defaults see init_resolver() */
+ struct kr_qflags options;
+
+ /** Default EDNS towards *both* clients and upstream.
+ * LATER: consider splitting the two, e.g. allow separately
+ * configured limits for UDP packet size (say, LAN is under control). */
+ knot_rrset_t *downstream_opt_rr;
+ knot_rrset_t *upstream_opt_rr;
+
+ trie_t *trust_anchors;
+ trie_t *negative_anchors;
+ struct kr_zonecut root_hints;
+ struct kr_cache cache;
+ unsigned cache_rtt_tout_retry_interval;
+ module_array_t *modules;
+ /* The cookie context structure should not be held within the cookies
+ * module because of better access. */
+ struct kr_cookie_ctx cookie_ctx;
+ kr_cookie_lru_t *cache_cookie;
+ int32_t tls_padding; /**< See net.tls_padding in ../daemon/README.rst -- -1 is "true" (default policy), 0 is "false" (no padding) */
+ knot_mm_t *pool;
+};
+
+/* Kept outside, because kres-gen.lua can't handle this depth
+ * (and lines here were too long anyway). */
+struct kr_request_qsource_flags {
+ bool tcp:1; /**< true if the request is not on UDP; only meaningful if (dst_addr). */
+ bool tls:1; /**< true if the request is encrypted; only meaningful if (dst_addr). */
+ bool http:1; /**< true if the request is on HTTP; only meaningful if (dst_addr). */
+ bool xdp:1; /**< true if the request is on AF_XDP; only meaningful if (dst_addr). */
+};
+
+/* Extended DNS Errors, RFC 8914 */
+struct kr_extended_error {
+ int32_t info_code; /**< May contain -1 (KNOT_EDNS_EDE_NONE); filter before converting to uint16_t. */
+ const char *extra_text; /**< Can be NULL. Allocated on the kr_request::pool or static. */
+};
+
+
+typedef bool (*addr_info_f)(struct sockaddr*);
+typedef void (*async_resolution_f)(knot_dname_t*, enum knot_rr_type);
+typedef array_t(union kr_sockaddr) kr_sockaddr_array_t;
+
+/**
+ * Name resolution request.
+ *
+ * Keeps information about current query processing between calls to
+ * processing APIs, i.e. current resolved query, resolution plan, ...
+ * Use this instead of the simple interface if you want to implement
+ * multiplexing or custom I/O.
+ *
+ * @note All data for this request must be allocated from the given pool.
+ */
+struct kr_request {
+ struct kr_context *ctx;
+ knot_pkt_t *answer; /**< See kr_request_ensure_answer() */
+ struct kr_query *current_query; /**< Current evaluated query. */
+ struct {
+ /** Address that originated the request. May be that of a client
+ * behind a proxy, if PROXYv2 is used. Otherwise, it will be
+ * the same as `comm_addr`. `NULL` for internal origin. */
+ const struct sockaddr *addr;
+ /** Address that communicated the request. This may be the address
+ * of a proxy. It is the same as `addr` if no proxy is used.
+ * `NULL` for internal origin. */
+ const struct sockaddr *comm_addr;
+ /** Address that accepted the request. `NULL` for internal origin.
+ * Beware: in case of UDP on wildcard address it will be wildcard;
+ * closely related: issue #173. */
+ const struct sockaddr *dst_addr;
+ const knot_pkt_t *packet;
+ /** Request flags from the point of view of the original client.
+ * This client may be behind a proxy. */
+ struct kr_request_qsource_flags flags;
+ /** Request flags from the point of view of the client actually
+ * communicating with the resolver. When PROXYv2 protocol is used,
+ * this describes the request from the proxy. When there is no
+ * proxy, this will have exactly the same value as `flags`. */
+ struct kr_request_qsource_flags comm_flags;
+ size_t size; /**< query packet size */
+ int32_t stream_id; /**< HTTP/2 stream ID for DoH requests */
+ kr_http_header_array_t headers; /**< HTTP/2 headers for DoH requests */
+ } qsource;
+ struct {
+ unsigned rtt; /**< Current upstream RTT */
+ const struct kr_transport *transport; /**< Current upstream transport */
+ } upstream; /**< Upstream information, valid only in consume() phase */
+ struct kr_qflags options;
+ int state;
+ ranked_rr_array_t answ_selected;
+ ranked_rr_array_t auth_selected;
+ ranked_rr_array_t add_selected;
+ bool answ_validated; /**< internal to validator; beware of caching, etc. */
+ bool auth_validated; /**< see answ_validated ^^ ; TODO */
+
+ /** Overall rank for the request.
+ *
+ * Values from kr_rank, currently just KR_RANK_SECURE and _INITIAL.
+ * Only read this in finish phase and after validator, please.
+ * Meaning of _SECURE: all RRs in answer+authority are _SECURE,
+ * including any negative results implied (NXDOMAIN, NODATA).
+ */
+ uint8_t rank;
+
+ struct kr_rplan rplan;
+ trace_log_f trace_log; /**< Logging tracepoint */
+ trace_callback_f trace_finish; /**< Request finish tracepoint */
+ int vars_ref; /**< Reference to per-request variable table. LUA_NOREF if not set. */
+ knot_mm_t pool;
+ unsigned int uid; /**< for logging purposes only */
+ struct {
+ addr_info_f is_tls_capable;
+ addr_info_f is_tcp_connected;
+ addr_info_f is_tcp_waiting;
+ kr_sockaddr_array_t forwarding_targets; /**< When forwarding, possible targets are put here */
+ } selection_context;
+ unsigned int count_no_nsaddr;
+ unsigned int count_fail_row;
+ alloc_wire_f alloc_wire_cb; /**< CB to allocate answer wire (can be NULL). */
+ struct kr_extended_error extended_error; /**< EDE info; don't modify directly, use kr_request_set_extended_error() */
+};
+
+/** Initializer for an array of *_selected. */
+#define kr_request_selected(req) { \
+ [KNOT_ANSWER] = &(req)->answ_selected, \
+ [KNOT_AUTHORITY] = &(req)->auth_selected, \
+ [KNOT_ADDITIONAL] = &(req)->add_selected, \
+ }
+
+/**
+ * Begin name resolution.
+ *
+ * @note Expects a request to have an initialized mempool.
+ *
+ * @param request request state with initialized mempool
+ * @param ctx resolution context
+ * @return CONSUME (expecting query)
+ */
+KR_EXPORT
+int kr_resolve_begin(struct kr_request *request, struct kr_context *ctx);
+
+/**
+ * Ensure that request->answer->opt_rr is present if query has EDNS.
+ *
+ * This function should be used after clearing a response packet to ensure its
+ * opt_rr is properly set. Returns the opt_rr (for convenience) or NULL.
+ */
+KR_EXPORT
+knot_rrset_t * kr_request_ensure_edns(struct kr_request *request);
+
+/**
+ * Ensure that request->answer is usable, and return it (for convenience).
+ *
+ * It may return NULL, in which case it marks ->state with _FAIL and no answer will be sent.
+ * Only use this when it's guaranteed that there will be no delay before sending it.
+ * You don't need to call this in places where "resolver knows" that there will be no delay,
+ * but even there you need to check if the ->answer is NULL (unless you check for _FAIL anyway).
+ */
+KR_EXPORT
+knot_pkt_t * kr_request_ensure_answer(struct kr_request *request);
+
+/**
+ * Consume input packet (may be either first query or answer to query originated from kr_resolve_produce())
+ *
+ * @note If the I/O fails, provide an empty or NULL packet, this will make iterator recognize nameserver failure.
+ *
+ * @param request request state (awaiting input)
+ * @param src [in] packet source address
+ * @param packet [in] input packet
+ * @return any state
+ */
+KR_EXPORT
+int kr_resolve_consume(struct kr_request *request, struct kr_transport **transport, knot_pkt_t *packet);
+
+/**
+ * Produce either next additional query or finish.
+ *
+ * If the CONSUME is returned then dst, type and packet will be filled with
+ * appropriate values and caller is responsible to send them and receive answer.
+ * If it returns any other state, then content of the variables is undefined.
+ *
+ * @param request request state (in PRODUCE state)
+ * @param dst [out] possible address of the next nameserver
+ * @param type [out] possible used socket type (SOCK_STREAM, SOCK_DGRAM)
+ * @param packet [out] packet to be filled with additional query
+ * @return any state
+ */
+KR_EXPORT
+int kr_resolve_produce(struct kr_request *request, struct kr_transport **transport, knot_pkt_t *packet);
+
+/**
+ * Finalises the outbound query packet with the knowledge of the IP addresses.
+ *
+ * @note The function must be called before actual sending of the request packet.
+ *
+ * @param request request state (in PRODUCE state)
+ * @param src address from which the query is going to be sent
+ * @param dst address of the name server
+ * @param type used socket type (SOCK_STREAM, SOCK_DGRAM)
+ * @param packet [in,out] query packet to be finalised
+ * @return kr_ok() or error code
+ */
+KR_EXPORT
+int kr_resolve_checkout(struct kr_request *request, const struct sockaddr *src,
+ struct kr_transport *transport, knot_pkt_t *packet);
+
+/**
+ * Finish resolution and commit results if the state is DONE.
+ *
+ * @note The structures will be deinitialized, but the assigned memory pool is not going to
+ * be destroyed, as it's owned by caller.
+ *
+ * @param request request state
+ * @param state either DONE or FAIL state (to be assigned to request->state)
+ * @return DONE
+ */
+KR_EXPORT
+int kr_resolve_finish(struct kr_request *request, int state);
+
+/**
+ * Return resolution plan.
+ * @param request request state
+ * @return pointer to rplan
+ */
+KR_EXPORT KR_PURE
+struct kr_rplan *kr_resolve_plan(struct kr_request *request);
+
+/**
+ * Return memory pool associated with request.
+ * @param request request state
+ * @return mempool
+ */
+KR_EXPORT KR_PURE
+knot_mm_t *kr_resolve_pool(struct kr_request *request);
+
+/**
+ * Set the extended DNS error for request.
+ *
+ * The error is set only if it has a higher or the same priority as the one
+ * already assigned. The provided extra_text may be NULL, or a string that is
+ * allocated either statically, or on the request's mempool. To clear any
+ * error, call it with KNOT_EDNS_EDE_NONE and NULL as extra_text.
+ *
+ * To facilitate debugging, we include a unique base32 identifier at the start
+ * of the extra_text field for every call of this function. To generate such an
+ * identifier, you can use the command:
+ * $ base32 /dev/random | head -c 4
+ *
+ * @param request request state
+ * @param info_code extended DNS error code
+ * @param extra_text optional string with additional information
+ * @return info_code that is set after the call
+ */
+KR_EXPORT
+int kr_request_set_extended_error(struct kr_request *request, int info_code, const char *extra_text);
+
+static inline void kr_query_inform_timeout(struct kr_request *req, const struct kr_query *qry)
+{
+ kr_request_set_extended_error(req, KNOT_EDNS_EDE_NREACH_AUTH, "RRPF");
+
+ unsigned ind = 0;
+ for (const struct kr_query *q = qry; q; q = q->parent)
+ ind += 2;
+ const uint32_t qid = qry ? qry->uid : 0;
+
+ kr_log_req(req, qid, ind, WORKER, "internal timeout for resolving the request has expired\n");
+}
diff --git a/lib/rplan.c b/lib/rplan.c
new file mode 100644
index 0000000..0bedd8a
--- /dev/null
+++ b/lib/rplan.c
@@ -0,0 +1,291 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#include <libknot/descriptor.h>
+#include <libknot/errcode.h>
+
+#include "lib/rplan.h"
+#include "lib/resolve.h"
+
+#define VERBOSE_MSG(qry, ...) kr_log_q(qry, PLAN, __VA_ARGS__)
+
+inline static unsigned char chars_or(const unsigned char a, const unsigned char b)
+{
+ return a | b;
+}
+
+/** Bits set to 1 in variable b will be set to zero in variable a. */
+inline static unsigned char chars_mask(const unsigned char a, const unsigned char b)
+{
+ return a & ~b;
+}
+
+/** Apply mod(a, b) to every byte a, b from fl1, fl2 and return result in fl1. */
+inline static void kr_qflags_mod(struct kr_qflags *fl1, struct kr_qflags fl2,
+ unsigned char mod(const unsigned char a, const unsigned char b))
+{
+ kr_require(fl1);
+ union {
+ struct kr_qflags flags;
+ /* C99 section 6.5.3.4: sizeof(char) == 1 */
+ unsigned char chars[sizeof(struct kr_qflags)];
+ } tmp1, tmp2;
+ /* The compiler should be able to optimize all this into simple ORs. */
+ tmp1.flags = *fl1;
+ tmp2.flags = fl2;
+ for (size_t i = 0; i < sizeof(struct kr_qflags); ++i) {
+ tmp1.chars[i] = mod(tmp1.chars[i], tmp2.chars[i]);
+ }
+ *fl1 = tmp1.flags;
+}
+
+/**
+ * Set bits from variable fl2 in variable fl1.
+ * Bits which are not set in fl2 are not modified in fl1.
+ *
+ * @param[in,out] fl1
+ * @param[in] fl2
+ */
+void kr_qflags_set(struct kr_qflags *fl1, struct kr_qflags fl2)
+{
+ kr_qflags_mod(fl1, fl2, chars_or);
+}
+
+/**
+ * Clear bits from variable fl2 in variable fl1.
+ * Bits which are not set in fl2 are not modified in fl1.
+ *
+ * @param[in,out] fl1
+ * @param[in] fl2
+ */
+void kr_qflags_clear(struct kr_qflags *fl1, struct kr_qflags fl2)
+{
+ kr_qflags_mod(fl1, fl2, chars_mask);
+}
+
+static struct kr_query *query_create(knot_mm_t *pool, const knot_dname_t *name, uint32_t uid)
+{
+ struct kr_query *qry = mm_calloc(pool, 1, sizeof(*qry));
+ if (qry == NULL) {
+ return NULL;
+ }
+
+ if (name != NULL) {
+ qry->sname = knot_dname_copy(name, pool);
+ if (qry->sname == NULL) {
+ mm_free(pool, qry);
+ return NULL;
+ }
+ }
+
+ knot_dname_to_lower(qry->sname);
+ qry->uid = uid;
+ return qry;
+}
+
+static void query_free(knot_mm_t *pool, struct kr_query *qry)
+{
+ kr_zonecut_deinit(&qry->zone_cut);
+ mm_free(pool, qry->sname);
+ mm_free(pool, qry);
+}
+
+int kr_rplan_init(struct kr_rplan *rplan, struct kr_request *request, knot_mm_t *pool)
+{
+ if (rplan == NULL) {
+ return KNOT_EINVAL;
+ }
+
+ memset(rplan, 0, sizeof(struct kr_rplan));
+
+ rplan->pool = pool;
+ rplan->request = request;
+ array_init(rplan->pending);
+ array_init(rplan->resolved);
+ rplan->next_uid = 0;
+ return KNOT_EOK;
+}
+
+void kr_rplan_deinit(struct kr_rplan *rplan)
+{
+ if (rplan == NULL) {
+ return;
+ }
+
+ for (size_t i = 0; i < rplan->pending.len; ++i) {
+ query_free(rplan->pool, rplan->pending.at[i]);
+ }
+ for (size_t i = 0; i < rplan->resolved.len; ++i) {
+ query_free(rplan->pool, rplan->resolved.at[i]);
+ }
+ array_clear_mm(rplan->pending, mm_free, rplan->pool);
+ array_clear_mm(rplan->resolved, mm_free, rplan->pool);
+}
+
+bool kr_rplan_empty(struct kr_rplan *rplan)
+{
+ if (rplan == NULL) {
+ return true;
+ }
+
+ return rplan->pending.len == 0;
+}
+
+static struct kr_query *kr_rplan_push_query(struct kr_rplan *rplan,
+ struct kr_query *parent,
+ const knot_dname_t *name)
+{
+ if (rplan == NULL) {
+ return NULL;
+ }
+
+ /* Make sure there's enough space */
+ int ret = array_reserve_mm(rplan->pending, rplan->pending.len + 1, kr_memreserve, rplan->pool);
+ if (ret != 0) {
+ return NULL;
+ }
+
+ struct kr_query *qry = query_create(rplan->pool, name, rplan->next_uid);
+ if (qry == NULL) {
+ return NULL;
+ }
+ rplan->next_uid += 1;
+ /* Class and type must be set outside this function. */
+ qry->flags = rplan->request->options;
+ qry->parent = parent;
+ qry->request = rplan->request;
+
+ gettimeofday(&qry->timestamp, NULL);
+ qry->timestamp_mono = kr_now();
+ qry->creation_time_mono = parent ? parent->creation_time_mono : qry->timestamp_mono;
+ kr_zonecut_init(&qry->zone_cut, (const uint8_t *)"", rplan->pool);
+ qry->reorder = qry->flags.REORDER_RR ? kr_rand_bytes(sizeof(qry->reorder)) : 0;
+
+
+ kr_assert((rplan->pending.len == 0 && rplan->resolved.len == 0)
+ == (rplan->initial == NULL));
+ if (rplan->initial == NULL) {
+ rplan->initial = qry;
+ }
+
+ array_push(rplan->pending, qry);
+
+ return qry;
+}
+
+struct kr_query *kr_rplan_push_empty(struct kr_rplan *rplan, struct kr_query *parent)
+{
+ if (rplan == NULL) {
+ return NULL;
+ }
+
+ struct kr_query *qry = kr_rplan_push_query(rplan, parent, NULL);
+ if (qry == NULL) {
+ return NULL;
+ }
+
+ VERBOSE_MSG(qry, "plan '%s' type '%s' uid [%05u.%02u]\n", "", "",
+ qry->request ? qry->request->uid : 0, qry->uid);
+ return qry;
+}
+
+struct kr_query *kr_rplan_push(struct kr_rplan *rplan, struct kr_query *parent,
+ const knot_dname_t *name, uint16_t cls, uint16_t type)
+{
+ if (rplan == NULL || name == NULL) {
+ return NULL;
+ }
+
+ struct kr_query *qry = kr_rplan_push_query(rplan, parent, name);
+ if (qry == NULL) {
+ return NULL;
+ }
+
+ qry->sclass = cls;
+ qry->stype = type;
+
+ if (kr_log_is_debug_qry(PLAN, qry)) {
+ KR_DNAME_GET_STR(name_str, name);
+ KR_RRTYPE_GET_STR(type_str, type);
+ VERBOSE_MSG(parent, "plan '%s' type '%s' uid [%05u.%02u]\n",
+ name_str, type_str,
+ qry->request ? qry->request->uid : 0, qry->uid);
+ }
+ return qry;
+}
+
+int kr_rplan_pop(struct kr_rplan *rplan, struct kr_query *qry)
+{
+ if (rplan == NULL || qry == NULL) {
+ return KNOT_EINVAL;
+ }
+
+ /* Make sure there's enough space */
+ int ret = array_reserve_mm(rplan->resolved, rplan->resolved.len + 1, kr_memreserve, rplan->pool);
+ if (ret != 0) {
+ return ret;
+ }
+
+ /* Find the query, it will likely be on top */
+ for (size_t i = rplan->pending.len; i > 0; i--) {
+ if (rplan->pending.at[i - 1] == qry) {
+ /* Delete i-1 element by *sliding* the rest,
+ * contrary to array_del() */
+ for (size_t j = i; j < rplan->pending.len; ++j)
+ rplan->pending.at[j - 1] = rplan->pending.at[j];
+ array_pop(rplan->pending);
+
+ array_push(rplan->resolved, qry);
+ break;
+ }
+ }
+ return KNOT_EOK;
+}
+
+bool kr_rplan_satisfies(struct kr_query *closure, const knot_dname_t *name, uint16_t cls, uint16_t type)
+{
+ while (name && closure) {
+ if (closure->sclass == cls && closure->stype == type
+ && knot_dname_is_equal(closure->sname, name)) {
+ return true;
+ }
+ closure = closure->parent;
+ }
+ return false;
+}
+
+struct kr_query *kr_rplan_resolved(struct kr_rplan *rplan)
+{
+ if (rplan->resolved.len == 0) {
+ return NULL;
+ }
+ return array_tail(rplan->resolved);
+}
+
+struct kr_query *kr_rplan_last(struct kr_rplan *rplan)
+{
+ if (!kr_rplan_empty(rplan)) {
+ return array_tail(rplan->pending);
+ }
+
+ return kr_rplan_resolved(rplan);
+}
+
+struct kr_query *kr_rplan_find_resolved(struct kr_rplan *rplan, struct kr_query *parent,
+ const knot_dname_t *name, uint16_t cls, uint16_t type)
+{
+ struct kr_query *ret = NULL;
+ for (int i = 0; i < rplan->resolved.len; ++i) {
+ struct kr_query *q = rplan->resolved.at[i];
+ if (q->stype == type && q->sclass == cls &&
+ (parent == NULL || q->parent == parent) &&
+ knot_dname_is_equal(q->sname, name)) {
+ ret = q;
+ break;
+ }
+ }
+ return ret;
+}
+
+#undef VERBOSE_MSG
diff --git a/lib/rplan.h b/lib/rplan.h
new file mode 100644
index 0000000..891781f
--- /dev/null
+++ b/lib/rplan.h
@@ -0,0 +1,221 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#include <sys/time.h>
+#include <libknot/dname.h>
+#include <libknot/codes.h>
+
+#include "lib/selection.h"
+#include "lib/zonecut.h"
+
+/** Query flags */
+struct kr_qflags {
+ bool NO_MINIMIZE : 1; /**< Don't minimize QNAME. */
+ bool NO_IPV6 : 1; /**< Disable IPv6 */
+ bool NO_IPV4 : 1; /**< Disable IPv4 */
+ bool TCP : 1; /**< Use TCP (or TLS) for this query. */
+ bool NO_ANSWER : 1; /**< Do not send any answer to the client.
+ * Request state should be set to `KR_STATE_FAIL`
+ * when this flag is set. */
+ bool RESOLVED : 1; /**< Query is resolved. Note that kr_query gets
+ * RESOLVED before following a CNAME chain; see .CNAME. */
+ bool AWAIT_IPV4 : 1; /**< Query is waiting for A address. */
+ bool AWAIT_IPV6 : 1; /**< Query is waiting for AAAA address. */
+ bool AWAIT_CUT : 1; /**< Query is waiting for zone cut lookup */
+ bool NO_EDNS : 1; /**< Don't use EDNS. */
+ bool CACHED : 1; /**< Query response is cached. */
+ bool NO_CACHE : 1; /**< No cache for lookup; exception: finding NSs and subqueries. */
+ bool EXPIRING : 1; /**< Query response is cached but expiring. See is_expiring(). */
+ bool ALLOW_LOCAL : 1; /**< Allow queries to local or private address ranges. */
+ bool DNSSEC_WANT : 1; /**< Want DNSSEC secured answer; exception: +cd,
+ * i.e. knot_wire_get_cd(request->qsource.packet->wire) */
+ bool DNSSEC_BOGUS : 1; /**< Query response is DNSSEC bogus. */
+ bool DNSSEC_INSECURE : 1;/**< Query response is DNSSEC insecure. */
+ bool DNSSEC_CD : 1; /**< Instruction to set CD bit in request. */
+ bool STUB : 1; /**< Stub resolution, accept received answer as solved. */
+ bool ALWAYS_CUT : 1; /**< Always recover zone cut (even if cached). */
+ bool DNSSEC_WEXPAND : 1; /**< Query response has wildcard expansion. */
+ bool PERMISSIVE : 1; /**< Permissive resolver mode. */
+ bool STRICT : 1; /**< Strict resolver mode. */
+ bool BADCOOKIE_AGAIN : 1;/**< Query again because bad cookie returned. */
+ bool CNAME : 1; /**< Query response contains CNAME in answer section. */
+ bool REORDER_RR : 1; /**< Reorder cached RRs. */
+ bool TRACE : 1; /**< Also log answers on debug level. */
+ bool NO_0X20 : 1; /**< Disable query case randomization . */
+ bool DNSSEC_NODS : 1; /**< DS non-existence is proven */
+ bool DNSSEC_OPTOUT : 1; /**< Closest encloser proof has optout */
+ bool NONAUTH : 1; /**< Non-authoritative in-bailiwick records are enough.
+ * TODO: utilize this also outside cache. */
+ bool FORWARD : 1; /**< Forward all queries to upstream; validate answers. */
+ bool DNS64_MARK : 1; /**< Internal mark for dns64 module. */
+ bool CACHE_TRIED : 1; /**< Internal to cache module. */
+ bool NO_NS_FOUND : 1; /**< No valid NS found during last PRODUCE stage. */
+ bool PKT_IS_SANE : 1; /**< Set by iterator in consume phase to indicate whether
+ * some basic aspects of the packet are OK, e.g. QNAME. */
+ bool DNS64_DISABLE : 1; /**< Don't do any DNS64 stuff (meant for view:addr). */
+};
+
+/** Combine flags together. This means set union for simple flags. */
+KR_EXPORT
+void kr_qflags_set(struct kr_qflags *fl1, struct kr_qflags fl2);
+
+/** Remove flags. This means set-theoretic difference. */
+KR_EXPORT
+void kr_qflags_clear(struct kr_qflags *fl1, struct kr_qflags fl2);
+
+/** Callback for serve-stale decisions.
+ * @param ttl the expired TTL (i.e. it's < 0)
+ * @return the adjusted TTL (typically 1) or < 0.
+ */
+typedef int32_t (*kr_stale_cb)(int32_t ttl, const knot_dname_t *owner, uint16_t type,
+ const struct kr_query *qry);
+
+/**
+ * Single query representation.
+ */
+struct kr_query {
+ struct kr_query *parent;
+ knot_dname_t *sname; /**< The name to resolve - lower-cased, uncompressed. */
+ uint16_t stype;
+ uint16_t sclass;
+ uint16_t id;
+ uint16_t reorder; /**< Seed to reorder (cached) RRs in answer or zero. */
+ struct kr_qflags flags;
+ struct kr_qflags forward_flags;
+ uint32_t secret;
+ uint32_t uid; /**< Query iteration number, unique within the kr_rplan. */
+ uint64_t creation_time_mono; /* The time of query's creation (milliseconds).
+ * Or time of creation of an oldest
+ * ancestor if it is a subquery. */
+ uint64_t timestamp_mono; /**< Time of query created or time of
+ * query to upstream resolver (milliseconds). */
+ struct timeval timestamp; /**< Real time for TTL+DNSSEC checks (.tv_sec only). */
+ struct kr_zonecut zone_cut;
+ struct kr_layer_pickle *deferred;
+
+ /** Current xNAME depth, set by iterator. 0 = uninitialized, 1 = no CNAME, ...
+ * See also KR_CNAME_CHAIN_LIMIT. */
+ int8_t cname_depth;
+ /** Pointer to the query that originated this one because of following a CNAME (or NULL). */
+ struct kr_query *cname_parent;
+ struct kr_request *request; /**< Parent resolution request. */
+ kr_stale_cb stale_cb; /**< See the type */
+ struct kr_server_selection server_selection;
+};
+
+/** @cond internal Array of queries. */
+typedef array_t(struct kr_query *) kr_qarray_t;
+/* @endcond */
+
+/**
+ * Query resolution plan structure.
+ *
+ * The structure most importantly holds the original query, answer and the
+ * list of pending queries required to resolve the original query.
+ * It also keeps a notion of current zone cut.
+ */
+struct kr_rplan {
+ kr_qarray_t pending; /**< List of pending queries.
+ Beware: order is significant ATM,
+ as the last is the next one to solve,
+ and they may be inter-dependent. */
+ kr_qarray_t resolved; /**< List of resolved queries. */
+ struct kr_query *initial; /**< The initial query (also in pending or resolved). */
+
+ struct kr_request *request; /**< Parent resolution request. */
+ knot_mm_t *pool; /**< Temporary memory pool. */
+ uint32_t next_uid; /**< Next value for kr_query::uid (incremental). */
+};
+
+/**
+ * Initialize resolution plan (empty).
+ * @param rplan plan instance
+ * @param request resolution request
+ * @param pool ephemeral memory pool for whole resolution
+ */
+KR_EXPORT
+int kr_rplan_init(struct kr_rplan *rplan, struct kr_request *request, knot_mm_t *pool);
+
+/**
+ * Deinitialize resolution plan, aborting any uncommitted transactions.
+ * @param rplan plan instance
+ */
+KR_EXPORT
+void kr_rplan_deinit(struct kr_rplan *rplan);
+
+/**
+ * Return true if the resolution plan is empty (i.e. finished or initialized)
+ * @param rplan plan instance
+ * @return true or false
+ */
+KR_EXPORT KR_PURE
+bool kr_rplan_empty(struct kr_rplan *rplan);
+
+/**
+ * Push empty query to the top of the resolution plan.
+ * @note This query serves as a cookie query only.
+ * @param rplan plan instance
+ * @param parent query parent (or NULL)
+ * @return query instance or NULL
+ */
+KR_EXPORT
+struct kr_query *kr_rplan_push_empty(struct kr_rplan *rplan,
+ struct kr_query *parent);
+
+/**
+ * Push a query to the top of the resolution plan.
+ * @note This means that this query takes precedence before all pending queries.
+ * @param rplan plan instance
+ * @param parent query parent (or NULL)
+ * @param name resolved name
+ * @param cls resolved class
+ * @param type resolved type
+ * @return query instance or NULL
+ */
+KR_EXPORT
+struct kr_query *kr_rplan_push(struct kr_rplan *rplan, struct kr_query *parent,
+ const knot_dname_t *name, uint16_t cls, uint16_t type);
+
+/**
+ * Pop existing query from the resolution plan.
+ * @note Popped queries are not discarded, but moved to the resolved list.
+ * @param rplan plan instance
+ * @param qry resolved query
+ * @return 0 or an error
+ */
+KR_EXPORT
+int kr_rplan_pop(struct kr_rplan *rplan, struct kr_query *qry);
+
+/**
+ * Return true if resolution chain satisfies given query.
+ */
+KR_EXPORT KR_PURE
+bool kr_rplan_satisfies(struct kr_query *closure, const knot_dname_t *name, uint16_t cls, uint16_t type);
+
+/** Return last resolved query. */
+KR_EXPORT KR_PURE
+struct kr_query *kr_rplan_resolved(struct kr_rplan *rplan);
+
+/**
+ * Return last query (either currently being solved or last resolved).
+ * This is necessary to retrieve the last query in case of resolution failures (e.g. time limit reached).
+ */
+KR_EXPORT KR_PURE
+struct kr_query *kr_rplan_last(struct kr_rplan *rplan);
+
+
+/**
+ * Check if a given query already resolved.
+ * @param rplan plan instance
+ * @param parent query parent (or NULL)
+ * @param name resolved name
+ * @param cls resolved class
+ * @param type resolved type
+ * @return query instance or NULL
+ */
+KR_EXPORT KR_PURE
+struct kr_query *kr_rplan_find_resolved(struct kr_rplan *rplan, struct kr_query *parent,
+ const knot_dname_t *name, uint16_t cls, uint16_t type);
diff --git a/lib/selection.c b/lib/selection.c
new file mode 100644
index 0000000..5aa2992
--- /dev/null
+++ b/lib/selection.c
@@ -0,0 +1,795 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#include <libknot/dname.h>
+
+#include "lib/selection.h"
+#include "lib/selection_forward.h"
+#include "lib/selection_iter.h"
+#include "lib/rplan.h"
+#include "lib/cache/api.h"
+#include "lib/resolve.h"
+
+#include "lib/utils.h"
+
+#define VERBOSE_MSG(qry, ...) kr_log_q((qry), SELECTION, __VA_ARGS__)
+
+#define DEFAULT_TIMEOUT 400
+#define MAX_TIMEOUT 10000
+#define EXPLORE_TIMEOUT_COEFFICIENT 2
+#define MAX_BACKOFF 8
+#define MINIMAL_TIMEOUT_ADDITION 20
+
+/* After TCP_TIMEOUT_THRESHOLD timeouts one transport, we'll switch to TCP. */
+#define TCP_TIMEOUT_THRESHOLD 2
+/* If the expected RTT is over TCP_RTT_THRESHOLD we switch to TCP instead. */
+#define TCP_RTT_THRESHOLD 2000
+
+/* Define ε for ε-greedy algorithm (see select_transport)
+ * as ε=EPSILON_NOMIN/EPSILON_DENOM */
+#define EPSILON_NOMIN 1
+#define EPSILON_DENOM 20
+
+static const char *kr_selection_error_str(enum kr_selection_error err) {
+ switch (err) {
+ #define X(ENAME) case KR_SELECTION_ ## ENAME: return #ENAME
+ X(OK);
+ X(QUERY_TIMEOUT);
+ X(TLS_HANDSHAKE_FAILED);
+ X(TCP_CONNECT_FAILED);
+ X(TCP_CONNECT_TIMEOUT);
+ X(REFUSED);
+ X(SERVFAIL);
+ X(FORMERR);
+ X(FORMERR_EDNS);
+ X(NOTIMPL);
+ X(OTHER_RCODE);
+ X(MALFORMED);
+ X(MISMATCHED);
+ X(TRUNCATED);
+ X(DNSSEC_ERROR);
+ X(LAME_DELEGATION);
+ X(BAD_CNAME);
+ case KR_SELECTION_NUMBER_OF_ERRORS: break; // not a valid code
+ #undef X
+ }
+ kr_assert(false); // we want to define all; compiler helps by -Wswitch (no default:)
+ return NULL;
+}
+
+
+/* Simple detection of IPv6 being broken.
+ *
+ * We follow all IPv6 timeouts and successes. Consider it broken iff we've had
+ * timeouts on several different IPv6 prefixes since the last IPv6 success.
+ * Note: unlike the rtt_state, this happens only per-process (for simplicity).
+ *
+ * ## NO6_PREFIX_* choice
+ * For our practical use we choose primarily based on root and typical TLD servers.
+ * Looking at *.{root,gtld}-servers.net, we have 7/26 AAAAs in 2001:500:00**::
+ * but adding one more byte makes these completely unique, so we choose /48.
+ * As distribution to ASs seems to be on shorter prefixes (RIPE: /32 -- /24?),
+ * we wait for several distinct prefixes.
+ */
+
+#define NO6_PREFIX_COUNT 6
+#define NO6_PREFIX_BYTES (48/8)
+static struct {
+ int len_used;
+ uint8_t addr_prefixes[NO6_PREFIX_COUNT][NO6_PREFIX_BYTES];
+} no6_est = { .len_used = 0 };
+
+bool no6_is_bad(void)
+{
+ return no6_est.len_used == NO6_PREFIX_COUNT;
+}
+
+static void no6_timed_out(const struct kr_query *qry, const uint8_t *addr)
+{
+ if (no6_is_bad()) { // we can't get worse
+ VERBOSE_MSG(qry, "NO6: timed out, but bad already\n");
+ return;
+ }
+ // If we have the address already, do nothing.
+ for (int i = 0; i < no6_est.len_used; ++i) {
+ if (memcmp(addr, no6_est.addr_prefixes[i], NO6_PREFIX_BYTES) == 0) {
+ VERBOSE_MSG(qry, "NO6: timed out, repeated prefix, timeouts %d/%d\n",
+ no6_est.len_used, (int)NO6_PREFIX_COUNT);
+ return;
+ }
+ }
+ // Append!
+ memcpy(no6_est.addr_prefixes[no6_est.len_used++], addr, NO6_PREFIX_BYTES);
+ VERBOSE_MSG(qry, "NO6: timed out, appended, timeouts %d/%d\n",
+ no6_est.len_used, (int)NO6_PREFIX_COUNT);
+}
+
+static inline void no6_success(const struct kr_query *qry)
+{
+ if (no6_est.len_used) {
+ VERBOSE_MSG(qry, "NO6: success, zeroing %d/%d\n",
+ no6_est.len_used, (int)NO6_PREFIX_COUNT);
+ }
+ no6_est.len_used = 0;
+}
+
+
+/* Simple cache interface follows */
+
+static knot_db_val_t cache_key(const uint8_t *ip, size_t len)
+{
+ // CACHE_KEY_DEF: '\0' + 'S' + raw IP
+ const size_t key_len = len + 2;
+ uint8_t *key_data = malloc(key_len);
+ key_data[0] = '\0';
+ key_data[1] = 'S';
+ memcpy(key_data + 2, ip, len);
+ knot_db_val_t key = {
+ .len = key_len,
+ .data = key_data,
+ };
+ return key;
+}
+
+/* First value of timeout will be calculated as SRTT+4*VARIANCE
+ * by calc_timeout(), so it'll be equal to DEFAULT_TIMEOUT. */
+static const struct rtt_state default_rtt_state = { .srtt = 0,
+ .variance = DEFAULT_TIMEOUT / 4,
+ .consecutive_timeouts = 0,
+ .dead_since = 0 };
+
+struct rtt_state get_rtt_state(const uint8_t *ip, size_t len,
+ struct kr_cache *cache)
+{
+ struct rtt_state state;
+ knot_db_val_t value;
+ knot_db_t *db = cache->db;
+ struct kr_cdb_stats *stats = &cache->stats;
+
+ knot_db_val_t key = cache_key(ip, len);
+
+ if (cache->api->read(db, stats, &key, &value, 1)) {
+ state = default_rtt_state;
+ } else if (kr_fails_assert(value.len == sizeof(struct rtt_state))) {
+ // shouldn't happen but let's be more robust
+ state = default_rtt_state;
+ } else { // memcpy is safe for unaligned case (on non-x86)
+ memcpy(&state, value.data, sizeof(state));
+ }
+
+ free(key.data);
+ return state;
+}
+
+int put_rtt_state(const uint8_t *ip, size_t len, struct rtt_state state,
+ struct kr_cache *cache)
+{
+ knot_db_t *db = cache->db;
+ struct kr_cdb_stats *stats = &cache->stats;
+
+ knot_db_val_t key = cache_key(ip, len);
+ knot_db_val_t value = { .len = sizeof(struct rtt_state),
+ .data = &state };
+
+ int ret = cache->api->write(db, stats, &key, &value, 1);
+ cache->api->commit(db, stats);
+
+ free(key.data);
+ return ret;
+}
+
+void bytes_to_ip(uint8_t *bytes, size_t len, uint16_t port, union kr_sockaddr *dst)
+{
+ switch (len) {
+ case sizeof(struct in_addr):
+ dst->ip4.sin_family = AF_INET;
+ memcpy(&dst->ip4.sin_addr, bytes, len);
+ dst->ip4.sin_port = htons(port);
+ break;
+ case sizeof(struct in6_addr):
+ memset(&dst->ip6, 0, sizeof(dst->ip6)); // avoid uninit surprises
+ dst->ip6.sin6_family = AF_INET6;
+ memcpy(&dst->ip6.sin6_addr, bytes, len);
+ dst->ip6.sin6_port = htons(port);
+ break;
+ default:
+ kr_assert(false);
+ }
+}
+
+uint8_t *ip_to_bytes(const union kr_sockaddr *src, size_t len)
+{
+ switch (len) {
+ case sizeof(struct in_addr):
+ return (uint8_t *)&src->ip4.sin_addr;
+ case sizeof(struct in6_addr):
+ return (uint8_t *)&src->ip6.sin6_addr;
+ default:
+ kr_assert(false);
+ return NULL;
+ }
+}
+
+static bool no_rtt_info(struct rtt_state s)
+{
+ return s.srtt == 0 && s.consecutive_timeouts == 0;
+}
+
+static unsigned back_off_timeout(uint32_t to, int pow)
+{
+ pow = MIN(pow, MAX_BACKOFF);
+ to <<= pow;
+ return MIN(to, MAX_TIMEOUT);
+}
+
+/* This is verbatim (minus the default timeout value and minimal variance)
+ * RFC6298, sec. 2. */
+static unsigned calc_timeout(struct rtt_state state)
+{
+ int32_t timeout = state.srtt + MAX(4 * state.variance, MINIMAL_TIMEOUT_ADDITION);
+ return back_off_timeout(timeout, state.consecutive_timeouts);
+}
+
+/* This is verbatim RFC6298, sec. 2. */
+static struct rtt_state calc_rtt_state(struct rtt_state old, unsigned new_rtt)
+{
+ if (no_rtt_info(old)) {
+ return (struct rtt_state){ new_rtt, new_rtt / 2, 0 };
+ }
+
+ struct rtt_state ret = { 0 };
+ ret.variance = (3 * old.variance + abs(old.srtt - (int32_t)new_rtt)
+ + 2/*rounding*/) / 4;
+ ret.srtt = (7 * old.srtt + new_rtt + 4/*rounding*/) / 8;
+
+ return ret;
+}
+
+/**
+ * @internal Invalidate addresses which should be considered dead
+ */
+static void invalidate_dead_upstream(struct address_state *state,
+ unsigned int retry_timeout)
+{
+ struct rtt_state *rs = &state->rtt_state;
+ if (rs->dead_since) {
+ uint64_t now = kr_now();
+ if (now < rs->dead_since) {
+ // broken continuity of timestamp (reboot, different machine, etc.)
+ *rs = default_rtt_state;
+ } else if (now < rs->dead_since + retry_timeout) {
+ // period when we don't want to use the address
+ state->generation = -1;
+ } else {
+ kr_assert(now >= rs->dead_since + retry_timeout);
+ // we allow to retry the server now
+ // TODO: perhaps tweak *rs?
+ }
+ }
+}
+
+/**
+ * @internal Check if IP address is TLS capable.
+ *
+ * @p req has to have the selection_context properly initialized.
+ */
+static void check_tls_capable(struct address_state *address_state,
+ struct kr_request *req, struct sockaddr *address)
+{
+ address_state->tls_capable =
+ req->selection_context.is_tls_capable ?
+ req->selection_context.is_tls_capable(address) :
+ false;
+}
+
+#if 0
+/* TODO: uncomment these once we actually use the information it collects. */
+/**
+ * Check if there is a existing TCP connection to this address.
+ *
+ * @p req has to have the selection_context properly initialized.
+ */
+void check_tcp_connections(struct address_state *address_state, struct kr_request *req, struct sockaddr *address) {
+ address_state->tcp_connected = req->selection_context.is_tcp_connected ? req->selection_context.is_tcp_connected(address) : false;
+ address_state->tcp_waiting = req->selection_context.is_tcp_waiting ? req->selection_context.is_tcp_waiting(address) : false;
+}
+#endif
+
+/**
+ * @internal Invalidate address if the respective IP version is disabled.
+ */
+static void check_network_settings(struct address_state *address_state,
+ size_t address_len, bool no_ipv4, bool no_ipv6)
+{
+ if (no_ipv4 && address_len == sizeof(struct in_addr)) {
+ address_state->generation = -1;
+ }
+ if (no_ipv6 && address_len == sizeof(struct in6_addr)) {
+ address_state->generation = -1;
+ }
+}
+
+void update_address_state(struct address_state *state, union kr_sockaddr *address,
+ size_t address_len, struct kr_query *qry)
+{
+ check_tls_capable(state, qry->request, &address->ip);
+ /* TODO: uncomment this once we actually use the information it collects
+ check_tcp_connections(address_state, qry->request, &address->ip);
+ */
+ check_network_settings(state, address_len, qry->flags.NO_IPV4,
+ qry->flags.NO_IPV6);
+ state->rtt_state =
+ get_rtt_state(ip_to_bytes(address, address_len),
+ address_len, &qry->request->ctx->cache);
+ invalidate_dead_upstream(
+ state, qry->request->ctx->cache_rtt_tout_retry_interval);
+#ifdef SELECTION_CHOICE_LOGGING
+ // This is sometimes useful for debugging, but usually too verbose
+ if (kr_log_is_debug_qry(SELECTION, qry)) {
+ const char *ns_str = kr_straddr(&address->ip);
+ VERBOSE_MSG(qry, "rtt of %s is %d, variance is %d\n", ns_str,
+ state->rtt_state.srtt, state->rtt_state.variance);
+ }
+#endif
+}
+
+static int cmp_choices(const struct choice *a_, const struct choice *b_)
+{
+ int diff;
+ /* Prefer IPv4 if IPv6 appears to be generally broken. */
+ diff = (int)a_->address_len - (int)b_->address_len;
+ if (diff && no6_is_bad()) {
+ return diff;
+ }
+ /* Address with no RTT information is better than address
+ * with some information. */
+ if ((diff = no_rtt_info(b_->address_state->rtt_state) -
+ no_rtt_info(a_->address_state->rtt_state))) {
+ return diff;
+ }
+ /* Address with less errors is better. */
+ if ((diff = a_->address_state->error_count -
+ b_->address_state->error_count)) {
+ return diff;
+ }
+ /* Address with smaller expected timeout is better. */
+ if ((diff = calc_timeout(a_->address_state->rtt_state) -
+ calc_timeout(b_->address_state->rtt_state))) {
+ return diff;
+ }
+ return 0;
+}
+/** Select the best entry from choices[] according to cmp_choices() comparator.
+ *
+ * Ties are decided in an (almost) uniformly random fashion.
+ */
+static const struct choice * select_best(const struct choice choices[], int choices_len)
+{
+ /* Deciding ties: it's as-if each index carries one byte of randomness.
+ * Ties get decided by comparing that byte, and the byte itself
+ * is computed lazily (negative until computed).
+ */
+ int best_i = 0;
+ int best_rnd = -1;
+ for (int i = 1; i < choices_len; ++i) {
+ int diff = cmp_choices(&choices[i], &choices[best_i]);
+ if (diff > 0)
+ continue;
+ if (diff < 0) {
+ best_i = i;
+ best_rnd = -1;
+ continue;
+ }
+ if (best_rnd < 0)
+ best_rnd = kr_rand_bytes(1);
+ int new_rnd = kr_rand_bytes(1);
+ if (new_rnd < best_rnd) {
+ best_i = i;
+ best_rnd = new_rnd;
+ }
+ }
+ return &choices[best_i];
+}
+
+/* Adjust choice from `unresolved` in case of NO6 (broken IPv6). */
+static struct kr_transport unresolved_adjust(const struct to_resolve unresolved[],
+ int unresolved_len, int index)
+{
+ if (unresolved[index].type != KR_TRANSPORT_RESOLVE_AAAA || !no6_is_bad())
+ goto finish;
+ /* AAAA is detected as bad; let's choose randomly from others, if there are any. */
+ int aaaa_count = 0;
+ for (int i = 0; i < unresolved_len; ++i)
+ aaaa_count += (unresolved[i].type == KR_TRANSPORT_RESOLVE_AAAA);
+ if (aaaa_count == unresolved_len)
+ goto finish;
+ /* Chosen index within non-AAAA items. */
+ int i_no6 = kr_rand_bytes(1) % (unresolved_len - aaaa_count);
+ for (int i = 0; i < unresolved_len; ++i) {
+ if (unresolved[i].type == KR_TRANSPORT_RESOLVE_AAAA) {
+ //continue
+ } else if (i_no6 == 0) {
+ index = i;
+ break;
+ } else {
+ --i_no6;
+ }
+ }
+finish:
+ return (struct kr_transport){
+ .protocol = unresolved[index].type,
+ .ns_name = unresolved[index].name
+ };
+}
+
+/* Performs the actual selection (currently variation on epsilon-greedy). */
+struct kr_transport *select_transport(const struct choice choices[], int choices_len,
+ const struct to_resolve unresolved[],
+ int unresolved_len, int timeouts,
+ struct knot_mm *mempool, bool tcp,
+ size_t *choice_index)
+{
+ if (!choices_len && !unresolved_len) {
+ /* There is nothing to choose from */
+ return NULL;
+ }
+
+ struct kr_transport *transport = mm_calloc(mempool, 1, sizeof(*transport));
+
+ /* If there are some addresses with no rtt_info we try them
+ * first (see cmp_choices). So unknown servers are chosen
+ * *before* the best know server. This ensures that every option
+ * is tried before going back to some that was tried before. */
+ const struct choice *best = select_best(choices, choices_len);
+ const struct choice *chosen;
+
+ const bool explore = choices_len == 0 || kr_rand_coin(EPSILON_NOMIN, EPSILON_DENOM)
+ /* We may need to explore to get at least one A record. */
+ || (no6_is_bad() && best->address.ip.sa_family == AF_INET6);
+ if (explore) {
+ /* "EXPLORE":
+ * randomly choose some option
+ * (including resolution of some new name). */
+ int index = kr_rand_bytes(1) % (choices_len + unresolved_len);
+ if (index < unresolved_len) {
+ // We will resolve a new NS name
+ *transport = unresolved_adjust(unresolved, unresolved_len, index);
+ return transport;
+ } else {
+ chosen = &choices[index - unresolved_len];
+ }
+ } else {
+ /* "EXPLOIT":
+ * choose a resolved address which seems best right now. */
+ chosen = best;
+ }
+
+ /* Don't try the same server again when there are other choices to be explored */
+ if (chosen->address_state->error_count && unresolved_len) {
+ int index = kr_rand_bytes(1) % unresolved_len;
+ *transport = unresolved_adjust(unresolved, unresolved_len, index);
+ return transport;
+ }
+
+ unsigned timeout;
+ if (no_rtt_info(chosen->address_state->rtt_state)) {
+ /* Exponential back-off when retrying after timeout and choosing
+ * an unknown server. */
+ timeout = back_off_timeout(DEFAULT_TIMEOUT, timeouts);
+ } else {
+ timeout = calc_timeout(chosen->address_state->rtt_state);
+ if (explore) {
+ /* When trying a random server, we cap the timeout to EXPLORE_TIMEOUT_COEFFICIENT
+ * times the timeout for the best server. This is done so we don't spend
+ * unreasonable amounts of time probing really bad servers while still
+ * checking once in a while for e.g. big network change etc.
+ * We also note this capping was done and don't punish the bad server
+ * further if it fails to answer in the capped timeout. */
+ unsigned best_timeout = calc_timeout(best->address_state->rtt_state);
+ if (timeout > best_timeout * EXPLORE_TIMEOUT_COEFFICIENT) {
+ timeout = best_timeout * EXPLORE_TIMEOUT_COEFFICIENT;
+ transport->timeout_capped = true;
+ }
+ }
+ }
+
+ enum kr_transport_protocol protocol;
+ if (chosen->address_state->tls_capable) {
+ protocol = KR_TRANSPORT_TLS;
+ } else if (tcp ||
+ chosen->address_state->errors[KR_SELECTION_QUERY_TIMEOUT] >= TCP_TIMEOUT_THRESHOLD ||
+ timeout > TCP_RTT_THRESHOLD) {
+ protocol = KR_TRANSPORT_TCP;
+ } else {
+ protocol = KR_TRANSPORT_UDP;
+ }
+
+ *transport = (struct kr_transport){
+ .ns_name = chosen->address_state->ns_name,
+ .protocol = protocol,
+ .timeout = timeout,
+ };
+
+ int port = chosen->port;
+ if (!port) {
+ switch (transport->protocol) {
+ case KR_TRANSPORT_TLS:
+ port = KR_DNS_TLS_PORT;
+ break;
+ case KR_TRANSPORT_UDP:
+ case KR_TRANSPORT_TCP:
+ port = KR_DNS_PORT;
+ break;
+ default:
+ kr_assert(false);
+ return NULL;
+ }
+ }
+
+ switch (chosen->address_len)
+ {
+ case sizeof(struct in_addr):
+ transport->address.ip4 = chosen->address.ip4;
+ transport->address.ip4.sin_port = htons(port);
+ break;
+ case sizeof(struct in6_addr):
+ transport->address.ip6 = chosen->address.ip6;
+ transport->address.ip6.sin6_port = htons(port);
+ break;
+ default:
+ kr_assert(false);
+ return NULL;
+ }
+
+ transport->address_len = chosen->address_len;
+
+ if (choice_index) {
+ *choice_index = chosen->address_state->choice_array_index;
+ }
+
+ return transport;
+}
+
+void update_rtt(struct kr_query *qry, struct address_state *addr_state,
+ const struct kr_transport *transport, unsigned rtt)
+{
+ if (!transport || !addr_state) {
+ /* Answers from cache have NULL transport, ignore them. */
+ return;
+ }
+
+ struct kr_cache *cache = &qry->request->ctx->cache;
+
+ uint8_t *address = ip_to_bytes(&transport->address, transport->address_len);
+ /* This construct is a bit racy since the global state may change
+ * between calls to `get_rtt_state` and `put_rtt_state` but we don't
+ * care that much since it is rare and we only risk slightly suboptimal
+ * transport choice. */
+ struct rtt_state cur_rtt_state =
+ get_rtt_state(address, transport->address_len, cache);
+ struct rtt_state new_rtt_state = calc_rtt_state(cur_rtt_state, rtt);
+ put_rtt_state(address, transport->address_len, new_rtt_state, cache);
+
+ if (transport->address_len == sizeof(struct in6_addr))
+ no6_success(qry);
+
+ if (kr_log_is_debug_qry(SELECTION, qry)) {
+ KR_DNAME_GET_STR(ns_name, transport->ns_name);
+ KR_DNAME_GET_STR(zonecut_str, qry->zone_cut.name);
+ const char *ns_str = kr_straddr(&transport->address.ip);
+
+ VERBOSE_MSG(
+ qry,
+ "=> id: '%05u' updating: '%s'@'%s' zone cut: '%s'"
+ " with rtt %u to srtt: %d and variance: %d \n",
+ qry->id, ns_name, ns_str ? ns_str : "", zonecut_str,
+ rtt, new_rtt_state.srtt, new_rtt_state.variance);
+ }
+}
+
+/// Update rtt_state (including caching) after a server timed out.
+static void server_timeout(const struct kr_query *qry, const struct kr_transport *transport,
+ struct address_state *addr_state, struct kr_cache *cache)
+{
+ // Make sure that the timeout wasn't capped; see kr_transport::timeout_capped
+ if (transport->timeout_capped)
+ return;
+
+ const uint8_t *address = ip_to_bytes(&transport->address, transport->address_len);
+ if (transport->address_len == sizeof(struct in6_addr))
+ no6_timed_out(qry, address);
+
+ struct rtt_state *state = &addr_state->rtt_state;
+ // While we were waiting for timeout, the stats might have changed considerably,
+ // so let's overwrite what we had by fresh cache contents.
+ // This is useful when the address is busy (we query it concurrently).
+ *state = get_rtt_state(address, transport->address_len, cache);
+
+ ++state->consecutive_timeouts;
+ // Avoid overflow; we don't utilize very high values anyway (arbitrary limit).
+ state->consecutive_timeouts = MIN(64, state->consecutive_timeouts);
+ if (state->consecutive_timeouts >= KR_NS_TIMEOUT_ROW_DEAD) {
+ // Only mark as dead if we waited long enough,
+ // so that many (concurrent) short attempts can't cause the dead state.
+ if (transport->timeout >= KR_NS_TIMEOUT_MIN_DEAD_TIMEOUT)
+ state->dead_since = kr_now();
+ }
+
+ // If transport was chosen by a different query, that one will cache it.
+ if (!transport->deduplicated) {
+ put_rtt_state(address, transport->address_len, *state, cache);
+ } else {
+ kr_cache_commit(cache); // Avoid any risk of long transaction.
+ }
+}
+// Not everything can be checked in nice ways like static_assert()
+static __attribute__((constructor)) void test_RTT_consts(void)
+{
+ // See KR_NS_TIMEOUT_MIN_DEAD_TIMEOUT above.
+ kr_require(
+ calc_timeout((struct rtt_state){ .consecutive_timeouts = MAX_BACKOFF, })
+ >= KR_NS_TIMEOUT_MIN_DEAD_TIMEOUT
+ );
+}
+
+void error(struct kr_query *qry, struct address_state *addr_state,
+ const struct kr_transport *transport,
+ enum kr_selection_error sel_error)
+{
+ if (!transport || !addr_state) {
+ /* Answers from cache have NULL transport, ignore them. */
+ return;
+ }
+
+ switch (sel_error) {
+ case KR_SELECTION_OK:
+ return;
+ case KR_SELECTION_TCP_CONNECT_FAILED:
+ case KR_SELECTION_TCP_CONNECT_TIMEOUT:
+ qry->server_selection.local_state->force_udp = true;
+ qry->flags.NO_0X20 = false;
+ /* Connection and handshake failures have properties similar
+ * to UDP timeouts, so we handle them (almost) the same way. */
+ /* fall-through */
+ case KR_SELECTION_TLS_HANDSHAKE_FAILED:
+ case KR_SELECTION_QUERY_TIMEOUT:
+ qry->server_selection.local_state->timeouts++;
+ server_timeout(qry, transport, addr_state, &qry->request->ctx->cache);
+ break;
+ case KR_SELECTION_FORMERR:
+ if (qry->flags.NO_EDNS) {
+ addr_state->broken = true;
+ } else {
+ qry->flags.NO_EDNS = true;
+ }
+ break;
+ case KR_SELECTION_FORMERR_EDNS:
+ addr_state->broken = true;
+ break;
+ case KR_SELECTION_MISMATCHED:
+ if (qry->flags.NO_0X20 && qry->flags.TCP) {
+ addr_state->broken = true;
+ } else {
+ qry->flags.TCP = true;
+ qry->flags.NO_0X20 = true;
+ }
+ break;
+ case KR_SELECTION_TRUNCATED:
+ if (transport->protocol == KR_TRANSPORT_UDP) {
+ qry->server_selection.local_state->truncated = true;
+ /* TC=1 over UDP is not an error, so we compensate. */
+ addr_state->error_count--;
+ } else {
+ addr_state->broken = true;
+ }
+ break;
+ case KR_SELECTION_REFUSED:
+ case KR_SELECTION_SERVFAIL:
+ if (qry->flags.NO_MINIMIZE && qry->flags.NO_0X20 && qry->flags.TCP) {
+ addr_state->broken = true;
+ } else if (qry->flags.NO_MINIMIZE) {
+ qry->flags.NO_0X20 = true;
+ qry->flags.TCP = true;
+ } else {
+ qry->flags.NO_MINIMIZE = true;
+ }
+ break;
+ case KR_SELECTION_LAME_DELEGATION:
+ if (qry->flags.NO_MINIMIZE) {
+ /* Lame delegations are weird, they breed more lame delegations on broken
+ * zones since trying another server from the same set usually doesn't help.
+ * We force resolution of another NS name in hope of getting somewhere. */
+ qry->server_selection.local_state->force_resolve = true;
+ addr_state->broken = true;
+ } else {
+ qry->flags.NO_MINIMIZE = true;
+ }
+ break;
+ case KR_SELECTION_NOTIMPL:
+ case KR_SELECTION_OTHER_RCODE:
+ case KR_SELECTION_DNSSEC_ERROR:
+ case KR_SELECTION_BAD_CNAME:
+ case KR_SELECTION_MALFORMED:
+ /* These errors are fatal, no point in trying this server again. */
+ addr_state->broken = true;
+ break;
+ default:
+ kr_assert(false);
+ return;
+ }
+
+ addr_state->error_count++;
+ addr_state->errors[sel_error]++;
+
+ if (kr_log_is_debug_qry(SELECTION, qry)) {
+ KR_DNAME_GET_STR(ns_name, transport->ns_name);
+ KR_DNAME_GET_STR(zonecut_str, qry->zone_cut.name);
+ const char *ns_str = kr_straddr(&transport->address.ip);
+ const char *err_str = kr_selection_error_str(sel_error);
+
+ VERBOSE_MSG(
+ qry,
+ "=> id: '%05u' noting selection error: '%s'@'%s'"
+ " zone cut: '%s' error: %d %s\n",
+ qry->id, ns_name, ns_str ? ns_str : "",
+ zonecut_str, sel_error, err_str ? err_str : "??");
+ }
+}
+
+void kr_server_selection_init(struct kr_query *qry)
+{
+ struct knot_mm *mempool = &qry->request->pool;
+ struct local_state *local_state = mm_calloc(mempool, 1, sizeof(*local_state));
+
+ if (qry->flags.FORWARD || qry->flags.STUB) {
+ qry->server_selection = (struct kr_server_selection){
+ .initialized = true,
+ .choose_transport = forward_choose_transport,
+ .update_rtt = forward_update_rtt,
+ .error = forward_error,
+ .local_state = local_state,
+ };
+ forward_local_state_alloc(
+ mempool, &qry->server_selection.local_state->private,
+ qry->request);
+ } else {
+ qry->server_selection = (struct kr_server_selection){
+ .initialized = true,
+ .choose_transport = iter_choose_transport,
+ .update_rtt = iter_update_rtt,
+ .error = iter_error,
+ .local_state = local_state,
+ };
+ iter_local_state_alloc(
+ mempool, &qry->server_selection.local_state->private);
+ }
+}
+
+int kr_forward_add_target(struct kr_request *req, const struct sockaddr *sock)
+{
+ if (!req->selection_context.forwarding_targets.at) {
+ return kr_error(EINVAL);
+ }
+
+ union kr_sockaddr address;
+
+ switch (sock->sa_family) {
+ case AF_INET:
+ if (req->options.NO_IPV4)
+ return kr_error(EINVAL);
+ address.ip4 = *(const struct sockaddr_in *)sock;
+ break;
+ case AF_INET6:
+ if (req->options.NO_IPV6)
+ return kr_error(EINVAL);
+ address.ip6 = *(const struct sockaddr_in6 *)sock;
+ break;
+ default:
+ return kr_error(EINVAL);
+ }
+
+ array_push_mm(req->selection_context.forwarding_targets, address,
+ kr_memreserve, &req->pool);
+ return kr_ok();
+}
diff --git a/lib/selection.h b/lib/selection.h
new file mode 100644
index 0000000..34cc69c
--- /dev/null
+++ b/lib/selection.h
@@ -0,0 +1,269 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+/**
+ * @file selection.h
+ * Provides server selection API (see `kr_server_selection`)
+ * and functions common to both implementations.
+ */
+
+#include "lib/cache/api.h"
+
+/* After KR_NS_TIMEOUT_ROW_DEAD consecutive timeouts
+ * where at least one was over KR_NS_TIMEOUT_MIN_DEAD_TIMEOUT ms,
+ * we consider the upstream IP dead for KR_NS_TIMEOUT_RETRY_INTERVAL ms */
+#define KR_NS_TIMEOUT_ROW_DEAD 4
+#define KR_NS_TIMEOUT_MIN_DEAD_TIMEOUT 800 /* == DEFAULT_TIMEOUT * 2 */
+#define KR_NS_TIMEOUT_RETRY_INTERVAL 1000
+
+/**
+ * These errors are to be reported as feedback to server selection.
+ * See `kr_server_selection::error` for more details.
+ */
+enum kr_selection_error {
+ KR_SELECTION_OK = 0,
+
+ // Network errors
+ KR_SELECTION_QUERY_TIMEOUT,
+ KR_SELECTION_TLS_HANDSHAKE_FAILED,
+ KR_SELECTION_TCP_CONNECT_FAILED,
+ KR_SELECTION_TCP_CONNECT_TIMEOUT,
+
+ // RCODEs
+ KR_SELECTION_REFUSED,
+ KR_SELECTION_SERVFAIL,
+ KR_SELECTION_FORMERR, /// inside an answer without an OPT record
+ KR_SELECTION_FORMERR_EDNS, /// with an OPT record
+ KR_SELECTION_NOTIMPL,
+ KR_SELECTION_OTHER_RCODE,
+
+ // DNS errors
+ KR_SELECTION_MALFORMED,
+ /** Name or type mismatch. */
+ KR_SELECTION_MISMATCHED,
+ KR_SELECTION_TRUNCATED,
+ KR_SELECTION_DNSSEC_ERROR,
+ KR_SELECTION_LAME_DELEGATION,
+ /** Too long chain, or a cycle. */
+ KR_SELECTION_BAD_CNAME,
+
+ /** Leave this last, as it is used as array size. */
+ KR_SELECTION_NUMBER_OF_ERRORS
+};
+
+enum kr_transport_protocol {
+ /** Selected name with no IPv4 address, it has to be resolved first. */
+ KR_TRANSPORT_RESOLVE_A,
+ /** Selected name with no IPv6 address, it has to be resolved first. */
+ KR_TRANSPORT_RESOLVE_AAAA,
+ KR_TRANSPORT_UDP,
+ KR_TRANSPORT_TCP,
+ KR_TRANSPORT_TLS,
+};
+
+/**
+ * Output of the selection algorithm.
+ */
+struct kr_transport {
+ knot_dname_t *ns_name; /**< Set to "." for forwarding targets.*/
+ union kr_sockaddr address;
+ size_t address_len;
+ enum kr_transport_protocol protocol;
+ unsigned timeout; /**< Timeout in ms to be set for UDP transmission. */
+ /** Timeout was capped to a maximum value based on the other candidates
+ * when choosing this transport. The timeout therefore can be much lower
+ * than what we expect it to be. We basically probe the server for a sudden
+ * network change but we expect it to timeout in most cases. We have to keep
+ * this in mind when noting the timeout in cache. */
+ bool timeout_capped;
+ /** True iff transport was set in worker.c:subreq_finalize,
+ * that means it may be different from the one originally chosen one.*/
+ bool deduplicated;
+};
+
+struct local_state {
+ int timeouts; /**< Number of timeouts that occurred resolving this query.*/
+ bool truncated; /**< Query was truncated, switch to TCP. */
+ /** Force resolution of a new NS name (if possible)
+ * Done by selection.c:error in some cases. */
+ bool force_resolve;
+ /** Used to work around auths with broken TCP. */
+ bool force_udp;
+ void *private; /**< Inner state of the implementation.*/
+};
+
+/**
+ * Specifies a API for selecting transports and giving feedback on the choices.
+ *
+ * The function pointers are to be used throughout resolver when some information about
+ * the transport is obtained. E.g. RTT in `worker.c` or RCODE in `iterate.c`,…
+ */
+struct kr_server_selection {
+ bool initialized;
+ /**
+ * Puts a pointer to next transport of @p qry to @p transport .
+ *
+ * Allocates new kr_transport in request's mempool, chooses transport to be used for this query.
+ * Selection may fail, so @p transport can be set to NULL.
+ *
+ * @param transport to be filled with pointer to the chosen transport or NULL on failure
+ */
+ void (*choose_transport)(struct kr_query *qry,
+ struct kr_transport **transport);
+ /** Report back the RTT of network operation for transport in ms. */
+ void (*update_rtt)(struct kr_query *qry,
+ const struct kr_transport *transport, unsigned rtt);
+ /** Report back error encountered with the chosen transport. See `enum kr_selection` */
+ void (*error)(struct kr_query *qry,
+ const struct kr_transport *transport,
+ enum kr_selection_error error);
+
+ struct local_state *local_state;
+};
+
+/**
+ * @brief Initialize the server selection API for @p qry.
+ *
+ * The implementation is to be chosen based on qry->flags.
+ */
+KR_EXPORT
+void kr_server_selection_init(struct kr_query *qry);
+
+/**
+ * @brief Add forwarding target to request.
+ *
+ * This is exposed to Lua in order to add forwarding targets to request.
+ * These are then shared by all the queries in said request.
+ */
+KR_EXPORT
+int kr_forward_add_target(struct kr_request *req, const struct sockaddr *sock);
+
+
+
+
+
+/* Below are internal parts shared by ./selection_{forward,iter}.c */
+
+/**
+ * To be held per IP address in the global LMDB cache
+ */
+struct rtt_state {
+ int32_t srtt; /**< Smoothed RTT, i.e. an estimate of round-trip time. */
+ int32_t variance; /**< An estimate of RTT's standard derivation (not variance). */
+ /** Note: some TCP and TLS failures are also considered as timeouts. */
+ int32_t consecutive_timeouts;
+ /** Timestamp of pronouncing this IP bad based on KR_NS_TIMEOUT_ROW_DEAD */
+ uint64_t dead_since;
+};
+
+/**
+ * @brief To be held per IP address and locally "inside" query.
+ */
+struct address_state {
+ /** Used to distinguish old and valid records in local_state; -1 means unusable IP. */
+ unsigned int generation;
+ struct rtt_state rtt_state;
+ knot_dname_t *ns_name;
+ bool tls_capable : 1;
+ /* TODO: uncomment these once we actually use this information in selection
+ bool tcp_waiting : 1;
+ bool tcp_connected : 1;
+ */
+ int choice_array_index;
+ int error_count;
+ bool broken;
+ int errors[KR_SELECTION_NUMBER_OF_ERRORS];
+};
+
+/**
+ * @brief Array of these is one of inputs for the actual selection algorithm (`select_transport`)
+ */
+struct choice {
+ union kr_sockaddr address;
+ size_t address_len;
+ struct address_state *address_state;
+ /** used to overwrite the port number;
+ * if zero, `select_transport` determines it. */
+ uint16_t port;
+};
+
+/**
+ * @brief Array of these is description of names to be resolved (i.e. name without some address)
+ */
+struct to_resolve {
+ knot_dname_t *name;
+ /** Either KR_TRANSPORT_RESOLVE_A or KR_TRANSPORT_RESOLVE_AAAA is valid here. */
+ enum kr_transport_protocol type;
+};
+
+/**
+ * @brief Based on passed choices, choose the next transport.
+ *
+ * Common function to both implementations (iteration and forwarding).
+ * The `*_choose_transport` functions from `selection_*.h` preprocess the input for this one.
+ *
+ * @param choices Options to choose from, see struct above
+ * @param unresolved Array of names that can be resolved (i.e. no A/AAAA record)
+ * @param timeouts Number of timeouts that occurred in this query (used for exponential backoff)
+ * @param mempool Memory context of current request
+ * @param tcp Force TCP as transport protocol
+ * @param[out] choice_index Optionally index of the chosen transport in the @p choices array.
+ * @return Chosen transport (on mempool) or NULL when no choice is viable
+ */
+struct kr_transport *select_transport(const struct choice choices[], int choices_len,
+ const struct to_resolve unresolved[],
+ int unresolved_len, int timeouts,
+ struct knot_mm *mempool, bool tcp,
+ size_t *choice_index);
+
+/**
+ * Common part of RTT feedback mechanism. Notes RTT to global cache.
+ */
+void update_rtt(struct kr_query *qry, struct address_state *addr_state,
+ const struct kr_transport *transport, unsigned rtt);
+
+/**
+ * Common part of error feedback mechanism.
+ */
+void error(struct kr_query *qry, struct address_state *addr_state,
+ const struct kr_transport *transport,
+ enum kr_selection_error sel_error);
+
+/**
+ * Get RTT state from cache. Returns `default_rtt_state` on unknown addresses.
+ *
+ * Note that this opens a cache transaction which is usually closed by calling
+ * `put_rtt_state`, i.e. callee is responsible for its closing
+ * (e.g. calling kr_cache_commit).
+ */
+struct rtt_state get_rtt_state(const uint8_t *ip, size_t len,
+ struct kr_cache *cache);
+
+int put_rtt_state(const uint8_t *ip, size_t len, struct rtt_state state,
+ struct kr_cache *cache);
+
+/**
+ * @internal Helper function for conversion between different IP representations.
+ */
+void bytes_to_ip(uint8_t *bytes, size_t len, uint16_t port, union kr_sockaddr *dst);
+
+/**
+ * @internal Helper function for conversion between different IP representations.
+ */
+uint8_t *ip_to_bytes(const union kr_sockaddr *src, size_t len);
+
+/**
+ * @internal Fetch per-address information from various sources.
+ *
+ * Note that this opens a RO cache transaction; the callee is responsible
+ * for its closing not too long afterwards (e.g. calling kr_cache_commit).
+ */
+void update_address_state(struct address_state *state, union kr_sockaddr *address,
+ size_t address_len, struct kr_query *qry);
+
+/** @internal Return whether IPv6 is considered to be broken. */
+bool no6_is_bad(void);
+
diff --git a/lib/selection_forward.c b/lib/selection_forward.c
new file mode 100644
index 0000000..54f9a12
--- /dev/null
+++ b/lib/selection_forward.c
@@ -0,0 +1,136 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#include "lib/selection_forward.h"
+#include "lib/resolve.h"
+
+#define VERBOSE_MSG(qry, ...) kr_log_q((qry), SELECTION, __VA_ARGS__)
+
+#define FORWARDING_TIMEOUT 2000
+/* TODO: well, this is a bit hard; maybe we'd better have a different approach
+ * for estimating DEAD-ness for forwarding.
+ * Even ACKs on connections might be useful here. */
+static_assert(FORWARDING_TIMEOUT >= KR_NS_TIMEOUT_MIN_DEAD_TIMEOUT,
+ "Bad combination of NS selection limits.");
+
+struct forward_local_state {
+ kr_sockaddr_array_t *targets;
+ struct address_state *addr_states;
+ /** Index of last choice in the targets array, used for error reporting. */
+ size_t last_choice_index;
+};
+
+void forward_local_state_alloc(struct knot_mm *mm, void **local_state,
+ struct kr_request *req)
+{
+ kr_require(req->selection_context.forwarding_targets.at);
+ *local_state = mm_calloc(mm, 1, sizeof(struct forward_local_state));
+
+ struct forward_local_state *forward_state = *local_state;
+ forward_state->targets = &req->selection_context.forwarding_targets;
+
+ forward_state->addr_states = mm_calloc(mm, forward_state->targets->len,
+ sizeof(struct address_state));
+}
+
+void forward_choose_transport(struct kr_query *qry,
+ struct kr_transport **transport)
+{
+ struct forward_local_state *local_state =
+ qry->server_selection.local_state->private;
+ struct choice choices[local_state->targets->len];
+ int valid = 0;
+
+ for (int i = 0; i < local_state->targets->len; i++) {
+ union kr_sockaddr *address = &local_state->targets->at[i];
+ size_t addr_len;
+ uint16_t port;
+ switch (address->ip.sa_family) {
+ case AF_INET:
+ port = ntohs(address->ip4.sin_port);
+ addr_len = sizeof(struct in_addr);
+ break;
+ case AF_INET6:
+ port = ntohs(address->ip6.sin6_port);
+ addr_len = sizeof(struct in6_addr);
+ break;
+ default:
+ kr_assert(false);
+ *transport = NULL;
+ goto cleanup;
+ }
+
+ struct address_state *addr_state = &local_state->addr_states[i];
+ addr_state->ns_name = (knot_dname_t *)"";
+
+ update_address_state(addr_state, address, addr_len, qry);
+
+ if (addr_state->generation == -1) {
+ continue;
+ }
+ addr_state->choice_array_index = i;
+
+ choices[valid++] = (struct choice){
+ .address = *address,
+ .address_len = addr_len,
+ .address_state = addr_state,
+ .port = port,
+ };
+ }
+
+ bool tcp = qry->flags.TCP || qry->server_selection.local_state->truncated;
+ *transport =
+ select_transport(choices, valid, NULL, 0,
+ qry->server_selection.local_state->timeouts,
+ &qry->request->pool, tcp,
+ &local_state->last_choice_index);
+ if (*transport) {
+ /* Set static timeout for forwarding; there is no point in this
+ * being dynamic since the RTT of a packet to forwarding target
+ * says nothing about the network RTT of said target, since
+ * it is doing resolution upstream. */
+ (*transport)->timeout = FORWARDING_TIMEOUT;
+ /* Try to avoid TCP in STUB case. It seems better for common use cases. */
+ if (qry->flags.STUB && !tcp && (*transport)->protocol == KR_TRANSPORT_TCP)
+ (*transport)->protocol = KR_TRANSPORT_UDP;
+ /* We need to propagate this to flags since it's used in other
+ * parts of the resolver (e.g. logging and stats). */
+ qry->flags.TCP = (*transport)->protocol == KR_TRANSPORT_TCP
+ || (*transport)->protocol == KR_TRANSPORT_TLS;
+ }
+cleanup:
+ kr_cache_commit(&qry->request->ctx->cache);
+}
+
+void forward_error(struct kr_query *qry, const struct kr_transport *transport,
+ enum kr_selection_error sel_error)
+{
+ if (!qry->server_selection.initialized) {
+ return;
+ }
+ struct forward_local_state *local_state =
+ qry->server_selection.local_state->private;
+ struct address_state *addr_state =
+ &local_state->addr_states[local_state->last_choice_index];
+ error(qry, addr_state, transport, sel_error);
+}
+
+void forward_update_rtt(struct kr_query *qry,
+ const struct kr_transport *transport, unsigned rtt)
+{
+ if (!qry->server_selection.initialized) {
+ return;
+ }
+
+ if (!transport) {
+ return;
+ }
+
+ struct forward_local_state *local_state =
+ qry->server_selection.local_state->private;
+ struct address_state *addr_state =
+ &local_state->addr_states[local_state->last_choice_index];
+
+ update_rtt(qry, addr_state, transport, rtt);
+}
diff --git a/lib/selection_forward.h b/lib/selection_forward.h
new file mode 100644
index 0000000..0c48c40
--- /dev/null
+++ b/lib/selection_forward.h
@@ -0,0 +1,17 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#include "lib/selection.h"
+#include "lib/resolve.h"
+
+void forward_local_state_alloc(struct knot_mm *mm, void **local_state,
+ struct kr_request *req);
+void forward_choose_transport(struct kr_query *qry,
+ struct kr_transport **transport);
+void forward_error(struct kr_query *qry, const struct kr_transport *transport,
+ enum kr_selection_error sel_error);
+void forward_update_rtt(struct kr_query *qry,
+ const struct kr_transport *transport, unsigned rtt);
diff --git a/lib/selection_iter.c b/lib/selection_iter.c
new file mode 100644
index 0000000..5978278
--- /dev/null
+++ b/lib/selection_iter.c
@@ -0,0 +1,378 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#include "lib/selection_iter.h"
+#include "lib/selection.h"
+
+#include "lib/generic/trie.h"
+#include "lib/generic/pack.h"
+#include "lib/zonecut.h"
+#include "lib/resolve.h"
+
+#define VERBOSE_MSG(qry, ...) kr_log_q((qry), SELECTION, __VA_ARGS__)
+
+/// To be held per query and locally. Allocations are in the kr_request's mempool.
+struct iter_local_state {
+ trie_t *names; /// knot_dname_t -> struct iter_name_state *
+ trie_t *addresses; /// IP address -> struct address_state *
+ knot_dname_t *zonecut;
+ /** Used to distinguish old and valid records in tries. */
+ unsigned int generation;
+ enum kr_selection_error last_error;
+ unsigned int no_ns_addr_count;
+};
+
+enum record_state { RECORD_UNKNOWN, RECORD_RESOLVED, RECORD_TRIED };
+
+// To be held per NS name and locally
+struct iter_name_state {
+ unsigned int generation;
+ enum record_state a_state;
+ enum record_state aaaa_state;
+};
+
+void iter_local_state_alloc(struct knot_mm *mm, void **local_state)
+{
+ *local_state = mm_calloc(mm, 1, sizeof(struct iter_local_state));
+}
+
+static struct address_state *get_address_state(struct iter_local_state *local_state,
+ const struct kr_transport *transport)
+{
+ if (!transport) {
+ return NULL;
+ }
+
+ uint8_t *address = ip_to_bytes(&transport->address, transport->address_len);
+ trie_val_t *address_state = trie_get_try(local_state->addresses, (char *)address,
+ transport->address_len);
+ if (!address_state) {
+ kr_assert(transport->deduplicated);
+ /* Transport was chosen by a different query. */
+ return NULL;
+ }
+ return *address_state;
+}
+
+static void unpack_state_from_zonecut(struct iter_local_state *local_state,
+ struct kr_query *qry)
+{
+ struct kr_zonecut *zonecut = &qry->zone_cut;
+ struct knot_mm *mm = &qry->request->pool;
+
+ bool zcut_changed = false;
+ if (local_state->names == NULL || local_state->addresses == NULL) {
+ /* Local state initialization. */
+ memset(local_state, 0, sizeof(struct iter_local_state));
+ local_state->names = trie_create(mm);
+ local_state->addresses = trie_create(mm);
+ } else {
+ zcut_changed = !knot_dname_is_equal(zonecut->name, local_state->zonecut);
+ }
+ local_state->zonecut = zonecut->name;
+ local_state->generation++;
+
+ if (zcut_changed) {
+ local_state->no_ns_addr_count = 0;
+ }
+
+ trie_it_t *it;
+ const unsigned int current_generation = local_state->generation;
+
+ for (it = trie_it_begin(zonecut->nsset); !trie_it_finished(it); trie_it_next(it)) {
+ knot_dname_t *dname = (knot_dname_t *)trie_it_key(it, NULL);
+ pack_t *addresses = *trie_it_val(it);
+
+ trie_val_t *val = trie_get_ins(local_state->names, (char *)dname,
+ knot_dname_size(dname));
+ if (!*val) {
+ /* We encountered this name for the first time. */
+ *val = mm_calloc(mm, 1, sizeof(struct iter_name_state));
+ }
+ struct iter_name_state *name_state = *val;
+ name_state->generation = current_generation;
+
+ if (zcut_changed) {
+ /* Set name as unresolved as they might have fallen out
+ * of cache (TTL expired). */
+ name_state->a_state = RECORD_UNKNOWN;
+ name_state->aaaa_state = RECORD_UNKNOWN;
+ }
+
+ /* Iterate over all addresses of this NS (if any). */
+ for (uint8_t *obj = pack_head(*addresses); obj != pack_tail(*addresses);
+ obj = pack_obj_next(obj)) {
+ uint8_t *address = pack_obj_val(obj);
+ size_t address_len = pack_obj_len(obj);
+ trie_val_t *tval = trie_get_ins(local_state->addresses,
+ (char *)address,
+ address_len);
+ if (!*tval) {
+ /* We have have not seen this address before. */
+ *tval = mm_calloc(mm, 1, sizeof(struct address_state));
+ }
+ struct address_state *address_state = *tval;
+ address_state->generation = current_generation;
+ address_state->ns_name = dname;
+
+ if (address_len == sizeof(struct in_addr)) {
+ name_state->a_state = RECORD_RESOLVED;
+ } else if (address_len == sizeof(struct in6_addr)) {
+ name_state->aaaa_state = RECORD_RESOLVED;
+ }
+ union kr_sockaddr tmp_address;
+ bytes_to_ip(address, address_len, 0, &tmp_address);
+ update_address_state(address_state, &tmp_address, address_len, qry);
+ }
+ }
+ trie_it_free(it);
+ kr_cache_commit(&qry->request->ctx->cache);
+}
+
+static int get_valid_addresses(struct iter_local_state *local_state,
+ struct choice choices[])
+{
+ unsigned count = 0;
+ trie_it_t *it;
+ for (it = trie_it_begin(local_state->addresses); !trie_it_finished(it);
+ trie_it_next(it)) {
+ size_t address_len;
+ uint8_t *address = (uint8_t *)trie_it_key(it, &address_len);
+ struct address_state *address_state = *trie_it_val(it);
+ if (address_state->generation == local_state->generation &&
+ !address_state->broken) {
+ choices[count] = (struct choice){
+ .address_len = address_len,
+ .address_state = address_state,
+ };
+ bytes_to_ip(address, address_len, 0, &choices[count].address);
+ count++;
+ }
+ }
+ trie_it_free(it);
+ return count;
+}
+
+static int get_resolvable_names(struct iter_local_state *local_state,
+ struct to_resolve resolvable[], struct kr_query *qry)
+{
+ /* Further resolution is not possible until we get `. DNSKEY` record;
+ * we have to choose one of the known addresses here. */
+ if (qry->sname[0] == '\0' && qry->stype == KNOT_RRTYPE_DNSKEY) {
+ return 0;
+ }
+
+ unsigned count = 0;
+ trie_it_t *it;
+ for (it = trie_it_begin(local_state->names); !trie_it_finished(it);
+ trie_it_next(it)) {
+ struct iter_name_state *name_state = *trie_it_val(it);
+ if (name_state->generation != local_state->generation)
+ continue;
+
+ knot_dname_t *name = (knot_dname_t *)trie_it_key(it, NULL);
+ if (qry->stype == KNOT_RRTYPE_DNSKEY &&
+ knot_dname_in_bailiwick(name, qry->sname) > 0) {
+ /* Resolving `domain. DNSKEY` can't trigger the
+ * resolution of `sub.domain. A/AAAA` since it
+ * will cause a cycle. */
+ continue;
+ }
+
+ /* FIXME: kr_rplan_satisfies(qry,…) should have been here, but this leads to failures on
+ * iter_ns_badip.rpl, this is because the test requires the resolver to switch to parent
+ * side after a record in cache expires. Only way to do this in the current zonecut setup is
+ * to requery the same query twice in the row. So we have to allow that and only check the
+ * rplan from parent upwards.
+ */
+ bool a_in_rplan = kr_rplan_satisfies(qry->parent, name,
+ KNOT_CLASS_IN, KNOT_RRTYPE_A);
+ bool aaaa_in_rplan = kr_rplan_satisfies(qry->parent, name,
+ KNOT_CLASS_IN, KNOT_RRTYPE_AAAA);
+
+ if (name_state->a_state == RECORD_UNKNOWN &&
+ !qry->flags.NO_IPV4 && !a_in_rplan) {
+ resolvable[count++] = (struct to_resolve){
+ name, KR_TRANSPORT_RESOLVE_A
+ };
+ }
+
+ if (name_state->aaaa_state == RECORD_UNKNOWN &&
+ !qry->flags.NO_IPV6 && !aaaa_in_rplan) {
+ resolvable[count++] = (struct to_resolve){
+ name, KR_TRANSPORT_RESOLVE_AAAA
+ };
+ }
+ }
+ trie_it_free(it);
+ return count;
+}
+
+static void update_name_state(knot_dname_t *name, enum kr_transport_protocol type,
+ trie_t *names)
+{
+ size_t name_len = knot_dname_size(name);
+ trie_val_t *val = trie_get_try(names, (char *)name, name_len);
+
+ if (!val) {
+ return;
+ }
+
+ struct iter_name_state *name_state = (struct iter_name_state *)*val;
+ switch (type) {
+ case KR_TRANSPORT_RESOLVE_A:
+ name_state->a_state = RECORD_TRIED;
+ break;
+ case KR_TRANSPORT_RESOLVE_AAAA:
+ name_state->aaaa_state = RECORD_TRIED;
+ break;
+ default:
+ kr_assert(false);
+ }
+}
+
+void iter_choose_transport(struct kr_query *qry, struct kr_transport **transport)
+{
+ struct knot_mm *mempool = &qry->request->pool;
+ struct iter_local_state *local_state =
+ (struct iter_local_state *)
+ qry->server_selection.local_state->private;
+
+ unpack_state_from_zonecut(local_state, qry);
+
+ struct choice choices[trie_weight(local_state->addresses) + 1/*avoid 0*/];
+ /* We may try to resolve A and AAAA record for each name, so therefore
+ * 2*trie_weight(…) is here. */
+ struct to_resolve resolvable[2 * trie_weight(local_state->names)];
+
+ // Filter valid addresses and names from the tries
+ int choices_len = get_valid_addresses(local_state, choices);
+ int resolvable_len = get_resolvable_names(local_state, resolvable, qry);
+ bool * const force_resolve_p = &qry->server_selection.local_state->force_resolve;
+
+ // Print some stats into debug logs.
+ if (kr_log_is_debug_qry(SELECTION, qry)) {
+ int v4_choices = 0;
+ for (int i = 0; i < choices_len; ++i)
+ if (choices[i].address.ip.sa_family == AF_INET)
+ ++v4_choices;
+ int v4_resolvable = 0;
+ for (int i = 0; i < resolvable_len; ++i)
+ if (resolvable[i].type == KR_TRANSPORT_RESOLVE_A)
+ ++v4_resolvable;
+ VERBOSE_MSG(qry, "=> id: '%05u' choosing from addresses: %d v4 + %d v6; "
+ "names to resolve: %d v4 + %d v6; "
+ "force_resolve: %d; NO6: IPv6 is %s\n",
+ qry->id, v4_choices, choices_len - v4_choices,
+ v4_resolvable, resolvable_len - v4_resolvable,
+ (int)*force_resolve_p, no6_is_bad() ? "KO" : "OK");
+ }
+
+ if (*force_resolve_p && resolvable_len) {
+ choices_len = 0;
+ *force_resolve_p = false;
+ }
+
+ bool tcp = qry->flags.TCP || qry->server_selection.local_state->truncated;
+ *transport = select_transport(choices, choices_len, resolvable, resolvable_len,
+ qry->server_selection.local_state->timeouts,
+ mempool, tcp, NULL);
+ bool nxnsattack_mitigation = false;
+
+ if (*transport) {
+ switch ((*transport)->protocol) {
+ case KR_TRANSPORT_RESOLVE_A:
+ case KR_TRANSPORT_RESOLVE_AAAA:
+ if (++local_state->no_ns_addr_count > KR_COUNT_NO_NSADDR_LIMIT) {
+ *transport = NULL;
+ nxnsattack_mitigation = true;
+ break;
+ }
+ /* Note that we tried resolving this name to not try it again. */
+ update_name_state((*transport)->ns_name, (*transport)->protocol, local_state->names);
+ break;
+ case KR_TRANSPORT_TLS:
+ case KR_TRANSPORT_TCP:
+ /* We need to propagate this to flags since it's used in
+ * other parts of the resolver. */
+ qry->flags.TCP = true;
+ case KR_TRANSPORT_UDP: /* fall through */
+ local_state->no_ns_addr_count = 0;
+ break;
+ default:
+ kr_assert(false);
+ break;
+ }
+
+ if (*transport &&
+ (*transport)->protocol == KR_TRANSPORT_TCP &&
+ !qry->server_selection.local_state->truncated &&
+ qry->server_selection.local_state->force_udp) {
+ // Last chance on broken TCP.
+ (*transport)->protocol = KR_TRANSPORT_UDP;
+ qry->flags.TCP = false;
+ }
+ }
+
+ if (*transport == NULL && local_state->last_error == KR_SELECTION_DNSSEC_ERROR) {
+ /* Last selected server had broken DNSSEC and now we have no more
+ * servers to ask. We signal this to the rest of resolver by
+ * setting DNSSEC_BOGUS flag. */
+ qry->flags.DNSSEC_BOGUS = true;
+ }
+
+ if (kr_log_is_debug_qry(SELECTION, qry))
+ {
+ KR_DNAME_GET_STR(zonecut_str, qry->zone_cut.name);
+ if (*transport) {
+ KR_DNAME_GET_STR(ns_name, (*transport)->ns_name);
+ const enum kr_transport_protocol proto = *transport ? (*transport)->protocol : -1;
+ const char *ns_str = kr_straddr(&(*transport)->address.ip);
+ const char *ip_version;
+ switch (proto)
+ {
+ case KR_TRANSPORT_RESOLVE_A:
+ case KR_TRANSPORT_RESOLVE_AAAA:
+ ip_version = (proto == KR_TRANSPORT_RESOLVE_A) ? "A" : "AAAA";
+ VERBOSE_MSG(qry, "=> id: '%05u' choosing to resolve %s: '%s' zone cut: '%s'\n",
+ qry->id, ip_version, ns_name, zonecut_str);
+ break;
+ default:
+ VERBOSE_MSG(qry, "=> id: '%05u' choosing: '%s'@'%s'"
+ " with timeout %u ms zone cut: '%s'\n",
+ qry->id, ns_name, ns_str ? ns_str : "",
+ (*transport)->timeout, zonecut_str);
+ break;
+ }
+ } else {
+ const char *nxns_msg = nxnsattack_mitigation
+ ? " (stopped due to mitigation for NXNSAttack CVE-2020-12667)" : "";
+ VERBOSE_MSG(qry, "=> id: '%05u' no suitable transport, zone cut: '%s'%s\n",
+ qry->id, zonecut_str, nxns_msg );
+ }
+ }
+}
+
+void iter_error(struct kr_query *qry, const struct kr_transport *transport,
+ enum kr_selection_error sel_error)
+{
+ if (!qry->server_selection.initialized) {
+ return;
+ }
+ struct iter_local_state *local_state = qry->server_selection.local_state->private;
+ struct address_state *addr_state = get_address_state(local_state, transport);
+ local_state->last_error = sel_error;
+ error(qry, addr_state, transport, sel_error);
+}
+
+void iter_update_rtt(struct kr_query *qry, const struct kr_transport *transport,
+ unsigned rtt)
+{
+ if (!qry->server_selection.initialized) {
+ return;
+ }
+ struct iter_local_state *local_state = qry->server_selection.local_state->private;
+ struct address_state *addr_state = get_address_state(local_state, transport);
+ update_rtt(qry, addr_state, transport, rtt);
+}
diff --git a/lib/selection_iter.h b/lib/selection_iter.h
new file mode 100644
index 0000000..692463c
--- /dev/null
+++ b/lib/selection_iter.h
@@ -0,0 +1,14 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#include "lib/selection.h"
+
+void iter_local_state_alloc(struct knot_mm *mm, void **local_state);
+void iter_choose_transport(struct kr_query *qry, struct kr_transport **transport);
+void iter_error(struct kr_query *qry, const struct kr_transport *transport,
+ enum kr_selection_error sel_error);
+void iter_update_rtt(struct kr_query *qry, const struct kr_transport *transport,
+ unsigned rtt);
diff --git a/lib/test_module.c b/lib/test_module.c
new file mode 100644
index 0000000..d7124c1
--- /dev/null
+++ b/lib/test_module.c
@@ -0,0 +1,39 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#include "tests/unit/test.h"
+#include "lib/module.h"
+
+static void test_module_params(void **state)
+{
+ struct kr_module module = { 0 };
+ assert_int_equal(kr_module_load(NULL, NULL, NULL), kr_error(EINVAL));
+ assert_int_equal(kr_module_load(&module, NULL, NULL), kr_error(EINVAL));
+ kr_module_unload(NULL);
+}
+
+static void test_module_builtin(void **state)
+{
+ struct kr_module module = { 0 };
+ assert_int_equal(kr_module_load(&module, "iterate", NULL), 0);
+ kr_module_unload(&module);
+}
+
+static void test_module_c(void **state)
+{
+ struct kr_module module = { 0 };
+ assert_int_equal(kr_module_load(&module, "mock_cmodule", "tests/unit"), 0);
+ kr_module_unload(&module);
+}
+
+int main(void)
+{
+ const UnitTest tests[] = {
+ unit_test(test_module_params),
+ unit_test(test_module_builtin),
+ unit_test(test_module_c),
+ };
+
+ return run_tests(tests);
+}
diff --git a/lib/test_rplan.c b/lib/test_rplan.c
new file mode 100644
index 0000000..12f4cc4
--- /dev/null
+++ b/lib/test_rplan.c
@@ -0,0 +1,75 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#include "tests/unit/test.h"
+#include "lib/resolve.h"
+#include "lib/rplan.h"
+
+static void test_rplan_params(void **state)
+{
+ /* NULL rplan */
+
+ assert_int_equal(kr_rplan_init(NULL, NULL, NULL), KNOT_EINVAL);
+ assert_null((void *)kr_rplan_push(NULL, NULL, NULL, 0, 0));
+ assert_int_equal(kr_rplan_pop(NULL, NULL), KNOT_EINVAL);
+ assert_true(kr_rplan_empty(NULL) == true);
+ kr_rplan_deinit(NULL);
+
+ /* NULL mandatory parameters */
+
+ struct kr_rplan rplan;
+ assert_int_equal(kr_rplan_init(&rplan, NULL, NULL), KNOT_EOK);
+ assert_null((void *)kr_rplan_push(&rplan, NULL, NULL, 0, 0));
+ assert_int_equal(kr_rplan_pop(&rplan, NULL), KNOT_EINVAL);
+ assert_true(kr_rplan_empty(&rplan) == true);
+ kr_rplan_deinit(&rplan);
+}
+
+static void test_rplan_push(void **state)
+{
+ knot_mm_t mm = { 0 };
+ test_mm_ctx_init(&mm);
+ struct kr_request request = {
+ .pool = mm,
+ .options = { 0 },
+ };
+
+ struct kr_rplan rplan;
+ kr_rplan_init(&rplan, &request, &mm);
+
+ /* Push query. */
+ assert_non_null((void *)kr_rplan_push(&rplan, NULL, (knot_dname_t *)"", 0, 0));
+
+ kr_rplan_deinit(&rplan);
+}
+
+/**
+ * Set and clear must not omit any bit, especially around byte boundaries.
+ */
+static void test_rplan_flags(void **state)
+{
+ static struct kr_qflags f1, f2, ones, zeros; /* static => initialized to zeroes */
+ assert_true(memcmp(&f1, &f2, sizeof(f1)) == 0); /* sanity check */
+ memset(&ones, 0xff, sizeof(ones)); /* all ones */
+
+ /* test set */
+ kr_qflags_set(&f1, ones);
+ assert_true(memcmp(&f1, &ones, sizeof(f1)) == 0); /* 1 == 1 */
+
+ /* test clear */
+ memset(&f2, 0xff, sizeof(f2)); /* all ones */
+ kr_qflags_clear(&f2, ones);
+ assert_true(memcmp(&f2, &zeros, sizeof(f1)) == 0); /* 0 == 0 */
+}
+
+int main(void)
+{
+ const UnitTest tests[] = {
+ unit_test(test_rplan_params),
+ unit_test(test_rplan_push),
+ unit_test(test_rplan_flags)
+ };
+
+ return run_tests(tests);
+}
diff --git a/lib/test_utils.c b/lib/test_utils.c
new file mode 100644
index 0000000..22f2483
--- /dev/null
+++ b/lib/test_utils.c
@@ -0,0 +1,147 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#include <sys/socket.h>
+#include <stdio.h>
+#include <contrib/cleanup.h>
+
+#include "tests/unit/test.h"
+#include "lib/utils.h"
+
+static void test_strcatdup(void **state)
+{
+ auto_free char *empty_res = kr_strcatdup(0);
+ assert_null(empty_res);
+
+ auto_free char *null_res = kr_strcatdup(1, NULL);
+ assert_null(null_res);
+
+ auto_free char *nullcat_res = kr_strcatdup(2, NULL, "beef");
+ assert_string_equal(nullcat_res, "beef");
+
+ auto_free char *multi_res = kr_strcatdup(3, "need", "beef", "dead");
+ assert_string_equal(multi_res, "needbeefdead");
+
+ /* Test fails if this leaks. */
+ auto_fclose FILE* null_file = fopen("/dev/null", "r");
+ (void)(null_file);
+
+ /* Test fails if this leaks. */
+ auto_close int null_sock = socket(AF_INET, SOCK_DGRAM, 0);
+ (void)(null_sock);
+}
+
+static inline int test_bitcmp(const char *subnet, const char *str_addr, size_t len)
+{
+ char addr_buf[16] = {'\0'};
+ kr_straddr_subnet(addr_buf, str_addr);
+ return kr_bitcmp(subnet, addr_buf, len);
+}
+
+static void test_straddr(void **state)
+{
+ const char *ip4_ok = "1.2.3.0/30";
+ const char *ip4_bad = "1.2.3.0/33";
+ const char *ip4_in = "1.2.3.1";
+ const char *ip4_out = "1.2.3.5";
+ const char *ip6_ok = "7caa::/4";
+ const char *ip6_bad = "7caa::/129";
+ const char *ip6_in = "7caa::aa7c";
+ const char *ip6_out = "8caa::aa7c";
+ /* Parsing family */
+ assert_int_equal(kr_straddr_family(ip4_ok), AF_INET);
+ assert_int_equal(kr_straddr_family(ip4_in), AF_INET);
+ assert_int_equal(kr_straddr_family(ip6_ok), AF_INET6);
+ assert_int_equal(kr_straddr_family(ip6_in), AF_INET6);
+ /* Parsing subnet */
+ char ip4_sub[4], ip6_sub[16];
+ assert_true(kr_straddr_subnet(ip4_sub, ip4_bad) < 0);
+ assert_int_equal(kr_straddr_subnet(ip4_sub, ip4_ok), 30);
+ assert_true(kr_straddr_subnet(ip6_sub, ip6_bad) < 0);
+ assert_int_equal(kr_straddr_subnet(ip6_sub, ip6_ok), 4);
+ /* Matching subnet */
+ assert_int_equal(test_bitcmp(ip4_sub, ip4_in, 30), 0);
+ assert_int_not_equal(test_bitcmp(ip4_sub, ip4_out, 30), 0);
+ assert_int_equal(test_bitcmp(ip6_sub, ip6_in, 4), 0);
+ assert_int_not_equal(test_bitcmp(ip6_sub, ip6_out, 4), 0);
+}
+
+static inline int assert_bitmask(const char *addr, const char *exp_masked)
+{
+ unsigned char addr_buf[16];
+ unsigned char exp_masked_buf[16];
+
+ int bits = kr_straddr_subnet(addr_buf, addr);
+ size_t addr_len = (kr_straddr_family(addr) == AF_INET6) ? 16 : 4;
+ int exp_masked_bits = kr_straddr_subnet(exp_masked_buf, exp_masked);
+ size_t exp_masked_len = (kr_straddr_family(exp_masked) == AF_INET6) ? 16 : 4;
+
+ /* sanity checks */
+ assert_true(bits >= 0);
+ assert_int_equal(addr_len, exp_masked_len);
+ assert_int_equal(exp_masked_bits, exp_masked_len * 8);
+
+ kr_bitmask(addr_buf, addr_len, bits);
+ return memcmp(addr_buf, exp_masked_buf, addr_len);
+}
+
+static void test_bitmask(void **state)
+{
+ assert_int_equal(assert_bitmask("10.0.1.5/32", "10.0.1.5"), 0);
+ assert_int_equal(assert_bitmask("10.0.1.5", "10.0.1.5"), 0);
+ assert_int_equal(assert_bitmask("10.0.1.5/24", "10.0.1.0"), 0);
+ assert_int_equal(assert_bitmask("128.30.1.16/16", "128.30.0.0"), 0);
+ assert_int_equal(assert_bitmask("255.255.255.255/20", "255.255.240.0"), 0);
+ assert_int_equal(assert_bitmask("255.255.255.255/22", "255.255.252.0"), 0);
+ assert_int_equal(assert_bitmask("192.168.0.1/0", "0.0.0.0"), 0);
+ assert_int_equal(assert_bitmask("7caa::/4", "7000::"), 0);
+ assert_int_equal(assert_bitmask("dead:beef::/16", "dead::"), 0);
+ assert_int_equal(assert_bitmask("dead:beef::/20", "dead:b000::"), 0);
+ assert_int_equal(assert_bitmask("dead:beef::/0", "::"), 0);
+ assert_int_equal(assert_bitmask("64aa:22fa:1378:aaaa:bbbb::/36", "64aa:22fa:1000::"), 0);
+}
+
+static void test_strptime_diff(void **state)
+{
+ char *format = "%Y-%m-%dT%H:%M:%S";
+ const char *errmsg = NULL;
+ double output;
+
+ errmsg = kr_strptime_diff(format,
+ "2019-01-09T12:06:04",
+ "2019-01-09T12:06:04", &output);
+ assert_true(errmsg == NULL);
+ /* double type -> equality is not reliable */
+ assert_true(output > -0.01 && output < 0.01);
+
+ errmsg = kr_strptime_diff(format,
+ "2019-01-09T12:06:04",
+ "2019-01-09T11:06:04", &output);
+ assert_true(errmsg == NULL);
+ /* double type -> equality is not reliable */
+ assert_true(output > -3600.01 && output < 3600.01);
+
+ /* invalid inputs */
+ errmsg = kr_strptime_diff(format,
+ "2019-01-09T25:06:04",
+ "2019-01-09T11:06:04", &output);
+ assert_true(errmsg != NULL);
+
+ errmsg = kr_strptime_diff("fail",
+ "2019-01-09T23:06:04",
+ "2019-01-09T11:06:04", &output);
+ assert_true(errmsg != NULL);
+}
+
+int main(void)
+{
+ const UnitTest tests[] = {
+ unit_test(test_strcatdup),
+ unit_test(test_straddr),
+ unit_test(test_bitmask),
+ unit_test(test_strptime_diff)
+ };
+
+ return run_tests(tests);
+}
diff --git a/lib/test_zonecut.c b/lib/test_zonecut.c
new file mode 100644
index 0000000..c039963
--- /dev/null
+++ b/lib/test_zonecut.c
@@ -0,0 +1,58 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#include <netinet/in.h>
+
+#include "tests/unit/test.h"
+#include "lib/zonecut.h"
+
+static void test_zonecut_params(void **state)
+{
+ /* NULL args */
+ struct kr_zonecut cut;
+ assert_int_not_equal(kr_zonecut_init(NULL, NULL, NULL), 0);
+ assert_int_not_equal(kr_zonecut_init(&cut, NULL, NULL), 0);
+ kr_zonecut_deinit(NULL);
+ kr_zonecut_set(NULL, NULL);
+ kr_zonecut_set(&cut, NULL);
+ /* TODO triggering inner assertion:
+ assert_int_not_equal(kr_zonecut_add(NULL, NULL, NULL, 0), 0);
+ */
+ assert_null((void *)kr_zonecut_find(NULL, NULL));
+ assert_null((void *)kr_zonecut_find(&cut, NULL));
+ assert_int_not_equal(kr_zonecut_set_sbelt(NULL, NULL), 0);
+ assert_int_not_equal(kr_zonecut_find_cached(NULL, NULL, NULL, 0, 0), 0);
+}
+
+static void test_zonecut_copy(void **state)
+{
+ const knot_dname_t *n_root = (const uint8_t *)"";
+ struct kr_zonecut cut1, cut2;
+ kr_zonecut_init(&cut1, n_root, NULL);
+ kr_zonecut_init(&cut2, n_root, NULL);
+ /* Insert some values */
+ const knot_dname_t
+ *n_1 = (const uint8_t *)"\4dead",
+ *n_2 = (const uint8_t *)"\3bee\1f";
+ assert_int_equal(kr_zonecut_add(&cut1, n_1, NULL, 0), 0);
+ assert_int_equal(kr_zonecut_add(&cut1, n_2, NULL, 0), 0);
+ /* Copy */
+ assert_int_equal(kr_zonecut_copy(&cut2, &cut1), 0);
+ /* Check if exist */
+ assert_non_null(kr_zonecut_find(&cut2, n_1));
+ assert_non_null(kr_zonecut_find(&cut2, n_2));
+ assert_null(kr_zonecut_find(&cut2, (const uint8_t *)"\5death"));
+ kr_zonecut_deinit(&cut1);
+ kr_zonecut_deinit(&cut2);
+}
+
+int main(void)
+{
+ const UnitTest tests[] = {
+ unit_test(test_zonecut_params),
+ unit_test(test_zonecut_copy)
+ };
+
+ return run_tests(tests);
+}
diff --git a/lib/utils.c b/lib/utils.c
new file mode 100644
index 0000000..c1b25db
--- /dev/null
+++ b/lib/utils.c
@@ -0,0 +1,1393 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#include "lib/utils.h"
+
+#include "contrib/cleanup.h"
+#include "contrib/ucw/mempool.h"
+#include "kresconfig.h"
+#include "lib/defines.h"
+#include "lib/generic/array.h"
+#include "lib/module.h"
+#include "lib/resolve.h"
+
+#include <libknot/descriptor.h>
+#include <libknot/dname.h>
+#include <libknot/rrset-dump.h>
+#include <libknot/rrtype/rrsig.h>
+#include <libknot/version.h>
+#include <uv.h>
+
+#include <arpa/inet.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+#include <sys/statvfs.h>
+#include <sys/un.h>
+
+struct __attribute__((packed)) kr_sockaddr_key {
+ int family;
+};
+
+struct __attribute__((packed)) kr_sockaddr_in_key {
+ int family;
+ char address[sizeof(((struct sockaddr_in *) NULL)->sin_addr)];
+ uint16_t port;
+};
+
+struct __attribute__((packed)) kr_sockaddr_in6_key {
+ int family;
+ char address[sizeof(((struct sockaddr_in6 *) NULL)->sin6_addr)];
+ uint32_t scope;
+ uint16_t port;
+};
+
+struct __attribute((packed)) kr_sockaddr_un_key {
+ int family;
+ char path[sizeof(((struct sockaddr_un *) NULL)->sun_path)];
+};
+
+extern inline uint64_t kr_rand_bytes(unsigned int size);
+
+/* Logging & debugging */
+bool kr_dbg_assertion_abort = DBG_ASSERTION_ABORT;
+int kr_dbg_assertion_fork = DBG_ASSERTION_FORK;
+
+void kr_fail(bool is_fatal, const char *expr, const char *func, const char *file, int line)
+{
+ const int errno_orig = errno;
+ if (is_fatal)
+ kr_log_crit(SYSTEM, "requirement \"%s\" failed in %s@%s:%d\n", expr, func, file, line);
+ else
+ kr_log_error(SYSTEM, "assertion \"%s\" failed in %s@%s:%d\n", expr, func, file, line);
+
+ if (is_fatal || (kr_dbg_assertion_abort && !kr_dbg_assertion_fork))
+ abort();
+ else if (!kr_dbg_assertion_abort || !kr_dbg_assertion_fork)
+ goto recover;
+ // We want to fork and abort the child, unless rate-limited.
+ static uint64_t limited_until = 0;
+ const uint64_t now = kr_now();
+ if (now < limited_until)
+ goto recover;
+ if (kr_dbg_assertion_fork > 0) {
+ // Add jitter +- 25%; in other words: 75% + uniform(0,50%).
+ // Motivation: if a persistent problem starts happening, desynchronize
+ // coredumps from different instances as they're not cheap.
+ limited_until = now + kr_dbg_assertion_fork * 3 / 4
+ + kr_dbg_assertion_fork * kr_rand_bytes(1) / 256 / 2;
+ }
+ if (fork() == 0)
+ abort();
+recover:
+ errno = errno_orig;
+}
+
+/*
+ * Macros.
+ */
+#define strlen_safe(x) ((x) ? strlen(x) : 0)
+
+/**
+ * @internal Convert 16bit unsigned to string, keeps leading spaces.
+ * @note Always fills dst length = 5
+ * Credit: http://computer-programming-forum.com/46-asm/7aa4b50bce8dd985.htm
+ */
+static inline int u16tostr(uint8_t *dst, uint16_t num)
+{
+ uint32_t tmp = num * (((1 << 28) / 10000) + 1) - (num / 4);
+ for(size_t i = 0; i < 5; i++) {
+ dst[i] = '0' + (char) (tmp >> 28);
+ tmp = (tmp & 0x0fffffff) * 10;
+ }
+ return 5;
+}
+
+char* kr_strcatdup(unsigned n, ...)
+{
+ if (n < 1) {
+ return NULL;
+ }
+
+ /* Calculate total length */
+ size_t total_len = 0;
+ va_list vl;
+ va_start(vl, n);
+ for (unsigned i = 0; i < n; ++i) {
+ char *item = va_arg(vl, char *);
+ const size_t new_len = total_len + strlen_safe(item);
+ if (unlikely(new_len < total_len)) {
+ va_end(vl);
+ return NULL;
+ }
+ total_len = new_len;
+ }
+ va_end(vl);
+
+ /* Allocate result and fill */
+ char *result = NULL;
+ if (total_len > 0) {
+ if (unlikely(total_len == SIZE_MAX)) return NULL;
+ result = malloc(total_len + 1);
+ }
+ if (result) {
+ char *stream = result;
+ va_start(vl, n);
+ for (unsigned i = 0; i < n; ++i) {
+ char *item = va_arg(vl, char *);
+ if (item) {
+ size_t len = strlen(item);
+ memcpy(stream, item, len + 1);
+ stream += len;
+ }
+ }
+ va_end(vl);
+ }
+
+ return result;
+}
+
+char * kr_absolutize_path(const char *dirname, const char *fname)
+{
+ if (kr_fails_assert(dirname && fname)) {
+ errno = EINVAL;
+ return NULL;
+ }
+ char *result;
+ int aret;
+ if (dirname[0] == '/') { // absolute path is easier
+ aret = asprintf(&result, "%s/%s", dirname, fname);
+ } else { // relative path, but don't resolve symlinks
+ char buf[PATH_MAX];
+ const char *cwd = getcwd(buf, sizeof(buf));
+ if (!cwd)
+ return NULL; // errno has been set already
+ if (strcmp(dirname, ".") == 0) {
+ // get rid of one common case of extraneous "./"
+ aret = asprintf(&result, "%s/%s", cwd, fname);
+ } else {
+ aret = asprintf(&result, "%s/%s/%s", cwd, dirname, fname);
+ }
+ }
+ if (aret > 0)
+ return result;
+ errno = -aret;
+ return NULL;
+}
+
+int kr_memreserve(void *baton, void **mem, size_t elm_size, size_t want, size_t *have)
+{
+ if (*have >= want) {
+ return 0;
+ } else {
+ knot_mm_t *pool = baton;
+ size_t next_size = array_next_count(elm_size, want, *have);
+ void *mem_new = mm_alloc(pool, next_size * elm_size);
+ if (mem_new != NULL) {
+ if (*mem) { /* 0-length memcpy from NULL isn't technically OK */
+ memcpy(mem_new, *mem, (*have)*(elm_size));
+ mm_free(pool, *mem);
+ }
+ *mem = mem_new;
+ *have = next_size;
+ return 0;
+ }
+ }
+ return -1;
+}
+
+static int pkt_recycle(knot_pkt_t *pkt, bool keep_question)
+{
+ /* The maximum size of a header + query name + (class, type) */
+ uint8_t buf[KNOT_WIRE_HEADER_SIZE + KNOT_DNAME_MAXLEN + 2 * sizeof(uint16_t)];
+
+ /* Save header and the question section */
+ size_t base_size = KNOT_WIRE_HEADER_SIZE;
+ if (keep_question) {
+ base_size += knot_pkt_question_size(pkt);
+ }
+ if (kr_fails_assert(base_size <= sizeof(buf))) return kr_error(EINVAL);
+ memcpy(buf, pkt->wire, base_size);
+
+ /* Clear the packet and its auxiliary structures */
+ knot_pkt_clear(pkt);
+
+ /* Restore header and question section and clear counters */
+ pkt->size = base_size;
+ memcpy(pkt->wire, buf, base_size);
+ knot_wire_set_qdcount(pkt->wire, keep_question);
+ knot_wire_set_ancount(pkt->wire, 0);
+ knot_wire_set_nscount(pkt->wire, 0);
+ knot_wire_set_arcount(pkt->wire, 0);
+
+ /* Reparse question */
+ knot_pkt_begin(pkt, KNOT_ANSWER);
+ return knot_pkt_parse_question(pkt);
+}
+
+int kr_pkt_recycle(knot_pkt_t *pkt)
+{
+ return pkt_recycle(pkt, false);
+}
+
+int kr_pkt_clear_payload(knot_pkt_t *pkt)
+{
+ return pkt_recycle(pkt, knot_wire_get_qdcount(pkt->wire));
+}
+
+int kr_pkt_put(knot_pkt_t *pkt, const knot_dname_t *name, uint32_t ttl,
+ uint16_t rclass, uint16_t rtype, const uint8_t *rdata, uint16_t rdlen)
+{
+ /* LATER(opt.): there's relatively lots of copying, but ATM kr_pkt_put()
+ * isn't considered to be used in any performance-critical parts (just lua). */
+ if (!pkt || !name) {
+ return kr_error(EINVAL);
+ }
+ /* Create empty RR */
+ knot_rrset_t rr;
+ knot_rrset_init(&rr, knot_dname_copy(name, &pkt->mm), rtype, rclass, ttl);
+ /* Create RDATA */
+ knot_rdata_t *rdata_tmp = mm_alloc(&pkt->mm, offsetof(knot_rdata_t, data) + rdlen);
+ knot_rdata_init(rdata_tmp, rdlen, rdata);
+ knot_rdataset_add(&rr.rrs, rdata_tmp, &pkt->mm);
+ mm_free(&pkt->mm, rdata_tmp); /* we're always on mempool for now, but whatever */
+ /* Append RR */
+ return knot_pkt_put(pkt, 0, &rr, KNOT_PF_FREE);
+}
+
+void kr_pkt_make_auth_header(knot_pkt_t *pkt)
+{
+ if (kr_fails_assert(pkt && pkt->wire)) return;
+ knot_wire_clear_ad(pkt->wire);
+ knot_wire_set_aa(pkt->wire);
+}
+
+const char *kr_inaddr(const struct sockaddr *addr)
+{
+ if (!addr) {
+ return NULL;
+ }
+ switch (addr->sa_family) {
+ case AF_INET: return (const char *)&(((const struct sockaddr_in *)addr)->sin_addr);
+ case AF_INET6: return (const char *)&(((const struct sockaddr_in6 *)addr)->sin6_addr);
+ default: return NULL;
+ }
+}
+
+int kr_inaddr_family(const struct sockaddr *addr)
+{
+ if (!addr)
+ return AF_UNSPEC;
+ return addr->sa_family;
+}
+
+int kr_inaddr_len(const struct sockaddr *addr)
+{
+ if (!addr) {
+ return kr_error(EINVAL);
+ }
+ return kr_family_len(addr->sa_family);
+}
+
+int kr_sockaddr_len(const struct sockaddr *addr)
+{
+ if (!addr) {
+ return kr_error(EINVAL);
+ }
+ switch (addr->sa_family) {
+ case AF_INET: return sizeof(struct sockaddr_in);
+ case AF_INET6: return sizeof(struct sockaddr_in6);
+ case AF_UNIX: return sizeof(struct sockaddr_un);
+ default: return kr_error(EINVAL);
+ }
+}
+
+ssize_t kr_sockaddr_key(struct kr_sockaddr_key_storage *dst,
+ const struct sockaddr *addr)
+{
+ kr_require(addr);
+
+ switch (addr->sa_family) {
+ case AF_INET:;
+ const struct sockaddr_in *addr_in = (const struct sockaddr_in *) addr;
+ struct kr_sockaddr_in_key *inkey = (struct kr_sockaddr_in_key *) dst;
+ inkey->family = AF_INET;
+ memcpy(&inkey->address, &addr_in->sin_addr, sizeof(inkey->address));
+ memcpy(&inkey->port, &addr_in->sin_port, sizeof(inkey->port));
+ return sizeof(*inkey);
+
+ case AF_INET6:;
+ const struct sockaddr_in6 *addr_in6 = (const struct sockaddr_in6 *) addr;
+ struct kr_sockaddr_in6_key *in6key = (struct kr_sockaddr_in6_key *) dst;
+ in6key->family = AF_INET6;
+ memcpy(&in6key->address, &addr_in6->sin6_addr, sizeof(in6key->address));
+ memcpy(&in6key->port, &addr_in6->sin6_port, sizeof(in6key->port));
+ if (kr_sockaddr_link_local(addr))
+ memcpy(&in6key->scope, &addr_in6->sin6_scope_id, sizeof(in6key->scope));
+ else
+ in6key->scope = 0;
+ return sizeof(*in6key);
+
+ case AF_UNIX:;
+ const struct sockaddr_un *addr_un = (const struct sockaddr_un *) addr;
+ struct kr_sockaddr_un_key *unkey = (struct kr_sockaddr_un_key *) dst;
+ unkey->family = AF_UNIX;
+ size_t pathlen = strnlen(addr_un->sun_path, sizeof(unkey->path));
+ if (pathlen == 0 || pathlen >= sizeof(unkey->path)) {
+ /* Abstract sockets are not supported - we would need
+ * to also supply a length value for the abstract
+ * pathname.
+ *
+ * UNIX socket path should be null-terminated.
+ *
+ * See unix(7). */
+ return kr_error(EINVAL);
+ }
+
+ pathlen += 1; /* Include null-terminator */
+ strncpy(unkey->path, addr_un->sun_path, pathlen);
+ return offsetof(struct kr_sockaddr_un_key, path) + pathlen;
+
+ default:
+ return kr_error(EAFNOSUPPORT);
+ }
+}
+
+struct sockaddr *kr_sockaddr_from_key(struct sockaddr_storage *dst,
+ const char *key)
+{
+ kr_require(key);
+
+ switch (((struct kr_sockaddr_key *) key)->family) {
+ case AF_INET:;
+ const struct kr_sockaddr_in_key *inkey = (struct kr_sockaddr_in_key *) key;
+ struct sockaddr_in *addr_in = (struct sockaddr_in *) dst;
+ addr_in->sin_family = AF_INET;
+ memcpy(&addr_in->sin_addr, &inkey->address, sizeof(inkey->address));
+ memcpy(&addr_in->sin_port, &inkey->port, sizeof(inkey->port));
+ return (struct sockaddr *) addr_in;
+
+ case AF_INET6:;
+ const struct kr_sockaddr_in6_key *in6key = (struct kr_sockaddr_in6_key *) key;
+ struct sockaddr_in6 *addr_in6 = (struct sockaddr_in6 *) dst;
+ addr_in6->sin6_family = AF_INET6;
+ memcpy(&addr_in6->sin6_addr, &in6key->address, sizeof(in6key->address));
+ memcpy(&addr_in6->sin6_port, &in6key->port, sizeof(in6key->port));
+ memcpy(&addr_in6->sin6_scope_id, &in6key->scope, sizeof(in6key->scope));
+ return (struct sockaddr *) addr_in6;
+
+ case AF_UNIX:;
+ const struct kr_sockaddr_un_key *unkey = (struct kr_sockaddr_un_key *) key;
+ struct sockaddr_un *addr_un = (struct sockaddr_un *) dst;
+ addr_un->sun_family = AF_UNIX;
+ strncpy(addr_un->sun_path, unkey->path, sizeof(unkey->path));
+ return (struct sockaddr *) addr_un;
+
+ default:
+ kr_assert(false);
+ return NULL;
+ }
+}
+
+bool kr_sockaddr_key_same_addr(const char *key_a, const char *key_b)
+{
+ const struct kr_sockaddr_in6_key *kkey_a = (struct kr_sockaddr_in6_key *) key_a;
+ const struct kr_sockaddr_in6_key *kkey_b = (struct kr_sockaddr_in6_key *) key_b;
+
+ if (kkey_a->family != kkey_b->family)
+ return false;
+
+ ptrdiff_t offset;
+ switch (kkey_a->family) {
+ case AF_INET:
+ offset = offsetof(struct kr_sockaddr_in_key, address);
+ break;
+ case AF_INET6:
+ if (unlikely(kkey_a->scope != kkey_b->scope))
+ return false;
+ offset = offsetof(struct kr_sockaddr_in6_key, address);
+ break;
+
+ case AF_UNIX:;
+ const struct kr_sockaddr_un_key *unkey_a =
+ (struct kr_sockaddr_un_key *) key_a;
+ const struct kr_sockaddr_un_key *unkey_b =
+ (struct kr_sockaddr_un_key *) key_b;
+
+ return strncmp(unkey_a->path, unkey_b->path,
+ sizeof(unkey_a->path)) == 0;
+
+ default:
+ kr_assert(false);
+ return false;
+ }
+
+ size_t len = kr_family_len(kkey_a->family);
+ return memcmp(key_a + offset, key_b + offset, len) == 0;
+}
+
+int kr_sockaddr_cmp(const struct sockaddr *left, const struct sockaddr *right)
+{
+ if (!left || !right) {
+ return kr_error(EINVAL);
+ }
+ if (left->sa_family != right->sa_family) {
+ return kr_error(EFAULT);
+ }
+ if (left->sa_family == AF_INET) {
+ struct sockaddr_in *left_in = (struct sockaddr_in *)left;
+ struct sockaddr_in *right_in = (struct sockaddr_in *)right;
+ if (left_in->sin_addr.s_addr != right_in->sin_addr.s_addr) {
+ return kr_error(EFAULT);
+ }
+ if (left_in->sin_port != right_in->sin_port) {
+ return kr_error(EFAULT);
+ }
+ } else if (left->sa_family == AF_INET6) {
+ struct sockaddr_in6 *left_in6 = (struct sockaddr_in6 *)left;
+ struct sockaddr_in6 *right_in6 = (struct sockaddr_in6 *)right;
+ if (memcmp(&left_in6->sin6_addr, &right_in6->sin6_addr,
+ sizeof(struct in6_addr)) != 0) {
+ return kr_error(EFAULT);
+ }
+ if (left_in6->sin6_port != right_in6->sin6_port) {
+ return kr_error(EFAULT);
+ }
+ } else {
+ return kr_error(ENOENT);
+ }
+ return kr_ok();
+}
+
+uint16_t kr_inaddr_port(const struct sockaddr *addr)
+{
+ if (!addr) {
+ return 0;
+ }
+ switch (addr->sa_family) {
+ case AF_INET: return ntohs(((const struct sockaddr_in *)addr)->sin_port);
+ case AF_INET6: return ntohs(((const struct sockaddr_in6 *)addr)->sin6_port);
+ default: return 0;
+ }
+}
+
+void kr_inaddr_set_port(struct sockaddr *addr, uint16_t port)
+{
+ if (!addr) {
+ return;
+ }
+ switch (addr->sa_family) {
+ case AF_INET:
+ ((struct sockaddr_in *)addr)->sin_port = htons(port);
+ break;
+ case AF_INET6:
+ ((struct sockaddr_in6 *)addr)->sin6_port = htons(port);
+ break;
+ default:
+ break;
+ }
+}
+
+int kr_inaddr_str(const struct sockaddr *addr, char *buf, size_t *buflen)
+{
+ if (!addr) {
+ return kr_error(EINVAL);
+ }
+ return kr_ntop_str(addr->sa_family, kr_inaddr(addr), kr_inaddr_port(addr),
+ buf, buflen);
+}
+
+int kr_ntop_str(int family, const void *src, uint16_t port, char *buf, size_t *buflen)
+{
+ if (!src || !buf || !buflen) {
+ return kr_error(EINVAL);
+ }
+
+ if (!inet_ntop(family, src, buf, *buflen)) {
+ return kr_error(errno);
+ }
+ const int len = strlen(buf);
+ const int len_need = len + 1 + 5 + 1;
+ if (len_need > *buflen) {
+ *buflen = len_need;
+ return kr_error(ENOSPC);
+ }
+ *buflen = len_need;
+ buf[len] = '#';
+ u16tostr((uint8_t *)&buf[len + 1], port);
+ buf[len_need - 1] = 0;
+ return kr_ok();
+}
+
+char *kr_straddr(const struct sockaddr *addr)
+{
+ if (kr_fails_assert(addr)) return NULL;
+ static char str[KR_STRADDR_MAXLEN + 1] = {0};
+ if (addr->sa_family == AF_UNIX) {
+ strncpy(str, ((struct sockaddr_un *)addr)->sun_path, sizeof(str) - 1);
+ return str;
+ }
+ size_t len = KR_STRADDR_MAXLEN;
+ int ret = kr_inaddr_str(addr, str, &len);
+ return ret != kr_ok() || len == 0 ? NULL : str;
+}
+
+int kr_straddr_family(const char *addr)
+{
+ if (!addr) {
+ return kr_error(EINVAL);
+ }
+ if (addr[0] == '/') {
+ return AF_UNIX;
+ }
+ if (strchr(addr, ':')) {
+ return AF_INET6;
+ }
+ if (strchr(addr, '.')) {
+ return AF_INET;
+ }
+ return kr_error(EINVAL);
+}
+
+int kr_family_len(int family)
+{
+ switch (family) {
+ case AF_INET: return sizeof(struct in_addr);
+ case AF_INET6: return sizeof(struct in6_addr);
+ default: return kr_error(EINVAL);
+ }
+}
+
+struct sockaddr * kr_straddr_socket(const char *addr, int port, knot_mm_t *pool)
+{
+ switch (kr_straddr_family(addr)) {
+ case AF_INET: {
+ struct sockaddr_in *res = mm_alloc(pool, sizeof(*res));
+ if (uv_ip4_addr(addr, port, res) >= 0) {
+ return (struct sockaddr *)res;
+ } else {
+ mm_free(pool, res);
+ return NULL;
+ }
+ }
+ case AF_INET6: {
+ struct sockaddr_in6 *res = mm_alloc(pool, sizeof(*res));
+ if (uv_ip6_addr(addr, port, res) >= 0) {
+ return (struct sockaddr *)res;
+ } else {
+ mm_free(pool, res);
+ return NULL;
+ }
+ }
+ case AF_UNIX: {
+ struct sockaddr_un *res;
+ const size_t alen = strlen(addr) + 1;
+ if (alen > sizeof(res->sun_path)) {
+ return NULL;
+ }
+ res = mm_alloc(pool, sizeof(*res));
+ res->sun_family = AF_UNIX;
+ memcpy(res->sun_path, addr, alen);
+ return (struct sockaddr *)res;
+ }
+ default:
+ return NULL;
+ }
+}
+
+int kr_straddr_subnet(void *dst, const char *addr)
+{
+ if (!dst || !addr) {
+ return kr_error(EINVAL);
+ }
+ /* Parse subnet */
+ int bit_len = 0;
+ int family = kr_straddr_family(addr);
+ if (family != AF_INET && family != AF_INET6)
+ return kr_error(EINVAL);
+ const int max_len = (family == AF_INET6) ? 128 : 32;
+ auto_free char *addr_str = strdup(addr);
+ char *subnet = strchr(addr_str, '/');
+ if (subnet) {
+ *subnet = '\0';
+ subnet += 1;
+ bit_len = strtol(subnet, NULL, 10);
+ /* Check client subnet length */
+ if (bit_len < 0 || bit_len > max_len) {
+ return kr_error(ERANGE);
+ }
+ } else {
+ /* No subnet, use maximal subnet length. */
+ bit_len = max_len;
+ }
+ /* Parse address */
+ int ret = inet_pton(family, addr_str, dst);
+ if (ret != 1) {
+ return kr_error(EILSEQ);
+ }
+
+ return bit_len;
+}
+
+int kr_straddr_split(const char *instr, char ipaddr[static restrict (INET6_ADDRSTRLEN + 1)],
+ uint16_t *port)
+{
+ if (kr_fails_assert(instr && ipaddr && port)) return kr_error(EINVAL);
+ /* Find where port number starts. */
+ const char *p_start = strchr(instr, '@');
+ if (!p_start)
+ p_start = strchr(instr, '#');
+ if (p_start) { /* Get and check the port number. */
+ if (p_start[1] == '\0') /* Don't accept empty port string. */
+ return kr_error(EILSEQ);
+ char *p_end;
+ long p = strtol(p_start + 1, &p_end, 10);
+ if (*p_end != '\0' || p <= 0 || p > UINT16_MAX)
+ return kr_error(EILSEQ);
+ *port = p;
+ }
+ /* Copy the address. */
+ const size_t addrlen = p_start ? p_start - instr : strlen(instr);
+ if (addrlen > INET6_ADDRSTRLEN)
+ return kr_error(EILSEQ);
+ memcpy(ipaddr, instr, addrlen);
+ ipaddr[addrlen] = '\0';
+ return kr_ok();
+}
+
+int kr_straddr_join(const char *addr, uint16_t port, char *buf, size_t *buflen)
+{
+ if (!addr || !buf || !buflen) {
+ return kr_error(EINVAL);
+ }
+
+ struct sockaddr_storage ss;
+ int family = kr_straddr_family(addr);
+ if (family == kr_error(EINVAL) || inet_pton(family, addr, &ss) != 1) {
+ return kr_error(EINVAL);
+ }
+
+ int len = strlen(addr);
+ if (len + 6 >= *buflen) {
+ return kr_error(ENOSPC);
+ }
+
+ memcpy(buf, addr, len + 1);
+ buf[len] = '#';
+ u16tostr((uint8_t *)&buf[len + 1], port);
+ len += 6;
+ buf[len] = 0;
+ *buflen = len;
+
+ return kr_ok();
+}
+
+int kr_bitcmp(const char *a, const char *b, int bits)
+{
+ /* We're using the function from lua directly, so at least for now
+ * we avoid crashing on bogus inputs. Meaning: NULL is ordered before
+ * anything else, and negative length is the same as zero.
+ * TODO: review the call sites and probably remove the checks. */
+ if (bits <= 0 || (!a && !b)) {
+ return 0;
+ } else if (!a) {
+ return -1;
+ } else if (!b) {
+ return 1;
+ }
+
+ kr_require((a && b && bits >= 0) || bits == 0);
+ /* Compare part byte-divisible part. */
+ const size_t chunk = bits / 8;
+ int ret = memcmp(a, b, chunk);
+ if (ret != 0) {
+ return ret;
+ }
+ a += chunk;
+ b += chunk;
+ bits -= chunk * 8;
+ /* Compare last partial byte address block. */
+ if (bits > 0) {
+ const size_t shift = (8 - bits);
+ ret = ((uint8_t)(*a >> shift) - (uint8_t)(*b >> shift));
+ }
+ return ret;
+}
+
+void kr_bitmask(unsigned char *a, size_t a_len, int bits)
+{
+ if (bits < 0 || !a || !a_len) {
+ return;
+ }
+
+ size_t i = bits / 8;
+ const size_t mid_bits = 8 - (bits % 8);
+ const unsigned char mask = 0xFF << mid_bits;
+ if (i < a_len)
+ a[i] &= mask;
+
+ for (++i; i < a_len; ++i)
+ a[i] = 0;
+}
+
+int kr_rrkey(char *key, uint16_t class, const knot_dname_t *owner,
+ uint16_t type, uint16_t additional)
+{
+ if (!key || !owner) {
+ return kr_error(EINVAL);
+ }
+ uint8_t *key_buf = (uint8_t *)key;
+ int ret = u16tostr(key_buf, class);
+ if (ret <= 0) {
+ return ret;
+ }
+ key_buf += ret;
+ ret = knot_dname_to_wire(key_buf, owner, KNOT_DNAME_MAXLEN);
+ if (ret <= 0) {
+ return ret;
+ }
+ knot_dname_to_lower(key_buf);
+ key_buf += ret - 1;
+ ret = u16tostr(key_buf, type);
+ if (ret <= 0) {
+ return ret;
+ }
+ key_buf += ret;
+ ret = u16tostr(key_buf, additional);
+ if (ret <= 0) {
+ return ret;
+ }
+ key_buf[ret] = '\0';
+ return (char *)&key_buf[ret] - key;
+}
+
+/** Return whether two RRsets match, i.e. would form the same set; see ranked_rr_array_t */
+static inline bool rrsets_match(const knot_rrset_t *rr1, const knot_rrset_t *rr2)
+{
+ bool match = rr1->type == rr2->type && rr1->rclass == rr2->rclass;
+ if (match && rr2->type == KNOT_RRTYPE_RRSIG) {
+ match = match && knot_rrsig_type_covered(rr1->rrs.rdata)
+ == knot_rrsig_type_covered(rr2->rrs.rdata);
+ }
+ match = match && knot_dname_is_equal(rr1->owner, rr2->owner);
+ return match;
+}
+
+/** Ensure that an index in a ranked array won't cause "duplicate" RRsets on wire.
+ *
+ * Other entries that would form the same RRset get to_wire = false.
+ * See also rrsets_match.
+ */
+static int to_wire_ensure_unique(ranked_rr_array_t *array, size_t index)
+{
+ if (kr_fails_assert(array && index < array->len)) return kr_error(EINVAL);
+
+ const struct ranked_rr_array_entry *e0 = array->at[index];
+ if (!e0->to_wire) {
+ return kr_ok();
+ }
+
+ for (ssize_t i = array->len - 1; i >= 0; --i) {
+ /* ^ iterate backwards, as the end is more likely in CPU caches */
+ struct ranked_rr_array_entry *ei = array->at[i];
+ if (ei->qry_uid == e0->qry_uid /* assumption: no duplicates within qry */
+ || !ei->to_wire /* no use for complex comparison if @to_wire */
+ ) {
+ continue;
+ }
+ if (rrsets_match(ei->rr, e0->rr)) {
+ ei->to_wire = false;
+ }
+ }
+ return kr_ok();
+}
+
+/* Implementation overview of _add() and _finalize():
+ * - for rdata we just maintain a list of pointers (in knot_rrset_t::additional)
+ * - we only construct the final rdataset at the end (and thus more efficiently)
+ */
+typedef array_t(knot_rdata_t *) rdata_array_t;
+int kr_ranked_rrarray_add(ranked_rr_array_t *array, const knot_rrset_t *rr,
+ uint8_t rank, bool to_wire, uint32_t qry_uid, knot_mm_t *pool)
+{
+ /* From normal packet parser we always get RRs one by one,
+ * but cache and prefil modules (also) feed us larger RRsets. */
+ kr_assert(rr->rrs.count >= 1);
+ /* Check if another rrset with the same
+ * rclass/type/owner combination exists within current query
+ * and merge if needed */
+ for (ssize_t i = array->len - 1; i >= 0; --i) {
+ ranked_rr_array_entry_t *stashed = array->at[i];
+ if (stashed->yielded) {
+ break;
+ }
+ if (stashed->qry_uid != qry_uid) {
+ break;
+ /* We do not guarantee merging RRs "across" any point that switched
+ * to processing a different upstream packet (i.e. qry_uid).
+ * In particular, iterator never returns KR_STATE_YIELD. */
+ }
+ if (!rrsets_match(stashed->rr, rr)) {
+ continue;
+ }
+ /* Found the entry to merge with. Check consistency and merge. */
+ if (kr_fails_assert(stashed->rank == rank && !stashed->cached && stashed->in_progress))
+ return kr_error(EEXIST);
+
+ /* It may happen that an RRset is first considered useful
+ * (to_wire = false, e.g. due to being part of glue),
+ * and later we may find we also want it in the answer. */
+ stashed->to_wire = stashed->to_wire || to_wire;
+
+ /* We just add the reference into this in_progress RRset. */
+ rdata_array_t *ra = stashed->rr->additional;
+ if (ra == NULL) {
+ /* RRset not in array format yet -> convert it. */
+ ra = stashed->rr->additional = mm_alloc(pool, sizeof(*ra));
+ if (!ra) {
+ return kr_error(ENOMEM);
+ }
+ array_init(*ra);
+ int ret = array_reserve_mm(*ra, stashed->rr->rrs.count + rr->rrs.count,
+ kr_memreserve, pool);
+ if (ret) {
+ return kr_error(ret);
+ }
+ knot_rdata_t *r_it = stashed->rr->rrs.rdata;
+ for (int ri = 0; ri < stashed->rr->rrs.count;
+ ++ri, r_it = knot_rdataset_next(r_it)) {
+ kr_require(array_push(*ra, r_it) >= 0);
+ }
+ } else {
+ int ret = array_reserve_mm(*ra, ra->len + rr->rrs.count,
+ kr_memreserve, pool);
+ if (ret) {
+ return kr_error(ret);
+ }
+ }
+ /* Append to the array. */
+ knot_rdata_t *r_it = rr->rrs.rdata;
+ for (int ri = 0; ri < rr->rrs.count;
+ ++ri, r_it = knot_rdataset_next(r_it)) {
+ kr_require(array_push(*ra, r_it) >= 0);
+ }
+ return i;
+ }
+
+ /* No stashed rrset found, add */
+ int ret = array_reserve_mm(*array, array->len + 1, kr_memreserve, pool);
+ if (ret) {
+ return kr_error(ret);
+ }
+
+ ranked_rr_array_entry_t *entry = mm_calloc(pool, 1, sizeof(*entry));
+ if (!entry) {
+ return kr_error(ENOMEM);
+ }
+
+ knot_rrset_t *rr_new = knot_rrset_new(rr->owner, rr->type, rr->rclass, rr->ttl, pool);
+ if (!rr_new) {
+ mm_free(pool, entry);
+ return kr_error(ENOMEM);
+ }
+ rr_new->rrs = rr->rrs;
+ if (kr_fails_assert(rr_new->additional == NULL)) {
+ mm_free(pool, entry);
+ return kr_error(EINVAL);
+ }
+
+ entry->qry_uid = qry_uid;
+ entry->rr = rr_new;
+ entry->rank = rank;
+ entry->to_wire = to_wire;
+ entry->in_progress = true;
+ if (array_push(*array, entry) < 0) {
+ /* Silence coverity. It shouldn't be possible to happen,
+ * due to the array_reserve_mm call above. */
+ mm_free(pool, entry);
+ return kr_error(ENOMEM);
+ }
+
+ ret = to_wire_ensure_unique(array, array->len - 1);
+ if (ret < 0) return ret;
+ return array->len - 1;
+}
+
+/** Comparator for qsort() on an array of knot_data_t pointers. */
+static int rdata_p_cmp(const void *rp1, const void *rp2)
+{
+ /* Just correct types of the parameters and pass them dereferenced. */
+ const knot_rdata_t
+ *const *r1 = rp1,
+ *const *r2 = rp2;
+ return knot_rdata_cmp(*r1, *r2);
+}
+int kr_ranked_rrarray_finalize(ranked_rr_array_t *array, uint32_t qry_uid, knot_mm_t *pool)
+{
+ for (ssize_t array_i = array->len - 1; array_i >= 0; --array_i) {
+ ranked_rr_array_entry_t *stashed = array->at[array_i];
+ if (stashed->qry_uid != qry_uid) {
+ continue; /* We apparently can't always short-cut the cycle. */
+ }
+ if (!stashed->in_progress) {
+ continue;
+ }
+ rdata_array_t *ra = stashed->rr->additional;
+ if (!ra) {
+ /* No array, so we just need to copy the rdataset. */
+ knot_rdataset_t *rds = &stashed->rr->rrs;
+ knot_rdataset_t tmp = *rds;
+ int ret = knot_rdataset_copy(rds, &tmp, pool);
+ if (ret) {
+ return kr_error(ret);
+ }
+ } else {
+ /* Multiple RRs; first: sort the array. */
+ stashed->rr->additional = NULL;
+ qsort(ra->at, ra->len, sizeof(ra->at[0]), rdata_p_cmp);
+ /* Prune duplicates: NULL all except the last instance. */
+ int dup_count = 0;
+ for (int i = 0; i + 1 < ra->len; ++i) {
+ if (knot_rdata_cmp(ra->at[i], ra->at[i + 1]) == 0) {
+ ra->at[i] = NULL;
+ ++dup_count;
+ kr_log_q(NULL, ITERATOR, "deleted duplicate RR\n");
+ }
+ }
+ /* Prepare rdataset, except rdata contents. */
+ knot_rdataset_t *rds = &stashed->rr->rrs;
+ rds->size = 0;
+ for (int i = 0; i < ra->len; ++i) {
+ if (ra->at[i]) {
+ rds->size += knot_rdata_size(ra->at[i]->len);
+ }
+ }
+ rds->count = ra->len - dup_count;
+ if (rds->size) {
+ rds->rdata = mm_alloc(pool, rds->size);
+ if (!rds->rdata) {
+ return kr_error(ENOMEM);
+ }
+ } else {
+ rds->rdata = NULL;
+ }
+ /* Everything is ready; now just copy all the rdata. */
+ uint8_t *raw_it = (uint8_t *)rds->rdata;
+ for (int i = 0; i < ra->len; ++i) {
+ if (ra->at[i] && rds->size/*linters*/) {
+ const int size = knot_rdata_size(ra->at[i]->len);
+ memcpy(raw_it, ra->at[i], size);
+ raw_it += size;
+ }
+ }
+ if (kr_fails_assert(raw_it == (uint8_t *)rds->rdata + rds->size))
+ return kr_error(EINVAL);
+ }
+ stashed->in_progress = false;
+ }
+ return kr_ok();
+}
+
+
+int kr_ranked_rrarray_set_wire(ranked_rr_array_t *array, bool to_wire,
+ uint32_t qry_uid, bool check_dups,
+ bool (*extraCheck)(const ranked_rr_array_entry_t *))
+{
+ for (size_t i = 0; i < array->len; ++i) {
+ ranked_rr_array_entry_t *entry = array->at[i];
+ if (entry->qry_uid != qry_uid) {
+ continue;
+ }
+ if (extraCheck != NULL && !extraCheck(entry)) {
+ continue;
+ }
+ entry->to_wire = to_wire;
+ if (check_dups) {
+ int ret = to_wire_ensure_unique(array, i);
+ if (ret) return ret;
+ }
+ }
+ return kr_ok();
+}
+
+
+static char *callprop(struct kr_module *module, const char *prop, const char *input, void *env)
+{
+ if (!module || !module->props || !prop) {
+ return NULL;
+ }
+ for (const struct kr_prop *p = module->props; p && p->name; ++p) {
+ if (p->cb != NULL && strcmp(p->name, prop) == 0) {
+ return p->cb(env, module, input);
+ }
+ }
+ return NULL;
+}
+
+char *kr_module_call(struct kr_context *ctx, const char *module, const char *prop, const char *input)
+{
+ if (!ctx || !ctx->modules || !module || !prop) {
+ return NULL;
+ }
+ module_array_t *mod_list = ctx->modules;
+ for (size_t i = 0; i < mod_list->len; ++i) {
+ struct kr_module *mod = mod_list->at[i];
+ if (strcmp(mod->name, module) == 0) {
+ return callprop(mod, prop, input, ctx);
+ }
+ }
+ return NULL;
+}
+
+static void flags_to_str(char *dst, const knot_pkt_t *pkt, size_t maxlen)
+{
+ int offset = 0;
+ int ret = 0;
+ struct {
+ uint8_t (*get) (const uint8_t *packet);
+ char name[3];
+ } flag[7] = {
+ {knot_wire_get_qr, "qr"},
+ {knot_wire_get_aa, "aa"},
+ {knot_wire_get_rd, "rd"},
+ {knot_wire_get_ra, "ra"},
+ {knot_wire_get_tc, "tc"},
+ {knot_wire_get_ad, "ad"},
+ {knot_wire_get_cd, "cd"}
+ };
+ for (int i = 0; i < 7; ++i) {
+ if (!flag[i].get(pkt->wire)) {
+ continue;
+ }
+ ret = snprintf(dst + offset, maxlen, "%s ", flag[i].name);
+ if (ret <= 0 || ret >= maxlen) {
+ dst[0] = 0;
+ return;
+ }
+ offset += ret;
+ maxlen -= ret;
+ }
+ dst[offset] = 0;
+}
+
+static char *print_section_opt(struct mempool *mp, char *endp, const knot_rrset_t *rr, const uint8_t rcode)
+{
+ uint8_t errcode = knot_edns_get_ext_rcode(rr);
+ uint16_t ext_rcode_id = knot_edns_whole_rcode(errcode, rcode);
+ const char *ext_rcode_str = "Unused";
+ const knot_lookup_t *ext_rcode;
+
+ if (errcode > 0) {
+ ext_rcode = knot_lookup_by_id(knot_rcode_names, ext_rcode_id);
+ if (ext_rcode != NULL) {
+ ext_rcode_str = ext_rcode->name;
+ } else {
+ ext_rcode_str = "Unknown";
+ }
+ }
+
+ return mp_printf_append(mp, endp,
+ ";; EDNS PSEUDOSECTION:\n;; "
+ "Version: %u; flags: %s; UDP size: %u B; ext-rcode: %s\n\n",
+ knot_edns_get_version(rr),
+ (knot_edns_do(rr) != 0) ? "do" : "",
+ knot_edns_get_payload(rr),
+ ext_rcode_str);
+
+}
+
+/**
+ * Detect if qname contains an uppercase letter.
+ */
+static bool qname_has_uppercase(const knot_dname_t *qname) {
+ const int len = knot_dname_size(qname) - 1; /* skip root label at the end */
+ for (int i = 1; i < len; ++i) { /* skip first length byte */
+ /* Note: this relies on the fact that correct label lengths
+ * can't pass this test by "luck" and that correctness
+ * is checked earlier by packet parser. */
+ if (qname[i] >= 'A' && qname[i] <= 'Z')
+ return true;
+ }
+ return false;
+}
+
+char *kr_pkt_text(const knot_pkt_t *pkt)
+{
+ if (!pkt) {
+ return NULL;
+ }
+
+ struct mempool *mp = mp_new(512);
+
+ static const char * snames[] = {
+ ";; ANSWER SECTION", ";; AUTHORITY SECTION", ";; ADDITIONAL SECTION"
+ };
+ char flags[32];
+ uint8_t pkt_rcode = knot_wire_get_rcode(pkt->wire);
+ uint8_t pkt_opcode = knot_wire_get_opcode(pkt->wire);
+ const char *rcode_str = "Unknown";
+ const char *opcode_str = "Unknown";
+ const knot_lookup_t *rcode = knot_lookup_by_id(knot_rcode_names, pkt_rcode);
+ const knot_lookup_t *opcode = knot_lookup_by_id(knot_opcode_names, pkt_opcode);
+ uint16_t qry_id = knot_wire_get_id(pkt->wire);
+ uint16_t qdcount = knot_wire_get_qdcount(pkt->wire);
+
+ if (rcode != NULL) {
+ rcode_str = rcode->name;
+ }
+ if (opcode != NULL) {
+ opcode_str = opcode->name;
+ }
+ flags_to_str(flags, pkt, sizeof(flags));
+
+ char *ptr = mp_printf(mp,
+ ";; ->>HEADER<<- opcode: %s; status: %s; id: %hu\n"
+ ";; Flags: %s QUERY: %hu; ANSWER: %hu; "
+ "AUTHORITY: %hu; ADDITIONAL: %hu\n\n",
+ opcode_str, rcode_str, qry_id,
+ flags,
+ qdcount,
+ knot_wire_get_ancount(pkt->wire),
+ knot_wire_get_nscount(pkt->wire),
+ knot_wire_get_arcount(pkt->wire));
+
+ if (knot_pkt_has_edns(pkt)) {
+ ptr = print_section_opt(mp, ptr, pkt->opt_rr, knot_wire_get_rcode(pkt->wire));
+ }
+
+ if (qdcount == 1) {
+ KR_DNAME_GET_STR(qname, knot_pkt_qname(pkt));
+ KR_RRTYPE_GET_STR(rrtype, knot_pkt_qtype(pkt));
+ const char *qnwarn;
+ if (qname_has_uppercase(knot_pkt_qname(pkt)))
+ qnwarn = \
+"; WARNING! Uppercase letters indicate positions with letter case mismatches!\n"
+"; Normally you should see all-lowercase qname here.\n";
+ else
+ qnwarn = "";
+ ptr = mp_printf_append(mp, ptr, ";; QUESTION SECTION\n%s%s\t\t%s\n", qnwarn, qname, rrtype);
+ } else if (qdcount > 1) {
+ ptr = mp_printf_append(mp, ptr, ";; Warning: unsupported QDCOUNT %hu\n", qdcount);
+ }
+
+ for (knot_section_t i = KNOT_ANSWER; i <= KNOT_ADDITIONAL; ++i) {
+ const knot_pktsection_t *sec = knot_pkt_section(pkt, i);
+ if (sec->count == 0) {
+ continue;
+ }
+
+ ptr = mp_printf_append(mp, ptr, "\n%s\n", snames[i - KNOT_ANSWER]);
+ for (unsigned k = 0; k < sec->count; ++k) {
+ const knot_rrset_t *rr = knot_pkt_rr(sec, k);
+ if (rr->type == KNOT_RRTYPE_OPT) {
+ continue;
+ }
+ auto_free char *rr_text = kr_rrset_text(rr);
+ ptr = mp_printf_append(mp, ptr, "%s", rr_text);
+ }
+ }
+
+ /* Close growing buffer and duplicate result before deleting */
+ char *result = strdup(ptr);
+ mp_delete(mp);
+ return result;
+}
+
+const knot_dump_style_t KR_DUMP_STYLE_DEFAULT = { /* almost all = false, */
+ .show_ttl = true,
+};
+
+char *kr_rrset_text(const knot_rrset_t *rr)
+{
+ if (!rr) {
+ return NULL;
+ }
+
+ /* Note: knot_rrset_txt_dump will double the size until the rrset fits */
+ size_t bufsize = 128;
+ char *buf = malloc(bufsize);
+ int ret = knot_rrset_txt_dump(rr, &buf, &bufsize, &KR_DUMP_STYLE_DEFAULT);
+ if (ret < 0) {
+ free(buf);
+ return NULL;
+ }
+
+ return buf;
+}
+
+uint64_t kr_now()
+{
+ return uv_now(uv_default_loop());
+}
+
+void kr_uv_free_cb(uv_handle_t* handle)
+{
+ free(handle->data);
+}
+
+const char *kr_strptime_diff(const char *format, const char *time1_str,
+ const char *time0_str, double *diff) {
+ if (kr_fails_assert(format && time1_str && time0_str && diff)) return NULL;
+
+ struct tm time1_tm;
+ time_t time1_u;
+ struct tm time0_tm;
+ time_t time0_u;
+
+ char *err = strptime(time1_str, format, &time1_tm);
+ if (err == NULL || err != time1_str + strlen(time1_str))
+ return "strptime failed for time1";
+ time1_tm.tm_isdst = -1; /* determine if DST is active or not */
+ time1_u = mktime(&time1_tm);
+ if (time1_u == (time_t)-1)
+ return "mktime failed for time1";
+
+ err = strptime(time0_str, format, &time0_tm);
+ if (err == NULL || err != time0_str + strlen(time0_str))
+ return "strptime failed for time0";
+ time0_tm.tm_isdst = -1; /* determine if DST is active or not */
+ time0_u = mktime(&time0_tm);
+ if (time0_u == (time_t)-1)
+ return "mktime failed for time0";
+ *diff = difftime(time1_u, time0_u);
+
+ return NULL;
+}
+
+int knot_dname_lf2wire(knot_dname_t * const dst, uint8_t len, const uint8_t *lf)
+{
+ knot_dname_t *d = dst; /* moving "cursor" as we write it out */
+ if (kr_fails_assert(d && (len == 0 || lf))) return kr_error(EINVAL);
+ /* we allow the final zero byte to be omitted */
+ if (!len) {
+ goto finish;
+ }
+ if (lf[len - 1]) {
+ ++len;
+ }
+ /* convert the name, one label at a time */
+ int label_end = len - 1; /* index of the zero byte after the current label */
+ while (label_end >= 0) {
+ /* find label_start */
+ int i = label_end - 1;
+ while (i >= 0 && lf[i])
+ --i;
+ const int label_start = i + 1; /* index of the first byte of the current label */
+ const int label_len = label_end - label_start;
+ kr_assert(label_len >= 0);
+ if (label_len > 63 || label_len <= 0)
+ return kr_error(EILSEQ);
+ /* write the label */
+ *d = label_len;
+ ++d;
+ memcpy(d, lf + label_start, label_len);
+ d += label_len;
+ /* next label */
+ label_end = label_start - 1;
+ }
+finish:
+ *d = 0; /* the final zero */
+ ++d;
+ return d - dst;
+}
+
+static void rnd_noerror(void *data, uint size)
+{
+ int ret = gnutls_rnd(GNUTLS_RND_NONCE, data, size);
+ if (ret) {
+ kr_log_error(SYSTEM, "gnutls_rnd(): %s\n", gnutls_strerror(ret));
+ abort();
+ }
+}
+void kr_rnd_buffered(void *data, uint size)
+{
+ /* static circular buffer, from index _begin (inclusive) to _end (exclusive) */
+ static uint8_t buf[512/8]; /* gnutls_rnd() works on blocks of 512 bits (chacha) */
+ static uint buf_begin = sizeof(buf);
+
+ if (unlikely(size > sizeof(buf))) {
+ rnd_noerror(data, size);
+ return;
+ }
+ /* Start with contiguous chunk, possibly until the end of buffer. */
+ const uint size1 = MIN(size, sizeof(buf) - buf_begin);
+ uint8_t *d = data;
+ memcpy(d, buf + buf_begin, size1);
+ if (size1 == size) {
+ buf_begin += size1;
+ return;
+ }
+ d += size1;
+ size -= size1;
+ /* Refill the whole buffer, and finish by another contiguous chunk. */
+ rnd_noerror(buf, sizeof(buf));
+ memcpy(d, buf, size);
+ buf_begin = size;
+}
+
+void kr_rrset_init(knot_rrset_t *rrset, knot_dname_t *owner,
+ uint16_t type, uint16_t rclass, uint32_t ttl)
+{
+ if (kr_fails_assert(rrset)) return;
+ knot_rrset_init(rrset, owner, type, rclass, ttl);
+}
+bool kr_pkt_has_wire(const knot_pkt_t *pkt)
+{
+ return pkt->size != KR_PKT_SIZE_NOWIRE;
+}
+bool kr_pkt_has_dnssec(const knot_pkt_t *pkt)
+{
+ return knot_pkt_has_dnssec(pkt);
+}
+uint16_t kr_pkt_qclass(const knot_pkt_t *pkt)
+{
+ return knot_pkt_qclass(pkt);
+}
+uint16_t kr_pkt_qtype(const knot_pkt_t *pkt)
+{
+ return knot_pkt_qtype(pkt);
+}
+uint32_t kr_rrsig_sig_inception(const knot_rdata_t *rdata)
+{
+ return knot_rrsig_sig_inception(rdata);
+}
+uint32_t kr_rrsig_sig_expiration(const knot_rdata_t *rdata)
+{
+ return knot_rrsig_sig_expiration(rdata);
+}
+uint16_t kr_rrsig_type_covered(const knot_rdata_t *rdata)
+{
+ return knot_rrsig_type_covered(rdata);
+}
+
+time_t kr_file_mtime (const char* fname) {
+ struct stat fstat;
+
+ if (stat(fname, &fstat) != 0) {
+ return 0;
+ }
+
+ return fstat.st_mtime;
+}
+
+long long kr_fssize(const char *path)
+{
+ if (!path)
+ return kr_error(EINVAL);
+
+ struct statvfs buf;
+ if (statvfs(path, &buf) != 0)
+ return kr_error(errno);
+
+ return buf.f_frsize * buf.f_blocks;
+}
+
+const char * kr_dirent_name(const struct dirent *de)
+{
+ return de ? de->d_name : NULL;
+}
+
diff --git a/lib/utils.h b/lib/utils.h
new file mode 100644
index 0000000..0d1d845
--- /dev/null
+++ b/lib/utils.h
@@ -0,0 +1,608 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#include <dirent.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <sys/un.h>
+#include <netinet/in.h>
+#include <unistd.h>
+
+#include <gnutls/gnutls.h>
+#include <gnutls/crypto.h>
+
+#include <libknot/libknot.h>
+#include <libknot/packet/pkt.h>
+#include <libknot/rrset.h>
+#include <libknot/rrtype/rrsig.h>
+#include <uv.h>
+
+#include "kresconfig.h"
+#include "contrib/mempattern.h"
+#include "lib/defines.h"
+#include "lib/generic/array.h"
+#include "lib/log.h"
+
+/** When knot_pkt is passed from cache without ->wire, this is the ->size. */
+static const size_t KR_PKT_SIZE_NOWIRE = -1;
+
+/** Maximum length (excluding null-terminator) of a presentation-form address
+ * returned by `kr_straddr`. */
+#define KR_STRADDR_MAXLEN 109
+
+/** Used for reserving enough space for the `kr_sockaddr_key` function
+ * output. */
+struct kr_sockaddr_key_storage {
+ char bytes[sizeof(struct sockaddr_storage)];
+};
+
+
+/*
+ * Logging and debugging.
+ */
+
+/** @brief Callback for request events. */
+typedef void (*trace_callback_f)(struct kr_request *request);
+/**
+ * @brief Callback for request logging handler.
+ * @param[in] msg Log message. Pointer is not valid after handler returns. */
+typedef void (*trace_log_f)(const struct kr_request *request, const char *msg);
+
+/** Assert() but always, regardless of -DNDEBUG. See also kr_assert(). */
+#define kr_require(expression) do { if (!(expression)) { \
+ kr_fail(true, #expression, __func__, __FILE__, __LINE__); \
+ __builtin_unreachable(); /* aid code analysis */ \
+ } } while (false)
+
+/** Check an assertion that's recoverable. Return the true if it fails and needs handling.
+ *
+ * If the check fails, optionally fork()+abort() to generate coredump
+ * and continue running in parent process. Return value must be handled to
+ * ensure safe recovery from error. Use kr_require() for unrecoverable checks.
+ * The errno variable is not mangled, e.g. you can: if (kr_fails_assert(...)) return errno;
+ */
+#define kr_fails_assert(expression) !kr_assert_func((expression), #expression, \
+ __func__, __FILE__, __LINE__)
+
+/** Kresd assertion without a return value.
+ *
+ * These can be turned on or off, for mandatory unrecoverable checks, use kr_require().
+ * For recoverable checks, use kr_fails_assert().
+ * */
+#define kr_assert(expression) (void)!kr_fails_assert((expression))
+
+/** Whether kr_assert() and kr_fails_assert() checks should abort. */
+KR_EXPORT extern bool kr_dbg_assertion_abort;
+
+/** How often kr_assert() should fork the process before issuing abort (if configured).
+ *
+ * This can be useful for debugging rare edge-cases in production.
+ * if (kr_debug_assertion_abort && kr_debug_assertion_fork), it is
+ * possible to both obtain a coredump (from forked child) and recover from the
+ * non-fatal error in the parent process.
+ *
+ * == 0 (false): no forking
+ * > 0: minimum delay between forks
+ * (in milliseconds, each instance separately, randomized +-25%)
+ * < 0: no rate-limiting (not recommended)
+ */
+KR_EXPORT extern int kr_dbg_assertion_fork;
+
+/** Use kr_require(), kr_assert() or kr_fails_assert() instead of directly this function. */
+KR_EXPORT KR_COLD void kr_fail(bool is_fatal, const char* expr, const char *func,
+ const char *file, int line);
+
+/** Use kr_require(), kr_assert() or kr_fails_assert() instead of directly this function. */
+__attribute__ ((warn_unused_result))
+static inline bool kr_assert_func(bool result, const char *expr, const char *func,
+ const char *file, int line)
+{
+ if (!result)
+ kr_fail(false, expr, func, file, line);
+ return result;
+}
+
+#define KR_DNAME_GET_STR(dname_str, dname) \
+ char dname_str[KR_DNAME_STR_MAXLEN]; \
+ knot_dname_to_str(dname_str, (dname), sizeof(dname_str)); \
+ dname_str[sizeof(dname_str) - 1] = 0;
+
+#define KR_RRTYPE_GET_STR(rrtype_str, rrtype) \
+ char rrtype_str[KR_RRTYPE_STR_MAXLEN]; \
+ knot_rrtype_to_string((rrtype), rrtype_str, sizeof(rrtype_str)); \
+ rrtype_str[sizeof(rrtype_str) - 1] = 0;
+
+// Use this for allocations with mm.
+// Use mm_alloc for allocations into mempool
+
+/** A strcmp() variant directly usable for qsort() on an array of strings. */
+static inline int strcmp_p(const void *p1, const void *p2)
+{
+ return strcmp(*(char * const *)p1, *(char * const *)p2);
+}
+
+/** Get current working directory with fallback value. */
+static inline void get_workdir(char *out, size_t len) {
+ if(getcwd(out, len) == NULL) {
+ static const char errprefix[] = "<invalid working directory>";
+ strncpy(out, errprefix, len);
+ }
+}
+
+/** @cond internal Array types */
+struct kr_context;
+
+struct ranked_rr_array_entry {
+ uint32_t qry_uid;
+ uint8_t rank; /**< enum kr_rank */
+ uint8_t revalidation_cnt;
+ bool cached : 1; /**< Set to true if the entry was written into cache */
+ bool yielded : 1;
+ bool to_wire : 1; /**< whether to be put into the answer */
+ bool expiring : 1; /**< low remaining TTL; see is_expiring; only used in cache ATM */
+ bool in_progress : 1; /**< build of RRset in progress, i.e. different format of RR data */
+ bool dont_cache : 1; /**< avoid caching; useful e.g. for generated data */
+ knot_rrset_t *rr;
+};
+typedef struct ranked_rr_array_entry ranked_rr_array_entry_t;
+
+/** Array of RRsets coming from multiple queries; for struct kr_request.
+ *
+ * Notes:
+ * - RRSIGs are only considered to form an RRset when the types covered match;
+ * cache-related code relies on that!
+ * - RRsets from the same packet (qry_uid) get merged.
+ */
+typedef array_t(ranked_rr_array_entry_t *) ranked_rr_array_t;
+/* @endcond */
+
+typedef struct kr_http_header_array_entry {
+ char* name;
+ char* value;
+} kr_http_header_array_entry_t;
+
+/** Array of HTTP headers for DoH. */
+typedef array_t(kr_http_header_array_entry_t) kr_http_header_array_t;
+
+/** Concatenate N strings. */
+KR_EXPORT
+char* kr_strcatdup(unsigned n, ...);
+
+/** Construct absolute file path, without resolving symlinks.
+ * \return malloc-ed string or NULL (+errno in that case) */
+KR_EXPORT
+char * kr_absolutize_path(const char *dirname, const char *fname);
+
+/** You probably want kr_rand_* convenience functions instead.
+ * This is a buffered version of gnutls_rnd(GNUTLS_RND_NONCE, ..) */
+KR_EXPORT
+void kr_rnd_buffered(void *data, unsigned int size);
+
+/** Return a few random bytes. */
+KR_EXPORT inline
+uint64_t kr_rand_bytes(unsigned int size)
+{
+ uint64_t result;
+ if (size <= 0 || size > sizeof(result)) {
+ kr_log_error(SYSTEM, "kr_rand_bytes(): EINVAL\n");
+ abort();
+ }
+ uint8_t data[sizeof(result)];
+ kr_rnd_buffered(data, size);
+ /* I would have liked to dump the random data into a size_t directly,
+ * but that would work well only on little-endian machines,
+ * so instead I hope that the compiler will optimize this out.
+ * (Tested via reading assembly from usual gcc -O2 setup.)
+ * Alternatively we could waste more rnd bytes, but that seemed worse. */
+ result = 0;
+ for (unsigned int i = 0; i < size; ++ i) {
+ result |= ((uint64_t)data[i]) << (i * 8);
+ }
+ return result;
+}
+
+/** Throw a pseudo-random coin, succeeding approximately with probability nomin/denomin.
+ * - low precision, only one byte of randomness (or none with extreme parameters)
+ * - tip: use !kr_rand_coin() to get the complementary probability
+ */
+static inline bool kr_rand_coin(unsigned int nomin, unsigned int denomin)
+{
+ /* This function might be called with non-constant values
+ * so we try to handle odd corner cases instead of crash. */
+ if (nomin >= denomin)
+ return true;
+ else if (nomin <= 0)
+ return false;
+
+ /* threshold = how many parts from 256 are a success */
+ unsigned int threshold = (nomin * 256 + /*rounding*/ denomin / 2) / denomin;
+ if (threshold == 0) threshold = 1;
+ if (threshold == 256) threshold = 255;
+ return (kr_rand_bytes(1) < threshold);
+}
+
+/** Memory reservation routine for knot_mm_t */
+KR_EXPORT
+int kr_memreserve(void *baton, void **mem, size_t elm_size, size_t want, size_t *have);
+
+/** @internal Fast packet reset. */
+KR_EXPORT
+int kr_pkt_recycle(knot_pkt_t *pkt);
+
+/** @internal Clear packet payload. */
+KR_EXPORT
+int kr_pkt_clear_payload(knot_pkt_t *pkt);
+
+/** Construct and put record to packet. */
+KR_EXPORT
+int kr_pkt_put(knot_pkt_t *pkt, const knot_dname_t *name, uint32_t ttl,
+ uint16_t rclass, uint16_t rtype, const uint8_t *rdata, uint16_t rdlen);
+
+/** Set packet header suitable for authoritative answer. (for policy module) */
+KR_EXPORT
+void kr_pkt_make_auth_header(knot_pkt_t *pkt);
+
+/** Get pointer to the in-header QNAME.
+ *
+ * That's normally not lower-cased. However, when receiving packets from upstream
+ * we xor-apply the secret during packet-parsing, so it would get lower-cased
+ * after that point if the case was right.
+ */
+static inline knot_dname_t * kr_pkt_qname_raw(const knot_pkt_t *pkt)
+{
+ if (pkt == NULL || pkt->qname_size == 0) {
+ return NULL;
+ }
+ return pkt->wire + KNOT_WIRE_HEADER_SIZE;
+}
+
+/** Simple storage for IPx address and their ports or AF_UNSPEC. */
+union kr_sockaddr {
+ struct sockaddr ip;
+ struct sockaddr_in ip4;
+ struct sockaddr_in6 ip6;
+};
+
+/** Simple storage for IPx addresses. */
+union kr_in_addr {
+ struct in_addr ip4;
+ struct in6_addr ip6;
+};
+
+/* TODO: rename kr_inaddr functions to kr_sockaddr */
+/** Address bytes for given family. */
+KR_EXPORT KR_PURE
+const char *kr_inaddr(const struct sockaddr *addr);
+/** Address family. */
+KR_EXPORT KR_PURE
+int kr_inaddr_family(const struct sockaddr *addr);
+/** Address length for given family, i.e. sizeof(struct in*_addr). */
+KR_EXPORT KR_PURE
+int kr_inaddr_len(const struct sockaddr *addr);
+/** Sockaddr length for given family, i.e. sizeof(struct sockaddr_in*). */
+KR_EXPORT KR_PURE
+int kr_sockaddr_len(const struct sockaddr *addr);
+
+/** Creates a packed structure from the specified `addr`, safe for use as a key
+ * in containers like `trie_t`, and writes it into `dst`. On success, returns
+ * the actual length of the key.
+ *
+ * Returns `kr_error(EAFNOSUPPORT)` if the family of `addr` is unsupported. */
+KR_EXPORT
+ssize_t kr_sockaddr_key(struct kr_sockaddr_key_storage *dst,
+ const struct sockaddr *addr);
+
+/** Creates a `struct sockaddr` from the specified `key` created using the
+ * `kr_sockaddr_key()` function. */
+KR_EXPORT
+struct sockaddr *kr_sockaddr_from_key(struct sockaddr_storage *dst,
+ const char *key);
+
+/** Checks whether the two keys represent the same address;
+ * does NOT compare the ports. */
+KR_EXPORT
+bool kr_sockaddr_key_same_addr(const char *key_a, const char *key_b);
+
+/** Compare two given sockaddr.
+ * return 0 - addresses are equal, error code otherwise.
+ */
+KR_EXPORT KR_PURE
+int kr_sockaddr_cmp(const struct sockaddr *left, const struct sockaddr *right);
+/** Port. */
+KR_EXPORT KR_PURE
+uint16_t kr_inaddr_port(const struct sockaddr *addr);
+/** Set port. */
+KR_EXPORT
+void kr_inaddr_set_port(struct sockaddr *addr, uint16_t port);
+
+/** Write string representation for given address as "<addr>#<port>".
+ * \param[in] addr the raw address
+ * \param[out] buf the buffer for output string
+ * \param[in,out] buflen the available(in) and utilized(out) length, including \0 */
+KR_EXPORT
+int kr_inaddr_str(const struct sockaddr *addr, char *buf, size_t *buflen);
+
+/** Write string representation for given address as "<addr>#<port>".
+ * It's the same as kr_inaddr_str(), but the input address is input in native format
+ * like for inet_ntop() (4 or 16 bytes) and port must be separate parameter. */
+KR_EXPORT
+int kr_ntop_str(int family, const void *src, uint16_t port, char *buf, size_t *buflen);
+
+/** @internal Create string representation addr#port.
+ * @return pointer to a *static* string, i.e. each call will overwrite it
+ */
+KR_EXPORT
+char *kr_straddr(const struct sockaddr *addr);
+
+/** Return address type for string. */
+KR_EXPORT KR_PURE
+int kr_straddr_family(const char *addr);
+/** Return address length in given family (struct in*_addr). */
+KR_EXPORT KR_CONST
+int kr_family_len(int family);
+
+/** Create a sockaddr* from string+port representation.
+ * Also accepts IPv6 link-local and AF_UNIX starting with "/" (ignoring port) */
+KR_EXPORT
+struct sockaddr * kr_straddr_socket(const char *addr, int port, knot_mm_t *pool);
+
+/** Parse address and return subnet length (bits).
+ * @warning 'dst' must be at least `sizeof(struct in6_addr)` long. */
+KR_EXPORT
+int kr_straddr_subnet(void *dst, const char *addr);
+
+/** Splits ip address specified as "addr@port" or "addr#port" into addr and port.
+ * \param[in] instr zero-terminated input, e.g. "192.0.2.1#12345\0"
+ * \param[out] ipaddr working buffer for the port-less prefix of instr;
+ * length >= INET6_ADDRSTRLEN + 1.
+ * \param[out] port written in case it's specified in instr
+ * \return error code
+ * \note Typically you follow this by kr_straddr_socket().
+ * \note Only internet addresses are supported, i.e. no AF_UNIX sockets.
+ */
+KR_EXPORT
+int kr_straddr_split(const char *instr, char ipaddr[static restrict (INET6_ADDRSTRLEN + 1)],
+ uint16_t *port);
+
+/** Formats ip address and port in "addr#port" format.
+ * and performs validation.
+ * @note Port always formatted as five-character string with leading zeros.
+ * @return kr_error(EINVAL) - addr or buf is NULL or buflen is 0 or
+ * addr doesn't contain a valid ip address
+ * kr_error(ENOSP) - buflen is too small
+ */
+KR_EXPORT
+int kr_straddr_join(const char *addr, uint16_t port, char *buf, size_t *buflen);
+
+/** Compare memory bitwise. The semantics is "the same" as for memcmp().
+ * The partial byte is considered with more-significant bits first,
+ * so this is e.g. suitable for comparing IP prefixes. */
+KR_EXPORT KR_PURE
+int kr_bitcmp(const char *a, const char *b, int bits);
+
+/** Masks bits. The specified number of bits in `a` from the left (network order)
+ * will remain their original value, while the rest will be set to zero.
+ * This is useful for storing network addresses in a trie. */
+KR_EXPORT
+void kr_bitmask(unsigned char *a, size_t a_len, int bits);
+
+/** Check whether `addr` points to an `AF_INET6` address and whether the address
+ * is link-local. */
+static inline bool kr_sockaddr_link_local(const struct sockaddr *addr)
+{
+ if (addr->sa_family != AF_INET6)
+ return false;
+
+ /* Link-local: https://tools.ietf.org/html/rfc4291#section-2.4 */
+ const uint8_t prefix[] = { 0xFE, 0x80 };
+ const struct sockaddr_in6 *ip6 = (const struct sockaddr_in6 *) addr;
+ return kr_bitcmp((char *) ip6->sin6_addr.s6_addr, (char *) prefix, 10) == 0;
+}
+
+/* Stash key = {[5] class, [1-255] owner, [5] type, [5] additional, [1] \x00 } */
+#define KR_RRKEY_LEN (16 + KNOT_DNAME_MAXLEN)
+/** Create unique null-terminated string key for RR.
+ * @param key Destination buffer for key size, MUST be KR_RRKEY_LEN or larger.
+ * @param class RR class.
+ * @param owner RR owner name.
+ * @param type RR type.
+ * @param additional flags (for instance can be used for storing covered type
+ * when RR type is RRSIG).
+ * @return key length if successful or an error
+ * */
+KR_EXPORT
+int kr_rrkey(char *key, uint16_t class, const knot_dname_t *owner,
+ uint16_t type, uint16_t additional);
+
+/** Add RRSet copy to a ranked RR array.
+ *
+ * To convert to standard RRs inside, you need to call _finalize() afterwards,
+ * and the memory of rr->rrs.rdata has to remain until then.
+ *
+ * \return array index (>= 0) or error code (< 0)
+ */
+KR_EXPORT
+int kr_ranked_rrarray_add(ranked_rr_array_t *array, const knot_rrset_t *rr,
+ uint8_t rank, bool to_wire, uint32_t qry_uid, knot_mm_t *pool);
+/** Finalize in_progress sets - all with matching qry_uid. */
+KR_EXPORT
+int kr_ranked_rrarray_finalize(ranked_rr_array_t *array, uint32_t qry_uid, knot_mm_t *pool);
+
+/** @internal Mark the RRSets from particular query as
+ * "have (not) to be recorded in the final answer".
+ * @param array RRSet array.
+ * @param to_wire Records must be\must not be recorded in final answer.
+ * @param qry_uid Query uid.
+ * @param check_dups When to_wire is true, try to avoid duplicate RRSets.
+ * @param extraCheck optional function checking whether to consider the record
+ * @return 0 or an error
+ */
+int kr_ranked_rrarray_set_wire(ranked_rr_array_t *array, bool to_wire,
+ uint32_t qry_uid, bool check_dups,
+ bool (*extraCheck)(const ranked_rr_array_entry_t *));
+
+
+/** Style used by the kr_*_text() functions. */
+KR_EXPORT extern
+const knot_dump_style_t KR_DUMP_STYLE_DEFAULT;
+
+/**
+ * @return Newly allocated string representation of packet.
+ * Caller has to free() returned string.
+ */
+KR_EXPORT
+char *kr_pkt_text(const knot_pkt_t *pkt);
+
+KR_PURE
+char *kr_rrset_text(const knot_rrset_t *rr);
+
+KR_PURE
+static inline char *kr_dname_text(const knot_dname_t *name) {
+ return knot_dname_to_str_alloc(name);
+}
+
+KR_CONST
+static inline char *kr_rrtype_text(const uint16_t rrtype) {
+ char type_str[32] = {0};
+ knot_rrtype_to_string(rrtype, type_str, sizeof(type_str));
+ return strdup(type_str);
+}
+
+/**
+ * Call module property.
+ */
+KR_EXPORT
+char *kr_module_call(struct kr_context *ctx, const char *module, const char *prop, const char *input);
+
+/** Swap two places. Note: the parameters need to be without side effects. */
+#define SWAP(x, y) do { /* http://stackoverflow.com/a/3982430/587396 */ \
+ unsigned char swap_temp[sizeof(x) == sizeof(y) ? (ssize_t)sizeof(x) : -1]; \
+ memcpy(swap_temp, &y, sizeof(x)); \
+ memcpy(&y, &x, sizeof(x)); \
+ memcpy(&x, swap_temp, sizeof(x)); \
+ } while(0)
+
+/** Return the (covered) type of an nonempty RRset. */
+static inline uint16_t kr_rrset_type_maysig(const knot_rrset_t *rr)
+{
+ kr_require(rr && rr->rrs.count && rr->rrs.rdata);
+ uint16_t type = rr->type;
+ if (type == KNOT_RRTYPE_RRSIG)
+ type = knot_rrsig_type_covered(rr->rrs.rdata);
+ return type;
+}
+
+/** The current time in monotonic milliseconds.
+ *
+ * \note it may be outdated in case of long callbacks; see uv_now().
+ */
+KR_EXPORT
+uint64_t kr_now();
+
+/** Call free(handle->data); it's useful e.g. as a callback in uv_close(). */
+KR_EXPORT void kr_uv_free_cb(uv_handle_t* handle);
+
+/** Convert name from lookup format to wire. See knot_dname_lf
+ *
+ * \note len bytes are read and len+1 are written with *normal* LF,
+ * but it's also allowed that the final zero byte is omitted in LF.
+ * \return the number of bytes written (>0) or error code (<0)
+ */
+int knot_dname_lf2wire(knot_dname_t *dst, uint8_t len, const uint8_t *lf);
+
+/** Patched knot_dname_lf. LF for "." has length zero instead of one, for consistency.
+ * (TODO: consistency?)
+ * \param add_wildcard append the wildcard label
+ * \note packet is always NULL
+ */
+static inline int kr_dname_lf(uint8_t *dst, const knot_dname_t *src, bool add_wildcard)
+{
+ knot_dname_storage_t right_aligned_dst;
+ uint8_t *right_aligned_dname_start = knot_dname_lf(src, right_aligned_dst);
+ if (!right_aligned_dname_start) {
+ return kr_error(EINVAL);
+ }
+ int len = right_aligned_dname_start[0];
+ if (kr_fails_assert(right_aligned_dname_start + 1 + len - KNOT_DNAME_MAXLEN == right_aligned_dst))
+ return kr_error(EINVAL);
+ memcpy(dst + 1, right_aligned_dname_start + 1, len);
+ if (add_wildcard) {
+ if (len + 2 > KNOT_DNAME_MAXLEN)
+ return kr_error(ENOSPC);
+ dst[len + 1] = '*';
+ dst[len + 2] = '\0';
+ len += 2;
+ }
+ dst[0] = len;
+ return KNOT_EOK;
+}
+
+
+/** Timer, i.e stop-watch. */
+typedef struct timespec kr_timer_t;
+
+/** Start, i.e. set the reference point. */
+static inline void kr_timer_start(kr_timer_t *start)
+{
+ /* The call should be very reliable, but let's check it in _start() at least. */
+ kr_require(start && clock_gettime(CLOCK_MONOTONIC, start) == 0);
+}
+
+/** Get elapsed time in floating-point seconds. */
+static inline double kr_timer_elapsed(kr_timer_t *start)
+{
+ kr_require(start);
+ kr_timer_t end = { 0 };
+ (void)clock_gettime(CLOCK_MONOTONIC, &end);
+ return (end.tv_sec - start->tv_sec) + (double)(end.tv_nsec - start->tv_nsec) / 1e9;
+}
+
+/** Get elapsed time in micro-seconds. */
+static inline uint64_t kr_timer_elapsed_us(kr_timer_t *start)
+{
+ kr_require(start);
+ kr_timer_t end = { 0 };
+ (void)clock_gettime(CLOCK_MONOTONIC, &end);
+ // avoid negative differences, because of integer division
+ if (end.tv_nsec - start->tv_nsec < 0) {
+ end.tv_nsec += 1000*1000*1000;
+ end.tv_sec -= 1;
+ }
+ return (uint64_t)(end.tv_sec - start->tv_sec) * 1000000
+ // adding 500 gives us rounding
+ + (end.tv_nsec - start->tv_nsec + 500) / 1000;
+}
+
+
+/**
+ * Difference between two calendar times specified as strings.
+ * \param[in] format format for strptime
+ * \param[out] diff result from C difftime(time1, time0)
+ */
+KR_EXPORT
+const char *kr_strptime_diff(const char *format, const char *time1_str,
+ const char *time0_str, double *diff);
+
+/* Trivial non-inline wrappers, to be used in lua. */
+KR_EXPORT void kr_rrset_init(knot_rrset_t *rrset, knot_dname_t *owner,
+ uint16_t type, uint16_t rclass, uint32_t ttl);
+KR_EXPORT bool kr_pkt_has_wire(const knot_pkt_t *pkt);
+KR_EXPORT bool kr_pkt_has_dnssec(const knot_pkt_t *pkt);
+KR_EXPORT uint16_t kr_pkt_qclass(const knot_pkt_t *pkt);
+KR_EXPORT uint16_t kr_pkt_qtype(const knot_pkt_t *pkt);
+KR_EXPORT uint32_t kr_rrsig_sig_inception(const knot_rdata_t *rdata);
+KR_EXPORT uint32_t kr_rrsig_sig_expiration(const knot_rdata_t *rdata);
+KR_EXPORT uint16_t kr_rrsig_type_covered(const knot_rdata_t *rdata);
+
+KR_EXPORT time_t kr_file_mtime (const char* fname);
+/** Return filesystem size in bytes. */
+KR_EXPORT long long kr_fssize(const char *path);
+/** Simply return de->dname. (useful from Lua) */
+KR_EXPORT const char * kr_dirent_name(const struct dirent *de);
+
diff --git a/lib/zonecut.c b/lib/zonecut.c
new file mode 100644
index 0000000..4ec4036
--- /dev/null
+++ b/lib/zonecut.c
@@ -0,0 +1,590 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#include "lib/zonecut.h"
+
+#include "contrib/cleanup.h"
+#include "lib/defines.h"
+#include "lib/generic/pack.h"
+#include "lib/resolve.h"
+#include "lib/rplan.h"
+
+#include <libknot/descriptor.h>
+#include <libknot/packet/wire.h>
+#include <libknot/rrtype/rdname.h>
+
+#define VERBOSE_MSG(qry, ...) kr_log_q(qry, ZCUT, __VA_ARGS__)
+
+/** Information for one NS name + address type. */
+typedef enum {
+ AI_UNINITED = 0,
+ AI_REPUT, /**< Don't use this addrset, due to: cache_rep, NO_IPV6, ...
+ * cache_rep approximates various problems when fetching the RRset. */
+ AI_CYCLED, /**< Skipped due to cycle detection; see implementation for details. */
+ AI_LAST_BAD = AI_CYCLED, /** bad states: <= AI_LAST_BAD */
+ AI_UNKNOWN, /**< Don't know status of this RRset; various reasons. */
+ AI_EMPTY, /**< No usable address (may mean e.g. just NODATA). */
+ AI_OK, /**< At least one usable address.
+ * LATER: we might be interested whether it's only glue. */
+} addrset_info_t;
+
+
+static void update_cut_name(struct kr_zonecut *cut, const knot_dname_t *name)
+{
+ if (knot_dname_is_equal(name, cut->name)) {
+ return;
+ }
+ knot_dname_t *next_name = knot_dname_copy(name, cut->pool);
+ mm_free(cut->pool, cut->name);
+ cut->name = next_name;
+}
+
+int kr_zonecut_init(struct kr_zonecut *cut, const knot_dname_t *name, knot_mm_t *pool)
+{
+ if (!cut || !name) {
+ return kr_error(EINVAL);
+ }
+
+ memset(cut, 0, sizeof(*cut));
+ cut->name = knot_dname_copy(name, pool);
+ cut->pool = pool;
+ cut->nsset = trie_create(pool);
+ return cut->name && cut->nsset ? kr_ok() : kr_error(ENOMEM);
+}
+
+/** Completely free a pack_t. */
+static inline void free_addr_set(pack_t *pack, knot_mm_t *pool)
+{
+ if (kr_fails_assert(pack)) {
+ /* promised we don't store NULL packs */
+ return;
+ }
+ pack_clear_mm(*pack, mm_free, pool);
+ mm_free(pool, pack);
+}
+/** Trivial wrapper for use in trie_apply, due to ugly casting. */
+static int free_addr_set_cb(trie_val_t *v, void *pool)
+{
+ free_addr_set(*v, pool);
+ return kr_ok();
+}
+
+void kr_zonecut_deinit(struct kr_zonecut *cut)
+{
+ if (!cut) {
+ return;
+ }
+ mm_free(cut->pool, cut->name);
+ if (cut->nsset) {
+ trie_apply(cut->nsset, free_addr_set_cb, cut->pool);
+ trie_free(cut->nsset);
+ }
+ knot_rrset_free(cut->key, cut->pool);
+ knot_rrset_free(cut->trust_anchor, cut->pool);
+}
+
+void kr_zonecut_move(struct kr_zonecut *to, const struct kr_zonecut *from)
+{
+ kr_require(to && from);
+ kr_zonecut_deinit(to);
+ memcpy(to, from, sizeof(*to));
+}
+
+void kr_zonecut_set(struct kr_zonecut *cut, const knot_dname_t *name)
+{
+ if (!cut || !name) {
+ return;
+ }
+ knot_rrset_t *key, *ta;
+ key = cut->key; cut->key = NULL;
+ ta = cut->trust_anchor; cut->trust_anchor = NULL;
+ kr_zonecut_deinit(cut);
+ kr_zonecut_init(cut, name, cut->pool);
+ cut->key = key;
+ cut->trust_anchor = ta;
+}
+
+int kr_zonecut_copy(struct kr_zonecut *dst, const struct kr_zonecut *src)
+{
+ if (!dst || !src) {
+ return kr_error(EINVAL);
+ }
+ if (!dst->nsset) {
+ dst->nsset = trie_create(dst->pool);
+ }
+ /* Copy the contents, one by one. */
+ int ret = kr_ok();
+ trie_it_t *it;
+ for (it = trie_it_begin(src->nsset); !trie_it_finished(it); trie_it_next(it)) {
+ size_t klen;
+ const char * const k = trie_it_key(it, &klen);
+ pack_t **new_pack = (pack_t **)trie_get_ins(dst->nsset, k, klen);
+ if (!new_pack) {
+ ret = kr_error(ENOMEM);
+ break;
+ }
+ const pack_t *old_pack = *trie_it_val(it);
+ ret = pack_clone(new_pack, old_pack, dst->pool);
+ if (ret) break;
+ }
+ trie_it_free(it);
+ return ret;
+}
+
+int kr_zonecut_copy_trust(struct kr_zonecut *dst, const struct kr_zonecut *src)
+{
+ knot_rrset_t *key_copy = NULL;
+ knot_rrset_t *ta_copy = NULL;
+
+ if (src->key) {
+ key_copy = knot_rrset_copy(src->key, dst->pool);
+ if (!key_copy) {
+ return kr_error(ENOMEM);
+ }
+ }
+
+ if (src->trust_anchor) {
+ ta_copy = knot_rrset_copy(src->trust_anchor, dst->pool);
+ if (!ta_copy) {
+ knot_rrset_free(key_copy, dst->pool);
+ return kr_error(ENOMEM);
+ }
+ }
+
+ knot_rrset_free(dst->key, dst->pool);
+ dst->key = key_copy;
+ knot_rrset_free(dst->trust_anchor, dst->pool);
+ dst->trust_anchor = ta_copy;
+
+ return kr_ok();
+}
+
+int kr_zonecut_add(struct kr_zonecut *cut, const knot_dname_t *ns, const void *data, int len)
+{
+ if (kr_fails_assert(cut && ns && cut->nsset && (!data || len > 0)))
+ return kr_error(EINVAL);
+ /* Disabled; add_reverse_pair() misuses this for domain name in rdata. */
+ if (false && data && len != sizeof(struct in_addr)
+ && len != sizeof(struct in6_addr)) {
+ kr_assert(!EINVAL);
+ return kr_error(EINVAL);
+ }
+
+ /* Get a pack_t for the ns. */
+ pack_t **pack = (pack_t **)trie_get_ins(cut->nsset, (const char *)ns, knot_dname_size(ns));
+ if (!pack) return kr_error(ENOMEM);
+ if (*pack == NULL) {
+ *pack = mm_alloc(cut->pool, sizeof(pack_t));
+ if (*pack == NULL) return kr_error(ENOMEM);
+ pack_init(**pack);
+ }
+ /* Insert data (if has any) */
+ if (data == NULL) {
+ return kr_ok();
+ }
+ /* Check for duplicates */
+ if (pack_obj_find(*pack, data, len)) {
+ return kr_ok();
+ }
+ /* Push new address */
+ int ret = pack_reserve_mm(**pack, 1, len, kr_memreserve, cut->pool);
+ if (ret != 0) {
+ return kr_error(ENOMEM);
+ }
+ return pack_obj_push(*pack, data, len);
+}
+
+int kr_zonecut_del(struct kr_zonecut *cut, const knot_dname_t *ns, const void *data, int len)
+{
+ if (!cut || !ns || (data && len <= 0)) {
+ return kr_error(EINVAL);
+ }
+
+ /* Find the address list. */
+ int ret = kr_ok();
+ pack_t *pack = kr_zonecut_find(cut, ns);
+ if (pack == NULL) {
+ return kr_error(ENOENT);
+ }
+ /* Remove address from the pack. */
+ if (data) {
+ ret = pack_obj_del(pack, data, len);
+ }
+ /* No servers left, remove NS from the set. */
+ if (pack->len == 0) {
+ free_addr_set(pack, cut->pool);
+ ret = trie_del(cut->nsset, (const char *)ns, knot_dname_size(ns), NULL);
+ if (kr_fails_assert(ret == 0)) /* only KNOT_ENOENT and that *can't* happen */
+ return kr_error(ret);
+ return kr_ok();
+ }
+
+ return ret;
+}
+
+int kr_zonecut_del_all(struct kr_zonecut *cut, const knot_dname_t *ns)
+{
+ if (!cut || !ns) {
+ return kr_error(EINVAL);
+ }
+
+ /* Find the address list; then free and remove it. */
+ pack_t *pack;
+ int ret = trie_del(cut->nsset, (const char *)ns, knot_dname_size(ns),
+ (trie_val_t *)&pack);
+ if (ret) { /* deletion failed */
+ kr_assert(ret == KNOT_ENOENT);
+ return kr_error(ENOENT);
+ }
+ free_addr_set(pack, cut->pool);
+ return kr_ok();
+}
+
+pack_t *kr_zonecut_find(struct kr_zonecut *cut, const knot_dname_t *ns)
+{
+ if (!cut || !ns) {
+ return NULL;
+ }
+ trie_val_t *val = trie_get_try(cut->nsset, (const char *)ns, knot_dname_size(ns));
+ /* we get pointer to the pack_t pointer */
+ return val ? (pack_t *)*val : NULL;
+}
+
+static int has_address(trie_val_t *v, void *baton_)
+{
+ const pack_t *pack = *v;
+ const bool found = pack != NULL && pack->len != 0;
+ return found;
+}
+
+bool kr_zonecut_is_empty(struct kr_zonecut *cut)
+{
+ if (kr_fails_assert(cut && cut->nsset))
+ return true;
+ return !trie_apply(cut->nsset, has_address, NULL);
+}
+
+int kr_zonecut_set_sbelt(struct kr_context *ctx, struct kr_zonecut *cut)
+{
+ if (!ctx || !cut || !ctx->root_hints.nsset) {
+ return kr_error(EINVAL);
+ }
+
+ trie_apply(cut->nsset, free_addr_set_cb, cut->pool);
+ trie_clear(cut->nsset);
+
+ const uint8_t *const dname_root = (const uint8_t *)/*sign-cast*/("");
+ update_cut_name(cut, dname_root);
+ /* Copy root hints from resolution context. */
+ return kr_zonecut_copy(cut, &ctx->root_hints);
+}
+
+/** Fetch address for zone cut. Any rank is accepted (i.e. glue as well). */
+static addrset_info_t fetch_addr(pack_t *addrs, const knot_dname_t *ns, uint16_t rrtype,
+ int *addr_budget,
+ knot_mm_t *mm_pool, const struct kr_query *qry)
+// LATER(optim.): excessive data copying
+{
+ int rdlen;
+ switch (rrtype) {
+ case KNOT_RRTYPE_A:
+ rdlen = 4;
+ break;
+ case KNOT_RRTYPE_AAAA:
+ rdlen = 16;
+ break;
+ default:
+ kr_assert(!EINVAL);
+ return AI_UNKNOWN;
+ }
+
+ struct kr_context *ctx = qry->request->ctx;
+ struct kr_cache_p peek;
+ if (kr_cache_peek_exact(&ctx->cache, ns, rrtype, &peek) != 0) {
+ return AI_UNKNOWN;
+ }
+ int32_t new_ttl = kr_cache_ttl(&peek, qry, ns, rrtype);
+ if (new_ttl < 0) {
+ return AI_UNKNOWN;
+ }
+
+ knot_rrset_t cached_rr;
+ knot_rrset_init(&cached_rr, /*const-cast*/(knot_dname_t *)ns, rrtype,
+ KNOT_CLASS_IN, new_ttl);
+ if (kr_cache_materialize(&cached_rr.rrs, &peek, mm_pool) < 0) {
+ return AI_UNKNOWN;
+ }
+
+ *addr_budget -= cached_rr.rrs.count - 1;
+ if (*addr_budget < 0) {
+ cached_rr.rrs.count += *addr_budget;
+ *addr_budget = 0;
+ }
+
+ /* Reserve memory in *addrs. Implementation detail:
+ * pack_t cares for lengths, so we don't store those in the data. */
+ const size_t pack_extra_size = cached_rr.rrs.size
+ - cached_rr.rrs.count * offsetof(knot_rdata_t, len);
+ int ret = pack_reserve_mm(*addrs, cached_rr.rrs.count, pack_extra_size,
+ kr_memreserve, mm_pool);
+ kr_require(ret == 0); /* ENOMEM "probably" */
+
+ int usable_cnt = 0;
+ addrset_info_t result = AI_EMPTY;
+ knot_rdata_t *rd = cached_rr.rrs.rdata;
+ for (uint16_t i = 0; i < cached_rr.rrs.count; ++i, rd = knot_rdataset_next(rd)) {
+ if (unlikely(rd->len != rdlen)) {
+ VERBOSE_MSG(qry, "bad NS address length %d for rrtype %d, skipping\n",
+ (int)rd->len, (int)rrtype);
+ continue;
+ }
+ result = AI_OK;
+ ++usable_cnt;
+
+ ret = pack_obj_push(addrs, rd->data, rd->len);
+ kr_assert(!ret); /* didn't fit because of incorrectly reserved memory */
+ /* LATER: for now we lose quite some information here,
+ * as keeping it would need substantial changes on other places,
+ * and it turned out to be premature optimization (most likely).
+ * We might e.g. skip adding unusable addresses,
+ * and either keep some rtt information associated
+ * or even finish up choosing the set to send packets to.
+ * Overall there's some overlap with nsrep.c functionality.
+ */
+ }
+ if (usable_cnt != cached_rr.rrs.count) {
+ VERBOSE_MSG(qry, "usable NS addresses: %d/%d\n",
+ usable_cnt, cached_rr.rrs.count);
+ }
+ return result;
+}
+
+/** Fetch best NS for zone cut. */
+static int fetch_ns(struct kr_context *ctx, struct kr_zonecut *cut,
+ const knot_dname_t *name, const struct kr_query *qry,
+ uint8_t * restrict rank)
+{
+ struct kr_cache_p peek;
+ int ret = kr_cache_peek_exact(&ctx->cache, name, KNOT_RRTYPE_NS, &peek);
+ if (ret != 0) {
+ return ret;
+ }
+ /* Note: we accept *any* rank from the cache. We assume that nothing
+ * completely untrustworthy could get into the cache, e.g out-of-bailiwick
+ * records that weren't validated.
+ */
+ *rank = peek.rank;
+
+ int32_t new_ttl = kr_cache_ttl(&peek, qry, name, KNOT_RRTYPE_NS);
+ if (new_ttl < 0) {
+ return kr_error(ESTALE);
+ }
+ /* Materialize the rdataset temporarily, for simplicity. */
+ knot_rdataset_t ns_rds = { 0 };
+ ret = kr_cache_materialize(&ns_rds, &peek, cut->pool);
+ if (ret < 0) {
+ return ret;
+ }
+
+ /* Consider at most 13 first NSs (like root). It's a trivial approach
+ * to limit our resources when choosing NSs. Otherwise DoS might be viable.
+ * We're not aware of any reasonable use case for having many NSs. */
+ if (ns_rds.count > 13) {
+ if (kr_log_is_debug_qry(ZCUT, qry)) {
+ auto_free char *name_txt = kr_dname_text(name);
+ VERBOSE_MSG(qry, "NS %s too large, reducing from %d names\n",
+ name_txt, (int)ns_rds.count);
+ }
+ ns_rds.count = 13;
+ }
+ /* Also trivially limit the total address count:
+ * first A and first AAAA are for free per NS,
+ * but the rest get a shared small limit and get skipped if exhausted. */
+ int addr_budget = 8;
+
+ /* Insert name servers for this zone cut, addresses will be looked up
+ * on-demand (either from cache or iteratively) */
+ bool all_bad = true; /**< All NSs (seen so far) are in a bad state. */
+ knot_rdata_t *rdata_i = ns_rds.rdata;
+ for (unsigned i = 0; i < ns_rds.count;
+ ++i, rdata_i = knot_rdataset_next(rdata_i)) {
+ const knot_dname_t *ns_name = knot_ns_name(rdata_i);
+ const size_t ns_size = knot_dname_size(ns_name);
+
+ /* Get a new pack within the nsset. */
+ pack_t **pack = (pack_t **)trie_get_ins(cut->nsset,
+ (const char *)ns_name, ns_size);
+ if (!pack) return kr_error(ENOMEM);
+ kr_assert(!*pack); /* not critical, really */
+ *pack = mm_alloc(cut->pool, sizeof(pack_t));
+ if (!*pack) return kr_error(ENOMEM);
+ pack_init(**pack);
+
+ addrset_info_t infos[2];
+
+ /* Fetch NS reputation and decide whether to prefetch A/AAAA records. */
+ infos[0] = fetch_addr(*pack, ns_name, KNOT_RRTYPE_A, &addr_budget,
+ cut->pool, qry);
+ infos[1] = fetch_addr(*pack, ns_name, KNOT_RRTYPE_AAAA, &addr_budget,
+ cut->pool, qry);
+
+ #if 0 /* rather unlikely to be useful unless changing some zcut code */
+ if (kr_log_is_debug_qry(ZCUT, qry)) {
+ auto_free char *ns_name_txt = kr_dname_text(ns_name);
+ VERBOSE_MSG(qry, "NS %s infos: %d, %d\n",
+ ns_name_txt, (int)infos[0], (int)infos[1]);
+ }
+ #endif
+
+ /* AI_CYCLED checks.
+ * If an ancestor query has its zone cut in the state that
+ * it's looking for name or address(es) of some NS(s),
+ * we want to avoid doing so with a NS that lies under its cut.
+ * Instead we need to consider such names unusable in the cut (for now). */
+ if (infos[0] != AI_UNKNOWN && infos[1] != AI_UNKNOWN) {
+ /* Optimization: the following loop would be pointless. */
+ all_bad = false;
+ continue;
+ }
+ for (const struct kr_query *aq = qry; aq->parent; aq = aq->parent) {
+ const struct kr_qflags *aqpf = &aq->parent->flags;
+ if ( (aqpf->AWAIT_CUT && aq->stype == KNOT_RRTYPE_NS)
+ || (aqpf->AWAIT_IPV4 && aq->stype == KNOT_RRTYPE_A)
+ || (aqpf->AWAIT_IPV6 && aq->stype == KNOT_RRTYPE_AAAA)) {
+ if (knot_dname_in_bailiwick(ns_name,
+ aq->parent->zone_cut.name)) {
+ for (int j = 0; j < 2; ++j)
+ if (infos[j] == AI_UNKNOWN)
+ infos[j] = AI_CYCLED;
+ break;
+ }
+ } else {
+ /* This ancestor waits for other reason that
+ * NS name or address, so we're out of a direct cycle. */
+ break;
+ }
+ }
+ all_bad = all_bad && infos[0] <= AI_LAST_BAD && infos[1] <= AI_LAST_BAD;
+ }
+
+ if (all_bad && kr_log_is_debug_qry(ZCUT, qry)) {
+ auto_free char *name_txt = kr_dname_text(name);
+ VERBOSE_MSG(qry, "cut %s: all NSs bad, count = %d\n",
+ name_txt, (int)ns_rds.count);
+ }
+
+ kr_assert(addr_budget >= 0);
+ if (addr_budget <= 0 && kr_log_is_debug_qry(ZCUT, qry)) {
+ auto_free char *name_txt = kr_dname_text(name);
+ VERBOSE_MSG(qry, "NS %s have too many addresses together, reduced\n",
+ name_txt);
+ }
+
+ knot_rdataset_clear(&ns_rds, cut->pool);
+ return all_bad ? ELOOP : kr_ok();
+}
+
+/**
+ * Fetch secure RRSet of given type.
+ */
+static int fetch_secure_rrset(knot_rrset_t **rr, struct kr_cache *cache,
+ const knot_dname_t *owner, uint16_t type, knot_mm_t *pool,
+ const struct kr_query *qry)
+{
+ if (kr_fails_assert(rr))
+ return kr_error(EINVAL);
+ /* peek, check rank and TTL */
+ struct kr_cache_p peek;
+ int ret = kr_cache_peek_exact(cache, owner, type, &peek);
+ if (ret != 0)
+ return ret;
+ if (!kr_rank_test(peek.rank, KR_RANK_SECURE))
+ return kr_error(ENOENT);
+ int32_t new_ttl = kr_cache_ttl(&peek, qry, owner, type);
+ if (new_ttl < 0)
+ return kr_error(ESTALE);
+ /* materialize a new RRset */
+ knot_rrset_free(*rr, pool);
+ *rr = mm_alloc(pool, sizeof(knot_rrset_t));
+ if (*rr == NULL)
+ return kr_error(ENOMEM);
+ owner = knot_dname_copy(/*const-cast*/(knot_dname_t *)owner, pool);
+ if (!owner) {
+ mm_free(pool, *rr);
+ *rr = NULL;
+ return kr_error(ENOMEM);
+ }
+ knot_rrset_init(*rr, /*const-cast*/(knot_dname_t *)owner, type,
+ KNOT_CLASS_IN, new_ttl);
+ ret = kr_cache_materialize(&(*rr)->rrs, &peek, pool);
+ if (ret < 0) {
+ knot_rrset_free(*rr, pool);
+ *rr = NULL;
+ return ret;
+ }
+
+ return kr_ok();
+}
+
+int kr_zonecut_find_cached(struct kr_context *ctx, struct kr_zonecut *cut,
+ const knot_dname_t *name, const struct kr_query *qry,
+ bool * restrict secured)
+{
+ if (!ctx || !cut || !name)
+ return kr_error(EINVAL);
+ /* I'm not sure whether the caller always passes a clean state;
+ * mixing doesn't seem to make sense in any case, so let's clear it.
+ * We don't bother freeing the packs, as they're on mempool. */
+ trie_clear(cut->nsset);
+ /* Copy name as it may overlap with cut name that is to be replaced. */
+ knot_dname_t *qname = knot_dname_copy(name, cut->pool);
+ if (!qname) {
+ return kr_error(ENOMEM);
+ }
+ /* Start at QNAME. */
+ int ret;
+ const knot_dname_t *label = qname;
+ while (true) {
+ /* Fetch NS first and see if it's insecure. */
+ uint8_t rank = 0;
+ const bool is_root = (label[0] == '\0');
+ ret = fetch_ns(ctx, cut, label, qry, &rank);
+ if (ret == 0) {
+ /* Flag as insecure if cached as this */
+ if (kr_rank_test(rank, KR_RANK_INSECURE)) {
+ *secured = false;
+ }
+ /* Fetch DS and DNSKEY if caller wants secure zone cut */
+ int ret_ds = 1, ret_dnskey = 1;
+ if (*secured || is_root) {
+ ret_ds = fetch_secure_rrset(&cut->trust_anchor, &ctx->cache,
+ label, KNOT_RRTYPE_DS, cut->pool, qry);
+ ret_dnskey = fetch_secure_rrset(&cut->key, &ctx->cache,
+ label, KNOT_RRTYPE_DNSKEY, cut->pool, qry);
+ }
+ update_cut_name(cut, label);
+ if (kr_log_is_debug_qry(ZCUT, qry)) {
+ auto_free char *label_str = kr_dname_text(label);
+ VERBOSE_MSG(qry,
+ "found cut: %s (rank 0%.2o return codes: DS %d, DNSKEY %d)\n",
+ label_str, rank, ret_ds, ret_dnskey);
+ }
+ ret = kr_ok();
+ break;
+ } /* else */
+
+ trie_clear(cut->nsset);
+ /* Subtract label from QNAME. */
+ if (!is_root) {
+ label = knot_wire_next_label(label, NULL);
+ } else {
+ ret = kr_error(ENOENT);
+ break;
+ }
+ }
+
+ kr_cache_commit(&ctx->cache);
+ mm_free(cut->pool, qname);
+ return ret;
+}
diff --git a/lib/zonecut.h b/lib/zonecut.h
new file mode 100644
index 0000000..9c960ec
--- /dev/null
+++ b/lib/zonecut.h
@@ -0,0 +1,164 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#include "lib/cache/api.h"
+#include "lib/defines.h"
+#include "lib/generic/pack.h"
+#include "lib/generic/trie.h"
+
+
+struct kr_rplan;
+struct kr_context;
+
+/**
+ * Current zone cut representation.
+*/
+struct kr_zonecut {
+ knot_dname_t *name; /**< Zone cut name. */
+ knot_rrset_t* key; /**< Zone cut DNSKEY. */
+ knot_rrset_t* trust_anchor; /**< Current trust anchor. */
+ struct kr_zonecut *parent; /**< Parent zone cut. */
+ trie_t *nsset; /**< Map of nameserver => address_set (pack_t). */
+ knot_mm_t *pool; /**< Memory pool. */
+};
+
+/**
+ * Populate root zone cut with SBELT.
+ * @param cut zone cut
+ * @param name
+ * @param pool
+ * @return 0 or error code
+ */
+KR_EXPORT
+int kr_zonecut_init(struct kr_zonecut *cut, const knot_dname_t *name, knot_mm_t *pool);
+
+/**
+ * Clear the structure and free the address set.
+ * @param cut zone cut
+ */
+KR_EXPORT
+void kr_zonecut_deinit(struct kr_zonecut *cut);
+
+/**
+ * Move a zonecut, transferring ownership of any pointed-to memory.
+ * @param to the target - it gets deinit-ed
+ * @param from the source - not modified, but shouldn't be used afterward
+ */
+KR_EXPORT
+void kr_zonecut_move(struct kr_zonecut *to, const struct kr_zonecut *from);
+
+/**
+ * Reset zone cut to given name and clear address list.
+ * @note This clears the address list even if the name doesn't change. TA and DNSKEY don't change.
+ * @param cut zone cut to be set
+ * @param name new zone cut name
+ */
+KR_EXPORT
+void kr_zonecut_set(struct kr_zonecut *cut, const knot_dname_t *name);
+
+/**
+ * Copy zone cut, including all data. Does not copy keys and trust anchor.
+ * @param dst destination zone cut
+ * @param src source zone cut
+ * @return 0 or an error code; If it fails with kr_error(ENOMEM),
+ * it may be in a half-filled state, but it's safe to deinit...
+ * @note addresses for names in `src` get replaced and others are left as they were.
+ */
+KR_EXPORT
+int kr_zonecut_copy(struct kr_zonecut *dst, const struct kr_zonecut *src);
+
+/**
+ * Copy zone trust anchor and keys.
+ * @param dst destination zone cut
+ * @param src source zone cut
+ * @return 0 or an error code
+ */
+KR_EXPORT
+int kr_zonecut_copy_trust(struct kr_zonecut *dst, const struct kr_zonecut *src);
+
+/**
+ * Add address record to the zone cut.
+ *
+ * The record will be merged with existing data,
+ * it may be either A/AAAA type.
+ *
+ * @param cut zone cut to be populated
+ * @param ns nameserver name
+ * @param data typically knot_rdata_t::data
+ * @param len typically knot_rdata_t::len
+ * @return 0 or error code
+ */
+KR_EXPORT
+int kr_zonecut_add(struct kr_zonecut *cut, const knot_dname_t *ns, const void *data, int len);
+
+/**
+ * Delete nameserver/address pair from the zone cut.
+ * @param cut
+ * @param ns name server name
+ * @param data typically knot_rdata_t::data
+ * @param len typically knot_rdata_t::len
+ * @return 0 or error code
+ */
+KR_EXPORT
+int kr_zonecut_del(struct kr_zonecut *cut, const knot_dname_t *ns, const void *data, int len);
+
+/**
+ * Delete all addresses associated with the given name.
+ * @param cut
+ * @param ns name server name
+ * @return 0 or error code
+ */
+KR_EXPORT
+int kr_zonecut_del_all(struct kr_zonecut *cut, const knot_dname_t *ns);
+
+/**
+ * Find nameserver address list in the zone cut.
+ *
+ * @note This can be used for membership test, a non-null pack is returned
+ * if the nameserver name exists.
+ *
+ * @param cut
+ * @param ns name server name
+ * @return pack of addresses or NULL
+ */
+KR_EXPORT KR_PURE
+pack_t *kr_zonecut_find(struct kr_zonecut *cut, const knot_dname_t *ns);
+
+/**
+ * Populate zone cut with a root zone using SBELT :rfc:`1034`
+ *
+ * @param ctx resolution context (to fetch root hints)
+ * @param cut zone cut to be populated
+ * @return 0 or error code
+ */
+KR_EXPORT
+int kr_zonecut_set_sbelt(struct kr_context *ctx, struct kr_zonecut *cut);
+
+/**
+ * Populate zone cut address set from cache.
+ *
+ * The size is limited to avoid possibility of doing too much CPU work.
+ *
+ * @param ctx resolution context (to fetch data from LRU caches)
+ * @param cut zone cut to be populated
+ * @param name QNAME to start finding zone cut for
+ * @param qry query for timestamp and stale-serving decisions
+ * @param secured set to true if want secured zone cut, will return false if it is provably insecure
+ * @return 0 or error code (ENOENT if it doesn't find anything)
+ */
+KR_EXPORT
+int kr_zonecut_find_cached(struct kr_context *ctx, struct kr_zonecut *cut,
+ const knot_dname_t *name, const struct kr_query *qry,
+ bool * restrict secured);
+/**
+ * Check if any address is present in the zone cut.
+ *
+ * @param cut zone cut to check
+ * @return true/false
+ */
+KR_EXPORT
+bool kr_zonecut_is_empty(struct kr_zonecut *cut);
+
diff --git a/meson.build b/meson.build
new file mode 100644
index 0000000..795947e
--- /dev/null
+++ b/meson.build
@@ -0,0 +1,357 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+project(
+ 'knot-resolver',
+ ['c', 'cpp'],
+ license: 'GPLv3+',
+ version: '5.6.0',
+ default_options: ['c_std=gnu11', 'b_ndebug=true'],
+ meson_version: '>=0.49',
+)
+
+
+# Unity build
+if get_option('unity') != 'off'
+ error('unity builds are not supported! ' +
+ 'https://gitlab.nic.cz/knot/knot-resolver/issues/460')
+endif
+
+
+message('--- required dependencies ---')
+knot_version = '>=3.0.2'
+libknot = dependency('libknot', version: knot_version)
+libdnssec = dependency('libdnssec', version: knot_version)
+libzscanner = dependency('libzscanner', version: knot_version)
+libuv = dependency('libuv', version: '>=1.7')
+lmdb = dependency('lmdb', required: false)
+if not lmdb.found() # darwin workaround: missing pkgconfig
+ lmdb = meson.get_compiler('c').find_library('lmdb')
+endif
+gnutls = dependency('gnutls')
+luajit = dependency('luajit')
+# NOTE avoid using link_args for luajit due to a macOS issue
+# https://github.com/Homebrew/homebrew-core/issues/37169
+luajit_inc = luajit.partial_dependency(compile_args: true, includes: true)
+message('------------------------------')
+
+
+# Variables
+libkres_soversion = 9
+
+libext = '.so'
+if host_machine.system() == 'darwin'
+ libext = '.dylib'
+endif
+
+## Paths
+prefix = get_option('prefix')
+data_dir = prefix / get_option('datadir') / 'knot-resolver'
+doc_dir = prefix / get_option('datadir') / 'doc' / 'knot-resolver'
+info_dir = prefix / get_option('datadir') / 'info'
+examples_dir = doc_dir / 'examples'
+etc_dir = prefix / get_option('sysconfdir') / 'knot-resolver'
+lib_dir = prefix / get_option('libdir') / 'knot-resolver'
+modules_dir = lib_dir / 'kres_modules'
+sbin_dir = prefix / get_option('sbindir')
+run_dir = '/run' / 'knot-resolver'
+systemd_work_dir = prefix / get_option('localstatedir') / 'lib' / 'knot-resolver'
+systemd_cache_dir = prefix / get_option('localstatedir') / 'cache' / 'knot-resolver'
+systemd_unit_dir = prefix / 'lib' / 'systemd' / 'system'
+systemd_tmpfiles_dir = prefix / 'lib' / 'tmpfiles.d'
+systemd_sysusers_dir = prefix / 'lib' / 'sysusers.d'
+mod_inc_dir = include_directories('.', 'contrib/')
+
+## Trust anchors
+managed_ta = get_option('managed_ta') == 'enabled'
+keyfile_default = etc_dir / get_option('keyfile_default')
+if keyfile_default == etc_dir / 'root.keys'
+ managed_ta = managed_ta or get_option('managed_ta') == 'auto'
+endif
+install_root_keys = get_option('install_root_keys') == 'enabled'
+if get_option('install_root_keys') == 'auto'
+ install_root_keys = managed_ta
+endif
+
+
+## Root hints
+root_hints = etc_dir / get_option('root_hints')
+if root_hints == etc_dir / 'root.hints'
+ install_root_hints = true
+else
+ install_root_hints = false
+endif
+
+## Additional options
+user = get_option('user')
+group = get_option('group')
+
+## Optional dependencies
+message('--- optional dependencies ---')
+nghttp2 = dependency('libnghttp2', required: false)
+openssl = dependency('openssl', required: false)
+
+have_asprintf = meson.get_compiler('c').has_function('asprintf',
+ prefix: '#define _GNU_SOURCE\n#include <stdio.h>')
+
+### capng
+# use empty name to disable the dependency, but still compile the dependent kresd
+capng_name = get_option('capng') == 'disabled' ? '' : 'libcap-ng'
+capng = dependency(capng_name, required: get_option('capng') == 'enabled')
+
+### sendmmsg
+has_sendmmsg = meson.get_compiler('c').has_function('sendmmsg',
+ prefix: '#define _GNU_SOURCE\n#include <sys/socket.h>')
+if get_option('sendmmsg') == 'enabled' and not has_sendmmsg
+ error('missing compiler function: sendmmsg(), use -Dsendmmsg=disabled')
+elif get_option('sendmmsg') == 'auto'
+ sendmmsg = has_sendmmsg
+else
+ sendmmsg = get_option('sendmmsg') == 'enabled'
+endif
+
+### XDP: not configurable - we just check if libknot supports it
+xdp = meson.get_compiler('c').has_header('libknot/xdp/xdp.h')
+
+### Systemd
+systemd_files = get_option('systemd_files')
+libsystemd = dependency('libsystemd', required: systemd_files == 'enabled')
+
+### Allocator
+# use empty name to disable the dependency, but still compile the dependent kresd
+malloc_name = get_option('malloc') == 'disabled' ? '' : 'jemalloc'
+malloc = meson.get_compiler('c').find_library(
+ malloc_name,
+ required: get_option('malloc') == 'jemalloc',
+ #static: false, #TODO: add when bumping meson to >= 0.51;
+ # static linking would most likely cause issues.
+ # Fortunately it seems unlikely that dynamic wouldn't be found and static would be.
+)
+
+message('---------------------------')
+
+## Compiler args
+add_project_arguments(
+ '-D_GNU_SOURCE',
+ '-Wformat',
+ '-Wformat-security',
+ '-Wtype-limits',
+ '-Wshadow',
+ '-Werror=implicit-function-declaration', # Probably messed up includes; implicit functions are evil!
+ '-Werror=attributes', # Missing cleanup attribute could lead to memory leaks.
+ '-fvisibility=hidden',
+ '-DHAVE_ASPRINTF=' + have_asprintf.to_int().to_string(),
+
+ # libuv handles have aliasing problems; see:
+ # https://github.com/libuv/libuv/pull/2588/files#diff-04c6e90faac2675aa89e2176d2eec7d8
+ # https://github.com/libuv/libuv/issues/1230#issuecomment-569030944
+ # Performance impact in our case seems OK:
+ # https://gitlab.nic.cz/knot/knot-resolver/-/merge_requests/962#note_147407
+ '-fno-strict-aliasing',
+
+ language: 'c',
+)
+
+# Files for clang-tidy lint
+c_src_lint = files()
+
+# Lists of tests
+# These lists are added to from subdir() and finally used in tests/*
+
+unit_tests = [
+ # [test_name, files(test)]
+]
+
+config_tests = [
+ # [name, files(test)] # or
+ # [name, files(test), [extra_suites]]
+]
+
+integr_tests = [
+ # [name, test_dir_relative_to_src_root]
+]
+
+
+# kresconfig.h
+conf_data = configuration_data()
+conf_data.set_quoted('PACKAGE_VERSION', meson.project_version())
+conf_data.set_quoted('LIBDIR', lib_dir)
+conf_data.set_quoted('ROOTHINTS', root_hints)
+conf_data.set_quoted('LIBEXT', libext)
+conf_data.set_quoted('OPERATING_SYSTEM', host_machine.system())
+conf_data.set_quoted('libzscanner_SONAME',
+ libzscanner.get_pkgconfig_variable('soname'))
+conf_data.set_quoted('libknot_SONAME',
+ libknot.get_pkgconfig_variable('soname'))
+conf_data.set('ENABLE_LIBSYSTEMD', libsystemd.found().to_int())
+conf_data.set('ENABLE_SENDMMSG', sendmmsg.to_int())
+conf_data.set('ENABLE_XDP', xdp.to_int())
+conf_data.set('ENABLE_CAP_NG', capng.found().to_int())
+conf_data.set('ENABLE_JEMALLOC', malloc.found().to_int())
+conf_data.set('ENABLE_DOH2', nghttp2.found().to_int())
+conf_data.set('DBG_ASSERTION_ABORT', get_option('debug').to_int())
+if get_option('debug')
+ conf_data.set('DBG_ASSERTION_FORK', '0')
+else
+ conf_data.set('DBG_ASSERTION_FORK', '(5 * 60 * 1000) /* five minutes */')
+endif
+
+kresconfig = configure_file(
+ output: 'kresconfig.h',
+ configuration: conf_data,
+)
+
+kresconfig_dep = declare_dependency(
+ sources: kresconfig,
+ include_directories: include_directories('.'),
+)
+
+
+# Compile
+## Dependencies first
+subdir('contrib')
+subdir('lib')
+
+## Remaining code
+subdir('daemon')
+subdir('modules')
+subdir('utils')
+if get_option('bench') == 'enabled'
+ subdir('bench')
+endif
+
+
+# Tests
+subdir('tests')
+
+
+# Documentation & configs
+subdir('doc')
+subdir('etc')
+
+
+# Systemd unit files
+if systemd_files != 'disabled'
+ subdir('systemd')
+endif
+
+
+# Additional files
+install_data(
+ sources: [
+ 'AUTHORS',
+ 'COPYING',
+ 'NEWS',
+ ],
+ install_dir: doc_dir,
+)
+
+
+# Lint
+message('--- lint dependencies ---')
+clangtidy = find_program('clang-tidy', required: false)
+luacheck = find_program('luacheck', required: false)
+flake8 = find_program('flake8', required: false)
+pylint_run = find_program('scripts/run-pylint.sh')
+message('-------------------------')
+
+if clangtidy.found()
+ run_target(
+ 'tidy',
+ command: [
+ clangtidy,
+ '-quiet',
+ '-p', meson.build_root(),
+ ] + c_src_lint
+ )
+endif
+
+if luacheck.found()
+ run_target(
+ 'luacheck',
+ command: [
+ luacheck,
+ '--codes',
+ '--formatter', 'TAP',
+ meson.source_root(),
+ ],
+ )
+endif
+
+if flake8.found()
+ run_target(
+ 'flake8',
+ command: [
+ flake8,
+ '--max-line-length=100',
+ meson.source_root() / 'tests' / 'pytests',
+ ],
+ )
+endif
+
+run_target(
+ 'pylint',
+ command: pylint_run,
+)
+
+
+# Summary message
+# NOTE: ternary operator in format() not supported
+# https://github.com/mesonbuild/meson/issues/2404
+s_managed_ta = managed_ta ? 'enabled' : 'disabled'
+s_install_root_keys = install_root_keys ? 'enabled' : 'disabled'
+s_build_client = build_client ? 'enabled' : 'disabled'
+s_build_utils = build_utils ? 'enabled' : 'disabled'
+s_build_dnstap = build_dnstap ? 'enabled' : 'disabled'
+s_build_unit_tests = build_unit_tests ? 'enabled' : 'disabled'
+s_build_config_tests = build_config_tests ? 'enabled' : 'disabled'
+s_build_extra_tests = build_extra_tests ? 'enabled' : 'disabled'
+s_install_kresd_conf = install_kresd_conf ? 'enabled' : 'disabled'
+s_sendmmsg = sendmmsg ? 'enabled': 'disabled'
+s_xdp = xdp ? 'enabled': 'disabled'
+s_openssl = openssl.found() ? 'present': 'missing'
+s_capng = capng.found() ? 'enabled': 'disabled'
+s_malloc = malloc.found() ? 'jemalloc' : 'libc default'
+s_doh2 = nghttp2.found() ? 'enabled': 'disabled'
+message('''
+
+======================= SUMMARY =======================
+
+ paths
+ prefix: @0@'''.format(prefix) + '''
+ lib_dir: @0@'''.format(lib_dir) + '''
+ sbin_dir: @0@'''.format(sbin_dir) + '''
+ etc_dir: @0@'''.format(etc_dir) + '''
+ root.hints: @0@'''.format(root_hints) + '''
+
+ trust_anchors
+ keyfile_default: @0@'''.format(keyfile_default) + '''
+ managed_ta: @0@'''.format(s_managed_ta) + '''
+ install_root_keys: @0@'''.format(s_install_root_keys) + '''
+
+ systemd:
+ files: @0@'''.format(systemd_files) + '''
+ work_dir: @0@'''.format(systemd_work_dir) + '''
+ cache_dir: @0@'''.format(systemd_cache_dir) + '''
+
+ optional components
+ client: @0@'''.format(s_build_client) + '''
+ utils: @0@'''.format(s_build_utils) + '''
+ dnstap: @0@'''.format(s_build_dnstap) + '''
+ unit_tests: @0@'''.format(s_build_unit_tests) + '''
+ config_tests: @0@'''.format(s_build_config_tests) + '''
+ extra_tests: @0@'''.format(s_build_extra_tests) + '''
+
+ additional
+ user: @0@'''.format(user) + '''
+ group: @0@'''.format(group) + '''
+ install_kresd_conf: @0@'''.format(s_install_kresd_conf) + '''
+ sendmmsg: @0@'''.format(s_sendmmsg) + '''
+ XDP (in libknot): @0@'''.format(s_xdp) + '''
+ openssl debug: @0@'''.format(s_openssl) + '''
+ capng: @0@'''.format(s_capng) + '''
+ malloc: @0@'''.format(s_malloc) + '''
+ doh2: @0@'''.format(s_doh2) + '''
+
+=======================================================
+
+''')
diff --git a/meson_options.txt b/meson_options.txt
new file mode 100644
index 0000000..576d385
--- /dev/null
+++ b/meson_options.txt
@@ -0,0 +1,219 @@
+# Configuration options
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+option(
+ 'keyfile_default',
+ type: 'string',
+ value: 'root.keys',
+ description: 'built-in path to DNSSEC trust anchors file',
+)
+
+option(
+ 'managed_ta',
+ type: 'combo',
+ choices: [
+ 'auto',
+ 'enabled',
+ 'disabled',
+ ],
+ value: 'auto',
+ description: 'auto-manage DNSSEC trust anchors (RFC 5011)',
+)
+
+option(
+ 'root_hints',
+ type: 'string',
+ value: 'root.hints',
+ description: 'built-in path to root.hints file',
+)
+
+option(
+ 'install_kresd_conf',
+ type: 'combo',
+ choices: [
+ 'auto',
+ 'enabled',
+ 'disabled',
+ ],
+ value: 'auto',
+ description: 'creates kresd.conf in config directory',
+)
+
+option(
+ 'install_root_keys',
+ type: 'combo',
+ choices: [
+ 'auto',
+ 'enabled',
+ 'disabled',
+ ],
+ value: 'auto',
+ description: 'installs DNSSEC TA to keyfile_default location',
+)
+
+option(
+ 'user',
+ type: 'string',
+ value: 'knot-resolver',
+ description: 'user which is used for running kresd',
+)
+
+option(
+ 'group',
+ type: 'string',
+ value: 'knot-resolver',
+ description: 'group which is used for running kresd',
+)
+
+option(
+ 'sendmmsg',
+ type: 'combo',
+ choices: [
+ 'auto',
+ 'enabled',
+ 'disabled',
+ ],
+ value: 'auto',
+ description: 'use sendmmsg syscall towards clients',
+)
+
+option(
+ 'capng',
+ type: 'combo',
+ choices: [
+ 'auto',
+ 'enabled',
+ 'disabled',
+ ],
+ value: 'auto',
+ description: 'use libcapng to drop capabilities for non-root users',
+)
+
+## Systemd
+option(
+ 'systemd_files',
+ type: 'combo',
+ choices: [
+ 'disabled',
+ 'enabled',
+ ],
+ value: 'disabled',
+ description: 'installs systemd-related files',
+)
+
+
+# Component options
+option(
+ 'bench',
+ type: 'combo',
+ choices: [
+ 'auto',
+ 'enabled',
+ 'disabled',
+ ],
+ value: 'disabled',
+ description: 'build benchmarks',
+)
+
+option(
+ 'client',
+ type: 'combo',
+ choices: [
+ 'auto',
+ 'enabled',
+ 'disabled',
+ ],
+ value: 'auto',
+ description: 'build kresc client binary',
+)
+
+option(
+ 'utils',
+ type: 'combo',
+ choices: [
+ 'auto',
+ 'enabled',
+ 'disabled',
+ ],
+ value: 'auto',
+ description: 'build kres utilities',
+)
+
+option(
+ 'dnstap',
+ type: 'combo',
+ choices: [
+ 'auto',
+ 'enabled',
+ 'disabled',
+ ],
+ value: 'auto',
+ description: 'build dnstap module',
+)
+
+option(
+ 'malloc',
+ type: 'combo',
+ choices: [
+ 'auto', # 'jemalloc' if available
+ 'disabled', # default provided by libc
+ 'jemalloc',
+ ],
+ value: 'auto',
+ description: 'memory allocator to use in kresd',
+)
+
+option(
+ 'doc',
+ type: 'combo',
+ choices: [
+ 'auto',
+ 'enabled',
+ 'disabled',
+ ],
+ value: 'disabled',
+ description: 'html documentation dependencies and installation',
+)
+
+option(
+ 'kres_gen_test',
+ type: 'boolean',
+ value: true,
+ description: 'run kres_gen_test: a simple sanity check for our lua bindings',
+)
+
+option(
+ 'config_tests',
+ type: 'combo',
+ choices: [
+ 'auto',
+ 'enabled',
+ 'disabled',
+ ],
+ value: 'auto',
+ description: 'postinstall config tests',
+)
+
+option(
+ 'extra_tests',
+ type: 'combo',
+ choices: [
+ 'auto',
+ 'enabled',
+ 'disabled',
+ ],
+ value: 'disabled',
+ description: 'postinstall tests with extra dependencies',
+)
+
+option(
+ 'unit_tests',
+ type: 'combo',
+ choices: [
+ 'auto',
+ 'enabled',
+ 'disabled',
+ ],
+ value: 'auto',
+ description: 'cmocka unit tests',
+)
diff --git a/modules/README.rst b/modules/README.rst
new file mode 100644
index 0000000..1096c37
--- /dev/null
+++ b/modules/README.rst
@@ -0,0 +1,251 @@
+.. SPDX-License-Identifier: GPL-3.0-or-later
+
+.. _modules-api:
+
+*********************
+Modules API reference
+*********************
+
+.. contents::
+ :depth: 1
+ :local:
+
+Supported languages
+===================
+
+Currently modules written in C and Lua(JIT) are supported.
+
+The anatomy of an extension
+===========================
+
+A module is a shared object or script defining specific functions/fields; here's an overview.
+
+.. csv-table::
+ :header: "C", "Lua", "Params", "Comment"
+
+ "``X_api()`` [#]_", "", "", "API version"
+ "``X_init()``", "``X.init()``", "``module``", "Constructor"
+ "``X_deinit()``", "``X.deinit()``", "``module``", "Destructor"
+ "``X_config()``", "``X.config()``", "``module, str``", "Configuration"
+ "``X_layer``", "``X.layer``", "", ":ref:`Module layer <lib-layers>`"
+ "``X_props``", "", "", "List of properties"
+
+.. [#] Mandatory symbol; defined by using :c:func:`KR_MODULE_EXPORT`.
+
+The ``X`` corresponds to the module name; if the module name is ``hints``, the prefix for constructor would be ``hints_init()``.
+More details are in docs for the :c:type:`kr_module` and :c:type:`kr_layer_api` structures.
+
+.. note::
+ The modules get ordered -- by default in the same as the order in which they were loaded. The loading command can specify where in the order the module should be positioned.
+
+
+Writing a module in Lua
+=======================
+
+The probably most convenient way of writing modules is Lua since you can use already installed modules
+from system and have first-class access to the scripting engine. You can also tap to all the events, that
+the C API has access to, but keep in mind that transitioning from the C to Lua function is slower than
+the other way round, especially when JIT-compilation is taken into account.
+
+.. note:: The Lua functions retrieve an additional first parameter compared to the C counterparts - a "state".
+ Most useful C functions and structures have lua FFI wrappers, sometimes with extra sugar.
+
+The modules follow the `Lua way <http://lua-users.org/wiki/ModuleDefinition>`_, where the module interface is returned in a named table.
+
+.. code-block:: lua
+
+ --- @module Count incoming queries
+ local counter = {}
+
+ function counter.init(module)
+ counter.total = 0
+ counter.last = 0
+ counter.failed = 0
+ end
+
+ function counter.deinit(module)
+ print('counted', counter.total, 'queries')
+ end
+
+ -- @function Run the q/s counter with given interval.
+ function counter.config(conf)
+ -- We can use the scripting facilities here
+ if counter.ev then event.cancel(counter.ev)
+ event.recurrent(conf.interval, function ()
+ print(counter.total - counter.last, 'q/s')
+ counter.last = counter.total
+ end)
+ end
+
+ return counter
+
+.. vv Hmm, we do not use these coroutine returns anywhere, so it's unclear whether they still work OK. Splitting work over time is now typically done via the ``event`` timers.
+
+.. The API functions may return an integer value just like in other languages, but they may also return a coroutine that will be continued asynchronously. A good use case for this approach is is a deferred initialization, e.g. loading a chunks of data or waiting for I/O.
+
+.. .. code-block:: lua
+
+ function counter.init(module)
+ counter.total = 0
+ counter.last = 0
+ counter.failed = 0
+ return coroutine.create(function ()
+ for line in io.lines('/etc/hosts') do
+ load(module, line)
+ coroutine.yield()
+ end
+ end)
+ end
+
+The created module can be then loaded just like any other module, except it isn't very useful since it
+doesn't provide any layer to capture events. The Lua module can however provide a processing layer, just
+:ref:`like its C counterpart <lib-layers>`.
+
+.. code-block:: lua
+
+ -- Notice it isn't a function, but a table of functions
+ counter.layer = {
+ begin = function (state, data)
+ counter.total = counter.total + 1
+ return state
+ end,
+ finish = function (state, req, answer)
+ if state == kres.FAIL then
+ counter.failed = counter.failed + 1
+ end
+ return state
+ end
+ }
+
+There is currently an additional "feature" in comparison to C layer functions:
+some functions do not get called at all if ``state == kres.FAIL``;
+see docs for details: :c:type:`kr_layer_api`.
+
+Since the modules are like any other Lua modules, you can interact with them through the CLI and and any interface.
+
+.. tip:: Module discovery: ``kres_modules.`` is prepended to the module name and lua search path is used on that.
+
+
+Writing a module in C
+=====================
+
+As almost all the functions are optional, the minimal module looks like this:
+
+.. code-block:: c
+
+ #include "lib/module.h"
+ /* Convenience macro to declare module ABI. */
+ KR_MODULE_EXPORT(mymodule)
+
+.. TODO it's probably not a good idea to start C module tutorial by pthread_create()
+
+Let's define an observer thread for the module as well. It's going to be stub for the sake of brevity,
+but you can for example create a condition, and notify the thread from query processing by declaring
+module layer (see the :ref:`Writing layers <lib-layers>`).
+
+.. code-block:: c
+
+ static void* observe(void *arg)
+ {
+ /* ... do some observing ... */
+ }
+
+ int mymodule_init(struct kr_module *module)
+ {
+ /* Create a thread and start it in the background. */
+ pthread_t thr_id;
+ int ret = pthread_create(&thr_id, NULL, &observe, NULL);
+ if (ret != 0) {
+ return kr_error(errno);
+ }
+
+ /* Keep it in the thread */
+ module->data = thr_id;
+ return kr_ok();
+ }
+
+ int mymodule_deinit(struct kr_module *module)
+ {
+ /* ... signalize cancellation ... */
+ void *res = NULL;
+ pthread_t thr_id = (pthread_t) module->data;
+ int ret = pthread_join(thr_id, res);
+ if (ret != 0) {
+ return kr_error(errno);
+ }
+
+ return kr_ok();
+ }
+
+This example shows how a module can run in the background, this enables you to, for example, observe
+and publish data about query resolution.
+
+Configuring modules
+===================
+
+There is a callback ``X_config()`` that you can implement, see hints module.
+
+.. _mod-properties:
+
+Exposing C module properties
+============================
+
+A module can offer NULL-terminated list of *properties*, each property is essentially a callable with free-form JSON input/output.
+JSON was chosen as an interchangeable format that doesn't require any schema beforehand, so you can do two things - query the module properties
+from external applications or between modules (e.g. `statistics` module can query `cache` module for memory usage).
+JSON was chosen not because it's the most efficient protocol, but because it's easy to read and write and interface to outside world.
+
+.. note:: The ``void *env`` is a generic module interface. Since we're implementing daemon modules, the pointer can be cast to ``struct engine*``.
+ This is guaranteed by the implemented API version (see `Writing a module in C`_).
+
+Here's an example how a module can expose its property:
+
+.. code-block:: c
+
+ char* get_size(void *env, struct kr_module *m,
+ const char *args)
+ {
+ /* Get cache from engine. */
+ struct engine *engine = env;
+ struct kr_cache *cache = &engine->resolver.cache;
+ /* Read item count */
+ int count = (cache->api)->count(cache->db);
+ char *result = NULL;
+ asprintf(&result, "{ \"result\": %d }", count);
+
+ return result;
+ }
+
+ struct kr_prop *cache_props(void)
+ {
+ static struct kr_prop prop_list[] = {
+ /* Callback, Name, Description */
+ {&get_size, "get_size", "Return number of records."},
+ {NULL, NULL, NULL}
+ };
+ return prop_list;
+ }
+
+ KR_MODULE_EXPORT(cache)
+
+Once you load the module, you can call the module property from the interactive console.
+*Note:* the JSON output will be transparently converted to Lua tables.
+
+.. code-block:: bash
+
+ $ kresd
+ ...
+ [system] started in interactive mode, type 'help()'
+ > modules.load('cached')
+ > cached.get_size()
+ [size] => 53
+
+.. No idea what this talks about, but kept for now:
+.. *Note:* this relies on function pointers, so the same ``static inline`` trick as for the ``Layer()`` is required for C.
+
+Special properties
+------------------
+
+If the module declares properties ``get`` or ``set``, they can be used in the Lua interpreter as
+regular tables.
+
diff --git a/modules/bogus_log/.packaging/test.config b/modules/bogus_log/.packaging/test.config
new file mode 100644
index 0000000..bf1c821
--- /dev/null
+++ b/modules/bogus_log/.packaging/test.config
@@ -0,0 +1,4 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+modules.load('bogus_log')
+assert(bogus_log)
+quit()
diff --git a/modules/bogus_log/README.rst b/modules/bogus_log/README.rst
new file mode 100644
index 0000000..d60c278
--- /dev/null
+++ b/modules/bogus_log/README.rst
@@ -0,0 +1,45 @@
+.. SPDX-License-Identifier: GPL-3.0-or-later
+
+.. _mod-bogus_log:
+
+DNSSEC validation failure logging
+=================================
+
+This module logs a message for each DNSSEC validation failure (on ``notice`` :func:`level <log_level>`).
+It is meant to provide hint to operators which queries should be
+investigated using diagnostic tools like DNSViz_.
+
+Add following line to your configuration file to enable it:
+
+.. code-block:: lua
+
+ modules.load('bogus_log')
+
+Example of error message logged by this module:
+
+.. code-block:: none
+
+ [dnssec] validation failure: dnssec-failed.org. DNSKEY
+
+.. _DNSViz: http://dnsviz.net/
+
+List of most frequent queries which fail as DNSSEC bogus can be obtained at run-time:
+
+.. code-block:: lua
+
+ > bogus_log.frequent()
+ {
+ {
+ ['count'] = 1,
+ ['name'] = 'dnssec-failed.org.',
+ ['type'] = 'DNSKEY',
+ },
+ {
+ ['count'] = 13,
+ ['name'] = 'rhybar.cz.',
+ ['type'] = 'DNSKEY',
+ },
+ }
+
+Please note that in future this module might be replaced
+with some other way to log this information.
diff --git a/modules/bogus_log/bogus_log.c b/modules/bogus_log/bogus_log.c
new file mode 100644
index 0000000..7b36187
--- /dev/null
+++ b/modules/bogus_log/bogus_log.c
@@ -0,0 +1,135 @@
+/* Copyright (C) Knot Resolver contributors
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ * This module logs (query name, type) pairs which failed DNSSEC validation. */
+
+#include <libknot/packet/pkt.h>
+#include <libknot/dname.h>
+#include <ccan/json/json.h>
+#include <contrib/cleanup.h>
+
+#include "daemon/engine.h"
+#include "lib/layer.h"
+#include "lib/generic/lru.h"
+
+#ifdef LRU_REP_SIZE
+ #define FREQUENT_COUNT LRU_REP_SIZE /* Size of frequent tables */
+#else
+ #define FREQUENT_COUNT 5000 /* Size of frequent tables */
+#endif
+
+/** @internal LRU hash of most frequent names. */
+typedef lru_t(unsigned) namehash_t;
+
+/** @internal Stats data structure. */
+struct stat_data {
+ namehash_t *frequent;
+};
+
+static int consume(kr_layer_t *ctx, knot_pkt_t *pkt)
+{
+ if (!(ctx->state & KR_STATE_FAIL)
+ || !ctx->req
+ || !ctx->req->current_query
+ || !ctx->req->current_query->flags.DNSSEC_BOGUS
+ || knot_wire_get_qdcount(pkt->wire) != 1)
+ return ctx->state;
+
+ auto_free char *qname_text = kr_dname_text(knot_pkt_qname(pkt));
+ auto_free char *qtype_text = kr_rrtype_text(knot_pkt_qtype(pkt));
+
+ kr_log_notice(DNSSEC, "validation failure: %s %s\n", qname_text, qtype_text);
+
+ /* log of most frequent bogus queries */
+ uint16_t type = knot_pkt_qtype(pkt);
+ char key[sizeof(type) + KNOT_DNAME_MAXLEN];
+ memcpy(key, &type, sizeof(type));
+ int key_len = knot_dname_to_wire((uint8_t *)key + sizeof(type), knot_pkt_qname(pkt), KNOT_DNAME_MAXLEN);
+ if (key_len >= 0) {
+ struct kr_module *module = ctx->api->data;
+ struct stat_data *data = module->data;
+ unsigned *count = lru_get_new(data->frequent, key, key_len+sizeof(type), NULL);
+ if (count)
+ *count += 1;
+ }
+
+ return ctx->state;
+}
+
+/** @internal Helper for dump_list: add a single namehash_t item to JSON. */
+static enum lru_apply_do dump_value(const char *key, uint len, unsigned *val, void *baton)
+{
+ uint16_t key_type = 0;
+ /* Extract query name, type and counter */
+ memcpy(&key_type, key, sizeof(key_type));
+ KR_DNAME_GET_STR(key_name, (uint8_t *)key + sizeof(key_type));
+ KR_RRTYPE_GET_STR(type_str, key_type);
+
+ /* Convert to JSON object */
+ JsonNode *json_val = json_mkobject();
+ json_append_member(json_val, "count", json_mknumber(*val));
+ json_append_member(json_val, "name", json_mkstring(key_name));
+ json_append_member(json_val, "type", json_mkstring(type_str));
+ json_append_element((JsonNode *)baton, json_val);
+ return LRU_APPLY_DO_NOTHING; // keep the item
+}
+
+/**
+ * List frequent names.
+ *
+ * Output: [{ count: <counter>, name: <qname>, type: <qtype>}, ... ]
+ */
+static char* dump_list(void *env, struct kr_module *module, const char *args, namehash_t *table)
+{
+ if (!table) {
+ return NULL;
+ }
+ JsonNode *root = json_mkarray();
+ lru_apply(table, dump_value, root);
+ char *ret = json_encode(root);
+ json_delete(root);
+ return ret;
+}
+
+static char* dump_frequent(void *env, struct kr_module *module, const char *args)
+{
+ struct stat_data *data = module->data;
+ return dump_list(env, module, args, data->frequent);
+}
+
+KR_EXPORT
+int bogus_log_init(struct kr_module *module)
+{
+ static kr_layer_api_t layer = {
+ .consume = &consume,
+ };
+ layer.data = module;
+ module->layer = &layer;
+
+ static const struct kr_prop props[] = {
+ { &dump_frequent, "frequent", "List most frequent queries.", },
+ { NULL, NULL, NULL }
+ };
+ module->props = props;
+
+ struct stat_data *data = calloc(1, sizeof(*data));
+ if (!data) {
+ return kr_error(ENOMEM);
+ }
+ module->data = data;
+ lru_create(&data->frequent, FREQUENT_COUNT, NULL, NULL);
+ return kr_ok();
+}
+
+KR_EXPORT
+int bogus_log_deinit(struct kr_module *module)
+{
+ struct stat_data *data = module->data;
+ if (data) {
+ lru_free(data->frequent);
+ free(data);
+ }
+ return kr_ok();
+}
+
+KR_MODULE_EXPORT(bogus_log)
diff --git a/modules/bogus_log/meson.build b/modules/bogus_log/meson.build
new file mode 100644
index 0000000..2dcf87f
--- /dev/null
+++ b/modules/bogus_log/meson.build
@@ -0,0 +1,21 @@
+# C module: bogus_log
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+bogus_log_src = files([
+ 'bogus_log.c',
+])
+c_src_lint += bogus_log_src
+
+bogus_log_mod = shared_module(
+ 'bogus_log',
+ bogus_log_src,
+ dependencies: libknot,
+ include_directories: mod_inc_dir,
+ name_prefix: '',
+ install: true,
+ install_dir: modules_dir,
+)
+
+integr_tests += [
+ ['bogus_log', meson.current_source_dir() / 'test.integr'],
+]
diff --git a/modules/bogus_log/test.integr/deckard.yaml b/modules/bogus_log/test.integr/deckard.yaml
new file mode 100644
index 0000000..ecd6cc5
--- /dev/null
+++ b/modules/bogus_log/test.integr/deckard.yaml
@@ -0,0 +1,13 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+programs:
+- name: kresd
+ binary: kresd
+ additional:
+ - --noninteractive
+ templates:
+ - modules/bogus_log/test.integr/kresd_config.j2
+ - tests/integration/hints_zone.j2
+ configs:
+ - config
+ - hints
+noclean: True
diff --git a/modules/bogus_log/test.integr/kresd_config.j2 b/modules/bogus_log/test.integr/kresd_config.j2
new file mode 100644
index 0000000..0471a27
--- /dev/null
+++ b/modules/bogus_log/test.integr/kresd_config.j2
@@ -0,0 +1,90 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+local ffi = require('ffi')
+
+{% for TAF in TRUST_ANCHOR_FILES %}
+trust_anchors.add_file('{{TAF}}')
+{% endfor %}
+
+{% raw %}
+modules.load('bogus_log')
+
+function check_stats(got)
+ log_info(ffi.C.LOG_GRP_TESTS, 'checking if bogus_log.frequent values match expected values:')
+ local expected = {
+ [1] = {
+ ['type'] = 'DNSKEY',
+ ['count'] = 2,
+ ['name'] = '.',
+ }
+ }
+ print(table_print(expected))
+
+ if table_print(expected) == table_print(got) then
+ log_info(ffi.C.LOG_GRP_TESTS, 'no problem found')
+ return policy.DENY_MSG('Ok')
+ else
+ log_info(ffi.C.LOG_GRP_TESTS, 'mismatch!')
+ return policy.DENY_MSG('bogus_log.frequent mismatch, see logs')
+ end
+end
+
+function reply_result(state, req)
+ local got = bogus_log.frequent()
+ print('current bogus_log.frequent() values:')
+ print(table_print(got))
+ local result = check_stats(got)
+ return result(state, req)
+end
+policy.add(policy.pattern(reply_result, 'bogus_log.test.'))
+
+-- Disable RFC5011 TA update
+if ta_update then
+ modules.unload('ta_update')
+end
+
+-- Disable RFC8145 signaling, scenario doesn't provide expected answers
+if ta_signal_query then
+ modules.unload('ta_signal_query')
+end
+
+-- Disable RFC8109 priming, scenario doesn't provide expected answers
+if priming then
+ modules.unload('priming')
+end
+
+-- Disable this module because it make one priming query
+if detect_time_skew then
+ modules.unload('detect_time_skew')
+end
+
+_hint_root_file('hints')
+cache.size = 2*MB
+log_level('debug')
+{% endraw %}
+
+net = { '{{SELF_ADDR}}' }
+
+
+{% if QMIN == "false" %}
+option('NO_MINIMIZE', true)
+{% else %}
+option('NO_MINIMIZE', false)
+{% endif %}
+
+
+-- Self-checks on globals
+assert(help() ~= nil)
+assert(worker.id ~= nil)
+-- Self-checks on facilities
+assert(cache.count() == 0)
+assert(cache.stats() ~= nil)
+assert(cache.backends() ~= nil)
+assert(worker.stats() ~= nil)
+assert(net.interfaces() ~= nil)
+-- Self-checks on loaded stuff
+assert(net.list()[1].transport.ip == '{{SELF_ADDR}}')
+assert(#modules.list() > 0)
+-- Self-check timers
+ev = event.recurrent(1 * sec, function (ev) return 1 end)
+event.cancel(ev)
+ev = event.after(0, function (ev) return 1 end)
diff --git a/modules/bogus_log/test.integr/val_minimal_expiredsignature.rpl b/modules/bogus_log/test.integr/val_minimal_expiredsignature.rpl
new file mode 100644
index 0000000..46c228c
--- /dev/null
+++ b/modules/bogus_log/test.integr/val_minimal_expiredsignature.rpl
@@ -0,0 +1,125 @@
+; SPDX-License-Identifier: GPL-3.0-or-later
+ trust-anchor: ". IN DS 49060 8 2 E7B1EB56D7D5791B3D45630FEAA9C823DB84B385ACEEAC5F44DD08885C36700F"
+ val-override-date: "20170410000000"
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+ query-minimization: off
+CONFIG_END
+
+SCENARIO_BEGIN Date after expiration of signatures.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ ADDRESS 2001:7fd::1
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. 518400 IN NS k.root-servers.net.
+. 518400 IN RRSIG NS 8 0 518400 20170409093827 20170310093827 20661 . uBuJpbRh1NYVciSKK0r3SA6NFnqE4s/+CqLfTXu26/HrY5c1aOhQHXZM cCDDjfPGFa7Eh4mqF0i9I+i+bFbYQitI1Heexye599VE19REbVsK4qaU xkArvt9k6HVqd/7BXXUyzLN1N0CScdyuT5tiEI9154SDNVpnC+z8i2u0 9hW8JEk4qqVWX/I1MYQB/UOcFSeDhD1Qku/26opqDuLl/1eaShxhMQ/c rjzOb5ZYzD0x+TUJZMYSOMwAraaFuYTT84oe6QYY+EGctAk1b50nA/5E C3Tm/xGuo9ioVtYhTwoo1XDUVeHmghdILjQZvR4pOSZoRGGP9ovb08Qg OmPXuQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+. IN DNSKEY
+SECTION ANSWER
+. IN DNSKEY 256 3 8 AwEAAe1oA46eOLNris1CtS0qM5TdMESK6i4hpalqa6JDv57eOUkaOeje ZW1tIFUokmaK7kuKEFEosddA89CYM8rt2RbC+sfKalbHAWOus0tXZyAL efb2sW95QRzyG6LNul0jQFn9eYWBUHrVe5Wqd0zrFCbTQLUhELSfrlkI UBpO/xKaGinRHX2JjyOnle4aPZY3bEVa/+KyY2ZU6UC4SBo3aHXanP26 ok91rOTmpTWp64ybsMdCXOU8deyuQFQf6q8DhIDmJrkymhX1MXWQQlE0 fAYIYf8/t9OCwucg8oEg4FPU8Gb4Zm/l6PgO4HFkFjBT6iGFCQt3qXe2 Qe3alUWoATc=
+. IN DNSKEY 257 3 8 AwEAAb8sZgVVa02muJ+/+SVhJAvz2EWKGEGquhPbQXuF6ALBYoF4KWTO bZVF8sIVTGoaX5+UWkwwHthg7RwS1DALT/AJymYeHhUwA04gLsfCZ/cv BjmRy5RozeSJ1uxAhoCYHCT2hQBZ0cH0n8roXFXI2Y+6708pO1IBkTPT 9MpAGfezTtGYOortbSn+vqT/Zu8jOpNwkleXON4rlZRBZPd4JUMGL9Y5 N/j6+ClYeM+eFQTKXrLi1oC+0yK1sG5OlqrBDhAhBnz+IhfZz4TOkqJ9 Li2BVMatHBeB9GQHtu0FZuC3J0EQgiZxvq1RgkefFJAiB+5uVRN8U7up 5mLDxSgmT0M=
+. 2592000 IN RRSIG DNSKEY 8 0 3600000 20170409093827 20170310093827 49060 . G7s3QiWNgOsl+LoG6OKjdBHPcFyhmCS17GFnaKjfJNdPQaFL5nM/vrXo eUIIdJXAvjj62TY7wTyFlnx3yjK93RVGKEEySpGC/1gkn5AdjVoQszog IxYjKzubizULSaX7SQ3/Ar+uHLxakdS1qgNdFu6hHCl857LJPtmC8SJt iFUmm5HFyARokMrfA88VrFRKEqojcCWajeZMfRtgBipFJZoYgPUCaFlz 8OupNdNUWCbGhnDWrXCWMzeKVXTQVlJf75PXXgtkuBUmr5RSWu7AYr+c wTJ4E4610goRqYxnZ33efKE/MuhKeY66xelPh0sirPrBMR5JAlyjV3k1 qDzhcQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+k.root-servers.net. IN AAAA
+SECTION ANSWER
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+k.root-servers.net. 2592000 IN RRSIG AAAA 8 3 3600000 20170409093827 20170310093827 20661 . qjVXwuxzmoRhdrXyQvKfrrzFxGiYuTTJHxwZPasJ1nVmN48dPyU6wA55 JeqoJv1Jm+XvIL1q0WtX6Zh6KLt6vVjHuMkhmFuIZYkFi/dmsEwFY8C0 ebyXyztQT5+6FOSVTAKacYc40LfBo8FqEn8RYlCu1mkAd8ANvvLrdLWW W03LVOY7JlCzyrKlAlmPmuV8z+e9PxNkUh6KfTEvAReoAAX7wYZkdefg 2d64c7rNWXvYm6LxBX6qeQ39d5WyKc8v+G01DJuDzs2Tx368QoK86vm/ qo9ERdT7koRt+gBZNYv8V4fh2SjaFsy2TJq/tiYcSia9snGDTFj6LWVM 6sBCYQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+k.root-servers.net. IN A
+SECTION ANSWER
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 2592000 IN RRSIG A 8 3 3600000 20170409093827 20170310093827 20661 . feIXXjskcsyH+ALZu67GVDaPWXjUGTWsTlDwzgJcLBzSuRVY/GVD5Z1Q B4/oUW99rLKB5bNS1MuasZ+nZFV67sBwJk1+SqNB2bAe7G5Tv1sR2Qgi qDAoB37YDVk5JGHfuxByLYbAVG9PrPXT60BN17OYrD/TFPzprye65gk3 7l9kPpAlblcsqdvh5piKrWc7VBcyMhlp56qdASNAl+Lrb+i0DZYyJXh+ b8LV5g5zp9FaVGKe0Gi4+yDXVjcM6VEtuNRAu2+flLoc3ho6qQF1Po4Y wueL72I+yFoUxkIOJvK47eWb+YUBIBK/L8/ORjYoLBRsrbc79wb0I3Zj Xy6O4Q==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype
+ADJUST copy_id copy_query
+REPLY QR AA REFUSED
+SECTION QUESTION
+. IN RRSIG
+SECTION ANSWER
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+. IN NS
+ENTRY_END
+
+
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA DO SERVFAIL
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+STEP 11 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+. IN NS
+ENTRY_END
+
+STEP 12 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA DO SERVFAIL
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+STEP 20 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+bogus_log.test. IN TXT
+ENTRY_END
+
+STEP 21 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR AA RD RA DO NXDOMAIN
+SECTION QUESTION
+bogus_log.test. IN TXT
+SECTION AUTHORITY
+bogus_log.test. 10800 IN SOA bogus_log.test. nobody.invalid. 1 3600 1200 604800 10800
+SECTION ADDITIONAL
+explanation.invalid. 10800 IN TXT "Ok"
+ENTRY_END
+
+SCENARIO_END
diff --git a/modules/cookies/README.rst b/modules/cookies/README.rst
new file mode 100644
index 0000000..b8aba8a
--- /dev/null
+++ b/modules/cookies/README.rst
@@ -0,0 +1,56 @@
+.. SPDX-License-Identifier: GPL-3.0-or-later
+
+.. _mod-cookies:
+
+DNS Cookies
+===========
+
+The module performs most of the :rfc:`7873` DNS cookies functionality. Its main purpose is to check the cookies of inbound queries and responses. It is also used to alter the behaviour of the cookie functionality.
+
+Example Configuration
+---------------------
+
+.. code-block:: lua
+
+ -- Load the module before the 'iterate' layer.
+ modules = {
+ 'cookies < iterate'
+ }
+
+ -- Configure the client part of the resolver. Set 8 bytes of the client
+ -- secret and choose the hashing algorithm to be used.
+ -- Use a string composed of hexadecimal digits to set the secret.
+ cookies.config { client_secret = '0123456789ABCDEF',
+ client_cookie_alg = 'FNV-64' }
+
+ -- Configure the server part of the resolver.
+ cookies.config { server_secret = 'FEDCBA9876543210',
+ server_cookie_alg = 'FNV-64' }
+
+ -- Enable client cookie functionality. (Add cookies into outbound
+ -- queries.)
+ cookies.config { client_enabled = true }
+
+ -- Enable server cookie functionality. (Handle cookies in inbound
+ -- requests.)
+ cookies.config { server_enabled = true }
+
+.. tip:: If you want to change several parameters regarding the client or server configuration then do it within a single ``cookies.config()`` invocation.
+
+.. warning:: The module must be loaded before any other module that has direct influence on query processing and response generation. The module must be able to intercept an incoming query before the processing of the actual query starts. It must also be able to check the cookies of inbound responses and eventually discard them before they are handled by other functional units.
+
+Properties
+----------
+
+.. function:: cookies.config(configuration)
+
+ :param table configuration: part of cookie configuration to be changed, may be called without parameter
+ :return: JSON dictionary containing current configuration
+
+ The function may be called without any parameter. In such case it only returns current configuration. The returned JSON also contains available algorithm choices.
+
+Dependencies
+------------
+
+* `Nettle <https://www.lysator.liu.se/~nisse/nettle/>`_ required for HMAC-SHA256
+
diff --git a/modules/cookies/cookiectl.c b/modules/cookies/cookiectl.c
new file mode 100644
index 0000000..f1ab80a
--- /dev/null
+++ b/modules/cookies/cookiectl.c
@@ -0,0 +1,689 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#include <ccan/json/json.h>
+#include <ctype.h>
+#include <libknot/rrtype/opt-cookie.h>
+#include <libknot/db/db_lmdb.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "lib/cookies/alg_containers.h"
+#include "modules/cookies/cookiectl.h"
+
+#define NAME_CLIENT_ENABLED "client_enabled"
+#define NAME_CLIENT_SECRET "client_secret"
+#define NAME_CLIENT_COOKIE_ALG "client_cookie_alg"
+#define NAME_AVAILABLE_CLIENT_COOKIE_ALGS "available_client_cookie_algs"
+
+#define NAME_SERVER_ENABLED "server_enabled"
+#define NAME_SERVER_SECRET "server_secret"
+#define NAME_SERVER_COOKIE_ALG "server_cookie_alg"
+#define NAME_AVAILABLE_SERVER_COOKIE_ALGS "available_server_cookie_algs"
+
+/**
+ * @brief Initialises cookie control context.
+ * @param ctx cookie control context
+ */
+static void kr_cookie_ctx_init(struct kr_cookie_ctx *ctx)
+{
+ if (!ctx) {
+ return;
+ }
+
+ memset(ctx, 0, sizeof(*ctx));
+
+ ctx->clnt.current.alg_id = ctx->clnt.recent.alg_id = -1;
+ ctx->srvr.current.alg_id = ctx->srvr.recent.alg_id = -1;
+}
+
+/**
+ * @brief Check whether node holds proper 'enabled' value.
+ * @param node JSON node holding the value
+ * @return true if value OK
+ */
+static bool enabled_ok(const JsonNode *node)
+{
+ if (kr_fails_assert(node))
+ return false;
+
+ return node->tag == JSON_BOOL;
+}
+
+/**
+ * @brief Check whether node holds proper 'secret' value.
+ * @param node JSON node holding the value
+ * @return true if value OK
+ */
+static bool secret_ok(const JsonNode *node)
+{
+ if (kr_fails_assert(node))
+ return false;
+
+ if (node->tag != JSON_STRING) {
+ return false;
+ }
+
+ const char *hexstr = node->string_;
+
+ size_t len = strlen(hexstr);
+ if ((len % 2) != 0) {
+ return false;
+ }
+ /* A check for minimal required length could also be performed. */
+
+ for (size_t i = 0; i < len; ++i) {
+ if (!isxdigit(tolower(hexstr[i]))) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+/**
+ * @brief Find hash function with given name.
+ * @param node JSON node holding the value
+ * @param table lookup table with algorithm names
+ * @return pointer to table entry or NULL on error if does not exist
+ */
+static const knot_lookup_t *hash_func_lookup(const JsonNode *node,
+ const knot_lookup_t table[])
+{
+ if (!node || node->tag != JSON_STRING) {
+ return NULL;
+ }
+
+ return knot_lookup_by_name(table, node->string_);
+}
+
+/**
+ * @brief Creates a cookie secret structure.
+ * @param size size of the actual secret
+ * @param zero set to true if value should be cleared
+ * @return pointer to new structure, NULL on failure or if @size is zero
+ */
+static struct kr_cookie_secret *new_cookie_secret(size_t size, bool zero)
+{
+ if (size == 0) {
+ return NULL;
+ }
+
+ struct kr_cookie_secret *sq = malloc(sizeof(*sq) + size);
+ if (!sq) {
+ return NULL;
+ }
+
+ sq->size = size;
+ if (zero) {
+ memset(sq->data, 0, size);
+ }
+ return sq;
+}
+
+/**
+ * @brief Clone a cookie secret.
+ * @param sec secret to be cloned
+ * @return pointer to new structure, NULL on failure or if @size is zero
+ */
+static struct kr_cookie_secret *clone_cookie_secret(const struct kr_cookie_secret *sec)
+{
+ if (!sec || sec->size == 0) {
+ return NULL;
+ }
+
+ struct kr_cookie_secret *sq = malloc(sizeof(*sq) + sec->size);
+ if (!sq) {
+ return NULL;
+ }
+
+ sq->size = sec->size;
+ memcpy(sq->data, sec->data, sq->size);
+ return sq;
+}
+
+static int hexchar2val(int d)
+{
+ if (('0' <= d) && (d <= '9')) {
+ return d - '0';
+ } else if (('a' <= d) && (d <= 'f')) {
+ return d - 'a' + 0x0a;
+ } else {
+ return -1;
+ }
+}
+
+static int hexval2char(int i)
+{
+ if ((0 <= i) && (i <= 9)) {
+ return i + '0';
+ } else if ((0x0a <= i) && (i <= 0x0f)) {
+ return i - 0x0a + 'A';
+ } else {
+ return -1;
+ }
+}
+
+/**
+ * @brief Converts string containing two-digit hexadecimal number into int.
+ * @param hexstr hexadecimal string
+ * @return -1 on error, value from 0 to 255 else.
+ */
+static int hexbyte2int(const char *hexstr)
+{
+ if (!hexstr) {
+ return -1;
+ }
+
+ int dhi = tolower(hexstr[0]);
+ if (!isxdigit(dhi)) {
+ /* Exit also on empty string. */
+ return -1;
+ }
+ int dlo = tolower(hexstr[1]);
+ if (!isxdigit(dlo)) {
+ return -1;
+ }
+
+ dhi = hexchar2val(dhi);
+ if (kr_fails_assert(dhi != -1))
+ return -1;
+ dlo = hexchar2val(dlo);
+ if (kr_fails_assert(dlo != -1))
+ return -1;
+
+ return (dhi << 4) | dlo;
+}
+
+/**
+ * @brief Writes two hexadecimal digits (two byes) into given memory location.
+ * @param tgt target location
+ * @param i number from 0 to 255
+ * @return 0 on success, -1 on failure
+ */
+static int int2hexbyte(char *tgt, int i)
+{
+ if (!tgt || i < 0x00 || i > 0xff) {
+ return -1;
+ }
+
+ int ilo = hexval2char(i & 0x0f);
+ if (kr_fails_assert(ilo != -1))
+ return -1;
+ int ihi = hexval2char((i >> 4) & 0x0f);
+ if (kr_fails_assert(ihi != -1))
+ return -1;
+
+ tgt[0] = ihi;
+ tgt[1] = ilo;
+
+ return 0;
+}
+
+/**
+ * @brief Reads a string containing hexadecimal values.
+ * @note String must consist of hexadecimal digits only and must have even
+ * non-zero length.
+ */
+static struct kr_cookie_secret *new_sq_from_hexstr(const char *hexstr)
+{
+ if (!hexstr) {
+ return NULL;
+ }
+
+ size_t len = strlen(hexstr);
+ if ((len % 2) != 0) {
+ return NULL;
+ }
+
+ struct kr_cookie_secret *sq = new_cookie_secret(len / 2, false);
+ if (!sq) {
+ return NULL;
+ }
+
+ uint8_t *data = sq->data;
+ for (size_t i = 0; i < len; i += 2) {
+ int num = hexbyte2int(hexstr + i);
+ if (num == -1) {
+ free(sq);
+ return NULL;
+ }
+ if (kr_fails_assert(0x00 <= num && num <= 0xff)) {
+ free(sq);
+ return NULL;
+ }
+ *data = num;
+ ++data;
+ }
+
+ return sq;
+}
+
+/**
+ * @brief Creates new secret.
+ * @param node JSON node holding the secret value
+ * @return pointer to newly allocated secret, NULL on error
+ */
+static struct kr_cookie_secret *create_secret(const JsonNode *node)
+{
+ if (!node) {
+ return NULL;
+ }
+
+ if (node->tag != JSON_STRING) {
+ return NULL;
+ }
+
+ return new_sq_from_hexstr(node->string_);
+}
+
+/**
+ * @brief Check whether configuration node contains valid values.
+ */
+static bool configuration_node_ok(const JsonNode *node)
+{
+ if (kr_fails_assert(node))
+ return false;
+
+ if (!node->key) {
+ /* All top most nodes must have names. */
+ return false;
+ }
+
+ if (strcmp(node->key, NAME_CLIENT_ENABLED) == 0) {
+ return enabled_ok(node);
+ } else if (strcmp(node->key, NAME_CLIENT_SECRET) == 0) {
+ return secret_ok(node);
+ } else if (strcmp(node->key, NAME_CLIENT_COOKIE_ALG) == 0) {
+ return hash_func_lookup(node, kr_cc_alg_names) != NULL;
+ } else if (strcmp(node->key, NAME_SERVER_ENABLED) == 0) {
+ return enabled_ok(node);
+ } else if (strcmp(node->key, NAME_SERVER_SECRET) == 0) {
+ return secret_ok(node);
+ } else if (strcmp(node->key, NAME_SERVER_COOKIE_ALG) == 0) {
+ return hash_func_lookup(node, kr_sc_alg_names) != NULL;
+ }
+
+ return false;
+}
+
+/**
+ * @brief Creates a new string from secret quantity.
+ * @param sq secret quantity
+ * @return newly allocated string or NULL on error
+ */
+static char *new_hexstr_from_sq(const struct kr_cookie_secret *sq)
+{
+ if (!sq) {
+ return NULL;
+ }
+
+ char *new_str = malloc((sq->size * 2) + 1);
+ if (!new_str) {
+ return NULL;
+ }
+
+ char *tgt = new_str;
+ for (size_t i = 0; i < sq->size; ++i) {
+ if (0 != int2hexbyte(tgt, sq->data[i])) {
+ free(new_str);
+ return NULL;
+ }
+ tgt += 2;
+ }
+
+ *tgt = '\0';
+ return new_str;
+}
+
+static bool read_secret(JsonNode *root, const char *node_name,
+ const struct kr_cookie_secret *secret)
+{
+ if (kr_fails_assert(root && node_name && secret))
+ return false;
+
+ char *secret_str = new_hexstr_from_sq(secret);
+ if (!secret_str) {
+ return false;
+ }
+
+ JsonNode *str_node = json_mkstring(secret_str);
+ if (!str_node) {
+ free(secret_str);
+ return false;
+ }
+
+ json_append_member(root, node_name, str_node);
+
+ free(secret_str);
+ return true;
+}
+
+static bool read_available_hashes(JsonNode *root, const char *root_name,
+ const knot_lookup_t table[])
+{
+ if (kr_fails_assert(root && root_name && table))
+ return false;
+
+ JsonNode *array = json_mkarray();
+ if (!array) {
+ return false;
+ }
+
+ const knot_lookup_t *aux_ptr = table;
+ while (aux_ptr && (aux_ptr->id >= 0) && aux_ptr->name) {
+ JsonNode *element = json_mkstring(aux_ptr->name);
+ if (!element) {
+ goto fail;
+ }
+ json_append_element(array, element);
+ ++aux_ptr;
+ }
+
+ json_append_member(root, root_name, array);
+
+ return true;
+
+fail:
+ if (array) {
+ json_delete(array);
+ }
+ return false;
+}
+
+/**
+ * @brief Check whether new settings are different from the old ones.
+ */
+static bool is_modified(const struct kr_cookie_comp *running,
+ struct kr_cookie_secret *secr,
+ const knot_lookup_t *alg_lookup)
+{
+ if (kr_fails_assert(running))
+ return false;
+
+ if (alg_lookup && alg_lookup->id >= 0) {
+ if (running->alg_id != alg_lookup->id) {
+ return true;
+ }
+ }
+
+ if (secr) {
+ if (kr_fails_assert(secr->size > 0))
+ return false;
+ if (running->secr->size != secr->size ||
+ 0 != memcmp(running->secr->data, secr->data,
+ running->secr->size)) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+/**
+ * @brief Returns newly allocated secret via pointer argument.
+ */
+static bool obtain_secret(JsonNode *root_node, struct kr_cookie_secret **secret,
+ const char *name)
+{
+ if (kr_fails_assert(secret && name))
+ return false;
+
+ const JsonNode *node;
+ if ((node = json_find_member(root_node, name)) != NULL) {
+ *secret = create_secret(node);
+ if (!*secret) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+/**
+ * @brief Updates the current configuration and moves current to recent.
+ */
+static void update_running(struct kr_cookie_settings *running,
+ struct kr_cookie_secret **secret,
+ const knot_lookup_t *alg_lookup)
+{
+ if (kr_fails_assert(running && secret) || kr_fails_assert(*secret || alg_lookup))
+ return;
+
+ running->recent.alg_id = -1;
+ free(running->recent.secr);
+ running->recent.secr = NULL;
+
+ running->recent.alg_id = running->current.alg_id;
+ if (alg_lookup) {
+ if (kr_fails_assert(alg_lookup->id >= 0))
+ return;
+ running->current.alg_id = alg_lookup->id;
+ }
+
+ if (*secret) {
+ running->recent.secr = running->current.secr;
+ running->current.secr = *secret;
+ *secret = NULL;
+ } else {
+ running->recent.secr = clone_cookie_secret(running->current.secr);
+ }
+}
+
+/**
+ * @brief Applies modification onto client/server running configuration.
+ * @note The @a secret is going to be consumed.
+ * @param secret pointer to new secret
+ * @param alg_lookup new algorithm
+ * @param enabled JSON node holding boolean value
+ */
+static void apply_changes(struct kr_cookie_settings *running,
+ struct kr_cookie_secret **secret,
+ const knot_lookup_t *alg_lookup,
+ const JsonNode *enabled)
+{
+ if (kr_fails_assert(running && secret))
+ return;
+
+ if (is_modified(&running->current, *secret, alg_lookup)) {
+ update_running(running, secret, alg_lookup);
+ }
+
+ if (enabled) {
+ kr_assert(enabled->tag == JSON_BOOL);
+ running->enabled = enabled->bool_;
+ }
+}
+
+/**
+ * @brief Applies configuration.
+ *
+ * @note The function must be called after the input values have been checked
+ * for validity. Only first found values are applied.
+ *
+ * @param ctx cookie configuration context
+ * @param root_node JSON root node
+ * @return true if changes were applied
+ */
+static bool config_apply_json(struct kr_cookie_ctx *ctx, JsonNode *root_node)
+{
+ if (kr_fails_assert(ctx && root_node))
+ return;
+
+ /*
+ * These must be allocated before actual change. Allocation failure
+ * should not leave configuration in inconsistent state.
+ */
+ struct kr_cookie_secret *new_clnt_secret = NULL;
+ struct kr_cookie_secret *new_srvr_secret = NULL;
+ if (!obtain_secret(root_node, &new_clnt_secret, NAME_CLIENT_SECRET)) {
+ return false;
+ }
+ if (!obtain_secret(root_node, &new_srvr_secret, NAME_SERVER_SECRET)) {
+ free(new_clnt_secret);
+ return false;
+ }
+
+ /* Algorithm pointers. */
+ const knot_lookup_t *clnt_lookup = hash_func_lookup(json_find_member(root_node, NAME_CLIENT_COOKIE_ALG), kr_cc_alg_names);
+ const knot_lookup_t *srvr_lookup = hash_func_lookup(json_find_member(root_node, NAME_SERVER_COOKIE_ALG), kr_sc_alg_names);
+
+ const JsonNode *clnt_enabled_node = json_find_member(root_node, NAME_CLIENT_ENABLED);
+ const JsonNode *srvr_enabled_node = json_find_member(root_node, NAME_SERVER_ENABLED);
+
+ apply_changes(&ctx->clnt, &new_clnt_secret, clnt_lookup, clnt_enabled_node);
+ apply_changes(&ctx->srvr, &new_srvr_secret, srvr_lookup, srvr_enabled_node);
+
+ /*
+ * Allocated secrets should be already consumed. There is no need to
+ * free them.
+ */
+
+ return true;
+}
+
+bool config_apply(struct kr_cookie_ctx *ctx, const char *args)
+{
+ if (!ctx) {
+ return false;
+ }
+
+ if (!args || !strlen(args)) {
+ return true;
+ }
+
+ if (!args || !strlen(args)) {
+ return true;
+ }
+
+ bool success = false;
+
+ /* Check whether all supplied data are valid. */
+ JsonNode *root_node = json_decode(args);
+ if (!root_node) {
+ return false;
+ }
+ JsonNode *node;
+ json_foreach (node, root_node) {
+ success = configuration_node_ok(node);
+ if (!success) {
+ break;
+ }
+ }
+
+ /* Apply configuration if values seem to be OK. */
+ if (success) {
+ success = config_apply_json(ctx, root_node);
+ }
+
+ json_delete(root_node);
+
+ return success;
+}
+
+char *config_read(struct kr_cookie_ctx *ctx)
+{
+ if (!ctx) {
+ return NULL;
+ }
+
+ const knot_lookup_t *lookup;
+ char *result;
+ JsonNode *root_node = json_mkobject();
+ if (!root_node) {
+ return NULL;
+ }
+
+ json_append_member(root_node, NAME_CLIENT_ENABLED,
+ json_mkbool(ctx->clnt.enabled));
+
+ read_secret(root_node, NAME_CLIENT_SECRET, ctx->clnt.current.secr);
+
+ lookup = knot_lookup_by_id(kr_cc_alg_names, ctx->clnt.current.alg_id);
+ if (lookup) {
+ json_append_member(root_node, NAME_CLIENT_COOKIE_ALG,
+ json_mkstring(lookup->name));
+ }
+
+ read_available_hashes(root_node, NAME_AVAILABLE_CLIENT_COOKIE_ALGS,
+ kr_cc_alg_names);
+
+ json_append_member(root_node, NAME_SERVER_ENABLED,
+ json_mkbool(ctx->srvr.enabled));
+
+ read_secret(root_node, NAME_SERVER_SECRET, ctx->srvr.current.secr);
+
+ lookup = knot_lookup_by_id(kr_sc_alg_names, ctx->srvr.current.alg_id);
+ if (lookup) {
+ json_append_member(root_node, NAME_SERVER_COOKIE_ALG,
+ json_mkstring(lookup->name));
+ }
+
+ read_available_hashes(root_node, NAME_AVAILABLE_SERVER_COOKIE_ALGS,
+ kr_sc_alg_names);
+
+ result = json_encode(root_node);
+ json_delete(root_node);
+ return result;
+}
+
+int config_init(struct kr_cookie_ctx *ctx)
+{
+ if (!ctx) {
+ return kr_error(EINVAL);
+ }
+
+ kr_cookie_ctx_init(ctx);
+
+ struct kr_cookie_secret *cs = new_cookie_secret(KNOT_OPT_COOKIE_CLNT,
+ true);
+ struct kr_cookie_secret *ss = new_cookie_secret(KNOT_OPT_COOKIE_CLNT,
+ true);
+ if (!cs || !ss) {
+ free(cs);
+ free(ss);
+ return kr_error(ENOMEM);
+ }
+
+ const knot_lookup_t *clookup = knot_lookup_by_name(kr_cc_alg_names,
+ "FNV-64");
+ const knot_lookup_t *slookup = knot_lookup_by_name(kr_sc_alg_names,
+ "FNV-64");
+ if (!clookup || !slookup) {
+ free(cs);
+ free(ss);
+ return kr_error(ENOENT);
+ }
+
+ ctx->clnt.current.secr = cs;
+ ctx->clnt.current.alg_id = clookup->id;
+
+ ctx->srvr.current.secr = ss;
+ ctx->srvr.current.alg_id = slookup->id;
+
+ return kr_ok();
+}
+
+void config_deinit(struct kr_cookie_ctx *ctx)
+{
+ if (!ctx) {
+ return;
+ }
+
+ ctx->clnt.enabled = false;
+
+ free(ctx->clnt.recent.secr);
+ ctx->clnt.recent.secr = NULL;
+
+ free(ctx->clnt.current.secr);
+ ctx->clnt.current.secr = NULL;
+
+ ctx->srvr.enabled = false;
+
+ free(ctx->srvr.recent.secr);
+ ctx->srvr.recent.secr = NULL;
+
+ free(ctx->srvr.current.secr);
+ ctx->srvr.current.secr = NULL;
+}
diff --git a/modules/cookies/cookiectl.h b/modules/cookies/cookiectl.h
new file mode 100644
index 0000000..6740e16
--- /dev/null
+++ b/modules/cookies/cookiectl.h
@@ -0,0 +1,35 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#include "lib/cookies/control.h"
+
+/**
+ * @brief Sets cookie control context structure.
+ * @param ctx cookie control context
+ * @param args JSON string describing configuration changes
+ * @return true if changes successfully applied
+ */
+bool config_apply(struct kr_cookie_ctx *ctx, const char *args);
+
+/**
+ * @brief Reads cookie control context structure.
+ * @param ctx cookie control context
+ * @return JSON string or NULL on error
+ */
+char *config_read(struct kr_cookie_ctx *ctx);
+
+/**
+ * @brief Initialises cookie control context to default values.
+ * @param ctx cookie control context
+ * @return kr_ok() or error code
+ */
+int config_init(struct kr_cookie_ctx *ctx);
+
+/**
+ * @brief Clears the cookie control context.
+ * @param ctx cookie control context
+ */
+void config_deinit(struct kr_cookie_ctx *ctx);
diff --git a/modules/cookies/cookiemonster.c b/modules/cookies/cookiemonster.c
new file mode 100644
index 0000000..595317b
--- /dev/null
+++ b/modules/cookies/cookiemonster.c
@@ -0,0 +1,464 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#include <ccan/json/json.h>
+#include <libknot/db/db_lmdb.h>
+#include <libknot/error.h>
+#include <libknot/mm_ctx.h>
+#include <libknot/rrtype/opt-cookie.h>
+#include <libknot/version.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "lib/cookies/alg_containers.h"
+#include "lib/cookies/control.h"
+#include "lib/cookies/helper.h"
+#include "lib/cookies/lru_cache.h"
+#include "lib/cookies/nonce.h"
+#include "lib/resolve.h"
+#include "lib/rplan.h"
+#include "modules/cookies/cookiemonster.h"
+
+#define VERBOSE_MSG(qry, ...) kr_log_q(qry, COOKIES, __VA_ARGS__)
+
+/**
+ * Obtain address from query/response context if if can be obtained.
+ * @param req resolution context
+ * @return pointer to where the server socket address, NULL if not provided within context
+ */
+static const struct sockaddr *passed_server_sockaddr(const struct kr_request *req)
+{
+ if (!req || !req->upstream.addr) {
+ return NULL;
+ }
+
+ if (req->upstream.addr->sa_family == AF_INET ||
+ req->upstream.addr->sa_family == AF_INET6) {
+ return req->upstream.addr;
+ }
+
+ return NULL;
+}
+
+/**
+ * Obtain pointer to server socket address that matches obtained cookie.
+ * @param srvr_sa server socket address
+ * @param cc client cookie from the response
+ * @param cc_len client cookie size
+ * @param clnt_sett client cookie settings structure
+ * @retval 1 if cookie matches current settings
+ * @retval 0 if cookie matches recent settings
+ * @return -1 if cookie does not match
+ * @return -2 on any error
+ */
+static int srvr_sockaddr_cc_check(const struct sockaddr *srvr_sa,
+ const uint8_t *cc, uint16_t cc_len,
+ const struct kr_cookie_settings *clnt_sett)
+{
+ if (kr_fails_assert(cc && cc_len > 0 && clnt_sett))
+ return -2;
+
+ if (!srvr_sa) {
+ return -2;
+ }
+
+ if (kr_fails_assert(clnt_sett->current.secr))
+ return -2;
+
+ /* The address must correspond with the client cookie. */
+ struct knot_cc_input input = {
+ .clnt_sockaddr = NULL, /* Not supported yet. */
+ .srvr_sockaddr = srvr_sa,
+ .secret_data = clnt_sett->current.secr->data,
+ .secret_len = clnt_sett->current.secr->size
+ };
+
+ const struct knot_cc_alg *cc_alg = kr_cc_alg_get(clnt_sett->current.alg_id);
+ if (!cc_alg) {
+ return -2;
+ }
+ int comp_ret = -1; /* Cookie does not match. */
+ int ret = knot_cc_check(cc, cc_len, &input, cc_alg);
+ if (ret == KNOT_EOK) {
+ comp_ret = 1;
+ } else {
+ cc_alg = kr_cc_alg_get(clnt_sett->recent.alg_id);
+ if (clnt_sett->recent.secr && cc_alg) {
+ input.secret_data = clnt_sett->recent.secr->data;
+ input.secret_len = clnt_sett->recent.secr->size;
+ ret = knot_cc_check(cc, cc_len, &input, cc_alg);
+ if (ret == KNOT_EOK) {
+ comp_ret = 0;
+ }
+ }
+ }
+
+ return comp_ret;
+}
+
+/**
+ * Obtain cookie from cache.
+ * @note Cookies with invalid length are ignored.
+ * @param cache cache context
+ * @param sa key value
+ * @param cookie_opt entire EDNS cookie option (including header)
+ * @return true if a cookie exists in cache
+ */
+static const uint8_t *get_cookie_opt(kr_cookie_lru_t *cache,
+ const struct sockaddr *sa)
+{
+ if (kr_fails_assert(cache && sa))
+ return NULL;
+
+ const uint8_t *cached_cookie_opt = kr_cookie_lru_get(cache, sa);
+ if (!cached_cookie_opt) {
+ return NULL;
+ }
+
+ size_t cookie_opt_size = KNOT_EDNS_OPTION_HDRLEN +
+ knot_edns_opt_get_length(cached_cookie_opt);
+ if (cookie_opt_size > KR_COOKIE_OPT_MAX_LEN) {
+ return NULL;
+ }
+
+ return cached_cookie_opt;
+}
+
+/**
+ * Check whether the supplied cookie is cached under the given key.
+ * @param cache cache context
+ * @param sa key value
+ * @param cookie_opt cookie option to search for
+ */
+static bool is_cookie_cached(kr_cookie_lru_t *cache, const struct sockaddr *sa,
+ const uint8_t *cookie_opt)
+{
+ if (kr_fails_assert(cache && sa && cookie_opt))
+ return false;
+
+ const uint8_t *cached_opt = get_cookie_opt(cache, sa);
+ if (!cached_opt) {
+ return false;
+ }
+
+ uint16_t cookie_opt_size = KNOT_EDNS_OPTION_HDRLEN +
+ knot_edns_opt_get_length(cookie_opt);
+ uint16_t cached_opt_size = KNOT_EDNS_OPTION_HDRLEN +
+ knot_edns_opt_get_length(cached_opt);
+
+ if (cookie_opt_size != cached_opt_size) {
+ return false;
+ }
+
+ return memcmp(cookie_opt, cached_opt, cookie_opt_size) == 0;
+}
+
+/**
+ * Check cookie content and store it to cache.
+ */
+static bool check_cookie_content_and_cache(const struct kr_cookie_settings *clnt_sett,
+ struct kr_request *req,
+ uint8_t *pkt_cookie_opt,
+ kr_cookie_lru_t *cache)
+{
+ if (kr_fails_assert(clnt_sett && req && pkt_cookie_opt && cache))
+ return false;
+
+ const uint8_t *pkt_cookie_data = knot_edns_opt_get_data(pkt_cookie_opt);
+ uint16_t pkt_cookie_len = knot_edns_opt_get_length(pkt_cookie_opt);
+ /* knot_edns_opt_cookie_parse() returns error on invalid data. */
+
+ const uint8_t *pkt_cc = NULL, *pkt_sc = NULL;
+ uint16_t pkt_cc_len = 0, pkt_sc_len = 0;
+
+ int ret = knot_edns_opt_cookie_parse(pkt_cookie_data, pkt_cookie_len,
+ &pkt_cc, &pkt_cc_len,
+ &pkt_sc, &pkt_sc_len);
+ if (ret != KNOT_EOK || !pkt_sc) {
+ VERBOSE_MSG(NULL, "%s\n",
+ "got malformed DNS cookie or server cookie missing");
+ return false;
+ }
+ if (kr_fails_assert(pkt_cc_len == KNOT_OPT_COOKIE_CLNT))
+ return false;
+
+ /* Check server address against received client cookie. */
+ const struct sockaddr *srvr_sockaddr = passed_server_sockaddr(req);
+ ret = srvr_sockaddr_cc_check(srvr_sockaddr, pkt_cc, pkt_cc_len,
+ clnt_sett);
+ if (ret < 0) {
+ VERBOSE_MSG(NULL, "%s\n", "could not match received cookie");
+ return false;
+ }
+ if (kr_fails_assert(srvr_sockaddr))
+ return false;
+
+ /* Don't cache received cookies that don't match the current secret. */
+ if ((ret == 1) &&
+ !is_cookie_cached(cache, srvr_sockaddr, pkt_cookie_opt)) {
+ ret = kr_cookie_lru_set(cache, srvr_sockaddr, pkt_cookie_opt);
+ if (ret != kr_ok()) {
+ VERBOSE_MSG(NULL, "%s\n", "failed caching cookie");
+ } else {
+ VERBOSE_MSG(NULL, "%s\n", "cookie cached");
+ }
+ }
+
+ return true;
+}
+
+/** Process incoming response. */
+int check_response(kr_layer_t *ctx, knot_pkt_t *pkt)
+{
+ struct kr_request *req = ctx->req;
+ struct kr_query *qry = req->current_query;
+ struct kr_cookie_ctx *cookie_ctx = &req->ctx->cookie_ctx;
+
+ if (ctx->state & (KR_STATE_DONE | KR_STATE_FAIL)) {
+ return ctx->state;
+ }
+
+ if (!cookie_ctx->clnt.enabled || (qry->flags.TCP)) {
+ return ctx->state;
+ }
+
+ /* Obtain cookie if present in response. Don't check actual content. */
+ uint8_t *pkt_cookie_opt = NULL;
+ if (knot_pkt_has_edns(pkt)) {
+ pkt_cookie_opt = knot_edns_get_option(pkt->opt_rr,
+ KNOT_EDNS_OPTION_COOKIE);
+ }
+
+ kr_cookie_lru_t *cookie_cache = req->ctx->cache_cookie;
+
+ const struct sockaddr *srvr_sockaddr = passed_server_sockaddr(req);
+
+ if (!pkt_cookie_opt && srvr_sockaddr &&
+ get_cookie_opt(cookie_cache, srvr_sockaddr)) {
+ /* We haven't received any cookies although we should. */
+ VERBOSE_MSG(NULL, "%s\n",
+ "expected to receive a cookie but none received");
+ return KR_STATE_FAIL;
+ }
+
+ if (!pkt_cookie_opt) {
+ /* Don't do anything if no cookies expected and received. */
+ return ctx->state;
+ }
+
+ if (!check_cookie_content_and_cache(&cookie_ctx->clnt, req,
+ pkt_cookie_opt, cookie_cache)) {
+ return KR_STATE_FAIL;
+ }
+
+ uint16_t rcode = knot_pkt_ext_rcode(pkt);
+ if (rcode == KNOT_RCODE_BADCOOKIE) {
+ struct kr_query *next = NULL;
+ if (!(qry->flags.BADCOOKIE_AGAIN)) {
+ /* Received first BADCOOKIE, regenerate query. */
+ next = kr_rplan_push(&req->rplan, qry->parent,
+ qry->sname, qry->sclass,
+ qry->stype);
+ }
+
+ if (next) {
+ VERBOSE_MSG(NULL, "%s\n", "BADCOOKIE querying again");
+ qry->flags.BADCOOKIE_AGAIN = true;
+ } else {
+ /*
+ * Either the planning of the second request failed or
+ * BADCOOKIE received for the second time.
+ *
+ * RFC7873 5.3 says that TCP should be used. Currently
+ * we always expect that the server doesn't support TCP.
+ */
+ qry->flags.BADCOOKIE_AGAIN = false;
+ return KR_STATE_FAIL;
+ }
+
+ return KR_STATE_CONSUME;
+ }
+
+ return ctx->state;
+}
+
+static inline uint8_t *req_cookie_option(struct kr_request *req)
+{
+ if (!req || !req->qsource.opt) {
+ return NULL;
+ }
+
+ return knot_edns_get_option(req->qsource.opt, KNOT_EDNS_OPTION_COOKIE);
+}
+
+/**
+ * @brief Returns resolver state and sets answer RCODE on missing or invalid
+ * server cookie.
+ *
+ * @note Caller should exit when only KR_STATE_FAIL is returned.
+ *
+ * @param state original resolver state
+ * @param sc_present true if server cookie is present
+ * @param ignore_badcookie true if bad cookies should be treated as good ones
+ * @param req request context
+ * @return new resolver state
+ */
+static int invalid_sc_status(int state, bool sc_present, bool ignore_badcookie,
+ const struct kr_request *req, knot_pkt_t *answer)
+{
+ if (kr_fails_assert(req && answer))
+ return KR_STATE_FAIL;
+
+ const knot_pkt_t *pkt = req->qsource.packet;
+
+ if (!pkt) {
+ return KR_STATE_FAIL;
+ }
+
+ if (knot_wire_get_qdcount(pkt->wire) == 0) {
+ /* RFC7873 5.4 */
+ state = KR_STATE_DONE;
+ if (sc_present) {
+ kr_pkt_set_ext_rcode(answer, KNOT_RCODE_BADCOOKIE);
+ state |= KR_STATE_FAIL;
+ }
+ } else if (!ignore_badcookie) {
+ /* Generate BADCOOKIE response. */
+ VERBOSE_MSG(NULL, "%s\n",
+ !sc_present ? "request is missing server cookie" :
+ "request has invalid server cookie");
+ if (!knot_pkt_has_edns(answer)) {
+ VERBOSE_MSG(NULL, "%s\n",
+ "missing EDNS section in prepared answer");
+ /* Caller should exit on this (and only this) state. */
+ return KR_STATE_FAIL;
+ }
+ kr_pkt_set_ext_rcode(answer, KNOT_RCODE_BADCOOKIE);
+ state = KR_STATE_FAIL | KR_STATE_DONE;
+ }
+
+ return state;
+}
+
+int check_request(kr_layer_t *ctx)
+{
+ struct kr_request *req = ctx->req;
+ struct kr_cookie_settings *srvr_sett = &req->ctx->cookie_ctx.srvr;
+
+ if (!srvr_sett->enabled) {
+ return ctx->state;
+ }
+
+ knot_pkt_t *answer = req->answer; // FIXME: see kr_request_ensure_answer()
+
+ if (ctx->state & (KR_STATE_DONE | KR_STATE_FAIL)) {
+ return ctx->state;
+ }
+
+ if (!srvr_sett->enabled) {
+ if (knot_pkt_has_edns(answer)) {
+ /* Delete any cookies. */
+ knot_edns_remove_options(answer->opt_rr,
+ KNOT_EDNS_OPTION_COOKIE);
+ }
+ return ctx->state;
+ }
+
+ uint8_t *req_cookie_opt = req_cookie_option(req);
+ if (!req_cookie_opt) {
+ return ctx->state; /* Don't do anything without cookies. */
+ }
+
+ struct knot_dns_cookies cookies;
+ memset(&cookies, 0, sizeof(cookies));
+ int ret = kr_parse_cookie_opt(req_cookie_opt, &cookies);
+ if (ret != kr_ok()) {
+ /* FORMERR -- malformed cookies. */
+ VERBOSE_MSG(NULL, "%s\n", "request with malformed cookie");
+ knot_wire_set_rcode(answer->wire, KNOT_RCODE_FORMERR);
+ return KR_STATE_FAIL | KR_STATE_DONE;
+ }
+
+ /*
+ * RFC7873 5.2.3 and 5.2.4 suggest that queries with invalid or
+ * missing server cookies can be treated like normal.
+ * Right now bad cookies are always ignored (i.e. treated as valid).
+ */
+ bool ignore_badcookie = true;
+
+ const struct knot_sc_alg *current_sc_alg = kr_sc_alg_get(srvr_sett->current.alg_id);
+
+ if (!req->qsource.addr || !srvr_sett->current.secr || !current_sc_alg) {
+ VERBOSE_MSG(NULL, "%s\n", "missing valid server cookie context");
+ return KR_STATE_FAIL;
+ }
+
+ int return_state = ctx->state;
+
+ struct knot_sc_private srvr_data = {
+ .clnt_sockaddr = req->qsource.addr,
+ .secret_data = srvr_sett->current.secr->data,
+ .secret_len = srvr_sett->current.secr->size
+ };
+
+ struct knot_sc_input sc_input = {
+ .cc = cookies.cc,
+ .cc_len = cookies.cc_len,
+ /* Don't set nonce here. */
+ .srvr_data = &srvr_data
+ };
+
+ struct kr_nonce_input nonce = {
+ .rand = kr_rand_bytes(sizeof(nonce.rand)),
+ .time = req->current_query->timestamp.tv_sec
+ };
+
+ if (!cookies.sc) {
+ /* Request has no server cookie. */
+ return_state = invalid_sc_status(return_state, false,
+ ignore_badcookie, req, answer);
+ if (return_state & KR_STATE_FAIL) {
+ return return_state;
+ }
+ goto answer_add_cookies;
+ }
+
+ /* Check server cookie obtained in request. */
+
+ ret = knot_sc_check(KR_NONCE_LEN, &cookies, &srvr_data, current_sc_alg);
+ if (ret == KNOT_EINVAL && srvr_sett->recent.secr) {
+ const struct knot_sc_alg *recent_sc_alg = kr_sc_alg_get(srvr_sett->recent.alg_id);
+ if (recent_sc_alg) {
+ /* Try recent algorithm. */
+ struct knot_sc_private recent_srvr_data = {
+ .clnt_sockaddr = req->qsource.addr,
+ .secret_data = srvr_sett->recent.secr->data,
+ .secret_len = srvr_sett->recent.secr->size
+ };
+ ret = knot_sc_check(KR_NONCE_LEN, &cookies,
+ &recent_srvr_data, recent_sc_alg);
+ }
+ }
+ if (ret != KNOT_EOK) {
+ /* Invalid server cookie. */
+ return_state = invalid_sc_status(return_state, true,
+ ignore_badcookie, req, answer);
+ if (return_state & KR_STATE_FAIL) {
+ return return_state;
+ }
+ goto answer_add_cookies;
+ }
+
+ /* Server cookie is OK. */
+
+answer_add_cookies:
+ /* Add server cookie into response. */
+ ret = kr_answer_write_cookie(&sc_input, &nonce, current_sc_alg, answer);
+ if (ret != kr_ok()) {
+ return_state = KR_STATE_FAIL;
+ }
+ return return_state;
+}
+
+#undef VERBOSE_MSG
diff --git a/modules/cookies/cookiemonster.h b/modules/cookies/cookiemonster.h
new file mode 100644
index 0000000..ab1fdeb
--- /dev/null
+++ b/modules/cookies/cookiemonster.h
@@ -0,0 +1,15 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#include <libknot/packet/pkt.h>
+
+#include "lib/layer.h"
+
+/** Checks cookies of inbound requests. It's for kr_layer_api_t::begin. */
+int check_request(kr_layer_t *ctx);
+
+/** Checks cookies of received responses. It's for kr_layer_api_t::consume. */
+int check_response(kr_layer_t *ctx, knot_pkt_t *pkt);
diff --git a/modules/cookies/cookies.c b/modules/cookies/cookies.c
new file mode 100644
index 0000000..5b688d3
--- /dev/null
+++ b/modules/cookies/cookies.c
@@ -0,0 +1,78 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#include "daemon/engine.h"
+#include "lib/layer.h"
+#include "modules/cookies/cookiectl.h"
+#include "modules/cookies/cookiemonster.h"
+
+/**
+ * Get/set DNS cookie related stuff.
+ *
+ * Input: { name: value, ... }
+ * Output: current configuration
+ */
+static char *cookies_config(void *env, struct kr_module *module,
+ const char *args)
+{
+ struct kr_cookie_ctx *cookie_ctx = module->data;
+ if (kr_fails_assert(cookie_ctx))
+ return NULL;
+
+ /* Apply configuration, if any. */
+ config_apply(cookie_ctx, args);
+
+ /* Return current configuration. */
+ return config_read(cookie_ctx);
+}
+
+/*
+ * Module implementation.
+ */
+
+KR_EXPORT
+int cookies_init(struct kr_module *module)
+{
+ /* The function answer_finalize() in resolver is called before any
+ * .finish callback. Therefore this layer does not use it. */
+ static kr_layer_api_t layer = {
+ .begin = &check_request,
+ .consume = &check_response
+ };
+ /* Store module reference */
+ layer.data = module;
+ module->layer = &layer;
+
+ static const struct kr_prop props[] = {
+ { &cookies_config, "config", "Empty value to return current configuration.", },
+ { NULL, NULL, NULL }
+ };
+ module->props = props;
+
+ struct engine *engine = module->data;
+
+ struct kr_cookie_ctx *cookie_ctx = &engine->resolver.cookie_ctx;
+
+ int ret = config_init(cookie_ctx);
+ if (ret != kr_ok()) {
+ return ret;
+ }
+
+ /* Replace engine pointer. */
+ module->data = cookie_ctx;
+
+ return kr_ok();
+}
+
+KR_EXPORT
+int cookies_deinit(struct kr_module *module)
+{
+ struct kr_cookie_ctx *cookie_ctx = module->data;
+
+ config_deinit(cookie_ctx);
+
+ return kr_ok();
+}
+
+KR_MODULE_EXPORT(cookies)
diff --git a/modules/daf/.packaging/test.config b/modules/daf/.packaging/test.config
new file mode 100644
index 0000000..2fa1d8c
--- /dev/null
+++ b/modules/daf/.packaging/test.config
@@ -0,0 +1,4 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+modules.load('daf')
+assert(daf)
+quit()
diff --git a/modules/daf/README.rst b/modules/daf/README.rst
new file mode 100644
index 0000000..a5e025e
--- /dev/null
+++ b/modules/daf/README.rst
@@ -0,0 +1,146 @@
+.. SPDX-License-Identifier: GPL-3.0-or-later
+
+.. _mod-daf:
+
+DNS Application Firewall
+========================
+
+This module is a high-level interface for other powerful filtering modules and DNS views. It provides an easy interface to apply and monitor DNS filtering rules and a persistent memory for them. It also provides a restful service interface and an HTTP interface.
+
+Example configuration
+---------------------
+
+Firewall rules are declarative and consist of filters and actions. Filters have ``field operator operand`` notation (e.g. ``qname = example.com``), and may be chained using AND/OR keywords. Actions may or may not have parameters after the action name.
+
+.. code-block:: lua
+
+ -- Let's write some daft rules!
+ modules = { 'daf' }
+
+ -- Block all queries with QNAME = example.com
+ daf.add('qname = example.com deny')
+
+ -- Filters can be combined using AND/OR...
+ -- Block all queries with QNAME match regex and coming from given subnet
+ daf.add('qname ~ %w+.example.com AND src = 192.0.2.0/24 deny')
+
+ -- We also can reroute addresses in response to alternate target
+ -- This reroutes 192.0.2.1 to localhost
+ daf.add('src = 127.0.0.0/8 reroute 192.0.2.1-127.0.0.1')
+
+ -- Subnets work too, this reroutes a whole subnet
+ -- e.g. 192.0.2.55 to 127.0.0.55
+ daf.add('src = 127.0.0.0/8 reroute 192.0.2.0/24-127.0.0.0')
+
+ -- This rewrites all A answers for 'example.com' from
+ -- whatever the original address was to 127.0.0.2
+ daf.add('src = 127.0.0.0/8 rewrite example.com A 127.0.0.2')
+
+ -- Mirror queries matching given name to DNS logger
+ daf.add('qname ~ %w+.example.com mirror 127.0.0.2')
+ daf.add('qname ~ example-%d.com mirror 127.0.0.3@5353')
+
+ -- Forward queries from subnet
+ daf.add('src = 127.0.0.1/8 forward 127.0.0.1@5353')
+ -- Forward to multiple targets
+ daf.add('src = 127.0.0.1/8 forward 127.0.0.1@5353,127.0.0.2@5353')
+
+ -- Truncate queries based on destination IPs
+ daf.add('dst = 192.0.2.51 truncate')
+
+ -- Disable a rule
+ daf.disable(2)
+ -- Enable a rule
+ daf.enable(2)
+ -- Delete a rule
+ daf.del(2)
+
+ -- Delete all rules and start from scratch
+ daf.clear()
+
+.. warning:: Only the first matching rule's action is executed. Defining
+ additional actions for the same matching rule, e.g. ``src = 127.0.0.1/8``,
+ will have no effect.
+
+If you're not sure what firewall rules are in effect, see ``daf.rules``:
+
+.. code-block:: text
+
+ -- Show active rules
+ > daf.rules
+ [1] => {
+ [rule] => {
+ [count] => 42
+ [id] => 1
+ [cb] => function: 0x1a3eda38
+ }
+ [info] => qname = example.com AND src = 127.0.0.1/8 deny
+ [policy] => function: 0x1a3eda38
+ }
+ [2] => {
+ [rule] => {
+ [suspended] => true
+ [count] => 123522
+ [id] => 2
+ [cb] => function: 0x1a3ede88
+ }
+ [info] => qname ~ %w+.facebook.com AND src = 127.0.0.1/8 deny...
+ [policy] => function: 0x1a3ede88
+ }
+
+Web interface
+-------------
+
+If you have :ref:`HTTP/2 <mod-http>` loaded, the firewall automatically loads as a snippet.
+You can create, track, suspend and remove firewall rules from the web interface.
+If you load both modules, you have to load `daf` after `http`.
+
+RESTful interface
+-----------------
+
+The module also exports a RESTful API for operations over rule chains.
+
+
+.. csv-table::
+ :header: "URL", "HTTP Verb", "Action"
+
+ "/daf", "GET", "Return JSON list of active rules."
+ "/daf", "POST", "Insert new rule, rule string is expected in body. Returns rule information in JSON."
+ "/daf/<id>", "GET", "Retrieve a rule matching given ID."
+ "/daf/<id>", "DELETE", "Delete a rule matching given ID."
+ "/daf/<id>/<prop>/<val>", "PATCH", "Modify given rule, for example /daf/3/active/false suspends rule 3."
+
+This interface is used by the web interface for all operations, but you can also use it directly
+for testing.
+
+.. code-block:: bash
+
+ # Get current rule set
+ $ curl -s -X GET http://localhost:8453/daf | jq .
+ {}
+
+ # Create new rule
+ $ curl -s -X POST -d "src = 127.0.0.1 pass" http://localhost:8453/daf | jq .
+ {
+ "count": 0,
+ "active": true,
+ "info": "src = 127.0.0.1 pass",
+ "id": 1
+ }
+
+ # Disable rule
+ $ curl -s -X PATCH http://localhost:8453/daf/1/active/false | jq .
+ true
+
+ # Retrieve a rule information
+ $ curl -s -X GET http://localhost:8453/daf/1 | jq .
+ {
+ "count": 4,
+ "active": true,
+ "info": "src = 127.0.0.1 pass",
+ "id": 1
+ }
+
+ # Delete a rule
+ $ curl -s -X DELETE http://localhost:8453/daf/1 | jq .
+ true
diff --git a/modules/daf/daf.js b/modules/daf/daf.js
new file mode 100644
index 0000000..05b171b
--- /dev/null
+++ b/modules/daf/daf.js
@@ -0,0 +1,295 @@
+/* Filter grammar
+ * SPDX-License-Identifier: GPL-3.0-or-later */
+const dafg = {
+ key: {'qname': true, 'src': true, 'dst': true},
+ op: {'=': true, '~': true},
+ conj: {'and': true, 'or': true},
+ action: {'pass': true, 'deny': true, 'drop': true, 'truncate': true, 'forward': true, 'reroute': true, 'rewrite': true, 'mirror': true},
+ suggest: [
+ 'QNAME = example.com',
+ 'QNAME ~ %d+.example.com',
+ 'SRC = 127.0.0.1',
+ 'SRC = 127.0.0.1/8',
+ 'DST = 127.0.0.1',
+ 'DST = 127.0.0.1/8',
+ /* Action examples */
+ 'PASS', 'DENY', 'DROP', 'TRUNCATE',
+ 'FORWARD 127.0.0.1',
+ 'MIRROR 127.0.0.1',
+ 'REROUTE 127.0.0.1-192.168.1.1',
+ 'REROUTE 127.0.0.1/24-192.168.1.0',
+ 'REWRITE example.com A 127.0.0.1',
+ 'REWRITE example.com AAAA ::1',
+ ]
+};
+
+function setValidateHint(cls) {
+ var builderForm = $('#daf-builder-form');
+ builderForm.removeClass('has-error has-warning has-success');
+ if (cls) {
+ builderForm.addClass(cls);
+ }
+}
+
+function validateToken(tok, tbl) {
+ if (tok.length > 0 && tok[0].length > 0) {
+ if (tbl[tok[0].toLowerCase()]) {
+ setValidateHint('has-success');
+ return true;
+ } else { setValidateHint('has-error'); }
+ } else { setValidateHint('has-warning'); }
+ return false;
+}
+
+function parseOption(tok) {
+ var key = tok.shift().toLowerCase();
+ var op = null;
+ if (dafg.key[key]) {
+ op = tok.shift();
+ if (op) {
+ op = op.toLowerCase();
+ }
+ }
+ const item = {
+ text: key.toUpperCase() + ' ' + (op ? op.toUpperCase() : '') + ' ' + tok.join(' '),
+ };
+ if (dafg.key[key]) {
+ item.class = 'tag-default';
+ } else if (dafg.action[key]) {
+ item.class = 'tag-warning';
+ } else if (dafg.conj[key]) {
+ item.class = 'tag-success';
+ }
+ return item;
+}
+
+function createOption(input) {
+ const item = parseOption(input.split(' '));
+ item.value = input;
+ return item;
+}
+
+function dafComplete(form) {
+ const items = form.items;
+ for (var i in items) {
+ const tok = items[i].split(' ')[0].toLowerCase();
+ if (dafg.action[tok]) {
+ return true;
+ }
+ }
+ return false;
+}
+
+function formatRule(input) {
+ const tok = input.split(' ');
+ var res = [];
+ while (tok.length > 0) {
+ const key = tok.shift().toLowerCase();
+ if (dafg.key[key]) {
+ var item = parseOption([key, tok.shift(), tok.shift()]);
+ res.push('<span class="label tag '+item.class+'">'+item.text+'</span>');
+ } else if (dafg.action[key]) {
+ var item = parseOption([key].concat(tok));
+ res.push('<span class="label tag '+item.class+'">'+item.text+'</span>');
+ tok.splice(0, tok.length);
+ } else if (dafg.conj[key]) {
+ var item = parseOption([key]);
+ res.push('<span class="label tag '+item.class+'">'+item.text+'</span>');
+ }
+ }
+ return res.join('');
+}
+
+function toggleRule(row, span, enabled) {
+ if (!enabled) {
+ span.removeClass('glyphicon-pause');
+ span.addClass('glyphicon-play');
+ row.addClass('warning');
+ } else {
+ span.removeClass('glyphicon-play');
+ span.addClass('glyphicon-pause');
+ row.removeClass('warning');
+ }
+}
+
+function ruleControl(cell, type, url, action) {
+ const row = cell.parent();
+ $.ajax({
+ url: 'daf/' + row.data('rule-id') + url,
+ type: type,
+ success: action,
+ error: function (data) {
+ row.show();
+ const reason = data.responseText.length > 0 ? data.responseText : 'internal error';
+ cell.find('.alert').remove();
+ cell.append(
+ '<div class="alert alert-danger" role="alert">'+
+ 'Failed (code: '+data.status+', reason: '+reason+').'+
+ '</div>'
+ );
+ },
+ });
+}
+
+function bindRuleControl(cell) {
+ const row = cell.parent();
+ cell.find('.daf-remove').click(function() {
+ row.hide();
+ ruleControl(cell, 'DELETE', '', function (data) {
+ cell.parent().remove();
+ });
+ });
+ cell.find('.daf-suspend').click(function() {
+ const span = $(this).find('span');
+ ruleControl(cell, 'PATCH', span.hasClass('glyphicon-pause') ? '/active/false' : '/active/true');
+ toggleRule(row, span, span.hasClass('glyphicon-play'));
+ });
+}
+
+function loadRule(rule, tbl) {
+ const row = $('<tr data-rule-id="'+rule.id+'" />');
+ row.append('<td class="daf-rule">' + formatRule(rule.info) + '</td>');
+ row.append('<td class="daf-count">' + rule.count + '</td>');
+ row.append('<td class="daf-rate"><span class="badge"></span></td>');
+ row.append('<td class="daf-ctl text-right">' +
+ '<div class="btn-group btn-group-xs">' +
+ '<button class="btn btn-default daf-suspend"><span class="glyphicon" aria="hidden" /></button>' +
+ '<button class="btn btn-default daf-remove"><span class="glyphicon glyphicon-remove" aria="hidden" /></button>' +
+ '</div></td>');
+ tbl.append(row);
+ /* Bind rule controls */
+ bindRuleControl(row.find('.daf-ctl'));
+ toggleRule(row, row.find('.daf-suspend span'), rule.active);
+}
+
+/* Load the filter table from JSON */
+function loadTable(resp) {
+ const tbl = $('#daf-rules')
+ tbl.children().remove();
+ tbl.append('<tr><th>Rule</th><th>Matches</th><th>Rate</th><th></th></tr>')
+ for (var i in resp) {
+ loadRule(resp[i], tbl);
+ }
+}
+
+document.addEventListener("DOMContentLoaded", () => {
+ /* Load the filter table. */
+ $.ajax({
+ url: 'daf',
+ type: 'get',
+ dataType: 'json',
+ success: loadTable
+ });
+ /* Listen for counter updates */
+ const wsStats = ('https:' == document.location.protocol ? 'wss://' : 'ws://') + location.host + '/daf';
+ const ws = new Socket(wsStats);
+ var lastRateUpdate = Date.now();
+ ws.onmessage = function(evt) {
+ var data = JSON.parse(evt.data);
+ /* Update heartbeat clock */
+ var now = Date.now();
+ var dt = now - lastRateUpdate;
+ lastRateUpdate = now;
+ /* Update match counts and rates */
+ $('#daf-rules .daf-rate span').text('');
+ for (var key in data) {
+ const row = $('tr[data-rule-id="'+key+'"]');
+ if (row) {
+ const cell = row.find('.daf-count');
+ const diff = data[key] - parseInt(cell.text());
+ cell.text(data[key]);
+ const badge = row.find('.daf-rate span');
+ if (diff > 0) {
+ /* Normalize difference to heartbeat (in msecs) */
+ const rate = Math.ceil((1000 * diff) / dt);
+ badge.text(rate + ' pps');
+ }
+ }
+ }
+ };
+ /* Rule builder UI */
+ $('#daf-builder').selectize({
+ delimiter: ',',
+ persist: true,
+ highlight: true,
+ closeAfterSelect: true,
+ onItemAdd: function (input, item) {
+ setValidateHint();
+ /* Prevent new rules when action is specified */
+ const tok = input.split(' ');
+ if (dafg.action[tok[0].toLowerCase()]) {
+ $('#daf-add').focus();
+ } else if(dafComplete(this)) {
+ /* No more rules after query is complete. */
+ item.remove();
+ }
+ },
+ createFilter: function (input) {
+ const tok = input.split(' ');
+ var key, op, expr;
+ /* If there are already filters, allow conjunctions. */
+ if (tok.length > 0 && this.items.length > 0 && dafg.conj[tok[0]]) {
+ setValidateHint();
+ return true;
+ }
+ /* First token is expected to be filter key,
+ * or any postrule with a parameter */
+ if (validateToken(tok, dafg.key)) {
+ key = tok.shift();
+ } else if (tok.length > 1 && validateToken(tok, dafg.action)) {
+ setValidateHint();
+ return true;
+ } else {
+ return false;
+ }
+ /* Input is a filter - second token must be operator */
+ if (validateToken(tok, dafg.op)) {
+ op = tok.shift();
+ } else {
+ return false;
+ }
+ /* Input is a filter - the rest of the tokens are RHS arguments. */
+ if (tok.length > 0 && tok[0].length > 0) {
+ expr = tok.join(' ');
+ } else {
+ setValidateHint('has-warning');
+ return false;
+ }
+ setValidateHint('has-success');
+ return true;
+ },
+ create: createOption,
+ render: {
+ item: function(item, escape) {
+ return '<div class="name '+item.class+'">' + escape(item.text) + '</span>';
+ },
+ },
+ });
+ /* Add default suggestions. */
+ const dafBuilder = $('#daf-builder')[0].selectize;
+ for (var i in dafg.suggest) {
+ dafBuilder.addOption(createOption(dafg.suggest[i]));
+ }
+ /* Rule builder submit */
+ $('#daf-add').click(function () {
+ const form = $('#daf-builder-form').parent();
+ if (dafBuilder.items.length == 0 || form.hasClass('has-error')) {
+ return;
+ }
+ /* Clear previous errors and resubmit. */
+ form.parent().find('.alert').remove();
+ $.post('daf', dafBuilder.items.join(' '))
+ .done(function (data) {
+ dafBuilder.clear();
+ loadRule(data, $('#daf-rules'));
+ })
+ .fail(function (data) {
+ const reason = data.responseText.length > 0 ? data.responseText : 'internal error';
+ form.after(
+ '<div class="alert alert-danger" role="alert">'+
+ 'Couldn\'t add rule (code: '+data.status+', reason: '+reason+').'+
+ '</div>'
+ );
+ });
+ });
+});
diff --git a/modules/daf/daf.lua b/modules/daf/daf.lua
new file mode 100644
index 0000000..c3b089b
--- /dev/null
+++ b/modules/daf/daf.lua
@@ -0,0 +1,392 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+
+local ffi = require('ffi')
+
+-- Load dependent modules
+if not view then modules.load('view') end
+if not policy then modules.load('policy') end
+
+-- Actions
+local actions = {
+ pass = function() return policy.PASS end,
+ deny = function () return policy.DENY end,
+ drop = function() return policy.DROP end,
+ tc = function() return policy.TC end,
+ truncate = function() return policy.TC end,
+ forward = function (g)
+ local addrs = {}
+ local tok = g()
+ for addr in string.gmatch(tok, '[^,]+') do
+ table.insert(addrs, addr)
+ end
+ return policy.FORWARD(addrs)
+ end,
+ mirror = function (g)
+ return policy.MIRROR(g())
+ end,
+ reroute = function (g)
+ local rules = {}
+ local tok = g()
+ while tok do
+ local from, to = tok:match '([^-]+)-(%S+)'
+ rules[from] = to
+ tok = g()
+ end
+ return policy.REROUTE(rules)
+ end,
+ rewrite = function (g)
+ local rules = {}
+ local tok = g()
+ while tok do
+ -- This is currently limited to A/AAAA rewriting
+ -- in fixed format '<owner> <type> <addr>'
+ local _, to = g(), g()
+ rules[tok] = to
+ tok = g()
+ end
+ return policy.REROUTE(rules, true)
+ end,
+}
+
+-- Filter rules per column
+local filters = {
+ -- Filter on QNAME (either pattern or suffix match)
+ qname = function (g)
+ local op, val = g(), todname(g())
+ if op == '~' then return policy.pattern(true, val:sub(2)) -- Skip leading label length
+ elseif op == '=' then return policy.suffix(true, {val})
+ else error(string.format('invalid operator "%s" on qname', op)) end
+ end,
+ -- Filter on source address
+ src = function (g)
+ local op = g()
+ if op ~= '=' then error('address supports only "=" operator') end
+ return view.rule_src(true, g())
+ end,
+ -- Filter on destination address
+ dst = function (g)
+ local op = g()
+ if op ~= '=' then error('address supports only "=" operator') end
+ return view.rule_dst(true, g())
+ end,
+}
+
+local function parse_filter(tok, g, prev)
+ if not tok then error(string.format('expected filter after "%s"', prev)) end
+ local filter = filters[tok:lower()]
+ if not filter then error(string.format('invalid filter "%s"', tok)) end
+ return filter(g)
+end
+
+local function parse_rule(g)
+ -- Allow action without filter
+ local tok = g()
+ if tok == nil then
+ error('empty rule is not allowed')
+ end
+ if not filters[tok:lower()] then
+ return tok, nil
+ end
+ local f = parse_filter(tok, g)
+ -- Compose filter functions on conjunctions
+ -- or terminate filter chain and return
+ tok = g()
+ while tok do
+ if tok:lower() == 'and' then
+ local fa, fb = f, parse_filter(g(), g, tok)
+ f = function (req, qry) return fa(req, qry) and fb(req, qry) end
+ elseif tok:lower() == 'or' then
+ local fa, fb = f, parse_filter(g(), g, tok)
+ f = function (req, qry) return fa(req, qry) or fb(req, qry) end
+ else
+ break
+ end
+ tok = g()
+ end
+ return tok, f
+end
+
+local function parse_query(g)
+ local ok, actid, filter = pcall(parse_rule, g)
+ if not ok then return nil, actid end
+ actid = actid:lower()
+ if not actions[actid] then return nil, string.format('invalid action "%s"', actid) end
+ -- Parse and interpret action
+ local action = actions[actid]
+ if type(action) == 'function' then
+ action = action(g)
+ end
+ return actid, action, filter
+end
+
+-- Compile a rule described by query language
+-- The query language is modelled by iptables/nftables
+-- conj = AND | OR
+-- op = IS | NOT | LIKE | IN
+-- filter = <key> <op> <expr>
+-- rule = <filter> | <filter> <conj> <rule>
+-- action = PASS | DENY | DROP | TC | FORWARD
+-- query = <rule> <action>
+local function compile(query)
+ local g = string.gmatch(query, '%S+')
+ return parse_query(g)
+end
+
+-- @function Describe given rule for presentation
+local function rule_info(r)
+ return {info=r.info, id=r.rule.id, active=(r.rule.suspended ~= true), count=r.rule.count}
+end
+
+-- Module declaration
+local M = {
+ rules = {}
+}
+
+-- @function Remove a rule
+
+-- @function Cleanup module
+function M.deinit()
+ if http then
+ local endpoints = http.configs._builtin.webmgmt.endpoints
+ endpoints['/daf'] = nil
+ endpoints['/daf.js'] = nil
+ http.snippets['/daf'] = nil
+ end
+end
+
+-- @function Add rule
+function M.add(rule)
+ -- Ignore duplicates
+ for _, r in ipairs(M.rules) do
+ if r.info == rule then return r end
+ end
+ local id, action, filter = compile(rule)
+ if not id then error(action) end
+ -- Combine filter and action into policy
+ local p
+ if filter then
+ p = function (req, qry)
+ return filter(req, qry) and action
+ end
+ else
+ p = function ()
+ return action
+ end
+ end
+ local desc = {info=rule, policy=p}
+ -- Enforce in policy module, special actions are postrules
+ if id == 'reroute' or id == 'rewrite' then
+ desc.rule = policy.add(p, true)
+ else
+ desc.rule = policy.add(p)
+ end
+ table.insert(M.rules, desc)
+ return desc
+end
+
+-- @function Remove a rule
+function M.del(id)
+ for key, r in ipairs(M.rules) do
+ if r.rule.id == id then
+ policy.del(id)
+ table.remove(M.rules, key)
+ return true
+ end
+ end
+ return nil
+end
+
+-- @function Remove all rules
+function M.clear()
+ for _, r in ipairs(M.rules) do
+ policy.del(r.rule.id)
+ end
+ M.rules = {}
+ return true
+end
+
+-- @function Find a rule
+function M.get(id)
+ for _, r in ipairs(M.rules) do
+ if r.rule.id == id then
+ return r
+ end
+ end
+ return nil
+end
+
+-- @function Enable/disable a rule
+function M.toggle(id, val)
+ for _, r in ipairs(M.rules) do
+ if r.rule.id == id then
+ r.rule.suspended = not val
+ return true
+ end
+ end
+ return nil
+end
+
+-- @function Enable/disable a rule
+function M.disable(id)
+ return M.toggle(id, false)
+end
+function M.enable(id)
+ return M.toggle(id, true)
+end
+
+local function consensus(op, ...)
+ local results = map(string.format(op, ...))
+ local ret = results.n > 0 -- init to true for non-empty results
+ for idx=1, results.n do
+ ret = ret and results[idx]
+ end
+ return ret
+end
+
+-- @function Public-facing API
+local function api(h, stream)
+ local m = h:get(':method')
+ -- GET method
+ if m == 'GET' then
+ local path = h:get(':path')
+ local id = tonumber(path:match '/([^/]*)$')
+ if id then
+ local r = M.get(id)
+ if r then
+ return rule_info(r)
+ end
+ return 404, '"No such rule"' -- Not found
+ else
+ local ret = {}
+ for _, r in ipairs(M.rules) do
+ table.insert(ret, rule_info(r))
+ end
+ return ret
+ end
+ -- DELETE method
+ elseif m == 'DELETE' then
+ local path = h:get(':path')
+ local id = tonumber(path:match '/([^/]*)$')
+ if id then
+ if consensus('daf.del(%s)', id) then
+ return tojson(true)
+ end
+ return 404, '"No such rule"' -- Not found
+ end
+ return 400 -- Request doesn't have numeric id
+ -- POST method
+ elseif m == 'POST' then
+ local query = stream:get_body_as_string()
+ if query then
+ local ok, r = pcall(M.add, query)
+ if not ok then return 500, string.format('"%s"', r:match('/([^/]+)$')) end
+ -- Dispatch to all other workers:
+ -- we ignore return values except error() because they are not serializable
+ consensus('daf.add "%s" and true', query)
+ return rule_info(r)
+ end
+ return 400
+ -- PATCH method
+ elseif m == 'PATCH' then
+ local path = h:get(':path')
+ local id, action, val = path:match '(%d+)/([^/]*)/([^/]*)$'
+ id = tonumber(id)
+ if not id or not action or not val then
+ return 400 -- Request not well formatted
+ end
+ -- We do not support more actions
+ if action == 'active' then
+ if consensus('daf.toggle(%d, %s)', id, val == 'true' or 'false') then
+ return tojson(true)
+ else
+ return 404, '"No such rule"'
+ end
+ else
+ return 501, '"Action not implemented"'
+ end
+ end
+end
+
+local function getmatches()
+ local update = {}
+ -- Must have string keys for JSON object and not an array
+ local inst_counters = map('ret = {} '
+ .. 'for _, rule in ipairs(daf.rules) do '
+ .. 'ret[tostring(rule.rule.id)] = rule.rule.count '
+ .. 'end '
+ .. 'return ret')
+ for inst_idx=1, inst_counters.n do
+ for r_id, r_cnt in pairs(inst_counters[inst_idx]) do
+ update[r_id] = (update[r_id] or 0) + r_cnt
+ end
+ end
+ return update
+end
+
+-- @function Publish DAF statistics
+local function publish(_, ws)
+ local ok, last = true, nil
+ while ok do
+ -- Check if we have new rule matches
+ local diff = {}
+ local has_update, update = pcall(getmatches)
+ if has_update then
+ if last then
+ for id, count in pairs(update) do
+ if not last[id] or last[id] < count then
+ diff[id] = count
+ end
+ end
+ end
+ last = update
+ end
+ -- Update counters when there is a new data
+ if next(diff) ~= nil then
+ ok = ws:send(tojson(diff))
+ else
+ ok = ws:send_ping()
+ end
+ worker.sleep(1)
+ end
+end
+
+function M.init()
+ -- avoid ordering problem between HTTP and daf module
+ event.after(0, M.config)
+end
+
+-- @function Configure module
+function M.config()
+ if not http then
+ log_warn(ffi.C.LOG_GRP_DAF,
+ 'HTTP API unavailable because HTTP module is not loaded, use modules.load("http")')
+ return
+ end
+ local endpoints = http.configs._builtin.webmgmt.endpoints
+ -- Export API and data publisher
+ endpoints['/daf.js'] = http.page('daf.js', 'daf')
+ endpoints['/daf'] = {'application/json', api, publish}
+ -- Export snippet
+ http.snippets['/daf'] = {'Application Firewall', [[
+ <script type="text/javascript" src="daf.js"></script>
+ <div class="row" style="margin-bottom: 5px">
+ <form id="daf-builder-form">
+ <div class="col-md-11">
+ <input type="text" id="daf-builder" class="form-control" aria-label="..." />
+ </div>
+ <div class="col-md-1">
+ <button type="button" id="daf-add" class="btn btn-default btn-sm">Add</button>
+ </div>
+ </form>
+ </div>
+ <div class="row">
+ <div class="col-md-12">
+ <table id="daf-rules" class="table table-striped table-responsive">
+ <th><td>No rules here yet.</td></th>
+ </table>
+ </div>
+ </div>
+ ]]}
+end
+
+return M
diff --git a/modules/daf/daf.test.lua b/modules/daf/daf.test.lua
new file mode 100644
index 0000000..2a46393
--- /dev/null
+++ b/modules/daf/daf.test.lua
@@ -0,0 +1,80 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+
+-- do not attempt to contact outside world, operate only on cache
+net.ipv4 = false
+net.ipv6 = false
+-- do not listen, test is driven by config code
+env.KRESD_NO_LISTEN = true
+
+local path = worker.cwd..'/control/'..worker.pid
+same(true, net.listen(path, nil, {kind = 'control'}),
+ 'new control sockets were created so map() can work')
+
+modules.load('hints > iterate')
+modules.load('daf')
+
+hints['pass.'] = '127.0.0.1'
+hints['deny.'] = '127.0.0.1'
+hints['deny.'] = '127.0.0.1'
+hints['drop.'] = '127.0.0.1'
+hints['del.'] = '127.0.0.1'
+hints['del2.'] = '127.0.0.1'
+hints['toggle.'] = '127.0.0.1'
+
+local check_answer = require('test_utils').check_answer
+
+local function test_sanity()
+ check_answer('daf sanity (no rules)', 'pass.', kres.type.A, kres.rcode.NOERROR)
+ check_answer('daf sanity (no rules)', 'deny.', kres.type.A, kres.rcode.NOERROR)
+ check_answer('daf sanity (no rules)', 'drop.', kres.type.A, kres.rcode.NOERROR)
+ check_answer('daf sanity (no rules)', 'del.', kres.type.A, kres.rcode.NOERROR)
+ check_answer('daf sanity (no rules)', 'del2.', kres.type.A, kres.rcode.NOERROR)
+ check_answer('daf sanity (no rules)', 'toggle.', kres.type.A, kres.rcode.NOERROR)
+end
+
+local function test_basic_actions()
+ daf.add('qname = pass. pass')
+ daf.add('qname = deny. deny')
+ daf.add('qname = drop. drop')
+
+ check_answer('daf pass action', 'pass.', kres.type.A, kres.rcode.NOERROR)
+ check_answer('daf deny action', 'deny.', kres.type.A, kres.rcode.NXDOMAIN)
+ check_answer('daf drop action', 'drop.', kres.type.A, kres.rcode.SERVFAIL)
+end
+
+local function test_del()
+ -- first matching rule is used
+ local first = daf.add('qname = del. deny')
+ local second = daf.add('qname = del2. deny')
+
+ check_answer('daf del - first rule active',
+ 'del.', kres.type.A, kres.rcode.NXDOMAIN)
+ check_answer('daf del - second rule active',
+ 'del2.', kres.type.A, kres.rcode.NXDOMAIN)
+ daf.del(first.rule.id)
+ check_answer('daf del - first rule deleted',
+ 'del.', kres.type.A, kres.rcode.NOERROR)
+ daf.del(second.rule.id)
+ check_answer('daf del - second rule deleted',
+ 'del2.', kres.type.A, kres.rcode.NOERROR)
+end
+
+local function test_toggle()
+ local toggle = daf.add('qname = toggle. deny')
+
+ check_answer('daf - toggle active',
+ 'toggle.', kres.type.A, kres.rcode.NXDOMAIN)
+ daf.disable(toggle.rule.id)
+ check_answer('daf - toggle disabled',
+ 'toggle.', kres.type.A, kres.rcode.NOERROR)
+ daf.enable(toggle.rule.id)
+ check_answer('daf - toggle enabled',
+ 'toggle.', kres.type.A, kres.rcode.NXDOMAIN)
+end
+
+return {
+ test_sanity, -- must be first, expects no daf rules
+ test_basic_actions,
+ test_del,
+ test_toggle,
+}
diff --git a/modules/daf/daf_http.test.lua b/modules/daf/daf_http.test.lua
new file mode 100644
index 0000000..20d5f90
--- /dev/null
+++ b/modules/daf/daf_http.test.lua
@@ -0,0 +1,216 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+-- check prerequisites
+local has_http = pcall(require, 'kres_modules.http') and pcall(require, 'http.request')
+if not has_http then
+ -- skipping daf module test because http its not installed
+ os.exit(77)
+else
+ local path = worker.cwd..'/control/'..worker.pid
+ same(true, net.listen(path, nil, {kind = 'control'}),
+ 'new control sockets were created so map() can work')
+
+ local request = require('http.request')
+
+ modules.load('http')
+ modules.load('daf')
+
+ local bound
+ for _ = 1,1000 do
+ bound, _err = pcall(net.listen, '127.0.0.1', math.random(40000, 49999), { kind = 'webmgmt'})
+ if bound then
+ break
+ end
+ end
+ assert(bound, 'unable to bind a port for HTTP module (1000 attempts)')
+
+ -- globals for this module
+ local _, host, port, baseuri
+ local function start_server()
+ local server_fd = next(http.servers)
+ assert(server_fd)
+ local server = http.servers[server_fd].server
+ ok(server ~= nil, 'creates server instance')
+ _, host, port = server:localname()
+ ok(host and port, 'binds to an interface')
+ baseuri = string.format('http://%s:%d/daf', host, port)
+ end
+
+ -- helper for returning useful values to test on
+-- local function http_get(uri)
+-- local headers, stream = assert(request.new_from_uri(uri):go(16))
+-- local body = assert(stream:get_body_as_string())
+-- return tonumber(headers:get(':status')), body, headers:get('content-type')
+-- end
+
+ local function http_req(uri, method, reqbody)
+ local req = assert(request.new_from_uri(baseuri .. uri))
+ req.headers:upsert(':method', method)
+ req:set_body(reqbody)
+ local headers, stream = assert(req:go(16))
+ local ansbody = assert(stream:get_body_as_string())
+ return tonumber(headers:get(':status')), ansbody, headers:get('content-type')
+ end
+
+ local function http_get(uri)
+ return http_req(uri, 'GET')
+ end
+
+ -- compare two tables, expected value is specified as JSON
+ -- comparison relies on table_print which sorts table keys
+ local function compare_tables(expectedjson, gotjson, desc)
+ same(
+ table_print(fromjson(expectedjson)),
+ table_print(fromjson(gotjson)),
+ desc)
+ end
+
+ -- test whether http interface responds and binds
+ local function test_daf_api()
+ local code, body, mime
+ -- rule listing /daf
+ code, body, mime = http_get('/')
+ same(code, 200, 'rule listing return 200 OK')
+ same(body, '{}', 'daf rule list is empty after start')
+ same(mime, 'application/json', 'daf rule list has application/json content type')
+ -- get non-existing rule
+ code, body = http_req('/0', 'GET')
+ same(code, 404, 'non-existing rule retrieval returns 404')
+ same(body, '"No such rule"', 'explanatory message is present')
+
+ -- delete non-existing rule
+ code, body = http_req('/0', 'DELETE')
+ same(code, 404, 'non-existing rule deletion returns 404')
+ same(body, '"No such rule"', 'explanatory message is present')
+
+ -- bad PATCH
+ code = http_req('/0', 'PATCH')
+ same(code, 400, 'PATCH detects missing parameters')
+
+ -- bad POST
+ code = http_req('/', 'POST')
+ same(code, 500, 'POST without parameters is detected')
+
+ -- POST first new rule
+ code, body, mime = http_req('/', 'POST', 'src = 192.0.2.0 pass')
+ same(code, 200, 'first POST succeeds')
+ compare_tables(body,
+ '{"count":0,"active":true,"id":0,"info":"src = 192.0.2.0 pass"}',
+ 'POST returns new rule in JSON')
+ same(mime, 'application/json', 'rule has application/json content type')
+
+ -- GET first rule
+ code, body, mime = http_req('/0', 'GET')
+ same(code, 200, 'GET for first rule succeeds')
+ compare_tables(body,
+ '{"count":0,"active":true,"id":0,"info":"src = 192.0.2.0 pass"}',
+ 'POST returns new rule in JSON')
+ same(mime, 'application/json', 'rule has application/json content type')
+
+ -- POST second new rule
+ code, body, mime = http_req('/', 'POST', 'src = 192.0.2.1 pass')
+ same(code, 200, 'second POST succeeds')
+ compare_tables(body,
+ '{"count":0,"active":true,"id":1,"info":"src = 192.0.2.1 pass"}',
+ 'POST returns new rule in JSON')
+ same(mime, 'application/json', 'rule has application/json content type')
+
+ -- GET second rule
+ code, body, mime = http_req('/1', 'GET')
+ same(code, 200, 'GET for second rule succeeds')
+ compare_tables(body,
+ '{"count":0,"active":true,"id":1,"info":"src = 192.0.2.1 pass"}',
+ 'POST returns new rule in JSON')
+ same(mime, 'application/json', 'rule has application/json content type')
+
+ -- PATCH first rule
+ code, body, mime = http_req('/0/active/false', 'PATCH')
+ same(code, 200, 'PATCH for first rule succeeds')
+ same(body, 'true', 'PATCH returns success in body')
+ same(mime, 'application/json', 'PATCH return value has application/json content type')
+
+ -- GET modified first rule
+ code, body, mime = http_req('/0', 'GET')
+ same(code, 200, 'GET for first rule succeeds')
+ compare_tables(body,
+ '{"count":0,"active":false,"id":0,"info":"src = 192.0.2.0 pass"}',
+ 'GET returns modified rule in JSON')
+ same(mime, 'application/json', 'rule has application/json content type')
+
+ -- GET both rules
+ code, body, mime = http_req('/', 'GET')
+ same(code, 200, 'GET for both rule succeeds')
+ compare_tables(body, [[
+ [
+ {"count":0,"active":false,"info":"src = 192.0.2.0 pass","id":0},
+ {"count":0,"active":true,"info":"src = 192.0.2.1 pass","id":1}]
+ ]],
+ 'GET returns both rules in JSON including modifications')
+ same(mime, 'application/json', 'rule list has application/json content type')
+
+ -- PATCH first rule back to original state
+ code, body, mime = http_req('/0/active/true', 'PATCH')
+ same(code, 200, 'PATCH for first rule succeeds')
+ same(body, 'true', 'PATCH returns success in body')
+ same(mime, 'application/json', 'PATCH return value has application/json content type')
+
+ -- GET modified (reversed) first rule
+ code, body, mime = http_req('/0', 'GET')
+ same(code, 200, 'GET for first rule succeeds')
+ compare_tables(body,
+ '{"count":0,"active":true,"id":0,"info":"src = 192.0.2.0 pass"}',
+ 'GET returns modified rule in JSON')
+ same(mime, 'application/json', 'rule has application/json content type')
+
+ -- DELETE first rule
+ code, body, mime = http_req('/0', 'DELETE')
+ same(code, 200, 'DELETE for first rule succeeds')
+ same(body, 'true', 'DELETE returns success in body')
+ same(mime, 'application/json', 'DELETE return value has application/json content type')
+
+ -- GET deleted (first) rule
+ code, body = http_req('/0', 'GET')
+ same(code, 404, 'GET for deleted fails with 404')
+ same(body, '"No such rule"', 'failed GET contains explanatory message')
+
+ -- GET second rule
+ code, body, mime = http_req('/1', 'GET')
+ same(code, 200, 'GET for second rule still succeeds')
+ compare_tables(body,
+ '{"count":0,"active":true,"id":1,"info":"src = 192.0.2.1 pass"}',
+ 'POST returns new rule in JSON')
+ same(mime, 'application/json', 'rule has application/json content type')
+
+ -- GET list of all rules
+ code, body, mime = http_req('/', 'GET')
+ same(code, 200, 'GET returns list with the remaining rule')
+ compare_tables(body,
+ '[{"count":0,"active":true,"id":1,"info":"src = 192.0.2.1 pass"}]',
+ 'rule list contains only the remaining rule in JSON')
+ same(mime, 'application/json', 'rule has application/json content type')
+
+ -- try to DELETE first rule again
+ code, body = http_req('/0', 'DELETE')
+ same(code, 404, 'DELETE for already deleted rule fails with 404')
+ same(body, '"No such rule"', 'DELETE explains failure')
+
+ -- DELETE second rule
+ code, body, mime = http_req('/1', 'DELETE')
+ same(code, 200, 'DELETE for second rule succeeds')
+ same(body, 'true', 'DELETE returns success in body')
+ same(mime, 'application/json', 'DELETE return value has application/json content type')
+
+ -- GET (supposedly empty) list of all rules
+ code, body, mime = http_req('/', 'GET')
+ same(code, 200, 'GET returns list with the remaining rule')
+ compare_tables(body, '[]', 'rule list is now empty JSON list')
+ same(mime, 'application/json', 'rule has application/json content type')
+ end
+
+ -- plan tests
+ local tests = {
+ start_server,
+ test_daf_api,
+ }
+
+ return tests
+end
diff --git a/modules/daf/meson.build b/modules/daf/meson.build
new file mode 100644
index 0000000..c46b749
--- /dev/null
+++ b/modules/daf/meson.build
@@ -0,0 +1,21 @@
+# LUA module: daf
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+config_tests += [
+ ['daf', files('daf.test.lua')],
+ ['daf_http', files('daf_http.test.lua')],
+]
+
+integr_tests += [
+ ['daf', meson.current_source_dir() / 'test.integr'],
+]
+
+lua_mod_src += [
+ files('daf.lua'),
+]
+
+# install daf.js
+install_data(
+ 'daf.js',
+ install_dir: modules_dir / 'daf',
+)
diff --git a/modules/daf/test.integr/deckard.yaml b/modules/daf/test.integr/deckard.yaml
new file mode 100644
index 0000000..455086f
--- /dev/null
+++ b/modules/daf/test.integr/deckard.yaml
@@ -0,0 +1,12 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+programs:
+- name: kresd
+ binary: kresd
+ additional:
+ - --noninteractive
+ templates:
+ - modules/daf/test.integr/kresd_config.j2
+ - tests/integration/hints_zone.j2
+ configs:
+ - config
+ - hints
diff --git a/modules/daf/test.integr/kresd_config.j2 b/modules/daf/test.integr/kresd_config.j2
new file mode 100644
index 0000000..0381f77
--- /dev/null
+++ b/modules/daf/test.integr/kresd_config.j2
@@ -0,0 +1,65 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+{% raw %}
+-- make sure DNSSEC is turned off for tests
+trust_anchors.remove('.')
+
+-- Disable RFC5011 TA update
+if ta_update then
+ modules.unload('ta_update')
+end
+
+-- Disable RFC8145 signaling, scenario doesn't provide expected answers
+if ta_signal_query then
+ modules.unload('ta_signal_query')
+end
+
+-- Disable RFC8109 priming, scenario doesn't provide expected answers
+if priming then
+ modules.unload('priming')
+end
+
+-- Disable this module because it make one priming query
+if detect_time_skew then
+ modules.unload('detect_time_skew')
+end
+
+modules.load('hints > iterate')
+modules.load('daf')
+
+hints['hints.net.'] = '192.0.2.1'
+
+daf.add('src = 127.0.0.0/8 reroute 192.0.2.1-192.0.2.101')
+
+policy.add(policy.suffix(policy.PASS, {todname('test.')}))
+
+_hint_root_file('hints')
+cache.size = 2*MB
+log_level('debug')
+{% endraw %}
+
+net = { '{{SELF_ADDR}}' }
+
+
+{% if QMIN == "false" %}
+option('NO_MINIMIZE', true)
+{% else %}
+option('NO_MINIMIZE', false)
+{% endif %}
+
+
+-- Self-checks on globals
+assert(help() ~= nil)
+assert(worker.id ~= nil)
+-- Self-checks on facilities
+assert(cache.count() == 0)
+assert(cache.stats() ~= nil)
+assert(cache.backends() ~= nil)
+assert(worker.stats() ~= nil)
+assert(net.interfaces() ~= nil)
+-- Self-checks on loaded stuff
+assert(net.list()[1].transport.ip == '{{SELF_ADDR}}')
+assert(#modules.list() > 0)
+-- Self-check timers
+ev = event.recurrent(1 * sec, function (ev) return 1 end)
+event.cancel(ev)
+ev = event.after(0, function (ev) return 1 end)
diff --git a/modules/daf/test.integr/module_daf.rpl b/modules/daf/test.integr/module_daf.rpl
new file mode 100644
index 0000000..686f04c
--- /dev/null
+++ b/modules/daf/test.integr/module_daf.rpl
@@ -0,0 +1,30 @@
+; SPDX-License-Identifier: GPL-3.0-or-later
+; config options
+; target-fetch-policy: "0 0 0 0 0"
+; module-config: "iterator"
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test DNS Application Firewall
+
+STEP 11 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+hints.net. IN A
+ENTRY_END
+
+; test rewrite rule applies to hints
+STEP 12 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+hints.net. IN A
+SECTION ANSWER
+hints.net. IN A 192.0.2.101
+ENTRY_END
+
+
+SCENARIO_END
diff --git a/modules/detect_time_jump/.packaging/test.config b/modules/detect_time_jump/.packaging/test.config
new file mode 100644
index 0000000..7ed0e60
--- /dev/null
+++ b/modules/detect_time_jump/.packaging/test.config
@@ -0,0 +1,4 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+modules.load('detect_time_jump')
+assert(detect_time_jump)
+quit()
diff --git a/modules/detect_time_jump/README.rst b/modules/detect_time_jump/README.rst
new file mode 100644
index 0000000..066f5a3
--- /dev/null
+++ b/modules/detect_time_jump/README.rst
@@ -0,0 +1,22 @@
+.. SPDX-License-Identifier: GPL-3.0-or-later
+
+.. _mod-detect_time_jump:
+
+Detect discontinuous jumps in the system time
+=============================================
+
+This module detect discontinuous jumps in the system time when resolver
+is running. It clears cache when a significant backward time jumps occurs.
+
+Time jumps are usually created by NTP time change or by admin intervention.
+These change can affect cache records as they store timestamp and TTL in real
+time.
+
+If you want to preserve cache during time travel you should disable
+this module by ``modules.unload('detect_time_jump')``.
+
+Due to the way monotonic system time works on typical systems,
+suspend-resume cycles will be perceived as forward time jumps,
+but this direction of shift does not have the risk of using records
+beyond their intended TTL, so forward jumps do not cause erasing the cache.
+
diff --git a/modules/detect_time_jump/detect_time_jump.lua b/modules/detect_time_jump/detect_time_jump.lua
new file mode 100644
index 0000000..6c5b63f
--- /dev/null
+++ b/modules/detect_time_jump/detect_time_jump.lua
@@ -0,0 +1,45 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+-- Module interface
+local ffi = require('ffi')
+
+local mod = {}
+mod.threshold = 10 * min
+local event_id = nil
+
+-- Get time of last cache clear. Compute difference between realtime
+-- and monotonic time. Compute difference of actual realtime and monotonic
+-- time. In ideal case these differences should be almost same.
+-- If they differ more than mod.threshold value then clear cache.
+local function check_time()
+ local checkpoint = cache.checkpoint()
+ local cache_timeshift = checkpoint.walltime.sec * 1000 - checkpoint.monotime
+ local actual_timeshift = os.time() * 1000 - tonumber(ffi.C.kr_now())
+ local jump_backward = cache_timeshift - actual_timeshift
+ if jump_backward > mod.threshold then
+ log_info(ffi.C.LOG_GRP_DETECTTIMEJUMP, "Detected backwards time jump, clearing cache.\n" ..
+ "But what does that mean? It means your future hasn't been written yet."
+ )
+ cache.clear()
+ elseif -jump_backward > mod.threshold then
+ -- On Linux 4.17+ this shouldn't happen anymore: https://lwn.net/Articles/751482/
+ log_info(ffi.C.LOG_GRP_DETECTTIMEJUMP, "Detected forward time jump. (Suspend-resume, possibly.)")
+ cache.checkpoint(true)
+ end
+end
+
+function mod.init()
+ if event_id then
+ error("Module is already loaded.")
+ else
+ event_id = event.recurrent(1 * min , check_time)
+ end
+end
+
+function mod.deinit()
+ if event_id then
+ event.cancel(event_id)
+ event_id = nil
+ end
+end
+
+return mod
diff --git a/modules/detect_time_skew/.packaging/test.config b/modules/detect_time_skew/.packaging/test.config
new file mode 100644
index 0000000..3a37907
--- /dev/null
+++ b/modules/detect_time_skew/.packaging/test.config
@@ -0,0 +1,4 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+modules.load('detect_time_skew')
+assert(detect_time_skew)
+quit()
diff --git a/modules/detect_time_skew/README.rst b/modules/detect_time_skew/README.rst
new file mode 100644
index 0000000..be66bd0
--- /dev/null
+++ b/modules/detect_time_skew/README.rst
@@ -0,0 +1,23 @@
+.. SPDX-License-Identifier: GPL-3.0-or-later
+
+.. _mod-detect_time_skew:
+
+System time skew detector
+=========================
+
+This module compares local system time with inception and expiration time
+bounds in DNSSEC signatures for ``. NS`` records. If the local system time is
+outside of these bounds, it is likely a misconfiguration which will cause
+all DNSSEC validation (and resolution) to fail.
+
+In case of mismatch, a warning message will be logged to help with
+further diagnostics.
+
+.. warning:: Information printed by this module can be forged by a network attacker!
+ System administrator MUST verify values printed by this module and
+ fix local system time using a trusted source.
+
+This module is useful for debugging purposes. It runs only once during resolver
+start does not anything after that. It is enabled by default.
+You may disable the module by appending
+``modules.unload('detect_time_skew')`` to your configuration.
diff --git a/modules/detect_time_skew/detect_time_skew.lua b/modules/detect_time_skew/detect_time_skew.lua
new file mode 100644
index 0000000..6669ce8
--- /dev/null
+++ b/modules/detect_time_skew/detect_time_skew.lua
@@ -0,0 +1,83 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+-- Module interface
+local ffi = require('ffi')
+
+local mod = {}
+local event_id = nil
+
+-- Resolve callback
+-- Check time validity of RRSIGs in priming query
+-- luacheck: no unused args
+local function check_time_callback(pkt, req)
+ if pkt == nil or pkt:rcode() ~= kres.rcode.NOERROR then
+ log_warn(ffi.C.LOG_GRP_DETECTTIMESKEW, "cannot resolve '.' NS")
+ return nil
+ end
+ local seen_rrsigs = 0
+ local valid_rrsigs = 0
+ local section = pkt:rrsets(kres.section.ANSWER)
+ local now = os.time()
+ local time_diff = 0
+ local inception = 0
+ local expiration = 0
+ for i = 1, #section do
+ local rr = section[i]
+ assert(rr.type)
+ if rr.type == kres.type.RRSIG then
+ for k = 0, rr.rrs.count - 1 do
+ seen_rrsigs = seen_rrsigs + 1
+ local rdata = rr:rdata_pt(k)
+ inception = ffi.C.kr_rrsig_sig_inception(rdata)
+ expiration = ffi.C.kr_rrsig_sig_expiration(rdata)
+ if now > expiration then
+ -- positive value = in the future
+ time_diff = now - expiration
+ elseif now < inception then
+ -- negative value = in the past
+ time_diff = now - inception
+ else
+ valid_rrsigs = valid_rrsigs + 1
+ end
+ end
+ end
+ end
+ if seen_rrsigs == 0 then
+ log_info(ffi.C.LOG_GRP_DETECTTIMESKEW, "No RRSIGs received! "..
+ "You really should configure DNSSEC trust anchor for the root.")
+ elseif valid_rrsigs == 0 then
+ log_warn(ffi.C.LOG_GRP_DETECTTIMESKEW, "Local system time %q seems to be at "..
+ "least %u seconds in the %s. DNSSEC signatures for '.' NS "..
+ "are not valid %s. Please check your system clock!",
+ os.date("%c", now),
+ math.abs(time_diff),
+ time_diff > 0 and "future" or "past",
+ time_diff > 0 and "anymore" or "yet")
+ else
+ log_info(ffi.C.LOG_GRP_DETECTTIMESKEW, "Local system time %q is within "..
+ "RRSIG validity interval <%q,%q>.", os.date("%c", now),
+ os.date("%c", inception), os.date("%c", expiration))
+ end
+end
+
+-- Do uncached priming query and check time validity of RRSIGs.
+local function check_time()
+ resolve(".", kres.type.NS, kres.class.IN, {"DNSSEC_WANT", "DNSSEC_CD", "NO_CACHE"},
+ check_time_callback)
+end
+
+function mod.init()
+ if event_id then
+ error("Module is already loaded.")
+ else
+ event_id = event.after(0 , check_time)
+ end
+end
+
+function mod.deinit()
+ if event_id then
+ event.cancel(event_id)
+ event_id = nil
+ end
+end
+
+return mod
diff --git a/modules/dns64/.packaging/test.config b/modules/dns64/.packaging/test.config
new file mode 100644
index 0000000..5abf524
--- /dev/null
+++ b/modules/dns64/.packaging/test.config
@@ -0,0 +1,4 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+modules.load('dns64')
+assert(dns64)
+quit()
diff --git a/modules/dns64/README.rst b/modules/dns64/README.rst
new file mode 100644
index 0000000..04d2427
--- /dev/null
+++ b/modules/dns64/README.rst
@@ -0,0 +1,62 @@
+.. SPDX-License-Identifier: GPL-3.0-or-later
+
+.. _mod-dns64:
+
+DNS64
+=====
+
+The module for :rfc:`6147` DNS64 AAAA-from-A record synthesis, it is used to enable client-server communication between an IPv6-only client and an IPv4-only server. See the well written `introduction`_ in the PowerDNS documentation.
+If no address is passed (i.e. ``nil``), the well-known prefix ``64:ff9b::`` is used.
+
+.. _introduction: https://doc.powerdns.com/md/recursor/dns64
+
+Simple example
+--------------
+
+.. code-block:: lua
+
+ -- Load the module with default settings
+ modules = { 'dns64' }
+ -- Reconfigure later
+ dns64.config({ prefix = '2001:db8::aabb:0:0' })
+
+.. warning:: The module currently won't work well with :func:`policy.STUB`.
+ Also, the IPv6 ``prefix`` passed in configuration is assumed to be ``/96``.
+
+.. tip:: The A record sub-requests will be DNSSEC secured, but the synthetic AAAA records can't be. Make sure the last mile between stub and resolver is secure to avoid spoofing.
+
+
+Advanced options
+----------------
+
+TTL in CNAME generated in the reverse ``ip6.arpa.`` subtree is configurable:
+
+.. code-block:: lua
+
+ dns64.config({ prefix = '2001:db8:77ff::', rev_ttl = 300 })
+
+You can specify a set of IPv6 subnets that are disallowed in answer.
+If they appear, they will be replaced by AAAAs generated from As.
+
+.. code-block:: lua
+
+ dns64.config({
+ prefix = '2001:db8:3::',
+ exclude_subnets = { '2001:db8:888::/48', '::ffff/96' },
+ })
+ -- You could even pass '::/0' to always force using generated AAAAs.
+
+In case you don't want dns64 for all clients,
+you can set ``DNS64_DISABLE`` flag via the :ref:`view module <mod-view>`.
+
+.. code-block:: lua
+
+ modules = { 'dns64', 'view' }
+ -- disable dns64 for all IPv4 source addresses
+ view:addr('0.0.0.0/0', policy.all(policy.FLAGS('DNS64_DISABLE')))
+ -- disable dns64 for all IPv6 source addresses
+ view:addr('::/0', policy.all(policy.FLAGS('DNS64_DISABLE')))
+ -- re-enable dns64 for two IPv6 subnets
+ view:addr('2001:db8:11::/48', policy.all(policy.FLAGS(nil, 'DNS64_DISABLE')))
+ view:addr('2001:db8:93::/48', policy.all(policy.FLAGS(nil, 'DNS64_DISABLE')))
+
diff --git a/modules/dns64/dns64.lua b/modules/dns64/dns64.lua
new file mode 100644
index 0000000..b4fb1ec
--- /dev/null
+++ b/modules/dns64/dns64.lua
@@ -0,0 +1,220 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+-- Module interface
+local kres = require('kres')
+local ffi = require('ffi')
+local C = ffi.C
+local M = { layer = { } }
+local addr_buf = ffi.new('char[16]')
+
+--[[
+Missing parts of the RFC:
+ > The implementation SHOULD support mapping of separate IPv4 address
+ > ranges to separate IPv6 prefixes for AAAA record synthesis. This
+ > allows handling of special use IPv4 addresses [RFC5735].
+
+ TODO: support different prefix lengths, defaulting to /96 if not specified
+ https://tools.ietf.org/html/rfc6052#section-2.2
+]]
+
+-- Config
+function M.config(conf)
+ if type(conf) ~= 'table' then
+ conf = { prefix = conf }
+ end
+ M.proxy = kres.str2ip(tostring(conf.prefix or '64:ff9b::'))
+ if M.proxy == nil or #M.proxy ~= 16 then
+ error(string.format('[dns64] %q is not a valid IPv6 address', conf.prefix), 2)
+ end
+
+ M.rev_ttl = conf.rev_ttl or 60
+ M.rev_suffix = kres.str2dname(M.proxy
+ :sub(1, 96/8)
+ -- hexdump, reverse, intersperse by dots
+ :gsub('.', function (ch) return string.format('%02x', string.byte(ch)) end)
+ :reverse()
+ :gsub('.', '%1.')
+ .. 'ip6.arpa.'
+ )
+
+ -- RFC 6147.5.1.4
+ M.exclude_subnets = {}
+ if conf.exclude_subnets ~= nil and type(conf.exclude_subnets) ~= 'table' then
+ error('[dns64] .exclude_subnets is not a table')
+ end
+ for _, subnet_cfg in ipairs(conf.exclude_subnets or { '::ffff/96' }) do
+ local subnet = {}
+ subnet.prefix = ffi.new('char[16]')
+ subnet.bitlen = C.kr_straddr_subnet(subnet.prefix, tostring(subnet_cfg))
+ if subnet.bitlen < 0 or not string.find(subnet_cfg, ':', 1, true) then
+ error(string.format('[dns64] failed to parse IPv6 subnet: %q', subnet_cfg))
+ end
+ table.insert(M.exclude_subnets, subnet)
+ end
+end
+
+-- Filter the AAAA records from the last ANSWER, return iff it's NODATA afterwards.
+-- Currently the implementation is lazy and kills it all if any AAAA is excluded.
+local function do_exclude_prefixes(qry)
+ local rrsel = qry.request.answ_selected
+ for i = 0, tonumber(rrsel.len) - 1 do
+ local rr_e = rrsel.at[i] -- struct ranked_rr_array_entry
+ if rr_e.qry_uid ~= qry.uid or rr_e.rr.type ~= kres.type.AAAA or not rr_e.to_wire
+ then goto next_rrset end
+ -- Found answer AAAA RRset
+ for _, subnet in ipairs(M.exclude_subnets) do
+ for j = 0, rr_e.rr:rdcount() - 1 do
+ local rd = rr_e.rr:rdata_pt(j)
+ if rd.len == 16 and C.kr_bitcmp(subnet.prefix, rd.data, subnet.bitlen) == 0 then
+ -- We can't use this RR. TODO: and we're lazy,
+ -- so we kill the whole RRset instead of filtering.
+ rr_e.to_wire = false
+ return true
+ end
+ end
+ end
+ -- We can use the answer -> return false
+ -- We use a nonsensical if to fool the parser; is return adjacent to a label forbidden?
+ if true then return false end
+
+ ::next_rrset::
+ end
+ -- No RRset found, it was probably NODATA.
+ return true
+end
+
+function M.layer.consume(state, req, pkt)
+ if state == kres.FAIL then return state end
+ local qry = req:current()
+ -- Observe only final answers in IN class where request has no CD flag.
+ if M.proxy == nil or not qry.flags.RESOLVED or qry.flags.DNS64_DISABLE
+ or pkt:qclass() ~= kres.class.IN or req.qsource.packet:cd() then
+ return state
+ end
+
+ -- Observe final AAAA NODATA responses to the current SNAME.
+ if pkt:qtype() == kres.type.AAAA and pkt:qname() == qry:name()
+ and qry.flags.RESOLVED and not qry.flags.CNAME and qry.parent == nil
+ and pkt:rcode() == kres.rcode.NOERROR and do_exclude_prefixes(qry) then
+ -- Start a *marked* corresponding A sub-query.
+ local extraFlags = kres.mk_qflags({})
+ extraFlags.DNSSEC_WANT = qry.flags.DNSSEC_WANT
+ extraFlags.AWAIT_CUT = true
+ extraFlags.DNS64_MARK = true
+ req:push(pkt:qname(), kres.type.A, kres.class.IN, extraFlags, qry)
+ return state
+ end
+
+
+ -- Observe answer to the marked sub-query, and convert all A records in ANSWER
+ -- to corresponding AAAA records to be put into the request's answer.
+ if not qry.flags.DNS64_MARK then return state end
+ -- Find rank for the NODATA answer.
+ -- That will result into corresponding AD flag. See RFC 6147 5.5.2.
+ local neg_rank
+ if qry.parent.flags.DNSSEC_WANT and not qry.parent.flags.DNSSEC_INSECURE
+ then neg_rank = ffi.C.KR_RANK_SECURE
+ else neg_rank = ffi.C.KR_RANK_INSECURE
+ end
+ -- Find TTL bound from SOA, according to RFC 6147 5.1.7.4.
+ local max_ttl = 600
+ for i = 1, tonumber(req.auth_selected.len) do
+ local entry = req.auth_selected.at[i - 1]
+ if entry.qry_uid == qry.parent.uid and entry.rr
+ and entry.rr.type == kres.type.SOA
+ and entry.rr.rclass == kres.class.IN then
+ max_ttl = entry.rr:ttl()
+ end
+ end
+ -- Find the As and do the conversion itself.
+ for i = 1, tonumber(req.answ_selected.len) do
+ local orig = req.answ_selected.at[i - 1]
+ if orig.qry_uid == qry.uid and orig.rr.type == kres.type.A then
+ local rank = neg_rank
+ if orig.rank < rank then rank = orig.rank end
+ -- Disable GC, as this object doesn't own owner or RDATA, it's just a reference
+ local ttl = orig.rr:ttl()
+ if ttl > max_ttl then ttl = max_ttl end
+ local rrs = ffi.gc(kres.rrset(nil, kres.type.AAAA, orig.rr.rclass, ttl), nil)
+ rrs._owner = orig.rr._owner
+ for k = 1, orig.rr.rrs.count do
+ local rdata = orig.rr:rdata( k - 1 )
+ ffi.copy(addr_buf, M.proxy, 12)
+ ffi.copy(addr_buf + 12, rdata, 4)
+ ffi.C.knot_rrset_add_rdata(rrs, ffi.string(addr_buf, 16), 16, req.pool)
+ end
+ ffi.C.kr_ranked_rrarray_add(
+ req.answ_selected,
+ rrs,
+ rank,
+ true,
+ qry.uid,
+ req.pool)
+ end
+ end
+ ffi.C.kr_ranked_rrarray_finalize(req.answ_selected, qry.uid, req.pool)
+ req:set_extended_error(kres.extended_error.FORGED, "BHD4: DNS64 synthesis")
+end
+
+local function hexchar2int(char)
+ if char >= string.byte('0') and char <= string.byte('9') then
+ return char - string.byte('0')
+ elseif char >= string.byte('a') and char <= string.byte('f') then
+ return 10 + char - string.byte('a')
+ else
+ return nil
+ end
+end
+
+-- Map the reverse subtree by generating CNAMEs; similarly to the hints module.
+--
+-- RFC 6147.5.3.1.2 says we SHOULD only generate CNAME if it points to data,
+-- but I can't see what's wrong with a CNAME to an NXDOMAIN/NODATA
+-- Reimplementation idea: as-if we had a DNAME in policy/cache?
+function M.layer.produce(_, req, pkt)
+ local qry = req.current_query
+ local sname = qry.sname
+ if ffi.C.knot_dname_in_bailiwick(sname, M.rev_suffix) < 0 or qry.flags.DNS64_DISABLE
+ then return end
+ -- Update packet question if it was minimized.
+ qry.flags.NO_MINIMIZE = true
+ if not ffi.C.knot_dname_is_equal(pkt.wire + 12, sname) or not pkt:has_wire() then
+ if not pkt:recycle() or not pkt:question(sname, qry.sclass, qry.stype)
+ then return end
+ end
+
+ -- Generate a CNAME iff the full address is queried; otherwise leave NODATA.
+ local labels_missing = 16*2 + 2 - ffi.C.knot_dname_labels(sname, nil)
+ if labels_missing == 0 then
+ -- Transforming v6 labels (hex) to v4 ones (decimal) isn't trivial:
+ local labels = sname
+ local v4name = ''
+ for _ = 1, 4 do -- append one IPv4 label at a time into v4name
+ local v4octet = 0
+ for i = 0, 1 do
+ if labels[0] ~= 1 then return end
+ local ch = hexchar2int(labels[1])
+ if not ch then return end
+ v4octet = v4octet + ch * 16^i
+ labels = labels + 2
+ end
+ v4octet = tostring(v4octet)
+ v4name = v4name .. string.char(#v4octet) .. v4octet
+ end
+ v4name = v4name .. '\7in-addr\4arpa\0'
+ if not pkt:put(sname, M.rev_ttl, kres.class.IN, kres.type.CNAME, v4name)
+ then return end
+ end
+
+ -- Simple finishing touches.
+ if labels_missing < 0 then -- and use NXDOMAIN for too long queries
+ pkt:rcode(kres.rcode.NXDOMAIN)
+ else
+ pkt:rcode(kres.rcode.NOERROR)
+ end
+ pkt.parsed = pkt.size
+ pkt:aa(true)
+ pkt:qr(true)
+ qry.flags.CACHED = true
+end
+
+return M
diff --git a/modules/dns64/dns64.test.lua b/modules/dns64/dns64.test.lua
new file mode 100644
index 0000000..45956a4
--- /dev/null
+++ b/modules/dns64/dns64.test.lua
@@ -0,0 +1,53 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+local condition = require('cqueues.condition')
+
+-- setup resolver
+modules = { 'hints', 'dns64' }
+hints['dns64.example'] = '192.168.1.1'
+hints.use_nodata(true) -- Respond NODATA to AAAA query
+hints.ttl(60)
+dns64.config('fe80::21b:77ff:0:0')
+
+-- helper to wait for query resolution
+local function wait_resolve(qname, qtype)
+ local waiting, done, cond = false, false, condition.new()
+ local rcode, answers = kres.rcode.SERVFAIL, {}
+ resolve {
+ name = qname,
+ type = qtype,
+ finish = function (answer, _)
+ rcode = answer:rcode()
+ answers = answer:section(kres.section.ANSWER)
+ -- Signal as completed
+ if waiting then
+ cond:signal()
+ end
+ done = true
+ end,
+ }
+ -- Wait if it didn't finish immediately
+ if not done then
+ waiting = true
+ cond:wait()
+ end
+ return rcode, answers
+end
+
+-- test builtin rules
+local function test_builtin_rules()
+ local rcode, answers = wait_resolve('dns64.example', kres.type.AAAA)
+ same(rcode, kres.rcode.NOERROR, 'dns64.example returns NOERROR')
+ same(#answers, 1, 'dns64.example synthesised answer')
+ local expect = {'dns64.example.', '60', 'AAAA', 'fe80::21b:77ff:c0a8:101'}
+ if #answers > 0 then
+ local rr = {kres.rr2str(answers[1]):match('(%S+)%s+(%S+)%s+(%S+)%s+(%S+)')}
+ same(rr, expect, 'dns64.example synthesised correct AAAA record')
+ end
+end
+
+-- plan tests
+local tests = {
+ test_builtin_rules,
+}
+
+return tests
diff --git a/modules/dnstap/.packaging/centos/7/builddeps b/modules/dnstap/.packaging/centos/7/builddeps
new file mode 100644
index 0000000..d3ab354
--- /dev/null
+++ b/modules/dnstap/.packaging/centos/7/builddeps
@@ -0,0 +1,3 @@
+fstrm-devel
+protobuf-c-devel
+protobuf-c-compiler
diff --git a/modules/dnstap/.packaging/centos/7/rundeps b/modules/dnstap/.packaging/centos/7/rundeps
new file mode 100644
index 0000000..06c2792
--- /dev/null
+++ b/modules/dnstap/.packaging/centos/7/rundeps
@@ -0,0 +1,2 @@
+fstrm
+protobuf-c
diff --git a/modules/dnstap/.packaging/centos/8/builddeps b/modules/dnstap/.packaging/centos/8/builddeps
new file mode 100644
index 0000000..d3ab354
--- /dev/null
+++ b/modules/dnstap/.packaging/centos/8/builddeps
@@ -0,0 +1,3 @@
+fstrm-devel
+protobuf-c-devel
+protobuf-c-compiler
diff --git a/modules/dnstap/.packaging/centos/8/rundeps b/modules/dnstap/.packaging/centos/8/rundeps
new file mode 100644
index 0000000..06c2792
--- /dev/null
+++ b/modules/dnstap/.packaging/centos/8/rundeps
@@ -0,0 +1,2 @@
+fstrm
+protobuf-c
diff --git a/modules/dnstap/.packaging/debian/10/builddeps b/modules/dnstap/.packaging/debian/10/builddeps
new file mode 100644
index 0000000..417dc04
--- /dev/null
+++ b/modules/dnstap/.packaging/debian/10/builddeps
@@ -0,0 +1,3 @@
+libfstrm-dev
+libprotobuf-c-dev
+protobuf-c-compiler
diff --git a/modules/dnstap/.packaging/debian/10/rundeps b/modules/dnstap/.packaging/debian/10/rundeps
new file mode 100644
index 0000000..a726e12
--- /dev/null
+++ b/modules/dnstap/.packaging/debian/10/rundeps
@@ -0,0 +1,2 @@
+libfstrm0
+libprotobuf-c1
diff --git a/modules/dnstap/.packaging/debian/9/builddeps b/modules/dnstap/.packaging/debian/9/builddeps
new file mode 100644
index 0000000..417dc04
--- /dev/null
+++ b/modules/dnstap/.packaging/debian/9/builddeps
@@ -0,0 +1,3 @@
+libfstrm-dev
+libprotobuf-c-dev
+protobuf-c-compiler
diff --git a/modules/dnstap/.packaging/debian/9/rundeps b/modules/dnstap/.packaging/debian/9/rundeps
new file mode 100644
index 0000000..a726e12
--- /dev/null
+++ b/modules/dnstap/.packaging/debian/9/rundeps
@@ -0,0 +1,2 @@
+libfstrm0
+libprotobuf-c1
diff --git a/modules/dnstap/.packaging/fedora/31/builddeps b/modules/dnstap/.packaging/fedora/31/builddeps
new file mode 100644
index 0000000..d3ab354
--- /dev/null
+++ b/modules/dnstap/.packaging/fedora/31/builddeps
@@ -0,0 +1,3 @@
+fstrm-devel
+protobuf-c-devel
+protobuf-c-compiler
diff --git a/modules/dnstap/.packaging/fedora/31/rundeps b/modules/dnstap/.packaging/fedora/31/rundeps
new file mode 100644
index 0000000..06c2792
--- /dev/null
+++ b/modules/dnstap/.packaging/fedora/31/rundeps
@@ -0,0 +1,2 @@
+fstrm
+protobuf-c
diff --git a/modules/dnstap/.packaging/fedora/32/builddeps b/modules/dnstap/.packaging/fedora/32/builddeps
new file mode 100644
index 0000000..d3ab354
--- /dev/null
+++ b/modules/dnstap/.packaging/fedora/32/builddeps
@@ -0,0 +1,3 @@
+fstrm-devel
+protobuf-c-devel
+protobuf-c-compiler
diff --git a/modules/dnstap/.packaging/fedora/32/rundeps b/modules/dnstap/.packaging/fedora/32/rundeps
new file mode 100644
index 0000000..06c2792
--- /dev/null
+++ b/modules/dnstap/.packaging/fedora/32/rundeps
@@ -0,0 +1,2 @@
+fstrm
+protobuf-c
diff --git a/modules/dnstap/.packaging/leap/15.2/builddeps b/modules/dnstap/.packaging/leap/15.2/builddeps
new file mode 100644
index 0000000..30f8d9e
--- /dev/null
+++ b/modules/dnstap/.packaging/leap/15.2/builddeps
@@ -0,0 +1,3 @@
+fstrm-devel
+libprotobuf-c-devel
+protobuf-c
diff --git a/modules/dnstap/.packaging/leap/15.2/rundeps b/modules/dnstap/.packaging/leap/15.2/rundeps
new file mode 100644
index 0000000..06c2792
--- /dev/null
+++ b/modules/dnstap/.packaging/leap/15.2/rundeps
@@ -0,0 +1,2 @@
+fstrm
+protobuf-c
diff --git a/modules/dnstap/.packaging/test.config b/modules/dnstap/.packaging/test.config
new file mode 100644
index 0000000..5966860
--- /dev/null
+++ b/modules/dnstap/.packaging/test.config
@@ -0,0 +1,4 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+modules.load('dnstap')
+assert(dnstap)
+quit()
diff --git a/modules/dnstap/.packaging/ubuntu/16.04/builddeps b/modules/dnstap/.packaging/ubuntu/16.04/builddeps
new file mode 100644
index 0000000..417dc04
--- /dev/null
+++ b/modules/dnstap/.packaging/ubuntu/16.04/builddeps
@@ -0,0 +1,3 @@
+libfstrm-dev
+libprotobuf-c-dev
+protobuf-c-compiler
diff --git a/modules/dnstap/.packaging/ubuntu/16.04/rundeps b/modules/dnstap/.packaging/ubuntu/16.04/rundeps
new file mode 100644
index 0000000..a726e12
--- /dev/null
+++ b/modules/dnstap/.packaging/ubuntu/16.04/rundeps
@@ -0,0 +1,2 @@
+libfstrm0
+libprotobuf-c1
diff --git a/modules/dnstap/.packaging/ubuntu/18.04/builddeps b/modules/dnstap/.packaging/ubuntu/18.04/builddeps
new file mode 100644
index 0000000..417dc04
--- /dev/null
+++ b/modules/dnstap/.packaging/ubuntu/18.04/builddeps
@@ -0,0 +1,3 @@
+libfstrm-dev
+libprotobuf-c-dev
+protobuf-c-compiler
diff --git a/modules/dnstap/.packaging/ubuntu/18.04/rundeps b/modules/dnstap/.packaging/ubuntu/18.04/rundeps
new file mode 100644
index 0000000..a726e12
--- /dev/null
+++ b/modules/dnstap/.packaging/ubuntu/18.04/rundeps
@@ -0,0 +1,2 @@
+libfstrm0
+libprotobuf-c1
diff --git a/modules/dnstap/.packaging/ubuntu/20.04/builddeps b/modules/dnstap/.packaging/ubuntu/20.04/builddeps
new file mode 100644
index 0000000..417dc04
--- /dev/null
+++ b/modules/dnstap/.packaging/ubuntu/20.04/builddeps
@@ -0,0 +1,3 @@
+libfstrm-dev
+libprotobuf-c-dev
+protobuf-c-compiler
diff --git a/modules/dnstap/.packaging/ubuntu/20.04/rundeps b/modules/dnstap/.packaging/ubuntu/20.04/rundeps
new file mode 100644
index 0000000..a726e12
--- /dev/null
+++ b/modules/dnstap/.packaging/ubuntu/20.04/rundeps
@@ -0,0 +1,2 @@
+libfstrm0
+libprotobuf-c1
diff --git a/modules/dnstap/README.rst b/modules/dnstap/README.rst
new file mode 100644
index 0000000..456d218
--- /dev/null
+++ b/modules/dnstap/README.rst
@@ -0,0 +1,42 @@
+.. SPDX-License-Identifier: GPL-3.0-or-later
+
+.. _mod-dnstap:
+
+Dnstap (traffic collection)
+===========================
+
+The ``dnstap`` module supports logging DNS requests and responses to a unix
+socket in `dnstap format <https://dnstap.info>`_ using fstrm framing library.
+This logging is useful if you need effectively log all DNS traffic.
+
+The unix socket and the socket reader must be present before starting resolver instances.
+Also it needs appropriate filesystem permissions;
+the typical user and group of the daemon are called ``knot-resolver``.
+
+Tunables:
+
+* ``socket_path``: the unix socket file where dnstap messages will be sent
+* ``identity``: identity string as typically returned by an "NSID" (RFC 5001) query, empty by default
+* ``version``: version string of the resolver, defaulting to "Knot Resolver major.minor.patch"
+* ``client.log_queries``: if ``true`` queries from downstream in wire format will be logged
+* ``client.log_responses``: if ``true`` responses to downstream in wire format will be logged
+
+.. Very non-standard and it seems unlikely that others want to collect the RTT.
+.. * ``client.log_tcp_rtt``: if ``true`` and on Linux,
+ add "extra" field with "rtt=12345\n",
+ signifying kernel's current estimate of RTT micro-seconds for the non-UDP connection
+ (alongside every arrived DNS message).
+
+.. code-block:: lua
+
+ modules = {
+ dnstap = {
+ socket_path = "/tmp/dnstap.sock",
+ identity = nsid.name() or "",
+ version = "My Custom Knot Resolver " .. package_version(),
+ client = {
+ log_queries = true,
+ log_responses = true,
+ },
+ }
+ }
diff --git a/modules/dnstap/dnstap.c b/modules/dnstap/dnstap.c
new file mode 100644
index 0000000..7572667
--- /dev/null
+++ b/modules/dnstap/dnstap.c
@@ -0,0 +1,524 @@
+/*
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ * @file dnstap.c
+ * @brief dnstap based query logging support
+ *
+ */
+
+#include "lib/module.h"
+#include "modules/dnstap/dnstap.pb-c.h"
+
+#include "contrib/cleanup.h"
+#include "daemon/session.h"
+#include "daemon/worker.h"
+#include "lib/layer.h"
+#include "lib/resolve.h"
+
+#include <ccan/json/json.h>
+#include <fstrm.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <uv.h>
+
+#define DEBUG_MSG(fmt, ...) kr_log_debug(DNSTAP, fmt, ##__VA_ARGS__);
+#define ERROR_MSG(fmt, ...) kr_log_error(DNSTAP, fmt, ##__VA_ARGS__);
+#define CFG_SOCK_PATH "socket_path"
+#define CFG_IDENTITY_STRING "identity"
+#define CFG_VERSION_STRING "version"
+#define CFG_LOG_CLIENT_PKT "client"
+#define CFG_LOG_QR_PKT "log_queries"
+#define CFG_LOG_RESP_PKT "log_responses"
+#define CFG_LOG_TCP_RTT "log_tcp_rtt"
+#define DEFAULT_SOCK_PATH "/tmp/dnstap.sock"
+#define DNSTAP_CONTENT_TYPE "protobuf:dnstap.Dnstap"
+#define DNSTAP_INITIAL_BUF_SIZE 256
+
+#define auto_destroy_uopts __attribute__((cleanup(fstrm_unix_writer_options_destroy)))
+#define auto_destroy_wopts __attribute__((cleanup(fstrm_writer_options_destroy)))
+
+/*
+ * Internal processing phase
+ * Distinguishes whether query or response should be processed
+ */
+enum dnstap_log_phase {
+ CLIENT_QUERY_PHASE = 0,
+ CLIENT_RESPONSE_PHASE,
+};
+
+/* Internal data structure */
+struct dnstap_data {
+ char *identity;
+ size_t identity_len;
+ char *version;
+ size_t version_len;
+ bool log_qr_pkt;
+ bool log_resp_pkt;
+ bool log_tcp_rtt;
+ struct fstrm_iothr *iothread;
+ struct fstrm_iothr_queue *ioq;
+};
+
+/*
+ * dt_pack packs the dnstap message for transport
+ * https://gitlab.nic.cz/knot/knot-dns/blob/master/src/contrib/dnstap/dnstap.c#L24
+ * */
+uint8_t* dt_pack(const Dnstap__Dnstap *d, uint8_t **buf, size_t *sz)
+{
+ ProtobufCBufferSimple sbuf = { { NULL } };
+
+ sbuf.base.append = protobuf_c_buffer_simple_append;
+ sbuf.len = 0;
+ sbuf.alloced = DNSTAP_INITIAL_BUF_SIZE;
+ sbuf.data = malloc(sbuf.alloced);
+ if (sbuf.data == NULL) {
+ return NULL;
+ }
+ sbuf.must_free_data = true;
+
+ *sz = dnstap__dnstap__pack_to_buffer(d, (ProtobufCBuffer *) &sbuf);
+ *buf = sbuf.data;
+ return *buf;
+}
+
+/* set_address fills in address detail in dnstap_message
+ * https://gitlab.nic.cz/knot/knot-dns/blob/master/src/contrib/dnstap/message.c#L28
+ */
+static void set_address(const struct sockaddr *sockaddr,
+ ProtobufCBinaryData *addr,
+ protobuf_c_boolean *has_addr,
+ uint32_t *port,
+ protobuf_c_boolean *has_port) {
+ const char *saddr = kr_inaddr(sockaddr);
+ if (saddr == NULL) {
+ *has_addr = false;
+ *has_port = false;
+ return;
+ }
+
+ addr->data = (uint8_t *)(saddr);
+ addr->len = kr_inaddr_len(sockaddr);
+ *has_addr = true;
+ *port = kr_inaddr_port(sockaddr);
+ *has_port = true;
+}
+
+#ifndef HAS_TCP_INFO
+ /* TCP RTT: not portable; not sure where else it might work. */
+ #define HAS_TCP_INFO __linux__
+#endif
+#if HAS_TCP_INFO
+/** Fill a tcp_info or return kr_error(). */
+static int get_tcp_info(const struct kr_request *req, struct tcp_info *info)
+{
+ if(kr_fails_assert(req && info))
+ return kr_error(EINVAL);
+ if (!req->qsource.dst_addr || !req->qsource.flags.tcp) /* not TCP-based */
+ return -abs(ENOENT);
+ /* First obtain the file-descriptor. */
+ uv_handle_t *h = session_get_handle(worker_request_get_source_session(req));
+ uv_os_fd_t fd;
+ int ret = uv_fileno(h, &fd);
+ if (ret)
+ return kr_error(ret);
+
+ socklen_t tcp_info_length = sizeof(*info);
+ if (getsockopt(fd, SOL_TCP, TCP_INFO, info, &tcp_info_length))
+ return kr_error(errno);
+ return kr_ok();
+}
+#endif
+
+/* dnstap_log prepares dnstap message and sends it to fstrm
+ *
+ * Return codes are kr_error(E*) and unused for now.
+ */
+static int dnstap_log(kr_layer_t *ctx, enum dnstap_log_phase phase) {
+ const struct kr_request *req = ctx->req;
+ const struct kr_module *module = ctx->api->data;
+ const struct kr_rplan *rplan = &req->rplan;
+ const struct dnstap_data *dnstap_dt = module->data;
+
+ if (!req->qsource.addr) {
+ return kr_ok();
+ }
+
+ /* check if we have a valid iothread */
+ if (!dnstap_dt->iothread || !dnstap_dt->ioq) {
+ DEBUG_MSG("dnstap_dt->iothread or dnstap_dt->ioq is NULL\n");
+ return kr_error(EFAULT);
+ }
+
+ /* Create dnstap message */
+ Dnstap__Message m;
+ Dnstap__Dnstap dnstap = DNSTAP__DNSTAP__INIT;
+ dnstap.type = DNSTAP__DNSTAP__TYPE__MESSAGE;
+ dnstap.message = &m;
+
+ memset(&m, 0, sizeof(m));
+
+ m.base.descriptor = &dnstap__message__descriptor;
+
+ if (req->qsource.addr) {
+ set_address(req->qsource.addr,
+ &m.query_address,
+ &m.has_query_address,
+ &m.query_port,
+ &m.has_query_port);
+ }
+
+ if (req->qsource.dst_addr) {
+ if (req->qsource.flags.http) {
+ m.socket_protocol = DNSTAP__SOCKET_PROTOCOL__DOH;
+ } else if (req->qsource.flags.tls) {
+ m.socket_protocol = DNSTAP__SOCKET_PROTOCOL__DOT;
+ } else if (req->qsource.flags.tcp) {
+ m.socket_protocol = DNSTAP__SOCKET_PROTOCOL__TCP;
+ } else {
+ m.socket_protocol = DNSTAP__SOCKET_PROTOCOL__UDP;
+ }
+ m.has_socket_protocol = true;
+
+ set_address(req->qsource.dst_addr,
+ &m.response_address,
+ &m.has_response_address,
+ &m.response_port,
+ &m.has_response_port);
+ switch (req->qsource.dst_addr->sa_family) {
+ case AF_INET:
+ m.socket_family = DNSTAP__SOCKET_FAMILY__INET;
+ m.has_socket_family = true;
+ break;
+ case AF_INET6:
+ m.socket_family = DNSTAP__SOCKET_FAMILY__INET6;
+ m.has_socket_family = true;
+ break;
+ }
+ }
+
+ char dnstap_extra_buf[24];
+ if (phase == CLIENT_QUERY_PHASE) {
+ m.type = DNSTAP__MESSAGE__TYPE__CLIENT_QUERY;
+
+ if (dnstap_dt->log_qr_pkt) {
+ const knot_pkt_t *qpkt = req->qsource.packet;
+ m.has_query_message = qpkt != NULL;
+ if (qpkt != NULL) {
+ m.query_message.len = qpkt->size;
+ m.query_message.data = qpkt->wire;
+ }
+ }
+
+ /* set query time to the timestamp of the first kr_query */
+ if (rplan->initial) {
+ struct kr_query *first = rplan->initial;
+
+ m.query_time_sec = first->timestamp.tv_sec;
+ m.has_query_time_sec = true;
+ m.query_time_nsec = first->timestamp.tv_usec * 1000;
+ m.has_query_time_nsec = true;
+ }
+#if HAS_TCP_INFO
+ struct tcp_info ti = { 0 };
+ if (dnstap_dt->log_tcp_rtt && get_tcp_info(req, &ti) == kr_ok()) {
+ int len = snprintf(dnstap_extra_buf, sizeof(dnstap_extra_buf),
+ "rtt=%u\n", (unsigned)ti.tcpi_rtt);
+ if (len < sizeof(dnstap_extra_buf)) {
+ dnstap.extra.data = (uint8_t *)dnstap_extra_buf;
+ dnstap.extra.len = len;
+ dnstap.has_extra = true;
+ }
+ }
+#else
+ (void)dnstap_extra_buf;
+#endif
+ } else if (phase == CLIENT_RESPONSE_PHASE) {
+ m.type = DNSTAP__MESSAGE__TYPE__CLIENT_RESPONSE;
+
+ /* current time */
+ struct timeval now;
+ gettimeofday(&now, NULL);
+
+ if (dnstap_dt->log_resp_pkt) {
+ const knot_pkt_t *rpkt = req->answer;
+ m.has_response_message = rpkt != NULL;
+ if (rpkt != NULL) {
+ m.response_message.len = rpkt->size;
+ m.response_message.data = rpkt->wire;
+ }
+ }
+
+ /* Set response time to now */
+ m.response_time_sec = now.tv_sec;
+ m.has_response_time_sec = true;
+ m.response_time_nsec = now.tv_usec * 1000;
+ m.has_response_time_nsec = true;
+ }
+
+ if (dnstap_dt->identity) {
+ dnstap.identity.data = (uint8_t*)dnstap_dt->identity;
+ dnstap.identity.len = dnstap_dt->identity_len;
+ dnstap.has_identity = true;
+ }
+
+ if (dnstap_dt->version) {
+ dnstap.version.data = (uint8_t*)dnstap_dt->version;
+ dnstap.version.len = dnstap_dt->version_len;
+ dnstap.has_version = true;
+ }
+
+ /* Pack the message */
+ uint8_t *frame = NULL;
+ size_t size = 0;
+ dt_pack(&dnstap, &frame, &size);
+ if (!frame) {
+ return kr_error(ENOMEM);
+ }
+
+ /* Submit a request to send message to fstrm_iothr*/
+ fstrm_res res = fstrm_iothr_submit(dnstap_dt->iothread, dnstap_dt->ioq, frame, size,
+ fstrm_free_wrapper, NULL);
+ if (res != fstrm_res_success) {
+ DEBUG_MSG("Error submitting dnstap message to iothr\n");
+ free(frame);
+ return kr_error(EBUSY);
+ }
+
+ return kr_ok();
+}
+
+/* dnstap_log_query prepares dnstap CLIENT_QUERY message and sends it to fstrm */
+static int dnstap_log_query(kr_layer_t *ctx) {
+ dnstap_log(ctx, CLIENT_QUERY_PHASE);
+ return ctx->state;
+}
+
+/* dnstap_log_response prepares dnstap CLIENT_RESPONSE message and sends it to fstrm */
+static int dnstap_log_response(kr_layer_t *ctx) {
+ dnstap_log(ctx, CLIENT_RESPONSE_PHASE);
+ return ctx->state;
+}
+
+KR_EXPORT
+int dnstap_init(struct kr_module *module) {
+ static kr_layer_api_t layer = {
+ .begin = &dnstap_log_query,
+ .finish = &dnstap_log_response,
+ };
+ /* Store module reference */
+ layer.data = module;
+ module->layer = &layer;
+
+ /* allocated memory for internal data */
+ struct dnstap_data *data = calloc(1, sizeof(*data));
+ if (!data) {
+ return kr_error(ENOMEM);
+ }
+
+ /* save pointer to internal struct in module for future reference */
+ module->data = data;
+ return kr_ok();
+}
+
+/** Clear, i.e. get to state as after the first dnstap_init(). */
+static void dnstap_clear(struct kr_module *module) {
+ struct dnstap_data *data = module->data;
+ if (data) {
+ free(data->identity);
+ free(data->version);
+
+ fstrm_iothr_destroy(&data->iothread);
+ DEBUG_MSG("fstrm iothread destroyed\n");
+ }
+}
+
+KR_EXPORT
+int dnstap_deinit(struct kr_module *module) {
+ dnstap_clear(module);
+ free(module->data);
+ return kr_ok();
+}
+
+/* dnstap_unix_writer returns a unix fstream writer
+ * https://gitlab.nic.cz/knot/knot-dns/blob/master/src/knot/modules/dnstap.c#L159
+ */
+static struct fstrm_writer* dnstap_unix_writer(const char *path) {
+
+ auto_destroy_uopts struct fstrm_unix_writer_options *opt = fstrm_unix_writer_options_init();
+ if (!opt) {
+ return NULL;
+ }
+ fstrm_unix_writer_options_set_socket_path(opt, path);
+
+ auto_destroy_wopts struct fstrm_writer_options *wopt = fstrm_writer_options_init();
+ if (!wopt) {
+ fstrm_unix_writer_options_destroy(&opt);
+ return NULL;
+ }
+ fstrm_writer_options_add_content_type(wopt, DNSTAP_CONTENT_TYPE,
+ strlen(DNSTAP_CONTENT_TYPE));
+
+ struct fstrm_writer *writer = fstrm_unix_writer_init(opt, wopt);
+ fstrm_unix_writer_options_destroy(&opt);
+ fstrm_writer_options_destroy(&wopt);
+ if (!writer) {
+ return NULL;
+ }
+
+ fstrm_res res = fstrm_writer_open(writer);
+ if (res != fstrm_res_success) {
+ DEBUG_MSG("fstrm_writer_open returned %d\n", res);
+ fstrm_writer_destroy(&writer);
+ return NULL;
+ }
+
+ return writer;
+}
+
+/* find_string
+ * create a new string from json
+ * *var is set to pointer of new string
+ * node must of type JSON_STRING
+ * new string can be at most len bytes
+ */
+static int find_string(const JsonNode *node, char **val, size_t len) {
+ if (!node || !node->key)
+ return kr_error(EINVAL);
+ if (kr_fails_assert(node->tag == JSON_STRING))
+ return kr_error(EINVAL);
+ *val = strndup(node->string_, len);
+ if (kr_fails_assert(*val != NULL))
+ return kr_error(errno);
+ return kr_ok();
+}
+
+/* find_bool returns bool from json */
+static bool find_bool(const JsonNode *node) {
+ if (!node || !node->key)
+ return false;
+ if (kr_fails_assert(node->tag == JSON_BOOL))
+ return false;
+ return node->bool_;
+}
+
+/* parse config */
+KR_EXPORT
+int dnstap_config(struct kr_module *module, const char *conf) {
+ dnstap_clear(module);
+ if (!conf) return kr_ok(); /* loaded module without configuring */
+ struct dnstap_data *data = module->data;
+ auto_free char *sock_path = NULL;
+
+ /* Empty conf passed, set default */
+ if (strlen(conf) < 1) {
+ sock_path = strdup(DEFAULT_SOCK_PATH);
+ } else {
+
+ JsonNode *root_node = json_decode(conf);
+ if (!root_node) {
+ ERROR_MSG("error parsing json\n");
+ return kr_error(EINVAL);
+ }
+
+ JsonNode *node;
+ /* dnstapPath key */
+ node = json_find_member(root_node, CFG_SOCK_PATH);
+ if (!node || find_string(node, &sock_path, PATH_MAX) != kr_ok()) {
+ sock_path = strdup(DEFAULT_SOCK_PATH);
+ }
+
+ /* identity string key */
+ node = json_find_member(root_node, CFG_IDENTITY_STRING);
+ if (!node || find_string(node, &data->identity, KR_EDNS_PAYLOAD) != kr_ok()) {
+ data->identity = NULL;
+ data->identity_len = 0;
+ } else {
+ data->identity_len = strlen(data->identity);
+ }
+
+ /* version string key */
+ node = json_find_member(root_node, CFG_VERSION_STRING);
+ if (!node || find_string(node, &data->version, KR_EDNS_PAYLOAD) != kr_ok()) {
+ data->version = strdup("Knot Resolver " PACKAGE_VERSION);
+ if (data->version) {
+ data->version_len = strlen(data->version);
+ }
+ } else {
+ data->version_len = strlen(data->version);
+ }
+
+ node = json_find_member(root_node, CFG_LOG_CLIENT_PKT);
+ if (node) {
+ JsonNode *subnode;
+ /* logRespPkt key */
+ subnode = json_find_member(node, CFG_LOG_RESP_PKT);
+ if (subnode) {
+ data->log_resp_pkt = find_bool(subnode);
+ } else {
+ data->log_resp_pkt = false;
+ }
+
+ /* logQrPkt key */
+ subnode = json_find_member(node, CFG_LOG_QR_PKT);
+ if (subnode) {
+ data->log_qr_pkt = find_bool(subnode);
+ } else {
+ data->log_qr_pkt = false;
+ }
+
+ subnode = json_find_member(node, CFG_LOG_TCP_RTT);
+ if (subnode) {
+ data->log_tcp_rtt = find_bool(subnode);
+ } else {
+ data->log_tcp_rtt = false;
+ }
+ } else {
+ data->log_qr_pkt = false;
+ data->log_resp_pkt = false;
+ data->log_tcp_rtt = false;
+ }
+
+ /* clean up json, we don't need it no more */
+ json_delete(root_node);
+ }
+
+ DEBUG_MSG("opening sock file %s\n",sock_path);
+ struct fstrm_writer *writer = dnstap_unix_writer(sock_path);
+ if (!writer) {
+ ERROR_MSG("failed to open socket %s\n"
+ "Please ensure that it exists beforehand and has appropriate access permissions.\n",
+ sock_path);
+ return kr_error(EINVAL);
+ }
+
+ struct fstrm_iothr_options *opt = fstrm_iothr_options_init();
+ if (!opt) {
+ ERROR_MSG("can't init fstrm options\n");
+ fstrm_writer_destroy(&writer);
+ return kr_error(EINVAL);
+ }
+
+ /* Create the I/O thread. */
+ data->iothread = fstrm_iothr_init(opt, &writer);
+ fstrm_iothr_options_destroy(&opt);
+ if (!data->iothread) {
+ ERROR_MSG("can't init fstrm_iothr\n");
+ fstrm_writer_destroy(&writer);
+ return kr_error(ENOMEM);
+ }
+
+ /* Get fstrm thread handle
+ * We only have one input queue, hence idx=0
+ */
+ data->ioq = fstrm_iothr_get_input_queue_idx(data->iothread, 0);
+ if (!data->ioq) {
+ fstrm_iothr_destroy(&data->iothread);
+ ERROR_MSG("can't get fstrm queue\n");
+ return kr_error(EBUSY);
+ }
+
+ return kr_ok();
+}
+
+KR_MODULE_EXPORT(dnstap)
+
diff --git a/modules/dnstap/dnstap.proto b/modules/dnstap/dnstap.proto
new file mode 100644
index 0000000..f2b7273
--- /dev/null
+++ b/modules/dnstap/dnstap.proto
@@ -0,0 +1,273 @@
+// dnstap: flexible, structured event replication format for DNS software
+//
+// This file contains the protobuf schemas for the "dnstap" structured event
+// replication format for DNS software.
+
+// Written in 2013-2014 by Farsight Security, Inc.
+//
+// SPDX-License-Identifier: CC0-1.0
+
+syntax = "proto2";
+package dnstap;
+
+// "Dnstap": this is the top-level dnstap type, which is a "union" type that
+// contains other kinds of dnstap payloads, although currently only one type
+// of dnstap payload is defined.
+// See: https://developers.google.com/protocol-buffers/docs/techniques#union
+message Dnstap {
+ // DNS server identity.
+ // If enabled, this is the identity string of the DNS server which generated
+ // this message. Typically this would be the same string as returned by an
+ // "NSID" (RFC 5001) query.
+ optional bytes identity = 1;
+
+ // DNS server version.
+ // If enabled, this is the version string of the DNS server which generated
+ // this message. Typically this would be the same string as returned by a
+ // "version.bind" query.
+ optional bytes version = 2;
+
+ // Extra data for this payload.
+ // This field can be used for adding an arbitrary byte-string annotation to
+ // the payload. No encoding or interpretation is applied or enforced.
+ optional bytes extra = 3;
+
+ // Identifies which field below is filled in.
+ enum Type {
+ MESSAGE = 1;
+ }
+ required Type type = 15;
+
+ // One of the following will be filled in.
+ optional Message message = 14;
+}
+
+// SocketFamily: the network protocol family of a socket. This specifies how
+// to interpret "network address" fields.
+enum SocketFamily {
+ INET = 1; // IPv4 (RFC 791)
+ INET6 = 2; // IPv6 (RFC 2460)
+}
+
+// SocketProtocol: the protocol used to transport a DNS message.
+enum SocketProtocol {
+ UDP = 1; // DNS over UDP transport (RFC 1035 section 4.2.1)
+ TCP = 2; // DNS over TCP transport (RFC 1035 section 4.2.2)
+ DOT = 3; // DNS over TLS (RFC 7858)
+ DOH = 4; // DNS over HTTPS (RFC 8484)
+}
+
+// Message: a wire-format (RFC 1035 section 4) DNS message and associated
+// metadata. Applications generating "Message" payloads should follow
+// certain requirements based on the MessageType, see below.
+message Message {
+
+ // There are eight types of "Message" defined that correspond to the
+ // four arrows in the following diagram, slightly modified from RFC 1035
+ // section 2:
+
+ // +---------+ +----------+ +--------+
+ // | | query | | query | |
+ // | Stub |-SQ--------CQ->| Recursive|-RQ----AQ->| Auth. |
+ // | Resolver| | Server | | Name |
+ // | |<-SR--------CR-| |<-RR----AR-| Server |
+ // +---------+ response | | response | |
+ // +----------+ +--------+
+
+ // Each arrow has two Type values each, one for each "end" of each arrow,
+ // because these are considered to be distinct events. Each end of each
+ // arrow on the diagram above has been marked with a two-letter Type
+ // mnemonic. Clockwise from upper left, these mnemonic values are:
+ //
+ // SQ: STUB_QUERY
+ // CQ: CLIENT_QUERY
+ // RQ: RESOLVER_QUERY
+ // AQ: AUTH_QUERY
+ // AR: AUTH_RESPONSE
+ // RR: RESOLVER_RESPONSE
+ // CR: CLIENT_RESPONSE
+ // SR: STUB_RESPONSE
+
+ // Two additional types of "Message" have been defined for the
+ // "forwarding" case where an upstream DNS server is responsible for
+ // further recursion. These are not shown on the diagram above, but have
+ // the following mnemonic values:
+
+ // FQ: FORWARDER_QUERY
+ // FR: FORWARDER_RESPONSE
+
+ // The "Message" Type values are defined below.
+
+ enum Type {
+ // AUTH_QUERY is a DNS query message received from a resolver by an
+ // authoritative name server, from the perspective of the authoritative
+ // name server.
+ AUTH_QUERY = 1;
+
+ // AUTH_RESPONSE is a DNS response message sent from an authoritative
+ // name server to a resolver, from the perspective of the authoritative
+ // name server.
+ AUTH_RESPONSE = 2;
+
+ // RESOLVER_QUERY is a DNS query message sent from a resolver to an
+ // authoritative name server, from the perspective of the resolver.
+ // Resolvers typically clear the RD (recursion desired) bit when
+ // sending queries.
+ RESOLVER_QUERY = 3;
+
+ // RESOLVER_RESPONSE is a DNS response message received from an
+ // authoritative name server by a resolver, from the perspective of
+ // the resolver.
+ RESOLVER_RESPONSE = 4;
+
+ // CLIENT_QUERY is a DNS query message sent from a client to a DNS
+ // server which is expected to perform further recursion, from the
+ // perspective of the DNS server. The client may be a stub resolver or
+ // forwarder or some other type of software which typically sets the RD
+ // (recursion desired) bit when querying the DNS server. The DNS server
+ // may be a simple forwarding proxy or it may be a full recursive
+ // resolver.
+ CLIENT_QUERY = 5;
+
+ // CLIENT_RESPONSE is a DNS response message sent from a DNS server to
+ // a client, from the perspective of the DNS server. The DNS server
+ // typically sets the RA (recursion available) bit when responding.
+ CLIENT_RESPONSE = 6;
+
+ // FORWARDER_QUERY is a DNS query message sent from a downstream DNS
+ // server to an upstream DNS server which is expected to perform
+ // further recursion, from the perspective of the downstream DNS
+ // server.
+ FORWARDER_QUERY = 7;
+
+ // FORWARDER_RESPONSE is a DNS response message sent from an upstream
+ // DNS server performing recursion to a downstream DNS server, from the
+ // perspective of the downstream DNS server.
+ FORWARDER_RESPONSE = 8;
+
+ // STUB_QUERY is a DNS query message sent from a stub resolver to a DNS
+ // server, from the perspective of the stub resolver.
+ STUB_QUERY = 9;
+
+ // STUB_RESPONSE is a DNS response message sent from a DNS server to a
+ // stub resolver, from the perspective of the stub resolver.
+ STUB_RESPONSE = 10;
+
+ // TOOL_QUERY is a DNS query message sent from a DNS software tool to a
+ // DNS server, from the perspective of the tool.
+ TOOL_QUERY = 11;
+
+ // TOOL_RESPONSE is a DNS response message received by a DNS software
+ // tool from a DNS server, from the perspective of the tool.
+ TOOL_RESPONSE = 12;
+
+ // UPDATE_QUERY is a DNS update query message received from a resolver
+ // by an authoritative name server, from the perspective of the
+ // authoritative name server.
+ UPDATE_QUERY = 13;
+
+ // UPDATE_RESPONSE is a DNS update response message sent from an
+ // authoritative name server to a resolver, from the perspective of the
+ // authoritative name server.
+ UPDATE_RESPONSE = 14;
+ }
+
+ // One of the Type values described above.
+ required Type type = 1;
+
+ // One of the SocketFamily values described above.
+ optional SocketFamily socket_family = 2;
+
+ // One of the SocketProtocol values described above.
+ optional SocketProtocol socket_protocol = 3;
+
+ // The network address of the message initiator.
+ // For SocketFamily INET, this field is 4 octets (IPv4 address).
+ // For SocketFamily INET6, this field is 16 octets (IPv6 address).
+ optional bytes query_address = 4;
+
+ // The network address of the message responder.
+ // For SocketFamily INET, this field is 4 octets (IPv4 address).
+ // For SocketFamily INET6, this field is 16 octets (IPv6 address).
+ optional bytes response_address = 5;
+
+ // The transport port of the message initiator.
+ // This is a 16-bit UDP or TCP port number, depending on SocketProtocol.
+ optional uint32 query_port = 6;
+
+ // The transport port of the message responder.
+ // This is a 16-bit UDP or TCP port number, depending on SocketProtocol.
+ optional uint32 response_port = 7;
+
+ // The time at which the DNS query message was sent or received, depending
+ // on whether this is an AUTH_QUERY, RESOLVER_QUERY, or CLIENT_QUERY.
+ // This is the number of seconds since the UNIX epoch.
+ optional uint64 query_time_sec = 8;
+
+ // The time at which the DNS query message was sent or received.
+ // This is the seconds fraction, expressed as a count of nanoseconds.
+ optional fixed32 query_time_nsec = 9;
+
+ // The initiator's original wire-format DNS query message, verbatim.
+ optional bytes query_message = 10;
+
+ // The "zone" or "bailiwick" pertaining to the DNS query message.
+ // This is a wire-format DNS domain name.
+ optional bytes query_zone = 11;
+
+ // The time at which the DNS response message was sent or received,
+ // depending on whether this is an AUTH_RESPONSE, RESOLVER_RESPONSE, or
+ // CLIENT_RESPONSE.
+ // This is the number of seconds since the UNIX epoch.
+ optional uint64 response_time_sec = 12;
+
+ // The time at which the DNS response message was sent or received.
+ // This is the seconds fraction, expressed as a count of nanoseconds.
+ optional fixed32 response_time_nsec = 13;
+
+ // The responder's original wire-format DNS response message, verbatim.
+ optional bytes response_message = 14;
+}
+
+// All fields except for 'type' in the Message schema are optional.
+// It is recommended that at least the following fields be filled in for
+// particular types of Messages.
+
+// AUTH_QUERY:
+// socket_family, socket_protocol
+// query_address, query_port
+// query_message
+// query_time_sec, query_time_nsec
+
+// AUTH_RESPONSE:
+// socket_family, socket_protocol
+// query_address, query_port
+// query_time_sec, query_time_nsec
+// response_message
+// response_time_sec, response_time_nsec
+
+// RESOLVER_QUERY:
+// socket_family, socket_protocol
+// query_message
+// query_time_sec, query_time_nsec
+// query_zone
+// response_address, response_port
+
+// RESOLVER_RESPONSE:
+// socket_family, socket_protocol
+// query_time_sec, query_time_nsec
+// query_zone
+// response_address, response_port
+// response_message
+// response_time_sec, response_time_nsec
+
+// CLIENT_QUERY:
+// socket_family, socket_protocol
+// query_message
+// query_time_sec, query_time_nsec
+
+// CLIENT_RESPONSE:
+// socket_family, socket_protocol
+// query_time_sec, query_time_nsec
+// response_message
+// response_time_sec, response_time_nsec
diff --git a/modules/dnstap/meson.build b/modules/dnstap/meson.build
new file mode 100644
index 0000000..e8a94bf
--- /dev/null
+++ b/modules/dnstap/meson.build
@@ -0,0 +1,57 @@
+# C module: dnstap
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+dnstap_src = files([
+ 'dnstap.c',
+])
+
+## dnstap dependencies
+build_dnstap = false
+if get_option('dnstap') != 'disabled'
+ dnstap_required = get_option('dnstap') == 'enabled'
+ message('--- dnstap module dependencies ---')
+ libprotobuf_c = dependency('libprotobuf-c', version: '>=1', required: dnstap_required)
+ libfstrm = dependency('libfstrm', version: '>=0.2', required: dnstap_required)
+ protoc_c = find_program('protoc-c', required: dnstap_required)
+ message('----------------------------------')
+ if libprotobuf_c.found() and libfstrm.found() and protoc_c.found()
+ build_dnstap = true
+ endif
+endif
+
+
+if build_dnstap
+ c_src_lint += dnstap_src
+
+ # generate protobuf-c sources using protoc-c
+ dnstap_pb = custom_target(
+ 'dnstap_pb',
+ command: [
+ protoc_c,
+ '--c_out=' + meson.current_build_dir(),
+ '--proto_path', meson.current_source_dir(),
+ meson.current_source_dir() / 'dnstap.proto',
+ ],
+ input: [ 'dnstap.proto' ],
+ output: [
+ 'dnstap.pb-c.h',
+ 'dnstap.pb-c.c',
+ ],
+ )
+
+ # build dnstap module
+ dnstap_mod = shared_module(
+ 'dnstap',
+ dnstap_src,
+ dependencies: [
+ declare_dependency(sources: dnstap_pb),
+ libfstrm,
+ libprotobuf_c,
+ libknot,
+ ],
+ include_directories: mod_inc_dir,
+ name_prefix: '',
+ install: true,
+ install_dir: modules_dir,
+ )
+endif
diff --git a/modules/edns_keepalive/.packaging/test.config b/modules/edns_keepalive/.packaging/test.config
new file mode 100644
index 0000000..5c71c79
--- /dev/null
+++ b/modules/edns_keepalive/.packaging/test.config
@@ -0,0 +1,10 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+modules.load('edns_keepalive')
+
+for _,item in ipairs(modules.list()) do
+ if item == "edns_keepalive" then
+ os.exit(0)
+ end
+end
+
+os.exit(1)
diff --git a/modules/edns_keepalive/README.rst b/modules/edns_keepalive/README.rst
new file mode 100644
index 0000000..d8034d2
--- /dev/null
+++ b/modules/edns_keepalive/README.rst
@@ -0,0 +1,22 @@
+.. SPDX-License-Identifier: GPL-3.0-or-later
+
+.. _mod-edns_keepalive:
+
+EDNS keepalive
+==============
+
+The ``edns_keepalive`` module implements :rfc:`7828` for *clients*
+connecting to Knot Resolver via TCP and TLS.
+The module just allows clients to discover the connection timeout,
+client connections are always timed-out the same way *regardless*
+of clients sending the EDNS option.
+
+When connecting to servers, Knot Resolver does not send this EDNS option.
+It still attempts to reuse established connections intelligently.
+
+This module is loaded by default. For debugging purposes it can be
+unloaded using standard means:
+
+.. code-block:: lua
+
+ modules.unload('edns_keepalive')
diff --git a/modules/edns_keepalive/edns_keepalive.c b/modules/edns_keepalive/edns_keepalive.c
new file mode 100644
index 0000000..30d5df3
--- /dev/null
+++ b/modules/edns_keepalive/edns_keepalive.c
@@ -0,0 +1,61 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+/**
+ * @file edns_keepalive.c
+ * @brief Minimalistic EDNS keepalive implementation on server side.
+ * If keepalive option is present in query,
+ * always reply with constant timeout value.
+ *
+ */
+#include <libknot/packet/pkt.h>
+#include "daemon/worker.h"
+#include "lib/module.h"
+#include "lib/layer.h"
+
+static int edns_keepalive_finalize(kr_layer_t *ctx)
+{
+ struct kr_request *req = ctx->req;
+ knot_pkt_t *answer = req->answer;
+ const knot_rrset_t *src_opt = req->qsource.packet->opt_rr;
+ knot_rrset_t *answ_opt = answer->opt_rr;
+
+ const bool ka_want =
+ req->qsource.flags.tcp &&
+ src_opt != NULL &&
+ knot_edns_get_option(src_opt, KNOT_EDNS_OPTION_TCP_KEEPALIVE, NULL) &&
+ answ_opt != NULL;
+ if (!ka_want) {
+ return ctx->state;
+ }
+ const struct network *net = &the_worker->engine->net;
+ uint64_t timeout = net->tcp.in_idle_timeout / 100;
+ if (timeout > UINT16_MAX) {
+ timeout = UINT16_MAX;
+ }
+ knot_mm_t *pool = &answer->mm;
+ uint16_t ka_size = knot_edns_keepalive_size(timeout);
+ uint8_t ka_buf[ka_size];
+ int ret = knot_edns_keepalive_write(ka_buf, ka_size, timeout);
+ if (ret == KNOT_EOK) {
+ ret = knot_edns_add_option(answ_opt, KNOT_EDNS_OPTION_TCP_KEEPALIVE,
+ ka_size, ka_buf, pool);
+ }
+ if (ret != KNOT_EOK) {
+ ctx->state = KR_STATE_FAIL;
+ }
+ return ctx->state;
+}
+
+KR_EXPORT int edns_keepalive_init(struct kr_module *self)
+{
+ static const kr_layer_api_t layer = {
+ .answer_finalize = &edns_keepalive_finalize,
+ };
+ self->layer = &layer;
+ return kr_ok();
+}
+
+KR_MODULE_EXPORT(edns_keepalive)
+
diff --git a/modules/edns_keepalive/meson.build b/modules/edns_keepalive/meson.build
new file mode 100644
index 0000000..979452f
--- /dev/null
+++ b/modules/edns_keepalive/meson.build
@@ -0,0 +1,17 @@
+# C module: edns_keepalive
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+edns_keepalive_src = files([
+ 'edns_keepalive.c',
+])
+c_src_lint += edns_keepalive_src
+
+edns_keepalive_mod = shared_module(
+ 'edns_keepalive',
+ edns_keepalive_src,
+ dependencies: libknot,
+ include_directories: mod_inc_dir,
+ name_prefix: '',
+ install: true,
+ install_dir: modules_dir,
+)
diff --git a/modules/etcd/.packaging/centos/7/pre-test.sh b/modules/etcd/.packaging/centos/7/pre-test.sh
new file mode 100755
index 0000000..4df79d9
--- /dev/null
+++ b/modules/etcd/.packaging/centos/7/pre-test.sh
@@ -0,0 +1 @@
+luarocks install etcd --from=https://mah0x211.github.io/rocks/
diff --git a/modules/etcd/.packaging/centos/7/rundeps b/modules/etcd/.packaging/centos/7/rundeps
new file mode 100644
index 0000000..795a3c4
--- /dev/null
+++ b/modules/etcd/.packaging/centos/7/rundeps
@@ -0,0 +1,6 @@
+openssl-devel
+lua-devel
+luarocks
+git
+gcc
+make
diff --git a/modules/etcd/.packaging/centos/8/NOTSUPPORTED b/modules/etcd/.packaging/centos/8/NOTSUPPORTED
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/modules/etcd/.packaging/centos/8/NOTSUPPORTED
diff --git a/modules/etcd/.packaging/debian/10/pre-test.sh b/modules/etcd/.packaging/debian/10/pre-test.sh
new file mode 100755
index 0000000..20073dc
--- /dev/null
+++ b/modules/etcd/.packaging/debian/10/pre-test.sh
@@ -0,0 +1 @@
+luarocks --lua-version 5.1 install etcd --from=https://mah0x211.github.io/rocks/
diff --git a/modules/etcd/.packaging/debian/10/rundeps b/modules/etcd/.packaging/debian/10/rundeps
new file mode 100644
index 0000000..02d3fcf
--- /dev/null
+++ b/modules/etcd/.packaging/debian/10/rundeps
@@ -0,0 +1,4 @@
+libssl-dev
+luarocks
+git
+make
diff --git a/modules/etcd/.packaging/debian/9/pre-test.sh b/modules/etcd/.packaging/debian/9/pre-test.sh
new file mode 100755
index 0000000..4df79d9
--- /dev/null
+++ b/modules/etcd/.packaging/debian/9/pre-test.sh
@@ -0,0 +1 @@
+luarocks install etcd --from=https://mah0x211.github.io/rocks/
diff --git a/modules/etcd/.packaging/debian/9/rundeps b/modules/etcd/.packaging/debian/9/rundeps
new file mode 100644
index 0000000..02d3fcf
--- /dev/null
+++ b/modules/etcd/.packaging/debian/9/rundeps
@@ -0,0 +1,4 @@
+libssl-dev
+luarocks
+git
+make
diff --git a/modules/etcd/.packaging/fedora/31/NOTSUPPORTED b/modules/etcd/.packaging/fedora/31/NOTSUPPORTED
new file mode 100644
index 0000000..b912289
--- /dev/null
+++ b/modules/etcd/.packaging/fedora/31/NOTSUPPORTED
@@ -0,0 +1,16 @@
+Error installing etcd using luarocks:
+
+
+
+Missing dependencies for process 1.9.0-1:
+ luarocks-fetch-gitrec >= 0.2 (not installed)
+
+process 1.9.0-1 depends on luarocks-fetch-gitrec >= 0.2 (not installed)
+Installing https://luarocks.org/luarocks-fetch-gitrec-0.2-1.src.rock
+
+No existing manifest. Attempting to rebuild...
+luarocks-fetch-gitrec 0.2-1 is now installed in /root/.luarocks (license: MIT)
+
+
+Error: Unknown protocol gitrec
+
diff --git a/modules/etcd/.packaging/fedora/32/NOTSUPPORTED b/modules/etcd/.packaging/fedora/32/NOTSUPPORTED
new file mode 100644
index 0000000..b912289
--- /dev/null
+++ b/modules/etcd/.packaging/fedora/32/NOTSUPPORTED
@@ -0,0 +1,16 @@
+Error installing etcd using luarocks:
+
+
+
+Missing dependencies for process 1.9.0-1:
+ luarocks-fetch-gitrec >= 0.2 (not installed)
+
+process 1.9.0-1 depends on luarocks-fetch-gitrec >= 0.2 (not installed)
+Installing https://luarocks.org/luarocks-fetch-gitrec-0.2-1.src.rock
+
+No existing manifest. Attempting to rebuild...
+luarocks-fetch-gitrec 0.2-1 is now installed in /root/.luarocks (license: MIT)
+
+
+Error: Unknown protocol gitrec
+
diff --git a/modules/etcd/.packaging/leap/15.2/pre-test.sh b/modules/etcd/.packaging/leap/15.2/pre-test.sh
new file mode 100755
index 0000000..20073dc
--- /dev/null
+++ b/modules/etcd/.packaging/leap/15.2/pre-test.sh
@@ -0,0 +1 @@
+luarocks --lua-version 5.1 install etcd --from=https://mah0x211.github.io/rocks/
diff --git a/modules/etcd/.packaging/leap/15.2/rundeps b/modules/etcd/.packaging/leap/15.2/rundeps
new file mode 100644
index 0000000..e8df59b
--- /dev/null
+++ b/modules/etcd/.packaging/leap/15.2/rundeps
@@ -0,0 +1,6 @@
+libopenssl-devel
+lua51-devel
+lua51-luarocks
+git
+gcc
+make
diff --git a/modules/etcd/.packaging/test.config b/modules/etcd/.packaging/test.config
new file mode 100644
index 0000000..1cc7e5a
--- /dev/null
+++ b/modules/etcd/.packaging/test.config
@@ -0,0 +1,4 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+modules.load('etcd')
+assert(etcd)
+quit()
diff --git a/modules/etcd/.packaging/ubuntu/16.04/pre-test.sh b/modules/etcd/.packaging/ubuntu/16.04/pre-test.sh
new file mode 100755
index 0000000..4df79d9
--- /dev/null
+++ b/modules/etcd/.packaging/ubuntu/16.04/pre-test.sh
@@ -0,0 +1 @@
+luarocks install etcd --from=https://mah0x211.github.io/rocks/
diff --git a/modules/etcd/.packaging/ubuntu/16.04/rundeps b/modules/etcd/.packaging/ubuntu/16.04/rundeps
new file mode 100644
index 0000000..a355a9f
--- /dev/null
+++ b/modules/etcd/.packaging/ubuntu/16.04/rundeps
@@ -0,0 +1,3 @@
+libssl-dev
+luarocks
+git
diff --git a/modules/etcd/.packaging/ubuntu/18.04/pre-test.sh b/modules/etcd/.packaging/ubuntu/18.04/pre-test.sh
new file mode 100755
index 0000000..4df79d9
--- /dev/null
+++ b/modules/etcd/.packaging/ubuntu/18.04/pre-test.sh
@@ -0,0 +1 @@
+luarocks install etcd --from=https://mah0x211.github.io/rocks/
diff --git a/modules/etcd/.packaging/ubuntu/18.04/rundeps b/modules/etcd/.packaging/ubuntu/18.04/rundeps
new file mode 100644
index 0000000..a355a9f
--- /dev/null
+++ b/modules/etcd/.packaging/ubuntu/18.04/rundeps
@@ -0,0 +1,3 @@
+libssl-dev
+luarocks
+git
diff --git a/modules/etcd/.packaging/ubuntu/20.04/pre-test.sh b/modules/etcd/.packaging/ubuntu/20.04/pre-test.sh
new file mode 100755
index 0000000..20073dc
--- /dev/null
+++ b/modules/etcd/.packaging/ubuntu/20.04/pre-test.sh
@@ -0,0 +1 @@
+luarocks --lua-version 5.1 install etcd --from=https://mah0x211.github.io/rocks/
diff --git a/modules/etcd/.packaging/ubuntu/20.04/rundeps b/modules/etcd/.packaging/ubuntu/20.04/rundeps
new file mode 100644
index 0000000..02d3fcf
--- /dev/null
+++ b/modules/etcd/.packaging/ubuntu/20.04/rundeps
@@ -0,0 +1,4 @@
+libssl-dev
+luarocks
+git
+make
diff --git a/modules/etcd/README.rst b/modules/etcd/README.rst
new file mode 100644
index 0000000..0ffa781
--- /dev/null
+++ b/modules/etcd/README.rst
@@ -0,0 +1,46 @@
+.. SPDX-License-Identifier: GPL-3.0-or-later
+
+.. _mod-etcd:
+
+Etcd support
+------------
+
+The `etcd` module connects to `etcd <https://etcd.io/>`_ peers and watches
+for configuration changes. By default, the module watches the subtree under
+``/knot-resolver`` directory, but you can change this in the
+`etcd library configuration <https://github.com/mah0x211/lua-etcd#cli-err--etcdnew-optiontable->`_.
+
+The subtree structure corresponds to the configuration variables in the declarative style.
+
+.. code-block:: bash
+
+ $ etcdctl set /knot-resolver/net/127.0.0.1 53
+ $ etcdctl set /knot-resolver/cache/size 10000000
+
+Configures all listening nodes to following configuration:
+
+.. code-block:: lua
+
+ net = { '127.0.0.1' }
+ cache.size = 10000000
+
+Example configuration
+^^^^^^^^^^^^^^^^^^^^^
+
+.. code-block:: lua
+
+ modules.load('etcd')
+ etcd.config({
+ prefix = '/knot-resolver',
+ peer = 'http://127.0.0.1:7001'
+ })
+
+.. warning:: Work in progress!
+
+Dependencies
+^^^^^^^^^^^^
+
+* `lua-etcd <https://github.com/mah0x211/lua-etcd>`_ library available in LuaRocks
+
+ ``$ luarocks --lua-version 5.1 install etcd --from=https://mah0x211.github.io/rocks/``
+
diff --git a/modules/etcd/etcd.lua b/modules/etcd/etcd.lua
new file mode 100644
index 0000000..ab58024
--- /dev/null
+++ b/modules/etcd/etcd.lua
@@ -0,0 +1,56 @@
+--- @module etcd
+-- SPDX-License-Identifier: GPL-3.0-or-later
+local etcd = {}
+
+-- @function update subtree configuration
+local function update_subtree(tree)
+ if not tree then return end
+ for _, k in pairs(tree) do
+ if k.dir then
+ update_subtree(k.nodes)
+ else
+ local key,opt = k.key:gmatch('([^/]+)/([^/]+)$')()
+ if _G[key][opt] ~= k.value then
+ _G[key][opt] = k.value
+ end
+ end
+ end
+end
+
+-- @function reload whole configuration
+function etcd.reload()
+ local res, err = etcd.cli:readdir('/', true)
+ if err then
+ error(err)
+ end
+ update_subtree(res.body.node.nodes)
+end
+
+function etcd.init()
+ etcd.Etcd = require('etcd.luasocket')
+ etcd.defaults = { prefix = '/knot-resolver' }
+end
+
+function etcd.deinit()
+ if etcd.ev then event.cancel(etcd.ev) end
+end
+
+function etcd.config(conf)
+ local options = etcd.defaults
+ if type(conf) == 'table' then
+ for k,v in pairs(conf) do options[k] = v end
+ end
+ -- create connection
+ local cli, err = etcd.Etcd.new(options)
+ if err then
+ error(err)
+ end
+ etcd.cli = cli
+ -- schedule recurrent polling
+ -- @todo: the etcd has watch() API, but this requires
+ -- coroutines on socket operations
+ if etcd.ev then event.cancel(etcd.ev) end
+ etcd.ev = event.recurrent(5 * sec, etcd.reload)
+end
+
+return etcd
diff --git a/modules/experimental_dot_auth/.packaging/centos/7/rundeps b/modules/experimental_dot_auth/.packaging/centos/7/rundeps
new file mode 100644
index 0000000..36b83e1
--- /dev/null
+++ b/modules/experimental_dot_auth/.packaging/centos/7/rundeps
@@ -0,0 +1 @@
+lua-basexx
diff --git a/modules/experimental_dot_auth/.packaging/centos/8/rundeps b/modules/experimental_dot_auth/.packaging/centos/8/rundeps
new file mode 100644
index 0000000..984c7ce
--- /dev/null
+++ b/modules/experimental_dot_auth/.packaging/centos/8/rundeps
@@ -0,0 +1 @@
+lua5.1-basexx
diff --git a/modules/experimental_dot_auth/.packaging/debian/10/rundeps b/modules/experimental_dot_auth/.packaging/debian/10/rundeps
new file mode 100644
index 0000000..36b83e1
--- /dev/null
+++ b/modules/experimental_dot_auth/.packaging/debian/10/rundeps
@@ -0,0 +1 @@
+lua-basexx
diff --git a/modules/experimental_dot_auth/.packaging/debian/9/rundeps b/modules/experimental_dot_auth/.packaging/debian/9/rundeps
new file mode 100644
index 0000000..36b83e1
--- /dev/null
+++ b/modules/experimental_dot_auth/.packaging/debian/9/rundeps
@@ -0,0 +1 @@
+lua-basexx
diff --git a/modules/experimental_dot_auth/.packaging/fedora/31/rundeps b/modules/experimental_dot_auth/.packaging/fedora/31/rundeps
new file mode 100644
index 0000000..984c7ce
--- /dev/null
+++ b/modules/experimental_dot_auth/.packaging/fedora/31/rundeps
@@ -0,0 +1 @@
+lua5.1-basexx
diff --git a/modules/experimental_dot_auth/.packaging/fedora/32/rundeps b/modules/experimental_dot_auth/.packaging/fedora/32/rundeps
new file mode 100644
index 0000000..984c7ce
--- /dev/null
+++ b/modules/experimental_dot_auth/.packaging/fedora/32/rundeps
@@ -0,0 +1 @@
+lua5.1-basexx
diff --git a/modules/experimental_dot_auth/.packaging/leap/15.2/NOTSUPPORTED b/modules/experimental_dot_auth/.packaging/leap/15.2/NOTSUPPORTED
new file mode 100644
index 0000000..682eff0
--- /dev/null
+++ b/modules/experimental_dot_auth/.packaging/leap/15.2/NOTSUPPORTED
@@ -0,0 +1,6 @@
+
+ERROR:test_packaging:Installing https://luarocks.org/basexx-0.4.1-1.rockspec
+Error: Failed extracting v0.4.1.tar.gz
+
+Doesn't works on GitLab CI/CD, but works on localhost.
+gzip and tar packages are installed, all packages has same version as packages on localhost's docker container.
diff --git a/modules/experimental_dot_auth/.packaging/leap/15.2/pre-test.sh b/modules/experimental_dot_auth/.packaging/leap/15.2/pre-test.sh
new file mode 100755
index 0000000..df5d784
--- /dev/null
+++ b/modules/experimental_dot_auth/.packaging/leap/15.2/pre-test.sh
@@ -0,0 +1 @@
+luarocks --lua-version 5.1 install basexx --from=https://mah0x211.github.io/rocks/
diff --git a/modules/experimental_dot_auth/.packaging/leap/15.2/rundeps b/modules/experimental_dot_auth/.packaging/leap/15.2/rundeps
new file mode 100644
index 0000000..9e636d8
--- /dev/null
+++ b/modules/experimental_dot_auth/.packaging/leap/15.2/rundeps
@@ -0,0 +1,4 @@
+lua51-luarocks
+git
+tar
+gzip
diff --git a/modules/experimental_dot_auth/.packaging/test.config b/modules/experimental_dot_auth/.packaging/test.config
new file mode 100644
index 0000000..39e9aed
--- /dev/null
+++ b/modules/experimental_dot_auth/.packaging/test.config
@@ -0,0 +1,4 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+modules.load('experimental_dot_auth')
+assert(experimental_dot_auth)
+quit()
diff --git a/modules/experimental_dot_auth/.packaging/ubuntu/16.04/NOTSUPPORTED b/modules/experimental_dot_auth/.packaging/ubuntu/16.04/NOTSUPPORTED
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/modules/experimental_dot_auth/.packaging/ubuntu/16.04/NOTSUPPORTED
diff --git a/modules/experimental_dot_auth/.packaging/ubuntu/18.04/rundeps b/modules/experimental_dot_auth/.packaging/ubuntu/18.04/rundeps
new file mode 100644
index 0000000..36b83e1
--- /dev/null
+++ b/modules/experimental_dot_auth/.packaging/ubuntu/18.04/rundeps
@@ -0,0 +1 @@
+lua-basexx
diff --git a/modules/experimental_dot_auth/.packaging/ubuntu/20.04/rundeps b/modules/experimental_dot_auth/.packaging/ubuntu/20.04/rundeps
new file mode 100644
index 0000000..36b83e1
--- /dev/null
+++ b/modules/experimental_dot_auth/.packaging/ubuntu/20.04/rundeps
@@ -0,0 +1 @@
+lua-basexx
diff --git a/modules/experimental_dot_auth/README.rst b/modules/experimental_dot_auth/README.rst
new file mode 100644
index 0000000..a93f516
--- /dev/null
+++ b/modules/experimental_dot_auth/README.rst
@@ -0,0 +1,91 @@
+.. SPDX-License-Identifier: GPL-3.0-or-later
+
+.. _mod-experimental_dot_auth:
+
+Experimental DNS-over-TLS Auto-discovery
+========================================
+
+This experimental module provides automatic discovery of authoritative servers' supporting DNS-over-TLS.
+The module uses magic NS names to detect SPKI_ fingerprint which is very similar to `dnscurve`_ mechanism.
+
+.. warning:: This protocol and module is experimental and can be changed or removed at any time. Use at own risk, security properties were not analyzed!
+
+How it works
+------------
+
+The module will look for NS target names formatted as:
+``dot-{base32(sha256(SPKI))}....``
+
+For instance, Knot Resolver will detect NS names formatted like this
+
+.. code-block:: none
+
+ example.com NS dot-tpwxmgqdaurcqxqsckxvdq5sty3opxlgcbjj43kumdq62kpqr72a.example.com
+
+and automatically discover that example.com NS supports DoT with the base64-encoded SPKI digest of ``m+12GgMFIiheEhKvUcOynjbn3WYQUp5tVGDh7Snwj/Q=``
+and will associate it with the IPs of ``dot-tpwxmgqdaurcqxqsckxvdq5sty3opxlgcbjj43kumdq62kpqr72a.example.com``.
+
+In that example, the base32 encoded (no padding) version of the sha256 PIN is ``tpwxmgqdaurcqxqsckxvdq5sty3opxlgcbjj43kumdq62kpqr72a``, which when
+converted to base64 translates to ``m+12GgMFIiheEhKvUcOynjbn3WYQUp5tVGDh7Snwj/Q=``.
+
+Generating NS target names
+--------------------------
+
+To generate the NS target name, use the following command to generate the base32 encoded string of the SPKI fingerprint:
+
+.. code-block:: bash
+
+ openssl x509 -in /path/to/cert.pem -pubkey -noout | \
+ openssl pkey -pubin -outform der | \
+ openssl dgst -sha256 -binary | \
+ base32 | tr -d '=' | tr '[:upper:]' '[:lower:]'
+ tpwxmgqdaurcqxqsckxvdq5sty3opxlgcbjj43kumdq62kpqr72a
+
+Then add a target to your NS with: ``dot-${b32}.a.example.com``
+
+Finally, map ``dot-${b32}.a.example.com`` to the right set of IPs.
+
+.. code-block:: bash
+
+ ...
+ ...
+ ;; QUESTION SECTION:
+ ;example.com. IN NS
+
+ ;; AUTHORITY SECTION:
+ example.com. 3600 IN NS dot-tpwxmgqdaurcqxqsckxvdq5sty3opxlgcbjj43kumdq62kpqr72a.a.example.com.
+ example.com. 3600 IN NS dot-tpwxmgqdaurcqxqsckxvdq5sty3opxlgcbjj43kumdq62kpqr72a.b.example.com.
+
+ ;; ADDITIONAL SECTION:
+ dot-tpwxmgqdaurcqxqsckxvdq5sty3opxlgcbjj43kumdq62kpqr72a.a.example.com. 3600 IN A 192.0.2.1
+ dot-tpwxmgqdaurcqxqsckxvdq5sty3opxlgcbjj43kumdq62kpqr72a.b.example.com. 3600 IN AAAA 2001:DB8::1
+ ...
+ ...
+
+Example configuration
+---------------------
+
+To enable the module, add this snippet to your config:
+
+.. code-block:: lua
+
+ -- Start an experiment, use with caution
+ modules.load('experimental_dot_auth')
+
+This module requires standard ``basexx`` Lua library which is typically provided by ``lua-basexx`` package.
+
+Caveats
+-------
+
+The module relies on seeing the reply of the NS query and as such will not work
+if Knot Resolver uses data from its cache. You may need to delete the cache before starting ``kresd`` to work around this.
+
+The module also assumes that the NS query answer will return both the NS targets in the Authority section as well as the glue records in the Additional section.
+
+Dependencies
+------------
+
+* `lua-basexx <https://github.com/aiq/basexx>`_ available in LuaRocks
+
+.. _dnscurve: https://dnscurve.org/
+.. _SPKI: https://en.wikipedia.org/wiki/Simple_public-key_infrastructure
diff --git a/modules/experimental_dot_auth/experimental_dot_auth.lua b/modules/experimental_dot_auth/experimental_dot_auth.lua
new file mode 100644
index 0000000..08c5080
--- /dev/null
+++ b/modules/experimental_dot_auth/experimental_dot_auth.lua
@@ -0,0 +1,122 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+-- Module interface
+
+local ffi = require('ffi')
+local basexx = require('basexx')
+local C = ffi.C
+
+-- Export module interface
+local M = {}
+M.layer = {}
+local base32 = {}
+local str = {}
+local AF_INET = 2
+local AF_INET6 = 10
+local INET_ADDRSTRLEN = 16
+local INET6_ADDRSTRLEN = 46
+
+ffi.cdef[[
+/*
+ * Data structures
+ */
+typedef int socklen_t;
+ struct sockaddr_storage{
+ unsigned short int ss_family;
+ unsigned long int __ss_align;
+ char __ss_padding[128 - (2 *sizeof(unsigned long int))];
+ };
+ struct in_addr{
+ unsigned char s_addr[4];
+ };
+ struct in6_addr{
+ unsigned char s6_addr[16];
+ };
+ struct sockaddr_in{
+ short sin_family;
+ unsigned short sin_port;
+ struct in_addr sin_addr;
+ char sin_zero[8];
+ } __attribute__ ((__packed__));
+ struct sockaddr_in6{
+ unsigned short sin6_family;
+ unsigned short sin6_port;
+ unsigned int sin6_flowinfo;
+ struct in6_addr sin6_addr;
+ unsigned int sin6_scope_id;
+ };
+ typedef unsigned short sa_family_t;
+ struct sockaddr_un {
+ sa_family_t sun_family;
+ char sun_path[108];
+ };
+ const char *inet_ntop(
+ int af,
+ const void *cp,
+ char *buf,
+ socklen_t len);
+]]
+
+function base32.pad(b32)
+ local m = #b32 % 8
+ if m ~= 0 then
+ b32 = b32 .. string.rep("=", 8 - m)
+ end
+ return b32
+end
+
+function str.starts(String,Start)
+ return string.sub(String,1,string.len(Start))==Start
+end
+
+-- Handle DoT signalling NS domains.
+function M.layer.consume(state, _, pkt)
+ -- Only successful answers
+ if state == kres.FAIL then return state end
+ -- log_debug(ffi.C.LOG_GRP_DOTAUTH, "%s", pkt:tostring())
+ local authority = pkt:section(kres.section.AUTHORITY)
+ local additional = pkt:section(kres.section.ADDITIONAL)
+ for _, rr in ipairs(authority) do
+ --log_debug(ffi.C.LOG_GRP_DOTAUTH, "%d %s", rr.type, kres.dname2str(rr.rdata))
+ if rr.type == kres.type.NS then
+ local name = kres.dname2str(rr.rdata):upper()
+ -- log_debug(ffi.C.LOG_GRP_DOTAUTH, "NS %d", name:len())
+ if name:len() > 56 and str.starts(name, "DOT-") then
+ local k = basexx.to_base64(
+ basexx.from_base32(
+ base32.pad(string.sub(name, 5, string.find(name, '[.]') - 1))
+ )
+ )
+ for _, rr_add in ipairs(additional) do
+ if rr_add.type == kres.type.A or rr_add.type == kres.type.AAAA then
+ local name_add = kres.dname2str(rr_add.owner):upper()
+ if name == name_add then
+ local addrbuf
+ if rr_add.type == kres.type.A then
+ local ns_addr = ffi.new("struct sockaddr_in")
+ ns_addr.sin_family = AF_INET
+
+ ns_addr.sin_addr.s_addr = rr_add.rdata
+ addrbuf = ffi.new("char[?]", INET_ADDRSTRLEN)
+ C.inet_ntop(AF_INET, ns_addr.sin_addr, addrbuf, INET_ADDRSTRLEN)
+ else
+ local ns_addr = ffi.new("struct sockaddr_in6")
+ ns_addr.sin6_family = AF_INET6
+
+ ns_addr.sin6_addr.s6_addr = rr_add.rdata
+ addrbuf = ffi.new("char[?]", INET6_ADDRSTRLEN)
+ C.inet_ntop(AF_INET6, ns_addr.sin6_addr, addrbuf, INET6_ADDRSTRLEN)
+ end
+ net.tls_client(ffi.string(addrbuf).."@853", {k})
+ log_info(ffi.C.LOG_GRP_DOTAUTH, "Adding %s IP %s %s", name_add, ffi.string(addrbuf).."@853", k)
+ end
+ end
+ end
+ end
+ end
+ end
+
+ return state
+
+end
+
+return M
diff --git a/modules/experimental_dot_auth/meson.build b/modules/experimental_dot_auth/meson.build
new file mode 100644
index 0000000..e2e1edf
--- /dev/null
+++ b/modules/experimental_dot_auth/meson.build
@@ -0,0 +1,13 @@
+# LUA module: experimental_dot_auth
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+lua_mod_src += [
+ files('experimental_dot_auth.lua'),
+]
+
+# install static files
+install_subdir(
+ 'static',
+ strip_directory: true,
+ install_dir: modules_dir / 'http',
+)
diff --git a/modules/extended_error/extended_error.c b/modules/extended_error/extended_error.c
new file mode 100644
index 0000000..db0ed57
--- /dev/null
+++ b/modules/extended_error/extended_error.c
@@ -0,0 +1,47 @@
+#include <libknot/rrtype/opt.h>
+
+#include "lib/module.h"
+#include "daemon/engine.h"
+
+static int extended_error_finalize(kr_layer_t *ctx) {
+ struct kr_request *req = ctx->req;
+ const knot_rrset_t *src_opt = req->qsource.packet->opt_rr;
+ const struct kr_extended_error *ede = &req->extended_error;
+
+ if (ede->info_code == KNOT_EDNS_EDE_NONE /* no extended error */
+ || src_opt == NULL /* no EDNS in query */
+ || kr_fails_assert(ede->info_code >= 0 && ede->info_code < UINT16_MAX) /* info code out of range */
+ || kr_fails_assert(req->answer->opt_rr) /* sanity check - answer should have EDNS */
+ ) {
+ return ctx->state;
+ }
+
+ const uint16_t info_code = (uint16_t)ede->info_code;
+ const size_t extra_len = ede->extra_text ? strlen(ede->extra_text) : 0;
+ uint8_t buf[sizeof(info_code) + extra_len];
+ knot_wire_write_u16(buf, info_code);
+ if (extra_len)
+ memcpy(buf + sizeof(info_code), ede->extra_text, extra_len);
+
+ if (knot_edns_add_option(req->answer->opt_rr, KNOT_EDNS_OPTION_EDE,
+ sizeof(buf), buf, &req->pool) != KNOT_EOK) {
+ /* something went wrong and there is no way to salvage content of OPT RRset */
+ kr_log_req(req, 0, 0, EDE, "unable to add Extended Error option\n");
+ knot_rrset_clear(req->answer->opt_rr, &req->pool);
+ }
+
+ return ctx->state;
+}
+
+KR_EXPORT
+int extended_error_init(struct kr_module *module) {
+ static kr_layer_api_t layer = {
+ .answer_finalize = &extended_error_finalize,
+ };
+ layer.data = module;
+ module->layer = &layer;
+
+ return kr_ok();
+}
+
+KR_MODULE_EXPORT(extended_error)
diff --git a/modules/extended_error/meson.build b/modules/extended_error/meson.build
new file mode 100644
index 0000000..26e87b0
--- /dev/null
+++ b/modules/extended_error/meson.build
@@ -0,0 +1,20 @@
+# C module: extended_error
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+extended_error_src = files([
+ 'extended_error.c',
+])
+c_src_lint += extended_error_src
+
+extended_error_mod = shared_module(
+ 'extended_error',
+ extended_error_src,
+ dependencies: [
+ libknot,
+ luajit_inc,
+ ],
+ include_directories: mod_inc_dir,
+ name_prefix: '',
+ install: true,
+ install_dir: modules_dir,
+)
diff --git a/modules/graphite/.packaging/centos/7/rundeps b/modules/graphite/.packaging/centos/7/rundeps
new file mode 100644
index 0000000..3da806b
--- /dev/null
+++ b/modules/graphite/.packaging/centos/7/rundeps
@@ -0,0 +1 @@
+lua-cqueues
diff --git a/modules/graphite/.packaging/centos/8/rundeps b/modules/graphite/.packaging/centos/8/rundeps
new file mode 100644
index 0000000..182251d
--- /dev/null
+++ b/modules/graphite/.packaging/centos/8/rundeps
@@ -0,0 +1 @@
+lua5.1-cqueues
diff --git a/modules/graphite/.packaging/debian/10/rundeps b/modules/graphite/.packaging/debian/10/rundeps
new file mode 100644
index 0000000..3da806b
--- /dev/null
+++ b/modules/graphite/.packaging/debian/10/rundeps
@@ -0,0 +1 @@
+lua-cqueues
diff --git a/modules/graphite/.packaging/debian/9/rundeps b/modules/graphite/.packaging/debian/9/rundeps
new file mode 100644
index 0000000..3da806b
--- /dev/null
+++ b/modules/graphite/.packaging/debian/9/rundeps
@@ -0,0 +1 @@
+lua-cqueues
diff --git a/modules/graphite/.packaging/fedora/31/rundeps b/modules/graphite/.packaging/fedora/31/rundeps
new file mode 100644
index 0000000..182251d
--- /dev/null
+++ b/modules/graphite/.packaging/fedora/31/rundeps
@@ -0,0 +1 @@
+lua5.1-cqueues
diff --git a/modules/graphite/.packaging/fedora/32/rundeps b/modules/graphite/.packaging/fedora/32/rundeps
new file mode 100644
index 0000000..182251d
--- /dev/null
+++ b/modules/graphite/.packaging/fedora/32/rundeps
@@ -0,0 +1 @@
+lua5.1-cqueues
diff --git a/modules/graphite/.packaging/leap/15.2/NOTSUPPORTED b/modules/graphite/.packaging/leap/15.2/NOTSUPPORTED
new file mode 100644
index 0000000..b1ae77d
--- /dev/null
+++ b/modules/graphite/.packaging/leap/15.2/NOTSUPPORTED
@@ -0,0 +1,6 @@
+
+ERROR:test_packaging:Installing https://luarocks.org/cqueues-20190813.51-0.src.rock
+164 Error: Failed extracting rel-20190813.tar.gz
+
+Doesn't works on GitLab CI/CD, but works on localhost.
+gzip and tar packages are installed, all packages has same version as packages on localhost's docker container.
diff --git a/modules/graphite/.packaging/leap/15.2/pre-test.sh b/modules/graphite/.packaging/leap/15.2/pre-test.sh
new file mode 100755
index 0000000..9614066
--- /dev/null
+++ b/modules/graphite/.packaging/leap/15.2/pre-test.sh
@@ -0,0 +1 @@
+luarocks --lua-version 5.1 install cqueues --from=https://mah0x211.github.io/rocks/
diff --git a/modules/graphite/.packaging/leap/15.2/rundeps b/modules/graphite/.packaging/leap/15.2/rundeps
new file mode 100644
index 0000000..8323887
--- /dev/null
+++ b/modules/graphite/.packaging/leap/15.2/rundeps
@@ -0,0 +1,6 @@
+libopenssl-devel
+lua51-luarocks
+git
+tar
+gzip
+m4
diff --git a/modules/graphite/.packaging/test.config b/modules/graphite/.packaging/test.config
new file mode 100644
index 0000000..c23033b
--- /dev/null
+++ b/modules/graphite/.packaging/test.config
@@ -0,0 +1,4 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+modules.load('graphite')
+assert(graphite)
+quit()
diff --git a/modules/graphite/.packaging/ubuntu/16.04/rundeps b/modules/graphite/.packaging/ubuntu/16.04/rundeps
new file mode 100644
index 0000000..3da806b
--- /dev/null
+++ b/modules/graphite/.packaging/ubuntu/16.04/rundeps
@@ -0,0 +1 @@
+lua-cqueues
diff --git a/modules/graphite/.packaging/ubuntu/18.04/rundeps b/modules/graphite/.packaging/ubuntu/18.04/rundeps
new file mode 100644
index 0000000..3da806b
--- /dev/null
+++ b/modules/graphite/.packaging/ubuntu/18.04/rundeps
@@ -0,0 +1 @@
+lua-cqueues
diff --git a/modules/graphite/.packaging/ubuntu/20.04/rundeps b/modules/graphite/.packaging/ubuntu/20.04/rundeps
new file mode 100644
index 0000000..3da806b
--- /dev/null
+++ b/modules/graphite/.packaging/ubuntu/20.04/rundeps
@@ -0,0 +1 @@
+lua-cqueues
diff --git a/modules/graphite/README.rst b/modules/graphite/README.rst
new file mode 100644
index 0000000..2f86a6f
--- /dev/null
+++ b/modules/graphite/README.rst
@@ -0,0 +1,49 @@
+.. SPDX-License-Identifier: GPL-3.0-or-later
+
+.. _mod-graphite:
+
+Graphite/InfluxDB/Metronome
+---------------------------
+
+The ``graphite`` sends statistics over the Graphite_ protocol to either Graphite_, Metronome_, InfluxDB_ or any compatible storage. This allows powerful visualization over metrics collected by Knot Resolver.
+
+.. tip:: The Graphite server is challenging to get up and running, InfluxDB_ combined with Grafana_ are much easier, and provide richer set of options and available front-ends. Metronome_ by PowerDNS alternatively provides a mini-graphite server for much simpler setups.
+
+Example configuration:
+
+Only the ``host`` parameter is mandatory.
+
+By default the module uses UDP so it doesn't guarantee the delivery, set ``tcp = true`` to enable Graphite over TCP. If the TCP consumer goes down or the connection with Graphite is lost, resolver will periodically attempt to reconnect with it.
+
+.. code-block:: lua
+
+ modules = {
+ graphite = {
+ prefix = hostname() .. worker.id, -- optional metric prefix
+ host = '127.0.0.1', -- graphite server address
+ port = 2003, -- graphite server port
+ interval = 5 * sec, -- publish interval
+ tcp = false -- set to true if you want TCP mode
+ }
+ }
+
+The module supports sending data to multiple servers at once.
+
+.. code-block:: lua
+
+ modules = {
+ graphite = {
+ host = { '127.0.0.1', '1.2.3.4', '::1' },
+ }
+ }
+
+Dependencies
+^^^^^^^^^^^^
+
+* `lua cqueues <https://25thandclement.com/~william/projects/cqueues.html>`_ package.
+
+
+.. _Graphite: https://graphite.readthedocs.io/en/latest/feeding-carbon.html
+.. _InfluxDB: https://influxdb.com/
+.. _Metronome: https://github.com/ahuPowerDNS/metronome
+.. _Grafana: http://grafana.org/
diff --git a/modules/graphite/graphite.lua b/modules/graphite/graphite.lua
new file mode 100644
index 0000000..be2d7b2
--- /dev/null
+++ b/modules/graphite/graphite.lua
@@ -0,0 +1,146 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+-- Load dependent modules
+if not stats then modules.load('stats') end
+
+-- This is leader-only module
+local M = {}
+local ffi = require("ffi")
+local socket = require("cqueues.socket")
+local proto_txt = {
+ [socket.SOCK_DGRAM] = 'udp',
+ [socket.SOCK_STREAM] = 'tcp'
+}
+
+local function make_socket(host, port, stype)
+ local s, err, status
+ -- timeout before next interval begins (roughly)
+ local timeout_sec = (M.interval - 10) / sec
+
+ s = socket.connect({ host = host, port = port, type = stype })
+ s:setmode('bn', 'bn')
+ s:settimeout(timeout_sec)
+ status, err = pcall(s.connect, s, timeout_sec)
+ if status == true and err == nil then
+ err = 'connect timeout'
+ s:close()
+ status = false
+ end
+
+ if not status then
+ log_info(ffi.C.LOG_GRP_GRAPHITE, 'connecting: %s@%d %s reason: %s',
+ host, port, proto_txt[stype], err)
+ return status, err
+ end
+ return s
+end
+
+-- Create connected UDP socket
+local function make_udp(host, port)
+ return make_socket(host, port, socket.SOCK_DGRAM)
+end
+
+-- Create connected TCP socket
+local function make_tcp(host, port)
+ return make_socket(host, port, socket.SOCK_STREAM)
+end
+
+-- Send the metrics in a table to multiple Graphite consumers
+local function publish_table(metrics, prefix, now)
+ local s
+ for i in ipairs(M.cli) do
+ local host = M.info[i]
+
+ if M.cli[i] == -1 then
+ if host.tcp then
+ s = make_tcp(host.addr, host.port)
+ else
+ s = make_udp(host.addr, host.port)
+ end
+ if s then
+ M.cli[i] = s
+ end
+ end
+
+ if M.cli[i] ~= -1 then
+ for key,val in pairs(metrics) do
+ local msg = key..' '..val..' '..now..'\n'
+ if prefix then
+ msg = prefix..'.'..msg
+ end
+
+ local ok, err = pcall(M.cli[i].write, M.cli[i], msg)
+ if not ok then
+ local tcp = M.cli[i]['connect'] ~= nil
+ if tcp and host.seen + 2 * M.interval / 1000 <= now then
+ local sock_type = (host.tcp and socket.SOCK_STREAM)
+ or socket.SOCK_DGRAM
+ log_info(ffi.C.LOG_GRP_GRAPHITE, 'reconnecting: %s@%d %s reason: %s',
+ host.addr, host.port, proto_txt[sock_type], err)
+ s = make_tcp(host.addr, host.port)
+ if s then
+ M.cli[i] = s
+ host.seen = now
+ else
+ M.cli[i] = -1
+ break
+ end
+ end
+ end
+ end -- loop metrics
+ end
+ end -- loop M.cli
+end
+
+function M.init()
+ M.ev = nil
+ M.cli = {}
+ M.info = {}
+ M.interval = 5 * sec
+ M.prefix = string.format('kresd.%s.%s', hostname(), worker.id)
+ return 0
+end
+
+function M.deinit()
+ if M.ev then event.cancel(M.ev) end
+ return 0
+end
+
+-- @function Publish results to the Graphite server(s)
+function M.publish()
+ local now = os.time()
+ -- Publish built-in statistics
+ if not M.cli then error("no graphite server configured") end
+ publish_table(cache.stats(), M.prefix..'.cache', now)
+ publish_table(worker.stats(), M.prefix..'.worker', now)
+ -- Publish extended statistics if available
+ publish_table(stats.list(), M.prefix, now)
+ return 0
+end
+
+-- @function Make connection to Graphite server.
+function M.add_server(_, host, port, tcp)
+ table.insert(M.cli, -1)
+ table.insert(M.info, {addr = host, port = port, tcp = tcp, seen = 0})
+ return 0
+end
+
+function M.config(conf)
+ -- config defaults
+ if not conf then return 0 end
+ if not conf.port then conf.port = 2003 end
+ if conf.interval then M.interval = conf.interval end
+ if conf.prefix then M.prefix = conf.prefix end
+ if type(conf.host) == 'table' then
+ for _, val in pairs(conf.host) do
+ M:add_server(val, conf.port, conf.tcp)
+ end
+ else
+ M:add_server(conf.host, conf.port, conf.tcp)
+ end
+ -- start publishing stats
+ if M.ev then event.cancel(M.ev) end
+ M.ev = event.recurrent(M.interval, function() worker.coroutine(M.publish) end)
+ return 0
+end
+
+return M
diff --git a/modules/hints/.packaging/test.config b/modules/hints/.packaging/test.config
new file mode 100644
index 0000000..d89c7f0
--- /dev/null
+++ b/modules/hints/.packaging/test.config
@@ -0,0 +1,4 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+modules.load('hints')
+assert(hints)
+quit()
diff --git a/modules/hints/README.rst b/modules/hints/README.rst
new file mode 100644
index 0000000..97d24dd
--- /dev/null
+++ b/modules/hints/README.rst
@@ -0,0 +1,145 @@
+.. SPDX-License-Identifier: GPL-3.0-or-later
+
+.. _mod-hints:
+
+Static hints
+============
+
+This is a module providing static hints for forward records (A/AAAA) and reverse records (PTR).
+The records can be loaded from ``/etc/hosts``-like files and/or added directly.
+
+You can also use the module to change the root hints; they are used as a safety belt or if the root NS
+drops out of cache.
+
+.. tip::
+
+ For blocking large lists of domains please use :func:`policy.rpz`
+ instead of creating huge list of domains with IP address *0.0.0.0*.
+
+Examples
+--------
+
+.. code-block:: lua
+
+ -- Load hints after iterator (so hints take precedence before caches)
+ modules = { 'hints > iterate' }
+ -- Add a custom hosts file
+ hints.add_hosts('hosts.custom')
+ -- Override the root hints
+ hints.root({
+ ['j.root-servers.net.'] = { '2001:503:c27::2:30', '192.58.128.30' }
+ })
+ -- Add a custom hint
+ hints['foo.bar'] = '127.0.0.1'
+
+.. note::
+ The :ref:`policy <mod-policy>` module applies before hints,
+ so your hints might get surprisingly shadowed by even default policies.
+
+ That most often happens for :rfc:`6761#section-6` names, e.g.
+ ``localhost`` and ``test`` or with ``PTR`` records in private address ranges.
+ To unblock the required names, you may use an explicit :any:`policy.PASS` action.
+
+ .. code-block:: lua
+
+ policy.add(policy.suffix(policy.PASS, {todname('1.168.192.in-addr.arpa')}))
+
+ This ``.PASS`` workaround isn't ideal. To improve some cases,
+ we recommend to move these ``.PASS`` lines to the end of your rule list.
+ The point is that applying any :ref:`non-chain action <mod-policy-actions>`
+ (e.g. :ref:`forwarding actions <forwarding>` or ``.PASS`` itself)
+ stops processing *any* later policy rules for that request (including the default block-rules).
+ You probably don't want this ``.PASS`` to shadow any other rules you might have;
+ and on the other hand, if any other non-chain rule triggers,
+ additional ``.PASS`` would not change anything even if it were somehow force-executed.
+
+Properties
+----------
+
+.. function:: hints.config([path])
+
+ :param string path: path to hosts-like file, default: no file
+ :return: ``{ result: bool }``
+
+ Clear any configured hints, and optionally load a hosts-like file as in ``hints.add_hosts(path)``.
+ (Root hints are not touched.)
+
+.. function:: hints.add_hosts([path])
+
+ :param string path: path to hosts-like file, default: ``/etc/hosts``
+
+ Add hints from a host-like file.
+
+.. function:: hints.get(hostname)
+
+ :param string hostname: i.e. ``"localhost"``
+ :return: ``{ result: [address1, address2, ...] }``
+
+ Return list of address record matching given name.
+ If no hostname is specified, all hints are returned in the table format used by ``hints.root()``.
+
+.. function:: hints.set(pair)
+
+ :param string pair: ``hostname address`` i.e. ``"localhost 127.0.0.1"``
+ :return: ``{ result: bool }``
+
+ Add a hostname--address pair hint.
+
+ .. note::
+
+ If multiple addresses have been added for a name (in separate ``hints.set()`` commands),
+ all are returned in a forward query.
+ If multiple names have been added to an address, the last one defined is returned
+ in a corresponding PTR query.
+
+.. function:: hints.del(pair)
+
+ :param string pair: ``hostname address`` i.e. ``"localhost 127.0.0.1"``, or just ``hostname``
+ :return: ``{ result: bool }``
+
+ Remove a hostname - address pair hint. If address is omitted, all addresses for the given name are deleted.
+
+.. function:: hints.root_file(path)
+
+ Replace current root hints from a zonefile. If the path is omitted, the compiled-in path is used, i.e. the root hints are reset to the default.
+
+.. function:: hints.root(root_hints)
+
+ :param table root_hints: new set of root hints i.e. ``{['name'] = 'addr', ...}``
+ :return: ``{ ['a.root-servers.net.'] = { '1.2.3.4', '5.6.7.8', ...}, ... }``
+
+ Replace current root hints and return the current table of root hints.
+
+ .. tip:: If no parameters are passed, it only returns current root hints set without changing anything.
+
+ Example:
+
+ .. code-block:: lua
+
+ > hints.root({
+ ['l.root-servers.net.'] = '199.7.83.42',
+ ['m.root-servers.net.'] = '202.12.27.33'
+ })
+ [l.root-servers.net.] => {
+ [1] => 199.7.83.42
+ }
+ [m.root-servers.net.] => {
+ [1] => 202.12.27.33
+ }
+
+ .. tip:: A good rule of thumb is to select only a few fastest root hints. The server learns RTT and NS quality over time, and thus tries all servers available. You can help it by preselecting the candidates.
+
+.. function:: hints.use_nodata(toggle)
+
+ :param bool toggle: true if enabling NODATA synthesis, false if disabling
+ :return: ``{ result: bool }``
+
+ If set to true (the default), NODATA will be synthesised for matching hint name, but mismatching type (e.g. AAAA query when only A hint exists).
+
+.. function:: hints.ttl([new_ttl])
+
+ :param int new_ttl: new TTL to set (optional)
+ :return: the TTL setting
+
+ This function allows to read and write the TTL value used for records generated by the hints module.
+
diff --git a/modules/hints/hints.c b/modules/hints/hints.c
new file mode 100644
index 0000000..34c08b9
--- /dev/null
+++ b/modules/hints/hints.c
@@ -0,0 +1,677 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+/**
+ * @file hints.c
+ * @brief Constructed zone cut from the hosts-like file, see @zonecut.h
+ *
+ * The module provides an override for queried address records.
+ */
+
+#include <libknot/packet/pkt.h>
+#include <libknot/descriptor.h>
+#include <ccan/json/json.h>
+#include <ucw/mempool.h>
+#include <contrib/cleanup.h>
+#include <lauxlib.h>
+
+#include "daemon/engine.h"
+#include "lib/zonecut.h"
+#include "lib/module.h"
+#include "lib/layer.h"
+
+#include <inttypes.h>
+#include <math.h>
+
+/* Defaults */
+#define VERBOSE_MSG(qry, ...) kr_log_q(qry, HINT, __VA_ARGS__)
+#define ERR_MSG(...) kr_log_error(HINT, "[ ]" __VA_ARGS__)
+
+struct hints_data {
+ struct kr_zonecut hints;
+ struct kr_zonecut reverse_hints;
+ bool use_nodata; /**< See hint_use_nodata() description, exposed via lua. */
+ uint32_t ttl; /**< TTL used for the hints, exposed via lua. */
+};
+static const uint32_t HINTS_TTL_DEFAULT = 5;
+
+/** Useful for returning from module properties. */
+static char * bool2jsonstr(bool val)
+{
+ char *result = NULL;
+ if (-1 == asprintf(&result, "{ \"result\": %s }", val ? "true" : "false"))
+ result = NULL;
+ return result;
+}
+
+static int put_answer(knot_pkt_t *pkt, struct kr_query *qry, knot_rrset_t *rr, bool use_nodata)
+{
+ int ret = 0;
+ if (!knot_rrset_empty(rr) || use_nodata) {
+ /* Update packet question */
+ if (!knot_dname_is_equal(knot_pkt_qname(pkt), rr->owner)) {
+ kr_pkt_recycle(pkt);
+ knot_pkt_put_question(pkt, qry->sname, qry->sclass, qry->stype);
+ }
+ if (!knot_rrset_empty(rr)) {
+ /* Append to packet */
+ ret = knot_pkt_put_rotate(pkt, KNOT_COMPR_HINT_QNAME, rr,
+ qry->reorder, KNOT_PF_FREE);
+ } else {
+ /* Return empty answer if name exists, but type doesn't match */
+ knot_wire_set_aa(pkt->wire);
+ }
+ } else {
+ ret = kr_error(ENOENT);
+ }
+ /* Clear RR if failed */
+ if (ret != 0) {
+ knot_rrset_clear(rr, &pkt->mm);
+ }
+ return ret;
+}
+
+static int satisfy_reverse(/*const*/ struct hints_data *data,
+ knot_pkt_t *pkt, struct kr_query *qry)
+{
+ /* Find a matching name */
+ pack_t *addr_set = kr_zonecut_find(&data->reverse_hints, qry->sname);
+ if (!addr_set || addr_set->len == 0) {
+ return kr_error(ENOENT);
+ }
+ knot_dname_t *qname = knot_dname_copy(qry->sname, &pkt->mm);
+ knot_rrset_t rr;
+ knot_rrset_init(&rr, qname, KNOT_RRTYPE_PTR, KNOT_CLASS_IN, data->ttl);
+
+ /* Append address records from hints */
+ uint8_t *addr = pack_last(*addr_set);
+ if (addr != NULL) {
+ size_t len = pack_obj_len(addr);
+ void *addr_val = pack_obj_val(addr);
+ knot_rrset_add_rdata(&rr, addr_val, len, &pkt->mm);
+ }
+
+ return put_answer(pkt, qry, &rr, data->use_nodata);
+}
+
+static int satisfy_forward(/*const*/ struct hints_data *data,
+ knot_pkt_t *pkt, struct kr_query *qry)
+{
+ /* Find a matching name */
+ pack_t *addr_set = kr_zonecut_find(&data->hints, qry->sname);
+ if (!addr_set || addr_set->len == 0) {
+ return kr_error(ENOENT);
+ }
+ knot_dname_t *qname = knot_dname_copy(qry->sname, &pkt->mm);
+ knot_rrset_t rr;
+ knot_rrset_init(&rr, qname, qry->stype, qry->sclass, data->ttl);
+
+ size_t family_len;
+ switch (rr.type) {
+ case KNOT_RRTYPE_A:
+ family_len = sizeof(struct in_addr);
+ break;
+ case KNOT_RRTYPE_AAAA:
+ family_len = sizeof(struct in6_addr);
+ break;
+ default:
+ goto finish;
+ };
+
+ /* Append address records from hints */
+ uint8_t *addr = pack_head(*addr_set);
+ while (addr != pack_tail(*addr_set)) {
+ size_t len = pack_obj_len(addr);
+ void *addr_val = pack_obj_val(addr);
+ if (len == family_len) {
+ knot_rrset_add_rdata(&rr, addr_val, len, &pkt->mm);
+ }
+ addr = pack_obj_next(addr);
+ }
+finish:
+ return put_answer(pkt, qry, &rr, data->use_nodata);
+}
+
+static int query(kr_layer_t *ctx, knot_pkt_t *pkt)
+{
+ struct kr_query *qry = ctx->req->current_query;
+ if (!qry || (ctx->state & KR_STATE_FAIL)) {
+ return ctx->state;
+ }
+
+ struct kr_module *module = ctx->api->data;
+ struct hints_data *data = module->data;
+ if (!data) { /* No valid file. */
+ return ctx->state;
+ }
+ /* We can optimize for early return like this: */
+ if (!data->use_nodata && qry->stype != KNOT_RRTYPE_A
+ && qry->stype != KNOT_RRTYPE_AAAA && qry->stype != KNOT_RRTYPE_PTR) {
+ return ctx->state;
+ }
+ /* FIXME: putting directly into packet breaks ordering in case the hint
+ * is applied after a CNAME jump. */
+ if (knot_dname_in_bailiwick(qry->sname, (const uint8_t *)"\4arpa\0") >= 0) {
+ if (satisfy_reverse(data, pkt, qry) != 0)
+ return ctx->state;
+ } else {
+ if (satisfy_forward(data, pkt, qry) != 0)
+ return ctx->state;
+ }
+
+ VERBOSE_MSG(qry, "<= answered from hints\n");
+ qry->flags.DNSSEC_WANT = false; /* Never authenticated */
+ qry->flags.CACHED = true;
+ qry->flags.NO_MINIMIZE = true;
+ pkt->parsed = pkt->size;
+ knot_wire_set_qr(pkt->wire);
+ return KR_STATE_DONE;
+}
+
+static int parse_addr_str(union kr_sockaddr *sa, const char *addr)
+{
+ int family = strchr(addr, ':') ? AF_INET6 : AF_INET;
+ memset(sa, 0, sizeof(*sa));
+ sa->ip.sa_family = family;
+ char *addr_bytes = (/*const*/char *)kr_inaddr(&sa->ip);
+ if (inet_pton(family, addr, addr_bytes) != 1) {
+ return kr_error(EILSEQ);
+ }
+ return 0;
+}
+
+/** @warning _NOT_ thread-safe; returns a pointer to static data! */
+static const knot_dname_t * raw_addr2reverse(const uint8_t *raw_addr, int family)
+{
+ #define REV_MAXLEN (4*16 + 16 /* the suffix, terminator, etc. */)
+ char reverse_addr[REV_MAXLEN];
+ static knot_dname_t dname[REV_MAXLEN];
+ #undef REV_MAXLEN
+
+ if (family == AF_INET) {
+ snprintf(reverse_addr, sizeof(reverse_addr),
+ "%d.%d.%d.%d.in-addr.arpa.",
+ raw_addr[3], raw_addr[2], raw_addr[1], raw_addr[0]);
+ } else if (family == AF_INET6) {
+ char *ra_it = reverse_addr;
+ for (int i = 15; i >= 0; --i) {
+ ssize_t free_space = reverse_addr + sizeof(reverse_addr) - ra_it;
+ int written = snprintf(ra_it, free_space, "%x.%x.",
+ raw_addr[i] & 0x0f, raw_addr[i] >> 4);
+ if (kr_fails_assert(written < free_space))
+ return NULL;
+ ra_it += written;
+ }
+ ssize_t free_space = reverse_addr + sizeof(reverse_addr) - ra_it;
+ if (snprintf(ra_it, free_space, "ip6.arpa.") >= free_space) {
+ return NULL;
+ }
+ } else {
+ return NULL;
+ }
+
+ if (!knot_dname_from_str(dname, reverse_addr, sizeof(dname))) {
+ return NULL;
+ }
+ return dname;
+}
+
+static const knot_dname_t * addr2reverse(const char *addr)
+{
+ /* Parse address string */
+ union kr_sockaddr ia;
+ if (parse_addr_str(&ia, addr) != 0) {
+ return NULL;
+ }
+ return raw_addr2reverse((const /*sign*/uint8_t *)kr_inaddr(&ia.ip),
+ kr_inaddr_family(&ia.ip));
+}
+
+static int add_pair(struct kr_zonecut *hints, const char *name, const char *addr)
+{
+ /* Build key */
+ knot_dname_t key[KNOT_DNAME_MAXLEN];
+ if (!knot_dname_from_str(key, name, sizeof(key))) {
+ return kr_error(EINVAL);
+ }
+ knot_dname_to_lower(key);
+
+ union kr_sockaddr ia;
+ if (parse_addr_str(&ia, addr) != 0) {
+ return kr_error(EINVAL);
+ }
+
+ return kr_zonecut_add(hints, key, kr_inaddr(&ia.ip), kr_inaddr_len(&ia.ip));
+}
+
+static int add_reverse_pair(struct kr_zonecut *hints, const char *name, const char *addr)
+{
+ const knot_dname_t *key = addr2reverse(addr);
+
+ if (key == NULL) {
+ return kr_error(EINVAL);
+ }
+
+ knot_dname_t ptr_name[KNOT_DNAME_MAXLEN];
+ if (!knot_dname_from_str(ptr_name, name, sizeof(ptr_name))) {
+ return kr_error(EINVAL);
+ }
+
+ return kr_zonecut_add(hints, key, ptr_name, knot_dname_size(ptr_name));
+}
+
+/** For a given name, remove either one address or all of them (if == NULL).
+ *
+ * Also remove the corresponding reverse records.
+ */
+static int del_pair(struct hints_data *data, const char *name, const char *addr)
+{
+ /* Build key */
+ knot_dname_t key[KNOT_DNAME_MAXLEN];
+ if (!knot_dname_from_str(key, name, sizeof(key))) {
+ return kr_error(EINVAL);
+ }
+ int key_len = knot_dname_size(key);
+
+ if (addr) {
+ /* Remove the pair. */
+ union kr_sockaddr ia;
+ if (parse_addr_str(&ia, addr) != 0) {
+ return kr_error(EINVAL);
+ }
+
+ const knot_dname_t *reverse_key = addr2reverse(addr);
+ kr_zonecut_del(&data->reverse_hints, reverse_key, key, key_len);
+ return kr_zonecut_del(&data->hints, key,
+ kr_inaddr(&ia.ip), kr_inaddr_len(&ia.ip));
+ }
+ /* We're removing everything for the name;
+ * first find the name's pack */
+ pack_t *addr_set = kr_zonecut_find(&data->hints, key);
+ if (!addr_set || addr_set->len == 0) {
+ return kr_error(ENOENT);
+ }
+
+ /* Remove address records in hints from reverse_hints. */
+
+ for (uint8_t *a = pack_head(*addr_set); a != pack_tail(*addr_set);
+ a = pack_obj_next(a)) {
+ void *addr_val = pack_obj_val(a);
+ int family = pack_obj_len(a) == kr_family_len(AF_INET)
+ ? AF_INET : AF_INET6;
+ const knot_dname_t *reverse_key = raw_addr2reverse(addr_val, family);
+ if (reverse_key != NULL) {
+ kr_zonecut_del(&data->reverse_hints, reverse_key, key, key_len);
+ }
+ }
+
+ /* Remove the whole name. */
+ return kr_zonecut_del_all(&data->hints, key);
+}
+
+static int load_file(struct kr_module *module, const char *path)
+{
+ auto_fclose FILE *fp = fopen(path, "r");
+ if (fp == NULL) {
+ ERR_MSG("reading '%s' failed: %s\n", path, strerror(errno));
+ return kr_error(errno);
+ } else {
+ VERBOSE_MSG(NULL, "reading '%s'\n", path);
+ }
+
+ /* Load file to map */
+ struct hints_data *data = module->data;
+ size_t line_len_unused = 0;
+ size_t count = 0;
+ size_t line_count = 0;
+ auto_free char *line = NULL;
+ int ret = kr_ok();
+
+ while (getline(&line, &line_len_unused, fp) > 0) {
+ ++line_count;
+ /* Ingore #comments as described in man hosts.5 */
+ char *comm = strchr(line, '#');
+ if (comm) {
+ *comm = '\0';
+ }
+
+ char *saveptr = NULL;
+ const char *addr = strtok_r(line, " \t\n", &saveptr);
+ if (addr == NULL || strlen(addr) == 0) {
+ continue;
+ }
+ const char *canonical_name = strtok_r(NULL, " \t\n", &saveptr);
+ if (canonical_name == NULL) {
+ ret = -1;
+ goto error;
+ }
+ /* Since the last added PTR records takes preference,
+ * we add canonical name as the last one. */
+ const char *name_tok;
+ while ((name_tok = strtok_r(NULL, " \t\n", &saveptr)) != NULL) {
+ ret = add_pair(&data->hints, name_tok, addr);
+ if (!ret) {
+ ret = add_reverse_pair(&data->reverse_hints, name_tok, addr);
+ }
+ if (ret) {
+ ret = -1;
+ goto error;
+ }
+ count += 1;
+ }
+ ret = add_pair(&data->hints, canonical_name, addr);
+ if (!ret) {
+ ret = add_reverse_pair(&data->reverse_hints, canonical_name, addr);
+ }
+ if (ret) {
+ ret = -1;
+ goto error;
+ }
+ count += 1;
+ }
+error:
+ if (ret) {
+ ret = kr_error(ret);
+ ERR_MSG("%s:%zu: invalid syntax\n", path, line_count);
+ }
+ VERBOSE_MSG(NULL, "loaded %zu hints\n", count);
+ return ret;
+}
+
+static char* hint_add_hosts(void *env, struct kr_module *module, const char *args)
+{
+ if (!args)
+ args = "/etc/hosts";
+ int err = load_file(module, args);
+ return bool2jsonstr(err == kr_ok());
+}
+
+/**
+ * Set name => address hint.
+ *
+ * Input: { name, address }
+ * Output: { result: bool }
+ *
+ */
+static char* hint_set(void *env, struct kr_module *module, const char *args)
+{
+ struct hints_data *data = module->data;
+ if (!args)
+ return NULL;
+ auto_free char *args_copy = strdup(args);
+ if (!args_copy)
+ return NULL;
+
+ int ret = -1;
+ char *addr = strchr(args_copy, ' ');
+ if (addr) {
+ *addr = '\0';
+ ++addr;
+ ret = add_reverse_pair(&data->reverse_hints, args_copy, addr);
+ if (ret) {
+ del_pair(data, args_copy, addr);
+ } else {
+ ret = add_pair(&data->hints, args_copy, addr);
+ }
+ }
+
+ return bool2jsonstr(ret == 0);
+}
+
+static char* hint_del(void *env, struct kr_module *module, const char *args)
+{
+ struct hints_data *data = module->data;
+ if (!args)
+ return NULL;
+ auto_free char *args_copy = strdup(args);
+ if (!args_copy)
+ return NULL;
+
+ int ret = -1;
+ char *addr = strchr(args_copy, ' ');
+ if (addr) {
+ *addr = '\0';
+ ++addr;
+ }
+ ret = del_pair(data, args_copy, addr);
+
+ return bool2jsonstr(ret == 0);
+}
+
+/** @internal Pack address list into JSON array. */
+static JsonNode *pack_addrs(pack_t *pack)
+{
+ char buf[INET6_ADDRSTRLEN];
+ JsonNode *root = json_mkarray();
+ uint8_t *addr = pack_head(*pack);
+ while (addr != pack_tail(*pack)) {
+ size_t len = pack_obj_len(addr);
+ int family = len == sizeof(struct in_addr) ? AF_INET : AF_INET6;
+ if (!inet_ntop(family, pack_obj_val(addr), buf, sizeof(buf))) {
+ break;
+ }
+ json_append_element(root, json_mkstring(buf));
+ addr = pack_obj_next(addr);
+ }
+ return root;
+}
+
+static char* pack_hints(struct kr_zonecut *hints);
+/**
+ * Retrieve address hints, either for given name or for all names.
+ *
+ * Input: name
+ * Output: NULL or "{ address1, address2, ... }"
+ */
+static char* hint_get(void *env, struct kr_module *module, const char *args)
+{
+ struct kr_zonecut *hints = &((struct hints_data *) module->data)->hints;
+ if (kr_fails_assert(hints))
+ return NULL;
+
+ if (!args) {
+ return pack_hints(hints);
+ }
+
+ knot_dname_t key[KNOT_DNAME_MAXLEN];
+ pack_t *pack = NULL;
+ if (knot_dname_from_str(key, args, sizeof(key))) {
+ pack = kr_zonecut_find(hints, key);
+ }
+ if (!pack || pack->len == 0) {
+ return NULL;
+ }
+
+ char *result = NULL;
+ JsonNode *root = pack_addrs(pack);
+ if (root) {
+ result = json_encode(root);
+ json_delete(root);
+ }
+ return result;
+}
+
+/** @internal Pack all hints into serialized JSON. */
+static char* pack_hints(struct kr_zonecut *hints) {
+ char *result = NULL;
+ JsonNode *root_node = json_mkobject();
+ trie_it_t *it;
+ for (it = trie_it_begin(hints->nsset); !trie_it_finished(it); trie_it_next(it)) {
+ KR_DNAME_GET_STR(nsname_str, (const knot_dname_t *)trie_it_key(it, NULL));
+ JsonNode *addr_list = pack_addrs((pack_t *)*trie_it_val(it));
+ if (!addr_list) goto error;
+ json_append_member(root_node, nsname_str, addr_list);
+ }
+ result = json_encode(root_node);
+error:
+ trie_it_free(it);
+ json_delete(root_node);
+ return result;
+}
+
+static void unpack_hint(struct kr_zonecut *root_hints, JsonNode *table, const char *name)
+{
+ JsonNode *node = NULL;
+ json_foreach(node, table) {
+ switch(node->tag) {
+ case JSON_STRING: add_pair(root_hints, name ? name : node->key, node->string_); break;
+ case JSON_ARRAY: unpack_hint(root_hints, node, name ? name : node->key); break;
+ default: continue;
+ }
+ }
+}
+
+/**
+ * Get/set root hints set.
+ *
+ * Input: { name: [addr_list], ... }
+ * Output: current list
+ *
+ */
+static char* hint_root(void *env, struct kr_module *module, const char *args)
+{
+ struct engine *engine = env;
+ struct kr_context *ctx = &engine->resolver;
+ struct kr_zonecut *root_hints = &ctx->root_hints;
+ /* Replace root hints if parameter is set */
+ if (args && args[0] != '\0') {
+ JsonNode *root_node = json_decode(args);
+ kr_zonecut_set(root_hints, (const uint8_t *)"");
+ unpack_hint(root_hints, root_node, NULL);
+ json_delete(root_node);
+ }
+ /* Return current root hints */
+ return pack_hints(root_hints);
+}
+
+static char* hint_root_file(void *env, struct kr_module *module, const char *args)
+{
+ struct engine *engine = env;
+ struct kr_context *ctx = &engine->resolver;
+ const char *err_msg = engine_hint_root_file(ctx, args);
+ if (err_msg) {
+ luaL_error(engine->L, "error when opening '%s': %s", args, err_msg);
+ }
+ return strdup(err_msg ? err_msg : "");
+}
+
+static char* hint_use_nodata(void *env, struct kr_module *module, const char *args)
+{
+ struct hints_data *data = module->data;
+ if (!args) {
+ return NULL;
+ }
+
+ JsonNode *root_node = json_decode(args);
+ if (!root_node || root_node->tag != JSON_BOOL) {
+ json_delete(root_node);
+ return bool2jsonstr(false);
+ }
+
+ data->use_nodata = root_node->bool_;
+ json_delete(root_node);
+ return bool2jsonstr(true);
+}
+
+static char* hint_ttl(void *env, struct kr_module *module, const char *args)
+{
+ struct hints_data *data = module->data;
+
+ /* Do no change on nonsense TTL values (incl. suspicious floats). */
+ JsonNode *root_node = args ? json_decode(args) : NULL;
+ if (root_node && root_node->tag == JSON_NUMBER) {
+ double ttl_d = root_node->number_;
+ uint32_t ttl = (uint32_t)round(ttl_d);
+ if (ttl_d >= 0 && fabs(ttl_d - ttl) * 64 < 1) {
+ data->ttl = ttl;
+ }
+ }
+ json_delete(root_node);
+
+ /* Always return the current TTL setting. Plain number is valid JSON. */
+ char *result = NULL;
+ if (-1 == asprintf(&result, "%"PRIu32, data->ttl)) {
+ result = NULL;
+ }
+ return result;
+}
+
+/** Basic initialization: get a memory pool, etc. */
+KR_EXPORT
+int hints_init(struct kr_module *module)
+{
+ static kr_layer_api_t layer = {
+ .produce = &query,
+ };
+ /* Store module reference */
+ layer.data = module;
+ module->layer = &layer;
+
+ static const struct kr_prop props[] = {
+ { &hint_set, "set", "Set {name, address} hint.", },
+ { &hint_del, "del", "Delete one {name, address} hint or all addresses for the name.", },
+ { &hint_get, "get", "Retrieve hint for given name.", },
+ { &hint_ttl, "ttl", "Set/get TTL used for the hints.", },
+ { &hint_add_hosts, "add_hosts", "Load a file with hosts-like formatting and add contents into hints.", },
+ { &hint_root, "root", "Replace root hints set (empty value to return current list).", },
+ { &hint_root_file, "root_file", "Replace root hints set from a zonefile.", },
+ { &hint_use_nodata, "use_nodata", "Synthesise NODATA if name matches, but type doesn't. True by default.", },
+ { NULL, NULL, NULL }
+ };
+ module->props = props;
+
+ knot_mm_t *pool = mm_ctx_mempool2(MM_DEFAULT_BLKSIZE);
+ if (!pool) {
+ return kr_error(ENOMEM);
+ }
+ struct hints_data *data = mm_alloc(pool, sizeof(struct hints_data));
+ if (!data) {
+ mp_delete(pool->ctx);
+ return kr_error(ENOMEM);
+ }
+ kr_zonecut_init(&data->hints, (const uint8_t *)(""), pool);
+ kr_zonecut_init(&data->reverse_hints, (const uint8_t *)(""), pool);
+ data->use_nodata = true;
+ data->ttl = HINTS_TTL_DEFAULT;
+ module->data = data;
+
+ return kr_ok();
+}
+
+/** Release all resources. */
+KR_EXPORT
+int hints_deinit(struct kr_module *module)
+{
+ struct hints_data *data = module->data;
+ if (data) {
+ kr_zonecut_deinit(&data->hints);
+ kr_zonecut_deinit(&data->reverse_hints);
+ mp_delete(data->hints.pool->ctx);
+ module->data = NULL;
+ }
+ return kr_ok();
+}
+
+/** Drop all hints, and load a hosts file if any was specified.
+ *
+ * It seems slightly strange to drop all, but keep doing that for now.
+ */
+KR_EXPORT
+int hints_config(struct kr_module *module, const char *conf)
+{
+ hints_deinit(module);
+ int err = hints_init(module);
+ if (err != kr_ok()) {
+ return err;
+ }
+
+ if (conf && conf[0]) {
+ return load_file(module, conf);
+ }
+ return kr_ok();
+}
+
+KR_MODULE_EXPORT(hints)
+
+#undef VERBOSE_MSG
diff --git a/modules/hints/meson.build b/modules/hints/meson.build
new file mode 100644
index 0000000..0a0945c
--- /dev/null
+++ b/modules/hints/meson.build
@@ -0,0 +1,24 @@
+# C module: hints
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+hints_src = files([
+ 'hints.c',
+])
+c_src_lint += hints_src
+
+hints_mod = shared_module(
+ 'hints',
+ hints_src,
+ dependencies: [
+ libknot,
+ luajit_inc,
+ ],
+ include_directories: mod_inc_dir,
+ name_prefix: '',
+ install: true,
+ install_dir: modules_dir,
+)
+
+config_tests += [
+ ['hints', files('tests/hints.test.lua'), ['skip_asan']],
+]
diff --git a/modules/hints/tests/hints.test.hosts b/modules/hints/tests/hints.test.hosts
new file mode 100644
index 0000000..0111507
--- /dev/null
+++ b/modules/hints/tests/hints.test.hosts
@@ -0,0 +1 @@
+192.0.2.1 myname.lan # badname.lan and the rest of the comment
diff --git a/modules/hints/tests/hints.test.lua b/modules/hints/tests/hints.test.lua
new file mode 100644
index 0000000..b62e502
--- /dev/null
+++ b/modules/hints/tests/hints.test.lua
@@ -0,0 +1,64 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+local utils = require('test_utils')
+
+-- setup resolver
+modules = { 'hints > iterate' }
+
+-- test for default configuration
+local function test_default()
+ -- get loaded root hints and change names to lowercase
+ local hints_data = utils.table_keys_to_lower(hints.root())
+
+ -- root hints loaded from default location
+ -- check correct ip address of a.root-server.net
+ utils.contains(hints_data['a.root-servers.net.'], '198.41.0.4', 'has IP address for a.root-servers.net.')
+end
+
+-- test loading from config file
+local function test_custom()
+ -- load custom root hints file with fake ip address for a.root-server.net
+ local err_msg = hints.root_file('hints_test.zone')
+ same(err_msg, '', 'load root hints from file')
+
+ -- get loaded root hints and change names to lowercase
+ local hints_data = utils.table_keys_to_lower(hints.root())
+ isnt(hints_data['a.root-servers.net.'], nil, 'can retrieve root hints')
+
+ -- check loaded ip address of a.root-server.net
+ utils.not_contains(hints_data['a.root-servers.net.'], '198.41.0.4',
+ 'real IP address for a.root-servers.net. is replaced')
+ utils.contains(hints_data['a.root-servers.net.'], '10.0.0.1',
+ 'real IP address for a.root-servers.net. is correct')
+end
+
+-- test that setting an address hint works (TODO: and NXDOMAIN)
+local function test_nxdomain()
+ hints.config() -- clean start
+ hints.use_nodata(false)
+ hints.add_hosts('hints.test.hosts')
+ -- TODO: prefilling or some other way of getting NXDOMAIN (instead of SERVFAIL)
+ utils.check_answer('bad name gives NXDOMAIN',
+ 'badname.lan', kres.type.A, kres.rcode.SERVFAIL)
+ utils.check_answer('another type gives NXDOMAIN',
+ 'myname.lan', kres.type.AAAA, kres.rcode.SERVFAIL)
+ utils.check_answer('record itself is OK',
+ 'myname.lan', kres.type.A, kres.rcode.NOERROR)
+end
+
+-- test that NODATA is correctly generated
+local function test_nodata()
+ hints.config() -- clean start
+ hints.use_nodata(true) -- default ATM but let's not depend on that
+ hints['myname.lan'] = '2001:db8::1'
+ utils.check_answer('another type gives NODATA',
+ 'myname.lan', kres.type.MX, utils.NODATA)
+ utils.check_answer('record itself is OK',
+ 'myname.lan', kres.type.AAAA, kres.rcode.NOERROR)
+end
+
+return {
+ test_default,
+ test_custom,
+ test_nxdomain,
+ test_nodata,
+}
diff --git a/modules/hints/tests/hints_test.zone b/modules/hints/tests/hints_test.zone
new file mode 100644
index 0000000..c3252f8
--- /dev/null
+++ b/modules/hints/tests/hints_test.zone
@@ -0,0 +1,2 @@
+; SPDX-License-Identifier: GPL-3.0-or-later
+A.ROOT-SERVERS.NET. 3600000 A 10.0.0.1
diff --git a/modules/http/.packaging/centos/7/rundeps b/modules/http/.packaging/centos/7/rundeps
new file mode 100644
index 0000000..c557cb2
--- /dev/null
+++ b/modules/http/.packaging/centos/7/rundeps
@@ -0,0 +1 @@
+lua-http
diff --git a/modules/http/.packaging/centos/8/rundeps b/modules/http/.packaging/centos/8/rundeps
new file mode 100644
index 0000000..ed5aee1
--- /dev/null
+++ b/modules/http/.packaging/centos/8/rundeps
@@ -0,0 +1 @@
+lua5.1-http
diff --git a/modules/http/.packaging/debian/10/rundeps b/modules/http/.packaging/debian/10/rundeps
new file mode 100644
index 0000000..c557cb2
--- /dev/null
+++ b/modules/http/.packaging/debian/10/rundeps
@@ -0,0 +1 @@
+lua-http
diff --git a/modules/http/.packaging/debian/9/rundeps b/modules/http/.packaging/debian/9/rundeps
new file mode 100644
index 0000000..c557cb2
--- /dev/null
+++ b/modules/http/.packaging/debian/9/rundeps
@@ -0,0 +1 @@
+lua-http
diff --git a/modules/http/.packaging/fedora/31/rundeps b/modules/http/.packaging/fedora/31/rundeps
new file mode 100644
index 0000000..ed5aee1
--- /dev/null
+++ b/modules/http/.packaging/fedora/31/rundeps
@@ -0,0 +1 @@
+lua5.1-http
diff --git a/modules/http/.packaging/fedora/32/rundeps b/modules/http/.packaging/fedora/32/rundeps
new file mode 100644
index 0000000..ed5aee1
--- /dev/null
+++ b/modules/http/.packaging/fedora/32/rundeps
@@ -0,0 +1 @@
+lua5.1-http
diff --git a/modules/http/.packaging/leap/15.2/NOTSUPPORTED b/modules/http/.packaging/leap/15.2/NOTSUPPORTED
new file mode 100644
index 0000000..bb50260
--- /dev/null
+++ b/modules/http/.packaging/leap/15.2/NOTSUPPORTED
@@ -0,0 +1,5 @@
+
+https://github.com/wahern/luaossl/issues/175
+
+
+Doesn't work with libopenssl-devel 1.1.0i-lp151.1.1
diff --git a/modules/http/.packaging/leap/15.2/pre-test.sh b/modules/http/.packaging/leap/15.2/pre-test.sh
new file mode 100755
index 0000000..bb1e131
--- /dev/null
+++ b/modules/http/.packaging/leap/15.2/pre-test.sh
@@ -0,0 +1 @@
+luarocks --lua-version 5.1 install http --from=https://mah0x211.github.io/rocks/
diff --git a/modules/http/.packaging/leap/15.2/rundeps b/modules/http/.packaging/leap/15.2/rundeps
new file mode 100644
index 0000000..ab05188
--- /dev/null
+++ b/modules/http/.packaging/leap/15.2/rundeps
@@ -0,0 +1,7 @@
+libopenssl-devel
+lua51-devel
+lua51-luarocks
+git
+tar
+gzip
+m4
diff --git a/modules/http/.packaging/test.config b/modules/http/.packaging/test.config
new file mode 100644
index 0000000..cb5e5dd
--- /dev/null
+++ b/modules/http/.packaging/test.config
@@ -0,0 +1,4 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+modules.load('http')
+assert(http)
+quit()
diff --git a/modules/http/.packaging/ubuntu/16.04/NOTSUPPORTED b/modules/http/.packaging/ubuntu/16.04/NOTSUPPORTED
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/modules/http/.packaging/ubuntu/16.04/NOTSUPPORTED
diff --git a/modules/http/.packaging/ubuntu/18.04/rundeps b/modules/http/.packaging/ubuntu/18.04/rundeps
new file mode 100644
index 0000000..c557cb2
--- /dev/null
+++ b/modules/http/.packaging/ubuntu/18.04/rundeps
@@ -0,0 +1 @@
+lua-http
diff --git a/modules/http/.packaging/ubuntu/20.04/rundeps b/modules/http/.packaging/ubuntu/20.04/rundeps
new file mode 100644
index 0000000..c557cb2
--- /dev/null
+++ b/modules/http/.packaging/ubuntu/20.04/rundeps
@@ -0,0 +1 @@
+lua-http
diff --git a/modules/http/README.rst b/modules/http/README.rst
new file mode 100644
index 0000000..6d8a075
--- /dev/null
+++ b/modules/http/README.rst
@@ -0,0 +1,188 @@
+.. SPDX-License-Identifier: GPL-3.0-or-later
+
+.. _mod-http:
+
+Other HTTP services
+===================
+
+.. tip:: In most distributions, the ``http`` module is available from a
+ separate package ``knot-resolver-module-http``. The module isn't packaged
+ for openSUSE.
+
+This module does the heavy lifting to provide an HTTP and HTTP/2 enabled
+server which provides few built-in services and also allows other
+modules to export restful APIs and websocket streams.
+
+One example is statistics module that can stream live metrics on the website,
+or publish metrics on request for Prometheus scraper.
+
+By default this module provides two kinds of endpoints,
+and unlimited number of "used-defined kinds" can be added in configuration.
+
++--------------+---------------------------------------------------------------------------------+
+| **Kind** | **Explanation** |
++--------------+---------------------------------------------------------------------------------+
+| webmgmt | :ref:`built-in web management <mod-http-built-in-services>` APIs (includes DoH) |
++--------------+---------------------------------------------------------------------------------+
+| doh_legacy | :ref:`mod-http-doh` |
++--------------+---------------------------------------------------------------------------------+
+
+Each network address and port combination can be configured to expose
+one kind of endpoint. This is done using the same mechanisms as
+network configuration for plain DNS and DNS-over-TLS,
+see chapter :ref:`network-configuration` for more details.
+
+.. warning:: Management endpoint (``webmgmt``) must not be directly exposed
+ to untrusted parties. Use `reverse-proxy`_ like Apache_
+ or Nginx_ if you need to authenticate API clients
+ for the management API.
+
+By default all endpoints share the same configuration for TLS certificates etc.
+This can be changed using ``http.config()`` configuration call explained below.
+
+.. _mod-http-example:
+
+Example configuration
+---------------------
+
+This section shows how to configure HTTP module itself. For information how
+to configure HTTP server's IP addresses and ports please see chapter
+:ref:`network-configuration`.
+
+.. code-block:: lua
+
+ -- load HTTP module with defaults (self-signed TLS cert)
+ modules.load('http')
+ -- optionally load geoIP database for server map
+ http.config({
+ geoip = 'GeoLite2-City.mmdb',
+ -- e.g. https://dev.maxmind.com/geoip/geoip2/geolite2/
+ -- and install mmdblua library
+ })
+
+Now you can reach the web services and APIs, done!
+
+.. code-block:: bash
+
+ $ curl -k https://localhost:8453
+ $ curl -k https://localhost:8453/stats
+
+.. _mod-http-tls:
+
+HTTPS (TLS for HTTP)
+--------------------
+
+By default, the web interface starts HTTPS/2 on specified port using an ephemeral
+TLS certificate that is valid for 90 days and is automatically renewed. It is of
+course self-signed. Why not use something like
+`Let's Encrypt <https://letsencrypt.org>`_?
+
+.. warning::
+
+ If you use package ``luaossl < 20181207``, intermediate certificate is not sent to clients,
+ which may cause problems with validating the connection in some cases.
+
+You can disable unencrypted HTTP and enforce HTTPS by passing
+``tls = true`` option for all HTTP endpoints:
+
+.. code-block:: lua
+
+ http.config({
+ tls = true,
+ })
+
+It is also possible to provide different configuration for each
+kind of endpoint, e.g. to enforce TLS and use custom certificate only for DoH:
+
+.. code-block:: lua
+
+ http.config({
+ tls = true,
+ cert = '/etc/knot-resolver/mycert.crt',
+ key = '/etc/knot-resolver/mykey.key',
+ }, 'doh_legacy')
+
+The format of both certificate and key is expected to be PEM, e.g. equivalent to
+the outputs of following:
+
+.. code-block:: bash
+
+ openssl ecparam -genkey -name prime256v1 -out mykey.key
+ openssl req -new -key mykey.key -out csr.pem
+ openssl req -x509 -days 90 -key mykey.key -in csr.pem -out mycert.crt
+
+It is also possible to disable HTTPS altogether by passing ``tls = false`` option.
+Plain HTTP gets handy if you want to use `reverse-proxy`_ like Apache_ or Nginx_
+for authentication to API etc.
+(Unencrypted HTTP could be fine for localhost tests as, for example,
+Safari doesn't allow WebSockets over HTTPS with a self-signed certificate.
+Major drawback is that current browsers won't do HTTP/2 over insecure connection.)
+
+.. warning::
+
+ If you use multiple Knot Resolver instances with these automatically maintained ephemeral certificates,
+ they currently won't be shared.
+ It's assumed that you don't want a self-signed certificate for serious deployments anyway.
+
+.. _mod-http-doh:
+
+Legacy DNS-over-HTTPS (DoH)
+---------------------------
+
+.. warning:: The legacy DoH implementation using ``http`` module (``kind='doh_legacy'``)
+ is deprecated. It has known performance and stability issues that won't be fixed.
+ Use new :ref:`dns-over-https` implementation instead.
+
+This was an experimental implementation of :rfc:`8484`. It can be configured using
+``doh_legacy`` kind in :func:`net.listen`. Its configuration (such as certificates)
+takes place in ``http.config()``.
+
+Queries were served on ``/doh`` and ``/dns-query`` endpoints.
+
+.. _mod-http-built-in-services:
+
+Built-in services
+-----------------
+
+The HTTP module has several built-in services to use.
+
+.. csv-table::
+ :header: "Endpoint", "Service", "Description"
+
+ "``/stats``", "Statistics/metrics", "Exported :ref:`metrics <mod-stats-list>` from :ref:`mod-stats` in JSON format."
+ "``/metrics``", "Prometheus metrics", "Exported metrics for Prometheus_."
+ "``/trace/:name/:type``", "Tracking", ":ref:`Trace resolution <mod-http-trace>` of a DNS query and return its debug-level logs."
+ "``/doh``", "Legacy DNS-over-HTTPS", ":rfc:`8484` endpoint, see :ref:`mod-http-doh`."
+ "``/dns-query``", "Legacy DNS-over-HTTPS", ":rfc:`8484` endpoint, see :ref:`mod-http-doh`."
+
+Dependencies
+------------
+
+* `lua-http <https://github.com/daurnimator/lua-http>`_ (>= 0.3) available in LuaRocks
+
+ If you're installing via Homebrew on OS X, you need OpenSSL too.
+
+ .. code-block:: bash
+
+ $ brew update
+ $ brew install openssl
+ $ brew link openssl --force # Override system OpenSSL
+
+ Some other systems can install from LuaRocks directly:
+
+ .. code-block:: bash
+
+ $ luarocks --lua-version 5.1 install http
+
+* (*optional*) `mmdblua <https://github.com/daurnimator/mmdblua>`_ available in LuaRocks
+
+ .. code-block:: bash
+
+ $ luarocks --lua-version 5.1 install --server=https://luarocks.org/dev mmdblua
+ $ curl -O https://geolite.maxmind.com/download/geoip/database/GeoLite2-City.mmdb.gz
+ $ gzip -d GeoLite2-City.mmdb.gz
+
+.. _Prometheus: https://prometheus.io
+.. _reverse-proxy: https://en.wikipedia.org/wiki/Reverse_proxy
+.. _Apache: https://httpd.apache.org/docs/2.4/howto/reverse_proxy.html
+.. _Nginx: https://docs.nginx.com/nginx/admin-guide/web-server/reverse-proxy/
diff --git a/modules/http/custom_services.rst b/modules/http/custom_services.rst
new file mode 100644
index 0000000..09ba5ab
--- /dev/null
+++ b/modules/http/custom_services.rst
@@ -0,0 +1,145 @@
+.. SPDX-License-Identifier: GPL-3.0-or-later
+
+.. _mod-http-custom-endpoint:
+
+Custom HTTP services
+====================
+
+This chapter describes how to create custom HTTP services inside Knot Resolver.
+Please read HTTP module basics in chapter :ref:`mod-http` before continuing.
+
+Each network address+protocol+port combination configured using :func:`net.listen`
+is associated with *kind* of endpoint, e.g. ``doh_legacy`` or ``webmgmt``.
+
+Each of these *kind* names is associated with table of HTTP endpoints,
+and the default table can be replaced using ``http.config()`` configuration call
+which allows your to provide your own HTTP endpoints.
+
+Items in the table of HTTP endpoints are small tables describing a triplet
+- ``{mime, on_serve, on_websocket}``.
+In order to register a new service in ``webmgmt`` *kind* of HTTP endpoint
+add the new endpoint description to respective table:
+
+.. code-block:: lua
+
+ -- custom function to handle HTTP /health requests
+ local on_health = {'application/json',
+ function (h, stream)
+ -- API call, return a JSON table
+ return {state = 'up', uptime = 0}
+ end,
+ function (h, ws)
+ -- Stream current status every second
+ local ok = true
+ while ok do
+ local push = tojson('up')
+ ok = ws:send(tojson({'up'}))
+ require('cqueues').sleep(1)
+ end
+ -- Finalize the WebSocket
+ ws:close()
+ end}
+
+ modules.load('http')
+ -- copy all existing webmgmt endpoints
+ my_mgmt_endpoints = http.configs._builtin.webmgmt.endpoints
+ -- add custom endpoint to the copy
+ my_mgmt_endpoints['/health'] = on_health
+ -- use custom HTTP configuration for webmgmt
+ http.config({
+ endpoints = my_mgmt_endpoints
+ }, 'webmgmt')
+
+Then you can query the API endpoint, or tail the WebSocket using curl.
+
+.. code-block:: bash
+
+ $ curl -k https://localhost:8453/health
+ {"state":"up","uptime":0}
+ $ curl -k -i -N -H "Connection: Upgrade" -H "Upgrade: websocket" -H "Host: localhost:8453/health" -H "Sec-Websocket-Key: nope" -H "Sec-Websocket-Version: 13" https://localhost:8453/health
+ HTTP/1.1 101 Switching Protocols
+ upgrade: websocket
+ sec-websocket-accept: eg18mwU7CDRGUF1Q+EJwPM335eM=
+ connection: upgrade
+
+ ?["up"]?["up"]?["up"]
+
+Since the stream handlers are effectively coroutines, you are free to keep state
+and yield using `cqueues library <http://www.25thandclement.com/~william/projects/cqueues.html>`_.
+
+This is especially useful for WebSockets, as you can stream content in a simple loop instead of
+chains of callbacks.
+
+Last thing you can publish from modules are *"snippets"*. Snippets are plain pieces of HTML code
+that are rendered at the end of the built-in webpage. The snippets can be extended with JS code to talk to already
+exported restful APIs and subscribe to WebSockets.
+
+.. code-block:: lua
+
+ http.snippets['/health'] = {'Health service', '<p>UP!</p>'}
+
+Custom RESTful services
+-----------------------
+
+A RESTful service is likely to respond differently to different type of methods and requests,
+there are three things that you can do in a service handler to send back results.
+First is to just send whatever you want to send back, it has to respect MIME type that the service
+declared in the endpoint definition. The response code would then be ``200 OK``, any non-string
+responses will be packed to JSON. Alternatively, you can respond with a number corresponding to
+the HTTP response code or send headers and body yourself.
+
+.. code-block:: lua
+
+ -- Our upvalue
+ local value = 42
+
+ -- Expose the service
+ local service = {'application/json',
+ function (h, stream)
+ -- Get request method and deal with it properly
+ local m = h:get(':method')
+ local path = h:get(':path')
+ log('method %s path %s', m, path)
+ -- Return table, response code will be '200 OK'
+ if m == 'GET' then
+ return {key = path, value = value}
+ -- Save body, perform check and either respond with 505 or 200 OK
+ elseif m == 'POST' then
+ local data = stream:get_body_as_string()
+ if not tonumber(data) then
+ return 500, 'Not a good request'
+ end
+ value = tonumber(data)
+ -- Unsupported method, return 405 Method not allowed
+ else
+ return 405, 'Cannot do that'
+ end
+ end}
+ modules.load('http')
+ http.config({
+ endpoints = { ['/service'] = service }
+ }, 'myservice')
+ -- do not forget to create socket of new kind using
+ -- net.listen(..., { kind = 'myservice' })
+ -- or configure systemd socket kresd-myservice.socket
+
+In some cases you might need to send back your own headers instead of default provided by HTTP handler,
+you can do this, but then you have to return ``false`` to notify handler that it shouldn't try to generate
+a response.
+
+.. code-block:: lua
+
+ local headers = require('http.headers')
+ function (h, stream)
+ -- Send back headers
+ local hsend = headers.new()
+ hsend:append(':status', '200')
+ hsend:append('content-type', 'binary/octet-stream')
+ assert(stream:write_headers(hsend, false))
+ -- Send back data
+ local data = 'binary-data'
+ assert(stream:write_chunk(data, true))
+ -- Disable default handler action
+ return false
+ end
+
diff --git a/modules/http/debug_opensslkeylog.c b/modules/http/debug_opensslkeylog.c
new file mode 100644
index 0000000..6709eb7
--- /dev/null
+++ b/modules/http/debug_opensslkeylog.c
@@ -0,0 +1,369 @@
+/*
+ * Dumps master keys for OpenSSL clients to file. The format is documented at
+ * https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS/Key_Log_Format
+ * Supports TLS 1.3 when used with OpenSSL 1.1.1.
+ *
+ * Copyright (C) 2014 Peter Wu <peter@lekensteyn.nl>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ * Usage:
+ * cc sslkeylog.c -shared -o libsslkeylog.so -fPIC -ldl
+ * SSLKEYLOGFILE=premaster.txt LD_PRELOAD=./libsslkeylog.so openssl ...
+ */
+
+/*
+ * A single libsslkeylog.so supports multiple OpenSSL runtime versions. If you
+ * would like to build this library without OpenSSL development headers and do
+ * not require support for older OpenSSL versions, then disable it by defining
+ * the NO_OPENSSL_102_SUPPORT or NO_OPENSSL_110_SUPPORT macros.
+ */
+/* Define to drop OpenSSL <= 1.0.2 support and require OpenSSL >= 1.1.0. */
+//#define NO_OPENSSL_102_SUPPORT
+/* Define to drop OpenSSL <= 1.1.0 support and require OpenSSL >= 1.1.1. */
+//#define NO_OPENSSL_110_SUPPORT
+
+/* No OpenSSL 1.1.0 support implies no OpenSSL 1.0.2 support. */
+#ifdef NO_OPENSSL_110_SUPPORT
+# define NO_OPENSSL_102_SUPPORT
+#endif
+
+#ifndef _GNU_SOURCE
+# define _GNU_SOURCE /* for RTLD_NEXT */
+#endif
+
+#include <dlfcn.h>
+#ifndef NO_OPENSSL_102_SUPPORT
+# include <openssl/ssl.h>
+#endif /* ! NO_OPENSSL_102_SUPPORT */
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#ifndef OPENSSL_SONAME
+/* fallback library if OpenSSL is not already loaded. Other values to try:
+ * libssl.so.0.9.8 libssl.so.1.0.0 libssl.so.1.1 */
+# define OPENSSL_SONAME "libssl.so"
+#endif
+
+/* When building for OpenSSL 1.1.0 or newer, no headers are required. */
+#ifdef NO_OPENSSL_102_SUPPORT
+typedef struct ssl_st SSL;
+typedef struct ssl_ctx_st SSL_CTX;
+/* Extra definitions for OpenSSL 1.1.0 support when headers are unavailable. */
+# ifndef NO_OPENSSL_110_SUPPORT
+typedef struct ssl_session_st SSL_SESSION;
+# define SSL3_RANDOM_SIZE 32
+# define SSL_MAX_MASTER_KEY_LENGTH 48
+# define OPENSSL_VERSION_NUMBER 0x10100000L
+# endif /* ! NO_OPENSSL_110_SUPPORT */
+#endif /* ! NO_OPENSSL_102_SUPPORT */
+
+static int keylog_file_fd = -1;
+
+/* Legacy routines for dumping TLS <= 1.2 secrets on older OpenSSL versions. */
+#ifndef NO_OPENSSL_110_SUPPORT
+#define PREFIX "CLIENT_RANDOM "
+#define PREFIX_LEN (sizeof(PREFIX) - 1)
+
+#pragma GCC diagnostic ignored "-Wpedantic"
+#pragma GCC diagnostic ignored "-Wunused-result"
+
+static inline void put_hex(char *buffer, int pos, char c)
+{
+ unsigned char c1 = ((unsigned char) c) >> 4;
+ unsigned char c2 = c & 0xF;
+ buffer[pos] = c1 < 10 ? '0' + c1 : 'A' + c1 - 10;
+ buffer[pos+1] = c2 < 10 ? '0' + c2 : 'A' + c2 - 10;
+}
+
+static void dump_to_fd(int fd, unsigned char *client_random,
+ unsigned char *master_key, int master_key_length)
+{
+ int pos, i;
+ char line[PREFIX_LEN + 2 * SSL3_RANDOM_SIZE + 1 +
+ 2 * SSL_MAX_MASTER_KEY_LENGTH + 1];
+
+ memcpy(line, PREFIX, PREFIX_LEN);
+ pos = PREFIX_LEN;
+ /* Client Random for SSLv3/TLS */
+ for (i = 0; i < SSL3_RANDOM_SIZE; i++) {
+ put_hex(line, pos, client_random[i]);
+ pos += 2;
+ }
+ line[pos++] = ' ';
+ /* Master Secret (size is at most SSL_MAX_MASTER_KEY_LENGTH) */
+ for (i = 0; i < master_key_length; i++) {
+ put_hex(line, pos, master_key[i]);
+ pos += 2;
+ }
+ line[pos++] = '\n';
+ /* Write at once rather than using buffered I/O. Perhaps there is concurrent
+ * write access so do not write hex values one by one. */
+ write(fd, line, pos);
+}
+#endif /* ! NO_OPENSSL_110_SUPPORT */
+
+static void init_keylog_file(void)
+{
+ if (keylog_file_fd >= 0)
+ return;
+
+ const char *filename = getenv("OPENSSLKEYLOGFILE");
+ if (filename) {
+ /* ctime output is max 26 bytes, POSIX 1003.1-2017 */
+ keylog_file_fd = open(filename, O_WRONLY | O_APPEND | O_CREAT, 0600);
+ if (keylog_file_fd >= 0) {
+ time_t timenow = time(NULL);
+ char txtnow[30] = { '#', ' ', 0 };
+ ctime_r(&timenow, txtnow + 2);
+ /* file is opened successfully and there is no data (pos == 0) */
+ write(keylog_file_fd, txtnow, strlen(txtnow));
+ }
+ }
+}
+
+static inline void *try_lookup_symbol(const char *sym, int optional)
+{
+ void *func = dlsym(RTLD_NEXT, sym);
+ if (!func && optional && dlsym(RTLD_NEXT, "SSL_new")) {
+ /* Symbol not found, but an old OpenSSL version was actually loaded. */
+ return NULL;
+ }
+ /* Symbol not found, OpenSSL is not loaded (linked) so try to load it
+ * manually. This is error-prone as it depends on a fixed library name.
+ * Perhaps it should be an env name? */
+ if (!func) {
+ void *handle = dlopen(OPENSSL_SONAME, RTLD_LAZY);
+ if (!handle) {
+ fprintf(stderr, "Lookup error for %s: %s\n", sym, dlerror());
+ abort();
+ }
+ func = dlsym(handle, sym);
+ if (!func && !optional) {
+ fprintf(stderr, "Cannot lookup %s\n", sym);
+ abort();
+ }
+ dlclose(handle);
+ }
+ return func;
+}
+
+static inline void *lookup_symbol(const char *sym)
+{
+ return try_lookup_symbol(sym, 0);
+}
+
+#ifndef NO_OPENSSL_110_SUPPORT
+typedef struct ssl_tap_state {
+ int master_key_length;
+ unsigned char master_key[SSL_MAX_MASTER_KEY_LENGTH];
+
+} ssl_tap_state_t;
+
+static inline SSL_SESSION *ssl_get_session(const SSL *ssl)
+{
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+ static SSL_SESSION *(*func)();
+ if (!func) {
+ func = lookup_symbol("SSL_get_session");
+ }
+ return func(ssl);
+#else
+ return ssl->session;
+#endif
+}
+
+static void copy_master_secret(const SSL_SESSION *session,
+ unsigned char *master_key_out, int *keylen_out)
+{
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+ static size_t (*func)();
+ if (!func) {
+ func = lookup_symbol("SSL_SESSION_get_master_key");
+ }
+ *keylen_out = func(session, master_key_out, SSL_MAX_MASTER_KEY_LENGTH);
+#else
+ if (session->master_key_length > 0) {
+ *keylen_out = session->master_key_length;
+ memcpy(master_key_out, session->master_key,
+ session->master_key_length);
+ }
+#endif
+}
+
+static void copy_client_random(const SSL *ssl, unsigned char *client_random)
+{
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+ static size_t (*func)();
+ if (!func) {
+ func = lookup_symbol("SSL_get_client_random");
+ }
+ /* ssl->s3 is not checked in openssl 1.1.0-pre6, but let's assume that
+ * we have a valid SSL context if we have a non-NULL session. */
+ func(ssl, client_random, SSL3_RANDOM_SIZE);
+#else
+ if (ssl->s3) {
+ memcpy(client_random, ssl->s3->client_random, SSL3_RANDOM_SIZE);
+ }
+#endif
+}
+
+/* non-NULL if the new OpenSSL 1.1.1 keylog API is supported. */
+static int supports_keylog_api(void)
+{
+ static int supported = -1;
+ if (supported == -1) {
+ supported = try_lookup_symbol("SSL_CTX_set_keylog_callback", 1) != NULL;
+ }
+ return supported;
+}
+
+/* Copies SSL state for later comparison in tap_ssl_key. */
+static void ssl_tap_state_init(ssl_tap_state_t *state, const SSL *ssl)
+{
+ if (supports_keylog_api()) {
+ /* Favor using the callbacks API to extract secrets. */
+ return;
+ }
+
+ const SSL_SESSION *session = ssl_get_session(ssl);
+
+ memset(state, 0, sizeof(ssl_tap_state_t));
+ if (session) {
+ copy_master_secret(session, state->master_key, &state->master_key_length);
+ }
+}
+
+#define SSL_TAP_STATE(state, ssl) \
+ ssl_tap_state_t state; \
+ ssl_tap_state_init(&state, ssl)
+
+static void tap_ssl_key(const SSL *ssl, ssl_tap_state_t *state)
+{
+ if (supports_keylog_api()) {
+ /* Favor using the callbacks API to extract secrets. */
+ return;
+ }
+
+ const SSL_SESSION *session = ssl_get_session(ssl);
+ unsigned char client_random[SSL3_RANDOM_SIZE];
+ unsigned char master_key[SSL_MAX_MASTER_KEY_LENGTH];
+ int master_key_length = 0;
+
+ if (session) {
+ copy_master_secret(session, master_key, &master_key_length);
+ /* Assume we have a client random if the master key is set. */
+ if (master_key_length > 0) {
+ copy_client_random(ssl, client_random);
+ }
+ }
+
+ /* Write the logfile when the master key is available for SSLv3/TLSv1. */
+ if (master_key_length > 0) {
+ /* Skip writing keys if it did not change. */
+ if (state->master_key_length == master_key_length &&
+ memcmp(state->master_key, master_key, master_key_length) == 0) {
+ return;
+ }
+
+ init_keylog_file();
+ if (keylog_file_fd >= 0) {
+ dump_to_fd(keylog_file_fd, client_random, master_key,
+ master_key_length);
+ }
+ }
+}
+
+int SSL_connect(SSL *ssl)
+{
+ static int (*func)();
+ if (!func) {
+ func = lookup_symbol(__func__);
+ }
+ SSL_TAP_STATE(state, ssl);
+ int ret = func(ssl);
+ tap_ssl_key(ssl, &state);
+ return ret;
+}
+
+int SSL_do_handshake(SSL *ssl)
+{
+ static int (*func)();
+ if (!func) {
+ func = lookup_symbol(__func__);
+ }
+ SSL_TAP_STATE(state, ssl);
+ int ret = func(ssl);
+ tap_ssl_key(ssl, &state);
+ return ret;
+}
+
+int SSL_accept(SSL *ssl)
+{
+ static int (*func)();
+ if (!func) {
+ func = lookup_symbol(__func__);
+ }
+ SSL_TAP_STATE(state, ssl);
+ int ret = func(ssl);
+ tap_ssl_key(ssl, &state);
+ return ret;
+}
+
+int SSL_read(SSL *ssl, void *buf, int num)
+{
+ static int (*func)();
+ if (!func) {
+ func = lookup_symbol(__func__);
+ }
+ SSL_TAP_STATE(state, ssl);
+ int ret = func(ssl, buf, num);
+ tap_ssl_key(ssl, &state);
+ return ret;
+}
+
+int SSL_write(SSL *ssl, const void *buf, int num)
+{
+ static int (*func)();
+ if (!func) {
+ func = lookup_symbol(__func__);
+ }
+ SSL_TAP_STATE(state, ssl);
+ int ret = func(ssl, buf, num);
+ tap_ssl_key(ssl, &state);
+ return ret;
+}
+#endif /* ! NO_OPENSSL_110_SUPPORT */
+
+/* Key extraction via the new OpenSSL 1.1.1 API. */
+static void keylog_callback(const SSL *ssl, const char *line)
+{
+ init_keylog_file();
+ if (keylog_file_fd >= 0) {
+ write(keylog_file_fd, line, strlen(line));
+ write(keylog_file_fd, "\n", 1);
+ }
+}
+
+SSL *SSL_new(SSL_CTX *ctx)
+{
+ static SSL *(*func)();
+ static void (*set_keylog_cb)();
+ if (!func) {
+ func = lookup_symbol(__func__);
+#ifdef NO_OPENSSL_110_SUPPORT
+ /* The new API MUST be available since OpenSSL 1.1.1. */
+ set_keylog_cb = lookup_symbol("SSL_CTX_set_keylog_callback");
+#else /* ! NO_OPENSSL_110_SUPPORT */
+ /* May be NULL if used with an older OpenSSL runtime library. */
+ set_keylog_cb = try_lookup_symbol("SSL_CTX_set_keylog_callback", 1);
+#endif /* ! NO_OPENSSL_110_SUPPORT */
+ }
+ if (set_keylog_cb) {
+ /* Override any previous key log callback. */
+ set_keylog_cb(ctx, keylog_callback);
+ }
+ return func(ctx);
+}
diff --git a/modules/http/http.lua.in b/modules/http/http.lua.in
new file mode 100644
index 0000000..b6cf16a
--- /dev/null
+++ b/modules/http/http.lua.in
@@ -0,0 +1,418 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+
+-- Load dependent modules
+if not stats then modules.load('stats') end
+if not bogus_log then modules.load('bogus_log') end
+
+local ffi = require('ffi')
+local cqueues = require('cqueues')
+cqueues.socket = require('cqueues.socket')
+assert(cqueues.VERSION >= 20150112) -- fdopen changed semantics
+
+-- This is a module that does the heavy lifting to provide an HTTP/2 enabled
+-- server that supports TLS by default and provides endpoint for other modules
+-- in order to enable them to export restful APIs and websocket streams.
+-- One example is statistics module that can stream live metrics on the website,
+-- or publish metrics on request for Prometheus scraper.
+local http_server = require('http.server')
+local http_headers = require('http.headers')
+local http_websocket = require('http.websocket')
+local http_util = require "http.util"
+local has_mmdb, mmdb = pcall(require, 'mmdb')
+
+-- A sub-module for certificate management.
+local tls_cert = require('kres_modules.http_tls_cert')
+
+-- Module declaration
+local M = {
+ servers = {},
+ configs = { _builtin = {} } -- configuration templates
+}
+
+-- inherited by all configurations
+M.configs._builtin._all = {
+ cq = worker.bg_worker.cq,
+ cert = 'self.crt',
+ key = 'self.key',
+ ephemeral = true,
+ client_timeout = 5
+}
+-- log errors but do not throw
+M.configs._builtin._all.onerror = function(myserver, context, op, err, errno) -- luacheck: ignore 212
+ local msg = op .. ' on ' .. tostring(context) .. ' failed'
+ if err then
+ msg = msg .. ': ' .. tostring(err)
+ end
+ log_info(ffi.C.LOG_GRP_HTTP, msg)
+end
+
+-- M.config() without explicit "kind" modifies this
+M.configs._all = {}
+
+-- DoH
+M.configs._builtin.doh_legacy = {}
+
+-- management endpoint
+M.configs._builtin.webmgmt = {}
+
+-- Map extensions to MIME type
+local mime_types = {
+ js = 'application/javascript',
+ css = 'text/css',
+ tpl = 'text/html',
+ ico = 'image/x-icon'
+}
+
+-- Preload static contents, nothing on runtime will touch the disk
+local function pgload(relpath, modname)
+ if not modname then modname = 'http' end
+ local fp, err = io.open(string.format(
+ '@modules_dir@/%s/%s', modname, relpath), 'r')
+ if not fp then
+ fp, err = io.open(string.format(
+ '@modules_dir@/%s/static/%s', modname, relpath), 'r')
+ end
+ if not fp then error(err) end
+ local data = fp:read('*all')
+ fp:close()
+ -- Guess content type
+ local ext = relpath:match('[^\\.]+$')
+ return {mime_types[ext] or 'text', data, nil, 86400}
+end
+M.page = pgload
+
+-- Preloaded static assets
+local pages = {
+ 'favicon.ico',
+ 'kresd.js',
+ 'kresd.css',
+ 'jquery.js',
+ 'd3.js',
+ 'topojson.js',
+ 'datamaps.world.min.js',
+ 'dygraph.min.js',
+ 'selectize.min.js',
+ 'selectize.bootstrap3.css',
+ 'bootstrap.min.js',
+ 'bootstrap.min.css',
+ 'bootstrap-theme.min.css',
+ 'glyphicons-halflings-regular.woff2',
+}
+
+-- Serve preloaded root page
+local function serve_root()
+ local data = pgload('main.tpl')[2]
+ data = data
+ :gsub('{{ title }}', M.title or ('kresd @ ' .. hostname()))
+ :gsub('{{ host }}', hostname())
+ return function (_, _)
+ -- Render snippets
+ local rsnippets = {}
+ for _,v in pairs(M.snippets) do
+ local sid = string.lower(string.gsub(v[1], ' ', '-'))
+ table.insert(rsnippets, string.format('<section id="%s"><h2>%s</h2>\n%s</section>', sid, v[1], v[2]))
+ end
+ -- Return index page
+ return data
+ :gsub('{{ snippets }}', table.concat(rsnippets, '\n'))
+ end
+end
+
+-- Export HTTP service endpoints
+M.configs._builtin.doh_legacy.endpoints = {}
+M.configs._builtin.webmgmt.endpoints = {}
+local mgmt_endpoints = M.configs._builtin.webmgmt.endpoints
+
+mgmt_endpoints['/'] = {'text/html', serve_root()}
+
+-- Export static pages
+for _, pg in ipairs(pages) do
+ mgmt_endpoints['/'..pg] = pgload(pg)
+end
+
+-- Export built-in prometheus interface
+local prometheus = require('kres_modules.prometheus')
+for k, v in pairs(prometheus.endpoints) do
+ mgmt_endpoints[k] = v
+end
+M.prometheus = prometheus
+
+-- Export built-in trace interface
+local http_trace = require('kres_modules.http_trace')
+for k, v in pairs(http_trace.endpoints) do
+ mgmt_endpoints[k] = v
+end
+M.trace = http_trace
+
+M.configs._builtin.doh_legacy.endpoints = {}
+local http_doh = require('kres_modules.http_doh')
+for k, v in pairs(http_doh.endpoints) do
+ mgmt_endpoints[k] = v
+ M.configs._builtin.doh_legacy.endpoints[k] = v
+end
+M.doh = http_doh
+
+-- Export HTTP service page snippets
+M.snippets = {}
+
+-- Serve known requests, for methods other than GET
+-- the endpoint must be a closure and not a preloaded string
+local function serve(endpoints, h, stream)
+ local hsend = http_headers.new()
+ local path = h:get(':path')
+ local entry = endpoints[path]
+ if not entry then -- Accept top-level path match
+ entry = endpoints[path:match '^/[^/?]*']
+ end
+ -- Unpack MIME and data
+ local data, mime, ttl, any_origin, err
+ if entry then
+ mime = entry[1]
+ data = entry[2]
+ ttl = entry[4]
+ any_origin = entry[5]
+ end
+ -- Get string data out of service endpoint
+ if type(data) == 'function' then
+ local set_mime, set_ttl
+ data, err, set_mime, set_ttl = data(h, stream)
+ -- Override default endpoint mime/TTL
+ if set_mime then mime = set_mime end
+ if set_ttl then ttl = set_ttl end
+ -- Handler doesn't provide any data
+ if data == false then return end
+ if type(data) == 'number' then return tostring(data), err end
+ -- Methods other than GET require handler to be closure
+ elseif h:get(':method') ~= 'GET' then
+ return '501', ''
+ end
+ if type(data) == 'table' then data = tojson(data) end
+ if not mime or type(data) ~= 'string' then
+ return '404', ''
+ else
+ -- Serve content type appropriately
+ hsend:append(':status', '200')
+ hsend:append('content-type', mime)
+ hsend:append('content-length', tostring(#data))
+ if ttl then
+ hsend:append('cache-control', string.format('max-age=%d', ttl))
+ end
+ if any_origin then
+ hsend:append('access-control-allow-origin', '*')
+ end
+ assert(stream:write_headers(hsend, false))
+ assert(stream:write_chunk(data, true))
+ end
+end
+
+-- Web server service closure
+local function route(endpoints)
+ assert(type(endpoints) == 'table', 'endpoints are not a table, is it a botched template?')
+ return function (_, stream)
+ -- HTTP/2: We're only permitted to send in open/half-closed (remote)
+ local connection = stream.connection
+ if connection.version >= 2 then
+ if stream.state ~= 'open' and stream.state ~= 'half closed (remote)' then
+ return
+ end
+ end
+ -- Start reading headers
+ local h = assert(stream:get_headers())
+ local m = h:get(':method')
+ local path = h:get(':path')
+
+ -- Upgrade connection to WebSocket
+ local ws = http_websocket.new_from_stream(stream, h)
+ if ws then
+ log_info(ffi.C.LOG_GRP_HTTP, '%s %s HTTP/%s web socket open',
+ m, path, tostring(connection.version))
+ assert(ws:accept { protocols = {'json'} })
+ -- Continue streaming results to client
+ local ep = endpoints[path]
+ local cb = ep[3]
+ if cb then
+ cb(h, ws)
+ end
+ ws:close()
+ log_info(ffi.C.LOG_GRP_HTTP, '%s %s HTTP/%s web socket closed',
+ m, path, tostring(connection.version))
+ return
+ else
+ local ok, err, reason = http_util.yieldable_pcall(serve, endpoints, h, stream)
+ if not ok or err then
+ err = err or '500'
+ log_info(ffi.C.LOG_GRP_HTTP, '%s %s HTTP/%s %s %s',
+ m, path, tostring(connection.version), err, reason or '')
+ -- Method is not supported
+ local hsend = http_headers.new()
+ hsend:append(':status', err)
+ if reason then
+ assert(stream:write_headers(hsend, false))
+ assert(stream:write_chunk(reason, true))
+ else
+ assert(stream:write_headers(hsend, true))
+ end
+ else
+ log_info(ffi.C.LOG_GRP_HTTP, '%s %s HTTP/%s 200',
+ m, path, tostring(connection.version))
+ end
+
+ end
+ end
+end
+
+-- @function Merge dictionaries, nil is like empty dict.
+-- Values from right-hand side dictionaries take precedence.
+local function mergeconf(...)
+ local merged = {}
+ local ntables = select('#', ...)
+ local tables = {...}
+ for i = 1, ntables do
+ local intable = tables[i]
+ if intable ~= nil then
+ assert(type(intable) == 'table', 'cannot merge non-tables')
+ for key, val in pairs(intable) do
+ merged[key] = val
+ end
+ end
+ end
+ return merged
+end
+
+-- @function Listen on given socket
+-- using configuration for specific "kind" of HTTP server
+local function add_socket(fd, kind, addr_str)
+ assert(M.servers[fd] == nil, 'socket is already served by an HTTP instance')
+ local conf = mergeconf(M.configs._builtin._all, M.configs._builtin[kind],
+ M.configs._all, M.configs[kind])
+ conf.socket = cqueues.socket.fdopen({ fd = fd, reuseport = true, reuseaddr = true })
+ if conf.tls ~= false then -- Create a TLS context, either from files or new.
+ if conf.ephemeral then
+ if not M.ephem_state then
+ M.ephem_state = { servers = M.servers }
+ tls_cert.ephemeral_state_maintain(M.ephem_state, conf.cert, conf.key)
+ end
+ conf.ctx = M.ephem_state.ctx
+ else
+ local certs, key = tls_cert.load(conf.cert, conf.key)
+ conf.ctx = tls_cert.new_tls_context(certs, key)
+ end
+ assert(conf.ctx)
+ end
+ -- Compose server handler
+ local routes = route(conf.endpoints)
+ conf.onstream = routes
+ -- Create TLS context and start listening
+ local s, err = http_server.new(conf)
+ -- Manually call :listen() so that we are bound before calling :localname()
+ if s then
+ err = select(2, s:listen())
+ end
+ if err then
+ panic('failed to listen on %s: %s', addr_str, err)
+ end
+ M.servers[fd] = {kind = kind, server = s, config = conf}
+end
+
+-- @function Stop listening on given socket
+local function remove_socket(fd)
+ local instance = M.servers[fd]
+ assert(instance, 'HTTP module is not listening on given socket')
+
+ instance.server:close()
+ M.servers[fd] = nil
+end
+
+-- @function Listen for config changes from net.listen()/net.close()
+local function cb_socket(...)
+ local added, endpoint, addr_str = unpack({...})
+ endpoint = ffi.cast('struct endpoint **', endpoint)[0]
+ local kind = ffi.string(endpoint.flags.kind)
+ local socket = endpoint.fd
+ if added then
+ return add_socket(socket, kind, addr_str)
+ else
+ return remove_socket(socket)
+ end
+end
+
+-- @function Init module
+function M.init()
+ net.register_endpoint_kind('doh_legacy', cb_socket)
+ net.register_endpoint_kind('webmgmt', cb_socket)
+end
+
+-- @function Cleanup module
+function M.deinit()
+ for fd, _ in pairs(M.servers) do
+ remove_socket(fd)
+ end
+ tls_cert.ephemeral_state_destroy(M.ephem_state)
+ net.register_endpoint_kind('doh_legacy')
+ net.register_endpoint_kind('webmgmt')
+end
+
+-- @function Configure module, i.e. store new configuration template
+-- kind = socket type (doh_legacy/webmgmt)
+function M.config(conf, kind)
+ if conf == nil and kind == nil then
+ -- default module config, nothing to do
+ return
+ end
+
+ kind = kind or '_all'
+ assert(type(kind) == 'string')
+
+ local operation
+ -- builtins cannot be removed or added
+ if M.configs._builtin[kind] then
+ operation = 'modify'
+ conf = conf or {}
+ elseif M.configs[kind] then -- config on an existing user template
+ if conf then operation = 'modify'
+ else operation = 'delete' end
+ else -- config for not-yet-existing template
+ if conf then operation = 'add'
+ else panic('[http] endpoint kind "%s" does not exist, '
+ .. 'nothing to delete', kind) end
+ end
+
+ if operation == 'modify' or operation == 'add' then
+ assert(type(conf) == 'table', 'config { cert = "...", key = "..." }')
+
+ if conf.cert then
+ conf.ephemeral = false
+ if not conf.key then
+ panic('[http] certificate provided, but missing key')
+ end
+ -- test if it can be loaded or not
+ tls_cert.load(conf.cert, conf.key)
+ end
+ if conf.geoip then
+ if has_mmdb then
+ M.geoip = mmdb.open(conf.geoip)
+ else
+ error('[http] mmdblua library not found, please remove GeoIP configuration')
+ end
+ end
+ end
+
+ for _, instance in pairs(M.servers) do
+ -- modification cannot be implemented as
+ -- remove_socket + add_socket because remove closes the socket
+ if instance.kind == kind or kind == '_all' then
+ panic('unable to modify configuration for '
+ .. 'endpoint kind "%s" because it is in '
+ .. 'use, use net.close() first', kind)
+ end
+ end
+
+ if operation == 'add' then
+ net.register_endpoint_kind(kind, cb_socket)
+ elseif operation == 'delete' then
+ net.register_endpoint_kind(kind)
+ end
+ M.configs[kind] = conf
+end
+
+return M
diff --git a/modules/http/http.test.lua b/modules/http/http.test.lua
new file mode 100644
index 0000000..b882f10
--- /dev/null
+++ b/modules/http/http.test.lua
@@ -0,0 +1,128 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+-- check prerequisites
+local has_http = pcall(require, 'kres_modules.http') and pcall(require, 'http.request')
+if not has_http then
+ -- skipping http module test because its not installed
+ os.exit(77)
+else
+ local path = worker.cwd..'/control/'..worker.pid
+ same(true, net.listen(path, nil, {kind = 'control'}),
+ 'new control sockets were created so map() can work')
+
+ local request = require('http.request')
+
+ modules.load('http')
+ local endpoints = http.configs._builtin.webmgmt.endpoints
+
+ -- custom endpoints
+ endpoints['/test'] = {'text/custom', function () return 'hello' end}
+
+ -- setup HTTP module with an additional endpoint
+ http.config({
+ tls = false,
+ endpoints = endpoints,
+ }, 'webtest')
+
+ local bound
+ for _ = 1,1000 do
+ bound, _err = pcall(net.listen, '127.0.0.1', math.random(20000, 29999), { kind = 'webtest'})
+ if bound then
+ break
+ end
+ end
+ assert(bound, 'unable to bind a port for HTTP module (1000 attempts)')
+
+ -- globals for this module
+ local _, host, port
+ local function start_server()
+ local server_fd = next(http.servers)
+ assert(server_fd)
+ local server = http.servers[server_fd].server
+ ok(server ~= nil, 'creates server instance')
+ _, host, port = server:localname()
+ ok(host and port, 'binds to an interface')
+ end
+
+ -- helper for returning useful values to test on
+ local function http_get(uri)
+ local headers, stream = assert(request.new_from_uri(uri .. '/'):go(16))
+ local body = assert(stream:get_body_as_string())
+ return tonumber(headers:get(':status')), body, headers:get('content-type')
+ end
+
+ -- test whether http interface responds and binds
+ local function test_builtin_pages()
+ local code, body, mime
+ local uri = string.format('http://%s:%d', host, port)
+ -- simple static page
+ code, body, mime = http_get(uri .. '/')
+ same(code, 200, 'static page return 200 OK')
+ ok(#body > 0, 'static page has non-empty body')
+ same(mime, 'text/html', 'static page has text/html content type')
+ -- custom endpoint
+ code, body, mime = http_get(uri .. '/test')
+ same(code, 200, 'custom page return 200 OK')
+ same(body, 'hello', 'custom page has non-empty body')
+ same(mime, 'text/custom', 'custom page has custom content type')
+ -- non-existent page
+ code = http_get(uri .. '/badpage')
+ same(code, 404, 'non-existent page returns 404')
+ -- /stats endpoint serves metrics
+ code, body, mime = http_get(uri .. '/stats')
+ same(code, 200, '/stats page return 200 OK')
+ ok(#body > 0, '/stats page has non-empty body')
+ same(mime, 'application/json', '/stats page has correct content type')
+ -- /metrics serves metrics
+ code, body, mime = http_get(uri .. '/metrics')
+ same(code, 200, '/metrics page return 200 OK')
+ ok(#body > 0, '/metrics page has non-empty body')
+ same(mime, 'text/plain; version=0.0.4', '/metrics page has correct content type')
+ -- /metrics serves frequent
+ code, body, mime = http_get(uri .. '/frequent')
+ same(code, 200, '/frequent page return 200 OK')
+ ok(#body > 0, '/frequent page has non-empty body')
+ same(mime, 'application/json', '/frequent page has correct content type')
+ -- /metrics serves bogus
+ code, body, mime = http_get(uri .. '/bogus')
+ same(code, 200, '/bogus page return 200 OK')
+ ok(#body > 0, '/bogus page has non-empty body')
+ same(mime, 'application/json', '/bogus page has correct content type')
+ -- /trace serves trace log for requests
+ code, body, mime = http_get(uri .. '/trace/localhost/A')
+ same(code, 200, '/trace page return 200 OK')
+ ok(#body > 0, '/trace page has non-empty body')
+ same(mime, 'text/plain', '/trace page has correct content type')
+ -- /trace checks variables
+ code = http_get(uri .. '/trace/localhost/BADTYPE')
+ same(code, 400, '/trace checks type')
+ code = http_get(uri .. '/trace/')
+ same(code, 400, '/trace requires name')
+ end
+
+ -- AF_UNIX tests (very basic ATM)
+ local function test_unix_socket()
+ local s_path = os.tmpname()
+ os.remove(s_path) -- on POSIX .tmpname() (usually) creates a file :-/
+ ok(net.listen(s_path, nil, { kind = 'webmgmt' }), 'AF_UNIX net.listen() on ' .. s_path)
+ -- Unfortunately we can't use standard functions for fetching http://
+ local socket = require("cqueues.socket")
+ local sock = socket.connect({ path = s_path })
+ local connection = require('http.h2_connection')
+ local conn = connection.new(sock, 'client')
+ local _, err = conn:connect()
+ os.remove(s_path) -- don't leave garbage around, hopefully not even on errors
+ same(err, nil, 'AF_UNIX connect(): ' .. (err or 'OK'))
+ same(conn:ping(), true, 'AF_UNIX http ping')
+ -- here we might do `conn:new_stream()` and some real queries
+ same(conn:close(), true, 'AF_UNIX close')
+ end
+
+ -- plan tests
+ local tests = {
+ start_server,
+ test_builtin_pages,
+ test_unix_socket,
+ }
+
+ return tests
+end
diff --git a/modules/http/http_doh.lua b/modules/http/http_doh.lua
new file mode 100644
index 0000000..33815f7
--- /dev/null
+++ b/modules/http/http_doh.lua
@@ -0,0 +1,116 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+local basexx = require('basexx')
+local ffi = require('ffi')
+local condition = require('cqueues.condition')
+
+-- Trace execution of DNS queries
+local function serve_doh(h, stream)
+ local input
+ local method = h:get(':method')
+ if method == 'POST' then
+ input = stream:get_body_chars(1025, 2) -- read timeout = KR_CONN_RTT_MAX
+ elseif method == 'GET' then
+ local input_b64 = string.match(h:get(':path'), '^/[^?]*%?dns=([a-zA-Z0-9_-]+)$') or
+ string.match(h:get(':path'), '^/[^?]*%?dns=([a-zA-Z0-9_-]+)&') or
+ string.match(h:get(':path'), '^/[^?]*%?.*&dns=([a-zA-Z0-9_-]+)$') or
+ string.match(h:get(':path'), '^/[^?]*%?.*&dns=([a-zA-Z0-9_-]+)&')
+ if not input_b64 then
+ return 400, 'base64url query not found'
+ end
+ if #input_b64 > 1368 then -- base64url encode 1024
+ return 414, 'query parameter in URI too long'
+ end
+ input = basexx.from_url64(input_b64)
+ if not input then
+ return 400, 'invalid base64url'
+ end
+ else
+ return 405, 'only HTTP POST and GET are supported'
+ end
+
+ if not input or #input < 12 then
+ return 400, 'input too short'
+ elseif #input > 1024 then
+ return 413, 'input too long'
+ end
+
+ local content_type = h:get('content-type') or 'application/dns-message'
+ if content_type ~= 'application/dns-message' then
+ return 415, 'only Content-Type: application/dns-message is supported'
+ end
+-- RFC 8484 section-4.1 allows us to ignore Accept header
+-- local accept = h:get('accept') or 'application/dns-message'
+-- if accept ~= 'application/dns-message' then
+-- return 406, 'only Accept: application/dns-message is supported'
+-- end
+
+ -- We get these values beforehand, because it's easier to handle errors now.
+ local _, peer_addr, peer_port = stream:peername()
+ local _, dst_addr, dst_port = stream:localname()
+ if not (peer_addr and peer_port and dst_addr and dst_port) then
+ -- The connection probably died in the meantime or something.
+ return 504, 'failed to determine your address'
+ end
+
+ -- Output buffer
+ local output
+ local output_ttl
+
+ -- Wait for the result of the query
+ -- Note: We can't do non-blocking write to stream directly from resolve callbacks
+ -- because they don't run inside cqueue.
+ local cond = condition.new()
+ local waiting, done = false, false
+ local finish_cb = function (answer, _)
+ output_ttl = ffi.C.packet_ttl(answer)
+ -- binary output
+ output = ffi.string(answer.wire, answer.size)
+ if waiting then
+ cond:signal()
+ end
+ done = true
+ end
+
+ -- convert query to knot_pkt_t
+ local wire = ffi.cast("void *", input)
+ local pkt = ffi.gc(ffi.C.knot_pkt_new(wire, #input, nil), ffi.C.knot_pkt_free)
+ if not pkt then
+ return 500, 'internal server error'
+ end
+
+ local result = ffi.C.knot_pkt_parse(pkt, 0)
+ if result ~= 0 then
+ return 400, 'unparseable DNS message'
+ end
+
+ -- set source address so filters can work
+ local function init_cb(req)
+ req.qsource.addr = ffi.C.kr_straddr_socket(peer_addr, peer_port, req.pool)
+ req.qsource.dst_addr = ffi.C.kr_straddr_socket(dst_addr, dst_port, req.pool)
+ assert(req.qsource.addr ~= nil and req.qsource.dst_addr ~= nil)
+ req.qsource.flags.tcp = true
+ req.qsource.flags.tls = (stream.connection:checktls() ~= nil)
+ req.qsource.flags.http = true
+ end
+
+ -- resolve query
+ worker.resolve_pkt(pkt, {}, finish_cb, init_cb)
+ if not done then
+ waiting = true
+ cond:wait()
+ end
+
+ -- Return buffered data
+ if not done then
+ return 504, 'huh?' -- FIXME
+ end
+ return output, nil, 'application/dns-message', output_ttl
+end
+
+-- Export endpoints
+return {
+ endpoints = {
+ ['/doh'] = {'text/plain', serve_doh, nil, nil, true},
+ ['/dns-query'] = {'text/plain', serve_doh, nil, nil, true},
+ }
+}
diff --git a/modules/http/http_doh.test.lua b/modules/http/http_doh.test.lua
new file mode 100644
index 0000000..f0685cb
--- /dev/null
+++ b/modules/http/http_doh.test.lua
@@ -0,0 +1,419 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+local basexx = require('basexx')
+local ffi = require('ffi')
+
+local function gen_huge_answer(_, req)
+ local answer = req:ensure_answer()
+ ffi.C.kr_pkt_make_auth_header(answer)
+
+ answer:rcode(kres.rcode.NOERROR)
+
+ -- 64k answer
+ answer:begin(kres.section.ANSWER)
+ answer:put('\4test\0', 300, answer:qclass(), kres.type.URI,
+ '\0\0\0\0' .. string.rep('0', 65000))
+ answer:put('\4test\0', 300, answer:qclass(), kres.type.URI,
+ '\0\0\0\0' .. 'done')
+ return kres.DONE
+end
+
+local function gen_varying_ttls(_, req)
+ local qry = req:current()
+ local answer = req:ensure_answer()
+ ffi.C.kr_pkt_make_auth_header(answer)
+
+ answer:rcode(kres.rcode.NOERROR)
+
+ -- varying TTLs in ANSWER section
+ answer:begin(kres.section.ANSWER)
+ answer:put(qry.sname, 1800, answer:qclass(), kres.type.AAAA,
+ '\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1')
+ answer:put(qry.sname, 900, answer:qclass(), kres.type.A, '\127\0\0\1')
+ answer:put(qry.sname, 20000, answer:qclass(), kres.type.NS, '\2ns\4test\0')
+
+ -- shorter TTL than all other RRs
+ answer:begin(kres.section.AUTHORITY)
+ answer:put('\4test\0', 300, answer:qclass(), kres.type.SOA,
+ '\2ns\4test\0\6nobody\7invalid\0\0\0\0\1\0\0\14\16\0\0\4\176\0\9\58\128\0\0\42\48')
+ return kres.DONE
+end
+
+function parse_pkt(input, desc)
+ local wire = ffi.cast("void *", input)
+ local pkt = ffi.C.knot_pkt_new(wire, #input, nil);
+ assert(pkt, desc .. ': failed to create new packet')
+
+ local result = ffi.C.knot_pkt_parse(pkt, 0)
+ ok(result == 0, desc .. ': knot_pkt_parse works on received answer')
+ return pkt
+end
+
+local function check_ok(req, desc)
+ local headers, stream, errno = req:go(16)
+ if errno then
+ local errmsg = stream
+ nok(errmsg, desc .. ': ' .. errmsg)
+ return
+ end
+ same(tonumber(headers:get(':status')), 200, desc .. ': status 200')
+ same(headers:get('content-type'), 'application/dns-message', desc .. ': content-type')
+ local body = assert(stream:get_body_as_string())
+ local pkt = parse_pkt(body, desc)
+ return headers, pkt
+end
+
+local function check_err(req, exp_status, desc)
+ local headers, errmsg, errno = req:go(16)
+ if errno then
+ nok(errmsg, desc .. ': ' .. errmsg)
+ return
+ end
+ local got_status = headers:get(':status')
+ same(got_status, exp_status, desc)
+end
+
+-- check prerequisites
+local has_http = pcall(require, 'kres_modules.http') and pcall(require, 'http.request')
+if not has_http then
+ -- skipping http module test because its not installed
+ os.exit(77)
+else
+ policy.add(policy.suffix(policy.DROP, policy.todnames({'servfail.test.'})))
+ policy.add(policy.suffix(policy.DENY, policy.todnames({'nxdomain.test.'})))
+ policy.add(policy.suffix(gen_varying_ttls, policy.todnames({'noerror.test.'})))
+
+ modules.load('http')
+ http.config({
+ tls = false,
+ }, 'doh_legacy')
+
+ local bound
+ for _ = 1,1000 do
+ bound, _err = pcall(net.listen, '127.0.0.1', math.random(30000, 39999), { kind = 'doh_legacy' })
+ if bound then
+ break
+ end
+ end
+ assert(bound, 'unable to bind a port for HTTP module (1000 attempts)')
+
+ local _, host, port, req_templ, uri_templ
+ local function start_server()
+ local request = require('http.request')
+ local server_fd = next(http.servers)
+ assert(server_fd)
+ local server = http.servers[server_fd].server
+ ok(server ~= nil, 'creates server instance')
+ _, host, port = server:localname()
+ ok(host and port, 'binds to an interface')
+ uri_templ = string.format('http://%s:%d/doh', host, port)
+ req_templ = assert(request.new_from_uri(uri_templ))
+ req_templ.headers:upsert('content-type', 'application/dns-message')
+ end
+
+
+ -- test a valid DNS query using POST
+ local function test_post_servfail()
+ local desc = 'valid POST query which ends with SERVFAIL'
+ local req = req_templ:clone()
+ req.headers:upsert(':method', 'POST')
+ req:set_body(basexx.from_base64( -- servfail.test. A
+ 'FZUBAAABAAAAAAAACHNlcnZmYWlsBHRlc3QAAAEAAQ=='))
+ local headers, pkt = check_ok(req, desc)
+ if not (headers and pkt) then
+ return
+ end
+ -- uncacheable
+ same(headers:get('cache-control'), 'max-age=0', desc .. ': TTL 0')
+ same(pkt:rcode(), kres.rcode.SERVFAIL, desc .. ': rcode matches')
+ end
+
+ local function test_post_noerror()
+ local desc = 'valid POST query which ends with NOERROR'
+ local req = req_templ:clone()
+ req.headers:upsert(':method', 'POST')
+ req:set_body(basexx.from_base64( -- noerror.test. A
+ 'vMEBAAABAAAAAAAAB25vZXJyb3IEdGVzdAAAAQAB'))
+ local headers, pkt = check_ok(req, desc)
+ if not (headers and pkt) then
+ return
+ end
+ -- HTTP TTL is minimum from all RRs in the answer
+ same(headers:get('cache-control'), 'max-age=300', desc .. ': TTL 900')
+ same(pkt:rcode(), kres.rcode.NOERROR, desc .. ': rcode matches')
+ same(pkt:ancount(), 3, desc .. ': ANSWER is present')
+ same(pkt:nscount(), 1, desc .. ': AUTHORITY is present')
+ same(pkt:arcount(), 0, desc .. ': ADDITIONAL is empty')
+ end
+
+ local function test_post_nxdomain()
+ local desc = 'valid POST query which ends with NXDOMAIN'
+ local req = req_templ:clone()
+ req.headers:upsert(':method', 'POST')
+ req:set_body(basexx.from_base64( -- nxdomain.test. A
+ 'viABAAABAAAAAAAACG54ZG9tYWluBHRlc3QAAAEAAQ=='))
+ local headers, pkt = check_ok(req, desc)
+ if not (headers and pkt) then
+ return
+ end
+ same(headers:get('cache-control'), 'max-age=10800', desc .. ': TTL 10800')
+ same(pkt:rcode(), kres.rcode.NXDOMAIN, desc .. ': rcode matches')
+ same(pkt:nscount(), 1, desc .. ': AUTHORITY is present')
+ end
+
+ -- RFC 8484 section 6 explicitly allows huge answers over HTTP
+ local function test_huge_answer()
+ policy.add(policy.suffix(gen_huge_answer, policy.todnames({'huge.test'})))
+ local desc = 'POST query for a huge answer'
+ local req = req_templ:clone()
+ req.headers:upsert(':method', 'POST')
+ req:set_body(basexx.from_base64( -- huge.test. URI, no EDNS
+ 'HHwBAAABAAAAAAAABGh1Z2UEdGVzdAABAAAB'))
+ local _, pkt = check_ok(req, desc)
+ same(pkt:rcode(), kres.rcode.NOERROR, desc .. ': rcode NOERROR')
+ same(pkt:tc(), false, desc .. ': no TC bit')
+ same(pkt:ancount(), 2, desc .. ': ANSWER contains both RRs')
+ end
+
+ -- test an invalid DNS query using POST
+ local function test_post_short_input()
+ local req = assert(req_templ:clone())
+ req.headers:upsert(':method', 'POST')
+ req:set_body(string.rep('0', 11)) -- 11 bytes < DNS msg header
+ check_err(req, '400', 'too short POST finishes with 400')
+ end
+
+ local function test_post_long_input()
+ local req = assert(req_templ:clone())
+ req.headers:upsert(':method', 'POST')
+ req:set_body(string.rep('s', 1025)) -- > DNS msg over UDP
+ check_err(req, '413', 'too long POST finishes with 413')
+ end
+
+ local function test_post_unparseable_input()
+ local req = assert(req_templ:clone())
+ req.headers:upsert(':method', 'POST')
+ req:set_body(string.rep('\0', 1024)) -- garbage
+ check_err(req, '400', 'unparseable DNS message finishes with 400')
+ end
+
+ local function test_post_unsupp_type()
+ local req = assert(req_templ:clone())
+ req.headers:upsert(':method', 'POST')
+ req.headers:upsert('content-type', 'application/dns+json')
+ req:set_body(string.rep('\0', 12)) -- valid message
+ check_err(req, '415', 'unsupported request content type finishes with 415')
+ end
+
+ -- test a valid DNS query using GET
+ local function test_get_servfail()
+ local desc = 'valid GET query which ends with SERVFAIL'
+ local req = req_templ:clone()
+ req.headers:upsert(':method', 'GET')
+ req.headers:upsert(':path', '/doh?dns=' -- servfail.test. A
+ .. 'FZUBAAABAAAAAAAACHNlcnZmYWlsBHRlc3QAAAEAAQ')
+ local headers, pkt = check_ok(req, desc)
+ if not (headers and pkt) then
+ return
+ end
+ -- uncacheable
+ same(headers:get('cache-control'), 'max-age=0', desc .. ': TTL 0')
+ same(pkt:rcode(), kres.rcode.SERVFAIL, desc .. ': rcode matches')
+ end
+
+ local function test_get_noerror()
+ local desc = 'valid GET query which ends with NOERROR'
+ local req = req_templ:clone()
+ req.headers:upsert(':method', 'GET')
+ req.headers:upsert(':path', '/doh?dns=' -- noerror.test. A
+ .. 'vMEBAAABAAAAAAAAB25vZXJyb3IEdGVzdAAAAQAB')
+ local headers, pkt = check_ok(req, desc)
+ if not (headers and pkt) then
+ return
+ end
+ -- HTTP TTL is minimum from all RRs in the answer
+ same(headers:get('cache-control'), 'max-age=300', desc .. ': TTL 900')
+ same(pkt:rcode(), kres.rcode.NOERROR, desc .. ': rcode matches')
+ same(pkt:ancount(), 3, desc .. ': ANSWER is present')
+ same(pkt:nscount(), 1, desc .. ': AUTHORITY is present')
+ same(pkt:arcount(), 0, desc .. ': ADDITIONAL is empty')
+ end
+
+ local function test_get_nxdomain()
+ local desc = 'valid GET query which ends with NXDOMAIN'
+ local req = req_templ:clone()
+ req.headers:upsert(':method', 'GET')
+ req.headers:upsert(':path', '/doh?dns=' -- nxdomain.test. A
+ .. 'viABAAABAAAAAAAACG54ZG9tYWluBHRlc3QAAAEAAQ')
+ local headers, pkt = check_ok(req, desc)
+ if not (headers and pkt) then
+ return
+ end
+ same(headers:get('cache-control'), 'max-age=10800', desc .. ': TTL 10800')
+ same(pkt:rcode(), kres.rcode.NXDOMAIN, desc .. ': rcode matches')
+ same(pkt:nscount(), 1, desc .. ': AUTHORITY is present')
+ end
+
+ local function test_get_other_params_before_dns()
+ local desc = 'GET query with other parameters before dns is valid'
+ local req = req_templ:clone()
+ req.headers:upsert(':method', 'GET')
+ req.headers:upsert(':path',
+ '/doh?other=something&another=something&dns=vMEBAAABAAAAAAAAB25vZXJyb3IEdGVzdAAAAQAB')
+ check_ok(req, desc)
+ end
+
+ local function test_get_other_params_after_dns()
+ local desc = 'GET query with other parameters after dns is valid'
+ local req = req_templ:clone()
+ req.headers:upsert(':method', 'GET')
+ req.headers:upsert(':path',
+ '/doh?dns=vMEBAAABAAAAAAAAB25vZXJyb3IEdGVzdAAAAQAB&other=something&another=something')
+ check_ok(req, desc)
+ end
+
+ local function test_get_other_params()
+ local desc = 'GET query with other parameters than dns on both sides is valid'
+ local req = req_templ:clone()
+ req.headers:upsert(':method', 'GET')
+ req.headers:upsert(':path',
+ '/doh?other=something&dns=vMEBAAABAAAAAAAAB25vZXJyb3IEdGVzdAAAAQAB&another=something')
+ check_ok(req, desc)
+ end
+
+ -- test an invalid DNS query using GET
+ local function test_get_long_input()
+ local req = assert(req_templ:clone())
+ req.headers:upsert(':method', 'GET')
+ req.headers:upsert(':path', '/doh?dns=' .. basexx.to_url64(string.rep('\0', 1030)))
+ check_err(req, '414', 'too long GET finishes with 414')
+ end
+
+ local function test_get_no_dns_param()
+ local req = assert(req_templ:clone())
+ req.headers:upsert(':method', 'GET')
+ req.headers:upsert(':path', '/doh?notdns=' .. basexx.to_url64(string.rep('\0', 1024)))
+ check_err(req, '400', 'GET without dns parameter finishes with 400')
+ end
+
+ local function test_get_unparseable()
+ local req = assert(req_templ:clone())
+ req.headers:upsert(':method', 'GET')
+ req.headers:upsert(':path', '/doh??dns=' .. basexx.to_url64(string.rep('\0', 1024)))
+ check_err(req, '400', 'unparseable GET finishes with 400')
+ end
+
+ local function test_get_invalid_b64()
+ local req = assert(req_templ:clone())
+ req.headers:upsert(':method', 'GET')
+ req.headers:upsert(':path', '/doh?dns=thisisnotb64')
+ check_err(req, '400', 'GET with invalid base64 finishes with 400')
+ end
+
+ local function test_get_invalid_chars()
+ local req = assert(req_templ:clone())
+ req.headers:upsert(':method', 'GET')
+ req.headers:upsert(':path', '/doh?dns=' .. basexx.to_url64(string.rep('\0', 200)) .. '@#$%?!')
+ check_err(req, '400', 'GET with invalid characters in b64 finishes with 400')
+ end
+
+ local function test_unsupp_method()
+ local req = assert(req_templ:clone())
+ req.headers:upsert(':method', 'PUT')
+ check_err(req, '405', 'unsupported method finishes with 405')
+ end
+
+ local function test_dstaddr()
+ local triggered = false
+ local exp_dstaddr = ffi.gc(ffi.C.kr_straddr_socket(host, port, nil), ffi.C.free)
+ local function check_dstaddr(state, req)
+ triggered = true
+ same(ffi.C.kr_sockaddr_cmp(req.qsource.dst_addr, exp_dstaddr), 0,
+ 'request has correct server address')
+ return state
+ end
+ policy.add(policy.suffix(check_dstaddr, policy.todnames({'dstaddr.test'})))
+ local desc = 'valid POST query has server address available in request'
+ local req = req_templ:clone()
+ req.headers:upsert(':method', 'POST')
+ req:set_body(basexx.from_base64( -- dstaddr.test. A
+ 'FnkBAAABAAAAAAAAB2RzdGFkZHIEdGVzdAAAAQAB'))
+ check_ok(req, desc)
+ ok(triggered, 'dstaddr policy was triggered')
+ end
+
+ local function test_srcaddr()
+ modules.load('view')
+ assert(view)
+ local policy_refuse = policy.suffix(policy.REFUSE, policy.todnames({'srcaddr.test.knot-resolver.cz'}))
+ -- these netmasks would not work if the request did not contain IP addresses
+ view:addr('0.0.0.0/0', policy_refuse)
+ view:addr('::/0', policy_refuse)
+
+ local desc = 'valid POST query has source address available in request'
+ local req = req_templ:clone()
+ req.headers:upsert(':method', 'POST')
+ req:set_body(basexx.from_base64( -- srcaddr.test.knot-resolver.cz TXT
+ 'QNQBAAABAAAAAAAAB3NyY2FkZHIEdGVzdA1rbm90LXJlc29sdmVyAmN6AAAQAAE'))
+ local _, pkt = check_ok(req, desc)
+ same(pkt:rcode(), kres.rcode.REFUSED, desc .. ': view module caught it')
+
+ modules.unload('view')
+ end
+
+ local function test_dns_query_endpoint()
+ local desc = 'valid POST query which ends with SERVFAIL on /dns-query'
+ local request = require('http.request')
+ uri_templ = string.format('http://%s:%d/dns-query', host, port)
+ req = assert(request.new_from_uri(uri_templ))
+ req.headers:upsert('content-type', 'application/dns-message')
+ req.headers:upsert(':method', 'POST')
+ req:set_body(basexx.from_base64( -- servfail.test. A
+ 'FZUBAAABAAAAAAAACHNlcnZmYWlsBHRlc3QAAAEAAQ=='))
+ local headers, pkt = check_ok(req, desc)
+ if not (headers and pkt) then
+ return
+ end
+ -- uncacheable
+ same(headers:get('cache-control'), 'max-age=0', desc .. ': TTL 0')
+ same(pkt:rcode(), kres.rcode.SERVFAIL, desc .. ': rcode matches')
+ end
+
+-- not implemented
+-- local function test_post_unsupp_accept()
+-- local req = assert(req_templ:clone())
+-- req.headers:upsert(':method', 'POST')
+-- req.headers:upsert('accept', 'application/dns+json')
+-- req:set_body(string.rep('\0', 12)) -- valid message
+-- check_err(req, '406', 'unsupported Accept type finishes with 406')
+-- end
+
+ -- plan tests
+ local tests = {
+ start_server,
+ test_post_servfail,
+ test_post_noerror,
+ test_post_nxdomain,
+ test_huge_answer,
+ test_post_short_input,
+ test_post_long_input,
+ test_post_unparseable_input,
+ test_post_unsupp_type,
+ test_get_servfail,
+ test_get_noerror,
+ test_get_nxdomain,
+ test_get_other_params_before_dns,
+ test_get_other_params_after_dns,
+ test_get_other_params,
+ test_get_long_input,
+ test_get_no_dns_param,
+ test_get_unparseable,
+ test_get_invalid_b64,
+ test_get_invalid_chars,
+ test_unsupp_method,
+ test_dstaddr,
+ test_srcaddr,
+ test_dns_query_endpoint,
+ }
+
+ return tests
+end
diff --git a/modules/http/http_tls_cert.lua b/modules/http/http_tls_cert.lua
new file mode 100644
index 0000000..7e557c4
--- /dev/null
+++ b/modules/http/http_tls_cert.lua
@@ -0,0 +1,186 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+--[[
+ Conventions:
+ - key = private+public key-pair in openssl.pkey format
+ - certs = lua list of certificates (at least one), each in openssl.x509 format,
+ ordered from leaf to almost-root
+ - panic('...') is used on bad problems instead of returning nils or such
+--]]
+local tls_cert = {}
+
+local ffi = require('ffi')
+local x509, pkey = require('openssl.x509'), require('openssl.pkey')
+
+-- @function Create self-signed certificate; return certs, key
+local function new_ephemeral(host)
+ -- Import luaossl directly
+ local name = require('openssl.x509.name')
+ local altname = require('openssl.x509.altname')
+ local openssl_bignum = require('openssl.bignum')
+ local openssl_rand = require('openssl.rand')
+ -- Create self-signed certificate
+ host = host or hostname()
+ local crt = x509.new()
+ local now = os.time()
+ crt:setVersion(3)
+ -- serial needs to be unique or browsers will show uninformative error messages
+ crt:setSerial(openssl_bignum.fromBinary(openssl_rand.bytes(16)))
+ -- use the host we're listening on as canonical name
+ local dn = name.new()
+ dn:add("CN", host)
+ crt:setSubject(dn)
+ crt:setIssuer(dn) -- should match subject for a self-signed
+ local alt = altname.new()
+ alt:add("DNS", host)
+ crt:setSubjectAlt(alt)
+ -- Valid for 90 days
+ crt:setLifetime(now, now + 90*60*60*24)
+ -- Can't be used as a CA
+ crt:setBasicConstraints{CA=false}
+ crt:setBasicConstraintsCritical(true)
+ -- Create and set key (default: EC/P-256 as a most "interoperable")
+ local key = pkey.new {type = 'EC', curve = 'prime256v1'}
+ crt:setPublicKey(key)
+ crt:sign(key)
+ return { crt }, key
+end
+
+-- @function Write certs and key to files
+local function write_cert_files(certs, key, certfile, keyfile)
+ -- Write certs
+ local f = assert(io.open(certfile, 'w'), string.format('cannot open "%s" for writing', certfile))
+ for _, cert in ipairs(certs) do
+ f:write(tostring(cert))
+ end
+ f:close()
+ -- Write key as a pair
+ f = assert(io.open(keyfile, 'w'), string.format('cannot open "%s" for writing', keyfile))
+ local pub, priv = key:toPEM('public', 'private')
+ assert(f:write(pub .. priv))
+ f:close()
+end
+
+-- @function Start maintenance of a self-signed TLS context (at ephem_state.ctx).
+-- Keep updating the ephem_state.servers table. Stop updating by calling _destroy().
+-- TODO: each process maintains its own ephemeral cert ATM, and the files aren't ever read from.
+function tls_cert.ephemeral_state_maintain(ephem_state, certfile, keyfile)
+ local certs, key = new_ephemeral()
+ write_cert_files(certs, key, certfile, keyfile)
+ ephem_state.ctx = tls_cert.new_tls_context(certs, key)
+ -- Each server needs to have its ctx updated.
+ for _, s in pairs(ephem_state.servers) do
+ s.server.ctx = ephem_state.ctx
+ s.config.ctx = ephem_state.ctx -- not required, but let's keep it synchronized
+ end
+ log_info(ffi.C.LOG_GRP_HTTP, 'created new ephemeral TLS certificate')
+ local _, expiry_stamp = certs[1]:getLifetime()
+ local wait_msec = 1000 * math.max(1, expiry_stamp - os.time() - 3 * 24 * 3600)
+ if not ephem_state.timer_id then
+ ephem_state.timer_id = event.after(wait_msec, function ()
+ tls_cert.ephemeral_state_maintain(ephem_state, certfile, keyfile)
+ end)
+ else
+ event.reschedule(ephem_state.timer_id, wait_msec)
+ end
+end
+function tls_cert.ephemeral_state_destroy(ephem_state)
+ if ephem_state and ephem_state.timer_id then
+ event.cancel(ephem_state.timer_id)
+ end
+end
+
+-- @function Read a certificate chain and a key from files; return certs, key
+function tls_cert.load(certfile, keyfile)
+ -- get key
+ local f, err = io.open(keyfile, 'r')
+ if not f then
+ panic('[http] unable to open TLS key file: %s', err)
+ end
+ local key = pkey.new(f:read('*all'))
+ f:close()
+ if not key then
+ panic('[http] unable to parse TLS key file %s', keyfile)
+ end
+
+ -- get certs list
+ local certs = {}
+ local f, err = io.open(certfile, 'r')
+ if not f then
+ panic('[http] unable to read TLS certificate file: %s', err)
+ end
+ while true do
+ -- Get the next "block" = single certificate as PEM string.
+ local block = nil
+ local line
+ repeat
+ line = f:read()
+ if not line then break end
+ if block then
+ block = block .. '\n' .. line
+ else
+ block = line
+ end
+ -- separator: "posteb" in https://tools.ietf.org/html/rfc7468#section-3
+ until string.sub(line, 1, 9) == '-----END '
+ -- Empty block means clean EOF.
+ if not block then break end
+ if not line then
+ panic('[http] unable to parse TLS certificate file %s, certificate number %d', certfile, 1 + #certs)
+ end
+
+ -- Parse the cert and append to the list.
+ local cert = x509.new(block, 'PEM')
+ if not cert then
+ panic('[http] unable to parse TLS certificate file %s, certificate number %d', certfile, 1 + #certs)
+ end
+ table.insert(certs, cert)
+ end
+ f:close()
+
+ return certs, key
+end
+
+
+-- @function Prefer HTTP/2 or HTTP/1.1
+local function alpnselect(_, protos)
+ for _, proto in ipairs(protos) do
+ if proto == 'h2' or proto == 'http/1.1' then
+ return proto
+ end
+ end
+ return nil
+end
+
+local warned_old_luaossl = false
+
+-- @function Return a new TLS context for a server.
+function tls_cert.new_tls_context(certs, key)
+ local ctx = require('http.tls').new_server_context()
+ if ctx.setAlpnSelect then
+ ctx:setAlpnSelect(alpnselect)
+ end
+ assert(ctx:setPrivateKey(key))
+ assert(ctx:setCertificate(certs[1]))
+
+ -- Set up certificate chain to be sent, if required and possible.
+ if #certs == 1 then return ctx end
+ if ctx.setCertificateChain then
+ local chain = require('openssl.x509.chain').new()
+ assert(chain)
+ for i = 2, #certs do
+ chain:add(certs[i])
+ assert(chain)
+ end
+ assert(ctx:setCertificateChain(chain))
+ elseif not warned_old_luaossl then
+ -- old luaossl version -> only final cert sent to clients
+ log_warn(ffi.C.LOG_GRP_HTTP,
+ 'need luaossl >= 20181207 to support sending intermediary certificate to clients')
+ warned_old_luaossl = true
+ end
+ return ctx
+end
+
+
+return tls_cert
+
diff --git a/modules/http/http_trace.lua b/modules/http/http_trace.lua
new file mode 100644
index 0000000..123cd52
--- /dev/null
+++ b/modules/http/http_trace.lua
@@ -0,0 +1,77 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+local ffi = require('ffi')
+local condition = require('cqueues.condition')
+
+-- Trace execution of DNS queries
+local function serve_trace(h, _)
+ local path = h:get(':path')
+ local qname, qtype_str = path:match('/trace/([^/]+)/?([^/]*)')
+ if not qname then
+ return 400, 'expected /trace/<query name>/<query type>'
+ end
+
+ -- Parse query type (or default to A)
+ if not qtype_str or #qtype_str == 0 then
+ qtype_str = 'A'
+ end
+
+ local qtype = kres.type[qtype_str]
+ if not qtype then
+ return 400, string.format('unexpected query type: %s', qtype_str)
+ end
+
+ -- Create logging handler callback
+ local buffer = {}
+ local buffer_log_cb = ffi.cast('trace_log_f', function (_, msg)
+ jit.off(true, true) -- JIT for (C -> lua)^2 nesting isn't allowed
+ table.insert(buffer, ffi.string(msg))
+ end)
+
+ -- Wait for the result of the query
+ -- Note: We can't do non-blocking write to stream directly from resolve callbacks
+ -- because they don't run inside cqueue.
+ local cond = condition.new()
+ local waiting, done = false, false
+ local finish_cb = ffi.cast('trace_callback_f', function (req)
+ jit.off(true, true) -- JIT for (C -> lua)^2 nesting isn't allowed
+ table.insert(buffer, req:selected_tostring())
+ if waiting then
+ cond:signal()
+ end
+ done = true
+ end)
+
+ -- Resolve query and buffer logs into table
+ resolve {
+ name = qname,
+ type = qtype,
+ options = {'TRACE'},
+ init = function (req)
+ req:trace_chain_callbacks(buffer_log_cb, finish_cb)
+ end
+ }
+
+ -- Wait for asynchronous query and free callbacks
+ if not done then
+ waiting = true
+ cond:wait()
+ end
+
+ buffer_log_cb:free()
+ finish_cb:free()
+
+ -- Build the result
+ local result = table.concat(buffer, '')
+ -- Return buffered data
+ if not done then
+ return 504, result
+ end
+ return result
+end
+
+-- Export endpoints
+return {
+ endpoints = {
+ ['/trace'] = {'text/plain', serve_trace},
+ }
+}
diff --git a/modules/http/meson.build b/modules/http/meson.build
new file mode 100644
index 0000000..6705143
--- /dev/null
+++ b/modules/http/meson.build
@@ -0,0 +1,61 @@
+# LUA module: http
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+lua_http_config = configuration_data()
+lua_http_config.set('modules_dir', modules_dir)
+
+lua_http = configure_file(
+ input: 'http.lua.in',
+ output: 'http.lua',
+ configuration: lua_http_config,
+)
+
+lua_mod_src += [
+ lua_http,
+ files('http_doh.lua'),
+ files('http_trace.lua'),
+ files('http_tls_cert.lua'),
+ files('prometheus.lua'),
+]
+
+config_tests += [
+ ['http', files('http.test.lua')],
+ ['http.doh', files('http_doh.test.lua')],
+ ['http.tls', files('test_tls/tls.test.lua')],
+]
+
+# install static files
+install_subdir(
+ 'static',
+ strip_directory: true,
+ exclude_files: [
+ 'bootstrap.min.css.spdx',
+ 'bootstrap.min.js.spdx',
+ 'bootstrap-theme.min.css.spdx',
+ 'datamaps.world.min.spdx',
+ 'dygraph.min.js.spdx',
+ 'd3.spdx',
+ 'epoch.spdx',
+ 'glyphicons-halflings-regular.spdx',
+ 'jquery.spdx',
+ 'selectize.spdx',
+ 'topojson.spdx',
+ ],
+ install_dir: modules_dir / 'http',
+)
+
+# auxiliary debug library for HTTP module
+if openssl.found()
+ debug_opensslkeylog_mod = shared_module(
+ 'debug_opensslkeylog',
+ ['debug_opensslkeylog.c'],
+ # visibility=default == public is required for LD_PRELOAD trick
+ c_args: '-fvisibility=default',
+ name_prefix: '',
+ install: true,
+ install_dir: lib_dir,
+ dependencies: [
+ openssl,
+ ],
+ )
+endif
diff --git a/modules/http/prometheus.lua b/modules/http/prometheus.lua
new file mode 100644
index 0000000..3218552
--- /dev/null
+++ b/modules/http/prometheus.lua
@@ -0,0 +1,178 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+-- Module implementation
+local M = {
+ namespace = '',
+ finalize = function (_ --[[metrics]]) end,
+}
+
+-- Gauge metrics
+local gauges = {
+ ['worker.concurrent'] = true,
+ ['worker.rss'] = true,
+}
+
+local function merge(t, results, prefix)
+ for _, result in pairs(results) do
+ if type(result) == 'table' then
+ for k, v in pairs(result) do
+ local val = t[prefix..k]
+ t[prefix..k] = (val or 0) + v
+ end
+ end
+ end
+end
+
+local function getstats()
+ local t = {}
+ merge(t, map 'stats.list()', '')
+ merge(t, map 'cache.stats()', 'cache.')
+ merge(t, map 'worker.stats()', 'worker.')
+ return t
+end
+
+-- @returns current stats + difference against previous data set passed in @param prev
+local function snapshot_start(prev)
+ assert(type(prev) == 'table', 'table with previous values expected')
+ local is_empty = true
+ -- Get current snapshot
+ local cur, stats_dt = getstats(), {}
+ for k,v in pairs(cur) do
+ if gauges[k] then
+ stats_dt[k] = v
+ else
+ stats_dt[k] = v - (prev[k] or 0)
+ end
+ is_empty = is_empty and stats_dt[k] == 0
+ end
+ -- Calculate upstreams and geotag them if possible
+ local upstreams
+ if http.geoip then
+ upstreams = stats.upstreams()
+ for k,v in pairs(upstreams) do
+ local gi
+ if string.find(k, '.', 1, true) then
+ gi = http.geoip:search_ipv4(k)
+ else
+ gi = http.geoip:search_ipv6(k)
+ end
+ if gi then
+ upstreams[k] = {data=v, location=gi.location, country=gi.country and gi.country.iso_code}
+ end
+ end
+ end
+ -- Aggregate per-worker metrics
+ local wdata = {}
+ for _, info in pairs(map 'worker.info()') do
+ if type(info) == 'table' then
+ wdata[tostring(info.pid)] = {
+ rss = info.rss,
+ usertime = info.usertime,
+ systime = info.systime,
+ pagefaults = info.pagefaults,
+ queries = info.queries
+ }
+ end
+ end
+ -- Publish stats updates periodically
+ if not is_empty then
+ local update = {time=os.time(), stats=stats_dt, upstreams=upstreams, workers=wdata}
+ return cur, update
+ end
+ return cur, nil
+end
+
+-- Function to sort frequency list
+local function stream_stats(_, ws)
+ local ok = true
+ -- Publish stats updates periodically
+ local prev = getstats()
+ while ok do
+ worker.sleep(1)
+ local update
+ prev, update = snapshot_start(prev)
+ local push = tojson(update)
+ ok = ws:send(push)
+ end
+end
+
+-- Transform metrics from Graphite to Prometheus format
+-- See: https://gitlab.nic.cz/knot/knot-resolver/-/issues/650
+-- E.g.:
+-- worker.ipv4 -> worker_ipv4
+-- answer.blocked;stype=A -> answer_blocked{stype="A"}
+local function get_metric(key)
+ local key_index, key_len, key_tag = 0, #key, 0
+ return select(1, key:gsub('.', function (c)
+ key_index = key_index + 1
+ if key_tag == 0 then
+ if c == '.' then return '_' end
+ if c == ';' then key_tag = 1; return '{' end
+ elseif key_tag == 1 then
+ if key_index == key_len then
+ if c == '=' then return '=""}'
+ else return c .. '"}' end
+ end
+ if c == '=' then key_tag = 2; return '="' end
+ elseif key_tag == 2 then
+ if key_index == key_len then
+ if c == ';' then return '"}'
+ else return c .. '"}' end
+ end
+ if c == ';' then key_tag = 1; return '",' end
+ end
+ return nil
+ end))
+end
+
+-- Render stats in Prometheus text format
+local function serve_prometheus()
+ -- First aggregate metrics list and print counters
+ local slist, render = getstats(), {}
+ local latency = {}
+ local counter = '# TYPE %s counter\n%s %f'
+ for k,v in pairs(slist) do
+ k = get_metric(k)
+ -- Aggregate histograms
+ local band = k:match('answer_([%d]+)ms')
+ if band then
+ table.insert(latency, {band, v})
+ elseif k == 'answer_slow' then
+ table.insert(latency, {'+Inf', v})
+ -- Counter as a fallback
+ else
+ local key = M.namespace .. k
+ local name, label = key:match('^([^{]+)(.*)$')
+ table.insert(render, string.format(counter, name, name .. label, v))
+ end
+ end
+ -- Fill in latency histogram
+ local function kweight(x) return tonumber(x) or math.huge end
+ table.sort(latency, function (a,b) return kweight(a[1]) < kweight(b[1]) end)
+ table.insert(render, string.format('# TYPE %slatency histogram', M.namespace))
+ local count, sum = 0.0, 0.0
+ for _,e in ipairs(latency) do
+ -- The information about the %Inf bin is lost, so we treat it
+ -- as a timeout (3000ms) for metrics purposes
+ count = count + e[2]
+ sum = sum + e[2] * (math.min(tonumber(e[1]), 3000.0))
+ table.insert(render, string.format('%slatency_bucket{le="%s"} %f', M.namespace, e[1], count))
+ end
+ table.insert(render, string.format('%slatency_count %f', M.namespace, count))
+ table.insert(render, string.format('%slatency_sum %f', M.namespace, sum))
+ -- Finalize metrics table before rendering
+ if type(M.finalize) == 'function' then
+ M.finalize(render)
+ end
+ return table.concat(render, '\n') .. '\n'
+end
+
+-- Export module interface
+M.endpoints = {
+ ['/stats'] = {'application/json', getstats, stream_stats},
+ ['/frequent'] = {'application/json', function () return stats.frequent() end},
+ ['/upstreams'] = {'application/json', function () return stats.upstreams() end},
+ ['/bogus'] = {'application/json', function () return bogus_log.frequent() end},
+ ['/metrics'] = {'text/plain; version=0.0.4', serve_prometheus},
+}
+
+return M
diff --git a/modules/http/prometheus.rst b/modules/http/prometheus.rst
new file mode 100644
index 0000000..acd8a82
--- /dev/null
+++ b/modules/http/prometheus.rst
@@ -0,0 +1,45 @@
+.. SPDX-License-Identifier: GPL-3.0-or-later
+
+.. _mod-http-prometheus:
+
+Prometheus metrics endpoint
+---------------------------
+
+The :ref:`HTTP module <mod-http>` exposes ``/metrics`` endpoint that serves metrics
+from :ref:`mod-stats` in Prometheus_ text format.
+You can use it as soon as HTTP module is configured:
+
+.. code-block:: bash
+
+ $ curl -k https://localhost:8453/metrics | tail
+ # TYPE latency histogram
+ latency_bucket{le=10} 2.000000
+ latency_bucket{le=50} 2.000000
+ latency_bucket{le=100} 2.000000
+ latency_bucket{le=250} 2.000000
+ latency_bucket{le=500} 2.000000
+ latency_bucket{le=1000} 2.000000
+ latency_bucket{le=1500} 2.000000
+ latency_bucket{le=+Inf} 2.000000
+ latency_count 2.000000
+ latency_sum 11.000000
+
+You can namespace the metrics in configuration, using `http.prometheus.namespace` attribute:
+
+.. code-block:: lua
+
+ modules.load('http')
+ -- Set Prometheus namespace
+ http.prometheus.namespace = 'resolver_'
+
+You can also add custom metrics or rewrite existing metrics before they are returned to Prometheus client.
+
+.. code-block:: lua
+
+ modules.load('http')
+ -- Add an arbitrary metric to Prometheus
+ http.prometheus.finalize = function (metrics)
+ table.insert(metrics, 'build_info{version="1.2.3"} 1')
+ end
+
+.. _Prometheus: https://prometheus.io
diff --git a/modules/http/static/bootstrap-theme.min.css b/modules/http/static/bootstrap-theme.min.css
new file mode 100644
index 0000000..449915d
--- /dev/null
+++ b/modules/http/static/bootstrap-theme.min.css
@@ -0,0 +1,6 @@
+/*!
+ * Bootstrap v3.3.6 (http://getbootstrap.com)
+ * Copyright 2011-2015 Twitter, Inc.
+ * SPDX-License-Identifier: MIT
+ */.btn-danger,.btn-default,.btn-info,.btn-primary,.btn-success,.btn-warning{text-shadow:0 -1px 0 rgba(0,0,0,.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 1px rgba(0,0,0,.075)}.btn-danger.active,.btn-danger:active,.btn-default.active,.btn-default:active,.btn-info.active,.btn-info:active,.btn-primary.active,.btn-primary:active,.btn-success.active,.btn-success:active,.btn-warning.active,.btn-warning:active{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-danger.disabled,.btn-danger[disabled],.btn-default.disabled,.btn-default[disabled],.btn-info.disabled,.btn-info[disabled],.btn-primary.disabled,.btn-primary[disabled],.btn-success.disabled,.btn-success[disabled],.btn-warning.disabled,.btn-warning[disabled],fieldset[disabled] .btn-danger,fieldset[disabled] .btn-default,fieldset[disabled] .btn-info,fieldset[disabled] .btn-primary,fieldset[disabled] .btn-success,fieldset[disabled] .btn-warning{-webkit-box-shadow:none;box-shadow:none}.btn-danger .badge,.btn-default .badge,.btn-info .badge,.btn-primary .badge,.btn-success .badge,.btn-warning .badge{text-shadow:none}.btn.active,.btn:active{background-image:none}.btn-default{text-shadow:0 1px 0 #fff;background-image:-webkit-linear-gradient(top,#fff 0,#e0e0e0 100%);background-image:-o-linear-gradient(top,#fff 0,#e0e0e0 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#e0e0e0));background-image:linear-gradient(to bottom,#fff 0,#e0e0e0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#dbdbdb;border-color:#ccc}.btn-default:focus,.btn-default:hover{background-color:#e0e0e0;background-position:0 -15px}.btn-default.active,.btn-default:active{background-color:#e0e0e0;border-color:#dbdbdb}.btn-default.disabled,.btn-default.disabled.active,.btn-default.disabled.focus,.btn-default.disabled:active,.btn-default.disabled:focus,.btn-default.disabled:hover,.btn-default[disabled],.btn-default[disabled].active,.btn-default[disabled].focus,.btn-default[disabled]:active,.btn-default[disabled]:focus,.btn-default[disabled]:hover,fieldset[disabled] .btn-default,fieldset[disabled] .btn-default.active,fieldset[disabled] .btn-default.focus,fieldset[disabled] .btn-default:active,fieldset[disabled] .btn-default:focus,fieldset[disabled] .btn-default:hover{background-color:#e0e0e0;background-image:none}.btn-primary{background-image:-webkit-linear-gradient(top,#337ab7 0,#265a88 100%);background-image:-o-linear-gradient(top,#337ab7 0,#265a88 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#265a88));background-image:linear-gradient(to bottom,#337ab7 0,#265a88 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff265a88', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#245580}.btn-primary:focus,.btn-primary:hover{background-color:#265a88;background-position:0 -15px}.btn-primary.active,.btn-primary:active{background-color:#265a88;border-color:#245580}.btn-primary.disabled,.btn-primary.disabled.active,.btn-primary.disabled.focus,.btn-primary.disabled:active,.btn-primary.disabled:focus,.btn-primary.disabled:hover,.btn-primary[disabled],.btn-primary[disabled].active,.btn-primary[disabled].focus,.btn-primary[disabled]:active,.btn-primary[disabled]:focus,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary,fieldset[disabled] .btn-primary.active,fieldset[disabled] .btn-primary.focus,fieldset[disabled] .btn-primary:active,fieldset[disabled] .btn-primary:focus,fieldset[disabled] .btn-primary:hover{background-color:#265a88;background-image:none}.btn-success{background-image:-webkit-linear-gradient(top,#5cb85c 0,#419641 100%);background-image:-o-linear-gradient(top,#5cb85c 0,#419641 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5cb85c),to(#419641));background-image:linear-gradient(to bottom,#5cb85c 0,#419641 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#3e8f3e}.btn-success:focus,.btn-success:hover{background-color:#419641;background-position:0 -15px}.btn-success.active,.btn-success:active{background-color:#419641;border-color:#3e8f3e}.btn-success.disabled,.btn-success.disabled.active,.btn-success.disabled.focus,.btn-success.disabled:active,.btn-success.disabled:focus,.btn-success.disabled:hover,.btn-success[disabled],.btn-success[disabled].active,.btn-success[disabled].focus,.btn-success[disabled]:active,.btn-success[disabled]:focus,.btn-success[disabled]:hover,fieldset[disabled] .btn-success,fieldset[disabled] .btn-success.active,fieldset[disabled] .btn-success.focus,fieldset[disabled] .btn-success:active,fieldset[disabled] .btn-success:focus,fieldset[disabled] .btn-success:hover{background-color:#419641;background-image:none}.btn-info{background-image:-webkit-linear-gradient(top,#5bc0de 0,#2aabd2 100%);background-image:-o-linear-gradient(top,#5bc0de 0,#2aabd2 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5bc0de),to(#2aabd2));background-image:linear-gradient(to bottom,#5bc0de 0,#2aabd2 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#28a4c9}.btn-info:focus,.btn-info:hover{background-color:#2aabd2;background-position:0 -15px}.btn-info.active,.btn-info:active{background-color:#2aabd2;border-color:#28a4c9}.btn-info.disabled,.btn-info.disabled.active,.btn-info.disabled.focus,.btn-info.disabled:active,.btn-info.disabled:focus,.btn-info.disabled:hover,.btn-info[disabled],.btn-info[disabled].active,.btn-info[disabled].focus,.btn-info[disabled]:active,.btn-info[disabled]:focus,.btn-info[disabled]:hover,fieldset[disabled] .btn-info,fieldset[disabled] .btn-info.active,fieldset[disabled] .btn-info.focus,fieldset[disabled] .btn-info:active,fieldset[disabled] .btn-info:focus,fieldset[disabled] .btn-info:hover{background-color:#2aabd2;background-image:none}.btn-warning{background-image:-webkit-linear-gradient(top,#f0ad4e 0,#eb9316 100%);background-image:-o-linear-gradient(top,#f0ad4e 0,#eb9316 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f0ad4e),to(#eb9316));background-image:linear-gradient(to bottom,#f0ad4e 0,#eb9316 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#e38d13}.btn-warning:focus,.btn-warning:hover{background-color:#eb9316;background-position:0 -15px}.btn-warning.active,.btn-warning:active{background-color:#eb9316;border-color:#e38d13}.btn-warning.disabled,.btn-warning.disabled.active,.btn-warning.disabled.focus,.btn-warning.disabled:active,.btn-warning.disabled:focus,.btn-warning.disabled:hover,.btn-warning[disabled],.btn-warning[disabled].active,.btn-warning[disabled].focus,.btn-warning[disabled]:active,.btn-warning[disabled]:focus,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning,fieldset[disabled] .btn-warning.active,fieldset[disabled] .btn-warning.focus,fieldset[disabled] .btn-warning:active,fieldset[disabled] .btn-warning:focus,fieldset[disabled] .btn-warning:hover{background-color:#eb9316;background-image:none}.btn-danger{background-image:-webkit-linear-gradient(top,#d9534f 0,#c12e2a 100%);background-image:-o-linear-gradient(top,#d9534f 0,#c12e2a 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9534f),to(#c12e2a));background-image:linear-gradient(to bottom,#d9534f 0,#c12e2a 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#b92c28}.btn-danger:focus,.btn-danger:hover{background-color:#c12e2a;background-position:0 -15px}.btn-danger.active,.btn-danger:active{background-color:#c12e2a;border-color:#b92c28}.btn-danger.disabled,.btn-danger.disabled.active,.btn-danger.disabled.focus,.btn-danger.disabled:active,.btn-danger.disabled:focus,.btn-danger.disabled:hover,.btn-danger[disabled],.btn-danger[disabled].active,.btn-danger[disabled].focus,.btn-danger[disabled]:active,.btn-danger[disabled]:focus,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger,fieldset[disabled] .btn-danger.active,fieldset[disabled] .btn-danger.focus,fieldset[disabled] .btn-danger:active,fieldset[disabled] .btn-danger:focus,fieldset[disabled] .btn-danger:hover{background-color:#c12e2a;background-image:none}.img-thumbnail,.thumbnail{-webkit-box-shadow:0 1px 2px rgba(0,0,0,.075);box-shadow:0 1px 2px rgba(0,0,0,.075)}.dropdown-menu>li>a:focus,.dropdown-menu>li>a:hover{background-color:#e8e8e8;background-image:-webkit-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-o-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#e8e8e8));background-image:linear-gradient(to bottom,#f5f5f5 0,#e8e8e8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);background-repeat:repeat-x}.dropdown-menu>.active>a,.dropdown-menu>.active>a:focus,.dropdown-menu>.active>a:hover{background-color:#2e6da4;background-image:-webkit-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2e6da4));background-image:linear-gradient(to bottom,#337ab7 0,#2e6da4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);background-repeat:repeat-x}.navbar-default{background-image:-webkit-linear-gradient(top,#fff 0,#f8f8f8 100%);background-image:-o-linear-gradient(top,#fff 0,#f8f8f8 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#f8f8f8));background-image:linear-gradient(to bottom,#fff 0,#f8f8f8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-radius:4px;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 5px rgba(0,0,0,.075);box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 5px rgba(0,0,0,.075)}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.open>a{background-image:-webkit-linear-gradient(top,#dbdbdb 0,#e2e2e2 100%);background-image:-o-linear-gradient(top,#dbdbdb 0,#e2e2e2 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#dbdbdb),to(#e2e2e2));background-image:linear-gradient(to bottom,#dbdbdb 0,#e2e2e2 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdbdbdb', endColorstr='#ffe2e2e2', GradientType=0);background-repeat:repeat-x;-webkit-box-shadow:inset 0 3px 9px rgba(0,0,0,.075);box-shadow:inset 0 3px 9px rgba(0,0,0,.075)}.navbar-brand,.navbar-nav>li>a{text-shadow:0 1px 0 rgba(255,255,255,.25)}.navbar-inverse{background-image:-webkit-linear-gradient(top,#3c3c3c 0,#222 100%);background-image:-o-linear-gradient(top,#3c3c3c 0,#222 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#3c3c3c),to(#222));background-image:linear-gradient(to bottom,#3c3c3c 0,#222 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-radius:4px}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.open>a{background-image:-webkit-linear-gradient(top,#080808 0,#0f0f0f 100%);background-image:-o-linear-gradient(top,#080808 0,#0f0f0f 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#080808),to(#0f0f0f));background-image:linear-gradient(to bottom,#080808 0,#0f0f0f 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff080808', endColorstr='#ff0f0f0f', GradientType=0);background-repeat:repeat-x;-webkit-box-shadow:inset 0 3px 9px rgba(0,0,0,.25);box-shadow:inset 0 3px 9px rgba(0,0,0,.25)}.navbar-inverse .navbar-brand,.navbar-inverse .navbar-nav>li>a{text-shadow:0 -1px 0 rgba(0,0,0,.25)}.navbar-fixed-bottom,.navbar-fixed-top,.navbar-static-top{border-radius:0}@media (max-width:767px){.navbar .navbar-nav .open .dropdown-menu>.active>a,.navbar .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar .navbar-nav .open .dropdown-menu>.active>a:hover{color:#fff;background-image:-webkit-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2e6da4));background-image:linear-gradient(to bottom,#337ab7 0,#2e6da4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);background-repeat:repeat-x}}.alert{text-shadow:0 1px 0 rgba(255,255,255,.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 2px rgba(0,0,0,.05);box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 2px rgba(0,0,0,.05)}.alert-success{background-image:-webkit-linear-gradient(top,#dff0d8 0,#c8e5bc 100%);background-image:-o-linear-gradient(top,#dff0d8 0,#c8e5bc 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#dff0d8),to(#c8e5bc));background-image:linear-gradient(to bottom,#dff0d8 0,#c8e5bc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0);background-repeat:repeat-x;border-color:#b2dba1}.alert-info{background-image:-webkit-linear-gradient(top,#d9edf7 0,#b9def0 100%);background-image:-o-linear-gradient(top,#d9edf7 0,#b9def0 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9edf7),to(#b9def0));background-image:linear-gradient(to bottom,#d9edf7 0,#b9def0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0);background-repeat:repeat-x;border-color:#9acfea}.alert-warning{background-image:-webkit-linear-gradient(top,#fcf8e3 0,#f8efc0 100%);background-image:-o-linear-gradient(top,#fcf8e3 0,#f8efc0 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fcf8e3),to(#f8efc0));background-image:linear-gradient(to bottom,#fcf8e3 0,#f8efc0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0);background-repeat:repeat-x;border-color:#f5e79e}.alert-danger{background-image:-webkit-linear-gradient(top,#f2dede 0,#e7c3c3 100%);background-image:-o-linear-gradient(top,#f2dede 0,#e7c3c3 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f2dede),to(#e7c3c3));background-image:linear-gradient(to bottom,#f2dede 0,#e7c3c3 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0);background-repeat:repeat-x;border-color:#dca7a7}.progress{background-image:-webkit-linear-gradient(top,#ebebeb 0,#f5f5f5 100%);background-image:-o-linear-gradient(top,#ebebeb 0,#f5f5f5 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#ebebeb),to(#f5f5f5));background-image:linear-gradient(to bottom,#ebebeb 0,#f5f5f5 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0);background-repeat:repeat-x}.progress-bar{background-image:-webkit-linear-gradient(top,#337ab7 0,#286090 100%);background-image:-o-linear-gradient(top,#337ab7 0,#286090 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#286090));background-image:linear-gradient(to bottom,#337ab7 0,#286090 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff286090', GradientType=0);background-repeat:repeat-x}.progress-bar-success{background-image:-webkit-linear-gradient(top,#5cb85c 0,#449d44 100%);background-image:-o-linear-gradient(top,#5cb85c 0,#449d44 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5cb85c),to(#449d44));background-image:linear-gradient(to bottom,#5cb85c 0,#449d44 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0);background-repeat:repeat-x}.progress-bar-info{background-image:-webkit-linear-gradient(top,#5bc0de 0,#31b0d5 100%);background-image:-o-linear-gradient(top,#5bc0de 0,#31b0d5 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5bc0de),to(#31b0d5));background-image:linear-gradient(to bottom,#5bc0de 0,#31b0d5 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0);background-repeat:repeat-x}.progress-bar-warning{background-image:-webkit-linear-gradient(top,#f0ad4e 0,#ec971f 100%);background-image:-o-linear-gradient(top,#f0ad4e 0,#ec971f 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f0ad4e),to(#ec971f));background-image:linear-gradient(to bottom,#f0ad4e 0,#ec971f 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0);background-repeat:repeat-x}.progress-bar-danger{background-image:-webkit-linear-gradient(top,#d9534f 0,#c9302c 100%);background-image:-o-linear-gradient(top,#d9534f 0,#c9302c 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9534f),to(#c9302c));background-image:linear-gradient(to bottom,#d9534f 0,#c9302c 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0);background-repeat:repeat-x}.progress-bar-striped{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.list-group{border-radius:4px;-webkit-box-shadow:0 1px 2px rgba(0,0,0,.075);box-shadow:0 1px 2px rgba(0,0,0,.075)}.list-group-item.active,.list-group-item.active:focus,.list-group-item.active:hover{text-shadow:0 -1px 0 #286090;background-image:-webkit-linear-gradient(top,#337ab7 0,#2b669a 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2b669a 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2b669a));background-image:linear-gradient(to bottom,#337ab7 0,#2b669a 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2b669a', GradientType=0);background-repeat:repeat-x;border-color:#2b669a}.list-group-item.active .badge,.list-group-item.active:focus .badge,.list-group-item.active:hover .badge{text-shadow:none}.panel{-webkit-box-shadow:0 1px 2px rgba(0,0,0,.05);box-shadow:0 1px 2px rgba(0,0,0,.05)}.panel-default>.panel-heading{background-image:-webkit-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-o-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#e8e8e8));background-image:linear-gradient(to bottom,#f5f5f5 0,#e8e8e8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);background-repeat:repeat-x}.panel-primary>.panel-heading{background-image:-webkit-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2e6da4));background-image:linear-gradient(to bottom,#337ab7 0,#2e6da4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);background-repeat:repeat-x}.panel-success>.panel-heading{background-image:-webkit-linear-gradient(top,#dff0d8 0,#d0e9c6 100%);background-image:-o-linear-gradient(top,#dff0d8 0,#d0e9c6 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#dff0d8),to(#d0e9c6));background-image:linear-gradient(to bottom,#dff0d8 0,#d0e9c6 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0);background-repeat:repeat-x}.panel-info>.panel-heading{background-image:-webkit-linear-gradient(top,#d9edf7 0,#c4e3f3 100%);background-image:-o-linear-gradient(top,#d9edf7 0,#c4e3f3 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9edf7),to(#c4e3f3));background-image:linear-gradient(to bottom,#d9edf7 0,#c4e3f3 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0);background-repeat:repeat-x}.panel-warning>.panel-heading{background-image:-webkit-linear-gradient(top,#fcf8e3 0,#faf2cc 100%);background-image:-o-linear-gradient(top,#fcf8e3 0,#faf2cc 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fcf8e3),to(#faf2cc));background-image:linear-gradient(to bottom,#fcf8e3 0,#faf2cc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0);background-repeat:repeat-x}.panel-danger>.panel-heading{background-image:-webkit-linear-gradient(top,#f2dede 0,#ebcccc 100%);background-image:-o-linear-gradient(top,#f2dede 0,#ebcccc 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f2dede),to(#ebcccc));background-image:linear-gradient(to bottom,#f2dede 0,#ebcccc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0);background-repeat:repeat-x}.well{background-image:-webkit-linear-gradient(top,#e8e8e8 0,#f5f5f5 100%);background-image:-o-linear-gradient(top,#e8e8e8 0,#f5f5f5 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#e8e8e8),to(#f5f5f5));background-image:linear-gradient(to bottom,#e8e8e8 0,#f5f5f5 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0);background-repeat:repeat-x;border-color:#dcdcdc;-webkit-box-shadow:inset 0 1px 3px rgba(0,0,0,.05),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 3px rgba(0,0,0,.05),0 1px 0 rgba(255,255,255,.1)}
+/*# sourceMappingURL=bootstrap-theme.min.css.map */
diff --git a/modules/http/static/bootstrap-theme.min.css.spdx b/modules/http/static/bootstrap-theme.min.css.spdx
new file mode 100644
index 0000000..a56f287
--- /dev/null
+++ b/modules/http/static/bootstrap-theme.min.css.spdx
@@ -0,0 +1,11 @@
+SPDXVersion: SPDX-2.1
+DataLicense: CC0-1.0
+SPDXID: SPDXRef-DOCUMENT
+DocumentName: bootstrap-theme
+DocumentNamespace: http://spdx.org/spdxdocs/spdx-v2.1-2794db89-37c2-415b-b1bd-d66b445c5202
+
+PackageName: bootstrap-theme
+PackageVersion: 3.3.6
+PackageDownloadLocation: git+https://github.com/twbs/bootstrap.git@81df608a40bf0629a1dc08e584849bb1e43e0b7a#dist/css/bootstrap-theme.min.css
+PackageOriginator: Organization: Twitter
+PackageLicenseDeclared: MIT
diff --git a/modules/http/static/bootstrap.min.css b/modules/http/static/bootstrap.min.css
new file mode 100644
index 0000000..3bda7c6
--- /dev/null
+++ b/modules/http/static/bootstrap.min.css
@@ -0,0 +1,11 @@
+/*!
+ * bootswatch v3.3.6+2 yeti
+ * Homepage: http://bootswatch.com
+ * Copyright 2012-2016 Thomas Park
+ * SPDX-License-Identifier: MIT
+ * Based on Bootstrap
+*//*!
+ * Bootstrap v3.3.6 (http://getbootstrap.com)
+ * Copyright 2011-2015 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ *//*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}dfn{font-style:italic}h1{font-size:2em;margin:0.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace, monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type="checkbox"],input[type="radio"]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}input[type="number"]::-webkit-inner-spin-button,input[type="number"]::-webkit-outer-spin-button{height:auto}input[type="search"]{-webkit-appearance:textfield;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid #c0c0c0;margin:0 2px;padding:0.35em 0.625em 0.75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:bold}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */@media print{*,*:before,*:after{background:transparent !important;color:#000 !important;-webkit-box-shadow:none !important;box-shadow:none !important;text-shadow:none !important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="#"]:after,a[href^="javascript:"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}.navbar{display:none}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000 !important}.label{border:1px solid #000}.table{border-collapse:collapse !important}.table td,.table th{background-color:#fff !important}.table-bordered th,.table-bordered td{border:1px solid #ddd !important}}@font-face{font-family:'Glyphicons Halflings';src:url('../glyphicons-halflings-regular.eot');src:url('../glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'),url('../glyphicons-halflings-regular.woff2') format('woff2'),url('../glyphicons-halflings-regular.woff') format('woff'),url('../glyphicons-halflings-regular.ttf') format('truetype'),url('../glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg')}.glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.glyphicon-asterisk:before{content:"\002a"}.glyphicon-plus:before{content:"\002b"}.glyphicon-euro:before,.glyphicon-eur:before{content:"\20ac"}.glyphicon-minus:before{content:"\2212"}.glyphicon-cloud:before{content:"\2601"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:before{content:"\e026"}.glyphicon-upload:before{content:"\e027"}.glyphicon-inbox:before{content:"\e028"}.glyphicon-play-circle:before{content:"\e029"}.glyphicon-repeat:before{content:"\e030"}.glyphicon-refresh:before{content:"\e031"}.glyphicon-list-alt:before{content:"\e032"}.glyphicon-lock:before{content:"\e033"}.glyphicon-flag:before{content:"\e034"}.glyphicon-headphones:before{content:"\e035"}.glyphicon-volume-off:before{content:"\e036"}.glyphicon-volume-down:before{content:"\e037"}.glyphicon-volume-up:before{content:"\e038"}.glyphicon-qrcode:before{content:"\e039"}.glyphicon-barcode:before{content:"\e040"}.glyphicon-tag:before{content:"\e041"}.glyphicon-tags:before{content:"\e042"}.glyphicon-book:before{content:"\e043"}.glyphicon-bookmark:before{content:"\e044"}.glyphicon-print:before{content:"\e045"}.glyphicon-camera:before{content:"\e046"}.glyphicon-font:before{content:"\e047"}.glyphicon-bold:before{content:"\e048"}.glyphicon-italic:before{content:"\e049"}.glyphicon-text-height:before{content:"\e050"}.glyphicon-text-width:before{content:"\e051"}.glyphicon-align-left:before{content:"\e052"}.glyphicon-align-center:before{content:"\e053"}.glyphicon-align-right:before{content:"\e054"}.glyphicon-align-justify:before{content:"\e055"}.glyphicon-list:before{content:"\e056"}.glyphicon-indent-left:before{content:"\e057"}.glyphicon-indent-right:before{content:"\e058"}.glyphicon-facetime-video:before{content:"\e059"}.glyphicon-picture:before{content:"\e060"}.glyphicon-map-marker:before{content:"\e062"}.glyphicon-adjust:before{content:"\e063"}.glyphicon-tint:before{content:"\e064"}.glyphicon-edit:before{content:"\e065"}.glyphicon-share:before{content:"\e066"}.glyphicon-check:before{content:"\e067"}.glyphicon-move:before{content:"\e068"}.glyphicon-step-backward:before{content:"\e069"}.glyphicon-fast-backward:before{content:"\e070"}.glyphicon-backward:before{content:"\e071"}.glyphicon-play:before{content:"\e072"}.glyphicon-pause:before{content:"\e073"}.glyphicon-stop:before{content:"\e074"}.glyphicon-forward:before{content:"\e075"}.glyphicon-fast-forward:before{content:"\e076"}.glyphicon-step-forward:before{content:"\e077"}.glyphicon-eject:before{content:"\e078"}.glyphicon-chevron-left:before{content:"\e079"}.glyphicon-chevron-right:before{content:"\e080"}.glyphicon-plus-sign:before{content:"\e081"}.glyphicon-minus-sign:before{content:"\e082"}.glyphicon-remove-sign:before{content:"\e083"}.glyphicon-ok-sign:before{content:"\e084"}.glyphicon-question-sign:before{content:"\e085"}.glyphicon-info-sign:before{content:"\e086"}.glyphicon-screenshot:before{content:"\e087"}.glyphicon-remove-circle:before{content:"\e088"}.glyphicon-ok-circle:before{content:"\e089"}.glyphicon-ban-circle:before{content:"\e090"}.glyphicon-arrow-left:before{content:"\e091"}.glyphicon-arrow-right:before{content:"\e092"}.glyphicon-arrow-up:before{content:"\e093"}.glyphicon-arrow-down:before{content:"\e094"}.glyphicon-share-alt:before{content:"\e095"}.glyphicon-resize-full:before{content:"\e096"}.glyphicon-resize-small:before{content:"\e097"}.glyphicon-exclamation-sign:before{content:"\e101"}.glyphicon-gift:before{content:"\e102"}.glyphicon-leaf:before{content:"\e103"}.glyphicon-fire:before{content:"\e104"}.glyphicon-eye-open:before{content:"\e105"}.glyphicon-eye-close:before{content:"\e106"}.glyphicon-warning-sign:before{content:"\e107"}.glyphicon-plane:before{content:"\e108"}.glyphicon-calendar:before{content:"\e109"}.glyphicon-random:before{content:"\e110"}.glyphicon-comment:before{content:"\e111"}.glyphicon-magnet:before{content:"\e112"}.glyphicon-chevron-up:before{content:"\e113"}.glyphicon-chevron-down:before{content:"\e114"}.glyphicon-retweet:before{content:"\e115"}.glyphicon-shopping-cart:before{content:"\e116"}.glyphicon-folder-close:before{content:"\e117"}.glyphicon-folder-open:before{content:"\e118"}.glyphicon-resize-vertical:before{content:"\e119"}.glyphicon-resize-horizontal:before{content:"\e120"}.glyphicon-hdd:before{content:"\e121"}.glyphicon-bullhorn:before{content:"\e122"}.glyphicon-bell:before{content:"\e123"}.glyphicon-certificate:before{content:"\e124"}.glyphicon-thumbs-up:before{content:"\e125"}.glyphicon-thumbs-down:before{content:"\e126"}.glyphicon-hand-right:before{content:"\e127"}.glyphicon-hand-left:before{content:"\e128"}.glyphicon-hand-up:before{content:"\e129"}.glyphicon-hand-down:before{content:"\e130"}.glyphicon-circle-arrow-right:before{content:"\e131"}.glyphicon-circle-arrow-left:before{content:"\e132"}.glyphicon-circle-arrow-up:before{content:"\e133"}.glyphicon-circle-arrow-down:before{content:"\e134"}.glyphicon-globe:before{content:"\e135"}.glyphicon-wrench:before{content:"\e136"}.glyphicon-tasks:before{content:"\e137"}.glyphicon-filter:before{content:"\e138"}.glyphicon-briefcase:before{content:"\e139"}.glyphicon-fullscreen:before{content:"\e140"}.glyphicon-dashboard:before{content:"\e141"}.glyphicon-paperclip:before{content:"\e142"}.glyphicon-heart-empty:before{content:"\e143"}.glyphicon-link:before{content:"\e144"}.glyphicon-phone:before{content:"\e145"}.glyphicon-pushpin:before{content:"\e146"}.glyphicon-usd:before{content:"\e148"}.glyphicon-gbp:before{content:"\e149"}.glyphicon-sort:before{content:"\e150"}.glyphicon-sort-by-alphabet:before{content:"\e151"}.glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.glyphicon-sort-by-order:before{content:"\e153"}.glyphicon-sort-by-order-alt:before{content:"\e154"}.glyphicon-sort-by-attributes:before{content:"\e155"}.glyphicon-sort-by-attributes-alt:before{content:"\e156"}.glyphicon-unchecked:before{content:"\e157"}.glyphicon-expand:before{content:"\e158"}.glyphicon-collapse-down:before{content:"\e159"}.glyphicon-collapse-up:before{content:"\e160"}.glyphicon-log-in:before{content:"\e161"}.glyphicon-flash:before{content:"\e162"}.glyphicon-log-out:before{content:"\e163"}.glyphicon-new-window:before{content:"\e164"}.glyphicon-record:before{content:"\e165"}.glyphicon-save:before{content:"\e166"}.glyphicon-open:before{content:"\e167"}.glyphicon-saved:before{content:"\e168"}.glyphicon-import:before{content:"\e169"}.glyphicon-export:before{content:"\e170"}.glyphicon-send:before{content:"\e171"}.glyphicon-floppy-disk:before{content:"\e172"}.glyphicon-floppy-saved:before{content:"\e173"}.glyphicon-floppy-remove:before{content:"\e174"}.glyphicon-floppy-save:before{content:"\e175"}.glyphicon-floppy-open:before{content:"\e176"}.glyphicon-credit-card:before{content:"\e177"}.glyphicon-transfer:before{content:"\e178"}.glyphicon-cutlery:before{content:"\e179"}.glyphicon-header:before{content:"\e180"}.glyphicon-compressed:before{content:"\e181"}.glyphicon-earphone:before{content:"\e182"}.glyphicon-phone-alt:before{content:"\e183"}.glyphicon-tower:before{content:"\e184"}.glyphicon-stats:before{content:"\e185"}.glyphicon-sd-video:before{content:"\e186"}.glyphicon-hd-video:before{content:"\e187"}.glyphicon-subtitles:before{content:"\e188"}.glyphicon-sound-stereo:before{content:"\e189"}.glyphicon-sound-dolby:before{content:"\e190"}.glyphicon-sound-5-1:before{content:"\e191"}.glyphicon-sound-6-1:before{content:"\e192"}.glyphicon-sound-7-1:before{content:"\e193"}.glyphicon-copyright-mark:before{content:"\e194"}.glyphicon-registration-mark:before{content:"\e195"}.glyphicon-cloud-download:before{content:"\e197"}.glyphicon-cloud-upload:before{content:"\e198"}.glyphicon-tree-conifer:before{content:"\e199"}.glyphicon-tree-deciduous:before{content:"\e200"}.glyphicon-cd:before{content:"\e201"}.glyphicon-save-file:before{content:"\e202"}.glyphicon-open-file:before{content:"\e203"}.glyphicon-level-up:before{content:"\e204"}.glyphicon-copy:before{content:"\e205"}.glyphicon-paste:before{content:"\e206"}.glyphicon-alert:before{content:"\e209"}.glyphicon-equalizer:before{content:"\e210"}.glyphicon-king:before{content:"\e211"}.glyphicon-queen:before{content:"\e212"}.glyphicon-pawn:before{content:"\e213"}.glyphicon-bishop:before{content:"\e214"}.glyphicon-knight:before{content:"\e215"}.glyphicon-baby-formula:before{content:"\e216"}.glyphicon-tent:before{content:"\26fa"}.glyphicon-blackboard:before{content:"\e218"}.glyphicon-bed:before{content:"\e219"}.glyphicon-apple:before{content:"\f8ff"}.glyphicon-erase:before{content:"\e221"}.glyphicon-hourglass:before{content:"\231b"}.glyphicon-lamp:before{content:"\e223"}.glyphicon-duplicate:before{content:"\e224"}.glyphicon-piggy-bank:before{content:"\e225"}.glyphicon-scissors:before{content:"\e226"}.glyphicon-bitcoin:before{content:"\e227"}.glyphicon-btc:before{content:"\e227"}.glyphicon-xbt:before{content:"\e227"}.glyphicon-yen:before{content:"\00a5"}.glyphicon-jpy:before{content:"\00a5"}.glyphicon-ruble:before{content:"\20bd"}.glyphicon-rub:before{content:"\20bd"}.glyphicon-scale:before{content:"\e230"}.glyphicon-ice-lolly:before{content:"\e231"}.glyphicon-ice-lolly-tasted:before{content:"\e232"}.glyphicon-education:before{content:"\e233"}.glyphicon-option-horizontal:before{content:"\e234"}.glyphicon-option-vertical:before{content:"\e235"}.glyphicon-menu-hamburger:before{content:"\e236"}.glyphicon-modal-window:before{content:"\e237"}.glyphicon-oil:before{content:"\e238"}.glyphicon-grain:before{content:"\e239"}.glyphicon-sunglasses:before{content:"\e240"}.glyphicon-text-size:before{content:"\e241"}.glyphicon-text-color:before{content:"\e242"}.glyphicon-text-background:before{content:"\e243"}.glyphicon-object-align-top:before{content:"\e244"}.glyphicon-object-align-bottom:before{content:"\e245"}.glyphicon-object-align-horizontal:before{content:"\e246"}.glyphicon-object-align-left:before{content:"\e247"}.glyphicon-object-align-vertical:before{content:"\e248"}.glyphicon-object-align-right:before{content:"\e249"}.glyphicon-triangle-right:before{content:"\e250"}.glyphicon-triangle-left:before{content:"\e251"}.glyphicon-triangle-bottom:before{content:"\e252"}.glyphicon-triangle-top:before{content:"\e253"}.glyphicon-console:before{content:"\e254"}.glyphicon-superscript:before{content:"\e255"}.glyphicon-subscript:before{content:"\e256"}.glyphicon-menu-left:before{content:"\e257"}.glyphicon-menu-right:before{content:"\e258"}.glyphicon-menu-down:before{content:"\e259"}.glyphicon-menu-up:before{content:"\e260"}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}*:before,*:after{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:10px;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;color:#222222;background-color:#ffffff}input,button,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#008cba;text-decoration:none}a:hover,a:focus{color:#008cba;text-decoration:underline}a:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.img-responsive,.thumbnail>img,.thumbnail a>img,.carousel-inner>.item>img,.carousel-inner>.item>a>img{display:block;max-width:100%;height:auto}.img-rounded{border-radius:0}.img-thumbnail{padding:4px;line-height:1.4;background-color:#ffffff;border:1px solid #dddddd;border-radius:0;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out;display:inline-block;max-width:100%;height:auto}.img-circle{border-radius:50%}hr{margin-top:21px;margin-bottom:21px;border:0;border-top:1px solid #dddddd}.sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0, 0, 0, 0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}[role="button"]{cursor:pointer}h1,h2,h3,h4,h5,h6,.h1,.h2,.h3,.h4,.h5,.h6{font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-weight:300;line-height:1.1;color:inherit}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small,.h1 small,.h2 small,.h3 small,.h4 small,.h5 small,.h6 small,h1 .small,h2 .small,h3 .small,h4 .small,h5 .small,h6 .small,.h1 .small,.h2 .small,.h3 .small,.h4 .small,.h5 .small,.h6 .small{font-weight:normal;line-height:1;color:#999999}h1,.h1,h2,.h2,h3,.h3{margin-top:21px;margin-bottom:10.5px}h1 small,.h1 small,h2 small,.h2 small,h3 small,.h3 small,h1 .small,.h1 .small,h2 .small,.h2 .small,h3 .small,.h3 .small{font-size:65%}h4,.h4,h5,.h5,h6,.h6{margin-top:10.5px;margin-bottom:10.5px}h4 small,.h4 small,h5 small,.h5 small,h6 small,.h6 small,h4 .small,.h4 .small,h5 .small,.h5 .small,h6 .small,.h6 .small{font-size:75%}h1,.h1{font-size:39px}h2,.h2{font-size:32px}h3,.h3{font-size:26px}h4,.h4{font-size:19px}h5,.h5{font-size:15px}h6,.h6{font-size:13px}p{margin:0 0 10.5px}.lead{margin-bottom:21px;font-size:17px;font-weight:300;line-height:1.4}@media (min-width:768px){.lead{font-size:22.5px}}small,.small{font-size:80%}mark,.mark{background-color:#fcf8e3;padding:.2em}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-lowercase{text-transform:lowercase}.text-uppercase{text-transform:uppercase}.text-capitalize{text-transform:capitalize}.text-muted{color:#999999}.text-primary{color:#008cba}a.text-primary:hover,a.text-primary:focus{color:#006687}.text-success{color:#43ac6a}a.text-success:hover,a.text-success:focus{color:#358753}.text-info{color:#5bc0de}a.text-info:hover,a.text-info:focus{color:#31b0d5}.text-warning{color:#e99002}a.text-warning:hover,a.text-warning:focus{color:#b67102}.text-danger{color:#f04124}a.text-danger:hover,a.text-danger:focus{color:#d32a0e}.bg-primary{color:#fff;background-color:#008cba}a.bg-primary:hover,a.bg-primary:focus{background-color:#006687}.bg-success{background-color:#dff0d8}a.bg-success:hover,a.bg-success:focus{background-color:#c1e2b3}.bg-info{background-color:#d9edf7}a.bg-info:hover,a.bg-info:focus{background-color:#afd9ee}.bg-warning{background-color:#fcf8e3}a.bg-warning:hover,a.bg-warning:focus{background-color:#f7ecb5}.bg-danger{background-color:#f2dede}a.bg-danger:hover,a.bg-danger:focus{background-color:#e4b9b9}.page-header{padding-bottom:9.5px;margin:42px 0 21px;border-bottom:1px solid #dddddd}ul,ol{margin-top:0;margin-bottom:10.5px}ul ul,ol ul,ul ol,ol ol{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none;margin-left:-5px}.list-inline>li{display:inline-block;padding-left:5px;padding-right:5px}dl{margin-top:0;margin-bottom:21px}dt,dd{line-height:1.4}dt{font-weight:bold}dd{margin-left:0}@media (min-width:768px){.dl-horizontal dt{float:left;width:160px;clear:left;text-align:right;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}}abbr[title],abbr[data-original-title]{cursor:help;border-bottom:1px dotted #999999}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10.5px 21px;margin:0 0 21px;font-size:18.75px;border-left:5px solid #dddddd}blockquote p:last-child,blockquote ul:last-child,blockquote ol:last-child{margin-bottom:0}blockquote footer,blockquote small,blockquote .small{display:block;font-size:80%;line-height:1.4;color:#6f6f6f}blockquote footer:before,blockquote small:before,blockquote .small:before{content:'\2014 \00A0'}.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;border-right:5px solid #dddddd;border-left:0;text-align:right}.blockquote-reverse footer:before,blockquote.pull-right footer:before,.blockquote-reverse small:before,blockquote.pull-right small:before,.blockquote-reverse .small:before,blockquote.pull-right .small:before{content:''}.blockquote-reverse footer:after,blockquote.pull-right footer:after,.blockquote-reverse small:after,blockquote.pull-right small:after,.blockquote-reverse .small:after,blockquote.pull-right .small:after{content:'\00A0 \2014'}address{margin-bottom:21px;font-style:normal;line-height:1.4}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,"Courier New",monospace}code{padding:2px 4px;font-size:90%;color:#c7254e;background-color:#f9f2f4;border-radius:0}kbd{padding:2px 4px;font-size:90%;color:#ffffff;background-color:#333333;border-radius:0;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.25);box-shadow:inset 0 -1px 0 rgba(0,0,0,0.25)}kbd kbd{padding:0;font-size:100%;font-weight:bold;-webkit-box-shadow:none;box-shadow:none}pre{display:block;padding:10px;margin:0 0 10.5px;font-size:14px;line-height:1.4;word-break:break-all;word-wrap:break-word;color:#333333;background-color:#f5f5f5;border:1px solid #cccccc;border-radius:0}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{margin-right:auto;margin-left:auto;padding-left:15px;padding-right:15px}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.container-fluid{margin-right:auto;margin-left:auto;padding-left:15px;padding-right:15px}.row{margin-left:-15px;margin-right:-15px}.col-xs-1,.col-sm-1,.col-md-1,.col-lg-1,.col-xs-2,.col-sm-2,.col-md-2,.col-lg-2,.col-xs-3,.col-sm-3,.col-md-3,.col-lg-3,.col-xs-4,.col-sm-4,.col-md-4,.col-lg-4,.col-xs-5,.col-sm-5,.col-md-5,.col-lg-5,.col-xs-6,.col-sm-6,.col-md-6,.col-lg-6,.col-xs-7,.col-sm-7,.col-md-7,.col-lg-7,.col-xs-8,.col-sm-8,.col-md-8,.col-lg-8,.col-xs-9,.col-sm-9,.col-md-9,.col-lg-9,.col-xs-10,.col-sm-10,.col-md-10,.col-lg-10,.col-xs-11,.col-sm-11,.col-md-11,.col-lg-11,.col-xs-12,.col-sm-12,.col-md-12,.col-lg-12{position:relative;min-height:1px;padding-left:15px;padding-right:15px}.col-xs-1,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9,.col-xs-10,.col-xs-11,.col-xs-12{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0%}@media (min-width:768px){.col-sm-1,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-10,.col-sm-11,.col-sm-12{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:auto}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:auto}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0%}}@media (min-width:992px){.col-md-1,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-10,.col-md-11,.col-md-12{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:auto}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:auto}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0%}}@media (min-width:1200px){.col-lg-1,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-10,.col-lg-11,.col-lg-12{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:auto}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:auto}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0%}}table{background-color:transparent}caption{padding-top:8px;padding-bottom:8px;color:#999999;text-align:left}th{text-align:left}.table{width:100%;max-width:100%;margin-bottom:21px}.table>thead>tr>th,.table>tbody>tr>th,.table>tfoot>tr>th,.table>thead>tr>td,.table>tbody>tr>td,.table>tfoot>tr>td{padding:8px;line-height:1.4;vertical-align:top;border-top:1px solid #dddddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #dddddd}.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>th,.table>caption+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>td,.table>thead:first-child>tr:first-child>td{border-top:0}.table>tbody+tbody{border-top:2px solid #dddddd}.table .table{background-color:#ffffff}.table-condensed>thead>tr>th,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>tbody>tr>td,.table-condensed>tfoot>tr>td{padding:5px}.table-bordered{border:1px solid #dddddd}.table-bordered>thead>tr>th,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>tbody>tr>td,.table-bordered>tfoot>tr>td{border:1px solid #dddddd}.table-bordered>thead>tr>th,.table-bordered>thead>tr>td{border-bottom-width:2px}.table-striped>tbody>tr:nth-of-type(odd){background-color:#f9f9f9}.table-hover>tbody>tr:hover{background-color:#f5f5f5}table col[class*="col-"]{position:static;float:none;display:table-column}table td[class*="col-"],table th[class*="col-"]{position:static;float:none;display:table-cell}.table>thead>tr>td.active,.table>tbody>tr>td.active,.table>tfoot>tr>td.active,.table>thead>tr>th.active,.table>tbody>tr>th.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>tbody>tr.active>td,.table>tfoot>tr.active>td,.table>thead>tr.active>th,.table>tbody>tr.active>th,.table>tfoot>tr.active>th{background-color:#f5f5f5}.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover,.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr:hover>.active,.table-hover>tbody>tr.active:hover>th{background-color:#e8e8e8}.table>thead>tr>td.success,.table>tbody>tr>td.success,.table>tfoot>tr>td.success,.table>thead>tr>th.success,.table>tbody>tr>th.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>tbody>tr.success>td,.table>tfoot>tr.success>td,.table>thead>tr.success>th,.table>tbody>tr.success>th,.table>tfoot>tr.success>th{background-color:#dff0d8}.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover,.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr:hover>.success,.table-hover>tbody>tr.success:hover>th{background-color:#d0e9c6}.table>thead>tr>td.info,.table>tbody>tr>td.info,.table>tfoot>tr>td.info,.table>thead>tr>th.info,.table>tbody>tr>th.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>tbody>tr.info>td,.table>tfoot>tr.info>td,.table>thead>tr.info>th,.table>tbody>tr.info>th,.table>tfoot>tr.info>th{background-color:#d9edf7}.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover,.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr:hover>.info,.table-hover>tbody>tr.info:hover>th{background-color:#c4e3f3}.table>thead>tr>td.warning,.table>tbody>tr>td.warning,.table>tfoot>tr>td.warning,.table>thead>tr>th.warning,.table>tbody>tr>th.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>tbody>tr.warning>td,.table>tfoot>tr.warning>td,.table>thead>tr.warning>th,.table>tbody>tr.warning>th,.table>tfoot>tr.warning>th{background-color:#fcf8e3}.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover,.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr:hover>.warning,.table-hover>tbody>tr.warning:hover>th{background-color:#faf2cc}.table>thead>tr>td.danger,.table>tbody>tr>td.danger,.table>tfoot>tr>td.danger,.table>thead>tr>th.danger,.table>tbody>tr>th.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>tbody>tr.danger>td,.table>tfoot>tr.danger>td,.table>thead>tr.danger>th,.table>tbody>tr.danger>th,.table>tfoot>tr.danger>th{background-color:#f2dede}.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover,.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr:hover>.danger,.table-hover>tbody>tr.danger:hover>th{background-color:#ebcccc}.table-responsive{overflow-x:auto;min-height:0.01%}@media screen and (max-width:767px){.table-responsive{width:100%;margin-bottom:15.75px;overflow-y:hidden;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #dddddd}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>thead>tr>th,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tfoot>tr>td{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>thead>tr>th:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child{border-left:0}.table-responsive>.table-bordered>thead>tr>th:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>th,.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>td{border-bottom:0}}fieldset{padding:0;margin:0;border:0;min-width:0}legend{display:block;width:100%;padding:0;margin-bottom:21px;font-size:22.5px;line-height:inherit;color:#333333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;max-width:100%;margin-bottom:5px;font-weight:bold}input[type="search"]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type="radio"],input[type="checkbox"]{margin:4px 0 0;margin-top:1px \9;line-height:normal}input[type="file"]{display:block}input[type="range"]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type="file"]:focus,input[type="radio"]:focus,input[type="checkbox"]:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}output{display:block;padding-top:9px;font-size:15px;line-height:1.4;color:#6f6f6f}.form-control{display:block;width:100%;height:39px;padding:8px 12px;font-size:15px;line-height:1.4;color:#6f6f6f;background-color:#ffffff;background-image:none;border:1px solid #cccccc;border-radius:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-webkit-transition:border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(102,175,233,0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(102,175,233,0.6)}.form-control::-moz-placeholder{color:#999999;opacity:1}.form-control:-ms-input-placeholder{color:#999999}.form-control::-webkit-input-placeholder{color:#999999}.form-control::-ms-expand{border:0;background-color:transparent}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{background-color:#eeeeee;opacity:1}.form-control[disabled],fieldset[disabled] .form-control{cursor:not-allowed}textarea.form-control{height:auto}input[type="search"]{-webkit-appearance:none}@media screen and (-webkit-min-device-pixel-ratio:0){input[type="date"].form-control,input[type="time"].form-control,input[type="datetime-local"].form-control,input[type="month"].form-control{line-height:39px}input[type="date"].input-sm,input[type="time"].input-sm,input[type="datetime-local"].input-sm,input[type="month"].input-sm,.input-group-sm input[type="date"],.input-group-sm input[type="time"],.input-group-sm input[type="datetime-local"],.input-group-sm input[type="month"]{line-height:36px}input[type="date"].input-lg,input[type="time"].input-lg,input[type="datetime-local"].input-lg,input[type="month"].input-lg,.input-group-lg input[type="date"],.input-group-lg input[type="time"],.input-group-lg input[type="datetime-local"],.input-group-lg input[type="month"]{line-height:60px}}.form-group{margin-bottom:15px}.radio,.checkbox{position:relative;display:block;margin-top:10px;margin-bottom:10px}.radio label,.checkbox label{min-height:21px;padding-left:20px;margin-bottom:0;font-weight:normal;cursor:pointer}.radio input[type="radio"],.radio-inline input[type="radio"],.checkbox input[type="checkbox"],.checkbox-inline input[type="checkbox"]{position:absolute;margin-left:-20px;margin-top:4px \9}.radio+.radio,.checkbox+.checkbox{margin-top:-5px}.radio-inline,.checkbox-inline{position:relative;display:inline-block;padding-left:20px;margin-bottom:0;vertical-align:middle;font-weight:normal;cursor:pointer}.radio-inline+.radio-inline,.checkbox-inline+.checkbox-inline{margin-top:0;margin-left:10px}input[type="radio"][disabled],input[type="checkbox"][disabled],input[type="radio"].disabled,input[type="checkbox"].disabled,fieldset[disabled] input[type="radio"],fieldset[disabled] input[type="checkbox"]{cursor:not-allowed}.radio-inline.disabled,.checkbox-inline.disabled,fieldset[disabled] .radio-inline,fieldset[disabled] .checkbox-inline{cursor:not-allowed}.radio.disabled label,.checkbox.disabled label,fieldset[disabled] .radio label,fieldset[disabled] .checkbox label{cursor:not-allowed}.form-control-static{padding-top:9px;padding-bottom:9px;margin-bottom:0;min-height:36px}.form-control-static.input-lg,.form-control-static.input-sm{padding-left:0;padding-right:0}.input-sm{height:36px;padding:8px 12px;font-size:12px;line-height:1.5;border-radius:0}select.input-sm{height:36px;line-height:36px}textarea.input-sm,select[multiple].input-sm{height:auto}.form-group-sm .form-control{height:36px;padding:8px 12px;font-size:12px;line-height:1.5;border-radius:0}.form-group-sm select.form-control{height:36px;line-height:36px}.form-group-sm textarea.form-control,.form-group-sm select[multiple].form-control{height:auto}.form-group-sm .form-control-static{height:36px;min-height:33px;padding:9px 12px;font-size:12px;line-height:1.5}.input-lg{height:60px;padding:16px 20px;font-size:19px;line-height:1.3333333;border-radius:0}select.input-lg{height:60px;line-height:60px}textarea.input-lg,select[multiple].input-lg{height:auto}.form-group-lg .form-control{height:60px;padding:16px 20px;font-size:19px;line-height:1.3333333;border-radius:0}.form-group-lg select.form-control{height:60px;line-height:60px}.form-group-lg textarea.form-control,.form-group-lg select[multiple].form-control{height:auto}.form-group-lg .form-control-static{height:60px;min-height:40px;padding:17px 20px;font-size:19px;line-height:1.3333333}.has-feedback{position:relative}.has-feedback .form-control{padding-right:48.75px}.form-control-feedback{position:absolute;top:0;right:0;z-index:2;display:block;width:39px;height:39px;line-height:39px;text-align:center;pointer-events:none}.input-lg+.form-control-feedback,.input-group-lg+.form-control-feedback,.form-group-lg .form-control+.form-control-feedback{width:60px;height:60px;line-height:60px}.input-sm+.form-control-feedback,.input-group-sm+.form-control-feedback,.form-group-sm .form-control+.form-control-feedback{width:36px;height:36px;line-height:36px}.has-success .help-block,.has-success .control-label,.has-success .radio,.has-success .checkbox,.has-success .radio-inline,.has-success .checkbox-inline,.has-success.radio label,.has-success.checkbox label,.has-success.radio-inline label,.has-success.checkbox-inline label{color:#43ac6a}.has-success .form-control{border-color:#43ac6a;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.has-success .form-control:focus{border-color:#358753;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #85d0a1;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #85d0a1}.has-success .input-group-addon{color:#43ac6a;border-color:#43ac6a;background-color:#dff0d8}.has-success .form-control-feedback{color:#43ac6a}.has-warning .help-block,.has-warning .control-label,.has-warning .radio,.has-warning .checkbox,.has-warning .radio-inline,.has-warning .checkbox-inline,.has-warning.radio label,.has-warning.checkbox label,.has-warning.radio-inline label,.has-warning.checkbox-inline label{color:#e99002}.has-warning .form-control{border-color:#e99002;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.has-warning .form-control:focus{border-color:#b67102;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #febc53;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #febc53}.has-warning .input-group-addon{color:#e99002;border-color:#e99002;background-color:#fcf8e3}.has-warning .form-control-feedback{color:#e99002}.has-error .help-block,.has-error .control-label,.has-error .radio,.has-error .checkbox,.has-error .radio-inline,.has-error .checkbox-inline,.has-error.radio label,.has-error.checkbox label,.has-error.radio-inline label,.has-error.checkbox-inline label{color:#f04124}.has-error .form-control{border-color:#f04124;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.has-error .form-control:focus{border-color:#d32a0e;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #f79483;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #f79483}.has-error .input-group-addon{color:#f04124;border-color:#f04124;background-color:#f2dede}.has-error .form-control-feedback{color:#f04124}.has-feedback label~.form-control-feedback{top:26px}.has-feedback label.sr-only~.form-control-feedback{top:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#626262}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-static{display:inline-block}.form-inline .input-group{display:inline-table;vertical-align:middle}.form-inline .input-group .input-group-addon,.form-inline .input-group .input-group-btn,.form-inline .input-group .form-control{width:auto}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .radio,.form-inline .checkbox{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.form-inline .radio label,.form-inline .checkbox label{padding-left:0}.form-inline .radio input[type="radio"],.form-inline .checkbox input[type="checkbox"]{position:relative;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}}.form-horizontal .radio,.form-horizontal .checkbox,.form-horizontal .radio-inline,.form-horizontal .checkbox-inline{margin-top:0;margin-bottom:0;padding-top:9px}.form-horizontal .radio,.form-horizontal .checkbox{min-height:30px}.form-horizontal .form-group{margin-left:-15px;margin-right:-15px}@media (min-width:768px){.form-horizontal .control-label{text-align:right;margin-bottom:0;padding-top:9px}}.form-horizontal .has-feedback .form-control-feedback{right:15px}@media (min-width:768px){.form-horizontal .form-group-lg .control-label{padding-top:17px;font-size:19px}}@media (min-width:768px){.form-horizontal .form-group-sm .control-label{padding-top:9px;font-size:12px}}.btn{display:inline-block;margin-bottom:0;font-weight:normal;text-align:center;vertical-align:middle;-ms-touch-action:manipulation;touch-action:manipulation;cursor:pointer;background-image:none;border:1px solid transparent;white-space:nowrap;padding:8px 12px;font-size:15px;line-height:1.4;border-radius:0;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.btn:focus,.btn:active:focus,.btn.active:focus,.btn.focus,.btn:active.focus,.btn.active.focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn:hover,.btn:focus,.btn.focus{color:#333333;text-decoration:none}.btn:active,.btn.active{outline:0;background-image:none;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);box-shadow:inset 0 3px 5px rgba(0,0,0,0.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{cursor:not-allowed;opacity:0.65;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none}a.btn.disabled,fieldset[disabled] a.btn{pointer-events:none}.btn-default{color:#333333;background-color:#e7e7e7;border-color:#cccccc}.btn-default:focus,.btn-default.focus{color:#333333;background-color:#cecece;border-color:#8c8c8c}.btn-default:hover{color:#333333;background-color:#cecece;border-color:#adadad}.btn-default:active,.btn-default.active,.open>.dropdown-toggle.btn-default{color:#333333;background-color:#cecece;border-color:#adadad}.btn-default:active:hover,.btn-default.active:hover,.open>.dropdown-toggle.btn-default:hover,.btn-default:active:focus,.btn-default.active:focus,.open>.dropdown-toggle.btn-default:focus,.btn-default:active.focus,.btn-default.active.focus,.open>.dropdown-toggle.btn-default.focus{color:#333333;background-color:#bcbcbc;border-color:#8c8c8c}.btn-default:active,.btn-default.active,.open>.dropdown-toggle.btn-default{background-image:none}.btn-default.disabled:hover,.btn-default[disabled]:hover,fieldset[disabled] .btn-default:hover,.btn-default.disabled:focus,.btn-default[disabled]:focus,fieldset[disabled] .btn-default:focus,.btn-default.disabled.focus,.btn-default[disabled].focus,fieldset[disabled] .btn-default.focus{background-color:#e7e7e7;border-color:#cccccc}.btn-default .badge{color:#e7e7e7;background-color:#333333}.btn-primary{color:#ffffff;background-color:#008cba;border-color:#0079a1}.btn-primary:focus,.btn-primary.focus{color:#ffffff;background-color:#006687;border-color:#001921}.btn-primary:hover{color:#ffffff;background-color:#006687;border-color:#004b63}.btn-primary:active,.btn-primary.active,.open>.dropdown-toggle.btn-primary{color:#ffffff;background-color:#006687;border-color:#004b63}.btn-primary:active:hover,.btn-primary.active:hover,.open>.dropdown-toggle.btn-primary:hover,.btn-primary:active:focus,.btn-primary.active:focus,.open>.dropdown-toggle.btn-primary:focus,.btn-primary:active.focus,.btn-primary.active.focus,.open>.dropdown-toggle.btn-primary.focus{color:#ffffff;background-color:#004b63;border-color:#001921}.btn-primary:active,.btn-primary.active,.open>.dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled:hover,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary:hover,.btn-primary.disabled:focus,.btn-primary[disabled]:focus,fieldset[disabled] .btn-primary:focus,.btn-primary.disabled.focus,.btn-primary[disabled].focus,fieldset[disabled] .btn-primary.focus{background-color:#008cba;border-color:#0079a1}.btn-primary .badge{color:#008cba;background-color:#ffffff}.btn-success{color:#ffffff;background-color:#43ac6a;border-color:#3c9a5f}.btn-success:focus,.btn-success.focus{color:#ffffff;background-color:#358753;border-color:#183e26}.btn-success:hover{color:#ffffff;background-color:#358753;border-color:#2b6e44}.btn-success:active,.btn-success.active,.open>.dropdown-toggle.btn-success{color:#ffffff;background-color:#358753;border-color:#2b6e44}.btn-success:active:hover,.btn-success.active:hover,.open>.dropdown-toggle.btn-success:hover,.btn-success:active:focus,.btn-success.active:focus,.open>.dropdown-toggle.btn-success:focus,.btn-success:active.focus,.btn-success.active.focus,.open>.dropdown-toggle.btn-success.focus{color:#ffffff;background-color:#2b6e44;border-color:#183e26}.btn-success:active,.btn-success.active,.open>.dropdown-toggle.btn-success{background-image:none}.btn-success.disabled:hover,.btn-success[disabled]:hover,fieldset[disabled] .btn-success:hover,.btn-success.disabled:focus,.btn-success[disabled]:focus,fieldset[disabled] .btn-success:focus,.btn-success.disabled.focus,.btn-success[disabled].focus,fieldset[disabled] .btn-success.focus{background-color:#43ac6a;border-color:#3c9a5f}.btn-success .badge{color:#43ac6a;background-color:#ffffff}.btn-info{color:#ffffff;background-color:#5bc0de;border-color:#46b8da}.btn-info:focus,.btn-info.focus{color:#ffffff;background-color:#31b0d5;border-color:#1b6d85}.btn-info:hover{color:#ffffff;background-color:#31b0d5;border-color:#269abc}.btn-info:active,.btn-info.active,.open>.dropdown-toggle.btn-info{color:#ffffff;background-color:#31b0d5;border-color:#269abc}.btn-info:active:hover,.btn-info.active:hover,.open>.dropdown-toggle.btn-info:hover,.btn-info:active:focus,.btn-info.active:focus,.open>.dropdown-toggle.btn-info:focus,.btn-info:active.focus,.btn-info.active.focus,.open>.dropdown-toggle.btn-info.focus{color:#ffffff;background-color:#269abc;border-color:#1b6d85}.btn-info:active,.btn-info.active,.open>.dropdown-toggle.btn-info{background-image:none}.btn-info.disabled:hover,.btn-info[disabled]:hover,fieldset[disabled] .btn-info:hover,.btn-info.disabled:focus,.btn-info[disabled]:focus,fieldset[disabled] .btn-info:focus,.btn-info.disabled.focus,.btn-info[disabled].focus,fieldset[disabled] .btn-info.focus{background-color:#5bc0de;border-color:#46b8da}.btn-info .badge{color:#5bc0de;background-color:#ffffff}.btn-warning{color:#ffffff;background-color:#e99002;border-color:#d08002}.btn-warning:focus,.btn-warning.focus{color:#ffffff;background-color:#b67102;border-color:#513201}.btn-warning:hover{color:#ffffff;background-color:#b67102;border-color:#935b01}.btn-warning:active,.btn-warning.active,.open>.dropdown-toggle.btn-warning{color:#ffffff;background-color:#b67102;border-color:#935b01}.btn-warning:active:hover,.btn-warning.active:hover,.open>.dropdown-toggle.btn-warning:hover,.btn-warning:active:focus,.btn-warning.active:focus,.open>.dropdown-toggle.btn-warning:focus,.btn-warning:active.focus,.btn-warning.active.focus,.open>.dropdown-toggle.btn-warning.focus{color:#ffffff;background-color:#935b01;border-color:#513201}.btn-warning:active,.btn-warning.active,.open>.dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled:hover,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning:hover,.btn-warning.disabled:focus,.btn-warning[disabled]:focus,fieldset[disabled] .btn-warning:focus,.btn-warning.disabled.focus,.btn-warning[disabled].focus,fieldset[disabled] .btn-warning.focus{background-color:#e99002;border-color:#d08002}.btn-warning .badge{color:#e99002;background-color:#ffffff}.btn-danger{color:#ffffff;background-color:#f04124;border-color:#ea2f10}.btn-danger:focus,.btn-danger.focus{color:#ffffff;background-color:#d32a0e;border-color:#731708}.btn-danger:hover{color:#ffffff;background-color:#d32a0e;border-color:#b1240c}.btn-danger:active,.btn-danger.active,.open>.dropdown-toggle.btn-danger{color:#ffffff;background-color:#d32a0e;border-color:#b1240c}.btn-danger:active:hover,.btn-danger.active:hover,.open>.dropdown-toggle.btn-danger:hover,.btn-danger:active:focus,.btn-danger.active:focus,.open>.dropdown-toggle.btn-danger:focus,.btn-danger:active.focus,.btn-danger.active.focus,.open>.dropdown-toggle.btn-danger.focus{color:#ffffff;background-color:#b1240c;border-color:#731708}.btn-danger:active,.btn-danger.active,.open>.dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled:hover,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger:hover,.btn-danger.disabled:focus,.btn-danger[disabled]:focus,fieldset[disabled] .btn-danger:focus,.btn-danger.disabled.focus,.btn-danger[disabled].focus,fieldset[disabled] .btn-danger.focus{background-color:#f04124;border-color:#ea2f10}.btn-danger .badge{color:#f04124;background-color:#ffffff}.btn-link{color:#008cba;font-weight:normal;border-radius:0}.btn-link,.btn-link:active,.btn-link.active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:hover,.btn-link:focus,.btn-link:active{border-color:transparent}.btn-link:hover,.btn-link:focus{color:#008cba;text-decoration:underline;background-color:transparent}.btn-link[disabled]:hover,fieldset[disabled] .btn-link:hover,.btn-link[disabled]:focus,fieldset[disabled] .btn-link:focus{color:#999999;text-decoration:none}.btn-lg,.btn-group-lg>.btn{padding:16px 20px;font-size:19px;line-height:1.3333333;border-radius:0}.btn-sm,.btn-group-sm>.btn{padding:8px 12px;font-size:12px;border-radius:0}.btn-xs,.btn-group-xs>.btn{padding:4px 6px;font-size:12px;line-height:1.5;border-radius:0}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:5px}input[type="submit"].btn-block,input[type="reset"].btn-block,input[type="button"].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity 0.15s linear;-o-transition:opacity 0.15s linear;transition:opacity 0.15s linear}.fade.in{opacity:1}.collapse{display:none}.collapse.in{display:block}tr.collapse.in{display:table-row}tbody.collapse.in{display:table-row-group}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition-property:height, visibility;-o-transition-property:height, visibility;transition-property:height, visibility;-webkit-transition-duration:0.35s;-o-transition-duration:0.35s;transition-duration:0.35s;-webkit-transition-timing-function:ease;-o-transition-timing-function:ease;transition-timing-function:ease}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px dashed;border-top:4px solid \9;border-right:4px solid transparent;border-left:4px solid transparent}.dropup,.dropdown{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;list-style:none;font-size:15px;text-align:left;background-color:#ffffff;border:1px solid #cccccc;border:1px solid rgba(0,0,0,0.15);border-radius:0;-webkit-box-shadow:0 6px 12px rgba(0,0,0,0.175);box-shadow:0 6px 12px rgba(0,0,0,0.175);-webkit-background-clip:padding-box;background-clip:padding-box}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9.5px 0;overflow:hidden;background-color:rgba(0,0,0,0.2)}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:normal;line-height:1.4;color:#555555;white-space:nowrap}.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus{text-decoration:none;color:#262626;background-color:#eeeeee}.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{color:#ffffff;text-decoration:none;outline:0;background-color:#008cba}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{color:#999999}.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{text-decoration:none;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);cursor:not-allowed}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{left:auto;right:0}.dropdown-menu-left{left:0;right:auto}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.4;color:#999999;white-space:nowrap}.dropdown-backdrop{position:fixed;left:0;right:0;bottom:0;top:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{border-top:0;border-bottom:4px dashed;border-bottom:4px solid \9;content:""}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:2px}@media (min-width:768px){.navbar-right .dropdown-menu{left:auto;right:0}.navbar-right .dropdown-menu-left{left:0;right:auto}}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group>.btn,.btn-group-vertical>.btn{position:relative;float:left}.btn-group>.btn:hover,.btn-group-vertical>.btn:hover,.btn-group>.btn:focus,.btn-group-vertical>.btn:focus,.btn-group>.btn:active,.btn-group-vertical>.btn:active,.btn-group>.btn.active,.btn-group-vertical>.btn.active{z-index:2}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{margin-left:-5px}.btn-toolbar .btn,.btn-toolbar .btn-group,.btn-toolbar .input-group{float:left}.btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-top-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-top-right-radius:0}.btn-group>.btn-group:last-child:not(:first-child)>.btn:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{padding-left:8px;padding-right:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-left:12px;padding-right:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);box-shadow:inset 0 3px 5px rgba(0,0,0,0.125)}.btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none}.btn .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0}.dropup .btn-lg .caret{border-width:0 5px 5px}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-top-right-radius:0;border-top-left-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-top-right-radius:0;border-top-left-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-right-radius:0;border-top-left-radius:0}.btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate}.btn-group-justified>.btn,.btn-group-justified>.btn-group{float:none;display:table-cell;width:1%}.btn-group-justified>.btn-group .btn{width:100%}.btn-group-justified>.btn-group .dropdown-menu{left:auto}[data-toggle="buttons"]>.btn input[type="radio"],[data-toggle="buttons"]>.btn-group>.btn input[type="radio"],[data-toggle="buttons"]>.btn input[type="checkbox"],[data-toggle="buttons"]>.btn-group>.btn input[type="checkbox"]{position:absolute;clip:rect(0, 0, 0, 0);pointer-events:none}.input-group{position:relative;display:table;border-collapse:separate}.input-group[class*="col-"]{float:none;padding-left:0;padding-right:0}.input-group .form-control{position:relative;z-index:2;float:left;width:100%;margin-bottom:0}.input-group .form-control:focus{z-index:3}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:60px;padding:16px 20px;font-size:19px;line-height:1.3333333;border-radius:0}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:60px;line-height:60px}textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn,select[multiple].input-group-lg>.form-control,select[multiple].input-group-lg>.input-group-addon,select[multiple].input-group-lg>.input-group-btn>.btn{height:auto}.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{height:36px;padding:8px 12px;font-size:12px;line-height:1.5;border-radius:0}select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{height:36px;line-height:36px}textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn,select[multiple].input-group-sm>.form-control,select[multiple].input-group-sm>.input-group-addon,select[multiple].input-group-sm>.input-group-btn>.btn{height:auto}.input-group-addon,.input-group-btn,.input-group .form-control{display:table-cell}.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child),.input-group .form-control:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.input-group-addon{padding:8px 12px;font-size:15px;font-weight:normal;line-height:1;color:#6f6f6f;text-align:center;background-color:#eeeeee;border:1px solid #cccccc;border-radius:0}.input-group-addon.input-sm{padding:8px 12px;font-size:12px;border-radius:0}.input-group-addon.input-lg{padding:16px 20px;font-size:19px;border-radius:0}.input-group-addon input[type="radio"],.input-group-addon input[type="checkbox"]{margin-top:0}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle),.input-group-btn:last-child>.btn-group:not(:last-child)>.btn{border-bottom-right-radius:0;border-top-right-radius:0}.input-group-addon:first-child{border-right:0}.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group>.btn,.input-group-btn:last-child>.dropdown-toggle,.input-group-btn:first-child>.btn:not(:first-child),.input-group-btn:first-child>.btn-group:not(:first-child)>.btn{border-bottom-left-radius:0;border-top-left-radius:0}.input-group-addon:last-child{border-left:0}.input-group-btn{position:relative;font-size:0;white-space:nowrap}.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-left:-1px}.input-group-btn>.btn:hover,.input-group-btn>.btn:focus,.input-group-btn>.btn:active{z-index:2}.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group{margin-right:-1px}.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group{z-index:2;margin-left:-1px}.nav{margin-bottom:0;padding-left:0;list-style:none}.nav>li{position:relative;display:block}.nav>li>a{position:relative;display:block;padding:10px 15px}.nav>li>a:hover,.nav>li>a:focus{text-decoration:none;background-color:#eeeeee}.nav>li.disabled>a{color:#999999}.nav>li.disabled>a:hover,.nav>li.disabled>a:focus{color:#999999;text-decoration:none;background-color:transparent;cursor:not-allowed}.nav .open>a,.nav .open>a:hover,.nav .open>a:focus{background-color:#eeeeee;border-color:#008cba}.nav .nav-divider{height:1px;margin:9.5px 0;overflow:hidden;background-color:#e5e5e5}.nav>li>a>img{max-width:none}.nav-tabs{border-bottom:1px solid #dddddd}.nav-tabs>li{float:left;margin-bottom:-1px}.nav-tabs>li>a{margin-right:2px;line-height:1.4;border:1px solid transparent;border-radius:0 0 0 0}.nav-tabs>li>a:hover{border-color:#eeeeee #eeeeee #dddddd}.nav-tabs>li.active>a,.nav-tabs>li.active>a:hover,.nav-tabs>li.active>a:focus{color:#6f6f6f;background-color:#ffffff;border:1px solid #dddddd;border-bottom-color:transparent;cursor:default}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{text-align:center;margin-bottom:5px}.nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}.nav-tabs.nav-justified>li>a{margin-bottom:0}}.nav-tabs.nav-justified>li>a{margin-right:0;border-radius:0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:hover,.nav-tabs.nav-justified>.active>a:focus{border:1px solid #dddddd}@media (min-width:768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid #dddddd;border-radius:0 0 0 0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:hover,.nav-tabs.nav-justified>.active>a:focus{border-bottom-color:#ffffff}}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:0}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a,.nav-pills>li.active>a:hover,.nav-pills>li.active>a:focus{color:#ffffff;background-color:#008cba}.nav-stacked>li{float:none}.nav-stacked>li+li{margin-top:2px;margin-left:0}.nav-justified{width:100%}.nav-justified>li{float:none}.nav-justified>li>a{text-align:center;margin-bottom:5px}.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a{margin-bottom:0}}.nav-tabs-justified{border-bottom:0}.nav-tabs-justified>li>a{margin-right:0;border-radius:0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:hover,.nav-tabs-justified>.active>a:focus{border:1px solid #dddddd}@media (min-width:768px){.nav-tabs-justified>li>a{border-bottom:1px solid #dddddd;border-radius:0 0 0 0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:hover,.nav-tabs-justified>.active>a:focus{border-bottom-color:#ffffff}}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-right-radius:0;border-top-left-radius:0}.navbar{position:relative;min-height:45px;margin-bottom:21px;border:1px solid transparent}@media (min-width:768px){.navbar{border-radius:0}}@media (min-width:768px){.navbar-header{float:left}}.navbar-collapse{overflow-x:visible;padding-right:15px;padding-left:15px;border-top:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1);box-shadow:inset 0 1px 0 rgba(255,255,255,0.1);-webkit-overflow-scrolling:touch}.navbar-collapse.in{overflow-y:auto}@media (min-width:768px){.navbar-collapse{width:auto;border-top:0;-webkit-box-shadow:none;box-shadow:none}.navbar-collapse.collapse{display:block !important;height:auto !important;padding-bottom:0;overflow:visible !important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{padding-left:0;padding-right:0}}.navbar-fixed-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{max-height:340px}@media (max-device-width:480px) and (orientation:landscape){.navbar-fixed-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{max-height:200px}}.container>.navbar-header,.container-fluid>.navbar-header,.container>.navbar-collapse,.container-fluid>.navbar-collapse{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.container>.navbar-header,.container-fluid>.navbar-header,.container>.navbar-collapse,.container-fluid>.navbar-collapse{margin-right:0;margin-left:0}}.navbar-static-top{z-index:1000;border-width:0 0 1px}@media (min-width:768px){.navbar-static-top{border-radius:0}}.navbar-fixed-top,.navbar-fixed-bottom{position:fixed;right:0;left:0;z-index:1030}@media (min-width:768px){.navbar-fixed-top,.navbar-fixed-bottom{border-radius:0}}.navbar-fixed-top{top:0;border-width:0 0 1px}.navbar-fixed-bottom{bottom:0;margin-bottom:0;border-width:1px 0 0}.navbar-brand{float:left;padding:12px 15px;font-size:19px;line-height:21px;height:45px}.navbar-brand:hover,.navbar-brand:focus{text-decoration:none}.navbar-brand>img{display:block}@media (min-width:768px){.navbar>.container .navbar-brand,.navbar>.container-fluid .navbar-brand{margin-left:-15px}}.navbar-toggle{position:relative;float:right;margin-right:15px;padding:9px 10px;margin-top:5.5px;margin-bottom:5.5px;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:0}.navbar-toggle:focus{outline:0}.navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media (min-width:768px){.navbar-toggle{display:none}}.navbar-nav{margin:6px -15px}.navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:21px}@media (max-width:767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;-webkit-box-shadow:none;box-shadow:none}.navbar-nav .open .dropdown-menu>li>a,.navbar-nav .open .dropdown-menu .dropdown-header{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:21px}.navbar-nav .open .dropdown-menu>li>a:hover,.navbar-nav .open .dropdown-menu>li>a:focus{background-image:none}}@media (min-width:768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:12px;padding-bottom:12px}}.navbar-form{margin-left:-15px;margin-right:-15px;padding:10px 15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);margin-top:3px;margin-bottom:3px}@media (min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block;width:auto;vertical-align:middle}.navbar-form .form-control-static{display:inline-block}.navbar-form .input-group{display:inline-table;vertical-align:middle}.navbar-form .input-group .input-group-addon,.navbar-form .input-group .input-group-btn,.navbar-form .input-group .form-control{width:auto}.navbar-form .input-group>.form-control{width:100%}.navbar-form .control-label{margin-bottom:0;vertical-align:middle}.navbar-form .radio,.navbar-form .checkbox{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.navbar-form .radio label,.navbar-form .checkbox label{padding-left:0}.navbar-form .radio input[type="radio"],.navbar-form .checkbox input[type="checkbox"]{position:relative;margin-left:0}.navbar-form .has-feedback .form-control-feedback{top:0}}@media (max-width:767px){.navbar-form .form-group{margin-bottom:5px}.navbar-form .form-group:last-child{margin-bottom:0}}@media (min-width:768px){.navbar-form{width:auto;border:0;margin-left:0;margin-right:0;padding-top:0;padding-bottom:0;-webkit-box-shadow:none;box-shadow:none}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-right-radius:0;border-top-left-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{margin-bottom:0;border-top-right-radius:0;border-top-left-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:0}.navbar-btn{margin-top:3px;margin-bottom:3px}.navbar-btn.btn-sm{margin-top:4.5px;margin-bottom:4.5px}.navbar-btn.btn-xs{margin-top:11.5px;margin-bottom:11.5px}.navbar-text{margin-top:12px;margin-bottom:12px}@media (min-width:768px){.navbar-text{float:left;margin-left:15px;margin-right:15px}}@media (min-width:768px){.navbar-left{float:left !important}.navbar-right{float:right !important;margin-right:-15px}.navbar-right~.navbar-right{margin-right:0}}.navbar-default{background-color:#333333;border-color:#222222}.navbar-default .navbar-brand{color:#ffffff}.navbar-default .navbar-brand:hover,.navbar-default .navbar-brand:focus{color:#ffffff;background-color:transparent}.navbar-default .navbar-text{color:#ffffff}.navbar-default .navbar-nav>li>a{color:#ffffff}.navbar-default .navbar-nav>li>a:hover,.navbar-default .navbar-nav>li>a:focus{color:#ffffff;background-color:#272727}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:hover,.navbar-default .navbar-nav>.active>a:focus{color:#ffffff;background-color:#272727}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:hover,.navbar-default .navbar-nav>.disabled>a:focus{color:#cccccc;background-color:transparent}.navbar-default .navbar-toggle{border-color:transparent}.navbar-default .navbar-toggle:hover,.navbar-default .navbar-toggle:focus{background-color:transparent}.navbar-default .navbar-toggle .icon-bar{background-color:#ffffff}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#222222}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:hover,.navbar-default .navbar-nav>.open>a:focus{background-color:#272727;color:#ffffff}@media (max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#ffffff}.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus{color:#ffffff;background-color:#272727}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus{color:#ffffff;background-color:#272727}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus{color:#cccccc;background-color:transparent}}.navbar-default .navbar-link{color:#ffffff}.navbar-default .navbar-link:hover{color:#ffffff}.navbar-default .btn-link{color:#ffffff}.navbar-default .btn-link:hover,.navbar-default .btn-link:focus{color:#ffffff}.navbar-default .btn-link[disabled]:hover,fieldset[disabled] .navbar-default .btn-link:hover,.navbar-default .btn-link[disabled]:focus,fieldset[disabled] .navbar-default .btn-link:focus{color:#cccccc}.navbar-inverse{background-color:#008cba;border-color:#006687}.navbar-inverse .navbar-brand{color:#ffffff}.navbar-inverse .navbar-brand:hover,.navbar-inverse .navbar-brand:focus{color:#ffffff;background-color:transparent}.navbar-inverse .navbar-text{color:#ffffff}.navbar-inverse .navbar-nav>li>a{color:#ffffff}.navbar-inverse .navbar-nav>li>a:hover,.navbar-inverse .navbar-nav>li>a:focus{color:#ffffff;background-color:#006687}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:hover,.navbar-inverse .navbar-nav>.active>a:focus{color:#ffffff;background-color:#006687}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:hover,.navbar-inverse .navbar-nav>.disabled>a:focus{color:#444444;background-color:transparent}.navbar-inverse .navbar-toggle{border-color:transparent}.navbar-inverse .navbar-toggle:hover,.navbar-inverse .navbar-toggle:focus{background-color:transparent}.navbar-inverse .navbar-toggle .icon-bar{background-color:#ffffff}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#007196}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:hover,.navbar-inverse .navbar-nav>.open>a:focus{background-color:#006687;color:#ffffff}@media (max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#006687}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#006687}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#ffffff}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus{color:#ffffff;background-color:#006687}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus{color:#ffffff;background-color:#006687}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus{color:#444444;background-color:transparent}}.navbar-inverse .navbar-link{color:#ffffff}.navbar-inverse .navbar-link:hover{color:#ffffff}.navbar-inverse .btn-link{color:#ffffff}.navbar-inverse .btn-link:hover,.navbar-inverse .btn-link:focus{color:#ffffff}.navbar-inverse .btn-link[disabled]:hover,fieldset[disabled] .navbar-inverse .btn-link:hover,.navbar-inverse .btn-link[disabled]:focus,fieldset[disabled] .navbar-inverse .btn-link:focus{color:#444444}.breadcrumb{padding:8px 15px;margin-bottom:21px;list-style:none;background-color:#f5f5f5;border-radius:0}.breadcrumb>li{display:inline-block}.breadcrumb>li+li:before{content:"/\00a0";padding:0 5px;color:#999999}.breadcrumb>.active{color:#333333}.pagination{display:inline-block;padding-left:0;margin:21px 0;border-radius:0}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:8px 12px;line-height:1.4;text-decoration:none;color:#008cba;background-color:transparent;border:1px solid transparent;margin-left:-1px}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-bottom-left-radius:0;border-top-left-radius:0}.pagination>li:last-child>a,.pagination>li:last-child>span{border-bottom-right-radius:0;border-top-right-radius:0}.pagination>li>a:hover,.pagination>li>span:hover,.pagination>li>a:focus,.pagination>li>span:focus{z-index:2;color:#008cba;background-color:#eeeeee;border-color:transparent}.pagination>.active>a,.pagination>.active>span,.pagination>.active>a:hover,.pagination>.active>span:hover,.pagination>.active>a:focus,.pagination>.active>span:focus{z-index:3;color:#ffffff;background-color:#008cba;border-color:transparent;cursor:default}.pagination>.disabled>span,.pagination>.disabled>span:hover,.pagination>.disabled>span:focus,.pagination>.disabled>a,.pagination>.disabled>a:hover,.pagination>.disabled>a:focus{color:#999999;background-color:#ffffff;border-color:transparent;cursor:not-allowed}.pagination-lg>li>a,.pagination-lg>li>span{padding:16px 20px;font-size:19px;line-height:1.3333333}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-bottom-left-radius:0;border-top-left-radius:0}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-bottom-right-radius:0;border-top-right-radius:0}.pagination-sm>li>a,.pagination-sm>li>span{padding:8px 12px;font-size:12px;line-height:1.5}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-bottom-left-radius:0;border-top-left-radius:0}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-bottom-right-radius:0;border-top-right-radius:0}.pager{padding-left:0;margin:21px 0;list-style:none;text-align:center}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:transparent;border:1px solid transparent;border-radius:3px}.pager li>a:hover,.pager li>a:focus{text-decoration:none;background-color:#eeeeee}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:hover,.pager .disabled>a:focus,.pager .disabled>span{color:#999999;background-color:transparent;cursor:not-allowed}.label{display:inline;padding:.2em .6em .3em;font-weight:bold;line-height:1;color:#ffffff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}a.label:hover,a.label:focus{color:#ffffff;text-decoration:none;cursor:pointer}.label:empty{display:none}.btn .label{position:relative;top:-1px}.label-default{background-color:#999999}.label-default[href]:hover,.label-default[href]:focus{background-color:#808080}.label-primary{background-color:#008cba}.label-primary[href]:hover,.label-primary[href]:focus{background-color:#006687}.label-success{background-color:#43ac6a}.label-success[href]:hover,.label-success[href]:focus{background-color:#358753}.label-info{background-color:#5bc0de}.label-info[href]:hover,.label-info[href]:focus{background-color:#31b0d5}.label-warning{background-color:#e99002}.label-warning[href]:hover,.label-warning[href]:focus{background-color:#b67102}.label-danger{background-color:#f04124}.label-danger[href]:hover,.label-danger[href]:focus{background-color:#d32a0e}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:bold;color:#ffffff;line-height:1;vertical-align:middle;white-space:nowrap;text-align:center;background-color:#008cba;border-radius:10px}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.btn-xs .badge,.btn-group-xs>.btn .badge{top:0;padding:1px 5px}a.badge:hover,a.badge:focus{color:#ffffff;text-decoration:none;cursor:pointer}.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#008cba;background-color:#ffffff}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding-top:30px;padding-bottom:30px;margin-bottom:30px;color:inherit;background-color:#fafafa}.jumbotron h1,.jumbotron .h1{color:inherit}.jumbotron p{margin-bottom:15px;font-size:23px;font-weight:200}.jumbotron>hr{border-top-color:#e1e1e1}.container .jumbotron,.container-fluid .jumbotron{border-radius:0;padding-left:15px;padding-right:15px}.jumbotron .container{max-width:100%}@media screen and (min-width:768px){.jumbotron{padding-top:48px;padding-bottom:48px}.container .jumbotron,.container-fluid .jumbotron{padding-left:60px;padding-right:60px}.jumbotron h1,.jumbotron .h1{font-size:68px}}.thumbnail{display:block;padding:4px;margin-bottom:21px;line-height:1.4;background-color:#ffffff;border:1px solid #dddddd;border-radius:0;-webkit-transition:border .2s ease-in-out;-o-transition:border .2s ease-in-out;transition:border .2s ease-in-out}.thumbnail>img,.thumbnail a>img{margin-left:auto;margin-right:auto}a.thumbnail:hover,a.thumbnail:focus,a.thumbnail.active{border-color:#008cba}.thumbnail .caption{padding:9px;color:#222222}.alert{padding:15px;margin-bottom:21px;border:1px solid transparent;border-radius:0}.alert h4{margin-top:0;color:inherit}.alert .alert-link{font-weight:bold}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable,.alert-dismissible{padding-right:35px}.alert-dismissable .close,.alert-dismissible .close{position:relative;top:-2px;right:-21px;color:inherit}.alert-success{background-color:#43ac6a;border-color:#3c9a5f;color:#ffffff}.alert-success hr{border-top-color:#358753}.alert-success .alert-link{color:#e6e6e6}.alert-info{background-color:#5bc0de;border-color:#3db5d8;color:#ffffff}.alert-info hr{border-top-color:#2aabd2}.alert-info .alert-link{color:#e6e6e6}.alert-warning{background-color:#e99002;border-color:#d08002;color:#ffffff}.alert-warning hr{border-top-color:#b67102}.alert-warning .alert-link{color:#e6e6e6}.alert-danger{background-color:#f04124;border-color:#ea2f10;color:#ffffff}.alert-danger hr{border-top-color:#d32a0e}.alert-danger .alert-link{color:#e6e6e6}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{overflow:hidden;height:21px;margin-bottom:21px;background-color:#f5f5f5;border-radius:0;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);box-shadow:inset 0 1px 2px rgba(0,0,0,0.1)}.progress-bar{float:left;width:0%;height:100%;font-size:12px;line-height:21px;color:#ffffff;text-align:center;background-color:#008cba;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);-webkit-transition:width 0.6s ease;-o-transition:width 0.6s ease;transition:width 0.6s ease}.progress-striped .progress-bar,.progress-bar-striped{background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);-webkit-background-size:40px 40px;background-size:40px 40px}.progress.active .progress-bar,.progress-bar.active{-webkit-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-bar-success{background-color:#43ac6a}.progress-striped .progress-bar-success{background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent)}.progress-bar-info{background-color:#5bc0de}.progress-striped .progress-bar-info{background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent)}.progress-bar-warning{background-color:#e99002}.progress-striped .progress-bar-warning{background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent)}.progress-bar-danger{background-color:#f04124}.progress-striped .progress-bar-danger{background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent)}.media{margin-top:15px}.media:first-child{margin-top:0}.media,.media-body{zoom:1;overflow:hidden}.media-body{width:10000px}.media-object{display:block}.media-object.img-thumbnail{max-width:none}.media-right,.media>.pull-right{padding-left:10px}.media-left,.media>.pull-left{padding-right:10px}.media-left,.media-right,.media-body{display:table-cell;vertical-align:top}.media-middle{vertical-align:middle}.media-bottom{vertical-align:bottom}.media-heading{margin-top:0;margin-bottom:5px}.media-list{padding-left:0;list-style:none}.list-group{margin-bottom:20px;padding-left:0}.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#ffffff;border:1px solid #dddddd}.list-group-item:first-child{border-top-right-radius:0;border-top-left-radius:0}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:0;border-bottom-left-radius:0}a.list-group-item,button.list-group-item{color:#555555}a.list-group-item .list-group-item-heading,button.list-group-item .list-group-item-heading{color:#333333}a.list-group-item:hover,button.list-group-item:hover,a.list-group-item:focus,button.list-group-item:focus{text-decoration:none;color:#555555;background-color:#f5f5f5}button.list-group-item{width:100%;text-align:left}.list-group-item.disabled,.list-group-item.disabled:hover,.list-group-item.disabled:focus{background-color:#eeeeee;color:#999999;cursor:not-allowed}.list-group-item.disabled .list-group-item-heading,.list-group-item.disabled:hover .list-group-item-heading,.list-group-item.disabled:focus .list-group-item-heading{color:inherit}.list-group-item.disabled .list-group-item-text,.list-group-item.disabled:hover .list-group-item-text,.list-group-item.disabled:focus .list-group-item-text{color:#999999}.list-group-item.active,.list-group-item.active:hover,.list-group-item.active:focus{z-index:2;color:#ffffff;background-color:#008cba;border-color:#008cba}.list-group-item.active .list-group-item-heading,.list-group-item.active:hover .list-group-item-heading,.list-group-item.active:focus .list-group-item-heading,.list-group-item.active .list-group-item-heading>small,.list-group-item.active:hover .list-group-item-heading>small,.list-group-item.active:focus .list-group-item-heading>small,.list-group-item.active .list-group-item-heading>.small,.list-group-item.active:hover .list-group-item-heading>.small,.list-group-item.active:focus .list-group-item-heading>.small{color:inherit}.list-group-item.active .list-group-item-text,.list-group-item.active:hover .list-group-item-text,.list-group-item.active:focus .list-group-item-text{color:#87e1ff}.list-group-item-success{color:#43ac6a;background-color:#dff0d8}a.list-group-item-success,button.list-group-item-success{color:#43ac6a}a.list-group-item-success .list-group-item-heading,button.list-group-item-success .list-group-item-heading{color:inherit}a.list-group-item-success:hover,button.list-group-item-success:hover,a.list-group-item-success:focus,button.list-group-item-success:focus{color:#43ac6a;background-color:#d0e9c6}a.list-group-item-success.active,button.list-group-item-success.active,a.list-group-item-success.active:hover,button.list-group-item-success.active:hover,a.list-group-item-success.active:focus,button.list-group-item-success.active:focus{color:#fff;background-color:#43ac6a;border-color:#43ac6a}.list-group-item-info{color:#5bc0de;background-color:#d9edf7}a.list-group-item-info,button.list-group-item-info{color:#5bc0de}a.list-group-item-info .list-group-item-heading,button.list-group-item-info .list-group-item-heading{color:inherit}a.list-group-item-info:hover,button.list-group-item-info:hover,a.list-group-item-info:focus,button.list-group-item-info:focus{color:#5bc0de;background-color:#c4e3f3}a.list-group-item-info.active,button.list-group-item-info.active,a.list-group-item-info.active:hover,button.list-group-item-info.active:hover,a.list-group-item-info.active:focus,button.list-group-item-info.active:focus{color:#fff;background-color:#5bc0de;border-color:#5bc0de}.list-group-item-warning{color:#e99002;background-color:#fcf8e3}a.list-group-item-warning,button.list-group-item-warning{color:#e99002}a.list-group-item-warning .list-group-item-heading,button.list-group-item-warning .list-group-item-heading{color:inherit}a.list-group-item-warning:hover,button.list-group-item-warning:hover,a.list-group-item-warning:focus,button.list-group-item-warning:focus{color:#e99002;background-color:#faf2cc}a.list-group-item-warning.active,button.list-group-item-warning.active,a.list-group-item-warning.active:hover,button.list-group-item-warning.active:hover,a.list-group-item-warning.active:focus,button.list-group-item-warning.active:focus{color:#fff;background-color:#e99002;border-color:#e99002}.list-group-item-danger{color:#f04124;background-color:#f2dede}a.list-group-item-danger,button.list-group-item-danger{color:#f04124}a.list-group-item-danger .list-group-item-heading,button.list-group-item-danger .list-group-item-heading{color:inherit}a.list-group-item-danger:hover,button.list-group-item-danger:hover,a.list-group-item-danger:focus,button.list-group-item-danger:focus{color:#f04124;background-color:#ebcccc}a.list-group-item-danger.active,button.list-group-item-danger.active,a.list-group-item-danger.active:hover,button.list-group-item-danger.active:hover,a.list-group-item-danger.active:focus,button.list-group-item-danger.active:focus{color:#fff;background-color:#f04124;border-color:#f04124}.list-group-item-heading{margin-top:0;margin-bottom:5px}.list-group-item-text{margin-bottom:0;line-height:1.3}.panel{margin-bottom:21px;background-color:#ffffff;border:1px solid transparent;border-radius:0;-webkit-box-shadow:0 1px 1px rgba(0,0,0,0.05);box-shadow:0 1px 1px rgba(0,0,0,0.05)}.panel-body{padding:15px}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-right-radius:-1;border-top-left-radius:-1}.panel-heading>.dropdown .dropdown-toggle{color:inherit}.panel-title{margin-top:0;margin-bottom:0;font-size:17px;color:inherit}.panel-title>a,.panel-title>small,.panel-title>.small,.panel-title>small>a,.panel-title>.small>a{color:inherit}.panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #dddddd;border-bottom-right-radius:-1;border-bottom-left-radius:-1}.panel>.list-group,.panel>.panel-collapse>.list-group{margin-bottom:0}.panel>.list-group .list-group-item,.panel>.panel-collapse>.list-group .list-group-item{border-width:1px 0;border-radius:0}.panel>.list-group:first-child .list-group-item:first-child,.panel>.panel-collapse>.list-group:first-child .list-group-item:first-child{border-top:0;border-top-right-radius:-1;border-top-left-radius:-1}.panel>.list-group:last-child .list-group-item:last-child,.panel>.panel-collapse>.list-group:last-child .list-group-item:last-child{border-bottom:0;border-bottom-right-radius:-1;border-bottom-left-radius:-1}.panel>.panel-heading+.panel-collapse>.list-group .list-group-item:first-child{border-top-right-radius:0;border-top-left-radius:0}.panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.list-group+.panel-footer{border-top-width:0}.panel>.table,.panel>.table-responsive>.table,.panel>.panel-collapse>.table{margin-bottom:0}.panel>.table caption,.panel>.table-responsive>.table caption,.panel>.panel-collapse>.table caption{padding-left:15px;padding-right:15px}.panel>.table:first-child,.panel>.table-responsive:first-child>.table:first-child{border-top-right-radius:-1;border-top-left-radius:-1}.panel>.table:first-child>thead:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child{border-top-left-radius:-1;border-top-right-radius:-1}.panel>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:first-child{border-top-left-radius:-1}.panel>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:last-child{border-top-right-radius:-1}.panel>.table:last-child,.panel>.table-responsive:last-child>.table:last-child{border-bottom-right-radius:-1;border-bottom-left-radius:-1}.panel>.table:last-child>tbody:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child{border-bottom-left-radius:-1;border-bottom-right-radius:-1}.panel>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:first-child{border-bottom-left-radius:-1}.panel>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:last-child{border-bottom-right-radius:-1}.panel>.panel-body+.table,.panel>.panel-body+.table-responsive,.panel>.table+.panel-body,.panel>.table-responsive+.panel-body{border-top:1px solid #dddddd}.panel>.table>tbody:first-child>tr:first-child th,.panel>.table>tbody:first-child>tr:first-child td{border-top:0}.panel>.table-bordered,.panel>.table-responsive>.table-bordered{border:0}.panel>.table-bordered>thead>tr>th:first-child,.panel>.table-responsive>.table-bordered>thead>tr>th:first-child,.panel>.table-bordered>tbody>tr>th:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.panel>.table-bordered>tfoot>tr>th:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.panel>.table-bordered>thead>tr>td:first-child,.panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.panel>.table-bordered>tbody>tr>td:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.panel>.table-bordered>tfoot>tr>td:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child{border-left:0}.panel>.table-bordered>thead>tr>th:last-child,.panel>.table-responsive>.table-bordered>thead>tr>th:last-child,.panel>.table-bordered>tbody>tr>th:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.panel>.table-bordered>tfoot>tr>th:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.panel>.table-bordered>thead>tr>td:last-child,.panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.panel>.table-bordered>tbody>tr>td:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.panel>.table-bordered>tfoot>tr>td:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child{border-right:0}.panel>.table-bordered>thead>tr:first-child>td,.panel>.table-responsive>.table-bordered>thead>tr:first-child>td,.panel>.table-bordered>tbody>tr:first-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>td,.panel>.table-bordered>thead>tr:first-child>th,.panel>.table-responsive>.table-bordered>thead>tr:first-child>th,.panel>.table-bordered>tbody>tr:first-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>th{border-bottom:0}.panel>.table-bordered>tbody>tr:last-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.panel>.table-bordered>tfoot>tr:last-child>td,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td,.panel>.table-bordered>tbody>tr:last-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.panel>.table-bordered>tfoot>tr:last-child>th,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}.panel>.table-responsive{border:0;margin-bottom:0}.panel-group{margin-bottom:21px}.panel-group .panel{margin-bottom:0;border-radius:0}.panel-group .panel+.panel{margin-top:5px}.panel-group .panel-heading{border-bottom:0}.panel-group .panel-heading+.panel-collapse>.panel-body,.panel-group .panel-heading+.panel-collapse>.list-group{border-top:1px solid #dddddd}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #dddddd}.panel-default{border-color:#dddddd}.panel-default>.panel-heading{color:#333333;background-color:#f5f5f5;border-color:#dddddd}.panel-default>.panel-heading+.panel-collapse>.panel-body{border-top-color:#dddddd}.panel-default>.panel-heading .badge{color:#f5f5f5;background-color:#333333}.panel-default>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#dddddd}.panel-primary{border-color:#008cba}.panel-primary>.panel-heading{color:#ffffff;background-color:#008cba;border-color:#008cba}.panel-primary>.panel-heading+.panel-collapse>.panel-body{border-top-color:#008cba}.panel-primary>.panel-heading .badge{color:#008cba;background-color:#ffffff}.panel-primary>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#008cba}.panel-success{border-color:#3c9a5f}.panel-success>.panel-heading{color:#ffffff;background-color:#43ac6a;border-color:#3c9a5f}.panel-success>.panel-heading+.panel-collapse>.panel-body{border-top-color:#3c9a5f}.panel-success>.panel-heading .badge{color:#43ac6a;background-color:#ffffff}.panel-success>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#3c9a5f}.panel-info{border-color:#3db5d8}.panel-info>.panel-heading{color:#ffffff;background-color:#5bc0de;border-color:#3db5d8}.panel-info>.panel-heading+.panel-collapse>.panel-body{border-top-color:#3db5d8}.panel-info>.panel-heading .badge{color:#5bc0de;background-color:#ffffff}.panel-info>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#3db5d8}.panel-warning{border-color:#d08002}.panel-warning>.panel-heading{color:#ffffff;background-color:#e99002;border-color:#d08002}.panel-warning>.panel-heading+.panel-collapse>.panel-body{border-top-color:#d08002}.panel-warning>.panel-heading .badge{color:#e99002;background-color:#ffffff}.panel-warning>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#d08002}.panel-danger{border-color:#ea2f10}.panel-danger>.panel-heading{color:#ffffff;background-color:#f04124;border-color:#ea2f10}.panel-danger>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ea2f10}.panel-danger>.panel-heading .badge{color:#f04124;background-color:#ffffff}.panel-danger>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ea2f10}.embed-responsive{position:relative;display:block;height:0;padding:0;overflow:hidden}.embed-responsive .embed-responsive-item,.embed-responsive iframe,.embed-responsive embed,.embed-responsive object,.embed-responsive video{position:absolute;top:0;left:0;bottom:0;height:100%;width:100%;border:0}.embed-responsive-16by9{padding-bottom:56.25%}.embed-responsive-4by3{padding-bottom:75%}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#fafafa;border:1px solid #e8e8e8;border-radius:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);box-shadow:inset 0 1px 1px rgba(0,0,0,0.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,0.15)}.well-lg{padding:24px;border-radius:0}.well-sm{padding:9px;border-radius:0}.close{float:right;font-size:22.5px;font-weight:bold;line-height:1;color:#ffffff;text-shadow:0 1px 0 #ffffff;opacity:0.2;filter:alpha(opacity=20)}.close:hover,.close:focus{color:#ffffff;text-decoration:none;cursor:pointer;opacity:0.5;filter:alpha(opacity=50)}button.close{padding:0;cursor:pointer;background:transparent;border:0;-webkit-appearance:none}.modal-open{overflow:hidden}.modal{display:none;overflow:hidden;position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transform:translate(0, -25%);-ms-transform:translate(0, -25%);-o-transform:translate(0, -25%);transform:translate(0, -25%);-webkit-transition:-webkit-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .3s ease-out}.modal.in .modal-dialog{-webkit-transform:translate(0, 0);-ms-transform:translate(0, 0);-o-transform:translate(0, 0);transform:translate(0, 0)}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;background-color:#ffffff;border:1px solid #999999;border:1px solid rgba(0,0,0,0.2);border-radius:0;-webkit-box-shadow:0 3px 9px rgba(0,0,0,0.5);box-shadow:0 3px 9px rgba(0,0,0,0.5);-webkit-background-clip:padding-box;background-clip:padding-box;outline:0}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000000}.modal-backdrop.fade{opacity:0;filter:alpha(opacity=0)}.modal-backdrop.in{opacity:0.5;filter:alpha(opacity=50)}.modal-header{padding:15px;border-bottom:1px solid #e5e5e5}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.4}.modal-body{position:relative;padding:20px}.modal-footer{padding:20px;text-align:right;border-top:1px solid #e5e5e5}.modal-footer .btn+.btn{margin-left:5px;margin-bottom:0}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:768px){.modal-dialog{width:600px;margin:30px auto}.modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,0.5);box-shadow:0 5px 15px rgba(0,0,0,0.5)}.modal-sm{width:300px}}@media (min-width:992px){.modal-lg{width:900px}}.tooltip{position:absolute;z-index:1070;display:block;font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-style:normal;font-weight:normal;letter-spacing:normal;line-break:auto;line-height:1.4;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;white-space:normal;word-break:normal;word-spacing:normal;word-wrap:normal;font-size:12px;opacity:0;filter:alpha(opacity=0)}.tooltip.in{opacity:0.9;filter:alpha(opacity=90)}.tooltip.top{margin-top:-3px;padding:5px 0}.tooltip.right{margin-left:3px;padding:0 5px}.tooltip.bottom{margin-top:3px;padding:5px 0}.tooltip.left{margin-left:-3px;padding:0 5px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#ffffff;text-align:center;background-color:#333333;border-radius:0}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#333333}.tooltip.top-left .tooltip-arrow{bottom:0;right:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#333333}.tooltip.top-right .tooltip-arrow{bottom:0;left:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#333333}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#333333}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#333333}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#333333}.tooltip.bottom-left .tooltip-arrow{top:0;right:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#333333}.tooltip.bottom-right .tooltip-arrow{top:0;left:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#333333}.popover{position:absolute;top:0;left:0;z-index:1060;display:none;max-width:276px;padding:1px;font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-style:normal;font-weight:normal;letter-spacing:normal;line-break:auto;line-height:1.4;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;white-space:normal;word-break:normal;word-spacing:normal;word-wrap:normal;font-size:15px;background-color:#333333;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #333333;border:1px solid transparent;border-radius:0;-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);box-shadow:0 5px 10px rgba(0,0,0,0.2)}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{margin:0;padding:8px 14px;font-size:15px;background-color:#333333;border-bottom:1px solid #262626;border-radius:-1 -1 0 0}.popover-content{padding:9px 14px}.popover>.arrow,.popover>.arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover>.arrow{border-width:11px}.popover>.arrow:after{border-width:10px;content:""}.popover.top>.arrow{left:50%;margin-left:-11px;border-bottom-width:0;border-top-color:#000000;border-top-color:rgba(0,0,0,0.05);bottom:-11px}.popover.top>.arrow:after{content:" ";bottom:1px;margin-left:-10px;border-bottom-width:0;border-top-color:#333333}.popover.right>.arrow{top:50%;left:-11px;margin-top:-11px;border-left-width:0;border-right-color:#000000;border-right-color:rgba(0,0,0,0.05)}.popover.right>.arrow:after{content:" ";left:1px;bottom:-10px;border-left-width:0;border-right-color:#333333}.popover.bottom>.arrow{left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#000000;border-bottom-color:rgba(0,0,0,0.05);top:-11px}.popover.bottom>.arrow:after{content:" ";top:1px;margin-left:-10px;border-top-width:0;border-bottom-color:#333333}.popover.left>.arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#000000;border-left-color:rgba(0,0,0,0.05)}.popover.left>.arrow:after{content:" ";right:1px;border-right-width:0;border-left-color:#333333;bottom:-10px}.carousel{position:relative}.carousel-inner{position:relative;overflow:hidden;width:100%}.carousel-inner>.item{display:none;position:relative;-webkit-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>img,.carousel-inner>.item>a>img{line-height:1}@media all and (transform-3d),(-webkit-transform-3d){.carousel-inner>.item{-webkit-transition:-webkit-transform .6s ease-in-out;-o-transition:-o-transform .6s ease-in-out;transition:transform .6s ease-in-out;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000px;perspective:1000px}.carousel-inner>.item.next,.carousel-inner>.item.active.right{-webkit-transform:translate3d(100%, 0, 0);transform:translate3d(100%, 0, 0);left:0}.carousel-inner>.item.prev,.carousel-inner>.item.active.left{-webkit-transform:translate3d(-100%, 0, 0);transform:translate3d(-100%, 0, 0);left:0}.carousel-inner>.item.next.left,.carousel-inner>.item.prev.right,.carousel-inner>.item.active{-webkit-transform:translate3d(0, 0, 0);transform:translate3d(0, 0, 0);left:0}}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:0;left:0;bottom:0;width:15%;opacity:0.5;filter:alpha(opacity=50);font-size:20px;color:#ffffff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,0.6);background-color:rgba(0,0,0,0)}.carousel-control.left{background-image:-webkit-linear-gradient(left, rgba(0,0,0,0.5) 0, rgba(0,0,0,0.0001) 100%);background-image:-o-linear-gradient(left, rgba(0,0,0,0.5) 0, rgba(0,0,0,0.0001) 100%);background-image:-webkit-gradient(linear, left top, right top, from(rgba(0,0,0,0.5)), to(rgba(0,0,0,0.0001)));background-image:linear-gradient(to right, rgba(0,0,0,0.5) 0, rgba(0,0,0,0.0001) 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1)}.carousel-control.right{left:auto;right:0;background-image:-webkit-linear-gradient(left, rgba(0,0,0,0.0001) 0, rgba(0,0,0,0.5) 100%);background-image:-o-linear-gradient(left, rgba(0,0,0,0.0001) 0, rgba(0,0,0,0.5) 100%);background-image:-webkit-gradient(linear, left top, right top, from(rgba(0,0,0,0.0001)), to(rgba(0,0,0,0.5)));background-image:linear-gradient(to right, rgba(0,0,0,0.0001) 0, rgba(0,0,0,0.5) 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1)}.carousel-control:hover,.carousel-control:focus{outline:0;color:#ffffff;text-decoration:none;opacity:0.9;filter:alpha(opacity=90)}.carousel-control .icon-prev,.carousel-control .icon-next,.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right{position:absolute;top:50%;margin-top:-10px;z-index:5;display:inline-block}.carousel-control .icon-prev,.carousel-control .glyphicon-chevron-left{left:50%;margin-left:-10px}.carousel-control .icon-next,.carousel-control .glyphicon-chevron-right{right:50%;margin-right:-10px}.carousel-control .icon-prev,.carousel-control .icon-next{width:20px;height:20px;line-height:1;font-family:serif}.carousel-control .icon-prev:before{content:'\2039'}.carousel-control .icon-next:before{content:'\203a'}.carousel-indicators{position:absolute;bottom:10px;left:50%;z-index:15;width:60%;margin-left:-30%;padding-left:0;list-style:none;text-align:center}.carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;border:1px solid #ffffff;border-radius:10px;cursor:pointer;background-color:#000 \9;background-color:rgba(0,0,0,0)}.carousel-indicators .active{margin:0;width:12px;height:12px;background-color:#ffffff}.carousel-caption{position:absolute;left:15%;right:15%;bottom:20px;z-index:10;padding-top:20px;padding-bottom:20px;color:#ffffff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,0.6)}.carousel-caption .btn{text-shadow:none}@media screen and (min-width:768px){.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-prev,.carousel-control .icon-next{width:30px;height:30px;margin-top:-10px;font-size:30px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{margin-left:-10px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{margin-right:-10px}.carousel-caption{left:20%;right:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.clearfix:before,.clearfix:after,.dl-horizontal dd:before,.dl-horizontal dd:after,.container:before,.container:after,.container-fluid:before,.container-fluid:after,.row:before,.row:after,.form-horizontal .form-group:before,.form-horizontal .form-group:after,.btn-toolbar:before,.btn-toolbar:after,.btn-group-vertical>.btn-group:before,.btn-group-vertical>.btn-group:after,.nav:before,.nav:after,.navbar:before,.navbar:after,.navbar-header:before,.navbar-header:after,.navbar-collapse:before,.navbar-collapse:after,.pager:before,.pager:after,.panel-body:before,.panel-body:after,.modal-header:before,.modal-header:after,.modal-footer:before,.modal-footer:after{content:" ";display:table}.clearfix:after,.dl-horizontal dd:after,.container:after,.container-fluid:after,.row:after,.form-horizontal .form-group:after,.btn-toolbar:after,.btn-group-vertical>.btn-group:after,.nav:after,.navbar:after,.navbar-header:after,.navbar-collapse:after,.pager:after,.panel-body:after,.modal-header:after,.modal-footer:after{clear:both}.center-block{display:block;margin-left:auto;margin-right:auto}.pull-right{float:right !important}.pull-left{float:left !important}.hide{display:none !important}.show{display:block !important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none !important}.affix{position:fixed}@-ms-viewport{width:device-width}.visible-xs,.visible-sm,.visible-md,.visible-lg{display:none !important}.visible-xs-block,.visible-xs-inline,.visible-xs-inline-block,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-lg-block,.visible-lg-inline,.visible-lg-inline-block{display:none !important}@media (max-width:767px){.visible-xs{display:block !important}table.visible-xs{display:table !important}tr.visible-xs{display:table-row !important}th.visible-xs,td.visible-xs{display:table-cell !important}}@media (max-width:767px){.visible-xs-block{display:block !important}}@media (max-width:767px){.visible-xs-inline{display:inline !important}}@media (max-width:767px){.visible-xs-inline-block{display:inline-block !important}}@media (min-width:768px) and (max-width:991px){.visible-sm{display:block !important}table.visible-sm{display:table !important}tr.visible-sm{display:table-row !important}th.visible-sm,td.visible-sm{display:table-cell !important}}@media (min-width:768px) and (max-width:991px){.visible-sm-block{display:block !important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline{display:inline !important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline-block{display:inline-block !important}}@media (min-width:992px) and (max-width:1199px){.visible-md{display:block !important}table.visible-md{display:table !important}tr.visible-md{display:table-row !important}th.visible-md,td.visible-md{display:table-cell !important}}@media (min-width:992px) and (max-width:1199px){.visible-md-block{display:block !important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline{display:inline !important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline-block{display:inline-block !important}}@media (min-width:1200px){.visible-lg{display:block !important}table.visible-lg{display:table !important}tr.visible-lg{display:table-row !important}th.visible-lg,td.visible-lg{display:table-cell !important}}@media (min-width:1200px){.visible-lg-block{display:block !important}}@media (min-width:1200px){.visible-lg-inline{display:inline !important}}@media (min-width:1200px){.visible-lg-inline-block{display:inline-block !important}}@media (max-width:767px){.hidden-xs{display:none !important}}@media (min-width:768px) and (max-width:991px){.hidden-sm{display:none !important}}@media (min-width:992px) and (max-width:1199px){.hidden-md{display:none !important}}@media (min-width:1200px){.hidden-lg{display:none !important}}.visible-print{display:none !important}@media print{.visible-print{display:block !important}table.visible-print{display:table !important}tr.visible-print{display:table-row !important}th.visible-print,td.visible-print{display:table-cell !important}}.visible-print-block{display:none !important}@media print{.visible-print-block{display:block !important}}.visible-print-inline{display:none !important}@media print{.visible-print-inline{display:inline !important}}.visible-print-inline-block{display:none !important}@media print{.visible-print-inline-block{display:inline-block !important}}@media print{.hidden-print{display:none !important}}.navbar{border:none;font-size:13px;font-weight:300}.navbar .navbar-toggle:hover .icon-bar{background-color:#b3b3b3}.navbar-collapse{border-top-color:rgba(0,0,0,0.2);-webkit-box-shadow:none;box-shadow:none}.navbar .btn{padding-top:6px;padding-bottom:6px}.navbar-form{margin-top:7px;margin-bottom:5px}.navbar-form .form-control{height:auto;padding:4px 6px}.navbar-text{margin:12px 15px;line-height:21px}.navbar .dropdown-menu{border:none}.navbar .dropdown-menu>li>a,.navbar .dropdown-menu>li>a:focus{background-color:transparent;font-size:13px;font-weight:300}.navbar .dropdown-header{color:rgba(255,255,255,0.5)}.navbar-default .dropdown-menu{background-color:#333333}.navbar-default .dropdown-menu>li>a,.navbar-default .dropdown-menu>li>a:focus{color:#ffffff}.navbar-default .dropdown-menu>li>a:hover,.navbar-default .dropdown-menu>.active>a,.navbar-default .dropdown-menu>.active>a:hover{background-color:#272727}.navbar-inverse .dropdown-menu{background-color:#008cba}.navbar-inverse .dropdown-menu>li>a,.navbar-inverse .dropdown-menu>li>a:focus{color:#ffffff}.navbar-inverse .dropdown-menu>li>a:hover,.navbar-inverse .dropdown-menu>.active>a,.navbar-inverse .dropdown-menu>.active>a:hover{background-color:#006687}.btn{padding:8px 12px}.btn-lg{padding:16px 20px}.btn-sm{padding:8px 12px}.btn-xs{padding:4px 6px}.btn-group .btn~.dropdown-toggle{padding-left:16px;padding-right:16px}.btn-group .dropdown-menu{border-top-width:0}.btn-group.dropup .dropdown-menu{border-top-width:1px;border-bottom-width:0;margin-bottom:0}.btn-group .dropdown-toggle.btn-default~.dropdown-menu{background-color:#e7e7e7;border-color:#cccccc}.btn-group .dropdown-toggle.btn-default~.dropdown-menu>li>a{color:#333333}.btn-group .dropdown-toggle.btn-default~.dropdown-menu>li>a:hover{background-color:#d3d3d3}.btn-group .dropdown-toggle.btn-primary~.dropdown-menu{background-color:#008cba;border-color:#0079a1}.btn-group .dropdown-toggle.btn-primary~.dropdown-menu>li>a{color:#ffffff}.btn-group .dropdown-toggle.btn-primary~.dropdown-menu>li>a:hover{background-color:#006d91}.btn-group .dropdown-toggle.btn-success~.dropdown-menu{background-color:#43ac6a;border-color:#3c9a5f}.btn-group .dropdown-toggle.btn-success~.dropdown-menu>li>a{color:#ffffff}.btn-group .dropdown-toggle.btn-success~.dropdown-menu>li>a:hover{background-color:#388f58}.btn-group .dropdown-toggle.btn-info~.dropdown-menu{background-color:#5bc0de;border-color:#46b8da}.btn-group .dropdown-toggle.btn-info~.dropdown-menu>li>a{color:#ffffff}.btn-group .dropdown-toggle.btn-info~.dropdown-menu>li>a:hover{background-color:#39b3d7}.btn-group .dropdown-toggle.btn-warning~.dropdown-menu{background-color:#e99002;border-color:#d08002}.btn-group .dropdown-toggle.btn-warning~.dropdown-menu>li>a{color:#ffffff}.btn-group .dropdown-toggle.btn-warning~.dropdown-menu>li>a:hover{background-color:#c17702}.btn-group .dropdown-toggle.btn-danger~.dropdown-menu{background-color:#f04124;border-color:#ea2f10}.btn-group .dropdown-toggle.btn-danger~.dropdown-menu>li>a{color:#ffffff}.btn-group .dropdown-toggle.btn-danger~.dropdown-menu>li>a:hover{background-color:#dc2c0f}.lead{color:#6f6f6f}cite{font-style:italic}blockquote{border-left-width:1px;color:#6f6f6f}blockquote.pull-right{border-right-width:1px}blockquote small{font-size:12px;font-weight:300}table{font-size:12px}label,.control-label,.help-block,.checkbox,.radio{font-size:12px;font-weight:normal}input[type="radio"],input[type="checkbox"]{margin-top:1px}.nav .open>a,.nav .open>a:hover,.nav .open>a:focus{border-color:transparent}.nav-tabs>li>a{background-color:#e7e7e7;color:#222222}.nav-tabs .caret{border-top-color:#222222;border-bottom-color:#222222}.nav-pills{font-weight:300}.breadcrumb{border:1px solid #dddddd;border-radius:3px;font-size:10px;font-weight:300;text-transform:uppercase}.pagination{font-size:12px;font-weight:300;color:#999999}.pagination>li>a,.pagination>li>span{margin-left:4px;color:#999999}.pagination>.active>a,.pagination>.active>span{color:#fff}.pagination>li>a,.pagination>li:first-child>a,.pagination>li:last-child>a,.pagination>li>span,.pagination>li:first-child>span,.pagination>li:last-child>span{border-radius:3px}.pagination-lg>li>a,.pagination-lg>li>span{padding-left:22px;padding-right:22px}.pagination-sm>li>a,.pagination-sm>li>span{padding:0 5px}.pager{font-size:12px;font-weight:300;color:#999999}.list-group{font-size:12px;font-weight:300}.close{opacity:0.4;text-decoration:none;text-shadow:none}.close:hover,.close:focus{opacity:1}.alert{font-size:12px;font-weight:300}.alert .alert-link{font-weight:normal;color:#fff;text-decoration:underline}.label{padding-left:1em;padding-right:1em;border-radius:0;font-weight:300}.label-default{background-color:#e7e7e7;color:#333333}.badge{font-weight:300}.progress{height:22px;padding:2px;background-color:#f6f6f6;border:1px solid #ccc;-webkit-box-shadow:none;box-shadow:none}.dropdown-menu{padding:0;margin-top:0;font-size:12px}.dropdown-menu>li>a{padding:12px 15px}.dropdown-header{padding-left:15px;padding-right:15px;font-size:9px;text-transform:uppercase}.popover{color:#fff;font-size:12px;font-weight:300}.panel-heading,.panel-footer{border-top-right-radius:0;border-top-left-radius:0}.panel-default .close{color:#222222}.modal .close{color:#222222}
diff --git a/modules/http/static/bootstrap.min.css.spdx b/modules/http/static/bootstrap.min.css.spdx
new file mode 100644
index 0000000..53aef61
--- /dev/null
+++ b/modules/http/static/bootstrap.min.css.spdx
@@ -0,0 +1,11 @@
+SPDXVersion: SPDX-2.1
+DataLicense: CC0-1.0
+SPDXID: SPDXRef-DOCUMENT
+DocumentName: bootswatch-yeti-bootstrap.min.css
+DocumentNamespace: http://spdx.org/spdxdocs/spdx-v2.1-da039738-1b9b-430a-984b-a97d1415ad0f
+
+PackageName: bootswatch-yeti-bootstrap.min.css
+PackageVersion: 3.3.6+2
+PackageDownloadLocation: git+https://github.com/twbs/bootstrap.git@a78dc3aed640a35914361b837ce24573a0515e19#yeti/bootstrap.min.css
+PackageOriginator: Person: Thomas Park (thomas@thomaspark.co)
+PackageLicenseDeclared: MIT
diff --git a/modules/http/static/bootstrap.min.js b/modules/http/static/bootstrap.min.js
new file mode 100644
index 0000000..07eaed1
--- /dev/null
+++ b/modules/http/static/bootstrap.min.js
@@ -0,0 +1,7 @@
+/*!
+ * Bootstrap v3.3.6 (http://getbootstrap.com)
+ * Copyright 2011-2015 Twitter, Inc.
+ * SPDX-License-Identifier: MIT
+ */
+if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");+function(a){"use strict";var b=a.fn.jquery.split(" ")[0].split(".");if(b[0]<2&&b[1]<9||1==b[0]&&9==b[1]&&b[2]<1||b[0]>2)throw new Error("Bootstrap's JavaScript requires jQuery version 1.9.1 or higher, but lower than version 3")}(jQuery),+function(a){"use strict";function b(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]};return!1}a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one("bsTransitionEnd",function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b(),a.support.transition&&(a.event.special.bsTransitionEnd={bindType:a.support.transition.end,delegateType:a.support.transition.end,handle:function(b){return a(b.target).is(this)?b.handleObj.handler.apply(this,arguments):void 0}})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var c=a(this),e=c.data("bs.alert");e||c.data("bs.alert",e=new d(this)),"string"==typeof b&&e[b].call(c)})}var c='[data-dismiss="alert"]',d=function(b){a(b).on("click",c,this.close)};d.VERSION="3.3.6",d.TRANSITION_DURATION=150,d.prototype.close=function(b){function c(){g.detach().trigger("closed.bs.alert").remove()}var e=a(this),f=e.attr("data-target");f||(f=e.attr("href"),f=f&&f.replace(/.*(?=#[^\s]*$)/,""));var g=a(f);b&&b.preventDefault(),g.length||(g=e.closest(".alert")),g.trigger(b=a.Event("close.bs.alert")),b.isDefaultPrevented()||(g.removeClass("in"),a.support.transition&&g.hasClass("fade")?g.one("bsTransitionEnd",c).emulateTransitionEnd(d.TRANSITION_DURATION):c())};var e=a.fn.alert;a.fn.alert=b,a.fn.alert.Constructor=d,a.fn.alert.noConflict=function(){return a.fn.alert=e,this},a(document).on("click.bs.alert.data-api",c,d.prototype.close)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.button"),f="object"==typeof b&&b;e||d.data("bs.button",e=new c(this,f)),"toggle"==b?e.toggle():b&&e.setState(b)})}var c=function(b,d){this.$element=a(b),this.options=a.extend({},c.DEFAULTS,d),this.isLoading=!1};c.VERSION="3.3.6",c.DEFAULTS={loadingText:"loading..."},c.prototype.setState=function(b){var c="disabled",d=this.$element,e=d.is("input")?"val":"html",f=d.data();b+="Text",null==f.resetText&&d.data("resetText",d[e]()),setTimeout(a.proxy(function(){d[e](null==f[b]?this.options[b]:f[b]),"loadingText"==b?(this.isLoading=!0,d.addClass(c).attr(c,c)):this.isLoading&&(this.isLoading=!1,d.removeClass(c).removeAttr(c))},this),0)},c.prototype.toggle=function(){var a=!0,b=this.$element.closest('[data-toggle="buttons"]');if(b.length){var c=this.$element.find("input");"radio"==c.prop("type")?(c.prop("checked")&&(a=!1),b.find(".active").removeClass("active"),this.$element.addClass("active")):"checkbox"==c.prop("type")&&(c.prop("checked")!==this.$element.hasClass("active")&&(a=!1),this.$element.toggleClass("active")),c.prop("checked",this.$element.hasClass("active")),a&&c.trigger("change")}else this.$element.attr("aria-pressed",!this.$element.hasClass("active")),this.$element.toggleClass("active")};var d=a.fn.button;a.fn.button=b,a.fn.button.Constructor=c,a.fn.button.noConflict=function(){return a.fn.button=d,this},a(document).on("click.bs.button.data-api",'[data-toggle^="button"]',function(c){var d=a(c.target);d.hasClass("btn")||(d=d.closest(".btn")),b.call(d,"toggle"),a(c.target).is('input[type="radio"]')||a(c.target).is('input[type="checkbox"]')||c.preventDefault()}).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',function(b){a(b.target).closest(".btn").toggleClass("focus",/^focus(in)?$/.test(b.type))})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.carousel"),f=a.extend({},c.DEFAULTS,d.data(),"object"==typeof b&&b),g="string"==typeof b?b:f.slide;e||d.data("bs.carousel",e=new c(this,f)),"number"==typeof b?e.to(b):g?e[g]():f.interval&&e.pause().cycle()})}var c=function(b,c){this.$element=a(b),this.$indicators=this.$element.find(".carousel-indicators"),this.options=c,this.paused=null,this.sliding=null,this.interval=null,this.$active=null,this.$items=null,this.options.keyboard&&this.$element.on("keydown.bs.carousel",a.proxy(this.keydown,this)),"hover"==this.options.pause&&!("ontouchstart"in document.documentElement)&&this.$element.on("mouseenter.bs.carousel",a.proxy(this.pause,this)).on("mouseleave.bs.carousel",a.proxy(this.cycle,this))};c.VERSION="3.3.6",c.TRANSITION_DURATION=600,c.DEFAULTS={interval:5e3,pause:"hover",wrap:!0,keyboard:!0},c.prototype.keydown=function(a){if(!/input|textarea/i.test(a.target.tagName)){switch(a.which){case 37:this.prev();break;case 39:this.next();break;default:return}a.preventDefault()}},c.prototype.cycle=function(b){return b||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(a.proxy(this.next,this),this.options.interval)),this},c.prototype.getItemIndex=function(a){return this.$items=a.parent().children(".item"),this.$items.index(a||this.$active)},c.prototype.getItemForDirection=function(a,b){var c=this.getItemIndex(b),d="prev"==a&&0===c||"next"==a&&c==this.$items.length-1;if(d&&!this.options.wrap)return b;var e="prev"==a?-1:1,f=(c+e)%this.$items.length;return this.$items.eq(f)},c.prototype.to=function(a){var b=this,c=this.getItemIndex(this.$active=this.$element.find(".item.active"));return a>this.$items.length-1||0>a?void 0:this.sliding?this.$element.one("slid.bs.carousel",function(){b.to(a)}):c==a?this.pause().cycle():this.slide(a>c?"next":"prev",this.$items.eq(a))},c.prototype.pause=function(b){return b||(this.paused=!0),this.$element.find(".next, .prev").length&&a.support.transition&&(this.$element.trigger(a.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},c.prototype.next=function(){return this.sliding?void 0:this.slide("next")},c.prototype.prev=function(){return this.sliding?void 0:this.slide("prev")},c.prototype.slide=function(b,d){var e=this.$element.find(".item.active"),f=d||this.getItemForDirection(b,e),g=this.interval,h="next"==b?"left":"right",i=this;if(f.hasClass("active"))return this.sliding=!1;var j=f[0],k=a.Event("slide.bs.carousel",{relatedTarget:j,direction:h});if(this.$element.trigger(k),!k.isDefaultPrevented()){if(this.sliding=!0,g&&this.pause(),this.$indicators.length){this.$indicators.find(".active").removeClass("active");var l=a(this.$indicators.children()[this.getItemIndex(f)]);l&&l.addClass("active")}var m=a.Event("slid.bs.carousel",{relatedTarget:j,direction:h});return a.support.transition&&this.$element.hasClass("slide")?(f.addClass(b),f[0].offsetWidth,e.addClass(h),f.addClass(h),e.one("bsTransitionEnd",function(){f.removeClass([b,h].join(" ")).addClass("active"),e.removeClass(["active",h].join(" ")),i.sliding=!1,setTimeout(function(){i.$element.trigger(m)},0)}).emulateTransitionEnd(c.TRANSITION_DURATION)):(e.removeClass("active"),f.addClass("active"),this.sliding=!1,this.$element.trigger(m)),g&&this.cycle(),this}};var d=a.fn.carousel;a.fn.carousel=b,a.fn.carousel.Constructor=c,a.fn.carousel.noConflict=function(){return a.fn.carousel=d,this};var e=function(c){var d,e=a(this),f=a(e.attr("data-target")||(d=e.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,""));if(f.hasClass("carousel")){var g=a.extend({},f.data(),e.data()),h=e.attr("data-slide-to");h&&(g.interval=!1),b.call(f,g),h&&f.data("bs.carousel").to(h),c.preventDefault()}};a(document).on("click.bs.carousel.data-api","[data-slide]",e).on("click.bs.carousel.data-api","[data-slide-to]",e),a(window).on("load",function(){a('[data-ride="carousel"]').each(function(){var c=a(this);b.call(c,c.data())})})}(jQuery),+function(a){"use strict";function b(b){var c,d=b.attr("data-target")||(c=b.attr("href"))&&c.replace(/.*(?=#[^\s]+$)/,"");return a(d)}function c(b){return this.each(function(){var c=a(this),e=c.data("bs.collapse"),f=a.extend({},d.DEFAULTS,c.data(),"object"==typeof b&&b);!e&&f.toggle&&/show|hide/.test(b)&&(f.toggle=!1),e||c.data("bs.collapse",e=new d(this,f)),"string"==typeof b&&e[b]()})}var d=function(b,c){this.$element=a(b),this.options=a.extend({},d.DEFAULTS,c),this.$trigger=a('[data-toggle="collapse"][href="#'+b.id+'"],[data-toggle="collapse"][data-target="#'+b.id+'"]'),this.transitioning=null,this.options.parent?this.$parent=this.getParent():this.addAriaAndCollapsedClass(this.$element,this.$trigger),this.options.toggle&&this.toggle()};d.VERSION="3.3.6",d.TRANSITION_DURATION=350,d.DEFAULTS={toggle:!0},d.prototype.dimension=function(){var a=this.$element.hasClass("width");return a?"width":"height"},d.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass("in")){var b,e=this.$parent&&this.$parent.children(".panel").children(".in, .collapsing");if(!(e&&e.length&&(b=e.data("bs.collapse"),b&&b.transitioning))){var f=a.Event("show.bs.collapse");if(this.$element.trigger(f),!f.isDefaultPrevented()){e&&e.length&&(c.call(e,"hide"),b||e.data("bs.collapse",null));var g=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[g](0).attr("aria-expanded",!0),this.$trigger.removeClass("collapsed").attr("aria-expanded",!0),this.transitioning=1;var h=function(){this.$element.removeClass("collapsing").addClass("collapse in")[g](""),this.transitioning=0,this.$element.trigger("shown.bs.collapse")};if(!a.support.transition)return h.call(this);var i=a.camelCase(["scroll",g].join("-"));this.$element.one("bsTransitionEnd",a.proxy(h,this)).emulateTransitionEnd(d.TRANSITION_DURATION)[g](this.$element[0][i])}}}},d.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass("in")){var b=a.Event("hide.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.dimension();this.$element[c](this.$element[c]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse in").attr("aria-expanded",!1),this.$trigger.addClass("collapsed").attr("aria-expanded",!1),this.transitioning=1;var e=function(){this.transitioning=0,this.$element.removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse")};return a.support.transition?void this.$element[c](0).one("bsTransitionEnd",a.proxy(e,this)).emulateTransitionEnd(d.TRANSITION_DURATION):e.call(this)}}},d.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()},d.prototype.getParent=function(){return a(this.options.parent).find('[data-toggle="collapse"][data-parent="'+this.options.parent+'"]').each(a.proxy(function(c,d){var e=a(d);this.addAriaAndCollapsedClass(b(e),e)},this)).end()},d.prototype.addAriaAndCollapsedClass=function(a,b){var c=a.hasClass("in");a.attr("aria-expanded",c),b.toggleClass("collapsed",!c).attr("aria-expanded",c)};var e=a.fn.collapse;a.fn.collapse=c,a.fn.collapse.Constructor=d,a.fn.collapse.noConflict=function(){return a.fn.collapse=e,this},a(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',function(d){var e=a(this);e.attr("data-target")||d.preventDefault();var f=b(e),g=f.data("bs.collapse"),h=g?"toggle":e.data();c.call(f,h)})}(jQuery),+function(a){"use strict";function b(b){var c=b.attr("data-target");c||(c=b.attr("href"),c=c&&/#[A-Za-z]/.test(c)&&c.replace(/.*(?=#[^\s]*$)/,""));var d=c&&a(c);return d&&d.length?d:b.parent()}function c(c){c&&3===c.which||(a(e).remove(),a(f).each(function(){var d=a(this),e=b(d),f={relatedTarget:this};e.hasClass("open")&&(c&&"click"==c.type&&/input|textarea/i.test(c.target.tagName)&&a.contains(e[0],c.target)||(e.trigger(c=a.Event("hide.bs.dropdown",f)),c.isDefaultPrevented()||(d.attr("aria-expanded","false"),e.removeClass("open").trigger(a.Event("hidden.bs.dropdown",f)))))}))}function d(b){return this.each(function(){var c=a(this),d=c.data("bs.dropdown");d||c.data("bs.dropdown",d=new g(this)),"string"==typeof b&&d[b].call(c)})}var e=".dropdown-backdrop",f='[data-toggle="dropdown"]',g=function(b){a(b).on("click.bs.dropdown",this.toggle)};g.VERSION="3.3.6",g.prototype.toggle=function(d){var e=a(this);if(!e.is(".disabled, :disabled")){var f=b(e),g=f.hasClass("open");if(c(),!g){"ontouchstart"in document.documentElement&&!f.closest(".navbar-nav").length&&a(document.createElement("div")).addClass("dropdown-backdrop").insertAfter(a(this)).on("click",c);var h={relatedTarget:this};if(f.trigger(d=a.Event("show.bs.dropdown",h)),d.isDefaultPrevented())return;e.trigger("focus").attr("aria-expanded","true"),f.toggleClass("open").trigger(a.Event("shown.bs.dropdown",h))}return!1}},g.prototype.keydown=function(c){if(/(38|40|27|32)/.test(c.which)&&!/input|textarea/i.test(c.target.tagName)){var d=a(this);if(c.preventDefault(),c.stopPropagation(),!d.is(".disabled, :disabled")){var e=b(d),g=e.hasClass("open");if(!g&&27!=c.which||g&&27==c.which)return 27==c.which&&e.find(f).trigger("focus"),d.trigger("click");var h=" li:not(.disabled):visible a",i=e.find(".dropdown-menu"+h);if(i.length){var j=i.index(c.target);38==c.which&&j>0&&j--,40==c.which&&j<i.length-1&&j++,~j||(j=0),i.eq(j).trigger("focus")}}}};var h=a.fn.dropdown;a.fn.dropdown=d,a.fn.dropdown.Constructor=g,a.fn.dropdown.noConflict=function(){return a.fn.dropdown=h,this},a(document).on("click.bs.dropdown.data-api",c).on("click.bs.dropdown.data-api",".dropdown form",function(a){a.stopPropagation()}).on("click.bs.dropdown.data-api",f,g.prototype.toggle).on("keydown.bs.dropdown.data-api",f,g.prototype.keydown).on("keydown.bs.dropdown.data-api",".dropdown-menu",g.prototype.keydown)}(jQuery),+function(a){"use strict";function b(b,d){return this.each(function(){var e=a(this),f=e.data("bs.modal"),g=a.extend({},c.DEFAULTS,e.data(),"object"==typeof b&&b);f||e.data("bs.modal",f=new c(this,g)),"string"==typeof b?f[b](d):g.show&&f.show(d)})}var c=function(b,c){this.options=c,this.$body=a(document.body),this.$element=a(b),this.$dialog=this.$element.find(".modal-dialog"),this.$backdrop=null,this.isShown=null,this.originalBodyPad=null,this.scrollbarWidth=0,this.ignoreBackdropClick=!1,this.options.remote&&this.$element.find(".modal-content").load(this.options.remote,a.proxy(function(){this.$element.trigger("loaded.bs.modal")},this))};c.VERSION="3.3.6",c.TRANSITION_DURATION=300,c.BACKDROP_TRANSITION_DURATION=150,c.DEFAULTS={backdrop:!0,keyboard:!0,show:!0},c.prototype.toggle=function(a){return this.isShown?this.hide():this.show(a)},c.prototype.show=function(b){var d=this,e=a.Event("show.bs.modal",{relatedTarget:b});this.$element.trigger(e),this.isShown||e.isDefaultPrevented()||(this.isShown=!0,this.checkScrollbar(),this.setScrollbar(),this.$body.addClass("modal-open"),this.escape(),this.resize(),this.$element.on("click.dismiss.bs.modal",'[data-dismiss="modal"]',a.proxy(this.hide,this)),this.$dialog.on("mousedown.dismiss.bs.modal",function(){d.$element.one("mouseup.dismiss.bs.modal",function(b){a(b.target).is(d.$element)&&(d.ignoreBackdropClick=!0)})}),this.backdrop(function(){var e=a.support.transition&&d.$element.hasClass("fade");d.$element.parent().length||d.$element.appendTo(d.$body),d.$element.show().scrollTop(0),d.adjustDialog(),e&&d.$element[0].offsetWidth,d.$element.addClass("in"),d.enforceFocus();var f=a.Event("shown.bs.modal",{relatedTarget:b});e?d.$dialog.one("bsTransitionEnd",function(){d.$element.trigger("focus").trigger(f)}).emulateTransitionEnd(c.TRANSITION_DURATION):d.$element.trigger("focus").trigger(f)}))},c.prototype.hide=function(b){b&&b.preventDefault(),b=a.Event("hide.bs.modal"),this.$element.trigger(b),this.isShown&&!b.isDefaultPrevented()&&(this.isShown=!1,this.escape(),this.resize(),a(document).off("focusin.bs.modal"),this.$element.removeClass("in").off("click.dismiss.bs.modal").off("mouseup.dismiss.bs.modal"),this.$dialog.off("mousedown.dismiss.bs.modal"),a.support.transition&&this.$element.hasClass("fade")?this.$element.one("bsTransitionEnd",a.proxy(this.hideModal,this)).emulateTransitionEnd(c.TRANSITION_DURATION):this.hideModal())},c.prototype.enforceFocus=function(){a(document).off("focusin.bs.modal").on("focusin.bs.modal",a.proxy(function(a){this.$element[0]===a.target||this.$element.has(a.target).length||this.$element.trigger("focus")},this))},c.prototype.escape=function(){this.isShown&&this.options.keyboard?this.$element.on("keydown.dismiss.bs.modal",a.proxy(function(a){27==a.which&&this.hide()},this)):this.isShown||this.$element.off("keydown.dismiss.bs.modal")},c.prototype.resize=function(){this.isShown?a(window).on("resize.bs.modal",a.proxy(this.handleUpdate,this)):a(window).off("resize.bs.modal")},c.prototype.hideModal=function(){var a=this;this.$element.hide(),this.backdrop(function(){a.$body.removeClass("modal-open"),a.resetAdjustments(),a.resetScrollbar(),a.$element.trigger("hidden.bs.modal")})},c.prototype.removeBackdrop=function(){this.$backdrop&&this.$backdrop.remove(),this.$backdrop=null},c.prototype.backdrop=function(b){var d=this,e=this.$element.hasClass("fade")?"fade":"";if(this.isShown&&this.options.backdrop){var f=a.support.transition&&e;if(this.$backdrop=a(document.createElement("div")).addClass("modal-backdrop "+e).appendTo(this.$body),this.$element.on("click.dismiss.bs.modal",a.proxy(function(a){return this.ignoreBackdropClick?void(this.ignoreBackdropClick=!1):void(a.target===a.currentTarget&&("static"==this.options.backdrop?this.$element[0].focus():this.hide()))},this)),f&&this.$backdrop[0].offsetWidth,this.$backdrop.addClass("in"),!b)return;f?this.$backdrop.one("bsTransitionEnd",b).emulateTransitionEnd(c.BACKDROP_TRANSITION_DURATION):b()}else if(!this.isShown&&this.$backdrop){this.$backdrop.removeClass("in");var g=function(){d.removeBackdrop(),b&&b()};a.support.transition&&this.$element.hasClass("fade")?this.$backdrop.one("bsTransitionEnd",g).emulateTransitionEnd(c.BACKDROP_TRANSITION_DURATION):g()}else b&&b()},c.prototype.handleUpdate=function(){this.adjustDialog()},c.prototype.adjustDialog=function(){var a=this.$element[0].scrollHeight>document.documentElement.clientHeight;this.$element.css({paddingLeft:!this.bodyIsOverflowing&&a?this.scrollbarWidth:"",paddingRight:this.bodyIsOverflowing&&!a?this.scrollbarWidth:""})},c.prototype.resetAdjustments=function(){this.$element.css({paddingLeft:"",paddingRight:""})},c.prototype.checkScrollbar=function(){var a=window.innerWidth;if(!a){var b=document.documentElement.getBoundingClientRect();a=b.right-Math.abs(b.left)}this.bodyIsOverflowing=document.body.clientWidth<a,this.scrollbarWidth=this.measureScrollbar()},c.prototype.setScrollbar=function(){var a=parseInt(this.$body.css("padding-right")||0,10);this.originalBodyPad=document.body.style.paddingRight||"",this.bodyIsOverflowing&&this.$body.css("padding-right",a+this.scrollbarWidth)},c.prototype.resetScrollbar=function(){this.$body.css("padding-right",this.originalBodyPad)},c.prototype.measureScrollbar=function(){var a=document.createElement("div");a.className="modal-scrollbar-measure",this.$body.append(a);var b=a.offsetWidth-a.clientWidth;return this.$body[0].removeChild(a),b};var d=a.fn.modal;a.fn.modal=b,a.fn.modal.Constructor=c,a.fn.modal.noConflict=function(){return a.fn.modal=d,this},a(document).on("click.bs.modal.data-api",'[data-toggle="modal"]',function(c){var d=a(this),e=d.attr("href"),f=a(d.attr("data-target")||e&&e.replace(/.*(?=#[^\s]+$)/,"")),g=f.data("bs.modal")?"toggle":a.extend({remote:!/#/.test(e)&&e},f.data(),d.data());d.is("a")&&c.preventDefault(),f.one("show.bs.modal",function(a){a.isDefaultPrevented()||f.one("hidden.bs.modal",function(){d.is(":visible")&&d.trigger("focus")})}),b.call(f,g,this)})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.tooltip"),f="object"==typeof b&&b;(e||!/destroy|hide/.test(b))&&(e||d.data("bs.tooltip",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.type=null,this.options=null,this.enabled=null,this.timeout=null,this.hoverState=null,this.$element=null,this.inState=null,this.init("tooltip",a,b)};c.VERSION="3.3.6",c.TRANSITION_DURATION=150,c.DEFAULTS={animation:!0,placement:"top",selector:!1,template:'<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',trigger:"hover focus",title:"",delay:0,html:!1,container:!1,viewport:{selector:"body",padding:0}},c.prototype.init=function(b,c,d){if(this.enabled=!0,this.type=b,this.$element=a(c),this.options=this.getOptions(d),this.$viewport=this.options.viewport&&a(a.isFunction(this.options.viewport)?this.options.viewport.call(this,this.$element):this.options.viewport.selector||this.options.viewport),this.inState={click:!1,hover:!1,focus:!1},this.$element[0]instanceof document.constructor&&!this.options.selector)throw new Error("`selector` option must be specified when initializing "+this.type+" on the window.document object!");for(var e=this.options.trigger.split(" "),f=e.length;f--;){var g=e[f];if("click"==g)this.$element.on("click."+this.type,this.options.selector,a.proxy(this.toggle,this));else if("manual"!=g){var h="hover"==g?"mouseenter":"focusin",i="hover"==g?"mouseleave":"focusout";this.$element.on(h+"."+this.type,this.options.selector,a.proxy(this.enter,this)),this.$element.on(i+"."+this.type,this.options.selector,a.proxy(this.leave,this))}}this.options.selector?this._options=a.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.getOptions=function(b){return b=a.extend({},this.getDefaults(),this.$element.data(),b),b.delay&&"number"==typeof b.delay&&(b.delay={show:b.delay,hide:b.delay}),b},c.prototype.getDelegateOptions=function(){var b={},c=this.getDefaults();return this._options&&a.each(this._options,function(a,d){c[a]!=d&&(b[a]=d)}),b},c.prototype.enter=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusin"==b.type?"focus":"hover"]=!0),c.tip().hasClass("in")||"in"==c.hoverState?void(c.hoverState="in"):(clearTimeout(c.timeout),c.hoverState="in",c.options.delay&&c.options.delay.show?void(c.timeout=setTimeout(function(){"in"==c.hoverState&&c.show()},c.options.delay.show)):c.show())},c.prototype.isInStateTrue=function(){for(var a in this.inState)if(this.inState[a])return!0;return!1},c.prototype.leave=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusout"==b.type?"focus":"hover"]=!1),c.isInStateTrue()?void 0:(clearTimeout(c.timeout),c.hoverState="out",c.options.delay&&c.options.delay.hide?void(c.timeout=setTimeout(function(){"out"==c.hoverState&&c.hide()},c.options.delay.hide)):c.hide())},c.prototype.show=function(){var b=a.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){this.$element.trigger(b);var d=a.contains(this.$element[0].ownerDocument.documentElement,this.$element[0]);if(b.isDefaultPrevented()||!d)return;var e=this,f=this.tip(),g=this.getUID(this.type);this.setContent(),f.attr("id",g),this.$element.attr("aria-describedby",g),this.options.animation&&f.addClass("fade");var h="function"==typeof this.options.placement?this.options.placement.call(this,f[0],this.$element[0]):this.options.placement,i=/\s?auto?\s?/i,j=i.test(h);j&&(h=h.replace(i,"")||"top"),f.detach().css({top:0,left:0,display:"block"}).addClass(h).data("bs."+this.type,this),this.options.container?f.appendTo(this.options.container):f.insertAfter(this.$element),this.$element.trigger("inserted.bs."+this.type);var k=this.getPosition(),l=f[0].offsetWidth,m=f[0].offsetHeight;if(j){var n=h,o=this.getPosition(this.$viewport);h="bottom"==h&&k.bottom+m>o.bottom?"top":"top"==h&&k.top-m<o.top?"bottom":"right"==h&&k.right+l>o.width?"left":"left"==h&&k.left-l<o.left?"right":h,f.removeClass(n).addClass(h)}var p=this.getCalculatedOffset(h,k,l,m);this.applyPlacement(p,h);var q=function(){var a=e.hoverState;e.$element.trigger("shown.bs."+e.type),e.hoverState=null,"out"==a&&e.leave(e)};a.support.transition&&this.$tip.hasClass("fade")?f.one("bsTransitionEnd",q).emulateTransitionEnd(c.TRANSITION_DURATION):q()}},c.prototype.applyPlacement=function(b,c){var d=this.tip(),e=d[0].offsetWidth,f=d[0].offsetHeight,g=parseInt(d.css("margin-top"),10),h=parseInt(d.css("margin-left"),10);isNaN(g)&&(g=0),isNaN(h)&&(h=0),b.top+=g,b.left+=h,a.offset.setOffset(d[0],a.extend({using:function(a){d.css({top:Math.round(a.top),left:Math.round(a.left)})}},b),0),d.addClass("in");var i=d[0].offsetWidth,j=d[0].offsetHeight;"top"==c&&j!=f&&(b.top=b.top+f-j);var k=this.getViewportAdjustedDelta(c,b,i,j);k.left?b.left+=k.left:b.top+=k.top;var l=/top|bottom/.test(c),m=l?2*k.left-e+i:2*k.top-f+j,n=l?"offsetWidth":"offsetHeight";d.offset(b),this.replaceArrow(m,d[0][n],l)},c.prototype.replaceArrow=function(a,b,c){this.arrow().css(c?"left":"top",50*(1-a/b)+"%").css(c?"top":"left","")},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle();a.find(".tooltip-inner")[this.options.html?"html":"text"](b),a.removeClass("fade in top bottom left right")},c.prototype.hide=function(b){function d(){"in"!=e.hoverState&&f.detach(),e.$element.removeAttr("aria-describedby").trigger("hidden.bs."+e.type),b&&b()}var e=this,f=a(this.$tip),g=a.Event("hide.bs."+this.type);return this.$element.trigger(g),g.isDefaultPrevented()?void 0:(f.removeClass("in"),a.support.transition&&f.hasClass("fade")?f.one("bsTransitionEnd",d).emulateTransitionEnd(c.TRANSITION_DURATION):d(),this.hoverState=null,this)},c.prototype.fixTitle=function(){var a=this.$element;(a.attr("title")||"string"!=typeof a.attr("data-original-title"))&&a.attr("data-original-title",a.attr("title")||"").attr("title","")},c.prototype.hasContent=function(){return this.getTitle()},c.prototype.getPosition=function(b){b=b||this.$element;var c=b[0],d="BODY"==c.tagName,e=c.getBoundingClientRect();null==e.width&&(e=a.extend({},e,{width:e.right-e.left,height:e.bottom-e.top}));var f=d?{top:0,left:0}:b.offset(),g={scroll:d?document.documentElement.scrollTop||document.body.scrollTop:b.scrollTop()},h=d?{width:a(window).width(),height:a(window).height()}:null;return a.extend({},e,g,h,f)},c.prototype.getCalculatedOffset=function(a,b,c,d){return"bottom"==a?{top:b.top+b.height,left:b.left+b.width/2-c/2}:"top"==a?{top:b.top-d,left:b.left+b.width/2-c/2}:"left"==a?{top:b.top+b.height/2-d/2,left:b.left-c}:{top:b.top+b.height/2-d/2,left:b.left+b.width}},c.prototype.getViewportAdjustedDelta=function(a,b,c,d){var e={top:0,left:0};if(!this.$viewport)return e;var f=this.options.viewport&&this.options.viewport.padding||0,g=this.getPosition(this.$viewport);if(/right|left/.test(a)){var h=b.top-f-g.scroll,i=b.top+f-g.scroll+d;h<g.top?e.top=g.top-h:i>g.top+g.height&&(e.top=g.top+g.height-i)}else{var j=b.left-f,k=b.left+f+c;j<g.left?e.left=g.left-j:k>g.right&&(e.left=g.left+g.width-k)}return e},c.prototype.getTitle=function(){var a,b=this.$element,c=this.options;return a=b.attr("data-original-title")||("function"==typeof c.title?c.title.call(b[0]):c.title)},c.prototype.getUID=function(a){do a+=~~(1e6*Math.random());while(document.getElementById(a));return a},c.prototype.tip=function(){if(!this.$tip&&(this.$tip=a(this.options.template),1!=this.$tip.length))throw new Error(this.type+" `template` option must consist of exactly 1 top-level element!");return this.$tip},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")},c.prototype.enable=function(){this.enabled=!0},c.prototype.disable=function(){this.enabled=!1},c.prototype.toggleEnabled=function(){this.enabled=!this.enabled},c.prototype.toggle=function(b){var c=this;b&&(c=a(b.currentTarget).data("bs."+this.type),c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c))),b?(c.inState.click=!c.inState.click,c.isInStateTrue()?c.enter(c):c.leave(c)):c.tip().hasClass("in")?c.leave(c):c.enter(c)},c.prototype.destroy=function(){var a=this;clearTimeout(this.timeout),this.hide(function(){a.$element.off("."+a.type).removeData("bs."+a.type),a.$tip&&a.$tip.detach(),a.$tip=null,a.$arrow=null,a.$viewport=null})};var d=a.fn.tooltip;a.fn.tooltip=b,a.fn.tooltip.Constructor=c,a.fn.tooltip.noConflict=function(){return a.fn.tooltip=d,this}}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.popover"),f="object"==typeof b&&b;(e||!/destroy|hide/.test(b))&&(e||d.data("bs.popover",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.init("popover",a,b)};if(!a.fn.tooltip)throw new Error("Popover requires tooltip.js");c.VERSION="3.3.6",c.DEFAULTS=a.extend({},a.fn.tooltip.Constructor.DEFAULTS,{placement:"right",trigger:"click",content:"",template:'<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'}),c.prototype=a.extend({},a.fn.tooltip.Constructor.prototype),c.prototype.constructor=c,c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle(),c=this.getContent();a.find(".popover-title")[this.options.html?"html":"text"](b),a.find(".popover-content").children().detach().end()[this.options.html?"string"==typeof c?"html":"append":"text"](c),a.removeClass("fade top bottom left right in"),a.find(".popover-title").html()||a.find(".popover-title").hide()},c.prototype.hasContent=function(){return this.getTitle()||this.getContent()},c.prototype.getContent=function(){var a=this.$element,b=this.options;return a.attr("data-content")||("function"==typeof b.content?b.content.call(a[0]):b.content)},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".arrow")};var d=a.fn.popover;a.fn.popover=b,a.fn.popover.Constructor=c,a.fn.popover.noConflict=function(){return a.fn.popover=d,this}}(jQuery),+function(a){"use strict";function b(c,d){this.$body=a(document.body),this.$scrollElement=a(a(c).is(document.body)?window:c),this.options=a.extend({},b.DEFAULTS,d),this.selector=(this.options.target||"")+" .nav li > a",this.offsets=[],this.targets=[],this.activeTarget=null,this.scrollHeight=0,this.$scrollElement.on("scroll.bs.scrollspy",a.proxy(this.process,this)),this.refresh(),this.process()}function c(c){return this.each(function(){var d=a(this),e=d.data("bs.scrollspy"),f="object"==typeof c&&c;e||d.data("bs.scrollspy",e=new b(this,f)),"string"==typeof c&&e[c]()})}b.VERSION="3.3.6",b.DEFAULTS={offset:10},b.prototype.getScrollHeight=function(){return this.$scrollElement[0].scrollHeight||Math.max(this.$body[0].scrollHeight,document.documentElement.scrollHeight)},b.prototype.refresh=function(){var b=this,c="offset",d=0;this.offsets=[],this.targets=[],this.scrollHeight=this.getScrollHeight(),a.isWindow(this.$scrollElement[0])||(c="position",d=this.$scrollElement.scrollTop()),this.$body.find(this.selector).map(function(){var b=a(this),e=b.data("target")||b.attr("href"),f=/^#./.test(e)&&a(e);return f&&f.length&&f.is(":visible")&&[[f[c]().top+d,e]]||null}).sort(function(a,b){return a[0]-b[0]}).each(function(){b.offsets.push(this[0]),b.targets.push(this[1])})},b.prototype.process=function(){var a,b=this.$scrollElement.scrollTop()+this.options.offset,c=this.getScrollHeight(),d=this.options.offset+c-this.$scrollElement.height(),e=this.offsets,f=this.targets,g=this.activeTarget;if(this.scrollHeight!=c&&this.refresh(),b>=d)return g!=(a=f[f.length-1])&&this.activate(a);if(g&&b<e[0])return this.activeTarget=null,this.clear();for(a=e.length;a--;)g!=f[a]&&b>=e[a]&&(void 0===e[a+1]||b<e[a+1])&&this.activate(f[a])},b.prototype.activate=function(b){this.activeTarget=b,this.clear();var c=this.selector+'[data-target="'+b+'"],'+this.selector+'[href="'+b+'"]',d=a(c).parents("li").addClass("active");
+d.parent(".dropdown-menu").length&&(d=d.closest("li.dropdown").addClass("active")),d.trigger("activate.bs.scrollspy")},b.prototype.clear=function(){a(this.selector).parentsUntil(this.options.target,".active").removeClass("active")};var d=a.fn.scrollspy;a.fn.scrollspy=c,a.fn.scrollspy.Constructor=b,a.fn.scrollspy.noConflict=function(){return a.fn.scrollspy=d,this},a(window).on("load.bs.scrollspy.data-api",function(){a('[data-spy="scroll"]').each(function(){var b=a(this);c.call(b,b.data())})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.tab");e||d.data("bs.tab",e=new c(this)),"string"==typeof b&&e[b]()})}var c=function(b){this.element=a(b)};c.VERSION="3.3.6",c.TRANSITION_DURATION=150,c.prototype.show=function(){var b=this.element,c=b.closest("ul:not(.dropdown-menu)"),d=b.data("target");if(d||(d=b.attr("href"),d=d&&d.replace(/.*(?=#[^\s]*$)/,"")),!b.parent("li").hasClass("active")){var e=c.find(".active:last a"),f=a.Event("hide.bs.tab",{relatedTarget:b[0]}),g=a.Event("show.bs.tab",{relatedTarget:e[0]});if(e.trigger(f),b.trigger(g),!g.isDefaultPrevented()&&!f.isDefaultPrevented()){var h=a(d);this.activate(b.closest("li"),c),this.activate(h,h.parent(),function(){e.trigger({type:"hidden.bs.tab",relatedTarget:b[0]}),b.trigger({type:"shown.bs.tab",relatedTarget:e[0]})})}}},c.prototype.activate=function(b,d,e){function f(){g.removeClass("active").find("> .dropdown-menu > .active").removeClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!1),b.addClass("active").find('[data-toggle="tab"]').attr("aria-expanded",!0),h?(b[0].offsetWidth,b.addClass("in")):b.removeClass("fade"),b.parent(".dropdown-menu").length&&b.closest("li.dropdown").addClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!0),e&&e()}var g=d.find("> .active"),h=e&&a.support.transition&&(g.length&&g.hasClass("fade")||!!d.find("> .fade").length);g.length&&h?g.one("bsTransitionEnd",f).emulateTransitionEnd(c.TRANSITION_DURATION):f(),g.removeClass("in")};var d=a.fn.tab;a.fn.tab=b,a.fn.tab.Constructor=c,a.fn.tab.noConflict=function(){return a.fn.tab=d,this};var e=function(c){c.preventDefault(),b.call(a(this),"show")};a(document).on("click.bs.tab.data-api",'[data-toggle="tab"]',e).on("click.bs.tab.data-api",'[data-toggle="pill"]',e)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.affix"),f="object"==typeof b&&b;e||d.data("bs.affix",e=new c(this,f)),"string"==typeof b&&e[b]()})}var c=function(b,d){this.options=a.extend({},c.DEFAULTS,d),this.$target=a(this.options.target).on("scroll.bs.affix.data-api",a.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",a.proxy(this.checkPositionWithEventLoop,this)),this.$element=a(b),this.affixed=null,this.unpin=null,this.pinnedOffset=null,this.checkPosition()};c.VERSION="3.3.6",c.RESET="affix affix-top affix-bottom",c.DEFAULTS={offset:0,target:window},c.prototype.getState=function(a,b,c,d){var e=this.$target.scrollTop(),f=this.$element.offset(),g=this.$target.height();if(null!=c&&"top"==this.affixed)return c>e?"top":!1;if("bottom"==this.affixed)return null!=c?e+this.unpin<=f.top?!1:"bottom":a-d>=e+g?!1:"bottom";var h=null==this.affixed,i=h?e:f.top,j=h?g:b;return null!=c&&c>=e?"top":null!=d&&i+j>=a-d?"bottom":!1},c.prototype.getPinnedOffset=function(){if(this.pinnedOffset)return this.pinnedOffset;this.$element.removeClass(c.RESET).addClass("affix");var a=this.$target.scrollTop(),b=this.$element.offset();return this.pinnedOffset=b.top-a},c.prototype.checkPositionWithEventLoop=function(){setTimeout(a.proxy(this.checkPosition,this),1)},c.prototype.checkPosition=function(){if(this.$element.is(":visible")){var b=this.$element.height(),d=this.options.offset,e=d.top,f=d.bottom,g=Math.max(a(document).height(),a(document.body).height());"object"!=typeof d&&(f=e=d),"function"==typeof e&&(e=d.top(this.$element)),"function"==typeof f&&(f=d.bottom(this.$element));var h=this.getState(g,b,e,f);if(this.affixed!=h){null!=this.unpin&&this.$element.css("top","");var i="affix"+(h?"-"+h:""),j=a.Event(i+".bs.affix");if(this.$element.trigger(j),j.isDefaultPrevented())return;this.affixed=h,this.unpin="bottom"==h?this.getPinnedOffset():null,this.$element.removeClass(c.RESET).addClass(i).trigger(i.replace("affix","affixed")+".bs.affix")}"bottom"==h&&this.$element.offset({top:g-b-f})}};var d=a.fn.affix;a.fn.affix=b,a.fn.affix.Constructor=c,a.fn.affix.noConflict=function(){return a.fn.affix=d,this},a(window).on("load",function(){a('[data-spy="affix"]').each(function(){var c=a(this),d=c.data();d.offset=d.offset||{},null!=d.offsetBottom&&(d.offset.bottom=d.offsetBottom),null!=d.offsetTop&&(d.offset.top=d.offsetTop),b.call(c,d)})})}(jQuery);
diff --git a/modules/http/static/bootstrap.min.js.spdx b/modules/http/static/bootstrap.min.js.spdx
new file mode 100644
index 0000000..d0df6eb
--- /dev/null
+++ b/modules/http/static/bootstrap.min.js.spdx
@@ -0,0 +1,11 @@
+SPDXVersion: SPDX-2.1
+DataLicense: CC0-1.0
+SPDXID: SPDXRef-DOCUMENT
+DocumentName: bootstrap.js
+DocumentNamespace: http://spdx.org/spdxdocs/spdx-v2.1-6797c679-d14a-4524-abe4-a668e07f213f
+
+PackageName: bootstrap.js
+PackageVersion: 3.3.6
+PackageDownloadLocation: git+https://github.com/twbs/bootstrap.git@81df608a40bf0629a1dc08e584849bb1e43e0b7a#dist/js/bootstrap.min.js
+PackageOriginator: Organization: Twitter
+PackageLicenseDeclared: MIT
diff --git a/modules/http/static/d3.js b/modules/http/static/d3.js
new file mode 100644
index 0000000..c3a27fd
--- /dev/null
+++ b/modules/http/static/d3.js
@@ -0,0 +1,6 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+!function(){function n(n){return n&&(n.ownerDocument||n.document||n).documentElement}function t(n){return n&&(n.ownerDocument&&n.ownerDocument.defaultView||n.document&&n||n.defaultView)}function e(n,t){return t>n?-1:n>t?1:n>=t?0:0/0}function r(n){return null===n?0/0:+n}function u(n){return!isNaN(n)}function i(n){return{left:function(t,e,r,u){for(arguments.length<3&&(r=0),arguments.length<4&&(u=t.length);u>r;){var i=r+u>>>1;n(t[i],e)<0?r=i+1:u=i}return r},right:function(t,e,r,u){for(arguments.length<3&&(r=0),arguments.length<4&&(u=t.length);u>r;){var i=r+u>>>1;n(t[i],e)>0?u=i:r=i+1}return r}}}function o(n){return n.length}function a(n){for(var t=1;n*t%1;)t*=10;return t}function c(n,t){for(var e in t)Object.defineProperty(n.prototype,e,{value:t[e],enumerable:!1})}function l(){this._=Object.create(null)}function s(n){return(n+="")===pa||n[0]===va?va+n:n}function f(n){return(n+="")[0]===va?n.slice(1):n}function h(n){return s(n)in this._}function g(n){return(n=s(n))in this._&&delete this._[n]}function p(){var n=[];for(var t in this._)n.push(f(t));return n}function v(){var n=0;for(var t in this._)++n;return n}function d(){for(var n in this._)return!1;return!0}function m(){this._=Object.create(null)}function y(n){return n}function M(n,t,e){return function(){var r=e.apply(t,arguments);return r===t?n:r}}function x(n,t){if(t in n)return t;t=t.charAt(0).toUpperCase()+t.slice(1);for(var e=0,r=da.length;r>e;++e){var u=da[e]+t;if(u in n)return u}}function b(){}function _(){}function w(n){function t(){for(var t,r=e,u=-1,i=r.length;++u<i;)(t=r[u].on)&&t.apply(this,arguments);return n}var e=[],r=new l;return t.on=function(t,u){var i,o=r.get(t);return arguments.length<2?o&&o.on:(o&&(o.on=null,e=e.slice(0,i=e.indexOf(o)).concat(e.slice(i+1)),r.remove(t)),u&&e.push(r.set(t,{on:u})),n)},t}function S(){ta.event.preventDefault()}function k(){for(var n,t=ta.event;n=t.sourceEvent;)t=n;return t}function E(n){for(var t=new _,e=0,r=arguments.length;++e<r;)t[arguments[e]]=w(t);return t.of=function(e,r){return function(u){try{var i=u.sourceEvent=ta.event;u.target=n,ta.event=u,t[u.type].apply(e,r)}finally{ta.event=i}}},t}function A(n){return ya(n,_a),n}function N(n){return"function"==typeof n?n:function(){return Ma(n,this)}}function C(n){return"function"==typeof n?n:function(){return xa(n,this)}}function z(n,t){function e(){this.removeAttribute(n)}function r(){this.removeAttributeNS(n.space,n.local)}function u(){this.setAttribute(n,t)}function i(){this.setAttributeNS(n.space,n.local,t)}function o(){var e=t.apply(this,arguments);null==e?this.removeAttribute(n):this.setAttribute(n,e)}function a(){var e=t.apply(this,arguments);null==e?this.removeAttributeNS(n.space,n.local):this.setAttributeNS(n.space,n.local,e)}return n=ta.ns.qualify(n),null==t?n.local?r:e:"function"==typeof t?n.local?a:o:n.local?i:u}function q(n){return n.trim().replace(/\s+/g," ")}function L(n){return new RegExp("(?:^|\\s+)"+ta.requote(n)+"(?:\\s+|$)","g")}function T(n){return(n+"").trim().split(/^|\s+/)}function R(n,t){function e(){for(var e=-1;++e<u;)n[e](this,t)}function r(){for(var e=-1,r=t.apply(this,arguments);++e<u;)n[e](this,r)}n=T(n).map(D);var u=n.length;return"function"==typeof t?r:e}function D(n){var t=L(n);return function(e,r){if(u=e.classList)return r?u.add(n):u.remove(n);var u=e.getAttribute("class")||"";r?(t.lastIndex=0,t.test(u)||e.setAttribute("class",q(u+" "+n))):e.setAttribute("class",q(u.replace(t," ")))}}function P(n,t,e){function r(){this.style.removeProperty(n)}function u(){this.style.setProperty(n,t,e)}function i(){var r=t.apply(this,arguments);null==r?this.style.removeProperty(n):this.style.setProperty(n,r,e)}return null==t?r:"function"==typeof t?i:u}function U(n,t){function e(){delete this[n]}function r(){this[n]=t}function u(){var e=t.apply(this,arguments);null==e?delete this[n]:this[n]=e}return null==t?e:"function"==typeof t?u:r}function j(n){function t(){var t=this.ownerDocument,e=this.namespaceURI;return e?t.createElementNS(e,n):t.createElement(n)}function e(){return this.ownerDocument.createElementNS(n.space,n.local)}return"function"==typeof n?n:(n=ta.ns.qualify(n)).local?e:t}function F(){var n=this.parentNode;n&&n.removeChild(this)}function H(n){return{__data__:n}}function O(n){return function(){return ba(this,n)}}function I(n){return arguments.length||(n=e),function(t,e){return t&&e?n(t.__data__,e.__data__):!t-!e}}function Y(n,t){for(var e=0,r=n.length;r>e;e++)for(var u,i=n[e],o=0,a=i.length;a>o;o++)(u=i[o])&&t(u,o,e);return n}function Z(n){return ya(n,Sa),n}function V(n){var t,e;return function(r,u,i){var o,a=n[i].update,c=a.length;for(i!=e&&(e=i,t=0),u>=t&&(t=u+1);!(o=a[t])&&++t<c;);return o}}function X(n,t,e){function r(){var t=this[o];t&&(this.removeEventListener(n,t,t.$),delete this[o])}function u(){var u=c(t,ra(arguments));r.call(this),this.addEventListener(n,this[o]=u,u.$=e),u._=t}function i(){var t,e=new RegExp("^__on([^.]+)"+ta.requote(n)+"$");for(var r in this)if(t=r.match(e)){var u=this[r];this.removeEventListener(t[1],u,u.$),delete this[r]}}var o="__on"+n,a=n.indexOf("."),c=$;a>0&&(n=n.slice(0,a));var l=ka.get(n);return l&&(n=l,c=B),a?t?u:r:t?b:i}function $(n,t){return function(e){var r=ta.event;ta.event=e,t[0]=this.__data__;try{n.apply(this,t)}finally{ta.event=r}}}function B(n,t){var e=$(n,t);return function(n){var t=this,r=n.relatedTarget;r&&(r===t||8&r.compareDocumentPosition(t))||e.call(t,n)}}function W(e){var r=".dragsuppress-"+ ++Aa,u="click"+r,i=ta.select(t(e)).on("touchmove"+r,S).on("dragstart"+r,S).on("selectstart"+r,S);if(null==Ea&&(Ea="onselectstart"in e?!1:x(e.style,"userSelect")),Ea){var o=n(e).style,a=o[Ea];o[Ea]="none"}return function(n){if(i.on(r,null),Ea&&(o[Ea]=a),n){var t=function(){i.on(u,null)};i.on(u,function(){S(),t()},!0),setTimeout(t,0)}}}function J(n,e){e.changedTouches&&(e=e.changedTouches[0]);var r=n.ownerSVGElement||n;if(r.createSVGPoint){var u=r.createSVGPoint();if(0>Na){var i=t(n);if(i.scrollX||i.scrollY){r=ta.select("body").append("svg").style({position:"absolute",top:0,left:0,margin:0,padding:0,border:"none"},"important");var o=r[0][0].getScreenCTM();Na=!(o.f||o.e),r.remove()}}return Na?(u.x=e.pageX,u.y=e.pageY):(u.x=e.clientX,u.y=e.clientY),u=u.matrixTransform(n.getScreenCTM().inverse()),[u.x,u.y]}var a=n.getBoundingClientRect();return[e.clientX-a.left-n.clientLeft,e.clientY-a.top-n.clientTop]}function G(){return ta.event.changedTouches[0].identifier}function K(n){return n>0?1:0>n?-1:0}function Q(n,t,e){return(t[0]-n[0])*(e[1]-n[1])-(t[1]-n[1])*(e[0]-n[0])}function nt(n){return n>1?0:-1>n?qa:Math.acos(n)}function tt(n){return n>1?Ra:-1>n?-Ra:Math.asin(n)}function et(n){return((n=Math.exp(n))-1/n)/2}function rt(n){return((n=Math.exp(n))+1/n)/2}function ut(n){return((n=Math.exp(2*n))-1)/(n+1)}function it(n){return(n=Math.sin(n/2))*n}function ot(){}function at(n,t,e){return this instanceof at?(this.h=+n,this.s=+t,void(this.l=+e)):arguments.length<2?n instanceof at?new at(n.h,n.s,n.l):bt(""+n,_t,at):new at(n,t,e)}function ct(n,t,e){function r(n){return n>360?n-=360:0>n&&(n+=360),60>n?i+(o-i)*n/60:180>n?o:240>n?i+(o-i)*(240-n)/60:i}function u(n){return Math.round(255*r(n))}var i,o;return n=isNaN(n)?0:(n%=360)<0?n+360:n,t=isNaN(t)?0:0>t?0:t>1?1:t,e=0>e?0:e>1?1:e,o=.5>=e?e*(1+t):e+t-e*t,i=2*e-o,new mt(u(n+120),u(n),u(n-120))}function lt(n,t,e){return this instanceof lt?(this.h=+n,this.c=+t,void(this.l=+e)):arguments.length<2?n instanceof lt?new lt(n.h,n.c,n.l):n instanceof ft?gt(n.l,n.a,n.b):gt((n=wt((n=ta.rgb(n)).r,n.g,n.b)).l,n.a,n.b):new lt(n,t,e)}function st(n,t,e){return isNaN(n)&&(n=0),isNaN(t)&&(t=0),new ft(e,Math.cos(n*=Da)*t,Math.sin(n)*t)}function ft(n,t,e){return this instanceof ft?(this.l=+n,this.a=+t,void(this.b=+e)):arguments.length<2?n instanceof ft?new ft(n.l,n.a,n.b):n instanceof lt?st(n.h,n.c,n.l):wt((n=mt(n)).r,n.g,n.b):new ft(n,t,e)}function ht(n,t,e){var r=(n+16)/116,u=r+t/500,i=r-e/200;return u=pt(u)*Xa,r=pt(r)*$a,i=pt(i)*Ba,new mt(dt(3.2404542*u-1.5371385*r-.4985314*i),dt(-.969266*u+1.8760108*r+.041556*i),dt(.0556434*u-.2040259*r+1.0572252*i))}function gt(n,t,e){return n>0?new lt(Math.atan2(e,t)*Pa,Math.sqrt(t*t+e*e),n):new lt(0/0,0/0,n)}function pt(n){return n>.206893034?n*n*n:(n-4/29)/7.787037}function vt(n){return n>.008856?Math.pow(n,1/3):7.787037*n+4/29}function dt(n){return Math.round(255*(.00304>=n?12.92*n:1.055*Math.pow(n,1/2.4)-.055))}function mt(n,t,e){return this instanceof mt?(this.r=~~n,this.g=~~t,void(this.b=~~e)):arguments.length<2?n instanceof mt?new mt(n.r,n.g,n.b):bt(""+n,mt,ct):new mt(n,t,e)}function yt(n){return new mt(n>>16,n>>8&255,255&n)}function Mt(n){return yt(n)+""}function xt(n){return 16>n?"0"+Math.max(0,n).toString(16):Math.min(255,n).toString(16)}function bt(n,t,e){var r,u,i,o=0,a=0,c=0;if(r=/([a-z]+)\((.*)\)/.exec(n=n.toLowerCase()))switch(u=r[2].split(","),r[1]){case"hsl":return e(parseFloat(u[0]),parseFloat(u[1])/100,parseFloat(u[2])/100);case"rgb":return t(kt(u[0]),kt(u[1]),kt(u[2]))}return(i=Ga.get(n))?t(i.r,i.g,i.b):(null==n||"#"!==n.charAt(0)||isNaN(i=parseInt(n.slice(1),16))||(4===n.length?(o=(3840&i)>>4,o=o>>4|o,a=240&i,a=a>>4|a,c=15&i,c=c<<4|c):7===n.length&&(o=(16711680&i)>>16,a=(65280&i)>>8,c=255&i)),t(o,a,c))}function _t(n,t,e){var r,u,i=Math.min(n/=255,t/=255,e/=255),o=Math.max(n,t,e),a=o-i,c=(o+i)/2;return a?(u=.5>c?a/(o+i):a/(2-o-i),r=n==o?(t-e)/a+(e>t?6:0):t==o?(e-n)/a+2:(n-t)/a+4,r*=60):(r=0/0,u=c>0&&1>c?0:r),new at(r,u,c)}function wt(n,t,e){n=St(n),t=St(t),e=St(e);var r=vt((.4124564*n+.3575761*t+.1804375*e)/Xa),u=vt((.2126729*n+.7151522*t+.072175*e)/$a),i=vt((.0193339*n+.119192*t+.9503041*e)/Ba);return ft(116*u-16,500*(r-u),200*(u-i))}function St(n){return(n/=255)<=.04045?n/12.92:Math.pow((n+.055)/1.055,2.4)}function kt(n){var t=parseFloat(n);return"%"===n.charAt(n.length-1)?Math.round(2.55*t):t}function Et(n){return"function"==typeof n?n:function(){return n}}function At(n){return function(t,e,r){return 2===arguments.length&&"function"==typeof e&&(r=e,e=null),Nt(t,e,n,r)}}function Nt(n,t,e,r){function u(){var n,t=c.status;if(!t&&zt(c)||t>=200&&300>t||304===t){try{n=e.call(i,c)}catch(r){return void o.error.call(i,r)}o.load.call(i,n)}else o.error.call(i,c)}var i={},o=ta.dispatch("beforesend","progress","load","error"),a={},c=new XMLHttpRequest,l=null;return!this.XDomainRequest||"withCredentials"in c||!/^(http(s)?:)?\/\//.test(n)||(c=new XDomainRequest),"onload"in c?c.onload=c.onerror=u:c.onreadystatechange=function(){c.readyState>3&&u()},c.onprogress=function(n){var t=ta.event;ta.event=n;try{o.progress.call(i,c)}finally{ta.event=t}},i.header=function(n,t){return n=(n+"").toLowerCase(),arguments.length<2?a[n]:(null==t?delete a[n]:a[n]=t+"",i)},i.mimeType=function(n){return arguments.length?(t=null==n?null:n+"",i):t},i.responseType=function(n){return arguments.length?(l=n,i):l},i.response=function(n){return e=n,i},["get","post"].forEach(function(n){i[n]=function(){return i.send.apply(i,[n].concat(ra(arguments)))}}),i.send=function(e,r,u){if(2===arguments.length&&"function"==typeof r&&(u=r,r=null),c.open(e,n,!0),null==t||"accept"in a||(a.accept=t+",*/*"),c.setRequestHeader)for(var s in a)c.setRequestHeader(s,a[s]);return null!=t&&c.overrideMimeType&&c.overrideMimeType(t),null!=l&&(c.responseType=l),null!=u&&i.on("error",u).on("load",function(n){u(null,n)}),o.beforesend.call(i,c),c.send(null==r?null:r),i},i.abort=function(){return c.abort(),i},ta.rebind(i,o,"on"),null==r?i:i.get(Ct(r))}function Ct(n){return 1===n.length?function(t,e){n(null==t?e:null)}:n}function zt(n){var t=n.responseType;return t&&"text"!==t?n.response:n.responseText}function qt(){var n=Lt(),t=Tt()-n;t>24?(isFinite(t)&&(clearTimeout(tc),tc=setTimeout(qt,t)),nc=0):(nc=1,rc(qt))}function Lt(){var n=Date.now();for(ec=Ka;ec;)n>=ec.t&&(ec.f=ec.c(n-ec.t)),ec=ec.n;return n}function Tt(){for(var n,t=Ka,e=1/0;t;)t.f?t=n?n.n=t.n:Ka=t.n:(t.t<e&&(e=t.t),t=(n=t).n);return Qa=n,e}function Rt(n,t){return t-(n?Math.ceil(Math.log(n)/Math.LN10):1)}function Dt(n,t){var e=Math.pow(10,3*ga(8-t));return{scale:t>8?function(n){return n/e}:function(n){return n*e},symbol:n}}function Pt(n){var t=n.decimal,e=n.thousands,r=n.grouping,u=n.currency,i=r&&e?function(n,t){for(var u=n.length,i=[],o=0,a=r[0],c=0;u>0&&a>0&&(c+a+1>t&&(a=Math.max(1,t-c)),i.push(n.substring(u-=a,u+a)),!((c+=a+1)>t));)a=r[o=(o+1)%r.length];return i.reverse().join(e)}:y;return function(n){var e=ic.exec(n),r=e[1]||" ",o=e[2]||">",a=e[3]||"-",c=e[4]||"",l=e[5],s=+e[6],f=e[7],h=e[8],g=e[9],p=1,v="",d="",m=!1,y=!0;switch(h&&(h=+h.substring(1)),(l||"0"===r&&"="===o)&&(l=r="0",o="="),g){case"n":f=!0,g="g";break;case"%":p=100,d="%",g="f";break;case"p":p=100,d="%",g="r";break;case"b":case"o":case"x":case"X":"#"===c&&(v="0"+g.toLowerCase());case"c":y=!1;case"d":m=!0,h=0;break;case"s":p=-1,g="r"}"$"===c&&(v=u[0],d=u[1]),"r"!=g||h||(g="g"),null!=h&&("g"==g?h=Math.max(1,Math.min(21,h)):("e"==g||"f"==g)&&(h=Math.max(0,Math.min(20,h)))),g=oc.get(g)||Ut;var M=l&&f;return function(n){var e=d;if(m&&n%1)return"";var u=0>n||0===n&&0>1/n?(n=-n,"-"):"-"===a?"":a;if(0>p){var c=ta.formatPrefix(n,h);n=c.scale(n),e=c.symbol+d}else n*=p;n=g(n,h);var x,b,_=n.lastIndexOf(".");if(0>_){var w=y?n.lastIndexOf("e"):-1;0>w?(x=n,b=""):(x=n.substring(0,w),b=n.substring(w))}else x=n.substring(0,_),b=t+n.substring(_+1);!l&&f&&(x=i(x,1/0));var S=v.length+x.length+b.length+(M?0:u.length),k=s>S?new Array(S=s-S+1).join(r):"";return M&&(x=i(k+x,k.length?s-b.length:1/0)),u+=v,n=x+b,("<"===o?u+n+k:">"===o?k+u+n:"^"===o?k.substring(0,S>>=1)+u+n+k.substring(S):u+(M?n:k+n))+e}}}function Ut(n){return n+""}function jt(){this._=new Date(arguments.length>1?Date.UTC.apply(this,arguments):arguments[0])}function Ft(n,t,e){function r(t){var e=n(t),r=i(e,1);return r-t>t-e?e:r}function u(e){return t(e=n(new cc(e-1)),1),e}function i(n,e){return t(n=new cc(+n),e),n}function o(n,r,i){var o=u(n),a=[];if(i>1)for(;r>o;)e(o)%i||a.push(new Date(+o)),t(o,1);else for(;r>o;)a.push(new Date(+o)),t(o,1);return a}function a(n,t,e){try{cc=jt;var r=new jt;return r._=n,o(r,t,e)}finally{cc=Date}}n.floor=n,n.round=r,n.ceil=u,n.offset=i,n.range=o;var c=n.utc=Ht(n);return c.floor=c,c.round=Ht(r),c.ceil=Ht(u),c.offset=Ht(i),c.range=a,n}function Ht(n){return function(t,e){try{cc=jt;var r=new jt;return r._=t,n(r,e)._}finally{cc=Date}}}function Ot(n){function t(n){function t(t){for(var e,u,i,o=[],a=-1,c=0;++a<r;)37===n.charCodeAt(a)&&(o.push(n.slice(c,a)),null!=(u=sc[e=n.charAt(++a)])&&(e=n.charAt(++a)),(i=N[e])&&(e=i(t,null==u?"e"===e?" ":"0":u)),o.push(e),c=a+1);return o.push(n.slice(c,a)),o.join("")}var r=n.length;return t.parse=function(t){var r={y:1900,m:0,d:1,H:0,M:0,S:0,L:0,Z:null},u=e(r,n,t,0);if(u!=t.length)return null;"p"in r&&(r.H=r.H%12+12*r.p);var i=null!=r.Z&&cc!==jt,o=new(i?jt:cc);return"j"in r?o.setFullYear(r.y,0,r.j):"w"in r&&("W"in r||"U"in r)?(o.setFullYear(r.y,0,1),o.setFullYear(r.y,0,"W"in r?(r.w+6)%7+7*r.W-(o.getDay()+5)%7:r.w+7*r.U-(o.getDay()+6)%7)):o.setFullYear(r.y,r.m,r.d),o.setHours(r.H+(r.Z/100|0),r.M+r.Z%100,r.S,r.L),i?o._:o},t.toString=function(){return n},t}function e(n,t,e,r){for(var u,i,o,a=0,c=t.length,l=e.length;c>a;){if(r>=l)return-1;if(u=t.charCodeAt(a++),37===u){if(o=t.charAt(a++),i=C[o in sc?t.charAt(a++):o],!i||(r=i(n,e,r))<0)return-1}else if(u!=e.charCodeAt(r++))return-1}return r}function r(n,t,e){_.lastIndex=0;var r=_.exec(t.slice(e));return r?(n.w=w.get(r[0].toLowerCase()),e+r[0].length):-1}function u(n,t,e){x.lastIndex=0;var r=x.exec(t.slice(e));return r?(n.w=b.get(r[0].toLowerCase()),e+r[0].length):-1}function i(n,t,e){E.lastIndex=0;var r=E.exec(t.slice(e));return r?(n.m=A.get(r[0].toLowerCase()),e+r[0].length):-1}function o(n,t,e){S.lastIndex=0;var r=S.exec(t.slice(e));return r?(n.m=k.get(r[0].toLowerCase()),e+r[0].length):-1}function a(n,t,r){return e(n,N.c.toString(),t,r)}function c(n,t,r){return e(n,N.x.toString(),t,r)}function l(n,t,r){return e(n,N.X.toString(),t,r)}function s(n,t,e){var r=M.get(t.slice(e,e+=2).toLowerCase());return null==r?-1:(n.p=r,e)}var f=n.dateTime,h=n.date,g=n.time,p=n.periods,v=n.days,d=n.shortDays,m=n.months,y=n.shortMonths;t.utc=function(n){function e(n){try{cc=jt;var t=new cc;return t._=n,r(t)}finally{cc=Date}}var r=t(n);return e.parse=function(n){try{cc=jt;var t=r.parse(n);return t&&t._}finally{cc=Date}},e.toString=r.toString,e},t.multi=t.utc.multi=ae;var M=ta.map(),x=Yt(v),b=Zt(v),_=Yt(d),w=Zt(d),S=Yt(m),k=Zt(m),E=Yt(y),A=Zt(y);p.forEach(function(n,t){M.set(n.toLowerCase(),t)});var N={a:function(n){return d[n.getDay()]},A:function(n){return v[n.getDay()]},b:function(n){return y[n.getMonth()]},B:function(n){return m[n.getMonth()]},c:t(f),d:function(n,t){return It(n.getDate(),t,2)},e:function(n,t){return It(n.getDate(),t,2)},H:function(n,t){return It(n.getHours(),t,2)},I:function(n,t){return It(n.getHours()%12||12,t,2)},j:function(n,t){return It(1+ac.dayOfYear(n),t,3)},L:function(n,t){return It(n.getMilliseconds(),t,3)},m:function(n,t){return It(n.getMonth()+1,t,2)},M:function(n,t){return It(n.getMinutes(),t,2)},p:function(n){return p[+(n.getHours()>=12)]},S:function(n,t){return It(n.getSeconds(),t,2)},U:function(n,t){return It(ac.sundayOfYear(n),t,2)},w:function(n){return n.getDay()},W:function(n,t){return It(ac.mondayOfYear(n),t,2)},x:t(h),X:t(g),y:function(n,t){return It(n.getFullYear()%100,t,2)},Y:function(n,t){return It(n.getFullYear()%1e4,t,4)},Z:ie,"%":function(){return"%"}},C={a:r,A:u,b:i,B:o,c:a,d:Qt,e:Qt,H:te,I:te,j:ne,L:ue,m:Kt,M:ee,p:s,S:re,U:Xt,w:Vt,W:$t,x:c,X:l,y:Wt,Y:Bt,Z:Jt,"%":oe};return t}function It(n,t,e){var r=0>n?"-":"",u=(r?-n:n)+"",i=u.length;return r+(e>i?new Array(e-i+1).join(t)+u:u)}function Yt(n){return new RegExp("^(?:"+n.map(ta.requote).join("|")+")","i")}function Zt(n){for(var t=new l,e=-1,r=n.length;++e<r;)t.set(n[e].toLowerCase(),e);return t}function Vt(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+1));return r?(n.w=+r[0],e+r[0].length):-1}function Xt(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e));return r?(n.U=+r[0],e+r[0].length):-1}function $t(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e));return r?(n.W=+r[0],e+r[0].length):-1}function Bt(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+4));return r?(n.y=+r[0],e+r[0].length):-1}function Wt(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+2));return r?(n.y=Gt(+r[0]),e+r[0].length):-1}function Jt(n,t,e){return/^[+-]\d{4}$/.test(t=t.slice(e,e+5))?(n.Z=-t,e+5):-1}function Gt(n){return n+(n>68?1900:2e3)}function Kt(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+2));return r?(n.m=r[0]-1,e+r[0].length):-1}function Qt(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+2));return r?(n.d=+r[0],e+r[0].length):-1}function ne(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+3));return r?(n.j=+r[0],e+r[0].length):-1}function te(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+2));return r?(n.H=+r[0],e+r[0].length):-1}function ee(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+2));return r?(n.M=+r[0],e+r[0].length):-1}function re(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+2));return r?(n.S=+r[0],e+r[0].length):-1}function ue(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+3));return r?(n.L=+r[0],e+r[0].length):-1}function ie(n){var t=n.getTimezoneOffset(),e=t>0?"-":"+",r=ga(t)/60|0,u=ga(t)%60;return e+It(r,"0",2)+It(u,"0",2)}function oe(n,t,e){hc.lastIndex=0;var r=hc.exec(t.slice(e,e+1));return r?e+r[0].length:-1}function ae(n){for(var t=n.length,e=-1;++e<t;)n[e][0]=this(n[e][0]);return function(t){for(var e=0,r=n[e];!r[1](t);)r=n[++e];return r[0](t)}}function ce(){}function le(n,t,e){var r=e.s=n+t,u=r-n,i=r-u;e.t=n-i+(t-u)}function se(n,t){n&&dc.hasOwnProperty(n.type)&&dc[n.type](n,t)}function fe(n,t,e){var r,u=-1,i=n.length-e;for(t.lineStart();++u<i;)r=n[u],t.point(r[0],r[1],r[2]);t.lineEnd()}function he(n,t){var e=-1,r=n.length;for(t.polygonStart();++e<r;)fe(n[e],t,1);t.polygonEnd()}function ge(){function n(n,t){n*=Da,t=t*Da/2+qa/4;var e=n-r,o=e>=0?1:-1,a=o*e,c=Math.cos(t),l=Math.sin(t),s=i*l,f=u*c+s*Math.cos(a),h=s*o*Math.sin(a);yc.add(Math.atan2(h,f)),r=n,u=c,i=l}var t,e,r,u,i;Mc.point=function(o,a){Mc.point=n,r=(t=o)*Da,u=Math.cos(a=(e=a)*Da/2+qa/4),i=Math.sin(a)},Mc.lineEnd=function(){n(t,e)}}function pe(n){var t=n[0],e=n[1],r=Math.cos(e);return[r*Math.cos(t),r*Math.sin(t),Math.sin(e)]}function ve(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]}function de(n,t){return[n[1]*t[2]-n[2]*t[1],n[2]*t[0]-n[0]*t[2],n[0]*t[1]-n[1]*t[0]]}function me(n,t){n[0]+=t[0],n[1]+=t[1],n[2]+=t[2]}function ye(n,t){return[n[0]*t,n[1]*t,n[2]*t]}function Me(n){var t=Math.sqrt(n[0]*n[0]+n[1]*n[1]+n[2]*n[2]);n[0]/=t,n[1]/=t,n[2]/=t}function xe(n){return[Math.atan2(n[1],n[0]),tt(n[2])]}function be(n,t){return ga(n[0]-t[0])<Ca&&ga(n[1]-t[1])<Ca}function _e(n,t){n*=Da;var e=Math.cos(t*=Da);we(e*Math.cos(n),e*Math.sin(n),Math.sin(t))}function we(n,t,e){++xc,_c+=(n-_c)/xc,wc+=(t-wc)/xc,Sc+=(e-Sc)/xc}function Se(){function n(n,u){n*=Da;var i=Math.cos(u*=Da),o=i*Math.cos(n),a=i*Math.sin(n),c=Math.sin(u),l=Math.atan2(Math.sqrt((l=e*c-r*a)*l+(l=r*o-t*c)*l+(l=t*a-e*o)*l),t*o+e*a+r*c);bc+=l,kc+=l*(t+(t=o)),Ec+=l*(e+(e=a)),Ac+=l*(r+(r=c)),we(t,e,r)}var t,e,r;qc.point=function(u,i){u*=Da;var o=Math.cos(i*=Da);t=o*Math.cos(u),e=o*Math.sin(u),r=Math.sin(i),qc.point=n,we(t,e,r)}}function ke(){qc.point=_e}function Ee(){function n(n,t){n*=Da;var e=Math.cos(t*=Da),o=e*Math.cos(n),a=e*Math.sin(n),c=Math.sin(t),l=u*c-i*a,s=i*o-r*c,f=r*a-u*o,h=Math.sqrt(l*l+s*s+f*f),g=r*o+u*a+i*c,p=h&&-nt(g)/h,v=Math.atan2(h,g);Nc+=p*l,Cc+=p*s,zc+=p*f,bc+=v,kc+=v*(r+(r=o)),Ec+=v*(u+(u=a)),Ac+=v*(i+(i=c)),we(r,u,i)}var t,e,r,u,i;qc.point=function(o,a){t=o,e=a,qc.point=n,o*=Da;var c=Math.cos(a*=Da);r=c*Math.cos(o),u=c*Math.sin(o),i=Math.sin(a),we(r,u,i)},qc.lineEnd=function(){n(t,e),qc.lineEnd=ke,qc.point=_e}}function Ae(n,t){function e(e,r){return e=n(e,r),t(e[0],e[1])}return n.invert&&t.invert&&(e.invert=function(e,r){return e=t.invert(e,r),e&&n.invert(e[0],e[1])}),e}function Ne(){return!0}function Ce(n,t,e,r,u){var i=[],o=[];if(n.forEach(function(n){if(!((t=n.length-1)<=0)){var t,e=n[0],r=n[t];if(be(e,r)){u.lineStart();for(var a=0;t>a;++a)u.point((e=n[a])[0],e[1]);return void u.lineEnd()}var c=new qe(e,n,null,!0),l=new qe(e,null,c,!1);c.o=l,i.push(c),o.push(l),c=new qe(r,n,null,!1),l=new qe(r,null,c,!0),c.o=l,i.push(c),o.push(l)}}),o.sort(t),ze(i),ze(o),i.length){for(var a=0,c=e,l=o.length;l>a;++a)o[a].e=c=!c;for(var s,f,h=i[0];;){for(var g=h,p=!0;g.v;)if((g=g.n)===h)return;s=g.z,u.lineStart();do{if(g.v=g.o.v=!0,g.e){if(p)for(var a=0,l=s.length;l>a;++a)u.point((f=s[a])[0],f[1]);else r(g.x,g.n.x,1,u);g=g.n}else{if(p){s=g.p.z;for(var a=s.length-1;a>=0;--a)u.point((f=s[a])[0],f[1])}else r(g.x,g.p.x,-1,u);g=g.p}g=g.o,s=g.z,p=!p}while(!g.v);u.lineEnd()}}}function ze(n){if(t=n.length){for(var t,e,r=0,u=n[0];++r<t;)u.n=e=n[r],e.p=u,u=e;u.n=e=n[0],e.p=u}}function qe(n,t,e,r){this.x=n,this.z=t,this.o=e,this.e=r,this.v=!1,this.n=this.p=null}function Le(n,t,e,r){return function(u,i){function o(t,e){var r=u(t,e);n(t=r[0],e=r[1])&&i.point(t,e)}function a(n,t){var e=u(n,t);d.point(e[0],e[1])}function c(){y.point=a,d.lineStart()}function l(){y.point=o,d.lineEnd()}function s(n,t){v.push([n,t]);var e=u(n,t);x.point(e[0],e[1])}function f(){x.lineStart(),v=[]}function h(){s(v[0][0],v[0][1]),x.lineEnd();var n,t=x.clean(),e=M.buffer(),r=e.length;if(v.pop(),p.push(v),v=null,r)if(1&t){n=e[0];var u,r=n.length-1,o=-1;if(r>0){for(b||(i.polygonStart(),b=!0),i.lineStart();++o<r;)i.point((u=n[o])[0],u[1]);i.lineEnd()}}else r>1&&2&t&&e.push(e.pop().concat(e.shift())),g.push(e.filter(Te))}var g,p,v,d=t(i),m=u.invert(r[0],r[1]),y={point:o,lineStart:c,lineEnd:l,polygonStart:function(){y.point=s,y.lineStart=f,y.lineEnd=h,g=[],p=[]},polygonEnd:function(){y.point=o,y.lineStart=c,y.lineEnd=l,g=ta.merge(g);var n=Fe(m,p);g.length?(b||(i.polygonStart(),b=!0),Ce(g,De,n,e,i)):n&&(b||(i.polygonStart(),b=!0),i.lineStart(),e(null,null,1,i),i.lineEnd()),b&&(i.polygonEnd(),b=!1),g=p=null},sphere:function(){i.polygonStart(),i.lineStart(),e(null,null,1,i),i.lineEnd(),i.polygonEnd()}},M=Re(),x=t(M),b=!1;return y}}function Te(n){return n.length>1}function Re(){var n,t=[];return{lineStart:function(){t.push(n=[])},point:function(t,e){n.push([t,e])},lineEnd:b,buffer:function(){var e=t;return t=[],n=null,e},rejoin:function(){t.length>1&&t.push(t.pop().concat(t.shift()))}}}function De(n,t){return((n=n.x)[0]<0?n[1]-Ra-Ca:Ra-n[1])-((t=t.x)[0]<0?t[1]-Ra-Ca:Ra-t[1])}function Pe(n){var t,e=0/0,r=0/0,u=0/0;return{lineStart:function(){n.lineStart(),t=1},point:function(i,o){var a=i>0?qa:-qa,c=ga(i-e);ga(c-qa)<Ca?(n.point(e,r=(r+o)/2>0?Ra:-Ra),n.point(u,r),n.lineEnd(),n.lineStart(),n.point(a,r),n.point(i,r),t=0):u!==a&&c>=qa&&(ga(e-u)<Ca&&(e-=u*Ca),ga(i-a)<Ca&&(i-=a*Ca),r=Ue(e,r,i,o),n.point(u,r),n.lineEnd(),n.lineStart(),n.point(a,r),t=0),n.point(e=i,r=o),u=a},lineEnd:function(){n.lineEnd(),e=r=0/0},clean:function(){return 2-t}}}function Ue(n,t,e,r){var u,i,o=Math.sin(n-e);return ga(o)>Ca?Math.atan((Math.sin(t)*(i=Math.cos(r))*Math.sin(e)-Math.sin(r)*(u=Math.cos(t))*Math.sin(n))/(u*i*o)):(t+r)/2}function je(n,t,e,r){var u;if(null==n)u=e*Ra,r.point(-qa,u),r.point(0,u),r.point(qa,u),r.point(qa,0),r.point(qa,-u),r.point(0,-u),r.point(-qa,-u),r.point(-qa,0),r.point(-qa,u);else if(ga(n[0]-t[0])>Ca){var i=n[0]<t[0]?qa:-qa;u=e*i/2,r.point(-i,u),r.point(0,u),r.point(i,u)}else r.point(t[0],t[1])}function Fe(n,t){var e=n[0],r=n[1],u=[Math.sin(e),-Math.cos(e),0],i=0,o=0;yc.reset();for(var a=0,c=t.length;c>a;++a){var l=t[a],s=l.length;if(s)for(var f=l[0],h=f[0],g=f[1]/2+qa/4,p=Math.sin(g),v=Math.cos(g),d=1;;){d===s&&(d=0),n=l[d];var m=n[0],y=n[1]/2+qa/4,M=Math.sin(y),x=Math.cos(y),b=m-h,_=b>=0?1:-1,w=_*b,S=w>qa,k=p*M;if(yc.add(Math.atan2(k*_*Math.sin(w),v*x+k*Math.cos(w))),i+=S?b+_*La:b,S^h>=e^m>=e){var E=de(pe(f),pe(n));Me(E);var A=de(u,E);Me(A);var N=(S^b>=0?-1:1)*tt(A[2]);(r>N||r===N&&(E[0]||E[1]))&&(o+=S^b>=0?1:-1)}if(!d++)break;h=m,p=M,v=x,f=n}}return(-Ca>i||Ca>i&&0>yc)^1&o}function He(n){function t(n,t){return Math.cos(n)*Math.cos(t)>i}function e(n){var e,i,c,l,s;return{lineStart:function(){l=c=!1,s=1},point:function(f,h){var g,p=[f,h],v=t(f,h),d=o?v?0:u(f,h):v?u(f+(0>f?qa:-qa),h):0;if(!e&&(l=c=v)&&n.lineStart(),v!==c&&(g=r(e,p),(be(e,g)||be(p,g))&&(p[0]+=Ca,p[1]+=Ca,v=t(p[0],p[1]))),v!==c)s=0,v?(n.lineStart(),g=r(p,e),n.point(g[0],g[1])):(g=r(e,p),n.point(g[0],g[1]),n.lineEnd()),e=g;else if(a&&e&&o^v){var m;d&i||!(m=r(p,e,!0))||(s=0,o?(n.lineStart(),n.point(m[0][0],m[0][1]),n.point(m[1][0],m[1][1]),n.lineEnd()):(n.point(m[1][0],m[1][1]),n.lineEnd(),n.lineStart(),n.point(m[0][0],m[0][1])))}!v||e&&be(e,p)||n.point(p[0],p[1]),e=p,c=v,i=d},lineEnd:function(){c&&n.lineEnd(),e=null},clean:function(){return s|(l&&c)<<1}}}function r(n,t,e){var r=pe(n),u=pe(t),o=[1,0,0],a=de(r,u),c=ve(a,a),l=a[0],s=c-l*l;if(!s)return!e&&n;var f=i*c/s,h=-i*l/s,g=de(o,a),p=ye(o,f),v=ye(a,h);me(p,v);var d=g,m=ve(p,d),y=ve(d,d),M=m*m-y*(ve(p,p)-1);if(!(0>M)){var x=Math.sqrt(M),b=ye(d,(-m-x)/y);if(me(b,p),b=xe(b),!e)return b;var _,w=n[0],S=t[0],k=n[1],E=t[1];w>S&&(_=w,w=S,S=_);var A=S-w,N=ga(A-qa)<Ca,C=N||Ca>A;if(!N&&k>E&&(_=k,k=E,E=_),C?N?k+E>0^b[1]<(ga(b[0]-w)<Ca?k:E):k<=b[1]&&b[1]<=E:A>qa^(w<=b[0]&&b[0]<=S)){var z=ye(d,(-m+x)/y);return me(z,p),[b,xe(z)]}}}function u(t,e){var r=o?n:qa-n,u=0;return-r>t?u|=1:t>r&&(u|=2),-r>e?u|=4:e>r&&(u|=8),u}var i=Math.cos(n),o=i>0,a=ga(i)>Ca,c=gr(n,6*Da);return Le(t,e,c,o?[0,-n]:[-qa,n-qa])}function Oe(n,t,e,r){return function(u){var i,o=u.a,a=u.b,c=o.x,l=o.y,s=a.x,f=a.y,h=0,g=1,p=s-c,v=f-l;if(i=n-c,p||!(i>0)){if(i/=p,0>p){if(h>i)return;g>i&&(g=i)}else if(p>0){if(i>g)return;i>h&&(h=i)}if(i=e-c,p||!(0>i)){if(i/=p,0>p){if(i>g)return;i>h&&(h=i)}else if(p>0){if(h>i)return;g>i&&(g=i)}if(i=t-l,v||!(i>0)){if(i/=v,0>v){if(h>i)return;g>i&&(g=i)}else if(v>0){if(i>g)return;i>h&&(h=i)}if(i=r-l,v||!(0>i)){if(i/=v,0>v){if(i>g)return;i>h&&(h=i)}else if(v>0){if(h>i)return;g>i&&(g=i)}return h>0&&(u.a={x:c+h*p,y:l+h*v}),1>g&&(u.b={x:c+g*p,y:l+g*v}),u}}}}}}function Ie(n,t,e,r){function u(r,u){return ga(r[0]-n)<Ca?u>0?0:3:ga(r[0]-e)<Ca?u>0?2:1:ga(r[1]-t)<Ca?u>0?1:0:u>0?3:2}function i(n,t){return o(n.x,t.x)}function o(n,t){var e=u(n,1),r=u(t,1);return e!==r?e-r:0===e?t[1]-n[1]:1===e?n[0]-t[0]:2===e?n[1]-t[1]:t[0]-n[0]}return function(a){function c(n){for(var t=0,e=d.length,r=n[1],u=0;e>u;++u)for(var i,o=1,a=d[u],c=a.length,l=a[0];c>o;++o)i=a[o],l[1]<=r?i[1]>r&&Q(l,i,n)>0&&++t:i[1]<=r&&Q(l,i,n)<0&&--t,l=i;return 0!==t}function l(i,a,c,l){var s=0,f=0;if(null==i||(s=u(i,c))!==(f=u(a,c))||o(i,a)<0^c>0){do l.point(0===s||3===s?n:e,s>1?r:t);while((s=(s+c+4)%4)!==f)}else l.point(a[0],a[1])}function s(u,i){return u>=n&&e>=u&&i>=t&&r>=i}function f(n,t){s(n,t)&&a.point(n,t)}function h(){C.point=p,d&&d.push(m=[]),S=!0,w=!1,b=_=0/0}function g(){v&&(p(y,M),x&&w&&A.rejoin(),v.push(A.buffer())),C.point=f,w&&a.lineEnd()}function p(n,t){n=Math.max(-Tc,Math.min(Tc,n)),t=Math.max(-Tc,Math.min(Tc,t));var e=s(n,t);if(d&&m.push([n,t]),S)y=n,M=t,x=e,S=!1,e&&(a.lineStart(),a.point(n,t));else if(e&&w)a.point(n,t);else{var r={a:{x:b,y:_},b:{x:n,y:t}};N(r)?(w||(a.lineStart(),a.point(r.a.x,r.a.y)),a.point(r.b.x,r.b.y),e||a.lineEnd(),k=!1):e&&(a.lineStart(),a.point(n,t),k=!1)}b=n,_=t,w=e}var v,d,m,y,M,x,b,_,w,S,k,E=a,A=Re(),N=Oe(n,t,e,r),C={point:f,lineStart:h,lineEnd:g,polygonStart:function(){a=A,v=[],d=[],k=!0},polygonEnd:function(){a=E,v=ta.merge(v);var t=c([n,r]),e=k&&t,u=v.length;(e||u)&&(a.polygonStart(),e&&(a.lineStart(),l(null,null,1,a),a.lineEnd()),u&&Ce(v,i,t,l,a),a.polygonEnd()),v=d=m=null}};return C}}function Ye(n){var t=0,e=qa/3,r=ir(n),u=r(t,e);return u.parallels=function(n){return arguments.length?r(t=n[0]*qa/180,e=n[1]*qa/180):[t/qa*180,e/qa*180]},u}function Ze(n,t){function e(n,t){var e=Math.sqrt(i-2*u*Math.sin(t))/u;return[e*Math.sin(n*=u),o-e*Math.cos(n)]}var r=Math.sin(n),u=(r+Math.sin(t))/2,i=1+r*(2*u-r),o=Math.sqrt(i)/u;return e.invert=function(n,t){var e=o-t;return[Math.atan2(n,e)/u,tt((i-(n*n+e*e)*u*u)/(2*u))]},e}function Ve(){function n(n,t){Dc+=u*n-r*t,r=n,u=t}var t,e,r,u;Hc.point=function(i,o){Hc.point=n,t=r=i,e=u=o},Hc.lineEnd=function(){n(t,e)}}function Xe(n,t){Pc>n&&(Pc=n),n>jc&&(jc=n),Uc>t&&(Uc=t),t>Fc&&(Fc=t)}function $e(){function n(n,t){o.push("M",n,",",t,i)}function t(n,t){o.push("M",n,",",t),a.point=e}function e(n,t){o.push("L",n,",",t)}function r(){a.point=n}function u(){o.push("Z")}var i=Be(4.5),o=[],a={point:n,lineStart:function(){a.point=t},lineEnd:r,polygonStart:function(){a.lineEnd=u},polygonEnd:function(){a.lineEnd=r,a.point=n},pointRadius:function(n){return i=Be(n),a},result:function(){if(o.length){var n=o.join("");return o=[],n}}};return a}function Be(n){return"m0,"+n+"a"+n+","+n+" 0 1,1 0,"+-2*n+"a"+n+","+n+" 0 1,1 0,"+2*n+"z"}function We(n,t){_c+=n,wc+=t,++Sc}function Je(){function n(n,r){var u=n-t,i=r-e,o=Math.sqrt(u*u+i*i);kc+=o*(t+n)/2,Ec+=o*(e+r)/2,Ac+=o,We(t=n,e=r)}var t,e;Ic.point=function(r,u){Ic.point=n,We(t=r,e=u)}}function Ge(){Ic.point=We}function Ke(){function n(n,t){var e=n-r,i=t-u,o=Math.sqrt(e*e+i*i);kc+=o*(r+n)/2,Ec+=o*(u+t)/2,Ac+=o,o=u*n-r*t,Nc+=o*(r+n),Cc+=o*(u+t),zc+=3*o,We(r=n,u=t)}var t,e,r,u;Ic.point=function(i,o){Ic.point=n,We(t=r=i,e=u=o)},Ic.lineEnd=function(){n(t,e)}}function Qe(n){function t(t,e){n.moveTo(t+o,e),n.arc(t,e,o,0,La)}function e(t,e){n.moveTo(t,e),a.point=r}function r(t,e){n.lineTo(t,e)}function u(){a.point=t}function i(){n.closePath()}var o=4.5,a={point:t,lineStart:function(){a.point=e},lineEnd:u,polygonStart:function(){a.lineEnd=i},polygonEnd:function(){a.lineEnd=u,a.point=t},pointRadius:function(n){return o=n,a},result:b};return a}function nr(n){function t(n){return(a?r:e)(n)}function e(t){return rr(t,function(e,r){e=n(e,r),t.point(e[0],e[1])})}function r(t){function e(e,r){e=n(e,r),t.point(e[0],e[1])}function r(){M=0/0,S.point=i,t.lineStart()}function i(e,r){var i=pe([e,r]),o=n(e,r);u(M,x,y,b,_,w,M=o[0],x=o[1],y=e,b=i[0],_=i[1],w=i[2],a,t),t.point(M,x)}function o(){S.point=e,t.lineEnd()}function c(){r(),S.point=l,S.lineEnd=s}function l(n,t){i(f=n,h=t),g=M,p=x,v=b,d=_,m=w,S.point=i}function s(){u(M,x,y,b,_,w,g,p,f,v,d,m,a,t),S.lineEnd=o,o()}var f,h,g,p,v,d,m,y,M,x,b,_,w,S={point:e,lineStart:r,lineEnd:o,polygonStart:function(){t.polygonStart(),S.lineStart=c
+},polygonEnd:function(){t.polygonEnd(),S.lineStart=r}};return S}function u(t,e,r,a,c,l,s,f,h,g,p,v,d,m){var y=s-t,M=f-e,x=y*y+M*M;if(x>4*i&&d--){var b=a+g,_=c+p,w=l+v,S=Math.sqrt(b*b+_*_+w*w),k=Math.asin(w/=S),E=ga(ga(w)-1)<Ca||ga(r-h)<Ca?(r+h)/2:Math.atan2(_,b),A=n(E,k),N=A[0],C=A[1],z=N-t,q=C-e,L=M*z-y*q;(L*L/x>i||ga((y*z+M*q)/x-.5)>.3||o>a*g+c*p+l*v)&&(u(t,e,r,a,c,l,N,C,E,b/=S,_/=S,w,d,m),m.point(N,C),u(N,C,E,b,_,w,s,f,h,g,p,v,d,m))}}var i=.5,o=Math.cos(30*Da),a=16;return t.precision=function(n){return arguments.length?(a=(i=n*n)>0&&16,t):Math.sqrt(i)},t}function tr(n){var t=nr(function(t,e){return n([t*Pa,e*Pa])});return function(n){return or(t(n))}}function er(n){this.stream=n}function rr(n,t){return{point:t,sphere:function(){n.sphere()},lineStart:function(){n.lineStart()},lineEnd:function(){n.lineEnd()},polygonStart:function(){n.polygonStart()},polygonEnd:function(){n.polygonEnd()}}}function ur(n){return ir(function(){return n})()}function ir(n){function t(n){return n=a(n[0]*Da,n[1]*Da),[n[0]*h+c,l-n[1]*h]}function e(n){return n=a.invert((n[0]-c)/h,(l-n[1])/h),n&&[n[0]*Pa,n[1]*Pa]}function r(){a=Ae(o=lr(m,M,x),i);var n=i(v,d);return c=g-n[0]*h,l=p+n[1]*h,u()}function u(){return s&&(s.valid=!1,s=null),t}var i,o,a,c,l,s,f=nr(function(n,t){return n=i(n,t),[n[0]*h+c,l-n[1]*h]}),h=150,g=480,p=250,v=0,d=0,m=0,M=0,x=0,b=Lc,_=y,w=null,S=null;return t.stream=function(n){return s&&(s.valid=!1),s=or(b(o,f(_(n)))),s.valid=!0,s},t.clipAngle=function(n){return arguments.length?(b=null==n?(w=n,Lc):He((w=+n)*Da),u()):w},t.clipExtent=function(n){return arguments.length?(S=n,_=n?Ie(n[0][0],n[0][1],n[1][0],n[1][1]):y,u()):S},t.scale=function(n){return arguments.length?(h=+n,r()):h},t.translate=function(n){return arguments.length?(g=+n[0],p=+n[1],r()):[g,p]},t.center=function(n){return arguments.length?(v=n[0]%360*Da,d=n[1]%360*Da,r()):[v*Pa,d*Pa]},t.rotate=function(n){return arguments.length?(m=n[0]%360*Da,M=n[1]%360*Da,x=n.length>2?n[2]%360*Da:0,r()):[m*Pa,M*Pa,x*Pa]},ta.rebind(t,f,"precision"),function(){return i=n.apply(this,arguments),t.invert=i.invert&&e,r()}}function or(n){return rr(n,function(t,e){n.point(t*Da,e*Da)})}function ar(n,t){return[n,t]}function cr(n,t){return[n>qa?n-La:-qa>n?n+La:n,t]}function lr(n,t,e){return n?t||e?Ae(fr(n),hr(t,e)):fr(n):t||e?hr(t,e):cr}function sr(n){return function(t,e){return t+=n,[t>qa?t-La:-qa>t?t+La:t,e]}}function fr(n){var t=sr(n);return t.invert=sr(-n),t}function hr(n,t){function e(n,t){var e=Math.cos(t),a=Math.cos(n)*e,c=Math.sin(n)*e,l=Math.sin(t),s=l*r+a*u;return[Math.atan2(c*i-s*o,a*r-l*u),tt(s*i+c*o)]}var r=Math.cos(n),u=Math.sin(n),i=Math.cos(t),o=Math.sin(t);return e.invert=function(n,t){var e=Math.cos(t),a=Math.cos(n)*e,c=Math.sin(n)*e,l=Math.sin(t),s=l*i-c*o;return[Math.atan2(c*i+l*o,a*r+s*u),tt(s*r-a*u)]},e}function gr(n,t){var e=Math.cos(n),r=Math.sin(n);return function(u,i,o,a){var c=o*t;null!=u?(u=pr(e,u),i=pr(e,i),(o>0?i>u:u>i)&&(u+=o*La)):(u=n+o*La,i=n-.5*c);for(var l,s=u;o>0?s>i:i>s;s-=c)a.point((l=xe([e,-r*Math.cos(s),-r*Math.sin(s)]))[0],l[1])}}function pr(n,t){var e=pe(t);e[0]-=n,Me(e);var r=nt(-e[1]);return((-e[2]<0?-r:r)+2*Math.PI-Ca)%(2*Math.PI)}function vr(n,t,e){var r=ta.range(n,t-Ca,e).concat(t);return function(n){return r.map(function(t){return[n,t]})}}function dr(n,t,e){var r=ta.range(n,t-Ca,e).concat(t);return function(n){return r.map(function(t){return[t,n]})}}function mr(n){return n.source}function yr(n){return n.target}function Mr(n,t,e,r){var u=Math.cos(t),i=Math.sin(t),o=Math.cos(r),a=Math.sin(r),c=u*Math.cos(n),l=u*Math.sin(n),s=o*Math.cos(e),f=o*Math.sin(e),h=2*Math.asin(Math.sqrt(it(r-t)+u*o*it(e-n))),g=1/Math.sin(h),p=h?function(n){var t=Math.sin(n*=h)*g,e=Math.sin(h-n)*g,r=e*c+t*s,u=e*l+t*f,o=e*i+t*a;return[Math.atan2(u,r)*Pa,Math.atan2(o,Math.sqrt(r*r+u*u))*Pa]}:function(){return[n*Pa,t*Pa]};return p.distance=h,p}function xr(){function n(n,u){var i=Math.sin(u*=Da),o=Math.cos(u),a=ga((n*=Da)-t),c=Math.cos(a);Yc+=Math.atan2(Math.sqrt((a=o*Math.sin(a))*a+(a=r*i-e*o*c)*a),e*i+r*o*c),t=n,e=i,r=o}var t,e,r;Zc.point=function(u,i){t=u*Da,e=Math.sin(i*=Da),r=Math.cos(i),Zc.point=n},Zc.lineEnd=function(){Zc.point=Zc.lineEnd=b}}function br(n,t){function e(t,e){var r=Math.cos(t),u=Math.cos(e),i=n(r*u);return[i*u*Math.sin(t),i*Math.sin(e)]}return e.invert=function(n,e){var r=Math.sqrt(n*n+e*e),u=t(r),i=Math.sin(u),o=Math.cos(u);return[Math.atan2(n*i,r*o),Math.asin(r&&e*i/r)]},e}function _r(n,t){function e(n,t){o>0?-Ra+Ca>t&&(t=-Ra+Ca):t>Ra-Ca&&(t=Ra-Ca);var e=o/Math.pow(u(t),i);return[e*Math.sin(i*n),o-e*Math.cos(i*n)]}var r=Math.cos(n),u=function(n){return Math.tan(qa/4+n/2)},i=n===t?Math.sin(n):Math.log(r/Math.cos(t))/Math.log(u(t)/u(n)),o=r*Math.pow(u(n),i)/i;return i?(e.invert=function(n,t){var e=o-t,r=K(i)*Math.sqrt(n*n+e*e);return[Math.atan2(n,e)/i,2*Math.atan(Math.pow(o/r,1/i))-Ra]},e):Sr}function wr(n,t){function e(n,t){var e=i-t;return[e*Math.sin(u*n),i-e*Math.cos(u*n)]}var r=Math.cos(n),u=n===t?Math.sin(n):(r-Math.cos(t))/(t-n),i=r/u+n;return ga(u)<Ca?ar:(e.invert=function(n,t){var e=i-t;return[Math.atan2(n,e)/u,i-K(u)*Math.sqrt(n*n+e*e)]},e)}function Sr(n,t){return[n,Math.log(Math.tan(qa/4+t/2))]}function kr(n){var t,e=ur(n),r=e.scale,u=e.translate,i=e.clipExtent;return e.scale=function(){var n=r.apply(e,arguments);return n===e?t?e.clipExtent(null):e:n},e.translate=function(){var n=u.apply(e,arguments);return n===e?t?e.clipExtent(null):e:n},e.clipExtent=function(n){var o=i.apply(e,arguments);if(o===e){if(t=null==n){var a=qa*r(),c=u();i([[c[0]-a,c[1]-a],[c[0]+a,c[1]+a]])}}else t&&(o=null);return o},e.clipExtent(null)}function Er(n,t){return[Math.log(Math.tan(qa/4+t/2)),-n]}function Ar(n){return n[0]}function Nr(n){return n[1]}function Cr(n){for(var t=n.length,e=[0,1],r=2,u=2;t>u;u++){for(;r>1&&Q(n[e[r-2]],n[e[r-1]],n[u])<=0;)--r;e[r++]=u}return e.slice(0,r)}function zr(n,t){return n[0]-t[0]||n[1]-t[1]}function qr(n,t,e){return(e[0]-t[0])*(n[1]-t[1])<(e[1]-t[1])*(n[0]-t[0])}function Lr(n,t,e,r){var u=n[0],i=e[0],o=t[0]-u,a=r[0]-i,c=n[1],l=e[1],s=t[1]-c,f=r[1]-l,h=(a*(c-l)-f*(u-i))/(f*o-a*s);return[u+h*o,c+h*s]}function Tr(n){var t=n[0],e=n[n.length-1];return!(t[0]-e[0]||t[1]-e[1])}function Rr(){tu(this),this.edge=this.site=this.circle=null}function Dr(n){var t=el.pop()||new Rr;return t.site=n,t}function Pr(n){Xr(n),Qc.remove(n),el.push(n),tu(n)}function Ur(n){var t=n.circle,e=t.x,r=t.cy,u={x:e,y:r},i=n.P,o=n.N,a=[n];Pr(n);for(var c=i;c.circle&&ga(e-c.circle.x)<Ca&&ga(r-c.circle.cy)<Ca;)i=c.P,a.unshift(c),Pr(c),c=i;a.unshift(c),Xr(c);for(var l=o;l.circle&&ga(e-l.circle.x)<Ca&&ga(r-l.circle.cy)<Ca;)o=l.N,a.push(l),Pr(l),l=o;a.push(l),Xr(l);var s,f=a.length;for(s=1;f>s;++s)l=a[s],c=a[s-1],Kr(l.edge,c.site,l.site,u);c=a[0],l=a[f-1],l.edge=Jr(c.site,l.site,null,u),Vr(c),Vr(l)}function jr(n){for(var t,e,r,u,i=n.x,o=n.y,a=Qc._;a;)if(r=Fr(a,o)-i,r>Ca)a=a.L;else{if(u=i-Hr(a,o),!(u>Ca)){r>-Ca?(t=a.P,e=a):u>-Ca?(t=a,e=a.N):t=e=a;break}if(!a.R){t=a;break}a=a.R}var c=Dr(n);if(Qc.insert(t,c),t||e){if(t===e)return Xr(t),e=Dr(t.site),Qc.insert(c,e),c.edge=e.edge=Jr(t.site,c.site),Vr(t),void Vr(e);if(!e)return void(c.edge=Jr(t.site,c.site));Xr(t),Xr(e);var l=t.site,s=l.x,f=l.y,h=n.x-s,g=n.y-f,p=e.site,v=p.x-s,d=p.y-f,m=2*(h*d-g*v),y=h*h+g*g,M=v*v+d*d,x={x:(d*y-g*M)/m+s,y:(h*M-v*y)/m+f};Kr(e.edge,l,p,x),c.edge=Jr(l,n,null,x),e.edge=Jr(n,p,null,x),Vr(t),Vr(e)}}function Fr(n,t){var e=n.site,r=e.x,u=e.y,i=u-t;if(!i)return r;var o=n.P;if(!o)return-1/0;e=o.site;var a=e.x,c=e.y,l=c-t;if(!l)return a;var s=a-r,f=1/i-1/l,h=s/l;return f?(-h+Math.sqrt(h*h-2*f*(s*s/(-2*l)-c+l/2+u-i/2)))/f+r:(r+a)/2}function Hr(n,t){var e=n.N;if(e)return Fr(e,t);var r=n.site;return r.y===t?r.x:1/0}function Or(n){this.site=n,this.edges=[]}function Ir(n){for(var t,e,r,u,i,o,a,c,l,s,f=n[0][0],h=n[1][0],g=n[0][1],p=n[1][1],v=Kc,d=v.length;d--;)if(i=v[d],i&&i.prepare())for(a=i.edges,c=a.length,o=0;c>o;)s=a[o].end(),r=s.x,u=s.y,l=a[++o%c].start(),t=l.x,e=l.y,(ga(r-t)>Ca||ga(u-e)>Ca)&&(a.splice(o,0,new Qr(Gr(i.site,s,ga(r-f)<Ca&&p-u>Ca?{x:f,y:ga(t-f)<Ca?e:p}:ga(u-p)<Ca&&h-r>Ca?{x:ga(e-p)<Ca?t:h,y:p}:ga(r-h)<Ca&&u-g>Ca?{x:h,y:ga(t-h)<Ca?e:g}:ga(u-g)<Ca&&r-f>Ca?{x:ga(e-g)<Ca?t:f,y:g}:null),i.site,null)),++c)}function Yr(n,t){return t.angle-n.angle}function Zr(){tu(this),this.x=this.y=this.arc=this.site=this.cy=null}function Vr(n){var t=n.P,e=n.N;if(t&&e){var r=t.site,u=n.site,i=e.site;if(r!==i){var o=u.x,a=u.y,c=r.x-o,l=r.y-a,s=i.x-o,f=i.y-a,h=2*(c*f-l*s);if(!(h>=-za)){var g=c*c+l*l,p=s*s+f*f,v=(f*g-l*p)/h,d=(c*p-s*g)/h,f=d+a,m=rl.pop()||new Zr;m.arc=n,m.site=u,m.x=v+o,m.y=f+Math.sqrt(v*v+d*d),m.cy=f,n.circle=m;for(var y=null,M=tl._;M;)if(m.y<M.y||m.y===M.y&&m.x<=M.x){if(!M.L){y=M.P;break}M=M.L}else{if(!M.R){y=M;break}M=M.R}tl.insert(y,m),y||(nl=m)}}}}function Xr(n){var t=n.circle;t&&(t.P||(nl=t.N),tl.remove(t),rl.push(t),tu(t),n.circle=null)}function $r(n){for(var t,e=Gc,r=Oe(n[0][0],n[0][1],n[1][0],n[1][1]),u=e.length;u--;)t=e[u],(!Br(t,n)||!r(t)||ga(t.a.x-t.b.x)<Ca&&ga(t.a.y-t.b.y)<Ca)&&(t.a=t.b=null,e.splice(u,1))}function Br(n,t){var e=n.b;if(e)return!0;var r,u,i=n.a,o=t[0][0],a=t[1][0],c=t[0][1],l=t[1][1],s=n.l,f=n.r,h=s.x,g=s.y,p=f.x,v=f.y,d=(h+p)/2,m=(g+v)/2;if(v===g){if(o>d||d>=a)return;if(h>p){if(i){if(i.y>=l)return}else i={x:d,y:c};e={x:d,y:l}}else{if(i){if(i.y<c)return}else i={x:d,y:l};e={x:d,y:c}}}else if(r=(h-p)/(v-g),u=m-r*d,-1>r||r>1)if(h>p){if(i){if(i.y>=l)return}else i={x:(c-u)/r,y:c};e={x:(l-u)/r,y:l}}else{if(i){if(i.y<c)return}else i={x:(l-u)/r,y:l};e={x:(c-u)/r,y:c}}else if(v>g){if(i){if(i.x>=a)return}else i={x:o,y:r*o+u};e={x:a,y:r*a+u}}else{if(i){if(i.x<o)return}else i={x:a,y:r*a+u};e={x:o,y:r*o+u}}return n.a=i,n.b=e,!0}function Wr(n,t){this.l=n,this.r=t,this.a=this.b=null}function Jr(n,t,e,r){var u=new Wr(n,t);return Gc.push(u),e&&Kr(u,n,t,e),r&&Kr(u,t,n,r),Kc[n.i].edges.push(new Qr(u,n,t)),Kc[t.i].edges.push(new Qr(u,t,n)),u}function Gr(n,t,e){var r=new Wr(n,null);return r.a=t,r.b=e,Gc.push(r),r}function Kr(n,t,e,r){n.a||n.b?n.l===e?n.b=r:n.a=r:(n.a=r,n.l=t,n.r=e)}function Qr(n,t,e){var r=n.a,u=n.b;this.edge=n,this.site=t,this.angle=e?Math.atan2(e.y-t.y,e.x-t.x):n.l===t?Math.atan2(u.x-r.x,r.y-u.y):Math.atan2(r.x-u.x,u.y-r.y)}function nu(){this._=null}function tu(n){n.U=n.C=n.L=n.R=n.P=n.N=null}function eu(n,t){var e=t,r=t.R,u=e.U;u?u.L===e?u.L=r:u.R=r:n._=r,r.U=u,e.U=r,e.R=r.L,e.R&&(e.R.U=e),r.L=e}function ru(n,t){var e=t,r=t.L,u=e.U;u?u.L===e?u.L=r:u.R=r:n._=r,r.U=u,e.U=r,e.L=r.R,e.L&&(e.L.U=e),r.R=e}function uu(n){for(;n.L;)n=n.L;return n}function iu(n,t){var e,r,u,i=n.sort(ou).pop();for(Gc=[],Kc=new Array(n.length),Qc=new nu,tl=new nu;;)if(u=nl,i&&(!u||i.y<u.y||i.y===u.y&&i.x<u.x))(i.x!==e||i.y!==r)&&(Kc[i.i]=new Or(i),jr(i),e=i.x,r=i.y),i=n.pop();else{if(!u)break;Ur(u.arc)}t&&($r(t),Ir(t));var o={cells:Kc,edges:Gc};return Qc=tl=Gc=Kc=null,o}function ou(n,t){return t.y-n.y||t.x-n.x}function au(n,t,e){return(n.x-e.x)*(t.y-n.y)-(n.x-t.x)*(e.y-n.y)}function cu(n){return n.x}function lu(n){return n.y}function su(){return{leaf:!0,nodes:[],point:null,x:null,y:null}}function fu(n,t,e,r,u,i){if(!n(t,e,r,u,i)){var o=.5*(e+u),a=.5*(r+i),c=t.nodes;c[0]&&fu(n,c[0],e,r,o,a),c[1]&&fu(n,c[1],o,r,u,a),c[2]&&fu(n,c[2],e,a,o,i),c[3]&&fu(n,c[3],o,a,u,i)}}function hu(n,t,e,r,u,i,o){var a,c=1/0;return function l(n,s,f,h,g){if(!(s>i||f>o||r>h||u>g)){if(p=n.point){var p,v=t-n.x,d=e-n.y,m=v*v+d*d;if(c>m){var y=Math.sqrt(c=m);r=t-y,u=e-y,i=t+y,o=e+y,a=p}}for(var M=n.nodes,x=.5*(s+h),b=.5*(f+g),_=t>=x,w=e>=b,S=w<<1|_,k=S+4;k>S;++S)if(n=M[3&S])switch(3&S){case 0:l(n,s,f,x,b);break;case 1:l(n,x,f,h,b);break;case 2:l(n,s,b,x,g);break;case 3:l(n,x,b,h,g)}}}(n,r,u,i,o),a}function gu(n,t){n=ta.rgb(n),t=ta.rgb(t);var e=n.r,r=n.g,u=n.b,i=t.r-e,o=t.g-r,a=t.b-u;return function(n){return"#"+xt(Math.round(e+i*n))+xt(Math.round(r+o*n))+xt(Math.round(u+a*n))}}function pu(n,t){var e,r={},u={};for(e in n)e in t?r[e]=mu(n[e],t[e]):u[e]=n[e];for(e in t)e in n||(u[e]=t[e]);return function(n){for(e in r)u[e]=r[e](n);return u}}function vu(n,t){return n=+n,t=+t,function(e){return n*(1-e)+t*e}}function du(n,t){var e,r,u,i=il.lastIndex=ol.lastIndex=0,o=-1,a=[],c=[];for(n+="",t+="";(e=il.exec(n))&&(r=ol.exec(t));)(u=r.index)>i&&(u=t.slice(i,u),a[o]?a[o]+=u:a[++o]=u),(e=e[0])===(r=r[0])?a[o]?a[o]+=r:a[++o]=r:(a[++o]=null,c.push({i:o,x:vu(e,r)})),i=ol.lastIndex;return i<t.length&&(u=t.slice(i),a[o]?a[o]+=u:a[++o]=u),a.length<2?c[0]?(t=c[0].x,function(n){return t(n)+""}):function(){return t}:(t=c.length,function(n){for(var e,r=0;t>r;++r)a[(e=c[r]).i]=e.x(n);return a.join("")})}function mu(n,t){for(var e,r=ta.interpolators.length;--r>=0&&!(e=ta.interpolators[r](n,t)););return e}function yu(n,t){var e,r=[],u=[],i=n.length,o=t.length,a=Math.min(n.length,t.length);for(e=0;a>e;++e)r.push(mu(n[e],t[e]));for(;i>e;++e)u[e]=n[e];for(;o>e;++e)u[e]=t[e];return function(n){for(e=0;a>e;++e)u[e]=r[e](n);return u}}function Mu(n){return function(t){return 0>=t?0:t>=1?1:n(t)}}function xu(n){return function(t){return 1-n(1-t)}}function bu(n){return function(t){return.5*(.5>t?n(2*t):2-n(2-2*t))}}function _u(n){return n*n}function wu(n){return n*n*n}function Su(n){if(0>=n)return 0;if(n>=1)return 1;var t=n*n,e=t*n;return 4*(.5>n?e:3*(n-t)+e-.75)}function ku(n){return function(t){return Math.pow(t,n)}}function Eu(n){return 1-Math.cos(n*Ra)}function Au(n){return Math.pow(2,10*(n-1))}function Nu(n){return 1-Math.sqrt(1-n*n)}function Cu(n,t){var e;return arguments.length<2&&(t=.45),arguments.length?e=t/La*Math.asin(1/n):(n=1,e=t/4),function(r){return 1+n*Math.pow(2,-10*r)*Math.sin((r-e)*La/t)}}function zu(n){return n||(n=1.70158),function(t){return t*t*((n+1)*t-n)}}function qu(n){return 1/2.75>n?7.5625*n*n:2/2.75>n?7.5625*(n-=1.5/2.75)*n+.75:2.5/2.75>n?7.5625*(n-=2.25/2.75)*n+.9375:7.5625*(n-=2.625/2.75)*n+.984375}function Lu(n,t){n=ta.hcl(n),t=ta.hcl(t);var e=n.h,r=n.c,u=n.l,i=t.h-e,o=t.c-r,a=t.l-u;return isNaN(o)&&(o=0,r=isNaN(r)?t.c:r),isNaN(i)?(i=0,e=isNaN(e)?t.h:e):i>180?i-=360:-180>i&&(i+=360),function(n){return st(e+i*n,r+o*n,u+a*n)+""}}function Tu(n,t){n=ta.hsl(n),t=ta.hsl(t);var e=n.h,r=n.s,u=n.l,i=t.h-e,o=t.s-r,a=t.l-u;return isNaN(o)&&(o=0,r=isNaN(r)?t.s:r),isNaN(i)?(i=0,e=isNaN(e)?t.h:e):i>180?i-=360:-180>i&&(i+=360),function(n){return ct(e+i*n,r+o*n,u+a*n)+""}}function Ru(n,t){n=ta.lab(n),t=ta.lab(t);var e=n.l,r=n.a,u=n.b,i=t.l-e,o=t.a-r,a=t.b-u;return function(n){return ht(e+i*n,r+o*n,u+a*n)+""}}function Du(n,t){return t-=n,function(e){return Math.round(n+t*e)}}function Pu(n){var t=[n.a,n.b],e=[n.c,n.d],r=ju(t),u=Uu(t,e),i=ju(Fu(e,t,-u))||0;t[0]*e[1]<e[0]*t[1]&&(t[0]*=-1,t[1]*=-1,r*=-1,u*=-1),this.rotate=(r?Math.atan2(t[1],t[0]):Math.atan2(-e[0],e[1]))*Pa,this.translate=[n.e,n.f],this.scale=[r,i],this.skew=i?Math.atan2(u,i)*Pa:0}function Uu(n,t){return n[0]*t[0]+n[1]*t[1]}function ju(n){var t=Math.sqrt(Uu(n,n));return t&&(n[0]/=t,n[1]/=t),t}function Fu(n,t,e){return n[0]+=e*t[0],n[1]+=e*t[1],n}function Hu(n,t){var e,r=[],u=[],i=ta.transform(n),o=ta.transform(t),a=i.translate,c=o.translate,l=i.rotate,s=o.rotate,f=i.skew,h=o.skew,g=i.scale,p=o.scale;return a[0]!=c[0]||a[1]!=c[1]?(r.push("translate(",null,",",null,")"),u.push({i:1,x:vu(a[0],c[0])},{i:3,x:vu(a[1],c[1])})):r.push(c[0]||c[1]?"translate("+c+")":""),l!=s?(l-s>180?s+=360:s-l>180&&(l+=360),u.push({i:r.push(r.pop()+"rotate(",null,")")-2,x:vu(l,s)})):s&&r.push(r.pop()+"rotate("+s+")"),f!=h?u.push({i:r.push(r.pop()+"skewX(",null,")")-2,x:vu(f,h)}):h&&r.push(r.pop()+"skewX("+h+")"),g[0]!=p[0]||g[1]!=p[1]?(e=r.push(r.pop()+"scale(",null,",",null,")"),u.push({i:e-4,x:vu(g[0],p[0])},{i:e-2,x:vu(g[1],p[1])})):(1!=p[0]||1!=p[1])&&r.push(r.pop()+"scale("+p+")"),e=u.length,function(n){for(var t,i=-1;++i<e;)r[(t=u[i]).i]=t.x(n);return r.join("")}}function Ou(n,t){return t=(t-=n=+n)||1/t,function(e){return(e-n)/t}}function Iu(n,t){return t=(t-=n=+n)||1/t,function(e){return Math.max(0,Math.min(1,(e-n)/t))}}function Yu(n){for(var t=n.source,e=n.target,r=Vu(t,e),u=[t];t!==r;)t=t.parent,u.push(t);for(var i=u.length;e!==r;)u.splice(i,0,e),e=e.parent;return u}function Zu(n){for(var t=[],e=n.parent;null!=e;)t.push(n),n=e,e=e.parent;return t.push(n),t}function Vu(n,t){if(n===t)return n;for(var e=Zu(n),r=Zu(t),u=e.pop(),i=r.pop(),o=null;u===i;)o=u,u=e.pop(),i=r.pop();return o}function Xu(n){n.fixed|=2}function $u(n){n.fixed&=-7}function Bu(n){n.fixed|=4,n.px=n.x,n.py=n.y}function Wu(n){n.fixed&=-5}function Ju(n,t,e){var r=0,u=0;if(n.charge=0,!n.leaf)for(var i,o=n.nodes,a=o.length,c=-1;++c<a;)i=o[c],null!=i&&(Ju(i,t,e),n.charge+=i.charge,r+=i.charge*i.cx,u+=i.charge*i.cy);if(n.point){n.leaf||(n.point.x+=Math.random()-.5,n.point.y+=Math.random()-.5);var l=t*e[n.point.index];n.charge+=n.pointCharge=l,r+=l*n.point.x,u+=l*n.point.y}n.cx=r/n.charge,n.cy=u/n.charge}function Gu(n,t){return ta.rebind(n,t,"sort","children","value"),n.nodes=n,n.links=ri,n}function Ku(n,t){for(var e=[n];null!=(n=e.pop());)if(t(n),(u=n.children)&&(r=u.length))for(var r,u;--r>=0;)e.push(u[r])}function Qu(n,t){for(var e=[n],r=[];null!=(n=e.pop());)if(r.push(n),(i=n.children)&&(u=i.length))for(var u,i,o=-1;++o<u;)e.push(i[o]);for(;null!=(n=r.pop());)t(n)}function ni(n){return n.children}function ti(n){return n.value}function ei(n,t){return t.value-n.value}function ri(n){return ta.merge(n.map(function(n){return(n.children||[]).map(function(t){return{source:n,target:t}})}))}function ui(n){return n.x}function ii(n){return n.y}function oi(n,t,e){n.y0=t,n.y=e}function ai(n){return ta.range(n.length)}function ci(n){for(var t=-1,e=n[0].length,r=[];++t<e;)r[t]=0;return r}function li(n){for(var t,e=1,r=0,u=n[0][1],i=n.length;i>e;++e)(t=n[e][1])>u&&(r=e,u=t);return r}function si(n){return n.reduce(fi,0)}function fi(n,t){return n+t[1]}function hi(n,t){return gi(n,Math.ceil(Math.log(t.length)/Math.LN2+1))}function gi(n,t){for(var e=-1,r=+n[0],u=(n[1]-r)/t,i=[];++e<=t;)i[e]=u*e+r;return i}function pi(n){return[ta.min(n),ta.max(n)]}function vi(n,t){return n.value-t.value}function di(n,t){var e=n._pack_next;n._pack_next=t,t._pack_prev=n,t._pack_next=e,e._pack_prev=t}function mi(n,t){n._pack_next=t,t._pack_prev=n}function yi(n,t){var e=t.x-n.x,r=t.y-n.y,u=n.r+t.r;return.999*u*u>e*e+r*r}function Mi(n){function t(n){s=Math.min(n.x-n.r,s),f=Math.max(n.x+n.r,f),h=Math.min(n.y-n.r,h),g=Math.max(n.y+n.r,g)}if((e=n.children)&&(l=e.length)){var e,r,u,i,o,a,c,l,s=1/0,f=-1/0,h=1/0,g=-1/0;if(e.forEach(xi),r=e[0],r.x=-r.r,r.y=0,t(r),l>1&&(u=e[1],u.x=u.r,u.y=0,t(u),l>2))for(i=e[2],wi(r,u,i),t(i),di(r,i),r._pack_prev=i,di(i,u),u=r._pack_next,o=3;l>o;o++){wi(r,u,i=e[o]);var p=0,v=1,d=1;for(a=u._pack_next;a!==u;a=a._pack_next,v++)if(yi(a,i)){p=1;break}if(1==p)for(c=r._pack_prev;c!==a._pack_prev&&!yi(c,i);c=c._pack_prev,d++);p?(d>v||v==d&&u.r<r.r?mi(r,u=a):mi(r=c,u),o--):(di(r,i),u=i,t(i))}var m=(s+f)/2,y=(h+g)/2,M=0;for(o=0;l>o;o++)i=e[o],i.x-=m,i.y-=y,M=Math.max(M,i.r+Math.sqrt(i.x*i.x+i.y*i.y));n.r=M,e.forEach(bi)}}function xi(n){n._pack_next=n._pack_prev=n}function bi(n){delete n._pack_next,delete n._pack_prev}function _i(n,t,e,r){var u=n.children;if(n.x=t+=r*n.x,n.y=e+=r*n.y,n.r*=r,u)for(var i=-1,o=u.length;++i<o;)_i(u[i],t,e,r)}function wi(n,t,e){var r=n.r+e.r,u=t.x-n.x,i=t.y-n.y;if(r&&(u||i)){var o=t.r+e.r,a=u*u+i*i;o*=o,r*=r;var c=.5+(r-o)/(2*a),l=Math.sqrt(Math.max(0,2*o*(r+a)-(r-=a)*r-o*o))/(2*a);e.x=n.x+c*u+l*i,e.y=n.y+c*i-l*u}else e.x=n.x+r,e.y=n.y}function Si(n,t){return n.parent==t.parent?1:2}function ki(n){var t=n.children;return t.length?t[0]:n.t}function Ei(n){var t,e=n.children;return(t=e.length)?e[t-1]:n.t}function Ai(n,t,e){var r=e/(t.i-n.i);t.c-=r,t.s+=e,n.c+=r,t.z+=e,t.m+=e}function Ni(n){for(var t,e=0,r=0,u=n.children,i=u.length;--i>=0;)t=u[i],t.z+=e,t.m+=e,e+=t.s+(r+=t.c)}function Ci(n,t,e){return n.a.parent===t.parent?n.a:e}function zi(n){return 1+ta.max(n,function(n){return n.y})}function qi(n){return n.reduce(function(n,t){return n+t.x},0)/n.length}function Li(n){var t=n.children;return t&&t.length?Li(t[0]):n}function Ti(n){var t,e=n.children;return e&&(t=e.length)?Ti(e[t-1]):n}function Ri(n){return{x:n.x,y:n.y,dx:n.dx,dy:n.dy}}function Di(n,t){var e=n.x+t[3],r=n.y+t[0],u=n.dx-t[1]-t[3],i=n.dy-t[0]-t[2];return 0>u&&(e+=u/2,u=0),0>i&&(r+=i/2,i=0),{x:e,y:r,dx:u,dy:i}}function Pi(n){var t=n[0],e=n[n.length-1];return e>t?[t,e]:[e,t]}function Ui(n){return n.rangeExtent?n.rangeExtent():Pi(n.range())}function ji(n,t,e,r){var u=e(n[0],n[1]),i=r(t[0],t[1]);return function(n){return i(u(n))}}function Fi(n,t){var e,r=0,u=n.length-1,i=n[r],o=n[u];return i>o&&(e=r,r=u,u=e,e=i,i=o,o=e),n[r]=t.floor(i),n[u]=t.ceil(o),n}function Hi(n){return n?{floor:function(t){return Math.floor(t/n)*n},ceil:function(t){return Math.ceil(t/n)*n}}:ml}function Oi(n,t,e,r){var u=[],i=[],o=0,a=Math.min(n.length,t.length)-1;for(n[a]<n[0]&&(n=n.slice().reverse(),t=t.slice().reverse());++o<=a;)u.push(e(n[o-1],n[o])),i.push(r(t[o-1],t[o]));return function(t){var e=ta.bisect(n,t,1,a)-1;return i[e](u[e](t))}}function Ii(n,t,e,r){function u(){var u=Math.min(n.length,t.length)>2?Oi:ji,c=r?Iu:Ou;return o=u(n,t,c,e),a=u(t,n,c,mu),i}function i(n){return o(n)}var o,a;return i.invert=function(n){return a(n)},i.domain=function(t){return arguments.length?(n=t.map(Number),u()):n},i.range=function(n){return arguments.length?(t=n,u()):t},i.rangeRound=function(n){return i.range(n).interpolate(Du)},i.clamp=function(n){return arguments.length?(r=n,u()):r},i.interpolate=function(n){return arguments.length?(e=n,u()):e},i.ticks=function(t){return Xi(n,t)},i.tickFormat=function(t,e){return $i(n,t,e)},i.nice=function(t){return Zi(n,t),u()},i.copy=function(){return Ii(n,t,e,r)},u()}function Yi(n,t){return ta.rebind(n,t,"range","rangeRound","interpolate","clamp")}function Zi(n,t){return Fi(n,Hi(Vi(n,t)[2]))}function Vi(n,t){null==t&&(t=10);var e=Pi(n),r=e[1]-e[0],u=Math.pow(10,Math.floor(Math.log(r/t)/Math.LN10)),i=t/r*u;return.15>=i?u*=10:.35>=i?u*=5:.75>=i&&(u*=2),e[0]=Math.ceil(e[0]/u)*u,e[1]=Math.floor(e[1]/u)*u+.5*u,e[2]=u,e}function Xi(n,t){return ta.range.apply(ta,Vi(n,t))}function $i(n,t,e){var r=Vi(n,t);if(e){var u=ic.exec(e);if(u.shift(),"s"===u[8]){var i=ta.formatPrefix(Math.max(ga(r[0]),ga(r[1])));return u[7]||(u[7]="."+Bi(i.scale(r[2]))),u[8]="f",e=ta.format(u.join("")),function(n){return e(i.scale(n))+i.symbol}}u[7]||(u[7]="."+Wi(u[8],r)),e=u.join("")}else e=",."+Bi(r[2])+"f";return ta.format(e)}function Bi(n){return-Math.floor(Math.log(n)/Math.LN10+.01)}function Wi(n,t){var e=Bi(t[2]);return n in yl?Math.abs(e-Bi(Math.max(ga(t[0]),ga(t[1]))))+ +("e"!==n):e-2*("%"===n)}function Ji(n,t,e,r){function u(n){return(e?Math.log(0>n?0:n):-Math.log(n>0?0:-n))/Math.log(t)}function i(n){return e?Math.pow(t,n):-Math.pow(t,-n)}function o(t){return n(u(t))}return o.invert=function(t){return i(n.invert(t))},o.domain=function(t){return arguments.length?(e=t[0]>=0,n.domain((r=t.map(Number)).map(u)),o):r},o.base=function(e){return arguments.length?(t=+e,n.domain(r.map(u)),o):t},o.nice=function(){var t=Fi(r.map(u),e?Math:xl);return n.domain(t),r=t.map(i),o},o.ticks=function(){var n=Pi(r),o=[],a=n[0],c=n[1],l=Math.floor(u(a)),s=Math.ceil(u(c)),f=t%1?2:t;if(isFinite(s-l)){if(e){for(;s>l;l++)for(var h=1;f>h;h++)o.push(i(l)*h);o.push(i(l))}else for(o.push(i(l));l++<s;)for(var h=f-1;h>0;h--)o.push(i(l)*h);for(l=0;o[l]<a;l++);for(s=o.length;o[s-1]>c;s--);o=o.slice(l,s)}return o},o.tickFormat=function(n,t){if(!arguments.length)return Ml;arguments.length<2?t=Ml:"function"!=typeof t&&(t=ta.format(t));var r,a=Math.max(.1,n/o.ticks().length),c=e?(r=1e-12,Math.ceil):(r=-1e-12,Math.floor);return function(n){return n/i(c(u(n)+r))<=a?t(n):""}},o.copy=function(){return Ji(n.copy(),t,e,r)},Yi(o,n)}function Gi(n,t,e){function r(t){return n(u(t))}var u=Ki(t),i=Ki(1/t);return r.invert=function(t){return i(n.invert(t))},r.domain=function(t){return arguments.length?(n.domain((e=t.map(Number)).map(u)),r):e},r.ticks=function(n){return Xi(e,n)},r.tickFormat=function(n,t){return $i(e,n,t)},r.nice=function(n){return r.domain(Zi(e,n))},r.exponent=function(o){return arguments.length?(u=Ki(t=o),i=Ki(1/t),n.domain(e.map(u)),r):t},r.copy=function(){return Gi(n.copy(),t,e)},Yi(r,n)}function Ki(n){return function(t){return 0>t?-Math.pow(-t,n):Math.pow(t,n)}}function Qi(n,t){function e(e){return i[((u.get(e)||("range"===t.t?u.set(e,n.push(e)):0/0))-1)%i.length]}function r(t,e){return ta.range(n.length).map(function(n){return t+e*n})}var u,i,o;return e.domain=function(r){if(!arguments.length)return n;n=[],u=new l;for(var i,o=-1,a=r.length;++o<a;)u.has(i=r[o])||u.set(i,n.push(i));return e[t.t].apply(e,t.a)},e.range=function(n){return arguments.length?(i=n,o=0,t={t:"range",a:arguments},e):i},e.rangePoints=function(u,a){arguments.length<2&&(a=0);var c=u[0],l=u[1],s=n.length<2?(c=(c+l)/2,0):(l-c)/(n.length-1+a);return i=r(c+s*a/2,s),o=0,t={t:"rangePoints",a:arguments},e},e.rangeRoundPoints=function(u,a){arguments.length<2&&(a=0);var c=u[0],l=u[1],s=n.length<2?(c=l=Math.round((c+l)/2),0):(l-c)/(n.length-1+a)|0;return i=r(c+Math.round(s*a/2+(l-c-(n.length-1+a)*s)/2),s),o=0,t={t:"rangeRoundPoints",a:arguments},e},e.rangeBands=function(u,a,c){arguments.length<2&&(a=0),arguments.length<3&&(c=a);var l=u[1]<u[0],s=u[l-0],f=u[1-l],h=(f-s)/(n.length-a+2*c);return i=r(s+h*c,h),l&&i.reverse(),o=h*(1-a),t={t:"rangeBands",a:arguments},e},e.rangeRoundBands=function(u,a,c){arguments.length<2&&(a=0),arguments.length<3&&(c=a);var l=u[1]<u[0],s=u[l-0],f=u[1-l],h=Math.floor((f-s)/(n.length-a+2*c));return i=r(s+Math.round((f-s-(n.length-a)*h)/2),h),l&&i.reverse(),o=Math.round(h*(1-a)),t={t:"rangeRoundBands",a:arguments},e},e.rangeBand=function(){return o},e.rangeExtent=function(){return Pi(t.a[0])},e.copy=function(){return Qi(n,t)},e.domain(n)}function no(n,t){function i(){var e=0,r=t.length;for(a=[];++e<r;)a[e-1]=ta.quantile(n,e/r);return o}function o(n){return isNaN(n=+n)?void 0:t[ta.bisect(a,n)]}var a;return o.domain=function(t){return arguments.length?(n=t.map(r).filter(u).sort(e),i()):n},o.range=function(n){return arguments.length?(t=n,i()):t},o.quantiles=function(){return a},o.invertExtent=function(e){return e=t.indexOf(e),0>e?[0/0,0/0]:[e>0?a[e-1]:n[0],e<a.length?a[e]:n[n.length-1]]},o.copy=function(){return no(n,t)},i()}function to(n,t,e){function r(t){return e[Math.max(0,Math.min(o,Math.floor(i*(t-n))))]}function u(){return i=e.length/(t-n),o=e.length-1,r}var i,o;return r.domain=function(e){return arguments.length?(n=+e[0],t=+e[e.length-1],u()):[n,t]},r.range=function(n){return arguments.length?(e=n,u()):e},r.invertExtent=function(t){return t=e.indexOf(t),t=0>t?0/0:t/i+n,[t,t+1/i]},r.copy=function(){return to(n,t,e)},u()}function eo(n,t){function e(e){return e>=e?t[ta.bisect(n,e)]:void 0}return e.domain=function(t){return arguments.length?(n=t,e):n},e.range=function(n){return arguments.length?(t=n,e):t},e.invertExtent=function(e){return e=t.indexOf(e),[n[e-1],n[e]]},e.copy=function(){return eo(n,t)},e}function ro(n){function t(n){return+n}return t.invert=t,t.domain=t.range=function(e){return arguments.length?(n=e.map(t),t):n},t.ticks=function(t){return Xi(n,t)},t.tickFormat=function(t,e){return $i(n,t,e)},t.copy=function(){return ro(n)},t}function uo(){return 0}function io(n){return n.innerRadius}function oo(n){return n.outerRadius}function ao(n){return n.startAngle}function co(n){return n.endAngle}function lo(n){return n&&n.padAngle}function so(n,t,e,r){return(n-e)*t-(t-r)*n>0?0:1}function fo(n,t,e,r,u){var i=n[0]-t[0],o=n[1]-t[1],a=(u?r:-r)/Math.sqrt(i*i+o*o),c=a*o,l=-a*i,s=n[0]+c,f=n[1]+l,h=t[0]+c,g=t[1]+l,p=(s+h)/2,v=(f+g)/2,d=h-s,m=g-f,y=d*d+m*m,M=e-r,x=s*g-h*f,b=(0>m?-1:1)*Math.sqrt(M*M*y-x*x),_=(x*m-d*b)/y,w=(-x*d-m*b)/y,S=(x*m+d*b)/y,k=(-x*d+m*b)/y,E=_-p,A=w-v,N=S-p,C=k-v;return E*E+A*A>N*N+C*C&&(_=S,w=k),[[_-c,w-l],[_*e/M,w*e/M]]}function ho(n){function t(t){function o(){l.push("M",i(n(s),a))}for(var c,l=[],s=[],f=-1,h=t.length,g=Et(e),p=Et(r);++f<h;)u.call(this,c=t[f],f)?s.push([+g.call(this,c,f),+p.call(this,c,f)]):s.length&&(o(),s=[]);return s.length&&o(),l.length?l.join(""):null}var e=Ar,r=Nr,u=Ne,i=go,o=i.key,a=.7;return t.x=function(n){return arguments.length?(e=n,t):e},t.y=function(n){return arguments.length?(r=n,t):r},t.defined=function(n){return arguments.length?(u=n,t):u},t.interpolate=function(n){return arguments.length?(o="function"==typeof n?i=n:(i=El.get(n)||go).key,t):o},t.tension=function(n){return arguments.length?(a=n,t):a},t}function go(n){return n.join("L")}function po(n){return go(n)+"Z"}function vo(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t<e;)u.push("H",(r[0]+(r=n[t])[0])/2,"V",r[1]);return e>1&&u.push("H",r[0]),u.join("")}function mo(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t<e;)u.push("V",(r=n[t])[1],"H",r[0]);return u.join("")}function yo(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t<e;)u.push("H",(r=n[t])[0],"V",r[1]);return u.join("")}function Mo(n,t){return n.length<4?go(n):n[1]+_o(n.slice(1,-1),wo(n,t))}function xo(n,t){return n.length<3?go(n):n[0]+_o((n.push(n[0]),n),wo([n[n.length-2]].concat(n,[n[1]]),t))}function bo(n,t){return n.length<3?go(n):n[0]+_o(n,wo(n,t))}function _o(n,t){if(t.length<1||n.length!=t.length&&n.length!=t.length+2)return go(n);var e=n.length!=t.length,r="",u=n[0],i=n[1],o=t[0],a=o,c=1;if(e&&(r+="Q"+(i[0]-2*o[0]/3)+","+(i[1]-2*o[1]/3)+","+i[0]+","+i[1],u=n[1],c=2),t.length>1){a=t[1],i=n[c],c++,r+="C"+(u[0]+o[0])+","+(u[1]+o[1])+","+(i[0]-a[0])+","+(i[1]-a[1])+","+i[0]+","+i[1];for(var l=2;l<t.length;l++,c++)i=n[c],a=t[l],r+="S"+(i[0]-a[0])+","+(i[1]-a[1])+","+i[0]+","+i[1]}if(e){var s=n[c];r+="Q"+(i[0]+2*a[0]/3)+","+(i[1]+2*a[1]/3)+","+s[0]+","+s[1]}return r}function wo(n,t){for(var e,r=[],u=(1-t)/2,i=n[0],o=n[1],a=1,c=n.length;++a<c;)e=i,i=o,o=n[a],r.push([u*(o[0]-e[0]),u*(o[1]-e[1])]);return r}function So(n){if(n.length<3)return go(n);var t=1,e=n.length,r=n[0],u=r[0],i=r[1],o=[u,u,u,(r=n[1])[0]],a=[i,i,i,r[1]],c=[u,",",i,"L",No(Cl,o),",",No(Cl,a)];for(n.push(n[e-1]);++t<=e;)r=n[t],o.shift(),o.push(r[0]),a.shift(),a.push(r[1]),Co(c,o,a);return n.pop(),c.push("L",r),c.join("")}function ko(n){if(n.length<4)return go(n);for(var t,e=[],r=-1,u=n.length,i=[0],o=[0];++r<3;)t=n[r],i.push(t[0]),o.push(t[1]);for(e.push(No(Cl,i)+","+No(Cl,o)),--r;++r<u;)t=n[r],i.shift(),i.push(t[0]),o.shift(),o.push(t[1]),Co(e,i,o);return e.join("")}function Eo(n){for(var t,e,r=-1,u=n.length,i=u+4,o=[],a=[];++r<4;)e=n[r%u],o.push(e[0]),a.push(e[1]);for(t=[No(Cl,o),",",No(Cl,a)],--r;++r<i;)e=n[r%u],o.shift(),o.push(e[0]),a.shift(),a.push(e[1]),Co(t,o,a);return t.join("")}function Ao(n,t){var e=n.length-1;if(e)for(var r,u,i=n[0][0],o=n[0][1],a=n[e][0]-i,c=n[e][1]-o,l=-1;++l<=e;)r=n[l],u=l/e,r[0]=t*r[0]+(1-t)*(i+u*a),r[1]=t*r[1]+(1-t)*(o+u*c);return So(n)}function No(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]+n[3]*t[3]}function Co(n,t,e){n.push("C",No(Al,t),",",No(Al,e),",",No(Nl,t),",",No(Nl,e),",",No(Cl,t),",",No(Cl,e))}function zo(n,t){return(t[1]-n[1])/(t[0]-n[0])}function qo(n){for(var t=0,e=n.length-1,r=[],u=n[0],i=n[1],o=r[0]=zo(u,i);++t<e;)r[t]=(o+(o=zo(u=i,i=n[t+1])))/2;return r[t]=o,r}function Lo(n){for(var t,e,r,u,i=[],o=qo(n),a=-1,c=n.length-1;++a<c;)t=zo(n[a],n[a+1]),ga(t)<Ca?o[a]=o[a+1]=0:(e=o[a]/t,r=o[a+1]/t,u=e*e+r*r,u>9&&(u=3*t/Math.sqrt(u),o[a]=u*e,o[a+1]=u*r));for(a=-1;++a<=c;)u=(n[Math.min(c,a+1)][0]-n[Math.max(0,a-1)][0])/(6*(1+o[a]*o[a])),i.push([u||0,o[a]*u||0]);return i}function To(n){return n.length<3?go(n):n[0]+_o(n,Lo(n))}function Ro(n){for(var t,e,r,u=-1,i=n.length;++u<i;)t=n[u],e=t[0],r=t[1]-Ra,t[0]=e*Math.cos(r),t[1]=e*Math.sin(r);return n}function Do(n){function t(t){function c(){v.push("M",a(n(m),f),s,l(n(d.reverse()),f),"Z")}for(var h,g,p,v=[],d=[],m=[],y=-1,M=t.length,x=Et(e),b=Et(u),_=e===r?function(){return g}:Et(r),w=u===i?function(){return p}:Et(i);++y<M;)o.call(this,h=t[y],y)?(d.push([g=+x.call(this,h,y),p=+b.call(this,h,y)]),m.push([+_.call(this,h,y),+w.call(this,h,y)])):d.length&&(c(),d=[],m=[]);return d.length&&c(),v.length?v.join(""):null}var e=Ar,r=Ar,u=0,i=Nr,o=Ne,a=go,c=a.key,l=a,s="L",f=.7;return t.x=function(n){return arguments.length?(e=r=n,t):r},t.x0=function(n){return arguments.length?(e=n,t):e},t.x1=function(n){return arguments.length?(r=n,t):r
+},t.y=function(n){return arguments.length?(u=i=n,t):i},t.y0=function(n){return arguments.length?(u=n,t):u},t.y1=function(n){return arguments.length?(i=n,t):i},t.defined=function(n){return arguments.length?(o=n,t):o},t.interpolate=function(n){return arguments.length?(c="function"==typeof n?a=n:(a=El.get(n)||go).key,l=a.reverse||a,s=a.closed?"M":"L",t):c},t.tension=function(n){return arguments.length?(f=n,t):f},t}function Po(n){return n.radius}function Uo(n){return[n.x,n.y]}function jo(n){return function(){var t=n.apply(this,arguments),e=t[0],r=t[1]-Ra;return[e*Math.cos(r),e*Math.sin(r)]}}function Fo(){return 64}function Ho(){return"circle"}function Oo(n){var t=Math.sqrt(n/qa);return"M0,"+t+"A"+t+","+t+" 0 1,1 0,"+-t+"A"+t+","+t+" 0 1,1 0,"+t+"Z"}function Io(n){return function(){var t,e;(t=this[n])&&(e=t[t.active])&&(--t.count?delete t[t.active]:delete this[n],t.active+=.5,e.event&&e.event.interrupt.call(this,this.__data__,e.index))}}function Yo(n,t,e){return ya(n,Pl),n.namespace=t,n.id=e,n}function Zo(n,t,e,r){var u=n.id,i=n.namespace;return Y(n,"function"==typeof e?function(n,o,a){n[i][u].tween.set(t,r(e.call(n,n.__data__,o,a)))}:(e=r(e),function(n){n[i][u].tween.set(t,e)}))}function Vo(n){return null==n&&(n=""),function(){this.textContent=n}}function Xo(n){return null==n?"__transition__":"__transition_"+n+"__"}function $o(n,t,e,r,u){var i=n[e]||(n[e]={active:0,count:0}),o=i[r];if(!o){var a=u.time;o=i[r]={tween:new l,time:a,delay:u.delay,duration:u.duration,ease:u.ease,index:t},u=null,++i.count,ta.timer(function(u){function c(e){if(i.active>r)return s();var u=i[i.active];u&&(--i.count,delete i[i.active],u.event&&u.event.interrupt.call(n,n.__data__,u.index)),i.active=r,o.event&&o.event.start.call(n,n.__data__,t),o.tween.forEach(function(e,r){(r=r.call(n,n.__data__,t))&&v.push(r)}),h=o.ease,f=o.duration,ta.timer(function(){return p.c=l(e||1)?Ne:l,1},0,a)}function l(e){if(i.active!==r)return 1;for(var u=e/f,a=h(u),c=v.length;c>0;)v[--c].call(n,a);return u>=1?(o.event&&o.event.end.call(n,n.__data__,t),s()):void 0}function s(){return--i.count?delete i[r]:delete n[e],1}var f,h,g=o.delay,p=ec,v=[];return p.t=g+a,u>=g?c(u-g):void(p.c=c)},0,a)}}function Bo(n,t,e){n.attr("transform",function(n){var r=t(n);return"translate("+(isFinite(r)?r:e(n))+",0)"})}function Wo(n,t,e){n.attr("transform",function(n){var r=t(n);return"translate(0,"+(isFinite(r)?r:e(n))+")"})}function Jo(n){return n.toISOString()}function Go(n,t,e){function r(t){return n(t)}function u(n,e){var r=n[1]-n[0],u=r/e,i=ta.bisect(Vl,u);return i==Vl.length?[t.year,Vi(n.map(function(n){return n/31536e6}),e)[2]]:i?t[u/Vl[i-1]<Vl[i]/u?i-1:i]:[Bl,Vi(n,e)[2]]}return r.invert=function(t){return Ko(n.invert(t))},r.domain=function(t){return arguments.length?(n.domain(t),r):n.domain().map(Ko)},r.nice=function(n,t){function e(e){return!isNaN(e)&&!n.range(e,Ko(+e+1),t).length}var i=r.domain(),o=Pi(i),a=null==n?u(o,10):"number"==typeof n&&u(o,n);return a&&(n=a[0],t=a[1]),r.domain(Fi(i,t>1?{floor:function(t){for(;e(t=n.floor(t));)t=Ko(t-1);return t},ceil:function(t){for(;e(t=n.ceil(t));)t=Ko(+t+1);return t}}:n))},r.ticks=function(n,t){var e=Pi(r.domain()),i=null==n?u(e,10):"number"==typeof n?u(e,n):!n.range&&[{range:n},t];return i&&(n=i[0],t=i[1]),n.range(e[0],Ko(+e[1]+1),1>t?1:t)},r.tickFormat=function(){return e},r.copy=function(){return Go(n.copy(),t,e)},Yi(r,n)}function Ko(n){return new Date(n)}function Qo(n){return JSON.parse(n.responseText)}function na(n){var t=ua.createRange();return t.selectNode(ua.body),t.createContextualFragment(n.responseText)}var ta={version:"3.5.6"},ea=[].slice,ra=function(n){return ea.call(n)},ua=this.document;if(ua)try{ra(ua.documentElement.childNodes)[0].nodeType}catch(ia){ra=function(n){for(var t=n.length,e=new Array(t);t--;)e[t]=n[t];return e}}if(Date.now||(Date.now=function(){return+new Date}),ua)try{ua.createElement("DIV").style.setProperty("opacity",0,"")}catch(oa){var aa=this.Element.prototype,ca=aa.setAttribute,la=aa.setAttributeNS,sa=this.CSSStyleDeclaration.prototype,fa=sa.setProperty;aa.setAttribute=function(n,t){ca.call(this,n,t+"")},aa.setAttributeNS=function(n,t,e){la.call(this,n,t,e+"")},sa.setProperty=function(n,t,e){fa.call(this,n,t+"",e)}}ta.ascending=e,ta.descending=function(n,t){return n>t?-1:t>n?1:t>=n?0:0/0},ta.min=function(n,t){var e,r,u=-1,i=n.length;if(1===arguments.length){for(;++u<i;)if(null!=(r=n[u])&&r>=r){e=r;break}for(;++u<i;)null!=(r=n[u])&&e>r&&(e=r)}else{for(;++u<i;)if(null!=(r=t.call(n,n[u],u))&&r>=r){e=r;break}for(;++u<i;)null!=(r=t.call(n,n[u],u))&&e>r&&(e=r)}return e},ta.max=function(n,t){var e,r,u=-1,i=n.length;if(1===arguments.length){for(;++u<i;)if(null!=(r=n[u])&&r>=r){e=r;break}for(;++u<i;)null!=(r=n[u])&&r>e&&(e=r)}else{for(;++u<i;)if(null!=(r=t.call(n,n[u],u))&&r>=r){e=r;break}for(;++u<i;)null!=(r=t.call(n,n[u],u))&&r>e&&(e=r)}return e},ta.extent=function(n,t){var e,r,u,i=-1,o=n.length;if(1===arguments.length){for(;++i<o;)if(null!=(r=n[i])&&r>=r){e=u=r;break}for(;++i<o;)null!=(r=n[i])&&(e>r&&(e=r),r>u&&(u=r))}else{for(;++i<o;)if(null!=(r=t.call(n,n[i],i))&&r>=r){e=u=r;break}for(;++i<o;)null!=(r=t.call(n,n[i],i))&&(e>r&&(e=r),r>u&&(u=r))}return[e,u]},ta.sum=function(n,t){var e,r=0,i=n.length,o=-1;if(1===arguments.length)for(;++o<i;)u(e=+n[o])&&(r+=e);else for(;++o<i;)u(e=+t.call(n,n[o],o))&&(r+=e);return r},ta.mean=function(n,t){var e,i=0,o=n.length,a=-1,c=o;if(1===arguments.length)for(;++a<o;)u(e=r(n[a]))?i+=e:--c;else for(;++a<o;)u(e=r(t.call(n,n[a],a)))?i+=e:--c;return c?i/c:void 0},ta.quantile=function(n,t){var e=(n.length-1)*t+1,r=Math.floor(e),u=+n[r-1],i=e-r;return i?u+i*(n[r]-u):u},ta.median=function(n,t){var i,o=[],a=n.length,c=-1;if(1===arguments.length)for(;++c<a;)u(i=r(n[c]))&&o.push(i);else for(;++c<a;)u(i=r(t.call(n,n[c],c)))&&o.push(i);return o.length?ta.quantile(o.sort(e),.5):void 0},ta.variance=function(n,t){var e,i,o=n.length,a=0,c=0,l=-1,s=0;if(1===arguments.length)for(;++l<o;)u(e=r(n[l]))&&(i=e-a,a+=i/++s,c+=i*(e-a));else for(;++l<o;)u(e=r(t.call(n,n[l],l)))&&(i=e-a,a+=i/++s,c+=i*(e-a));return s>1?c/(s-1):void 0},ta.deviation=function(){var n=ta.variance.apply(this,arguments);return n?Math.sqrt(n):n};var ha=i(e);ta.bisectLeft=ha.left,ta.bisect=ta.bisectRight=ha.right,ta.bisector=function(n){return i(1===n.length?function(t,r){return e(n(t),r)}:n)},ta.shuffle=function(n,t,e){(i=arguments.length)<3&&(e=n.length,2>i&&(t=0));for(var r,u,i=e-t;i;)u=Math.random()*i--|0,r=n[i+t],n[i+t]=n[u+t],n[u+t]=r;return n},ta.permute=function(n,t){for(var e=t.length,r=new Array(e);e--;)r[e]=n[t[e]];return r},ta.pairs=function(n){for(var t,e=0,r=n.length-1,u=n[0],i=new Array(0>r?0:r);r>e;)i[e]=[t=u,u=n[++e]];return i},ta.zip=function(){if(!(r=arguments.length))return[];for(var n=-1,t=ta.min(arguments,o),e=new Array(t);++n<t;)for(var r,u=-1,i=e[n]=new Array(r);++u<r;)i[u]=arguments[u][n];return e},ta.transpose=function(n){return ta.zip.apply(ta,n)},ta.keys=function(n){var t=[];for(var e in n)t.push(e);return t},ta.values=function(n){var t=[];for(var e in n)t.push(n[e]);return t},ta.entries=function(n){var t=[];for(var e in n)t.push({key:e,value:n[e]});return t},ta.merge=function(n){for(var t,e,r,u=n.length,i=-1,o=0;++i<u;)o+=n[i].length;for(e=new Array(o);--u>=0;)for(r=n[u],t=r.length;--t>=0;)e[--o]=r[t];return e};var ga=Math.abs;ta.range=function(n,t,e){if(arguments.length<3&&(e=1,arguments.length<2&&(t=n,n=0)),(t-n)/e===1/0)throw new Error("infinite range");var r,u=[],i=a(ga(e)),o=-1;if(n*=i,t*=i,e*=i,0>e)for(;(r=n+e*++o)>t;)u.push(r/i);else for(;(r=n+e*++o)<t;)u.push(r/i);return u},ta.map=function(n,t){var e=new l;if(n instanceof l)n.forEach(function(n,t){e.set(n,t)});else if(Array.isArray(n)){var r,u=-1,i=n.length;if(1===arguments.length)for(;++u<i;)e.set(u,n[u]);else for(;++u<i;)e.set(t.call(n,r=n[u],u),r)}else for(var o in n)e.set(o,n[o]);return e};var pa="__proto__",va="\x00";c(l,{has:h,get:function(n){return this._[s(n)]},set:function(n,t){return this._[s(n)]=t},remove:g,keys:p,values:function(){var n=[];for(var t in this._)n.push(this._[t]);return n},entries:function(){var n=[];for(var t in this._)n.push({key:f(t),value:this._[t]});return n},size:v,empty:d,forEach:function(n){for(var t in this._)n.call(this,f(t),this._[t])}}),ta.nest=function(){function n(t,o,a){if(a>=i.length)return r?r.call(u,o):e?o.sort(e):o;for(var c,s,f,h,g=-1,p=o.length,v=i[a++],d=new l;++g<p;)(h=d.get(c=v(s=o[g])))?h.push(s):d.set(c,[s]);return t?(s=t(),f=function(e,r){s.set(e,n(t,r,a))}):(s={},f=function(e,r){s[e]=n(t,r,a)}),d.forEach(f),s}function t(n,e){if(e>=i.length)return n;var r=[],u=o[e++];return n.forEach(function(n,u){r.push({key:n,values:t(u,e)})}),u?r.sort(function(n,t){return u(n.key,t.key)}):r}var e,r,u={},i=[],o=[];return u.map=function(t,e){return n(e,t,0)},u.entries=function(e){return t(n(ta.map,e,0),0)},u.key=function(n){return i.push(n),u},u.sortKeys=function(n){return o[i.length-1]=n,u},u.sortValues=function(n){return e=n,u},u.rollup=function(n){return r=n,u},u},ta.set=function(n){var t=new m;if(n)for(var e=0,r=n.length;r>e;++e)t.add(n[e]);return t},c(m,{has:h,add:function(n){return this._[s(n+="")]=!0,n},remove:g,values:p,size:v,empty:d,forEach:function(n){for(var t in this._)n.call(this,f(t))}}),ta.behavior={},ta.rebind=function(n,t){for(var e,r=1,u=arguments.length;++r<u;)n[e=arguments[r]]=M(n,t,t[e]);return n};var da=["webkit","ms","moz","Moz","o","O"];ta.dispatch=function(){for(var n=new _,t=-1,e=arguments.length;++t<e;)n[arguments[t]]=w(n);return n},_.prototype.on=function(n,t){var e=n.indexOf("."),r="";if(e>=0&&(r=n.slice(e+1),n=n.slice(0,e)),n)return arguments.length<2?this[n].on(r):this[n].on(r,t);if(2===arguments.length){if(null==t)for(n in this)this.hasOwnProperty(n)&&this[n].on(r,null);return this}},ta.event=null,ta.requote=function(n){return n.replace(ma,"\\$&")};var ma=/[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g,ya={}.__proto__?function(n,t){n.__proto__=t}:function(n,t){for(var e in t)n[e]=t[e]},Ma=function(n,t){return t.querySelector(n)},xa=function(n,t){return t.querySelectorAll(n)},ba=function(n,t){var e=n.matches||n[x(n,"matchesSelector")];return(ba=function(n,t){return e.call(n,t)})(n,t)};"function"==typeof Sizzle&&(Ma=function(n,t){return Sizzle(n,t)[0]||null},xa=Sizzle,ba=Sizzle.matchesSelector),ta.selection=function(){return ta.select(ua.documentElement)};var _a=ta.selection.prototype=[];_a.select=function(n){var t,e,r,u,i=[];n=N(n);for(var o=-1,a=this.length;++o<a;){i.push(t=[]),t.parentNode=(r=this[o]).parentNode;for(var c=-1,l=r.length;++c<l;)(u=r[c])?(t.push(e=n.call(u,u.__data__,c,o)),e&&"__data__"in u&&(e.__data__=u.__data__)):t.push(null)}return A(i)},_a.selectAll=function(n){var t,e,r=[];n=C(n);for(var u=-1,i=this.length;++u<i;)for(var o=this[u],a=-1,c=o.length;++a<c;)(e=o[a])&&(r.push(t=ra(n.call(e,e.__data__,a,u))),t.parentNode=e);return A(r)};var wa={svg:"http://www.w3.org/2000/svg",xhtml:"http://www.w3.org/1999/xhtml",xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"};ta.ns={prefix:wa,qualify:function(n){var t=n.indexOf(":"),e=n;return t>=0&&(e=n.slice(0,t),n=n.slice(t+1)),wa.hasOwnProperty(e)?{space:wa[e],local:n}:n}},_a.attr=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node();return n=ta.ns.qualify(n),n.local?e.getAttributeNS(n.space,n.local):e.getAttribute(n)}for(t in n)this.each(z(t,n[t]));return this}return this.each(z(n,t))},_a.classed=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node(),r=(n=T(n)).length,u=-1;if(t=e.classList){for(;++u<r;)if(!t.contains(n[u]))return!1}else for(t=e.getAttribute("class");++u<r;)if(!L(n[u]).test(t))return!1;return!0}for(t in n)this.each(R(t,n[t]));return this}return this.each(R(n,t))},_a.style=function(n,e,r){var u=arguments.length;if(3>u){if("string"!=typeof n){2>u&&(e="");for(r in n)this.each(P(r,n[r],e));return this}if(2>u){var i=this.node();return t(i).getComputedStyle(i,null).getPropertyValue(n)}r=""}return this.each(P(n,e,r))},_a.property=function(n,t){if(arguments.length<2){if("string"==typeof n)return this.node()[n];for(t in n)this.each(U(t,n[t]));return this}return this.each(U(n,t))},_a.text=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.textContent=null==t?"":t}:null==n?function(){this.textContent=""}:function(){this.textContent=n}):this.node().textContent},_a.html=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.innerHTML=null==t?"":t}:null==n?function(){this.innerHTML=""}:function(){this.innerHTML=n}):this.node().innerHTML},_a.append=function(n){return n=j(n),this.select(function(){return this.appendChild(n.apply(this,arguments))})},_a.insert=function(n,t){return n=j(n),t=N(t),this.select(function(){return this.insertBefore(n.apply(this,arguments),t.apply(this,arguments)||null)})},_a.remove=function(){return this.each(F)},_a.data=function(n,t){function e(n,e){var r,u,i,o=n.length,f=e.length,h=Math.min(o,f),g=new Array(f),p=new Array(f),v=new Array(o);if(t){var d,m=new l,y=new Array(o);for(r=-1;++r<o;)m.has(d=t.call(u=n[r],u.__data__,r))?v[r]=u:m.set(d,u),y[r]=d;for(r=-1;++r<f;)(u=m.get(d=t.call(e,i=e[r],r)))?u!==!0&&(g[r]=u,u.__data__=i):p[r]=H(i),m.set(d,!0);for(r=-1;++r<o;)m.get(y[r])!==!0&&(v[r]=n[r])}else{for(r=-1;++r<h;)u=n[r],i=e[r],u?(u.__data__=i,g[r]=u):p[r]=H(i);for(;f>r;++r)p[r]=H(e[r]);for(;o>r;++r)v[r]=n[r]}p.update=g,p.parentNode=g.parentNode=v.parentNode=n.parentNode,a.push(p),c.push(g),s.push(v)}var r,u,i=-1,o=this.length;if(!arguments.length){for(n=new Array(o=(r=this[0]).length);++i<o;)(u=r[i])&&(n[i]=u.__data__);return n}var a=Z([]),c=A([]),s=A([]);if("function"==typeof n)for(;++i<o;)e(r=this[i],n.call(r,r.parentNode.__data__,i));else for(;++i<o;)e(r=this[i],n);return c.enter=function(){return a},c.exit=function(){return s},c},_a.datum=function(n){return arguments.length?this.property("__data__",n):this.property("__data__")},_a.filter=function(n){var t,e,r,u=[];"function"!=typeof n&&(n=O(n));for(var i=0,o=this.length;o>i;i++){u.push(t=[]),t.parentNode=(e=this[i]).parentNode;for(var a=0,c=e.length;c>a;a++)(r=e[a])&&n.call(r,r.__data__,a,i)&&t.push(r)}return A(u)},_a.order=function(){for(var n=-1,t=this.length;++n<t;)for(var e,r=this[n],u=r.length-1,i=r[u];--u>=0;)(e=r[u])&&(i&&i!==e.nextSibling&&i.parentNode.insertBefore(e,i),i=e);return this},_a.sort=function(n){n=I.apply(this,arguments);for(var t=-1,e=this.length;++t<e;)this[t].sort(n);return this.order()},_a.each=function(n){return Y(this,function(t,e,r){n.call(t,t.__data__,e,r)})},_a.call=function(n){var t=ra(arguments);return n.apply(t[0]=this,t),this},_a.empty=function(){return!this.node()},_a.node=function(){for(var n=0,t=this.length;t>n;n++)for(var e=this[n],r=0,u=e.length;u>r;r++){var i=e[r];if(i)return i}return null},_a.size=function(){var n=0;return Y(this,function(){++n}),n};var Sa=[];ta.selection.enter=Z,ta.selection.enter.prototype=Sa,Sa.append=_a.append,Sa.empty=_a.empty,Sa.node=_a.node,Sa.call=_a.call,Sa.size=_a.size,Sa.select=function(n){for(var t,e,r,u,i,o=[],a=-1,c=this.length;++a<c;){r=(u=this[a]).update,o.push(t=[]),t.parentNode=u.parentNode;for(var l=-1,s=u.length;++l<s;)(i=u[l])?(t.push(r[l]=e=n.call(u.parentNode,i.__data__,l,a)),e.__data__=i.__data__):t.push(null)}return A(o)},Sa.insert=function(n,t){return arguments.length<2&&(t=V(this)),_a.insert.call(this,n,t)},ta.select=function(t){var e;return"string"==typeof t?(e=[Ma(t,ua)],e.parentNode=ua.documentElement):(e=[t],e.parentNode=n(t)),A([e])},ta.selectAll=function(n){var t;return"string"==typeof n?(t=ra(xa(n,ua)),t.parentNode=ua.documentElement):(t=n,t.parentNode=null),A([t])},_a.on=function(n,t,e){var r=arguments.length;if(3>r){if("string"!=typeof n){2>r&&(t=!1);for(e in n)this.each(X(e,n[e],t));return this}if(2>r)return(r=this.node()["__on"+n])&&r._;e=!1}return this.each(X(n,t,e))};var ka=ta.map({mouseenter:"mouseover",mouseleave:"mouseout"});ua&&ka.forEach(function(n){"on"+n in ua&&ka.remove(n)});var Ea,Aa=0;ta.mouse=function(n){return J(n,k())};var Na=this.navigator&&/WebKit/.test(this.navigator.userAgent)?-1:0;ta.touch=function(n,t,e){if(arguments.length<3&&(e=t,t=k().changedTouches),t)for(var r,u=0,i=t.length;i>u;++u)if((r=t[u]).identifier===e)return J(n,r)},ta.behavior.drag=function(){function n(){this.on("mousedown.drag",i).on("touchstart.drag",o)}function e(n,t,e,i,o){return function(){function a(){var n,e,r=t(h,v);r&&(n=r[0]-M[0],e=r[1]-M[1],p|=n|e,M=r,g({type:"drag",x:r[0]+l[0],y:r[1]+l[1],dx:n,dy:e}))}function c(){t(h,v)&&(m.on(i+d,null).on(o+d,null),y(p&&ta.event.target===f),g({type:"dragend"}))}var l,s=this,f=ta.event.target,h=s.parentNode,g=r.of(s,arguments),p=0,v=n(),d=".drag"+(null==v?"":"-"+v),m=ta.select(e(f)).on(i+d,a).on(o+d,c),y=W(f),M=t(h,v);u?(l=u.apply(s,arguments),l=[l.x-M[0],l.y-M[1]]):l=[0,0],g({type:"dragstart"})}}var r=E(n,"drag","dragstart","dragend"),u=null,i=e(b,ta.mouse,t,"mousemove","mouseup"),o=e(G,ta.touch,y,"touchmove","touchend");return n.origin=function(t){return arguments.length?(u=t,n):u},ta.rebind(n,r,"on")},ta.touches=function(n,t){return arguments.length<2&&(t=k().touches),t?ra(t).map(function(t){var e=J(n,t);return e.identifier=t.identifier,e}):[]};var Ca=1e-6,za=Ca*Ca,qa=Math.PI,La=2*qa,Ta=La-Ca,Ra=qa/2,Da=qa/180,Pa=180/qa,Ua=Math.SQRT2,ja=2,Fa=4;ta.interpolateZoom=function(n,t){function e(n){var t=n*y;if(m){var e=rt(v),o=i/(ja*h)*(e*ut(Ua*t+v)-et(v));return[r+o*l,u+o*s,i*e/rt(Ua*t+v)]}return[r+n*l,u+n*s,i*Math.exp(Ua*t)]}var r=n[0],u=n[1],i=n[2],o=t[0],a=t[1],c=t[2],l=o-r,s=a-u,f=l*l+s*s,h=Math.sqrt(f),g=(c*c-i*i+Fa*f)/(2*i*ja*h),p=(c*c-i*i-Fa*f)/(2*c*ja*h),v=Math.log(Math.sqrt(g*g+1)-g),d=Math.log(Math.sqrt(p*p+1)-p),m=d-v,y=(m||Math.log(c/i))/Ua;return e.duration=1e3*y,e},ta.behavior.zoom=function(){function n(n){n.on(q,f).on(Oa+".zoom",g).on("dblclick.zoom",p).on(R,h)}function e(n){return[(n[0]-k.x)/k.k,(n[1]-k.y)/k.k]}function r(n){return[n[0]*k.k+k.x,n[1]*k.k+k.y]}function u(n){k.k=Math.max(N[0],Math.min(N[1],n))}function i(n,t){t=r(t),k.x+=n[0]-t[0],k.y+=n[1]-t[1]}function o(t,e,r,o){t.__chart__={x:k.x,y:k.y,k:k.k},u(Math.pow(2,o)),i(d=e,r),t=ta.select(t),C>0&&(t=t.transition().duration(C)),t.call(n.event)}function a(){b&&b.domain(x.range().map(function(n){return(n-k.x)/k.k}).map(x.invert)),w&&w.domain(_.range().map(function(n){return(n-k.y)/k.k}).map(_.invert))}function c(n){z++||n({type:"zoomstart"})}function l(n){a(),n({type:"zoom",scale:k.k,translate:[k.x,k.y]})}function s(n){--z||(n({type:"zoomend"}),d=null)}function f(){function n(){f=1,i(ta.mouse(u),g),l(a)}function r(){h.on(L,null).on(T,null),p(f&&ta.event.target===o),s(a)}var u=this,o=ta.event.target,a=D.of(u,arguments),f=0,h=ta.select(t(u)).on(L,n).on(T,r),g=e(ta.mouse(u)),p=W(u);Dl.call(u),c(a)}function h(){function n(){var n=ta.touches(p);return g=k.k,n.forEach(function(n){n.identifier in d&&(d[n.identifier]=e(n))}),n}function t(){var t=ta.event.target;ta.select(t).on(x,r).on(b,a),_.push(t);for(var e=ta.event.changedTouches,u=0,i=e.length;i>u;++u)d[e[u].identifier]=null;var c=n(),l=Date.now();if(1===c.length){if(500>l-M){var s=c[0];o(p,s,d[s.identifier],Math.floor(Math.log(k.k)/Math.LN2)+1),S()}M=l}else if(c.length>1){var s=c[0],f=c[1],h=s[0]-f[0],g=s[1]-f[1];m=h*h+g*g}}function r(){var n,t,e,r,o=ta.touches(p);Dl.call(p);for(var a=0,c=o.length;c>a;++a,r=null)if(e=o[a],r=d[e.identifier]){if(t)break;n=e,t=r}if(r){var s=(s=e[0]-n[0])*s+(s=e[1]-n[1])*s,f=m&&Math.sqrt(s/m);n=[(n[0]+e[0])/2,(n[1]+e[1])/2],t=[(t[0]+r[0])/2,(t[1]+r[1])/2],u(f*g)}M=null,i(n,t),l(v)}function a(){if(ta.event.touches.length){for(var t=ta.event.changedTouches,e=0,r=t.length;r>e;++e)delete d[t[e].identifier];for(var u in d)return void n()}ta.selectAll(_).on(y,null),w.on(q,f).on(R,h),E(),s(v)}var g,p=this,v=D.of(p,arguments),d={},m=0,y=".zoom-"+ta.event.changedTouches[0].identifier,x="touchmove"+y,b="touchend"+y,_=[],w=ta.select(p),E=W(p);t(),c(v),w.on(q,null).on(R,t)}function g(){var n=D.of(this,arguments);y?clearTimeout(y):(Dl.call(this),v=e(d=m||ta.mouse(this)),c(n)),y=setTimeout(function(){y=null,s(n)},50),S(),u(Math.pow(2,.002*Ha())*k.k),i(d,v),l(n)}function p(){var n=ta.mouse(this),t=Math.log(k.k)/Math.LN2;o(this,n,e(n),ta.event.shiftKey?Math.ceil(t)-1:Math.floor(t)+1)}var v,d,m,y,M,x,b,_,w,k={x:0,y:0,k:1},A=[960,500],N=Ia,C=250,z=0,q="mousedown.zoom",L="mousemove.zoom",T="mouseup.zoom",R="touchstart.zoom",D=E(n,"zoomstart","zoom","zoomend");return Oa||(Oa="onwheel"in ua?(Ha=function(){return-ta.event.deltaY*(ta.event.deltaMode?120:1)},"wheel"):"onmousewheel"in ua?(Ha=function(){return ta.event.wheelDelta},"mousewheel"):(Ha=function(){return-ta.event.detail},"MozMousePixelScroll")),n.event=function(n){n.each(function(){var n=D.of(this,arguments),t=k;Tl?ta.select(this).transition().each("start.zoom",function(){k=this.__chart__||{x:0,y:0,k:1},c(n)}).tween("zoom:zoom",function(){var e=A[0],r=A[1],u=d?d[0]:e/2,i=d?d[1]:r/2,o=ta.interpolateZoom([(u-k.x)/k.k,(i-k.y)/k.k,e/k.k],[(u-t.x)/t.k,(i-t.y)/t.k,e/t.k]);return function(t){var r=o(t),a=e/r[2];this.__chart__=k={x:u-r[0]*a,y:i-r[1]*a,k:a},l(n)}}).each("interrupt.zoom",function(){s(n)}).each("end.zoom",function(){s(n)}):(this.__chart__=k,c(n),l(n),s(n))})},n.translate=function(t){return arguments.length?(k={x:+t[0],y:+t[1],k:k.k},a(),n):[k.x,k.y]},n.scale=function(t){return arguments.length?(k={x:k.x,y:k.y,k:+t},a(),n):k.k},n.scaleExtent=function(t){return arguments.length?(N=null==t?Ia:[+t[0],+t[1]],n):N},n.center=function(t){return arguments.length?(m=t&&[+t[0],+t[1]],n):m},n.size=function(t){return arguments.length?(A=t&&[+t[0],+t[1]],n):A},n.duration=function(t){return arguments.length?(C=+t,n):C},n.x=function(t){return arguments.length?(b=t,x=t.copy(),k={x:0,y:0,k:1},n):b},n.y=function(t){return arguments.length?(w=t,_=t.copy(),k={x:0,y:0,k:1},n):w},ta.rebind(n,D,"on")};var Ha,Oa,Ia=[0,1/0];ta.color=ot,ot.prototype.toString=function(){return this.rgb()+""},ta.hsl=at;var Ya=at.prototype=new ot;Ya.brighter=function(n){return n=Math.pow(.7,arguments.length?n:1),new at(this.h,this.s,this.l/n)},Ya.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),new at(this.h,this.s,n*this.l)},Ya.rgb=function(){return ct(this.h,this.s,this.l)},ta.hcl=lt;var Za=lt.prototype=new ot;Za.brighter=function(n){return new lt(this.h,this.c,Math.min(100,this.l+Va*(arguments.length?n:1)))},Za.darker=function(n){return new lt(this.h,this.c,Math.max(0,this.l-Va*(arguments.length?n:1)))},Za.rgb=function(){return st(this.h,this.c,this.l).rgb()},ta.lab=ft;var Va=18,Xa=.95047,$a=1,Ba=1.08883,Wa=ft.prototype=new ot;Wa.brighter=function(n){return new ft(Math.min(100,this.l+Va*(arguments.length?n:1)),this.a,this.b)},Wa.darker=function(n){return new ft(Math.max(0,this.l-Va*(arguments.length?n:1)),this.a,this.b)},Wa.rgb=function(){return ht(this.l,this.a,this.b)},ta.rgb=mt;var Ja=mt.prototype=new ot;Ja.brighter=function(n){n=Math.pow(.7,arguments.length?n:1);var t=this.r,e=this.g,r=this.b,u=30;return t||e||r?(t&&u>t&&(t=u),e&&u>e&&(e=u),r&&u>r&&(r=u),new mt(Math.min(255,t/n),Math.min(255,e/n),Math.min(255,r/n))):new mt(u,u,u)},Ja.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),new mt(n*this.r,n*this.g,n*this.b)},Ja.hsl=function(){return _t(this.r,this.g,this.b)},Ja.toString=function(){return"#"+xt(this.r)+xt(this.g)+xt(this.b)};var Ga=ta.map({aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,rebeccapurple:6697881,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074});Ga.forEach(function(n,t){Ga.set(n,yt(t))}),ta.functor=Et,ta.xhr=At(y),ta.dsv=function(n,t){function e(n,e,i){arguments.length<3&&(i=e,e=null);var o=Nt(n,t,null==e?r:u(e),i);return o.row=function(n){return arguments.length?o.response(null==(e=n)?r:u(n)):e},o}function r(n){return e.parse(n.responseText)}function u(n){return function(t){return e.parse(t.responseText,n)}}function i(t){return t.map(o).join(n)}function o(n){return a.test(n)?'"'+n.replace(/\"/g,'""')+'"':n}var a=new RegExp('["'+n+"\n]"),c=n.charCodeAt(0);return e.parse=function(n,t){var r;return e.parseRows(n,function(n,e){if(r)return r(n,e-1);var u=new Function("d","return {"+n.map(function(n,t){return JSON.stringify(n)+": d["+t+"]"}).join(",")+"}");r=t?function(n,e){return t(u(n),e)}:u})},e.parseRows=function(n,t){function e(){if(s>=l)return o;if(u)return u=!1,i;var t=s;if(34===n.charCodeAt(t)){for(var e=t;e++<l;)if(34===n.charCodeAt(e)){if(34!==n.charCodeAt(e+1))break;++e}s=e+2;var r=n.charCodeAt(e+1);return 13===r?(u=!0,10===n.charCodeAt(e+2)&&++s):10===r&&(u=!0),n.slice(t+1,e).replace(/""/g,'"')}for(;l>s;){var r=n.charCodeAt(s++),a=1;if(10===r)u=!0;else if(13===r)u=!0,10===n.charCodeAt(s)&&(++s,++a);else if(r!==c)continue;return n.slice(t,s-a)}return n.slice(t)}for(var r,u,i={},o={},a=[],l=n.length,s=0,f=0;(r=e())!==o;){for(var h=[];r!==i&&r!==o;)h.push(r),r=e();t&&null==(h=t(h,f++))||a.push(h)}return a},e.format=function(t){if(Array.isArray(t[0]))return e.formatRows(t);var r=new m,u=[];return t.forEach(function(n){for(var t in n)r.has(t)||u.push(r.add(t))}),[u.map(o).join(n)].concat(t.map(function(t){return u.map(function(n){return o(t[n])}).join(n)})).join("\n")},e.formatRows=function(n){return n.map(i).join("\n")},e},ta.csv=ta.dsv(",","text/csv"),ta.tsv=ta.dsv(" ","text/tab-separated-values");var Ka,Qa,nc,tc,ec,rc=this[x(this,"requestAnimationFrame")]||function(n){setTimeout(n,17)};ta.timer=function(n,t,e){var r=arguments.length;2>r&&(t=0),3>r&&(e=Date.now());var u=e+t,i={c:n,t:u,f:!1,n:null};Qa?Qa.n=i:Ka=i,Qa=i,nc||(tc=clearTimeout(tc),nc=1,rc(qt))},ta.timer.flush=function(){Lt(),Tt()},ta.round=function(n,t){return t?Math.round(n*(t=Math.pow(10,t)))/t:Math.round(n)};var uc=["y","z","a","f","p","n","\xb5","m","","k","M","G","T","P","E","Z","Y"].map(Dt);ta.formatPrefix=function(n,t){var e=0;return n&&(0>n&&(n*=-1),t&&(n=ta.round(n,Rt(n,t))),e=1+Math.floor(1e-12+Math.log(n)/Math.LN10),e=Math.max(-24,Math.min(24,3*Math.floor((e-1)/3)))),uc[8+e/3]};var ic=/(?:([^{])?([<>=^]))?([+\- ])?([$#])?(0)?(\d+)?(,)?(\.-?\d+)?([a-z%])?/i,oc=ta.map({b:function(n){return n.toString(2)},c:function(n){return String.fromCharCode(n)},o:function(n){return n.toString(8)},x:function(n){return n.toString(16)},X:function(n){return n.toString(16).toUpperCase()},g:function(n,t){return n.toPrecision(t)},e:function(n,t){return n.toExponential(t)},f:function(n,t){return n.toFixed(t)},r:function(n,t){return(n=ta.round(n,Rt(n,t))).toFixed(Math.max(0,Math.min(20,Rt(n*(1+1e-15),t))))}}),ac=ta.time={},cc=Date;jt.prototype={getDate:function(){return this._.getUTCDate()},getDay:function(){return this._.getUTCDay()},getFullYear:function(){return this._.getUTCFullYear()},getHours:function(){return this._.getUTCHours()},getMilliseconds:function(){return this._.getUTCMilliseconds()},getMinutes:function(){return this._.getUTCMinutes()},getMonth:function(){return this._.getUTCMonth()},getSeconds:function(){return this._.getUTCSeconds()},getTime:function(){return this._.getTime()},getTimezoneOffset:function(){return 0},valueOf:function(){return this._.valueOf()},setDate:function(){lc.setUTCDate.apply(this._,arguments)},setDay:function(){lc.setUTCDay.apply(this._,arguments)},setFullYear:function(){lc.setUTCFullYear.apply(this._,arguments)},setHours:function(){lc.setUTCHours.apply(this._,arguments)},setMilliseconds:function(){lc.setUTCMilliseconds.apply(this._,arguments)},setMinutes:function(){lc.setUTCMinutes.apply(this._,arguments)},setMonth:function(){lc.setUTCMonth.apply(this._,arguments)},setSeconds:function(){lc.setUTCSeconds.apply(this._,arguments)},setTime:function(){lc.setTime.apply(this._,arguments)}};var lc=Date.prototype;ac.year=Ft(function(n){return n=ac.day(n),n.setMonth(0,1),n},function(n,t){n.setFullYear(n.getFullYear()+t)},function(n){return n.getFullYear()}),ac.years=ac.year.range,ac.years.utc=ac.year.utc.range,ac.day=Ft(function(n){var t=new cc(2e3,0);return t.setFullYear(n.getFullYear(),n.getMonth(),n.getDate()),t},function(n,t){n.setDate(n.getDate()+t)},function(n){return n.getDate()-1}),ac.days=ac.day.range,ac.days.utc=ac.day.utc.range,ac.dayOfYear=function(n){var t=ac.year(n);return Math.floor((n-t-6e4*(n.getTimezoneOffset()-t.getTimezoneOffset()))/864e5)},["sunday","monday","tuesday","wednesday","thursday","friday","saturday"].forEach(function(n,t){t=7-t;var e=ac[n]=Ft(function(n){return(n=ac.day(n)).setDate(n.getDate()-(n.getDay()+t)%7),n},function(n,t){n.setDate(n.getDate()+7*Math.floor(t))},function(n){var e=ac.year(n).getDay();return Math.floor((ac.dayOfYear(n)+(e+t)%7)/7)-(e!==t)});ac[n+"s"]=e.range,ac[n+"s"].utc=e.utc.range,ac[n+"OfYear"]=function(n){var e=ac.year(n).getDay();return Math.floor((ac.dayOfYear(n)+(e+t)%7)/7)}}),ac.week=ac.sunday,ac.weeks=ac.sunday.range,ac.weeks.utc=ac.sunday.utc.range,ac.weekOfYear=ac.sundayOfYear;var sc={"-":"",_:" ",0:"0"},fc=/^\s*\d+/,hc=/^%/;ta.locale=function(n){return{numberFormat:Pt(n),timeFormat:Ot(n)}};var gc=ta.locale({decimal:".",thousands:",",grouping:[3],currency:["$",""],dateTime:"%a %b %e %X %Y",date:"%m/%d/%Y",time:"%H:%M:%S",periods:["AM","PM"],days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],shortDays:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],shortMonths:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]});ta.format=gc.numberFormat,ta.geo={},ce.prototype={s:0,t:0,add:function(n){le(n,this.t,pc),le(pc.s,this.s,this),this.s?this.t+=pc.t:this.s=pc.t
+},reset:function(){this.s=this.t=0},valueOf:function(){return this.s}};var pc=new ce;ta.geo.stream=function(n,t){n&&vc.hasOwnProperty(n.type)?vc[n.type](n,t):se(n,t)};var vc={Feature:function(n,t){se(n.geometry,t)},FeatureCollection:function(n,t){for(var e=n.features,r=-1,u=e.length;++r<u;)se(e[r].geometry,t)}},dc={Sphere:function(n,t){t.sphere()},Point:function(n,t){n=n.coordinates,t.point(n[0],n[1],n[2])},MultiPoint:function(n,t){for(var e=n.coordinates,r=-1,u=e.length;++r<u;)n=e[r],t.point(n[0],n[1],n[2])},LineString:function(n,t){fe(n.coordinates,t,0)},MultiLineString:function(n,t){for(var e=n.coordinates,r=-1,u=e.length;++r<u;)fe(e[r],t,0)},Polygon:function(n,t){he(n.coordinates,t)},MultiPolygon:function(n,t){for(var e=n.coordinates,r=-1,u=e.length;++r<u;)he(e[r],t)},GeometryCollection:function(n,t){for(var e=n.geometries,r=-1,u=e.length;++r<u;)se(e[r],t)}};ta.geo.area=function(n){return mc=0,ta.geo.stream(n,Mc),mc};var mc,yc=new ce,Mc={sphere:function(){mc+=4*qa},point:b,lineStart:b,lineEnd:b,polygonStart:function(){yc.reset(),Mc.lineStart=ge},polygonEnd:function(){var n=2*yc;mc+=0>n?4*qa+n:n,Mc.lineStart=Mc.lineEnd=Mc.point=b}};ta.geo.bounds=function(){function n(n,t){M.push(x=[s=n,h=n]),f>t&&(f=t),t>g&&(g=t)}function t(t,e){var r=pe([t*Da,e*Da]);if(m){var u=de(m,r),i=[u[1],-u[0],0],o=de(i,u);Me(o),o=xe(o);var c=t-p,l=c>0?1:-1,v=o[0]*Pa*l,d=ga(c)>180;if(d^(v>l*p&&l*t>v)){var y=o[1]*Pa;y>g&&(g=y)}else if(v=(v+360)%360-180,d^(v>l*p&&l*t>v)){var y=-o[1]*Pa;f>y&&(f=y)}else f>e&&(f=e),e>g&&(g=e);d?p>t?a(s,t)>a(s,h)&&(h=t):a(t,h)>a(s,h)&&(s=t):h>=s?(s>t&&(s=t),t>h&&(h=t)):t>p?a(s,t)>a(s,h)&&(h=t):a(t,h)>a(s,h)&&(s=t)}else n(t,e);m=r,p=t}function e(){b.point=t}function r(){x[0]=s,x[1]=h,b.point=n,m=null}function u(n,e){if(m){var r=n-p;y+=ga(r)>180?r+(r>0?360:-360):r}else v=n,d=e;Mc.point(n,e),t(n,e)}function i(){Mc.lineStart()}function o(){u(v,d),Mc.lineEnd(),ga(y)>Ca&&(s=-(h=180)),x[0]=s,x[1]=h,m=null}function a(n,t){return(t-=n)<0?t+360:t}function c(n,t){return n[0]-t[0]}function l(n,t){return t[0]<=t[1]?t[0]<=n&&n<=t[1]:n<t[0]||t[1]<n}var s,f,h,g,p,v,d,m,y,M,x,b={point:n,lineStart:e,lineEnd:r,polygonStart:function(){b.point=u,b.lineStart=i,b.lineEnd=o,y=0,Mc.polygonStart()},polygonEnd:function(){Mc.polygonEnd(),b.point=n,b.lineStart=e,b.lineEnd=r,0>yc?(s=-(h=180),f=-(g=90)):y>Ca?g=90:-Ca>y&&(f=-90),x[0]=s,x[1]=h}};return function(n){g=h=-(s=f=1/0),M=[],ta.geo.stream(n,b);var t=M.length;if(t){M.sort(c);for(var e,r=1,u=M[0],i=[u];t>r;++r)e=M[r],l(e[0],u)||l(e[1],u)?(a(u[0],e[1])>a(u[0],u[1])&&(u[1]=e[1]),a(e[0],u[1])>a(u[0],u[1])&&(u[0]=e[0])):i.push(u=e);for(var o,e,p=-1/0,t=i.length-1,r=0,u=i[t];t>=r;u=e,++r)e=i[r],(o=a(u[1],e[0]))>p&&(p=o,s=e[0],h=u[1])}return M=x=null,1/0===s||1/0===f?[[0/0,0/0],[0/0,0/0]]:[[s,f],[h,g]]}}(),ta.geo.centroid=function(n){xc=bc=_c=wc=Sc=kc=Ec=Ac=Nc=Cc=zc=0,ta.geo.stream(n,qc);var t=Nc,e=Cc,r=zc,u=t*t+e*e+r*r;return za>u&&(t=kc,e=Ec,r=Ac,Ca>bc&&(t=_c,e=wc,r=Sc),u=t*t+e*e+r*r,za>u)?[0/0,0/0]:[Math.atan2(e,t)*Pa,tt(r/Math.sqrt(u))*Pa]};var xc,bc,_c,wc,Sc,kc,Ec,Ac,Nc,Cc,zc,qc={sphere:b,point:_e,lineStart:Se,lineEnd:ke,polygonStart:function(){qc.lineStart=Ee},polygonEnd:function(){qc.lineStart=Se}},Lc=Le(Ne,Pe,je,[-qa,-qa/2]),Tc=1e9;ta.geo.clipExtent=function(){var n,t,e,r,u,i,o={stream:function(n){return u&&(u.valid=!1),u=i(n),u.valid=!0,u},extent:function(a){return arguments.length?(i=Ie(n=+a[0][0],t=+a[0][1],e=+a[1][0],r=+a[1][1]),u&&(u.valid=!1,u=null),o):[[n,t],[e,r]]}};return o.extent([[0,0],[960,500]])},(ta.geo.conicEqualArea=function(){return Ye(Ze)}).raw=Ze,ta.geo.albers=function(){return ta.geo.conicEqualArea().rotate([96,0]).center([-.6,38.7]).parallels([29.5,45.5]).scale(1070)},ta.geo.albersUsa=function(){function n(n){var i=n[0],o=n[1];return t=null,e(i,o),t||(r(i,o),t)||u(i,o),t}var t,e,r,u,i=ta.geo.albers(),o=ta.geo.conicEqualArea().rotate([154,0]).center([-2,58.5]).parallels([55,65]),a=ta.geo.conicEqualArea().rotate([157,0]).center([-3,19.9]).parallels([8,18]),c={point:function(n,e){t=[n,e]}};return n.invert=function(n){var t=i.scale(),e=i.translate(),r=(n[0]-e[0])/t,u=(n[1]-e[1])/t;return(u>=.12&&.234>u&&r>=-.425&&-.214>r?o:u>=.166&&.234>u&&r>=-.214&&-.115>r?a:i).invert(n)},n.stream=function(n){var t=i.stream(n),e=o.stream(n),r=a.stream(n);return{point:function(n,u){t.point(n,u),e.point(n,u),r.point(n,u)},sphere:function(){t.sphere(),e.sphere(),r.sphere()},lineStart:function(){t.lineStart(),e.lineStart(),r.lineStart()},lineEnd:function(){t.lineEnd(),e.lineEnd(),r.lineEnd()},polygonStart:function(){t.polygonStart(),e.polygonStart(),r.polygonStart()},polygonEnd:function(){t.polygonEnd(),e.polygonEnd(),r.polygonEnd()}}},n.precision=function(t){return arguments.length?(i.precision(t),o.precision(t),a.precision(t),n):i.precision()},n.scale=function(t){return arguments.length?(i.scale(t),o.scale(.35*t),a.scale(t),n.translate(i.translate())):i.scale()},n.translate=function(t){if(!arguments.length)return i.translate();var l=i.scale(),s=+t[0],f=+t[1];return e=i.translate(t).clipExtent([[s-.455*l,f-.238*l],[s+.455*l,f+.238*l]]).stream(c).point,r=o.translate([s-.307*l,f+.201*l]).clipExtent([[s-.425*l+Ca,f+.12*l+Ca],[s-.214*l-Ca,f+.234*l-Ca]]).stream(c).point,u=a.translate([s-.205*l,f+.212*l]).clipExtent([[s-.214*l+Ca,f+.166*l+Ca],[s-.115*l-Ca,f+.234*l-Ca]]).stream(c).point,n},n.scale(1070)};var Rc,Dc,Pc,Uc,jc,Fc,Hc={point:b,lineStart:b,lineEnd:b,polygonStart:function(){Dc=0,Hc.lineStart=Ve},polygonEnd:function(){Hc.lineStart=Hc.lineEnd=Hc.point=b,Rc+=ga(Dc/2)}},Oc={point:Xe,lineStart:b,lineEnd:b,polygonStart:b,polygonEnd:b},Ic={point:We,lineStart:Je,lineEnd:Ge,polygonStart:function(){Ic.lineStart=Ke},polygonEnd:function(){Ic.point=We,Ic.lineStart=Je,Ic.lineEnd=Ge}};ta.geo.path=function(){function n(n){return n&&("function"==typeof a&&i.pointRadius(+a.apply(this,arguments)),o&&o.valid||(o=u(i)),ta.geo.stream(n,o)),i.result()}function t(){return o=null,n}var e,r,u,i,o,a=4.5;return n.area=function(n){return Rc=0,ta.geo.stream(n,u(Hc)),Rc},n.centroid=function(n){return _c=wc=Sc=kc=Ec=Ac=Nc=Cc=zc=0,ta.geo.stream(n,u(Ic)),zc?[Nc/zc,Cc/zc]:Ac?[kc/Ac,Ec/Ac]:Sc?[_c/Sc,wc/Sc]:[0/0,0/0]},n.bounds=function(n){return jc=Fc=-(Pc=Uc=1/0),ta.geo.stream(n,u(Oc)),[[Pc,Uc],[jc,Fc]]},n.projection=function(n){return arguments.length?(u=(e=n)?n.stream||tr(n):y,t()):e},n.context=function(n){return arguments.length?(i=null==(r=n)?new $e:new Qe(n),"function"!=typeof a&&i.pointRadius(a),t()):r},n.pointRadius=function(t){return arguments.length?(a="function"==typeof t?t:(i.pointRadius(+t),+t),n):a},n.projection(ta.geo.albersUsa()).context(null)},ta.geo.transform=function(n){return{stream:function(t){var e=new er(t);for(var r in n)e[r]=n[r];return e}}},er.prototype={point:function(n,t){this.stream.point(n,t)},sphere:function(){this.stream.sphere()},lineStart:function(){this.stream.lineStart()},lineEnd:function(){this.stream.lineEnd()},polygonStart:function(){this.stream.polygonStart()},polygonEnd:function(){this.stream.polygonEnd()}},ta.geo.projection=ur,ta.geo.projectionMutator=ir,(ta.geo.equirectangular=function(){return ur(ar)}).raw=ar.invert=ar,ta.geo.rotation=function(n){function t(t){return t=n(t[0]*Da,t[1]*Da),t[0]*=Pa,t[1]*=Pa,t}return n=lr(n[0]%360*Da,n[1]*Da,n.length>2?n[2]*Da:0),t.invert=function(t){return t=n.invert(t[0]*Da,t[1]*Da),t[0]*=Pa,t[1]*=Pa,t},t},cr.invert=ar,ta.geo.circle=function(){function n(){var n="function"==typeof r?r.apply(this,arguments):r,t=lr(-n[0]*Da,-n[1]*Da,0).invert,u=[];return e(null,null,1,{point:function(n,e){u.push(n=t(n,e)),n[0]*=Pa,n[1]*=Pa}}),{type:"Polygon",coordinates:[u]}}var t,e,r=[0,0],u=6;return n.origin=function(t){return arguments.length?(r=t,n):r},n.angle=function(r){return arguments.length?(e=gr((t=+r)*Da,u*Da),n):t},n.precision=function(r){return arguments.length?(e=gr(t*Da,(u=+r)*Da),n):u},n.angle(90)},ta.geo.distance=function(n,t){var e,r=(t[0]-n[0])*Da,u=n[1]*Da,i=t[1]*Da,o=Math.sin(r),a=Math.cos(r),c=Math.sin(u),l=Math.cos(u),s=Math.sin(i),f=Math.cos(i);return Math.atan2(Math.sqrt((e=f*o)*e+(e=l*s-c*f*a)*e),c*s+l*f*a)},ta.geo.graticule=function(){function n(){return{type:"MultiLineString",coordinates:t()}}function t(){return ta.range(Math.ceil(i/d)*d,u,d).map(h).concat(ta.range(Math.ceil(l/m)*m,c,m).map(g)).concat(ta.range(Math.ceil(r/p)*p,e,p).filter(function(n){return ga(n%d)>Ca}).map(s)).concat(ta.range(Math.ceil(a/v)*v,o,v).filter(function(n){return ga(n%m)>Ca}).map(f))}var e,r,u,i,o,a,c,l,s,f,h,g,p=10,v=p,d=90,m=360,y=2.5;return n.lines=function(){return t().map(function(n){return{type:"LineString",coordinates:n}})},n.outline=function(){return{type:"Polygon",coordinates:[h(i).concat(g(c).slice(1),h(u).reverse().slice(1),g(l).reverse().slice(1))]}},n.extent=function(t){return arguments.length?n.majorExtent(t).minorExtent(t):n.minorExtent()},n.majorExtent=function(t){return arguments.length?(i=+t[0][0],u=+t[1][0],l=+t[0][1],c=+t[1][1],i>u&&(t=i,i=u,u=t),l>c&&(t=l,l=c,c=t),n.precision(y)):[[i,l],[u,c]]},n.minorExtent=function(t){return arguments.length?(r=+t[0][0],e=+t[1][0],a=+t[0][1],o=+t[1][1],r>e&&(t=r,r=e,e=t),a>o&&(t=a,a=o,o=t),n.precision(y)):[[r,a],[e,o]]},n.step=function(t){return arguments.length?n.majorStep(t).minorStep(t):n.minorStep()},n.majorStep=function(t){return arguments.length?(d=+t[0],m=+t[1],n):[d,m]},n.minorStep=function(t){return arguments.length?(p=+t[0],v=+t[1],n):[p,v]},n.precision=function(t){return arguments.length?(y=+t,s=vr(a,o,90),f=dr(r,e,y),h=vr(l,c,90),g=dr(i,u,y),n):y},n.majorExtent([[-180,-90+Ca],[180,90-Ca]]).minorExtent([[-180,-80-Ca],[180,80+Ca]])},ta.geo.greatArc=function(){function n(){return{type:"LineString",coordinates:[t||r.apply(this,arguments),e||u.apply(this,arguments)]}}var t,e,r=mr,u=yr;return n.distance=function(){return ta.geo.distance(t||r.apply(this,arguments),e||u.apply(this,arguments))},n.source=function(e){return arguments.length?(r=e,t="function"==typeof e?null:e,n):r},n.target=function(t){return arguments.length?(u=t,e="function"==typeof t?null:t,n):u},n.precision=function(){return arguments.length?n:0},n},ta.geo.interpolate=function(n,t){return Mr(n[0]*Da,n[1]*Da,t[0]*Da,t[1]*Da)},ta.geo.length=function(n){return Yc=0,ta.geo.stream(n,Zc),Yc};var Yc,Zc={sphere:b,point:b,lineStart:xr,lineEnd:b,polygonStart:b,polygonEnd:b},Vc=br(function(n){return Math.sqrt(2/(1+n))},function(n){return 2*Math.asin(n/2)});(ta.geo.azimuthalEqualArea=function(){return ur(Vc)}).raw=Vc;var Xc=br(function(n){var t=Math.acos(n);return t&&t/Math.sin(t)},y);(ta.geo.azimuthalEquidistant=function(){return ur(Xc)}).raw=Xc,(ta.geo.conicConformal=function(){return Ye(_r)}).raw=_r,(ta.geo.conicEquidistant=function(){return Ye(wr)}).raw=wr;var $c=br(function(n){return 1/n},Math.atan);(ta.geo.gnomonic=function(){return ur($c)}).raw=$c,Sr.invert=function(n,t){return[n,2*Math.atan(Math.exp(t))-Ra]},(ta.geo.mercator=function(){return kr(Sr)}).raw=Sr;var Bc=br(function(){return 1},Math.asin);(ta.geo.orthographic=function(){return ur(Bc)}).raw=Bc;var Wc=br(function(n){return 1/(1+n)},function(n){return 2*Math.atan(n)});(ta.geo.stereographic=function(){return ur(Wc)}).raw=Wc,Er.invert=function(n,t){return[-t,2*Math.atan(Math.exp(n))-Ra]},(ta.geo.transverseMercator=function(){var n=kr(Er),t=n.center,e=n.rotate;return n.center=function(n){return n?t([-n[1],n[0]]):(n=t(),[n[1],-n[0]])},n.rotate=function(n){return n?e([n[0],n[1],n.length>2?n[2]+90:90]):(n=e(),[n[0],n[1],n[2]-90])},e([0,0,90])}).raw=Er,ta.geom={},ta.geom.hull=function(n){function t(n){if(n.length<3)return[];var t,u=Et(e),i=Et(r),o=n.length,a=[],c=[];for(t=0;o>t;t++)a.push([+u.call(this,n[t],t),+i.call(this,n[t],t),t]);for(a.sort(zr),t=0;o>t;t++)c.push([a[t][0],-a[t][1]]);var l=Cr(a),s=Cr(c),f=s[0]===l[0],h=s[s.length-1]===l[l.length-1],g=[];for(t=l.length-1;t>=0;--t)g.push(n[a[l[t]][2]]);for(t=+f;t<s.length-h;++t)g.push(n[a[s[t]][2]]);return g}var e=Ar,r=Nr;return arguments.length?t(n):(t.x=function(n){return arguments.length?(e=n,t):e},t.y=function(n){return arguments.length?(r=n,t):r},t)},ta.geom.polygon=function(n){return ya(n,Jc),n};var Jc=ta.geom.polygon.prototype=[];Jc.area=function(){for(var n,t=-1,e=this.length,r=this[e-1],u=0;++t<e;)n=r,r=this[t],u+=n[1]*r[0]-n[0]*r[1];return.5*u},Jc.centroid=function(n){var t,e,r=-1,u=this.length,i=0,o=0,a=this[u-1];for(arguments.length||(n=-1/(6*this.area()));++r<u;)t=a,a=this[r],e=t[0]*a[1]-a[0]*t[1],i+=(t[0]+a[0])*e,o+=(t[1]+a[1])*e;return[i*n,o*n]},Jc.clip=function(n){for(var t,e,r,u,i,o,a=Tr(n),c=-1,l=this.length-Tr(this),s=this[l-1];++c<l;){for(t=n.slice(),n.length=0,u=this[c],i=t[(r=t.length-a)-1],e=-1;++e<r;)o=t[e],qr(o,s,u)?(qr(i,s,u)||n.push(Lr(i,o,s,u)),n.push(o)):qr(i,s,u)&&n.push(Lr(i,o,s,u)),i=o;a&&n.push(n[0]),s=u}return n};var Gc,Kc,Qc,nl,tl,el=[],rl=[];Or.prototype.prepare=function(){for(var n,t=this.edges,e=t.length;e--;)n=t[e].edge,n.b&&n.a||t.splice(e,1);return t.sort(Yr),t.length},Qr.prototype={start:function(){return this.edge.l===this.site?this.edge.a:this.edge.b},end:function(){return this.edge.l===this.site?this.edge.b:this.edge.a}},nu.prototype={insert:function(n,t){var e,r,u;if(n){if(t.P=n,t.N=n.N,n.N&&(n.N.P=t),n.N=t,n.R){for(n=n.R;n.L;)n=n.L;n.L=t}else n.R=t;e=n}else this._?(n=uu(this._),t.P=null,t.N=n,n.P=n.L=t,e=n):(t.P=t.N=null,this._=t,e=null);for(t.L=t.R=null,t.U=e,t.C=!0,n=t;e&&e.C;)r=e.U,e===r.L?(u=r.R,u&&u.C?(e.C=u.C=!1,r.C=!0,n=r):(n===e.R&&(eu(this,e),n=e,e=n.U),e.C=!1,r.C=!0,ru(this,r))):(u=r.L,u&&u.C?(e.C=u.C=!1,r.C=!0,n=r):(n===e.L&&(ru(this,e),n=e,e=n.U),e.C=!1,r.C=!0,eu(this,r))),e=n.U;this._.C=!1},remove:function(n){n.N&&(n.N.P=n.P),n.P&&(n.P.N=n.N),n.N=n.P=null;var t,e,r,u=n.U,i=n.L,o=n.R;if(e=i?o?uu(o):i:o,u?u.L===n?u.L=e:u.R=e:this._=e,i&&o?(r=e.C,e.C=n.C,e.L=i,i.U=e,e!==o?(u=e.U,e.U=n.U,n=e.R,u.L=n,e.R=o,o.U=e):(e.U=u,u=e,n=e.R)):(r=n.C,n=e),n&&(n.U=u),!r){if(n&&n.C)return void(n.C=!1);do{if(n===this._)break;if(n===u.L){if(t=u.R,t.C&&(t.C=!1,u.C=!0,eu(this,u),t=u.R),t.L&&t.L.C||t.R&&t.R.C){t.R&&t.R.C||(t.L.C=!1,t.C=!0,ru(this,t),t=u.R),t.C=u.C,u.C=t.R.C=!1,eu(this,u),n=this._;break}}else if(t=u.L,t.C&&(t.C=!1,u.C=!0,ru(this,u),t=u.L),t.L&&t.L.C||t.R&&t.R.C){t.L&&t.L.C||(t.R.C=!1,t.C=!0,eu(this,t),t=u.L),t.C=u.C,u.C=t.L.C=!1,ru(this,u),n=this._;break}t.C=!0,n=u,u=u.U}while(!n.C);n&&(n.C=!1)}}},ta.geom.voronoi=function(n){function t(n){var t=new Array(n.length),r=a[0][0],u=a[0][1],i=a[1][0],o=a[1][1];return iu(e(n),a).cells.forEach(function(e,a){var c=e.edges,l=e.site,s=t[a]=c.length?c.map(function(n){var t=n.start();return[t.x,t.y]}):l.x>=r&&l.x<=i&&l.y>=u&&l.y<=o?[[r,o],[i,o],[i,u],[r,u]]:[];s.point=n[a]}),t}function e(n){return n.map(function(n,t){return{x:Math.round(i(n,t)/Ca)*Ca,y:Math.round(o(n,t)/Ca)*Ca,i:t}})}var r=Ar,u=Nr,i=r,o=u,a=ul;return n?t(n):(t.links=function(n){return iu(e(n)).edges.filter(function(n){return n.l&&n.r}).map(function(t){return{source:n[t.l.i],target:n[t.r.i]}})},t.triangles=function(n){var t=[];return iu(e(n)).cells.forEach(function(e,r){for(var u,i,o=e.site,a=e.edges.sort(Yr),c=-1,l=a.length,s=a[l-1].edge,f=s.l===o?s.r:s.l;++c<l;)u=s,i=f,s=a[c].edge,f=s.l===o?s.r:s.l,r<i.i&&r<f.i&&au(o,i,f)<0&&t.push([n[r],n[i.i],n[f.i]])}),t},t.x=function(n){return arguments.length?(i=Et(r=n),t):r},t.y=function(n){return arguments.length?(o=Et(u=n),t):u},t.clipExtent=function(n){return arguments.length?(a=null==n?ul:n,t):a===ul?null:a},t.size=function(n){return arguments.length?t.clipExtent(n&&[[0,0],n]):a===ul?null:a&&a[1]},t)};var ul=[[-1e6,-1e6],[1e6,1e6]];ta.geom.delaunay=function(n){return ta.geom.voronoi().triangles(n)},ta.geom.quadtree=function(n,t,e,r,u){function i(n){function i(n,t,e,r,u,i,o,a){if(!isNaN(e)&&!isNaN(r))if(n.leaf){var c=n.x,s=n.y;if(null!=c)if(ga(c-e)+ga(s-r)<.01)l(n,t,e,r,u,i,o,a);else{var f=n.point;n.x=n.y=n.point=null,l(n,f,c,s,u,i,o,a),l(n,t,e,r,u,i,o,a)}else n.x=e,n.y=r,n.point=t}else l(n,t,e,r,u,i,o,a)}function l(n,t,e,r,u,o,a,c){var l=.5*(u+a),s=.5*(o+c),f=e>=l,h=r>=s,g=h<<1|f;n.leaf=!1,n=n.nodes[g]||(n.nodes[g]=su()),f?u=l:a=l,h?o=s:c=s,i(n,t,e,r,u,o,a,c)}var s,f,h,g,p,v,d,m,y,M=Et(a),x=Et(c);if(null!=t)v=t,d=e,m=r,y=u;else if(m=y=-(v=d=1/0),f=[],h=[],p=n.length,o)for(g=0;p>g;++g)s=n[g],s.x<v&&(v=s.x),s.y<d&&(d=s.y),s.x>m&&(m=s.x),s.y>y&&(y=s.y),f.push(s.x),h.push(s.y);else for(g=0;p>g;++g){var b=+M(s=n[g],g),_=+x(s,g);v>b&&(v=b),d>_&&(d=_),b>m&&(m=b),_>y&&(y=_),f.push(b),h.push(_)}var w=m-v,S=y-d;w>S?y=d+w:m=v+S;var k=su();if(k.add=function(n){i(k,n,+M(n,++g),+x(n,g),v,d,m,y)},k.visit=function(n){fu(n,k,v,d,m,y)},k.find=function(n){return hu(k,n[0],n[1],v,d,m,y)},g=-1,null==t){for(;++g<p;)i(k,n[g],f[g],h[g],v,d,m,y);--g}else n.forEach(k.add);return f=h=n=s=null,k}var o,a=Ar,c=Nr;return(o=arguments.length)?(a=cu,c=lu,3===o&&(u=e,r=t,e=t=0),i(n)):(i.x=function(n){return arguments.length?(a=n,i):a},i.y=function(n){return arguments.length?(c=n,i):c},i.extent=function(n){return arguments.length?(null==n?t=e=r=u=null:(t=+n[0][0],e=+n[0][1],r=+n[1][0],u=+n[1][1]),i):null==t?null:[[t,e],[r,u]]},i.size=function(n){return arguments.length?(null==n?t=e=r=u=null:(t=e=0,r=+n[0],u=+n[1]),i):null==t?null:[r-t,u-e]},i)},ta.interpolateRgb=gu,ta.interpolateObject=pu,ta.interpolateNumber=vu,ta.interpolateString=du;var il=/[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g,ol=new RegExp(il.source,"g");ta.interpolate=mu,ta.interpolators=[function(n,t){var e=typeof t;return("string"===e?Ga.has(t.toLowerCase())||/^(#|rgb\(|hsl\()/i.test(t)?gu:du:t instanceof ot?gu:Array.isArray(t)?yu:"object"===e&&isNaN(t)?pu:vu)(n,t)}],ta.interpolateArray=yu;var al=function(){return y},cl=ta.map({linear:al,poly:ku,quad:function(){return _u},cubic:function(){return wu},sin:function(){return Eu},exp:function(){return Au},circle:function(){return Nu},elastic:Cu,back:zu,bounce:function(){return qu}}),ll=ta.map({"in":y,out:xu,"in-out":bu,"out-in":function(n){return bu(xu(n))}});ta.ease=function(n){var t=n.indexOf("-"),e=t>=0?n.slice(0,t):n,r=t>=0?n.slice(t+1):"in";return e=cl.get(e)||al,r=ll.get(r)||y,Mu(r(e.apply(null,ea.call(arguments,1))))},ta.interpolateHcl=Lu,ta.interpolateHsl=Tu,ta.interpolateLab=Ru,ta.interpolateRound=Du,ta.transform=function(n){var t=ua.createElementNS(ta.ns.prefix.svg,"g");return(ta.transform=function(n){if(null!=n){t.setAttribute("transform",n);var e=t.transform.baseVal.consolidate()}return new Pu(e?e.matrix:sl)})(n)},Pu.prototype.toString=function(){return"translate("+this.translate+")rotate("+this.rotate+")skewX("+this.skew+")scale("+this.scale+")"};var sl={a:1,b:0,c:0,d:1,e:0,f:0};ta.interpolateTransform=Hu,ta.layout={},ta.layout.bundle=function(){return function(n){for(var t=[],e=-1,r=n.length;++e<r;)t.push(Yu(n[e]));return t}},ta.layout.chord=function(){function n(){var n,l,f,h,g,p={},v=[],d=ta.range(i),m=[];for(e=[],r=[],n=0,h=-1;++h<i;){for(l=0,g=-1;++g<i;)l+=u[h][g];v.push(l),m.push(ta.range(i)),n+=l}for(o&&d.sort(function(n,t){return o(v[n],v[t])}),a&&m.forEach(function(n,t){n.sort(function(n,e){return a(u[t][n],u[t][e])})}),n=(La-s*i)/n,l=0,h=-1;++h<i;){for(f=l,g=-1;++g<i;){var y=d[h],M=m[y][g],x=u[y][M],b=l,_=l+=x*n;p[y+"-"+M]={index:y,subindex:M,startAngle:b,endAngle:_,value:x}}r[y]={index:y,startAngle:f,endAngle:l,value:(l-f)/n},l+=s}for(h=-1;++h<i;)for(g=h-1;++g<i;){var w=p[h+"-"+g],S=p[g+"-"+h];(w.value||S.value)&&e.push(w.value<S.value?{source:S,target:w}:{source:w,target:S})}c&&t()}function t(){e.sort(function(n,t){return c((n.source.value+n.target.value)/2,(t.source.value+t.target.value)/2)})}var e,r,u,i,o,a,c,l={},s=0;return l.matrix=function(n){return arguments.length?(i=(u=n)&&u.length,e=r=null,l):u},l.padding=function(n){return arguments.length?(s=n,e=r=null,l):s},l.sortGroups=function(n){return arguments.length?(o=n,e=r=null,l):o},l.sortSubgroups=function(n){return arguments.length?(a=n,e=null,l):a},l.sortChords=function(n){return arguments.length?(c=n,e&&t(),l):c},l.chords=function(){return e||n(),e},l.groups=function(){return r||n(),r},l},ta.layout.force=function(){function n(n){return function(t,e,r,u){if(t.point!==n){var i=t.cx-n.x,o=t.cy-n.y,a=u-e,c=i*i+o*o;if(c>a*a/d){if(p>c){var l=t.charge/c;n.px-=i*l,n.py-=o*l}return!0}if(t.point&&c&&p>c){var l=t.pointCharge/c;n.px-=i*l,n.py-=o*l}}return!t.charge}}function t(n){n.px=ta.event.x,n.py=ta.event.y,a.resume()}var e,r,u,i,o,a={},c=ta.dispatch("start","tick","end"),l=[1,1],s=.9,f=fl,h=hl,g=-30,p=gl,v=.1,d=.64,m=[],M=[];return a.tick=function(){if((r*=.99)<.005)return c.end({type:"end",alpha:r=0}),!0;var t,e,a,f,h,p,d,y,x,b=m.length,_=M.length;for(e=0;_>e;++e)a=M[e],f=a.source,h=a.target,y=h.x-f.x,x=h.y-f.y,(p=y*y+x*x)&&(p=r*i[e]*((p=Math.sqrt(p))-u[e])/p,y*=p,x*=p,h.x-=y*(d=f.weight/(h.weight+f.weight)),h.y-=x*d,f.x+=y*(d=1-d),f.y+=x*d);if((d=r*v)&&(y=l[0]/2,x=l[1]/2,e=-1,d))for(;++e<b;)a=m[e],a.x+=(y-a.x)*d,a.y+=(x-a.y)*d;if(g)for(Ju(t=ta.geom.quadtree(m),r,o),e=-1;++e<b;)(a=m[e]).fixed||t.visit(n(a));for(e=-1;++e<b;)a=m[e],a.fixed?(a.x=a.px,a.y=a.py):(a.x-=(a.px-(a.px=a.x))*s,a.y-=(a.py-(a.py=a.y))*s);c.tick({type:"tick",alpha:r})},a.nodes=function(n){return arguments.length?(m=n,a):m},a.links=function(n){return arguments.length?(M=n,a):M},a.size=function(n){return arguments.length?(l=n,a):l},a.linkDistance=function(n){return arguments.length?(f="function"==typeof n?n:+n,a):f},a.distance=a.linkDistance,a.linkStrength=function(n){return arguments.length?(h="function"==typeof n?n:+n,a):h},a.friction=function(n){return arguments.length?(s=+n,a):s},a.charge=function(n){return arguments.length?(g="function"==typeof n?n:+n,a):g},a.chargeDistance=function(n){return arguments.length?(p=n*n,a):Math.sqrt(p)},a.gravity=function(n){return arguments.length?(v=+n,a):v},a.theta=function(n){return arguments.length?(d=n*n,a):Math.sqrt(d)},a.alpha=function(n){return arguments.length?(n=+n,r?r=n>0?n:0:n>0&&(c.start({type:"start",alpha:r=n}),ta.timer(a.tick)),a):r},a.start=function(){function n(n,r){if(!e){for(e=new Array(c),a=0;c>a;++a)e[a]=[];for(a=0;s>a;++a){var u=M[a];e[u.source.index].push(u.target),e[u.target.index].push(u.source)}}for(var i,o=e[t],a=-1,l=o.length;++a<l;)if(!isNaN(i=o[a][n]))return i;return Math.random()*r}var t,e,r,c=m.length,s=M.length,p=l[0],v=l[1];for(t=0;c>t;++t)(r=m[t]).index=t,r.weight=0;for(t=0;s>t;++t)r=M[t],"number"==typeof r.source&&(r.source=m[r.source]),"number"==typeof r.target&&(r.target=m[r.target]),++r.source.weight,++r.target.weight;for(t=0;c>t;++t)r=m[t],isNaN(r.x)&&(r.x=n("x",p)),isNaN(r.y)&&(r.y=n("y",v)),isNaN(r.px)&&(r.px=r.x),isNaN(r.py)&&(r.py=r.y);if(u=[],"function"==typeof f)for(t=0;s>t;++t)u[t]=+f.call(this,M[t],t);else for(t=0;s>t;++t)u[t]=f;if(i=[],"function"==typeof h)for(t=0;s>t;++t)i[t]=+h.call(this,M[t],t);else for(t=0;s>t;++t)i[t]=h;if(o=[],"function"==typeof g)for(t=0;c>t;++t)o[t]=+g.call(this,m[t],t);else for(t=0;c>t;++t)o[t]=g;return a.resume()},a.resume=function(){return a.alpha(.1)},a.stop=function(){return a.alpha(0)},a.drag=function(){return e||(e=ta.behavior.drag().origin(y).on("dragstart.force",Xu).on("drag.force",t).on("dragend.force",$u)),arguments.length?void this.on("mouseover.force",Bu).on("mouseout.force",Wu).call(e):e},ta.rebind(a,c,"on")};var fl=20,hl=1,gl=1/0;ta.layout.hierarchy=function(){function n(u){var i,o=[u],a=[];for(u.depth=0;null!=(i=o.pop());)if(a.push(i),(l=e.call(n,i,i.depth))&&(c=l.length)){for(var c,l,s;--c>=0;)o.push(s=l[c]),s.parent=i,s.depth=i.depth+1;r&&(i.value=0),i.children=l}else r&&(i.value=+r.call(n,i,i.depth)||0),delete i.children;return Qu(u,function(n){var e,u;t&&(e=n.children)&&e.sort(t),r&&(u=n.parent)&&(u.value+=n.value)}),a}var t=ei,e=ni,r=ti;return n.sort=function(e){return arguments.length?(t=e,n):t},n.children=function(t){return arguments.length?(e=t,n):e},n.value=function(t){return arguments.length?(r=t,n):r},n.revalue=function(t){return r&&(Ku(t,function(n){n.children&&(n.value=0)}),Qu(t,function(t){var e;t.children||(t.value=+r.call(n,t,t.depth)||0),(e=t.parent)&&(e.value+=t.value)})),t},n},ta.layout.partition=function(){function n(t,e,r,u){var i=t.children;if(t.x=e,t.y=t.depth*u,t.dx=r,t.dy=u,i&&(o=i.length)){var o,a,c,l=-1;for(r=t.value?r/t.value:0;++l<o;)n(a=i[l],e,c=a.value*r,u),e+=c}}function t(n){var e=n.children,r=0;if(e&&(u=e.length))for(var u,i=-1;++i<u;)r=Math.max(r,t(e[i]));return 1+r}function e(e,i){var o=r.call(this,e,i);return n(o[0],0,u[0],u[1]/t(o[0])),o}var r=ta.layout.hierarchy(),u=[1,1];return e.size=function(n){return arguments.length?(u=n,e):u},Gu(e,r)},ta.layout.pie=function(){function n(o){var a,c=o.length,l=o.map(function(e,r){return+t.call(n,e,r)}),s=+("function"==typeof r?r.apply(this,arguments):r),f=("function"==typeof u?u.apply(this,arguments):u)-s,h=Math.min(Math.abs(f)/c,+("function"==typeof i?i.apply(this,arguments):i)),g=h*(0>f?-1:1),p=(f-c*g)/ta.sum(l),v=ta.range(c),d=[];return null!=e&&v.sort(e===pl?function(n,t){return l[t]-l[n]}:function(n,t){return e(o[n],o[t])}),v.forEach(function(n){d[n]={data:o[n],value:a=l[n],startAngle:s,endAngle:s+=a*p+g,padAngle:h}}),d}var t=Number,e=pl,r=0,u=La,i=0;return n.value=function(e){return arguments.length?(t=e,n):t},n.sort=function(t){return arguments.length?(e=t,n):e},n.startAngle=function(t){return arguments.length?(r=t,n):r},n.endAngle=function(t){return arguments.length?(u=t,n):u},n.padAngle=function(t){return arguments.length?(i=t,n):i},n};var pl={};ta.layout.stack=function(){function n(a,c){if(!(h=a.length))return a;var l=a.map(function(e,r){return t.call(n,e,r)}),s=l.map(function(t){return t.map(function(t,e){return[i.call(n,t,e),o.call(n,t,e)]})}),f=e.call(n,s,c);l=ta.permute(l,f),s=ta.permute(s,f);var h,g,p,v,d=r.call(n,s,c),m=l[0].length;for(p=0;m>p;++p)for(u.call(n,l[0][p],v=d[p],s[0][p][1]),g=1;h>g;++g)u.call(n,l[g][p],v+=s[g-1][p][1],s[g][p][1]);return a}var t=y,e=ai,r=ci,u=oi,i=ui,o=ii;return n.values=function(e){return arguments.length?(t=e,n):t},n.order=function(t){return arguments.length?(e="function"==typeof t?t:vl.get(t)||ai,n):e},n.offset=function(t){return arguments.length?(r="function"==typeof t?t:dl.get(t)||ci,n):r},n.x=function(t){return arguments.length?(i=t,n):i},n.y=function(t){return arguments.length?(o=t,n):o},n.out=function(t){return arguments.length?(u=t,n):u},n};var vl=ta.map({"inside-out":function(n){var t,e,r=n.length,u=n.map(li),i=n.map(si),o=ta.range(r).sort(function(n,t){return u[n]-u[t]}),a=0,c=0,l=[],s=[];for(t=0;r>t;++t)e=o[t],c>a?(a+=i[e],l.push(e)):(c+=i[e],s.push(e));return s.reverse().concat(l)},reverse:function(n){return ta.range(n.length).reverse()},"default":ai}),dl=ta.map({silhouette:function(n){var t,e,r,u=n.length,i=n[0].length,o=[],a=0,c=[];for(e=0;i>e;++e){for(t=0,r=0;u>t;t++)r+=n[t][e][1];r>a&&(a=r),o.push(r)}for(e=0;i>e;++e)c[e]=(a-o[e])/2;return c},wiggle:function(n){var t,e,r,u,i,o,a,c,l,s=n.length,f=n[0],h=f.length,g=[];for(g[0]=c=l=0,e=1;h>e;++e){for(t=0,u=0;s>t;++t)u+=n[t][e][1];for(t=0,i=0,a=f[e][0]-f[e-1][0];s>t;++t){for(r=0,o=(n[t][e][1]-n[t][e-1][1])/(2*a);t>r;++r)o+=(n[r][e][1]-n[r][e-1][1])/a;i+=o*n[t][e][1]}g[e]=c-=u?i/u*a:0,l>c&&(l=c)}for(e=0;h>e;++e)g[e]-=l;return g},expand:function(n){var t,e,r,u=n.length,i=n[0].length,o=1/u,a=[];for(e=0;i>e;++e){for(t=0,r=0;u>t;t++)r+=n[t][e][1];if(r)for(t=0;u>t;t++)n[t][e][1]/=r;else for(t=0;u>t;t++)n[t][e][1]=o}for(e=0;i>e;++e)a[e]=0;return a},zero:ci});ta.layout.histogram=function(){function n(n,i){for(var o,a,c=[],l=n.map(e,this),s=r.call(this,l,i),f=u.call(this,s,l,i),i=-1,h=l.length,g=f.length-1,p=t?1:1/h;++i<g;)o=c[i]=[],o.dx=f[i+1]-(o.x=f[i]),o.y=0;if(g>0)for(i=-1;++i<h;)a=l[i],a>=s[0]&&a<=s[1]&&(o=c[ta.bisect(f,a,1,g)-1],o.y+=p,o.push(n[i]));return c}var t=!0,e=Number,r=pi,u=hi;return n.value=function(t){return arguments.length?(e=t,n):e},n.range=function(t){return arguments.length?(r=Et(t),n):r},n.bins=function(t){return arguments.length?(u="number"==typeof t?function(n){return gi(n,t)}:Et(t),n):u},n.frequency=function(e){return arguments.length?(t=!!e,n):t},n},ta.layout.pack=function(){function n(n,i){var o=e.call(this,n,i),a=o[0],c=u[0],l=u[1],s=null==t?Math.sqrt:"function"==typeof t?t:function(){return t};if(a.x=a.y=0,Qu(a,function(n){n.r=+s(n.value)}),Qu(a,Mi),r){var f=r*(t?1:Math.max(2*a.r/c,2*a.r/l))/2;Qu(a,function(n){n.r+=f}),Qu(a,Mi),Qu(a,function(n){n.r-=f})}return _i(a,c/2,l/2,t?1:1/Math.max(2*a.r/c,2*a.r/l)),o}var t,e=ta.layout.hierarchy().sort(vi),r=0,u=[1,1];return n.size=function(t){return arguments.length?(u=t,n):u},n.radius=function(e){return arguments.length?(t=null==e||"function"==typeof e?e:+e,n):t},n.padding=function(t){return arguments.length?(r=+t,n):r},Gu(n,e)},ta.layout.tree=function(){function n(n,u){var s=o.call(this,n,u),f=s[0],h=t(f);if(Qu(h,e),h.parent.m=-h.z,Ku(h,r),l)Ku(f,i);else{var g=f,p=f,v=f;Ku(f,function(n){n.x<g.x&&(g=n),n.x>p.x&&(p=n),n.depth>v.depth&&(v=n)});var d=a(g,p)/2-g.x,m=c[0]/(p.x+a(p,g)/2+d),y=c[1]/(v.depth||1);Ku(f,function(n){n.x=(n.x+d)*m,n.y=n.depth*y})}return s}function t(n){for(var t,e={A:null,children:[n]},r=[e];null!=(t=r.pop());)for(var u,i=t.children,o=0,a=i.length;a>o;++o)r.push((i[o]=u={_:i[o],parent:t,children:(u=i[o].children)&&u.slice()||[],A:null,a:null,z:0,m:0,c:0,s:0,t:null,i:o}).a=u);return e.children[0]}function e(n){var t=n.children,e=n.parent.children,r=n.i?e[n.i-1]:null;if(t.length){Ni(n);var i=(t[0].z+t[t.length-1].z)/2;r?(n.z=r.z+a(n._,r._),n.m=n.z-i):n.z=i}else r&&(n.z=r.z+a(n._,r._));n.parent.A=u(n,r,n.parent.A||e[0])}function r(n){n._.x=n.z+n.parent.m,n.m+=n.parent.m}function u(n,t,e){if(t){for(var r,u=n,i=n,o=t,c=u.parent.children[0],l=u.m,s=i.m,f=o.m,h=c.m;o=Ei(o),u=ki(u),o&&u;)c=ki(c),i=Ei(i),i.a=n,r=o.z+f-u.z-l+a(o._,u._),r>0&&(Ai(Ci(o,n,e),n,r),l+=r,s+=r),f+=o.m,l+=u.m,h+=c.m,s+=i.m;o&&!Ei(i)&&(i.t=o,i.m+=f-s),u&&!ki(c)&&(c.t=u,c.m+=l-h,e=n)}return e}function i(n){n.x*=c[0],n.y=n.depth*c[1]}var o=ta.layout.hierarchy().sort(null).value(null),a=Si,c=[1,1],l=null;return n.separation=function(t){return arguments.length?(a=t,n):a},n.size=function(t){return arguments.length?(l=null==(c=t)?i:null,n):l?null:c},n.nodeSize=function(t){return arguments.length?(l=null==(c=t)?null:i,n):l?c:null},Gu(n,o)},ta.layout.cluster=function(){function n(n,i){var o,a=t.call(this,n,i),c=a[0],l=0;Qu(c,function(n){var t=n.children;t&&t.length?(n.x=qi(t),n.y=zi(t)):(n.x=o?l+=e(n,o):0,n.y=0,o=n)});var s=Li(c),f=Ti(c),h=s.x-e(s,f)/2,g=f.x+e(f,s)/2;return Qu(c,u?function(n){n.x=(n.x-c.x)*r[0],n.y=(c.y-n.y)*r[1]}:function(n){n.x=(n.x-h)/(g-h)*r[0],n.y=(1-(c.y?n.y/c.y:1))*r[1]}),a}var t=ta.layout.hierarchy().sort(null).value(null),e=Si,r=[1,1],u=!1;return n.separation=function(t){return arguments.length?(e=t,n):e},n.size=function(t){return arguments.length?(u=null==(r=t),n):u?null:r},n.nodeSize=function(t){return arguments.length?(u=null!=(r=t),n):u?r:null},Gu(n,t)},ta.layout.treemap=function(){function n(n,t){for(var e,r,u=-1,i=n.length;++u<i;)r=(e=n[u]).value*(0>t?0:t),e.area=isNaN(r)||0>=r?0:r}function t(e){var i=e.children;if(i&&i.length){var o,a,c,l=f(e),s=[],h=i.slice(),p=1/0,v="slice"===g?l.dx:"dice"===g?l.dy:"slice-dice"===g?1&e.depth?l.dy:l.dx:Math.min(l.dx,l.dy);for(n(h,l.dx*l.dy/e.value),s.area=0;(c=h.length)>0;)s.push(o=h[c-1]),s.area+=o.area,"squarify"!==g||(a=r(s,v))<=p?(h.pop(),p=a):(s.area-=s.pop().area,u(s,v,l,!1),v=Math.min(l.dx,l.dy),s.length=s.area=0,p=1/0);s.length&&(u(s,v,l,!0),s.length=s.area=0),i.forEach(t)}}function e(t){var r=t.children;if(r&&r.length){var i,o=f(t),a=r.slice(),c=[];for(n(a,o.dx*o.dy/t.value),c.area=0;i=a.pop();)c.push(i),c.area+=i.area,null!=i.z&&(u(c,i.z?o.dx:o.dy,o,!a.length),c.length=c.area=0);r.forEach(e)}}function r(n,t){for(var e,r=n.area,u=0,i=1/0,o=-1,a=n.length;++o<a;)(e=n[o].area)&&(i>e&&(i=e),e>u&&(u=e));return r*=r,t*=t,r?Math.max(t*u*p/r,r/(t*i*p)):1/0}function u(n,t,e,r){var u,i=-1,o=n.length,a=e.x,l=e.y,s=t?c(n.area/t):0;if(t==e.dx){for((r||s>e.dy)&&(s=e.dy);++i<o;)u=n[i],u.x=a,u.y=l,u.dy=s,a+=u.dx=Math.min(e.x+e.dx-a,s?c(u.area/s):0);u.z=!0,u.dx+=e.x+e.dx-a,e.y+=s,e.dy-=s}else{for((r||s>e.dx)&&(s=e.dx);++i<o;)u=n[i],u.x=a,u.y=l,u.dx=s,l+=u.dy=Math.min(e.y+e.dy-l,s?c(u.area/s):0);u.z=!1,u.dy+=e.y+e.dy-l,e.x+=s,e.dx-=s}}function i(r){var u=o||a(r),i=u[0];return i.x=0,i.y=0,i.dx=l[0],i.dy=l[1],o&&a.revalue(i),n([i],i.dx*i.dy/i.value),(o?e:t)(i),h&&(o=u),u}var o,a=ta.layout.hierarchy(),c=Math.round,l=[1,1],s=null,f=Ri,h=!1,g="squarify",p=.5*(1+Math.sqrt(5));
+return i.size=function(n){return arguments.length?(l=n,i):l},i.padding=function(n){function t(t){var e=n.call(i,t,t.depth);return null==e?Ri(t):Di(t,"number"==typeof e?[e,e,e,e]:e)}function e(t){return Di(t,n)}if(!arguments.length)return s;var r;return f=null==(s=n)?Ri:"function"==(r=typeof n)?t:"number"===r?(n=[n,n,n,n],e):e,i},i.round=function(n){return arguments.length?(c=n?Math.round:Number,i):c!=Number},i.sticky=function(n){return arguments.length?(h=n,o=null,i):h},i.ratio=function(n){return arguments.length?(p=n,i):p},i.mode=function(n){return arguments.length?(g=n+"",i):g},Gu(i,a)},ta.random={normal:function(n,t){var e=arguments.length;return 2>e&&(t=1),1>e&&(n=0),function(){var e,r,u;do e=2*Math.random()-1,r=2*Math.random()-1,u=e*e+r*r;while(!u||u>1);return n+t*e*Math.sqrt(-2*Math.log(u)/u)}},logNormal:function(){var n=ta.random.normal.apply(ta,arguments);return function(){return Math.exp(n())}},bates:function(n){var t=ta.random.irwinHall(n);return function(){return t()/n}},irwinHall:function(n){return function(){for(var t=0,e=0;n>e;e++)t+=Math.random();return t}}},ta.scale={};var ml={floor:y,ceil:y};ta.scale.linear=function(){return Ii([0,1],[0,1],mu,!1)};var yl={s:1,g:1,p:1,r:1,e:1};ta.scale.log=function(){return Ji(ta.scale.linear().domain([0,1]),10,!0,[1,10])};var Ml=ta.format(".0e"),xl={floor:function(n){return-Math.ceil(-n)},ceil:function(n){return-Math.floor(-n)}};ta.scale.pow=function(){return Gi(ta.scale.linear(),1,[0,1])},ta.scale.sqrt=function(){return ta.scale.pow().exponent(.5)},ta.scale.ordinal=function(){return Qi([],{t:"range",a:[[]]})},ta.scale.category10=function(){return ta.scale.ordinal().range(bl)},ta.scale.category20=function(){return ta.scale.ordinal().range(_l)},ta.scale.category20b=function(){return ta.scale.ordinal().range(wl)},ta.scale.category20c=function(){return ta.scale.ordinal().range(Sl)};var bl=[2062260,16744206,2924588,14034728,9725885,9197131,14907330,8355711,12369186,1556175].map(Mt),_l=[2062260,11454440,16744206,16759672,2924588,10018698,14034728,16750742,9725885,12955861,9197131,12885140,14907330,16234194,8355711,13092807,12369186,14408589,1556175,10410725].map(Mt),wl=[3750777,5395619,7040719,10264286,6519097,9216594,11915115,13556636,9202993,12426809,15186514,15190932,8666169,11356490,14049643,15177372,8077683,10834324,13528509,14589654].map(Mt),Sl=[3244733,7057110,10406625,13032431,15095053,16616764,16625259,16634018,3253076,7652470,10607003,13101504,7695281,10394312,12369372,14342891,6513507,9868950,12434877,14277081].map(Mt);ta.scale.quantile=function(){return no([],[])},ta.scale.quantize=function(){return to(0,1,[0,1])},ta.scale.threshold=function(){return eo([.5],[0,1])},ta.scale.identity=function(){return ro([0,1])},ta.svg={},ta.svg.arc=function(){function n(){var n=Math.max(0,+e.apply(this,arguments)),l=Math.max(0,+r.apply(this,arguments)),s=o.apply(this,arguments)-Ra,f=a.apply(this,arguments)-Ra,h=Math.abs(f-s),g=s>f?0:1;if(n>l&&(p=l,l=n,n=p),h>=Ta)return t(l,g)+(n?t(n,1-g):"")+"Z";var p,v,d,m,y,M,x,b,_,w,S,k,E=0,A=0,N=[];if((m=(+c.apply(this,arguments)||0)/2)&&(d=i===kl?Math.sqrt(n*n+l*l):+i.apply(this,arguments),g||(A*=-1),l&&(A=tt(d/l*Math.sin(m))),n&&(E=tt(d/n*Math.sin(m)))),l){y=l*Math.cos(s+A),M=l*Math.sin(s+A),x=l*Math.cos(f-A),b=l*Math.sin(f-A);var C=Math.abs(f-s-2*A)<=qa?0:1;if(A&&so(y,M,x,b)===g^C){var z=(s+f)/2;y=l*Math.cos(z),M=l*Math.sin(z),x=b=null}}else y=M=0;if(n){_=n*Math.cos(f-E),w=n*Math.sin(f-E),S=n*Math.cos(s+E),k=n*Math.sin(s+E);var q=Math.abs(s-f+2*E)<=qa?0:1;if(E&&so(_,w,S,k)===1-g^q){var L=(s+f)/2;_=n*Math.cos(L),w=n*Math.sin(L),S=k=null}}else _=w=0;if((p=Math.min(Math.abs(l-n)/2,+u.apply(this,arguments)))>.001){v=l>n^g?0:1;var T=null==S?[_,w]:null==x?[y,M]:Lr([y,M],[S,k],[x,b],[_,w]),R=y-T[0],D=M-T[1],P=x-T[0],U=b-T[1],j=1/Math.sin(Math.acos((R*P+D*U)/(Math.sqrt(R*R+D*D)*Math.sqrt(P*P+U*U)))/2),F=Math.sqrt(T[0]*T[0]+T[1]*T[1]);if(null!=x){var H=Math.min(p,(l-F)/(j+1)),O=fo(null==S?[_,w]:[S,k],[y,M],l,H,g),I=fo([x,b],[_,w],l,H,g);p===H?N.push("M",O[0],"A",H,",",H," 0 0,",v," ",O[1],"A",l,",",l," 0 ",1-g^so(O[1][0],O[1][1],I[1][0],I[1][1]),",",g," ",I[1],"A",H,",",H," 0 0,",v," ",I[0]):N.push("M",O[0],"A",H,",",H," 0 1,",v," ",I[0])}else N.push("M",y,",",M);if(null!=S){var Y=Math.min(p,(n-F)/(j-1)),Z=fo([y,M],[S,k],n,-Y,g),V=fo([_,w],null==x?[y,M]:[x,b],n,-Y,g);p===Y?N.push("L",V[0],"A",Y,",",Y," 0 0,",v," ",V[1],"A",n,",",n," 0 ",g^so(V[1][0],V[1][1],Z[1][0],Z[1][1]),",",1-g," ",Z[1],"A",Y,",",Y," 0 0,",v," ",Z[0]):N.push("L",V[0],"A",Y,",",Y," 0 0,",v," ",Z[0])}else N.push("L",_,",",w)}else N.push("M",y,",",M),null!=x&&N.push("A",l,",",l," 0 ",C,",",g," ",x,",",b),N.push("L",_,",",w),null!=S&&N.push("A",n,",",n," 0 ",q,",",1-g," ",S,",",k);return N.push("Z"),N.join("")}function t(n,t){return"M0,"+n+"A"+n+","+n+" 0 1,"+t+" 0,"+-n+"A"+n+","+n+" 0 1,"+t+" 0,"+n}var e=io,r=oo,u=uo,i=kl,o=ao,a=co,c=lo;return n.innerRadius=function(t){return arguments.length?(e=Et(t),n):e},n.outerRadius=function(t){return arguments.length?(r=Et(t),n):r},n.cornerRadius=function(t){return arguments.length?(u=Et(t),n):u},n.padRadius=function(t){return arguments.length?(i=t==kl?kl:Et(t),n):i},n.startAngle=function(t){return arguments.length?(o=Et(t),n):o},n.endAngle=function(t){return arguments.length?(a=Et(t),n):a},n.padAngle=function(t){return arguments.length?(c=Et(t),n):c},n.centroid=function(){var n=(+e.apply(this,arguments)+ +r.apply(this,arguments))/2,t=(+o.apply(this,arguments)+ +a.apply(this,arguments))/2-Ra;return[Math.cos(t)*n,Math.sin(t)*n]},n};var kl="auto";ta.svg.line=function(){return ho(y)};var El=ta.map({linear:go,"linear-closed":po,step:vo,"step-before":mo,"step-after":yo,basis:So,"basis-open":ko,"basis-closed":Eo,bundle:Ao,cardinal:bo,"cardinal-open":Mo,"cardinal-closed":xo,monotone:To});El.forEach(function(n,t){t.key=n,t.closed=/-closed$/.test(n)});var Al=[0,2/3,1/3,0],Nl=[0,1/3,2/3,0],Cl=[0,1/6,2/3,1/6];ta.svg.line.radial=function(){var n=ho(Ro);return n.radius=n.x,delete n.x,n.angle=n.y,delete n.y,n},mo.reverse=yo,yo.reverse=mo,ta.svg.area=function(){return Do(y)},ta.svg.area.radial=function(){var n=Do(Ro);return n.radius=n.x,delete n.x,n.innerRadius=n.x0,delete n.x0,n.outerRadius=n.x1,delete n.x1,n.angle=n.y,delete n.y,n.startAngle=n.y0,delete n.y0,n.endAngle=n.y1,delete n.y1,n},ta.svg.chord=function(){function n(n,a){var c=t(this,i,n,a),l=t(this,o,n,a);return"M"+c.p0+r(c.r,c.p1,c.a1-c.a0)+(e(c,l)?u(c.r,c.p1,c.r,c.p0):u(c.r,c.p1,l.r,l.p0)+r(l.r,l.p1,l.a1-l.a0)+u(l.r,l.p1,c.r,c.p0))+"Z"}function t(n,t,e,r){var u=t.call(n,e,r),i=a.call(n,u,r),o=c.call(n,u,r)-Ra,s=l.call(n,u,r)-Ra;return{r:i,a0:o,a1:s,p0:[i*Math.cos(o),i*Math.sin(o)],p1:[i*Math.cos(s),i*Math.sin(s)]}}function e(n,t){return n.a0==t.a0&&n.a1==t.a1}function r(n,t,e){return"A"+n+","+n+" 0 "+ +(e>qa)+",1 "+t}function u(n,t,e,r){return"Q 0,0 "+r}var i=mr,o=yr,a=Po,c=ao,l=co;return n.radius=function(t){return arguments.length?(a=Et(t),n):a},n.source=function(t){return arguments.length?(i=Et(t),n):i},n.target=function(t){return arguments.length?(o=Et(t),n):o},n.startAngle=function(t){return arguments.length?(c=Et(t),n):c},n.endAngle=function(t){return arguments.length?(l=Et(t),n):l},n},ta.svg.diagonal=function(){function n(n,u){var i=t.call(this,n,u),o=e.call(this,n,u),a=(i.y+o.y)/2,c=[i,{x:i.x,y:a},{x:o.x,y:a},o];return c=c.map(r),"M"+c[0]+"C"+c[1]+" "+c[2]+" "+c[3]}var t=mr,e=yr,r=Uo;return n.source=function(e){return arguments.length?(t=Et(e),n):t},n.target=function(t){return arguments.length?(e=Et(t),n):e},n.projection=function(t){return arguments.length?(r=t,n):r},n},ta.svg.diagonal.radial=function(){var n=ta.svg.diagonal(),t=Uo,e=n.projection;return n.projection=function(n){return arguments.length?e(jo(t=n)):t},n},ta.svg.symbol=function(){function n(n,r){return(zl.get(t.call(this,n,r))||Oo)(e.call(this,n,r))}var t=Ho,e=Fo;return n.type=function(e){return arguments.length?(t=Et(e),n):t},n.size=function(t){return arguments.length?(e=Et(t),n):e},n};var zl=ta.map({circle:Oo,cross:function(n){var t=Math.sqrt(n/5)/2;return"M"+-3*t+","+-t+"H"+-t+"V"+-3*t+"H"+t+"V"+-t+"H"+3*t+"V"+t+"H"+t+"V"+3*t+"H"+-t+"V"+t+"H"+-3*t+"Z"},diamond:function(n){var t=Math.sqrt(n/(2*Ll)),e=t*Ll;return"M0,"+-t+"L"+e+",0 0,"+t+" "+-e+",0Z"},square:function(n){var t=Math.sqrt(n)/2;return"M"+-t+","+-t+"L"+t+","+-t+" "+t+","+t+" "+-t+","+t+"Z"},"triangle-down":function(n){var t=Math.sqrt(n/ql),e=t*ql/2;return"M0,"+e+"L"+t+","+-e+" "+-t+","+-e+"Z"},"triangle-up":function(n){var t=Math.sqrt(n/ql),e=t*ql/2;return"M0,"+-e+"L"+t+","+e+" "+-t+","+e+"Z"}});ta.svg.symbolTypes=zl.keys();var ql=Math.sqrt(3),Ll=Math.tan(30*Da);_a.transition=function(n){for(var t,e,r=Tl||++Ul,u=Xo(n),i=[],o=Rl||{time:Date.now(),ease:Su,delay:0,duration:250},a=-1,c=this.length;++a<c;){i.push(t=[]);for(var l=this[a],s=-1,f=l.length;++s<f;)(e=l[s])&&$o(e,s,u,r,o),t.push(e)}return Yo(i,u,r)},_a.interrupt=function(n){return this.each(null==n?Dl:Io(Xo(n)))};var Tl,Rl,Dl=Io(Xo()),Pl=[],Ul=0;Pl.call=_a.call,Pl.empty=_a.empty,Pl.node=_a.node,Pl.size=_a.size,ta.transition=function(n,t){return n&&n.transition?Tl?n.transition(t):n:ta.selection().transition(n)},ta.transition.prototype=Pl,Pl.select=function(n){var t,e,r,u=this.id,i=this.namespace,o=[];n=N(n);for(var a=-1,c=this.length;++a<c;){o.push(t=[]);for(var l=this[a],s=-1,f=l.length;++s<f;)(r=l[s])&&(e=n.call(r,r.__data__,s,a))?("__data__"in r&&(e.__data__=r.__data__),$o(e,s,i,u,r[i][u]),t.push(e)):t.push(null)}return Yo(o,i,u)},Pl.selectAll=function(n){var t,e,r,u,i,o=this.id,a=this.namespace,c=[];n=C(n);for(var l=-1,s=this.length;++l<s;)for(var f=this[l],h=-1,g=f.length;++h<g;)if(r=f[h]){i=r[a][o],e=n.call(r,r.__data__,h,l),c.push(t=[]);for(var p=-1,v=e.length;++p<v;)(u=e[p])&&$o(u,p,a,o,i),t.push(u)}return Yo(c,a,o)},Pl.filter=function(n){var t,e,r,u=[];"function"!=typeof n&&(n=O(n));for(var i=0,o=this.length;o>i;i++){u.push(t=[]);for(var e=this[i],a=0,c=e.length;c>a;a++)(r=e[a])&&n.call(r,r.__data__,a,i)&&t.push(r)}return Yo(u,this.namespace,this.id)},Pl.tween=function(n,t){var e=this.id,r=this.namespace;return arguments.length<2?this.node()[r][e].tween.get(n):Y(this,null==t?function(t){t[r][e].tween.remove(n)}:function(u){u[r][e].tween.set(n,t)})},Pl.attr=function(n,t){function e(){this.removeAttribute(a)}function r(){this.removeAttributeNS(a.space,a.local)}function u(n){return null==n?e:(n+="",function(){var t,e=this.getAttribute(a);return e!==n&&(t=o(e,n),function(n){this.setAttribute(a,t(n))})})}function i(n){return null==n?r:(n+="",function(){var t,e=this.getAttributeNS(a.space,a.local);return e!==n&&(t=o(e,n),function(n){this.setAttributeNS(a.space,a.local,t(n))})})}if(arguments.length<2){for(t in n)this.attr(t,n[t]);return this}var o="transform"==n?Hu:mu,a=ta.ns.qualify(n);return Zo(this,"attr."+n,t,a.local?i:u)},Pl.attrTween=function(n,t){function e(n,e){var r=t.call(this,n,e,this.getAttribute(u));return r&&function(n){this.setAttribute(u,r(n))}}function r(n,e){var r=t.call(this,n,e,this.getAttributeNS(u.space,u.local));return r&&function(n){this.setAttributeNS(u.space,u.local,r(n))}}var u=ta.ns.qualify(n);return this.tween("attr."+n,u.local?r:e)},Pl.style=function(n,e,r){function u(){this.style.removeProperty(n)}function i(e){return null==e?u:(e+="",function(){var u,i=t(this).getComputedStyle(this,null).getPropertyValue(n);return i!==e&&(u=mu(i,e),function(t){this.style.setProperty(n,u(t),r)})})}var o=arguments.length;if(3>o){if("string"!=typeof n){2>o&&(e="");for(r in n)this.style(r,n[r],e);return this}r=""}return Zo(this,"style."+n,e,i)},Pl.styleTween=function(n,e,r){function u(u,i){var o=e.call(this,u,i,t(this).getComputedStyle(this,null).getPropertyValue(n));return o&&function(t){this.style.setProperty(n,o(t),r)}}return arguments.length<3&&(r=""),this.tween("style."+n,u)},Pl.text=function(n){return Zo(this,"text",n,Vo)},Pl.remove=function(){var n=this.namespace;return this.each("end.transition",function(){var t;this[n].count<2&&(t=this.parentNode)&&t.removeChild(this)})},Pl.ease=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].ease:("function"!=typeof n&&(n=ta.ease.apply(ta,arguments)),Y(this,function(r){r[e][t].ease=n}))},Pl.delay=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].delay:Y(this,"function"==typeof n?function(r,u,i){r[e][t].delay=+n.call(r,r.__data__,u,i)}:(n=+n,function(r){r[e][t].delay=n}))},Pl.duration=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].duration:Y(this,"function"==typeof n?function(r,u,i){r[e][t].duration=Math.max(1,n.call(r,r.__data__,u,i))}:(n=Math.max(1,n),function(r){r[e][t].duration=n}))},Pl.each=function(n,t){var e=this.id,r=this.namespace;if(arguments.length<2){var u=Rl,i=Tl;try{Tl=e,Y(this,function(t,u,i){Rl=t[r][e],n.call(t,t.__data__,u,i)})}finally{Rl=u,Tl=i}}else Y(this,function(u){var i=u[r][e];(i.event||(i.event=ta.dispatch("start","end","interrupt"))).on(n,t)});return this},Pl.transition=function(){for(var n,t,e,r,u=this.id,i=++Ul,o=this.namespace,a=[],c=0,l=this.length;l>c;c++){a.push(n=[]);for(var t=this[c],s=0,f=t.length;f>s;s++)(e=t[s])&&(r=e[o][u],$o(e,s,o,i,{time:r.time,ease:r.ease,delay:r.delay+r.duration,duration:r.duration})),n.push(e)}return Yo(a,o,i)},ta.svg.axis=function(){function n(n){n.each(function(){var n,l=ta.select(this),s=this.__chart__||e,f=this.__chart__=e.copy(),h=null==c?f.ticks?f.ticks.apply(f,a):f.domain():c,g=null==t?f.tickFormat?f.tickFormat.apply(f,a):y:t,p=l.selectAll(".tick").data(h,f),v=p.enter().insert("g",".domain").attr("class","tick").style("opacity",Ca),d=ta.transition(p.exit()).style("opacity",Ca).remove(),m=ta.transition(p.order()).style("opacity",1),M=Math.max(u,0)+o,x=Ui(f),b=l.selectAll(".domain").data([0]),_=(b.enter().append("path").attr("class","domain"),ta.transition(b));v.append("line"),v.append("text");var w,S,k,E,A=v.select("line"),N=m.select("line"),C=p.select("text").text(g),z=v.select("text"),q=m.select("text"),L="top"===r||"left"===r?-1:1;if("bottom"===r||"top"===r?(n=Bo,w="x",k="y",S="x2",E="y2",C.attr("dy",0>L?"0em":".71em").style("text-anchor","middle"),_.attr("d","M"+x[0]+","+L*i+"V0H"+x[1]+"V"+L*i)):(n=Wo,w="y",k="x",S="y2",E="x2",C.attr("dy",".32em").style("text-anchor",0>L?"end":"start"),_.attr("d","M"+L*i+","+x[0]+"H0V"+x[1]+"H"+L*i)),A.attr(E,L*u),z.attr(k,L*M),N.attr(S,0).attr(E,L*u),q.attr(w,0).attr(k,L*M),f.rangeBand){var T=f,R=T.rangeBand()/2;s=f=function(n){return T(n)+R}}else s.rangeBand?s=f:d.call(n,f,s);v.call(n,s,f),m.call(n,f,f)})}var t,e=ta.scale.linear(),r=jl,u=6,i=6,o=3,a=[10],c=null;return n.scale=function(t){return arguments.length?(e=t,n):e},n.orient=function(t){return arguments.length?(r=t in Fl?t+"":jl,n):r},n.ticks=function(){return arguments.length?(a=arguments,n):a},n.tickValues=function(t){return arguments.length?(c=t,n):c},n.tickFormat=function(e){return arguments.length?(t=e,n):t},n.tickSize=function(t){var e=arguments.length;return e?(u=+t,i=+arguments[e-1],n):u},n.innerTickSize=function(t){return arguments.length?(u=+t,n):u},n.outerTickSize=function(t){return arguments.length?(i=+t,n):i},n.tickPadding=function(t){return arguments.length?(o=+t,n):o},n.tickSubdivide=function(){return arguments.length&&n},n};var jl="bottom",Fl={top:1,right:1,bottom:1,left:1};ta.svg.brush=function(){function n(t){t.each(function(){var t=ta.select(this).style("pointer-events","all").style("-webkit-tap-highlight-color","rgba(0,0,0,0)").on("mousedown.brush",i).on("touchstart.brush",i),o=t.selectAll(".background").data([0]);o.enter().append("rect").attr("class","background").style("visibility","hidden").style("cursor","crosshair"),t.selectAll(".extent").data([0]).enter().append("rect").attr("class","extent").style("cursor","move");var a=t.selectAll(".resize").data(v,y);a.exit().remove(),a.enter().append("g").attr("class",function(n){return"resize "+n}).style("cursor",function(n){return Hl[n]}).append("rect").attr("x",function(n){return/[ew]$/.test(n)?-3:null}).attr("y",function(n){return/^[ns]/.test(n)?-3:null}).attr("width",6).attr("height",6).style("visibility","hidden"),a.style("display",n.empty()?"none":null);var c,f=ta.transition(t),h=ta.transition(o);l&&(c=Ui(l),h.attr("x",c[0]).attr("width",c[1]-c[0]),r(f)),s&&(c=Ui(s),h.attr("y",c[0]).attr("height",c[1]-c[0]),u(f)),e(f)})}function e(n){n.selectAll(".resize").attr("transform",function(n){return"translate("+f[+/e$/.test(n)]+","+h[+/^s/.test(n)]+")"})}function r(n){n.select(".extent").attr("x",f[0]),n.selectAll(".extent,.n>rect,.s>rect").attr("width",f[1]-f[0])}function u(n){n.select(".extent").attr("y",h[0]),n.selectAll(".extent,.e>rect,.w>rect").attr("height",h[1]-h[0])}function i(){function i(){32==ta.event.keyCode&&(C||(M=null,q[0]-=f[1],q[1]-=h[1],C=2),S())}function v(){32==ta.event.keyCode&&2==C&&(q[0]+=f[1],q[1]+=h[1],C=0,S())}function d(){var n=ta.mouse(b),t=!1;x&&(n[0]+=x[0],n[1]+=x[1]),C||(ta.event.altKey?(M||(M=[(f[0]+f[1])/2,(h[0]+h[1])/2]),q[0]=f[+(n[0]<M[0])],q[1]=h[+(n[1]<M[1])]):M=null),A&&m(n,l,0)&&(r(k),t=!0),N&&m(n,s,1)&&(u(k),t=!0),t&&(e(k),w({type:"brush",mode:C?"move":"resize"}))}function m(n,t,e){var r,u,i=Ui(t),c=i[0],l=i[1],s=q[e],v=e?h:f,d=v[1]-v[0];return C&&(c-=s,l-=d+s),r=(e?p:g)?Math.max(c,Math.min(l,n[e])):n[e],C?u=(r+=s)+d:(M&&(s=Math.max(c,Math.min(l,2*M[e]-r))),r>s?(u=r,r=s):u=s),v[0]!=r||v[1]!=u?(e?a=null:o=null,v[0]=r,v[1]=u,!0):void 0}function y(){d(),k.style("pointer-events","all").selectAll(".resize").style("display",n.empty()?"none":null),ta.select("body").style("cursor",null),L.on("mousemove.brush",null).on("mouseup.brush",null).on("touchmove.brush",null).on("touchend.brush",null).on("keydown.brush",null).on("keyup.brush",null),z(),w({type:"brushend"})}var M,x,b=this,_=ta.select(ta.event.target),w=c.of(b,arguments),k=ta.select(b),E=_.datum(),A=!/^(n|s)$/.test(E)&&l,N=!/^(e|w)$/.test(E)&&s,C=_.classed("extent"),z=W(b),q=ta.mouse(b),L=ta.select(t(b)).on("keydown.brush",i).on("keyup.brush",v);if(ta.event.changedTouches?L.on("touchmove.brush",d).on("touchend.brush",y):L.on("mousemove.brush",d).on("mouseup.brush",y),k.interrupt().selectAll("*").interrupt(),C)q[0]=f[0]-q[0],q[1]=h[0]-q[1];else if(E){var T=+/w$/.test(E),R=+/^n/.test(E);x=[f[1-T]-q[0],h[1-R]-q[1]],q[0]=f[T],q[1]=h[R]}else ta.event.altKey&&(M=q.slice());k.style("pointer-events","none").selectAll(".resize").style("display",null),ta.select("body").style("cursor",_.style("cursor")),w({type:"brushstart"}),d()}var o,a,c=E(n,"brushstart","brush","brushend"),l=null,s=null,f=[0,0],h=[0,0],g=!0,p=!0,v=Ol[0];return n.event=function(n){n.each(function(){var n=c.of(this,arguments),t={x:f,y:h,i:o,j:a},e=this.__chart__||t;this.__chart__=t,Tl?ta.select(this).transition().each("start.brush",function(){o=e.i,a=e.j,f=e.x,h=e.y,n({type:"brushstart"})}).tween("brush:brush",function(){var e=yu(f,t.x),r=yu(h,t.y);return o=a=null,function(u){f=t.x=e(u),h=t.y=r(u),n({type:"brush",mode:"resize"})}}).each("end.brush",function(){o=t.i,a=t.j,n({type:"brush",mode:"resize"}),n({type:"brushend"})}):(n({type:"brushstart"}),n({type:"brush",mode:"resize"}),n({type:"brushend"}))})},n.x=function(t){return arguments.length?(l=t,v=Ol[!l<<1|!s],n):l},n.y=function(t){return arguments.length?(s=t,v=Ol[!l<<1|!s],n):s},n.clamp=function(t){return arguments.length?(l&&s?(g=!!t[0],p=!!t[1]):l?g=!!t:s&&(p=!!t),n):l&&s?[g,p]:l?g:s?p:null},n.extent=function(t){var e,r,u,i,c;return arguments.length?(l&&(e=t[0],r=t[1],s&&(e=e[0],r=r[0]),o=[e,r],l.invert&&(e=l(e),r=l(r)),e>r&&(c=e,e=r,r=c),(e!=f[0]||r!=f[1])&&(f=[e,r])),s&&(u=t[0],i=t[1],l&&(u=u[1],i=i[1]),a=[u,i],s.invert&&(u=s(u),i=s(i)),u>i&&(c=u,u=i,i=c),(u!=h[0]||i!=h[1])&&(h=[u,i])),n):(l&&(o?(e=o[0],r=o[1]):(e=f[0],r=f[1],l.invert&&(e=l.invert(e),r=l.invert(r)),e>r&&(c=e,e=r,r=c))),s&&(a?(u=a[0],i=a[1]):(u=h[0],i=h[1],s.invert&&(u=s.invert(u),i=s.invert(i)),u>i&&(c=u,u=i,i=c))),l&&s?[[e,u],[r,i]]:l?[e,r]:s&&[u,i])},n.clear=function(){return n.empty()||(f=[0,0],h=[0,0],o=a=null),n},n.empty=function(){return!!l&&f[0]==f[1]||!!s&&h[0]==h[1]},ta.rebind(n,c,"on")};var Hl={n:"ns-resize",e:"ew-resize",s:"ns-resize",w:"ew-resize",nw:"nwse-resize",ne:"nesw-resize",se:"nwse-resize",sw:"nesw-resize"},Ol=[["n","e","s","w","nw","ne","se","sw"],["e","w"],["n","s"],[]],Il=ac.format=gc.timeFormat,Yl=Il.utc,Zl=Yl("%Y-%m-%dT%H:%M:%S.%LZ");Il.iso=Date.prototype.toISOString&&+new Date("2000-01-01T00:00:00.000Z")?Jo:Zl,Jo.parse=function(n){var t=new Date(n);return isNaN(t)?null:t},Jo.toString=Zl.toString,ac.second=Ft(function(n){return new cc(1e3*Math.floor(n/1e3))},function(n,t){n.setTime(n.getTime()+1e3*Math.floor(t))},function(n){return n.getSeconds()}),ac.seconds=ac.second.range,ac.seconds.utc=ac.second.utc.range,ac.minute=Ft(function(n){return new cc(6e4*Math.floor(n/6e4))},function(n,t){n.setTime(n.getTime()+6e4*Math.floor(t))},function(n){return n.getMinutes()}),ac.minutes=ac.minute.range,ac.minutes.utc=ac.minute.utc.range,ac.hour=Ft(function(n){var t=n.getTimezoneOffset()/60;return new cc(36e5*(Math.floor(n/36e5-t)+t))},function(n,t){n.setTime(n.getTime()+36e5*Math.floor(t))},function(n){return n.getHours()}),ac.hours=ac.hour.range,ac.hours.utc=ac.hour.utc.range,ac.month=Ft(function(n){return n=ac.day(n),n.setDate(1),n},function(n,t){n.setMonth(n.getMonth()+t)},function(n){return n.getMonth()}),ac.months=ac.month.range,ac.months.utc=ac.month.utc.range;var Vl=[1e3,5e3,15e3,3e4,6e4,3e5,9e5,18e5,36e5,108e5,216e5,432e5,864e5,1728e5,6048e5,2592e6,7776e6,31536e6],Xl=[[ac.second,1],[ac.second,5],[ac.second,15],[ac.second,30],[ac.minute,1],[ac.minute,5],[ac.minute,15],[ac.minute,30],[ac.hour,1],[ac.hour,3],[ac.hour,6],[ac.hour,12],[ac.day,1],[ac.day,2],[ac.week,1],[ac.month,1],[ac.month,3],[ac.year,1]],$l=Il.multi([[".%L",function(n){return n.getMilliseconds()}],[":%S",function(n){return n.getSeconds()}],["%I:%M",function(n){return n.getMinutes()}],["%I %p",function(n){return n.getHours()}],["%a %d",function(n){return n.getDay()&&1!=n.getDate()}],["%b %d",function(n){return 1!=n.getDate()}],["%B",function(n){return n.getMonth()}],["%Y",Ne]]),Bl={range:function(n,t,e){return ta.range(Math.ceil(n/e)*e,+t,e).map(Ko)},floor:y,ceil:y};Xl.year=ac.year,ac.scale=function(){return Go(ta.scale.linear(),Xl,$l)};var Wl=Xl.map(function(n){return[n[0].utc,n[1]]}),Jl=Yl.multi([[".%L",function(n){return n.getUTCMilliseconds()}],[":%S",function(n){return n.getUTCSeconds()}],["%I:%M",function(n){return n.getUTCMinutes()}],["%I %p",function(n){return n.getUTCHours()}],["%a %d",function(n){return n.getUTCDay()&&1!=n.getUTCDate()}],["%b %d",function(n){return 1!=n.getUTCDate()}],["%B",function(n){return n.getUTCMonth()}],["%Y",Ne]]);Wl.year=ac.year.utc,ac.scale.utc=function(){return Go(ta.scale.linear(),Wl,Jl)},ta.text=At(function(n){return n.responseText}),ta.json=function(n,t){return Nt(n,"application/json",Qo,t)},ta.html=function(n,t){return Nt(n,"text/html",na,t)},ta.xml=At(function(n){return n.responseXML}),"function"==typeof define&&define.amd?define(ta):"object"==typeof module&&module.exports&&(module.exports=ta),this.d3=ta}();
diff --git a/modules/http/static/d3.spdx b/modules/http/static/d3.spdx
new file mode 100644
index 0000000..95477b1
--- /dev/null
+++ b/modules/http/static/d3.spdx
@@ -0,0 +1,12 @@
+SPDXVersion: SPDX-2.1
+DataLicense: CC0-1.0
+SPDXID: SPDXRef-DOCUMENT
+DocumentName: d3js
+DocumentNamespace: http://spdx.org/spdxdocs/spdx-v2.1-d849c611-6d18-4c73-9318-f01eab74a036
+
+PackageName: d3js
+PackageVersion: 3.5.6
+PackageDownloadLocation: https://github.com/d3/d3/releases/download/v3.5.6/d3.zip#d3.min.js
+PackageChecksum: SHA256: 3865a5ee7b9f91126f2ef1121a7635e57bd820c9dbc384c2c48626b93a13d3f6
+PackageOriginator: Person: Michael Bostock (mike@ocks.org)
+PackageLicenseDeclared: BSD-3-Clause
diff --git a/modules/http/static/datamaps.world.min.js b/modules/http/static/datamaps.world.min.js
new file mode 100644
index 0000000..39e0e0a
--- /dev/null
+++ b/modules/http/static/datamaps.world.min.js
@@ -0,0 +1,3 @@
+/* SPDX-License-Identifier: MIT */
+!function(){function a(a,b,c){return this.svg=m.select(a).append("svg").attr("width",c||a.offsetWidth).attr("data-width",c||a.offsetWidth).attr("class","datamap").attr("height",b||a.offsetHeight).style("overflow","hidden"),this.options.responsive&&(m.select(this.options.element).style({position:"relative","padding-bottom":"60%"}),m.select(this.options.element).select("svg").style({position:"absolute",width:"100%",height:"100%"}),m.select(this.options.element).select("svg").select("g").selectAll("path").style("vector-effect","non-scaling-stroke")),this.svg}function b(a,b){var c,d,e=b.width||a.offsetWidth,f=b.height||a.offsetHeight,g=this.svg;return b&&"undefined"==typeof b.scope&&(b.scope="world"),"usa"===b.scope?c=m.geo.albersUsa().scale(e).translate([e/2,f/2]):"world"===b.scope&&(c=m.geo[b.projection]().scale((e+1)/2/Math.PI).translate([e/2,f/("mercator"===b.projection?1.45:1.8)])),"orthographic"===b.projection&&(g.append("defs").append("path").datum({type:"Sphere"}).attr("id","sphere").attr("d",d),g.append("use").attr("class","stroke").attr("xlink:href","#sphere"),g.append("use").attr("class","fill").attr("xlink:href","#sphere"),c.scale(250).clipAngle(90).rotate(b.projectionConfig.rotation)),d=m.geo.path().projection(c),{path:d,projection:c}}function c(){m.select(".datamaps-style-block").empty()&&m.select("head").append("style").attr("class","datamaps-style-block").html('.datamap path.datamaps-graticule { fill: none; stroke: #777; stroke-width: 0.5px; stroke-opacity: .5; pointer-events: none; } .datamap .labels {pointer-events: none;} .datamap path {stroke: #FFFFFF; stroke-width: 1px;} .datamaps-legend dt, .datamaps-legend dd { float: left; margin: 0 3px 0 0;} .datamaps-legend dd {width: 20px; margin-right: 6px; border-radius: 3px;} .datamaps-legend {padding-bottom: 20px; z-index: 1001; position: absolute; left: 4px; font-size: 12px; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;} .datamaps-hoverover {display: none; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; } .hoverinfo {padding: 4px; border-radius: 1px; background-color: #FFF; box-shadow: 1px 1px 5px #CCC; font-size: 12px; border: 1px solid #CCC; } .hoverinfo hr {border:1px dotted #CCC; }')}function d(a){var b=this.options.fills,c=this.options.data||{},d=this.options.geographyConfig,e=this.svg.select("g.datamaps-subunits");e.empty()&&(e=this.addLayer("datamaps-subunits",null,!0));var f=n.feature(a,a.objects[this.options.scope]).features;d.hideAntarctica&&(f=f.filter(function(a){return"ATA"!==a.id}));var g=e.selectAll("path.datamaps-subunit").data(f);g.enter().append("path").attr("d",this.path).attr("class",function(a){return"datamaps-subunit "+a.id}).attr("data-info",function(a){return JSON.stringify(c[a.id])}).style("fill",function(a){var d;return c[a.id]&&(d=b[c[a.id].fillKey]),d||b.defaultFill}).style("stroke-width",d.borderWidth).style("stroke",d.borderColor)}function e(){function a(){this.parentNode.appendChild(this)}var b=this.svg,c=this,d=this.options.geographyConfig;(d.highlightOnHover||d.popupOnHover)&&b.selectAll(".datamaps-subunit").on("mouseover",function(e){var f=m.select(this);if(d.highlightOnHover){var g={fill:f.style("fill"),stroke:f.style("stroke"),"stroke-width":f.style("stroke-width"),"fill-opacity":f.style("fill-opacity")};f.style("fill",d.highlightFillColor).style("stroke",d.highlightBorderColor).style("stroke-width",d.highlightBorderWidth).style("fill-opacity",d.highlightFillOpacity).attr("data-previousAttributes",JSON.stringify(g)),/((MSIE)|(Trident))/.test||a.call(this)}d.popupOnHover&&c.updatePopup(f,e,d,b)}).on("mouseout",function(){var a=m.select(this);if(d.highlightOnHover){var b=JSON.parse(a.attr("data-previousAttributes"));for(var c in b)a.style(c,b[c])}a.on("mousemove",null),m.selectAll(".datamaps-hoverover").style("display","none")})}function f(a,b){if(b=b||{},this.options.fills){var c="<dl>",d="";b.legendTitle&&(c="<h2>"+b.legendTitle+"</h2>"+c);for(var e in this.options.fills){if("defaultFill"===e){if(!b.defaultFillName)continue;d=b.defaultFillName}else d=b.labels&&b.labels[e]?b.labels[e]:e+": ";c+="<dt>"+d+"</dt>",c+='<dd style="background-color:'+this.options.fills[e]+'">&nbsp;</dd>'}c+="</dl>",m.select(this.options.element).append("div").attr("class","datamaps-legend").html(c)}}function g(){var a=m.geo.graticule();this.svg.insert("path",".datamaps-subunits").datum(a).attr("class","datamaps-graticule").attr("d",this.path)}function h(a,b,c){var d=this;if(this.svg,!b||b&&!b.slice)throw"Datamaps Error - arcs must be an array";"undefined"==typeof c&&(c=o.arcConfig);var e=a.selectAll("path.datamaps-arc").data(b,JSON.stringify),f=m.geo.path().projection(d.projection),g=m.geo.greatArc().source(function(a){return[a.origin.longitude,a.origin.latitude]}).target(function(a){return[a.destination.longitude,a.destination.latitude]});e.enter().append("svg:path").attr("class","datamaps-arc").style("stroke-linecap","round").style("stroke",function(a){return a.options&&a.options.strokeColor?a.options.strokeColor:c.strokeColor}).style("fill","none").style("stroke-width",function(a){return a.options&&a.options.strokeWidth?a.options.strokeWidth:c.strokeWidth}).attr("d",function(a){var b=d.latLngToXY(a.origin.latitude,a.origin.longitude),e=d.latLngToXY(a.destination.latitude,a.destination.longitude),h=[(b[0]+e[0])/2,(b[1]+e[1])/2];return c.greatArc?f(g(a)):"M"+b[0]+","+b[1]+"S"+(h[0]+50*c.arcSharpness)+","+(h[1]-75*c.arcSharpness)+","+e[0]+","+e[1]}).transition().delay(100).style("fill",function(){var a=this.getTotalLength();return this.style.transition=this.style.WebkitTransition="none",this.style.strokeDasharray=a+" "+a,this.style.strokeDashoffset=a,this.getBoundingClientRect(),this.style.transition=this.style.WebkitTransition="stroke-dashoffset "+c.animationSpeed+"ms ease-out",this.style.strokeDashoffset="0","none"}),e.exit().transition().style("opacity",0).remove()}function i(a,b){var c=this;b=b||{};var d=this.projection([-67.707617,42.722131]);this.svg.selectAll(".datamaps-subunit").attr("data-foo",function(e){var f=c.path.centroid(e),g=7.5,h=5;["FL","KY","MI"].indexOf(e.id)>-1&&(g=-2.5),"NY"===e.id&&(g=-1),"MI"===e.id&&(h=18),"LA"===e.id&&(g=13);var i,j;i=f[0]-g,j=f[1]+h;var k=["VT","NH","MA","RI","CT","NJ","DE","MD","DC"].indexOf(e.id);if(k>-1){var l=d[1];i=d[0],j=l+k*(2+(b.fontSize||12)),a.append("line").attr("x1",i-3).attr("y1",j-5).attr("x2",f[0]).attr("y2",f[1]).style("stroke",b.labelColor||"#000").style("stroke-width",b.lineWidth||1)}return a.append("text").attr("x",i).attr("y",j).style("font-size",(b.fontSize||10)+"px").style("font-family",b.fontFamily||"Verdana").style("fill",b.labelColor||"#000").text(e.id),"bar"})}function j(a,b,c){function d(a){return"undefined"!=typeof a&&"undefined"!=typeof a.latitude&&"undefined"!=typeof a.longitude}var e=this,f=this.options.fills,g=this.svg;if(!b||b&&!b.slice)throw"Datamaps Error - bubbles must be an array";var h=a.selectAll("circle.datamaps-bubble").data(b,JSON.stringify);h.enter().append("svg:circle").attr("class","datamaps-bubble").attr("cx",function(a){var b;return d(a)?b=e.latLngToXY(a.latitude,a.longitude):a.centered&&(b=e.path.centroid(g.select("path."+a.centered).data()[0])),b?b[0]:void 0}).attr("cy",function(a){var b;return d(a)?b=e.latLngToXY(a.latitude,a.longitude):a.centered&&(b=e.path.centroid(g.select("path."+a.centered).data()[0])),b?b[1]:void 0}).attr("r",0).attr("data-info",function(a){return JSON.stringify(a)}).style("stroke",function(a){return"undefined"!=typeof a.borderColor?a.borderColor:c.borderColor}).style("stroke-width",function(a){return"undefined"!=typeof a.borderWidth?a.borderWidth:c.borderWidth}).style("fill-opacity",function(a){return"undefined"!=typeof a.fillOpacity?a.fillOpacity:c.fillOpacity}).style("fill",function(a){var b=f[a.fillKey];return b||f.defaultFill}).on("mouseover",function(a){var b=m.select(this);if(c.highlightOnHover){var d={fill:b.style("fill"),stroke:b.style("stroke"),"stroke-width":b.style("stroke-width"),"fill-opacity":b.style("fill-opacity")};b.style("fill",c.highlightFillColor).style("stroke",c.highlightBorderColor).style("stroke-width",c.highlightBorderWidth).style("fill-opacity",c.highlightFillOpacity).attr("data-previousAttributes",JSON.stringify(d))}c.popupOnHover&&e.updatePopup(b,a,c,g)}).on("mouseout",function(){var a=m.select(this);if(c.highlightOnHover){var b=JSON.parse(a.attr("data-previousAttributes"));for(var d in b)a.style(d,b[d])}m.selectAll(".datamaps-hoverover").style("display","none")}).transition().duration(400).attr("r",function(a){return a.radius}),h.exit().transition().delay(c.exitDelay).attr("r",0).remove()}function k(a){return Array.prototype.slice.call(arguments,1).forEach(function(b){if(b)for(var c in b)null==a[c]&&(a[c]=b[c])}),a}function l(b){if("undefined"==typeof m||"undefined"==typeof n)throw new Error("Include d3.js (v3.0.3 or greater) and topojson on this page before creating a new map");return this.options=k(b,o),this.options.geographyConfig=k(b.geographyConfig,o.geographyConfig),this.options.projectionConfig=k(b.projectionConfig,o.projectionConfig),this.options.bubblesConfig=k(b.bubblesConfig,o.bubblesConfig),this.options.arcConfig=k(b.arcConfig,o.arcConfig),m.select(this.options.element).select("svg").length>0&&a.call(this,this.options.element,this.options.height,this.options.width),this.addPlugin("bubbles",j),this.addPlugin("legend",f),this.addPlugin("arc",h),this.addPlugin("labels",i),this.addPlugin("graticule",g),this.options.disableDefaultStyles||c(),this.draw()}var m=window.d3,n=window.topojson,o={scope:"world",responsive:!1,setProjection:b,projection:"equirectangular",dataType:"json",done:function(){},fills:{defaultFill:"#ABDDA4"},geographyConfig:{dataUrl:null,hideAntarctica:!0,borderWidth:1,borderColor:"#FDFDFD",popupTemplate:function(a){return'<div class="hoverinfo"><strong>'+a.properties.name+"</strong></div>"},popupOnHover:!0,highlightOnHover:!0,highlightFillColor:"#FC8D59",highlightBorderColor:"rgba(250, 15, 160, 0.2)",highlightBorderWidth:2},projectionConfig:{rotation:[97,0]},bubblesConfig:{borderWidth:2,borderColor:"#FFFFFF",popupOnHover:!0,popupTemplate:function(a,b){return'<div class="hoverinfo"><strong>'+b.name+"</strong></div>"},fillOpacity:.75,animate:!0,highlightOnHover:!0,highlightFillColor:"#FC8D59",highlightBorderColor:"rgba(250, 15, 160, 0.2)",highlightBorderWidth:2,highlightFillOpacity:.85,exitDelay:100},arcConfig:{strokeColor:"#DD1C77",strokeWidth:1,arcSharpness:1,animationSpeed:600}};l.prototype.resize=function(){var a=this,b=a.options;if(b.responsive){var c="-webkit-transform"in document.body.style?"-webkit-":"-moz-transform"in document.body.style?"-moz-":"-ms-transform"in document.body.style?"-ms-":"",d=b.element.clientWidth,e=m.select(b.element).select("svg").attr("data-width");m.select(b.element).select("svg").selectAll("g").style(c+"transform","scale("+d/e+")")}},l.prototype.draw=function(){function a(a){b.options.dataUrl&&m[b.options.dataType](b.options.dataUrl,function(a){if("csv"===b.options.dataType&&a&&a.slice){for(var c={},d=0;d<a.length;d++)c[a[d].id]=a[d];a=c}Datamaps.prototype.updateChoropleth.call(b,a)}),d.call(b,a),e.call(b),(b.options.geographyConfig.popupOnHover||b.options.bubblesConfig.popupOnHover)&&(hoverover=m.select(b.options.element).append("div").attr("class","datamaps-hoverover").style("z-index",10001).style("position","absolute")),b.options.done(b)}var b=this,c=b.options,f=c.setProjection.apply(b,[c.element,c]);return this.path=f.path,this.projection=f.projection,c.geographyConfig.dataUrl?m.json(c.geographyConfig.dataUrl,function(c,d){if(c)throw new Error(c);b.customTopo=d,a(d)}):a(this[c.scope+"Topo"]||c.geographyConfig.dataJson),this},l.prototype.worldTopo={type:"Topology",objects:{world:{type:"GeometryCollection",geometries:[{type:"Polygon",properties:{name:"Afghanistan"},id:"AFG",arcs:[[0,1,2,3,4,5]]},{type:"MultiPolygon",properties:{name:"Angola"},id:"AGO",arcs:[[[6,7,8,9]],[[10,11,12]]]},{type:"Polygon",properties:{name:"Albania"},id:"ALB",arcs:[[13,14,15,16,17]]},{type:"Polygon",properties:{name:"United Arab Emirates"},id:"ARE",arcs:[[18,19,20,21,22]]},{type:"MultiPolygon",properties:{name:"Argentina"},id:"ARG",arcs:[[[23,24]],[[25,26,27,28,29,30]]]},{type:"Polygon",properties:{name:"Armenia"},id:"ARM",arcs:[[31,32,33,34,35]]},{type:"MultiPolygon",properties:{name:"Antarctica"},id:"ATA",arcs:[[[36]],[[37]],[[38]],[[39]],[[40]],[[41]],[[42]],[[43]]]},{type:"Polygon",properties:{name:"French Southern and Antarctic Lands"},id:"ATF",arcs:[[44]]},{type:"MultiPolygon",properties:{name:"Australia"},id:"AUS",arcs:[[[45]],[[46]]]},{type:"Polygon",properties:{name:"Austria"},id:"AUT",arcs:[[47,48,49,50,51,52,53]]},{type:"MultiPolygon",properties:{name:"Azerbaijan"},id:"AZE",arcs:[[[54,-35]],[[55,56,-33,57,58]]]},{type:"Polygon",properties:{name:"Burundi"},id:"BDI",arcs:[[59,60,61]]},{type:"Polygon",properties:{name:"Belgium"},id:"BEL",arcs:[[62,63,64,65,66]]},{type:"Polygon",properties:{name:"Benin"},id:"BEN",arcs:[[67,68,69,70,71]]},{type:"Polygon",properties:{name:"Burkina Faso"},id:"BFA",arcs:[[72,73,74,-70,75,76]]},{type:"Polygon",properties:{name:"Bangladesh"},id:"BGD",arcs:[[77,78,79]]},{type:"Polygon",properties:{name:"Bulgaria"},id:"BGR",arcs:[[80,81,82,83,84,85]]},{type:"MultiPolygon",properties:{name:"The Bahamas"},id:"BHS",arcs:[[[86]],[[87]],[[88]]]},{type:"Polygon",properties:{name:"Bosnia and Herzegovina"},id:"BIH",arcs:[[89,90,91]]},{type:"Polygon",properties:{name:"Belarus"},id:"BLR",arcs:[[92,93,94,95,96]]},{type:"Polygon",properties:{name:"Belize"},id:"BLZ",arcs:[[97,98,99]]},{type:"Polygon",properties:{name:"Bolivia"},id:"BOL",arcs:[[100,101,102,103,-31]]},{type:"Polygon",properties:{name:"Brazil"},id:"BRA",arcs:[[-27,104,-103,105,106,107,108,109,110,111,112]]},{type:"Polygon",properties:{name:"Brunei"},id:"BRN",arcs:[[113,114]]},{type:"Polygon",properties:{name:"Bhutan"},id:"BTN",arcs:[[115,116]]},{type:"Polygon",properties:{name:"Botswana"},id:"BWA",arcs:[[117,118,119,120]]},{type:"Polygon",properties:{name:"Central African Republic"},id:"CAF",arcs:[[121,122,123,124,125,126,127]]},{type:"MultiPolygon",properties:{name:"Canada"},id:"CAN",arcs:[[[128]],[[129]],[[130]],[[131]],[[132]],[[133]],[[134]],[[135]],[[136]],[[137]],[[138,139,140,141]],[[142]],[[143]],[[144]],[[145]],[[146]],[[147]],[[148]],[[149]],[[150]],[[151]],[[152]],[[153]],[[154]],[[155]],[[156]],[[157]],[[158]],[[159]],[[160]]]},{type:"Polygon",properties:{name:"Switzerland"},id:"CHE",arcs:[[-51,161,162,163]]},{type:"MultiPolygon",properties:{name:"Chile"},id:"CHL",arcs:[[[-24,164]],[[-30,165,166,-101]]]},{type:"MultiPolygon",properties:{name:"China"},id:"CHN",arcs:[[[167]],[[168,169,170,171,172,173,-117,174,175,176,177,-4,178,179,180,181,182,183]]]},{type:"Polygon",properties:{name:"Ivory Coast"},id:"CIV",arcs:[[184,185,186,187,-73,188]]},{type:"Polygon",properties:{name:"Cameroon"},id:"CMR",arcs:[[189,190,191,192,193,194,-128,195]]},{type:"Polygon",properties:{name:"Democratic Republic of the Congo"},id:"COD",arcs:[[196,197,-60,198,199,-10,200,-13,201,-126,202]]},{type:"Polygon",properties:{name:"Republic of the Congo"},id:"COG",arcs:[[-12,203,204,-196,-127,-202]]},{type:"Polygon",properties:{name:"Colombia"},id:"COL",arcs:[[205,206,207,208,209,-107,210]]},{type:"Polygon",properties:{name:"Costa Rica"},id:"CRI",arcs:[[211,212,213,214]]},{type:"Polygon",properties:{name:"Cuba"},id:"CUB",arcs:[[215]]},{type:"Polygon",properties:{name:"Northern Cyprus"},id:"-99",arcs:[[216,217]]},{type:"Polygon",properties:{name:"Cyprus"},id:"CYP",arcs:[[218,-218]]},{type:"Polygon",properties:{name:"Czech Republic"},id:"CZE",arcs:[[-53,219,220,221]]},{type:"Polygon",properties:{name:"Germany"},id:"DEU",arcs:[[222,223,-220,-52,-164,224,225,-64,226,227,228]]},{type:"Polygon",properties:{name:"Djibouti"},id:"DJI",arcs:[[229,230,231,232]]},{type:"MultiPolygon",properties:{name:"Denmark"},id:"DNK",arcs:[[[233]],[[-229,234]]]},{type:"Polygon",properties:{name:"Dominican Republic"},id:"DOM",arcs:[[235,236]]},{type:"Polygon",properties:{name:"Algeria"},id:"DZA",arcs:[[237,238,239,240,241,242,243,244]]},{type:"Polygon",properties:{name:"Ecuador"},id:"ECU",arcs:[[245,-206,246]]},{type:"Polygon",properties:{name:"Egypt"},id:"EGY",arcs:[[247,248,249,250,251]]},{type:"Polygon",properties:{name:"Eritrea"},id:"ERI",arcs:[[252,253,254,-233]]},{type:"Polygon",properties:{name:"Spain"},id:"ESP",arcs:[[255,256,257,258]]},{type:"Polygon",properties:{name:"Estonia"},id:"EST",arcs:[[259,260,261]]},{type:"Polygon",properties:{name:"Ethiopia"},id:"ETH",arcs:[[-232,262,263,264,265,266,267,-253]]},{type:"Polygon",properties:{name:"Finland"},id:"FIN",arcs:[[268,269,270,271]]},{type:"MultiPolygon",properties:{name:"Fiji"},id:"FJI",arcs:[[[272]],[[273,274]],[[275,-275]]]},{type:"Polygon",properties:{name:"Falkland Islands"},id:"FLK",arcs:[[276]]},{type:"MultiPolygon",properties:{name:"France"},id:"FRA",arcs:[[[277]],[[278,-225,-163,279,280,-257,281,-66]]]},{type:"Polygon",properties:{name:"French Guiana"},id:"GUF",arcs:[[282,283,284,285,-111]]},{type:"Polygon",properties:{name:"Gabon"},id:"GAB",arcs:[[286,287,-190,-205]]},{type:"MultiPolygon",properties:{name:"United Kingdom"},id:"GBR",arcs:[[[288,289]],[[290]]]},{type:"Polygon",properties:{name:"Georgia"},id:"GEO",arcs:[[291,292,-58,-32,293]]},{type:"Polygon",properties:{name:"Ghana"},id:"GHA",arcs:[[294,-189,-77,295]]},{type:"Polygon",properties:{name:"Guinea"},id:"GIN",arcs:[[296,297,298,299,300,301,-187]]},{type:"Polygon",properties:{name:"Gambia"},id:"GMB",arcs:[[302,303]]},{type:"Polygon",properties:{name:"Guinea Bissau"},id:"GNB",arcs:[[304,305,-300]]},{type:"Polygon",properties:{name:"Equatorial Guinea"},id:"GNQ",arcs:[[306,-191,-288]]},{type:"MultiPolygon",properties:{name:"Greece"},id:"GRC",arcs:[[[307]],[[308,-15,309,-84,310]]]},{type:"Polygon",properties:{name:"Greenland"},id:"GRL",arcs:[[311]]},{type:"Polygon",properties:{name:"Guatemala"},id:"GTM",arcs:[[312,313,-100,314,315,316]]},{type:"Polygon",properties:{name:"Guyana"},id:"GUY",arcs:[[317,318,-109,319]]},{type:"Polygon",properties:{name:"Honduras"},id:"HND",arcs:[[320,321,-316,322,323]]},{type:"Polygon",properties:{name:"Croatia"},id:"HRV",arcs:[[324,-92,325,326,327,328]]},{type:"Polygon",properties:{name:"Haiti"},id:"HTI",arcs:[[-237,329]]},{type:"Polygon",properties:{name:"Hungary"},id:"HUN",arcs:[[-48,330,331,332,333,-329,334]]},{type:"MultiPolygon",properties:{name:"Indonesia"},id:"IDN",arcs:[[[335]],[[336,337]],[[338]],[[339]],[[340]],[[341]],[[342]],[[343]],[[344,345]],[[346]],[[347]],[[348,349]],[[350]]]},{type:"Polygon",properties:{name:"India"},id:"IND",arcs:[[-177,351,-175,-116,-174,352,-80,353,354]]},{type:"Polygon",properties:{name:"Ireland"},id:"IRL",arcs:[[355,-289]]},{type:"Polygon",properties:{name:"Iran"},id:"IRN",arcs:[[356,-6,357,358,359,360,-55,-34,-57,361]]},{type:"Polygon",properties:{name:"Iraq"},id:"IRQ",arcs:[[362,363,364,365,366,367,-360]]},{type:"Polygon",properties:{name:"Iceland"},id:"ISL",arcs:[[368]]},{type:"Polygon",properties:{name:"Israel"},id:"ISR",arcs:[[369,370,371,-252,372,373,374]]},{type:"MultiPolygon",properties:{name:"Italy"},id:"ITA",arcs:[[[375]],[[376]],[[377,378,-280,-162,-50]]]},{type:"Polygon",properties:{name:"Jamaica"},id:"JAM",arcs:[[379]]},{type:"Polygon",properties:{name:"Jordan"},id:"JOR",arcs:[[-370,380,-366,381,382,-372,383]]},{type:"MultiPolygon",properties:{name:"Japan"},id:"JPN",arcs:[[[384]],[[385]],[[386]]]},{type:"Polygon",properties:{name:"Kazakhstan"},id:"KAZ",arcs:[[387,388,389,390,-181,391]]},{type:"Polygon",properties:{name:"Kenya"},id:"KEN",arcs:[[392,393,394,395,-265,396]]},{type:"Polygon",properties:{name:"Kyrgyzstan"},id:"KGZ",arcs:[[-392,-180,397,398]]},{type:"Polygon",properties:{name:"Cambodia"},id:"KHM",arcs:[[399,400,401,402]]},{type:"Polygon",properties:{name:"South Korea"},id:"KOR",arcs:[[403,404]]},{type:"Polygon",properties:{name:"Kosovo"},id:"-99",arcs:[[-18,405,406,407]]},{type:"Polygon",properties:{name:"Kuwait"},id:"KWT",arcs:[[408,409,-364]]},{type:"Polygon",properties:{name:"Laos"},id:"LAO",arcs:[[410,411,-172,412,-401]]},{type:"Polygon",properties:{name:"Lebanon"},id:"LBN",arcs:[[-374,413,414]]},{type:"Polygon",properties:{name:"Liberia"},id:"LBR",arcs:[[415,416,-297,-186]]},{type:"Polygon",properties:{name:"Libya"},id:"LBY",arcs:[[417,-245,418,419,-250,420,421]]},{type:"Polygon",properties:{name:"Sri Lanka"},id:"LKA",arcs:[[422]]},{type:"Polygon",properties:{name:"Lesotho"},id:"LSO",arcs:[[423]]},{type:"Polygon",properties:{name:"Lithuania"},id:"LTU",arcs:[[424,425,426,-93,427]]},{type:"Polygon",properties:{name:"Luxembourg"},id:"LUX",arcs:[[-226,-279,-65]]},{type:"Polygon",properties:{name:"Latvia"},id:"LVA",arcs:[[428,-262,429,-94,-427]]},{type:"Polygon",properties:{name:"Morocco"},id:"MAR",arcs:[[-242,430,431]]},{type:"Polygon",properties:{name:"Moldova"},id:"MDA",arcs:[[432,433]]},{type:"Polygon",properties:{name:"Madagascar"},id:"MDG",arcs:[[434]]},{type:"Polygon",properties:{name:"Mexico"},id:"MEX",arcs:[[435,-98,-314,436,437]]},{type:"Polygon",properties:{name:"Macedonia"},id:"MKD",arcs:[[-408,438,-85,-310,-14]]},{type:"Polygon",properties:{name:"Mali"},id:"MLI",arcs:[[439,-239,440,-74,-188,-302,441]]},{type:"Polygon",properties:{name:"Myanmar"},id:"MMR",arcs:[[442,-78,-353,-173,-412,443]]},{type:"Polygon",properties:{name:"Montenegro"},id:"MNE",arcs:[[444,-326,-91,445,-406,-17]]},{type:"Polygon",properties:{name:"Mongolia"},id:"MNG",arcs:[[446,-183]]},{type:"Polygon",properties:{name:"Mozambique"},id:"MOZ",arcs:[[447,448,449,450,451,452,453,454]]},{type:"Polygon",properties:{name:"Mauritania"},id:"MRT",arcs:[[455,456,457,-240,-440]]},{type:"Polygon",properties:{name:"Malawi"},id:"MWI",arcs:[[-455,458,459]]},{type:"MultiPolygon",properties:{name:"Malaysia"},id:"MYS",arcs:[[[460,461]],[[-349,462,-115,463]]]},{type:"Polygon",properties:{name:"Namibia"},id:"NAM",arcs:[[464,-8,465,-119,466]]},{type:"Polygon",properties:{name:"New Caledonia"},id:"NCL",arcs:[[467]]},{type:"Polygon",properties:{name:"Niger"},id:"NER",arcs:[[-75,-441,-238,-418,468,-194,469,-71]]},{type:"Polygon",properties:{name:"Nigeria"},id:"NGA",arcs:[[470,-72,-470,-193]]},{type:"Polygon",properties:{name:"Nicaragua"},id:"NIC",arcs:[[471,-324,472,-213]]},{type:"Polygon",properties:{name:"Netherlands"},id:"NLD",arcs:[[-227,-63,473]]},{type:"MultiPolygon",properties:{name:"Norway"},id:"NOR",arcs:[[[474,-272,475,476]],[[477]],[[478]],[[479]]]},{type:"Polygon",properties:{name:"Nepal"},id:"NPL",arcs:[[-352,-176]]},{type:"MultiPolygon",properties:{name:"New Zealand"},id:"NZL",arcs:[[[480]],[[481]]]},{type:"MultiPolygon",properties:{name:"Oman"},id:"OMN",arcs:[[[482,483,-22,484]],[[-20,485]]]},{type:"Polygon",properties:{name:"Pakistan"},id:"PAK",arcs:[[-178,-355,486,-358,-5]]},{type:"Polygon",properties:{name:"Panama"},id:"PAN",arcs:[[487,-215,488,-208]]},{type:"Polygon",properties:{name:"Peru"},id:"PER",arcs:[[-167,489,-247,-211,-106,-102]]},{type:"MultiPolygon",properties:{name:"Philippines"},id:"PHL",arcs:[[[490]],[[491]],[[492]],[[493]],[[494]],[[495]],[[496]]]},{type:"MultiPolygon",properties:{name:"Papua New Guinea"},id:"PNG",arcs:[[[497]],[[498]],[[-345,499]],[[500]]]},{type:"Polygon",properties:{name:"Poland"},id:"POL",arcs:[[-224,501,502,-428,-97,503,504,-221]]},{type:"Polygon",properties:{name:"Puerto Rico"},id:"PRI",arcs:[[505]]},{type:"Polygon",properties:{name:"North Korea"},id:"PRK",arcs:[[506,507,-405,508,-169]]},{type:"Polygon",properties:{name:"Portugal"},id:"PRT",arcs:[[-259,509]]},{type:"Polygon",properties:{name:"Paraguay"},id:"PRY",arcs:[[-104,-105,-26]]},{type:"Polygon",properties:{name:"Qatar"},id:"QAT",arcs:[[510,511]]},{type:"Polygon",properties:{name:"Romania"},id:"ROU",arcs:[[512,-434,513,514,-81,515,-333]]},{type:"MultiPolygon",properties:{name:"Russia"},id:"RUS",arcs:[[[516]],[[-503,517,-425]],[[518,519]],[[520]],[[521]],[[522]],[[523]],[[524]],[[525]],[[526,-507,-184,-447,-182,-391,527,-59,-293,528,529,-95,-430,-261,530,-269,-475,531,-520]],[[532]],[[533]],[[534]]]},{type:"Polygon",properties:{name:"Rwanda"},id:"RWA",arcs:[[535,-61,-198,536]]},{type:"Polygon",properties:{name:"Western Sahara"},id:"ESH",arcs:[[-241,-458,537,-431]]},{type:"Polygon",properties:{name:"Saudi Arabia"},id:"SAU",arcs:[[538,-382,-365,-410,539,-512,540,-23,-484,541]]},{type:"Polygon",properties:{name:"Sudan"},id:"SDN",arcs:[[542,543,-123,544,-421,-249,545,-254,-268,546]]},{type:"Polygon",properties:{name:"South Sudan"},id:"SSD",arcs:[[547,-266,-396,548,-203,-125,549,-543]]},{type:"Polygon",properties:{name:"Senegal"},id:"SEN",arcs:[[550,-456,-442,-301,-306,551,-304]]},{type:"MultiPolygon",properties:{name:"Solomon Islands"},id:"SLB",arcs:[[[552]],[[553]],[[554]],[[555]],[[556]]]},{type:"Polygon",properties:{name:"Sierra Leone"},id:"SLE",arcs:[[557,-298,-417]]},{type:"Polygon",properties:{name:"El Salvador"},id:"SLV",arcs:[[558,-317,-322]]},{type:"Polygon",properties:{name:"Somaliland"},id:"-99",arcs:[[-263,-231,559,560]]},{type:"Polygon",properties:{name:"Somalia"},id:"SOM",arcs:[[-397,-264,-561,561]]},{type:"Polygon",properties:{name:"Republic of Serbia"},id:"SRB",arcs:[[-86,-439,-407,-446,-90,-325,-334,-516]]},{type:"Polygon",properties:{name:"Suriname"},id:"SUR",arcs:[[562,-285,563,-283,-110,-319]]},{type:"Polygon",properties:{name:"Slovakia"},id:"SVK",arcs:[[-505,564,-331,-54,-222]]},{type:"Polygon",properties:{name:"Slovenia"},id:"SVN",arcs:[[-49,-335,-328,565,-378]]},{type:"Polygon",properties:{name:"Sweden"},id:"SWE",arcs:[[-476,-271,566]]},{type:"Polygon",properties:{name:"Swaziland"},id:"SWZ",arcs:[[567,-451]]},{type:"Polygon",properties:{name:"Syria"},id:"SYR",arcs:[[-381,-375,-415,568,569,-367]]},{type:"Polygon",properties:{name:"Chad"},id:"TCD",arcs:[[-469,-422,-545,-122,-195]]},{type:"Polygon",properties:{name:"Togo"},id:"TGO",arcs:[[570,-296,-76,-69]]},{type:"Polygon",properties:{name:"Thailand"},id:"THA",arcs:[[571,-462,572,-444,-411,-400]]},{type:"Polygon",properties:{name:"Tajikistan"},id:"TJK",arcs:[[-398,-179,-3,573]]},{type:"Polygon",properties:{name:"Turkmenistan"},id:"TKM",arcs:[[-357,574,-389,575,-1]]},{type:"Polygon",properties:{name:"East Timor"},id:"TLS",arcs:[[576,-337]]},{type:"Polygon",properties:{name:"Trinidad and Tobago"},id:"TTO",arcs:[[577]]},{type:"Polygon",properties:{name:"Tunisia"},id:"TUN",arcs:[[-244,578,-419]]},{type:"MultiPolygon",properties:{name:"Turkey"},id:"TUR",arcs:[[[-294,-36,-361,-368,-570,579]],[[-311,-83,580]]]},{type:"Polygon",properties:{name:"Taiwan"},id:"TWN",arcs:[[581]]},{type:"Polygon",properties:{name:"United Republic of Tanzania"},id:"TZA",arcs:[[-394,582,-448,-460,583,-199,-62,-536,584]]},{type:"Polygon",properties:{name:"Uganda"},id:"UGA",arcs:[[-537,-197,-549,-395,-585]]},{type:"Polygon",properties:{name:"Ukraine"},id:"UKR",arcs:[[-530,585,-514,-433,-513,-332,-565,-504,-96]]},{type:"Polygon",properties:{name:"Uruguay"},id:"URY",arcs:[[-113,586,-28]]},{type:"MultiPolygon",properties:{name:"United States of America"},id:"USA",arcs:[[[587]],[[588]],[[589]],[[590]],[[591]],[[592,-438,593,-139]],[[594]],[[595]],[[596]],[[-141,597]]]},{type:"Polygon",properties:{name:"Uzbekistan"},id:"UZB",arcs:[[-576,-388,-399,-574,-2]]},{type:"Polygon",properties:{name:"Venezuela"},id:"VEN",arcs:[[598,-320,-108,-210]]},{type:"Polygon",properties:{name:"Vietnam"},id:"VNM",arcs:[[599,-402,-413,-171]]},{type:"MultiPolygon",properties:{name:"Vanuatu"},id:"VUT",arcs:[[[600]],[[601]]]},{type:"Polygon",properties:{name:"West Bank"},id:"PSE",arcs:[[-384,-371]]},{type:"Polygon",properties:{name:"Yemen"},id:"YEM",arcs:[[602,-542,-483]]},{type:"Polygon",properties:{name:"South Africa"},id:"ZAF",arcs:[[-467,-118,603,-452,-568,-450,604],[-424]]},{type:"Polygon",properties:{name:"Zambia"},id:"ZMB",arcs:[[-459,-454,605,-120,-466,-7,-200,-584]]},{type:"Polygon",properties:{name:"Zimbabwe"},id:"ZWE",arcs:[[-604,-121,-606,-453]]}]}},arcs:[[[6700,7164],[28,-23],[21,8],[6,27],[22,9],[15,18],[6,47],[23,11],[5,21],[13,-15],[8,-2]],[[6847,7265],[16,-1],[20,-12]],[[6883,7252],[9,-7],[20,19],[9,-12],[9,27],[17,-1],[4,9],[3,24],[12,20],[15,-13],[-3,-18],[9,-3],[-3,-50],[11,-19],[10,12],[12,6],[17,27],[19,-5],[29,0]],[[7082,7268],[5,-17]],[[7087,7251],[-16,-6],[-14,-11],[-32,-7],[-30,-13],[-16,-25],[6,-25],[4,-30],[-14,-25],[1,-22],[-8,-22],[-26,2],[11,-39],[-18,-15],[-12,-35],[2,-36],[-11,-16],[-10,5],[-22,-8],[-3,-16],[-20,0],[-16,-34],[-1,-50],[-36,-24],[-19,5],[-6,-13],[-16,7],[-28,-8],[-47,30]],[[6690,6820],[25,53],[-2,38],[-21,10],[-2,38],[-9,47],[12,32],[-12,9],[7,43],[12,74]],[[5664,4412],[3,-18],[-4,-29],[5,-28],[-4,-22],[3,-20],[-58,1],[-2,-188],[19,-49],[18,-37]],[[5644,4022],[-51,-24],[-67,9],[-19,28],[-113,-3],[-4,-4],[-17,27],[-18,2],[-16,-10],[-14,-12]],[[5325,4035],[-2,38],[4,51],[9,55],[2,25],[9,53],[6,24],[16,39],[9,26],[3,44],[-1,34],[-9,21],[-7,36],[-7,35],[2,12],[8,24],[-8,57],[-6,39],[-14,38],[3,11]],[[5342,4697],[11,8],[8,-1],[10,7],[82,-1],[7,-44],[8,-35],[6,-19],[11,-31],[18,5],[9,8],[16,-8],[4,14],[7,35],[17,2],[2,10],[14,1],[-3,-22],[34,1],[1,-37],[5,-23],[-4,-36],[2,-36],[9,-22],[-1,-70],[7,5],[12,-1],[17,8],[13,-3]],[[5338,4715],[-8,45]],[[5330,4760],[12,25],[8,10],[10,-20]],[[5360,4775],[-10,-12],[-4,-16],[-1,-25],[-7,-7]],[[5571,7530],[-3,-20],[4,-25],[11,-15]],[[5583,7470],[0,-15],[-9,-9],[-2,-19],[-13,-29]],[[5559,7398],[-5,5],[0,13],[-15,19],[-3,29],[2,40],[4,18],[-4,10]],[[5538,7532],[-2,18],[12,29],[1,-11],[8,6]],[[5557,7574],[6,-16],[7,-6],[1,-22]],[[6432,6490],[5,3],[1,-16],[22,9],[23,-2],[17,-1],[19,39],[20,38],[18,37]],[[6557,6597],[5,-20]],[[6562,6577],[4,-47]],[[6566,6530],[-14,0],[-3,-39],[5,-8],[-12,-12],[0,-24],[-8,-24],[-1,-24]],[[6533,6399],[-6,-12],[-83,29],[-11,60],[-1,14]],[[3140,1814],[-17,2],[-30,0],[0,132]],[[3093,1948],[11,-27],[14,-45],[36,-35],[39,-15],[-13,-30],[-26,-2],[-14,20]],[[3258,3743],[51,-96],[23,-9],[34,-44],[29,-23],[4,-26],[-28,-90],[28,-16],[32,-9],[22,10],[25,45],[4,52]],[[3482,3537],[14,11],[14,-34],[-1,-47],[-23,-33],[-19,-24],[-31,-57],[-37,-81]],[[3399,3272],[-7,-47],[-7,-61],[0,-58],[-6,-14],[-2,-38]],[[3377,3054],[-2,-31],[35,-50],[-4,-41],[18,-26],[-2,-29],[-26,-75],[-42,-32],[-55,-12],[-31,6],[6,-36],[-6,-44],[5,-30],[-16,-20],[-29,-8],[-26,21],[-11,-15],[4,-59],[18,-18],[16,19],[8,-31],[-26,-18],[-22,-37],[-4,-59],[-7,-32],[-26,0],[-22,-31],[-8,-44],[28,-43],[26,-12],[-9,-53],[-33,-33],[-18,-70],[-25,-23],[-12,-28],[9,-61],[19,-34],[-12,3]],[[3095,1968],[-26,9],[-67,8],[-11,34],[0,45],[-18,-4],[-10,21],[-3,63],[22,26],[9,37],[-4,30],[15,51],[10,78],[-3,35],[12,11],[-3,22],[-13,12],[10,25],[-13,22],[-6,68],[11,12],[-5,72],[7,61],[7,52],[17,22],[-9,58],[0,54],[21,38],[-1,50],[16,57],[0,55],[-7,11],[-13,102],[17,60],[-2,58],[10,53],[18,56],[20,36],[-9,24],[6,19],[-1,98],[30,29],[10,62],[-3,14]],[[3136,3714],[23,54],[36,-15],[16,-42],[11,47],[32,-2],[4,-13]],[[6210,7485],[39,9]],[[6249,7494],[5,-15],[11,-10],[-6,-15],[15,-21],[-8,-18],[12,-16],[13,-10],[0,-41]],[[6291,7348],[-10,-2]],[[6281,7346],[-11,34],[0,10],[-12,-1],[-9,16],[-5,-1]],[[6244,7404],[-11,17],[-21,15],[3,28],[-5,21]],[[3345,329],[-8,-30],[-8,-27],[-59,8],[-62,-3],[-34,20],[0,2],[-16,17],[63,-2],[60,-6],[20,24],[15,21],[29,-24]],[[577,361],[-53,-8],[-36,21],[-17,21],[-1,3],[-18,16],[17,22],[52,-9],[28,-18],[21,-21],[7,-27]],[[3745,447],[35,-26],[12,-36],[3,-25],[1,-30],[-43,-19],[-45,-15],[-52,-14],[-59,-11],[-65,3],[-37,20],[5,24],[59,16],[24,20],[18,26],[12,22],[17,20],[18,25],[14,0],[41,12],[42,-12]],[[1633,715],[36,-9],[33,10],[-16,-20],[-26,-15],[-39,4],[-27,21],[6,20],[33,-11]],[[1512,716],[43,-23],[-17,3],[-36,5],[-38,17],[20,12],[28,-14]],[[2250,808],[31,-8],[30,7],[17,-34],[-22,5],[-34,-2],[-34,2],[-38,-4],[-28,12],[-15,24],[18,11],[35,-8],[40,-5]],[[3098,866],[4,-27],[-5,-23],[-8,-22],[-33,-8],[-31,-12],[-36,1],[14,24],[-33,-9],[-31,-8],[-21,18],[-2,24],[30,23],[20,7],[32,-2],[8,30],[1,22],[0,47],[16,28],[25,9],[15,-22],[6,-22],[12,-26],[10,-26],[7,-26]],[[3371,1268],[-11,-13],[-21,9],[-23,-6],[-19,-14],[-20,-15],[-14,-17],[-4,-23],[2,-22],[13,-20],[-19,-14],[-26,-4],[-15,-20],[-17,-19],[-17,-25],[-4,-22],[9,-24],[15,-19],[23,-14],[21,-18],[12,-23],[6,-22],[8,-24],[13,-19],[8,-22],[4,-55],[8,-22],[2,-23],[9,-23],[-4,-31],[-15,-24],[-17,-20],[-37,-8],[-12,-21],[-17,-20],[-42,-22],[-37,-9],[-35,-13],[-37,-13],[-22,-24],[-45,-2],[-49,2],[-44,-4],[-47,0],[9,-24],[42,-10],[31,-16],[18,-21],[-31,-19],[-48,6],[-40,-15],[-2,-24],[-1,-23],[33,-20],[6,-22],[35,-22],[59,-9],[50,-16],[40,-19],[50,-18],[70,-10],[68,-16],[47,-17],[52,-20],[27,-28],[13,-22],[34,21],[46,17],[48,19],[58,15],[49,16],[69,1],[68,-8],[56,-14],[18,26],[39,17],[70,1],[55,13],[52,13],[58,8],[62,10],[43,15],[-20,21],[-12,21],[0,22],[-54,-2],[-57,-10],[-54,0],[-8,22],[4,44],[12,13],[40,14],[47,14],[34,17],[33,18],[25,23],[38,10],[38,8],[19,5],[43,2],[41,8],[34,12],[34,14],[30,14],[39,18],[24,20],[26,17],[9,24],[-30,13],[10,25],[18,18],[29,12],[31,14],[28,18],[22,23],[13,28],[21,16],[33,-3],[13,-20],[34,-2],[1,22],[14,23],[30,-6],[7,-22],[33,-3],[36,10],[35,7],[31,-3],[12,-25],[31,20],[28,10],[31,9],[31,8],[29,14],[31,9],[24,13],[17,20],[20,-15],[29,8],[20,-27],[16,-21],[32,11],[12,24],[28,16],[37,-4],[11,-22],[22,22],[30,7],[33,3],[29,-2],[31,-7],[30,-3],[13,-20],[18,-17],[31,10],[32,3],[32,0],[31,1],[28,8],[29,7],[25,16],[26,11],[28,5],[21,17],[15,32],[16,20],[29,-10],[11,-21],[24,-13],[29,4],[19,-21],[21,-15],[28,14],[10,26],[25,10],[29,20],[27,8],[33,11],[22,13],[22,14],[22,13],[26,-7],[25,21],[18,16],[26,-1],[23,14],[6,21],[23,16],[23,11],[28,10],[25,4],[25,-3],[26,-6],[22,-16],[3,-26],[24,-19],[17,-17],[33,-7],[19,-16],[23,-16],[26,-3],[23,11],[24,24],[26,-12],[27,-7],[26,-7],[27,-5],[28,0],[23,-61],[-1,-15],[-4,-27],[-26,-15],[-22,-22],[4,-23],[31,1],[-4,-23],[-14,-22],[-13,-24],[21,-19],[32,-6],[32,11],[15,23],[10,22],[15,18],[17,18],[7,21],[15,29],[18,5],[31,3],[28,7],[28,9],[14,23],[8,22],[19,22],[27,15],[23,12],[16,19],[15,11],[21,9],[27,-6],[25,6],[28,7],[30,-4],[20,17],[14,39],[11,-16],[13,-28],[23,-12],[27,-4],[26,7],[29,-5],[26,-1],[17,6],[24,-4],[21,-12],[25,8],[30,0],[25,8],[29,-8],[19,19],[14,20],[19,16],[35,44],[18,-8],[21,-16],[18,-21],[36,-36],[27,-1],[25,0],[30,7],[30,8],[23,16],[19,18],[31,2],[21,13],[22,-12],[14,-18],[19,-19],[31,2],[19,-15],[33,-15],[35,-5],[29,4],[21,19],[19,18],[25,5],[25,-8],[29,-6],[26,9],[25,0],[24,-6],[26,-5],[25,10],[30,9],[28,3],[32,0],[25,5],[25,5],[8,29],[1,24],[17,-16],[5,-27],[10,-24],[11,-20],[23,-10],[32,4],[36,1],[25,3],[37,0],[26,1],[36,-2],[31,-5],[20,-18],[-5,-22],[18,-18],[30,-13],[31,-15],[35,-11],[38,-9],[28,-9],[32,-2],[18,20],[24,-16],[21,-19],[25,-13],[34,-6],[32,-7],[13,-23],[32,-14],[21,-21],[31,-9],[32,1],[30,-4],[33,1],[34,-4],[31,-8],[28,-14],[29,-12],[20,-17],[-3,-23],[-15,-21],[-13,-27],[-9,-21],[-14,-24],[-36,-9],[-16,-21],[-36,-13],[-13,-23],[-19,-22],[-20,-18],[-11,-25],[-7,-22],[-3,-26],[0,-22],[16,-23],[6,-22],[13,-21],[52,-8],[11,-26],[-50,-9],[-43,-13],[-52,-2],[-24,-34],[-5,-27],[-12,-22],[-14,-22],[37,-20],[14,-24],[24,-22],[33,-20],[39,-19],[42,-18],[64,-19],[14,-29],[80,-12],[5,-5],[21,-17],[77,15],[63,-19],[48,-14],[-9997,-1],[24,35],[50,-19],[3,2],[30,19],[4,0],[3,-1],[40,-25],[35,25],[7,3],[81,11],[27,-14],[13,-7],[41,-20],[79,-15],[63,-18],[107,-14],[80,16],[118,-11],[67,-19],[73,17],[78,17],[6,27],[-110,3],[-89,14],[-24,23],[-74,12],[5,27],[10,24],[10,22],[-5,25],[-46,16],[-22,21],[-43,18],[68,-3],[64,9],[40,-20],[50,18],[45,22],[23,19],[-10,25],[-36,16],[-41,17],[-57,4],[-50,8],[-54,6],[-18,22],[-36,18],[-21,21],[-9,67],[14,-6],[25,-18],[45,6],[44,8],[23,-26],[44,6],[37,13],[35,16],[32,20],[41,5],[-1,22],[-9,22],[8,21],[36,11],[16,-20],[42,12],[32,15],[40,1],[38,6],[37,13],[30,13],[34,13],[22,-4],[19,-4],[41,8],[37,-10],[38,1],[37,8],[37,-6],[41,-6],[39,3],[40,-2],[42,-1],[38,3],[28,17],[34,9],[35,-13],[33,11],[30,21],[18,-19],[9,-21],[18,-19],[29,17],[33,-22],[38,-7],[32,-16],[39,3],[36,11],[41,-3],[38,-8],[38,-10],[15,25],[-18,20],[-14,21],[-36,5],[-15,22],[-6,22],[-10,43],[21,-8],[36,-3],[36,3],[33,-9],[28,-17],[12,-21],[38,-4],[36,9],[38,11],[34,7],[28,-14],[37,5],[24,45],[23,-27],[32,-10],[34,6],[23,-23],[37,-3],[33,-7],[34,-12],[21,22],[11,20],[28,-23],[38,6],[28,-13],[19,-19],[37,5],[29,13],[29,15],[33,8],[39,7],[36,8],[27,13],[16,19],[7,25],[-3,24],[-9,24],[-10,23],[-9,23],[-7,21],[-1,23],[2,23],[13,22],[11,24],[5,23],[-6,26],[-3,23],[14,27],[15,17],[18,22],[19,19],[22,17],[11,25],[15,17],[18,15],[26,3],[18,19],[19,11],[23,7],[20,15],[16,19],[22,7],[16,-15],[-10,-20],[-29,-17]],[[6914,2185],[18,-19],[26,-7],[1,-11],[-7,-27],[-43,-4],[-1,31],[4,25],[2,12]],[[9038,2648],[27,-21],[15,8],[22,12],[16,-4],[2,-70],[-9,-21],[-3,-47],[-10,16],[-19,-41],[-6,3],[-17,2],[-17,50],[-4,39],[-16,52],[1,27],[18,-5]],[[8987,4244],[10,-46],[18,22],[9,-25],[13,-23],[-3,-26],[6,-51],[5,-29],[7,-7],[7,-51],[-3,-30],[9,-40],[31,-31],[19,-28],[19,-26],[-4,-14],[16,-37],[11,-64],[11,13],[11,-26],[7,9],[5,-63],[19,-36],[13,-22],[22,-48],[8,-48],[1,-33],[-2,-37],[13,-50],[-2,-52],[-5,-28],[-7,-52],[1,-34],[-6,-43],[-12,-53],[-21,-29],[-10,-46],[-9,-29],[-8,-51],[-11,-30],[-7,-44],[-4,-41],[2,-18],[-16,-21],[-31,-2],[-26,-24],[-13,-23],[-17,-26],[-23,27],[-17,10],[5,31],[-15,-11],[-25,-43],[-24,16],[-15,9],[-16,4],[-27,17],[-18,37],[-5,45],[-7,30],[-13,24],[-27,7],[9,28],[-7,44],[-13,-41],[-25,-11],[14,33],[5,34],[10,29],[-2,44],[-22,-50],[-18,-21],[-10,-47],[-22,25],[1,31],[-18,43],[-14,22],[5,14],[-36,35],[-19,2],[-27,29],[-50,-6],[-36,-21],[-31,-20],[-27,4],[-29,-30],[-24,-14],[-6,-31],[-10,-24],[-23,-1],[-18,-5],[-24,10],[-20,-6],[-19,-3],[-17,-31],[-8,2],[-14,-16],[-13,-19],[-21,2],[-18,0],[-30,38],[-15,11],[1,34],[14,8],[4,14],[-1,21],[4,41],[-3,35],[-15,60],[-4,33],[1,34],[-11,38],[-1,18],[-12,23],[-4,47],[-16,46],[-4,26],[13,-26],[-10,55],[14,-17],[8,-23],[0,30],[-14,47],[-3,18],[-6,18],[3,34],[6,15],[4,29],[-3,35],[11,42],[2,-45],[12,41],[22,20],[14,25],[21,22],[13,4],[7,-7],[22,22],[17,6],[4,13],[8,6],[15,-2],[29,18],[15,26],[7,31],[17,30],[1,24],[1,32],[19,50],[12,-51],[12,12],[-10,28],[9,29],[12,-13],[3,45],[15,29],[7,23],[14,10],[0,17],[13,-7],[0,15],[12,8],[14,8],[20,-27],[16,-35],[17,0],[18,-6],[-6,33],[13,47],[13,15],[-5,15],[12,34],[17,21],[14,-7],[24,11],[-1,30],[-20,19],[15,9],[18,-15],[15,-24],[23,-15],[8,6],[17,-18],[17,17],[10,-5],[7,11],[12,-29],[-7,-32],[-11,-24],[-9,-2],[3,-23],[-8,-30],[-10,-29],[2,-17],[22,-32],[21,-19],[15,-20],[20,-35],[8,0],[14,-15],[4,-19],[27,-20],[18,20],[6,32],[5,26],[4,33],[8,47],[-4,28],[2,17],[-3,34],[4,45],[5,12],[-4,20],[7,31],[5,32],[1,17],[10,22],[8,-29],[2,-37],[7,-7],[1,-25],[10,-30],[2,-33],[-1,-22]],[[5471,7900],[-2,-24],[-16,0],[6,-13],[-9,-38]],[[5450,7825],[-6,-10],[-24,-1],[-14,-13],[-23,4]],[[5383,7805],[-40,15],[-6,21],[-27,-10],[-4,-12],[-16,9]],[[5290,7828],[-15,1],[-12,11],[4,15],[-1,10]],[[5266,7865],[8,3],[14,-16],[4,16],[25,-3],[20,11],[13,-2],[9,-12],[2,10],[-4,38],[10,8],[10,27]],[[5377,7945],[21,-19],[15,24],[10,5],[22,-18],[13,3],[13,-12]],[[5471,7928],[-3,-7],[3,-21]],[[6281,7346],[-19,8],[-14,27],[-4,23]],[[6349,7527],[15,-31],[14,-42],[13,-2],[8,-16],[-23,-5],[-5,-46],[-4,-21],[-11,-13],[1,-30]],[[6357,7321],[-7,-3],[-17,31],[10,30],[-9,17],[-10,-4],[-33,-44]],[[6249,7494],[6,10],[21,-17],[15,-4],[4,7],[-14,32],[7,9]],[[6288,7531],[8,-2],[19,-36],[13,-4],[4,15],[17,23]],[[5814,4792],[-1,71],[-7,27]],[[5806,4890],[17,-5],[8,34],[15,-4]],[[5846,4915],[1,-23],[6,-14],[1,-19],[-7,-12],[-11,-31],[-10,-22],[-12,-2]],[[5092,8091],[20,-5],[26,12],[17,-25],[16,-14]],[[5171,8059],[-4,-40]],[[5167,8019],[-7,-2],[-3,-33]],[[5157,7984],[-24,26],[-14,-4],[-20,28],[-13,23],[-13,1],[-4,21]],[[5069,8079],[23,12]],[[5074,5427],[-23,-7]],[[5051,5420],[-7,41],[2,136],[-6,12],[-1,29],[-10,21],[-8,17],[3,31]],[[5024,5707],[10,7],[6,26],[13,5],[6,18]],[[5059,5763],[10,17],[10,0],[21,-34]],[[5100,5746],[-1,-19],[6,-35],[-6,-24],[3,-16],[-13,-37],[-9,-18],[-5,-37],[1,-38],[-2,-95]],[[4921,5627],[-19,15],[-13,-2],[-10,-15],[-12,13],[-5,19],[-13,13]],[[4849,5670],[-1,34],[7,26],[-1,20],[23,48],[4,41],[7,14],[14,-8],[11,12],[4,16],[22,26],[5,19],[26,24],[15,9],[7,-12],[18,0]],[[5010,5939],[-2,-28],[3,-27],[16,-39],[1,-28],[32,-14],[-1,-40]],[[5024,5707],[-24,1]],[[5e3,5708],[-13,5],[-9,-9],[-12,4],[-48,-3],[-1,-33],[4,-45]],[[7573,6360],[0,-43],[-10,9],[2,-47]],[[7565,6279],[-8,30],[-1,31],[-6,28],[-11,34],[-26,3],[3,-25],[-9,-32],[-12,12],[-4,-11],[-8,6],[-11,5]],[[7472,6360],[-4,49],[-10,45],[5,35],[-17,16],[6,22],[18,22],[-20,31],[9,40],[22,-26],[14,-3],[2,-41],[26,-8],[26,1],[16,-10],[-13,-50],[-12,-3],[-9,-34],[16,-31],[4,38],[8,0],[14,-93]],[[5629,7671],[8,-25],[11,5],[21,-9],[41,-4],[13,16],[33,13],[20,-21],[17,-6]],[[5793,7640],[-15,-25],[-10,-42],[9,-34]],[[5777,7539],[-24,8],[-28,-18]],[[5725,7529],[0,-30],[-26,-5],[-19,20],[-22,-16],[-21,2]],[[5637,7500],[-2,39],[-14,19]],[[5621,7558],[5,8],[-3,7],[4,19],[11,18],[-14,26],[-2,21],[7,14]],[[2846,6461],[-7,-3],[-7,34],[-10,17],[6,38],[8,-3],[10,-49],[0,-34]],[[2838,6628],[-30,-10],[-2,22],[13,5],[18,-2],[1,-15]],[[2861,6628],[-5,-42],[-5,8],[0,31],[-12,23],[0,7],[22,-27]],[[5527,7708],[10,0],[-7,-26],[14,-23],[-4,-28],[-7,-2]],[[5533,7629],[-5,-6],[-9,-13],[-4,-33]],[[5515,7577],[-25,23],[-10,24],[-11,13],[-12,22],[-6,19],[-14,27],[6,25],[10,-14],[6,12],[13,2],[24,-10],[19,1],[12,-13]],[[5652,8242],[27,0],[30,22],[6,34],[23,19],[-3,26]],[[5735,8343],[17,10],[30,23]],[[5782,8376],[29,-15],[4,-15],[15,7],[27,-14],[3,-27],[-6,-16],[17,-39],[12,-11],[-2,-11],[19,-10],[8,-16],[-11,-13],[-23,2],[-5,-5],[7,-20],[6,-37]],[[5882,8136],[-23,-4],[-9,-13],[-2,-30],[-11,6],[-25,-3],[-7,14],[-11,-10],[-10,8],[-22,1],[-31,15],[-28,4],[-22,-1],[-15,-16],[-13,-2]],[[5653,8105],[-1,26],[-8,27],[17,12],[0,24],[-8,22],[-1,26]],[[2524,6110],[-1,8],[4,3],[5,-7],[10,36],[5,0]],[[2547,6150],[0,-8],[5,-1],[0,-16],[-5,-25],[3,-9],[-3,-21],[2,-6],[-4,-30],[-5,-16],[-5,-1],[-6,-21]],[[2529,5996],[-8,0],[2,67],[1,47]],[[3136,3714],[-20,-8],[-11,82],[-15,66],[9,57],[-15,25],[-4,43],[-13,40]],[[3067,4019],[17,64],[-12,49],[7,20],[-5,22],[10,30],[1,50],[1,41],[6,20],[-24,96]],[[3068,4411],[21,-5],[14,1],[6,18],[25,24],[14,22],[37,10],[-3,-44],[3,-23],[-2,-40],[30,-53],[31,-9],[11,-23],[19,-11],[11,-17],[18,0],[16,-17],[1,-34],[6,-18],[0,-25],[-8,-1],[11,-69],[53,-2],[-4,-35],[3,-23],[15,-16],[6,-37],[-4,-47],[-8,-26],[3,-33],[-9,-12]],[[3384,3866],[-1,18],[-25,30],[-26,1],[-49,-17],[-13,-52],[-1,-32],[-11,-71]],[[3482,3537],[6,34],[3,35],[1,32],[-10,11],[-11,-9],[-10,2],[-4,23],[-2,54],[-5,18],[-19,16],[-11,-12],[-30,11],[2,81],[-8,33]],[[3068,4411],[-15,-11],[-13,7],[2,90],[-23,-35],[-24,2],[-11,31],[-18,4],[5,25],[-15,36],[-11,53],[7,11],[0,25],[17,17],[-3,32],[7,20],[2,28],[32,40],[22,11],[4,9],[25,-2]],[[3058,4804],[13,162],[0,25],[-4,34],[-12,22],[0,42],[15,10],[6,-6],[1,23],[-16,6],[-1,37],[54,-2],[10,21],[7,-19],[6,-35],[5,8]],[[3142,5132],[15,-32],[22,4],[5,18],[21,14],[11,10],[4,25],[19,17],[-1,12],[-24,5],[-3,37],[1,40],[-13,15],[5,6],[21,-8],[22,-15],[8,14],[20,9],[31,23],[10,22],[-3,17]],[[3313,5365],[14,2],[7,-13],[-4,-26],[9,-9],[7,-28],[-8,-20],[-4,-51],[7,-30],[2,-27],[17,-28],[14,-3],[3,12],[8,3],[13,10],[9,16],[15,-5],[7,2]],[[3429,5170],[15,-5],[3,12],[-5,12],[3,17],[11,-5],[13,6],[16,-13]],[[3485,5194],[12,-12],[9,16],[6,-3],[4,-16],[13,4],[11,22],[8,44],[17,54]],[[3565,5303],[9,3],[7,-33],[16,-103],[14,-10],[1,-41],[-21,-48],[9,-18],[49,-9],[1,-60],[21,39],[35,-21],[46,-36],[14,-35],[-5,-32],[33,18],[54,-32],[41,3],[41,-49],[36,-66],[21,-17],[24,-3],[10,-18],[9,-76],[5,-35],[-11,-98],[-14,-39],[-39,-82],[-18,-67],[-21,-51],[-7,-1],[-7,-43],[2,-111],[-8,-91],[-3,-39],[-9,-23],[-5,-79],[-28,-77],[-5,-61],[-22,-26],[-7,-35],[-30,0],[-44,-23],[-19,-26],[-31,-18],[-33,-47],[-23,-58],[-5,-44],[5,-33],[-5,-60],[-6,-28],[-20,-33],[-31,-104],[-24,-47],[-19,-27],[-13,-57],[-18,-33]],[[3517,3063],[-8,33],[13,28],[-16,40],[-22,33],[-29,38],[-10,-2],[-28,46],[-18,-7]],[[8172,5325],[11,22],[23,32]],[[8206,5379],[-1,-29],[-2,-37],[-13,1],[-6,-20],[-12,31]],[[7546,6698],[12,-19],[-2,-36],[-23,-2],[-23,4],[-18,-9],[-25,22],[-1,12]],[[7466,6670],[19,44],[15,15],[20,-14],[14,-1],[12,-16]],[[5817,3752],[-39,-43],[-25,-44],[-10,-40],[-8,-22],[-15,-4],[-5,-29],[-3,-18],[-17,-14],[-23,3],[-13,17],[-12,7],[-14,-14],[-6,-28],[-14,-18],[-13,-26],[-20,-6],[-6,20],[2,36],[-16,56],[-8,9]],[[5552,3594],[0,173],[27,2],[1,210],[21,2],[43,21],[10,-24],[18,23],[9,0],[15,13]],[[5696,4014],[5,-4]],[[5701,4010],[11,-48],[5,-10],[9,-34],[32,-65],[12,-7],[0,-20],[8,-38],[21,-9],[18,-27]],[[5424,5496],[23,4],[5,16],[5,-2],[7,-13],[34,23],[12,23],[15,20],[-3,21],[8,6],[27,-4],[26,27],[20,65],[14,24],[18,10]],[[5635,5716],[3,-26],[16,-36],[0,-25],[-5,-24],[2,-18],[10,-18]],[[5661,5569],[21,-25]],[[5682,5544],[15,-24],[0,-19],[19,-31],[12,-26],[7,-35],[20,-24],[5,-18]],[[5760,5367],[-9,-7],[-18,2],[-21,6],[-10,-5],[-5,-14],[-9,-2],[-10,12],[-31,-29],[-13,6],[-4,-5],[-8,-35],[-21,11],[-20,6],[-18,22],[-23,20],[-15,-19],[-10,-30],[-3,-41]],[[5512,5265],[-18,3],[-19,10],[-16,-32],[-15,-55]],[[5444,5191],[-3,18],[-1,27],[-13,19],[-10,30],[-2,21],[-13,31],[2,18],[-3,25],[2,45],[7,11],[14,60]],[[3231,7808],[20,-8],[26,1],[-14,-24],[-10,-4],[-35,25],[-7,20],[10,18],[10,-28]],[[3283,7958],[-14,-1],[-36,19],[-26,28],[10,5],[37,-15],[28,-25],[1,-11]],[[1569,7923],[-14,-8],[-46,27],[-8,21],[-25,21],[-5,16],[-28,11],[-11,32],[2,14],[30,-13],[17,-9],[26,-6],[9,-21],[14,-28],[28,-24],[11,-33]],[[3440,8052],[-18,-52],[18,20],[19,-12],[-10,-21],[25,-16],[12,14],[28,-18],[-8,-43],[19,10],[4,-32],[8,-36],[-11,-52],[-13,-2],[-18,11],[6,48],[-8,8],[-32,-52],[-17,2],[20,28],[-27,14],[-30,-3],[-54,2],[-4,17],[17,21],[-12,16],[24,36],[28,94],[18,33],[24,21],[13,-3],[-6,-16],[-15,-37]],[[1313,8250],[27,5],[-8,-67],[24,-48],[-11,0],[-17,27],[-10,27],[-14,19],[-5,26],[1,19],[13,-8]],[[2798,8730],[-11,-31],[-12,5],[-8,17],[2,4],[10,18],[12,-1],[7,-12]],[[2725,8762],[-33,-32],[-19,1],[-6,16],[20,27],[38,0],[0,-12]],[[2634,8936],[5,-26],[15,9],[16,-15],[30,-20],[32,-19],[2,-28],[21,5],[20,-20],[-25,-18],[-43,14],[-16,26],[-27,-31],[-40,-31],[-9,35],[-38,-6],[24,30],[4,46],[9,54],[20,-5]],[[2892,9024],[-31,-3],[-7,29],[12,34],[26,8],[21,-17],[1,-25],[-4,-8],[-18,-18]],[[2343,9140],[-17,-21],[-38,18],[-22,-6],[-38,26],[24,19],[19,25],[30,-16],[17,-11],[8,-11],[17,-23]],[[3135,7724],[-18,33],[0,81],[-13,17],[-18,-10],[-10,16],[-21,-45],[-8,-46],[-10,-27],[-12,-9],[-9,-3],[-3,-15],[-51,0],[-42,0],[-12,-11],[-30,-42],[-3,-5],[-9,-23],[-26,0],[-27,0],[-12,-10],[4,-11],[2,-18],[0,-6],[-36,-30],[-29,-9],[-32,-31],[-7,0],[-10,9],[-3,8],[1,6],[6,21],[13,33],[8,35],[-5,51],[-6,53],[-29,28],[3,11],[-4,7],[-8,0],[-5,9],[-2,14],[-5,-6],[-7,2],[1,6],[-6,6],[-3,15],[-21,19],[-23,20],[-27,23],[-26,21],[-25,-17],[-9,0],[-34,15],[-23,-8],[-27,19],[-28,9],[-19,4],[-9,10],[-5,32],[-9,0],[-1,-23],[-57,0],[-95,0],[-94,0],[-84,0],[-83,0],[-82,0],[-85,0],[-27,0],[-82,0],[-79,0]],[[1588,7952],[-4,0],[-54,58],[-20,26],[-50,24],[-15,53],[3,36],[-35,25],[-5,48],[-34,43],[0,30]],[[1374,8295],[15,29],[0,37],[-48,37],[-28,68],[-17,42],[-26,27],[-19,24],[-14,31],[-28,-20],[-27,-33],[-25,39],[-19,26],[-27,16],[-28,2],[0,337],[1,219]],[[1084,9176],[51,-14],[44,-29],[29,-5],[24,24],[34,19],[41,-7],[42,26],[45,14],[20,-24],[20,14],[6,27],[20,-6],[47,-53],[37,40],[3,-45],[34,10],[11,17],[34,-3],[42,-25],[65,-22],[38,-10],[28,4],[37,-30],[-39,-29],[50,-13],[75,7],[24,11],[29,-36],[31,30],[-29,25],[18,20],[34,3],[22,6],[23,-14],[28,-32],[31,5],[49,-27],[43,9],[40,-1],[-3,37],[25,10],[43,-20],[0,-56],[17,47],[23,-1],[12,59],[-30,36],[-32,24],[2,65],[33,43],[37,-9],[28,-26],[38,-67],[-25,-29],[52,-12],[-1,-60],[38,46],[33,-38],[-9,-44],[27,-40],[29,43],[21,51],[1,65],[40,-5],[41,-8],[37,-30],[2,-29],[-21,-31],[20,-32],[-4,-29],[-54,-41],[-39,-9],[-29,18],[-8,-30],[-27,-50],[-8,-26],[-32,-40],[-40,-4],[-22,-25],[-2,-38],[-32,-7],[-34,-48],[-30,-67],[-11,-46],[-1,-69],[40,-10],[13,-55],[13,-45],[39,12],[51,-26],[28,-22],[20,-28],[35,-17],[29,-24],[46,-4],[30,-6],[-4,-51],[8,-59],[21,-66],[41,-56],[21,19],[15,61],[-14,93],[-20,31],[45,28],[31,41],[16,41],[-3,40],[-19,50],[-33,44],[32,62],[-12,54],[-9,92],[19,14],[48,-16],[29,-6],[23,15],[25,-20],[35,-34],[8,-23],[50,-4],[-1,-50],[9,-74],[25,-10],[21,-35],[40,33],[26,65],[19,28],[21,-53],[36,-75],[31,-71],[-11,-37],[37,-33],[25,-34],[44,-15],[18,-19],[11,-50],[22,-8],[11,-22],[2,-67],[-20,-22],[-20,-21],[-46,-21],[-35,-48],[-47,-10],[-59,13],[-42,0],[-29,-4],[-23,-43],[-35,-26],[-40,-78],[-32,-54],[23,9],[45,78],[58,49],[42,6],[24,-29],[-26,-40],[9,-63],[9,-45],[36,-29],[46,8],[28,67],[2,-43],[17,-22],[-34,-38],[-61,-36],[-28,-23],[-31,-43],[-21,4],[-1,50],[48,49],[-44,-2],[-31,-7]],[[1829,9377],[-14,-27],[61,17],[39,-29],[31,30],[26,-20],[23,-58],[14,25],[-20,60],[24,9],[28,-9],[31,-24],[17,-58],[9,-41],[47,-30],[50,-28],[-3,-26],[-46,-4],[18,-23],[-9,-22],[-51,9],[-48,16],[-32,-3],[-52,-20],[-70,-9],[-50,-6],[-15,28],[-38,16],[-24,-6],[-35,47],[19,6],[43,10],[39,-3],[36,11],[-54,13],[-59,-4],[-39,1],[-15,22],[64,23],[-42,-1],[-49,16],[23,44],[20,24],[74,36],[29,-12]],[[2097,9395],[-24,-39],[-44,41],[10,9],[37,2],[21,-13]],[[2879,9376],[3,-16],[-30,2],[-30,1],[-30,-8],[-8,3],[-31,32],[1,21],[14,4],[63,-6],[48,-33]],[[2595,9379],[22,-36],[26,47],[70,24],[48,-61],[-4,-38],[55,17],[26,23],[62,-30],[38,-28],[3,-25],[52,13],[29,-38],[67,-23],[24,-24],[26,-55],[-51,-28],[66,-38],[44,-13],[40,-55],[44,-3],[-9,-42],[-49,-69],[-34,26],[-44,57],[-36,-8],[-3,-34],[29,-34],[38,-27],[11,-16],[18,-58],[-9,-43],[-35,16],[-70,47],[39,-51],[29,-35],[5,-21],[-76,24],[-59,34],[-34,29],[10,17],[-42,30],[-40,29],[0,-18],[-80,-9],[-23,20],[18,44],[52,1],[57,7],[-9,21],[10,30],[36,57],[-8,27],[-11,20],[-42,29],[-57,20],[18,15],[-29,36],[-25,4],[-22,20],[-14,-18],[-51,-7],[-101,13],[-59,17],[-45,9],[-23,21],[29,27],[-39,0],[-9,60],[21,53],[29,24],[72,16],[-21,-39]],[[2212,9420],[33,-12],[50,7],[7,-17],[-26,-28],[42,-26],[-5,-53],[-45,-23],[-27,5],[-19,23],[-69,45],[0,19],[57,-7],[-31,38],[33,29]],[[2411,9357],[-30,-45],[-32,3],[-17,52],[1,29],[14,25],[28,16],[58,-2],[53,-14],[-42,-53],[-33,-11]],[[1654,9275],[-73,-29],[-15,26],[-64,31],[12,25],[19,43],[24,39],[-27,36],[94,10],[39,-13],[71,-3],[27,-17],[30,-25],[-35,-15],[-68,-41],[-34,-42],[0,-25]],[[2399,9487],[-15,-23],[-40,5],[-34,15],[15,27],[40,16],[24,-21],[10,-19]],[[2264,9590],[21,-27],[1,-31],[-13,-44],[-46,-6],[-30,10],[1,34],[-45,-4],[-2,45],[30,-2],[41,21],[40,-4],[2,8]],[[1994,9559],[11,-21],[25,10],[29,-2],[5,-29],[-17,-28],[-94,-10],[-70,-25],[-43,-2],[-3,20],[57,26],[-125,-7],[-39,10],[38,58],[26,17],[78,-20],[50,-35],[48,-5],[-40,57],[26,21],[29,-7],[9,-28]],[[2370,9612],[30,-19],[55,0],[24,-19],[-6,-22],[32,-14],[17,-14],[38,-2],[40,-5],[44,13],[57,5],[45,-5],[30,-22],[6,-24],[-17,-16],[-42,-13],[-35,8],[-80,-10],[-57,-1],[-45,8],[-74,19],[-9,32],[-4,29],[-27,26],[-58,7],[-32,19],[10,24],[58,-4]],[[1772,9645],[-4,-46],[-21,-20],[-26,-3],[-52,-26],[-44,-9],[-38,13],[47,44],[57,39],[43,-1],[38,9]],[[2393,9637],[-13,-2],[-52,4],[-7,17],[56,-1],[19,-11],[-3,-7]],[[1939,9648],[-52,-17],[-41,19],[23,19],[40,6],[39,-10],[-9,-17]],[[1954,9701],[-34,-11],[-46,0],[0,8],[29,18],[14,-3],[37,-12]],[[2338,9669],[-41,-12],[-23,13],[-12,23],[-2,24],[36,-2],[16,-4],[33,-21],[-7,-21]],[[2220,9685],[11,-25],[-45,7],[-46,19],[-62,2],[27,18],[-34,14],[-2,22],[55,-8],[75,-21],[21,-28]],[[2583,9764],[33,-20],[-38,-17],[-51,-45],[-50,-4],[-57,8],[-30,24],[0,21],[22,16],[-50,0],[-31,19],[-18,27],[20,26],[19,18],[28,4],[-12,14],[65,3],[35,-32],[47,-12],[46,-11],[22,-39]],[[3097,9967],[74,-4],[60,-8],[51,-16],[-2,-16],[-67,-25],[-68,-12],[-25,-14],[61,1],[-66,-36],[-45,-17],[-48,-48],[-57,-10],[-18,-12],[-84,-6],[39,-8],[-20,-10],[23,-29],[-26,-21],[-43,-16],[-13,-24],[-39,-17],[4,-14],[48,3],[0,-15],[-74,-35],[-73,16],[-81,-9],[-42,7],[-52,3],[-4,29],[52,13],[-14,43],[17,4],[74,-26],[-38,38],[-45,11],[23,23],[49,14],[8,21],[-39,23],[-12,31],[76,-3],[22,-6],[43,21],[-62,7],[-98,-4],[-49,20],[-23,24],[-32,17],[-6,21],[41,11],[32,2],[55,9],[41,22],[34,-3],[30,-16],[21,32],[37,9],[50,7],[85,2],[14,-6],[81,10],[60,-4],[60,-4]],[[5290,7828],[-3,-24],[-12,-10],[-20,7],[-6,-24],[-14,-2],[-5,10],[-15,-20],[-13,-3],[-12,13]],[[5190,7775],[-10,25],[-13,-9],[0,27],[21,33],[-1,15],[12,-5],[8,10]],[[5207,7871],[24,-1],[5,13],[30,-18]],[[3140,1814],[-10,-24],[-23,-18],[-14,2],[-16,5],[-21,18],[-29,8],[-35,33],[-28,32],[-38,66],[23,-12],[39,-40],[36,-21],[15,27],[9,41],[25,24],[20,-7]],[[3095,1968],[-25,0],[-13,-14],[-25,-22],[-5,-55],[-11,-1],[-32,19],[-32,41],[-34,34],[-9,37],[8,35],[-14,39],[-4,101],[12,57],[30,45],[-43,18],[27,52],[9,98],[31,-21],[15,123],[-19,15],[-9,-73],[-17,8],[9,84],[9,110],[13,40],[-8,58],[-2,66],[11,2],[17,96],[20,94],[11,88],[-6,89],[8,49],[-3,72],[16,73],[5,114],[9,123],[9,132],[-2,96],[-6,84]],[[3045,3974],[14,15],[8,30]],[[8064,6161],[-24,-28],[-23,18],[0,51],[13,26],[31,17],[16,-1],[6,-23],[-12,-26],[-7,-34]],[[8628,7562],[-18,35],[-11,-33],[-43,-26],[4,-31],[-24,2],[-13,19],[-19,-42],[-30,-32],[-23,-38]],[[8451,7416],[-39,-17],[-20,-27],[-30,-17],[15,28],[-6,23],[22,40],[-15,30],[-24,-20],[-32,-41],[-17,-39],[-27,-2],[-14,-28],[15,-40],[22,-10],[1,-26],[22,-17],[31,42],[25,-23],[18,-2],[4,-31],[-39,-16],[-13,-32],[-27,-30],[-14,-41],[30,-33],[11,-58],[17,-54],[18,-45],[0,-44],[-17,-16],[6,-32],[17,-18],[-5,-48],[-7,-47],[-15,-5],[-21,-64],[-22,-78],[-26,-70],[-38,-55],[-39,-50],[-31,-6],[-17,-27],[-10,20],[-15,-30],[-39,-29],[-29,-9],[-10,-63],[-15,-3],[-8,43],[7,22],[-37,19],[-13,-9]],[[8001,6331],[-28,15],[-14,24],[5,34],[-26,11],[-13,22],[-24,-31],[-27,-7],[-22,0],[-15,-14]],[[7837,6385],[-14,-9],[4,-68],[-15,2],[-2,14]],[[7810,6324],[-1,24],[-20,-17],[-12,11],[-21,22],[8,49],[-18,12],[-6,54],[-30,-10],[4,70],[26,50],[1,48],[-1,46],[-12,14],[-9,35],[-16,-5]],[[7703,6727],[-30,9],[9,25],[-13,36],[-20,-24],[-23,14],[-32,-37],[-25,-44],[-23,-8]],[[7466,6670],[-2,47],[-17,-13]],[[7447,6704],[-32,6],[-32,14],[-22,26],[-22,11],[-9,29],[-16,8],[-28,39],[-22,18],[-12,-14]],[[7252,6841],[-38,41],[-28,37],[-7,65],[20,-7],[1,30],[-12,30],[3,48],[-30,69]],[[7161,7154],[-45,24],[-8,46],[-21,27]],[[7082,7268],[-4,34],[1,23],[-17,13],[-9,-6],[-7,55]],[[7046,7387],[8,13],[-4,14],[26,28],[20,12],[29,-8],[11,38],[35,7],[10,23],[44,32],[4,13]],[[7229,7559],[-2,34],[19,15],[-25,103],[55,24],[14,13],[20,106],[55,-20],[15,27],[2,59],[23,6],[21,39]],[[7426,7965],[11,5]],[[7437,7970],[7,-41],[23,-32],[40,-22],[19,-47],[-10,-70],[10,-25],[33,-10],[37,-8],[33,-37],[18,-7],[12,-54],[17,-35],[30,1],[58,-13],[36,8],[28,-9],[41,-36],[34,0],[12,-18],[32,32],[45,20],[42,2],[32,21],[20,32],[20,20],[-5,19],[-9,23],[15,38],[15,-5],[29,-12],[28,31],[42,23],[20,39],[20,17],[40,8],[22,-7],[3,21],[-25,41],[-22,19],[-22,-22],[-27,10],[-16,-8],[-7,24],[20,59],[13,45]],[[8240,8005],[34,-23],[39,38],[-1,26],[26,62],[15,19],[0,33],[-16,14],[23,29],[35,11],[37,2],[41,-18],[25,-22],[17,-59],[10,-26],[10,-36],[10,-58],[49,-19],[32,-42],[12,-55],[42,0],[24,23],[46,17],[-15,-53],[-11,-21],[-9,-65],[-19,-58],[-33,11],[-24,-21],[7,-51],[-4,-69],[-14,-2],[0,-30]],[[4920,5353],[-12,-1],[-20,12],[-18,-1],[-33,-10],[-19,-18],[-27,-21],[-6,1]],[[4785,5315],[2,49],[3,7],[-1,24],[-12,24],[-8,4],[-8,17],[6,26],[-3,28],[1,18]],[[4765,5512],[5,0],[1,25],[-2,12],[3,8],[10,7],[-7,47],[-6,25],[2,20],[5,4]],[[4776,5660],[4,6],[8,-9],[21,-1],[5,18],[5,-1],[8,6],[4,-25],[7,7],[11,9]],[[4921,5627],[7,-84],[-11,-50],[-8,-66],[12,-51],[-1,-23]],[[5363,5191],[-4,4],[-16,-8],[-17,8],[-13,-4]],[[5313,5191],[-45,1]],[[5268,5192],[4,47],[-11,39],[-13,10],[-6,27],[-7,8],[1,16]],[[5236,5339],[7,42],[13,57],[8,1],[17,34],[10,1],[16,-24],[19,20],[2,25],[7,23],[4,30],[15,25],[5,41],[6,13],[4,31],[7,37],[24,46],[1,20],[3,10],[-11,24]],[[5393,5795],[1,19],[8,3]],[[5402,5817],[11,-38],[2,-39],[-1,-39],[15,-54],[-15,1],[-8,-4],[-13,6],[-6,-28],[16,-35],[13,-10],[3,-24],[9,-41],[-4,-16]],[[5444,5191],[-2,-31],[-22,14],[-22,15],[-35,2]],[[5856,5265],[-2,-69],[11,-8],[-9,-21],[-10,-16],[-11,-31],[-6,-27],[-1,-48],[-7,-22],[0,-45]],[[5821,4978],[-8,-16],[-1,-35],[-4,-5],[-2,-32]],[[5814,4792],[5,-55],[-2,-30],[5,-35],[16,-33],[15,-74]],[[5853,4565],[-11,6],[-37,-10],[-7,-7],[-8,-38],[6,-26],[-5,-70],[-3,-59],[7,-11],[19,-23],[8,11],[2,-64],[-21,1],[-11,32],[-10,25],[-22,9],[-6,31],[-17,-19],[-22,8],[-10,27],[-17,6],[-13,-2],[-2,19],[-9,1]],[[5342,4697],[-4,18]],[[5360,4775],[8,-6],[9,23],[15,-1],[2,-17],[11,-10],[16,37],[16,29],[7,19],[-1,48],[12,58],[13,30],[18,29],[3,18],[1,22],[5,21],[-2,33],[4,52],[5,37],[8,32],[2,36]],[[5760,5367],[17,-49],[12,-7],[8,10],[12,-4],[16,12],[6,-25],[25,-39]],[[5330,4760],[-22,62]],[[5308,4822],[21,33],[-11,39],[10,15],[19,7],[2,26],[15,-28],[24,-2],[9,27],[3,40],[-3,46],[-13,35],[12,68],[-7,12],[-21,-5],[-7,31],[2,25]],[[2906,5049],[-12,14],[-14,19],[-7,-9],[-24,8],[-7,25],[-5,-1],[-28,34]],[[2809,5139],[-3,18],[10,5],[-1,29],[6,22],[14,4],[12,37],[10,31],[-10,14],[5,34],[-6,54],[6,16],[-4,50],[-12,31]],[[2836,5484],[4,29],[9,-4],[5,17],[-6,35],[3,9]],[[2851,5570],[14,-2],[21,41],[12,6],[0,20],[5,50],[16,27],[17,1],[3,13],[21,-5],[22,30],[11,13],[14,28],[9,-3],[8,-16],[-6,-20]],[[3018,5753],[-18,-10],[-7,-29],[-10,-17],[-8,-22],[-4,-42],[-8,-35],[15,-4],[3,-27],[6,-13],[3,-24],[-4,-22],[1,-12],[7,-5],[7,-20],[36,5],[16,-7],[19,-51],[11,6],[20,-3],[16,7],[10,-10],[-5,-32],[-6,-20],[-2,-42],[5,-40],[8,-17],[1,-13],[-14,-30],[10,-13],[8,-21],[8,-58]],[[3058,4804],[-14,31],[-8,1],[18,61],[-21,27],[-17,-5],[-10,10],[-15,-15],[-21,7],[-16,62],[-13,15],[-9,28],[-19,28],[-7,-5]],[[2695,5543],[-15,14],[-6,12],[4,10],[-1,13],[-8,14],[-11,12],[-10,8],[-1,17],[-8,10],[2,-17],[-5,-14],[-7,17],[-9,5],[-4,12],[1,18],[3,19],[-8,8],[7,12]],[[2619,5713],[4,7],[18,-15],[7,7],[9,-5],[4,-12],[8,-4],[7,13]],[[2676,5704],[7,-32],[11,-24],[13,-25]],[[2707,5623],[-11,-6],[0,-23],[6,-9],[-4,-7],[1,-11],[-2,-12],[-2,-12]],[[2715,6427],[23,-4],[22,0],[26,-21],[11,-21],[26,6],[10,-13],[24,-37],[17,-27],[9,1],[17,-12],[-2,-17],[20,-2],[21,-24],[-3,-14],[-19,-7],[-18,-3],[-19,4],[-40,-5],[18,32],[-11,16],[-18,4],[-9,17],[-7,33],[-16,-2],[-26,16],[-8,12],[-36,10],[-10,11],[11,15],[-28,3],[-20,-31],[-11,-1],[-4,-14],[-14,-7],[-12,6],[15,18],[6,22],[13,13],[14,11],[21,6],[7,6]],[[5909,7133],[2,1],[4,14],[20,-1],[25,18],[-19,-25],[2,-11]],[[5943,7129],[-3,2],[-5,-5],[-4,1],[-2,-2],[0,6],[-2,4],[-6,0],[-7,-5],[-5,3]],[[5943,7129],[1,-5],[-28,-24],[-14,8],[-7,23],[14,2]],[[5377,7945],[-16,25],[-14,15],[-3,25],[-5,17],[21,13],[10,15],[20,11],[7,11],[7,-6],[13,6]],[[5417,8077],[13,-19],[21,-5],[-2,-17],[15,-12],[4,15],[19,-6],[3,-19],[20,-3],[13,-29]],[[5523,7982],[-8,0],[-4,-11],[-7,-3],[-2,-13],[-5,-3],[-1,-5],[-9,-7],[-12,1],[-4,-13]],[[5275,8306],[1,-23],[28,-14],[-1,-21],[29,11],[15,16],[32,-23],[13,-19]],[[5392,8233],[6,-30],[-8,-16],[11,-21],[6,-31],[-2,-21],[12,-37]],[[5207,7871],[3,42],[14,40],[-40,11],[-13,16]],[[5171,7980],[2,26],[-6,13]],[[5171,8059],[-5,62],[17,0],[7,22],[6,54],[-5,20]],[[5191,8217],[6,13],[23,3],[5,-13],[19,29],[-6,22],[-2,34]],[[5236,8305],[21,-8],[18,9]],[[6196,5808],[7,-19],[-1,-24],[-16,-14],[12,-16]],[[6198,5735],[-10,-32]],[[6188,5703],[-7,11],[-6,-5],[-16,1],[0,18],[-2,17],[9,27],[10,26]],[[6176,5798],[12,-5],[8,15]],[[5352,8343],[-17,-48],[-29,33],[-4,25],[41,19],[9,-29]],[[5236,8305],[-11,32],[-1,61],[5,16],[8,17],[24,4],[10,16],[22,17],[-1,-30],[-8,-20],[4,-16],[15,-9],[-7,-22],[-8,6],[-20,-42],[7,-29]],[[3008,6222],[3,10],[22,0],[16,-15],[8,1],[5,-21],[15,1],[-1,-17],[12,-2],[14,-22],[-10,-24],[-14,13],[-12,-3],[-9,3],[-5,-11],[-11,-3],[-4,14],[-10,-8],[-11,-41],[-7,10],[-1,17]],[[3008,6124],[0,16],[-7,17],[7,10],[2,23],[-2,32]],[[5333,6444],[-95,-112],[-81,-117],[-39,-26]],[[5118,6189],[-31,-6],[0,38],[-13,10],[-17,16],[-7,28],[-94,129],[-93,129]],[[4863,6533],[-105,143]],[[4758,6676],[1,11],[0,4]],[[4759,6691],[0,70],[44,44],[28,9],[23,16],[11,29],[32,24],[1,44],[16,5],[13,22],[36,9],[5,23],[-7,13],[-10,62],[-1,36],[-11,38]],[[4939,7135],[27,32],[30,11],[17,24],[27,18],[47,11],[46,4],[14,-8],[26,23],[30,0],[11,-13],[19,3]],[[5233,7240],[-5,-30],[4,-56],[-6,-49],[-18,-33],[3,-45],[23,-35],[0,-14],[17,-24],[12,-106]],[[5263,6848],[9,-52],[1,-28],[-5,-48],[2,-27],[-3,-32],[2,-37],[-11,-25],[17,-43],[1,-25],[10,-33],[13,11],[22,-28],[12,-37]],[[2769,4856],[15,45],[-6,25],[-11,-27],[-16,26],[5,16],[-4,54],[9,9],[5,37],[11,38],[-2,24],[15,13],[19,23]],[[2906,5049],[4,-45],[-9,-39],[-30,-62],[-33,-23],[-17,-51],[-6,-40],[-15,-24],[-12,29],[-11,7],[-12,-5],[-1,22],[8,14],[-3,24]],[[5969,6800],[-7,-23],[-6,-45],[-8,-31],[-6,-10],[-10,19],[-12,26],[-20,85],[-3,-5],[12,-63],[17,-59],[21,-92],[10,-32],[9,-34],[25,-65],[-6,-10],[1,-39],[33,-53],[4,-12]],[[6023,6357],[-110,0],[-107,0],[-112,0]],[[5694,6357],[0,218],[0,210],[-8,47],[7,37],[-5,25],[10,29]],[[5698,6923],[37,0],[27,-15],[28,-18],[13,-9],[21,19],[11,17],[25,5],[20,-8],[7,-29],[7,19],[22,-14],[22,-3],[13,15]],[[5951,6902],[18,-102]],[[6176,5798],[-10,20],[-11,34],[-12,19],[-8,21],[-24,23],[-19,1],[-7,12],[-16,-14],[-17,27],[-8,-44],[-33,13]],[[6011,5910],[-3,23],[12,87],[3,39],[9,18],[20,10],[14,34]],[[6066,6121],[16,-69],[8,-54],[15,-29],[38,-55],[16,-34],[15,-34],[8,-20],[14,-18]],[[4749,7532],[1,42],[-11,25],[39,43],[34,-11],[37,1],[30,-10],[23,3],[45,-2]],[[4947,7623],[11,-23],[51,-27],[10,13],[31,-27],[32,8]],[[5082,7567],[2,-35],[-26,-39],[-36,-12],[-2,-20],[-18,-33],[-10,-48],[11,-34],[-16,-26],[-6,-39],[-21,-11],[-20,-46],[-35,-1],[-27,1],[-17,-21],[-11,-22],[-13,5],[-11,20],[-8,34],[-26,9]],[[4792,7249],[-2,20],[10,22],[4,16],[-9,17],[7,39],[-11,36],[12,5],[1,27],[5,9],[0,46],[13,16],[-8,30],[-16,2],[-5,-8],[-16,0],[-7,29],[-11,-8],[-10,-15]],[[5675,8472],[3,35],[-10,-8],[-18,21],[-2,34],[35,17],[35,8],[30,-10],[29,2]],[[5777,8571],[4,-10],[-20,-34],[8,-55],[-12,-19]],[[5757,8453],[-22,0],[-24,22],[-13,7],[-23,-10]],[[6188,5703],[-6,-21],[10,-32],[10,-29],[11,-21],[90,-70],[24,0]],[[6327,5530],[-79,-177],[-36,-3],[-25,-41],[-17,-1],[-8,-19]],[[6162,5289],[-19,0],[-11,20],[-26,-25],[-8,-24],[-18,4],[-6,7],[-7,-1],[-9,0],[-35,50],[-19,0],[-10,20],[0,33],[-14,10]],[[5980,5383],[-17,64],[-12,14],[-5,23],[-14,29],[-17,4],[9,34],[15,2],[4,18]],[[5943,5571],[0,53]],[[5943,5624],[8,62],[13,16],[3,24],[12,45],[17,30],[11,58],[4,51]],[[5794,9138],[-4,-42],[42,-39],[-26,-45],[33,-67],[-19,-51],[25,-43],[-11,-39],[41,-40],[-11,-31],[-25,-34],[-60,-75]],[[5779,8632],[-50,-5],[-49,-21],[-45,-13],[-16,32],[-27,20],[6,58],[-14,53],[14,35],[25,37],[63,64],[19,12],[-3,25],[-39,28]],[[5663,8957],[-9,23],[-1,91],[-43,40],[-37,29]],[[5573,9140],[17,16],[30,-32],[37,3],[30,-14],[26,26],[14,44],[43,20],[35,-24],[-11,-41]],[[9954,4033],[9,-17],[-4,-31],[-17,-8],[-16,7],[-2,26],[10,21],[13,-8],[7,10]],[[0,4079],[9981,-14],[-17,-13],[-4,23],[14,12],[9,3],[-9983,18]],[[0,4108],[0,-29]],[[0,4108],[6,3],[-4,-28],[-2,-4]],[[3300,1994],[33,36],[24,-15],[16,24],[22,-27],[-8,-21],[-37,-17],[-13,20],[-23,-26],[-14,26]],[[5265,7548],[-9,-46],[-13,12],[-6,40],[5,22],[18,22],[5,-50]],[[5157,7984],[6,-6],[8,2]],[[5190,7775],[-2,-17],[9,-22],[-10,-18],[7,-46],[15,-8],[-3,-25]],[[5206,7639],[-25,-34],[-55,16],[-40,-19],[-4,-35]],[[4947,7623],[14,35],[5,118],[-28,62],[-21,30],[-42,23],[-3,43],[36,12],[47,-15],[-9,67],[26,-25],[65,46],[8,48],[24,12]],[[3485,5194],[7,25],[3,27]],[[3495,5246],[4,26],[-10,34]],[[3489,5306],[-3,41],[15,51]],[[3501,5398],[9,-7],[21,-14],[29,-50],[5,-24]],[[5308,4822],[-29,60],[-18,49],[-17,61],[1,19],[6,19],[7,43],[5,44]],[[5263,5117],[10,4],[40,-1],[0,71]],[[4827,8240],[-21,12],[-17,-1],[6,32],[-6,32]],[[4789,8315],[23,2],[30,-37],[-15,-40]],[[4916,8521],[-30,-63],[29,8],[30,-1],[-7,-48],[-25,-53],[29,-4],[2,-6],[25,-69],[19,-10],[17,-67],[8,-24],[33,-11],[-3,-38],[-14,-17],[11,-30],[-25,-31],[-37,0],[-48,-16],[-13,12],[-18,-28],[-26,7],[-19,-23],[-15,12],[41,62],[25,13],[-1,0],[-43,9],[-8,24],[29,18],[-15,32],[5,39],[42,-6],[4,35],[-19,36],[0,1],[-34,10],[-7,16],[10,27],[-9,16],[-15,-28],[-1,57],[-14,30],[10,61],[21,48],[23,-4],[33,4]],[[6154,7511],[4,26],[-7,40],[-16,22],[-16,6],[-10,19]],[[6109,7624],[4,6],[23,-10],[41,-9],[38,-28],[5,-11],[17,9],[25,-13],[9,-24],[17,-13]],[[6210,7485],[-27,29],[-29,-3]],[[5029,5408],[-44,-35],[-15,-20],[-25,-17],[-25,17]],[[5e3,5708],[-2,-18],[12,-30],[0,-43],[2,-47],[7,-21],[-6,-54],[2,-29],[8,-37],[6,-21]],[[4765,5512],[-8,1],[-5,-24],[-8,1],[-6,12],[2,24],[-11,36],[-8,-7],[-6,-1]],[[4715,5554],[-7,-3],[0,21],[-4,16],[0,17],[-6,25],[-7,21],[-23,0],[-6,-11],[-8,-1],[-4,-13],[-4,-17],[-14,-26]],[[4632,5583],[-13,35],[-10,24],[-8,7],[-6,12],[-4,26],[-4,13],[-8,10]],[[4579,5710],[13,29],[8,-2],[7,10],[6,0],[5,8],[-3,20],[3,6],[1,20]],[[4619,5801],[13,-1],[20,-14],[6,1],[3,7],[15,-5],[4,4]],[[4680,5793],[1,-22],[5,0],[7,8],[5,-2],[7,-15],[12,-5],[8,13],[9,8],[6,8],[6,-1],[6,-13],[3,-17],[12,-24],[-6,-16],[-1,-19],[6,6],[3,-7],[-1,-17],[8,-18]],[[4532,5834],[3,27]],[[4535,5861],[31,1],[6,14],[9,1],[11,-14],[8,-1],[9,10],[6,-17],[-12,-13],[-12,1],[-12,13],[-10,-14],[-5,-1],[-7,-8],[-25,1]],[[4579,5710],[-15,24],[-11,4],[-7,17],[1,9],[-9,13],[-2,12]],[[4536,5789],[15,10],[9,-2],[8,7],[51,-3]],[[5263,5117],[-5,9],[10,66]],[[5658,7167],[15,-20],[22,3],[20,-4],[0,-10],[15,7],[-4,-18],[-40,-5],[1,10],[-34,12],[5,25]],[[5723,7469],[-17,2],[-14,6],[-34,-16],[19,-33],[-14,-10],[-15,0],[-15,31],[-5,-13],[6,-36],[14,-27],[-10,-13],[15,-27],[14,-18],[0,-33],[-25,16],[8,-30],[-18,-7],[11,-52],[-19,-1],[-23,26],[-10,47],[-5,40],[-11,27],[-14,34],[-2,16]],[[5583,7470],[18,6],[11,13],[15,-2],[5,11],[5,2]],[[5725,7529],[13,-16],[-8,-37],[-7,-7]],[[3701,9939],[93,35],[97,-2],[36,21],[98,6],[222,-7],[174,-47],[-52,-23],[-106,-3],[-150,-5],[14,-11],[99,7],[83,-21],[54,18],[23,-21],[-30,-34],[71,22],[135,23],[83,-12],[15,-25],[-113,-42],[-16,-14],[-88,-10],[64,-3],[-32,-43],[-23,-38],[1,-66],[33,-38],[-43,-3],[-46,-19],[52,-31],[6,-50],[-30,-6],[36,-50],[-61,-5],[32,-24],[-9,-20],[-39,-10],[-39,0],[35,-40],[0,-26],[-55,24],[-14,-15],[37,-15],[37,-36],[10,-48],[-49,-11],[-22,22],[-34,34],[10,-40],[-33,-31],[73,-2],[39,-3],[-75,-52],[-75,-46],[-81,-21],[-31,0],[-29,-23],[-38,-62],[-60,-42],[-19,-2],[-37,-15],[-40,-13],[-24,-37],[0,-41],[-15,-39],[-45,-47],[11,-47],[-12,-48],[-14,-58],[-39,-4],[-41,49],[-56,0],[-27,32],[-18,58],[-49,73],[-14,39],[-3,53],[-39,54],[10,44],[-18,21],[27,69],[42,22],[11,25],[6,46],[-32,-21],[-15,-9],[-25,-8],[-34,19],[-2,40],[11,31],[25,1],[57,-15],[-48,37],[-24,20],[-28,-8],[-23,15],[31,55],[-17,22],[-22,41],[-34,62],[-35,23],[0,25],[-74,34],[-59,5],[-74,-3],[-68,-4],[-32,19],[-49,37],[73,19],[56,3],[-119,15],[-62,24],[3,23],[106,28],[101,29],[11,21],[-75,22],[24,23],[97,41],[40,7],[-12,26],[66,16],[86,9],[85,1],[30,-19],[74,33],[66,-22],[39,-5],[58,-19],[-66,32],[4,25]],[[2497,5869],[-14,10],[-17,1],[-13,12],[-15,24]],[[2438,5916],[1,18],[3,13],[-4,12],[13,48],[36,0],[1,20],[-5,4],[-3,12],[-10,14],[-11,20],[13,0],[0,33],[26,0],[26,0]],[[2529,5996],[10,-11],[2,9],[8,-7]],[[2549,5987],[-13,-23],[-13,-16],[-2,-12],[2,-11],[-5,-15]],[[2518,5910],[-7,-4],[2,-7],[-6,-6],[-9,-15],[-1,-9]],[[3340,5552],[18,-22],[17,-38],[1,-31],[10,-1],[15,-29],[11,-21]],[[3412,5410],[-4,-53],[-17,-15],[1,-14],[-5,-31],[13,-42],[9,-1],[3,-33],[17,-51]],[[3313,5365],[-19,45],[7,16],[0,27],[17,10],[7,11],[-10,22],[3,21],[22,35]],[[2574,5825],[-5,18],[-8,5]],[[2561,5848],[2,24],[-4,6],[-6,4],[-12,-7],[-1,8],[-8,10],[-6,12],[-8,5]],[[2549,5987],[3,-3],[6,11],[8,1],[3,-5],[4,3],[13,-6],[13,2],[9,6],[3,7],[9,-3],[6,-4],[8,1],[5,5],[13,-8],[4,-1],[9,-11],[8,-13],[10,-9],[7,-17]],[[2690,5943],[-9,2],[-4,-8],[-10,-8],[-7,0],[-6,-8],[-6,3],[-4,9],[-3,-2],[-4,-14],[-3,1],[0,-12],[-10,-17],[-5,-7],[-3,-7],[-8,12],[-6,-16],[-6,1],[-6,-2],[0,-29],[-4,0],[-3,-14],[-9,-2]],[[5522,7770],[7,-23],[9,-17],[-11,-22]],[[5515,7577],[-3,-10]],[[5512,7567],[-26,22],[-16,21],[-26,18],[-23,43],[6,5],[-13,25],[-1,19],[-17,10],[-9,-26],[-8,20],[0,21],[1,1]],[[5380,7746],[20,-2],[5,9],[9,-9],[11,-1],[0,16],[10,6],[2,24],[23,16]],[[5460,7805],[8,-7],[21,-26],[23,-11],[10,9]],[[3008,6124],[-19,10],[-13,-5],[-17,5],[-13,-11],[-15,18],[3,19],[25,-8],[21,-5],[10,13],[-12,26],[0,23],[-18,9],[7,16],[17,-3],[24,-9]],[[5471,7900],[14,-15],[10,-6],[24,7],[2,12],[11,2],[14,9],[3,-4],[13,8],[6,13],[9,4],[30,-18],[6,6]],[[5613,7918],[15,-16],[2,-16]],[[5630,7886],[-17,-12],[-13,-40],[-17,-40],[-22,-11]],[[5561,7783],[-17,2],[-22,-15]],[[5460,7805],[-6,20],[-4,0]],[[8352,4453],[-11,-2],[-37,42],[26,11],[14,-18],[10,-17],[-2,-16]],[[8471,4532],[2,-11],[1,-18]],[[8474,4503],[-18,-45],[-24,-13],[-3,8],[2,20],[12,36],[28,23]],[[8274,4579],[10,-16],[17,5],[7,-25],[-32,-12],[-19,-8],[-15,1],[10,34],[15,0],[7,21]],[[8413,4579],[-4,-32],[-42,-17],[-37,7],[0,22],[22,12],[18,-18],[18,5],[25,21]],[[8017,4657],[53,-6],[6,25],[51,-29],[10,-38],[42,-11],[34,-35],[-31,-23],[-31,24],[-25,-1],[-29,4],[-26,11],[-32,22],[-21,6],[-11,-7],[-51,24],[-5,25],[-25,5],[19,56],[34,-3],[22,-23],[12,-5],[4,-21]],[[8741,4690],[-14,-40],[-3,45],[5,21],[6,20],[7,-17],[-1,-29]],[[8534,4853],[-11,-19],[-19,10],[-5,26],[28,3],[7,-20]],[[8623,4875],[10,-45],[-23,24],[-23,5],[-16,-4],[-19,2],[6,33],[35,2],[30,-17]],[[8916,4904],[0,-193],[1,-192]],[[8917,4519],[-25,48],[-28,12],[-7,-17],[-35,-1],[12,48],[17,16],[-7,64],[-14,50],[-53,50],[-23,5],[-42,54],[-8,-28],[-11,-5],[-6,21],[0,26],[-21,29],[29,21],[20,-1],[-2,16],[-41,0],[-11,35],[-25,11],[-11,29],[37,14],[14,20],[45,-25],[4,-22],[8,-95],[29,-35],[23,62],[32,36],[25,0],[23,-21],[21,-21],[30,-11]],[[8478,5141],[-22,-58],[-21,-12],[-27,12],[-46,-3],[-24,-8],[-4,-45],[24,-53],[15,27],[52,20],[-2,-27],[-12,9],[-12,-35],[-25,-23],[27,-76],[-5,-20],[25,-68],[-1,-39],[-14,-17],[-11,20],[13,49],[-27,-23],[-7,16],[3,23],[-20,35],[3,57],[-19,-18],[2,-69],[1,-84],[-17,-9],[-12,18],[8,54],[-4,57],[-12,1],[-9,40],[12,39],[4,47],[14,89],[5,24],[24,44],[22,-18],[35,-8],[32,3],[27,43],[5,-14]],[[8574,5124],[-2,-51],[-14,6],[-4,-36],[11,-32],[-8,-7],[-11,38],[-8,75],[6,47],[9,22],[2,-32],[16,-5],[3,-25]],[[8045,5176],[5,-39],[19,-34],[18,12],[18,-4],[16,30],[13,5],[26,-17],[23,13],[14,82],[11,21],[10,67],[32,0],[24,-10]],[[8274,5302],[-16,-53],[20,-56],[-5,-28],[32,-54],[-33,-7],[-10,-40],[2,-54],[-27,-40],[-1,-59],[-10,-91],[-5,21],[-31,-26],[-11,36],[-20,3],[-14,19],[-33,-21],[-10,29],[-18,-4],[-23,7],[-4,79],[-14,17],[-13,50],[-4,52],[3,55],[16,39]],[[7939,4712],[-31,-1],[-24,49],[-35,48],[-12,36],[-21,48],[-14,44],[-21,83],[-24,49],[-9,51],[-10,46],[-25,37],[-14,51],[-21,33],[-29,65],[-3,30],[18,-2],[43,-12],[25,-57],[21,-40],[16,-25],[26,-63],[28,-1],[23,-41],[16,-49],[22,-27],[-12,-49],[16,-20],[10,-2],[5,-41],[10,-33],[20,-5],[14,-37],[-7,-74],[-1,-91]],[[7252,6841],[-17,-27],[-11,-55],[27,-23],[26,-29],[36,-33],[38,-8],[16,-30],[22,-5],[33,-14],[23,1],[4,23],[-4,38],[2,25]],[[7703,6727],[2,-22],[-10,-11],[2,-36],[-19,10],[-36,-41],[0,-33],[-15,-50],[-1,-29],[-13,-48],[-21,13],[-1,-61],[-7,-20],[3,-25],[-14,-14]],[[7472,6360],[-4,-21],[-19,1],[-34,-13],[2,-44],[-15,-35],[-40,-40],[-31,-69],[-21,-38],[-28,-38],[0,-27],[-13,-15],[-26,-21],[-12,-3],[-9,-45],[6,-77],[1,-49],[-11,-56],[0,-101],[-15,-2],[-12,-46],[8,-19],[-25,-17],[-10,-40],[-11,-17],[-26,55],[-13,83],[-11,60],[-9,28],[-15,56],[-7,74],[-5,37],[-25,81],[-12,115],[-8,75],[0,72],[-5,55],[-41,-35],[-19,7],[-36,71],[13,22],[-8,23],[-33,50]],[[6893,6457],[19,40],[61,-1],[-6,51],[-15,30],[-4,46],[-18,26],[31,62],[32,-4],[29,61],[18,60],[27,60],[-1,42],[24,34],[-23,29],[-9,40],[-10,52],[14,25],[42,-14],[31,9],[26,49]],[[4827,8240],[5,-42],[-21,-53],[-49,-35],[-40,9],[23,62],[-15,60],[38,46],[21,28]],[[6497,7255],[25,12],[19,33],[19,-1],[12,11],[20,-6],[31,-30],[22,-6],[31,-53],[21,-2],[3,-49]],[[6690,6820],[14,-31],[11,-36],[27,-26],[1,-52],[13,-10],[2,-27],[-40,-30],[-10,-69]],[[6708,6539],[-53,18],[-30,13],[-31,8],[-12,73],[-13,10],[-22,-11],[-28,-28],[-34,20],[-28,45],[-27,17],[-18,56],[-21,79],[-15,-10],[-17,20],[-11,-24]],[[6348,6825],[-15,32],[0,31],[-9,0],[5,43],[-15,45],[-34,32],[-19,56],[6,46],[14,21],[-2,34],[-18,18],[-18,70]],[[6243,7253],[-15,48],[5,18],[-8,68],[19,17]],[[6357,7321],[9,-43],[26,-13],[20,-29],[39,-10],[44,15],[2,14]],[[6348,6825],[-16,3]],[[6332,6828],[-19,5],[-20,-56]],[[6293,6777],[-52,4],[-78,119],[-41,41],[-34,16]],[[6088,6957],[-11,72]],[[6077,7029],[61,62],[11,71],[-3,43],[16,15],[14,37]],[[6176,7257],[12,9],[32,-8],[10,-15],[13,10]],[[4597,8984],[-7,-39],[31,-40],[-36,-45],[-80,-41],[-24,-10],[-36,8],[-78,19],[28,26],[-61,29],[49,12],[-1,17],[-58,14],[19,38],[42,9],[43,-40],[42,32],[35,-17],[45,32],[47,-4]],[[5992,6990],[-5,-19]],[[5987,6971],[-10,8],[-6,-39],[7,-7],[-7,-8],[-1,-15],[13,8]],[[5983,6918],[0,-23],[-14,-95]],[[5951,6902],[8,19],[-2,4],[8,27],[5,45],[4,15],[1,0]],[[5975,7012],[9,0],[3,11],[7,0]],[[5994,7023],[1,-24],[-4,-9],[1,0]],[[5431,7316],[-10,-46],[4,-19],[-6,-30],[-21,22],[-14,7],[-39,30],[4,30],[32,-6],[28,7],[22,5]],[[5255,7492],[17,-42],[-4,-78],[-13,4],[-11,-20],[-10,16],[-2,71],[-6,34],[15,-3],[14,18]],[[5383,7805],[-3,-29],[7,-25]],[[5387,7751],[-22,8],[-23,-20],[1,-30],[-3,-17],[9,-30],[26,-29],[14,-49],[31,-48],[22,0],[7,-13],[-8,-11],[25,-22],[20,-18],[24,-30],[3,-11],[-5,-22],[-16,28],[-24,10],[-12,-39],[20,-21],[-3,-31],[-11,-4],[-15,-50],[-12,-5],[0,18],[6,32],[6,12],[-11,35],[-8,29],[-12,8],[-8,25],[-18,11],[-12,24],[-21,4],[-21,26],[-26,39],[-19,34],[-8,58],[-14,7],[-23,20],[-12,-8],[-16,-28],[-12,-4]],[[2845,6150],[19,-5],[14,-15],[5,-16],[-19,-1],[-9,-10],[-15,10],[-16,21],[3,14],[12,4],[6,-2]],[[5992,6990],[31,-24],[54,63]],[[6088,6957],[-5,-8],[-56,-30],[28,-59],[-9,-10],[-5,-20],[-21,-8],[-7,-21],[-12,-19],[-31,10]],[[5970,6792],[-1,8]],[[5983,6918],[4,17],[0,36]],[[8739,7075],[4,-20],[-16,-36],[-11,19],[-15,-14],[-7,-34],[-18,16],[0,28],[15,36],[16,-7],[12,25],[20,-13]],[[8915,7252],[-10,-47],[4,-30],[-14,-42],[-35,-27],[-49,-4],[-40,-67],[-19,22],[-1,44],[-48,-13],[-33,-27],[-32,-2],[28,-43],[-19,-101],[-18,-24],[-13,23],[7,53],[-18,17],[-11,41],[26,18],[15,37],[28,30],[20,41],[55,17],[30,-12],[29,105],[19,-28],[40,59],[16,23],[18,72],[-5,67],[11,37],[30,11],[15,-82],[-1,-48],[-25,-59],[0,-61]],[[8997,7667],[19,-12],[20,25],[6,-67],[-41,-16],[-25,-59],[-43,41],[-15,-65],[-31,-1],[-4,59],[14,46],[29,3],[8,82],[9,46],[32,-62],[22,-20]],[[6970,7554],[-15,-10],[-37,-42],[-12,-42],[-11,0],[-7,28],[-36,2],[-5,48],[-14,0],[2,60],[-33,43],[-48,-5],[-32,-8],[-27,53],[-22,22],[-43,43],[-6,5],[-71,-35],[1,-218]],[[6554,7498],[-14,-3],[-20,46],[-18,17],[-32,-12],[-12,-20]],[[6458,7526],[-2,14],[7,25],[-5,21],[-32,20],[-13,53],[-15,15],[-1,19],[27,-6],[1,44],[23,9],[25,-9],[5,58],[-5,36],[-28,-2],[-24,14],[-32,-26],[-26,-12]],[[6363,7799],[-14,9],[3,31],[-18,39],[-20,-2],[-24,40],[16,45],[-8,12],[22,65],[29,-34],[3,43],[58,64],[43,2],[61,-41],[33,-24],[30,25],[44,1],[35,-30],[8,17],[39,-2],[7,28],[-45,40],[27,29],[-5,16],[26,15],[-20,41],[13,20],[104,21],[13,14],[70,22],[25,24],[50,-12],[9,-61],[29,14],[35,-20],[-2,-32],[27,3],[69,56],[-10,-19],[35,-46],[62,-150],[15,31],[39,-34],[39,16],[16,-11],[13,-34],[20,-12],[11,-25],[36,8],[15,-36]],[[7229,7559],[-17,9],[-14,21],[-42,6],[-46,2],[-10,-6],[-39,24],[-16,-12],[-4,-35],[-46,21],[-18,-9],[-7,-26]],[[6155,4958],[-20,-24],[-7,-24],[-10,-4],[-4,-42],[-9,-24],[-5,-39],[-12,-20]],[[6088,4781],[-40,59],[-1,35],[-101,120],[-5,6]],[[5941,5001],[0,63],[8,24],[14,39],[10,43],[-13,68],[-3,30],[-13,41]],[[5944,5309],[17,35],[19,39]],[[6162,5289],[-24,-67],[0,-215],[17,-49]],[[7046,7387],[-53,-9],[-34,19],[-30,-4],[3,34],[30,-10],[10,18]],[[6972,7435],[21,-6],[36,43],[-33,31],[-20,-15],[-21,22],[24,39],[-9,5]],[[7849,5777],[-7,72],[18,49],[36,11],[26,-8]],[[7922,5901],[23,-23],[12,40],[25,-21]],[[7982,5897],[6,-40],[-3,-71],[-47,-45],[13,-36],[-30,-4],[-24,-24]],[[7897,5677],[-23,9],[-11,30],[-14,61]],[[8564,7339],[24,-70],[7,-38],[0,-68],[-10,-33],[-25,-11],[-22,-25],[-25,-5],[-3,32],[5,45],[-13,61],[21,10],[-19,51]],[[8504,7288],[2,5],[12,-2],[11,27],[20,2],[11,4],[4,15]],[[5557,7574],[5,13]],[[5562,7587],[7,4],[4,20],[5,3],[4,-8],[5,-4],[3,-10],[5,-2],[5,-11],[4,0],[-3,-14],[-3,-7],[1,-5]],[[5599,7553],[-6,-2],[-17,-9],[-1,-12],[-4,0]],[[6332,6828],[6,-26],[-3,-13],[9,-45]],[[6344,6744],[-19,-1],[-7,28],[-25,6]],[[7922,5901],[9,26],[1,50],[-22,52],[-2,58],[-21,48],[-21,4],[-6,-20],[-16,-2],[-8,10],[-30,-35],[0,53],[7,62],[-19,3],[-2,36],[-12,18]],[[7780,6264],[6,21],[24,39]],[[7837,6385],[17,-47],[12,-54],[34,0],[11,-52],[-18,-15],[-8,-21],[34,-36],[23,-70],[17,-52],[21,-41],[7,-41],[-5,-59]],[[5975,7012],[10,49],[14,41],[0,2]],[[5999,7104],[13,-3],[4,-23],[-15,-22],[-7,-33]],[[4785,5315],[-7,0],[-29,28],[-25,45],[-24,32],[-18,38]],[[4682,5458],[6,19],[2,17],[12,33],[13,27]],[[5412,6408],[-20,-22],[-15,33],[-44,25]],[[5263,6848],[13,14],[3,25],[-3,24],[19,23],[8,19],[14,17],[2,45]],[[5319,7015],[32,-20],[12,5],[23,-10],[37,-26],[13,-53],[25,-11],[39,-25],[30,-29],[13,15],[13,27],[-6,45],[9,29],[20,28],[19,8],[37,-12],[10,-27],[10,0],[9,-10],[28,-7],[6,-19]],[[5694,6357],[0,-118],[-32,0],[0,-25]],[[5662,6214],[-111,113],[-111,113],[-28,-32]],[[7271,5502],[-4,-62],[-12,-16],[-24,-14],[-13,47],[-5,85],[13,96],[19,-33],[13,-42],[13,-61]],[[5804,3347],[10,-18],[-9,-29],[-4,-19],[-16,-9],[-5,-19],[-10,-6],[-21,46],[15,37],[15,23],[13,12],[12,-18]],[[5631,8267],[-2,15],[3,16],[-13,10],[-29,10]],[[5590,8318],[-6,50]],[[5584,8368],[32,18],[47,-4],[27,6],[4,-12],[15,-4],[26,-29]],[[5652,8242],[-7,19],[-14,6]],[[5584,8368],[1,44],[14,37],[26,20],[22,-44],[22,1],[6,46]],[[5757,8453],[14,-14],[2,-28],[9,-35]],[[4759,6691],[-4,0],[0,-31],[-17,-2],[-9,-14],[-13,0],[-10,8],[-23,-6],[-9,-46],[-9,-5],[-13,-74],[-38,-64],[-9,-81],[-12,-27],[-3,-21],[-63,-5]],[[4527,6323],[1,27],[11,17],[9,30],[-2,20],[10,42],[15,38],[9,9],[8,35],[0,31],[10,37],[19,21],[18,60],[0,1],[14,23],[26,6],[22,41],[14,16],[23,49],[-7,73],[10,51],[4,31],[18,40],[28,27],[21,25],[18,61],[9,36],[20,0],[17,-25],[26,4],[29,-13],[12,-1]],[[5739,7906],[6,9],[19,6],[20,-19],[12,-2],[12,-16],[-2,-20],[11,-9],[4,-25],[9,-15],[-2,-9],[5,-6],[-7,-4],[-16,1],[-3,9],[-6,-5],[2,-11],[-7,-19],[-5,-20],[-7,-6]],[[5784,7745],[-5,27],[3,25],[-1,26],[-16,35],[-9,25],[-9,17],[-8,6]],[[6376,4321],[7,-25],[7,-39],[4,-71],[7,-28],[-2,-28],[-5,-18],[-10,35],[-5,-18],[5,-43],[-2,-25],[-8,-14],[-1,-50],[-11,-69],[-14,-81],[-17,-112],[-11,-82],[-12,-69],[-23,-14],[-24,-25],[-16,15],[-22,21],[-8,31],[-2,53],[-10,47],[-2,42],[5,43],[13,10],[0,20],[13,45],[2,37],[-6,28],[-5,38],[-2,54],[9,33],[4,38],[14,2],[15,12],[11,10],[12,1],[16,34],[23,36],[8,30],[-4,25],[12,-7],[15,41],[1,36],[9,26],[10,-25]],[[2301,6586],[-10,-52],[-5,-43],[-2,-79],[-3,-29],[5,-32],[9,-29],[5,-45],[19,-44],[6,-34],[11,-29],[29,-16],[12,-25],[24,17],[21,6],[21,11],[18,10],[17,24],[7,34],[2,50],[5,17],[19,16],[29,13],[25,-2],[17,5],[6,-12],[-1,-29],[-15,-35],[-6,-36],[5,-10],[-4,-26],[-7,-46],[-7,15],[-6,-1]],[[2438,5916],[-32,64],[-14,19],[-23,16],[-15,-5],[-22,-22],[-14,-6],[-20,16],[-21,11],[-26,27],[-21,8],[-31,28],[-23,28],[-7,16],[-16,3],[-28,19],[-12,27],[-30,34],[-14,37],[-6,29],[9,5],[-3,17],[7,16],[0,20],[-10,27],[-2,23],[-9,30],[-25,59],[-28,46],[-13,37],[-24,24],[-5,14],[4,37],[-14,13],[-17,29],[-7,41],[-14,5],[-17,31],[-13,29],[-1,19],[-15,44],[-10,45],[1,23],[-20,23],[-10,-2],[-15,16],[-5,-24],[5,-28],[2,-45],[10,-24],[21,-41],[4,-14],[4,-4],[4,-20],[5,1],[6,-38],[8,-15],[6,-21],[17,-30],[10,-55],[8,-26],[8,-28],[1,-31],[13,-2],[12,-27],[10,-26],[-1,-11],[-12,-21],[-5,0],[-7,36],[-18,33],[-20,29],[-14,15],[1,43],[-5,32],[-13,19],[-19,26],[-4,-8],[-7,16],[-17,14],[-16,34],[2,5],[11,-4],[11,22],[1,27],[-22,42],[-16,17],[-10,36],[-11,39],[-12,47],[-12,54]],[[1746,6980],[32,4],[35,7],[-2,-12],[41,-29],[64,-41],[55,0],[22,0],[0,24],[48,0],[10,-20],[15,-19],[16,-26],[9,-31],[7,-32],[15,-18],[23,-18],[17,47],[23,1],[19,-24],[14,-40],[10,-35],[16,-34],[6,-41],[8,-28],[22,-18],[20,-13],[10,2]],[[5599,7553],[9,4],[13,1]],[[4661,5921],[10,11],[4,35],[9,1],[20,-16],[15,11],[11,-4],[4,13],[112,1],[6,42],[-5,7],[-13,255],[-14,255],[43,1]],[[5118,6189],[0,-136],[-15,-39],[-2,-37],[-25,-9],[-38,-5],[-10,-21],[-18,-3]],[[4680,5793],[1,18],[-2,23],[-11,16],[-5,34],[-2,37]],[[7737,5644],[-3,44],[9,45],[-10,35],[3,65],[-12,30],[-9,71],[-5,75],[-12,49],[-18,-30],[-32,-42],[-15,5],[-17,14],[9,73],[-6,56],[-21,68],[3,21],[-16,7],[-20,49]],[[7780,6264],[-16,-14],[-16,-26],[-20,-2],[-12,-64],[-12,-11],[14,-52],[17,-43],[12,-39],[-11,-51],[-9,-11],[6,-30],[19,-47],[3,-33],[0,-27],[11,-54],[-16,-55],[-13,-61]],[[5538,7532],[-6,4],[-8,19],[-12,12]],[[5533,7629],[8,-10],[4,-9],[9,-6],[10,-12],[-2,-5]],[[7437,7970],[29,10],[53,51],[42,28],[24,-18],[29,-1],[19,-28],[28,-2],[40,-15],[27,41],[-11,35],[28,61],[31,-24],[26,-7],[32,-15],[6,-44],[39,-25],[26,11],[36,7],[27,-7],[28,-29],[16,-30],[26,1],[35,-10],[26,15],[36,9],[41,42],[17,-6],[14,-20],[33,5]],[[5959,4377],[21,5],[34,-17],[7,8],[19,1],[10,18],[17,-1],[30,23],[22,34]],[[6119,4448],[5,-26],[-1,-59],[3,-52],[1,-92],[5,-29],[-8,-43],[-11,-41],[-18,-36],[-25,-23],[-31,-28],[-32,-64],[-10,-11],[-20,-42],[-11,-13],[-3,-42],[14,-45],[5,-35],[0,-17],[5,3],[-1,-58],[-4,-28],[6,-10],[-4,-25],[-11,-21],[-23,-20],[-34,-32],[-12,-21],[3,-25],[7,-4],[-3,-31]],[[5911,3478],[-21,0]],[[5890,3478],[-2,26],[-4,27]],[[5884,3531],[-3,21],[5,66],[-7,42],[-13,83]],[[5866,3743],[29,67],[7,43],[5,5],[3,35],[-5,17],[1,44],[6,41],[0,75],[-15,19],[-13,4],[-6,15],[-13,12],[-23,-1],[-2,22]],[[5840,4141],[-2,42],[84,49]],[[5922,4232],[16,-28],[8,5],[11,-15],[1,-23],[-6,-28],[2,-42],[19,-36],[8,41],[12,12],[-2,76],[-12,43],[-10,19],[-10,-1],[-7,77],[7,45]],[[4661,5921],[-18,41],[-17,43],[-18,16],[-13,17],[-16,-1],[-13,-12],[-14,5],[-10,-19]],[[4542,6011],[-2,32],[8,29],[3,55],[-3,59],[-3,29],[2,30],[-7,28],[-14,25]],[[4526,6298],[6,20],[108,-1],[-5,86],[7,30],[26,5],[-1,152],[91,-4],[0,90]],[[5922,4232],[-15,15],[9,55],[9,21],[-6,49],[6,48],[5,16],[-7,50],[-14,26]],[[5909,4512],[28,-11],[5,-16],[10,-28],[7,-80]],[[7836,5425],[7,-5],[16,-36],[12,-40],[2,-39],[-3,-27],[2,-21],[2,-35],[10,-16],[11,-52],[-1,-20],[-19,-4],[-27,44],[-32,47],[-4,30],[-16,39],[-4,49],[-10,32],[4,43],[-7,25]],[[7779,5439],[5,11],[23,-26],[2,-30],[18,7],[9,24]],[[8045,5176],[21,-20],[21,11],[6,50],[12,11],[33,13],[20,47],[14,37]],[[8206,5379],[22,41],[14,47],[11,0],[14,-30],[1,-26],[19,-16],[23,-18],[-2,-23],[-19,-3],[5,-29],[-20,-20]],[[5453,3369],[-20,45],[-11,43],[-6,58],[-7,42],[-9,91],[-1,71],[-3,32],[-11,25],[-15,48],[-14,71],[-6,37],[-23,58],[-2,45]],[[5644,4022],[23,14],[18,-4],[11,-13],[0,-5]],[[5552,3594],[0,-218],[-25,-30],[-15,-4],[-17,11],[-13,4],[-4,25],[-11,17],[-14,-30]],[[9604,3812],[23,-36],[14,-28],[-10,-14],[-16,16],[-19,27],[-18,31],[-19,42],[-4,20],[12,-1],[16,-20],[12,-20],[9,-17]],[[5412,6408],[7,-92],[10,-15],[1,-19],[11,-20],[-6,-25],[-11,-120],[-1,-77],[-35,-56],[-12,-78],[11,-22],[0,-38],[18,-1],[-3,-28]],[[5393,5795],[-5,-1],[-19,64],[-6,3],[-22,-33],[-21,17],[-15,3],[-8,-8],[-17,2],[-16,-25],[-14,-2],[-34,31],[-13,-15],[-14,1],[-10,23],[-28,22],[-30,-7],[-7,-13],[-4,-34],[-8,-24],[-2,-53]],[[5236,5339],[-29,-21],[-11,3],[-10,-13],[-23,1],[-15,37],[-9,43],[-19,39],[-21,-1],[-25,0]],[[2619,5713],[-10,18],[-13,24],[-6,20],[-12,19],[-13,26],[3,9],[4,-9],[2,5]],[[2690,5943],[-2,-5],[-2,-13],[3,-22],[-6,-20],[-3,-24],[-1,-26],[1,-15],[1,-27],[-4,-6],[-3,-25],[2,-15],[-6,-16],[2,-16],[4,-9]],[[5092,8091],[14,16],[24,87],[38,25],[23,-2]],[[5863,9167],[-47,-24],[-22,-5]],[[5573,9140],[-17,-2],[-4,-39],[-53,9],[-7,-33],[-27,1],[-18,-42],[-28,-66],[-43,-83],[10,-20],[-10,-24],[-27,1],[-18,-55],[2,-79],[17,-29],[-9,-70],[-23,-40],[-12,-34]],[[5306,8535],[-19,36],[-55,-69],[-37,-13],[-38,30],[-10,63],[-9,137],[26,38],[73,49],[55,61],[51,82],[66,115],[47,44],[76,74],[61,26],[46,-3],[42,49],[51,-3],[50,12],[87,-43],[-36,-16],[30,-37]],[[5686,9657],[-62,-24],[-49,13],[19,16],[-16,19],[57,11],[11,-22],[40,-13]],[[5506,9766],[92,-44],[-70,-23],[-15,-44],[-25,-11],[-13,-49],[-34,-2],[-59,36],[25,21],[-42,17],[-54,50],[-21,46],[75,21],[16,-20],[39,0],[11,21],[40,2],[35,-21]],[[5706,9808],[55,-21],[-41,-32],[-81,-7],[-82,10],[-5,16],[-40,1],[-30,27],[86,17],[40,-14],[28,17],[70,-14]],[[9805,2640],[6,-24],[20,24],[8,-25],[0,-25],[-10,-27],[-18,-44],[-14,-24],[10,-28],[-22,-1],[-23,-22],[-8,-39],[-16,-60],[-21,-26],[-14,-17],[-26,1],[-18,20],[-30,4],[-5,22],[15,43],[35,59],[18,11],[20,22],[24,31],[16,31],[13,44],[10,15],[5,33],[19,27],[6,-25]],[[9849,2922],[20,-63],[1,41],[13,-16],[4,-45],[22,-19],[19,-5],[16,22],[14,-6],[-7,-53],[-8,-34],[-22,1],[-7,-18],[3,-25],[-4,-11],[-11,-32],[-14,-41],[-21,-23],[-5,15],[-12,9],[16,48],[-9,33],[-30,23],[1,22],[20,20],[5,46],[-1,38],[-12,40],[1,10],[-13,25],[-22,52],[-12,42],[11,4],[15,-33],[21,-15],[8,-52]],[[6475,6041],[-9,41],[-22,98]],[[6444,6180],[83,59],[19,118],[-13,42]],[[6566,6530],[12,-40],[16,-22],[20,-8],[17,-10],[12,-34],[8,-20],[10,-7],[0,-13],[-10,-36],[-5,-16],[-12,-19],[-10,-41],[-13,3],[-5,-14],[-5,-30],[4,-39],[-3,-7],[-13,0],[-17,-22],[-3,-29],[-6,-12],[-18,0],[-10,-15],[0,-24],[-14,-16],[-15,5],[-19,-19],[-12,-4]],[[6557,6597],[8,20],[3,-5],[-2,-25],[-4,-10]],[[6893,6457],[-20,15],[-9,43],[-21,45],[-51,-12],[-45,-1],[-39,-8]],[[2836,5484],[-9,17],[-6,32],[7,16],[-7,4],[-5,20],[-14,16],[-12,-4],[-6,-20],[-11,-15],[-6,-2],[-3,-13],[13,-32],[-7,-7],[-4,-9],[-13,-3],[-5,35],[-4,-10],[-9,4],[-5,24],[-12,3],[-7,7],[-12,0],[-1,-13],[-3,9]],[[2707,5623],[10,-22],[-1,-12],[11,-3],[3,5],[8,-14],[13,4],[12,15],[17,12],[9,17],[16,-3],[-1,-6],[15,-2],[12,-10],[10,-18],[10,-16]],[[3045,3974],[-28,33],[-2,25],[-55,59],[-50,65],[-22,36],[-11,49],[4,17],[-23,77],[-28,109],[-26,118],[-11,27],[-9,43],[-21,39],[-20,24],[9,26],[-14,57],[9,41],[22,37]],[[8510,5555],[2,-40],[2,-33],[-9,-54],[-11,60],[-13,-30],[9,-43],[-8,-28],[-32,35],[-8,42],[8,28],[-17,28],[-9,-24],[-13,2],[-21,-33],[-4,17],[11,50],[17,17],[15,22],[10,-27],[21,17],[5,26],[19,1],[-1,46],[22,-28],[3,-30],[2,-21]],[[8443,5665],[-10,-20],[-9,-37],[-8,-17],[-17,40],[5,16],[7,17],[3,36],[16,4],[-5,-40],[21,57],[-3,-56]],[[8291,5608],[-37,-56],[14,41],[20,37],[16,41],[15,58],[5,-48],[-18,-33],[-15,-40]],[[8385,5760],[16,-18],[18,0],[0,-25],[-13,-25],[-18,-18],[-1,28],[2,30],[-4,28]],[[8485,5776],[8,-66],[-21,16],[0,-20],[7,-37],[-13,-13],[-1,42],[-9,3],[-4,36],[16,-5],[0,22],[-17,45],[27,-1],[7,-22]],[[8375,5830],[-7,-51],[-12,29],[-15,45],[24,-2],[10,-21]],[[8369,6151],[17,-17],[9,15],[2,-15],[-4,-24],[9,-43],[-7,-49],[-16,-19],[-5,-48],[7,-47],[14,-7],[13,7],[34,-32],[-2,-32],[9,-15],[-3,-27],[-22,29],[-10,31],[-7,-22],[-18,36],[-25,-9],[-14,13],[1,25],[9,15],[-8,13],[-4,-21],[-14,34],[-4,26],[-1,56],[11,-19],[3,92],[9,54],[17,0]],[[9329,4655],[-8,-6],[-12,22],[-12,38],[-6,45],[4,6],[3,-18],[8,-13],[14,-38],[13,-20],[-4,-16]],[[9221,4734],[-15,-5],[-4,-17],[-15,-14],[-15,-14],[-14,0],[-23,18],[-16,16],[2,18],[25,-8],[15,4],[5,29],[4,1],[2,-31],[16,4],[8,20],[16,21],[-4,35],[17,1],[6,-9],[-1,-33],[-9,-36]],[[8916,4904],[48,-41],[51,-34],[19,-30],[16,-30],[4,-34],[46,-37],[7,-31],[-25,-7],[6,-39],[25,-39],[18,-62],[15,2],[-1,-27],[22,-10],[-9,-11],[30,-25],[-3,-17],[-18,-4],[-7,16],[-24,6],[-28,9],[-22,38],[-16,32],[-14,52],[-36,26],[-24,-17],[-17,-20],[4,-43],[-22,-20],[-16,9],[-28,3]],[[9253,4792],[-9,-16],[-5,35],[-6,23],[-13,19],[-16,25],[-20,18],[8,14],[15,-17],[9,-13],[12,-14],[11,-25],[11,-19],[3,-30]],[[5392,8233],[19,18],[43,27],[35,20],[28,-10],[2,-14],[27,-1]],[[5546,8273],[34,-7],[51,1]],[[5653,8105],[14,-52],[-3,-17],[-14,-6],[-25,-50],[7,-26],[-6,3]],[[5626,7957],[-26,23],[-20,-8],[-13,6],[-17,-13],[-14,21],[-11,-8],[-2,4]],[[3159,6151],[14,-5],[5,-12],[-7,-15],[-21,1],[-17,-2],[-1,25],[4,9],[23,-1]],[[8628,7562],[4,-10]],[[8632,7552],[-11,3],[-12,-20],[-8,-20],[1,-42],[-14,-13],[-5,-11],[-11,-17],[-18,-10],[-12,-16],[-1,-25],[-3,-7],[11,-9],[15,-26]],[[8504,7288],[-13,11],[-4,-11],[-8,-5],[-1,11],[-7,5],[-8,10],[8,26],[7,7],[-3,11],[7,31],[-2,10],[-16,7],[-13,15]],[[4792,7249],[-11,-15],[-14,8],[-15,-6],[5,46],[-3,36],[-12,6],[-7,22],[2,39],[11,21],[2,24],[6,36],[-1,25],[-5,21],[-1,20]],[[6411,6520],[-2,43],[7,31],[8,6],[8,-18],[1,-35],[-6,-35]],[[6427,6512],[-8,-4],[-8,12]],[[5630,7886],[12,13],[17,-7],[18,0],[13,-14],[10,9],[20,5],[7,14],[12,0]],[[5784,7745],[12,-11],[13,9],[13,-10]],[[5822,7733],[0,-15],[-13,-13],[-9,6],[-7,-71]],[[5629,7671],[-5,10],[6,10],[-7,7],[-8,-13],[-17,17],[-2,25],[-17,14],[-3,18],[-15,24]],[[8989,8056],[28,-105],[-41,19],[-17,-85],[27,-61],[-1,-41],[-21,36],[-18,-46],[-5,50],[3,57],[-3,64],[6,45],[2,79],[-17,58],[3,80],[25,28],[-11,27],[13,8],[7,-39],[10,-57],[-1,-58],[11,-59]],[[5546,8273],[6,26],[38,19]],[[0,9132],[68,-45],[73,-59],[-3,-37],[19,-15],[-6,43],[75,-8],[55,-56],[-28,-26],[-46,-6],[0,-57],[-11,-13],[-26,2],[-22,21],[-36,17],[-7,26],[-28,9],[-31,-7],[-16,20],[6,22],[-33,-14],[13,-28],[-16,-25]],[[0,8896],[0,236]],[[0,9282],[9999,-40],[-30,-3],[-5,19],[-9964,24]],[[0,9282],[4,3],[23,0],[40,-17],[-2,-8],[-29,-14],[-36,-4],[0,40]],[[8988,9383],[-42,-1],[-57,7],[-5,3],[27,23],[34,6],[40,-23],[3,-15]],[[9186,9493],[-32,-23],[-44,5],[-52,23],[7,20],[51,-9],[70,-16]],[[9029,9522],[-22,-44],[-102,1],[-46,-14],[-55,39],[15,40],[37,11],[73,-2],[100,-31]],[[6598,9235],[-17,-5],[-91,8],[-7,26],[-50,16],[-4,32],[28,13],[-1,32],[55,50],[-25,7],[66,52],[-7,27],[62,31],[91,38],[93,11],[48,22],[54,8],[19,-23],[-19,-19],[-98,-29],[-85,-28],[-86,-57],[-42,-57],[-43,-57],[5,-49],[54,-49]],[[0,8896],[9963,-26],[-36,4],[25,-31],[17,-49],[13,-16],[3,-24],[-7,-16],[-52,13],[-78,-44],[-25,-7],[-42,-42],[-40,-36],[-11,-27],[-39,41],[-73,-46],[-12,22],[-27,-26],[-37,8],[-9,-38],[-33,-58],[1,-24],[31,-13],[-4,-86],[-25,-2],[-12,-49],[11,-26],[-48,-30],[-10,-67],[-41,-15],[-9,-60],[-40,-55],[-10,41],[-12,86],[-15,131],[13,82],[23,35],[2,28],[43,13],[50,75],[47,60],[50,48],[23,83],[-34,-5],[-17,-49],[-70,-65],[-23,73],[-72,-20],[-69,-99],[23,-36],[-62,-16],[-43,-6],[2,43],[-43,9],[-35,-29],[-85,10],[-91,-18],[-90,-115],[-106,-139],[43,-8],[14,-37],[27,-13],[18,30],[30,-4],[40,-65],[1,-50],[-21,-59],[-3,-71],[-12,-94],[-42,-86],[-9,-41],[-38,-69],[-38,-68],[-18,-35],[-37,-34],[-17,-1],[-17,29],[-38,-44],[-4,-19]],[[6363,7799],[-12,-35],[-27,-10],[-28,-61],[25,-56],[-2,-40],[30,-70]],[[6109,7624],[-35,49],[-32,23],[-24,34],[20,10],[23,49],[-15,24],[41,24],[-1,13],[-25,-10]],[[6061,7840],[1,26],[14,17],[27,4],[5,20],[-7,33],[12,30],[-1,18],[-41,19],[-16,-1],[-17,28],[-21,-9],[-35,20],[0,12],[-10,26],[-22,3],[-2,18],[7,12],[-18,33],[-29,-5],[-8,3],[-7,-14],[-11,3]],[[5777,8571],[31,33],[-29,28]],[[5863,9167],[29,20],[46,-35],[76,-14],[105,-67],[21,-28],[2,-40],[-31,-31],[-45,-15],[-124,44],[-21,-7],[45,-43],[2,-28],[2,-60],[36,-18],[22,-15],[3,28],[-17,26],[18,22],[67,-37],[24,15],[-19,43],[65,58],[25,-4],[26,-20],[16,40],[-23,35],[14,36],[-21,36],[78,-18],[16,-34],[-35,-7],[0,-33],[22,-20],[43,13],[7,38],[58,28],[97,50],[20,-3],[-27,-35],[35,-7],[19,21],[52,1],[42,25],[31,-36],[32,39],[-29,35],[14,19],[82,-18],[39,-18],[100,-68],[19,31],[-28,31],[-1,13],[-34,6],[10,28],[-15,46],[-1,19],[51,53],[18,54],[21,11],[74,-15],[5,-33],[-26,-48],[17,-19],[9,-41],[-6,-81],[31,-36],[-12,-40],[-55,-84],[32,-8],[11,21],[31,15],[7,29],[24,29],[-16,33],[13,39],[-31,5],[-6,33],[22,59],[-36,48],[50,40],[-7,42],[14,2],[15,-33],[-11,-57],[29,-11],[-12,43],[46,23],[58,3],[51,-34],[-25,49],[-2,63],[48,12],[67,-2],[60,7],[-23,31],[33,39],[31,2],[54,29],[74,8],[9,16],[73,6],[23,-14],[62,32],[51,-1],[8,25],[26,25],[66,25],[48,-19],[-38,-15],[63,-9],[7,-29],[25,14],[82,-1],[62,-29],[23,-22],[-7,-30],[-31,-18],[-73,-33],[-21,-17],[35,-8],[41,-15],[25,11],[14,-38],[12,15],[44,10],[90,-10],[6,-28],[116,-9],[2,46],[59,-11],[44,1],[45,-32],[13,-37],[-17,-25],[35,-47],[44,-24],[27,62],[44,-26],[48,16],[53,-18],[21,16],[45,-8],[-20,55],[37,25],[251,-38],[24,-35],[72,-45],[112,11],[56,-10],[23,-24],[-4,-44],[35,-16],[37,12],[49,1],[52,-11],[53,6],[49,-52],[34,19],[-23,37],[13,27],[88,-17],[58,4],[80,-29],[-9960,-25]],[[7918,9684],[-157,-23],[51,77],[23,7],[21,-4],[70,-33],[-8,-24]],[[6420,9816],[-37,-8],[-25,-4],[-4,-10],[-33,-10],[-30,14],[16,19],[-62,2],[54,10],[43,1],[5,-16],[16,14],[26,10],[42,-13],[-11,-9]],[[7775,9718],[-60,-8],[-78,17],[-46,23],[-21,42],[-38,12],[72,40],[60,14],[54,-30],[64,-57],[-7,-53]],[[5844,4990],[11,-33],[-1,-35],[-8,-7]],[[5821,4978],[7,-6],[16,18]],[[4526,6298],[1,25]],[[6188,6023],[-4,26],[-8,17],[-2,24],[-15,21],[-15,50],[-7,48],[-20,40],[-12,10],[-18,56],[-4,41],[2,35],[-16,66],[-13,23],[-15,12],[-10,34],[2,13],[-8,31],[-8,13],[-11,44],[-17,48],[-14,40],[-14,0],[5,33],[1,20],[3,24]],[[6344,6744],[11,-51],[14,-13],[5,-21],[18,-25],[2,-24],[-3,-20],[4,-20],[8,-16],[4,-20],[4,-14]],[[6427,6512],[5,-22]],[[6444,6180],[-80,-23],[-26,-26],[-20,-62],[-13,-10],[-7,20],[-11,-3],[-27,6],[-5,5],[-32,-1],[-7,-5],[-12,15],[-7,-29],[3,-25],[-12,-19]],[[5943,5617],[-4,1],[0,29],[-3,20],[-14,24],[-4,42],[4,44],[-13,4],[-2,-13],[-17,-3],[7,-17],[2,-36],[-15,-32],[-14,-43],[-14,-6],[-23,34],[-11,-12],[-3,-17],[-14,-11],[-1,-12],[-28,0],[-3,12],[-20,2],[-10,-10],[-8,5],[-14,34],[-5,17],[-20,-9],[-8,-27],[-7,-53],[-10,-11],[-8,-6]],[[5663,5567],[-2,2]],[[5635,5716],[0,14],[-10,17],[-1,35],[-5,23],[-10,-4],[3,22],[7,25],[-3,24],[9,18],[-6,14],[7,36],[13,44],[24,-4],[-1,234]],[[6023,6357],[9,-58],[-6,-10],[4,-61],[11,-71],[10,-14],[15,-22]],[[5943,5624],[0,-7]],[[5943,5617],[0,-46]],[[5944,5309],[-17,-28],[-20,1],[-22,-14],[-18,13],[-11,-16]],[[5682,5544],[-19,23]],[[4535,5861],[-11,46],[-14,21],[12,11],[14,41],[6,31]],[[4536,5789],[-4,45]],[[9502,4438],[8,-20],[-19,0],[-11,37],[17,-15],[5,-2]],[[9467,4474],[-11,-1],[-17,6],[-5,9],[1,23],[19,-9],[9,-12],[4,-16]],[[9490,4490],[-4,-11],[-21,52],[-5,35],[9,0],[10,-47],[11,-29]],[[9440,4565],[1,-12],[-22,25],[-15,21],[-10,20],[4,6],[13,-14],[23,-27],[6,-19]],[[9375,4623],[-5,-3],[-13,14],[-11,24],[1,10],[17,-25],[11,-20]],[[4682,5458],[-8,5],[-20,24],[-14,31],[-5,22],[-3,43]],[[2561,5848],[-3,-14],[-16,1],[-10,6],[-12,12],[-15,3],[-8,13]],[[6198,5735],[9,-11],[5,-25],[13,-24],[14,-1],[26,16],[30,7],[25,18],[13,4],[10,11],[16,2]],[[6359,5732],[0,-1],[0,-25],[0,-59],[0,-31],[-13,-36],[-19,-50]],[[6359,5732],[9,1],[13,9],[14,6],[14,20],[10,0],[1,-16],[-3,-35],[0,-31],[-6,-21],[-7,-64],[-14,-66],[-17,-75],[-24,-87],[-23,-66],[-33,-81],[-28,-48],[-42,-58],[-25,-45],[-31,-72],[-6,-31],[-6,-14]],[[3412,5410],[34,-11],[2,10],[23,4],[30,-15]],[[3489,5306],[10,-35],[-4,-25]],[[5626,7957],[-8,-15],[-5,-24]],[[5380,7746],[7,5]],[[5663,8957],[-47,-17],[-27,-41],[4,-36],[-44,-48],[-54,-50],[-20,-84],[20,-41],[26,-33],[-25,-67],[-29,-14],[-11,-99],[-15,-55],[-34,6],[-16,-47],[-32,-3],[-9,56],[-23,67],[-21,84]],[[5890,3478],[-5,-26],[-17,-6],[-16,32],[0,20],[7,22],[3,17],[8,5],[14,-11]],[[5999,7104],[-2,45],[7,25]],[[6004,7174],[7,13],[7,13],[2,33],[9,-12],[31,17],[14,-12],[23,1],[32,22],[15,-1],[32,9]],[[5051,5420],[-22,-12]],[[7849,5777],[-25,28],[-24,-2],[4,47],[-24,0],[-2,-65],[-15,-87],[-10,-52],[2,-43],[18,-2],[12,-53],[5,-52],[15,-33],[17,-7],[14,-31]],[[7779,5439],[-11,23],[-4,29],[-15,34],[-14,28],[-4,-35],[-5,33],[3,37],[8,56]],[[6883,7252],[16,60],[-6,44],[-20,14],[7,26],[23,-3],[13,33],[9,38],[37,13],[-6,-27],[4,-17],[12,2]],[[6497,7255],[-5,42],[4,62],[-22,20],[8,40],[-19,4],[6,49],[26,-14],[25,19],[-20,35],[-8,34],[-23,-15],[-3,-43],[-8,38]],[[6554,7498],[31,1],[-4,29],[24,21],[23,34],[37,-31],[3,-47],[11,-12],[30,2],[9,-10],[14,-61],[32,-41],[18,-28],[29,-29],[37,-25],[-1,-36]],[[8471,4532],[3,14],[24,13],[19,2],[9,8],[10,-8],[-10,-16],[-29,-25],[-23,-17]],[[3286,5693],[16,8],[6,-2],[-1,-44],[-23,-7],[-5,6],[8,16],[-1,23]],[[5233,7240],[31,24],[19,-7],[-1,-30],[24,22],[2,-12],[-14,-29],[0,-27],[9,-15],[-3,-51],[-19,-29],[6,-33],[14,-1],[7,-28],[11,-9]],[[6004,7174],[-11,27],[11,22],[-17,-5],[-23,13],[-19,-34],[-43,-6],[-22,31],[-30,2],[-6,-24],[-20,-7],[-26,31],[-31,-1],[-16,59],[-21,33],[14,46],[-18,28],[31,56],[43,3],[12,45],[53,-8],[33,38],[32,17],[46,1],[49,-42],[40,-22],[32,9],[24,-6],[33,31]],[[5777,7539],[3,-23],[25,-19],[-5,-14],[-33,-3],[-12,-19],[-23,-31],[-9,27],[0,12]],[[8382,6499],[-17,-95],[-12,-49],[-14,50],[-4,44],[17,58],[22,45],[13,-18],[-5,-35]],[[6088,4781],[-12,-73],[1,-33],[18,-22],[1,-15],[-8,-36],[2,-18],[-2,-28],[10,-37],[11,-58],[10,-13]],[[5909,4512],[-15,18],[-18,10],[-11,10],[-12,15]],[[5844,4990],[10,8],[31,-1],[56,4]],[[6061,7840],[-22,-5],[-18,-19],[-26,-3],[-24,-22],[1,-37],[14,-14],[28,4],[-5,-21],[-31,-11],[-37,-34],[-16,12],[6,28],[-30,17],[5,12],[26,19],[-8,14],[-43,15],[-2,22],[-25,-8],[-11,-32],[-21,-44]],[[3517,3063],[-12,-38],[-31,-32],[-21,11],[-15,-6],[-26,25],[-18,-1],[-17,32]],[[679,6185],[-4,-10],[-7,8],[1,17],[-4,21],[1,7],[5,10],[-2,11],[1,6],[3,-1],[10,-10],[5,-5],[5,-8],[7,-21],[-1,-3],[-11,-13],[-9,-9]],[[664,6277],[-9,-4],[-5,12],[-3,5],[0,4],[3,5],[9,-6],[8,-9],[-3,-7]],[[646,6309],[-1,-7],[-15,2],[2,7],[14,-2]],[[621,6317],[-2,-3],[-2,1],[-9,2],[-4,13],[-1,2],[7,8],[3,-3],[8,-20]],[[574,6356],[-4,-6],[-9,11],[1,4],[5,6],[6,-1],[1,-14]],[[3135,7724],[5,-19],[-30,-29],[-29,-20],[-29,-18],[-15,-35],[-4,-13],[-1,-31],[10,-32],[11,-1],[-3,21],[8,-13],[-2,-17],[-19,-9],[-13,1],[-20,-10],[-12,-3],[-17,-3],[-23,-17],[41,11],[8,-11],[-39,-18],[-17,0],[0,7],[-8,-16],[8,-3],[-6,-43],[-20,-45],[-2,15],[-6,3],[-9,15],[5,-32],[7,-10],[1,-23],[-9,-23],[-16,-47],[-2,3],[8,40],[-14,22],[-3,49],[-5,-25],[5,-38],[-18,10],[19,-19],[1,-57],[8,-4],[3,-20],[4,-59],[-17,-44],[-29,-18],[-18,-34],[-14,-4],[-14,-22],[-4,-20],[-31,-38],[-16,-28],[-13,-35],[-4,-42],[5,-41],[9,-51],[13,-41],[0,-26],[13,-69],[-1,-39],[-1,-23],[-7,-36],[-8,-8],[-14,7],[-4,26],[-11,14],[-15,51],[-13,45],[-4,23],[6,39],[-8,33],[-22,49],[-10,9],[-28,-27],[-5,3],[-14,28],[-17,14],[-32,-7],[-24,7],[-21,-5],[-12,-9],[5,-15],[0,-24],[5,-12],[-5,-8],[-10,9],[-11,-11],[-20,2],[-20,31],[-25,-8],[-20,14],[-17,-4],[-24,-14],[-25,-44],[-27,-25],[-16,-28],[-6,-27],[0,-41],[1,-28],[5,-20]],[[1746,6980],[-4,30],[-18,34],[-13,7],[-3,17],[-16,3],[-10,16],[-26,6],[-7,9],[-3,32],[-27,60],[-23,82],[1,14],[-13,19],[-21,50],[-4,48],[-15,32],[6,49],[-1,51],[-8,45],[10,56],[4,53],[3,54],[-5,79],[-9,51],[-8,27],[4,12],[40,-20],[15,-56],[7,15],[-5,49],[-9,48]],[[750,8432],[-28,-23],[-14,15],[-4,28],[25,21],[15,9],[18,-4],[12,-18],[-24,-28]],[[401,8597],[-18,-9],[-18,11],[-17,16],[28,10],[22,-6],[3,-22]],[[230,8826],[17,-12],[17,6],[23,-15],[27,-8],[-2,-7],[-21,-12],[-21,13],[-11,11],[-24,-4],[-7,5],[2,23]],[[1374,8295],[-15,22],[-25,19],[-8,52],[-36,47],[-15,56],[-26,4],[-44,2],[-33,17],[-57,61],[-27,11],[-49,21],[-38,-5],[-55,27],[-33,25],[-30,-12],[5,-41],[-15,-4],[-32,-12],[-25,-20],[-30,-13],[-4,35],[12,58],[30,18],[-8,15],[-35,-33],[-19,-39],[-40,-42],[20,-29],[-26,-42],[-30,-25],[-28,-18],[-7,-26],[-43,-31],[-9,-28],[-32,-25],[-20,5],[-25,-17],[-29,-20],[-23,-20],[-47,-16],[-5,9],[31,28],[27,18],[29,33],[35,6],[14,25],[38,35],[6,12],[21,21],[5,44],[14,35],[-32,-18],[-9,11],[-15,-22],[-18,30],[-8,-21],[-10,29],[-28,-23],[-17,0],[-3,35],[5,21],[-17,22],[-37,-12],[-23,28],[-19,14],[0,34],[-22,25],[11,34],[23,33],[10,30],[22,4],[19,-9],[23,28],[20,-5],[21,19],[-5,27],[-16,10],[21,23],[-17,-1],[-30,-13],[-8,-13],[-22,13],[-39,-6],[-41,14],[-12,24],[-35,34],[39,25],[62,29],[23,0],[-4,-30],[59,2],[-23,37],[-34,23],[-20,29],[-26,25],[-38,19],[15,31],[49,2],[35,27],[7,29],[28,28],[28,6],[52,27],[26,-4],[42,31],[42,-12],[21,-27],[12,11],[47,-3],[-2,-14],[43,-10],[28,6],[59,-18],[53,-6],[21,-8],[37,10],[42,-18],[31,-8]],[[3018,5753],[-1,-14],[-16,-7],[9,-26],[0,-31],[-12,-35],[10,-47],[12,4],[6,43],[-8,21],[-2,45],[35,24],[-4,27],[10,19],[10,-41],[19,-1],[18,-33],[1,-20],[25,0],[30,6],[16,-27],[21,-7],[16,18],[0,15],[34,4],[34,1],[-24,-18],[10,-28],[22,-4],[21,-29],[4,-48],[15,2],[11,-14]],[[8001,6331],[-37,-51],[-24,-56],[-6,-41],[22,-62],[25,-77],[26,-37],[17,-47],[12,-109],[-3,-104],[-24,-39],[-31,-38],[-23,-49],[-35,-55],[-10,37],[8,40],[-21,34]],[[9661,4085],[-9,-8],[-9,26],[1,16],[17,-34]],[[9641,4175],[4,-47],[-7,7],[-6,-3],[-4,16],[0,45],[13,-18]],[[6475,6041],[-21,-16],[-5,-26],[-1,-20],[-27,-25],[-45,-28],[-24,-41],[-13,-3],[-8,3],[-16,-25],[-18,-11],[-23,-3],[-7,-3],[-6,-16],[-8,-4],[-4,-15],[-14,1],[-9,-8],[-19,3],[-7,35],[1,32],[-5,17],[-5,44],[-8,24],[5,3],[-2,27],[3,12],[-1,25]],[[5817,3752],[11,0],[14,-10],[9,7],[15,-6]],[[5911,3478],[-7,-43],[-3,-49],[-7,-27],[-19,-30],[-5,-8],[-12,-30],[-8,-31],[-16,-42],[-31,-61],[-20,-36],[-21,-26],[-29,-23],[-14,-3],[-3,-17],[-17,9],[-14,-11],[-30,11],[-17,-7],[-12,3],[-28,-23],[-24,-10],[-17,-22],[-13,-1],[-11,21],[-10,1],[-12,26],[-1,-8],[-4,16],[0,34],[-9,40],[9,11],[0,45],[-19,55],[-14,50],[0,1],[-20,76]],[[5840,4141],[-21,-8],[-15,-23],[-4,-21],[-10,-4],[-24,-49],[-15,-38],[-10,-2],[-9,7],[-31,7]]],transform:{scale:[.036003600360036005,.016927109510951093],translate:[-180,-85.609038]}},l.prototype.usaTopo="__USA__",l.prototype.latLngToXY=function(a,b){return this.projection([b,a])
+},l.prototype.addLayer=function(a,b,c){var d;return d=c?this.svg.insert("g",":first-child"):this.svg.append("g"),d.attr("id",b||"").attr("class",a||"")},l.prototype.updateChoropleth=function(a){var b=this.svg;for(var c in a)if(a.hasOwnProperty(c)){var d,e=a[c];if(!c)continue;d="string"==typeof e?e:"string"==typeof e.color?e.color:this.options.fills[e.fillKey],e===Object(e)&&(this.options.data[c]=k(e,this.options.data[c]||{}),this.svg.select("."+c).attr("data-info",JSON.stringify(this.options.data[c]))),b.selectAll("."+c).transition().style("fill",d)}},l.prototype.updatePopup=function(a,b,c){var d=this;a.on("mousemove",null),a.on("mousemove",function(){var e=m.mouse(d.options.element);m.select(d.svg[0][0].parentNode).select(".datamaps-hoverover").style("top",e[1]+30+"px").html(function(){var d=JSON.parse(a.attr("data-info"));return c.popupTemplate(b,d)}).style("left",e[0]+"px")}),m.select(d.svg[0][0].parentNode).select(".datamaps-hoverover").style("display","block")},l.prototype.addPlugin=function(a,b){var c=this;"undefined"==typeof l.prototype[a]&&(l.prototype[a]=function(d,e,f,g){var h;"undefined"==typeof g&&(g=!1),"function"==typeof e&&(f=e,e=void 0),e=k(e||{},c.options[a+"Config"]),!g&&this.options[a+"Layer"]?(h=this.options[a+"Layer"],e=e||this.options[a+"Options"]):(h=this.addLayer(a),this.options[a+"Layer"]=h,this.options[a+"Options"]=e),b.apply(this,[h,d,e]),f&&f(h)})},"function"==typeof define&&define.amd?define("datamaps",function(a){return m=a("d3"),n=a("topojson"),l}):window.Datamap=window.Datamaps=l,window.jQuery&&(window.jQuery.fn.datamaps=function(a,b){a=a||{},a.element=this[0];var c=new l(a);return"function"==typeof b&&b(c,a),this})}();
diff --git a/modules/http/static/datamaps.world.min.spdx b/modules/http/static/datamaps.world.min.spdx
new file mode 100644
index 0000000..b699d72
--- /dev/null
+++ b/modules/http/static/datamaps.world.min.spdx
@@ -0,0 +1,11 @@
+SPDXVersion: SPDX-2.1
+DataLicense: CC0-1.0
+SPDXID: SPDXRef-DOCUMENT
+DocumentName: datamaps
+DocumentNamespace: http://spdx.org/spdxdocs/spdx-v2.1-b0f0e722-a8b4-4961-825d-7392f165a0be
+
+PackageName: datamaps
+PackageVersion: 0.3.7
+PackageDownloadLocation: git+https://github.com/markmarkoh/datamaps.git@37beb5995b8489906e070ec6002c7f7d84b17c7a/datamaps.world.min.js
+PackageOriginator: Person: Mark DiMarco (mark.dimarco@gmail.com)
+PackageLicenseDeclared: MIT
diff --git a/modules/http/static/dygraph.min.js b/modules/http/static/dygraph.min.js
new file mode 100644
index 0000000..613c3b8
--- /dev/null
+++ b/modules/http/static/dygraph.min.js
@@ -0,0 +1,7 @@
+/*! @license Copyright 2017 Dan Vanderkam (danvdk@gmail.com)
+ * SPDX-License-Identifier: MIT */
+!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.Dygraph=t()}}(function(){return function t(e,a,i){function n(o,s){if(!a[o]){if(!e[o]){var l="function"==typeof require&&require;if(!s&&l)return l(o,!0);if(r)return r(o,!0);var h=new Error("Cannot find module '"+o+"'");throw h.code="MODULE_NOT_FOUND",h}var u=a[o]={exports:{}};e[o][0].call(u.exports,function(t){var a=e[o][1][t];return n(a||t)},u,u.exports,t,e,a,i)}return a[o].exports}for(var r="function"==typeof require&&require,o=0;o<i.length;o++)n(i[o]);return n}({1:[function(t,e,a){function i(){throw new Error("setTimeout has not been defined")}function n(){throw new Error("clearTimeout has not been defined")}function r(t){if(d===setTimeout)return setTimeout(t,0);if((d===i||!d)&&setTimeout)return d=setTimeout,setTimeout(t,0);try{return d(t,0)}catch(e){try{return d.call(null,t,0)}catch(e){return d.call(this,t,0)}}}function o(t){if(c===clearTimeout)return clearTimeout(t);if((c===n||!c)&&clearTimeout)return c=clearTimeout,clearTimeout(t);try{return c(t)}catch(e){try{return c.call(null,t)}catch(e){return c.call(this,t)}}}function s(){_&&g&&(_=!1,g.length?f=g.concat(f):v=-1,f.length&&l())}function l(){if(!_){var t=r(s);_=!0;for(var e=f.length;e;){for(g=f,f=[];++v<e;)g&&g[v].run();v=-1,e=f.length}g=null,_=!1,o(t)}}function h(t,e){this.fun=t,this.array=e}function u(){}var d,c,p=e.exports={};!function(){try{d="function"==typeof setTimeout?setTimeout:i}catch(t){d=i}try{c="function"==typeof clearTimeout?clearTimeout:n}catch(t){c=n}}();var g,f=[],_=!1,v=-1;p.nextTick=function(t){var e=new Array(arguments.length-1);if(arguments.length>1)for(var a=1;a<arguments.length;a++)e[a-1]=arguments[a];f.push(new h(t,e)),1!==f.length||_||r(l)},h.prototype.run=function(){this.fun.apply(null,this.array)},p.title="browser",p.browser=!0,p.env={},p.argv=[],p.version="",p.versions={},p.on=u,p.addListener=u,p.once=u,p.off=u,p.removeListener=u,p.removeAllListeners=u,p.emit=u,p.prependListener=u,p.prependOnceListener=u,p.listeners=function(t){return[]},p.binding=function(t){throw new Error("process.binding is not supported")},p.cwd=function(){return"/"},p.chdir=function(t){throw new Error("process.chdir is not supported")},p.umask=function(){return 0}},{}],2:[function(t,e,a){"use strict";Object.defineProperty(a,"__esModule",{value:!0});var i=t("./bars"),n=function(t){return t&&t.__esModule?t:{default:t}}(i),r=function(){};r.prototype=new n.default,r.prototype.extractSeries=function(t,e,a){for(var i,n,r,o=[],s=a.get("logscale"),l=0;l<t.length;l++)i=t[l][0],r=t[l][e],s&&null!==r&&(r[0]<=0||r[1]<=0||r[2]<=0)&&(r=null),null!==r?(n=r[1],null===n||isNaN(n)?o.push([i,n,[n,n]]):o.push([i,n,[r[0],r[2]]])):o.push([i,null,[null,null]]);return o},r.prototype.rollingAverage=function(t,e,a){e=Math.min(e,t.length);var i,n,r,o,s,l,h,u=[];for(n=0,o=0,r=0,s=0,l=0;l<t.length;l++){if(i=t[l][1],h=t[l][2],u[l]=t[l],null===i||isNaN(i)||(n+=h[0],o+=i,r+=h[1],s+=1),l-e>=0){var d=t[l-e];null===d[1]||isNaN(d[1])||(n-=d[2][0],o-=d[1],r-=d[2][1],s-=1)}u[l]=s?[t[l][0],1*o/s,[1*n/s,1*r/s]]:[t[l][0],null,[null,null]]}return u},a.default=r,e.exports=a.default},{"./bars":5}],3:[function(t,e,a){"use strict";Object.defineProperty(a,"__esModule",{value:!0});var i=t("./bars"),n=function(t){return t&&t.__esModule?t:{default:t}}(i),r=function(){};r.prototype=new n.default,r.prototype.extractSeries=function(t,e,a){for(var i,n,r,o,s=[],l=a.get("sigma"),h=a.get("logscale"),u=0;u<t.length;u++)i=t[u][0],o=t[u][e],h&&null!==o&&(o[0]<=0||o[0]-l*o[1]<=0)&&(o=null),null!==o?(n=o[0],null===n||isNaN(n)?s.push([i,n,[n,n,n]]):(r=l*o[1],s.push([i,n,[n-r,n+r,o[1]]]))):s.push([i,null,[null,null,null]]);return s},r.prototype.rollingAverage=function(t,e,a){e=Math.min(e,t.length);var i,n,r,o,s,l,h,u,d,c=[],p=a.get("sigma");for(i=0;i<t.length;i++){for(s=0,u=0,l=0,n=Math.max(0,i-e+1);n<i+1;n++)null===(r=t[n][1])||isNaN(r)||(l++,s+=r,u+=Math.pow(t[n][2][2],2));l?(h=Math.sqrt(u)/l,d=s/l,c[i]=[t[i][0],d,[d-p*h,d+p*h]]):(o=1==e?t[i][1]:null,c[i]=[t[i][0],o,[o,o]])}return c},a.default=r,e.exports=a.default},{"./bars":5}],4:[function(t,e,a){"use strict";Object.defineProperty(a,"__esModule",{value:!0});var i=t("./bars"),n=function(t){return t&&t.__esModule?t:{default:t}}(i),r=function(){};r.prototype=new n.default,r.prototype.extractSeries=function(t,e,a){for(var i,n,r,o,s,l,h,u,d=[],c=a.get("sigma"),p=a.get("logscale"),g=0;g<t.length;g++)i=t[g][0],r=t[g][e],p&&null!==r&&(r[0]<=0||r[1]<=0)&&(r=null),null!==r?(o=r[0],s=r[1],null===o||isNaN(o)?d.push([i,o,[o,o,o,s]]):(l=s?o/s:0,h=s?c*Math.sqrt(l*(1-l)/s):1,u=100*h,n=100*l,d.push([i,n,[n-u,n+u,o,s]]))):d.push([i,null,[null,null,null,null]]);return d},r.prototype.rollingAverage=function(t,e,a){e=Math.min(e,t.length);var i,n,r,o,s=[],l=a.get("sigma"),h=a.get("wilsonInterval"),u=0,d=0;for(r=0;r<t.length;r++){u+=t[r][2][2],d+=t[r][2][3],r-e>=0&&(u-=t[r-e][2][2],d-=t[r-e][2][3]);var c=t[r][0],p=d?u/d:0;if(h)if(d){var g=p<0?0:p,f=d,_=l*Math.sqrt(g*(1-g)/f+l*l/(4*f*f)),v=1+l*l/d;i=(g+l*l/(2*d)-_)/v,n=(g+l*l/(2*d)+_)/v,s[r]=[c,100*g,[100*i,100*n]]}else s[r]=[c,0,[0,0]];else o=d?l*Math.sqrt(p*(1-p)/d):1,s[r]=[c,100*p,[100*(p-o),100*(p+o)]]}return s},a.default=r,e.exports=a.default},{"./bars":5}],5:[function(t,e,a){"use strict";function i(t){return t&&t.__esModule?t:{default:t}}Object.defineProperty(a,"__esModule",{value:!0});var n=t("./datahandler"),r=i(n),o=t("../dygraph-layout"),s=i(o),l=function(){r.default.call(this)};l.prototype=new r.default,l.prototype.extractSeries=function(t,e,a){},l.prototype.rollingAverage=function(t,e,a){},l.prototype.onPointsCreated_=function(t,e){for(var a=0;a<t.length;++a){var i=t[a],n=e[a];n.y_top=NaN,n.y_bottom=NaN,n.yval_minus=r.default.parseFloat(i[2][0]),n.yval_plus=r.default.parseFloat(i[2][1])}},l.prototype.getExtremeYValues=function(t,e,a){for(var i,n=null,r=null,o=t.length-1,s=0;s<=o;s++)if(null!==(i=t[s][1])&&!isNaN(i)){var l=t[s][2][0],h=t[s][2][1];l>i&&(l=i),h<i&&(h=i),(null===r||h>r)&&(r=h),(null===n||l<n)&&(n=l)}return[n,r]},l.prototype.onLineEvaluated=function(t,e,a){for(var i,n=0;n<t.length;n++)i=t[n],i.y_top=s.default.calcYNormal_(e,i.yval_minus,a),i.y_bottom=s.default.calcYNormal_(e,i.yval_plus,a)},a.default=l,e.exports=a.default},{"../dygraph-layout":13,"./datahandler":6}],6:[function(t,e,a){"use strict";Object.defineProperty(a,"__esModule",{value:!0});var i=function(){},n=i;n.X=0,n.Y=1,n.EXTRAS=2,n.prototype.extractSeries=function(t,e,a){},n.prototype.seriesToPoints=function(t,e,a){for(var i=[],r=0;r<t.length;++r){var o=t[r],s=o[1],l=null===s?null:n.parseFloat(s),h={x:NaN,y:NaN,xval:n.parseFloat(o[0]),yval:l,name:e,idx:r+a};i.push(h)}return this.onPointsCreated_(t,i),i},n.prototype.onPointsCreated_=function(t,e){},n.prototype.rollingAverage=function(t,e,a){},n.prototype.getExtremeYValues=function(t,e,a){},n.prototype.onLineEvaluated=function(t,e,a){},n.parseFloat=function(t){return null===t?NaN:t},a.default=i,e.exports=a.default},{}],7:[function(t,e,a){"use strict";function i(t){return t&&t.__esModule?t:{default:t}}Object.defineProperty(a,"__esModule",{value:!0});var n=t("./datahandler"),r=(i(n),t("./default")),o=i(r),s=function(){};s.prototype=new o.default,s.prototype.extractSeries=function(t,e,a){for(var i,n,r,o,s,l,h=[],u=a.get("logscale"),d=0;d<t.length;d++)i=t[d][0],r=t[d][e],u&&null!==r&&(r[0]<=0||r[1]<=0)&&(r=null),null!==r?(o=r[0],s=r[1],null===o||isNaN(o)?h.push([i,o,[o,s]]):(l=s?o/s:0,n=100*l,h.push([i,n,[o,s]]))):h.push([i,null,[null,null]]);return h},s.prototype.rollingAverage=function(t,e,a){e=Math.min(e,t.length);var i,n=[],r=0,o=0;for(i=0;i<t.length;i++){r+=t[i][2][0],o+=t[i][2][1],i-e>=0&&(r-=t[i-e][2][0],o-=t[i-e][2][1]);var s=t[i][0],l=o?r/o:0;n[i]=[s,100*l]}return n},a.default=s,e.exports=a.default},{"./datahandler":6,"./default":8}],8:[function(t,e,a){"use strict";Object.defineProperty(a,"__esModule",{value:!0});var i=t("./datahandler"),n=function(t){return t&&t.__esModule?t:{default:t}}(i),r=function(){};r.prototype=new n.default,r.prototype.extractSeries=function(t,e,a){for(var i=[],n=a.get("logscale"),r=0;r<t.length;r++){var o=t[r][0],s=t[r][e];n&&s<=0&&(s=null),i.push([o,s])}return i},r.prototype.rollingAverage=function(t,e,a){e=Math.min(e,t.length);var i,n,r,o,s,l=[];if(1==e)return t;for(i=0;i<t.length;i++){for(o=0,s=0,n=Math.max(0,i-e+1);n<i+1;n++)null===(r=t[n][1])||isNaN(r)||(s++,o+=t[n][1]);l[i]=s?[t[i][0],o/s]:[t[i][0],null]}return l},r.prototype.getExtremeYValues=function(t,e,a){for(var i,n=null,r=null,o=t.length-1,s=0;s<=o;s++)null===(i=t[s][1])||isNaN(i)||((null===r||i>r)&&(r=i),(null===n||i<n)&&(n=i));return[n,r]},a.default=r,e.exports=a.default},{"./datahandler":6}],9:[function(t,e,a){"use strict";Object.defineProperty(a,"__esModule",{value:!0});var i=t("./dygraph-utils"),n=function(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var a in t)Object.prototype.hasOwnProperty.call(t,a)&&(e[a]=t[a]);return e.default=t,e}(i),r=t("./dygraph"),o=function(t){return t&&t.__esModule?t:{default:t}}(r),s=function(t,e,a,i){if(this.dygraph_=t,this.layout=i,this.element=e,this.elementContext=a,this.height=t.height_,this.width=t.width_,!n.isCanvasSupported(this.element))throw"Canvas is not supported.";this.area=i.getPlotArea();var r=this.dygraph_.canvas_ctx_;r.beginPath(),r.rect(this.area.x,this.area.y,this.area.w,this.area.h),r.clip(),r=this.dygraph_.hidden_ctx_,r.beginPath(),r.rect(this.area.x,this.area.y,this.area.w,this.area.h),r.clip()};s.prototype.clear=function(){this.elementContext.clearRect(0,0,this.width,this.height)},s.prototype.render=function(){this._updatePoints(),this._renderLineChart()},s._getIteratorPredicate=function(t){return t?s._predicateThatSkipsEmptyPoints:null},s._predicateThatSkipsEmptyPoints=function(t,e){return null!==t[e].yval},s._drawStyledLine=function(t,e,a,i,r,o,l){var h=t.dygraph,u=h.getBooleanOption("stepPlot",t.setName);n.isArrayLike(i)||(i=null);var d=h.getBooleanOption("drawGapEdgePoints",t.setName),c=t.points,p=t.setName,g=n.createIterator(c,0,c.length,s._getIteratorPredicate(h.getBooleanOption("connectSeparatedPoints",p))),f=i&&i.length>=2,_=t.drawingContext;_.save(),f&&_.setLineDash&&_.setLineDash(i);var v=s._drawSeries(t,g,a,l,r,d,u,e);s._drawPointsOnLine(t,v,o,e,l),f&&_.setLineDash&&_.setLineDash([]),_.restore()},s._drawSeries=function(t,e,a,i,n,r,o,s){var l,h,u=null,d=null,c=null,p=[],g=!0,f=t.drawingContext;f.beginPath(),f.strokeStyle=s,f.lineWidth=a;for(var _=e.array_,v=e.end_,y=e.predicate_,x=e.start_;x<v;x++){if(h=_[x],y){for(;x<v&&!y(_,x);)x++;if(x==v)break;h=_[x]}if(null===h.canvasy||h.canvasy!=h.canvasy)o&&null!==u&&(f.moveTo(u,d),f.lineTo(h.canvasx,d)),u=d=null;else{if(l=!1,r||null===u){e.nextIdx_=x,e.next(),c=e.hasNext?e.peek.canvasy:null;var m=null===c||c!=c;l=null===u&&m,r&&(!g&&null===u||e.hasNext&&m)&&(l=!0)}null!==u?a&&(o&&(f.moveTo(u,d),f.lineTo(h.canvasx,d)),f.lineTo(h.canvasx,h.canvasy)):f.moveTo(h.canvasx,h.canvasy),(n||l)&&p.push([h.canvasx,h.canvasy,h.idx]),u=h.canvasx,d=h.canvasy}g=!1}return f.stroke(),p},s._drawPointsOnLine=function(t,e,a,i,n){for(var r=t.drawingContext,o=0;o<e.length;o++){var s=e[o];r.save(),a.call(t.dygraph,t.dygraph,t.setName,r,s[0],s[1],i,n,s[2]),r.restore()}},s.prototype._updatePoints=function(){for(var t=this.layout.points,e=t.length;e--;)for(var a=t[e],i=a.length;i--;){var n=a[i];n.canvasx=this.area.w*n.x+this.area.x,n.canvasy=this.area.h*n.y+this.area.y}},s.prototype._renderLineChart=function(t,e){var a,i,r=e||this.elementContext,o=this.layout.points,s=this.layout.setNames;this.colors=this.dygraph_.colorsMap_;var l=this.dygraph_.getOption("plotter"),h=l;n.isArrayLike(h)||(h=[h]);var u={};for(a=0;a<s.length;a++){i=s[a];var d=this.dygraph_.getOption("plotter",i);d!=l&&(u[i]=d)}for(a=0;a<h.length;a++)for(var c=h[a],p=a==h.length-1,g=0;g<o.length;g++)if(i=s[g],!t||i==t){var f=o[g],_=c;if(i in u){if(!p)continue;_=u[i]}var v=this.colors[i],y=this.dygraph_.getOption("strokeWidth",i);r.save(),r.strokeStyle=v,r.lineWidth=y,_({points:f,setName:i,drawingContext:r,color:v,strokeWidth:y,dygraph:this.dygraph_,axis:this.dygraph_.axisPropertiesForSeries(i),plotArea:this.area,seriesIndex:g,seriesCount:o.length,singleSeriesName:t,allSeriesPoints:o}),r.restore()}},s._Plotters={linePlotter:function(t){s._linePlotter(t)},fillPlotter:function(t){s._fillPlotter(t)},errorPlotter:function(t){s._errorPlotter(t)}},s._linePlotter=function(t){var e=t.dygraph,a=t.setName,i=t.strokeWidth,r=e.getNumericOption("strokeBorderWidth",a),o=e.getOption("drawPointCallback",a)||n.Circles.DEFAULT,l=e.getOption("strokePattern",a),h=e.getBooleanOption("drawPoints",a),u=e.getNumericOption("pointSize",a);r&&i&&s._drawStyledLine(t,e.getOption("strokeBorderColor",a),i+2*r,l,h,o,u),s._drawStyledLine(t,t.color,i,l,h,o,u)},s._errorPlotter=function(t){var e=t.dygraph,a=t.setName;if(e.getBooleanOption("errorBars")||e.getBooleanOption("customBars")){e.getBooleanOption("fillGraph",a)&&console.warn("Can't use fillGraph option with error bars");var i,r=t.drawingContext,o=t.color,l=e.getNumericOption("fillAlpha",a),h=e.getBooleanOption("stepPlot",a),u=t.points,d=n.createIterator(u,0,u.length,s._getIteratorPredicate(e.getBooleanOption("connectSeparatedPoints",a))),c=NaN,p=NaN,g=[-1,-1],f=n.toRGB_(o),_="rgba("+f.r+","+f.g+","+f.b+","+l+")";r.fillStyle=_,r.beginPath();for(var v=function(t){return null===t||void 0===t||isNaN(t)};d.hasNext;){var y=d.next();!h&&v(y.y)||h&&!isNaN(p)&&v(p)?c=NaN:(i=[y.y_bottom,y.y_top],h&&(p=y.y),isNaN(i[0])&&(i[0]=y.y),isNaN(i[1])&&(i[1]=y.y),i[0]=t.plotArea.h*i[0]+t.plotArea.y,i[1]=t.plotArea.h*i[1]+t.plotArea.y,isNaN(c)||(h?(r.moveTo(c,g[0]),r.lineTo(y.canvasx,g[0]),r.lineTo(y.canvasx,g[1])):(r.moveTo(c,g[0]),r.lineTo(y.canvasx,i[0]),r.lineTo(y.canvasx,i[1])),r.lineTo(c,g[1]),r.closePath()),g=i,c=y.canvasx)}r.fill()}},s._fastCanvasProxy=function(t){var e=[],a=null,i=null,n=0,r=function(t){if(!(e.length<=1)){for(var a=e.length-1;a>0;a--){var i=e[a];if(2==i[0]){var n=e[a-1];n[1]==i[1]&&n[2]==i[2]&&e.splice(a,1)}}for(var a=0;a<e.length-1;){var i=e[a];2==i[0]&&2==e[a+1][0]?e.splice(a,1):a++}if(e.length>2&&!t){var r=0;2==e[0][0]&&r++;for(var o=null,s=null,a=r;a<e.length;a++){var i=e[a];if(1==i[0])if(null===o&&null===s)o=a,s=a;else{var l=i[2];l<e[o][2]?o=a:l>e[s][2]&&(s=a)}}var h=e[o],u=e[s];e.splice(r,e.length-r),o<s?(e.push(h),e.push(u)):o>s?(e.push(u),e.push(h)):e.push(h)}}},o=function(a){r(a);for(var o=0,s=e.length;o<s;o++){var l=e[o];1==l[0]?t.lineTo(l[1],l[2]):2==l[0]&&t.moveTo(l[1],l[2])}e.length&&(i=e[e.length-1][1]),n+=e.length,e=[]},s=function(t,n,r){var s=Math.round(n);if(null===a||s!=a){var l=a-i>1,h=s-a>1;o(l||h),a=s}e.push([t,n,r])};return{moveTo:function(t,e){s(2,t,e)},lineTo:function(t,e){s(1,t,e)},stroke:function(){o(!0),t.stroke()},fill:function(){o(!0),t.fill()},beginPath:function(){o(!0),t.beginPath()},closePath:function(){o(!0),t.closePath()},_count:function(){return n}}},s._fillPlotter=function(t){if(!t.singleSeriesName&&0===t.seriesIndex){for(var e=t.dygraph,a=e.getLabels().slice(1),i=a.length;i>=0;i--)e.visibility()[i]||a.splice(i,1);if(function(){for(var t=0;t<a.length;t++)if(e.getBooleanOption("fillGraph",a[t]))return!0;return!1}())for(var r,l,h=t.plotArea,u=t.allSeriesPoints,d=u.length,c=e.getBooleanOption("stackedGraph"),p=e.getColors(),g={},f=function(t,e,a,i){if(t.lineTo(e,a),c)for(var n=i.length-1;n>=0;n--){var r=i[n];t.lineTo(r[0],r[1])}},_=d-1;_>=0;_--){var v=t.drawingContext,y=a[_];if(e.getBooleanOption("fillGraph",y)){var x=e.getNumericOption("fillAlpha",y),m=e.getBooleanOption("stepPlot",y),b=p[_],w=e.axisPropertiesForSeries(y),A=1+w.minyval*w.yscale;A<0?A=0:A>1&&(A=1),A=h.h*A+h.y;var O,D=u[_],E=n.createIterator(D,0,D.length,s._getIteratorPredicate(e.getBooleanOption("connectSeparatedPoints",y))),L=NaN,T=[-1,-1],S=n.toRGB_(b),P="rgba("+S.r+","+S.g+","+S.b+","+x+")";v.fillStyle=P,v.beginPath();var C,M=!0;(D.length>2*e.width_||o.default.FORCE_FAST_PROXY)&&(v=s._fastCanvasProxy(v));for(var N,F=[];E.hasNext;)if(N=E.next(),n.isOK(N.y)||m){if(c){if(!M&&C==N.xval)continue;M=!1,C=N.xval,r=g[N.canvasx];var k;k=void 0===r?A:l?r[0]:r,O=[N.canvasy,k],m?-1===T[0]?g[N.canvasx]=[N.canvasy,A]:g[N.canvasx]=[N.canvasy,T[0]]:g[N.canvasx]=N.canvasy}else O=isNaN(N.canvasy)&&m?[h.y+h.h,A]:[N.canvasy,A];isNaN(L)?(v.moveTo(N.canvasx,O[1]),v.lineTo(N.canvasx,O[0])):(m?(v.lineTo(N.canvasx,T[0]),v.lineTo(N.canvasx,O[0])):v.lineTo(N.canvasx,O[0]),c&&(F.push([L,T[1]]),l&&r?F.push([N.canvasx,r[1]]):F.push([N.canvasx,O[1]]))),T=O,L=N.canvasx}else f(v,L,T[1],F),F=[],L=NaN,null===N.y_stacked||isNaN(N.y_stacked)||(g[N.canvasx]=h.h*N.y_stacked+h.y);l=m,O&&N&&(f(v,N.canvasx,O[1],F),F=[]),v.fill()}}}},a.default=s,e.exports=a.default},{"./dygraph":18,"./dygraph-utils":17}],10:[function(t,e,a){"use strict";function i(t){return t&&t.__esModule?t:{default:t}}function n(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var a in t)Object.prototype.hasOwnProperty.call(t,a)&&(e[a]=t[a]);return e.default=t,e}Object.defineProperty(a,"__esModule",{value:!0});var r=t("./dygraph-tickers"),o=n(r),s=t("./dygraph-interaction-model"),l=i(s),h=t("./dygraph-canvas"),u=i(h),d=t("./dygraph-utils"),c=n(d),p={highlightCircleSize:3,highlightSeriesOpts:null,highlightSeriesBackgroundAlpha:.5,highlightSeriesBackgroundColor:"rgb(255, 255, 255)",labelsSeparateLines:!1,labelsShowZeroValues:!0,labelsKMB:!1,labelsKMG2:!1,showLabelsOnHighlight:!0,digitsAfterDecimal:2,maxNumberWidth:6,sigFigs:null,strokeWidth:1,strokeBorderWidth:0,strokeBorderColor:"white",axisTickSize:3,axisLabelFontSize:14,rightGap:5,showRoller:!1,xValueParser:void 0,delimiter:",",sigma:2,errorBars:!1,fractions:!1,wilsonInterval:!0,customBars:!1,fillGraph:!1,fillAlpha:.15,connectSeparatedPoints:!1,stackedGraph:!1,stackedGraphNaNFill:"all",hideOverlayOnMouseOut:!0,legend:"onmouseover",stepPlot:!1,xRangePad:0,yRangePad:null,drawAxesAtZero:!1,titleHeight:28,xLabelHeight:18,yLabelWidth:18,axisLineColor:"black",axisLineWidth:.3,gridLineWidth:.3,axisLabelWidth:50,gridLineColor:"rgb(128,128,128)",interactionModel:l.default.defaultModel,animatedZooms:!1,showRangeSelector:!1,rangeSelectorHeight:40,rangeSelectorPlotStrokeColor:"#808FAB",rangeSelectorPlotFillGradientColor:"white",rangeSelectorPlotFillColor:"#A7B1C4",rangeSelectorBackgroundStrokeColor:"gray",rangeSelectorBackgroundLineWidth:1,rangeSelectorPlotLineWidth:1.5,rangeSelectorForegroundStrokeColor:"black",rangeSelectorForegroundLineWidth:1,rangeSelectorAlpha:.6,showInRangeSelector:null,plotter:[u.default._fillPlotter,u.default._errorPlotter,u.default._linePlotter],plugins:[],axes:{x:{pixelsPerLabel:70,axisLabelWidth:60,axisLabelFormatter:c.dateAxisLabelFormatter,valueFormatter:c.dateValueFormatter,drawGrid:!0,drawAxis:!0,independentTicks:!0,ticker:o.dateTicker},y:{axisLabelWidth:50,pixelsPerLabel:30,valueFormatter:c.numberValueFormatter,axisLabelFormatter:c.numberAxisLabelFormatter,drawGrid:!0,drawAxis:!0,independentTicks:!0,ticker:o.numericTicks},y2:{axisLabelWidth:50,pixelsPerLabel:30,valueFormatter:c.numberValueFormatter,axisLabelFormatter:c.numberAxisLabelFormatter,drawAxis:!0,drawGrid:!1,independentTicks:!1,ticker:o.numericTicks}}};a.default=p,e.exports=a.default},{"./dygraph-canvas":9,"./dygraph-interaction-model":12,"./dygraph-tickers":16,"./dygraph-utils":17}],11:[function(t,e,a){"use strict";Object.defineProperty(a,"__esModule",{value:!0});var i=t("./dygraph"),n=function(t){return t&&t.__esModule?t:{default:t}}(i),r=function(t){this.container=t};r.prototype.draw=function(t,e){this.container.innerHTML="",void 0!==this.date_graph&&this.date_graph.destroy(),this.date_graph=new n.default(this.container,t,e)},r.prototype.setSelection=function(t){var e=!1;t.length&&(e=t[0].row),this.date_graph.setSelection(e)},r.prototype.getSelection=function(){var t=[],e=this.date_graph.getSelection();if(e<0)return t;for(var a=this.date_graph.layout_.points,i=0;i<a.length;++i)t.push({row:e,column:i+1});return t},a.default=r,e.exports=a.default},{"./dygraph":18}],12:[function(t,e,a){"use strict";Object.defineProperty(a,"__esModule",{value:!0});var i=t("./dygraph-utils"),n=function(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var a in t)Object.prototype.hasOwnProperty.call(t,a)&&(e[a]=t[a]);return e.default=t,e}(i),r={};r.maybeTreatMouseOpAsClick=function(t,e,a){a.dragEndX=n.dragGetX_(t,a),a.dragEndY=n.dragGetY_(t,a);var i=Math.abs(a.dragEndX-a.dragStartX),o=Math.abs(a.dragEndY-a.dragStartY);i<2&&o<2&&void 0!==e.lastx_&&-1!=e.lastx_&&r.treatMouseOpAsClick(e,t,a),a.regionWidth=i,a.regionHeight=o},r.startPan=function(t,e,a){var i,r;a.isPanning=!0;var o=e.xAxisRange();if(e.getOptionForAxis("logscale","x")?(a.initialLeftmostDate=n.log10(o[0]),a.dateRange=n.log10(o[1])-n.log10(o[0])):(a.initialLeftmostDate=o[0],a.dateRange=o[1]-o[0]),a.xUnitsPerPixel=a.dateRange/(e.plotter_.area.w-1),e.getNumericOption("panEdgeFraction")){var s=e.width_*e.getNumericOption("panEdgeFraction"),l=e.xAxisExtremes(),h=e.toDomXCoord(l[0])-s,u=e.toDomXCoord(l[1])+s,d=e.toDataXCoord(h),c=e.toDataXCoord(u);a.boundedDates=[d,c];var p=[],g=e.height_*e.getNumericOption("panEdgeFraction");for(i=0;i<e.axes_.length;i++){r=e.axes_[i];var f=r.extremeRange,_=e.toDomYCoord(f[0],i)+g,v=e.toDomYCoord(f[1],i)-g,y=e.toDataYCoord(_,i),x=e.toDataYCoord(v,i);p[i]=[y,x]}a.boundedValues=p}for(a.is2DPan=!1,a.axes=[],i=0;i<e.axes_.length;i++){r=e.axes_[i];var m={},b=e.yAxisRange(i);e.attributes_.getForAxis("logscale",i)?(m.initialTopValue=n.log10(b[1]),m.dragValueRange=n.log10(b[1])-n.log10(b[0])):(m.initialTopValue=b[1],m.dragValueRange=b[1]-b[0]),m.unitsPerPixel=m.dragValueRange/(e.plotter_.area.h-1),a.axes.push(m),r.valueRange&&(a.is2DPan=!0)}},r.movePan=function(t,e,a){a.dragEndX=n.dragGetX_(t,a),a.dragEndY=n.dragGetY_(t,a);var i=a.initialLeftmostDate-(a.dragEndX-a.dragStartX)*a.xUnitsPerPixel;a.boundedDates&&(i=Math.max(i,a.boundedDates[0]));var r=i+a.dateRange;if(a.boundedDates&&r>a.boundedDates[1]&&(i-=r-a.boundedDates[1],r=i+a.dateRange),e.getOptionForAxis("logscale","x")?e.dateWindow_=[Math.pow(n.LOG_SCALE,i),Math.pow(n.LOG_SCALE,r)]:e.dateWindow_=[i,r],a.is2DPan)for(var o=a.dragEndY-a.dragStartY,s=0;s<e.axes_.length;s++){var l=e.axes_[s],h=a.axes[s],u=o*h.unitsPerPixel,d=a.boundedValues?a.boundedValues[s]:null,c=h.initialTopValue+u;d&&(c=Math.min(c,d[1]));var p=c-h.dragValueRange;d&&p<d[0]&&(c-=p-d[0],p=c-h.dragValueRange),e.attributes_.getForAxis("logscale",s)?l.valueRange=[Math.pow(n.LOG_SCALE,p),Math.pow(n.LOG_SCALE,c)]:l.valueRange=[p,c]}e.drawGraph_(!1)},r.endPan=r.maybeTreatMouseOpAsClick,r.startZoom=function(t,e,a){a.isZooming=!0,a.zoomMoved=!1},r.moveZoom=function(t,e,a){a.zoomMoved=!0,a.dragEndX=n.dragGetX_(t,a),a.dragEndY=n.dragGetY_(t,a);var i=Math.abs(a.dragStartX-a.dragEndX),r=Math.abs(a.dragStartY-a.dragEndY);a.dragDirection=i<r/2?n.VERTICAL:n.HORIZONTAL,e.drawZoomRect_(a.dragDirection,a.dragStartX,a.dragEndX,a.dragStartY,a.dragEndY,a.prevDragDirection,a.prevEndX,a.prevEndY),a.prevEndX=a.dragEndX,a.prevEndY=a.dragEndY,a.prevDragDirection=a.dragDirection},r.treatMouseOpAsClick=function(t,e,a){for(var i=t.getFunctionOption("clickCallback"),n=t.getFunctionOption("pointClickCallback"),r=null,o=-1,s=Number.MAX_VALUE,l=0;l<t.selPoints_.length;l++){var h=t.selPoints_[l],u=Math.pow(h.canvasx-a.dragEndX,2)+Math.pow(h.canvasy-a.dragEndY,2);!isNaN(u)&&(-1==o||u<s)&&(s=u,o=l)}var d=t.getNumericOption("highlightCircleSize")+2;if(s<=d*d&&(r=t.selPoints_[o]),r){var c={cancelable:!0,point:r,canvasx:a.dragEndX,canvasy:a.dragEndY};if(t.cascadeEvents_("pointClick",c))return;n&&n.call(t,e,r)}var c={cancelable:!0,xval:t.lastx_,pts:t.selPoints_,canvasx:a.dragEndX,canvasy:a.dragEndY};t.cascadeEvents_("click",c)||i&&i.call(t,e,t.lastx_,t.selPoints_)},r.endZoom=function(t,e,a){e.clearZoomRect_(),a.isZooming=!1,r.maybeTreatMouseOpAsClick(t,e,a);var i=e.getArea();if(a.regionWidth>=10&&a.dragDirection==n.HORIZONTAL){var o=Math.min(a.dragStartX,a.dragEndX),s=Math.max(a.dragStartX,a.dragEndX);o=Math.max(o,i.x),s=Math.min(s,i.x+i.w),o<s&&e.doZoomX_(o,s),a.cancelNextDblclick=!0}else if(a.regionHeight>=10&&a.dragDirection==n.VERTICAL){var l=Math.min(a.dragStartY,a.dragEndY),h=Math.max(a.dragStartY,a.dragEndY);l=Math.max(l,i.y),h=Math.min(h,i.y+i.h),l<h&&e.doZoomY_(l,h),a.cancelNextDblclick=!0}a.dragStartX=null,a.dragStartY=null},r.startTouch=function(t,e,a){t.preventDefault(),t.touches.length>1&&(a.startTimeForDoubleTapMs=null);for(var i=[],n=0;n<t.touches.length;n++){var r=t.touches[n];i.push({pageX:r.pageX,pageY:r.pageY,dataX:e.toDataXCoord(r.pageX),dataY:e.toDataYCoord(r.pageY)})}if(a.initialTouches=i,1==i.length)a.initialPinchCenter=i[0],a.touchDirections={x:!0,y:!0};else if(i.length>=2){a.initialPinchCenter={pageX:.5*(i[0].pageX+i[1].pageX),pageY:.5*(i[0].pageY+i[1].pageY),dataX:.5*(i[0].dataX+i[1].dataX),dataY:.5*(i[0].dataY+i[1].dataY)};var o=180/Math.PI*Math.atan2(a.initialPinchCenter.pageY-i[0].pageY,i[0].pageX-a.initialPinchCenter.pageX);o=Math.abs(o),o>90&&(o=90-o),a.touchDirections={x:o<67.5,y:o>22.5}}a.initialRange={x:e.xAxisRange(),y:e.yAxisRange()}},r.moveTouch=function(t,e,a){a.startTimeForDoubleTapMs=null;var i,n=[];for(i=0;i<t.touches.length;i++){var r=t.touches[i];n.push({pageX:r.pageX,pageY:r.pageY})}var o,s=a.initialTouches,l=a.initialPinchCenter;o=1==n.length?n[0]:{pageX:.5*(n[0].pageX+n[1].pageX),pageY:.5*(n[0].pageY+n[1].pageY)};var h={pageX:o.pageX-l.pageX,pageY:o.pageY-l.pageY},u=a.initialRange.x[1]-a.initialRange.x[0],d=a.initialRange.y[0]-a.initialRange.y[1];h.dataX=h.pageX/e.plotter_.area.w*u,h.dataY=h.pageY/e.plotter_.area.h*d;var c,p;if(1==n.length)c=1,p=1;else if(n.length>=2){var g=s[1].pageX-l.pageX;c=(n[1].pageX-o.pageX)/g;var f=s[1].pageY-l.pageY;p=(n[1].pageY-o.pageY)/f}c=Math.min(8,Math.max(.125,c)),p=Math.min(8,Math.max(.125,p));var _=!1;if(a.touchDirections.x&&(e.dateWindow_=[l.dataX-h.dataX+(a.initialRange.x[0]-l.dataX)/c,l.dataX-h.dataX+(a.initialRange.x[1]-l.dataX)/c],_=!0),a.touchDirections.y)for(i=0;i<1;i++){var v=e.axes_[i],y=e.attributes_.getForAxis("logscale",i);y||(v.valueRange=[l.dataY-h.dataY+(a.initialRange.y[0]-l.dataY)/p,l.dataY-h.dataY+(a.initialRange.y[1]-l.dataY)/p],_=!0)}if(e.drawGraph_(!1),_&&n.length>1&&e.getFunctionOption("zoomCallback")){var x=e.xAxisRange();e.getFunctionOption("zoomCallback").call(e,x[0],x[1],e.yAxisRanges())}},r.endTouch=function(t,e,a){if(0!==t.touches.length)r.startTouch(t,e,a);else if(1==t.changedTouches.length){var i=(new Date).getTime(),n=t.changedTouches[0];a.startTimeForDoubleTapMs&&i-a.startTimeForDoubleTapMs<500&&a.doubleTapX&&Math.abs(a.doubleTapX-n.screenX)<50&&a.doubleTapY&&Math.abs(a.doubleTapY-n.screenY)<50?e.resetZoom():(a.startTimeForDoubleTapMs=i,a.doubleTapX=n.screenX,a.doubleTapY=n.screenY)}};var o=function(t,e,a){return t<e?e-t:t>a?t-a:0},s=function(t,e){var a=n.findPos(e.canvas_),i={left:a.x,right:a.x+e.canvas_.offsetWidth,top:a.y,bottom:a.y+e.canvas_.offsetHeight},r={x:n.pageX(t),y:n.pageY(t)},s=o(r.x,i.left,i.right),l=o(r.y,i.top,i.bottom);return Math.max(s,l)};r.defaultModel={mousedown:function(t,e,a){if(!t.button||2!=t.button){a.initializeMouseDown(t,e,a),t.altKey||t.shiftKey?r.startPan(t,e,a):r.startZoom(t,e,a);var i=function(t){if(a.isZooming){s(t,e)<100?r.moveZoom(t,e,a):null!==a.dragEndX&&(a.dragEndX=null,a.dragEndY=null,e.clearZoomRect_())}else a.isPanning&&r.movePan(t,e,a)},o=function t(o){a.isZooming?null!==a.dragEndX?r.endZoom(o,e,a):r.maybeTreatMouseOpAsClick(o,e,a):a.isPanning&&r.endPan(o,e,a),n.removeEvent(document,"mousemove",i),n.removeEvent(document,"mouseup",t),a.destroy()};e.addAndTrackEvent(document,"mousemove",i),e.addAndTrackEvent(document,"mouseup",o)}},willDestroyContextMyself:!0,touchstart:function(t,e,a){r.startTouch(t,e,a)},touchmove:function(t,e,a){r.moveTouch(t,e,a)},touchend:function(t,e,a){r.endTouch(t,e,a)},dblclick:function(t,e,a){if(a.cancelNextDblclick)return void(a.cancelNextDblclick=!1);var i={canvasx:a.dragEndX,canvasy:a.dragEndY,cancelable:!0};e.cascadeEvents_("dblclick",i)||t.altKey||t.shiftKey||e.resetZoom()}},r.nonInteractiveModel_={mousedown:function(t,e,a){a.initializeMouseDown(t,e,a)},mouseup:r.maybeTreatMouseOpAsClick},r.dragIsPanInteractionModel={mousedown:function(t,e,a){a.initializeMouseDown(t,e,a),r.startPan(t,e,a)},mousemove:function(t,e,a){a.isPanning&&r.movePan(t,e,a)},mouseup:function(t,e,a){a.isPanning&&r.endPan(t,e,a)}},a.default=r,e.exports=a.default},{"./dygraph-utils":17}],13:[function(t,e,a){"use strict";Object.defineProperty(a,"__esModule",{value:!0});var i=t("./dygraph-utils"),n=function(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var a in t)Object.prototype.hasOwnProperty.call(t,a)&&(e[a]=t[a]);return e.default=t,e}(i),r=function(t){this.dygraph_=t,this.points=[],this.setNames=[],this.annotations=[],this.yAxes_=null,this.xTicks_=null,this.yTicks_=null};r.prototype.addDataset=function(t,e){this.points.push(e),this.setNames.push(t)},r.prototype.getPlotArea=function(){return this.area_},r.prototype.computePlotArea=function(){var t={x:0,y:0};t.w=this.dygraph_.width_-t.x-this.dygraph_.getOption("rightGap"),t.h=this.dygraph_.height_;var e={chart_div:this.dygraph_.graphDiv,reserveSpaceLeft:function(e){var a={x:t.x,y:t.y,w:e,h:t.h};return t.x+=e,t.w-=e,a},reserveSpaceRight:function(e){var a={x:t.x+t.w-e,y:t.y,w:e,h:t.h};return t.w-=e,a},reserveSpaceTop:function(e){var a={x:t.x,y:t.y,w:t.w,h:e};return t.y+=e,t.h-=e,a},reserveSpaceBottom:function(e){var a={x:t.x,y:t.y+t.h-e,w:t.w,h:e};return t.h-=e,a},chartRect:function(){return{x:t.x,y:t.y,w:t.w,h:t.h}}};this.dygraph_.cascadeEvents_("layout",e),this.area_=t},r.prototype.setAnnotations=function(t){this.annotations=[];for(var e=this.dygraph_.getOption("xValueParser")||function(t){return t},a=0;a<t.length;a++){var i={};if(!t[a].xval&&void 0===t[a].x)return void console.error("Annotations must have an 'x' property");if(t[a].icon&&(!t[a].hasOwnProperty("width")||!t[a].hasOwnProperty("height")))return void console.error("Must set width and height when setting annotation.icon property");n.update(i,t[a]),i.xval||(i.xval=e(i.x)),this.annotations.push(i)}},r.prototype.setXTicks=function(t){this.xTicks_=t},r.prototype.setYAxes=function(t){this.yAxes_=t},r.prototype.evaluate=function(){this._xAxis={},this._evaluateLimits(),this._evaluateLineCharts(),this._evaluateLineTicks(),this._evaluateAnnotations()},r.prototype._evaluateLimits=function(){var t=this.dygraph_.xAxisRange();this._xAxis.minval=t[0],this._xAxis.maxval=t[1];var e=t[1]-t[0];this._xAxis.scale=0!==e?1/e:1,this.dygraph_.getOptionForAxis("logscale","x")&&(this._xAxis.xlogrange=n.log10(this._xAxis.maxval)-n.log10(this._xAxis.minval),this._xAxis.xlogscale=0!==this._xAxis.xlogrange?1/this._xAxis.xlogrange:1);for(var a=0;a<this.yAxes_.length;a++){var i=this.yAxes_[a];i.minyval=i.computedValueRange[0],i.maxyval=i.computedValueRange[1],i.yrange=i.maxyval-i.minyval,i.yscale=0!==i.yrange?1/i.yrange:1,this.dygraph_.getOption("logscale")&&(i.ylogrange=n.log10(i.maxyval)-n.log10(i.minyval),i.ylogscale=0!==i.ylogrange?1/i.ylogrange:1,isFinite(i.ylogrange)&&!isNaN(i.ylogrange)||console.error("axis "+a+" of graph at "+i.g+" can't be displayed in log scale for range ["+i.minyval+" - "+i.maxyval+"]"))}},r.calcXNormal_=function(t,e,a){return a?(n.log10(t)-n.log10(e.minval))*e.xlogscale:(t-e.minval)*e.scale},r.calcYNormal_=function(t,e,a){if(a){var i=1-(n.log10(e)-n.log10(t.minyval))*t.ylogscale;return isFinite(i)?i:NaN}return 1-(e-t.minyval)*t.yscale},r.prototype._evaluateLineCharts=function(){for(var t=this.dygraph_.getOption("stackedGraph"),e=this.dygraph_.getOptionForAxis("logscale","x"),a=0;a<this.points.length;a++){for(var i=this.points[a],n=this.setNames[a],o=this.dygraph_.getOption("connectSeparatedPoints",n),s=this.dygraph_.axisPropertiesForSeries(n),l=this.dygraph_.attributes_.getForSeries("logscale",n),h=0;h<i.length;h++){var u=i[h];u.x=r.calcXNormal_(u.xval,this._xAxis,e);var d=u.yval;t&&(u.y_stacked=r.calcYNormal_(s,u.yval_stacked,l),
+null===d||isNaN(d)||(d=u.yval_stacked)),null===d&&(d=NaN,o||(u.yval=NaN)),u.y=r.calcYNormal_(s,d,l)}this.dygraph_.dataHandler_.onLineEvaluated(i,s,l)}},r.prototype._evaluateLineTicks=function(){var t,e,a,i,n,r;for(this.xticks=[],t=0;t<this.xTicks_.length;t++)e=this.xTicks_[t],a=e.label,r=!("label_v"in e),n=r?e.v:e.label_v,(i=this.dygraph_.toPercentXCoord(n))>=0&&i<1&&this.xticks.push({pos:i,label:a,has_tick:r});for(this.yticks=[],t=0;t<this.yAxes_.length;t++)for(var o=this.yAxes_[t],s=0;s<o.ticks.length;s++)e=o.ticks[s],a=e.label,r=!("label_v"in e),n=r?e.v:e.label_v,(i=this.dygraph_.toPercentYCoord(n,t))>0&&i<=1&&this.yticks.push({axis:t,pos:i,label:a,has_tick:r})},r.prototype._evaluateAnnotations=function(){var t,e={};for(t=0;t<this.annotations.length;t++){var a=this.annotations[t];e[a.xval+","+a.series]=a}if(this.annotated_points=[],this.annotations&&this.annotations.length)for(var i=0;i<this.points.length;i++){var n=this.points[i];for(t=0;t<n.length;t++){var r=n[t],o=r.xval+","+r.name;o in e&&(r.annotation=e[o],this.annotated_points.push(r))}}},r.prototype.removeAllDatasets=function(){delete this.points,delete this.setNames,delete this.setPointsLengths,delete this.setPointsOffsets,this.points=[],this.setNames=[],this.setPointsLengths=[],this.setPointsOffsets=[]},a.default=r,e.exports=a.default},{"./dygraph-utils":17}],14:[function(t,e,a){(function(t){"use strict";Object.defineProperty(a,"__esModule",{value:!0});var i=null;if(void 0!==t);a.default=i,e.exports=a.default}).call(this,t("_process"))},{_process:1}],15:[function(t,e,a){(function(i){"use strict";function n(t){return t&&t.__esModule?t:{default:t}}Object.defineProperty(a,"__esModule",{value:!0});var r=t("./dygraph-utils"),o=function(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var a in t)Object.prototype.hasOwnProperty.call(t,a)&&(e[a]=t[a]);return e.default=t,e}(r),s=t("./dygraph-default-attrs"),l=n(s),h=t("./dygraph-options-reference"),u=(n(h),function(t){this.dygraph_=t,this.yAxes_=[],this.xAxis_={},this.series_={},this.global_=this.dygraph_.attrs_,this.user_=this.dygraph_.user_attrs_||{},this.labels_=[],this.highlightSeries_=this.get("highlightSeriesOpts")||{},this.reparseSeries()});if(u.AXIS_STRING_MAPPINGS_={y:0,Y:0,y1:0,Y1:0,y2:1,Y2:1},u.axisToIndex_=function(t){if("string"==typeof t){if(u.AXIS_STRING_MAPPINGS_.hasOwnProperty(t))return u.AXIS_STRING_MAPPINGS_[t];throw"Unknown axis : "+t}if("number"==typeof t){if(0===t||1===t)return t;throw"Dygraphs only supports two y-axes, indexed from 0-1."}if(t)throw"Unknown axis : "+t;return 0},u.prototype.reparseSeries=function(){var t=this.get("labels");if(t){this.labels_=t.slice(1),this.yAxes_=[{series:[],options:{}}],this.xAxis_={options:{}},this.series_={};for(var e=this.user_.series||{},a=0;a<this.labels_.length;a++){var i=this.labels_[a],n=e[i]||{},r=u.axisToIndex_(n.axis);this.series_[i]={idx:a,yAxis:r,options:n},this.yAxes_[r]?this.yAxes_[r].series.push(i):this.yAxes_[r]={series:[i],options:{}}}var s=this.user_.axes||{};o.update(this.yAxes_[0].options,s.y||{}),this.yAxes_.length>1&&o.update(this.yAxes_[1].options,s.y2||{}),o.update(this.xAxis_.options,s.x||{})}},u.prototype.get=function(t){var e=this.getGlobalUser_(t);return null!==e?e:this.getGlobalDefault_(t)},u.prototype.getGlobalUser_=function(t){return this.user_.hasOwnProperty(t)?this.user_[t]:null},u.prototype.getGlobalDefault_=function(t){return this.global_.hasOwnProperty(t)?this.global_[t]:l.default.hasOwnProperty(t)?l.default[t]:null},u.prototype.getForAxis=function(t,e){var a,i;if("number"==typeof e)a=e,i=0===a?"y":"y2";else{if("y1"==e&&(e="y"),"y"==e)a=0;else if("y2"==e)a=1;else{if("x"!=e)throw"Unknown axis "+e;a=-1}i=e}var n=-1==a?this.xAxis_:this.yAxes_[a];if(n){var r=n.options;if(r.hasOwnProperty(t))return r[t]}if("x"!==e||"logscale"!==t){var o=this.getGlobalUser_(t);if(null!==o)return o}var s=l.default.axes[i];return s.hasOwnProperty(t)?s[t]:this.getGlobalDefault_(t)},u.prototype.getForSeries=function(t,e){if(e===this.dygraph_.getHighlightSeries()&&this.highlightSeries_.hasOwnProperty(t))return this.highlightSeries_[t];if(!this.series_.hasOwnProperty(e))throw"Unknown series: "+e;var a=this.series_[e],i=a.options;return i.hasOwnProperty(t)?i[t]:this.getForAxis(t,a.yAxis)},u.prototype.numAxes=function(){return this.yAxes_.length},u.prototype.axisForSeries=function(t){return this.series_[t].yAxis},u.prototype.axisOptions=function(t){return this.yAxes_[t].options},u.prototype.seriesForAxis=function(t){return this.yAxes_[t].series},u.prototype.seriesNames=function(){return this.labels_},void 0!==i);a.default=u,e.exports=a.default}).call(this,t("_process"))},{"./dygraph-default-attrs":10,"./dygraph-options-reference":14,"./dygraph-utils":17,_process:1}],16:[function(t,e,a){"use strict";Object.defineProperty(a,"__esModule",{value:!0});var i=t("./dygraph-utils"),n=function(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var a in t)Object.prototype.hasOwnProperty.call(t,a)&&(e[a]=t[a]);return e.default=t,e}(i),r=function(t,e,a,i,n,r){return o(t,e,a,function(t){return"logscale"!==t&&i(t)},n,r)};a.numericLinearTicks=r;var o=function(t,e,a,i,r,o){var s,l,h,u,c=i("pixelsPerLabel"),p=[];if(o)for(s=0;s<o.length;s++)p.push({v:o[s]});else{if(i("logscale")){u=Math.floor(a/c);var g=n.binarySearch(t,d,1),f=n.binarySearch(e,d,-1);-1==g&&(g=0),-1==f&&(f=d.length-1);var _=null;if(f-g>=u/4){for(var v=f;v>=g;v--){var y=d[v],x=Math.log(y/t)/Math.log(e/t)*a,m={v:y};null===_?_={tickValue:y,pixel_coord:x}:Math.abs(x-_.pixel_coord)>=c?_={tickValue:y,pixel_coord:x}:m.label="",p.push(m)}p.reverse()}}if(0===p.length){var b,w,A=i("labelsKMG2");A?(b=[1,2,4,8,16,32,64,128,256],w=16):(b=[1,2,5,10,20,50,100],w=10);var O,D,E,L=Math.ceil(a/c),T=Math.abs(e-t)/L,S=Math.floor(Math.log(T)/Math.log(w)),P=Math.pow(w,S);for(l=0;l<b.length&&(O=P*b[l],D=Math.floor(t/O)*O,E=Math.ceil(e/O)*O,u=Math.abs(E-D)/O,!(a/u>c));l++);for(D>E&&(O*=-1),s=0;s<=u;s++)h=D+s*O,p.push({v:h})}}var C=i("axisLabelFormatter");for(s=0;s<p.length;s++)void 0===p[s].label&&(p[s].label=C.call(r,p[s].v,0,i,r));return p};a.numericTicks=o;var s=function(t,e,a,i,n,r){var o=c(t,e,a,i);return o>=0?g(t,e,o,i,n):[]};a.dateTicker=s;var l={MILLISECONDLY:0,TWO_MILLISECONDLY:1,FIVE_MILLISECONDLY:2,TEN_MILLISECONDLY:3,FIFTY_MILLISECONDLY:4,HUNDRED_MILLISECONDLY:5,FIVE_HUNDRED_MILLISECONDLY:6,SECONDLY:7,TWO_SECONDLY:8,FIVE_SECONDLY:9,TEN_SECONDLY:10,THIRTY_SECONDLY:11,MINUTELY:12,TWO_MINUTELY:13,FIVE_MINUTELY:14,TEN_MINUTELY:15,THIRTY_MINUTELY:16,HOURLY:17,TWO_HOURLY:18,SIX_HOURLY:19,DAILY:20,TWO_DAILY:21,WEEKLY:22,MONTHLY:23,QUARTERLY:24,BIANNUAL:25,ANNUAL:26,DECADAL:27,CENTENNIAL:28,NUM_GRANULARITIES:29};a.Granularity=l;var h={DATEFIELD_Y:0,DATEFIELD_M:1,DATEFIELD_D:2,DATEFIELD_HH:3,DATEFIELD_MM:4,DATEFIELD_SS:5,DATEFIELD_MS:6,NUM_DATEFIELDS:7},u=[];u[l.MILLISECONDLY]={datefield:h.DATEFIELD_MS,step:1,spacing:1},u[l.TWO_MILLISECONDLY]={datefield:h.DATEFIELD_MS,step:2,spacing:2},u[l.FIVE_MILLISECONDLY]={datefield:h.DATEFIELD_MS,step:5,spacing:5},u[l.TEN_MILLISECONDLY]={datefield:h.DATEFIELD_MS,step:10,spacing:10},u[l.FIFTY_MILLISECONDLY]={datefield:h.DATEFIELD_MS,step:50,spacing:50},u[l.HUNDRED_MILLISECONDLY]={datefield:h.DATEFIELD_MS,step:100,spacing:100},u[l.FIVE_HUNDRED_MILLISECONDLY]={datefield:h.DATEFIELD_MS,step:500,spacing:500},u[l.SECONDLY]={datefield:h.DATEFIELD_SS,step:1,spacing:1e3},u[l.TWO_SECONDLY]={datefield:h.DATEFIELD_SS,step:2,spacing:2e3},u[l.FIVE_SECONDLY]={datefield:h.DATEFIELD_SS,step:5,spacing:5e3},u[l.TEN_SECONDLY]={datefield:h.DATEFIELD_SS,step:10,spacing:1e4},u[l.THIRTY_SECONDLY]={datefield:h.DATEFIELD_SS,step:30,spacing:3e4},u[l.MINUTELY]={datefield:h.DATEFIELD_MM,step:1,spacing:6e4},u[l.TWO_MINUTELY]={datefield:h.DATEFIELD_MM,step:2,spacing:12e4},u[l.FIVE_MINUTELY]={datefield:h.DATEFIELD_MM,step:5,spacing:3e5},u[l.TEN_MINUTELY]={datefield:h.DATEFIELD_MM,step:10,spacing:6e5},u[l.THIRTY_MINUTELY]={datefield:h.DATEFIELD_MM,step:30,spacing:18e5},u[l.HOURLY]={datefield:h.DATEFIELD_HH,step:1,spacing:36e5},u[l.TWO_HOURLY]={datefield:h.DATEFIELD_HH,step:2,spacing:72e5},u[l.SIX_HOURLY]={datefield:h.DATEFIELD_HH,step:6,spacing:216e5},u[l.DAILY]={datefield:h.DATEFIELD_D,step:1,spacing:864e5},u[l.TWO_DAILY]={datefield:h.DATEFIELD_D,step:2,spacing:1728e5},u[l.WEEKLY]={datefield:h.DATEFIELD_D,step:7,spacing:6048e5},u[l.MONTHLY]={datefield:h.DATEFIELD_M,step:1,spacing:2629817280},u[l.QUARTERLY]={datefield:h.DATEFIELD_M,step:3,spacing:216e5*365.2524},u[l.BIANNUAL]={datefield:h.DATEFIELD_M,step:6,spacing:432e5*365.2524},u[l.ANNUAL]={datefield:h.DATEFIELD_Y,step:1,spacing:864e5*365.2524},u[l.DECADAL]={datefield:h.DATEFIELD_Y,step:10,spacing:315578073600},u[l.CENTENNIAL]={datefield:h.DATEFIELD_Y,step:100,spacing:3155780736e3};var d=function(){for(var t=[],e=-39;e<=39;e++)for(var a=Math.pow(10,e),i=1;i<=9;i++){var n=a*i;t.push(n)}return t}(),c=function(t,e,a,i){for(var n=i("pixelsPerLabel"),r=0;r<l.NUM_GRANULARITIES;r++){if(a/p(t,e,r)>=n)return r}return-1},p=function(t,e,a){var i=u[a].spacing;return Math.round(1*(e-t)/i)},g=function(t,e,a,i,r){var o=i("axisLabelFormatter"),s=i("labelsUTC"),d=s?n.DateAccessorsUTC:n.DateAccessorsLocal,c=u[a].datefield,p=u[a].step,g=u[a].spacing,f=new Date(t),_=[];_[h.DATEFIELD_Y]=d.getFullYear(f),_[h.DATEFIELD_M]=d.getMonth(f),_[h.DATEFIELD_D]=d.getDate(f),_[h.DATEFIELD_HH]=d.getHours(f),_[h.DATEFIELD_MM]=d.getMinutes(f),_[h.DATEFIELD_SS]=d.getSeconds(f),_[h.DATEFIELD_MS]=d.getMilliseconds(f);var v=_[c]%p;a==l.WEEKLY&&(v=d.getDay(f)),_[c]-=v;for(var y=c+1;y<h.NUM_DATEFIELDS;y++)_[y]=y===h.DATEFIELD_D?1:0;var x=[],m=d.makeDate.apply(null,_),b=m.getTime();if(a<=l.HOURLY)for(b<t&&(b+=g,m=new Date(b));b<=e;)x.push({v:b,label:o.call(r,m,a,i,r)}),b+=g,m=new Date(b);else for(b<t&&(_[c]+=p,m=d.makeDate.apply(null,_),b=m.getTime());b<=e;)(a>=l.DAILY||d.getHours(m)%p==0)&&x.push({v:b,label:o.call(r,m,a,i,r)}),_[c]+=p,m=d.makeDate.apply(null,_),b=m.getTime();return x};a.getDateAxis=g},{"./dygraph-utils":17}],17:[function(t,e,a){"use strict";function i(t,e,a){t.removeEventListener(e,a,!1)}function n(t){return t=t||window.event,t.stopPropagation&&t.stopPropagation(),t.preventDefault&&t.preventDefault(),t.cancelBubble=!0,t.cancel=!0,t.returnValue=!1,!1}function r(t,e,a){var i,n,r;if(0===e)i=a,n=a,r=a;else{var o=Math.floor(6*t),s=6*t-o,l=a*(1-e),h=a*(1-e*s),u=a*(1-e*(1-s));switch(o){case 1:i=h,n=a,r=l;break;case 2:i=l,n=a,r=u;break;case 3:i=l,n=h,r=a;break;case 4:i=u,n=l,r=a;break;case 5:i=a,n=l,r=h;break;case 6:case 0:i=a,n=u,r=l}}return i=Math.floor(255*i+.5),n=Math.floor(255*n+.5),r=Math.floor(255*r+.5),"rgb("+i+","+n+","+r+")"}function o(t){var e=t.getBoundingClientRect(),a=window,i=document.documentElement;return{x:e.left+(a.pageXOffset||i.scrollLeft),y:e.top+(a.pageYOffset||i.scrollTop)}}function s(t){return!t.pageX||t.pageX<0?0:t.pageX}function l(t){return!t.pageY||t.pageY<0?0:t.pageY}function h(t,e){return s(t)-e.px}function u(t,e){return l(t)-e.py}function d(t){return!!t&&!isNaN(t)}function c(t,e){return!!t&&(null!==t.yval&&(null!==t.x&&void 0!==t.x&&(null!==t.y&&void 0!==t.y&&!(isNaN(t.x)||!e&&isNaN(t.y)))))}function p(t,e){var a=Math.min(Math.max(1,e||2),21);return Math.abs(t)<.001&&0!==t?t.toExponential(a-1):t.toPrecision(a)}function g(t){return t<10?"0"+t:""+t}function f(t,e,a,i){var n=g(t)+":"+g(e);if(a&&(n+=":"+g(a),i)){var r=""+i;n+="."+("000"+r).substring(r.length)}return n}function _(t,e){var a=e?tt:$,i=new Date(t),n=a.getFullYear(i),r=a.getMonth(i),o=a.getDate(i),s=a.getHours(i),l=a.getMinutes(i),h=a.getSeconds(i),u=a.getMilliseconds(i),d=""+n,c=g(r+1),p=g(o),_=3600*s+60*l+h+.001*u,v=d+"/"+c+"/"+p;return _&&(v+=" "+f(s,l,h,u)),v}function v(t,e){var a=Math.pow(10,e);return Math.round(t*a)/a}function y(t,e,a,i,n){for(var r=!0;r;){var o=t,s=e,l=a,h=i,u=n;if(r=!1,null!==h&&void 0!==h&&null!==u&&void 0!==u||(h=0,u=s.length-1),h>u)return-1;null!==l&&void 0!==l||(l=0);var d,c=function(t){return t>=0&&t<s.length},p=parseInt((h+u)/2,10),g=s[p];if(g==o)return p;if(g>o){if(l>0&&(d=p-1,c(d)&&s[d]<o))return p;t=o,e=s,a=l,i=h,n=p-1,r=!0,c=p=g=d=void 0}else{if(!(g<o))return-1;if(l<0&&(d=p+1,c(d)&&s[d]>o))return p;t=o,e=s,a=l,i=p+1,n=u,r=!0,c=p=g=d=void 0}}}function x(t){var e,a;if((-1==t.search("-")||-1!=t.search("T")||-1!=t.search("Z"))&&(a=m(t))&&!isNaN(a))return a;if(-1!=t.search("-")){for(e=t.replace("-","/","g");-1!=e.search("-");)e=e.replace("-","/");a=m(e)}else 8==t.length?(e=t.substr(0,4)+"/"+t.substr(4,2)+"/"+t.substr(6,2),a=m(e)):a=m(t);return a&&!isNaN(a)||console.error("Couldn't parse "+t+" as a date"),a}function m(t){return new Date(t).getTime()}function b(t,e){if(void 0!==e&&null!==e)for(var a in e)e.hasOwnProperty(a)&&(t[a]=e[a]);return t}function w(t,e){if(void 0!==e&&null!==e)for(var a in e)e.hasOwnProperty(a)&&(null===e[a]?t[a]=null:A(e[a])?t[a]=e[a].slice():!function(t){return"object"==typeof Node?t instanceof Node:"object"==typeof t&&"number"==typeof t.nodeType&&"string"==typeof t.nodeName}(e[a])&&"object"==typeof e[a]?("object"==typeof t[a]&&null!==t[a]||(t[a]={}),w(t[a],e[a])):t[a]=e[a]);return t}function A(t){var e=typeof t;return("object"==e||"function"==e&&"function"==typeof t.item)&&null!==t&&"number"==typeof t.length&&3!==t.nodeType}function O(t){return"object"==typeof t&&null!==t&&"function"==typeof t.getTime}function D(t){for(var e=[],a=0;a<t.length;a++)A(t[a])?e.push(D(t[a])):e.push(t[a]);return e}function E(){return document.createElement("canvas")}function L(t){try{var e=window.devicePixelRatio,a=t.webkitBackingStorePixelRatio||t.mozBackingStorePixelRatio||t.msBackingStorePixelRatio||t.oBackingStorePixelRatio||t.backingStorePixelRatio||1;return void 0!==e?e/a:1}catch(t){return 1}}function T(t,e,a,i){e=e||0,a=a||t.length,this.hasNext=!0,this.peek=null,this.start_=e,this.array_=t,this.predicate_=i,this.end_=Math.min(t.length,e+a),this.nextIdx_=e-1,this.next()}function S(t,e,a,i){return new T(t,e,a,i)}function P(t,e,a,i){var n,r=0,o=(new Date).getTime();if(t(r),1==e)return void i();var s=e-1;!function l(){r>=e||et.call(window,function(){var e=(new Date).getTime(),h=e-o;n=r,r=Math.floor(h/a);var u=r-n;r+u>s||r>=s?(t(s),i()):(0!==u&&t(r),l())})}()}function C(t,e){var a={};if(t)for(var i=1;i<t.length;i++)a[t[i]]=!0;var n=function(t){for(var e in t)if(t.hasOwnProperty(e)&&!at[e])return!0;return!1};for(var r in e)if(e.hasOwnProperty(r))if("highlightSeriesOpts"==r||a[r]&&!e.series){if(n(e[r]))return!0}else if("series"==r||"axes"==r){var o=e[r];for(var s in o)if(o.hasOwnProperty(s)&&n(o[s]))return!0}else if(!at[r])return!0;return!1}function M(t){for(var e=0;e<t.length;e++){var a=t.charAt(e);if("\r"===a)return e+1<t.length&&"\n"===t.charAt(e+1)?"\r\n":a;if("\n"===a)return e+1<t.length&&"\r"===t.charAt(e+1)?"\n\r":a}return null}function N(t,e){if(null===e||null===t)return!1;for(var a=t;a&&a!==e;)a=a.parentNode;return a===e}function F(t,e){return e<0?1/Math.pow(t,-e):Math.pow(t,e)}function k(t){var e=nt.exec(t);if(!e)return null;var a=parseInt(e[1],10),i=parseInt(e[2],10),n=parseInt(e[3],10);return e[4]?{r:a,g:i,b:n,a:parseFloat(e[4])}:{r:a,g:i,b:n}}function R(t){var e=k(t);if(e)return e;var a=document.createElement("div");a.style.backgroundColor=t,a.style.visibility="hidden",document.body.appendChild(a);var i=window.getComputedStyle(a,null).backgroundColor;return document.body.removeChild(a),k(i)}function I(t){try{(t||document.createElement("canvas")).getContext("2d")}catch(t){return!1}return!0}function H(t,e,a){var i=parseFloat(t);if(!isNaN(i))return i;if(/^ *$/.test(t))return null;if(/^ *nan *$/i.test(t))return NaN;var n="Unable to parse '"+t+"' as a number";return void 0!==a&&void 0!==e&&(n+=" on line "+(1+(e||0))+" ('"+a+"') of CSV."),console.error(n),null}function Y(t,e){var a=e("sigFigs");if(null!==a)return p(t,a);var i,n=e("digitsAfterDecimal"),r=e("maxNumberWidth"),o=e("labelsKMB"),s=e("labelsKMG2");if(i=0!==t&&(Math.abs(t)>=Math.pow(10,r)||Math.abs(t)<Math.pow(10,-n))?t.toExponential(n):""+v(t,n),o||s){var l,h=[],u=[];o&&(l=1e3,h=rt),s&&(o&&console.warn("Setting both labelsKMB and labelsKMG2. Pick one!"),l=1024,h=ot,u=st);for(var d=Math.abs(t),c=F(l,h.length),g=h.length-1;g>=0;g--,c/=l)if(d>=c){i=v(t/c,n)+h[g];break}if(s){var f=String(t.toExponential()).split("e-");2===f.length&&f[1]>=3&&f[1]<=24&&(i=f[1]%3>0?v(f[0]/F(10,f[1]%3),n):Number(f[0]).toFixed(2),i+=u[Math.floor(f[1]/3)-1])}}return i}function X(t,e,a){return Y.call(this,t,a)}function V(t,e,a){var i=a("labelsUTC"),n=i?tt:$,r=n.getFullYear(t),o=n.getMonth(t),s=n.getDate(t),l=n.getHours(t),h=n.getMinutes(t),u=n.getSeconds(t),d=n.getMilliseconds(t);if(e>=G.Granularity.DECADAL)return""+r;if(e>=G.Granularity.MONTHLY)return lt[o]+"&#160;"+r;if(0===3600*l+60*h+u+.001*d||e>=G.Granularity.DAILY)return g(s)+"&#160;"+lt[o];if(e<G.Granularity.SECONDLY){var c=""+d;return g(u)+"."+("000"+c).substring(c.length)}return e>G.Granularity.MINUTELY?f(l,h,u,0):f(l,h,u,d)}function Z(t,e){return _(t,e("labelsUTC"))}Object.defineProperty(a,"__esModule",{value:!0}),a.removeEvent=i,a.cancelEvent=n,a.hsvToRGB=r,a.findPos=o,a.pageX=s,a.pageY=l,a.dragGetX_=h,a.dragGetY_=u,a.isOK=d,a.isValidPoint=c,a.floatFormat=p,a.zeropad=g,a.hmsString_=f,a.dateString_=_,a.round_=v,a.binarySearch=y,a.dateParser=x,a.dateStrToMillis=m,a.update=b,a.updateDeep=w,a.isArrayLike=A,a.isDateLike=O,a.clone=D,a.createCanvas=E,a.getContextPixelRatio=L,a.Iterator=T,a.createIterator=S,a.repeatAndCleanup=P,a.isPixelChangingOptionList=C,a.detectLineDelimiter=M,a.isNodeContainedBy=N,a.pow=F,a.toRGB_=R,a.isCanvasSupported=I,a.parseFloat_=H,a.numberValueFormatter=Y,a.numberAxisLabelFormatter=X,a.dateAxisLabelFormatter=V,a.dateValueFormatter=Z;var B=t("./dygraph-tickers"),G=function(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var a in t)Object.prototype.hasOwnProperty.call(t,a)&&(e[a]=t[a]);return e.default=t,e}(B);a.LOG_SCALE=10;var W=Math.log(10);a.LN_TEN=W;var U=function(t){return Math.log(t)/W};a.log10=U;var z=function(t,e,a){var i=U(t),n=U(e),r=i+a*(n-i);return Math.pow(10,r)};a.logRangeFraction=z;var j=[2,2];a.DOTTED_LINE=j;var K=[7,3];a.DASHED_LINE=K;var q=[7,2,2,2];a.DOT_DASH_LINE=q;a.HORIZONTAL=1;a.VERTICAL=2;var Q=function(t){return t.getContext("2d")};a.getContext=Q;var J=function(t,e,a){t.addEventListener(e,a,!1)};a.addEvent=J;var $={getFullYear:function(t){return t.getFullYear()},getMonth:function(t){return t.getMonth()},getDate:function(t){return t.getDate()},getHours:function(t){return t.getHours()},getMinutes:function(t){return t.getMinutes()},getSeconds:function(t){return t.getSeconds()},getMilliseconds:function(t){return t.getMilliseconds()},getDay:function(t){return t.getDay()},makeDate:function(t,e,a,i,n,r,o){return new Date(t,e,a,i,n,r,o)}};a.DateAccessorsLocal=$;var tt={getFullYear:function(t){return t.getUTCFullYear()},getMonth:function(t){return t.getUTCMonth()},getDate:function(t){return t.getUTCDate()},getHours:function(t){return t.getUTCHours()},getMinutes:function(t){return t.getUTCMinutes()},getSeconds:function(t){return t.getUTCSeconds()},getMilliseconds:function(t){return t.getUTCMilliseconds()},getDay:function(t){return t.getUTCDay()},makeDate:function(t,e,a,i,n,r,o){return new Date(Date.UTC(t,e,a,i,n,r,o))}};a.DateAccessorsUTC=tt,T.prototype.next=function(){if(!this.hasNext)return null;for(var t=this.peek,e=this.nextIdx_+1,a=!1;e<this.end_;){if(!this.predicate_||this.predicate_(this.array_,e)){this.peek=this.array_[e],a=!0;break}e++}return this.nextIdx_=e,a||(this.hasNext=!1,this.peek=null),t};var et=function(){return window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(t){window.setTimeout(t,1e3/60)}}();a.requestAnimFrame=et;var at={annotationClickHandler:!0,annotationDblClickHandler:!0,annotationMouseOutHandler:!0,annotationMouseOverHandler:!0,axisLineColor:!0,axisLineWidth:!0,clickCallback:!0,drawCallback:!0,drawHighlightPointCallback:!0,drawPoints:!0,drawPointCallback:!0,drawGrid:!0,fillAlpha:!0,gridLineColor:!0,gridLineWidth:!0,hideOverlayOnMouseOut:!0,highlightCallback:!0,highlightCircleSize:!0,interactionModel:!0,labelsDiv:!0,labelsKMB:!0,labelsKMG2:!0,labelsSeparateLines:!0,labelsShowZeroValues:!0,legend:!0,panEdgeFraction:!0,pixelsPerYLabel:!0,pointClickCallback:!0,pointSize:!0,rangeSelectorPlotFillColor:!0,rangeSelectorPlotFillGradientColor:!0,rangeSelectorPlotStrokeColor:!0,rangeSelectorBackgroundStrokeColor:!0,rangeSelectorBackgroundLineWidth:!0,rangeSelectorPlotLineWidth:!0,rangeSelectorForegroundStrokeColor:!0,rangeSelectorForegroundLineWidth:!0,rangeSelectorAlpha:!0,showLabelsOnHighlight:!0,showRoller:!0,strokeWidth:!0,underlayCallback:!0,unhighlightCallback:!0,zoomCallback:!0},it={DEFAULT:function(t,e,a,i,n,r,o){a.beginPath(),a.fillStyle=r,a.arc(i,n,o,0,2*Math.PI,!1),a.fill()}};a.Circles=it;var nt=/^rgba?\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})(?:,\s*([01](?:\.\d+)?))?\)$/,rt=["K","M","B","T","Q"],ot=["k","M","G","T","P","E","Z","Y"],st=["m","u","n","p","f","a","z","y"],lt=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]},{"./dygraph-tickers":16}],18:[function(t,e,a){(function(i){"use strict";function n(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var a in t)Object.prototype.hasOwnProperty.call(t,a)&&(e[a]=t[a]);return e.default=t,e}function r(t){return t&&t.__esModule?t:{default:t}}function o(t){var e=t[0],a=e[0];if("number"!=typeof a&&!x.isDateLike(a))throw new Error("Expected number or date but got "+typeof a+": "+a+".");for(var i=1;i<e.length;i++){var n=e[i];if(null!==n&&void 0!==n&&("number"!=typeof n&&!x.isArrayLike(n)))throw new Error("Expected number or array but got "+typeof n+": "+n+".")}}Object.defineProperty(a,"__esModule",{value:!0});var s=function(){function t(t,e){var a=[],i=!0,n=!1,r=void 0;try{for(var o,s=t[Symbol.iterator]();!(i=(o=s.next()).done)&&(a.push(o.value),!e||a.length!==e);i=!0);}catch(t){n=!0,r=t}finally{try{!i&&s.return&&s.return()}finally{if(n)throw r}}return a}return function(e,a){if(Array.isArray(e))return e;if(Symbol.iterator in Object(e))return t(e,a);throw new TypeError("Invalid attempt to destructure non-iterable instance")}}(),l=t("./dygraph-layout"),h=r(l),u=t("./dygraph-canvas"),d=r(u),c=t("./dygraph-options"),p=r(c),g=t("./dygraph-interaction-model"),f=r(g),_=t("./dygraph-tickers"),v=n(_),y=t("./dygraph-utils"),x=n(y),m=t("./dygraph-default-attrs"),b=r(m),w=t("./dygraph-options-reference"),A=(r(w),t("./iframe-tarp")),O=r(A),D=t("./datahandler/default"),E=r(D),L=t("./datahandler/bars-error"),T=r(L),S=t("./datahandler/bars-custom"),P=r(S),C=t("./datahandler/default-fractions"),M=r(C),N=t("./datahandler/bars-fractions"),F=r(N),k=t("./datahandler/bars"),R=r(k),I=t("./plugins/annotations"),H=r(I),Y=t("./plugins/axes"),X=r(Y),V=t("./plugins/chart-labels"),Z=r(V),B=t("./plugins/grid"),G=r(B),W=t("./plugins/legend"),U=r(W),z=t("./plugins/range-selector"),j=r(z),K=t("./dygraph-gviz"),q=r(K),Q=function(t,e,a){this.__init__(t,e,a)};Q.NAME="Dygraph",Q.VERSION="2.1.0",Q.DEFAULT_ROLL_PERIOD=1,Q.DEFAULT_WIDTH=480,Q.DEFAULT_HEIGHT=320,Q.ANIMATION_STEPS=12,Q.ANIMATION_DURATION=200,Q.Plotters=d.default._Plotters,Q.addedAnnotationCSS=!1,Q.prototype.__init__=function(t,e,a){if(this.is_initial_draw_=!0,this.readyFns_=[],null!==a&&void 0!==a||(a={}),a=Q.copyUserAttrs_(a),"string"==typeof t&&(t=document.getElementById(t)),!t)throw new Error("Constructing dygraph with a non-existent div!");this.maindiv_=t,this.file_=e,this.rollPeriod_=a.rollPeriod||Q.DEFAULT_ROLL_PERIOD,this.previousVerticalX_=-1,this.fractions_=a.fractions||!1,this.dateWindow_=a.dateWindow||null,this.annotations_=[],t.innerHTML="",""===t.style.width&&a.width&&(t.style.width=a.width+"px"),""===t.style.height&&a.height&&(t.style.height=a.height+"px"),""===t.style.height&&0===t.clientHeight&&(t.style.height=Q.DEFAULT_HEIGHT+"px",""===t.style.width&&(t.style.width=Q.DEFAULT_WIDTH+"px")),this.width_=t.clientWidth||a.width||0,this.height_=t.clientHeight||a.height||0,a.stackedGraph&&(a.fillGraph=!0),this.user_attrs_={},x.update(this.user_attrs_,a),this.attrs_={},x.updateDeep(this.attrs_,b.default),this.boundaryIds_=[],this.setIndexByName_={},this.datasetIndex_=[],this.registeredEvents_=[],this.eventListeners_={},this.attributes_=new p.default(this),this.createInterface_(),this.plugins_=[];for(var i=Q.PLUGINS.concat(this.getOption("plugins")),n=0;n<i.length;n++){var r,o=i[n];r=void 0!==o.activate?o:new o;var s={plugin:r,events:{},options:{},pluginOptions:{}},l=r.activate(this);for(var h in l)l.hasOwnProperty(h)&&(s.events[h]=l[h]);this.plugins_.push(s)}for(var n=0;n<this.plugins_.length;n++){var u=this.plugins_[n];for(var h in u.events)if(u.events.hasOwnProperty(h)){var d=u.events[h],c=[u.plugin,d];h in this.eventListeners_?this.eventListeners_[h].push(c):this.eventListeners_[h]=[c]}}this.createDragInterface_(),this.start_()},Q.prototype.cascadeEvents_=function(t,e){if(!(t in this.eventListeners_))return!1;var a={dygraph:this,cancelable:!1,defaultPrevented:!1,preventDefault:function(){if(!a.cancelable)throw"Cannot call preventDefault on non-cancelable event.";a.defaultPrevented=!0},propagationStopped:!1,stopPropagation:function(){a.propagationStopped=!0}};x.update(a,e);var i=this.eventListeners_[t];if(i)for(var n=i.length-1;n>=0;n--){var r=i[n][0],o=i[n][1];if(o.call(r,a),a.propagationStopped)break}return a.defaultPrevented},Q.prototype.getPluginInstance_=function(t){for(var e=0;e<this.plugins_.length;e++){var a=this.plugins_[e];if(a.plugin instanceof t)return a.plugin}return null},Q.prototype.isZoomed=function(t){var e=!!this.dateWindow_;if("x"===t)return e;var a=this.axes_.map(function(t){return!!t.valueRange}).indexOf(!0)>=0;if(null===t||void 0===t)return e||a;if("y"===t)return a;throw new Error("axis parameter is ["+t+"] must be null, 'x' or 'y'.")},Q.prototype.toString=function(){var t=this.maindiv_;return"[Dygraph "+(t&&t.id?t.id:t)+"]"},Q.prototype.attr_=function(t,e){return e?this.attributes_.getForSeries(t,e):this.attributes_.get(t)},Q.prototype.getOption=function(t,e){return this.attr_(t,e)},Q.prototype.getNumericOption=function(t,e){return this.getOption(t,e)},Q.prototype.getStringOption=function(t,e){return this.getOption(t,e)},Q.prototype.getBooleanOption=function(t,e){return this.getOption(t,e)},Q.prototype.getFunctionOption=function(t,e){return this.getOption(t,e)},Q.prototype.getOptionForAxis=function(t,e){return this.attributes_.getForAxis(t,e)},Q.prototype.optionsViewForAxis_=function(t){var e=this;return function(a){var i=e.user_attrs_.axes;return i&&i[t]&&i[t].hasOwnProperty(a)?i[t][a]:("x"!==t||"logscale"!==a)&&(void 0!==e.user_attrs_[a]?e.user_attrs_[a]:(i=e.attrs_.axes,i&&i[t]&&i[t].hasOwnProperty(a)?i[t][a]:"y"==t&&e.axes_[0].hasOwnProperty(a)?e.axes_[0][a]:"y2"==t&&e.axes_[1].hasOwnProperty(a)?e.axes_[1][a]:e.attr_(a)))}},Q.prototype.rollPeriod=function(){return this.rollPeriod_},Q.prototype.xAxisRange=function(){return this.dateWindow_?this.dateWindow_:this.xAxisExtremes()},Q.prototype.xAxisExtremes=function(){var t=this.getNumericOption("xRangePad")/this.plotter_.area.w;if(0===this.numRows())return[0-t,1+t];var e=this.rawData_[0][0],a=this.rawData_[this.rawData_.length-1][0];if(t){var i=a-e;e-=i*t,a+=i*t}return[e,a]},Q.prototype.yAxisExtremes=function(){var t=this.gatherDatasets_(this.rolledSeries_,null),e=t.extremes,a=this.axes_;this.computeYAxisRanges_(e);var i=this.axes_;return this.axes_=a,i.map(function(t){return t.extremeRange})},Q.prototype.yAxisRange=function(t){if(void 0===t&&(t=0),t<0||t>=this.axes_.length)return null;var e=this.axes_[t];return[e.computedValueRange[0],e.computedValueRange[1]]},Q.prototype.yAxisRanges=function(){for(var t=[],e=0;e<this.axes_.length;e++)t.push(this.yAxisRange(e));return t},Q.prototype.toDomCoords=function(t,e,a){return[this.toDomXCoord(t),this.toDomYCoord(e,a)]},Q.prototype.toDomXCoord=function(t){if(null===t)return null;var e=this.plotter_.area,a=this.xAxisRange();return e.x+(t-a[0])/(a[1]-a[0])*e.w},Q.prototype.toDomYCoord=function(t,e){var a=this.toPercentYCoord(t,e);if(null===a)return null;var i=this.plotter_.area;return i.y+a*i.h},Q.prototype.toDataCoords=function(t,e,a){return[this.toDataXCoord(t),this.toDataYCoord(e,a)]},Q.prototype.toDataXCoord=function(t){if(null===t)return null;var e=this.plotter_.area,a=this.xAxisRange();if(this.attributes_.getForAxis("logscale","x")){var i=(t-e.x)/e.w;return x.logRangeFraction(a[0],a[1],i)}return a[0]+(t-e.x)/e.w*(a[1]-a[0])},Q.prototype.toDataYCoord=function(t,e){if(null===t)return null;var a=this.plotter_.area,i=this.yAxisRange(e);if(void 0===e&&(e=0),this.attributes_.getForAxis("logscale",e)){var n=(t-a.y)/a.h;return x.logRangeFraction(i[1],i[0],n)}return i[0]+(a.y+a.h-t)/a.h*(i[1]-i[0])},Q.prototype.toPercentYCoord=function(t,e){if(null===t)return null;void 0===e&&(e=0);var a,i=this.yAxisRange(e);if(this.attributes_.getForAxis("logscale",e)){var n=x.log10(i[0]),r=x.log10(i[1]);a=(r-x.log10(t))/(r-n)}else a=(i[1]-t)/(i[1]-i[0]);return a},Q.prototype.toPercentXCoord=function(t){if(null===t)return null;var e,a=this.xAxisRange();if(!0===this.attributes_.getForAxis("logscale","x")){var i=x.log10(a[0]),n=x.log10(a[1]);e=(x.log10(t)-i)/(n-i)}else e=(t-a[0])/(a[1]-a[0]);return e},Q.prototype.numColumns=function(){return this.rawData_?this.rawData_[0]?this.rawData_[0].length:this.attr_("labels").length:0},Q.prototype.numRows=function(){return this.rawData_?this.rawData_.length:0},Q.prototype.getValue=function(t,e){return t<0||t>this.rawData_.length?null:e<0||e>this.rawData_[t].length?null:this.rawData_[t][e]},Q.prototype.createInterface_=function(){var t=this.maindiv_;this.graphDiv=document.createElement("div"),this.graphDiv.style.textAlign="left",this.graphDiv.style.position="relative",t.appendChild(this.graphDiv),this.canvas_=x.createCanvas(),this.canvas_.style.position="absolute",this.hidden_=this.createPlotKitCanvas_(this.canvas_),this.canvas_ctx_=x.getContext(this.canvas_),this.hidden_ctx_=x.getContext(this.hidden_),this.resizeElements_(),this.graphDiv.appendChild(this.hidden_),this.graphDiv.appendChild(this.canvas_),this.mouseEventElement_=this.createMouseEventElement_(),this.layout_=new h.default(this);var e=this;this.mouseMoveHandler_=function(t){e.mouseMove_(t)},this.mouseOutHandler_=function(t){var a=t.target||t.fromElement,i=t.relatedTarget||t.toElement;x.isNodeContainedBy(a,e.graphDiv)&&!x.isNodeContainedBy(i,e.graphDiv)&&e.mouseOut_(t)},this.addAndTrackEvent(window,"mouseout",this.mouseOutHandler_),this.addAndTrackEvent(this.mouseEventElement_,"mousemove",this.mouseMoveHandler_),this.resizeHandler_||(this.resizeHandler_=function(t){e.resize()},this.addAndTrackEvent(window,"resize",this.resizeHandler_))},Q.prototype.resizeElements_=function(){this.graphDiv.style.width=this.width_+"px",this.graphDiv.style.height=this.height_+"px";var t=this.getNumericOption("pixelRatio"),e=t||x.getContextPixelRatio(this.canvas_ctx_);this.canvas_.width=this.width_*e,this.canvas_.height=this.height_*e,this.canvas_.style.width=this.width_+"px",this.canvas_.style.height=this.height_+"px",1!==e&&this.canvas_ctx_.scale(e,e);var a=t||x.getContextPixelRatio(this.hidden_ctx_);this.hidden_.width=this.width_*a,this.hidden_.height=this.height_*a,this.hidden_.style.width=this.width_+"px",this.hidden_.style.height=this.height_+"px",1!==a&&this.hidden_ctx_.scale(a,a)},Q.prototype.destroy=function(){this.canvas_ctx_.restore(),this.hidden_ctx_.restore();for(var t=this.plugins_.length-1;t>=0;t--){var e=this.plugins_.pop();e.plugin.destroy&&e.plugin.destroy()}this.removeTrackedEvents_(),x.removeEvent(window,"mouseout",this.mouseOutHandler_),x.removeEvent(this.mouseEventElement_,"mousemove",this.mouseMoveHandler_),x.removeEvent(window,"resize",this.resizeHandler_),this.resizeHandler_=null,function t(e){for(;e.hasChildNodes();)t(e.firstChild),e.removeChild(e.firstChild)}(this.maindiv_);var a=function(t){for(var e in t)"object"==typeof t[e]&&(t[e]=null)};a(this.layout_),a(this.plotter_),a(this)},Q.prototype.createPlotKitCanvas_=function(t){var e=x.createCanvas();return e.style.position="absolute",e.style.top=t.style.top,e.style.left=t.style.left,
+e.width=this.width_,e.height=this.height_,e.style.width=this.width_+"px",e.style.height=this.height_+"px",e},Q.prototype.createMouseEventElement_=function(){return this.canvas_},Q.prototype.setColors_=function(){var t=this.getLabels(),e=t.length-1;this.colors_=[],this.colorsMap_={};for(var a=this.getNumericOption("colorSaturation")||1,i=this.getNumericOption("colorValue")||.5,n=Math.ceil(e/2),r=this.getOption("colors"),o=this.visibility(),s=0;s<e;s++)if(o[s]){var l=t[s+1],h=this.attributes_.getForSeries("color",l);if(!h)if(r)h=r[s%r.length];else{var u=s%2?n+(s+1)/2:Math.ceil((s+1)/2),d=1*u/(1+e);h=x.hsvToRGB(d,a,i)}this.colors_.push(h),this.colorsMap_[l]=h}},Q.prototype.getColors=function(){return this.colors_},Q.prototype.getPropertiesForSeries=function(t){for(var e=-1,a=this.getLabels(),i=1;i<a.length;i++)if(a[i]==t){e=i;break}return-1==e?null:{name:t,column:e,visible:this.visibility()[e-1],color:this.colorsMap_[t],axis:1+this.attributes_.axisForSeries(t)}},Q.prototype.createRollInterface_=function(){var t=this,e=this.roller_;e||(this.roller_=e=document.createElement("input"),e.type="text",e.style.display="none",e.className="dygraph-roller",this.graphDiv.appendChild(e));var a=this.getBooleanOption("showRoller")?"block":"none",i=this.getArea(),n={top:i.y+i.h-25+"px",left:i.x+1+"px",display:a};e.size="2",e.value=this.rollPeriod_,x.update(e.style,n),e.onchange=function(){return t.adjustRoll(e.value)}},Q.prototype.createDragInterface_=function(){var t={isZooming:!1,isPanning:!1,is2DPan:!1,dragStartX:null,dragStartY:null,dragEndX:null,dragEndY:null,dragDirection:null,prevEndX:null,prevEndY:null,prevDragDirection:null,cancelNextDblclick:!1,initialLeftmostDate:null,xUnitsPerPixel:null,dateRange:null,px:0,py:0,boundedDates:null,boundedValues:null,tarp:new O.default,initializeMouseDown:function(t,e,a){t.preventDefault?t.preventDefault():(t.returnValue=!1,t.cancelBubble=!0);var i=x.findPos(e.canvas_);a.px=i.x,a.py=i.y,a.dragStartX=x.dragGetX_(t,a),a.dragStartY=x.dragGetY_(t,a),a.cancelNextDblclick=!1,a.tarp.cover()},destroy:function(){var t=this;if((t.isZooming||t.isPanning)&&(t.isZooming=!1,t.dragStartX=null,t.dragStartY=null),t.isPanning){t.isPanning=!1,t.draggingDate=null,t.dateRange=null;for(var e=0;e<a.axes_.length;e++)delete a.axes_[e].draggingValue,delete a.axes_[e].dragValueRange}t.tarp.uncover()}},e=this.getOption("interactionModel"),a=this;for(var i in e)e.hasOwnProperty(i)&&this.addAndTrackEvent(this.mouseEventElement_,i,function(e){return function(i){e(i,a,t)}}(e[i]));if(!e.willDestroyContextMyself){var n=function(e){t.destroy()};this.addAndTrackEvent(document,"mouseup",n)}},Q.prototype.drawZoomRect_=function(t,e,a,i,n,r,o,s){var l=this.canvas_ctx_;r==x.HORIZONTAL?l.clearRect(Math.min(e,o),this.layout_.getPlotArea().y,Math.abs(e-o),this.layout_.getPlotArea().h):r==x.VERTICAL&&l.clearRect(this.layout_.getPlotArea().x,Math.min(i,s),this.layout_.getPlotArea().w,Math.abs(i-s)),t==x.HORIZONTAL?a&&e&&(l.fillStyle="rgba(128,128,128,0.33)",l.fillRect(Math.min(e,a),this.layout_.getPlotArea().y,Math.abs(a-e),this.layout_.getPlotArea().h)):t==x.VERTICAL&&n&&i&&(l.fillStyle="rgba(128,128,128,0.33)",l.fillRect(this.layout_.getPlotArea().x,Math.min(i,n),this.layout_.getPlotArea().w,Math.abs(n-i)))},Q.prototype.clearZoomRect_=function(){this.currentZoomRectArgs_=null,this.canvas_ctx_.clearRect(0,0,this.width_,this.height_)},Q.prototype.doZoomX_=function(t,e){this.currentZoomRectArgs_=null;var a=this.toDataXCoord(t),i=this.toDataXCoord(e);this.doZoomXDates_(a,i)},Q.prototype.doZoomXDates_=function(t,e){var a=this,i=this.xAxisRange(),n=[t,e],r=this.getFunctionOption("zoomCallback");this.doAnimatedZoom(i,n,null,null,function(){r&&r.call(a,t,e,a.yAxisRanges())})},Q.prototype.doZoomY_=function(t,e){var a=this;this.currentZoomRectArgs_=null;for(var i=this.yAxisRanges(),n=[],r=0;r<this.axes_.length;r++){var o=this.toDataYCoord(t,r),l=this.toDataYCoord(e,r);n.push([l,o])}var h=this.getFunctionOption("zoomCallback");this.doAnimatedZoom(null,null,i,n,function(){if(h){var t=a.xAxisRange(),e=s(t,2),i=e[0],n=e[1];h.call(a,i,n,a.yAxisRanges())}})},Q.zoomAnimationFunction=function(t,e){return(1-Math.pow(1.5,-t))/(1-Math.pow(1.5,-e))},Q.prototype.resetZoom=function(){var t=this,e=this.isZoomed("x"),a=this.isZoomed("y"),i=e||a;if(this.clearSelection(),i){var n=this.xAxisExtremes(),r=s(n,2),o=r[0],l=r[1],h=this.getBooleanOption("animatedZooms"),u=this.getFunctionOption("zoomCallback");if(!h)return this.dateWindow_=null,this.axes_.forEach(function(t){t.valueRange&&delete t.valueRange}),this.drawGraph_(),void(u&&u.call(this,o,l,this.yAxisRanges()));var d=null,c=null,p=null,g=null;e&&(d=this.xAxisRange(),c=[o,l]),a&&(p=this.yAxisRanges(),g=this.yAxisExtremes()),this.doAnimatedZoom(d,c,p,g,function(){t.dateWindow_=null,t.axes_.forEach(function(t){t.valueRange&&delete t.valueRange}),u&&u.call(t,o,l,t.yAxisRanges())})}},Q.prototype.doAnimatedZoom=function(t,e,a,i,n){var r,o,s=this,l=this.getBooleanOption("animatedZooms")?Q.ANIMATION_STEPS:1,h=[],u=[];if(null!==t&&null!==e)for(r=1;r<=l;r++)o=Q.zoomAnimationFunction(r,l),h[r-1]=[t[0]*(1-o)+o*e[0],t[1]*(1-o)+o*e[1]];if(null!==a&&null!==i)for(r=1;r<=l;r++){o=Q.zoomAnimationFunction(r,l);for(var d=[],c=0;c<this.axes_.length;c++)d.push([a[c][0]*(1-o)+o*i[c][0],a[c][1]*(1-o)+o*i[c][1]]);u[r-1]=d}x.repeatAndCleanup(function(t){if(u.length)for(var e=0;e<s.axes_.length;e++){var a=u[t][e];s.axes_[e].valueRange=[a[0],a[1]]}h.length&&(s.dateWindow_=h[t]),s.drawGraph_()},l,Q.ANIMATION_DURATION/l,n)},Q.prototype.getArea=function(){return this.plotter_.area},Q.prototype.eventToDomCoords=function(t){if(t.offsetX&&t.offsetY)return[t.offsetX,t.offsetY];var e=x.findPos(this.mouseEventElement_);return[x.pageX(t)-e.x,x.pageY(t)-e.y]},Q.prototype.findClosestRow=function(t){for(var e=1/0,a=-1,i=this.layout_.points,n=0;n<i.length;n++)for(var r=i[n],o=r.length,s=0;s<o;s++){var l=r[s];if(x.isValidPoint(l,!0)){var h=Math.abs(l.canvasx-t);h<e&&(e=h,a=l.idx)}}return a},Q.prototype.findClosestPoint=function(t,e){for(var a,i,n,r,o,s,l,h=1/0,u=this.layout_.points.length-1;u>=0;--u)for(var d=this.layout_.points[u],c=0;c<d.length;++c)r=d[c],x.isValidPoint(r)&&(i=r.canvasx-t,n=r.canvasy-e,(a=i*i+n*n)<h&&(h=a,o=r,s=u,l=r.idx));return{row:l,seriesName:this.layout_.setNames[s],point:o}},Q.prototype.findStackedPoint=function(t,e){for(var a,i,n=this.findClosestRow(t),r=0;r<this.layout_.points.length;++r){var o=this.getLeftBoundary_(r),s=n-o,l=this.layout_.points[r];if(!(s>=l.length)){var h=l[s];if(x.isValidPoint(h)){var u=h.canvasy;if(t>h.canvasx&&s+1<l.length){var d=l[s+1];if(x.isValidPoint(d)){var c=d.canvasx-h.canvasx;if(c>0){var p=(t-h.canvasx)/c;u+=p*(d.canvasy-h.canvasy)}}}else if(t<h.canvasx&&s>0){var g=l[s-1];if(x.isValidPoint(g)){var c=h.canvasx-g.canvasx;if(c>0){var p=(h.canvasx-t)/c;u+=p*(g.canvasy-h.canvasy)}}}(0===r||u<e)&&(a=h,i=r)}}}return{row:n,seriesName:this.layout_.setNames[i],point:a}},Q.prototype.mouseMove_=function(t){var e=this.layout_.points;if(void 0!==e&&null!==e){var a=this.eventToDomCoords(t),i=a[0],n=a[1],r=this.getOption("highlightSeriesOpts"),o=!1;if(r&&!this.isSeriesLocked()){var s;s=this.getBooleanOption("stackedGraph")?this.findStackedPoint(i,n):this.findClosestPoint(i,n),o=this.setSelection(s.row,s.seriesName)}else{var l=this.findClosestRow(i);o=this.setSelection(l)}var h=this.getFunctionOption("highlightCallback");h&&o&&h.call(this,t,this.lastx_,this.selPoints_,this.lastRow_,this.highlightSet_)}},Q.prototype.getLeftBoundary_=function(t){if(this.boundaryIds_[t])return this.boundaryIds_[t][0];for(var e=0;e<this.boundaryIds_.length;e++)if(void 0!==this.boundaryIds_[e])return this.boundaryIds_[e][0];return 0},Q.prototype.animateSelection_=function(t){void 0===this.fadeLevel&&(this.fadeLevel=0),void 0===this.animateId&&(this.animateId=0);var e=this.fadeLevel,a=t<0?e:10-e;if(a<=0)return void(this.fadeLevel&&this.updateSelection_(1));var i=++this.animateId,n=this,r=function(){0!==n.fadeLevel&&t<0&&(n.fadeLevel=0,n.clearSelection())};x.repeatAndCleanup(function(e){n.animateId==i&&(n.fadeLevel+=t,0===n.fadeLevel?n.clearSelection():n.updateSelection_(n.fadeLevel/10))},a,30,r)},Q.prototype.updateSelection_=function(t){this.cascadeEvents_("select",{selectedRow:-1===this.lastRow_?void 0:this.lastRow_,selectedX:-1===this.lastx_?void 0:this.lastx_,selectedPoints:this.selPoints_});var e,a=this.canvas_ctx_;if(this.getOption("highlightSeriesOpts")){a.clearRect(0,0,this.width_,this.height_);var i=1-this.getNumericOption("highlightSeriesBackgroundAlpha"),n=x.toRGB_(this.getOption("highlightSeriesBackgroundColor"));if(i){if(void 0===t)return void this.animateSelection_(1);i*=t,a.fillStyle="rgba("+n.r+","+n.g+","+n.b+","+i+")",a.fillRect(0,0,this.width_,this.height_)}this.plotter_._renderLineChart(this.highlightSet_,a)}else if(this.previousVerticalX_>=0){var r=0,o=this.attr_("labels");for(e=1;e<o.length;e++){var s=this.getNumericOption("highlightCircleSize",o[e]);s>r&&(r=s)}var l=this.previousVerticalX_;a.clearRect(l-r-1,0,2*r+2,this.height_)}if(this.selPoints_.length>0){var h=this.selPoints_[0].canvasx;for(a.save(),e=0;e<this.selPoints_.length;e++){var u=this.selPoints_[e];if(!isNaN(u.canvasy)){var d=this.getNumericOption("highlightCircleSize",u.name),c=this.getFunctionOption("drawHighlightPointCallback",u.name),p=this.plotter_.colors[u.name];c||(c=x.Circles.DEFAULT),a.lineWidth=this.getNumericOption("strokeWidth",u.name),a.strokeStyle=p,a.fillStyle=p,c.call(this,this,u.name,a,h,u.canvasy,p,d,u.idx)}}a.restore(),this.previousVerticalX_=h}},Q.prototype.setSelection=function(t,e,a){this.selPoints_=[];var i=!1;if(!1!==t&&t>=0){t!=this.lastRow_&&(i=!0),this.lastRow_=t;for(var n=0;n<this.layout_.points.length;++n){var r=this.layout_.points[n],o=t-this.getLeftBoundary_(n);if(o>=0&&o<r.length&&r[o].idx==t){var s=r[o];null!==s.yval&&this.selPoints_.push(s)}else for(var l=0;l<r.length;++l){var s=r[l];if(s.idx==t){null!==s.yval&&this.selPoints_.push(s);break}}}}else this.lastRow_>=0&&(i=!0),this.lastRow_=-1;return this.selPoints_.length?this.lastx_=this.selPoints_[0].xval:this.lastx_=-1,void 0!==e&&(this.highlightSet_!==e&&(i=!0),this.highlightSet_=e),void 0!==a&&(this.lockedSet_=a),i&&this.updateSelection_(void 0),i},Q.prototype.mouseOut_=function(t){this.getFunctionOption("unhighlightCallback")&&this.getFunctionOption("unhighlightCallback").call(this,t),this.getBooleanOption("hideOverlayOnMouseOut")&&!this.lockedSet_&&this.clearSelection()},Q.prototype.clearSelection=function(){if(this.cascadeEvents_("deselect",{}),this.lockedSet_=!1,this.fadeLevel)return void this.animateSelection_(-1);this.canvas_ctx_.clearRect(0,0,this.width_,this.height_),this.fadeLevel=0,this.selPoints_=[],this.lastx_=-1,this.lastRow_=-1,this.highlightSet_=null},Q.prototype.getSelection=function(){if(!this.selPoints_||this.selPoints_.length<1)return-1;for(var t=0;t<this.layout_.points.length;t++)for(var e=this.layout_.points[t],a=0;a<e.length;a++)if(e[a].x==this.selPoints_[0].x)return e[a].idx;return-1},Q.prototype.getHighlightSeries=function(){return this.highlightSet_},Q.prototype.isSeriesLocked=function(){return this.lockedSet_},Q.prototype.loadedEvent_=function(t){this.rawData_=this.parseCSV_(t),this.cascadeDataDidUpdateEvent_(),this.predraw_()},Q.prototype.addXTicks_=function(){var t;t=this.dateWindow_?[this.dateWindow_[0],this.dateWindow_[1]]:this.xAxisExtremes();var e=this.optionsViewForAxis_("x"),a=e("ticker")(t[0],t[1],this.plotter_.area.w,e,this);this.layout_.setXTicks(a)},Q.prototype.getHandlerClass_=function(){return this.attr_("dataHandler")?this.attr_("dataHandler"):this.fractions_?this.getBooleanOption("errorBars")?F.default:M.default:this.getBooleanOption("customBars")?P.default:this.getBooleanOption("errorBars")?T.default:E.default},Q.prototype.predraw_=function(){var t=new Date;this.dataHandler_=new(this.getHandlerClass_()),this.layout_.computePlotArea(),this.computeYAxes_(),this.is_initial_draw_||(this.canvas_ctx_.restore(),this.hidden_ctx_.restore()),this.canvas_ctx_.save(),this.hidden_ctx_.save(),this.plotter_=new d.default(this,this.hidden_,this.hidden_ctx_,this.layout_),this.createRollInterface_(),this.cascadeEvents_("predraw"),this.rolledSeries_=[null];for(var e=1;e<this.numColumns();e++){var a=this.dataHandler_.extractSeries(this.rawData_,e,this.attributes_);this.rollPeriod_>1&&(a=this.dataHandler_.rollingAverage(a,this.rollPeriod_,this.attributes_)),this.rolledSeries_.push(a)}this.drawGraph_();var i=new Date;this.drawingTimeMs_=i-t},Q.PointType=void 0,Q.stackPoints_=function(t,e,a,i){for(var n=null,r=null,o=null,s=-1,l=0;l<t.length;++l){var h=t[l],u=h.xval;void 0===e[u]&&(e[u]=0);var d=h.yval;isNaN(d)||null===d?"none"==i?d=0:(!function(e){if(!(s>=e))for(var a=e;a<t.length;++a)if(o=null,!isNaN(t[a].yval)&&null!==t[a].yval){s=a,o=t[a];break}}(l),d=r&&o&&"none"!=i?r.yval+(o.yval-r.yval)*((u-r.xval)/(o.xval-r.xval)):r&&"all"==i?r.yval:o&&"all"==i?o.yval:0):r=h;var c=e[u];n!=u&&(c+=d,e[u]=c),n=u,h.yval_stacked=c,c>a[1]&&(a[1]=c),c<a[0]&&(a[0]=c)}},Q.prototype.gatherDatasets_=function(t,e){var a,i,n,r,o,s,l=[],h=[],u=[],d={},c=t.length-1;for(a=c;a>=1;a--)if(this.visibility()[a-1]){if(e){s=t[a];var p=e[0],g=e[1];for(n=null,r=null,i=0;i<s.length;i++)s[i][0]>=p&&null===n&&(n=i),s[i][0]<=g&&(r=i);null===n&&(n=0);for(var f=n,_=!0;_&&f>0;)f--,_=null===s[f][1];null===r&&(r=s.length-1);var v=r;for(_=!0;_&&v<s.length-1;)v++,_=null===s[v][1];f!==n&&(n=f),v!==r&&(r=v),l[a-1]=[n,r],s=s.slice(n,r+1)}else s=t[a],l[a-1]=[0,s.length-1];var y=this.attr_("labels")[a],x=this.dataHandler_.getExtremeYValues(s,e,this.getBooleanOption("stepPlot",y)),m=this.dataHandler_.seriesToPoints(s,y,l[a-1][0]);this.getBooleanOption("stackedGraph")&&(o=this.attributes_.axisForSeries(y),void 0===u[o]&&(u[o]=[]),Q.stackPoints_(m,u[o],x,this.getBooleanOption("stackedGraphNaNFill"))),d[y]=x,h[a]=m}return{points:h,extremes:d,boundaryIds:l}},Q.prototype.drawGraph_=function(){var t=new Date,e=this.is_initial_draw_;this.is_initial_draw_=!1,this.layout_.removeAllDatasets(),this.setColors_(),this.attrs_.pointSize=.5*this.getNumericOption("highlightCircleSize");var a=this.gatherDatasets_(this.rolledSeries_,this.dateWindow_),i=a.points,n=a.extremes;this.boundaryIds_=a.boundaryIds,this.setIndexByName_={};for(var r=this.attr_("labels"),o=0,s=1;s<i.length;s++)this.visibility()[s-1]&&(this.layout_.addDataset(r[s],i[s]),this.datasetIndex_[s]=o++);for(var s=0;s<r.length;s++)this.setIndexByName_[r[s]]=s;if(this.computeYAxisRanges_(n),this.layout_.setYAxes(this.axes_),this.addXTicks_(),this.layout_.evaluate(),this.renderGraph_(e),this.getStringOption("timingName")){var l=new Date;console.log(this.getStringOption("timingName")+" - drawGraph: "+(l-t)+"ms")}},Q.prototype.renderGraph_=function(t){this.cascadeEvents_("clearChart"),this.plotter_.clear();var e=this.getFunctionOption("underlayCallback");e&&e.call(this,this.hidden_ctx_,this.layout_.getPlotArea(),this,this);var a={canvas:this.hidden_,drawingContext:this.hidden_ctx_};this.cascadeEvents_("willDrawChart",a),this.plotter_.render(),this.cascadeEvents_("didDrawChart",a),this.lastRow_=-1,this.canvas_.getContext("2d").clearRect(0,0,this.width_,this.height_);var i=this.getFunctionOption("drawCallback");if(null!==i&&i.call(this,this,t),t)for(this.readyFired_=!0;this.readyFns_.length>0;){var n=this.readyFns_.pop();n(this)}},Q.prototype.computeYAxes_=function(){var t,e,a;for(this.axes_=[],t=0;t<this.attributes_.numAxes();t++)e={g:this},x.update(e,this.attributes_.axisOptions(t)),this.axes_[t]=e;for(t=0;t<this.axes_.length;t++)if(0===t)e=this.optionsViewForAxis_("y"+(t?"2":"")),(a=e("valueRange"))&&(this.axes_[t].valueRange=a);else{var i=this.user_attrs_.axes;i&&i.y2&&(a=i.y2.valueRange)&&(this.axes_[t].valueRange=a)}},Q.prototype.numAxes=function(){return this.attributes_.numAxes()},Q.prototype.axisPropertiesForSeries=function(t){return this.axes_[this.attributes_.axisForSeries(t)]},Q.prototype.computeYAxisRanges_=function(t){for(var e,a,i,n,r,o=function(t){return isNaN(parseFloat(t))},s=this.attributes_.numAxes(),l=0;l<s;l++){var h=this.axes_[l],u=this.attributes_.getForAxis("logscale",l),d=this.attributes_.getForAxis("includeZero",l),c=this.attributes_.getForAxis("independentTicks",l);i=this.attributes_.seriesForAxis(l),e=!0,n=.1;var p=this.getNumericOption("yRangePad");if(null!==p&&(e=!1,n=p/this.plotter_.area.h),0===i.length)h.extremeRange=[0,1];else{for(var g,f,_=1/0,v=-1/0,y=0;y<i.length;y++)t.hasOwnProperty(i[y])&&(g=t[i[y]][0],null!==g&&(_=Math.min(g,_)),null!==(f=t[i[y]][1])&&(v=Math.max(f,v)));d&&!u&&(_>0&&(_=0),v<0&&(v=0)),_==1/0&&(_=0),v==-1/0&&(v=1),a=v-_,0===a&&(0!==v?a=Math.abs(v):(v=1,a=1));var m=v,b=_;e&&(u?(m=v+n*a,b=_):(m=v+n*a,b=_-n*a,b<0&&_>=0&&(b=0),m>0&&v<=0&&(m=0))),h.extremeRange=[b,m]}if(h.valueRange){var w=o(h.valueRange[0])?h.extremeRange[0]:h.valueRange[0],A=o(h.valueRange[1])?h.extremeRange[1]:h.valueRange[1];h.computedValueRange=[w,A]}else h.computedValueRange=h.extremeRange;if(!e)if(u){w=h.computedValueRange[0],A=h.computedValueRange[1];var O=n/(2*n-1),D=(n-1)/(2*n-1);h.computedValueRange[0]=x.logRangeFraction(w,A,O),h.computedValueRange[1]=x.logRangeFraction(w,A,D)}else w=h.computedValueRange[0],A=h.computedValueRange[1],a=A-w,h.computedValueRange[0]=w-a*n,h.computedValueRange[1]=A+a*n;if(c){h.independentTicks=c;var E=this.optionsViewForAxis_("y"+(l?"2":"")),L=E("ticker");h.ticks=L(h.computedValueRange[0],h.computedValueRange[1],this.plotter_.area.h,E,this),r||(r=h)}}if(void 0===r)throw'Configuration Error: At least one axis has to have the "independentTicks" option activated.';for(var l=0;l<s;l++){var h=this.axes_[l];if(!h.independentTicks){for(var E=this.optionsViewForAxis_("y"+(l?"2":"")),L=E("ticker"),T=r.ticks,S=r.computedValueRange[1]-r.computedValueRange[0],P=h.computedValueRange[1]-h.computedValueRange[0],C=[],M=0;M<T.length;M++){var N=(T[M].v-r.computedValueRange[0])/S,F=h.computedValueRange[0]+N*P;C.push(F)}h.ticks=L(h.computedValueRange[0],h.computedValueRange[1],this.plotter_.area.h,E,this,C)}}},Q.prototype.detectTypeFromString_=function(t){var e=!1,a=t.indexOf("-");a>0&&"e"!=t[a-1]&&"E"!=t[a-1]||t.indexOf("/")>=0||isNaN(parseFloat(t))?e=!0:8==t.length&&t>"19700101"&&t<"20371231"&&(e=!0),this.setXAxisOptions_(e)},Q.prototype.setXAxisOptions_=function(t){t?(this.attrs_.xValueParser=x.dateParser,this.attrs_.axes.x.valueFormatter=x.dateValueFormatter,this.attrs_.axes.x.ticker=v.dateTicker,this.attrs_.axes.x.axisLabelFormatter=x.dateAxisLabelFormatter):(this.attrs_.xValueParser=function(t){return parseFloat(t)},this.attrs_.axes.x.valueFormatter=function(t){return t},this.attrs_.axes.x.ticker=v.numericTicks,this.attrs_.axes.x.axisLabelFormatter=this.attrs_.axes.x.valueFormatter)},Q.prototype.parseCSV_=function(t){var e,a,i=[],n=x.detectLineDelimiter(t),r=t.split(n||"\n"),o=this.getStringOption("delimiter");-1==r[0].indexOf(o)&&r[0].indexOf("\t")>=0&&(o="\t");var s=0;"labels"in this.user_attrs_||(s=1,this.attrs_.labels=r[0].split(o),this.attributes_.reparseSeries());for(var l,h=!1,u=this.attr_("labels").length,d=!1,c=s;c<r.length;c++){var p=r[c];if(c,0!==p.length&&"#"!=p[0]){var g=p.split(o);if(!(g.length<2)){var f=[];if(h||(this.detectTypeFromString_(g[0]),l=this.getFunctionOption("xValueParser"),h=!0),f[0]=l(g[0],this),this.fractions_)for(a=1;a<g.length;a++)e=g[a].split("/"),2!=e.length?(console.error('Expected fractional "num/den" values in CSV data but found a value \''+g[a]+"' on line "+(1+c)+" ('"+p+"') which is not of this form."),f[a]=[0,0]):f[a]=[x.parseFloat_(e[0],c,p),x.parseFloat_(e[1],c,p)];else if(this.getBooleanOption("errorBars"))for(g.length%2!=1&&console.error("Expected alternating (value, stdev.) pairs in CSV data but line "+(1+c)+" has an odd number of values ("+(g.length-1)+"): '"+p+"'"),a=1;a<g.length;a+=2)f[(a+1)/2]=[x.parseFloat_(g[a],c,p),x.parseFloat_(g[a+1],c,p)];else if(this.getBooleanOption("customBars"))for(a=1;a<g.length;a++){var _=g[a];/^ *$/.test(_)?f[a]=[null,null,null]:(e=_.split(";"),3==e.length?f[a]=[x.parseFloat_(e[0],c,p),x.parseFloat_(e[1],c,p),x.parseFloat_(e[2],c,p)]:console.warn('When using customBars, values must be either blank or "low;center;high" tuples (got "'+_+'" on line '+(1+c)))}else for(a=1;a<g.length;a++)f[a]=x.parseFloat_(g[a],c,p);if(i.length>0&&f[0]<i[i.length-1][0]&&(d=!0),f.length!=u&&console.error("Number of columns in line "+c+" ("+f.length+") does not agree with number of labels ("+u+") "+p),0===c&&this.attr_("labels")){var v=!0;for(a=0;v&&a<f.length;a++)f[a]&&(v=!1);if(v){console.warn("The dygraphs 'labels' option is set, but the first row of CSV data ('"+p+"') appears to also contain labels. Will drop the CSV labels and use the option labels.");continue}}i.push(f)}}}return d&&(console.warn("CSV is out of order; order it correctly to speed loading."),i.sort(function(t,e){return t[0]-e[0]})),i},Q.prototype.parseArray_=function(t){if(0===t.length)return console.error("Can't plot empty data set"),null;if(0===t[0].length)return console.error("Data set cannot contain an empty row"),null;o(t);var e;if(null===this.attr_("labels")){for(console.warn("Using default labels. Set labels explicitly via 'labels' in the options parameter"),this.attrs_.labels=["X"],e=1;e<t[0].length;e++)this.attrs_.labels.push("Y"+e);this.attributes_.reparseSeries()}else{var a=this.attr_("labels");if(a.length!=t[0].length)return console.error("Mismatch between number of labels ("+a+") and number of columns in array ("+t[0].length+")"),null}if(x.isDateLike(t[0][0])){this.attrs_.axes.x.valueFormatter=x.dateValueFormatter,this.attrs_.axes.x.ticker=v.dateTicker,this.attrs_.axes.x.axisLabelFormatter=x.dateAxisLabelFormatter;var i=x.clone(t);for(e=0;e<t.length;e++){if(0===i[e].length)return console.error("Row "+(1+e)+" of data is empty"),null;if(null===i[e][0]||"function"!=typeof i[e][0].getTime||isNaN(i[e][0].getTime()))return console.error("x value in row "+(1+e)+" is not a Date"),null;i[e][0]=i[e][0].getTime()}return i}return this.attrs_.axes.x.valueFormatter=function(t){return t},this.attrs_.axes.x.ticker=v.numericTicks,this.attrs_.axes.x.axisLabelFormatter=x.numberAxisLabelFormatter,t},Q.prototype.parseDataTable_=function(t){var e=t.getNumberOfColumns(),a=t.getNumberOfRows(),i=t.getColumnType(0);if("date"==i||"datetime"==i)this.attrs_.xValueParser=x.dateParser,this.attrs_.axes.x.valueFormatter=x.dateValueFormatter,this.attrs_.axes.x.ticker=v.dateTicker,this.attrs_.axes.x.axisLabelFormatter=x.dateAxisLabelFormatter;else{if("number"!=i)throw new Error("only 'date', 'datetime' and 'number' types are supported for column 1 of DataTable input (Got '"+i+"')");this.attrs_.xValueParser=function(t){return parseFloat(t)},this.attrs_.axes.x.valueFormatter=function(t){return t},this.attrs_.axes.x.ticker=v.numericTicks,this.attrs_.axes.x.axisLabelFormatter=this.attrs_.axes.x.valueFormatter}var n,r,o=[],s={},l=!1;for(n=1;n<e;n++){var h=t.getColumnType(n);if("number"==h)o.push(n);else{if("string"!=h||!this.getBooleanOption("displayAnnotations"))throw new Error("Only 'number' is supported as a dependent type with Gviz. 'string' is only supported if displayAnnotations is true");var u=o[o.length-1];s.hasOwnProperty(u)?s[u].push(n):s[u]=[n],l=!0}}var d=[t.getColumnLabel(0)];for(n=0;n<o.length;n++)d.push(t.getColumnLabel(o[n])),this.getBooleanOption("errorBars")&&(n+=1);this.attrs_.labels=d,e=d.length;var c=[],p=!1,g=[];for(n=0;n<a;n++){var f=[];if(void 0!==t.getValue(n,0)&&null!==t.getValue(n,0)){if("date"==i||"datetime"==i?f.push(t.getValue(n,0).getTime()):f.push(t.getValue(n,0)),this.getBooleanOption("errorBars"))for(r=0;r<e-1;r++)f.push([t.getValue(n,1+2*r),t.getValue(n,2+2*r)]);else{for(r=0;r<o.length;r++){var _=o[r];if(f.push(t.getValue(n,_)),l&&s.hasOwnProperty(_)&&null!==t.getValue(n,s[_][0])){var y={};y.series=t.getColumnLabel(_),y.xval=f[0],y.shortText=function(t){var e=String.fromCharCode(65+t%26);for(t=Math.floor(t/26);t>0;)e=String.fromCharCode(65+(t-1)%26)+e.toLowerCase(),t=Math.floor((t-1)/26);return e}(g.length),y.text="";for(var m=0;m<s[_].length;m++)m&&(y.text+="\n"),y.text+=t.getValue(n,s[_][m]);g.push(y)}}for(r=0;r<f.length;r++)isFinite(f[r])||(f[r]=null)}c.length>0&&f[0]<c[c.length-1][0]&&(p=!0),c.push(f)}else console.warn("Ignoring row "+n+" of DataTable because of undefined or null first column.")}p&&(console.warn("DataTable is out of order; order it correctly to speed loading."),c.sort(function(t,e){return t[0]-e[0]})),this.rawData_=c,g.length>0&&this.setAnnotations(g,!0),this.attributes_.reparseSeries()},Q.prototype.cascadeDataDidUpdateEvent_=function(){this.cascadeEvents_("dataDidUpdate",{})},Q.prototype.start_=function(){var t=this.file_;if("function"==typeof t&&(t=t()),x.isArrayLike(t))this.rawData_=this.parseArray_(t),this.cascadeDataDidUpdateEvent_(),this.predraw_();else if("object"==typeof t&&"function"==typeof t.getColumnRange)this.parseDataTable_(t),this.cascadeDataDidUpdateEvent_(),this.predraw_();else if("string"==typeof t){var e=x.detectLineDelimiter(t);if(e)this.loadedEvent_(t);else{var a;a=window.XMLHttpRequest?new XMLHttpRequest:new ActiveXObject("Microsoft.XMLHTTP");var i=this;a.onreadystatechange=function(){4==a.readyState&&(200!==a.status&&0!==a.status||i.loadedEvent_(a.responseText))},a.open("GET",t,!0),a.send(null)}}else console.error("Unknown data format: "+typeof t)},Q.prototype.updateOptions=function(t,e){void 0===e&&(e=!1);var a=t.file,i=Q.copyUserAttrs_(t);"rollPeriod"in i&&(this.rollPeriod_=i.rollPeriod),"dateWindow"in i&&(this.dateWindow_=i.dateWindow);var n=x.isPixelChangingOptionList(this.attr_("labels"),i);x.updateDeep(this.user_attrs_,i),this.attributes_.reparseSeries(),a?(this.cascadeEvents_("dataWillUpdate",{}),this.file_=a,e||this.start_()):e||(n?this.predraw_():this.renderGraph_(!1))},Q.copyUserAttrs_=function(t){var e={};for(var a in t)t.hasOwnProperty(a)&&"file"!=a&&t.hasOwnProperty(a)&&(e[a]=t[a]);return e},Q.prototype.resize=function(t,e){if(!this.resize_lock){this.resize_lock=!0,null===t!=(null===e)&&(console.warn("Dygraph.resize() should be called with zero parameters or two non-NULL parameters. Pretending it was zero."),t=e=null);var a=this.width_,i=this.height_;t?(this.maindiv_.style.width=t+"px",this.maindiv_.style.height=e+"px",this.width_=t,this.height_=e):(this.width_=this.maindiv_.clientWidth,this.height_=this.maindiv_.clientHeight),a==this.width_&&i==this.height_||(this.resizeElements_(),this.predraw_()),this.resize_lock=!1}},Q.prototype.adjustRoll=function(t){this.rollPeriod_=t,this.predraw_()},Q.prototype.visibility=function(){for(this.getOption("visibility")||(this.attrs_.visibility=[]);this.getOption("visibility").length<this.numColumns()-1;)this.attrs_.visibility.push(!0);return this.getOption("visibility")},Q.prototype.setVisibility=function(t,e){var a=this.visibility(),i=!1;if(Array.isArray(t)||(null!==t&&"object"==typeof t?i=!0:t=[t]),i)for(var n in t)t.hasOwnProperty(n)&&(n<0||n>=a.length?console.warn("Invalid series number in setVisibility: "+n):a[n]=t[n]);else for(var n=0;n<t.length;n++)"boolean"==typeof t[n]?n>=a.length?console.warn("Invalid series number in setVisibility: "+n):a[n]=t[n]:t[n]<0||t[n]>=a.length?console.warn("Invalid series number in setVisibility: "+t[n]):a[t[n]]=e;this.predraw_()},Q.prototype.size=function(){return{width:this.width_,height:this.height_}},Q.prototype.setAnnotations=function(t,e){if(this.annotations_=t,!this.layout_)return void console.warn("Tried to setAnnotations before dygraph was ready. Try setting them in a ready() block. See dygraphs.com/tests/annotation.html");this.layout_.setAnnotations(this.annotations_),e||this.predraw_()},Q.prototype.annotations=function(){return this.annotations_},Q.prototype.getLabels=function(){var t=this.attr_("labels");return t?t.slice():null},Q.prototype.indexFromSetName=function(t){return this.setIndexByName_[t]},Q.prototype.getRowForX=function(t){for(var e=0,a=this.numRows()-1;e<=a;){var i=a+e>>1,n=this.getValue(i,0);if(n<t)e=i+1;else if(n>t)a=i-1;else{if(e==i)return i;a=i}}return null},Q.prototype.ready=function(t){this.is_initial_draw_?this.readyFns_.push(t):t.call(this,this)},Q.prototype.addAndTrackEvent=function(t,e,a){x.addEvent(t,e,a),this.registeredEvents_.push({elem:t,type:e,fn:a})},Q.prototype.removeTrackedEvents_=function(){if(this.registeredEvents_)for(var t=0;t<this.registeredEvents_.length;t++){var e=this.registeredEvents_[t];x.removeEvent(e.elem,e.type,e.fn)}this.registeredEvents_=[]},Q.PLUGINS=[U.default,X.default,j.default,Z.default,H.default,G.default],Q.GVizChart=q.default,Q.DASHED_LINE=x.DASHED_LINE,Q.DOT_DASH_LINE=x.DOT_DASH_LINE,Q.dateAxisLabelFormatter=x.dateAxisLabelFormatter,Q.toRGB_=x.toRGB_,Q.findPos=x.findPos,Q.pageX=x.pageX,Q.pageY=x.pageY,Q.dateString_=x.dateString_,Q.defaultInteractionModel=f.default.defaultModel,Q.nonInteractiveModel=Q.nonInteractiveModel_=f.default.nonInteractiveModel_,Q.Circles=x.Circles,Q.Plugins={Legend:U.default,Axes:X.default,Annotations:H.default,ChartLabels:Z.default,Grid:G.default,RangeSelector:j.default},Q.DataHandlers={DefaultHandler:E.default,BarsHandler:R.default,CustomBarsHandler:P.default,DefaultFractionHandler:M.default,ErrorBarsHandler:T.default,FractionsBarsHandler:F.default},Q.startPan=f.default.startPan,Q.startZoom=f.default.startZoom,Q.movePan=f.default.movePan,Q.moveZoom=f.default.moveZoom,Q.endPan=f.default.endPan,Q.endZoom=f.default.endZoom,Q.numericLinearTicks=v.numericLinearTicks,Q.numericTicks=v.numericTicks,Q.dateTicker=v.dateTicker,Q.Granularity=v.Granularity,Q.getDateAxis=v.getDateAxis,Q.floatFormat=x.floatFormat,a.default=Q,e.exports=a.default}).call(this,t("_process"))},{"./datahandler/bars":5,"./datahandler/bars-custom":2,"./datahandler/bars-error":3,"./datahandler/bars-fractions":4,"./datahandler/default":8,"./datahandler/default-fractions":7,"./dygraph-canvas":9,"./dygraph-default-attrs":10,"./dygraph-gviz":11,"./dygraph-interaction-model":12,"./dygraph-layout":13,"./dygraph-options":15,"./dygraph-options-reference":14,"./dygraph-tickers":16,"./dygraph-utils":17,"./iframe-tarp":19,"./plugins/annotations":20,"./plugins/axes":21,"./plugins/chart-labels":22,"./plugins/grid":23,"./plugins/legend":24,"./plugins/range-selector":25,_process:1}],19:[function(t,e,a){"use strict";function i(){this.tarps=[]}Object.defineProperty(a,"__esModule",{value:!0});var n=t("./dygraph-utils"),r=function(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var a in t)Object.prototype.hasOwnProperty.call(t,a)&&(e[a]=t[a]);return e.default=t,e}(n);i.prototype.cover=function(){for(var t=document.getElementsByTagName("iframe"),e=0;e<t.length;e++){var a=t[e],i=r.findPos(a),n=i.x,o=i.y,s=a.offsetWidth,l=a.offsetHeight,h=document.createElement("div");h.style.position="absolute",h.style.left=n+"px",h.style.top=o+"px",h.style.width=s+"px",h.style.height=l+"px",h.style.zIndex=999,document.body.appendChild(h),this.tarps.push(h)}},i.prototype.uncover=function(){for(var t=0;t<this.tarps.length;t++)this.tarps[t].parentNode.removeChild(this.tarps[t]);this.tarps=[]},a.default=i,e.exports=a.default},{"./dygraph-utils":17}],20:[function(t,e,a){"use strict";Object.defineProperty(a,"__esModule",{value:!0});var i=function(){this.annotations_=[]};i.prototype.toString=function(){return"Annotations Plugin"},i.prototype.activate=function(t){return{clearChart:this.clearChart,didDrawChart:this.didDrawChart}},i.prototype.detachLabels=function(){for(var t=0;t<this.annotations_.length;t++){var e=this.annotations_[t];e.parentNode&&e.parentNode.removeChild(e),this.annotations_[t]=null}this.annotations_=[]},i.prototype.clearChart=function(t){this.detachLabels()},i.prototype.didDrawChart=function(t){var e=t.dygraph,a=e.layout_.annotated_points;if(a&&0!==a.length)for(var i=t.canvas.parentNode,n=function(t,a,i){return function(n){var r=i.annotation;r.hasOwnProperty(t)?r[t](r,i,e,n):e.getOption(a)&&e.getOption(a)(r,i,e,n)}},r=t.dygraph.getArea(),o={},s=0;s<a.length;s++){var l=a[s];if(!(l.canvasx<r.x||l.canvasx>r.x+r.w||l.canvasy<r.y||l.canvasy>r.y+r.h)){var h=l.annotation,u=6;h.hasOwnProperty("tickHeight")&&(u=h.tickHeight);var d=document.createElement("div")
+;d.style.fontSize=e.getOption("axisLabelFontSize")+"px";var c="dygraph-annotation";h.hasOwnProperty("icon")||(c+=" dygraphDefaultAnnotation dygraph-default-annotation"),h.hasOwnProperty("cssClass")&&(c+=" "+h.cssClass),d.className=c;var p=h.hasOwnProperty("width")?h.width:16,g=h.hasOwnProperty("height")?h.height:16;if(h.hasOwnProperty("icon")){var f=document.createElement("img");f.src=h.icon,f.width=p,f.height=g,d.appendChild(f)}else l.annotation.hasOwnProperty("shortText")&&d.appendChild(document.createTextNode(l.annotation.shortText));var _=l.canvasx-p/2;d.style.left=_+"px";var v=0;if(h.attachAtBottom){var y=r.y+r.h-g-u;o[_]?y-=o[_]:o[_]=0,o[_]+=u+g,v=y}else v=l.canvasy-g-u;d.style.top=v+"px",d.style.width=p+"px",d.style.height=g+"px",d.title=l.annotation.text,d.style.color=e.colorsMap_[l.name],d.style.borderColor=e.colorsMap_[l.name],h.div=d,e.addAndTrackEvent(d,"click",n("clickHandler","annotationClickHandler",l)),e.addAndTrackEvent(d,"mouseover",n("mouseOverHandler","annotationMouseOverHandler",l)),e.addAndTrackEvent(d,"mouseout",n("mouseOutHandler","annotationMouseOutHandler",l)),e.addAndTrackEvent(d,"dblclick",n("dblClickHandler","annotationDblClickHandler",l)),i.appendChild(d),this.annotations_.push(d);var x=t.drawingContext;if(x.save(),x.strokeStyle=h.hasOwnProperty("tickColor")?h.tickColor:e.colorsMap_[l.name],x.lineWidth=h.hasOwnProperty("tickWidth")?h.tickWidth:e.getOption("strokeWidth"),x.beginPath(),h.attachAtBottom){var y=v+g;x.moveTo(l.canvasx,y),x.lineTo(l.canvasx,y+u)}else x.moveTo(l.canvasx,l.canvasy),x.lineTo(l.canvasx,l.canvasy-2-u);x.closePath(),x.stroke(),x.restore()}}},i.prototype.destroy=function(){this.detachLabels()},a.default=i,e.exports=a.default},{}],21:[function(t,e,a){"use strict";Object.defineProperty(a,"__esModule",{value:!0});var i=t("../dygraph-utils"),n=function(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var a in t)Object.prototype.hasOwnProperty.call(t,a)&&(e[a]=t[a]);return e.default=t,e}(i),r=function(){this.xlabels_=[],this.ylabels_=[]};r.prototype.toString=function(){return"Axes Plugin"},r.prototype.activate=function(t){return{layout:this.layout,clearChart:this.clearChart,willDrawChart:this.willDrawChart}},r.prototype.layout=function(t){var e=t.dygraph;if(e.getOptionForAxis("drawAxis","y")){var a=e.getOptionForAxis("axisLabelWidth","y")+2*e.getOptionForAxis("axisTickSize","y");t.reserveSpaceLeft(a)}if(e.getOptionForAxis("drawAxis","x")){var i;i=e.getOption("xAxisHeight")?e.getOption("xAxisHeight"):e.getOptionForAxis("axisLabelFontSize","x")+2*e.getOptionForAxis("axisTickSize","x"),t.reserveSpaceBottom(i)}if(2==e.numAxes()){if(e.getOptionForAxis("drawAxis","y2")){var a=e.getOptionForAxis("axisLabelWidth","y2")+2*e.getOptionForAxis("axisTickSize","y2");t.reserveSpaceRight(a)}}else e.numAxes()>2&&e.error("Only two y-axes are supported at this time. (Trying to use "+e.numAxes()+")")},r.prototype.detachLabels=function(){function t(t){for(var e=0;e<t.length;e++){var a=t[e];a.parentNode&&a.parentNode.removeChild(a)}}t(this.xlabels_),t(this.ylabels_),this.xlabels_=[],this.ylabels_=[]},r.prototype.clearChart=function(t){this.detachLabels()},r.prototype.willDrawChart=function(t){function e(t){return Math.round(t)+.5}function a(t){return Math.round(t)-.5}var i=this,r=t.dygraph;if(r.getOptionForAxis("drawAxis","x")||r.getOptionForAxis("drawAxis","y")||r.getOptionForAxis("drawAxis","y2")){var o,s,l,h=t.drawingContext,u=t.canvas.parentNode,d=r.width_,c=r.height_,p=function(t){return{position:"absolute",fontSize:r.getOptionForAxis("axisLabelFontSize",t)+"px",width:r.getOptionForAxis("axisLabelWidth",t)+"px"}},g={x:p("x"),y:p("y"),y2:p("y2")},f=function(t,e,a){var i=document.createElement("div"),r=g["y2"==a?"y2":e];n.update(i.style,r);var o=document.createElement("div");return o.className="dygraph-axis-label dygraph-axis-label-"+e+(a?" dygraph-axis-label-"+a:""),o.innerHTML=t,i.appendChild(o),i};h.save();var _=r.layout_,v=t.dygraph.plotter_.area,y=function(t){return function(e){return r.getOptionForAxis(e,t)}};if(r.getOptionForAxis("drawAxis","y")){if(_.yticks&&_.yticks.length>0){var x=r.numAxes(),m=[y("y"),y("y2")];_.yticks.forEach(function(t){if(void 0!==t.label){s=v.x;var e="y1",a=m[0];1==t.axis&&(s=v.x+v.w,-1,e="y2",a=m[1]);var n=a("axisLabelFontSize");l=v.y+t.pos*v.h,o=f(t.label,"y",2==x?e:null);var r=l-n/2;r<0&&(r=0),r+n+3>c?o.style.bottom="0":o.style.top=r+"px",0===t.axis?(o.style.left=v.x-a("axisLabelWidth")-a("axisTickSize")+"px",o.style.textAlign="right"):1==t.axis&&(o.style.left=v.x+v.w+a("axisTickSize")+"px",o.style.textAlign="left"),o.style.width=a("axisLabelWidth")+"px",u.appendChild(o),i.ylabels_.push(o)}});var b=this.ylabels_[0],w=r.getOptionForAxis("axisLabelFontSize","y");parseInt(b.style.top,10)+w>c-w&&(b.style.top=parseInt(b.style.top,10)-w/2+"px")}var A;if(r.getOption("drawAxesAtZero")){var O=r.toPercentXCoord(0);(O>1||O<0||isNaN(O))&&(O=0),A=e(v.x+O*v.w)}else A=e(v.x);h.strokeStyle=r.getOptionForAxis("axisLineColor","y"),h.lineWidth=r.getOptionForAxis("axisLineWidth","y"),h.beginPath(),h.moveTo(A,a(v.y)),h.lineTo(A,a(v.y+v.h)),h.closePath(),h.stroke(),2==r.numAxes()&&(h.strokeStyle=r.getOptionForAxis("axisLineColor","y2"),h.lineWidth=r.getOptionForAxis("axisLineWidth","y2"),h.beginPath(),h.moveTo(a(v.x+v.w),a(v.y)),h.lineTo(a(v.x+v.w),a(v.y+v.h)),h.closePath(),h.stroke())}if(r.getOptionForAxis("drawAxis","x")){if(_.xticks){var D=y("x");_.xticks.forEach(function(t){if(void 0!==t.label){s=v.x+t.pos*v.w,l=v.y+v.h,o=f(t.label,"x"),o.style.textAlign="center",o.style.top=l+D("axisTickSize")+"px";var e=s-D("axisLabelWidth")/2;e+D("axisLabelWidth")>d&&(e=d-D("axisLabelWidth"),o.style.textAlign="right"),e<0&&(e=0,o.style.textAlign="left"),o.style.left=e+"px",o.style.width=D("axisLabelWidth")+"px",u.appendChild(o),i.xlabels_.push(o)}})}h.strokeStyle=r.getOptionForAxis("axisLineColor","x"),h.lineWidth=r.getOptionForAxis("axisLineWidth","x"),h.beginPath();var E;if(r.getOption("drawAxesAtZero")){var O=r.toPercentYCoord(0,0);(O>1||O<0)&&(O=1),E=a(v.y+O*v.h)}else E=a(v.y+v.h);h.moveTo(e(v.x),E),h.lineTo(e(v.x+v.w),E),h.closePath(),h.stroke()}h.restore()}},a.default=r,e.exports=a.default},{"../dygraph-utils":17}],22:[function(t,e,a){"use strict";Object.defineProperty(a,"__esModule",{value:!0});var i=function(){this.title_div_=null,this.xlabel_div_=null,this.ylabel_div_=null,this.y2label_div_=null};i.prototype.toString=function(){return"ChartLabels Plugin"},i.prototype.activate=function(t){return{layout:this.layout,didDrawChart:this.didDrawChart}};var n=function(t){var e=document.createElement("div");return e.style.position="absolute",e.style.left=t.x+"px",e.style.top=t.y+"px",e.style.width=t.w+"px",e.style.height=t.h+"px",e};i.prototype.detachLabels_=function(){for(var t=[this.title_div_,this.xlabel_div_,this.ylabel_div_,this.y2label_div_],e=0;e<t.length;e++){var a=t[e];a&&(a.parentNode&&a.parentNode.removeChild(a))}this.title_div_=null,this.xlabel_div_=null,this.ylabel_div_=null,this.y2label_div_=null};var r=function(t,e,a,i,n){var r=document.createElement("div");r.style.position="absolute",r.style.left=1==a?"0px":e.x+"px",r.style.top=e.y+"px",r.style.width=e.w+"px",r.style.height=e.h+"px",r.style.fontSize=t.getOption("yLabelWidth")-2+"px";var o=document.createElement("div");o.style.position="absolute",o.style.width=e.h+"px",o.style.height=e.w+"px",o.style.top=e.h/2-e.w/2+"px",o.style.left=e.w/2-e.h/2+"px",o.className="dygraph-label-rotate-"+(1==a?"right":"left");var s=document.createElement("div");return s.className=i,s.innerHTML=n,o.appendChild(s),r.appendChild(o),r};i.prototype.layout=function(t){this.detachLabels_();var e=t.dygraph,a=t.chart_div;if(e.getOption("title")){var i=t.reserveSpaceTop(e.getOption("titleHeight"));this.title_div_=n(i),this.title_div_.style.fontSize=e.getOption("titleHeight")-8+"px";var o=document.createElement("div");o.className="dygraph-label dygraph-title",o.innerHTML=e.getOption("title"),this.title_div_.appendChild(o),a.appendChild(this.title_div_)}if(e.getOption("xlabel")){var s=t.reserveSpaceBottom(e.getOption("xLabelHeight"));this.xlabel_div_=n(s),this.xlabel_div_.style.fontSize=e.getOption("xLabelHeight")-2+"px";var o=document.createElement("div");o.className="dygraph-label dygraph-xlabel",o.innerHTML=e.getOption("xlabel"),this.xlabel_div_.appendChild(o),a.appendChild(this.xlabel_div_)}if(e.getOption("ylabel")){var l=t.reserveSpaceLeft(0);this.ylabel_div_=r(e,l,1,"dygraph-label dygraph-ylabel",e.getOption("ylabel")),a.appendChild(this.ylabel_div_)}if(e.getOption("y2label")&&2==e.numAxes()){var h=t.reserveSpaceRight(0);this.y2label_div_=r(e,h,2,"dygraph-label dygraph-y2label",e.getOption("y2label")),a.appendChild(this.y2label_div_)}},i.prototype.didDrawChart=function(t){var e=t.dygraph;this.title_div_&&(this.title_div_.children[0].innerHTML=e.getOption("title")),this.xlabel_div_&&(this.xlabel_div_.children[0].innerHTML=e.getOption("xlabel")),this.ylabel_div_&&(this.ylabel_div_.children[0].children[0].innerHTML=e.getOption("ylabel")),this.y2label_div_&&(this.y2label_div_.children[0].children[0].innerHTML=e.getOption("y2label"))},i.prototype.clearChart=function(){},i.prototype.destroy=function(){this.detachLabels_()},a.default=i,e.exports=a.default},{}],23:[function(t,e,a){"use strict";Object.defineProperty(a,"__esModule",{value:!0});var i=function(){};i.prototype.toString=function(){return"Gridline Plugin"},i.prototype.activate=function(t){return{willDrawChart:this.willDrawChart}},i.prototype.willDrawChart=function(t){function e(t){return Math.round(t)+.5}function a(t){return Math.round(t)-.5}var i,n,r,o,s=t.dygraph,l=t.drawingContext,h=s.layout_,u=t.dygraph.plotter_.area;if(s.getOptionForAxis("drawGrid","y")){for(var d=["y","y2"],c=[],p=[],g=[],f=[],_=[],r=0;r<d.length;r++)g[r]=s.getOptionForAxis("drawGrid",d[r]),g[r]&&(c[r]=s.getOptionForAxis("gridLineColor",d[r]),p[r]=s.getOptionForAxis("gridLineWidth",d[r]),_[r]=s.getOptionForAxis("gridLinePattern",d[r]),f[r]=_[r]&&_[r].length>=2);o=h.yticks,l.save(),o.forEach(function(t){if(t.has_tick){var r=t.axis;g[r]&&(l.save(),f[r]&&l.setLineDash&&l.setLineDash(_[r]),l.strokeStyle=c[r],l.lineWidth=p[r],i=e(u.x),n=a(u.y+t.pos*u.h),l.beginPath(),l.moveTo(i,n),l.lineTo(i+u.w,n),l.stroke(),l.restore())}}),l.restore()}if(s.getOptionForAxis("drawGrid","x")){o=h.xticks,l.save();var _=s.getOptionForAxis("gridLinePattern","x"),f=_&&_.length>=2;f&&l.setLineDash&&l.setLineDash(_),l.strokeStyle=s.getOptionForAxis("gridLineColor","x"),l.lineWidth=s.getOptionForAxis("gridLineWidth","x"),o.forEach(function(t){t.has_tick&&(i=e(u.x+t.pos*u.w),n=a(u.y+u.h),l.beginPath(),l.moveTo(i,n),l.lineTo(i,u.y),l.closePath(),l.stroke())}),f&&l.setLineDash&&l.setLineDash([]),l.restore()}},i.prototype.destroy=function(){},a.default=i,e.exports=a.default},{}],24:[function(t,e,a){"use strict";function i(t,e,a){if(!t||t.length<=1)return'<div class="dygraph-legend-line" style="border-bottom-color: '+e+';"></div>';var i,n,r,o,s,l=0,h=0,u=[];for(i=0;i<=t.length;i++)l+=t[i%t.length];if((s=Math.floor(a/(l-t[0])))>1){for(i=0;i<t.length;i++)u[i]=t[i]/a;h=u.length}else{for(s=1,i=0;i<t.length;i++)u[i]=t[i]/l;h=u.length+1}var d="";for(n=0;n<s;n++)for(i=0;i<h;i+=2)r=u[i%u.length],o=i<t.length?u[(i+1)%u.length]:0,d+='<div class="dygraph-legend-dash" style="margin-right: '+o+"em; padding-left: "+r+'em;"></div>';return d}Object.defineProperty(a,"__esModule",{value:!0});var n=t("../dygraph-utils"),r=function(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var a in t)Object.prototype.hasOwnProperty.call(t,a)&&(e[a]=t[a]);return e.default=t,e}(n),o=function(){this.legend_div_=null,this.is_generated_div_=!1};o.prototype.toString=function(){return"Legend Plugin"},o.prototype.activate=function(t){var e,a=t.getOption("labelsDiv");return a&&null!==a?e="string"==typeof a||a instanceof String?document.getElementById(a):a:(e=document.createElement("div"),e.className="dygraph-legend",t.graphDiv.appendChild(e),this.is_generated_div_=!0),this.legend_div_=e,this.one_em_width_=10,{select:this.select,deselect:this.deselect,predraw:this.predraw,didDrawChart:this.didDrawChart}};var s=function(t){var e=document.createElement("span");e.setAttribute("style","margin: 0; padding: 0 0 0 1em; border: 0;"),t.appendChild(e);var a=e.offsetWidth;return t.removeChild(e),a},l=function(t){return t.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;")};o.prototype.select=function(t){var e=t.selectedX,a=t.selectedPoints,i=t.selectedRow,n=t.dygraph.getOption("legend");if("never"===n)return void(this.legend_div_.style.display="none");if("follow"===n){var r=t.dygraph.plotter_.area,s=this.legend_div_.offsetWidth,l=t.dygraph.getOptionForAxis("axisLabelWidth","y"),h=a[0].x*r.w+50,u=a[0].y*r.h-50;h+s+1>r.w&&(h=h-100-s-(l-r.x)),t.dygraph.graphDiv.appendChild(this.legend_div_),this.legend_div_.style.left=l+h+"px",this.legend_div_.style.top=u+"px"}var d=o.generateLegendHTML(t.dygraph,e,a,this.one_em_width_,i);this.legend_div_.innerHTML=d,this.legend_div_.style.display=""},o.prototype.deselect=function(t){"always"!==t.dygraph.getOption("legend")&&(this.legend_div_.style.display="none");var e=s(this.legend_div_);this.one_em_width_=e;var a=o.generateLegendHTML(t.dygraph,void 0,void 0,e,null);this.legend_div_.innerHTML=a},o.prototype.didDrawChart=function(t){this.deselect(t)},o.prototype.predraw=function(t){if(this.is_generated_div_){t.dygraph.graphDiv.appendChild(this.legend_div_);var e=t.dygraph.getArea(),a=this.legend_div_.offsetWidth;this.legend_div_.style.left=e.x+e.w-a-1+"px",this.legend_div_.style.top=e.y+"px"}},o.prototype.destroy=function(){this.legend_div_=null},o.generateLegendHTML=function(t,e,a,n,s){var h={dygraph:t,x:e,series:[]},u={},d=t.getLabels();if(d)for(var c=1;c<d.length;c++){var p=t.getPropertiesForSeries(d[c]),g=t.getOption("strokePattern",d[c]),f={dashHTML:i(g,p.color,n),label:d[c],labelHTML:l(d[c]),isVisible:p.visible,color:p.color};h.series.push(f),u[d[c]]=f}if(void 0!==e){var _=t.optionsViewForAxis_("x"),v=_("valueFormatter");h.xHTML=v.call(t,e,_,d[0],t,s,0);for(var y=[],x=t.numAxes(),c=0;c<x;c++)y[c]=t.optionsViewForAxis_("y"+(c?1+c:""));var m=t.getOption("labelsShowZeroValues"),b=t.getHighlightSeries();for(c=0;c<a.length;c++){var w=a[c],f=u[w.name];if(f.y=w.yval,0===w.yval&&!m||isNaN(w.canvasy))f.isVisible=!1;else{var p=t.getPropertiesForSeries(w.name),A=y[p.axis-1],O=A("valueFormatter"),D=O.call(t,w.yval,A,w.name,t,s,d.indexOf(w.name));r.update(f,{yHTML:D}),w.name==b&&(f.isHighlighted=!0)}}}return(t.getOption("legendFormatter")||o.defaultFormatter).call(t,h)},o.defaultFormatter=function(t){var e=t.dygraph;if(!0!==e.getOption("showLabelsOnHighlight"))return"";var a,i=e.getOption("labelsSeparateLines");if(void 0===t.x){if("always"!=e.getOption("legend"))return"";a="";for(var n=0;n<t.series.length;n++){var r=t.series[n];r.isVisible&&(""!==a&&(a+=i?"<br/>":" "),a+="<span style='font-weight: bold; color: "+r.color+";'>"+r.dashHTML+" "+r.labelHTML+"</span>")}return a}a=t.xHTML+":";for(var n=0;n<t.series.length;n++){var r=t.series[n];if(r.isVisible){i&&(a+="<br>");a+="<span"+(r.isHighlighted?' class="highlight"':"")+"> <b><span style='color: "+r.color+";'>"+r.labelHTML+"</span></b>:&#160;"+r.yHTML+"</span>"}}return a},a.default=o,e.exports=a.default},{"../dygraph-utils":17}],25:[function(t,e,a){"use strict";function i(t){return t&&t.__esModule?t:{default:t}}Object.defineProperty(a,"__esModule",{value:!0});var n=t("../dygraph-utils"),r=function(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var a in t)Object.prototype.hasOwnProperty.call(t,a)&&(e[a]=t[a]);return e.default=t,e}(n),o=t("../dygraph-interaction-model"),s=i(o),l=t("../iframe-tarp"),h=i(l),u=function(){this.hasTouchInterface_="undefined"!=typeof TouchEvent,this.isMobileDevice_=/mobile|android/gi.test(navigator.appVersion),this.interfaceCreated_=!1};u.prototype.toString=function(){return"RangeSelector Plugin"},u.prototype.activate=function(t){return this.dygraph_=t,this.getOption_("showRangeSelector")&&this.createInterface_(),{layout:this.reserveSpace_,predraw:this.renderStaticLayer_,didDrawChart:this.renderInteractiveLayer_}},u.prototype.destroy=function(){this.bgcanvas_=null,this.fgcanvas_=null,this.leftZoomHandle_=null,this.rightZoomHandle_=null},u.prototype.getOption_=function(t,e){return this.dygraph_.getOption(t,e)},u.prototype.setDefaultOption_=function(t,e){this.dygraph_.attrs_[t]=e},u.prototype.createInterface_=function(){this.createCanvases_(),this.createZoomHandles_(),this.initInteraction_(),this.getOption_("animatedZooms")&&(console.warn("Animated zooms and range selector are not compatible; disabling animatedZooms."),this.dygraph_.updateOptions({animatedZooms:!1},!0)),this.interfaceCreated_=!0,this.addToGraph_()},u.prototype.addToGraph_=function(){var t=this.graphDiv_=this.dygraph_.graphDiv;t.appendChild(this.bgcanvas_),t.appendChild(this.fgcanvas_),t.appendChild(this.leftZoomHandle_),t.appendChild(this.rightZoomHandle_)},u.prototype.removeFromGraph_=function(){var t=this.graphDiv_;t.removeChild(this.bgcanvas_),t.removeChild(this.fgcanvas_),t.removeChild(this.leftZoomHandle_),t.removeChild(this.rightZoomHandle_),this.graphDiv_=null},u.prototype.reserveSpace_=function(t){this.getOption_("showRangeSelector")&&t.reserveSpaceBottom(this.getOption_("rangeSelectorHeight")+4)},u.prototype.renderStaticLayer_=function(){this.updateVisibility_()&&(this.resize_(),this.drawStaticLayer_())},u.prototype.renderInteractiveLayer_=function(){this.updateVisibility_()&&!this.isChangingRange_&&(this.placeZoomHandles_(),this.drawInteractiveLayer_())},u.prototype.updateVisibility_=function(){var t=this.getOption_("showRangeSelector");if(t)this.interfaceCreated_?this.graphDiv_&&this.graphDiv_.parentNode||this.addToGraph_():this.createInterface_();else if(this.graphDiv_){this.removeFromGraph_();var e=this.dygraph_;setTimeout(function(){e.width_=0,e.resize()},1)}return t},u.prototype.resize_=function(){function t(t,e,a,i){var n=i||r.getContextPixelRatio(e);t.style.top=a.y+"px",t.style.left=a.x+"px",t.width=a.w*n,t.height=a.h*n,t.style.width=a.w+"px",t.style.height=a.h+"px",1!=n&&e.scale(n,n)}var e=this.dygraph_.layout_.getPlotArea(),a=0;this.dygraph_.getOptionForAxis("drawAxis","x")&&(a=this.getOption_("xAxisHeight")||this.getOption_("axisLabelFontSize")+2*this.getOption_("axisTickSize")),this.canvasRect_={x:e.x,y:e.y+e.h+a+4,w:e.w,h:this.getOption_("rangeSelectorHeight")};var i=this.dygraph_.getNumericOption("pixelRatio");t(this.bgcanvas_,this.bgcanvas_ctx_,this.canvasRect_,i),t(this.fgcanvas_,this.fgcanvas_ctx_,this.canvasRect_,i)},u.prototype.createCanvases_=function(){this.bgcanvas_=r.createCanvas(),this.bgcanvas_.className="dygraph-rangesel-bgcanvas",this.bgcanvas_.style.position="absolute",this.bgcanvas_.style.zIndex=9,this.bgcanvas_ctx_=r.getContext(this.bgcanvas_),this.fgcanvas_=r.createCanvas(),this.fgcanvas_.className="dygraph-rangesel-fgcanvas",this.fgcanvas_.style.position="absolute",this.fgcanvas_.style.zIndex=9,this.fgcanvas_.style.cursor="default",this.fgcanvas_ctx_=r.getContext(this.fgcanvas_)},u.prototype.createZoomHandles_=function(){var t=new Image;t.className="dygraph-rangesel-zoomhandle",t.style.position="absolute",t.style.zIndex=10,t.style.visibility="hidden",t.style.cursor="col-resize",t.width=9,t.height=16,t.src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAQCAYAAADESFVDAAAAAXNSR0IArs4c6QAAAAZiS0dEANAAzwDP4Z7KegAAAAlwSFlzAAAOxAAADsQBlSsOGwAAAAd0SU1FB9sHGw0cMqdt1UwAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAAaElEQVQoz+3SsRFAQBCF4Z9WJM8KCDVwownl6YXsTmCUsyKGkZzcl7zkz3YLkypgAnreFmDEpHkIwVOMfpdi9CEEN2nGpFdwD03yEqDtOgCaun7sqSTDH32I1pQA2Pb9sZecAxc5r3IAb21d6878xsAAAAAASUVORK5CYII=",this.isMobileDevice_&&(t.width*=2,t.height*=2),this.leftZoomHandle_=t,this.rightZoomHandle_=t.cloneNode(!1)},u.prototype.initInteraction_=function(){var t,e,a,i,n,o,l,u,d,c,p,g,f,_,v=this,y=document,x=0,m=null,b=!1,w=!1,A=!this.isMobileDevice_,O=new h.default;t=function(t){var e=v.dygraph_.xAxisExtremes(),a=(e[1]-e[0])/v.canvasRect_.w;return[e[0]+(t.leftHandlePos-v.canvasRect_.x)*a,e[0]+(t.rightHandlePos-v.canvasRect_.x)*a]},e=function(t){return r.cancelEvent(t),b=!0,x=t.clientX,m=t.target?t.target:t.srcElement,"mousedown"!==t.type&&"dragstart"!==t.type||(r.addEvent(y,"mousemove",a),r.addEvent(y,"mouseup",i)),v.fgcanvas_.style.cursor="col-resize",O.cover(),!0},a=function(t){if(!b)return!1;r.cancelEvent(t);var e=t.clientX-x;if(Math.abs(e)<4)return!0;x=t.clientX;var a,i=v.getZoomHandleStatus_();m==v.leftZoomHandle_?(a=i.leftHandlePos+e,a=Math.min(a,i.rightHandlePos-m.width-3),a=Math.max(a,v.canvasRect_.x)):(a=i.rightHandlePos+e,a=Math.min(a,v.canvasRect_.x+v.canvasRect_.w),a=Math.max(a,i.leftHandlePos+m.width+3));var o=m.width/2;return m.style.left=a-o+"px",v.drawInteractiveLayer_(),A&&n(),!0},i=function(t){return!!b&&(b=!1,O.uncover(),r.removeEvent(y,"mousemove",a),r.removeEvent(y,"mouseup",i),v.fgcanvas_.style.cursor="default",A||n(),!0)},n=function(){try{var e=v.getZoomHandleStatus_();if(v.isChangingRange_=!0,e.isZoomed){var a=t(e);v.dygraph_.doZoomXDates_(a[0],a[1])}else v.dygraph_.resetZoom()}finally{v.isChangingRange_=!1}},o=function(t){var e=v.leftZoomHandle_.getBoundingClientRect(),a=e.left+e.width/2;e=v.rightZoomHandle_.getBoundingClientRect();var i=e.left+e.width/2;return t.clientX>a&&t.clientX<i},l=function(t){return!(w||!o(t)||!v.getZoomHandleStatus_().isZoomed)&&(r.cancelEvent(t),w=!0,x=t.clientX,"mousedown"===t.type&&(r.addEvent(y,"mousemove",u),r.addEvent(y,"mouseup",d)),!0)},u=function(t){if(!w)return!1;r.cancelEvent(t);var e=t.clientX-x;if(Math.abs(e)<4)return!0;x=t.clientX;var a=v.getZoomHandleStatus_(),i=a.leftHandlePos,n=a.rightHandlePos,o=n-i;i+e<=v.canvasRect_.x?(i=v.canvasRect_.x,n=i+o):n+e>=v.canvasRect_.x+v.canvasRect_.w?(n=v.canvasRect_.x+v.canvasRect_.w,i=n-o):(i+=e,n+=e);var s=v.leftZoomHandle_.width/2;return v.leftZoomHandle_.style.left=i-s+"px",v.rightZoomHandle_.style.left=n-s+"px",v.drawInteractiveLayer_(),A&&c(),!0},d=function(t){return!!w&&(w=!1,r.removeEvent(y,"mousemove",u),r.removeEvent(y,"mouseup",d),A||c(),!0)},c=function(){try{v.isChangingRange_=!0,v.dygraph_.dateWindow_=t(v.getZoomHandleStatus_()),v.dygraph_.drawGraph_(!1)}finally{v.isChangingRange_=!1}},p=function(t){if(!b&&!w){var e=o(t)?"move":"default";e!=v.fgcanvas_.style.cursor&&(v.fgcanvas_.style.cursor=e)}},g=function(t){"touchstart"==t.type&&1==t.targetTouches.length?e(t.targetTouches[0])&&r.cancelEvent(t):"touchmove"==t.type&&1==t.targetTouches.length?a(t.targetTouches[0])&&r.cancelEvent(t):i(t)},f=function(t){"touchstart"==t.type&&1==t.targetTouches.length?l(t.targetTouches[0])&&r.cancelEvent(t):"touchmove"==t.type&&1==t.targetTouches.length?u(t.targetTouches[0])&&r.cancelEvent(t):d(t)},_=function(t,e){for(var a=["touchstart","touchend","touchmove","touchcancel"],i=0;i<a.length;i++)v.dygraph_.addAndTrackEvent(t,a[i],e)},this.setDefaultOption_("interactionModel",s.default.dragIsPanInteractionModel),this.setDefaultOption_("panEdgeFraction",1e-4);var D=window.opera?"mousedown":"dragstart";this.dygraph_.addAndTrackEvent(this.leftZoomHandle_,D,e),this.dygraph_.addAndTrackEvent(this.rightZoomHandle_,D,e),this.dygraph_.addAndTrackEvent(this.fgcanvas_,"mousedown",l),this.dygraph_.addAndTrackEvent(this.fgcanvas_,"mousemove",p),this.hasTouchInterface_&&(_(this.leftZoomHandle_,g),_(this.rightZoomHandle_,g),_(this.fgcanvas_,f))},u.prototype.drawStaticLayer_=function(){var t=this.bgcanvas_ctx_;t.clearRect(0,0,this.canvasRect_.w,this.canvasRect_.h);try{this.drawMiniPlot_()}catch(t){console.warn(t)}this.bgcanvas_ctx_.lineWidth=this.getOption_("rangeSelectorBackgroundLineWidth"),t.strokeStyle=this.getOption_("rangeSelectorBackgroundStrokeColor"),t.beginPath(),t.moveTo(.5,.5),t.lineTo(.5,this.canvasRect_.h-.5),t.lineTo(this.canvasRect_.w-.5,this.canvasRect_.h-.5),t.lineTo(this.canvasRect_.w-.5,.5),t.stroke()},u.prototype.drawMiniPlot_=function(){var t=this.getOption_("rangeSelectorPlotFillColor"),e=this.getOption_("rangeSelectorPlotFillGradientColor"),a=this.getOption_("rangeSelectorPlotStrokeColor");if(t||a){var i=this.getOption_("stepPlot"),n=this.computeCombinedSeriesAndLimits_(),r=n.yMax-n.yMin,o=this.bgcanvas_ctx_,s=this.dygraph_.xAxisExtremes(),l=Math.max(s[1]-s[0],1e-30),h=(this.canvasRect_.w-.5)/l,u=(this.canvasRect_.h-.5)/r,d=this.canvasRect_.w-.5,c=this.canvasRect_.h-.5,p=null,g=null;o.beginPath(),o.moveTo(.5,c);for(var f=0;f<n.data.length;f++){var _=n.data[f],v=null!==_[0]?(_[0]-s[0])*h:NaN,y=null!==_[1]?c-(_[1]-n.yMin)*u:NaN;(i||null===p||Math.round(v)!=Math.round(p))&&(isFinite(v)&&isFinite(y)?(null===p?o.lineTo(v,c):i&&o.lineTo(v,g),o.lineTo(v,y),p=v,g=y):(null!==p&&(i?(o.lineTo(v,g),o.lineTo(v,c)):o.lineTo(p,c)),p=g=null))}if(o.lineTo(d,c),o.closePath(),t){var x=this.bgcanvas_ctx_.createLinearGradient(0,0,0,c);e&&x.addColorStop(0,e),x.addColorStop(1,t),this.bgcanvas_ctx_.fillStyle=x,o.fill()}a&&(this.bgcanvas_ctx_.strokeStyle=a,this.bgcanvas_ctx_.lineWidth=this.getOption_("rangeSelectorPlotLineWidth"),o.stroke())}},u.prototype.computeCombinedSeriesAndLimits_=function(){var t,e=this.dygraph_,a=this.getOption_("logscale"),i=e.numColumns(),n=e.getLabels(),o=new Array(i),s=!1,l=e.visibility(),h=[];for(t=1;t<i;t++){var u=this.getOption_("showInRangeSelector",n[t]);h.push(u),null!==u&&(s=!0)}if(s)for(t=1;t<i;t++)o[t]=h[t-1];else for(t=1;t<i;t++)o[t]=l[t-1];var d=[],c=e.dataHandler_,p=e.attributes_;for(t=1;t<e.numColumns();t++)if(o[t]){var g=c.extractSeries(e.rawData_,t,p);e.rollPeriod()>1&&(g=c.rollingAverage(g,e.rollPeriod(),p)),d.push(g)}var f=[];for(t=0;t<d[0].length;t++){for(var _=0,v=0,y=0;y<d.length;y++){var x=d[y][t][1];null===x||isNaN(x)||(v++,_+=x)}f.push([d[0][t][0],_/v])}var m=Number.MAX_VALUE,b=-Number.MAX_VALUE;for(t=0;t<f.length;t++){var w=f[t][1];null!==w&&isFinite(w)&&(!a||w>0)&&(m=Math.min(m,w),b=Math.max(b,w))}if(a)for(b=r.log10(b),b+=.25*b,m=r.log10(m),t=0;t<f.length;t++)f[t][1]=r.log10(f[t][1]);else{var A,O=b-m;A=O<=Number.MIN_VALUE?.25*b:.25*O,b+=A,m-=A}return{data:f,yMin:m,yMax:b}},u.prototype.placeZoomHandles_=function(){var t=this.dygraph_.xAxisExtremes(),e=this.dygraph_.xAxisRange(),a=t[1]-t[0],i=Math.max(0,(e[0]-t[0])/a),n=Math.max(0,(t[1]-e[1])/a),r=this.canvasRect_.x+this.canvasRect_.w*i,o=this.canvasRect_.x+this.canvasRect_.w*(1-n),s=Math.max(this.canvasRect_.y,this.canvasRect_.y+(this.canvasRect_.h-this.leftZoomHandle_.height)/2),l=this.leftZoomHandle_.width/2;this.leftZoomHandle_.style.left=r-l+"px",this.leftZoomHandle_.style.top=s+"px",this.rightZoomHandle_.style.left=o-l+"px",this.rightZoomHandle_.style.top=this.leftZoomHandle_.style.top,this.leftZoomHandle_.style.visibility="visible",this.rightZoomHandle_.style.visibility="visible"},u.prototype.drawInteractiveLayer_=function(){var t=this.fgcanvas_ctx_;t.clearRect(0,0,this.canvasRect_.w,this.canvasRect_.h);var e=this.canvasRect_.w-1,a=this.canvasRect_.h-1,i=this.getZoomHandleStatus_();if(t.strokeStyle=this.getOption_("rangeSelectorForegroundStrokeColor"),t.lineWidth=this.getOption_("rangeSelectorForegroundLineWidth"),i.isZoomed){var n=Math.max(1,i.leftHandlePos-this.canvasRect_.x),r=Math.min(e,i.rightHandlePos-this.canvasRect_.x);t.fillStyle="rgba(240, 240, 240, "+this.getOption_("rangeSelectorAlpha").toString()+")",t.fillRect(0,0,n,this.canvasRect_.h),t.fillRect(r,0,this.canvasRect_.w-r,this.canvasRect_.h),t.beginPath(),t.moveTo(1,1),t.lineTo(n,1),t.lineTo(n,a),t.lineTo(r,a),t.lineTo(r,1),t.lineTo(e,1),t.stroke()}else t.beginPath(),t.moveTo(1,1),t.lineTo(1,a),t.lineTo(e,a),t.lineTo(e,1),t.stroke()},u.prototype.getZoomHandleStatus_=function(){var t=this.leftZoomHandle_.width/2,e=parseFloat(this.leftZoomHandle_.style.left)+t,a=parseFloat(this.rightZoomHandle_.style.left)+t;return{leftHandlePos:e,rightHandlePos:a,isZoomed:e-1>this.canvasRect_.x||a+1<this.canvasRect_.x+this.canvasRect_.w}},a.default=u,e.exports=a.default},{"../dygraph-interaction-model":12,"../dygraph-utils":17,"../iframe-tarp":19}]},{},[18])(18)});
+//# sourceMappingURL=dist/dygraph.min.js.map
diff --git a/modules/http/static/dygraph.min.js.spdx b/modules/http/static/dygraph.min.js.spdx
new file mode 100644
index 0000000..9b03d07
--- /dev/null
+++ b/modules/http/static/dygraph.min.js.spdx
@@ -0,0 +1,12 @@
+SPDXVersion: SPDX-2.1
+DataLicense: CC0-1.0
+SPDXID: SPDXRef-DOCUMENT
+DocumentName: dygraph
+DocumentNamespace: http://spdx.org/spdxdocs/spdx-v2.1-4433b214-29e7-41ba-afa9-5d06f5e643e1
+
+PackageName: dygraph
+PackageVersion: 2.1.0
+PackageDownloadLocation: http://dygraphs.com/2.1.0/dygraph.min.js
+PackageChecksum: SHA256: f3b2eafa9250129f3cadf4eef279dd3ede862d4f2fa193094ea7aff3bd231303
+PackageOriginator: Person: Dan Vanderkam (danvdk@gmail.com)
+PackageLicenseDeclared: MIT
diff --git a/modules/http/static/epoch.css b/modules/http/static/epoch.css
new file mode 100644
index 0000000..928f441
--- /dev/null
+++ b/modules/http/static/epoch.css
@@ -0,0 +1,2 @@
+/* SPDX-License-Identifier: MIT */
+.epoch .axis path,.epoch .axis line{shape-rendering:crispEdges}.epoch .axis.canvas .tick line{shape-rendering:geometricPrecision}div#_canvas_css_reference{width:0;height:0;position:absolute;top:-1000px;left:-1000px}div#_canvas_css_reference svg{position:absolute;width:0;height:0;top:-1000px;left:-1000px}.epoch{font-family:"Helvetica Neue", Helvetica, Arial, sans-serif;font-size:12pt}.epoch .axis path,.epoch .axis line{fill:transparent;stroke:#000}.epoch .axis .tick text{font-size:9pt}.epoch .line{fill:transparent;stroke-width:2px}.epoch.sparklines .line{stroke-width:1px}.epoch .area{stroke:transparent}.epoch .arc.pie{stroke:#fff;stroke-width:1.5px}.epoch .arc.pie text{stroke:transparent;fill:white;font-size:9pt}.epoch .gauge-labels .value{text-anchor:middle;font-size:140%;fill:#666}.epoch.gauge-tiny{width:120px;height:90px}.epoch.gauge-tiny .gauge-labels .value{font-size:80%}.epoch.gauge-tiny .gauge .arc.outer{stroke-width:2px}.epoch.gauge-small{width:180px;height:135px}.epoch.gauge-small .gauge-labels .value{font-size:120%}.epoch.gauge-small .gauge .arc.outer{stroke-width:3px}.epoch.gauge-medium{width:240px;height:180px}.epoch.gauge-medium .gauge .arc.outer{stroke-width:3px}.epoch.gauge-large{width:320px;height:240px}.epoch.gauge-large .gauge-labels .value{font-size:180%}.epoch .gauge .arc.outer{stroke-width:4px;stroke:#666}.epoch .gauge .arc.inner{stroke-width:1px;stroke:#555}.epoch .gauge .tick{stroke-width:1px;stroke:#555}.epoch .gauge .needle{fill:orange}.epoch .gauge .needle-base{fill:#666}.epoch div.ref.category1,.epoch.category10 div.ref.category1{background-color:#1f77b4}.epoch .category1 .line,.epoch.category10 .category1 .line{stroke:#1f77b4}.epoch .category1 .area,.epoch .category1 .dot,.epoch.category10 .category1 .area,.epoch.category10 .category1 .dot{fill:#1f77b4;stroke:transparent}.epoch .arc.category1 path,.epoch.category10 .arc.category1 path{fill:#1f77b4}.epoch .bar.category1,.epoch.category10 .bar.category1{fill:#1f77b4}.epoch div.ref.category2,.epoch.category10 div.ref.category2{background-color:#ff7f0e}.epoch .category2 .line,.epoch.category10 .category2 .line{stroke:#ff7f0e}.epoch .category2 .area,.epoch .category2 .dot,.epoch.category10 .category2 .area,.epoch.category10 .category2 .dot{fill:#ff7f0e;stroke:transparent}.epoch .arc.category2 path,.epoch.category10 .arc.category2 path{fill:#ff7f0e}.epoch .bar.category2,.epoch.category10 .bar.category2{fill:#ff7f0e}.epoch div.ref.category3,.epoch.category10 div.ref.category3{background-color:#2ca02c}.epoch .category3 .line,.epoch.category10 .category3 .line{stroke:#2ca02c}.epoch .category3 .area,.epoch .category3 .dot,.epoch.category10 .category3 .area,.epoch.category10 .category3 .dot{fill:#2ca02c;stroke:transparent}.epoch .arc.category3 path,.epoch.category10 .arc.category3 path{fill:#2ca02c}.epoch .bar.category3,.epoch.category10 .bar.category3{fill:#2ca02c}.epoch div.ref.category4,.epoch.category10 div.ref.category4{background-color:#d62728}.epoch .category4 .line,.epoch.category10 .category4 .line{stroke:#d62728}.epoch .category4 .area,.epoch .category4 .dot,.epoch.category10 .category4 .area,.epoch.category10 .category4 .dot{fill:#d62728;stroke:transparent}.epoch .arc.category4 path,.epoch.category10 .arc.category4 path{fill:#d62728}.epoch .bar.category4,.epoch.category10 .bar.category4{fill:#d62728}.epoch div.ref.category5,.epoch.category10 div.ref.category5{background-color:#9467bd}.epoch .category5 .line,.epoch.category10 .category5 .line{stroke:#9467bd}.epoch .category5 .area,.epoch .category5 .dot,.epoch.category10 .category5 .area,.epoch.category10 .category5 .dot{fill:#9467bd;stroke:transparent}.epoch .arc.category5 path,.epoch.category10 .arc.category5 path{fill:#9467bd}.epoch .bar.category5,.epoch.category10 .bar.category5{fill:#9467bd}.epoch div.ref.category6,.epoch.category10 div.ref.category6{background-color:#8c564b}.epoch .category6 .line,.epoch.category10 .category6 .line{stroke:#8c564b}.epoch .category6 .area,.epoch .category6 .dot,.epoch.category10 .category6 .area,.epoch.category10 .category6 .dot{fill:#8c564b;stroke:transparent}.epoch .arc.category6 path,.epoch.category10 .arc.category6 path{fill:#8c564b}.epoch .bar.category6,.epoch.category10 .bar.category6{fill:#8c564b}.epoch div.ref.category7,.epoch.category10 div.ref.category7{background-color:#e377c2}.epoch .category7 .line,.epoch.category10 .category7 .line{stroke:#e377c2}.epoch .category7 .area,.epoch .category7 .dot,.epoch.category10 .category7 .area,.epoch.category10 .category7 .dot{fill:#e377c2;stroke:transparent}.epoch .arc.category7 path,.epoch.category10 .arc.category7 path{fill:#e377c2}.epoch .bar.category7,.epoch.category10 .bar.category7{fill:#e377c2}.epoch div.ref.category8,.epoch.category10 div.ref.category8{background-color:#7f7f7f}.epoch .category8 .line,.epoch.category10 .category8 .line{stroke:#7f7f7f}.epoch .category8 .area,.epoch .category8 .dot,.epoch.category10 .category8 .area,.epoch.category10 .category8 .dot{fill:#7f7f7f;stroke:transparent}.epoch .arc.category8 path,.epoch.category10 .arc.category8 path{fill:#7f7f7f}.epoch .bar.category8,.epoch.category10 .bar.category8{fill:#7f7f7f}.epoch div.ref.category9,.epoch.category10 div.ref.category9{background-color:#bcbd22}.epoch .category9 .line,.epoch.category10 .category9 .line{stroke:#bcbd22}.epoch .category9 .area,.epoch .category9 .dot,.epoch.category10 .category9 .area,.epoch.category10 .category9 .dot{fill:#bcbd22;stroke:transparent}.epoch .arc.category9 path,.epoch.category10 .arc.category9 path{fill:#bcbd22}.epoch .bar.category9,.epoch.category10 .bar.category9{fill:#bcbd22}.epoch div.ref.category10,.epoch.category10 div.ref.category10{background-color:#17becf}.epoch .category10 .line,.epoch.category10 .category10 .line{stroke:#17becf}.epoch .category10 .area,.epoch .category10 .dot,.epoch.category10 .category10 .area,.epoch.category10 .category10 .dot{fill:#17becf;stroke:transparent}.epoch .arc.category10 path,.epoch.category10 .arc.category10 path{fill:#17becf}.epoch .bar.category10,.epoch.category10 .bar.category10{fill:#17becf}.epoch.category20 div.ref.category1{background-color:#1f77b4}.epoch.category20 .category1 .line{stroke:#1f77b4}.epoch.category20 .category1 .area,.epoch.category20 .category1 .dot{fill:#1f77b4;stroke:transparent}.epoch.category20 .arc.category1 path{fill:#1f77b4}.epoch.category20 .bar.category1{fill:#1f77b4}.epoch.category20 div.ref.category2{background-color:#aec7e8}.epoch.category20 .category2 .line{stroke:#aec7e8}.epoch.category20 .category2 .area,.epoch.category20 .category2 .dot{fill:#aec7e8;stroke:transparent}.epoch.category20 .arc.category2 path{fill:#aec7e8}.epoch.category20 .bar.category2{fill:#aec7e8}.epoch.category20 div.ref.category3{background-color:#ff7f0e}.epoch.category20 .category3 .line{stroke:#ff7f0e}.epoch.category20 .category3 .area,.epoch.category20 .category3 .dot{fill:#ff7f0e;stroke:transparent}.epoch.category20 .arc.category3 path{fill:#ff7f0e}.epoch.category20 .bar.category3{fill:#ff7f0e}.epoch.category20 div.ref.category4{background-color:#ffbb78}.epoch.category20 .category4 .line{stroke:#ffbb78}.epoch.category20 .category4 .area,.epoch.category20 .category4 .dot{fill:#ffbb78;stroke:transparent}.epoch.category20 .arc.category4 path{fill:#ffbb78}.epoch.category20 .bar.category4{fill:#ffbb78}.epoch.category20 div.ref.category5{background-color:#2ca02c}.epoch.category20 .category5 .line{stroke:#2ca02c}.epoch.category20 .category5 .area,.epoch.category20 .category5 .dot{fill:#2ca02c;stroke:transparent}.epoch.category20 .arc.category5 path{fill:#2ca02c}.epoch.category20 .bar.category5{fill:#2ca02c}.epoch.category20 div.ref.category6{background-color:#98df8a}.epoch.category20 .category6 .line{stroke:#98df8a}.epoch.category20 .category6 .area,.epoch.category20 .category6 .dot{fill:#98df8a;stroke:transparent}.epoch.category20 .arc.category6 path{fill:#98df8a}.epoch.category20 .bar.category6{fill:#98df8a}.epoch.category20 div.ref.category7{background-color:#d62728}.epoch.category20 .category7 .line{stroke:#d62728}.epoch.category20 .category7 .area,.epoch.category20 .category7 .dot{fill:#d62728;stroke:transparent}.epoch.category20 .arc.category7 path{fill:#d62728}.epoch.category20 .bar.category7{fill:#d62728}.epoch.category20 div.ref.category8{background-color:#ff9896}.epoch.category20 .category8 .line{stroke:#ff9896}.epoch.category20 .category8 .area,.epoch.category20 .category8 .dot{fill:#ff9896;stroke:transparent}.epoch.category20 .arc.category8 path{fill:#ff9896}.epoch.category20 .bar.category8{fill:#ff9896}.epoch.category20 div.ref.category9{background-color:#9467bd}.epoch.category20 .category9 .line{stroke:#9467bd}.epoch.category20 .category9 .area,.epoch.category20 .category9 .dot{fill:#9467bd;stroke:transparent}.epoch.category20 .arc.category9 path{fill:#9467bd}.epoch.category20 .bar.category9{fill:#9467bd}.epoch.category20 div.ref.category10{background-color:#c5b0d5}.epoch.category20 .category10 .line{stroke:#c5b0d5}.epoch.category20 .category10 .area,.epoch.category20 .category10 .dot{fill:#c5b0d5;stroke:transparent}.epoch.category20 .arc.category10 path{fill:#c5b0d5}.epoch.category20 .bar.category10{fill:#c5b0d5}.epoch.category20 div.ref.category11{background-color:#8c564b}.epoch.category20 .category11 .line{stroke:#8c564b}.epoch.category20 .category11 .area,.epoch.category20 .category11 .dot{fill:#8c564b;stroke:transparent}.epoch.category20 .arc.category11 path{fill:#8c564b}.epoch.category20 .bar.category11{fill:#8c564b}.epoch.category20 div.ref.category12{background-color:#c49c94}.epoch.category20 .category12 .line{stroke:#c49c94}.epoch.category20 .category12 .area,.epoch.category20 .category12 .dot{fill:#c49c94;stroke:transparent}.epoch.category20 .arc.category12 path{fill:#c49c94}.epoch.category20 .bar.category12{fill:#c49c94}.epoch.category20 div.ref.category13{background-color:#e377c2}.epoch.category20 .category13 .line{stroke:#e377c2}.epoch.category20 .category13 .area,.epoch.category20 .category13 .dot{fill:#e377c2;stroke:transparent}.epoch.category20 .arc.category13 path{fill:#e377c2}.epoch.category20 .bar.category13{fill:#e377c2}.epoch.category20 div.ref.category14{background-color:#f7b6d2}.epoch.category20 .category14 .line{stroke:#f7b6d2}.epoch.category20 .category14 .area,.epoch.category20 .category14 .dot{fill:#f7b6d2;stroke:transparent}.epoch.category20 .arc.category14 path{fill:#f7b6d2}.epoch.category20 .bar.category14{fill:#f7b6d2}.epoch.category20 div.ref.category15{background-color:#7f7f7f}.epoch.category20 .category15 .line{stroke:#7f7f7f}.epoch.category20 .category15 .area,.epoch.category20 .category15 .dot{fill:#7f7f7f;stroke:transparent}.epoch.category20 .arc.category15 path{fill:#7f7f7f}.epoch.category20 .bar.category15{fill:#7f7f7f}.epoch.category20 div.ref.category16{background-color:#c7c7c7}.epoch.category20 .category16 .line{stroke:#c7c7c7}.epoch.category20 .category16 .area,.epoch.category20 .category16 .dot{fill:#c7c7c7;stroke:transparent}.epoch.category20 .arc.category16 path{fill:#c7c7c7}.epoch.category20 .bar.category16{fill:#c7c7c7}.epoch.category20 div.ref.category17{background-color:#bcbd22}.epoch.category20 .category17 .line{stroke:#bcbd22}.epoch.category20 .category17 .area,.epoch.category20 .category17 .dot{fill:#bcbd22;stroke:transparent}.epoch.category20 .arc.category17 path{fill:#bcbd22}.epoch.category20 .bar.category17{fill:#bcbd22}.epoch.category20 div.ref.category18{background-color:#dbdb8d}.epoch.category20 .category18 .line{stroke:#dbdb8d}.epoch.category20 .category18 .area,.epoch.category20 .category18 .dot{fill:#dbdb8d;stroke:transparent}.epoch.category20 .arc.category18 path{fill:#dbdb8d}.epoch.category20 .bar.category18{fill:#dbdb8d}.epoch.category20 div.ref.category19{background-color:#17becf}.epoch.category20 .category19 .line{stroke:#17becf}.epoch.category20 .category19 .area,.epoch.category20 .category19 .dot{fill:#17becf;stroke:transparent}.epoch.category20 .arc.category19 path{fill:#17becf}.epoch.category20 .bar.category19{fill:#17becf}.epoch.category20 div.ref.category20{background-color:#9edae5}.epoch.category20 .category20 .line{stroke:#9edae5}.epoch.category20 .category20 .area,.epoch.category20 .category20 .dot{fill:#9edae5;stroke:transparent}.epoch.category20 .arc.category20 path{fill:#9edae5}.epoch.category20 .bar.category20{fill:#9edae5}.epoch.category20b div.ref.category1{background-color:#393b79}.epoch.category20b .category1 .line{stroke:#393b79}.epoch.category20b .category1 .area,.epoch.category20b .category1 .dot{fill:#393b79;stroke:transparent}.epoch.category20b .arc.category1 path{fill:#393b79}.epoch.category20b .bar.category1{fill:#393b79}.epoch.category20b div.ref.category2{background-color:#5254a3}.epoch.category20b .category2 .line{stroke:#5254a3}.epoch.category20b .category2 .area,.epoch.category20b .category2 .dot{fill:#5254a3;stroke:transparent}.epoch.category20b .arc.category2 path{fill:#5254a3}.epoch.category20b .bar.category2{fill:#5254a3}.epoch.category20b div.ref.category3{background-color:#6b6ecf}.epoch.category20b .category3 .line{stroke:#6b6ecf}.epoch.category20b .category3 .area,.epoch.category20b .category3 .dot{fill:#6b6ecf;stroke:transparent}.epoch.category20b .arc.category3 path{fill:#6b6ecf}.epoch.category20b .bar.category3{fill:#6b6ecf}.epoch.category20b div.ref.category4{background-color:#9c9ede}.epoch.category20b .category4 .line{stroke:#9c9ede}.epoch.category20b .category4 .area,.epoch.category20b .category4 .dot{fill:#9c9ede;stroke:transparent}.epoch.category20b .arc.category4 path{fill:#9c9ede}.epoch.category20b .bar.category4{fill:#9c9ede}.epoch.category20b div.ref.category5{background-color:#637939}.epoch.category20b .category5 .line{stroke:#637939}.epoch.category20b .category5 .area,.epoch.category20b .category5 .dot{fill:#637939;stroke:transparent}.epoch.category20b .arc.category5 path{fill:#637939}.epoch.category20b .bar.category5{fill:#637939}.epoch.category20b div.ref.category6{background-color:#8ca252}.epoch.category20b .category6 .line{stroke:#8ca252}.epoch.category20b .category6 .area,.epoch.category20b .category6 .dot{fill:#8ca252;stroke:transparent}.epoch.category20b .arc.category6 path{fill:#8ca252}.epoch.category20b .bar.category6{fill:#8ca252}.epoch.category20b div.ref.category7{background-color:#b5cf6b}.epoch.category20b .category7 .line{stroke:#b5cf6b}.epoch.category20b .category7 .area,.epoch.category20b .category7 .dot{fill:#b5cf6b;stroke:transparent}.epoch.category20b .arc.category7 path{fill:#b5cf6b}.epoch.category20b .bar.category7{fill:#b5cf6b}.epoch.category20b div.ref.category8{background-color:#cedb9c}.epoch.category20b .category8 .line{stroke:#cedb9c}.epoch.category20b .category8 .area,.epoch.category20b .category8 .dot{fill:#cedb9c;stroke:transparent}.epoch.category20b .arc.category8 path{fill:#cedb9c}.epoch.category20b .bar.category8{fill:#cedb9c}.epoch.category20b div.ref.category9{background-color:#8c6d31}.epoch.category20b .category9 .line{stroke:#8c6d31}.epoch.category20b .category9 .area,.epoch.category20b .category9 .dot{fill:#8c6d31;stroke:transparent}.epoch.category20b .arc.category9 path{fill:#8c6d31}.epoch.category20b .bar.category9{fill:#8c6d31}.epoch.category20b div.ref.category10{background-color:#bd9e39}.epoch.category20b .category10 .line{stroke:#bd9e39}.epoch.category20b .category10 .area,.epoch.category20b .category10 .dot{fill:#bd9e39;stroke:transparent}.epoch.category20b .arc.category10 path{fill:#bd9e39}.epoch.category20b .bar.category10{fill:#bd9e39}.epoch.category20b div.ref.category11{background-color:#e7ba52}.epoch.category20b .category11 .line{stroke:#e7ba52}.epoch.category20b .category11 .area,.epoch.category20b .category11 .dot{fill:#e7ba52;stroke:transparent}.epoch.category20b .arc.category11 path{fill:#e7ba52}.epoch.category20b .bar.category11{fill:#e7ba52}.epoch.category20b div.ref.category12{background-color:#e7cb94}.epoch.category20b .category12 .line{stroke:#e7cb94}.epoch.category20b .category12 .area,.epoch.category20b .category12 .dot{fill:#e7cb94;stroke:transparent}.epoch.category20b .arc.category12 path{fill:#e7cb94}.epoch.category20b .bar.category12{fill:#e7cb94}.epoch.category20b div.ref.category13{background-color:#843c39}.epoch.category20b .category13 .line{stroke:#843c39}.epoch.category20b .category13 .area,.epoch.category20b .category13 .dot{fill:#843c39;stroke:transparent}.epoch.category20b .arc.category13 path{fill:#843c39}.epoch.category20b .bar.category13{fill:#843c39}.epoch.category20b div.ref.category14{background-color:#ad494a}.epoch.category20b .category14 .line{stroke:#ad494a}.epoch.category20b .category14 .area,.epoch.category20b .category14 .dot{fill:#ad494a;stroke:transparent}.epoch.category20b .arc.category14 path{fill:#ad494a}.epoch.category20b .bar.category14{fill:#ad494a}.epoch.category20b div.ref.category15{background-color:#d6616b}.epoch.category20b .category15 .line{stroke:#d6616b}.epoch.category20b .category15 .area,.epoch.category20b .category15 .dot{fill:#d6616b;stroke:transparent}.epoch.category20b .arc.category15 path{fill:#d6616b}.epoch.category20b .bar.category15{fill:#d6616b}.epoch.category20b div.ref.category16{background-color:#e7969c}.epoch.category20b .category16 .line{stroke:#e7969c}.epoch.category20b .category16 .area,.epoch.category20b .category16 .dot{fill:#e7969c;stroke:transparent}.epoch.category20b .arc.category16 path{fill:#e7969c}.epoch.category20b .bar.category16{fill:#e7969c}.epoch.category20b div.ref.category17{background-color:#7b4173}.epoch.category20b .category17 .line{stroke:#7b4173}.epoch.category20b .category17 .area,.epoch.category20b .category17 .dot{fill:#7b4173;stroke:transparent}.epoch.category20b .arc.category17 path{fill:#7b4173}.epoch.category20b .bar.category17{fill:#7b4173}.epoch.category20b div.ref.category18{background-color:#a55194}.epoch.category20b .category18 .line{stroke:#a55194}.epoch.category20b .category18 .area,.epoch.category20b .category18 .dot{fill:#a55194;stroke:transparent}.epoch.category20b .arc.category18 path{fill:#a55194}.epoch.category20b .bar.category18{fill:#a55194}.epoch.category20b div.ref.category19{background-color:#ce6dbd}.epoch.category20b .category19 .line{stroke:#ce6dbd}.epoch.category20b .category19 .area,.epoch.category20b .category19 .dot{fill:#ce6dbd;stroke:transparent}.epoch.category20b .arc.category19 path{fill:#ce6dbd}.epoch.category20b .bar.category19{fill:#ce6dbd}.epoch.category20b div.ref.category20{background-color:#de9ed6}.epoch.category20b .category20 .line{stroke:#de9ed6}.epoch.category20b .category20 .area,.epoch.category20b .category20 .dot{fill:#de9ed6;stroke:transparent}.epoch.category20b .arc.category20 path{fill:#de9ed6}.epoch.category20b .bar.category20{fill:#de9ed6}.epoch.category20c div.ref.category1{background-color:#3182bd}.epoch.category20c .category1 .line{stroke:#3182bd}.epoch.category20c .category1 .area,.epoch.category20c .category1 .dot{fill:#3182bd;stroke:transparent}.epoch.category20c .arc.category1 path{fill:#3182bd}.epoch.category20c .bar.category1{fill:#3182bd}.epoch.category20c div.ref.category2{background-color:#6baed6}.epoch.category20c .category2 .line{stroke:#6baed6}.epoch.category20c .category2 .area,.epoch.category20c .category2 .dot{fill:#6baed6;stroke:transparent}.epoch.category20c .arc.category2 path{fill:#6baed6}.epoch.category20c .bar.category2{fill:#6baed6}.epoch.category20c div.ref.category3{background-color:#9ecae1}.epoch.category20c .category3 .line{stroke:#9ecae1}.epoch.category20c .category3 .area,.epoch.category20c .category3 .dot{fill:#9ecae1;stroke:transparent}.epoch.category20c .arc.category3 path{fill:#9ecae1}.epoch.category20c .bar.category3{fill:#9ecae1}.epoch.category20c div.ref.category4{background-color:#c6dbef}.epoch.category20c .category4 .line{stroke:#c6dbef}.epoch.category20c .category4 .area,.epoch.category20c .category4 .dot{fill:#c6dbef;stroke:transparent}.epoch.category20c .arc.category4 path{fill:#c6dbef}.epoch.category20c .bar.category4{fill:#c6dbef}.epoch.category20c div.ref.category5{background-color:#e6550d}.epoch.category20c .category5 .line{stroke:#e6550d}.epoch.category20c .category5 .area,.epoch.category20c .category5 .dot{fill:#e6550d;stroke:transparent}.epoch.category20c .arc.category5 path{fill:#e6550d}.epoch.category20c .bar.category5{fill:#e6550d}.epoch.category20c div.ref.category6{background-color:#fd8d3c}.epoch.category20c .category6 .line{stroke:#fd8d3c}.epoch.category20c .category6 .area,.epoch.category20c .category6 .dot{fill:#fd8d3c;stroke:transparent}.epoch.category20c .arc.category6 path{fill:#fd8d3c}.epoch.category20c .bar.category6{fill:#fd8d3c}.epoch.category20c div.ref.category7{background-color:#fdae6b}.epoch.category20c .category7 .line{stroke:#fdae6b}.epoch.category20c .category7 .area,.epoch.category20c .category7 .dot{fill:#fdae6b;stroke:transparent}.epoch.category20c .arc.category7 path{fill:#fdae6b}.epoch.category20c .bar.category7{fill:#fdae6b}.epoch.category20c div.ref.category8{background-color:#fdd0a2}.epoch.category20c .category8 .line{stroke:#fdd0a2}.epoch.category20c .category8 .area,.epoch.category20c .category8 .dot{fill:#fdd0a2;stroke:transparent}.epoch.category20c .arc.category8 path{fill:#fdd0a2}.epoch.category20c .bar.category8{fill:#fdd0a2}.epoch.category20c div.ref.category9{background-color:#31a354}.epoch.category20c .category9 .line{stroke:#31a354}.epoch.category20c .category9 .area,.epoch.category20c .category9 .dot{fill:#31a354;stroke:transparent}.epoch.category20c .arc.category9 path{fill:#31a354}.epoch.category20c .bar.category9{fill:#31a354}.epoch.category20c div.ref.category10{background-color:#74c476}.epoch.category20c .category10 .line{stroke:#74c476}.epoch.category20c .category10 .area,.epoch.category20c .category10 .dot{fill:#74c476;stroke:transparent}.epoch.category20c .arc.category10 path{fill:#74c476}.epoch.category20c .bar.category10{fill:#74c476}.epoch.category20c div.ref.category11{background-color:#a1d99b}.epoch.category20c .category11 .line{stroke:#a1d99b}.epoch.category20c .category11 .area,.epoch.category20c .category11 .dot{fill:#a1d99b;stroke:transparent}.epoch.category20c .arc.category11 path{fill:#a1d99b}.epoch.category20c .bar.category11{fill:#a1d99b}.epoch.category20c div.ref.category12{background-color:#c7e9c0}.epoch.category20c .category12 .line{stroke:#c7e9c0}.epoch.category20c .category12 .area,.epoch.category20c .category12 .dot{fill:#c7e9c0;stroke:transparent}.epoch.category20c .arc.category12 path{fill:#c7e9c0}.epoch.category20c .bar.category12{fill:#c7e9c0}.epoch.category20c div.ref.category13{background-color:#756bb1}.epoch.category20c .category13 .line{stroke:#756bb1}.epoch.category20c .category13 .area,.epoch.category20c .category13 .dot{fill:#756bb1;stroke:transparent}.epoch.category20c .arc.category13 path{fill:#756bb1}.epoch.category20c .bar.category13{fill:#756bb1}.epoch.category20c div.ref.category14{background-color:#9e9ac8}.epoch.category20c .category14 .line{stroke:#9e9ac8}.epoch.category20c .category14 .area,.epoch.category20c .category14 .dot{fill:#9e9ac8;stroke:transparent}.epoch.category20c .arc.category14 path{fill:#9e9ac8}.epoch.category20c .bar.category14{fill:#9e9ac8}.epoch.category20c div.ref.category15{background-color:#bcbddc}.epoch.category20c .category15 .line{stroke:#bcbddc}.epoch.category20c .category15 .area,.epoch.category20c .category15 .dot{fill:#bcbddc;stroke:transparent}.epoch.category20c .arc.category15 path{fill:#bcbddc}.epoch.category20c .bar.category15{fill:#bcbddc}.epoch.category20c div.ref.category16{background-color:#dadaeb}.epoch.category20c .category16 .line{stroke:#dadaeb}.epoch.category20c .category16 .area,.epoch.category20c .category16 .dot{fill:#dadaeb;stroke:transparent}.epoch.category20c .arc.category16 path{fill:#dadaeb}.epoch.category20c .bar.category16{fill:#dadaeb}.epoch.category20c div.ref.category17{background-color:#636363}.epoch.category20c .category17 .line{stroke:#636363}.epoch.category20c .category17 .area,.epoch.category20c .category17 .dot{fill:#636363;stroke:transparent}.epoch.category20c .arc.category17 path{fill:#636363}.epoch.category20c .bar.category17{fill:#636363}.epoch.category20c div.ref.category18{background-color:#969696}.epoch.category20c .category18 .line{stroke:#969696}.epoch.category20c .category18 .area,.epoch.category20c .category18 .dot{fill:#969696;stroke:transparent}.epoch.category20c .arc.category18 path{fill:#969696}.epoch.category20c .bar.category18{fill:#969696}.epoch.category20c div.ref.category19{background-color:#bdbdbd}.epoch.category20c .category19 .line{stroke:#bdbdbd}.epoch.category20c .category19 .area,.epoch.category20c .category19 .dot{fill:#bdbdbd;stroke:transparent}.epoch.category20c .arc.category19 path{fill:#bdbdbd}.epoch.category20c .bar.category19{fill:#bdbdbd}.epoch.category20c div.ref.category20{background-color:#d9d9d9}.epoch.category20c .category20 .line{stroke:#d9d9d9}.epoch.category20c .category20 .area,.epoch.category20c .category20 .dot{fill:#d9d9d9;stroke:transparent}.epoch.category20c .arc.category20 path{fill:#d9d9d9}.epoch.category20c .bar.category20{fill:#d9d9d9}.epoch .category1 .bucket,.epoch.heatmap5 .category1 .bucket{fill:#1f77b4}.epoch .category2 .bucket,.epoch.heatmap5 .category2 .bucket{fill:#2ca02c}.epoch .category3 .bucket,.epoch.heatmap5 .category3 .bucket{fill:#d62728}.epoch .category4 .bucket,.epoch.heatmap5 .category4 .bucket{fill:#8c564b}.epoch .category5 .bucket,.epoch.heatmap5 .category5 .bucket{fill:#7f7f7f}.epoch-theme-dark .epoch .axis path,.epoch-theme-dark .epoch .axis line{stroke:#d0d0d0}.epoch-theme-dark .epoch .axis .tick text{fill:#d0d0d0}.epoch-theme-dark .arc.pie{stroke:#333}.epoch-theme-dark .arc.pie text{fill:#333}.epoch-theme-dark .epoch .gauge-labels .value{fill:#BBB}.epoch-theme-dark .epoch .gauge .arc.outer{stroke:#999}.epoch-theme-dark .epoch .gauge .arc.inner{stroke:#AAA}.epoch-theme-dark .epoch .gauge .tick{stroke:#AAA}.epoch-theme-dark .epoch .gauge .needle{fill:#F3DE88}.epoch-theme-dark .epoch .gauge .needle-base{fill:#999}.epoch-theme-dark .epoch div.ref.category1,.epoch-theme-dark .epoch.category10 div.ref.category1{background-color:#909CFF}.epoch-theme-dark .epoch .category1 .line,.epoch-theme-dark .epoch.category10 .category1 .line{stroke:#909CFF}.epoch-theme-dark .epoch .category1 .area,.epoch-theme-dark .epoch .category1 .dot,.epoch-theme-dark .epoch.category10 .category1 .area,.epoch-theme-dark .epoch.category10 .category1 .dot{fill:#909CFF;stroke:transparent}.epoch-theme-dark .epoch .arc.category1 path,.epoch-theme-dark .epoch.category10 .arc.category1 path{fill:#909CFF}.epoch-theme-dark .epoch .bar.category1,.epoch-theme-dark .epoch.category10 .bar.category1{fill:#909CFF}.epoch-theme-dark .epoch div.ref.category2,.epoch-theme-dark .epoch.category10 div.ref.category2{background-color:#FFAC89}.epoch-theme-dark .epoch .category2 .line,.epoch-theme-dark .epoch.category10 .category2 .line{stroke:#FFAC89}.epoch-theme-dark .epoch .category2 .area,.epoch-theme-dark .epoch .category2 .dot,.epoch-theme-dark .epoch.category10 .category2 .area,.epoch-theme-dark .epoch.category10 .category2 .dot{fill:#FFAC89;stroke:transparent}.epoch-theme-dark .epoch .arc.category2 path,.epoch-theme-dark .epoch.category10 .arc.category2 path{fill:#FFAC89}.epoch-theme-dark .epoch .bar.category2,.epoch-theme-dark .epoch.category10 .bar.category2{fill:#FFAC89}.epoch-theme-dark .epoch div.ref.category3,.epoch-theme-dark .epoch.category10 div.ref.category3{background-color:#E889E8}.epoch-theme-dark .epoch .category3 .line,.epoch-theme-dark .epoch.category10 .category3 .line{stroke:#E889E8}.epoch-theme-dark .epoch .category3 .area,.epoch-theme-dark .epoch .category3 .dot,.epoch-theme-dark .epoch.category10 .category3 .area,.epoch-theme-dark .epoch.category10 .category3 .dot{fill:#E889E8;stroke:transparent}.epoch-theme-dark .epoch .arc.category3 path,.epoch-theme-dark .epoch.category10 .arc.category3 path{fill:#E889E8}.epoch-theme-dark .epoch .bar.category3,.epoch-theme-dark .epoch.category10 .bar.category3{fill:#E889E8}.epoch-theme-dark .epoch div.ref.category4,.epoch-theme-dark .epoch.category10 div.ref.category4{background-color:#78E8D3}.epoch-theme-dark .epoch .category4 .line,.epoch-theme-dark .epoch.category10 .category4 .line{stroke:#78E8D3}.epoch-theme-dark .epoch .category4 .area,.epoch-theme-dark .epoch .category4 .dot,.epoch-theme-dark .epoch.category10 .category4 .area,.epoch-theme-dark .epoch.category10 .category4 .dot{fill:#78E8D3;stroke:transparent}.epoch-theme-dark .epoch .arc.category4 path,.epoch-theme-dark .epoch.category10 .arc.category4 path{fill:#78E8D3}.epoch-theme-dark .epoch .bar.category4,.epoch-theme-dark .epoch.category10 .bar.category4{fill:#78E8D3}.epoch-theme-dark .epoch div.ref.category5,.epoch-theme-dark .epoch.category10 div.ref.category5{background-color:#C2FF97}.epoch-theme-dark .epoch .category5 .line,.epoch-theme-dark .epoch.category10 .category5 .line{stroke:#C2FF97}.epoch-theme-dark .epoch .category5 .area,.epoch-theme-dark .epoch .category5 .dot,.epoch-theme-dark .epoch.category10 .category5 .area,.epoch-theme-dark .epoch.category10 .category5 .dot{fill:#C2FF97;stroke:transparent}.epoch-theme-dark .epoch .arc.category5 path,.epoch-theme-dark .epoch.category10 .arc.category5 path{fill:#C2FF97}.epoch-theme-dark .epoch .bar.category5,.epoch-theme-dark .epoch.category10 .bar.category5{fill:#C2FF97}.epoch-theme-dark .epoch div.ref.category6,.epoch-theme-dark .epoch.category10 div.ref.category6{background-color:#B7BCD1}.epoch-theme-dark .epoch .category6 .line,.epoch-theme-dark .epoch.category10 .category6 .line{stroke:#B7BCD1}.epoch-theme-dark .epoch .category6 .area,.epoch-theme-dark .epoch .category6 .dot,.epoch-theme-dark .epoch.category10 .category6 .area,.epoch-theme-dark .epoch.category10 .category6 .dot{fill:#B7BCD1;stroke:transparent}.epoch-theme-dark .epoch .arc.category6 path,.epoch-theme-dark .epoch.category10 .arc.category6 path{fill:#B7BCD1}.epoch-theme-dark .epoch .bar.category6,.epoch-theme-dark .epoch.category10 .bar.category6{fill:#B7BCD1}.epoch-theme-dark .epoch div.ref.category7,.epoch-theme-dark .epoch.category10 div.ref.category7{background-color:#FF857F}.epoch-theme-dark .epoch .category7 .line,.epoch-theme-dark .epoch.category10 .category7 .line{stroke:#FF857F}.epoch-theme-dark .epoch .category7 .area,.epoch-theme-dark .epoch .category7 .dot,.epoch-theme-dark .epoch.category10 .category7 .area,.epoch-theme-dark .epoch.category10 .category7 .dot{fill:#FF857F;stroke:transparent}.epoch-theme-dark .epoch .arc.category7 path,.epoch-theme-dark .epoch.category10 .arc.category7 path{fill:#FF857F}.epoch-theme-dark .epoch .bar.category7,.epoch-theme-dark .epoch.category10 .bar.category7{fill:#FF857F}.epoch-theme-dark .epoch div.ref.category8,.epoch-theme-dark .epoch.category10 div.ref.category8{background-color:#F3DE88}.epoch-theme-dark .epoch .category8 .line,.epoch-theme-dark .epoch.category10 .category8 .line{stroke:#F3DE88}.epoch-theme-dark .epoch .category8 .area,.epoch-theme-dark .epoch .category8 .dot,.epoch-theme-dark .epoch.category10 .category8 .area,.epoch-theme-dark .epoch.category10 .category8 .dot{fill:#F3DE88;stroke:transparent}.epoch-theme-dark .epoch .arc.category8 path,.epoch-theme-dark .epoch.category10 .arc.category8 path{fill:#F3DE88}.epoch-theme-dark .epoch .bar.category8,.epoch-theme-dark .epoch.category10 .bar.category8{fill:#F3DE88}.epoch-theme-dark .epoch div.ref.category9,.epoch-theme-dark .epoch.category10 div.ref.category9{background-color:#C9935E}.epoch-theme-dark .epoch .category9 .line,.epoch-theme-dark .epoch.category10 .category9 .line{stroke:#C9935E}.epoch-theme-dark .epoch .category9 .area,.epoch-theme-dark .epoch .category9 .dot,.epoch-theme-dark .epoch.category10 .category9 .area,.epoch-theme-dark .epoch.category10 .category9 .dot{fill:#C9935E;stroke:transparent}.epoch-theme-dark .epoch .arc.category9 path,.epoch-theme-dark .epoch.category10 .arc.category9 path{fill:#C9935E}.epoch-theme-dark .epoch .bar.category9,.epoch-theme-dark .epoch.category10 .bar.category9{fill:#C9935E}.epoch-theme-dark .epoch div.ref.category10,.epoch-theme-dark .epoch.category10 div.ref.category10{background-color:#A488FF}.epoch-theme-dark .epoch .category10 .line,.epoch-theme-dark .epoch.category10 .category10 .line{stroke:#A488FF}.epoch-theme-dark .epoch .category10 .area,.epoch-theme-dark .epoch .category10 .dot,.epoch-theme-dark .epoch.category10 .category10 .area,.epoch-theme-dark .epoch.category10 .category10 .dot{fill:#A488FF;stroke:transparent}.epoch-theme-dark .epoch .arc.category10 path,.epoch-theme-dark .epoch.category10 .arc.category10 path{fill:#A488FF}.epoch-theme-dark .epoch .bar.category10,.epoch-theme-dark .epoch.category10 .bar.category10{fill:#A488FF}.epoch-theme-dark .epoch.category20 div.ref.category1{background-color:#909CFF}.epoch-theme-dark .epoch.category20 .category1 .line{stroke:#909CFF}.epoch-theme-dark .epoch.category20 .category1 .area,.epoch-theme-dark .epoch.category20 .category1 .dot{fill:#909CFF;stroke:transparent}.epoch-theme-dark .epoch.category20 .arc.category1 path{fill:#909CFF}.epoch-theme-dark .epoch.category20 .bar.category1{fill:#909CFF}.epoch-theme-dark .epoch.category20 div.ref.category2{background-color:#626AAD}.epoch-theme-dark .epoch.category20 .category2 .line{stroke:#626AAD}.epoch-theme-dark .epoch.category20 .category2 .area,.epoch-theme-dark .epoch.category20 .category2 .dot{fill:#626AAD;stroke:transparent}.epoch-theme-dark .epoch.category20 .arc.category2 path{fill:#626AAD}.epoch-theme-dark .epoch.category20 .bar.category2{fill:#626AAD}.epoch-theme-dark .epoch.category20 div.ref.category3{background-color:#FFAC89}.epoch-theme-dark .epoch.category20 .category3 .line{stroke:#FFAC89}.epoch-theme-dark .epoch.category20 .category3 .area,.epoch-theme-dark .epoch.category20 .category3 .dot{fill:#FFAC89;stroke:transparent}.epoch-theme-dark .epoch.category20 .arc.category3 path{fill:#FFAC89}.epoch-theme-dark .epoch.category20 .bar.category3{fill:#FFAC89}.epoch-theme-dark .epoch.category20 div.ref.category4{background-color:#BD7F66}.epoch-theme-dark .epoch.category20 .category4 .line{stroke:#BD7F66}.epoch-theme-dark .epoch.category20 .category4 .area,.epoch-theme-dark .epoch.category20 .category4 .dot{fill:#BD7F66;stroke:transparent}.epoch-theme-dark .epoch.category20 .arc.category4 path{fill:#BD7F66}.epoch-theme-dark .epoch.category20 .bar.category4{fill:#BD7F66}.epoch-theme-dark .epoch.category20 div.ref.category5{background-color:#E889E8}.epoch-theme-dark .epoch.category20 .category5 .line{stroke:#E889E8}.epoch-theme-dark .epoch.category20 .category5 .area,.epoch-theme-dark .epoch.category20 .category5 .dot{fill:#E889E8;stroke:transparent}.epoch-theme-dark .epoch.category20 .arc.category5 path{fill:#E889E8}.epoch-theme-dark .epoch.category20 .bar.category5{fill:#E889E8}.epoch-theme-dark .epoch.category20 div.ref.category6{background-color:#995A99}.epoch-theme-dark .epoch.category20 .category6 .line{stroke:#995A99}.epoch-theme-dark .epoch.category20 .category6 .area,.epoch-theme-dark .epoch.category20 .category6 .dot{fill:#995A99;stroke:transparent}.epoch-theme-dark .epoch.category20 .arc.category6 path{fill:#995A99}.epoch-theme-dark .epoch.category20 .bar.category6{fill:#995A99}.epoch-theme-dark .epoch.category20 div.ref.category7{background-color:#78E8D3}.epoch-theme-dark .epoch.category20 .category7 .line{stroke:#78E8D3}.epoch-theme-dark .epoch.category20 .category7 .area,.epoch-theme-dark .epoch.category20 .category7 .dot{fill:#78E8D3;stroke:transparent}.epoch-theme-dark .epoch.category20 .arc.category7 path{fill:#78E8D3}.epoch-theme-dark .epoch.category20 .bar.category7{fill:#78E8D3}.epoch-theme-dark .epoch.category20 div.ref.category8{background-color:#4F998C}.epoch-theme-dark .epoch.category20 .category8 .line{stroke:#4F998C}.epoch-theme-dark .epoch.category20 .category8 .area,.epoch-theme-dark .epoch.category20 .category8 .dot{fill:#4F998C;stroke:transparent}.epoch-theme-dark .epoch.category20 .arc.category8 path{fill:#4F998C}.epoch-theme-dark .epoch.category20 .bar.category8{fill:#4F998C}.epoch-theme-dark .epoch.category20 div.ref.category9{background-color:#C2FF97}.epoch-theme-dark .epoch.category20 .category9 .line{stroke:#C2FF97}.epoch-theme-dark .epoch.category20 .category9 .area,.epoch-theme-dark .epoch.category20 .category9 .dot{fill:#C2FF97;stroke:transparent}.epoch-theme-dark .epoch.category20 .arc.category9 path{fill:#C2FF97}.epoch-theme-dark .epoch.category20 .bar.category9{fill:#C2FF97}.epoch-theme-dark .epoch.category20 div.ref.category10{background-color:#789E5E}.epoch-theme-dark .epoch.category20 .category10 .line{stroke:#789E5E}.epoch-theme-dark .epoch.category20 .category10 .area,.epoch-theme-dark .epoch.category20 .category10 .dot{fill:#789E5E;stroke:transparent}.epoch-theme-dark .epoch.category20 .arc.category10 path{fill:#789E5E}.epoch-theme-dark .epoch.category20 .bar.category10{fill:#789E5E}.epoch-theme-dark .epoch.category20 div.ref.category11{background-color:#B7BCD1}.epoch-theme-dark .epoch.category20 .category11 .line{stroke:#B7BCD1}.epoch-theme-dark .epoch.category20 .category11 .area,.epoch-theme-dark .epoch.category20 .category11 .dot{fill:#B7BCD1;stroke:transparent}.epoch-theme-dark .epoch.category20 .arc.category11 path{fill:#B7BCD1}.epoch-theme-dark .epoch.category20 .bar.category11{fill:#B7BCD1}.epoch-theme-dark .epoch.category20 div.ref.category12{background-color:#7F8391}.epoch-theme-dark .epoch.category20 .category12 .line{stroke:#7F8391}.epoch-theme-dark .epoch.category20 .category12 .area,.epoch-theme-dark .epoch.category20 .category12 .dot{fill:#7F8391;stroke:transparent}.epoch-theme-dark .epoch.category20 .arc.category12 path{fill:#7F8391}.epoch-theme-dark .epoch.category20 .bar.category12{fill:#7F8391}.epoch-theme-dark .epoch.category20 div.ref.category13{background-color:#CCB889}.epoch-theme-dark .epoch.category20 .category13 .line{stroke:#CCB889}.epoch-theme-dark .epoch.category20 .category13 .area,.epoch-theme-dark .epoch.category20 .category13 .dot{fill:#CCB889;stroke:transparent}.epoch-theme-dark .epoch.category20 .arc.category13 path{fill:#CCB889}.epoch-theme-dark .epoch.category20 .bar.category13{fill:#CCB889}.epoch-theme-dark .epoch.category20 div.ref.category14{background-color:#A1906B}.epoch-theme-dark .epoch.category20 .category14 .line{stroke:#A1906B}.epoch-theme-dark .epoch.category20 .category14 .area,.epoch-theme-dark .epoch.category20 .category14 .dot{fill:#A1906B;stroke:transparent}.epoch-theme-dark .epoch.category20 .arc.category14 path{fill:#A1906B}.epoch-theme-dark .epoch.category20 .bar.category14{fill:#A1906B}.epoch-theme-dark .epoch.category20 div.ref.category15{background-color:#F3DE88}.epoch-theme-dark .epoch.category20 .category15 .line{stroke:#F3DE88}.epoch-theme-dark .epoch.category20 .category15 .area,.epoch-theme-dark .epoch.category20 .category15 .dot{fill:#F3DE88;stroke:transparent}.epoch-theme-dark .epoch.category20 .arc.category15 path{fill:#F3DE88}.epoch-theme-dark .epoch.category20 .bar.category15{fill:#F3DE88}.epoch-theme-dark .epoch.category20 div.ref.category16{background-color:#A89A5E}.epoch-theme-dark .epoch.category20 .category16 .line{stroke:#A89A5E}.epoch-theme-dark .epoch.category20 .category16 .area,.epoch-theme-dark .epoch.category20 .category16 .dot{fill:#A89A5E;stroke:transparent}.epoch-theme-dark .epoch.category20 .arc.category16 path{fill:#A89A5E}.epoch-theme-dark .epoch.category20 .bar.category16{fill:#A89A5E}.epoch-theme-dark .epoch.category20 div.ref.category17{background-color:#FF857F}.epoch-theme-dark .epoch.category20 .category17 .line{stroke:#FF857F}.epoch-theme-dark .epoch.category20 .category17 .area,.epoch-theme-dark .epoch.category20 .category17 .dot{fill:#FF857F;stroke:transparent}.epoch-theme-dark .epoch.category20 .arc.category17 path{fill:#FF857F}.epoch-theme-dark .epoch.category20 .bar.category17{fill:#FF857F}.epoch-theme-dark .epoch.category20 div.ref.category18{background-color:#BA615D}.epoch-theme-dark .epoch.category20 .category18 .line{stroke:#BA615D}.epoch-theme-dark .epoch.category20 .category18 .area,.epoch-theme-dark .epoch.category20 .category18 .dot{fill:#BA615D;stroke:transparent}.epoch-theme-dark .epoch.category20 .arc.category18 path{fill:#BA615D}.epoch-theme-dark .epoch.category20 .bar.category18{fill:#BA615D}.epoch-theme-dark .epoch.category20 div.ref.category19{background-color:#A488FF}.epoch-theme-dark .epoch.category20 .category19 .line{stroke:#A488FF}.epoch-theme-dark .epoch.category20 .category19 .area,.epoch-theme-dark .epoch.category20 .category19 .dot{fill:#A488FF;stroke:transparent}.epoch-theme-dark .epoch.category20 .arc.category19 path{fill:#A488FF}.epoch-theme-dark .epoch.category20 .bar.category19{fill:#A488FF}.epoch-theme-dark .epoch.category20 div.ref.category20{background-color:#7662B8}.epoch-theme-dark .epoch.category20 .category20 .line{stroke:#7662B8}.epoch-theme-dark .epoch.category20 .category20 .area,.epoch-theme-dark .epoch.category20 .category20 .dot{fill:#7662B8;stroke:transparent}.epoch-theme-dark .epoch.category20 .arc.category20 path{fill:#7662B8}.epoch-theme-dark .epoch.category20 .bar.category20{fill:#7662B8}.epoch-theme-dark .epoch.category20b div.ref.category1{background-color:#909CFF}.epoch-theme-dark .epoch.category20b .category1 .line{stroke:#909CFF}.epoch-theme-dark .epoch.category20b .category1 .area,.epoch-theme-dark .epoch.category20b .category1 .dot{fill:#909CFF;stroke:transparent}.epoch-theme-dark .epoch.category20b .arc.category1 path{fill:#909CFF}.epoch-theme-dark .epoch.category20b .bar.category1{fill:#909CFF}.epoch-theme-dark .epoch.category20b div.ref.category2{background-color:#7680D1}.epoch-theme-dark .epoch.category20b .category2 .line{stroke:#7680D1}.epoch-theme-dark .epoch.category20b .category2 .area,.epoch-theme-dark .epoch.category20b .category2 .dot{fill:#7680D1;stroke:transparent}.epoch-theme-dark .epoch.category20b .arc.category2 path{fill:#7680D1}.epoch-theme-dark .epoch.category20b .bar.category2{fill:#7680D1}.epoch-theme-dark .epoch.category20b div.ref.category3{background-color:#656DB2}.epoch-theme-dark .epoch.category20b .category3 .line{stroke:#656DB2}.epoch-theme-dark .epoch.category20b .category3 .area,.epoch-theme-dark .epoch.category20b .category3 .dot{fill:#656DB2;stroke:transparent}.epoch-theme-dark .epoch.category20b .arc.category3 path{fill:#656DB2}.epoch-theme-dark .epoch.category20b .bar.category3{fill:#656DB2}.epoch-theme-dark .epoch.category20b div.ref.category4{background-color:#525992}.epoch-theme-dark .epoch.category20b .category4 .line{stroke:#525992}.epoch-theme-dark .epoch.category20b .category4 .area,.epoch-theme-dark .epoch.category20b .category4 .dot{fill:#525992;stroke:transparent}.epoch-theme-dark .epoch.category20b .arc.category4 path{fill:#525992}.epoch-theme-dark .epoch.category20b .bar.category4{fill:#525992}.epoch-theme-dark .epoch.category20b div.ref.category5{background-color:#FFAC89}.epoch-theme-dark .epoch.category20b .category5 .line{stroke:#FFAC89}.epoch-theme-dark .epoch.category20b .category5 .area,.epoch-theme-dark .epoch.category20b .category5 .dot{fill:#FFAC89;stroke:transparent}.epoch-theme-dark .epoch.category20b .arc.category5 path{fill:#FFAC89}.epoch-theme-dark .epoch.category20b .bar.category5{fill:#FFAC89}.epoch-theme-dark .epoch.category20b div.ref.category6{background-color:#D18D71}.epoch-theme-dark .epoch.category20b .category6 .line{stroke:#D18D71}.epoch-theme-dark .epoch.category20b .category6 .area,.epoch-theme-dark .epoch.category20b .category6 .dot{fill:#D18D71;stroke:transparent}.epoch-theme-dark .epoch.category20b .arc.category6 path{fill:#D18D71}.epoch-theme-dark .epoch.category20b .bar.category6{fill:#D18D71}.epoch-theme-dark .epoch.category20b div.ref.category7{background-color:#AB735C}.epoch-theme-dark .epoch.category20b .category7 .line{stroke:#AB735C}.epoch-theme-dark .epoch.category20b .category7 .area,.epoch-theme-dark .epoch.category20b .category7 .dot{fill:#AB735C;stroke:transparent}.epoch-theme-dark .epoch.category20b .arc.category7 path{fill:#AB735C}.epoch-theme-dark .epoch.category20b .bar.category7{fill:#AB735C}.epoch-theme-dark .epoch.category20b div.ref.category8{background-color:#92624E}.epoch-theme-dark .epoch.category20b .category8 .line{stroke:#92624E}.epoch-theme-dark .epoch.category20b .category8 .area,.epoch-theme-dark .epoch.category20b .category8 .dot{fill:#92624E;stroke:transparent}.epoch-theme-dark .epoch.category20b .arc.category8 path{fill:#92624E}.epoch-theme-dark .epoch.category20b .bar.category8{fill:#92624E}.epoch-theme-dark .epoch.category20b div.ref.category9{background-color:#E889E8}.epoch-theme-dark .epoch.category20b .category9 .line{stroke:#E889E8}.epoch-theme-dark .epoch.category20b .category9 .area,.epoch-theme-dark .epoch.category20b .category9 .dot{fill:#E889E8;stroke:transparent}.epoch-theme-dark .epoch.category20b .arc.category9 path{fill:#E889E8}.epoch-theme-dark .epoch.category20b .bar.category9{fill:#E889E8}.epoch-theme-dark .epoch.category20b div.ref.category10{background-color:#BA6EBA}.epoch-theme-dark .epoch.category20b .category10 .line{stroke:#BA6EBA}.epoch-theme-dark .epoch.category20b .category10 .area,.epoch-theme-dark .epoch.category20b .category10 .dot{fill:#BA6EBA;stroke:transparent}.epoch-theme-dark .epoch.category20b .arc.category10 path{fill:#BA6EBA}.epoch-theme-dark .epoch.category20b .bar.category10{fill:#BA6EBA}.epoch-theme-dark .epoch.category20b div.ref.category11{background-color:#9B5C9B}.epoch-theme-dark .epoch.category20b .category11 .line{stroke:#9B5C9B}.epoch-theme-dark .epoch.category20b .category11 .area,.epoch-theme-dark .epoch.category20b .category11 .dot{fill:#9B5C9B;stroke:transparent}.epoch-theme-dark .epoch.category20b .arc.category11 path{fill:#9B5C9B}.epoch-theme-dark .epoch.category20b .bar.category11{fill:#9B5C9B}.epoch-theme-dark .epoch.category20b div.ref.category12{background-color:#7B487B}.epoch-theme-dark .epoch.category20b .category12 .line{stroke:#7B487B}.epoch-theme-dark .epoch.category20b .category12 .area,.epoch-theme-dark .epoch.category20b .category12 .dot{fill:#7B487B;stroke:transparent}.epoch-theme-dark .epoch.category20b .arc.category12 path{fill:#7B487B}.epoch-theme-dark .epoch.category20b .bar.category12{fill:#7B487B}.epoch-theme-dark .epoch.category20b div.ref.category13{background-color:#78E8D3}.epoch-theme-dark .epoch.category20b .category13 .line{stroke:#78E8D3}.epoch-theme-dark .epoch.category20b .category13 .area,.epoch-theme-dark .epoch.category20b .category13 .dot{fill:#78E8D3;stroke:transparent}.epoch-theme-dark .epoch.category20b .arc.category13 path{fill:#78E8D3}.epoch-theme-dark .epoch.category20b .bar.category13{fill:#78E8D3}.epoch-theme-dark .epoch.category20b div.ref.category14{background-color:#60BAAA}.epoch-theme-dark .epoch.category20b .category14 .line{stroke:#60BAAA}.epoch-theme-dark .epoch.category20b .category14 .area,.epoch-theme-dark .epoch.category20b .category14 .dot{fill:#60BAAA;stroke:transparent}.epoch-theme-dark .epoch.category20b .arc.category14 path{fill:#60BAAA}.epoch-theme-dark .epoch.category20b .bar.category14{fill:#60BAAA}.epoch-theme-dark .epoch.category20b div.ref.category15{background-color:#509B8D}.epoch-theme-dark .epoch.category20b .category15 .line{stroke:#509B8D}.epoch-theme-dark .epoch.category20b .category15 .area,.epoch-theme-dark .epoch.category20b .category15 .dot{fill:#509B8D;stroke:transparent}.epoch-theme-dark .epoch.category20b .arc.category15 path{fill:#509B8D}.epoch-theme-dark .epoch.category20b .bar.category15{fill:#509B8D}.epoch-theme-dark .epoch.category20b div.ref.category16{background-color:#3F7B70}.epoch-theme-dark .epoch.category20b .category16 .line{stroke:#3F7B70}.epoch-theme-dark .epoch.category20b .category16 .area,.epoch-theme-dark .epoch.category20b .category16 .dot{fill:#3F7B70;stroke:transparent}.epoch-theme-dark .epoch.category20b .arc.category16 path{fill:#3F7B70}.epoch-theme-dark .epoch.category20b .bar.category16{fill:#3F7B70}.epoch-theme-dark .epoch.category20b div.ref.category17{background-color:#C2FF97}.epoch-theme-dark .epoch.category20b .category17 .line{stroke:#C2FF97}.epoch-theme-dark .epoch.category20b .category17 .area,.epoch-theme-dark .epoch.category20b .category17 .dot{fill:#C2FF97;stroke:transparent}.epoch-theme-dark .epoch.category20b .arc.category17 path{fill:#C2FF97}.epoch-theme-dark .epoch.category20b .bar.category17{fill:#C2FF97}.epoch-theme-dark .epoch.category20b div.ref.category18{background-color:#9FD17C}.epoch-theme-dark .epoch.category20b .category18 .line{stroke:#9FD17C}.epoch-theme-dark .epoch.category20b .category18 .area,.epoch-theme-dark .epoch.category20b .category18 .dot{fill:#9FD17C;stroke:transparent}.epoch-theme-dark .epoch.category20b .arc.category18 path{fill:#9FD17C}.epoch-theme-dark .epoch.category20b .bar.category18{fill:#9FD17C}.epoch-theme-dark .epoch.category20b div.ref.category19{background-color:#7DA361}.epoch-theme-dark .epoch.category20b .category19 .line{stroke:#7DA361}.epoch-theme-dark .epoch.category20b .category19 .area,.epoch-theme-dark .epoch.category20b .category19 .dot{fill:#7DA361;stroke:transparent}.epoch-theme-dark .epoch.category20b .arc.category19 path{fill:#7DA361}.epoch-theme-dark .epoch.category20b .bar.category19{fill:#7DA361}.epoch-theme-dark .epoch.category20b div.ref.category20{background-color:#65854E}.epoch-theme-dark .epoch.category20b .category20 .line{stroke:#65854E}.epoch-theme-dark .epoch.category20b .category20 .area,.epoch-theme-dark .epoch.category20b .category20 .dot{fill:#65854E;stroke:transparent}.epoch-theme-dark .epoch.category20b .arc.category20 path{fill:#65854E}.epoch-theme-dark .epoch.category20b .bar.category20{fill:#65854E}.epoch-theme-dark .epoch.category20c div.ref.category1{background-color:#B7BCD1}.epoch-theme-dark .epoch.category20c .category1 .line{stroke:#B7BCD1}.epoch-theme-dark .epoch.category20c .category1 .area,.epoch-theme-dark .epoch.category20c .category1 .dot{fill:#B7BCD1;stroke:transparent}.epoch-theme-dark .epoch.category20c .arc.category1 path{fill:#B7BCD1}.epoch-theme-dark .epoch.category20c .bar.category1{fill:#B7BCD1}.epoch-theme-dark .epoch.category20c div.ref.category2{background-color:#979DAD}.epoch-theme-dark .epoch.category20c .category2 .line{stroke:#979DAD}.epoch-theme-dark .epoch.category20c .category2 .area,.epoch-theme-dark .epoch.category20c .category2 .dot{fill:#979DAD;stroke:transparent}.epoch-theme-dark .epoch.category20c .arc.category2 path{fill:#979DAD}.epoch-theme-dark .epoch.category20c .bar.category2{fill:#979DAD}.epoch-theme-dark .epoch.category20c div.ref.category3{background-color:#6E717D}.epoch-theme-dark .epoch.category20c .category3 .line{stroke:#6E717D}.epoch-theme-dark .epoch.category20c .category3 .area,.epoch-theme-dark .epoch.category20c .category3 .dot{fill:#6E717D;stroke:transparent}.epoch-theme-dark .epoch.category20c .arc.category3 path{fill:#6E717D}.epoch-theme-dark .epoch.category20c .bar.category3{fill:#6E717D}.epoch-theme-dark .epoch.category20c div.ref.category4{background-color:#595C66}.epoch-theme-dark .epoch.category20c .category4 .line{stroke:#595C66}.epoch-theme-dark .epoch.category20c .category4 .area,.epoch-theme-dark .epoch.category20c .category4 .dot{fill:#595C66;stroke:transparent}.epoch-theme-dark .epoch.category20c .arc.category4 path{fill:#595C66}.epoch-theme-dark .epoch.category20c .bar.category4{fill:#595C66}.epoch-theme-dark .epoch.category20c div.ref.category5{background-color:#FF857F}.epoch-theme-dark .epoch.category20c .category5 .line{stroke:#FF857F}.epoch-theme-dark .epoch.category20c .category5 .area,.epoch-theme-dark .epoch.category20c .category5 .dot{fill:#FF857F;stroke:transparent}.epoch-theme-dark .epoch.category20c .arc.category5 path{fill:#FF857F}.epoch-theme-dark .epoch.category20c .bar.category5{fill:#FF857F}.epoch-theme-dark .epoch.category20c div.ref.category6{background-color:#DE746E}.epoch-theme-dark .epoch.category20c .category6 .line{stroke:#DE746E}.epoch-theme-dark .epoch.category20c .category6 .area,.epoch-theme-dark .epoch.category20c .category6 .dot{fill:#DE746E;stroke:transparent}.epoch-theme-dark .epoch.category20c .arc.category6 path{fill:#DE746E}.epoch-theme-dark .epoch.category20c .bar.category6{fill:#DE746E}.epoch-theme-dark .epoch.category20c div.ref.category7{background-color:#B55F5A}.epoch-theme-dark .epoch.category20c .category7 .line{stroke:#B55F5A}.epoch-theme-dark .epoch.category20c .category7 .area,.epoch-theme-dark .epoch.category20c .category7 .dot{fill:#B55F5A;stroke:transparent}.epoch-theme-dark .epoch.category20c .arc.category7 path{fill:#B55F5A}.epoch-theme-dark .epoch.category20c .bar.category7{fill:#B55F5A}.epoch-theme-dark .epoch.category20c div.ref.category8{background-color:#964E4B}.epoch-theme-dark .epoch.category20c .category8 .line{stroke:#964E4B}.epoch-theme-dark .epoch.category20c .category8 .area,.epoch-theme-dark .epoch.category20c .category8 .dot{fill:#964E4B;stroke:transparent}.epoch-theme-dark .epoch.category20c .arc.category8 path{fill:#964E4B}.epoch-theme-dark .epoch.category20c .bar.category8{fill:#964E4B}.epoch-theme-dark .epoch.category20c div.ref.category9{background-color:#F3DE88}.epoch-theme-dark .epoch.category20c .category9 .line{stroke:#F3DE88}.epoch-theme-dark .epoch.category20c .category9 .area,.epoch-theme-dark .epoch.category20c .category9 .dot{fill:#F3DE88;stroke:transparent}.epoch-theme-dark .epoch.category20c .arc.category9 path{fill:#F3DE88}.epoch-theme-dark .epoch.category20c .bar.category9{fill:#F3DE88}.epoch-theme-dark .epoch.category20c div.ref.category10{background-color:#DBC87B}.epoch-theme-dark .epoch.category20c .category10 .line{stroke:#DBC87B}.epoch-theme-dark .epoch.category20c .category10 .area,.epoch-theme-dark .epoch.category20c .category10 .dot{fill:#DBC87B;stroke:transparent}.epoch-theme-dark .epoch.category20c .arc.category10 path{fill:#DBC87B}.epoch-theme-dark .epoch.category20c .bar.category10{fill:#DBC87B}.epoch-theme-dark .epoch.category20c div.ref.category11{background-color:#BAAA68}.epoch-theme-dark .epoch.category20c .category11 .line{stroke:#BAAA68}.epoch-theme-dark .epoch.category20c .category11 .area,.epoch-theme-dark .epoch.category20c .category11 .dot{fill:#BAAA68;stroke:transparent}.epoch-theme-dark .epoch.category20c .arc.category11 path{fill:#BAAA68}.epoch-theme-dark .epoch.category20c .bar.category11{fill:#BAAA68}.epoch-theme-dark .epoch.category20c div.ref.category12{background-color:#918551}.epoch-theme-dark .epoch.category20c .category12 .line{stroke:#918551}.epoch-theme-dark .epoch.category20c .category12 .area,.epoch-theme-dark .epoch.category20c .category12 .dot{fill:#918551;stroke:transparent}.epoch-theme-dark .epoch.category20c .arc.category12 path{fill:#918551}.epoch-theme-dark .epoch.category20c .bar.category12{fill:#918551}.epoch-theme-dark .epoch.category20c div.ref.category13{background-color:#C9935E}.epoch-theme-dark .epoch.category20c .category13 .line{stroke:#C9935E}.epoch-theme-dark .epoch.category20c .category13 .area,.epoch-theme-dark .epoch.category20c .category13 .dot{fill:#C9935E;stroke:transparent}.epoch-theme-dark .epoch.category20c .arc.category13 path{fill:#C9935E}.epoch-theme-dark .epoch.category20c .bar.category13{fill:#C9935E}.epoch-theme-dark .epoch.category20c div.ref.category14{background-color:#B58455}.epoch-theme-dark .epoch.category20c .category14 .line{stroke:#B58455}.epoch-theme-dark .epoch.category20c .category14 .area,.epoch-theme-dark .epoch.category20c .category14 .dot{fill:#B58455;stroke:transparent}.epoch-theme-dark .epoch.category20c .arc.category14 path{fill:#B58455}.epoch-theme-dark .epoch.category20c .bar.category14{fill:#B58455}.epoch-theme-dark .epoch.category20c div.ref.category15{background-color:#997048}.epoch-theme-dark .epoch.category20c .category15 .line{stroke:#997048}.epoch-theme-dark .epoch.category20c .category15 .area,.epoch-theme-dark .epoch.category20c .category15 .dot{fill:#997048;stroke:transparent}.epoch-theme-dark .epoch.category20c .arc.category15 path{fill:#997048}.epoch-theme-dark .epoch.category20c .bar.category15{fill:#997048}.epoch-theme-dark .epoch.category20c div.ref.category16{background-color:#735436}.epoch-theme-dark .epoch.category20c .category16 .line{stroke:#735436}.epoch-theme-dark .epoch.category20c .category16 .area,.epoch-theme-dark .epoch.category20c .category16 .dot{fill:#735436;stroke:transparent}.epoch-theme-dark .epoch.category20c .arc.category16 path{fill:#735436}.epoch-theme-dark .epoch.category20c .bar.category16{fill:#735436}.epoch-theme-dark .epoch.category20c div.ref.category17{background-color:#A488FF}.epoch-theme-dark .epoch.category20c .category17 .line{stroke:#A488FF}.epoch-theme-dark .epoch.category20c .category17 .area,.epoch-theme-dark .epoch.category20c .category17 .dot{fill:#A488FF;stroke:transparent}.epoch-theme-dark .epoch.category20c .arc.category17 path{fill:#A488FF}.epoch-theme-dark .epoch.category20c .bar.category17{fill:#A488FF}.epoch-theme-dark .epoch.category20c div.ref.category18{background-color:#8670D1}.epoch-theme-dark .epoch.category20c .category18 .line{stroke:#8670D1}.epoch-theme-dark .epoch.category20c .category18 .area,.epoch-theme-dark .epoch.category20c .category18 .dot{fill:#8670D1;stroke:transparent}.epoch-theme-dark .epoch.category20c .arc.category18 path{fill:#8670D1}.epoch-theme-dark .epoch.category20c .bar.category18{fill:#8670D1}.epoch-theme-dark .epoch.category20c div.ref.category19{background-color:#705CAD}.epoch-theme-dark .epoch.category20c .category19 .line{stroke:#705CAD}.epoch-theme-dark .epoch.category20c .category19 .area,.epoch-theme-dark .epoch.category20c .category19 .dot{fill:#705CAD;stroke:transparent}.epoch-theme-dark .epoch.category20c .arc.category19 path{fill:#705CAD}.epoch-theme-dark .epoch.category20c .bar.category19{fill:#705CAD}.epoch-theme-dark .epoch.category20c div.ref.category20{background-color:#52447F}.epoch-theme-dark .epoch.category20c .category20 .line{stroke:#52447F}.epoch-theme-dark .epoch.category20c .category20 .area,.epoch-theme-dark .epoch.category20c .category20 .dot{fill:#52447F;stroke:transparent}.epoch-theme-dark .epoch.category20c .arc.category20 path{fill:#52447F}.epoch-theme-dark .epoch.category20c .bar.category20{fill:#52447F}
diff --git a/modules/http/static/epoch.js b/modules/http/static/epoch.js
new file mode 100644
index 0000000..98fc691
--- /dev/null
+++ b/modules/http/static/epoch.js
@@ -0,0 +1,4 @@
+/* SPDX-License-Identifier: MIT */
+var base,base1,base2,base3;null==window.Epoch&&(window.Epoch={}),null==(base=window.Epoch).Chart&&(base.Chart={}),null==(base1=window.Epoch).Time&&(base1.Time={}),null==(base2=window.Epoch).Util&&(base2.Util={}),null==(base3=window.Epoch).Formats&&(base3.Formats={}),Epoch.warn=function(t){return(console.warn||console.log)("Epoch Warning: "+t)},Epoch.exception=function(t){throw"Epoch Error: "+t},Epoch.TestContext=function(){function t(){var t,n,e;for(this._log=[],t=0,n=i.length;n>t;t++)e=i[t],this._makeFauxMethod(e)}var i;return i=["arc","arcTo","beginPath","bezierCurveTo","clearRect","clip","closePath","drawImage","fill","fillRect","fillText","moveTo","quadraticCurveTo","rect","restore","rotate","save","scale","scrollPathIntoView","setLineDash","setTransform","stroke","strokeRect","strokeText","transform","translate","lineTo"],t.prototype._makeFauxMethod=function(t){return this[t]=function(){var i;return this._log.push(t+"("+function(){var t,n,e;for(e=[],t=0,n=arguments.length;n>t;t++)i=arguments[t],e.push(i.toString());return e}.apply(this,arguments).join(",")+")")}},t.prototype.getImageData=function(){var t;return this._log.push("getImageData("+function(){var i,n,e;for(e=[],i=0,n=arguments.length;n>i;i++)t=arguments[i],e.push(t.toString());return e}.apply(this,arguments).join(",")+")"),{width:0,height:0,resolution:1,data:[]}},t}();var ref,typeFunction,hasProp={}.hasOwnProperty;typeFunction=function(t){return function(i){return Object.prototype.toString.call(i)==="[object "+t+"]"}},Epoch.isArray=null!=(ref=Array.isArray)?ref:typeFunction("Array"),Epoch.isObject=typeFunction("Object"),Epoch.isString=typeFunction("String"),Epoch.isFunction=typeFunction("Function"),Epoch.isNumber=typeFunction("Number"),Epoch.isElement=function(t){return"undefined"!=typeof HTMLElement&&null!==HTMLElement?t instanceof HTMLElement:null!=t&&Epoch.isObject(t)&&1===t.nodeType&&Epoch.isString(t.nodeName)},Epoch.isNonEmptyArray=function(t){return Epoch.isArray(t)&&t.length>0},Epoch.Util.copy=function(t){var i,n,e;if(null==t)return null;i={};for(n in t)hasProp.call(t,n)&&(e=t[n],i[n]=e);return i},Epoch.Util.defaults=function(t,i){var n,e,r,o,s,a;s=Epoch.Util.copy(t);for(r in i)hasProp.call(i,r)&&(a=i[r],o=t[r],e=i[r],n=Epoch.isObject(o)&&Epoch.isObject(e),null!=o&&null!=e?n&&!Epoch.isArray(o)?s[r]=Epoch.Util.defaults(o,e):s[r]=o:null!=o?s[r]=o:s[r]=e);return s},Epoch.Util.formatSI=function(t,i,n){var e,r,o,s,a;if(null==i&&(i=1),null==n&&(n=!1),1e3>t)return s=t,((0|s)!==s||n)&&(s=s.toFixed(i)),s;a=["K","M","G","T","P","E","Z","Y"];for(r in a)if(hasProp.call(a,r)&&(o=a[r],e=Math.pow(10,3*((0|r)+1)),t>=e&&t<Math.pow(10,3*((0|r)+2))))return s=t/e,(s%1!==0||n)&&(s=s.toFixed(i)),s+" "+o},Epoch.Util.formatBytes=function(t,i,n){var e,r,o,s,a;if(null==i&&(i=1),null==n&&(n=!1),1024>t)return s=t,(s%1!==0||n)&&(s=s.toFixed(i)),s+" B";a=["KB","MB","GB","TB","PB","EB","ZB","YB"];for(r in a)if(hasProp.call(a,r)&&(o=a[r],e=Math.pow(1024,(0|r)+1),t>=e&&t<Math.pow(1024,(0|r)+2)))return s=t/e,(s%1!==0||n)&&(s=s.toFixed(i)),s+" "+o},Epoch.Util.dasherize=function(t){return Epoch.Util.trim(t).replace("\n","").replace(/\s+/g,"-").toLowerCase()},Epoch.Util.domain=function(t,i){var n,e,r,o,s,a,h,p,l;for(null==i&&(i="x"),l={},n=[],r=0,a=t.length;a>r;r++)for(s=t[r],p=s.values,o=0,h=p.length;h>o;o++)e=p[o],null==l[e[i]]&&(n.push(e[i]),l[e[i]]=!0);return n},Epoch.Util.trim=function(t){return Epoch.isString(t)?t.replace(/^\s+/g,"").replace(/\s+$/g,""):null},Epoch.Util.getComputedStyle=function(t,i){return Epoch.isFunction(window.getComputedStyle)?window.getComputedStyle(t,i):null!=t.currentStyle?t.currentStyle:void 0},Epoch.Util.toRGBA=function(t,i){var n,e,r,o,s,a,h;return(o=t.match(/^rgba\(\s*([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\s*,\s*[0-9\.]+\)/))?(n=o[0],s=o[1],r=o[2],e=o[3],a="rgba("+s+","+r+","+e+","+i+")"):(h=d3.rgb(t))&&(a="rgba("+h.r+","+h.g+","+h.b+","+i+")"),a},Epoch.Util.getContext=function(t,i){return null==i&&(i="2d"),t.getContext(i)},Epoch.Events=function(){function t(){this._events={}}return t.prototype.on=function(t,i){var n;if(null!=i)return null==(n=this._events)[t]&&(n[t]=[]),this._events[t].push(i)},t.prototype.onAll=function(t){var i,n,e;if(Epoch.isObject(t)){e=[];for(n in t)hasProp.call(t,n)&&(i=t[n],e.push(this.on(n,i)));return e}},t.prototype.off=function(t,i){var n,e;if(Epoch.isArray(this._events[t])){if(null==i)return delete this._events[t];for(e=[];(n=this._events[t].indexOf(i))>=0;)e.push(this._events[t].splice(n,1));return e}},t.prototype.offAll=function(t){var i,n,e,r,o,s;if(Epoch.isArray(t)){for(o=[],n=0,e=t.length;e>n;n++)r=t[n],o.push(this.off(r));return o}if(Epoch.isObject(t)){s=[];for(r in t)hasProp.call(t,r)&&(i=t[r],s.push(this.off(r,i)));return s}},t.prototype.trigger=function(t){var i,n,e,r,o,s,a,h;if(null!=this._events[t]){for(i=function(){var t,i,n;for(n=[],r=t=1,i=arguments.length;i>=1?i>t:t>i;r=i>=1?++t:--t)n.push(arguments[r]);return n}.apply(this,arguments),a=this._events[t],h=[],o=0,s=a.length;s>o;o++)n=a[o],e=null,Epoch.isString(n)?e=this[n]:Epoch.isFunction(n)&&(e=n),null==e&&Epoch.exception("Callback for event '"+t+"' is not a function or reference to a method."),h.push(e.apply(this,i));return h}},t}(),Epoch.Util.flatten=function(t){var i,n,e,r,o,s,a;if(!Array.isArray(t))throw new Error("Epoch.Util.flatten only accepts arrays");for(a=[],e=0,o=t.length;o>e;e++)if(i=t[e],Array.isArray(i))for(r=0,s=i.length;s>r;r++)n=i[r],a.push(n);else a.push(i);return a},d3.selection.prototype.width=function(t){return null!=t&&Epoch.isString(t)?this.style("width",t):null!=t&&Epoch.isNumber(t)?this.style("width",t+"px"):+Epoch.Util.getComputedStyle(this.node(),null).width.replace("px","")},d3.selection.prototype.height=function(t){return null!=t&&Epoch.isString(t)?this.style("height",t):null!=t&&Epoch.isNumber(t)?this.style("height",t+"px"):+Epoch.Util.getComputedStyle(this.node(),null).height.replace("px","")};var d3Seconds;Epoch.Formats.regular=function(t){return t},Epoch.Formats.si=function(t){return Epoch.Util.formatSI(t)},Epoch.Formats.percent=function(t){return(100*t).toFixed(1)+"%"},Epoch.Formats.seconds=function(t){return d3Seconds(new Date(1e3*t))},d3Seconds=d3.time.format("%I:%M:%S %p"),Epoch.Formats.bytes=function(t){return Epoch.Util.formatBytes(t)};var extend=function(t,i){function n(){this.constructor=t}for(var e in i)hasProp.call(i,e)&&(t[e]=i[e]);return n.prototype=i.prototype,t.prototype=new n,t.__super__=i.prototype,t},hasProp={}.hasOwnProperty;Epoch.Chart.Base=function(t){function i(t){this.options=null!=t?t:{},i.__super__.constructor.call(this),this.options.model?(null!=this.options.model.hasData()?this.setData(this.options.model.getData(this.options.type,this.options.dataFormat)):this.setData(this.options.data||[]),this.options.model.on("data:updated",function(t){return function(){return t.setDataFromModel()}}(this))):this.setData(this.options.data||[]),null!=this.options.el&&(this.el=d3.select(this.options.el)),this.width=this.options.width,this.height=this.options.height,null!=this.el?(null==this.width&&(this.width=this.el.width()),null==this.height&&(this.height=this.el.height())):(null==this.width&&(this.width=n.width),null==this.height&&(this.height=n.height),this.el=d3.select(document.createElement("DIV")).attr("width",this.width).attr("height",this.height)),this.onAll(e)}var n,e;return extend(i,t),n={width:320,height:240,dataFormat:null},e={"option:width":"dimensionsChanged","option:height":"dimensionsChanged","layer:shown":"layerChanged","layer:hidden":"layerChanged"},i.prototype._getAllOptions=function(){return Epoch.Util.defaults({},this.options)},i.prototype._getOption=function(t){var i,n,e;for(i=t.split("."),n=this.options;i.length&&null!=n;)e=i.shift(),n=n[e];return n},i.prototype._setOption=function(t,i){var n,e,r;for(n=t.split("."),e=this.options;n.length;){if(r=n.shift(),0===n.length)return e[r]=arguments[1],void this.trigger("option:"+arguments[0]);null==e[r]&&(e[r]={}),e=e[r]}},i.prototype._setManyOptions=function(t,i){var n,e,r;null==i&&(i=""),e=[];for(n in t)hasProp.call(t,n)&&(r=t[n],Epoch.isObject(r)?e.push(this._setManyOptions(r,i+n+".")):e.push(this._setOption(i+n,r)));return e},i.prototype.option=function(){return 0===arguments.length?this._getAllOptions():1===arguments.length&&Epoch.isString(arguments[0])?this._getOption(arguments[0]):2===arguments.length&&Epoch.isString(arguments[0])?this._setOption(arguments[0],arguments[1]):1===arguments.length&&Epoch.isObject(arguments[0])?this._setManyOptions(arguments[0]):void 0},i.prototype.setDataFromModel=function(){var t;return t=this._prepareData(this.options.model.getData(this.options.type,this.options.dataFormat)),this.data=this._annotateLayers(t),this.draw()},i.prototype.setData=function(t,i){var n;return null==i&&(i={}),n=this._prepareData(this.rawData=this._formatData(t)),this.data=this._annotateLayers(n)},i.prototype._prepareData=function(t){return t},i.prototype._formatData=function(t){return Epoch.Data.formatData(t,this.options.type,this.options.dataFormat)},i.prototype._annotateLayers=function(t){var i,n,e,r,o;for(i=1,e=0,o=t.length;o>e;e++)r=t[e],n=["layer"],n.push("category"+i),r.category=i,r.visible=!0,null!=r.label&&n.push(Epoch.Util.dasherize(r.label)),r.className=n.join(" "),i++;return t},i.prototype._findLayer=function(t){var i,n,e,r,o,s;if(r=null,Epoch.isString(t)){for(s=this.data,i=0,o=s.length;o>i;i++)if(e=s[i],e.label===t){r=e;break}}else Epoch.isNumber(t)&&(n=parseInt(t),0>n||n>=this.data.length||(r=this.data[n]));return r},i.prototype.showLayer=function(t){var i;if((i=this._findLayer(t))&&!i.visible)return i.visible=!0,this.trigger("layer:shown")},i.prototype.hideLayer=function(t){var i;if((i=this._findLayer(t))&&i.visible)return i.visible=!1,this.trigger("layer:hidden")},i.prototype.toggleLayer=function(t){var i;if(i=this._findLayer(t))return i.visible=!i.visible,i.visible?this.trigger("layer:shown"):this.trigger("layer:hidden")},i.prototype.isLayerVisible=function(t){var i;return(i=this._findLayer(t))?i.visible:null},i.prototype.getVisibleLayers=function(){return this.data.filter(function(t){return t.visible})},i.prototype.update=function(t,i){return null==i&&(i=!0),this.setData(t),i?this.draw():void 0},i.prototype.draw=function(){return this.trigger("draw")},i.prototype._getScaleDomain=function(t){var i,n,e,r;return Array.isArray(t)?t:Epoch.isString(t)&&(i=this.getVisibleLayers().filter(function(i){return i.range===t}).map(function(t){return t.values}),null!=i&&i.length)?(r=Epoch.Util.flatten(i).map(function(t){return t.y}),e=function(t,i){return t>i?i:t},n=function(t,i){return i>t?i:t},[r.reduce(e,r[0]),r.reduce(n,r[0])]):Array.isArray(this.options.range)?this.options.range:this.options.range&&Array.isArray(this.options.range.left)?this.options.range.left:this.options.range&&Array.isArray(this.options.range.right)?this.options.range.right:this.extent(function(t){return t.y})},i.prototype.extent=function(t){return[d3.min(this.getVisibleLayers(),function(i){return d3.min(i.values,t)}),d3.max(this.getVisibleLayers(),function(i){return d3.max(i.values,t)})]},i.prototype.dimensionsChanged=function(){return this.width=this.option("width")||this.width,this.height=this.option("height")||this.height,this.el.width(this.width),this.el.height(this.height)},i.prototype.layerChanged=function(){return this.draw()},i}(Epoch.Events),Epoch.Chart.SVG=function(t){function i(t){this.options=null!=t?t:{},i.__super__.constructor.call(this,this.options),null!=this.el?this.svg=this.el.append("svg"):this.svg=d3.select(document.createElement("svg")),this.svg.attr({xmlns:"http://www.w3.org/2000/svg",width:this.width,height:this.height})}return extend(i,t),i.prototype.dimensionsChanged=function(){return i.__super__.dimensionsChanged.call(this),this.svg.attr("width",this.width).attr("height",this.height)},i}(Epoch.Chart.Base),Epoch.Chart.Canvas=function(t){function i(t){this.options=null!=t?t:{},i.__super__.constructor.call(this,this.options),null!=this.options.pixelRatio?this.pixelRatio=this.options.pixelRatio:null!=window.devicePixelRatio?this.pixelRatio=window.devicePixelRatio:this.pixelRatio=1,this.canvas=d3.select(document.createElement("CANVAS")),this.canvas.style({width:this.width+"px",height:this.height+"px"}),this.canvas.attr({width:this.getWidth(),height:this.getHeight()}),null!=this.el&&this.el.node().appendChild(this.canvas.node()),this.ctx=Epoch.Util.getContext(this.canvas.node())}return extend(i,t),i.prototype.getWidth=function(){return this.width*this.pixelRatio},i.prototype.getHeight=function(){return this.height*this.pixelRatio},i.prototype.clear=function(){return this.ctx.clearRect(0,0,this.getWidth(),this.getHeight())},i.prototype.getStyles=function(t){return Epoch.QueryCSS.getStyles(t,this.el)},i.prototype.dimensionsChanged=function(){return i.__super__.dimensionsChanged.call(this),this.canvas.style({width:this.width+"px",height:this.height+"px"}),this.canvas.attr({width:this.getWidth(),height:this.getHeight()})},i.prototype.redraw=function(){return Epoch.QueryCSS.purge(),this.draw()},i}(Epoch.Chart.Base);var QueryCSS;QueryCSS=function(){function t(){}var i,n,e,r,o,s,a;return e="_canvas_css_reference",i="data-epoch-container-id",r=0,s=function(){return"epoch-container-"+r++},n=/^([^#. ]+)?(#[^. ]+)?(\.[^# ]+)?$/,o=!1,a=function(t){var i,e,r,o,s,a;return o=t.match(n),null==o?Epoch.error("Query CSS cannot match given selector: "+t):(a=o[0],s=o[1],r=o[2],i=o[3],s=(null!=s?s:"div").toUpperCase(),e=document.createElement(s),null!=r&&(e.id=r.substr(1)),null!=i&&(e.className=i.substr(1).replace(/\./g," ")),e)},t.log=function(t){return o=t},t.cache={},t.styleList=["fill","stroke","stroke-width"],t.container=null,t.purge=function(){return t.cache={}},t.getContainer=function(){var i;return null!=t.container?t.container:(i=document.createElement("DIV"),i.id=e,document.body.appendChild(i),t.container=d3.select(i))},t.hash=function(t,n){var e;return e=n.attr(i),null==e&&(e=s(),n.attr(i,e)),e+"__"+t},t.getStyles=function(i,n){var r,s,h,p,l,u,c,g,d,f,y,m,v,x,_,w,k,b,E,C,A,S;if(s=t.hash(i,n),r=t.cache[s],null!=r)return r;for(x=[],v=n.node().parentNode;null!=v&&"body"!==v.nodeName.toLowerCase();)x.unshift(v),v=v.parentNode;for(x.push(n.node()),C=[],l=0,g=x.length;g>l;l++)p=x[l],E=p.nodeName.toLowerCase(),null!=p.id&&p.id.length>0&&(E+="#"+p.id),null!=p.className&&p.className.length>0&&(E+="."+Epoch.Util.trim(p.className).replace(/\s+/g,".")),C.push(E);for(C.push("svg"),w=Epoch.Util.trim(i).split(/\s+/),u=0,d=w.length;d>u;u++)S=w[u],C.push(S);for(o&&console.log(C),m=b=a(C.shift());C.length;)h=a(C.shift()),m.appendChild(h),m=h;for(o&&console.log(b),t.getContainer().node().appendChild(b),_=d3.select("#"+e+" "+i),A={},k=t.styleList,c=0,f=k.length;f>c;c++)y=k[c],A[y]=_.style(y);return t.cache[s]=A,t.getContainer().html(""),A},t}(),Epoch.QueryCSS=QueryCSS;var applyLayerLabel,base,hasProp={}.hasOwnProperty,slice=[].slice;null==Epoch.Data&&(Epoch.Data={}),null==(base=Epoch.Data).Format&&(base.Format={}),applyLayerLabel=function(t,i,n,e){var r,o,s,a,h;if(null==e&&(e=[]),h=[i.labels,i.autoLabels,i.keyLabels],a=h[0],r=h[1],o=h[2],null!=a&&Epoch.isArray(a)&&a.length>n)t.label=a[n];else if(o&&e.length>n)t.label=e[n];else if(r){for(s=[];n>=0;)s.push(String.fromCharCode(65+n%26)),n-=26;t.label=s.join("")}return t},Epoch.Data.Format.array=function(){var t,i,n,e,r,o,s;return i={x:function(t,i){return i},y:function(t,i){return t},time:function(t,i,n){return parseInt(n)+parseInt(i)},type:"area",autoLabels:!1,labels:[],startTime:parseInt((new Date).getTime()/1e3)},t=function(t,i,n){var e,r,o;if(r=[],Epoch.isArray(t[0]))for(e in t)hasProp.call(t,e)&&(o=t[e],r.push(applyLayerLabel({values:o.map(n)},i,parseInt(e))));else r.push(applyLayerLabel({values:t.map(n)},i,0));return r},e=function(i,n){return t(i,n,function(t,i){return{x:n.x(t,i),y:n.y(t,i)}})},s=function(i,n){return t(i,n,function(t,i){return{time:n.time(t,i,n.startTime),y:n.y(t,i)}})},r=function(i,n){return t(i,n,function(t,i){return{time:n.time(t,i,n.startTime),histogram:t}})},o=function(t,i){var n,e,r;e=[];for(n in t)if(hasProp.call(t,n)){if(r=t[n],!Epoch.isNumber(t[0]))return[];e.push(applyLayerLabel({value:r},i,n))}return e},n=function(t,n){var a;return null==t&&(t=[]),null==n&&(n={}),Epoch.isNonEmptyArray(t)?(a=Epoch.Util.defaults(n,i),"time.heatmap"===a.type?r(t,a):a.type.match(/^time\./)?s(t,a):"pie"===a.type?o(t,a):e(t,a)):[]},n.entry=function(t,e){var r,o,s,a,h,p,l,u;if(null==e&&(e={}),"time.gauge"===e.type)return null==t?0:(p=Epoch.Util.defaults(e,i),r=Epoch.isArray(t)?t[0]:t,p.y(r,0));if(null==t)return[];for(null==e.startTime&&(e.startTime=parseInt((new Date).getTime()/1e3)),o=Epoch.isArray(t)?t.map(function(t){return[t]}):[t],l=n(o,e),u=[],s=0,h=l.length;h>s;s++)a=l[s],u.push(a.values[0]);return u},n}(),Epoch.Data.Format.tuple=function(){var t,i,n;return i={x:function(t,i){return t},y:function(t,i){return t},time:function(t,i){return t},type:"area",autoLabels:!1,labels:[]},t=function(t,i,n){var e,r,o;if(!Epoch.isArray(t[0]))return[];if(r=[],Epoch.isArray(t[0][0]))for(e in t)hasProp.call(t,e)&&(o=t[e],r.push(applyLayerLabel({values:o.map(n)},i,parseInt(e))));else r.push(applyLayerLabel({values:t.map(n)},i,0));return r},n=function(n,e){var r;return null==n&&(n=[]),null==e&&(e={}),Epoch.isNonEmptyArray(n)?(r=Epoch.Util.defaults(e,i),"pie"===r.type||"time.heatmap"===r.type||"time.gauge"===r.type?[]:r.type.match(/^time\./)?t(n,r,function(t,i){return{time:r.time(t[0],parseInt(i)),y:r.y(t[1],parseInt(i))}}):t(n,r,function(t,i){return{x:r.x(t[0],parseInt(i)),y:r.y(t[1],parseInt(i))}})):[]},n.entry=function(t,i){var e,r,o,s,a,h;if(null==i&&(i={}),null==t)return[];for(null==i.startTime&&(i.startTime=parseInt((new Date).getTime()/1e3)),e=Epoch.isArray(t)&&Epoch.isArray(t[0])?t.map(function(t){return[t]}):[t],a=n(e,i),h=[],r=0,s=a.length;s>r;r++)o=a[r],h.push(o.values[0]);return h},n}(),Epoch.Data.Format.keyvalue=function(){var t,i,n,e,r;return i={type:"area",x:function(t,i){return parseInt(i)},y:function(t,i){return t},time:function(t,i,n){return parseInt(n)+parseInt(i)},labels:[],autoLabels:!1,keyLabels:!0,startTime:parseInt((new Date).getTime()/1e3)},t=function(t,i,n,e){var r,o,s,a,h,p;h=[];for(s in i)if(hasProp.call(i,s)){a=i[s],p=[];for(o in t)hasProp.call(t,o)&&(r=t[o],p.push(e(r,a,parseInt(o))));h.push(applyLayerLabel({values:p},n,parseInt(s),i))}return h},e=function(i,n,e){return t(i,n,e,function(t,i,n){var r;return r=Epoch.isString(e.x)?t[e.x]:e.x(t,parseInt(n)),{x:r,y:e.y(t[i],parseInt(n))}})},r=function(i,n,e,r){return null==r&&(r="y"),t(i,n,e,function(t,i,n){var o;return o=Epoch.isString(e.time)?{time:t[e.time]}:{time:e.time(t,parseInt(n),e.startTime)},o[r]=e.y(t[i],parseInt(n)),o})},n=function(t,n,o){var s;return null==t&&(t=[]),null==n&&(n=[]),null==o&&(o={}),Epoch.isNonEmptyArray(t)&&Epoch.isNonEmptyArray(n)?(s=Epoch.Util.defaults(o,i),"pie"===s.type||"time.gauge"===s.type?[]:"time.heatmap"===s.type?r(t,n,s,"histogram"):s.type.match(/^time\./)?r(t,n,s):e(t,n,s)):[]},n.entry=function(t,i,e){var r,o,s,a,h;if(null==i&&(i=[]),null==e&&(e={}),null==t||!Epoch.isNonEmptyArray(i))return[];for(null==e.startTime&&(e.startTime=parseInt((new Date).getTime()/1e3)),a=n([t],i,e),h=[],r=0,s=a.length;s>r;r++)o=a[r],h.push(o.values[0]);return h},n}(),Epoch.data=function(){var t,i,n;return n=arguments[0],t=2<=arguments.length?slice.call(arguments,1):[],null==(i=Epoch.Data.Format[n])?[]:i.apply(i,t)},Epoch.Data.formatData=function(t,i,n){var e,r,o,s,a,h;if(null==t&&(t=[]),!Epoch.isNonEmptyArray(t))return t;if(Epoch.isString(n))return a={type:i},Epoch.data(n,t,a);if(!Epoch.isObject(n))return t;if(null==n.name||!Epoch.isString(n.name))return t;if(null==Epoch.Data.Format[n.name])return t;if(r=[n.name,t],null!=n.arguments&&Epoch.isArray(n.arguments))for(h=n.arguments,o=0,s=h.length;s>o;o++)e=h[o],r.push(e);return null!=n.options?(a=n.options,null!=i&&null==a.type&&(a.type=i),r.push(a)):null!=i&&r.push({type:i}),Epoch.data.apply(Epoch.data,r)},Epoch.Data.formatEntry=function(t,i,n){var e,r,o,s,a,h,p,l;if(null==n)return t;if(Epoch.isString(n))return p={type:i},Epoch.Data.Format[n].entry(t,p);if(!Epoch.isObject(n))return t;if(null==n.name||!Epoch.isString(n.name))return t;if(null==Epoch.Data.Format[n.name])return t;if(o=Epoch.Util.defaults(n,{}),r=[t],null!=o.arguments&&Epoch.isArray(o.arguments))for(l=o.arguments,a=0,h=l.length;h>a;a++)e=l[a],r.push(e);return null!=o.options?(p=o.options,p.type=i,r.push(p)):null!=i&&r.push({type:i}),s=Epoch.Data.Format[o.name].entry,s.apply(s,r)};var extend=function(t,i){function n(){this.constructor=t}for(var e in i)hasProp.call(i,e)&&(t[e]=i[e]);return n.prototype=i.prototype,t.prototype=new n,t.__super__=i.prototype,t},hasProp={}.hasOwnProperty;Epoch.Model=function(t){function i(t){null==t&&(t={}),i.__super__.constructor.call(this),t=Epoch.Util.defaults(t,n),this.dataFormat=t.dataFormat,this.data=t.data,this.loading=!1}var n;return extend(i,t),n={dataFormat:null},i.prototype.setData=function(t){return this.data=t,this.trigger("data:updated")},i.prototype.push=function(t){return this.entry=t,this.trigger("data:push")},i.prototype.hasData=function(){return null!=this.data},i.prototype.getData=function(t,i){return null==i&&(i=this.dataFormat),Epoch.Data.formatData(this.data,t,i)},i.prototype.getNext=function(t,i){return null==i&&(i=this.dataFormat),Epoch.Data.formatEntry(this.entry,t,i)},i}(Epoch.Events);var extend=function(t,i){function n(){this.constructor=t}for(var e in i)hasProp.call(i,e)&&(t[e]=i[e]);return n.prototype=i.prototype,t.prototype=new n,t.__super__=i.prototype,t},hasProp={}.hasOwnProperty;Epoch.Chart.Plot=function(t){function i(t){var o,s,a,h,p;for(this.options=null!=t?t:{},o=Epoch.Util.copy(this.options.margins)||{},i.__super__.constructor.call(this,this.options=Epoch.Util.defaults(this.options,e)),this.margins={},p=["top","right","bottom","left"],s=0,a=p.length;a>s;s++)h=p[s],this.margins[h]=null!=this.options.margins&&null!=this.options.margins[h]?this.options.margins[h]:this.hasAxis(h)?n[h]:6;this.g=this.svg.append("g").attr("transform","translate("+this.margins.left+", "+this.margins.top+")"),this.onAll(r)}var n,e,r;return extend(i,t),e={domain:null,range:null,axes:["left","bottom"],ticks:{top:14,bottom:14,left:5,right:5},tickFormats:{top:Epoch.Formats.regular,bottom:Epoch.Formats.regular,left:Epoch.Formats.si,right:Epoch.Formats.si}},n={top:25,right:50,bottom:25,left:50},r={"option:margins.top":"marginsChanged","option:margins.right":"marginsChanged","option:margins.bottom":"marginsChanged","option:margins.left":"marginsChanged","option:axes":"axesChanged","option:ticks.top":"ticksChanged","option:ticks.right":"ticksChanged","option:ticks.bottom":"ticksChanged","option:ticks.left":"ticksChanged","option:tickFormats.top":"tickFormatsChanged","option:tickFormats.right":"tickFormatsChanged","option:tickFormats.bottom":"tickFormatsChanged","option:tickFormats.left":"tickFormatsChanged","option:domain":"domainChanged","option:range":"rangeChanged"},i.prototype.setTickFormat=function(t,i){return this.options.tickFormats[t]=i},i.prototype.hasAxis=function(t){return this.options.axes.indexOf(t)>-1},i.prototype.innerWidth=function(){return this.width-(this.margins.left+this.margins.right)},i.prototype.innerHeight=function(){return this.height-(this.margins.top+this.margins.bottom)},i.prototype.x=function(){var t,i;return t=null!=(i=this.options.domain)?i:this.extent(function(t){return t.x}),d3.scale.linear().domain(t).range([0,this.innerWidth()])},i.prototype.y=function(t){return d3.scale.linear().domain(this._getScaleDomain(t)).range([this.innerHeight(),0])},i.prototype.bottomAxis=function(){return d3.svg.axis().scale(this.x()).orient("bottom").ticks(this.options.ticks.bottom).tickFormat(this.options.tickFormats.bottom)},i.prototype.topAxis=function(){return d3.svg.axis().scale(this.x()).orient("top").ticks(this.options.ticks.top).tickFormat(this.options.tickFormats.top)},i.prototype.leftAxis=function(){var t;return t=this.options.range?this.options.range.left:null,d3.svg.axis().scale(this.y(t)).orient("left").ticks(this.options.ticks.left).tickFormat(this.options.tickFormats.left)},i.prototype.rightAxis=function(){var t;return t=this.options.range?this.options.range.right:null,d3.svg.axis().scale(this.y(t)).orient("right").ticks(this.options.ticks.right).tickFormat(this.options.tickFormats.right)},i.prototype.draw=function(){return this._axesDrawn?this._redrawAxes():this._drawAxes(),i.__super__.draw.call(this)},i.prototype._redrawAxes=function(){return this.hasAxis("bottom")&&this.g.selectAll(".x.axis.bottom").transition().duration(500).ease("linear").call(this.bottomAxis()),this.hasAxis("top")&&this.g.selectAll(".x.axis.top").transition().duration(500).ease("linear").call(this.topAxis()),this.hasAxis("left")&&this.g.selectAll(".y.axis.left").transition().duration(500).ease("linear").call(this.leftAxis()),this.hasAxis("right")?this.g.selectAll(".y.axis.right").transition().duration(500).ease("linear").call(this.rightAxis()):void 0},i.prototype._drawAxes=function(){return this.hasAxis("bottom")&&this.g.append("g").attr("class","x axis bottom").attr("transform","translate(0, "+this.innerHeight()+")").call(this.bottomAxis()),this.hasAxis("top")&&this.g.append("g").attr("class","x axis top").call(this.topAxis()),this.hasAxis("left")&&this.g.append("g").attr("class","y axis left").call(this.leftAxis()),this.hasAxis("right")&&this.g.append("g").attr("class","y axis right").attr("transform","translate("+this.innerWidth()+", 0)").call(this.rightAxis()),this._axesDrawn=!0},i.prototype.dimensionsChanged=function(){return i.__super__.dimensionsChanged.call(this),this.g.selectAll(".axis").remove(),this._axesDrawn=!1,this.draw()},i.prototype.marginsChanged=function(){var t,i,n;if(null!=this.options.margins){i=this.options.margins;for(t in i)hasProp.call(i,t)&&(n=i[t],null==n?this.margins[t]=6:this.margins[t]=n);return this.g.transition().duration(750).attr("transform","translate("+this.margins.left+", "+this.margins.top+")"),this.draw()}},i.prototype.axesChanged=function(){var t,i,e,r;for(r=["top","right","bottom","left"],t=0,i=r.length;i>t;t++)e=r[t],(null==this.options.margins||null==this.options.margins[e])&&(this.hasAxis(e)?this.margins[e]=n[e]:this.margins[e]=6);return this.g.transition().duration(750).attr("transform","translate("+this.margins.left+", "+this.margins.top+")"),this.g.selectAll(".axis").remove(),this._axesDrawn=!1,this.draw()},i.prototype.ticksChanged=function(){return this.draw()},i.prototype.tickFormatsChanged=function(){return this.draw()},i.prototype.domainChanged=function(){return this.draw()},i.prototype.rangeChanged=function(){return this.draw()},i}(Epoch.Chart.SVG);var extend=function(t,i){function n(){this.constructor=t}for(var e in i)hasProp.call(i,e)&&(t[e]=i[e]);return n.prototype=i.prototype,t.prototype=new n,t.__super__=i.prototype,t},hasProp={}.hasOwnProperty;Epoch.Chart.Area=function(t){function i(t){var n;this.options=null!=t?t:{},null==(n=this.options).type&&(n.type="area"),i.__super__.constructor.call(this,this.options),this.draw()}return extend(i,t),i.prototype.y=function(){var t,i,n,e,r,o,s,a,h;for(t=[],o=this.getVisibleLayers(),i=0,r=o.length;r>i;i++){e=o[i],s=e.values;for(n in s)hasProp.call(s,n)&&(h=s[n],null!=t[n]&&(t[n]+=h.y),null==t[n]&&(t[n]=h.y))}return d3.scale.linear().domain(null!=(a=this.options.range)?a:[0,d3.max(t)]).range([this.height-this.margins.top-this.margins.bottom,0])},i.prototype.draw=function(){var t,n,e,r,o,s,a,h;return o=[this.x(),this.y(),this.getVisibleLayers()],a=o[0],h=o[1],r=o[2],this.g.selectAll(".layer").remove(),0!==r.length?(t=d3.svg.area().x(function(t){return a(t.x)}).y0(function(t){return h(t.y0)}).y1(function(t){return h(t.y0+t.y)}),s=d3.layout.stack().values(function(t){return t.values}),n=s(r),e=this.g.selectAll(".layer").data(r,function(t){return t.category}),e.select(".area").attr("d",function(i){return t(i.values)}),e.enter().append("g").attr("class",function(t){return t.className}),e.append("path").attr("class","area").attr("d",function(i){return t(i.values)}),i.__super__.draw.call(this)):void 0},i}(Epoch.Chart.Plot);var extend=function(t,i){function n(){this.constructor=t}for(var e in i)hasProp.call(i,e)&&(t[e]=i[e]);return n.prototype=i.prototype,t.prototype=new n,t.__super__=i.prototype,t},hasProp={}.hasOwnProperty;Epoch.Chart.Bar=function(t){function i(t){this.options=null!=t?t:{},this._isHorizontal()?this.options=Epoch.Util.defaults(this.options,e):this.options=Epoch.Util.defaults(this.options,n),i.__super__.constructor.call(this,this.options),this.onAll(o),this.draw()}var n,e,r,o;return extend(i,t),n={type:"bar",style:"grouped",orientation:"vertical",padding:{bar:.08,group:.1},outerPadding:{bar:.08,group:.1}},r={tickFormats:{top:Epoch.Formats.si,bottom:Epoch.Formats.si,left:Epoch.Formats.regular,right:Epoch.Formats.regular}},e=Epoch.Util.defaults(r,n),o={"option:orientation":"orientationChanged","option:padding":"paddingChanged","option:outerPadding":"paddingChanged","option:padding:bar":"paddingChanged","option:padding:group":"paddingChanged","option:outerPadding:bar":"paddingChanged","option:outerPadding:group":"paddingChanged"},i.prototype._isVertical=function(){return"vertical"===this.options.orientation},i.prototype._isHorizontal=function(){return"horizontal"===this.options.orientation},i.prototype.x=function(){var t;return this._isVertical()?d3.scale.ordinal().domain(Epoch.Util.domain(this.getVisibleLayers())).rangeRoundBands([0,this.innerWidth()],this.options.padding.group,this.options.outerPadding.group):(t=this.extent(function(t){return t.y}),t[0]=Math.min(0,t[0]),d3.scale.linear().domain(t).range([0,this.width-this.margins.left-this.margins.right]))},i.prototype.x1=function(t){var i;return d3.scale.ordinal().domain(function(){var t,n,e,r;for(e=this.getVisibleLayers(),r=[],t=0,n=e.length;n>t;t++)i=e[t],r.push(i.category);return r}.call(this)).rangeRoundBands([0,t.rangeBand()],this.options.padding.bar,this.options.outerPadding.bar)},i.prototype.y=function(){var t;return this._isVertical()?(t=this.extent(function(t){return t.y}),t[0]=Math.min(0,t[0]),d3.scale.linear().domain(t).range([this.height-this.margins.top-this.margins.bottom,0])):d3.scale.ordinal().domain(Epoch.Util.domain(this.getVisibleLayers())).rangeRoundBands([0,this.innerHeight()],this.options.padding.group,this.options.outerPadding.group)},i.prototype.y1=function(t){var i;return d3.scale.ordinal().domain(function(){var t,n,e,r;for(e=this.getVisibleLayers(),r=[],t=0,n=e.length;n>t;t++)i=e[t],r.push(i.category);return r}.call(this)).rangeRoundBands([0,t.rangeBand()],this.options.padding.bar,this.options.outerPadding.bar)},i.prototype._remapData=function(){var t,i,n,e,r,o,s,a,h,p,l,u,c,g;for(h={},l=this.getVisibleLayers(),n=0,s=l.length;s>n;n++)for(o=l[n],t="bar "+o.className.replace(/\s*layer\s*/,""),u=o.values,r=0,a=u.length;a>r;r++)i=u[r],null==h[p=i.x]&&(h[p]=[]),h[i.x].push({label:o.category,y:i.y,className:t});c=[];for(e in h)hasProp.call(h,e)&&(g=h[e],c.push({group:e,values:g}));return c},i.prototype.draw=function(){return this._isVertical()?this._drawVertical():this._drawHorizontal(),i.__super__.draw.call(this)},i.prototype._drawVertical=function(){var t,i,n,e,r,o,s,a;return r=[this.x(),this.y()],o=r[0],a=r[1],s=this.x1(o),i=this.height-this.margins.top-this.margins.bottom,t=this._remapData(),n=this.g.selectAll(".layer").data(t,function(t){return t.group}),n.transition().duration(750).attr("transform",function(t){return"translate("+o(t.group)+", 0)"}),n.enter().append("g").attr("class","layer").attr("transform",function(t){return"translate("+o(t.group)+", 0)"}),e=n.selectAll("rect").data(function(t){return t.values}),e.attr("class",function(t){return t.className}),e.transition().duration(600).attr("x",function(t){return s(t.label)}).attr("y",function(t){return a(t.y)}).attr("width",s.rangeBand()).attr("height",function(t){return i-a(t.y)}),e.enter().append("rect").attr("class",function(t){return t.className}).attr("x",function(t){return s(t.label)}).attr("y",function(t){return a(t.y)}).attr("width",s.rangeBand()).attr("height",function(t){
+return i-a(t.y)}),e.exit().transition().duration(150).style("opacity","0").remove(),n.exit().transition().duration(750).style("opacity","0").remove()},i.prototype._drawHorizontal=function(){var t,i,n,e,r,o,s,a;return e=[this.x(),this.y()],o=e[0],s=e[1],a=this.y1(s),r=this.width-this.margins.left-this.margins.right,t=this._remapData(),i=this.g.selectAll(".layer").data(t,function(t){return t.group}),i.transition().duration(750).attr("transform",function(t){return"translate(0, "+s(t.group)+")"}),i.enter().append("g").attr("class","layer").attr("transform",function(t){return"translate(0, "+s(t.group)+")"}),n=i.selectAll("rect").data(function(t){return t.values}),n.attr("class",function(t){return t.className}),n.transition().duration(600).attr("x",function(t){return 0}).attr("y",function(t){return a(t.label)}).attr("height",a.rangeBand()).attr("width",function(t){return o(t.y)}),n.enter().append("rect").attr("class",function(t){return t.className}).attr("x",function(t){return 0}).attr("y",function(t){return a(t.label)}).attr("height",a.rangeBand()).attr("width",function(t){return o(t.y)}),n.exit().transition().duration(150).style("opacity","0").remove(),i.exit().transition().duration(750).style("opacity","0").remove()},i.prototype._getTickValues=function(t,i){var n,e,r,o;return null==i&&(i="x"),null==this.data[0]?[]:(o=this.data[0].values.length,e=0|Math.ceil(o/t),r=function(){var t,i,r,s;for(s=[],n=t=0,i=o,r=e;r>0?i>t:t>i;n=t+=r)s.push(this.data[0].values[n].x);return s}.call(this))},i.prototype.bottomAxis=function(){var t;return t=d3.svg.axis().scale(this.x()).orient("bottom").ticks(this.options.ticks.bottom).tickFormat(this.options.tickFormats.bottom),this._isVertical()&&null!=this.options.ticks.bottom&&t.tickValues(this._getTickValues(this.options.ticks.bottom)),t},i.prototype.topAxis=function(){var t;return t=d3.svg.axis().scale(this.x()).orient("top").ticks(this.options.ticks.top).tickFormat(this.options.tickFormats.top),this._isVertical()&&null!=this.options.ticks.top&&t.tickValues(this._getTickValues(this.options.ticks.top)),t},i.prototype.leftAxis=function(){var t;return t=d3.svg.axis().scale(this.y()).orient("left").ticks(this.options.ticks.left).tickFormat(this.options.tickFormats.left),this._isHorizontal()&&null!=this.options.ticks.left&&t.tickValues(this._getTickValues(this.options.ticks.left)),t},i.prototype.rightAxis=function(){var t;return t=d3.svg.axis().scale(this.y()).orient("right").ticks(this.options.ticks.right).tickFormat(this.options.tickFormats.right),this._isHorizontal()&&null!=this.options.ticks.right&&t.tickValues(this._getTickValues(this.options.ticks.right)),t},i.prototype.orientationChanged=function(){var t,i,n,e;return e=this.options.tickFormats.top,t=this.options.tickFormats.bottom,i=this.options.tickFormats.left,n=this.options.tickFormats.right,this.options.tickFormats.left=e,this.options.tickFormats.right=t,this.options.tickFormats.top=i,this.options.tickFormats.bottom=n,this.draw()},i.prototype.paddingChanged=function(){return this.draw()},i}(Epoch.Chart.Plot);var extend=function(t,i){function n(){this.constructor=t}for(var e in i)hasProp.call(i,e)&&(t[e]=i[e]);return n.prototype=i.prototype,t.prototype=new n,t.__super__=i.prototype,t},hasProp={}.hasOwnProperty;Epoch.Chart.Histogram=function(t){function i(t){this.options=null!=t?t:{},i.__super__.constructor.call(this,this.options=Epoch.Util.defaults(this.options,n)),this.onAll(e),this.draw()}var n,e;return extend(i,t),n={type:"histogram",domain:[0,100],bucketRange:[0,100],buckets:10,cutOutliers:!1},e={"option:bucketRange":"bucketRangeChanged","option:buckets":"bucketsChanged","option:cutOutliers":"cutOutliersChanged"},i.prototype._prepareData=function(t){var i,n,e,r,o,s,a,h,p,l,u,c,g,d,f;for(i=(this.options.bucketRange[1]-this.options.bucketRange[0])/this.options.buckets,c=[],o=0,p=t.length;p>o;o++){for(h=t[o],n=function(){var t,i,n;for(n=[],e=t=0,i=this.options.buckets;i>=0?i>t:t>i;e=i>=0?++t:--t)n.push(0);return n}.call(this),d=h.values,a=0,l=d.length;l>a;a++)u=d[a],r=parseInt((u.x-this.options.bucketRange[0])/i),this.options.cutOutliers&&(0>r||r>=this.options.buckets)||(0>r?r=0:r>=this.options.buckets&&(r=this.options.buckets-1),n[r]+=parseInt(u.y));g={values:n.map(function(t,n){return{x:parseInt(n)*i,y:t}})};for(s in h)hasProp.call(h,s)&&(f=h[s],"values"!==s&&(g[s]=f));c.push(g)}return c},i.prototype.resetData=function(){return this.setData(this.rawData),this.draw()},i.prototype.bucketRangeChanged=function(){return this.resetData()},i.prototype.bucketsChanged=function(){return this.resetData()},i.prototype.cutOutliersChanged=function(){return this.resetData()},i}(Epoch.Chart.Bar);var extend=function(t,i){function n(){this.constructor=t}for(var e in i)hasProp.call(i,e)&&(t[e]=i[e]);return n.prototype=i.prototype,t.prototype=new n,t.__super__=i.prototype,t},hasProp={}.hasOwnProperty;Epoch.Chart.Line=function(t){function i(t){var n;this.options=null!=t?t:{},null==(n=this.options).type&&(n.type="line"),i.__super__.constructor.call(this,this.options),this.draw()}return extend(i,t),i.prototype.line=function(t){var i,n,e;return i=[this.x(),this.y(t.range)],n=i[0],e=i[1],d3.svg.line().x(function(t){return n(t.x)}).y(function(t){return e(t.y)})},i.prototype.draw=function(){var t,n,e,r,o;return e=[this.x(),this.y(),this.getVisibleLayers()],r=e[0],o=e[1],n=e[2],0===n.length?this.g.selectAll(".layer").remove():(t=this.g.selectAll(".layer").data(n,function(t){return t.category}),t.select(".line").transition().duration(500).attr("d",function(t){return function(i){return t.line(i)(i.values)}}(this)),t.enter().append("g").attr("class",function(t){return t.className}).append("path").attr("class","line").attr("d",function(t){return function(i){return t.line(i)(i.values)}}(this)),t.exit().transition().duration(750).style("opacity","0").remove(),i.__super__.draw.call(this))},i}(Epoch.Chart.Plot);var extend=function(t,i){function n(){this.constructor=t}for(var e in i)hasProp.call(i,e)&&(t[e]=i[e]);return n.prototype=i.prototype,t.prototype=new n,t.__super__=i.prototype,t},hasProp={}.hasOwnProperty;Epoch.Chart.Pie=function(t){function i(t){this.options=null!=t?t:{},i.__super__.constructor.call(this,this.options=Epoch.Util.defaults(this.options,n)),this.pie=d3.layout.pie().sort(null).value(function(t){return t.value}),this.arc=d3.svg.arc().outerRadius(function(t){return function(){return Math.max(t.width,t.height)/2-t.options.margin}}(this)).innerRadius(function(t){return function(){return t.options.inner}}(this)),this.g=this.svg.append("g").attr("transform","translate("+this.width/2+", "+this.height/2+")"),this.on("option:margin","marginChanged"),this.on("option:inner","innerChanged"),this.draw()}var n;return extend(i,t),n={type:"pie",margin:10,inner:0},i.prototype.draw=function(){var t,n,e;return this.g.selectAll(".arc").remove(),t=this.g.selectAll(".arc").data(this.pie(this.getVisibleLayers()),function(t){return t.data.category}),t.enter().append("g").attr("class",function(t){return"arc pie "+t.data.className}),t.select("path").attr("d",this.arc),t.select("text").attr("transform",function(t){return function(i){return"translate("+t.arc.centroid(i)+")"}}(this)).text(function(t){return t.data.label||t.data.category}),n=t.append("path").attr("d",this.arc).each(function(t){return this._current=t}),e=t.append("text").attr("transform",function(t){return function(i){return"translate("+t.arc.centroid(i)+")"}}(this)).attr("dy",".35em").style("text-anchor","middle").text(function(t){return t.data.label||t.data.category}),i.__super__.draw.call(this)},i.prototype.marginChanged=function(){return this.draw()},i.prototype.innerChanged=function(){return this.draw()},i}(Epoch.Chart.SVG);var extend=function(t,i){function n(){this.constructor=t}for(var e in i)hasProp.call(i,e)&&(t[e]=i[e]);return n.prototype=i.prototype,t.prototype=new n,t.__super__=i.prototype,t},hasProp={}.hasOwnProperty;Epoch.Chart.Scatter=function(t){function i(t){this.options=null!=t?t:{},i.__super__.constructor.call(this,this.options=Epoch.Util.defaults(this.options,n)),this.on("option:radius","radiusChanged"),this.draw()}var n;return extend(i,t),n={type:"scatter",radius:3.5,axes:["top","bottom","left","right"]},i.prototype.draw=function(){var t,n,e,r,o,s,a;return o=[this.x(),this.y(),this.getVisibleLayers()],s=o[0],a=o[1],e=o[2],r=this.options.radius,0===e.length?this.g.selectAll(".layer").remove():(n=this.g.selectAll(".layer").data(e,function(t){return t.category}),n.enter().append("g").attr("class",function(t){return t.className}),t=n.selectAll(".dot").data(function(t){return t.values}),t.transition().duration(500).attr("r",function(t){var i;return null!=(i=t.r)?i:r}).attr("cx",function(t){return s(t.x)}).attr("cy",function(t){return a(t.y)}),t.enter().append("circle").attr("class","dot").attr("r",function(t){var i;return null!=(i=t.r)?i:r}).attr("cx",function(t){return s(t.x)}).attr("cy",function(t){return a(t.y)}),t.exit().transition().duration(750).style("opacity",0).remove(),n.exit().transition().duration(750).style("opacity",0).remove(),i.__super__.draw.call(this))},i.prototype.radiusChanged=function(){return this.draw()},i}(Epoch.Chart.Plot);var extend=function(t,i){function n(){this.constructor=t}for(var e in i)hasProp.call(i,e)&&(t[e]=i[e]);return n.prototype=i.prototype,t.prototype=new n,t.__super__=i.prototype,t},hasProp={}.hasOwnProperty;Epoch.Time.Plot=function(t){function i(t){var o,s,a,h,p;for(this.options=t,o=Epoch.Util.copy(this.options.margins)||{},i.__super__.constructor.call(this,this.options=Epoch.Util.defaults(this.options,e)),this.options.model&&this.options.model.on("data:push",function(t){return function(){return t.pushFromModel()}}(this)),this._queue=[],this.margins={},p=["top","right","bottom","left"],s=0,a=p.length;a>s;s++)h=p[s],this.margins[h]=null!=this.options.margins&&null!=this.options.margins[h]?this.options.margins[h]:this.hasAxis(h)?n[h]:6;this.svg=this.el.insert("svg",":first-child").attr("width",this.width).attr("height",this.height).style("z-index","1000"),"absolute"!==this.el.style("position")&&"relative"!==this.el.style("position")&&this.el.style("position","relative"),this.canvas.style({position:"absolute","z-index":"999"}),this._sizeCanvas(),this.animation={interval:null,active:!1,delta:function(t){return function(){return-(t.w()/t.options.fps)}}(this),tickDelta:function(t){return function(){return-(t.w()/t.pixelRatio/t.options.fps)}}(this),frame:0,duration:this.options.fps},this._buildAxes(),this.animationCallback=function(t){return function(){return t._animate()}}(this),this.onAll(r)}var n,e,r;return extend(i,t),e={range:null,fps:24,historySize:120,windowSize:40,queueSize:10,axes:["bottom"],ticks:{time:15,left:5,right:5},tickFormats:{top:Epoch.Formats.seconds,bottom:Epoch.Formats.seconds,left:Epoch.Formats.si,right:Epoch.Formats.si}},n={top:25,right:50,bottom:25,left:50},r={"option:margins":"marginsChanged","option:margins.top":"marginsChanged","option:margins.right":"marginsChanged","option:margins.bottom":"marginsChanged","option:margins.left":"marginsChanged","option:axes":"axesChanged","option:ticks":"ticksChanged","option:ticks.top":"ticksChanged","option:ticks.right":"ticksChanged","option:ticks.bottom":"ticksChanged","option:ticks.left":"ticksChanged","option:tickFormats":"tickFormatsChanged","option:tickFormats.top":"tickFormatsChanged","option:tickFormats.right":"tickFormatsChanged","option:tickFormats.bottom":"tickFormatsChanged","option:tickFormats.left":"tickFormatsChanged"},i.prototype._sizeCanvas=function(){return this.canvas.attr({width:this.innerWidth(),height:this.innerHeight()}),this.canvas.style({width:this.innerWidth()/this.pixelRatio+"px",height:this.innerHeight()/this.pixelRatio+"px",top:this.margins.top+"px",left:this.margins.left+"px"})},i.prototype._buildAxes=function(){return this.svg.selectAll(".axis").remove(),this._prepareTimeAxes(),this._prepareRangeAxes()},i.prototype._annotateLayers=function(t){var i,n,e,r,o,s;e=[];for(r in t)hasProp.call(t,r)&&(o=t[r],n=Epoch.Util.copy(o),s=Math.max(0,o.values.length-this.options.historySize),n.values=o.values.slice(s),i=["layer"],i.push("category"+((0|r)+1)),null!=o.label&&i.push(Epoch.Util.dasherize(o.label)),n.className=i.join(" "),n.visible=!0,e.push(n));return e},i.prototype._offsetX=function(){return 0},i.prototype._prepareTimeAxes=function(){var t;return this.hasAxis("bottom")&&(t=this.bottomAxis=this.svg.append("g").attr("class","x axis bottom canvas").attr("transform","translate("+(this.margins.left-1)+", "+(this.innerHeight()/this.pixelRatio+this.margins.top)+")"),t.append("path").attr("class","domain").attr("d","M0,0H"+(this.innerWidth()/this.pixelRatio+1))),this.hasAxis("top")&&(t=this.topAxis=this.svg.append("g").attr("class","x axis top canvas").attr("transform","translate("+(this.margins.left-1)+", "+this.margins.top+")"),t.append("path").attr("class","domain").attr("d","M0,0H"+(this.innerWidth()/this.pixelRatio+1))),this._resetInitialTimeTicks()},i.prototype._resetInitialTimeTicks=function(){var t,i,n,e,r,o,s,a,h;for(h=this.options.ticks.time,this._ticks=[],this._tickTimer=h,null!=this.bottomAxis&&this.bottomAxis.selectAll(".tick").remove(),null!=this.topAxis&&this.topAxis.selectAll(".tick").remove(),o=this.data,a=[],n=0,r=o.length;r>n;n++)if(e=o[n],Epoch.isNonEmptyArray(e.values)){for(s=[this.options.windowSize-1,e.values.length-1],t=s[0],i=s[1];t>=0&&i>=0;)this._pushTick(t,e.values[i].time,!1,!0),t-=h,i-=h;break}return a},i.prototype._prepareRangeAxes=function(){return this.hasAxis("left")&&this.svg.append("g").attr("class","y axis left").attr("transform","translate("+(this.margins.left-1)+", "+this.margins.top+")").call(this.leftAxis()),this.hasAxis("right")?this.svg.append("g").attr("class","y axis right").attr("transform","translate("+(this.width-this.margins.right)+", "+this.margins.top+")").call(this.rightAxis()):void 0},i.prototype.leftAxis=function(){var t,i;return i=this.options.ticks.left,t=d3.svg.axis().scale(this.ySvgLeft()).orient("left").tickFormat(this.options.tickFormats.left),2===i?t.tickValues(this.extent(function(t){return t.y})):t.ticks(i)},i.prototype.rightAxis=function(){var t,i,n;return i=this.extent(function(t){return t.y}),n=this.options.ticks.right,t=d3.svg.axis().scale(this.ySvgRight()).orient("right").tickFormat(this.options.tickFormats.right),2===n?t.tickValues(this.extent(function(t){return t.y})):t.ticks(n)},i.prototype.hasAxis=function(t){return this.options.axes.indexOf(t)>-1},i.prototype.innerWidth=function(){return(this.width-(this.margins.left+this.margins.right))*this.pixelRatio},i.prototype.innerHeight=function(){return(this.height-(this.margins.top+this.margins.bottom))*this.pixelRatio},i.prototype._prepareEntry=function(t){return t},i.prototype._prepareLayers=function(t){return t},i.prototype._startTransition=function(){return this.animation.active!==!0&&0!==this._queue.length?(this.trigger("transition:start"),this._shift(),this.animation.active=!0,this.animation.interval=setInterval(this.animationCallback,1e3/this.options.fps)):void 0},i.prototype._stopTransition=function(){var t,i,n,e,r,o,s;if(this.inTransition()){for(o=this.data,i=0,r=o.length;r>i;i++)e=o[i],e.values.length>this.options.windowSize+1&&e.values.shift();return s=[this._ticks[0],this._ticks[this._ticks.length-1]],t=s[0],n=s[1],null!=n&&n.enter&&(n.enter=!1,n.opacity=1),null!=t&&t.exit&&this._shiftTick(),this.animation.frame=0,this.trigger("transition:end"),this._queue.length>0?this._shift():(this.animation.active=!1,clearInterval(this.animation.interval))}},i.prototype.inTransition=function(){return this.animation.active},i.prototype.push=function(t){return t=this._prepareLayers(t),this._queue.length>this.options.queueSize&&this._queue.splice(this.options.queueSize,this._queue.length-this.options.queueSize),this._queue.length===this.options.queueSize?!1:(this._queue.push(t.map(function(t){return function(i){return t._prepareEntry(i)}}(this))),this.trigger("push"),this.inTransition()?void 0:this._startTransition())},i.prototype.pushFromModel=function(){return this.push(this.options.model.getNext(this.options.type,this.options.dataFormat))},i.prototype._shift=function(){var t,i,n,e;this.trigger("before:shift"),t=this._queue.shift(),e=this.data;for(i in e)hasProp.call(e,i)&&(n=e[i],n.values.push(t[i]));return this._updateTicks(t[0].time),this._transitionRangeAxes(),this.trigger("after:shift")},i.prototype._transitionRangeAxes=function(){return this.hasAxis("left")&&this.svg.selectAll(".y.axis.left").transition().duration(500).ease("linear").call(this.leftAxis()),this.hasAxis("right")?this.svg.selectAll(".y.axis.right").transition().duration(500).ease("linear").call(this.rightAxis()):void 0},i.prototype._animate=function(){return this.inTransition()?(++this.animation.frame===this.animation.duration&&this._stopTransition(),this.draw(this.animation.frame*this.animation.delta()),this._updateTimeAxes()):void 0},i.prototype.y=function(t){return d3.scale.linear().domain(this._getScaleDomain(t)).range([this.innerHeight(),0])},i.prototype.ySvg=function(t){return d3.scale.linear().domain(this._getScaleDomain(t)).range([this.innerHeight()/this.pixelRatio,0])},i.prototype.ySvgLeft=function(){return null!=this.options.range?this.ySvg(this.options.range.left):this.ySvg()},i.prototype.ySvgRight=function(){return null!=this.options.range?this.ySvg(this.options.range.right):this.ySvg()},i.prototype.w=function(){return this.innerWidth()/this.options.windowSize},i.prototype._updateTicks=function(t){return(this.hasAxis("top")||this.hasAxis("bottom"))&&(++this._tickTimer%this.options.ticks.time||this._pushTick(this.options.windowSize,t,!0),this._ticks.length>0)?this._ticks[0].x-this.w()/this.pixelRatio>=0?void 0:this._ticks[0].exit=!0:void 0},i.prototype._pushTick=function(t,i,n,e){var r,o;return null==n&&(n=!1),null==e&&(e=!1),this.hasAxis("top")||this.hasAxis("bottom")?(o={time:i,x:t*(this.w()/this.pixelRatio)+this._offsetX(),opacity:n?0:1,enter:n?!0:!1,exit:!1},this.hasAxis("bottom")&&(r=this.bottomAxis.append("g").attr("class","tick major").attr("transform","translate("+(o.x+1)+",0)").style("opacity",o.opacity),r.append("line").attr("y2",6),r.append("text").attr("text-anchor","middle").attr("dy",19).text(this.options.tickFormats.bottom(o.time)),o.bottomEl=r),this.hasAxis("top")&&(r=this.topAxis.append("g").attr("class","tick major").attr("transform","translate("+(o.x+1)+",0)").style("opacity",o.opacity),r.append("line").attr("y2",-6),r.append("text").attr("text-anchor","middle").attr("dy",-10).text(this.options.tickFormats.top(o.time)),o.topEl=r),e?this._ticks.unshift(o):this._ticks.push(o),o):void 0},i.prototype._shiftTick=function(){var t;if(this._ticks.length>0)return t=this._ticks.shift(),null!=t.topEl&&t.topEl.remove(),null!=t.bottomEl?t.bottomEl.remove():void 0},i.prototype._updateTimeAxes=function(){var t,i,n,e,r,o,s,a;if(this.hasAxis("top")||this.hasAxis("bottom")){for(r=[this.animation.tickDelta(),1/this.options.fps],i=r[0],t=r[1],o=this._ticks,s=[],n=0,e=o.length;e>n;n++)a=o[n],a.x+=i,this.hasAxis("bottom")&&a.bottomEl.attr("transform","translate("+(a.x+1)+",0)"),this.hasAxis("top")&&a.topEl.attr("transform","translate("+(a.x+1)+",0)"),a.enter?a.opacity+=t:a.exit&&(a.opacity-=t),a.enter||a.exit?(this.hasAxis("bottom")&&a.bottomEl.style("opacity",a.opacity),this.hasAxis("top")?s.push(a.topEl.style("opacity",a.opacity)):s.push(void 0)):s.push(void 0);return s}},i.prototype.draw=function(t){return null==t&&(t=0),i.__super__.draw.call(this)},i.prototype.dimensionsChanged=function(){return i.__super__.dimensionsChanged.call(this),this.svg.attr("width",this.width).attr("height",this.height),this._sizeCanvas(),this._buildAxes(),this.draw(this.animation.frame*this.animation.delta())},i.prototype.axesChanged=function(){var t,i,e,r;for(r=["top","right","bottom","left"],t=0,i=r.length;i>t;t++)e=r[t],(null==this.options.margins||null==this.options.margins[e])&&(this.hasAxis(e)?this.margins[e]=n[e]:this.margins[e]=6);return this._sizeCanvas(),this._buildAxes(),this.draw(this.animation.frame*this.animation.delta())},i.prototype.ticksChanged=function(){return this._resetInitialTimeTicks(),this._transitionRangeAxes(),this.draw(this.animation.frame*this.animation.delta())},i.prototype.tickFormatsChanged=function(){return this._resetInitialTimeTicks(),this._transitionRangeAxes(),this.draw(this.animation.frame*this.animation.delta())},i.prototype.marginsChanged=function(){var t,i,n;if(null!=this.options.margins){i=this.options.margins;for(t in i)hasProp.call(i,t)&&(n=i[t],null==n?this.margins[t]=6:this.margins[t]=n);return this._sizeCanvas(),this.draw(this.animation.frame*this.animation.delta())}},i.prototype.layerChanged=function(){return this._transitionRangeAxes(),i.__super__.layerChanged.call(this)},i}(Epoch.Chart.Canvas),Epoch.Time.Stack=function(t){function i(){return i.__super__.constructor.apply(this,arguments)}return extend(i,t),i.prototype._stackLayers=function(){var t,i,n,e,r,o,s;if((e=this.getVisibleLayers()).length>0){for(o=[],t=i=0,r=e[0].values.length;r>=0?r>i:i>r;t=r>=0?++i:--i)s=0,o.push(function(){var i,r,o;for(o=[],r=0,i=e.length;i>r;r++)n=e[r],n.values[t].y0=s,o.push(s+=n.values[t].y);return o}());return o}},i.prototype._prepareLayers=function(t){var i,n,e;e=0;for(n in t)hasProp.call(t,n)&&(i=t[n],this.data[n].visible&&(i.y0=e,e+=i.y));return t},i.prototype.setData=function(t){return i.__super__.setData.call(this,t),this._stackLayers()},i.prototype.extent=function(){var t,i,n,e,r,o,s,a,h,p;if(s=[0,this.getVisibleLayers()],o=s[0],e=s[1],!e.length)return[0,0];for(t=n=0,a=e[0].values.length;a>=0?a>n:n>a;t=a>=0?++n:--n){for(p=0,i=r=0,h=e.length;h>=0?h>r:r>h;i=h>=0?++r:--r)p+=e[i].values[t].y;p>o&&(o=p)}return[0,o]},i.prototype.layerChanged=function(){var t,n,e,r;for(this._stackLayers(),r=this._queue,t=0,e=r.length;e>t;t++)n=r[t],this._prepareLayers(n);return i.__super__.layerChanged.call(this)},i}(Epoch.Time.Plot);var extend=function(t,i){function n(){this.constructor=t}for(var e in i)hasProp.call(i,e)&&(t[e]=i[e]);return n.prototype=i.prototype,t.prototype=new n,t.__super__=i.prototype,t},hasProp={}.hasOwnProperty;Epoch.Time.Area=function(t){function i(t){var n;this.options=null!=t?t:{},null==(n=this.options).type&&(n.type="time.area"),i.__super__.constructor.call(this,this.options),this.draw()}return extend(i,t),i.prototype.setStyles=function(t){var i;return i=null!=t&&null!=t.className?this.getStyles("g."+t.className.replace(/\s/g,".")+" path.area"):this.getStyles("g path.area"),this.ctx.fillStyle=i.fill,null!=i.stroke&&(this.ctx.strokeStyle=i.stroke),null!=i["stroke-width"]?this.ctx.lineWidth=i["stroke-width"].replace("px",""):void 0},i.prototype._drawAreas=function(t){var i,n,e,r,o,s,a,h,p,l,u,c,g,d,f,y,m;for(null==t&&(t=0),u=[this.y(),this.w(),this.getVisibleLayers()],m=u[0],y=u[1],l=u[2],d=[],o=h=c=l.length-1;0>=c?0>=h:h>=0;o=0>=c?++h:--h)if(p=l[o]){for(this.setStyles(p),this.ctx.beginPath(),g=[this.options.windowSize,p.values.length,this.inTransition()],s=g[0],a=g[1],f=g[2],r=null;--s>=-2&&--a>=0;)e=p.values[a],i=[(s+1)*y+t,m(e.y+e.y0)],f&&(i[0]+=y),o===this.options.windowSize-1?this.ctx.moveTo.apply(this.ctx,i):this.ctx.lineTo.apply(this.ctx,i);n=f?(s+3)*y+t:(s+2)*y+t,this.ctx.lineTo(n,this.innerHeight()),this.ctx.lineTo(this.width*this.pixelRatio+y+t,this.innerHeight()),this.ctx.closePath(),d.push(this.ctx.fill())}return d},i.prototype._drawStrokes=function(t){var i,n,e,r,o,s,a,h,p,l,u,c,g,d,f;for(null==t&&(t=0),p=[this.y(),this.w(),this.getVisibleLayers()],f=p[0],d=p[1],h=p[2],c=[],r=s=l=h.length-1;0>=l?0>=s:s>=0;r=0>=l?++s:--s)if(a=h[r]){for(this.setStyles(a),this.ctx.beginPath(),u=[this.options.windowSize,a.values.length,this.inTransition()],r=u[0],o=u[1],g=u[2],e=null;--r>=-2&&--o>=0;)n=a.values[o],i=[(r+1)*d+t,f(n.y+n.y0)],g&&(i[0]+=d),r===this.options.windowSize-1?this.ctx.moveTo.apply(this.ctx,i):this.ctx.lineTo.apply(this.ctx,i);c.push(this.ctx.stroke())}return c},i.prototype.draw=function(t){return null==t&&(t=0),this.clear(),this._drawAreas(t),this._drawStrokes(t),i.__super__.draw.call(this)},i}(Epoch.Time.Stack);var extend=function(t,i){function n(){this.constructor=t}for(var e in i)hasProp.call(i,e)&&(t[e]=i[e]);return n.prototype=i.prototype,t.prototype=new n,t.__super__=i.prototype,t},hasProp={}.hasOwnProperty;Epoch.Time.Bar=function(t){function i(t){var n;this.options=null!=t?t:{},null==(n=this.options).type&&(n.type="time.bar"),i.__super__.constructor.call(this,this.options),this.draw()}return extend(i,t),i.prototype._offsetX=function(){return.5*this.w()/this.pixelRatio},i.prototype.setStyles=function(t){var i;return i=this.getStyles("rect.bar."+t.replace(/\s/g,".")),this.ctx.fillStyle=i.fill,null==i.stroke||"none"===i.stroke?this.ctx.strokeStyle="transparent":this.ctx.strokeStyle=i.stroke,null!=i["stroke-width"]?this.ctx.lineWidth=i["stroke-width"].replace("px",""):void 0},i.prototype.draw=function(t){var n,e,r,o,s,a,h,p,l,u,c,g,d,f,y,m,v,x;for(null==t&&(t=0),this.clear(),g=[this.y(),this.w()],x=g[0],v=g[1],d=this.getVisibleLayers(),p=0,c=d.length;c>p;p++)if(u=d[p],Epoch.isNonEmptyArray(u.values))for(this.setStyles(u.className),f=[this.options.windowSize,u.values.length,this.inTransition()],a=f[0],l=f[1],m=f[2],h=m?-1:0;--a>=h&&--l>=0;)e=u.values[l],y=[a*v+t,e.y,e.y0],r=y[0],o=y[1],s=y[2],m&&(r+=v),n=[r+1,x(o+s),v-2,this.innerHeight()-x(o)+.5*this.pixelRatio],this.ctx.fillRect.apply(this.ctx,n),this.ctx.strokeRect.apply(this.ctx,n);return i.__super__.draw.call(this)},i}(Epoch.Time.Stack);var extend=function(t,i){function n(){this.constructor=t}for(var e in i)hasProp.call(i,e)&&(t[e]=i[e]);return n.prototype=i.prototype,t.prototype=new n,t.__super__=i.prototype,t},hasProp={}.hasOwnProperty;Epoch.Time.Gauge=function(t){function i(t){this.options=null!=t?t:{},i.__super__.constructor.call(this,this.options=Epoch.Util.defaults(this.options,n)),this.value=this.options.value||0,this.options.model&&this.options.model.on("data:push",function(t){return function(){return t.pushFromModel()}}(this)),"absolute"!==this.el.style("position")&&"relative"!==this.el.style("position")&&this.el.style("position","relative"),this.svg=this.el.insert("svg",":first-child").attr("width",this.width).attr("height",this.height).attr("class","gauge-labels"),this.svg.style({position:"absolute","z-index":"1"}),this.svg.append("g").attr("transform","translate("+this.textX()+", "+this.textY()+")").append("text").attr("class","value").text(this.options.format(this.value)),this.animation={interval:null,active:!1,delta:0,target:0},this._animate=function(t){return function(){return Math.abs(t.animation.target-t.value)<Math.abs(t.animation.delta)?(t.value=t.animation.target,clearInterval(t.animation.interval),t.animation.active=!1):t.value+=t.animation.delta,t.svg.select("text.value").text(t.options.format(t.value)),t.draw()}}(this),this.onAll(e),this.draw()}var n,e;return extend(i,t),n={type:"time.gauge",domain:[0,1],ticks:10,tickSize:5,tickOffset:5,fps:34,format:Epoch.Formats.percent},e={"option:domain":"domainChanged","option:ticks":"ticksChanged","option:tickSize":"tickSizeChanged","option:tickOffset":"tickOffsetChanged","option:format":"formatChanged"},i.prototype.update=function(t){return this.animation.target=t,this.animation.delta=(t-this.value)/this.options.fps,this.animation.active?void 0:(this.animation.interval=setInterval(this._animate,1e3/this.options.fps),this.animation.active=!0)},i.prototype.push=function(t){return this.update(t)},i.prototype.pushFromModel=function(){var t;return t=this.options.model.getNext(this.options.type,this.options.dataFormat),this.update(t)},i.prototype.radius=function(){return this.getHeight()/1.58},i.prototype.centerX=function(){return this.getWidth()/2},i.prototype.centerY=function(){return.68*this.getHeight()},i.prototype.textX=function(){return this.width/2},i.prototype.textY=function(){return.48*this.height},i.prototype.getAngle=function(t){var i,n,e;return e=this.options.domain,i=e[0],n=e[1],(t-i)/(n-i)*(Math.PI+2*Math.PI/8)-Math.PI/2-Math.PI/8},i.prototype.setStyles=function(t){var i;return i=this.getStyles(t),this.ctx.fillStyle=i.fill,this.ctx.strokeStyle=i.stroke,null!=i["stroke-width"]?this.ctx.lineWidth=i["stroke-width"].replace("px",""):void 0},i.prototype.draw=function(){var t,n,e,r,o,s,a,h,p,l,u,c,g,d,f,y,m,v,x;for(h=[this.centerX(),this.centerY(),this.radius()],e=h[0],r=h[1],a=h[2],p=[this.options.tickOffset,this.options.tickSize],d=p[0],f=p[1],this.clear(),g=d3.scale.linear().domain([0,this.options.ticks]).range([-1.125*Math.PI,Math.PI/8]),this.setStyles(".epoch .gauge .tick"),this.ctx.beginPath(),o=s=0,l=this.options.ticks;l>=0?l>=s:s>=l;o=l>=0?++s:--s)t=g(o),u=[Math.cos(t),Math.sin(t)],n=u[0],c=u[1],y=n*(a-d)+e,v=c*(a-d)+r,m=n*(a-d-f)+e,x=c*(a-d-f)+r,this.ctx.moveTo(y,v),this.ctx.lineTo(m,x);return this.ctx.stroke(),this.setStyles(".epoch .gauge .arc.outer"),this.ctx.beginPath(),this.ctx.arc(e,r,a,-1.125*Math.PI,1/8*Math.PI,!1),this.ctx.stroke(),this.setStyles(".epoch .gauge .arc.inner"),this.ctx.beginPath(),this.ctx.arc(e,r,a-10,-1.125*Math.PI,1/8*Math.PI,!1),this.ctx.stroke(),this.drawNeedle(),i.__super__.draw.call(this)},i.prototype.drawNeedle=function(){var t,i,n,e,r;return r=[this.centerX(),this.centerY(),this.radius()],t=r[0],i=r[1],n=r[2],e=this.value/this.options.domain[1],this.setStyles(".epoch .gauge .needle"),this.ctx.beginPath(),this.ctx.save(),this.ctx.translate(t,i),this.ctx.rotate(this.getAngle(this.value)),this.ctx.moveTo(4*this.pixelRatio,0),this.ctx.lineTo(-4*this.pixelRatio,0),this.ctx.lineTo(-1*this.pixelRatio,19-n),this.ctx.lineTo(1,19-n),this.ctx.fill(),this.setStyles(".epoch .gauge .needle-base"),this.ctx.beginPath(),this.ctx.arc(0,0,this.getWidth()/25,0,2*Math.PI),this.ctx.fill(),this.ctx.restore()},i.prototype.domainChanged=function(){return this.draw()},i.prototype.ticksChanged=function(){return this.draw()},i.prototype.tickSizeChanged=function(){return this.draw()},i.prototype.tickOffsetChanged=function(){return this.draw()},i.prototype.formatChanged=function(){return this.svg.select("text.value").text(this.options.format(this.value))},i}(Epoch.Chart.Canvas);var extend=function(t,i){function n(){this.constructor=t}for(var e in i)hasProp.call(i,e)&&(t[e]=i[e]);return n.prototype=i.prototype,t.prototype=new n,t.__super__=i.prototype,t},hasProp={}.hasOwnProperty;Epoch.Time.Heatmap=function(t){function i(t){this.options=null!=t?t:{},i.__super__.constructor.call(this,this.options=Epoch.Util.defaults(this.options,e)),this._setOpacityFunction(),this._setupPaintCanvas(),this.onAll(r),this.draw()}var n,e,r;return extend(i,t),e={type:"time.heatmap",buckets:10,bucketRange:[0,100],opacity:"linear",bucketPadding:2,paintZeroValues:!1,cutOutliers:!1},n={root:function(t,i){return Math.pow(t/i,.5)},linear:function(t,i){return t/i},quadratic:function(t,i){return Math.pow(t/i,2)},cubic:function(t,i){return Math.pow(t/i,3)},quartic:function(t,i){return Math.pow(t/i,4)},quintic:function(t,i){return Math.pow(t/i,5)}},r={"option:buckets":"bucketsChanged","option:bucketRange":"bucketRangeChanged","option:opacity":"opacityChanged","option:bucketPadding":"bucketPaddingChanged","option:paintZeroValues":"paintZeroValuesChanged","option:cutOutliers":"cutOutliersChanged"},i.prototype._setOpacityFunction=function(){return Epoch.isString(this.options.opacity)?(this._opacityFn=n[this.options.opacity],null==this._opacityFn?Epoch.exception("Unknown coloring function provided '"+this.options.opacity+"'"):void 0):Epoch.isFunction(this.options.opacity)?this._opacityFn=this.options.opacity:Epoch.exception("Unknown type for provided coloring function.")},i.prototype.setData=function(t){var n,e,r,o,s;for(i.__super__.setData.call(this,t),o=this.data,s=[],n=0,r=o.length;r>n;n++)e=o[n],s.push(e.values=e.values.map(function(t){return function(i){return t._prepareEntry(i)}}(this)));return s},i.prototype._getBuckets=function(t){var i,n,e,r,o,s,a,h,p;s={time:t.time,max:0,buckets:function(){var t,i,n;for(n=[],e=t=0,i=this.options.buckets;i>=0?i>t:t>i;e=i>=0?++t:--t)n.push(0);return n}.call(this)},i=(this.options.bucketRange[1]-this.options.bucketRange[0])/this.options.buckets,
+a=t.histogram;for(p in a)hasProp.call(a,p)&&(n=a[p],r=parseInt((p-this.options.bucketRange[0])/i),this.options.cutOutliers&&(0>r||r>=this.options.buckets)||(0>r?r=0:r>=this.options.buckets&&(r=this.options.buckets-1),s.buckets[r]+=parseInt(n)));for(e=o=0,h=s.buckets.length;h>=0?h>o:o>h;e=h>=0?++o:--o)s.max=Math.max(s.max,s.buckets[e]);return s},i.prototype.y=function(){return d3.scale.linear().domain(this.options.bucketRange).range([this.innerHeight(),0])},i.prototype.ySvg=function(){return d3.scale.linear().domain(this.options.bucketRange).range([this.innerHeight()/this.pixelRatio,0])},i.prototype.h=function(){return this.innerHeight()/this.options.buckets},i.prototype._offsetX=function(){return.5*this.w()/this.pixelRatio},i.prototype._setupPaintCanvas=function(){return this.paintWidth=(this.options.windowSize+1)*this.w(),this.paintHeight=this.height*this.pixelRatio,this.paint=document.createElement("CANVAS"),this.paint.width=this.paintWidth,this.paint.height=this.paintHeight,this.p=Epoch.Util.getContext(this.paint),this.redraw(),this.on("after:shift","_paintEntry"),this.on("transition:end","_shiftPaintCanvas"),this.on("transition:end",function(t){return function(){return t.draw(t.animation.frame*t.animation.delta())}}(this))},i.prototype.redraw=function(){var t,i;if(Epoch.isNonEmptyArray(this.data)&&Epoch.isNonEmptyArray(this.data[0].values)){for(i=this.data[0].values.length,t=this.options.windowSize,this.inTransition()&&t++;--i>=0&&--t>=0;)this._paintEntry(i,t);return this.draw(this.animation.frame*this.animation.delta())}},i.prototype._computeColor=function(t,i,n){return Epoch.Util.toRGBA(n,this._opacityFn(t,i))},i.prototype._paintEntry=function(t,i){var n,e,r,o,s,a,h,p,l,u,c,g,d,f,y,m,v,x,_,w,k,b,E,C;for(null==t&&(t=null),null==i&&(i=null),v=[this.w(),this.h()],E=v[0],h=v[1],null==t&&(t=this.data[0].values.length-1),null==i&&(i=this.options.windowSize),s=[],e=function(){var t,i,n;for(n=[],p=t=0,i=this.options.buckets;i>=0?i>t:t>i;p=i>=0?++t:--t)n.push(0);return n}.call(this),m=0,x=this.getVisibleLayers(),u=0,g=x.length;g>u;u++){c=x[u],a=this._getBuckets(c.values[t]),_=a.buckets;for(n in _)hasProp.call(_,n)&&(o=_[n],e[n]+=o);m+=a.max,k=this.getStyles("."+c.className.split(" ").join(".")+" rect.bucket"),a.color=k.fill,s.push(a)}C=i*E,this.p.clearRect(C,0,E,this.paintHeight),l=this.options.buckets,w=[];for(n in e)if(hasProp.call(e,n)){for(b=e[n],r=this._avgLab(s,n),y=0,f=0,d=s.length;d>f;f++)a=s[f],y+=a.buckets[n]/b*m;(b>0||this.options.paintZeroValues)&&(this.p.fillStyle=this._computeColor(b,y,r),this.p.fillRect(C,(l-1)*h,E-this.options.bucketPadding,h-this.options.bucketPadding)),w.push(l--)}return w},i.prototype._shiftPaintCanvas=function(){var t;return t=this.p.getImageData(this.w(),0,this.paintWidth-this.w(),this.paintHeight),this.p.putImageData(t,0,0)},i.prototype._avgLab=function(t,i){var n,e,r,o,s,a,h,p,l,u,c,g;for(u=[0,0,0,0],h=u[0],n=u[1],e=u[2],c=u[3],a=0,p=t.length;p>a;a++)o=t[a],null!=o.buckets[i]&&(c+=o.buckets[i]);for(s in t)hasProp.call(t,s)&&(o=t[s],g=null!=o.buckets[i]?0|o.buckets[i]:0,l=g/c,r=d3.lab(o.color),h+=l*r.l,n+=l*r.a,e+=l*r.b);return d3.lab(h,n,e).toString()},i.prototype.draw=function(t){return null==t&&(t=0),this.clear(),this.ctx.drawImage(this.paint,t,0),i.__super__.draw.call(this)},i.prototype.bucketsChanged=function(){return this.redraw()},i.prototype.bucketRangeChanged=function(){return this._transitionRangeAxes(),this.redraw()},i.prototype.opacityChanged=function(){return this._setOpacityFunction(),this.redraw()},i.prototype.bucketPaddingChanged=function(){return this.redraw()},i.prototype.paintZeroValuesChanged=function(){return this.redraw()},i.prototype.cutOutliersChanged=function(){return this.redraw()},i.prototype.layerChanged=function(){return this.redraw()},i}(Epoch.Time.Plot);var extend=function(t,i){function n(){this.constructor=t}for(var e in i)hasProp.call(i,e)&&(t[e]=i[e]);return n.prototype=i.prototype,t.prototype=new n,t.__super__=i.prototype,t},hasProp={}.hasOwnProperty;Epoch.Time.Line=function(t){function i(t){var n;this.options=null!=t?t:{},null==(n=this.options).type&&(n.type="time.line"),i.__super__.constructor.call(this,this.options),this.draw()}return extend(i,t),i.prototype.setStyles=function(t){var i;return i=this.getStyles("g."+t.replace(/\s/g,".")+" path.line"),this.ctx.fillStyle=i.fill,this.ctx.strokeStyle=i.stroke,this.ctx.lineWidth=this.pixelRatio*i["stroke-width"].replace("px","")},i.prototype.draw=function(t){var n,e,r,o,s,a,h,p,l,u,c,g;for(null==t&&(t=0),this.clear(),c=this.w(),p=this.getVisibleLayers(),o=0,h=p.length;h>o;o++)if(a=p[o],Epoch.isNonEmptyArray(a.values)){for(this.setStyles(a.className),this.ctx.beginPath(),g=this.y(a.range),l=[this.options.windowSize,a.values.length,this.inTransition()],r=l[0],s=l[1],u=l[2];--r>=-2&&--s>=0;)e=a.values[s],n=[(r+1)*c+t,g(e.y)],u&&(n[0]+=c),r===this.options.windowSize-1?this.ctx.moveTo.apply(this.ctx,n):this.ctx.lineTo.apply(this.ctx,n);this.ctx.stroke()}return i.__super__.draw.call(this)},i}(Epoch.Time.Plot),Epoch._typeMap={area:Epoch.Chart.Area,bar:Epoch.Chart.Bar,line:Epoch.Chart.Line,pie:Epoch.Chart.Pie,scatter:Epoch.Chart.Scatter,histogram:Epoch.Chart.Histogram,"time.area":Epoch.Time.Area,"time.bar":Epoch.Time.Bar,"time.line":Epoch.Time.Line,"time.gauge":Epoch.Time.Gauge,"time.heatmap":Epoch.Time.Heatmap};var jQueryModule;jQueryModule=function(t){var i;return i="epoch-chart",t.fn.epoch=function(t){var n,e;return t.el=this.get(0),null==(n=this.data(i))&&(e=Epoch._typeMap[t.type],null==e&&Epoch.exception("Unknown chart type '"+t.type+"'"),this.data(i,n=new e(t))),n}},null!=window.jQuery&&jQueryModule(jQuery);var MooToolsModule;MooToolsModule=function(){var t;return t="epoch-chart",Element.implement("epoch",function(i){var n,e,r;return r=$$(this),null==(n=r.retrieve(t)[0])&&(i.el=this,e=Epoch._typeMap[i.type],null==e&&Epoch.exception("Unknown chart type '"+i.type+"'"),r.store(t,n=new e(i))),n})},null!=window.MooTools&&MooToolsModule();var zeptoModule;zeptoModule=function(t){var i,n,e,r;return i="epoch-chart",e={},n=0,r=function(){return i+"-"+ ++n},t.extend(t.fn,{epoch:function(t){var n,o,s;return null!=(o=this.data(i))?e[o]:(t.el=this.get(0),s=Epoch._typeMap[t.type],null==s&&Epoch.exception("Unknown chart type '"+t.type+"'"),this.data(i,o=r()),n=new s(t),e[o]=n,n)}})},null!=window.Zepto&&zeptoModule(Zepto);
diff --git a/modules/http/static/epoch.spdx b/modules/http/static/epoch.spdx
new file mode 100644
index 0000000..c01b497
--- /dev/null
+++ b/modules/http/static/epoch.spdx
@@ -0,0 +1,11 @@
+SPDXVersion: SPDX-2.1
+DataLicense: CC0-1.0
+SPDXID: SPDXRef-DOCUMENT
+DocumentName: epoch
+DocumentNamespace: http://spdx.org/spdxdocs/spdx-v2.1-4efd8b6e-174f-48e4-a228-3059f191c7e8
+
+PackageName: epoch
+PackageVersion: 0.8.3
+PackageDownloadLocation: git+https://github.com/epochjs/epoch.git@47aef0a5aa8458bdd5011d108ab92a560215bc57#dist/
+PackageOriginator: Organization: Fastly
+PackageLicenseDeclared: MIT
diff --git a/modules/http/static/favicon.ico b/modules/http/static/favicon.ico
new file mode 100644
index 0000000..8c85535
--- /dev/null
+++ b/modules/http/static/favicon.ico
Binary files differ
diff --git a/modules/http/static/glyphicons-halflings-regular.spdx b/modules/http/static/glyphicons-halflings-regular.spdx
new file mode 100644
index 0000000..3241fd5
--- /dev/null
+++ b/modules/http/static/glyphicons-halflings-regular.spdx
@@ -0,0 +1,11 @@
+SPDXVersion: SPDX-2.1
+DataLicense: CC0-1.0
+SPDXID: SPDXRef-DOCUMENT
+DocumentName: bootstrap-glyphicons-halflings-regular
+DocumentNamespace: http://spdx.org/spdxdocs/spdx-v2.1-5fdae9d2-c79e-4242-8a82-0909ddd93ae3
+
+PackageName: bootstrap-glyphicons-halflings-regular
+PackageVersion: 3.3.6
+PackageDownloadLocation: git+https://github.com/twbs/bootstrap.git@81df608a40bf0629a1dc08e584849bb1e43e0b7a#dist/fonts/glyphicons-halflings-regular.woff2
+PackageOriginator: Organization: Twitter
+PackageLicenseDeclared: MIT
diff --git a/modules/http/static/glyphicons-halflings-regular.woff2 b/modules/http/static/glyphicons-halflings-regular.woff2
new file mode 100644
index 0000000..64539b5
--- /dev/null
+++ b/modules/http/static/glyphicons-halflings-regular.woff2
Binary files differ
diff --git a/modules/http/static/jquery.js b/modules/http/static/jquery.js
new file mode 100644
index 0000000..bb692f6
--- /dev/null
+++ b/modules/http/static/jquery.js
@@ -0,0 +1,5 @@
+/*! jQuery v2.1.4 | (c) 2005, 2015 jQuery Foundation, Inc. | jquery.org/license */
+/* SPDX-License-Identifier: MIT */
+!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k={},l=a.document,m="2.1.4",n=function(a,b){return new n.fn.init(a,b)},o=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,p=/^-ms-/,q=/-([\da-z])/gi,r=function(a,b){return b.toUpperCase()};n.fn=n.prototype={jquery:m,constructor:n,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=n.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return n.each(this,a,b)},map:function(a){return this.pushStack(n.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},n.extend=n.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||n.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(a=arguments[h]))for(b in a)c=g[b],d=a[b],g!==d&&(j&&d&&(n.isPlainObject(d)||(e=n.isArray(d)))?(e?(e=!1,f=c&&n.isArray(c)?c:[]):f=c&&n.isPlainObject(c)?c:{},g[b]=n.extend(j,f,d)):void 0!==d&&(g[b]=d));return g},n.extend({expando:"jQuery"+(m+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===n.type(a)},isArray:Array.isArray,isWindow:function(a){return null!=a&&a===a.window},isNumeric:function(a){return!n.isArray(a)&&a-parseFloat(a)+1>=0},isPlainObject:function(a){return"object"!==n.type(a)||a.nodeType||n.isWindow(a)?!1:a.constructor&&!j.call(a.constructor.prototype,"isPrototypeOf")?!1:!0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(a){var b,c=eval;a=n.trim(a),a&&(1===a.indexOf("use strict")?(b=l.createElement("script"),b.text=a,l.head.appendChild(b).parentNode.removeChild(b)):c(a))},camelCase:function(a){return a.replace(p,"ms-").replace(q,r)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=s(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(o,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(s(Object(a))?n.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){return null==b?-1:g.call(b,a,c)},merge:function(a,b){for(var c=+b.length,d=0,e=a.length;c>d;d++)a[e++]=b[d];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=s(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(c=a[b],b=a,a=c),n.isFunction(a)?(e=d.call(arguments,2),f=function(){return a.apply(b||this,e.concat(d.call(arguments)))},f.guid=a.guid=a.guid||n.guid++,f):void 0},now:Date.now,support:k}),n.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function s(a){var b="length"in a&&a.length,c=n.type(a);return"function"===c||n.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var t=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ha(),z=ha(),A=ha(),B=function(a,b){return a===b&&(l=!0),0},C=1<<31,D={}.hasOwnProperty,E=[],F=E.pop,G=E.push,H=E.push,I=E.slice,J=function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1},K="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",L="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",N=M.replace("w","w#"),O="\\["+L+"*("+M+")(?:"+L+"*([*^$|!~]?=)"+L+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+N+"))|)"+L+"*\\]",P=":("+M+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+O+")*)|.*)\\)|)",Q=new RegExp(L+"+","g"),R=new RegExp("^"+L+"+|((?:^|[^\\\\])(?:\\\\.)*)"+L+"+$","g"),S=new RegExp("^"+L+"*,"+L+"*"),T=new RegExp("^"+L+"*([>+~]|"+L+")"+L+"*"),U=new RegExp("="+L+"*([^\\]'\"]*?)"+L+"*\\]","g"),V=new RegExp(P),W=new RegExp("^"+N+"$"),X={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),TAG:new RegExp("^("+M.replace("w","w*")+")"),ATTR:new RegExp("^"+O),PSEUDO:new RegExp("^"+P),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+L+"*(even|odd|(([+-]|)(\\d*)n|)"+L+"*(?:([+-]|)"+L+"*(\\d+)|))"+L+"*\\)|)","i"),bool:new RegExp("^(?:"+K+")$","i"),needsContext:new RegExp("^"+L+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+L+"*((?:-\\d)?\\d*)"+L+"*\\)|)(?=[^-]|$)","i")},Y=/^(?:input|select|textarea|button)$/i,Z=/^h\d$/i,$=/^[^{]+\{\s*\[native \w/,_=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,aa=/[+~]/,ba=/'|\\/g,ca=new RegExp("\\\\([\\da-f]{1,6}"+L+"?|("+L+")|.)","ig"),da=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},ea=function(){m()};try{H.apply(E=I.call(v.childNodes),v.childNodes),E[v.childNodes.length].nodeType}catch(fa){H={apply:E.length?function(a,b){G.apply(a,I.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function ga(a,b,d,e){var f,h,j,k,l,o,r,s,w,x;if((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,d=d||[],k=b.nodeType,"string"!=typeof a||!a||1!==k&&9!==k&&11!==k)return d;if(!e&&p){if(11!==k&&(f=_.exec(a)))if(j=f[1]){if(9===k){if(h=b.getElementById(j),!h||!h.parentNode)return d;if(h.id===j)return d.push(h),d}else if(b.ownerDocument&&(h=b.ownerDocument.getElementById(j))&&t(b,h)&&h.id===j)return d.push(h),d}else{if(f[2])return H.apply(d,b.getElementsByTagName(a)),d;if((j=f[3])&&c.getElementsByClassName)return H.apply(d,b.getElementsByClassName(j)),d}if(c.qsa&&(!q||!q.test(a))){if(s=r=u,w=b,x=1!==k&&a,1===k&&"object"!==b.nodeName.toLowerCase()){o=g(a),(r=b.getAttribute("id"))?s=r.replace(ba,"\\$&"):b.setAttribute("id",s),s="[id='"+s+"'] ",l=o.length;while(l--)o[l]=s+ra(o[l]);w=aa.test(a)&&pa(b.parentNode)||b,x=o.join(",")}if(x)try{return H.apply(d,w.querySelectorAll(x)),d}catch(y){}finally{r||b.removeAttribute("id")}}}return i(a.replace(R,"$1"),b,d,e)}function ha(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ia(a){return a[u]=!0,a}function ja(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ka(a,b){var c=a.split("|"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function la(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||C)-(~a.sourceIndex||C);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function na(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function oa(a){return ia(function(b){return b=+b,ia(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function pa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=ga.support={},f=ga.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=ga.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=g.documentElement,e=g.defaultView,e&&e!==e.top&&(e.addEventListener?e.addEventListener("unload",ea,!1):e.attachEvent&&e.attachEvent("onunload",ea)),p=!f(g),c.attributes=ja(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ja(function(a){return a.appendChild(g.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=$.test(g.getElementsByClassName),c.getById=ja(function(a){return o.appendChild(a).id=u,!g.getElementsByName||!g.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},d.filter.ID=function(a){var b=a.replace(ca,da);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(ca,da);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=$.test(g.querySelectorAll))&&(ja(function(a){o.appendChild(a).innerHTML="<a id='"+u+"'></a><select id='"+u+"-\f]' msallowcapture=''><option selected=''></option></select>",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+L+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+L+"*(?:value|"+K+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ja(function(a){var b=g.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+L+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=$.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ja(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",P)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=$.test(o.compareDocumentPosition),t=b||$.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===g||a.ownerDocument===v&&t(v,a)?-1:b===g||b.ownerDocument===v&&t(v,b)?1:k?J(k,a)-J(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,h=[a],i=[b];if(!e||!f)return a===g?-1:b===g?1:e?-1:f?1:k?J(k,a)-J(k,b):0;if(e===f)return la(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)i.unshift(c);while(h[d]===i[d])d++;return d?la(h[d],i[d]):h[d]===v?-1:i[d]===v?1:0},g):n},ga.matches=function(a,b){return ga(a,null,null,b)},ga.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(U,"='$1']"),!(!c.matchesSelector||!p||r&&r.test(b)||q&&q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return ga(b,n,null,[a]).length>0},ga.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},ga.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&D.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},ga.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},ga.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=ga.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=ga.selectors={cacheLength:50,createPseudo:ia,match:X,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(ca,da),a[3]=(a[3]||a[4]||a[5]||"").replace(ca,da),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||ga.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&ga.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return X.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&V.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(ca,da).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+L+")"+a+"("+L+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=ga.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(Q," ")+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h;if(q){if(f){while(p){l=b;while(l=l[p])if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){k=q[u]||(q[u]={}),j=k[a]||[],n=j[0]===w&&j[1],m=j[0]===w&&j[2],l=n&&q.childNodes[n];while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if(1===l.nodeType&&++m&&l===b){k[a]=[w,n,m];break}}else if(s&&(j=(b[u]||(b[u]={}))[a])&&j[0]===w)m=j[1];else while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if((h?l.nodeName.toLowerCase()===r:1===l.nodeType)&&++m&&(s&&((l[u]||(l[u]={}))[a]=[w,m]),l===b))break;return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||ga.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ia(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=J(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ia(function(a){var b=[],c=[],d=h(a.replace(R,"$1"));return d[u]?ia(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ia(function(a){return function(b){return ga(a,b).length>0}}),contains:ia(function(a){return a=a.replace(ca,da),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ia(function(a){return W.test(a||"")||ga.error("unsupported lang: "+a),a=a.replace(ca,da).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Z.test(a.nodeName)},input:function(a){return Y.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:oa(function(){return[0]}),last:oa(function(a,b){return[b-1]}),eq:oa(function(a,b,c){return[0>c?c+b:c]}),even:oa(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:oa(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:oa(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:oa(function(a,b,c){for(var d=0>c?c+b:c;++d<b;)a.push(d);return a})}},d.pseudos.nth=d.pseudos.eq;for(b in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})d.pseudos[b]=ma(b);for(b in{submit:!0,reset:!0})d.pseudos[b]=na(b);function qa(){}qa.prototype=d.filters=d.pseudos,d.setFilters=new qa,g=ga.tokenize=function(a,b){var c,e,f,g,h,i,j,k=z[a+" "];if(k)return b?0:k.slice(0);h=a,i=[],j=d.preFilter;while(h){(!c||(e=S.exec(h)))&&(e&&(h=h.slice(e[0].length)||h),i.push(f=[])),c=!1,(e=T.exec(h))&&(c=e.shift(),f.push({value:c,type:e[0].replace(R," ")}),h=h.slice(c.length));for(g in d.filter)!(e=X[g].exec(h))||j[g]&&!(e=j[g](e))||(c=e.shift(),f.push({value:c,type:g,matches:e}),h=h.slice(c.length));if(!c)break}return b?h.length:h?ga.error(a):z(a,i).slice(0)};function ra(a){for(var b=0,c=a.length,d="";c>b;b++)d+=a[b].value;return d}function sa(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(i=b[u]||(b[u]={}),(h=i[d])&&h[0]===w&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function ta(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function ua(a,b,c){for(var d=0,e=b.length;e>d;d++)ga(a,b[d],c);return c}function va(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function wa(a,b,c,d,e,f){return d&&!d[u]&&(d=wa(d)),e&&!e[u]&&(e=wa(e,f)),ia(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||ua(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:va(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=va(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?J(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=va(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):H.apply(g,r)})}function xa(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=sa(function(a){return a===b},h,!0),l=sa(function(a){return J(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];f>i;i++)if(c=d.relative[a[i].type])m=[sa(ta(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return wa(i>1&&ta(m),i>1&&ra(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(R,"$1"),c,e>i&&xa(a.slice(i,e)),f>e&&xa(a=a.slice(e)),f>e&&ra(a))}m.push(c)}return ta(m)}function ya(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,m,o,p=0,q="0",r=f&&[],s=[],t=j,u=f||e&&d.find.TAG("*",k),v=w+=null==t?1:Math.random()||.1,x=u.length;for(k&&(j=g!==n&&g);q!==x&&null!=(l=u[q]);q++){if(e&&l){m=0;while(o=a[m++])if(o(l,g,h)){i.push(l);break}k&&(w=v)}c&&((l=!o&&l)&&p--,f&&r.push(l))}if(p+=q,c&&q!==p){m=0;while(o=b[m++])o(r,s,g,h);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=F.call(i));s=va(s)}H.apply(i,s),k&&!f&&s.length>0&&p+b.length>1&&ga.uniqueSort(i)}return k&&(w=v,j=t),r};return c?ia(f):f}return h=ga.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=xa(b[c]),f[u]?d.push(f):e.push(f);f=A(a,ya(e,d)),f.selector=a}return f},i=ga.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(ca,da),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=X.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(ca,da),aa.test(j[0].type)&&pa(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&ra(j),!a)return H.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,aa.test(a)&&pa(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ja(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),ja(function(a){return a.innerHTML="<a href='#'></a>","#"===a.firstChild.getAttribute("href")})||ka("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ja(function(a){return a.innerHTML="<input/>",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ka("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ja(function(a){return null==a.getAttribute("disabled")})||ka(K,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),ga}(a);n.find=t,n.expr=t.selectors,n.expr[":"]=n.expr.pseudos,n.unique=t.uniqueSort,n.text=t.getText,n.isXMLDoc=t.isXML,n.contains=t.contains;var u=n.expr.match.needsContext,v=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,w=/^.[^:#\[\.,]*$/;function x(a,b,c){if(n.isFunction(b))return n.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return n.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(w.test(b))return n.filter(b,a,c);b=n.filter(b,a)}return n.grep(a,function(a){return g.call(b,a)>=0!==c})}n.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?n.find.matchesSelector(d,a)?[d]:[]:n.find.matches(a,n.grep(b,function(a){return 1===a.nodeType}))},n.fn.extend({find:function(a){var b,c=this.length,d=[],e=this;if("string"!=typeof a)return this.pushStack(n(a).filter(function(){for(b=0;c>b;b++)if(n.contains(e[b],this))return!0}));for(b=0;c>b;b++)n.find(a,e[b],d);return d=this.pushStack(c>1?n.unique(d):d),d.selector=this.selector?this.selector+" "+a:a,d},filter:function(a){return this.pushStack(x(this,a||[],!1))},not:function(a){return this.pushStack(x(this,a||[],!0))},is:function(a){return!!x(this,"string"==typeof a&&u.test(a)?n(a):a||[],!1).length}});var y,z=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,A=n.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:z.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||y).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof n?b[0]:b,n.merge(this,n.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:l,!0)),v.test(c[1])&&n.isPlainObject(b))for(c in b)n.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}return d=l.getElementById(c[2]),d&&d.parentNode&&(this.length=1,this[0]=d),this.context=l,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):n.isFunction(a)?"undefined"!=typeof y.ready?y.ready(a):a(n):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),n.makeArray(a,this))};A.prototype=n.fn,y=n(l);var B=/^(?:parents|prev(?:Until|All))/,C={children:!0,contents:!0,next:!0,prev:!0};n.extend({dir:function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&n(a).is(c))break;d.push(a)}return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),n.fn.extend({has:function(a){var b=n(a,this),c=b.length;return this.filter(function(){for(var a=0;c>a;a++)if(n.contains(this,b[a]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=u.test(a)||"string"!=typeof a?n(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&n.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?n.unique(f):f)},index:function(a){return a?"string"==typeof a?g.call(n(a),this[0]):g.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(n.unique(n.merge(this.get(),n(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function D(a,b){while((a=a[b])&&1!==a.nodeType);return a}n.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return n.dir(a,"parentNode")},parentsUntil:function(a,b,c){return n.dir(a,"parentNode",c)},next:function(a){return D(a,"nextSibling")},prev:function(a){return D(a,"previousSibling")},nextAll:function(a){return n.dir(a,"nextSibling")},prevAll:function(a){return n.dir(a,"previousSibling")},nextUntil:function(a,b,c){return n.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return n.dir(a,"previousSibling",c)},siblings:function(a){return n.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return n.sibling(a.firstChild)},contents:function(a){return a.contentDocument||n.merge([],a.childNodes)}},function(a,b){n.fn[a]=function(c,d){var e=n.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=n.filter(d,e)),this.length>1&&(C[a]||n.unique(e),B.test(a)&&e.reverse()),this.pushStack(e)}});var E=/\S+/g,F={};function G(a){var b=F[a]={};return n.each(a.match(E)||[],function(a,c){b[c]=!0}),b}n.Callbacks=function(a){a="string"==typeof a?F[a]||G(a):n.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(b=a.memory&&l,c=!0,g=e||0,e=0,f=h.length,d=!0;h&&f>g;g++)if(h[g].apply(l[0],l[1])===!1&&a.stopOnFalse){b=!1;break}d=!1,h&&(i?i.length&&j(i.shift()):b?h=[]:k.disable())},k={add:function(){if(h){var c=h.length;!function g(b){n.each(b,function(b,c){var d=n.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&g(c)})}(arguments),d?f=h.length:b&&(e=c,j(b))}return this},remove:function(){return h&&n.each(arguments,function(a,b){var c;while((c=n.inArray(b,h,c))>-1)h.splice(c,1),d&&(f>=c&&f--,g>=c&&g--)}),this},has:function(a){return a?n.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],f=0,this},disable:function(){return h=i=b=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,b||k.disable(),this},locked:function(){return!i},fireWith:function(a,b){return!h||c&&!i||(b=b||[],b=[a,b.slice?b.slice():b],d?i.push(b):j(b)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!c}};return k},n.extend({Deferred:function(a){var b=[["resolve","done",n.Callbacks("once memory"),"resolved"],["reject","fail",n.Callbacks("once memory"),"rejected"],["notify","progress",n.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return n.Deferred(function(c){n.each(b,function(b,f){var g=n.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&n.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?n.extend(a,d):d}},e={};return d.pipe=d.then,n.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=d.call(arguments),e=c.length,f=1!==e||a&&n.isFunction(a.promise)?e:0,g=1===f?a:n.Deferred(),h=function(a,b,c){return function(e){b[a]=this,c[a]=arguments.length>1?d.call(arguments):e,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(e>1)for(i=new Array(e),j=new Array(e),k=new Array(e);e>b;b++)c[b]&&n.isFunction(c[b].promise)?c[b].promise().done(h(b,k,c)).fail(g.reject).progress(h(b,j,i)):--f;return f||g.resolveWith(k,c),g.promise()}});var H;n.fn.ready=function(a){return n.ready.promise().done(a),this},n.extend({isReady:!1,readyWait:1,holdReady:function(a){a?n.readyWait++:n.ready(!0)},ready:function(a){(a===!0?--n.readyWait:n.isReady)||(n.isReady=!0,a!==!0&&--n.readyWait>0||(H.resolveWith(l,[n]),n.fn.triggerHandler&&(n(l).triggerHandler("ready"),n(l).off("ready"))))}});function I(){l.removeEventListener("DOMContentLoaded",I,!1),a.removeEventListener("load",I,!1),n.ready()}n.ready.promise=function(b){return H||(H=n.Deferred(),"complete"===l.readyState?setTimeout(n.ready):(l.addEventListener("DOMContentLoaded",I,!1),a.addEventListener("load",I,!1))),H.promise(b)},n.ready.promise();var J=n.access=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===n.type(c)){e=!0;for(h in c)n.access(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,n.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(n(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f};n.acceptData=function(a){return 1===a.nodeType||9===a.nodeType||!+a.nodeType};function K(){Object.defineProperty(this.cache={},0,{get:function(){return{}}}),this.expando=n.expando+K.uid++}K.uid=1,K.accepts=n.acceptData,K.prototype={key:function(a){if(!K.accepts(a))return 0;var b={},c=a[this.expando];if(!c){c=K.uid++;try{b[this.expando]={value:c},Object.defineProperties(a,b)}catch(d){b[this.expando]=c,n.extend(a,b)}}return this.cache[c]||(this.cache[c]={}),c},set:function(a,b,c){var d,e=this.key(a),f=this.cache[e];if("string"==typeof b)f[b]=c;else if(n.isEmptyObject(f))n.extend(this.cache[e],b);else for(d in b)f[d]=b[d];return f},get:function(a,b){var c=this.cache[this.key(a)];return void 0===b?c:c[b]},access:function(a,b,c){var d;return void 0===b||b&&"string"==typeof b&&void 0===c?(d=this.get(a,b),void 0!==d?d:this.get(a,n.camelCase(b))):(this.set(a,b,c),void 0!==c?c:b)},remove:function(a,b){var c,d,e,f=this.key(a),g=this.cache[f];if(void 0===b)this.cache[f]={};else{n.isArray(b)?d=b.concat(b.map(n.camelCase)):(e=n.camelCase(b),b in g?d=[b,e]:(d=e,d=d in g?[d]:d.match(E)||[])),c=d.length;while(c--)delete g[d[c]]}},hasData:function(a){return!n.isEmptyObject(this.cache[a[this.expando]]||{})},discard:function(a){a[this.expando]&&delete this.cache[a[this.expando]]}};var L=new K,M=new K,N=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,O=/([A-Z])/g;function P(a,b,c){var d;if(void 0===c&&1===a.nodeType)if(d="data-"+b.replace(O,"-$1").toLowerCase(),c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:N.test(c)?n.parseJSON(c):c}catch(e){}M.set(a,b,c)}else c=void 0;return c}n.extend({hasData:function(a){return M.hasData(a)||L.hasData(a)},data:function(a,b,c){
+return M.access(a,b,c)},removeData:function(a,b){M.remove(a,b)},_data:function(a,b,c){return L.access(a,b,c)},_removeData:function(a,b){L.remove(a,b)}}),n.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=M.get(f),1===f.nodeType&&!L.get(f,"hasDataAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=n.camelCase(d.slice(5)),P(f,d,e[d])));L.set(f,"hasDataAttrs",!0)}return e}return"object"==typeof a?this.each(function(){M.set(this,a)}):J(this,function(b){var c,d=n.camelCase(a);if(f&&void 0===b){if(c=M.get(f,a),void 0!==c)return c;if(c=M.get(f,d),void 0!==c)return c;if(c=P(f,d,void 0),void 0!==c)return c}else this.each(function(){var c=M.get(this,d);M.set(this,d,b),-1!==a.indexOf("-")&&void 0!==c&&M.set(this,a,b)})},null,b,arguments.length>1,null,!0)},removeData:function(a){return this.each(function(){M.remove(this,a)})}}),n.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=L.get(a,b),c&&(!d||n.isArray(c)?d=L.access(a,b,n.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=n.queue(a,b),d=c.length,e=c.shift(),f=n._queueHooks(a,b),g=function(){n.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return L.get(a,c)||L.access(a,c,{empty:n.Callbacks("once memory").add(function(){L.remove(a,[b+"queue",c])})})}}),n.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length<c?n.queue(this[0],a):void 0===b?this:this.each(function(){var c=n.queue(this,a,b);n._queueHooks(this,a),"fx"===a&&"inprogress"!==c[0]&&n.dequeue(this,a)})},dequeue:function(a){return this.each(function(){n.dequeue(this,a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,b){var c,d=1,e=n.Deferred(),f=this,g=this.length,h=function(){--d||e.resolveWith(f,[f])};"string"!=typeof a&&(b=a,a=void 0),a=a||"fx";while(g--)c=L.get(f[g],a+"queueHooks"),c&&c.empty&&(d++,c.empty.add(h));return h(),e.promise(b)}});var Q=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,R=["Top","Right","Bottom","Left"],S=function(a,b){return a=b||a,"none"===n.css(a,"display")||!n.contains(a.ownerDocument,a)},T=/^(?:checkbox|radio)$/i;!function(){var a=l.createDocumentFragment(),b=a.appendChild(l.createElement("div")),c=l.createElement("input");c.setAttribute("type","radio"),c.setAttribute("checked","checked"),c.setAttribute("name","t"),b.appendChild(c),k.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,b.innerHTML="<textarea>x</textarea>",k.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var U="undefined";k.focusinBubbles="onfocusin"in a;var V=/^key/,W=/^(?:mouse|pointer|contextmenu)|click/,X=/^(?:focusinfocus|focusoutblur)$/,Y=/^([^.]*)(?:\.(.+)|)$/;function Z(){return!0}function $(){return!1}function _(){try{return l.activeElement}catch(a){}}n.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=L.get(a);if(r){c.handler&&(f=c,c=f.handler,e=f.selector),c.guid||(c.guid=n.guid++),(i=r.events)||(i=r.events={}),(g=r.handle)||(g=r.handle=function(b){return typeof n!==U&&n.event.triggered!==b.type?n.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(E)||[""],j=b.length;while(j--)h=Y.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o&&(l=n.event.special[o]||{},o=(e?l.delegateType:l.bindType)||o,l=n.event.special[o]||{},k=n.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&n.expr.match.needsContext.test(e),namespace:p.join(".")},f),(m=i[o])||(m=i[o]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,p,g)!==!1||a.addEventListener&&a.addEventListener(o,g,!1)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),n.event.global[o]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=L.hasData(a)&&L.get(a);if(r&&(i=r.events)){b=(b||"").match(E)||[""],j=b.length;while(j--)if(h=Y.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=n.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,m=i[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&q!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&("**"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||n.removeEvent(a,o,r.handle),delete i[o])}else for(o in i)n.event.remove(a,o+b[j],c,d,!0);n.isEmptyObject(i)&&(delete r.handle,L.remove(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,m,o,p=[d||l],q=j.call(b,"type")?b.type:b,r=j.call(b,"namespace")?b.namespace.split("."):[];if(g=h=d=d||l,3!==d.nodeType&&8!==d.nodeType&&!X.test(q+n.event.triggered)&&(q.indexOf(".")>=0&&(r=q.split("."),q=r.shift(),r.sort()),k=q.indexOf(":")<0&&"on"+q,b=b[n.expando]?b:new n.Event(q,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=r.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+r.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:n.makeArray(c,[b]),o=n.event.special[q]||{},e||!o.trigger||o.trigger.apply(d,c)!==!1)){if(!e&&!o.noBubble&&!n.isWindow(d)){for(i=o.delegateType||q,X.test(i+q)||(g=g.parentNode);g;g=g.parentNode)p.push(g),h=g;h===(d.ownerDocument||l)&&p.push(h.defaultView||h.parentWindow||a)}f=0;while((g=p[f++])&&!b.isPropagationStopped())b.type=f>1?i:o.bindType||q,m=(L.get(g,"events")||{})[b.type]&&L.get(g,"handle"),m&&m.apply(g,c),m=k&&g[k],m&&m.apply&&n.acceptData(g)&&(b.result=m.apply(g,c),b.result===!1&&b.preventDefault());return b.type=q,e||b.isDefaultPrevented()||o._default&&o._default.apply(p.pop(),c)!==!1||!n.acceptData(d)||k&&n.isFunction(d[q])&&!n.isWindow(d)&&(h=d[k],h&&(d[k]=null),n.event.triggered=q,d[q](),n.event.triggered=void 0,h&&(d[k]=h)),b.result}},dispatch:function(a){a=n.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(L.get(this,"events")||{})[a.type]||[],k=n.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=n.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,c=0;while((g=f.handlers[c++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(g.namespace))&&(a.handleObj=g,a.data=g.data,e=((n.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==e&&(a.result=e)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||"click"!==a.type))for(;i!==this;i=i.parentNode||this)if(i.disabled!==!0||"click"!==a.type){for(d=[],c=0;h>c;c++)f=b[c],e=f.selector+" ",void 0===d[e]&&(d[e]=f.needsContext?n(e,this).index(i)>=0:n.find(e,this,null,[i]).length),d[e]&&d.push(f);d.length&&g.push({elem:i,handlers:d})}return h<b.length&&g.push({elem:this,handlers:b.slice(h)}),g},props:"altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(a,b){return null==a.which&&(a.which=null!=b.charCode?b.charCode:b.keyCode),a}},mouseHooks:{props:"button buttons clientX clientY offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(a,b){var c,d,e,f=b.button;return null==a.pageX&&null!=b.clientX&&(c=a.target.ownerDocument||l,d=c.documentElement,e=c.body,a.pageX=b.clientX+(d&&d.scrollLeft||e&&e.scrollLeft||0)-(d&&d.clientLeft||e&&e.clientLeft||0),a.pageY=b.clientY+(d&&d.scrollTop||e&&e.scrollTop||0)-(d&&d.clientTop||e&&e.clientTop||0)),a.which||void 0===f||(a.which=1&f?1:2&f?3:4&f?2:0),a}},fix:function(a){if(a[n.expando])return a;var b,c,d,e=a.type,f=a,g=this.fixHooks[e];g||(this.fixHooks[e]=g=W.test(e)?this.mouseHooks:V.test(e)?this.keyHooks:{}),d=g.props?this.props.concat(g.props):this.props,a=new n.Event(f),b=d.length;while(b--)c=d[b],a[c]=f[c];return a.target||(a.target=l),3===a.target.nodeType&&(a.target=a.target.parentNode),g.filter?g.filter(a,f):a},special:{load:{noBubble:!0},focus:{trigger:function(){return this!==_()&&this.focus?(this.focus(),!1):void 0},delegateType:"focusin"},blur:{trigger:function(){return this===_()&&this.blur?(this.blur(),!1):void 0},delegateType:"focusout"},click:{trigger:function(){return"checkbox"===this.type&&this.click&&n.nodeName(this,"input")?(this.click(),!1):void 0},_default:function(a){return n.nodeName(a.target,"a")}},beforeunload:{postDispatch:function(a){void 0!==a.result&&a.originalEvent&&(a.originalEvent.returnValue=a.result)}}},simulate:function(a,b,c,d){var e=n.extend(new n.Event,c,{type:a,isSimulated:!0,originalEvent:{}});d?n.event.trigger(e,null,b):n.event.dispatch.call(b,e),e.isDefaultPrevented()&&c.preventDefault()}},n.removeEvent=function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c,!1)},n.Event=function(a,b){return this instanceof n.Event?(a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||void 0===a.defaultPrevented&&a.returnValue===!1?Z:$):this.type=a,b&&n.extend(this,b),this.timeStamp=a&&a.timeStamp||n.now(),void(this[n.expando]=!0)):new n.Event(a,b)},n.Event.prototype={isDefaultPrevented:$,isPropagationStopped:$,isImmediatePropagationStopped:$,preventDefault:function(){var a=this.originalEvent;this.isDefaultPrevented=Z,a&&a.preventDefault&&a.preventDefault()},stopPropagation:function(){var a=this.originalEvent;this.isPropagationStopped=Z,a&&a.stopPropagation&&a.stopPropagation()},stopImmediatePropagation:function(){var a=this.originalEvent;this.isImmediatePropagationStopped=Z,a&&a.stopImmediatePropagation&&a.stopImmediatePropagation(),this.stopPropagation()}},n.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(a,b){n.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c,d=this,e=a.relatedTarget,f=a.handleObj;return(!e||e!==d&&!n.contains(d,e))&&(a.type=f.origType,c=f.handler.apply(this,arguments),a.type=b),c}}}),k.focusinBubbles||n.each({focus:"focusin",blur:"focusout"},function(a,b){var c=function(a){n.event.simulate(b,a.target,n.event.fix(a),!0)};n.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=L.access(d,b);e||d.addEventListener(a,c,!0),L.access(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=L.access(d,b)-1;e?L.access(d,b,e):(d.removeEventListener(a,c,!0),L.remove(d,b))}}}),n.fn.extend({on:function(a,b,c,d,e){var f,g;if("object"==typeof a){"string"!=typeof b&&(c=c||b,b=void 0);for(g in a)this.on(g,b,c,a[g],e);return this}if(null==c&&null==d?(d=b,c=b=void 0):null==d&&("string"==typeof b?(d=c,c=void 0):(d=c,c=b,b=void 0)),d===!1)d=$;else if(!d)return this;return 1===e&&(f=d,d=function(a){return n().off(a),f.apply(this,arguments)},d.guid=f.guid||(f.guid=n.guid++)),this.each(function(){n.event.add(this,a,d,c,b)})},one:function(a,b,c,d){return this.on(a,b,c,d,1)},off:function(a,b,c){var d,e;if(a&&a.preventDefault&&a.handleObj)return d=a.handleObj,n(a.delegateTarget).off(d.namespace?d.origType+"."+d.namespace:d.origType,d.selector,d.handler),this;if("object"==typeof a){for(e in a)this.off(e,b,a[e]);return this}return(b===!1||"function"==typeof b)&&(c=b,b=void 0),c===!1&&(c=$),this.each(function(){n.event.remove(this,a,c,b)})},trigger:function(a,b){return this.each(function(){n.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];return c?n.event.trigger(a,b,c,!0):void 0}});var aa=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,ba=/<([\w:]+)/,ca=/<|&#?\w+;/,da=/<(?:script|style|link)/i,ea=/checked\s*(?:[^=]|=\s*.checked.)/i,fa=/^$|\/(?:java|ecma)script/i,ga=/^true\/(.*)/,ha=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,ia={option:[1,"<select multiple='multiple'>","</select>"],thead:[1,"<table>","</table>"],col:[2,"<table><colgroup>","</colgroup></table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:[0,"",""]};ia.optgroup=ia.option,ia.tbody=ia.tfoot=ia.colgroup=ia.caption=ia.thead,ia.th=ia.td;function ja(a,b){return n.nodeName(a,"table")&&n.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function ka(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function la(a){var b=ga.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function ma(a,b){for(var c=0,d=a.length;d>c;c++)L.set(a[c],"globalEval",!b||L.get(b[c],"globalEval"))}function na(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(L.hasData(a)&&(f=L.access(a),g=L.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;d>c;c++)n.event.add(b,e,j[e][c])}M.hasData(a)&&(h=M.access(a),i=n.extend({},h),M.set(b,i))}}function oa(a,b){var c=a.getElementsByTagName?a.getElementsByTagName(b||"*"):a.querySelectorAll?a.querySelectorAll(b||"*"):[];return void 0===b||b&&n.nodeName(a,b)?n.merge([a],c):c}function pa(a,b){var c=b.nodeName.toLowerCase();"input"===c&&T.test(a.type)?b.checked=a.checked:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}n.extend({clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=n.contains(a.ownerDocument,a);if(!(k.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||n.isXMLDoc(a)))for(g=oa(h),f=oa(a),d=0,e=f.length;e>d;d++)pa(f[d],g[d]);if(b)if(c)for(f=f||oa(a),g=g||oa(h),d=0,e=f.length;e>d;d++)na(f[d],g[d]);else na(a,h);return g=oa(h,"script"),g.length>0&&ma(g,!i&&oa(a,"script")),h},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,k=b.createDocumentFragment(),l=[],m=0,o=a.length;o>m;m++)if(e=a[m],e||0===e)if("object"===n.type(e))n.merge(l,e.nodeType?[e]:e);else if(ca.test(e)){f=f||k.appendChild(b.createElement("div")),g=(ba.exec(e)||["",""])[1].toLowerCase(),h=ia[g]||ia._default,f.innerHTML=h[1]+e.replace(aa,"<$1></$2>")+h[2],j=h[0];while(j--)f=f.lastChild;n.merge(l,f.childNodes),f=k.firstChild,f.textContent=""}else l.push(b.createTextNode(e));k.textContent="",m=0;while(e=l[m++])if((!d||-1===n.inArray(e,d))&&(i=n.contains(e.ownerDocument,e),f=oa(k.appendChild(e),"script"),i&&ma(f),c)){j=0;while(e=f[j++])fa.test(e.type||"")&&c.push(e)}return k},cleanData:function(a){for(var b,c,d,e,f=n.event.special,g=0;void 0!==(c=a[g]);g++){if(n.acceptData(c)&&(e=c[L.expando],e&&(b=L.cache[e]))){if(b.events)for(d in b.events)f[d]?n.event.remove(c,d):n.removeEvent(c,d,b.handle);L.cache[e]&&delete L.cache[e]}delete M.cache[c[M.expando]]}}}),n.fn.extend({text:function(a){return J(this,function(a){return void 0===a?n.text(this):this.empty().each(function(){(1===this.nodeType||11===this.nodeType||9===this.nodeType)&&(this.textContent=a)})},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=ja(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=ja(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?n.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||n.cleanData(oa(c)),c.parentNode&&(b&&n.contains(c.ownerDocument,c)&&ma(oa(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(n.cleanData(oa(a,!1)),a.textContent="");return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return n.clone(this,a,b)})},html:function(a){return J(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a&&1===b.nodeType)return b.innerHTML;if("string"==typeof a&&!da.test(a)&&!ia[(ba.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(aa,"<$1></$2>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(n.cleanData(oa(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,n.cleanData(oa(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=e.apply([],a);var c,d,f,g,h,i,j=0,l=this.length,m=this,o=l-1,p=a[0],q=n.isFunction(p);if(q||l>1&&"string"==typeof p&&!k.checkClone&&ea.test(p))return this.each(function(c){var d=m.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(l&&(c=n.buildFragment(a,this[0].ownerDocument,!1,this),d=c.firstChild,1===c.childNodes.length&&(c=d),d)){for(f=n.map(oa(c,"script"),ka),g=f.length;l>j;j++)h=c,j!==o&&(h=n.clone(h,!0,!0),g&&n.merge(f,oa(h,"script"))),b.call(this[j],h,j);if(g)for(i=f[f.length-1].ownerDocument,n.map(f,la),j=0;g>j;j++)h=f[j],fa.test(h.type||"")&&!L.access(h,"globalEval")&&n.contains(i,h)&&(h.src?n._evalUrl&&n._evalUrl(h.src):n.globalEval(h.textContent.replace(ha,"")))}return this}}),n.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){n.fn[a]=function(a){for(var c,d=[],e=n(a),g=e.length-1,h=0;g>=h;h++)c=h===g?this:this.clone(!0),n(e[h])[b](c),f.apply(d,c.get());return this.pushStack(d)}});var qa,ra={};function sa(b,c){var d,e=n(c.createElement(b)).appendTo(c.body),f=a.getDefaultComputedStyle&&(d=a.getDefaultComputedStyle(e[0]))?d.display:n.css(e[0],"display");return e.detach(),f}function ta(a){var b=l,c=ra[a];return c||(c=sa(a,b),"none"!==c&&c||(qa=(qa||n("<iframe frameborder='0' width='0' height='0'/>")).appendTo(b.documentElement),b=qa[0].contentDocument,b.write(),b.close(),c=sa(a,b),qa.detach()),ra[a]=c),c}var ua=/^margin/,va=new RegExp("^("+Q+")(?!px)[a-z%]+$","i"),wa=function(b){return b.ownerDocument.defaultView.opener?b.ownerDocument.defaultView.getComputedStyle(b,null):a.getComputedStyle(b,null)};function xa(a,b,c){var d,e,f,g,h=a.style;return c=c||wa(a),c&&(g=c.getPropertyValue(b)||c[b]),c&&(""!==g||n.contains(a.ownerDocument,a)||(g=n.style(a,b)),va.test(g)&&ua.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=g,g=c.width,h.width=d,h.minWidth=e,h.maxWidth=f)),void 0!==g?g+"":g}function ya(a,b){return{get:function(){return a()?void delete this.get:(this.get=b).apply(this,arguments)}}}!function(){var b,c,d=l.documentElement,e=l.createElement("div"),f=l.createElement("div");if(f.style){f.style.backgroundClip="content-box",f.cloneNode(!0).style.backgroundClip="",k.clearCloneStyle="content-box"===f.style.backgroundClip,e.style.cssText="border:0;width:0;height:0;top:0;left:-9999px;margin-top:1px;position:absolute",e.appendChild(f);function g(){f.style.cssText="-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;display:block;margin-top:1%;top:1%;border:1px;padding:1px;width:4px;position:absolute",f.innerHTML="",d.appendChild(e);var g=a.getComputedStyle(f,null);b="1%"!==g.top,c="4px"===g.width,d.removeChild(e)}a.getComputedStyle&&n.extend(k,{pixelPosition:function(){return g(),b},boxSizingReliable:function(){return null==c&&g(),c},reliableMarginRight:function(){var b,c=f.appendChild(l.createElement("div"));return c.style.cssText=f.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:0",c.style.marginRight=c.style.width="0",f.style.width="1px",d.appendChild(e),b=!parseFloat(a.getComputedStyle(c,null).marginRight),d.removeChild(e),f.removeChild(c),b}})}}(),n.swap=function(a,b,c,d){var e,f,g={};for(f in b)g[f]=a.style[f],a.style[f]=b[f];e=c.apply(a,d||[]);for(f in b)a.style[f]=g[f];return e};var za=/^(none|table(?!-c[ea]).+)/,Aa=new RegExp("^("+Q+")(.*)$","i"),Ba=new RegExp("^([+-])=("+Q+")","i"),Ca={position:"absolute",visibility:"hidden",display:"block"},Da={letterSpacing:"0",fontWeight:"400"},Ea=["Webkit","O","Moz","ms"];function Fa(a,b){if(b in a)return b;var c=b[0].toUpperCase()+b.slice(1),d=b,e=Ea.length;while(e--)if(b=Ea[e]+c,b in a)return b;return d}function Ga(a,b,c){var d=Aa.exec(b);return d?Math.max(0,d[1]-(c||0))+(d[2]||"px"):b}function Ha(a,b,c,d,e){for(var f=c===(d?"border":"content")?4:"width"===b?1:0,g=0;4>f;f+=2)"margin"===c&&(g+=n.css(a,c+R[f],!0,e)),d?("content"===c&&(g-=n.css(a,"padding"+R[f],!0,e)),"margin"!==c&&(g-=n.css(a,"border"+R[f]+"Width",!0,e))):(g+=n.css(a,"padding"+R[f],!0,e),"padding"!==c&&(g+=n.css(a,"border"+R[f]+"Width",!0,e)));return g}function Ia(a,b,c){var d=!0,e="width"===b?a.offsetWidth:a.offsetHeight,f=wa(a),g="border-box"===n.css(a,"boxSizing",!1,f);if(0>=e||null==e){if(e=xa(a,b,f),(0>e||null==e)&&(e=a.style[b]),va.test(e))return e;d=g&&(k.boxSizingReliable()||e===a.style[b]),e=parseFloat(e)||0}return e+Ha(a,b,c||(g?"border":"content"),d,f)+"px"}function Ja(a,b){for(var c,d,e,f=[],g=0,h=a.length;h>g;g++)d=a[g],d.style&&(f[g]=L.get(d,"olddisplay"),c=d.style.display,b?(f[g]||"none"!==c||(d.style.display=""),""===d.style.display&&S(d)&&(f[g]=L.access(d,"olddisplay",ta(d.nodeName)))):(e=S(d),"none"===c&&e||L.set(d,"olddisplay",e?c:n.css(d,"display"))));for(g=0;h>g;g++)d=a[g],d.style&&(b&&"none"!==d.style.display&&""!==d.style.display||(d.style.display=b?f[g]||"":"none"));return a}n.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=xa(a,"opacity");return""===c?"1":c}}}},cssNumber:{columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":"cssFloat"},style:function(a,b,c,d){if(a&&3!==a.nodeType&&8!==a.nodeType&&a.style){var e,f,g,h=n.camelCase(b),i=a.style;return b=n.cssProps[h]||(n.cssProps[h]=Fa(i,h)),g=n.cssHooks[b]||n.cssHooks[h],void 0===c?g&&"get"in g&&void 0!==(e=g.get(a,!1,d))?e:i[b]:(f=typeof c,"string"===f&&(e=Ba.exec(c))&&(c=(e[1]+1)*e[2]+parseFloat(n.css(a,b)),f="number"),null!=c&&c===c&&("number"!==f||n.cssNumber[h]||(c+="px"),k.clearCloneStyle||""!==c||0!==b.indexOf("background")||(i[b]="inherit"),g&&"set"in g&&void 0===(c=g.set(a,c,d))||(i[b]=c)),void 0)}},css:function(a,b,c,d){var e,f,g,h=n.camelCase(b);return b=n.cssProps[h]||(n.cssProps[h]=Fa(a.style,h)),g=n.cssHooks[b]||n.cssHooks[h],g&&"get"in g&&(e=g.get(a,!0,c)),void 0===e&&(e=xa(a,b,d)),"normal"===e&&b in Da&&(e=Da[b]),""===c||c?(f=parseFloat(e),c===!0||n.isNumeric(f)?f||0:e):e}}),n.each(["height","width"],function(a,b){n.cssHooks[b]={get:function(a,c,d){return c?za.test(n.css(a,"display"))&&0===a.offsetWidth?n.swap(a,Ca,function(){return Ia(a,b,d)}):Ia(a,b,d):void 0},set:function(a,c,d){var e=d&&wa(a);return Ga(a,c,d?Ha(a,b,d,"border-box"===n.css(a,"boxSizing",!1,e),e):0)}}}),n.cssHooks.marginRight=ya(k.reliableMarginRight,function(a,b){return b?n.swap(a,{display:"inline-block"},xa,[a,"marginRight"]):void 0}),n.each({margin:"",padding:"",border:"Width"},function(a,b){n.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f="string"==typeof c?c.split(" "):[c];4>d;d++)e[a+R[d]+b]=f[d]||f[d-2]||f[0];return e}},ua.test(a)||(n.cssHooks[a+b].set=Ga)}),n.fn.extend({css:function(a,b){return J(this,function(a,b,c){var d,e,f={},g=0;if(n.isArray(b)){for(d=wa(a),e=b.length;e>g;g++)f[b[g]]=n.css(a,b[g],!1,d);return f}return void 0!==c?n.style(a,b,c):n.css(a,b)},a,b,arguments.length>1)},show:function(){return Ja(this,!0)},hide:function(){return Ja(this)},toggle:function(a){return"boolean"==typeof a?a?this.show():this.hide():this.each(function(){S(this)?n(this).show():n(this).hide()})}});function Ka(a,b,c,d,e){return new Ka.prototype.init(a,b,c,d,e)}n.Tween=Ka,Ka.prototype={constructor:Ka,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||"swing",this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(n.cssNumber[c]?"":"px")},cur:function(){var a=Ka.propHooks[this.prop];return a&&a.get?a.get(this):Ka.propHooks._default.get(this)},run:function(a){var b,c=Ka.propHooks[this.prop];return this.options.duration?this.pos=b=n.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):this.pos=b=a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):Ka.propHooks._default.set(this),this}},Ka.prototype.init.prototype=Ka.prototype,Ka.propHooks={_default:{get:function(a){var b;return null==a.elem[a.prop]||a.elem.style&&null!=a.elem.style[a.prop]?(b=n.css(a.elem,a.prop,""),b&&"auto"!==b?b:0):a.elem[a.prop]},set:function(a){n.fx.step[a.prop]?n.fx.step[a.prop](a):a.elem.style&&(null!=a.elem.style[n.cssProps[a.prop]]||n.cssHooks[a.prop])?n.style(a.elem,a.prop,a.now+a.unit):a.elem[a.prop]=a.now}}},Ka.propHooks.scrollTop=Ka.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},n.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2}},n.fx=Ka.prototype.init,n.fx.step={};var La,Ma,Na=/^(?:toggle|show|hide)$/,Oa=new RegExp("^(?:([+-])=|)("+Q+")([a-z%]*)$","i"),Pa=/queueHooks$/,Qa=[Va],Ra={"*":[function(a,b){var c=this.createTween(a,b),d=c.cur(),e=Oa.exec(b),f=e&&e[3]||(n.cssNumber[a]?"":"px"),g=(n.cssNumber[a]||"px"!==f&&+d)&&Oa.exec(n.css(c.elem,a)),h=1,i=20;if(g&&g[3]!==f){f=f||g[3],e=e||[],g=+d||1;do h=h||".5",g/=h,n.style(c.elem,a,g+f);while(h!==(h=c.cur()/d)&&1!==h&&--i)}return e&&(g=c.start=+g||+d||0,c.unit=f,c.end=e[1]?g+(e[1]+1)*e[2]:+e[2]),c}]};function Sa(){return setTimeout(function(){La=void 0}),La=n.now()}function Ta(a,b){var c,d=0,e={height:a};for(b=b?1:0;4>d;d+=2-b)c=R[d],e["margin"+c]=e["padding"+c]=a;return b&&(e.opacity=e.width=a),e}function Ua(a,b,c){for(var d,e=(Ra[b]||[]).concat(Ra["*"]),f=0,g=e.length;g>f;f++)if(d=e[f].call(c,b,a))return d}function Va(a,b,c){var d,e,f,g,h,i,j,k,l=this,m={},o=a.style,p=a.nodeType&&S(a),q=L.get(a,"fxshow");c.queue||(h=n._queueHooks(a,"fx"),null==h.unqueued&&(h.unqueued=0,i=h.empty.fire,h.empty.fire=function(){h.unqueued||i()}),h.unqueued++,l.always(function(){l.always(function(){h.unqueued--,n.queue(a,"fx").length||h.empty.fire()})})),1===a.nodeType&&("height"in b||"width"in b)&&(c.overflow=[o.overflow,o.overflowX,o.overflowY],j=n.css(a,"display"),k="none"===j?L.get(a,"olddisplay")||ta(a.nodeName):j,"inline"===k&&"none"===n.css(a,"float")&&(o.display="inline-block")),c.overflow&&(o.overflow="hidden",l.always(function(){o.overflow=c.overflow[0],o.overflowX=c.overflow[1],o.overflowY=c.overflow[2]}));for(d in b)if(e=b[d],Na.exec(e)){if(delete b[d],f=f||"toggle"===e,e===(p?"hide":"show")){if("show"!==e||!q||void 0===q[d])continue;p=!0}m[d]=q&&q[d]||n.style(a,d)}else j=void 0;if(n.isEmptyObject(m))"inline"===("none"===j?ta(a.nodeName):j)&&(o.display=j);else{q?"hidden"in q&&(p=q.hidden):q=L.access(a,"fxshow",{}),f&&(q.hidden=!p),p?n(a).show():l.done(function(){n(a).hide()}),l.done(function(){var b;L.remove(a,"fxshow");for(b in m)n.style(a,b,m[b])});for(d in m)g=Ua(p?q[d]:0,d,l),d in q||(q[d]=g.start,p&&(g.end=g.start,g.start="width"===d||"height"===d?1:0))}}function Wa(a,b){var c,d,e,f,g;for(c in a)if(d=n.camelCase(c),e=b[d],f=a[c],n.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=n.cssHooks[d],g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function Xa(a,b,c){var d,e,f=0,g=Qa.length,h=n.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=La||Sa(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;i>g;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),1>f&&i?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:n.extend({},b),opts:n.extend(!0,{specialEasing:{}},c),originalProperties:b,originalOptions:c,startTime:La||Sa(),duration:c.duration,tweens:[],createTween:function(b,c){var d=n.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;d>c;c++)j.tweens[c].run(1);return b?h.resolveWith(a,[j,b]):h.rejectWith(a,[j,b]),this}}),k=j.props;for(Wa(k,j.opts.specialEasing);g>f;f++)if(d=Qa[f].call(j,a,k,j.opts))return d;return n.map(k,Ua,j),n.isFunction(j.opts.start)&&j.opts.start.call(a,j),n.fx.timer(n.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}n.Animation=n.extend(Xa,{tweener:function(a,b){n.isFunction(a)?(b=a,a=["*"]):a=a.split(" ");for(var c,d=0,e=a.length;e>d;d++)c=a[d],Ra[c]=Ra[c]||[],Ra[c].unshift(b)},prefilter:function(a,b){b?Qa.unshift(a):Qa.push(a)}}),n.speed=function(a,b,c){var d=a&&"object"==typeof a?n.extend({},a):{complete:c||!c&&b||n.isFunction(a)&&a,duration:a,easing:c&&b||b&&!n.isFunction(b)&&b};return d.duration=n.fx.off?0:"number"==typeof d.duration?d.duration:d.duration in n.fx.speeds?n.fx.speeds[d.duration]:n.fx.speeds._default,(null==d.queue||d.queue===!0)&&(d.queue="fx"),d.old=d.complete,d.complete=function(){n.isFunction(d.old)&&d.old.call(this),d.queue&&n.dequeue(this,d.queue)},d},n.fn.extend({fadeTo:function(a,b,c,d){return this.filter(S).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=n.isEmptyObject(a),f=n.speed(b,c,d),g=function(){var b=Xa(this,n.extend({},a),f);(e||L.get(this,"finish"))&&b.stop(!0)};return g.finish=g,e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,b,c){var d=function(a){var b=a.stop;delete a.stop,b(c)};return"string"!=typeof a&&(c=b,b=a,a=void 0),b&&a!==!1&&this.queue(a||"fx",[]),this.each(function(){var b=!0,e=null!=a&&a+"queueHooks",f=n.timers,g=L.get(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&Pa.test(e)&&d(g[e]);for(e=f.length;e--;)f[e].elem!==this||null!=a&&f[e].queue!==a||(f[e].anim.stop(c),b=!1,f.splice(e,1));(b||!c)&&n.dequeue(this,a)})},finish:function(a){return a!==!1&&(a=a||"fx"),this.each(function(){var b,c=L.get(this),d=c[a+"queue"],e=c[a+"queueHooks"],f=n.timers,g=d?d.length:0;for(c.finish=!0,n.queue(this,a,[]),e&&e.stop&&e.stop.call(this,!0),b=f.length;b--;)f[b].elem===this&&f[b].queue===a&&(f[b].anim.stop(!0),f.splice(b,1));for(b=0;g>b;b++)d[b]&&d[b].finish&&d[b].finish.call(this);delete c.finish})}}),n.each(["toggle","show","hide"],function(a,b){var c=n.fn[b];n.fn[b]=function(a,d,e){return null==a||"boolean"==typeof a?c.apply(this,arguments):this.animate(Ta(b,!0),a,d,e)}}),n.each({slideDown:Ta("show"),slideUp:Ta("hide"),slideToggle:Ta("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){n.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),n.timers=[],n.fx.tick=function(){var a,b=0,c=n.timers;for(La=n.now();b<c.length;b++)a=c[b],a()||c[b]!==a||c.splice(b--,1);c.length||n.fx.stop(),La=void 0},n.fx.timer=function(a){n.timers.push(a),a()?n.fx.start():n.timers.pop()},n.fx.interval=13,n.fx.start=function(){Ma||(Ma=setInterval(n.fx.tick,n.fx.interval))},n.fx.stop=function(){clearInterval(Ma),Ma=null},n.fx.speeds={slow:600,fast:200,_default:400},n.fn.delay=function(a,b){return a=n.fx?n.fx.speeds[a]||a:a,b=b||"fx",this.queue(b,function(b,c){var d=setTimeout(b,a);c.stop=function(){clearTimeout(d)}})},function(){var a=l.createElement("input"),b=l.createElement("select"),c=b.appendChild(l.createElement("option"));a.type="checkbox",k.checkOn=""!==a.value,k.optSelected=c.selected,b.disabled=!0,k.optDisabled=!c.disabled,a=l.createElement("input"),a.value="t",a.type="radio",k.radioValue="t"===a.value}();var Ya,Za,$a=n.expr.attrHandle;n.fn.extend({attr:function(a,b){return J(this,n.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){n.removeAttr(this,a)})}}),n.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(a&&3!==f&&8!==f&&2!==f)return typeof a.getAttribute===U?n.prop(a,b,c):(1===f&&n.isXMLDoc(a)||(b=b.toLowerCase(),d=n.attrHooks[b]||(n.expr.match.bool.test(b)?Za:Ya)),
+void 0===c?d&&"get"in d&&null!==(e=d.get(a,b))?e:(e=n.find.attr(a,b),null==e?void 0:e):null!==c?d&&"set"in d&&void 0!==(e=d.set(a,c,b))?e:(a.setAttribute(b,c+""),c):void n.removeAttr(a,b))},removeAttr:function(a,b){var c,d,e=0,f=b&&b.match(E);if(f&&1===a.nodeType)while(c=f[e++])d=n.propFix[c]||c,n.expr.match.bool.test(c)&&(a[d]=!1),a.removeAttribute(c)},attrHooks:{type:{set:function(a,b){if(!k.radioValue&&"radio"===b&&n.nodeName(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}}}),Za={set:function(a,b,c){return b===!1?n.removeAttr(a,c):a.setAttribute(c,c),c}},n.each(n.expr.match.bool.source.match(/\w+/g),function(a,b){var c=$a[b]||n.find.attr;$a[b]=function(a,b,d){var e,f;return d||(f=$a[b],$a[b]=e,e=null!=c(a,b,d)?b.toLowerCase():null,$a[b]=f),e}});var _a=/^(?:input|select|textarea|button)$/i;n.fn.extend({prop:function(a,b){return J(this,n.prop,a,b,arguments.length>1)},removeProp:function(a){return this.each(function(){delete this[n.propFix[a]||a]})}}),n.extend({propFix:{"for":"htmlFor","class":"className"},prop:function(a,b,c){var d,e,f,g=a.nodeType;if(a&&3!==g&&8!==g&&2!==g)return f=1!==g||!n.isXMLDoc(a),f&&(b=n.propFix[b]||b,e=n.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){return a.hasAttribute("tabindex")||_a.test(a.nodeName)||a.href?a.tabIndex:-1}}}}),k.optSelected||(n.propHooks.selected={get:function(a){var b=a.parentNode;return b&&b.parentNode&&b.parentNode.selectedIndex,null}}),n.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){n.propFix[this.toLowerCase()]=this});var ab=/[\t\r\n\f]/g;n.fn.extend({addClass:function(a){var b,c,d,e,f,g,h="string"==typeof a&&a,i=0,j=this.length;if(n.isFunction(a))return this.each(function(b){n(this).addClass(a.call(this,b,this.className))});if(h)for(b=(a||"").match(E)||[];j>i;i++)if(c=this[i],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(ab," "):" ")){f=0;while(e=b[f++])d.indexOf(" "+e+" ")<0&&(d+=e+" ");g=n.trim(d),c.className!==g&&(c.className=g)}return this},removeClass:function(a){var b,c,d,e,f,g,h=0===arguments.length||"string"==typeof a&&a,i=0,j=this.length;if(n.isFunction(a))return this.each(function(b){n(this).removeClass(a.call(this,b,this.className))});if(h)for(b=(a||"").match(E)||[];j>i;i++)if(c=this[i],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(ab," "):"")){f=0;while(e=b[f++])while(d.indexOf(" "+e+" ")>=0)d=d.replace(" "+e+" "," ");g=a?n.trim(d):"",c.className!==g&&(c.className=g)}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):this.each(n.isFunction(a)?function(c){n(this).toggleClass(a.call(this,c,this.className,b),b)}:function(){if("string"===c){var b,d=0,e=n(this),f=a.match(E)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else(c===U||"boolean"===c)&&(this.className&&L.set(this,"__className__",this.className),this.className=this.className||a===!1?"":L.get(this,"__className__")||"")})},hasClass:function(a){for(var b=" "+a+" ",c=0,d=this.length;d>c;c++)if(1===this[c].nodeType&&(" "+this[c].className+" ").replace(ab," ").indexOf(b)>=0)return!0;return!1}});var bb=/\r/g;n.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=n.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,n(this).val()):a,null==e?e="":"number"==typeof e?e+="":n.isArray(e)&&(e=n.map(e,function(a){return null==a?"":a+""})),b=n.valHooks[this.type]||n.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=n.valHooks[e.type]||n.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(bb,""):null==c?"":c)}}}),n.extend({valHooks:{option:{get:function(a){var b=n.find.attr(a,"value");return null!=b?b:n.trim(n.text(a))}},select:{get:function(a){for(var b,c,d=a.options,e=a.selectedIndex,f="select-one"===a.type||0>e,g=f?null:[],h=f?e+1:d.length,i=0>e?h:f?e:0;h>i;i++)if(c=d[i],!(!c.selected&&i!==e||(k.optDisabled?c.disabled:null!==c.getAttribute("disabled"))||c.parentNode.disabled&&n.nodeName(c.parentNode,"optgroup"))){if(b=n(c).val(),f)return b;g.push(b)}return g},set:function(a,b){var c,d,e=a.options,f=n.makeArray(b),g=e.length;while(g--)d=e[g],(d.selected=n.inArray(d.value,f)>=0)&&(c=!0);return c||(a.selectedIndex=-1),f}}}}),n.each(["radio","checkbox"],function(){n.valHooks[this]={set:function(a,b){return n.isArray(b)?a.checked=n.inArray(n(a).val(),b)>=0:void 0}},k.checkOn||(n.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})}),n.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(a,b){n.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),n.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)},bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return 1===arguments.length?this.off(a,"**"):this.off(b,a||"**",c)}});var cb=n.now(),db=/\?/;n.parseJSON=function(a){return JSON.parse(a+"")},n.parseXML=function(a){var b,c;if(!a||"string"!=typeof a)return null;try{c=new DOMParser,b=c.parseFromString(a,"text/xml")}catch(d){b=void 0}return(!b||b.getElementsByTagName("parsererror").length)&&n.error("Invalid XML: "+a),b};var eb=/#.*$/,fb=/([?&])_=[^&]*/,gb=/^(.*?):[ \t]*([^\r\n]*)$/gm,hb=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,ib=/^(?:GET|HEAD)$/,jb=/^\/\//,kb=/^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,lb={},mb={},nb="*/".concat("*"),ob=a.location.href,pb=kb.exec(ob.toLowerCase())||[];function qb(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(E)||[];if(n.isFunction(c))while(d=f[e++])"+"===d[0]?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function rb(a,b,c,d){var e={},f=a===mb;function g(h){var i;return e[h]=!0,n.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function sb(a,b){var c,d,e=n.ajaxSettings.flatOptions||{};for(c in b)void 0!==b[c]&&((e[c]?a:d||(d={}))[c]=b[c]);return d&&n.extend(!0,a,d),a}function tb(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===d&&(d=a.mimeType||b.getResponseHeader("Content-Type"));if(d)for(e in h)if(h[e]&&h[e].test(d)){i.unshift(e);break}if(i[0]in c)f=i[0];else{for(e in c){if(!i[0]||a.converters[e+" "+i[0]]){f=e;break}g||(g=e)}f=f||g}return f?(f!==i[0]&&i.unshift(f),c[f]):void 0}function ub(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}n.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:ob,type:"GET",isLocal:hb.test(pb[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":nb,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":n.parseJSON,"text xml":n.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?sb(sb(a,n.ajaxSettings),b):sb(n.ajaxSettings,a)},ajaxPrefilter:qb(lb),ajaxTransport:qb(mb),ajax:function(a,b){"object"==typeof a&&(b=a,a=void 0),b=b||{};var c,d,e,f,g,h,i,j,k=n.ajaxSetup({},b),l=k.context||k,m=k.context&&(l.nodeType||l.jquery)?n(l):n.event,o=n.Deferred(),p=n.Callbacks("once memory"),q=k.statusCode||{},r={},s={},t=0,u="canceled",v={readyState:0,getResponseHeader:function(a){var b;if(2===t){if(!f){f={};while(b=gb.exec(e))f[b[1].toLowerCase()]=b[2]}b=f[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return 2===t?e:null},setRequestHeader:function(a,b){var c=a.toLowerCase();return t||(a=s[c]=s[c]||a,r[a]=b),this},overrideMimeType:function(a){return t||(k.mimeType=a),this},statusCode:function(a){var b;if(a)if(2>t)for(b in a)q[b]=[q[b],a[b]];else v.always(a[v.status]);return this},abort:function(a){var b=a||u;return c&&c.abort(b),x(0,b),this}};if(o.promise(v).complete=p.add,v.success=v.done,v.error=v.fail,k.url=((a||k.url||ob)+"").replace(eb,"").replace(jb,pb[1]+"//"),k.type=b.method||b.type||k.method||k.type,k.dataTypes=n.trim(k.dataType||"*").toLowerCase().match(E)||[""],null==k.crossDomain&&(h=kb.exec(k.url.toLowerCase()),k.crossDomain=!(!h||h[1]===pb[1]&&h[2]===pb[2]&&(h[3]||("http:"===h[1]?"80":"443"))===(pb[3]||("http:"===pb[1]?"80":"443")))),k.data&&k.processData&&"string"!=typeof k.data&&(k.data=n.param(k.data,k.traditional)),rb(lb,k,b,v),2===t)return v;i=n.event&&k.global,i&&0===n.active++&&n.event.trigger("ajaxStart"),k.type=k.type.toUpperCase(),k.hasContent=!ib.test(k.type),d=k.url,k.hasContent||(k.data&&(d=k.url+=(db.test(d)?"&":"?")+k.data,delete k.data),k.cache===!1&&(k.url=fb.test(d)?d.replace(fb,"$1_="+cb++):d+(db.test(d)?"&":"?")+"_="+cb++)),k.ifModified&&(n.lastModified[d]&&v.setRequestHeader("If-Modified-Since",n.lastModified[d]),n.etag[d]&&v.setRequestHeader("If-None-Match",n.etag[d])),(k.data&&k.hasContent&&k.contentType!==!1||b.contentType)&&v.setRequestHeader("Content-Type",k.contentType),v.setRequestHeader("Accept",k.dataTypes[0]&&k.accepts[k.dataTypes[0]]?k.accepts[k.dataTypes[0]]+("*"!==k.dataTypes[0]?", "+nb+"; q=0.01":""):k.accepts["*"]);for(j in k.headers)v.setRequestHeader(j,k.headers[j]);if(k.beforeSend&&(k.beforeSend.call(l,v,k)===!1||2===t))return v.abort();u="abort";for(j in{success:1,error:1,complete:1})v[j](k[j]);if(c=rb(mb,k,b,v)){v.readyState=1,i&&m.trigger("ajaxSend",[v,k]),k.async&&k.timeout>0&&(g=setTimeout(function(){v.abort("timeout")},k.timeout));try{t=1,c.send(r,x)}catch(w){if(!(2>t))throw w;x(-1,w)}}else x(-1,"No Transport");function x(a,b,f,h){var j,r,s,u,w,x=b;2!==t&&(t=2,g&&clearTimeout(g),c=void 0,e=h||"",v.readyState=a>0?4:0,j=a>=200&&300>a||304===a,f&&(u=tb(k,v,f)),u=ub(k,u,v,j),j?(k.ifModified&&(w=v.getResponseHeader("Last-Modified"),w&&(n.lastModified[d]=w),w=v.getResponseHeader("etag"),w&&(n.etag[d]=w)),204===a||"HEAD"===k.type?x="nocontent":304===a?x="notmodified":(x=u.state,r=u.data,s=u.error,j=!s)):(s=x,(a||!x)&&(x="error",0>a&&(a=0))),v.status=a,v.statusText=(b||x)+"",j?o.resolveWith(l,[r,x,v]):o.rejectWith(l,[v,x,s]),v.statusCode(q),q=void 0,i&&m.trigger(j?"ajaxSuccess":"ajaxError",[v,k,j?r:s]),p.fireWith(l,[v,x]),i&&(m.trigger("ajaxComplete",[v,k]),--n.active||n.event.trigger("ajaxStop")))}return v},getJSON:function(a,b,c){return n.get(a,b,c,"json")},getScript:function(a,b){return n.get(a,void 0,b,"script")}}),n.each(["get","post"],function(a,b){n[b]=function(a,c,d,e){return n.isFunction(c)&&(e=e||d,d=c,c=void 0),n.ajax({url:a,type:b,dataType:e,data:c,success:d})}}),n._evalUrl=function(a){return n.ajax({url:a,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0})},n.fn.extend({wrapAll:function(a){var b;return n.isFunction(a)?this.each(function(b){n(this).wrapAll(a.call(this,b))}):(this[0]&&(b=n(a,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstElementChild)a=a.firstElementChild;return a}).append(this)),this)},wrapInner:function(a){return this.each(n.isFunction(a)?function(b){n(this).wrapInner(a.call(this,b))}:function(){var b=n(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=n.isFunction(a);return this.each(function(c){n(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){n.nodeName(this,"body")||n(this).replaceWith(this.childNodes)}).end()}}),n.expr.filters.hidden=function(a){return a.offsetWidth<=0&&a.offsetHeight<=0},n.expr.filters.visible=function(a){return!n.expr.filters.hidden(a)};var vb=/%20/g,wb=/\[\]$/,xb=/\r?\n/g,yb=/^(?:submit|button|image|reset|file)$/i,zb=/^(?:input|select|textarea|keygen)/i;function Ab(a,b,c,d){var e;if(n.isArray(b))n.each(b,function(b,e){c||wb.test(a)?d(a,e):Ab(a+"["+("object"==typeof e?b:"")+"]",e,c,d)});else if(c||"object"!==n.type(b))d(a,b);else for(e in b)Ab(a+"["+e+"]",b[e],c,d)}n.param=function(a,b){var c,d=[],e=function(a,b){b=n.isFunction(b)?b():null==b?"":b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};if(void 0===b&&(b=n.ajaxSettings&&n.ajaxSettings.traditional),n.isArray(a)||a.jquery&&!n.isPlainObject(a))n.each(a,function(){e(this.name,this.value)});else for(c in a)Ab(c,a[c],b,e);return d.join("&").replace(vb,"+")},n.fn.extend({serialize:function(){return n.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=n.prop(this,"elements");return a?n.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!n(this).is(":disabled")&&zb.test(this.nodeName)&&!yb.test(a)&&(this.checked||!T.test(a))}).map(function(a,b){var c=n(this).val();return null==c?null:n.isArray(c)?n.map(c,function(a){return{name:b.name,value:a.replace(xb,"\r\n")}}):{name:b.name,value:c.replace(xb,"\r\n")}}).get()}}),n.ajaxSettings.xhr=function(){try{return new XMLHttpRequest}catch(a){}};var Bb=0,Cb={},Db={0:200,1223:204},Eb=n.ajaxSettings.xhr();a.attachEvent&&a.attachEvent("onunload",function(){for(var a in Cb)Cb[a]()}),k.cors=!!Eb&&"withCredentials"in Eb,k.ajax=Eb=!!Eb,n.ajaxTransport(function(a){var b;return k.cors||Eb&&!a.crossDomain?{send:function(c,d){var e,f=a.xhr(),g=++Bb;if(f.open(a.type,a.url,a.async,a.username,a.password),a.xhrFields)for(e in a.xhrFields)f[e]=a.xhrFields[e];a.mimeType&&f.overrideMimeType&&f.overrideMimeType(a.mimeType),a.crossDomain||c["X-Requested-With"]||(c["X-Requested-With"]="XMLHttpRequest");for(e in c)f.setRequestHeader(e,c[e]);b=function(a){return function(){b&&(delete Cb[g],b=f.onload=f.onerror=null,"abort"===a?f.abort():"error"===a?d(f.status,f.statusText):d(Db[f.status]||f.status,f.statusText,"string"==typeof f.responseText?{text:f.responseText}:void 0,f.getAllResponseHeaders()))}},f.onload=b(),f.onerror=b("error"),b=Cb[g]=b("abort");try{f.send(a.hasContent&&a.data||null)}catch(h){if(b)throw h}},abort:function(){b&&b()}}:void 0}),n.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/(?:java|ecma)script/},converters:{"text script":function(a){return n.globalEval(a),a}}}),n.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET")}),n.ajaxTransport("script",function(a){if(a.crossDomain){var b,c;return{send:function(d,e){b=n("<script>").prop({async:!0,charset:a.scriptCharset,src:a.url}).on("load error",c=function(a){b.remove(),c=null,a&&e("error"===a.type?404:200,a.type)}),l.head.appendChild(b[0])},abort:function(){c&&c()}}}});var Fb=[],Gb=/(=)\?(?=&|$)|\?\?/;n.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=Fb.pop()||n.expando+"_"+cb++;return this[a]=!0,a}}),n.ajaxPrefilter("json jsonp",function(b,c,d){var e,f,g,h=b.jsonp!==!1&&(Gb.test(b.url)?"url":"string"==typeof b.data&&!(b.contentType||"").indexOf("application/x-www-form-urlencoded")&&Gb.test(b.data)&&"data");return h||"jsonp"===b.dataTypes[0]?(e=b.jsonpCallback=n.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,h?b[h]=b[h].replace(Gb,"$1"+e):b.jsonp!==!1&&(b.url+=(db.test(b.url)?"&":"?")+b.jsonp+"="+e),b.converters["script json"]=function(){return g||n.error(e+" was not called"),g[0]},b.dataTypes[0]="json",f=a[e],a[e]=function(){g=arguments},d.always(function(){a[e]=f,b[e]&&(b.jsonpCallback=c.jsonpCallback,Fb.push(e)),g&&n.isFunction(f)&&f(g[0]),g=f=void 0}),"script"):void 0}),n.parseHTML=function(a,b,c){if(!a||"string"!=typeof a)return null;"boolean"==typeof b&&(c=b,b=!1),b=b||l;var d=v.exec(a),e=!c&&[];return d?[b.createElement(d[1])]:(d=n.buildFragment([a],b,e),e&&e.length&&n(e).remove(),n.merge([],d.childNodes))};var Hb=n.fn.load;n.fn.load=function(a,b,c){if("string"!=typeof a&&Hb)return Hb.apply(this,arguments);var d,e,f,g=this,h=a.indexOf(" ");return h>=0&&(d=n.trim(a.slice(h)),a=a.slice(0,h)),n.isFunction(b)?(c=b,b=void 0):b&&"object"==typeof b&&(e="POST"),g.length>0&&n.ajax({url:a,type:e,dataType:"html",data:b}).done(function(a){f=arguments,g.html(d?n("<div>").append(n.parseHTML(a)).find(d):a)}).complete(c&&function(a,b){g.each(c,f||[a.responseText,b,a])}),this},n.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(a,b){n.fn[b]=function(a){return this.on(b,a)}}),n.expr.filters.animated=function(a){return n.grep(n.timers,function(b){return a===b.elem}).length};var Ib=a.document.documentElement;function Jb(a){return n.isWindow(a)?a:9===a.nodeType&&a.defaultView}n.offset={setOffset:function(a,b,c){var d,e,f,g,h,i,j,k=n.css(a,"position"),l=n(a),m={};"static"===k&&(a.style.position="relative"),h=l.offset(),f=n.css(a,"top"),i=n.css(a,"left"),j=("absolute"===k||"fixed"===k)&&(f+i).indexOf("auto")>-1,j?(d=l.position(),g=d.top,e=d.left):(g=parseFloat(f)||0,e=parseFloat(i)||0),n.isFunction(b)&&(b=b.call(a,c,h)),null!=b.top&&(m.top=b.top-h.top+g),null!=b.left&&(m.left=b.left-h.left+e),"using"in b?b.using.call(a,m):l.css(m)}},n.fn.extend({offset:function(a){if(arguments.length)return void 0===a?this:this.each(function(b){n.offset.setOffset(this,a,b)});var b,c,d=this[0],e={top:0,left:0},f=d&&d.ownerDocument;if(f)return b=f.documentElement,n.contains(b,d)?(typeof d.getBoundingClientRect!==U&&(e=d.getBoundingClientRect()),c=Jb(f),{top:e.top+c.pageYOffset-b.clientTop,left:e.left+c.pageXOffset-b.clientLeft}):e},position:function(){if(this[0]){var a,b,c=this[0],d={top:0,left:0};return"fixed"===n.css(c,"position")?b=c.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),n.nodeName(a[0],"html")||(d=a.offset()),d.top+=n.css(a[0],"borderTopWidth",!0),d.left+=n.css(a[0],"borderLeftWidth",!0)),{top:b.top-d.top-n.css(c,"marginTop",!0),left:b.left-d.left-n.css(c,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||Ib;while(a&&!n.nodeName(a,"html")&&"static"===n.css(a,"position"))a=a.offsetParent;return a||Ib})}}),n.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(b,c){var d="pageYOffset"===c;n.fn[b]=function(e){return J(this,function(b,e,f){var g=Jb(b);return void 0===f?g?g[c]:b[e]:void(g?g.scrollTo(d?a.pageXOffset:f,d?f:a.pageYOffset):b[e]=f)},b,e,arguments.length,null)}}),n.each(["top","left"],function(a,b){n.cssHooks[b]=ya(k.pixelPosition,function(a,c){return c?(c=xa(a,b),va.test(c)?n(a).position()[b]+"px":c):void 0})}),n.each({Height:"height",Width:"width"},function(a,b){n.each({padding:"inner"+a,content:b,"":"outer"+a},function(c,d){n.fn[d]=function(d,e){var f=arguments.length&&(c||"boolean"!=typeof d),g=c||(d===!0||e===!0?"margin":"border");return J(this,function(b,c,d){var e;return n.isWindow(b)?b.document.documentElement["client"+a]:9===b.nodeType?(e=b.documentElement,Math.max(b.body["scroll"+a],e["scroll"+a],b.body["offset"+a],e["offset"+a],e["client"+a])):void 0===d?n.css(b,c,g):n.style(b,c,d,g)},b,f?d:void 0,f,null)}})}),n.fn.size=function(){return this.length},n.fn.andSelf=n.fn.addBack,"function"==typeof define&&define.amd&&define("jquery",[],function(){return n});var Kb=a.jQuery,Lb=a.$;return n.noConflict=function(b){return a.$===n&&(a.$=Lb),b&&a.jQuery===n&&(a.jQuery=Kb),n},typeof b===U&&(a.jQuery=a.$=n),n});
diff --git a/modules/http/static/jquery.spdx b/modules/http/static/jquery.spdx
new file mode 100644
index 0000000..af3cbb4
--- /dev/null
+++ b/modules/http/static/jquery.spdx
@@ -0,0 +1,12 @@
+SPDXVersion: SPDX-2.1
+DataLicense: CC0-1.0
+SPDXID: SPDXRef-DOCUMENT
+DocumentName: jquery
+DocumentNamespace: http://spdx.org/spdxdocs/spdx-v2.1-d1bf4e73-cd79-434a-ba6c-834967690525
+
+PackageName: jquery
+PackageVersion: 2.1.4
+PackageDownloadLocation: https://code.jquery.com/jquery-2.1.4.min.js
+PackageChecksum: SHA256: f16ab224bb962910558715c82f58c10c3ed20f153ddfaa199029f141b5b0255c
+PackageOriginator: Organization: jQuery Foundation
+PackageLicenseDeclared: MIT
diff --git a/modules/http/static/kresd.css b/modules/http/static/kresd.css
new file mode 100644
index 0000000..16238a4
--- /dev/null
+++ b/modules/http/static/kresd.css
@@ -0,0 +1,44 @@
+/*
+ * Base structure
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+/* Move down content because we have a fixed navbar that is 50px tall */
+body {
+ padding-top: 50px;
+}
+
+/*
+ * Tags and labels.
+ */
+.tag {
+ margin: 0 3px 3px 0;
+}
+
+.tag-default {
+ background-color: #efefef !important;
+ color: #000 !important;
+}
+
+.tag-warning {
+ background-color: #f0ad4e !important;
+ border-color: #eea236 !important;
+ color: #fff !important;
+}
+.tag-success {
+ background-color: #5cb85c !important;
+ border-color: #4cae4c !important;
+ color: #fff !important;
+}
+
+.spark {
+ display: inline-block;
+}
+
+.spark-legend {
+ display: inline-block;
+}
+
+.dygraph-legend {
+ text-align: right;
+}
diff --git a/modules/http/static/kresd.js b/modules/http/static/kresd.js
new file mode 100644
index 0000000..6a6dab1
--- /dev/null
+++ b/modules/http/static/kresd.js
@@ -0,0 +1,367 @@
+/* SPDX-License-Identifier: GPL-3.0-or-later */
+var colours = ["#081d58", "#253494", "#225ea8", "#1d91c0", "#41b6c4", "#7fcdbb", "#c7e9b4", "#edf8b1", "#edf8b1"];
+var latency = ["slow", "1500ms", "1000ms", "500ms", "250ms", "100ms", "50ms", "10ms", "1ms"];
+var Socket = "MozWebSocket" in window ? MozWebSocket : WebSocket;
+let isGraphPaused = false;
+
+$(function() {
+ /* Helper functions */
+ function colorBracket(rtt) {
+ for (var i = latency.length - 1; i >= 0; i--) {
+ if (rtt <= parseInt(latency[i])) {
+ return 'q' + i;
+ }
+ }
+ return 'q8';
+ }
+ function toGeokey(lon, lat) {
+ return lon.toFixed(0)+'#'+lat.toFixed(0);
+ }
+ function updateVisibility(graph, metrics, id, toggle) {
+ /* Some labels are aggregates */
+ if (metrics[id] == null) {
+ for (var key in metrics) {
+ const m = metrics[key];
+ if (m.length > 3 && m[3] == id) {
+ graph.setVisibility(m[0], toggle);
+ }
+ }
+ } else {
+ graph.setVisibility(metrics[id][0], toggle);
+ }
+ }
+ function formatNumber(n) {
+ with (Math) {
+ var base = floor(log(abs(n))/log(1000));
+ var suffix = 'KMB'[base-1];
+ return suffix ? String(n/pow(1000,base)).substring(0,3)+suffix : ''+n;
+ }
+ }
+
+ /* Initialize snippets. */
+ $('section').each(function () {
+ const heading = $(this).find('h2');
+ $('#modules-dropdown').append('<li><a href="#'+this.id+'">'+heading.text()+'</a></li>');
+ });
+
+ /* Render other interesting metrics as lines (hidden by default) */
+ var data = [];
+ var last_metric = 17;
+ var metrics = {
+ 'answer.noerror': [0, 'NOERROR', null, 'By RCODE'],
+ 'answer.nodata': [1, 'NODATA', null, 'By RCODE'],
+ 'answer.nxdomain': [2, 'NXDOMAIN', null, 'By RCODE'],
+ 'answer.servfail': [3, 'SERVFAIL', null, 'By RCODE'],
+ 'answer.dnssec': [4, 'DNSSEC', null, 'By RCODE'],
+ 'cache.hit': [5, 'Cache hit'],
+ 'cache.miss': [6, 'Cache miss'],
+ 'cache.insert': [7, 'Cache insert'],
+ 'cache.delete': [8, 'Cache delete'],
+ 'worker.udp': [9, 'UDP queries'],
+ 'worker.tcp': [10, 'TCP queries'],
+ 'worker.ipv4': [11, 'IPv4 queries'],
+ 'worker.ipv6': [12, 'IPv6 queries'],
+ 'worker.concurrent': [13, 'Concurrent requests'],
+ 'worker.queries': [14, 'Queries received/s'],
+ 'worker.dropped': [15, 'Queries dropped'],
+ 'worker.usertime': [16, 'CPU (user)', null, 'Workers'],
+ 'worker.systime': [17, 'CPU (sys)', null, 'Workers'],
+ };
+
+ /* Render latency metrics as sort of a heatmap */
+ var series = {};
+ for (var i in latency) {
+ const name = 'RTT '+latency[i];
+ const colour = colours[colours.length - i - 1];
+ last_metric = last_metric + 1;
+ metrics['answer.'+latency[i]] = [last_metric, name, colour, 'latency'];
+ series[name] = {fillGraph: true, color: colour, fillAlpha: 1.0};
+ }
+ var labels = ['x'];
+ var visibility = [];
+ for (var key in metrics) {
+ labels.push(metrics[key][1]);
+ visibility.push(false);
+ }
+
+ /* Define how graph looks like. */
+ const graphContainer = $('#stats');
+ const graph = new Dygraph(
+ document.getElementById("chart"),
+ data, {
+ labels: labels,
+ labelsUTC: true,
+ labelsShowZeroValues: false,
+ visibility: visibility,
+ axes: { y: {
+ axisLabelFormatter: function(d) {
+ return formatNumber(d) + 'pps';
+ },
+ }},
+ series: series,
+ strokeWidth: 1,
+ highlightSeriesOpts: {
+ strokeWidth: 3,
+ strokeBorderWidth: 1,
+ highlightCircleSize: 5,
+ },
+ });
+ /* Define metric selector */
+ const chartSelector = $('#chart-selector').selectize({
+ maxItems: null,
+ create: false,
+ onItemAdd: function (x) { updateVisibility(graph, metrics, x, true); },
+ onItemRemove: function (x) { updateVisibility(graph, metrics, x, false); }
+ })[0].selectize;
+ for (var key in metrics) {
+ const m = metrics[key];
+ const groupid = m.length > 3 ? m[3] : key.split('.')[0];
+ const group = m.length > 3 ? m[3] : m[1].split(' ')[0];
+ /* Latency has a special aggregated item */
+ if (group != 'latency') {
+ chartSelector.addOptionGroup(groupid, { label: group } );
+ chartSelector.addOption({ text: m[1], value: key, optgroup: groupid });
+ }
+ }
+ /* Add latency as default */
+ chartSelector.addOption({ text: 'Latency', value: 'latency', optgroup: 'Queries' });
+ chartSelector.addItem('latency');
+ /* Add stacked graph control */
+ $('#chart-stacked').on('change', function(e) {
+ graph.updateOptions({stackedGraph: this.checked});
+ }).click();
+
+ /* Data map */
+ var fills = { defaultFill: '#F5F5F5' };
+ for (var i in colours) {
+ fills['q' + i] = colours[i];
+ }
+ const map = new Datamap({
+ element: document.getElementById('map'),
+ fills: fills,
+ data: {},
+ height: 400,
+ geographyConfig: {
+ highlightOnHover: false,
+ borderColor: '#ccc',
+ borderWidth: 0.5,
+ popupTemplate: function(geo, data) {
+ return ['<div class="hoverinfo">',
+ '<strong>', geo.properties.name, '</strong>',
+ '<br>Queries: <strong>', data ? data.queries : '0', '</strong>',
+ '</div>'].join('');
+ }
+ },
+ bubblesConfig: {
+ popupTemplate: function(geo, data) {
+ return ['<div class="hoverinfo">',
+ '<strong>', data.name, '</strong>',
+ '<br>Queries: <strong>', data ? data.queries : '0', '</strong>',
+ '<br>Average RTT: <strong>', data ? parseInt(data.rtt) : '0', ' ms</strong>',
+ '</div>'].join('');
+ }
+ }
+ });
+
+ /* Realtime updates over WebSockets */
+ function pushMetrics(resp, now, buffer) {
+ var line = new Array(labels.length);
+ line[0] = new Date(now * 1000);
+ for (var lb in resp) {
+ /* Push new datapoints */
+ const metric = metrics[lb];
+ if (metric) {
+ line[metric[0] + 1] = resp[lb];
+ }
+ }
+ /* Buffer graph changes. */
+ data.push(line);
+ if (data.length > 1000) {
+ data.shift();
+ }
+ if ( !buffer ) {
+ if ( !isGraphPaused ) {
+ graph.updateOptions( { 'file': data } );
+ }
+ }
+ }
+
+ var age = 0;
+ var bubbles = [];
+ var bubblemap = {};
+ function pushUpstreams(resp) {
+ if (resp == null) {
+ $('#map-container').hide();
+ return;
+ } else {
+ $('#map-container').show();
+ }
+ /* Get current maximum number of queries for bubble diameter adjustment */
+ var maxQueries = 1;
+ for (var key in resp) {
+ var val = resp[key];
+ if ('data' in val) {
+ maxQueries = Math.max(maxQueries, resp[key].data.length)
+ }
+ }
+ /* Update bubbles and prune the oldest */
+ for (var key in resp) {
+ var val = resp[key];
+ if (!val.data || !val.location || val.location.longitude == null) {
+ continue;
+ }
+ var sum = val.data.reduce(function(a, b) { return a + b; });
+ var avg = sum / val.data.length;
+ var geokey = toGeokey(val.location.longitude, val.location.latitude)
+ var found = bubblemap[geokey];
+ if (!found) {
+ found = {
+ name: [key],
+ longitude: val.location.longitude,
+ latitude: val.location.latitude,
+ queries: 0,
+ rtt: avg,
+ }
+ bubbles.push(found);
+ bubblemap[geokey] = found;
+ }
+ /* Update bubble parameters */
+ if (!(key in found.name)) {
+ found.name.push(key);
+ }
+ found.rtt = (found.rtt + avg) / 2.0;
+ found.fillKey = colorBracket(found.rtt);
+ found.queries = found.queries + val.data.length;
+ found.radius = Math.max(5, 15*(val.data.length/maxQueries));
+ found.age = age;
+ }
+ /* Prune bubbles not updated in a while. */
+ for (var i in bubbles) {
+ var b = bubbles[i];
+ if (b.age <= age - 5) {
+ bubbles.splice(i, 1)
+ bubblemap[i] = null;
+ }
+ }
+ map.bubbles(bubbles);
+ age = age + 1;
+ }
+
+ /* Per-worker information */
+ function updateRate(x, y, dt) {
+ return (100.0 * ((x - y) / dt)).toFixed(1);
+ }
+ function updateWorker(row, next, data, timestamp, buffer) {
+ const dt = timestamp - data.timestamp;
+ const cell = row.find('td');
+ /* Update spark lines and CPU times first */
+ if (dt > 0.0) {
+ const utimeRate = updateRate(next.usertime, data.last.usertime, dt);
+ const stimeRate = updateRate(next.systime, data.last.systime, dt);
+ cell.eq(1).find('span').text(utimeRate + '% / ' + stimeRate + '%');
+ /* Update sparkline graph */
+ data.data.push([new Date(timestamp * 1000), Number(utimeRate), Number(stimeRate)]);
+ if (data.data.length > 60) {
+ data.data.shift();
+ }
+ if (!buffer) {
+ data.graph.updateOptions( { 'file': data.data } );
+ }
+ }
+ /* Update other fields */
+ if (!buffer) {
+ cell.eq(2).text(formatNumber(next.rss) + 'B');
+ cell.eq(3).text(next.pagefaults);
+ cell.eq(4).text('Healthy').addClass('text-success');
+ }
+ }
+
+ var workerData = {};
+ function pushWorkers(resp, timestamp, buffer) {
+ if (resp == null) {
+ return;
+ }
+ const workerTable = $('#workers');
+ for (var pid in resp) {
+ var row = workerTable.find('tr[data-pid='+pid+']');
+ if (row.length == 0) {
+ row = workerTable.append(
+ '<tr data-pid='+pid+'><td>'+pid+'</td>'+
+ '<td><div class="spark" id="spark-'+pid+'" /><span /></td><td></td><td></td><td></td>'+
+ '</tr>');
+ /* Create sparkline visualisation */
+ const spark = row.find('#spark-'+pid);
+ spark.css({'margin-right': '1em', width: '80px', height: '1.4em'});
+ workerData[pid] = {timestamp: timestamp, data: [[new Date(timestamp * 1000),0,0]], last: resp[pid]};
+ const workerGraph = new Dygraph(spark[0],
+ workerData[pid].data, {
+ valueRange: [0, 100],
+ legend: 'never',
+ axes : {
+ x : {
+ drawGrid: false,
+ drawAxis : false,
+ },
+ y : {
+ drawGrid: false,
+ drawAxis : false,
+ }
+ },
+ labels: ['x', '%user', '%sys'],
+ labelsDiv: '',
+ stackedGraph: true,
+ }
+ );
+ workerData[pid].graph = workerGraph;
+ }
+ updateWorker(row, resp[pid], workerData[pid], timestamp, buffer);
+ /* Track last datapoint */
+ workerData[pid].last = resp[pid];
+ workerData[pid].timestamp = timestamp;
+ }
+ /* Prune unhealthy PIDs */
+ if (!buffer) {
+ workerTable.find('tr').each(function () {
+ const e = $(this);
+ if (!(e.data('pid') in resp)) {
+ const healthCell = e.find('td').last();
+ healthCell.removeClass('text-success')
+ healthCell.text('Dead').addClass('text-danger');
+ }
+ });
+ }
+ }
+
+ /* WebSocket endpoints */
+ var wsStats = ('https:' == document.location.protocol ? 'wss://' : 'ws://') + location.host + '/stats';
+ var ws = new Socket(wsStats);
+ ws.onmessage = function(evt) {
+ var data = JSON.parse(evt.data);
+ if (data[0]) {
+ if (data.length > 0) {
+ pushUpstreams(data[data.length - 1].upstreams);
+ }
+ /* Buffer datapoints and redraw last */
+ for (var i in data) {
+ const is_last = (i == data.length - 1);
+ pushWorkers(data[i].workers, data[i].time, !is_last);
+ pushMetrics(data[i].stats, data[i].time, !is_last);
+ }
+ } else {
+ pushUpstreams(data.upstreams);
+ pushWorkers(data.workers, data.time);
+ pushMetrics(data.stats, data.time);
+ }
+ };
+
+ chartElement.addEventListener( 'mouseover', ( event ) =>
+ {
+ isGraphPaused = true;
+ }, false );
+
+ chartElement.addEventListener( 'mouseout', ( event ) =>
+ {
+ isGraphPaused = false;
+ }, false );
+
+});
diff --git a/modules/http/static/main.tpl b/modules/http/static/main.tpl
new file mode 100644
index 0000000..087f19e
--- /dev/null
+++ b/modules/http/static/main.tpl
@@ -0,0 +1,87 @@
+<!DOCTYPE html>
+<!-- SPDX-License-Identifier: GPL-3.0-or-later -->
+<meta charset="utf-8">
+<meta name="viewport" content="width=device-width, initial-scale=1">
+<title>{{ title }}</title>
+<script type="text/javascript">
+ var host = "{{ host }}";
+</script>
+<script src="jquery.js"></script>
+<script src="bootstrap.min.js"></script>
+<script src="d3.js"></script>
+<script src="dygraph.min.js"></script>
+<script src="selectize.min.js"></script>
+<script src="topojson.js"></script>
+<script src="datamaps.world.min.js"></script>
+<script src="kresd.js"></script>
+<link rel="icon" type="image/ico" href="favicon.ico">
+<link href="kresd.css" rel="stylesheet">
+<link href="bootstrap.min.css" rel="stylesheet">
+<link href="selectize.bootstrap3.css" rel="stylesheet">
+<nav class="navbar navbar-inverse navbar-fixed-top">
+ <div class="container">
+ <div class="navbar-header">
+ <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
+ <span class="sr-only">Toggle navigation</span>
+ <span class="icon-bar"></span>
+ <span class="icon-bar"></span>
+ <span class="icon-bar"></span>
+ </button>
+ <a class="navbar-brand" href="#">{{ title }}</a>
+ </div>
+ <ul class="nav navbar-nav navbar-right">
+ <li><a href="#">Metrics</a></li>
+ <li class="dropdown">
+ <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Modules <span class="caret"></span></a>
+ <ul class="dropdown-menu" id="modules-dropdown">
+ </ul>
+ </li>
+ </ul>
+ </div>
+</nav>
+<div class="container">
+ <div class="main">
+ <h2 class="sub-header">Metrics</h2>
+ <div class="col-md-12">
+ <div class="row">
+ <div id="stats" class="row placeholders">
+ <div id="chart" style="width:100%"></div>
+ </div>
+ </div>
+ <div class="row">
+ <div class="col-md-12">
+ <h3><small>More metrics</small></h3>
+ <div class="col-md-11">
+ <select id="chart-selector" multiple></select>
+ </div>
+ <div class="col-md-1">
+ <div class="checkbox">
+ <label><input id="chart-stacked" type="checkbox">Stacked</label>
+ </div>
+ </div>
+ </div>
+ </div>
+ <div class="row">
+ <h3>Instances</h3>
+ <div class="col-md-12">
+ <table id="workers" class="table table-responsive">
+ <tr>
+ <th>PID</th><th>CPU per-worker (user/sys)</th>
+ <th>RSS</th><th>Page faults</th><th>Status</th>
+ </tr>
+ </table>
+ </div>
+ </div>
+ </div>
+ <div class="row" id="map-container">
+ <a name="worldmap"></a>
+ <h2 class="sub-header">Outbound queries</h2>
+ <div class="col-md-12">
+ <div id="map" style="position: relative;"></div>
+ </div>
+ </div>
+ <div class="col-md-12">
+ {{ snippets }}
+ </div>
+ </div>
+</div>
diff --git a/modules/http/static/selectize.bootstrap3.css b/modules/http/static/selectize.bootstrap3.css
new file mode 100644
index 0000000..abc02b6
--- /dev/null
+++ b/modules/http/static/selectize.bootstrap3.css
@@ -0,0 +1,418 @@
+/**
+ * selectize.bootstrap3.css (v0.12.6) - Bootstrap 3 Theme
+ * Copyright (c) 2013–2015 Brian Reavis & contributors
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
+ * file except in compliance with the License. You may obtain a copy of the License at:
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
+ * ANY KIND, either express or implied. See the License for the specific language
+ * governing permissions and limitations under the License.
+ *
+ * @author Brian Reavis <brian@thirdroute.com>
+ */
+.selectize-control.plugin-drag_drop.multi > .selectize-input > div.ui-sortable-placeholder {
+ visibility: visible !important;
+ background: #f2f2f2 !important;
+ background: rgba(0, 0, 0, 0.06) !important;
+ border: 0 none !important;
+ -webkit-box-shadow: inset 0 0 12px 4px #fff;
+ box-shadow: inset 0 0 12px 4px #fff;
+}
+.selectize-control.plugin-drag_drop .ui-sortable-placeholder::after {
+ content: '!';
+ visibility: hidden;
+}
+.selectize-control.plugin-drag_drop .ui-sortable-helper {
+ -webkit-box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
+ box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
+}
+.selectize-dropdown-header {
+ position: relative;
+ padding: 3px 12px;
+ border-bottom: 1px solid #d0d0d0;
+ background: #f8f8f8;
+ -webkit-border-radius: 4px 4px 0 0;
+ -moz-border-radius: 4px 4px 0 0;
+ border-radius: 4px 4px 0 0;
+}
+.selectize-dropdown-header-close {
+ position: absolute;
+ right: 12px;
+ top: 50%;
+ color: #333333;
+ opacity: 0.4;
+ margin-top: -12px;
+ line-height: 20px;
+ font-size: 20px !important;
+}
+.selectize-dropdown-header-close:hover {
+ color: #000000;
+}
+.selectize-dropdown.plugin-optgroup_columns .optgroup {
+ border-right: 1px solid #f2f2f2;
+ border-top: 0 none;
+ float: left;
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+}
+.selectize-dropdown.plugin-optgroup_columns .optgroup:last-child {
+ border-right: 0 none;
+}
+.selectize-dropdown.plugin-optgroup_columns .optgroup:before {
+ display: none;
+}
+.selectize-dropdown.plugin-optgroup_columns .optgroup-header {
+ border-top: 0 none;
+}
+.selectize-control.plugin-remove_button [data-value] {
+ position: relative;
+ padding-right: 24px !important;
+}
+.selectize-control.plugin-remove_button [data-value] .remove {
+ z-index: 1;
+ /* fixes ie bug (see #392) */
+ position: absolute;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ width: 17px;
+ text-align: center;
+ font-weight: bold;
+ font-size: 12px;
+ color: inherit;
+ text-decoration: none;
+ vertical-align: middle;
+ display: inline-block;
+ padding: 1px 0 0 0;
+ border-left: 1px solid rgba(0, 0, 0, 0);
+ -webkit-border-radius: 0 2px 2px 0;
+ -moz-border-radius: 0 2px 2px 0;
+ border-radius: 0 2px 2px 0;
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+}
+.selectize-control.plugin-remove_button [data-value] .remove:hover {
+ background: rgba(0, 0, 0, 0.05);
+}
+.selectize-control.plugin-remove_button [data-value].active .remove {
+ border-left-color: rgba(0, 0, 0, 0);
+}
+.selectize-control.plugin-remove_button .disabled [data-value] .remove:hover {
+ background: none;
+}
+.selectize-control.plugin-remove_button .disabled [data-value] .remove {
+ border-left-color: rgba(77, 77, 77, 0);
+}
+.selectize-control.plugin-remove_button .remove-single {
+ position: absolute;
+ right: 0;
+ top: 0;
+ font-size: 23px;
+}
+.selectize-control {
+ position: relative;
+}
+.selectize-dropdown,
+.selectize-input,
+.selectize-input input {
+ color: #333333;
+ font-family: inherit;
+ font-size: inherit;
+ line-height: 20px;
+ -webkit-font-smoothing: inherit;
+}
+.selectize-input,
+.selectize-control.single .selectize-input.input-active {
+ background: #fff;
+ cursor: text;
+ display: inline-block;
+}
+.selectize-input {
+ border: 1px solid #ccc;
+ padding: 6px 12px;
+ display: inline-block;
+ width: 100%;
+ overflow: hidden;
+ position: relative;
+ z-index: 1;
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+ -webkit-box-shadow: none;
+ box-shadow: none;
+ -webkit-border-radius: 4px;
+ -moz-border-radius: 4px;
+ border-radius: 4px;
+}
+.selectize-control.multi .selectize-input.has-items {
+ padding: 5px 12px 2px;
+}
+.selectize-input.full {
+ background-color: #fff;
+}
+.selectize-input.disabled,
+.selectize-input.disabled * {
+ cursor: default !important;
+}
+.selectize-input.focus {
+ -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.15);
+ box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.15);
+}
+.selectize-input.dropdown-active {
+ -webkit-border-radius: 4px 4px 0 0;
+ -moz-border-radius: 4px 4px 0 0;
+ border-radius: 4px 4px 0 0;
+}
+.selectize-input > * {
+ vertical-align: baseline;
+ display: -moz-inline-stack;
+ display: inline-block;
+ zoom: 1;
+ *display: inline;
+}
+.selectize-control.multi .selectize-input > div {
+ cursor: pointer;
+ margin: 0 3px 3px 0;
+ padding: 1px 3px;
+ background: #efefef;
+ color: #333333;
+ border: 0 solid rgba(0, 0, 0, 0);
+}
+.selectize-control.multi .selectize-input > div.active {
+ background: #428bca;
+ color: #fff;
+ border: 0 solid rgba(0, 0, 0, 0);
+}
+.selectize-control.multi .selectize-input.disabled > div,
+.selectize-control.multi .selectize-input.disabled > div.active {
+ color: #808080;
+ background: #ffffff;
+ border: 0 solid rgba(77, 77, 77, 0);
+}
+.selectize-input > input {
+ display: inline-block !important;
+ padding: 0 !important;
+ min-height: 0 !important;
+ max-height: none !important;
+ max-width: 100% !important;
+ margin: 0 !important;
+ text-indent: 0 !important;
+ border: 0 none !important;
+ background: none !important;
+ line-height: inherit !important;
+ -webkit-user-select: auto !important;
+ -webkit-box-shadow: none !important;
+ box-shadow: none !important;
+}
+.selectize-input > input::-ms-clear {
+ display: none;
+}
+.selectize-input > input:focus {
+ outline: none !important;
+}
+.selectize-input::after {
+ content: ' ';
+ display: block;
+ clear: left;
+}
+.selectize-input.dropdown-active::before {
+ content: ' ';
+ display: block;
+ position: absolute;
+ background: #ffffff;
+ height: 1px;
+ bottom: 0;
+ left: 0;
+ right: 0;
+}
+.selectize-dropdown {
+ position: absolute;
+ z-index: 10;
+ border: 1px solid #d0d0d0;
+ background: #fff;
+ margin: -1px 0 0 0;
+ border-top: 0 none;
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+ -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
+ -webkit-border-radius: 0 0 4px 4px;
+ -moz-border-radius: 0 0 4px 4px;
+ border-radius: 0 0 4px 4px;
+}
+.selectize-dropdown [data-selectable] {
+ cursor: pointer;
+ overflow: hidden;
+}
+.selectize-dropdown [data-selectable] .highlight {
+ background: rgba(255, 237, 40, 0.4);
+ -webkit-border-radius: 1px;
+ -moz-border-radius: 1px;
+ border-radius: 1px;
+}
+.selectize-dropdown .option,
+.selectize-dropdown .optgroup-header {
+ padding: 3px 12px;
+}
+.selectize-dropdown .option,
+.selectize-dropdown [data-disabled],
+.selectize-dropdown [data-disabled] [data-selectable].option {
+ cursor: inherit;
+ opacity: 0.5;
+}
+.selectize-dropdown [data-selectable].option {
+ opacity: 1;
+}
+.selectize-dropdown .optgroup:first-child .optgroup-header {
+ border-top: 0 none;
+}
+.selectize-dropdown .optgroup-header {
+ color: #777777;
+ background: #fff;
+ cursor: default;
+}
+.selectize-dropdown .active {
+ background-color: #f5f5f5;
+ color: #262626;
+}
+.selectize-dropdown .active.create {
+ color: #262626;
+}
+.selectize-dropdown .create {
+ color: rgba(51, 51, 51, 0.5);
+}
+.selectize-dropdown-content {
+ overflow-y: auto;
+ overflow-x: hidden;
+ max-height: 200px;
+ -webkit-overflow-scrolling: touch;
+}
+.selectize-control.single .selectize-input,
+.selectize-control.single .selectize-input input {
+ cursor: pointer;
+}
+.selectize-control.single .selectize-input.input-active,
+.selectize-control.single .selectize-input.input-active input {
+ cursor: text;
+}
+.selectize-control.single .selectize-input:after {
+ content: ' ';
+ display: block;
+ position: absolute;
+ top: 50%;
+ right: 17px;
+ margin-top: -3px;
+ width: 0;
+ height: 0;
+ border-style: solid;
+ border-width: 5px 5px 0 5px;
+ border-color: #333333 transparent transparent transparent;
+}
+.selectize-control.single .selectize-input.dropdown-active:after {
+ margin-top: -4px;
+ border-width: 0 5px 5px 5px;
+ border-color: transparent transparent #333333 transparent;
+}
+.selectize-control.rtl.single .selectize-input:after {
+ left: 17px;
+ right: auto;
+}
+.selectize-control.rtl .selectize-input > input {
+ margin: 0 4px 0 -2px !important;
+}
+.selectize-control .selectize-input.disabled {
+ opacity: 0.5;
+ background-color: #fff;
+}
+.selectize-dropdown,
+.selectize-dropdown.form-control {
+ height: auto;
+ padding: 0;
+ margin: 2px 0 0 0;
+ z-index: 1000;
+ background: #fff;
+ border: 1px solid #ccc;
+ border: 1px solid rgba(0, 0, 0, 0.15);
+ -webkit-border-radius: 4px;
+ -moz-border-radius: 4px;
+ border-radius: 4px;
+ -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);
+ box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);
+}
+.selectize-dropdown .optgroup-header {
+ font-size: 12px;
+ line-height: 1.42857143;
+}
+.selectize-dropdown .optgroup:first-child:before {
+ display: none;
+}
+.selectize-dropdown .optgroup:before {
+ content: ' ';
+ display: block;
+ height: 1px;
+ margin: 9px 0;
+ overflow: hidden;
+ background-color: #e5e5e5;
+ margin-left: -12px;
+ margin-right: -12px;
+}
+.selectize-dropdown-content {
+ padding: 5px 0;
+}
+.selectize-dropdown-header {
+ padding: 6px 12px;
+}
+.selectize-input {
+ min-height: 34px;
+}
+.selectize-input.dropdown-active {
+ -webkit-border-radius: 4px;
+ -moz-border-radius: 4px;
+ border-radius: 4px;
+}
+.selectize-input.dropdown-active::before {
+ display: none;
+}
+.selectize-input.focus {
+ border-color: #66afe9;
+ outline: 0;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);
+ box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);
+}
+.has-error .selectize-input {
+ border-color: #a94442;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+}
+.has-error .selectize-input:focus {
+ border-color: #843534;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483;
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483;
+}
+.selectize-control.multi .selectize-input.has-items {
+ padding-left: 9px;
+ padding-right: 9px;
+}
+.selectize-control.multi .selectize-input > div {
+ -webkit-border-radius: 3px;
+ -moz-border-radius: 3px;
+ border-radius: 3px;
+}
+.form-control.selectize-control {
+ padding: 0;
+ height: auto;
+ border: none;
+ background: none;
+ -webkit-box-shadow: none;
+ box-shadow: none;
+ -webkit-border-radius: 0;
+ -moz-border-radius: 0;
+ border-radius: 0;
+}
diff --git a/modules/http/static/selectize.min.js b/modules/http/static/selectize.min.js
new file mode 100644
index 0000000..6161cd7
--- /dev/null
+++ b/modules/http/static/selectize.min.js
@@ -0,0 +1,4 @@
+/*! selectize.js - v0.12.6 | https://github.com/selectize/selectize.js | SPDX-License-Identifier: Apache-2.0 */
+
+!function(a,b){"function"==typeof define&&define.amd?define("sifter",b):"object"==typeof exports?module.exports=b():a.Sifter=b()}(this,function(){var a=function(a,b){this.items=a,this.settings=b||{diacritics:!0}};a.prototype.tokenize=function(a){if(!(a=e(String(a||"").toLowerCase()))||!a.length)return[];var b,c,d,g,i=[],j=a.split(/ +/);for(b=0,c=j.length;b<c;b++){if(d=f(j[b]),this.settings.diacritics)for(g in h)h.hasOwnProperty(g)&&(d=d.replace(new RegExp(g,"g"),h[g]));i.push({string:j[b],regex:new RegExp(d,"i")})}return i},a.prototype.iterator=function(a,b){var c;c=g(a)?Array.prototype.forEach||function(a){for(var b=0,c=this.length;b<c;b++)a(this[b],b,this)}:function(a){for(var b in this)this.hasOwnProperty(b)&&a(this[b],b,this)},c.apply(a,[b])},a.prototype.getScoreFunction=function(a,b){var c,e,f,g,h;c=this,a=c.prepareSearch(a,b),f=a.tokens,e=a.options.fields,g=f.length,h=a.options.nesting;var i=function(a,b){var c,d;return a?(a=String(a||""),-1===(d=a.search(b.regex))?0:(c=b.string.length/a.length,0===d&&(c+=.5),c)):0},j=function(){var a=e.length;return a?1===a?function(a,b){return i(d(b,e[0],h),a)}:function(b,c){for(var f=0,g=0;f<a;f++)g+=i(d(c,e[f],h),b);return g/a}:function(){return 0}}();return g?1===g?function(a){return j(f[0],a)}:"and"===a.options.conjunction?function(a){for(var b,c=0,d=0;c<g;c++){if((b=j(f[c],a))<=0)return 0;d+=b}return d/g}:function(a){for(var b=0,c=0;b<g;b++)c+=j(f[b],a);return c/g}:function(){return 0}},a.prototype.getSortFunction=function(a,c){var e,f,g,h,i,j,k,l,m,n,o;if(g=this,a=g.prepareSearch(a,c),o=!a.query&&c.sort_empty||c.sort,m=function(a,b){return"$score"===a?b.score:d(g.items[b.id],a,c.nesting)},i=[],o)for(e=0,f=o.length;e<f;e++)(a.query||"$score"!==o[e].field)&&i.push(o[e]);if(a.query){for(n=!0,e=0,f=i.length;e<f;e++)if("$score"===i[e].field){n=!1;break}n&&i.unshift({field:"$score",direction:"desc"})}else for(e=0,f=i.length;e<f;e++)if("$score"===i[e].field){i.splice(e,1);break}for(l=[],e=0,f=i.length;e<f;e++)l.push("desc"===i[e].direction?-1:1);return j=i.length,j?1===j?(h=i[0].field,k=l[0],function(a,c){return k*b(m(h,a),m(h,c))}):function(a,c){var d,e,f;for(d=0;d<j;d++)if(f=i[d].field,e=l[d]*b(m(f,a),m(f,c)))return e;return 0}:null},a.prototype.prepareSearch=function(a,b){if("object"==typeof a)return a;b=c({},b);var d=b.fields,e=b.sort,f=b.sort_empty;return d&&!g(d)&&(b.fields=[d]),e&&!g(e)&&(b.sort=[e]),f&&!g(f)&&(b.sort_empty=[f]),{options:b,query:String(a||"").toLowerCase(),tokens:this.tokenize(a),total:0,items:[]}},a.prototype.search=function(a,b){var c,d,e,f,g=this;return d=this.prepareSearch(a,b),b=d.options,a=d.query,f=b.score||g.getScoreFunction(d),a.length?g.iterator(g.items,function(a,e){c=f(a),(!1===b.filter||c>0)&&d.items.push({score:c,id:e})}):g.iterator(g.items,function(a,b){d.items.push({score:1,id:b})}),e=g.getSortFunction(d,b),e&&d.items.sort(e),d.total=d.items.length,"number"==typeof b.limit&&(d.items=d.items.slice(0,b.limit)),d};var b=function(a,b){return"number"==typeof a&&"number"==typeof b?a>b?1:a<b?-1:0:(a=i(String(a||"")),b=i(String(b||"")),a>b?1:b>a?-1:0)},c=function(a,b){var c,d,e,f;for(c=1,d=arguments.length;c<d;c++)if(f=arguments[c])for(e in f)f.hasOwnProperty(e)&&(a[e]=f[e]);return a},d=function(a,b,c){if(a&&b){if(!c)return a[b];for(var d=b.split(".");d.length&&(a=a[d.shift()]););return a}},e=function(a){return(a+"").replace(/^\s+|\s+$|/g,"")},f=function(a){return(a+"").replace(/([.?*+^$[\]\\(){}|-])/g,"\\$1")},g=Array.isArray||"undefined"!=typeof $&&$.isArray||function(a){return"[object Array]"===Object.prototype.toString.call(a)},h={a:"[aḀá¸Ä‚ăÂâÇǎȺⱥȦȧẠạÄäÀàÃáĀÄÃãÅåąĄÃąĄ]",b:"[bâ¢Î²Î’B฿ðŒá›’]",c:"[cĆćĈĉČÄÄŠÄ‹CÌ„c̄ÇçḈḉȻȼƇƈɕᴄCc]",d:"[dÄŽÄḊḋá¸á¸‘Ḍá¸á¸’ḓḎá¸ÄÄ‘D̦d̦ƉɖƊɗƋƌᵭá¶á¶‘ȡᴅDdð]",e:"[eÉéÈèÊêḘḙĚěĔĕẼẽḚḛẺẻĖėËëĒēȨȩĘęᶒɆɇȄȅẾếỀá»á»„ễỂểḜá¸á¸–ḗḔḕȆȇẸẹỆệⱸᴇEeɘÇÆÆε]",f:"[fƑƒḞḟ]",g:"[gɢ₲ǤǥĜÄĞğĢģƓɠĠġ]",h:"[hĤĥĦħḨḩẖẖḤḥḢḣɦʰǶƕ]",i:"[iÃíÌìĬĭÎîÇÇÃïḮḯĨĩĮįĪīỈỉȈȉȊȋỊịḬḭƗɨɨ̆ᵻᶖİiIıɪIi]",j:"[jȷĴĵɈɉÊɟʲ]",k:"[kƘƙê€êḰḱǨǩḲḳḴḵκϰ₭]",l:"[lÅłĽľĻļĹĺḶḷḸḹḼḽḺḻĿŀȽƚⱠⱡⱢɫɬᶅɭȴʟLl]",n:"[nŃńǸǹŇňÑñṄṅŅņṆṇṊṋṈṉN̈n̈ÆɲȠƞᵰᶇɳȵɴNnŊŋ]",o:"[oØøÖöÓóÒòÔôǑǒÅÅ‘ÅŽÅȮȯỌá»ÆŸÉµÆ Æ¡á»Žá»ÅŒÅÕõǪǫȌÈÕ•Ö…]",p:"[pṔṕṖṗⱣᵽƤƥᵱ]",q:"[qê–ê—Ê ÉŠÉ‹ê˜ê™q̃]",r:"[rŔŕɌÉŘřŖŗṘṙÈȑȒȓṚṛⱤɽ]",s:"[sŚśṠṡṢṣꞨꞩŜÅŠšŞşȘșS̈s̈]",t:"[tŤťṪṫŢţṬṭƮʈȚțṰṱṮṯƬƭ]",u:"[uŬŭɄʉỤụÜüÚúÙùÛûǓǔŰűŬŭƯưỦủŪūŨũŲųȔȕ∪]",v:"[vṼṽṾṿƲʋêžêŸâ±±Ê‹]",w:"[wẂẃẀáºÅ´Åµáº„ẅẆẇẈẉ]",x:"[xẌáºáºŠáº‹Ï‡]",y:"[yÃýỲỳŶŷŸÿỸỹẎáºá»´á»µÉŽÉƳƴ]",z:"[zŹźáºáº‘ŽžŻżẒẓẔẕƵƶ]"},i=function(){var a,b,c,d,e="",f={};for(c in h)if(h.hasOwnProperty(c))for(d=h[c].substring(2,h[c].length-1),e+=d,a=0,b=d.length;a<b;a++)f[d.charAt(a)]=c;var g=new RegExp("["+e+"]","g");return function(a){return a.replace(g,function(a){return f[a]}).toLowerCase()}}();return a}),function(a,b){"function"==typeof define&&define.amd?define("microplugin",b):"object"==typeof exports?module.exports=b():a.MicroPlugin=b()}(this,function(){var a={};a.mixin=function(a){a.plugins={},a.prototype.initializePlugins=function(a){var c,d,e,f=this,g=[];if(f.plugins={names:[],settings:{},requested:{},loaded:{}},b.isArray(a))for(c=0,d=a.length;c<d;c++)"string"==typeof a[c]?g.push(a[c]):(f.plugins.settings[a[c].name]=a[c].options,g.push(a[c].name));else if(a)for(e in a)a.hasOwnProperty(e)&&(f.plugins.settings[e]=a[e],g.push(e));for(;g.length;)f.require(g.shift())},a.prototype.loadPlugin=function(b){var c=this,d=c.plugins,e=a.plugins[b];if(!a.plugins.hasOwnProperty(b))throw new Error('Unable to find "'+b+'" plugin');d.requested[b]=!0,d.loaded[b]=e.fn.apply(c,[c.plugins.settings[b]||{}]),d.names.push(b)},a.prototype.require=function(a){var b=this,c=b.plugins;if(!b.plugins.loaded.hasOwnProperty(a)){if(c.requested[a])throw new Error('Plugin has circular dependency ("'+a+'")');b.loadPlugin(a)}return c.loaded[a]},a.define=function(b,c){a.plugins[b]={name:b,fn:c}}};var b={isArray:Array.isArray||function(a){return"[object Array]"===Object.prototype.toString.call(a)}};return a}),function(a,b){"function"==typeof define&&define.amd?define("selectize",["jquery","sifter","microplugin"],b):"object"==typeof exports?module.exports=b(require("jquery"),require("sifter"),require("microplugin")):a.Selectize=b(a.jQuery,a.Sifter,a.MicroPlugin)}(this,function(a,b,c){"use strict";var d=function(a,b){if("string"!=typeof b||b.length){var c="string"==typeof b?new RegExp(b,"i"):b,d=function(a){var b=0;if(3===a.nodeType){var e=a.data.search(c);if(e>=0&&a.data.length>0){var f=a.data.match(c),g=document.createElement("span");g.className="highlight";var h=a.splitText(e),i=(h.splitText(f[0].length),h.cloneNode(!0));g.appendChild(i),h.parentNode.replaceChild(g,h),b=1}}else if(1===a.nodeType&&a.childNodes&&!/(script|style)/i.test(a.tagName)&&("highlight"!==a.className||"SPAN"!==a.tagName))for(var j=0;j<a.childNodes.length;++j)j+=d(a.childNodes[j]);return b};return a.each(function(){d(this)})}};a.fn.removeHighlight=function(){return this.find("span.highlight").each(function(){this.parentNode.firstChild.nodeName;var a=this.parentNode;a.replaceChild(this.firstChild,this),a.normalize()}).end()};var e=function(){};e.prototype={on:function(a,b){this._events=this._events||{},this._events[a]=this._events[a]||[],this._events[a].push(b)},off:function(a,b){var c=arguments.length;return 0===c?delete this._events:1===c?delete this._events[a]:(this._events=this._events||{},void(a in this._events!=!1&&this._events[a].splice(this._events[a].indexOf(b),1)))},trigger:function(a){if(this._events=this._events||{},a in this._events!=!1)for(var b=0;b<this._events[a].length;b++)this._events[a][b].apply(this,Array.prototype.slice.call(arguments,1))}},e.mixin=function(a){for(var b=["on","off","trigger"],c=0;c<b.length;c++)a.prototype[b[c]]=e.prototype[b[c]]};var f=/Mac/.test(navigator.userAgent),g=f?91:17,h=f?18:17,i=!/android/i.test(window.navigator.userAgent)&&!!document.createElement("input").validity,j=function(a){return void 0!==a},k=function(a){return void 0===a||null===a?null:"boolean"==typeof a?a?"1":"0":a+""},l=function(a){return(a+"").replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")},m={};m.before=function(a,b,c){var d=a[b];a[b]=function(){return c.apply(a,arguments),d.apply(a,arguments)}},m.after=function(a,b,c){var d=a[b];a[b]=function(){var b=d.apply(a,arguments);return c.apply(a,arguments),b}};var n=function(a){var b=!1;return function(){b||(b=!0,a.apply(this,arguments))}},o=function(a,b){var c;return function(){var d=this,e=arguments;window.clearTimeout(c),c=window.setTimeout(function(){a.apply(d,e)},b)}},p=function(a,b,c){var d,e=a.trigger,f={};a.trigger=function(){var c=arguments[0];if(-1===b.indexOf(c))return e.apply(a,arguments);f[c]=arguments},c.apply(a,[]),a.trigger=e;for(d in f)f.hasOwnProperty(d)&&e.apply(a,f[d])},q=function(a,b,c,d){a.on(b,c,function(b){for(var c=b.target;c&&c.parentNode!==a[0];)c=c.parentNode;return b.currentTarget=c,d.apply(this,[b])})},r=function(a){var b={};if("selectionStart"in a)b.start=a.selectionStart,b.length=a.selectionEnd-b.start;else if(document.selection){a.focus();var c=document.selection.createRange(),d=document.selection.createRange().text.length;c.moveStart("character",-a.value.length),b.start=c.text.length-d,b.length=d}return b},s=function(a,b,c){var d,e,f={};if(c)for(d=0,e=c.length;d<e;d++)f[c[d]]=a.css(c[d]);else f=a.css();b.css(f)},t=function(b,c){return b?(w.$testInput||(w.$testInput=a("<span />").css({position:"absolute",top:-99999,left:-99999,width:"auto",padding:0,whiteSpace:"pre"}).appendTo("body")),w.$testInput.text(b),s(c,w.$testInput,["letterSpacing","fontSize","fontFamily","fontWeight","textTransform"]),w.$testInput.width()):0},u=function(a){var b=null,c=function(c,d){var e,f,g,h,i,j,k,l;c=c||window.event||{},d=d||{},c.metaKey||c.altKey||(d.force||!1!==a.data("grow"))&&(e=a.val(),c.type&&"keydown"===c.type.toLowerCase()&&(f=c.keyCode,g=f>=48&&f<=57||f>=65&&f<=90||f>=96&&f<=111||f>=186&&f<=222||32===f,46===f||8===f?(l=r(a[0]),l.length?e=e.substring(0,l.start)+e.substring(l.start+l.length):8===f&&l.start?e=e.substring(0,l.start-1)+e.substring(l.start+1):46===f&&void 0!==l.start&&(e=e.substring(0,l.start)+e.substring(l.start+1))):g&&(j=c.shiftKey,k=String.fromCharCode(c.keyCode),k=j?k.toUpperCase():k.toLowerCase(),e+=k)),h=a.attr("placeholder"),!e&&h&&(e=h),(i=t(e,a)+4)!==b&&(b=i,a.width(i),a.triggerHandler("resize")))};a.on("keydown keyup update blur",c),c()},v=function(a){var b=document.createElement("div");return b.appendChild(a.cloneNode(!0)),b.innerHTML},w=function(c,d){var e,f,g,h,i=this;h=c[0],h.selectize=i;var j=window.getComputedStyle&&window.getComputedStyle(h,null);if(g=j?j.getPropertyValue("direction"):h.currentStyle&&h.currentStyle.direction,g=g||c.parents("[dir]:first").attr("dir")||"",a.extend(i,{order:0,settings:d,$input:c,tabIndex:c.attr("tabindex")||"",tagType:"select"===h.tagName.toLowerCase()?1:2,rtl:/rtl/i.test(g),eventNS:".selectize"+ ++w.count,highlightedValue:null,isBlurring:!1,isOpen:!1,isDisabled:!1,isRequired:c.is("[required]"),isInvalid:!1,isLocked:!1,isFocused:!1,isInputHidden:!1,isSetup:!1,isShiftDown:!1,isCmdDown:!1,isCtrlDown:!1,ignoreFocus:!1,ignoreBlur:!1,ignoreHover:!1,hasOptions:!1,currentResults:null,lastValue:"",caretPos:0,loading:0,loadedSearches:{},$activeOption:null,$activeItems:[],optgroups:{},options:{},userOptions:{},items:[],renderCache:{},onSearchChange:null===d.loadThrottle?i.onSearchChange:o(i.onSearchChange,d.loadThrottle)}),i.sifter=new b(this.options,{diacritics:d.diacritics}),i.settings.options){for(e=0,f=i.settings.options.length;e<f;e++)i.registerOption(i.settings.options[e]);delete i.settings.options}if(i.settings.optgroups){for(e=0,f=i.settings.optgroups.length;e<f;e++)i.registerOptionGroup(i.settings.optgroups[e]);delete i.settings.optgroups}i.settings.mode=i.settings.mode||(1===i.settings.maxItems?"single":"multi"),"boolean"!=typeof i.settings.hideSelected&&(i.settings.hideSelected="multi"===i.settings.mode),i.initializePlugins(i.settings.plugins),i.setupCallbacks(),i.setupTemplates(),i.setup()};return e.mixin(w),void 0!==c?c.mixin(w):function(a,b){b||(b={});console.error("Selectize: "+a),b.explanation&&(console.group&&console.group(),console.error(b.explanation),console.group&&console.groupEnd())}("Dependency MicroPlugin is missing",{explanation:'Make sure you either: (1) are using the "standalone" version of Selectize, or (2) require MicroPlugin before you load Selectize.'}),a.extend(w.prototype,{setup:function(){var b,c,d,e,j,k,l,m,n,o,p=this,r=p.settings,s=p.eventNS,t=a(window),v=a(document),w=p.$input;if(l=p.settings.mode,m=w.attr("class")||"",b=a("<div>").addClass(r.wrapperClass).addClass(m).addClass(l),c=a("<div>").addClass(r.inputClass).addClass("items").appendTo(b),d=a('<input type="text" autocomplete="off" />').appendTo(c).attr("tabindex",w.is(":disabled")?"-1":p.tabIndex),k=a(r.dropdownParent||b),e=a("<div>").addClass(r.dropdownClass).addClass(l).hide().appendTo(k),j=a("<div>").addClass(r.dropdownContentClass).appendTo(e),(o=w.attr("id"))&&(d.attr("id",o+"-selectized"),a("label[for='"+o+"']").attr("for",o+"-selectized")),p.settings.copyClassesToDropdown&&e.addClass(m),b.css({width:w[0].style.width}),p.plugins.names.length&&(n="plugin-"+p.plugins.names.join(" plugin-"),b.addClass(n),e.addClass(n)),(null===r.maxItems||r.maxItems>1)&&1===p.tagType&&w.attr("multiple","multiple"),p.settings.placeholder&&d.attr("placeholder",r.placeholder),!p.settings.splitOn&&p.settings.delimiter){var x=p.settings.delimiter.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&");p.settings.splitOn=new RegExp("\\s*"+x+"+\\s*")}w.attr("autocorrect")&&d.attr("autocorrect",w.attr("autocorrect")),w.attr("autocapitalize")&&d.attr("autocapitalize",w.attr("autocapitalize")),d[0].type=w[0].type,p.$wrapper=b,p.$control=c,p.$control_input=d,p.$dropdown=e,p.$dropdown_content=j,e.on("mouseenter mousedown click","[data-disabled]>[data-selectable]",function(a){a.stopImmediatePropagation()}),e.on("mouseenter","[data-selectable]",function(){return p.onOptionHover.apply(p,arguments)}),e.on("mousedown click","[data-selectable]",function(){return p.onOptionSelect.apply(p,arguments)}),q(c,"mousedown","*:not(input)",function(){return p.onItemSelect.apply(p,arguments)}),u(d),c.on({mousedown:function(){return p.onMouseDown.apply(p,arguments)},click:function(){return p.onClick.apply(p,arguments)}}),d.on({mousedown:function(a){a.stopPropagation()},keydown:function(){return p.onKeyDown.apply(p,arguments)},keyup:function(){return p.onKeyUp.apply(p,arguments)},keypress:function(){return p.onKeyPress.apply(p,arguments)},resize:function(){p.positionDropdown.apply(p,[])},blur:function(){return p.onBlur.apply(p,arguments)},focus:function(){return p.ignoreBlur=!1,p.onFocus.apply(p,arguments)},paste:function(){return p.onPaste.apply(p,arguments)}}),v.on("keydown"+s,function(a){p.isCmdDown=a[f?"metaKey":"ctrlKey"],p.isCtrlDown=a[f?"altKey":"ctrlKey"],p.isShiftDown=a.shiftKey}),v.on("keyup"+s,function(a){a.keyCode===h&&(p.isCtrlDown=!1),16===a.keyCode&&(p.isShiftDown=!1),a.keyCode===g&&(p.isCmdDown=!1)}),v.on("mousedown"+s,function(a){if(p.isFocused){if(a.target===p.$dropdown[0]||a.target.parentNode===p.$dropdown[0])return!1;p.$control.has(a.target).length||a.target===p.$control[0]||p.blur(a.target)}}),t.on(["scroll"+s,"resize"+s].join(" "),function(){p.isOpen&&p.positionDropdown.apply(p,arguments)}),t.on("mousemove"+s,function(){p.ignoreHover=!1}),this.revertSettings={$children:w.children().detach(),tabindex:w.attr("tabindex")},w.attr("tabindex",-1).hide().after(p.$wrapper),a.isArray(r.items)&&(p.setValue(r.items),delete r.items),i&&w.on("invalid"+s,function(a){a.preventDefault(),p.isInvalid=!0,p.refreshState()}),p.updateOriginalInput(),p.refreshItems(),p.refreshState(),p.updatePlaceholder(),p.isSetup=!0,w.is(":disabled")&&p.disable(),p.on("change",this.onChange),w.data("selectize",p),w.addClass("selectized"),p.trigger("initialize"),!0===r.preload&&p.onSearchChange("")},setupTemplates:function(){var b=this,c=b.settings.labelField,d=b.settings.optgroupLabelField,e={optgroup:function(a){return'<div class="optgroup">'+a.html+"</div>"},optgroup_header:function(a,b){return'<div class="optgroup-header">'+b(a[d])+"</div>"},option:function(a,b){return'<div class="option">'+b(a[c])+"</div>"},item:function(a,b){return'<div class="item">'+b(a[c])+"</div>"},option_create:function(a,b){return'<div class="create">Add <strong>'+b(a.input)+"</strong>&hellip;</div>"}};b.settings.render=a.extend({},e,b.settings.render)},setupCallbacks:function(){var a,b,c={initialize:"onInitialize",change:"onChange",item_add:"onItemAdd",item_remove:"onItemRemove",clear:"onClear",option_add:"onOptionAdd",option_remove:"onOptionRemove",option_clear:"onOptionClear",optgroup_add:"onOptionGroupAdd",optgroup_remove:"onOptionGroupRemove",optgroup_clear:"onOptionGroupClear",dropdown_open:"onDropdownOpen",dropdown_close:"onDropdownClose",type:"onType",load:"onLoad",focus:"onFocus",blur:"onBlur"};for(a in c)c.hasOwnProperty(a)&&(b=this.settings[c[a]])&&this.on(a,b)},onClick:function(a){var b=this;b.isFocused&&b.isOpen||(b.focus(),a.preventDefault())},onMouseDown:function(b){var c=this,d=b.isDefaultPrevented();a(b.target);if(c.isFocused){if(b.target!==c.$control_input[0])return"single"===c.settings.mode?c.isOpen?c.close():c.open():d||c.setActiveItem(null),!1}else d||window.setTimeout(function(){c.focus()},0)},onChange:function(){this.$input.trigger("change")},onPaste:function(b){var c=this;if(c.isFull()||c.isInputHidden||c.isLocked)return void b.preventDefault();c.settings.splitOn&&setTimeout(function(){var b=c.$control_input.val();if(b.match(c.settings.splitOn))for(var d=a.trim(b).split(c.settings.splitOn),e=0,f=d.length;e<f;e++)c.createItem(d[e])},0)},onKeyPress:function(a){if(this.isLocked)return a&&a.preventDefault();var b=String.fromCharCode(a.keyCode||a.which);return this.settings.create&&"multi"===this.settings.mode&&b===this.settings.delimiter?(this.createItem(),a.preventDefault(),!1):void 0},onKeyDown:function(a){var b=(a.target,this.$control_input[0],this);if(b.isLocked)return void(9!==a.keyCode&&a.preventDefault());switch(a.keyCode){case 65:if(b.isCmdDown)return void b.selectAll();break;case 27:return void(b.isOpen&&(a.preventDefault(),a.stopPropagation(),b.close()));case 78:if(!a.ctrlKey||a.altKey)break;case 40:if(!b.isOpen&&b.hasOptions)b.open();else if(b.$activeOption){b.ignoreHover=!0;var c=b.getAdjacentOption(b.$activeOption,1);c.length&&b.setActiveOption(c,!0,!0)}return void a.preventDefault();case 80:if(!a.ctrlKey||a.altKey)break;case 38:if(b.$activeOption){b.ignoreHover=!0;var d=b.getAdjacentOption(b.$activeOption,-1);d.length&&b.setActiveOption(d,!0,!0)}return void a.preventDefault();case 13:return void(b.isOpen&&b.$activeOption&&(b.onOptionSelect({currentTarget:b.$activeOption}),a.preventDefault()));case 37:return void b.advanceSelection(-1,a);case 39:return void b.advanceSelection(1,a);case 9:return b.settings.selectOnTab&&b.isOpen&&b.$activeOption&&(b.onOptionSelect({currentTarget:b.$activeOption}),b.isFull()||a.preventDefault()),void(b.settings.create&&b.createItem()&&a.preventDefault());case 8:case 46:return void b.deleteSelection(a)}return!b.isFull()&&!b.isInputHidden||(f?a.metaKey:a.ctrlKey)?void 0:void a.preventDefault()},onKeyUp:function(a){var b=this;if(b.isLocked)return a&&a.preventDefault();var c=b.$control_input.val()||"";b.lastValue!==c&&(b.lastValue=c,b.onSearchChange(c),b.refreshOptions(),b.trigger("type",c))},onSearchChange:function(a){var b=this,c=b.settings.load;c&&(b.loadedSearches.hasOwnProperty(a)||(b.loadedSearches[a]=!0,b.load(function(d){c.apply(b,[a,d])})))},onFocus:function(a){var b=this,c=b.isFocused;if(b.isDisabled)return b.blur(),a&&a.preventDefault(),!1;b.ignoreFocus||(b.isFocused=!0,"focus"===b.settings.preload&&b.onSearchChange(""),c||b.trigger("focus"),b.$activeItems.length||(b.showInput(),b.setActiveItem(null),b.refreshOptions(!!b.settings.openOnFocus)),b.refreshState())},onBlur:function(a,b){var c=this;if(c.isFocused&&(c.isFocused=!1,!c.ignoreFocus)){if(!c.ignoreBlur&&document.activeElement===c.$dropdown_content[0])return c.ignoreBlur=!0,void c.onFocus(a);var d=function(){c.close(),c.setTextboxValue(""),c.setActiveItem(null),c.setActiveOption(null),c.setCaret(c.items.length),c.refreshState(),b&&b.focus&&b.focus(),c.isBlurring=!1,c.ignoreFocus=!1,c.trigger("blur")};c.isBlurring=!0,c.ignoreFocus=!0,c.settings.create&&c.settings.createOnBlur?c.createItem(null,!1,d):d()}},onOptionHover:function(a){this.ignoreHover||this.setActiveOption(a.currentTarget,!1)},onOptionSelect:function(b){var c,d,e=this;b.preventDefault&&(b.preventDefault(),b.stopPropagation()),d=a(b.currentTarget),d.hasClass("create")?e.createItem(null,function(){e.settings.closeAfterSelect&&e.close()}):void 0!==(c=d.attr("data-value"))&&(e.lastQuery=null,e.setTextboxValue(""),e.addItem(c),e.settings.closeAfterSelect?e.close():!e.settings.hideSelected&&b.type&&/mouse/.test(b.type)&&e.setActiveOption(e.getOption(c)))},onItemSelect:function(a){var b=this;b.isLocked||"multi"===b.settings.mode&&(a.preventDefault(),b.setActiveItem(a.currentTarget,a))},load:function(a){var b=this,c=b.$wrapper.addClass(b.settings.loadingClass);b.loading++,a.apply(b,[function(a){b.loading=Math.max(b.loading-1,0),a&&a.length&&(b.addOption(a),b.refreshOptions(b.isFocused&&!b.isInputHidden)),b.loading||c.removeClass(b.settings.loadingClass),b.trigger("load",a)}])},setTextboxValue:function(a){var b=this.$control_input;b.val()!==a&&(b.val(a).triggerHandler("update"),this.lastValue=a)},getValue:function(){return 1===this.tagType&&this.$input.attr("multiple")?this.items:this.items.join(this.settings.delimiter)},setValue:function(a,b){p(this,b?[]:["change"],function(){this.clear(b),this.addItems(a,b)})},setActiveItem:function(b,c){var d,e,f,g,h,i,j,k,l=this;if("single"!==l.settings.mode){if(b=a(b),!b.length)return a(l.$activeItems).removeClass("active"),l.$activeItems=[],void(l.isFocused&&l.showInput());if("mousedown"===(d=c&&c.type.toLowerCase())&&l.isShiftDown&&l.$activeItems.length){for(k=l.$control.children(".active:last"),g=Array.prototype.indexOf.apply(l.$control[0].childNodes,[k[0]]),h=Array.prototype.indexOf.apply(l.$control[0].childNodes,[b[0]]),g>h&&(j=g,g=h,h=j),e=g;e<=h;e++)i=l.$control[0].childNodes[e],-1===l.$activeItems.indexOf(i)&&(a(i).addClass("active"),l.$activeItems.push(i));c.preventDefault()}else"mousedown"===d&&l.isCtrlDown||"keydown"===d&&this.isShiftDown?b.hasClass("active")?(f=l.$activeItems.indexOf(b[0]),l.$activeItems.splice(f,1),b.removeClass("active")):l.$activeItems.push(b.addClass("active")[0]):(a(l.$activeItems).removeClass("active"),l.$activeItems=[b.addClass("active")[0]]);l.hideInput(),this.isFocused||l.focus()}},setActiveOption:function(b,c,d){var e,f,g,h,i,k=this;k.$activeOption&&k.$activeOption.removeClass("active"),k.$activeOption=null,b=a(b),b.length&&(k.$activeOption=b.addClass("active"),!c&&j(c)||(e=k.$dropdown_content.height(),f=k.$activeOption.outerHeight(!0),c=k.$dropdown_content.scrollTop()||0,g=k.$activeOption.offset().top-k.$dropdown_content.offset().top+c,h=g,i=g-e+f,g+f>e+c?k.$dropdown_content.stop().animate({scrollTop:i},d?k.settings.scrollDuration:0):g<c&&k.$dropdown_content.stop().animate({scrollTop:h},d?k.settings.scrollDuration:0)))},selectAll:function(){var a=this;"single"!==a.settings.mode&&(a.$activeItems=Array.prototype.slice.apply(a.$control.children(":not(input)").addClass("active")),a.$activeItems.length&&(a.hideInput(),a.close()),a.focus())},hideInput:function(){var a=this;a.setTextboxValue(""),a.$control_input.css({opacity:0,position:"absolute",left:a.rtl?1e4:-1e4}),a.isInputHidden=!0},showInput:function(){this.$control_input.css({opacity:1,position:"relative",left:0}),this.isInputHidden=!1},focus:function(){var a=this;a.isDisabled||(a.ignoreFocus=!0,a.$control_input[0].focus(),window.setTimeout(function(){a.ignoreFocus=!1,a.onFocus()},0))},blur:function(a){this.$control_input[0].blur(),this.onBlur(null,a)},getScoreFunction:function(a){return this.sifter.getScoreFunction(a,this.getSearchOptions())},getSearchOptions:function(){var a=this.settings,b=a.sortField;return"string"==typeof b&&(b=[{field:b}]),{fields:a.searchField,conjunction:a.searchConjunction,sort:b,nesting:a.nesting}},search:function(b){var c,d,e,f=this,g=f.settings,h=this.getSearchOptions();if(g.score&&"function"!=typeof(e=f.settings.score.apply(this,[b])))throw new Error('Selectize "score" setting must be a function that returns a function');if(b!==f.lastQuery?(f.lastQuery=b,d=f.sifter.search(b,a.extend(h,{score:e})),f.currentResults=d):d=a.extend(!0,{},f.currentResults),g.hideSelected)for(c=d.items.length-1;c>=0;c--)-1!==f.items.indexOf(k(d.items[c].id))&&d.items.splice(c,1);return d},refreshOptions:function(b){var c,e,f,g,h,i,j,l,m,n,o,p,q,r,s,t;void 0===b&&(b=!0);var u=this,w=a.trim(u.$control_input.val()),x=u.search(w),y=u.$dropdown_content,z=u.$activeOption&&k(u.$activeOption.attr("data-value"));for(g=x.items.length,"number"==typeof u.settings.maxOptions&&(g=Math.min(g,u.settings.maxOptions)),h={},i=[],c=0;c<g;c++)for(j=u.options[x.items[c].id],l=u.render("option",j),m=j[u.settings.optgroupField]||"",n=a.isArray(m)?m:[m],e=0,f=n&&n.length;e<f;e++)m=n[e],u.optgroups.hasOwnProperty(m)||(m=""),h.hasOwnProperty(m)||(h[m]=document.createDocumentFragment(),i.push(m)),h[m].appendChild(l);for(this.settings.lockOptgroupOrder&&i.sort(function(a,b){return(u.optgroups[a].$order||0)-(u.optgroups[b].$order||0)}),o=document.createDocumentFragment(),c=0,g=i.length;c<g;c++)m=i[c],u.optgroups.hasOwnProperty(m)&&h[m].childNodes.length?(p=document.createDocumentFragment(),p.appendChild(u.render("optgroup_header",u.optgroups[m])),p.appendChild(h[m]),o.appendChild(u.render("optgroup",a.extend({},u.optgroups[m],{html:v(p),dom:p})))):o.appendChild(h[m]);if(y.html(o),u.settings.highlight&&(y.removeHighlight(),x.query.length&&x.tokens.length))for(c=0,g=x.tokens.length;c<g;c++)d(y,x.tokens[c].regex);if(!u.settings.hideSelected)for(c=0,g=u.items.length;c<g;c++)u.getOption(u.items[c]).addClass("selected");q=u.canCreate(w),q&&(y.prepend(u.render("option_create",{input:w})),t=a(y[0].childNodes[0])),u.hasOptions=x.items.length>0||q,u.hasOptions?(x.items.length>0?(s=z&&u.getOption(z),s&&s.length?r=s:"single"===u.settings.mode&&u.items.length&&(r=u.getOption(u.items[0])),r&&r.length||(r=t&&!u.settings.addPrecedence?u.getAdjacentOption(t,1):y.find("[data-selectable]:first"))):r=t,u.setActiveOption(r),b&&!u.isOpen&&u.open()):(u.setActiveOption(null),b&&u.isOpen&&u.close())},addOption:function(b){var c,d,e,f=this;if(a.isArray(b))for(c=0,d=b.length;c<d;c++)f.addOption(b[c]);else(e=f.registerOption(b))&&(f.userOptions[e]=!0,f.lastQuery=null,f.trigger("option_add",e,b))},registerOption:function(a){var b=k(a[this.settings.valueField]);return void 0!==b&&null!==b&&!this.options.hasOwnProperty(b)&&(a.$order=a.$order||++this.order,this.options[b]=a,b)},registerOptionGroup:function(a){var b=k(a[this.settings.optgroupValueField]);return!!b&&(a.$order=a.$order||++this.order,this.optgroups[b]=a,b)},addOptionGroup:function(a,b){b[this.settings.optgroupValueField]=a,(a=this.registerOptionGroup(b))&&this.trigger("optgroup_add",a,b)},removeOptionGroup:function(a){this.optgroups.hasOwnProperty(a)&&(delete this.optgroups[a],this.renderCache={},this.trigger("optgroup_remove",a))},clearOptionGroups:function(){this.optgroups={},this.renderCache={},this.trigger("optgroup_clear")},updateOption:function(b,c){var d,e,f,g,h,i,j,l=this;if(b=k(b),f=k(c[l.settings.valueField]),null!==b&&l.options.hasOwnProperty(b)){if("string"!=typeof f)throw new Error("Value must be set in option data");j=l.options[b].$order,f!==b&&(delete l.options[b],-1!==(g=l.items.indexOf(b))&&l.items.splice(g,1,f)),c.$order=c.$order||j,l.options[f]=c,h=l.renderCache.item,i=l.renderCache.option,h&&(delete h[b],delete h[f]),i&&(delete i[b],delete i[f]),-1!==l.items.indexOf(f)&&(d=l.getItem(b),e=a(l.render("item",c)),d.hasClass("active")&&e.addClass("active"),d.replaceWith(e)),l.lastQuery=null,l.isOpen&&l.refreshOptions(!1)}},removeOption:function(a,b){var c=this;a=k(a);var d=c.renderCache.item,e=c.renderCache.option;d&&delete d[a],e&&delete e[a],delete c.userOptions[a],delete c.options[a],c.lastQuery=null,c.trigger("option_remove",a),c.removeItem(a,b)},clearOptions:function(){var b=this;b.loadedSearches={},b.userOptions={},b.renderCache={};var c=b.options;a.each(b.options,function(a,d){-1==b.items.indexOf(a)&&delete c[a]}),b.options=b.sifter.items=c,b.lastQuery=null,b.trigger("option_clear")},getOption:function(a){return this.getElementWithValue(a,this.$dropdown_content.find("[data-selectable]"))},getAdjacentOption:function(b,c){var d=this.$dropdown.find("[data-selectable]"),e=d.index(b)+c;return e>=0&&e<d.length?d.eq(e):a()},getElementWithValue:function(b,c){if(void 0!==(b=k(b))&&null!==b)for(var d=0,e=c.length;d<e;d++)if(c[d].getAttribute("data-value")===b)return a(c[d]);return a()},getItem:function(a){return this.getElementWithValue(a,this.$control.children())},addItems:function(b,c){this.buffer=document.createDocumentFragment();for(var d=this.$control[0].childNodes,e=0;e<d.length;e++)this.buffer.appendChild(d[e]);for(var f=a.isArray(b)?b:[b],e=0,g=f.length;e<g;e++)this.isPending=e<g-1,this.addItem(f[e],c);var h=this.$control[0];h.insertBefore(this.buffer,h.firstChild),this.buffer=null},addItem:function(b,c){p(this,c?[]:["change"],function(){var d,e,f,g,h,i=this,j=i.settings.mode;if(b=k(b),-1!==i.items.indexOf(b))return void("single"===j&&i.close());i.options.hasOwnProperty(b)&&("single"===j&&i.clear(c),"multi"===j&&i.isFull()||(d=a(i.render("item",i.options[b])),h=i.isFull(),i.items.splice(i.caretPos,0,b),i.insertAtCaret(d),(!i.isPending||!h&&i.isFull())&&i.refreshState(),i.isSetup&&(f=i.$dropdown_content.find("[data-selectable]"),i.isPending||(e=i.getOption(b),g=i.getAdjacentOption(e,1).attr("data-value"),i.refreshOptions(i.isFocused&&"single"!==j),g&&i.setActiveOption(i.getOption(g))),!f.length||i.isFull()?i.close():i.isPending||i.positionDropdown(),i.updatePlaceholder(),i.trigger("item_add",b,d),i.isPending||i.updateOriginalInput({silent:c}))))})},removeItem:function(b,c){var d,e,f,g=this;d=b instanceof a?b:g.getItem(b),b=k(d.attr("data-value")),-1!==(e=g.items.indexOf(b))&&(d.remove(),d.hasClass("active")&&(f=g.$activeItems.indexOf(d[0]),g.$activeItems.splice(f,1)),g.items.splice(e,1),g.lastQuery=null,!g.settings.persist&&g.userOptions.hasOwnProperty(b)&&g.removeOption(b,c),e<g.caretPos&&g.setCaret(g.caretPos-1),g.refreshState(),g.updatePlaceholder(),g.updateOriginalInput({silent:c}),g.positionDropdown(),g.trigger("item_remove",b,d))},createItem:function(b,c){var d=this,e=d.caretPos;b=b||a.trim(d.$control_input.val()||"");var f=arguments[arguments.length-1];if("function"!=typeof f&&(f=function(){}),"boolean"!=typeof c&&(c=!0),!d.canCreate(b))return f(),!1;d.lock();var g="function"==typeof d.settings.create?this.settings.create:function(a){var b={};return b[d.settings.labelField]=a,b[d.settings.valueField]=a,b},h=n(function(a){if(d.unlock(),!a||"object"!=typeof a)return f();var b=k(a[d.settings.valueField]);if("string"!=typeof b)return f();d.setTextboxValue(""),d.addOption(a),d.setCaret(e),d.addItem(b),d.refreshOptions(c&&"single"!==d.settings.mode),f(a)}),i=g.apply(this,[b,h]);return void 0!==i&&h(i),!0},refreshItems:function(){this.lastQuery=null,this.isSetup&&this.addItem(this.items),this.refreshState(),this.updateOriginalInput()},refreshState:function(){this.refreshValidityState(),this.refreshClasses()},refreshValidityState:function(){if(!this.isRequired)return!1;var a=!this.items.length;this.isInvalid=a,this.$control_input.prop("required",a),this.$input.prop("required",!a)},refreshClasses:function(){var b=this,c=b.isFull(),d=b.isLocked;b.$wrapper.toggleClass("rtl",b.rtl),b.$control.toggleClass("focus",b.isFocused).toggleClass("disabled",b.isDisabled).toggleClass("required",b.isRequired).toggleClass("invalid",b.isInvalid).toggleClass("locked",d).toggleClass("full",c).toggleClass("not-full",!c).toggleClass("input-active",b.isFocused&&!b.isInputHidden).toggleClass("dropdown-active",b.isOpen).toggleClass("has-options",!a.isEmptyObject(b.options)).toggleClass("has-items",b.items.length>0),b.$control_input.data("grow",!c&&!d)},isFull:function(){
+return null!==this.settings.maxItems&&this.items.length>=this.settings.maxItems},updateOriginalInput:function(a){var b,c,d,e,f=this;if(a=a||{},1===f.tagType){for(d=[],b=0,c=f.items.length;b<c;b++)e=f.options[f.items[b]][f.settings.labelField]||"",d.push('<option value="'+l(f.items[b])+'" selected="selected">'+l(e)+"</option>");d.length||this.$input.attr("multiple")||d.push('<option value="" selected="selected"></option>'),f.$input.html(d.join(""))}else f.$input.val(f.getValue()),f.$input.attr("value",f.$input.val());f.isSetup&&(a.silent||f.trigger("change",f.$input.val()))},updatePlaceholder:function(){if(this.settings.placeholder){var a=this.$control_input;this.items.length?a.removeAttr("placeholder"):a.attr("placeholder",this.settings.placeholder),a.triggerHandler("update",{force:!0})}},open:function(){var a=this;a.isLocked||a.isOpen||"multi"===a.settings.mode&&a.isFull()||(a.focus(),a.isOpen=!0,a.refreshState(),a.$dropdown.css({visibility:"hidden",display:"block"}),a.positionDropdown(),a.$dropdown.css({visibility:"visible"}),a.trigger("dropdown_open",a.$dropdown))},close:function(){var a=this,b=a.isOpen;"single"===a.settings.mode&&a.items.length&&(a.hideInput(),a.isBlurring||a.$control_input.blur()),a.isOpen=!1,a.$dropdown.hide(),a.setActiveOption(null),a.refreshState(),b&&a.trigger("dropdown_close",a.$dropdown)},positionDropdown:function(){var a=this.$control,b="body"===this.settings.dropdownParent?a.offset():a.position();b.top+=a.outerHeight(!0),this.$dropdown.css({width:a[0].getBoundingClientRect().width,top:b.top,left:b.left})},clear:function(a){var b=this;b.items.length&&(b.$control.children(":not(input)").remove(),b.items=[],b.lastQuery=null,b.setCaret(0),b.setActiveItem(null),b.updatePlaceholder(),b.updateOriginalInput({silent:a}),b.refreshState(),b.showInput(),b.trigger("clear"))},insertAtCaret:function(a){var b=Math.min(this.caretPos,this.items.length),c=a[0],d=this.buffer||this.$control[0];0===b?d.insertBefore(c,d.firstChild):d.insertBefore(c,d.childNodes[b]),this.setCaret(b+1)},deleteSelection:function(b){var c,d,e,f,g,h,i,j,k,l=this;if(e=b&&8===b.keyCode?-1:1,f=r(l.$control_input[0]),l.$activeOption&&!l.settings.hideSelected&&(i=l.getAdjacentOption(l.$activeOption,-1).attr("data-value")),g=[],l.$activeItems.length){for(k=l.$control.children(".active:"+(e>0?"last":"first")),h=l.$control.children(":not(input)").index(k),e>0&&h++,c=0,d=l.$activeItems.length;c<d;c++)g.push(a(l.$activeItems[c]).attr("data-value"));b&&(b.preventDefault(),b.stopPropagation())}else(l.isFocused||"single"===l.settings.mode)&&l.items.length&&(e<0&&0===f.start&&0===f.length?g.push(l.items[l.caretPos-1]):e>0&&f.start===l.$control_input.val().length&&g.push(l.items[l.caretPos]));if(!g.length||"function"==typeof l.settings.onDelete&&!1===l.settings.onDelete.apply(l,[g]))return!1;for(void 0!==h&&l.setCaret(h);g.length;)l.removeItem(g.pop());return l.showInput(),l.positionDropdown(),l.refreshOptions(!0),i&&(j=l.getOption(i),j.length&&l.setActiveOption(j)),!0},advanceSelection:function(a,b){var c,d,e,f,g,h=this;0!==a&&(h.rtl&&(a*=-1),c=a>0?"last":"first",d=r(h.$control_input[0]),h.isFocused&&!h.isInputHidden?(f=h.$control_input.val().length,(a<0?0===d.start&&0===d.length:d.start===f)&&!f&&h.advanceCaret(a,b)):(g=h.$control.children(".active:"+c),g.length&&(e=h.$control.children(":not(input)").index(g),h.setActiveItem(null),h.setCaret(a>0?e+1:e))))},advanceCaret:function(a,b){var c,d,e=this;0!==a&&(c=a>0?"next":"prev",e.isShiftDown?(d=e.$control_input[c](),d.length&&(e.hideInput(),e.setActiveItem(d),b&&b.preventDefault())):e.setCaret(e.caretPos+a))},setCaret:function(b){var c=this;if(b="single"===c.settings.mode?c.items.length:Math.max(0,Math.min(c.items.length,b)),!c.isPending){var d,e,f,g;for(f=c.$control.children(":not(input)"),d=0,e=f.length;d<e;d++)g=a(f[d]).detach(),d<b?c.$control_input.before(g):c.$control.append(g)}c.caretPos=b},lock:function(){this.close(),this.isLocked=!0,this.refreshState()},unlock:function(){this.isLocked=!1,this.refreshState()},disable:function(){var a=this;a.$input.prop("disabled",!0),a.$control_input.prop("disabled",!0).prop("tabindex",-1),a.isDisabled=!0,a.lock()},enable:function(){var a=this;a.$input.prop("disabled",!1),a.$control_input.prop("disabled",!1).prop("tabindex",a.tabIndex),a.isDisabled=!1,a.unlock()},destroy:function(){var b=this,c=b.eventNS,d=b.revertSettings;b.trigger("destroy"),b.off(),b.$wrapper.remove(),b.$dropdown.remove(),b.$input.html("").append(d.$children).removeAttr("tabindex").removeClass("selectized").attr({tabindex:d.tabindex}).show(),b.$control_input.removeData("grow"),b.$input.removeData("selectize"),0==--w.count&&w.$testInput&&(w.$testInput.remove(),w.$testInput=void 0),a(window).off(c),a(document).off(c),a(document.body).off(c),delete b.$input[0].selectize},render:function(b,c){var d,e,f="",g=!1,h=this;return"option"!==b&&"item"!==b||(d=k(c[h.settings.valueField]),g=!!d),g&&(j(h.renderCache[b])||(h.renderCache[b]={}),h.renderCache[b].hasOwnProperty(d))?h.renderCache[b][d]:(f=a(h.settings.render[b].apply(this,[c,l])),"option"===b||"option_create"===b?c[h.settings.disabledField]||f.attr("data-selectable",""):"optgroup"===b&&(e=c[h.settings.optgroupValueField]||"",f.attr("data-group",e),c[h.settings.disabledField]&&f.attr("data-disabled","")),"option"!==b&&"item"!==b||f.attr("data-value",d||""),g&&(h.renderCache[b][d]=f[0]),f[0])},clearCache:function(a){var b=this;void 0===a?b.renderCache={}:delete b.renderCache[a]},canCreate:function(a){var b=this;if(!b.settings.create)return!1;var c=b.settings.createFilter;return a.length&&("function"!=typeof c||c.apply(b,[a]))&&("string"!=typeof c||new RegExp(c).test(a))&&(!(c instanceof RegExp)||c.test(a))}}),w.count=0,w.defaults={options:[],optgroups:[],plugins:[],delimiter:",",splitOn:null,persist:!0,diacritics:!0,create:!1,createOnBlur:!1,createFilter:null,highlight:!0,openOnFocus:!0,maxOptions:1e3,maxItems:null,hideSelected:null,addPrecedence:!1,selectOnTab:!1,preload:!1,allowEmptyOption:!1,closeAfterSelect:!1,scrollDuration:60,loadThrottle:300,loadingClass:"loading",dataAttr:"data-data",optgroupField:"optgroup",valueField:"value",labelField:"text",disabledField:"disabled",optgroupLabelField:"label",optgroupValueField:"value",lockOptgroupOrder:!1,sortField:"$order",searchField:["text"],searchConjunction:"and",mode:null,wrapperClass:"selectize-control",inputClass:"selectize-input",dropdownClass:"selectize-dropdown",dropdownContentClass:"selectize-dropdown-content",dropdownParent:null,copyClassesToDropdown:!0,render:{}},a.fn.selectize=function(b){var c=a.fn.selectize.defaults,d=a.extend({},c,b),e=d.dataAttr,f=d.labelField,g=d.valueField,h=d.disabledField,i=d.optgroupField,j=d.optgroupLabelField,l=d.optgroupValueField,m=function(b,c){var h,i,j,k,l=b.attr(e);if(l)for(c.options=JSON.parse(l),h=0,i=c.options.length;h<i;h++)c.items.push(c.options[h][g]);else{var m=a.trim(b.val()||"");if(!d.allowEmptyOption&&!m.length)return;for(j=m.split(d.delimiter),h=0,i=j.length;h<i;h++)k={},k[f]=j[h],k[g]=j[h],c.options.push(k);c.items=j}},n=function(b,c){var m,n,o,p,q=c.options,r={},s=function(a){var b=e&&a.attr(e);return"string"==typeof b&&b.length?JSON.parse(b):null},t=function(b,e){b=a(b);var j=k(b.val());if(j||d.allowEmptyOption)if(r.hasOwnProperty(j)){if(e){var l=r[j][i];l?a.isArray(l)?l.push(e):r[j][i]=[l,e]:r[j][i]=e}}else{var m=s(b)||{};m[f]=m[f]||b.text(),m[g]=m[g]||j,m[h]=m[h]||b.prop("disabled"),m[i]=m[i]||e,r[j]=m,q.push(m),b.is(":selected")&&c.items.push(j)}};for(c.maxItems=b.attr("multiple")?null:1,p=b.children(),m=0,n=p.length;m<n;m++)o=p[m].tagName.toLowerCase(),"optgroup"===o?function(b){var d,e,f,g,i;for(b=a(b),f=b.attr("label"),f&&(g=s(b)||{},g[j]=f,g[l]=f,g[h]=b.prop("disabled"),c.optgroups.push(g)),i=a("option",b),d=0,e=i.length;d<e;d++)t(i[d],f)}(p[m]):"option"===o&&t(p[m])};return this.each(function(){if(!this.selectize){var e=a(this),f=this.tagName.toLowerCase(),g=e.attr("placeholder")||e.attr("data-placeholder");g||d.allowEmptyOption||(g=e.children('option[value=""]').text());var h={placeholder:g,options:[],optgroups:[],items:[]};"select"===f?n(e,h):m(e,h),new w(e,a.extend(!0,{},c,h,b))}})},a.fn.selectize.defaults=w.defaults,a.fn.selectize.support={validity:i},w.define("drag_drop",function(b){if(!a.fn.sortable)throw new Error('The "drag_drop" plugin requires jQuery UI "sortable".');if("multi"===this.settings.mode){var c=this;c.lock=function(){var a=c.lock;return function(){var b=c.$control.data("sortable");return b&&b.disable(),a.apply(c,arguments)}}(),c.unlock=function(){var a=c.unlock;return function(){var b=c.$control.data("sortable");return b&&b.enable(),a.apply(c,arguments)}}(),c.setup=function(){var b=c.setup;return function(){b.apply(this,arguments);var d=c.$control.sortable({items:"[data-value]",forcePlaceholderSize:!0,disabled:c.isLocked,start:function(a,b){b.placeholder.css("width",b.helper.css("width")),d.css({overflow:"visible"})},stop:function(){d.css({overflow:"hidden"});var b=c.$activeItems?c.$activeItems.slice():null,e=[];d.children("[data-value]").each(function(){e.push(a(this).attr("data-value"))}),c.setValue(e),c.setActiveItem(b)}})}}()}}),w.define("dropdown_header",function(b){var c=this;b=a.extend({title:"Untitled",headerClass:"selectize-dropdown-header",titleRowClass:"selectize-dropdown-header-title",labelClass:"selectize-dropdown-header-label",closeClass:"selectize-dropdown-header-close",html:function(a){return'<div class="'+a.headerClass+'"><div class="'+a.titleRowClass+'"><span class="'+a.labelClass+'">'+a.title+'</span><a href="javascript:void(0)" class="'+a.closeClass+'">&times;</a></div></div>'}},b),c.setup=function(){var d=c.setup;return function(){d.apply(c,arguments),c.$dropdown_header=a(b.html(b)),c.$dropdown.prepend(c.$dropdown_header)}}()}),w.define("optgroup_columns",function(b){var c=this;b=a.extend({equalizeWidth:!0,equalizeHeight:!0},b),this.getAdjacentOption=function(b,c){var d=b.closest("[data-group]").find("[data-selectable]"),e=d.index(b)+c;return e>=0&&e<d.length?d.eq(e):a()},this.onKeyDown=function(){var a=c.onKeyDown;return function(b){var d,e,f,g;return!this.isOpen||37!==b.keyCode&&39!==b.keyCode?a.apply(this,arguments):(c.ignoreHover=!0,g=this.$activeOption.closest("[data-group]"),d=g.find("[data-selectable]").index(this.$activeOption),g=37===b.keyCode?g.prev("[data-group]"):g.next("[data-group]"),f=g.find("[data-selectable]"),e=f.eq(Math.min(f.length-1,d)),void(e.length&&this.setActiveOption(e)))}}();var d=function(){var a,b=d.width,c=document;return void 0===b&&(a=c.createElement("div"),a.innerHTML='<div style="width:50px;height:50px;position:absolute;left:-50px;top:-50px;overflow:auto;"><div style="width:1px;height:100px;"></div></div>',a=a.firstChild,c.body.appendChild(a),b=d.width=a.offsetWidth-a.clientWidth,c.body.removeChild(a)),b},e=function(){var e,f,g,h,i,j,k;if(k=a("[data-group]",c.$dropdown_content),(f=k.length)&&c.$dropdown_content.width()){if(b.equalizeHeight){for(g=0,e=0;e<f;e++)g=Math.max(g,k.eq(e).height());k.css({height:g})}b.equalizeWidth&&(j=c.$dropdown_content.innerWidth()-d(),h=Math.round(j/f),k.css({width:h}),f>1&&(i=j-h*(f-1),k.eq(f-1).css({width:i})))}};(b.equalizeHeight||b.equalizeWidth)&&(m.after(this,"positionDropdown",e),m.after(this,"refreshOptions",e))}),w.define("remove_button",function(b){b=a.extend({label:"&times;",title:"Remove",className:"remove",append:!0},b);if("single"===this.settings.mode)return void function(b,c){c.className="remove-single";var d=b,e='<a href="javascript:void(0)" class="'+c.className+'" tabindex="-1" title="'+l(c.title)+'">'+c.label+"</a>",f=function(b,c){return a("<span>").append(b).append(c)};b.setup=function(){var g=d.setup;return function(){if(c.append){var h=a(d.$input.context).attr("id"),i=(a("#"+h),d.settings.render.item);d.settings.render.item=function(a){return f(i.apply(b,arguments),e)}}g.apply(b,arguments),b.$control.on("click","."+c.className,function(a){a.preventDefault(),d.isLocked||d.clear()})}}()}(this,b);!function(b,c){var d=b,e='<a href="javascript:void(0)" class="'+c.className+'" tabindex="-1" title="'+l(c.title)+'">'+c.label+"</a>",f=function(a,b){var c=a.search(/(<\/[^>]+>\s*)$/);return a.substring(0,c)+b+a.substring(c)};b.setup=function(){var g=d.setup;return function(){if(c.append){var h=d.settings.render.item;d.settings.render.item=function(a){return f(h.apply(b,arguments),e)}}g.apply(b,arguments),b.$control.on("click","."+c.className,function(b){if(b.preventDefault(),!d.isLocked){var c=a(b.currentTarget).parent();d.setActiveItem(c),d.deleteSelection()&&d.setCaret(d.items.length)}})}}()}(this,b)}),w.define("restore_on_backspace",function(a){var b=this;a.text=a.text||function(a){return a[this.settings.labelField]},this.onKeyDown=function(){var c=b.onKeyDown;return function(b){var d,e;return 8===b.keyCode&&""===this.$control_input.val()&&!this.$activeItems.length&&(d=this.caretPos-1)>=0&&d<this.items.length?(e=this.options[this.items[d]],this.deleteSelection(b)&&(this.setTextboxValue(a.text.apply(this,[e])),this.refreshOptions(!0)),void b.preventDefault()):c.apply(this,arguments)}}()}),w});
diff --git a/modules/http/static/selectize.spdx b/modules/http/static/selectize.spdx
new file mode 100644
index 0000000..594c413
--- /dev/null
+++ b/modules/http/static/selectize.spdx
@@ -0,0 +1,11 @@
+SPDXVersion: SPDX-2.1
+DataLicense: CC0-1.0
+SPDXID: SPDXRef-DOCUMENT
+DocumentName: selectize.js
+DocumentNamespace: http://spdx.org/spdxdocs/spdx-v2.1-5ffbfb08-4009-4a41-bc96-16adb5f2b632
+
+PackageName: selectize.js
+PackageVersion: 0.12.6
+PackageDownloadLocation: git+https://github.com/selectize/selectize.js.git@eb0fca364f9bd6864ae197ea58c853f2717052a9#dist/
+PackageOriginator: Person: Jonathan Allard (jonathan@allard.io)
+PackageLicenseDeclared: Apache-2.0
diff --git a/modules/http/static/topojson.js b/modules/http/static/topojson.js
new file mode 100644
index 0000000..f66214b
--- /dev/null
+++ b/modules/http/static/topojson.js
@@ -0,0 +1,2 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+!function(){function t(n,t){function r(t){var r,e=n.arcs[0>t?~t:t],o=e[0];return n.transform?(r=[0,0],e.forEach(function(n){r[0]+=n[0],r[1]+=n[1]})):r=e[e.length-1],0>t?[r,o]:[o,r]}function e(n,t){for(var r in n){var e=n[r];delete t[e.start],delete e.start,delete e.end,e.forEach(function(n){o[0>n?~n:n]=1}),f.push(e)}}var o={},i={},u={},f=[],c=-1;return t.forEach(function(r,e){var o,i=n.arcs[0>r?~r:r];i.length<3&&!i[1][0]&&!i[1][1]&&(o=t[++c],t[c]=r,t[e]=o)}),t.forEach(function(n){var t,e,o=r(n),f=o[0],c=o[1];if(t=u[f])if(delete u[t.end],t.push(n),t.end=c,e=i[c]){delete i[e.start];var a=e===t?t:t.concat(e);i[a.start=t.start]=u[a.end=e.end]=a}else i[t.start]=u[t.end]=t;else if(t=i[c])if(delete i[t.start],t.unshift(n),t.start=f,e=u[f]){delete u[e.end];var s=e===t?t:e.concat(t);i[s.start=e.start]=u[s.end=t.end]=s}else i[t.start]=u[t.end]=t;else t=[n],i[t.start=f]=u[t.end=c]=t}),e(u,i),e(i,u),t.forEach(function(n){o[0>n?~n:n]||f.push([n])}),f}function r(n,r,e){function o(n){var t=0>n?~n:n;(s[t]||(s[t]=[])).push({i:n,g:a})}function i(n){n.forEach(o)}function u(n){n.forEach(i)}function f(n){"GeometryCollection"===n.type?n.geometries.forEach(f):n.type in l&&(a=n,l[n.type](n.arcs))}var c=[];if(arguments.length>1){var a,s=[],l={LineString:i,MultiLineString:u,Polygon:u,MultiPolygon:function(n){n.forEach(u)}};f(r),s.forEach(arguments.length<3?function(n){c.push(n[0].i)}:function(n){e(n[0].g,n[n.length-1].g)&&c.push(n[0].i)})}else for(var h=0,p=n.arcs.length;p>h;++h)c.push(h);return{type:"MultiLineString",arcs:t(n,c)}}function e(r,e){function o(n){n.forEach(function(t){t.forEach(function(t){(f[t=0>t?~t:t]||(f[t]=[])).push(n)})}),c.push(n)}function i(n){return l(u(r,{type:"Polygon",arcs:[n]}).coordinates[0])>0}var f={},c=[],a=[];return e.forEach(function(n){"Polygon"===n.type?o(n.arcs):"MultiPolygon"===n.type&&n.arcs.forEach(o)}),c.forEach(function(n){if(!n._){var t=[],r=[n];for(n._=1,a.push(t);n=r.pop();)t.push(n),n.forEach(function(n){n.forEach(function(n){f[0>n?~n:n].forEach(function(n){n._||(n._=1,r.push(n))})})})}}),c.forEach(function(n){delete n._}),{type:"MultiPolygon",arcs:a.map(function(e){var o=[];if(e.forEach(function(n){n.forEach(function(n){n.forEach(function(n){f[0>n?~n:n].length<2&&o.push(n)})})}),o=t(r,o),(n=o.length)>1)for(var u,c=i(e[0][0]),a=0;n>a;++a)if(c===i(o[a])){u=o[0],o[0]=o[a],o[a]=u;break}return o})}}function o(n,t){return"GeometryCollection"===t.type?{type:"FeatureCollection",features:t.geometries.map(function(t){return i(n,t)})}:i(n,t)}function i(n,t){var r={type:"Feature",id:t.id,properties:t.properties||{},geometry:u(n,t)};return null==t.id&&delete r.id,r}function u(n,t){function r(n,t){t.length&&t.pop();for(var r,e=s[0>n?~n:n],o=0,i=e.length;i>o;++o)t.push(r=e[o].slice()),a(r,o);0>n&&f(t,i)}function e(n){return n=n.slice(),a(n,0),n}function o(n){for(var t=[],e=0,o=n.length;o>e;++e)r(n[e],t);return t.length<2&&t.push(t[0].slice()),t}function i(n){for(var t=o(n);t.length<4;)t.push(t[0].slice());return t}function u(n){return n.map(i)}function c(n){var t=n.type;return"GeometryCollection"===t?{type:t,geometries:n.geometries.map(c)}:t in l?{type:t,coordinates:l[t](n)}:null}var a=g(n.transform),s=n.arcs,l={Point:function(n){return e(n.coordinates)},MultiPoint:function(n){return n.coordinates.map(e)},LineString:function(n){return o(n.arcs)},MultiLineString:function(n){return n.arcs.map(o)},Polygon:function(n){return u(n.arcs)},MultiPolygon:function(n){return n.arcs.map(u)}};return c(t)}function f(n,t){for(var r,e=n.length,o=e-t;o<--e;)r=n[o],n[o++]=n[e],n[e]=r}function c(n,t){for(var r=0,e=n.length;e>r;){var o=r+e>>>1;n[o]<t?r=o+1:e=o}return r}function a(n){function t(n,t){n.forEach(function(n){0>n&&(n=~n);var r=o[n];r?r.push(t):o[n]=[t]})}function r(n,r){n.forEach(function(n){t(n,r)})}function e(n,t){"GeometryCollection"===n.type?n.geometries.forEach(function(n){e(n,t)}):n.type in u&&u[n.type](n.arcs,t)}var o={},i=n.map(function(){return[]}),u={LineString:t,MultiLineString:r,Polygon:r,MultiPolygon:function(n,t){n.forEach(function(n){r(n,t)})}};n.forEach(e);for(var f in o)for(var a=o[f],s=a.length,l=0;s>l;++l)for(var h=l+1;s>h;++h){var p,v=a[l],g=a[h];(p=i[v])[f=c(p,g)]!==g&&p.splice(f,0,g),(p=i[g])[f=c(p,v)]!==v&&p.splice(f,0,v)}return i}function s(n,t){function r(n){u.remove(n),n[1][2]=t(n),u.push(n)}var e,o=g(n.transform),i=m(n.transform),u=v(),f=0;for(t||(t=h),n.arcs.forEach(function(n){var r=[];n.forEach(o);for(var i=1,f=n.length-1;f>i;++i)e=n.slice(i-1,i+2),e[1][2]=t(e),r.push(e),u.push(e);n[0][2]=n[f][2]=1/0;for(var i=0,f=r.length;f>i;++i)e=r[i],e.previous=r[i-1],e.next=r[i+1]});e=u.pop();){var c=e.previous,a=e.next;e[1][2]<f?e[1][2]=f:f=e[1][2],c&&(c.next=a,c[2]=e[2],r(c)),a&&(a.previous=c,a[0]=e[0],r(a))}return n.arcs.forEach(function(n){n.forEach(i)}),n}function l(n){for(var t,r=-1,e=n.length,o=n[e-1],i=0;++r<e;)t=o,o=n[r],i+=t[0]*o[1]-t[1]*o[0];return.5*i}function h(n){var t=n[0],r=n[1],e=n[2];return Math.abs((t[0]-e[0])*(r[1]-t[1])-(t[0]-r[0])*(e[1]-t[1]))}function p(n,t){return n[1][2]-t[1][2]}function v(){function n(n,t){for(;t>0;){var r=(t+1>>1)-1,o=e[r];if(p(n,o)>=0)break;e[o._=t]=o,e[n._=t=r]=n}}function t(n,t){for(;;){var r=t+1<<1,i=r-1,u=t,f=e[u];if(o>i&&p(e[i],f)<0&&(f=e[u=i]),o>r&&p(e[r],f)<0&&(f=e[u=r]),u===t)break;e[f._=t]=f,e[n._=t=u]=n}}var r={},e=[],o=0;return r.push=function(t){return n(e[t._=o]=t,o++),o},r.pop=function(){if(!(0>=o)){var n,r=e[0];return--o>0&&(n=e[o],t(e[n._=0]=n,0)),r}},r.remove=function(r){var i,u=r._;if(e[u]===r)return u!==--o&&(i=e[o],(p(i,r)<0?n:t)(e[i._=u]=i,u)),u},r}function g(n){if(!n)return y;var t,r,e=n.scale[0],o=n.scale[1],i=n.translate[0],u=n.translate[1];return function(n,f){f||(t=r=0),n[0]=(t+=n[0])*e+i,n[1]=(r+=n[1])*o+u}}function m(n){if(!n)return y;var t,r,e=n.scale[0],o=n.scale[1],i=n.translate[0],u=n.translate[1];return function(n,f){f||(t=r=0);var c=(n[0]-i)/e|0,a=(n[1]-u)/o|0;n[0]=c-t,n[1]=a-r,t=c,r=a}}function y(){}var d={version:"1.6.9",mesh:function(n){return u(n,r.apply(this,arguments))},meshArcs:r,merge:function(n){return u(n,e.apply(this,arguments))},mergeArcs:e,feature:o,neighbors:a,presimplify:s};"function"==typeof define&&define.amd?define(d):"object"==typeof module&&module.exports?module.exports=d:this.topojson=d}();
diff --git a/modules/http/static/topojson.spdx b/modules/http/static/topojson.spdx
new file mode 100644
index 0000000..5e5f302
--- /dev/null
+++ b/modules/http/static/topojson.spdx
@@ -0,0 +1,12 @@
+SPDXVersion: SPDX-2.1
+DataLicense: CC0-1.0
+SPDXID: SPDXRef-DOCUMENT
+DocumentName: topojson
+DocumentNamespace: http://spdx.org/spdxdocs/spdx-v2.1-2a02fcb5-2889-42c1-ac6a-2674fb1b7be0
+
+PackageName: topojson
+PackageVersion: 1.6.9
+PackageDownloadLocation: https://unpkg.com/topojson@1.6.9/topojson.min.js
+PackageChecksum: SHA256: 091bee8a099772d9a377ddbb4f2a43a026c4877e986d6c6a9291daf043b0b37e
+PackageOriginator: Person: Michael Bostock (mike@ocks.org)
+PackageLicenseDeclared: BSD-3-Clause
diff --git a/modules/http/test_tls/broken.crt b/modules/http/test_tls/broken.crt
new file mode 100644
index 0000000..d93d1f8
--- /dev/null
+++ b/modules/http/test_tls/broken.crt
@@ -0,0 +1,3 @@
+Æ¿¯ˆž³psâ$Ðëí¯Ö¡«Æȼ[ŒîØ1´Ç =fl:°Êl=z†=M}iÉ»¤Ñ­†÷*7ƒ)Ä Ñ5
+ÈóîÒj¨šIÜWÈÀ­®·´ MwÚf[´HïŽíÙÑÅ-Á¯ËìýEȼë€fû¦Ö   2fTKÊqýFѬUÖ ƒ“(jÀ¤œaà,Õœ¥*²X:lFÌÍ¿£Mî©>ó3Œš
+¬‘áD<^O™qk¥ˆQŽÉý‘κM…gÄ]pUNÉö¥MÝ>ŒŸÂÿº¹á(EI”®µ'ÌGÅ€÷mÕÅ÷Ã:ž3 º_”!‚ÁÎ’? 3Œú$H[„E†¡M¡4èòR¨†ÒA+0w¥ö0ÏÓÁ“%é¸eo¤ašåëØó(öw;¥oÇ¥î¯$—!ZèÀˆr%Äùàü&ßýh;1¾@ˆñý-9((Ób7±á\„UâoÃJÊ`»:Þª€†¼™~ŸdÃŽa•œƒìÜЃÇŒEÂœ—PB*l«Î}!q7ü;+QRL‘¢¶vÉûËQ‡[KãYûXðRà 2(¬íùªå7ÀÜ+$ëÃE,óõ­Ûý³IRÄÙï· §^4µD ¼_r…,išÁèÁ\ðhξ \ No newline at end of file
diff --git a/modules/http/test_tls/broken.key b/modules/http/test_tls/broken.key
new file mode 100644
index 0000000..ebcbfcf
--- /dev/null
+++ b/modules/http/test_tls/broken.key
Binary files differ
diff --git a/modules/http/test_tls/ca.crt b/modules/http/test_tls/ca.crt
new file mode 100644
index 0000000..81a42d2
--- /dev/null
+++ b/modules/http/test_tls/ca.crt
@@ -0,0 +1,20 @@
+-----BEGIN CERTIFICATE-----
+MIIDVzCCAj+gAwIBAgIUAu0lPjQwQtB0QMMjaFfa+RrJPo0wDQYJKoZIhvcNAQEL
+BQAwMzELMAkGA1UEBhMCR0IxEDAOBgNVBAgMB0VuZ2xhbmQxEjAQBgNVBAoMCUFs
+aWNlIEx0ZDAeFw0xOTAzMjgxMjUzMjNaFw0zOTAzMjMxMjUzMjNaMDMxCzAJBgNV
+BAYTAkdCMRAwDgYDVQQIDAdFbmdsYW5kMRIwEAYDVQQKDAlBbGljZSBMdGQwggEi
+MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDkLE9N62uDhi/zecTnGgQisDcg
+RuSgvU8Z/CVQC5WvSmZxO/RKw+TwSKigVMBiLKvi2gZwda4QZN1+If2/IPO41NvV
+Gc9vMffOpYCi3dLW9u3a3n7ZDHUlbmbYMyrkWcYEKC+wGBgvg9a1bce3VEvLGj/t
+YtTV4DPiUQz87jQxRp1a++XVvYkM6XpRIxfoyRdjW7ixssdpkd3DAsf2+qS35Ax8
+XTUvcoHuBcL2j4FAvptRk09T4S7bYLzx5cG0DBxhc75++n1T02D40D5uV7j2OI2N
+pQpsGhewrvS+9+F7z2f7Kpc1slJ7MW5eiYflF/R4gDxFTd0kZ9YWeRwwf1ltAgMB
+AAGjYzBhMB0GA1UdDgQWBBQRVncFgsUWq566JMAcejJj0t9uFjAfBgNVHSMEGDAW
+gBQRVncFgsUWq566JMAcejJj0t9uFjAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB
+/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAQEANdM7o2phBhK5ZhRVjQQb7Ff+l1zn
+EZ5HVnn+YwL3y9h8nJsW5Y1xiIm1w/Apn+gqrBYUMchJxQ1/ha0Bza6kl29i2fck
+oAAaduTsZImiKCAMxlN8KpJm9DZ3woCwktG7orgzEFgVOiAqk6wbXaff1rAgoVDV
+nzWKh7AoyGkXxFI+wrJFODl92a+gy20pNZCDQqVtiC8AiHl2p+UrU8f7yzjyUyyl
+4ZKyvVne+SB4n4mug1JRLgxTM1C/Qp21DaYaCAYeqT7MZTd7d5nm0nWNOSlZ2lrZ
+e3RuQZic89G1OK9qvjfaUMvzm0iAE9hZ7d3ac1PU+KqRmi0TTO1y62M+rA==
+-----END CERTIFICATE-----
diff --git a/modules/http/test_tls/chain.crt b/modules/http/test_tls/chain.crt
new file mode 100644
index 0000000..1822e6d
--- /dev/null
+++ b/modules/http/test_tls/chain.crt
@@ -0,0 +1,41 @@
+-----BEGIN CERTIFICATE-----
+MIIDVjCCAj6gAwIBAgICEAEwDQYJKoZIhvcNAQELBQAwTTELMAkGA1UEBhMCR0Ix
+EDAOBgNVBAgMB0VuZ2xhbmQxEjAQBgNVBAoMCUFsaWNlIEx0ZDEYMBYGA1UEAwwP
+SW50ZXJtZWRpYXRlIENBMB4XDTE5MDYxNDA5NTAzOVoXDTM5MDYwOTA5NTAzOVow
+WDELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGElu
+dGVybmV0IFdpZGdpdHMgUHR5IEx0ZDERMA8GA1UEAwwIa3IubG9jYWwwggEiMA0G
+CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDVh57hcYaSjQVQ+cUPD++o4ws0vI+S
+2LGQ4u+YzRvx2o3r85DFklfYTM2OICJKEyMNsUm6c45gc5Gq1DBXbmQ+bUTL+Be5
+olJYO1IVP5CcTUmqUOw6yqm4idqoDdmRxwhglRIqv4OYOcU6JBlOqQHmYIKTiwgU
+I0y0lRiWQF+lPaa97HI0YrTcqYG0eLMCDKWnk1FBlIvOcrnrOS7/zzcYYoytYvNi
+//iavyQNMfHlhPUNNmE3TNQ6OmRkKI8wvoRkrvjfnwf04suIrOkd1ADdNqguWTUO
+pNE316lgmZpkfd4hYzlSGTCfjuhRqa1/a7eA8GNkKq03xuOI75rR15eZAgMBAAGj
+NTAzMAkGA1UdEwQCMAAwCwYDVR0PBAQDAgXgMBkGA1UdEQQSMBCCCGtyLmxvY2Fs
+hwR/AAABMA0GCSqGSIb3DQEBCwUAA4IBAQBC4Op5SaXqAdvZKjqO8cd8JpJlnGa/
+UnuQAsVgsQ2giBuZMIMIHzxawbEfCOHhkv1doLW9uEWyPQEGdQntoCHqc4Mb70Zd
+XBcepTlqUprpx/k6nw2io3JCUMmhbgfme63c5OiodxbBQCfWf6vIZjfOSPN0IYVr
+NY4kc0jcUEN0dsqjXEqKVbiDUcApKGGbe87KmSqi02UZHSoBPxm/Tr12n1Eu4AJR
+k7e3tJ3dslIYxYbQE6tUKiPWlP+rETcL7ran0m3YzEplMPvZdme9mu3w9Upsigx7
+lRCELEjwpBPZ5cUD04SkesoTGP6g8ZbmdpyjkI7lOjXvrBDim20EK47x
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDYjCCAkqgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwMzELMAkGA1UEBhMCR0Ix
+EDAOBgNVBAgMB0VuZ2xhbmQxEjAQBgNVBAoMCUFsaWNlIEx0ZDAeFw0xOTAzMjgx
+MjU5NTRaFw0zOTAzMjMxMjU5NTRaME0xCzAJBgNVBAYTAkdCMRAwDgYDVQQIDAdF
+bmdsYW5kMRIwEAYDVQQKDAlBbGljZSBMdGQxGDAWBgNVBAMMD0ludGVybWVkaWF0
+ZSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMOH4k6f8wL5IruB
+m1BqQCE4ZQnDN8SX1ZwDp7G7tlycnJDB9PBkCziZcU11ezw6xdhT3J0jCEDwLrx2
+gsi+DWJwsC4CfcLdN1iuPeMRZQyC4GmQzPTJmQ8Kl/dQFZPV0wkd+JZNOfvpxpnD
+5WHkqg3DX6933/86raZ3NVfeVmTdHRdol+K8ve+1924IfrZNbZxatCX7AwEgyUFi
+qogXjcO+fqQed8VzHXGasqYMMLlMZMGLmusHlK6pDyscayubNOk1U9eHoRNYp6cb
+LChG8WnSpFv/LAB6QuyxvOwTK86R7k3J48ProPEFHkhUhHXxIHnR5l5+XLxcQSJ9
+xP7dFL8CAwEAAaNmMGQwHQYDVR0OBBYEFOaglkXoUdbRnwAXnDbbX5g62VXQMB8G
+A1UdIwQYMBaAFBFWdwWCxRarnrokwBx6MmPS324WMBIGA1UdEwEB/wQIMAYBAf8C
+AQAwDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4IBAQDeEA0klOFmdxHV
+jO0z2nXKE2jRvckoSKDGxj0L6gSxoUVRqVJMvlYmje8i0D9NyFCTlhRBX/24NCoZ
+2Oe4drzAiF+g97Ns7wIyYhAhcdJLn/820FZLsDMUbvW0BSsKsFckEABev3/miuJE
+O5/OzkU53V+7Nu4zT8CcI5cni2tn7Xq0p0L410lL6Lobkn7jON+BNhshK+H/Vcwj
+hf8L+ZxlDomXx7SfcIDc6AdFz2t4gu+6CyP/G/zeqUOPeh2WrqHg+caPQcq58Ol8
+p1r258mH8fxafu7Qcm2j23ZjW7xrDVC2XLWeXozJztlnODv73Jm686jHKflcfFTm
+6OgxKoIT
+-----END CERTIFICATE-----
diff --git a/modules/http/test_tls/test.crt b/modules/http/test_tls/test.crt
new file mode 100644
index 0000000..e9405f9
--- /dev/null
+++ b/modules/http/test_tls/test.crt
@@ -0,0 +1,20 @@
+-----BEGIN CERTIFICATE-----
+MIIDVjCCAj6gAwIBAgICEAEwDQYJKoZIhvcNAQELBQAwTTELMAkGA1UEBhMCR0Ix
+EDAOBgNVBAgMB0VuZ2xhbmQxEjAQBgNVBAoMCUFsaWNlIEx0ZDEYMBYGA1UEAwwP
+SW50ZXJtZWRpYXRlIENBMB4XDTE5MDYxNDA5NTAzOVoXDTM5MDYwOTA5NTAzOVow
+WDELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGElu
+dGVybmV0IFdpZGdpdHMgUHR5IEx0ZDERMA8GA1UEAwwIa3IubG9jYWwwggEiMA0G
+CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDVh57hcYaSjQVQ+cUPD++o4ws0vI+S
+2LGQ4u+YzRvx2o3r85DFklfYTM2OICJKEyMNsUm6c45gc5Gq1DBXbmQ+bUTL+Be5
+olJYO1IVP5CcTUmqUOw6yqm4idqoDdmRxwhglRIqv4OYOcU6JBlOqQHmYIKTiwgU
+I0y0lRiWQF+lPaa97HI0YrTcqYG0eLMCDKWnk1FBlIvOcrnrOS7/zzcYYoytYvNi
+//iavyQNMfHlhPUNNmE3TNQ6OmRkKI8wvoRkrvjfnwf04suIrOkd1ADdNqguWTUO
+pNE316lgmZpkfd4hYzlSGTCfjuhRqa1/a7eA8GNkKq03xuOI75rR15eZAgMBAAGj
+NTAzMAkGA1UdEwQCMAAwCwYDVR0PBAQDAgXgMBkGA1UdEQQSMBCCCGtyLmxvY2Fs
+hwR/AAABMA0GCSqGSIb3DQEBCwUAA4IBAQBC4Op5SaXqAdvZKjqO8cd8JpJlnGa/
+UnuQAsVgsQ2giBuZMIMIHzxawbEfCOHhkv1doLW9uEWyPQEGdQntoCHqc4Mb70Zd
+XBcepTlqUprpx/k6nw2io3JCUMmhbgfme63c5OiodxbBQCfWf6vIZjfOSPN0IYVr
+NY4kc0jcUEN0dsqjXEqKVbiDUcApKGGbe87KmSqi02UZHSoBPxm/Tr12n1Eu4AJR
+k7e3tJ3dslIYxYbQE6tUKiPWlP+rETcL7ran0m3YzEplMPvZdme9mu3w9Upsigx7
+lRCELEjwpBPZ5cUD04SkesoTGP6g8ZbmdpyjkI7lOjXvrBDim20EK47x
+-----END CERTIFICATE-----
diff --git a/modules/http/test_tls/test.key b/modules/http/test_tls/test.key
new file mode 100644
index 0000000..1faa097
--- /dev/null
+++ b/modules/http/test_tls/test.key
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpAIBAAKCAQEA1Yee4XGGko0FUPnFDw/vqOMLNLyPktixkOLvmM0b8dqN6/OQ
+xZJX2EzNjiAiShMjDbFJunOOYHORqtQwV25kPm1Ey/gXuaJSWDtSFT+QnE1JqlDs
+OsqpuInaqA3ZkccIYJUSKr+DmDnFOiQZTqkB5mCCk4sIFCNMtJUYlkBfpT2mvexy
+NGK03KmBtHizAgylp5NRQZSLznK56zku/883GGKMrWLzYv/4mr8kDTHx5YT1DTZh
+N0zUOjpkZCiPML6EZK74358H9OLLiKzpHdQA3TaoLlk1DqTRN9epYJmaZH3eIWM5
+Uhkwn47oUamtf2u3gPBjZCqtN8bjiO+a0deXmQIDAQABAoIBAQCBnoUk50xAlBhh
+Em27+fmKtOBtj/U7uAz6HbhCMmg/RWOXktAUDwUCSYUSPJF0E+/YdQGDjHgmNqF7
+aLk7qchyWNRFWQHV7yI7ay8ltONs7kHEgMEV40Zpvk0cbOPg6Ug9kOBpUL5qXs9J
+vvYZ2OBNX9KEDAbIarE6gbNeKg+ldw5q8kCpDWpv+N7zmXq/9GDWPNBG/5lvGYrV
+MgBm6X4OdaYBD234MV5fNLtqiZQuM3JquEf4gFCCeBpA1MJYcodC+VcXNeZotziZ
+xssbGVsevPpLUkFNDV0s5UFYzEKgoCPNS+usNnwD5r6rFof7vEt8UHfKI2Dz6C9R
+q9xMFt4BAoGBAOzdsCQbveuGbae1HD616TliwgrGjaOVh8sT3r79YRLwekhWgqaP
+vbH0m6sEHKi0Sltj8jWd/ktO0ttfaMy45/DQRNjtPOwhr4kT+bmuyrMCfVOWsW/L
+bRrCU348OKr+VyhEI4YEFsaN1jpiwaQmaqcZFbGKJM84wW1OccUY2d7BAoGBAObH
+WPMKU1YwJmeMs38/MMUwWaw7BrLLk2zRsrOLX0ongp4+TGgI0iaFr8gwh3gAUc6W
+VjPyQtlWh2PLA9VabnSAmPu/NNq7X8fbpKFaBFdlkcFq7DpA8RuBN/b6+p4LD2Tb
+2q92VF4szrcflCnXnZrNxUqjY7NPxARw3y6vgUbZAoGAKImIK6XTywsmmR0VyGW5
+lGiibNWuR+C/bLHp3SXgBy3Av8COe5L+FAaY3ZvGi9jPIPTp7uMrMhg7Xe/mL6M1
+jrEWF0oCsybQs9UHWA/iAODcMgIIO+nEsl+vilskF5+PqwR+T+FDRJfhofxkx4ML
+na1dWRUbV5uO/vX94o1uPAECgYBTwHTffxfPZ5oIal+aBmzEo09n2eQMbyUJkPCx
+iBsE5mHY2/MOrmTV5h5tIG+JdVQ7DQQrxffMuEJaTQsPGsqLLUBX3IRp/SY9edC9
+XdXFge7rqsogOgFGYhbVYzAguxLTH5a1ptPneYtrmeJDbSSdUaAP/kvof0I7+lqE
+rtzTwQKBgQDTlchGtbuVAQzWuaN86UyXU43Ug9YybyLhanh8ZLCoUxsZVf2D2zVb
+TvqzKCx2qP+f3c6ydkg7pRSY0R80bxshhv1qUAvEqC74JgLBDlD7R/rQlj17MtNl
+G3TZIcskdnaHY5zydtvxXJxNxCCHJyBYqWN4L6NzJ+hp7lbP6hQICQ==
+-----END RSA PRIVATE KEY-----
diff --git a/modules/http/test_tls/tls.test.lua b/modules/http/test_tls/tls.test.lua
new file mode 100644
index 0000000..7d5c437
--- /dev/null
+++ b/modules/http/test_tls/tls.test.lua
@@ -0,0 +1,193 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+-- check prerequisites
+local has_http = pcall(require, 'kres_modules.http') and pcall(require, 'http.request')
+if not has_http then
+ -- skipping http module test because its not installed
+ os.exit(77)
+else
+ local request = require('http.request')
+ local openssl_ctx = require('openssl.ssl.context')
+
+ local function setup_module(desc, config)
+ if http then
+ modules.unload('http')
+ end
+ modules.load('http')
+ same(http.config(config), nil, desc .. ' can be configured')
+
+ local bound
+ for _ = 1,1000 do
+ bound, _err = pcall(net.listen, '127.0.0.1', math.random(1025,65535), { kind = 'webmgmt' })
+ if bound then
+ break
+ end
+ end
+ assert(bound, 'unable to bind a port for HTTP module (1000 attempts)')
+
+ local server_fd = next(http.servers)
+ assert(server_fd)
+ local server = http.servers[server_fd].server
+ ok(server ~= nil, 'creates server instance')
+ _, host, port = server:localname()
+ ok(host and port, 'binds to an interface')
+ return host, port
+ end
+
+ local function http_get(uri)
+ -- disable certificate verification in this test
+ local req = request.new_from_uri(uri)
+ local idxstart = string.find(uri, 'https://')
+ if idxstart == 1 then
+ req.ctx = openssl_ctx.new()
+ assert(req.ctx, 'OpenSSL cert verification must be disabled')
+ req.ctx:setVerify(openssl_ctx.VERIFY_NONE)
+ end
+
+ local headers = assert(req:go(16))
+ return tonumber(headers:get(':status'))
+ end
+
+ -- test whether http interface responds and binds
+ local function check_protocol(uri, description, ok_expected)
+ if ok_expected then
+ local code = http_get(uri)
+ same(code, 200, description)
+ else
+ boom(http_get, {uri}, description)
+ end
+ end
+
+ local function test_defaults()
+ local host, port = setup_module('HTTP module default config', nil)
+
+ local uri = string.format('http://%s:%d', host, port)
+ check_protocol(uri, 'HTTP is enabled by default', true)
+ uri = string.format('https://%s:%d', host, port)
+ check_protocol(uri, 'HTTPS is enabled by default', true)
+
+ modules.unload('http')
+ uri = string.format('http://%s:%d', host, port)
+ check_protocol(uri, 'HTTP stops working after module unload', false)
+ uri = string.format('https://%s:%d', host, port)
+ check_protocol(uri, 'HTTPS stops working after module unload', false)
+
+ end
+
+ local function test_http_only()
+ local desc = 'HTTP-only config'
+ local host, port = setup_module(desc,
+ {
+ tls = false,
+ })
+
+ local uri = string.format('http://%s:%d', host, port)
+ check_protocol(uri, 'HTTP works in ' .. desc, true)
+ uri = string.format('https://%s:%d', host, port)
+ check_protocol(uri, 'HTTPS does not work in ' .. desc, false)
+ end
+
+ local function test_https_only()
+ local desc = 'HTTPS-only config'
+ local host, port = setup_module(desc,
+ {
+ tls = true,
+ })
+
+ local uri = string.format('http://%s:%d', host, port)
+ check_protocol(uri, 'HTTP does not work in ' .. desc, false)
+ uri = string.format('https://%s:%d', host, port)
+ check_protocol(uri, 'HTTPS works in ' .. desc, true)
+ end
+
+ local function test_custom_cert()
+ desc = 'config with custom certificate'
+ local host, port = setup_module(desc, {{
+ cert = 'test.crt',
+ key = 'test.key'
+ }})
+
+ uri = string.format('https://%s:%d', host, port)
+ check_protocol(uri, 'HTTPS works for ' .. desc, true)
+ end
+
+ local function test_nonexistent_cert()
+ desc = 'config with non-existing certificate file'
+ boom(http.config, {{
+ cert = '/tmp/surely_nonexistent_cert_1532432095',
+ key = 'test.key'
+ }}, desc)
+ end
+
+ local function test_nonexistent_key()
+ desc = 'config with non-existing key file'
+ boom(http.config, {{
+ cert = 'test.crt',
+ key = '/tmp/surely_nonexistent_cert_1532432095'
+ }}, desc)
+ end
+
+ local function test_missing_key_param()
+ desc = 'config with missing key= param'
+ boom(http.config, {{
+ cert = 'test.crt'
+ }}, desc)
+ end
+
+ local function test_broken_cert()
+ desc = 'config with broken file in cert= param'
+ boom(http.config, {{
+ cert = 'broken.crt',
+ key = 'test.key'
+ }}, desc)
+ end
+
+ local function test_broken_key()
+ desc = 'config with broken file in key= param'
+ boom(http.config, {{
+ cert = 'test.crt',
+ key = 'broken.key'
+ }}, desc)
+ end
+
+ local function test_certificate_chain()
+ local desc = 'config with certificate chain (with intermediate CA cert)'
+ local host, port = setup_module(desc,
+ {
+ tls = true,
+ cert = 'chain.crt',
+ key = 'test.key',
+ })
+ local uri = string.format('https://%s:%d', host, port)
+ local req = request.new_from_uri(uri)
+ req.ctx = openssl_ctx.new()
+
+ if not req.ctx.setCertificateChain then
+ pass(string.format('SKIP (luaossl <= 20181207) - %s', desc))
+ else
+ local store = req.ctx:getStore()
+ store:add('ca.crt')
+ req.ctx:setVerify(openssl_ctx.VERIFY_PEER)
+
+ local headers = assert(req:go(16))
+ local code = tonumber(headers:get(':status'))
+ same(code, 200, desc)
+ end
+ end
+
+
+ -- plan tests
+ local tests = {
+ test_defaults,
+ test_http_only,
+ test_https_only,
+ test_custom_cert,
+ test_nonexistent_cert,
+ test_nonexistent_key,
+ test_missing_key_param,
+ test_broken_cert,
+ test_broken_key,
+ test_certificate_chain,
+ }
+
+ return tests
+end
diff --git a/modules/http/trace.rst b/modules/http/trace.rst
new file mode 100644
index 0000000..de6950c
--- /dev/null
+++ b/modules/http/trace.rst
@@ -0,0 +1,43 @@
+.. SPDX-License-Identifier: GPL-3.0-or-later
+
+.. _mod-http-trace:
+
+Debugging a single request
+==========================
+
+Using query policies
+--------------------
+
+Query policies :any:`policy.DEBUG_ALWAYS`, :any:`policy.DEBUG_CACHE_MISS` or
+:any:`policy.DEBUG_IF` can be used to enable debug-level logging for selected
+subdomains or queries matching specific conditions. Please refer to
+:ref:`mod-policy-logging` for more information.
+
+Using HTTP module
+-----------------
+
+The :ref:`http module <mod-http>` provides ``/trace`` endpoint which allows to trace various
+aspects of the request execution. The basic mode allows you to resolve a query
+and trace debug-level logs for it (and messages received):
+
+.. code-block:: bash
+
+ $ curl https://localhost:8453/trace/e.root-servers.net
+ [ 8138] [iter] 'e.root-servers.net.' type 'A' created outbound query, parent id 0
+ [ 8138] [ rc ] => rank: 020, lowest 020, e.root-servers.net. A
+ [ 8138] [ rc ] => satisfied from cache
+ [ 8138] [iter] <= answer received:
+ ;; ->>HEADER<<- opcode: QUERY; status: NOERROR; id: 8138
+ ;; Flags: qr aa QUERY: 1; ANSWER: 0; AUTHORITY: 0; ADDITIONAL: 0
+
+ ;; QUESTION SECTION
+ e.root-servers.net. A
+
+ ;; ANSWER SECTION
+ e.root-servers.net. 3556353 A 192.203.230.10
+
+ [ 8138] [iter] <= rcode: NOERROR
+ [ 8138] [resl] finished: 4, queries: 1, mempool: 81952 B
+
+See chapter about :ref:`mod-http` for further instructions how to load ``webmgmt``
+endpoint into HTTP module, it is a prerequisite for using ``/trace``.
diff --git a/modules/meson.build b/modules/meson.build
new file mode 100644
index 0000000..c5360c8
--- /dev/null
+++ b/modules/meson.build
@@ -0,0 +1,59 @@
+# modules
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+lua_mod_src = [ # add lua modules without separate meson.build
+ files('detect_time_jump/detect_time_jump.lua'),
+ files('detect_time_skew/detect_time_skew.lua'),
+ files('dns64/dns64.lua'),
+ files('etcd/etcd.lua'),
+ files('graphite/graphite.lua'),
+ files('predict/predict.lua'),
+ files('prefill/prefill.lua'),
+ files('priming/priming.lua'),
+ files('rebinding/rebinding.lua'),
+ files('renumber/renumber.lua'),
+ files('serve_stale/serve_stale.lua'),
+ files('ta_sentinel/ta_sentinel.lua'),
+ files('ta_signal_query/ta_signal_query.lua'),
+ files('watchdog/watchdog.lua'),
+ files('workarounds/workarounds.lua'),
+]
+
+# When adding tests, prefer to use module's meson.build (if it exists).
+config_tests += [
+ ['dns64', files('dns64/dns64.test.lua')],
+ ['prefill', files('prefill/prefill.test/prefill.test.lua')],
+ ['renumber', files('renumber/renumber.test.lua')],
+ ['ta_update', files('ta_update/ta_update.test.lua'), ['snowflake']],
+]
+
+integr_tests += [
+ ['rebinding', meson.current_source_dir() / 'rebinding' / 'test.integr'],
+ ['serve_stale', meson.current_source_dir() / 'serve_stale' / 'test.integr'],
+]
+
+
+# handle more complex C/LUA modules separately
+subdir('bogus_log')
+# cookies module is not currently used
+subdir('daf')
+subdir('dnstap')
+subdir('edns_keepalive')
+subdir('experimental_dot_auth')
+subdir('extended_error')
+subdir('hints')
+subdir('http')
+subdir('nsid')
+subdir('policy')
+subdir('refuse_nord')
+subdir('stats')
+subdir('ta_update')
+subdir('view')
+
+# install lua modules
+foreach mod : lua_mod_src
+ install_data(
+ mod,
+ install_dir: modules_dir,
+ )
+endforeach
diff --git a/modules/nsid/.packaging/test.config b/modules/nsid/.packaging/test.config
new file mode 100644
index 0000000..de54cce
--- /dev/null
+++ b/modules/nsid/.packaging/test.config
@@ -0,0 +1,4 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+modules.load('nsid')
+assert(nsid)
+quit()
diff --git a/modules/nsid/README.rst b/modules/nsid/README.rst
new file mode 100644
index 0000000..3d0bf4e
--- /dev/null
+++ b/modules/nsid/README.rst
@@ -0,0 +1,35 @@
+.. SPDX-License-Identifier: GPL-3.0-or-later
+
+.. _mod-nsid:
+
+Name Server Identifier (NSID)
+=============================
+
+Module ``nsid`` provides server-side support for :rfc:`5001`
+which allows DNS clients to request resolver to send back its NSID
+along with the reply to a DNS request.
+This is useful for debugging larger resolver farms
+(e.g. when using :ref:`systemd-multiple-instances`, anycast or load balancers).
+
+NSID value can be configured in the resolver's configuration file:
+
+.. code-block:: lua
+
+ modules.load('nsid')
+ nsid.name('instance 1')
+
+.. tip:: When dealing with Knot Resolver running in `multiple instances`
+ managed with systemd see :ref:`instance-specific-configuration`.
+
+You can also obtain configured NSID value:
+
+.. code-block:: lua
+
+ > nsid.name()
+ 'instance 1'
+
+The module can be disabled at run-time:
+
+.. code-block:: lua
+
+ modules.unload('nsid')
diff --git a/modules/nsid/meson.build b/modules/nsid/meson.build
new file mode 100644
index 0000000..b0fcd9e
--- /dev/null
+++ b/modules/nsid/meson.build
@@ -0,0 +1,24 @@
+# C module: nsid
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+nsid_src = files([
+ 'nsid.c',
+])
+c_src_lint += nsid_src
+
+nsid_mod = shared_module(
+ 'nsid',
+ nsid_src,
+ dependencies: [
+ libknot,
+ luajit_inc,
+ ],
+ include_directories: mod_inc_dir,
+ name_prefix: '',
+ install: true,
+ install_dir: modules_dir,
+)
+
+config_tests += [
+ ['nsid', files('nsid.test.lua')],
+]
diff --git a/modules/nsid/nsid.c b/modules/nsid/nsid.c
new file mode 100644
index 0000000..a67dcdb
--- /dev/null
+++ b/modules/nsid/nsid.c
@@ -0,0 +1,114 @@
+/* Copyright (C) Knot Resolver contributors
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ * This module provides NSID support according to RFC 5001. */
+
+#include <libknot/packet/pkt.h>
+#include <contrib/cleanup.h>
+#include <ccan/json/json.h>
+#include <lauxlib.h>
+
+#include "daemon/engine.h"
+#include "lib/layer.h"
+
+struct nsid_config {
+ uint8_t *local_nsid;
+ size_t local_nsid_len;
+};
+
+static int nsid_finalize(kr_layer_t *ctx) {
+ const struct kr_module *module = ctx->api->data;
+ const struct nsid_config *config = module->data;
+ struct kr_request *req = ctx->req;
+
+ /* no local NSID configured, do nothing */
+ if (config->local_nsid == NULL)
+ return ctx->state;
+
+ const knot_rrset_t *src_opt = req->qsource.packet->opt_rr;
+ /* no EDNS in request, do nothing */
+ if (src_opt == NULL)
+ return ctx->state;
+
+ const uint8_t *req_nsid = knot_edns_get_option(src_opt, KNOT_EDNS_OPTION_NSID, NULL);
+ /* NSID option must be explicitly requested */
+ if (req_nsid == NULL)
+ return ctx->state;
+
+ /* Check violation of https://tools.ietf.org/html/rfc5001#section-2.1:
+ * The resolver MUST NOT include any NSID payload data in the query */
+ if (knot_edns_opt_get_length(req_nsid) != 0)
+ kr_log_debug(NSID, "[%05u. ] FORMERR: NSID option in query "
+ "must not contain payload, continuing\n", req->uid);
+ /* FIXME: actually change RCODE in answer to FORMERR? */
+
+ /* Sanity check, answer should have EDNS as well but who knows ... */
+ if (kr_fails_assert(req->answer->opt_rr))
+ return ctx->state;
+
+ if (knot_edns_add_option(req->answer->opt_rr, KNOT_EDNS_OPTION_NSID,
+ config->local_nsid_len, config->local_nsid,
+ &req->pool) != KNOT_EOK) {
+ /* something went wrong and there is no way to salvage content of OPT RRset */
+ kr_log_debug(NSID, "[%05u. ] unable to add NSID option\n", req->uid);
+ knot_rrset_clear(req->answer->opt_rr, &req->pool);
+ }
+
+ return ctx->state;
+}
+
+static char* nsid_name(void *env, struct kr_module *module, const char *args)
+{
+ struct engine *engine = env;
+ struct nsid_config *config = module->data;
+ if (args) { /* set */
+ /* API is not binary safe, we need to fix this one day */
+ uint8_t *arg_copy = (uint8_t *)strdup(args);
+ if (arg_copy == NULL)
+ luaL_error(engine->L, "[nsid] error while allocating new NSID value\n");
+ free(config->local_nsid);
+ config->local_nsid = arg_copy;
+ config->local_nsid_len = strlen(args);
+ }
+
+ /* get */
+ if (config->local_nsid != NULL)
+ return json_encode_string((char *)config->local_nsid);
+ else
+ return NULL;
+}
+
+KR_EXPORT
+int nsid_init(struct kr_module *module) {
+ static kr_layer_api_t layer = {
+ .answer_finalize = &nsid_finalize,
+ };
+ layer.data = module;
+ module->layer = &layer;
+
+ static const struct kr_prop props[] = {
+ { &nsid_name, "name", "Get or set local NSID value" },
+ { NULL, NULL, NULL }
+ };
+ module->props = props;
+
+ struct nsid_config *config = calloc(1, sizeof(struct nsid_config));
+ if (config == NULL)
+ return kr_error(ENOMEM);
+
+ module->data = config;
+ return kr_ok();
+}
+
+KR_EXPORT
+int nsid_deinit(struct kr_module *module) {
+ struct nsid_config *config = module->data;
+ if (config != NULL) {
+ free(config->local_nsid);
+ free(config);
+ module->data = NULL;
+ }
+ return kr_ok();
+}
+
+KR_MODULE_EXPORT(nsid)
diff --git a/modules/nsid/nsid.test.lua b/modules/nsid/nsid.test.lua
new file mode 100644
index 0000000..8e5d4f9
--- /dev/null
+++ b/modules/nsid/nsid.test.lua
@@ -0,0 +1,22 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+-- disable networking so we can get SERVFAIL immediately
+net.ipv4 = false
+net.ipv6 = false
+
+-- test for nsid.name() interface
+local function test_nsid_name()
+ if nsid then
+ modules.unload('nsid')
+ end
+ modules.load('nsid')
+ same(nsid.name(), nil, 'NSID modes not provide default NSID value')
+ same(nsid.name('123456'), '123456', 'NSID value can be changed')
+ same(nsid.name(), '123456', 'NSID module remembers configured NSID value')
+ modules.unload('nsid')
+ modules.load('nsid')
+ same(nsid.name(), nil, 'NSID module reload removes configured value')
+end
+
+return {
+ test_nsid_name,
+}
diff --git a/modules/policy/.packaging/test.config b/modules/policy/.packaging/test.config
new file mode 100644
index 0000000..60c9ddc
--- /dev/null
+++ b/modules/policy/.packaging/test.config
@@ -0,0 +1,4 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+modules.load('policy')
+assert(policy)
+quit()
diff --git a/modules/policy/README.rst b/modules/policy/README.rst
new file mode 100644
index 0000000..202aaba
--- /dev/null
+++ b/modules/policy/README.rst
@@ -0,0 +1,774 @@
+.. SPDX-License-Identifier: GPL-3.0-or-later
+
+.. default-domain:: py
+.. module:: policy
+
+.. _mod-policy:
+
+
+Query policies
+==============
+
+This module can block, rewrite, or alter inbound queries based on user-defined policies. It does not affect queries generated by the resolver itself, e.g. when following CNAME chains etc.
+
+Each policy *rule* has two parts: a *filter* and an *action*. A *filter* selects which queries will be affected by the policy, and *action* which modifies queries matching the associated filter.
+
+Typically a rule is defined as follows: ``filter(action(action parameters), filter parameters)``. For example, a filter can be ``suffix`` which matches queries whose suffix part is in specified set, and one of possible actions is :any:`policy.DENY`, which denies resolution. These are combined together into ``policy.suffix(policy.DENY, {todname('badguy.example.')})``. The rule is effective when it is added into rule table using ``policy.add()``, please see examples below.
+
+This module is enabled by default because it implements mandatory :rfc:`6761` logic.
+When no rule applies to a query, built-in rules for `special-use <https://www.iana.org/assignments/special-use-domain-names/special-use-domain-names.xhtml>`_ and `locally-served <http://www.iana.org/assignments/locally-served-dns-zones>`_ domain names are applied.
+These rules can be overridden by action :any:`policy.PASS`. For debugging purposes you can also add ``modules.unload('policy')`` to your config to unload the module.
+
+
+Filters
+-------
+A *filter* selects which queries will be affected by specified Actions_. There are several policy filters available in the ``policy.`` table:
+
+.. function:: all(action)
+
+ Always applies the action.
+
+.. function:: pattern(action, pattern)
+
+ Applies the action if query name matches a `Lua regular expression <http://lua-users.org/wiki/PatternsTutorial>`_.
+
+.. function:: suffix(action, suffix_table)
+
+ Applies the action if query name suffix matches one of suffixes in the table (useful for "is domain in zone" rules).
+
+ .. code-block:: lua
+
+ policy.add(policy.suffix(policy.DENY, policy.todnames({'example.com', 'example.net'})))
+
+.. note:: For speed this filter requires domain names in DNS wire format, not textual representation, so each label in the name must be prefixed with its length. Always use convenience function :func:`policy.todnames` for automatic conversion from strings! For example:
+
+.. _IDN:
+
+.. note:: Non-ASCII is not supported.
+
+ Knot Resolver does not provide any convenience support for IDN.
+ Therefore everywhere (all configuration, logs, RPZ files) you need to deal with the
+ `xn\-\- forms <https://en.wikipedia.org/wiki/Internationalized_domain_name#Example_of_IDNA_encoding>`_
+ of domain name labels, instead of directly using unicode characters.
+
+.. function:: domains(action, domain_table)
+
+ Like :func:`policy.suffix` match, but the queried name must match exactly, not just its suffix.
+
+.. function:: suffix_common(action, suffix_table[, common_suffix])
+
+ :param action: action if the pattern matches query name
+ :param suffix_table: table of valid suffixes
+ :param common_suffix: common suffix of entries in suffix_table
+
+ Like :func:`policy.suffix` match, but you can also provide a common suffix of all matches for faster processing (nil otherwise).
+ This function is faster for small suffix tables (in the order of "hundreds").
+
+.. :noindex: function:: rpz(default_action, path, [watch])
+
+ Implements a subset of `Response Policy Zone` (RPZ_) stored in zonefile format. See below for details: :func:`policy.rpz`.
+
+It is also possible to define custom filter function with any name.
+
+.. function:: custom_filter(state, query)
+
+ :param state: Request processing state :c:type:`kr_layer_state`, typically not used by filter function.
+ :param query: Incoming DNS query as :c:type:`kr_query` structure.
+ :return: An `action <#actions>`_ function or ``nil`` if filter did not match.
+
+ Typically filter function is generated by another function, which allows easy parametrization - this technique is called `closure <https://www.lua.org/pil/6.1.html>`_. An practical example of such filter generator is:
+
+.. code-block:: lua
+
+ function match_query_type(action, target_qtype)
+ return function (state, query)
+ if query.stype == target_qtype then
+ -- filter matched the query, return action function
+ return action
+ else
+ -- filter did not match, continue with next filter
+ return nil
+ end
+ end
+ end
+
+This custom filter can be used as any other built-in filter.
+For example this applies our custom filter and executes action :any:`policy.DENY` on all queries of type `HINFO`:
+
+.. code-block:: lua
+
+ -- custom filter which matches HINFO queries, action is policy.DENY
+ policy.add(match_query_type(policy.DENY, kres.type.HINFO))
+
+
+.. _mod-policy-actions:
+
+Actions
+-------
+An *action* is a function which modifies DNS request, and is either of type *chain* or *non-chain*:
+
+ * `Non-chain actions`_ modify state of the request and stop rule processing. An example of such action is :ref:`forwarding`.
+ * `Chain actions`_ modify state of the request and allow other rules to evaluate and act on the same request. One such example is :func:`policy.MIRROR`.
+
+Non-chain actions
+^^^^^^^^^^^^^^^^^
+
+Following actions stop the policy matching on the query, i.e. other rules are not evaluated once rule with following actions matches:
+
+.. py:attribute:: PASS
+
+ Let the query pass through; it's useful to make exceptions before wider rules. For example:
+
+ More specific whitelist rule must precede generic blacklist rule:
+
+ .. code-block:: lua
+
+ -- Whitelist 'good.example.com'
+ policy.add(policy.pattern(policy.PASS, todname('good.example.com.')))
+ -- Block all names below example.com
+ policy.add(policy.suffix(policy.DENY, {todname('example.com.')}))
+
+.. py:attribute:: DENY
+
+ Deny existence of names matching filter, i.e. reply NXDOMAIN authoritatively.
+
+.. function:: DENY_MSG(message, [extended_error=kres.extended_error.BLOCKED])
+
+ Deny existence of a given domain and add explanatory message. NXDOMAIN reply
+ contains an additional explanatory message as TXT record in the additional
+ section.
+
+ You may override the extended DNS error to provide the user with more
+ information. By default, ``BLOCKED`` is returned to indicate the domain is
+ blocked due to the internal policy of the operator. Other suitable error
+ codes are ``CENSORED`` (for externally imposed policy reasons) or
+ ``FILTERED`` (for blocking requested by the client). For more information,
+ please refer to :rfc:`8914`.
+
+.. py:attribute:: DROP
+
+ Terminate query resolution and return SERVFAIL to the requestor.
+
+.. py:attribute:: REFUSE
+
+ Terminate query resolution and return REFUSED to the requestor.
+
+.. py:attribute:: NO_ANSWER
+
+ Terminate query resolution and do not return any answer to the requestor.
+
+ .. warning:: During normal operation, an answer should always be returned.
+ Deliberate query drops are indistinguishable from packet loss and may
+ cause problems as described in :rfc:`8906`. Only use :any:`NO_ANSWER`
+ on very specific occasions, e.g. as a defense mechanism during an attack,
+ and prefer other actions (e.g. :any:`DROP` or :any:`REFUSE`) for normal
+ operation.
+
+.. py:attribute:: TC
+
+ Force requestor to use TCP. It sets truncated bit (*TC*) in response to true if the request came through UDP, which will force standard-compliant clients to retry the request over TCP.
+
+.. function:: REROUTE({subnet = target, ...})
+
+ Reroute IP addresses in response matching given subnet to given target, e.g. ``{['192.0.2.0/24'] = '127.0.0.0'}`` will rewrite '192.0.2.55' to '127.0.0.55', see :ref:`renumber module <mod-renumber>` for more information. See :func:`policy.add` and do not forget to specify that this is *postrule*. Quick example:
+
+ .. code-block:: lua
+
+ -- this policy is enforced on answers
+ -- therefore we have to use 'postrule'
+ -- (the "true" at the end of policy.add)
+ policy.add(policy.all(policy.REROUTE({['192.0.2.0/24'] = '127.0.0.0'})), true)
+
+.. function:: ANSWER({ type = { rdata=data, [ttl=1] } }, [nodata=false])
+
+ Overwrite Resource Records in responses with specified values.
+
+ * type
+ - RR type to be replaced, e.g. ``[kres.type.A]`` or `numeric value <https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml#dns-parameters-4>`_.
+ * rdata
+ - RR data in DNS wire format, i.e. binary form specific for given RR type. Set of multiple RRs can be specified as table ``{ rdata1, rdata2, ... }``. Use helper function :func:`kres.str2ip` to generate wire format for A and AAAA records. Wire format for other record types can be generated with :func:`kres.parse_rdata`.
+ * ttl
+ - TTL in seconds. Default: 1 second.
+ * nodata
+ - If type requested by client is not configured in this policy:
+
+ - ``true``: Return empty answer (`NODATA`).
+ - ``false``: Ignore this policy and continue processing other rules.
+
+ Default: ``false``.
+
+ .. code-block:: lua
+
+ -- policy to change IPv4 address and TTL for example.com
+ policy.add(
+ policy.domains(
+ policy.ANSWER(
+ { [kres.type.A] = { rdata=kres.str2ip('192.0.2.7'), ttl=300 } }
+ ), { todname('example.com') }))
+ -- policy to generate two TXT records (specified in binary format) for example.net
+ policy.add(
+ policy.domains(
+ policy.ANSWER(
+ { [kres.type.TXT] = { rdata={'\005first', '\006second'}, ttl=5 } }
+ ), { todname('example.net') }))
+
+
+ .. function:: kres.parse_rdata({str, ...})
+
+ Parse string representation of RTYPE and RDATA into RDATA wire format. Expects
+ a table of string(s) and returns a table of wire data.
+
+ .. code-block:: lua
+
+ -- create wire format RDATA that can be passed to policy.ANSWER
+ kres.parse_rdata({'SVCB 1 resolver.example. alpn=dot'})
+ kres.parse_rdata({
+ 'SVCB 1 resolver.example. alpn=dot ipv4hint=192.0.2.1 ipv6hint=2001:db8::1',
+ 'SVCB 2 resolver.example. mandatory=key65380 alpn=h2 key65380=/dns-query{?dns}',
+ })
+
+More complex non-chain actions are described in their own chapters, namely:
+
+ * :ref:`forwarding`
+ * `Response Policy Zones`_
+
+Chain actions
+^^^^^^^^^^^^^
+
+Following actions act on request and then processing continue until first non-chain action (specified in the previous section) is triggered:
+
+.. function:: MIRROR(ip_address)
+
+ Send copy of incoming DNS queries to a given IP address using DNS-over-UDP and continue resolving them as usual. This is useful for sanity testing new versions of DNS resolvers.
+
+ .. code-block:: lua
+
+ policy.add(policy.all(policy.MIRROR('127.0.0.2')))
+
+.. function:: FLAGS(set, clear)
+
+ Set and/or clear some flags for the query. There can be multiple flags to set/clear. You can just pass a single flag name (string) or a set of names. Flag names correspond to :c:type:`kr_qflags` structure. Use only if you know what you are doing.
+
+
+.. _mod-policy-logging:
+
+Actions for extra logging
+^^^^^^^^^^^^^^^^^^^^^^^^^
+
+These are also "chain" actions, i.e. they don't stop processing the policy rule list.
+Similarly to other actions, they apply during whole processing of the client's request,
+i.e. including any sub-queries.
+
+The log lines from these policy actions are tagged by extra ``[reqdbg]`` prefix,
+and they are produced regardless of your :func:`log_level()` setting.
+They are marked as ``debug`` level, so e.g. with journalctl command you can use ``-p info`` to skip them.
+
+.. warning:: Beware of producing too much logs.
+
+ These actions are not suitable for use on a large fraction of resolver's requests.
+ The extra logs have significant performance impact and might also overload your logging system
+ (or get rate-limited by it).
+ You can use `Filters`_ to further limit on which requests this happens.
+
+.. py:attribute:: DEBUG_ALWAYS
+
+ Print debug-level logging for this request.
+ That also includes messages from client (:any:`REQTRACE`), upstream servers (:any:`QTRACE`), and stats about interesting records at the end.
+
+ .. code-block:: lua
+
+ -- debug requests that ask for flaky.example.net or below
+ policy.add(policy.suffix(policy.DEBUG_ALWAYS,
+ policy.todnames({'flaky.example.net'})))
+
+.. py:attribute:: DEBUG_CACHE_MISS
+
+ Same as :any:`DEBUG_ALWAYS` but only if the request required information which was not available locally, i.e. requests which forced resolver to ask upstream server(s).
+ Intended usage is for debugging problems with remote servers.
+
+.. py:function:: DEBUG_IF(test_function)
+
+ :param test_function: Function with single argument of type :c:type:`kr_request` which returns ``true`` if debug logs for that request should be generated and ``false`` otherwise.
+
+ Same as :any:`DEBUG_ALWAYS` but only logs if the test_function says so.
+
+ .. note:: ``test_function`` is evaluated only when request is finished.
+ As a result all debug logs this request must be collected,
+ and at the end they get either printed or thrown away.
+
+ Example usage which gathers verbose logs for all requests in subtree ``dnssec-failed.org.`` and prints debug logs for those finishing in a different state than ``kres.DONE`` (most importantly ``kres.FAIL``, see :c:type:`kr_layer_state`).
+
+ .. code-block:: lua
+
+ policy.add(policy.suffix(
+ policy.DEBUG_IF(function(req)
+ return (req.state ~= kres.DONE)
+ end),
+ policy.todnames({'dnssec-failed.org.'})))
+
+.. py:attribute:: QTRACE
+
+ Pretty-print DNS responses from upstream servers (or cache) into logs.
+ It's useful for debugging weird DNS servers.
+
+ If you do not use ``QTRACE`` in combination with ``DEBUG*``,
+ you additionally need either ``log_groups({'iterat'})`` (possibly with other groups)
+ or ``log_level('debug')`` to see the output in logs.
+
+.. py:attribute:: REQTRACE
+
+ Pretty-print DNS requests from clients into the verbose log. It's useful for debugging weird DNS clients.
+ It makes most sense together with :ref:`mod-view` (enabling per-client)
+ and probably with verbose logging those request (e.g. use :any:`DEBUG_ALWAYS` instead).
+
+.. py:attribute:: IPTRACE
+
+ Log how the request arrived.
+ Most notably, this includes the client's IP address, so beware of privacy implications.
+
+ .. code-block:: lua
+
+ -- example usage in configuration
+ policy.add(policy.all(policy.IPTRACE))
+ -- you might want to combine it with some other logs, e.g.
+ policy.add(policy.all(policy.DEBUG_ALWAYS))
+
+ .. code-block:: text
+
+ -- example log lines from IPTRACE:
+ [reqdbg][policy][57517.00] request packet arrived from ::1#37931 to ::1#00853 (TCP + TLS)
+ [reqdbg][policy][65538.00] request packet arrived internally
+
+
+Custom actions
+^^^^^^^^^^^^^^
+
+.. function:: custom_action(state, request)
+
+ :param state: Request processing state :c:type:`kr_layer_state`.
+ :param request: Current DNS request as :c:type:`kr_request` structure.
+ :return: Returning a new :c:type:`kr_layer_state` prevents evaluating other policy rules. Returning ``nil`` creates a `chain action <#actions>`_ and allows to continue evaluating other rules.
+
+ This is real example of an action function:
+
+.. code-block:: lua
+
+ -- Custom action which generates fake A record
+ local ffi = require('ffi')
+ local function fake_A_record(state, req)
+ local answer = req:ensure_answer()
+ if answer == nil then return nil end
+ local qry = req:current()
+ if qry.stype ~= kres.type.A then
+ return state
+ end
+ ffi.C.kr_pkt_make_auth_header(answer)
+ answer:rcode(kres.rcode.NOERROR)
+ answer:begin(kres.section.ANSWER)
+ answer:put(qry.sname, 900, answer:qclass(), kres.type.A, '\192\168\1\3')
+ return kres.DONE
+ end
+
+This custom action can be used as any other built-in action.
+For example this applies our *fake A record action* and executes it on all queries in subtree ``example.net``:
+
+.. code-block:: lua
+
+ policy.add(policy.suffix(fake_A_record, policy.todnames({'example.net'})))
+
+The action function can implement arbitrary logic so it is possible to implement complex heuristics, e.g. to deflect `Slow drip DNS attacks <https://secure64.com/water-torture-slow-drip-dns-ddos-attack>`_ or gray-list resolution of misbehaving zones.
+
+.. warning:: The policy module currently only looks at whole DNS requests. The rules won't be re-applied e.g. when following CNAMEs.
+
+.. _forwarding:
+
+Forwarding
+----------
+
+Forwarding action alters behavior for cache-miss events. If an information is missing in the local cache the resolver will *forward* the query to *another DNS resolver* for resolution (instead of contacting authoritative servers directly). DNS answers from the remote resolver are then processed locally and sent back to the original client.
+
+Actions :func:`policy.FORWARD`, :func:`policy.TLS_FORWARD` and :func:`policy.STUB` accept up to four IP addresses at once and the resolver will automatically select IP address which statistically responds the fastest.
+
+.. function:: FORWARD(ip_address)
+ FORWARD({ ip_address, [ip_address, ...] })
+
+ Forward cache-miss queries to specified IP addresses (without encryption), DNSSEC validate received answers and cache them. Target IP addresses are expected to be DNS resolvers.
+
+ .. code-block:: lua
+
+ -- Forward all queries to public resolvers https://www.nic.cz/odvr
+ policy.add(policy.all(
+ policy.FORWARD(
+ {'2001:148f:fffe::1', '2001:148f:ffff::1',
+ '185.43.135.1', '193.14.47.1'})))
+
+ A variant which uses encrypted DNS-over-TLS transport is called :func:`policy.TLS_FORWARD`, please see section :ref:`tls-forwarding`.
+
+.. function:: STUB(ip_address)
+ STUB({ ip_address, [ip_address, ...] })
+
+ Similar to :func:`policy.FORWARD` but *without* attempting DNSSEC validation.
+ Each request may be either answered from cache or simply sent to one of the IPs with proxying back the answer.
+
+ This mode does not support encryption and should be used only for `Replacing part of the DNS tree`_.
+ Use :func:`policy.FORWARD` mode if possible.
+
+ .. code-block:: lua
+
+ -- Answers for reverse queries about the 192.168.1.0/24 subnet
+ -- are to be obtained from IP address 192.0.2.1 port 5353
+ -- This disables DNSSEC validation!
+ policy.add(policy.suffix(
+ policy.STUB('192.0.2.1@5353'),
+ {todname('1.168.192.in-addr.arpa')}))
+
+.. note:: By default, forwarding targets must support
+ `EDNS <https://en.wikipedia.org/wiki/Extension_mechanisms_for_DNS>`_ and
+ `0x20 randomization <https://tools.ietf.org/html/draft-vixie-dnsext-dns0x20-00>`_.
+ See example in `Replacing part of the DNS tree`_.
+
+.. warning::
+ Limiting forwarding actions by filters (e.g. :func:`policy.suffix`) may have unexpected consequences.
+ Notably, forwarders can inject *any* records into your cache
+ even if you "restrict" them to an insignificant DNS subtree --
+ except in cases where DNSSEC validation applies, of course.
+
+ The behavior is probably best understood through the fact
+ that filters and actions are completely decoupled.
+ The forwarding actions have no clue about why they were executed,
+ e.g. that the user wanted to restrict the forwarder only to some subtree.
+ The action just selects some set of forwarders to process this whole request from the client,
+ and during that processing it might need some other "sub-queries" (e.g. for validation).
+ Some of those might not've passed the intended filter,
+ but policy rule-set only applies once per client's request.
+
+.. _tls-forwarding:
+
+Forwarding over TLS protocol (DNS-over-TLS)
+-------------------------------------------
+.. function:: TLS_FORWARD( { {ip_address, authentication}, [...] } )
+
+ Same as :func:`policy.FORWARD` but send query over DNS-over-TLS protocol (encrypted).
+ Each target IP address needs explicit configuration how to validate
+ TLS certificate so each IP address is configured by pair:
+ ``{ip_address, authentication}``. See sections below for more details.
+
+
+Policy :func:`policy.TLS_FORWARD` allows you to forward queries using `Transport Layer Security`_ protocol, which hides the content of your queries from an attacker observing the network traffic. Further details about this protocol can be found in :rfc:`7858` and `IETF draft dprive-dtls-and-tls-profiles`_.
+
+Queries affected by :func:`policy.TLS_FORWARD` will always be resolved over TLS connection. Knot Resolver does not implement fallback to non-TLS connection, so if TLS connection cannot be established or authenticated according to the configuration, the resolution will fail.
+
+To test this feature you need to either :ref:`configure Knot Resolver as DNS-over-TLS server <tls-server-config>`, or pick some public DNS-over-TLS server. Please see `DNS Privacy Project`_ homepage for list of public servers.
+
+.. note:: Some public DNS-over-TLS providers may apply rate-limiting which
+ makes their service incompatible with Knot Resolver's TLS forwarding.
+ Notably, `Google Public DNS
+ <https://developers.google.com/speed/public-dns/docs/dns-over-tls>`_ doesn't
+ work as of 2019-07-10.
+
+When multiple servers are specified, the one with the lowest round-trip time is used.
+
+CA+hostname authentication
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+Traditional PKI authentication requires server to present certificate with specified hostname, which is issued by one of trusted CAs. Example policy is:
+
+.. code-block:: lua
+
+ policy.TLS_FORWARD({
+ {'2001:DB8::d0c', hostname='res.example.com'}})
+
+- ``hostname`` must be a valid domain name matching server's certificate. It will also be sent to the server as SNI_.
+- ``ca_file`` optionally contains a path to a CA certificate (or certificate bundle) in `PEM format`_.
+ If you omit that, the system CA certificate store will be used instead (usually sufficient).
+ A list of paths is also accepted, but all of them must be valid PEMs.
+
+Key-pinned authentication
+^^^^^^^^^^^^^^^^^^^^^^^^^
+Instead of CAs, you can specify hashes of accepted certificates in ``pin_sha256``.
+They are in the usual format -- base64 from sha256.
+You may still specify ``hostname`` if you want SNI_ to be sent.
+
+.. _tls-examples:
+
+TLS Examples
+^^^^^^^^^^^^
+
+.. code-block:: lua
+
+ modules = { 'policy' }
+ -- forward all queries over TLS to the specified server
+ policy.add(policy.all(policy.TLS_FORWARD({{'192.0.2.1', pin_sha256='YQ=='}})))
+ -- for brevity, other TLS examples omit policy.add(policy.all())
+ -- single server authenticated using its certificate pin_sha256
+ policy.TLS_FORWARD({{'192.0.2.1', pin_sha256='YQ=='}}) -- pin_sha256 is base64-encoded
+ -- single server authenticated using hostname and system-wide CA certificates
+ policy.TLS_FORWARD({{'192.0.2.1', hostname='res.example.com'}})
+ -- single server using non-standard port
+ policy.TLS_FORWARD({{'192.0.2.1@443', pin_sha256='YQ=='}}) -- use @ or # to specify port
+ -- single server with multiple valid pins (e.g. anycast)
+ policy.TLS_FORWARD({{'192.0.2.1', pin_sha256={'YQ==', 'Wg=='}})
+ -- multiple servers, each with own authenticator
+ policy.TLS_FORWARD({ -- please note that { here starts list of servers
+ {'192.0.2.1', pin_sha256='Wg=='},
+ -- server must present certificate issued by specified CA and hostname must match
+ {'2001:DB8::d0c', hostname='res.example.com', ca_file='/etc/knot-resolver/tlsca.crt'}
+ })
+
+Forwarding to multiple targets
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+With the use of :func:`policy.slice` function, it is possible to split the
+entire DNS namespace into distinct slices. When used in conjunction with
+:func:`policy.TLS_FORWARD`, it's possible to forward different queries to
+different targets.
+
+.. function:: slice(slice_func, action[, action[, ...])
+
+ :param slice_func: slicing function that returns index based on query
+ :param action: action to be performed for the slice
+
+ This function splits the entire domain space into multiple slices (determined
+ by the number of provided ``actions``). A ``slice_func`` is called to determine
+ which slice a query belongs to. The corresponding ``action`` is then executed.
+
+
+.. function:: slice_randomize_psl(seed = os.time() / (3600 * 24 * 7))
+
+ :param seed: seed for random assignment
+
+ The function initializes and returns a slicing function, which
+ deterministically assigns ``query`` to a slice based on the query name.
+
+ It utilizes the `Public Suffix List`_ to ensure domains under the same
+ registrable domain end up in a single slice. (see example below)
+
+ ``seed`` can be used to re-shuffle the slicing algorithm when the slicing
+ function is initialized. By default, the assignment is re-shuffled after one
+ week (when resolver restart / reloads config). To force a stable
+ distribution, pass a fixed value. To re-shuffle on every resolver restart,
+ use ``os.time()``.
+
+ The following example demonstrates a distribution among 3 slices::
+
+ slice 1/3:
+ example.com
+ a.example.com
+ b.example.com
+ x.b.example.com
+ example3.com
+
+ slice 2/3:
+ example2.co.uk
+
+ slice 3/3:
+ example.co.uk
+ a.example.co.uk
+
+These two functions can be used together to forward queries for names
+in different parts of DNS name space to different target servers:
+
+.. code-block:: lua
+
+ policy.add(policy.slice(
+ policy.slice_randomize_psl(),
+ policy.TLS_FORWARD({{'192.0.2.1', hostname='res.example.com'}}),
+ policy.TLS_FORWARD({
+ -- multiple servers can be specified for a single slice
+ -- the one with lowest round-trip time will be used
+ {'193.17.47.1', hostname='odvr.nic.cz'},
+ {'185.43.135.1', hostname='odvr.nic.cz'},
+ })
+ ))
+
+.. note:: The privacy implications of using this feature aren't clear. Since
+ websites often make requests to multiple domains, these might be forwarded
+ to different targets. This could result in decreased privacy (e.g. when the
+ remote targets are both logging or otherwise processing your DNS traffic).
+ The intended use-case is to use this feature with semi-trusted resolvers
+ which claim to do no logging (such as those listed on `dnsprivacy.org
+ <https://dnsprivacy.org/wiki/display/DP/DNS+Privacy+Test+Servers>`_), to
+ decrease the potential exposure of your DNS data to a malicious resolver
+ operator.
+
+.. _dns-graft:
+
+Replacing part of the DNS tree
+------------------------------
+
+Following procedure applies only to domains which have different content
+publicly and internally. For example this applies to "your own" top-level domain
+``example.`` which does not exist in the public (global) DNS namespace.
+
+Dealing with these internal-only domains requires extra configuration because
+DNS was designed as "single namespace" and local modifications like adding
+your own TLD break this assumption.
+
+.. warning:: Use of internal names which are not delegated from the public DNS
+ *is causing technical problems* with caching and DNSSEC validation
+ and generally makes DNS operation more costly.
+ We recommend **against** using these non-delegated names.
+
+To make such internal domain available in your resolver it is necessary to
+*graft* your domain onto the public DNS namespace,
+but *grafting* creates new issues:
+
+These *grafted* domains will be rejected by DNSSEC validation
+because such domains are technically indistinguishable from an spoofing attack
+against the public DNS.
+Therefore, if you trust the remote resolver which hosts the internal-only domain,
+and you trust your link to it, you need to use the :func:`policy.STUB` policy
+instead of :func:`policy.FORWARD` to disable DNSSEC validation for those
+*grafted* domains.
+
+.. code-block:: lua
+ :caption: Example configuration grafting domains onto public DNS namespace
+
+ extraTrees = policy.todnames(
+ {'faketldtest.',
+ 'sld.example.',
+ 'internal.example.com.',
+ '2.0.192.in-addr.arpa.' -- this applies to reverse DNS tree as well
+ })
+ -- Beware: the rule order is important, as policy.STUB is not a chain action.
+ -- Flags: for "dumb" targets disabling EDNS can help (below) as DNSSEC isn't
+ -- validated anyway; in some of those cases adding 'NO_0X20' can also help,
+ -- though it also lowers defenses against off-path attacks on communication
+ -- between the two servers.
+ -- With kresd <= 5.5.3 you also needed 'NO_CACHE' flag to avoid unintentional
+ -- NXDOMAINs that could sometimes happen due to aggressive DNSSEC caching.
+ policy.add(policy.suffix(policy.FLAGS({'NO_EDNS'}), extraTrees))
+ policy.add(policy.suffix(policy.STUB({'2001:db8::1'}), extraTrees))
+
+Response policy zones
+---------------------
+ .. warning::
+
+ There is no published Internet Standard for RPZ_ and implementations vary.
+ At the moment Knot Resolver supports limited subset of RPZ format and deviates
+ from implementation in BIND. Nevertheless it is good enough
+ for blocking large lists of spam or advertising domains.
+
+
+
+ The RPZ file format is basically a DNS zone file with *very special* semantics.
+ For example:
+
+ .. code-block:: none
+
+ ; left hand side ; TTL and class ; right hand side
+ ; encodes RPZ trigger ; ignored ; encodes action
+ ; (i.e. filter)
+ blocked.domain.example 600 IN CNAME . ; block main domain
+ *.blocked.domain.example 600 IN CNAME . ; block subdomains
+
+ The only "trigger" supported in Knot Resolver is query name,
+ i.e. left hand side must be a domain name which triggers the action specified
+ on the right hand side.
+
+ Subset of possible RPZ actions is supported, namely:
+
+ .. csv-table::
+ :header: "RPZ Right Hand Side", "Knot Resolver Action", "BIND Compatibility"
+
+ "``.``", "``action`` is used", "compatible if ``action`` is :any:`policy.DENY`"
+ "``*.``", ":func:`policy.ANSWER`", "yes"
+ "``rpz-passthru.``", ":any:`policy.PASS`", "yes"
+ "``rpz-tcp-only.``", ":any:`policy.TC`", "yes"
+ "``rpz-drop.``", ":any:`policy.DROP`", "no [#]_"
+ "fake A/AAAA", ":func:`policy.ANSWER`", "yes"
+ "fake CNAME", "not supported", "no"
+
+ .. [#] Our :any:`policy.DROP` returns *SERVFAIL* answer (for historical reasons).
+
+
+ .. note::
+
+ To debug which domains are affected by RPZ (or other policy actions), you can enable the ``policy`` log group:
+
+ .. code-block:: lua
+
+ log_groups({'policy'})
+
+ See also :ref:`non-ASCII support note <IDN>`.
+
+
+.. function:: rpz(action, path, [watch = true])
+
+ :param action: the default action for match in the zone; typically you want :any:`policy.DENY`
+ :param path: path to zone file
+ :param watch: boolean, if true, the file will be reloaded on file change
+
+ Enforce RPZ_ rules. This can be used in conjunction with published blocklist feeds.
+ The RPZ_ operation is well described in this `Jan-Piet Mens's post`_,
+ or the `Pro DNS and BIND`_ book.
+
+ For example, we can store the example snippet with domain ``blocked.domain.example``
+ (above) into file ``/etc/knot-resolver/blocklist.rpz`` and configure resolver to
+ answer with *NXDOMAIN* plus the specified additional text to queries for this domain:
+
+ .. code-block:: lua
+
+ policy.add(
+ policy.rpz(policy.DENY_MSG('domain blocked by your resolver operator'),
+ '/etc/knot-resolver/blocklist.rpz',
+ true))
+
+ Resolver will reload RPZ file at run-time if the RPZ file changes.
+ Recommended RPZ update procedure is to store new blocklist in a new file
+ (*newblocklist.rpz*) and then rename the new file to the original file name
+ (*blocklist.rpz*). This avoids problems where resolver might attempt
+ to re-read an incomplete file.
+
+
+
+Additional properties
+---------------------
+
+Most properties (actions, filters) are described above.
+
+.. function:: add(rule, postrule)
+
+ :param rule: added rule, i.e. ``policy.pattern(policy.DENY, '[0-9]+\2cz')``
+ :param postrule: boolean, if true the rule will be evaluated on answer instead of query
+ :return: rule description
+
+ Add a new policy rule that is executed either or queries or answers, depending on the ``postrule`` parameter. You can then use the returned rule description to get information and unique identifier for the rule, as well as match count.
+
+ .. code-block:: lua
+
+ -- mirror all queries, keep handle so we can retrieve information later
+ local rule = policy.add(policy.all(policy.MIRROR('127.0.0.2')))
+ -- we can print statistics about this rule any time later
+ print(string.format('id: %d, matched queries: %d', rule.id, rule.count)
+
+.. function:: del(id)
+
+ :param id: identifier of a given rule returned by :func:`policy.add`
+ :return: boolean ``true`` if rule was deleted, ``false`` otherwise
+
+ Remove a rule from policy list.
+
+.. function:: todnames({name, ...})
+
+ :param: names table of domain names in textual format
+
+ Returns table of domain names in wire format converted from strings.
+
+ .. code-block:: lua
+
+ -- Convert single name
+ assert(todname('example.com') == '\7example\3com\0')
+ -- Convert table of names
+ policy.todnames({'example.com', 'me.cz'})
+ { '\7example\3com\0', '\2me\2cz\0' }
+
+
+.. _RPZ: https://dnsrpz.info/
+.. _`PEM format`: https://en.wikipedia.org/wiki/Privacy-enhanced_Electronic_Mail
+.. _`Pro DNS and BIND`: http://www.zytrax.com/books/dns/ch7/rpz.html
+.. _`Jan-Piet Mens's post`: http://jpmens.net/2011/04/26/how-to-configure-your-bind-resolvers-to-lie-using-response-policy-zones-rpz/
+.. _`Transport Layer Security`: https://en.wikipedia.org/wiki/Transport_Layer_Security
+.. _`DNS Privacy Project`: https://dnsprivacy.org/
+.. _`IETF draft dprive-dtls-and-tls-profiles`: https://tools.ietf.org/html/draft-ietf-dprive-dtls-and-tls-profiles
+.. _SNI: https://en.wikipedia.org/wiki/Server_Name_Indication
+.. _`Public Suffix List`: https://publicsuffix.org
diff --git a/modules/policy/lua-aho-corasick/LICENSE b/modules/policy/lua-aho-corasick/LICENSE
new file mode 100644
index 0000000..dd65f72
--- /dev/null
+++ b/modules/policy/lua-aho-corasick/LICENSE
@@ -0,0 +1,28 @@
+ Copyright (c) 2014 CloudFlare, Inc. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following disclaimer
+ in the documentation and/or other materials provided with the
+ distribution.
+ * Neither the name of CloudFlare, Inc. nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
diff --git a/modules/policy/lua-aho-corasick/Makefile b/modules/policy/lua-aho-corasick/Makefile
new file mode 100644
index 0000000..6471664
--- /dev/null
+++ b/modules/policy/lua-aho-corasick/Makefile
@@ -0,0 +1,134 @@
+OS := $(shell uname)
+
+ifeq ($(OS), Darwin)
+ SO_EXT := dylib
+else
+ SO_EXT := so
+endif
+
+#############################################################################
+#
+# Binaries we are going to build
+#
+#############################################################################
+#
+C_SO_NAME = libac.$(SO_EXT)
+LUA_SO_NAME = ahocorasick.$(SO_EXT)
+AR_NAME = libac.a
+
+#############################################################################
+#
+# Compile and link flags
+#
+#############################################################################
+PREFIX ?= /usr/local
+LUA_VERSION := 5.1
+LUA_INCLUDE_DIR := $(PREFIX)/include/lua$(LUA_VERSION)
+SO_TARGET_DIR := $(PREFIX)/lib/lua/$(LUA_VERSION)
+LUA_TARGET_DIR := $(PREFIX)/share/lua/$(LUA_VERSION)
+
+# Available directives:
+# -DDEBUG : Turn on debugging support
+# -DVERIFY : To verify if the slow-version and fast-version implementations
+# get exactly the same result. Note -DVERIFY implies -DDEBUG.
+#
+COMMON_FLAGS = -O3 #-g -DVERIFY -msse2 -msse3 -msse4.1
+COMMON_FLAGS += -fvisibility=hidden -Wall $(CXXFLAGS) $(MY_CXXFLAGS) $(CPPFLAGS)
+
+SO_CXXFLAGS = $(COMMON_FLAGS) -fPIC
+SO_LFLAGS = $(COMMON_FLAGS) $(LDFLAGS)
+AR_CXXFLAGS = $(COMMON_FLAGS)
+
+# -DVERIFY implies -DDEBUG
+ifneq ($(findstring -DVERIFY, $(COMMON_FLAGS)), )
+ifeq ($(findstring -DDEBUG, $(COMMON_FLAGS)), )
+ COMMON_FLAGS += -DDEBUG
+endif
+endif
+
+AR = ar
+AR_FLAGS = cru
+
+#############################################################################
+#
+# Divide source codes and objects into several categories
+#
+#############################################################################
+#
+SRC_COMMON := ac_fast.cxx ac_slow.cxx
+LIBAC_SO_SRC := $(SRC_COMMON) ac.cxx # source for libac.so
+LUA_SO_SRC := $(SRC_COMMON) ac_lua.cxx # source for ahocorasick.so
+LIBAC_A_SRC := $(LIBAC_SO_SRC) # source for libac.a
+
+#############################################################################
+#
+# Make rules
+#
+#############################################################################
+#
+.PHONY = all clean test benchmark prepare
+all : $(C_SO_NAME) $(LUA_SO_NAME) $(AR_NAME)
+
+-include c_so_dep.txt
+-include lua_so_dep.txt
+-include ar_dep.txt
+
+BUILD_SO_DIR := build_so
+BUILD_AR_DIR := build_ar
+
+$(BUILD_SO_DIR) :; mkdir $@
+$(BUILD_AR_DIR) :; mkdir $@
+
+$(BUILD_SO_DIR)/%.o : %.cxx | $(BUILD_SO_DIR)
+ $(CXX) $< -c $(SO_CXXFLAGS) -I$(LUA_INCLUDE_DIR) -MMD -o $@
+
+$(BUILD_AR_DIR)/%.o : %.cxx | $(BUILD_AR_DIR)
+ $(CXX) $< -c $(AR_CXXFLAGS) -I$(LUA_INCLUDE_DIR) -MMD -o $@
+
+ifneq ($(OS), Darwin)
+$(C_SO_NAME) : $(addprefix $(BUILD_SO_DIR)/, ${LIBAC_SO_SRC:.cxx=.o})
+ $(CXX) $+ -shared -Wl,-soname=$(C_SO_NAME) $(SO_LFLAGS) -o $@
+ cat $(addprefix $(BUILD_SO_DIR)/, ${LIBAC_SO_SRC:.cxx=.d}) > c_so_dep.txt
+
+$(LUA_SO_NAME) : $(addprefix $(BUILD_SO_DIR)/, ${LUA_SO_SRC:.cxx=.o})
+ $(CXX) $+ -shared -Wl,-soname=$(LUA_SO_NAME) $(SO_LFLAGS) -o $@
+ cat $(addprefix $(BUILD_SO_DIR)/, ${LUA_SO_SRC:.cxx=.d}) > lua_so_dep.txt
+
+else
+$(C_SO_NAME) : $(addprefix $(BUILD_SO_DIR)/, ${LIBAC_SO_SRC:.cxx=.o})
+ $(CXX) $+ -shared $(SO_LFLAGS) -o $@
+ cat $(addprefix $(BUILD_SO_DIR)/, ${LIBAC_SO_SRC:.cxx=.d}) > c_so_dep.txt
+
+$(LUA_SO_NAME) : $(addprefix $(BUILD_SO_DIR)/, ${LUA_SO_SRC:.cxx=.o})
+ $(CXX) $+ -shared $(SO_LFLAGS) -o $@ -Wl,-undefined,dynamic_lookup
+ cat $(addprefix $(BUILD_SO_DIR)/, ${LUA_SO_SRC:.cxx=.d}) > lua_so_dep.txt
+endif
+
+$(AR_NAME) : $(addprefix $(BUILD_AR_DIR)/, ${LIBAC_A_SRC:.cxx=.o})
+ $(AR) $(AR_FLAGS) $@ $+
+ cat $(addprefix $(BUILD_AR_DIR)/, ${LIBAC_A_SRC:.cxx=.d}) > lua_so_dep.txt
+
+#############################################################################
+#
+# Misc
+#
+#############################################################################
+#
+test : $(C_SO_NAME)
+ $(MAKE) -C tests && \
+ luajit tests/lua_test.lua && \
+ luajit tests/load_ac_test.lua
+
+benchmark: $(C_SO_NAME)
+ $(MAKE) benchmark -C tests
+
+clean :
+ -rm -rf *.o *.d c_so_dep.txt lua_so_dep.txt ar_dep.txt $(TEST) \
+ $(C_SO_NAME) $(LUA_SO_NAME) $(TEST) $(BUILD_SO_DIR) $(BUILD_AR_DIR) \
+ $(AR_NAME)
+ make clean -C tests
+
+install:
+ install -D -m 755 $(C_SO_NAME) $(DESTDIR)/$(SO_TARGET_DIR)/$(C_SO_NAME)
+ install -D -m 755 $(LUA_SO_NAME) $(DESTDIR)/$(SO_TARGET_DIR)/$(LUA_SO_NAME)
+ install -D -m 664 load_ac.lua $(DESTDIR)/$(LUA_TARGET_DIR)/load_ac.lua
diff --git a/modules/policy/lua-aho-corasick/README.md b/modules/policy/lua-aho-corasick/README.md
new file mode 100644
index 0000000..b5cc406
--- /dev/null
+++ b/modules/policy/lua-aho-corasick/README.md
@@ -0,0 +1,40 @@
+aho-corasick-lua
+================
+
+C++ and Lua Implementation of the Aho-Corasick (AC) string matching algorithm
+(http://dl.acm.org/citation.cfm?id=360855).
+
+We began with pure Lua implementation and realize the performance is not
+satisfactory. So we switch to C/C++ implementation.
+
+There are two shared objects provied by this package: libac.so and ahocorasick.so
+The former is a regular shared object which can be directly used by C/C++
+application, or by Lua via FFI; and the later is a Lua module. An example usage
+is shown bellow:
+
+```lua
+local ac = require "ahocorasick"
+local dict = {"string1", "string", "etc"}
+local acinst = ac.create(dict)
+local r = ac.match(acinst, "mystring")
+```
+
+For efficiency reasons, the implementation is slightly different from the
+standard AC algorithm in that it doesn't return a set of strings in the dictionary
+that match the given string, instead it only returns one of them in case the string
+matches. The functionality of our implementation can be (precisely) described by
+following pseudo-c snippet.
+
+```C
+string foo(input-string, dictionary) {
+ string ret = the-end-of-input-string;
+ for each string s in dictionary {
+ // find the first occurrence match sub-string.
+ ret = min(ret, strstr(input-string, s);
+ }
+ return ret;
+}
+```
+
+It's pretty easy to get rid of this limitation, just to associate each state with
+a spare bit-vector dipicting the set of strings recognized by that state.
diff --git a/modules/policy/lua-aho-corasick/ac.cxx b/modules/policy/lua-aho-corasick/ac.cxx
new file mode 100644
index 0000000..23fb3b5
--- /dev/null
+++ b/modules/policy/lua-aho-corasick/ac.cxx
@@ -0,0 +1,101 @@
+// Interface functions for libac.so
+//
+#include "ac_slow.hpp"
+#include "ac_fast.hpp"
+#include "ac.h"
+
+static inline ac_result_t
+_match(buf_header_t* ac, const char* str, unsigned int len) {
+ AC_Buffer* buf = (AC_Buffer*)(void*)ac;
+ ASSERT(ac->magic_num == AC_MAGIC_NUM);
+
+ ac_result_t r = Match(buf, str, len);
+
+ #ifdef VERIFY
+ {
+ Match_Result r2 = buf->slow_impl->Match(str, len);
+ if (r.match_begin != r2.begin) {
+ ASSERT(0);
+ } else {
+ ASSERT((r.match_begin < 0) ||
+ (r.match_end == r2.end &&
+ r.pattern_idx == r2.pattern_idx));
+ }
+ }
+ #endif
+ return r;
+}
+
+extern "C" int
+ac_match2(ac_t* ac, const char* str, unsigned int len) {
+ ac_result_t r = _match((buf_header_t*)(void*)ac, str, len);
+ return r.match_begin;
+}
+
+extern "C" ac_result_t
+ac_match(ac_t* ac, const char* str, unsigned int len) {
+ return _match((buf_header_t*)(void*)ac, str, len);
+}
+
+extern "C" ac_result_t
+ac_match_longest_l(ac_t* ac, const char* str, unsigned int len) {
+ AC_Buffer* buf = (AC_Buffer*)(void*)ac;
+ ASSERT(((buf_header_t*)ac)->magic_num == AC_MAGIC_NUM);
+
+ ac_result_t r = Match_Longest_L(buf, str, len);
+ return r;
+}
+
+class BufAlloc : public Buf_Allocator {
+public:
+ virtual AC_Buffer* alloc(int sz) {
+ return (AC_Buffer*)(new unsigned char[sz]);
+ }
+
+ // Do not de-allocate the buffer when the BufAlloc die.
+ virtual void free() {}
+
+ static void myfree(AC_Buffer* buf) {
+ ASSERT(buf->hdr.magic_num == AC_MAGIC_NUM);
+ const char* b = (const char*)buf;
+ delete[] b;
+ }
+};
+
+extern "C" ac_t*
+ac_create(const char** strv, unsigned int* strlenv, unsigned int v_len) {
+ if (v_len >= 65535) {
+ // TODO: Currently we use 16-bit to encode pattern-index (see the
+ // comment to AC_State::is_term), therefore we are not able to
+ // handle pattern set with more than 65535 entries.
+ return 0;
+ }
+
+ ACS_Constructor *acc;
+#ifdef VERIFY
+ acc = new ACS_Constructor;
+#else
+ ACS_Constructor tmp;
+ acc = &tmp;
+#endif
+ acc->Construct(strv, strlenv, v_len);
+
+ BufAlloc ba;
+ AC_Converter cvt(*acc, ba);
+ AC_Buffer* buf = cvt.Convert();
+
+#ifdef VERIFY
+ buf->slow_impl = acc;
+#endif
+ return (ac_t*)(void*)buf;
+}
+
+extern "C" void
+ac_free(void* ac) {
+ AC_Buffer* buf = (AC_Buffer*)ac;
+#ifdef VERIFY
+ delete buf->slow_impl;
+#endif
+
+ BufAlloc::myfree(buf);
+}
diff --git a/modules/policy/lua-aho-corasick/ac.h b/modules/policy/lua-aho-corasick/ac.h
new file mode 100644
index 0000000..30bf447
--- /dev/null
+++ b/modules/policy/lua-aho-corasick/ac.h
@@ -0,0 +1,49 @@
+#ifndef AC_H
+#define AC_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define AC_EXPORT __attribute__ ((visibility ("default")))
+
+/* If the subject-string dosen't match any of the given patterns, "match_begin"
+ * should be a negative; otherwise the substring of the subject-string,
+ * starting from offset "match_begin" to "match_end" incusively,
+ * should exactly match the pattern specified by the 'pattern_idx' (i.e.
+ * the pattern is "pattern_v[pattern_idx]" where the "pattern_v" is the
+ * first acutal argument passing to ac_create())
+ */
+typedef struct {
+ int match_begin;
+ int match_end;
+ int pattern_idx;
+} ac_result_t;
+
+struct ac_t;
+
+/* Create an AC instance. "pattern_v" is a vector of patterns, the length of
+ * i-th pattern is specified by "pattern_len_v[i]"; the number of patterns
+ * is specified by "vect_len".
+ *
+ * Return the instance on success, or NUL otherwise.
+ */
+ac_t* ac_create(const char** pattern_v, unsigned int* pattern_len_v,
+ unsigned int vect_len) AC_EXPORT;
+
+ac_result_t ac_match(ac_t*, const char *str, unsigned int len) AC_EXPORT;
+
+ac_result_t ac_match_longest_l(ac_t*, const char *str, unsigned int len) AC_EXPORT;
+
+/* Similar to ac_match() except that it only returns match-begin. The rationale
+ * for this interface is that luajit has hard time in dealing with strcture-
+ * return-value.
+ */
+int ac_match2(ac_t*, const char *str, unsigned int len) AC_EXPORT;
+
+void ac_free(void*) AC_EXPORT;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* AC_H */
diff --git a/modules/policy/lua-aho-corasick/ac_fast.cxx b/modules/policy/lua-aho-corasick/ac_fast.cxx
new file mode 100644
index 0000000..9dbc2e6
--- /dev/null
+++ b/modules/policy/lua-aho-corasick/ac_fast.cxx
@@ -0,0 +1,468 @@
+#include <algorithm> // for std::sort
+#include "ac_slow.hpp"
+#include "ac_fast.hpp"
+
+uint32
+AC_Converter::Calc_State_Sz(const ACS_State* s) const {
+ AC_State dummy;
+ uint32 sz = offsetof(AC_State, input_vect);
+ sz += s->Get_GotoNum() * sizeof(dummy.input_vect[0]);
+
+ if (sz < sizeof(AC_State))
+ sz = sizeof(AC_State);
+
+ uint32 align = __alignof__(dummy);
+ sz = (sz + align - 1) & ~(align - 1);
+ return sz;
+}
+
+AC_Buffer*
+AC_Converter::Alloc_Buffer() {
+ const vector<ACS_State*>& all_states = _acs.Get_All_States();
+ const ACS_State* root_state = _acs.Get_Root_State();
+ uint32 root_fanout = root_state->Get_GotoNum();
+
+ // Step 1: Calculate the buffer size
+ AC_Ofst root_goto_ofst, states_ofst_ofst, first_state_ofst;
+
+ // part 1 : buffer header
+ uint32 sz = root_goto_ofst = sizeof(AC_Buffer);
+
+ // part 2: Root-node's goto function
+ if (likely(root_fanout != 255))
+ sz += 256;
+ else
+ root_goto_ofst = 0;
+
+ // part 3: mapping of state's relative position.
+ unsigned align = __alignof__(AC_Ofst);
+ sz = (sz + align - 1) & ~(align - 1);
+ states_ofst_ofst = sz;
+
+ sz += sizeof(AC_Ofst) * all_states.size();
+
+ // part 4: state's contents
+ align = __alignof__(AC_State);
+ sz = (sz + align - 1) & ~(align - 1);
+ first_state_ofst = sz;
+
+ uint32 state_sz = 0;
+ for (vector<ACS_State*>::const_iterator i = all_states.begin(),
+ e = all_states.end(); i != e; i++) {
+ state_sz += Calc_State_Sz(*i);
+ }
+ state_sz -= Calc_State_Sz(root_state);
+
+ sz += state_sz;
+
+ // Step 2: Allocate buffer, and populate header.
+ AC_Buffer* buf = _buf_alloc.alloc(sz);
+
+ buf->hdr.magic_num = AC_MAGIC_NUM;
+ buf->hdr.impl_variant = IMPL_FAST_VARIANT;
+ buf->buf_len = sz;
+ buf->root_goto_ofst = root_goto_ofst;
+ buf->states_ofst_ofst = states_ofst_ofst;
+ buf->first_state_ofst = first_state_ofst;
+ buf->root_goto_num = root_fanout;
+ buf->state_num = _acs.Get_State_Num();
+ return buf;
+}
+
+void
+AC_Converter::Populate_Root_Goto_Func(AC_Buffer* buf,
+ GotoVect& goto_vect) {
+ unsigned char *buf_base = (unsigned char*)(buf);
+ InputTy* root_gotos = (InputTy*)(buf_base + buf->root_goto_ofst);
+ const ACS_State* root_state = _acs.Get_Root_State();
+
+ root_state->Get_Sorted_Gotos(goto_vect);
+
+ // Renumber the ID of root-node's immediate kids.
+ uint32 new_id = 1;
+ bool full_fantout = (goto_vect.size() == 255);
+ if (likely(!full_fantout))
+ bzero(root_gotos, 256*sizeof(InputTy));
+
+ for (GotoVect::iterator i = goto_vect.begin(), e = goto_vect.end();
+ i != e; i++, new_id++) {
+ InputTy c = i->first;
+ ACS_State* s = i->second;
+ _id_map[s->Get_ID()] = new_id;
+
+ if (likely(!full_fantout))
+ root_gotos[c] = new_id;
+ }
+}
+
+AC_Buffer*
+AC_Converter::Convert() {
+ // Step 1: Some preparation stuff.
+ GotoVect gotovect;
+
+ _id_map.clear();
+ _ofst_map.clear();
+ _id_map.resize(_acs.Get_Next_Node_Id());
+ _ofst_map.resize(_acs.Get_Next_Node_Id());
+
+ // Step 2: allocate buffer to accommodate the entire AC graph.
+ AC_Buffer* buf = Alloc_Buffer();
+ unsigned char* buf_base = (unsigned char*)buf;
+
+ // Step 3: Root node need special care.
+ Populate_Root_Goto_Func(buf, gotovect);
+ buf->root_goto_num = gotovect.size();
+ _id_map[_acs.Get_Root_State()->Get_ID()] = 0;
+
+ // Step 4: Converting the remaining states by BFSing the graph.
+ // First of all, enter root's immediate kids to the working list.
+ vector<const ACS_State*> wl;
+ State_ID id = 1;
+ for (GotoVect::iterator i = gotovect.begin(), e = gotovect.end();
+ i != e; i++, id++) {
+ ACS_State* s = i->second;
+ wl.push_back(s);
+ _id_map[s->Get_ID()] = id;
+ }
+
+ AC_Ofst* state_ofst_vect = (AC_Ofst*)(buf_base + buf->states_ofst_ofst);
+ AC_Ofst ofst = buf->first_state_ofst;
+ for (uint32 idx = 0; idx < wl.size(); idx++) {
+ const ACS_State* old_s = wl[idx];
+ AC_State* new_s = (AC_State*)(buf_base + ofst);
+
+ // This property should hold as we:
+ // - States are appended to worklist in the BFS order.
+ // - sibiling states are appended to worklist in the order of their
+ // corresponding input.
+ //
+ State_ID state_id = idx + 1;
+ ASSERT(_id_map[old_s->Get_ID()] == state_id);
+
+ state_ofst_vect[state_id] = ofst;
+
+ new_s->first_kid = wl.size() + 1;
+ new_s->depth = old_s->Get_Depth();
+ new_s->is_term = old_s->is_Terminal() ?
+ old_s->get_Pattern_Idx() + 1 : 0;
+
+ uint32 gotonum = old_s->Get_GotoNum();
+ new_s->goto_num = gotonum;
+
+ // Populate the "input" field
+ old_s->Get_Sorted_Gotos(gotovect);
+ uint32 input_idx = 0;
+ uint32 id = wl.size() + 1;
+ InputTy* input_vect = new_s->input_vect;
+ for (GotoVect::iterator i = gotovect.begin(), e = gotovect.end();
+ i != e; i++, id++, input_idx++) {
+ input_vect[input_idx] = i->first;
+
+ ACS_State* kid = i->second;
+ _id_map[kid->Get_ID()] = id;
+ wl.push_back(kid);
+ }
+
+ _ofst_map[old_s->Get_ID()] = ofst;
+ ofst += Calc_State_Sz(old_s);
+ }
+
+ // This assertion might be useful to catch buffer overflow
+ ASSERT(ofst == buf->buf_len);
+
+ // Populate the fail-link field.
+ for (vector<const ACS_State*>::iterator i = wl.begin(), e = wl.end();
+ i != e; i++) {
+ const ACS_State* slow_s = *i;
+ State_ID fast_s_id = _id_map[slow_s->Get_ID()];
+ AC_State* fast_s = (AC_State*)(buf_base + state_ofst_vect[fast_s_id]);
+ if (const ACS_State* fl = slow_s->Get_FailLink()) {
+ State_ID id = _id_map[fl->Get_ID()];
+ fast_s->fail_link = id;
+ } else
+ fast_s->fail_link = 0;
+ }
+#ifdef DEBUG
+ //dump_buffer(buf, stderr);
+#endif
+ return buf;
+}
+
+static inline AC_State*
+Get_State_Addr(unsigned char* buf_base, AC_Ofst* StateOfstVect, uint32 state_id) {
+ ASSERT(state_id != 0 && "root node is handled in speical way");
+ ASSERT(state_id < ((AC_Buffer*)buf_base)->state_num);
+ return (AC_State*)(buf_base + StateOfstVect[state_id]);
+}
+
+// The performance of the binary search is critical to this work.
+//
+// Here we provide two versions of binary-search functions.
+// The non-pristine version seems to consistently out-perform "pristine" one on
+// bunch of benchmarks we tested. With the benchmark under tests/testinput/
+//
+// The speedup is following on my laptop (core i7, ubuntu):
+//
+// benchmark was is
+// ----------------------------------------
+// image.bin 2.3s 2.0s
+// test.tar 6.7s 5.7s
+//
+// NOTE: As of I write this comment, we only measure the performance on about
+// 10+ benchmarks. It's still too early to say which one works better.
+//
+#if !defined(BS_MULTI_VER)
+static bool __attribute__((always_inline)) inline
+Binary_Search_Input(InputTy* input_vect, int vect_len, InputTy input, int& idx) {
+ if (vect_len <= 8) {
+ for (int i = 0; i < vect_len; i++) {
+ if (input_vect[i] == input) {
+ idx = i;
+ return true;
+ }
+ }
+ return false;
+ }
+
+ // The "low" and "high" must be signed integers, as they could become -1.
+ // Also since they are signed integer, "(low + high)/2" is sightly more
+ // expensive than (low+high)>>1 or ((unsigned)(low + high))/2.
+ //
+ int low = 0, high = vect_len - 1;
+ while (low <= high) {
+ int mid = (low + high) >> 1;
+ InputTy mid_c = input_vect[mid];
+
+ if (input < mid_c)
+ high = mid - 1;
+ else if (input > mid_c)
+ low = mid + 1;
+ else {
+ idx = mid;
+ return true;
+ }
+ }
+ return false;
+}
+
+#else
+
+/* Let us call this version "pristine" version. */
+static inline bool
+Binary_Search_Input(InputTy* input_vect, int vect_len, InputTy input, int& idx) {
+ int low = 0, high = vect_len - 1;
+ while (low <= high) {
+ int mid = (low + high) >> 1;
+ InputTy mid_c = input_vect[mid];
+
+ if (input < mid_c)
+ high = mid - 1;
+ else if (input > mid_c)
+ low = mid + 1;
+ else {
+ idx = mid;
+ return true;
+ }
+ }
+ return false;
+}
+#endif
+
+typedef enum {
+ // Look for the first match. e.g. pattern set = {"ab", "abc", "def"},
+ // subject string "ababcdef". The first match would be "ab" at the
+ // beginning of the subject string.
+ MV_FIRST_MATCH,
+
+ // Look for the left-most longest match. Follow above example; there are
+ // two longest matches, "abc" and "def", and the left-most longest match
+ // is "abc".
+ MV_LEFT_LONGEST,
+
+ // Similar to the left-most longest match, except that it returns the
+ // *right* most longest match. Follow above example, the match would
+ // be "def". NYI.
+ MV_RIGHT_LONGEST,
+
+ // Return all patterns that match that given subject string. NYI.
+ MV_ALL_MATCHES,
+} MATCH_VARIANT;
+
+/* The Match_Tmpl is the template for vairants MV_FIRST_MATCH, MV_LEFT_LONGEST,
+ * MV_RIGHT_LONGEST (If we really really need MV_RIGHT_LONGEST variant, we are
+ * better off implementing it in a seprate function).
+ *
+ * The Match_Tmpl supports three variants at once "symbolically", once it's
+ * instanced to a particular variants, all the code irrelevant to the variants
+ * will be statically removed. So don't worry about the code like
+ * "if (variant == MV_XXXX)"; they will not incur any penalty.
+ *
+ * The drawback of using template is increased code size. Unfortunately, there
+ * is no silver bullet.
+ */
+template<MATCH_VARIANT variant> static ac_result_t
+Match_Tmpl(AC_Buffer* buf, const char* str, uint32 len) {
+ unsigned char* buf_base = (unsigned char*)(buf);
+ unsigned char* root_goto = buf_base + buf->root_goto_ofst;
+ AC_Ofst* states_ofst_vect = (AC_Ofst* )(buf_base + buf->states_ofst_ofst);
+
+ AC_State* state = 0;
+ uint32 idx = 0;
+
+ // Skip leading chars that are not valid input of root-nodes.
+ if (likely(buf->root_goto_num != 255)) {
+ while(idx < len) {
+ unsigned char c = str[idx++];
+ if (unsigned char kid_id = root_goto[c]) {
+ state = Get_State_Addr(buf_base, states_ofst_vect, kid_id);
+ break;
+ }
+ }
+ } else {
+ idx = 1;
+ state = Get_State_Addr(buf_base, states_ofst_vect, *str);
+ }
+
+ ac_result_t r = {-1, -1};
+ if (likely(state != 0)) {
+ if (unlikely(state->is_term)) {
+ /* Dictionary may have string of length 1 */
+ r.match_begin = idx - state->depth;
+ r.match_end = idx - 1;
+ r.pattern_idx = state->is_term - 1;
+
+ if (variant == MV_FIRST_MATCH) {
+ return r;
+ }
+ }
+ }
+
+ while (idx < len) {
+ unsigned char c = str[idx];
+ int res;
+ bool found;
+ found = Binary_Search_Input(state->input_vect, state->goto_num, c, res);
+ if (found) {
+ // The "t = goto(c, current_state)" is valid, advance to state "t".
+ uint32 kid = state->first_kid + res;
+ state = Get_State_Addr(buf_base, states_ofst_vect, kid);
+ idx++;
+ } else {
+ // Follow the fail-link.
+ State_ID fl = state->fail_link;
+ if (fl == 0) {
+ // fail-link is root-node, which implies the root-node dosen't
+ // have 255 valid transitions (otherwise, the fail-link should
+ // points to "goto(root, c)"), so we don't need speical handling
+ // as we did before this while-loop is entered.
+ //
+ while(idx < len) {
+ InputTy c = str[idx++];
+ if (unsigned char kid_id = root_goto[c]) {
+ state =
+ Get_State_Addr(buf_base, states_ofst_vect, kid_id);
+ break;
+ }
+ }
+ } else {
+ state = Get_State_Addr(buf_base, states_ofst_vect, fl);
+ }
+ }
+
+ // Check to see if the state is terminal state?
+ if (state->is_term) {
+ if (variant == MV_FIRST_MATCH) {
+ ac_result_t r;
+ r.match_begin = idx - state->depth;
+ r.match_end = idx - 1;
+ r.pattern_idx = state->is_term - 1;
+ return r;
+ }
+
+ if (variant == MV_LEFT_LONGEST) {
+ int match_begin = idx - state->depth;
+ int match_end = idx - 1;
+
+ if (r.match_begin == -1 ||
+ match_end - match_begin > r.match_end - r.match_begin) {
+ r.match_begin = match_begin;
+ r.match_end = match_end;
+ r.pattern_idx = state->is_term - 1;
+ }
+ continue;
+ }
+
+ ASSERT(false && "NYI");
+ }
+ }
+
+ return r;
+}
+
+ac_result_t
+Match(AC_Buffer* buf, const char* str, uint32 len) {
+ return Match_Tmpl<MV_FIRST_MATCH>(buf, str, len);
+}
+
+ac_result_t
+Match_Longest_L(AC_Buffer* buf, const char* str, uint32 len) {
+ return Match_Tmpl<MV_LEFT_LONGEST>(buf, str, len);
+}
+
+#ifdef DEBUG
+void
+AC_Converter::dump_buffer(AC_Buffer* buf, FILE* f) {
+ vector<AC_Ofst> state_ofst;
+ state_ofst.resize(_id_map.size());
+
+ fprintf(f, "Id maps between old/slow and new/fast graphs\n");
+ int old_id = 0;
+ for (vector<uint32>::iterator i = _id_map.begin(), e = _id_map.end();
+ i != e; i++, old_id++) {
+ State_ID new_id = *i;
+ if (new_id != 0) {
+ fprintf(f, "%d -> %d, ", old_id, new_id);
+ }
+ }
+ fprintf(f, "\n");
+
+ int idx = 0;
+ for (vector<uint32>::iterator i = _id_map.begin(), e = _id_map.end();
+ i != e; i++, idx++) {
+ uint32 id = *i;
+ if (id == 0) continue;
+ state_ofst[id] = _ofst_map[idx];
+ }
+
+ unsigned char* buf_base = (unsigned char*)buf;
+
+ // dump root goto-function.
+ fprintf(f, "root, fanout:%d goto {", buf->root_goto_num);
+ if (buf->root_goto_num != 255) {
+ unsigned char* root_goto = buf_base + buf->root_goto_ofst;
+ for (uint32 i = 0; i < 255; i++) {
+ if (root_goto[i] != 0)
+ fprintf(f, "%c->S:%d, ", (unsigned char)i, root_goto[i]);
+ }
+ } else {
+ fprintf(f, "full fanout\n");
+ }
+ fprintf(f, "}\n");
+
+ // dump remaining states.
+ AC_Ofst* state_ofst_vect = (AC_Ofst*)(buf_base + buf->states_ofst_ofst);
+ for (uint32 i = 1, e = buf->state_num; i < e; i++) {
+ AC_Ofst ofst = state_ofst_vect[i];
+ ASSERT(ofst == state_ofst[i]);
+ fprintf(f, "S:%d, ofst:%d, goto={", i, ofst);
+
+ AC_State* s = (AC_State*)(buf_base + ofst);
+ State_ID kid = s->first_kid;
+ for (uint32 k = 0, ke = s->goto_num; k < ke; k++, kid++)
+ fprintf(f, "%c->S:%d, ", s->input_vect[k], kid);
+
+ fprintf(f, "}, fail-link = S:%d, %s\n", s->fail_link,
+ s->is_term ? "terminal" : "");
+ }
+}
+#endif
diff --git a/modules/policy/lua-aho-corasick/ac_fast.hpp b/modules/policy/lua-aho-corasick/ac_fast.hpp
new file mode 100644
index 0000000..9ac557c
--- /dev/null
+++ b/modules/policy/lua-aho-corasick/ac_fast.hpp
@@ -0,0 +1,124 @@
+#ifndef AC_FAST_H
+#define AC_FAST_H
+
+#include <vector>
+#include "ac.h"
+#include "ac_slow.hpp"
+
+using namespace std;
+
+class ACS_Constructor;
+
+typedef uint32 AC_Ofst;
+typedef uint32 State_ID;
+
+// The entire "fast" AC graph is converted from its "slow" version, and store
+// in an consecutive trunk of memory or "buffer". Since the pointers in the
+// fast AC graph are represented as offset relative to the base address of
+// the buffer, this fast AC graph is position-independent, meaning cloning
+// the fast graph is just to memcpy the entire buffer.
+//
+// The buffer is laid-out as following:
+//
+// 1. The buffer header. (i.e. the AC_Buffer content)
+// 2. root-node's goto functions. It is represented as an array indiced by
+// root-node's valid inputs, and the element is the ID of the corresponding
+// transition state (aka kid). To save space, we used 8-bit to represent
+// the IDs. ID of root's kids starts with 1.
+//
+// Root may have 255 valid inputs. In this speical case, i-th element
+// stores value i -- i.e the i-th state. So, we don't need such array
+// at all. On the other hand, 8-bit is insufficient to encode kids' ID.
+//
+// 3. An array indiced by state's id, and the element is the offset
+// of correspoding state wrt the base address of the buffer.
+//
+// 4. the contents of states.
+//
+typedef struct {
+ buf_header_t hdr; // The header exposed to the user using this lib.
+#ifdef VERIFY
+ ACS_Constructor* slow_impl;
+#endif
+ uint32 buf_len;
+ AC_Ofst root_goto_ofst; // addr of root node's goto() function.
+ AC_Ofst states_ofst_ofst; // addr of state pointer vector (indiced by id)
+ AC_Ofst first_state_ofst; // addr of the first state in the buffer.
+ uint16 root_goto_num; // fan-out of root-node.
+ uint16 state_num; // number of states
+
+ // Followed by the gut of the buffer:
+ // 1. map: root's-valid-input -> kid's id
+ // 2. map: state's ID -> offset of the state
+ // 3. states' content.
+} AC_Buffer;
+
+// Depict the state of "fast" AC graph.
+typedef struct {
+ // transition are sorted. For instance, state s1, has two transitions :
+ // goto(b) -> S_b, goto(a)->S_a. The inputs are sorted in the ascending
+ // order, and the target states are permuted accordingly. In this case,
+ // the inputs are sorted as : a, b, and the target states are permuted
+ // into S_a, S_b. So, S_a is the 1st kid, the ID of kids are consecutive,
+ // so we don't need to save all the target kids.
+ //
+ State_ID first_kid;
+ AC_Ofst fail_link;
+ short depth; // How far away from root.
+ unsigned short is_term; // Is terminal node. if is_term != 0, it encodes
+ // the value of "1 + pattern-index".
+ unsigned char goto_num; // The number of valid transition.
+ InputTy input_vect[1]; // Vector of valid input. Must be last field!
+} AC_State;
+
+class Buf_Allocator {
+public:
+ Buf_Allocator() : _buf(0) {}
+ virtual ~Buf_Allocator() { free(); }
+
+ virtual AC_Buffer* alloc(int sz) = 0;
+ virtual void free() {};
+protected:
+ AC_Buffer* _buf;
+};
+
+// Convert slow-AC-graph into fast one.
+class AC_Converter {
+public:
+ AC_Converter(ACS_Constructor& acs, Buf_Allocator& ba) :
+ _acs(acs), _buf_alloc(ba) {}
+ AC_Buffer* Convert();
+
+private:
+ // Return the size in byte needed to to save the specified state.
+ uint32 Calc_State_Sz(const ACS_State *) const;
+
+ // In fast-AC-graph, the ID is bit trikcy. Given a state of slow-graph,
+ // this function is to return the ID of its counterpart in the fast-graph.
+ State_ID Get_Renumbered_Id(const ACS_State *s) const {
+ const vector<uint32> &m = _id_map;
+ return m[s->Get_ID()];
+ }
+
+ AC_Buffer* Alloc_Buffer();
+ void Populate_Root_Goto_Func(AC_Buffer *, GotoVect&);
+
+#ifdef DEBUG
+ void dump_buffer(AC_Buffer*, FILE*);
+#endif
+
+private:
+ ACS_Constructor& _acs;
+ Buf_Allocator& _buf_alloc;
+
+ // map: ID of state in slow-graph -> ID of counterpart in fast-graph.
+ vector<uint32> _id_map;
+
+ // map: ID of state in slow-graph -> offset of counterpart in fast-graph.
+ vector<AC_Ofst> _ofst_map;
+};
+
+ac_result_t Match(AC_Buffer* buf, const char* str, uint32 len);
+ac_result_t Match_Longest_L(AC_Buffer* buf, const char* str, uint32 len);
+
+#endif // AC_FAST_H
diff --git a/modules/policy/lua-aho-corasick/ac_lua.cxx b/modules/policy/lua-aho-corasick/ac_lua.cxx
new file mode 100644
index 0000000..ad7307e
--- /dev/null
+++ b/modules/policy/lua-aho-corasick/ac_lua.cxx
@@ -0,0 +1,173 @@
+// Interface functions for libac.so
+//
+#include <vector>
+#include <string>
+#include "ac_slow.hpp"
+#include "ac_fast.hpp"
+#include "ac.h" // for the definition of ac_result_t
+#include "ac_util.hpp"
+
+extern "C" {
+ #include <lua.h>
+ #include <lauxlib.h>
+}
+
+#if defined(USE_SLOW_VER)
+#error "Not going to implement it"
+#endif
+
+using namespace std;
+static const char* tname = "aho-corasick";
+
+class BufAlloc : public Buf_Allocator {
+public:
+ BufAlloc(lua_State* L) : _L(L) {}
+ virtual AC_Buffer* alloc(int sz) {
+ return (AC_Buffer*)lua_newuserdata (_L, sz);
+ }
+
+ // Let GC to take care.
+ virtual void free() {}
+
+private:
+ lua_State* _L;
+};
+
+static bool
+_create_helper(lua_State* L, const vector<const char*>& str_v,
+ const vector<unsigned int>& strlen_v) {
+ ASSERT(str_v.size() == strlen_v.size());
+
+ ACS_Constructor acc;
+ BufAlloc ba(L);
+
+ // Step 1: construt the slow version.
+ unsigned int strnum = str_v.size();
+ const char** str_vect = new const char*[strnum];
+ unsigned int* strlen_vect = new unsigned int[strnum];
+
+ int idx = 0;
+ for (vector<const char*>::const_iterator i = str_v.begin(), e = str_v.end();
+ i != e; i++) {
+ str_vect[idx++] = *i;
+ }
+
+ idx = 0;
+ for (vector<unsigned int>::const_iterator i = strlen_v.begin(),
+ e = strlen_v.end(); i != e; i++) {
+ strlen_vect[idx++] = *i;
+ }
+
+ acc.Construct(str_vect, strlen_vect, idx);
+ delete[] str_vect;
+ delete[] strlen_vect;
+
+ // Step 2: convert to fast version
+ AC_Converter cvt(acc, ba);
+ return cvt.Convert() != 0;
+}
+
+static ac_result_t
+_match_helper(buf_header_t* ac, const char *str, unsigned int len) {
+ AC_Buffer* buf = (AC_Buffer*)(void*)ac;
+ ASSERT(ac->magic_num == AC_MAGIC_NUM);
+
+ ac_result_t r = Match(buf, str, len);
+ return r;
+}
+
+// LUA sematic:
+// input: array of strings
+// output: userdata containing the AC-graph (i.e. the AC_Buffer).
+//
+static int
+lac_create(lua_State* L) {
+ // The table of the array must be the 1st argument.
+ int input_tab = 1;
+
+ luaL_checktype(L, input_tab, LUA_TTABLE);
+
+ // Init the "iteartor".
+ lua_pushnil(L);
+
+ vector<const char*> str_v;
+ vector<unsigned int> strlen_v;
+
+ // Loop over the elements
+ while (lua_next(L, input_tab)) {
+ size_t str_len;
+ const char* s = luaL_checklstring(L, -1, &str_len);
+ str_v.push_back(s);
+ strlen_v.push_back(str_len);
+
+ // remove the value, but keep the key as the iterator.
+ lua_pop(L, 1);
+ }
+
+ // pop the nil value
+ lua_pop(L, 1);
+
+ if (_create_helper(L, str_v, strlen_v)) {
+ // The AC graph, as a userdata is already pushed to the stack, hence 1.
+ return 1;
+ }
+
+ return 0;
+}
+
+// LUA input:
+// arg1: the userdata, representing the AC graph, returned from l_create().
+// arg2: the string to be matched.
+//
+// LUA return:
+// if match, return index range of the match; otherwise nil is returned.
+//
+static int
+lac_match(lua_State* L) {
+ buf_header_t* ac = (buf_header_t*)lua_touserdata(L, 1);
+ if (!ac) {
+ luaL_checkudata(L, 1, tname);
+ return 0;
+ }
+
+ size_t len;
+ const char* str;
+ #if LUA_VERSION_NUM >= 502
+ str = luaL_tolstring(L, 2, &len);
+ #else
+ str = lua_tolstring(L, 2, &len);
+ #endif
+ if (!str) {
+ luaL_checkstring(L, 2);
+ return 0;
+ }
+
+ ac_result_t r = _match_helper(ac, str, len);
+ if (r.match_begin != -1) {
+ lua_pushinteger(L, r.match_begin);
+ lua_pushinteger(L, r.match_end);
+ return 2;
+ }
+
+ return 0;
+}
+
+static const struct luaL_Reg lib_funcs[] = {
+ { "create", lac_create },
+ { "match", lac_match },
+ {0, 0}
+};
+
+extern "C" int AC_EXPORT
+luaopen_ahocorasick(lua_State* L) {
+ luaL_newmetatable(L, tname);
+
+#if LUA_VERSION_NUM == 501
+ luaL_register(L, tname, lib_funcs);
+#elif LUA_VERSION_NUM >= 502
+ luaL_newlib(L, lib_funcs);
+#else
+ #error "Don't know how to do it right"
+#endif
+ return 1;
+}
diff --git a/modules/policy/lua-aho-corasick/ac_slow.cxx b/modules/policy/lua-aho-corasick/ac_slow.cxx
new file mode 100644
index 0000000..cb3957a
--- /dev/null
+++ b/modules/policy/lua-aho-corasick/ac_slow.cxx
@@ -0,0 +1,318 @@
+#include <ctype.h>
+#include <strings.h> // for bzero
+#include <algorithm>
+#include "ac_slow.hpp"
+#include "ac.h"
+
+//////////////////////////////////////////////////////////////////////////
+//
+// Implementation of AhoCorasick_Slow
+//
+//////////////////////////////////////////////////////////////////////////
+//
+ACS_Constructor::ACS_Constructor() : _next_node_id(1) {
+ _root = new_state();
+ _root_char = new InputTy[256];
+ bzero((void*)_root_char, 256);
+
+#ifdef VERIFY
+ _pattern_buf = 0;
+#endif
+}
+
+ACS_Constructor::~ACS_Constructor() {
+ for (std::vector<ACS_State* >::iterator i = _all_states.begin(),
+ e = _all_states.end(); i != e; i++) {
+ delete *i;
+ }
+ _all_states.clear();
+ delete[] _root_char;
+
+#ifdef VERIFY
+ delete[] _pattern_buf;
+#endif
+}
+
+ACS_State*
+ACS_Constructor::new_state() {
+ ACS_State* t = new ACS_State(_next_node_id++);
+ _all_states.push_back(t);
+ return t;
+}
+
+void
+ACS_Constructor::Add_Pattern(const char* str, unsigned int str_len,
+ int pattern_idx) {
+ ACS_State* state = _root;
+ for (unsigned int i = 0; i < str_len; i++) {
+ const char c = str[i];
+ ACS_State* new_s = state->Get_Goto(c);
+ if (!new_s) {
+ new_s = new_state();
+ new_s->_depth = state->_depth + 1;
+ state->Set_Goto(c, new_s);
+ }
+ state = new_s;
+ }
+ state->_is_terminal = true;
+ state->set_Pattern_Idx(pattern_idx);
+}
+
+void
+ACS_Constructor::Propagate_faillink() {
+ ACS_State* r = _root;
+ std::vector<ACS_State*> wl;
+
+ const ACS_Goto_Map& m = r->Get_Goto_Map();
+ for (ACS_Goto_Map::const_iterator i = m.begin(), e = m.end(); i != e; i++) {
+ ACS_State* s = i->second;
+ s->_fail_link = r;
+ wl.push_back(s);
+ }
+
+ // For any input c, make sure "goto(root, c)" is valid, which make the
+ // fail-link propagation lot easier.
+ ACS_Goto_Map goto_save = r->_goto_map;
+ for (uint32 i = 0; i <= 255; i++) {
+ ACS_State* s = r->Get_Goto(i);
+ if (!s) r->Set_Goto(i, r);
+ }
+
+ for (uint32 i = 0; i < wl.size(); i++) {
+ ACS_State* s = wl[i];
+ ACS_State* fl = s->_fail_link;
+
+ const ACS_Goto_Map& tran_map = s->Get_Goto_Map();
+
+ for (ACS_Goto_Map::const_iterator ii = tran_map.begin(),
+ ee = tran_map.end(); ii != ee; ii++) {
+ InputTy c = ii->first;
+ ACS_State *tran = ii->second;
+
+ ACS_State* tran_fl = 0;
+ for (ACS_State* fl_walk = fl; ;) {
+ if (ACS_State* t = fl_walk->Get_Goto(c)) {
+ tran_fl = t;
+ break;
+ } else {
+ fl_walk = fl_walk->Get_FailLink();
+ }
+ }
+
+ tran->_fail_link = tran_fl;
+ wl.push_back(tran);
+ }
+ }
+
+ // Remove "goto(root, c) == root" transitions
+ r->_goto_map = goto_save;
+}
+
+void
+ACS_Constructor::Construct(const char** strv, unsigned int* strlenv,
+ uint32 strnum) {
+ Save_Patterns(strv, strlenv, strnum);
+
+ for (uint32 i = 0; i < strnum; i++) {
+ Add_Pattern(strv[i], strlenv[i], i);
+ }
+
+ Propagate_faillink();
+ unsigned char* p = _root_char;
+
+ const ACS_Goto_Map& m = _root->Get_Goto_Map();
+ for (ACS_Goto_Map::const_iterator i = m.begin(), e = m.end();
+ i != e; i++) {
+ p[i->first] = 1;
+ }
+}
+
+Match_Result
+ACS_Constructor::MatchHelper(const char *str, uint32 len) const {
+ const ACS_State* root = _root;
+ const ACS_State* state = root;
+
+ uint32 idx = 0;
+ while (idx < len) {
+ InputTy c = str[idx];
+ idx++;
+ if (_root_char[c]) {
+ state = root->Get_Goto(c);
+ break;
+ }
+ }
+
+ if (unlikely(state->is_Terminal())) {
+ // This could happen if the one of the pattern has only one char!
+ uint32 pos = idx - 1;
+ Match_Result r(pos - state->Get_Depth() + 1, pos,
+ state->get_Pattern_Idx());
+ return r;
+ }
+
+ while (idx < len) {
+ InputTy c = str[idx];
+ ACS_State* gs = state->Get_Goto(c);
+
+ if (!gs) {
+ ACS_State* fl = state->Get_FailLink();
+ if (fl == root) {
+ while (idx < len) {
+ InputTy c = str[idx];
+ idx++;
+ if (_root_char[c]) {
+ state = root->Get_Goto(c);
+ break;
+ }
+ }
+ } else {
+ state = fl;
+ }
+ } else {
+ idx ++;
+ state = gs;
+ }
+
+ if (state->is_Terminal()) {
+ uint32 pos = idx - 1;
+ Match_Result r = Match_Result(pos - state->Get_Depth() + 1, pos,
+ state->get_Pattern_Idx());
+ return r;
+ }
+ }
+
+ return Match_Result(-1, -1, -1);
+}
+
+#ifdef DEBUG
+void
+ACS_Constructor::dump_text(const char* txtfile) const {
+ FILE* f = fopen(txtfile, "w+");
+ for (std::vector<ACS_State*>::const_iterator i = _all_states.begin(),
+ e = _all_states.end(); i != e; i++) {
+ ACS_State* s = *i;
+
+ fprintf(f, "S%d goto:{", s->Get_ID());
+ const ACS_Goto_Map& goto_func = s->Get_Goto_Map();
+
+ for (ACS_Goto_Map::const_iterator i = goto_func.begin(), e = goto_func.end();
+ i != e; i++) {
+ InputTy input = i->first;
+ ACS_State* tran = i->second;
+ if (isprint(input))
+ fprintf(f, "'%c' -> S:%d,", input, tran->Get_ID());
+ else
+ fprintf(f, "%#x -> S:%d,", input, tran->Get_ID());
+ }
+ fprintf(f, "} ");
+
+ if (s->_fail_link) {
+ fprintf(f, ", fail=S:%d", s->_fail_link->Get_ID());
+ }
+
+ if (s->_is_terminal) {
+ fprintf(f, ", terminal");
+ }
+
+ fprintf(f, "\n");
+ }
+ fclose(f);
+}
+
+void
+ACS_Constructor::dump_dot(const char *dotfile) const {
+ FILE* f = fopen(dotfile, "w+");
+ const char* indent = " ";
+
+ fprintf(f, "digraph G {\n");
+
+ // Emit node information
+ fprintf(f, "%s%d [style=filled];\n", indent, _root->Get_ID());
+ for (std::vector<ACS_State*>::const_iterator i = _all_states.begin(),
+ e = _all_states.end(); i != e; i++) {
+ ACS_State *s = *i;
+ if (s->_is_terminal) {
+ fprintf(f, "%s%d [shape=doublecircle];\n", indent, s->Get_ID());
+ }
+ }
+ fprintf(f, "\n");
+
+ // Emit edge information
+ for (std::vector<ACS_State*>::const_iterator i = _all_states.begin(),
+ e = _all_states.end(); i != e; i++) {
+ ACS_State* s = *i;
+ uint32 id = s->Get_ID();
+
+ const ACS_Goto_Map& m = s->Get_Goto_Map();
+ for (ACS_Goto_Map::const_iterator ii = m.begin(), ee = m.end();
+ ii != ee; ii++) {
+ InputTy input = ii->first;
+ ACS_State* tran = ii->second;
+ if (isalnum(input))
+ fprintf(f, "%s%d -> %d [label=%c];\n",
+ indent, id, tran->Get_ID(), input);
+ else
+ fprintf(f, "%s%d -> %d [label=\"%#x\"];\n",
+ indent, id, tran->Get_ID(), input);
+
+ }
+
+ // Emit fail-link
+ ACS_State* fl = s->Get_FailLink();
+ if (fl && fl != _root) {
+ fprintf(f, "%s%d -> %d [style=dotted, color=red]; \n",
+ indent, id, fl->Get_ID());
+ }
+ }
+ fprintf(f, "}\n");
+ fclose(f);
+}
+#endif
+
+#ifdef VERIFY
+void
+ACS_Constructor::Verify_Result(const char* subject, const Match_Result* r)
+ const {
+ if (r->begin >= 0) {
+ unsigned len = r->end - r->begin + 1;
+ int ptn_idx = r->pattern_idx;
+
+ ASSERT(ptn_idx >= 0 &&
+ len == get_ith_Pattern_Len(ptn_idx) &&
+ memcmp(subject + r->begin, get_ith_Pattern(ptn_idx), len) == 0);
+ }
+}
+
+void
+ACS_Constructor::Save_Patterns(const char** strv, unsigned int* strlenv,
+ int pattern_num) {
+ // calculate the total size needed to save all patterns.
+ //
+ int buf_size = 0;
+ for (int i = 0; i < pattern_num; i++) { buf_size += strlenv[i]; }
+
+ // HINT: patterns are delimited by '\0' in order to ease debugging.
+ buf_size += pattern_num;
+ ASSERT(_pattern_buf == 0);
+ _pattern_buf = new char[buf_size + 1];
+ #define MAGIC_NUM 0x5a
+ _pattern_buf[buf_size] = MAGIC_NUM;
+
+ int ofst = 0;
+ _pattern_lens.resize(pattern_num);
+ _pattern_vect.resize(pattern_num);
+ for (int i = 0; i < pattern_num; i++) {
+ int l = strlenv[i];
+ _pattern_lens[i] = l;
+ _pattern_vect[i] = _pattern_buf + ofst;
+
+ memcpy(_pattern_buf + ofst, strv[i], l);
+ ofst += l;
+ _pattern_buf[ofst++] = '\0';
+ }
+
+ ASSERT(_pattern_buf[buf_size] == MAGIC_NUM);
+ #undef MAGIC_NUM
+}
+
+#endif
diff --git a/modules/policy/lua-aho-corasick/ac_slow.hpp b/modules/policy/lua-aho-corasick/ac_slow.hpp
new file mode 100644
index 0000000..030b95d
--- /dev/null
+++ b/modules/policy/lua-aho-corasick/ac_slow.hpp
@@ -0,0 +1,158 @@
+#ifndef MY_AC_H
+#define MY_AC_H
+
+#include <string.h>
+#include <stdio.h>
+#include <map>
+#include <vector>
+#include <algorithm> // for std::sort
+#include "ac_util.hpp"
+
+// Forward decl. the acronym "ACS" stands for "Aho-Corasick Slow implementation"
+class ACS_State;
+class ACS_Constructor;
+class AhoCorasick;
+
+using namespace std;
+
+typedef std::map<InputTy, ACS_State*> ACS_Goto_Map;
+
+class Match_Result {
+public:
+ int begin;
+ int end;
+ int pattern_idx;
+ Match_Result(int b, int e, int p): begin(b), end(e), pattern_idx(p) {}
+};
+
+typedef pair<InputTy, ACS_State *> GotoPair;
+typedef vector<GotoPair> GotoVect;
+
+// Sorting functor
+class GotoSort {
+public:
+ bool operator() (const GotoPair& g1, const GotoPair& g2) {
+ return g1.first < g2.first;
+ }
+};
+
+class ACS_State {
+friend class ACS_Constructor;
+
+public:
+ ACS_State(uint32 id): _id(id), _pattern_idx(-1), _depth(0),
+ _is_terminal(false), _fail_link(0){}
+ ~ACS_State() {};
+
+ void Set_Goto(InputTy c, ACS_State* s) { _goto_map[c] = s; }
+ ACS_State *Get_Goto(InputTy c) const {
+ ACS_Goto_Map::const_iterator iter = _goto_map.find(c);
+ return iter != _goto_map.end() ? (*iter).second : 0;
+ }
+
+ // Return all transitions sorted in the ascending order of their input.
+ void Get_Sorted_Gotos(GotoVect& Gotos) const {
+ const ACS_Goto_Map& m = _goto_map;
+ Gotos.clear();
+ for (ACS_Goto_Map::const_iterator i = m.begin(), e = m.end();
+ i != e; i++) {
+ Gotos.push_back(GotoPair(i->first, i->second));
+ }
+ sort(Gotos.begin(), Gotos.end(), GotoSort());
+ }
+
+ ACS_State* Get_FailLink() const { return _fail_link; }
+ uint32 Get_GotoNum() const { return _goto_map.size(); }
+ uint32 Get_ID() const { return _id; }
+ uint32 Get_Depth() const { return _depth; }
+ const ACS_Goto_Map& Get_Goto_Map(void) const { return _goto_map; }
+ bool is_Terminal() const { return _is_terminal; }
+ int get_Pattern_Idx() const {
+ ASSERT(is_Terminal() && _pattern_idx >= 0);
+ return _pattern_idx;
+ }
+
+private:
+ void set_Pattern_Idx(int idx) {
+ ASSERT(is_Terminal());
+ _pattern_idx = idx;
+ }
+
+private:
+ uint32 _id;
+ int _pattern_idx;
+ short _depth;
+ bool _is_terminal;
+ ACS_Goto_Map _goto_map;
+ ACS_State* _fail_link;
+};
+
+class ACS_Constructor {
+public:
+ ACS_Constructor();
+ ~ACS_Constructor();
+
+ void Construct(const char** strv, unsigned int* strlenv,
+ unsigned int strnum);
+
+ Match_Result Match(const char* s, uint32 len) const {
+ Match_Result r = MatchHelper(s, len);
+ Verify_Result(s, &r);
+ return r;
+ }
+
+ Match_Result Match(const char* s) const { return Match(s, strlen(s)); }
+
+#ifdef DEBUG
+ void dump_text(const char* = "ac.txt") const;
+ void dump_dot(const char* = "ac.dot") const;
+#endif
+ const ACS_State *Get_Root_State() const { return _root; }
+ const vector<ACS_State*>& Get_All_States() const {
+ return _all_states;
+ }
+
+ uint32 Get_Next_Node_Id() const { return _next_node_id; }
+ uint32 Get_State_Num() const { return _next_node_id - 1; }
+
+private:
+ void Add_Pattern(const char* str, unsigned int str_len, int pattern_idx);
+ ACS_State* new_state();
+ void Propagate_faillink();
+
+ Match_Result MatchHelper(const char*, uint32 len) const;
+
+#ifdef VERIFY
+ void Verify_Result(const char* subject, const Match_Result* r) const;
+ void Save_Patterns(const char** strv, unsigned int* strlenv, int vect_len);
+ const char* get_ith_Pattern(unsigned i) const {
+ ASSERT(i < _pattern_vect.size());
+ return _pattern_vect.at(i);
+ }
+ unsigned get_ith_Pattern_Len(unsigned i) const {
+ ASSERT(i < _pattern_lens.size());
+ return _pattern_lens.at(i);
+ }
+#else
+ void Verify_Result(const char* subject, const Match_Result* r) const {
+ (void)subject; (void)r;
+ }
+ void Save_Patterns(const char** strv, unsigned int* strlenv, int vect_len) {
+ (void)strv; (void)strlenv;
+ }
+#endif
+
+private:
+ ACS_State* _root;
+ vector<ACS_State*> _all_states;
+ unsigned char* _root_char;
+ uint32 _next_node_id;
+
+#ifdef VERIFY
+ char* _pattern_buf;
+ vector<int> _pattern_lens;
+ vector<char*> _pattern_vect;
+#endif
+};
+
+#endif
diff --git a/modules/policy/lua-aho-corasick/ac_util.hpp b/modules/policy/lua-aho-corasick/ac_util.hpp
new file mode 100644
index 0000000..56fd46c
--- /dev/null
+++ b/modules/policy/lua-aho-corasick/ac_util.hpp
@@ -0,0 +1,69 @@
+/*
+ Copyright (c) 2014 CloudFlare, Inc. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following disclaimer
+ in the documentation and/or other materials provided with the
+ distribution.
+ * Neither the name of CloudFlare, Inc. nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+#ifndef AC_UTIL_H
+#define AC_UTIL_H
+
+#ifdef DEBUG
+#include <stdio.h> // for fprintf
+#include <stdlib.h> // for abort
+#endif
+
+typedef unsigned short uint16;
+typedef unsigned int uint32;
+typedef unsigned long uint64;
+typedef unsigned char InputTy;
+
+#ifdef DEBUG
+ // Usage examples: ASSERT(a > b), ASSERT(foo() && "Opps, foo() reutrn 0");
+ #define ASSERT(c) if (!(c))\
+ { fprintf(stderr, "%s:%d Assert: %s\n", __FILE__, __LINE__, #c); abort(); }
+#else
+ #define ASSERT(c) ((void)0)
+#endif
+
+#define likely(x) __builtin_expect((x),1)
+#define unlikely(x) __builtin_expect((x),0)
+
+#ifndef offsetof
+#define offsetof(st, m) ((size_t)(&((st *)0)->m))
+#endif
+
+typedef enum {
+ IMPL_SLOW_VARIANT = 1,
+ IMPL_FAST_VARIANT = 2,
+} impl_var_t;
+
+#define AC_MAGIC_NUM 0x5a
+typedef struct {
+ unsigned char magic_num;
+ unsigned char impl_variant;
+} buf_header_t;
+
+#endif //AC_UTIL_H
diff --git a/modules/policy/lua-aho-corasick/load_ac.lua b/modules/policy/lua-aho-corasick/load_ac.lua
new file mode 100644
index 0000000..eb70446
--- /dev/null
+++ b/modules/policy/lua-aho-corasick/load_ac.lua
@@ -0,0 +1,90 @@
+-- Helper wrappring script for loading shared object libac.so (FFI interface)
+-- from package.cpath instead of LD_LIBRARTY_PATH.
+--
+
+local ffi = require 'ffi'
+ffi.cdef[[
+ void* ac_create(const char** str_v, unsigned int* strlen_v,
+ unsigned int v_len);
+ int ac_match2(void*, const char *str, int len);
+ void ac_free(void*);
+]]
+
+local _M = {}
+
+local string_gmatch = string.gmatch
+local string_match = string.match
+
+local ac_lib = nil
+local ac_create = nil
+local ac_match = nil
+local ac_free = nil
+
+--[[ Find shared object file package.cpath, obviating the need of setting
+ LD_LIBRARY_PATH
+]]
+local function find_shared_obj(cpath, so_name)
+ for k, v in string_gmatch(cpath, "[^;]+") do
+ local so_path = string_match(k, "(.*/)")
+ if so_path then
+ -- "so_path" could be nil. e.g, the dir path component is "."
+ so_path = so_path .. so_name
+
+ -- Don't get me wrong, the only way to know if a file exist is
+ -- trying to open it.
+ local f = io.open(so_path)
+ if f ~= nil then
+ io.close(f)
+ return so_path
+ end
+ end
+ end
+end
+
+function _M.load_ac_lib()
+ if ac_lib ~= nil then
+ return ac_lib
+ else
+ local so_path = find_shared_obj(package.cpath, "libac.so")
+ if so_path ~= nil then
+ ac_lib = ffi.load(so_path)
+ ac_create = ac_lib.ac_create
+ ac_match = ac_lib.ac_match2
+ ac_free = ac_lib.ac_free
+ return ac_lib
+ end
+ end
+end
+
+-- Create an Aho-Corasick instance, and return the instance if it was
+-- successful.
+function _M.create_ac(dict)
+ local strnum = #dict
+ if ac_lib == nil then
+ _M.load_ac_lib()
+ end
+
+ local str_v = ffi.new("const char *[?]", strnum)
+ local strlen_v = ffi.new("unsigned int [?]", strnum)
+
+ for i = 1, strnum do
+ local s = dict[i]
+ str_v[i - 1] = s
+ strlen_v[i - 1] = #s
+ end
+
+ local ac = ac_create(str_v, strlen_v, strnum);
+ if ac ~= nil then
+ return ffi.gc(ac, ac_free)
+ end
+end
+
+-- Return nil if str doesn't match the dictionary, else return non-nil.
+function _M.match(ac, str)
+ local r = ac_match(ac, str, #str);
+ if r >= 0 then
+ return r
+ end
+end
+
+return _M
diff --git a/modules/policy/lua-aho-corasick/mytest.cxx b/modules/policy/lua-aho-corasick/mytest.cxx
new file mode 100644
index 0000000..ef3dc87
--- /dev/null
+++ b/modules/policy/lua-aho-corasick/mytest.cxx
@@ -0,0 +1,200 @@
+#include <stdio.h>
+#include <string.h>
+#include <vector>
+#include "ac.h"
+
+using namespace std;
+
+/////////////////////////////////////////////////////////////////////////
+//
+// Test using strings from input files
+//
+/////////////////////////////////////////////////////////////////////////
+//
+class BigFileTester {
+public:
+ BigFileTester(const char* filepath);
+
+private:
+ void Genector
+privaete:
+ const char* _msg;
+ int _msg_len;
+ int _key_num; // number of strings in dictionary
+ int _key_len_idx;
+};
+
+/////////////////////////////////////////////////////////////////////////
+//
+// Simple (yet maybe tricky) testings
+//
+/////////////////////////////////////////////////////////////////////////
+//
+typedef struct {
+ const char* str;
+ const char* match;
+} StrPair;
+
+typedef struct {
+ const char* name;
+ const char** dict;
+ StrPair* strpairs;
+ int dict_len;
+ int strpair_num;
+} TestingCase;
+
+class Tests {
+public:
+ Tests(const char* name,
+ const char* dict[], int dict_len,
+ StrPair strpairs[], int strpair_num) {
+ if (!_tests)
+ _tests = new vector<TestingCase>;
+
+ TestingCase tc;
+ tc.name = name;
+ tc.dict = dict;
+ tc.strpairs = strpairs;
+ tc.dict_len = dict_len;
+ tc.strpair_num = strpair_num;
+ _tests->push_back(tc);
+ }
+
+ static vector<TestingCase>* Get_Tests() { return _tests; }
+ static void Erase_Tests() { delete _tests; _tests = 0; }
+
+private:
+ static vector<TestingCase> *_tests;
+};
+
+vector<TestingCase>* Tests::_tests = 0;
+
+static void
+simple_test(void) {
+ int total = 0;
+ int fail = 0;
+
+ vector<TestingCase> *tests = Tests::Get_Tests();
+ if (!tests)
+ return 0;
+
+ for (vector<TestingCase>::iterator i = tests->begin(), e = tests->end();
+ i != e; i++) {
+ TestingCase& t = *i;
+ fprintf(stdout, ">Testing %s\nDictionary:[ ", t.name);
+ for (int i = 0, e = t.dict_len, need_break=0; i < e; i++) {
+ fprintf(stdout, "%s, ", t.dict[i]);
+ if (need_break++ == 16) {
+ fputs("\n ", stdout);
+ need_break = 0;
+ }
+ }
+ fputs("]\n", stdout);
+
+ /* Create the dictionary */
+ int dict_len = t.dict_len;
+ ac_t* ac = ac_create(t.dict, dict_len);
+
+ for (int ii = 0, ee = t.strpair_num; ii < ee; ii++, total++) {
+ const StrPair& sp = t.strpairs[ii];
+ const char *str = sp.str; // the string to be matched
+ const char *match = sp.match;
+
+ fprintf(stdout, "[%3d] Testing '%s' : ", total, str);
+
+ int len = strlen(str);
+ ac_result_t r = ac_match(ac, str, len);
+ int m_b = r.match_begin;
+ int m_e = r.match_end;
+
+ // The return value per se is insane.
+ if (m_b > m_e ||
+ ((m_b < 0 || m_e < 0) && (m_b != -1 || m_e != -1))) {
+ fprintf(stdout, "Insane return value (%d, %d)\n", m_b, m_e);
+ fail ++;
+ continue;
+ }
+
+ // If the string is not supposed to match the dictionary.
+ if (!match) {
+ if (m_b != -1 || m_e != -1) {
+ fail ++;
+ fprintf(stdout, "Not Supposed to match (%d, %d) \n",
+ m_b, m_e);
+ } else
+ fputs("Pass\n", stdout);
+ continue;
+ }
+
+ // The string or its substring is match the dict.
+ if (m_b >= len || m_b >= len) {
+ fail ++;
+ fprintf(stdout,
+ "Return value >= the length of the string (%d, %d)\n",
+ m_b, m_e);
+ continue;
+ } else {
+ int mlen = strlen(match);
+ if ((mlen != m_e - m_b + 1) ||
+ strncmp(str + m_b, match, mlen)) {
+ fail ++;
+ fprintf(stdout, "Fail\n");
+ } else
+ fprintf(stdout, "Pass\n");
+ }
+ }
+ fputs("\n", stdout);
+ ac_free(ac);
+ }
+
+ fprintf(stdout, "Total : %d, Fail %d\n", total, fail);
+
+ return fail ? -1 : 0;
+}
+
+int
+main (int argc, char** argv) {
+ int res = simple_test();
+ return res;
+};
+
+/* test 1*/
+const char *dict1[] = {"he", "she", "his", "her"};
+StrPair strpair1[] = {
+ {"he", "he"}, {"she", "she"}, {"his", "his"},
+ {"hers", "he"}, {"ahe", "he"}, {"shhe", "he"},
+ {"shis2", "his"}, {"ahhe", "he"}
+};
+Tests test1("test 1",
+ dict1, sizeof(dict1)/sizeof(dict1[0]),
+ strpair1, sizeof(strpair1)/sizeof(strpair1[0]));
+
+/* test 2*/
+const char *dict2[] = {"poto", "poto"}; /* duplicated strings*/
+StrPair strpair2[] = {{"The pot had a handle", 0}};
+Tests test2("test 2", dict2, 2, strpair2, 1);
+
+/* test 3*/
+const char *dict3[] = {"The"};
+StrPair strpair3[] = {{"The pot had a handle", "The"}};
+Tests test3("test 3", dict3, 1, strpair3, 1);
+
+/* test 4*/
+const char *dict4[] = {"pot"};
+StrPair strpair4[] = {{"The pot had a handle", "pot"}};
+Tests test4("test 4", dict4, 1, strpair4, 1);
+
+/* test 5*/
+const char *dict5[] = {"pot "};
+StrPair strpair5[] = {{"The pot had a handle", "pot "}};
+Tests test5("test 5", dict5, 1, strpair5, 1);
+
+/* test 6*/
+const char *dict6[] = {"ot h"};
+StrPair strpair6[] = {{"The pot had a handle", "ot h"}};
+Tests test6("test 6", dict6, 1, strpair6, 1);
+
+/* test 7*/
+const char *dict7[] = {"andle"};
+StrPair strpair7[] = {{"The pot had a handle", "andle"}};
+Tests test7("test 7", dict7, 1, strpair7, 1);
diff --git a/modules/policy/lua-aho-corasick/tests/Makefile b/modules/policy/lua-aho-corasick/tests/Makefile
new file mode 100644
index 0000000..54fd90f
--- /dev/null
+++ b/modules/policy/lua-aho-corasick/tests/Makefile
@@ -0,0 +1,65 @@
+OS := $(shell uname)
+ifeq ($(OS), Darwin)
+ SO_EXT := dylib
+else
+ SO_EXT := so
+endif
+
+.PHONY = all clean test runtest benchmark
+
+PROGRAM = ac_test
+BENCHMARK = ac_bench
+all: runtest
+
+CXXFLAGS = -O3 -g -march=native -Wall -DDEBUG
+MYCXXFLAGS = -MMD -I.. $(CXXFLAGS)
+%.o : %.cxx
+ $(CXX) $< -c $(MYCXXFLAGS)
+
+-include dep.cxx
+SRC = test_main.cxx ac_test_simple.cxx ac_test_aggr.cxx test_bigfile.cxx
+
+OBJ = ${SRC:.cxx=.o}
+
+-include test_dep.txt
+-include bench_dep.txt
+
+$(PROGRAM) $(BENCHMARK) : testinput/text.tar testinput/image.bin
+$(PROGRAM) : $(OBJ) ../libac.$(SO_EXT)
+ $(CXX) $(OBJ) -L.. -lac -o $@
+ -cat *.d > test_dep.txt
+
+$(BENCHMARK) : ac_bench.o ../libac.$(SO_EXT)
+ $(CXX) ac_bench.o -L.. -lac -o $@
+ -cat *.d > bench_dep.txt
+
+ifneq ($(OS), Darwin)
+runtest:$(PROGRAM)
+ LD_LIBRARY_PATH=$(LD_LIBRARY_PATH):.. ./$(PROGRAM) testinput/*
+
+benchmark:$(BENCHMARK)
+ LD_LIBRARY_PATH=$(LD_LIBRARY_PATH):.. ./ac_bench
+
+else
+runtest:$(PROGRAM)
+ DYLD_LIBRARY_PATH=$(DYLD_LIBRARY_PATH):.. ./$(PROGRAM) testinput/*
+
+benchmark:$(BENCHMARK)
+ DYLD_LIBRARY_PATH=$(DYLD_LIBRARY_PATH):.. ./ac_bench
+
+endif
+
+testinput/text.tar:
+ echo "download testing files (gcc tarball)..."
+ if [ ! -d testinput ] ; then mkdir testinput; fi
+ cd testinput && \
+ curl ftp://ftp.gnu.org/gnu/gcc/gcc-1.42.tar.gz -o text.tar.gz 2>/dev/null \
+ && gzip -d text.tar.gz
+
+testinput/image.bin:
+ echo "download testing files.."
+ if [ ! -d testinput ] ; then mkdir testinput; fi
+ curl http://www.3dvisionlive.com/sites/default/files/Curiosity_render_hiresb.jpg -o $@ 2>/dev/null
+
+clean:
+ -rm -f *.o *.d dep.txt $(PROGRAM) $(BENCHMARK)
diff --git a/modules/policy/lua-aho-corasick/tests/ac_bench.cxx b/modules/policy/lua-aho-corasick/tests/ac_bench.cxx
new file mode 100644
index 0000000..421322c
--- /dev/null
+++ b/modules/policy/lua-aho-corasick/tests/ac_bench.cxx
@@ -0,0 +1,519 @@
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <sys/time.h>
+#include <time.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <dirent.h>
+#include <libgen.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <getopt.h>
+
+#include <string>
+#include <vector>
+#include "ac.h"
+#include "ac_util.hpp"
+
+using namespace std;
+
+static bool SomethingWrong = false;
+
+static int iteration = 300;
+static string dict_dir;
+static string obj_file_dir;
+static bool print_help = false;
+static int piece_size = 1024;
+
+class PatternSet {
+public:
+ PatternSet(const char* filepath);
+ ~PatternSet() { Cleanup(); }
+
+ int getPatternNum() const { return _pat_num; }
+ const char** getPatternVector() const { return _patterns; }
+ unsigned int* getPatternLenVector() const { return _pat_len; }
+
+ const char* getErrMessage() const { return _errmsg; }
+ static bool isDictFile(const char* filepath) {
+ if (strncmp(basename(const_cast<char*>(filepath)), "dict", 4))
+ return false;
+ return true;
+ }
+
+private:
+ bool ExtractPattern(const char* filepath);
+ void Cleanup();
+
+ const char** _patterns;
+ unsigned int* _pat_len;
+ char* _mmap;
+ int _fd;
+ size_t _mmap_size;
+ int _pat_num;
+
+ const char* _errmsg;
+};
+
+bool
+PatternSet::ExtractPattern(const char* filepath) {
+ if (!isDictFile(filepath))
+ return false;
+
+ struct stat filestat;
+ if (stat(filepath, &filestat)) {
+ _errmsg = "fail to call stat()";
+ return false;
+ }
+
+ if (filestat.st_size > 4096 * 1024) {
+ /* It dosen't seem to be a dictionary file*/
+ _errmsg = "file too big?";
+ return false;
+ }
+
+ _fd = open(filepath, 0);
+ if (_fd == -1) {
+ _errmsg = "fail to open dictionary file";
+ return false;
+ }
+
+ _mmap_size = filestat.st_size;
+ _mmap = (char*)mmap(0, filestat.st_size, PROT_READ|PROT_WRITE,
+ MAP_PRIVATE, _fd, 0);
+ if (_mmap == MAP_FAILED) {
+ _errmsg = "fail to call mmap";
+ return false;
+ }
+
+ const char* pat = _mmap;
+ vector<const char*> pat_vect;
+ vector<unsigned> pat_len_vect;
+
+ for (size_t i = 0, e = filestat.st_size; i < e; i++) {
+ if (_mmap[i] == '\r' || _mmap[i] == '\n') {
+ _mmap[i] = '\0';
+ int len = _mmap + i - pat;
+ if (len > 0) {
+ pat_vect.push_back(pat);
+ pat_len_vect.push_back(len);
+ }
+ pat = _mmap + i + 1;
+ }
+ }
+
+ ASSERT(pat_vect.size() == pat_len_vect.size());
+
+ int pat_num = pat_vect.size();
+ if (pat_num > 0) {
+ const char** p = _patterns = new const char*[pat_num];
+ int i = 0;
+ for (vector<const char*>::iterator iter = pat_vect.begin(),
+ iter_e = pat_vect.end(); iter != iter_e; ++iter) {
+ p[i++] = *iter;
+ }
+
+ i = 0;
+ unsigned int* q = _pat_len = new unsigned int[pat_num];
+ for (vector<unsigned>::iterator iter = pat_len_vect.begin(),
+ iter_e = pat_len_vect.end(); iter != iter_e; ++iter) {
+ q[i++] = *iter;
+ }
+ }
+
+ _pat_num = pat_num;
+ if (pat_num <= 0) {
+ _errmsg = "no pattern at all";
+ return false;
+ }
+
+ return true;
+}
+
+void
+PatternSet::Cleanup() {
+ if (_mmap != MAP_FAILED) {
+ munmap(_mmap, _mmap_size);
+ _mmap = (char*)MAP_FAILED;
+ _mmap_size = 0;
+ }
+
+ delete[] _patterns;
+ delete[] _pat_len;
+ if (_fd != -1)
+ close(_fd);
+ _pat_num = -1;
+}
+
+PatternSet::PatternSet(const char* filepath) {
+ _patterns = 0;
+ _pat_len = 0;
+ _mmap = (char*)MAP_FAILED;
+ _mmap_size = 0;
+ _pat_num = -1;
+ _errmsg = "";
+
+ if (!ExtractPattern(filepath))
+ Cleanup();
+}
+
+bool
+getFilesUnderDir(vector<string>& files, const char* path) {
+ files.clear();
+
+ DIR* dir = opendir(path);
+ if (!dir)
+ return false;
+
+ string path_dir = path;
+ path_dir += "/";
+
+ for (;;) {
+ struct dirent* entry = readdir(dir);
+ if (entry) {
+ string filepath = path_dir + entry->d_name;
+ struct stat file_stat;
+ if (stat(filepath.c_str(), &file_stat)) {
+ closedir(dir);
+ return false;
+ }
+
+ if (S_ISREG(file_stat.st_mode))
+ files.push_back(filepath);
+
+ continue;
+ }
+
+ if (errno) {
+ return false;
+ }
+ break;
+ }
+ closedir(dir);
+ return true;
+}
+
+class Timer {
+public:
+ Timer() {
+ my_clock_gettime(&_start);
+ _stop = _start;
+ _acc.tv_sec = 0;
+ _acc.tv_nsec = 0;
+ }
+
+ const Timer& operator += (const Timer& that) {
+ time_t sec = _acc.tv_sec + that._acc.tv_sec;
+ long nsec = _acc.tv_nsec + that._acc.tv_nsec;
+ if (nsec > 1000000000) {
+ nsec -= 1000000000;
+ sec += 1;
+ }
+ _acc.tv_sec = sec;
+ _acc.tv_nsec = nsec;
+ return *this;
+ }
+
+ // return duration in us
+ size_t getDuration() const {
+ return _acc.tv_sec * (size_t)1000000 + _acc.tv_nsec/1000;
+ }
+
+ void Start(bool acc=true) {
+ my_clock_gettime(&_start);
+ }
+
+ void Stop() {
+ my_clock_gettime(&_stop);
+ struct timespec t = CalcDuration();
+ _acc = add_duration(_acc, t);
+ }
+
+private:
+ int my_clock_gettime(struct timespec* t) {
+#ifdef __linux
+ return clock_gettime(CLOCK_PROCESS_CPUTIME_ID, t);
+#else
+ struct timeval tv;
+ int rc = gettimeofday(&tv, 0);
+ t->tv_sec = tv.tv_sec;
+ t->tv_nsec = tv.tv_usec * 1000;
+ return rc;
+#endif
+ }
+
+ struct timespec add_duration(const struct timespec& dur1,
+ const struct timespec& dur2) {
+ time_t sec = dur1.tv_sec + dur2.tv_sec;
+ long nsec = dur1.tv_nsec + dur2.tv_nsec;
+ if (nsec > 1000000000) {
+ nsec -= 1000000000;
+ sec += 1;
+ }
+ timespec t;
+ t.tv_sec = sec;
+ t.tv_nsec = nsec;
+
+ return t;
+ }
+
+ struct timespec CalcDuration() const {
+ timespec diff;
+ if ((_stop.tv_nsec - _start.tv_nsec)<0) {
+ diff.tv_sec = _stop.tv_sec - _start.tv_sec - 1;
+ diff.tv_nsec = 1000000000 + _stop.tv_nsec - _start.tv_nsec;
+ } else {
+ diff.tv_sec = _stop.tv_sec - _start.tv_sec;
+ diff.tv_nsec = _stop.tv_nsec - _start.tv_nsec;
+ }
+ return diff;
+ }
+
+ struct timespec _start;
+ struct timespec _stop;
+ struct timespec _acc;
+};
+
+class Benchmark {
+public:
+ Benchmark(const PatternSet& pat_set, const char* infile):
+ _pat_set(pat_set), _infile(infile) {
+ _mmap = (char*)MAP_FAILED;
+ _file_sz = 0;
+ _fd = -1;
+ }
+
+ ~Benchmark() {
+ if (_mmap != MAP_FAILED)
+ munmap(_mmap, _file_sz);
+ if (_fd != -1)
+ close(_fd);
+ }
+
+ bool Run(int iteration);
+ const Timer& getTimer() const { return _timer; }
+
+private:
+ const PatternSet& _pat_set;
+ const char* _infile;
+ char* _mmap;
+ int _fd;
+ size_t _file_sz; // input file size
+ Timer _timer;
+};
+
+bool
+Benchmark::Run(int iteration) {
+ if (_pat_set.getPatternNum() <= 0) {
+ SomethingWrong = true;
+ return false;
+ }
+
+ if (_mmap == MAP_FAILED) {
+ struct stat filestat;
+ if (stat(_infile, &filestat)) {
+ SomethingWrong = true;
+ return false;
+ }
+
+ if (!S_ISREG(filestat.st_mode)) {
+ SomethingWrong = true;
+ return false;
+ }
+
+ _fd = open(_infile, 0);
+ if (_fd == -1)
+ return false;
+
+ _mmap = (char*)mmap(0, filestat.st_size, PROT_READ|PROT_WRITE,
+ MAP_PRIVATE, _fd, 0);
+
+ if (_mmap == MAP_FAILED) {
+ SomethingWrong = true;
+ return false;
+ }
+
+ _file_sz = filestat.st_size;
+ }
+
+ ac_t* ac = ac_create(_pat_set.getPatternVector(),
+ _pat_set.getPatternLenVector(),
+ _pat_set.getPatternNum());
+ if (!ac) {
+ SomethingWrong = true;
+ return false;
+ }
+
+ int piece_num = _file_sz/piece_size;
+
+ _timer.Start(false);
+
+ /* Stupid compiler may not be able to promote piece_size into register.
+ * Do it manually.
+ */
+ int piece_sz = piece_size;
+ for (int i = 0; i < iteration; i++) {
+ size_t match_ofst = 0;
+ for (int piece_idx = 0; piece_idx < piece_num; piece_idx ++) {
+ ac_match2(ac, _mmap + match_ofst, piece_sz);
+ match_ofst += piece_sz;
+ }
+ if (match_ofst != _file_sz)
+ ac_match2(ac, _mmap + match_ofst, _file_sz - match_ofst);
+ }
+ _timer.Stop();
+ return true;
+}
+
+const char* short_opt = "hd:f:i:p:";
+const struct option long_opts[] = {
+ {"help", no_argument, 0, 'h'},
+ {"iteration", required_argument, 0, 'i'},
+ {"dictionary-dir", required_argument, 0, 'd'},
+ {"obj-file-dir", required_argument, 0, 'f'},
+ {"piece-size", required_argument, 0, 'p'},
+};
+
+static void
+PrintHelp(const char* prog_name) {
+ const char* msg =
+"Usage %s [OPTIONS]\n"
+" -d, --dictionary-dir : specify the dictionary directory (./dict by default)\n"
+" -f, --obj-file-dir : specify the object file directory\n"
+" (./testinput by default)\n"
+" -i, --iteration : Run this many iteration for each pattern match\n"
+" -p, --piece-size : The size of 'piece' in byte. The input file is\n"
+" divided into pieces, and match function is working\n"
+" on one piece at a time. The default size of piece\n"
+" is 1k byte.\n";
+
+ fprintf(stdout, msg, prog_name);
+}
+
+static bool
+getOptions(int argc, char** argv) {
+ bool dict_dir_set = false;
+ bool objfile_dir_set = false;
+ int opt_index;
+
+ while (1) {
+ if (print_help) break;
+
+ int c = getopt_long(argc, argv, short_opt, long_opts, &opt_index);
+
+ if (c == -1) break;
+ if (c == 0) { c = long_opts[opt_index].val; }
+
+ switch(c) {
+ case 'h':
+ print_help = true;
+ break;
+
+ case 'i':
+ iteration = atol(optarg);
+ break;
+
+ case 'd':
+ dict_dir = optarg;
+ dict_dir_set = true;
+ break;
+
+ case 'f':
+ obj_file_dir = optarg;
+ objfile_dir_set = true;
+ break;
+
+ case 'p':
+ piece_size = atol(optarg);
+ break;
+
+ case '?':
+ default:
+ return false;
+ }
+ }
+
+ if (print_help)
+ return true;
+
+ string basedir(dirname(argv[0]));
+ if (!dict_dir_set)
+ dict_dir = basedir + "/dict";
+
+ if (!objfile_dir_set)
+ obj_file_dir = basedir + "/testinput";
+
+ return true;
+}
+
+int
+main(int argc, char** argv) {
+ if (!getOptions(argc, argv))
+ return -1;
+
+ if (print_help) {
+ PrintHelp(argv[0]);
+ return 0;
+ }
+
+#ifndef __linux
+ fprintf(stdout, "\n!!!WARNING: On this OS, the execution time is measured"
+ " by gettimeofday(2) which is imprecise!!!\n\n");
+#endif
+
+ fprintf(stdout, "Test with iteration = %d, piece size = %d, and",
+ iteration, piece_size);
+ fprintf(stdout, "\n dictionary dir = %s\n object file dir = %s\n\n",
+ dict_dir.c_str(), obj_file_dir.c_str());
+
+ vector<string> dict_files;
+ vector<string> input_files;
+
+ if (!getFilesUnderDir(dict_files, dict_dir.c_str())) {
+ fprintf(stdout, "fail to find dictionary files\n");
+ return -1;
+ }
+
+ if (!getFilesUnderDir(input_files, obj_file_dir.c_str())) {
+ fprintf(stdout, "fail to find test input files\n");
+ return -1;
+ }
+
+ for (vector<string>::iterator diter = dict_files.begin(),
+ diter_e = dict_files.end(); diter != diter_e; ++diter) {
+
+ const char* dict_name = diter->c_str();
+ if (!PatternSet::isDictFile(dict_name))
+ continue;
+
+ PatternSet ps(dict_name);
+ if (ps.getPatternNum() <= 0) {
+ fprintf(stdout, "fail to open dictionary file %s : %s\n",
+ dict_name, ps.getErrMessage());
+ SomethingWrong = true;
+ continue;
+ }
+
+ fprintf(stdout, "Using dictionary %s\n", dict_name);
+ Timer timer;
+ for (vector<string>::iterator iter = input_files.begin(),
+ iter_e = input_files.end(); iter != iter_e; ++iter) {
+ fprintf(stdout, " testing %s ... ", iter->c_str());
+ fflush(stdout);
+ Benchmark bm(ps, iter->c_str());
+ bm.Run(iteration);
+ const Timer& t = bm.getTimer();
+ timer += bm.getTimer();
+ fprintf(stdout, "elapsed %.3f\n", t.getDuration() / 1000000.0);
+ }
+
+ fprintf(stdout,
+ "\n==========================================================\n"
+ " Total Elapse %.3f\n\n", timer.getDuration() / 1000000.0);
+ }
+
+ return SomethingWrong ? -1 : 0;
+}
diff --git a/modules/policy/lua-aho-corasick/tests/ac_test_aggr.cxx b/modules/policy/lua-aho-corasick/tests/ac_test_aggr.cxx
new file mode 100644
index 0000000..4ea02bc
--- /dev/null
+++ b/modules/policy/lua-aho-corasick/tests/ac_test_aggr.cxx
@@ -0,0 +1,135 @@
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <vector>
+#include <string>
+
+#include "ac.h"
+#include "ac_util.hpp"
+#include "test_base.hpp"
+
+using namespace std;
+
+namespace {
+class ACBigFileTester : public BigFileTester {
+public:
+ ACBigFileTester(const char* filepath) : BigFileTester(filepath){};
+
+private:
+ virtual buf_header_t* PM_Create(const char** strv, uint32* strlenv,
+ uint32 vect_len) {
+ return (buf_header_t*)ac_create(strv, strlenv, vect_len);
+ }
+
+ virtual void PM_Free(buf_header_t* PM) { ac_free(PM); }
+ virtual bool Run_Helper(buf_header_t* PM);
+};
+
+class ACTestAggressive: public ACTestBase {
+public:
+ ACTestAggressive(const vector<const char*>& files, const char* banner)
+ : ACTestBase(banner), _files(files) {}
+ virtual bool Run();
+
+private:
+ void PrintSummary(int total, int fail) {
+ fprintf(stdout, "Test count : %d, fail: %d\n", total, fail);
+ fflush(stdout);
+ }
+ vector<const char*> _files;
+};
+
+} // end of anonymous namespace
+
+bool
+ACBigFileTester::Run_Helper(buf_header_t* PM) {
+ int fail = 0;
+ // advance one chunk at a time.
+ int len = _msg_len;
+ int chunk_sz = _chunk_sz;
+
+ vector<const char*> c_style_keys;
+ for (int i = 0, e = _keys.size(); i != e; i++) {
+ const char* key = _keys[i].first;
+ int len = _keys[i].second;
+ char *t = new char[len+1];
+ memcpy(t, key, len);
+ t[len] = '\0';
+ c_style_keys.push_back(t);
+ }
+
+ for (int ofst = 0, chunk_idx = 0, chunk_num = _chunk_num;
+ chunk_idx < chunk_num; ofst += chunk_sz, chunk_idx++) {
+ const char* substring = _msg + ofst;
+ ac_result_t r = ac_match((ac_t*)(void*)PM, substring , len - ofst);
+ int m_b = r.match_begin;
+ int m_e = r.match_end;
+
+ if (m_b < 0 || m_e < 0 || m_e <= m_b || m_e >= len) {
+ fprintf(stdout, "fail to find match substring[%d:%d])\n",
+ ofst, len - 1);
+ fail ++;
+ continue;
+ }
+
+ const char* match_str = _msg + len;
+ int strstr_len = 0;
+ int key_idx = -1;
+
+ for (int i = 0, e = c_style_keys.size(); i != e; i++) {
+ const char* key = c_style_keys[i];
+ if (const char *m = strstr(substring, key)) {
+ if (m < match_str) {
+ match_str = m;
+ strstr_len = _keys[i].second;
+ key_idx = i;
+ }
+ }
+ }
+ ASSERT(key_idx != -1);
+ if ((match_str - substring != m_b)) {
+ fprintf(stdout,
+ "Fail to find match substring[%d:%d]),"
+ " expected to find match at offset %d instead of %d\n",
+ ofst, len - 1,
+ (int)(match_str - _msg), ofst + m_b);
+ fprintf(stdout, "%d vs %d (key idx %d)\n", strstr_len, m_e - m_b + 1, key_idx);
+ PrintStr(stdout, match_str, strstr_len);
+ fprintf(stdout, "\n");
+ PrintStr(stdout, _msg + ofst + m_b,
+ m_e - m_b + 1);
+ fprintf(stdout, "\n");
+ fail ++;
+ }
+ }
+ for (vector<const char*>::iterator i = c_style_keys.begin(),
+ e = c_style_keys.end(); i != e; i++) {
+ delete[] *i;
+ }
+
+ return fail == 0;
+}
+
+bool
+ACTestAggressive::Run() {
+ int fail = 0;
+ for (vector<const char*>::iterator i = _files.begin(), e = _files.end();
+ i != e; i++) {
+ ACBigFileTester bft(*i);
+ if (!bft.Run())
+ fail ++;
+ }
+ return fail == 0;
+}
+
+bool
+Run_AC_Aggressive_Test(const vector<const char*>& files) {
+ ACTestAggressive t(files, "AC Aggressive test");
+ t.PrintBanner();
+ return t.Run();
+}
diff --git a/modules/policy/lua-aho-corasick/tests/ac_test_simple.cxx b/modules/policy/lua-aho-corasick/tests/ac_test_simple.cxx
new file mode 100644
index 0000000..fa2d7fd
--- /dev/null
+++ b/modules/policy/lua-aho-corasick/tests/ac_test_simple.cxx
@@ -0,0 +1,275 @@
+#include <stdio.h>
+#include <string.h>
+#include <vector>
+#include <string>
+
+#include "ac.h"
+#include "ac_util.hpp"
+#include "test_base.hpp"
+
+using namespace std;
+
+namespace {
+typedef struct {
+ const char* str;
+ const char* match;
+} StrPair;
+
+typedef enum {
+ MV_FIRST_MATCH = 0,
+ MV_LEFT_LONGEST = 1,
+} MatchVariant;
+
+typedef struct {
+ const char* name;
+ const char** dict;
+ StrPair* strpairs;
+ int dict_len;
+ int strpair_num;
+ MatchVariant match_variant;
+} TestingCase;
+
+class Tests {
+public:
+ Tests(const char* name,
+ const char* dict[], int dict_len,
+ StrPair strpairs[], int strpair_num,
+ MatchVariant mv = MV_FIRST_MATCH) {
+ if (!_tests)
+ _tests = new vector<TestingCase>;
+
+ TestingCase tc;
+ tc.name = name;
+ tc.dict = dict;
+ tc.strpairs = strpairs;
+ tc.dict_len = dict_len;
+ tc.strpair_num = strpair_num;
+ tc.match_variant = mv;
+ _tests->push_back(tc);
+ }
+
+ static vector<TestingCase>* Get_Tests() { return _tests; }
+ static void Erase_Tests() { delete _tests; _tests = 0; }
+
+private:
+ static vector<TestingCase> *_tests;
+};
+
+class LeftLongestTests : public Tests {
+public:
+ LeftLongestTests (const char* name, const char* dict[], int dict_len,
+ StrPair strpairs[], int strpair_num):
+ Tests(name, dict, dict_len, strpairs, strpair_num, MV_LEFT_LONGEST) {
+ }
+};
+
+vector<TestingCase>* Tests::_tests = 0;
+
+class ACTestSimple: public ACTestBase {
+public:
+ ACTestSimple(const char* banner) : ACTestBase(banner) {}
+ virtual bool Run();
+
+private:
+ void PrintSummary(int total, int fail) {
+ fprintf(stdout, "Test count : %d, fail: %d\n", total, fail);
+ fflush(stdout);
+ }
+};
+}
+
+bool
+ACTestSimple::Run() {
+ int total = 0;
+ int fail = 0;
+
+ vector<TestingCase> *tests = Tests::Get_Tests();
+ if (!tests) {
+ PrintSummary(0, 0);
+ return true;
+ }
+
+ for (vector<TestingCase>::iterator i = tests->begin(), e = tests->end();
+ i != e; i++) {
+ TestingCase& t = *i;
+ int dict_len = t.dict_len;
+ unsigned int* strlen_v = new unsigned int[dict_len];
+
+ fprintf(stdout, ">Testing %s\nDictionary:[ ", t.name);
+ for (int i = 0, need_break=0; i < dict_len; i++) {
+ const char* s = t.dict[i];
+ fprintf(stdout, "%s, ", s);
+ strlen_v[i] = strlen(s);
+ if (need_break++ == 16) {
+ fputs("\n ", stdout);
+ need_break = 0;
+ }
+ }
+ fputs("]\n", stdout);
+
+ /* Create the dictionary */
+ ac_t* ac = ac_create(t.dict, strlen_v, dict_len);
+ delete[] strlen_v;
+
+ for (int ii = 0, ee = t.strpair_num; ii < ee; ii++, total++) {
+ const StrPair& sp = t.strpairs[ii];
+ const char *str = sp.str; // the string to be matched
+ const char *match = sp.match;
+
+ fprintf(stdout, "[%3d] Testing '%s' : ", total, str);
+
+ int len = strlen(str);
+ ac_result_t r;
+ if (t.match_variant == MV_FIRST_MATCH)
+ r = ac_match(ac, str, len);
+ else if (t.match_variant == MV_LEFT_LONGEST)
+ r = ac_match_longest_l(ac, str, len);
+ else {
+ ASSERT(false && "Unknown variant");
+ }
+
+ int m_b = r.match_begin;
+ int m_e = r.match_end;
+
+ // The return value per se is insane.
+ if (m_b > m_e ||
+ ((m_b < 0 || m_e < 0) && (m_b != -1 || m_e != -1))) {
+ fprintf(stdout, "Insane return value (%d, %d)\n", m_b, m_e);
+ fail ++;
+ continue;
+ }
+
+ // If the string is not supposed to match the dictionary.
+ if (!match) {
+ if (m_b != -1 || m_e != -1) {
+ fail ++;
+ fprintf(stdout, "Not Supposed to match (%d, %d) \n",
+ m_b, m_e);
+ } else
+ fputs("Pass\n", stdout);
+ continue;
+ }
+
+ // The string or its substring is match the dict.
+ if (m_b >= len || m_b >= len) {
+ fail ++;
+ fprintf(stdout,
+ "Return value >= the length of the string (%d, %d)\n",
+ m_b, m_e);
+ continue;
+ } else {
+ int mlen = strlen(match);
+ if ((mlen != m_e - m_b + 1) ||
+ strncmp(str + m_b, match, mlen)) {
+ fail ++;
+ fprintf(stdout, "Fail\n");
+ } else
+ fprintf(stdout, "Pass\n");
+ }
+ }
+ fputs("\n", stdout);
+ ac_free(ac);
+ }
+
+ PrintSummary(total, fail);
+ return fail == 0;
+}
+
+bool
+Run_AC_Simple_Test() {
+ ACTestSimple t("AC Simple test");
+ t.PrintBanner();
+ return t.Run();
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// Testing cases for first-match variant (i.e. test ac_match())
+//
+//////////////////////////////////////////////////////////////////////////////
+//
+
+/* test 1*/
+const char *dict1[] = {"he", "she", "his", "her"};
+StrPair strpair1[] = {
+ {"he", "he"}, {"she", "she"}, {"his", "his"},
+ {"hers", "he"}, {"ahe", "he"}, {"shhe", "he"},
+ {"shis2", "his"}, {"ahhe", "he"}
+};
+Tests test1("test 1",
+ dict1, sizeof(dict1)/sizeof(dict1[0]),
+ strpair1, sizeof(strpair1)/sizeof(strpair1[0]));
+
+/* test 2*/
+const char *dict2[] = {"poto", "poto"}; /* duplicated strings*/
+StrPair strpair2[] = {{"The pot had a handle", 0}};
+Tests test2("test 2", dict2, 2, strpair2, 1);
+
+/* test 3*/
+const char *dict3[] = {"The"};
+StrPair strpair3[] = {{"The pot had a handle", "The"}};
+Tests test3("test 3", dict3, 1, strpair3, 1);
+
+/* test 4*/
+const char *dict4[] = {"pot"};
+StrPair strpair4[] = {{"The pot had a handle", "pot"}};
+Tests test4("test 4", dict4, 1, strpair4, 1);
+
+/* test 5*/
+const char *dict5[] = {"pot "};
+StrPair strpair5[] = {{"The pot had a handle", "pot "}};
+Tests test5("test 5", dict5, 1, strpair5, 1);
+
+/* test 6*/
+const char *dict6[] = {"ot h"};
+StrPair strpair6[] = {{"The pot had a handle", "ot h"}};
+Tests test6("test 6", dict6, 1, strpair6, 1);
+
+/* test 7*/
+const char *dict7[] = {"andle"};
+StrPair strpair7[] = {{"The pot had a handle", "andle"}};
+Tests test7("test 7", dict7, 1, strpair7, 1);
+
+const char *dict8[] = {"aaab"};
+StrPair strpair8[] = {{"aaaaaaab", "aaab"}};
+Tests test8("test 8", dict8, 1, strpair8, 1);
+
+const char *dict9[] = {"haha", "z"};
+StrPair strpair9[] = {{"aaaaz", "z"}, {"z", "z"}};
+Tests test9("test 9", dict9, 2, strpair9, 2);
+
+/* test the case when input string dosen't contain even a single char
+ * of the pattern in dictionary.
+ */
+const char *dict10[] = {"abc"};
+StrPair strpair10[] = {{"cde", 0}};
+Tests test10("test 10", dict10, 1, strpair10, 1);
+
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// Testing cases for first longest match variant (i.e.
+// test ac_match_longest_l())
+//
+//////////////////////////////////////////////////////////////////////////////
+//
+
+// This was actually first motivation for left-longest-match
+const char *dict100[] = {"Mozilla", "Mozilla Mobile"};
+StrPair strpair100[] = {{"User Agent containing string Mozilla Mobile", "Mozilla Mobile"}};
+LeftLongestTests test100("l_test 100", dict100, 2, strpair100, 1);
+
+// Dict with single char is tricky
+const char *dict101[] = {"a", "abc"};
+StrPair strpair101[] = {{"abcdef", "abc"}};
+LeftLongestTests test101("l_test 101", dict101, 2, strpair101, 1);
+
+// Testing case with partially overlapping patterns. The purpose is to
+// check if the fail-link leading from terminal state is correct.
+//
+// The fail-link leading from terminal-state does not matter in
+// match-first-occurrence variant, as it stop when a terminal is hit.
+//
+const char *dict102[] = {"abc", "bcdef"};
+StrPair strpair102[] = {{"abcdef", "bcdef"}};
+LeftLongestTests test102("l_test 102", dict102, 2, strpair102, 1);
diff --git a/modules/policy/lua-aho-corasick/tests/dict/README.txt b/modules/policy/lua-aho-corasick/tests/dict/README.txt
new file mode 100644
index 0000000..cd50b41
--- /dev/null
+++ b/modules/policy/lua-aho-corasick/tests/dict/README.txt
@@ -0,0 +1 @@
+This directory contains pattern set of benchmark purpose.
diff --git a/modules/policy/lua-aho-corasick/tests/dict/dict1.txt b/modules/policy/lua-aho-corasick/tests/dict/dict1.txt
new file mode 100644
index 0000000..94085a9
--- /dev/null
+++ b/modules/policy/lua-aho-corasick/tests/dict/dict1.txt
@@ -0,0 +1,11 @@
+false_return@
+forloop#haha
+wtfprogram
+mmaporunmap
+ThIs?Module!IsEssential
+struct rtlwtf
+gettIMEOfdayWrong
+edistribution_and_use_in_@source
+Copyright~#@
+while {!
+!%SQLinje
diff --git a/modules/policy/lua-aho-corasick/tests/load_ac_test.lua b/modules/policy/lua-aho-corasick/tests/load_ac_test.lua
new file mode 100644
index 0000000..7fb7db9
--- /dev/null
+++ b/modules/policy/lua-aho-corasick/tests/load_ac_test.lua
@@ -0,0 +1,82 @@
+-- This script is to test load_ac.lua
+--
+-- Some notes:
+-- 1. The purpose of this script is not to check if the libac.so work
+-- properly, it is to check if there are something stupid in load_ac.lua
+--
+-- 2. There are bunch of collectgarbage() calls, the purpose is to make
+-- sure the shared lib is not unloaded after GC.
+
+-- load_ac.lua looks up libac.so via package.cpath rather than LD_LIBRARY_PATH,
+-- prepend (instead of appending) some insane paths here to see if it quit
+-- prematurely.
+--
+package.cpath = ".;./?.so;" .. package.cpath
+
+local ac = require "load_ac"
+
+local ac_create = ac.create_ac
+local ac_match = ac.match
+local string_fmt = string.format
+local string_sub = string.sub
+
+local err_cnt = 0
+local function mytest(testname, dict, match, notmatch)
+ print(">Testing ", testname)
+
+ io.write(string_fmt("Dictionary: "));
+ for i=1, #dict do
+ io.write(string_fmt("%s, ", dict[i]))
+ end
+ print ""
+
+ local ac_inst = ac_create(dict);
+ collectgarbage()
+ for i=1, #match do
+ local str = match[i]
+ io.write(string_fmt("Matching %s, ", str))
+ local b = ac_match(ac_inst, str)
+ if b then
+ print "pass"
+ else
+ err_cnt = err_cnt + 1
+ print "fail"
+ end
+ collectgarbage()
+ end
+
+ if notmatch == nil then
+ return
+ end
+
+ collectgarbage()
+
+ for i = 1, #notmatch do
+ local str = notmatch[i]
+ io.write(string_fmt("*Matching %s, ", str))
+ local r = ac_match(ac_inst, str)
+ if r then
+ err_cnt = err_cnt + 1
+ print("fail")
+ else
+ print("succ")
+ end
+ collectgarbage()
+ end
+ ac_inst = nil
+ collectgarbage()
+end
+
+print("")
+print("====== Test to see if load_ac.lua works properly ========")
+
+mytest("test1",
+ {"he", "she", "his", "her", "str\0ing"},
+ -- matching cases
+ { "he", "she", "his", "hers", "ahe", "shhe", "shis2", "ahhe", "str\0ing" },
+
+ -- not matching case
+ {"str\0", "str"}
+ )
+
+os.exit((err_cnt == 0) and 0 or 1)
diff --git a/modules/policy/lua-aho-corasick/tests/lua_test.lua b/modules/policy/lua-aho-corasick/tests/lua_test.lua
new file mode 100644
index 0000000..cfe178f
--- /dev/null
+++ b/modules/policy/lua-aho-corasick/tests/lua_test.lua
@@ -0,0 +1,67 @@
+-- This script is to test ahocorasick.so not libac.so
+--
+local ac = require "ahocorasick"
+
+local ac_create = ac.create
+local ac_match = ac.match
+local string_fmt = string.format
+local string_sub = string.sub
+
+local err_cnt = 0
+local function mytest(testname, dict, match, notmatch)
+ print(">Testing ", testname)
+
+ io.write(string_fmt("Dictionary: "));
+ for i=1, #dict do
+ io.write(string_fmt("%s, ", dict[i]))
+ end
+ print ""
+
+ local ac_inst = ac_create(dict);
+ for i=1, #match do
+ local str = match[i][1]
+ local substr = match[i][2]
+ io.write(string_fmt("Matching %s, ", str))
+ local b, e = ac_match(ac_inst, str)
+ if b and e and (string_sub(str, b+1, e+1) == substr) then
+ print "pass"
+ else
+ err_cnt = err_cnt + 1
+ print "fail"
+ end
+ --print("gc is called")
+ collectgarbage()
+ end
+
+ if notmatch == nil then
+ return
+ end
+
+ for i = 1, #notmatch do
+ local str = notmatch[i]
+ io.write(string_fmt("*Matching %s, ", str))
+ local r = ac_match(ac_inst, str)
+ if r then
+ err_cnt = err_cnt + 1
+ print("fail")
+ else
+ print("succ")
+ end
+ collectgarbage()
+ end
+end
+
+mytest("test1",
+ {"he", "she", "his", "her", "str\0ing"},
+ -- matching cases
+ { {"he", "he"}, {"she", "she"}, {"his", "his"}, {"hers", "he"},
+ {"ahe", "he"}, {"shhe", "he"}, {"shis2", "his"}, {"ahhe", "he"},
+ {"str\0ing", "str\0ing"}
+ },
+
+ -- not matching case
+ {"str\0", "str"}
+
+ )
+
+os.exit((err_cnt == 0) and 0 or 1)
diff --git a/modules/policy/lua-aho-corasick/tests/test_base.hpp b/modules/policy/lua-aho-corasick/tests/test_base.hpp
new file mode 100644
index 0000000..7758371
--- /dev/null
+++ b/modules/policy/lua-aho-corasick/tests/test_base.hpp
@@ -0,0 +1,60 @@
+#ifndef TEST_BASE_H
+#define TEST_BASE_H
+
+#include <stdio.h>
+#include <string>
+#include <stdint.h>
+
+using namespace std;
+class ACTestBase {
+public:
+ ACTestBase(const char* name) :_banner(name) {}
+ virtual void PrintBanner() {
+ fprintf(stdout, "\n===== %s ====\n", _banner.c_str());
+ }
+
+ virtual bool Run() = 0;
+private:
+ string _banner;
+};
+
+typedef std::pair<const char*, int> StrInfo;
+class BigFileTester {
+public:
+ BigFileTester(const char* filepath);
+ virtual ~BigFileTester() { Cleanup(); }
+
+ bool Run();
+
+protected:
+ virtual buf_header_t* PM_Create(const char** strv, uint32_t* strlenv,
+ uint32_t vect_len) = 0;
+ virtual void PM_Free(buf_header_t*) = 0;
+ virtual bool Run_Helper(buf_header_t* PM) = 0;
+
+ // Return true if the '\0' is valid char of a string.
+ virtual bool Str_C_Style() { return true; }
+
+ bool GenerateKeys();
+ void Cleanup();
+ void PrintStr(FILE*, const char* str, int len);
+
+protected:
+ const char* _filepath;
+ int _fd;
+ vector<StrInfo> _keys;
+ char* _msg;
+ int _msg_len;
+ int _key_num; // number of strings in dictionary
+ int _chunk_sz;
+ int _chunk_num;
+
+ int _max_key_num;
+ int _key_min_len;
+ int _key_max_len;
+};
+
+extern bool Run_AC_Simple_Test();
+extern bool Run_AC_Aggressive_Test(const vector<const char*>& files);
+
+#endif
diff --git a/modules/policy/lua-aho-corasick/tests/test_bigfile.cxx b/modules/policy/lua-aho-corasick/tests/test_bigfile.cxx
new file mode 100644
index 0000000..f189d8d
--- /dev/null
+++ b/modules/policy/lua-aho-corasick/tests/test_bigfile.cxx
@@ -0,0 +1,167 @@
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <vector>
+#include <string>
+
+#include "ac.h"
+#include "ac_util.hpp"
+#include "test_base.hpp"
+
+///////////////////////////////////////////////////////////////////////////
+//
+// Implementation of BigFileTester
+//
+///////////////////////////////////////////////////////////////////////////
+//
+BigFileTester::BigFileTester(const char* filepath) {
+ _filepath = filepath;
+ _fd = -1;
+ _msg = (char*)MAP_FAILED;
+ _msg_len = 0;
+ _key_num = 0;
+ _chunk_sz = 0;
+ _chunk_num = 0;
+
+ _max_key_num = 100;
+ _key_min_len = 20;
+ _key_max_len = 80;
+}
+
+void
+BigFileTester::Cleanup() {
+ if (_msg != MAP_FAILED) {
+ munmap((void*)_msg, _msg_len);
+ _msg = (char*)MAP_FAILED;
+ _msg_len = 0;
+ }
+
+ if (_fd != -1) {
+ close(_fd);
+ _fd = -1;
+ }
+}
+
+bool
+BigFileTester::GenerateKeys() {
+ int chunk_sz = 4096;
+ int max_key_num = _max_key_num;
+ int key_min_len = _key_min_len;
+ int key_max_len = _key_max_len;
+
+ int t = _msg_len / chunk_sz;
+ int keynum = t > max_key_num ? max_key_num : t;
+
+ if (keynum <= 4) {
+ // file is too small
+ return false;
+ }
+ chunk_sz = _msg_len / keynum;
+ _chunk_sz = chunk_sz;
+
+ // For each chunck, "randomly" grab a sub-string searving
+ // as key.
+ int random_ofst[] = { 12, 30, 23, 15 };
+ int rofstsz = sizeof(random_ofst)/sizeof(random_ofst[0]);
+ int ofst = 0;
+ const char* msg = _msg;
+ _chunk_num = keynum - 1;
+ for (int idx = 0, e = _chunk_num; idx < e; idx++) {
+ const char* key = msg + ofst + idx % rofstsz;
+ int key_len = key_min_len + idx % (key_max_len - key_min_len);
+ _keys.push_back(StrInfo(key, key_len));
+ ofst += chunk_sz;
+ }
+ return true;
+}
+
+bool
+BigFileTester::Run() {
+ // Step 1: Bring the file into memory
+ fprintf(stdout, "Testing using file '%s'...\n", _filepath);
+
+ int fd = _fd = ::open(_filepath, O_RDONLY);
+ if (fd == -1) {
+ perror("open");
+ return false;
+ }
+
+ struct stat sb;
+ if (fstat(fd, &sb) == -1) {
+ perror("fstat");
+ return false;
+ }
+
+ if (!S_ISREG (sb.st_mode)) {
+ fprintf(stderr, "%s is not regular file\n", _filepath);
+ return false;
+ }
+
+ int ten_M = 1024 * 1024 * 10;
+ int map_sz = _msg_len = sb.st_size > ten_M ? ten_M : sb.st_size;
+ char* p = _msg =
+ (char*)mmap (0, map_sz, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0);
+ if (p == MAP_FAILED) {
+ perror("mmap");
+ return false;
+ }
+
+ // Get rid of '\0' if we are picky at it.
+ if (Str_C_Style()) {
+ for (int i = 0; i < map_sz; i++) { if (!p[i]) p[i] = 'a'; }
+ p[map_sz - 1] = 0;
+ }
+
+ // Step 2: "Fabricate" some keys from the file.
+ if (!GenerateKeys()) {
+ close(fd);
+ return false;
+ }
+
+ // Step 3: Create PM instance
+ const char** keys = new const char*[_keys.size()];
+ unsigned int* keylens = new unsigned int[_keys.size()];
+
+ int i = 0;
+ for (vector<StrInfo>::iterator si = _keys.begin(), se = _keys.end();
+ si != se; si++, i++) {
+ const StrInfo& strinfo = *si;
+ keys[i] = strinfo.first;
+ keylens[i] = strinfo.second;
+ }
+
+ buf_header_t* PM = PM_Create(keys, keylens, i);
+ delete[] keys;
+ delete[] keylens;
+
+ // Step 4: Run testing
+ bool res = Run_Helper(PM);
+ PM_Free(PM);
+
+ // Step 5: Clanup
+ munmap(p, map_sz);
+ _msg = (char*)MAP_FAILED;
+ close(fd);
+ _fd = -1;
+
+ fprintf(stdout, "%s\n", res ? "succ" : "fail");
+ return res;
+}
+
+void
+BigFileTester::PrintStr(FILE* f, const char* str, int len) {
+ fprintf(f, "{");
+ for (int i = 0; i < len; i++) {
+ unsigned char c = str[i];
+ if (isprint(c))
+ fprintf(f, "'%c', ", c);
+ else
+ fprintf(f, "%#x, ", c);
+ }
+ fprintf(f, "}");
+};
diff --git a/modules/policy/lua-aho-corasick/tests/test_main.cxx b/modules/policy/lua-aho-corasick/tests/test_main.cxx
new file mode 100644
index 0000000..b4f5225
--- /dev/null
+++ b/modules/policy/lua-aho-corasick/tests/test_main.cxx
@@ -0,0 +1,33 @@
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <vector>
+#include <string>
+#include "ac.h"
+#include "ac_util.hpp"
+#include "test_base.hpp"
+
+using namespace std;
+
+
+/////////////////////////////////////////////////////////////////////////
+//
+// Simple (yet maybe tricky) testings
+//
+/////////////////////////////////////////////////////////////////////////
+//
+int
+main (int argc, char** argv) {
+ bool succ = Run_AC_Simple_Test();
+
+ vector<const char*> files;
+ for (int i = 1; i < argc; i++) { files.push_back(argv[i]); }
+ succ = Run_AC_Aggressive_Test(files) && succ;
+
+ return succ ? 0 : -1;
+};
diff --git a/modules/policy/meson.build b/modules/policy/meson.build
new file mode 100644
index 0000000..37f1683
--- /dev/null
+++ b/modules/policy/meson.build
@@ -0,0 +1,50 @@
+# LUA module: policy
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+lua_mod_src += [
+ files('policy.lua'),
+]
+
+config_tests += [
+ ['policy', files('policy.test.lua')],
+ ['policy.slice', files('policy.slice.test.lua')],
+ ['policy.rpz', files('policy.rpz.test.lua')],
+]
+
+integr_tests += [
+ ['policy', meson.current_source_dir() / 'test.integr'],
+ ['policy.noipv6', meson.current_source_dir() / 'noipv6.test.integr'],
+ ['policy.noipvx', meson.current_source_dir() / 'noipvx.test.integr'],
+]
+
+# check git submodules were initialized
+lua_ac_submodule = run_command(['test', '-r',
+ '@0@/lua-aho-corasick/ac_fast.cxx'.format(meson.current_source_dir())],
+ check: false)
+if lua_ac_submodule.returncode() != 0
+ error('run "git submodule update --init --recursive" to initialize git submodules')
+endif
+
+# compile bundled lua-aho-corasick as shared module
+lua_ac_src = files([
+ 'lua-aho-corasick/ac_fast.cxx',
+ 'lua-aho-corasick/ac_lua.cxx',
+ 'lua-aho-corasick/ac_slow.cxx',
+])
+
+lua_ac_lib = shared_module(
+ 'ahocorasick',
+ lua_ac_src,
+ cpp_args: [
+ '-fvisibility=hidden',
+ '-Wall',
+ '-fPIC',
+ ],
+ dependencies: [
+ luajit_inc,
+ ],
+ include_directories: mod_inc_dir,
+ name_prefix: '',
+ install: true,
+ install_dir: lib_dir,
+)
diff --git a/modules/policy/noipv6.test.integr/broken-ipv6.rpl b/modules/policy/noipv6.test.integr/broken-ipv6.rpl
new file mode 100644
index 0000000..cb0738d
--- /dev/null
+++ b/modules/policy/noipv6.test.integr/broken-ipv6.rpl
@@ -0,0 +1,47 @@
+; config options
+; SPDX-License-Identifier: GPL-3.0-or-later
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test that IPv6 is not used by kresd.
+
+RANGE_BEGIN 0 100
+ ADDRESS ::1:2:3:4
+RANGE_END
+
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.test.org A
+SECTION ANSWER
+www.test.org 3600 A 4.3.2.1
+ENTRY_END
+
+RANGE_END
+
+
+STEP 10 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+www.test.org A
+ENTRY_END
+
+STEP 20 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all answer
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.test.org A
+SECTION ANSWER
+www.test.org 3600 A 4.3.2.1
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+SCENARIO_END
diff --git a/modules/policy/noipv6.test.integr/deckard.yaml b/modules/policy/noipv6.test.integr/deckard.yaml
new file mode 100644
index 0000000..4c1b6f8
--- /dev/null
+++ b/modules/policy/noipv6.test.integr/deckard.yaml
@@ -0,0 +1,12 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+programs:
+- name: kresd
+ binary: kresd
+ additional:
+ - --noninteractive
+ templates:
+ - modules/policy/noipv6.test.integr/kresd_config.j2
+ - tests/integration/hints_zone.j2
+ configs:
+ - config
+ - hints
diff --git a/modules/policy/noipv6.test.integr/kresd_config.j2 b/modules/policy/noipv6.test.integr/kresd_config.j2
new file mode 100644
index 0000000..a897d17
--- /dev/null
+++ b/modules/policy/noipv6.test.integr/kresd_config.j2
@@ -0,0 +1,59 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+{% raw %}
+net.ipv6 = false
+policy.add(policy.all(policy.STUB({ '::1:2:3:4', '1.2.3.4' })))
+
+-- make sure DNSSEC is turned off for tests
+trust_anchors.remove('.')
+
+-- Disable RFC5011 TA update
+if ta_update then
+ modules.unload('ta_update')
+end
+
+-- Disable RFC8145 signaling, scenario doesn't provide expected answers
+if ta_signal_query then
+ modules.unload('ta_signal_query')
+end
+
+-- Disable RFC8109 priming, scenario doesn't provide expected answers
+if priming then
+ modules.unload('priming')
+end
+
+-- Disable this module because it make one priming query
+if detect_time_skew then
+ modules.unload('detect_time_skew')
+end
+
+_hint_root_file('hints')
+cache.size = 2*MB
+log_level('debug')
+{% endraw %}
+
+net = { '{{SELF_ADDR}}' }
+
+
+{% if QMIN == "false" %}
+option('NO_MINIMIZE', true)
+{% else %}
+option('NO_MINIMIZE', false)
+{% endif %}
+
+
+-- Self-checks on globals
+assert(help() ~= nil)
+assert(worker.id ~= nil)
+-- Self-checks on facilities
+assert(cache.count() == 0)
+assert(cache.stats() ~= nil)
+assert(cache.backends() ~= nil)
+assert(worker.stats() ~= nil)
+assert(net.interfaces() ~= nil)
+-- Self-checks on loaded stuff
+assert(net.list()[1].transport.ip == '{{SELF_ADDR}}')
+assert(#modules.list() > 0)
+-- Self-check timers
+ev = event.recurrent(1 * sec, function (ev) return 1 end)
+event.cancel(ev)
+ev = event.after(0, function (ev) return 1 end)
diff --git a/modules/policy/noipvx.test.integr/broken-ipvx.rpl b/modules/policy/noipvx.test.integr/broken-ipvx.rpl
new file mode 100644
index 0000000..60ed618
--- /dev/null
+++ b/modules/policy/noipvx.test.integr/broken-ipvx.rpl
@@ -0,0 +1,35 @@
+; config options
+; SPDX-License-Identifier: GPL-3.0-or-later
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test that neither IPv6 nor IPv4 is used by kresd :-)
+
+RANGE_BEGIN 0 100
+ ADDRESS ::1:2:3:4
+RANGE_END
+
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+RANGE_END
+
+
+STEP 10 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+www.test.org A
+ENTRY_END
+
+STEP 20 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all answer
+REPLY QR RD RA SERVFAIL
+SECTION QUESTION
+www.test.org A
+SECTION ANSWER
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+SCENARIO_END
diff --git a/modules/policy/noipvx.test.integr/deckard.yaml b/modules/policy/noipvx.test.integr/deckard.yaml
new file mode 100644
index 0000000..8178759
--- /dev/null
+++ b/modules/policy/noipvx.test.integr/deckard.yaml
@@ -0,0 +1,12 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+programs:
+- name: kresd
+ binary: kresd
+ additional:
+ - --noninteractive
+ templates:
+ - modules/policy/noipvx.test.integr/kresd_config.j2
+ - tests/integration/hints_zone.j2
+ configs:
+ - config
+ - hints
diff --git a/modules/policy/noipvx.test.integr/kresd_config.j2 b/modules/policy/noipvx.test.integr/kresd_config.j2
new file mode 100644
index 0000000..87873e8
--- /dev/null
+++ b/modules/policy/noipvx.test.integr/kresd_config.j2
@@ -0,0 +1,60 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+{% raw %}
+net.ipv4 = false
+net.ipv6 = false
+policy.add(policy.all(policy.STUB({ '::1:2:3:4', '1.2.3.4' })))
+
+-- make sure DNSSEC is turned off for tests
+trust_anchors.remove('.')
+
+-- Disable RFC5011 TA update
+if ta_update then
+ modules.unload('ta_update')
+end
+
+-- Disable RFC8145 signaling, scenario doesn't provide expected answers
+if ta_signal_query then
+ modules.unload('ta_signal_query')
+end
+
+-- Disable RFC8109 priming, scenario doesn't provide expected answers
+if priming then
+ modules.unload('priming')
+end
+
+-- Disable this module because it make one priming query
+if detect_time_skew then
+ modules.unload('detect_time_skew')
+end
+
+_hint_root_file('hints')
+cache.size = 2*MB
+log_level('debug')
+{% endraw %}
+
+net = { '{{SELF_ADDR}}' }
+
+
+{% if QMIN == "false" %}
+option('NO_MINIMIZE', true)
+{% else %}
+option('NO_MINIMIZE', false)
+{% endif %}
+
+
+-- Self-checks on globals
+assert(help() ~= nil)
+assert(worker.id ~= nil)
+-- Self-checks on facilities
+assert(cache.count() == 0)
+assert(cache.stats() ~= nil)
+assert(cache.backends() ~= nil)
+assert(worker.stats() ~= nil)
+assert(net.interfaces() ~= nil)
+-- Self-checks on loaded stuff
+assert(net.list()[1].transport.ip == '{{SELF_ADDR}}')
+assert(#modules.list() > 0)
+-- Self-check timers
+ev = event.recurrent(1 * sec, function (ev) return 1 end)
+event.cancel(ev)
+ev = event.after(0, function (ev) return 1 end)
diff --git a/modules/policy/policy.lua b/modules/policy/policy.lua
new file mode 100644
index 0000000..47e436f
--- /dev/null
+++ b/modules/policy/policy.lua
@@ -0,0 +1,1109 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+local kres = require('kres')
+local ffi = require('ffi')
+
+local LOG_GRP_POLICY_TAG = ffi.string(ffi.C.kr_log_grp2name(ffi.C.LOG_GRP_POLICY))
+local LOG_GRP_REQDBG_TAG = ffi.string(ffi.C.kr_log_grp2name(ffi.C.LOG_GRP_REQDBG))
+
+local todname = kres.str2dname -- not available during module load otherwise
+
+-- Counter of unique rules
+local nextid = 0
+local function getruleid()
+ local newid = nextid
+ nextid = nextid + 1
+ return newid
+end
+
+-- Support for client sockets from inside policy actions
+local socket_client = function ()
+ return error("missing lua-cqueues library, can't create socket client")
+end
+local has_socket, socket = pcall(require, 'cqueues.socket')
+if has_socket then
+ socket_client = function (host, port)
+ local s, err, status
+
+ s = socket.connect({ host = host, port = port, type = socket.SOCK_DGRAM })
+ s:setmode('bn', 'bn')
+ status, err = pcall(s.connect, s)
+
+ if not status then
+ return status, err
+ end
+ return s
+ end
+end
+
+-- Split address and port from a combined string.
+local function addr_split_port(target, default_port)
+ assert(default_port and type(default_port) == 'number')
+ local port = ffi.new('uint16_t[1]', default_port)
+ local addr = ffi.new('char[47]') -- INET6_ADDRSTRLEN + 1
+ local ret = ffi.C.kr_straddr_split(target, addr, port)
+ if ret ~= 0 then
+ error('failed to parse address ' .. target)
+ end
+ return addr, tonumber(port[0])
+end
+
+-- String address@port -> sockaddr.
+local function addr2sock(target, default_port)
+ local addr, port = addr_split_port(target, default_port)
+ local sock = ffi.gc(ffi.C.kr_straddr_socket(addr, port, nil), ffi.C.free);
+ if sock == nil then
+ error("target '"..target..'" is not a valid IP address')
+ end
+ return sock
+end
+
+-- Debug logging for taken policy actions
+local function log_policy_action(req, name)
+ if ffi.C.kr_log_is_debug_fun(ffi.C.LOG_GRP_POLICY, req) then
+ local qry = req:current()
+ ffi.C.kr_log_req1(
+ req, qry.uid, 2, ffi.C.LOG_GRP_POLICY, LOG_GRP_POLICY_TAG,
+ "%s applied for %s %s\n",
+ name, kres.dname2str(qry.sname), kres.tostring.type[qry.stype])
+ end
+end
+
+-- policy functions are defined below
+local policy = {}
+
+function policy.PASS(state, _)
+ return state
+end
+
+-- Mirror request elsewhere, and continue solving
+function policy.MIRROR(target)
+ local addr, port = addr_split_port(target, 53)
+ local sink, err = socket_client(ffi.string(addr), port)
+ if not sink then panic('MIRROR target %s is not a valid: %s', target, err) end
+ return function(state, req)
+ if state == kres.FAIL then return state end
+ local query = req.qsource.packet
+ if query ~= nil then
+ sink:send(ffi.string(query.wire, query.size), 1, tonumber(query.size))
+ end
+ return -- Chain action to next
+ end
+end
+
+-- Override the list of nameservers (forwarders)
+local function set_nslist(req, list)
+ local ns_i = 0
+ for _, ns in ipairs(list) do
+ if ffi.C.kr_forward_add_target(req, ns) == 0 then
+ ns_i = ns_i + 1
+ end
+ end
+ if ns_i == 0 then
+ -- would use assert() but don't want to compose the message if not triggered
+ error('no usable address in NS set (check net.ipv4 and '
+ .. 'net.ipv6 config):\n' .. table_print(list, 2))
+ end
+end
+
+-- Forward request, and solve as stub query
+function policy.STUB(target)
+ local list = {}
+ if type(target) == 'table' then
+ for _, v in pairs(target) do
+ table.insert(list, addr2sock(v, 53))
+ end
+ else
+ table.insert(list, addr2sock(target, 53))
+ end
+ return function(state, req)
+ local qry = req:current()
+ -- Switch mode to stub resolver, do not track origin zone cut since it's not real authority NS
+ qry.flags.STUB = true
+ qry.flags.ALWAYS_CUT = false
+ set_nslist(req, list)
+ return state
+ end
+end
+
+-- Forward request and all subrequests to upstream; validate answers
+function policy.FORWARD(target)
+ local list = {}
+ if type(target) == 'table' then
+ for _, v in pairs(target) do
+ table.insert(list, addr2sock(v, 53))
+ end
+ else
+ table.insert(list, addr2sock(target, 53))
+ end
+ return function(state, req)
+ local qry = req:current()
+ req.options.FORWARD = true
+ req.options.NO_MINIMIZE = true
+ qry.flags.FORWARD = true
+ qry.flags.ALWAYS_CUT = false
+ qry.flags.NO_MINIMIZE = true
+ qry.flags.AWAIT_CUT = true
+ set_nslist(req, list)
+ return state
+ end
+end
+
+-- Forward request and all subrequests to upstream over TLS; validate answers
+function policy.TLS_FORWARD(targets)
+ if type(targets) ~= 'table' or #targets < 1 then
+ error('TLS_FORWARD argument must be a non-empty table')
+ end
+
+ local sockaddr_c_set = {}
+ local nslist = {} -- to persist in closure of the returned function
+ for idx, target in pairs(targets) do
+ if type(target) ~= 'table' or type(target[1]) ~= 'string' then
+ error(string.format('TLS_FORWARD configuration at position ' ..
+ '%d must be a table starting with an IP address', idx))
+ end
+ -- Note: some functions have checks with error() calls inside.
+ local sockaddr_c = addr2sock(target[1], 853)
+
+ -- Refuse repeated addresses in the same set.
+ local sockaddr_lua = ffi.string(sockaddr_c, ffi.C.kr_sockaddr_len(sockaddr_c))
+ if sockaddr_c_set[sockaddr_lua] then
+ error('TLS_FORWARD configuration cannot declare two configs for IP address '
+ .. target[1])
+ else
+ sockaddr_c_set[sockaddr_lua] = true;
+ end
+
+ table.insert(nslist, sockaddr_c)
+ net.tls_client(target)
+ end
+
+ return function(state, req)
+ local qry = req:current()
+ req.options.FORWARD = true
+ req.options.NO_MINIMIZE = true
+ qry.flags.FORWARD = true
+ qry.flags.ALWAYS_CUT = false
+ qry.flags.NO_MINIMIZE = true
+ qry.flags.AWAIT_CUT = true
+ req.options.TCP = true
+ qry.flags.TCP = true
+ set_nslist(req, nslist)
+ return state
+ end
+end
+
+-- Rewrite records in packet
+function policy.REROUTE(tbl, names)
+ -- Import renumbering rules
+ local ren = require('kres_modules.renumber')
+ local prefixes = {}
+ for from, to in pairs(tbl) do
+ local prefix = names and ren.name(from, to) or ren.prefix(from, to)
+ table.insert(prefixes, prefix)
+ end
+ -- Return rule closure
+ return ren.rule(prefixes)
+end
+
+-- Set and clear some query flags
+function policy.FLAGS(opts_set, opts_clear)
+ return function(_, req)
+ -- We assume to be running in the begin phase, so to truly apply
+ -- to the whole request we need to change both kr_request and kr_query.
+ local qry = req:current()
+ for _, flags in pairs({qry.flags, req.options}) do
+ ffi.C.kr_qflags_set (flags, kres.mk_qflags(opts_set or {}))
+ ffi.C.kr_qflags_clear(flags, kres.mk_qflags(opts_clear or {}))
+ end
+ return nil -- chain rule
+ end
+end
+
+local function mkauth_soa(answer, dname, mname, ttl)
+ if mname == nil then
+ mname = dname
+ end
+ return answer:put(dname, ttl or 10800, answer:qclass(), kres.type.SOA,
+ mname .. '\6nobody\7invalid\0\0\0\0\1\0\0\14\16\0\0\4\176\0\9\58\128\0\0\42\48')
+end
+
+-- Create answer with passed arguments
+function policy.ANSWER(rtable, nodata)
+ return function(_, req)
+ local qry = req:current()
+ local data = rtable[qry.stype]
+ if data == nil and nodata ~= true then
+ return nil
+ end
+ -- now we're certain we want to generate an answer
+
+ local answer = req:ensure_answer()
+ if answer == nil then return nil end
+ ffi.C.kr_pkt_make_auth_header(answer)
+ local ttl = (data or {}).ttl or 1
+ answer:rcode(kres.rcode.NOERROR)
+ req:set_extended_error(kres.extended_error.FORGED, "5DO5")
+
+ if data == nil then -- want NODATA, i.e. just a SOA
+ answer:begin(kres.section.AUTHORITY)
+ local soa = rtable[kres.type.SOA]
+ if soa ~= nil then
+ answer:put(qry.sname, soa.ttl or ttl, qry.sclass, kres.type.SOA,
+ soa.rdata[1] or soa.rdata)
+ else
+ mkauth_soa(answer, kres.dname2wire(qry.sname), nil, ttl)
+ end
+ log_policy_action(req, 'ANSWER (nodata)')
+ else
+ answer:begin(kres.section.ANSWER)
+ if type(data.rdata) == 'table' then
+ for _, entry in ipairs(data.rdata) do
+ answer:put(qry.sname, ttl, qry.sclass, qry.stype, entry)
+ end
+ else
+ answer:put(qry.sname, ttl, qry.sclass, qry.stype, data.rdata)
+ end
+ log_policy_action(req, 'ANSWER (forged)')
+ end
+ return kres.DONE
+ end
+end
+
+local dname_localhost = todname('localhost.')
+
+-- Rule for localhost. zone; see RFC6303, sec. 3
+local function localhost(_, req)
+ local qry = req:current()
+ local answer = req:ensure_answer()
+ if answer == nil then return nil end
+ ffi.C.kr_pkt_make_auth_header(answer)
+
+ local is_exact = ffi.C.knot_dname_is_equal(qry.sname, dname_localhost)
+
+ answer:rcode(kres.rcode.NOERROR)
+ answer:begin(kres.section.ANSWER)
+ if qry.stype == kres.type.AAAA then
+ answer:put(qry.sname, 900, answer:qclass(), kres.type.AAAA,
+ '\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1')
+ elseif qry.stype == kres.type.A then
+ answer:put(qry.sname, 900, answer:qclass(), kres.type.A, '\127\0\0\1')
+ elseif is_exact and qry.stype == kres.type.SOA then
+ mkauth_soa(answer, dname_localhost)
+ elseif is_exact and qry.stype == kres.type.NS then
+ answer:put(dname_localhost, 900, answer:qclass(), kres.type.NS, dname_localhost)
+ else
+ answer:begin(kres.section.AUTHORITY)
+ mkauth_soa(answer, dname_localhost)
+ end
+ return kres.DONE
+end
+
+local dname_rev4_localhost = todname('1.0.0.127.in-addr.arpa');
+local dname_rev4_localhost_apex = todname('127.in-addr.arpa');
+
+-- Rule for reverse localhost.
+-- Answer with locally served minimal 127.in-addr.arpa domain, only having
+-- a PTR record in 1.0.0.127.in-addr.arpa, and with 1.0...0.ip6.arpa. zone.
+-- TODO: much of this would better be left to the hints module (or coordinated).
+local function localhost_reversed(_, req)
+ local qry = req:current()
+ local answer = req:ensure_answer()
+ if answer == nil then return nil end
+
+ -- classify qry.sname:
+ local is_exact -- exact dname for localhost
+ local is_apex -- apex of a locally-served localhost zone
+ local is_nonterm -- empty non-terminal name
+ if ffi.C.knot_dname_in_bailiwick(qry.sname, todname('ip6.arpa.')) > 0 then
+ -- exact ::1 query (relying on the calling rule)
+ is_exact = true
+ is_apex = true
+ else
+ -- within 127.in-addr.arpa.
+ local labels = ffi.C.knot_dname_labels(qry.sname, nil)
+ if labels == 3 then
+ is_exact = false
+ is_apex = true
+ elseif labels == 4+2 and ffi.C.knot_dname_is_equal(
+ qry.sname, dname_rev4_localhost) then
+ is_exact = true
+ else
+ is_exact = false
+ is_apex = false
+ is_nonterm = ffi.C.knot_dname_in_bailiwick(dname_rev4_localhost, qry.sname) > 0
+ end
+ end
+
+ ffi.C.kr_pkt_make_auth_header(answer)
+ answer:rcode(kres.rcode.NOERROR)
+ answer:begin(kres.section.ANSWER)
+ if is_exact and qry.stype == kres.type.PTR then
+ answer:put(qry.sname, 900, answer:qclass(), kres.type.PTR, dname_localhost)
+ elseif is_apex and qry.stype == kres.type.SOA then
+ mkauth_soa(answer, dname_rev4_localhost_apex, dname_localhost)
+ elseif is_apex and qry.stype == kres.type.NS then
+ answer:put(dname_rev4_localhost_apex, 900, answer:qclass(), kres.type.NS,
+ dname_localhost)
+ else
+ if not is_nonterm then
+ answer:rcode(kres.rcode.NXDOMAIN)
+ end
+ answer:begin(kres.section.AUTHORITY)
+ mkauth_soa(answer, dname_rev4_localhost_apex, dname_localhost)
+ end
+ return kres.DONE
+end
+
+-- All requests
+function policy.all(action)
+ return function(_, _) return action end
+end
+
+-- Requests whose QNAME is exactly the provided domain
+function policy.domains(action, dname_list)
+ return function(_, query)
+ local qname = query:name()
+ for _, dname in ipairs(dname_list) do
+ if ffi.C.knot_dname_is_equal(qname, dname) then
+ return action
+ end
+ end
+ return nil
+ end
+end
+
+-- Requests whose QNAME matches given zone list (i.e. suffix match)
+function policy.suffix(action, zone_list)
+ local AC = require('ahocorasick')
+ local tree = AC.create(zone_list)
+ return function(_, query)
+ local match = AC.match(tree, query:name(), false)
+ if match ~= nil then
+ return action
+ end
+ return nil
+ end
+end
+
+-- Check for common suffix first, then suffix match (specialized version of suffix match)
+function policy.suffix_common(action, suffix_list, common_suffix)
+ local common_len = string.len(common_suffix)
+ local suffix_count = #suffix_list
+ return function(_, query)
+ -- Preliminary check
+ local qname = query:name()
+ if not string.find(qname, common_suffix, -common_len, true) then
+ return nil
+ end
+ -- String match
+ for i = 1, suffix_count do
+ local zone = suffix_list[i]
+ if string.find(qname, zone, -string.len(zone), true) then
+ return action
+ end
+ end
+ return nil
+ end
+end
+
+-- Filter QNAME pattern
+function policy.pattern(action, pattern)
+ return function(_, query)
+ if string.find(query:name(), pattern) then
+ return action
+ end
+ return nil
+ end
+end
+
+local function rpz_parse(action, path)
+ local rules = {}
+ local new_actions = {}
+ local action_map = {
+ -- RPZ Policy Actions
+ ['\0'] = action,
+ ['\1*\0'] = policy.ANSWER({}, true),
+ ['\012rpz-passthru\0'] = policy.PASS, -- the grammar...
+ ['\008rpz-drop\0'] = policy.DROP,
+ ['\012rpz-tcp-only\0'] = policy.TC,
+ -- Policy triggers @NYI@
+ }
+ -- RR types to be skipped; boolean denoting whether to throw a warning even for RPZ apex.
+ local rrtype_bad = {
+ [kres.type.DNAME] = true,
+ [kres.type.NS] = false,
+ [kres.type.DNSKEY] = true,
+ [kres.type.DS] = true,
+ [kres.type.RRSIG] = true,
+ [kres.type.NSEC] = true,
+ [kres.type.NSEC3] = true,
+ }
+
+ -- We generally don't know what zone should be in the file; we try to detect it.
+ -- Fortunately, it's typical that SOA is the first record, even required for AXFR.
+ local origin_soa = nil
+ local warned_soa, warned_bailiwick
+
+ local parser = require('zonefile').new()
+ local ok, errstr = parser:open(path)
+ if not ok then
+ error(string.format('failed to parse "%s": %s', path, errstr or "unknown error"))
+ end
+ while true do
+ ok, errstr = parser:parse()
+ if errstr then
+ log_warn(ffi.C.LOG_GRP_POLICY, 'RPZ %s:%d: %s',
+ path, tonumber(parser.line_counter), errstr)
+ end
+ if not ok then break end
+
+ local full_name = ffi.gc(ffi.C.knot_dname_copy(parser.r_owner, nil), ffi.C.free)
+ local rdata = ffi.string(parser.r_data, parser.r_data_length)
+ ffi.C.knot_dname_to_lower(full_name)
+
+ local origin = origin_soa or parser.zone_origin
+ local prefix_labels = ffi.C.knot_dname_in_bailiwick(full_name, origin)
+ if prefix_labels < 0 then
+ if not warned_bailiwick then
+ warned_bailiwick = true
+ log_warn(ffi.C.LOG_GRP_POLICY,
+ 'RPZ %s:%d: RR owner "%s" outside the zone (ignored; reported once per file)',
+ path, tonumber(parser.line_counter), kres.dname2str(full_name))
+ end
+ goto continue
+ end
+
+ local bytes = ffi.C.knot_dname_size(full_name) - ffi.C.knot_dname_size(origin)
+ local name = ffi.string(full_name, bytes) .. '\0'
+
+ if parser.r_type == kres.type.CNAME then
+ if action_map[rdata] then
+ rules[name] = action_map[rdata]
+ else
+ log_warn(ffi.C.LOG_GRP_POLICY,
+ 'RPZ %s:%d: CNAME with custom target in RPZ is not supported yet (ignored)',
+ path, tonumber(parser.line_counter))
+ end
+ else
+ if #name then
+ local is_bad = rrtype_bad[parser.r_type]
+
+ if parser.r_type == kres.type.SOA then
+ if origin_soa == nil then
+ origin_soa = ffi.gc(ffi.C.knot_dname_copy(parser.r_owner, nil), ffi.C.free)
+ goto continue -- we don't want to modify `new_actions`
+ else
+ is_bad = true -- maybe provide more info, but it seems rare
+ end
+ elseif origin_soa == nil and not warned_soa then
+ warned_soa = true
+ log_warn(ffi.C.LOG_GRP_POLICY,
+ 'RPZ %s:%d warning: SOA missing as the first record',
+ path, tonumber(parser.line_counter))
+ end
+
+ if is_bad == true or (is_bad == false and prefix_labels ~= 0) then
+ log_warn(ffi.C.LOG_GRP_POLICY, 'RPZ %s:%d warning: RR type %s is not allowed in RPZ (ignored)',
+ path, tonumber(parser.line_counter), kres.tostring.type[parser.r_type])
+ elseif is_bad == nil then
+ if new_actions[name] == nil then new_actions[name] = {} end
+ local act = new_actions[name][parser.r_type]
+ if act == nil then
+ new_actions[name][parser.r_type] = { ttl=parser.r_ttl, rdata=rdata }
+ else -- multiple RRs: no reordering or deduplication
+ if type(act.rdata) ~= 'table' then
+ act.rdata = { act.rdata }
+ end
+ table.insert(act.rdata, rdata)
+ if parser.r_ttl ~= act.ttl then -- be conservative
+ log_warn(ffi.C.LOG_GRP_POLICY, 'RPZ %s:%d warning: different TTLs in a set (minimum taken)',
+ path, tonumber(parser.line_counter))
+ act.ttl = math.min(act.ttl, parser.r_ttl)
+ end
+ end
+ else
+ assert(is_bad == false and prefix_labels == 0)
+ end
+ end
+ end
+
+ ::continue::
+ end
+ collectgarbage()
+ for qname, rrsets in pairs(new_actions) do
+ rules[qname] = policy.ANSWER(rrsets, true)
+ end
+ return rules
+end
+
+-- Split path into dirname and basename (like the shell utilities)
+local function get_dir_and_file(path)
+ local dir, file = string.match(path, "(.*)/([^/]+)")
+
+ -- If regex doesn't match then path must be the file directly (i.e. doesn't contain '/')
+ -- This assumes that the file exists (rpz_parse() would fail if it doesn't)
+ if not dir and not file then
+ dir = '.'
+ file = path
+ end
+
+ return dir, file
+end
+
+-- RPZ policy set
+-- Create RPZ from zone file and optionally watch the file for changes
+function policy.rpz(action, path, watch)
+ local rules = rpz_parse(action, path)
+
+ if watch ~= false then
+ local has_notify, notify = pcall(require, 'cqueues.notify')
+ if has_notify then
+ local bit = require('bit')
+
+ local dir, file = get_dir_and_file(path)
+ local watcher = notify.opendir(dir)
+ watcher:add(file, bit.bxor(notify.CREATE, notify.MODIFY))
+
+ worker.coroutine(function ()
+ for _, name in watcher:changes() do
+ -- Limit to changes on file we're interested in
+ -- Watcher will also fire for changes to the directory itself
+ if name == file then
+ -- If the file changes then reparse and replace the existing ruleset
+ log_info(ffi.C.LOG_GRP_POLICY, 'RPZ reloading: ' .. name)
+ rules = rpz_parse(action, path)
+ end
+ end
+ end)
+ elseif watch then -- explicitly requested and failed
+ error('[poli] lua-cqueues required to watch and reload RPZ file')
+ else
+ log_info(ffi.C.LOG_GRP_POLICY, 'lua-cqueues required to watch and reload RPZ file, continuing without watching')
+ end
+ end
+
+ return function(_, query)
+ local label = query:name()
+ local rule = rules[label]
+ while rule == nil and string.len(label) > 0 do
+ label = string.sub(label, string.byte(label) + 2)
+ rule = rules['\1*'..label]
+ end
+ return rule
+ end
+end
+
+-- Apply an action when query belongs to a slice (determined by slice_func())
+function policy.slice(slice_func, ...)
+ local actions = {...}
+ if #actions <= 0 then
+ error('[poli] at least one action must be provided to policy.slice()')
+ end
+
+ return function(_, query)
+ local index = slice_func(query, #actions)
+ return actions[index]
+ end
+end
+
+-- Initializes slicing function that randomly assigns queries to a slice based on their registrable domain
+function policy.slice_randomize_psl(seed)
+ local has_psl, psl_lib = pcall(require, 'psl')
+ if not has_psl then
+ error('[poli] lua-psl is required for policy.slice_randomize_psl()')
+ end
+ -- load psl
+ local has_latest, psl = pcall(psl_lib.latest)
+ if not has_latest then -- compatibility with lua-psl < 0.15
+ psl = psl_lib.builtin()
+ end
+
+ if seed == nil then
+ seed = os.time() / (3600 * 24 * 7)
+ end
+ seed = math.floor(seed) -- convert to int
+
+ return function(query, length)
+ assert(length > 0)
+
+ local domain = kres.dname2str(query:name())
+ if domain == nil then -- invalid data: auto-select first action
+ return 1
+ end
+ if domain:len() > 1 then --remove trailing dot
+ domain = domain:sub(0, -2)
+ end
+
+ -- do psl lookup for registrable domain
+ local reg_domain = psl:registrable_domain(domain)
+ if reg_domain == nil then -- fallback to unreg. domain
+ reg_domain = psl:unregistrable_domain(domain)
+ if reg_domain == nil then -- shouldn't happen: safe fallback
+ return 1
+ end
+ end
+
+ local rand_seed = seed
+ -- create deterministic seed for pseudo-random slice assignment
+ for i = 1, #reg_domain do
+ rand_seed = rand_seed + reg_domain:byte(i)
+ end
+
+ -- use linear congruential generator with values from ANSI C
+ rand_seed = rand_seed % 0x80000000 -- ensure seed is positive 32b int
+ local rand = (1103515245 * rand_seed + 12345) % 0x10000
+ return 1 + rand % length
+ end
+end
+
+-- Prepare for making an answer from scratch. (Return the packet for convenience.)
+local function answer_clear(req)
+ -- If we're in postrules, previous resolving might have chosen some RRs
+ -- for inclusion in the answer, so we need to avoid those.
+ -- *_selected arrays are in mempool, so explicit deallocation is not necessary.
+ req.answ_selected.len = 0
+ req.auth_selected.len = 0
+ req.add_selected.len = 0
+
+ -- Let's be defensive and clear the answer, too.
+ local pkt = req:ensure_answer()
+ if pkt == nil then return nil end
+ pkt:clear_payload()
+ req:ensure_edns()
+ return pkt
+end
+
+function policy.DENY_MSG(msg, extended_error)
+ if msg and (type(msg) ~= 'string' or #msg >= 255) then
+ error('DENY_MSG: optional msg must be string shorter than 256 characters')
+ end
+ if extended_error == nil then
+ extended_error = kres.extended_error.BLOCKED
+ end
+ local action_name = msg and 'DENY_MSG' or 'DENY'
+
+ return function (_, req)
+ -- Write authority information
+ local answer = answer_clear(req)
+ if answer == nil then return nil end
+ ffi.C.kr_pkt_make_auth_header(answer)
+ answer:rcode(kres.rcode.NXDOMAIN)
+ answer:begin(kres.section.AUTHORITY)
+ mkauth_soa(answer, answer:qname())
+ if msg then
+ answer:begin(kres.section.ADDITIONAL)
+ answer:put('\11explanation\7invalid', 10800, answer:qclass(), kres.type.TXT,
+ string.char(#msg) .. msg)
+
+ end
+ req:set_extended_error(extended_error, "CR36")
+ log_policy_action(req, action_name)
+ return kres.DONE
+ end
+end
+
+local function free_cb(func)
+ func:free()
+end
+
+local debug_logline_cb = ffi.cast('trace_log_f', function (_, msg)
+ jit.off(true, true) -- JIT for (C -> lua)^2 nesting isn't allowed
+ ffi.C.kr_log_fmt(
+ ffi.C.LOG_GRP_REQDBG, -- but the original [group] tag also remains in the string
+ LOG_DEBUG,
+ 'CODE_FILE=policy.lua', 'CODE_LINE=', 'CODE_FUNC=policy.DEBUG_ALWAYS', -- no meaningful locations
+ '[%-6s]%s', LOG_GRP_REQDBG_TAG, msg) -- msg should end with newline already
+end)
+ffi.gc(debug_logline_cb, free_cb)
+
+-- LOG_DEBUG without log_trace and without code locations
+local function log_notrace(req, fmt, ...)
+ ffi.C.kr_log_fmt(ffi.C.LOG_GRP_REQDBG, LOG_DEBUG,
+ 'CODE_FILE=policy.lua', 'CODE_LINE=', 'CODE_FUNC=', -- no meaningful locations
+ '%s', string.format( -- convert in lua, as integers in C varargs would pass as double
+ '[%-6s][%-6s][%05u.00] ' .. fmt,
+ LOG_GRP_REQDBG_TAG, LOG_GRP_POLICY_TAG, req.uid, ...)
+ )
+end
+
+local debug_logfinish_cb = ffi.cast('trace_callback_f', function (req)
+ jit.off(true, true) -- JIT for (C -> lua)^2 nesting isn't allowed
+ log_notrace(req, 'following rrsets were marked as interesting:\n%s\n',
+ req:selected_tostring())
+ if req.answer ~= nil then
+ log_notrace(req, 'answer packet:\n%s\n', req.answer)
+ else
+ log_notrace(req, 'answer packet DROPPED\n')
+ end
+end)
+ffi.gc(debug_logfinish_cb, free_cb)
+
+-- log request packet
+function policy.REQTRACE(_, req)
+ log_notrace(req, 'request packet:\n%s', req.qsource.packet)
+end
+
+-- log how the request arrived, notably the client's IP
+function policy.IPTRACE(_, req)
+ if req.qsource.addr == nil then
+ log_notrace(req, 'request packet arrived internally\n')
+ else
+ -- stringify transport flags: struct kr_request_qsource_flags
+ local qf = req.qsource.flags
+ local qf_str = qf.tcp and 'TCP' or 'UDP'
+ if qf.tls then qf_str = qf_str .. ' + TLS' end
+ if qf.http then qf_str = qf_str .. ' + HTTP' end
+ if qf.xdp then qf_str = qf_str .. ' + XDP' end
+
+ log_notrace(req, 'request packet arrived from %s to %s (%s)\n',
+ req.qsource.addr, req.qsource.dst_addr, qf_str)
+ end
+ return nil -- chain rule
+end
+
+function policy.DEBUG_ALWAYS(state, req)
+ policy.QTRACE(state, req)
+ req:trace_chain_callbacks(debug_logline_cb, debug_logfinish_cb)
+ policy.REQTRACE(state, req)
+end
+
+local debug_stashlog_cb = ffi.cast('trace_log_f', function (req, msg)
+ jit.off(true, true) -- JIT for (C -> lua)^2 nesting isn't allowed
+
+ -- stash messages for conditional logging in trace_finish
+ local stash = req:vars()['policy_debug_stash']
+ table.insert(stash, ffi.string(msg))
+end)
+ffi.gc(debug_stashlog_cb, free_cb)
+
+-- buffer debug logs and print then only if test() returns a truthy value
+function policy.DEBUG_IF(test)
+ local debug_finish_cb = ffi.cast('trace_callback_f', function (cbreq)
+ jit.off(true, true) -- JIT for (C -> lua)^2 nesting isn't allowed
+ if test(cbreq) then
+ policy.REQTRACE(nil, cbreq)
+ debug_logfinish_cb(cbreq) -- unconditional version
+
+ local stash = cbreq:vars()['policy_debug_stash']
+ for _, line in ipairs(stash) do -- don't want one huge entry
+ ffi.C.kr_log_fmt(ffi.C.LOG_GRP_REQDBG, LOG_DEBUG,
+ 'CODE_FILE=policy.lua', 'CODE_LINE=', 'CODE_FUNC=', -- no meaningful locations
+ '[%-6s]%s', LOG_GRP_REQDBG_TAG, line)
+ end
+ end
+ end)
+ ffi.gc(debug_finish_cb, function (func) func:free() end)
+
+ return function (state, req)
+ req:vars()['policy_debug_stash'] = {}
+ policy.QTRACE(state, req)
+ req:trace_chain_callbacks(debug_stashlog_cb, debug_finish_cb)
+ return
+ end
+end
+
+policy.DEBUG_CACHE_MISS = policy.DEBUG_IF(
+ function(req)
+ return not req:all_from_cache()
+ end
+)
+
+policy.DENY = policy.DENY_MSG() -- compatibility with < 2.0
+
+function policy.DROP(_, req)
+ local answer = answer_clear(req)
+ if answer == nil then return nil end
+ req:set_extended_error(kres.extended_error.PROHIBITED, "U5KL")
+ log_policy_action(req, 'DROP')
+ return kres.FAIL
+end
+
+function policy.NO_ANSWER(_, req)
+ req.options.NO_ANSWER = true
+ log_policy_action(req, 'NO_ANSWER')
+ return kres.FAIL
+end
+
+function policy.REFUSE(_, req)
+ local answer = answer_clear(req)
+ if answer == nil then return nil end
+ answer:rcode(kres.rcode.REFUSED)
+ answer:ad(false)
+ req:set_extended_error(kres.extended_error.PROHIBITED, "EIM4")
+ log_policy_action(req, 'REFUSE')
+ return kres.DONE
+end
+
+function policy.TC(state, req)
+ -- Avoid non-UDP queries
+ if req.qsource.addr == nil or req.qsource.flags.tcp then
+ return state
+ end
+
+ local answer = answer_clear(req)
+ if answer == nil then return nil end
+ answer:tc(1)
+ answer:ad(false)
+ log_policy_action(req, 'TC')
+ return kres.DONE
+end
+
+function policy.QTRACE(_, req)
+ local qry = req:current()
+ req.options.TRACE = true
+ qry.flags.TRACE = true
+ return -- this allows to continue iterating over policy list
+end
+
+-- Evaluate packet in given rules to determine policy action
+function policy.evaluate(rules, req, query, state)
+ for i = 1, #rules do
+ local rule = rules[i]
+ if not rule.suspended then
+ local action = rule.cb(req, query)
+ if action ~= nil then
+ rule.count = rule.count + 1
+ local next_state = action(state, req)
+ if next_state then -- Not a chain rule,
+ return next_state -- stop on first match
+ end
+ end
+ end
+ end
+ return
+end
+
+-- Add rule to policy list
+function policy.add(rule, postrule)
+ -- Compatibility with 1.0.0 API
+ -- it will be dropped in 1.2.0
+ if rule == policy then
+ rule = postrule
+ postrule = nil
+ end
+ -- End of compatibility shim
+ local desc = {id=getruleid(), cb=rule, count=0}
+ table.insert(postrule and policy.postrules or policy.rules, desc)
+ return desc
+end
+
+-- Remove rule from a list
+local function delrule(rules, id)
+ for i, r in ipairs(rules) do
+ if r.id == id then
+ table.remove(rules, i)
+ return true
+ end
+ end
+ return false
+end
+
+-- Delete rule from policy list
+function policy.del(id)
+ if not delrule(policy.rules, id) then
+ if not delrule(policy.postrules, id) then
+ return false
+ end
+ end
+ return true
+end
+
+-- Convert list of string names to domain names
+function policy.todnames(names)
+ for i, v in ipairs(names) do
+ names[i] = kres.str2dname(v)
+ end
+ return names
+end
+
+-- RFC1918 Private, local, broadcast, test and special zones
+-- Considerations: RFC6761, sec 6.1.
+-- https://www.iana.org/assignments/locally-served-dns-zones
+local private_zones = {
+ -- RFC6303
+ '10.in-addr.arpa.',
+ '16.172.in-addr.arpa.',
+ '17.172.in-addr.arpa.',
+ '18.172.in-addr.arpa.',
+ '19.172.in-addr.arpa.',
+ '20.172.in-addr.arpa.',
+ '21.172.in-addr.arpa.',
+ '22.172.in-addr.arpa.',
+ '23.172.in-addr.arpa.',
+ '24.172.in-addr.arpa.',
+ '25.172.in-addr.arpa.',
+ '26.172.in-addr.arpa.',
+ '27.172.in-addr.arpa.',
+ '28.172.in-addr.arpa.',
+ '29.172.in-addr.arpa.',
+ '30.172.in-addr.arpa.',
+ '31.172.in-addr.arpa.',
+ '168.192.in-addr.arpa.',
+ '0.in-addr.arpa.',
+ '254.169.in-addr.arpa.',
+ '2.0.192.in-addr.arpa.',
+ '100.51.198.in-addr.arpa.',
+ '113.0.203.in-addr.arpa.',
+ '255.255.255.255.in-addr.arpa.',
+ -- RFC7793
+ '64.100.in-addr.arpa.',
+ '65.100.in-addr.arpa.',
+ '66.100.in-addr.arpa.',
+ '67.100.in-addr.arpa.',
+ '68.100.in-addr.arpa.',
+ '69.100.in-addr.arpa.',
+ '70.100.in-addr.arpa.',
+ '71.100.in-addr.arpa.',
+ '72.100.in-addr.arpa.',
+ '73.100.in-addr.arpa.',
+ '74.100.in-addr.arpa.',
+ '75.100.in-addr.arpa.',
+ '76.100.in-addr.arpa.',
+ '77.100.in-addr.arpa.',
+ '78.100.in-addr.arpa.',
+ '79.100.in-addr.arpa.',
+ '80.100.in-addr.arpa.',
+ '81.100.in-addr.arpa.',
+ '82.100.in-addr.arpa.',
+ '83.100.in-addr.arpa.',
+ '84.100.in-addr.arpa.',
+ '85.100.in-addr.arpa.',
+ '86.100.in-addr.arpa.',
+ '87.100.in-addr.arpa.',
+ '88.100.in-addr.arpa.',
+ '89.100.in-addr.arpa.',
+ '90.100.in-addr.arpa.',
+ '91.100.in-addr.arpa.',
+ '92.100.in-addr.arpa.',
+ '93.100.in-addr.arpa.',
+ '94.100.in-addr.arpa.',
+ '95.100.in-addr.arpa.',
+ '96.100.in-addr.arpa.',
+ '97.100.in-addr.arpa.',
+ '98.100.in-addr.arpa.',
+ '99.100.in-addr.arpa.',
+ '100.100.in-addr.arpa.',
+ '101.100.in-addr.arpa.',
+ '102.100.in-addr.arpa.',
+ '103.100.in-addr.arpa.',
+ '104.100.in-addr.arpa.',
+ '105.100.in-addr.arpa.',
+ '106.100.in-addr.arpa.',
+ '107.100.in-addr.arpa.',
+ '108.100.in-addr.arpa.',
+ '109.100.in-addr.arpa.',
+ '110.100.in-addr.arpa.',
+ '111.100.in-addr.arpa.',
+ '112.100.in-addr.arpa.',
+ '113.100.in-addr.arpa.',
+ '114.100.in-addr.arpa.',
+ '115.100.in-addr.arpa.',
+ '116.100.in-addr.arpa.',
+ '117.100.in-addr.arpa.',
+ '118.100.in-addr.arpa.',
+ '119.100.in-addr.arpa.',
+ '120.100.in-addr.arpa.',
+ '121.100.in-addr.arpa.',
+ '122.100.in-addr.arpa.',
+ '123.100.in-addr.arpa.',
+ '124.100.in-addr.arpa.',
+ '125.100.in-addr.arpa.',
+ '126.100.in-addr.arpa.',
+ '127.100.in-addr.arpa.',
+
+ -- RFC6303
+ -- localhost_reversed handles ::1
+ '0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa.',
+ 'd.f.ip6.arpa.',
+ '8.e.f.ip6.arpa.',
+ '9.e.f.ip6.arpa.',
+ 'a.e.f.ip6.arpa.',
+ 'b.e.f.ip6.arpa.',
+ '8.b.d.0.1.0.0.2.ip6.arpa.',
+ -- RFC8375
+ 'home.arpa.',
+}
+policy.todnames(private_zones)
+
+-- @var Default rules
+policy.rules = {}
+policy.postrules = {}
+policy.special_names = {
+ -- XXX: beware of special_names_optim() when modifying these filters
+ {
+ cb=policy.suffix_common(policy.DENY_MSG(
+ 'Blocking is mandated by standards, see references on '
+ .. 'https://www.iana.org/assignments/'
+ .. 'locally-served-dns-zones/locally-served-dns-zones.xhtml',
+ kres.extended_error.NOTSUP),
+ private_zones, todname('arpa.')),
+ count=0
+ },
+ {
+ cb=policy.suffix(policy.DENY_MSG(
+ 'Blocking is mandated by standards, see references on '
+ .. 'https://www.iana.org/assignments/'
+ .. 'special-use-domain-names/special-use-domain-names.xhtml',
+ kres.extended_error.NOTSUP),
+ {
+ todname('test.'),
+ todname('onion.'),
+ todname('invalid.'),
+ todname('local.'), -- RFC 8375.4
+ }),
+ count=0
+ },
+ {
+ cb=policy.suffix(localhost, {dname_localhost}),
+ count=0
+ },
+ {
+ cb=policy.suffix_common(localhost_reversed, {
+ todname('127.in-addr.arpa.'),
+ todname('1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa.')},
+ todname('arpa.')),
+ count=0
+ },
+}
+
+-- Return boolean; false = no special name may apply, true = some might apply.
+-- The point is to *efficiently* filter almost all QNAMEs that do not apply.
+local function special_names_optim(req, sname)
+ local qname_size = req.qsource.packet.qname_size
+ if qname_size < 9 then return true end -- don't want to special-case bad array access
+ local root = sname + qname_size - 1
+ return
+ -- .a???. or .t???.
+ (root[-5] == 4 and (root[-4] == 97 or root[-4] == 116))
+ -- .on???. or .in?????. or lo???. or *ost.
+ or (root[-6] == 5 and root[-5] == 111 and root[-4] == 110)
+ or (root[-8] == 7 and root[-7] == 105 and root[-6] == 110)
+ or (root[-6] == 5 and root[-5] == 108 and root[-4] == 111)
+ or (root[-3] == 111 and root[-2] == 115 and root[-1] == 116)
+end
+
+-- Top-down policy list walk until we hit a match
+-- the caller is responsible for reordering policy list
+-- from most specific to least specific.
+-- Some rules may be chained, in this case they are evaluated
+-- as a dependency chain, e.g. r1,r2,r3 -> r3(r2(r1(state)))
+policy.layer = {
+ begin = function(state, req)
+ -- Don't act on "finished" cases.
+ if bit.band(state, bit.bor(kres.FAIL, kres.DONE)) ~= 0 then return state end
+ local qry = req:initial() -- same as :current() but more descriptive
+ return policy.evaluate(policy.rules, req, qry, state)
+ or (special_names_optim(req, qry.sname)
+ and policy.evaluate(policy.special_names, req, qry, state))
+ or state
+ end,
+ finish = function(state, req)
+ -- Optimization for the typical case
+ if #policy.postrules == 0 then return state end
+ -- Don't act on failed cases.
+ if bit.band(state, kres.FAIL) ~= 0 then return state end
+ return policy.evaluate(policy.postrules, req, req:initial(), state) or state
+ end
+}
+
+return policy
diff --git a/modules/policy/policy.rpz.test.lua b/modules/policy/policy.rpz.test.lua
new file mode 100644
index 0000000..94fb9ce
--- /dev/null
+++ b/modules/policy/policy.rpz.test.lua
@@ -0,0 +1,65 @@
+
+local function prepare_cache()
+ cache.open(100*MB)
+ cache.clear()
+
+ local ffi = require('ffi')
+ local c = kres.context().cache
+
+ local passthru_addr = '\127\0\0\9'
+ rr_passthru = kres.rrset(todname('rpzpassthru.'), kres.type.A, kres.class.IN, 2147483647)
+ assert(rr_passthru:add_rdata(passthru_addr, #passthru_addr))
+ assert(c:insert(rr_passthru, nil, ffi.C.KR_RANK_SECURE + ffi.C.KR_RANK_AUTH))
+
+ c:commit()
+end
+
+local check_answer = require('test_utils').check_answer
+
+local function test_rpz()
+ check_answer('"CNAME ." return NXDOMAIN',
+ 'nxdomain.', kres.type.A, kres.rcode.NXDOMAIN)
+ check_answer('"CNAME *." return NODATA',
+ 'nodata.', kres.type.A, kres.rcode.NOERROR, {})
+ check_answer('"CNAME *. on wildcard" return NODATA',
+ 'nodata.nxdomain.', kres.type.A, kres.rcode.NOERROR, {})
+ check_answer('"CNAME rpz-drop." be dropped',
+ 'rpzdrop.', kres.type.A, kres.rcode.SERVFAIL)
+ check_answer('"CNAME rpz-passthru" return A rrset',
+ 'rpzpassthru.', kres.type.A, kres.rcode.NOERROR, '127.0.0.9')
+ check_answer('"A 192.168.5.5" return local A rrset',
+ 'rra.', kres.type.A, kres.rcode.NOERROR, '192.168.5.5')
+ check_answer('"A 192.168.6.6" with suffixed zone name in owner return local A rrset',
+ 'rra-zonename-suffix.', kres.type.A, kres.rcode.NOERROR, '192.168.6.6')
+ check_answer('"A 192.168.7.7" with suffixed zone name in owner return local A rrset',
+ 'testdomain.rra.', kres.type.A, kres.rcode.NOERROR, '192.168.7.7')
+ check_answer('non existing AAAA on rra domain return NODATA',
+ 'rra.', kres.type.AAAA, kres.rcode.NOERROR, {})
+ check_answer('"A 192.168.8.8" and domain with uppercase and lowercase letters',
+ 'case.sensitive.', kres.type.A, kres.rcode.NOERROR, '192.168.8.8')
+ check_answer('"A 192.168.8.8" and domain with uppercase and lowercase letters',
+ 'CASe.SENSItivE.', kres.type.A, kres.rcode.NOERROR, '192.168.8.8')
+ check_answer('two AAAA records',
+ 'two.records.', kres.type.AAAA, kres.rcode.NOERROR,
+ {'2001:db8::2', '2001:db8::1'})
+end
+
+local function test_rpz_soa()
+ check_answer('"CNAME ." return NXDOMAIN (SOA origin)',
+ 'nxdomain-fqdn.', kres.type.A, kres.rcode.NXDOMAIN)
+ check_answer('"CNAME *." return NODATA (SOA origin)',
+ 'nodata-fqdn.', kres.type.A, kres.rcode.NOERROR, {})
+end
+
+net.ipv4 = false
+net.ipv6 = false
+
+prepare_cache()
+
+policy.add(policy.rpz(policy.DENY, 'policy.test.rpz'))
+policy.add(policy.rpz(policy.DENY, 'policy.test.rpz.soa'))
+
+return {
+ test_rpz,
+ test_rpz_soa,
+}
diff --git a/modules/policy/policy.slice.test.lua b/modules/policy/policy.slice.test.lua
new file mode 100644
index 0000000..89c1b05
--- /dev/null
+++ b/modules/policy/policy.slice.test.lua
@@ -0,0 +1,109 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+-- check lua-psl is available
+local has_psl = pcall(require, 'psl')
+if not has_psl then
+ os.exit(77) -- SKIP policy.slice
+end
+
+-- unload modules which are not related to this test
+if ta_update then
+ modules.unload('ta_update')
+end
+if ta_signal_query then
+ modules.unload('ta_signal_query')
+end
+if priming then
+ modules.unload('priming')
+end
+if detect_time_skew then
+ modules.unload('detect_time_skew')
+end
+
+local kres = require('kres')
+
+local slice_queries = {
+ {},
+ {},
+ {},
+}
+
+local function sliceaction(index)
+ return function(_, req)
+ -- log query
+ local qry = req:current()
+ local name = kres.dname2str(qry:name())
+ local count = slice_queries[index][name]
+ if not count then
+ count = 0
+ end
+ slice_queries[index][name] = count + 1
+
+ -- refuse query
+ local answer = req:ensure_answer()
+ if answer == nil then return nil end
+ answer:rcode(kres.rcode.REFUSED)
+ answer:ad(false)
+ return kres.DONE
+ end
+end
+
+-- configure slicing
+policy.add(policy.slice(
+ policy.slice_randomize_psl(0),
+ sliceaction(1),
+ sliceaction(2),
+ sliceaction(3)
+))
+
+local function check_slice(desc, qname, qtype, expected_slice, expected_count)
+ callback = function()
+ count = slice_queries[expected_slice][qname]
+ qtype_str = kres.tostring.type[qtype]
+ same(count, expected_count, desc .. qname .. ' ' .. qtype_str)
+ end
+ resolve(qname, qtype, kres.class.IN, {}, callback)
+end
+
+local function test_randomize_psl()
+ local desc = 'randomize_psl() same qname, different qtype (same slice): '
+ check_slice(desc, 'example.com.', kres.type.A, 2, 1)
+ check_slice(desc, 'example.com.', kres.type.AAAA, 2, 2)
+ check_slice(desc, 'example.com.', kres.type.MX, 2, 3)
+ check_slice(desc, 'example.com.', kres.type.NS, 2, 4)
+
+ desc = 'randomize_psl() subdomain in same slice: '
+ check_slice(desc, 'a.example.com.', kres.type.A, 2, 1)
+ check_slice(desc, 'b.example.com.', kres.type.A, 2, 1)
+ check_slice(desc, 'c.example.com.', kres.type.A, 2, 1)
+ check_slice(desc, 'a.a.example.com.', kres.type.A, 2, 1)
+ check_slice(desc, 'a.a.a.example.com.', kres.type.A, 2, 1)
+
+ desc = 'randomize_psl() different qnames in different slices: '
+ check_slice(desc, 'example2.com.', kres.type.A, 1, 1)
+ check_slice(desc, 'example5.com.', kres.type.A, 3, 1)
+
+ desc = 'randomize_psl() check unregistrable domains: '
+ check_slice(desc, '.', kres.type.A, 3, 1)
+ check_slice(desc, 'com.', kres.type.A, 1, 1)
+ check_slice(desc, 'cz.', kres.type.A, 2, 1)
+ check_slice(desc, 'co.uk.', kres.type.A, 1, 1)
+
+ desc = 'randomize_psl() check multi-level reg. domains: '
+ check_slice(desc, 'example.co.uk.', kres.type.A, 3, 1)
+ check_slice(desc, 'a.example.co.uk.', kres.type.A, 3, 1)
+ check_slice(desc, 'b.example.co.uk.', kres.type.MX, 3, 1)
+ check_slice(desc, 'example2.co.uk.', kres.type.A, 2, 1)
+
+ desc = 'randomize_psl() reg. domain - always ends up in slice: '
+ check_slice(desc, 'fdsnnsdfvkdn.com.', kres.type.A, 3, 1)
+ check_slice(desc, 'bdfbd.cz.', kres.type.A, 1, 1)
+ check_slice(desc, 'nrojgvn.net.', kres.type.A, 1, 1)
+ check_slice(desc, 'jnojtnbv.engineer.', kres.type.A, 2, 1)
+ check_slice(desc, 'dfnjonfdsjg.gov.', kres.type.A, 1, 1)
+ check_slice(desc, 'okfjnosdfgjn.mil.', kres.type.A, 1, 1)
+ check_slice(desc, 'josdhnojn.test.', kres.type.A, 2, 1)
+end
+
+return {
+ test_randomize_psl,
+}
diff --git a/modules/policy/policy.test.lua b/modules/policy/policy.test.lua
new file mode 100644
index 0000000..69dda1f
--- /dev/null
+++ b/modules/policy/policy.test.lua
@@ -0,0 +1,145 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+-- setup resolver
+-- policy module should be loaded by default, do not load it explicitly
+
+-- do not attempt to contact outside world, operate only on cache
+net.ipv4 = false
+net.ipv6 = false
+-- do not listen, test is driven by config code
+env.KRESD_NO_LISTEN = true
+
+-- test for default configuration
+local function test_tls_forward()
+ boom(policy.TLS_FORWARD, {}, 'TLS_FORWARD without arguments')
+ boom(policy.TLS_FORWARD, {'1'}, 'TLS_FORWARD with non-table argument')
+ boom(policy.TLS_FORWARD, {{}}, 'TLS_FORWARD with empty table')
+ boom(policy.TLS_FORWARD, {{{}}}, 'TLS_FORWARD with empty target table')
+ boom(policy.TLS_FORWARD, {{{bleble=''}}}, 'TLS_FORWARD with invalid parameters in table')
+
+ boom(policy.TLS_FORWARD, {{'1'}}, 'TLS_FORWARD with invalid IP address')
+ boom(policy.TLS_FORWARD, {{{'::1', bleble=''}}}, 'TLS_FORWARD with valid IP and invalid parameters')
+ boom(policy.TLS_FORWARD, {{{'127.0.0.1'}}}, 'TLS_FORWARD with missing auth parameters')
+
+ ok(policy.TLS_FORWARD({{'127.0.0.1', insecure=true}}), 'TLS_FORWARD with no authentication')
+ boom(policy.TLS_FORWARD, {{{'100:dead::', insecure=true},
+ {'100:DEAD:0::', insecure=true}
+ }}, 'TLS_FORWARD with duplicate IP addresses is not allowed')
+ ok(policy.TLS_FORWARD({{'100:dead::2', insecure=true},
+ {'100:dead::2@443', insecure=true}
+ }), 'TLS_FORWARD with duplicate IP addresses but different ports is allowed')
+ ok(policy.TLS_FORWARD({{'100:dead::3', insecure=true},
+ {'100:beef::3', insecure=true}
+ }), 'TLS_FORWARD with different IPv6 addresses is allowed')
+ ok(policy.TLS_FORWARD({{'127.0.0.1', insecure=true},
+ {'127.0.0.2', insecure=true}
+ }), 'TLS_FORWARD with different IPv4 addresses is allowed')
+
+ boom(policy.TLS_FORWARD, {{{'::1', pin_sha256=''}}}, 'TLS_FORWARD with empty pin_sha256')
+ boom(policy.TLS_FORWARD, {{{'::1', pin_sha256='Ä'}}}, 'TLS_FORWARD with bad pin_sha256')
+ boom(policy.TLS_FORWARD, {{{'::1', pin_sha256='d161VN6aMSSdRN/TSDP6HZOHdaqcIvISlyFB9xLbGg='}}},
+ 'TLS_FORWARD with bad pin_sha256 (short base64)')
+ boom(policy.TLS_FORWARD, {{{'::1', pin_sha256='bbd161VN6aMSSdRN/TSDP6HZOHdaqcIvISlyFB9xLbGg='}}},
+ 'TLS_FORWARD with bad pin_sha256 (long base64)')
+ ok(policy.TLS_FORWARD({
+ {'::1', pin_sha256='g1PpXsxqPchz2tH6w9kcvVXqzQ0QclhInFP2+VWOqic='}
+ }), 'TLS_FORWARD with base64 pin_sha256')
+ ok(policy.TLS_FORWARD({
+ {'::1', pin_sha256={
+ 'ev1xcdU++dY9BlcX0QoKeaUftvXQvNIz/PCss1Z/3ek=',
+ 'SgnqTFcvYduWX7+VUnlNFT1gwSNvQdZakH7blChIRbM=',
+ 'bd161VN6aMSSdRN/TSDP6HZOHdaqcIvISlyFB9xLbGg=',
+ }}}), 'TLS_FORWARD with a table of pins')
+
+ -- ok(policy.TLS_FORWARD({{'::1', hostname='test.', ca_file='/tmp/ca.crt'}}), 'TLS_FORWARD with hostname + CA cert')
+ ok(policy.TLS_FORWARD({{'::1', hostname='test.'}}),
+ 'TLS_FORWARD with just hostname (use system CA store)')
+ boom(policy.TLS_FORWARD, {{{'::1', ca_file='/tmp/ca.crt'}}},
+ 'TLS_FORWARD with just CA cert')
+ boom(policy.TLS_FORWARD, {{{'::1', hostname='', ca_file='/tmp/ca.crt'}}},
+ 'TLS_FORWARD with empty hostname + CA cert')
+ boom(policy.TLS_FORWARD, {
+ {{'::1', hostname='test.', ca_file='/dev/a_file_which_surely_does_NOT_exist!'}}
+ }, 'TLS_FORWARD with hostname + unreadable CA cert')
+
+end
+
+local function test_slice()
+ boom(policy.slice, {function() end}, 'policy.slice() without any action')
+ ok(policy.slice, {function() end, policy.FORWARD, policy.FORWARD})
+end
+
+local function mirror_parser(srv, cv, nqueries)
+ local ffi = require('ffi')
+ local test_end = 0
+ local TIMEOUT = 5 -- seconds
+
+ while true do
+ local input = srv:xread('*a', 'bn', TIMEOUT)
+ if not input then
+ cv:signal()
+ return false, 'mirror: timeout'
+ end
+ --print(#input, input)
+ -- convert query to knot_pkt_t
+ local wire = ffi.cast("void *", input)
+ local pkt = ffi.gc(ffi.C.knot_pkt_new(wire, #input, nil), ffi.C.knot_pkt_free)
+ if not pkt then
+ cv:signal()
+ return false, 'mirror: packet allocation error'
+ end
+
+ local result = ffi.C.knot_pkt_parse(pkt, 0)
+ if result ~= 0 then
+ cv:signal()
+ return false, 'mirror: packet parse error'
+ end
+ --print(pkt)
+ test_end = test_end + 1
+
+ if test_end == nqueries then
+ cv:signal()
+ return true, 'packet mirror pass'
+ end
+
+ end
+end
+
+local function test_mirror()
+ local kluautil = require('kluautil')
+ local socket = require('cqueues.socket')
+ local cond = require('cqueues.condition')
+ local cv = cond.new()
+ local queries = {}
+ local srv = socket.listen({
+ host = "127.0.0.1",
+ port = 36659,
+ type = socket.SOCK_DGRAM,
+ })
+ -- binary mode, no buffering
+ srv:setmode('bn', 'bn')
+
+ queries["bla.mujtest.cz."] = kres.type.AAAA
+ queries["bla.mujtest2.cz."] = kres.type.AAAA
+
+ -- UDP server for test
+ worker.bg_worker.cq:wrap(function()
+ local err, msg = mirror_parser(srv, cv, kluautil.kr_table_len(queries))
+
+ ok(err, msg)
+ end)
+
+ policy.add(policy.suffix(policy.MIRROR('127.0.0.1@36659'), policy.todnames({'mujtest.cz.'})))
+ policy.add(policy.suffix(policy.MIRROR('127.0.0.1@36659'), policy.todnames({'mujtest2.cz.'})))
+
+ for name, rtype in pairs(queries) do
+ resolve(name, rtype)
+ end
+
+ cv:wait()
+end
+
+return {
+ test_tls_forward,
+ test_mirror,
+ test_slice,
+}
diff --git a/modules/policy/policy.test.rpz b/modules/policy/policy.test.rpz
new file mode 100644
index 0000000..d962e9f
--- /dev/null
+++ b/modules/policy/policy.test.rpz
@@ -0,0 +1,18 @@
+$ORIGIN testdomain.
+$TTL 30
+testdomain. SOA nonexistent.testdomain. testdomain. 1 12h 15m 3w 2h
+ NS nonexistent.testdomain.
+
+nxdomain CNAME .
+nodata CNAME *.
+*.nxdomain CNAME *.
+rpzdrop CNAME rpz-drop.
+rpzpassthru CNAME rpz-passthru.
+rra A 192.168.5.5
+rra-zonename-suffix A 192.168.6.6
+testdomain.rra.testdomain. A 192.168.7.7
+CaSe.SeNSiTiVe A 192.168.8.8
+
+two.records AAAA 2001:db8::2
+two.records AAAA 2001:db8::1
+
diff --git a/modules/policy/policy.test.rpz.soa b/modules/policy/policy.test.rpz.soa
new file mode 100644
index 0000000..ad18aa4
--- /dev/null
+++ b/modules/policy/policy.test.rpz.soa
@@ -0,0 +1,5 @@
+test2domain. SOA nonexistent.test2domain. test2domain. 1 12h 15m 3w 2h
+ NS nonexistent.test2domain.
+
+nxdomain-fqdn.test2domain. CNAME .
+nodata-fqdn.test2domain. CNAME *.
diff --git a/modules/policy/test.integr/deckard.yaml b/modules/policy/test.integr/deckard.yaml
new file mode 100644
index 0000000..9c6cb70
--- /dev/null
+++ b/modules/policy/test.integr/deckard.yaml
@@ -0,0 +1,12 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+programs:
+- name: kresd
+ binary: kresd
+ additional:
+ - --noninteractive
+ templates:
+ - modules/policy/test.integr/kresd_config.j2
+ - tests/integration/hints_zone.j2
+ configs:
+ - config
+ - hints
diff --git a/modules/policy/test.integr/kresd_config.j2 b/modules/policy/test.integr/kresd_config.j2
new file mode 100644
index 0000000..668c792
--- /dev/null
+++ b/modules/policy/test.integr/kresd_config.j2
@@ -0,0 +1,59 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+{% raw %}
+policy.add(policy.domains(policy.DENY, {todname('example.com')}))
+policy.add(policy.suffix(policy.REFUSE, {todname('refuse.example.com')}))
+
+-- make sure DNSSEC is turned off for tests
+trust_anchors.remove('.')
+
+-- Disable RFC5011 TA update
+if ta_update then
+ modules.unload('ta_update')
+end
+
+-- Disable RFC8145 signaling, scenario doesn't provide expected answers
+if ta_signal_query then
+ modules.unload('ta_signal_query')
+end
+
+-- Disable RFC8109 priming, scenario doesn't provide expected answers
+if priming then
+ modules.unload('priming')
+end
+
+-- Disable this module because it make one priming query
+if detect_time_skew then
+ modules.unload('detect_time_skew')
+end
+
+_hint_root_file('hints')
+cache.size = 2*MB
+log_level('debug')
+{% endraw %}
+
+net = { '{{SELF_ADDR}}' }
+
+
+{% if QMIN == "false" %}
+option('NO_MINIMIZE', true)
+{% else %}
+option('NO_MINIMIZE', false)
+{% endif %}
+
+
+-- Self-checks on globals
+assert(help() ~= nil)
+assert(worker.id ~= nil)
+-- Self-checks on facilities
+assert(cache.count() == 0)
+assert(cache.stats() ~= nil)
+assert(cache.backends() ~= nil)
+assert(worker.stats() ~= nil)
+assert(net.interfaces() ~= nil)
+-- Self-checks on loaded stuff
+assert(net.list()[1].transport.ip == '{{SELF_ADDR}}')
+assert(#modules.list() > 0)
+-- Self-check timers
+ev = event.recurrent(1 * sec, function (ev) return 1 end)
+event.cancel(ev)
+ev = event.after(0, function (ev) return 1 end)
diff --git a/modules/policy/test.integr/refuse.rpl b/modules/policy/test.integr/refuse.rpl
new file mode 100644
index 0000000..08f9942
--- /dev/null
+++ b/modules/policy/test.integr/refuse.rpl
@@ -0,0 +1,44 @@
+; SPDX-License-Identifier: GPL-3.0-or-later
+; config options
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test refuse policy
+
+STEP 10 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+www.refuse.example.com. IN A
+ENTRY_END
+
+STEP 20 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all answer
+; AD must not be set in the answer
+REPLY QR RD RA REFUSED
+SECTION QUESTION
+www.refuse.example.com. IN A
+SECTION ANSWER
+ENTRY_END
+
+STEP 30 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+example.com. IN A
+ENTRY_END
+
+STEP 40 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all answer
+REPLY QR RD AA RA NXDOMAIN
+SECTION QUESTION
+example.com. IN A
+SECTION ANSWER
+SECTION AUTHORITY
+example.com. 10800 IN SOA example.com. nobody.invalid. 1 3600 1200 604800 10800
+ENTRY_END
+
+
+SCENARIO_END
diff --git a/modules/predict/.packaging/test.config b/modules/predict/.packaging/test.config
new file mode 100644
index 0000000..b8e706e
--- /dev/null
+++ b/modules/predict/.packaging/test.config
@@ -0,0 +1,4 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+modules.load('predict')
+assert(predict)
+quit()
diff --git a/modules/predict/README.rst b/modules/predict/README.rst
new file mode 100644
index 0000000..966c4ca
--- /dev/null
+++ b/modules/predict/README.rst
@@ -0,0 +1,67 @@
+.. SPDX-License-Identifier: GPL-3.0-or-later
+
+.. _mod-predict:
+
+Prefetching records
+===================
+
+The ``predict`` module helps to keep the cache hot by prefetching records.
+It can utilize two independent mechanisms to select the records which should be refreshed:
+expiring records and prediction.
+
+Expiring records
+----------------
+
+This mechanism is always active when the predict module is loaded and it is not configurable.
+
+Any time the resolver answers with records that are about to expire,
+they get refreshed. (see :c:func:`is_expiring`)
+That improves latency for records which get frequently queried, relatively to their TTL.
+
+Prediction
+----------
+
+The predict module can also learn usage patterns and repetitive queries,
+though this mechanism is a prototype and **not recommended** for use in production or with high traffic.
+
+For example, if it makes a query every day at 18:00,
+the resolver expects that it is needed by that time and prefetches it ahead of time.
+This is helpful to minimize the perceived latency and keeps the cache hot.
+
+You can disable prediction by configuring ``period = 0``.
+Otherwise it will load the required :ref:`stats <mod-stats>` module if not present,
+and it will use its :func:`stats.frequent` table and clear it periodically.
+
+.. tip:: The tracking window and period length determine memory requirements. If you have a server with relatively fast query turnover, keep the period low (hour for start) and shorter tracking window (5 minutes). For personal slower resolver, keep the tracking window longer (i.e. 30 minutes) and period longer (a day), as the habitual queries occur daily. Experiment to get the best results.
+
+Example configuration
+---------------------
+
+.. code-block:: lua
+
+ modules = {
+ predict = {
+ -- this mode is NOT RECOMMENDED for use in production
+ window = 15, -- 15 minutes sampling window
+ period = 6*(60/15) -- track last 6 hours
+ }
+ }
+
+Exported metrics
+----------------
+
+To visualize the efficiency of the predictions, the module exports following statistics.
+
+* ``predict.epoch`` - current prediction epoch (based on time of day and sampling window)
+* ``predict.queue`` - number of queued queries in current window
+* ``predict.learned`` - number of learned queries in current window
+
+
+Properties
+----------
+
+.. function:: predict.config({ window = 15, period = 24})
+
+ Reconfigure the predictor to given tracking window and period length. Both parameters are optional.
+ Window length is in minutes, period is a number of windows that can be kept in memory.
+ e.g. if a ``window`` is 15 minutes, a ``period`` of "24" means 6 hours.
diff --git a/modules/predict/predict.lua b/modules/predict/predict.lua
new file mode 100644
index 0000000..0117fd5
--- /dev/null
+++ b/modules/predict/predict.lua
@@ -0,0 +1,189 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+-- Speculative prefetching for repetitive and soon-expiring records to reduce latency.
+-- @module predict
+-- @field queue queue of scheduled queries
+-- @field queue_len number of scheduled queries
+-- @field period length of prediction history (number of windows)
+-- @field window length of the prediction window
+local predict = {
+ queue = {},
+ queue_len = 0,
+ batch = 0,
+ period = 24,
+ window = 15,
+ log = {},
+}
+
+
+-- Calculate next sample with jitter [1-2/5 of window]
+local function next_event()
+ local jitter = (predict.window * minute) / 5;
+ return math.random(jitter, 2 * jitter)
+end
+
+-- Calculate current epoch (which window fits current time)
+function predict.epoch()
+ if not predict.period or predict.period <= 1 then return nil end
+ return (os.date('%H')*(60/predict.window) +
+ math.floor(os.date('%M')/predict.window)) % predict.period + 1
+end
+
+-- Resolve queued records and flush the queue
+function predict.drain()
+ local deleted = 0
+ for key, _ in pairs(predict.queue) do
+ local qtype, qname = key:match('(%S*)%s(.*)')
+ resolve(qname, kres.type[qtype], kres.class.IN, {'NO_CACHE'})
+ predict.queue[key] = nil
+ deleted = deleted + 1
+ -- Resolve smaller batches at a time
+ if predict.batch > 0 and deleted >= predict.batch then
+ break
+ end
+ end
+ -- Schedule prefetch of another batch if not complete
+ if predict.ev_drain then event.cancel(predict.ev_drain) end
+ predict.ev_drain = nil
+ if deleted > 0 then
+ predict.ev_drain = event.after((predict.window * 3) * sec, predict.drain)
+ end
+ predict.queue_len = predict.queue_len - deleted
+ stats['predict.queue'] = predict.queue_len
+ collectgarbage('step')
+ return 0
+end
+
+-- Enqueue queries from same format as predict.queue or predict.log
+local function enqueue_from_log(current)
+ if not current then return 0 end
+ local queued = 0
+ for key, val in pairs(current) do
+ if val and not predict.queue[key] then
+ predict.queue[key] = val
+ queued = queued + 1
+ end
+ end
+ return queued
+end
+
+-- Sample current epoch, return number of sampled queries
+function predict.sample(epoch_now)
+ if not epoch_now then return 0, 0 end
+ local current = predict.log[epoch_now] or {}
+ local queries = stats.frequent()
+ stats.clear_frequent()
+ local nr_samples = #queries
+ for i = 1, nr_samples do
+ local entry = queries[i]
+ local key = string.format('%s %s', entry.type, entry.name)
+ current[key] = 1
+ end
+ predict.log[epoch_now] = current
+ return nr_samples
+end
+
+-- Predict queries for the upcoming epoch
+local function generate(epoch_now)
+ if not epoch_now then return 0 end
+ local queued = 0
+ for i = 1, predict.period / 2 - 1 do
+ local current = predict.log[(epoch_now - i - 1) % predict.period + 1]
+ local past = predict.log[(epoch_now - 2*i - 1) % predict.period + 1]
+ if current and past then
+ for k, _ in pairs(current) do
+ if past[k] ~= nil and not predict.queue[k] then
+ queued = queued + 1
+ predict.queue[k] = 1
+ end
+ end
+ end
+ end
+ return queued
+end
+
+function predict.process()
+ -- Start a new epoch, or continue sampling
+ local epoch_now = predict.epoch()
+ local nr_queued = 0
+
+ -- End of epoch
+ if predict.current_epoch ~= epoch_now then
+ stats['predict.epoch'] = epoch_now
+ predict.current_epoch = epoch_now
+ -- enqueue records from upcoming epoch
+ nr_queued = enqueue_from_log(predict.log[epoch_now])
+ -- predict next epoch
+ nr_queued = nr_queued + generate(epoch_now)
+ -- clear log for new epoch
+ predict.log[epoch_now] = {}
+ end
+
+ -- Sample current epoch
+ local nr_learned = predict.sample(epoch_now)
+
+ -- Dispatch predicted queries
+ if nr_queued > 0 then
+ predict.queue_len = predict.queue_len + nr_queued
+ predict.batch = predict.queue_len / 5
+ if not predict.ev_drain then
+ predict.ev_drain = event.after(0, predict.drain)
+ end
+ end
+
+ if predict.ev_sample then event.cancel(predict.ev_sample) end
+ predict.ev_sample = event.after(next_event(), predict.process)
+ if stats then
+ stats['predict.queue'] = predict.queue_len
+ stats['predict.learned'] = nr_learned
+ end
+ collectgarbage()
+end
+
+function predict.init()
+ if predict.window > 0 and predict.period > 0 then
+ predict.current_epoch = predict.epoch()
+ predict.ev_sample = event.after(next_event(), predict.process)
+ end
+end
+
+function predict.deinit()
+ if predict.ev_sample then event.cancel(predict.ev_sample) end
+ if predict.ev_drain then event.cancel(predict.ev_drain) end
+ predict.ev_sample = nil
+ predict.ev_drain = nil
+ predict.log = {}
+ predict.queue = {}
+ predict.queue_len = 0
+ collectgarbage()
+end
+
+function predict.config(config)
+ -- Reconfigure
+ config = config or {}
+ if type(config) ~= 'table' then
+ error('[predict] configuration must be a table or nil')
+ end
+ if config.window then predict.window = config.window end
+ if config.period then predict.period = config.period end
+ -- Load dependent modules
+ if (predict.period or 0) ~= 0 and not stats then modules.load('stats') end
+ -- Reinitialize to reset timers
+ predict.deinit()
+ predict.init()
+end
+
+predict.layer = {
+ -- Prefetch all expiring (sub-)queries immediately after the request finishes.
+ -- Doing that immediately is simplest and avoids creating (new) large bursts of activity.
+ finish = function (_, req)
+ local qrys = req.rplan.resolved
+ for i = 0, (tonumber(qrys.len) - 1) do -- size_t doesn't work for some reason
+ local qry = qrys.at[i]
+ if qry.flags.EXPIRING == true then
+ resolve(kres.dname2str(qry.sname), qry.stype, qry.sclass, {'NO_CACHE'})
+ end
+ end
+ end
+}
+
+return predict
diff --git a/modules/predict/predict.test.lua b/modules/predict/predict.test.lua
new file mode 100644
index 0000000..590b41c
--- /dev/null
+++ b/modules/predict/predict.test.lua
@@ -0,0 +1,61 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+-- setup resolver
+modules = { 'predict' }
+
+-- mock global functions
+local resolve_count = 0
+local current_epoch = 0
+
+resolve = function ()
+ resolve_count = resolve_count + 1
+end
+
+stats.frequent = function ()
+ return {
+ {name = 'example.com', type = 'TYPE65535'},
+ {name = 'example.com', type = 'SOA'},
+ }
+end
+
+predict.epoch = function ()
+ return current_epoch % predict.period + 1
+end
+
+-- test if draining of prefetch queue works
+local function test_predict_drain()
+ resolve_count = 0
+ predict.queue_len = 2
+ predict.queue['TYPE65535 example.com'] = 1
+ predict.queue['SOA example.com'] = 1
+ predict.drain()
+ -- test that it attempted to prefetch
+ same(resolve_count, 2, 'attempted to prefetch on drain')
+ same(predict.queue_len, 0, 'prefetch queue empty after drain')
+end
+
+-- test if prediction process works
+local function test_predict_process()
+ -- start new epoch
+ predict.process()
+ same(predict.queue_len, 0, 'first epoch, empty prefetch queue')
+ -- next epoch, still no period for frequent queries
+ current_epoch = current_epoch + 1
+ predict.process()
+ same(predict.queue_len, 0, 'second epoch, empty prefetch queue')
+ -- next epoch, found period
+ current_epoch = current_epoch + 1
+ predict.process()
+ same(predict.queue_len, 2, 'third epoch, prefetching')
+ -- drain works with scheduled prefetches (two batches)
+ resolve_count = 0
+ predict.drain()
+ predict.drain()
+ same(resolve_count, 2, 'attempted to resolve queries in queue')
+ same(predict.queue_len, 0, 'prefetch queue is empty')
+end
+
+-- return test set
+return {
+ test_predict_drain,
+ test_predict_process
+}
diff --git a/modules/prefill/.packaging/test.config b/modules/prefill/.packaging/test.config
new file mode 100644
index 0000000..d0258b0
--- /dev/null
+++ b/modules/prefill/.packaging/test.config
@@ -0,0 +1,4 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+modules.load('prefill')
+assert(prefill)
+quit()
diff --git a/modules/prefill/README.rst b/modules/prefill/README.rst
new file mode 100644
index 0000000..a99f1f0
--- /dev/null
+++ b/modules/prefill/README.rst
@@ -0,0 +1,43 @@
+.. SPDX-License-Identifier: GPL-3.0-or-later
+
+.. _mod-prefill:
+
+Cache prefilling
+================
+
+This module provides ability to periodically prefill the DNS cache by importing root zone data obtained over HTTPS.
+
+Intended users of this module are big resolver operators which will benefit from decreased latencies and smaller amount of traffic towards DNS root servers.
+
+Example configuration is:
+
+.. code-block:: lua
+
+ modules.load('prefill')
+ prefill.config({
+ ['.'] = {
+ url = 'https://www.internic.net/domain/root.zone',
+ interval = 86400, -- seconds
+ ca_file = '/etc/pki/tls/certs/ca-bundle.crt', -- optional
+ }
+ })
+
+This configuration downloads the zone file from URL `https://www.internic.net/domain/root.zone` and imports it into the cache every 86400 seconds (1 day). The HTTPS connection is authenticated using a CA certificate from file `/etc/pki/tls/certs/ca-bundle.crt` and signed zone content is validated using DNSSEC.
+
+The root zone to be imported must be signed using DNSSEC and the resolver must have a valid DNSSEC configuration.
+
+.. csv-table::
+ :header: "Parameter", "Description"
+
+ "ca_file", "path to CA certificate bundle used to authenticate the HTTPS connection (optional, system-wide store will be used if not specified)"
+ "interval", "number of seconds between zone data refresh attempts"
+ "url", "URL of a file in :rfc:`1035` zone file format"
+
+Only root zone import is supported at the moment.
+
+Dependencies
+------------
+
+Prefilling depends on the lua-http_ library.
+
+.. _lua-http: https://luarocks.org/modules/daurnimator/http
diff --git a/modules/prefill/prefill.lua b/modules/prefill/prefill.lua
new file mode 100644
index 0000000..f4a4288
--- /dev/null
+++ b/modules/prefill/prefill.lua
@@ -0,0 +1,199 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+local ffi = require('ffi')
+
+local rz_url = "https://www.internic.net/domain/root.zone"
+local rz_local_fname = "root.zone"
+local rz_ca_file = nil
+local rz_event_id = nil
+
+local rz_default_interval = 86400
+local rz_https_fail_interval = 600
+local rz_import_error_interval = 600
+local rz_cur_interval = rz_default_interval
+local rz_interval_randomizer_limit = 10
+local rz_interval_threshold = 5
+local rz_interval_min = 3600
+
+local rz_first_try = true
+
+local prefill = {}
+
+-- hack for circular dependency between timer() and fill_cache()
+local forward_references = {}
+
+local function stop_timer()
+ if rz_event_id then
+ event.cancel(rz_event_id)
+ rz_event_id = nil
+ end
+end
+
+local function timer()
+ stop_timer()
+ worker.bg_worker.cq:wrap(forward_references.fill_cache)
+end
+
+local function restart_timer(after)
+ stop_timer()
+ rz_event_id = event.after(after * sec, timer)
+end
+
+local function display_delay(time)
+ local days = math.floor(time / 86400)
+ local hours = math.floor((time % 86400) / 3600)
+ local minutes = math.floor((time % 3600) / 60)
+ local seconds = math.floor(time % 60)
+ if days > 0 then
+ return string.format("%d days %02d hours", days, hours)
+ elseif hours > 0 then
+ return string.format("%02d hours %02d minutes", hours, minutes)
+ elseif minutes > 0 then
+ return string.format("%02d minutes %02d seconds", minutes, seconds)
+ end
+ return string.format("%02d seconds", seconds)
+end
+
+-- returns: number of seconds the file is valid for
+-- 0 indicates immediate download
+local function get_file_ttl(fname)
+ local mtime = tonumber(ffi.C.kr_file_mtime(fname))
+
+ if mtime > 0 then
+ local age = os.time() - mtime
+ return math.max(
+ rz_cur_interval - age,
+ 0)
+ else
+ return 0 -- file does not exist, download now
+ end
+end
+
+local function download(url, fname)
+ local kluautil = require('kluautil')
+ local file, rcode, errmsg
+ file, errmsg = io.open(fname, 'w')
+ if not file then
+ error(string.format("[prefil] unable to open file %s (%s)",
+ fname, errmsg))
+ end
+
+ log_info(ffi.C.LOG_GRP_PREFILL, "downloading root zone to file %s ...", fname)
+ rcode, errmsg = kluautil.kr_https_fetch(url, file, rz_ca_file)
+ if rcode == nil then
+ error(string.format("[prefil] fetch of `%s` failed: %s", url, errmsg))
+ end
+
+ file:close()
+end
+
+local function import(fname)
+ local ret = ffi.C.zi_zone_import({
+ zone_file = fname,
+ time_src = ffi.C.ZI_STAMP_MTIM, -- the file might be slightly older
+ })
+ if ret == 0 then
+ log_info(ffi.C.LOG_GRP_PREFILL, "zone successfully parsed, import started")
+ else
+ error(string.format(
+ "[prefil] zone import failed: %s", ffi.C.knot_strerror(ret)
+ ))
+ end
+end
+
+function forward_references.fill_cache()
+ local file_ttl = get_file_ttl(rz_local_fname)
+
+ if file_ttl > rz_interval_threshold then
+ log_info(ffi.C.LOG_GRP_PREFILL, "root zone file valid for %s, reusing data from disk",
+ display_delay(file_ttl))
+ else
+ local ok, errmsg = pcall(download, rz_url, rz_local_fname)
+ if not ok then
+ rz_cur_interval = rz_https_fail_interval
+ - math.random(rz_interval_randomizer_limit)
+ log_info(ffi.C.LOG_GRP_PREFILL, "cannot download new zone (%s), "
+ .. "will retry root zone download in %s",
+ errmsg, display_delay(rz_cur_interval))
+ restart_timer(rz_cur_interval)
+ os.remove(rz_local_fname)
+ return
+ end
+ file_ttl = rz_default_interval
+ end
+ -- file is up to date, import
+ -- import/filter function gets executed after resolver/module
+ local ok, errmsg = pcall(import, rz_local_fname)
+ if not ok then
+ if rz_first_try then
+ rz_first_try = false
+ rz_cur_interval = 1
+ else
+ rz_cur_interval = rz_import_error_interval
+ - math.random(rz_interval_randomizer_limit)
+ end
+ log_info(ffi.C.LOG_GRP_PREFILL, "root zone import failed (%s), retry in %s",
+ errmsg, display_delay(rz_cur_interval))
+ else
+ -- re-download before TTL expires
+ rz_cur_interval = (file_ttl - rz_interval_threshold
+ - math.random(rz_interval_randomizer_limit))
+ log_info(ffi.C.LOG_GRP_PREFILL, "root zone refresh in %s",
+ display_delay(rz_cur_interval))
+ end
+ restart_timer(rz_cur_interval)
+end
+
+function prefill.deinit()
+ stop_timer()
+end
+
+-- process one item from configuration table
+-- right now it supports only root zone because
+-- prefill module uses global variables
+local function config_zone(zone_cfg)
+ if zone_cfg.interval then
+ zone_cfg.interval = tonumber(zone_cfg.interval)
+ if zone_cfg.interval < rz_interval_min then
+ error(string.format('[prefil] refresh interval %d s is too short, '
+ .. 'minimal interval is %d s',
+ zone_cfg.interval, rz_interval_min))
+ end
+ rz_default_interval = zone_cfg.interval
+ rz_cur_interval = zone_cfg.interval
+ end
+
+ rz_ca_file = zone_cfg.ca_file
+
+ if not zone_cfg.url or not string.match(zone_cfg.url, '^https://') then
+ error('[prefil] option url must contain a '
+ .. 'https:// URL of a zone file')
+ else
+ rz_url = zone_cfg.url
+ end
+end
+
+function prefill.config(config)
+ if config == nil then return end -- e.g. just modules = { 'prefill' }
+ local root_configured = false
+ if type(config) ~= 'table' then
+ error('[prefil] configuration must be in table '
+ .. '{owner name = {per-zone config}}')
+ end
+ for owner, zone_cfg in pairs(config) do
+ if owner ~= '.' then
+ error('[prefil] only root zone can be imported '
+ .. 'at the moment')
+ else
+ config_zone(zone_cfg)
+ root_configured = true
+ end
+ end
+ if not root_configured then
+ error('[prefil] this module version requires configuration '
+ .. 'for root zone')
+ end
+
+ restart_timer(0) -- start now
+end
+
+return prefill
diff --git a/modules/prefill/prefill.test/empty.zone b/modules/prefill/prefill.test/empty.zone
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/modules/prefill/prefill.test/empty.zone
diff --git a/modules/prefill/prefill.test/example.com.zone b/modules/prefill/prefill.test/example.com.zone
new file mode 100644
index 0000000..55edbf0
--- /dev/null
+++ b/modules/prefill/prefill.test/example.com.zone
@@ -0,0 +1,12 @@
+; SPDX-License-Identifier: GPL-3.0-or-later
+$ORIGIN example.com.
+$TTL 3600
+
+@ SOA dns1.example.com. hostmaster.example.com. (
+ 2010111213 ; serial
+ 6h ; refresh
+ 1h ; retry
+ 1w ; expire
+ 1d ) ; minimum
+
+ NS dns1
diff --git a/modules/prefill/prefill.test/prefill.test.lua b/modules/prefill/prefill.test/prefill.test.lua
new file mode 100644
index 0000000..3d39d8f
--- /dev/null
+++ b/modules/prefill/prefill.test/prefill.test.lua
@@ -0,0 +1,123 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+-- unload modules which are not related to this test
+if ta_signal_query then
+ modules.unload('ta_signal_query')
+end
+if priming then
+ modules.unload('priming')
+end
+if detect_time_skew then
+ modules.unload('detect_time_skew')
+end
+
+-- test. domain is used by some tests, allow it
+policy.add(policy.suffix(policy.PASS, {todname('test.')}))
+
+cache.size = 2*MB
+-- log_level('debug')
+
+-- Self-checks on globals
+assert(help() ~= nil)
+assert(worker.id ~= nil)
+-- Self-checks on facilities
+assert(cache.stats() ~= nil)
+assert(cache.backends() ~= nil)
+assert(worker.stats() ~= nil)
+assert(net.interfaces() ~= nil)
+-- Self-checks on loaded stuff
+assert(#modules.list() > 0)
+-- Self-check timers
+ev = event.recurrent(1 * sec, function () return 1 end)
+event.cancel(ev)
+ev = event.after(0, function () return 1 end)
+
+
+-- Import fake root zone; avoid interference with configured keyfile_default.
+trust_anchors.remove('.')
+trust_anchors.add('. IN DS 18213 7 2 A1D391053583A4BC597DB9588B296060FC55EAC80B3831CA371BA1FA AE997244')
+
+-- do not attempt to contact outside world, operate only on cache
+net.ipv4 = false
+net.ipv6 = false
+-- do not listen, test is driven by config code
+env.KRESD_NO_LISTEN = true
+
+local check_answer = require('test_utils').check_answer
+
+local function zone_import(fname, downgrade)
+ return require('ffi').C.zi_zone_import({
+ zone_file = fname,
+ downgrade = downgrade,
+ })
+end
+
+local function import_valid_root_zone()
+ cache.clear()
+ local import_res = zone_import('testroot.zone')
+ assert(import_res == 0)
+ -- beware that import takes at least 100 ms
+ worker.sleep(0.2) -- zimport is delayed by 100 ms from function call
+ -- sanity checks - cache must be filled in
+ ok(cache.count() > 0, 'cache is not empty after import of valid signed root zone')
+ check_answer('root apex is in cache',
+ '.', kres.type.NS, kres.rcode.NOERROR)
+ check_answer('deep subdomain is in cache',
+ 'a.b.subtree1.', kres.type.AAAA, kres.rcode.NOERROR)
+end
+
+local function import_root_no_soa()
+ cache.clear()
+ local import_res = zone_import('testroot_no_soa.zone')
+ assert(import_res == -1)
+ -- beware that import takes at least 100 ms
+ worker.sleep(0.2) -- zimport is delayed by 100 ms from function call
+ -- sanity checks - cache must be filled in
+ ok(cache.count() == 0 , 'cache is still empty after import of zone without SOA record')
+end
+
+local function import_unsigned_root_zone()
+ cache.clear()
+ zone_import('testroot.zone.unsigned')
+ -- beware that import takes at least 100 ms
+ worker.sleep(0.2) -- zimport is delayed by 100 ms from function call
+ -- we wanted it to fail
+ ok(cache.count() == 0, 'cache is still empty after import of unsigned zone')
+end
+
+local function import_not_root_zone()
+ cache.clear()
+ zone_import('example.com.zone')
+ -- beware that import takes at least 100 ms
+ worker.sleep(0.2) -- zimport is delayed by 100 ms from function call
+ -- we wanted it to fail
+ ok(cache.count() == 0, 'cache is still empty after import of other zone than root')
+end
+
+local function import_empty_zone()
+ cache.clear()
+ local import_res = zone_import('empty.zone')
+ assert(import_res < 0)
+ -- beware that import takes at least 100 ms
+ worker.sleep(0.2) -- zimport is delayed by 100 ms from function call
+ -- sanity checks - cache must be filled in
+ ok(cache.count() == 0, 'cache is still empty after import of empty zone')
+end
+
+local function import_random_trash()
+ cache.clear()
+ local import_res = zone_import('random.zone')
+ assert(import_res < 0)
+ -- beware that import takes at least 100 ms
+ worker.sleep(0.2) -- zimport is delayed by 100 ms from function call
+ -- sanity checks - cache must be filled in
+ ok(cache.count() == 0, 'cache is still empty after import of unparseable file')
+end
+
+return {
+ import_valid_root_zone,
+ import_root_no_soa,
+ import_unsigned_root_zone,
+ import_not_root_zone,
+ import_empty_zone,
+ import_random_trash,
+}
diff --git a/modules/prefill/prefill.test/random.zone b/modules/prefill/prefill.test/random.zone
new file mode 100644
index 0000000..1650ac2
--- /dev/null
+++ b/modules/prefill/prefill.test/random.zone
@@ -0,0 +1,2 @@
+4ƒ…Óð=g<¨ú¦£k~åŸÌ>BËiÚ´= FN5—0H.ÚÄÃaÅ@æ±wUë†Ù¼’ûPné2Þ—t}‡³3Éqì©U•ž‰¡lÊΤQIa  ©y¦GíD#¿ ÈÖˆ>Ž»SdjÿÿU?ʨïTö…ÒâWMC}2 )Ø`a’œ®© *lj7Vº5¹%圅.• þü˜eZ5BI”‹òSÞšÙÉÑLv>Šþ|óœï­<dFß;ß6ï¾ ÂàG´¥L{tɹÀÝŒ*C¬÷cj$»G)­ÈÛIáœïCÿ0¦}ÏtÐãåNKþ¾^Íßd±ÐØÚ
+; SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/modules/prefill/prefill.test/testroot.zone b/modules/prefill/prefill.test/testroot.zone
new file mode 100644
index 0000000..76b9d18
--- /dev/null
+++ b/modules/prefill/prefill.test/testroot.zone
@@ -0,0 +1,59 @@
+; SPDX-License-Identifier: GPL-3.0-or-later
+; File written on Thu Aug 22 15:47:02 2019
+; dnssec_signzone version 9.11.3-1ubuntu1.8-Ubuntu
+. 86400 IN SOA rootns. you.test. (
+ 2017071102 ; serial
+ 1800 ; refresh (30 minutes)
+ 900 ; retry (15 minutes)
+ 604800 ; expire (1 week)
+ 86400 ; minimum (1 day)
+ )
+ 86400 RRSIG SOA 7 0 86400 (
+ 20500101000000 20190822124702 46349 .
+ QRmlVBvwhkNqmsp4H9zxcPeVg++5g/eR8EPb
+ DldazjUIoqbQYarTD+3DDf8tvwJu1aBNvBhm
+ cQCauTS5JWzisg== )
+ 86400 NS rootns.
+ 86400 RRSIG NS 7 0 86400 (
+ 20500101000000 20190822124702 46349 .
+ kMiL+id0WrESTSw51qI96kbolLTegn+Uraim
+ 8GjNr0d2fH8m885ORkr7C4g0RrzfAKNokArF
+ rQltwL8sMowgJg== )
+ 86400 NSEC a.b.subtree1. NS SOA RRSIG NSEC DNSKEY
+ 86400 RRSIG NSEC 7 0 86400 (
+ 20500101000000 20190822124702 46349 .
+ zv+f8FELPfYeWn7Ryy/+rBR+qASu4QC6gAka
+ vpeWRgybUQh50LrJIxINuf0YLCpqxjsX6zkK
+ zwbt0BgPHjfRHA== )
+ 86400 DNSKEY 256 3 7 (
+ AwEAAc9BtlREycexYH5az+dIbhI6sM56F+kd
+ SI43ZTGNT/Bam5vGrXju0uTHCJ2+KBwOSz7d
+ ZVchX0ulIJOUV9MteT0=
+ ) ; ZSK; alg = NSEC3RSASHA1 ; key id = 46349
+ 86400 DNSKEY 257 3 7 (
+ AwEAAcEFKHPyE1JMfRLhJK9mgcBZ+TR0Pj6u
+ shF6YbLkQoRs6Uzm458ErCcAdukJsTckqCzq
+ PFEqGLRztzyAJ7Z3G0k=
+ ) ; KSK; alg = NSEC3RSASHA1 ; key id = 18213
+ 86400 RRSIG DNSKEY 7 0 86400 (
+ 20500101000000 20190822124702 18213 .
+ ih4ScNqt9muT/Dqc05oO5T/xAyRK1/LblHph
+ GHedPHW7mC6IzsDBbqjD/P1nVK5RkM2Q+ozV
+ Ltbtmt2CafXsLA== )
+ 86400 RRSIG DNSKEY 7 0 86400 (
+ 20500101000000 20190822124702 46349 .
+ Lqle63cGoJdZA4CHHUq3ZqFxsbYATelzj5Dl
+ lDcc7vLbn2Qy9AVUC5I6UdZqMK2UDyO+DWCG
+ Cmq5705eAQlcsQ== )
+a.b.subtree1. 86400 IN AAAA 2001:db8::
+ 86400 RRSIG AAAA 7 3 86400 (
+ 20500101000000 20190822124702 46349 .
+ Hq6CUu3CVN/90b1Sozv0uIgH5ePxY3olc3eq
+ PoeyfdS+3HjSgb+Ji+GjYAAOMaVDS0APwwMe
+ pHxhdgO/zpKHRQ== )
+ 86400 NSEC . AAAA RRSIG NSEC
+ 86400 RRSIG NSEC 7 3 86400 (
+ 20500101000000 20190822124702 46349 .
+ lcJ7xdzxgTTvj2JiwzhDRyxTx2ZJ5zwzx0hC
+ ttTrSfG+2GyMnPzJ9MFid5S2w0WbWOWWLaKH
+ O0ucI8xvYInNAA== )
diff --git a/modules/prefill/prefill.test/testroot.zone.unsigned b/modules/prefill/prefill.test/testroot.zone.unsigned
new file mode 100644
index 0000000..fbc551f
--- /dev/null
+++ b/modules/prefill/prefill.test/testroot.zone.unsigned
@@ -0,0 +1,4 @@
+; SPDX-License-Identifier: GPL-3.0-or-later
+. 86400 SOA rootns. you.test. 2017071101 1800 900 604800 86400
+. 86400 NS rootns.
+a.b.subtree1. 86400 AAAA 2001:db8::
diff --git a/modules/prefill/prefill.test/testroot_no_soa.zone b/modules/prefill/prefill.test/testroot_no_soa.zone
new file mode 100644
index 0000000..e3ad08c
--- /dev/null
+++ b/modules/prefill/prefill.test/testroot_no_soa.zone
@@ -0,0 +1,52 @@
+; SPDX-License-Identifier: GPL-3.0-or-later
+; File written on Thu Aug 22 15:47:02 2019
+; dnssec_signzone version 9.11.3-1ubuntu1.8-Ubuntu
+. 86400 RRSIG SOA 7 0 86400 (
+ 20500101000000 20190822124702 46349 .
+ QRmlVBvwhkNqmsp4H9zxcPeVg++5g/eR8EPb
+ DldazjUIoqbQYarTD+3DDf8tvwJu1aBNvBhm
+ cQCauTS5JWzisg== )
+ 86400 NS rootns.
+ 86400 RRSIG NS 7 0 86400 (
+ 20500101000000 20190822124702 46349 .
+ kMiL+id0WrESTSw51qI96kbolLTegn+Uraim
+ 8GjNr0d2fH8m885ORkr7C4g0RrzfAKNokArF
+ rQltwL8sMowgJg== )
+ 86400 NSEC a.b.subtree1. NS SOA RRSIG NSEC DNSKEY
+ 86400 RRSIG NSEC 7 0 86400 (
+ 20500101000000 20190822124702 46349 .
+ zv+f8FELPfYeWn7Ryy/+rBR+qASu4QC6gAka
+ vpeWRgybUQh50LrJIxINuf0YLCpqxjsX6zkK
+ zwbt0BgPHjfRHA== )
+ 86400 DNSKEY 256 3 7 (
+ AwEAAc9BtlREycexYH5az+dIbhI6sM56F+kd
+ SI43ZTGNT/Bam5vGrXju0uTHCJ2+KBwOSz7d
+ ZVchX0ulIJOUV9MteT0=
+ ) ; ZSK; alg = NSEC3RSASHA1 ; key id = 46349
+ 86400 DNSKEY 257 3 7 (
+ AwEAAcEFKHPyE1JMfRLhJK9mgcBZ+TR0Pj6u
+ shF6YbLkQoRs6Uzm458ErCcAdukJsTckqCzq
+ PFEqGLRztzyAJ7Z3G0k=
+ ) ; KSK; alg = NSEC3RSASHA1 ; key id = 18213
+ 86400 RRSIG DNSKEY 7 0 86400 (
+ 20500101000000 20190822124702 18213 .
+ ih4ScNqt9muT/Dqc05oO5T/xAyRK1/LblHph
+ GHedPHW7mC6IzsDBbqjD/P1nVK5RkM2Q+ozV
+ Ltbtmt2CafXsLA== )
+ 86400 RRSIG DNSKEY 7 0 86400 (
+ 20500101000000 20190822124702 46349 .
+ Lqle63cGoJdZA4CHHUq3ZqFxsbYATelzj5Dl
+ lDcc7vLbn2Qy9AVUC5I6UdZqMK2UDyO+DWCG
+ Cmq5705eAQlcsQ== )
+a.b.subtree1. 86400 IN AAAA 2001:db8::
+ 86400 RRSIG AAAA 7 3 86400 (
+ 20500101000000 20190822124702 46349 .
+ Hq6CUu3CVN/90b1Sozv0uIgH5ePxY3olc3eq
+ PoeyfdS+3HjSgb+Ji+GjYAAOMaVDS0APwwMe
+ pHxhdgO/zpKHRQ== )
+ 86400 NSEC . AAAA RRSIG NSEC
+ 86400 RRSIG NSEC 7 3 86400 (
+ 20500101000000 20190822124702 46349 .
+ lcJ7xdzxgTTvj2JiwzhDRyxTx2ZJ5zwzx0hC
+ ttTrSfG+2GyMnPzJ9MFid5S2w0WbWOWWLaKH
+ O0ucI8xvYInNAA== )
diff --git a/modules/priming/.packaging/test.config b/modules/priming/.packaging/test.config
new file mode 100644
index 0000000..63239f0
--- /dev/null
+++ b/modules/priming/.packaging/test.config
@@ -0,0 +1,4 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+modules.load('priming')
+assert(priming)
+quit()
diff --git a/modules/priming/README.rst b/modules/priming/README.rst
new file mode 100644
index 0000000..b74bad4
--- /dev/null
+++ b/modules/priming/README.rst
@@ -0,0 +1,18 @@
+.. SPDX-License-Identifier: GPL-3.0-or-later
+
+.. _mod-priming:
+
+Priming module
+==============
+
+The module for Initializing a DNS Resolver with Priming Queries implemented
+according to :rfc:`8109`. Purpose of the module is to keep up-to-date list of
+root DNS servers and associated IP addresses.
+
+Result of successful priming query replaces root hints distributed with
+the resolver software. Unlike other DNS resolvers, Knot Resolver caches
+result of priming query on disk and keeps the data between restarts until
+TTL expires.
+
+This module is enabled by default; you may disable it by adding
+``modules.unload('priming')`` to your configuration.
diff --git a/modules/priming/priming.lua b/modules/priming/priming.lua
new file mode 100644
index 0000000..624a9df
--- /dev/null
+++ b/modules/priming/priming.lua
@@ -0,0 +1,130 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+-- Module interface
+local ffi = require('ffi')
+
+local priming = {}
+priming.retry_time = 10 * sec -- retry time when priming fail
+
+-- internal state variables and functions
+local internal = {}
+internal.nsset = {} -- set of resolved nameservers
+internal.min_ttl = 0 -- minimal TTL of NS records
+internal.to_resolve = 0 -- number of pending queries to A or AAAA
+internal.prime = {} -- function triggering priming query
+internal.event = nil -- stores event id
+
+-- Copy hints from nsset table to resolver engine
+-- These addresses replace root hints loaded by default from file.
+-- They are stored outside cache and cache flush will not affect them.
+local function publish_hints(nsset)
+ local roothints = kres.context().root_hints
+ -- reset zone cut and clear address list
+ ffi.C.kr_zonecut_set(roothints, kres.str2dname("."))
+ for dname, addrsets in pairs(nsset) do
+ for i = 0, addrsets:rdcount() - 1 do
+ local rdpt = addrsets:rdata_pt(i)
+ ffi.C.kr_zonecut_add(roothints, dname, rdpt.data, rdpt.len)
+ end
+ end
+end
+
+-- Count A and AAAA addresses in nsset
+local function count_addresses(nsset)
+ local count = 0
+ for _, addrset in pairs(nsset) do
+ count = count + addrset:rdcount()
+ end
+ return count
+end
+
+-- Callback for response from A or AAAA query for root nameservers
+-- address is added to table internal.nsset.
+-- When all response is processed internal.nsset is published in resolver engine
+-- luacheck: no unused args
+local function address_callback(pkt, req)
+ if pkt == nil or pkt:rcode() ~= kres.rcode.NOERROR then
+ pkt = req.qsource.packet
+ log_info(ffi.C.LOG_GRP_PRIMING, "cannot resolve address '%s', type: %d", kres.dname2str(pkt:qname()), pkt:qtype())
+ else
+ local section = pkt:rrsets(kres.section.ANSWER)
+ for i = 1, #section do
+ local rrset_new = section[i]
+ if rrset_new.type == kres.type.A or rrset_new.type == kres.type.AAAA then
+ local owner = rrset_new:owner()
+ local rrset_comb = internal.nsset[owner]
+ if rrset_comb == nil then
+ rrset_comb = kres.rrset(nil, rrset_new.type)
+ internal.nsset[owner] = rrset_comb
+ end
+ assert(ffi.istype(kres.rrset, rrset_new))
+ rrset_comb:merge_rdata(rrset_new)
+ end
+ end
+ end
+ internal.to_resolve = internal.to_resolve - 1
+ if internal.to_resolve == 0 then
+ if count_addresses(internal.nsset) == 0 then
+ log_info(ffi.C.LOG_GRP_PRIMING, "cannot resolve any root server address, \
+ next priming query in %d seconds", priming.retry_time / sec)
+ internal.event = event.after(priming.retry_time, internal.prime)
+ else
+ publish_hints(internal.nsset)
+ log_info(ffi.C.LOG_GRP_PRIMING, "triggered priming query, next in %d seconds", internal.min_ttl)
+ internal.event = event.after(internal.min_ttl * sec, internal.prime)
+ end
+ end
+end
+
+-- Callback for priming query ('.' NS)
+-- For every NS record creates two separate queries for A and AAAA.
+-- These new queries should be resolved from cache.
+-- luacheck: no unused args
+local function priming_callback(pkt, req)
+ if pkt == nil or pkt:rcode() ~= kres.rcode.NOERROR then
+ log_info(ffi.C.LOG_GRP_PRIMING, "cannot resolve '.' NS, next priming query in %d seconds", priming.retry_time / sec)
+ internal.event = event.after(priming.retry_time, internal.prime)
+ return nil
+ end
+ local section = pkt:rrsets(kres.section.ANSWER)
+ for i = 1, #section do
+ local rr = section[i]
+ if rr.type == kres.type.NS then
+ internal.min_ttl = math.min(internal.min_ttl, rr:ttl())
+ internal.to_resolve = internal.to_resolve + 2 * rr.rrs.count
+ for k = 0, rr.rrs.count-1 do
+ local nsname_text = rr:tostring(k)
+ if net.ipv4 then
+ resolve(nsname_text, kres.type.A, kres.class.IN, 0, address_callback)
+ end
+ if net.ipv6 then
+ resolve(nsname_text, kres.type.AAAA, kres.class.IN, 0, address_callback)
+ end
+ end
+ end
+ end
+end
+
+-- trigger priming query
+function internal.prime()
+ internal.min_ttl = math.max(1, cache.max_ttl()) -- sanity check for disabled cache
+ internal.nsset = {}
+ internal.to_resolve = 0
+ resolve(".", kres.type.NS, kres.class.IN, 0, priming_callback)
+end
+
+function priming.init()
+ if internal.event then
+ error("Priming module is already loaded.")
+ else
+ internal.event = event.after(0 , internal.prime)
+ end
+end
+
+function priming.deinit()
+ if internal.event then
+ event.cancel(internal.event)
+ internal.event = nil
+ end
+end
+
+return priming
diff --git a/modules/rebinding/.packaging/test.config b/modules/rebinding/.packaging/test.config
new file mode 100644
index 0000000..0a84b88
--- /dev/null
+++ b/modules/rebinding/.packaging/test.config
@@ -0,0 +1,4 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+modules.load('rebinding')
+assert(rebinding)
+quit()
diff --git a/modules/rebinding/README.rst b/modules/rebinding/README.rst
new file mode 100644
index 0000000..222d1da
--- /dev/null
+++ b/modules/rebinding/README.rst
@@ -0,0 +1,29 @@
+.. SPDX-License-Identifier: GPL-3.0-or-later
+
+.. _mod-rebinding:
+
+Rebinding protection
+====================
+
+This module provides protection from `DNS Rebinding attack`_ by blocking
+answers which contain IPv4_ or IPv6_ addresses for private use
+(or some other special-use addresses).
+
+To enable this module insert following line into your configuration file:
+
+.. code-block:: lua
+
+ modules.load('rebinding < iterate')
+
+Please note that this module does not offer stable configuration interface
+yet. For this reason it is suitable mainly for public resolver operators
+who do not need to whitelist certain subnets.
+
+.. warning:: DNS Blacklists (`RFC 5782`_) often use `127.0.0.0/8` to blacklist
+ a domain. Using the rebinding module prevents DNSBL from functioning
+ properly.
+
+.. _`DNS Rebinding attack`: https://en.wikipedia.org/wiki/DNS_rebinding
+.. _IPv4: https://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml
+.. _IPv6: https://www.iana.org/assignments/iana-ipv6-special-registry/iana-ipv6-special-registry.xhtml
+.. _`RFC 5782`: https://tools.ietf.org/html/rfc5782#section-2.1
diff --git a/modules/rebinding/rebinding.lua b/modules/rebinding/rebinding.lua
new file mode 100644
index 0000000..d5d6e74
--- /dev/null
+++ b/modules/rebinding/rebinding.lua
@@ -0,0 +1,115 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+local ffi = require('ffi')
+
+-- Protection from DNS rebinding attacks
+local kres = require('kres')
+local renumber = require('kres_modules.renumber')
+local policy = require('kres_modules.policy')
+
+local M = {}
+M.layer = {}
+M.blacklist = {
+ -- https://www.iana.org/assignments/iana-ipv4-special-registry
+ -- + IPv4-to-IPv6 mapping
+ renumber.prefix('0.0.0.0/8', '0.0.0.0'),
+ renumber.prefix('::ffff:0.0.0.0/104', '::'),
+ renumber.prefix('10.0.0.0/8', '0.0.0.0'),
+ renumber.prefix('::ffff:10.0.0.0/104', '::'),
+ renumber.prefix('100.64.0.0/10', '0.0.0.0'),
+ renumber.prefix('::ffff:100.64.0.0/106', '::'),
+ renumber.prefix('127.0.0.0/8', '0.0.0.0'),
+ renumber.prefix('::ffff:127.0.0.0/104', '::'),
+ renumber.prefix('169.254.0.0/16', '0.0.0.0'),
+ renumber.prefix('::ffff:169.254.0.0/112', '::'),
+ renumber.prefix('172.16.0.0/12', '0.0.0.0'),
+ renumber.prefix('::ffff:172.16.0.0/108', '::'),
+ renumber.prefix('192.168.0.0/16', '0.0.0.0'),
+ renumber.prefix('::ffff:192.168.0.0/112', '::'),
+ -- https://www.iana.org/assignments/iana-ipv6-special-registry/iana-ipv6-special-registry.xhtml
+ renumber.prefix('::/128', '::'),
+ renumber.prefix('::1/128', '::'),
+ renumber.prefix('fc00::/7', '::'),
+ renumber.prefix('fe80::/10', '::'),
+} -- second parameter for renumber module is ignored except for being v4 or v6
+
+local function is_rr_blacklisted(rr)
+ for i = 1, #M.blacklist do
+ local prefix = M.blacklist[i]
+ -- Match record type to address family and record address to given subnet
+ if renumber.match_subnet(prefix[1], prefix[2], prefix[4], rr) then
+ return true
+ end
+ end
+ return false
+end
+
+local function check_section(pkt, section)
+ local records = pkt:section(section)
+ local count = #records
+ if count == 0 then
+ return nil end
+ for i = 1, count do
+ local rr = records[i]
+ if rr.type == kres.type.A or rr.type == kres.type.AAAA then
+ local result = is_rr_blacklisted(rr)
+ if result then
+ return rr end
+ end
+ end
+end
+
+local function check_pkt(pkt)
+ for _, section in ipairs({kres.section.ANSWER,
+ kres.section.AUTHORITY,
+ kres.section.ADDITIONAL}) do
+ local bad_rr = check_section(pkt, section)
+ if bad_rr then
+ return bad_rr
+ end
+ end
+end
+
+local function refuse(req)
+ policy.REFUSE(nil, req)
+ local pkt = req:ensure_answer()
+ if pkt == nil then return nil end
+ pkt:aa(false)
+ pkt:begin(kres.section.ADDITIONAL)
+
+ local msg = 'blocked by DNS rebinding protection'
+ pkt:put('\11explanation\7invalid\0', 10800, pkt:qclass(), kres.type.TXT,
+ string.char(#msg) .. msg)
+ return kres.DONE
+end
+
+-- act on DNS queries which were not answered from cache
+function M.layer.consume(state, req, pkt)
+ if state == kres.FAIL then
+ return state end
+
+ local qry = req:current()
+ if qry.flags.CACHED or qry.flags.ALLOW_LOCAL then -- do not slow down cached queries
+ return state end
+
+ local bad_rr = check_pkt(pkt)
+ if not bad_rr then
+ return state end
+
+ qry.flags.RESOLVED = 1 -- stop iteration
+ qry.flags.CACHED = 1 -- do not cache
+
+ --[[ In case we're in a sub-query, we do not touch the final req answer.
+ Only this sub-query will get finished without a result - there we
+ rely on the iterator reacting to flags.RESOLVED
+ Typical example: NS address resolution -> only this NS won't be used
+ but others may still be OK (or we SERVFAIL due to no NS being usable).
+ --]]
+ if qry.parent == nil then
+ state = refuse(req)
+ end
+ log_qry(qry, ffi.C.LOG_GRP_REBIND,
+ 'blocking blacklisted IP in RR \'%s\'\n', kres.rr2str(bad_rr))
+ return state
+end
+
+return M
diff --git a/modules/rebinding/test.integr/deckard.yaml b/modules/rebinding/test.integr/deckard.yaml
new file mode 100644
index 0000000..9b1793b
--- /dev/null
+++ b/modules/rebinding/test.integr/deckard.yaml
@@ -0,0 +1,12 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+programs:
+- name: kresd
+ binary: kresd
+ additional:
+ - --noninteractive
+ templates:
+ - modules/rebinding/test.integr/kresd_config.j2
+ - tests/integration/hints_zone.j2
+ configs:
+ - config
+ - hints
diff --git a/modules/rebinding/test.integr/kresd_config.j2 b/modules/rebinding/test.integr/kresd_config.j2
new file mode 100644
index 0000000..aed3551
--- /dev/null
+++ b/modules/rebinding/test.integr/kresd_config.j2
@@ -0,0 +1,59 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+{% raw %}
+-- make sure DNSSEC is turned off for tests
+trust_anchors.remove('.')
+
+-- Disable RFC5011 TA update
+if ta_update then
+ modules.unload('ta_update')
+end
+
+-- Disable RFC8145 signaling, scenario doesn't provide expected answers
+if ta_signal_query then
+ modules.unload('ta_signal_query')
+end
+
+-- Disable RFC8109 priming, scenario doesn't provide expected answers
+if priming then
+ modules.unload('priming')
+end
+
+-- Disable this module because it make one priming query
+if detect_time_skew then
+ modules.unload('detect_time_skew')
+end
+
+modules.load('rebinding < iterate')
+
+_hint_root_file('hints')
+cache.size = 2*MB
+log_level('debug')
+net.ipv6 = false
+{% endraw %}
+
+net = { '{{SELF_ADDR}}' }
+
+
+{% if QMIN == "false" %}
+option('NO_MINIMIZE', true)
+{% else %}
+option('NO_MINIMIZE', false)
+{% endif %}
+
+
+-- Self-checks on globals
+assert(help() ~= nil)
+assert(worker.id ~= nil)
+-- Self-checks on facilities
+assert(cache.count() == 0)
+assert(cache.stats() ~= nil)
+assert(cache.backends() ~= nil)
+assert(worker.stats() ~= nil)
+assert(net.interfaces() ~= nil)
+-- Self-checks on loaded stuff
+assert(net.list()[1].transport.ip == '{{SELF_ADDR}}')
+assert(#modules.list() > 0)
+-- Self-check timers
+ev = event.recurrent(1 * sec, function (ev) return 1 end)
+event.cancel(ev)
+ev = event.after(0, function (ev) return 1 end)
diff --git a/modules/rebinding/test.integr/module_rebinding.rpl b/modules/rebinding/test.integr/module_rebinding.rpl
new file mode 100644
index 0000000..1e344c5
--- /dev/null
+++ b/modules/rebinding/test.integr/module_rebinding.rpl
@@ -0,0 +1,834 @@
+; SPDX-License-Identifier: GPL-3.0-or-later
+; config options
+; target-fetch-policy: "0 0 0 0 0"
+; module-config: "iterator"
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test protection from DNS rebinding
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 1000
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+; net.
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+net. IN NS
+SECTION AUTHORITY
+. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+; root-servers.net.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+root-servers.net. IN NS
+SECTION ANSWER
+root-servers.net. IN NS k.root-servers.net.
+SECTION ADDITIONAL
+k.root-servers.net. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+root-servers.net. IN A
+SECTION AUTHORITY
+root-servers.net. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+k.root-servers.net. IN A
+SECTION ANSWER
+k.root-servers.net. IN A 193.0.14.129
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+k.root-servers.net. IN AAAA
+SECTION AUTHORITY
+root-servers.net. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+; gtld-servers.net.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+gtld-servers.net. IN NS
+SECTION ANSWER
+gtld-servers.net. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+gtld-servers.net. IN A
+SECTION AUTHORITY
+gtld-servers.net. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+a.gtld-servers.net. IN A
+SECTION ANSWER
+a.gtld-servers.net. IN A 192.5.6.30
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+a.gtld-servers.net. IN AAAA
+SECTION AUTHORITY
+gtld-servers.net. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 1000
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+
+; NS with address pointing into a private range must not be followed
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+attacker.com. IN A
+SECTION AUTHORITY
+attacker.com. IN NS ns.attacker.com.
+SECTION ADDITIONAL
+ns.attacker.com. IN A 192.168.3.5
+ENTRY_END
+RANGE_END
+
+; ns.attacker.com.
+RANGE_BEGIN 0 1000
+ ADDRESS 19.168.3.5
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+attacker.com. IN NS
+SECTION ANSWER
+attacker.com. IN NS ns.attacker.com.
+SECTION ADDITIONAL
+ns.attacker.com. IN A 192.168.3.5
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.attacker.com. IN A
+SECTION ANSWER
+www.attacker.com. IN A 192.0.2.55
+ENTRY_END
+RANGE_END
+
+
+; ns.example.com.
+RANGE_BEGIN 0 1000
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 192.0.2.40
+ENTRY_END
+
+; blacklisted IP addresses
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+attack-ipv4-0-0-0-0.example.com. IN A
+SECTION ANSWER
+attack-ipv4-0-0-0-0.example.com. IN A 0.0.0.0
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+attack-ipv4over6-0-0-0-0.example.com. IN AAAA
+SECTION ANSWER
+attack-ipv4over6-0-0-0-0.example.com. IN AAAA ::ffff:0.0.0.0
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+attack-ipv4-10-1-2-3.example.com. IN A
+SECTION ANSWER
+attack-ipv4-10-1-2-3.example.com. IN A 10.1.2.3
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+attack-ipv4over6-10-2-3-4.example.com. IN AAAA
+SECTION ANSWER
+attack-ipv4over6-10-2-3-4.example.com. IN AAAA ::ffff:10.2.3.4
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+attack-ipv4-100-127-255-254.example.com. IN A
+SECTION ANSWER
+attack-ipv4-100-127-255-254.example.com. IN A 100.127.255.254
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+attack-ipv4over6-100-127-255-255.example.com. IN AAAA
+SECTION ANSWER
+attack-ipv4over6-100-127-255-255.example.com. IN AAAA ::ffff:100.127.255.255
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+attack-ipv4-127-0-0-1.example.com. IN A
+SECTION ANSWER
+attack-ipv4-127-0-0-1.example.com. IN A 127.0.0.1
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+attack-ipv4over6-127-0-0-1.example.com. IN AAAA
+SECTION ANSWER
+attack-ipv4over6-127-0-0-1.example.com. IN AAAA ::ffff:127.0.0.1
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+attack-ipv4-169-254-255-255.example.com. IN A
+SECTION ANSWER
+attack-ipv4-169-254-255-255.example.com. IN A 169.254.255.255
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+attack-ipv4over6-169-254-0-0.example.com. IN AAAA
+SECTION ANSWER
+attack-ipv4over6-169-254-0-0.example.com. IN AAAA ::ffff:169.254.0.0
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+attack-ipv4-172-16-0-0.example.com. IN A
+SECTION ANSWER
+attack-ipv4-172-16-0-0.example.com. IN A 172.16.0.0
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+attack-ipv4over6-172-31-255-255.example.com. IN AAAA
+SECTION ANSWER
+attack-ipv4over6-172-31-255-255.example.com. IN AAAA ::ffff:172.31.255.255
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+attack-ipv4-192-168-3-8.example.com. IN A
+SECTION ANSWER
+attack-ipv4-192-168-3-8.example.com. IN A 192.168.3.8
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+attack-ipv4over6-192-168-254-210.example.com. IN AAAA
+SECTION ANSWER
+attack-ipv4over6-192-168-254-210.example.com. IN AAAA ::ffff:192.168.254.210
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+attack-ipv6-.example.com. IN AAAA
+SECTION ANSWER
+attack-ipv6-.example.com. IN AAAA ::
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+attack-ipv6-1.example.com. IN AAAA
+SECTION ANSWER
+attack-ipv6-1.example.com. IN AAAA ::1
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+attack-ipv6-fc00.example.com. IN AAAA
+SECTION ANSWER
+attack-ipv6-fc00.example.com. IN AAAA fc00::
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+attack-ipv6-fe80.example.com. IN AAAA
+SECTION ANSWER
+attack-ipv6-fe80.example.com. IN AAAA fe80::
+ENTRY_END
+
+RANGE_END
+
+STEP 11 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+; recursion happens here, no blacklisted IP address is present
+STEP 12 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 192.0.2.40
+;SECTION AUTHORITY
+;example.com. IN NS ns.example.com.
+;SECTION ADDITIONAL
+;ns.example.com. IN A 1.2.3.4
+ENTRY_END
+
+; test that 0.0.0.0 is blacklisted
+STEP 201 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+attack-ipv4-0-0-0-0.example.com. IN A
+ENTRY_END
+
+STEP 202 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all answer authority
+REPLY QR RD RA REFUSED
+SECTION QUESTION
+attack-ipv4-0-0-0-0.example.com. IN A
+SECTION ANSWER
+SECTION AUTHORITY
+SECTION ADDITIONAL
+explanation.invalid. TXT "blocked by DNS rebinding protection"
+ENTRY_END
+
+; test that ::ffff:0.0.0.0 is blacklisted
+STEP 211 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+attack-ipv4over6-0-0-0-0.example.com. IN AAAA
+ENTRY_END
+
+STEP 212 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all answer authority
+REPLY QR RD RA REFUSED
+SECTION QUESTION
+attack-ipv4over6-0-0-0-0.example.com. IN AAAA
+SECTION ANSWER
+SECTION AUTHORITY
+SECTION ADDITIONAL
+explanation.invalid. TXT "blocked by DNS rebinding protection"
+ENTRY_END
+
+; test that 10.1.2.3 is blacklisted
+STEP 221 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+attack-ipv4-10-1-2-3.example.com. IN A
+ENTRY_END
+
+STEP 222 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all answer authority
+REPLY QR RD RA REFUSED
+SECTION QUESTION
+attack-ipv4-10-1-2-3.example.com. IN A
+SECTION ANSWER
+SECTION AUTHORITY
+SECTION ADDITIONAL
+explanation.invalid. TXT "blocked by DNS rebinding protection"
+ENTRY_END
+
+; test that ::ffff:10.2.3.4 is blacklisted
+STEP 231 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+attack-ipv4over6-10-2-3-4.example.com. IN AAAA
+ENTRY_END
+
+STEP 232 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all answer authority
+REPLY QR RD RA REFUSED
+SECTION QUESTION
+attack-ipv4over6-10-2-3-4.example.com. IN AAAA
+SECTION ANSWER
+SECTION AUTHORITY
+SECTION ADDITIONAL
+explanation.invalid. TXT "blocked by DNS rebinding protection"
+ENTRY_END
+
+; test that 100.127.255.254 is blacklisted
+STEP 241 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+attack-ipv4-100-127-255-254.example.com. IN A
+ENTRY_END
+
+STEP 242 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all answer authority
+REPLY QR RD RA REFUSED
+SECTION QUESTION
+attack-ipv4-100-127-255-254.example.com. IN A
+SECTION ANSWER
+SECTION AUTHORITY
+SECTION ADDITIONAL
+explanation.invalid. TXT "blocked by DNS rebinding protection"
+ENTRY_END
+
+; test that ::ffff:100.127.255.255 is blacklisted
+STEP 251 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+attack-ipv4over6-100-127-255-255.example.com. IN AAAA
+ENTRY_END
+
+STEP 252 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all answer authority
+REPLY QR RD RA REFUSED
+SECTION QUESTION
+attack-ipv4over6-100-127-255-255.example.com. IN AAAA
+SECTION ANSWER
+SECTION AUTHORITY
+SECTION ADDITIONAL
+explanation.invalid. TXT "blocked by DNS rebinding protection"
+ENTRY_END
+
+; test that 127.0.0.1 is blacklisted
+STEP 261 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+attack-ipv4-127-0-0-1.example.com. IN A
+ENTRY_END
+
+STEP 262 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all answer authority
+REPLY QR RD RA REFUSED
+SECTION QUESTION
+attack-ipv4-127-0-0-1.example.com. IN A
+SECTION ANSWER
+SECTION AUTHORITY
+SECTION ADDITIONAL
+explanation.invalid. TXT "blocked by DNS rebinding protection"
+ENTRY_END
+
+; test that ::ffff:127.0.0.1 is blacklisted
+STEP 271 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+attack-ipv4over6-127-0-0-1.example.com. IN AAAA
+ENTRY_END
+
+STEP 272 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all answer authority
+REPLY QR RD RA REFUSED
+SECTION QUESTION
+attack-ipv4over6-127-0-0-1.example.com. IN AAAA
+SECTION ANSWER
+SECTION AUTHORITY
+SECTION ADDITIONAL
+explanation.invalid. TXT "blocked by DNS rebinding protection"
+ENTRY_END
+
+; test that 169.254.255.255 is blacklisted
+STEP 281 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+attack-ipv4-169-254-255-255.example.com. IN A
+ENTRY_END
+
+STEP 282 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all answer authority
+REPLY QR RD RA REFUSED
+SECTION QUESTION
+attack-ipv4-169-254-255-255.example.com. IN A
+SECTION ANSWER
+SECTION AUTHORITY
+SECTION ADDITIONAL
+explanation.invalid. TXT "blocked by DNS rebinding protection"
+ENTRY_END
+
+; test that ::ffff:169.254.0.0 is blacklisted
+STEP 291 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+attack-ipv4over6-169-254-0-0.example.com. IN AAAA
+ENTRY_END
+
+STEP 292 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all answer authority
+REPLY QR RD RA REFUSED
+SECTION QUESTION
+attack-ipv4over6-169-254-0-0.example.com. IN AAAA
+SECTION ANSWER
+SECTION AUTHORITY
+SECTION ADDITIONAL
+explanation.invalid. TXT "blocked by DNS rebinding protection"
+ENTRY_END
+
+; test that 172.16.0.0 is blacklisted
+STEP 301 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+attack-ipv4-172-16-0-0.example.com. IN A
+ENTRY_END
+
+STEP 302 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all answer authority
+REPLY QR RD RA REFUSED
+SECTION QUESTION
+attack-ipv4-172-16-0-0.example.com. IN A
+SECTION ANSWER
+SECTION AUTHORITY
+SECTION ADDITIONAL
+explanation.invalid. TXT "blocked by DNS rebinding protection"
+ENTRY_END
+
+; test that ::ffff:172.31.255.255 is blacklisted
+STEP 311 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+attack-ipv4over6-172-31-255-255.example.com. IN AAAA
+ENTRY_END
+
+STEP 312 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all answer authority
+REPLY QR RD RA REFUSED
+SECTION QUESTION
+attack-ipv4over6-172-31-255-255.example.com. IN AAAA
+SECTION ANSWER
+SECTION AUTHORITY
+SECTION ADDITIONAL
+explanation.invalid. TXT "blocked by DNS rebinding protection"
+ENTRY_END
+
+; test that 192.168.3.8 is blacklisted
+STEP 321 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+attack-ipv4-192-168-3-8.example.com. IN A
+ENTRY_END
+
+STEP 322 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all answer authority
+REPLY QR RD RA REFUSED
+SECTION QUESTION
+attack-ipv4-192-168-3-8.example.com. IN A
+SECTION ANSWER
+SECTION AUTHORITY
+SECTION ADDITIONAL
+explanation.invalid. TXT "blocked by DNS rebinding protection"
+ENTRY_END
+
+; test that ::ffff:192.168.254.210 is blacklisted
+STEP 331 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+attack-ipv4over6-192-168-254-210.example.com. IN AAAA
+ENTRY_END
+
+STEP 332 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all answer authority
+REPLY QR RD RA REFUSED
+SECTION QUESTION
+attack-ipv4over6-192-168-254-210.example.com. IN AAAA
+SECTION ANSWER
+SECTION AUTHORITY
+SECTION ADDITIONAL
+explanation.invalid. TXT "blocked by DNS rebinding protection"
+ENTRY_END
+
+; test that :: is blacklisted
+STEP 341 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+attack-ipv6-.example.com. IN AAAA
+ENTRY_END
+
+STEP 342 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all answer authority
+REPLY QR RD RA REFUSED
+SECTION QUESTION
+attack-ipv6-.example.com. IN AAAA
+SECTION ANSWER
+SECTION AUTHORITY
+SECTION ADDITIONAL
+explanation.invalid. TXT "blocked by DNS rebinding protection"
+ENTRY_END
+
+; test that ::1 is blacklisted
+STEP 351 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+attack-ipv6-1.example.com. IN AAAA
+ENTRY_END
+
+STEP 352 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all answer authority
+REPLY QR RD RA REFUSED
+SECTION QUESTION
+attack-ipv6-1.example.com. IN AAAA
+SECTION ANSWER
+SECTION AUTHORITY
+SECTION ADDITIONAL
+explanation.invalid. TXT "blocked by DNS rebinding protection"
+ENTRY_END
+
+; test that fc00:: is blacklisted
+STEP 361 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+attack-ipv6-fc00.example.com. IN AAAA
+ENTRY_END
+
+STEP 362 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all answer authority
+REPLY QR RD RA REFUSED
+SECTION QUESTION
+attack-ipv6-fc00.example.com. IN AAAA
+SECTION ANSWER
+SECTION AUTHORITY
+SECTION ADDITIONAL
+explanation.invalid. TXT "blocked by DNS rebinding protection"
+ENTRY_END
+
+; test that fe80:: is blacklisted
+STEP 371 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+attack-ipv6-fe80.example.com. IN AAAA
+ENTRY_END
+
+STEP 372 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all answer authority
+REPLY QR RD RA REFUSED
+SECTION QUESTION
+attack-ipv6-fe80.example.com. IN AAAA
+SECTION ANSWER
+SECTION AUTHORITY
+SECTION ADDITIONAL
+explanation.invalid. TXT "blocked by DNS rebinding protection"
+ENTRY_END
+
+STEP 401 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+; it still works if no blacklisted IP address is present
+STEP 402 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 192.0.2.40
+ENTRY_END
+
+STEP 501 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.attacker.com. IN A
+ENTRY_END
+
+; NS for attacker.com. has IP address from private range, it must fail
+STEP 502 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all answer authority
+REPLY QR RD RA REFUSED
+SECTION QUESTION
+www.attacker.com. IN A
+SECTION ANSWER
+SECTION AUTHORITY
+SECTION ADDITIONAL
+explanation.invalid. TXT "blocked by DNS rebinding protection"
+ENTRY_END
+
+SCENARIO_END
diff --git a/modules/refuse_nord/.packaging/test.config b/modules/refuse_nord/.packaging/test.config
new file mode 100644
index 0000000..8679e26
--- /dev/null
+++ b/modules/refuse_nord/.packaging/test.config
@@ -0,0 +1,3 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+assert(modules.load('refuse_nord') == true)
+quit()
diff --git a/modules/refuse_nord/README.rst b/modules/refuse_nord/README.rst
new file mode 100644
index 0000000..c093518
--- /dev/null
+++ b/modules/refuse_nord/README.rst
@@ -0,0 +1,16 @@
+.. SPDX-License-Identifier: GPL-3.0-or-later
+
+.. _mod-refuse_nord:
+
+Refuse queries without RD bit
+=============================
+
+This module ensures all queries without RD (recursion desired) bit set in query
+are answered with REFUSED. This prevents snooping on the resolver's cache content.
+
+The module is loaded by default. If you'd like to disable this behavior, you can
+unload it:
+
+.. code-block:: lua
+
+ modules.unload('refuse_nord')
diff --git a/modules/refuse_nord/meson.build b/modules/refuse_nord/meson.build
new file mode 100644
index 0000000..1bcdbd7
--- /dev/null
+++ b/modules/refuse_nord/meson.build
@@ -0,0 +1,21 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+# C module: refuse_nord
+
+integr_tests += [
+ ['refuse_nord', meson.current_source_dir() / 'test.integr'],
+]
+
+refuse_nord_src = files([
+ 'refuse_nord.c',
+])
+c_src_lint += refuse_nord_src
+
+refuse_nord_mod = shared_module(
+ 'refuse_nord',
+ refuse_nord_src,
+ dependencies: libknot,
+ include_directories: mod_inc_dir,
+ name_prefix: '',
+ install: true,
+ install_dir: modules_dir,
+)
diff --git a/modules/refuse_nord/refuse_nord.c b/modules/refuse_nord/refuse_nord.c
new file mode 100644
index 0000000..607ff61
--- /dev/null
+++ b/modules/refuse_nord/refuse_nord.c
@@ -0,0 +1,38 @@
+/* Copyright (C) Knot Resolver contributors.
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ * This module responds to all queries without RD bit set with REFUSED. */
+
+#include <libknot/consts.h>
+#include <libknot/packet/pkt.h>
+#include "daemon/worker.h"
+#include "lib/module.h"
+#include "lib/layer.h"
+
+static int refuse_nord_query(kr_layer_t *ctx)
+{
+ struct kr_request *req = ctx->req;
+ uint8_t rd = knot_wire_get_rd(req->qsource.packet->wire);
+ if (rd)
+ return ctx->state;
+
+ knot_pkt_t *answer = kr_request_ensure_answer(req);
+ if (!answer)
+ return ctx->state;
+ knot_wire_set_rcode(answer->wire, KNOT_RCODE_REFUSED);
+ knot_wire_clear_ad(answer->wire);
+ kr_request_set_extended_error(req, KNOT_EDNS_EDE_NOTAUTH, "ABC4");
+ ctx->state = KR_STATE_DONE;
+ return ctx->state;
+}
+
+KR_EXPORT int refuse_nord_init(struct kr_module *module)
+{
+ static const kr_layer_api_t layer = {
+ .begin = &refuse_nord_query,
+ };
+ module->layer = &layer;
+ return kr_ok();
+}
+
+KR_MODULE_EXPORT(refuse_nord)
diff --git a/modules/refuse_nord/test.integr/deckard.yaml b/modules/refuse_nord/test.integr/deckard.yaml
new file mode 100644
index 0000000..60bf040
--- /dev/null
+++ b/modules/refuse_nord/test.integr/deckard.yaml
@@ -0,0 +1,12 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+programs:
+- name: kresd
+ binary: kresd
+ additional:
+ - --noninteractive
+ templates:
+ - modules/refuse_nord/test.integr/kresd_config.j2
+ - tests/integration/hints_zone.j2
+ configs:
+ - config
+ - hints
diff --git a/modules/refuse_nord/test.integr/kresd_config.j2 b/modules/refuse_nord/test.integr/kresd_config.j2
new file mode 100644
index 0000000..1abe4e4
--- /dev/null
+++ b/modules/refuse_nord/test.integr/kresd_config.j2
@@ -0,0 +1,56 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+{% raw %}
+-- make sure DNSSEC is turned off for tests
+trust_anchors.remove('.')
+
+-- Disable RFC5011 TA update
+if ta_update then
+ modules.unload('ta_update')
+end
+
+-- Disable RFC8145 signaling, scenario doesn't provide expected answers
+if ta_signal_query then
+ modules.unload('ta_signal_query')
+end
+
+-- Disable RFC8109 priming, scenario doesn't provide expected answers
+if priming then
+ modules.unload('priming')
+end
+
+-- Disable this module because it make one priming query
+if detect_time_skew then
+ modules.unload('detect_time_skew')
+end
+
+_hint_root_file('hints')
+cache.size = 2*MB
+log_level('debug')
+{% endraw %}
+
+net = { '{{SELF_ADDR}}' }
+
+
+{% if QMIN == "false" %}
+option('NO_MINIMIZE', true)
+{% else %}
+option('NO_MINIMIZE', false)
+{% endif %}
+
+
+-- Self-checks on globals
+assert(help() ~= nil)
+assert(worker.id ~= nil)
+-- Self-checks on facilities
+assert(cache.count() == 0)
+assert(cache.stats() ~= nil)
+assert(cache.backends() ~= nil)
+assert(worker.stats() ~= nil)
+assert(net.interfaces() ~= nil)
+-- Self-checks on loaded stuff
+assert(net.list()[1].transport.ip == '{{SELF_ADDR}}')
+assert(#modules.list() > 0)
+-- Self-check timers
+ev = event.recurrent(1 * sec, function (ev) return 1 end)
+event.cancel(ev)
+ev = event.after(0, function (ev) return 1 end)
diff --git a/modules/refuse_nord/test.integr/refuse_nord.rpl b/modules/refuse_nord/test.integr/refuse_nord.rpl
new file mode 100644
index 0000000..5515b3a
--- /dev/null
+++ b/modules/refuse_nord/test.integr/refuse_nord.rpl
@@ -0,0 +1,24 @@
+; SPDX-License-Identifier: GPL-3.0-or-later
+; config options
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test refuse queries without RD bit
+
+STEP 10 QUERY
+ENTRY_BEGIN
+; RD bit is cleared
+SECTION QUESTION
+www.example.com IN A
+ENTRY_END
+
+STEP 20 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all answer
+REPLY QR RA REFUSED
+SECTION QUESTION
+www.example.com IN A
+SECTION ANSWER
+ENTRY_END
+
+SCENARIO_END
diff --git a/modules/renumber/.packaging/test.config b/modules/renumber/.packaging/test.config
new file mode 100644
index 0000000..37f136a
--- /dev/null
+++ b/modules/renumber/.packaging/test.config
@@ -0,0 +1,4 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+modules.load('renumber')
+assert(renumber)
+quit()
diff --git a/modules/renumber/README.rst b/modules/renumber/README.rst
new file mode 100644
index 0000000..2e68991
--- /dev/null
+++ b/modules/renumber/README.rst
@@ -0,0 +1,36 @@
+.. SPDX-License-Identifier: GPL-3.0-or-later
+
+.. _mod-renumber:
+
+IP address renumbering
+======================
+
+The module renumbers addresses in answers to different address space.
+e.g. you can redirect malicious addresses to a blackhole, or use private address ranges
+in local zones, that will be remapped to real addresses by the resolver.
+
+
+.. warning:: While requests are still validated using DNSSEC, the signatures
+ are stripped from final answer. The reason is that the address synthesis
+ breaks signatures. You can see whether an answer was valid or not based on
+ the AD flag.
+
+Example configuration
+---------------------
+
+.. code-block:: lua
+
+ modules = {
+ renumber = {
+ -- Source subnet, destination subnet
+ {'10.10.10.0/24', '192.168.1.0'},
+ -- Remap /16 block to localhost address range
+ {'166.66.0.0/16', '127.0.0.0'},
+ -- Remap /26 subnet (64 ip addresses)
+ {'166.55.77.128/26', '127.0.0.192'},
+ -- Remap a /32 block to a single address
+ {'2001:db8::/32', '::1!'},
+ }
+ }
+
+.. TODO: renumber.name() hangs in vacuum, kind of. No occurrences in code or docs, and probably bad UX.
diff --git a/modules/renumber/renumber.lua b/modules/renumber/renumber.lua
new file mode 100644
index 0000000..60803d5
--- /dev/null
+++ b/modules/renumber/renumber.lua
@@ -0,0 +1,181 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+-- Module interface
+local ffi = require('ffi')
+local prefixes_global = {}
+
+-- get address from config: either subnet prefix or fixed endpoint
+local function extract_address(target)
+ local idx = string.find(target, "!", 1, true)
+ if idx == nil then
+ return target, false
+ end
+ if idx ~= #target then
+ error("[renumber] \"!\" symbol in target is only accepted at the end of address")
+ end
+ return string.sub(target, 1, idx - 1), true
+end
+
+-- Create bitmask from integer mask for single octet: 2 -> 11000000
+local function getOctetBitmask(intMask)
+ return bit.lshift(bit.rshift(255, 8 - intMask), 8 - intMask)
+end
+
+-- Merge ipNet with ipHost, using intMask
+local function mergeIps(ipNet, ipHost, intMask)
+ local octetMask
+ local result = ""
+
+ if #ipNet ~= #ipHost then
+ return nil
+ end
+
+ if intMask == nil then
+ return ipNet
+ end
+
+ for currentOctetNo = 1, #ipNet do
+ if intMask >= 8 then
+ result = result .. ipNet:sub(currentOctetNo,currentOctetNo)
+ elseif (intMask <= 0) then
+ result = result .. ipHost:sub(currentOctetNo,currentOctetNo)
+ else
+ octetMask = getOctetBitmask(intMask)
+ result = result .. string.char(bit.bor(
+ bit.band(string.byte(ipNet:sub(currentOctetNo,currentOctetNo)), octetMask),
+ bit.band(string.byte(ipHost:sub(currentOctetNo,currentOctetNo)), bit.bnot(octetMask))
+ ))
+ end
+ intMask = intMask - 8
+ end
+
+ return result
+end
+
+-- Create subnet prefix rule
+local function matchprefix(subnet, addr)
+ local is_exact
+ addr, is_exact = extract_address(addr)
+ local target = kres.str2ip(addr)
+ if target == nil then error('[renumber] invalid address: '..addr) end
+ local addrtype = string.find(addr, ':', 1, true) and kres.type.AAAA or kres.type.A
+ local subnet_cd = ffi.new('char[16]')
+ local bitlen = ffi.C.kr_straddr_subnet(subnet_cd, subnet)
+ if bitlen < 0 then error('[renumber] invalid subnet: '..subnet) end
+ return {subnet_cd, bitlen, target, addrtype, is_exact}
+end
+
+-- Create name match rule
+local function matchname(name, addr)
+ local is_exact
+ addr, is_exact = extract_address(addr) -- though matchname() always leads to replacing whole address
+ local target = kres.str2ip(addr)
+ if target == nil then error('[renumber] invalid address: '..addr) end
+ local owner = todname(name)
+ if not name then error('[renumber] invalid name: '..name) end
+ local addrtype = string.find(addr, ':', 1, true) and kres.type.AAAA or kres.type.A
+ return {owner, nil, target, addrtype, is_exact}
+end
+
+-- Add subnet prefix rewrite rule
+local function add_prefix(subnet, addr)
+ local prefix = matchprefix(subnet, addr)
+ table.insert(prefixes_global, prefix)
+end
+
+-- Match IP against given subnet or record owner
+local function match_subnet(subnet, bitlen, addrtype, rr)
+ local addr = rr.rdata
+ return addrtype == rr.type and
+ ((bitlen and (#addr >= bitlen / 8) and (ffi.C.kr_bitcmp(subnet, addr, bitlen) == 0)) or subnet == rr.owner)
+end
+
+-- Renumber address record
+local function renumber_record(tbl, rr)
+ for i = 1, #tbl do
+ local prefix = tbl[i]
+ local subnet = prefix[1]
+ local bitlen = prefix[2]
+ local target = prefix[3]
+ local addrtype = prefix[4]
+ local is_exact = prefix[5]
+
+ -- Match record type to address family and record address to given subnet
+ -- If provided, compare record owner to prefix name
+ if match_subnet(subnet, bitlen, addrtype, rr) then
+ if is_exact then
+ rr.rdata = target
+ else
+ local mergedHost = mergeIps(target, rr.rdata, bitlen)
+ if mergedHost ~= nil then rr.rdata = mergedHost end
+ end
+
+ return rr
+ end
+ end
+ return nil
+end
+
+-- Renumber addresses based on config
+local function rule(prefixes)
+ return function (state, req)
+ if state == kres.FAIL then return state end
+ local pkt = req.answer
+ -- Only successful answers
+ local records = pkt:section(kres.section.ANSWER)
+ local ancount = #records
+ if ancount == 0 then return state end
+ -- Find renumber candidates
+ local changed = false
+ for i = 1, ancount do
+ local rr = records[i]
+ if rr.type == kres.type.A or rr.type == kres.type.AAAA then
+ local new_rr = renumber_record(prefixes, rr)
+ if new_rr ~= nil then
+ records[i] = new_rr
+ changed = true
+ end
+ end
+ end
+ -- If not rewritten, chain action
+ if not changed then return state end
+ -- Replace section if renumbering
+ local qname = pkt:qname()
+ local qclass = pkt:qclass()
+ local qtype = pkt:qtype()
+ pkt:recycle()
+ pkt:question(qname, qclass, qtype)
+ for i = 1, ancount do
+ local rr = records[i]
+ -- Strip signatures as rewritten data cannot be validated
+ if rr.type ~= kres.type.RRSIG then
+ pkt:put(rr.owner, rr.ttl, rr.class, rr.type, rr.rdata)
+ end
+ end
+ req:set_extended_error(kres.extended_error.FORGED, "DUQR")
+ return state
+ end
+end
+
+-- Export module interface
+local M = {
+ prefix = matchprefix,
+ name = matchname,
+ rule = rule,
+ match_subnet = match_subnet,
+}
+
+-- Config
+function M.config (conf)
+ if conf == nil then return end
+ if type(conf) ~= 'table' or type(conf[1]) ~= 'table' then
+ error('[renumber] expected { {prefix, target}, ... }')
+ end
+ for i = 1, #conf do add_prefix(conf[i][1], conf[i][2]) end
+end
+
+-- Layers
+M.layer = {
+ finish = rule(prefixes_global),
+}
+
+return M
diff --git a/modules/renumber/renumber.test.lua b/modules/renumber/renumber.test.lua
new file mode 100644
index 0000000..97d6a6f
--- /dev/null
+++ b/modules/renumber/renumber.test.lua
@@ -0,0 +1,103 @@
+local function gen_rrset(owner, rrtype, rdataset)
+ assert(type(rdataset) == 'table' or type(rdataset) == 'string')
+ if type(rdataset) ~= 'table' then
+ rdataset = { rdataset }
+ end
+ local rrset = kres.rrset(todname(owner), rrtype, kres.class.IN, 3600)
+ for _, rdata in pairs(rdataset) do
+ assert(rrset:add_rdata(rdata, #rdata))
+ end
+ return rrset
+end
+
+local function prepare_cache()
+ cache.open(100*MB)
+ cache.clear()
+
+ local ffi = require('ffi')
+ local c = kres.context().cache
+
+ assert(c:insert(
+ gen_rrset('a10-0.test.',
+ kres.type.A, kres.str2ip('10.0.0.1')),
+ nil, ffi.C.KR_RANK_SECURE + ffi.C.KR_RANK_AUTH))
+ assert(c:insert(
+ gen_rrset('a10-2.test.',
+ kres.type.A, kres.str2ip('10.2.0.1')),
+ nil, ffi.C.KR_RANK_SECURE + ffi.C.KR_RANK_AUTH))
+ assert(c:insert(
+ gen_rrset('a10-0plus2.test.',
+ kres.type.A, {
+ kres.str2ip('10.0.0.1'),
+ kres.str2ip('10.2.0.1')
+ }),
+ nil, ffi.C.KR_RANK_SECURE + ffi.C.KR_RANK_AUTH))
+ assert(c:insert(
+ gen_rrset('a10-3plus4.test.',
+ kres.type.A, {
+ kres.str2ip('10.3.0.1'),
+ kres.str2ip('10.4.0.1')
+ }),
+ nil, ffi.C.KR_RANK_SECURE + ffi.C.KR_RANK_AUTH))
+ assert(c:insert(
+ gen_rrset('a166-66.test.',
+ kres.type.A, kres.str2ip('166.66.42.123')),
+ nil, ffi.C.KR_RANK_SECURE + ffi.C.KR_RANK_AUTH))
+ assert(c:insert(
+ gen_rrset('a167-81.test.',
+ kres.type.A, kres.str2ip('167.81.254.221')),
+ nil, ffi.C.KR_RANK_SECURE + ffi.C.KR_RANK_AUTH))
+ assert(c:insert(
+ gen_rrset('aaaa-db8-1.test.',
+ kres.type.AAAA, {
+ kres.str2ip('2001:db8:1::1'),
+ kres.str2ip('2001:db8:1::2'),
+ }),
+ nil, ffi.C.KR_RANK_SECURE + ffi.C.KR_RANK_AUTH))
+
+ c:commit()
+end
+
+local check_answer = require('test_utils').check_answer
+
+local function test_renumber()
+ check_answer('unknown IPv4 range passes through unaffected',
+ 'a10-0.test.', kres.type.A, kres.rcode.NOERROR, '10.0.0.1')
+ check_answer('known IPv4 range is remapped when matching first-defined rule',
+ 'a10-2.test.', kres.type.A, kres.rcode.NOERROR, '192.168.2.1')
+ check_answer('mix of known and unknown IPv4 ranges is remapped correctly',
+ 'a10-0plus2.test.', kres.type.A, kres.rcode.NOERROR, {'192.168.2.1', '10.0.0.1'})
+ check_answer('mix of known and unknown IPv4 ranges is remapped correctly to exact address',
+ 'a10-3plus4.test.', kres.type.A, kres.rcode.NOERROR, {'10.3.0.1', '192.168.3.10'})
+ check_answer('known IPv4 range is remapped when matching second-defined rule',
+ 'a166-66.test.', kres.type.A, kres.rcode.NOERROR, '127.0.42.123')
+ check_answer('known IPv4 range is remapped when matching a rule with netmask not on a byte boundary',
+ 'a167-81.test.', kres.type.A, kres.rcode.NOERROR, {'127.0.30.221'})
+
+ check_answer('two AAAA records',
+ 'aaaa-db8-1.test.', kres.type.AAAA, kres.rcode.NOERROR,
+ {'2001:db8:2::2', '2001:db8:2::1'})
+end
+
+net.ipv4 = false
+net.ipv6 = false
+
+trust_anchors.remove('.')
+policy.add(policy.all(policy.DEBUG_ALWAYS))
+policy.add(policy.suffix(policy.PASS, {todname('test.')}))
+prepare_cache()
+
+log_level('debug')
+modules.load('renumber < cache')
+renumber.config({
+ -- Source subnet, destination subnet
+ {'10.2.0.0/24', '192.168.2.0'},
+ {'10.4.0.0/24', '192.168.3.10!'},
+ {'166.66.0.0/16', '127.0.0.0'},
+ {'167.81.255.0/19', '127.0.0.0'},
+ {'2001:db8:1::/48', '2001:db8:2::'},
+})
+
+return {
+ test_renumber,
+}
diff --git a/modules/rfc7706.rst b/modules/rfc7706.rst
new file mode 100644
index 0000000..aa9b62e
--- /dev/null
+++ b/modules/rfc7706.rst
@@ -0,0 +1,12 @@
+.. SPDX-License-Identifier: GPL-3.0-or-later
+
+Root on loopback (RFC 7706)
+---------------------------
+Knot Resolver developers think that literal implementation of :rfc:`7706`
+("Decreasing Access Time to Root Servers by Running One on Loopback")
+is a bad idea so it is not implemented in the form envisioned by the RFC.
+
+You can get the very similar effect without its downsides by combining
+:ref:`mod-prefill` and :ref:`mod-serve_stale` modules with Aggressive Use
+of DNSSEC-Validated Cache (:rfc:`8198`) behavior which is enabled
+automatically together with DNSSEC validation.
diff --git a/modules/serve_stale/.packaging/test.config b/modules/serve_stale/.packaging/test.config
new file mode 100644
index 0000000..362c4ec
--- /dev/null
+++ b/modules/serve_stale/.packaging/test.config
@@ -0,0 +1,4 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+modules.load('serve_stale')
+assert(serve_stale)
+quit()
diff --git a/modules/serve_stale/README.rst b/modules/serve_stale/README.rst
new file mode 100644
index 0000000..6d2230c
--- /dev/null
+++ b/modules/serve_stale/README.rst
@@ -0,0 +1,23 @@
+.. SPDX-License-Identifier: GPL-3.0-or-later
+
+.. _mod-serve_stale:
+
+Serve stale
+===========
+
+Demo module that allows using timed-out records in case kresd is
+unable to contact upstream servers.
+
+By default it allows stale-ness by up to one day,
+after roughly four seconds trying to contact the servers.
+It's quite configurable/flexible; see the beginning of the module source for details.
+See also the RFC draft_ (not fully followed) and :any:`cache.ns_tout`.
+
+Running
+-------
+.. code-block:: lua
+
+ modules = { 'serve_stale < cache' }
+
+.. _draft: https://tools.ietf.org/html/draft-ietf-dnsop-serve-stale-00
+
diff --git a/modules/serve_stale/serve_stale.lua b/modules/serve_stale/serve_stale.lua
new file mode 100644
index 0000000..faf07fb
--- /dev/null
+++ b/modules/serve_stale/serve_stale.lua
@@ -0,0 +1,42 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+local M = {} -- the module
+
+local ffi = require('ffi')
+
+-- Beware that the timeout is only considered at certain points in time;
+-- approximately at multiples of KR_CONN_RTT_MAX.
+M.timeout = 3*sec
+
+M.callback = ffi.cast("kr_stale_cb",
+ function (ttl) --, name, type, qry)
+ --log_debug(ffi.C.SRVSTALE, ' => called back with TTL: ' .. tostring(ttl))
+ if ttl + 3600 * 24 > 0 then -- at most one day stale
+ return 1
+ else
+ return -1
+ end
+ end)
+
+M.layer = {
+ produce = function (state, req)
+ local qry = req:current()
+ -- Don't do anything for priming, prefetching, etc.
+ -- TODO: not all cases detected ATM.
+ if qry.flags.NO_CACHE then return state end
+
+ local now = ffi.C.kr_now()
+ local deadline = qry.creation_time_mono + M.timeout
+ if now > deadline or qry.flags.NO_NS_FOUND then
+ log_debug(ffi.C.LOG_GRP_SRVSTALE, ' => no reachable NS, using stale data')
+ qry.stale_cb = M.callback
+ -- TODO: probably start the same request that doesn't stale-serve,
+ -- but first we need some detection of non-interactive / internal requests.
+ -- resolve(kres.dname2str(qry.sname), qry.stype, qry.sclass)
+ end
+
+ return state
+ end,
+}
+
+return M
+
diff --git a/modules/serve_stale/test.integr/deckard.yaml b/modules/serve_stale/test.integr/deckard.yaml
new file mode 100644
index 0000000..c191345
--- /dev/null
+++ b/modules/serve_stale/test.integr/deckard.yaml
@@ -0,0 +1,12 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+programs:
+- name: kresd
+ binary: kresd
+ additional:
+ - --noninteractive
+ templates:
+ - modules/serve_stale/test.integr/kresd_config.j2
+ - tests/integration/hints_zone.j2
+ configs:
+ - config
+ - hints
diff --git a/modules/serve_stale/test.integr/kresd_config.j2 b/modules/serve_stale/test.integr/kresd_config.j2
new file mode 100644
index 0000000..8570833
--- /dev/null
+++ b/modules/serve_stale/test.integr/kresd_config.j2
@@ -0,0 +1,70 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+{% raw %}
+modules = { 'serve_stale < cache' }
+
+-- make sure DNSSEC is turned off for tests
+trust_anchors.remove('.')
+
+-- Disable RFC5011 TA update
+if ta_update then
+ modules.unload('ta_update')
+end
+
+-- Disable RFC8145 signaling, scenario doesn't provide expected answers
+if ta_signal_query then
+ modules.unload('ta_signal_query')
+end
+
+-- Disable RFC8109 priming, scenario doesn't provide expected answers
+if priming then
+ modules.unload('priming')
+end
+
+-- Disable this module because it make one priming query
+if detect_time_skew then
+ modules.unload('detect_time_skew')
+end
+
+_hint_root_file('hints')
+cache.size = 2*MB
+log_level('debug')
+{% endraw %}
+
+{% if DO_IP6 == "true" %}
+net.ipv6 = true
+{% else %}
+net.ipv6 = false
+{% endif %}
+
+{% if DO_IP4 == "true" %}
+net.ipv4 = true
+{% else %}
+net.ipv4 = false
+{% endif %}
+
+net = { '{{SELF_ADDR}}' }
+
+
+{% if QMIN == "false" %}
+option('NO_MINIMIZE', true)
+{% else %}
+option('NO_MINIMIZE', false)
+{% endif %}
+
+
+-- Self-checks on globals
+assert(help() ~= nil)
+assert(worker.id ~= nil)
+-- Self-checks on facilities
+assert(cache.count() == 0)
+assert(cache.stats() ~= nil)
+assert(cache.backends() ~= nil)
+assert(worker.stats() ~= nil)
+assert(net.interfaces() ~= nil)
+-- Self-checks on loaded stuff
+assert(net.list()[1].transport.ip == '{{SELF_ADDR}}')
+assert(#modules.list() > 0)
+-- Self-check timers
+ev = event.recurrent(1 * sec, function (ev) return 1 end)
+event.cancel(ev)
+ev = event.after(0, function (ev) return 1 end)
diff --git a/modules/serve_stale/test.integr/module_serve_stale.rpl b/modules/serve_stale/test.integr/module_serve_stale.rpl
new file mode 100644
index 0000000..3ab3a84
--- /dev/null
+++ b/modules/serve_stale/test.integr/module_serve_stale.rpl
@@ -0,0 +1,280 @@
+do-ip6: no
+; SPDX-License-Identifier: GPL-3.0-or-later
+; config options
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Modified iter_resolve.rpl to test serve_stale module.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. 30 IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. 30 IN A 192.5.6.30
+ENTRY_END
+
+; net.
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+net. IN NS
+SECTION AUTHORITY
+. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+; root-servers.net.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+root-servers.net. IN NS
+SECTION ANSWER
+root-servers.net. 30 IN NS k.root-servers.net.
+SECTION ADDITIONAL
+k.root-servers.net. 30 IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+root-servers.net. IN A
+SECTION AUTHORITY
+root-servers.net. 30 IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+k.root-servers.net. IN A
+SECTION ANSWER
+k.root-servers.net. 30 IN A 193.0.14.129
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+k.root-servers.net. IN AAAA
+SECTION AUTHORITY
+root-servers.net. 30 IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+; gtld-servers.net.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+gtld-servers.net. IN NS
+SECTION ANSWER
+gtld-servers.net. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. 30 IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+gtld-servers.net. IN A
+SECTION AUTHORITY
+gtld-servers.net. 30 IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+a.gtld-servers.net. IN A
+SECTION ANSWER
+a.gtld-servers.net. 30 IN A 192.5.6.30
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+a.gtld-servers.net. IN AAAA
+SECTION AUTHORITY
+gtld-servers.net. 30 IN SOA . . 0 0 0 0 0
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. 30 IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. 30 IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. 30 IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. 30 IN A 1.2.3.4
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. 30 IN A 10.20.30.40
+SECTION AUTHORITY
+example.com. 30 IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. 30 IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+; K.ROOT-SERVERS.NET.
+; return REFUSED to all queries
+RANGE_BEGIN 101 200
+ ADDRESS 193.0.14.129
+ ADDRESS 192.5.6.30
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR REFUSED
+SECTION QUESTION
+. IN A
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+;SECTION AUTHORITY
+;example.com. IN NS ns.example.com.
+;SECTION ADDITIONAL
+;ns.example.com. IN A 1.2.3.4
+ENTRY_END
+
+STEP 101 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+; Must be resolved from cache
+STEP 110 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+;SECTION AUTHORITY
+;example.com. IN NS ns.example.com.
+;SECTION ADDITIONAL
+;ns.example.com. IN A 1.2.3.4
+ENTRY_END
+
+; Expire cached records (TTL is 30)
+STEP 120 TIME_PASSES ELAPSE 60
+
+STEP 121 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+; Must be resolved from expired cache by serve_stale module
+STEP 130 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+;SECTION AUTHORITY
+;example.com. IN NS ns.example.com.
+;SECTION ADDITIONAL
+;ns.example.com. IN A 1.2.3.4
+ENTRY_END
+
+SCENARIO_END
diff --git a/modules/stats/.packaging/test.config b/modules/stats/.packaging/test.config
new file mode 100644
index 0000000..fd25460
--- /dev/null
+++ b/modules/stats/.packaging/test.config
@@ -0,0 +1,4 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+modules.load('stats')
+assert(stats)
+quit()
diff --git a/modules/stats/README.rst b/modules/stats/README.rst
new file mode 100644
index 0000000..7d423aa
--- /dev/null
+++ b/modules/stats/README.rst
@@ -0,0 +1,211 @@
+.. SPDX-License-Identifier: GPL-3.0-or-later
+
+.. _mod-stats:
+
+Statistics collector
+====================
+
+Module ``stats`` gathers various counters from the query resolution
+and server internals, and offers them as a key-value storage.
+These metrics can be either exported to :ref:`mod-graphite`,
+exposed as :ref:`mod-http-prometheus`, or processed using user-provided script
+as described in chapter :ref:`async-events`.
+
+.. note:: Please remember that each Knot Resolver instance keeps its own
+ statistics, and instances can be started and stopped dynamically. This might
+ affect your data postprocessing procedures if you are using
+ :ref:`systemd-multiple-instances`.
+
+.. _mod-stats-list:
+
+Built-in statistics
+-------------------
+
+Built-in counters keep track of number of queries and answers matching specific criteria.
+
++-----------------------------------------------------------------+
+| **Global request counters** |
++------------------+----------------------------------------------+
+| request.total | total number of DNS requests |
+| | (including internal client requests) |
++------------------+----------------------------------------------+
+| request.internal | internal requests generated by Knot Resolver |
+| | (e.g. DNSSEC trust anchor updates) |
++------------------+----------------------------------------------+
+| request.udp | external requests received over plain UDP |
+| | (:rfc:`1035`) |
++------------------+----------------------------------------------+
+| request.tcp | external requests received over plain TCP |
+| | (:rfc:`1035`) |
++------------------+----------------------------------------------+
+| request.dot | external requests received over |
+| | DNS-over-TLS (:rfc:`7858`) |
++------------------+----------------------------------------------+
+| request.doh | external requests received over |
+| | DNS-over-HTTP (:rfc:`8484`) |
++------------------+----------------------------------------------+
+| request.xdp | external requests received over plain UDP |
+| | via an AF_XDP socket |
++------------------+----------------------------------------------+
+
++----------------------------------------------------+
+| **Global answer counters** |
++-----------------+----------------------------------+
+| answer.total | total number of answered queries |
++-----------------+----------------------------------+
+| answer.cached | queries answered from cache |
++-----------------+----------------------------------+
+
++-----------------+----------------------------------+
+| **Answers categorized by RCODE** |
++-----------------+----------------------------------+
+| answer.noerror | NOERROR answers |
++-----------------+----------------------------------+
+| answer.nodata | NOERROR, but empty answers |
++-----------------+----------------------------------+
+| answer.nxdomain | NXDOMAIN answers |
++-----------------+----------------------------------+
+| answer.servfail | SERVFAIL answers |
++-----------------+----------------------------------+
+
++-----------------+----------------------------------+
+| **Answer latency** |
++-----------------+----------------------------------+
+| answer.1ms | completed in 1ms |
++-----------------+----------------------------------+
+| answer.10ms | completed in 10ms |
++-----------------+----------------------------------+
+| answer.50ms | completed in 50ms |
++-----------------+----------------------------------+
+| answer.100ms | completed in 100ms |
++-----------------+----------------------------------+
+| answer.250ms | completed in 250ms |
++-----------------+----------------------------------+
+| answer.500ms | completed in 500ms |
++-----------------+----------------------------------+
+| answer.1000ms | completed in 1000ms |
++-----------------+----------------------------------+
+| answer.1500ms | completed in 1500ms |
++-----------------+----------------------------------+
+| answer.slow | completed in more than 1500ms |
++-----------------+----------------------------------+
+
++-----------------+----------------------------------+
+| **Answer flags** |
++-----------------+----------------------------------+
+| answer.aa | authoritative answer |
++-----------------+----------------------------------+
+| answer.tc | truncated answer |
++-----------------+----------------------------------+
+| answer.ra | recursion available |
++-----------------+----------------------------------+
+| answer.rd | recursion desired (in answer!) |
++-----------------+----------------------------------+
+| answer.ad | authentic data (DNSSEC) |
++-----------------+----------------------------------+
+| answer.cd | checking disabled (DNSSEC) |
++-----------------+----------------------------------+
+| answer.do | DNSSEC answer OK |
++-----------------+----------------------------------+
+| answer.edns0 | EDNS0 present |
++-----------------+----------------------------------+
+
++-----------------+----------------------------------+
+| **Query flags** |
++-----------------+----------------------------------+
+| query.edns | queries with EDNS present |
++-----------------+----------------------------------+
+| query.dnssec | queries with DNSSEC DO=1 |
++-----------------+----------------------------------+
+
+Example:
+
+.. code-block:: none
+
+ modules.load('stats')
+
+ -- Enumerate metrics
+ > stats.list()
+ [answer.cached] => 486178
+ [iterator.tcp] => 490
+ [answer.noerror] => 507367
+ [answer.total] => 618631
+ [iterator.udp] => 102408
+ [query.concurrent] => 149
+
+ -- Query metrics by prefix
+ > stats.list('iter')
+ [iterator.udp] => 105104
+ [iterator.tcp] => 490
+
+ -- Fetch most common queries
+ > stats.frequent()
+ [1] => {
+ [type] => 2
+ [count] => 4
+ [name] => cz.
+ }
+
+ -- Fetch most common queries (sorted by frequency)
+ > table.sort(stats.frequent(), function (a, b) return a.count > b.count end)
+
+ -- Show recently contacted authoritative servers
+ > stats.upstreams()
+ [2a01:618:404::1] => {
+ [1] => 26 -- RTT
+ }
+ [128.241.220.33] => {
+ [1] => 31 - RTT
+ }
+
+ -- Set custom metrics from modules
+ > stats['filter.match'] = 5
+ > stats['filter.match']
+ 5
+
+Module reference
+----------------
+
+.. function:: stats.get(key)
+
+ :param string key: i.e. ``"answer.total"``
+ :return: ``number``
+
+Return nominal value of given metric.
+
+.. function:: stats.set('key val')
+
+Set nominal value of given metric.
+
+Example:
+
+.. code-block:: lua
+
+ stats.set('answer.total 5')
+ -- or syntactic sugar
+ stats['answer.total'] = 5
+
+
+.. function:: stats.list([prefix])
+
+ :param string prefix: optional metric prefix, i.e. ``"answer"`` shows only metrics beginning with "answer"
+
+Outputs collected metrics as a JSON dictionary.
+
+.. function:: stats.upstreams()
+
+Outputs a list of recent upstreams and their RTT. It is sorted by time and stored in a ring buffer of
+a fixed size. This means it's not aggregated and readable by multiple consumers, but also that
+you may lose entries if you don't read quickly enough. The default ring size is 512 entries, and may be overridden on compile time by ``-DUPSTREAMS_COUNT=X``.
+
+.. function:: stats.frequent()
+
+Outputs list of most frequent iterative queries as a JSON array. The queries are sampled probabilistically,
+and include subrequests. The list maximum size is 5000 entries, make diffs if you want to track it over time.
+
+.. function:: stats.clear_frequent()
+
+Clear the list of most frequent iterative queries.
+
+.. include:: ../modules/graphite/README.rst
+.. include:: ../modules/http/prometheus.rst
diff --git a/modules/stats/meson.build b/modules/stats/meson.build
new file mode 100644
index 0000000..4f2d41e
--- /dev/null
+++ b/modules/stats/meson.build
@@ -0,0 +1,25 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+# C module: stats
+
+stats_src = files([
+ 'stats.c',
+])
+c_src_lint += stats_src
+
+integr_tests += [
+ ['stats', meson.current_source_dir() / 'test.integr'],
+]
+
+
+stats_mod = shared_module(
+ 'stats',
+ stats_src,
+ dependencies: [
+ libknot,
+ luajit_inc,
+ ],
+ include_directories: mod_inc_dir,
+ name_prefix: '',
+ install: true,
+ install_dir: modules_dir,
+)
diff --git a/modules/stats/stats.c b/modules/stats/stats.c
new file mode 100644
index 0000000..ebb2877
--- /dev/null
+++ b/modules/stats/stats.c
@@ -0,0 +1,534 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+/**
+ * @file stats.c
+ * @brief Storage for various counters and metrics from query resolution.
+ *
+ * You can either reuse this module to compute statistics or store custom metrics
+ * in it via the extensions.
+ */
+
+#include <libknot/packet/pkt.h>
+#include <libknot/packet/wire.h>
+#include <libknot/descriptor.h>
+#include <ccan/json/json.h>
+#include <contrib/cleanup.h>
+#include <arpa/inet.h>
+#include <lua.h>
+
+#include "lib/generic/trie.h"
+#include "lib/layer/iterate.h"
+#include "lib/rplan.h"
+#include "lib/module.h"
+#include "lib/layer.h"
+#include "lib/resolve.h"
+
+/* Defaults */
+#define VERBOSE_MSG(qry, ...) kr_log_q(qry, STATISTICS, __VA_ARGS__)
+#define FREQUENT_PSAMPLE 10 /* Sampling rate, 1 in N */
+#ifdef LRU_REP_SIZE
+ #define FREQUENT_COUNT LRU_REP_SIZE /* Size of frequent tables */
+#else
+ #define FREQUENT_COUNT 5000 /* Size of frequent tables */
+#endif
+#ifndef UPSTREAMS_COUNT
+ #define UPSTREAMS_COUNT 512 /* Size of recent upstreams */
+#endif
+
+/** @cond internal Fixed-size map of predefined metrics. */
+#define CONST_METRICS(X) \
+ X(answer,total) X(answer,noerror) X(answer,nodata) X(answer,nxdomain) X(answer,servfail) \
+ X(answer,cached) X(answer,1ms) X(answer,10ms) X(answer,50ms) X(answer,100ms) \
+ X(answer,250ms) X(answer,500ms) X(answer,1000ms) X(answer,1500ms) X(answer,slow) \
+ X(answer,aa) X(answer,tc) X(answer,rd) X(answer,ra) X(answer, ad) X(answer,cd) \
+ X(answer,edns0) X(answer,do) \
+ X(query,edns) X(query,dnssec) \
+ X(request,total) X(request,udp) X(request,tcp) X(request,xdp) \
+ X(request,dot) X(request,doh) X(request,internal) \
+ X(const,end)
+
+enum const_metric {
+ #define X(a,b) metric_ ## a ## _ ## b,
+ CONST_METRICS(X)
+ #undef X
+};
+struct const_metric_elm {
+ const char *key;
+ size_t val;
+};
+static struct const_metric_elm const_metrics[] = {
+ #define X(a,b) [metric_ ## a ## _ ## b] = { #a "." #b, 0 },
+ CONST_METRICS(X)
+ #undef X
+};
+/** @endcond */
+
+/** @internal LRU hash of most frequent names. */
+typedef lru_t(unsigned) namehash_t;
+typedef array_t(struct sockaddr_in6) addrlist_t;
+
+/** @internal Stats data structure. */
+struct stat_data {
+ trie_t *trie;
+ struct {
+ namehash_t *frequent;
+ } queries;
+ struct {
+ addrlist_t q;
+ size_t head;
+ } upstreams;
+};
+
+/** @internal We don't store/publish port, repurpose it for RTT instead. */
+#define sin6_rtt sin6_port
+
+/** @internal Add to const map counter */
+static inline void stat_const_add(struct stat_data *data, enum const_metric key, ssize_t incr)
+{
+ const_metrics[key].val += incr;
+}
+
+static int collect_answer(struct stat_data *data, knot_pkt_t *pkt)
+{
+ stat_const_add(data, metric_answer_total, 1);
+ /* Count per-rcode */
+ switch(knot_wire_get_rcode(pkt->wire)) {
+ case KNOT_RCODE_NOERROR:
+ if (knot_wire_get_ancount(pkt->wire) > 0)
+ stat_const_add(data, metric_answer_noerror, 1);
+ else
+ stat_const_add(data, metric_answer_nodata, 1);
+ break;
+ case KNOT_RCODE_NXDOMAIN: stat_const_add(data, metric_answer_nxdomain, 1); break;
+ case KNOT_RCODE_SERVFAIL: stat_const_add(data, metric_answer_servfail, 1); break;
+ default: break;
+ }
+
+ return kr_ok();
+}
+
+static inline int collect_key(char *key, const knot_dname_t *name, uint16_t type)
+{
+ memcpy(key, &type, sizeof(type));
+ int key_len = knot_dname_to_wire((uint8_t *)key + sizeof(type), name, KNOT_DNAME_MAXLEN);
+ if (key_len < 0) {
+ return kr_error(key_len);
+ }
+ return key_len + sizeof(type);
+}
+
+static void collect_sample(struct stat_data *data, struct kr_rplan *rplan)
+{
+ /* Sample key = {[2] type, [1-255] owner} */
+ char key[sizeof(uint16_t) + KNOT_DNAME_MAXLEN];
+ for (size_t i = 0; i < rplan->resolved.len; ++i) {
+ /* Sample queries leading to iteration */
+ struct kr_query *qry = rplan->resolved.at[i];
+ if (qry->flags.CACHED) {
+ continue;
+ }
+ /* Consider 1 in N for frequent sampling.
+ * TODO: redesign the sampling approach. */
+ if (kr_rand_coin(1, FREQUENT_PSAMPLE)) {
+ int key_len = collect_key(key, qry->sname, qry->stype);
+ if (kr_fails_assert(key_len >= 0))
+ continue;
+ unsigned *count = lru_get_new(data->queries.frequent, key, key_len, NULL);
+ if (count)
+ *count += 1;
+ }
+ }
+}
+
+static int collect_rtt(kr_layer_t *ctx, knot_pkt_t *pkt)
+{
+ struct kr_request *req = ctx->req;
+ struct kr_query *qry = req->current_query;
+ if (qry->flags.CACHED || !req->upstream.transport) {
+ return ctx->state;
+ }
+
+ /* Push address and RTT to the ring buffer head */
+ struct kr_module *module = ctx->api->data;
+ struct stat_data *data = module->data;
+
+ /* Socket address is encoded into sockaddr_in6 struct that
+ * unions with sockaddr_in and differ in sa_family */
+ struct sockaddr_in6 *e = &data->upstreams.q.at[data->upstreams.head];
+ const union kr_sockaddr *src = &req->upstream.transport->address;
+ switch (src->ip.sa_family) {
+ case AF_INET: memcpy(e, &src->ip4, sizeof(src->ip4)); break;
+ case AF_INET6: memcpy(e, &src->ip6, sizeof(src->ip6)); break;
+ default: return ctx->state;
+ }
+ /* Replace port number with the RTT information (cap is UINT16_MAX milliseconds) */
+ e->sin6_rtt = req->upstream.rtt;
+
+ /* Advance ring buffer head */
+ data->upstreams.head = (data->upstreams.head + 1) % UPSTREAMS_COUNT;
+ return ctx->state;
+}
+
+static int collect_transport(kr_layer_t *ctx)
+{
+ struct kr_request *req = ctx->req;
+ struct kr_module *module = ctx->api->data;
+ struct stat_data *data = module->data;
+
+ stat_const_add(data, metric_request_total, 1);
+ if (req->qsource.dst_addr == NULL) {
+ stat_const_add(data, metric_request_internal, 1);
+ return ctx->state;
+ }
+
+ /**
+ * Count each transport only once,
+ * i.e. DoT does not count as TCP and XDP does not count as UDP.
+ */
+ if (req->qsource.flags.http)
+ stat_const_add(data, metric_request_doh, 1);
+ else if (req->qsource.flags.tls)
+ stat_const_add(data, metric_request_dot, 1);
+ else if (req->qsource.flags.tcp)
+ stat_const_add(data, metric_request_tcp, 1);
+ else if (req->qsource.flags.xdp)
+ stat_const_add(data, metric_request_xdp, 1);
+ else
+ stat_const_add(data, metric_request_udp, 1);
+ return ctx->state;
+}
+
+static int collect(kr_layer_t *ctx)
+{
+ struct kr_request *param = ctx->req;
+ struct kr_module *module = ctx->api->data;
+ struct kr_rplan *rplan = &param->rplan;
+ struct stat_data *data = module->data;
+
+ collect_sample(data, rplan);
+ if (!param->answer) {
+ /* The answer is being dropped. TODO: perhaps add some stat for this? */
+ return ctx->state;
+ }
+
+ /* Collect data on final answer */
+ collect_answer(data, param->answer);
+ /* Count cached and unresolved */
+ if (rplan->resolved.len > 0) {
+ /* Histogram of answer latency. */
+ struct kr_query *first = rplan->resolved.at[0];
+ uint64_t elapsed = kr_now() - first->timestamp_mono;
+ if (elapsed <= 1) {
+ stat_const_add(data, metric_answer_1ms, 1);
+ } else if (elapsed <= 10) {
+ stat_const_add(data, metric_answer_10ms, 1);
+ } else if (elapsed <= 50) {
+ stat_const_add(data, metric_answer_50ms, 1);
+ } else if (elapsed <= 100) {
+ stat_const_add(data, metric_answer_100ms, 1);
+ } else if (elapsed <= 250) {
+ stat_const_add(data, metric_answer_250ms, 1);
+ } else if (elapsed <= 500) {
+ stat_const_add(data, metric_answer_500ms, 1);
+ } else if (elapsed <= 1000) {
+ stat_const_add(data, metric_answer_1000ms, 1);
+ } else if (elapsed <= 1500) {
+ stat_const_add(data, metric_answer_1500ms, 1);
+ } else {
+ stat_const_add(data, metric_answer_slow, 1);
+ }
+ /* Observe the final query. */
+ struct kr_query *last = kr_rplan_last(rplan);
+ stat_const_add(data, metric_answer_cached, last->flags.CACHED);
+ }
+
+ /* Keep stats of all response header flags;
+ * these don't return bool, so that's why we use !! */
+ stat_const_add(data, metric_answer_aa, !!knot_wire_get_aa(param->answer->wire));
+ stat_const_add(data, metric_answer_tc, !!knot_wire_get_tc(param->answer->wire));
+ stat_const_add(data, metric_answer_rd, !!knot_wire_get_rd(param->answer->wire));
+ stat_const_add(data, metric_answer_ra, !!knot_wire_get_ra(param->answer->wire));
+ stat_const_add(data, metric_answer_ad, !!knot_wire_get_ad(param->answer->wire));
+ stat_const_add(data, metric_answer_cd, !!knot_wire_get_cd(param->answer->wire));
+
+ /* EDNS0 stats */
+ stat_const_add(data, metric_answer_edns0, knot_pkt_has_edns(param->answer));
+ stat_const_add(data, metric_answer_do, knot_pkt_has_dnssec(param->answer));
+
+ /* Query parameters and transport mode */
+ /*
+ DEPRECATED
+ use new names metric_answer_edns0 and metric_answer_do
+ */
+ stat_const_add(data, metric_query_edns, knot_pkt_has_edns(param->answer));
+ stat_const_add(data, metric_query_dnssec, knot_pkt_has_dnssec(param->answer));
+
+ return ctx->state;
+}
+
+/**
+ * Set nominal value of a key.
+ *
+ * Input: { key, val }
+ *
+ */
+static char* stats_set(void *env, struct kr_module *module, const char *args)
+{
+ if (args == NULL)
+ return NULL;
+
+ struct stat_data *data = module->data;
+
+ auto_free char *pair = strdup(args);
+ char *val = strchr(pair, ' ');
+ if (val) {
+ *val = '\0';
+ size_t number = strtoul(val + 1, NULL, 10);
+ for (unsigned i = 0; i < metric_const_end; ++i) {
+ if (strcmp(const_metrics[i].key, pair) == 0) {
+ const_metrics[i].val = number;
+ return NULL;
+ }
+ }
+ trie_val_t *trie_val = trie_get_ins(data->trie, pair, strlen(pair));
+ *trie_val = (void *)number;
+ }
+
+ return NULL;
+}
+
+/**
+ * Retrieve metrics by key.
+ *
+ * Input: string key
+ * Output: number value
+ */
+static char* stats_get(void *env, struct kr_module *module, const char *args)
+{
+ if (args == NULL)
+ return NULL;
+
+ struct stat_data *data = module->data;
+
+ /* Expecting CHAR_BIT to be 8, this is a safe bet */
+ char *ret = malloc(3 * sizeof(size_t) + 2);
+ if (!ret) {
+ return NULL;
+ }
+
+ /* Check if it exists in const map. */
+ for (unsigned i = 0; i < metric_const_end; ++i) {
+ if (strcmp(const_metrics[i].key, args) == 0) {
+ sprintf(ret, "%zu", const_metrics[i].val);
+ return ret;
+ }
+ }
+ /* Check in variable map */
+ trie_val_t *val = trie_get_try(data->trie, args, strlen(args));
+ if (!val) {
+ free(ret);
+ return NULL;
+ }
+ sprintf(ret, "%zu", (size_t) *val);
+ return ret;
+}
+
+/** Checks whether:
+ * - `key` starts with `prefix`; OR
+ * - The prefix is a wildcard, which is indicated by `prefix_len` being zero. */
+static inline bool key_matches_prefix(const char *key, size_t key_len,
+ const char *prefix, size_t prefix_len)
+{
+ return prefix_len == 0 || (prefix_len <= key_len && memcmp(key, prefix, prefix_len) == 0);
+}
+
+struct list_entry_context {
+ JsonNode *root; /**< JSON object into which matching entries will be inserted. */
+ const char *key_prefix; /**< The prefix against which entries will be matched. */
+ size_t key_prefix_len; /**< Prefix length. Prefix is a wildcard if zero. */
+};
+
+/** Inserts the entry with a matching key into the JSON object. */
+static int list_entry(const char *key, uint32_t key_len, trie_val_t *val, void *baton)
+{
+ struct list_entry_context *ctx = baton;
+ if (!key_matches_prefix(key, key_len, ctx->key_prefix, ctx->key_prefix_len))
+ return 0;
+ size_t number = (size_t) *val;
+ auto_free char *key_nt = strndup(key, key_len);
+ json_append_member(ctx->root, key_nt, json_mknumber(number));
+ return 0;
+}
+
+/**
+ * List observed metrics.
+ *
+ * Output: { key: val, ... }
+ */
+static char* stats_list(void *env, struct kr_module *module, const char *args)
+{
+ JsonNode *root = json_mkobject();
+ /* Walk const metrics map */
+ size_t args_len = args ? strlen(args) : 0;
+ for (unsigned i = 0; i < metric_const_end; ++i) {
+ struct const_metric_elm *elm = &const_metrics[i];
+ if (!args || strncmp(elm->key, args, args_len) == 0) {
+ json_append_member(root, elm->key, json_mknumber(elm->val));
+ }
+ }
+ struct list_entry_context ctx = {
+ .root = root,
+ .key_prefix = args,
+ .key_prefix_len = args_len
+ };
+ struct stat_data *data = module->data;
+ trie_apply_with_key(data->trie, list_entry, &ctx);
+ char *ret = json_encode(root);
+ json_delete(root);
+ return ret;
+}
+
+/** @internal Helper for dump_list: add a single namehash_t item to JSON. */
+static enum lru_apply_do dump_value(const char *key, uint len, unsigned *val, void *baton)
+{
+ uint16_t key_type = 0;
+ /* Extract query name, type and counter */
+ memcpy(&key_type, key, sizeof(key_type));
+ KR_DNAME_GET_STR(key_name, (uint8_t *)key + sizeof(key_type));
+ KR_RRTYPE_GET_STR(type_str, key_type);
+
+ /* Convert to JSON object */
+ JsonNode *json_val = json_mkobject();
+ json_append_member(json_val, "count", json_mknumber(*val));
+ json_append_member(json_val, "name", json_mkstring(key_name));
+ json_append_member(json_val, "type", json_mkstring(type_str));
+ json_append_element((JsonNode *)baton, json_val);
+ return LRU_APPLY_DO_NOTHING; // keep the item
+}
+/**
+ * List frequent names.
+ *
+ * Output: [{ count: <counter>, name: <qname>, type: <qtype>}, ... ]
+ */
+static char* dump_list(void *env, struct kr_module *module, const char *args, namehash_t *table)
+{
+ if (!table) {
+ return NULL;
+ }
+ JsonNode *root = json_mkarray();
+ lru_apply(table, dump_value, root);
+ char *ret = json_encode(root);
+ json_delete(root);
+ return ret;
+}
+
+static char* dump_frequent(void *env, struct kr_module *module, const char *args)
+{
+ struct stat_data *data = module->data;
+ return dump_list(env, module, args, data->queries.frequent);
+}
+
+static char* clear_frequent(void *env, struct kr_module *module, const char *args)
+{
+ struct stat_data *data = module->data;
+ lru_reset(data->queries.frequent);
+ return NULL;
+}
+
+static char* dump_upstreams(void *env, struct kr_module *module, const char *args)
+{
+ struct stat_data *data = module->data;
+ if (!data) {
+ return NULL;
+ }
+
+ /* Walk the ring backwards until AF_UNSPEC or we hit head. */
+ JsonNode *root = json_mkobject();
+ size_t head = data->upstreams.head;
+ for (size_t i = 1; i < UPSTREAMS_COUNT; ++i) {
+ size_t h = (UPSTREAMS_COUNT + head - i) % UPSTREAMS_COUNT;
+ struct sockaddr_in6 *e = &data->upstreams.q.at[h];
+ if (e->sin6_family == AF_UNSPEC) {
+ break;
+ }
+ /* Convert address to string */
+ char addr_str[INET6_ADDRSTRLEN];
+ const char *ret = inet_ntop(e->sin6_family, kr_inaddr((const struct sockaddr *)e), addr_str, sizeof(addr_str));
+ if (!ret) {
+ break;
+ }
+ /* Append to map with an array encoding RTTs */
+ JsonNode *json_val = json_find_member(root, addr_str);
+ if (!json_val) {
+ json_val = json_mkarray();
+ json_append_member(root, addr_str, json_val);
+ }
+ json_append_element(json_val, json_mknumber(e->sin6_rtt));
+ }
+
+ /* Encode and return */
+ char *ret = json_encode(root);
+ json_delete(root);
+ return ret;
+}
+
+KR_EXPORT
+int stats_init(struct kr_module *module)
+{
+ static kr_layer_api_t layer = {
+ .consume = &collect_rtt,
+ .finish = &collect,
+ .begin = &collect_transport,
+ };
+ /* Store module reference */
+ layer.data = module;
+ module->layer = &layer;
+
+ static const struct kr_prop props[] = {
+ { &stats_set, "set", "Set {key, val} metrics.", },
+ { &stats_get, "get", "Get metrics for given key.", },
+ { &stats_list, "list", "List observed metrics.", },
+ { &dump_frequent, "frequent", "List most frequent queries.", },
+ { &clear_frequent,"clear_frequent", "Clear frequent queries log.", },
+ { &dump_upstreams, "upstreams", "List recently seen authoritatives.", },
+ { NULL, NULL, NULL }
+ };
+ module->props = props;
+
+ struct stat_data *data = calloc(1, sizeof(*data));
+ if (!data) {
+ return kr_error(ENOMEM);
+ }
+ data->trie = trie_create(NULL);
+ module->data = data;
+ lru_create(&data->queries.frequent, FREQUENT_COUNT, NULL, NULL);
+ /* Initialize ring buffer of recently visited upstreams */
+ array_init(data->upstreams.q);
+ if (array_reserve(data->upstreams.q, UPSTREAMS_COUNT) != 0) {
+ return kr_error(ENOMEM);
+ }
+ data->upstreams.q.len = UPSTREAMS_COUNT; /* signify we use the entries */
+ for (size_t i = 0; i < UPSTREAMS_COUNT; ++i) {
+ data->upstreams.q.at[i].sin6_family = AF_UNSPEC;
+ }
+ return kr_ok();
+}
+
+KR_EXPORT
+int stats_deinit(struct kr_module *module)
+{
+ struct stat_data *data = module->data;
+ if (data) {
+ trie_free(data->trie);
+ lru_free(data->queries.frequent);
+ array_clear(data->upstreams.q);
+ free(data);
+ }
+ return kr_ok();
+}
+
+KR_MODULE_EXPORT(stats)
+
+#undef VERBOSE_MSG
diff --git a/modules/stats/test.integr/deckard.yaml b/modules/stats/test.integr/deckard.yaml
new file mode 100644
index 0000000..6dd0c22
--- /dev/null
+++ b/modules/stats/test.integr/deckard.yaml
@@ -0,0 +1,12 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+programs:
+- name: kresd
+ binary: kresd
+ additional:
+ - --noninteractive
+ templates:
+ - modules/stats/test.integr/kresd_config.j2
+ - tests/integration/hints_zone.j2
+ configs:
+ - config
+ - hints
diff --git a/modules/stats/test.integr/kresd_config.j2 b/modules/stats/test.integr/kresd_config.j2
new file mode 100644
index 0000000..4db7caa
--- /dev/null
+++ b/modules/stats/test.integr/kresd_config.j2
@@ -0,0 +1,114 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+local ffi = require('ffi')
+
+{% raw %}
+modules.load('stats')
+
+FWD_TARGET = policy.FORWARD('192.0.2.1')
+
+function check_stats(got)
+ log_info(ffi.C.LOG_GRP_TESTS, 'checking if stat values match expected values:')
+ local expected = {
+ ['answer.cd'] = 2,
+ ['answer.cached'] = 1,
+ ['answer.nodata'] = 1,
+ ['answer.noerror'] = 2,
+ ['answer.nxdomain'] = 1,
+ ['answer.servfail'] = 2,
+ ['answer.edns0'] = 6,
+ ['answer.ra'] = 6,
+ ['answer.rd'] = 5,
+ ['answer.do'] = 1,
+ ['answer.ad'] = 0,
+ ['answer.tc'] = 0,
+ ['answer.aa'] = 0,
+ ['answer.total'] = 6
+ }
+ print(table_print(expected))
+
+ local ok = true
+ for key, expval in pairs(expected) do
+ if got[key] ~= expval then
+ log_info(ffi.C.LOG_GRP_TESTS,
+ 'ERROR: stats key ' .. key
+ .. ' has unexpected value'
+ .. ' (expected ' .. tostring(expval)
+ .. ' got ' .. tostring(got[key] .. ')'))
+ ok = false
+ end
+ end
+ if ok then
+ log_info(ffi.C.LOG_GRP_TESTS, 'no problem found')
+ return FWD_TARGET
+ else
+ return policy.DENY_MSG('Stats test failure')
+ end
+end
+
+function reply_result(state, req)
+ local got = stats.list()
+ log_info(ffi.C.LOG_GRP_TESTS, 'current stats.list() values:')
+ print(table_print(got))
+ local result = check_stats(got)
+ return result(state, req)
+end
+policy.add(policy.pattern(reply_result, 'stats.test.'))
+policy.add(policy.all(FWD_TARGET)) -- avoid iteration
+
+-- make sure DNSSEC is turned off for tests
+trust_anchors.remove('.')
+
+-- Enable queries without RD bit
+pcall(modules.unload, 'refuse_nord')
+
+-- Disable RFC5011 TA update
+if ta_update then
+ modules.unload('ta_update')
+end
+
+-- Disable RFC8145 signaling, scenario doesn't provide expected answers
+if ta_signal_query then
+ modules.unload('ta_signal_query')
+end
+
+-- Disable RFC8109 priming, scenario doesn't provide expected answers
+if priming then
+ modules.unload('priming')
+end
+
+-- Disable this module because it make one priming query
+if detect_time_skew then
+ modules.unload('detect_time_skew')
+end
+
+_hint_root_file('hints')
+cache.size = 2*MB
+log_level('debug')
+{% endraw %}
+
+net = { '{{SELF_ADDR}}' }
+
+
+{% if QMIN == "false" %}
+option('NO_MINIMIZE', true)
+{% else %}
+option('NO_MINIMIZE', false)
+{% endif %}
+
+
+-- Self-checks on globals
+assert(help() ~= nil)
+assert(worker.id ~= nil)
+-- Self-checks on facilities
+assert(cache.count() == 0)
+assert(cache.stats() ~= nil)
+assert(cache.backends() ~= nil)
+assert(worker.stats() ~= nil)
+assert(net.interfaces() ~= nil)
+-- Self-checks on loaded stuff
+assert(net.list()[1].transport.ip == '{{SELF_ADDR}}')
+assert(#modules.list() > 0)
+-- Self-check timers
+ev = event.recurrent(1 * sec, function (ev) return 1 end)
+event.cancel(ev)
+ev = event.after(0, function (ev) return 1 end)
diff --git a/modules/stats/test.integr/stats.rpl b/modules/stats/test.integr/stats.rpl
new file mode 100644
index 0000000..ecab062
--- /dev/null
+++ b/modules/stats/test.integr/stats.rpl
@@ -0,0 +1,194 @@
+; SPDX-License-Identifier: GPL-3.0-or-later
+ trust-anchor: "example. DNSKEY 257 3 7 AwEAAcUlFV1vhmqx6NSOUOq2R/dsR7Xm3upJ ( j7IommWSpJABVfW8Q0rOvXdM6kzt+TAu92L9 AbsUdblMFin8CVF3n4s= )"
+CONFIG_END
+
+SCENARIO_BEGIN Test stats module
+
+RANGE_BEGIN 0 100
+ ADDRESS 192.0.2.1
+
+ENTRY_BEGIN
+REPLY QR RA RD CD NOERROR
+MATCH opcode question rcode
+ADJUST copy_id
+SECTION QUESTION
+cd.test. IN TXT
+SECTION ANSWER
+cd.test. IN TXT "CD is set"
+ENTRY_END
+
+ENTRY_BEGIN
+REPLY QR RA RD CD NOERROR
+MATCH opcode question rcode
+ADJUST copy_id
+SECTION QUESTION
+nodata.test. IN TXT
+ENTRY_END
+
+ENTRY_BEGIN
+REPLY QR RA RD CD NXDOMAIN
+MATCH opcode question
+ADJUST copy_id
+SECTION QUESTION
+nxdomain.test. IN TXT
+ENTRY_END
+
+; failing DNSSEC-signed subdomain
+ENTRY_BEGIN
+REPLY QR RA RD CD SERVFAIL
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+SECTION QUESTION
+bogus.test. IN TXT
+ENTRY_END
+
+; query for this name triggers check in Lua config
+ENTRY_BEGIN
+REPLY QR RA RD CD NOERROR
+MATCH opcode question rcode
+ADJUST copy_id
+SECTION QUESTION
+stats.test. IN TXT
+SECTION ANSWER
+stats.test. IN TXT "Ok, trigger query was not intercepted!"
+ENTRY_END
+
+ENTRY_BEGIN
+REPLY QR RD RA CD TC NOERROR
+MATCH opcode question rcode
+ADJUST copy_id
+SECTION QUESTION
+tc.test. IN URI
+ENTRY_END
+
+RANGE_END
+
+
+; +cd +rd
+STEP 10 QUERY
+ENTRY_BEGIN
+REPLY RD CD NOERROR
+SECTION QUESTION
+cd.test. IN TXT
+ENTRY_END
+
+STEP 11 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA CD NOERROR
+SECTION QUESTION
+cd.test. IN TXT
+SECTION ANSWER
+cd.test. IN TXT "CD is set"
+ENTRY_END
+
+; +cd +cached +rd
+STEP 12 QUERY
+ENTRY_BEGIN
+REPLY RD CD NOERROR
+SECTION QUESTION
+cd.test. IN TXT
+ENTRY_END
+
+STEP 13 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA CD NOERROR
+SECTION QUESTION
+cd.test. IN TXT
+SECTION ANSWER
+cd.test. IN TXT "CD is set"
+ENTRY_END
+
+; +nodata +rd
+STEP 20 QUERY
+ENTRY_BEGIN
+REPLY RD NOERROR
+SECTION QUESTION
+nodata.test. IN TXT
+SECTION ADDITIONAL
+ENTRY_END
+
+STEP 21 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA NOERROR
+MATCH all
+SECTION QUESTION
+nodata.test. IN TXT
+ENTRY_END
+
+; +nxdomain +rd
+STEP 30 QUERY
+ENTRY_BEGIN
+REPLY RD NOERROR
+SECTION QUESTION
+nxdomain.test. IN TXT
+SECTION ADDITIONAL
+ENTRY_END
+
+STEP 31 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA NXDOMAIN
+MATCH all
+SECTION QUESTION
+nxdomain.test. IN TXT
+ENTRY_END
+
+; +servfail +do +rd
+STEP 40 QUERY
+ENTRY_BEGIN
+REPLY RD DO NOERROR
+SECTION QUESTION
+bogus.test. IN TXT
+SECTION ADDITIONAL
+ENTRY_END
+
+STEP 41 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA DO SERVFAIL
+MATCH all
+SECTION QUESTION
+bogus.test. IN TXT
+ENTRY_END
+
+; no rd
+STEP 50 QUERY
+ENTRY_BEGIN
+REPLY NOERROR
+SECTION QUESTION
+bogus.test. IN TXT
+SECTION ADDITIONAL
+ENTRY_END
+
+STEP 51 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RA SERVFAIL
+MATCH all
+SECTION QUESTION
+bogus.test. IN TXT
+ENTRY_END
+
+
+
+
+STEP 100 QUERY
+ENTRY_BEGIN
+REPLY RD NOERROR
+SECTION QUESTION
+stats.test. IN TXT
+SECTION ADDITIONAL
+ENTRY_END
+
+STEP 101 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY NOERROR
+MATCH opcode question additional rcode answer
+; AD must not be set in the answer
+SECTION QUESTION
+stats.test. IN TXT
+SECTION ANSWER
+stats.test. IN TXT "Ok, trigger query was not intercepted!"
+ENTRY_END
+
+
+SCENARIO_END
diff --git a/modules/ta_sentinel/.packaging/test.config b/modules/ta_sentinel/.packaging/test.config
new file mode 100644
index 0000000..4bb6ac9
--- /dev/null
+++ b/modules/ta_sentinel/.packaging/test.config
@@ -0,0 +1,4 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+modules.load('ta_sentinel')
+assert(ta_sentinel)
+quit()
diff --git a/modules/ta_sentinel/README.rst b/modules/ta_sentinel/README.rst
new file mode 100644
index 0000000..aa9d733
--- /dev/null
+++ b/modules/ta_sentinel/README.rst
@@ -0,0 +1,18 @@
+.. SPDX-License-Identifier: GPL-3.0-or-later
+
+.. _mod-ta_sentinel:
+
+Sentinel for Detecting Trusted Root Keys
+========================================
+
+The module ``ta_sentinel`` implements A Root Key Trust Anchor Sentinel for DNSSEC
+according to standard :rfc:`8509`.
+
+This feature allows users of DNSSEC validating resolver to detect which root keys
+are configured in resolver's chain of trust. The data from such
+signaling are necessary to monitor the progress of the DNSSEC root key rollover
+and to detect potential breakage before it affect users. One example of research enabled by this module `is available here <https://www.potaroo.net/ispcol/2018-11/kskpm.html>`_.
+
+This module is enabled by default and we urge users not to disable it.
+If it is absolutely necessary you may add ``modules.unload('ta_sentinel')``
+to your configuration to disable it.
diff --git a/modules/ta_sentinel/ta_sentinel.lua b/modules/ta_sentinel/ta_sentinel.lua
new file mode 100644
index 0000000..5a2654b
--- /dev/null
+++ b/modules/ta_sentinel/ta_sentinel.lua
@@ -0,0 +1,80 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+local M = {}
+M.layer = {}
+local ffi = require('ffi')
+
+function M.layer.finish(state, req, pkt)
+ if pkt == nil then return end
+ -- fast filter by the length of the first QNAME label
+ if pkt.wire[5] == 0 then return state end -- QDCOUNT % 256 == 0, in case we produced that
+ local label_len = pkt.wire[12]
+ if label_len ~= 29 and label_len ~= 30 then
+ return state end
+ -- end of hot path
+
+ local qtype = pkt:qtype()
+ if not (qtype == kres.type.A or qtype == kres.type.AAAA) then
+ return state end
+ if bit.band(state, kres.FAIL) ~= 0 then
+ return state end
+
+ -- check the label name
+ local qry = req:resolved()
+ local qname = kres.dname2str(qry:name()):lower()
+ local sentype, keytag
+ if label_len == 29 then
+ sentype = true
+ keytag = qname:match('^root%-key%-sentinel%-is%-ta%-(%x+)%.')
+ elseif label_len == 30 then
+ sentype = false
+ keytag = qname:match('^root%-key%-sentinel%-not%-ta%-(%x+)%.')
+ end
+ if not keytag then return state end
+
+ if req.rank ~= ffi.C.KR_RANK_SECURE or req.answer:cd() then
+ log_info(ffi.C.LOG_GRP_TASENTINEL, 'name+type OK but not AD+CD conditions')
+ return state
+ end
+
+ -- check keytag from the label
+ keytag = tonumber(keytag)
+ if not keytag or math.floor(keytag) ~= keytag then
+ return state end -- pattern did not match, exit
+ if keytag < 0 or keytag > 0xffff then
+ return state end -- invalid keytag?!, exit
+
+ log_info(ffi.C.LOG_GRP_TASENTINEL, 'key tag: ' .. keytag .. ', sentinel: ' .. tostring(sentype))
+
+ local found = false
+ local ds_set = ffi.C.kr_ta_get(kres.context().trust_anchors, '\0')
+ if ds_set ~= nil then
+ for i = 0, ds_set:rdcount() - 1 do
+ -- Find the key tag in rdata and compare
+ -- https://tools.ietf.org/html/rfc4034#section-5.1
+ local rdata = ds_set:rdata_pt(i)
+ local tag = rdata.data[0] * 256 + rdata.data[1]
+ if tag == keytag then
+ found = true
+ end
+ end
+ end
+ log_info(ffi.C.LOG_GRP_TASENTINEL, 'matching trusted TA found: ' .. tostring(found))
+ if not found then -- print matching TAs in *other* states than Valid
+ for i = 1, #(trust_anchors.keysets['\0'] or {}) do
+ local key = trust_anchors.keysets['\0'][i]
+ if key.key_tag == keytag and key.state ~= 'Valid' then
+ log_info(ffi.C.LOG_GRP_TASENTINEL, 'matching UNtrusted TA found in state: '
+ .. key.state)
+ end
+ end
+ end
+
+ if sentype ~= found then -- expected key is not there, or unexpected key is there
+ pkt:clear_payload()
+ pkt:rcode(kres.rcode.SERVFAIL)
+ pkt:ad(false)
+ end
+ return state -- do not break resolution process
+end
+
+return M
diff --git a/modules/ta_signal_query/.packaging/test.config b/modules/ta_signal_query/.packaging/test.config
new file mode 100644
index 0000000..dfa7c2a
--- /dev/null
+++ b/modules/ta_signal_query/.packaging/test.config
@@ -0,0 +1,4 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+modules.load('ta_signal_query')
+assert(ta_signal_query)
+quit()
diff --git a/modules/ta_signal_query/README.rst b/modules/ta_signal_query/README.rst
new file mode 100644
index 0000000..3136ecb
--- /dev/null
+++ b/modules/ta_signal_query/README.rst
@@ -0,0 +1,31 @@
+.. SPDX-License-Identifier: GPL-3.0-or-later
+
+.. _mod-ta_signal_query:
+
+Signaling Trust Anchor Knowledge in DNSSEC
+==========================================
+
+The module for Signaling Trust Anchor Knowledge in DNSSEC Using Key Tag Query,
+implemented according to :rfc:`8145#section-5`.
+
+This feature allows validating resolvers to signal to authoritative servers
+which keys are referenced in their chain of trust. The data from such
+signaling allow zone administrators to monitor the progress of rollovers
+in a DNSSEC-signed zone.
+
+This mechanism serve to measure the acceptance and use of new DNSSEC
+trust anchors and key signing keys (KSKs). This signaling data can be
+used by zone administrators as a gauge to measure the successful deployment
+of new keys. This is of particular interest for the DNS root zone in the event
+of key and/or algorithm rollovers that rely on :rfc:`5011` to automatically
+update a validating DNS resolver’s trust anchor.
+
+.. attention::
+ Experience from root zone KSK rollover in 2018 shows that this mechanism
+ by itself is not sufficient to reliably measure acceptance of the new key.
+ Nevertheless, some DNS researchers found it is useful in combination
+ with other data so we left it enabled for now. This default might change
+ once more information is available.
+
+This module is enabled by default. You may use ``modules.unload('ta_signal_query')``
+in your configuration.
diff --git a/modules/ta_signal_query/ta_signal_query.lua b/modules/ta_signal_query/ta_signal_query.lua
new file mode 100644
index 0000000..72c1568
--- /dev/null
+++ b/modules/ta_signal_query/ta_signal_query.lua
@@ -0,0 +1,64 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+-- Module implementing RFC 8145 section 5
+-- Signaling Trust Anchor Knowledge in DNS using Key Tag Query
+local kres = require('kres')
+local ffi = require('ffi')
+
+local M = {}
+M.layer = {}
+
+-- transform trust anchor keyset structure for one domain name (in wire format)
+-- to signalling query name like _ta-keytag1-keytag2.example.com.
+-- Returns:
+-- string constructed from valid keytags
+-- nil if no valid keytag is present in keyset
+local function prepare_query_name(keyset, name)
+ if not keyset then return nil end
+ local keytags = {}
+ for _, key in ipairs(keyset) do
+ if key.state == "Valid" then
+ table.insert(keytags, key.key_tag)
+ end
+ end
+ if next(keytags) == nil then return nil end
+
+ table.sort(keytags)
+ local query = "_ta"
+ for _, tag in pairs(keytags) do
+ query = string.format("%s-%04x", query, tag)
+ end
+ if name == "\0" then
+ return query .. "."
+ else
+ return query .. "." .. kres.dname2str(name)
+ end
+end
+
+-- construct keytag query for valid keys and send it as asynchronous query
+-- (does nothing if no valid keys are present at given domain name)
+local function send_ta_query(domain)
+ local keyset = trust_anchors.keysets[domain]
+ local qname = prepare_query_name(keyset, domain)
+ if qname ~= nil then
+ log_info(ffi.C.LOG_GRP_TASIGNALING, "signalling query triggered: %s", qname)
+ -- asynchronous query
+ -- we do not care about result or from where it was obtained
+ event.after(0, function ()
+ resolve(qname, kres.type.NULL, kres.class.IN, "NONAUTH")
+ end)
+ end
+end
+
+-- act on DNSKEY queries which were not answered from cache
+function M.layer.consume(state, req, pkt)
+ -- First check for standard "cached packets": PKT_SIZE_NOWIRE, for efficiency.
+ if pkt.size ~= -1 and pkt:qtype() == kres.type.DNSKEY then
+ local qry = req:current()
+ if not qry.flags.CACHED then
+ send_ta_query(qry:name())
+ end
+ end
+ return state -- do not interfere with normal query processing
+end
+
+return M
diff --git a/modules/ta_update/.packaging/test.config b/modules/ta_update/.packaging/test.config
new file mode 100644
index 0000000..5fe5587
--- /dev/null
+++ b/modules/ta_update/.packaging/test.config
@@ -0,0 +1,4 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+modules.load('ta_update')
+assert(ta_update)
+quit()
diff --git a/modules/ta_update/meson.build b/modules/ta_update/meson.build
new file mode 100644
index 0000000..e1c074e
--- /dev/null
+++ b/modules/ta_update/meson.build
@@ -0,0 +1,21 @@
+# LUA module: ta_update
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+config_tests += [
+ ['ta_update', files('ta_update.test.lua'), ['snowflake']],
+]
+
+integr_tests += [
+ # NOTE: ta_update may pass in cases when it should fail due to race conditions
+ # To ensure reliability, deckard should introduce a time wait
+ ['ta_update', meson.current_source_dir() / 'ta_update.test.integr'],
+ ['ta_update.unmanagedkey', meson.current_source_dir() / 'ta_update.unmanagedkey.test.integr'],
+]
+
+lua_mod_src += [
+ files('ta_update.lua'),
+]
+
+install_data(
+ install_dir: modules_dir / 'ta_update',
+)
diff --git a/modules/ta_update/root.keys b/modules/ta_update/root.keys
new file mode 100644
index 0000000..e292b5a
--- /dev/null
+++ b/modules/ta_update/root.keys
@@ -0,0 +1 @@
+. IN DS 20326 8 2 E06D44B80B8F1D39A95C0B0D7C65D08458E880409BBC683457104237C7F8EC8D
diff --git a/modules/ta_update/ta_update.lua b/modules/ta_update/ta_update.lua
new file mode 100644
index 0000000..2361e16
--- /dev/null
+++ b/modules/ta_update/ta_update.lua
@@ -0,0 +1,349 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+-- Module interface
+local ffi = require('ffi')
+local kres = require('kres')
+local C = ffi.C
+
+assert(trust_anchors, 'ta_update module depends on initialized trust_anchors library')
+local key_state = trust_anchors.key_state
+assert(key_state)
+
+local ta_update = {}
+local tracked_tas = {} -- zone name (wire) => {event = number}
+
+
+-- Find key in current keyset
+local function ta_find(keyset, rr)
+ local rr_tag = C.kr_dnssec_key_tag(rr.type, rr.rdata, #rr.rdata)
+ if rr_tag < 0 or rr_tag > 65535 then
+ log_warn(ffi.C.LOG_GRP_TAUPDATE, string.format('ignoring invalid or unsupported RR: %s: %s',
+ kres.rr2str(rr), ffi.string(C.knot_strerror(rr_tag))))
+ return nil
+ end
+ for i, ta in ipairs(keyset) do
+ -- Match key owner and content
+ local ta_tag = C.kr_dnssec_key_tag(ta.type, ta.rdata, #ta.rdata)
+ if ta_tag < 0 or ta_tag > 65535 then
+ log_warn(ffi.C.LOG_GRP_TAUPDATE, string.format('[ta_update] ignoring invalid or unsupported RR: %s: %s',
+ kres.rr2str(ta), ffi.string(C.knot_strerror(ta_tag))))
+ else
+ if ta.owner == rr.owner then
+ if ta.type == rr.type then
+ if rr.type == kres.type.DNSKEY then
+ if C.kr_dnssec_key_match(ta.rdata, #ta.rdata, rr.rdata, #rr.rdata) == 0 then
+ return ta
+ end
+ elseif rr.type == kres.type.DS and ta.rdata == rr.rdata then
+ return ta
+ end
+ -- DNSKEY superseding DS, inexact match
+ elseif rr.type == kres.type.DNSKEY and ta.type == kres.type.DS then
+ if ta.key_tag == rr_tag then
+ keyset[i] = rr -- Replace current DS
+ rr.state = ta.state
+ rr.key_tag = ta.key_tag
+ return rr
+ end
+ -- DS key matching DNSKEY, inexact match
+ elseif rr.type == kres.type.DS and ta.type == kres.type.DNSKEY then
+ if rr_tag == ta_tag then
+ return ta
+ end
+ end
+ end
+ end
+ end
+ return nil
+end
+
+-- Evaluate TA status of a RR according to RFC5011. The time is in seconds.
+local function ta_present(keyset, rr, hold_down_time)
+ if rr.type == kres.type.DNSKEY and not C.kr_dnssec_key_ksk(rr.rdata) then
+ return false -- Ignore
+ end
+ -- Attempt to extract key_tag
+ local key_tag = C.kr_dnssec_key_tag(rr.type, rr.rdata, #rr.rdata)
+ if key_tag < 0 or key_tag > 65535 then
+ log_warn(ffi.C.LOG_GRP_TAUPDATE, string.format('[ta_update] ignoring invalid or unsupported RR: %s: %s',
+ kres.rr2str(rr), ffi.string(C.knot_strerror(key_tag))))
+ return false
+ end
+ -- Find the key in current key set and check its status
+ local now = os.time()
+ local key_revoked = (rr.type == kres.type.DNSKEY) and C.kr_dnssec_key_revoked(rr.rdata)
+ local ta = ta_find(keyset, rr)
+ if ta then
+ -- Key reappears (KeyPres)
+ if ta.state == key_state.Missing then
+ ta.state = key_state.Valid
+ ta.timer = nil
+ end
+ -- Key is revoked (RevBit)
+ if ta.state == key_state.Valid or ta.state == key_state.Missing then
+ if key_revoked then
+ ta.state = key_state.Revoked
+ ta.timer = now + hold_down_time
+ end
+ end
+ -- Remove hold-down timer expires (RemTime)
+ if ta.state == key_state.Revoked and os.difftime(ta.timer, now) <= 0 then
+ ta.state = key_state.Removed
+ ta.timer = nil
+ end
+ -- Add hold-down timer expires (AddTime)
+ if ta.state == key_state.AddPend and os.difftime(ta.timer, now) <= 0 then
+ ta.state = key_state.Valid
+ ta.timer = nil
+ end
+ if rr.state ~= key_state.Valid then
+ log_info(ffi.C.LOG_GRP_TAUPDATE, 'key: ' .. key_tag .. ' state: '..ta.state)
+ end
+ return true
+ elseif not key_revoked then -- First time seen (NewKey)
+ rr.state = key_state.AddPend
+ rr.key_tag = key_tag
+ rr.timer = now + hold_down_time
+ table.insert(keyset, rr)
+ return false
+ end
+end
+
+-- TA is missing in the new key set. The time is in seconds.
+local function ta_missing(ta, hold_down_time)
+ -- Key is removed (KeyRem)
+ local keep_ta = true
+ local key_tag = C.kr_dnssec_key_tag(ta.type, ta.rdata, #ta.rdata)
+ if key_tag < 0 or key_tag > 65535 then
+ log_warn(ffi.C.LOG_GRP_TAUPDATE, string.format('[ta_update] ignoring invalid or unsupported RR: %s: %s',
+ kres.rr2str(ta), ffi.string(C.knot_strerror(key_tag))))
+ key_tag = ''
+ end
+ if ta.state == key_state.Valid then
+ ta.state = key_state.Missing
+ ta.timer = os.time() + hold_down_time
+
+ -- Remove key that is missing for too long
+ elseif ta.state == key_state.Missing and os.difftime(ta.timer, os.time()) <= 0 then
+ ta.state = key_state.Removed
+ log_info(ffi.C.LOG_GRP_TAUPDATE, 'key: '..key_tag..' removed because missing for too long')
+ keep_ta = false
+
+ -- Purge pending key
+ elseif ta.state == key_state.AddPend then
+ log_info(ffi.C.LOG_GRP_TAUPDATE, 'key: '..key_tag..' purging')
+ keep_ta = false
+ end
+ log_info(ffi.C.LOG_GRP_TAUPDATE, 'key: '..key_tag..' state: '..ta.state)
+ return keep_ta
+end
+
+-- Update existing keyset; return true if successful.
+local function update(keyset, new_keys)
+ if not new_keys then return false end
+ if not keyset.managed then
+ -- this may happen due to race condition during testing in CI (refresh time < query time)
+ return false
+ end
+
+ -- Filter TAs to be purged from the keyset (KeyRem), in three steps
+ -- 1: copy TAs to be kept to `keepset`
+ local hold_down = (keyset.hold_down_time or ta_update.hold_down_time) / 1000
+ local keepset = {}
+ local keep_removed = keyset.keep_removed or ta_update.keep_removed
+ for _, ta in ipairs(keyset) do
+ local keep = true
+ if not ta_find(new_keys, ta) then
+ -- Ad-hoc: RFC 5011 doesn't mention removing a Missing key.
+ -- Let's do it after a very long period has elapsed.
+ keep = ta_missing(ta, hold_down * 4)
+ end
+ -- Purge removed keys
+ if ta.state == key_state.Removed then
+ if keep_removed > 0 then
+ keep_removed = keep_removed - 1
+ else
+ keep = false
+ end
+ end
+ if keep then
+ table.insert(keepset, ta)
+ end
+ end
+ -- 2: remove all TAs - other settings etc. will remain in the keyset
+ for i, _ in ipairs(keyset) do
+ keyset[i] = nil
+ end
+ -- 3: move TAs to be kept into the keyset (same indices)
+ for k, ta in pairs(keepset) do
+ keyset[k] = ta
+ end
+
+ -- Evaluate new TAs
+ for _, rr in ipairs(new_keys) do
+ if (rr.type == kres.type.DNSKEY or rr.type == kres.type.DS) and rr.rdata ~= nil then
+ ta_present(keyset, rr, hold_down)
+ end
+ end
+
+ -- Store the keyset
+ trust_anchors.keyset_write(keyset)
+
+ -- Start using the new TAs.
+ if not trust_anchors.keyset_publish(keyset) then
+ -- TODO: try to rebootstrap if for root?
+ return false
+ else
+ log_debug(ffi.C.LOG_GRP_TAUPDATE, 'refreshed trust anchors for domain ' .. kres.dname2str(keyset.owner) .. ' are:\n'
+ .. trust_anchors.summary(keyset.owner))
+ end
+
+ return true
+end
+
+local function unmanagedkey_change(file_name)
+ log_warn(ffi.C.LOG_GRP_TAUPDATE, 'you need to update package with trust anchors in "%s" before it breaks', file_name)
+end
+
+local function check_upstream(keyset, new_keys)
+ local process_keys = {}
+
+ for _, rr in ipairs(new_keys) do
+ local key_revoked = (rr.type == kres.type.DNSKEY) and C.kr_dnssec_key_revoked(rr.rdata)
+ local ta = ta_find(keyset, rr)
+ table.insert(process_keys, ta)
+
+ if rr.type == kres.type.DNSKEY and not C.kr_dnssec_key_ksk(rr.rdata) then
+ goto continue -- Ignore
+ end
+
+ if not ta and not key_revoked then
+ -- I see new key
+ ta_update.cb_unmanagedkey_change(keyset.filename)
+ end
+
+ if ta and key_revoked then
+ -- I see revoked key
+ ta_update.cb_unmanagedkey_change(keyset.filename)
+ end
+
+ ::continue::
+ end
+
+ for _, rr in ipairs(keyset) do
+ local missing_rr = true
+ for _, rr_old in ipairs(process_keys) do
+ if (rr.owner == rr_old.owner) and (rr.type == rr_old.type) and (rr.type == kres.type.DNSKEY) then
+ if C.kr_dnssec_key_match(rr.rdata, #rr.rdata, rr_old.rdata, #rr_old.rdata) == 0 then
+ missing_rr = false
+ break
+ end
+ end
+ end
+
+ if missing_rr then
+ -- This key is missing in the new keyset
+ ta_update.cb_unmanagedkey_change(keyset.filename)
+ end
+ end
+
+end
+
+-- Refresh the DNSKEYs from the packet, and return time to the next check.
+local function active_refresh(keyset, pkt, req, managed)
+ local retry = true
+
+ if pkt ~= nil and pkt:rcode() == kres.rcode.NOERROR then
+ local records = pkt:section(kres.section.ANSWER)
+ local new_keys = {}
+ for _, rr in ipairs(records) do
+ if rr.type == kres.type.DNSKEY then
+ table.insert(new_keys, rr)
+ end
+ end
+
+ if managed then
+ update(keyset, new_keys)
+ else
+ check_upstream(keyset, new_keys)
+ end
+ retry = false
+ else
+ local qry = req:initial()
+ if qry.flags.DNSSEC_BOGUS == true then
+ log_warn(ffi.C.LOG_GRP_TAUPDATE, 'active refresh failed, update your trust anchors in "%s"', keyset.filename)
+ elseif pkt == nil then
+ log_warn(ffi.C.LOG_GRP_TAUPDATE, 'active refresh failed, answer was dropped')
+ else
+ log_warn(ffi.C.LOG_GRP_TAUPDATE, 'active refresh failed for ' .. kres.dname2str(keyset.owner)
+ .. ' with rcode: ' .. pkt:rcode())
+ end
+ end
+ -- Calculate refresh/retry timer (RFC 5011, 2.3)
+ local min_ttl = retry and day or 15 * day
+ for _, rr in ipairs(keyset) do -- 10 or 50% of the original TTL
+ min_ttl = math.min(min_ttl, (retry and 100 or 500) * rr.ttl)
+ end
+ return math.max(hour, min_ttl)
+end
+
+-- Plan an event for refreshing DNSKEYs and re-scheduling itself
+local function refresh_plan(keyset, delay, managed)
+ local owner = keyset.owner
+ local owner_str = kres.dname2str(keyset.owner)
+ if not tracked_tas[owner] then
+ tracked_tas[owner] = {}
+ end
+ local track_cfg = tracked_tas[owner]
+ if track_cfg.event then -- restart timer if necessary
+ event.cancel(track_cfg.event)
+ end
+ track_cfg.event = event.after(delay, function ()
+ log_info(ffi.C.LOG_GRP_TAUPDATE, 'refreshing TA for ' .. owner_str)
+ resolve(owner_str, kres.type.DNSKEY, kres.class.IN, 'NO_CACHE',
+ function (pkt, req)
+ -- Schedule itself with updated timeout
+ local delay_new = active_refresh(keyset, pkt, req, managed)
+ delay_new = keyset.refresh_time or ta_update.refresh_time or delay_new
+ log_info(ffi.C.LOG_GRP_TAUPDATE, 'next refresh for ' .. owner_str .. ' in '
+ .. delay_new/hour .. ' hours')
+ refresh_plan(keyset, delay_new, managed)
+ end)
+ end)
+end
+
+ta_update = {
+ -- [optional] overrides for global defaults of
+ -- hold_down_time, refresh_time, keep_removed
+ hold_down_time = 30 * day,
+ refresh_time = nil,
+ keep_removed = 0,
+ tracked = tracked_tas, -- debug and visibility, should not be changed by hand
+ cb_unmanagedkey_change = unmanagedkey_change,
+}
+
+-- start tracking (already loaded) TA with given zone name in wire format
+-- do first refresh immediately
+function ta_update.start(zname, managed)
+ local keyset = trust_anchors.keysets[zname]
+ if not keyset then
+ panic('[ta_update] TA must be configured first before tracking it')
+ end
+ refresh_plan(keyset, 0, managed)
+end
+
+function ta_update.stop(zname)
+ if tracked_tas[zname] then
+ event.cancel(tracked_tas[zname].event)
+ tracked_tas[zname] = nil
+ trust_anchors.keysets[zname].managed = false
+ end
+end
+
+-- stop all timers
+function ta_update.deinit()
+ for zname, _ in pairs(tracked_tas) do
+ ta_update.stop(zname)
+ end
+end
+
+return ta_update
diff --git a/modules/ta_update/ta_update.test.integr/deckard.yaml b/modules/ta_update/ta_update.test.integr/deckard.yaml
new file mode 100644
index 0000000..1d005e3
--- /dev/null
+++ b/modules/ta_update/ta_update.test.integr/deckard.yaml
@@ -0,0 +1,12 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+programs:
+- name: kresd
+ binary: kresd
+ additional:
+ - --noninteractive
+ templates:
+ - modules/ta_update/ta_update.test.integr/kresd_config.j2
+ - tests/integration/hints_zone.j2
+ configs:
+ - config
+ - hints
diff --git a/modules/ta_update/ta_update.test.integr/kresd_config.j2 b/modules/ta_update/ta_update.test.integr/kresd_config.j2
new file mode 100644
index 0000000..da319a2
--- /dev/null
+++ b/modules/ta_update/ta_update.test.integr/kresd_config.j2
@@ -0,0 +1,56 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+{% for TAF in TRUST_ANCHOR_FILES %}
+trust_anchors.add_file('{{TAF}}')
+{% endfor %}
+
+{% raw %}
+
+-- Disable RFC8145 signaling, scenario doesn't provide expected answers
+if ta_signal_query then
+ modules.unload('ta_signal_query')
+end
+
+-- Disable RFC8109 priming, scenario doesn't provide expected answers
+if priming then
+ modules.unload('priming')
+end
+
+-- Disable this module because it make one priming query
+if detect_time_skew then
+ modules.unload('detect_time_skew')
+end
+
+policy.add(policy.suffix(policy.PASS, {todname('test.')}))
+cache.size = 2*MB
+log_level('debug')
+{% endraw %}
+
+modules.load('hints')
+hints.root({['{{ROOT_NAME}}'] = '{{ROOT_ADDR}}'})
+
+net = { '{{SELF_ADDR}}' }
+
+
+{% if QMIN == "false" %}
+option('NO_MINIMIZE', true)
+{% else %}
+option('NO_MINIMIZE', false)
+{% endif %}
+
+
+-- Self-checks on globals
+assert(help() ~= nil)
+assert(worker.id ~= nil)
+-- Self-checks on facilities
+assert(cache.count() == 0)
+assert(cache.stats() ~= nil)
+assert(cache.backends() ~= nil)
+assert(worker.stats() ~= nil)
+assert(net.interfaces() ~= nil)
+-- Self-checks on loaded stuff
+assert(net.list()[1].transport.ip == '{{SELF_ADDR}}')
+assert(#modules.list() > 0)
+-- Self-check timers
+ev = event.recurrent(1 * sec, function (ev) return 1 end)
+event.cancel(ev)
+ev = event.after(0, function (ev) return 1 end)
diff --git a/modules/ta_update/ta_update.test.integr/rfc5011-monotonictime.rpl b/modules/ta_update/ta_update.test.integr/rfc5011-monotonictime.rpl
new file mode 100644
index 0000000..c9e2204
--- /dev/null
+++ b/modules/ta_update/ta_update.test.integr/rfc5011-monotonictime.rpl
@@ -0,0 +1,5755 @@
+stub-addr: 2001:503:ba3e::2:30
+stub-name: rootns.
+trust-anchor: . IN DS 1867 8 2 EBF6C553C9DDABFB3522DFD4E62A857D9E00E373686C3479064B46BF6E43AC5E
+val-override-date: 20170701000000
+query-minimization: off
+CONFIG_END
+
+SCENARIO_BEGIN Successfull RFC 5011 KSK roll-over simulator for 2017
+
+
+RANGE_BEGIN 20170701000000 20170710999999
+ ADDRESS 198.41.0.4
+ ADDRESS 2001:503:ba3e::2:30
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. IN SOA
+SECTION ANSWER
+. 86400 IN SOA rootns. you.test. 2017071100 1800 900 604800 86400
+. 86400 IN RRSIG SOA 8 0 86400 20170715000000 20170701000000 37284 . MXzziCbaLNyN/I6vS5rNpEua0moTNYjG ICy9SgiSs4yNvyZ+Kn/1puEbaxLJ2M6J vVjVCbJMVTrINvLmgVcG3UphIFBdrgfo FZkav2nHbybKao5WafStZzGpKQJkBTeA fqKMXuPtKwM1g9Tzwr2YxdLVoGzBYA/t s41uKHI0/1YcU9nMadlmY/3rJPFOUIrl iCwskFGmLVickcRnp/z0FmTd1k67wSrn z16Ys7xeQknHOlr5DqBtezicRE63srvv j8QuOL5wLhknmmqnntVYkYXHKsZpWsEE OWxLc4PwbDvVI5LDZ3NmCAH0k7ygc5/s WsnAKKvzDfT5lXtudOkCWg==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. IN DNSKEY
+SECTION ANSWER
+. 1814400 IN DNSKEY 256 3 8 AwEAAeh0qmH7cGmSjplVMqU27YkofOHp tt6deTnAprIDS5lws0Y3vFm+NNEDaZHB SHqIbxEFW5uX33rQ5EfCFQI1gdfjCtCi obwPvu04P6t2cuP9qSusTXGlr9qaqNCh ntErj1oK+2QH1S86ttgepzv4kF9y/Ee4 B4YQttSLuTcWO9bZR3v5QWT4581bPlMO Oj3Yo2Ubs81qtOoiI2grq7Yn7x/sTt43 pDstuS7wwaOnKb36S5BAMBDwZCXRFeDV sm0EseG5qeu0K6E8AOVE3wjOePetzpDE 6O0k0BM6QlPZ3EttnNgqVyZFZwHZu8vM Yoo5zypyH58AAGAONZKwQeg3nak=
+. 1814400 IN DNSKEY 256 3 8 AwEAAe1udmhwaWyg6PD00YReHeT6nYeN hKAy6oKMc7X5NXXJq6baVZT5p3AnFm7B 0ReT1dOpOjZuArydSdASupCQwRPVja+m 8PQSaAdThTifIBbP0Y2TeeA3yfGbHubo scMezJAXr7FGDQ8XIfyUYBDBoDaINi6j V/oI+aSnwm0uWdxHqfonzioTYenuTsax OGLYYuCMn9soxIuXatO53MpqfsJgh7UK FDCDGKA9pFts1vTQdCMPGgEsuYHjsYF0 /kUoRAQJM3jh0t3wE3JQ/HjFIyR37NCM w+i20b1v6/Xo86gy2nhXq2BopawLPEh0 Fv2UCCI7f8k2JvvF2o9udq/N+FE=
+. 1814400 IN DNSKEY 257 3 8 AwEAAcgeCFZiwMD0S6TVgSK3Ob/MKFo+ dHYeNgoOjxH3JoxV09WShBXID/LwKs/e sYAIzTOBB8Fu9IDoVuQe5prOEcGZRp6u zF7JLnqrgOzoaSPRmKsvXh8DfipA56qE AqNwYBCqzlbGIGjHOQ8t+Xonp4fSBYbN MLmh7o8+u55k7PxemKTCiAnY7Bjx0g3m J1HuFvQXDDdvyletuoS3NKqrkjqdOHRB 3p3GKrKgw+zVb05UEyotCEKjqqi+BOmg cm8rmUIeaNQREjxrUyr8/Ry67h5NJLfq LAqAnSePf1PyhQcl8XjGHXN7w1tLLyJu Gy5B3zLSW1P6jIjon77PSn+cXi0=
+. 1209600 IN RRSIG DNSKEY 8 0 1814400 20170722000000 20170701000000 1867 . aCKUdEnbwdvfHHiGS4xzUB/H+wdSgyqs 2YiGyLAnd8R/u1LpQ2hqEzSMqSr7blfL OLMIy/SA3PulAdPbBub5aM9qAveqc+Mc +vOIugZrWHYOECPXmJsmNBj8VT5FEOuw N+PzReRG4P6SzyZ4DckIcfpIjikCHPS/ 6JEkkYCzktx/DcKmI0kQtGIUHXrwvaTn 7G8fjZpZUUBwG0IKYg629vo5IgVlmPPr kvsLWgQuKu6pu30iA3DmIAI6AX0O2xnh HsUzliRPdt7WgJCCX+knJr4d9rv3FsGi /VvCeQhBxjWVQBKMlfvnWagp820muw0X UwHnzEkIRQyv9JDabdJtQg==
+. 1209600 IN RRSIG DNSKEY 8 0 1814400 20170722000000 20170701000000 37284 . KpkR9ceTqCxkKT7Gbq0poQhiv19qI1BD ahGsTJheWlruVH3wSQ2OsAl4pkmS+ich 1065M/OsL/3EHAbYsZ9yskhPJwyeZVDP cgfEusQxMekz+0s98jHt/QqgKBJdiF2F uu/krrYctAJos4i6P93paKHmuji7tiL2 JBuENw5G+WfqGBUciI3ca9QMDPbHWS4z bgW6ViSFdVC/D3l+ZULoAB/FBQykAESn /hGGbDBfG1wfkngfXkByTLKzWzSQsIOr krbJ38W3Sm/1GjAZdesJBJQcxm6e2dyN N3j51hZTH23dvEzqCcRCVqkeCDRlzxPc YGteAaRAnMNh/gB4r7AUbw==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. 518400 IN NS rootns.
+. 518400 IN RRSIG NS 8 0 518400 20170715000000 20170701000000 37284 . TV/Ad1roCxCazfDEk1UvRiGIelQDmQIx yHEtce3db9fTcag3fvSj+swbAiHoYaV8 gm7ZWaI/rBuoi4WIeHPGmtc5WF8uTpgK EmIO5DzVYubZQ9o3KdYxe4fqHm0LZovX H+7eLsUcMHavzhrRx0KvrHQQ3mxMGIGv cxwO1WDhAAj1tlkkix1Rwxwf59lIBB6s Y+eXI2TKVe9gnVSjx/YHkVeRxB4lHhWy cCWiqYjgKmeu+tlGorcI9gwvjc0/CFnL fnk3cnWD3RdnNyg4qnqpziqkCWrZ0Vae KJ/nDWmObViBKclYVSGMMv/O1HCQS6/M rYo2HKURPYvWqjUr+JOq3Q==
+SECTION ADDITIONAL
+rootns. 518400 IN A 198.41.0.4
+rootns. 518400 IN AAAA 2001:503:ba3e::2:30
+rootns. 518400 IN RRSIG A 8 1 518400 20170715000000 20170701000000 37284 . bqmvP3LjtKK+owiC+MpcZeYM3xmHUpEX YEMqCQmFL7Pa7dOBJIedO9ZXNBV6RjTI 3MY1VEtQxsUu0QbdCsjHksZw6N1ovHoq PyPssQF1WZsNZan8fMPdtvByKBjbM5qL AGF3IeAnIMYEaPDovDBaBXFh3JqLBrV2 kDM5/ddyI0NgFr/XFcrEyCCSXzEqzEFC J0Bps1+cleRZT4ypUA0UYH2/feoBHV// jhG1BQqoGFQwvQnTUVNxcmZpJa+jNCnL YrDwUmbRx0drh++9uFhdWL7nElWKejcj 3tt02FnAwASKz6VpFGVk0Iu7r/OFAf3a r/KB3beYk+ahMbHl53+gJg==
+rootns. 518400 IN RRSIG AAAA 8 1 518400 20170715000000 20170701000000 37284 . 0VMyTLgwifNoeM9EWiRRD5m4I6Hmg/va vRnhLSv4l3+v7l1FakRjGQ1Ov9bEs5sR vyzFlr0D9TwCQyMD9pnE3kiWpwtFYLaS RRSM9rPbSQ9+UnZ0OMvg5k1g+wQ/ssS4 vLduDlTXPXrwdg8NrAM3RhI2lAanPrGU MSu+eWNOvv2hu9x1L+I5orbMELJfjSvu 30hEa1HUJmvC6oyshWBIbQtiWWPRqXo2 AuwT+IpZrR87FsCQxxrAX8ptxnKI8A19 SOLfiHMXXAoHxF3xZvTR5ZO1zpx6YL8O cwXkln+6OMIPlrlQ60vrRIXmBiJcJq9q Bn2ER5//+J3fzmmeRWhodQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rootns. IN NS
+SECTION AUTHORITY
+. 86400 IN SOA rootns. you.test. 2017071100 1800 900 604800 86400
+rootns. 86400 IN NSEC test. A AAAA RRSIG NSEC
+. 86400 IN RRSIG SOA 8 0 86400 20170715000000 20170701000000 37284 . MXzziCbaLNyN/I6vS5rNpEua0moTNYjG ICy9SgiSs4yNvyZ+Kn/1puEbaxLJ2M6J vVjVCbJMVTrINvLmgVcG3UphIFBdrgfo FZkav2nHbybKao5WafStZzGpKQJkBTeA fqKMXuPtKwM1g9Tzwr2YxdLVoGzBYA/t s41uKHI0/1YcU9nMadlmY/3rJPFOUIrl iCwskFGmLVickcRnp/z0FmTd1k67wSrn z16Ys7xeQknHOlr5DqBtezicRE63srvv j8QuOL5wLhknmmqnntVYkYXHKsZpWsEE OWxLc4PwbDvVI5LDZ3NmCAH0k7ygc5/s WsnAKKvzDfT5lXtudOkCWg==
+rootns. 86400 IN RRSIG NSEC 8 1 86400 20170715000000 20170701000000 37284 . Umcn1NDbjEEmeIjK2V5JgIjD45fh+CMw ry834Q7hCK838ePxPVGt3eqXsD/evlk4 WD72Ir49kb7P2rtPqPSdYZBJy0qRiznZ +9+IoXSwezSfMYAze4rb2Qng2TjPEgan ptrFAFBNrRyQB83QLqhUKMHoqINyX+yJ WhMmO/KoEYzg+VdttS1VOi61TL6CivjL 5WFwO5oBHyj91kudvt0LQ58wSndlXzJ2 NwX8tjJcBfyp2tMItFn7c4mMjZyHKxrt tnJkP743NH4Og84ie4QSu4PaVWk+T3+Y n9pg0Dxc2URqbI2OXN0Ggi5i17zdyAeC 6mjA60qAJEKfacqJrqh4nA==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rootns. IN A
+SECTION ANSWER
+rootns. 518400 IN A 198.41.0.4
+rootns. 518400 IN RRSIG A 8 1 518400 20170715000000 20170701000000 37284 . bqmvP3LjtKK+owiC+MpcZeYM3xmHUpEX YEMqCQmFL7Pa7dOBJIedO9ZXNBV6RjTI 3MY1VEtQxsUu0QbdCsjHksZw6N1ovHoq PyPssQF1WZsNZan8fMPdtvByKBjbM5qL AGF3IeAnIMYEaPDovDBaBXFh3JqLBrV2 kDM5/ddyI0NgFr/XFcrEyCCSXzEqzEFC J0Bps1+cleRZT4ypUA0UYH2/feoBHV// jhG1BQqoGFQwvQnTUVNxcmZpJa+jNCnL YrDwUmbRx0drh++9uFhdWL7nElWKejcj 3tt02FnAwASKz6VpFGVk0Iu7r/OFAf3a r/KB3beYk+ahMbHl53+gJg==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rootns. IN AAAA
+SECTION ANSWER
+rootns. 518400 IN AAAA 2001:503:ba3e::2:30
+rootns. 518400 IN RRSIG AAAA 8 1 518400 20170715000000 20170701000000 37284 . 0VMyTLgwifNoeM9EWiRRD5m4I6Hmg/va vRnhLSv4l3+v7l1FakRjGQ1Ov9bEs5sR vyzFlr0D9TwCQyMD9pnE3kiWpwtFYLaS RRSM9rPbSQ9+UnZ0OMvg5k1g+wQ/ssS4 vLduDlTXPXrwdg8NrAM3RhI2lAanPrGU MSu+eWNOvv2hu9x1L+I5orbMELJfjSvu 30hEa1HUJmvC6oyshWBIbQtiWWPRqXo2 AuwT+IpZrR87FsCQxxrAX8ptxnKI8A19 SOLfiHMXXAoHxF3xZvTR5ZO1zpx6YL8O cwXkln+6OMIPlrlQ60vrRIXmBiJcJq9q Bn2ER5//+J3fzmmeRWhodQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. 1 IN TXT "it works"
+test. 1 IN RRSIG TXT 8 1 1 20170715000000 20170701000000 37284 . h9R23s9ZHXVX5wcCV7ToIE4dTQ1fAGqw ehpmzvbblti8phOdm+/u2ActSH4VMLo1 ze1U7vVuSuNMII4l27vARn6XFwhdHYqh lril9Yu6iyx/sKyqbLoyzQ0aD9E1SnO2 aRNWdpjeIYvw7cwvqFaH4bj854eB2clc 7s1olLEkQmZ7oBWKx9+v73Pg587Ky3Z1 Cw5f+iLa0ld/t6m8BtAmRjYc9hj1s0ph 65SzaU4KZKNikG0QVsNC1AnpFbrYSbWD MAEyp6cU/KfF7VrKGaIgWu+Z8eU1v0fN BOsPkfBooSJj2v5nded2W+yCV+plZGVj pdTESXNoZYLyvgsX6DoDYQ==
+ENTRY_END
+RANGE_END
+
+
+
+RANGE_BEGIN 20170711000000 20170720999999
+ ADDRESS 198.41.0.4
+ ADDRESS 2001:503:ba3e::2:30
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. IN SOA
+SECTION ANSWER
+. 86400 IN SOA rootns. you.test. 2017071100 1800 900 604800 86400
+. 86400 IN RRSIG SOA 8 0 86400 20170725000000 20170711000000 37284 . 2OY96fDuZ/ZCQxiryCYeSknlLFG3btVH W15h88UgKw5z0eLmBMUO95tPlSjF5A/Z PgQT6+qXXJMoLNxPGeTsNGl+oPxXCeFq 7+egtR1KLNafoYb8TgpW9I/lsKi8KwY9 tL1ySvoultD8Vd4RYx5MD/T+NI1f5rk7 y7UxPngi5zIw+GMZnGWSdJW3qhevUGLN l5wFjFhSleLXO1JkCzM+fxQJgR+qLJk0 0YfFK6TCEPwMBybwWN6/NuRWotfc57au 7ZavTEPDDLpWivElJyMH1/BSUviHbJI5 brQsdc91jADXp+W9lCpwNDNs5iU5WdJv rN8tqpp/MHJedmYMW67jdg==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. IN DNSKEY
+SECTION ANSWER
+. 1814400 IN DNSKEY 256 3 8 AwEAAe1udmhwaWyg6PD00YReHeT6nYeN hKAy6oKMc7X5NXXJq6baVZT5p3AnFm7B 0ReT1dOpOjZuArydSdASupCQwRPVja+m 8PQSaAdThTifIBbP0Y2TeeA3yfGbHubo scMezJAXr7FGDQ8XIfyUYBDBoDaINi6j V/oI+aSnwm0uWdxHqfonzioTYenuTsax OGLYYuCMn9soxIuXatO53MpqfsJgh7UK FDCDGKA9pFts1vTQdCMPGgEsuYHjsYF0 /kUoRAQJM3jh0t3wE3JQ/HjFIyR37NCM w+i20b1v6/Xo86gy2nhXq2BopawLPEh0 Fv2UCCI7f8k2JvvF2o9udq/N+FE=
+. 1814400 IN DNSKEY 257 3 8 AwEAAcgeCFZiwMD0S6TVgSK3Ob/MKFo+ dHYeNgoOjxH3JoxV09WShBXID/LwKs/e sYAIzTOBB8Fu9IDoVuQe5prOEcGZRp6u zF7JLnqrgOzoaSPRmKsvXh8DfipA56qE AqNwYBCqzlbGIGjHOQ8t+Xonp4fSBYbN MLmh7o8+u55k7PxemKTCiAnY7Bjx0g3m J1HuFvQXDDdvyletuoS3NKqrkjqdOHRB 3p3GKrKgw+zVb05UEyotCEKjqqi+BOmg cm8rmUIeaNQREjxrUyr8/Ry67h5NJLfq LAqAnSePf1PyhQcl8XjGHXN7w1tLLyJu Gy5B3zLSW1P6jIjon77PSn+cXi0=
+. 1814400 IN DNSKEY 257 3 8 AwEAAfX4eSO5BEPXggvx4jL5HkEjbA+5 QD8Acnh4wOHNv/OJX4QhKnpoMDOrpp38 n0Rgcr8qZ0XUqiJWl8eEH//wrQDHoO5/ JHRmibVrcA6UqfhUa25D1BfeMtTgMCSS +W3/heB/YhyXOJtOdWDmJutDY1nfJUSK rF6XwBj4us7U5jvwXwq+l36AeI4q7I87 Std0GNgRdA6/cJtApPoGv/0oNE0iNTyu IBcAR+AeWu32+JavhTycmtMfZ+KOIShq uI9RHzChZ9yLikAT+gclJGLLlxIr6HDr SLChCG90/yvmc57dLn8qhRWRJtJeLT2V HSxeP7oREb6RSdkxET6OTf9GYHE=
+. 1209600 IN RRSIG DNSKEY 8 0 1814400 20170801000000 20170711000000 1867 . FyApZOPhk7K90BGdNryD4EbpD/0bB6th 8rztEnRZV8dmtILZOaFmkoTweyJGpZZU HoVjsffD+wr1FlngJy7mYwZRIctK6NYJ 3aocw1BXNeSZdvmaQnPOI2TBbHhb8bhG GHzpsmFMNmD5lMDMbjZWzJKfv5pCboun pbyowlGNz9uX/x2uSGkTa0m4XkCEQLYT lHLntHu07Y834yfmcIUsQC2Z0ZWTdumh /RXWrw4dwTPT8+ldiUOcVwGsjaKGkyq2 +qCohuU7wrjJoWFTqZg2kbCfSP+4/kLk x7/AetbXAXyZaFRofo/3Lxuz+5lUs/p6 NoLBniZG6mxR5t7B4brVsg==
+. 1209600 IN RRSIG DNSKEY 8 0 1814400 20170801000000 20170711000000 37284 . wDk28IaSAi/tIgARka5b8CyyC8fcj092 GMhS6wFy7M1rBfuALvcD+Tx/PpCmWFiq bv5zmomvWzMfV80fYGngc2zOpuQfrSfM GN0JnR2PVh84B1x6H1jpnnxE4Q3fYNBi jNHRwAuuACAaSv98vcNt964v8eZypCrS t+yLz5AQUMciG0PNP15UbgF9gyWGfIW4 dgGOT8R23vxPdaXcRMltF6lW9IUTU46i 4gC345GYwrJw5BW1cVLg5YL3VtEUFJFM K0A21HwJgm2IH26AHvyuxOnOlwSO6AXu Cxg983nxABMz0ek6hXAFYkMAT2yINUrO 2nQisL+40gnq3hEUoNZUKA==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. 518400 IN NS rootns.
+. 518400 IN RRSIG NS 8 0 518400 20170725000000 20170711000000 37284 . H8r2rvoxyCYAlajIv4puL97JwYg141+F uqXAchdx9Ko0P/7ynaRVttOIAQ1WtCha REXryEctxIp+sfOTzZBJSfQklRrYZuwh TWl9w7Ly1HcSu4NJG30Tg0rfKpPLHbsP dYee6tuJgqK+ZYU06bVd4ZySZ7WHLBMh gf3kjk2QbArp/+wtvbzhELXEw2fj2SD7 GKjvifUa3EymG7NyzFtd6+eJX7/88r8V qa176g7ueukqjnt2Yyiw+mKbYAsr3Ob3 Yx+x8tWUF6/depiB33jNfxhQJBD824kz c3o+hKWI/Dq+9WNRjm/hSGZZqtjdpdNa WF1Iq25nMg/G7oWezFIS+g==
+SECTION ADDITIONAL
+rootns. 518400 IN A 198.41.0.4
+rootns. 518400 IN AAAA 2001:503:ba3e::2:30
+rootns. 518400 IN RRSIG A 8 1 518400 20170725000000 20170711000000 37284 . KJYdNDfdqXwtTQrU7Rwe0mN5mG90GfSm Uu7w10wZhFr/Vi0yXdbVbs3yBOmlPMEI vQ3TFjfMfdyNGxBxoJ4gX4w47GIXXX1W uIN6g+xt0pIfYo/+aKY8776akfRjBNOk Un825x9HArLiA64QkOZya1ESWFKzx9uL dIwxHm53QkmtAPU0D12xrZmamdLKANQu rHUDDxZYg49sraLDZQxTIP+jSA7pge9K 5iNdCs9RuJfW43J1hpaM7tNjq34w9Je8 LnLEUDsN0VD2w375wXEznwx3CQk2lpLP hjTHHp/fs51GwAjVD2v8GHYOi+3CBjkK 1c70SE9ARujlpDzybbGv3Q==
+rootns. 518400 IN RRSIG AAAA 8 1 518400 20170725000000 20170711000000 37284 . QQQI7Bnp7H3UXzhlybA1UfJxyUmtCFO/ Syv/GVoQfmHuCpTye9COUaqwC1d6H9+K 59L7zKMZ8Vpn9OMmuYD/w47qwPLR/0LK Ni+AuHqi4Yjv8ADSqOXzXNl+isWWvOJd 4hR11ZuRoZW5tgWu5o3Ih0Ec5Y/VPpLj JtKBRTBk5xccSgGIk8GSovu7hyMEKamI wMIO1rIfIKSYFrp09YCIc66nrU6/hyg2 0tUtsZNjZwg9c2O/NIH8VYSATw0ppFnO LMoR6CpRZyCrxCB1FsrnyVuzRTYvAdO6 +7UuDiliPQ4GPHFb1wdhTr/W+TGh0UIQ JI02FsITRsf2BNjE6DXk6Q==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rootns. IN NS
+SECTION AUTHORITY
+. 86400 IN SOA rootns. you.test. 2017071100 1800 900 604800 86400
+rootns. 86400 IN NSEC test. A AAAA RRSIG NSEC
+. 86400 IN RRSIG SOA 8 0 86400 20170725000000 20170711000000 37284 . 2OY96fDuZ/ZCQxiryCYeSknlLFG3btVH W15h88UgKw5z0eLmBMUO95tPlSjF5A/Z PgQT6+qXXJMoLNxPGeTsNGl+oPxXCeFq 7+egtR1KLNafoYb8TgpW9I/lsKi8KwY9 tL1ySvoultD8Vd4RYx5MD/T+NI1f5rk7 y7UxPngi5zIw+GMZnGWSdJW3qhevUGLN l5wFjFhSleLXO1JkCzM+fxQJgR+qLJk0 0YfFK6TCEPwMBybwWN6/NuRWotfc57au 7ZavTEPDDLpWivElJyMH1/BSUviHbJI5 brQsdc91jADXp+W9lCpwNDNs5iU5WdJv rN8tqpp/MHJedmYMW67jdg==
+rootns. 86400 IN RRSIG NSEC 8 1 86400 20170725000000 20170711000000 37284 . v5dTMrchkwFBx30aWw+I3IrZB/rH79Ar zfnX337y5PlocwWGl31QXxl8JXjt14wU zRTGebGceKeYpuSl4KcR/zxPaP/Y/wtf o9HnxsuAja9vlQh2b2nY5TWRHf4ZqCkA c41SPAAn59O2HKEE4/9TPn1W47n4IZsJ 4mb/x7G6pL7jUykaVnLtlnEv3RrQxxbp hJe+JW2bk8Gj8ih+fYavO23pxUIR5vEb CSM9yAFJ+is4X6d6UqCOgvy+qHzHcTAu 6PJzmI1fX2mNkn0Zj//DaQg+cRkggEsE FJGSxvZBb7pvOIy7khMNB+NuwSHkcGyp OVplGjchbkLY59kOYKRQNA==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rootns. IN A
+SECTION ANSWER
+rootns. 518400 IN A 198.41.0.4
+rootns. 518400 IN RRSIG A 8 1 518400 20170725000000 20170711000000 37284 . KJYdNDfdqXwtTQrU7Rwe0mN5mG90GfSm Uu7w10wZhFr/Vi0yXdbVbs3yBOmlPMEI vQ3TFjfMfdyNGxBxoJ4gX4w47GIXXX1W uIN6g+xt0pIfYo/+aKY8776akfRjBNOk Un825x9HArLiA64QkOZya1ESWFKzx9uL dIwxHm53QkmtAPU0D12xrZmamdLKANQu rHUDDxZYg49sraLDZQxTIP+jSA7pge9K 5iNdCs9RuJfW43J1hpaM7tNjq34w9Je8 LnLEUDsN0VD2w375wXEznwx3CQk2lpLP hjTHHp/fs51GwAjVD2v8GHYOi+3CBjkK 1c70SE9ARujlpDzybbGv3Q==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rootns. IN AAAA
+SECTION ANSWER
+rootns. 518400 IN AAAA 2001:503:ba3e::2:30
+rootns. 518400 IN RRSIG AAAA 8 1 518400 20170725000000 20170711000000 37284 . QQQI7Bnp7H3UXzhlybA1UfJxyUmtCFO/ Syv/GVoQfmHuCpTye9COUaqwC1d6H9+K 59L7zKMZ8Vpn9OMmuYD/w47qwPLR/0LK Ni+AuHqi4Yjv8ADSqOXzXNl+isWWvOJd 4hR11ZuRoZW5tgWu5o3Ih0Ec5Y/VPpLj JtKBRTBk5xccSgGIk8GSovu7hyMEKamI wMIO1rIfIKSYFrp09YCIc66nrU6/hyg2 0tUtsZNjZwg9c2O/NIH8VYSATw0ppFnO LMoR6CpRZyCrxCB1FsrnyVuzRTYvAdO6 +7UuDiliPQ4GPHFb1wdhTr/W+TGh0UIQ JI02FsITRsf2BNjE6DXk6Q==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. 1 IN TXT "it works"
+test. 1 IN RRSIG TXT 8 1 1 20170725000000 20170711000000 37284 . YryqMdq2kUnFyGH+m2iUSdQDu2W2W/Oc tWia7RSvPKzL+W9QdxQi3D/HX3/jXEXj vsIRJQiupIkKOLwXcugV0qdAK04pEnWp NgqKKmNzsjzp+CPy5VfFrfWuZ/GelsSh NbD2lPaNFZ/PBVk5dlyJJJerG+CiT0w8 l+uoxdwQ88OpNoXf+vTchnFBJmcuKkW0 +eXOM8R0nt1lt9pQxycxExiJgw2wEv64 vVPdDCytzJ43XTwKlpjPaX4j5Ga13N6K kLf/wltyB0ucLe+ERFaHuQBEs2buQ7zm UF6l7LfjAlepU1UwE7Zk8dXrKbWmD7oP kXx/6U6E51RRyB8w66qsWA==
+ENTRY_END
+RANGE_END
+
+
+
+RANGE_BEGIN 20170721000000 20170730999999
+ ADDRESS 198.41.0.4
+ ADDRESS 2001:503:ba3e::2:30
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. IN SOA
+SECTION ANSWER
+. 86400 IN SOA rootns. you.test. 2017071100 1800 900 604800 86400
+. 86400 IN RRSIG SOA 8 0 86400 20170804000000 20170721000000 37284 . St+fTzqEpu/Sq4oQwNZY9YaEkD4+Oqgy LFW4JNxYuwM0vMZnhAgMxrHZKI4Vg+I2 +85inalP5mYJm0kEYm7QF4FeRk1xWKWb f8GRIYSo3eWsd4FHlfGtLkLm9MIcopzY 4N6v/tHPVanhT61ppqXPg9A8DyjPrDKp tw/aMyV7ewV8GFpip/YHT5imMChbyfyM Gg74MhqREpO+LpCFeXseH4O+1d4gw2nI ewX7sEnb5CqZlKHf/eas5MpwyUysZ0y+ UPerUDPc7NDo/zZkA032BeqMFXAcwdy8 vN+UANTJHWFLhnPtCHX0Imc6rW9Zlopo TqCrXW25bMLByViigbZwIQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. IN DNSKEY
+SECTION ANSWER
+. 1814400 IN DNSKEY 256 3 8 AwEAAe1udmhwaWyg6PD00YReHeT6nYeN hKAy6oKMc7X5NXXJq6baVZT5p3AnFm7B 0ReT1dOpOjZuArydSdASupCQwRPVja+m 8PQSaAdThTifIBbP0Y2TeeA3yfGbHubo scMezJAXr7FGDQ8XIfyUYBDBoDaINi6j V/oI+aSnwm0uWdxHqfonzioTYenuTsax OGLYYuCMn9soxIuXatO53MpqfsJgh7UK FDCDGKA9pFts1vTQdCMPGgEsuYHjsYF0 /kUoRAQJM3jh0t3wE3JQ/HjFIyR37NCM w+i20b1v6/Xo86gy2nhXq2BopawLPEh0 Fv2UCCI7f8k2JvvF2o9udq/N+FE=
+. 1814400 IN DNSKEY 257 3 8 AwEAAcgeCFZiwMD0S6TVgSK3Ob/MKFo+ dHYeNgoOjxH3JoxV09WShBXID/LwKs/e sYAIzTOBB8Fu9IDoVuQe5prOEcGZRp6u zF7JLnqrgOzoaSPRmKsvXh8DfipA56qE AqNwYBCqzlbGIGjHOQ8t+Xonp4fSBYbN MLmh7o8+u55k7PxemKTCiAnY7Bjx0g3m J1HuFvQXDDdvyletuoS3NKqrkjqdOHRB 3p3GKrKgw+zVb05UEyotCEKjqqi+BOmg cm8rmUIeaNQREjxrUyr8/Ry67h5NJLfq LAqAnSePf1PyhQcl8XjGHXN7w1tLLyJu Gy5B3zLSW1P6jIjon77PSn+cXi0=
+. 1814400 IN DNSKEY 257 3 8 AwEAAfX4eSO5BEPXggvx4jL5HkEjbA+5 QD8Acnh4wOHNv/OJX4QhKnpoMDOrpp38 n0Rgcr8qZ0XUqiJWl8eEH//wrQDHoO5/ JHRmibVrcA6UqfhUa25D1BfeMtTgMCSS +W3/heB/YhyXOJtOdWDmJutDY1nfJUSK rF6XwBj4us7U5jvwXwq+l36AeI4q7I87 Std0GNgRdA6/cJtApPoGv/0oNE0iNTyu IBcAR+AeWu32+JavhTycmtMfZ+KOIShq uI9RHzChZ9yLikAT+gclJGLLlxIr6HDr SLChCG90/yvmc57dLn8qhRWRJtJeLT2V HSxeP7oREb6RSdkxET6OTf9GYHE=
+. 1209600 IN RRSIG DNSKEY 8 0 1814400 20170811000000 20170721000000 1867 . Xy4GIqglfhPKFoO7bbK/FzQwbWYw/e/d MwYYHGzjvui3MykT53WTP0qQk08Pr+Ae zF8Z05Bv4j7QTY3+l0W1NVMQD1akc0Tp purQRzqgv/PzoTzMm0g7h2mGHP3R17pV kWAb7tv1ha6oO6cx8TQfMeKfuI0Z9vPd N20BYUd1FwLLITnbXrpCRvNMJw7mf3fN 1SbTJrMquQhcN6EA3pdDxYGktabYBnRv DCeWluSHTBlqym0Hq3afphc0zYwfwgUq ZPKcuxXjXbxO0yZCeJjQ49u7z55nw6yc 1qSJEjPtQPKHjcJSdbB60rNIdg5osKqz iApC63Ug8VTP18eIugRSjA==
+. 1209600 IN RRSIG DNSKEY 8 0 1814400 20170811000000 20170721000000 37284 . S2cOcWa3/a/y5udmWgsXal3a0SlnUpnV Wr7eJCdkQ8Au4V+nOdaBj0ZFg0RscC/I QHrNoKaY2H0QpuLtX+wtav/CyL36Uhse xP4MzY+KPJkPzCq8AsReHeFWFV1PSiAo 6PlF81QgLeO5AytRu9dEPhgOc0k9q7cQ np+STJqoD7+j0C8rKclJmAa4qsrFgIk4 45pgwgbHhmbnWHCpKLJXK326K1x9yP1W DZIwX9U+UEDyZxvdoiwrXcytehvae6Fs FdQ1WlP+SLdrQC4NrQUeTHBlveYlL0o2 gW9+M/lljq+Tb+3T2eoBRCev+CW4E9jc UEV+v0rGHW7Oqivcb9yoiA==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. 518400 IN NS rootns.
+. 518400 IN RRSIG NS 8 0 518400 20170804000000 20170721000000 37284 . CRMahktbnKGSnjLeg1KOUHLql++CLK7C A3v6y6h04COVZcq7IojE/woy1yOGY2cK 1oyFvhvYn0fN9DTmsGnoNojY4kiyOvg0 egbizLiHHsy2QJTM5sQOKy2L7me5LDjO eGlgVAOAs531ITPnGXM0MGO9yz0Oib0p ShQ+HQVUzHGSFYj9VCWLodPKuMYm6wPJ gkpzIT3Vd2QkHvMOc4tW07FQMNpNGUsm 369fnbkHcHiwjw/uKoZdPV9XQJvlQNsz xgF99hhth2Ix2zDYFYP6X6D9uIjD4KC1 Mpr6AFEq/Gp/DJt5soQNrO3z3D1qfxBy NoraHiRPzZ5HXh9Zlg7pDw==
+SECTION ADDITIONAL
+rootns. 518400 IN A 198.41.0.4
+rootns. 518400 IN AAAA 2001:503:ba3e::2:30
+rootns. 518400 IN RRSIG A 8 1 518400 20170804000000 20170721000000 37284 . 2SPmEVXrEp4xGnYvrk6r1Mz4NKC5t9E4 nV3NA9fWQRkld7URF4ryKA2y6GxlYHig nY9guQ7diD9jV8oQUL/9d/wcPIzqGvWC Q32LTki3BTwky25kNIByRKiXrSEpNMLt 1eaonaNhb0BFSoZGw4l7A34TJ/3JjM35 1R/F/PdEyrGE1Yme3xb8YgfQQuOS8Ymq 09iWA8zOI9vw403Ksk1t6739Mtc+j7Ht lxGtA+Nb4Y+6jZc2bK3TzGgkmdxfaYYM Zs+rIhS2OFE2tmAsHK/A1VBTuEc4m/OM X6UOWZDPavDmFgYjrfPn/fQ/v1WLgcJu NpI049g5FAKLuzd8qjvKoA==
+rootns. 518400 IN RRSIG AAAA 8 1 518400 20170804000000 20170721000000 37284 . XSyzOTwPB9zTlOCKdDm52NyuSsLoOxTw owOD072MFxbGXautWxnnDUmKGr2+lWe9 hmXtSOQCxDtL1fQGhdPZAqwL9lSoWUEX t5SMJ9muqI7KzPiwXHAcyXJJ3xxh5i60 UD+8EF5pcgwhTtzcrRgKwRizDpA1b3gv 3kWO49DFOh6wkqj1NUfUCSNgvG0nMta1 y52vpElqD81dPdrd6DZ9a5QCdbuyuLSN w0825JVj5GK1chdS8wp7PiPYLCrndAHl Tzm9o4Oejfi7jeszPZFhze/2NsQeADDc tzDD9fVXPI63pM721DbJXZCAsg7ekyW0 BOSUd2xSWgZ9WPP8xDE8yA==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rootns. IN NS
+SECTION AUTHORITY
+. 86400 IN SOA rootns. you.test. 2017071100 1800 900 604800 86400
+rootns. 86400 IN NSEC test. A AAAA RRSIG NSEC
+. 86400 IN RRSIG SOA 8 0 86400 20170804000000 20170721000000 37284 . St+fTzqEpu/Sq4oQwNZY9YaEkD4+Oqgy LFW4JNxYuwM0vMZnhAgMxrHZKI4Vg+I2 +85inalP5mYJm0kEYm7QF4FeRk1xWKWb f8GRIYSo3eWsd4FHlfGtLkLm9MIcopzY 4N6v/tHPVanhT61ppqXPg9A8DyjPrDKp tw/aMyV7ewV8GFpip/YHT5imMChbyfyM Gg74MhqREpO+LpCFeXseH4O+1d4gw2nI ewX7sEnb5CqZlKHf/eas5MpwyUysZ0y+ UPerUDPc7NDo/zZkA032BeqMFXAcwdy8 vN+UANTJHWFLhnPtCHX0Imc6rW9Zlopo TqCrXW25bMLByViigbZwIQ==
+rootns. 86400 IN RRSIG NSEC 8 1 86400 20170804000000 20170721000000 37284 . VkUQMiyde/Q7I4g+cgTWu13y0RT4VWlu Rf+/4CZu+huIDyhpsKNggG0Y7JEqKo9p FHDds//kvFsMQuhRTUvt/Jrnxwig+p1C RwQ9tYbZIkWCI1wOCQ/mjB1F+8iq4uOM OdGh86xtiCaWWDUPkZr5Bi+AQqA9mU3p ksaoI+fWs8rjTNr1SOH9Hp8s+hxBAPJs DRXrAGcpIMbmfr5pPJPtX0D+qDW2m8eA Vopl0YLyMkK7dj1PEV/zGvv222oht//0 mXFVse7ceaI+izSggDsr23CI3tCdAhSO RiEQMa/XeDWv7OLXIy5KEsjgf9DGL1bI SdX2U7DNB0ZdSY9VzUpCRA==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rootns. IN A
+SECTION ANSWER
+rootns. 518400 IN A 198.41.0.4
+rootns. 518400 IN RRSIG A 8 1 518400 20170804000000 20170721000000 37284 . 2SPmEVXrEp4xGnYvrk6r1Mz4NKC5t9E4 nV3NA9fWQRkld7URF4ryKA2y6GxlYHig nY9guQ7diD9jV8oQUL/9d/wcPIzqGvWC Q32LTki3BTwky25kNIByRKiXrSEpNMLt 1eaonaNhb0BFSoZGw4l7A34TJ/3JjM35 1R/F/PdEyrGE1Yme3xb8YgfQQuOS8Ymq 09iWA8zOI9vw403Ksk1t6739Mtc+j7Ht lxGtA+Nb4Y+6jZc2bK3TzGgkmdxfaYYM Zs+rIhS2OFE2tmAsHK/A1VBTuEc4m/OM X6UOWZDPavDmFgYjrfPn/fQ/v1WLgcJu NpI049g5FAKLuzd8qjvKoA==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rootns. IN AAAA
+SECTION ANSWER
+rootns. 518400 IN AAAA 2001:503:ba3e::2:30
+rootns. 518400 IN RRSIG AAAA 8 1 518400 20170804000000 20170721000000 37284 . XSyzOTwPB9zTlOCKdDm52NyuSsLoOxTw owOD072MFxbGXautWxnnDUmKGr2+lWe9 hmXtSOQCxDtL1fQGhdPZAqwL9lSoWUEX t5SMJ9muqI7KzPiwXHAcyXJJ3xxh5i60 UD+8EF5pcgwhTtzcrRgKwRizDpA1b3gv 3kWO49DFOh6wkqj1NUfUCSNgvG0nMta1 y52vpElqD81dPdrd6DZ9a5QCdbuyuLSN w0825JVj5GK1chdS8wp7PiPYLCrndAHl Tzm9o4Oejfi7jeszPZFhze/2NsQeADDc tzDD9fVXPI63pM721DbJXZCAsg7ekyW0 BOSUd2xSWgZ9WPP8xDE8yA==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. 1 IN TXT "it works"
+test. 1 IN RRSIG TXT 8 1 1 20170804000000 20170721000000 37284 . yz3cwQjabEPPuuTjJwVW5ORb/PiJsB/6 2TEvBkpRyLvQUHr6Q6d4HosmIEExmrdq N/iNj6SiZ0upa4SyftzRbyYcoGeAWonV yha4FxCSy7T/0E1FlBNCfrdjCKoMJtOD rmzJmVRA63HbxcSyhYLSB+sN8LBhoLve iQkMJU9iBNV59qvoztgUnPi+Ky5y24vN S4Bg7oCgqWvA4L3JKAvcek3fymPj9/2q E9jPn7i2jtTJmAVH1cNKHX1i5YCVuNK3 oXHD22HJ3wxCumT2c2GWepx71dvrgjGv 5a53iSSOQ9aVzD5JSwf5rSytKPGdb98e Y2jkgCXYTedrm0UctRktNg==
+ENTRY_END
+RANGE_END
+
+
+
+RANGE_BEGIN 20170731000000 20170809999999
+ ADDRESS 198.41.0.4
+ ADDRESS 2001:503:ba3e::2:30
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. IN SOA
+SECTION ANSWER
+. 86400 IN SOA rootns. you.test. 2017071100 1800 900 604800 86400
+. 86400 IN RRSIG SOA 8 0 86400 20170814000000 20170731000000 37284 . xmUjSrpl9mlXOv44w7/rSXtlhoZeVVLU o96YJ2RoSa3OStDW6NrvsC5xG2TW+Ow0 Z+DU2y5G1hGLQkcT6KXbEoGAHBGOXI4M ZmgjLxD6hf5ttlTEZMZY7+y/wXzZnNMZ OJTCYkVht1+uZkI3GWtETmxNvLbNnRQt TSjrp20i692OmUi61utqEBR/wyiZj8Qz iCG4FvSWETf/XrjjuKpD7EWfn30RWnmE iB5Se/FbGtPVsHgPLsEiDLEMMRVjqgGh GGZQg9UVZmyHY+h2iTVryB8DK0IINNDs doIvs2ywFLTC2LhHVTmPvz2p9KFR4RIc 4Ci2Mz09N8D9umQRIekU2w==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. IN DNSKEY
+SECTION ANSWER
+. 1814400 IN DNSKEY 256 3 8 AwEAAe1udmhwaWyg6PD00YReHeT6nYeN hKAy6oKMc7X5NXXJq6baVZT5p3AnFm7B 0ReT1dOpOjZuArydSdASupCQwRPVja+m 8PQSaAdThTifIBbP0Y2TeeA3yfGbHubo scMezJAXr7FGDQ8XIfyUYBDBoDaINi6j V/oI+aSnwm0uWdxHqfonzioTYenuTsax OGLYYuCMn9soxIuXatO53MpqfsJgh7UK FDCDGKA9pFts1vTQdCMPGgEsuYHjsYF0 /kUoRAQJM3jh0t3wE3JQ/HjFIyR37NCM w+i20b1v6/Xo86gy2nhXq2BopawLPEh0 Fv2UCCI7f8k2JvvF2o9udq/N+FE=
+. 1814400 IN DNSKEY 257 3 8 AwEAAcgeCFZiwMD0S6TVgSK3Ob/MKFo+ dHYeNgoOjxH3JoxV09WShBXID/LwKs/e sYAIzTOBB8Fu9IDoVuQe5prOEcGZRp6u zF7JLnqrgOzoaSPRmKsvXh8DfipA56qE AqNwYBCqzlbGIGjHOQ8t+Xonp4fSBYbN MLmh7o8+u55k7PxemKTCiAnY7Bjx0g3m J1HuFvQXDDdvyletuoS3NKqrkjqdOHRB 3p3GKrKgw+zVb05UEyotCEKjqqi+BOmg cm8rmUIeaNQREjxrUyr8/Ry67h5NJLfq LAqAnSePf1PyhQcl8XjGHXN7w1tLLyJu Gy5B3zLSW1P6jIjon77PSn+cXi0=
+. 1814400 IN DNSKEY 257 3 8 AwEAAfX4eSO5BEPXggvx4jL5HkEjbA+5 QD8Acnh4wOHNv/OJX4QhKnpoMDOrpp38 n0Rgcr8qZ0XUqiJWl8eEH//wrQDHoO5/ JHRmibVrcA6UqfhUa25D1BfeMtTgMCSS +W3/heB/YhyXOJtOdWDmJutDY1nfJUSK rF6XwBj4us7U5jvwXwq+l36AeI4q7I87 Std0GNgRdA6/cJtApPoGv/0oNE0iNTyu IBcAR+AeWu32+JavhTycmtMfZ+KOIShq uI9RHzChZ9yLikAT+gclJGLLlxIr6HDr SLChCG90/yvmc57dLn8qhRWRJtJeLT2V HSxeP7oREb6RSdkxET6OTf9GYHE=
+. 1209600 IN RRSIG DNSKEY 8 0 1814400 20170821000000 20170731000000 1867 . Z3qb2ZevT0tfFrjLk+zVHYcEG7uU/lWD DMVZydBTABQqSEzRee/neEeme5MU/V1e D5nrYf6XJVqsj3O781vB/0OYiqbPcxgU m1tqelVDH0NcBSB0UIaADl4TqA72OnNR kBUa9U0pBJ/4e70rubuxieO6WuyPRzti UGaydhR8CREMr+r8FAItdjJWPFukIvrt ju+brh6xZKl5Xuxw/dklaZp+Dd6u2jRW 9tH79rh5N8rTdHdxHjn3JQs02wzx4iD4 OHd70QOW6avgvg2x2RnzS4Q7n1iU8hcR aYgvk0+FToMFlxhFW82M3xRDCjTrktF+ bUKyxz/frYKuS17pxRS1gw==
+. 1209600 IN RRSIG DNSKEY 8 0 1814400 20170821000000 20170731000000 37284 . gF++btbXlsLxe02aeytRLug6tJN994B/ F9LigfvZGjC/GE47VIlUmS8qgPWA4Sqd yUHiforLg5aMLO/CMe5WxqmEzSoU03Ka +PXW2R+q5k6tsTuowVDvM6W8P72f4epk XwEK27dmVJXeTbYVoREV186Sk0fowavm Hqdo8AX2XXB09pkBto8kgjH9otXnB3jA 2BRZKNicP3wJoH6S9Oy+nRSzyWRyBDjX Apv2h+quzWBNYux1GePJol5V/wem176Q kHUolQtCcRB4XIJG0BOHm+6P5nHRZ7iU JqsQJJ5PnnzH4sBO1ZBSJgDCzvIb1bLb Ixd3VGg3ZrEjrWda/OR8ww==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. 518400 IN NS rootns.
+. 518400 IN RRSIG NS 8 0 518400 20170814000000 20170731000000 37284 . tGGr2W4HHWtFIdziLL0066dn1UKLSfv0 L0l8OyvX9fDPUNgKtVRMo91kNMm2Mp7o /pHiEDL8ZxxGsm1WKBmANjIQ2BBKzb0S TXmRrMmeuGtMiI+8PGQ4ZnlU32PtePyC /6WNh1+5PIg6cPkMJPx0+h7Mj7mdtKDi We2Ha56Fm9lMuEo+igAmO4rKLSrkjqVS QH1xwTwie+KPBHTK7rIannW96KYfzAEI ybN+CGTCgPawXuYxKcmiq2ZmNSoU4bJp YkZdVoFPr4btnO1Ai1Mh2QhcPlnDuN0M OWNzlJ7DaObEK7oCHMkb5tvBNTu9CsGO SZvGA603Md2D0YZfRKpQ1Q==
+SECTION ADDITIONAL
+rootns. 518400 IN A 198.41.0.4
+rootns. 518400 IN AAAA 2001:503:ba3e::2:30
+rootns. 518400 IN RRSIG A 8 1 518400 20170814000000 20170731000000 37284 . ykmbNQ7VSbpkumK9V7pECrxiws53YIKM O+OaKde/OHaQCVPIXgbVf3fc+Rk5e630 zHxZdwwpOcVJKr9RSCLylRnZY6ocDySy 10qeqVV7QCgwYN60/68DAPz2WjIQWGN4 UH8mtr+KyCa0Fj8SOzhPf9VBZ4u5w+1z lOLhWqc+lmelm8VjgWbyo6dn+/IokwKU Ks37sTh3sa+qk9zREwv0Ut6YEo//DOcT WdXxt1+MvmM0jssuWaCGqHiEQZlnVmJ5 7puQIiPUCj+YMEbX+rZB5CnP4eA14FD3 /L/Nq8cwb+0+yd0BjNS5bHfE1eIQawbL e7LrztJSYeNvS9TIZzRKww==
+rootns. 518400 IN RRSIG AAAA 8 1 518400 20170814000000 20170731000000 37284 . PY5wleVbShlse11/pOPJMYiFBsNnWfE1 dUcPrAnLEZE7fTF5uFF/mAdkfLLIMG0Z mx4d63ilbMWJXBwmSk5nDsaDxbYLjqGW 7kitDATwiNUKtP3MXZ3jPl7qIq4GjlHn Hm4sRdsuo5OXO28mHCBhKVUCgjK9+Tg1 nxPqhc0V7momil5Tpl6I/h+gX6saMOsb 2wgcVV0wHwI2dOztgNOpqgQda3VqHVRd LN+sq1k1bDeZt4YdIonPwhPY45tZ44VH VPpjbJcyhJSzvQte6gCrARK9/MUx/1sJ bdP1o+cXJxzOn7TgfETYUS9QCP+7pbpL 55s1uno8nV88D5dMAuCI2Q==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rootns. IN NS
+SECTION AUTHORITY
+. 86400 IN SOA rootns. you.test. 2017071100 1800 900 604800 86400
+rootns. 86400 IN NSEC test. A AAAA RRSIG NSEC
+. 86400 IN RRSIG SOA 8 0 86400 20170814000000 20170731000000 37284 . xmUjSrpl9mlXOv44w7/rSXtlhoZeVVLU o96YJ2RoSa3OStDW6NrvsC5xG2TW+Ow0 Z+DU2y5G1hGLQkcT6KXbEoGAHBGOXI4M ZmgjLxD6hf5ttlTEZMZY7+y/wXzZnNMZ OJTCYkVht1+uZkI3GWtETmxNvLbNnRQt TSjrp20i692OmUi61utqEBR/wyiZj8Qz iCG4FvSWETf/XrjjuKpD7EWfn30RWnmE iB5Se/FbGtPVsHgPLsEiDLEMMRVjqgGh GGZQg9UVZmyHY+h2iTVryB8DK0IINNDs doIvs2ywFLTC2LhHVTmPvz2p9KFR4RIc 4Ci2Mz09N8D9umQRIekU2w==
+rootns. 86400 IN RRSIG NSEC 8 1 86400 20170814000000 20170731000000 37284 . hKhEcL2qwpjPZNsyTLnqTytfuTgEyHeN k3N+xhhy8nFWu1CiQLcdrsSUlG58h4I0 eFQw7bwZR6anymWx3nJGQe1UnH0ugbcd UlP2JstzqYuMa4+mpaA5IMzKe8vflEYl nas1j2I3tq59qXnRq+/XLAE22Lm2IDY6 Np/3E9zRT8plr+baWcY/E7E1xJcyDY+v id7gXwQa3EQxvOIKj0Q17xyJ2g1t/7SY vvJUDmEHZ/OKknqgdzwskAzUreld41qm LILE3TH8bfWGC25JSKxR9qU7c6sU0oGs 6pR7//IpTWRUH+tskFVmY8Jfx/ot11+H +mPqViBvNhXl2l20HJ635Q==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rootns. IN A
+SECTION ANSWER
+rootns. 518400 IN A 198.41.0.4
+rootns. 518400 IN RRSIG A 8 1 518400 20170814000000 20170731000000 37284 . ykmbNQ7VSbpkumK9V7pECrxiws53YIKM O+OaKde/OHaQCVPIXgbVf3fc+Rk5e630 zHxZdwwpOcVJKr9RSCLylRnZY6ocDySy 10qeqVV7QCgwYN60/68DAPz2WjIQWGN4 UH8mtr+KyCa0Fj8SOzhPf9VBZ4u5w+1z lOLhWqc+lmelm8VjgWbyo6dn+/IokwKU Ks37sTh3sa+qk9zREwv0Ut6YEo//DOcT WdXxt1+MvmM0jssuWaCGqHiEQZlnVmJ5 7puQIiPUCj+YMEbX+rZB5CnP4eA14FD3 /L/Nq8cwb+0+yd0BjNS5bHfE1eIQawbL e7LrztJSYeNvS9TIZzRKww==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rootns. IN AAAA
+SECTION ANSWER
+rootns. 518400 IN AAAA 2001:503:ba3e::2:30
+rootns. 518400 IN RRSIG AAAA 8 1 518400 20170814000000 20170731000000 37284 . PY5wleVbShlse11/pOPJMYiFBsNnWfE1 dUcPrAnLEZE7fTF5uFF/mAdkfLLIMG0Z mx4d63ilbMWJXBwmSk5nDsaDxbYLjqGW 7kitDATwiNUKtP3MXZ3jPl7qIq4GjlHn Hm4sRdsuo5OXO28mHCBhKVUCgjK9+Tg1 nxPqhc0V7momil5Tpl6I/h+gX6saMOsb 2wgcVV0wHwI2dOztgNOpqgQda3VqHVRd LN+sq1k1bDeZt4YdIonPwhPY45tZ44VH VPpjbJcyhJSzvQte6gCrARK9/MUx/1sJ bdP1o+cXJxzOn7TgfETYUS9QCP+7pbpL 55s1uno8nV88D5dMAuCI2Q==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. 1 IN TXT "it works"
+test. 1 IN RRSIG TXT 8 1 1 20170814000000 20170731000000 37284 . y+EKJ2utPXopOSD29GZvwZOAx7ICHszl ia8LbeT6jAUF9oTVm0YKC30VQULQfskc oWwPssD9ZsGLUi/8GOsE4cropD5lk/AD Df021TAv/tgQTvIvNggpu4u4fpOopxz4 1E9P/rf7nROayVTo2dsgIg+zabkhb96i yIr/nhoxkvEYFcYTucfZTlVhOwjYGqvr FE/Ro4Gl4axf5FN+CK8CNebd43Ep3yJ/ 3UvecFYMofMEytguBLNsHFIrOtKGLQfr YfttDOl9Dr2h9txDAVXIWrdvYEuLnYR9 I7vBBfgBMwkyDfhmG90xFt51E8KSDcgQ lDMMiPrnLTBjIa3d21Bt6w==
+ENTRY_END
+RANGE_END
+
+
+
+RANGE_BEGIN 20170810000000 20170819999999
+ ADDRESS 198.41.0.4
+ ADDRESS 2001:503:ba3e::2:30
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. IN SOA
+SECTION ANSWER
+. 86400 IN SOA rootns. you.test. 2017071100 1800 900 604800 86400
+. 86400 IN RRSIG SOA 8 0 86400 20170824000000 20170810000000 37284 . E3PCc79NFLHFfnf2+WYF1PvcIPYEF7cf CghVd0wWcP5B1Bh+vEdo6gsJaYD9/QtM q68IW4bPm49dI0zRvkRGG4NjE8zU8bO2 wGf3Ky61F4Xm1fwq9TYYCT29ofkm0NpE 12fP5P/ahA6K7cw7BfDPjLPhlqw+/iwO IlEKWbeg6CT33eMBfhQC1B/47bLon/AU 4AAd+sy50sMhkTeId7Zy5BAHg6V09Qg/ FV8PlgiSUgmSiEa22gITJOEu2LtRYPFe cJHEGZAtKAt30sQ0o5dR6m48mWdOo/4B GFoC1HfrpsCyGtpi9Ab3jFjwtpGFqu7X wzQS8OlqBPFYA33OJq4f+A==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. IN DNSKEY
+SECTION ANSWER
+. 1814400 IN DNSKEY 256 3 8 AwEAAe1udmhwaWyg6PD00YReHeT6nYeN hKAy6oKMc7X5NXXJq6baVZT5p3AnFm7B 0ReT1dOpOjZuArydSdASupCQwRPVja+m 8PQSaAdThTifIBbP0Y2TeeA3yfGbHubo scMezJAXr7FGDQ8XIfyUYBDBoDaINi6j V/oI+aSnwm0uWdxHqfonzioTYenuTsax OGLYYuCMn9soxIuXatO53MpqfsJgh7UK FDCDGKA9pFts1vTQdCMPGgEsuYHjsYF0 /kUoRAQJM3jh0t3wE3JQ/HjFIyR37NCM w+i20b1v6/Xo86gy2nhXq2BopawLPEh0 Fv2UCCI7f8k2JvvF2o9udq/N+FE=
+. 1814400 IN DNSKEY 257 3 8 AwEAAcgeCFZiwMD0S6TVgSK3Ob/MKFo+ dHYeNgoOjxH3JoxV09WShBXID/LwKs/e sYAIzTOBB8Fu9IDoVuQe5prOEcGZRp6u zF7JLnqrgOzoaSPRmKsvXh8DfipA56qE AqNwYBCqzlbGIGjHOQ8t+Xonp4fSBYbN MLmh7o8+u55k7PxemKTCiAnY7Bjx0g3m J1HuFvQXDDdvyletuoS3NKqrkjqdOHRB 3p3GKrKgw+zVb05UEyotCEKjqqi+BOmg cm8rmUIeaNQREjxrUyr8/Ry67h5NJLfq LAqAnSePf1PyhQcl8XjGHXN7w1tLLyJu Gy5B3zLSW1P6jIjon77PSn+cXi0=
+. 1814400 IN DNSKEY 257 3 8 AwEAAfX4eSO5BEPXggvx4jL5HkEjbA+5 QD8Acnh4wOHNv/OJX4QhKnpoMDOrpp38 n0Rgcr8qZ0XUqiJWl8eEH//wrQDHoO5/ JHRmibVrcA6UqfhUa25D1BfeMtTgMCSS +W3/heB/YhyXOJtOdWDmJutDY1nfJUSK rF6XwBj4us7U5jvwXwq+l36AeI4q7I87 Std0GNgRdA6/cJtApPoGv/0oNE0iNTyu IBcAR+AeWu32+JavhTycmtMfZ+KOIShq uI9RHzChZ9yLikAT+gclJGLLlxIr6HDr SLChCG90/yvmc57dLn8qhRWRJtJeLT2V HSxeP7oREb6RSdkxET6OTf9GYHE=
+. 1209600 IN RRSIG DNSKEY 8 0 1814400 20170831000000 20170810000000 1867 . NvCmbFb31NahFemdIPwno85Uzjwj3QbB bdo1NsGTIMU9IODLqRDBR/6i5XFoqOWE +SS0W8urCtb+dwg8Z0iJD3isVGOzDtnG tjoZq19S3E6UU28MehpOh9u6dJoZqlSr 0jvinZsVSKtd784O4IHBFDLhaMtGsTab PIEc/jY3XeHSQu3a0O1SWZaYy9/tn89v mWdHsYNmyR1EC6JhXf5pb3yPjgHhUg9v 5tS7poOWpYJMkLqNfIWKyciCLpc7IW/g kvuE+GI89qBVfFBQmhyKINHHIouwexqC qdTqrEL2VKPyqsiWjJ2jT9JZW/K2zvgH /WoCneDpHokp04wS1dQwpg==
+. 1209600 IN RRSIG DNSKEY 8 0 1814400 20170831000000 20170810000000 37284 . Igc1ImQmud5Oj4KrdnY6fFBJKK5T7DF0 lULf/IsYtNruJUmP9h/5JNaqZTfhCrbH SOFwlm01qeuZb39X91FMZbCegRowGL+n 3DTzwl6w6USRd4MhVVtTJjvP4+lB8rwm Xkw0k1sWK3RqnJ9vmINhKu/HHxLGG+qT VgjtMJ27DmIum6IPt53c8waqbVnbNzL4 LThPEEEzt1gMv+FKmMlIQw6GbdFrYatD JfXAu0+B9UhgZtkPzjq5sMgvkmKonmHp qXuuRnbzxehv+Wq09cBQwu9xHfnJxGHy i1vsVGIxPttLwYhGxnOvzOJEylmlOCLP 3PCXFuu3B5l6b5LFM7ssxg==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. 518400 IN NS rootns.
+. 518400 IN RRSIG NS 8 0 518400 20170824000000 20170810000000 37284 . LmgEtpDF4tZPcrrnqdFJHNay9PUwVupw xLjeDIZyzX1LTtrbHfiAS/luCAvHcZGh h9WJkxfulM5nthpxWFu/qEiBljjBXTKr YUAoCnV05VLjBjjrV473O197CwPCMWzh RE4v0Z+0nenW+zi4ckTT66h88UjGzq65 uHnjmp2X+0M7R+SHY3JhYalFo4Lo9PrW 26gnbDTvNRbV+XMLD0YS3YWIZdMRaEWG 23f39ZrCZF1P8AP7pbsfRjchQJz6ApIl KWj9Uyl9oXL434ClQGArKnXrX3eMVnKl 0I4uVUK4ILF9oz/ckxBPPzJRl+fqrleF 2YeB810tgu9qNWkQRcsczQ==
+SECTION ADDITIONAL
+rootns. 518400 IN A 198.41.0.4
+rootns. 518400 IN AAAA 2001:503:ba3e::2:30
+rootns. 518400 IN RRSIG A 8 1 518400 20170824000000 20170810000000 37284 . WjEAJUBZwFd9q4mq2n4hTf8itP5EjcZe 8LmggAJ/eUlHzram+owSwIo5IoYeEdNU y9b0yyXwQWa0DZH7zALKiSi9gW/Bglft Ejfdw8u+XXHgCcI17naRdEawVIWaQCuk Hnn4Rp8aapfQRSqcxCPa42W5BDy8cEXe rhi3yGr6tyAsrya+8ZrIM9U5c1+1fXvR G+wWQ8q4TP1SsuG3G55pSbY+N8VMa96c IhM9PlmZ8H1OtMokvKPYL6tZi3DQfN+f PJbT7ej7OcfogbhoYkRAWibgMM7R/dee M9zIEhBJlaU4KmuFthu++Fe2Tbj6Sp5r ooTLb65UnkoWbGOYhgSamg==
+rootns. 518400 IN RRSIG AAAA 8 1 518400 20170824000000 20170810000000 37284 . ypCP7WbleHUNZI9xB+3weFFWqM2Ery6f +bic9OtSyFjAkTmAb4z2B737fAhEALNe CFr5NgEvG+9aRrETUac+vs7ljA6jj/gQ PgVE8cE4bXXl3sWnwzgSrG3HUyxYFNJm n16Joj9RA84ldgsxsZ5mDML1uH2GtyZe AvIqsCdtIKI/WD6QnqUQyCPibYyXbGLf NNh0K8wosKKrA/hx2y4oIHEXEwf0yA0f PzQQtn6/bHEzWYpvzkl3HT7gYxSBmH0h v0av1Q4MUjhnUBNwayYAmeXd0xfKV7DN yGqr2pzLuziC0RkLBiC85qt/14kN90ZH +aKeSeeRxx6YaGU1T1IVcg==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rootns. IN NS
+SECTION AUTHORITY
+. 86400 IN SOA rootns. you.test. 2017071100 1800 900 604800 86400
+rootns. 86400 IN NSEC test. A AAAA RRSIG NSEC
+. 86400 IN RRSIG SOA 8 0 86400 20170824000000 20170810000000 37284 . E3PCc79NFLHFfnf2+WYF1PvcIPYEF7cf CghVd0wWcP5B1Bh+vEdo6gsJaYD9/QtM q68IW4bPm49dI0zRvkRGG4NjE8zU8bO2 wGf3Ky61F4Xm1fwq9TYYCT29ofkm0NpE 12fP5P/ahA6K7cw7BfDPjLPhlqw+/iwO IlEKWbeg6CT33eMBfhQC1B/47bLon/AU 4AAd+sy50sMhkTeId7Zy5BAHg6V09Qg/ FV8PlgiSUgmSiEa22gITJOEu2LtRYPFe cJHEGZAtKAt30sQ0o5dR6m48mWdOo/4B GFoC1HfrpsCyGtpi9Ab3jFjwtpGFqu7X wzQS8OlqBPFYA33OJq4f+A==
+rootns. 86400 IN RRSIG NSEC 8 1 86400 20170824000000 20170810000000 37284 . ut9CvNq5yKmhwZXGInuB6eVW8FPmKixM Lr9Vi4wbLo42Qr+nGNlhAKuDM160tZ9V 2D38DskRYwucSZ06UWb5zuuQ+LEMr7np Q2J8Ydt/ecXLsIvLYs45S5W8ovJmTnss qkU0fZIb9ySwdWW2rYqE9Hy1PadKS53m zFyqIA7OtsHcear83X1P4Jwzp/s1PA+N fiNePt+UoyRJXCgLJjNAI4Ay5T0HMD4n 00S6aQS7VmKWsJmQ7Uzyd/Q79pLo5mIQ MAQjowlcYSMcOen4JFKeQyiEEDfq0/Kp yvEP//mVgnzANm1QqALHwJuuHKRvg4Sw 3En8feCAesJLjx86GMelxg==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rootns. IN A
+SECTION ANSWER
+rootns. 518400 IN A 198.41.0.4
+rootns. 518400 IN RRSIG A 8 1 518400 20170824000000 20170810000000 37284 . WjEAJUBZwFd9q4mq2n4hTf8itP5EjcZe 8LmggAJ/eUlHzram+owSwIo5IoYeEdNU y9b0yyXwQWa0DZH7zALKiSi9gW/Bglft Ejfdw8u+XXHgCcI17naRdEawVIWaQCuk Hnn4Rp8aapfQRSqcxCPa42W5BDy8cEXe rhi3yGr6tyAsrya+8ZrIM9U5c1+1fXvR G+wWQ8q4TP1SsuG3G55pSbY+N8VMa96c IhM9PlmZ8H1OtMokvKPYL6tZi3DQfN+f PJbT7ej7OcfogbhoYkRAWibgMM7R/dee M9zIEhBJlaU4KmuFthu++Fe2Tbj6Sp5r ooTLb65UnkoWbGOYhgSamg==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rootns. IN AAAA
+SECTION ANSWER
+rootns. 518400 IN AAAA 2001:503:ba3e::2:30
+rootns. 518400 IN RRSIG AAAA 8 1 518400 20170824000000 20170810000000 37284 . ypCP7WbleHUNZI9xB+3weFFWqM2Ery6f +bic9OtSyFjAkTmAb4z2B737fAhEALNe CFr5NgEvG+9aRrETUac+vs7ljA6jj/gQ PgVE8cE4bXXl3sWnwzgSrG3HUyxYFNJm n16Joj9RA84ldgsxsZ5mDML1uH2GtyZe AvIqsCdtIKI/WD6QnqUQyCPibYyXbGLf NNh0K8wosKKrA/hx2y4oIHEXEwf0yA0f PzQQtn6/bHEzWYpvzkl3HT7gYxSBmH0h v0av1Q4MUjhnUBNwayYAmeXd0xfKV7DN yGqr2pzLuziC0RkLBiC85qt/14kN90ZH +aKeSeeRxx6YaGU1T1IVcg==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. 1 IN TXT "it works"
+test. 1 IN RRSIG TXT 8 1 1 20170824000000 20170810000000 37284 . KdU8rLyDvoUejIT/W0O/jldfOdQQgEbj lNkK5OzdqgGCa5ohaOB+7EDk4+ycrClP NzOYc9+W7wR7il0eCzAqabxzm6NBHCJ1 Q7Oci1TQXnx7q3Y2IXKycCk+95qAMEMB h9OmmMLJNc5wGGgxh+4ARR//bIw2sv/L gABeXIQ2T1Iug06r/lBBP+4sTdMOAgTE Y+uLPF4K8iK4JIKZWTPmPlEgrzPiqEFf znjSCXavIyWgsHjFNqrAnGHcdVbz7GNP vVwBfcjjhwBWm1LIY68yQtIBWlUyXUgS 3ieegfiz4GET13SXEM6SZIDPrstJ2qhx Zeu4NlBA0zgspOtCwJzO4Q==
+ENTRY_END
+RANGE_END
+
+
+
+RANGE_BEGIN 20170820000000 20170829999999
+ ADDRESS 198.41.0.4
+ ADDRESS 2001:503:ba3e::2:30
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. IN SOA
+SECTION ANSWER
+. 86400 IN SOA rootns. you.test. 2017071100 1800 900 604800 86400
+. 86400 IN RRSIG SOA 8 0 86400 20170903000000 20170820000000 37284 . VwR/AJaqwjI1aDnB0x0KyuUZW/AA0RkD XRHFiyLWs3z5rYSMHVietUAoS1gEqd1+ UHhfwzhdKNwtINfqBQEvALqD/Dl0p0Zb XrwMvf2gk8Cdotgh6vbDwafcySr5/xyv ryy4S+6tVm4APLejzBN7Qsnpi9FusNvE 9Y+d9yKHnHTLTpAihKEbokcsACu4Jwo1 QAJk5LxlM6a72iUlg/Ce/hYUxZrbyt+n QtZhP5sK4cX5v7GeblV9BWsA2JGRQ/IX oGY6T9BqjNi7CA4oxIaurbdrOuAXv9Bq t6vmue/PaIN+eEaqCvHMn2wj5+bgJ5T+ dMSMxgpbg/kIE5n3qYv/nQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. IN DNSKEY
+SECTION ANSWER
+. 1814400 IN DNSKEY 256 3 8 AwEAAe1udmhwaWyg6PD00YReHeT6nYeN hKAy6oKMc7X5NXXJq6baVZT5p3AnFm7B 0ReT1dOpOjZuArydSdASupCQwRPVja+m 8PQSaAdThTifIBbP0Y2TeeA3yfGbHubo scMezJAXr7FGDQ8XIfyUYBDBoDaINi6j V/oI+aSnwm0uWdxHqfonzioTYenuTsax OGLYYuCMn9soxIuXatO53MpqfsJgh7UK FDCDGKA9pFts1vTQdCMPGgEsuYHjsYF0 /kUoRAQJM3jh0t3wE3JQ/HjFIyR37NCM w+i20b1v6/Xo86gy2nhXq2BopawLPEh0 Fv2UCCI7f8k2JvvF2o9udq/N+FE=
+. 1814400 IN DNSKEY 257 3 8 AwEAAcgeCFZiwMD0S6TVgSK3Ob/MKFo+ dHYeNgoOjxH3JoxV09WShBXID/LwKs/e sYAIzTOBB8Fu9IDoVuQe5prOEcGZRp6u zF7JLnqrgOzoaSPRmKsvXh8DfipA56qE AqNwYBCqzlbGIGjHOQ8t+Xonp4fSBYbN MLmh7o8+u55k7PxemKTCiAnY7Bjx0g3m J1HuFvQXDDdvyletuoS3NKqrkjqdOHRB 3p3GKrKgw+zVb05UEyotCEKjqqi+BOmg cm8rmUIeaNQREjxrUyr8/Ry67h5NJLfq LAqAnSePf1PyhQcl8XjGHXN7w1tLLyJu Gy5B3zLSW1P6jIjon77PSn+cXi0=
+. 1814400 IN DNSKEY 257 3 8 AwEAAfX4eSO5BEPXggvx4jL5HkEjbA+5 QD8Acnh4wOHNv/OJX4QhKnpoMDOrpp38 n0Rgcr8qZ0XUqiJWl8eEH//wrQDHoO5/ JHRmibVrcA6UqfhUa25D1BfeMtTgMCSS +W3/heB/YhyXOJtOdWDmJutDY1nfJUSK rF6XwBj4us7U5jvwXwq+l36AeI4q7I87 Std0GNgRdA6/cJtApPoGv/0oNE0iNTyu IBcAR+AeWu32+JavhTycmtMfZ+KOIShq uI9RHzChZ9yLikAT+gclJGLLlxIr6HDr SLChCG90/yvmc57dLn8qhRWRJtJeLT2V HSxeP7oREb6RSdkxET6OTf9GYHE=
+. 1209600 IN RRSIG DNSKEY 8 0 1814400 20170910000000 20170820000000 1867 . BX86vECnGwrEZUK/uEaActkHGytrF6G1 2bgGFiWWBjpf3pqaPodMP3P4n2vvYejg bSoHf0SIlV9no1iYMZWZon3uTZcgjbuD UYppPBhcT2O3dlv0EF8Wwmp7NEEp0HN+ 6GRyK50kGlRbQpkmrLSIlMkPiev0kAYd wzt9OzIxMfGrAPiOLgF561rIYZC0mJi2 MkvDJyr+D0cUE7jOWFchMqUxHjal+jY0 aWcM53Kf7XBi/58dzct/rp8m7bedgKtF 8mCNCeKPMpsjtRbFsiehjl8oF/EKvLCI PSie9a4D7N/eRAuIqIpcjWz2ncPlyKT4 2ueX6/NjJaBVEFSuORWdNQ==
+. 1209600 IN RRSIG DNSKEY 8 0 1814400 20170910000000 20170820000000 37284 . Z+qzNq341hMzghshwHURDxy96C0zSup+ f5Wa2p0OVlvfmQvxhGPLi0cMAVUib8IP PM9oAfK7C5/Gj0hZnVjoEnc2psZu4GdN GKc0c3SybJoY1l3gDM1llRMctdorllVx vE2WZJh2PSlA+9kW7s3QWMCsAjddyQUf dsz4C9cNY9hb+dSQAcLeodwvbWSANvBV wiP0+qSdNuT0Fbqbz/dvJOHVBVUDLaHD tVcI+q3Lw0GzzvAZuV9eMGizCW6XJ6Ed JSsfTAkuZ325wiLz2GDTAB1QP8i5IEFN 0GqmuNj8n7U1loqNNd+Dj+bsSb9g7k6e JjPE9N7UP17eu/R1zXfu+w==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. 518400 IN NS rootns.
+. 518400 IN RRSIG NS 8 0 518400 20170903000000 20170820000000 37284 . UowTPtGOKWyFFHehAXDf8r89LasrvoSx MXuWBpk6/zvXBLJQiNTKLpkVEe6yPqtj B4sdI3BvvP1Vi1Kk/oXUgmsQVC+fhlFI 0lLXDoXcjzCI3IEju+l9YyzAqSfhtzIY i0an070u8WUtyN6onlislSlM1uGi3mrQ rq2Rca5atwEop1cAo1Merl0Ll9yI4vVp FR4YbMaj0JI/cixrFZ5n5srDhq9s9h4F n7h4thWvyA5SujXPW1bPHEtOW7hx5hl3 Zi3xmRQAuzzsKsj5ID+t6JVtTcm6u064 kSrvWOwWHYsEHCmuZ/p4TyNnDtjFnVE5 DOedv3vxR8GUUCf1IfQ4+Q==
+SECTION ADDITIONAL
+rootns. 518400 IN A 198.41.0.4
+rootns. 518400 IN AAAA 2001:503:ba3e::2:30
+rootns. 518400 IN RRSIG A 8 1 518400 20170903000000 20170820000000 37284 . WiRICxAPQ1iK7B5hPT8TEK6PMhZauoFj qtw8sR922TGye2CPMgBWGAmqF1wjnJAH SWYgz1r6vx+QcI/HGwVxbnfjVUq8JmZx EFxbChlcDOxqv2YdLud0wkDlrP/nTwjF CNcY+OkqMDtUg/3LUcbJfGFO2b5vhCDS w+ETff6ZZS4wg7Joy86xojcRb6hWhDFm ei075+N06io2T+RX9YH7LNPXfPpC3OaH cn/4neNoxDe05YkqubB4pjLQanrIF64z 9fqPxDp2T+Ln0TDezMRR+dKBOK+c1VIm mfRMEeEHk6tmH72outgEDVUXxV9stjN3 /YfLs7kv3KRaqYLe8D3hvw==
+rootns. 518400 IN RRSIG AAAA 8 1 518400 20170903000000 20170820000000 37284 . TQthucelRM5g+wAyl7sbwXfHZLZsozys ppIkTZV4mrbprZfqPxP8Jks7Be/Zcvy5 nftAOwD+RXOA6K16qTR6V76zpuBnfUEs emufRjCmbb41GOTBFcn00zp13u0q+x7T VEBMeM/1AwJR85cArTU1f0GZhLCYxino 9U6n9RlKy0b60tduK42z6B7px9wok35U 5MmkXop6NVxM0LR97ox6EAPOzUZZkUgC D20mx9gwhu7szDIMY2jgjWg7V+QDOaoB /JYncYAdy4O6sPGtL88vj6l3A25mvAe3 86c2SZmmiYBc20Fg6sq9qbH9XH1GFK/M iJrNX4FT6+fn2XAIcWOj+g==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rootns. IN NS
+SECTION AUTHORITY
+. 86400 IN SOA rootns. you.test. 2017071100 1800 900 604800 86400
+rootns. 86400 IN NSEC test. A AAAA RRSIG NSEC
+. 86400 IN RRSIG SOA 8 0 86400 20170903000000 20170820000000 37284 . VwR/AJaqwjI1aDnB0x0KyuUZW/AA0RkD XRHFiyLWs3z5rYSMHVietUAoS1gEqd1+ UHhfwzhdKNwtINfqBQEvALqD/Dl0p0Zb XrwMvf2gk8Cdotgh6vbDwafcySr5/xyv ryy4S+6tVm4APLejzBN7Qsnpi9FusNvE 9Y+d9yKHnHTLTpAihKEbokcsACu4Jwo1 QAJk5LxlM6a72iUlg/Ce/hYUxZrbyt+n QtZhP5sK4cX5v7GeblV9BWsA2JGRQ/IX oGY6T9BqjNi7CA4oxIaurbdrOuAXv9Bq t6vmue/PaIN+eEaqCvHMn2wj5+bgJ5T+ dMSMxgpbg/kIE5n3qYv/nQ==
+rootns. 86400 IN RRSIG NSEC 8 1 86400 20170903000000 20170820000000 37284 . tQAEQyOmVLpxqHu2JCh18vsX6dy5B8a2 KfuwvoIBtTTSqZkJb7X0nHukqnKMnKR9 /IIfgyH8gi5gMJcaDAxqNzwiZWndstJF z/d7VfXUdIKDu5mIxDlylVNO6OOYRe9R RkZ256e4i4IoWsyYS8temy58+j4/+ohV PTIZe0rPmhgH7YEBioWnUd4HKbeQnMnO qwICbPWzlPiNTNH74DOYQS8hF41FDkDl /c7zjjwWaNHYLGFOSQR7aeg0uQajZk2V 3jVmv0wTLlivF3Z3T+Yl4OLuW4jm0e12 rsYX6kwdEZ49PQWOaMd5eyR5MWBbFja5 tHuZ6czAV5NzBD4NY17z2Q==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rootns. IN A
+SECTION ANSWER
+rootns. 518400 IN A 198.41.0.4
+rootns. 518400 IN RRSIG A 8 1 518400 20170903000000 20170820000000 37284 . WiRICxAPQ1iK7B5hPT8TEK6PMhZauoFj qtw8sR922TGye2CPMgBWGAmqF1wjnJAH SWYgz1r6vx+QcI/HGwVxbnfjVUq8JmZx EFxbChlcDOxqv2YdLud0wkDlrP/nTwjF CNcY+OkqMDtUg/3LUcbJfGFO2b5vhCDS w+ETff6ZZS4wg7Joy86xojcRb6hWhDFm ei075+N06io2T+RX9YH7LNPXfPpC3OaH cn/4neNoxDe05YkqubB4pjLQanrIF64z 9fqPxDp2T+Ln0TDezMRR+dKBOK+c1VIm mfRMEeEHk6tmH72outgEDVUXxV9stjN3 /YfLs7kv3KRaqYLe8D3hvw==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rootns. IN AAAA
+SECTION ANSWER
+rootns. 518400 IN AAAA 2001:503:ba3e::2:30
+rootns. 518400 IN RRSIG AAAA 8 1 518400 20170903000000 20170820000000 37284 . TQthucelRM5g+wAyl7sbwXfHZLZsozys ppIkTZV4mrbprZfqPxP8Jks7Be/Zcvy5 nftAOwD+RXOA6K16qTR6V76zpuBnfUEs emufRjCmbb41GOTBFcn00zp13u0q+x7T VEBMeM/1AwJR85cArTU1f0GZhLCYxino 9U6n9RlKy0b60tduK42z6B7px9wok35U 5MmkXop6NVxM0LR97ox6EAPOzUZZkUgC D20mx9gwhu7szDIMY2jgjWg7V+QDOaoB /JYncYAdy4O6sPGtL88vj6l3A25mvAe3 86c2SZmmiYBc20Fg6sq9qbH9XH1GFK/M iJrNX4FT6+fn2XAIcWOj+g==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. 1 IN TXT "it works"
+test. 1 IN RRSIG TXT 8 1 1 20170903000000 20170820000000 37284 . IdGsiFPBibUlbjGQcsm0y6HzVk1bpKhe odSvmA3r8si+1AkAzyGbLC7Cd1gmQJfO pMLQ7AHZFcQptp07oexFqqCI9HPVoj1M ItMZK9eFUPiZKM1pXnUuuxremUQuOPnJ NMfECR2qicVkd+K+383gd0I+qyfeyVkl VbdZzGe+2sPRkj+9h7rvWAPU77JMb6To dS0TJhWb/kH7k7+DXXcT0315IqnjKn71 2xoNN8rb2afYdgV0kMXUvQCd9JqtsIBT RnjrB8Vru32jc4TyKCrm6YT3kZb2MzWn hMLEkZfi+OBiOeVpULqkliLUH1os1pH7 u/Kdsizxl1GdpzuVv2TC0g==
+ENTRY_END
+RANGE_END
+
+
+
+RANGE_BEGIN 20170830000000 20170908999999
+ ADDRESS 198.41.0.4
+ ADDRESS 2001:503:ba3e::2:30
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. IN SOA
+SECTION ANSWER
+. 86400 IN SOA rootns. you.test. 2017071100 1800 900 604800 86400
+. 86400 IN RRSIG SOA 8 0 86400 20170913000000 20170830000000 37284 . hGcp4EeAF4ETIwVvhdM47CKT7ePfuiI1 l/bEWXwsYfd0XHUgORkdfPouInN40vIj VXtO/rE8HU6FvfisBTcC23GCH3sMFDYT HEcEDXAR9FczdXtDIPXYnRL/TUCIo/f8 /3iNis/QUO4LRedG+dgSclYhvOQqIcbZ I0crF/JugXrrckXhkM3JQhjbK3DSMy5/ srY63HkAKV42kVLJPTcTeZ6Jse4wej1U t46mqkB+YfjM9Cnkc/UjGFgaaq5+XPIz UIZ7oLBbdtfTR4hMCGpAjLtpxqICdvbE 6pKGxqPBGtBYDkupWzZV08X4Lmr1bdwf CCgAIqCwy0xiBbk/zG/Ufw==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. IN DNSKEY
+SECTION ANSWER
+. 1814400 IN DNSKEY 256 3 8 AwEAAe1udmhwaWyg6PD00YReHeT6nYeN hKAy6oKMc7X5NXXJq6baVZT5p3AnFm7B 0ReT1dOpOjZuArydSdASupCQwRPVja+m 8PQSaAdThTifIBbP0Y2TeeA3yfGbHubo scMezJAXr7FGDQ8XIfyUYBDBoDaINi6j V/oI+aSnwm0uWdxHqfonzioTYenuTsax OGLYYuCMn9soxIuXatO53MpqfsJgh7UK FDCDGKA9pFts1vTQdCMPGgEsuYHjsYF0 /kUoRAQJM3jh0t3wE3JQ/HjFIyR37NCM w+i20b1v6/Xo86gy2nhXq2BopawLPEh0 Fv2UCCI7f8k2JvvF2o9udq/N+FE=
+. 1814400 IN DNSKEY 257 3 8 AwEAAcgeCFZiwMD0S6TVgSK3Ob/MKFo+ dHYeNgoOjxH3JoxV09WShBXID/LwKs/e sYAIzTOBB8Fu9IDoVuQe5prOEcGZRp6u zF7JLnqrgOzoaSPRmKsvXh8DfipA56qE AqNwYBCqzlbGIGjHOQ8t+Xonp4fSBYbN MLmh7o8+u55k7PxemKTCiAnY7Bjx0g3m J1HuFvQXDDdvyletuoS3NKqrkjqdOHRB 3p3GKrKgw+zVb05UEyotCEKjqqi+BOmg cm8rmUIeaNQREjxrUyr8/Ry67h5NJLfq LAqAnSePf1PyhQcl8XjGHXN7w1tLLyJu Gy5B3zLSW1P6jIjon77PSn+cXi0=
+. 1814400 IN DNSKEY 257 3 8 AwEAAfX4eSO5BEPXggvx4jL5HkEjbA+5 QD8Acnh4wOHNv/OJX4QhKnpoMDOrpp38 n0Rgcr8qZ0XUqiJWl8eEH//wrQDHoO5/ JHRmibVrcA6UqfhUa25D1BfeMtTgMCSS +W3/heB/YhyXOJtOdWDmJutDY1nfJUSK rF6XwBj4us7U5jvwXwq+l36AeI4q7I87 Std0GNgRdA6/cJtApPoGv/0oNE0iNTyu IBcAR+AeWu32+JavhTycmtMfZ+KOIShq uI9RHzChZ9yLikAT+gclJGLLlxIr6HDr SLChCG90/yvmc57dLn8qhRWRJtJeLT2V HSxeP7oREb6RSdkxET6OTf9GYHE=
+. 1209600 IN RRSIG DNSKEY 8 0 1814400 20170920000000 20170830000000 1867 . o7N+8dSYDD37wWTtz8ISO3Z2C6Jrill+ r94YmxQQWimsbJ3LEihrjGyXL7Lr+Kgw rpbYUgjwzx5JvDOIUSqmM2SBxsg76Rhj 5NAARoNjR4GQDQJ8U6txxXVO1X6Llgly mBTi0ImUu0p5YZz3HxWpPJEoYE1goiIl xE7G6AFN+nd+riO1tbaMG0X1+9xw5NYt ImuErToPcc0ylMzpvXBLZqUg/s7bJHyL HdoGghslRLz2W1DXWiAnBvICBB/HHPpJ 5LSncL5h/d2HSwVUT30NkS08Vse1aBBX YZpAoupxeYsZ6KPPsdY8Y3xary1mASdw 0RYC6AzGMjuhtevYEPmRsg==
+. 1209600 IN RRSIG DNSKEY 8 0 1814400 20170920000000 20170830000000 37284 . UkQ4HtPbhAKw5BP64OqiZO+xKisJzIA5 YfTAnriF3MiUSMlcx9BYAkrUNkJYWzlZ YgWtAsuE7k/wCYGDxg8CHGTLTx4gCErh gKxAZu5HIz3tyUYZghPT+OIDV0X+hYVZ ZgAO+8w8oSDab3sS1j0ye1weDldhjt9o qEbVhy7gZo0MZpTz7n96TbLgjSF0uT+h Xpp00H/10hgDbvjimI64D5KuHUusL964 h9XIcoZ0vQW6aO3Ufve4/9ma7n+MDGna Ci4/uUGcYA6aNqi+hF518Yi/A2v/tBnq QK2mbnF3POV+kpmQH4iQJ07X4aaeu0cX PsgIYi991e0SFZ6jBWX9Lg==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. 518400 IN NS rootns.
+. 518400 IN RRSIG NS 8 0 518400 20170913000000 20170830000000 37284 . oHsPF5SHum+uJ0JboRPVvwPXPWlcrfW3 sp0MYYsdVVy/H4EetBzVl8I7xEmSI6c2 LY4rlxYtWKxUuDr7mcvlwbPIRG7Rs+C2 f737cCNlm8mBVNEpCcxExnf4swVssIwM bFfLfr8hZjQ5YhU+3Y0L2/YiCBwugRBb vLpbrmuI4th1a+wb0fDF2WYS5GdUzinI pRBF3ZQdoZIMXFdbCvDVGxwd7yBkXxq3 l7u7UK1QBWZdutS+RhHvG3Am3lnKaF1+ tEzseXWDPh/KD4BX1oDrxROdATif3FtJ ktD/1nb/DgIxy12fLx3+NMtCRV6Q+iOa FyFZn6PkltoMEa8CdY1tiA==
+SECTION ADDITIONAL
+rootns. 518400 IN A 198.41.0.4
+rootns. 518400 IN AAAA 2001:503:ba3e::2:30
+rootns. 518400 IN RRSIG A 8 1 518400 20170913000000 20170830000000 37284 . iBK2d08iy7leYXYJKClLj5glo+fxB+zT bRuqnF0qIHEhEDHqo+i+9wI0c5hq6mWL PXmPUrjZkdkmeQF8xreI3GcXATbV49yu v7d7RkmnoiyMqRSEZODx0tH0JugZROUv to4KBweniM9JNCo/iwXJqUcrtawdY4Uz hYn/fvpsHw7DhdEh4o634WSFEgsPvW2H +DcL+xJ4GMfdF2RV35kd/hI40ILMqbbU cFRzcXX1r3ZK+2JOJ/InkjYmusnShB/8 oL3BIXW9g6d7EXA1qjDlc3TD1zOC0tPW G0cTOWpRZydvnLq5yEFVpbNbquXOfB6D 3u+kHoEQ1T5a1EYkOdQSQw==
+rootns. 518400 IN RRSIG AAAA 8 1 518400 20170913000000 20170830000000 37284 . eMd6DeVqe/USIOeZ5MBNfxArFmnmEpnk +Kl9yrnLBISN2PkkcrOY/D/zOQ7jMfbd MB0HUt6R3a7uQNMYhsuLnIQoTPeZdflu I6QNPFCntf53KZKtvr7AcnTex0yx4IJI n/2+xbrdROLbe5deFccKsGvIXA6MkTQd zP8vmOg/1ltpN66bMSNouaCbDC6aDoMs ABBneHYaGnYlxA4aTByRtJzUh+IGEMvB 3eNwbuQ2vbkJhkKrSsJubIqhjSEhNEdK oYmgzUsFL0M3vUsTFbhTASr/ngISJN69 fMJ3yrDPdjlJBXkkSlPZUWnfKHfxjDbR /6Ul50cpb6wcP3ll++u7Qg==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rootns. IN NS
+SECTION AUTHORITY
+. 86400 IN SOA rootns. you.test. 2017071100 1800 900 604800 86400
+rootns. 86400 IN NSEC test. A AAAA RRSIG NSEC
+. 86400 IN RRSIG SOA 8 0 86400 20170913000000 20170830000000 37284 . hGcp4EeAF4ETIwVvhdM47CKT7ePfuiI1 l/bEWXwsYfd0XHUgORkdfPouInN40vIj VXtO/rE8HU6FvfisBTcC23GCH3sMFDYT HEcEDXAR9FczdXtDIPXYnRL/TUCIo/f8 /3iNis/QUO4LRedG+dgSclYhvOQqIcbZ I0crF/JugXrrckXhkM3JQhjbK3DSMy5/ srY63HkAKV42kVLJPTcTeZ6Jse4wej1U t46mqkB+YfjM9Cnkc/UjGFgaaq5+XPIz UIZ7oLBbdtfTR4hMCGpAjLtpxqICdvbE 6pKGxqPBGtBYDkupWzZV08X4Lmr1bdwf CCgAIqCwy0xiBbk/zG/Ufw==
+rootns. 86400 IN RRSIG NSEC 8 1 86400 20170913000000 20170830000000 37284 . bUh3BmbXKHB8ahKfaXzpOSdof0MAR/Qe U97k8jR5CDK3LFWF9JaCiSA9QHVSl8Mb dK/yPQmZCG5//jhW7rddOGo7TSmG+fqC oZtwJS9/HsySuvpBmxiHVjwvmJsbtCqu Ob8hxJO1S0LkAKEN0n5zUrY9wjbzXvSd Vr8sVzpJY2r+T8MD1lewERQtb97bzvGV LYK6lnNJoH6KZwAJd6krcVJWVt4ENj51 6sOiGslAG8FdTuLU4DJSr85y1hag8sJl l3gJWpPfrEJN1cgrWWs91VI365rIW5ZQ zb/vAauB3s6dQ2BrWOWJnepSA9tF4GES siWsiE1feIUsWVaOYCmCSg==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rootns. IN A
+SECTION ANSWER
+rootns. 518400 IN A 198.41.0.4
+rootns. 518400 IN RRSIG A 8 1 518400 20170913000000 20170830000000 37284 . iBK2d08iy7leYXYJKClLj5glo+fxB+zT bRuqnF0qIHEhEDHqo+i+9wI0c5hq6mWL PXmPUrjZkdkmeQF8xreI3GcXATbV49yu v7d7RkmnoiyMqRSEZODx0tH0JugZROUv to4KBweniM9JNCo/iwXJqUcrtawdY4Uz hYn/fvpsHw7DhdEh4o634WSFEgsPvW2H +DcL+xJ4GMfdF2RV35kd/hI40ILMqbbU cFRzcXX1r3ZK+2JOJ/InkjYmusnShB/8 oL3BIXW9g6d7EXA1qjDlc3TD1zOC0tPW G0cTOWpRZydvnLq5yEFVpbNbquXOfB6D 3u+kHoEQ1T5a1EYkOdQSQw==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rootns. IN AAAA
+SECTION ANSWER
+rootns. 518400 IN AAAA 2001:503:ba3e::2:30
+rootns. 518400 IN RRSIG AAAA 8 1 518400 20170913000000 20170830000000 37284 . eMd6DeVqe/USIOeZ5MBNfxArFmnmEpnk +Kl9yrnLBISN2PkkcrOY/D/zOQ7jMfbd MB0HUt6R3a7uQNMYhsuLnIQoTPeZdflu I6QNPFCntf53KZKtvr7AcnTex0yx4IJI n/2+xbrdROLbe5deFccKsGvIXA6MkTQd zP8vmOg/1ltpN66bMSNouaCbDC6aDoMs ABBneHYaGnYlxA4aTByRtJzUh+IGEMvB 3eNwbuQ2vbkJhkKrSsJubIqhjSEhNEdK oYmgzUsFL0M3vUsTFbhTASr/ngISJN69 fMJ3yrDPdjlJBXkkSlPZUWnfKHfxjDbR /6Ul50cpb6wcP3ll++u7Qg==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. 1 IN TXT "it works"
+test. 1 IN RRSIG TXT 8 1 1 20170913000000 20170830000000 37284 . Z7ZBkT7afpWPO2bxz/mItkegNlUuRZIe BcBx+AYTAvs8ffIhm0EYS62j2AVIZwwj S/WnenaOgEvQDtoKi4c2vD8SvOM3n6Ia g6GagJrDTFhVcd0moZdzPNiIukfSg2RS xvO7SckRlp7ILApY6P6EfvgT5tjA39O6 VlgtKcwa8h49PsFdPwpqH2FtkG0i0iUr v4gR/JqzG/ZB+07KF7AtbxLfvvj3o7/t Imal3xl0OAscxAN8hKYRQhRKs4snryXY y9ar5Wf2JVHoyRPJ/rE00UK7/zYr9qIx 4QcTKKdes0prgtu7xyiouXzOSkXE+4KU 6E1tHxRip8Skk1r1XVZwwg==
+ENTRY_END
+RANGE_END
+
+
+
+RANGE_BEGIN 20170909000000 20170918999999
+ ADDRESS 198.41.0.4
+ ADDRESS 2001:503:ba3e::2:30
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. IN SOA
+SECTION ANSWER
+. 86400 IN SOA rootns. you.test. 2017071100 1800 900 604800 86400
+. 86400 IN RRSIG SOA 8 0 86400 20170923000000 20170909000000 37284 . 4sVe391XlvS128uzSEJZuV+LxGPJutXl UpZs3zvvI5LYJH0ivfIMq/ju8wyuVMXx tppwUz2chDoVF4VG9U09R/OXX35EFtn+ 1b77QwoGdciYZ+BTB7mdvY8Ft1M9GOmn 7G+bUOmdQ5DBY6DxgrqnCtnPHtXbsbnU 07PahqotEPXpPntxN9QG/F9i7bLm6O0j qRGFeAHA37aEjkjCKLkAQ6mV3u9zoLY7 UAS+/eE2QwzvitGjaRprbnS3djb6vG2B s0c6/udgypOCY/Ocs7nTRAstBLnRhTXO dmLxaQIviCNs84/gD9ZHa66n5lyqpM3p xwkly7gophmpaad2Z6sG4g==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. IN DNSKEY
+SECTION ANSWER
+. 1814400 IN DNSKEY 256 3 8 AwEAAe1udmhwaWyg6PD00YReHeT6nYeN hKAy6oKMc7X5NXXJq6baVZT5p3AnFm7B 0ReT1dOpOjZuArydSdASupCQwRPVja+m 8PQSaAdThTifIBbP0Y2TeeA3yfGbHubo scMezJAXr7FGDQ8XIfyUYBDBoDaINi6j V/oI+aSnwm0uWdxHqfonzioTYenuTsax OGLYYuCMn9soxIuXatO53MpqfsJgh7UK FDCDGKA9pFts1vTQdCMPGgEsuYHjsYF0 /kUoRAQJM3jh0t3wE3JQ/HjFIyR37NCM w+i20b1v6/Xo86gy2nhXq2BopawLPEh0 Fv2UCCI7f8k2JvvF2o9udq/N+FE=
+. 1814400 IN DNSKEY 257 3 8 AwEAAcgeCFZiwMD0S6TVgSK3Ob/MKFo+ dHYeNgoOjxH3JoxV09WShBXID/LwKs/e sYAIzTOBB8Fu9IDoVuQe5prOEcGZRp6u zF7JLnqrgOzoaSPRmKsvXh8DfipA56qE AqNwYBCqzlbGIGjHOQ8t+Xonp4fSBYbN MLmh7o8+u55k7PxemKTCiAnY7Bjx0g3m J1HuFvQXDDdvyletuoS3NKqrkjqdOHRB 3p3GKrKgw+zVb05UEyotCEKjqqi+BOmg cm8rmUIeaNQREjxrUyr8/Ry67h5NJLfq LAqAnSePf1PyhQcl8XjGHXN7w1tLLyJu Gy5B3zLSW1P6jIjon77PSn+cXi0=
+. 1814400 IN DNSKEY 257 3 8 AwEAAfX4eSO5BEPXggvx4jL5HkEjbA+5 QD8Acnh4wOHNv/OJX4QhKnpoMDOrpp38 n0Rgcr8qZ0XUqiJWl8eEH//wrQDHoO5/ JHRmibVrcA6UqfhUa25D1BfeMtTgMCSS +W3/heB/YhyXOJtOdWDmJutDY1nfJUSK rF6XwBj4us7U5jvwXwq+l36AeI4q7I87 Std0GNgRdA6/cJtApPoGv/0oNE0iNTyu IBcAR+AeWu32+JavhTycmtMfZ+KOIShq uI9RHzChZ9yLikAT+gclJGLLlxIr6HDr SLChCG90/yvmc57dLn8qhRWRJtJeLT2V HSxeP7oREb6RSdkxET6OTf9GYHE=
+. 1209600 IN RRSIG DNSKEY 8 0 1814400 20170930000000 20170909000000 1867 . nYKCrIGWK/cioGfdAArMBL1Xw4JTRSnl 9hWCY26Ib7ogWnkJd5zp0WIbjNNJiNO/ XRDUZEXC7anjXzSt8ZrncqMsFI+fQD++ ZJpmEZpz4FkNrGN0yooO5uPJNxznf8Rz /Zz4i+DUWCJWyiUSOVZ/zFTgv7oTOuat bqYuXNp0mLk1ue093M5pOYTLuzuGDWlZ s08ZhO6VPV+9nfEjnqKgRyNKSiQz4juS GMBQE0nLF9oWv8Wl4h8XKuXPPYAgg4Hf J54ZGckuDXLG1UU3/d7iLmbKWRsPFyRn e3Jm6bWQ51C9BJhTjRmQYKdEPPTUhVnE wNsn9VekiSAeRNt6Fv/e8A==
+. 1209600 IN RRSIG DNSKEY 8 0 1814400 20170930000000 20170909000000 37284 . jQ4JxIi9y6o9RG+pqB9OXt6XWKNU082y v/tDJH4O6XwaeAcM9lq75K62u0jVc7iF ZOxOBglei/rMC0JwnBDmU27gn1vWmpwy cUtlqK5b7n+EgydfLpAru9bCgUD8Cn8M qQ3gpsClpZY2l1fRAsk3BQa/OpjBCjmX +LvikL1t+bzgH0198BQrNbgNjBi7kr28 8YxH4K+MqcLA2t+uoHNoGxygectBMURG 7luS0Cy+Y1dN4YUERrX0F31toLfo+Qpn KVtxrA2Aw0iHhWChBsVn1IHGYvnmbN7A u6IbaggzrNru6t3OqG6sxLZd6gKSuY1d SfOU0RwM4f6dhZKz0Cyiwg==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. 518400 IN NS rootns.
+. 518400 IN RRSIG NS 8 0 518400 20170923000000 20170909000000 37284 . nUcSfFQOC46LyoBiQSVWoUUop3AU/sQa FjqJKG3aL9sTk2Rm+VzbKbpzlFyBCxcg nChFWq7m5EjzmeG379dTCM/6Imge+npQ jhsgz7yHh4jwfYqgOaGFp84fduBFlbLc XvJvZvjmnxsPlB6fYOlBKuXEANzLJgob tlle84oGusjWpbPW/eNtvMAhPG9Ct0CF zoL2UkqO3wp2V/gxPiEPmNs3lr7ov95J kltL2AbL4SmxQ9T94FLqrJWmUCKAHjdF bF27F4zfwCVu1f3Qrwa/77H6o9KAtvZm tevGo/lsO2xEWK0QV2Olex6KHQx1NWKy cR/7GH11NBnsjYmiglLIUA==
+SECTION ADDITIONAL
+rootns. 518400 IN A 198.41.0.4
+rootns. 518400 IN AAAA 2001:503:ba3e::2:30
+rootns. 518400 IN RRSIG A 8 1 518400 20170923000000 20170909000000 37284 . g8bM4iGPuB1ZyAjP39aGVi21hUhdrsxu gqHBb3xRne4L79U8rHc1SHpA5BupowTl LQJV+3pM5KnX/eBVenWf/4y6gjI7aj/l u1chVmUfRKeI4kTXd+Bhhv/9SJXEvHqw 10fcWavusnuHs/qNCZlZCs0RmZaaEuhl EJF6Vat2x56/dEGw08KToo05OR4esdq1 r7ARQlARYZocINyQgB5JqgxV3CJ87LEz IwGu3pOJGwBA/Lqg6LOqv/TCREwWJITs 2cfFpwRyKmiGd7Qo0k4+0Dw9nIupR4rj KM1EXklx5YwAG1dNTQUu6lmQ7BJbSXs6 x7uOjdl2id2RQfysiTNokw==
+rootns. 518400 IN RRSIG AAAA 8 1 518400 20170923000000 20170909000000 37284 . 6u3jOiK1+7BoFdnFwHWHDGRYfmTAeQV7 X2yCqBtBiaAUbeTrH14ycJdyd++jL/fa w3nZa+xkdxACrsMu+0rWzH0zNtP2gbg0 iI3FyxExBWnlJfzK7fRAfzE6i7OCTjJo 4dTa0VxV/lJN4v2criQ3QdmJgw+Yzpmu Aac35W53zHioliK1gEhqZRAyNLXVvfXq zJYxgAzmIdGwoS6QyJXx1Sxsd7HGrosw HdhQPPY9rI2ZXzZjat68bpDXw/jqTdi5 vw+lD9STlXg1ZrWWAN7Nip19JEteUnC6 EyoUPggFdu4hG6GUIIJKjbM0SKcUGBjn F8HZJH8LIOap2UoVUkVvQA==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rootns. IN NS
+SECTION AUTHORITY
+. 86400 IN SOA rootns. you.test. 2017071100 1800 900 604800 86400
+rootns. 86400 IN NSEC test. A AAAA RRSIG NSEC
+. 86400 IN RRSIG SOA 8 0 86400 20170923000000 20170909000000 37284 . 4sVe391XlvS128uzSEJZuV+LxGPJutXl UpZs3zvvI5LYJH0ivfIMq/ju8wyuVMXx tppwUz2chDoVF4VG9U09R/OXX35EFtn+ 1b77QwoGdciYZ+BTB7mdvY8Ft1M9GOmn 7G+bUOmdQ5DBY6DxgrqnCtnPHtXbsbnU 07PahqotEPXpPntxN9QG/F9i7bLm6O0j qRGFeAHA37aEjkjCKLkAQ6mV3u9zoLY7 UAS+/eE2QwzvitGjaRprbnS3djb6vG2B s0c6/udgypOCY/Ocs7nTRAstBLnRhTXO dmLxaQIviCNs84/gD9ZHa66n5lyqpM3p xwkly7gophmpaad2Z6sG4g==
+rootns. 86400 IN RRSIG NSEC 8 1 86400 20170923000000 20170909000000 37284 . co+5dOhcVlu7rKvhWgJY2te7PNFQnvt8 DFn2xKP5ZV1qDtId/qepvY4FHEYzTJua DLD4efHBL0uY3R0VONqnHS/DppUBRXHt 1JcjFETuMt2pZszEDyEimFDLNCtclmnP 13A3fwDObFZxxqHmcQXV8pb4ZBInJuCs 5SCU1NE0XmBjAbpgB//Nfllht+G1SQlD 3XHNvlNBQ6D7Ma1qs1w0XIse5ekS09nq QRAJbgu6ob1Yb9b3zuvcFyU357h4MJPb ligrO4HrPY7Q4w6M2GUKgnCUVlPG9Wrk vgnNNMOIzVAwWY95vr5K/bANTjI6Mh6b Cr61MpLk5Y7JTPIsyMJgrA==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rootns. IN A
+SECTION ANSWER
+rootns. 518400 IN A 198.41.0.4
+rootns. 518400 IN RRSIG A 8 1 518400 20170923000000 20170909000000 37284 . g8bM4iGPuB1ZyAjP39aGVi21hUhdrsxu gqHBb3xRne4L79U8rHc1SHpA5BupowTl LQJV+3pM5KnX/eBVenWf/4y6gjI7aj/l u1chVmUfRKeI4kTXd+Bhhv/9SJXEvHqw 10fcWavusnuHs/qNCZlZCs0RmZaaEuhl EJF6Vat2x56/dEGw08KToo05OR4esdq1 r7ARQlARYZocINyQgB5JqgxV3CJ87LEz IwGu3pOJGwBA/Lqg6LOqv/TCREwWJITs 2cfFpwRyKmiGd7Qo0k4+0Dw9nIupR4rj KM1EXklx5YwAG1dNTQUu6lmQ7BJbSXs6 x7uOjdl2id2RQfysiTNokw==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rootns. IN AAAA
+SECTION ANSWER
+rootns. 518400 IN AAAA 2001:503:ba3e::2:30
+rootns. 518400 IN RRSIG AAAA 8 1 518400 20170923000000 20170909000000 37284 . 6u3jOiK1+7BoFdnFwHWHDGRYfmTAeQV7 X2yCqBtBiaAUbeTrH14ycJdyd++jL/fa w3nZa+xkdxACrsMu+0rWzH0zNtP2gbg0 iI3FyxExBWnlJfzK7fRAfzE6i7OCTjJo 4dTa0VxV/lJN4v2criQ3QdmJgw+Yzpmu Aac35W53zHioliK1gEhqZRAyNLXVvfXq zJYxgAzmIdGwoS6QyJXx1Sxsd7HGrosw HdhQPPY9rI2ZXzZjat68bpDXw/jqTdi5 vw+lD9STlXg1ZrWWAN7Nip19JEteUnC6 EyoUPggFdu4hG6GUIIJKjbM0SKcUGBjn F8HZJH8LIOap2UoVUkVvQA==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. 1 IN TXT "it works"
+test. 1 IN RRSIG TXT 8 1 1 20170923000000 20170909000000 37284 . ENRCRlKqQ6DYCQTD41xWMM7vfU+vIsem i5S243UV7pWEb3f67JQyM8ynCPvINQq9 pZE6oruuPlp9HHixMiEdNwyFGPbKTCsr 0o8CTsuRZWKOmVjMtKWOg5F+cmU+uWr6 sWjfQ4ON64Zez8ED5i9p5ZBgTRN4sFAy TC7/xSidQ2+D9tN3EjrUkgECkujGvErP NBFOUukZ18l6IgeboDF9GpJ20xxsnMkT I1NtQ1g5v13M45ct/XYrUeuT913/wdVf HwUjptkF5127XEc4vyRZ02Cy7hv+x5Rf RK0V2IjuTN1MgxvTDsCAbxiNJKesx9lJ DFFD9P6UDQiMr5USjMuAwQ==
+ENTRY_END
+RANGE_END
+
+
+
+RANGE_BEGIN 20170919000000 20171000999999
+ ADDRESS 198.41.0.4
+ ADDRESS 2001:503:ba3e::2:30
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. IN SOA
+SECTION ANSWER
+. 86400 IN SOA rootns. you.test. 2017071100 1800 900 604800 86400
+. 86400 IN RRSIG SOA 8 0 86400 20171003000000 20170919000000 37284 . zIsYbxp2lc9mFdhHsUmvb12AM8fIcHem 6YgkRu4Owgv/NkRo4yQ2GvfkuSmXb9EU fsHKaJ1CrDQRckXTGtKLvWvFnUuxJtrO DkxKdTUG+yBwL4Sma1xhsj11JFu57Hm7 hQemP9LdYGXxntRh24kNG/ILuj4qk6Oj k+l87JcMnrG8SzOvykliSPriywagnvl/ bEMWzbFRFwEdxr9hkwMNxK4XbAAeEBJ0 j475+LS0FYiijsvqhkU5sjkTPkHzVtTI Ks1POK9cerSOJPm8GtWrduGYvIJjSwmH qVvzKBG5RfUZiAigW/VrqYcPn/8lpYqI kz6lAFl/pGsEd6v2gSo43g==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. IN DNSKEY
+SECTION ANSWER
+. 1814400 IN DNSKEY 256 3 8 AwEAAbS4LSbmieIk96i3AK8IEZXlLRdM YLoEp4QSRMrdtJ0VcZKsjHWF6g9Q50T/ 1XKBxY/+6j71//cFRi1cViqoNsPd3LEb txWa3Jx/1HBINOkAPdHMBc3SQQ5qEIar PObq98RLnQ22ske1xZtbzNRZogPNi7zM HwQ3GYf0sUVCnYTmv8en5yYfSh8mY9Ez 8okorK7UN2RlHx9B8S5DRtBphO61mSI8 MXRj91aC3iRTbYZndTWorVkj4UvCBBr9 qh7oNpRbprIvAmRzRK6IaxpYDS6iGtSq 05WbGRtQRXkngOzFZO1BBDHgj9Agtx2S HBxAKuX4wF+w8I8xO7m5z0MOIF0=
+. 1814400 IN DNSKEY 256 3 8 AwEAAe1udmhwaWyg6PD00YReHeT6nYeN hKAy6oKMc7X5NXXJq6baVZT5p3AnFm7B 0ReT1dOpOjZuArydSdASupCQwRPVja+m 8PQSaAdThTifIBbP0Y2TeeA3yfGbHubo scMezJAXr7FGDQ8XIfyUYBDBoDaINi6j V/oI+aSnwm0uWdxHqfonzioTYenuTsax OGLYYuCMn9soxIuXatO53MpqfsJgh7UK FDCDGKA9pFts1vTQdCMPGgEsuYHjsYF0 /kUoRAQJM3jh0t3wE3JQ/HjFIyR37NCM w+i20b1v6/Xo86gy2nhXq2BopawLPEh0 Fv2UCCI7f8k2JvvF2o9udq/N+FE=
+. 1814400 IN DNSKEY 257 3 8 AwEAAcgeCFZiwMD0S6TVgSK3Ob/MKFo+ dHYeNgoOjxH3JoxV09WShBXID/LwKs/e sYAIzTOBB8Fu9IDoVuQe5prOEcGZRp6u zF7JLnqrgOzoaSPRmKsvXh8DfipA56qE AqNwYBCqzlbGIGjHOQ8t+Xonp4fSBYbN MLmh7o8+u55k7PxemKTCiAnY7Bjx0g3m J1HuFvQXDDdvyletuoS3NKqrkjqdOHRB 3p3GKrKgw+zVb05UEyotCEKjqqi+BOmg cm8rmUIeaNQREjxrUyr8/Ry67h5NJLfq LAqAnSePf1PyhQcl8XjGHXN7w1tLLyJu Gy5B3zLSW1P6jIjon77PSn+cXi0=
+. 1814400 IN DNSKEY 257 3 8 AwEAAfX4eSO5BEPXggvx4jL5HkEjbA+5 QD8Acnh4wOHNv/OJX4QhKnpoMDOrpp38 n0Rgcr8qZ0XUqiJWl8eEH//wrQDHoO5/ JHRmibVrcA6UqfhUa25D1BfeMtTgMCSS +W3/heB/YhyXOJtOdWDmJutDY1nfJUSK rF6XwBj4us7U5jvwXwq+l36AeI4q7I87 Std0GNgRdA6/cJtApPoGv/0oNE0iNTyu IBcAR+AeWu32+JavhTycmtMfZ+KOIShq uI9RHzChZ9yLikAT+gclJGLLlxIr6HDr SLChCG90/yvmc57dLn8qhRWRJtJeLT2V HSxeP7oREb6RSdkxET6OTf9GYHE=
+. 1209600 IN RRSIG DNSKEY 8 0 1814400 20171010000000 20170919000000 1867 . LMUm+N+voM+56KcWjWsPGklkKiyFbgtX Ay/Ji/tJf0a2uh2mdlkXUWAVjPOkafQx 5Tq4zjw+/pWvVwisLiYSn8m+m+hdxcSg viy9etd6dfrsVZNwgsMG3K6LdHfsbuC4 Ydrv6yZoZTUFyfHyQRCfATHJch0piSLL /LMFObaDBC3MWLra6WtdirrYnNTP011S y9tbfC/V7wtDrlIFtkK3zJIsHurm4BGW M9oFfMg7VDBgJef0LbZhhU+4yjTaWRaG VVcSBeqmXqhqlqLxDsqj5mrdIHwW2vF+ Hb9D+F0bwCswKrsKixXOnkCFIrhT1RZQ 0CB9BZH/QGDCDtWUGXueRw==
+. 1209600 IN RRSIG DNSKEY 8 0 1814400 20171010000000 20170919000000 37284 . pOG+720+4AOjs6Fif7BUPGOGxGXilWFh z+YeXx6C/IIk08i9DqW4WvGG1o9CMX/+ NN5OyuecUFJp8n22xwfckf3RORs6LhQ2 megC4ihkWAcxXHqyqjqkUx4P7DVAAAGn yzVyXY7KMpuMO7ionGgZk04RxdKeeoT8 8AXKdwNwTUQ61+rNdsUU8Fygg7DLvB3b zT9QkjYTi+QPo6ALwgjHcr6l97hGs5cp U9FCAZXu5oTp9eqjXAmI5eyrDRDRK7nq hSjnbbXTT7GzPvTswda+o906PYkB2gW7 qkGofxD4Ciu8siz3vy9ALUQTT4eeNm7Y WtoCrJbhsZ0/7FacD3L8jw==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. 518400 IN NS rootns.
+. 518400 IN RRSIG NS 8 0 518400 20171003000000 20170919000000 37284 . uZ3lgEsJfhMjLnVepQJ9SyRoIRJZZhM/ GSl9T1WfxljeWcVuH0OqxOaCGCK27Vpj PWjJ/n6l1zjy3lz1s34/XZ8WmcfbrLdg zZ+9sZsGVXqxT+npo3IeFUXD5a2LgB3d oIidRs/IbkKDaKw7U8FF0SPXS8h1St7V 4/ENnq54WPdh8BZC2f0C9VU+xsnDlp5z NsrqDeMwPZ1yPdnlxJA6koL0F3p1/VYT DP/Mriyzjt+dmvhojkkQnWG2rnnXGWh4 ewlZwlR68mB+DCQ/WhnMHq9RffCTIygC F3Drb6482XR7ANtmXDsNA/Y2iQjADZpb cjb7yyogu5yPHw0SJHfPPA==
+SECTION ADDITIONAL
+rootns. 518400 IN A 198.41.0.4
+rootns. 518400 IN AAAA 2001:503:ba3e::2:30
+rootns. 518400 IN RRSIG A 8 1 518400 20171003000000 20170919000000 37284 . 4OZ8eS+IN3twUhfuk78BkQbVehkxz4x4 EeEoPfL24Vex9AMnIj+DlwgYsErcczgK HgJpoTUZqlGGn2kNzZ03RX3RoAyoBMoW C+1lpVpkv3x6RdNQO0RMtFVRieh1viuQ cd6oFXUsNETjVEJS/spzPEF37xx3lJKl bOLvY65YhfnFtngfYuPTQQ/SEn5mr8jZ r/0iuFs8XAH6I2frpd7h48rD96OeXQV0 Uppw5M3ClEKBSHU+f71M3SWue07HJuBx jKaAZMJYfYhci4vm9NqZe0V/dQWHwRRG OpHwPQNaI0tJBUlHTddKE2pPjxnQXS5t W+o7hHZrH3SI1GsE5Ugsrw==
+rootns. 518400 IN RRSIG AAAA 8 1 518400 20171003000000 20170919000000 37284 . oqdH8h+fUxn9TSNLtANXQxUiRHUEraOv GuOZ4hdbEs6K65QY4P4fj/fO7Qi6hlCF O+N2FgG4CTc0lNLQzQ4+FGtpwiczSN5I SCw6lunF53F6ljWl4IheBtvYfdcDgKG6 Oqms9N7cj6eigTejag8qr+mL1/QNe+UI bVGntou/NBdA7B/Co91en6A0jdB8w2CE PRh3FshPPaAvjybZ7vhpaObZf6Q/a27P fFt9o3udlESHx4d8wUhCovfDiXPYBRNd ZOTYfXozedUmwVB9uZ29GR/8cxq8SJhq D69VIL2eqThBK9EbaEyIDhvSDXxbExFi vgvOKzd2/1CLrnCjF3pC+A==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rootns. IN NS
+SECTION AUTHORITY
+. 86400 IN SOA rootns. you.test. 2017071100 1800 900 604800 86400
+rootns. 86400 IN NSEC test. A AAAA RRSIG NSEC
+. 86400 IN RRSIG SOA 8 0 86400 20171003000000 20170919000000 37284 . zIsYbxp2lc9mFdhHsUmvb12AM8fIcHem 6YgkRu4Owgv/NkRo4yQ2GvfkuSmXb9EU fsHKaJ1CrDQRckXTGtKLvWvFnUuxJtrO DkxKdTUG+yBwL4Sma1xhsj11JFu57Hm7 hQemP9LdYGXxntRh24kNG/ILuj4qk6Oj k+l87JcMnrG8SzOvykliSPriywagnvl/ bEMWzbFRFwEdxr9hkwMNxK4XbAAeEBJ0 j475+LS0FYiijsvqhkU5sjkTPkHzVtTI Ks1POK9cerSOJPm8GtWrduGYvIJjSwmH qVvzKBG5RfUZiAigW/VrqYcPn/8lpYqI kz6lAFl/pGsEd6v2gSo43g==
+rootns. 86400 IN RRSIG NSEC 8 1 86400 20171003000000 20170919000000 37284 . FYT56I3bIBcEPdHW7pvndYI3Wvw6uElt j8aRh97PR5UsTuwR/ldnYlaPZORD7HXo ia+bKlkHJArJIX49ZrKfCf+/bdLHD6ai AbPzUm0f+jfcPpZ5WO/cXXv97sfOL2Ob mRpQ6jUOmm0fSIU5gnE+V+EIWSgHuWEP w4cy4O6whqI290ktNaDJbLwIoKzuWa4+ WcSAjtikkgkqLejHVWlftT+/5y3d8c9F fWjj3YvCy9J4HPpfCfrgX5dMCeyUTnVb iGwYp50xJJDeaPcXc9HxGfmdJOnzo1se /UGfqjw3J68RHjokzgo/w1Ny56IbgtC7 4rDxGIHjInmeM1+svCbJHQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rootns. IN A
+SECTION ANSWER
+rootns. 518400 IN A 198.41.0.4
+rootns. 518400 IN RRSIG A 8 1 518400 20171003000000 20170919000000 37284 . 4OZ8eS+IN3twUhfuk78BkQbVehkxz4x4 EeEoPfL24Vex9AMnIj+DlwgYsErcczgK HgJpoTUZqlGGn2kNzZ03RX3RoAyoBMoW C+1lpVpkv3x6RdNQO0RMtFVRieh1viuQ cd6oFXUsNETjVEJS/spzPEF37xx3lJKl bOLvY65YhfnFtngfYuPTQQ/SEn5mr8jZ r/0iuFs8XAH6I2frpd7h48rD96OeXQV0 Uppw5M3ClEKBSHU+f71M3SWue07HJuBx jKaAZMJYfYhci4vm9NqZe0V/dQWHwRRG OpHwPQNaI0tJBUlHTddKE2pPjxnQXS5t W+o7hHZrH3SI1GsE5Ugsrw==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rootns. IN AAAA
+SECTION ANSWER
+rootns. 518400 IN AAAA 2001:503:ba3e::2:30
+rootns. 518400 IN RRSIG AAAA 8 1 518400 20171003000000 20170919000000 37284 . oqdH8h+fUxn9TSNLtANXQxUiRHUEraOv GuOZ4hdbEs6K65QY4P4fj/fO7Qi6hlCF O+N2FgG4CTc0lNLQzQ4+FGtpwiczSN5I SCw6lunF53F6ljWl4IheBtvYfdcDgKG6 Oqms9N7cj6eigTejag8qr+mL1/QNe+UI bVGntou/NBdA7B/Co91en6A0jdB8w2CE PRh3FshPPaAvjybZ7vhpaObZf6Q/a27P fFt9o3udlESHx4d8wUhCovfDiXPYBRNd ZOTYfXozedUmwVB9uZ29GR/8cxq8SJhq D69VIL2eqThBK9EbaEyIDhvSDXxbExFi vgvOKzd2/1CLrnCjF3pC+A==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. 1 IN TXT "it works"
+test. 1 IN RRSIG TXT 8 1 1 20171003000000 20170919000000 37284 . SIetFloLSKUteCyhAROcwKu97x30Yjev Xjuo/iCpTSQwPD9Hkw3o6w4Jg4MFI51/ T/TOhr/x3V4AFIon7FyRjYzbe8FBtTCO k2B393CMp4TgcQUDYtdGYwZX37NN7YGr clF5PY5ejLNTT4HauuTObzPB3ZaNLRMd zQK7sTSCWQmjdQYXumL6rYBYLrCD6R52 Tnh8YDL0k2al9bD8FCiQJoqMqHqXYFAE GD0lxBKJrRfubzRmpk7u1zDhfwaP7TfT owkW3V9k8e1UBFkbyBtHaBzRQrnxuCvv BsuEoAx/1q3gItRvj5APM/4Qkmb8oiC3 l0j6fev46O9SQeCREPPXVw==
+ENTRY_END
+RANGE_END
+
+
+
+RANGE_BEGIN 20171001000000 20171010999999
+ ADDRESS 198.41.0.4
+ ADDRESS 2001:503:ba3e::2:30
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. IN SOA
+SECTION ANSWER
+. 86400 IN SOA rootns. you.test. 2017071100 1800 900 604800 86400
+. 86400 IN RRSIG SOA 8 0 86400 20171015000000 20171001000000 43863 . NqLOBYw5S0U6TN0X70UZv1V45vVbiDSp 1qpD4Sb+dNaCRuz9xxAWyQ4hfAcRh1GB 7L9w5HBviGwqfHQYZQqWvqEjXl5Dcgu7 h0pGQnNfEh2Eq/v16MEVf9XSR4C6ngK8 qtjigNahjsVNYz8COoooQuP5plu1LDzs myTcldGM3EbW9oYEZS5gpPXrMjFn/j7Z 6q87y/1uhJh4hiv5THl5kL416YVQzZdK fVS+oJxJe2B70H7PIOtOuKD2wIuMLXCk MWQz/Zmciz53i8/WicTHnGlWU7xKVH8m ZIFEzzhtcR71NVkHrMVuESKuJp1fm3lR 6FgC4KReLduGXcqDVCZNwg==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. IN DNSKEY
+SECTION ANSWER
+. 1814400 IN DNSKEY 256 3 8 AwEAAbS4LSbmieIk96i3AK8IEZXlLRdM YLoEp4QSRMrdtJ0VcZKsjHWF6g9Q50T/ 1XKBxY/+6j71//cFRi1cViqoNsPd3LEb txWa3Jx/1HBINOkAPdHMBc3SQQ5qEIar PObq98RLnQ22ske1xZtbzNRZogPNi7zM HwQ3GYf0sUVCnYTmv8en5yYfSh8mY9Ez 8okorK7UN2RlHx9B8S5DRtBphO61mSI8 MXRj91aC3iRTbYZndTWorVkj4UvCBBr9 qh7oNpRbprIvAmRzRK6IaxpYDS6iGtSq 05WbGRtQRXkngOzFZO1BBDHgj9Agtx2S HBxAKuX4wF+w8I8xO7m5z0MOIF0=
+. 1814400 IN DNSKEY 256 3 8 AwEAAe1udmhwaWyg6PD00YReHeT6nYeN hKAy6oKMc7X5NXXJq6baVZT5p3AnFm7B 0ReT1dOpOjZuArydSdASupCQwRPVja+m 8PQSaAdThTifIBbP0Y2TeeA3yfGbHubo scMezJAXr7FGDQ8XIfyUYBDBoDaINi6j V/oI+aSnwm0uWdxHqfonzioTYenuTsax OGLYYuCMn9soxIuXatO53MpqfsJgh7UK FDCDGKA9pFts1vTQdCMPGgEsuYHjsYF0 /kUoRAQJM3jh0t3wE3JQ/HjFIyR37NCM w+i20b1v6/Xo86gy2nhXq2BopawLPEh0 Fv2UCCI7f8k2JvvF2o9udq/N+FE=
+. 1814400 IN DNSKEY 257 3 8 AwEAAcgeCFZiwMD0S6TVgSK3Ob/MKFo+ dHYeNgoOjxH3JoxV09WShBXID/LwKs/e sYAIzTOBB8Fu9IDoVuQe5prOEcGZRp6u zF7JLnqrgOzoaSPRmKsvXh8DfipA56qE AqNwYBCqzlbGIGjHOQ8t+Xonp4fSBYbN MLmh7o8+u55k7PxemKTCiAnY7Bjx0g3m J1HuFvQXDDdvyletuoS3NKqrkjqdOHRB 3p3GKrKgw+zVb05UEyotCEKjqqi+BOmg cm8rmUIeaNQREjxrUyr8/Ry67h5NJLfq LAqAnSePf1PyhQcl8XjGHXN7w1tLLyJu Gy5B3zLSW1P6jIjon77PSn+cXi0=
+. 1814400 IN DNSKEY 257 3 8 AwEAAfX4eSO5BEPXggvx4jL5HkEjbA+5 QD8Acnh4wOHNv/OJX4QhKnpoMDOrpp38 n0Rgcr8qZ0XUqiJWl8eEH//wrQDHoO5/ JHRmibVrcA6UqfhUa25D1BfeMtTgMCSS +W3/heB/YhyXOJtOdWDmJutDY1nfJUSK rF6XwBj4us7U5jvwXwq+l36AeI4q7I87 Std0GNgRdA6/cJtApPoGv/0oNE0iNTyu IBcAR+AeWu32+JavhTycmtMfZ+KOIShq uI9RHzChZ9yLikAT+gclJGLLlxIr6HDr SLChCG90/yvmc57dLn8qhRWRJtJeLT2V HSxeP7oREb6RSdkxET6OTf9GYHE=
+. 1209600 IN RRSIG DNSKEY 8 0 1814400 20171022000000 20171001000000 1867 . SLUfyBPUVaIp+yzafCz6VdqrSFGI8XA4 4Yh1m5g33CTjHLHYdtprsZbOmU1DkcJf zeQpHrMwStfDycnvwCbtN7QV3hzVIsOS +4npL6l1nn8ORi4x3dklHrks2rl/L+ju vsI1KE5dLuTEPLKxcrt0SRd+JsxhzewR WZwAxFFYVeXNWoKQeuFPH3BSeqC1hcJ9 p54vcoOYvwm4h+x+R93QZ6j3ePmj6wih x0haMVJ1tbPxoCYJK+LZoRynnWmhEm2p Wivw5TlYE5eGWPK2NYSO2te7cOH2y8Py taiWTE/VOpKEFJVHyXDQfffONLbTRFaV MCC4eDAVi4LTYt1gejgx+w==
+. 1209600 IN RRSIG DNSKEY 8 0 1814400 20171022000000 20171001000000 43863 . sWLCuaV0WZTEAIjXVuAC6jV18aQubTO4 Cs2wA9hLJQyPFIN+cKVrwMP0PXHrVNs/ 3k8UIBg/4BcgWCT7BbypiaaJjiXhKDxn hIk0oJRHzE7sGE5mvsKlqk4XBeLNnuCN NykshvAbpbh7lsFBqQ7JjtaZeRTu6JW+ CJixWFb9E9QYyJ3jfKDwLhiytpiWmr3Y ny8y4a2pOwYnuAiz2XzZP7I8dHXdPHaA sfitx1HSLpFwGUvfe3GdcAZRpoTKmtL5 gz4Uy+4HIawROTtnptir5OyAvCqeU1T4 BfnrMuYt28Zj1CzbF0H4vCjTyBWYC7gj GEehw4AutnhxoFlgFIFx3Q==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. 518400 IN NS rootns.
+. 518400 IN RRSIG NS 8 0 518400 20171015000000 20171001000000 43863 . UUCE+pmAPxa4t+LyPxbpjtVEq7F2DU7d 5tGfvJcNhFmbgEcl/7/PvaoPRTHOtnKI J6zLb8068Q/Y/rziAgW1vjuvmmIScefi nEcASJAkczBMQLDzyqLYnOfhORPRQyTo MRG0fGnsw03+qjOo4lfsdqvLvzSzkiMe idplhFpQ65Wpc4ARKRc0AHzde9rdD9uU BAFAUg23A8Z0p6+WuVi5lwS/TCnFbT/Y bBx9/wcOK1Be4nzvtR6KiwxZVk2DHVyV 8DqgGCQxLWbd/4sIftHG+URJlXi1ZGeG eFQLs9wY1ES5fSCdot3yRfAGRnLzBxN8 2SoCIGo7VfhRK6/Z00/K8A==
+SECTION ADDITIONAL
+rootns. 518400 IN A 198.41.0.4
+rootns. 518400 IN AAAA 2001:503:ba3e::2:30
+rootns. 518400 IN RRSIG A 8 1 518400 20171015000000 20171001000000 43863 . WhLjFUV6O/CeESF8322BZSdt32YTh7uh H2wJNLJnvtkJu/4QoPGx3AvgiLquC52m r3PFFcD6ZPC1iqKRieLqEfyH0B8iS1Oq iADBUjdLC1e5mKsEc+bwb5P5heaWdu6g FrhoPPL98QtswwXFfsmhOwoQomplIDlu gNLUyCjfvCSjX6raEKbuBn6pn65OlT4s sZh6nCT9YOYma5QL5FxFlaFzUfJn0qGQ 2k341M6sS6U84rhiFKWyRtSqShPzCnfB Q06Rcx47fabVpcUJ2rS1DE3jc9bIszeZ n8IK4TlxkkQ6CbaahKAUeXQ6iVdAEaZ8 Ut2XVbPlTnkCGbBQQbismw==
+rootns. 518400 IN RRSIG AAAA 8 1 518400 20171015000000 20171001000000 43863 . VfbolsQWe3CmwrnWRsdmx2k5gaQmSt7Q oKv6b11iLn+oY1gpQL9fz4YRU8z5HzTv XFvgtdLDnN/7jmo6ECgKU43ToOgRlNBv nu7FijQ0iBj34Lxl0D9geAJ12lakVHHG pbzokVSTVyIduoOhhMT5ZEPmQ3e3ru1B xArn4MFUH97cWnfFkGobDz+nas1Z9E0i kZ510rYpKB8MVyhO7l79txsxwK8Y/ut4 4jg6bfGTwTSk9ILWalsSMYy0CVkQHUgE Cm8MracEG7D8TTBWipvoT5WD/qA4usyx 7nXUeQH/wM5q/9U4iRY4Vf+1iPk3d6+h gK/MteVeDPZYTOS+IwzWVw==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rootns. IN NS
+SECTION AUTHORITY
+. 86400 IN SOA rootns. you.test. 2017071100 1800 900 604800 86400
+rootns. 86400 IN NSEC test. A AAAA RRSIG NSEC
+. 86400 IN RRSIG SOA 8 0 86400 20171015000000 20171001000000 43863 . NqLOBYw5S0U6TN0X70UZv1V45vVbiDSp 1qpD4Sb+dNaCRuz9xxAWyQ4hfAcRh1GB 7L9w5HBviGwqfHQYZQqWvqEjXl5Dcgu7 h0pGQnNfEh2Eq/v16MEVf9XSR4C6ngK8 qtjigNahjsVNYz8COoooQuP5plu1LDzs myTcldGM3EbW9oYEZS5gpPXrMjFn/j7Z 6q87y/1uhJh4hiv5THl5kL416YVQzZdK fVS+oJxJe2B70H7PIOtOuKD2wIuMLXCk MWQz/Zmciz53i8/WicTHnGlWU7xKVH8m ZIFEzzhtcR71NVkHrMVuESKuJp1fm3lR 6FgC4KReLduGXcqDVCZNwg==
+rootns. 86400 IN RRSIG NSEC 8 1 86400 20171015000000 20171001000000 43863 . js4jobso3JzElwlF+PAw4W9No9vgyaJm l9EdFtRCdGyixA6bLL+mAdZESbpMvUpR 4t+DBd+zbOeHlJUnmtTib/eU7stYM1LT T4s1UZUh7HZh1RYQ/ujZsn48+eKCShKG OGdidugQyIreLm55qvj51yro0Ie03juN jag88naOfvS5mbq8OmN82apeGxjwiISG u+VegiXchOiDeHZAT/dxlXF2lJQ+fodN pmGrMo6y5jm1EW2hpDNqW3DcM0rWJ1fY AkiBxiwRnkpdR5ckqfVXT18xKoZfEy+3 bXbdh0Cd40IipkuwjmOh5ZXGma15CU7D BgGJzmP/60pJdMAAD7rjsg==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rootns. IN A
+SECTION ANSWER
+rootns. 518400 IN A 198.41.0.4
+rootns. 518400 IN RRSIG A 8 1 518400 20171015000000 20171001000000 43863 . WhLjFUV6O/CeESF8322BZSdt32YTh7uh H2wJNLJnvtkJu/4QoPGx3AvgiLquC52m r3PFFcD6ZPC1iqKRieLqEfyH0B8iS1Oq iADBUjdLC1e5mKsEc+bwb5P5heaWdu6g FrhoPPL98QtswwXFfsmhOwoQomplIDlu gNLUyCjfvCSjX6raEKbuBn6pn65OlT4s sZh6nCT9YOYma5QL5FxFlaFzUfJn0qGQ 2k341M6sS6U84rhiFKWyRtSqShPzCnfB Q06Rcx47fabVpcUJ2rS1DE3jc9bIszeZ n8IK4TlxkkQ6CbaahKAUeXQ6iVdAEaZ8 Ut2XVbPlTnkCGbBQQbismw==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rootns. IN AAAA
+SECTION ANSWER
+rootns. 518400 IN AAAA 2001:503:ba3e::2:30
+rootns. 518400 IN RRSIG AAAA 8 1 518400 20171015000000 20171001000000 43863 . VfbolsQWe3CmwrnWRsdmx2k5gaQmSt7Q oKv6b11iLn+oY1gpQL9fz4YRU8z5HzTv XFvgtdLDnN/7jmo6ECgKU43ToOgRlNBv nu7FijQ0iBj34Lxl0D9geAJ12lakVHHG pbzokVSTVyIduoOhhMT5ZEPmQ3e3ru1B xArn4MFUH97cWnfFkGobDz+nas1Z9E0i kZ510rYpKB8MVyhO7l79txsxwK8Y/ut4 4jg6bfGTwTSk9ILWalsSMYy0CVkQHUgE Cm8MracEG7D8TTBWipvoT5WD/qA4usyx 7nXUeQH/wM5q/9U4iRY4Vf+1iPk3d6+h gK/MteVeDPZYTOS+IwzWVw==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. 1 IN TXT "it works"
+test. 1 IN RRSIG TXT 8 1 1 20171015000000 20171001000000 43863 . nkmiASU/GeSZEoCScItfXTCRJHCkCGsr fYarRDxNDH2hegzh2XHT2l/bEhDoaV+b gaPNVGg/nTcKsQ3zUKg9ufhnpSNE3tMd zlo5PPpPz/2+8hKrd4m7n8HwKilVaruk FC9pTCu46QzBCiz2TDj87ADf3vaamJVj iEmZQEiVu3TDUi1M3wjj6E7Pbl1i08AF ejYcYXex7gjen4kyQhLZ9CpxgdJb8n3U Z6eXRjBNo8r57XZr37vDGlVDcQB7w2sV APFsiQBNTQyY+t+B8T2AK3JPK7ipn08T gdqrO6XhkLalMZo5wF0UNmEHTOKznt+Q Rt1eEgUReLPxhWDz4tQnxA==
+ENTRY_END
+RANGE_END
+
+
+
+RANGE_BEGIN 20171011000000 20171020999999
+ ADDRESS 198.41.0.4
+ ADDRESS 2001:503:ba3e::2:30
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. IN SOA
+SECTION ANSWER
+. 86400 IN SOA rootns. you.test. 2017071100 1800 900 604800 86400
+. 86400 IN RRSIG SOA 8 0 86400 20171025000000 20171011000000 43863 . j84QURP9YH3d3RDmH+1/hTcF3oDAwQx6 1aorcrvDubtKljRL+fD/lPpdTDqa0IT8 tQv+N4AyHe2M/CguEoQLe7//Mckn0oxB 2fW8FRsXBg2ROroG3LHo1Fr7vMwJdT1u s+ybnUUO1yIwmC9WgDZ7X0alRtsV1kqB w18tcpsgoFR7S5pyO6iQ15nJCP9+dXNT 0OMIR6IF9jAxju39zSMHd8sx6WHvYgYK gEBpxHBqHspqupopbaDFvLGyYM5Sl1dQ KBI0HxVTPkL5xg36Ds9mK2AImWltHRMw oYdTOCvzrvXIH8U3z1gv38dMbvyHBKyE qCKQmG5bSdlYZEN56Ds9TA==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. IN DNSKEY
+SECTION ANSWER
+. 1814400 IN DNSKEY 256 3 8 AwEAAbS4LSbmieIk96i3AK8IEZXlLRdM YLoEp4QSRMrdtJ0VcZKsjHWF6g9Q50T/ 1XKBxY/+6j71//cFRi1cViqoNsPd3LEb txWa3Jx/1HBINOkAPdHMBc3SQQ5qEIar PObq98RLnQ22ske1xZtbzNRZogPNi7zM HwQ3GYf0sUVCnYTmv8en5yYfSh8mY9Ez 8okorK7UN2RlHx9B8S5DRtBphO61mSI8 MXRj91aC3iRTbYZndTWorVkj4UvCBBr9 qh7oNpRbprIvAmRzRK6IaxpYDS6iGtSq 05WbGRtQRXkngOzFZO1BBDHgj9Agtx2S HBxAKuX4wF+w8I8xO7m5z0MOIF0=
+. 1814400 IN DNSKEY 257 3 8 AwEAAcgeCFZiwMD0S6TVgSK3Ob/MKFo+ dHYeNgoOjxH3JoxV09WShBXID/LwKs/e sYAIzTOBB8Fu9IDoVuQe5prOEcGZRp6u zF7JLnqrgOzoaSPRmKsvXh8DfipA56qE AqNwYBCqzlbGIGjHOQ8t+Xonp4fSBYbN MLmh7o8+u55k7PxemKTCiAnY7Bjx0g3m J1HuFvQXDDdvyletuoS3NKqrkjqdOHRB 3p3GKrKgw+zVb05UEyotCEKjqqi+BOmg cm8rmUIeaNQREjxrUyr8/Ry67h5NJLfq LAqAnSePf1PyhQcl8XjGHXN7w1tLLyJu Gy5B3zLSW1P6jIjon77PSn+cXi0=
+. 1814400 IN DNSKEY 257 3 8 AwEAAfX4eSO5BEPXggvx4jL5HkEjbA+5 QD8Acnh4wOHNv/OJX4QhKnpoMDOrpp38 n0Rgcr8qZ0XUqiJWl8eEH//wrQDHoO5/ JHRmibVrcA6UqfhUa25D1BfeMtTgMCSS +W3/heB/YhyXOJtOdWDmJutDY1nfJUSK rF6XwBj4us7U5jvwXwq+l36AeI4q7I87 Std0GNgRdA6/cJtApPoGv/0oNE0iNTyu IBcAR+AeWu32+JavhTycmtMfZ+KOIShq uI9RHzChZ9yLikAT+gclJGLLlxIr6HDr SLChCG90/yvmc57dLn8qhRWRJtJeLT2V HSxeP7oREb6RSdkxET6OTf9GYHE=
+. 1209600 IN RRSIG DNSKEY 8 0 1814400 20171101000000 20171011000000 43306 . prNbOqQOWhxL1tTDnVFk0IiHBmFZfYGf L/1jC0gcC7r20aODKHGXsxzNfacx+ohB Jr1b8s5UOk9Y6L7R9FwYNDAGC8W80F1A qp7d6CKKAUcnmiGYLbr/YaxZa/dLRLSM MYxSbKjCu7dEtZPp1RHhn4Mm9F9LatdF wP+Gt/tsKM41Rp2yaev7MyzlQmzKeRuk q4+nOOlGoreVCxr7gTedX2aOAlU0dy7V 90UKkmoQT2/qG770n1nT6SZLO+3gzahJ 4qog+N4nj3v33YLVCep6sbQApQdrIScU cqCQLh8+b+ZZSwFQ5exS9EQ3Vn/Qq6Vv oHvvdgDhHN5it3hN+KwaAw==
+. 1209600 IN RRSIG DNSKEY 8 0 1814400 20171101000000 20171011000000 43863 . RnQlmuJYsevQtDCaROBK2EhRYg4a6VQU Mml2ACLppliraGaCYrZ3Md1QG2NYx3jv LrqYLXCPOL1gYTQ+cviT6vzltvPqaATB oZvqfoxTlv0Ue72SZixxFJpphv/KkxaI Amer++W3j24AcsYFJRtgMejjQAoZuoou GfYiF+STZKUv0atrfA+ff1Bccc8qPB8A fXW9W7VdAQj0oizKDUr2++XaAL7w06pl 9EEK50JhhFiQT7ycxJdwXwq1quQCxAYK hlGyOGcolAbSnyMMqSvAnuEmdQ4xViLn aA3qSlm+MwCAQof6CRZKQykMIubo2ADf qcjLwxIsiezhnFs2GPV1Tg==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. 518400 IN NS rootns.
+. 518400 IN RRSIG NS 8 0 518400 20171025000000 20171011000000 43863 . rpQpv1g2i6O3oeePRi5/rFU3IxV3mn5v fmHgrmx90DSrD+sIqJmZccH6HywkvB3/ oNsYlub6X6+ynHaKXLwjEcqF5W1Vx9+d 8mY7Bb5ncT8zICJA8ey4whQ53xaBZiMT NI0IsH49QfO9ni7oS2BXzZfzT3VJFbWW xTa/n2Ptw54IlODyiRWiZa6pmMPvSC0O 3CpxD2nKN4wbmR8CicyVfqbBzqlb4et7 z630ydAVMKnm9lZu3o5ILI+TzYww4dNO diUBUR3H4ui/U6x390S/ymdgn05PL+xs nHq1/yAjrbDLAKlgr7mxTnxUMXq+MIPR aMeR0WHZMjl1jZH22Cjz9Q==
+SECTION ADDITIONAL
+rootns. 518400 IN A 198.41.0.4
+rootns. 518400 IN AAAA 2001:503:ba3e::2:30
+rootns. 518400 IN RRSIG A 8 1 518400 20171025000000 20171011000000 43863 . DhvuKaow+/abfok7XV/keFr6vx/5OBV4 P1k9XtNmg9BZ3E+7NRvyJUWj8MEqAKYX GhVbVU8L7ByLVOC7GBzpuJg1Ics8vP/H 5vSXJGfc4C1gGnPt2SvhcPrWTNKdFsT6 PnO7J7YWNzCJOvbNkT398vi20nZTF7Wq V8XDEr6sg50X5b3BqAncvnj2ZzIC9ONg InX0F/R1CxUS84DAitqHmwRpZ5Ci215G 0Ho1LPPPe7ENzpLRAtGNVjmk0y08+/re TcqoRPxV+1puXvFDr7x2y1dwE7U/EL+i BIM+mZmDv57BrqilmaEASqk6JjBb3jxS 13m6pS4AK7x6kvlEtWp6bw==
+rootns. 518400 IN RRSIG AAAA 8 1 518400 20171025000000 20171011000000 43863 . A8wCWy4vpVHqbcBeHinc1gzt9ox6FcRo kSLwswv2SRCAgG/U9iyZHT9fI3K2EjRL VdQycBQrEdp7TiXx1kfFYqvBkgN4IDBr F72HNr47O00reAQs7TAy4E4rtiNkqS/Y 8TJ+ifvaMVJhUGTGzNPOBJcvSRag3Lf8 slr5m53ZM7Cqjt+lV0yF2OAlb85Mi1VM 7iW1gX+OAIu9i6pxbDyJy7HKI6RVvZ/C 5f0dYlBz6WMEfT7CQ1ai21y6hrMZZMAv wRO6msou52aSfpcs9Gt56R8TJ8ZAG4mx wHSDJESBEL8HZPrnwDTUkgWtgMasvLa1 7Y9b4J0QfyWKFJqF9qCAJg==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rootns. IN NS
+SECTION AUTHORITY
+. 86400 IN SOA rootns. you.test. 2017071100 1800 900 604800 86400
+rootns. 86400 IN NSEC test. A AAAA RRSIG NSEC
+. 86400 IN RRSIG SOA 8 0 86400 20171025000000 20171011000000 43863 . j84QURP9YH3d3RDmH+1/hTcF3oDAwQx6 1aorcrvDubtKljRL+fD/lPpdTDqa0IT8 tQv+N4AyHe2M/CguEoQLe7//Mckn0oxB 2fW8FRsXBg2ROroG3LHo1Fr7vMwJdT1u s+ybnUUO1yIwmC9WgDZ7X0alRtsV1kqB w18tcpsgoFR7S5pyO6iQ15nJCP9+dXNT 0OMIR6IF9jAxju39zSMHd8sx6WHvYgYK gEBpxHBqHspqupopbaDFvLGyYM5Sl1dQ KBI0HxVTPkL5xg36Ds9mK2AImWltHRMw oYdTOCvzrvXIH8U3z1gv38dMbvyHBKyE qCKQmG5bSdlYZEN56Ds9TA==
+rootns. 86400 IN RRSIG NSEC 8 1 86400 20171025000000 20171011000000 43863 . V7uXPeHovcCZXfST0psQLPNfg22S1Kq2 Vzk5wihwlwIAhAYOjVDFvFhItZzf9yQ3 WYzJXfDOh4oy8bb2WKMJkOTlA+5q78cX 6iWlp3eqx57Vs6J7n+FlvO4mVdod372+ yRh2XhjKwfTK58dhSm70cTtVP4wxcQ5d ZjPvhK79LJuHU8WbrputA0W9BSv/in3L amf+wYEsKEMEKZC1bsMBPWLDdlUyjaHQ mqxR+UxODtAzl1JLXo1T3dNKeqspbIZU IEhcKSUuFGF4sqYPhPh77wc5cD4jXJcY /qgSDvjUtiK1cyFDhw4JWK/rRsisxgt0 +wIN8FVVt0TCCZFVmC6BfA==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rootns. IN A
+SECTION ANSWER
+rootns. 518400 IN A 198.41.0.4
+rootns. 518400 IN RRSIG A 8 1 518400 20171025000000 20171011000000 43863 . DhvuKaow+/abfok7XV/keFr6vx/5OBV4 P1k9XtNmg9BZ3E+7NRvyJUWj8MEqAKYX GhVbVU8L7ByLVOC7GBzpuJg1Ics8vP/H 5vSXJGfc4C1gGnPt2SvhcPrWTNKdFsT6 PnO7J7YWNzCJOvbNkT398vi20nZTF7Wq V8XDEr6sg50X5b3BqAncvnj2ZzIC9ONg InX0F/R1CxUS84DAitqHmwRpZ5Ci215G 0Ho1LPPPe7ENzpLRAtGNVjmk0y08+/re TcqoRPxV+1puXvFDr7x2y1dwE7U/EL+i BIM+mZmDv57BrqilmaEASqk6JjBb3jxS 13m6pS4AK7x6kvlEtWp6bw==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rootns. IN AAAA
+SECTION ANSWER
+rootns. 518400 IN AAAA 2001:503:ba3e::2:30
+rootns. 518400 IN RRSIG AAAA 8 1 518400 20171025000000 20171011000000 43863 . A8wCWy4vpVHqbcBeHinc1gzt9ox6FcRo kSLwswv2SRCAgG/U9iyZHT9fI3K2EjRL VdQycBQrEdp7TiXx1kfFYqvBkgN4IDBr F72HNr47O00reAQs7TAy4E4rtiNkqS/Y 8TJ+ifvaMVJhUGTGzNPOBJcvSRag3Lf8 slr5m53ZM7Cqjt+lV0yF2OAlb85Mi1VM 7iW1gX+OAIu9i6pxbDyJy7HKI6RVvZ/C 5f0dYlBz6WMEfT7CQ1ai21y6hrMZZMAv wRO6msou52aSfpcs9Gt56R8TJ8ZAG4mx wHSDJESBEL8HZPrnwDTUkgWtgMasvLa1 7Y9b4J0QfyWKFJqF9qCAJg==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. 1 IN TXT "it works"
+test. 1 IN RRSIG TXT 8 1 1 20171025000000 20171011000000 43863 . jou6HluOgT2jv6k74V4tJZcstOdYnTl4 kWV+x4NZbYYCNrVoeNf91yeX45ABSIB1 PZZppw9aR27m6GiOqQ9I6jSWmpVV99Cy u6KbsK52xc21S4dVhamv47wz8o82JtqY FPYz2GhidDKezf944ggoti2lTteeZl+M zbxpEq5Oq/9138wawGEePBuWsMp/ObNe FQycIfICMkm7Ng0qww/0jiwQB2LvYvak x6O1c4C45AYOsHt5U3DFu1XVbqDQKC/i WW2LOdn+RD94QRudjFxt1AVyn0UA55KP sUuoZq4eBQLY3Tp0QQPn/5XAhrT+iA41 PaBL/0kuNyhygHm+pmi7Cg==
+ENTRY_END
+RANGE_END
+
+
+
+RANGE_BEGIN 20171021000000 20171030999999
+ ADDRESS 198.41.0.4
+ ADDRESS 2001:503:ba3e::2:30
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. IN SOA
+SECTION ANSWER
+. 86400 IN SOA rootns. you.test. 2017071100 1800 900 604800 86400
+. 86400 IN RRSIG SOA 8 0 86400 20171104000000 20171021000000 43863 . QooElIIDCY4Jam07Bii596BBCb2TiGUY TmbV60FaeBfBXWRkkT+mCuWe5PpBx3/A gdMbB2/OrvDi7CrGOehWyiT4gUkgAO37 BgVG0JEwEt5S4SOCDRz7lUgedB1KdoTw FhWTJDJSXZfQYVE3ksh9Chi+ySUaoPUk dEk6MTw4F1CEOMAXJ+ST9sG88kg6E+YY 00GmZGR32ALaCx07FOaUE6JESbhRdF92 6NlS+VVMGw/v5B0lxvlyneQJWZ4mBDGL MxvNhwwC6ElwJBO09sgg1UOP18A1zpkn dSInPzXP+qS+P63QuUlFuE+1DhfNP4WW 7ISPuytZyMIVSGB9b7igUA==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. IN DNSKEY
+SECTION ANSWER
+. 1814400 IN DNSKEY 256 3 8 AwEAAbS4LSbmieIk96i3AK8IEZXlLRdM YLoEp4QSRMrdtJ0VcZKsjHWF6g9Q50T/ 1XKBxY/+6j71//cFRi1cViqoNsPd3LEb txWa3Jx/1HBINOkAPdHMBc3SQQ5qEIar PObq98RLnQ22ske1xZtbzNRZogPNi7zM HwQ3GYf0sUVCnYTmv8en5yYfSh8mY9Ez 8okorK7UN2RlHx9B8S5DRtBphO61mSI8 MXRj91aC3iRTbYZndTWorVkj4UvCBBr9 qh7oNpRbprIvAmRzRK6IaxpYDS6iGtSq 05WbGRtQRXkngOzFZO1BBDHgj9Agtx2S HBxAKuX4wF+w8I8xO7m5z0MOIF0=
+. 1814400 IN DNSKEY 257 3 8 AwEAAcgeCFZiwMD0S6TVgSK3Ob/MKFo+ dHYeNgoOjxH3JoxV09WShBXID/LwKs/e sYAIzTOBB8Fu9IDoVuQe5prOEcGZRp6u zF7JLnqrgOzoaSPRmKsvXh8DfipA56qE AqNwYBCqzlbGIGjHOQ8t+Xonp4fSBYbN MLmh7o8+u55k7PxemKTCiAnY7Bjx0g3m J1HuFvQXDDdvyletuoS3NKqrkjqdOHRB 3p3GKrKgw+zVb05UEyotCEKjqqi+BOmg cm8rmUIeaNQREjxrUyr8/Ry67h5NJLfq LAqAnSePf1PyhQcl8XjGHXN7w1tLLyJu Gy5B3zLSW1P6jIjon77PSn+cXi0=
+. 1814400 IN DNSKEY 257 3 8 AwEAAfX4eSO5BEPXggvx4jL5HkEjbA+5 QD8Acnh4wOHNv/OJX4QhKnpoMDOrpp38 n0Rgcr8qZ0XUqiJWl8eEH//wrQDHoO5/ JHRmibVrcA6UqfhUa25D1BfeMtTgMCSS +W3/heB/YhyXOJtOdWDmJutDY1nfJUSK rF6XwBj4us7U5jvwXwq+l36AeI4q7I87 Std0GNgRdA6/cJtApPoGv/0oNE0iNTyu IBcAR+AeWu32+JavhTycmtMfZ+KOIShq uI9RHzChZ9yLikAT+gclJGLLlxIr6HDr SLChCG90/yvmc57dLn8qhRWRJtJeLT2V HSxeP7oREb6RSdkxET6OTf9GYHE=
+. 1209600 IN RRSIG DNSKEY 8 0 1814400 20171111000000 20171021000000 43306 . shYCeDVHCCBc+HDxr3Sdl1IlnbqpqR+P BDt1j8U37iGqHMfa9tAHUtUU5a2hlDbY N7xBPA2ZWJwksW1MGhgJO9bDrK0Pi1MH mfk1S2shqOmz8Z2VrDaO+RWzxDDh/b0R 0tVrcVrYOPR7C2QD0tsjhxDFZlE2TC9I 6WIXllAjOckxVqKidjzbKmOGgvlNHYJg uU333Tg+clWLlJVTghwHsTe7lZ6BiVqS 7frKNg2CaJg/XKkqH8mNkiAjfc8hc4Wo Yr3fDklX5p9leylrkq8TIYA6jTHK/v/d wUpK7mevN3PViuB+CSmqIGyHRTqbajBl euN9iRNAAaAHGyXo5jqqkQ==
+. 1209600 IN RRSIG DNSKEY 8 0 1814400 20171111000000 20171021000000 43863 . Yz7jMz1gE04oN+qZgNTiWABeemxA5+V1 QkWcIVvHqGOHzoFllKVIGoKu5MqEINXQ qJ3Mta5stkDHHQqbSGVAf1zwZwt/rJ/7 37Vi+dfP7rVyhRiyqr7blXQU9aOGXirK mDl9QyiTos3O3XJzu62Tlf1KeotOa0bO UAKN/Fo3u/9qLQT1KAQ0mmcuE2hmXE9f 1oJgmL7C2cduMhPIy9BbpSuF1KEWwO0J KrXggSwVV2Sj5C/LAHuAQOzDjPIhsQQw sYGiZLnY2A7GIm9jNfFrlidrgM9awNvK O1k2owB+Ocf1n0GIMsq9d/PkFdqfrDh3 rL/fjtbcHoWnvAK+ZGeXAw==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. 518400 IN NS rootns.
+. 518400 IN RRSIG NS 8 0 518400 20171104000000 20171021000000 43863 . fINfuCHxhSG/AkiA0+qA+9XixCDk0vRD W75jOQdvgrSCb5KpGcYCEYUTf4gmKB3A 9uxkTkLnozBXRr0RiYY9Cyzm4bWgyMo3 5QIY/zr78Ovtw4/DHobM3Pi2ZJuXPSk2 HfOs8paP9xoFvc+56oU4C/uGdbb2c45G Fenet3RDZEIEIWODChQn6Fr6Nf4NTrQV Y7oMggzDnNXpjUPHwcywzuBsd55D3rJc 80IwMGvaXzIh9pjth/i92WfiVk01pfM0 B9+uBQAjeF7VQXVH9iTpdiErm6jX0fUD M46wZQQgW63q81lGGeXgyU5QU/KchqL2 ZdwOUGJzIFWLZIh9C0efdQ==
+SECTION ADDITIONAL
+rootns. 518400 IN A 198.41.0.4
+rootns. 518400 IN AAAA 2001:503:ba3e::2:30
+rootns. 518400 IN RRSIG A 8 1 518400 20171104000000 20171021000000 43863 . o9EjGTFdfjfKCsZ2gd++IKzw1PjLeOLN 9ImHCTfPt228hOIToC46/JC5kNlFUpbT 5ojeEBqgQYHASBk9iSrOIBTL6m4aFReJ a+dl+xWHc9+hAXi/7ygZBrQ+FHQ9rF7t wIHn+EQPCjw29yxxgyUGsOE7mbeU3BX3 +EbPIdxxsldq3lasHPPOQVJPazxAVMa8 PTZhNMTzVg2s2yxwZjHfyINwkR0SyUub bEW9g47U1c0vspJi+1gsjfq9Rls3Tzta cIk6n7vICYx9lrGEUrBGktO2ODtiOdXu ffL0z/zOVl8e3rzNRm/PRzyWpQvIqis8 3ehJq7S1OaNV7XqE9oetdg==
+rootns. 518400 IN RRSIG AAAA 8 1 518400 20171104000000 20171021000000 43863 . jIFv95ONRDAGEW5HuwBA5wC+vIRb6p7u mTuDoY3IgJPP1etrVi7bf/HlTL9Y/6O3 DXrqq+WaBN0MC7unImWssydpMHN/3U8e HDPybfeHC+XqoRLnz0TJ3Ue24tuzEU5Q LyqumAHyfeEAdIdIIff+RKqTLoGbY3+j W8zBsXbWe5c4yc5ywiGcheCIuJXzJEQf vxFtdyHdkoWgNkK8P8h5SVhZiocWOjnM pjbxVOnehVJtqBfwCQNGU+0ZuSlUUD9D EG0U7D5K5VndP9ccyEhPk9nLc37cp9Ho PRmxPb0y7nW+4L0oW82veAz4XFab+lYM 0oiRDz3Oytrxp1dwUATC6A==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rootns. IN NS
+SECTION AUTHORITY
+. 86400 IN SOA rootns. you.test. 2017071100 1800 900 604800 86400
+rootns. 86400 IN NSEC test. A AAAA RRSIG NSEC
+. 86400 IN RRSIG SOA 8 0 86400 20171104000000 20171021000000 43863 . QooElIIDCY4Jam07Bii596BBCb2TiGUY TmbV60FaeBfBXWRkkT+mCuWe5PpBx3/A gdMbB2/OrvDi7CrGOehWyiT4gUkgAO37 BgVG0JEwEt5S4SOCDRz7lUgedB1KdoTw FhWTJDJSXZfQYVE3ksh9Chi+ySUaoPUk dEk6MTw4F1CEOMAXJ+ST9sG88kg6E+YY 00GmZGR32ALaCx07FOaUE6JESbhRdF92 6NlS+VVMGw/v5B0lxvlyneQJWZ4mBDGL MxvNhwwC6ElwJBO09sgg1UOP18A1zpkn dSInPzXP+qS+P63QuUlFuE+1DhfNP4WW 7ISPuytZyMIVSGB9b7igUA==
+rootns. 86400 IN RRSIG NSEC 8 1 86400 20171104000000 20171021000000 43863 . azjrdB6MPXt1MBU4N24js2WxcHllrqPZ NCTkEJXqHgdTrkUIHwkaNvIqbqpPQEfk 3KSmVzelKQ+IvQyi++skRUJdXgo8AQ// iM5P06RoNjIorjMCnF+ttYK6LCy7Sk0A d/r+nYsn+uVU6WF8/SKzb4CXntv/pIDr 4qdIF5zt0W3ear2/m0q8k0ET0abncL3U QJKU/1y9IC3Xe9L4z8Ivp8h1pQk0+kda TW7RYNao4O+XOsT5FFARvLCRUIu+J2yC NUwqa9qmfwd2a0HFxQ5xmCAD6sH7n5gp isEBlg6lp7RpuqzgMpQU4PzbH/yQ6XJj huU2sB4zkYogd5F1f0b1sw==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rootns. IN A
+SECTION ANSWER
+rootns. 518400 IN A 198.41.0.4
+rootns. 518400 IN RRSIG A 8 1 518400 20171104000000 20171021000000 43863 . o9EjGTFdfjfKCsZ2gd++IKzw1PjLeOLN 9ImHCTfPt228hOIToC46/JC5kNlFUpbT 5ojeEBqgQYHASBk9iSrOIBTL6m4aFReJ a+dl+xWHc9+hAXi/7ygZBrQ+FHQ9rF7t wIHn+EQPCjw29yxxgyUGsOE7mbeU3BX3 +EbPIdxxsldq3lasHPPOQVJPazxAVMa8 PTZhNMTzVg2s2yxwZjHfyINwkR0SyUub bEW9g47U1c0vspJi+1gsjfq9Rls3Tzta cIk6n7vICYx9lrGEUrBGktO2ODtiOdXu ffL0z/zOVl8e3rzNRm/PRzyWpQvIqis8 3ehJq7S1OaNV7XqE9oetdg==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rootns. IN AAAA
+SECTION ANSWER
+rootns. 518400 IN AAAA 2001:503:ba3e::2:30
+rootns. 518400 IN RRSIG AAAA 8 1 518400 20171104000000 20171021000000 43863 . jIFv95ONRDAGEW5HuwBA5wC+vIRb6p7u mTuDoY3IgJPP1etrVi7bf/HlTL9Y/6O3 DXrqq+WaBN0MC7unImWssydpMHN/3U8e HDPybfeHC+XqoRLnz0TJ3Ue24tuzEU5Q LyqumAHyfeEAdIdIIff+RKqTLoGbY3+j W8zBsXbWe5c4yc5ywiGcheCIuJXzJEQf vxFtdyHdkoWgNkK8P8h5SVhZiocWOjnM pjbxVOnehVJtqBfwCQNGU+0ZuSlUUD9D EG0U7D5K5VndP9ccyEhPk9nLc37cp9Ho PRmxPb0y7nW+4L0oW82veAz4XFab+lYM 0oiRDz3Oytrxp1dwUATC6A==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. 1 IN TXT "it works"
+test. 1 IN RRSIG TXT 8 1 1 20171104000000 20171021000000 43863 . R0doO41QT7TCbRhaJNymCye+QTEbSMKY XPE/hp62sZm4zQaXuALDdMz9L+4dyDJ0 sp0HK+1hiLZQeWxG36gPMXcsfBB63wlv 4yWyqJWlzbRMJjI60BAhqaYDVz/6x3gi Y1zgzWtw0NFcrXJLysS5a8JCzAWMqW9b IITITWqz8Cv6WA9qqSxHI7HdQkbSg+0t LWq0hECZmRsZUrJviqCRs7Mf2rQyNKBE 8637RRq8MFBW3GKuK6Z3eXSn3fLsbWQd 3Mvcr8lmBAtlpvbZw4JZdvL9xwhqxMBr 5kkHL1zeGVJx/8ibrXZTMvlEcrwNV5ap 1fjJ8Ecu7o/Bits0jYC3Lg==
+ENTRY_END
+RANGE_END
+
+
+
+RANGE_BEGIN 20171031000000 20171109999999
+ ADDRESS 198.41.0.4
+ ADDRESS 2001:503:ba3e::2:30
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. IN SOA
+SECTION ANSWER
+. 86400 IN SOA rootns. you.test. 2017071100 1800 900 604800 86400
+. 86400 IN RRSIG SOA 8 0 86400 20171114000000 20171031000000 43863 . pDeid0DvLx90cUWzAnUqCLV8XehmC5Ks VyGws6GCHwW4m8/9E8XXKcQFMVITO2yn MbOeIFs/OXMG+TnOuJfckXAyais6/TxO iiQg22r1ZdlZtv3szzoirJl4/+HXqCuU dm6esFje5djjrwAW82dHkt/FTu+Kly5x 0pwltZ2Qz2JvlIypExZoI6OxedNsv2v8 IMllSsTEJ2/w28ALGNvpyTN/LAX0cP1z IAOHd5r3UMraMS9CyRqVXNESj3g2Mhpi JM51+funl5ZEE8s4TzYjuqeQqP92jWfZ 6ViiK6sKGcM63+TRMVLW8DE07YDHREu0 JUsSPwtrD4hpHbfXSIiNEQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. IN DNSKEY
+SECTION ANSWER
+. 1814400 IN DNSKEY 256 3 8 AwEAAbS4LSbmieIk96i3AK8IEZXlLRdM YLoEp4QSRMrdtJ0VcZKsjHWF6g9Q50T/ 1XKBxY/+6j71//cFRi1cViqoNsPd3LEb txWa3Jx/1HBINOkAPdHMBc3SQQ5qEIar PObq98RLnQ22ske1xZtbzNRZogPNi7zM HwQ3GYf0sUVCnYTmv8en5yYfSh8mY9Ez 8okorK7UN2RlHx9B8S5DRtBphO61mSI8 MXRj91aC3iRTbYZndTWorVkj4UvCBBr9 qh7oNpRbprIvAmRzRK6IaxpYDS6iGtSq 05WbGRtQRXkngOzFZO1BBDHgj9Agtx2S HBxAKuX4wF+w8I8xO7m5z0MOIF0=
+. 1814400 IN DNSKEY 257 3 8 AwEAAcgeCFZiwMD0S6TVgSK3Ob/MKFo+ dHYeNgoOjxH3JoxV09WShBXID/LwKs/e sYAIzTOBB8Fu9IDoVuQe5prOEcGZRp6u zF7JLnqrgOzoaSPRmKsvXh8DfipA56qE AqNwYBCqzlbGIGjHOQ8t+Xonp4fSBYbN MLmh7o8+u55k7PxemKTCiAnY7Bjx0g3m J1HuFvQXDDdvyletuoS3NKqrkjqdOHRB 3p3GKrKgw+zVb05UEyotCEKjqqi+BOmg cm8rmUIeaNQREjxrUyr8/Ry67h5NJLfq LAqAnSePf1PyhQcl8XjGHXN7w1tLLyJu Gy5B3zLSW1P6jIjon77PSn+cXi0=
+. 1814400 IN DNSKEY 257 3 8 AwEAAfX4eSO5BEPXggvx4jL5HkEjbA+5 QD8Acnh4wOHNv/OJX4QhKnpoMDOrpp38 n0Rgcr8qZ0XUqiJWl8eEH//wrQDHoO5/ JHRmibVrcA6UqfhUa25D1BfeMtTgMCSS +W3/heB/YhyXOJtOdWDmJutDY1nfJUSK rF6XwBj4us7U5jvwXwq+l36AeI4q7I87 Std0GNgRdA6/cJtApPoGv/0oNE0iNTyu IBcAR+AeWu32+JavhTycmtMfZ+KOIShq uI9RHzChZ9yLikAT+gclJGLLlxIr6HDr SLChCG90/yvmc57dLn8qhRWRJtJeLT2V HSxeP7oREb6RSdkxET6OTf9GYHE=
+. 1209600 IN RRSIG DNSKEY 8 0 1814400 20171121000000 20171031000000 43306 . V9PYEXyiskggl3JXqBuvAqgp4v6yQaJS swlbgCQSS84BI+nuJ+QgSpaRj89OS3rt We5VXJRe6OP4uD0bgfqggv8u4nLvjGcn bM/UWNb/u+cE5d7sX4P7/ANkSAHBiSC2 VVMwIYJwfQD//t+vMhZ1rjicX2S/p7tg zCn0VqG2RD8m2ZM2QfUrMWFB/hbVOftL TduQpPEy9N4GPo0VDOpZQ/Qn9/VcQIEu yVk0TRHkrCtkYEG7pngWKgyxQF3rVN+P enVrMuEVOdBjKImqDVvsgcvBSqgx5i82 BQkI2b1QvwKOj5QM2qSX38bNqpuTrkpR RgJV8DG7tI6ocHcEPtA0Zg==
+. 1209600 IN RRSIG DNSKEY 8 0 1814400 20171121000000 20171031000000 43863 . N1IXPtQQvfwqYmVPM4fWqewZjn9JXrav C88m44i6ng6UNIawuFC89Wy9eU7JrCxZ mgCCfBWfQUAS1MCj8J/AERRhm5Q6Wgy3 RCDKgsPO2ZmIfDELXd63e3VY6xUcjFOA 6eb5OuMeiL5yKL7EmPm7veIb5ggVWHj3 ViQTxICYpxiDdZqg03gtXSLrRObVLCi1 8We1RYsPbA2PgXbmHSgbV9P5ThVsla/C FAbynsOllBdefqrKtlQVBYwfHpZDkBKG 4DFkZgh8ugePcC4hF6zLajAH7ql8T9Jx ENQCZdlqkym4M2HUH0RWj74zR9qdaBix HpR27cnmMDhj5nkR/7Nyjg==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. 518400 IN NS rootns.
+. 518400 IN RRSIG NS 8 0 518400 20171114000000 20171031000000 43863 . KSnCPuiaTPZcw68L4x8jKg9Y3pABRzI8 yF7d0E/HFjXCp78Ika/qeD+AMKOhmgnr 5FbqeKQ+lw+M4ir81i4/GviGvovAu/ak 1M8+n8bTqfeoh071+xaOWP2orJIMCgH2 rdNaU8wJ5DdAmiT/wjWU4KqR1ghnTFaa GGSsWhbuECzbmxilgDN1Nm183w8g5B+B 0dAPNDXQd9oOeYIFb7lKnB/cbJtftgGJ Kmt8DEerfW3j4OKtcLKfvsk+bVRu5yPu /Vfz2yV6hqcIXguwTv5cswiy6gzPx7mB kjG6eiW9+WwoJBZoqkUZ2z7T8sUDDc1U Qodd9HG1pQL1iQBw6D5rlg==
+SECTION ADDITIONAL
+rootns. 518400 IN A 198.41.0.4
+rootns. 518400 IN AAAA 2001:503:ba3e::2:30
+rootns. 518400 IN RRSIG A 8 1 518400 20171114000000 20171031000000 43863 . Q2f22oIR9AT33oXvIJLO0dfO3wtMXp7W J9HVugc4XkY2unjuFjX5zsdTsx7UiVwp eGF8EFaRXo7LFQUdu2mqZN1dh/V44srC e5GGDsWrjJUXYZZbXxVGMni3RQNCzRgf 6o9zTJhl0Q/uQVjbRz3720J7C6dZY8ph qxt9cPuf2w6o5I7suCjFKGbdMm7X35Fb m2Hm52mKMdtWRfCpFSp7rLymINnJYyiP 7m5k+2LryfzX7/LUGKBQdaKB5eYysnss U6S0gMLNhCeDM0vBQeGKGa83WV2G1VAo 0jxySyFZJAWH54MJh65X8WiSz5tM/gZE FxfeQmnSJATDPzz+muWROw==
+rootns. 518400 IN RRSIG AAAA 8 1 518400 20171114000000 20171031000000 43863 . K336HxxLMygdaKlNABZQ1KTmVLCdFtCO iJSoarH3+hDnk5bJ9oPNcFP3F9maVomj KXkLCbOYu36w9OwsY2nSqkYef+lwiRH5 5S3ngGo71uQG4lyvX9xGO6/KDjhFdlwA TptdlemBNtbAa2AwHI/xXTNLeM/I17Yo 4l8z8lztKZSoQynBio09jk3tsw8b1E8c Vvbodg+JoLrIRY+7yHsfxZ5CASCtxpnp Re3UV/6OEZqnbdI5Z2kxBTzGPBY7MpYF S0rLRL3uiNaTRUtngfiGXiSvbM1jynQg wM9v3LwfuDyL+DWHyuJV6Zg9Nvs5EVZH PsgSbYKGjD0dRFtK0kUFqw==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rootns. IN NS
+SECTION AUTHORITY
+. 86400 IN SOA rootns. you.test. 2017071100 1800 900 604800 86400
+rootns. 86400 IN NSEC test. A AAAA RRSIG NSEC
+. 86400 IN RRSIG SOA 8 0 86400 20171114000000 20171031000000 43863 . pDeid0DvLx90cUWzAnUqCLV8XehmC5Ks VyGws6GCHwW4m8/9E8XXKcQFMVITO2yn MbOeIFs/OXMG+TnOuJfckXAyais6/TxO iiQg22r1ZdlZtv3szzoirJl4/+HXqCuU dm6esFje5djjrwAW82dHkt/FTu+Kly5x 0pwltZ2Qz2JvlIypExZoI6OxedNsv2v8 IMllSsTEJ2/w28ALGNvpyTN/LAX0cP1z IAOHd5r3UMraMS9CyRqVXNESj3g2Mhpi JM51+funl5ZEE8s4TzYjuqeQqP92jWfZ 6ViiK6sKGcM63+TRMVLW8DE07YDHREu0 JUsSPwtrD4hpHbfXSIiNEQ==
+rootns. 86400 IN RRSIG NSEC 8 1 86400 20171114000000 20171031000000 43863 . fAkq3vxra8l/AN3x8kt8XYT0wXpPdESj M7FR7EKFAPCFL2BAelt3Hkfj+HPKqgCO 78iVXdIDfiFTzTIqG9JbUWtpTJF08P9R 76qFPoRRJ1vrmLC5d9LW5OG5MgGcFkQT OkKNN0LbKiE76W31f7ZFuFTZOHo/RJ1K vMG/ls0F+k29ZZHtyktLqr6tD5kkKJ6m QopzlejJTBkeFSHqQGFuJ/v76uSySa67 31cK0YiAYgIJBKmUP2cZu3jalYJ0JaTv eAJObpg/t2n0aKdclJHL/+2neqVCqTvw PYJ/eDYK/r2i8mioviysNOM8BKv2v3PO SBpKfaQ4P0tadHmqimZL4g==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rootns. IN A
+SECTION ANSWER
+rootns. 518400 IN A 198.41.0.4
+rootns. 518400 IN RRSIG A 8 1 518400 20171114000000 20171031000000 43863 . Q2f22oIR9AT33oXvIJLO0dfO3wtMXp7W J9HVugc4XkY2unjuFjX5zsdTsx7UiVwp eGF8EFaRXo7LFQUdu2mqZN1dh/V44srC e5GGDsWrjJUXYZZbXxVGMni3RQNCzRgf 6o9zTJhl0Q/uQVjbRz3720J7C6dZY8ph qxt9cPuf2w6o5I7suCjFKGbdMm7X35Fb m2Hm52mKMdtWRfCpFSp7rLymINnJYyiP 7m5k+2LryfzX7/LUGKBQdaKB5eYysnss U6S0gMLNhCeDM0vBQeGKGa83WV2G1VAo 0jxySyFZJAWH54MJh65X8WiSz5tM/gZE FxfeQmnSJATDPzz+muWROw==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rootns. IN AAAA
+SECTION ANSWER
+rootns. 518400 IN AAAA 2001:503:ba3e::2:30
+rootns. 518400 IN RRSIG AAAA 8 1 518400 20171114000000 20171031000000 43863 . K336HxxLMygdaKlNABZQ1KTmVLCdFtCO iJSoarH3+hDnk5bJ9oPNcFP3F9maVomj KXkLCbOYu36w9OwsY2nSqkYef+lwiRH5 5S3ngGo71uQG4lyvX9xGO6/KDjhFdlwA TptdlemBNtbAa2AwHI/xXTNLeM/I17Yo 4l8z8lztKZSoQynBio09jk3tsw8b1E8c Vvbodg+JoLrIRY+7yHsfxZ5CASCtxpnp Re3UV/6OEZqnbdI5Z2kxBTzGPBY7MpYF S0rLRL3uiNaTRUtngfiGXiSvbM1jynQg wM9v3LwfuDyL+DWHyuJV6Zg9Nvs5EVZH PsgSbYKGjD0dRFtK0kUFqw==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. 1 IN TXT "it works"
+test. 1 IN RRSIG TXT 8 1 1 20171114000000 20171031000000 43863 . GBgRHIHToQAAAn8VfGAPZwEO7YsOr0Kq wHtKcBlSdbj5y76sz/gfd0BE4ApyzCbL qo/RwOk/oxmTa7C/h2mRx6CXBzgLB317 LmAZWfm+/FxRZrHeaoH9/bTGeiwbhFJe aoq9wYa9D9oYBTUM+z9GFh72MHEc0Udd 7pPH+mEYdWO08h2Sx1lRpoi/ktLeH3Su y6ti1BNiH1pk9dm0JKduxmrlUTfmWmAv sWxTJihr71coNRHXXPavoH1nyKfc1rWc fmtrasozpZh1ddmcXn4YZAyxD/BZr2Vw 0GA+lcchfsRII3dPAOS2mz/XZoZxguf6 DEhdlERVGfmAOR2iyE9XZQ==
+ENTRY_END
+RANGE_END
+
+
+
+RANGE_BEGIN 20171110000000 20171119999999
+ ADDRESS 198.41.0.4
+ ADDRESS 2001:503:ba3e::2:30
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. IN SOA
+SECTION ANSWER
+. 86400 IN SOA rootns. you.test. 2017071100 1800 900 604800 86400
+. 86400 IN RRSIG SOA 8 0 86400 20171124000000 20171110000000 43863 . Kg/cVNP2kAPJa/Tv5d3X8pPpq/oZgdh7 8NzEhZN7ZeHCcI39r4f6e40RdUGNzLI5 k2bZa9ncfCfA0au1s24Ctxl207X1ZDZ3 Q0jRIz6XgP3wI0ZoEzZwYbaBv0Tpuhr3 0Wg6nU2KJZ0avRhahKVAzmj164+JbFQg yDN+dOj0npJ45vdnK9kwos9ymdC/c6Ae uXgHoF188EpTs7xTtImBvNVQwONrduNs qkKfpsl+V1PdFl1f1NWDzzMrwKYGCyBt 3idLeRkqWODb0r1O3m8B7hrZnk5ASsRJ ERDMLIrfZvw91lYcSVzgV+GL++hG8oc+ 8pq68C1rJjBBHeqNodbHmQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. IN DNSKEY
+SECTION ANSWER
+. 1814400 IN DNSKEY 256 3 8 AwEAAbS4LSbmieIk96i3AK8IEZXlLRdM YLoEp4QSRMrdtJ0VcZKsjHWF6g9Q50T/ 1XKBxY/+6j71//cFRi1cViqoNsPd3LEb txWa3Jx/1HBINOkAPdHMBc3SQQ5qEIar PObq98RLnQ22ske1xZtbzNRZogPNi7zM HwQ3GYf0sUVCnYTmv8en5yYfSh8mY9Ez 8okorK7UN2RlHx9B8S5DRtBphO61mSI8 MXRj91aC3iRTbYZndTWorVkj4UvCBBr9 qh7oNpRbprIvAmRzRK6IaxpYDS6iGtSq 05WbGRtQRXkngOzFZO1BBDHgj9Agtx2S HBxAKuX4wF+w8I8xO7m5z0MOIF0=
+. 1814400 IN DNSKEY 257 3 8 AwEAAcgeCFZiwMD0S6TVgSK3Ob/MKFo+ dHYeNgoOjxH3JoxV09WShBXID/LwKs/e sYAIzTOBB8Fu9IDoVuQe5prOEcGZRp6u zF7JLnqrgOzoaSPRmKsvXh8DfipA56qE AqNwYBCqzlbGIGjHOQ8t+Xonp4fSBYbN MLmh7o8+u55k7PxemKTCiAnY7Bjx0g3m J1HuFvQXDDdvyletuoS3NKqrkjqdOHRB 3p3GKrKgw+zVb05UEyotCEKjqqi+BOmg cm8rmUIeaNQREjxrUyr8/Ry67h5NJLfq LAqAnSePf1PyhQcl8XjGHXN7w1tLLyJu Gy5B3zLSW1P6jIjon77PSn+cXi0=
+. 1814400 IN DNSKEY 257 3 8 AwEAAfX4eSO5BEPXggvx4jL5HkEjbA+5 QD8Acnh4wOHNv/OJX4QhKnpoMDOrpp38 n0Rgcr8qZ0XUqiJWl8eEH//wrQDHoO5/ JHRmibVrcA6UqfhUa25D1BfeMtTgMCSS +W3/heB/YhyXOJtOdWDmJutDY1nfJUSK rF6XwBj4us7U5jvwXwq+l36AeI4q7I87 Std0GNgRdA6/cJtApPoGv/0oNE0iNTyu IBcAR+AeWu32+JavhTycmtMfZ+KOIShq uI9RHzChZ9yLikAT+gclJGLLlxIr6HDr SLChCG90/yvmc57dLn8qhRWRJtJeLT2V HSxeP7oREb6RSdkxET6OTf9GYHE=
+. 1209600 IN RRSIG DNSKEY 8 0 1814400 20171201000000 20171110000000 43306 . TFUGDmiPAAixO77X5cFmU3Sx5eeMIdR3 8x3+fNGKkx0Fk4ZYsqLqI3pcihF7iNCM aOVqVkQkBrvWGd1T8SwPnDNoplS1y5Mw hA9uY+8npAKd0O4FOCalI73UW6aSvrRE PgjbUJO9BkAsj6QO0+ejdOA21XkCplm9 giQTRX26fWw37C0C7v75R69w8C9X0Dkj nymc3TmoHaCtsEWT+1MpreK/c/3obqNm 071jo8q6Pwo6acFjCRGu+qBWfdk0VuMS zoxO7VoI4DacE0xcfrd4gg+XVw7F45JV xeL+m3/EMOFqFizVWNmmIyAgYV1qCre2 nME7E+FdVgt6pS27DtphEg==
+. 1209600 IN RRSIG DNSKEY 8 0 1814400 20171201000000 20171110000000 43863 . agbQ597bBZCy0sTArlwjA7SS1Q5vrC4w tN3UPB2gTW+qysLL+S5gXMUfltyZ0MIa cJXDgxzXr2NkSn1zn399422uHyIvYmF1 +nOj6nvnYGbTUU0S69j0nUjdFxgulHsk HbrmK96N0nBIv6hvbresZ1jdzQvsRFhw v7s5x1hgKACz3VOMNt+n25feRrZanzGf YXr6jw+EXG2RjtH4tdu7uxcIsGlqsZwC F0KUTnpU2GX8Cj3RZ9HJ9oh+yQq1tJFx x+a+ystolVcQFPPJSFlTSc3KmBaP/uGI 3gJ/JvGqh3BvMGefkK6QYUCm6uBoc/V1 TUJf2X7qL7fORt7Lq/yXUg==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. 518400 IN NS rootns.
+. 518400 IN RRSIG NS 8 0 518400 20171124000000 20171110000000 43863 . pXHd/1pTHynpuquF1pHha2eFKyCu08mH 1+4A41rlauVzAibvKylmVvhxcwIA0CKI pjTh1STFFNc+7L61tNcLlOqUdAEwutNJ mUh2RtRFZF1kxTbRvZRGgUfL/+nD7M7G db3j6XsTQTdyKcytNc9+e1FH8lYV5E+s +aH6J50Y00XKK3pMxa5DkZcNTTzZDHpr WzZmFqvtE+ZefIawvjmX0Qol8fOfDeOi xEDwvwwWR4O/0PLdizQeYnzusxLL+wlp QxkbZ8tMYvG+vnhR/IW2o8ZddNeLU6Pg r7vjp61Oxb4lRvRzJdzIN1rGfvqq+eiT cMdbQ326wmTyhdxxkwkP7w==
+SECTION ADDITIONAL
+rootns. 518400 IN A 198.41.0.4
+rootns. 518400 IN AAAA 2001:503:ba3e::2:30
+rootns. 518400 IN RRSIG A 8 1 518400 20171124000000 20171110000000 43863 . l2h5+ktnsD5G+obFbqe3jTV96AowrBBk GFwAbwHuRujkp92YC+iY55CU4cTjozZI e5nYpgvE83ZHEewC44eN4mkZ0iGDkUYS 7ifh5QLiWTHaZDiEKxbqqiIay2c5jq6f uDmT9dJGin8aOwrWTaLHEXvX5VBAy9ym Q48kZl7rONOU3Amsxh2fdfW7qrl04RG+ XZVATT9mFuP8yJeXdFFr6HLb4PkscBXn IgJle0HaV2ZZ+RPUVigKwNlBnTDq4UtZ zZ7JxzLopxkxSSIZrmunCHRayVjCO4So ZBlYRjflAbZOWtG4pFwi+/fyY+y4/NGA fULau0RBP9phug4HGsDslA==
+rootns. 518400 IN RRSIG AAAA 8 1 518400 20171124000000 20171110000000 43863 . hTNNClNXX6qsoopTGHMiRGkBSVcR9W7F xNvy/e9nYbS79wcNWzYdweXp1AFtEm4t /l55IucR2c+n5Cm/i4ahQCrduGVDdKAy LfIm8tKf6MAMlEu6JxIWQ8r4z+dsmtml ATIffXshG3IPeS/htNAuxkwU7j23JW65 o321VNVvIGVJ1mPcyM1Z6n4xjvGmj40O Vj14vib/LA5ItQ/pWVl7U7Y8QoeMG45s FU8N4+TibInsJo8hnV3GM3t3B61QsziA gEvwvgD3gFRn4W1czvdxWQuQyyQVr8z4 Q3O78QHh5crzMgqlbnwrBr7q3a5+ltWb pAoEhCE7uccLmCIdde+bXg==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rootns. IN NS
+SECTION AUTHORITY
+. 86400 IN SOA rootns. you.test. 2017071100 1800 900 604800 86400
+rootns. 86400 IN NSEC test. A AAAA RRSIG NSEC
+. 86400 IN RRSIG SOA 8 0 86400 20171124000000 20171110000000 43863 . Kg/cVNP2kAPJa/Tv5d3X8pPpq/oZgdh7 8NzEhZN7ZeHCcI39r4f6e40RdUGNzLI5 k2bZa9ncfCfA0au1s24Ctxl207X1ZDZ3 Q0jRIz6XgP3wI0ZoEzZwYbaBv0Tpuhr3 0Wg6nU2KJZ0avRhahKVAzmj164+JbFQg yDN+dOj0npJ45vdnK9kwos9ymdC/c6Ae uXgHoF188EpTs7xTtImBvNVQwONrduNs qkKfpsl+V1PdFl1f1NWDzzMrwKYGCyBt 3idLeRkqWODb0r1O3m8B7hrZnk5ASsRJ ERDMLIrfZvw91lYcSVzgV+GL++hG8oc+ 8pq68C1rJjBBHeqNodbHmQ==
+rootns. 86400 IN RRSIG NSEC 8 1 86400 20171124000000 20171110000000 43863 . aXTGM1DUbge++aq6a7SODevS+g/GaqEn wiyUpCzl5/mBo0HbIQSop4iP+j5A1Gv5 keW9+Jm23Nsa87KlsCkem5O25HseTo3c sIvMgEBrqalLJRC1R/lEVH1lmfz08gwd jWkc/zWgU9WiWVqC5fp+4rM2cIbtCMrt vCioYGTxPhQaEG9jm8RRMCS+mV5lPibY lq3f1S7iz/ZvzPPiA0JMshdBWOzRNCIH noTQ80eVX87yaBr9KWbbVezZa4jqP9yN +8IWwnvghcWBH2Tz7BujrqidRSyc1aVy bI1oCA8ykOcTqdJSUcl541ei72IVG0XO Mdu/qTOpqkw2d7aJBzRkqw==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rootns. IN A
+SECTION ANSWER
+rootns. 518400 IN A 198.41.0.4
+rootns. 518400 IN RRSIG A 8 1 518400 20171124000000 20171110000000 43863 . l2h5+ktnsD5G+obFbqe3jTV96AowrBBk GFwAbwHuRujkp92YC+iY55CU4cTjozZI e5nYpgvE83ZHEewC44eN4mkZ0iGDkUYS 7ifh5QLiWTHaZDiEKxbqqiIay2c5jq6f uDmT9dJGin8aOwrWTaLHEXvX5VBAy9ym Q48kZl7rONOU3Amsxh2fdfW7qrl04RG+ XZVATT9mFuP8yJeXdFFr6HLb4PkscBXn IgJle0HaV2ZZ+RPUVigKwNlBnTDq4UtZ zZ7JxzLopxkxSSIZrmunCHRayVjCO4So ZBlYRjflAbZOWtG4pFwi+/fyY+y4/NGA fULau0RBP9phug4HGsDslA==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rootns. IN AAAA
+SECTION ANSWER
+rootns. 518400 IN AAAA 2001:503:ba3e::2:30
+rootns. 518400 IN RRSIG AAAA 8 1 518400 20171124000000 20171110000000 43863 . hTNNClNXX6qsoopTGHMiRGkBSVcR9W7F xNvy/e9nYbS79wcNWzYdweXp1AFtEm4t /l55IucR2c+n5Cm/i4ahQCrduGVDdKAy LfIm8tKf6MAMlEu6JxIWQ8r4z+dsmtml ATIffXshG3IPeS/htNAuxkwU7j23JW65 o321VNVvIGVJ1mPcyM1Z6n4xjvGmj40O Vj14vib/LA5ItQ/pWVl7U7Y8QoeMG45s FU8N4+TibInsJo8hnV3GM3t3B61QsziA gEvwvgD3gFRn4W1czvdxWQuQyyQVr8z4 Q3O78QHh5crzMgqlbnwrBr7q3a5+ltWb pAoEhCE7uccLmCIdde+bXg==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. 1 IN TXT "it works"
+test. 1 IN RRSIG TXT 8 1 1 20171124000000 20171110000000 43863 . YBZuPs+ERzW1BLvmihMVYebVLgSn/EeF L+R4S8RMgvYdPAHCqDjQy6vpT6JW9YUh r1JVbCw6gq2Wp6UqgHnYcTzDKCe8sodz yXUotZrUY8u0MEmcWMoeTR9goAq3EznW LPWvuE0jqB6qIV+1xFg21fkVaSR5g0Ex j/JT238NUIABu7xEoOkWIt1H15/CnRgk 9QSD575ERP3ksfNtoonO5B2cvgn2Rlxp PKZ12uP/bQC2Xxr3n6TVOkBiFs7RNm5H yxf3HXvb+K4JlYiC1VkrXlBX7dnbFUEk NLK/BVwFPZYmbJlTT+VrlvgbeWLkfEYK CKPhnMU5ZBRalkFQGqfAEQ==
+ENTRY_END
+RANGE_END
+
+
+
+RANGE_BEGIN 20171120000000 20171129999999
+ ADDRESS 198.41.0.4
+ ADDRESS 2001:503:ba3e::2:30
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. IN SOA
+SECTION ANSWER
+. 86400 IN SOA rootns. you.test. 2017071100 1800 900 604800 86400
+. 86400 IN RRSIG SOA 8 0 86400 20171204000000 20171120000000 43863 . ijEdh2wgt4tTeSZRus0IBsndUKIa41u4 LmVEhXyi85hcsvkSt/FrTqZiZAm34f6A FcmtPt8Tk+mUq+c6PoBArVvt6Tr9FE4P haMCzKrNruthWe3+ch54l/yBbn93A+Xd hQB9KSn8IWMUMEjg+9Gnc08v2UavBo4L IKHRUyM0lSx0UX4gdrauW7XimWDwioSD 7VOFrcCmPTLs4JdEqd+LEOm7/qodYaX1 fWzIARcw+0fk8jHq0OqeJh7B4xiRSr+N 73bL9d39ljs6HK3A4gipoWhCab+F7ewI WZZ6BGHy1jIvm9+rPSKfFct8+0B2uApc xEyyz4gJZooFVgrP7uT4Lw==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. IN DNSKEY
+SECTION ANSWER
+. 1814400 IN DNSKEY 256 3 8 AwEAAbS4LSbmieIk96i3AK8IEZXlLRdM YLoEp4QSRMrdtJ0VcZKsjHWF6g9Q50T/ 1XKBxY/+6j71//cFRi1cViqoNsPd3LEb txWa3Jx/1HBINOkAPdHMBc3SQQ5qEIar PObq98RLnQ22ske1xZtbzNRZogPNi7zM HwQ3GYf0sUVCnYTmv8en5yYfSh8mY9Ez 8okorK7UN2RlHx9B8S5DRtBphO61mSI8 MXRj91aC3iRTbYZndTWorVkj4UvCBBr9 qh7oNpRbprIvAmRzRK6IaxpYDS6iGtSq 05WbGRtQRXkngOzFZO1BBDHgj9Agtx2S HBxAKuX4wF+w8I8xO7m5z0MOIF0=
+. 1814400 IN DNSKEY 257 3 8 AwEAAcgeCFZiwMD0S6TVgSK3Ob/MKFo+ dHYeNgoOjxH3JoxV09WShBXID/LwKs/e sYAIzTOBB8Fu9IDoVuQe5prOEcGZRp6u zF7JLnqrgOzoaSPRmKsvXh8DfipA56qE AqNwYBCqzlbGIGjHOQ8t+Xonp4fSBYbN MLmh7o8+u55k7PxemKTCiAnY7Bjx0g3m J1HuFvQXDDdvyletuoS3NKqrkjqdOHRB 3p3GKrKgw+zVb05UEyotCEKjqqi+BOmg cm8rmUIeaNQREjxrUyr8/Ry67h5NJLfq LAqAnSePf1PyhQcl8XjGHXN7w1tLLyJu Gy5B3zLSW1P6jIjon77PSn+cXi0=
+. 1814400 IN DNSKEY 257 3 8 AwEAAfX4eSO5BEPXggvx4jL5HkEjbA+5 QD8Acnh4wOHNv/OJX4QhKnpoMDOrpp38 n0Rgcr8qZ0XUqiJWl8eEH//wrQDHoO5/ JHRmibVrcA6UqfhUa25D1BfeMtTgMCSS +W3/heB/YhyXOJtOdWDmJutDY1nfJUSK rF6XwBj4us7U5jvwXwq+l36AeI4q7I87 Std0GNgRdA6/cJtApPoGv/0oNE0iNTyu IBcAR+AeWu32+JavhTycmtMfZ+KOIShq uI9RHzChZ9yLikAT+gclJGLLlxIr6HDr SLChCG90/yvmc57dLn8qhRWRJtJeLT2V HSxeP7oREb6RSdkxET6OTf9GYHE=
+. 1209600 IN RRSIG DNSKEY 8 0 1814400 20171211000000 20171120000000 43306 . OFuHLGCCYvssVgObtX4ugAG68DDhCEIi nLTe5rZfhPc0cYoZbRkheyyeMeyV6xuV x4JVah4k5C6vabPK3sVbEWiWVgRhtPMD 8cZVBMb4EZHmqbXCRV8NYZQ62JNwhsBx pgFWLTd1Fg9kpxS2opDvj/86w6JuOX60 KJ0ASWJsqujbH+nPfxKZEsddImXfu98Q czav9cw3fN1PQqt/UBjrwglDPz3YpkFs ce21EwgAd46p4CboEl8LGzU4QWrz4ndR OdG1vdgFCLq1bhwOYXciXT1PNGPnkMUT 9mpAtNOgR/ufIT+XYNfM3C9MJI7ukmUx Wo5VkH0GN2Ogo72t3BkGYw==
+. 1209600 IN RRSIG DNSKEY 8 0 1814400 20171211000000 20171120000000 43863 . rVYGkFuBpbElsJzwG4y2LOZvmTPLFXV6 /3jh6G4b951ILKhLTc9kl/Ecc6X09Pow 0pZtMgvZlQt+zfgHRaYaZ+cG05mbpw5C ojOJRycXgxVrzhPI2KtDu12iD1Uov2P0 ytE5msd57PDq8uwdvtj3e/7Vfyx9qVr5 QEEXqtV0EBAMIrNLRpRPav3jViGodY8v kfDP0YbJh1fTz0LFFmzP8I1WlSi665Q4 HT1KO6TdTrlZl1fbMlbJmop+zcZ7wWft 8M+PolxhwPpT0LIctA93mrCr1t+jTx/Y 3TeA/vYb3KHgpypNYfPImbnrxSuruyJ/ 7+lwmLKbuxb15NHUrDaeHw==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. 518400 IN NS rootns.
+. 518400 IN RRSIG NS 8 0 518400 20171204000000 20171120000000 43863 . ZRzL9+U8+HkObgmmCNGJEhL4lwbgVJYV EY6qin9F2xvq68t4H57D2d8+7jjCmmnm +GhzrjckeHVOrRO9ujt18NTpfhR86n/D eNLK+NfsLCW2i7l8lAj6LJoYZnPcdSeD KWC1U6HjYrzsuQRSKDkPEHPARgYfceM4 WcHnb+QhTgEueSMkikEQI8w3wQByWIlD kAZxcE0wrzHxxnFyqav5UsmJX0Jscb+h kZSTCwK+YMcrAyo8/t3O+7wP6XRb+MTs LnmXUo/53FtLPjDxX+3p6e2aPvEuOgXi rySMuE3+o5SIWgP/cD6yrHJjmdTelWMe vjXQ0NXILFy/+2/iTi/DCg==
+SECTION ADDITIONAL
+rootns. 518400 IN A 198.41.0.4
+rootns. 518400 IN AAAA 2001:503:ba3e::2:30
+rootns. 518400 IN RRSIG A 8 1 518400 20171204000000 20171120000000 43863 . pbyOQnscKVBkn4Ik1VwX7tPt/1i0W9hO AOg/X9WHDdQLJBaaElCRc0njtT8HqBYe PJ1E6+tG0MLNbznGpjUaJ8FwInjbzqug 70WuDyZxS6GW5GPtP3PaK+cv+Kwc+sj6 OimX67TmCIrkA8aza51RfdfuSccY/MLx HwEgzfKBWOzbnECd92P86D901Fyr9xWj bNlQVj20SxvkTaQ8wgTnaslG5kSRJCbv 8gNG0WFYVVUoDU2oMS0xx/Rr+qWMf6+f ZXG0B/T0QJm/84ov0BYibVXwJTwLIJC7 8GB9RBdO2lzpiSvhl+PCt7cgpsQyoM9y jhV1iVeYccqf6+aQ0lEr/w==
+rootns. 518400 IN RRSIG AAAA 8 1 518400 20171204000000 20171120000000 43863 . Ge7dUr1EmWWJ9/rleiFkH1M+2GqwIufx y6OdMww2tvQV0R6lfcz8VWXz4xGfVG4L HJIdYVTnVLV+xnVafxGBJVfWcqfcvKHp 3qeskzgl118QPAgf9SY53U+bKwg32qWq GyGp5XK1LWnVAMAqilEbI+KnP/sMOB4T d0c6BEdpGi3hV+ZC/Mf/vGf0FSJjBOcS 5OsC/wl+1BnM7vmuMAaoPU4mOrF8f0mK Z3gjaZijU47TGfl3K/Yayr12nOtjs3hh 0f4er+3UhxglBYVCJzxaZj8GGT9oqSKy 9LCrK9ZqeBg9QgxB+57RBwEG/KlqdQe0 PWPHGjhzRJSMF+T6SMdxDw==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rootns. IN NS
+SECTION AUTHORITY
+. 86400 IN SOA rootns. you.test. 2017071100 1800 900 604800 86400
+rootns. 86400 IN NSEC test. A AAAA RRSIG NSEC
+. 86400 IN RRSIG SOA 8 0 86400 20171204000000 20171120000000 43863 . ijEdh2wgt4tTeSZRus0IBsndUKIa41u4 LmVEhXyi85hcsvkSt/FrTqZiZAm34f6A FcmtPt8Tk+mUq+c6PoBArVvt6Tr9FE4P haMCzKrNruthWe3+ch54l/yBbn93A+Xd hQB9KSn8IWMUMEjg+9Gnc08v2UavBo4L IKHRUyM0lSx0UX4gdrauW7XimWDwioSD 7VOFrcCmPTLs4JdEqd+LEOm7/qodYaX1 fWzIARcw+0fk8jHq0OqeJh7B4xiRSr+N 73bL9d39ljs6HK3A4gipoWhCab+F7ewI WZZ6BGHy1jIvm9+rPSKfFct8+0B2uApc xEyyz4gJZooFVgrP7uT4Lw==
+rootns. 86400 IN RRSIG NSEC 8 1 86400 20171204000000 20171120000000 43863 . UByOkUebyZ68uVjCkAC/yAJSkAosnKMr hIsV428f844njgazLWSq6KjsfCo0WTLz peH9rwQGzure/8Dd2/vxpYjxvT/85jEC LuBAAInNYt7GIz+UrPDCpfe43pE0L0cK XStz/x0R9mNGH5/sq5MfQOxaVWWWZtuV 5S0MVpoNCnNkBlPcCrJT9tV3uL89lptT tiQ07PYCeEkB7nmC7E96jDpopMlo/PC5 zK2bXBh9LuG8UjlvNzSeelE72CkhId1+ 8FrXO/1lpCX4Cegp8gHtTiVEr6ZQMz+d dmLLl9MvPczXXAf4W1Rqa0BG94BU3ZwN ivElxk1UXlxV64WNAQSFsQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rootns. IN A
+SECTION ANSWER
+rootns. 518400 IN A 198.41.0.4
+rootns. 518400 IN RRSIG A 8 1 518400 20171204000000 20171120000000 43863 . pbyOQnscKVBkn4Ik1VwX7tPt/1i0W9hO AOg/X9WHDdQLJBaaElCRc0njtT8HqBYe PJ1E6+tG0MLNbznGpjUaJ8FwInjbzqug 70WuDyZxS6GW5GPtP3PaK+cv+Kwc+sj6 OimX67TmCIrkA8aza51RfdfuSccY/MLx HwEgzfKBWOzbnECd92P86D901Fyr9xWj bNlQVj20SxvkTaQ8wgTnaslG5kSRJCbv 8gNG0WFYVVUoDU2oMS0xx/Rr+qWMf6+f ZXG0B/T0QJm/84ov0BYibVXwJTwLIJC7 8GB9RBdO2lzpiSvhl+PCt7cgpsQyoM9y jhV1iVeYccqf6+aQ0lEr/w==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rootns. IN AAAA
+SECTION ANSWER
+rootns. 518400 IN AAAA 2001:503:ba3e::2:30
+rootns. 518400 IN RRSIG AAAA 8 1 518400 20171204000000 20171120000000 43863 . Ge7dUr1EmWWJ9/rleiFkH1M+2GqwIufx y6OdMww2tvQV0R6lfcz8VWXz4xGfVG4L HJIdYVTnVLV+xnVafxGBJVfWcqfcvKHp 3qeskzgl118QPAgf9SY53U+bKwg32qWq GyGp5XK1LWnVAMAqilEbI+KnP/sMOB4T d0c6BEdpGi3hV+ZC/Mf/vGf0FSJjBOcS 5OsC/wl+1BnM7vmuMAaoPU4mOrF8f0mK Z3gjaZijU47TGfl3K/Yayr12nOtjs3hh 0f4er+3UhxglBYVCJzxaZj8GGT9oqSKy 9LCrK9ZqeBg9QgxB+57RBwEG/KlqdQe0 PWPHGjhzRJSMF+T6SMdxDw==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. 1 IN TXT "it works"
+test. 1 IN RRSIG TXT 8 1 1 20171204000000 20171120000000 43863 . SlxNxV5dq19/lFcTpRpqn6ux/KwAQV87 0YKUjQxS//BXgkd65+hGRfnBLEIrF3JA 0GGpVqzVuIlVvNIUTq82QitgYBqO283H EwJTvH0ObcKVTMD+snHcQs3IL6bbwRCD uJabvcIQh4Id1uT6S1kYjkGqii5HgRAN 34boOGku9thUBByXW2XX+daPTLYD2yK8 KPzgaaWssaqZ9w7Ef1jr1ijcPQNlAraO nS5CZVT4+jLFSOSPPKRkR1sGGUry9NAl GDoaWp8Fr3D6AI38NZ1vtMdE2b66yb4I gjy/3TrHfqOIeIoJ39EA8hCB+bHRURO2 bcsI/t7U/aYzdTlU4fguWw==
+ENTRY_END
+RANGE_END
+
+
+
+RANGE_BEGIN 20171130000000 20171209999999
+ ADDRESS 198.41.0.4
+ ADDRESS 2001:503:ba3e::2:30
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. IN SOA
+SECTION ANSWER
+. 86400 IN SOA rootns. you.test. 2017071100 1800 900 604800 86400
+. 86400 IN RRSIG SOA 8 0 86400 20171214000000 20171130000000 43863 . UCxuHrfdTZiT4SdJ7i8hcVu7NVyI07CE BkA856ZsxXq0R/GM2MqJu+QugBJARBE8 QNues+v+FqWMfaMMQ8mSOq1QfqChCjx1 eeLahhBPEY+H+d3zE/IXzxHs2eJr9voB 8U5hSznwhJu2kLR3Q6M6SisKME1/IO5V lEV34XMScd6Ys5jVGVwu+6rZt3oSksVh t8g0k+MOVnPFQvA6lcd4sDY5rpMHqQ0h 8nd4OaidLaYM2cbGUtsjJTZdmLIj60Ah 22HIv69gxy7C8sg2/2nz8VHtklOpOLxL uxWWt+4gLR3oNsg+HR3ospSMBfidmu4X /K3aUK7e6fg/khI5kibXIg==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. IN DNSKEY
+SECTION ANSWER
+. 1814400 IN DNSKEY 256 3 8 AwEAAbS4LSbmieIk96i3AK8IEZXlLRdM YLoEp4QSRMrdtJ0VcZKsjHWF6g9Q50T/ 1XKBxY/+6j71//cFRi1cViqoNsPd3LEb txWa3Jx/1HBINOkAPdHMBc3SQQ5qEIar PObq98RLnQ22ske1xZtbzNRZogPNi7zM HwQ3GYf0sUVCnYTmv8en5yYfSh8mY9Ez 8okorK7UN2RlHx9B8S5DRtBphO61mSI8 MXRj91aC3iRTbYZndTWorVkj4UvCBBr9 qh7oNpRbprIvAmRzRK6IaxpYDS6iGtSq 05WbGRtQRXkngOzFZO1BBDHgj9Agtx2S HBxAKuX4wF+w8I8xO7m5z0MOIF0=
+. 1814400 IN DNSKEY 257 3 8 AwEAAcgeCFZiwMD0S6TVgSK3Ob/MKFo+ dHYeNgoOjxH3JoxV09WShBXID/LwKs/e sYAIzTOBB8Fu9IDoVuQe5prOEcGZRp6u zF7JLnqrgOzoaSPRmKsvXh8DfipA56qE AqNwYBCqzlbGIGjHOQ8t+Xonp4fSBYbN MLmh7o8+u55k7PxemKTCiAnY7Bjx0g3m J1HuFvQXDDdvyletuoS3NKqrkjqdOHRB 3p3GKrKgw+zVb05UEyotCEKjqqi+BOmg cm8rmUIeaNQREjxrUyr8/Ry67h5NJLfq LAqAnSePf1PyhQcl8XjGHXN7w1tLLyJu Gy5B3zLSW1P6jIjon77PSn+cXi0=
+. 1814400 IN DNSKEY 257 3 8 AwEAAfX4eSO5BEPXggvx4jL5HkEjbA+5 QD8Acnh4wOHNv/OJX4QhKnpoMDOrpp38 n0Rgcr8qZ0XUqiJWl8eEH//wrQDHoO5/ JHRmibVrcA6UqfhUa25D1BfeMtTgMCSS +W3/heB/YhyXOJtOdWDmJutDY1nfJUSK rF6XwBj4us7U5jvwXwq+l36AeI4q7I87 Std0GNgRdA6/cJtApPoGv/0oNE0iNTyu IBcAR+AeWu32+JavhTycmtMfZ+KOIShq uI9RHzChZ9yLikAT+gclJGLLlxIr6HDr SLChCG90/yvmc57dLn8qhRWRJtJeLT2V HSxeP7oREb6RSdkxET6OTf9GYHE=
+. 1209600 IN RRSIG DNSKEY 8 0 1814400 20171221000000 20171130000000 43306 . KWzRB5lrZNkjIYKcZAWMvbQyadre36hz UhSr/lJAvRUvpWotDhgTzr0wezKHtgyH vh6zUhGn4bJVKWU13ikum9+X6IgjALy0 GU+teeNhq+6v3rL1fCUSYaG5uxsutGZH QQF76XcVXMwmE9zU8ksFP45SQnjbhJW0 j1UPrH8YnUzlX2ElvdcZvJmF61xYt5dt S1wPk0qBsTpKvh0tY0nOpY4bHVkm/uG9 notsyRbxzZHGb2hGjAFVL6fRDFGLltBN l5OpJ50ml/wVcTcSbXV+at1oxZsBCXhK Knchw8FBRBoIC+X88UXdoN410QE8qYXC u/aDb2lWOr7nJCTa6GPTGw==
+. 1209600 IN RRSIG DNSKEY 8 0 1814400 20171221000000 20171130000000 43863 . hmNpauPne5OdaR9AmO0F8RugnhM1zyEQ +Xd3rzcW0YmQtf/ZkDuJJExr+4zWePvo ABf85e9KoOjHKA3gIh1Cvu+KYIJWGHzi jBGA6QAI/xcrPlA/1HpI93PjJM4wvGrO Lu6sOMTGg9HTtXP6tlx7/ynl2Ap28W5Q b0MS2I4q5aklMC1JTPUAyRTO68WoqT1c n7RH1PPrq0f5UWOPzc8htCDf66UGhjDm EEM678tF9wNIKQxavny/hKHYk5ulj6Yj clbsATUlCV++V55eg+mpQAGE+LFVdwNU 8oEgLX+wCpSI1tgPZEi28qPIufKn16Y/ wK3UBWMjHEt8ZrTQGUVF6Q==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. 518400 IN NS rootns.
+. 518400 IN RRSIG NS 8 0 518400 20171214000000 20171130000000 43863 . l0g5TXXkZS/8gRZTabMisId2gKjEOX+S Zf/rsZDISgFwgGHiXiHl2AF9Xt1oXNa8 eQ6jgfyrb3blorYxnKLpPHvQgGmlQYGj +DQvprLE+2WEfuqNUJJiyS6YQt1PUG9W 7Js6oupPzmpKsJFmQJCrc9gqu2FaTBau TK+8hBF92vJT71Lz+aSytByAilMYeOiZ kk7tJOaVKI7j2yl6D5ymzi234XHg/UxE pODae+XWbDp/7cQrSpDmAqrIf4BhhCZf jdNn5ZPrKWYqMRQhzU8fNNLcLFe6TsRP eVf1S4cZXJaje+qFHRwPjB2eqH9ZFnft ReTDezSHakHbdFOvPFKP4Q==
+SECTION ADDITIONAL
+rootns. 518400 IN A 198.41.0.4
+rootns. 518400 IN AAAA 2001:503:ba3e::2:30
+rootns. 518400 IN RRSIG A 8 1 518400 20171214000000 20171130000000 43863 . kaKieodcrDtLvvgfxLbZzx5heRAxrWIt 4DprkLP0l7nR2n5gPB4TX9toRqAART1X iWl06iDVXa9P8fqwCfpJa36mkI4WEecq 8AbRT6UxXpAVso4/uvR+UG8c79kueXkF 6TpZoaKs+4S1IwO9P2nefiyaQ+AJ9D7a KpBjcSfF+zKY3fIj/ck+fc3Owz2XNtJ5 qWRtppnRQ5t4gzYAIJeULC+622k8QSpL qb/1rhOCm5aGTxIOGVjvW8Zt5wGlJEd/ xvM6hW0NcnQU/4w8gOBJuraklWXTnG6q GKtdZtTJ4P6xTOiKG3kROrSIBwQ1iUR2 7qlmLabMHrTZC+cOcUXA+w==
+rootns. 518400 IN RRSIG AAAA 8 1 518400 20171214000000 20171130000000 43863 . XZROZxFmRY6FygyYribn7/xFRRke0M+s Q76DiSDdL6R1/NlActeocZ6RjG/l9icS Ca9GZqczS9qcjs7dhQtvyeK84cV31YlW Lv3LiQGmHP07+4Yv6Lq/BPUaRcbbQldw dgwKXDgC8P+z8PocjBA84dyIVV8q7yRm niusMJNDpA5r7rwHfM1JUzaj2e6tsRjX IkXzReSul7Z0DZ8yQuPL0vh16XigbkO3 ZANdKw2flCynvcI/8tV8Ni+lPIlH4+E5 1SMJ/485NKmjPDK4AsS4Ic3u6eonen6v I+jq3xii0cWjzM3IEma1oin8ZzL/NWXl hSodAhBe5eMgV5zx+SeQDA==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rootns. IN NS
+SECTION AUTHORITY
+. 86400 IN SOA rootns. you.test. 2017071100 1800 900 604800 86400
+rootns. 86400 IN NSEC test. A AAAA RRSIG NSEC
+. 86400 IN RRSIG SOA 8 0 86400 20171214000000 20171130000000 43863 . UCxuHrfdTZiT4SdJ7i8hcVu7NVyI07CE BkA856ZsxXq0R/GM2MqJu+QugBJARBE8 QNues+v+FqWMfaMMQ8mSOq1QfqChCjx1 eeLahhBPEY+H+d3zE/IXzxHs2eJr9voB 8U5hSznwhJu2kLR3Q6M6SisKME1/IO5V lEV34XMScd6Ys5jVGVwu+6rZt3oSksVh t8g0k+MOVnPFQvA6lcd4sDY5rpMHqQ0h 8nd4OaidLaYM2cbGUtsjJTZdmLIj60Ah 22HIv69gxy7C8sg2/2nz8VHtklOpOLxL uxWWt+4gLR3oNsg+HR3ospSMBfidmu4X /K3aUK7e6fg/khI5kibXIg==
+rootns. 86400 IN RRSIG NSEC 8 1 86400 20171214000000 20171130000000 43863 . OmAfGDmBR47KWGoXaW9u+WIj3zqBg8ia ASd+SywAflqH2cvx9St9lBmN/g4hzof1 l/2O1mMDU/8XlAcZ3slpnTt5XE0NNnDr 5GQpPlVhrbvYnriSpl7LGamgf/i5BtJ9 eu5jP3wBb7Ra79EGT60QgcwbHPyFCUbh EUW31Ak2Kupai3LWc/3vXdgf2DWk5MXv C9g9QEpE/6Zcn2H9hxLgXghlEGighcZP a+sPcOacytQpSi/ggMX0ztLj20DM7Hes 3YUwG84SlcDhLpLN5M009hFlPu2+pVjC CmFywB4dtyUS62014UIR+PAByFcFEGOS MreqUAs/wj3RnpevarcaBg==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rootns. IN A
+SECTION ANSWER
+rootns. 518400 IN A 198.41.0.4
+rootns. 518400 IN RRSIG A 8 1 518400 20171214000000 20171130000000 43863 . kaKieodcrDtLvvgfxLbZzx5heRAxrWIt 4DprkLP0l7nR2n5gPB4TX9toRqAART1X iWl06iDVXa9P8fqwCfpJa36mkI4WEecq 8AbRT6UxXpAVso4/uvR+UG8c79kueXkF 6TpZoaKs+4S1IwO9P2nefiyaQ+AJ9D7a KpBjcSfF+zKY3fIj/ck+fc3Owz2XNtJ5 qWRtppnRQ5t4gzYAIJeULC+622k8QSpL qb/1rhOCm5aGTxIOGVjvW8Zt5wGlJEd/ xvM6hW0NcnQU/4w8gOBJuraklWXTnG6q GKtdZtTJ4P6xTOiKG3kROrSIBwQ1iUR2 7qlmLabMHrTZC+cOcUXA+w==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rootns. IN AAAA
+SECTION ANSWER
+rootns. 518400 IN AAAA 2001:503:ba3e::2:30
+rootns. 518400 IN RRSIG AAAA 8 1 518400 20171214000000 20171130000000 43863 . XZROZxFmRY6FygyYribn7/xFRRke0M+s Q76DiSDdL6R1/NlActeocZ6RjG/l9icS Ca9GZqczS9qcjs7dhQtvyeK84cV31YlW Lv3LiQGmHP07+4Yv6Lq/BPUaRcbbQldw dgwKXDgC8P+z8PocjBA84dyIVV8q7yRm niusMJNDpA5r7rwHfM1JUzaj2e6tsRjX IkXzReSul7Z0DZ8yQuPL0vh16XigbkO3 ZANdKw2flCynvcI/8tV8Ni+lPIlH4+E5 1SMJ/485NKmjPDK4AsS4Ic3u6eonen6v I+jq3xii0cWjzM3IEma1oin8ZzL/NWXl hSodAhBe5eMgV5zx+SeQDA==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. 1 IN TXT "it works"
+test. 1 IN RRSIG TXT 8 1 1 20171214000000 20171130000000 43863 . LwubT77ebb9kYgMvgQIIR7/V0t9IgY2y fEXhCbK2nQ/ugSInCMb2zpoF6t6JswR6 07lvjKGaG/B/V7p4cKfJXdW6O/+ke/ub YA+MNVJ8tg2/sC244ATvH+rk+K7qvFWs TuBL77AaRRKU1z8V3AQPbka7pV+2myTL NlIEgd0Dh2dr823rEqgqnKxpTpobJpPv Z2HWQvPT7n7MSDsKyzYNaVINxwYo84Nb 5vit+Nh5WU/g+1gmsVhxfNSO+XPSEQE7 7YGfc/IaOoqQzSKo3q7mcLrTMA5RbmAO DMoJl5xaHpxHz5kYZvb4XOlDC+gWChj3 t99u7aun2VHpcaUyqdfk3g==
+ENTRY_END
+RANGE_END
+
+
+
+RANGE_BEGIN 20171210000000 20171219999999
+ ADDRESS 198.41.0.4
+ ADDRESS 2001:503:ba3e::2:30
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. IN SOA
+SECTION ANSWER
+. 86400 IN SOA rootns. you.test. 2017071100 1800 900 604800 86400
+. 86400 IN RRSIG SOA 8 0 86400 20171224000000 20171210000000 43863 . TWYLfFkfkhzVbdQwXVasQj0RUQZsDiMU HJyRzISnRIL+6hoSi6+imw8z2PcvSQne 6QKGrab1cEZgDFiyzOcjYO5I0FGfQta1 IKrITe5n+l04r3WlqZL3r4acXaX8Pb3R tC02hYb+oIjxgTmauL9qkNHiISNaSi6S wjVEaeXC4kOvSPNBKaB/aXRp/DKU1FVi R+l2fofpIai4HpVxOAbJ2+qzDfG0vfzQ S8+RMfJ3s9hyqwluc/6loC9eABjve6Su ukRgoRzw5CmAKw2trUNLlcnLhLFt4YUG Qhpgzo3/FsTJiT2Eu15eO+zp03RhTv1Q KpnVPjhOhXH8aiVGLzHF1w==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. IN DNSKEY
+SECTION ANSWER
+. 1814400 IN DNSKEY 256 3 8 AwEAAbS4LSbmieIk96i3AK8IEZXlLRdM YLoEp4QSRMrdtJ0VcZKsjHWF6g9Q50T/ 1XKBxY/+6j71//cFRi1cViqoNsPd3LEb txWa3Jx/1HBINOkAPdHMBc3SQQ5qEIar PObq98RLnQ22ske1xZtbzNRZogPNi7zM HwQ3GYf0sUVCnYTmv8en5yYfSh8mY9Ez 8okorK7UN2RlHx9B8S5DRtBphO61mSI8 MXRj91aC3iRTbYZndTWorVkj4UvCBBr9 qh7oNpRbprIvAmRzRK6IaxpYDS6iGtSq 05WbGRtQRXkngOzFZO1BBDHgj9Agtx2S HBxAKuX4wF+w8I8xO7m5z0MOIF0=
+. 1814400 IN DNSKEY 257 3 8 AwEAAcgeCFZiwMD0S6TVgSK3Ob/MKFo+ dHYeNgoOjxH3JoxV09WShBXID/LwKs/e sYAIzTOBB8Fu9IDoVuQe5prOEcGZRp6u zF7JLnqrgOzoaSPRmKsvXh8DfipA56qE AqNwYBCqzlbGIGjHOQ8t+Xonp4fSBYbN MLmh7o8+u55k7PxemKTCiAnY7Bjx0g3m J1HuFvQXDDdvyletuoS3NKqrkjqdOHRB 3p3GKrKgw+zVb05UEyotCEKjqqi+BOmg cm8rmUIeaNQREjxrUyr8/Ry67h5NJLfq LAqAnSePf1PyhQcl8XjGHXN7w1tLLyJu Gy5B3zLSW1P6jIjon77PSn+cXi0=
+. 1814400 IN DNSKEY 257 3 8 AwEAAfX4eSO5BEPXggvx4jL5HkEjbA+5 QD8Acnh4wOHNv/OJX4QhKnpoMDOrpp38 n0Rgcr8qZ0XUqiJWl8eEH//wrQDHoO5/ JHRmibVrcA6UqfhUa25D1BfeMtTgMCSS +W3/heB/YhyXOJtOdWDmJutDY1nfJUSK rF6XwBj4us7U5jvwXwq+l36AeI4q7I87 Std0GNgRdA6/cJtApPoGv/0oNE0iNTyu IBcAR+AeWu32+JavhTycmtMfZ+KOIShq uI9RHzChZ9yLikAT+gclJGLLlxIr6HDr SLChCG90/yvmc57dLn8qhRWRJtJeLT2V HSxeP7oREb6RSdkxET6OTf9GYHE=
+. 1209600 IN RRSIG DNSKEY 8 0 1814400 20171231000000 20171210000000 43306 . j7fn3Wmksge84eUfePg/6iOXBNnx04hD s996uSsqG5oqXC4VOtLR9mfPN99xHGfO swEhDgV3EMyutxBAnPqk+d3mHVQQDOld MQ4KASoLaGrzmovSRiw/ne4ozgDnfrMV JFozXV+P9HhQ+tRWF3x01vx3H8m+aCIK NaRUSNjs8bTJ8JvDEa4PxuD3uPgcJ7Qe UtMsQjaotPbenA1zTVx/E9LtI/wX1Tzs UOa89+dXWZDuny8mBKWD7KOIi63Upsnd zGbogel+QuLsF7E0AlinjTZD8FzaAujt hUUw66TGyEfciv888tyK/7nOhLmf+7qt X5LN+qfX5VBxt/wrN8SEjQ==
+. 1209600 IN RRSIG DNSKEY 8 0 1814400 20171231000000 20171210000000 43863 . sk7zKGpiNflz5vQUiBM/tGH4cCEwfv2E y/DGmjaa8DWHlui+GepsaRl1t7dDWBW7 JxqDm1cESd0uU3BOqEDv+zGBbCYuhM5p WTqb2Fm3r98uH8jhXpXkpj2xMZw9D3Fo fnsotjc3a7mMLPYf4G/WyCJDYXSFOI76 dsUXwNB0vbu0vpwbPzDLFxNbwIU2cAnW rFATn8yhUU4qZyuiZyfIJFMBExfoXSiy oHa6sDvngz8Ve83eIom+B6hN1IndD5i0 C+d0uZ+tZSu2lJA6yXXPiztu2w8RsJRE qpCvBHZEZeSVz59yfY9sM+5xYgC7O492 xdiHCDZy0S/7inugSZVq4A==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. 518400 IN NS rootns.
+. 518400 IN RRSIG NS 8 0 518400 20171224000000 20171210000000 43863 . FcAn2lVVdJ0QH3oYR+3YS/ReGs6pEdJU Wzmb68N7OG7V4bHovlCBVY3bGaC4+a1k Ye5t4uImqSTAygc/Ih8Nh4zUP+Ypmg57 XkQPAizWW/pc3yMVAxnGiF++do7CTf9W L9ZKknNsfhKN4L7+49BdPk3zbi8taj8L IUl9Oxic2F5QoTxb9MJ6Aetb8HXFMd9Y cmGa1/SLwDu74F1vXXZ5Br73RzTh3J4m y30T1uWvcVf76fTgsDVnj93sc/pSXQVk MARPd6OpGp6x4wGjN9LPOTAG8uV/g51y wJCdOcXikuWxX59dXIp6fnY+5GLyPyRt wmb3v54kwnXUHe5IyIT73w==
+SECTION ADDITIONAL
+rootns. 518400 IN A 198.41.0.4
+rootns. 518400 IN AAAA 2001:503:ba3e::2:30
+rootns. 518400 IN RRSIG A 8 1 518400 20171224000000 20171210000000 43863 . JVTjFY4Dsa4jcl2lNy178dO/4XuXzM12 do4ddbz80Zri18P6JW4ro/fUAN142jtl ybwrt3MRUpZQUXKhQijQpmiEYIfHPrc8 Gl4gitSnEPFjemyN6tOWJH8tzOPhkmm0 IqpdtLKG1MRuDsE50MAoVxA/C82ZzHza JExrCZxnRYMVkZSd19DacE2yHMDSXSMC OhPSEft1Jc5Sk5bUk9Jh27zQ59ZoccUq fE2nCeApt4d9WSRMAPRUlvZC8NHYZ8Sd WY/7/eX5XB2pw0xExtTwTQFPyPXxv1kt L5F+vrdwPrVgHXI3XD5lDRY8J80uyfo2 YwX3mGxAENwXPu0B+/GuAw==
+rootns. 518400 IN RRSIG AAAA 8 1 518400 20171224000000 20171210000000 43863 . JI/lzbKGeJ2b25hqnJlrJ6SYZhkIiti4 pJs9F1dTa+xuYGv/rj7E6/g3H/sRxfS1 OKwOUfB5jTuhrbEmjffqHB7f+5+kNleE EJiDwwKW5KROtPhmwcYmTFnH+sjyotKB Wh3MHqbSTdKjtH1oZ0y1c2c4se2R+nE1 DKhjCPr2+cznWgraZld68aQ/anGktEr/ ib9zw0gH9cy88WMqV6g/vrTQOLM1Zl9F PM/zvuveDqrVbATRSEeAieK5tVlRXc+0 3ReWMme2kYQrnxik8UZA8VXZpzwakcFi HJagYURn/ZZtbXgyDkrvJN3S+EXrZ4TI C+jX3OlwAIOvMZUr0uIWug==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rootns. IN NS
+SECTION AUTHORITY
+. 86400 IN SOA rootns. you.test. 2017071100 1800 900 604800 86400
+rootns. 86400 IN NSEC test. A AAAA RRSIG NSEC
+. 86400 IN RRSIG SOA 8 0 86400 20171224000000 20171210000000 43863 . TWYLfFkfkhzVbdQwXVasQj0RUQZsDiMU HJyRzISnRIL+6hoSi6+imw8z2PcvSQne 6QKGrab1cEZgDFiyzOcjYO5I0FGfQta1 IKrITe5n+l04r3WlqZL3r4acXaX8Pb3R tC02hYb+oIjxgTmauL9qkNHiISNaSi6S wjVEaeXC4kOvSPNBKaB/aXRp/DKU1FVi R+l2fofpIai4HpVxOAbJ2+qzDfG0vfzQ S8+RMfJ3s9hyqwluc/6loC9eABjve6Su ukRgoRzw5CmAKw2trUNLlcnLhLFt4YUG Qhpgzo3/FsTJiT2Eu15eO+zp03RhTv1Q KpnVPjhOhXH8aiVGLzHF1w==
+rootns. 86400 IN RRSIG NSEC 8 1 86400 20171224000000 20171210000000 43863 . sS3OI7gVoxtgc15H83an5b1KRhZyqF7U f2uAnSdy+dVqOpGbcnI98dVJ7n0SGZR9 snpfl0mMTNd5aVM57FEigkcOVjN6h2+b JgXmIsxPCIoKLJ9fCBz8GC/6UvBaDt9K h66FrkWz7IXBXBqkGyAjoeN4hyelisun wAgo1CfpAHcwWjc8IknfM6T606RMD+03 QuPqlzdXs4L2Kp5ozyuQH5MiP0to7Cvd bBj35zvGrNLs5IAK74rQJaLr7N5WVvpQ IXFNslDboc/PY/0UotPq34oSgfOUdy5V SesteyEziztLJgWpb/4F7FJrtDaRcTzM +0xpQKrk0toob/02m5yccg==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rootns. IN A
+SECTION ANSWER
+rootns. 518400 IN A 198.41.0.4
+rootns. 518400 IN RRSIG A 8 1 518400 20171224000000 20171210000000 43863 . JVTjFY4Dsa4jcl2lNy178dO/4XuXzM12 do4ddbz80Zri18P6JW4ro/fUAN142jtl ybwrt3MRUpZQUXKhQijQpmiEYIfHPrc8 Gl4gitSnEPFjemyN6tOWJH8tzOPhkmm0 IqpdtLKG1MRuDsE50MAoVxA/C82ZzHza JExrCZxnRYMVkZSd19DacE2yHMDSXSMC OhPSEft1Jc5Sk5bUk9Jh27zQ59ZoccUq fE2nCeApt4d9WSRMAPRUlvZC8NHYZ8Sd WY/7/eX5XB2pw0xExtTwTQFPyPXxv1kt L5F+vrdwPrVgHXI3XD5lDRY8J80uyfo2 YwX3mGxAENwXPu0B+/GuAw==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rootns. IN AAAA
+SECTION ANSWER
+rootns. 518400 IN AAAA 2001:503:ba3e::2:30
+rootns. 518400 IN RRSIG AAAA 8 1 518400 20171224000000 20171210000000 43863 . JI/lzbKGeJ2b25hqnJlrJ6SYZhkIiti4 pJs9F1dTa+xuYGv/rj7E6/g3H/sRxfS1 OKwOUfB5jTuhrbEmjffqHB7f+5+kNleE EJiDwwKW5KROtPhmwcYmTFnH+sjyotKB Wh3MHqbSTdKjtH1oZ0y1c2c4se2R+nE1 DKhjCPr2+cznWgraZld68aQ/anGktEr/ ib9zw0gH9cy88WMqV6g/vrTQOLM1Zl9F PM/zvuveDqrVbATRSEeAieK5tVlRXc+0 3ReWMme2kYQrnxik8UZA8VXZpzwakcFi HJagYURn/ZZtbXgyDkrvJN3S+EXrZ4TI C+jX3OlwAIOvMZUr0uIWug==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. 1 IN TXT "it works"
+test. 1 IN RRSIG TXT 8 1 1 20171224000000 20171210000000 43863 . bI93JmKmTuyDeGyek/OL4FsoK0wcr2DT enIf9HiEuLhsffQQAyfa2l4rEstTgBAP w75VDITGASJpar4qjtmCkYnXvljA+P5y MvgyOH8QmDIEc2795D4RkgAdvi5f7U4d tVMPqaFpSe36w1g/89ubn11Emn2Izq3w QnIkCpfAj6E9Hsq7SsXogUbt5vNc15aV jnG98LgrRaUtjCWWLQ72H4SXJtsM3T1H 8SvHYfNFCY49fmbhFubWa6Ai4SJzUZ0A p0vK/ecuSuUxZofYASkNRiu4pZqzKrY7 L9DMI53EE6/fPqPBNb01XakvNff9mn5Q tGL0o3GQN0xmxMwu2rXUJQ==
+ENTRY_END
+RANGE_END
+
+
+
+RANGE_BEGIN 20171220000000 99999999999999
+ ADDRESS 198.41.0.4
+ ADDRESS 2001:503:ba3e::2:30
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. IN SOA
+SECTION ANSWER
+. 86400 IN SOA rootns. you.test. 2017071100 1800 900 604800 86400
+. 86400 IN RRSIG SOA 8 0 86400 20180103000000 20171220000000 43863 . oUqoqEdKMlNikXS+IfDF99twoBLkQeMp FNH8xdI7bN+CJ3asb+Zm/VvPNXjhu3fd +4HMwRJVT1Ar9IWI5CYKvhMPuTuiCgXO Nx7tTIYD0xGtIPeRwRBI1+M5v7iOdtwD CyCb9IUtAQu6Jcg4hC8LUFTpo53PWBD5 V7b3EC18aKOqpn5C6YwoXSal1LlNgTcr wIYs1OjAtDWgKtFbK/YVOOavgfEYs6eg Fwqtn1xNAhpSDc5CnMUdl2gg/ejUvUvs 28/e2Wcp4xg5B6pB0mbHs1RjBYES2Vo/ OMyKqY1/1GJhqLm5Gal7h8nW6LHJSkjH K6YenULi+qMDAaC4kCFtqw==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. IN DNSKEY
+SECTION ANSWER
+. 1814400 IN DNSKEY 256 3 8 AwEAAbS4LSbmieIk96i3AK8IEZXlLRdM YLoEp4QSRMrdtJ0VcZKsjHWF6g9Q50T/ 1XKBxY/+6j71//cFRi1cViqoNsPd3LEb txWa3Jx/1HBINOkAPdHMBc3SQQ5qEIar PObq98RLnQ22ske1xZtbzNRZogPNi7zM HwQ3GYf0sUVCnYTmv8en5yYfSh8mY9Ez 8okorK7UN2RlHx9B8S5DRtBphO61mSI8 MXRj91aC3iRTbYZndTWorVkj4UvCBBr9 qh7oNpRbprIvAmRzRK6IaxpYDS6iGtSq 05WbGRtQRXkngOzFZO1BBDHgj9Agtx2S HBxAKuX4wF+w8I8xO7m5z0MOIF0=
+. 1814400 IN DNSKEY 256 3 8 AwEAAbgig4A5ky59AgWQLv02ZWvrP/PE +7D6PaQuOgbdmhdFqTQerNTEu1AztTaC 0QpMsG9HuhHi5rcOYGHHyxDagghZa4mQ Z08XWA+6Q2xBo5CMRh6+XTACY/N8ZoGU Si53XiVVh12t+BfbREXnT5zH45BBhPe1 dXYn8tolXXfK8oFhl8K0dvU4xhmOC1xD bDCeX1vyP0WyKtQzBU3tLHRIQQvss8vb iY+y3yTdJu062inDpGC+grJcY2nd4x16 ydcCUVRg8teLO0uuvfa0sdKLaoKJWWy7 CGWZX7lA4Nnb2CKWm0/ZySKIeSqOYW1B hr5MjdlzbyotJPhbxvBUUr3T+Kk=
+. 1814400 IN DNSKEY 257 3 8 AwEAAcgeCFZiwMD0S6TVgSK3Ob/MKFo+ dHYeNgoOjxH3JoxV09WShBXID/LwKs/e sYAIzTOBB8Fu9IDoVuQe5prOEcGZRp6u zF7JLnqrgOzoaSPRmKsvXh8DfipA56qE AqNwYBCqzlbGIGjHOQ8t+Xonp4fSBYbN MLmh7o8+u55k7PxemKTCiAnY7Bjx0g3m J1HuFvQXDDdvyletuoS3NKqrkjqdOHRB 3p3GKrKgw+zVb05UEyotCEKjqqi+BOmg cm8rmUIeaNQREjxrUyr8/Ry67h5NJLfq LAqAnSePf1PyhQcl8XjGHXN7w1tLLyJu Gy5B3zLSW1P6jIjon77PSn+cXi0=
+. 1814400 IN DNSKEY 257 3 8 AwEAAfX4eSO5BEPXggvx4jL5HkEjbA+5 QD8Acnh4wOHNv/OJX4QhKnpoMDOrpp38 n0Rgcr8qZ0XUqiJWl8eEH//wrQDHoO5/ JHRmibVrcA6UqfhUa25D1BfeMtTgMCSS +W3/heB/YhyXOJtOdWDmJutDY1nfJUSK rF6XwBj4us7U5jvwXwq+l36AeI4q7I87 Std0GNgRdA6/cJtApPoGv/0oNE0iNTyu IBcAR+AeWu32+JavhTycmtMfZ+KOIShq uI9RHzChZ9yLikAT+gclJGLLlxIr6HDr SLChCG90/yvmc57dLn8qhRWRJtJeLT2V HSxeP7oREb6RSdkxET6OTf9GYHE=
+. 1209600 IN RRSIG DNSKEY 8 0 1814400 20180110000000 20171220000000 43306 . iBsFCS0+aXyL+rLqQ45jBe1l6LSXyzFF w4kkB3opgU5o7TdaSnclpvGlabO2W1fR v9WrVDFPFYfWsMBH6TebraLm2do5HkWi bEaA8sZVKCv5Cew0FMRKtmcCYwFC5rRi MBY1ftWm1smyMEo4cU3ZvdH2Nd134Vmj xjN6LXJNJ/cx5TGp+AI0OSkdxIkVcPHr 6oQXM23WyTYp4QALnfEoh33jVlgiG9YQ 3OJ4IiKOVaeYZd1HyLaUVrreViuBCyWs S/tIScwBxKo+XImuqnNMRbun/jmkoTS/ 6BqUNxzjSq+jS7ayzXgnHsTKlXFPSDg4 bBelCv1A+DA2NG9NE4624g==
+. 1209600 IN RRSIG DNSKEY 8 0 1814400 20180110000000 20171220000000 43863 . HOvNMA8EiqTdQR3kuRm1Djf0hyphC5WM DffZbEQ0S3/PiXCUYqt/8WhGgs9NDj7l engBOouhNrmahtIM6W6Q4egeZjRX6hrf +Oe9hXa8EyStHZEdM3Bt9eAiptxliBfz OO5N8/+6vT4lSgn02zigc2S7UWVsezM6 kwhhm5m2IUb3qXpAqJ8rwrwhVKdoGHOr QStBrrLgOHRAaZf68GjI+E2KRneu90M1 mofkjA29iZdXK8+XlEhxDnLVfR3zZflL /IjE6kCGOaNurrRhA0G3+g7wY91F+guT FsTqNKApCEvEI5O8N3XhxfJmKlWZ8UKf TTnrfxghMi11IxM3MRNsxw==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. 518400 IN NS rootns.
+. 518400 IN RRSIG NS 8 0 518400 20180103000000 20171220000000 43863 . rlRwW56KLEwKjMVwq7vWtEHH8iUe0ME3 NRntwA96dWMXtYNp9ggPp+XYmQ8/fl/5 RwYtdcj649KjxdpauOiyCgBLpdu4dQnT JjfsHPRRMyTa3JLTxmQcnKKL84gVSI9P 4YRoUNiD1GCx0PpTsImF794Eg4k6qWjW +TPoraR41qv1+GywDLc6AZvkyMvm73Ru Fvj0TxI8KZuHlmwGL0gBPFl1Eqm0c/Pr n0PuTJXaNkDMBU/Bqm4K1uoWsZdECyT8 hnbOLMYIH8CENHn0h9miCAISdj5j+2mc bruRI9ZUknLF2fTev058NvHCYUOOTMmu NggrZOoVAMhUpyWUf3eooA==
+SECTION ADDITIONAL
+rootns. 518400 IN A 198.41.0.4
+rootns. 518400 IN AAAA 2001:503:ba3e::2:30
+rootns. 518400 IN RRSIG A 8 1 518400 20180103000000 20171220000000 43863 . qqJJVS9HmQPp5iPEUanAyVRFVJo70IEH zXOyegIPrVV4xAknPZezkwlDTxPJKEY/ 2Ob2sbvGmMiXvZn7vER5MPPOcb6YlT3E x9ygW8pa/5dx/gtemYmY4yhW4UhST4yB j500JpBItlMlbIP87ElECY8KyvekZ1RC PQfacGqJvZzG7SoHAOA+jphNgan0Qir8 Cx6iUsc2MEw5UMJmTCtx8fpweVmxHObT 7EaSleGQabSiV153GzRcTMA1Ye1ETUE5 YqIy89lKBDJfAJZ2m1AMYthLQwGOTtSI xyxA+qBgZfxC8foBVXgLUGB03X554V7K 32v2myX5HFSCNMhkXnQdSg==
+rootns. 518400 IN RRSIG AAAA 8 1 518400 20180103000000 20171220000000 43863 . AXlfge8y4s4b0PS9u8ZhJsVaF52ihXKa SO+HR5yWAfzskmNTglPcv2R9UEkiXxuP EVwGz9vmWPo1STlBGw6vJ03TtGOR7BQW dn/20j4cYvtIM5RjosZ8u58OxKDsPy9e uLI+nlqx2gq/DUZ+pxySgV836As1GBhB c4QxQY3oCej52qDnWLCDfs+5j2JXx8q0 MiAH8m3H91tSJ3dWG198HmfpLTemBt41 WnYxBO0AS2Z9gf+TvYXulcbJMNwqXIzB 85NGzgq+fL1u11MJfjIQVW9F5bK7KTYk 8X+rT7b/DzIMSRupMJEYLCT8ECvlqOBM PQW8Nv+YSbLrKPBIJ2Vivw==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rootns. IN NS
+SECTION AUTHORITY
+. 86400 IN SOA rootns. you.test. 2017071100 1800 900 604800 86400
+rootns. 86400 IN NSEC test. A AAAA RRSIG NSEC
+. 86400 IN RRSIG SOA 8 0 86400 20180103000000 20171220000000 43863 . oUqoqEdKMlNikXS+IfDF99twoBLkQeMp FNH8xdI7bN+CJ3asb+Zm/VvPNXjhu3fd +4HMwRJVT1Ar9IWI5CYKvhMPuTuiCgXO Nx7tTIYD0xGtIPeRwRBI1+M5v7iOdtwD CyCb9IUtAQu6Jcg4hC8LUFTpo53PWBD5 V7b3EC18aKOqpn5C6YwoXSal1LlNgTcr wIYs1OjAtDWgKtFbK/YVOOavgfEYs6eg Fwqtn1xNAhpSDc5CnMUdl2gg/ejUvUvs 28/e2Wcp4xg5B6pB0mbHs1RjBYES2Vo/ OMyKqY1/1GJhqLm5Gal7h8nW6LHJSkjH K6YenULi+qMDAaC4kCFtqw==
+rootns. 86400 IN RRSIG NSEC 8 1 86400 20180103000000 20171220000000 43863 . jlED8vYS7eDm/0s4ZrlCuVJfRVSfQKxY 3STI2gq0PptQx+M6ovJf1oxjw6rNLF7s 8DK8WnznqxEocXFaJaR6jgUggZ8Dkgj7 DHNfshwISf5P93qDkPCOLqQ62vHTBmNk Pww3+aV2atnKhNAoEe8OphpGGpFeE0W+ gRf1+GAp+1Tid7E8SBxduIzrxEtKKvJM l/Ow0rLal5MKrnejV45hgAsVF0r0ZF0B 2G7Ud2aK47ZGcIDybRUD/rUxYiPDjSwe PgLU5M9+4VDSCdW1z/sf2fgQP7kt8tzC dhxRu9wLlM/YFSJb25qBhDI267qEh9cE rA1X0mbnTkueDGq9Wty4MA==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rootns. IN A
+SECTION ANSWER
+rootns. 518400 IN A 198.41.0.4
+rootns. 518400 IN RRSIG A 8 1 518400 20180103000000 20171220000000 43863 . qqJJVS9HmQPp5iPEUanAyVRFVJo70IEH zXOyegIPrVV4xAknPZezkwlDTxPJKEY/ 2Ob2sbvGmMiXvZn7vER5MPPOcb6YlT3E x9ygW8pa/5dx/gtemYmY4yhW4UhST4yB j500JpBItlMlbIP87ElECY8KyvekZ1RC PQfacGqJvZzG7SoHAOA+jphNgan0Qir8 Cx6iUsc2MEw5UMJmTCtx8fpweVmxHObT 7EaSleGQabSiV153GzRcTMA1Ye1ETUE5 YqIy89lKBDJfAJZ2m1AMYthLQwGOTtSI xyxA+qBgZfxC8foBVXgLUGB03X554V7K 32v2myX5HFSCNMhkXnQdSg==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rootns. IN AAAA
+SECTION ANSWER
+rootns. 518400 IN AAAA 2001:503:ba3e::2:30
+rootns. 518400 IN RRSIG AAAA 8 1 518400 20180103000000 20171220000000 43863 . AXlfge8y4s4b0PS9u8ZhJsVaF52ihXKa SO+HR5yWAfzskmNTglPcv2R9UEkiXxuP EVwGz9vmWPo1STlBGw6vJ03TtGOR7BQW dn/20j4cYvtIM5RjosZ8u58OxKDsPy9e uLI+nlqx2gq/DUZ+pxySgV836As1GBhB c4QxQY3oCej52qDnWLCDfs+5j2JXx8q0 MiAH8m3H91tSJ3dWG198HmfpLTemBt41 WnYxBO0AS2Z9gf+TvYXulcbJMNwqXIzB 85NGzgq+fL1u11MJfjIQVW9F5bK7KTYk 8X+rT7b/DzIMSRupMJEYLCT8ECvlqOBM PQW8Nv+YSbLrKPBIJ2Vivw==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. 1 IN TXT "it works"
+test. 1 IN RRSIG TXT 8 1 1 20180103000000 20171220000000 43863 . s8AQUwbk1av7JPMS3E1/K6Ew2Pv01lYo JkgknqA4+i5LK4Jrqj+TgDXt4er5sFfK bD9FjDRVIXQJkpLtb48YGsIGqZK0ePSd hS/+eyfjg7W0XPDBsLjuNmJBZ4/Gtih5 I8+pZs9o1UwwrLTX7LrWDQnJAsLY/kyP aZYmOrGgki9LNw6m/itOn1FcACRI3Fmz zGeW0MXwFKA+SE3yAMcoAjhGdYWaWMR3 jZAWhLQRHDvZXRUS9XjLsDWfMSN1pEJx UrQY7+Q/B3aEf9kNw9rAgMkKST3GeNEn ElUZ/gIr3P5mCVqHr8Bi2L/Mts/vo+2N VQx7KoJL7pf9jjSokV9NuA==
+ENTRY_END
+RANGE_END
+
+
+; 2017-07-01T00:00:00
+STEP 20170701000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170701000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170701000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-07-02T00:00:00
+STEP 20170702000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170702000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170702000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-07-03T00:00:00
+STEP 20170703000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170703000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170703000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-07-04T00:00:00
+STEP 20170704000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170704000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170704000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-07-05T00:00:00
+STEP 20170705000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170705000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170705000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-07-06T00:00:00
+STEP 20170706000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170706000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170706000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-07-07T00:00:00
+STEP 20170707000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170707000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170707000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-07-08T00:00:00
+STEP 20170708000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170708000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170708000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-07-09T00:00:00
+STEP 20170709000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170709000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170709000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-07-10T00:00:00
+STEP 20170710000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170710000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170710000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-07-11T00:00:00
+STEP 20170711000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170711000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170711000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-07-12T00:00:00
+STEP 20170712000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170712000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170712000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-07-13T00:00:00
+STEP 20170713000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170713000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170713000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-07-14T00:00:00
+STEP 20170714000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170714000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170714000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-07-15T00:00:00
+STEP 20170715000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170715000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170715000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-07-16T00:00:00
+STEP 20170716000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170716000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170716000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-07-17T00:00:00
+STEP 20170717000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170717000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170717000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-07-18T00:00:00
+STEP 20170718000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170718000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170718000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-07-19T00:00:00
+STEP 20170719000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170719000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170719000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-07-20T00:00:00
+STEP 20170720000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170720000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170720000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-07-21T00:00:00
+STEP 20170721000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170721000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170721000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-07-22T00:00:00
+STEP 20170722000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170722000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170722000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-07-23T00:00:00
+STEP 20170723000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170723000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170723000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-07-24T00:00:00
+STEP 20170724000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170724000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170724000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-07-25T00:00:00
+STEP 20170725000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170725000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170725000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-07-26T00:00:00
+STEP 20170726000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170726000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170726000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-07-27T00:00:00
+STEP 20170727000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170727000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170727000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-07-28T00:00:00
+STEP 20170728000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170728000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170728000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-07-29T00:00:00
+STEP 20170729000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170729000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170729000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-07-30T00:00:00
+STEP 20170730000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170730000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170730000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-07-31T00:00:00
+STEP 20170731000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170731000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170731000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-08-01T00:00:00
+STEP 20170801000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170801000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170801000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-08-02T00:00:00
+STEP 20170802000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170802000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170802000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-08-03T00:00:00
+STEP 20170803000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170803000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170803000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-08-04T00:00:00
+STEP 20170804000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170804000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170804000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-08-05T00:00:00
+STEP 20170805000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170805000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170805000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-08-06T00:00:00
+STEP 20170806000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170806000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170806000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-08-07T00:00:00
+STEP 20170807000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170807000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170807000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-08-08T00:00:00
+STEP 20170808000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170808000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170808000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-08-09T00:00:00
+STEP 20170809000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170809000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170809000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-08-10T00:00:00
+STEP 20170810000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170810000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170810000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-08-11T00:00:00
+STEP 20170811000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170811000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170811000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-08-12T00:00:00
+STEP 20170812000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170812000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170812000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-08-13T00:00:00
+STEP 20170813000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170813000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170813000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-08-14T00:00:00
+STEP 20170814000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170814000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170814000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-08-15T00:00:00
+STEP 20170815000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170815000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170815000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-08-16T00:00:00
+STEP 20170816000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170816000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170816000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-08-17T00:00:00
+STEP 20170817000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170817000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170817000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-08-18T00:00:00
+STEP 20170818000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170818000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170818000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-08-19T00:00:00
+STEP 20170819000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170819000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170819000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-08-20T00:00:00
+STEP 20170820000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170820000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170820000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-08-21T00:00:00
+STEP 20170821000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170821000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170821000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-08-22T00:00:00
+STEP 20170822000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170822000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170822000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-08-23T00:00:00
+STEP 20170823000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170823000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170823000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-08-24T00:00:00
+STEP 20170824000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170824000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170824000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-08-25T00:00:00
+STEP 20170825000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170825000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170825000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-08-26T00:00:00
+STEP 20170826000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170826000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170826000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-08-27T00:00:00
+STEP 20170827000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170827000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170827000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-08-28T00:00:00
+STEP 20170828000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170828000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170828000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-08-29T00:00:00
+STEP 20170829000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170829000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170829000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-08-30T00:00:00
+STEP 20170830000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170830000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170830000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-08-31T00:00:00
+STEP 20170831000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170831000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170831000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-09-01T00:00:00
+STEP 20170901000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170901000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170901000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-09-02T00:00:00
+STEP 20170902000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170902000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170902000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-09-03T00:00:00
+STEP 20170903000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170903000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170903000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-09-04T00:00:00
+STEP 20170904000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170904000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170904000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-09-05T00:00:00
+STEP 20170905000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170905000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170905000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-09-06T00:00:00
+STEP 20170906000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170906000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170906000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-09-07T00:00:00
+STEP 20170907000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170907000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170907000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-09-08T00:00:00
+STEP 20170908000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170908000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170908000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-09-09T00:00:00
+STEP 20170909000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170909000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170909000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-09-10T00:00:00
+STEP 20170910000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170910000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170910000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-09-11T00:00:00
+STEP 20170911000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170911000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170911000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-09-12T00:00:00
+STEP 20170912000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170912000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170912000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-09-13T00:00:00
+STEP 20170913000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170913000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170913000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-09-14T00:00:00
+STEP 20170914000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170914000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170914000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-09-15T00:00:00
+STEP 20170915000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170915000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170915000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-09-16T00:00:00
+STEP 20170916000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170916000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170916000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-09-17T00:00:00
+STEP 20170917000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170917000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170917000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-09-18T00:00:00
+STEP 20170918000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170918000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170918000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-09-19T00:00:00
+STEP 20170919000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170919000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170919000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-09-20T00:00:00
+STEP 20170920000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170920000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170920000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-09-21T00:00:00
+STEP 20170921000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170921000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170921000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-09-22T00:00:00
+STEP 20170922000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170922000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170922000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-09-23T00:00:00
+STEP 20170923000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170923000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170923000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-09-24T00:00:00
+STEP 20170924000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170924000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170924000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-09-25T00:00:00
+STEP 20170925000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170925000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170925000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-09-26T00:00:00
+STEP 20170926000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170926000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170926000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-09-27T00:00:00
+STEP 20170927000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170927000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170927000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-09-28T00:00:00
+STEP 20170928000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170928000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170928000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-09-29T00:00:00
+STEP 20170929000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170929000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170929000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-09-30T00:00:00
+STEP 20170930000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170930000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170930000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-10-01T00:00:00
+STEP 20171001000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20171001000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20171001000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-10-02T00:00:00
+STEP 20171002000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20171002000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20171002000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-10-03T00:00:00
+STEP 20171003000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20171003000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20171003000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-10-04T00:00:00
+STEP 20171004000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20171004000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20171004000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-10-05T00:00:00
+STEP 20171005000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20171005000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20171005000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-10-06T00:00:00
+STEP 20171006000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20171006000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20171006000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-10-07T00:00:00
+STEP 20171007000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20171007000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20171007000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-10-08T00:00:00
+STEP 20171008000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20171008000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20171008000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-10-09T00:00:00
+STEP 20171009000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20171009000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20171009000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-10-10T00:00:00
+STEP 20171010000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20171010000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20171010000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-10-11T00:00:00
+STEP 20171011000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20171011000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20171011000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-10-12T00:00:00
+STEP 20171012000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20171012000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20171012000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-10-13T00:00:00
+STEP 20171013000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20171013000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20171013000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-10-14T00:00:00
+STEP 20171014000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20171014000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20171014000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-10-15T00:00:00
+STEP 20171015000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20171015000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20171015000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-10-16T00:00:00
+STEP 20171016000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20171016000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20171016000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-10-17T00:00:00
+STEP 20171017000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20171017000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20171017000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-10-18T00:00:00
+STEP 20171018000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20171018000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20171018000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-10-19T00:00:00
+STEP 20171019000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20171019000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20171019000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-10-20T00:00:00
+STEP 20171020000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20171020000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20171020000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-10-21T00:00:00
+STEP 20171021000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20171021000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20171021000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-10-22T00:00:00
+STEP 20171022000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20171022000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20171022000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-10-23T00:00:00
+STEP 20171023000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20171023000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20171023000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-10-24T00:00:00
+STEP 20171024000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20171024000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20171024000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-10-25T00:00:00
+STEP 20171025000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20171025000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20171025000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-10-26T00:00:00
+STEP 20171026000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20171026000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20171026000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-10-27T00:00:00
+STEP 20171027000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20171027000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20171027000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-10-28T00:00:00
+STEP 20171028000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20171028000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20171028000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-10-29T00:00:00
+STEP 20171029000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20171029000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20171029000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-10-30T00:00:00
+STEP 20171030000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20171030000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20171030000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-10-31T00:00:00
+STEP 20171031000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20171031000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20171031000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-11-01T00:00:00
+STEP 20171101000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20171101000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20171101000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-11-02T00:00:00
+STEP 20171102000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20171102000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20171102000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-11-03T00:00:00
+STEP 20171103000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20171103000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20171103000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-11-04T00:00:00
+STEP 20171104000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20171104000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20171104000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-11-05T00:00:00
+STEP 20171105000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20171105000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20171105000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-11-06T00:00:00
+STEP 20171106000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20171106000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20171106000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-11-07T00:00:00
+STEP 20171107000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20171107000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20171107000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-11-08T00:00:00
+STEP 20171108000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20171108000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20171108000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-11-09T00:00:00
+STEP 20171109000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20171109000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20171109000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-11-10T00:00:00
+STEP 20171110000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20171110000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20171110000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-11-11T00:00:00
+STEP 20171111000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20171111000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20171111000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-11-12T00:00:00
+STEP 20171112000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20171112000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20171112000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-11-13T00:00:00
+STEP 20171113000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20171113000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20171113000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-11-14T00:00:00
+STEP 20171114000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20171114000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20171114000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-11-15T00:00:00
+STEP 20171115000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20171115000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20171115000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-11-16T00:00:00
+STEP 20171116000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20171116000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20171116000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-11-17T00:00:00
+STEP 20171117000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20171117000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20171117000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-11-18T00:00:00
+STEP 20171118000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20171118000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20171118000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-11-19T00:00:00
+STEP 20171119000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20171119000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20171119000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-11-20T00:00:00
+STEP 20171120000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20171120000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20171120000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-11-21T00:00:00
+STEP 20171121000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20171121000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20171121000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-11-22T00:00:00
+STEP 20171122000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20171122000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20171122000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-11-23T00:00:00
+STEP 20171123000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20171123000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20171123000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-11-24T00:00:00
+STEP 20171124000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20171124000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20171124000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-11-25T00:00:00
+STEP 20171125000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20171125000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20171125000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-11-26T00:00:00
+STEP 20171126000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20171126000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20171126000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-11-27T00:00:00
+STEP 20171127000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20171127000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20171127000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-11-28T00:00:00
+STEP 20171128000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20171128000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20171128000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-11-29T00:00:00
+STEP 20171129000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20171129000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20171129000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-11-30T00:00:00
+STEP 20171130000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20171130000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20171130000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-12-01T00:00:00
+STEP 20171201000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20171201000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20171201000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-12-02T00:00:00
+STEP 20171202000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20171202000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20171202000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-12-03T00:00:00
+STEP 20171203000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20171203000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20171203000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-12-04T00:00:00
+STEP 20171204000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20171204000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20171204000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-12-05T00:00:00
+STEP 20171205000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20171205000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20171205000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-12-06T00:00:00
+STEP 20171206000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20171206000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20171206000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-12-07T00:00:00
+STEP 20171207000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20171207000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20171207000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-12-08T00:00:00
+STEP 20171208000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20171208000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20171208000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-12-09T00:00:00
+STEP 20171209000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20171209000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20171209000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-12-10T00:00:00
+STEP 20171210000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20171210000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20171210000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-12-11T00:00:00
+STEP 20171211000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20171211000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20171211000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-12-12T00:00:00
+STEP 20171212000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20171212000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20171212000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-12-13T00:00:00
+STEP 20171213000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20171213000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20171213000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-12-14T00:00:00
+STEP 20171214000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20171214000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20171214000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-12-15T00:00:00
+STEP 20171215000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20171215000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20171215000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-12-16T00:00:00
+STEP 20171216000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20171216000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20171216000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-12-17T00:00:00
+STEP 20171217000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20171217000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20171217000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-12-18T00:00:00
+STEP 20171218000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20171218000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20171218000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-12-19T00:00:00
+STEP 20171219000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20171219000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20171219000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-12-20T00:00:00
+STEP 20171220000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20171220000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20171220000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-12-21T00:00:00
+STEP 20171221000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20171221000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20171221000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-12-22T00:00:00
+STEP 20171222000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20171222000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20171222000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-12-23T00:00:00
+STEP 20171223000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20171223000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20171223000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-12-24T00:00:00
+STEP 20171224000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20171224000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20171224000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-12-25T00:00:00
+STEP 20171225000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20171225000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20171225000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-12-26T00:00:00
+STEP 20171226000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20171226000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20171226000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-12-27T00:00:00
+STEP 20171227000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20171227000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20171227000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-12-28T00:00:00
+STEP 20171228000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20171228000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20171228000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-12-29T00:00:00
+STEP 20171229000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20171229000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20171229000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-12-30T00:00:00
+STEP 20171230000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20171230000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20171230000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-12-31T00:00:00
+STEP 20171231000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20171231000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20171231000099 TIME_PASSES ELAPSE 86400
+
+
+
+SCENARIO_END
+
diff --git a/modules/ta_update/ta_update.test.integr/rfc5011/README b/modules/ta_update/ta_update.test.integr/rfc5011/README
new file mode 100644
index 0000000..9b71987
--- /dev/null
+++ b/modules/ta_update/ta_update.test.integr/rfc5011/README
@@ -0,0 +1,13 @@
+Start with `genkeyszones.sh` and generate DNSSEC keys + signed versions of `unsigned_*.db`.
+Then use `dns2rpl.py` to run Knot DNS server with signed zone
+and to generate RPL file from server's answers.
+
+Generate RFC5011 test:
+`dns2rpl.py`.
+`./genkeyszones.sh`
+
+Generate unmanaged keys tests:
+`./genkeyszones.sh <--unmanaged_key-presens|--unmanagedkey-missing|--unmanagedkey-revoke>`
+`VARIANT="unmanaged_key" ./dns2rpl.py`
+
+See comments in script headers to further details.
diff --git a/modules/ta_update/ta_update.test.integr/rfc5011/dns2rpl.py b/modules/ta_update/ta_update.test.integr/rfc5011/dns2rpl.py
new file mode 100755
index 0000000..317d671
--- /dev/null
+++ b/modules/ta_update/ta_update.test.integr/rfc5011/dns2rpl.py
@@ -0,0 +1,222 @@
+#!/usr/bin/python3
+"""
+Generate RFC 5011 test simulating successful KSK roll-over in 2017.
+
+Dependencies: Knot DNS server + Deckard library.
+Environment: Set PYTHONPATH variable so "import pydnstest" will use module from Deckard.
+Input: Root zone files, presumably created by genkeyszones.sh.
+Output: RPL file for Deckard on standard output.
+"""
+
+import copy
+import datetime
+import os.path
+import subprocess
+import time
+
+import dns.resolver
+
+import pydnstest.scenario
+
+try:
+ VARIANT = os.environ["VARIANT"]
+except KeyError:
+ VARIANT = ""
+
+def store_answer(qname, qtype, template):
+ answ = dns.resolver.query(qname, qtype, raise_on_no_answer=False)
+ entr = copy.copy(template)
+ entr.message = answ.response
+ return entr
+
+
+def resolver_init():
+ """
+ Configure dns.resolver to ask ::1@5353 with EDNS0 DO set.
+ """
+ dns.resolver.reset_default_resolver()
+ dns.resolver.default_resolver.use_edns(0, dns.flags.DO, 4096)
+ dns.resolver.default_resolver.nameservers = ['::1']
+ dns.resolver.default_resolver.nameserver_ports = {'::1': 5353}
+ dns.resolver.default_resolver.flags = 0
+
+
+def get_templates():
+ """
+ Return empty objects for RANGE and ENTRY suitable as object templates.
+ """
+ empty_case, _ = pydnstest.scenario.parse_file(os.path.realpath('empty.rpl'))
+
+ rng = copy.copy(empty_case.ranges[0])
+
+ entry = copy.copy(rng.stored[0])
+ entry.adjust_fields = ['copy_id']
+ entry.match_fields = ['opcode', 'question']
+
+ rng.addresses = {'198.41.0.4', '2001:503:ba3e::2:30'}
+ rng.stored = []
+
+ return rng, entry
+
+
+def generate_range(filename, rng_templ, entry_templ):
+ """
+ Run Knot DNS server with specified zone file and generate RANGE object.
+ """
+ assert filename.startswith('20')
+ assert filename.endswith('.db')
+ try:
+ os.unlink('root.db')
+ except FileNotFoundError:
+ pass
+ os.link(filename, 'root.db')
+
+ # run server
+ knotd = subprocess.Popen(['knotd', '-c', 'knot.root.conf', '-s', '/tmp/knot-dns2rpl.sock'])
+ time.sleep(0.1) # give kresd time to start so we do not wait for first timeout
+
+ # query data
+ rng = copy.copy(rng_templ)
+ rng.stored = []
+ rng.stored.append(store_answer('.', 'SOA', entry_templ))
+ rng.stored.append(store_answer('.', 'DNSKEY', entry_templ))
+ rng.stored.append(store_answer('.', 'NS', entry_templ))
+ rng.stored.append(store_answer('rootns.', 'NS', entry_templ))
+ rng.stored.append(store_answer('rootns.', 'A', entry_templ))
+ rng.stored.append(store_answer('rootns.', 'AAAA', entry_templ))
+ rng.stored.append(store_answer('test.', 'TXT', entry_templ))
+ rng.a = int(filename[:-len('.db')])
+
+ # kill server
+ knotd.kill()
+
+ return rng
+
+
+def generate_step_query(tcurr, id_prefix):
+ out = '; {0}'.format(tcurr.isoformat())
+ out += '''
+STEP {0}000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+'''.format(id_prefix)
+ return out
+
+
+def generate_step_check(id_prefix):
+ return '''STEP {0}000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+'''.format(id_prefix)
+
+def generate_step_nocheck(id_prefix):
+ return '''STEP {0}000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode qname question
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+'''.format(id_prefix)
+
+def generate_step_finish_msg(id_prefix):
+ return '''STEP {0}000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AA NXDOMAIN
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION AUTHORITY
+test. 10800 IN SOA test. nobody.invalid. 1 3600 1200 604800 10800
+SECTION ADDITIONAL
+explanation.invalid. 10800 IN TXT "check last answer"
+ENTRY_END
+'''.format(id_prefix)
+
+def generate_step_elapse(tstep, id_prefix):
+ out = '; move time by {0}\n'.format(tstep)
+ out += '''STEP {0}000099 TIME_PASSES ELAPSE {1}\n\n'''.format(
+ id_prefix, int(tstep.total_seconds()))
+ return out
+
+
+def main():
+ resolver_init()
+ rng_templ, entry_templ = get_templates()
+ ranges = []
+ check_last_msg = False
+
+ # transform data in zones files into RANGEs
+ files = os.listdir()
+ files.sort()
+ for fn in files:
+ if not fn.endswith('.db') or not fn.startswith('20'):
+ continue
+ ranges.append(generate_range(fn, rng_templ, entry_templ))
+
+ # connect ranges
+ for i in range(1, len(ranges)):
+ ranges[i - 1].b = ranges[i].a - 1
+ ranges[-1].b = 99999999999999
+
+ # steps
+ steps = []
+ tstart = datetime.datetime(year=2017, month=7, day=1)
+ if VARIANT == "unmanaged_key":
+ tend = datetime.datetime(year=2017, month=7, day=21, hour=23, minute=59, second=59)
+ check_last_msg = True
+ else:
+ tend = datetime.datetime(year=2017, month=12, day=31, hour=23, minute=59, second=59)
+ tstep = datetime.timedelta(days=1)
+ tcurr = tstart
+ while tcurr < tend:
+ id_prefix = tcurr.strftime('%Y%m%d')
+ steps.append(generate_step_query(tcurr, id_prefix))
+ if (check_last_msg is True and tcurr + tstep > tend):
+ steps.append(generate_step_finish_msg(id_prefix))
+ elif VARIANT == "unmanaged_key":
+ steps.append(generate_step_nocheck(id_prefix))
+ else:
+ steps.append(generate_step_check(id_prefix))
+ steps.append(generate_step_elapse(tstep, id_prefix))
+ tcurr += tstep
+
+ # generate output
+ with open('keys/ds') as dsfile:
+ tas = dsfile.read().strip()
+
+ # constant RPL file header
+ print("stub-addr: 2001:503:ba3e::2:30")
+ for ta in tas.split('\n'):
+ print ("trust-anchor: " + ta)
+ print("""val-override-date: 20170701000000
+query-minimization: off
+CONFIG_END
+
+SCENARIO_BEGIN Simulation of successful RFC 5011 KSK roll-over during 2017
+ """.format(ta=ta))
+ for rng in ranges:
+ print(rng)
+
+ for step in steps:
+ print(step)
+
+ # constant RPL file footer
+ print('''
+SCENARIO_END
+ ''')
+
+
+if __name__ == '__main__':
+ main()
diff --git a/modules/ta_update/ta_update.test.integr/rfc5011/empty.rpl b/modules/ta_update/ta_update.test.integr/rfc5011/empty.rpl
new file mode 100644
index 0000000..295d5a5
--- /dev/null
+++ b/modules/ta_update/ta_update.test.integr/rfc5011/empty.rpl
@@ -0,0 +1,20 @@
+stub-addr: 127.0.0.10
+CONFIG_END
+
+SCENARIO_BEGIN empty replies
+
+RANGE_BEGIN 0 100
+ ADDRESS 127.0.0.10
+ENTRY_BEGIN
+MATCH subdomain
+ADJUST copy_id copy_query
+SECTION QUESTION
+. IN A
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+ENTRY_END
+
+SCENARIO_END
diff --git a/modules/ta_update/ta_update.test.integr/rfc5011/genkeyszones.sh b/modules/ta_update/ta_update.test.integr/rfc5011/genkeyszones.sh
new file mode 100755
index 0000000..4a65469
--- /dev/null
+++ b/modules/ta_update/ta_update.test.integr/rfc5011/genkeyszones.sh
@@ -0,0 +1,174 @@
+#!/usr/bin/bash
+
+# First, generate DNSSEC keys with timers set to simulate 2017 KSK roll-over.
+# Second, fake system time to pretend that we are at the beginning on time slots
+# used during 2017 and sign our fake root zone.
+
+# Depends on libfaketime + dnssec-keygen and dnssec-signzone from BIND 9.11.
+
+# Output: Bunch of DNSSEC keys + several versions of signed root zone.
+
+set -o nounset -o errexit -o xtrace
+
+GEN="dnssec-keygen -K keys/ -a RSASHA256 -b 2048 -L 21d"
+
+function usage {
+ echo -e "Usage: $0 <option>\n\n\
+Option:\n\
+\t--help\t\t\tShow this help.
+\t--rollover\t\tGenerate files for rollover test.\n\
+\t--unmanagedkey-present\tGenerate files for present new unmanaged key.\n\
+\t--unmanagedkey-missing\tGenerate files for missing unmanaged key.\n\
+\t--unmanagedkey-revoke\tGenerate files for revoked unmanaged key."
+}
+
+function sign () {
+ OUTFILE="$(echo "$1" | sed 's/[- :]//g').db"
+ TZ=UTC \
+ LD_PRELOAD="/usr/lib64/faketime/libfaketimeMT.so.1" \
+ FAKETIME="$1" \
+ dnssec-signzone \
+ -K keys/ \
+ -o . \
+ -S \
+ -T 21d \
+ -s now \
+ -e +14d \
+ -X +21d \
+ -O full \
+ -f "${OUTFILE}" \
+ "$2"
+
+ # DS for the very first KSK
+ test ! -f keys/ds && dnssec-dsfromkey -2 -f "${OUTFILE}" . > keys/ds || : initial DS RR already exists
+}
+
+function test_rollover {
+ # old KSK
+ ${GEN} -f KSK -P 20100715000000 -A 20100715000000 -I 20171011000000 -R 20180111000000 -D 20180322000000 .
+ # new KSK
+ ${GEN} -f KSK -P 20170711000000 -A 20171011000000 .
+
+ # ZSK before roll-over: 2017-Q2
+ ${GEN} -P 20170320000000 -A 20170401000000 -I 20170701000000 -D 20170711000000 .
+ # ZSK-q1: 2017-Q3
+ ${GEN} -P 20170621000000 -A 20170701000000 -I 20171001000000 -D 20171011000000 .
+ # ZSK-q2: 2017-Q4
+ ${GEN} -P 20170919000000 -A 20171001000000 -I 20180101000000 -D 20180111000000 .
+ # ZSK-q3: 2018-Q1
+ ${GEN} -P 20171220000000 -A 20180101000000 -I 20180401000000 -D 20180411000000 .
+ # ZSK: 2018-Q2
+ ${GEN} -P 20180322000000 -A 20180401000000 .
+
+
+ # hopefully slots according to
+ # https://www.icann.org/en/system/files/files/ksk-rollover-operational-implementation-plan-22jul16-en.pdf
+ # https://data.iana.org/ksk-ceremony/29/KC29_Script_Annotated.pdf
+ sign "2017-07-01 00:00:00" # 2017 Q3 slot 1
+ sign "2017-07-11 00:00:00" # 2017 Q3 slot 2
+ sign "2017-07-21 00:00:00" # 2017 Q3 slot 3
+ sign "2017-07-31 00:00:00" # 2017 Q3 slot 4
+ sign "2017-08-10 00:00:00" # 2017 Q3 slot 5
+ sign "2017-08-20 00:00:00" # 2017 Q3 slot 6
+ sign "2017-08-30 00:00:00" # 2017 Q3 slot 7
+ sign "2017-09-09 00:00:00" # 2017 Q3 slot 8
+ sign "2017-09-19 00:00:00" # 2017 Q3 slot 9
+
+ sign "2017-10-01 00:00:00" # 2017 Q4 slot 1
+ sign "2017-10-11 00:00:00" # 2017 Q4 slot 2
+ sign "2017-10-21 00:00:00" # 2017 Q4 slot 3
+ sign "2017-10-31 00:00:00" # 2017 Q4 slot 4
+ sign "2017-11-10 00:00:00" # 2017 Q4 slot 5
+ sign "2017-11-20 00:00:00" # 2017 Q4 slot 6
+ sign "2017-11-30 00:00:00" # 2017 Q4 slot 7
+ sign "2017-12-10 00:00:00" # 2017 Q4 slot 8
+ sign "2017-12-20 00:00:00" # 2017 Q4 slot 9
+
+ # 2018-01-01 00:00:00 # 2018 Q1 slot 1
+ # 2018-01-11 00:00:00 # 2018 Q1 slot 2
+ # 2018-01-21 00:00:00 # 2018 Q1 slot 3
+ # 2018-01-31 00:00:00 # 2018 Q1 slot 4
+ # 2018-02-10 00:00:00 # 2018 Q1 slot 5
+ # 2018-02-20 00:00:00 # 2018 Q1 slot 6
+ # 2018-03-02 00:00:00 # 2018 Q1 slot 7
+ # 2018-03-12 00:00:00 # 2018 Q1 slot 8
+ # 2018-03-22 00:00:00 # 2018 Q1 slot 9
+}
+
+function test_unmanagedkey_present {
+ # old KSK
+ ${GEN} -f KSK -P 20100715000000 -A 20100715000000 -I 20171011000000 -R 20180111000000 -D 20180322000000 .
+ # new KSK
+ ${GEN} -f KSK -P 20170711000000 -A 20171011000000 .
+
+ # ZSKs
+ ${GEN} -P 20170621000000 -A 20170701000000 -I 20171001000000 -D 20171011000000 .
+ ${GEN} -P 20170919000000 -A 20171001000000 -I 20180101000000 -D 20180111000000 .
+
+ sign "2017-07-01 00:00:00" unsigned_ok.db
+ sign "2017-07-11 00:00:00" unsigned_ok.db # present key is seen 10 days
+ sign "2017-07-21 00:00:00" unsigned_check.db # last edited message for check result from deckard
+}
+
+function test_unmanagedkey_revoke {
+ # old KSK
+ ${GEN} -f KSK -P 20100715000000 -A 20100715000000 -I 20171011000000 -R 20180111000000 -D 20180322000000 .
+ # revoked KSK
+ ${GEN} -f KSK -P 20100715000000 -A 20100715000000 -I 20171011000000 -R 20170710000000 -D 20180322000000 .
+
+ # ZSKs
+ ${GEN} -P 20170621000000 -A 20170701000000 -I 20171001000000 -D 20171011000000 .
+ ${GEN} -P 20170919000000 -A 20171001000000 -I 20180101000000 -D 20180111000000 .
+
+ sign "2017-07-01 00:00:00" unsigned_ok.db
+ sign "2017-07-11 00:00:00" unsigned_ok.db # revoke key is seen 10 days
+ sign "2017-07-21 00:00:00" unsigned_check.db # last edited message for check result from deckard
+}
+
+function test_unmanagedkey_missing {
+ # old KSK
+ ${GEN} -f KSK -P 20100715000000 -A 20100715000000 -I 20171011000000 -R 20180111000000 -D 20180322000000 .
+ # missing KSK
+ ${GEN} -f KSK -P 20100715000000 -A 20100715000000 -I 20171011000000 -R 20180111000000 -D 20170710000000 .
+
+ # ZSKs
+ ${GEN} -P 20170621000000 -A 20170701000000 -I 20171001000000 -D 20171011000000 .
+ ${GEN} -P 20170919000000 -A 20171001000000 -I 20180101000000 -D 20180111000000 .
+
+ sign "2017-07-01 00:00:00" unsigned_ok.db
+ sign "2017-07-11 00:00:00" unsigned_ok.db # missing key is seen 10 days
+ sign "2017-07-21 00:00:00" unsigned_check.db # last edited message for check result from deckard
+}
+
+if [ $# -ne 1 ]; then
+ usage
+ exit 0
+fi
+
+rm -f 20*.db
+rm -f keys/K*
+rm -f keys/ds
+mkdir -p keys/
+
+case $1 in
+ --rollover)
+ test_rollover
+ ;;
+ --unmanagedkey-present)
+ test_unmanagedkey_present
+ #test_rollover
+ ;;
+ --unmanagedkey-revoke)
+ test_unmanagedkey_revoke
+ ;;
+ --unmanagedkey-missing)
+ test_unmanagedkey_missing
+ ;;
+ --help|-h)
+ usage
+ ;;
+ *)
+ echo -e "Unknown option !\n\n"
+ usage
+ ;;
+esac
diff --git a/modules/ta_update/ta_update.test.integr/rfc5011/knot.root.conf b/modules/ta_update/ta_update.test.integr/rfc5011/knot.root.conf
new file mode 100644
index 0000000..5e20747
--- /dev/null
+++ b/modules/ta_update/ta_update.test.integr/rfc5011/knot.root.conf
@@ -0,0 +1,26 @@
+#
+# Minimal configuration file for Knot DNS server used by dns2rpl.py.
+#
+
+server:
+ # Listen on all configured IPv4 interfaces.
+ listen: 0.0.0.0@5353
+ # Listen on all configured IPv6 interfaces.
+ listen: ::@5353
+ # User for running the server.
+ # user: knot:knot
+# Log info and more serious events to syslog.
+log:
+ - target: stderr
+ any: debug
+
+template:
+# - id: default
+# storage: "/usr/local/var/lib/knot"
+
+zone:
+# Master zone.
+ - domain: .
+ storage: "."
+ file: "root.db"
+
diff --git a/modules/ta_update/ta_update.test.integr/rfc5011/pydnstest b/modules/ta_update/ta_update.test.integr/rfc5011/pydnstest
new file mode 120000
index 0000000..331fa73
--- /dev/null
+++ b/modules/ta_update/ta_update.test.integr/rfc5011/pydnstest
@@ -0,0 +1 @@
+../../../../tests/integration/deckard/pydnstest \ No newline at end of file
diff --git a/modules/ta_update/ta_update.test.integr/rfc5011/unsigned_check.db b/modules/ta_update/ta_update.test.integr/rfc5011/unsigned_check.db
new file mode 100644
index 0000000..cf03621
--- /dev/null
+++ b/modules/ta_update/ta_update.test.integr/rfc5011/unsigned_check.db
@@ -0,0 +1,8 @@
+. 86400 IN SOA rootns. you.test. 2017071100 1800 900 604800 86400
+
+. 518400 IN NS rootns.
+
+rootns. 518400 IN A 198.41.0.4
+rootns. 518400 IN AAAA 2001:503:ba3e::2:30
+
+test. 1 IN TXT "check and change answer"
diff --git a/modules/ta_update/ta_update.test.integr/rfc5011/unsigned_ok.db b/modules/ta_update/ta_update.test.integr/rfc5011/unsigned_ok.db
new file mode 100644
index 0000000..b837acd
--- /dev/null
+++ b/modules/ta_update/ta_update.test.integr/rfc5011/unsigned_ok.db
@@ -0,0 +1,8 @@
+. 86400 IN SOA rootns. you.test. 2017071100 1800 900 604800 86400
+
+. 518400 IN NS rootns.
+
+rootns. 518400 IN A 198.41.0.4
+rootns. 518400 IN AAAA 2001:503:ba3e::2:30
+
+test. 1 IN TXT "it works"
diff --git a/modules/ta_update/ta_update.test.integr/rfc5011_unsupported_key_rollover.rpl b/modules/ta_update/ta_update.test.integr/rfc5011_unsupported_key_rollover.rpl
new file mode 100644
index 0000000..77fbd35
--- /dev/null
+++ b/modules/ta_update/ta_update.test.integr/rfc5011_unsupported_key_rollover.rpl
@@ -0,0 +1,91 @@
+; SPDX-License-Identifier: GPL-3.0-or-later
+ trust-anchor: ". IN DS 13876 8 2 240B81A3498168E9F1FF85F83C24B63994D91D0569D7FB13C87E0D59AA8EB2DD"
+ val-override-date: "20190313000000"
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+ query-minimization: off
+CONFIG_END
+
+SCENARIO_BEGIN RFC 5011 key rollover to unsupported algorhitm.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ ADDRESS 2001:7fd::1
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. 518400 IN NS k.root-servers.net.
+. 518400 IN RRSIG NS 8 0 518400 20190326123543 20190312123543 13191 . kyHWRA9F6SKNXHKbB/roiZIUYvsQXdRzdTYZBWeiHb2puAug4h8NqdU9 yJwOpW7lzZyQILshzThh1NXueSOyJ7VYqxgAqIMiQ7hTKXvgfPsDPZYK hl05XtUZYmXQO5gdXyeKbcsI/oC4yom3IU7wt81Y18CJnlKmbY4hAf7e aDAluhbL4H9/4dXWyVBNKk8aOzHnusWjbyFdb/+UlGVEv62RhXYYMuWy c1v/8uSc1CHSgS9ef1krVkqstJtaob5lysa6Vko08XTsDKmyUJXrhhgz wzmZKaVpthAM58dMm+Twho+tLpQ2HApZUOa6Z7F9Rc2QnNLMJLRl7Iz+ fq7JBg==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+. IN DNSKEY
+SECTION ANSWER
+. 1814400 IN DNSKEY 257 3 253 AwEAAcVR4S9H/xPz0EZNso6tsX+z/CLhzwsDNbPVQNWddu5YP04iHKkA prBuseYVwswkQm14Jqr7u2oLOMDJ0Vn0tbw7UfBDD9nLlMhi8X3l8X++ T7xzqn99xL+8Ad0L5xQwRR7dlij8SuL0DuNhWpWmKwPDP7mI/oTNSYLD 3U/zm023Wgq+mrx+7w9Or7bh9Fo/bPN54RsTQ3BIg7LM2/wmLKtHZqiR lpyCF5gQ+eUSR6JGDfedjrvl+ywEl7dcmF11MV69pyAeASNo9+mvknwx VearXoz1KcNiCpgNmuu3lBQvoygTVmDw0RvYiWkVUmm/b+mo6hsYz6O+ XSRya8C681c=
+. 1814400 IN DNSKEY 257 3 8 AwEAAcVR4S9H/xPz0EZNso6tsX+z/CLhzwsDNbPVQNWddu5YP04iHKkA prBuseYVwswkQm14Jqr7u2oLOMDJ0Vn0tbw7UfBDD9nLlMhi8X3l8X++ T7xzqn99xL+8Ad0L5xQwRR7dlij8SuL0DuNhWpWmKwPDP7mI/oTNSYLD 3U/zm023Wgq+mrx+7w9Or7bh9Fo/bPN54RsTQ3BIg7LM2/wmLKtHZqiR lpyCF5gQ+eUSR6JGDfedjrvl+ywEl7dcmF11MV69pyAeASNo9+mvknwx VearXoz1KcNiCpgNmuu3lBQvoygTVmDw0RvYiWkVUmm/b+mo6hsYz6O+ XSRya8C681c=
+. 1814400 IN DNSKEY 256 3 8 AwEAAZ7wwdoX/a2Va1Wx5tlTF/gVpznA/m1m7jvhnEjHCVE6iGQW3qII +tL87ScygLKV25ATPmfjIIkIIG7/NSx66eo2KiJusDjzUR8BQWcy/SHd k+r8yCifsIYTaKqgtnj91gYPoY22bG4CUt8/v1hl9FWh+C+X6occdmLr uXxeo6UOhORkM9oVcK2tOLgK1oedarg5z663JmQdEjwPkgYS7QazCAHh m3eQF8n6mD1AqKh1O6uNaVmLh3mvaI2K/0E9jRfefHJgWh1v2PfRtqlG j9idQkBZX+3IclEx8BoSXrRxVdehBvyntS+eqgx/YBOnJcdH1kOls/s2 0ZknTVQvOdE=
+. 1209600 IN RRSIG DNSKEY 8 0 1814400 20190402125328 20190312125328 13876 . qy0f6TfZls3/njJKIQlpZC3/Zq7e1O7VUFtEDiDCk8vU23PeARcMNDfb Io9VPE4MqUtHDJ7DuHUlSttLwH4KZUK7uoYW74Ii6YlnE+2pci1lj8Bn PlodQiOAhrpeH6BdZe55La5uGFE/GB7w9vbjVf6ytz5HBrdFUFoxg5V/ vUwnZS12eW0JY8HXZ7kdiyr/z9eOIRmUYIZHTXDzT5MJBYAaoDXBqE0j DKwxTn5Wx5/O2KthiRYc0j44hEQBawQnL0upBRmof+iAuUInoMBrk1u8 Ylr7RSbvS69qs8lkWGPC6VSKvAnludzcTW79K5avz3jST6rccSowuFNI oyN5UA==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+k.root-servers.net. IN AAAA
+SECTION ANSWER
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+k.root-servers.net. 1209600 IN RRSIG AAAA 8 3 3600000 20190326123543 20190312123543 13191 . GNsOgKS3KLLHf7J05LRrLHoWWq8qtcyLoT9x5b4fk6yQvSjbRrYxjxsv kUR9f3RE+dPndevDv/GI5PHQ/UKgWeVQEvyhU5QjgveR/AvULIy3dk8f FzkOd/USy931BrOCJF2Zqzw0pHavjotdDVsoVWwwgjNlrahtKFP+e8Bm qD7C1NVrncv9bmMYNlH/ZrPniXR1pWYt4294rrSUSqoH+tVxmwdwX2kL SU/c/a4p+7ST/+GhsG26QBl0K/OJP7nAwdKP1gQBUoKDRUIzXlPdDIc8 fvDaYPq8iKYA5QHAXy3Fvd4Z02J9iTc1/vTncDJata3CNUk2B295f5F/ uk+a0Q==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+k.root-servers.net. IN A
+SECTION ANSWER
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 1209600 IN RRSIG A 8 3 3600000 20190326123543 20190312123543 13191 . fi34mMaQ+cEP1mueazJ3YXBOTKX5FGU9hZGQKMogrKLw4jwItTaxBtl2 CYCMP8B2rX9bAhBNjvqxqT5Lj1LJfomKLi+eVQhGONL3t8TgIFml6Z72 7d2qr/AiGgNH71tF/mbf5xFKrIOx37k0is3nRSmbB1FWMuvpVtlPFBey H1rAF/o69jnI7xvFu4TnQHQM+tG/NeCa1fBTJB2J02gS2XUBgPIk9f1a bkuf7nofj7tEN7+jHv2U3dDFDoMafcYIgzF/wlieqDTorBi9SkT68+nh hpJAG29d0rbG3CWUPI6Tm6El8eH+3hC6B8Emc3T30m3R5E/A4VJsbsOt vKBUIQ==
+ENTRY_END
+
+; QTYPE == RRSIG is not supported, https://tools.ietf.org/html/draft-ietf-dnsop-refuse-any-04#section-7
+ENTRY_BEGIN
+MATCH opcode qtype
+ADJUST copy_id copy_query
+REPLY QR AA REFUSED
+SECTION QUESTION
+. IN RRSIG
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+. IN NS
+ENTRY_END
+
+
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH opcode qname flags rcode question answer
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. 518400 IN NS k.root-servers.net.
+. 518400 IN RRSIG NS 8 0 518400 20190326123543 20190312123543 13191 . kyHWRA9F6SKNXHKbB/roiZIUYvsQXdRzdTYZBWeiHb2puAug4h8NqdU9 yJwOpW7lzZyQILshzThh1NXueSOyJ7VYqxgAqIMiQ7hTKXvgfPsDPZYK hl05XtUZYmXQO5gdXyeKbcsI/oC4yom3IU7wt81Y18CJnlKmbY4hAf7e aDAluhbL4H9/4dXWyVBNKk8aOzHnusWjbyFdb/+UlGVEv62RhXYYMuWy c1v/8uSc1CHSgS9ef1krVkqstJtaob5lysa6Vko08XTsDKmyUJXrhhgz wzmZKaVpthAM58dMm+Twho+tLpQ2HApZUOa6Z7F9Rc2QnNLMJLRl7Iz+ fq7JBg==
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+SCENARIO_END
diff --git a/modules/ta_update/ta_update.test.lua b/modules/ta_update/ta_update.test.lua
new file mode 100644
index 0000000..4d6b0ff
--- /dev/null
+++ b/modules/ta_update/ta_update.test.lua
@@ -0,0 +1,84 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+-- shorten update interval
+modules.load('ta_update')
+ta_update.refresh_time = 0.5 * sec
+ta_update.hold_down_time = 1 * sec
+sleep_time = 1.5
+
+-- prevent build-time config from interfering with the test
+trust_anchors.remove('.')
+
+-- count . IN DNSKEY queries
+counter = 0
+local function counter_func (state, req)
+ local answer = req:ensure_answer()
+ if answer == nil then return nil end
+ local qry = req:current()
+ if answer:qclass() == kres.class.IN
+ and qry.stype == kres.type.DNSKEY
+ and kres.dname2wire(qry.sname) == '\0' then
+ counter = counter + 1
+ end
+ return state
+end
+policy.add(policy.all(counter_func))
+
+local function test_ta_update_vs_trust_anchors_dependency()
+ ok(ta_update, 'ta_update module is loaded by default')
+
+ assert(counter == 0, 'test init must work')
+ same(trust_anchors.add_file('root.keys'), nil, 'load managed TA for root zone')
+ same(trust_anchors.keysets['\0'].managed, true, 'managed TA has managed flag')
+ same(type(ta_update.tracked['\0'].event), 'number', 'adding managed TA starts tracking')
+ same(counter, 0, 'TA refresh is only scheduled')
+ worker.sleep(sleep_time)
+ ok(counter > 0, 'TA refresh asked for TA DNSKEY after some time')
+
+ same(ta_update.stop('\0'), nil, 'key tracking can be stopped')
+ same(ta_update.tracked['\0'], nil, 'stopping removed metadata')
+ same(trust_anchors.keysets['\0'].managed, false, 'now unmanaged TA does not have managed flag')
+ counter = 0
+ worker.sleep(sleep_time)
+ same(counter, 0, 'stop() actually prevents further TA refreshes')
+
+ ok(modules.unload('ta_update'), 'module can be unloaded')
+ same(ta_update, nil, 'unloaded module is nil')
+
+ ok(trust_anchors.remove('.'), 'managed root TA can be removed')
+ same(trust_anchors.keysets['\0'], nil, 'TA removal works')
+end
+
+local function test_unloaded()
+ same(ta_update, nil, 'ta_update module is nil')
+ same(trust_anchors.add_file('root.keys', false), nil, 'managed TA can be added with unloaded ta_update module')
+ ok(ta_update ~= nil, 'ta_update module automatically loaded')
+ ok(modules.unload('ta_update'), 'ta_update module can be unloaded')
+ same(ta_update, nil, 'ta_update module is nil')
+
+ same(trust_anchors.add_file('root.keys', true), nil, 'unmanaged TA can be added with unloaded ta_update module')
+ ok(ta_update ~= nil, 'ta_update module automatically loaded')
+
+ ok(trust_anchors.remove('.'), 'unmanaged root TA can be removed')
+ same(trust_anchors.keysets['\0'], nil, 'TA removal works')
+
+end
+
+local function test_reload()
+ ok(modules.load('ta_update'), 'module can be re-loaded')
+ same(trust_anchors.add_file('root.keys', false), nil, 'managed TA can be added after loading ta_update module')
+ same(counter, 0, 'TA refresh is only scheduled')
+ worker.sleep(sleep_time)
+ ok(counter > 0, 'TA refresh asked for TA DNSKEY after some time')
+end
+
+local function test_err_inputs()
+ ok(modules.load('ta_update'), 'make sure module is loaded')
+ boom(ta_update.start, {'\12nonexistent'}, 'nonexistent TA cannot be tracked')
+end
+
+return {
+ test_ta_update_vs_trust_anchors_dependency,
+ test_unloaded,
+ test_reload,
+ test_err_inputs,
+}
diff --git a/modules/ta_update/ta_update.unmanagedkey.test.integr/deckard.yaml b/modules/ta_update/ta_update.unmanagedkey.test.integr/deckard.yaml
new file mode 100644
index 0000000..eab0592
--- /dev/null
+++ b/modules/ta_update/ta_update.unmanagedkey.test.integr/deckard.yaml
@@ -0,0 +1,12 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+programs:
+- name: kresd
+ binary: kresd
+ additional:
+ - --noninteractive
+ templates:
+ - modules/ta_update/ta_update.unmanagedkey.test.integr/kresd_config.j2
+ - tests/integration/hints_zone.j2
+ configs:
+ - config
+ - hints
diff --git a/modules/ta_update/ta_update.unmanagedkey.test.integr/kresd_config.j2 b/modules/ta_update/ta_update.unmanagedkey.test.integr/kresd_config.j2
new file mode 100644
index 0000000..263404d
--- /dev/null
+++ b/modules/ta_update/ta_update.unmanagedkey.test.integr/kresd_config.j2
@@ -0,0 +1,72 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+
+{% for TAF in TRUST_ANCHOR_FILES %}
+trust_anchors.add_file('{{TAF}}', true)
+{% endfor %}
+
+{% raw %}
+
+local cb_counter = 0
+function inc_cb()
+ cb_counter = cb_counter + 1
+end
+
+function check_status(state, query)
+ -- status was present for 10 days
+ if cb_counter > 0 then
+ return policy.DENY_MSG('check last answer')
+ end
+end
+ta_update.refresh_time = 12 * hour
+ta_update.cb_unmanagedkey_change = inc_cb
+policy.add(check_status, true)
+
+-- Disable RFC8145 signaling, scenario doesn't provide expected answers
+if ta_signal_query then
+ modules.unload('ta_signal_query')
+end
+
+-- Disable RFC8109 priming, scenario doesn't provide expected answers
+if priming then
+ modules.unload('priming')
+end
+
+-- Disable this module because it make one priming query
+if detect_time_skew then
+ modules.unload('detect_time_skew')
+end
+
+policy.add(policy.suffix(policy.PASS, {todname('test.')}))
+cache.size = 2*MB
+log_level('debug')
+{% endraw %}
+
+modules.load('hints')
+hints.root({['{{ROOT_NAME}}'] = '{{ROOT_ADDR}}'})
+
+net = { '{{SELF_ADDR}}' }
+
+
+{% if QMIN == "false" %}
+option('NO_MINIMIZE', true)
+{% else %}
+option('NO_MINIMIZE', false)
+{% endif %}
+
+
+-- Self-checks on globals
+assert(help() ~= nil)
+assert(worker.id ~= nil)
+-- Self-checks on facilities
+assert(cache.count() == 0)
+assert(cache.stats() ~= nil)
+assert(cache.backends() ~= nil)
+assert(worker.stats() ~= nil)
+assert(net.interfaces() ~= nil)
+-- Self-checks on loaded stuff
+assert(net.list()[1].transport.ip == '{{SELF_ADDR}}')
+assert(#modules.list() > 0)
+-- Self-check timers
+ev = event.recurrent(1 * sec, function (ev) return 1 end)
+event.cancel(ev)
+ev = event.after(0, function (ev) return 1 end)
diff --git a/modules/ta_update/ta_update.unmanagedkey.test.integr/rfc5011 b/modules/ta_update/ta_update.unmanagedkey.test.integr/rfc5011
new file mode 120000
index 0000000..b467cd6
--- /dev/null
+++ b/modules/ta_update/ta_update.unmanagedkey.test.integr/rfc5011
@@ -0,0 +1 @@
+../ta_update.test.integr/rfc5011 \ No newline at end of file
diff --git a/modules/ta_update/ta_update.unmanagedkey.test.integr/unmanagedkey-missing-monotonictime.rpl b/modules/ta_update/ta_update.unmanagedkey.test.integr/unmanagedkey-missing-monotonictime.rpl
new file mode 100644
index 0000000..334d959
--- /dev/null
+++ b/modules/ta_update/ta_update.unmanagedkey.test.integr/unmanagedkey-missing-monotonictime.rpl
@@ -0,0 +1,758 @@
+stub-addr: 2001:503:ba3e::2:30
+stub-name: rootns.
+trust-anchor: . IN DS 15116 8 2 6743F544CF087FE23094D4FC1305F6B9C4EEFA2025B4FC348A622CE202F5DD4B
+trust-anchor: . IN DS 45050 8 2 DB11ECB4E98390817B2D4BBBE73D7FDFE7ECC418E006EEF6EA05044E565A3733
+val-override-date: 20170701000000
+query-minimization: off
+CONFIG_END
+
+SCENARIO_BEGIN Simulation of successfull RFC 5011 KSK roll-over during 2017
+
+
+RANGE_BEGIN 20170701000000 20170710999999
+ ADDRESS 198.41.0.4
+ ADDRESS 2001:503:ba3e::2:30
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. IN SOA
+SECTION ANSWER
+. 86400 IN SOA rootns. you.test. 2017071100 1800 900 604800 86400
+. 86400 IN RRSIG SOA 8 0 86400 20170715000000 20170701000000 31500 . dPoTEA/PKBUCWNsGLH27WXLRSoQBpgw4 R0cAGdXZHVlYTZzfaHAmfgvoZOeoT0pt 11584nVWOTJDH3p0bDgJBTLsCbs3IeTx SnrZQxWP6/WvyK3NwAxI9q8amEIf8Rin JQCiTOvxdVnb5lrDZt3bzgCTvWm0EqVy 4WjewqhhduiWYq5sRjqDMSKbbP9zGE4l 9gaCgIJA4zPvcedYpqQpmDnITM1SlpLH /JtpPVVstLTV1MmfmvY1ay3FMYRMr0FU 7FKHtKmY+RSaRWzno3ghWPi3PZrc9J5Z dyS8EfD+dpFibv+auFp43NnVL+mISQ+/ nfKLf8PYT8DDBog7OlaCsQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. IN DNSKEY
+SECTION ANSWER
+. 1814400 IN DNSKEY 256 3 8 AwEAAecpzqv0lz4aTPxYhm+LlvNVtLCq LhWvBuUdPoOxVO99j/KDXEdslHRfRLlf ZHi5KBfGLBwW13VeO9bzv+/62PycepCH WyE4I+IHSgVau1vkCtfRtX5wp8EMPyqU MtHPvuForHdp3ZWepuZh8i8TUgEGn3F+ ISS6yyy10gR8fPTSmXui6ZWPk+yarFNC /BosJPw0Y5gkPIltk9oHeWcTTwd1XpqP b2Pm4FdRN8rpJGvx5livyVdrEAXMnlV9 PqCtJVLBq4HN7LJmXde+ODLmzVP1JgaO qC9vlu2vKL2AlKW5BCCL9gt0+XeFU3KH qrs5GgnX2xVKoIzA9Sraepg+3i0=
+. 1814400 IN DNSKEY 257 3 8 AwEAAa4D+Q6MqSfx9vyCCGlOHYAbbxo9 buybBLpq2Q08j+cUDc1/pSVSmYfJ3Xup QcFc7Ney7BUrPqRfzQyL/NHEtupWyLJ/ gstz55oiEXw8RCsYZH+nay4nPthtQ+nt FSAZpw32ED0CHH87ENxxxfkB1hkT78ru RG5pYT+qGeSDXGrkYSHGNSfS7YB7RX9h Q1/RM8ef/QyKqLkFli6OPvLa6u0eCAI1 IHvHbQvieoVioWaJ7jmKxMwIONQfMbYH 8Hs2JeBgNhaH4qHDJdLJePJNuht6NZ2K 0vfcDpkDbj/6r9XpJiEEjB7iFIfhc/ya Tkyu7tIUwXs7tTDALi7gpOk3kL0=
+. 1814400 IN DNSKEY 257 3 8 AwEAAcfEF/AXBm9m/eLNdnsq4O5otNVD zNmdViy4pC1paInyq7tgy8blsivvpy7X Hh/xnFPCX6XRMUxxpe7Afuc9BITwepap rIdM/j4QOIeuQbLSxhzay1jdsCWMHFQ3 hMQeXZ8X05oxnIKihnfISyhqyaNdlY2k 4ApVHDF6ugDd1+Zu4T/5M9DIhxCTHpVo hctCzkgFP9tRocAlIwptcoZLdR3LxdXk OJ9tfSOuqHnQ4Zh8Aj407rVtz6CWQGyg qO+fb+Y98DI3V7IYisnW18r7QorMUycA OuDnnlZSvkrcWgtpuyylTsqhs/3+73iK kb0QUKscoTeSLgeoocFN+r8ZfaM=
+. 1814400 IN RRSIG DNSKEY 8 0 1814400 20170722000000 20170701000000 15116 . mkcwXhObb+tZcwBexTnJQU9xFXI4DYLH P3J80/mYHj3r/6542Wd4+IscpVIFhtxf WsFQhvzS7IZevSbOojRYPjLIKpaa+WnU zYOi4n5vNq5PWzXd1Y5tHqDCxF6fQB4H SfI2GB/a37s3GnaEWA+ECzIZiC0xxASt obIkWkYoqLaI6aMILOSjXHJxKbY1wNPm SGm+RohpjYmgLzFAD3NJNqleYexcarrK +pfbeBoQFmAq3wJqCRnPYfAfivFA2mDN 2PMI+K6hx1Wf/NmmPM2a+UoPREashEe6 exbC7XZbs10aP8gCgHkGmGWgSlbLqFpx 9f2GBjotJsEbJCumiT6hpA==
+. 1814400 IN RRSIG DNSKEY 8 0 1814400 20170722000000 20170701000000 31500 . DOjVyLlWPX1DpvYhWHoh/LHXqTJK2SIG yp7iLXnmkb3SCFslOcVwYm2m0xfRplZo dA/HhFdT+cJ1wlXZSXBm17QgDK9hNhnm kmstpbv+xj/Pf31TJkHRS2Mn7FtQTRKE zJGMJvnfgY2PMpAwVyDMc2psA5AJbx47 uS5+JJgDcnnfM8OoTkT3RkHKV942nWTo lhpyBnj1Ymzvlc1DxVW1DIJjnQjoU9PZ sJT4NESMJyF/cskELuSqyqvrUC7WAnNU hhE0rcTBhxJpA9iaCW+Jn/CGTxR5Hrmq Vlyf4ctduNwuOl+puA9RNj7+JnBX6EN+ KM1NqxpSI+gcHSEj9MXejA==
+. 1814400 IN RRSIG DNSKEY 8 0 1814400 20170722000000 20170701000000 45050 . mi9PqTNCsum4+302sDVzJW4RJsW3Gtec 3+Z/5CKa5cP0l+w/5g6mWV1eBeT3ZeF7 kkleUP7chgtHmh1d/q24OE7R+R+iZrf7 OP1SJRN4cxeliM1mJFGz67YFkWzqzwiU +WbuAg/HBgGmtSO/6QlwRtBEbx8LwZx5 6OIHEUVCYEPdk96iU6wAcgc9RkkBVrJz M8UEbSFI5WNbWKJMfT6BqgFPd84AslqN lxZm0WNGP2xdsdVR9TSx2dTUiXdTymi/ x61AFQKn6hlf5cY6LZPOR5JquqXtAgV2 xf3XtOjnFaH81IECqXA/cRrR7Y3Oxl01 Fl3A9C0BBpOH2ngQwHyhiw==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. 518400 IN NS rootns.
+. 518400 IN RRSIG NS 8 0 518400 20170715000000 20170701000000 31500 . fWSlKWRwiYLYHxZi7z/0lFEhGd7uJrnJ BCe5cY0MVWuhNKx/k331hulrolI6NBrJ Tek6rMtkHpg4fF4x8yTFYS0lNhMI/dJk AZP+7w16T4YCtEwQdqfaPLV+Q0xxSGyI f1tqkQ7iLzrjBHc91IdSKysY0N/z3A0H VwpELudEq6P840ocrolQpxHLD0TgvrXe PO4+Wrg9G122fpvB7WGvufiKRyU2qVGZ hUa++t+JKe8sdCPXe8fe+njD6iOBOBUx WMXxJ92zV92KfxdyvwEaFyPVUAEmHFyc zUQHMmPPAoR2Uy7b4etXlBN5pgYwYk/O tmAuyKNJg38Frdz/TK7F3A==
+SECTION ADDITIONAL
+rootns. 518400 IN A 198.41.0.4
+rootns. 518400 IN AAAA 2001:503:ba3e::2:30
+rootns. 518400 IN RRSIG A 8 1 518400 20170715000000 20170701000000 31500 . mA/R6+XmbyI0ljRHtTaDpu1fgm7/XGvE UMwmNqieJ/z7RbJ38yvGnfKDERhKBhQr 7EPdCSldpwg8LXx70Luu/kklvvxn20Aj my8hWGW4Hsl+C2qVZ10qzHxbx0lDgnK6 JKYBLdCnDXHS8KfXkrFIeWFdZWGXpcOt mPppEG4sp8OhpVohgiU/WGZQWs3TjeO0 k85iq4g5QLOeQnRKlCaX2S6wlNOTfcvi j8iuUjcMstx0z5MWMn9RuFvKYXM0aWwT d+QMLBEt16LBCF52mxKy9RD7Wi5zIo1T SfxAxvXofrsnw48UZ4PpnE0K6bCzW//M rJMycfKaqjPDN2nabZHIqQ==
+rootns. 518400 IN RRSIG AAAA 8 1 518400 20170715000000 20170701000000 31500 . xLCTTIMJwqN9qDMm4tggaqUtf5pq7V5/ 0n6YT6Be9lstyIVL32ra94lJtjeF8gUA Ys1ugC9y9j88pYLcD+/IWSHvQ6FhZU73 XZA5wm6da2NQnyOXZSEofz/E7Arlmy7y Dojb9zmzgaUEEqnvQ4koqhpENbq4oTSp aJ7/UpsRrXUwrwJdxPnu2EW2hCgyFQ2i uAra/Bmzl046hAOTGzjUbbNgJt3JaLu4 qYKNcs/yUqGoZdcU/OOYfxFoAI1I+K/s FqCoVYV4yjQ6sB0s3isjoJT0fN1/QGMR 6a+ebQJ/B0B3Ch+VcC4abpMkWafTrOY/ J2KTNzvbXD9X2as1y6pa+w==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rootns. IN NS
+SECTION AUTHORITY
+. 86400 IN SOA rootns. you.test. 2017071100 1800 900 604800 86400
+rootns. 86400 IN NSEC test. A AAAA RRSIG NSEC
+. 86400 IN RRSIG SOA 8 0 86400 20170715000000 20170701000000 31500 . dPoTEA/PKBUCWNsGLH27WXLRSoQBpgw4 R0cAGdXZHVlYTZzfaHAmfgvoZOeoT0pt 11584nVWOTJDH3p0bDgJBTLsCbs3IeTx SnrZQxWP6/WvyK3NwAxI9q8amEIf8Rin JQCiTOvxdVnb5lrDZt3bzgCTvWm0EqVy 4WjewqhhduiWYq5sRjqDMSKbbP9zGE4l 9gaCgIJA4zPvcedYpqQpmDnITM1SlpLH /JtpPVVstLTV1MmfmvY1ay3FMYRMr0FU 7FKHtKmY+RSaRWzno3ghWPi3PZrc9J5Z dyS8EfD+dpFibv+auFp43NnVL+mISQ+/ nfKLf8PYT8DDBog7OlaCsQ==
+rootns. 86400 IN RRSIG NSEC 8 1 86400 20170715000000 20170701000000 31500 . czXWsvkZgPgtICpYspe8ny5sloUCCQ01 S4CwdGKFkyoOh0jvnL/iGa9X4TtTeTry 2gtT8+Azuvaq/rXXG4hrSmvQloCyDMtD Qy86So9w8nMxGBnXW/fHqt0mgYBoYmw4 PYM6vrOwMOxh/db8qMdHz/MdHPUWxUNG t+2LJ55RwUlb4YFtLzcNUe3CPf7nydSY y8lDbDz6GzbwGz65mUN8/rjeEOaRaQON rb+1ETXGKX7aFga/0t0GBTEjkwAKbaV/ 7nBk9CYR4IpeIIMuHPQiSEenzhXEjDMx Z6pue7+DrFuw/yFfvNeArQ4XLPglMzM+ YigxHXt8Z1d8CJzeImCWmA==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rootns. IN A
+SECTION ANSWER
+rootns. 518400 IN A 198.41.0.4
+rootns. 518400 IN RRSIG A 8 1 518400 20170715000000 20170701000000 31500 . mA/R6+XmbyI0ljRHtTaDpu1fgm7/XGvE UMwmNqieJ/z7RbJ38yvGnfKDERhKBhQr 7EPdCSldpwg8LXx70Luu/kklvvxn20Aj my8hWGW4Hsl+C2qVZ10qzHxbx0lDgnK6 JKYBLdCnDXHS8KfXkrFIeWFdZWGXpcOt mPppEG4sp8OhpVohgiU/WGZQWs3TjeO0 k85iq4g5QLOeQnRKlCaX2S6wlNOTfcvi j8iuUjcMstx0z5MWMn9RuFvKYXM0aWwT d+QMLBEt16LBCF52mxKy9RD7Wi5zIo1T SfxAxvXofrsnw48UZ4PpnE0K6bCzW//M rJMycfKaqjPDN2nabZHIqQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rootns. IN AAAA
+SECTION ANSWER
+rootns. 518400 IN AAAA 2001:503:ba3e::2:30
+rootns. 518400 IN RRSIG AAAA 8 1 518400 20170715000000 20170701000000 31500 . xLCTTIMJwqN9qDMm4tggaqUtf5pq7V5/ 0n6YT6Be9lstyIVL32ra94lJtjeF8gUA Ys1ugC9y9j88pYLcD+/IWSHvQ6FhZU73 XZA5wm6da2NQnyOXZSEofz/E7Arlmy7y Dojb9zmzgaUEEqnvQ4koqhpENbq4oTSp aJ7/UpsRrXUwrwJdxPnu2EW2hCgyFQ2i uAra/Bmzl046hAOTGzjUbbNgJt3JaLu4 qYKNcs/yUqGoZdcU/OOYfxFoAI1I+K/s FqCoVYV4yjQ6sB0s3isjoJT0fN1/QGMR 6a+ebQJ/B0B3Ch+VcC4abpMkWafTrOY/ J2KTNzvbXD9X2as1y6pa+w==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. 1 IN TXT "it works"
+test. 1 IN RRSIG TXT 8 1 1 20170715000000 20170701000000 31500 . mVYjV/8KTVvel7+USquoejpj3GYlnLmm 4AUifG/JHOOHsxak7JpRmoGx720oYBLm mLYuxIU4RB1GmZSb8lQH8Nv/vG6yOtKc 7sajnu3M6edPSM0+6Tsh+01G4s5rhqUe 8K5vc6s/HmWziHKpcWTGU6mq5OrYpcZD WmMdu7S75rcZDqX5ZbjrB8liBT528V/z 3nWNTKevL+vGYkwXfxiEYqTfbO8rlLZS Gqj/gAPFrojtu1qdmeJ78YE5ZiQwnAqz 5jAdsyQCFaX/tn4UMwmxyIBYdb9OrU9S Ec8TbRS24s9aaPFEmPJNHX0HYD84hMNY IF+0igXM6HFeTxVO0F6TSA==
+ENTRY_END
+RANGE_END
+
+
+
+RANGE_BEGIN 20170711000000 20170720999999
+ ADDRESS 198.41.0.4
+ ADDRESS 2001:503:ba3e::2:30
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. IN SOA
+SECTION ANSWER
+. 86400 IN SOA rootns. you.test. 2017071100 1800 900 604800 86400
+. 86400 IN RRSIG SOA 8 0 86400 20170725000000 20170711000000 31500 . fna14VuFmwBxUnBYNILk3jMd25fjhUm/ hkbF4bJxDnJk+qV6pSCMPAkINYbZb+UF UqtaIqOy0W3gSAxKPObFOjX+KExtyjRq AQPKTBRTDuYWndgEfVMNe9x9DkEqv6Gg fygyGD1kRAc2Rum5iOF5G/kLrGEIuSiq AJ/LKqF+hlPxC7E1HttlSVPCeEnW+Rrm pbiniH0hFqYQhOlPzHZ6aX8A2oERn1IS 4+XwNBQzLjqxcOHyf2EhlwCK2tYhMjAU NkzK4kcHK2r8jHVh+VBNF6kgP55qKwWz +fE13zkkkVP4f1JZtzfrC0TUIRQAztJ4 0vWR3XEatn8cNlobKfiGPw==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. IN DNSKEY
+SECTION ANSWER
+. 1814400 IN DNSKEY 256 3 8 AwEAAecpzqv0lz4aTPxYhm+LlvNVtLCq LhWvBuUdPoOxVO99j/KDXEdslHRfRLlf ZHi5KBfGLBwW13VeO9bzv+/62PycepCH WyE4I+IHSgVau1vkCtfRtX5wp8EMPyqU MtHPvuForHdp3ZWepuZh8i8TUgEGn3F+ ISS6yyy10gR8fPTSmXui6ZWPk+yarFNC /BosJPw0Y5gkPIltk9oHeWcTTwd1XpqP b2Pm4FdRN8rpJGvx5livyVdrEAXMnlV9 PqCtJVLBq4HN7LJmXde+ODLmzVP1JgaO qC9vlu2vKL2AlKW5BCCL9gt0+XeFU3KH qrs5GgnX2xVKoIzA9Sraepg+3i0=
+. 1814400 IN DNSKEY 257 3 8 AwEAAcfEF/AXBm9m/eLNdnsq4O5otNVD zNmdViy4pC1paInyq7tgy8blsivvpy7X Hh/xnFPCX6XRMUxxpe7Afuc9BITwepap rIdM/j4QOIeuQbLSxhzay1jdsCWMHFQ3 hMQeXZ8X05oxnIKihnfISyhqyaNdlY2k 4ApVHDF6ugDd1+Zu4T/5M9DIhxCTHpVo hctCzkgFP9tRocAlIwptcoZLdR3LxdXk OJ9tfSOuqHnQ4Zh8Aj407rVtz6CWQGyg qO+fb+Y98DI3V7IYisnW18r7QorMUycA OuDnnlZSvkrcWgtpuyylTsqhs/3+73iK kb0QUKscoTeSLgeoocFN+r8ZfaM=
+. 1814400 IN RRSIG DNSKEY 8 0 1814400 20170801000000 20170711000000 31500 . IGL5Fg08GJae04Y+aAy7xWGb+0pnXPnB XlFr16x6V2X40G7QdVEwATK+FO8T93m8 lgD+ixOX+6Wz67tlEOlCjdTl8BJUwlSk HB3+s+GZnotwkXnyTeWFrupOPNdkSTT4 wDMZLsNVKWCsrdBV5o4kwQedjFbeEQKC KVaDbSAZ6Pjr8F+uCkaGGmKYq3tvU5j4 Gd8JXLWASqj1AT5lJjNiVgACbSLpReVV bpxRHvdoKPgog/5INATqZS/lR5SXMEik DyEOv4CGl4pi+7yB73i6r7V5SWCMp8Jl 8RVLUFlMMqKg+SScybWkVSMJJyfnW1/j EpIO+3LzTKoZcdwhAJi1+A==
+. 1814400 IN RRSIG DNSKEY 8 0 1814400 20170801000000 20170711000000 45050 . pujHutwLhvT+8bki6jnCpW5UtK8xbruO /Wyg25ABJE+V0Qjqss3UbmqtRjaCT+b5 ZORlk8N7ZmuRdxQM++qT34UlmLtT3D43 DRRMYdCCnnBKqZhpOjZMm+ry1xNj3qUb izl74tPaGhibxzlaLdld2FlaBOKlJXeC y2d05I2nXICzsjb04cFDMskLeHMq4P3M AMf6RYqAlAPoLeeaW6Q2m+D8qIa3epIs eHJL6GhQYwpg6hT/fACOYX8YqPQTvhmC 7PVmRghYYeUb6am2kywJaMZg+zzyemVf R9HOYSEquyRvjj/1IbbanpdEZh6bO/et pIOK9bTqQpvg6pkZ8x708Q==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. 518400 IN NS rootns.
+. 518400 IN RRSIG NS 8 0 518400 20170725000000 20170711000000 31500 . zcWreQ7KQq9QK20WvzbNjfGrVEO15RaV YJv1QkgPj8JlgNedGg4pHvD72c9pVgqY DBuXQNfV0m1l+5LTtLAoX5s7t8PzhljQ S0t0RNkZXpQji/FtQQO7/jXt8bPTRDi6 wcn3uhu2fLuXEpXYVdFCC1s/8//9vPUU BeGY1vpdRZV+wd8HgnkqAoTyOKl7csSI cOYyhMpfwfiXohFz3AxG67Qjwj7wzot3 RsS9CDpBgwoWBTmi5dnPD++wbn0EXgmo w+tDGtk+PQBC9FPxxmVmaqHlnRM1QGqi ivS1MGGUzXXkZdzWNsdc/ZXQmJt5F3jX 3oZDR9pyAAky4tdebyuRlA==
+SECTION ADDITIONAL
+rootns. 518400 IN A 198.41.0.4
+rootns. 518400 IN AAAA 2001:503:ba3e::2:30
+rootns. 518400 IN RRSIG A 8 1 518400 20170725000000 20170711000000 31500 . AcVAjovwI9gcS/v+36yqoC4myF2iCLp0 65URXF3OEnpG9PRoQYCHhY9NuC9MaX02 gR/FfUJcHQT+NKKLL3WXZJ5llWKuNQa7 aPJV4ygrOjQ7ypehEYRVBygvDPfFAGNj 8Dxd0rvjpWtaMz5A5DXBLa2W84iDrOhZ RbnDNREItVEZGG9BN26T8me0YJoYOwx9 BUOC6FfAoupZJd/cbPcsp3kzIJCCP3Vy H8DFkYeno8yaWhoEuKwleto74nrsl8Fl ihBXEqqUResGkjMyJedgvnPtv/5kXmXN tvuNBw71Y85FkRgbCQKPJdaMb/Gq+K8a 9aVGNH+/XHqPDNZ0oJF4TA==
+rootns. 518400 IN RRSIG AAAA 8 1 518400 20170725000000 20170711000000 31500 . 1oeKgUeMR97GMVAZL8pgbBcgw6Kf4iu6 9nNjKtrHntavlQpBavUM2JX/nDyeBpcI C1oo0+GuqA5y5MfK2nmy5gQgXyN4S0Ag aXgrHZx6vgvFp5RXB7BY8leSTt0Pl8QC ugb179QYbzIxnHxZ+GJMQdA8Jb8FpBRH yVXhrTwypjW1Wdyoeo6TdxAikuF/esGp oZCg8V9WG2VHDmtU04uIpocN2t8mk8jA TBHKW3z0Vak0/4j/cvj2Yi+4dFivs88+ asgCsfzExN9r++BLm0uif+29pFgqh+yx pVjQZ9dUgQdkhnnJRmgwezpHei/c4/ZW 9HAKvp3qdPoPvIo1/dQClQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rootns. IN NS
+SECTION AUTHORITY
+. 86400 IN SOA rootns. you.test. 2017071100 1800 900 604800 86400
+rootns. 86400 IN NSEC test. A AAAA RRSIG NSEC
+. 86400 IN RRSIG SOA 8 0 86400 20170725000000 20170711000000 31500 . fna14VuFmwBxUnBYNILk3jMd25fjhUm/ hkbF4bJxDnJk+qV6pSCMPAkINYbZb+UF UqtaIqOy0W3gSAxKPObFOjX+KExtyjRq AQPKTBRTDuYWndgEfVMNe9x9DkEqv6Gg fygyGD1kRAc2Rum5iOF5G/kLrGEIuSiq AJ/LKqF+hlPxC7E1HttlSVPCeEnW+Rrm pbiniH0hFqYQhOlPzHZ6aX8A2oERn1IS 4+XwNBQzLjqxcOHyf2EhlwCK2tYhMjAU NkzK4kcHK2r8jHVh+VBNF6kgP55qKwWz +fE13zkkkVP4f1JZtzfrC0TUIRQAztJ4 0vWR3XEatn8cNlobKfiGPw==
+rootns. 86400 IN RRSIG NSEC 8 1 86400 20170725000000 20170711000000 31500 . kMVZp4DiHSXYRBgio4X+4nK32ITxnk7B uUwJHT9UIeQuyc0ag5T4sgNo73dcWAZF Jy+oXiv/5RkTA1DuFE7xLkgu51DwUo+E QmIFYPiVB8WYijF/c1aawx3mawEnERpS MvvX8e9rvtW1wNpNWDYjOOvR9S8HnQk/ MbSC96Non8LDX9chdITYlM33qVDDFCyh nd5PDe79UN8HvKXhhtin6h5LyAwVQolz 14/fEGimtHbEYCni88j3vWRKjt/vs6S6 Fl+OJ3NoSVr52BbbnaI7A06iXKGTyLSg HE1G6K6ENMfrhz3HIE5ze+CRZN5/WNtS 6A8+j3QqphFIouHqAPqw0Q==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rootns. IN A
+SECTION ANSWER
+rootns. 518400 IN A 198.41.0.4
+rootns. 518400 IN RRSIG A 8 1 518400 20170725000000 20170711000000 31500 . AcVAjovwI9gcS/v+36yqoC4myF2iCLp0 65URXF3OEnpG9PRoQYCHhY9NuC9MaX02 gR/FfUJcHQT+NKKLL3WXZJ5llWKuNQa7 aPJV4ygrOjQ7ypehEYRVBygvDPfFAGNj 8Dxd0rvjpWtaMz5A5DXBLa2W84iDrOhZ RbnDNREItVEZGG9BN26T8me0YJoYOwx9 BUOC6FfAoupZJd/cbPcsp3kzIJCCP3Vy H8DFkYeno8yaWhoEuKwleto74nrsl8Fl ihBXEqqUResGkjMyJedgvnPtv/5kXmXN tvuNBw71Y85FkRgbCQKPJdaMb/Gq+K8a 9aVGNH+/XHqPDNZ0oJF4TA==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rootns. IN AAAA
+SECTION ANSWER
+rootns. 518400 IN AAAA 2001:503:ba3e::2:30
+rootns. 518400 IN RRSIG AAAA 8 1 518400 20170725000000 20170711000000 31500 . 1oeKgUeMR97GMVAZL8pgbBcgw6Kf4iu6 9nNjKtrHntavlQpBavUM2JX/nDyeBpcI C1oo0+GuqA5y5MfK2nmy5gQgXyN4S0Ag aXgrHZx6vgvFp5RXB7BY8leSTt0Pl8QC ugb179QYbzIxnHxZ+GJMQdA8Jb8FpBRH yVXhrTwypjW1Wdyoeo6TdxAikuF/esGp oZCg8V9WG2VHDmtU04uIpocN2t8mk8jA TBHKW3z0Vak0/4j/cvj2Yi+4dFivs88+ asgCsfzExN9r++BLm0uif+29pFgqh+yx pVjQZ9dUgQdkhnnJRmgwezpHei/c4/ZW 9HAKvp3qdPoPvIo1/dQClQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. 1 IN TXT "it works"
+test. 1 IN RRSIG TXT 8 1 1 20170725000000 20170711000000 31500 . IflrU7TCMFd6L9qaQEgwSobKiGUfj2YZ 16MFrgiTl7mqZSjjS/Jf/dMXRJv/btan /XDT1yoItIcQgio3htKf/7Lo95kbUelU jSc6GvFEPoiceid8QigIAuSpKKH4eCh3 G/KW14UC1yHuLT3uwO8YLR3GNeO61sGB gafeCa4ePFSXszOcfq8ZfMKHTs8H8l1N 39rrN1rrcdsp2bVUA37BpJ2TI8eCf/K4 r50BXWE8db4PiXi3PHE1o8KEdhMKo5ku DyfXEuC7pgR0r01jB3nozb+rNRfF/VFd b3Zv7Fb+b1k79uUNtuTY24xTkxSeLSWy tesX5w7ReAEO+L9Mkh6N+Q==
+ENTRY_END
+RANGE_END
+
+
+
+RANGE_BEGIN 20170721000000 99999999999999
+ ADDRESS 198.41.0.4
+ ADDRESS 2001:503:ba3e::2:30
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. IN SOA
+SECTION ANSWER
+. 86400 IN SOA rootns. you.test. 2017071100 1800 900 604800 86400
+. 86400 IN RRSIG SOA 8 0 86400 20170804000000 20170721000000 31500 . lPXV8zPAsFCStPWYakYlvnOjRpqJm4RX 0tlJQAyDiQ7WwuuVqAYQefZx0fhveIHw Ntn2W69QGU+qZKUujrmSWg7KgK0+sOQ6 eLqTi+F0rg4qg92Q2Fh4DpHFOn6CzSp7 y/Ndyepli+B/xnRuvJsZiR0bpNdzpDSP uN9boISWMqoOD6EgL+2N1qJ4Bw9J9STe Ay7ZZz3gJYX0Pq0m+ndEChNbpDayB3Gz FeaicTl2Owqjj4XUUPlAUD5udlen688g vGqj/MS3rSs9Fv5QrvmP/fOKEw5wO1/7 UMS86BU+v4vnZ3EamXCnvfWTQeYfqy2Y wnzpucnMFI/11O723xtjTA==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. IN DNSKEY
+SECTION ANSWER
+. 1814400 IN DNSKEY 256 3 8 AwEAAecpzqv0lz4aTPxYhm+LlvNVtLCq LhWvBuUdPoOxVO99j/KDXEdslHRfRLlf ZHi5KBfGLBwW13VeO9bzv+/62PycepCH WyE4I+IHSgVau1vkCtfRtX5wp8EMPyqU MtHPvuForHdp3ZWepuZh8i8TUgEGn3F+ ISS6yyy10gR8fPTSmXui6ZWPk+yarFNC /BosJPw0Y5gkPIltk9oHeWcTTwd1XpqP b2Pm4FdRN8rpJGvx5livyVdrEAXMnlV9 PqCtJVLBq4HN7LJmXde+ODLmzVP1JgaO qC9vlu2vKL2AlKW5BCCL9gt0+XeFU3KH qrs5GgnX2xVKoIzA9Sraepg+3i0=
+. 1814400 IN DNSKEY 257 3 8 AwEAAcfEF/AXBm9m/eLNdnsq4O5otNVD zNmdViy4pC1paInyq7tgy8blsivvpy7X Hh/xnFPCX6XRMUxxpe7Afuc9BITwepap rIdM/j4QOIeuQbLSxhzay1jdsCWMHFQ3 hMQeXZ8X05oxnIKihnfISyhqyaNdlY2k 4ApVHDF6ugDd1+Zu4T/5M9DIhxCTHpVo hctCzkgFP9tRocAlIwptcoZLdR3LxdXk OJ9tfSOuqHnQ4Zh8Aj407rVtz6CWQGyg qO+fb+Y98DI3V7IYisnW18r7QorMUycA OuDnnlZSvkrcWgtpuyylTsqhs/3+73iK kb0QUKscoTeSLgeoocFN+r8ZfaM=
+. 1814400 IN RRSIG DNSKEY 8 0 1814400 20170811000000 20170721000000 31500 . taRMDz94VQ0lr4fUz9RcksuoEmSJ2dba BtEzOdj1GQHLUvIeY9n5kGqSvWA/ijSQ i8U3gs3KBWUGFZYVLNFRWzLEOumNx28a i+M2cXSo1z5lfh/kJVPrsV7lfNdilk1X yIDYDSKLrdEhfPly0Sm1SeF1AFdUZ5Br acniNZ67nO1z3qNQOoHnt/ZXNAkfUQoJ Iu5w87qxDVXT4ju5bDH2ozscPrbO0cbs Oq5S8H17O8d/njPdxAcYAW/aIjRcKOaD S1WDweTES96JURAo9I52JzkzPcnv2RW5 BiVIzI3o6gOVDTpzIeQAonGpT5QljdUC bUCYXkV+c6dIzA/aIVEwtg==
+. 1814400 IN RRSIG DNSKEY 8 0 1814400 20170811000000 20170721000000 45050 . QFDngPrnZLHICu5Sga7Hzmw4e4I2IL8O ED3u/F04CycjN7QgwcQyNr4tHrk94W7p 16fvkeORpG8BuLbHCium23u/7V5TJOOD MeyhO6V0wBzpmf7xrYfPPmHStTk1hgIE gkevsV7MMT4Kpc1VAGAHEIODtXwlQg71 YOITOz4tGgovIVej2qqLjYcYq6HfEMx+ Oytp87hu1+bGOjlbo+mfiEv/vRNejqVj rgq6ixkw3DAsI+Pnr49oolDApN6/wofd qh3OudgyCQVmxArXREBFrmcHL7lWy3A9 /NTaFtsCwAZHWqO3BeoU0qWfpo8TsEow tsW56HdwhYV5CW9js+VwcQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. 518400 IN NS rootns.
+. 518400 IN RRSIG NS 8 0 518400 20170804000000 20170721000000 31500 . JVme/rkfApeeE/Op6KYQuRGj5UgCl1L7 sMsCOCgXvQp4Ch4T2t2Fou+aC0/QKtGz nVxZhT9euD11cdsCGl+MVhRfbqfKeaSk LczLWw3CcJJHNa3OkKnbTlVMjB/6m08c Vv3tUsySIrGU3Hu06n7UBc7X88jbJ9hy EVWmIQ+B7goans7PWCuifMIqD/ELPFPd uCrSPn4GOdsTdnHmrXfRSBG4keUuGu7J ZZ5sWUmffa09uJUTWxC+0idzuCR0t9KF 07PPwcdst6z87Vc0ScTdDBt3Dim4+fim azBJTnEriTNyXBCIo+/O7xpMvPCTnIsR L/5/gfcKJppAjmwc86eOKQ==
+SECTION ADDITIONAL
+rootns. 518400 IN A 198.41.0.4
+rootns. 518400 IN AAAA 2001:503:ba3e::2:30
+rootns. 518400 IN RRSIG A 8 1 518400 20170804000000 20170721000000 31500 . fSxz+ikGl01EsGT/yLc4BgPWf+KePqx0 TfWiXV1dZjiX2xajzeVp75fv3TsFkgWu zsAYmVTeOdcqWSaYrXarBi8p0tu3HWUs XB1qBLHcW31rfTYI28NsurIPSZDG8ZdD No7LQ32eO9YxzsZv6Wbe6XGkuYLmWevn Spy2sPobBe/UH585XyuZds1U3VLJ11Ys sOk1EUEF4bQswmVRjNX/Snr1PEH9pqDY BJAh29t1VNAyhlEibAztATVJqayLKxGK SCDVmzqIQoafupmcl6SruyhJJx8m6SEa HyknUxV5JC4vDSObwv2INc9nPH9vODF4 dhzHYbW8FA0zON79JuNUtg==
+rootns. 518400 IN RRSIG AAAA 8 1 518400 20170804000000 20170721000000 31500 . 2z1lZl81ufBgiUsfgVnn3524CNxoFA5T 8Wfv8Up/484yxitiEFXCR/AohncE2kRH pWN/9UmuzUALJk10SYcD185lBoqhB5iI NPllRyYNYcnuS4Oq7sp+52tJRxqkMIWX V8v09rjhQzTx24UNNB5uZncOmZA0e9P3 KoeR1wG/Eh0dUESrjiwOHvzfmOffAhy/ ymY4XE5KZEwSxKaUfoUT8VgiKLxnNqwB UiCN15xSCAQBpHCxV1owQFtqYfKzNiML jL/ZjznEQfcvdGvfVAM15nLg6VNEYL8G LxP2CgH5NZpakCFRLD3Bos8F3w6WBuME 3CXUo/gqNlV+EQ4R823SxQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rootns. IN NS
+SECTION AUTHORITY
+. 86400 IN SOA rootns. you.test. 2017071100 1800 900 604800 86400
+rootns. 86400 IN NSEC test. A AAAA RRSIG NSEC
+. 86400 IN RRSIG SOA 8 0 86400 20170804000000 20170721000000 31500 . lPXV8zPAsFCStPWYakYlvnOjRpqJm4RX 0tlJQAyDiQ7WwuuVqAYQefZx0fhveIHw Ntn2W69QGU+qZKUujrmSWg7KgK0+sOQ6 eLqTi+F0rg4qg92Q2Fh4DpHFOn6CzSp7 y/Ndyepli+B/xnRuvJsZiR0bpNdzpDSP uN9boISWMqoOD6EgL+2N1qJ4Bw9J9STe Ay7ZZz3gJYX0Pq0m+ndEChNbpDayB3Gz FeaicTl2Owqjj4XUUPlAUD5udlen688g vGqj/MS3rSs9Fv5QrvmP/fOKEw5wO1/7 UMS86BU+v4vnZ3EamXCnvfWTQeYfqy2Y wnzpucnMFI/11O723xtjTA==
+rootns. 86400 IN RRSIG NSEC 8 1 86400 20170804000000 20170721000000 31500 . 3P8Vf4KjZRcPyoAJpHAUr2HEx2t75e3K kcc4BnzOgSubeSOrDm33ncnUhBx8tKSD G4oth7beyxmVy9yCWtiHyk+LjfOnyMhP FPlX+/Eflz3Ehri+8qdR6RTnRpp6NVpm aVeocIeONo1NKye8J3PLRZxyxNxxoTSM WRHtWfGA+I3IoDe/fY9Bu5k+HU5pqHgf iSHMo21B/jLHgbPXerOUfIUFUr8UExBt faQC743Dc56zR2IO20VrBAJQueWGqFdE ZUDwYks1PZulj6oGNSd5+PNqB2cVUznW evt3wkQyol11uXNjEv8TwoCjTbks/tmt wUZ1kZm+8PJc1QbooX29qg==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rootns. IN A
+SECTION ANSWER
+rootns. 518400 IN A 198.41.0.4
+rootns. 518400 IN RRSIG A 8 1 518400 20170804000000 20170721000000 31500 . fSxz+ikGl01EsGT/yLc4BgPWf+KePqx0 TfWiXV1dZjiX2xajzeVp75fv3TsFkgWu zsAYmVTeOdcqWSaYrXarBi8p0tu3HWUs XB1qBLHcW31rfTYI28NsurIPSZDG8ZdD No7LQ32eO9YxzsZv6Wbe6XGkuYLmWevn Spy2sPobBe/UH585XyuZds1U3VLJ11Ys sOk1EUEF4bQswmVRjNX/Snr1PEH9pqDY BJAh29t1VNAyhlEibAztATVJqayLKxGK SCDVmzqIQoafupmcl6SruyhJJx8m6SEa HyknUxV5JC4vDSObwv2INc9nPH9vODF4 dhzHYbW8FA0zON79JuNUtg==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rootns. IN AAAA
+SECTION ANSWER
+rootns. 518400 IN AAAA 2001:503:ba3e::2:30
+rootns. 518400 IN RRSIG AAAA 8 1 518400 20170804000000 20170721000000 31500 . 2z1lZl81ufBgiUsfgVnn3524CNxoFA5T 8Wfv8Up/484yxitiEFXCR/AohncE2kRH pWN/9UmuzUALJk10SYcD185lBoqhB5iI NPllRyYNYcnuS4Oq7sp+52tJRxqkMIWX V8v09rjhQzTx24UNNB5uZncOmZA0e9P3 KoeR1wG/Eh0dUESrjiwOHvzfmOffAhy/ ymY4XE5KZEwSxKaUfoUT8VgiKLxnNqwB UiCN15xSCAQBpHCxV1owQFtqYfKzNiML jL/ZjznEQfcvdGvfVAM15nLg6VNEYL8G LxP2CgH5NZpakCFRLD3Bos8F3w6WBuME 3CXUo/gqNlV+EQ4R823SxQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. 1 IN TXT "check and change answer"
+test. 1 IN RRSIG TXT 8 1 1 20170804000000 20170721000000 31500 . dnGQw6mSrNv3mhxWLQ+jFwHQea3PtL2t TOAGEVfyal5Kjpb8aVRWfCcBEdz5JVgh iXHXrZ59dbQA4sQbBrtCZLQl9eSjD/xr sOvMl+/gXMQVMnKBtjmN/kXFliuibTvC +1o9ZplEvWIQUDYZLk1SEZZQNNEnUIBt B/8N8EYrMfGRMkZkyD28PhbrFL65SEJg qyjJlwYsb7wBrElXQp8WoiPe44oBAL/0 3Xs/FkDh/52nHZ/79SW/d8iwHD12my1d 0cEYphlyk0nFs2zI6AnsbGODoVDb3snb 9VV4XJLkYdeo+iTalF5v/0Ept9PAMw8n bz81f7Ww1yDZ5KLcSaQzmg==
+ENTRY_END
+RANGE_END
+
+
+; 2017-07-01T00:00:00
+STEP 20170701000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170701000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode qname question
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170701000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-07-02T00:00:00
+STEP 20170702000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170702000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode qname question
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170702000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-07-03T00:00:00
+STEP 20170703000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170703000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode qname question
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170703000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-07-04T00:00:00
+STEP 20170704000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170704000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode qname question
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170704000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-07-05T00:00:00
+STEP 20170705000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170705000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode qname question
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170705000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-07-06T00:00:00
+STEP 20170706000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170706000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode qname question
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170706000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-07-07T00:00:00
+STEP 20170707000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170707000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode qname question
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170707000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-07-08T00:00:00
+STEP 20170708000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170708000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode qname question
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170708000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-07-09T00:00:00
+STEP 20170709000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170709000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode qname question
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170709000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-07-10T00:00:00
+STEP 20170710000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170710000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode qname question
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170710000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-07-11T00:00:00
+STEP 20170711000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170711000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode qname question
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170711000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-07-12T00:00:00
+STEP 20170712000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170712000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode qname question
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170712000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-07-13T00:00:00
+STEP 20170713000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170713000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode qname question
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170713000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-07-14T00:00:00
+STEP 20170714000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170714000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode qname question
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170714000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-07-15T00:00:00
+STEP 20170715000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170715000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode qname question
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170715000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-07-16T00:00:00
+STEP 20170716000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170716000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode qname question
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170716000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-07-17T00:00:00
+STEP 20170717000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170717000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode qname question
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170717000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-07-18T00:00:00
+STEP 20170718000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170718000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode qname question
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170718000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-07-19T00:00:00
+STEP 20170719000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170719000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode qname question
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170719000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-07-20T00:00:00
+STEP 20170720000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170720000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode qname question
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170720000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-07-21T00:00:00
+STEP 20170721000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170721000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AA NXDOMAIN
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION AUTHORITY
+test. 10800 IN SOA test. nobody.invalid. 1 3600 1200 604800 10800
+SECTION ADDITIONAL
+explanation.invalid. 10800 IN TXT "check last answer"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170721000099 TIME_PASSES ELAPSE 86400
+
+
+
+SCENARIO_END
+
diff --git a/modules/ta_update/ta_update.unmanagedkey.test.integr/unmanagedkey-present-monotonictime.rpl b/modules/ta_update/ta_update.unmanagedkey.test.integr/unmanagedkey-present-monotonictime.rpl
new file mode 100644
index 0000000..5011210
--- /dev/null
+++ b/modules/ta_update/ta_update.unmanagedkey.test.integr/unmanagedkey-present-monotonictime.rpl
@@ -0,0 +1,757 @@
+stub-addr: 2001:503:ba3e::2:30
+stub-name: rootns.
+trust-anchor: . IN DS 63640 8 2 00EBC5520847A812819359F554C1701C9BDA488A6111BBC4ACC47A32980C1FB8
+val-override-date: 20170701000000
+query-minimization: off
+CONFIG_END
+
+SCENARIO_BEGIN Simulation of successfull RFC 5011 KSK roll-over during 2017
+
+
+RANGE_BEGIN 20170701000000 20170710999999
+ ADDRESS 2001:503:ba3e::2:30
+ ADDRESS 198.41.0.4
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. IN SOA
+SECTION ANSWER
+. 86400 IN SOA rootns. you.test. 2017071100 1800 900 604800 86400
+. 86400 IN RRSIG SOA 8 0 86400 20170715000000 20170701000000 28969 . nzThS2g1c+WqXeYIM3Lkkd8s54Giigvd K+Cmb45GTsybSEDPweCbrX3sIKIRLTee h6PqpL1OO0MJRe5RQRonrnRwUsL4zV2Z Ql6+htnV3o5KkS773Z/nanRKabq3ubIF Ct7JCmMBJ383pcYdFYUJXviDwI6Bp/oW qoYNPiky7OkQ/dcE6SKCIokuQtd3yaIr QZPbry9mhAEIfw3a3VRdB27cSAdpTsXe gkZv/HV0/u153F82hlJgB3rHgmV3IKuL rz721IyKst1JF+nGpg4eg7zBK4ivw0E7 wEt3+3eTznkKSa06Nu86CgK3Xg1SVQcx P1vTzS+e9qKZhrsgqfA0Jg==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. IN DNSKEY
+SECTION ANSWER
+. 1814400 IN DNSKEY 256 3 8 AwEAAaJ74lYmnNx+UIkPCTsfndfoXZ6S MprUoVw6UgEOgBC81w6szA82TssdOAFM iNk5lIZ8uRl6u1KO5sY3JMi/yau4ND4u 30H2IyyIIdIu8ad8dCbxoYXwh3ErrODc 2xXWG/x0mHR27/HEPOXs6U4iweuBivJD 5yWhxDWafrM9MjNvKGefic6B8/qqSdtI nr2WCxafZKHZ0xBBioFi3x5IHxpKj6aw JrXJisNzhNlxCJI90qEw7eUfg9eqPhx2 dTsOE3OghNYncDi6t74f319q0mWaEKAn cip5W8fCZQdVKry9QjDSM8tsqDkjrlkO CAbbrJjlwOzbM5y9EcpvwJTtA7E=
+. 1814400 IN DNSKEY 257 3 8 AwEAAbE+Bu1LTy+xuBMo55R2EJASOaWy KCCJYhVRsx3p6CqCiMWonDOKG91FnOSY jwhao5e8wuzNNHArIxhvsTLkUS5k1Oaq mt2E2Fw8Dkr6Y+H23SpcaNATIwcr8wnS 6oSFYYR+IfB/tynu3HVZ6rFPNiKGr1Q1 Z+HK2hKWSqDigtwi08UVf/Vpq2jrocGg K89G4RSC1gK7MNjc7mDe21mzSjOtQqRC Vl3kKdMbRIPX7y51W7b7k7MBfq5/MpwO 1Pq5nDpClBi2823yPEZQHTV3SlOZkY0B WzJ8ahEOwmr0d+SsoKFSfXDAGhubr5gV S9YTHjun8oocjRDNxEcM0itRCSc=
+. 1814400 IN RRSIG DNSKEY 8 0 1814400 20170722000000 20170701000000 28969 . WBUz87YLXQOj/cC+6+8qzpBJz/GhSng+ b6TzA0RQRgh4EsgXKnuCiAnU3fAtDvGr 2pQEF2ySgHNB7Ef210y2IMoR00W8zSAh oTOy/Dbb1Xf/PYznEbnBmTdD7wjDXNwd p/rb6xySvWEGC6a154KEuFzMWYB2bSsA ylmhnqmDeC1Z25xcxJCWzphfaMSirpT1 w7KwcNrHraSYY154wbpTD+5X/kmRNTTi wllR0lymoyintdWrA6ofRxQRg0Qwq1kN ANJ03mskJ2/wpE19byde5EQxMbuYxF9c ++HvmtO4+l3qkGRjxOj6BcFol0jL2fDw e2/7whVZpR30Vad8ir3LXg==
+. 1814400 IN RRSIG DNSKEY 8 0 1814400 20170722000000 20170701000000 63640 . e6NxhVRd+UaOb9A+HTuXr+d/5shed+Qd GLHlVlAmXd04ktEGFy+34tbGt/AfE49i tjVXV8gjxxI1CBNprzrOJFEvdmonRih9 uU3aIb7nIx+EZHLawJz+533ZnpezLKA8 YjqJo4PECsehejXMvqjqSwcmgF/9sVX+ O+RyKRecn92NldNogvTuDgll9XF5kLRu 7/gMvzhpfpbTPz9JeblDrJoMGON+5fGo zYL48k8p4pLoy+Qe5FiP0aLNyTvRCvFM ioXqpehA9sh0PBIMWEatI7sji0Z/4yGa Grni32o+STvVC8Kct4IeNxxfHXhPSam5 hvHqB4P7lELbKj0VZDcBFA==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. 518400 IN NS rootns.
+. 518400 IN RRSIG NS 8 0 518400 20170715000000 20170701000000 28969 . bsiTkZ+Qbpg53ZIOX2LpeZfoXSgUqqo1 0eK3pxh0G9irczolgFUGaWIf6KDlm8dA Sr9oR86U5IMgjRnghX2XlGBFqS0InYOS TGAV1ZRgiB7/u3YFHPw3qbw3xX/NHBpc qHr8/qnoJUnQrwrhzawpSu+EybhCsHfx 518MRPMxdQuxkC+rHE69PWQgjM7BE55S lQvJd8iASQlWMdcnC8As9VRxki3aUykL llDOTQeQvRRc9abPRFK43SbiUhO7JOpc pF5CTHy+barj1KVyju1TeERrYVe7pR0L pulbvwWCDgmwhuHaPJmy/A53e+SkQTkj buoCA8biSmFwIB89psFZ0Q==
+SECTION ADDITIONAL
+rootns. 518400 IN A 198.41.0.4
+rootns. 518400 IN AAAA 2001:503:ba3e::2:30
+rootns. 518400 IN RRSIG A 8 1 518400 20170715000000 20170701000000 28969 . YNPFwsjeDerMI+ONb0ksp5oZ9V7zuMts e1sTb5RxffdK8z4MqF1YBw0vfhJ03AYK U2OyS9p1m+41T1IS3+9Unk1grgyUCajP Pek9eAK0FMFZyuQMrQQMmOcbboKwa6G0 x6UJTIIy+evnMrLnbfK4EHzzbmdmmcrH r2sD29RjbH03U7E5Ie6gohgfaV1cvirz dyue4YIcUeQ95P6yqihMK3zJyeBZpcq9 fBm8TKg4+chtkjT/Xp+GuVH53gCoGMQF Muf5CpWnd6CTJ14CHDcoTR1WvZx0ISUM uVCjdnCq99q173yeXYzptgbESXcHgVh6 5wQbuemJi7yqMdk4742eMg==
+rootns. 518400 IN RRSIG AAAA 8 1 518400 20170715000000 20170701000000 28969 . V4mHW8mz6d1wD7CXTLW1Np4xUrFJ5F3k MeVbke0Jyl9ciSthVZc6Qj02YbESegVI p7WZfi8I5w646MjS6d04CC2XPLv8nyAU SLwUvKgYCdwE6swEcb4QgpRX1Lv0WxTB 5taQWrJDwQ/G0ifnOEWt3iQPbXAn2UTg 0pnde9arz9RU4V430mdMiWc84xNtRvP6 Ncgu4GnT65us1QGKWetKEOoJPU4RQztE OkJu/Abw8CPLpfirckMEdDprNqO8NELF nj34L/dxS4yEb6vYp6sPjL6y9k0xdMLG 1g0RDWzXeCSKPb847WeiBj4D7I6i3XAC Dkj/SiWQ+IVjiDHD66rl0Q==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rootns. IN NS
+SECTION AUTHORITY
+. 86400 IN SOA rootns. you.test. 2017071100 1800 900 604800 86400
+rootns. 86400 IN NSEC test. A AAAA RRSIG NSEC
+. 86400 IN RRSIG SOA 8 0 86400 20170715000000 20170701000000 28969 . nzThS2g1c+WqXeYIM3Lkkd8s54Giigvd K+Cmb45GTsybSEDPweCbrX3sIKIRLTee h6PqpL1OO0MJRe5RQRonrnRwUsL4zV2Z Ql6+htnV3o5KkS773Z/nanRKabq3ubIF Ct7JCmMBJ383pcYdFYUJXviDwI6Bp/oW qoYNPiky7OkQ/dcE6SKCIokuQtd3yaIr QZPbry9mhAEIfw3a3VRdB27cSAdpTsXe gkZv/HV0/u153F82hlJgB3rHgmV3IKuL rz721IyKst1JF+nGpg4eg7zBK4ivw0E7 wEt3+3eTznkKSa06Nu86CgK3Xg1SVQcx P1vTzS+e9qKZhrsgqfA0Jg==
+rootns. 86400 IN RRSIG NSEC 8 1 86400 20170715000000 20170701000000 28969 . flD/0sHGiEdO31gKLXt9gt0HNSXXza0q 4i39YuCkJ0nKhcToFVPk6lo6XKLe34QW CqdR5rLlOjlul3tUrEde7flEhCyLf1du 6cF/AxBrZ1qRNrUOG2seSjFmBNxFD9p4 pTG/4lwRzr6p/TbaW1YyXWm65qi+3TGx 8DlD/HkcIU/Nc8zhqORcN+AhAl5Zp0hN GVTAFAMzHBPkJ+Nuy7iUYQPw5S2KWm9C ozbH7skiFb1eQgJq6oV150sGIqcrQhxI xvHKjlQLaLU8V+QcmNhLVz1KXdPiLe37 LgM4/5GuvoywISknr4lucrBxFJym6bA6 3zbaTiqBbKLo8fAuXG06kQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rootns. IN A
+SECTION ANSWER
+rootns. 518400 IN A 198.41.0.4
+rootns. 518400 IN RRSIG A 8 1 518400 20170715000000 20170701000000 28969 . YNPFwsjeDerMI+ONb0ksp5oZ9V7zuMts e1sTb5RxffdK8z4MqF1YBw0vfhJ03AYK U2OyS9p1m+41T1IS3+9Unk1grgyUCajP Pek9eAK0FMFZyuQMrQQMmOcbboKwa6G0 x6UJTIIy+evnMrLnbfK4EHzzbmdmmcrH r2sD29RjbH03U7E5Ie6gohgfaV1cvirz dyue4YIcUeQ95P6yqihMK3zJyeBZpcq9 fBm8TKg4+chtkjT/Xp+GuVH53gCoGMQF Muf5CpWnd6CTJ14CHDcoTR1WvZx0ISUM uVCjdnCq99q173yeXYzptgbESXcHgVh6 5wQbuemJi7yqMdk4742eMg==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rootns. IN AAAA
+SECTION ANSWER
+rootns. 518400 IN AAAA 2001:503:ba3e::2:30
+rootns. 518400 IN RRSIG AAAA 8 1 518400 20170715000000 20170701000000 28969 . V4mHW8mz6d1wD7CXTLW1Np4xUrFJ5F3k MeVbke0Jyl9ciSthVZc6Qj02YbESegVI p7WZfi8I5w646MjS6d04CC2XPLv8nyAU SLwUvKgYCdwE6swEcb4QgpRX1Lv0WxTB 5taQWrJDwQ/G0ifnOEWt3iQPbXAn2UTg 0pnde9arz9RU4V430mdMiWc84xNtRvP6 Ncgu4GnT65us1QGKWetKEOoJPU4RQztE OkJu/Abw8CPLpfirckMEdDprNqO8NELF nj34L/dxS4yEb6vYp6sPjL6y9k0xdMLG 1g0RDWzXeCSKPb847WeiBj4D7I6i3XAC Dkj/SiWQ+IVjiDHD66rl0Q==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. 1 IN TXT "it works"
+test. 1 IN RRSIG TXT 8 1 1 20170715000000 20170701000000 28969 . dp1L09l+y0OTOTFCnypmZ5taInflPNAU Iuh4bVn8zQoKC4O4LBoXhE5Udt+y9ul/ pyMP1JHtcJKD8AWjABQKz7FQdnOzEap+ ioUA+qZicnnW+MUaYbtN9jgKqnOfanxM PXSSjzLDfFEEZip9Ii08XKkc6zsmCJ6N Gbmq3fOhOXy01cQFoKYC3WxW853yB2s+ vLhirvAusQxfnpHW9ghN0Q4Qbb+OMccE PVltuWzVypRXXUj92EJzCQ8CCyshvgGM gxfpI+T+K5h9xAn8PGFBmhanqnSI3FKI LzAqQvxfZC7vsEQq3/6sSO1BKVLZjXFJ G4C1BaIdtyvd15UIfykePw==
+ENTRY_END
+RANGE_END
+
+
+
+RANGE_BEGIN 20170711000000 20170720999999
+ ADDRESS 2001:503:ba3e::2:30
+ ADDRESS 198.41.0.4
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. IN SOA
+SECTION ANSWER
+. 86400 IN SOA rootns. you.test. 2017071100 1800 900 604800 86400
+. 86400 IN RRSIG SOA 8 0 86400 20170725000000 20170711000000 28969 . fiv9MSFJla1quIPpZIp+qWqzS1VylSH2 FkF0swo2rbdpidqHPfJnZWJR25+XMch8 i6URA5mRS0Ce7imMxNJVDFyDV3ahusSa LwI6mPnfzgBURkv3MjW38/9LnAVfaun/ NU7WOypPskk4QXfoyJC0Po96LoaU5Nbh iN8IFnipmLQ6LV3nPx3hItGBxL70M2uN FvwD31BInnjG2R+jXDvSzLEeFmoqT6af QXWxNrcKYrJUNrS9x4Sop2XbrYgCvUe1 +UXb5Z0BFgeDeBFFxSSeUogW8SEjCJtS DeUl4RSVQyIqbaeDQ06YPCwY40Oe2buV wSCvZoWeU8p8yOkzwRoR6A==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. IN DNSKEY
+SECTION ANSWER
+. 1814400 IN DNSKEY 256 3 8 AwEAAaJ74lYmnNx+UIkPCTsfndfoXZ6S MprUoVw6UgEOgBC81w6szA82TssdOAFM iNk5lIZ8uRl6u1KO5sY3JMi/yau4ND4u 30H2IyyIIdIu8ad8dCbxoYXwh3ErrODc 2xXWG/x0mHR27/HEPOXs6U4iweuBivJD 5yWhxDWafrM9MjNvKGefic6B8/qqSdtI nr2WCxafZKHZ0xBBioFi3x5IHxpKj6aw JrXJisNzhNlxCJI90qEw7eUfg9eqPhx2 dTsOE3OghNYncDi6t74f319q0mWaEKAn cip5W8fCZQdVKry9QjDSM8tsqDkjrlkO CAbbrJjlwOzbM5y9EcpvwJTtA7E=
+. 1814400 IN DNSKEY 257 3 8 AwEAAbE+Bu1LTy+xuBMo55R2EJASOaWy KCCJYhVRsx3p6CqCiMWonDOKG91FnOSY jwhao5e8wuzNNHArIxhvsTLkUS5k1Oaq mt2E2Fw8Dkr6Y+H23SpcaNATIwcr8wnS 6oSFYYR+IfB/tynu3HVZ6rFPNiKGr1Q1 Z+HK2hKWSqDigtwi08UVf/Vpq2jrocGg K89G4RSC1gK7MNjc7mDe21mzSjOtQqRC Vl3kKdMbRIPX7y51W7b7k7MBfq5/MpwO 1Pq5nDpClBi2823yPEZQHTV3SlOZkY0B WzJ8ahEOwmr0d+SsoKFSfXDAGhubr5gV S9YTHjun8oocjRDNxEcM0itRCSc=
+. 1814400 IN DNSKEY 257 3 8 AwEAAduG/aGjlqV4zHxSHn/VNbEp+ns+ KEHgGj/4/MLCcaTiMXqQuZFhsYbRGB2K fDduGNxcf1ETC4iuU0Mj8++3ofhALnAz irQsKOxWpWCvwWJC6qlp80U0GYIkjZA8 7XEzSAx6jZUPh/9xMxrmogIxwJ2KP7KH X0aF2jh76+HA5GmEBG+7dq1Z0v1l22aY gvyK/uUntu1vaVyQqyD8IhaAkl+mI2kr 2N0Cp4UcKutuRbaveUP/LdTpJoHmN9CR wc3LkvbBYB5F7VL8hgnhKFIcbQHhYoTQ YCQzgBA5OxcfWFWBfQGtpaSmv3V+aQjI JhEbWLDmN2o2kwl89AN3DGtEtsE=
+. 1814400 IN RRSIG DNSKEY 8 0 1814400 20170801000000 20170711000000 28969 . g/ODtn/IzUHbBK2B8dS5D3Q+Ee/8msx6 4ONLHXf2SolIxfiTm9Pl2Kqnm3SRPsid rwL2LGkdMMMkE7faX2cE0PW8/b9y4VhP 4V+piqiMJByUM9qU4ZdMZ2BvMlLhfmTC 0QI36vnIfIwDddBJ86xo/ee3PX5je9Vw xardvEpvpLDe5oWf4ThoT8NW1nJ/P5fg /cff0U8qtLXcZkHZfTNWvx86t0bOg1qv uWOc4aiMne1FePp9QCmVs7D2s0gvuK8T P6tbx++Tz+0setDOdapSo0oe8PFvPySg GxRQ9L2CtVPv8YmKheojXoyKJ50KzQPY yWXl5FAXLfx1PKfPgq+X/A==
+. 1814400 IN RRSIG DNSKEY 8 0 1814400 20170801000000 20170711000000 63640 . jVqcr43tfrNMVgoentuUlqxZ9lr2SDzo xEgZtnMtNkK7dr2MjI4OhZvzSkepIAI2 GppyU5auUqJwrKXwk9VOfQy2a2yBzoqQ XC4h3BRuWlmw00zg5gLgys3M41um9sx/ QSZ51ScaZxVw3cy4Zf04LYx5RARcp3fM iRVVVLPWYVtd5ATbUcp59aCUa8EvQE7Q t0bkzBDd5dBOnrANPFnhHYhPPZICuKqd ll7hTN1eQNqGmlKNb5fYeAZiD5+qg2vf JMo1XpY656HLNowVsAS5TQ+kP3+genb7 AOM1iIZEkCbiByrjeXdJfPARlkCODJ5h PcBkN9bd6JB5EhzOSIK/wQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. 518400 IN NS rootns.
+. 518400 IN RRSIG NS 8 0 518400 20170725000000 20170711000000 28969 . aVcR90IFl5ogQYSg60KeNHRviuSC76UZ DsLKDuZCljZIEI5S/qu5hAVohsW2uHJ2 1hMJHQKuOyWJO+3GtzLzqSWxZSKxV0/N aKWhQEbB7+gEm50ZLM8Mw6875vkpOUwF 3K2tzFH4MVBiJowL6whqeOadpmDvDbgy VFcFHw+2+MLVEOG0vruj5jQD1wTelT7k GE3CdwLt6m5TkLt89sJkojRpbK2Jt3zw X+/j0vzJbwQJSbWWxftSdKY+vmHJCwpn 0hT6Ax4jx2e2w6/vkMI8izaglsOIaCBE d1rzXR4DdEhqaCPpLqYLZaYBrNhdZg4c hvpyn5sdugZcDd2vp55iJw==
+SECTION ADDITIONAL
+rootns. 518400 IN A 198.41.0.4
+rootns. 518400 IN AAAA 2001:503:ba3e::2:30
+rootns. 518400 IN RRSIG A 8 1 518400 20170725000000 20170711000000 28969 . e/85gZqEaHv+Zn+I2FJaUkZHHDzhnzuk iOAfP2EiiTuzPR9B18PWpIJxzFp38+tX Z7Ny86yj68Zrk3aBBDMOgynIMdNd/Xf7 lsYQzAutq/BFRlxtPmPoIpKSSSd+F6ka MVTVxISjaLWADjYlKYYLMjcX7UYFYdXS 4laxdjtYPLCSKDHBBYFyaOxfV6TfVR+K t0JQUrPcJTTRVAORkQQgXkd1Qsah+abc RN0AedeMG3jQEaSqJL5SSHRqjrqHWx1R czveXdjs+2wZMwq0S8mkTQXTm9H9Zi+c GR2841N26fnEI0qCSHUru2AngM+k0HJs Qz2wrV/VENnRJjxJv/VGhw==
+rootns. 518400 IN RRSIG AAAA 8 1 518400 20170725000000 20170711000000 28969 . N0Lwwyu99CFaAtoj5SVsT4k5I/DW/qd9 WDzeYx9dXL9Ra15jGCkoyvEl8+mdd1EE Knj7Ri8m4L13mI4B/8BKsssMUGRu4k3c B9ZcIkVWs+xIOu2YLnrzz/s4JQbUxzDk 5Bu5Rhi7sF1xIfbl1T6pvw5exGkPYjMW MYVXlq/vfRWqgoaYdQ5MIukT52a7OhUn CGtoqzZoSnYkmKAwAv9rlSDkTnkLXWtt VTNfwZxAgWsEJa6GacsauPWEpNElXIvh hG9SX/s8YPDhcLg/tTi9ZCZm5VDkXzAl zsGHHEQ+HT/qezqCMMf5wEyqnhDPv+XK YOO6EERSCTpOaHvOo2Z8wQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rootns. IN NS
+SECTION AUTHORITY
+. 86400 IN SOA rootns. you.test. 2017071100 1800 900 604800 86400
+rootns. 86400 IN NSEC test. A AAAA RRSIG NSEC
+. 86400 IN RRSIG SOA 8 0 86400 20170725000000 20170711000000 28969 . fiv9MSFJla1quIPpZIp+qWqzS1VylSH2 FkF0swo2rbdpidqHPfJnZWJR25+XMch8 i6URA5mRS0Ce7imMxNJVDFyDV3ahusSa LwI6mPnfzgBURkv3MjW38/9LnAVfaun/ NU7WOypPskk4QXfoyJC0Po96LoaU5Nbh iN8IFnipmLQ6LV3nPx3hItGBxL70M2uN FvwD31BInnjG2R+jXDvSzLEeFmoqT6af QXWxNrcKYrJUNrS9x4Sop2XbrYgCvUe1 +UXb5Z0BFgeDeBFFxSSeUogW8SEjCJtS DeUl4RSVQyIqbaeDQ06YPCwY40Oe2buV wSCvZoWeU8p8yOkzwRoR6A==
+rootns. 86400 IN RRSIG NSEC 8 1 86400 20170725000000 20170711000000 28969 . hJ4FfZ1c4tXEx3MhS0iz/Ypu6Qincctu Dzc9PHqhMUCAKumNBTpbiQpqjnZEhi3m a9iEx11ysLFUp+5REWgSCDdSHkL1reVX MoE0/Uvivz04VBbj9YM1RIa24hsmO9BH b1j7rnRZGLz5kGllKPuD2V360cV8MPc/ HGV7xgB/j/T9MBk555Hhu8oqiaj/YXzC 4MT4UM5TObPd7+NstwocO5x0WdpbqhM4 D1eXxq7TRS42EKGRZ3uFjn+szrtkcQ1l fcxkAs+VcCyGBeZ51cvFZmNwQwjgcIZt CP5OwGvWdJRi9JPb5jdTImNVFe6xOV6H h8I4MQl+yBEw+62LKWz4YQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rootns. IN A
+SECTION ANSWER
+rootns. 518400 IN A 198.41.0.4
+rootns. 518400 IN RRSIG A 8 1 518400 20170725000000 20170711000000 28969 . e/85gZqEaHv+Zn+I2FJaUkZHHDzhnzuk iOAfP2EiiTuzPR9B18PWpIJxzFp38+tX Z7Ny86yj68Zrk3aBBDMOgynIMdNd/Xf7 lsYQzAutq/BFRlxtPmPoIpKSSSd+F6ka MVTVxISjaLWADjYlKYYLMjcX7UYFYdXS 4laxdjtYPLCSKDHBBYFyaOxfV6TfVR+K t0JQUrPcJTTRVAORkQQgXkd1Qsah+abc RN0AedeMG3jQEaSqJL5SSHRqjrqHWx1R czveXdjs+2wZMwq0S8mkTQXTm9H9Zi+c GR2841N26fnEI0qCSHUru2AngM+k0HJs Qz2wrV/VENnRJjxJv/VGhw==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rootns. IN AAAA
+SECTION ANSWER
+rootns. 518400 IN AAAA 2001:503:ba3e::2:30
+rootns. 518400 IN RRSIG AAAA 8 1 518400 20170725000000 20170711000000 28969 . N0Lwwyu99CFaAtoj5SVsT4k5I/DW/qd9 WDzeYx9dXL9Ra15jGCkoyvEl8+mdd1EE Knj7Ri8m4L13mI4B/8BKsssMUGRu4k3c B9ZcIkVWs+xIOu2YLnrzz/s4JQbUxzDk 5Bu5Rhi7sF1xIfbl1T6pvw5exGkPYjMW MYVXlq/vfRWqgoaYdQ5MIukT52a7OhUn CGtoqzZoSnYkmKAwAv9rlSDkTnkLXWtt VTNfwZxAgWsEJa6GacsauPWEpNElXIvh hG9SX/s8YPDhcLg/tTi9ZCZm5VDkXzAl zsGHHEQ+HT/qezqCMMf5wEyqnhDPv+XK YOO6EERSCTpOaHvOo2Z8wQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. 1 IN TXT "it works"
+test. 1 IN RRSIG TXT 8 1 1 20170725000000 20170711000000 28969 . Kt5QnrqvSHi9bp16JY+zInP+jvKrqCks 7TrTskXzZftyHL5bnYVTXTJekoBE3S0j cQaU24/xbDfXZ+vbnaNbfL5lQtMV7cyC Hq5ydrkfmDUDK83J++RR3zGbSEg0vhiv Mign05MHxpwIAaQLOfABc8TVHNC/uTar el66xI3MPAm1dovqV8rvKXhsZn+c+2ec izJ06J3OnwYB7Qtvv79J7uPKp9VeuY2c gXrPIR73laEHlV0pwGZjWk1Pj6T9w2KX tzcALzFsGPlvf7WwQlOMfu0PVvp1mg09 LLyosDdjDVuMdFZdoie9FAXDia3LNDVk VcWhf53KK2kDA+2MFw44ow==
+ENTRY_END
+RANGE_END
+
+
+
+RANGE_BEGIN 20170721000000 99999999999999
+ ADDRESS 2001:503:ba3e::2:30
+ ADDRESS 198.41.0.4
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. IN SOA
+SECTION ANSWER
+. 86400 IN SOA rootns. you.test. 2017071100 1800 900 604800 86400
+. 86400 IN RRSIG SOA 8 0 86400 20170804000000 20170721000000 28969 . RF31T45DXJHLnVI6wENwbT6Enc+9RZt2 ydueew94jnGTB55BJT9Mq2rWkzkP/ymR RzZjixoBsoRgCFlfs865Z+JJtR7nk23s Cl02erMw6lra4IaD8q4M/sH7vh7AAo/c /GVqKyxcCZiIwk/A3J1qpAAvbapE/jwT seg04WM7XEsqp58BuNluff6SavIaFB/Y 70sGNMm+jbBnk+W6HOJw6bB1GOyLE1Gd Ae+YMSbEA2H99WAZo7rlKO43CQY8sbzY 3pKCrY6kXNoBQSlpqWxjU7UIjYdU/8F6 RrBJzq1aIKBEjAh2zEqqpb1NyxfMoJku 2I6eERUs/J9MNc+gn3pwgw==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. IN DNSKEY
+SECTION ANSWER
+. 1814400 IN DNSKEY 256 3 8 AwEAAaJ74lYmnNx+UIkPCTsfndfoXZ6S MprUoVw6UgEOgBC81w6szA82TssdOAFM iNk5lIZ8uRl6u1KO5sY3JMi/yau4ND4u 30H2IyyIIdIu8ad8dCbxoYXwh3ErrODc 2xXWG/x0mHR27/HEPOXs6U4iweuBivJD 5yWhxDWafrM9MjNvKGefic6B8/qqSdtI nr2WCxafZKHZ0xBBioFi3x5IHxpKj6aw JrXJisNzhNlxCJI90qEw7eUfg9eqPhx2 dTsOE3OghNYncDi6t74f319q0mWaEKAn cip5W8fCZQdVKry9QjDSM8tsqDkjrlkO CAbbrJjlwOzbM5y9EcpvwJTtA7E=
+. 1814400 IN DNSKEY 257 3 8 AwEAAbE+Bu1LTy+xuBMo55R2EJASOaWy KCCJYhVRsx3p6CqCiMWonDOKG91FnOSY jwhao5e8wuzNNHArIxhvsTLkUS5k1Oaq mt2E2Fw8Dkr6Y+H23SpcaNATIwcr8wnS 6oSFYYR+IfB/tynu3HVZ6rFPNiKGr1Q1 Z+HK2hKWSqDigtwi08UVf/Vpq2jrocGg K89G4RSC1gK7MNjc7mDe21mzSjOtQqRC Vl3kKdMbRIPX7y51W7b7k7MBfq5/MpwO 1Pq5nDpClBi2823yPEZQHTV3SlOZkY0B WzJ8ahEOwmr0d+SsoKFSfXDAGhubr5gV S9YTHjun8oocjRDNxEcM0itRCSc=
+. 1814400 IN DNSKEY 257 3 8 AwEAAduG/aGjlqV4zHxSHn/VNbEp+ns+ KEHgGj/4/MLCcaTiMXqQuZFhsYbRGB2K fDduGNxcf1ETC4iuU0Mj8++3ofhALnAz irQsKOxWpWCvwWJC6qlp80U0GYIkjZA8 7XEzSAx6jZUPh/9xMxrmogIxwJ2KP7KH X0aF2jh76+HA5GmEBG+7dq1Z0v1l22aY gvyK/uUntu1vaVyQqyD8IhaAkl+mI2kr 2N0Cp4UcKutuRbaveUP/LdTpJoHmN9CR wc3LkvbBYB5F7VL8hgnhKFIcbQHhYoTQ YCQzgBA5OxcfWFWBfQGtpaSmv3V+aQjI JhEbWLDmN2o2kwl89AN3DGtEtsE=
+. 1814400 IN RRSIG DNSKEY 8 0 1814400 20170811000000 20170721000000 28969 . XWhkgZWb58eV5z5eoGWQwq65HbwA5ozF b9BPTQEwph8IAgvjoK+5+fW8Krf8rxqG nZDu7qFHN/T0s4wux+8+ey2HSfRUXj8Q 4xNACKWavLaIGundNiYleVjzmeOkbv5S vOcINlbhuLsm3J0AmXCe4/QMfs8yJ6+k VCHCAgUwykq9CoOQlJW3A/C7Ky5Ztx5W ujuc+7Ou91SwT880xBfIBD17U4PXF3zE Xmdd0/D+vaEBSmT526Ons+fEXP8W1TK0 1xBJGaGT/N2pqaOQOnj7N6Y8gjfmnJso 4J5wZ91B7f5Flc7Qzd4FxAlHkbKroSl8 yS6eaYJzRGZc5+zHActPxQ==
+. 1814400 IN RRSIG DNSKEY 8 0 1814400 20170811000000 20170721000000 63640 . fuaYzy7riEOS0vwe0ZaR5hPMD8S5oGeH PaZZ2jCnWVDuiFvPObYVuuB9RfWhyyLB +LOQ0xkoV5LRm8mmbqoZWniy4HS/4+oc 3TeIenMJLdP9FqLdgz8Pk3aO4O0o2FgT 4P8jlQ41R1TUct3vBtcjqzzKQXqOqA9+ y+iSPspWs3r305u49YyknOin8OAE3Zoh J2l+m/fVvW3pQ0jKCkD0CMg5k0nbORs5 aK1T5UAuKPUTwZoL9i+Bov89rQWWUp0B POzdBFHCM6nMlo1Wtu4RQHSL0GmLDsSS 1SZoOdbCsrX1DWCpq2mg9yCy/mnsM5sE +oSy/iFy4F02Ggk11R4gXQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. 518400 IN NS rootns.
+. 518400 IN RRSIG NS 8 0 518400 20170804000000 20170721000000 28969 . A5hMjKgZIhBWemZZUirkziI/ObpsHmlT +2zotPOO3Xk+8niKkWNBo6d8JCa+ofyd bhQb+3486j8YgKgjzz2YyjJtGemRJrLm 1frRV6lxx3lRYZCmNyS3ZUnN8vJaIREV WXr8f8HtGov6Pu9lIXikLxIFo9g2dMK3 jUYXbA6HTJBh5Eki3xBW27yGFlq0hGDa E2fV2swD5C8vQmo1KK2yDzA92G87eCXt pxrz7b4BKPXi5kadBapudB7r9htkaI8S 5ORTgXpmAcYGDk4sVUg/f3hp/fyU/CMc 9KVZPdLjqGUL+FnlBee+L+wR0HSCc13L j4RK67DtfsGMpeR80LlcZw==
+SECTION ADDITIONAL
+rootns. 518400 IN A 198.41.0.4
+rootns. 518400 IN AAAA 2001:503:ba3e::2:30
+rootns. 518400 IN RRSIG A 8 1 518400 20170804000000 20170721000000 28969 . QZhev/bmwYaANmOIgiKUZbhb4+6cf0pK AYWChRC+oFv2KSlI2qkWjdu9D36Cxwph 4q0UeKsz1BgB+bk6iA+qCdZdv550ssvw LALjZ59bhnD0ts5hfKttpSVRrRLocL8L VOKsh89+vcFggOtNBNxR0uvQZaDwHAqB 5qle9YjqICpo66kXaHtDVB0rptYwnRoP je5CtgGVKrTgxFnNvuQhqq+Jex1DetFU CQcvlObPV57LxGIaWVsHspO0y1u+U5EU rkICR/j3kCX+ugdTfRYhGJ+MiDdhqj1v KaXmVuAUliybx9ElQA9AjjLy9SdmJriq rr86biqSr3tpfAB4B4RfNg==
+rootns. 518400 IN RRSIG AAAA 8 1 518400 20170804000000 20170721000000 28969 . ceLKW/BKyqC5qryqZWXFaFVMRJOu7Lrh dKqcqh7zHevV5ZGF+RzGtGX0XeOahzoo 3W+tM4r7oP7yduPetBGQnnVb8WiuEs2B YUx7LwFdR+I9hSIHVAmB9rIPVm9QHAx0 KCYEIu5Trv7sxWGgetxdXQwMeAY+xHhG YdXZQ1vgxM7bG4w6Ei9+pKi3iw6oH7pX 91uldh9Xgi4ajFcYQ+/N7azjddzv6jKB cTro1PQTiX80vUnAZQxTRQAMvKfWkWZM 8mjna00RSnvs2T7EPS1wrL7sK4os9dU6 1B5SoQhTrJRmzF/Bc1kB1lXhTW8TrPnV UMeoJAN9VFEfRC6fqOq4iQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rootns. IN NS
+SECTION AUTHORITY
+. 86400 IN SOA rootns. you.test. 2017071100 1800 900 604800 86400
+rootns. 86400 IN NSEC test. A AAAA RRSIG NSEC
+. 86400 IN RRSIG SOA 8 0 86400 20170804000000 20170721000000 28969 . RF31T45DXJHLnVI6wENwbT6Enc+9RZt2 ydueew94jnGTB55BJT9Mq2rWkzkP/ymR RzZjixoBsoRgCFlfs865Z+JJtR7nk23s Cl02erMw6lra4IaD8q4M/sH7vh7AAo/c /GVqKyxcCZiIwk/A3J1qpAAvbapE/jwT seg04WM7XEsqp58BuNluff6SavIaFB/Y 70sGNMm+jbBnk+W6HOJw6bB1GOyLE1Gd Ae+YMSbEA2H99WAZo7rlKO43CQY8sbzY 3pKCrY6kXNoBQSlpqWxjU7UIjYdU/8F6 RrBJzq1aIKBEjAh2zEqqpb1NyxfMoJku 2I6eERUs/J9MNc+gn3pwgw==
+rootns. 86400 IN RRSIG NSEC 8 1 86400 20170804000000 20170721000000 28969 . ErIpaMwf+buKKDCcMvwoqji0YvvSacdL M4zSZKjiLPhGhaDmcWTLECes4En511Pt m8ft/F+ghQPobhH55VbBFFPLpFqVXg7/ JO/EoUYXDKSmjOxSLre5UVzCeeyKq2wf GmTLZUyhRJQbuQnzv29IIhr5pGUcFebU d/B4blebChkwSH+/Pb8LIfBRiMEoFXiV sHu75Pl9pKgAe76fUUdstB/7vT4SGXHa hHvduxGk3qSBqfi8h+/mnQzfk1H5UiUs U3Uvgq9JuWVBioSIHh4pF2RUMkk4aXCl 02H9iBZdIU3PjQu0O+CJmjFCoFslxUrK /6IQMZc9Ram1zUd/HfKbUw==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rootns. IN A
+SECTION ANSWER
+rootns. 518400 IN A 198.41.0.4
+rootns. 518400 IN RRSIG A 8 1 518400 20170804000000 20170721000000 28969 . QZhev/bmwYaANmOIgiKUZbhb4+6cf0pK AYWChRC+oFv2KSlI2qkWjdu9D36Cxwph 4q0UeKsz1BgB+bk6iA+qCdZdv550ssvw LALjZ59bhnD0ts5hfKttpSVRrRLocL8L VOKsh89+vcFggOtNBNxR0uvQZaDwHAqB 5qle9YjqICpo66kXaHtDVB0rptYwnRoP je5CtgGVKrTgxFnNvuQhqq+Jex1DetFU CQcvlObPV57LxGIaWVsHspO0y1u+U5EU rkICR/j3kCX+ugdTfRYhGJ+MiDdhqj1v KaXmVuAUliybx9ElQA9AjjLy9SdmJriq rr86biqSr3tpfAB4B4RfNg==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rootns. IN AAAA
+SECTION ANSWER
+rootns. 518400 IN AAAA 2001:503:ba3e::2:30
+rootns. 518400 IN RRSIG AAAA 8 1 518400 20170804000000 20170721000000 28969 . ceLKW/BKyqC5qryqZWXFaFVMRJOu7Lrh dKqcqh7zHevV5ZGF+RzGtGX0XeOahzoo 3W+tM4r7oP7yduPetBGQnnVb8WiuEs2B YUx7LwFdR+I9hSIHVAmB9rIPVm9QHAx0 KCYEIu5Trv7sxWGgetxdXQwMeAY+xHhG YdXZQ1vgxM7bG4w6Ei9+pKi3iw6oH7pX 91uldh9Xgi4ajFcYQ+/N7azjddzv6jKB cTro1PQTiX80vUnAZQxTRQAMvKfWkWZM 8mjna00RSnvs2T7EPS1wrL7sK4os9dU6 1B5SoQhTrJRmzF/Bc1kB1lXhTW8TrPnV UMeoJAN9VFEfRC6fqOq4iQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. 1 IN TXT "check and change answer"
+test. 1 IN RRSIG TXT 8 1 1 20170804000000 20170721000000 28969 . BKc79/iitLm4EWqaIpRy49O0VosanODV w4YR0tVoCQLNKePEVnzBQdPxsBpRV4nk 38TRSqp7XwZJd8gPskXtrfrkO5Pz28M1 8cA6B/uExOBQYCFVGjv7avo07p0EaxGD CjX0yoNbA0Z3SQHhgsUYC4eMiPsOcfos UtnNkZHipA6/QKUD1fqo13Y69gcl8glr Cb/rQn+IYo7GqrRrESUkQEFcwlWd2sii Z06ZchNxTspNL2irm2mqpsmMK/osEkyv LG9dauX83ZO6WaQlZmDspaHEFbS9HhlI OVTPG7mUTlTROQFG1zTVuGW2gu6kY6ms LFwpurPHw0bVeRJ2JLFifQ==
+ENTRY_END
+RANGE_END
+
+
+; 2017-07-01T00:00:00
+STEP 20170701000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170701000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode qname question
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170701000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-07-02T00:00:00
+STEP 20170702000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170702000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode qname question
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170702000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-07-03T00:00:00
+STEP 20170703000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170703000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode qname question
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170703000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-07-04T00:00:00
+STEP 20170704000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170704000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode qname question
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170704000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-07-05T00:00:00
+STEP 20170705000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170705000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode qname question
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170705000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-07-06T00:00:00
+STEP 20170706000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170706000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode qname question
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170706000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-07-07T00:00:00
+STEP 20170707000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170707000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode qname question
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170707000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-07-08T00:00:00
+STEP 20170708000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170708000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode qname question
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170708000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-07-09T00:00:00
+STEP 20170709000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170709000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode qname question
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170709000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-07-10T00:00:00
+STEP 20170710000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170710000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode qname question
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170710000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-07-11T00:00:00
+STEP 20170711000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170711000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode qname question
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170711000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-07-12T00:00:00
+STEP 20170712000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170712000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode qname question
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170712000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-07-13T00:00:00
+STEP 20170713000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170713000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode qname question
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170713000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-07-14T00:00:00
+STEP 20170714000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170714000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode qname question
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170714000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-07-15T00:00:00
+STEP 20170715000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170715000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode qname question
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170715000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-07-16T00:00:00
+STEP 20170716000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170716000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode qname question
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170716000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-07-17T00:00:00
+STEP 20170717000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170717000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode qname question
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170717000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-07-18T00:00:00
+STEP 20170718000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170718000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode qname question
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170718000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-07-19T00:00:00
+STEP 20170719000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170719000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode qname question
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170719000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-07-20T00:00:00
+STEP 20170720000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170720000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode qname question
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170720000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-07-21T00:00:00
+STEP 20170721000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170721000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AA NXDOMAIN
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION AUTHORITY
+test. 10800 IN SOA test. nobody.invalid. 1 3600 1200 604800 10800
+SECTION ADDITIONAL
+explanation.invalid. 10800 IN TXT "check last answer"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170721000099 TIME_PASSES ELAPSE 86400
+
+
+
+SCENARIO_END
+
diff --git a/modules/ta_update/ta_update.unmanagedkey.test.integr/unmanagedkey-revoke-monotonictime.rpl b/modules/ta_update/ta_update.unmanagedkey.test.integr/unmanagedkey-revoke-monotonictime.rpl
new file mode 100644
index 0000000..c0949f0
--- /dev/null
+++ b/modules/ta_update/ta_update.unmanagedkey.test.integr/unmanagedkey-revoke-monotonictime.rpl
@@ -0,0 +1,762 @@
+stub-addr: 2001:503:ba3e::2:30
+stub-name: rootns.
+trust-anchor: . IN DS 5191 8 2 78DE555142AECCBFE1F4F24A9053F7A3C8BAAB2891DBB80D0CDD29534A44C3AA
+trust-anchor: . IN DS 24784 8 2 5448342C83F1CCB31F966A835897DF1484B12074AB535B2CB84CFD8E2E792B28
+val-override-date: 20170701000000
+query-minimization: off
+CONFIG_END
+
+SCENARIO_BEGIN Simulation of successfull RFC 5011 KSK roll-over during 2017
+
+
+RANGE_BEGIN 20170701000000 20170710999999
+ ADDRESS 198.41.0.4
+ ADDRESS 2001:503:ba3e::2:30
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. IN SOA
+SECTION ANSWER
+. 86400 IN SOA rootns. you.test. 2017071100 1800 900 604800 86400
+. 86400 IN RRSIG SOA 8 0 86400 20170715000000 20170701000000 50124 . mlDK2ln5t2Ql7/neef2Pzz1URLXCV5ml 0QYXbt2kzrgeKqoHRXMGc6nxqYv5Ttpn TtY82BhNlYuTzubWrrg+SS7z+vSAwUM2 mXG16Y0Z3PoKc/25dmYElwcaG1h10elI unPy1GKGoEkUlEtT/6nHQdkhvyUL5QcX AwjljLIxsY7BnzhmQEsz0ywMrTmg85vX H0BOK0IFBKxLBncx10wvJGApaVzaxdWc 0H/+fnF1r/rg2NvRFuIXlz4vrl9ExNMa ZmXR4PLlZTHO3FaH9yF18IHPCY/bi8L9 NjfW9pj+Fg4LR2kPj5WCkrCR9RKhdUAO xJKLSBuSi0CL1OyLWg9QMA==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. IN DNSKEY
+SECTION ANSWER
+. 1814400 IN DNSKEY 256 3 8 AwEAAcHrmeeZUfVAS5KzAL2mHyjpdS3y 5Du2ScdXa1nunnaA35ARZR6BbwuQdIik CC1LH8D7d/AlDW7SlkHWeWBK7eMxO0Ps E2u9jlN2yy+9OQwo1kybg4cBDwbgHmu8 ppX7U3S5SpP9XZIJhYRYqNube/zkoDSa uLaeghU13CCuIwdbJrPNOC6Zvn0op3WL ryTVMnMUzgld6WsiTWZDlaMy5IJdhg5R X2wa0UCJjr1M3kguTHftYExgUKbQytx2 +i1mq+vSKqcS9Bxo1vFTWMtFV2FFpV8T Fv4dL1aC1Aq8e9CiAIEfCVVy8Dw+vYpO VDrd+1qkNorMNetwEly9EgkWgB0=
+. 1814400 IN DNSKEY 257 3 8 AwEAAZxJIBnv0pOId/Ukgr0pwVLXjiBR RyV0kc76BssLTIFPWnEWNLv7+3JRvcAm tpHzDvpCoX92taEYVP3pgF3WUNA/LOJR iYIE8taQ0j0TpbdiizFtgFCc+zE5TZ6z /Ru1Eq6VXgdpHzpPtTep0+gB1Qz6HQNT Wd0v2/XQmKWkh3KnJuDSrBjQy50ax9zX 1Sj8Syv+oA0iREf886Bb3e1nBaWrw9RE xovh2F68eE5hxwBcipwNyf7iEN8Um8Tj KCXWeEnTM+Giip0F+JgbapEKr8Dk5YYv nRBLwPZiekL35AbGA9/8PfCwtAIBAj3A CVHhgmlPbLzPGRyawTtIe9D/6uc=
+. 1814400 IN DNSKEY 257 3 8 AwEAAa7l/x0mKre1XGN10bhnsSuo+Lc7 wFv6ksfiDz/kLgbR1TQY37ntCm3akRr/ hp3CE1YUnAGlk9B5lZYEeT0hoD2BkD7E P9DpOxUqKtQeYhe34pO/ygT+dFYSaMy/ 0OStoYLphzbIfElrpg+gvv+CkFKQzO5W rAL1tWu037erXbhSjko7AokpjfEWyT8H o7qGHiW1vWgzWGtWIgXOdydUJYqQNaOY cddJNV23fod6+KrKE245JRv+KabqnLJv 3+D6g7NDh+D5uLiX4vcTsLoB3LiAruQA r+ickjYFsVvfJlJ3m9O0/st9UsXu+v0e 6Esl5DmWWYo63T31sgmSEOjUSBE=
+. 1814400 IN RRSIG DNSKEY 8 0 1814400 20170722000000 20170701000000 5191 . aIPJnGM1RKAVdVGU1I+3cgs7eSa+mYMG iIzrG9sD98id0zCZ+ekUOYjw6UfWYlBI YT7ebhDIdr0bXwCuiTcvuNZ5ps3EzreW bh6udtTBumshkcxEVFFbzgdUw08L9xoq 9aXDDz5+wS9qbxizaoLYb3DxdDKALKzN VQ3ToLe+V51obIULXYAJbhvUSNRqsATW Rj+Au9j+wiKWgnHl3el+/iwmomNmYvNE USi4+2uHIMA3g47E4VeAGskVgDAskgNH rSeVLoNS43r77UCmpD6WT3P7Kc5BNWY5 RNUX1a17GCnLFamcJlmEnfvxKUC+qTkg cXPe+bGH8W29f9vJFheicw==
+. 1814400 IN RRSIG DNSKEY 8 0 1814400 20170722000000 20170701000000 24784 . GI/kjTcDyKgcLW98ySEPrNk0kRHR+F4u HyNmPGUq19xUdr3uBKrBUCsnSxb93QRo wb9z7b73FwloyQiXOR9Q9M2MiO58+RDG eEC+G/+67abfItVkBf/ZglcPu+LTyg9F 2y0YzcQ5zH1JkmG/I7d7NGN7Wq4rEWWJ FHAOrIruOl1mNkGnRXDY/vytR4ntiWDk NNpEof6Qfzg8fXP5JegezNwUatwbrFwO xqsM2pITtIS3Kl/H4L7iajyxeQZCqX+R iCZ/O9FIn3Y+OX6JkvvMXGB+0DatTGPJ iE0AHWWPFa1V4SeJz8WKPB1UorvOqM61 LR1GlPWlQGutZhbTlUFLyA==
+. 1814400 IN RRSIG DNSKEY 8 0 1814400 20170722000000 20170701000000 50124 . tQqe8/mF2f7HIXlXe77EdgRoKu7KqdjD PR/ELk9i/le8GLy/eDI6nlwAfiWKcgqN nFey9UzT/kWk3L8umb3c8aazpuQYJAwi dsZNWlx+yc1dEw6lS+6WqTSiEEzXhQh3 wvOPA58rWflatBYuaAx2scQ/OhPtf0me 64G4O/LIpZO5yLPs3RwBnjzSq2907Bfz pD2xfa4fvqI1yxfQzMx46QF6zYy2zam2 XBEbSKNxSamW8VN60oItbozLbQ4pVwyX Ni1k/WKZHrJ+ppKSDtQhqN4CvxvyybL7 5ovtJpAKYEGsmvoZqoz33FcU2HxleIun 8sKzXaNJ8+tXlrKoicZI6A==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. 518400 IN NS rootns.
+. 518400 IN RRSIG NS 8 0 518400 20170715000000 20170701000000 50124 . JziSSYhqZP9eOAenLKp28LqcrAe1gs3K eWhGpOxX/u+hCnQFhuJZm2bZHomTh8Il IwQ9eKZizGQjG2BVIWhMJEWCUaPuUul1 Iq7hW9sSilivZNjef69I0xbA2Mk9MyrX 3rRUl1c5y37u5olOU7aNUAdlS3A9Kvvv dOuCWoOiVjjequaZi9JKEwHagk9il2fF HGT8/XMfIyNl4w2AvzHJ9G5oNA+HaH5E npbr8opWSxsxu8W00ne1PcDtMnmGtrPH Is1hIs/JfYQFP+0lsXU5L8gs5nfZVXgj CdluHHCnynlfp9omhbF657Mh6RMqZE/Q r+eKi0Tti/Z5W3xX2SMbWg==
+SECTION ADDITIONAL
+rootns. 518400 IN A 198.41.0.4
+rootns. 518400 IN AAAA 2001:503:ba3e::2:30
+rootns. 518400 IN RRSIG A 8 1 518400 20170715000000 20170701000000 50124 . g9NhvW/Ka1w9I9JPTktcJsmeDJAxAJ4i A+Eot8m7I4HTRQFHLD7DJHFB2pxesbJs WgdY+y38RJ4SDi4NodmEB60FSyNptQxO gsVYRaPclfZSjv/YhYOztns8aeZP6Qrt 4ETFI/A6ABwDjL/1ATk8zsgdhgP2u/dO d0s8pz7reNfUAf7/BsLER3pF8y23yYbp afZaVgZ1N5xj4EorGdDYhsOIN71dzAjK xaqdmj/mW/AcoAj8F+cRjVNt8vJvH7tj KiMU42hLne6RNHTCod6xn2wpZzwUB2OO kv73wEP+sJuWW4gMLpUfuGBltq5QlYH5 JAVl1V93KKNgz5szeIEpAw==
+rootns. 518400 IN RRSIG AAAA 8 1 518400 20170715000000 20170701000000 50124 . tNv9R7ZphTo6s/yHsQKEZkoCK47KCPL8 p5nlc5Y0gHST42zu17SuRLKz4UQOSGjV RzFpSE7NxtERLeMhIqtEX/z+yQJ9EVJr exx/7/Ihlq4cRFzwu+7wfte+iGXXy9ZK B7kNce4ft/xgAXP9X1afruFlClb+gqar M6PETTuluNkdjTQRsOD8F62H6CXnLQQI QEMTQ4ZfAdxzrXcuIH+QHW3daMm8HfXz x9+15bVGWofeQsnZASTrK+UmcMPwu8Em z73me3YF+eKW4mMoYcQphI73wa+MltaW 5LO27IThIo0VVrtuQ2dgYg/d4J6zPUo1 k9vUS6eWFHSE5yNTu1YDyg==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rootns. IN NS
+SECTION AUTHORITY
+. 86400 IN SOA rootns. you.test. 2017071100 1800 900 604800 86400
+rootns. 86400 IN NSEC test. A AAAA RRSIG NSEC
+. 86400 IN RRSIG SOA 8 0 86400 20170715000000 20170701000000 50124 . mlDK2ln5t2Ql7/neef2Pzz1URLXCV5ml 0QYXbt2kzrgeKqoHRXMGc6nxqYv5Ttpn TtY82BhNlYuTzubWrrg+SS7z+vSAwUM2 mXG16Y0Z3PoKc/25dmYElwcaG1h10elI unPy1GKGoEkUlEtT/6nHQdkhvyUL5QcX AwjljLIxsY7BnzhmQEsz0ywMrTmg85vX H0BOK0IFBKxLBncx10wvJGApaVzaxdWc 0H/+fnF1r/rg2NvRFuIXlz4vrl9ExNMa ZmXR4PLlZTHO3FaH9yF18IHPCY/bi8L9 NjfW9pj+Fg4LR2kPj5WCkrCR9RKhdUAO xJKLSBuSi0CL1OyLWg9QMA==
+rootns. 86400 IN RRSIG NSEC 8 1 86400 20170715000000 20170701000000 50124 . gHVrjgFrTN3p4a/4C7yyqNQKYxsIGRKH l85pqif1AoXjWQfRpVpX7JvjQ0TMJwFK GRyKpcuy6wofSg9HglcaJ6xd2BSv0Qx5 OTz1DD0x8/Vf7BDyR8S0X7CUKkkmxKt4 VjMzh1vZxktVh32d562hOCaIXaL8obuB 0+oYABZTT+6qc6a7dBAhtzg6e0qtH9vg o1v/0JXudTY3L1Gv92hBI+51/nfPZwaB Tea3VbwYdG9YzqAYenVakaAvtVvadcMD 8vV8Gjx58CaPxvIDoA0z7EYGvY3VSaV8 hL+KIV9x8bV8MVa++ykwDcgcXInp3Sg1 zUhrGGoTGRnY/dC+cUpjoQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rootns. IN A
+SECTION ANSWER
+rootns. 518400 IN A 198.41.0.4
+rootns. 518400 IN RRSIG A 8 1 518400 20170715000000 20170701000000 50124 . g9NhvW/Ka1w9I9JPTktcJsmeDJAxAJ4i A+Eot8m7I4HTRQFHLD7DJHFB2pxesbJs WgdY+y38RJ4SDi4NodmEB60FSyNptQxO gsVYRaPclfZSjv/YhYOztns8aeZP6Qrt 4ETFI/A6ABwDjL/1ATk8zsgdhgP2u/dO d0s8pz7reNfUAf7/BsLER3pF8y23yYbp afZaVgZ1N5xj4EorGdDYhsOIN71dzAjK xaqdmj/mW/AcoAj8F+cRjVNt8vJvH7tj KiMU42hLne6RNHTCod6xn2wpZzwUB2OO kv73wEP+sJuWW4gMLpUfuGBltq5QlYH5 JAVl1V93KKNgz5szeIEpAw==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rootns. IN AAAA
+SECTION ANSWER
+rootns. 518400 IN AAAA 2001:503:ba3e::2:30
+rootns. 518400 IN RRSIG AAAA 8 1 518400 20170715000000 20170701000000 50124 . tNv9R7ZphTo6s/yHsQKEZkoCK47KCPL8 p5nlc5Y0gHST42zu17SuRLKz4UQOSGjV RzFpSE7NxtERLeMhIqtEX/z+yQJ9EVJr exx/7/Ihlq4cRFzwu+7wfte+iGXXy9ZK B7kNce4ft/xgAXP9X1afruFlClb+gqar M6PETTuluNkdjTQRsOD8F62H6CXnLQQI QEMTQ4ZfAdxzrXcuIH+QHW3daMm8HfXz x9+15bVGWofeQsnZASTrK+UmcMPwu8Em z73me3YF+eKW4mMoYcQphI73wa+MltaW 5LO27IThIo0VVrtuQ2dgYg/d4J6zPUo1 k9vUS6eWFHSE5yNTu1YDyg==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. 1 IN TXT "it works"
+test. 1 IN RRSIG TXT 8 1 1 20170715000000 20170701000000 50124 . MMOSQjU/uKwroJnNJgwb9ddyp/P5VUBr S9F4RMcPYvjqVEczfkwTMZCZvHU6S+kV AoYuMJsWhqja/YLAL9l6h1c3DJM2apVE 59ro3u1k6NeKBghVNcRscbpYeI0jaZMD 6c5r2dBtB3sE0zUPV2feCfsyV1wBPxtr 8XWBOVYu30LYXCath13F+DqXEkTNudzQ oCHixJQ9y71QXJniXgDaRxq9l5iqA4Q4 nt4zhIWntHClUJRwpQlJVU34eLiDrO6n 1s2oVPXKLwa2/mG71afpAgsOiCvJDLeH Oa2AqjAvQ9yUDIjNoaOvLv0mrp4csBSj ZC0HIMMDWqHES4UoinY4tw==
+ENTRY_END
+RANGE_END
+
+
+
+RANGE_BEGIN 20170711000000 20170720999999
+ ADDRESS 198.41.0.4
+ ADDRESS 2001:503:ba3e::2:30
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. IN SOA
+SECTION ANSWER
+. 86400 IN SOA rootns. you.test. 2017071100 1800 900 604800 86400
+. 86400 IN RRSIG SOA 8 0 86400 20170725000000 20170711000000 50124 . Ioju8kIHgI70wBcbEyZZLbb61G42MnKd wGLxNNhBctq03x74tpqlR6HeCMJf4PW/ UHO4QqubeGK7m6TAfWvx76NKa4bYNYAj S4w+Izv5V57GL3u6BtawIdBLJfHGMLyA Aifn9xc8BnWv1Fw0k09mzXb99EC2Mc77 n99imV/I8B5sX1qi3z7bBj0pFGwvyILV FDBqFIU+kq3S78XEXpTFYInoPnDGhqAj 4g6H1QXAdW89GqkCATBKA642xI7jZ8pA 1AMlHo/YhkYr1rPQx27kGLKQJgJVpPa7 +Dh4+hy+DBRYZUUldqV4Ee+TyTT/nh36 VylsuIjbQYN801N5eFw4Qw==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. IN DNSKEY
+SECTION ANSWER
+. 1814400 IN DNSKEY 256 3 8 AwEAAcHrmeeZUfVAS5KzAL2mHyjpdS3y 5Du2ScdXa1nunnaA35ARZR6BbwuQdIik CC1LH8D7d/AlDW7SlkHWeWBK7eMxO0Ps E2u9jlN2yy+9OQwo1kybg4cBDwbgHmu8 ppX7U3S5SpP9XZIJhYRYqNube/zkoDSa uLaeghU13CCuIwdbJrPNOC6Zvn0op3WL ryTVMnMUzgld6WsiTWZDlaMy5IJdhg5R X2wa0UCJjr1M3kguTHftYExgUKbQytx2 +i1mq+vSKqcS9Bxo1vFTWMtFV2FFpV8T Fv4dL1aC1Aq8e9CiAIEfCVVy8Dw+vYpO VDrd+1qkNorMNetwEly9EgkWgB0=
+. 1814400 IN DNSKEY 257 3 8 AwEAAa7l/x0mKre1XGN10bhnsSuo+Lc7 wFv6ksfiDz/kLgbR1TQY37ntCm3akRr/ hp3CE1YUnAGlk9B5lZYEeT0hoD2BkD7E P9DpOxUqKtQeYhe34pO/ygT+dFYSaMy/ 0OStoYLphzbIfElrpg+gvv+CkFKQzO5W rAL1tWu037erXbhSjko7AokpjfEWyT8H o7qGHiW1vWgzWGtWIgXOdydUJYqQNaOY cddJNV23fod6+KrKE245JRv+KabqnLJv 3+D6g7NDh+D5uLiX4vcTsLoB3LiAruQA r+ickjYFsVvfJlJ3m9O0/st9UsXu+v0e 6Esl5DmWWYo63T31sgmSEOjUSBE=
+. 1814400 IN DNSKEY 385 3 8 AwEAAZxJIBnv0pOId/Ukgr0pwVLXjiBR RyV0kc76BssLTIFPWnEWNLv7+3JRvcAm tpHzDvpCoX92taEYVP3pgF3WUNA/LOJR iYIE8taQ0j0TpbdiizFtgFCc+zE5TZ6z /Ru1Eq6VXgdpHzpPtTep0+gB1Qz6HQNT Wd0v2/XQmKWkh3KnJuDSrBjQy50ax9zX 1Sj8Syv+oA0iREf886Bb3e1nBaWrw9RE xovh2F68eE5hxwBcipwNyf7iEN8Um8Tj KCXWeEnTM+Giip0F+JgbapEKr8Dk5YYv nRBLwPZiekL35AbGA9/8PfCwtAIBAj3A CVHhgmlPbLzPGRyawTtIe9D/6uc=
+. 1814400 IN RRSIG DNSKEY 8 0 1814400 20170801000000 20170711000000 5319 . CznzeEi6yFncw3D4NCZhUJTGf6yB9Gli tODI6UUbpntDKgdRXAWPaP13gfDUcUfb 1rhNeVJdAgxgcosDaXc3QIU1hOe85jra Z76D2hVP8/jRnEaJVaClvD7qtWaIP7bV z0JvH/4fDysSAVUySZGju+YwZfKtw8Xa exFhMJ/cqHmKV8KKTwvFddmWYSdiPGCY YokbxblHQClFMoO5FtNbVbNlRXyi8LcW 6YXNpyAyuDlYHxTc/6ilCC+fE3VzAIb+ 7b2r3NZzVkorSLurJBSHGI5vvqeOtoZX LiVpim9RASXbbP6XHf4ycsmWg9t5Eyud 7boxwvlRUlhe+he/li2ucw==
+. 1814400 IN RRSIG DNSKEY 8 0 1814400 20170801000000 20170711000000 24784 . UUk7x64kvHURXPoiFHokjEta03vK89s6 xPC3dclk0TkVg+wSIMdI7eGuaZd+YYzJ 5iUYQBbLak4zZAbfq/wFl+sIoxt4Zmh/ Ja/T0LEhRqFru3/F0WcXmN39gPlmRqoH hogy7cxuAlj+L/MZf0JQAdUeb+RO0e55 ELpZ5kErYhQNG5/c2rdIg/PVV5DK638g APJ6Z0xDxqkmlBeuiMM1jrCytnmBPNHl HdR80VKFIeNL0ss5nsZzeDl4xLyqhleM K9wfmXwfySLu/ZZdfNQl5/qZMCKuDcTz 8HJ5dFmRl3nu3M8urLzYHj1lxdWfO+c4 lcjkT4S6bsozH84z6HymaA==
+. 1814400 IN RRSIG DNSKEY 8 0 1814400 20170801000000 20170711000000 50124 . scFytgOyp7j+yR1QC5dSQEqzbUEeq99b aNoz8KoS1u49CM4IkxnmMiWQ4Ocs7Lc1 X0P9i6WgYEVIlo7OoRwFMGoxtsrG4rSs Crg3cCopCLtinGugO5pdj4zQi/SWIjy7 Ydq00Qrq9W25QAr4Z6BlvF85RYb7LSUi 9e3wbL2cFprG4OGP4cyMM2sByPPt/H0S dOsNEppsInTA61EYD2siRfbt9vEXOY+C ikcJ7LACBJ+ga5D+7Wsr8/tmEHb5Zd/5 8Zl6RlL1F8Zj/MvZT6a9GEM+vSkUWWln HsPGwhvoWcl/z9vdQag4E2Vaw6MUY7zj p4Mls23OJv03FbCvpWogtg==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. 518400 IN NS rootns.
+. 518400 IN RRSIG NS 8 0 518400 20170725000000 20170711000000 50124 . sL/q7IdMSJir2sAkL53PcYcmec33LeGk j3V+GmlvwrK71usBnz4Hp/xZ+hlyqjnX +y9qmNRMLngfW44Kmp/U3A3db3CSHJ4t XRYDjMbuR0UI2Y6zX5I3/v5VYoDEnV4R Amij1UtEQDdqQRe5BHoikUZHyN+In14I sRNTqjWgKd7W4jxJtmRVz1VTc86O9UmX PmreNjP/w6OJsfE/uozxxdOXk5Pnf5Ln 2rr4NO1kkhrFVf0VV0UNOBijkJIHEoRu 94/NMaAC3asuOW/rXbScnW+s6iX3kTIb 3LjiAks44uudRgTXcpgwnSrPhPkW/7Ct O+sXGZr4bY3C0r+rjkkirg==
+SECTION ADDITIONAL
+rootns. 518400 IN A 198.41.0.4
+rootns. 518400 IN AAAA 2001:503:ba3e::2:30
+rootns. 518400 IN RRSIG A 8 1 518400 20170725000000 20170711000000 50124 . roCz+GbpvVzD1RHy0RU0ji4iHBL36x0D bcWhC2PGj14AzX2j6OPlpDG1dRf9X4qz Es73u3IZjYRb3ZdQE0V/lBXpqbCb+Usp SGdj0huP7j0aNRawNmSKTimx3eSzhI1t CCmsYiavH1GpFUKQdLDP0vBq3OHxJHBM GP1ff6scTG9tBKzZtr7ZCdFK8hH9Z6Yr bOkXmRMM11rKMRjB9A0qBcVknWclDcY+ KajxfhUsjvAuGsEqQf58ekU6PPYXNmy9 lK8LRTf4UDNt86qjY8MRflhWN83cRc8g GCNKSGqXZ4yqZnQF2gbACVH7LY3YOLKe 7Rfl+CYGJACMLfzUJ7B6Kg==
+rootns. 518400 IN RRSIG AAAA 8 1 518400 20170725000000 20170711000000 50124 . oR5QQvmd3XU4E/njBMZq1Px+iHgKla9/ /PRteMz2c2gqvQBX7gMk6+6ybgQ10IhA cAE4xflPtOdLS7Wvb3OP2LA5Sdi/vxwZ R+2bHHwPAtkbP8AO/70mcWIW5MIBqPD3 bQkRmTDnBylNRU3j+DPu6xew+f6DzUPt cSRrm+8j54y44yNB4lV9yppoXYEibX/q xIIqkauYEVETVtmzTmB4PjWDTriA0b9z 0eZetan+z2x0GqnBaQT/3a+cn6xyZA4X JwDJ0n7dL/VVJbJwb2/ZziMRO2ng4M5F RMWlD6aKZkBKn3CLDtzVOhG+HO243ivO vzTg72aTIVkUQOj2k0sjbw==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rootns. IN NS
+SECTION AUTHORITY
+. 86400 IN SOA rootns. you.test. 2017071100 1800 900 604800 86400
+rootns. 86400 IN NSEC test. A AAAA RRSIG NSEC
+. 86400 IN RRSIG SOA 8 0 86400 20170725000000 20170711000000 50124 . Ioju8kIHgI70wBcbEyZZLbb61G42MnKd wGLxNNhBctq03x74tpqlR6HeCMJf4PW/ UHO4QqubeGK7m6TAfWvx76NKa4bYNYAj S4w+Izv5V57GL3u6BtawIdBLJfHGMLyA Aifn9xc8BnWv1Fw0k09mzXb99EC2Mc77 n99imV/I8B5sX1qi3z7bBj0pFGwvyILV FDBqFIU+kq3S78XEXpTFYInoPnDGhqAj 4g6H1QXAdW89GqkCATBKA642xI7jZ8pA 1AMlHo/YhkYr1rPQx27kGLKQJgJVpPa7 +Dh4+hy+DBRYZUUldqV4Ee+TyTT/nh36 VylsuIjbQYN801N5eFw4Qw==
+rootns. 86400 IN RRSIG NSEC 8 1 86400 20170725000000 20170711000000 50124 . hvFKqAWhl5GNl1r8yPMgCGDiskPKPBCx xzWWfoeZZIzhAXgeZGdCsd/5tS3fifaX Y7Wn6rMi0BstLa/+63xaY4iIvX36Zb+n eLxaKrtjr06Pnappg6EHDvF2qjEHf+ip pIif7yiX6UZemLK30E/mUhkL1HFtc9eW 9ZGdTI4VUyJvhax2qW4fcoYNgPeLeB+i LrdjyfKXB3tnrcZbmVqKa7OQX+JNL9yN s5YHbftvraZt9p0Ye+A8wwsvKE1eOlyd msdylrtlDz3JdKBsAdQm9ek5Ltpuvbht xYyvhh72c8RpO9aUUP1ehT9rtH6NeA3U dBooOLGimGRzJJ3BNYuBig==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rootns. IN A
+SECTION ANSWER
+rootns. 518400 IN A 198.41.0.4
+rootns. 518400 IN RRSIG A 8 1 518400 20170725000000 20170711000000 50124 . roCz+GbpvVzD1RHy0RU0ji4iHBL36x0D bcWhC2PGj14AzX2j6OPlpDG1dRf9X4qz Es73u3IZjYRb3ZdQE0V/lBXpqbCb+Usp SGdj0huP7j0aNRawNmSKTimx3eSzhI1t CCmsYiavH1GpFUKQdLDP0vBq3OHxJHBM GP1ff6scTG9tBKzZtr7ZCdFK8hH9Z6Yr bOkXmRMM11rKMRjB9A0qBcVknWclDcY+ KajxfhUsjvAuGsEqQf58ekU6PPYXNmy9 lK8LRTf4UDNt86qjY8MRflhWN83cRc8g GCNKSGqXZ4yqZnQF2gbACVH7LY3YOLKe 7Rfl+CYGJACMLfzUJ7B6Kg==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rootns. IN AAAA
+SECTION ANSWER
+rootns. 518400 IN AAAA 2001:503:ba3e::2:30
+rootns. 518400 IN RRSIG AAAA 8 1 518400 20170725000000 20170711000000 50124 . oR5QQvmd3XU4E/njBMZq1Px+iHgKla9/ /PRteMz2c2gqvQBX7gMk6+6ybgQ10IhA cAE4xflPtOdLS7Wvb3OP2LA5Sdi/vxwZ R+2bHHwPAtkbP8AO/70mcWIW5MIBqPD3 bQkRmTDnBylNRU3j+DPu6xew+f6DzUPt cSRrm+8j54y44yNB4lV9yppoXYEibX/q xIIqkauYEVETVtmzTmB4PjWDTriA0b9z 0eZetan+z2x0GqnBaQT/3a+cn6xyZA4X JwDJ0n7dL/VVJbJwb2/ZziMRO2ng4M5F RMWlD6aKZkBKn3CLDtzVOhG+HO243ivO vzTg72aTIVkUQOj2k0sjbw==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. 1 IN TXT "it works"
+test. 1 IN RRSIG TXT 8 1 1 20170725000000 20170711000000 50124 . UFS44wefPpNwYGd5AtJL2LgjnL2HJs19 po0R+h6WBuxSoSLnMjg0gYHaiN26LNQT Wgs9A3DsW9I5mJJZeh4ZPNzzxWH0MSGL nvyRVwSPj/WGhzhwHTDReJ5cAKzOUD3H qxr9nYEyd3PWbRHY4SgfAfbR+qv3uInN MGcnX4+/8HPYcmcyuS2E7XdEv8teFBXr +evmJzQiJAqrpQ4maUlz6hKeJjOWBvKW Ta8neWaO6rqnmSQjO6h0SGSdhfeXUnqA 6LwmkV3Gqy1Dt7kAAzLVQhYvN5w+nqj7 26NHTZUQ1yXb1fCrdLpVa6a14bgDJQsf leRh4tR0P5H9MPjPi9M6ew==
+ENTRY_END
+RANGE_END
+
+
+
+RANGE_BEGIN 20170721000000 99999999999999
+ ADDRESS 198.41.0.4
+ ADDRESS 2001:503:ba3e::2:30
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. IN SOA
+SECTION ANSWER
+. 86400 IN SOA rootns. you.test. 2017071100 1800 900 604800 86400
+. 86400 IN RRSIG SOA 8 0 86400 20170804000000 20170721000000 50124 . dRkNimO+IbMX99xfiauuzh2Z+fpuvVis EUvJMqJLTvomlofQhQVJbjNvnjNP2FcL MKEumKdDY9sLR7xAPc9h3lmp3NC7L0Q2 kY0uoxitDD5NCZJY82HAn1A4LPvZaFYs 3fIgA1wpz/GipIVDsZ7LXN8fqdpvmxNK l8HgU+t4Gp8X/uDGjFW6TrY+AlN1LYmd rN8dMXuA2iajQob9WyBDQkmDrbRZ7iJ+ a2JCQqJfIaBFEY7gc9JphxS7ehlaLlqK MMlLH3Nugh+gNLToDdeUXYUqBvefP0/U CGw8dhAIgqC3x0wn2fgYxSsJBdmLsRGt Lv+mISIfw6Ay21Kmi65Ytg==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. IN DNSKEY
+SECTION ANSWER
+. 1814400 IN DNSKEY 256 3 8 AwEAAcHrmeeZUfVAS5KzAL2mHyjpdS3y 5Du2ScdXa1nunnaA35ARZR6BbwuQdIik CC1LH8D7d/AlDW7SlkHWeWBK7eMxO0Ps E2u9jlN2yy+9OQwo1kybg4cBDwbgHmu8 ppX7U3S5SpP9XZIJhYRYqNube/zkoDSa uLaeghU13CCuIwdbJrPNOC6Zvn0op3WL ryTVMnMUzgld6WsiTWZDlaMy5IJdhg5R X2wa0UCJjr1M3kguTHftYExgUKbQytx2 +i1mq+vSKqcS9Bxo1vFTWMtFV2FFpV8T Fv4dL1aC1Aq8e9CiAIEfCVVy8Dw+vYpO VDrd+1qkNorMNetwEly9EgkWgB0=
+. 1814400 IN DNSKEY 257 3 8 AwEAAa7l/x0mKre1XGN10bhnsSuo+Lc7 wFv6ksfiDz/kLgbR1TQY37ntCm3akRr/ hp3CE1YUnAGlk9B5lZYEeT0hoD2BkD7E P9DpOxUqKtQeYhe34pO/ygT+dFYSaMy/ 0OStoYLphzbIfElrpg+gvv+CkFKQzO5W rAL1tWu037erXbhSjko7AokpjfEWyT8H o7qGHiW1vWgzWGtWIgXOdydUJYqQNaOY cddJNV23fod6+KrKE245JRv+KabqnLJv 3+D6g7NDh+D5uLiX4vcTsLoB3LiAruQA r+ickjYFsVvfJlJ3m9O0/st9UsXu+v0e 6Esl5DmWWYo63T31sgmSEOjUSBE=
+. 1814400 IN DNSKEY 385 3 8 AwEAAZxJIBnv0pOId/Ukgr0pwVLXjiBR RyV0kc76BssLTIFPWnEWNLv7+3JRvcAm tpHzDvpCoX92taEYVP3pgF3WUNA/LOJR iYIE8taQ0j0TpbdiizFtgFCc+zE5TZ6z /Ru1Eq6VXgdpHzpPtTep0+gB1Qz6HQNT Wd0v2/XQmKWkh3KnJuDSrBjQy50ax9zX 1Sj8Syv+oA0iREf886Bb3e1nBaWrw9RE xovh2F68eE5hxwBcipwNyf7iEN8Um8Tj KCXWeEnTM+Giip0F+JgbapEKr8Dk5YYv nRBLwPZiekL35AbGA9/8PfCwtAIBAj3A CVHhgmlPbLzPGRyawTtIe9D/6uc=
+. 1814400 IN RRSIG DNSKEY 8 0 1814400 20170811000000 20170721000000 5319 . j9HlRZ3AkCZDpje5AQCXS4N21LfKzqFf c871WzN/OgHF2CO6xDQ3fMznWttRprz4 rpFBUDtXWWyCaLtjzNSrv7XFw6ui3Y05 jdAfAqhYkFQ1NeH6MG/tpZyWGDocJhiq 1hwcgJ9E+IZsOleyziYD3/vrFGKel3Ou qMd7n+T+zLzNjBnDymtSu+sUzWn3A6wG rgHbxO650aLvD4uIQYVEKqLJUddEUwOv 1Yy/Td5RDGbxHLc6L0uTyYkIFc9u4zzf bMpd3zJFSgcSsOkwkd9K+GKNPx2LXisH 01VwpermkzR3bVyl2NTglCy1CjB503gS ePdb1YNZAFUfaNzK0j5mUA==
+. 1814400 IN RRSIG DNSKEY 8 0 1814400 20170811000000 20170721000000 24784 . JWuXNkU74/Y8FqZ9EaQr6czGQDGUhcnw PiwIi3JV77zy34KE0jwWj7AXXdOARk9L 2IfKG+ykFDej7ft85L/z4uViWBICcRrN E9RVKuLkNmzvCtQD5rp4rGdtnNP80qD/ 7Iql62/Vl1atftBzO3uUTY+1DL3O8IQD ry1hGmWRt4RLCFOl1VTUFa8TTf3p0QgK aoD+usTf7x5/Tiy228A36exmsEAG+Xfo g2QbYnN8sxe2w2Jce5ete30eA1QGxxGr cF1vN5v8wbrFYBCSmKLKqtJtUhCZyVX8 vcZofvXa7ufaSdfGURoi/hYT3OCFoeiM tOjEYUttSgdjJycDB3P3Ag==
+. 1814400 IN RRSIG DNSKEY 8 0 1814400 20170811000000 20170721000000 50124 . qOnGDMrqd2LZ1+TkpaGopSBXmabYt82D JvhEtUZIVayOGAvAVt0rK5VsE2YffIFy pewgkBVs7aGds4X7SX1x7EEI/ovrgQlR A2fIS7BvknDFsE4mZ2QEmR8C1N2WA1Gu ddot0cjx0kgLL8VS9Kycy+QoTrROFa5Z 3JHiGfzS1lTQuCby29Ne2GKT0edjr9RD 1QuXugwEmZvgbW0+6EcZCeYoEo/o+0MG It9Bf6mJqKG8ni3xLtQORglhn1rWutkh kzhpC6rm0mXcv7VgwXiFj+smHE5+rnDf CSR7ke830+2cSr6Kd5dSOI0ohRLYH+5p H5Oc4A0eFoD0grg5CZ/8vw==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. 518400 IN NS rootns.
+. 518400 IN RRSIG NS 8 0 518400 20170804000000 20170721000000 50124 . qYBWDglfJ252SaOEo6+wHhXd9xo743sq rbF2csOGAvEmd+TAHQ0T+I6acH2AdOmf 088pBeQFkKodIBeBcdq7HPXK9v4A5ld+ OVWYmXxiNdLreOHsn/lw4hybbYu5iiwy hathQKOolfg7sS9evVB+YUGD6GLMTyDt vIkbbB5750khnO27rF1Ud6wWeayDOwUv rhriU7cjCPN4G7yo2FiZYDA0ZhOafTOo TgESBEREPRGZaOVjLIV16g8EGr1rche3 AfMfam0bAfYdkdU2scSCXDfB78MprnCN otAd2ze4VtbjZdxWq4Ji4XfleIQ7ICXQ 2Ao7vchX9IpME5vdNLvAig==
+SECTION ADDITIONAL
+rootns. 518400 IN A 198.41.0.4
+rootns. 518400 IN AAAA 2001:503:ba3e::2:30
+rootns. 518400 IN RRSIG A 8 1 518400 20170804000000 20170721000000 50124 . m2MZgby1HEHD9nRhRvprWdBMQtXBjPQU vpom5LA2iF5CIect6fF1pHG38ckRz7s2 hsWb8QLic3CtAqB8nxkHPiS8rfTdlN7N +3DEXEaurAB4RCZFmpukK9aqwasW1BLI Ul7eYgvihgo6aErN01IP5Thqqrd8b/SS 6RcCtk2Cfdyf7jMwSAR8D1RJxuRqoyOe Gofk2yYMm6wuBStVRtLvJwaAk3rsyWRT jmx4tlKijIYZvjZ2Iusnr6+rptQmNMqd xtNSrREbB94m6WZbsviy4rdvx7rq18LA mq+eB+7ROz2/tSpUkrXL7nFF09+Fkztx Tz2JRKV/Ee7LKpvw7v91Hw==
+rootns. 518400 IN RRSIG AAAA 8 1 518400 20170804000000 20170721000000 50124 . mz2zvQhPZsyQ2YS5GuRVTYwXl5daG9uY 259B2cJbfNRIsiWtpugPnnITtKMABZUY aHP7IaR9j+LsIhNL2z3u/e0H+bmMS0Mb +w3qEhrx6L6h1h4mZAeHN31iUP1kilbH TlBHTJkPeh6xM9+BX/LH7LPozqFl3Nai 4iqv7oG+niQ5rb758bAG8AM5jQ5WyPev ZmkAqhkQiQrkpYRsVtUkNNoTTGrTytUM LVwFUC8KRAmJzavUlHXeucUXWLkzZFYw 07lNug5/8ZdCPlpv1+bdBKa1Bth8f5Bn 269xi1PZX7OV22luv2dnoU1/+xqQ0su2 NRHeLG39gD7JnOE2BC5Tlw==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rootns. IN NS
+SECTION AUTHORITY
+. 86400 IN SOA rootns. you.test. 2017071100 1800 900 604800 86400
+rootns. 86400 IN NSEC test. A AAAA RRSIG NSEC
+. 86400 IN RRSIG SOA 8 0 86400 20170804000000 20170721000000 50124 . dRkNimO+IbMX99xfiauuzh2Z+fpuvVis EUvJMqJLTvomlofQhQVJbjNvnjNP2FcL MKEumKdDY9sLR7xAPc9h3lmp3NC7L0Q2 kY0uoxitDD5NCZJY82HAn1A4LPvZaFYs 3fIgA1wpz/GipIVDsZ7LXN8fqdpvmxNK l8HgU+t4Gp8X/uDGjFW6TrY+AlN1LYmd rN8dMXuA2iajQob9WyBDQkmDrbRZ7iJ+ a2JCQqJfIaBFEY7gc9JphxS7ehlaLlqK MMlLH3Nugh+gNLToDdeUXYUqBvefP0/U CGw8dhAIgqC3x0wn2fgYxSsJBdmLsRGt Lv+mISIfw6Ay21Kmi65Ytg==
+rootns. 86400 IN RRSIG NSEC 8 1 86400 20170804000000 20170721000000 50124 . En0/8voZSHLFgopg9yKSKo+IVbyZVVEC kHPBNEDqen7oRAt7pUqYDYFKNURQ9gii BD68xxSgQltFxzY5u5ml2QA1J/I59AuM gUgm6FznTzD0Td5sA5mMNKs6l1Kn4IvR PIJbsgth/RqkTFtyJ44aHqxFCYAVbv46 PiX0aEMRNx+exvHhCjLwpNDuHJ0msX7m rHWRwOr2kVOv+KXLFsInfutUQah8Ujpc 4urpFJ0qF4QbkioVhl+5jD3UanvY1UqL gD2g0p23GJSIJXyuPAEsJOeq4PrvTcqk b48TWOlsmpKwy+Nd9p/eUdpqr+b0XFw0 mm7JBJnz7fsqMapcvipwVw==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rootns. IN A
+SECTION ANSWER
+rootns. 518400 IN A 198.41.0.4
+rootns. 518400 IN RRSIG A 8 1 518400 20170804000000 20170721000000 50124 . m2MZgby1HEHD9nRhRvprWdBMQtXBjPQU vpom5LA2iF5CIect6fF1pHG38ckRz7s2 hsWb8QLic3CtAqB8nxkHPiS8rfTdlN7N +3DEXEaurAB4RCZFmpukK9aqwasW1BLI Ul7eYgvihgo6aErN01IP5Thqqrd8b/SS 6RcCtk2Cfdyf7jMwSAR8D1RJxuRqoyOe Gofk2yYMm6wuBStVRtLvJwaAk3rsyWRT jmx4tlKijIYZvjZ2Iusnr6+rptQmNMqd xtNSrREbB94m6WZbsviy4rdvx7rq18LA mq+eB+7ROz2/tSpUkrXL7nFF09+Fkztx Tz2JRKV/Ee7LKpvw7v91Hw==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rootns. IN AAAA
+SECTION ANSWER
+rootns. 518400 IN AAAA 2001:503:ba3e::2:30
+rootns. 518400 IN RRSIG AAAA 8 1 518400 20170804000000 20170721000000 50124 . mz2zvQhPZsyQ2YS5GuRVTYwXl5daG9uY 259B2cJbfNRIsiWtpugPnnITtKMABZUY aHP7IaR9j+LsIhNL2z3u/e0H+bmMS0Mb +w3qEhrx6L6h1h4mZAeHN31iUP1kilbH TlBHTJkPeh6xM9+BX/LH7LPozqFl3Nai 4iqv7oG+niQ5rb758bAG8AM5jQ5WyPev ZmkAqhkQiQrkpYRsVtUkNNoTTGrTytUM LVwFUC8KRAmJzavUlHXeucUXWLkzZFYw 07lNug5/8ZdCPlpv1+bdBKa1Bth8f5Bn 269xi1PZX7OV22luv2dnoU1/+xqQ0su2 NRHeLG39gD7JnOE2BC5Tlw==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. 1 IN TXT "check and change answer"
+test. 1 IN RRSIG TXT 8 1 1 20170804000000 20170721000000 50124 . MrLc+GLJYf5OB/rXAtNUzB5vXAvDVIv0 uVzq5QtWij6/GVPja0gsgB0+ZeDusszf RNwFrcJi8wxxBwSAoQWr1wnwvSCODZUG i+8bsVAlP/BysUnajLZdhSUO6LsLhAl/ qCh6wTSbCHa9jp7wODEnRCanXNAl4G2J Q6arffoRd0oWG4vGFvGKzcQSijaIlByI cTxSWyclJRYCyPofPzMq+dKyB0l+kCCr sCy9ke/dXhl8wv6xw7u1UquqwoMp4xjF zNeXdwXdUdZisl9eQIKxFqWpfAKQCRgh 2ZNCHb2Q8ljAxR2Uyj7A06A5pMjTFJlQ sH7FEAlJ2LGNK/nRf8wXGg==
+ENTRY_END
+RANGE_END
+
+
+; 2017-07-01T00:00:00
+STEP 20170701000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170701000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode qname question
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170701000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-07-02T00:00:00
+STEP 20170702000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170702000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode qname question
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170702000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-07-03T00:00:00
+STEP 20170703000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170703000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode qname question
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170703000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-07-04T00:00:00
+STEP 20170704000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170704000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode qname question
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170704000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-07-05T00:00:00
+STEP 20170705000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170705000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode qname question
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170705000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-07-06T00:00:00
+STEP 20170706000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170706000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode qname question
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170706000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-07-07T00:00:00
+STEP 20170707000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170707000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode qname question
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170707000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-07-08T00:00:00
+STEP 20170708000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170708000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode qname question
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170708000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-07-09T00:00:00
+STEP 20170709000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170709000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode qname question
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170709000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-07-10T00:00:00
+STEP 20170710000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170710000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode qname question
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170710000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-07-11T00:00:00
+STEP 20170711000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170711000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode qname question
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170711000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-07-12T00:00:00
+STEP 20170712000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170712000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode qname question
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170712000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-07-13T00:00:00
+STEP 20170713000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170713000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode qname question
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170713000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-07-14T00:00:00
+STEP 20170714000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170714000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode qname question
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170714000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-07-15T00:00:00
+STEP 20170715000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170715000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode qname question
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170715000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-07-16T00:00:00
+STEP 20170716000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170716000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode qname question
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170716000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-07-17T00:00:00
+STEP 20170717000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170717000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode qname question
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170717000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-07-18T00:00:00
+STEP 20170718000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170718000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode qname question
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170718000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-07-19T00:00:00
+STEP 20170719000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170719000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode qname question
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170719000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-07-20T00:00:00
+STEP 20170720000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170720000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD
+MATCH opcode qname question
+SECTION QUESTION
+test. IN TXT
+SECTION ANSWER
+test. IN TXT "it works"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170720000099 TIME_PASSES ELAPSE 86400
+
+
+; 2017-07-21T00:00:00
+STEP 20170721000000 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+test. IN TXT
+ENTRY_END
+
+STEP 20170721000001 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AA NXDOMAIN
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+test. IN TXT
+SECTION AUTHORITY
+test. 10800 IN SOA test. nobody.invalid. 1 3600 1200 604800 10800
+SECTION ADDITIONAL
+explanation.invalid. 10800 IN TXT "check last answer"
+ENTRY_END
+
+; move time by 1 day, 0:00:00
+STEP 20170721000099 TIME_PASSES ELAPSE 86400
+
+
+
+SCENARIO_END
+
diff --git a/modules/view/.packaging/test.config b/modules/view/.packaging/test.config
new file mode 100644
index 0000000..b639fda
--- /dev/null
+++ b/modules/view/.packaging/test.config
@@ -0,0 +1,4 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+modules.load('view')
+assert(view)
+quit()
diff --git a/modules/view/README.rst b/modules/view/README.rst
new file mode 100644
index 0000000..daffd30
--- /dev/null
+++ b/modules/view/README.rst
@@ -0,0 +1,92 @@
+.. SPDX-License-Identifier: GPL-3.0-or-later
+
+.. _mod-view:
+
+Views and ACLs
+==============
+
+The :ref:`policy <mod-policy>` module implements policies for global query matching, e.g. solves "how to react to certain query".
+This module combines it with query source matching, e.g. "who asked the query". This allows you to create personalized blacklists, filters and ACLs.
+
+There are two identification mechanisms:
+
+* ``addr``
+ - identifies the client based on his subnet
+* ``tsig``
+ - identifies the client based on a TSIG key name (only for testing purposes, TSIG signature is not verified!)
+
+View module allows you to combine query source information with :ref:`policy <mod-policy>` rules.
+
+.. code-block:: lua
+
+ view:addr('10.0.0.1', policy.suffix(policy.TC, policy.todnames({'example.com'})))
+
+This example will force given client to TCP for names in ``example.com`` subtree.
+You can combine view selectors with RPZ_ to create personalized filters for example.
+
+.. warning::
+
+ Beware that cache is shared by *all* requests. For example, it is safe
+ to refuse answer based on who asks the resolver, but trying to serve
+ different data to different clients will result in unexpected behavior.
+ Setups like **split-horizon** which depend on isolated DNS caches
+ are explicitly not supported.
+
+
+Example configuration
+---------------------
+
+.. code-block:: lua
+
+ -- Load modules
+ modules = { 'view' }
+ -- Whitelist queries identified by TSIG key
+ view:tsig('\5mykey', policy.all(policy.PASS))
+ -- Block local IPv4 clients (ACL like)
+ view:addr('127.0.0.1', policy.all(policy.DENY))
+ -- Block local IPv6 clients (ACL like)
+ view:addr('::1', policy.all(policy.DENY))
+ -- Drop queries with suffix match for remote client
+ view:addr('10.0.0.0/8', policy.suffix(policy.DROP, policy.todnames({'xxx'})))
+ -- RPZ for subset of clients
+ view:addr('192.168.1.0/24', policy.rpz(policy.PASS, 'whitelist.rpz'))
+ -- Do not try this - it will pollute cache and surprise you!
+ -- view:addr('10.0.0.0/8', policy.all(policy.FORWARD('2001:DB8::1')))
+ -- Drop all IPv4 that hasn't matched
+ view:addr('0.0.0.0/0', policy.all(policy.DROP))
+
+Rule order
+----------
+
+The current implementation is best understood as three separate rule chains:
+vanilla ``policy.add``, ``view:tsig`` and ``view:addr``.
+For each request the rules in these chains get tried one by one until a :ref:`non-chain policy action <mod-policy-actions>` gets executed.
+
+By default :ref:`policy module <mod-policy>` acts before ``view`` module due to ``policy`` being loaded by default. If you want to intermingle universal rules with ``view:addr``, you may simply wrap the universal policy rules in view closure like this:
+
+.. code-block:: lua
+
+ view:addr('0.0.0.0/0', policy.<rule>) -- and
+ view:addr('::0/0', policy.<rule>)
+
+
+Properties
+----------
+
+.. function:: view:addr(subnet, rule)
+
+ :param subnet: client subnet, e.g. ``10.0.0.1``
+ :param rule: added rule, e.g. ``policy.pattern(policy.DENY, '[0-9]+\2cz')``
+
+ Apply rule to clients in given subnet.
+
+.. function:: view:tsig(key, rule)
+
+ :param key: client TSIG key domain name, e.g. ``\5mykey``
+ :param rule: added rule, e.g. ``policy.pattern(policy.DENY, '[0-9]+\2cz')``
+
+ Apply rule to clients with given TSIG key.
+
+ .. warning:: This just selects rule based on the key name, it doesn't verify the key or signature yet.
+
+.. _RPZ: https://dnsrpz.info/
diff --git a/modules/view/addr.test.integr/deckard.yaml b/modules/view/addr.test.integr/deckard.yaml
new file mode 100644
index 0000000..8170ffd
--- /dev/null
+++ b/modules/view/addr.test.integr/deckard.yaml
@@ -0,0 +1,12 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+programs:
+- name: kresd
+ binary: kresd
+ additional:
+ - --noninteractive
+ templates:
+ - modules/view/addr.test.integr/kresd_config.j2
+ - tests/integration/hints_zone.j2
+ configs:
+ - config
+ - hints
diff --git a/modules/view/addr.test.integr/kresd_config.j2 b/modules/view/addr.test.integr/kresd_config.j2
new file mode 100644
index 0000000..3dd8d92
--- /dev/null
+++ b/modules/view/addr.test.integr/kresd_config.j2
@@ -0,0 +1,62 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+{% raw %}
+modules.load('view < policy')
+
+view:addr('127.127.0.0/16', policy.suffix(policy.DENY_MSG("addr 127.127.0.0/16 matched com"),{"\3com\0"}))
+view:addr('127.127.0.0/16', policy.suffix(policy.DENY_MSG("addr 127.127.0.0/16 matched net"),{"\3net\0"}))
+policy.add(policy.all(policy.FORWARD('1.2.3.4')))
+
+-- make sure DNSSEC is turned off for tests
+trust_anchors.remove('.')
+
+-- Disable RFC5011 TA update
+if ta_update then
+ modules.unload('ta_update')
+end
+
+-- Disable RFC8145 signaling, scenario doesn't provide expected answers
+if ta_signal_query then
+ modules.unload('ta_signal_query')
+end
+
+-- Disable RFC8109 priming, scenario doesn't provide expected answers
+if priming then
+ modules.unload('priming')
+end
+
+-- Disable this module because it make one priming query
+if detect_time_skew then
+ modules.unload('detect_time_skew')
+end
+
+_hint_root_file('hints')
+cache.size = 2*MB
+log_level('debug')
+{% endraw %}
+
+net = { '{{SELF_ADDR}}' }
+
+
+{% if QMIN == "false" %}
+option('NO_MINIMIZE', true)
+{% else %}
+option('NO_MINIMIZE', false)
+{% endif %}
+
+
+-- Self-checks on globals
+assert(help() ~= nil)
+assert(worker.id ~= nil)
+-- Self-checks on facilities
+assert(cache.count() == 0)
+assert(cache.stats() ~= nil)
+assert(cache.backends() ~= nil)
+assert(worker.stats() ~= nil)
+assert(net.interfaces() ~= nil)
+-- Self-checks on loaded stuff
+assert(net.list()[1].transport.ip == '{{SELF_ADDR}}')
+assert(#modules.list() > 0)
+-- Self-check timers
+ev = event.recurrent(1 * sec, function (ev) return 1 end)
+event.cancel(ev)
+ev = event.after(0, function (ev) return 1 end)
diff --git a/modules/view/addr.test.integr/module_view_addr.rpl b/modules/view/addr.test.integr/module_view_addr.rpl
new file mode 100644
index 0000000..f9370da
--- /dev/null
+++ b/modules/view/addr.test.integr/module_view_addr.rpl
@@ -0,0 +1,79 @@
+; SPDX-License-Identifier: GPL-3.0-or-later
+; config options
+ stub-addr: 1.2.3.4
+ query-minimization: off
+CONFIG_END
+
+SCENARIO_BEGIN view:addr test
+
+RANGE_BEGIN 0 110
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+example.cz. IN A
+SECTION ANSWER
+example.cz. IN A 5.6.7.8
+ENTRY_END
+
+RANGE_END
+
+; policy module loaded before view module must take precedence before view
+STEP 10 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+example.cz. IN A
+ENTRY_END
+
+STEP 20 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH flags rcode question answer
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+example.cz. IN A
+SECTION ANSWER
+example.cz. IN A 5.6.7.8
+ENTRY_END
+
+; blocked by view:addr + inner policy.suffix com
+; NXDOMAIN expected
+STEP 30 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+example.com. IN A
+ENTRY_END
+
+STEP 31 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH opcode question rcode additional
+REPLY QR RD RA AA NXDOMAIN
+SECTION QUESTION
+example.com. IN A
+SECTION ADDITIONAL
+explanation.invalid. 10800 IN TXT "addr 127.127.0.0/16 matched com"
+ENTRY_END
+
+; blocked by view:addr + inner policy.suffix net
+; second view rule gets executed if policy in preceding view rule did not match
+STEP 32 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+example.net. IN A
+ENTRY_END
+
+STEP 33 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH opcode question rcode additional
+REPLY QR RD RA AA NXDOMAIN
+SECTION QUESTION
+example.net. IN A
+SECTION ADDITIONAL
+explanation.invalid. 10800 IN TXT "addr 127.127.0.0/16 matched net"
+ENTRY_END
+
+SCENARIO_END
diff --git a/modules/view/meson.build b/modules/view/meson.build
new file mode 100644
index 0000000..233448b
--- /dev/null
+++ b/modules/view/meson.build
@@ -0,0 +1,11 @@
+# LUA module: view
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+lua_mod_src += [
+ files('view.lua'),
+]
+
+integr_tests += [
+ ['view.tsig', meson.current_source_dir() / 'tsig.test.integr'],
+ ['view.addr', meson.current_source_dir() / 'addr.test.integr'],
+]
diff --git a/modules/view/tsig.test.integr/deckard.yaml b/modules/view/tsig.test.integr/deckard.yaml
new file mode 100644
index 0000000..06792be
--- /dev/null
+++ b/modules/view/tsig.test.integr/deckard.yaml
@@ -0,0 +1,12 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+programs:
+- name: kresd
+ binary: kresd
+ additional:
+ - --noninteractive
+ templates:
+ - modules/view/tsig.test.integr/kresd_config.j2
+ - tests/integration/hints_zone.j2
+ configs:
+ - config
+ - hints
diff --git a/modules/view/tsig.test.integr/kresd_config.j2 b/modules/view/tsig.test.integr/kresd_config.j2
new file mode 100644
index 0000000..f04dce2
--- /dev/null
+++ b/modules/view/tsig.test.integr/kresd_config.j2
@@ -0,0 +1,64 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+{% raw %}
+modules.load('view')
+print(table_print(modules.list()))
+
+view:tsig('\8testkey1\0', policy.suffix(policy.DENY_MSG("TSIG key testkey1 matched com"),{"\3com\0"}))
+view:tsig('\8testkey1\0', policy.suffix(policy.DENY_MSG("TSIG key testkey1 matched net"),{"\3net\0"}))
+view:tsig('\7testkey\0', policy.suffix(policy.DENY_MSG("TSIG key testkey matched example"),{"\7example\0"}))
+policy.add(policy.all(policy.FORWARD('1.2.3.4')))
+
+-- Disable RFC5011 TA update
+if ta_update then
+ modules.unload('ta_update')
+end
+
+-- Disable RFC8145 signaling, scenario doesn't provide expected answers
+if ta_signal_query then
+ modules.unload('ta_signal_query')
+end
+
+-- Disable RFC8109 priming, scenario doesn't provide expected answers
+if priming then
+ modules.unload('priming')
+end
+
+-- Disable this module because it make one priming query
+if detect_time_skew then
+ modules.unload('detect_time_skew')
+end
+
+-- make sure DNSSEC is turned off for tests
+trust_anchors.remove('.')
+
+_hint_root_file('hints')
+cache.size = 2*MB
+log_level('debug')
+{% endraw %}
+
+net = { '{{SELF_ADDR}}' }
+
+
+{% if QMIN == "false" %}
+option('NO_MINIMIZE', true)
+{% else %}
+option('NO_MINIMIZE', false)
+{% endif %}
+
+
+-- Self-checks on globals
+assert(help() ~= nil)
+assert(worker.id ~= nil)
+-- Self-checks on facilities
+assert(cache.count() == 0)
+assert(cache.stats() ~= nil)
+assert(cache.backends() ~= nil)
+assert(worker.stats() ~= nil)
+assert(net.interfaces() ~= nil)
+-- Self-checks on loaded stuff
+assert(net.list()[1].transport.ip == '{{SELF_ADDR}}')
+assert(#modules.list() > 0)
+-- Self-check timers
+ev = event.recurrent(1 * sec, function (ev) return 1 end)
+event.cancel(ev)
+ev = event.after(0, function (ev) return 1 end)
diff --git a/modules/view/tsig.test.integr/module_view_tsig.rpl b/modules/view/tsig.test.integr/module_view_tsig.rpl
new file mode 100644
index 0000000..fd6d291
--- /dev/null
+++ b/modules/view/tsig.test.integr/module_view_tsig.rpl
@@ -0,0 +1,114 @@
+; SPDX-License-Identifier: GPL-3.0-or-later
+; config options
+ stub-addr: 1.2.3.4
+CONFIG_END
+
+SCENARIO_BEGIN view:tsig test
+
+RANGE_BEGIN 0 110
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+example.cz. IN A
+SECTION ANSWER
+example.cz. IN A 5.6.7.8
+ENTRY_END
+
+RANGE_END
+
+RANGE_BEGIN 0 110
+ ADDRESS 192.0.2.1
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+example.net. IN A
+SECTION ANSWER
+example.net. IN A 6.6.6.6
+ENTRY_END
+RANGE_END
+
+; policy fallback (no view matched, policy is behind view module)
+STEP 10 QUERY
+ENTRY_BEGIN
+REPLY RD
+TSIG testkey +Cdjlkef9ZTSeixERZ433Q==
+SECTION QUESTION
+example.cz. IN A
+ENTRY_END
+
+STEP 20 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH flags rcode question answer
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+example.cz. IN A
+SECTION ANSWER
+example.cz. IN A 5.6.7.8
+ENTRY_END
+
+; blocked by view:tsig testkey1 + inner policy.suffix com
+; NXDOMAIN expected
+STEP 30 QUERY
+ENTRY_BEGIN
+REPLY RD
+TSIG testkey1 +Cdjlkef9ZTSeixERZ433Q==
+SECTION QUESTION
+example.com. IN A
+ENTRY_END
+
+STEP 31 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH opcode question rcode additional
+REPLY QR RD RA AA NXDOMAIN
+SECTION QUESTION
+example.com. IN A
+SECTION ADDITIONAL
+explanation.invalid. 10800 IN TXT "TSIG key testkey1 matched com"
+ENTRY_END
+
+; blocked by view:tsig testkey1 + inner policy.suffix net
+; second view rule gets executed if policy in preceding view rule did not match
+STEP 32 QUERY
+ENTRY_BEGIN
+REPLY RD
+TSIG testkey1 +Cdjlkef9ZTSeixERZ433Q==
+SECTION QUESTION
+example.net. IN A
+ENTRY_END
+
+STEP 33 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH opcode question rcode additional
+REPLY QR RD RA AA NXDOMAIN
+SECTION QUESTION
+example.net. IN A
+SECTION ADDITIONAL
+explanation.invalid. 10800 IN TXT "TSIG key testkey1 matched net"
+ENTRY_END
+
+; blocked by view:tsig testkey + inner policy.suffix example (different key)
+; third view rule gets executed if policy in preceding view rule did not match
+STEP 34 QUERY
+ENTRY_BEGIN
+REPLY RD
+TSIG testkey +Cdjlkef9ZTSeixERZ433Q==
+SECTION QUESTION
+example. IN A
+ENTRY_END
+
+STEP 35 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH opcode question rcode additional
+REPLY QR RD RA AA NXDOMAIN
+SECTION QUESTION
+example. IN A
+SECTION ADDITIONAL
+explanation.invalid. 10800 IN TXT "TSIG key testkey matched example"
+ENTRY_END
+
+SCENARIO_END
diff --git a/modules/view/view.lua b/modules/view/view.lua
new file mode 100644
index 0000000..f5e1862
--- /dev/null
+++ b/modules/view/view.lua
@@ -0,0 +1,121 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+local kres = require('kres')
+local ffi = require('ffi')
+local C = ffi.C
+
+-- Module declaration
+local view = {
+ key = {}, -- map from :owner() to list of policy rules
+ src = {},
+ dst = {},
+}
+
+-- @function View based on TSIG key name.
+function view.tsig(_, tsig, rule)
+ if view.key[tsig] == nil then
+ view.key[tsig] = { rule }
+ else
+ table.insert(view.key[tsig], rule)
+ end
+end
+
+-- @function View based on source IP subnet.
+function view.addr(_, subnet, rules, dst)
+ local subnet_cd = ffi.new('char[16]')
+ local family = C.kr_straddr_family(subnet)
+ local bitlen = C.kr_straddr_subnet(subnet_cd, subnet)
+ if bitlen < 0 then
+ error(string.format('failed to parse subnet %s', subnet))
+ end
+ local t = {family, subnet_cd, bitlen, rules}
+ table.insert(dst and view.dst or view.src, t)
+ return t
+end
+
+-- @function Match IP against given subnet
+local function match_subnet(family, subnet, bitlen, addr)
+ return (family == addr:family()) and (C.kr_bitcmp(subnet, addr:ip(), bitlen) == 0)
+end
+
+-- @function Execute a policy callback (may be nil);
+-- return boolean: whether to continue trying further rules.
+local function execute(state, req, match_cb)
+ if match_cb == nil then return false end
+ local action = match_cb(req, req:current())
+ if action == nil then return false end
+ local next_state = action(state, req)
+ if next_state then -- Not a chain rule,
+ req.state = next_state
+ return true
+ else
+ return false
+ end
+end
+
+-- @function Try all the rules in order, until a non-chain rule gets executed.
+local function evaluate(state, req)
+ -- Try :tsig rules first.
+ local client_key = req.qsource.packet.tsig_rr
+ local match_cbs = (client_key ~= nil) and view.key[client_key:owner()] or {}
+ for _, match_cb in ipairs(match_cbs) do
+ if execute(state, req, match_cb) then return end
+ end
+ -- Then try :addr by the source.
+ if req.qsource.addr ~= nil then
+ for i = 1, #view.src do
+ local pair = view.src[i]
+ if match_subnet(pair[1], pair[2], pair[3], req.qsource.addr) then
+ local match_cb = pair[4]
+ if execute(state, req, match_cb) then return end
+ end
+ end
+ -- Finally try :addr by the destination.
+ elseif req.qsource.dst_addr ~= nil then
+ for i = 1, #view.dst do
+ local pair = view.dst[i]
+ if match_subnet(pair[1], pair[2], pair[3], req.qsource.dst_addr) then
+ local match_cb = pair[4]
+ if execute(state, req, match_cb) then return end
+ end
+ end
+ end
+end
+
+-- @function Return policy based on source address
+function view.rule_src(action, subnet)
+ local subnet_cd = ffi.new('char[16]')
+ local family = C.kr_straddr_family(subnet)
+ local bitlen = C.kr_straddr_subnet(subnet_cd, subnet)
+ return function(req, _)
+ local addr = req.qsource.addr
+ if addr ~= nil and match_subnet(family, subnet_cd, bitlen, addr) then
+ return action
+ end
+ end
+end
+
+-- @function Return policy based on destination address
+function view.rule_dst(action, subnet)
+ local subnet_cd = ffi.new('char[16]')
+ local family = C.kr_straddr_family(subnet)
+ local bitlen = C.kr_straddr_subnet(subnet_cd, subnet)
+ return function(req, _)
+ local addr = req.qsource.dst_addr
+ if addr ~= nil and match_subnet(family, subnet_cd, bitlen, addr) then
+ return action
+ end
+ end
+end
+
+-- @function Module layers
+view.layer = {
+ begin = function(state, req)
+ -- Don't act on "finished" cases.
+ if bit.band(state, bit.bor(kres.FAIL, kres.DONE)) ~= 0 then return state end
+
+ evaluate(state, req)
+ return req.state
+ end
+}
+
+return view
diff --git a/modules/watchdog/.packaging/test.config b/modules/watchdog/.packaging/test.config
new file mode 100644
index 0000000..9d1a291
--- /dev/null
+++ b/modules/watchdog/.packaging/test.config
@@ -0,0 +1,4 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+modules.load('watchdog')
+assert(watchdog)
+quit()
diff --git a/modules/watchdog/README.rst b/modules/watchdog/README.rst
new file mode 100644
index 0000000..514f6c0
--- /dev/null
+++ b/modules/watchdog/README.rst
@@ -0,0 +1,43 @@
+.. SPDX-License-Identifier: GPL-3.0-or-later
+
+.. _mod-watchdog:
+
+Watchdog
+========
+
+This module cooperates with Systemd watchdog to restart the process in case
+the internal event loop gets stuck. The upstream Systemd unit files are configured
+to use this feature, which is turned on with the ``WatchdogSec=`` directive
+in the service file.
+
+As an optional feature, this module can also do an internal DNS query to check if resolver
+answers correctly. To use this feature you must configure DNS name and type to query for:
+
+.. code-block:: lua
+
+ watchdog.config({ qname = 'nic.cz.', qtype = kres.type.A })
+
+Each single query from watchdog must result in answer with
+RCODE = NOERROR or NXDOMAIN. Any other result will terminate the resolver
+(with SIGABRT) to allow the supervisor process to do cleanup, gather coredump
+and restart the resolver.
+
+It is recommended to use a name with a very short TTL to make sure the watchdog
+is testing all parts of resolver and not only its cache. Obviously this check
+makes sense only when used with very reliable domains; otherwise a failure
+on authoritative side will shutdown resolver!
+
+`WatchdogSec` specifies deadline for supervisor when the process will be killed.
+Watchdog queries are executed each `WatchdogSec / 2` seconds.
+This implies that **half** of `WatchdogSec` interval must be long enough for
+normal DNS query to succeed, so do not forget to add two or three seconds
+for random network timeouts etc.
+
+The module is loaded by default. If you'd like to disable it you can unload it:
+
+.. code-block:: lua
+
+ modules.unload('watchdog')
+
+Beware that unloading the module without disabling watchdog feature in supervisor
+will lead to infinite restart loop.
diff --git a/modules/watchdog/watchdog.lua b/modules/watchdog/watchdog.lua
new file mode 100644
index 0000000..6d50be2
--- /dev/null
+++ b/modules/watchdog/watchdog.lua
@@ -0,0 +1,129 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+local ffi = require('ffi')
+
+ffi.cdef([[
+ int sd_watchdog_enabled(int unset_environment, uint64_t *usec);
+ int sd_notify(int unset_environment, const char *state);
+ void abort(void);
+]])
+
+local watchdog = {}
+local private = {}
+
+local function sd_signal_ok()
+ ffi.C.sd_notify(0, 'WATCHDOG=1')
+end
+
+function private.fail_callback()
+ log_error(ffi.C.LOG_GRP_WATCHDOG, 'ABORTING resolver, supervisor is expected to restart it')
+ ffi.C.abort()
+end
+
+-- logging
+local function add_tracer(logbuf)
+ return function (req)
+ local function qrylogger(_, msg)
+ jit.off(true, true) -- JIT for (C -> lua)^2 nesting isn't allowed
+ table.insert(logbuf, ffi.string(msg))
+ end
+ req.trace_log = ffi.cast('trace_log_f', qrylogger)
+ end
+end
+
+local function check_answer(logbuf)
+ return function (pkt, req)
+ req.trace_log:free()
+ if pkt ~= nil and (pkt:rcode() == kres.rcode.NOERROR
+ or pkt:rcode() == kres.rcode.NXDOMAIN) then
+ private.ok_callback()
+ return
+ end
+ log_info(ffi.C.LOG_GRP_WATCHDOG, 'watchdog query returned unexpected answer! query log:')
+ log_info(ffi.C.LOG_GRP_WATCHDOG, table.concat(logbuf, ''))
+ if pkt ~= nil then
+ log_info(ffi.C.LOG_GRP_WATCHDOG, 'problematic answer:\n%s', pkt)
+ else
+ log_info(ffi.C.LOG_GRP_WATCHDOG, 'answer was dropped')
+ end
+ -- failure! quit immediately to allow process supervisor to restart us
+ private.fail_callback()
+ end
+end
+private.check_answer_callback = check_answer
+
+local function timer()
+ local logbuf = {}
+ -- fire watchdog query
+ if private.qname and private.qtype then
+ log_info(ffi.C.LOG_GRP_WATCHDOG, 'starting watchdog query %s %s', private.qname, private.qtype)
+ resolve(private.qname,
+ private.qtype,
+ kres.class.IN,
+ {'TRACE'},
+ private.check_answer_callback(logbuf),
+ add_tracer(logbuf))
+ else
+ private.ok_callback()
+ end
+end
+
+function watchdog.config(cfg)
+ -- read only
+ if not cfg then
+ return private
+ end
+
+ local interval = tonumber(cfg.interval or private.interval or 10000)
+ if not interval or interval < 1 then
+ error('[watchdog] interval must be >= 1 ms')
+ end
+ private.interval = interval
+
+ -- qname = nil will disable DNS queries
+ private.qname = cfg.qname
+ private.qtype = cfg.qtype or kres.type.A
+
+ -- restart timers
+ watchdog.deinit()
+ private.event = event.recurrent(private.interval, timer)
+ return private
+end
+
+-- automatically enable watchdog if it is configured in systemd
+function watchdog.init()
+ if private.event then
+ error('[watchdog] module is already loaded')
+ end
+ local timeoutptr = ffi.new('uint64_t[1]')
+ local systemd_present, ret = pcall(function() return ffi.C.sd_watchdog_enabled(0, timeoutptr) end)
+ if not systemd_present then
+ log_info(ffi.C.LOG_GRP_WATCHDOG, 'systemd library not detected')
+ return
+ end
+ private.ok_callback = sd_signal_ok
+ if ret < 0 then
+ error('[watchdog] %s', ffi.string(ffi.C.knot_strerror(math.abs(ret))))
+ return
+ elseif ret == 0 then
+ log_info(ffi.C.LOG_GRP_WATCHDOG, 'disabled in systemd (WatchdogSec= not specified)')
+ return
+ end
+ local timeout = tonumber(timeoutptr[0]) / 1000 -- convert to ms
+ local interval = timeout / 2 -- halve interval to make sure we are never late
+ if interval < 1 then
+ log_error(ffi.C.LOG_GRP_WATCHDOG, 'error: WatchdogSec= must be at least 2ms! (got %d usec)',
+ tonumber(timeoutptr[0]))
+ end
+ watchdog.config({ interval = interval })
+ log_info(ffi.C.LOG_GRP_WATCHDOG, 'systemd watchdog enabled (check interval: %s ms, timeout: %s ms)',
+ private.interval, timeout)
+end
+
+function watchdog.deinit()
+ if private.event then
+ event.cancel(private.event)
+ private.event = nil
+ end
+end
+
+return watchdog
diff --git a/modules/workarounds/.packaging/test.config b/modules/workarounds/.packaging/test.config
new file mode 100644
index 0000000..c420810
--- /dev/null
+++ b/modules/workarounds/.packaging/test.config
@@ -0,0 +1,4 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+modules.load('workarounds')
+assert(workarounds)
+quit()
diff --git a/modules/workarounds/README.rst b/modules/workarounds/README.rst
new file mode 100644
index 0000000..fcb04aa
--- /dev/null
+++ b/modules/workarounds/README.rst
@@ -0,0 +1,11 @@
+.. SPDX-License-Identifier: GPL-3.0-or-later
+
+.. _mod-workarounds:
+
+Module `workarounds` resolver behavior on specific broken sub-domains.
+Currently it mainly disables case randomization.
+
+.. code-block:: lua
+
+ modules.load('workarounds < iterate')
+
diff --git a/modules/workarounds/workarounds.lua b/modules/workarounds/workarounds.lua
new file mode 100644
index 0000000..4ce7c47
--- /dev/null
+++ b/modules/workarounds/workarounds.lua
@@ -0,0 +1,23 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+-- Load dependent module
+if not policy then modules.load('policy') end
+
+local M = {} -- the module
+
+function M.config()
+ policy.add(policy.suffix(policy.FLAGS('NO_0X20'), {
+ -- https://github.com/DNS-OARC/dns-violations/blob/master/2017/DVE-2017-0003.md
+ todname('avqs.mcafee.com'), todname('avts.mcafee.com'),
+
+ -- https://github.com/DNS-OARC/dns-violations/blob/master/2017/DVE-2017-0006.md
+ -- Obtained via a reverse search on {ns1,ns3}.panthercdn.com.
+ todname('cdnga.com'), todname('cdngc.com'), todname('cdngd.com'),
+ todname('cdngl.com'), todname('cdngm.com'),
+ todname('cdngc.net'), todname('panthercdn.com'),
+
+ todname('magazine-fashion.net.'),
+ }))
+end
+
+return M
+
diff --git a/scripts/bench.sh b/scripts/bench.sh
new file mode 100755
index 0000000..232c523
--- /dev/null
+++ b/scripts/bench.sh
@@ -0,0 +1,12 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-3.0-or-later
+set -o errexit -o nounset
+
+# Run benchmark
+cd "${MESON_SOURCE_ROOT}"
+
+echo "Test LRU with increasing overfill, misses should increase ~ linearly"
+
+for num in 65536 32768 16384 8192 4096; do
+ "${MESON_BUILD_ROOT}/${MESON_SUBDIR}/bench_lru" 23 "${MESON_SOURCE_ROOT}/${MESON_SUBDIR}/bench_lru_set1.tsv" - "${num}"
+done
diff --git a/scripts/bugreport-journals.py b/scripts/bugreport-journals.py
new file mode 100755
index 0000000..d66ddfb
--- /dev/null
+++ b/scripts/bugreport-journals.py
@@ -0,0 +1,194 @@
+#!/usr/bin/python3
+"""
+Collect systemd-journal log entries around time of daemon exit and coredumps.
+"""
+
+import datetime
+import json
+import logging
+import pathlib
+import shutil
+import subprocess
+import sys
+
+
+TIMESPAN_BEFORE = 600 # s
+TIMESPAN_AFTER = TIMESPAN_BEFORE
+CURSOR_DIR = pathlib.Path('/var/lib/knot-resolver')
+CURSOR_PATH = CURSOR_DIR / 'coredump_watcher.cursor'
+
+
+class Timestamp:
+ def __init__(self, usec):
+ self.usec = int(usec)
+
+ @property
+ def unix(self):
+ return self.usec // 10**6
+
+ def __str__(self):
+ return datetime.datetime.utcfromtimestamp(self.unix).strftime('%Y-%m-%d_%H:%M:%S')
+
+ def __lt__(self, other):
+ return self.usec < other.usec
+
+ def __eq__(self, other):
+ return self.usec == other.usec
+
+
+class Entry(dict):
+ @property
+ def timestamp(self):
+ usec = self.get('__REALTIME_TIMESTAMP')
+ if usec is None:
+ return None
+ return Timestamp(usec)
+
+ @property
+ def core_path(self):
+ filename = self.get('COREDUMP_FILENAME')
+ if filename is None:
+ return None
+ return pathlib.Path(filename)
+
+ def get_first(self, *keys):
+ for key in keys:
+ try:
+ return self[key]
+ except KeyError:
+ continue
+ return None
+
+ @property
+ def program(self):
+ return self.get_first('COREDUMP_UNIT', 'UNIT', '_SYSTEMD_UNIT', 'SYSLOG_IDENTIFIER')
+
+ @property
+ def pid(self):
+ return self.get_first('COREDUMP_PID', '_PID')
+
+
+def save_cursor(cursor):
+ if cursor is None:
+ return
+ CURSOR_DIR.mkdir(parents=True, exist_ok=True)
+ with CURSOR_PATH.open('w') as curfile:
+ curfile.write(cursor)
+ logging.info('log cursor saved into %s, next run will skip old logs',
+ CURSOR_PATH)
+
+
+def load_cursor():
+ try:
+ with CURSOR_PATH.open('r') as curfile:
+ logging.info('log cursor read from %s, skipping old logs',
+ CURSOR_PATH)
+ return curfile.read().strip()
+ except FileNotFoundError:
+ logging.info('log cursor file %s does not exist, parsing all logs',
+ CURSOR_PATH)
+ return None
+
+
+def get_cursor():
+ journal_args = ['journalctl', '-o', 'json', '-n', '1']
+ with subprocess.Popen(
+ journal_args,
+ bufsize=1, # line buffering
+ universal_newlines=True,
+ stdout=subprocess.PIPE) as jproc:
+ stdout, _ = jproc.communicate()
+ data = json.loads(stdout)
+ entry = Entry(**data)
+ return entry.get('__CURSOR')
+
+
+def read_journal(*args):
+ journal_args = [
+ 'journalctl',
+ '-o', 'json',
+ '-u', 'kres*',
+ '-u', 'systemd-coredump*']
+ journal_args += args
+ with subprocess.Popen(
+ journal_args,
+ bufsize=1, # line buffering
+ universal_newlines=True,
+ stdout=subprocess.PIPE) as jproc:
+ for line in jproc.stdout:
+ data = json.loads(line)
+ yield Entry(**data)
+
+
+def extract_logs(around_time, log_name):
+ start_time = Timestamp(around_time.usec - TIMESPAN_BEFORE * 10**6)
+ end_time = Timestamp(around_time.usec + TIMESPAN_AFTER * 10**6)
+ log_window = list(read_journal(
+ '--since', '@{}'.format(start_time.unix),
+ '--until', '@{}'.format(end_time.unix)))
+ with log_name.with_suffix('.json').open('w') as jsonf:
+ json.dump(log_window, jsonf, indent=4)
+ with log_name.with_suffix('.log').open('w') as logf:
+ logf.write('##### logs since {}\n'.format(start_time))
+ for entry in log_window:
+ if entry.timestamp == around_time:
+ logf.write('##### HERE #####\n')
+ logf.write('{t} {h} {prg}[{pid}]: {m}\n'.format(
+ t=entry.timestamp,
+ h=entry.get('_HOSTNAME'),
+ prg=entry.program,
+ pid=entry.pid,
+ m=entry.get('MESSAGE')))
+ logf.write('##### logs until {}\n'.format(end_time))
+
+
+def main():
+ logging.basicConfig(level=logging.INFO)
+
+ if len(sys.argv) != 2:
+ sys.exit('Usage: {} <output log directory>'.format(sys.argv[0]))
+ outdir = pathlib.Path(sys.argv[1])
+ outdir.mkdir(parents=True, exist_ok=True)
+
+ cursor_previous = load_cursor()
+ cursor_at_start = get_cursor()
+
+ exit_times = []
+ coredumps = {}
+ filter_args = []
+ if cursor_previous is not None:
+ filter_args = ['--after-cursor', cursor_previous]
+ for entry in read_journal(*filter_args):
+ if 'EXIT_CODE' in entry:
+ logging.debug('exit@%s: %s', entry.timestamp, entry)
+ exit_times.append(entry.timestamp)
+ if 'COREDUMP_FILENAME' in entry:
+ logging.debug('coredump @ %s: %s', entry.timestamp, entry.core_path)
+ coredumps[entry.core_path] = entry.timestamp
+
+ exit_times.sort()
+ logging.debug('detected exits: %s', exit_times)
+ for exit_time in exit_times:
+ extract_logs(exit_time, outdir / str(exit_time))
+
+ coredumps_missing = 0
+ logging.debug('detected coredumps: %s', coredumps)
+ for core_path, core_time in coredumps.items():
+ core_name = core_path.name
+ out_path_prefix = (outdir / str(core_time))
+ extract_logs(core_time, out_path_prefix.with_suffix('.logs'))
+ try:
+ shutil.copy(
+ str(core_path),
+ str(out_path_prefix.with_suffix('.{}'.format(core_name))))
+ except FileNotFoundError as ex:
+ logging.error('coredump file %s cannot be copied: %s', core_path, ex)
+ coredumps_missing += 1
+ logging.info('wrote %d coredumps and %d logs snippets (%s coredumps missing)',
+ len(coredumps) - coredumps_missing, len(exit_times), coredumps_missing)
+
+ save_cursor(cursor_at_start)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/scripts/build-in-obs.sh b/scripts/build-in-obs.sh
new file mode 100755
index 0000000..3256dde
--- /dev/null
+++ b/scripts/build-in-obs.sh
@@ -0,0 +1,32 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# Push packaging files to OBS
+#
+# Example usage:
+# 1. ./scripts/make-obs.sh
+# 2. ./scripts/build-in-obs.sh knot-resolver-latest
+set -o errexit -o nounset -o xtrace
+
+pkgdir='pkg/obs'
+
+project=home:CZ-NIC:$1
+package=knot-resolver
+
+if ! [[ "$1" == *-devel || "$1" == *-testing ]]; then
+ read -p "Pushing to '$project', are you sure? [y/N]: " yn
+ case $yn in
+ [Yy]* )
+ ;;
+ * )
+ exit 1
+ esac
+fi
+
+osc co "${project}" "${package}"
+pushd "${project}/${package}"
+osc del * ||:
+cp -r ../../${pkgdir}/* ./
+osc addremove
+osc ci -n
+popd
diff --git a/scripts/coverage_c_combine.sh b/scripts/coverage_c_combine.sh
new file mode 100755
index 0000000..a891ded
--- /dev/null
+++ b/scripts/coverage_c_combine.sh
@@ -0,0 +1,26 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# $1 = top source directory
+# $2 = coverage data directory path
+# $3 = output directory for *.info files
+
+set -o errexit -o nounset
+shopt -s nullglob
+IFS=$'\n'
+
+TOPSRCDIR="$1"
+DATAROOT="$2"
+OUTDIR="$3"
+
+cd "${TOPSRCDIR}"
+for COVNAME in $(find "${DATAROOT}" -name .topdir_kresd_coverage)
+do
+ find "${DATAROOT}" -name '*.gcda' -not -path "${DATAROOT}/*" -delete
+ COVDIR="$(dirname "${COVNAME}")"
+ COVDATA_FILENAMES=("${COVDIR}"/*) # filenames in BASH array
+ (( ${#COVDATA_FILENAMES[*]} )) || continue # skip empty dirs
+
+ cp -r -t ${TOPSRCDIR} "${COVDIR}"/*
+ ${LCOV} -q --no-external --capture -d lib -d daemon -d modules -o "$(mktemp -p "${OUTDIR}" -t XXXXXXXX.c.info)" > /dev/null
+done
diff --git a/scripts/coverage_env.sh b/scripts/coverage_env.sh
new file mode 100755
index 0000000..0f6810f
--- /dev/null
+++ b/scripts/coverage_env.sh
@@ -0,0 +1,42 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# generate variables for coverage testing
+# $1 = top source directory
+# $2 = coverage data directory path
+# $3 = name of test/new subdirectory name
+# $4 = [optional] --export to generate export commands
+
+set -o errexit -o nounset
+shopt -s nullglob
+
+test -z "${COVERAGE:-}" && exit 0 # not enabled, do nothing
+test ! -z "${V:-}" && set -o xtrace # verbose mode
+
+EXPORT=""
+test "${4:-}" == "--export" && EXPORT="export "
+TOPSRCDIR="$1"
+DATAROOT="$2"
+OUTPATH="$2/$3"
+
+# check that output directory is empty
+# beware: Makefile will always call coverage_env.sh for all targets
+# so directories get created but not populated
+# i.e. test -d is not sufficient check
+OUTPATH_FILENAMES=("${OUTPATH}"/*) # filenames in BASH array
+(( ${#OUTPATH_FILENAMES[*]} )) && echo "false" && >&2 echo "fatal: output directory ${OUTPATH} must be empty (or non-existent)" && exit 1
+
+mkdir -p "${OUTPATH}"
+# convert paths to absolute
+pushd "${OUTPATH}" &> /dev/null
+touch .topdir_kresd_coverage
+OUTPATH="$(pwd -P)"
+popd &> /dev/null
+
+# determine GCOV_PREFIX_STRIP value for current source directory
+TOPSRCDIR_SLASHES="${TOPSRCDIR//[^\/]/}" # remove everything except /
+GCOV_PREFIX_STRIP="${#TOPSRCDIR_SLASHES}" # number of / == number of components
+
+KRESD_COVERAGE_STATS="${OUTPATH}/luacov.stats.out"
+GCOV_PREFIX="${OUTPATH}"
+echo "${EXPORT}KRESD_COVERAGE_STATS=\"${KRESD_COVERAGE_STATS}\" ${EXPORT}GCOV_PREFIX=\"${GCOV_PREFIX}\" ${EXPORT}GCOV_PREFIX_STRIP=\"${GCOV_PREFIX_STRIP}\""
diff --git a/scripts/doh_b64encode_query.py b/scripts/doh_b64encode_query.py
new file mode 100755
index 0000000..59569b8
--- /dev/null
+++ b/scripts/doh_b64encode_query.py
@@ -0,0 +1,26 @@
+#!/usr/bin/env python3
+import argparse
+import base64
+
+import dns
+import dns.message
+
+
+def main():
+ parser = argparse.ArgumentParser(
+ description='Convert query name and type to base64 URL-encoded form')
+ parser.add_argument('qname', type=str, help='query name')
+ parser.add_argument('qtype', type=str, help='query type')
+ args = parser.parse_args()
+
+ msg = dns.message.make_query(args.qname, args.qtype, dns.rdataclass.IN)
+ msg.id = 0
+ wire = msg.to_wire()
+ encoded = base64.urlsafe_b64encode(wire)
+ printable = encoded.decode('utf-8')
+
+ print(printable)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/scripts/gen-cdefs.sh b/scripts/gen-cdefs.sh
new file mode 100755
index 0000000..ddb0aa7
--- /dev/null
+++ b/scripts/gen-cdefs.sh
@@ -0,0 +1,82 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-3.0-or-later
+set -o pipefail -o errexit
+
+if [ "$2" != types ] && [ "$2" != functions ]; then
+ echo "Usage: $0 libkres (types|functions)" >&2
+ echo " and input identifiers, one per line." >&2
+ echo " You need debug symbols in the library." >&2
+ echo
+ echo " If you call this on a type that's a typedef, it gets expanded." >&2
+ echo " To avoid that, prefix the identifier with 'typedef '." >&2
+ exit 1
+fi
+
+if ! command -v gdb >/dev/null; then
+ echo "Failed to find gdb" >&2
+ exit 1
+fi
+
+if ! command -v sed >/dev/null; then
+ echo "Failed to find GNU sed" >&2
+ exit 1
+fi
+
+if ! sed --version | head -1 | grep -q "GNU sed"; then
+ echo "GNU sed required to run this script" >&2
+fi
+
+# be very precise with the directories for libraries to not pick wrong library
+case "$1" in
+ libknot) library="$(PATH="$(pkg-config libknot --variable=libdir)" command -v "$1.so")" ;;
+ libzscanner) library="$(PATH="$(pkg-config libzscanner --variable=libdir)" command -v "$1.so")" ;;
+ *) library="$(command -v "$1")" # use absolute path to library
+esac
+
+if [ -z "$library" ]; then
+ echo "$1 not found. Note: only .so platforms work currently." >&2
+ exit 1
+fi
+
+# Let's use an array to hold command-line arguments, to simplify quoting.
+GDB=(gdb)
+GDB+=(-n -quiet -batch "-symbols=$library")
+GDB+=(-iex "set width unlimited" -iex "set max-value-size unlimited")
+
+grep -v '^#\|^$' | while read -r ident; do
+ if [ "$2" = functions ]; then
+ output="$("${GDB[@]}" --ex "info functions ^$ident\$" \
+ | sed '0,/^All functions/ d; /^File .*:$/ d')"
+ else # types
+ case "$ident" in
+ struct\ *|union\ *|enum\ *)
+ output="$("${GDB[@]}" --ex "ptype $ident" \
+ | sed '0,/^type = /s/^type = /\n/; $ s/$/;/')"
+ ;;
+ typedef\ *) # typedef that shouldn't be expanded
+ output="$("${GDB[@]}" --ex "info types ^"$(echo "$ident" | sed 's/^typedef //')"\$" \
+ | sed -e '0,/^File .*:$/ d' -e '/^File .*:$/,$ d')"
+ # we need to stop early to remove ^^ multiple matches
+ ;;
+ *) # we assume it's a typedef that should be expanded
+ output="$("${GDB[@]}" --ex "ptype $ident" \
+ | sed "0,/^type = /s/^type = /typedef /; $ s/$/ $ident;/")"
+ ;;
+ esac
+ fi
+ # LuaJIT FFI blows up on "uint" type
+ output="$(echo "$output" | sed 's/\buint\b/unsigned int/g')"
+ # GDB 8.2+ added source line prefix to output
+ output="$(echo "$output" | sed 's/^[0-9]\+:[[:space:]]*//g')"
+ # use tabs instead of spaces
+ output="$(echo "$output" | sed 's/ /\t/g')"
+
+ # abort on empty output
+ if [ -z "$(echo "$output" | tr -d "\n;")" ]; then
+ echo "Failed to find cdef of $ident" >&2
+ exit 1
+ fi
+ echo "$output" | grep -v '^$'
+done
+
+exit 0
diff --git a/scripts/gen-pgp-keyblock.sh b/scripts/gen-pgp-keyblock.sh
new file mode 100755
index 0000000..2985531
--- /dev/null
+++ b/scripts/gen-pgp-keyblock.sh
@@ -0,0 +1,38 @@
+#!/bin/bash
+# Script to create/update Knot Resolver PGP keyring
+set -o errexit -o nounset
+
+keys=(
+ 'B6006460B60A80E782062449E747DF1F9575A3AA' # vladimir.cunat@nic.cz
+ '3057EE9A448F362D74205A779AB120DA0A76F6DE' # ales.mrazek@nic.cz
+ # '4A8BA48C2AED933BD495C509A1FBA5F7EF8C4869' # tomas.krizek@nic.cz expired 2022-03-31
+)
+outfile="kresd-keyblock.asc"
+url="https://secure.nic.cz/files/knot-resolver/kresd-keyblock.asc"
+
+keyring="$(mktemp -d)"
+keyring_import="$(mktemp -d)"
+published="$(mktemp)"
+
+cleanup() {
+ rm -rf "${keyring}"
+ rm -rf "${keyring_import}"
+ rm -rf "${published}"
+}
+trap cleanup EXIT
+
+# obtain keys from keys.openpgp.org
+gpg --homedir "${keyring}" -q --keyserver keys.openpgp.org --recv-keys "${keys[@]}"
+
+# export minimal size keys with just the necessary signatures
+rm -f "${outfile}"
+gpg --homedir "${keyring}" -q --export --export-options export-minimal --armor --output "${outfile}" "${keys[@]}"
+
+# display keys after import
+gpg --homedir "${keyring_import}" -q --import "${outfile}"
+gpg --homedir "${keyring_import}" -k
+echo "Created: ${outfile}"
+
+# check if update of secure.nic.cz keyblock might be needed
+curl -sfo "${published}" "${url}"
+diff -q "${outfile}" "${published}" &>/dev/null || echo "Generated keyblock differs from ${url}"
diff --git a/scripts/get-date.sh b/scripts/get-date.sh
new file mode 100755
index 0000000..3653155
--- /dev/null
+++ b/scripts/get-date.sh
@@ -0,0 +1,14 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-3.0-or-later
+set -o nounset
+cd "$(dirname $0)/.."
+
+# Get date from NEWS if possible (regular release)
+DATE=$(head -n1 < NEWS | sed 's/.*(\(.*\)).*/\1/' | grep -E '^[0-9]{4}-[0-9]{2}-[0-9]{2}$$')
+
+if [[ $? -ne 0 ]]; then
+ # or use last modification time of NEWS (dev versions)
+ DATE=$(date -u -r NEWS +%F)
+fi
+
+echo -n $DATE
diff --git a/scripts/kresd-host.lua b/scripts/kresd-host.lua
new file mode 100755
index 0000000..be6efd4
--- /dev/null
+++ b/scripts/kresd-host.lua
@@ -0,0 +1,115 @@
+#!/usr/bin/env luajit
+-- SPDX-License-Identifier: GPL-3.0-or-later
+-- Work around OS X stripping dyld variables
+cli_bin = 'luajit scripts/kresd-query.lua'
+libdir = os.getenv('DYLD_LIBRARY_PATH')
+if libdir then
+ cli_bin = string.format('DYLD_LIBRARY_PATH="%s" %s', libdir, cli_bin)
+end
+-- Parse CLI arguments
+local function help(rc)
+ print(string.format([[
+Usage: %s [-vdh46D] [-c class] [-t type]
+ [-f keyfile] hostname
+ Queries the DNS for information.
+ The hostname is looked up for IP4, IP6 and mail.
+ Use the -v option to see DNSSEC security information.
+ -t type what type to look for.
+ -c class what class to look for, if not class IN.
+ -C confstr additional kresd-style configuration.
+ -D DNSSEC enable with default root anchor
+ -f keyfile read trust anchors from file, with lines as -y.
+ -v be more verbose, shows nodata and security.
+ -d debug, traces the action, -d -d shows more.
+ -4 use ipv4 network, avoid ipv6.
+ -6 use ipv6 network, avoid ipv4.
+ -h show this usage help.]],
+ arg[0]))
+ return rc
+end
+
+-- Parse CLI arguments
+if #arg < 1 then
+ return help(1)
+end
+local qtypes, qclass, qname = {}, 'IN', nil
+local verbose, config = false, {}
+k = 1 while k <= #arg do
+ local v = arg[k]
+ if v == '-h' or v == '--help' then
+ return help(0)
+ elseif v == '-C' then
+ k = k + 1
+ table.insert(config, arg[k])
+ elseif v == '-D' then
+ table.insert(config, 'trust_anchors.add_file("root.keys")')
+ elseif v == '-f' then
+ k = k + 1
+ table.insert(config, string.format('trust_anchors.add_file("%s")', arg[k]))
+ elseif v == '-v' then
+ verbose = true
+ elseif v == '-d' then
+ verbose = true
+ table.insert(config, 'log_level("debug")')
+ elseif v == '-4' then
+ table.insert(config, 'net.ipv6 = false')
+ elseif v == '-6' then
+ table.insert(config, 'net.ipv4 = false')
+ elseif v == '-c' then
+ k = k + 1
+ qclass = arg[k]:upper()
+ elseif v == '-t' then
+ k = k + 1
+ table.insert(qtypes, arg[k]:upper())
+ elseif v:byte() == string.byte('-') then
+ return help(1)
+ else
+ qname = v
+ -- Check if name is an IP addresses
+ -- @TODO: convert to domain name and make a PTR lookup
+ end
+ k = k + 1
+end
+if not qname then
+ return help(1)
+end
+if #qtypes == 0 then
+ qtypes = {'A', 'AAAA', 'MX'}
+end
+-- Assemble config/query
+for _, qtype in ipairs(qtypes) do
+ query = string.format('-t %s -c %s %s', qtype, qclass, qname)
+ capture = string.format([[
+ local qname = "%s"
+ local qtype = "%s"
+ local qverbose = %s]], qname, qtype, tostring(verbose))..[[
+ local qry = req:resolved()
+ local section = pkt:rrsets(kres.section.ANSWER)
+ for i = 1, #section do
+ local rr = section[i]
+ for k = 1, rr.rrs.count do
+ local rdata = rr:tostring(k - 1)
+ local owner = kres.dname2str(rr:owner())
+ if qverbose then
+ if not qry.flags.DNSSEC_WANT or qry.flags.DNSSEC_INSECURE then
+ rdata = rdata .. " (insecure)"
+ else
+ rdata = rdata .. " (secure)"
+ end
+ end
+ if rr.type == kres.type.A then
+ print(string.format("%s has address %s", owner, rdata))
+ elseif rr.type == kres.type.AAAA then
+ print(string.format("%s has IPv6 address %s", owner, rdata))
+ elseif rr.type == kres.type.MX then
+ print(string.format("%s mail is handled by %s", owner, rdata))
+ elseif rr.type == kres.type.CNAME then
+ print(string.format("%s is an alias for %s", owner, rdata))
+ else
+ print(string.format("%s has %s record %s", owner, qtype, rdata))
+ end
+ end
+ end
+ ]]
+ os.execute(string.format('%s -C \'%s\' %s \'%s\'', cli_bin, table.concat(config, ' '), query, capture))
+end
diff --git a/scripts/kresd-query.lua b/scripts/kresd-query.lua
new file mode 100755
index 0000000..713b9c7
--- /dev/null
+++ b/scripts/kresd-query.lua
@@ -0,0 +1,63 @@
+#!/usr/bin/env luajit
+-- SPDX-License-Identifier: GPL-3.0-or-later
+cli_bin = 'kresd -q -c -'
+-- Work around OS X stripping dyld variables
+libdir = os.getenv('DYLD_LIBRARY_PATH')
+if libdir then
+ cli_bin = string.format('DYLD_LIBRARY_PATH="%s" %s', libdir, cli_bin)
+end
+cli_cmd = [[echo '
+option("ALWAYS_CUT", true)
+%s
+return resolve("%s", kres.type.%s, kres.class.%s, 0,
+function (pkt, req)
+ local ok, err = pcall(function () %s end)
+ if not ok then
+ print(err)
+ end
+ quit()
+end)']]
+-- Parse CLI arguments
+local function help()
+ name = 'kresd-query.lua'
+ print(string.format('Usage: %s [-t type] [-c class] [-C config] <name> <script>', name))
+ print('Execute a single-shot query and run a script on the result.')
+ print('There are two variables available: pkt (kres.pkt_t), req (kres.request_t)')
+ print('See modules README to learn about their APIs.')
+ print('')
+ print('Options:')
+ print('\t-h,--help ... print this help')
+ print('\t-t TYPE ... query for given type (default: A)')
+ print('\t-c CLASS ... query in given class (default: IN)')
+ print('\t-C config_str ... kresd-style config (default: -)')
+ print('Examples:')
+ print('\t'..name..' -t SOA cz "print(pkt:qname())" ... print response QNAME')
+end
+-- Parse CLI arguments
+if #arg < 2 then help() return 1 end
+local qtype, qclass, qname = 'A', 'IN', nil
+local config, scripts = '', {}
+k = 1 while k <= #arg do
+ local v = arg[k]
+ if v == '-h' or v == '--help' then
+ return help()
+ elseif v == '-C' then
+ k = k + 1
+ config = arg[k]
+ elseif v == '-c' then
+ k = k + 1
+ qclass = arg[k]:upper()
+ elseif v == '-t' then
+ k = k + 1
+ qtype = arg[k]:upper()
+ elseif v:byte() == string.byte('-') then
+ return help()
+ elseif not qname then
+ qname = v
+ else
+ table.insert(scripts, v)
+ end
+ k = k + 1
+end
+cli_cmd = string.format(cli_cmd, config, qname, qtype, qclass, table.concat(scripts, ' '))
+return os.execute(cli_cmd..' | '..cli_bin)
diff --git a/scripts/kresd.apparmor b/scripts/kresd.apparmor
new file mode 100644
index 0000000..ad6f911
--- /dev/null
+++ b/scripts/kresd.apparmor
@@ -0,0 +1,29 @@
+#include <tunables/global>
+
+/usr/sbin/kresd {
+ #include <abstractions/base>
+ #include <abstractions/p11-kit>
+ #include <abstractions/nameservice>
+ capability net_bind_service,
+ capability setgid,
+ capability setuid,
+ # seems to be needed during start to read /var/lib/knot-resolver
+ # while we still run as root.
+ capability dac_override,
+
+ network tcp,
+ network udp,
+
+ /proc/sys/net/core/somaxconn r,
+ /etc/knot-resolver/* r,
+ /var/lib/knot-resolver/ r,
+ /var/lib/knot-resolver/** rwlk,
+
+ # modules
+ /usr/lib{,64}/kdns_modules/*.lua r,
+ /usr/lib{,64}/kdns_modules/*.so rm,
+
+ # Site-specific additions and overrides. See local/README for details.
+ #include <local/usr.sbin.kresd>
+}
+
diff --git a/scripts/luacov_gen_empty.sh b/scripts/luacov_gen_empty.sh
new file mode 100755
index 0000000..127734d
--- /dev/null
+++ b/scripts/luacov_gen_empty.sh
@@ -0,0 +1,18 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-3.0-or-later
+# Generate stats file in luacov format indicating that files named on stdin
+# were not processed.
+#
+# Normally luacov does not know about files which were not loaded so
+# without this manual addition the files are missing in coverage report.
+
+# Usage:
+# $ luacov_gen_empty.sh < list_of_lua_files > luacov.empty_stats.out
+
+set -o errexit -o nounset
+IFS=$'\n'
+
+while read FILENAME
+do
+ echo -e "0:${FILENAME}\n "
+done
diff --git a/scripts/luacov_to_info.lua b/scripts/luacov_to_info.lua
new file mode 100755
index 0000000..b27ba99
--- /dev/null
+++ b/scripts/luacov_to_info.lua
@@ -0,0 +1,57 @@
+#!/usr/bin/env luajit
+-- SPDX-License-Identifier: GPL-3.0-or-later
+
+local luacov = require('luacov')
+local ReporterBase = require('luacov.reporter').ReporterBase
+local LcovReporter = setmetatable({}, ReporterBase)
+LcovReporter.__index = LcovReporter
+
+function LcovReporter:on_new_file(filename)
+ self.finfo = self.current_files[filename] or {name=filename, coverage={}}
+end
+
+function LcovReporter:on_mis_line(_, lineno, _)
+ self.finfo.coverage[lineno] = self.finfo.coverage[lineno] or 0
+end
+
+function LcovReporter:on_hit_line(_, lineno, _, hits)
+ self.finfo.coverage[lineno] = (self.finfo.coverage[lineno] or 0) + hits
+end
+
+function LcovReporter:on_end_file()
+ self.current_files[self.finfo.name] = self.finfo
+ self.finfo = nil
+end
+
+-- Write out results in lcov format
+local function write_lcov_info(files)
+ for fname, finfo in pairs(files) do
+ local instrumented, nonzero = 0, 0
+ print('TN:')
+ print(string.format('SF:%s', fname))
+ for i, hits in pairs(finfo.coverage) do
+ print(string.format('DA:%d,%d', i, hits))
+ instrumented = instrumented + 1
+ if hits > 0 then
+ nonzero = nonzero + 1
+ end
+ end
+ print(string.format('LH:%d', nonzero))
+ print(string.format('LF:%d', instrumented))
+ print('end_of_record')
+ end
+end
+
+-- Accumulate total coverage
+local all_files = {}
+for _, fname in ipairs(arg) do
+ local conf = luacov.load_config()
+ conf.statsfile = fname
+ local reporter = assert(LcovReporter:new(conf))
+ reporter.current_files = all_files
+ reporter:run()
+ reporter:close()
+end
+
+-- Write results
+write_lcov_info(all_files)
diff --git a/scripts/make-archive.sh b/scripts/make-archive.sh
new file mode 100755
index 0000000..8270367
--- /dev/null
+++ b/scripts/make-archive.sh
@@ -0,0 +1,38 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-3.0-or-later
+# Create a development tarball
+set -o errexit -o nounset -o xtrace
+
+cd "$(dirname ${0})/.."
+
+# make sure we don't accidentally add / overwrite forgotten changes in git
+(git diff-index --quiet HEAD && git diff-index --cached --quiet HEAD) || \
+ (echo 'git index has uncommitted changes!'; exit 1)
+
+if ! git describe --tags --exact-match; then
+ # devel version
+ GIT_HASH=$(git rev-parse --short HEAD )
+ TIMESTAMP=$(date -u +'%s' 2>/dev/null)
+
+ # modify and commit meson.build
+ sed -i "s/^\(\s*version\s*:\s*'\)\([^']\+\)\('.*\)/\1\2.$TIMESTAMP.$GIT_HASH\3/" meson.build
+
+ : changed version in meson.build, changes must be committed to git
+ git add meson.build
+ git commit -m 'DROP: devel version archive'
+
+ cleanup() {
+ # undo commit
+ git reset --hard HEAD^ >/dev/null
+ }
+ trap cleanup EXIT
+fi
+
+# create tarball
+rm -rf build_dist ||:
+meson build_dist
+ninja -C build_dist dist
+
+# print path to generated tarball
+set +o xtrace
+find "${PWD}/build_dist/meson-dist/" -name "knot-resolver-*.tar.xz"
diff --git a/scripts/make-doc.sh b/scripts/make-doc.sh
new file mode 100755
index 0000000..d41e234
--- /dev/null
+++ b/scripts/make-doc.sh
@@ -0,0 +1,42 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-3.0-or-later
+cd "$(dirname ${0})/.."
+
+pushd doc
+doxygen
+popd
+
+SPHINX=$(command -v sphinx-build-3)
+if [ $? -ne 0 ]; then
+ SPHINX=$(command -v sphinx-build)
+fi
+
+set -o errexit -o nounset
+
+rm -rf doc/html
+${SPHINX} ${@} -b html -d doc/.doctrees doc doc/html
+
+if command -v makeinfo &>/dev/null; then
+ rm -rf doc/texinfo
+ ${SPHINX} ${@} -b texinfo -d doc/.doctrees doc doc/texinfo
+
+ # Sphinx < 2 doesn't create a separate directory for figures, so if
+ # necessary move them to the correct location and update the references in
+ # the generated Texinfo file
+ if [ ! -d doc/texinfo/knot-resolver-figures ]; then
+ cd doc/texinfo
+ mkdir knot-resolver-figures
+ mv *.png *.svg knot-resolver-figures/
+ sed -e 's/\(@image{\)/\1knot-resolver-figures\//' \
+ knot-resolver.texi > knot-resolver.texi.tmp
+ mv knot-resolver.texi.tmp knot-resolver.texi
+ cd ../..
+ fi
+
+ make -C doc/texinfo info
+
+ mkdir doc/texinfo/.install
+ mv doc/texinfo/knot-resolver.info \
+ doc/texinfo/knot-resolver-figures \
+ doc/texinfo/.install/
+fi
diff --git a/scripts/make-obs.sh b/scripts/make-obs.sh
new file mode 100755
index 0000000..abe9670
--- /dev/null
+++ b/scripts/make-obs.sh
@@ -0,0 +1,59 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# create OpenSUSE Build System (OBS) source package
+#
+# this needs to be run on a system with:
+#
+# * apkg
+# * dpkg-buildpackage
+#
+# usage:
+# ./scripts/make-obs.sh [path.to.archive.xz] [1]
+#
+# supply archives as optional arguments to build from,
+# otherwise archive will be built from sources by apkg
+# second argument is optional release number (defaults to 1)
+#
+# output at pkg/obs/ (removed on each run)
+set -o errexit -o nounset
+
+pushd "$(dirname ${0})/.."
+
+OUTDIR="pkg/obs"
+APKG_OPTS="-O $OUTDIR"
+
+if [ -z $@ ]; then
+ echo "building OBS srcpkg from project files"
+else
+ AR=$1
+ echo "building OBS srcpkg from specified archive(s)"
+ APKG_OPTS="-a $AR $APKG_OPTS"
+
+ RELEASE=${2:-}
+ if [ ! -z "$RELEASE" ]; then
+ echo "custom release: $RELEASE"
+ APKG_OPTS="-r $RELEASE $APKG_OPTS"
+ fi
+fi
+
+set -o xtrace
+
+: removing existing output files at output dir: $OUTDIR
+rm -rf "$OUTDIR"
+: making debian source package from archive
+apkg srcpkg $APKG_OPTS -d debian
+: removing extra debian source package files
+rm -f $OUTDIR/*_source.*
+: rendering RPM template
+apkg srcpkg $APKG_OPTS -d fedora --render-template
+: fixing RPM .spec to use debian source archive
+sed -i 's/^\(Source0:\s\+\).*/\1knot-resolver_%{version}.orig.tar.xz/' $OUTDIR/*.spec
+: rendering PKGBUILD template
+apkg srcpkg $APKG_OPTS -d arch --render-template
+: fixing PKGBUILD to use debian source archive
+sed -i 's/^source=.*/source=("knot-resolver_${pkgver}.orig.tar.xz")/' $OUTDIR/PKGBUILD
+popd >/dev/null
+
+echo "OBS srcpkg ready at: $OUTDIR"
+
diff --git a/scripts/map_install_src.lua b/scripts/map_install_src.lua
new file mode 100755
index 0000000..ffc9a30
--- /dev/null
+++ b/scripts/map_install_src.lua
@@ -0,0 +1,168 @@
+#!/usr/bin/env luajit
+-- SPDX-License-Identifier: GPL-3.0-or-later
+
+-- parse install commands from stdin
+-- input: PREFIX=... make install --dry-run --always-make
+-- output: <install path> <source path>
+-- (or sed commands if --sed was specified)
+
+output = 'list'
+if #arg > 1 or arg[1] == '-h' or arg[1] == '--help' then
+ print(string.format([[
+Read install commands and map install paths to paths in source directory.
+
+Usage:
+$ PREFIX=... make install --dry-run --always-make | %s
+
+Example output:
+/kresd/git/.local/lib/kdns_modules/policy.lua modules/policy/policy.lua
+
+Option --sed will produce output suitable as input suitable for sed.]],
+ arg[0]))
+ os.exit(1)
+elseif #arg == 0 then
+ output = 'list'
+elseif arg[1] == '--sed' then
+ output = 'sed'
+else
+ print('Invalid arguments. See --help.')
+ os.exit(2)
+end
+
+-- remove double // from paths and remove trailing /
+function normalize_path(path)
+ assert(path)
+ repeat
+ path, changes = path:gsub('//', '/')
+ until changes == 0
+ return path:gsub('/$', '')
+end
+
+function is_opt(word)
+ return word:match('^-')
+end
+
+-- opts requiring additional argument to be skipped
+local ignored_opts_with_arg = {
+ ['--backup'] = true,
+ ['-g'] = true,
+ ['--group'] = true,
+ ['-m'] = true,
+ ['--mode'] = true,
+ ['-o'] = true,
+ ['--owner'] = true,
+ ['--strip-program'] = true,
+ ['--suffix'] = true,
+}
+
+-- state machine junctions caused by --opts
+-- returns: new state (expect, mode) and target name if any
+function parse_opts(word, expect, mode)
+ if word == '--' then
+ return 'names', mode, nil -- no options anymore
+ elseif word == '-d' or word == '--directory' then
+ return 'opt_or_name', 'newdir', nil
+ elseif word == '-t' or word == '--target-directory' then
+ return 'targetdir', mode, nil
+ elseif word:match('^--target-directory=') then
+ return 'opt_or_name', mode, string.sub(word, 20)
+ elseif ignored_opts_with_arg[word] then
+ return 'ignore', mode, nil -- ignore next word
+ else
+ return expect, mode, nil -- unhandled opt
+ end
+end
+
+
+-- cmd: complete install command line: install -m 0644 -t dest src1 src2
+-- dirs: names known to be directories: name => true
+-- returns: updated dirs
+function process_cmd(cmd, dirs)
+ -- print('# ' .. cmd)
+ sanity_check(cmd)
+ local expect = 'install'
+ local mode = 'copy' -- copy or newdir
+ local target -- last argument or argument for install -t
+ local names = {} -- non-option arguments
+
+ for word in cmd:gmatch('%S+') do
+ if expect == 'install' then -- parsing 'install'
+ assert(word == 'install')
+ expect = 'opt_or_name'
+ elseif expect == 'opt_or_name' then
+ if is_opt(word) then
+ expect, mode, newtarget = parse_opts(word, expect, mode)
+ target = newtarget or target
+ else
+ if mode == 'copy' then
+ table.insert(names, word)
+ elseif mode == 'newdir' then
+ local path = normalize_path(word)
+ dirs[path] = true
+ else
+ assert(false, 'bad mode')
+ end
+ end
+ elseif expect == 'targetdir' then
+ local path = normalize_path(word)
+ dirs[path] = true
+ target = word
+ expect = 'opt_or_name'
+ elseif expect == 'names' then
+ table.insert(names, word)
+ elseif expect == 'ignore' then
+ expect = 'opt_or_name'
+ else
+ assert(false, 'bad expect')
+ end
+ end
+ if mode == 'newdir' then
+ -- no mapping to print, this cmd just created directory
+ return dirs
+ end
+
+ if not target then -- last argument is the target
+ target = table.remove(names)
+ end
+ assert(target, 'fatal: no target in install cmd')
+ target = normalize_path(target)
+
+ for _, name in pairs(names) do
+ basename = string.gsub(name, "(.*/)(.*)", "%2")
+ if not dirs[target] then
+ print('fatal: target directory "' .. target .. '" was not created yet!')
+ os.exit(2)
+ end
+ -- mapping installed name -> source name
+ if output == 'list' then
+ print(target .. '/' .. basename, name)
+ elseif output == 'sed' then
+ print(string.format([[s`%s`%s`g]],
+ target .. '/' .. basename, name))
+ else
+ assert(false, 'unsupported output')
+ end
+ end
+ return dirs
+end
+
+function sanity_check(cmd)
+ -- shell quotation is not supported
+ assert(not cmd:match('"'), 'quotes " are not supported')
+ assert(not cmd:match("'"), "quotes ' are not supported")
+ assert(not cmd:match('\\'), "escapes like \\ are not supported")
+ assert(cmd:match('^install%s'), 'not an install command')
+end
+
+-- remember directories created by install -d so we can expand relative paths
+local dirs = {}
+while true do
+ local cmd = io.read("*line")
+ if not cmd then
+ break
+ end
+ local isinstall = cmd:match('^install%s')
+ if isinstall then
+ dirs = process_cmd(cmd, dirs)
+ end
+end
diff --git a/scripts/run-pylint.sh b/scripts/run-pylint.sh
new file mode 100755
index 0000000..9241382
--- /dev/null
+++ b/scripts/run-pylint.sh
@@ -0,0 +1,12 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-3.0-or-later
+set -o errexit -o nounset
+
+cd "$(dirname ${0})/.."
+
+# Find Python modules and standalone Python scripts
+FILES=$(find ./tests/pytests \
+ -type d -exec test -e '{}/__init__.py' \; -print -prune -o \
+ -name '*.py' -print)
+
+python3 -m pylint -j 0 --rcfile ./tests/pytests/pylintrc ${FILES}
diff --git a/scripts/run-scanbuild-with-args.sh b/scripts/run-scanbuild-with-args.sh
new file mode 100755
index 0000000..b295453
--- /dev/null
+++ b/scripts/run-scanbuild-with-args.sh
@@ -0,0 +1,51 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-3.0-or-later
+set -o errexit -o nounset
+
+# following checkers are disabled on purpose:
+# Clang does not support attribute cleanup and this is causing false positives in following checkers:
+# unix.Malloc
+# alpha.unix.SimpleStream
+# alpha.unix.Stream
+# https://bugs.llvm.org/show_bug.cgi?id=3888
+
+# These are disabled for other reasons:
+# alpha.clone.CloneChecker # way too many false positives
+# alpha.core.CastToStruct # we use this pattern too much, hard to avoid in many cases
+# alpha.deadcode.UnreachableCode # false positives/flags sanity checks depending on implementation details
+# alpha.security.MallocOverflow # not smart enough to infer max values from data types
+
+exec scan-build --status-bugs -no-failure-reports \
+-analyzer-config aggressive-binary-operation-simplification=true \
+-disable-checker unix.Malloc \
+-enable-checker alpha.core.BoolAssignment \
+-enable-checker alpha.core.CastSize \
+-enable-checker alpha.core.Conversion \
+-enable-checker alpha.core.DynamicTypeChecker \
+-enable-checker alpha.core.FixedAddr \
+-enable-checker alpha.core.IdenticalExpr \
+-enable-checker alpha.core.PointerArithm \
+-enable-checker alpha.core.PointerSub \
+-enable-checker alpha.core.SizeofPtr \
+-enable-checker alpha.core.TestAfterDivZero \
+-enable-checker alpha.cplusplus.IteratorRange \
+-enable-checker alpha.security.ArrayBound \
+-enable-checker alpha.security.ArrayBoundV2 \
+-enable-checker alpha.security.ReturnPtrRange \
+-enable-checker alpha.security.taint.TaintPropagation \
+-enable-checker alpha.unix.BlockInCriticalSection \
+-enable-checker alpha.unix.Chroot \
+-enable-checker alpha.unix.PthreadLock \
+-enable-checker alpha.unix.cstring.BufferOverlap \
+-enable-checker alpha.unix.cstring.NotNullTerminated \
+-enable-checker alpha.unix.cstring.OutOfBounds \
+-enable-checker nullability.NullableDereferenced \
+-enable-checker nullability.NullablePassedToNonnull \
+-enable-checker nullability.NullableReturnedFromNonnull \
+-enable-checker optin.performance.Padding \
+-enable-checker optin.portability.UnixAPI \
+-enable-checker security.FloatLoopCounter \
+-enable-checker valist.CopyToSelf \
+-enable-checker valist.Uninitialized \
+-enable-checker valist.Unterminated \
+"$@"
diff --git a/scripts/test-config.sh b/scripts/test-config.sh
new file mode 100755
index 0000000..695e518
--- /dev/null
+++ b/scripts/test-config.sh
@@ -0,0 +1,32 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-3.0-or-later
+# Utility script used by meson to run config tests post installation
+set -o nounset -o errexit
+
+# if anything fails during test setup, use exit code 77 to mark it as skipped
+function skip {
+ exit 77
+}
+trap skip ERR
+
+TEST_DIR="$(dirname ${TEST_FILE})"
+TMP_RUNDIR="$(mktemp -d)"
+
+function finish {
+ if [[ "$(jobs -p)" != "" ]]
+ then
+ echo "SIGKILLing leftover processes:"
+ jobs -l
+ kill -s SIGKILL $(jobs -p)
+ fi
+ rm -rf "${TMP_RUNDIR}"
+}
+trap finish EXIT
+
+cp -a "${TEST_DIR}/"* "${TMP_RUNDIR}/"
+cd "${TMP_RUNDIR}"
+
+which kresd || (echo "kresd not executable!"; exit 77)
+trap ERR # get actual kresd error code from now on
+
+kresd "$@"
diff --git a/scripts/test-integration-prepare.sh b/scripts/test-integration-prepare.sh
new file mode 100755
index 0000000..13db143
--- /dev/null
+++ b/scripts/test-integration-prepare.sh
@@ -0,0 +1,8 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-3.0-or-later
+set -o errexit -o nounset
+
+cd "${1}"
+
+git submodule update --init --recursive
+make depend &>/dev/null
diff --git a/scripts/update-authors.sh b/scripts/update-authors.sh
new file mode 100755
index 0000000..fe1d857
--- /dev/null
+++ b/scripts/update-authors.sh
@@ -0,0 +1,41 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-3.0-or-later
+set -o nounset -o xtrace
+
+function spdx_originator_to_authors {
+ # $1 = Person/Organization
+ find -name '*.spdx' | xargs grep --no-filename "^PackageOriginator: $1: " \
+ | cut -d : -f 3 | sed -e 's/^ *//' -e 's/(/</' -e 's/)/>/' | sort -u
+}
+
+cd "$(git rev-parse --show-toplevel)"
+AUTHORS_FILE=AUTHORS
+TEMP_FILE="$(mktemp AUTHORS.XXXXXXXXXX)"
+
+# drop all names from the current file
+sed '/^People who contributed commits to our Git repo are/q' "${AUTHORS_FILE}" > "${TEMP_FILE}"
+# append to the new file
+git log --format="%aN <%aE>" | sort -u | git check-mailmap --stdin | sort -u >> "${TEMP_FILE}"
+
+echo '' >> "${TEMP_FILE}"
+echo 'Knot Resolver source tree also bundles code and content published by:' >> "${TEMP_FILE}"
+spdx_originator_to_authors "Person" >> "${TEMP_FILE}"
+spdx_originator_to_authors "Organization" >> "${TEMP_FILE}"
+
+echo '' >> "${TEMP_FILE}"
+echo 'Thanks to everyone who knowingly or unknowingly contributed!' >> "${TEMP_FILE}"
+
+# check for changes
+diff "${AUTHORS_FILE}" "${TEMP_FILE}"
+CHANGED=$?
+
+if [ $CHANGED -ne 0 ]; then
+ # update
+ mv "${TEMP_FILE}" "${AUTHORS_FILE}"
+fi
+
+# cleanup
+rm -f "${TEMP_FILE}"
+
+# signal change with exit code
+exit $CHANGED
diff --git a/scripts/update-root-hints.sh b/scripts/update-root-hints.sh
new file mode 100755
index 0000000..5f7a564
--- /dev/null
+++ b/scripts/update-root-hints.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-3.0-or-later
+set -o nounset -o xtrace
+
+TEMP_FILE=/tmp/root.hints
+HINTS_FILE=etc/root.hints
+
+# download latest root hints
+wget -O ${TEMP_FILE} https://www.internic.net/domain/named.root
+
+# strip comments for diff
+sed '/^;/d' ${TEMP_FILE} > ${TEMP_FILE}.clean
+sed '/^;/d' ${HINTS_FILE} > ${HINTS_FILE}.clean
+
+# check for changes
+diff ${TEMP_FILE}.clean ${HINTS_FILE}.clean >/dev/null
+CHANGED=$?
+
+if [ $CHANGED -ne 0 ]; then
+ # update root.hints
+ mv ${TEMP_FILE} ${HINTS_FILE}
+fi
+
+# cleanup
+rm -f ${TEMP_FILE} ${TEMP_FILE}.clean ${HINTS_FILE}.clean
+
+# signal change with exit code
+exit $CHANGED
diff --git a/security.txt b/security.txt
new file mode 100644
index 0000000..085bbfd
--- /dev/null
+++ b/security.txt
@@ -0,0 +1,9 @@
+Please report security issues that require encryption to the following e-mail
+address.
+
+vladimir.cunat@nic.cz
+
+You can obtain our PGP keys from:
+https://secure.nic.cz/files/knot-resolver/kresd-keyblock.asc
+
+More info: https://www.knot-resolver.cz/contact
diff --git a/systemd/README.rst b/systemd/README.rst
new file mode 100644
index 0000000..1d10a1f
--- /dev/null
+++ b/systemd/README.rst
@@ -0,0 +1,11 @@
+.. SPDX-License-Identifier: GPL-3.0-or-later
+
+Notes for packagers
+-------------------
+
+* kresd.target should be enabled by default by linking it to systemd lib/
+ directory. Instances of kresd@.service are then added manually to
+ kresd.target when the user enables them.
+* Distributions using systemd-sysv-generator should mask kresd.service to
+ be consistent with other distributions. Any use of kresd.service instead of
+ kresd@N.service is discouraged to avoid confusing the users.
diff --git a/systemd/kres-cache-gc.service.in b/systemd/kres-cache-gc.service.in
new file mode 100644
index 0000000..6e39fcc
--- /dev/null
+++ b/systemd/kres-cache-gc.service.in
@@ -0,0 +1,19 @@
+# SPDX-License-Identifier: CC0-1.0
+[Unit]
+Description=Knot Resolver Garbage Collector daemon
+Documentation=man:kresd.systemd(7)
+Documentation=man:kresd(8)
+
+[Service]
+Type=simple
+ExecStart=@sbin_dir@/kres-cache-gc -c @systemd_cache_dir@ -d 1000
+User=@user@
+Group=@group@
+Restart=on-failure
+RestartSec=30
+StartLimitInterval=400
+StartLimitBurst=10
+Slice=system-kresd.slice
+
+[Install]
+WantedBy=kresd.target
diff --git a/systemd/kresd.systemd.7.in b/systemd/kresd.systemd.7.in
new file mode 100644
index 0000000..a602b8e
--- /dev/null
+++ b/systemd/kresd.systemd.7.in
@@ -0,0 +1,100 @@
+.TH "kresd.systemd" "7" "@date@" "CZ.NIC" "Knot Resolver @version@ Systemd Units"
+.\"
+.\" kresd.systemd.7 -- man page for systemd units for kresd
+.\"
+.\" Copyright (c) CZ.NIC. All rights reserved.
+.\"
+.\" SPDX-License-Identifier: GPL-3.0-or-later
+.\"
+.\"
+.SH "NAME"
+kresd.systemd
+\- managing Knot Resolver @version@ through systemd.
+
+.SH "SYNOPSIS"
+.nf
+kresd@.service
+kresd.target
+system-kresd.slice
+.fi
+
+.SH "DESCRIPTION"
+.P
+This manual page describes how to manage \fBkresd\fR using \fBsystemd\fR
+units.
+
+.B QUICKSTART
+
+.nf
+.RS 4n
+\fBsystemctl start kresd@1\fR - single instance of kresd, responding on localhost
+.RE
+.fi
+
+.B CONCURRENT DAEMONS
+
+\fBkresd\fR daemon can be executed in multiple independent processes, which are
+managed with \fBsystemd\fR via systemd templates (see \fBsystemd.unit\fR(5)).
+Each \fBsystemd\fR service instance of \fBkresd\fR (\fIkresd@.service\fR)
+represents a single, independent kresd process.
+
+If you have more than one CPU core available, a single running \fBkresd\fR
+daemon will only be able to make use of one core at a time, leaving the other
+cores idle. If you want \fBkresd\fR to take advantage of all available cores,
+while sharing both cache and sockets, you should enable and start as many
+instances of the \fBkresd@.service\fR as you have cores. Typically, each
+instance is just named \fIkresd@\fBN\fI.service\fR, where \fIN\fR is a decimal
+number. For example, to enable and start 3 concurrent daemons:
+
+.nf
+.RS 4n
+.B systemctl enable --now kresd@1.service kresd@2.service kresd@3.service
+.RE
+.fi
+
+The systemd-managed \fBkresd\fR service set is grouped in the
+\fIsystem-kresd.slice\fR slice. The slice includes all running daemons
+(instances of \fIkresd@.service\fR).
+
+.SH "EXAMPLES"
+
+To start a single kresd instance and enable it at boot:
+.nf
+.RS 4n
+.B systemctl enable --now kresd@1.service
+.RE
+.fi
+
+To restart (or stop) all running instances, you can use a glob expression.
+Please note that glob can't be used to start or enable instances.
+.nf
+.RS 4n
+.B systemctl restart 'kresd@*'
+.RE
+.fi
+
+Bash users can also use Brace Expansion to enable or start multiple instances,
+instead of listing them manually.
+.nf
+.RS 4n
+.B systemctl enable --now kresd@{1..4}.service
+.RE
+.fi
+
+To start all enabled kresd daemons, you can also use the provided \fIkresd.target\fR:
+.nf
+.RS 4n
+.B systemctl start kresd.target
+.RE
+.fi
+
+.RE
+
+.SH "SEE ALSO"
+\fIkresd(8)\fR,
+\fIsystemd.unit(5)\fR,
+\fIhttps://knot-resolver.readthedocs.io/en/v@version@/\fR
+
+.SH "AUTHORS"
+.B kresd
+developers are mentioned in the AUTHORS file in the distribution.
diff --git a/systemd/kresd.target b/systemd/kresd.target
new file mode 100644
index 0000000..5a2d786
--- /dev/null
+++ b/systemd/kresd.target
@@ -0,0 +1,9 @@
+# SPDX-License-Identifier: CC0-1.0
+[Unit]
+Description=Knot Resolver daemons
+Documentation=man:kresd.systemd(7)
+Documentation=man:kresd(8)
+After=network-online.target
+
+[Install]
+WantedBy=multi-user.target
diff --git a/systemd/kresd@.service.in b/systemd/kresd@.service.in
new file mode 100644
index 0000000..adb303a
--- /dev/null
+++ b/systemd/kresd@.service.in
@@ -0,0 +1,30 @@
+# SPDX-License-Identifier: CC0-1.0
+[Unit]
+Description=Knot Resolver daemon
+Documentation=man:kresd.systemd(7)
+Documentation=man:kresd(8)
+Wants=kres-cache-gc.service
+Before=kres-cache-gc.service
+Wants=network-online.target
+After=network-online.target
+Before=nss-lookup.target
+Wants=nss-lookup.target
+
+[Service]
+Type=notify
+Environment="SYSTEMD_INSTANCE=%i"
+WorkingDirectory=@systemd_work_dir@
+ExecStart=@sbin_dir@/kresd -c @lib_dir@/distro-preconfig.lua -c @etc_dir@/kresd.conf -n
+ExecStopPost=/usr/bin/env rm -f "@run_dir@/control/%i"
+User=@user@
+Group=@group@
+CapabilityBoundingSet=CAP_NET_BIND_SERVICE CAP_SETPCAP
+AmbientCapabilities=CAP_NET_BIND_SERVICE CAP_SETPCAP
+TimeoutStopSec=10s
+WatchdogSec=10s
+Restart=on-abnormal
+LimitNOFILE=524288
+Slice=system-kresd.slice
+
+[Install]
+WantedBy=kresd.target
diff --git a/systemd/meson.build b/systemd/meson.build
new file mode 100644
index 0000000..6ca0bac
--- /dev/null
+++ b/systemd/meson.build
@@ -0,0 +1,66 @@
+# systemd
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+## configuration
+systemd_config = configuration_data()
+systemd_config.set('user', user)
+systemd_config.set('group', group)
+systemd_config.set('systemd_work_dir', systemd_work_dir)
+systemd_config.set('systemd_cache_dir', systemd_cache_dir)
+systemd_config.set('sbin_dir', sbin_dir)
+systemd_config.set('etc_dir', etc_dir)
+systemd_config.set('run_dir', run_dir)
+systemd_config.set('lib_dir', lib_dir)
+
+if systemd_files == 'enabled'
+ ## unit files
+ kresd_service = configure_file(
+ input: 'kresd@.service.in',
+ output: 'kresd@.service',
+ configuration: systemd_config,
+ install_dir: systemd_unit_dir,
+ )
+ kres_cache_gc_service = configure_file(
+ input: 'kres-cache-gc.service.in',
+ output: 'kres-cache-gc.service',
+ configuration: systemd_config,
+ install_dir: systemd_unit_dir,
+ )
+ install_data(
+ sources: 'kresd.target',
+ install_dir: systemd_unit_dir,
+ )
+
+ ## man page
+ kresd_systemd_man = configure_file(
+ input: 'kresd.systemd.7.in',
+ output: 'kresd.systemd.7',
+ configuration: man_config,
+ )
+ install_man(kresd_systemd_man)
+
+ ## tmpfiles
+ tmpfiles = configure_file(
+ input: 'tmpfiles.d/knot-resolver.conf.in',
+ output: 'knot-resolver.tmpfiles',
+ configuration: systemd_config,
+ )
+ install_data(
+ tmpfiles,
+ rename: ['knot-resolver.conf'],
+ install_dir: systemd_tmpfiles_dir,
+ )
+
+ ## sysusers
+ sysusers = configure_file(
+ input: 'sysusers.d/knot-resolver.conf.in',
+ output: 'knot-resolver.sysusers',
+ configuration: systemd_config,
+ )
+ install_data(
+ sysusers,
+ rename: ['knot-resolver.conf'],
+ install_dir: systemd_sysusers_dir,
+ )
+
+endif
diff --git a/systemd/multiinst.rst b/systemd/multiinst.rst
new file mode 100644
index 0000000..2a5c63c
--- /dev/null
+++ b/systemd/multiinst.rst
@@ -0,0 +1,99 @@
+.. SPDX-License-Identifier: GPL-3.0-or-later
+
+.. _systemd-multiple-instances:
+
+Multiple instances
+==================
+
+.. note:: This section describes the usage of kresd when running under systemd.
+ For other uses, please refer to :ref:`usage-without-systemd`.
+
+Knot Resolver can utilize multiple CPUs running in multiple independent instances (processes), where each process utilizes at most single CPU core on your machine. If your machine handles a lot of DNS traffic run multiple instances.
+
+All instances typically share the same configuration and cache, and incoming queries are automatically distributed by operating system among all instances.
+
+Advantage of using multiple instances is that a problem in a single instance will not affect others, so a single instance crash will not bring whole DNS resolver service down.
+
+.. tip:: For maximum performance, there should be as many kresd processes as
+ there are available CPU threads.
+
+To run multiple instances, use a different identifier after `@` sign for each instance, for
+example:
+
+.. code-block:: bash
+
+ $ systemctl start kresd@1.service
+ $ systemctl start kresd@2.service
+ $ systemctl start kresd@3.service
+ $ systemctl start kresd@4.service
+
+With the use of brace expansion in BASH the equivalent command looks like this:
+
+.. code-block:: bash
+
+ $ systemctl start kresd@{1..4}.service
+
+For more details see ``kresd.systemd(7)``.
+
+
+.. _systemd-zero-downtime-restarts:
+
+Zero-downtime restarts
+----------------------
+Resolver restart normally takes just milliseconds and cache content is persistent to avoid performance drop
+after restart. If you want real zero-downtime restarts use `multiple instances`_ and do rolling
+restart, i.e. restart only one resolver process at a time.
+
+On a system with 4 instances run these commands sequentially:
+
+.. code-block:: bash
+
+ $ systemctl restart kresd@1.service
+ $ systemctl restart kresd@2.service
+ $ systemctl restart kresd@3.service
+ $ systemctl restart kresd@4.service
+
+At any given time only a single instance is stopped and restarted so remaining three instances continue to service clients.
+
+
+.. _instance-specific-configuration:
+
+Instance-specific configuration
+-------------------------------
+
+Instances can use arbitrary identifiers for the instances, for example we can name instances like `dns1`, `tls` and so on.
+
+.. code-block:: bash
+
+ $ systemctl start kresd@dns1
+ $ systemctl start kresd@dns2
+ $ systemctl start kresd@tls
+ $ systemctl start kresd@doh
+
+The instance name is subsequently exposed to kresd via the environment variable
+``SYSTEMD_INSTANCE``. This can be used to tell the instances apart, e.g. when
+using the :ref:`mod-nsid` module with per-instance configuration:
+
+.. code-block:: lua
+
+ local systemd_instance = os.getenv("SYSTEMD_INSTANCE")
+
+ modules.load('nsid')
+ nsid.name(systemd_instance)
+
+More arcane set-ups are also possible. The following example isolates the
+individual services for classic DNS, DoT and DoH from each other.
+
+.. code-block:: lua
+
+ local systemd_instance = os.getenv("SYSTEMD_INSTANCE")
+
+ if string.match(systemd_instance, '^dns') then
+ net.listen('127.0.0.1', 53, { kind = 'dns' })
+ elseif string.match(systemd_instance, '^tls') then
+ net.listen('127.0.0.1', 853, { kind = 'tls' })
+ elseif string.match(systemd_instance, '^doh') then
+ net.listen('127.0.0.1', 443, { kind = 'doh2' })
+ else
+ panic("Use kresd@dns*, kresd@tls* or kresd@doh* instance names")
+ end
diff --git a/systemd/sysusers.d/knot-resolver.conf.in b/systemd/sysusers.d/knot-resolver.conf.in
new file mode 100644
index 0000000..ea66e27
--- /dev/null
+++ b/systemd/sysusers.d/knot-resolver.conf.in
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: CC0-1.0
+# sysusers.d(5) file for knot-resolver (kresd)
+#Type Name ID GECOS Home directory Shell
+u @user@ - "Knot Resolver Daemon User"
+g @group@
diff --git a/systemd/tmpfiles.d/knot-resolver.conf.in b/systemd/tmpfiles.d/knot-resolver.conf.in
new file mode 100644
index 0000000..204088d
--- /dev/null
+++ b/systemd/tmpfiles.d/knot-resolver.conf.in
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: CC0-1.0
+# tmpfiles.d(5) directories for knot-resolver (kresd)
+#Type Path Mode UID GID Age Argument
+ d @run_dir@ 0750 @user@ @group@ - -
+ d @systemd_work_dir@ 0750 @user@ @group@ - -
+ d @systemd_cache_dir@ 0750 @user@ @group@ - -
diff --git a/tests/.gitignore b/tests/.gitignore
new file mode 100644
index 0000000..ee3d88a
--- /dev/null
+++ b/tests/.gitignore
@@ -0,0 +1,6 @@
+*.pyc
+tmp*
+test_cache
+test_context
+test_resolve
+test_rplan
diff --git a/tests/README.rst b/tests/README.rst
new file mode 100644
index 0000000..69393dc
--- /dev/null
+++ b/tests/README.rst
@@ -0,0 +1,94 @@
+.. SPDX-License-Identifier: GPL-3.0-or-later
+
+Tests
+-----
+
+The following is a non-comprehensitve lists of various tests that can be found
+in this repo. These can be enabled by the build system.
+
+Unit tests
+~~~~~~~~~~
+
+The unit tests depend on cmocka_ and can easily be executed after compilation.
+They are enabled by default (if ``cmocka`` is found).
+
+.. code-block:: bash
+
+ $ ninja -C build_dir
+ $ meson test -C build_dir --suite unit
+
+Postinstall tests
+~~~~~~~~~~~~~~~~~
+
+There following tests require a working installation of kresd. The
+binary ``kresd`` found in ``$PATH`` will be tested. When testing through meson,
+``$PATH`` is modified automatically and you just need to make sure to install
+kresd first.
+
+.. code-block:: bash
+
+ $ ninja install -C build_dir
+
+Config tests
+~~~~~~~~~~~~
+
+Config tests utilize the kresd's lua config file to execute arbitrary tests,
+typically testing various modules, their API etc.
+
+To enable these tests, specify ``-Dconfig_tests=enabled`` option for meson.
+Multiple dependencies are required (refer to meson's output when configuring
+the build dir).
+
+.. code-block:: bash
+
+ $ meson configure build_dir -Dconfig_tests=enabled
+ $ ninja install -C build_dir
+ $ meson test -C build_dir --suite config
+
+Extra tests
+~~~~~~~~~~~
+
+The extra tests require a large set of additional dependencies and executing
+them outside of upstream development is probably redundant.
+
+To enable these tests, specify ``-Dextra_tests=enabled`` option for meson.
+Multiple dependencies are required (refer to meson's output when configuring
+the build dir). Enabling ``extra_tests`` automatically enables config tests as
+well.
+
+**Integration tests**
+
+The integration tests are using Deckard, the `DNS test harness
+<https://gitlab.nic.cz/knot/deckard>`_. The tests simulate specific DNS
+scenarios, including authoritative server and their responses. These tests rely
+on linux namespaces, refer to Deckard documentation for more info.
+
+.. code-block:: bash
+
+ $ meson configure build_dir -Dextra_tests=enabled
+ $ ninja install -C build_dir
+ $ meson test -C build_dir --suite integration
+
+**Pytests**
+
+The pytest suite is designed to spin up a kresd instance, acquire a connected
+socket, and then performs any tests on it. These tests are used to test for
+example TCP, TLS and its connection management.
+
+.. code-block:: bash
+
+ $ meson configure build_dir -Dextra_tests=enabled
+ $ ninja install -C build_dir
+ $ meson test -C build_dir --suite pytests
+
+Useful meson commands
+~~~~~~~~~~~~~~~~~~~~~
+
+It's possible to run only specific test suite or a test.
+
+.. code-block:: bash
+
+ $ meson test -C build_dir --help
+ $ meson test -C build_dir --list
+ $ meson test -C build_dir --no-suite postinstall
+ $ meson test -C build_dir integration.serve_stale
diff --git a/tests/config/basic.test.lua b/tests/config/basic.test.lua
new file mode 100644
index 0000000..73356a4
--- /dev/null
+++ b/tests/config/basic.test.lua
@@ -0,0 +1,211 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+local ffi = require('ffi')
+
+-- test if constants work properly
+local function test_constants()
+ same(kres.class.IN, 1, 'class constants work')
+ same(kres.type.NS, 2, 'record type constants work')
+ same(kres.type.TYPE2, 2, 'unnamed record type constants work')
+ same(kres.type.BADTYPE, nil, 'non-existent type constants are checked')
+ same(kres.section.ANSWER, 0, 'section constants work')
+ same(kres.rcode.SERVFAIL, 2, 'rcode constants work')
+ same(kres.opcode.UPDATE, 5, 'opcode constants work')
+ -- Test inverse tables to convert constants to text
+ same(kres.tostring.class[1], 'IN', 'text class constants work')
+ same(kres.tostring.type[2], 'NS', 'text record type constants work')
+ same(kres.tostring.type[65535], 'TYPE65535', 'text record type undefined constants work')
+ same(kres.tostring.section[0], 'ANSWER', 'text section constants work')
+ same(kres.tostring.rcode[2], 'SERVFAIL', 'text rcode constants work')
+ same(kres.tostring.opcode[5], 'UPDATE', 'text opcode constants work')
+end
+
+-- test globals
+local function test_globals()
+ ok(mode('strict'), 'changing strictness mode')
+ boom(mode, {'badmode'}, 'changing to non-existent strictness mode')
+ same(reorder_RR(true), true, 'answer section reordering')
+ same(option('REORDER_RR', false), false, 'generic option call')
+ boom(option, {'REORDER_RR', 'potato'}, 'generic option call argument check')
+ boom(option, {'MARS_VACATION', false}, 'generic option check name')
+ same(table_print('crabdiary'), "'crabdiary'", 'table print works')
+ same(table_print({fakepizza=1}), "{\n ['fakepizza'] = 1,\n}", 'table print works on tables')
+end
+
+-- test global API functions
+local function test_global_functions()
+ boom(kres.parse_rdata, {'A 127.0.0.1'}, 'parse_rdata with non-table argument')
+ boom(kres.parse_rdata, {{1}}, 'parse_rdata with non-string data in arg table')
+ same(kres.parse_rdata({'A 127.0.0.1'}), {string.char(127, 0, 0, 1)}, 'parse_rdata with single record')
+ same(kres.parse_rdata({'A 127.0.0.1', 'A 127.0.0.2'}),
+ {string.char(127, 0, 0, 1), string.char(127, 0, 0, 2)}, 'parse_rdata with multiple records')
+end
+
+-- test if dns library functions work
+local function test_rrset_functions()
+ local rr = {owner = '\3com\0', ttl = 1, type = kres.type.TXT, rdata = '\5hello'}
+ local rr_text = tostring(kres.rr2str(rr))
+ same(rr_text:gsub('%s+', ' '), 'com. 1 TXT "hello"', 'rrset to text works')
+ same(kres.dname2str(todname('com.')), 'com.', 'domain name conversion works')
+ -- test creating rrset
+ rr = kres.rrset(todname('com.'), kres.type.A, kres.class.IN, 66)
+ ok(ffi.istype(kres.rrset, rr), 'created an empty RR')
+ same(rr:owner(), '\3com\0', 'created RR has correct owner')
+ same(rr:class(), kres.class.IN, 'created RR has correct class')
+ same(rr:class(kres.class.CH), kres.class.CH, 'can set a different class')
+ same(rr:class(kres.class.IN), kres.class.IN, 'can restore a class')
+ same(rr.type, kres.type.A, 'created RR has correct type')
+ -- test adding rdata
+ same(rr:wire_size(), 0, 'empty RR wire size is zero')
+ ok(rr:add_rdata('\1\2\3\4', 4), 'adding RDATA works')
+ same(rr:wire_size(), 5 + 4 + 4 + 2 + 4, 'RR wire size works after adding RDATA')
+ -- test conversion to text
+ local expect = 'com. 66 A 1.2.3.4\n'
+ same(rr:txt_dump(), expect, 'RR to text works')
+ -- create a dummy rrsig
+ local rrsig = kres.rrset(todname('com.'), kres.type.RRSIG, kres.class.IN, 0)
+ rrsig:add_rdata('\0\1', 2)
+ same(rr:rdcount(), 1, 'add_rdata really added RDATA')
+ -- check rrsig matching
+ same(rr.type, rrsig:type_covered(), 'rrsig type covered matches covered RR type')
+ ok(rr:is_covered_by(rrsig), 'rrsig is covering a record')
+ -- test rrset merging
+ local copy = kres.rrset(rr:owner(), rr.type, kres.class.IN, 66)
+ ok(copy:add_rdata('\4\3\2\1', 4), 'adding second RDATA works')
+ ok(rr:merge_rdata(copy), 'merge_rdata works')
+ same(rr:rdcount(), 2, 'RDATA count is correct after merge_rdata')
+ expect = 'com. 66 A 1.2.3.4\n' ..
+ 'com. 66 A 4.3.2.1\n'
+ same(rr:txt_dump(), expect, 'merge_rdata actually merged RDATA')
+end
+
+-- test dns library packet interface
+local function test_packet_functions()
+ local pkt = kres.packet(512)
+ isnt(pkt, nil, 'creating packets works')
+ -- Test manipulating header
+ ok(pkt:rcode(kres.rcode.NOERROR), 'setting rcode works')
+ same(pkt:rcode(), 0, 'getting rcode works')
+ same(pkt:opcode(), 0, 'getting opcode works')
+ is(pkt:aa(), false, 'packet is created without AA')
+ is(pkt:ra(), false, 'packet is created without RA')
+ is(pkt:ad(), false, 'packet is created without AD')
+ ok(pkt:rd(true), 'setting RD bit works')
+ is(pkt:rd(), true, 'getting RD bit works')
+ ok(pkt:tc(true), 'setting TC bit works')
+ is(pkt:tc(), true, 'getting TC bit works')
+ ok(pkt:tc(false), 'disabling TC bit works')
+ is(pkt:tc(), false, 'getting TC bit after disable works')
+ is(pkt:cd(), false, 'getting CD bit works')
+ is(pkt:id(1234), 1234, 'setting MSGID works')
+ is(pkt:id(), 1234, 'getting MSGID works')
+ -- Test manipulating question
+ is(pkt:qname(), nil, 'reading name from empty question')
+ is(pkt:qtype(), 0, 'reading type from empty question')
+ is(pkt:qclass(), 0, 'reading class from empty question')
+ ok(pkt:question(todname('hello'), kres.class.IN, kres.type.A), 'setting question section works')
+ same(pkt:qname(), todname('hello'), 'reading QNAME works')
+ same(pkt:qtype(), kres.type.A, 'reading QTYPE works')
+ same(pkt:qclass(), kres.class.IN, 'reading QCLASS works')
+ -- Test manipulating sections
+ ok(pkt:begin(kres.section.ANSWER), 'switching sections works')
+ local res, err = pkt:put(nil, 0, 0, 0, '')
+ isnt(res, true, 'inserting nil entry doesnt work')
+ isnt(err.code, 0, 'error code is non-zero')
+ isnt(tostring(res), '', 'inserting nil returns invalid parameter')
+ ok(pkt:put(pkt:qname(), 900, pkt:qclass(), kres.type.A, '\1\2\3\4'), 'adding rrsets works')
+ boom(pkt.begin, {pkt, 10}, 'switching to invalid section doesnt work')
+ ok(pkt:begin(kres.section.ADDITIONAL), 'switching to different section works')
+ boom(pkt.begin, {pkt, 0}, 'rewinding sections doesnt work')
+ local before_insert = pkt:remaining_bytes()
+ ok(pkt:put(pkt:qname(), 900, pkt:qclass(), kres.type.A, '\4\3\2\1'), 'adding rrsets to different section works')
+ same(pkt:remaining_bytes(), before_insert - (2 + 4 + 4 + 2 + 4), 'remaining bytes count goes down with insertions')
+ -- Test conversions to text
+ like(pkt:tostring(), '->>HEADER<<-', 'packet to text works')
+ -- Test deserialization
+ local wire = pkt:towire()
+ same(#wire, 55, 'packet serialization works')
+ local parsed = kres.packet(#wire, wire)
+ isnt(parsed, nil, 'creating packet from wire works')
+ ok(parsed:parse(), 'parsing packet from wire works')
+ same(parsed:qname(), pkt:qname(), 'parsed packet has same QNAME')
+ same(parsed:qtype(), pkt:qtype(), 'parsed packet has same QTYPE')
+ same(parsed:qclass(), pkt:qclass(), 'parsed packet has same QCLASS')
+ same(parsed:opcode(), pkt:opcode(), 'parsed packet has same opcode')
+ same(parsed:rcode(), pkt:rcode(), 'parsed packet has same rcode')
+ same(parsed:rd(), pkt:rd(), 'parsed packet has same RD')
+ same(parsed:id(), pkt:id(), 'parsed packet has same MSGID')
+ same(parsed:qdcount(), pkt:qdcount(), 'parsed packet has same question count')
+ same(parsed:ancount(), pkt:ancount(), 'parsed packet has same answer count')
+ same(parsed:nscount(), pkt:nscount(), 'parsed packet has same authority count')
+ same(parsed:arcount(), pkt:arcount(), 'parsed packet has same additional count')
+ same(parsed:tostring(), pkt:tostring(), 'parsed packet is equal to source packet')
+
+ -- Test adding RR sets directly
+ local copy = kres.packet(512)
+ copy:question(todname('hello'), kres.class.IN, kres.type.A)
+ copy:begin(kres.section.ANSWER)
+ local rr = kres.rrset(pkt:qname(), kres.type.A, kres.class.IN, 66)
+ rr:add_rdata('\4\3\2\1', 4)
+ ok(copy:put_rr(rr), 'adding RR sets directly works')
+ ok(copy:recycle(), 'recycling packet works')
+
+ -- Test recycling of packets
+ -- Clear_payload keeps header + question intact
+ local cleared = kres.packet(#wire, wire) -- same as "parsed" above
+ ok(cleared:parse(), 'parsing packet from wire works')
+ ok(cleared:clear_payload(), 'clear_payload works')
+ same(cleared:id(), pkt:id(), 'cleared packet has same MSGID')
+ same(cleared:qr(), pkt:qr(), 'cleared packet has same QR')
+ same(cleared:opcode(), pkt:opcode(), 'cleared packet has same OPCODE')
+ same(cleared:aa(), pkt:aa(), 'cleared packet has same AA')
+ same(cleared:tc(), pkt:tc(), 'cleared packet has same TC')
+ same(cleared:rd(), pkt:rd(), 'cleared packet has same RD')
+ same(cleared:ra(), pkt:ra(), 'cleared packet has same RA')
+ same(cleared:ad(), pkt:ad(), 'cleared packet has same AD')
+ same(cleared:cd(), pkt:cd(), 'cleared packet has same CD')
+ same(cleared:rcode(), pkt:rcode(), 'cleared packet has same RCODE')
+ same(cleared:qdcount(), pkt:qdcount(), 'cleared packet has same question count')
+ same(cleared:ancount(), 0, 'cleared packet has no answers')
+ same(cleared:nscount(), 0, 'cleared packet has no authority')
+ same(cleared:arcount(), 0, 'cleared packet has no additional')
+ same(cleared:qname(), pkt:qname(), 'cleared packet has same QNAME')
+ same(cleared:qtype(), pkt:qtype(), 'cleared packet has same QTYPE')
+ same(cleared:qclass(), pkt:qclass(), 'cleared packet has same QCLASS')
+
+ -- Recycle clears question as well
+ ok(pkt:recycle(), 'recycle() works')
+ is(pkt:ancount(), 0, 'recycle() clears records')
+ is(pkt:qname(), nil, 'recycle() clears question')
+ is(#pkt:towire(), 12, 'recycle() clears the packet wireformat')
+end
+
+-- test JSON encode/decode functions
+local function test_json_functions()
+ for msg, obj in pairs({
+ ['number'] = 0,
+ ['string'] = 'ok',
+ ['list'] = {1, 2, 3},
+ ['map'] = {foo='bar'},
+ ['nest structure'] = {foo='bar', baz={1,2,3}},
+ }) do
+ same(fromjson(tojson(obj)), obj, 'json test: ' .. msg)
+ end
+
+ for _, str in ipairs({
+ '{', '}',
+ '[', ']',
+ 'x,',
+ '[1,2,3,]',
+ }) do
+ boom(fromjson, {'{'}, 'json test: invalid \'' .. str .. '\'')
+ end
+end
+
+return {
+ test_constants,
+ test_globals,
+ test_global_functions,
+ test_rrset_functions,
+ test_packet_functions,
+ test_json_functions,
+}
diff --git a/tests/config/cache.test.lua b/tests/config/cache.test.lua
new file mode 100644
index 0000000..33b87db
--- /dev/null
+++ b/tests/config/cache.test.lua
@@ -0,0 +1,67 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+-- test if cache module properties work
+local function test_properties()
+ is(type(cache), 'table', 'cache module is loaded')
+ is(cache.count(), 0, 'cache is empty on startup')
+ local backends = cache.backends()
+ is(type(backends), 'table', 'cache provides a list of backends')
+ ok(backends['lmdb'], 'cache provides built-in lmdb backend')
+ is(cache.current_storage, 'lmdb://', 'cache starts with lmdb backend')
+ is(cache.current_size, 100 * MB, 'cache starts with default size limit')
+ is(cache.max_ttl(10), 10, 'allows setting maximum TTL')
+ is(cache.max_ttl(), 10, 'stored maximum TTL')
+ is(cache.min_ttl(1), 1, 'allows setting minimum TTL')
+ is(cache.min_ttl(), 1, 'stored minimum TTL')
+end
+
+-- test if the stats work with reopening the cache and operations fail with closed cache
+local function test_stats()
+ ok(cache.close(), 'cache can be closed')
+ boom(cache.open, {100 * MB, 'invalid://'}, 'cache cannot be opened with invalid backend')
+
+ boom(cache.clear, {}, '.clear() does not work on closed cache')
+ boom(cache.count, {}, '.count() does not work on closed cache')
+ boom(cache.get, { 'key' }, '.get(...) does not work on closed cache')
+
+ ok(cache.open(100 * MB), 'cache can be reopened')
+ local s = cache.stats()
+ is(type(s), 'table', 'stats returns a table')
+ -- Just checking the most useful fields
+ isnt(s.read and s.read_miss and s.write, nil, 'stats returns correct fields')
+end
+
+-- test if cache can be resized or shrunk
+local function test_resize()
+ ok(cache.open(200 * MB, 'lmdb://'), 'cache can be resized')
+ is(cache.current_size, 200 * MB, 'cache was resized')
+ ok(cache.open(50 * MB), 'cache can be shrunk')
+ is(cache.current_size, 50 * MB, 'cache was shrunk')
+end
+
+-- test access to cache through context
+local function test_context_cache()
+ local c = kres.context().cache
+ is(type(c), 'cdata', 'context has a cache object')
+ local s = c.stats
+ isnt(s.read and s.read_miss and s.write, 'context cache stats works')
+ -- insert A record into cache
+ local rdata = '\1\2\3\4'
+ local rr = kres.rrset('\3com\0', kres.type.A, kres.class.IN, 66)
+ rr:add_rdata(rdata, #rdata)
+ local s_write = s.write
+ ok(c:insert(rr, nil, 0, 0), 'cache insertion works (A)')
+ ok(c:commit(), 'cache commit works')
+ isnt(s.write, s_write, 'cache insertion increments counters')
+ -- insert NS record into cache
+ local rr_ns = kres.rrset('\3com\0', kres.type.NS, kres.class.IN, 66)
+ local rdata_ns = todname('c.gtld-servers.net')
+ ok(rr_ns:add_rdata(rdata_ns, #rdata_ns), 'adding rdata works')
+ ok(c:insert(rr_ns, nil, 0), 'cache insertion works (NS)')
+end
+
+return {
+ test_properties,
+ test_stats,
+ test_resize,
+ test_context_cache,
+}
diff --git a/tests/config/doh2.test.lua b/tests/config/doh2.test.lua
new file mode 100644
index 0000000..2360e7f
--- /dev/null
+++ b/tests/config/doh2.test.lua
@@ -0,0 +1,524 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+local basexx = require('basexx')
+local ffi = require('ffi')
+
+local function gen_huge_answer(_, req)
+ local answer = req:ensure_answer()
+ ffi.C.kr_pkt_make_auth_header(answer)
+
+ answer:rcode(kres.rcode.NOERROR)
+
+ -- 64k answer
+ answer:begin(kres.section.ANSWER)
+ answer:put('\4test\0', 300, answer:qclass(), kres.type.URI,
+ '\0\0\0\0' .. string.rep('0', 65000))
+ answer:put('\4test\0', 300, answer:qclass(), kres.type.URI,
+ '\0\0\0\0' .. 'done')
+ return kres.DONE
+end
+
+local function gen_varying_ttls(_, req)
+ local qry = req:current()
+ local answer = req:ensure_answer()
+ ffi.C.kr_pkt_make_auth_header(answer)
+
+ answer:rcode(kres.rcode.NOERROR)
+
+ -- varying TTLs in ANSWER section
+ answer:begin(kres.section.ANSWER)
+ answer:put(qry.sname, 1800, answer:qclass(), kres.type.AAAA,
+ '\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1')
+ answer:put(qry.sname, 900, answer:qclass(), kres.type.A, '\127\0\0\1')
+ answer:put(qry.sname, 20000, answer:qclass(), kres.type.NS, '\2ns\4test\0')
+
+ -- shorter TTL than all other RRs
+ answer:begin(kres.section.AUTHORITY)
+ answer:put('\4test\0', 300, answer:qclass(), kres.type.SOA,
+ -- ns.test. nobody.invalid. 1 3600 1200 604800 10800
+ '\2ns\4test\0\6nobody\7invalid\0\0\0\0\1\0\0\14\16\0\0\4\176\0\9\58\128\0\0\42\48')
+ return kres.DONE
+end
+
+function parse_pkt(input, desc)
+ local wire = ffi.cast("void *", input)
+ local pkt = ffi.C.knot_pkt_new(wire, #input, nil);
+ assert(pkt, desc .. ': failed to create new packet')
+
+ local result = ffi.C.knot_pkt_parse(pkt, 0)
+ ok(result == 0, desc .. ': knot_pkt_parse works on received answer')
+ return pkt
+end
+
+local function check_ok(req, desc)
+ local headers, stream, errno = req:go(16)
+ if errno then
+ local errmsg = stream
+ nok(errmsg, desc .. ': ' .. errmsg)
+ return
+ end
+ same(tonumber(headers:get(':status')), 200, desc .. ': status 200')
+ same(headers:get('content-type'), 'application/dns-message', desc .. ': content-type')
+ local body = assert(stream:get_body_as_string())
+ local pkt = parse_pkt(body, desc)
+ return headers, pkt
+end
+
+local function check_err(req, exp_status, desc)
+ local headers, errmsg, errno = req:go(16)
+ if errno then
+ nok(errmsg, desc .. ': ' .. errmsg)
+ return
+ end
+ local got_status = headers:get(':status')
+ same(got_status, exp_status, desc)
+end
+
+-- check prerequisites
+local bound, port
+local host = '127.0.0.1'
+for _ = 1,10 do
+ port = math.random(30000, 39999)
+ bound = pcall(net.listen, host, port, { kind = 'doh2'})
+ if bound then
+ break
+ end
+end
+
+if not bound then
+ -- skipping doh2 tests (failure to bind may be caused by missing support during build)
+ os.exit(77)
+else
+ policy.add(policy.suffix(policy.DROP, policy.todnames({'servfail.test.'})))
+ policy.add(policy.suffix(policy.DENY, policy.todnames({'nxdomain.test.'})))
+ policy.add(policy.suffix(gen_varying_ttls, policy.todnames({'noerror.test.'})))
+
+ local req_templ, uri_templ
+ local function start_server()
+ local request = require('http.request')
+ local ssl_ctx = require('openssl.ssl.context')
+ uri_templ = string.format('https://%s:%d/dns-query', host, port)
+ req_templ = assert(request.new_from_uri(uri_templ))
+ req_templ.headers:upsert('content-type', 'application/dns-message')
+ req_templ.ctx = ssl_ctx.new()
+ req_templ.ctx:setVerify(ssl_ctx.VERIFY_NONE)
+ end
+
+
+ -- test a valid DNS query using POST
+ local function test_post_servfail()
+ local desc = 'valid POST query which ends with SERVFAIL'
+ local req = req_templ:clone()
+ req.headers:upsert(':method', 'POST')
+ req:set_body(basexx.from_base64( -- servfail.test. A
+ 'FZUBAAABAAAAAAAACHNlcnZmYWlsBHRlc3QAAAEAAQ=='))
+ local headers, pkt = check_ok(req, desc)
+ if not (headers and pkt) then
+ return
+ end
+ -- uncacheable
+ same(headers:get('cache-control'), 'max-age=0', desc .. ': TTL 0')
+ same(headers:get('access-control-allow-origin'), '*', desc .. ': CORS headers')
+ same(pkt:rcode(), kres.rcode.SERVFAIL, desc .. ': rcode matches')
+ end
+
+ local function test_post_noerror()
+ local desc = 'valid POST query which ends with NOERROR'
+ local req = req_templ:clone()
+ req.headers:upsert(':method', 'POST')
+ req:set_body(basexx.from_base64( -- noerror.test. A
+ 'vMEBAAABAAAAAAAAB25vZXJyb3IEdGVzdAAAAQAB'))
+ local headers, pkt = check_ok(req, desc)
+ if not (headers and pkt) then
+ return
+ end
+ -- HTTP TTL is minimum from all RRs in the answer
+ same(headers:get('cache-control'), 'max-age=300', desc .. ': TTL 900')
+ same(pkt:rcode(), kres.rcode.NOERROR, desc .. ': rcode matches')
+ same(pkt:ancount(), 3, desc .. ': ANSWER is present')
+ same(pkt:nscount(), 1, desc .. ': AUTHORITY is present')
+ same(pkt:arcount(), 0, desc .. ': ADDITIONAL is empty')
+ end
+
+ local function test_post_ignore_params_1()
+ local desc = 'valid POST ignores parameters (without ?dns)'
+ local req = req_templ:clone()
+ req.headers:upsert(':method', 'POST')
+ req.headers:upsert(':path', '/doh?something=asdf&aaa=bbb')
+ req:set_body(basexx.from_base64( -- noerror.test. A
+ 'vMEBAAABAAAAAAAAB25vZXJyb3IEdGVzdAAAAQAB'))
+ local headers, pkt = check_ok(req, desc)
+ if not (headers and pkt) then
+ return
+ end
+ -- HTTP TTL is minimum from all RRs in the answer
+ same(headers:get('cache-control'), 'max-age=300', desc .. ': TTL 900')
+ same(pkt:rcode(), kres.rcode.NOERROR, desc .. ': rcode matches')
+ same(pkt:ancount(), 3, desc .. ': ANSWER is present')
+ same(pkt:nscount(), 1, desc .. ': AUTHORITY is present')
+ same(pkt:arcount(), 0, desc .. ': ADDITIONAL is empty')
+ end
+
+ local function test_post_ignore_params_2()
+ local desc = 'valid POST ignores parameters (with ?dns)'
+ local req = req_templ:clone()
+ req.headers:upsert(':method', 'POST')
+ req.headers:upsert(':path', '/dns-query?dns=' -- servfail.test. A
+ .. 'FZUBAAABAAAAAAAACHNlcnZmYWlsBHRlc3QAAAEAAQ')
+ req:set_body(basexx.from_base64( -- noerror.test. A
+ 'vMEBAAABAAAAAAAAB25vZXJyb3IEdGVzdAAAAQAB'))
+ local headers, pkt = check_ok(req, desc)
+ if not (headers and pkt) then
+ return
+ end
+ -- HTTP TTL is minimum from all RRs in the answer
+ same(headers:get('cache-control'), 'max-age=300', desc .. ': TTL 900')
+ same(pkt:rcode(), kres.rcode.NOERROR, desc .. ': rcode matches')
+ same(pkt:ancount(), 3, desc .. ': ANSWER is present')
+ same(pkt:nscount(), 1, desc .. ': AUTHORITY is present')
+ same(pkt:arcount(), 0, desc .. ': ADDITIONAL is empty')
+ end
+
+ local function test_post_nxdomain()
+ local desc = 'valid POST query which ends with NXDOMAIN'
+ local req = req_templ:clone()
+ req.headers:upsert(':method', 'POST')
+ req:set_body(basexx.from_base64( -- nxdomain.test. A
+ 'viABAAABAAAAAAAACG54ZG9tYWluBHRlc3QAAAEAAQ=='))
+ local headers, pkt = check_ok(req, desc)
+ if not (headers and pkt) then
+ return
+ end
+ same(headers:get('cache-control'), 'max-age=10800', desc .. ': TTL 10800')
+ same(pkt:rcode(), kres.rcode.NXDOMAIN, desc .. ': rcode matches')
+ same(pkt:nscount(), 1, desc .. ': AUTHORITY is present')
+ end
+
+ -- RFC 8484 section 6 explicitly allows huge answers over HTTP
+ local function test_huge_answer()
+ policy.add(policy.suffix(gen_huge_answer, policy.todnames({'huge.test'})))
+ local desc = 'POST query for a huge answer'
+ local req = req_templ:clone()
+ req.headers:upsert(':method', 'POST')
+ req:set_body(basexx.from_base64( -- huge.test. URI, no EDNS
+ 'HHwBAAABAAAAAAAABGh1Z2UEdGVzdAABAAAB'))
+ local _, pkt = check_ok(req, desc)
+ same(pkt:rcode(), kres.rcode.NOERROR, desc .. ': rcode NOERROR')
+ same(pkt:tc(), false, desc .. ': no TC bit')
+ same(pkt:ancount(), 2, desc .. ': ANSWER contains both RRs')
+ end
+
+ -- test an invalid DNS query using POST
+ local function test_post_short_input()
+ local req = assert(req_templ:clone())
+ req.headers:upsert(':method', 'POST')
+ req:set_body(string.rep('0', 11)) -- 11 bytes < DNS msg header
+ check_err(req, '400', 'too short POST finishes with 400')
+ end
+
+-- local function test_post_long_input()
+-- -- FIXME: This test is broken in Lua. The connection times out
+-- -- for some reason, but sending a request like this with `curl`
+-- -- or PowerShell's `Invoke-RestMethod` provides correct results.
+--
+-- local req = assert(req_templ:clone())
+-- req.headers:upsert(':method', 'POST')
+-- req:set_body(string.rep('s', 1025)) -- > DNS msg over UDP
+-- check_err(req, '400', 'too long POST finishes with 400')
+-- end
+
+ local function test_post_unparseable_input()
+ local req = assert(req_templ:clone())
+ req.headers:upsert(':method', 'POST')
+ req:set_body(string.rep('\0', 1024)) -- garbage
+ check_err(req, '400', 'unparseable DNS message finishes with 400')
+ end
+
+ local function test_post_unsupp_type()
+ local req = assert(req_templ:clone())
+ req.headers:upsert(':method', 'POST')
+ req.headers:upsert('content-type', 'application/dns+json')
+ req:set_body(string.rep('\0', 12)) -- valid message
+ check_err(req, '415', 'unsupported request content type finishes with 415')
+ end
+
+ -- test a valid DNS query using GET
+ local function test_get_servfail()
+ local desc = 'valid GET query which ends with SERVFAIL'
+ local req = req_templ:clone()
+ req.headers:upsert(':method', 'GET')
+ req.headers:upsert(':path', '/doh?dns=' -- servfail.test. A
+ .. 'FZUBAAABAAAAAAAACHNlcnZmYWlsBHRlc3QAAAEAAQ')
+ local headers, pkt = check_ok(req, desc)
+ if not (headers and pkt) then
+ return
+ end
+ -- uncacheable
+ same(headers:get('cache-control'), 'max-age=0', desc .. ': TTL 0')
+ same(pkt:rcode(), kres.rcode.SERVFAIL, desc .. ': rcode matches')
+ end
+
+ local function test_get_noerror()
+ local desc = 'valid GET query which ends with NOERROR'
+ local req = req_templ:clone()
+ req.headers:upsert(':method', 'GET')
+ req.headers:upsert(':path', '/doh?dns=' -- noerror.test. A
+ .. 'vMEBAAABAAAAAAAAB25vZXJyb3IEdGVzdAAAAQAB')
+ local headers, pkt = check_ok(req, desc)
+ if not (headers and pkt) then
+ return
+ end
+ -- HTTP TTL is minimum from all RRs in the answer
+ same(headers:get('cache-control'), 'max-age=300', desc .. ': TTL 900')
+ same(headers:get('access-control-allow-origin'), '*', desc .. ': CORS headers')
+ same(pkt:rcode(), kres.rcode.NOERROR, desc .. ': rcode matches')
+ same(pkt:ancount(), 3, desc .. ': ANSWER is present')
+ same(pkt:nscount(), 1, desc .. ': AUTHORITY is present')
+ same(pkt:arcount(), 0, desc .. ': ADDITIONAL is empty')
+ end
+
+ local function test_get_nxdomain()
+ local desc = 'valid GET query which ends with NXDOMAIN'
+ local req = req_templ:clone()
+ req.headers:upsert(':method', 'GET')
+ req.headers:upsert(':path', '/doh?dns=' -- nxdomain.test. A
+ .. 'viABAAABAAAAAAAACG54ZG9tYWluBHRlc3QAAAEAAQ')
+ local headers, pkt = check_ok(req, desc)
+ if not (headers and pkt) then
+ return
+ end
+ same(headers:get('cache-control'), 'max-age=10800', desc .. ': TTL 10800')
+ same(pkt:rcode(), kres.rcode.NXDOMAIN, desc .. ': rcode matches')
+ same(pkt:nscount(), 1, desc .. ': AUTHORITY is present')
+ end
+
+ local function test_get_multiple_amps()
+ local desc = 'GET query with consecutive ampersands'
+ local req = req_templ:clone()
+ req.headers:upsert(':method', 'GET')
+ req.headers:upsert(':path',
+ '/doh?other=something&another=something&&&&dns=vMEBAAABAAAAAAAAB25vZXJyb3IEdGVzdAAAAQAB')
+ check_ok(req, desc)
+ end
+
+ local function test_get_other_params_before_dns()
+ local desc = 'GET query with other parameters before dns is valid'
+ local req = req_templ:clone()
+ req.headers:upsert(':method', 'GET')
+ req.headers:upsert(':path',
+ '/doh?other=something&another=something&dns=vMEBAAABAAAAAAAAB25vZXJyb3IEdGVzdAAAAQAB')
+ check_ok(req, desc)
+ end
+
+ local function test_get_other_params_after_dns()
+ local desc = 'GET query with other parameters after dns is valid'
+ local req = req_templ:clone()
+ req.headers:upsert(':method', 'GET')
+ req.headers:upsert(':path',
+ '/doh?dns=vMEBAAABAAAAAAAAB25vZXJyb3IEdGVzdAAAAQAB&other=something&another=something')
+ check_ok(req, desc)
+ end
+
+ local function test_get_other_params()
+ local desc = 'GET query with other parameters than dns on both sides is valid'
+ local req = req_templ:clone()
+ req.headers:upsert(':method', 'GET')
+ req.headers:upsert(':path',
+ '/doh?other=something&dns=vMEBAAABAAAAAAAAB25vZXJyb3IEdGVzdAAAAQAB&another=something')
+ check_ok(req, desc)
+ end
+
+ -- test an invalid DNS query using GET
+ local function test_get_long_input()
+ local req = assert(req_templ:clone())
+ req.headers:upsert(':method', 'GET')
+ req.headers:upsert(':path', '/doh?dns=' .. basexx.to_url64(string.rep('\0', 1030)))
+ check_err(req, '400', 'too long GET finishes with 400')
+ end
+
+ local function test_get_no_dns_param()
+ local req = assert(req_templ:clone())
+ req.headers:upsert(':method', 'GET')
+ req.headers:upsert(':path', '/doh?notdns=' .. basexx.to_url64(string.rep('\0', 1024)))
+ check_err(req, '400', 'GET without dns parameter finishes with 400')
+ end
+
+ local function test_get_unparseable()
+ local req = assert(req_templ:clone())
+ req.headers:upsert(':method', 'GET')
+ req.headers:upsert(':path', '/doh??dns=' .. basexx.to_url64(string.rep('\0', 1024)))
+ check_err(req, '400', 'unparseable GET finishes with 400')
+ end
+
+ local function test_get_invalid_b64()
+ local req = assert(req_templ:clone())
+ req.headers:upsert(':method', 'GET')
+ req.headers:upsert(':path', '/doh?dns=thisisnotb64')
+ check_err(req, '400', 'GET with invalid base64 finishes with 400')
+ end
+
+ local function test_get_invalid_chars()
+ local req = assert(req_templ:clone())
+ req.headers:upsert(':method', 'GET')
+ req.headers:upsert(':path', '/doh?dns=' .. basexx.to_url64(string.rep('\0', 200)) .. '@#$%?!')
+ check_err(req, '400', 'GET with invalid characters in b64 finishes with 400')
+ end
+
+ local function test_unsupp_method()
+ local req = assert(req_templ:clone())
+ req.headers:upsert(':method', 'PUT')
+ check_err(req, '501', 'unsupported method finishes with 501')
+ end
+
+ local function test_dstaddr()
+ local triggered = false
+ local exp_dstaddr = ffi.gc(ffi.C.kr_straddr_socket(host, port, nil), ffi.C.free)
+ local function check_dstaddr(state, req)
+ triggered = true
+ same(ffi.C.kr_sockaddr_cmp(req.qsource.dst_addr, exp_dstaddr), 0,
+ 'request has correct server address')
+ return state
+ end
+ policy.add(policy.suffix(check_dstaddr, policy.todnames({'dstaddr.test'})))
+ local desc = 'valid POST query has server address available in request'
+ local req = req_templ:clone()
+ req.headers:upsert(':method', 'POST')
+ req:set_body(basexx.from_base64( -- dstaddr.test. A
+ 'FnkBAAABAAAAAAAAB2RzdGFkZHIEdGVzdAAAAQAB'))
+ check_ok(req, desc)
+ ok(triggered, 'dstaddr policy was triggered')
+ end
+
+ local function test_srcaddr()
+ modules.load('view')
+ assert(view)
+ local policy_refuse = policy.suffix(policy.REFUSE, policy.todnames({'srcaddr.test.knot-resolver.cz'}))
+ -- these netmasks would not work if the request did not contain IP addresses
+ view:addr('0.0.0.0/0', policy_refuse)
+ view:addr('::/0', policy_refuse)
+
+ local desc = 'valid POST query has source address available in request'
+ local req = req_templ:clone()
+ req.headers:upsert(':method', 'POST')
+ req:set_body(basexx.from_base64( -- srcaddr.test.knot-resolver.cz TXT
+ 'QNQBAAABAAAAAAAAB3NyY2FkZHIEdGVzdA1rbm90LXJlc29sdmVyAmN6AAAQAAE'))
+ local _, pkt = check_ok(req, desc)
+ same(pkt:rcode(), kres.rcode.REFUSED, desc .. ': view module caught it')
+
+ modules.unload('view')
+ end
+
+ local function test_headers()
+ local get_desc = nil
+
+ local function check_headers_zero_len(state, req)
+ same(tonumber(req.qsource.headers.len), 0, get_desc())
+ return state
+ end
+
+ local function check_headers_value(state, req)
+ local value = ffi.string(req.qsource.headers.at[0].value)
+ same(value, 'lua test config.doh2', get_desc())
+ return state
+ end
+
+ local function check_headers_more_values(state, req)
+ local checked = 0
+ for i = 1, tonumber(req.qsource.headers.len) do
+ local name = ffi.string(req.qsource.headers.at[i - 1].name)
+ local value = ffi.string(req.qsource.headers.at[i - 1].value)
+ if (name == 'user-agent') then
+ same(value, 'lua test config.doh2', get_desc() .. ' - user-agent')
+ checked = checked + 1
+ elseif (name == ':scheme') then
+ same(value, 'https', get_desc() .. ' - :scheme')
+ checked = checked + 1
+ end
+ end
+
+ same(checked, 2, get_desc() .. ' - two checked')
+ return state
+ end
+
+ local req = req_templ:clone()
+ req.headers:upsert(':method', 'GET')
+ req.headers:upsert(':path', '/doh?dns=' -- headers.test. A
+ .. 'AAABAAABAAAAAAAAB2hlYWRlcnMEdGVzdAAAAQAB')
+ req.headers:upsert('user-agent', 'lua test config.doh2')
+ req.headers:upsert(':scheme', 'https')
+
+ get_desc = function() return 'exposed HTTP headers: no headers' end
+ rule_desc = policy.add(policy.all(check_headers_zero_len))
+ check_ok(req, get_desc())
+ get_desc = function() return 'exposed HTTP headers: empty string' end
+ net.doh_headers('')
+ check_ok(req, get_desc())
+ get_desc = function() return 'exposed HTTP headers: empty table' end
+ net.doh_headers({''})
+ check_ok(req, get_desc())
+ policy.del(rule_desc.id)
+
+ get_desc = function() return 'exposed HTTP headers: take just one string parameter' end
+ boom(net.doh_headers, {'user-agent', ':method'}, get_desc())
+ get_desc = function() return 'exposed HTTP headers: take just one table parameter' end
+ boom(net.doh_headers, {{'user-agent'}, {':method'}}, get_desc())
+
+ get_desc = function() return 'exposed HTTP headers: take one header - as string' end
+ net.doh_headers('user-agent')
+ rule_desc = policy.add(policy.all(check_headers_value))
+ check_ok(req, get_desc())
+ get_desc = function() return 'exposed HTTP headers: take one header - as table' end
+ net.doh_headers({ 'user-agent' })
+ check_ok(req, get_desc())
+ policy.del(rule_desc.id)
+
+ get_desc = function() return 'exposed HTTP headers: take more headers' end
+ net.doh_headers({ ':method', 'user-agent', ':path', ':scheme' })
+ rule_desc = policy.add(policy.all(check_headers_more_values))
+ check_ok(req, get_desc())
+ policy.del(rule_desc.id)
+
+
+ end
+
+-- not implemented
+-- local function test_post_unsupp_accept()
+-- local req = assert(req_templ:clone())
+-- req.headers:upsert(':method', 'POST')
+-- req.headers:upsert('accept', 'application/dns+json')
+-- req:set_body(string.rep('\0', 12)) -- valid message
+-- check_err(req, '406', 'unsupported Accept type finishes with 406')
+-- end
+
+ -- plan tests
+ local tests = {
+ start_server,
+ test_post_servfail,
+ test_post_noerror,
+ test_post_ignore_params_1,
+ test_post_ignore_params_2,
+ test_post_nxdomain,
+ test_huge_answer,
+ test_post_short_input,
+-- test_post_long_input, -- FIXME see the test function
+ test_post_unparseable_input,
+ test_post_unsupp_type,
+ test_get_servfail,
+ test_get_noerror,
+ test_get_nxdomain,
+ test_get_multiple_amps,
+ test_get_other_params_before_dns,
+ test_get_other_params_after_dns,
+ test_get_other_params,
+ test_get_long_input,
+ test_get_no_dns_param,
+ test_get_unparseable,
+ test_get_invalid_b64,
+ test_get_invalid_chars,
+ test_unsupp_method,
+ test_dstaddr,
+ test_srcaddr,
+ test_headers
+ }
+
+ return tests
+end
diff --git a/tests/config/lru.test.lua b/tests/config/lru.test.lua
new file mode 100644
index 0000000..324d636
--- /dev/null
+++ b/tests/config/lru.test.lua
@@ -0,0 +1,84 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+local ffi = require('ffi')
+
+-- Test LRU interface
+local function test_lru()
+ local capacity = 1024
+ local lru = kres.lru(capacity)
+ local dict = {
+ "catagmatic", "prevaricator", "statoscope", "workhand", "benzamide",
+ "alluvia", "fanciful", "bladish", "Tarsius", "unfast", "appropriative",
+ "seraphically", "monkeypod", "deflectometer", "tanglesome", "zodiacal",
+ "physiologically", "economizer", "forcepslike", "betrumpet",
+ "Danization", "broadthroat", "randir", "usherette", "nephropyosis",
+ "hematocyanin", "chrysohermidin", "uncave", "mirksome", "podophyllum",
+ "siphonognathous", "indoor", "featheriness", "forwardation",
+ "archruler", "soricoid", "Dailamite", "carmoisin", "controllability",
+ "unpragmatical", "childless", "transumpt", "productive",
+ "thyreotoxicosis", "oversorrow", "disshadow", "osse", "roar",
+ "pantomnesia", "talcer", "hydrorrhoea", "Satyridae", "undetesting",
+ "smoothbored", "widower", "sivathere", "pendle", "saltation",
+ "autopelagic", "campfight", "unexplained", "Macrorhamphosus",
+ "absconsa", "counterflory", "interdependent", "triact", "reconcentration",
+ "oversharpness", "sarcoenchondroma", "superstimulate", "assessory",
+ "pseudepiscopacy", "telescopically", "ventriloque", "politicaster",
+ "Caesalpiniaceae", "inopportunity", "Helion", "uncompatible",
+ "cephaloclasia", "oversearch", "Mahayanistic", "quarterspace",
+ "bacillogenic", "hamartite", "polytheistical", "unescapableness",
+ "Pterophorus", "cradlemaking", "Hippoboscidae", "overindustrialize",
+ "perishless", "cupidity", "semilichen", "gadge", "detrimental",
+ "misencourage", "toparchia", "lurchingly", "apocatastasis"
+ }
+
+ -- Check that key insertion works
+ local inserted = 0
+ for i, word in ipairs(dict) do
+ if lru:set(word, i) then
+ if lru:get(word) == i then
+ inserted = inserted + 1
+ end
+ end
+ end
+
+ is(inserted, #dict, 'all inserted keys can be retrieved')
+
+ -- Check that using binary data as keys works
+ local badinserts = 0
+ for i, word in ipairs(dict) do
+ local word_len = #word
+ word = ffi.cast('char *', word)
+ if lru:set(word, i, word_len) then
+ if lru:get(word, word_len) ~= i then
+ badinserts = badinserts + 1
+ end
+ end
+ end
+
+ is(badinserts, 0, 'insertion works for binary keys')
+
+ -- Sanity check that non-existent keys cannot be retrieved
+ local missing = "not in lru"
+ is(lru:get(missing, #missing, false), nil, 'key that wasnt inserted cannot be retrieved')
+
+ -- Test whether key eviction works and LRU is able to insert past the capacity
+ badinserts = 0
+ for i = 0, capacity do
+ local word = dict[1] .. tostring(i)
+ if lru:set(word, i) then
+ if lru:get(word) ~= i then
+ badinserts = badinserts + 1
+ end
+ end
+ end
+
+ is(badinserts, 0, 'insertion works for more keys than LRU capacity')
+
+ -- Delete and GC
+ lru = nil -- luacheck: ignore 311
+ collectgarbage()
+ collectgarbage()
+end
+
+return {
+ test_lru,
+}
diff --git a/tests/config/meson.build b/tests/config/meson.build
new file mode 100644
index 0000000..a739222
--- /dev/null
+++ b/tests/config/meson.build
@@ -0,0 +1,41 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+config_tests += [
+ ['basic', files('basic.test.lua'), ['skip_asan']],
+ ['cache', files('cache.test.lua'), ['skip_asan']],
+ ['net', files('net.test.lua'), ['config_net']],
+ ['doh2', files('doh2.test.lua')],
+ ['lru', files('lru.test.lua')],
+ ['tls', files('tls.test.lua')],
+ ['worker', files('worker.test.lua')],
+]
+
+
+run_configtest = find_program('../../scripts/test-config.sh')
+
+
+foreach config_test : config_tests
+ # additional suites
+ extra_suites = config_test.length() >= 3 ? config_test[2] : []
+
+ # environment variables for test
+ conftest_env = environment()
+ conftest_env.prepend('PATH', sbin_dir)
+ conftest_env.set('KRESD_NO_LISTEN', '1')
+ conftest_env.set('SOURCE_PATH', meson.current_source_dir())
+ conftest_env.set(
+ 'TEST_FILE', '@0@/@1@'.format(meson.source_root(), config_test[1][0]))
+
+ test(
+ 'config.' + config_test[0],
+ run_configtest,
+ args: [
+ '-c', files('test.cfg'),
+ '-n'
+ ],
+ env: conftest_env,
+ suite: [
+ 'postinstall',
+ 'config',
+ ] + extra_suites,
+ )
+endforeach
diff --git a/tests/config/net.test.lua b/tests/config/net.test.lua
new file mode 100644
index 0000000..589bf61
--- /dev/null
+++ b/tests/config/net.test.lua
@@ -0,0 +1,67 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+local kr_table_len = require('kluautil').kr_table_len
+
+local function test_env_no_listen()
+ -- config tests are executed with env variable KRESD_NO_LISTEN=1
+ -- so net.list() should be an empty table
+ same(kr_table_len(net.list()), 0,
+ "env 'KRESD_NO_LISTEN=1' prevents kresd from listening")
+end
+
+local function test_freebind()
+ if require('jit').os == 'OSX' then
+ return 77 -- freebind is not supported on macOS
+ end
+ boom(net.listen, {'192.0.2.1', 50049},
+ 'net.listen() without freebind should fail')
+ -- TODO: same(kr_table_len(net.list()), 0,
+ -- "net.listen() failure does not modify output from net.list()")
+ ok(net.listen('192.0.2.1', 50049, { freebind=true }),
+ 'net.listen() with freebind succeeds')
+ local net_list = net.list()
+ -- same(list length == 2)
+ same(net_list[1].transport.protocol, 'udp',
+ 'net.listen({freebind = true}) without kind starts UDP listener')
+ same(net_list[2].transport.protocol, 'tcp',
+ 'net.listen({freebind = true}) without kind starts TCP listener')
+ same(net_list[1].transport.freebind, true,
+ 'net.listen({freebind = true}) enables FREEBIND for UDP listener')
+ same(net_list[2].transport.freebind, true,
+ 'net.listen({freebind = true}) enables FREEBIND for TCP listener')
+end
+
+local function test_proxy_allowed()
+ same(net.proxy_allowed(), {}, 'net.proxy_allowed() empty by default')
+ net.proxy_allowed('172.22.0.1')
+ same(net.proxy_allowed(), {'172.22.0.1/32'}, 'net.proxy_allowed() single IPv4 host')
+ net.proxy_allowed({'172.22.0.1'})
+ same(net.proxy_allowed(), {'172.22.0.1/32'}, 'net.proxy_allowed() single IPv4 host (as table)')
+ net.proxy_allowed('172.18.1.0/24')
+ same(net.proxy_allowed(), {'172.18.1.0/24'}, 'net.proxy_allowed() IPv4 net')
+ net.proxy_allowed({'172.22.0.1', '172.18.1.0/24'})
+ same(net.proxy_allowed(), {'172.18.1.0/24', '172.22.0.1/32'}, 'net.proxy_allowed() multiple IPv4 args as table')
+ net.proxy_allowed({})
+ same(net.proxy_allowed(), {}, 'net.proxy_allowed() clear table')
+ net.proxy_allowed({'::1'})
+ same(net.proxy_allowed(), {'::1/128'}, 'net.proxy_allowed() single IPv6 host')
+ net.proxy_allowed({'2001:db8:cafe:beef::/64'})
+ same(net.proxy_allowed(), {'2001:db8:cafe:beef::/64'}, 'net.proxy_allowed() IPv6 net')
+ net.proxy_allowed({'0.0.0.0/0', '::/0'})
+ same(net.proxy_allowed(), {'0.0.0.0/0', '::/0'}, 'net.proxy_allowed() allow all IPv4 and IPv6')
+ net.proxy_allowed({'::1'})
+ same(net.proxy_allowed(), {'::1/128'}, 'net.proxy_allowed() single IPv6 host after all (proper reset)')
+ boom(net.proxy_allowed, {'a'}, 'net.proxy_allowed() invalid string arg')
+ boom(net.proxy_allowed, {'127.0.0.'}, 'net.proxy_allowed() incomplete IPv4')
+ boom(net.proxy_allowed, {'256.0.0.0'}, 'net.proxy_allowed() invalid IPv4')
+ boom(net.proxy_allowed, {'xx::'}, 'net.proxy_allowed() invalid IPv6')
+ boom(net.proxy_allowed, {'127.0.0.1/33'}, 'net.proxy_allowed() IPv4 invalid netmask')
+ boom(net.proxy_allowed, {'127.0.0.1/-1'}, 'net.proxy_allowed() IPv4 negative netmask')
+ boom(net.proxy_allowed, {'fd::/132'}, 'net.proxy_allowed() IPv6 invalid netmask')
+ boom(net.proxy_allowed, {{'127.0.0.0/8', '::1/129'}}, 'net.proxy_allowed() single param invalid')
+end
+
+return {
+ test_env_no_listen,
+ test_freebind,
+ test_proxy_allowed,
+}
diff --git a/tests/config/tapered/.travis.yml b/tests/config/tapered/.travis.yml
new file mode 100644
index 0000000..77135af
--- /dev/null
+++ b/tests/config/tapered/.travis.yml
@@ -0,0 +1,40 @@
+language: c
+
+sudo: false
+
+env:
+ global:
+ - LUAROCKS=2.4.3
+ matrix:
+ - LUA=lua5.1
+ - LUA=lua5.2
+ - LUA=lua5.3
+ - LUA=luajit # latest stable version (2.0.4)
+ - LUA=luajit2.0 # current head of 2.0 branch
+ - LUA=luajit2.1 # current head of 2.1 branch
+
+branches:
+ only:
+ - bugfix
+ - master
+
+before_install:
+ - source .travis/setenv_lua.sh
+ - lua -v
+ - luarocks install luacov
+
+script:
+ - cd test
+ - git clone https://github.com/sstephenson/bats.git
+ - ./bats/bin/bats runner.bash
+
+after_success:
+ - luacov
+ - cp -v luacov.report.out ../
+ - cd ..
+ - bash <(curl -s https://codecov.io/bash)
+
+notifications:
+ email:
+ on_success: change
+ on_failure: always
diff --git a/tests/config/tapered/.travis/platform.sh b/tests/config/tapered/.travis/platform.sh
new file mode 100644
index 0000000..7259a7d
--- /dev/null
+++ b/tests/config/tapered/.travis/platform.sh
@@ -0,0 +1,15 @@
+if [ -z "${PLATFORM:-}" ]; then
+ PLATFORM=$TRAVIS_OS_NAME;
+fi
+
+if [ "$PLATFORM" == "osx" ]; then
+ PLATFORM="macosx";
+fi
+
+if [ -z "$PLATFORM" ]; then
+ if [ "$(uname)" == "Linux" ]; then
+ PLATFORM="linux";
+ else
+ PLATFORM="macosx";
+ fi;
+fi
diff --git a/tests/config/tapered/.travis/setenv_lua.sh b/tests/config/tapered/.travis/setenv_lua.sh
new file mode 100644
index 0000000..8d8c825
--- /dev/null
+++ b/tests/config/tapered/.travis/setenv_lua.sh
@@ -0,0 +1,3 @@
+export PATH=${PATH}:$HOME/.lua:$HOME/.local/bin:${TRAVIS_BUILD_DIR}/install/luarocks/bin
+bash .travis/setup_lua.sh
+eval `$HOME/.lua/luarocks path`
diff --git a/tests/config/tapered/.travis/setup_lua.sh b/tests/config/tapered/.travis/setup_lua.sh
new file mode 100644
index 0000000..a72b6d2
--- /dev/null
+++ b/tests/config/tapered/.travis/setup_lua.sh
@@ -0,0 +1,122 @@
+#! /bin/bash
+
+# A script for setting up environment for travis-ci testing.
+# Sets up Lua and Luarocks.
+# LUA must be "lua5.1", "lua5.2" or "luajit".
+# luajit2.0 - master v2.0
+# luajit2.1 - master v2.1
+
+set -eufo pipefail
+
+LUAJIT_VERSION="2.0.4"
+LUAJIT_BASE="LuaJIT-$LUAJIT_VERSION"
+
+source .travis/platform.sh
+
+LUA_HOME_DIR=$TRAVIS_BUILD_DIR/install/lua
+
+LR_HOME_DIR=$TRAVIS_BUILD_DIR/install/luarocks
+
+mkdir $HOME/.lua
+
+LUAJIT="no"
+
+if [ "$PLATFORM" == "macosx" ]; then
+ if [ "$LUA" == "luajit" ]; then
+ LUAJIT="yes";
+ fi
+ if [ "$LUA" == "luajit2.0" ]; then
+ LUAJIT="yes";
+ fi
+ if [ "$LUA" == "luajit2.1" ]; then
+ LUAJIT="yes";
+ fi;
+elif [ "$(expr substr $LUA 1 6)" == "luajit" ]; then
+ LUAJIT="yes";
+fi
+
+mkdir -p "$LUA_HOME_DIR"
+
+if [ "$LUAJIT" == "yes" ]; then
+
+ if [ "$LUA" == "luajit" ]; then
+ curl --location https://github.com/LuaJIT/LuaJIT/archive/v$LUAJIT_VERSION.tar.gz | tar xz;
+ else
+ git clone https://github.com/LuaJIT/LuaJIT.git $LUAJIT_BASE;
+ fi
+
+ cd $LUAJIT_BASE
+
+ if [ "$LUA" == "luajit2.1" ]; then
+ git checkout v2.1;
+ # force the INSTALL_TNAME to be luajit
+ perl -i -pe 's/INSTALL_TNAME=.+/INSTALL_TNAME= luajit/' Makefile
+ fi
+
+ make && make install PREFIX="$LUA_HOME_DIR"
+
+ ln -s $LUA_HOME_DIR/bin/luajit $HOME/.lua/luajit
+ ln -s $LUA_HOME_DIR/bin/luajit $HOME/.lua/lua;
+
+else
+
+ if [ "$LUA" == "lua5.1" ]; then
+ curl http://www.lua.org/ftp/lua-5.1.5.tar.gz | tar xz
+ cd lua-5.1.5;
+ elif [ "$LUA" == "lua5.2" ]; then
+ curl http://www.lua.org/ftp/lua-5.2.4.tar.gz | tar xz
+ cd lua-5.2.4;
+ elif [ "$LUA" == "lua5.3" ]; then
+ curl http://www.lua.org/ftp/lua-5.3.4.tar.gz | tar xz
+ cd lua-5.3.4;
+ fi
+
+ # Build Lua without backwards compatibility for testing
+ perl -i -pe 's/-DLUA_COMPAT_(ALL|5_2)//' src/Makefile
+ make $PLATFORM
+ make INSTALL_TOP="$LUA_HOME_DIR" install;
+
+ ln -s $LUA_HOME_DIR/bin/lua $HOME/.lua/lua
+ ln -s $LUA_HOME_DIR/bin/luac $HOME/.lua/luac;
+
+fi
+
+cd $TRAVIS_BUILD_DIR
+
+lua -v
+
+LUAROCKS_BASE=luarocks-$LUAROCKS
+
+curl --location http://luarocks.org/releases/$LUAROCKS_BASE.tar.gz | tar xz
+
+cd $LUAROCKS_BASE
+
+if [ "$LUA" == "luajit" ]; then
+ ./configure --lua-suffix=jit --with-lua-include="$LUA_HOME_DIR/include/luajit-2.0" --prefix="$LR_HOME_DIR";
+elif [ "$LUA" == "luajit2.0" ]; then
+ ./configure --lua-suffix=jit --with-lua-include="$LUA_HOME_DIR/include/luajit-2.0" --prefix="$LR_HOME_DIR";
+elif [ "$LUA" == "luajit2.1" ]; then
+ ./configure --lua-suffix=jit --with-lua-include="$LUA_HOME_DIR/include/luajit-2.1" --prefix="$LR_HOME_DIR";
+else
+ ./configure --with-lua="$LUA_HOME_DIR" --prefix="$LR_HOME_DIR"
+fi
+
+make build && make install
+
+ln -s $LR_HOME_DIR/bin/luarocks $HOME/.lua/luarocks
+
+cd $TRAVIS_BUILD_DIR
+
+luarocks --version
+
+rm -rf $LUAROCKS_BASE
+
+if [ "$LUAJIT" == "yes" ]; then
+ rm -rf $LUAJIT_BASE;
+elif [ "$LUA" == "lua5.1" ]; then
+ rm -rf lua-5.1.5;
+elif [ "$LUA" == "lua5.2" ]; then
+ rm -rf lua-5.2.4;
+elif [ "$LUA" == "lua5.3" ]; then
+ rm -rf lua-5.3.4;
+fi
diff --git a/tests/config/tapered/CHANGES.md b/tests/config/tapered/CHANGES.md
new file mode 100644
index 0000000..63b19b0
--- /dev/null
+++ b/tests/config/tapered/CHANGES.md
@@ -0,0 +1,70 @@
+# tapered version history
+
+## *1.0-0* (July 10, 2015)
+
++ Initial public release
+
+## *1.0-1* (July 10, 2015)
+
++ Fix rockspec: the URL for Bitbucket was wrong.
+
+## *1.1-0* (July 13, 2015)
+
++ Improve organization and coverage of tests
++ Refactor the `same` method
++ Remove `same_mt`
++ Meaningful exit statuses via `done`
++ Add CI via [drone.io][dio]
+
+[dio]: https://drone.io/bitbucket.org/telemachus/tapered/latest
+
+## *1.2.0-1* (July 19, 2015)
+
++ Clean up code using luacheck and luacov
++ Small tweaks to README and CHANGES
++ Fix version number: the previous two digit number was a mistake, based on
+ a misunderstanding of LuaRocks conventions. This is an annoying switch, but
+ better now than later. And better to do it than to live with a versioning
+ pattern I dislike.
+
+## *1.2.1-1* (December 5, 2015)
+
++ Test coverage stats are now thanks to [codecov][codecov].
++ Latest stable Lua in the 5.3 series is 5.3.2, so we test against that now.
+
+[codecov]: https://codecov.io
+
+## *2.0.0-1* (May 1, 2016)
+
++ The informational fields are now functions that return strings. This is to prevent them from violating Lua recommendations about variables such as `_VERSION`. (I've bumped the major version number since this is technically an API change, though for most users it will not require any changes on their end.)
+
+## *2.0.1-1* (May 2, 2016)
+
++ Fix a typo in the documentation.
++ Adjust the `version()` return value to show only software version, not the rockspec version as well.
+
+## *2.1.0-1* (July 21, 2016)
+
++ Update to test against Lua 5.3.3
+
+## *2.2.0-1* (February 11, 2017)
+
++ Update to test against Lua 5.3.4
++ The repo is now housed on [Github](https://github.com/telemachus/tapered)
++ CI is now provided by [Travis.ci](https://travis-ci.org/telemachus/tapered)
+
+## *2.3.0-1* (October 15, 2017)
+
++ Remove `setup()` and `teardown()`
++ Update to use luarocks 2.4.3 for testing on Travis
+
+Would you rather view the [documentation][d]?
+
+[d]: /README.md
+
+---
+
+(c) 2012-2017 Peter Aronoff. BSD 3-Clause license; see [LICENSE.md][l] for
+details.
+
+[l]: /LICENSE.md
diff --git a/tests/config/tapered/LICENSE.md b/tests/config/tapered/LICENSE.md
new file mode 100644
index 0000000..bcaacde
--- /dev/null
+++ b/tests/config/tapered/LICENSE.md
@@ -0,0 +1,27 @@
+Copyright (c) 2012-2017, Peter Aronoff All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+3. Neither the name of the copyright holder nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
diff --git a/tests/config/tapered/README.md b/tests/config/tapered/README.md
new file mode 100644
index 0000000..bafb2e7
--- /dev/null
+++ b/tests/config/tapered/README.md
@@ -0,0 +1,116 @@
+# tapered [![Build Status](https://travis-ci.org/telemachus/tapered.svg?branch=master)](https://travis-ci.org/telemachus/tapered) [![Coverage](https://codecov.io/gh/telemachus/tapered/branch/master/graph/badge.svg)](https://codecov.io/gh/telemachus/tapered)
+
+## Synopsis
+
+Very minimal tap testing for Lua. Arguably too minimal.
+
+## Assertions
+
+The `message` parameter is always optional. Brief messages help make test output
+clearer to readers, but are not needed if the output goes straight to another
+program for parsing.
+
++ `ok(expression, [message])` Tests whether `expression` returns a truthy
+ value.
+
++ `nok(expression, [message])` Tests whether `expression` returns a falsy
+ value.
+
++ `is(actual, expected, [message])` Tests whether `actual` is equal to
+ `expected`. The test uses `==` internally.
+
++ `isnt(actual, expected, [message])` Tests whether `actual` is not equal to
+ `actual`. The test uses `~=` internally.
+
++ `same(actual, expected, [message])` Tests whether `actual` is a deep copy
+ of `expected`. The test uses an `__eq` metamethod if one is found. Useful
+ for comparing tables.
+
++ `like(string, pattern, [message])` Tests whether `string` matches the given
+ `pattern`.
+
++ `unlike(string, pattern, [message])` Tests whether `string` does not match
+ the given `pattern`.
+
++ `pass([message])` A test that always passes. Useful as a quasi-skip with a
+ message.
+
++ `fail([message])` A test that always fails. Useful as a quasi-TODO with a
+ message.
+
++ `boom(function, args, [message])` Calls `function` with `args` as
+ parameters and checks to see if an exception is raised. Passes if an
+ exception is raised; fails otherwise. (The exception is swallowed.) The
+ `args` parameter expects a table. The table can be empty but not `nil`.
+
+## Helper method
+
+A method is available to show how many tests were run. (This output
+is required for [TAP compliance][tap], which may matter in some cases.)
+
+[tap]: http://testanything.org/tap-specification.html
+
++ `done([number])` Call this function (optionally) at the end of your test file.
+ It will print out a line in the form `1..n` where `n` is the total number
+ of tests run. This secures TAP compliance when needed. The call to `done`
+ is not otherwise required. If you don't care about TAP compliance, neither does
+ the library. If you pass the optional parameter to the method, it will check
+ whether the number of tests you expected matches the number of actual tests.
+ Thus, if can function like a traditional `plan` method. However, this method
+ should always be called *last* in your tap file, unlike `plan` methods which
+ normally start the test file.
+
+ Another reason to use `done` is if you care about the exit status of the
+ tests. Many continuous integration tools rely on tests signalling success or
+ failure via their exit status. After `done` is called, the script will exit
+ with a status of 0, indicating success, if all tests passed. If some tests
+ failed, the script will exit with a status equal to the number of failed
+ tests, indicating failure. A script will also exit with an error status if
+ there is a mismatch between the actual number of tests run and the number
+ passed to `done` as a parameter.
+
+## Varia
+
+The module provides four informational functions that return strings. They
+should be self-explanatory.
+
++ `version() -- 2.3.0`
+
++ `author() -- Peter Aronoff`
+
++ `url() -- https://github.com/telemachus/tapered.git`
+
++ `license() -- BSD 3-Clause`
+
+## Credits
+
+For the `same` method I took ideas and code from [Penlight][p], [Underscore][u],
+[luassert][l], and [cwtest][cw]. I thank all the people who worked on those.
+
+Indirect inspirations include [knock][k], [Test::More][tm], and [bats][b]—not so
+much for code as for ideas about testing and simplicity.
+
+Thanks in particular to [Pierre Chapuis][pchapuis] for help with ideas and
+getting continuous integration for tapered.
+
+An anonymous email showed me that my setup and teardown methods had a logical
+flaw. As a result, I've removed those methods. I appreciate the report.
+
+All the mistakes are mine. See [version history][c] for release details.
+
+[p]: https://github.com/stevedonovan/Penlight
+[u]: https://github.com/mirven/underscore.lua
+[l]: https://github.com/Olivine-Labs/luassert
+[cw]: https://github.com/catwell/cwtest
+[k]: https://github.com/chneukirchen/knock
+[tm]: http://search.cpan.org/perldoc?Test::More
+[b]: https://github.com/sstephenson/bats
+[c]: /CHANGES.md
+[pchapuis]: https://twitter.com/pchapuis
+
+---
+
+(c) 2012-2017 Peter Aronoff. BSD 3-Clause license; see [LICENSE.md][li] for
+details.
+
+[li]: /LICENSE.md
diff --git a/tests/config/tapered/doc/changes.html b/tests/config/tapered/doc/changes.html
new file mode 100644
index 0000000..a4f7034
--- /dev/null
+++ b/tests/config/tapered/doc/changes.html
@@ -0,0 +1,104 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<meta name="author" content="Peter Aronoff">
+<title>tapered version history</title>
+<link rel="stylesheet" href="normalize.css" media="screen,projection">
+<link rel="stylesheet" href="screen.css" media="screen,projection">
+</head>
+<body>
+<h1>tapered version history</h1>
+
+<h2><em>1.0-0</em> (July 10, 2015)</h2>
+
+<ul>
+<li>Initial public release</li>
+</ul>
+
+
+<h2><em>1.0-1</em> (July 10, 2015)</h2>
+
+<ul>
+<li>Fix rockspec: the URL for Bitbucket was wrong.</li>
+</ul>
+
+
+<h2><em>1.1-0</em> (July 13, 2015)</h2>
+
+<ul>
+<li>Improve organization and coverage of tests</li>
+<li>Refactor the <code>same</code> method</li>
+<li>Remove <code>same_mt</code></li>
+<li>Meaningful exit statuses via <code>done</code></li>
+<li>Add CI via <a href="https://drone.io/bitbucket.org/telemachus/tapered/latest">drone.io</a></li>
+</ul>
+
+
+<h2><em>1.2.0-1</em> (July 19, 2015)</h2>
+
+<ul>
+<li>Clean up code using luacheck and luacov</li>
+<li>Small tweaks to README and CHANGES</li>
+<li>Fix version number: the previous two digit number was a mistake, based on
+a misunderstanding of LuaRocks conventions. This is an annoying switch, but
+better now than later. And better to do it than to live with a versioning
+pattern I dislike.</li>
+</ul>
+
+
+<h2><em>1.2.1-1</em> (December 5, 2015)</h2>
+
+<ul>
+<li>Test coverage stats are now thanks to <a href="https://codecov.io">codecov</a>.</li>
+<li>Latest stable Lua in the 5.3 series is 5.3.2, so we test against that now.</li>
+</ul>
+
+
+<h2><em>2.0.0-1</em> (May 1, 2016)</h2>
+
+<ul>
+<li>The informational fields are now functions that return strings. This is to prevent them from violating Lua recommendations about variables such as <code>_VERSION</code>. (I&rsquo;ve bumped the major version number since this is technically an API change, though for most users it will not require any changes on their end.)</li>
+</ul>
+
+
+<h2><em>2.0.1-1</em> (May 2, 2016)</h2>
+
+<ul>
+<li>Fix a typo in the documentation.</li>
+<li>Adjust the <code>version()</code> return value to show only software version, not the rockspec version as well.</li>
+</ul>
+
+
+<h2><em>2.1.0-1</em> (July 21, 2016)</h2>
+
+<ul>
+<li>Update to test against Lua 5.3.3</li>
+</ul>
+
+
+<h2><em>2.2.0-1</em> (February 11, 2017)</h2>
+
+<ul>
+<li>Update to test against Lua 5.3.4</li>
+<li>The repo is now housed on <a href="https://github.com/telemachus/tapered">Github</a></li>
+<li>CI is now provided by <a href="https://travis-ci.org/telemachus/tapered">Travis.ci</a></li>
+</ul>
+
+
+<h2><em>2.3.0-1</em> (October 15, 2017)</h2>
+
+<ul>
+<li>Remove <code>setup()</code> and <code>teardown()</code></li>
+<li>Update to use luarocks 2.4.3 for testing on Travis</li>
+</ul>
+
+
+<p>Would you rather view the <a href="index.html">documentation</a>?</p>
+
+<hr />
+
+<p>&copy; 2012-2017 Peter Aronoff. BSD 3-Clause license; see <a href="license.html">the license</a> for
+details.</p>
+</body>
+</html>
diff --git a/tests/config/tapered/doc/index.html b/tests/config/tapered/doc/index.html
new file mode 100644
index 0000000..69d6b24
--- /dev/null
+++ b/tests/config/tapered/doc/index.html
@@ -0,0 +1,111 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<meta name="author" content="Peter Aronoff">
+<title>tapered documentation</title>
+<link rel="stylesheet" href="normalize.css" media="screen,projection">
+<link rel="stylesheet" href="screen.css" media="screen,projection">
+</head>
+<body>
+<h1>tapered <a href="https://travis-ci.org/telemachus/tapered"><img src="https://travis-ci.org/telemachus/tapered.svg?branch=master" alt="Build Status" /></a> <a href="https://codecov.io/gh/telemachus/tapered"><img src="https://codecov.io/gh/telemachus/tapered/branch/master/graph/badge.svg" alt="Coverage" /></a></h1>
+
+<h2>Synopsis</h2>
+
+<p>Very minimal tap testing for Lua. Arguably too minimal.</p>
+
+<h2>Assertions</h2>
+
+<p>The <code>message</code> parameter is always optional. Brief messages help make test output
+clearer to readers, but are not needed if the output goes straight to another
+program for parsing.</p>
+
+<ul>
+<li><p><code>ok(expression, [message])</code> Tests whether <code>expression</code> returns a truthy
+value.</p></li>
+<li><p><code>nok(expression, [message])</code> Tests whether <code>expression</code> returns a falsy
+value.</p></li>
+<li><p><code>is(actual, expected, [message])</code> Tests whether <code>actual</code> is equal to
+<code>expected</code>. The test uses <code>==</code> internally.</p></li>
+<li><p><code>isnt(actual, expected, [message])</code> Tests whether <code>actual</code> is not equal to
+<code>actual</code>. The test uses <code>~=</code> internally.</p></li>
+<li><p><code>same(actual, expected, [message])</code> Tests whether <code>actual</code> is a deep copy
+of <code>expected</code>. The test uses an <code>__eq</code> metamethod if one is found. Useful
+for comparing tables.</p></li>
+<li><p><code>like(string, pattern, [message])</code> Tests whether <code>string</code> matches the given
+<code>pattern</code>.</p></li>
+<li><p><code>unlike(string, pattern, [message])</code> Tests whether <code>string</code> does not match
+the given <code>pattern</code>.</p></li>
+<li><p><code>pass([message])</code> A test that always passes. Useful as a quasi-skip with a
+message.</p></li>
+<li><p><code>fail([message])</code> A test that always fails. Useful as a quasi-TODO with a
+message.</p></li>
+<li><p><code>boom(function, args, [message])</code> Calls <code>function</code> with <code>args</code> as
+parameters and checks to see if an exception is raised. Passes if an
+exception is raised; fails otherwise. (The exception is swallowed.) The
+<code>args</code> parameter expects a table. The table can be empty but not <code>nil</code>.</p></li>
+</ul>
+
+
+<h2>Helper method</h2>
+
+<p>A method is available to show how many tests were run. (This output
+is required for <a href="http://testanything.org/tap-specification.html">TAP compliance</a>, which may matter in some cases.)</p>
+
+<ul>
+<li><p><code>done([number])</code> Call this function (optionally) at the end of your test file.
+It will print out a line in the form <code>1..n</code> where <code>n</code> is the total number
+of tests run. This secures TAP compliance when needed. The call to <code>done</code>
+is not otherwise required. If you don&rsquo;t care about TAP compliance, neither does
+the library. If you pass the optional parameter to the method, it will check
+whether the number of tests you expected matches the number of actual tests.
+Thus, if can function like a traditional <code>plan</code> method. However, this method
+should always be called <em>last</em> in your tap file, unlike <code>plan</code> methods which
+normally start the test file.</p>
+
+<p>Another reason to use <code>done</code> is if you care about the exit status of the
+tests. Many continuous integration tools rely on tests signalling success or
+failure via their exit status. After <code>done</code> is called, the script will exit
+with a status of 0, indicating success, if all tests passed. If some tests
+failed, the script will exit with a status equal to the number of failed
+tests, indicating failure. A script will also exit with an error status if
+there is a mismatch between the actual number of tests run and the number
+passed to <code>done</code> as a parameter.</p></li>
+</ul>
+
+
+<h2>Varia</h2>
+
+<p>The module provides four informational functions that return strings. They
+should be self-explanatory.</p>
+
+<ul>
+<li><p><code>version() -- 2.3.0</code></p></li>
+<li><p><code>author() -- Peter Aronoff</code></p></li>
+<li><p><code>url() -- https://github.com/telemachus/tapered.git</code></p></li>
+<li><p><code>license() -- BSD 3-Clause</code></p></li>
+</ul>
+
+
+<h2>Credits</h2>
+
+<p>For the <code>same</code> method I took ideas and code from <a href="https://github.com/stevedonovan/Penlight">Penlight</a>, <a href="https://github.com/mirven/underscore.lua">Underscore</a>,
+<a href="https://github.com/Olivine-Labs/luassert">luassert</a>, and <a href="https://github.com/catwell/cwtest">cwtest</a>. I thank all the people who worked on those.</p>
+
+<p>Indirect inspirations include <a href="https://github.com/chneukirchen/knock">knock</a>, <a href="http://search.cpan.org/perldoc?Test::More">Test::More</a>, and <a href="https://github.com/sstephenson/bats">bats</a>—not so
+much for code as for ideas about testing and simplicity.</p>
+
+<p>Thanks in particular to <a href="https://twitter.com/pchapuis">Pierre Chapuis</a> for help with ideas and
+getting continuous integration for tapered.</p>
+
+<p>An anonymous email showed me that my setup and teardown methods had a logical
+flaw. As a result, I&rsquo;ve removed those methods. I appreciate the report.</p>
+
+<p>All the mistakes are mine. See <a href="changes.html">version history</a> for release details.</p>
+
+<hr />
+
+<p>&copy; 2012-2017 Peter Aronoff. BSD 3-Clause license; see <a href="license.html">the license</a> for
+details.</p>
+</body>
+</html>
diff --git a/tests/config/tapered/doc/license.html b/tests/config/tapered/doc/license.html
new file mode 100644
index 0000000..7c8ae8c
--- /dev/null
+++ b/tests/config/tapered/doc/license.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<meta name="author" content="Peter Aronoff">
+<title>tapered license</title>
+<link rel="stylesheet" href="normalize.css" media="screen,projection">
+<link rel="stylesheet" href="screen.css" media="screen,projection">
+</head>
+<body>
+<p>Copyright &copy; 2012-2017, Peter Aronoff All rights reserved.</p>
+
+<p>Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:</p>
+
+<ol>
+<li><p>Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.</p></li>
+<li><p>Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.</p></li>
+<li><p>Neither the name of the copyright holder nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.</p></li>
+</ol>
+
+
+<p>THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS &ldquo;AS IS&rdquo;
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.</p>
+</body>
+</html>
diff --git a/tests/config/tapered/doc/normalize.css b/tests/config/tapered/doc/normalize.css
new file mode 100644
index 0000000..9fc7ae4
--- /dev/null
+++ b/tests/config/tapered/doc/normalize.css
@@ -0,0 +1,439 @@
+/*! normalize.css 2011-08-12T17:28 UTC · http://github.com/necolas/normalize.css */
+
+/* =============================================================================
+ HTML5 display definitions
+ ========================================================================== */
+
+/*
+ * Corrects block display not defined in IE6/7/8/9 & FF3
+ */
+
+article,
+aside,
+details,
+figcaption,
+figure,
+footer,
+header,
+hgroup,
+nav,
+section {
+ display: block;
+}
+
+/*
+ * Corrects inline-block display not defined in IE6/7/8/9 & FF3
+ */
+
+audio,
+canvas,
+video {
+ display: inline-block;
+ *display: inline;
+ *zoom: 1;
+}
+
+/*
+ * Prevents modern browsers from displaying 'audio' without controls
+ */
+
+audio:not([controls]) {
+ display: none;
+}
+
+/*
+ * Addresses styling for 'hidden' attribute not present in IE7/8/9, FF3, S4
+ * Known issue: no IE6 support
+ */
+
+[hidden] {
+ display: none;
+}
+
+
+/* =============================================================================
+ Base
+ ========================================================================== */
+
+/*
+ * 1. Corrects text resizing oddly in IE6/7 when body font-size is set using em units
+ * http://clagnut.com/blog/348/#c790
+ * 2. Keeps page centred in all browsers regardless of content height
+ * 3. Prevents iOS text size adjust after orientation change, without disabling user zoom
+ * www.456bereastreet.com/archive/201012/controlling_text_size_in_safari_for_ios_without_disabling_user_zoom/
+ */
+
+html {
+ font-size: 100%; /* 1 */
+ overflow-y: scroll; /* 2 */
+ -webkit-text-size-adjust: 100%; /* 3 */
+ -ms-text-size-adjust: 100%; /* 3 */
+}
+
+/*
+ * Addresses margins handled incorrectly in IE6/7
+ */
+
+body {
+ margin: 0;
+}
+
+/*
+ * Addresses font-family inconsistency between 'textarea' and other form elements.
+ */
+
+body,
+button,
+input,
+select,
+textarea {
+ font-family: sans-serif;
+}
+
+
+/* =============================================================================
+ Links
+ ========================================================================== */
+
+a {
+ color: #00e;
+}
+
+a:visited {
+ color: #551a8b;
+}
+
+/*
+ * Addresses outline displayed oddly in Chrome
+ */
+
+a:focus {
+ outline: thin dotted;
+}
+
+/*
+ * Improves readability when focused and also mouse hovered in all browsers
+ * people.opera.com/patrickl/experiments/keyboard/test
+ */
+
+a:hover,
+a:active {
+ outline: 0;
+}
+
+
+/* =============================================================================
+ Typography
+ ========================================================================== */
+
+/*
+ * Addresses styling not present in IE7/8/9, S5, Chrome
+ */
+
+abbr[title] {
+ border-bottom: 1px dotted;
+}
+
+/*
+ * Addresses style set to 'bolder' in FF3/4, S4/5, Chrome
+*/
+
+b,
+strong {
+ font-weight: bold;
+}
+
+blockquote {
+ margin: 1em 40px;
+}
+
+/*
+ * Addresses styling not present in S5, Chrome
+ */
+
+dfn {
+ font-style: italic;
+}
+
+/*
+ * Addresses styling not present in IE6/7/8/9
+ */
+
+mark {
+ background: #ff0;
+ color: #000;
+}
+
+/*
+ * Corrects font family set oddly in IE6, S4/5, Chrome
+ * en.wikipedia.org/wiki/User:Davidgothberg/Test59
+ */
+
+pre,
+code,
+kbd,
+samp {
+ font-family: monospace, serif;
+ _font-family: 'courier new', monospace;
+ font-size: 1em;
+}
+
+/*
+ * Improves readability of pre-formatted text in all browsers
+ */
+
+pre {
+ white-space: pre;
+ white-space: pre-wrap;
+ word-wrap: break-word;
+}
+
+/*
+ * 1. Addresses CSS quotes not supported in IE6/7
+ * 2. Addresses quote property not supported in S4
+ */
+
+/* 1 */
+
+q {
+ quotes: none;
+}
+
+/* 2 */
+
+q:before,
+q:after {
+ content: '';
+ content: none;
+}
+
+small {
+ font-size: 75%;
+}
+
+/*
+ * Prevents sub and sup affecting line-height in all browsers
+ * gist.github.com/413930
+ */
+
+sub,
+sup {
+ font-size: 75%;
+ line-height: 0;
+ position: relative;
+ vertical-align: baseline;
+}
+
+sup {
+ top: -0.5em;
+}
+
+sub {
+ bottom: -0.25em;
+}
+
+
+/* =============================================================================
+ Lists
+ ========================================================================== */
+
+ul,
+ol {
+ margin: 1em 0;
+ padding: 0 0 0 40px;
+}
+
+dd {
+ margin: 0 0 0 40px;
+}
+
+nav ul,
+nav ol {
+ list-style: none;
+ list-style-image: none;
+}
+
+
+/* =============================================================================
+ Embedded content
+ ========================================================================== */
+
+/*
+ * 1. Removes border when inside 'a' element in IE6/7/8/9
+ * 2. Improves image quality when scaled in IE7
+ * code.flickr.com/blog/2008/11/12/on-ui-quality-the-little-things-client-side-image-resizing/
+ */
+
+img {
+ border: 0; /* 1 */
+ -ms-interpolation-mode: bicubic; /* 2 */
+}
+
+/*
+ * Corrects overflow displayed oddly in IE9
+ */
+
+svg:not(:root) {
+ overflow: hidden;
+}
+
+
+/* =============================================================================
+ Figures
+ ========================================================================== */
+
+/*
+ * Addresses margin not present in IE6/7/8/9, S5, O11
+ */
+
+figure {
+ margin: 0;
+}
+
+
+/* =============================================================================
+ Forms
+ ========================================================================== */
+
+/*
+ * Corrects margin displayed oddly in IE6/7
+ */
+
+form {
+ margin: 0;
+}
+
+/*
+ * Define consistent margin and padding
+ */
+
+fieldset {
+ margin: 0 2px;
+ padding: 0.35em 0.625em 0.75em;
+}
+
+/*
+ * 1. Corrects color not being inherited in IE6/7/8/9
+ * 2. Corrects alignment displayed oddly in IE6/7
+ */
+
+legend {
+ border: 0; /* 1 */
+ *margin-left: -7px; /* 2 */
+}
+
+/*
+ * 1. Corrects font size not being inherited in all browsers
+ * 2. Addresses margins set differently in IE6/7, F3/4, S5, Chrome
+ * 3. Improves appearance and consistency in all browsers
+ */
+
+button,
+input,
+select,
+textarea {
+ font-size: 100%; /* 1 */
+ margin: 0; /* 2 */
+ vertical-align: baseline; /* 3 */
+ *vertical-align: middle; /* 3 */
+}
+
+/*
+ * 1. Addresses FF3/4 setting line-height using !important in the UA stylesheet
+ * 2. Corrects inner spacing displayed oddly in IE6/7
+ */
+
+button,
+input {
+ line-height: normal; /* 1 */
+ *overflow: visible; /* 2 */
+}
+
+/*
+ * Corrects overlap and whitespace issue for buttons and inputs in IE6/7
+ * Known issue: reintroduces inner spacing
+ */
+
+table button,
+table input {
+ *overflow: auto;
+}
+
+/*
+ * 1. Improves usability and consistency of cursor style between image-type 'input' and others
+ * 2. Corrects inability to style clickable 'input' types in iOS
+ */
+
+button,
+html input[type="button"],
+input[type="reset"],
+input[type="submit"] {
+ cursor: pointer; /* 1 */
+ -webkit-appearance: button; /* 2 */
+}
+
+/*
+ * 1. Addresses box sizing set to content-box in IE8/9
+ * 2. Addresses excess padding in IE8/9
+ */
+
+input[type="checkbox"],
+input[type="radio"] {
+ box-sizing: border-box; /* 1 */
+ padding: 0; /* 2 */
+}
+
+/*
+ * 1. Addresses appearance set to searchfield in S5, Chrome
+ * 2. Addresses box sizing set to border-box in S5, Chrome (include -moz to future-proof)
+ */
+
+input[type="search"] {
+ -webkit-appearance: textfield; /* 1 */
+ -moz-box-sizing: content-box;
+ -webkit-box-sizing: content-box; /* 2 */
+ box-sizing: content-box;
+}
+
+/*
+ * Corrects inner padding displayed oddly in S5, Chrome on OSX
+ */
+
+input[type="search"]::-webkit-search-decoration {
+ -webkit-appearance: none;
+}
+
+/*
+ * Corrects inner padding and border displayed oddly in FF3/4
+ * www.sitepen.com/blog/2008/05/14/the-devils-in-the-details-fixing-dojos-toolbar-buttons/
+ */
+
+button::-moz-focus-inner,
+input::-moz-focus-inner {
+ border: 0;
+ padding: 0;
+}
+
+/*
+ * 1. Removes default vertical scrollbar in IE6/7/8/9
+ * 2. Improves readability and alignment in all browsers
+ */
+
+textarea {
+ overflow: auto; /* 1 */
+ vertical-align: top; /* 2 */
+}
+
+
+/* =============================================================================
+ Tables
+ ========================================================================== */
+
+/*
+ * Remove most spacing between table cells
+ */
+
+table {
+ border-collapse: collapse;
+ border-spacing: 0;
+}
diff --git a/tests/config/tapered/doc/screen.css b/tests/config/tapered/doc/screen.css
new file mode 100644
index 0000000..2583183
--- /dev/null
+++ b/tests/config/tapered/doc/screen.css
@@ -0,0 +1,109 @@
+body {
+ margin: 10px auto;
+ width: 820px;
+ font-size: 18px;
+ font-family: "DejaVuSerifBook", "Palatino", "Palatino Linotype", serif;
+ color: #333;
+}
+
+h1, h2, h3, h4, h5, h6 {
+ font-family: "DejaVuSansBook", "Lucida Grande", "Helvetica Neue", sans-serif;
+ font-weight: bold;
+ line-height: 1.6;
+ margin-bottom: 5px;
+ color: #111;
+}
+
+h1 {
+ margin-top: 10px;
+}
+
+h2, h3, h4, h5, h6 { margin-top: 20px; }
+
+h1 { font-size: 28px; }
+
+h2 { font-size: 24px; border-bottom: solid 4px; }
+h3 { font-size: 20px; }
+
+p {
+ line-height: 1.3;
+ margin: 12px auto;
+
+}
+
+code {
+ font-family: "DejaVuSansMono", Inconsolata, Consolas, Menlo, monospace;
+}
+
+blockquote {
+ margin: 10px 30px 10px 20px;
+}
+
+blockquote p {
+ line-height: 1.2;
+}
+
+ul, ol, ul p, ol p {
+ margin-left: 0;
+ line-height: 1.3;
+}
+
+ul ul, ol ol {
+ font-size: 100%;
+}
+
+ul {
+ list-style-type: disc;
+}
+
+ul ul {
+ list-style-type: circle;
+}
+
+ul ul ul {
+ list-style-type: square;
+}
+
+ul ul ul ul {
+ list-style-type: disc;
+}
+
+h2 + p {
+ margin-top: 15px;
+}
+
+a:link, a:visited {
+ text-decoration: underline;
+ color: #336891;
+}
+
+a:hover, a:focus {
+ text-decoration: none;
+ color: #336891;
+}
+
+pre {
+ margin: 30px 15px;
+ padding: 10px 5px 10px 15px;
+ border: solid black 5px;
+ border-left: solid black 30px;
+ font-size: 14px;
+ line-height: 1.3;
+ background: #FFF;
+ color: #000;
+ -moz-border-radius: 5px;
+ -webkit-border-radius: 5px;
+ border-radius: 5px;
+}
+
+ins {
+ text-decoration: none;
+}
+
+ins:before {
+ content: "〈";
+}
+
+ins:after {
+ content: "〉";
+}
diff --git a/tests/config/tapered/make-doc.bash b/tests/config/tapered/make-doc.bash
new file mode 100755
index 0000000..4ceb65d
--- /dev/null
+++ b/tests/config/tapered/make-doc.bash
@@ -0,0 +1,55 @@
+#!/usr/bin/env bash
+
+{
+ printf "<!DOCTYPE html>\n"
+ printf "<html lang=\"en\">\n"
+ printf "<head>\n"
+ printf "<meta charset=\"utf-8\">\n"
+ printf "<meta name=\"author\" content=\"Peter Aronoff\">\n"
+ printf "<title>tapered documentation</title>\n"
+ printf "<link rel=\"stylesheet\" href=\"normalize.css\" "
+ printf "media=\"screen,projection\">\n"
+ printf "<link rel=\"stylesheet\" href=\"screen.css\" "
+ printf "media=\"screen,projection\">\n"
+ printf "</head>\n"
+ printf "<body>\n"
+ markdown README.md | sed -e 's/\/CHANGES.md/changes.html/' -e 's/\/LICENSE.md/license.html/' -e 's/LICENSE.md/the license/'
+ printf "</body>\n"
+ printf "</html>\n"
+} > doc/index.html
+
+{
+ printf "<!DOCTYPE html>\n"
+ printf "<html lang=\"en\">\n"
+ printf "<head>\n"
+ printf "<meta charset=\"utf-8\">\n"
+ printf "<meta name=\"author\" content=\"Peter Aronoff\">\n"
+ printf "<title>tapered version history</title>\n"
+ printf "<link rel=\"stylesheet\" href=\"normalize.css\" "
+ printf "media=\"screen,projection\">\n"
+ printf "<link rel=\"stylesheet\" href=\"screen.css\" "
+ printf "media=\"screen,projection\">\n"
+ printf "</head>\n"
+ printf "<body>\n"
+ markdown CHANGES.md | sed -e 's/\/README.md/index.html/' -e 's/\/LICENSE.md/license.html/' -e 's/LICENSE.md/the license/'
+ printf "</body>\n"
+ printf "</html>\n"
+} > doc/changes.html
+
+{
+ printf "<!DOCTYPE html>\n"
+ printf "<html lang=\"en\">\n"
+ printf "<head>\n"
+ printf "<meta charset=\"utf-8\">\n"
+ printf "<meta name=\"author\" content=\"Peter Aronoff\">\n"
+ printf "<title>tapered license</title>\n"
+ printf "<link rel=\"stylesheet\" href=\"normalize.css\" "
+ printf "media=\"screen,projection\">\n"
+ printf "<link rel=\"stylesheet\" href=\"screen.css\" "
+ printf "media=\"screen,projection\">\n"
+ printf "</head>\n"
+ printf "<body>\n"
+ markdown LICENSE.md
+ printf "</body>\n"
+ printf "</html>\n"
+} > doc/license.html
diff --git a/tests/config/tapered/src/tapered.lua b/tests/config/tapered/src/tapered.lua
new file mode 100644
index 0000000..de648c2
--- /dev/null
+++ b/tests/config/tapered/src/tapered.lua
@@ -0,0 +1,205 @@
+-- vim: et:ts=2:sw=2
+-- Helper variables and functions
+local get_info = debug.getinfo
+local pcall = pcall
+local slice = string.sub
+local sprintf = string.format
+local str_find = string.find
+local tonumber = tonumber
+-- Lua 5.3 moved unpack to table.unpack
+local unpack = unpack or table.unpack
+local write = io.write
+local rawget = rawget
+local getmetatable = getmetatable
+local exit = os.exit
+local krprint = require("krprint")
+
+---- Helper methods
+
+--- C-like printf method
+local printf = function(fmt, ...)
+ write(sprintf(fmt, ...))
+end
+
+local printdiff = function(func_name, actual, expected)
+ printf("Assertion %s() failed for test below (marked 'not ok'):\n", func_name)
+ printf("Expected: %s\n", krprint.pprint(expected))
+ printf("Got: %s\n", krprint.pprint(actual))
+end
+
+--- Compare potentially complex tables or objects
+--
+-- Ideas here are taken from [Penlight][p], [Underscore][u], [cwtest][cw], and
+-- [luassert][l].
+-- [p]: https://github.com/stevedonovan/Penlight
+-- [u]: https://github.com/mirven/underscore.lua
+-- [cw]: https://github.com/catwell/cwtest
+-- [l]: https://github.com/Olivine-Labs/luassert
+--
+-- Predeclare both function names
+local keyvaluesame
+local deepsame
+--
+--- keyvaluesame(table, table) => true or false
+-- Helper method to compare all the keys and values of a table
+keyvaluesame = function (t1, t2)
+ for k1, v1 in pairs(t1) do
+ local v2 = t2[k1]
+ if v2 == nil or not deepsame(v1, v2) then return false end
+ end
+
+ -- Check for any keys present in t2 but not t1
+ for k2, _ in pairs(t2) do
+ if t1[k2] == nil then return false end
+ end
+
+ return true
+end
+--
+--- deepsame(item, item) => true or false
+-- Compare two items of any type for identity
+deepsame = function (t1, t2)
+ local ty1, ty2 = type(t1), type(t2)
+ if ty1 ~= ty2 then return false end
+ if ty1 ~= 'table' then return t1 == t2 end
+
+ -- If ._eq is found, use == and end quickly.
+ -- As of Lua 5.3 == only cares if **one** of the two items has a __eq
+ -- metamethod. Penlight, underscore and cwtest take the same approach,
+ -- so I will as well.
+ local eq = rawget(getmetatable(t1) or {}, '__eq')
+ if (type(eq) == 'function') then
+ return not not eq(t1, t2)
+ else
+ return keyvaluesame(t1, t2)
+ end
+end
+
+---- tapered test suite
+
+local exit_status = 0
+local test_count = 0
+local debug_level = 3
+
+-- All other tests are defined in terms of this primitive, which is
+-- kept private.
+local _test = function (exp, msg)
+ test_count = test_count + 1
+
+ if msg then
+ msg = sprintf(" - %s", msg)
+ else
+ msg = ''
+ end
+
+ if exp then
+ printf("ok %s%s\n", test_count, msg)
+ else
+ exit_status = 1 + exit_status
+ printf("not ok %s%s\n", test_count, msg)
+ local info = get_info(debug_level)
+ printf("# Trouble in %s around line %s\n",
+ slice(info.source, 2), info.currentline)
+ end
+end
+
+local ok = function (expression, msg)
+ _test(expression, msg)
+end
+
+local nok = function (expression, msg)
+ _test(not expression, msg)
+end
+
+local is = function (actual, expected, msg)
+ local result = actual == expected;
+ if not result then
+ printdiff("is", actual, expected)
+ end
+ _test(result, msg)
+end
+
+local isnt = function (actual, expected, msg)
+ _test(actual ~= expected, msg)
+end
+
+local same = function (actual, expected, msg)
+ local result = deepsame(actual, expected)
+ if not result then
+ printdiff("same", actual, expected)
+ end
+ _test(result, msg)
+end
+
+local like = function (str, pattern, msg)
+ _test(str_find(str, pattern), msg)
+end
+
+local unlike = function (str, pattern, msg)
+ _test(not str_find(str, pattern), msg)
+end
+
+local pass = function (msg)
+ _test(true, msg)
+end
+
+local fail = function (msg)
+ _test(false, msg)
+end
+
+local boom = function (func, args, msg)
+ local err, errmsg
+ err, errmsg = pcall(func, unpack(args))
+ _test(not err, msg)
+ if not err and type(errmsg) == 'string' then
+ printf('# Got this error: "%s"\n', errmsg)
+ end
+end
+
+local done = function (n)
+ local expected = tonumber(n)
+ if not expected or test_count == expected then
+ printf('1..%d\n', test_count)
+ elseif expected ~= test_count then
+ exit_status = 1 + exit_status
+ local s
+ if expected == 1 then s = '' else s = 's' end
+ printf("# Bad plan. You planned %d test%s but ran %d\n",
+ expected, s, test_count)
+ end
+ exit(exit_status)
+end
+
+local version = function ()
+ return "2.3.0"
+end
+
+local author = function ()
+ return "Peter Aronoff"
+end
+
+local url = function ()
+ return "https://github.com/telemachus/tapered"
+end
+
+local license = function ()
+ return "BSD 3-Clause"
+end
+
+return {
+ ok = ok,
+ nok = nok,
+ is = is,
+ isnt = isnt,
+ same = same,
+ like = like,
+ unlike = unlike,
+ pass = pass,
+ fail = fail,
+ boom = boom,
+ done = done,
+ version = version,
+ author = author,
+ url = url,
+ license = license
+}
diff --git a/tests/config/tapered/tapered-1.1-0.rockspec b/tests/config/tapered/tapered-1.1-0.rockspec
new file mode 100644
index 0000000..d6dea7d
--- /dev/null
+++ b/tests/config/tapered/tapered-1.1-0.rockspec
@@ -0,0 +1,21 @@
+package = 'tapered'
+version = '1.1-0'
+source = {
+ url = 'https://bitbucket.org/telemachus/tapered/downloads/tapered-v1.1-0.tar.gz',
+ dir = 'tapered',
+}
+description = {
+ summary = 'Very minimal tap testing for Lua.',
+ detailed = [[
+ Very minimal tap testing for Lua. Arguably too minimal.
+ ]],
+ license = 'BSD 3-Clause'
+}
+dependencies = {
+ 'lua >= 5.1'
+}
+build = {
+ type = 'builtin',
+ modules = { tapered = 'src/tapered.lua' },
+ copy_directories = { 'doc' }
+}
diff --git a/tests/config/tapered/tapered-1.2.0-1.rockspec b/tests/config/tapered/tapered-1.2.0-1.rockspec
new file mode 100644
index 0000000..5e6c364
--- /dev/null
+++ b/tests/config/tapered/tapered-1.2.0-1.rockspec
@@ -0,0 +1,21 @@
+package = 'tapered'
+version = '1.2.0-1'
+source = {
+ url = 'https://bitbucket.org/telemachus/tapered/downloads/tapered-v1.2.0-1.tar.gz',
+ dir = 'tapered',
+}
+description = {
+ summary = 'Very minimal tap testing for Lua.',
+ detailed = [[
+ Very minimal tap testing for Lua. Arguably too minimal.
+ ]],
+ license = 'BSD 3-Clause'
+}
+dependencies = {
+ 'lua >= 5.1'
+}
+build = {
+ type = 'builtin',
+ modules = { tapered = 'src/tapered.lua' },
+ copy_directories = { 'doc' }
+}
diff --git a/tests/config/tapered/tapered-1.2.1-1.rockspec b/tests/config/tapered/tapered-1.2.1-1.rockspec
new file mode 100644
index 0000000..673e1af
--- /dev/null
+++ b/tests/config/tapered/tapered-1.2.1-1.rockspec
@@ -0,0 +1,21 @@
+package = 'tapered'
+version = '1.2.1-1'
+source = {
+ url = 'https://bitbucket.org/telemachus/tapered/downloads/tapered-v1.2.1-1.tar.gz',
+ dir = 'tapered',
+}
+description = {
+ summary = 'Very minimal tap testing for Lua.',
+ detailed = [[
+ Very minimal tap testing for Lua. Arguably too minimal.
+ ]],
+ license = 'BSD 3-Clause'
+}
+dependencies = {
+ 'lua >= 5.1'
+}
+build = {
+ type = 'builtin',
+ modules = { tapered = 'src/tapered.lua' },
+ copy_directories = { 'doc' }
+}
diff --git a/tests/config/tapered/tapered-2.0.0-1.rockspec b/tests/config/tapered/tapered-2.0.0-1.rockspec
new file mode 100644
index 0000000..5e5484a
--- /dev/null
+++ b/tests/config/tapered/tapered-2.0.0-1.rockspec
@@ -0,0 +1,21 @@
+package = 'tapered'
+version = '2.0.0-1'
+source = {
+ url = 'https://bitbucket.org/telemachus/tapered/downloads/tapered-v2.0.0-1.tar.gz',
+ dir = 'tapered',
+}
+description = {
+ summary = 'Very minimal tap testing for Lua.',
+ detailed = [[
+ Very minimal tap testing for Lua. Arguably too minimal.
+ ]],
+ license = 'BSD 3-Clause'
+}
+dependencies = {
+ 'lua >= 5.1'
+}
+build = {
+ type = 'builtin',
+ modules = { tapered = 'src/tapered.lua' },
+ copy_directories = { 'doc' }
+}
diff --git a/tests/config/tapered/tapered-2.0.1-1.rockspec b/tests/config/tapered/tapered-2.0.1-1.rockspec
new file mode 100644
index 0000000..1127375
--- /dev/null
+++ b/tests/config/tapered/tapered-2.0.1-1.rockspec
@@ -0,0 +1,21 @@
+package = 'tapered'
+version = '2.0.1-1'
+source = {
+ url = 'https://bitbucket.org/telemachus/tapered/downloads/tapered-v2.0.1-1.tar.gz',
+ dir = 'tapered',
+}
+description = {
+ summary = 'Very minimal tap testing for Lua.',
+ detailed = [[
+ Very minimal tap testing for Lua. Arguably too minimal.
+ ]],
+ license = 'BSD 3-Clause'
+}
+dependencies = {
+ 'lua >= 5.1'
+}
+build = {
+ type = 'builtin',
+ modules = { tapered = 'src/tapered.lua' },
+ copy_directories = { 'doc' }
+}
diff --git a/tests/config/tapered/tapered-2.1.0-1.rockspec b/tests/config/tapered/tapered-2.1.0-1.rockspec
new file mode 100644
index 0000000..f14c756
--- /dev/null
+++ b/tests/config/tapered/tapered-2.1.0-1.rockspec
@@ -0,0 +1,21 @@
+package = 'tapered'
+version = '2.1.0-1'
+source = {
+ url = 'https://bitbucket.org/telemachus/tapered/downloads/tapered-v2.1.0-1.tar.gz',
+ dir = 'tapered',
+}
+description = {
+ summary = 'Very minimal tap testing for Lua.',
+ detailed = [[
+ Very minimal tap testing for Lua. Arguably too minimal.
+ ]],
+ license = 'BSD 3-Clause'
+}
+dependencies = {
+ 'lua >= 5.1'
+}
+build = {
+ type = 'builtin',
+ modules = { tapered = 'src/tapered.lua' },
+ copy_directories = { 'doc' }
+}
diff --git a/tests/config/tapered/tapered-2.2.0-1.rockspec b/tests/config/tapered/tapered-2.2.0-1.rockspec
new file mode 100644
index 0000000..cfb8b51
--- /dev/null
+++ b/tests/config/tapered/tapered-2.2.0-1.rockspec
@@ -0,0 +1,22 @@
+package = 'tapered'
+version = '2.2.0-1'
+source = {
+ url = 'git://github.com/telemachus/tapered.git',
+ branch = 'master',
+ tag = 'v2.2.0-1'
+}
+description = {
+ summary = 'Very minimal tap testing for Lua.',
+ detailed = [[
+ Very minimal tap testing for Lua. Arguably too minimal.
+ ]],
+ license = 'BSD 3-Clause'
+}
+dependencies = {
+ 'lua >= 5.1'
+}
+build = {
+ type = 'builtin',
+ modules = { tapered = 'src/tapered.lua' },
+ copy_directories = { 'doc' }
+}
diff --git a/tests/config/tapered/tapered-2.3.0-1.rockspec b/tests/config/tapered/tapered-2.3.0-1.rockspec
new file mode 100644
index 0000000..b3060fb
--- /dev/null
+++ b/tests/config/tapered/tapered-2.3.0-1.rockspec
@@ -0,0 +1,22 @@
+package = 'tapered'
+version = '2.3.0-1'
+source = {
+ url = 'git://github.com/telemachus/tapered.git',
+ branch = 'master',
+ tag = 'v2.3.0-1'
+}
+description = {
+ summary = 'Very minimal tap testing for Lua.',
+ detailed = [[
+ Very minimal tap testing for Lua. Arguably too minimal.
+ ]],
+ license = 'BSD 3-Clause'
+}
+dependencies = {
+ 'lua >= 5.1'
+}
+build = {
+ type = 'builtin',
+ modules = { tapered = 'src/tapered.lua' },
+ copy_directories = { 'doc' }
+}
diff --git a/tests/config/tapered/test/.luacov b/tests/config/tapered/test/.luacov
new file mode 100644
index 0000000..7d3205e
--- /dev/null
+++ b/tests/config/tapered/test/.luacov
@@ -0,0 +1,55 @@
+--- Global configuration file. Copy, customize and store in your
+-- project folder as '.luacov' for project specific configuration.
+-- If some options are missing, their default values from this file
+-- will be used.
+-- @class module
+-- @name luacov.defaults
+return {
+
+ -- default filename to load for config options if not provided
+ -- only has effect in 'luacov.defaults.lua'
+ ["configfile"] = ".luacov",
+
+ -- filename to store stats collected
+ ["statsfile"] = "luacov.stats.out",
+
+ -- filename to store report
+ ["reportfile"] = "luacov.report.out",
+
+ -- luacov.stats file updating frequency.
+ -- The lower this value - the more frequenty results will be written out to luacov.stats
+ -- You may want to reduce this value for short lived scripts (to for example 2) to avoid losing coverage data.
+ ["savestepsize"] = 100,
+
+ -- Run reporter on completion? (won't work for ticks)
+ runreport = false,
+
+ -- Delete stats file after reporting?
+ deletestats = false,
+
+ -- Process Lua code loaded from raw strings
+ -- (that is, when the 'source' field in the debug info
+ -- does not start with '@')
+ codefromstrings = false,
+
+ -- Patterns for files to include when reporting
+ -- all will be included if nothing is listed
+ -- (exclude overrules include, do not include
+ -- the .lua extension, path separator is always '/')
+ ["include"] = { 'src/tapered' },
+
+ -- Patterns for files to exclude when reporting
+ -- all will be included if nothing is listed
+ -- (exclude overrules include, do not include
+ -- the .lua extension, path separator is always '/')
+ ["exclude"] = {
+ "luacov$",
+ "luacov/reporter$",
+ "luacov/defaults$",
+ "luacov/runner$",
+ "luacov/stats$",
+ "luacov/tick$",
+ },
+
+
+}
diff --git a/tests/config/tapered/test/boom-result.txt b/tests/config/tapered/test/boom-result.txt
new file mode 100644
index 0000000..871b509
--- /dev/null
+++ b/tests/config/tapered/test/boom-result.txt
@@ -0,0 +1,7 @@
+ok 1 - ok - return nada.__eq
+# Got this error: "boom-test.lua:13: attempt to index local 'x' (a nil value)"
+not ok 2 - not ok - Test boom with a method that throws no exception
+# Trouble in boom-test.lua around line 16
+ok 3 - ok - Test boom with a method that throws an exception "Kaboom!"
+# Got this error: "Kaboom!"
+1..3
diff --git a/tests/config/tapered/test/boom-test.lua b/tests/config/tapered/test/boom-test.lua
new file mode 100755
index 0000000..f2b585a
--- /dev/null
+++ b/tests/config/tapered/test/boom-test.lua
@@ -0,0 +1,19 @@
+package.path = '../src/?.lua;' .. package.path
+local tap = require 'tapered'
+local error = error
+
+--- boom
+-- boom(method, arguments, [msg]) tests if the function throws an exception when
+-- given the arguments supplied. The arguments parameter must be a table. It can
+-- be empty if the given method takes no arguments, but it cannot be nil.
+--
+-- Note that boom expects an exception. It passes if an exception is throw, and
+-- fails if one is not. The exception, however, will be swallowed by boom so
+-- that test execution continues.
+local broken = function (x) return x.__eq end
+local add = function (x, y) return x+y end
+tap.boom(broken, {}, 'ok - return nada.__eq')
+tap.boom(add, {2, 3}, 'not ok - Test boom with a method that throws no exception')
+tap.boom(error, {'Kaboom!'},
+ 'ok - Test boom with a method that throws an exception "Kaboom!"')
+tap.done()
diff --git a/tests/config/tapered/test/done-failure-result.txt b/tests/config/tapered/test/done-failure-result.txt
new file mode 100644
index 0000000..ce29e24
--- /dev/null
+++ b/tests/config/tapered/test/done-failure-result.txt
@@ -0,0 +1,2 @@
+ok 1
+# Bad plan. You planned 10 tests but ran 1
diff --git a/tests/config/tapered/test/done-failure-test.lua b/tests/config/tapered/test/done-failure-test.lua
new file mode 100644
index 0000000..40603d4
--- /dev/null
+++ b/tests/config/tapered/test/done-failure-test.lua
@@ -0,0 +1,5 @@
+package.path = '../src/?.lua;' .. package.path
+local tap = require 'tapered'
+
+tap.ok(true)
+tap.done(10)
diff --git a/tests/config/tapered/test/done-success-result.txt b/tests/config/tapered/test/done-success-result.txt
new file mode 100644
index 0000000..45541bc
--- /dev/null
+++ b/tests/config/tapered/test/done-success-result.txt
@@ -0,0 +1,2 @@
+ok 1
+1..1
diff --git a/tests/config/tapered/test/done-success-test.lua b/tests/config/tapered/test/done-success-test.lua
new file mode 100644
index 0000000..9e58ddd
--- /dev/null
+++ b/tests/config/tapered/test/done-success-test.lua
@@ -0,0 +1,5 @@
+package.path = '../src/?.lua;' .. package.path
+local tap = require 'tapered'
+
+tap.ok(true)
+tap.done(1)
diff --git a/tests/config/tapered/test/dynamic-setup-teardown-result.txt b/tests/config/tapered/test/dynamic-setup-teardown-result.txt
new file mode 100644
index 0000000..7130f99
--- /dev/null
+++ b/tests/config/tapered/test/dynamic-setup-teardown-result.txt
@@ -0,0 +1,10 @@
+# I'm a little teapot.
+ok 1 - setup() only with '# I'm a little teapot.'
+# This is my handle and this is my spout.
+ok 2 - setup() handle and spout, teardown() cleanup on aisle 9
+# Cleanup on aisle 9!
+# This is my handle and this is my spout.
+ok 3 - setup() again handle and spout, teardown() changed
+# I changed this.
+ok 4 - Both setup and teardown should be gone now: redefined as nil.
+1..4
diff --git a/tests/config/tapered/test/dynamic-setup-teardown-test.lua b/tests/config/tapered/test/dynamic-setup-teardown-test.lua
new file mode 100755
index 0000000..c7abb9d
--- /dev/null
+++ b/tests/config/tapered/test/dynamic-setup-teardown-test.lua
@@ -0,0 +1,27 @@
+package.path = '../src/?.lua;' .. package.path
+local tap = require 'tapered'
+
+-- luacheck: globals setup teardown
+function setup()
+ print("# I'm a little teapot.")
+end
+tap.ok(true, "setup() only with '# I'm a little teapot.'")
+
+function setup()
+ print('# This is my handle and this is my spout.')
+end
+function teardown()
+ print('# Cleanup on aisle 9!')
+end
+tap.ok(true, 'setup() handle and spout, teardown() cleanup on aisle 9')
+
+function teardown()
+ print('# I changed this.')
+end
+tap.ok(true, 'setup() again handle and spout, teardown() changed')
+
+setup = nil
+teardown = nil
+tap.ok(true, 'Both setup and teardown should be gone now: redefined as nil.')
+
+tap.done()
diff --git a/tests/config/tapered/test/exit-failure-test.lua b/tests/config/tapered/test/exit-failure-test.lua
new file mode 100755
index 0000000..18339c2
--- /dev/null
+++ b/tests/config/tapered/test/exit-failure-test.lua
@@ -0,0 +1,6 @@
+package.path = '../src/?.lua;' .. package.path
+local tap = require 'tapered'
+
+-- Test exit status with a failed test. Call `fail` and we're done!
+tap.fail('not ok - No test: just fail')
+tap.done()
diff --git a/tests/config/tapered/test/exit-success-test.lua b/tests/config/tapered/test/exit-success-test.lua
new file mode 100755
index 0000000..b588b64
--- /dev/null
+++ b/tests/config/tapered/test/exit-success-test.lua
@@ -0,0 +1,6 @@
+package.path = '../src/?.lua;' .. package.path
+local tap = require 'tapered'
+
+-- Testing exit status. Call `pass` and then we're out.
+tap.pass('ok - No test: just pass')
+tap.done()
diff --git a/tests/config/tapered/test/informational-fields-result.txt b/tests/config/tapered/test/informational-fields-result.txt
new file mode 100644
index 0000000..4d0ebc1
--- /dev/null
+++ b/tests/config/tapered/test/informational-fields-result.txt
@@ -0,0 +1,4 @@
+ok 1 - author() should be 'Peter Aronoff'
+ok 2 - version() should be '2.3.0'
+ok 3 - license() should be 'BSD 3-Clause'
+ok 4 - url() should be 'https://github.com/telemachus/tapered'
diff --git a/tests/config/tapered/test/informational-fields-test.lua b/tests/config/tapered/test/informational-fields-test.lua
new file mode 100755
index 0000000..35ef7d8
--- /dev/null
+++ b/tests/config/tapered/test/informational-fields-test.lua
@@ -0,0 +1,8 @@
+package.path = '../src/?.lua;' .. package.path
+local tap = require 'tapered'
+
+tap.is(tap.author(), 'Peter Aronoff', "author() should be 'Peter Aronoff'")
+tap.is(tap.version(), '2.3.0', "version() should be '2.3.0'")
+tap.is(tap.license(), 'BSD 3-Clause', "license() should be 'BSD 3-Clause'")
+tap.is(tap.url(), "https://github.com/telemachus/tapered",
+ "url() should be 'https://github.com/telemachus/tapered'")
diff --git a/tests/config/tapered/test/is-isnt-result.txt b/tests/config/tapered/test/is-isnt-result.txt
new file mode 100644
index 0000000..583a9a7
--- /dev/null
+++ b/tests/config/tapered/test/is-isnt-result.txt
@@ -0,0 +1,43 @@
+ok 1 - ok - is(2+1, 3)
+not ok 2 - not ok - is(2+2, 3)
+# Trouble in is-isnt-test.lua around line 8
+ok 3 - ok - is(print, print)
+not ok 4 - not ok - is(print, 3)
+# Trouble in is-isnt-test.lua around line 10
+ok 5 - ok - is("hello", "hello")
+not ok 6 - not ok - is("goodbye", "hello")
+# Trouble in is-isnt-test.lua around line 12
+ok 7 - ok - is(nil, nil)
+not ok 8 - not ok - is(nil, false)
+# Trouble in is-isnt-test.lua around line 14
+ok 9 - ok - is(false, false)
+ok 10 - ok - is(true, true)
+not ok 11 - not ok - is(true, false)
+# Trouble in is-isnt-test.lua around line 17
+not ok 12 - not ok - is(false, true)
+# Trouble in is-isnt-test.lua around line 18
+ok 13 - ok - isnt(2+2, 3)
+not ok 14 - not ok - isnt(2+2, 4)
+# Trouble in is-isnt-test.lua around line 20
+ok 15 - ok - isnt(3, print)
+ok 16 - ok - isnt(print, os.exit)
+ok 17 - ok - isnt("hello", "goodbye")
+not ok 18 - not ok - isnt("hello", "hello")
+# Trouble in is-isnt-test.lua around line 24
+not ok 19 - not ok - isnt(nil, nil)
+# Trouble in is-isnt-test.lua around line 25
+ok 20 - ok - isnt(nil, false)
+not ok 21 - not ok - isnt(false, false)
+# Trouble in is-isnt-test.lua around line 27
+not ok 22 - not ok - isnt(true, true)
+# Trouble in is-isnt-test.lua around line 28
+ok 23 - ok - isnt(true, false)
+ok 24 - ok - isnt(false, true)
+ok 25 - ok - isnt(nil, false)
+not ok 26 - not ok - isnt(false, false)
+# Trouble in is-isnt-test.lua around line 32
+not ok 27 - not ok - isnt(true, true)
+# Trouble in is-isnt-test.lua around line 33
+ok 28 - ok - isnt(true, false)
+ok 29 - ok - isnt(false, true)
+1..29
diff --git a/tests/config/tapered/test/is-isnt-test.lua b/tests/config/tapered/test/is-isnt-test.lua
new file mode 100755
index 0000000..d1c7636
--- /dev/null
+++ b/tests/config/tapered/test/is-isnt-test.lua
@@ -0,0 +1,36 @@
+package.path = '../src/?.lua;' .. package.path
+local tap = require 'tapered'
+
+--- is and isnt
+-- is(actual, expected, [msg]) tests if actual == expected
+-- isnt(actual, expected, [msg]) tests if actual ~= expected
+tap.is(2+1, 3, 'ok - is(2+1, 3)')
+tap.is(2+2, 3, 'not ok - is(2+2, 3)')
+tap.is(print, print, 'ok - is(print, print)')
+tap.is(print, 3, 'not ok - is(print, 3)')
+tap.is('hello', 'hello', 'ok - is("hello", "hello")')
+tap.is('goodbye', 'hello', 'not ok - is("goodbye", "hello")')
+tap.is(nil, nil, 'ok - is(nil, nil)')
+tap.is(nil, false, 'not ok - is(nil, false)')
+tap.is(false, false, 'ok - is(false, false)')
+tap.is(true, true, 'ok - is(true, true)')
+tap.is(true, false, 'not ok - is(true, false)')
+tap.is(false, true, 'not ok - is(false, true)')
+tap.isnt(2+2, 3, 'ok - isnt(2+2, 3)')
+tap.isnt(2+2, 4, 'not ok - isnt(2+2, 4)')
+tap.isnt(3, print, 'ok - isnt(3, print)')
+tap.isnt(print, os.exit, 'ok - isnt(print, os.exit)')
+tap.isnt('hello', 'goodbye', 'ok - isnt("hello", "goodbye")')
+tap.isnt('hello', 'hello', 'not ok - isnt("hello", "hello")')
+tap.isnt(nil, nil, 'not ok - isnt(nil, nil)')
+tap.isnt(nil, false, 'ok - isnt(nil, false)')
+tap.isnt(false, false, 'not ok - isnt(false, false)')
+tap.isnt(true, true, 'not ok - isnt(true, true)')
+tap.isnt(true, false, 'ok - isnt(true, false)')
+tap.isnt(false, true, 'ok - isnt(false, true)')
+tap.isnt(nil, false, 'ok - isnt(nil, false)')
+tap.isnt(false, false, 'not ok - isnt(false, false)')
+tap.isnt(true, true, 'not ok - isnt(true, true)')
+tap.isnt(true, false, 'ok - isnt(true, false)')
+tap.isnt(false, true, 'ok - isnt(false, true)')
+tap.done()
diff --git a/tests/config/tapered/test/like-unlike-result.txt b/tests/config/tapered/test/like-unlike-result.txt
new file mode 100644
index 0000000..f61aac2
--- /dev/null
+++ b/tests/config/tapered/test/like-unlike-result.txt
@@ -0,0 +1,13 @@
+ok 1 - ok - like('sat', 'sat')
+not ok 2 - not ok - like('sat', 'bbb')
+# Trouble in like-unlike-test.lua around line 8
+ok 3 - ok - unlike('sat', 'q')
+not ok 4 - not ok - unlike('q', 'q')
+# Trouble in like-unlike-test.lua around line 10
+ok 5 - ok - like(' sat', '%s+sat')
+ok 6 - ok - like('934', '%d%d%d')
+ok 7 - ok - like('934', '%d%d')
+not ok 8 - not ok - like('934', '%d%s')
+# Trouble in like-unlike-test.lua around line 14
+ok 9 - ok - unlike('934', '%d%s')
+1..9
diff --git a/tests/config/tapered/test/like-unlike-test.lua b/tests/config/tapered/test/like-unlike-test.lua
new file mode 100755
index 0000000..ab48ca7
--- /dev/null
+++ b/tests/config/tapered/test/like-unlike-test.lua
@@ -0,0 +1,16 @@
+package.path = '../src/?.lua;' .. package.path
+local tap = require 'tapered'
+
+--- like and unlike
+-- like(string, pattern, [msg]) tests if the pattern matches the string
+-- unlike(string, pattern, [msg]) tests if the pattern does not match the string
+tap.like('sat', 'sat', "ok - like('sat', 'sat')")
+tap.like('sat', 'bbb', "not ok - like('sat', 'bbb')")
+tap.unlike('sat', 'q', "ok - unlike('sat', 'q')")
+tap.unlike('q', 'q', "not ok - unlike('q', 'q')")
+tap.like(' sat', '%s+sat', "ok - like(' sat', '%s+sat')")
+tap.like('934', '%d%d%d', "ok - like('934', '%d%d%d')")
+tap.like('934', '%d%d', "ok - like('934', '%d%d')")
+tap.like('934', '%d%s', "not ok - like('934', '%d%s')")
+tap.unlike('934', '%d%s', "ok - unlike('934', '%d%s')")
+tap.done()
diff --git a/tests/config/tapered/test/ok-nok-result.txt b/tests/config/tapered/test/ok-nok-result.txt
new file mode 100644
index 0000000..ef45c6a
--- /dev/null
+++ b/tests/config/tapered/test/ok-nok-result.txt
@@ -0,0 +1,7 @@
+ok 1 - ok - ok(true)
+not ok 2 - not ok - ok(false)
+# Trouble in ok-nok-test.lua around line 8
+ok 3 - ok - nok(false)
+not ok 4 - not ok - nok(true)
+# Trouble in ok-nok-test.lua around line 10
+1..4
diff --git a/tests/config/tapered/test/ok-nok-test.lua b/tests/config/tapered/test/ok-nok-test.lua
new file mode 100755
index 0000000..c2a0b4d
--- /dev/null
+++ b/tests/config/tapered/test/ok-nok-test.lua
@@ -0,0 +1,11 @@
+package.path = '../src/?.lua;' .. package.path
+local tap = require 'tapered'
+
+--- ok and nok
+-- ok(exp, [msg]) tests if exp returns (or is) a truthy value.
+-- nok(exp, [msg]) tests if exp returns (or is) a falsey value.
+tap.ok(true, 'ok - ok(true)')
+tap.ok(false, 'not ok - ok(false)')
+tap.nok(false, 'ok - nok(false)')
+tap.nok(true, 'not ok - nok(true)')
+tap.done()
diff --git a/tests/config/tapered/test/pass-fail-result.txt b/tests/config/tapered/test/pass-fail-result.txt
new file mode 100644
index 0000000..8c29e66
--- /dev/null
+++ b/tests/config/tapered/test/pass-fail-result.txt
@@ -0,0 +1,4 @@
+ok 1 - ok - No test: just pass
+not ok 2 - not ok - No test: just fail
+# Trouble in pass-fail-test.lua around line 10
+1..2
diff --git a/tests/config/tapered/test/pass-fail-test.lua b/tests/config/tapered/test/pass-fail-test.lua
new file mode 100755
index 0000000..0f2418a
--- /dev/null
+++ b/tests/config/tapered/test/pass-fail-test.lua
@@ -0,0 +1,11 @@
+package.path = '../src/?.lua;' .. package.path
+local tap = require 'tapered'
+
+--- pass and fail
+-- pass([msg]) is not a test. It always passes.
+-- fail([msg]) is not a test. It always fails.
+-- These two methods are useful for checking the basic setup of a test suite.
+-- Also, pass can be used as a quasi-skip and fail as a quasi-TODO.
+tap.pass('ok - No test: just pass')
+tap.fail('not ok - No test: just fail')
+tap.done()
diff --git a/tests/config/tapered/test/result_test03.txt b/tests/config/tapered/test/result_test03.txt
new file mode 100644
index 0000000..58c066c
--- /dev/null
+++ b/tests/config/tapered/test/result_test03.txt
@@ -0,0 +1,55 @@
+ok 1 - Test ok on true
+not ok 2 - Test ok on false
+# Trouble in test03-allfuncs.lua around line 9
+ok 3 - Test nok on false
+not ok 4 - Test nok on true
+# Trouble in test03-allfuncs.lua around line 11
+ok 5 - Test is on 2 + 1 = 3
+not ok 6 - Test is on 2 + 2 = 3
+# Trouble in test03-allfuncs.lua around line 17
+ok 7 - Test isnt on 2 + 2 = 3
+not ok 8 - Test isnt on 2 + 2 = 4
+# Trouble in test03-allfuncs.lua around line 19
+ok 9 - Test same on two empty tables
+ok 10 - Test same on two identical, simple tables
+not ok 11 - Test same on two simple non-identical tables
+# Trouble in test03-allfuncs.lua around line 36
+ok 12 - Test same on two identical, nested tables
+ok 13 - Test same on identical, array-like tables
+not ok 14 - Test same on two non-identical, array-like tables
+# Trouble in test03-allfuncs.lua around line 43
+ok 15 - Test same on two identical, hash-like tables
+not ok 16 - Test same on two non-identical, hash-like tables
+# Trouble in test03-allfuncs.lua around line 65
+ok 17 - Test same on two identical tables with functions as values
+not ok 18 - Test same on two non-identical tables with functions as values
+# Trouble in test03-allfuncs.lua around line 74
+ok 19 - Test same on two dissimilar tables that share .__eq => true
+not ok 20 - Test same: first table .__eq => true, second => false
+# Trouble in test03-allfuncs.lua around line 89
+not ok 21 - Test same: first table .__eq => false, second => true
+# Trouble in test03-allfuncs.lua around line 90
+not ok 22 - Test same on two similar tables where first .__eq => true
+# Trouble in test03-allfuncs.lua around line 91
+not ok 23 - Test same on two similar tables where second .__eq => true
+# Trouble in test03-allfuncs.lua around line 92
+ok 24 - Test like with string 'sat' and pattern 'sat'
+not ok 25 - Test like with string 'sat' and pattern 'bbb'
+# Trouble in test03-allfuncs.lua around line 98
+ok 26 - Test unlike with string 'sat' and pattern 'q'
+not ok 27 - Test unlike with string 'q' and pattern 'q'
+# Trouble in test03-allfuncs.lua around line 100
+ok 28 - Test like with string ' sat' and pattern '%s+sat'
+ok 29 - Test like with string '934' and pattern '%d%d%d'
+ok 30 - Test like with string '934' and pattern '%d%d'
+ok 31 - Test unlike with string '934' and pattern '%d%s'
+ok 32 - No test: just pass
+not ok 33 - No test: just fail
+# Trouble in test03-allfuncs.lua around line 112
+not ok 34 - Test boom with a method that throws no exception
+# Trouble in test03-allfuncs.lua around line 123
+ok 35 - Test boom with a method that throws an exception "Kaboom!"
+# Got this error:
+# Kaboom!
+1..35
+# Bad plan. You planned 43 tests but ran 35
diff --git a/tests/config/tapered/test/runner.bash b/tests/config/tapered/test/runner.bash
new file mode 100755
index 0000000..f7f38fc
--- /dev/null
+++ b/tests/config/tapered/test/runner.bash
@@ -0,0 +1,71 @@
+#!/usr/bin/env bats
+
+@test "ignition!" {
+ run true
+ [ "$status" -eq 0 ]
+ [ "$output" = "" ]
+}
+
+@test "ok and nok" {
+ run lua -lluacov ok-nok-test.lua
+ [ "$status" -eq 2 ]
+ [ "$output" = "$(cat ok-nok-result.txt)" ]
+}
+
+@test "is and isnt" {
+ run lua -lluacov is-isnt-test.lua
+ [ "$status" -eq 13 ]
+ [ "$output" = "$(cat is-isnt-result.txt)" ]
+}
+
+@test "same" {
+ run lua -lluacov same-test.lua
+ [ "$status" -eq 10 ]
+ [ "$output" = "$(cat same-result.txt)" ]
+}
+
+@test "like and unlike" {
+ run lua -lluacov like-unlike-test.lua
+ [ "$status" -eq 3 ]
+ [ "$output" = "$(cat like-unlike-result.txt)" ]
+}
+
+@test "pass and fail" {
+ run lua -lluacov pass-fail-test.lua
+ [ "$status" -eq 1 ]
+ [ "$output" = "$(cat pass-fail-result.txt)" ]
+}
+
+@test "boom" {
+ run lua -lluacov boom-test.lua
+ [ "$status" -eq 1 ]
+ # This is foul, but choices are limited. Error messages for Lua 5.3
+ # are different, so I need to look at the output but NOT the errors.
+ [ "$(grep -v '^#' <<< "$output")" = "$(cat boom-result.txt | grep -v '^#')" ]
+}
+
+@test "done success" {
+ run lua -lluacov done-success-test.lua
+ [ "$status" -eq 0 ]
+ [ "$output" = "$(cat done-success-result.txt)" ]
+}
+
+@test "done failure" {
+ run lua -lluacov done-failure-test.lua
+ [ "$status" -eq 1 ]
+ [ "$output" = "$(cat done-failure-result.txt)" ]
+}
+
+@test "exit status" {
+ run lua -lluacov exit-success-test.lua
+ [ "$status" -eq 0 ]
+
+ run lua -lluacov exit-failure-test.lua
+ [ "$status" -eq 1 ]
+}
+
+@test "informational fields" {
+ run lua -lluacov informational-fields-test.lua
+ [ "$status" -eq 0 ]
+ [ "$output" = "$(cat informational-fields-result.txt)" ]
+}
diff --git a/tests/config/tapered/test/same-result.txt b/tests/config/tapered/test/same-result.txt
new file mode 100644
index 0000000..c77a5a4
--- /dev/null
+++ b/tests/config/tapered/test/same-result.txt
@@ -0,0 +1,31 @@
+ok 1 - ok - same({}, {}
+ok 2 - ok - same({1,2,3}, {1,2,3})
+not ok 3 - not ok - same({1}, {})
+# Trouble in same-test.lua around line 7
+ok 4 - ok - same({{1}, 2, {3,4}}, {{1}, 2, {3,4})
+ok 5 - ok - same({"Monday", "Tuesday"}, {"Monday", "Tuesday"})
+not ok 6 - not ok - same({"Monday", "Tuesday"}, {"Monday", "Tuesday", "Wednesday"})
+# Trouble in same-test.lua around line 15
+ok 7 - ok - same({Monday = 1}, {Monday = 1})
+not ok 8 - not ok - same({Monday = 1}, {Monday = 1, Tuesday = 2})
+# Trouble in same-test.lua around line 29
+ok 9 - ok - same({m = {1,2}, n = {1,2}}, {m = {1,2}, n = {1,2}})
+not ok 10 - not ok - same({m = {1,2}, n = {1,2}}, {m = {1,2}, n = {1,2,3}})
+# Trouble in same-test.lua around line 36
+not ok 11 - not ok - same({m = {1,2}, n = {1,2,3}}, {m = {1,2}, n = {1,2}})
+# Trouble in same-test.lua around line 37
+ok 12 - ok - same({p = print, a = assert}, {p = print, a = assert})
+not ok 13 - not ok - same({p = print, a = assert}, {p = print, a = assert, e = error})
+# Trouble in same-test.lua around line 44
+ok 14 - ok - same({4, s=4}, {6, s=4},__eq => x[s] and y[s] are even)
+ok 15 - ok - same({6, s=8}, {4, s=4},__eq => x[s] and y[s] are even)
+not ok 16 - not ok - same({4, s=4}, {4, s=3},__eq => x[s] and y[s] are even)
+# Trouble in same-test.lua around line 61
+not ok 17 - not ok - same({4, s=4}, {4, s=3},__eq => x[s] and y[s] are even)
+# Trouble in same-test.lua around line 63
+not ok 18 - not ok - same({4, s=4}, {6, s=4},__eq => x[s] is even, y[s] odd)
+# Trouble in same-test.lua around line 68
+ok 19 - ok - same({4, s=4}, {4, s=3},__eq => x[s] is even, y[s] odd)
+not ok 20 - not ok - same({4, s=3}, {4, s=4},__eq => x[s] is even, y[s] odd)
+# Trouble in same-test.lua around line 72
+1..20
diff --git a/tests/config/tapered/test/same-test.lua b/tests/config/tapered/test/same-test.lua
new file mode 100644
index 0000000..68c3574
--- /dev/null
+++ b/tests/config/tapered/test/same-test.lua
@@ -0,0 +1,74 @@
+package.path = '../src/?.lua;' .. package.path
+local tap = require 'tapered'
+-- luacheck: compat
+
+tap.same({},{}, 'ok - same({}, {}')
+tap.same({1,2,3}, {1,2,3}, 'ok - same({1,2,3}, {1,2,3})')
+tap.same({1},{}, 'not ok - same({1}, {})')
+tap.same({{1}, 2, {3,4}},{{1}, 2, {3,4}},
+ 'ok - same({{1}, 2, {3,4}}, {{1}, 2, {3,4})')
+
+local days1 = { 'Monday', 'Tuesday' }
+local days2 = { 'Monday', 'Tuesday' }
+tap.same(days1, days2, 'ok - same({"Monday", "Tuesday"}, {"Monday", "Tuesday"})')
+local days3 = { 'Monday', 'Tuesday', 'Wednesday', }
+tap.same(days2, days3,
+ 'not ok - same({"Monday", "Tuesday"}, {"Monday", "Tuesday", "Wednesday"})')
+
+local hash1 = {
+ Monday = 1,
+}
+local hash2 = {
+ Monday = 1,
+}
+local hash3 = {
+ Monday = 1,
+ Tuesday = 2,
+}
+tap.same(hash1, hash2, 'ok - same({Monday = 1}, {Monday = 1})')
+tap.same(hash1, hash3,
+ 'not ok - same({Monday = 1}, {Monday = 1, Tuesday = 2})')
+
+local n1 = { m = { 1, 2 }, n = { 1, 2 } }
+local n2 = { m = { 1, 2 }, n = { 1, 2 } }
+local n3 = { m = { 1, 2 }, n = { 1, 2, 3 } }
+tap.same(n1, n2, 'ok - same({m = {1,2}, n = {1,2}}, {m = {1,2}, n = {1,2}})')
+tap.same(n1, n3, 'not ok - same({m = {1,2}, n = {1,2}}, {m = {1,2}, n = {1,2,3}})')
+tap.same(n3, n1, 'not ok - same({m = {1,2}, n = {1,2,3}}, {m = {1,2}, n = {1,2}})')
+
+local method_table1 = { p = print, a = assert }
+local method_table2 = { p = print, a = assert }
+local method_table3 = { p = print, a = assert, e = error }
+tap.same(method_table1, method_table2,
+ 'ok - same({p = print, a = assert}, {p = print, a = assert})')
+tap.same(method_table1, method_table3,
+ 'not ok - same({p = print, a = assert}, {p = print, a = assert, e = error})')
+
+local foo = {4, s = 4}
+local bar = {6, s = 8}
+local oof = {4, s = 3}
+local mt1 = {}
+local mt2 = {}
+local evens = function (x, y) return x['s'] % 2 == 0 and y['s'] % 2 == 0 end
+local even_odd = function (x, y) return x['s'] % 2 == 0 and y['s'] % 2 ~= 0 end
+mt1.__eq = evens
+mt2.__eq = even_odd
+setmetatable(foo, mt1)
+setmetatable(bar, mt1)
+setmetatable(oof, mt1)
+tap.same(foo, bar, 'ok - same({4, s=4}, {6, s=4},__eq => x[s] and y[s] are even)')
+tap.same(bar, foo, 'ok - same({6, s=8}, {4, s=4},__eq => x[s] and y[s] are even)')
+tap.same(foo, oof,
+ 'not ok - same({4, s=4}, {4, s=3},__eq => x[s] and y[s] are even)')
+tap.same(oof, foo,
+ 'not ok - same({4, s=4}, {4, s=3},__eq => x[s] and y[s] are even)')
+setmetatable(foo, mt2)
+setmetatable(bar, mt2)
+setmetatable(oof, mt2)
+tap.same(foo, bar,
+ 'not ok - same({4, s=4}, {6, s=4},__eq => x[s] is even, y[s] odd)')
+tap.same(foo, oof,
+ 'ok - same({4, s=4}, {4, s=3},__eq => x[s] is even, y[s] odd)')
+tap.same(oof, foo,
+ 'not ok - same({4, s=3}, {4, s=4},__eq => x[s] is even, y[s] odd)')
+tap.done()
diff --git a/tests/config/tapered/test/setup-teardown-result.txt b/tests/config/tapered/test/setup-teardown-result.txt
new file mode 100644
index 0000000..c5d5668
--- /dev/null
+++ b/tests/config/tapered/test/setup-teardown-result.txt
@@ -0,0 +1,4 @@
+# I'm a little teapot.
+ok 1 - Short and stout.
+# Here is my handle, and here is my spout.
+1..1
diff --git a/tests/config/tapered/test/setup-teardown-test.lua b/tests/config/tapered/test/setup-teardown-test.lua
new file mode 100755
index 0000000..974a4aa
--- /dev/null
+++ b/tests/config/tapered/test/setup-teardown-test.lua
@@ -0,0 +1,14 @@
+package.path = '../src/?.lua;' .. package.path
+local tap = require 'tapered'
+
+-- luacheck: globals setup teardown
+function setup()
+ print("# I'm a little teapot.")
+end
+
+function teardown()
+ print("# Here is my handle, and here is my spout.")
+end
+
+tap.ok(true, "Short and stout.")
+tap.done()
diff --git a/tests/config/test.cfg b/tests/config/test.cfg
new file mode 100644
index 0000000..b45226c
--- /dev/null
+++ b/tests/config/test.cfg
@@ -0,0 +1,46 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+-- disable output buffering to crashes do not leave us without log
+io.stdout:setvbuf('no')
+io.stderr:setvbuf('no')
+
+-- modify path to be able to load testing modules
+package.path = package.path .. ';' .. env.SOURCE_PATH .. '/?.lua'
+
+-- export testing module in globals
+local tapered = require('tapered.src.tapered')
+for k, v in pairs(tapered) do
+ _G[k] = v
+end
+
+-- don't send priming queries etc.
+modules.unload 'detect_time_skew'
+modules.unload 'priming'
+modules.unload 'ta_signal_query'
+modules.unload 'ta_update'
+
+-- load test
+local ffi = require('ffi')
+assert(type(env.TEST_FILE) == 'string')
+log_info(ffi.C.LOG_GRP_TESTS, 'processing test file %s', env.TEST_FILE)
+local tests = dofile(env.TEST_FILE)
+
+-- run test after processed config file
+-- default config will be used and we can test it.
+assert(type(tests) == 'table',
+ string.format('file %s did not return a table of test'
+ .. ' functions, did you forget return?',
+ env.TEST_FILE))
+
+local runtest = require('test_utils').test
+worker.coroutine(function ()
+ local at_least_one_test = false
+ for idx, t in ipairs(tests) do
+ assert(type(t) == 'function',
+ string.format('test table idx %d in file %s'
+ .. ' is not a function', idx, env.TEST_FILE))
+ at_least_one_test = true
+ runtest(t)
+ end
+ assert(at_least_one_test, 'test set is empty?! a typo in function name?')
+ done()
+end)
diff --git a/tests/config/test_dns_generators.lua b/tests/config/test_dns_generators.lua
new file mode 100644
index 0000000..4a7cc0a
--- /dev/null
+++ b/tests/config/test_dns_generators.lua
@@ -0,0 +1,134 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+local ffi = require('ffi')
+local kr_cach = kres.context().cache
+
+
+local charset = {
+ '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', '-'}
+
+local function gen_bytes(len)
+ local bytes = {}
+ for _ = 1,len do
+ table.insert(bytes, charset[math.random(1, #charset)])
+ end
+ local result = table.concat(bytes)
+ assert(#result == len)
+ return result
+end
+
+local function gen_ttl()
+ return math.random(0, 2^31-1)
+end
+
+local function gen_rrtype()
+ return math.random(1024, 61000)
+end
+
+local function gen_rdata(len)
+ assert(len >= 1 and len <= 65535)
+ return gen_bytes(len)
+end
+
+local function gen_label(len) -- in bytes including the length byte
+ assert(len >= 2 and len <= 64)
+ local bytes = {string.char(len - 1), gen_bytes(len - 1)}
+ return table.concat(bytes)
+end
+
+local function gen_dname()
+ local target_len -- length 2 bytes does not make sense
+ while target_len == nil or target_len == 2 do
+ target_len = math.random(1, 255)
+ end
+
+ local labels = {string.char(0)}
+ local cur_len = 1
+ while target_len > cur_len do
+ local new_len = math.random(
+ 2,
+ math.min(target_len - cur_len,
+ 64))
+ if (target_len - cur_len - new_len) == 1 then
+ -- it is a trap, single-byte label is allowed only at the end
+ -- we cannot leave room for single-byte label in the next round
+ if new_len == 64 then
+ goto continue -- we are at max label length, try again
+ end
+ new_len = new_len + 1
+ end
+ table.insert(labels, 1, gen_label(new_len))
+ cur_len = cur_len + new_len
+ ::continue::
+ end
+ assert(target_len == cur_len)
+ local dname = table.concat(labels)
+ assert(#dname >= 1 and #dname <= 255)
+ assert(string.byte(dname, #dname) == 0)
+ return dname
+end
+
+
+local function gen_rrset()
+ local rrs = {}
+ local maxsize = 300 -- RR data size in bytes per RR set, does not include owner etc.
+ local target_len = math.random(1, maxsize)
+ local cur_len = 0
+ while target_len > cur_len do
+ local new_len = math.random(1, target_len - cur_len)
+ local new_rr = gen_rdata(new_len)
+ cur_len = cur_len + #new_rr
+ table.insert(rrs, new_rr)
+ end
+ assert(target_len == cur_len)
+ return rrs, cur_len
+end
+
+
+local function add_random_rrset()
+ local owner = gen_dname()
+ local ttl = gen_ttl()
+ local rr_type = gen_rrtype()
+ local rdata_set = gen_rrset()
+
+ local kr_rrset = kres.rrset(owner, rr_type, kres.class.IN, ttl)
+ for _, rr in ipairs(rdata_set) do
+ assert(kr_rrset:add_rdata(rr, #rr))
+ end
+ assert(kr_cach:insert(kr_rrset, nil, ffi.C.KR_RANK_SECURE))
+end
+
+ffi.cdef('int usleep(uint32_t usec);') -- at least in current glibc it's always 32-bit
+
+local rr_count = 0
+local function gen_batch()
+ for _ = 1,math.random(1,10) do
+ add_random_rrset()
+ rr_count = rr_count + 1
+ if rr_count % 100 == 0 then
+ print('cache usage ', cache.stats()['usage_percent'], '%')
+ end
+ end
+ kr_cach:commit()
+ ffi.C.usleep(15) -- stop *whole process* to give better chance to GC executing
+ local delay
+ if math.random(1,4) == 1 then
+ delay = 1 -- give a chance to DNS resolving
+ else
+ delay = 0
+ end
+ event.after(delay, gen_batch)
+end
+
+return {
+ add_random_rrset=add_random_rrset,
+ gen_batch=gen_batch,
+ gen_bytes=gen_bytes,
+ gen_dname=gen_dname,
+ gen_label=gen_label,
+ gen_rdata=gen_rdata,
+ gen_rrset=gen_rrset,
+ gen_rrtype=gen_rrtype,
+ gen_ttl=gen_ttl
+}
diff --git a/tests/config/test_utils.lua b/tests/config/test_utils.lua
new file mode 100644
index 0000000..4389293
--- /dev/null
+++ b/tests/config/test_utils.lua
@@ -0,0 +1,121 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+local M = {}
+
+function M.test(f, ...)
+ local res, exception = xpcall(f, debug.traceback, ...)
+ if not res then
+ io.stderr:write(string.format('%s\n', exception))
+ os.exit(2)
+ end
+ return res
+end
+
+function M.table_keys_to_lower(table)
+ local res = {}
+ for k, v in pairs(table) do
+ res[k:lower()] = v
+ end
+ return res
+end
+
+local function contains(pass, fail, table, value, message)
+ message = message or string.format('table contains "%s"', value)
+ for _, v in pairs(table) do
+ if v == value then
+ pass(message)
+ return
+ end
+ end
+ fail(message)
+ return
+end
+
+function M.contains(table, value, message)
+ return contains(pass, fail, table, value, message)
+end
+
+function M.not_contains(table, value, message)
+ return contains(fail, pass, table, value, message)
+end
+
+local function answer2table(pkt)
+ local got_answers = {}
+ local ans_rrs = pkt:rrsets(kres.section.ANSWER)
+ for i = 1, #ans_rrs do
+ rrs = ans_rrs[i]
+ for rri = 0, rrs:rdcount() - 1 do
+ local rr = ans_rrs[i]:txt_fields(rri)
+ got_answers[rr.owner] = got_answers[rr.owner] or {}
+ got_answers[rr.owner][rr.type] = got_answers[rr.owner][rr.type] or {}
+ table.insert(got_answers[rr.owner][rr.type], rr.rdata)
+ table.sort(got_answers[rr.owner][rr.type])
+ end
+ end
+ return got_answers
+end
+
+M.NODATA = -1
+-- Resolve a name and check the answer. Do *not* return until finished.
+-- expected_rdata is one string or a table of strings in presentation format
+function M.check_answer(desc, qname, qtype, expected_rcode, expected_rdata)
+ assert(type(qtype) == 'number')
+ local qtype_str = kres.tostring.type[qtype]
+ qname = string.lower(qname)
+
+ local expected_answer = {}
+ if expected_rdata ~= nil then
+ if type(expected_rdata) ~= 'table' then
+ expected_rdata = { expected_rdata }
+ end
+ if #expected_rdata > 0 then
+ table.sort(expected_rdata)
+ expected_answer = {
+ [qname] = {
+ [qtype_str] =
+ expected_rdata
+ }
+ }
+ end
+ end
+
+ local wire_rcode = expected_rcode
+ if expected_rcode == kres.rcode.NOERROR and type(expected_rdata) == 'table'
+ and #expected_rdata == 0 then
+ expected_rcode = M.NODATA
+ end
+ if expected_rcode == M.NODATA then wire_rcode = kres.rcode.NOERROR end
+
+ local done = false
+ local callback = function(pkt)
+ ok(pkt, 'answer not dropped')
+ same(pkt:rcode(), wire_rcode,
+ desc .. ': expecting answer for query ' .. qname .. ' ' .. qtype_str
+ .. ' with rcode ' .. kres.tostring.rcode[wire_rcode])
+
+ ok((pkt:ancount() > 0) == (expected_rcode == kres.rcode.NOERROR),
+ desc ..': checking number of answers for ' .. qname .. ' ' .. qtype_str)
+
+ if expected_rdata then
+ same(expected_answer, answer2table(pkt), 'ANSWER section matches')
+ end
+ done = true
+ end
+ resolve(qname, qtype, kres.class.IN, {},
+ function(...)
+ local ok, err = xpcall(callback, debug.traceback, ...)
+ if not ok then
+ fail('error in check_answer callback function')
+ io.stderr:write(string.format('%s\n', err))
+ os.exit(2)
+ end
+ end
+ )
+
+ for delay = 0.1, 5, 0.5 do -- total max 23.5s in 9 steps
+ if done then return end
+ worker.sleep(delay)
+ end
+ if not done then fail('check_answer() timed out') end
+end
+
+return M
diff --git a/tests/config/tls.test.lua b/tests/config/tls.test.lua
new file mode 100644
index 0000000..ef811bb
--- /dev/null
+++ b/tests/config/tls.test.lua
@@ -0,0 +1,29 @@
+local ffi = require('ffi')
+ffi.cdef([[ const char * gnutls_check_version (const char * req_version); ]])
+
+-- SPDX-License-Identifier: GPL-3.0-or-later
+local function test_session_config()
+ ok(net.tls_sticket_secret(),
+ 'net.tls_sticket_secret() to trigger key regeneration')
+ if ffi.C.gnutls_check_version("3.6.3") ~= nil then
+ ok(net.tls_sticket_secret('0123456789ABCDEF0123456789ABCDEF'),
+ 'net.tls_sticket_secret with valid key')
+ end
+ boom(net.tls_sticket_secret, {{}},
+ 'net.tls_sticket_secret({}) is invalid')
+ boom(net.tls_sticket_secret, {'0123456789ABCDEF0123456789ABCDE'},
+ 'net.tls_sticket_secret with too short key')
+
+ boom(net.tls_sticket_secret_file, {},
+ 'net.tls_sticket_secret_file without filename')
+ boom(net.tls_sticket_secret_file, {{}},
+ 'net.tls_sticket_secret_file with non-string filename')
+ boom(net.tls_sticket_secret_file, {'/tmp/a_non_existent_file_REALLY_1528898130'},
+ 'net.tls_sticket_secret_file with non-existent filename')
+ boom(net.tls_sticket_secret_file, {'/dev/null'},
+ 'net.tls_sticket_secret_file with empty file')
+end
+
+return {
+ test_session_config
+}
diff --git a/tests/config/worker.test.lua b/tests/config/worker.test.lua
new file mode 100644
index 0000000..756bb5f
--- /dev/null
+++ b/tests/config/worker.test.lua
@@ -0,0 +1,65 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+-- check prerequisites
+if not worker.bg_worker then
+ -- skipping worker test because it doesnt support background worker
+ os.exit(77)
+else
+ -- import primitives for synchronisation
+ local monotime = require('cqueues').monotime
+
+ -- test whether sleeping works
+ local function test_worker_sleep()
+ local now = monotime()
+ ok(pcall(worker.sleep, 0.1), 'sleep works')
+ local elapsed = monotime() - now
+ ok(elapsed > 0, 'sleep takes non-zero time')
+ end
+
+ -- helper to track number of executions
+ local cv = require('cqueues.condition').new()
+ local tasks = 0
+ local function work ()
+ worker.sleep(0.1)
+ tasks = tasks - 1
+ if tasks == 0 then
+ cv:signal()
+ elseif tasks < 0 then
+ error('too many executions')
+ end
+ end
+
+ -- test whether coroutines work
+ local function test_worker_coroutine()
+ tasks = 2
+ worker.coroutine(work)
+ worker.coroutine(work)
+ -- Check if coroutines finish
+ local status = cv:wait(1)
+ same(tasks, 0, 'all coroutines finish')
+ ok(status, 'coroutines finish successfully')
+ -- Check if nesting coroutines works
+ local now = monotime()
+ tasks = 100
+ worker.coroutine(function ()
+ for _ = 1, 100 do
+ worker.coroutine(work)
+ end
+ end)
+ status = cv:wait(1)
+ local elapsed = monotime() - now
+ same(tasks, 0, 'all nested coroutines finish')
+ ok(status, 'nested coroutines finish successfully')
+ -- Test if 100 coroutines didnt execute synchronously
+ -- (the wait time would be 100 * 0.1 = 10s sleep time)
+ -- Concurrent sleep time should still be ~0.1s (added some safe margin)
+ ok(elapsed < 0.5, 'coroutines didnt block while sleeping')
+ end
+
+ -- plan tests
+ local tests = {
+ test_worker_sleep,
+ test_worker_coroutine
+ }
+
+ return tests
+end
diff --git a/tests/dnstap/meson.build b/tests/dnstap/meson.build
new file mode 100644
index 0000000..1dfd87e
--- /dev/null
+++ b/tests/dnstap/meson.build
@@ -0,0 +1,11 @@
+
+# note: it will be skipped if 'go' is missing (and marked so)
+test('dnstap',
+ find_program('./src/dnstap-test/run.sh'),
+ args: [ sbin_dir / 'kresd' ],
+ suite: [ 'postinstall', 'dnstap' ],
+ timeout: 120, # it may need to fetch go packages, etc.
+ # it takes relatively long time
+ kwargs: meson.version().version_compare('<0.52') ? {} : { 'priority': 5 },
+)
+
diff --git a/tests/dnstap/src/dnstap-test/config b/tests/dnstap/src/dnstap-test/config
new file mode 100644
index 0000000..5f15308
--- /dev/null
+++ b/tests/dnstap/src/dnstap-test/config
@@ -0,0 +1,14 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+modules = {
+ 'hints',
+ dnstap = {
+ socket_path = "dnstap.sock",
+ client = {
+ log_queries = true,
+ log_responses = true,
+ }
+ }
+}
+hints['fake1.localdomain'] = '1.2.3.4'
+hints['fake2.localdomain'] = '1.2.3.5'
+hints['fake3.localdomain'] = '1.2.3.6'
diff --git a/tests/dnstap/src/dnstap-test/main.go b/tests/dnstap/src/dnstap-test/main.go
new file mode 100644
index 0000000..c04b4c1
--- /dev/null
+++ b/tests/dnstap/src/dnstap-test/main.go
@@ -0,0 +1,247 @@
+package main
+
+import (
+ "context"
+ "flag"
+ "fmt"
+ "github.com/cloudflare/dns"
+ dnstap "github.com/dnstap/golang-dnstap"
+ "github.com/golang/protobuf/proto"
+ "io"
+ "io/ioutil"
+ "log"
+ "net"
+ "os"
+ "os/exec"
+ "strings"
+ "time"
+)
+
+var (
+ kresdArgs = []string{
+ "-n",
+ "-q",
+ }
+)
+
+func qnameFromFrame(b []byte) (string, error) {
+ dt := &dnstap.Dnstap{}
+ var name string
+ if err := proto.Unmarshal(b, dt); err != nil {
+ return name, err
+ }
+
+ var msg_raw []byte
+ m := dt.Message
+ if *m.Type == dnstap.Message_CLIENT_QUERY {
+ msg_raw = m.QueryMessage
+ } else if *m.Type == dnstap.Message_CLIENT_RESPONSE {
+ msg_raw = m.ResponseMessage
+ } else {
+ return name, fmt.Errorf("incorrect message type: %v", *m.Type)
+ }
+
+ if msg_raw == nil {
+ return name, fmt.Errorf("no message payload")
+ }
+ if err := dns.IsMsg(msg_raw); err != nil {
+ return name, err
+ }
+ var msg dns.Msg
+ if err := msg.Unpack(msg_raw); err != nil {
+ return name, err
+ }
+ if len(msg.Question) < 1 {
+ return name, fmt.Errorf("question empty")
+ }
+ return msg.Question[0].Name, nil
+}
+
+func listenOn() (net.Addr, *os.File, error) {
+ udpConn, err := net.ListenUDP("udp", &net.UDPAddr{
+ IP: net.ParseIP("127.0.0.1"),
+ Port: 0,
+ })
+ if err != nil {
+ return nil, nil, err
+ }
+
+ file, err := udpConn.File()
+ if err != nil {
+ return nil, nil, err
+ }
+ return udpConn.LocalAddr(), file, nil
+}
+
+func runKresd(ctx context.Context, path, configFile string, grace time.Duration) (chan bool, error) {
+ ch := make(chan bool)
+ kresdArgs = append(kresdArgs, "-c"+configFile)
+ // we have 1 object in ExtraFiles with index 0
+ // child fd will be 3 + i = 3
+ kresdArgs = append(kresdArgs, "-S3")
+
+ file := ctx.Value("file").(*os.File)
+ debug := ctx.Value("debug").(bool)
+
+ cmd := exec.CommandContext(ctx, path, kresdArgs...)
+ cmd.ExtraFiles = []*os.File{file}
+
+ var stdout, stderr io.ReadCloser
+ var err error
+ if debug {
+ stdout, err = cmd.StdoutPipe()
+ if err != nil {
+ log.Printf("stdoutpipe: %v\n", err)
+ return ch, err
+ }
+
+ stderr, err = cmd.StderrPipe()
+ if err != nil {
+ log.Printf("stderrpipe: %v\n", err)
+ return ch, err
+ }
+ }
+
+ go func() {
+ status := false
+ defer func() {
+ ch <- status // kresd done
+ }()
+ if err := cmd.Start(); err != nil {
+ log.Printf("start: %v\n", err)
+ return
+ }
+ time.Sleep(grace)
+ ch <- true // Started kresd
+
+ if debug {
+ s, err := ioutil.ReadAll(stdout)
+ if err != nil {
+ log.Printf("readall: %v\n", err)
+ return
+ }
+ if len(s) > 0 {
+ fmt.Printf("stdout:\n%s\n", s)
+ }
+
+ s, err = ioutil.ReadAll(stderr)
+ if err != nil {
+ log.Printf("readall: %v\n", err)
+ return
+ }
+ if len(s) > 0 {
+ fmt.Printf("stderr:\n%s\n", s)
+ }
+ }
+
+ if err := cmd.Wait(); err != nil && err.Error() != "signal: killed" {
+ log.Printf("wait: %v\n", err)
+ return
+ }
+ status = true
+ }()
+ return ch, nil
+}
+
+func main() {
+ var (
+ unixSocket = flag.String("u", "dnstap.sock", "dnstap socket")
+ kresdPath = flag.String("cmd", "kresd", "kresd path")
+ configFile = flag.String("c", "config", "config file")
+ qnames = flag.String("q", ".", "list of comma separated zones")
+ grace = flag.String("g", "1s", "Time to wait for daemon start")
+ timeout = flag.String("t", "60s", "Test Timeout")
+ debug = flag.Bool("d", false, "Debug")
+ )
+
+ flag.Parse()
+
+ kresdStartGracePeriod, err := time.ParseDuration(*grace)
+ if err != nil {
+ panic(err)
+ }
+
+ testTimeout, err := time.ParseDuration(*timeout)
+ if err != nil {
+ panic(err)
+ }
+
+ input, err := dnstap.NewFrameStreamSockInputFromPath(*unixSocket)
+ if err != nil {
+ panic(err)
+ }
+
+ output := make(chan []byte)
+ go input.ReadInto(output)
+
+ ctx, cancel := context.WithTimeout(context.Background(), testTimeout)
+
+ // Create a UDP listening socket on random port
+ // FD will be passed on to kresd
+ addr, file, err := listenOn()
+ if err != nil {
+ panic(err)
+ }
+ if *debug {
+ log.Printf("listen addr:%v", addr)
+ }
+ ctx = context.WithValue(ctx, "file", file)
+ ctx = context.WithValue(ctx, "debug", *debug)
+
+ ch, err := runKresd(ctx, *kresdPath, *configFile, kresdStartGracePeriod)
+ if err != nil {
+ panic(err)
+ }
+
+ log.Printf("Waiting for kresd to start\n")
+ status := <-ch
+ if !status {
+ os.Exit(1) // error starting
+ }
+
+ go func() {
+ parts := strings.Split(*qnames, ",")
+
+ if len(parts) == 0 {
+ log.Printf("qname count is 0")
+ }
+ for _, name := range parts {
+ m := new(dns.Msg)
+ fqdn := dns.Fqdn(name)
+ m.SetQuestion(fqdn, dns.TypeA)
+ c := new(dns.Client)
+ resp, _, err := c.Exchange(m, fmt.Sprintf("%v", addr))
+ if err != nil {
+ log.Printf("%v\n", err)
+ os.Exit(1) // Test Failed
+ }
+ if *debug {
+ log.Printf("Response: %v", resp)
+ }
+
+ for range "QR" { // Checking Query and Response is the same ATM
+ o := <-output
+ if *debug {
+ log.Printf("raw dnstap:%v", o)
+ }
+ dtName, err := qnameFromFrame(o)
+ if err != nil {
+ log.Printf("%v\n", err)
+ os.Exit(1)
+ }
+ if fqdn != dtName {
+ log.Printf("expected %v got %v", fqdn, dtName)
+ os.Exit(1) // Test failed
+ }
+ log.Printf("matched qname: %v", dtName)
+ }
+ }
+ cancel() // Send signal to close daemon
+ }()
+
+ status = <-ch
+ if !status {
+ os.Exit(1) // error in wait
+ }
+ log.Printf("Tested OK\n")
+}
diff --git a/tests/dnstap/src/dnstap-test/run.sh b/tests/dnstap/src/dnstap-test/run.sh
new file mode 100755
index 0000000..2f32ea1
--- /dev/null
+++ b/tests/dnstap/src/dnstap-test/run.sh
@@ -0,0 +1,31 @@
+#!/bin/bash
+set -e
+KRESD_CMD=$1
+MESON_BUILD_ROOT=$(pwd)
+mkdir -p tests/dnstap
+export GOPATH=$MESON_BUILD_ROOT/tests/dnstap
+cd "$(dirname $0)"
+DNSTAP_TEST=dnstap-test
+
+if [ -z "$GITLAB_CI" ]; then
+ type -P go >/dev/null || exit 77
+ echo "Building the dnstap test and its dependencies..."
+ # some packages may be missing on the system right now
+ go get github.com/{FiloSottile/gvt,cloudflare/dns,dnstap/golang-dnstap,golang/protobuf/proto}
+else
+ # In CI we've prebuilt dependencies into the default GOPATH.
+ # We're in a scratch container, so we just add the dnstap test inside.
+ export GOPATH=/root/go
+fi
+DTAP=$GOPATH/src/$DNSTAP_TEST
+rm -f $DTAP && ln -s $(realpath ..)/$DNSTAP_TEST $DTAP
+go install $DNSTAP_TEST
+
+
+CONFIG=$(realpath ./config)
+ZONES="fake1.localdomain,fake2.localdomain,fake3.localdomain"
+TIMEOUT=60s
+GRACE=5s
+cd $MESON_BUILD_ROOT/tests/dnstap # don't leave stuff like *.mdb in ./.
+$GOPATH/bin/$DNSTAP_TEST -c $CONFIG -cmd $KRESD_CMD -q $ZONES -t $TIMEOUT -g $GRACE -d
+
diff --git a/tests/dnstap/src/dnstap-test/vendor/manifest b/tests/dnstap/src/dnstap-test/vendor/manifest
new file mode 100644
index 0000000..27c1dec
--- /dev/null
+++ b/tests/dnstap/src/dnstap-test/vendor/manifest
@@ -0,0 +1,55 @@
+{
+ "version": 0,
+ "dependencies": [
+ {
+ "importpath": "github.com/cloudflare/dns",
+ "repository": "https://github.com/cloudflare/dns",
+ "vcs": "git",
+ "revision": "e20ffa3da443071c7b3d164dec5b1f80dfb2ecf3",
+ "branch": "master",
+ "notests": true
+ },
+ {
+ "importpath": "github.com/dnstap/golang-dnstap",
+ "repository": "https://github.com/dnstap/golang-dnstap",
+ "vcs": "git",
+ "revision": "0145fd8482619f9c04788c7ba4e96cdeef64a041",
+ "branch": "master",
+ "notests": true
+ },
+ {
+ "importpath": "github.com/farsightsec/golang-framestream",
+ "repository": "https://github.com/farsightsec/golang-framestream",
+ "vcs": "git",
+ "revision": "b600ccf606747139c84b6d69b5c3988164db4d42",
+ "branch": "master",
+ "notests": true
+ },
+ {
+ "importpath": "github.com/golang/protobuf/proto",
+ "repository": "https://github.com/golang/protobuf",
+ "vcs": "git",
+ "revision": "8ee79997227bf9b34611aee7946ae64735e6fd93",
+ "branch": "master",
+ "path": "/proto",
+ "notests": true
+ },
+ {
+ "importpath": "github.com/golang/protobuf/ptypes/any",
+ "repository": "https://github.com/golang/protobuf",
+ "vcs": "git",
+ "revision": "8ee79997227bf9b34611aee7946ae64735e6fd93",
+ "branch": "master",
+ "path": "ptypes/any",
+ "notests": true
+ },
+ {
+ "importpath": "github.com/miekg/dns",
+ "repository": "https://github.com/miekg/dns",
+ "vcs": "git",
+ "revision": "f4d2b086946a624202dc59e6a43f72e8f3f02bc1",
+ "branch": "master",
+ "notests": true
+ }
+ ]
+} \ No newline at end of file
diff --git a/tests/integration/deckard/LICENSE b/tests/integration/deckard/LICENSE
new file mode 100644
index 0000000..7f30d4f
--- /dev/null
+++ b/tests/integration/deckard/LICENSE
@@ -0,0 +1,23 @@
+Copyright (c) 2016, CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/tests/integration/deckard/README.rst b/tests/integration/deckard/README.rst
new file mode 100644
index 0000000..12c3b68
--- /dev/null
+++ b/tests/integration/deckard/README.rst
@@ -0,0 +1,95 @@
+DNS test harness (Deckard)
+==========================
+
+Deckard is a DNS software testing tool that creates a controlled network environment for reproducible tests.
+
+In essence, it works like this:
+
+- Deckard runs given binaries as subprocesses in an isolated network environment.
+- When binaries are up, Deckard sends scripted queries and checks replies.
+- When a binary attempts to contact another server, Deckard intercepts the communication and replies with scripted answer.
+- Deckard can simulate network issues, DNS environment changes, and fake time (for DNSSEC validation tests).
+
+No changes to real network setup are required because all network communications are made in a network namespace.
+
+Test cases are described by `scenarios <doc/scenario_guide.rst>`_ that contain:
+
+- A declarative description of the environment (e.g. what queries can the binary under test make and what Deckard should answer)
+- A sequence of queries (and expected answers), and other events (e.g. time jumps forward)
+
+
+Requirements
+------------
+
+Deckard requires following software to be installed:
+
+- Python >= 3.6
+- Linux kernel >= 3.8
+- augeas_ - library for editing configuration files
+- dnspython_ - DNS library for Python
+- Jinja2_ - template engine for generating config files
+- PyYAML_ - YAML parser for Python
+- python-augeas_ - Python bindings for augeas API
+- pytest_ - testing framework for Python, used for running the test cases
+- pytest-xdist_ - module for pytest for distributed testing
+- pytest-forked_ - module for pytest for testing in forked subprocesses
+- pyroute2_ - Python netlink library (managing IP addresses, routes,…)
+- dumpcap_ - command line tool for network capture (part of Wireshark)
+- faketime_ - used for faking the time in tests of DNSSEC
+
+Compatibility
+-------------
+
+Deckard uses user and network namespaces to simulate the network environment
+so only Linux (with kernel version 3.8 or newer) is supported. It however is possible
+to run Deckard on other platforms in Docker. Just note that your container has to run as
+`--priviledged` for the namespaces to run properly.
+
+Usage
+-----
+
+- `User guide <doc/user_guide.rst>`_ describes how to run tests on a binary.
+- `Scenario guide <doc/scenario_guide.rst>`_ describes how to write a new test.
+- `Devel guide <doc/devel_guide.rst>`_ contains some tips for Deckard developers.
+
+
+License
+-------
+
+See `LICENSE <LICENSE>`_ file.
+
+
+Acknowledgments
+---------------
+
+The test scenario design and a lot of tests were written by `NLnet Labs`_ for ``testbound`` suite used by `Unbound`_ (BSD licensed). We are grateful that ``testbound`` authors are `willing to discuss <https://unbound.nlnetlabs.nl/pipermail/unbound-users/2017-March/004699.html>`_ further Deckard development.
+
+The original test case format is described in the `header file replay.h <http://unbound.net/documentation/doxygen/replay_8h.html#a6f204646f02cc4debbaf8a9b3fdb59a7>`_ distributed with `Unbound`_.
+
+
+Contacting us
+-------------
+
+Please report problems to our GitLab: https://gitlab.nic.cz/knot/deckard/issues
+
+If you have any comments feel free to send e-mail to knot-resolver@labs.nic.cz! Do not get confused by the name, we are happy if you want to use Deckard with any software.
+
+Happy testing.
+
+
+.. _`augeas`: http://augeas.net/
+.. _`CSR`: http://apple.stackexchange.com/questions/193368/what-is-the-rootless-feature-in-el-capitan-really
+.. _`Jinja2`: http://jinja.pocoo.org/
+.. _`Knot Resolver`: https://gitlab.nic.cz/knot/resolver/blob/master/README.md
+.. _`NLnet Labs`: https://www.nlnetlabs.nl/
+.. _`PowerDNS Recursor`: https://doc.powerdns.com/md/recursor/
+.. _`PyYAML`: http://pyyaml.org/
+.. _`Unbound`: https://www.unbound.net/
+.. _`dnspython`: http://www.dnspython.org/
+.. _`libfaketime`: https://github.com/wolfcw/libfaketime
+.. _`python-augeas`: https://pypi.org/project/python-augeas/
+.. _`pytest`: https://pytest.org/
+.. _`pytest-xdist`: https://pypi.python.org/pypi/pytest-xdist
+.. _`pytest-forked`: https://pypi.python.org/pypi/pytest-forked
+.. _`pyroute2`: https://pyroute2.org/
+.. _`dumpcap`: https://www.wireshark.org/docs/man-pages/dumpcap.html
diff --git a/tests/integration/deckard/ci/README.rst b/tests/integration/deckard/ci/README.rst
new file mode 100644
index 0000000..39955f9
--- /dev/null
+++ b/tests/integration/deckard/ci/README.rst
@@ -0,0 +1,4 @@
+Deckard CI
+==========
+
+For testing with Deckard in Docker use kresd ci image: registry.labs.nic.cz/knot/knot-resolver/ci:debian-stable
diff --git a/tests/integration/deckard/ci/__init__.py b/tests/integration/deckard/ci/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/integration/deckard/ci/__init__.py
diff --git a/tests/integration/deckard/ci/common.sh b/tests/integration/deckard/ci/common.sh
new file mode 100644
index 0000000..5430e64
--- /dev/null
+++ b/tests/integration/deckard/ci/common.sh
@@ -0,0 +1,17 @@
+set -o errexit -o nounset
+
+HEAD="$(git log -1 --format="%H" HEAD)"
+MERGEBASE="$(git merge-base origin/master "${HEAD}")"
+LOGDIR="$(pwd)"
+PYTHON=${PYTHON:-"python3"}
+CIDIR="$(dirname "${0}")"
+
+# workaround for Gitlab's missing support for absolute paths in artifacts:
+# https://gitlab.com/gitlab-org/gitlab-ci-multi-runner/issues/1011
+declare -a LOGS
+LOGS[0]="" # avoid unbound variable error if user does not specify own logs
+function collect_logs {
+ set +o errexit
+ test -n "${LOGS[*]}" && cp "--target-directory=${LOGDIR}" ${LOGS[*]}
+}
+trap collect_logs EXIT
diff --git a/tests/integration/deckard/ci/compare-rplint.sh b/tests/integration/deckard/ci/compare-rplint.sh
new file mode 100755
index 0000000..0146dc9
--- /dev/null
+++ b/tests/integration/deckard/ci/compare-rplint.sh
@@ -0,0 +1,31 @@
+#!/bin/bash
+set -o nounset -o xtrace -o errexit
+source "$(dirname "$(readlink -f "$0")")/common.sh"
+
+
+function find_new_tests {
+ : detect tests affected by current merge request
+ : store list of modified tests in ${NEW_TESTS_FILE}
+ git diff --name-only --diff-filter=AM ${MERGEBASE} ${HEAD} | fgrep .rpl > "${NEW_TESTS_FILE}" || : no new tests detected
+}
+
+NEW_TESTS_FILE="/tmp/new_tests"
+find_new_tests
+
+truncate -s0 /tmp/rplint_fails
+
+: run rplint of all new tests
+FAIL=0
+cat /tmp/new_tests
+for test in $(cat ${NEW_TESTS_FILE})
+do
+ ${PYTHON} -m rplint $test >> /tmp/rplint_fails || FAIL=1
+done
+
+: if even one of the test does not pass rplint, fail
+if [ "$FAIL" -eq 1 ]
+then
+ cat /tmp/rplint_fails
+ exit 1
+fi
+exit 0
diff --git a/tests/integration/deckard/ci/compare-tests.sh b/tests/integration/deckard/ci/compare-tests.sh
new file mode 100755
index 0000000..63d8c67
--- /dev/null
+++ b/tests/integration/deckard/ci/compare-tests.sh
@@ -0,0 +1,30 @@
+#!/bin/bash
+set -o nounset -o xtrace -o errexit
+source "$(dirname "$0")/common.sh"
+TESTRUNNER="$1"
+: comparing results from test script "${TESTRUNNER}"
+
+# Run specified test runner on HEAD and again on merge base for master..HEAD
+# Fail if result of any test not modified between master..HEAD changed
+# (i.e. any change in Deckard should not change results of non-modified tests)
+
+function find_modified_tests {
+ : detect tests affected by current merge request
+ : store list of modified tests in ${MODIFIED_TESTS_FILE}
+ git diff --numstat "${MERGEBASE}..${HEAD}" | cut -f 3 | fgrep .rpl > "${MODIFIED_TESTS_FILE}" || : no modified tests detected
+}
+
+MODIFIED_TESTS_FILE="/tmp/modified_tests"
+find_modified_tests
+LOGS[0]="${MODIFIED_TESTS_FILE}"
+LOGS[1]="/tmp/base.xml"
+LOGS[2]="/tmp/head.xml"
+
+: get test results from version under test
+"${TESTRUNNER}" -n $(nproc) --junit-xml=/tmp/head.xml || : some tests on HEAD ${HEAD} failed
+
+: get test results from common ancestor with master branch
+git checkout --force --detach "${MERGEBASE}"
+git clean -xdf
+"${TESTRUNNER}" -n $(nproc) --junit-xml=/tmp/base.xml || : some tests on merge base ${MERGEBASE} failed
+"${CIDIR}/junit-compare.py" /tmp/head.xml /tmp/base.xml /tmp/modified_tests && echo "OK, no differences found"
diff --git a/tests/integration/deckard/ci/junit-compare.py b/tests/integration/deckard/ci/junit-compare.py
new file mode 100755
index 0000000..23409bb
--- /dev/null
+++ b/tests/integration/deckard/ci/junit-compare.py
@@ -0,0 +1,38 @@
+#!/usr/bin/python3
+
+import sys
+
+import xml.etree.ElementTree as xml
+
+
+def parse_junit_xml(filename):
+ """
+ Transform junit XML file into set of tuples:
+ (test description, file name, test result)
+ """
+ results = set()
+ suite = xml.parse(filename).getroot().find("testsuite")
+ for case in suite:
+ if case.find("failure") is not None: # Because empty XML elements are falsey
+ results.add((case.get("name"), case.get("name").split("'")[1], "FAILED"))
+ elif case.find("skipped") is not None:
+ results.add((case.get("name"), case.get("name").split("'")[1], "SKIPPED"))
+ else:
+ results.add((case.get("name"), case.get("name").split("'")[1], "PASSED"))
+
+ return results
+
+
+new = sys.argv[1]
+old = sys.argv[2]
+with open(sys.argv[3]) as f:
+ modified_tests = [line.strip() for line in f.readlines()]
+
+test_diffs = parse_junit_xml(old) ^ parse_junit_xml(new)
+errorneous_rpls = [diff[1] for diff in test_diffs
+ if diff[1] not in modified_tests]
+if errorneous_rpls:
+ print('FAIL! Following tests changed their result without test modification:')
+ for rpl in sorted(set(errorneous_rpls)):
+ print(rpl)
+ sys.exit(1)
diff --git a/tests/integration/deckard/ci/mypy-run.sh b/tests/integration/deckard/ci/mypy-run.sh
new file mode 100755
index 0000000..1abfef1
--- /dev/null
+++ b/tests/integration/deckard/ci/mypy-run.sh
@@ -0,0 +1,17 @@
+#!/usr/bin/env bash
+set -o nounset -o errexit
+source "$(dirname "$0")/common.sh"
+
+PYFILES=$(find . \
+ -path ./.git -prune -o \
+ -path ./contrib -o \
+ -path ./tools -prune -o \
+ -type d -exec test -e '{}/__init__.py' \; -print -prune -o \
+ -name '*.py' -print -o \
+ -type f -exec grep -qsm1 '^#!.*\bpython' '{}' \; -print)
+set -e
+
+${PYTHON} -m mypy --ignore-missing-imports ${PYFILES}
+
+# tools
+${PYTHON} -m mypy --ignore-missing-imports tools
diff --git a/tests/integration/deckard/ci/pylint-run.sh b/tests/integration/deckard/ci/pylint-run.sh
new file mode 100755
index 0000000..107c674
--- /dev/null
+++ b/tests/integration/deckard/ci/pylint-run.sh
@@ -0,0 +1,12 @@
+#!/bin/bash
+set -o nounset -o errexit
+source "$(dirname "$0")/common.sh"
+
+PYFILES=$(find . \
+ -path ./.git -prune -o \
+ -path ./contrib -o \
+ -type d -exec test -e '{}/__init__.py' \; -print -prune -o \
+ -name '*.py' -print -o \
+ -type f -exec grep -qsm1 '^#!.*\bpython' '{}' \; -print)
+
+PYTHONPATH=.${PYTHONPATH:+":${PYTHONPATH}"} ${PYTHON} -m pylint -j 0 --rcfile pylintrc ${PYFILES}
diff --git a/tests/integration/deckard/ci/raw_id.py b/tests/integration/deckard/ci/raw_id.py
new file mode 100755
index 0000000..cc4fe8e
--- /dev/null
+++ b/tests/integration/deckard/ci/raw_id.py
@@ -0,0 +1,20 @@
+#!/usr/bin/python3
+import sys
+
+import dns.message
+
+from pydnstest import mock_client
+
+q = dns.message.make_query("anything", "A")
+qid = q.id.to_bytes(2, "big", signed=False)
+sock = mock_client.setup_socket("1.2.3.4", 53)
+mock_client.send_query(sock, q)
+a = mock_client.get_answer(sock)
+print(qid)
+print(a)
+
+
+if a == qid:
+ sys.exit(0)
+else:
+ sys.exit(1)
diff --git a/tests/integration/deckard/ci/raw_id_check.sh b/tests/integration/deckard/ci/raw_id_check.sh
new file mode 100755
index 0000000..336b37b
--- /dev/null
+++ b/tests/integration/deckard/ci/raw_id_check.sh
@@ -0,0 +1,7 @@
+#!/bin/bash
+make depend
+cat env.sh
+source env.sh
+python3 -m pydnstest.testserver --scenario $(pwd)/tests/deckard_raw_id.rpl &
+sleep 1
+python3 -m ci.raw_id \ No newline at end of file
diff --git a/tests/integration/deckard/ci/runlocally.sh b/tests/integration/deckard/ci/runlocally.sh
new file mode 100755
index 0000000..25bf0c9
--- /dev/null
+++ b/tests/integration/deckard/ci/runlocally.sh
@@ -0,0 +1,41 @@
+#!/bin/bash
+set -o nounset -o errexit
+CIDIR="$(dirname "$0")"
+ORIGNAME="$(git symbolic-ref -q --short HEAD || git describe --all --always HEAD)"
+FAILURE_DETECTED="?"
+
+function checkout_back {
+ git checkout --force "${ORIGNAME}" || { echo "Warning: unable to checkout back!"; exit 5; }
+
+ test "${FAILURE_DETECTED}" "==" "0" && echo "All tests passed, good work!"
+ test "${FAILURE_DETECTED}" "!=" "0" && echo "Problem found, go fix it!"
+}
+
+STATUS=$(git status --untracked-files=normal --porcelain)
+test -n "${STATUS}" && echo "Working tree is dirty, commit your changes now." && exit 2
+
+# return back to whatever branch we were on the beginning
+# to avoid need for git checkout before fixing reported bugs
+trap checkout_back EXIT
+trap "{ FAILURE_DETECTED=1; }" ERR
+
+"${CIDIR}"/compare-rplint.sh
+checkout_back
+git clean -xdf
+
+"${CIDIR}"/compare-pylint.sh
+checkout_back
+git clean -xdf
+
+"${CIDIR}"/compare-pep8.sh
+checkout_back
+git clean -xdf
+
+"${CIDIR}"/compare-tests.sh "${CIDIR}/../kresd_run.sh"
+checkout_back
+git clean -xdf
+
+# at this point all the tests passed so we can clean up
+git clean -xdf
+FAILURE_DETECTED=0
+trap - ERR
diff --git a/tests/integration/deckard/configs/getdns.yaml b/tests/integration/deckard/configs/getdns.yaml
new file mode 100644
index 0000000..a5d1a2e
--- /dev/null
+++ b/tests/integration/deckard/configs/getdns.yaml
@@ -0,0 +1,12 @@
+programs:
+- name: getdns
+ binary: getdns_query
+ additional:
+ - -C
+ - getdns.conf
+ templates:
+ - template/getdns.j2
+ - template/dnssec_getdns.j2
+ configs:
+ - getdns.conf
+ - getdns-root.key
diff --git a/tests/integration/deckard/configs/knotd_master.yaml b/tests/integration/deckard/configs/knotd_master.yaml
new file mode 100644
index 0000000..2e08b72
--- /dev/null
+++ b/tests/integration/deckard/configs/knotd_master.yaml
@@ -0,0 +1,10 @@
+programs:
+- name: knotd
+ binary: knotd
+ additional:
+ - -c
+ - ./knotd.conf
+ templates:
+ - "template/knotd_master.j2"
+ configs:
+ - "knotd.conf"
diff --git a/tests/integration/deckard/configs/knotd_slave.yaml b/tests/integration/deckard/configs/knotd_slave.yaml
new file mode 100644
index 0000000..4655ded
--- /dev/null
+++ b/tests/integration/deckard/configs/knotd_slave.yaml
@@ -0,0 +1,10 @@
+programs:
+- name: knotd
+ binary: knotd
+ additional:
+ - -c
+ - ./knotd.conf
+ templates:
+ - "template/knotd_slave.j2"
+ configs:
+ - "knotd.conf" \ No newline at end of file
diff --git a/tests/integration/deckard/configs/kresd.yaml b/tests/integration/deckard/configs/kresd.yaml
new file mode 100644
index 0000000..3c9350c
--- /dev/null
+++ b/tests/integration/deckard/configs/kresd.yaml
@@ -0,0 +1,9 @@
+programs:
+- name: kresd
+ binary: kresd
+ additional:
+ - -n
+ templates:
+ - template/kresd.j2
+ configs:
+ - config
diff --git a/tests/integration/deckard/configs/named.yaml b/tests/integration/deckard/configs/named.yaml
new file mode 100644
index 0000000..06c69f8
--- /dev/null
+++ b/tests/integration/deckard/configs/named.yaml
@@ -0,0 +1,15 @@
+programs:
+- name: named
+ binary: named
+ additional:
+ - -g
+ - -d
+ - "99"
+ - -c
+ - named.conf
+ templates:
+ - template/named.j2
+ - template/hints_zone.j2
+ configs:
+ - named.conf
+ - hints.zone
diff --git a/tests/integration/deckard/configs/pdns.yaml b/tests/integration/deckard/configs/pdns.yaml
new file mode 100644
index 0000000..c9a3d23
--- /dev/null
+++ b/tests/integration/deckard/configs/pdns.yaml
@@ -0,0 +1,15 @@
+programs:
+- name: pdns
+ binary: pdns_recursor
+ additional:
+ - --config-dir=./
+ templates:
+ - template/pdns_recursor.j2
+ - template/hints_zone.j2
+ - template/pdns_dnssec.j2
+ configs:
+ - recursor.conf
+ - hints.pdns
+ - dnssec.lua
+ # SIGTERM leads to return code -15 instead of clean 0 so we have to ignore it
+ ignore_exit_code: true
diff --git a/tests/integration/deckard/configs/unbound.yaml b/tests/integration/deckard/configs/unbound.yaml
new file mode 100644
index 0000000..3c200db
--- /dev/null
+++ b/tests/integration/deckard/configs/unbound.yaml
@@ -0,0 +1,13 @@
+programs:
+- name: unbound
+ binary: unbound
+ additional:
+ - -d
+ - -c
+ - unbound.conf
+ templates:
+ - template/unbound.j2
+ - template/hints_zone.j2
+ configs:
+ - unbound.conf
+ - hints.zone
diff --git a/tests/integration/deckard/conftest.py b/tests/integration/deckard/conftest.py
new file mode 100644
index 0000000..8cf9004
--- /dev/null
+++ b/tests/integration/deckard/conftest.py
@@ -0,0 +1,126 @@
+import glob
+import os
+import re
+from collections import namedtuple
+
+import pytest
+import yaml
+
+from contrib.namespaces import LinuxNamespace
+
+Scenario = namedtuple("Scenario", ["path", "qmin", "config"])
+
+
+def config_sanity_check(config_dict, config_name):
+ """Checks if parsed configuration is valid"""
+ mandatory_keys = {'name', 'binary', 'templates', 'configs', 'additional'}
+ for cfg in config_dict['programs']:
+ missing_keys = mandatory_keys - set(cfg.keys())
+ assert not missing_keys, 'Mandatory fields in configuration are missing: %s' % missing_keys
+
+ # sanity check templates vs. configs
+ assert len(cfg['templates']) == len(cfg['configs']),\
+ ('Number of jinja2 template files is not equal '
+ 'to number of config files to be generated for '
+ 'program "%s" (%s), i.e. len(templates) != len(configs)'
+ % (cfg['name'], config_name))
+
+ for additional in cfg["additional"]:
+ assert isinstance(additional, str),\
+ "All additional arguments in yaml should be strings. (%s, %s)"\
+ % (cfg['name'], config_name)
+
+
+def get_qmin_config(path):
+ """Reads configuration from the *.rpl file and determines query-minimization setting."""
+ with open(path) as f:
+ for line in f:
+ if re.search(r"^CONFIG_END", line) or re.search(r"^SCENARIO_BEGIN", line):
+ return None
+ if re.search(r"^\s*query-minimization:\s*(on|yes)", line):
+ return True
+ if re.search(r"^\s*query-minimization:\s*(off|no)", line):
+ return False
+ return None
+
+
+def scenarios(paths, configs):
+ """Returns list of *.rpl files from given path and packs them with their minimization setting"""
+
+ assert len(paths) == len(configs),\
+ "Number of --config has to be equal to number of --scenarios arguments."
+
+ scenario_list = []
+
+ for path, config in zip(paths, configs):
+ with open(config) as f:
+ config_dict = yaml.load(f, yaml.SafeLoader)
+ config_sanity_check(config_dict, config)
+
+ if os.path.isfile(path):
+ filelist = [path] # path to single file, accept it
+ else:
+ filelist = sorted(glob.glob(os.path.join(path, "*.rpl")))
+
+ if not filelist:
+ raise ValueError('no *.rpl files found in path "{}"'.format(path))
+
+ for file in filelist:
+ scenario_list.append(Scenario(file, get_qmin_config(file), config_dict))
+
+ return scenario_list
+
+
+def rpls(paths):
+ for path in paths:
+ if os.path.isfile(path):
+ filelist = [path] # path to single file, accept it
+ else:
+ filelist = sorted(glob.glob(os.path.join(path, "*.rpl")))
+
+ return filelist
+
+
+def pytest_addoption(parser):
+ parser.addoption("--config", action="append", help="path to Deckard configuration .yaml file")
+ parser.addoption("--scenarios", action="append", help="directory with .rpl files")
+ parser.addoption("--retries", action="store", help=("number of retries per"
+ "test when Deckard is under load"))
+
+
+def pytest_generate_tests(metafunc):
+ """This is pytest weirdness to parametrize the test over all the *.rpl files.
+ See https://docs.pytest.org/en/latest/parametrize.html#basic-pytest-generate-tests-example
+ for more info."""
+
+ if 'scenario' in metafunc.fixturenames:
+ if metafunc.config.option.config is None:
+ configs = []
+ else:
+ configs = metafunc.config.option.config
+
+ if metafunc.config.option.scenarios is None:
+ paths = ["sets/resolver"] * len(configs)
+ else:
+ paths = metafunc.config.option.scenarios
+
+ metafunc.parametrize("scenario", scenarios(paths, configs), ids=str)
+ if 'rpl_path' in metafunc.fixturenames:
+ paths = metafunc.config.option.scenarios
+ metafunc.parametrize("rpl_path", rpls(paths), ids=str)
+ if 'max_retries' in metafunc.fixturenames:
+ max_retries = metafunc.config.option.retries
+ if max_retries is None:
+ max_retries = 3
+ metafunc.parametrize("max_retries", [max_retries], ids=lambda id: "max-retries-"+str(id))
+
+
+def pytest_collection_modifyitems(items):
+ """We automatically mark test that need faking monotonic time and run them separately."""
+ for item in items:
+ if "monotonic" in item.nodeid:
+ item.add_marker(pytest.mark.monotonic)
+
+
+def pytest_runtest_setup(item): # pylint: disable=unused-argument
+ LinuxNamespace("user").__enter__()
diff --git a/tests/integration/deckard/contrib/__init__.py b/tests/integration/deckard/contrib/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/integration/deckard/contrib/__init__.py
diff --git a/tests/integration/deckard/contrib/deckard.vim b/tests/integration/deckard/contrib/deckard.vim
new file mode 100644
index 0000000..3ae687a
--- /dev/null
+++ b/tests/integration/deckard/contrib/deckard.vim
@@ -0,0 +1,26 @@
+" Deckard syntax highlighting & folding
+"
+" Usage: Put following lines into ~/.vim/ftdetect/deckard.vim
+" au BufRead,BufNewFile *.rpl set filetype=deckard
+" au BufRead,BufNewFile *.stc set foldmethod=syntax
+
+syntax keyword Keyword MATCH STEP ADJUST MANDATORY RAW
+syntax keyword Structure CONFIG_END
+syntax keyword Function CHECK_ANSWER QUERY TIME_PASSES
+
+syntax region deckardEntry matchgroup=Structure start="ENTRY_BEGIN" end="ENTRY_END" fold transparent
+syntax region deckardRange matchgroup=Structure start="RANGE_BEGIN" end="RANGE_END" fold transparent
+syntax region deckardScenario matchgroup=Structure start="SCENARIO_BEGIN" end="SCENARIO_END" fold transparent
+
+syntax match deckardSection 'SECTION \+[^ ]\+'
+syntax match deckardReply 'REPLY.*'
+
+syntax match Comment ';.*$'
+
+hi def link deckardEntry Folded
+hi def link deckardRange Folded
+hi def link deckardScenario Folded
+hi def link deckardSection Special
+hi def link deckardReply String
+
+let b:current_syntax = 'deckard'
diff --git a/tests/integration/deckard/contrib/licenses/ISC b/tests/integration/deckard/contrib/licenses/ISC
new file mode 100644
index 0000000..e813ff3
--- /dev/null
+++ b/tests/integration/deckard/contrib/licenses/ISC
@@ -0,0 +1,15 @@
+SPDX-License-Identifier: ISC
+SPDX-URL: https://spdx.org/licenses/ISC.html
+License-Text:
+
+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 THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS. IN NO EVENT SHALL THE AUTHOR 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.
diff --git a/tests/integration/deckard/contrib/namespaces.py b/tests/integration/deckard/contrib/namespaces.py
new file mode 100644
index 0000000..16c2285
--- /dev/null
+++ b/tests/integration/deckard/contrib/namespaces.py
@@ -0,0 +1,125 @@
+# SPDX-License-Identifier: ISC
+# Source: https://vincentbernat.github.io/lldpd/
+# Copyright (c) 2008-2017, Vincent Bernat <vincent@bernat.im>
+
+import contextlib
+import ctypes
+import errno
+import os
+import signal
+
+# All allowed namespace types
+NAMESPACE_FLAGS = dict(mnt=0x00020000,
+ uts=0x04000000,
+ ipc=0x08000000,
+ user=0x10000000,
+ pid=0x20000000,
+ net=0x40000000)
+STACKSIZE = 1024*1024
+
+libc = ctypes.CDLL('libc.so.6', use_errno=True)
+
+
+@contextlib.contextmanager
+def keep_directory():
+ """Restore the current directory on exit."""
+ pwd = os.getcwd()
+ try:
+ yield
+ finally:
+ os.chdir(pwd)
+
+
+class LinuxNamespace:
+ """Combine several namespaces into one.
+ This gets a list of namespace types to create and combine into one. The
+ combined namespace can be used as a context manager to enter all the
+ created namespaces and exit them at the end.
+ """
+
+ def __init__(self, *namespaces):
+ self.namespaces = namespaces
+ for ns in namespaces:
+ assert ns in NAMESPACE_FLAGS
+
+ # Get a pipe to signal the future child to exit
+ self.pipe = os.pipe()
+
+ # First, create a child in the given namespaces
+ child = ctypes.CFUNCTYPE(ctypes.c_int)(self.child)
+ child_stack = ctypes.create_string_buffer(STACKSIZE)
+ child_stack_pointer = ctypes.c_void_p(
+ ctypes.cast(child_stack,
+ ctypes.c_void_p).value + STACKSIZE)
+ flags = signal.SIGCHLD
+ for ns in namespaces:
+ flags |= NAMESPACE_FLAGS[ns]
+ pid = libc.clone(child, child_stack_pointer, flags)
+ if pid == -1:
+ e = ctypes.get_errno()
+ raise OSError(e, os.strerror(e))
+
+ # If a user namespace, map UID 0 to the current one
+ if 'user' in namespaces:
+ uid_map = '0 {} 1'.format(os.getuid())
+ gid_map = '0 {} 1'.format(os.getgid())
+ with open('/proc/{}/uid_map'.format(pid), 'w') as f:
+ f.write(uid_map)
+ with open('/proc/{}/setgroups'.format(pid), 'w') as f:
+ f.write('deny')
+ with open('/proc/{}/gid_map'.format(pid), 'w') as f:
+ f.write(gid_map)
+
+ # Retrieve a file descriptor to this new namespace
+ self.next = [os.open('/proc/{}/ns/{}'.format(pid, x),
+ os.O_RDONLY) for x in namespaces]
+
+ # Keep a file descriptor to our old namespaces
+ self.previous = [os.open('/proc/self/ns/{}'.format(x),
+ os.O_RDONLY) for x in namespaces]
+
+ # Tell the child all is done and let it die
+ os.close(self.pipe[0])
+ if 'pid' not in namespaces:
+ os.close(self.pipe[1])
+ self.pipe = None
+ os.waitpid(pid, 0)
+
+ def __del__(self):
+ pass
+
+ def child(self):
+ """Cloned child.
+ Just be here until our parent extract the file descriptor from
+ us.
+ """
+ os.close(self.pipe[1])
+
+ while True:
+ try:
+ os.read(self.pipe[0], 1)
+ except OSError as e:
+ if e.errno in [errno.EAGAIN, errno.EINTR]:
+ continue
+ break
+
+ os._exit(0) # Adopted code. pylint: disable=protected-access
+
+ def fd(self, namespace):
+ """Return the file descriptor associated to a namespace"""
+ assert namespace in self.namespaces
+ return self.next[self.namespaces.index(namespace)]
+
+ def __enter__(self):
+ with keep_directory():
+ for n in self.next:
+ if libc.setns(n, 0) == -1:
+ ns = self.namespaces[self.next.index(n)] # noqa Adopted code. pylint: disable=unused-variable
+ e = ctypes.get_errno()
+ raise OSError(e, os.strerror(e))
+
+ def __exit__(self, *exc):
+ pass
+
+ def __repr__(self):
+ return 'Namespace({})'.format(", ".join(self.namespaces))
diff --git a/tests/integration/deckard/contrib/namespaces.spdx b/tests/integration/deckard/contrib/namespaces.spdx
new file mode 100644
index 0000000..4eea4e8
--- /dev/null
+++ b/tests/integration/deckard/contrib/namespaces.spdx
@@ -0,0 +1,10 @@
+SPDXVersion: SPDX-2.1
+DataLicense: CC0-1.0
+SPDXID: SPDXRef-DOCUMENT
+DocumentName: lldpd-namespaces
+DocumentNamespace: http://spdx.org/spdxdocs/spdx-v2.1-ab80d102-398e-43c0-b978-7a9559f5a76b
+
+PackageName: lldpd-namespaces
+PackageDownloadLocation: git+https://github.com/vincentbernat/lldpd.git@987454994be604a3b8c27e58d68ff7d88fcf24de#tests/integration/fixtures/namespaces.py
+PackageOriginator: Person: Vincent Bernat (vincent@bernat.im)
+PackageLicenseDeclared: ISC
diff --git a/tests/integration/deckard/deckard.py b/tests/integration/deckard/deckard.py
new file mode 100755
index 0000000..45fd045
--- /dev/null
+++ b/tests/integration/deckard/deckard.py
@@ -0,0 +1,253 @@
+#!/usr/bin/env python3
+import errno
+import logging
+import logging.config
+import os
+import shlex
+import shutil
+import socket
+import subprocess
+import time
+from datetime import datetime
+from typing import Set # noqa
+
+import jinja2
+
+from pydnstest import scenario, testserver
+
+# path to Deckard files
+INSTALLDIR = os.path.dirname(os.path.abspath(__file__))
+# relative to working directory
+TRUST_ANCHOR_SUBDIR = 'ta'
+
+
+class DeckardUnderLoadError(Exception):
+ pass
+
+
+def setup_internal_addresses(context):
+ context["DECKARD_IP"] = context["if_manager"].assign_internal_address(context["_SOCKET_FAMILY"])
+ for program in context["programs"]:
+ program["address"] = context["if_manager"].assign_internal_address(
+ context["_SOCKET_FAMILY"])
+
+
+def write_timestamp_file(path, tst):
+ with open(path, 'w') as time_file:
+ time_file.write(datetime.fromtimestamp(tst).strftime('@%Y-%m-%d %H:%M:%S'))
+
+
+def setup_faketime(context):
+ """
+ Setup environment shared between Deckard and binaries under test.
+
+ Environment for child processes must be based on on.environ as modified
+ by this function.
+ """
+ # Set up libfaketime
+ os.environ["FAKETIME_NO_CACHE"] = "1"
+ os.environ["FAKETIME_TIMESTAMP_FILE"] = os.path.join(context["tmpdir"], ".time")
+ os.unsetenv("FAKETIME")
+
+ write_timestamp_file(os.environ["FAKETIME_TIMESTAMP_FILE"],
+ context.get('_OVERRIDE_TIMESTAMP', time.time()))
+
+
+def setup_daemon_environment(program_config, context):
+ program_config["WORKING_DIR"] = os.path.join(context["tmpdir"], program_config["name"])
+ os.mkdir(program_config['WORKING_DIR'])
+ program_config["DAEMON_NAME"] = program_config["name"]
+ program_config['SELF_ADDR'] = program_config['address']
+ program_config['TRUST_ANCHOR_FILES'] = create_trust_anchor_files(
+ context["TRUST_ANCHOR_FILES"], program_config['WORKING_DIR'])
+
+
+def create_trust_anchor_files(ta_files, work_dir):
+ """
+ Write trust anchor files in specified working directory.
+
+ Params:
+ ta_files Dict {domain name: [TA lines]}
+ Returns:
+ List of absolute filesystem paths to TA files.
+ """
+ full_paths = []
+ for domain, ta_lines in ta_files.items():
+ file_name = u'{}.key'.format(domain)
+ full_path = os.path.realpath(
+ os.path.join(work_dir, TRUST_ANCHOR_SUBDIR, file_name))
+ full_paths.append(full_path)
+ dir_path = os.path.dirname(full_path)
+ try:
+ os.makedirs(dir_path)
+ except OSError as ex:
+ if ex.errno != errno.EEXIST:
+ raise
+ with open(full_path, "w") as ta_file:
+ ta_file.writelines('{0}\n'.format(line) for line in ta_lines)
+ return full_paths
+
+
+def generate_from_templates(program_config, context):
+ """Generate configuration for the program"""
+ template_ctx = context.copy()
+ template_ctx.update(program_config)
+
+ # public mapping program name -> program vars
+ template_ctx['PROGRAMS'] = {}
+ for cfg in template_ctx['programs']:
+ template_ctx['PROGRAMS'][cfg['name']] = cfg
+
+ j2template_loader = jinja2.FileSystemLoader(searchpath=os.getcwd())
+ j2template_env = jinja2.Environment(loader=j2template_loader)
+
+ for template_name, config_name in zip(template_ctx['templates'], template_ctx['configs']):
+ j2template = j2template_env.get_template(template_name)
+ cfg_rendered = j2template.render(template_ctx)
+ with open(os.path.join(template_ctx['WORKING_DIR'], config_name), 'w') as output:
+ output.write(cfg_rendered)
+
+
+def run_daemon(program_config):
+ """Start binary and return its process object"""
+ name = program_config['DAEMON_NAME']
+ proc = None
+ program_config['log'] = os.path.join(program_config["WORKING_DIR"], 'server.log')
+ program_config['args'] = (
+ shlex.split(os.environ.get('DECKARD_WRAPPER', ''))
+ + [program_config['binary']]
+ + program_config['additional']
+ )
+ logging.getLogger('deckard.daemon.%s.argv' % name).debug('%s', program_config['args'])
+ with open(program_config['log'], 'w') as daemon_log_file:
+ try:
+ # pylint: disable=consider-using-with
+ proc = subprocess.Popen(program_config['args'], stdout=daemon_log_file,
+ stderr=subprocess.STDOUT, cwd=program_config['WORKING_DIR'])
+ except subprocess.CalledProcessError:
+ logger = logging.getLogger('deckard.daemon_log.%s' % name)
+ logger.exception("Can't start '%s'", program_config['args'])
+ raise
+ return proc
+
+
+def log_fatal_daemon_error(cfg, msg):
+ logger = logging.getLogger('deckard.daemon_log.%s' % cfg['name'])
+ logger.critical(msg)
+ logger.critical('logs are in "%s"', cfg['WORKING_DIR'])
+ with open(cfg['log']) as logfile:
+ logger.error('daemon log follows:')
+ logger.error(logfile.read())
+
+
+def conncheck_daemon(process, cfg, sockfamily):
+ """Wait until the server accepts TCP clients"""
+ sock = socket.socket(sockfamily, socket.SOCK_STREAM)
+ deadline = time.monotonic() + 5
+ with sock:
+ while True:
+ # Check if the process is running
+ if process.poll() is not None:
+ msg = 'process died, exit code %s' % process.poll()
+ log_fatal_daemon_error(cfg, msg)
+ raise subprocess.CalledProcessError(process.returncode, cfg['args'], msg)
+ try:
+ sock.connect((cfg['address'], 53))
+ return # success
+ except socket.error as ex:
+ if time.monotonic() > deadline:
+ msg = 'server does not accept connections on TCP port 53'
+ log_fatal_daemon_error(cfg, msg)
+ raise DeckardUnderLoadError(msg) from ex
+
+ time.sleep(0.1)
+
+
+def setup_daemons(context):
+ """Configure daemons and start them"""
+ # Setup daemon environment
+ daemons = []
+
+ for program_config in context['programs']:
+ setup_daemon_environment(program_config, context)
+ generate_from_templates(program_config, context)
+
+ daemon_proc = run_daemon(program_config)
+ daemons.append({'proc': daemon_proc, 'cfg': program_config})
+ if program_config.get('conncheck', True):
+ try:
+ conncheck_daemon(daemon_proc, program_config, context['_SOCKET_FAMILY'])
+ except: # noqa -- bare except might be valid here?
+ daemon_proc.terminate()
+ raise
+
+ return daemons
+
+
+def check_for_reply_steps(case: scenario.Scenario) -> bool:
+ return any(s.type == "REPLY" for s in case.steps)
+
+
+def run_testcase(case, daemons, context, prog_under_test_ip):
+ """Run actual test and raise exception if the test failed"""
+ server = testserver.TestServer(case, context["_SOCKET_FAMILY"],
+ context["DECKARD_IP"], context["if_manager"])
+ server.start()
+
+ try:
+ server.play(prog_under_test_ip)
+ finally:
+ server.stop()
+
+ if check_for_reply_steps(case):
+ logging.warning("%s has REPLY steps in it. These are known to fail randomly. "
+ "Errors might be false positives.", case.file)
+
+ for daemon in daemons:
+ daemon['proc'].terminate()
+ daemon['proc'].wait()
+ daemon_logger_log = logging.getLogger('deckard.daemon_log.%s' % daemon['cfg']['name'])
+ with open(daemon['cfg']['log']) as logf:
+ for line in logf:
+ daemon_logger_log.debug(line.strip())
+ ignore_exit = daemon["cfg"].get('ignore_exit_code', False)
+ if daemon['proc'].returncode != 0 and not ignore_exit:
+ raise ValueError('process %s terminated with return code %s'
+ % (daemon['cfg']['name'], daemon['proc'].returncode))
+
+ if server.undefined_answers > 0:
+ raise ValueError('the scenario does not define all necessary answers (see error log)')
+
+
+def process_file(path, qmin, config):
+ """Parse scenario from a file object and create workdir."""
+
+ # Preserve original configuration
+ context = config.copy()
+
+ # Parse scenario
+ case, case_config_text = scenario.parse_file(os.path.realpath(path))
+ case_config = scenario.parse_config(case_config_text, qmin, INSTALLDIR)
+
+ # Merge global and scenario configs
+ context.update(case_config)
+
+ # Asign addresses to the programs and Deckard itself
+ setup_internal_addresses(context)
+
+ # Deckard will communicate with first program
+ prog_under_test_ip = context['programs'][0]['address']
+
+ setup_faketime(context)
+
+ # Copy the scenario to tmpdir for future reference
+ shutil.copy2(path, os.path.join(context["tmpdir"]))
+
+ try:
+ daemons = setup_daemons(context)
+ run_testcase(case, daemons, context, prog_under_test_ip)
+
+ except Exception:
+ logging.getLogger('deckard.hint').error(
+ 'test failed, inspect working directory %s', context["tmpdir"])
+ raise
diff --git a/tests/integration/deckard/deckard_pytest.ini b/tests/integration/deckard/deckard_pytest.ini
new file mode 100644
index 0000000..44ba4d4
--- /dev/null
+++ b/tests/integration/deckard/deckard_pytest.ini
@@ -0,0 +1,8 @@
+[pytest]
+python_files=deckard_pytest.py
+markers=
+ monotonic : mark test that require faking monotonic time
+norecursedirs=*
+log_cli=true
+log_level=WARNING
+
diff --git a/tests/integration/deckard/deckard_pytest.py b/tests/integration/deckard/deckard_pytest.py
new file mode 100755
index 0000000..b7b7a7e
--- /dev/null
+++ b/tests/integration/deckard/deckard_pytest.py
@@ -0,0 +1,167 @@
+import logging
+import os
+import random
+import shutil
+import subprocess
+import sys
+import tempfile
+import time
+from ipaddress import ip_address
+
+import dpkt
+import pytest
+
+import deckard
+from contrib.namespaces import LinuxNamespace
+from networking import InterfaceManager
+
+
+def set_coverage_env(path, qmin):
+ """Sets up enviroment variables so code coverage utility can work."""
+ if os.environ.get("COVERAGE"):
+ exports = subprocess.check_output([os.environ["COVERAGE_ENV_SCRIPT"],
+ os.environ["DAEMONSRCDIR"],
+ os.environ["COVERAGE_STATSDIR"],
+ path + "-qmin-" + str(qmin)]).decode()
+ for export in exports.split():
+ key, value = export.split("=", 1)
+ value = value.strip('"')
+ os.environ[key] = value
+
+
+def check_platform():
+ if sys.platform == 'windows':
+ pytest.exit('Not supported at all on Windows')
+
+
+# Suppress extensive Augeas logging
+logging.getLogger("augeas").setLevel(logging.ERROR)
+
+
+check_platform()
+
+
+class DeckardUnderLoadError(Exception):
+ pass
+
+
+class TCPDump:
+ """This context manager captures a PCAP file and than checks it for obvious errors."""
+
+ DUMPCAP_CMD = ["dumpcap", "-i", "any", "-q", "-P", "-w"]
+
+ def __init__(self, config):
+ self.config = config
+ self.config["tmpdir"] = self.get_tmpdir()
+ self.tcpdump = None
+ self.config["pcap"] = os.path.join(self.config["tmpdir"], "deckard.pcap")
+
+ def __enter__(self):
+ cmd = self.DUMPCAP_CMD.copy()
+ cmd.append(self.config["pcap"])
+ # pylint: disable=consider-using-with
+ self.tcpdump = subprocess.Popen(cmd, stderr=subprocess.PIPE, stdout=subprocess.PIPE)
+
+ def __exit__(self, _, exc_value, __):
+ # Wait for the PCAP to be finalized
+ while not os.path.exists(self.config["pcap"]):
+ time.sleep(1)
+
+ self.tcpdump.terminate()
+ self.tcpdump.wait()
+
+ self.check_for_unknown_server()
+
+ if exc_value is None:
+ if self.config.get('noclean') or "DECKARD_NOCLEAN" in os.environ:
+ # Do not clear files if the server crashed (for analysis)
+ logging.getLogger('deckard.hint').info(
+ 'test working directory %s', self.config["tmpdir"])
+ else:
+ shutil.rmtree(self.config["tmpdir"])
+ else:
+ if isinstance(exc_value, ValueError):
+ self.check_for_icmp()
+ raise
+
+ @staticmethod
+ def get_tmpdir():
+ if "DECKARD_DIR" in os.environ:
+ tmpdir = os.environ["DECKARD_DIR"]
+ if os.path.lexists(tmpdir):
+ raise ValueError('DECKARD_DIR "%s" must not exist' % tmpdir)
+ else:
+ tmpdir = tempfile.mkdtemp(suffix='', prefix='tmpdeckard')
+
+ return tmpdir
+
+ def check_for_icmp(self):
+ """ Checks Deckards's PCAP for ICMP packets """
+ # Deckard's responses to resolvers might be delayed due to load which
+ # leads the resolver to close the port and to the test failing in the
+ # end. We partially detect these by checking the PCAP for ICMP packets.
+ udp_seen = False
+ with open(self.config["pcap"], "rb") as f:
+ pcap = dpkt.pcap.Reader(f)
+ for _, packet in pcap:
+ ip = dpkt.sll.SLL(packet).data
+
+ if isinstance(ip.data, dpkt.udp.UDP):
+ udp_seen = True
+
+ if udp_seen:
+ if isinstance(ip.data, (dpkt.icmp.ICMP, dpkt.icmp6.ICMP6)):
+ raise DeckardUnderLoadError("Deckard is under load. "
+ "Other errors might be false negatives. "
+ "Consider retrying the job later.")
+
+ def check_for_unknown_server(self):
+ unknown_addresses = set()
+ with open(self.config["pcap"], "rb") as f:
+ pcap = dpkt.pcap.Reader(f)
+ for _, packet in pcap:
+ ip = dpkt.sll.SLL(packet).data
+ try:
+ if ip.p != dpkt.ip.IP_PROTO_TCP or ip.p != dpkt.ip.IP_PROTO_UDP:
+ continue
+ except AttributeError:
+ continue
+ dest = str(ip_address(ip.dst))
+ if dest not in self.config["if_manager"].added_addresses:
+ unknown_addresses.add(dest)
+
+ if unknown_addresses:
+ raise RuntimeError("Binary under test queried an IP address not present"
+ " in scenario %s" % unknown_addresses)
+
+
+def run_test(path, qmin, config, max_retries, retries=0):
+ set_coverage_env(path, qmin)
+
+ try:
+ with LinuxNamespace("net"):
+ config["if_manager"] = InterfaceManager()
+ with TCPDump(config):
+ deckard.process_file(path, qmin, config)
+ except deckard.DeckardUnderLoadError as e:
+ if retries < max_retries:
+ logging.error("Deckard under load. Retrying…")
+ # Exponential backoff
+ time.sleep((2 ** retries) + random.random())
+ run_test(path, qmin, config, max_retries, retries + 1)
+ else:
+ raise e
+
+
+def test_passes_qmin_on(scenario, max_retries):
+ if scenario.qmin is True or scenario.qmin is None:
+ run_test(scenario.path, True, scenario.config, max_retries)
+ else:
+ pytest.skip("Query minimization is off in test config")
+
+
+def test_passes_qmin_off(scenario, max_retries):
+ if scenario.qmin is False or scenario.qmin is None:
+ run_test(scenario.path, False, scenario.config, max_retries)
+ else:
+ pytest.skip("Query minimization is on in test config")
diff --git a/tests/integration/deckard/doc/devel_guide.rst b/tests/integration/deckard/doc/devel_guide.rst
new file mode 100644
index 0000000..bf2e607
--- /dev/null
+++ b/tests/integration/deckard/doc/devel_guide.rst
@@ -0,0 +1,6 @@
+Notes for Deckard developers
+============================
+
+libfaketime
+^^^^^^^^^^^
+Run-time changes to ``FAKETIME_`` environment variables might not be picked up by running process if ``FAKETIME_NO_CACHE=1`` variable is not set before the process starts.
diff --git a/tests/integration/deckard/doc/scenario_example.rst b/tests/integration/deckard/doc/scenario_example.rst
new file mode 100644
index 0000000..7fb6f3e
--- /dev/null
+++ b/tests/integration/deckard/doc/scenario_example.rst
@@ -0,0 +1,337 @@
+Scenario example
+=================
+iter_ns_badaa.rpl
+::
+
+ ; config options
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+ CONFIG_END
+
+ SCENARIO_BEGIN Test iterator with NS falsely declaring referral answer as authoritative.
+
+ ; K.ROOT-SERVERS.NET.
+ RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ ENTRY_BEGIN
+ MATCH opcode qtype qname
+ ADJUST copy_id
+ REPLY QR NOERROR
+ SECTION QUESTION
+ . IN NS
+ SECTION ANSWER
+ . IN NS K.ROOT-SERVERS.NET.
+ SECTION ADDITIONAL
+ K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ ENTRY_END
+
+ ENTRY_BEGIN
+ MATCH opcode subdomain
+ ADJUST copy_id copy_query
+ ; False declaration here
+ REPLY QR AA NOERROR
+ SECTION QUESTION
+ MORECOWBELL. IN A
+ SECTION AUTHORITY
+ MORECOWBELL. IN NS a.gtld-servers.net.
+ SECTION ADDITIONAL
+ a.gtld-servers.net. IN A 192.5.6.30
+ ENTRY_END
+
+ ENTRY_BEGIN
+ MATCH opcode qtype qname
+ ADJUST copy_id copy_query
+ REPLY QR NOERROR
+ SECTION QUESTION
+ a.gtld-servers.net. IN A
+ SECTION ANSWER
+ a.gtld-servers.net. IN A 192.5.6.30
+ ENTRY_END
+
+ ENTRY_BEGIN
+ MATCH opcode qtype qname
+ ADJUST copy_id copy_query
+ REPLY QR NOERROR
+ SECTION QUESTION
+ a.gtld-servers.net. IN AAAA
+ SECTION AUTHORITY
+ . SOA bla bla 1 2 3 4 5
+ ENTRY_END
+
+ RANGE_END
+
+ ; a.gtld-servers.net.
+ RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+
+ ENTRY_BEGIN
+ MATCH opcode qtype qname
+ ADJUST copy_id copy_query
+ REPLY QR AA NOERROR
+ SECTION QUESTION
+ CATALYST.MORECOWBELL. IN A
+ SECTION ANSWER
+ CATALYST.MORECOWBELL. IN A 10.20.30.40
+ SECTION AUTHORITY
+ CATALYST.MORECOWBELL. IN NS a.gtld-servers.net.
+ ENTRY_END
+
+ RANGE_END
+
+ STEP 1 QUERY
+ ENTRY_BEGIN
+ REPLY RD
+ SECTION QUESTION
+ catalyst.morecowbell. IN A
+ ENTRY_END
+
+ ; recursion happens here.
+ STEP 10 CHECK_ANSWER
+ ENTRY_BEGIN
+ MATCH all
+ REPLY QR RD RA NOERROR
+ SECTION QUESTION
+ catalyst.morecowbell. IN A
+ SECTION ANSWER
+ catalyst.morecowbell. IN A 10.20.30.40
+ ENTRY_END
+
+ SCENARIO_END
+
+Execution flow :
+
+First, STEP 1 QUERY will be performed.
+
+Python sends query to Resolver
+::
+
+ id 31296
+ opcode QUERY
+ rcode NOERROR
+ flags RD
+ edns 1
+ eflags
+ payload 1280
+ ;QUESTION
+ catalyst.morecowbell. IN A
+ ;ANSWER
+ ;AUTHORITY
+ ;ADDITIONAL
+
+At this scenario stub-addr is set to 193.0.14.129, thus Resolver have been configured to use address
+193.0.14.129 as a root server. So it sends query to Python fake server which listen at address 193.0.14.129
+
+::
+
+ > [plan] plan 'catalyst.morecowbell.' type 'A'
+ [resl] => using root hints
+ [resl] => querying: '193.0.14.129' score: 10 zone cut: '.' m12n: 'CaTALYSt.MoReCoWBEll.' type: 'A'
+
+
+::
+
+ id 7367
+ opcode QUERY
+ rcode NOERROR
+ flags
+ edns 0
+ payload 1452
+ ;QUESTION
+ CaTALYSt.MoReCoWBEll. IN A
+ ;ANSWER
+ ;AUTHORITY
+ ;ADDITIONAL
+
+Python fake server starts range analyzing to make answer.
+Let's look at first range
+::
+
+ RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+
+STEP ID is equal 1, so it matches the condition n1 <= step id <= n2
+Next, ADDRESS field is equal to 193.0.14.129. Since query was directed
+specifically to 193.0.14.129, this range will be used.
+
+Next, Python walks through list of entries to choose eligible entry.
+First entry at this range requires comparison of "opcode qtype qname" field list.
+Since opcode is QUERY, first comparison is true.
+Next, qtype field at question section is equal NS.
+But qtype field at question section of incoming query is A.
+So this comparison failed and this entry will be rejected.
+
+Next entry requires comparison of opcode and subdomain fields.
+As we seen, opcode matches.
+Let's look at domain names.
+ENTRY datablock:
+::
+
+ SECTION QUESTION
+ MORECOWBELL. IN A
+
+Incoming query :
+::
+
+ ;QUESTION
+ CaTALYSt.MoReCoWBEll. IN A
+
+So, subdomain matches and second entry of first range used as answer pattern.
+Python fake server sends answer to Resolver :
+::
+
+ id 7367
+ opcode QUERY
+ rcode NOERROR
+ flags QR AA
+ edns 0
+ payload 1280
+ ;QUESTION
+ CaTALYSt.MoReCoWBEll. IN A
+ ;ANSWER
+ ;AUTHORITY
+ MORECOWBELL. 3600 IN NS a.gtld-servers.net.
+ ;ADDITIONAL
+ a.gtld-servers.net. 3600 IN A 192.5.6.30
+
+Note that additional section contains IP address. Because new address is found,
+Python fake server immediately starts listening on this address.
+Resolver sends next query to 192.5.6.30:
+
+::
+
+ [iter] <= referral response, follow
+ [ pc ] => answer cached for TTL=900
+ [resl] => querying: '192.5.6.30' score: 10 zone cut: 'morecowbell.' m12n: 'catalyst.mOREcoWBEll.' type: 'A'
+
+
+::
+
+ id 58167
+ opcode QUERY
+ rcode NOERROR
+ flags
+ edns 0
+ payload 1452
+ ;QUESTION
+ catalyst.mOREcoWBEll. IN A
+ ;ANSWER
+ ;AUTHORITY
+ ;ADDITIONAL
+
+Since query is directed to 192.5.6.30,
+this range will be analyzed :
+::
+
+ ; a.gtld-servers.net.
+ RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+
+It has a single entry, which requires "opcode qtype qname" field list to be compared.
+Opcode and qtype fields are the same as fields in incoming query.
+Let's compare qname.
+ENTRY datablock :
+::
+
+ SECTION QUESTION
+ CATALYST.MORECOWBELL. IN A
+
+Incoming query :
+::
+
+ ;QUESTION
+ catalyst.mOREcoWBEll. IN A
+
+So, qname also the same. All fields matches and Python server sends answer
+derived from this entry :
+::
+
+ id 58167
+ opcode QUERY
+ rcode NOERROR
+ flags QR AA
+ edns 0
+ payload 1280
+ ;QUESTION
+ cAtaLyst.MoRECowBEll. IN A
+ ;ANSWER
+ CATALYST.MORECOWBELL. 3600 IN A 10.20.30.40
+ ;AUTHORITY
+ CATALYST.MORECOWBELL. 3600 IN NS a.gtld-servers.net.
+ ;ADDITIONAL
+
+Here Python found new address 10.20.30.40 and starts listening.
+Next queries and answers :
+
+::
+
+ [iter] <= referral response, follow
+ [plan] plan 'a.gtld-servers.net.' type 'AAAA'
+ [resl] => using root hints
+ [resl] => querying: '193.0.14.129' score: 54 zone cut: '.' m12n: 'A.Gtld-sERverS.nEt.' type: 'AAAA'
+
+
+query; Resolver ---> Python (193.0.14.129)
+::
+
+ id 13810
+ opcode QUERY
+ rcode NOERROR
+ flags
+ edns 0
+ payload 1452
+ ;QUESTION
+ A.Gtld-sERverS.nEt. IN AAAA
+ ;ANSWER
+ ;AUTHORITY
+ ;ADDITIONAL
+
+answer; Python ---> Resolver
+::
+
+ id 13810
+ opcode QUERY
+ rcode NOERROR
+ flags QR
+ edns 0
+ payload 1280
+ ;QUESTION
+ A.gTld-serveRS.NET. IN AAAA
+ ;ANSWER
+ ;AUTHORITY
+ . 3600 IN SOA bla. bla. 1 2 3 4 5
+ ;ADDITIONAL
+
+
+at this point Resolver returns answer to query from STEP 1 QUERY.
+
+::
+
+ [iter] <= rcode: NOERROR
+ [ pc ] => answer cached for TTL=900
+ [ rc ] => satisfied from cache
+ [iter] <= rcode: NOERROR
+ [resl] finished: 4, queries: 2, mempool: 16400 B
+
+
+::
+
+ opcode QUERY
+ rcode NOERROR
+ flags QR RD RA
+ edns 0
+ payload 4096
+ ;QUESTION
+ catalyst.morecowbell. IN A
+ ;ANSWER
+ catalyst.morecowbell. 3600 IN A 10.20.30.40
+ ;AUTHORITY
+ ;ADDITIONAL
+
+Now STEP 10 will be performed. Is has a single entry which contains
+**MATCH all** clause. **MATCH all** means set of dns flags must be equal and
+all sections presented in ENTRY must be equal to ones in answer.
+Incoming answer has next flags were set: **QR RD AA**. ENTRY datablock contains
+**REPLY QR RD RA NOERROR** clause. As we see, flags set is equal. Also, we can
+see equality of question and answer sections of both dns messages.
+
+So, Python got expected answer and test is passed.
+
diff --git a/tests/integration/deckard/doc/scenario_guide.rst b/tests/integration/deckard/doc/scenario_guide.rst
new file mode 100644
index 0000000..9d8ec44
--- /dev/null
+++ b/tests/integration/deckard/doc/scenario_guide.rst
@@ -0,0 +1,431 @@
+Deckard scenario guide
+======================
+.. contents::
+
+On the highest level, Deckard scenario consists of three parts (in this order):
+
+- scenario-specific configuration in the header,
+- declarative description of the simulated network environment,
+- sequence of test steps.
+
+The scenario is stored as ASCII encoded text file with following structure:
+
+.. code-block::
+
+ ; configuration part starts on beginning of the file
+ ; comments start with semicolon
+ CONFIG_END
+
+ SCENARIO_BEGIN ; SCENARIO block combines declarative description and sequence of steps
+
+
+ ; declarative description of network environment starts here
+ RANGE_BEGIN a b
+ ENTRY_BEGIN
+ ; entries inside RANGE block describe DNS messages
+ ; used as answers from simulated network
+ ENTRY_END
+ RANGE_END
+
+
+ ; sequence of test steps begins here
+ STEP x QUERY ; this is step number x
+ ENTRY_BEGIN
+ ; ENTRY inside STEP may describe DNS message sent as query
+ ENTRY_END
+
+ STEP y CHECK_ANSWER ; arbitrary number of steps is allowed
+ ENTRY_BEGIN
+ ; also, ENTRY inside STEP may describe DNS message with expected answer
+ ENTRY_END
+ SCENARIO_END
+
+The scenario is processed as follows:
+
+- Deckard parses configuration block and generates configuration files for binaries under test
+- binaries are executed in an isolated network environment
+- Deckard walks through all ``STEP`` blocks and sends queries to the binary under test, and checks answers it receives
+- when a binary attempts to contact another server, Deckard intercepts the communication and replies with scripted answer as defined in ``RANGE`` blocks
+
+To better understand this structure, we will walk-through from sequential steps through declarative description up to scenario-specific configuration.
+
+Scenario
+--------
+Scenario part starts with ``SCENARIO_BEGIN`` and ends with ``SCENARIO_END`` statements, which are present after ``CONFIG_END`` keyword. ``SCENARIO_BEGIN`` keyword must be followed by scenario description:
+
+.. code-block::
+
+ SCENARIO_BEGIN Test basic query minimization www.example.com.
+ ...
+ SCENARIO_END
+
+
+
+Test steps (``STEP``)
+---------------------
+One ``STEP`` describes one action during scenario execution. It might be action like send next query to binary under test, send reply to binary under test, change faked system time, or check the last answer. Sequence of two steps might look like this:
+
+.. code-block::
+
+ STEP 1 QUERY ; send query specified in the following ENTRY to the binary
+ ENTRY_BEGIN ; ENTRY defines content of DNS message
+ REPLY RD
+ SECTION QUESTION
+ www.example.com. IN A
+ ENTRY_END
+
+ STEP 10 CHECK_ANSWER ; check that answer to the previous query matches following ENTRY
+ ENTRY_BEGIN
+ MATCH all ; MATCH specifies what fields in answer have to match the ENTRY
+ REPLY QR RD RA NOERROR
+ SECTION QUESTION
+ www.example.com. IN A
+ SECTION ANSWER
+ www.example.com. IN CNAME www.next.com.
+ www.next.com. IN A 10.20.30.40
+ SECTION AUTHORITY
+ SECTION ADDITIONAL
+ ENTRY_END
+
+
+Most important parts of a step are:
+
+- id - number specifying order in which steps are executed, e.g. ``1`` or ``10``
+- type - action to execute, e.g. ``QUERY`` or ``CHECK_ANSWER``
+- entry - DNS message content, while meaning of the message depends on the step *type*
+
+One ``STEP`` block starts with ``STEP`` keyword and continues until one of {``STEP``,
+``RANGE``, ``END_SCENARIO``} keywords is found.
+
+Format
+^^^^^^
+
+.. code-block::
+
+ STEP id type [additional data]
+
+- id - step identifier, a positive integer value; all steps must have
+ different id's. This value used within RANGE block, see above.
+- type - step type; can be ``QUERY`` | ``REPLY`` | ``CHECK_ANSWER`` | ``TIME_PASSES ELAPSE`` *seconds*
+
+ - QUERY - send query defined by associated ``ENTRY`` to binary under test
+ - CHECK_ANSWER - check if last received answer matches associated ``ENTRY``
+ - TIME_PASSES ELAPSE - move faked system time for binary under test by number of *seconds* to future
+ - REPLY - *use of this type is discouraged*; it defines one-shot reply to query from binary under test
+
+.. warning::
+ - ``REPLY`` type is useful only if you know exact order of queries sent *by the binary under test*
+ - steps of this type are used only when no matching ``RANGE`` datablock exists
+ - priority of ``REPLY`` type is going to change in future
+
+
+.. _entry:
+
+DNS messages (normal ``ENTRY``)
+-------------------------------
+One ``ENTRY`` describes one DNS message plus additional metadata, depending on intended use of the entry. There are three possible uses of entry which require little bit different entry format. An entry might define:
+
+#. *query message* to be sent in ``STEP QUERY``
+#. *expected message* to be compared with a message received from binary in ``STEP CHECK_ANSWER``
+#. *answer template message* to be used for simulating answers from network in ``RANGE`` block
+
+Particular use of data in an ``ENTRY`` depends on context and is different
+for ``STEP`` types and ``RANGE`` blocks, see details below.
+
+In any case, entry starts with ``ENTRY_BEGIN`` and ends with ``ENTRY_END`` keywords and share ``REPLY`` and ``SECTION`` definitions.
+Some fields in DNS messages have default values which can be overriden by explicit specification.
+
+Format of query messages (for ``STEP QUERY``)
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+``STEP QUERY`` requires a DNS message which will be sent by Deckard to the binary under test. Structure of the entry is:
+
+.. code-block::
+
+ STEP <n> QUERY
+ ENTRY_BEGIN
+ REPLY <OPCODE flags> ; REPLY is a bad keyword name, OPCODE and flags will be sent out!
+ SECTION QUESTION ; it is possible to replace QUESTION section or omit it
+ <name> <class> <type> ; to simulate weird queries
+ ENTRY_END
+
+The message will be assigned a random message ID, converted into DNS wire format, and sent to the binary under test.
+
+.. warning:: The keyword ``REPLY`` in fact defines value of flags in the outgoing message. The confusing name is here for compatibility with the original ``testbound``.
+
+
+Format of expected messages (for ``STEP CHECK_ANSWER``)
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+``STEP CHECK_ANSWER`` requires a DNS message which will be compared with a reply received from the binary under test. Structure of the entry describing the expected message is:
+
+.. code-block::
+
+ ENTRY_BEGIN
+ MATCH <match element list> ; MATCH elements define what message fields will be compared
+ REPLY <OPCODE RCODE flags> ; REPLY field here defines expected OPCODE, RCODE as well as flags!
+ SECTION QUESTION
+ <name> <class> <type> ; to simulate weird queries
+ SECTION <type2>
+ <RR sets>
+ ENTRY_END
+
+Deckard will compare messages according to *<match element list>*. Any mismatch between *received* message and the *expected* message (specified by the entry) will result in test failure. (See chapter `entry matching`_.)
+
+
+Format of answer templates (for ``RANGE``)
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+Entries in ``RANGE`` blocks are used to answer queries *from binaries under test*. E.g. if a DNS resolver under test sends query ``. IN NS`` to a simulated server, Deckard will use matching entry associated with the simulated server for reply. Entry used for answer is selected using the same `entry matching`_ logic as with ``STEP CHECK_ANSWER``. The difference is that entry is automatically modified before sending out the answer. These modifications are specified by ``ADJUST`` and ``REPLY`` keywords. It's also possible to not send any reply using the ``ADJUST do_not_answer`` option. See chapters `entry adjusting`_ and `entry flags`_.
+
+.. code-block::
+
+ ENTRY_BEGIN
+ MATCH <match element list> ; all MATCH elements must match before using this answer template
+ ADJUST <adjust element list> ; ADJUST fields will be modified before answering
+ REPLY <OPCODE RCODE flags> ; OPCODE, RCODE, and flags to be set in the outgoing answer
+ SECTION <type1>
+ <RR sets>
+ SECTION <type2>
+ <RR sets>
+ ENTRY_END
+
+
+.. _`entry matching`:
+
+Entry matching
+^^^^^^^^^^^^^^
+Entries present in Deckard scenario define values *expected* in DNS messages. The *expected* values are compared with values in messages *received* from the network. Entry matches only if all specified elements match.
+
+.. code-block::
+
+ MATCH <match element list>
+
+*<match element list>* is a space-separated list of elements in *expected* and *received* messages to be compared. Supported elements are:
+
+============ =========================================================================================
+element DNS message fields and additional rules
+============ =========================================================================================
+opcode ``OPCODE`` as `defined in IANA registry <https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml#dns-parameters-5>`_
+
+ - *expected* message ``OPCODE`` is defined by ``REPLY`` keyword
+
+qtype RR type in question section [qmatch]_
+qname name in question section (case insensitive) [qmatch]_
+qcase name in question section (case sensitive) [qmatch]_
+subdomain name in question section of the *received* message is a subdomain of the name in *expected* question section
+ (case insensitive, exact match accepted) [qmatch]_
+flags all `defined flags <https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml#dns-parameters-12>`_
+ in message header: ``QR AA TC RD RA AD CD``
+
+ - it does not match on ``DO`` flag which resides in EDNS header flags
+ - *expected* message flags are defined by ``REPLY`` keyword
+
+rcode extended response code (``RCODE`` value
+ `combined from message header and EDNS header <https://tools.ietf.org/html/rfc6891#section-6.1.3>`_)
+
+ - *expected* message ``RCODE`` is defined by ``REPLY`` keyword
+
+question equivalent to ``qtype qname``
+answer whole ANSWER section [sectmatch]_
+authority whole AUTHORITY section [sectmatch]_
+additional whole ADDITIONAL section [sectmatch]_
+edns EDNS `version <https://tools.ietf.org/html/rfc6891#section-6.1.3>`_ and
+ EDNS `payload <https://tools.ietf.org/html/rfc6891#section-6.1.2>`_ size
+nsid `NSID <https://tools.ietf.org/html/rfc5001>`_ presence and value
+all equivalent to ``opcode qtype qname flags rcode answer authority additional``
+============ =========================================================================================
+
+.. [qmatch] *Expected* values are defined by QUESTION section in the entry. If the *expected* QUESTION section is empty, the conditions is ignored. Only values from the first (qname, qclass, qtype) tuple are checked. Question matching is case insensitive (except for ``qcase``).
+
+.. [sectmatch] Number of records must match. Owner names are case-insensitive and TTL is ignored. RR data are compared according to type-specific rules. Each RR present in the *expected* message must be present in the *received* message and vice versa.
+
+
+.. _`entry adjusting`:
+
+Entry adjusting
+^^^^^^^^^^^^^^^
+.. code-block::
+
+ ADJUST <adjust element list>
+
+An entry used as a template to prepare an answer to an incoming query might be preprocessed.
+Adjust element list defines what fields will be modified:
+
+============= ===========================================================================================
+element modification to the DNS message
+============= ===========================================================================================
+copy_id query id + query domain name will be copied from incoming message [copy_id_bug]_
+copy_query whole question section will be copied from incoming message
+raw_id query id will be copied into the first two bytes of RAW answer
+do_not_answer no response will be sent at all
+============= ===========================================================================================
+
+.. [copy_id_bug] https://gitlab.nic.cz/knot/deckard/issues/9
+
+
+.. _`entry flags`:
+
+Entry flags
+^^^^^^^^^^^
+.. code-block::
+
+ REPLY <RCODE flags>
+
+*<RCODE flags>* is space-separated RCODE and list of flags in the entry. Usage of these flags depend on entry context.
+
+Supported values:
+
+ - NOERROR, FORMERR, SERVFAIL, NXDOMAIN, NOTIMP, REFUSED, YXDOMAIN, YXRRSET, NXRRSET, NOTAUTH, NOTZONE, BADVERS - standard rcodes
+ - QR, AA, TC, RD, RA, AD, CD - i.e. standard dns flags
+ - DO - enable 'DNSSEC desired' flag
+
+.. warning:: The keyword ``REPLY`` has different meaning depending on the ``ENTRY`` context.
+
+
+Entry RR sections
+^^^^^^^^^^^^^^^^^
+An entry might specify content of DNS message sections QUESTION, ANSWER, AUTHORITY, and ADDITIONAL. Syntax is of resource records is the same as in zone file. Format:
+
+.. code-block::
+
+ SECTION QUESTION
+ <owner name> [class] <RR type> ; QUESTION is special
+ SECTION <ANSWER/AUTHORITY/ADDITIONAL>
+ <owner name> [TTL] [class] <RR type> <RR data> ; same as in zone file
+ ...
+ <owner name> [TTL] [class] <RR type> <RR data>
+
+Example:
+
+.. code-block::
+
+ SECTION QUESTION
+ www.example.com. IN A
+ SECTION ANSWER
+ www.example.com. IN A 10.20.30.40
+ SECTION AUTHORITY
+ example.com. IN NS ns.example.com.
+ SECTION ADDITIONAL
+ ns.example.com. IN A 1.2.3.4
+
+
+Default values for DNS messages
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+========== ===========================================================================================
+feature default value
+========== ===========================================================================================
+EDNS version 0 with buffer size 4096 B
+REPLY QUERY, NOERROR
+========== ===========================================================================================
+
+
+Entry with RAW data
+^^^^^^^^^^^^^^^^^^^
+An entry might have special section named ``RAW``. This section is used only for sending raw,
+potentially invalid DNS messages. The section contains a single-line data interpreted as hexadecimal string.
+Data decoded from this string will be sent to binary under test without any changes.
+
+Deckard does not expect any answer to RAW queries, so ``STEP CHECK_ANSWER`` is not needed.
+Main intent of this behavior is to check if binary under test is
+able to process valid queries after getting series badly formed packets.
+
+It is also possible to use ``RAW`` in conjuction with ``SECTION`` for the
+purpose of responding with raw data to a query that matches the ``SECTION``.
+It's possible to modify raw data to use query's ID by using ``ADJUST raw_id``.
+
+One ``ENTRY`` can contain only one ``RAW`` section.
+
+Example
+
+.. code-block::
+
+ ENTRY_BEGIN
+ RAW
+ b5c9ca3d50104320f4120000000000000000
+ ENTRY_END
+
+
+
+Mock answers (``RANGE``)
+------------------------
+When Deckard receives a query *from binary under test*, it searches for mock answers.
+A set of mock answers for particular set of IP addresses and ID range is described using ``RANGE``
+block starting with ``RANGE_BEGIN`` keyword. The ``RANGE`` contains mock DNS messages represented
+as ENTRY_ blocks which specify `entry matching`_ conditions along with `entry adjusting`_ actions and `entry flags`_ specification.
+
+Format:
+
+.. code-block::
+
+ ; comment before the range, e.g. K.ROOT-SERVERS.NET.
+ RANGE_BEGIN 0 100 ; this RANGE is valid for STEP IDs <0, 100>
+ ADDRESS 193.0.14.129 ; IP address simulated by this range
+ ;ADDRESS 192.0.2.222 ; multiple IP addresses are allowed
+
+ ENTRY_BEGIN ; first ENTRY in this range
+ MATCH opcode qtype qname ; use this entry only if all these match the query
+ ADJUST copy_id ; adjust message ID before senting the answer
+ REPLY QR NOERROR ; answer with RCODE NOERROR and QR flag set
+ SECTION QUESTION
+ . IN NS ; MATCH qname qtype are compared with this value
+ SECTION ANSWER ; all this will be copied verbatim to the answer
+ . IN NS K.ROOT-SERVERS.NET.
+ SECTION ADDITIONAL
+ K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ ENTRY_END
+
+ ENTRY_BEGIN ; second ENTRY in this range
+ ...
+ ENTRY_END
+
+ RANGE_END
+
+When Deckard receives a query *from binary under test*, it searches for an eligible range. When an eligible range is found, it searches inside the range to find a mock answer. In detail, it works like this:
+
+#. Deckard searches for an eligible ``RANGE`` block. Following two conditions must be fulfilled:
+
+ - current ``STEP ID`` is inside ID range specified by ``RANGE_BEGIN`` keyword.
+ - target IP address of the query is in set of IP addresses specified using ``ADDRESS`` keywords
+
+#. If an eligible range is found, Deckard examines all entries in the range and evaluate all ``MATCH`` conditions associated with entries.
+#. An entry where all MATCH conditions are fulfilled is used as template for the mock answer. (See `entry matching`_.)
+#. Mock answer is modified according to ``ADJUST`` and ``REPLY`` keywords. (See `entry adjusting`_ actions and `entry flags`_ specification.)
+#. The modified answer message is sent to the binary under test.
+
+Valid scenario must specify answers for all queries generated by the binary under test. The test will fail if no answer is found in the eligible range or if no eligible range is defined.
+
+.. note:: Behavior of the binary under test, including queries it generates, depends on its configuration. For example enabling or disabling query name minimization will change minimal set of queries which a test scenario has to describe using ``RANGE`` blocks.
+
+.. tip:: It is recommended to construct scenarios that support multiple configurations and possibly software implementations. This leads to higher number of entries in ``RANGE`` blocks but provides robustness against changes in particular implementation. E.g. a scenario for DNS resolver testing can be developed using multiple DNS resolver implementations and combine entries for all of them inside single scenario. With this approach a small change in a resolver implementation will likely not require further changes to the scenario.
+
+
+Configuration (``CONFIG_END``)
+------------------------------
+Configuration block affects behavior of the binary under test. Deckard transforms configuration block into configuration for the binary under test.
+
+Format is list of "key: value" pairs, one pair per line. There is no explicit start keyword, configuration block starts immediately at scenario file begin and ends with keyword ``CONFIG_END``.
+
+.. code-block::
+
+ ; config options
+ query-minimization: on
+ stub-addr: 193.0.14.129 ; K.ROOT-SERVERS.NET.
+ trust-anchor: ". 3600 IN DS 10000 13 4 ABCDEF0123456789"
+ val-override-date: "1442323400"
+ CONFIG_END
+
+========================== ======= =====================================================================
+config option default meaning
+========================== ======= =====================================================================
+do-not-query-localhost on on = queries cannot be sent to 127.0.0.1/8 or ::1/128 addresses
+domain-insecure (none) domain name specifying DNS sub-tree with explicitly disabled DNSSEC validation
+force-ipv6 off use a IPv6 address as ``stub-addr``
+harden-glue on additional checks on glue addresses
+query-minimization on RFC 7816 query algorithm enabled; default inherited from QMIN environment variable
+stub-addr (none) IP address for resolver priming queries (RFC 8109)
+trust-anchor (none) owner name with its DS records (this option can be repeated multiple times)
+val-override-date (none) system time reported to binary under the test; format ``YYYYMMDDHHMMSS``, so ``20120420235959`` means ``Fri Apr 20 23:59:59 2012``
+val-override-timestamp (none) system time reported to binary under the test: format POSIX timestamp
+========================== ======= =====================================================================
+
+Examples
+--------
+See `scenatio example <scenario_example.rst>`_. The example there is a bit terse but still valid.
diff --git a/tests/integration/deckard/doc/user_guide.rst b/tests/integration/deckard/doc/user_guide.rst
new file mode 100644
index 0000000..4ae8f97
--- /dev/null
+++ b/tests/integration/deckard/doc/user_guide.rst
@@ -0,0 +1,286 @@
+.. sectnum::
+
+How to use Deckard
+==================
+.. contents::
+
+Deckard runs one or more binaries in isolated network which is described by so-called *scenario*.
+There are four components in play:
+
+- Deckard itself (test orchestrator)
+- binary under test (your own)
+- configuration for the binary (generated by Deckard from *template* and *YaML configuration*, i.e. ``.j2`` and ``.yaml`` files)
+- environment description and test data (Deckard *scenario*, i.e. ``.rpl`` file)
+
+It is easy to run tests if everything is already prepared and running tests gets harder
+as number of components you have to prepare yourself raises.
+
+Let's start with the easiest case:
+
+First run
+---------
+Easiest way to run Deckard is using one of the prepared Shell scripts in Deckard repository (``{kresd,named,pdns,unbound}_run.sh`` for Knot Resolver, BIND, PowerDNS, and Unbound Recursor respectively).
+
+Deckard uses `pytest` to generate and run the tests as well as collect the results.
+Output is therefore generated by `pytest` as well (``.`` for passed test, ``F`` for failed test and ``s`` for skipped test) and will look something like this:
+
+.. code-block::
+
+ $ ./kresd_run.sh
+ deckard_pytest.py::test_passes_qmin_on[Scenario(path='sets/resolver/black_data.rpl',
+ qmin=False, config={'programs': [{'name': 'kresd', 'binary': 'kresd', 'additional':
+ ['-n'], 'templates': ['template/kresd.j2'], 'configs': ['config']}]})-max-retries-3]
+ SKIPPED [ 0%]
+
+ […many lines later…]
+
+ deckard_pytest.py::test_passes_qmin_off[Scenario(path='sets/resolver/world_mx_nic_www.rpl',
+ qmin=None, config={'programs': [{'name': 'kresd', 'binary': 'kresd', 'additional': ['-n'],
+ 'templates': ['template/kresd.j2'], 'configs': ['config']}]})-max-retries-3] PASSED [100%]
+
+ ======================= 275 passed, 97 skipped in 316.61s (0:05:16) =======================
+
+.. note:: There is a lot of tests skipped because we run them with query minimization both on and off and some of the scenarios work only with query minimization on (or off respectively). For details see `Scenario guide#Configuration <scenario_guide.rst#configuration-config-end>`_.
+
+Command line arguments
+----------------------
+As mentioned above we use `py.test` to run the tests so all possible command line arguments for the ``*run.sh`` scripts can be seen by running ``py.test -h`` in the root of Deckard repository.
+
+Here is a list of the most useful ones:
+
+- ``-n number`` – runs the testing in parallel with ``number`` of processes (this requires `pytest-xdist` and `pytest-forked` to be installed)
+- ``-k EXPRESSION`` – only run tests which match the given substring expression (e.g. ``./kresd_run -k "world_"`` will only run the scenarios with `world_` in their file name.
+- ``--collectonly`` – only print the names of selected tests, no tests will be run
+- ``--log-level DEBUG`` – print all debug information for failed tests
+- ``--scenarios path`` – specifies where to look for `.rpl` files (``sets/resolver`` is the default)
+
+YaML configuration
+------------------
+All ``*_run.sh`` scripts internally call the ``run.sh`` script and pass command line arguments to it. For example:
+
+.. code-block::
+
+ # running ./kresd_run.sh -n 4 -k "iter_" will result in running
+ ./run.sh --config configs/kresd.yaml -n 4 -k "iter_"
+
+As you can see, path to YaML configuration file is passed to ``run.sh``. You can edit one of the prepared ones stored in `configs/` or write your own.
+
+Commented contents of ``kresd.yaml`` follows:
+
+.. code-block:: yaml
+
+ programs:
+ - name: kresd # path to binary under test
+ binary: kresd
+ additional: # list additional parameters for binary under test (e.g. path to configuration files)
+ - --noninteractive
+ conncheck: True # wait until TCP port 53 accepts connections (enabled by default)
+ templates:
+ - template/kresd.j2 # list of Jinja2_ template files to generate configuration files
+ configs:
+ - config # list of names of configuration files to be generated from Jinja2_ templates
+ noclean: True # optional, do not remove working dir after a successful test
+
+- 'configs' files will be generated from respective files in 'templates' list
+- i.e. the first file in 'configs' list is the result of processing of the first file from 'templates' list and so on
+- generated files are stored in a new working directory created by Deckard for each binary
+
+Most often it is sufficient to use these files for basic configuration changes. Read next section for details about config file templates.
+
+Running multiple binaries
+^^^^^^^^^^^^^^^^^^^^^^^^^
+You can specify multiple programs to run in the YaML configuration. Deckard executes all binaries using parameters from the file. This is handy for testing interoperability of multiple binaries, e.g. when one program is configured as DNS recursor and other program is using it as forwarder.
+
+The YAML file contains **ordered** list of binaries and their parameters. Deckard will send queries to the binary listed first.
+
+.. code-block:: yaml
+
+ programs:
+ - name: forwarding # name of this Knot Resolver instance
+ binary: kresd # kresd is first so it will receive queries from Deckard
+ additional: []
+ templates:
+ - template/kresd_fwd.j2 # uses variable PROGRAMS['recursor']['address']
+ configs:
+ - config
+ - name: recursor # name of this Unbound instance
+ binary: unbound
+ additional:
+ - -d
+ - -c
+ - unbound.conf
+ templates:
+ - template/unbound.j2
+ - template/hints_zone.j2 # uses variable ROOT_ADDR
+ configs:
+ - unbound.conf
+ - hints.zone
+ - ta.keys
+
+In this setup it is necessary to configure one binary to contact the other. IP addresses assigned by Deckard at run-time are accessible using ``PROGRAMS`` `template variables`_ and symbolic names assigned to binaries in the YAML file. For example, template ``kresd_fwd.j2`` can use IP address of binary named ``recursor`` like this:
+
+.. code-block:: lua
+
+ policy.add(policy.all(policy.FORWARD("{{PROGRAMS['recursor']['address']}}")))
+
+When all preparations are finished, run Deckard using following syntax:
+
+.. code-block:: bash
+
+ $ ./run.sh --config path/to/config.yaml
+
+.. note:: You can run multiple configs in one test instance. Just be aware that ``--scenarios`` must be provided for each config.
+
+.. code-block::
+
+ # This will run scenarios from `scenarios1` folder with configuration from `config1.yaml` and `scenarios2.yaml` with `config2.yaml` respectively.
+ $ ./run.sh --config path/to/config1.yaml --scenarios path/to/scenarios1 --config path/to/config2.yaml --scenarios path/to/scenarios2
+
+
+
+
+Using an existing scenarios with custom configuration template
+--------------------------------------------------------------
+
+It some cases it is necessary to modify or create new template files. Typically this is needed when:
+
+- there are no templates for particular binary (e.g. if you want to test a brand new program)
+- an existing template hardcodes some configuration and you want to change it
+
+Deckard uses the Jinja2_ templating engine (like Ansible or Salt) and supplies several variables that you can use in templates. For simplicity you can imagine that all occurrences of ``{{variable}}`` in template are replaced with value of the *variable*. See Jinja2_ documentation for further details.
+
+Here is an example of template for Unbound:
+
+.. code-block:: jinja
+
+ server:
+ directory: "" # do not leave current working directory
+ chroot: ""
+ pidfile: ""
+ username: ""
+
+ interface: {{SELF_ADDR}} # Deckard will assign an address
+ interface-automatic: no
+ access-control: ::0/0 allow # accept queries from Deckard
+
+ do-daemonize: no # log to stdout & stderr
+ use-syslog: no
+ verbosity: 3 # be verbose, it is handy for debugging
+ val-log-level: 2
+ log-queries: yes
+
+ {% if QMIN == "false" %} # Jinja2 condition
+ qname-minimisation: no # a constant inside condition
+ {% else %}
+ qname-minimisation: yes
+ {% endif %}
+ harden-glue: no # hardcoded constant, use a variable instead!
+
+ root-hints: "hints.zone" # reference to other files in working directory
+ trust-anchor-file: "ta.keys" # use separate template to generate these
+
+This configuration snippet refers to files ``hints.zone`` and ``ta.keys`` which need to be generated as well. Each file uses own template file. An template for ``hints.zone`` might look like this:
+
+.. code-block:: jinja
+
+ # this is hints file which directs resolver to query
+ # fake root server simulated by Deckard
+ . 3600000 NS K.ROOT-SERVERS.NET.
+ # IP address version depends on scenario setting, handle IPv4 & IPv6
+ {% if ':' in ROOT_ADDR %}
+ K.ROOT-SERVERS.NET. 3600000 AAAA {{ROOT_ADDR}}
+ {% else %}
+ K.ROOT-SERVERS.NET. 3600000 A {{ROOT_ADDR}}
+ {% endif %}
+
+Templates can use any of following variables:
+
+.. _`template variables`:
+
+List of variables for templates
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+- ``DAEMON_NAME`` - user-specified symbolic name of particular binary under test, e.g. ``recursor``
+
+Addresses:
+
+- ``ROOT_ADDR`` - fake root server hint (an address declared in a RANGE)
+- ``FORWARD_ADDR`` - IP address where resolver should forward all queries (an address declared in a RANGE)
+- ``SELF_ADDR`` - address assigned to the binary under test
+
+- port is not expressed, must be 53
+- IP version depends on settings in particular scenario
+- templates must handle IPv4 and IPv6 as well
+
+Path variables:
+
+- ``INSTALL_DIR`` - path to directory containing file ``deckard.py``
+- ``WORKING_DIR`` - working directory for binary under test, each binary gets its own directory
+
+DNS specifics:
+
+- ``DO_NOT_QUERY_LOCALHOST`` [bool]_ - allows or disallows querying local addresses
+- ``HARDEN_GLUE`` [bool]_ - enables or disables additional checks on glue addresses
+- ``QMIN`` [bool]_ - enables or disables query minimization respectively
+- ``TRUST_ANCHORS`` - list of trust anchors in form of a DS records, see `scenario guide <doc/scenario_guide.rst>`_
+- ``NEGATIVE_TRUST_ANCHORS`` - list of domain names with explicitly disabled DNSSEC validation
+
+Cross references:
+- ``PROGRAMS`` - dictionary of dictionaries with parameters for each binary under test
+ - it is handy for cases where configuration for one binary under test has to refer to another binary under test, e.g. ``PROGRAMS['recursor']['address']`` and ``PROGRAMS['forwarder']['address']``.
+
+
+.. [bool] boolean expressed as string ``true``/``false``
+
+It's okay if you don't use all of the variables, but expect some tests to fail. E.g. if you don't set the ``TRUST_ANCHORS``,
+then the DNSSEC tests will not work properly.
+
+
+Debugging scenario execution
+----------------------------
+Output from a failed test looks like this:
+
+.. code-block::
+
+ $ ./kresd_run.sh
+ =========================================== FAILURES ===========================================
+ _____ test_passes_qmin_off[Scenario(path='sets/resolver/val_ta_sentinel.rpl', qmin=False)] _____
+ [...]
+ E ValueError: val_ta_sentinel.rpl step 212 char position 15875, "rcode": expected 'SERVFAIL',
+ E got 'NOERROR' in the response:
+ E id 54873
+ E opcode QUERY
+ E rcode NOERROR
+ E flags QR RD RA AD
+ E edns 0
+ E payload 4096
+ E ;QUESTION
+ E _is-ta-bd19.test. IN A
+ E ;ANSWER
+ E _is-ta-bd19.test. 5 IN A 192.0.2.1
+ E ;AUTHORITY
+ E ;ADDITIONAL
+
+ pydnstest/scenario.py:888: ValueError
+
+In this example, the test step ``212`` in scenario ``sets/resolver/val_ta_sentinel.rpl`` is failing with query-minimisation off. The binary under test did not produce expected answer, so either the test scenario or binary is wrong. If we were debugging this example, we would have to open file ``val_ta_sentinel.rpl`` on character postition ``15875`` and use our brains :-).
+
+Tips:
+
+- details about scenario format are in `the scenario guide <scenario_guide.rst>`_
+- network traffic from each binary is logged in PCAP format to a file in working directory
+- standard output and error from each binary is logged into log file in working directory
+- working directory can be explicitly specified in environment variable ``DECKARD_DIR`
+- command line argument ``--log-level DEBUG`` forces extra verbose logging, including logs from all binaries and packets handled by Deckard
+- environment variable ``DECKARD_NOCLEAN`` instructs Deckard not to remove working directories after successful tests
+- environment variable ``DECKARD_WRAPPER`` is prepended to all commands to be executed, intended usage is to run binary under test with ``valgrind`` or ``rr record``
+
+
+Writting own scenarios
+----------------------
+See `the scenario guide <scenario_guide.rst>`_.
+
+
+
+
+
+.. _`Jinja2`: http://jinja.pocoo.org/
diff --git a/tests/integration/deckard/getdns_run.sh b/tests/integration/deckard/getdns_run.sh
new file mode 100755
index 0000000..2dc7313
--- /dev/null
+++ b/tests/integration/deckard/getdns_run.sh
@@ -0,0 +1,63 @@
+#!/bin/bash
+set -o errexit -o nounset
+
+# Below a summary of tests that failed including a reason for the failure.
+# It might be wise to move these out of the way before testing with getdns.
+# Or provide alternatives.
+#
+# Tests known to fail can be moved out of the way:
+#
+# mkdir sets/resolver.out-of-the-way; for t in `grep '^##' getdns_run.sh | sed 's/^## //g'` ; do mv sets/resolver/$t sets/resolver.out-of-the-way; done
+#
+#
+# OPT-OUT is INSECURE
+# ===================
+# These fail because getdns will give answers to proven opt-out NSEC3 spans
+# the INSECURE status, but will include the DNSSEC data still:
+#
+## val_nsec3_b1_nameerror.rpl val_nsec3_b4_wild.rpl val_nsec3_b5_wcnodata.rpl
+## val_nsec3_b5_wcnodata_nowc.rpl val_nsec3_noopt_ref.out
+#
+#
+# Dependent on specific unbound configuration
+# ===========================================
+# These fail because they set specific unbound options in the
+# "; config options" section. We might consider facilitating this in getdns
+# at some point.
+#
+## iter_cycle_noh.rpl iter_ns_spoof.rpl
+#
+#
+# Knot resolver specific behaviour
+# ================================
+# These fail because it tests specific behaviour which is not the only "right"
+# way to do it correct.
+#
+## iter_lame_nosoa.rpl
+#
+#
+# Modules
+# =======
+# These fail because it tests certain modules that getdns does not have (yet).
+#
+## module_dns64.rpl module_policy_pass_deny.rpl
+## module_hint_static.rpl module_policy_rpz.rpl
+## module_policy_deny_all.rpl module_policy_tc.rpl
+## module_policy_deny_suff_comm.rpl module_renumber.rpl
+## module_policy_deny_suff_patt.rpl module_view_addr.rpl
+## module_policy_forward.rpl module_view_tsig.rpl
+#
+#
+# To investigate
+# ==============
+# These tests don't work, but we need to investigate what's wrong.
+#
+## iter_cname_badauth.rpl iter_minim_nonempty.rpl
+## iter_escape_bailiwick.rpl iter_minim_ns.rpl
+## iter_formerr.rpl iter_validate_extradata.rpl
+## iter_lame_root.rpl iter_validate.rpl
+## iter_minim_a_nxdomain.rpl nsec3_wildcard_no_data_response.rpl
+## iter_minim_a.rpl val_nsec3_optout_unsec_cache.rpl
+
+RUNDIR="$(dirname "$0")"
+cd "$RUNDIR" && ./run.sh --config configs/getdns.yaml "$@"
diff --git a/tests/integration/deckard/knotd_master_run.sh b/tests/integration/deckard/knotd_master_run.sh
new file mode 100755
index 0000000..9a61f3c
--- /dev/null
+++ b/tests/integration/deckard/knotd_master_run.sh
@@ -0,0 +1,6 @@
+#!/bin/bash
+set -o errexit -o nounset
+
+echo 'INFO: Tests require Knot compiled with ./configure --enable-recvmmsg=no'
+RUNDIR="$(dirname "$0")"
+cd "$RUNDIR" && ./run.sh --config configs/knotd_master.yaml "$@"
diff --git a/tests/integration/deckard/knotd_slave_run.sh b/tests/integration/deckard/knotd_slave_run.sh
new file mode 100755
index 0000000..239cef1
--- /dev/null
+++ b/tests/integration/deckard/knotd_slave_run.sh
@@ -0,0 +1,6 @@
+#!/bin/bash
+set -o errexit -o nounset
+
+echo 'INFO: Tests require Knot compiled with ./configure --enable-recvmmsg=no'
+RUNDIR="$(dirname "$0")"
+cd "$RUNDIR" && ./run.sh --config configs/knotd_slave.yaml "$@"
diff --git a/tests/integration/deckard/kresd_run.sh b/tests/integration/deckard/kresd_run.sh
new file mode 100755
index 0000000..5fd93e1
--- /dev/null
+++ b/tests/integration/deckard/kresd_run.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+set -o errexit -o nounset
+
+RUNDIR="$(dirname "$0")"
+cd "$RUNDIR" && ./run.sh --config configs/kresd.yaml "$@"
diff --git a/tests/integration/deckard/mypy.ini b/tests/integration/deckard/mypy.ini
new file mode 100644
index 0000000..2152e0b
--- /dev/null
+++ b/tests/integration/deckard/mypy.ini
@@ -0,0 +1,3 @@
+[mypy]
+[mypy-yaml.*]
+ignore_missing_imports = True
diff --git a/tests/integration/deckard/named_run.sh b/tests/integration/deckard/named_run.sh
new file mode 100755
index 0000000..d8a044b
--- /dev/null
+++ b/tests/integration/deckard/named_run.sh
@@ -0,0 +1,11 @@
+#!/bin/bash
+set -o errexit -o nounset
+named -V | grep --quiet -- '--without-jemalloc' || echo 'WARNING: Make sure BIND is compiled without jemalloc library; for 9.17+ use ./configure --without-jemalloc'
+MINOR="$(named -v | cut -d . -f 2)"
+if [[ "$MINOR" -le "13" ]]
+then
+ echo 'WARNING: For BIND <= 9.13.2 manually remove qname-minimization option from named.conf template referenced in configs/named.yaml (usually template/named.j2)'
+fi
+
+RUNDIR="$(dirname "$0")"
+cd "$RUNDIR" && ./run.sh --config configs/named.yaml "$@"
diff --git a/tests/integration/deckard/networking.py b/tests/integration/deckard/networking.py
new file mode 100644
index 0000000..6b76273
--- /dev/null
+++ b/tests/integration/deckard/networking.py
@@ -0,0 +1,93 @@
+import errno
+from ipaddress import IPv4Network, IPv6Network, ip_address
+from socket import AF_INET, AF_INET6
+
+# pylint: disable=no-name-in-module,import-error
+from pyroute2 import IPRoute
+from pyroute2.netlink.rtnl import ndmsg
+from pyroute2.netlink.exceptions import NetlinkError
+# pylint: enable=no-name-in-module,import-error
+
+
+class InterfaceManager:
+ """Wrapper for the `ip` command."""
+
+ def __init__(self,
+ interface="deckard",
+ ip4_range=IPv4Network('127.127.0.0/16'),
+ ip6_range=IPv6Network('fd00:dec::/32')):
+ self.ip4_internal_range = ip4_range
+ self.ip6_internal_range = ip6_range
+ self.ip4_iterator = (host for host in ip4_range)
+ self.ip6_iterator = (host for host in ip6_range)
+ self.added_addresses = set()
+ self.interface = interface
+
+ self._ip = IPRoute()
+ try:
+ self._dev = self._setup_interface()
+ except NetlinkError as ex:
+ raise RuntimeError(f"Couldn't set interface `{self.interface}` up.") from ex
+
+ def _setup_interface(self):
+ """Set up a dummy interface with default route as well as loopback.
+ This is done so the resulting PCAP contains as much of the communication
+ as possible (including ICMP Destination unreachable packets etc.)."""
+
+ # Create and set the interface up.
+ self._ip.link("add", ifname=self.interface, kind="dummy")
+ dev = self._ip.link_lookup(ifname=self.interface)[0]
+ self._ip.link("set", index=dev, state="up")
+
+ # Set up default route for both IPv6 and IPv4
+ self._ip.neigh("add", dst='169.254.1.1', lladdr='21:21:21:21:21:21',
+ state=ndmsg.states['permanent'], ifindex=dev)
+ self._ip.neigh("add", family=AF_INET6, dst='fe80::1', lladdr='21:21:21:21:21:21',
+ state=ndmsg.states['permanent'], ifindex=dev)
+ self._ip.addr("add", index=dev, address="169.254.1.2", mask=24)
+ self._ip.route("add", gateway="169.254.1.1", oif=dev)
+ self._ip.route("add", family=AF_INET6, gateway='fe80::1', oif=dev)
+
+ # Set the loopback up as well since some of the packets go through there.
+ lo = self._ip.link_lookup(ifname="lo")[0]
+ self._ip.link("set", index=lo, state="up")
+
+ # Return internal interface ID for later use
+ return dev
+
+ def assign_internal_address(self, sockfamily) -> str:
+ """Add and return new address from the internal range"""
+ try:
+ if sockfamily == AF_INET:
+ a = str(next(self.ip4_iterator))
+ elif sockfamily == AF_INET6:
+ a = str(next(self.ip6_iterator))
+ else:
+ raise ValueError(f"Unknown sockfamily {sockfamily}")
+ except StopIteration as ex:
+ raise RuntimeError("Out of addresses.") from ex
+
+ self._add_address(a)
+ return a
+
+ def add_address(self, address: str, check_duplicate=False):
+ """Add an arbitrary new address to the interface"""
+ if address in self.added_addresses and check_duplicate:
+ raise ValueError(f"Tried to add duplicate address {address}")
+ if ip_address(address) in self.ip4_internal_range or \
+ ip_address(address) in self.ip6_internal_range:
+ raise ValueError(f"Address {address} in the internally reserved range.")
+ self._add_address(address)
+
+ def _add_address(self, address):
+ if ":" in address:
+ mask = 128
+ else:
+ mask = 32
+ try:
+ self._ip.addr("add", index=self._dev, address=address, mask=mask, nodad=True)
+ except NetlinkError as ex:
+ if ex.code != errno.EEXIST: # 'RTNETLINK answers: File exists' is OK here
+ raise ValueError(f"Couldn't add {address}") from ex
+
+ self.added_addresses.add(address)
diff --git a/tests/integration/deckard/pdns_run.sh b/tests/integration/deckard/pdns_run.sh
new file mode 100755
index 0000000..bb1900e
--- /dev/null
+++ b/tests/integration/deckard/pdns_run.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+set -o errexit -o nounset
+
+RUNDIR="$(dirname "$0")"
+cd "$RUNDIR" && ./run.sh --config configs/pdns.yaml "$@"
diff --git a/tests/integration/deckard/pydnstest/__init__.py b/tests/integration/deckard/pydnstest/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/integration/deckard/pydnstest/__init__.py
diff --git a/tests/integration/deckard/pydnstest/augwrap.py b/tests/integration/deckard/pydnstest/augwrap.py
new file mode 100644
index 0000000..a0ec190
--- /dev/null
+++ b/tests/integration/deckard/pydnstest/augwrap.py
@@ -0,0 +1,226 @@
+#!/usr/bin/python3
+
+# Copyright (C) 2017
+
+import collections.abc
+import logging
+import os # requires posix
+
+from augeas import Augeas
+
+AUGEAS_LOAD_PATH = '/augeas/load/'
+AUGEAS_FILES_PATH = '/files/'
+AUGEAS_ERROR_PATH = '//error'
+
+log = logging.getLogger('augeas')
+
+
+def join(*paths):
+ """
+ join two Augeas tree paths
+
+ FIXME: Beware: // is normalized to /
+ """
+ norm_paths = [os.path.normpath(path) for path in paths]
+ # first path must be absolute
+ assert norm_paths[0][0] == '/'
+ new_paths = [norm_paths[0]]
+ # relativize all other paths so join works as expected
+ for path in norm_paths[1:]:
+ if path.startswith('/'):
+ path = path[1:]
+ new_paths.append(path)
+ new_path = os.path.join(*new_paths)
+ log.debug("join: new_path %s", new_path)
+ return os.path.normpath(new_path)
+
+
+class AugeasWrapper:
+ """python-augeas higher-level wrapper.
+
+ Load single augeas lens and configuration file.
+ Exposes configuration file as AugeasNode object with dict-like interface.
+
+ AugeasWrapper can be used in with statement in the same way as file does.
+ """
+
+ def __init__(self, confpath, lens, root=None, loadpath=None,
+ flags=Augeas.NO_MODL_AUTOLOAD | Augeas.NO_LOAD | Augeas.ENABLE_SPAN):
+ """Parse configuration file using given lens.
+
+ Params:
+ confpath (str): Absolute path to the configuration file
+ lens (str): Name of module containing Augeas lens
+ root: passed down to original Augeas
+ flags: passed down to original Augeas
+ loadpath: passed down to original Augeas
+ flags: passed down to original Augeas
+ """
+ log.debug('loadpath: %s', loadpath)
+ log.debug('confpath: %s', confpath)
+ self._aug = Augeas(root=root, loadpath=loadpath, flags=flags)
+
+ # /augeas/load/{lens}
+ aug_load_path = join(AUGEAS_LOAD_PATH, lens)
+ # /augeas/load/{lens}/lens = {lens}.lns
+ self._aug.set(join(aug_load_path, 'lens'), '%s.lns' % lens)
+ # /augeas/load/{lens}/incl[0] = {confpath}
+ self._aug.set(join(aug_load_path, 'incl[0]'), confpath)
+ self._aug.load()
+
+ errors = self._aug.match(AUGEAS_ERROR_PATH)
+ if errors:
+ err_msg = '\n'.join(
+ ["{}: {}".format(e, self._aug.get(e)) for e in errors]
+ )
+ raise RuntimeError(err_msg)
+
+ path = join(AUGEAS_FILES_PATH, confpath)
+ paths = self._aug.match(path)
+ if len(paths) != 1:
+ raise ValueError('path %s did not match exactly once' % path)
+ self.tree = AugeasNode(self._aug, path)
+ self._loaded = True
+
+ def __enter__(self):
+ return self
+
+ def __exit__(self, exc_type, exc_value, traceback):
+ self.save()
+ self.close()
+
+ def save(self):
+ """Save Augeas tree to its original file."""
+ assert self._loaded
+ try:
+ self._aug.save()
+ except IOError as exc:
+ log.exception(exc)
+ for err_path in self._aug.match('//error'):
+ log.error('%s: %s', err_path,
+ self._aug.get(os.path.join(err_path, 'message')))
+ raise
+
+ def close(self):
+ """
+ close Augeas library
+
+ After calling close() the object must not be used anymore.
+ """
+ assert self._loaded
+ self._aug.close()
+ del self._aug
+ self._loaded = False
+
+ def match(self, path):
+ """Yield AugeasNodes matching given expression."""
+ assert self._loaded
+ assert path
+ log.debug('tree match %s', path)
+ for matched_path in self._aug.match(path):
+ yield AugeasNode(self._aug, matched_path)
+
+
+class AugeasNode(collections.abc.MutableMapping):
+ """One Augeas tree node with dict-like interface."""
+
+ def __init__(self, aug, path):
+ """
+ Args:
+ aug (AugeasWrapper or Augeas): Augeas library instance
+ path (str): absolute path in Augeas tree matching single node
+
+ BEWARE: There are no sanity checks of given path for performance reasons.
+ """
+ assert aug
+ assert path
+ assert path.startswith('/')
+ self._aug = aug
+ self._path = path
+ self._span = None
+
+ @property
+ def path(self):
+ """canonical path in Augeas tree, read-only"""
+ return self._path
+
+ @property
+ def value(self):
+ """
+ get value of this node in Augeas tree
+ """
+ value = self._aug.get(self._path)
+ log.debug('tree get: %s = %s', self._path, value)
+ return value
+
+ @value.setter
+ def value(self, value):
+ """
+ set value of this node in Augeas tree
+ """
+ log.debug('tree set: %s = %s', self._path, value)
+ self._aug.set(self._path, value)
+
+ @property
+ def span(self):
+ if self._span is None:
+ self._span = "char position %s" % self._aug.span(self._path)[5]
+ return self._span
+
+ @property
+ def char(self):
+ return self._aug.span(self._path)[5]
+
+ def __len__(self):
+ """
+ number of items matching this path
+
+ It is always 1 after __init__() but it may change
+ as Augeas tree changes.
+ """
+ return len(self._aug.match(self._path))
+
+ def __getitem__(self, key):
+ if isinstance(key, int):
+ # int is a shortcut to write [int]
+ target_path = '%s[%s]' % (self._path, key)
+ else:
+ target_path = self._path + key
+ log.debug('tree getitem: target_path %s', target_path)
+ paths = self._aug.match(target_path)
+ if len(paths) != 1:
+ raise KeyError('path %s did not match exactly once' % target_path)
+ return AugeasNode(self._aug, target_path)
+
+ def __delitem__(self, key):
+ log.debug('tree delitem: %s + %s', self._path, key)
+ target_path = self._path + key
+ log.debug('tree delitem: target_path %s', target_path)
+ self._aug.remove(target_path)
+
+ def __setitem__(self, key, value):
+ assert isinstance(value, AugeasNode)
+ target_path = self.path + key
+ self._aug.copy(value.path, target_path)
+
+ def __iter__(self):
+ self_path_len = len(self._path)
+ assert self_path_len > 0
+
+ log.debug('tree iter: %s', self._path)
+ for new_path in self._aug.match(self._path):
+ if len(new_path) == self_path_len:
+ yield ''
+ else:
+ yield new_path[self_path_len - 1:]
+
+ def match(self, subpath):
+ """Yield AugeasNodes matching given sub-expression."""
+ assert subpath.startswith("/")
+ match_path = "%s%s" % (self._path, subpath)
+ log.debug('tree match %s: %s', match_path, self._path)
+ for matched_path in self._aug.match(match_path):
+ yield AugeasNode(self._aug, matched_path)
+
+ def __repr__(self):
+ return 'AugeasNode(%s)' % self._path
diff --git a/tests/integration/deckard/pydnstest/deckard.aug b/tests/integration/deckard/pydnstest/deckard.aug
new file mode 100644
index 0000000..9e2d167
--- /dev/null
+++ b/tests/integration/deckard/pydnstest/deckard.aug
@@ -0,0 +1,94 @@
+module Deckard =
+ autoload xfm
+
+let del_str = Util.del_str
+
+let space = del /[ \t]+/ " "
+let tab = del /[ \t]+/ "\t"
+let ws = del /[\t ]*/ ""
+let word = /[^\t\n\/; ]+/
+
+let comment = del /[;]/ ";" . [label "comment" . store /[^\n]+/]
+
+let eol = del /([ \t]*([;][^\n]*)?\n)+/ "\n" . Util.indent
+let comment_or_eol = ws . comment? . del_str "\n" . del /([ \t]*([;][^\n]*)?\n)*/ "" . Util.indent
+
+
+(*let comment_or_eol = [ label "#comment" . counter "comment" . (ws . [del /[;#]/ ";" . label "" . store /[^\n]*/ ]? . del_str "\n")]+ . Util.indent
+*)
+
+
+let domain_re = (/[^.\t\n\/; ]+(\.[^.\t\n\/; ]+)*\.?/ | ".") - "SECTION" (*quick n dirty, sorry to whoever will ever own SECTION TLD*)
+let class_re = /CLASS[0-9]+/ | "IN" | "CH" | "HS" | "NONE" | "ANY"
+let domain = [ label "domain" . store domain_re ]
+let ttl = [label "ttl" . store /[0-9]+/]
+let class = [label "class" . store class_re ]
+let type = [label "type" . store ((/[^0-9;\n \t][^\t\n\/; ]*/) - class_re) ]
+(* RFC 3597 section 5 rdata syntax is "\# 1 ab"*)
+let data_re = /((\\#[ \t])?[^ \t\n;][^\n;]*[^ \t\n;])|[^ \t\n;]/ (*Can not start nor end with whitespace but can have whitespace in the middle. Disjunction is there so we match strings of length one.*)
+let data = [label "data" . store data_re ]
+
+let ip_re = /[0-9a-f.:]+/
+let hex_re = /[0-9a-fA-F]+/
+
+
+let match_option = "opcode" | "qtype" | "qcase" | "qname" | "subdomain" | "flags" | "rcode" | "question" | "answer" | "authority" | "additional" | "all" | "edns"
+let adjust_option = "copy_id" | "copy_query" | "raw_id" | "do_not_answer"
+let reply_option = "QR" | "TC" | "AA" | "AD" | "RD" | "RA" | "CD" | "DO" | "NOERROR" | "FORMERR" | "SERVFAIL" | "NXDOMAIN" | "NOTIMP" | "REFUSED" | "YXDOMAIN" | "YXRRSET" | "NXRRSET" | "NOTAUTH" | "NOTZONE" | "BADVERS" | "BADSIG" | "BADKEY" | "BADTIME" | "BADMODE" | "BADNAME" | "BADALG" | "BADTRUNC" | "BADCOOKIE"
+let step_option = "REPLY" | "QUERY" | "CHECK_ANSWER" | "CHECK_OUT_QUERY" | /TIME_PASSES[ \t]+ELAPSE/
+
+let mandatory = [del_str "MANDATORY" . label "mandatory" . value "true" . comment_or_eol]
+let tsig = [del_str "TSIG" . label "tsig" . space . [label "keyname" . store word] . space . [label "secret" . store word] . comment_or_eol]
+
+let match = (mandatory | tsig)* . [ label "match_present" . value "true" . del_str "MATCH" ] . [space . label "match" . store match_option ]+ . comment_or_eol
+let adjust = (mandatory | tsig)* . del_str "ADJUST" . [space . label "adjust" . store adjust_option ]+ . comment_or_eol
+let reply = (mandatory | tsig)* . del ("REPLY" | "FLAGS") "REPLY" . [space . label "reply" . store reply_option ]+ . comment_or_eol
+
+
+let question = [label "record" . domain . tab . (class . tab)? . type . comment_or_eol ]
+let record = [label "record" . domain . tab . (ttl . tab)? . (class . tab)? . type . tab . data . comment_or_eol]
+
+let section_question = [ label "question" . del_str "SECTION QUESTION" .
+ comment_or_eol . question? ]
+let section_answer = [ label "answer" . del_str "SECTION ANSWER" .
+ comment_or_eol . record* ]
+let section_authority = [ label "authority" . del_str "SECTION AUTHORITY" .
+ comment_or_eol . record* ]
+let section_additional = [ label "additional" . del_str "SECTION ADDITIONAL" .
+ comment_or_eol . record* ]
+let sections = [label "section" . section_question? . section_answer? . section_authority? . section_additional?]
+let raw = [del_str "RAW" . comment_or_eol . label "raw" . store hex_re ] . comment_or_eol
+
+(* This is quite dirty hack to match every combination of options given to entry since 'let dnsmsg = ((match | adjust | reply | mandatory | tsig)* . sections)' just is not possible *)
+
+let dnsmsg = (match . (adjust . reply? | reply . adjust?)? | adjust . (match . reply? | reply . match?)? | reply . (match . adjust? | adjust . match?)?)? . (mandatory | tsig)* . sections
+
+let entry = [label "entry" . del_str "ENTRY_BEGIN" . comment_or_eol . dnsmsg . raw? . del_str "ENTRY_END" . eol]
+
+let single_address = [ label "address" . space . store ip_re ]
+
+let addresses = [label "address" . counter "address" . [seq "address" . del_str "ADDRESS" . space . store ip_re . comment_or_eol]+]
+
+let range = [label "range" . del_str "RANGE_BEGIN" . space . [ label "from" . store /[0-9]+/] . space .
+ [ label "to" . store /[0-9]+/] . single_address? . comment_or_eol . addresses? . entry* . del_str "RANGE_END" . eol]
+
+let step = [label "step" . del_str "STEP" . space . store /[0-9]+/ . space . [label "type" . store step_option] . [space . label "timestamp" . store /[0-9]+/]? . comment_or_eol .
+ entry? ]
+
+let config_record = /[^\n]*/ - ("CONFIG_END" | /STEP.*/ | /SCENARIO.*/ | /RANGE.*/ | /ENTRY.*/)
+
+let config = [ label "config" . counter "config" . [seq "config" . store config_record . del_str "\n"]* . del_str "CONFIG_END" . comment_or_eol ]
+
+let guts = (step | range )*
+
+let scenario = [label "scenario" . del_str "SCENARIO_BEGIN" . space . store data_re . comment_or_eol . guts . del_str "SCENARIO_END" . eol]
+
+let lns = config? . scenario
+
+(* TODO: REPLAY step *)
+(* TODO: store all comments into the tree instead of ignoring them *)
+
+(*let filter = incl "/home/test/*.rpl"*)
+let filter = incl "/home/sbalazik/nic/deckard/git/sets/resolver/*.rpl"
+
+let xfm = transform lns filter
diff --git a/tests/integration/deckard/pydnstest/empty.rpl b/tests/integration/deckard/pydnstest/empty.rpl
new file mode 100644
index 0000000..295d5a5
--- /dev/null
+++ b/tests/integration/deckard/pydnstest/empty.rpl
@@ -0,0 +1,20 @@
+stub-addr: 127.0.0.10
+CONFIG_END
+
+SCENARIO_BEGIN empty replies
+
+RANGE_BEGIN 0 100
+ ADDRESS 127.0.0.10
+ENTRY_BEGIN
+MATCH subdomain
+ADJUST copy_id copy_query
+SECTION QUESTION
+. IN A
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/pydnstest/matchpart.py b/tests/integration/deckard/pydnstest/matchpart.py
new file mode 100644
index 0000000..4a9d8a0
--- /dev/null
+++ b/tests/integration/deckard/pydnstest/matchpart.py
@@ -0,0 +1,238 @@
+"""matchpart is used to compare two DNS messages using a single criterion"""
+
+from typing import ( # noqa
+ Any, Hashable, Sequence, Tuple, Union)
+
+import dns.edns
+import dns.rcode
+import dns.set
+
+MismatchValue = Union[str, Sequence[Any]]
+
+
+class DataMismatch(Exception):
+ def __init__(self, exp_val, got_val):
+ super().__init__()
+ self.exp_val = exp_val
+ self.got_val = got_val
+
+ @staticmethod
+ def format_value(value: MismatchValue) -> str:
+ if isinstance(value, list):
+ return ' '.join([str(val) for val in value])
+ else:
+ return str(value)
+
+ def __str__(self) -> str:
+ return 'expected "{}" got "{}"'.format(
+ self.format_value(self.exp_val),
+ self.format_value(self.got_val))
+
+ def __eq__(self, other):
+ return (isinstance(other, DataMismatch)
+ and self.exp_val == other.exp_val
+ and self.got_val == other.got_val)
+
+ def __ne__(self, other):
+ return not self.__eq__(other)
+
+ @property
+ def key(self) -> Tuple[Hashable, Hashable]:
+ def make_hashable(value):
+ if isinstance(value, (list, dns.set.Set)):
+ value = (make_hashable(item) for item in value)
+ value = tuple(value)
+ return value
+
+ return (make_hashable(self.exp_val), make_hashable(self.got_val))
+
+ def __hash__(self) -> int:
+ return hash(self.key)
+
+
+def compare_val(exp, got):
+ """Compare arbitraty objects, throw exception if different. """
+ if exp != got:
+ raise DataMismatch(exp, got)
+ return True
+
+
+def compare_rrs(expected, got):
+ """ Compare lists of RR sets, throw exception if different. """
+ for rr in expected:
+ if rr not in got:
+ raise DataMismatch(expected, got)
+ for rr in got:
+ if rr not in expected:
+ raise DataMismatch(expected, got)
+ if len(expected) != len(got):
+ raise DataMismatch(expected, got)
+ return True
+
+
+def compare_rrs_types(exp_val, got_val, skip_rrsigs):
+ """sets of RR types in both sections must match"""
+ def rr_ordering_key(rrset):
+ if rrset.covers:
+ return rrset.covers, 1 # RRSIGs go to the end of RRtype list
+ else:
+ return rrset.rdtype, 0
+
+ def key_to_text(rrtype, rrsig):
+ if not rrsig:
+ return dns.rdatatype.to_text(rrtype)
+ else:
+ return 'RRSIG(%s)' % dns.rdatatype.to_text(rrtype)
+
+ if skip_rrsigs:
+ exp_val = (rrset for rrset in exp_val
+ if rrset.rdtype != dns.rdatatype.RRSIG)
+ got_val = (rrset for rrset in got_val
+ if rrset.rdtype != dns.rdatatype.RRSIG)
+
+ exp_types = frozenset(rr_ordering_key(rrset) for rrset in exp_val)
+ got_types = frozenset(rr_ordering_key(rrset) for rrset in got_val)
+ if exp_types != got_types:
+ exp_types = tuple(key_to_text(*i) for i in sorted(exp_types))
+ got_types = tuple(key_to_text(*i) for i in sorted(got_types))
+ raise DataMismatch(exp_types, got_types)
+
+
+def check_question(question):
+ if len(question) > 2:
+ raise NotImplementedError("More than one record in QUESTION SECTION.")
+
+
+def match_opcode(exp, got):
+ return compare_val(exp.opcode(),
+ got.opcode())
+
+
+def match_qtype(exp, got):
+ check_question(exp.question)
+ check_question(got.question)
+ if not exp.question and not got.question:
+ return True
+ if not exp.question:
+ raise DataMismatch("<empty question>", got.question[0].rdtype)
+ if not got.question:
+ raise DataMismatch(exp.question[0].rdtype, "<empty question>")
+ return compare_val(exp.question[0].rdtype,
+ got.question[0].rdtype)
+
+
+def match_qname(exp, got):
+ check_question(exp.question)
+ check_question(got.question)
+ if not exp.question and not got.question:
+ return True
+ if not exp.question:
+ raise DataMismatch("<empty question>", got.question[0].name)
+ if not got.question:
+ raise DataMismatch(exp.question[0].name, "<empty question>")
+ return compare_val(exp.question[0].name,
+ got.question[0].name)
+
+
+def match_qcase(exp, got):
+ check_question(exp.question)
+ check_question(got.question)
+ if not exp.question and not got.question:
+ return True
+ if not exp.question:
+ raise DataMismatch("<empty question>", got.question[0].name.labels)
+ if not got.question:
+ raise DataMismatch(exp.question[0].name.labels, "<empty question>")
+ return compare_val(exp.question[0].name.labels,
+ got.question[0].name.labels)
+
+
+def match_subdomain(exp, got):
+ if not exp.question:
+ return True
+ if got.question:
+ qname = got.question[0].name
+ else:
+ qname = dns.name.root
+ if exp.question[0].name.is_superdomain(qname):
+ return True
+ raise DataMismatch(exp, got)
+
+
+def match_flags(exp, got):
+ return compare_val(dns.flags.to_text(exp.flags),
+ dns.flags.to_text(got.flags))
+
+
+def match_rcode(exp, got):
+ return compare_val(dns.rcode.to_text(exp.rcode()),
+ dns.rcode.to_text(got.rcode()))
+
+
+def match_answer(exp, got):
+ return compare_rrs(exp.answer,
+ got.answer)
+
+
+def match_answertypes(exp, got):
+ return compare_rrs_types(exp.answer,
+ got.answer, skip_rrsigs=True)
+
+
+def match_answerrrsigs(exp, got):
+ return compare_rrs_types(exp.answer,
+ got.answer, skip_rrsigs=False)
+
+
+def match_authority(exp, got):
+ return compare_rrs(exp.authority,
+ got.authority)
+
+
+def match_additional(exp, got):
+ return compare_rrs(exp.additional,
+ got.additional)
+
+
+def match_edns(exp, got):
+ if got.edns != exp.edns:
+ raise DataMismatch(exp.edns,
+ got.edns)
+ if got.payload != exp.payload:
+ raise DataMismatch(exp.payload,
+ got.payload)
+
+
+def match_nsid(exp, got):
+ nsid_opt = None
+ for opt in exp.options:
+ if opt.otype == dns.edns.NSID:
+ nsid_opt = opt
+ break
+ # Find matching NSID
+ for opt in got.options:
+ if opt.otype == dns.edns.NSID:
+ if not nsid_opt:
+ raise DataMismatch(None, opt.data)
+ if opt == nsid_opt:
+ return True
+ else:
+ raise DataMismatch(nsid_opt.data, opt.data)
+ if nsid_opt:
+ raise DataMismatch(nsid_opt.data, None)
+ return True
+
+
+MATCH = {"opcode": match_opcode, "qtype": match_qtype, "qname": match_qname, "qcase": match_qcase,
+ "subdomain": match_subdomain, "flags": match_flags, "rcode": match_rcode,
+ "answer": match_answer, "answertypes": match_answertypes,
+ "answerrrsigs": match_answerrrsigs, "authority": match_authority,
+ "additional": match_additional, "edns": match_edns,
+ "nsid": match_nsid}
+
+
+def match_part(exp, got, code):
+ try:
+ return MATCH[code](exp, got)
+ except KeyError as ex:
+ raise NotImplementedError('unknown match request "%s"' % code) from ex
diff --git a/tests/integration/deckard/pydnstest/mock_client.py b/tests/integration/deckard/pydnstest/mock_client.py
new file mode 100644
index 0000000..6089a21
--- /dev/null
+++ b/tests/integration/deckard/pydnstest/mock_client.py
@@ -0,0 +1,136 @@
+"""Module takes care of sending and recieving DNS messages as a mock client"""
+
+import errno
+import socket
+import struct
+import time
+from typing import Optional, Tuple, Union
+
+import dns.message
+import dns.inet
+
+
+SOCKET_OPERATION_TIMEOUT = 5
+RECEIVE_MESSAGE_SIZE = 2**16-1
+THROTTLE_BY = 0.1
+
+
+def handle_socket_timeout(sock: socket.socket, deadline: float):
+ # deadline is always time.monotonic
+ remaining = deadline - time.monotonic()
+ if remaining <= 0:
+ raise RuntimeError("Server took too long to respond")
+ sock.settimeout(remaining)
+
+
+def recv_n_bytes_from_tcp(stream: socket.socket, n: int, deadline: float) -> bytes:
+ # deadline is always time.monotonic
+ data = b""
+ while n != 0:
+ handle_socket_timeout(stream, deadline)
+ chunk = stream.recv(n)
+ # Empty bytes from socket.recv mean that socket is closed
+ if not chunk:
+ raise OSError()
+ n -= len(chunk)
+ data += chunk
+ return data
+
+
+def recvfrom_blob(sock: socket.socket,
+ timeout: int = SOCKET_OPERATION_TIMEOUT) -> Tuple[bytes, str]:
+ """
+ Receive DNS message from TCP/UDP socket.
+ """
+
+ # deadline is always time.monotonic
+ deadline = time.monotonic() + timeout
+
+ while True:
+ try:
+ if sock.type & socket.SOCK_DGRAM:
+ handle_socket_timeout(sock, deadline)
+ data, addr = sock.recvfrom(RECEIVE_MESSAGE_SIZE)
+ elif sock.type & socket.SOCK_STREAM:
+ # First 2 bytes of TCP packet are the size of the message
+ # See https://tools.ietf.org/html/rfc1035#section-4.2.2
+ data = recv_n_bytes_from_tcp(sock, 2, deadline)
+ msg_len = struct.unpack_from("!H", data)[0]
+ data = recv_n_bytes_from_tcp(sock, msg_len, deadline)
+ addr = sock.getpeername()[0]
+ else:
+ raise NotImplementedError("[recvfrom_blob]: unknown socket type '%i'" % sock.type)
+ return data, addr
+ except socket.timeout as ex:
+ raise RuntimeError("Server took too long to respond") from ex
+ except OSError as ex:
+ if ex.errno == errno.ENOBUFS:
+ time.sleep(0.1)
+ else:
+ raise
+
+
+def recvfrom_msg(sock: socket.socket,
+ timeout: int = SOCKET_OPERATION_TIMEOUT) -> Tuple[dns.message.Message, str]:
+ data, addr = recvfrom_blob(sock, timeout=timeout)
+ msg = dns.message.from_wire(data, one_rr_per_rrset=True)
+ return msg, addr
+
+
+def sendto_msg(sock: socket.socket, message: bytes, addr: Optional[str] = None) -> None:
+ """ Send DNS/UDP/TCP message. """
+ try:
+ if sock.type & socket.SOCK_DGRAM:
+ if addr is None:
+ sock.send(message)
+ else:
+ sock.sendto(message, addr)
+ elif sock.type & socket.SOCK_STREAM:
+ data = struct.pack("!H", len(message)) + message
+ sock.sendall(data)
+ else:
+ raise NotImplementedError("[sendto_msg]: unknown socket type '%i'" % sock.type)
+ except OSError as ex:
+ # Reference: http://lkml.iu.edu/hypermail/linux/kernel/0002.3/0709.html
+ if ex.errno != errno.ECONNREFUSED:
+ raise
+
+
+def setup_socket(address: str,
+ port: int,
+ tcp: bool = False,
+ src_address: str = None) -> socket.socket:
+ family = dns.inet.af_for_address(address)
+ sock = socket.socket(family, socket.SOCK_STREAM if tcp else socket.SOCK_DGRAM)
+ if tcp:
+ sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, True)
+ if src_address is not None:
+ sock.bind((src_address, 0)) # random source port
+ sock.settimeout(SOCKET_OPERATION_TIMEOUT)
+ sock.connect((address, port))
+ return sock
+
+
+def send_query(sock: socket.socket, query: Union[dns.message.Message, bytes]) -> None:
+ message = query if isinstance(query, bytes) else query.to_wire()
+ while True:
+ try:
+ sendto_msg(sock, message)
+ break
+ except OSError as ex:
+ # ENOBUFS, throttle sending
+ if ex.errno == errno.ENOBUFS:
+ time.sleep(0.1)
+ else:
+ raise
+
+
+def get_answer(sock: socket.socket, timeout: int = SOCKET_OPERATION_TIMEOUT) -> bytes:
+ """ Compatibility function """
+ answer, _ = recvfrom_blob(sock, timeout=timeout)
+ return answer
+
+
+def get_dns_message(sock: socket.socket,
+ timeout: int = SOCKET_OPERATION_TIMEOUT) -> dns.message.Message:
+ return dns.message.from_wire(get_answer(sock, timeout=timeout))
diff --git a/tests/integration/deckard/pydnstest/scenario.py b/tests/integration/deckard/pydnstest/scenario.py
new file mode 100644
index 0000000..9ef318c
--- /dev/null
+++ b/tests/integration/deckard/pydnstest/scenario.py
@@ -0,0 +1,888 @@
+from abc import ABC
+import binascii
+import calendar
+from datetime import datetime
+import logging
+import os # requires posix
+import random
+import socket
+import struct
+import time
+from typing import Optional
+
+import dns.dnssec
+import dns.message
+import dns.name
+import dns.rcode
+import dns.rrset
+import dns.tsigkeyring
+
+import pydnstest.augwrap
+import pydnstest.matchpart
+import pydnstest.mock_client
+
+
+def str2bool(v):
+ """ Return conversion of JSON-ish string value to boolean. """
+ return v.lower() in ('yes', 'true', 'on', '1')
+
+
+# Global statistics
+g_rtt = 0.0
+g_nqueries = 0
+
+
+class DNSBlob(ABC):
+ def to_wire(self) -> bytes:
+ raise NotImplementedError
+
+ def __str__(self) -> str:
+ return '<DNSBlob>'
+
+
+class DNSMessage(DNSBlob):
+ def __init__(self, message: dns.message.Message) -> None:
+ assert message is not None
+ self.message = message
+
+ def to_wire(self) -> bytes:
+ return self.message.to_wire(max_size=65535)
+
+ def __str__(self) -> str:
+ return str(self.message)
+
+
+class DNSReply(DNSMessage):
+ def __init__(
+ self,
+ message: dns.message.Message,
+ query: Optional[dns.message.Message] = None,
+ copy_id: bool = False,
+ copy_query: bool = False
+ ) -> None:
+ super().__init__(message)
+ if copy_id or copy_query:
+ if query is None:
+ raise ValueError("query must be provided to adjust copy_id/copy_query")
+ self.adjust_reply(query, copy_id, copy_query)
+
+ def adjust_reply(
+ self,
+ query: dns.message.Message,
+ copy_id: bool = True,
+ copy_query: bool = True
+ ) -> None:
+ answer = dns.message.from_wire(self.message.to_wire(),
+ xfr=self.message.xfr,
+ one_rr_per_rrset=True)
+ answer.use_edns(query.edns, query.ednsflags, options=self.message.options)
+ if copy_id:
+ answer.id = query.id
+ # Copy letter-case if the template has QD
+ if answer.question:
+ answer.question[0].name = query.question[0].name
+ if copy_query:
+ answer.question = query.question
+ # Re-set, as the EDNS might have reset the ext-rcode
+ answer.set_rcode(self.message.rcode())
+
+ # sanity check: adjusted answer should be almost the same
+ assert len(answer.answer) == len(self.message.answer)
+ assert len(answer.authority) == len(self.message.authority)
+ assert len(answer.additional) == len(self.message.additional)
+ self.message = answer
+
+
+class DNSReplyRaw(DNSBlob):
+ def __init__(
+ self,
+ wire: bytes,
+ query: Optional[dns.message.Message] = None,
+ copy_id: bool = False
+ ) -> None:
+ assert wire is not None
+ self.wire = wire
+ if copy_id:
+ if query is None:
+ raise ValueError("query must be provided to adjust copy_id")
+ self.adjust_reply(query, copy_id)
+
+ def adjust_reply(
+ self,
+ query: dns.message.Message,
+ raw_id: bool = True
+ ) -> None:
+ if raw_id:
+ if len(self.wire) < 2:
+ raise ValueError(
+ 'wire data must contain at least 2 bytes to adjust query id')
+ raw_answer = bytearray(self.wire)
+ struct.pack_into('!H', raw_answer, 0, query.id)
+ self.wire = bytes(raw_answer)
+
+ def to_wire(self) -> bytes:
+ return self.wire
+
+ def __str__(self) -> str:
+ return '<DNSReplyRaw>'
+
+
+class DNSReplyServfail(DNSMessage):
+ def __init__(self, query: dns.message.Message) -> None:
+ message = dns.message.make_response(query)
+ message.set_rcode(dns.rcode.SERVFAIL)
+ super().__init__(message)
+
+
+class Entry:
+ """
+ Data entry represents scripted message and extra metadata,
+ notably match criteria and reply adjustments.
+ """
+
+ # Globals
+ default_ttl = 3600
+ default_cls = 'IN'
+ default_rc = 'NOERROR'
+
+ def __init__(self, node):
+ """ Initialize data entry. """
+ self.node = node
+ self.origin = '.'
+ self.message = dns.message.Message()
+ self.message.use_edns(edns=0, payload=4096)
+ self.fired = 0
+
+ # RAW
+ self.raw_data = self.process_raw()
+
+ # MATCH
+ self.match_fields = self.process_match()
+
+ # FLAGS (old alias REPLY)
+ self.process_reply_line()
+
+ # ADJUST
+ self.adjust_fields = {m.value for m in node.match("/adjust")}
+
+ # MANDATORY
+ try:
+ self.mandatory = list(node.match("/mandatory"))[0]
+ except (KeyError, IndexError):
+ self.mandatory = None
+
+ # TSIG
+ self.process_tsig()
+
+ # SECTIONS & RECORDS
+ self.sections = self.process_sections()
+
+ def process_raw(self):
+ try:
+ return binascii.unhexlify(self.node["/raw"].value)
+ except KeyError:
+ return None
+
+ def process_match(self):
+ try:
+ self.node["/match_present"]
+ except KeyError:
+ return None
+
+ fields = set(m.value for m in self.node.match("/match"))
+
+ if 'all' in fields:
+ fields.remove("all")
+ fields |= set(["opcode", "qtype", "qname", "flags",
+ "rcode", "answer", "authority", "additional"])
+
+ if 'question' in fields:
+ fields.remove("question")
+ fields |= set(["qtype", "qname"])
+
+ return fields
+
+ def process_reply_line(self):
+ """Extracts flags, rcode and opcode from given node and adjust dns message accordingly"""
+ fields = [f.value for f in self.node.match("/reply")]
+ if 'DO' in fields:
+ self.message.want_dnssec(True)
+ opcode = self.get_opcode(fields)
+ rcode = self.get_rcode(fields)
+ self.message.flags = self.get_flags(fields)
+ if rcode is not None:
+ self.message.set_rcode(rcode)
+ if opcode is not None:
+ self.message.set_opcode(opcode)
+
+ def process_tsig(self):
+ try:
+ tsig = list(self.node.match("/tsig"))[0]
+ tsig_keyname = tsig["/keyname"].value
+ tsig_secret = tsig["/secret"].value
+ keyring = dns.tsigkeyring.from_text({tsig_keyname: tsig_secret})
+ self.message.use_tsig(keyring=keyring, keyname=tsig_keyname)
+ except (KeyError, IndexError):
+ pass
+
+ def process_sections(self):
+ sections = set()
+ for section in self.node.match("/section/*"):
+ section_name = os.path.basename(section.path)
+ sections.add(section_name)
+ for record in section.match("/record"):
+ owner = record['/domain'].value
+ if not owner.endswith("."):
+ owner += self.origin
+ try:
+ ttl = dns.ttl.from_text(record['/ttl'].value)
+ except KeyError:
+ ttl = self.default_ttl
+ try:
+ rdclass = dns.rdataclass.from_text(record['/class'].value)
+ except KeyError:
+ rdclass = dns.rdataclass.from_text(self.default_cls)
+ rdtype = dns.rdatatype.from_text(record['/type'].value)
+ rr = dns.rrset.from_text(owner, ttl, rdclass, rdtype)
+ if section_name != "question":
+ rd = record['/data'].value.split()
+ if rd:
+ if rdtype == dns.rdatatype.DS:
+ rd[1] = '{}'.format(dns.dnssec.algorithm_from_text(rd[1]))
+ rd = dns.rdata.from_text(rr.rdclass, rr.rdtype, ' '.join(
+ rd), origin=dns.name.from_text(self.origin), relativize=False)
+ rr.add(rd)
+ if section_name == 'question':
+ if rr.rdtype == dns.rdatatype.AXFR:
+ self.message.xfr = True
+ self.message.question.append(rr)
+ elif section_name == 'answer':
+ self.message.answer.append(rr)
+ elif section_name == 'authority':
+ self.message.authority.append(rr)
+ elif section_name == 'additional':
+ self.message.additional.append(rr)
+ return sections
+
+ def __str__(self):
+ txt = 'ENTRY_BEGIN\n'
+ if self.raw_data is None:
+ txt += 'MATCH {0}\n'.format(' '.join(self.match_fields))
+ txt += 'ADJUST {0}\n'.format(' '.join(self.adjust_fields))
+ txt += 'REPLY {rcode} {flags}\n'.format(
+ rcode=dns.rcode.to_text(self.message.rcode()),
+ flags=' '.join([dns.flags.to_text(self.message.flags),
+ dns.flags.edns_to_text(self.message.ednsflags)])
+ )
+ for sect_name in ['question', 'answer', 'authority', 'additional']:
+ sect = getattr(self.message, sect_name)
+ if not sect:
+ continue
+ txt += 'SECTION {n}\n'.format(n=sect_name.upper())
+ for rr in sect:
+ txt += str(rr)
+ txt += '\n'
+ if self.raw_data is not None:
+ txt += 'RAW\n'
+ if self.raw_data:
+ txt += binascii.hexlify(self.raw_data)
+ else:
+ txt += 'NULL'
+ txt += '\n'
+ txt += 'ENTRY_END\n'
+ return txt
+
+ @classmethod
+ def get_flags(cls, fields):
+ """From `fields` extracts and returns flags"""
+ flags = []
+ for code in fields:
+ try:
+ dns.flags.from_text(code) # throws KeyError on failure
+ flags.append(code)
+ except KeyError:
+ pass
+ return dns.flags.from_text(' '.join(flags))
+
+ @classmethod
+ def get_rcode(cls, fields):
+ """
+ From `fields` extracts and returns rcode.
+ Throws `ValueError` if there are more then one rcodes
+ """
+ rcodes = []
+ for code in fields:
+ try:
+ rcodes.append(dns.rcode.from_text(code))
+ except dns.rcode.UnknownRcode:
+ pass
+ if len(rcodes) > 1:
+ raise ValueError("Parse failed, too many rcode values.", rcodes)
+ if not rcodes:
+ return None
+ return rcodes[0]
+
+ @classmethod
+ def get_opcode(cls, fields):
+ """
+ From `fields` extracts and returns opcode.
+ Throws `ValueError` if there are more then one opcodes
+ """
+ opcodes = []
+ for code in fields:
+ try:
+ opcodes.append(dns.opcode.from_text(code))
+ except dns.opcode.UnknownOpcode:
+ pass
+ if len(opcodes) > 1:
+ raise ValueError("Parse failed, too many opcode values.")
+ if not opcodes:
+ return None
+ return opcodes[0]
+
+ def match(self, msg):
+ """ Compare scripted reply to given message based on match criteria. """
+ for code in self.match_fields:
+ try:
+ pydnstest.matchpart.match_part(self.message, msg, code)
+ except pydnstest.matchpart.DataMismatch as ex:
+ errstr = '%s in the response:\n%s' % (str(ex), msg.to_text())
+ # TODO: cisla radku
+ raise ValueError("%s, \"%s\": %s" % (self.node.span, code, errstr)) from None
+
+ def cmp_raw(self, raw_value):
+ assert self.raw_data is not None
+ expected = None
+ if self.raw_data is not None:
+ expected = binascii.hexlify(self.raw_data)
+ got = None
+ if raw_value is not None:
+ got = binascii.hexlify(raw_value)
+ if expected != got:
+ raise ValueError("raw message comparsion failed: expected %s got %s" % (expected, got))
+
+ def reply(self, query) -> Optional[DNSBlob]:
+ if 'do_not_answer' in self.adjust_fields:
+ return None
+ if self.raw_data is not None:
+ raw_id = 'raw_id' in self.adjust_fields
+ assert self.raw_data is not None
+ return DNSReplyRaw(self.raw_data, query, raw_id)
+ copy_id = 'copy_id' in self.adjust_fields
+ copy_query = 'copy_query' in self.adjust_fields
+ return DNSReply(self.message, query, copy_id, copy_query)
+
+ def set_edns(self, fields):
+ """ Set EDNS version and bufsize. """
+ version = 0
+ bufsize = 4096
+ if fields and fields[0].isdigit():
+ version = int(fields.pop(0))
+ if fields and fields[0].isdigit():
+ bufsize = int(fields.pop(0))
+ if bufsize == 0:
+ self.message.use_edns(False)
+ return
+ opts = []
+ for v in fields:
+ k, v = tuple(v.split('=')) if '=' in v else (v, True)
+ if k.lower() == 'nsid':
+ opts.append(dns.edns.GenericOption(dns.edns.NSID, '' if v is True else v))
+ if k.lower() == 'subnet':
+ net = v.split('/')
+ subnet_addr = net[0]
+ family = socket.AF_INET6 if ':' in subnet_addr else socket.AF_INET
+ addr = socket.inet_pton(family, subnet_addr)
+ prefix = len(addr) * 8
+ if len(net) > 1:
+ prefix = int(net[1])
+ addr = addr[0: (prefix + 7) / 8]
+ if prefix % 8 != 0: # Mask the last byte
+ addr = addr[:-1] + chr(ord(addr[-1]) & 0xFF << (8 - prefix % 8))
+ opts.append(dns.edns.GenericOption(8, struct.pack(
+ "!HBB", 1 if family == socket.AF_INET else 2, prefix, 0) + addr))
+ self.message.use_edns(edns=version, payload=bufsize, options=opts)
+
+
+class Range:
+ """
+ Range represents a set of scripted queries valid for given step range.
+ """
+ log = logging.getLogger('pydnstest.scenario.Range')
+
+ def __init__(self, node):
+ """ Initialize reply range. """
+ self.node = node
+ self.a = int(node['/from'].value)
+ self.b = int(node['/to'].value)
+ assert self.a <= self.b
+
+ address = node["/address"].value
+ self.addresses = {address} if address is not None else set()
+ self.addresses |= {a.value for a in node.match("/address/*")}
+ self.stored = [Entry(n) for n in node.match("/entry")]
+ self.args = {}
+ self.received = 0
+ self.sent = 0
+
+ def __del__(self):
+ self.log.info('[ RANGE %d-%d ] %s received: %d sent: %d',
+ self.a, self.b, self.addresses, self.received, self.sent)
+
+ def __str__(self):
+ txt = '\nRANGE_BEGIN {a} {b}\n'.format(a=self.a, b=self.b)
+ for addr in self.addresses:
+ txt += ' ADDRESS {0}\n'.format(addr)
+
+ for entry in self.stored:
+ txt += '\n'
+ txt += str(entry)
+ txt += 'RANGE_END\n\n'
+ return txt
+
+ def eligible(self, ident, address):
+ """ Return true if this range is eligible for fetching reply. """
+ if self.a <= ident <= self.b:
+ return (None is address
+ or set() == self.addresses
+ or address in self.addresses)
+ return False
+
+ def reply(self, query: dns.message.Message) -> Optional[DNSBlob]:
+ """Get answer for given query (adjusted if needed)."""
+ self.received += 1
+ for candidate in self.stored:
+ try:
+ candidate.match(query)
+ resp = candidate.reply(query)
+ # Probabilistic loss
+ if 'LOSS' in self.args:
+ if random.random() < float(self.args['LOSS']):
+ return DNSReplyServfail(query)
+ self.sent += 1
+ candidate.fired += 1
+ return resp
+ except ValueError:
+ pass
+ return DNSReplyServfail(query)
+
+
+class StepLogger(logging.LoggerAdapter): # pylint: disable=too-few-public-methods
+ """
+ Prepent Step identification before each log message.
+ """
+ def process(self, msg, kwargs):
+ return '[STEP %s %s] %s' % (self.extra['id'], self.extra['type'], msg), kwargs
+
+
+class Step:
+ """
+ Step represents one scripted action in a given moment,
+ each step has an order identifier, type and optionally data entry.
+ """
+ require_data = ['QUERY', 'CHECK_ANSWER', 'REPLY']
+
+ def __init__(self, node):
+ """ Initialize single scenario step. """
+ self.node = node
+ self.id = int(node.value)
+ self.type = node["/type"].value
+ self.log = StepLogger(logging.getLogger('pydnstest.scenario.Step'),
+ {'id': self.id, 'type': self.type})
+ try:
+ self.delay = int(node["/timestamp"].value)
+ except KeyError:
+ pass
+ self.data = [Entry(n) for n in node.match("/entry")]
+ self.queries = []
+ self.has_data = self.type in Step.require_data
+ self.answer = None
+ self.raw_answer = None
+ self.repeat_if_fail = 0
+ self.pause_if_fail = 0
+ self.next_if_fail = -1
+
+ def __str__(self):
+ txt = '\nSTEP {i} {t}'.format(i=self.id, t=self.type)
+ if self.repeat_if_fail:
+ txt += ' REPEAT {v}'.format(v=self.repeat_if_fail)
+ elif self.pause_if_fail:
+ txt += ' PAUSE {v}'.format(v=self.pause_if_fail)
+ elif self.next_if_fail != -1:
+ txt += ' NEXT {v}'.format(v=self.next_if_fail)
+ # if self.args:
+ # txt += ' '
+ # txt += ' '.join(self.args)
+ txt += '\n'
+
+ for data in self.data:
+ # from IPython.core.debugger import Tracer
+ # Tracer()()
+ txt += str(data)
+ return txt
+
+ def play(self, ctx):
+ """ Play one step from a scenario. """
+ if self.type == 'QUERY':
+ self.log.info('')
+ self.log.debug(self.data[0].message.to_text())
+ # Parse QUERY-specific parameters
+ choice, tcp, src_address = None, False, ctx.deckard_address
+ return self.__query(ctx, tcp=tcp, choice=choice, src_address=src_address)
+ elif self.type == 'CHECK_OUT_QUERY': # ignore
+ self.log.info('')
+ return None
+ elif self.type == 'CHECK_ANSWER' or self.type == 'ANSWER':
+ self.log.info('')
+ return self.__check_answer(ctx)
+ elif self.type == 'TIME_PASSES ELAPSE':
+ self.log.info('')
+ return self.__time_passes()
+ elif self.type == 'REPLY' or self.type == 'MOCK':
+ self.log.info('')
+ return None
+ else:
+ raise NotImplementedError('step %03d type %s unsupported' % (self.id, self.type))
+
+ def __check_answer(self, ctx):
+ """ Compare answer from previously resolved query. """
+ if not self.data:
+ raise ValueError("response definition required")
+ expected = self.data[0]
+ if expected.raw_data is not None:
+ self.log.debug("raw answer: %s", ctx.last_raw_answer.to_text())
+ expected.cmp_raw(ctx.last_raw_answer)
+ else:
+ if ctx.last_answer is None:
+ raise ValueError("no answer from preceding query")
+ self.log.debug("answer: %s", ctx.last_answer.to_text())
+ expected.match(ctx.last_answer)
+
+ def __query(self, ctx, tcp=False, choice=None, src_address=None):
+ """
+ Send query and wait for an answer (if the query is not RAW).
+
+ The received answer is stored in self.answer and ctx.last_answer.
+ """
+ if not self.data:
+ raise ValueError("query definition required")
+ if self.data[0].raw_data is not None:
+ data_to_wire = self.data[0].raw_data
+ else:
+ # Don't use a message copy as the EDNS data portion is not copied.
+ data_to_wire = self.data[0].message.to_wire()
+ if choice is None or not choice:
+ choice = list(ctx.client.keys())[0]
+ if choice not in ctx.client:
+ raise ValueError('step %03d invalid QUERY target: %s' % (self.id, choice))
+
+ tstart = datetime.now()
+
+ # Send query and wait for answer
+ answer = None
+ sock = pydnstest.mock_client.setup_socket(ctx.client[choice][0],
+ ctx.client[choice][1],
+ tcp,
+ src_address=src_address)
+ with sock:
+ pydnstest.mock_client.send_query(sock, data_to_wire)
+ if self.data[0].raw_data is None:
+ answer = pydnstest.mock_client.get_answer(sock)
+
+ # Track RTT
+ rtt = (datetime.now() - tstart).total_seconds() * 1000
+ global g_rtt, g_nqueries
+ g_nqueries += 1
+ g_rtt += rtt
+
+ # Remember last answer for checking later
+ self.raw_answer = answer
+ ctx.last_raw_answer = answer
+ if self.raw_answer is not None:
+ self.answer = dns.message.from_wire(self.raw_answer, one_rr_per_rrset=True)
+ else:
+ self.answer = None
+ ctx.last_answer = self.answer
+
+ def __time_passes(self):
+ """ Modify system time. """
+ file_old = os.environ["FAKETIME_TIMESTAMP_FILE"]
+ file_next = os.environ["FAKETIME_TIMESTAMP_FILE"] + ".next"
+ with open(file_old, 'r') as time_file:
+ line = time_file.readline().strip()
+ t = time.mktime(datetime.strptime(line, '@%Y-%m-%d %H:%M:%S').timetuple())
+ t += self.delay
+ with open(file_next, 'w') as time_file:
+ time_file.write(datetime.fromtimestamp(t).strftime('@%Y-%m-%d %H:%M:%S') + "\n")
+ time_file.flush()
+ os.replace(file_next, file_old)
+
+
+class Scenario:
+ log = logging.getLogger('pydnstest.scenatio.Scenario')
+
+ def __init__(self, node, filename, deckard_address=None):
+ """ Initialize scenario with description. """
+ self.node = node
+ self.info = node.value
+ self.file = filename
+ self.ranges = [Range(n) for n in node.match("/range")]
+ self.current_range = None
+ self.steps = [Step(n) for n in node.match("/step")]
+ self.current_step = None
+ self.client = {}
+ self.deckard_address = deckard_address
+
+ def __str__(self):
+ txt = 'SCENARIO_BEGIN'
+ if self.info:
+ txt += ' {0}'.format(self.info)
+ txt += '\n'
+ for range_ in self.ranges:
+ txt += str(range_)
+ for step in self.steps:
+ txt += str(step)
+ txt += "\nSCENARIO_END"
+ return txt
+
+ def reply(self, query: dns.message.Message, address=None) -> Optional[DNSBlob]:
+ """Generate answer packet for given query."""
+ current_step_id = self.current_step.id
+ # Unknown address, select any match
+ # TODO: workaround until the server supports stub zones
+ all_addresses = set() # type: ignore
+ for rng in self.ranges:
+ all_addresses.update(rng.addresses)
+ if address not in all_addresses:
+ address = None
+ # Find current valid query response range
+ for rng in self.ranges:
+ if rng.eligible(current_step_id, address):
+ self.current_range = rng
+ return rng.reply(query)
+ # Find any prescripted one-shot replies
+ for step in self.steps:
+ if step.id < current_step_id or step.type != 'REPLY':
+ continue
+ try:
+ candidate = step.data[0]
+ candidate.match(query)
+ step.data.remove(candidate)
+ return candidate.reply(query)
+ except (IndexError, ValueError):
+ pass
+ return DNSReplyServfail(query)
+
+ def play(self, paddr):
+ """ Play given scenario. """
+ # Store test subject => address mapping
+ self.client = paddr
+
+ step = None
+ i = 0
+ while i < len(self.steps):
+ step = self.steps[i]
+ self.current_step = step
+ try:
+ step.play(self)
+ except ValueError as ex:
+ if step.repeat_if_fail > 0:
+ self.log.info("[play] step %d: exception - '%s', retrying step %d (%d left)",
+ step.id, ex, step.next_if_fail, step.repeat_if_fail)
+ step.repeat_if_fail -= 1
+ if step.pause_if_fail > 0:
+ time.sleep(step.pause_if_fail)
+ if step.next_if_fail != -1:
+ next_steps = [j for j in range(len(self.steps)) if self.steps[
+ j].id == step.next_if_fail]
+ if not next_steps:
+ raise ValueError('step %d: wrong NEXT value "%d"' %
+ (step.id, step.next_if_fail)) from ex
+ next_step = next_steps[0]
+ if next_step < len(self.steps):
+ i = next_step
+ else:
+ raise ValueError('step %d: Can''t branch to NEXT value "%d"' %
+ (step.id, step.next_if_fail)) from ex
+ continue
+ ex_details = ex if self.log.isEnabledFor(logging.DEBUG) else None
+ raise ValueError('%s step %d %s' % (self.file, step.id, str(ex))) from ex_details
+ i += 1
+
+ for r in self.ranges:
+ for e in r.stored:
+ if e.mandatory and e.fired == 0:
+ # TODO: cisla radku
+ raise ValueError('Mandatory section at %s not fired' % e.mandatory.span)
+
+
+def get_next(file_in, skip_empty=True):
+ """ Return next token from the input stream. """
+ while True:
+ line = file_in.readline()
+ if not line:
+ return False
+ quoted, escaped = False, False
+ for i, char in enumerate(line):
+ if char == '\\':
+ escaped = not escaped
+ if not escaped and char == '"':
+ quoted = not quoted
+ if char == ';' and not quoted:
+ line = line[0:i]
+ break
+ if char != '\\':
+ escaped = False
+ tokens = ' '.join(line.strip().split()).split()
+ if not tokens:
+ if skip_empty:
+ continue
+ return '', []
+ op = tokens.pop(0)
+ return op, tokens
+
+
+def parse_config(scn_cfg, qmin, installdir): # FIXME: pylint: disable=too-many-statements
+ """
+ Transform scene config (key, value) pairs into dict filled with defaults.
+ Returns tuple:
+ context dict: {Jinja2 variable: value}
+ trust anchor dict: {domain: [TA lines for particular domain]}
+ """
+ # defaults
+ do_not_query_localhost = True
+ harden_glue = True
+ sockfamily = 0 # auto-select value for socket.getaddrinfo
+ trust_anchor_list = []
+ trust_anchor_files = {}
+ negative_ta_list = []
+ stub_addr = None
+ stub_name = "k.root-servers.net"
+ override_timestamp = None
+ forward_addr = None
+ do_ip6 = True
+ do_ip4 = True
+ features = {}
+ feature_list_delimiter = ';'
+ feature_pair_delimiter = '='
+
+ for k, v in scn_cfg:
+ # Enable selectively for some tests
+ if k == 'do-not-query-localhost':
+ do_not_query_localhost = str2bool(v)
+ elif k == 'domain-insecure':
+ negative_ta_list.append(v)
+ elif k == 'harden-glue':
+ harden_glue = str2bool(v)
+ elif k == 'query-minimization':
+ qmin = str2bool(v)
+ elif k == 'trust-anchor':
+ trust_anchor = v.strip('"\'')
+ trust_anchor_list.append(trust_anchor)
+ domain = dns.name.from_text(trust_anchor.split()[0]).canonicalize()
+ if domain not in trust_anchor_files:
+ trust_anchor_files[domain] = []
+ trust_anchor_files[domain].append(trust_anchor)
+ elif k == 'val-override-timestamp':
+ override_timestamp_str = v.strip('"\'')
+ override_timestamp = int(override_timestamp_str)
+ elif k == 'val-override-date':
+ override_date_str = v.strip('"\'')
+ ovr_yr = override_date_str[0:4]
+ ovr_mnt = override_date_str[4:6]
+ ovr_day = override_date_str[6:8]
+ ovr_hr = override_date_str[8:10]
+ ovr_min = override_date_str[10:12]
+ ovr_sec = override_date_str[12:]
+ override_date_str_arg = '{0} {1} {2} {3} {4} {5}'.format(
+ ovr_yr, ovr_mnt, ovr_day, ovr_hr, ovr_min, ovr_sec)
+ override_date = time.strptime(override_date_str_arg, "%Y %m %d %H %M %S")
+ override_timestamp = calendar.timegm(override_date)
+ elif k == 'stub-addr':
+ stub_addr = v.strip('"\'')
+ elif k == 'stub-name':
+ stub_name = v
+ elif k == 'features':
+ feature_list = v.split(feature_list_delimiter)
+ try:
+ for f_item in feature_list:
+ if f_item.find(feature_pair_delimiter) != -1:
+ f_key, f_value = [x.strip()
+ for x
+ in f_item.split(feature_pair_delimiter, 1)]
+ else:
+ f_key = f_item.strip()
+ f_value = ""
+ features[f_key] = f_value
+ except KeyError as ex:
+ raise KeyError("can't parse features (%s) in config section (%s)"
+ % (v, str(ex))) from ex
+ elif k == 'feature-list':
+ try:
+ f_key, f_value = [x.strip() for x in v.split(feature_pair_delimiter, 1)]
+ if f_key not in features:
+ features[f_key] = []
+ f_value = f_value.replace("{{INSTALL_DIR}}", installdir)
+ features[f_key].append(f_value)
+ except KeyError as ex:
+ raise KeyError("can't parse feature-list (%s) in config section (%s)"
+ % (v, str(ex))) from ex
+ elif k == 'force-ipv6' and v.upper() == 'TRUE':
+ sockfamily = socket.AF_INET6
+ elif k == 'forward-addr': # currently forwards everything
+ forward_addr = v.strip('"\'')
+ elif k == 'do-ip4':
+ do_ip4 = str2bool(v)
+ elif k == 'do-ip6':
+ do_ip6 = str2bool(v)
+ else:
+ raise NotImplementedError('unsupported CONFIG key "%s"' % k)
+
+ ctx = {
+ "DO_NOT_QUERY_LOCALHOST": str(do_not_query_localhost).lower(),
+ "NEGATIVE_TRUST_ANCHORS": negative_ta_list,
+ "FEATURES": features,
+ "HARDEN_GLUE": str(harden_glue).lower(),
+ "INSTALL_DIR": installdir,
+ "QMIN": str(qmin).lower(),
+ "TRUST_ANCHORS": trust_anchor_list,
+ "TRUST_ANCHOR_FILES": trust_anchor_files,
+ "FORWARD_ADDR": forward_addr,
+ "DO_IP6": str(do_ip6).lower(),
+ "DO_IP4": str(do_ip4).lower(),
+ }
+ if stub_addr:
+ ctx['ROOT_ADDR'] = stub_addr
+ ctx['ROOT_NAME'] = stub_name
+ # determine and verify socket family for specified root address
+ gai = socket.getaddrinfo(stub_addr, 53, sockfamily, 0,
+ socket.IPPROTO_UDP, socket.AI_NUMERICHOST)
+ assert len(gai) == 1
+ sockfamily = gai[0][0]
+ if not sockfamily:
+ sockfamily = socket.AF_INET # default to IPv4
+ ctx['_SOCKET_FAMILY'] = sockfamily
+ if override_timestamp:
+ ctx['_OVERRIDE_TIMESTAMP'] = override_timestamp
+ return ctx
+
+
+def parse_file(path, deckard_address=None):
+ """ Parse scenario from a file. """
+
+ aug = pydnstest.augwrap.AugeasWrapper(
+ confpath=path, lens='Deckard', loadpath=os.path.dirname(__file__))
+ node = aug.tree
+ config = []
+ for line in [c.value for c in node.match("/config/*")]:
+ if line:
+ if not line.startswith(';'):
+ if '#' in line:
+ line = line[0:line.index('#')]
+ # Break to key-value pairs
+ # e.g.: ['minimization', 'on']
+ kv = [x.strip() for x in line.split(':', 1)]
+ if len(kv) >= 2:
+ config.append(kv)
+ scenario = Scenario(node["/scenario"], os.path.basename(node.path), deckard_address)
+ return scenario, config
diff --git a/tests/integration/deckard/pydnstest/tests/__init__.py b/tests/integration/deckard/pydnstest/tests/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/integration/deckard/pydnstest/tests/__init__.py
diff --git a/tests/integration/deckard/pydnstest/tests/test_parse_config.py b/tests/integration/deckard/pydnstest/tests/test_parse_config.py
new file mode 100644
index 0000000..d8cdea1
--- /dev/null
+++ b/tests/integration/deckard/pydnstest/tests/test_parse_config.py
@@ -0,0 +1,17 @@
+""" This is unittest file for parse methods in scenario.py """
+import os
+
+from pydnstest.scenario import parse_config
+
+
+def test_parse_config__trust_anchor():
+ """Checks if trust-anchors are separated into files according to domain."""
+ anchor1 = u'domain1.com.\t3600\tIN\tDS\t11901 7 1 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
+ anchor2 = u'domain2.net.\t3600\tIN\tDS\t59835 7 1 cccccccccccccccccccccccccccccccccccccccc'
+ anchor3 = u'domain1.com.\t3600\tIN\tDS\t11902 7 1 1111111111111111111111111111111111111111'
+ anchors = [[u'trust-anchor', u'"{}"'.format(anchor1)],
+ [u'trust-anchor', u'"{}"'.format(anchor2)],
+ [u'trust-anchor', u'"{}"'.format(anchor3)]]
+ args = (anchors, True, os.getcwd())
+ ta_files = parse_config(*args)["TRUST_ANCHOR_FILES"]
+ assert sorted(ta_files.values()) == sorted([[anchor1, anchor3], [anchor2]])
diff --git a/tests/integration/deckard/pydnstest/tests/test_scenario.py b/tests/integration/deckard/pydnstest/tests/test_scenario.py
new file mode 100644
index 0000000..454cb5c
--- /dev/null
+++ b/tests/integration/deckard/pydnstest/tests/test_scenario.py
@@ -0,0 +1,55 @@
+""" This is unittest file for scenario.py """
+
+import pytest
+
+from pydnstest.scenario import Entry
+
+RCODE_FLAGS = ['NOERROR', 'FORMERR', 'SERVFAIL', 'NXDOMAIN', 'NOTIMP', 'REFUSED', 'YXDOMAIN',
+ 'YXRRSET', 'NXRRSET', 'NOTAUTH', 'NOTZONE', 'BADVERS']
+OPCODE_FLAGS = ['QUERY', 'IQUERY', 'STATUS', 'NOTIFY', 'UPDATE']
+FLAGS = ['QR', 'TC', 'AA', 'AD', 'RD', 'RA', 'CD']
+
+
+def test_entry__get_flags():
+ """Checks if all rcodes and opcodes are filtered out"""
+ expected_flags = Entry.get_flags(FLAGS)
+ for flag in RCODE_FLAGS + OPCODE_FLAGS:
+ rcode_flags = Entry.get_flags(FLAGS + [flag])
+ assert rcode_flags == expected_flags, \
+ 'Entry._get_flags does not filter out "{flag}"'.format(flag=flag)
+
+
+def test_entry__get_rcode():
+ """
+ Checks if the error is raised for multiple rcodes
+ checks if None is returned for no rcode
+ checks if flags and opcode are filtered out
+ """
+ with pytest.raises(ValueError):
+ Entry.get_rcode(RCODE_FLAGS[:2])
+
+ assert Entry.get_rcode(FLAGS) is None
+ assert Entry.get_rcode([]) is None
+
+ for rcode in RCODE_FLAGS:
+ given_rcode = Entry.get_rcode(FLAGS + OPCODE_FLAGS + [rcode])
+ assert given_rcode is not None, 'Entry.get_rcode does not recognize {rcode}'.format(
+ rcode=rcode)
+
+
+def test_entry__get_opcode():
+ """
+ Checks if the error is raised for multiple opcodes
+ checks if None is returned for no opcode
+ checks if flags and opcode are filtered out
+ """
+ with pytest.raises(ValueError):
+ Entry.get_opcode(OPCODE_FLAGS[:2])
+
+ assert Entry.get_opcode(FLAGS) is None
+ assert Entry.get_opcode([]) is None
+
+ for opcode in OPCODE_FLAGS:
+ given_rcode = Entry.get_opcode(FLAGS + RCODE_FLAGS + [opcode])
+ assert given_rcode is not None, 'Entry.get_opcode does not recognize {opcode}'.format(
+ opcode=opcode)
diff --git a/tests/integration/deckard/pydnstest/testserver.py b/tests/integration/deckard/pydnstest/testserver.py
new file mode 100644
index 0000000..5be2959
--- /dev/null
+++ b/tests/integration/deckard/pydnstest/testserver.py
@@ -0,0 +1,309 @@
+import argparse
+import itertools
+import logging
+import os
+import random
+import signal
+import selectors
+import socket
+import sys
+import threading
+import time
+
+import dns.message
+import dns.rdatatype
+
+from pydnstest import scenario, mock_client
+from networking import InterfaceManager
+
+
+class TestServer:
+ """ This simulates UDP DNS server returning scripted or mirror DNS responses. """
+
+ RETRIES_ON_BIND = 3
+
+ def __init__(self, test_scenario, addr_family,
+ deckard_address=None, if_manager=None):
+ """ Initialize server instance. """
+ self.thread = None
+ self.srv_socks = []
+ self.client_socks = []
+ self.connections = []
+ self.active = False
+ self.active_lock = threading.Lock()
+ self.condition = threading.Condition()
+ self.scenario = test_scenario
+ self.scenario.deckard_address = deckard_address
+ self.addr_map = []
+ self.start_iface = 2
+ self.cur_iface = self.start_iface
+ self.addr_family = addr_family
+ self.undefined_answers = 0
+ self.if_manager = if_manager
+
+ def __del__(self):
+ """ Cleanup after deletion. """
+ with self.active_lock:
+ active = self.active
+ if active:
+ self.stop()
+
+ def start(self):
+ """ Synchronous start """
+ with self.active_lock:
+ if self.active:
+ raise Exception('TestServer already started')
+ with self.active_lock:
+ self.active = True
+
+ self._bind_sockets()
+
+ def stop(self):
+ """ Stop socket server operation. """
+ with self.active_lock:
+ self.active = False
+ if self.thread:
+ self.thread.join()
+ for conn in self.connections:
+ conn.close()
+ for srv_sock in self.srv_socks:
+ srv_sock.close()
+ for client_sock in self.client_socks:
+ client_sock.close()
+ self.client_socks = []
+ self.srv_socks = []
+ self.connections = []
+ self.scenario = None
+
+ def address(self):
+ """ Returns opened sockets list """
+ addrlist = []
+ for s in self.srv_socks:
+ addrlist.append(s.getsockname())
+ return addrlist
+
+ def handle_query(self, client):
+ """
+ Receive query from client socket and send an answer.
+
+ Returns:
+ True if client socket should be closed by caller
+ False if client socket should be kept open
+ """
+ log = logging.getLogger('pydnstest.testserver.handle_query')
+ server_addr = client.getsockname()[0]
+ query, client_addr = mock_client.recvfrom_msg(client)
+ if query is None:
+ return False
+ log.debug('server %s received query from %s: %s', server_addr, client_addr, query)
+
+ message = self.scenario.reply(query, server_addr)
+ if not message:
+ log.debug('ignoring')
+ return True
+ elif isinstance(message, scenario.DNSReplyServfail):
+ self.undefined_answers += 1
+ self.scenario.current_step.log.error(
+ 'server %s has no response for question %s, answering with SERVFAIL',
+ server_addr,
+ '; '.join([str(rr) for rr in query.question]))
+ else:
+ log.debug('response: %s', message)
+
+ mock_client.sendto_msg(client, message.to_wire(), client_addr)
+ return True
+
+ def query_io(self):
+ """ Main server process """
+ self.undefined_answers = 0
+ with self.active_lock:
+ if not self.active:
+ raise Exception("[query_io] Test server not active")
+ while True:
+ with self.condition:
+ self.condition.notify()
+ with self.active_lock:
+ if not self.active:
+ break
+ objects = self.srv_socks + self.connections
+ sel = selectors.DefaultSelector()
+ for obj in objects:
+ sel.register(obj, selectors.EVENT_READ)
+ items = sel.select(0.1)
+ for key, event in items:
+ sock = key.fileobj
+ if event & selectors.EVENT_READ:
+ if sock in self.srv_socks:
+ if sock.proto == socket.IPPROTO_TCP:
+ conn, _ = sock.accept()
+ self.connections.append(conn)
+ else:
+ self.handle_query(sock)
+ elif sock in self.connections:
+ if not self.handle_query(sock):
+ sock.close()
+ self.connections.remove(sock)
+ else:
+ raise Exception(
+ "[query_io] Socket IO internal error {}, exit"
+ .format(sock.getsockname()))
+ else:
+ raise Exception("[query_io] Socket IO error {}, exit"
+ .format(sock.getsockname()))
+
+ def start_srv(self, address, family, proto=socket.IPPROTO_UDP):
+ """ Starts listening thread if necessary """
+ assert address
+ assert address[0] # host
+ assert address[1] # port
+ assert family
+ assert proto
+ if family == socket.AF_INET6:
+ if not socket.has_ipv6:
+ raise NotImplementedError("[start_srv] IPv6 is not supported by socket {0}"
+ .format(socket))
+ elif family != socket.AF_INET:
+ raise NotImplementedError("[start_srv] unsupported protocol family {0}".format(family))
+
+ if proto == socket.IPPROTO_TCP:
+ socktype = socket.SOCK_STREAM
+ elif proto == socket.IPPROTO_UDP:
+ socktype = socket.SOCK_DGRAM
+ else:
+ raise NotImplementedError("[start_srv] unsupported protocol {0}".format(proto))
+
+ if self.thread is None:
+ self.thread = threading.Thread(target=self.query_io)
+ self.thread.start()
+ with self.condition:
+ self.condition.wait()
+
+ for srv_sock in self.srv_socks:
+ if (srv_sock.family == family
+ and srv_sock.getsockname()[:2] == address
+ and srv_sock.proto == proto):
+ return
+
+ sock = socket.socket(family, socktype, proto)
+ sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
+
+ # Add address to interface when running from Deckard
+ if self.if_manager is not None:
+ if address[0] not in self.if_manager.added_addresses:
+ self.if_manager.add_address(address[0])
+
+ # A lot of addresses are added to the interface while runnning from Deckard in
+ # the small amount of time which caused ocassional hiccups while binding to them
+ # right afterwards in testing. Therefore, we retry a few times.
+ final_ex = None
+ for i in range(self.RETRIES_ON_BIND):
+ try:
+ sock.bind(address)
+ break
+ except OSError as ex:
+ # Exponential backoff
+ time.sleep((2 ** i) + random.random())
+ final_ex = ex
+ continue
+ else:
+ print(final_ex, address)
+ raise final_ex
+
+ if proto == socket.IPPROTO_TCP:
+ sock.listen(5)
+ self.srv_socks.append(sock)
+
+ def _bind_sockets(self):
+ """
+ Bind test server to port 53 on all addresses referenced by test scenario.
+ """
+ # Bind to test servers
+ for r in self.scenario.ranges:
+ for addr in r.addresses:
+ family = socket.AF_INET6 if ':' in addr else socket.AF_INET
+ self.start_srv((addr, 53), family)
+ self.start_srv((addr, 53), family, proto=socket.IPPROTO_TCP)
+
+ # Bind addresses in ad-hoc REPLYs
+ for s in self.scenario.steps:
+ if s.type == 'REPLY':
+ reply = s.data[0].message
+ for rr in itertools.chain(reply.answer,
+ reply.additional,
+ reply.question,
+ reply.authority):
+ for rd in rr:
+ if rd.rdtype == dns.rdatatype.A:
+ self.start_srv((rd.address, 53), socket.AF_INET)
+ self.start_srv((rd.address, 53), socket.AF_INET,
+ proto=socket.IPPROTO_TCP)
+ elif rd.rdtype == dns.rdatatype.AAAA:
+ self.start_srv((rd.address, 53), socket.AF_INET6)
+ self.start_srv((rd.address, 53), socket.AF_INET6,
+ proto=socket.IPPROTO_TCP)
+
+ def play(self, subject_addr):
+ self.scenario.play({'': (subject_addr, 53)})
+
+
+def empty_test_case():
+ """
+ Return (scenario, config) pair which answers to any query on 127.0.0.10.
+ """
+ # Mirror server
+ empty_test_path = os.path.dirname(os.path.realpath(__file__)) + "/empty.rpl"
+ test_config = {'ROOT_ADDR': '127.0.0.10',
+ '_SOCKET_FAMILY': socket.AF_INET}
+ return scenario.parse_file(empty_test_path)[0], test_config
+
+
+def standalone_self_test():
+ """
+ Self-test code
+
+ Usage:
+ unshare -rn $PYTHON -m pydnstest.testserver --help
+ """
+ logging.basicConfig(level=logging.DEBUG)
+ argparser = argparse.ArgumentParser()
+ argparser.add_argument('--scenario', help='absolute path to test scenario',
+ required=False)
+ argparser.add_argument('--step', help='step # in the scenario (default: first)',
+ required=False, type=int)
+ args = argparser.parse_args()
+ if args.scenario:
+ test_scenario, test_config_text = scenario.parse_file(args.scenario)
+ test_config = scenario.parse_config(test_config_text, True, os.getcwd())
+ else:
+ test_scenario, test_config = empty_test_case()
+
+ if args.step:
+ for step in test_scenario.steps:
+ if step.id == args.step:
+ test_scenario.current_step = step
+ if not test_scenario.current_step:
+ raise ValueError('step ID %s not found in scenario' % args.step)
+ else:
+ test_scenario.current_step = test_scenario.steps[0]
+
+ if_manager = InterfaceManager(interface="testserver")
+ server = TestServer(test_scenario, test_config['_SOCKET_FAMILY'], if_manager=if_manager)
+ server.start()
+
+ logging.info("[==========] Mirror server running at %s", server.address())
+
+ def kill(signum, frame): # pylint: disable=unused-argument
+ logging.info("[==========] Shutdown.")
+ server.stop()
+ sys.exit(128 + signum)
+
+ signal.signal(signal.SIGINT, kill)
+ signal.signal(signal.SIGTERM, kill)
+
+ while True:
+ time.sleep(0.5)
+
+
+if __name__ == '__main__':
+ # this is done to avoid creating global variables
+ standalone_self_test()
diff --git a/tests/integration/deckard/pylintrc b/tests/integration/deckard/pylintrc
new file mode 100644
index 0000000..59eb616
--- /dev/null
+++ b/tests/integration/deckard/pylintrc
@@ -0,0 +1,27 @@
+[MESSAGES CONTROL]
+
+disable=
+ missing-docstring,
+ too-few-public-methods,
+ too-many-arguments,
+ too-many-locals,
+ too-many-branches,
+ too-many-instance-attributes,
+ fixme,
+ unused-import, # checked by flake8
+ line-too-long, # checked by flake8
+ invalid-name,
+ global-statement,
+ no-else-return,
+ bad-continuation,
+ duplicate-code,
+
+
+[SIMILARITIES]
+min-similarity-lines=6
+ignore-comments=yes
+ignore-docstrings=yes
+ignore-imports=no
+
+[DESIGN]
+max-parents=10
diff --git a/tests/integration/deckard/requirements.txt b/tests/integration/deckard/requirements.txt
new file mode 100644
index 0000000..900b86b
--- /dev/null
+++ b/tests/integration/deckard/requirements.txt
@@ -0,0 +1,9 @@
+dnspython>=1.15
+dpkt
+Jinja2>=2.10.2
+PyYAML
+python-augeas
+pytest>=3.4
+pytest-xdist
+pytest-forked
+pyroute2
diff --git a/tests/integration/deckard/rplint.py b/tests/integration/deckard/rplint.py
new file mode 100755
index 0000000..558045e
--- /dev/null
+++ b/tests/integration/deckard/rplint.py
@@ -0,0 +1,352 @@
+#!/usr/bin/env python3
+
+import itertools
+import os
+import sys
+from typing import Any, Callable, Iterable, Iterator, Optional, List, Union, Set # noqa
+
+import pydnstest.augwrap
+import pydnstest.matchpart
+import pydnstest.scenario
+
+Element = Union["Entry", "Step", pydnstest.scenario.Range]
+
+RCODES = {"NOERROR", "FORMERR", "SERVFAIL", "NXDOMAIN", "NOTIMP", "REFUSED", "YXDOMAIN", "YXRRSET",
+ "NXRRSET", "NOTAUTH", "NOTZONE", "BADVERS", "BADSIG", "BADKEY", "BADTIME", "BADMODE",
+ "BADNAME", "BADALG", "BADTRUNC", "BADCOOKIE"}
+FLAGS = {"QR", "AA", "TC", "RD", "RA", "AD", "CD"}
+SECTIONS = {"question", "answer", "authority", "additional"}
+
+
+class RplintError(ValueError):
+ def __init__(self, fails):
+ msg = ""
+ for fail in fails:
+ msg += str(fail) + "\n"
+ super().__init__(msg)
+
+
+def get_line_number(file: str, char_number: int) -> int:
+ pos = 0
+ with open(file) as f:
+ for number, line in enumerate(f):
+ pos += len(line)
+ if pos >= char_number:
+ return number + 2
+ return 0
+
+
+def is_empty(iterable: Iterator[Any]) -> bool:
+ try:
+ next(iterable)
+ except StopIteration:
+ return True
+ return False
+
+
+class Entry:
+ def __init__(self, node: pydnstest.augwrap.AugeasNode) -> None:
+ self.match = {m.value for m in node.match("/match")}
+ self.adjust = {a.value for a in node.match("/adjust")}
+ self.answer = list(node.match("/section/answer/record"))
+ self.authority = list(node.match("/section/authority/record"))
+ self.additional = list(node.match("/section/additional/record"))
+ self.reply = {r.value for r in node.match("/reply")}
+ self.records = list(node.match("/section/*/record"))
+ self.node = node
+
+
+class Step:
+ def __init__(self, node: pydnstest.augwrap.AugeasNode) -> None:
+ self.node = node
+ self.type = node["/type"].value
+ try:
+ self.entry = Entry(node["/entry"]) # type: Optional[Entry]
+ except KeyError:
+ self.entry = None
+
+
+class RplintFail:
+ def __init__(self, test: "RplintTest",
+ element: Optional[Element] = None,
+ etc: str = "") -> None:
+ self.path = test.path
+ self.element = element # type: Optional[Element]
+ self.line = get_line_number(self.path, element.node.char if element is not None else 0)
+ self.etc = etc
+ self.check = None # type: Optional[Callable[[RplintTest], List[RplintFail]]]
+
+ def __str__(self):
+ if self.etc:
+ return "{}:{} {}: {} ({})".format(os.path.basename(self.path), self.line,
+ self.check.__name__, self.check.__doc__, self.etc)
+ return "{}:{} {}: {}".format(os.path.basename(self.path), self.line, self.check.__name__,
+ self.check.__doc__)
+
+
+class RplintTest:
+ def __init__(self, path: str) -> None:
+ aug = pydnstest.augwrap.AugeasWrapper(confpath=os.path.realpath(path),
+ lens='Deckard',
+ loadpath=os.path.join(os.path.dirname(__file__),
+ 'pydnstest'))
+ self.node = aug.tree
+ self.name = os.path.basename(path)
+ self.path = path
+
+ _, self.config = pydnstest.scenario.parse_file(os.path.realpath(path))
+ self.range_entries = [Entry(node) for node in self.node.match("/scenario/range/entry")]
+ self.steps = [Step(node) for node in self.node.match("/scenario/step")]
+ self.step_entries = [step.entry for step in self.steps if step.entry is not None]
+ self.entries = self.range_entries + self.step_entries
+
+ self.ranges = [pydnstest.scenario.Range(n) for n in self.node.match("/scenario/range")]
+
+ self.fails = None # type: Optional[List[RplintFail]]
+ self.checks = [
+ entry_more_than_one_rcode,
+ entry_no_qname_qtype_copy_query,
+ # Commented out for now until we implement selective turning off of checks
+ # entry_ns_in_authority,
+ range_overlapping_ips,
+ range_shadowing_match_rules,
+ step_check_answer_no_match,
+ step_query_match,
+ step_query_sections,
+ step_query_qr,
+ step_section_unchecked,
+ step_unchecked_match,
+ step_unchecked_rcode,
+ scenario_ad_or_rrsig_no_ta,
+ scenario_timestamp,
+ config_trust_anchor_trailing_period_missing,
+ step_duplicate_id,
+ ]
+
+ def run_checks(self) -> bool:
+ """returns True iff all tests passed"""
+ self.fails = []
+ for check in self.checks:
+ fails = check(self)
+ for fail in fails:
+ fail.check = check
+ self.fails += fails
+
+ if self.fails == []:
+ return True
+ return False
+
+ def print_fails(self) -> None:
+ if self.fails is None:
+ raise RuntimeError("Maybe you should run some test first…")
+ for fail in self.fails:
+ print(fail)
+
+
+def config_trust_anchor_trailing_period_missing(test: RplintTest) -> List[RplintFail]:
+ """Trust-anchor option in configuration contains domain without trailing period"""
+ for conf in test.config:
+ if conf[0] == "trust-anchor":
+ if conf[1].split()[0][-1] != ".":
+ return [RplintFail(test, etc=conf[1])]
+ return []
+
+
+def scenario_timestamp(test: RplintTest) -> List[RplintFail]:
+ """RRSSIG record present in test but no val-override-date or val-override-timestamp in config"""
+ rrsigs = []
+ for entry in test.entries:
+ for record in entry.records:
+ if record["/type"].value == "RRSIG":
+ rrsigs.append(RplintFail(test, entry))
+ if rrsigs:
+ for k in test.config:
+ if k[0] == "val-override-date" or k[0] == "val-override-timestamp":
+ return []
+ return rrsigs
+
+
+def entry_no_qname_qtype_copy_query(test: RplintTest) -> List[RplintFail]:
+ """ENTRY without qname and qtype in MATCH and without copy_query in ADJUST"""
+ fails = []
+ for entry in test.range_entries:
+ if "question" not in entry.match and ("qname" not in entry.match or
+ "qtype" not in entry.match):
+ if "copy_query" not in entry.adjust:
+ fails.append(RplintFail(test, entry))
+ return fails
+
+
+def entry_ns_in_authority(test: RplintTest) -> List[RplintFail]:
+ """ENTRY has authority section with NS records, consider using MATCH subdomain"""
+ fails = []
+ for entry in test.range_entries:
+ if entry.authority and "subdomain" not in entry.match:
+ for record in entry.authority:
+ if record["/type"].value == "NS":
+ fails.append(RplintFail(test, entry))
+ return fails
+
+
+def entry_more_than_one_rcode(test: RplintTest) -> List[RplintFail]:
+ """ENTRY has more than one rcode in MATCH"""
+ fails = []
+ for entry in test.entries:
+ if len(RCODES & entry.reply) > 1:
+ fails.append(RplintFail(test, entry))
+ return fails
+
+
+def scenario_ad_or_rrsig_no_ta(test: RplintTest) -> List[RplintFail]:
+ """AD or RRSIG present in test but no trust-anchor present in config"""
+ dnssec = []
+ for entry in test.entries:
+ if "AD" in entry.reply or "AD" in entry.match:
+ dnssec.append(RplintFail(test, entry))
+ else:
+ for record in entry.records:
+ if record["/type"].value == "RRSIG":
+ dnssec.append(RplintFail(test, entry))
+
+ if dnssec:
+ for k in test.config:
+ if k[0] == "trust-anchor":
+ return []
+ return dnssec
+
+
+def step_query_match(test: RplintTest) -> List[RplintFail]:
+ """STEP QUERY has a MATCH rule"""
+ return [RplintFail(test, step) for step in test.steps if step.type == "QUERY" and
+ step.entry and step.entry.match]
+
+
+def step_query_sections(test: RplintTest) -> List[RplintFail]:
+ """STEP QUERY has some records in sections other than QUESTION"""
+ return [RplintFail(test, step) for step in test.steps if step.type == "QUERY" and
+ step.entry and (step.entry.answer or step.entry.authority or step.entry.additional)]
+
+
+def step_query_qr(test: RplintTest) -> List[RplintFail]:
+ """STEP QUERY specified QR=1 flag (i.e. message is an answer)"""
+ return [RplintFail(test, step) for step in test.steps if step.type == "QUERY" and
+ step.entry and step.entry.reply and 'QR' in step.entry.reply]
+
+
+def step_check_answer_no_match(test: RplintTest) -> List[RplintFail]:
+ """ENTRY in STEP CHECK_ANSWER has no MATCH rule"""
+ return [RplintFail(test, step) for step in test.steps if step.type == "CHECK_ANSWER" and
+ step.entry and not step.entry.match]
+
+
+def step_unchecked_rcode(test: RplintTest) -> List[RplintFail]:
+ """ENTRY specifies rcode but STEP MATCH does not check for it."""
+ fails = []
+ for step in test.steps:
+ if step.type == "CHECK_ANSWER" and step.entry and "all" not in step.entry.match:
+ if step.entry.reply & RCODES and "rcode" not in step.entry.match:
+ fails.append(RplintFail(test, step.entry))
+ return fails
+
+
+def step_unchecked_match(test: RplintTest) -> List[RplintFail]:
+ """ENTRY specifies flags but MATCH does not check for them"""
+ fails = []
+ for step in test.steps:
+ if step.type == "CHECK_ANSWER":
+ entry = step.entry
+ if entry and "all" not in entry.match and entry.reply - RCODES and \
+ "flags" not in entry.match:
+ fails.append(RplintFail(test, entry, str(entry.reply - RCODES)))
+ return fails
+
+
+def step_section_unchecked(test: RplintTest) -> List[RplintFail]:
+ """ENTRY has non-empty sections but MATCH does not check for all of them"""
+ fails = []
+ for step in test.steps:
+ if step.type == "CHECK_ANSWER" and step.entry and "all" not in step.entry.match:
+ for section in SECTIONS:
+ if not is_empty(step.node.match("/entry/section/" + section + "/*")):
+ if section not in step.entry.match:
+ fails.append(RplintFail(test, step.entry, section))
+ return fails
+
+
+def range_overlapping_ips(test: RplintTest) -> List[RplintFail]:
+ """RANGE has common IPs with some previous overlapping RANGE"""
+ fails = []
+ for r1, r2 in itertools.combinations(test.ranges, 2):
+ # If the ranges overlap
+ if min(r1.b, r2.b) >= max(r1.a, r2.a):
+ if r1.addresses & r2.addresses:
+ info = "previous range on line %d" % get_line_number(test.path, r1.node.char)
+ fails.append(RplintFail(test, r2, info))
+ return fails
+
+
+def range_shadowing_match_rules(test: RplintTest) -> List[RplintFail]:
+ """ENTRY has no effect since one of previous entries has the same or broader match rules"""
+ fails = []
+ for r in test.ranges:
+ for e1, e2 in itertools.combinations(r.stored, 2):
+ try:
+ e1.match(e2.message)
+ except ValueError:
+ pass
+ else:
+ info = "previous entry on line %d" % get_line_number(test.path, e1.node.char)
+ if e1.match_fields > e2.match_fields:
+ continue
+ if "subdomain" not in e1.match_fields and "subdomain" in e2.match_fields:
+ continue
+ fails.append(RplintFail(test, e2, info))
+ return fails
+
+
+def step_duplicate_id(test: RplintTest) -> List[RplintFail]:
+ """STEP has the same ID as one of previous ones"""
+ fails = []
+ step_numbers = set() # type: Set[int]
+ for step in test.steps:
+ if step.node.value in step_numbers:
+ fails.append(RplintFail(test, step))
+ else:
+ step_numbers.add(step.node.value)
+ return fails
+
+
+# TODO: This will make sense after we fix how we handle defaults in deckard.aug and scenario.py
+# We might just not use defaults altogether as testbound does
+# if "copy_id" not in adjust:
+# entry_error(test, entry, "copy_id should be in ADJUST")
+
+def test_run_rplint(rpl_path: str) -> None:
+ t = RplintTest(rpl_path)
+ passed = t.run_checks()
+ if not passed:
+ raise RplintError(t.fails)
+
+
+def main():
+ try:
+ test_path = sys.argv[1]
+ except IndexError:
+ print("usage: %s <path to rpl file>" % sys.argv[0])
+ sys.exit(2)
+ if not os.path.isfile(test_path):
+ print("rplint.py works on single file only.")
+ print("Use rplint.sh with --scenarios=<directory with rpls> to run on rpls.")
+ sys.exit(2)
+ print("Linting %s" % test_path)
+ t = RplintTest(test_path)
+ passed = t.run_checks()
+ t.print_fails()
+
+ if passed:
+ sys.exit(0)
+ sys.exit(1)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/tests/integration/deckard/rplint.sh b/tests/integration/deckard/rplint.sh
new file mode 100755
index 0000000..ccdc435
--- /dev/null
+++ b/tests/integration/deckard/rplint.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+set -x
+set -o errexit -o nounset
+MAKEDIR="$(dirname "$0")"
+python3 -m pytest -c "${MAKEDIR}/rplint_pytest.ini" ${TESTS:+"--scenarios=${TESTS}"} "$@"
diff --git a/tests/integration/deckard/rplint_pytest.ini b/tests/integration/deckard/rplint_pytest.ini
new file mode 100644
index 0000000..400f4ad
--- /dev/null
+++ b/tests/integration/deckard/rplint_pytest.ini
@@ -0,0 +1,4 @@
+[pytest]
+log_print = False
+python_files=rplint.py
+norecursedirs=*
diff --git a/tests/integration/deckard/run.sh b/tests/integration/deckard/run.sh
new file mode 100755
index 0000000..911fce5
--- /dev/null
+++ b/tests/integration/deckard/run.sh
@@ -0,0 +1,18 @@
+#!/bin/bash
+MAKEDIR="$(dirname "$0")"
+
+# Currently there no tests requiring faking monotonic time in this repository (there are some elsewhere)
+# pytest returns code 5 on "no tests were run" so we just ignore it
+faketime -m "" python3 -m pytest -c "${MAKEDIR}/deckard_pytest.ini" --tb=short -q ${VERBOSE:+"--log-level=DEBUG"} "${MAKEDIR}" ${DECKARDFLAGS:-} ${TESTS:+"--scenarios=${TESTS}"} -m "monotonic" --forked "$@"
+MONO_RES=$(( $? == 5 ? 0 : $? ))
+faketime -m --exclude-monotonic "" python3 -m pytest -c "${MAKEDIR}/deckard_pytest.ini" --tb=short -q ${VERBOSE:+"--log-level=DEBUG"} "${MAKEDIR}" ${DECKARDFLAGS:-} ${TESTS:+"--scenarios=${TESTS}"} -m "not monotonic" --forked "$@"
+NONMONO_RES=$(( $? == 5 ? 0 : $? ))
+
+if [ $NONMONO_RES -ne 0 ]
+then
+ exit $NONMONO_RES
+fi
+if [ $MONO_RES -ne 0 ]
+then
+ exit $MONO_RES
+fi
diff --git a/tests/integration/deckard/sets/knotd/master/example.com.zone b/tests/integration/deckard/sets/knotd/master/example.com.zone
new file mode 100644
index 0000000..ee51895
--- /dev/null
+++ b/tests/integration/deckard/sets/knotd/master/example.com.zone
@@ -0,0 +1,22 @@
+$ORIGIN example.com.
+$TTL 3600
+
+@ SOA dns1.example.com. hostmaster.example.com. (
+ 2010111213 ; serial
+ 6h ; refresh
+ 1h ; retry
+ 1w ; expire
+ 1d ) ; minimum
+
+ NS dns1
+ NS dns2
+ MX 10 mail
+
+dns1 A 192.0.2.1
+ AAAA 2001:DB8::1
+
+dns2 A 192.0.2.2
+ AAAA 2001:DB8::2
+
+mail A 192.0.2.3
+ AAAA 2001:DB8::3
diff --git a/tests/integration/deckard/sets/knotd/master/iter_ns.rpl b/tests/integration/deckard/sets/knotd/master/iter_ns.rpl
new file mode 100644
index 0000000..089dec1
--- /dev/null
+++ b/tests/integration/deckard/sets/knotd/master/iter_ns.rpl
@@ -0,0 +1,28 @@
+ stub-addr: 192.0.2.10
+CONFIG_END
+
+SCENARIO_BEGIN Simple knotd query.
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+example.com IN NS
+ENTRY_END
+
+STEP 2 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD AA NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. 3600 IN NS dns1.example.com.
+example.com. 3600 IN NS dns2.example.com.
+SECTION ADDITIONAL
+dns1.example.com. 3600 IN A 192.0.2.1
+dns1.example.com. 3600 IN AAAA 2001:DB8::1
+dns2.example.com. 3600 IN A 192.0.2.2
+dns2.example.com. 3600 IN AAAA 2001:DB8::2
+ENTRY_END
+
diff --git a/tests/integration/deckard/sets/knotd/slave/iter_ns.rpl b/tests/integration/deckard/sets/knotd/slave/iter_ns.rpl
new file mode 100644
index 0000000..3015d08
--- /dev/null
+++ b/tests/integration/deckard/sets/knotd/slave/iter_ns.rpl
@@ -0,0 +1,78 @@
+ stub-addr: 192.0.2.10
+CONFIG_END
+
+SCENARIO_BEGIN Simple knotd query.
+
+RANGE_BEGIN 0 100
+ADDRESS 192.0.2.10
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RD NOERROR
+SECTION QUESTION
+example.com. IN AXFR
+SECTION ANSWER
+example.com. 3600 IN SOA dns1.example.com. hostmaster.example.com. 2010111213 21600 3600 604800 86400
+example.com. 3600 IN NS dns1.example.com.
+example.com. 3600 IN NS dns2.example.com.
+example.com. 3600 IN MX 10 mail.example.com.
+dns1.example.com. 3600 IN A 192.0.2.1
+dns1.example.com. 3600 IN AAAA 2001:DB8::1
+dns2.example.com. 3600 IN A 192.0.2.2
+dns2.example.com. 3600 IN AAAA 2001:DB8::2
+mail.example.com. 3600 IN A 192.0.2.3
+mail.example.com. 3600 IN AAAA 2001:DB8::3
+example.com. 3600 IN SOA dns1.example.com. hostmaster.example.com. 2010111213 21600 3600 604800 86400
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RD NOERROR
+SECTION QUESTION
+example.com. IN SOA
+SECTION ANSWER
+example.com. 3600 IN SOA dns1.example.com. hostmaster.example.com. 2010111213 21600 3600 604800 86400
+ENTRY_END
+RANGE_END
+
+STEP 10 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+example.com IN SOA
+ENTRY_END
+
+STEP 20 CHECK_ANSWER REPEAT=3 PAUSE=1 NEXT=10
+ENTRY_BEGIN
+MATCH all
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+example.com IN SOA
+SECTION ANSWER
+example.com. 3600 IN SOA dns1.example.com. hostmaster.example.com. 2010111213 21600 3600 604800 86400
+ENTRY_END
+
+STEP 30 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+example.com IN NS
+ENTRY_END
+
+STEP 40 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. 3600 IN NS dns1.example.com.
+example.com. 3600 IN NS dns2.example.com.
+SECTION ADDITIONAL
+dns1.example.com. 3600 IN A 192.0.2.1
+dns1.example.com. 3600 IN AAAA 2001:DB8::1
+dns2.example.com. 3600 IN A 192.0.2.2
+dns2.example.com. 3600 IN AAAA 2001:DB8::2
+ENTRY_END
+
diff --git a/tests/integration/deckard/sets/resolver/LICENSE b/tests/integration/deckard/sets/resolver/LICENSE
new file mode 100644
index 0000000..1859c09
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/LICENSE
@@ -0,0 +1,30 @@
+Copyright (c) 2007, NLnet Labs. All rights reserved.
+
+This software is open source.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+
+Redistributions in binary form must reproduce the above copyright notice,
+this list of conditions and the following disclaimer in the documentation
+and/or other materials provided with the distribution.
+
+Neither the name of the NLNET LABS nor the names of its contributors may
+be used to endorse or promote products derived from this software without
+specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/tests/integration/deckard/sets/resolver/black_data.rpl b/tests/integration/deckard/sets/resolver/black_data.rpl
new file mode 100644
index 0000000..9343f92
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/black_data.rpl
@@ -0,0 +1,302 @@
+do-ip6: no
+
+; config options
+; The island of trust is at example.com
+;server:
+ trust-anchor: "example.com. 3600 IN DS 34385 7 1 32E1CF5B4E0089080FF6DDC4A48CEE63E88101D6 "
+val-override-date: "20181130121750"
+; target-fetch-policy: "0 0 0 0 0"
+; fake-sha1: yes
+
+;stub-zone:
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+query-minimization: off
+CONFIG_END
+
+SCENARIO_BEGIN Test validator with blacklist for data response
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.blabla.com. IN A
+SECTION ANSWER
+ns.blabla.com. IN A 1.2.3.5
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.blabla.com. IN AAAA
+SECTION AUTHORITY
+com. IN SOA com. com. 2009100100 28800 7200 604800 3600
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. IN NS ns.blabla.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+; no ns.blabla.com, try that later
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+example.com. IN NS ns.blabla.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20181230101749 20181130101749 34385 example.com. INVALIDsEFCHHAzHnCKeBg1j9lMvQROaOx8I0mLqMvuLWaxcjpkxNL5W J4GOZbQuAZRQSCPUpZoR6PXazY/2Iiqaa6VsHBKYlUKOMkqOJBkEs19L PCFUlTFZ8Ayv4eN6OR2BzDdHv0o38Cu6OBQul/hyEmpIX2g03aO1cpGT 3s0= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101749 20181130101749 34385 example.com. INVALIDKPMI48wT/JYtif460cxOjvcdpRm+mjHsKQ9GrMPf3lCuWfY9H 1cB5eeo0yxUW7euIOiKgMD9zsKaafoca1VxXgRp4DaBGgEu59AQI8ot1 FRqYwKUme8v723ZcTpaW4g2e3x2MdVs5F8HtNAII+u+MbPAhNBCzy7rk GbM= ;{id = 2854}
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.com. IN A
+SECTION ANSWER
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101749 20181130101749 34385 example.com. INVALIDKPMI48wT/JYtif460cxOjvcdpRm+mjHsKQ9GrMPf3lCuWfY9H 1cB5eeo0yxUW7euIOiKgMD9zsKaafoca1VxXgRp4DaBGgEu59AQI8ot1 FRqYwKUme8v723ZcTpaW4g2e3x2MdVs5F8HtNAII+u+MbPAhNBCzy7rk GbM= ;{id = 2854}
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.com. IN AAAA
+SECTION ANSWER
+SECTION ADDITIONAL
+ns.example.com. IN NSEC oof.example.com. NSEC RRSIG A
+ns.example.com. 3600 IN RRSIG NSEC 7 3 3600 20181230101749 20181130101749 34385 example.com. INVALIDBxu5PjpUClx48y03pqOFnKIVYDzCdVWquRlXj3kaIDgHipesg oTs2e7cd9/P6MtSRWumr9FQNs1+L0gcfs/YIzuHBeoBH3LG5zZ4qpbs9 Z1Ay7yrxLIritwayyQnZMd9hlUFYLzNLxpL1cjMl/865r0lA3aVajmcv SYc= ;{id = 2854}
+ENTRY_END
+
+; response to DNSKEY priming query
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN DNSKEY
+SECTION ANSWER
+example.com. 3600 IN DNSKEY 256 3 7 AwEAAcNjFHsWLbEHq/G2EjKS2pq/bGsWy6NtwBW7IcP4stnCF+a3cBpJ MZpR78GnL+YxpQYj0IyasgziAGTI/tgiTyY2qatR+6OaqebJkVbJDFx5 g0Ts1VrUk/4Z/G5tm0RMZxXxWMjjIy3wnET3Bt3dvUSI/tcTs5CUegnM MNrcMbG3 ;{id = 2854 (zsk), size = 1688b}
+; make priming query succeed
+example.com. 3600 IN RRSIG DNSKEY 7 2 3600 20181230101749 20181130101749 34385 example.com. cbYR1BnWMDItEpJqSz9L+D7XC/Zl6wnkhOA3+Z8ikZivBMfAu3OSFLWA Wu1SyiBFU+ooZ8v4/vVWN/IAkqt2CGvXeiWweiifegZEENjeAQCh8Jzw qTBf43yXwPeIpN2DpAoS+UxKbSOYhhSwBahoRefgZl7iEo3lg6TdoaOl y+U= ;{id = 2854}
+;example.com. 3600 IN RRSIG DNSKEY 3 2 3600 20030926134150 20030829134150 2854 example.com. AG21xE8CFQzTq6XtHErg28b9EAmqPsoYCUcFPEAoAjFybM6AY4/bMOo= ;{id = 2854}
+SECTION AUTHORITY
+;example.com. IN NS ns.example.com.
+;example.com. IN NS ns.blabla.com.
+;example.com. 3600 IN RRSIG NS 3 2 3600 20030926134150 20030829134150 2854 example.com. ACiWu7zjBHqgEX3iUoOF7rfpOmIAHj1npKQ+XDIaNlmdkfJxoCwFl04= ;{id = 2854}
+SECTION ADDITIONAL
+;ns.example.com. IN A 1.2.3.4
+;ns.example.com. 3600 IN RRSIG A 3 3 3600 20030926134150 20030829134150 2854 example.com. ACmAsKTf7hqDaYK8CQ7FL1cGYPW+blTCnzZGkExFtEUAGrHeze87o+A= ;{id = 2854}
+ENTRY_END
+
+; response to query of interest
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+www.example.com. 3600 IN RRSIG A 7 3 3600 20181230101749 20181130101749 34385 example.com. INVALIDiQusXsW6tz5yQdklAv+PvoEHP1cC8IkJqo9YnMcSdoFHbZALs XFlbNRl2uwPnthKOIPZf89/pXNX3o19aq4LzfPOEiOkylboTiKmgLVyi WhqYKkJtK1B9SVn/dZN4VnmSNtrcmHi5EERl/aTEM7nfIT3jG4a/ORz6 IHY= ;{id = 2854}
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. IN NS ns.blabla.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20181230101749 20181130101749 34385 example.com. INVALIDsEFCHHAzHnCKeBg1j9lMvQROaOx8I0mLqMvuLWaxcjpkxNL5W J4GOZbQuAZRQSCPUpZoR6PXazY/2Iiqaa6VsHBKYlUKOMkqOJBkEs19L PCFUlTFZ8Ayv4eN6OR2BzDdHv0o38Cu6OBQul/hyEmpIX2g03aO1cpGT 3s0= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101749 20181130101749 34385 example.com. INVALIDKPMI48wT/JYtif460cxOjvcdpRm+mjHsKQ9GrMPf3lCuWfY9H 1cB5eeo0yxUW7euIOiKgMD9zsKaafoca1VxXgRp4DaBGgEu59AQI8ot1 FRqYwKUme8v723ZcTpaW4g2e3x2MdVs5F8HtNAII+u+MbPAhNBCzy7rk GbM= ;{id = 2854}
+ENTRY_END
+RANGE_END
+
+; ns.blabla.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.5
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+example.com. IN NS ns.blabla.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20181230101749 20181130101749 34385 example.com. hMeEUjDsEFCHHAzHnCKeBg1j9lMvQROaOx8I0mLqMvuLWaxcjpkxNL5W J4GOZbQuAZRQSCPUpZoR6PXazY/2Iiqaa6VsHBKYlUKOMkqOJBkEs19L PCFUlTFZ8Ayv4eN6OR2BzDdHv0o38Cu6OBQul/hyEmpIX2g03aO1cpGT 3s0= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101749 20181130101749 34385 example.com. GoDRZGoKPMI48wT/JYtif460cxOjvcdpRm+mjHsKQ9GrMPf3lCuWfY9H 1cB5eeo0yxUW7euIOiKgMD9zsKaafoca1VxXgRp4DaBGgEu59AQI8ot1 FRqYwKUme8v723ZcTpaW4g2e3x2MdVs5F8HtNAII+u+MbPAhNBCzy7rk GbM= ;{id = 2854}
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.com. IN A
+SECTION ANSWER
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101749 20181130101749 34385 example.com. GoDRZGoKPMI48wT/JYtif460cxOjvcdpRm+mjHsKQ9GrMPf3lCuWfY9H 1cB5eeo0yxUW7euIOiKgMD9zsKaafoca1VxXgRp4DaBGgEu59AQI8ot1 FRqYwKUme8v723ZcTpaW4g2e3x2MdVs5F8HtNAII+u+MbPAhNBCzy7rk GbM= ;{id = 2854}
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.com. IN AAAA
+SECTION ANSWER
+SECTION ADDITIONAL
+ns.example.com. IN NSEC oof.example.com. NSEC RRSIG A
+ns.example.com. 3600 IN RRSIG NSEC 7 3 3600 20181230101749 20181130101749 34385 example.com. F5OQnNGBxu5PjpUClx48y03pqOFnKIVYDzCdVWquRlXj3kaIDgHipesg oTs2e7cd9/P6MtSRWumr9FQNs1+L0gcfs/YIzuHBeoBH3LG5zZ4qpbs9 Z1Ay7yrxLIritwayyQnZMd9hlUFYLzNLxpL1cjMl/865r0lA3aVajmcv SYc= ;{id = 2854}
+ENTRY_END
+
+; response to DNSKEY priming query
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN DNSKEY
+SECTION ANSWER
+example.com. 3600 IN DNSKEY 256 3 7 AwEAAcNjFHsWLbEHq/G2EjKS2pq/bGsWy6NtwBW7IcP4stnCF+a3cBpJ MZpR78GnL+YxpQYj0IyasgziAGTI/tgiTyY2qatR+6OaqebJkVbJDFx5 g0Ts1VrUk/4Z/G5tm0RMZxXxWMjjIy3wnET3Bt3dvUSI/tcTs5CUegnM MNrcMbG3 ;{id = 2854 (zsk), size = 1688b}
+example.com. 3600 IN RRSIG DNSKEY 7 2 3600 20181230101749 20181130101749 34385 example.com. cbYR1BnWMDItEpJqSz9L+D7XC/Zl6wnkhOA3+Z8ikZivBMfAu3OSFLWA Wu1SyiBFU+ooZ8v4/vVWN/IAkqt2CGvXeiWweiifegZEENjeAQCh8Jzw qTBf43yXwPeIpN2DpAoS+UxKbSOYhhSwBahoRefgZl7iEo3lg6TdoaOl y+U= ;{id = 2854}
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. IN NS ns.blabla.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20181230101749 20181130101749 34385 example.com. hMeEUjDsEFCHHAzHnCKeBg1j9lMvQROaOx8I0mLqMvuLWaxcjpkxNL5W J4GOZbQuAZRQSCPUpZoR6PXazY/2Iiqaa6VsHBKYlUKOMkqOJBkEs19L PCFUlTFZ8Ayv4eN6OR2BzDdHv0o38Cu6OBQul/hyEmpIX2g03aO1cpGT 3s0= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101749 20181130101749 34385 example.com. GoDRZGoKPMI48wT/JYtif460cxOjvcdpRm+mjHsKQ9GrMPf3lCuWfY9H 1cB5eeo0yxUW7euIOiKgMD9zsKaafoca1VxXgRp4DaBGgEu59AQI8ot1 FRqYwKUme8v723ZcTpaW4g2e3x2MdVs5F8HtNAII+u+MbPAhNBCzy7rk GbM= ;{id = 2854}
+ENTRY_END
+
+; response to query of interest
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+www.example.com. 3600 IN RRSIG A 7 3 3600 20181230101749 20181130101749 34385 example.com. aFxyCGziQusXsW6tz5yQdklAv+PvoEHP1cC8IkJqo9YnMcSdoFHbZALs XFlbNRl2uwPnthKOIPZf89/pXNX3o19aq4LzfPOEiOkylboTiKmgLVyi WhqYKkJtK1B9SVn/dZN4VnmSNtrcmHi5EERl/aTEM7nfIT3jG4a/ORz6 IHY= ;{id = 2854}
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. IN NS ns.blabla.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20181230101749 20181130101749 34385 example.com. hMeEUjDsEFCHHAzHnCKeBg1j9lMvQROaOx8I0mLqMvuLWaxcjpkxNL5W J4GOZbQuAZRQSCPUpZoR6PXazY/2Iiqaa6VsHBKYlUKOMkqOJBkEs19L PCFUlTFZ8Ayv4eN6OR2BzDdHv0o38Cu6OBQul/hyEmpIX2g03aO1cpGT 3s0= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101749 20181130101749 34385 example.com. GoDRZGoKPMI48wT/JYtif460cxOjvcdpRm+mjHsKQ9GrMPf3lCuWfY9H 1cB5eeo0yxUW7euIOiKgMD9zsKaafoca1VxXgRp4DaBGgEu59AQI8ot1 FRqYwKUme8v723ZcTpaW4g2e3x2MdVs5F8HtNAII+u+MbPAhNBCzy7rk GbM= ;{id = 2854}
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH opcode rcode flags question answer
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+www.example.com. 3600 IN RRSIG A 7 3 3600 20181230101749 20181130101749 34385 example.com. aFxyCGziQusXsW6tz5yQdklAv+PvoEHP1cC8IkJqo9YnMcSdoFHbZALs XFlbNRl2uwPnthKOIPZf89/pXNX3o19aq4LzfPOEiOkylboTiKmgLVyi WhqYKkJtK1B9SVn/dZN4VnmSNtrcmHi5EERl/aTEM7nfIT3jG4a/ORz6 IHY= ;{id = 2854}
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+; remove pending ns.blabla.com AAAA msg
+STEP 30 QUERY
+ENTRY_BEGIN
+REPLY RD DO CD
+SECTION QUESTION
+ns.blabla.com. IN AAAA
+ENTRY_END
+
+; recursion happens here.
+STEP 40 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD CD RA DO NOERROR
+SECTION QUESTION
+ns.blabla.com. IN AAAA
+SECTION ANSWER
+SECTION AUTHORITY
+com. IN SOA com. com. 2009100100 28800 7200 604800 3600
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/black_dnskey.rpl b/tests/integration/deckard/sets/resolver/black_dnskey.rpl
new file mode 100644
index 0000000..bfa0d3d
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/black_dnskey.rpl
@@ -0,0 +1,510 @@
+do-ip6: no
+
+; config options
+; The island of trust is at example.com
+;server:
+ trust-anchor: "example.com. 3600 IN DS 62867 7 1 FD75C8B653BF8FECB755D16AC0DF400B33043881 "
+val-override-date: "20181130121751"
+; target-fetch-policy: "0 0 0 0 0"
+; fake-sha1: yes
+
+;stub-zone:
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+query-minimization: off
+CONFIG_END
+
+SCENARIO_BEGIN Test validator with blacklist for DNSKEY response
+; DNSKEY not for prime but further down the chain of trust
+; data response also needs a blacklist action.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.blabla.com. IN A
+SECTION ANSWER
+ns.blabla.com. IN A 1.2.3.5
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.blabla.com. IN AAAA
+SECTION AUTHORITY
+com. IN SOA com. com. 2009100100 28800 7200 604800 3600
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.foo.com. IN A
+SECTION ANSWER
+ns.foo.com. IN A 1.2.4.7
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.foo.com. IN AAAA
+SECTION AUTHORITY
+com. IN SOA com. com. 2009100100 28800 7200 604800 3600
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. IN NS ns.blabla.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+; no ns.blabla.com, try that later
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+example.com. IN NS ns.blabla.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20181230101751 20181130101751 62867 example.com. INVALIDl98ot8mRBklpnoFYwYmqmoz/iWC/tS8q0bkurxZivPdmvt63C DjHpH8vv36fnO0s89btfC3eIBnDX5miuaiLbxqINmxpxDYgy3/TN+DWT VfjiWAPfaFkfwedx8oHHWwO0O7DEjrnbaqTI+5BJW7LOVYSMLNx7nFjg 490= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101751 20181130101751 62867 example.com. INVALID17he6wGm7+lLbzVsblvW+zsWx5LctUfEeHOkaJ6YqvrZ2yuKl ePHbVN5yO5czQEHa8arTAhh6lSZNFAz1QijkCX/HW8VHzQgUnCjncAvE nf6ab3vVx25Ggr5E3TqJnyH62AP0qZbTZfc3dBYT1F9tQC5LUebW8Xes EBU= ;{id = 2854}
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.com. IN A
+SECTION ANSWER
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101751 20181130101751 62867 example.com. INVALID17he6wGm7+lLbzVsblvW+zsWx5LctUfEeHOkaJ6YqvrZ2yuKl ePHbVN5yO5czQEHa8arTAhh6lSZNFAz1QijkCX/HW8VHzQgUnCjncAvE nf6ab3vVx25Ggr5E3TqJnyH62AP0qZbTZfc3dBYT1F9tQC5LUebW8Xes EBU= ;{id = 2854}
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.com. IN AAAA
+SECTION ANSWER
+SECTION ADDITIONAL
+ns.example.com. IN NSEC oof.example.com. NSEC RRSIG A
+ns.example.com. 3600 IN RRSIG NSEC 7 3 3600 20181230101751 20181130101751 62867 example.com. INVALIDJDQlK7ptDtIq0/V+QBXNIv0F5NTYnJoxDRmUdE3dMqsTxS6jC RIV6U2T609yLL+6elv4WtkLyfSVLlN/DO1TAPzPeWstx5VHvPS3beBn7 0FmcTWvj7vEJlmVfQEn8KeEDsOrThvBCgGjHJ/ottlz0VCL4KHJQfqXx ewA= ;{id = 2854}
+ENTRY_END
+
+; response to DNSKEY priming query
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN DNSKEY
+SECTION ANSWER
+example.com. 3600 IN DNSKEY 256 3 7 AwEAAdMz5YCS6AnlK5Id93IA0wp8aFVHsecJNWYjPNOIdN1G0FufP8z7 yVfdWef/Lmj7VzrpHq9a+HlJ1396SCr6FYbm4Wg0nx4KxF4/dXKpIRYw HWdQiwxAu/bqixy1Yklz1HaljKenSQxEsy0dbRv+GQM65whuNui0Uk/D P1bgZsW9 ;{id = 2854 (zsk), size = 1688b}
+; make priming query succeed
+example.com. 3600 IN RRSIG DNSKEY 7 2 3600 20181230101751 20181130101751 62867 example.com. wSoXZPx8cm7DDDLM8cN7Guzh3kSSCkVgmhBSNzs9kPT/fOfz8nUyeBaf saOeU19aPuSKWFxLKiUCxy1Nwtcyax6HIeYgDVBsZ0iNxV5SD6znoJlY f/vLg/43c3e/CLSSCuWM/4DA9fZNyBrthX7BgcZdnHY5D9TVsTAskp4b 97w= ;{id = 2854}
+;example.com. 3600 IN RRSIG DNSKEY 3 2 3600 20030926134150 20030829134150 2854 example.com. AG21xE8CFQzTq6XtHErg28b9EAmqPsoYCUcFPEAoAjFybM6AY4/bMOo= ;{id = 2854}
+SECTION AUTHORITY
+;example.com. IN NS ns.example.com.
+;example.com. IN NS ns.blabla.com.
+;example.com. 3600 IN RRSIG NS 3 2 3600 20030926134150 20030829134150 2854 example.com. ACiWu7zjBHqgEX3iUoOF7rfpOmIAHj1npKQ+XDIaNlmdkfJxoCwFl04= ;{id = 2854}
+SECTION ADDITIONAL
+;ns.example.com. IN A 1.2.3.4
+;ns.example.com. 3600 IN RRSIG A 3 3 3600 20030926134150 20030829134150 2854 example.com. ACmAsKTf7hqDaYK8CQ7FL1cGYPW+blTCnzZGkExFtEUAGrHeze87o+A= ;{id = 2854}
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+www.example.com. 3600 IN RRSIG A 7 3 3600 20181230101751 20181130101751 62867 example.com. INVALID2pVPZe/Or/iLKGuxmkYlSzh2T+zq2SUMbgDKBgAXQGeZaYHIm ypvZzbmxGtXJfFK0vT1VexagQasf8WSGbZD5O3B8oSDuQ+0Dos9JYRBp q16dhOU+rGgBaBDPfF1WNP2V9kmMRkYOP+3MhxRyynywzIrlu+uMb5sw EOI= ;{id = 2854}
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. IN NS ns.blabla.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20181230101751 20181130101751 62867 example.com. INVALIDl98ot8mRBklpnoFYwYmqmoz/iWC/tS8q0bkurxZivPdmvt63C DjHpH8vv36fnO0s89btfC3eIBnDX5miuaiLbxqINmxpxDYgy3/TN+DWT VfjiWAPfaFkfwedx8oHHWwO0O7DEjrnbaqTI+5BJW7LOVYSMLNx7nFjg 490= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101751 20181130101751 62867 example.com. INVALID17he6wGm7+lLbzVsblvW+zsWx5LctUfEeHOkaJ6YqvrZ2yuKl ePHbVN5yO5czQEHa8arTAhh6lSZNFAz1QijkCX/HW8VHzQgUnCjncAvE nf6ab3vVx25Ggr5E3TqJnyH62AP0qZbTZfc3dBYT1F9tQC5LUebW8Xes EBU= ;{id = 2854}
+ENTRY_END
+
+; DS request
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+sub.example.com. IN DS
+SECTION ANSWER
+sub.example.com. 3600 IN DS 12981 5 1 626AD6C14D2BE93B5EDF1C8A2FFCBC5447666CF3
+sub.example.com. 3600 IN RRSIG DS 7 3 3600 20181230101751 20181130101751 62867 example.com. bwKyS7x0t/By9YxMmwnJSIkMZEYQu7MPW4MmIZqB6/2amawL0r16mBKe fhuamuH2CdYvzoSdYqjk4+8xZ9YyhzLI4Fmd4nE2XznoCDc+/GG4QH4R eH3e+GEXtyRnmZgANk845pYYJ2n4TcE3F3OwG7AIP6ol8I8k17g9RfGT w2I= ;{id = 2854}
+;sub.example.com. 3600 IN RRSIG DS 3 3 3600 20030926134150 20030829134150 2854 example.com. AAT/7XwtMjHiT1GFHfV6Wvv4n+oOkqxllNdf9bLnpTHw/8h586yBgwg= ;{id = 2854}
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR AA NOERROR
+SECTION QUESTION
+sub.example.com. IN NS
+SECTION AUTHORITY
+sub.example.com. IN NS ns.sub.example.com.
+sub.example.com. IN NS ns.foo.com.
+sub.example.com. 3600 IN DS 12981 5 1 626AD6C14D2BE93B5EDF1C8A2FFCBC5447666CF3
+sub.example.com. 3600 IN RRSIG DS 7 3 3600 20181230101751 20181130101751 62867 example.com. bwKyS7x0t/By9YxMmwnJSIkMZEYQu7MPW4MmIZqB6/2amawL0r16mBKe fhuamuH2CdYvzoSdYqjk4+8xZ9YyhzLI4Fmd4nE2XznoCDc+/GG4QH4R eH3e+GEXtyRnmZgANk845pYYJ2n4TcE3F3OwG7AIP6ol8I8k17g9RfGT w2I= ;{id = 2854}
+;sub.example.com. 3600 IN RRSIG DS 3 3 3600 20030926134150 20030829134150 2854 example.com. AAT/7XwtMjHiT1GFHfV6Wvv4n+oOkqxllNdf9bLnpTHw/8h586yBgwg= ;{id = 2854}
+SECTION ADDITIONAL
+ns.sub.example.com. IN A 1.2.4.6
+ENTRY_END
+
+RANGE_END
+
+; ns.blabla.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.5
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+example.com. IN NS ns.blabla.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20181230101751 20181130101751 62867 example.com. l15h4pHl98ot8mRBklpnoFYwYmqmoz/iWC/tS8q0bkurxZivPdmvt63C DjHpH8vv36fnO0s89btfC3eIBnDX5miuaiLbxqINmxpxDYgy3/TN+DWT VfjiWAPfaFkfwedx8oHHWwO0O7DEjrnbaqTI+5BJW7LOVYSMLNx7nFjg 490= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101751 20181130101751 62867 example.com. nJSkzyA17he6wGm7+lLbzVsblvW+zsWx5LctUfEeHOkaJ6YqvrZ2yuKl ePHbVN5yO5czQEHa8arTAhh6lSZNFAz1QijkCX/HW8VHzQgUnCjncAvE nf6ab3vVx25Ggr5E3TqJnyH62AP0qZbTZfc3dBYT1F9tQC5LUebW8Xes EBU= ;{id = 2854}
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.com. IN A
+SECTION ANSWER
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101751 20181130101751 62867 example.com. nJSkzyA17he6wGm7+lLbzVsblvW+zsWx5LctUfEeHOkaJ6YqvrZ2yuKl ePHbVN5yO5czQEHa8arTAhh6lSZNFAz1QijkCX/HW8VHzQgUnCjncAvE nf6ab3vVx25Ggr5E3TqJnyH62AP0qZbTZfc3dBYT1F9tQC5LUebW8Xes EBU= ;{id = 2854}
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.com. IN AAAA
+SECTION ANSWER
+SECTION ADDITIONAL
+ns.example.com. IN NSEC oof.example.com. NSEC RRSIG A
+ns.example.com. 3600 IN RRSIG NSEC 7 3 3600 20181230101751 20181130101751 62867 example.com. RHlNZwaJDQlK7ptDtIq0/V+QBXNIv0F5NTYnJoxDRmUdE3dMqsTxS6jC RIV6U2T609yLL+6elv4WtkLyfSVLlN/DO1TAPzPeWstx5VHvPS3beBn7 0FmcTWvj7vEJlmVfQEn8KeEDsOrThvBCgGjHJ/ottlz0VCL4KHJQfqXx ewA= ;{id = 2854}
+ENTRY_END
+
+; response to DNSKEY priming query
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN DNSKEY
+SECTION ANSWER
+example.com. 3600 IN DNSKEY 256 3 7 AwEAAdMz5YCS6AnlK5Id93IA0wp8aFVHsecJNWYjPNOIdN1G0FufP8z7 yVfdWef/Lmj7VzrpHq9a+HlJ1396SCr6FYbm4Wg0nx4KxF4/dXKpIRYw HWdQiwxAu/bqixy1Yklz1HaljKenSQxEsy0dbRv+GQM65whuNui0Uk/D P1bgZsW9 ;{id = 2854 (zsk), size = 1688b}
+example.com. 3600 IN RRSIG DNSKEY 7 2 3600 20181230101751 20181130101751 62867 example.com. wSoXZPx8cm7DDDLM8cN7Guzh3kSSCkVgmhBSNzs9kPT/fOfz8nUyeBaf saOeU19aPuSKWFxLKiUCxy1Nwtcyax6HIeYgDVBsZ0iNxV5SD6znoJlY f/vLg/43c3e/CLSSCuWM/4DA9fZNyBrthX7BgcZdnHY5D9TVsTAskp4b 97w= ;{id = 2854}
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. IN NS ns.blabla.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20181230101751 20181130101751 62867 example.com. l15h4pHl98ot8mRBklpnoFYwYmqmoz/iWC/tS8q0bkurxZivPdmvt63C DjHpH8vv36fnO0s89btfC3eIBnDX5miuaiLbxqINmxpxDYgy3/TN+DWT VfjiWAPfaFkfwedx8oHHWwO0O7DEjrnbaqTI+5BJW7LOVYSMLNx7nFjg 490= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101751 20181130101751 62867 example.com. nJSkzyA17he6wGm7+lLbzVsblvW+zsWx5LctUfEeHOkaJ6YqvrZ2yuKl ePHbVN5yO5czQEHa8arTAhh6lSZNFAz1QijkCX/HW8VHzQgUnCjncAvE nf6ab3vVx25Ggr5E3TqJnyH62AP0qZbTZfc3dBYT1F9tQC5LUebW8Xes EBU= ;{id = 2854}
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+www.example.com. 3600 IN RRSIG A 7 3 3600 20181230101751 20181130101751 62867 example.com. byNMYNt2pVPZe/Or/iLKGuxmkYlSzh2T+zq2SUMbgDKBgAXQGeZaYHIm ypvZzbmxGtXJfFK0vT1VexagQasf8WSGbZD5O3B8oSDuQ+0Dos9JYRBp q16dhOU+rGgBaBDPfF1WNP2V9kmMRkYOP+3MhxRyynywzIrlu+uMb5sw EOI= ;{id = 2854}
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. IN NS ns.blabla.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20181230101751 20181130101751 62867 example.com. l15h4pHl98ot8mRBklpnoFYwYmqmoz/iWC/tS8q0bkurxZivPdmvt63C DjHpH8vv36fnO0s89btfC3eIBnDX5miuaiLbxqINmxpxDYgy3/TN+DWT VfjiWAPfaFkfwedx8oHHWwO0O7DEjrnbaqTI+5BJW7LOVYSMLNx7nFjg 490= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101751 20181130101751 62867 example.com. nJSkzyA17he6wGm7+lLbzVsblvW+zsWx5LctUfEeHOkaJ6YqvrZ2yuKl ePHbVN5yO5czQEHa8arTAhh6lSZNFAz1QijkCX/HW8VHzQgUnCjncAvE nf6ab3vVx25Ggr5E3TqJnyH62AP0qZbTZfc3dBYT1F9tQC5LUebW8Xes EBU= ;{id = 2854}
+ENTRY_END
+
+; DS request
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+sub.example.com. IN DS
+SECTION ANSWER
+sub.example.com. 3600 IN DS 12981 5 1 626AD6C14D2BE93B5EDF1C8A2FFCBC5447666CF3
+sub.example.com. 3600 IN RRSIG DS 7 3 3600 20181230101751 20181130101751 62867 example.com. bwKyS7x0t/By9YxMmwnJSIkMZEYQu7MPW4MmIZqB6/2amawL0r16mBKe fhuamuH2CdYvzoSdYqjk4+8xZ9YyhzLI4Fmd4nE2XznoCDc+/GG4QH4R eH3e+GEXtyRnmZgANk845pYYJ2n4TcE3F3OwG7AIP6ol8I8k17g9RfGT w2I= ;{id = 2854}
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR AA NOERROR
+SECTION QUESTION
+sub.example.com. IN NS
+SECTION AUTHORITY
+sub.example.com. IN NS ns.sub.example.com.
+sub.example.com. IN NS ns.foo.com.
+sub.example.com. 3600 IN DS 12981 5 1 626AD6C14D2BE93B5EDF1C8A2FFCBC5447666CF3
+sub.example.com. 3600 IN RRSIG DS 7 3 3600 20181230101751 20181130101751 62867 example.com. bwKyS7x0t/By9YxMmwnJSIkMZEYQu7MPW4MmIZqB6/2amawL0r16mBKe fhuamuH2CdYvzoSdYqjk4+8xZ9YyhzLI4Fmd4nE2XznoCDc+/GG4QH4R eH3e+GEXtyRnmZgANk845pYYJ2n4TcE3F3OwG7AIP6ol8I8k17g9RfGT w2I= ;{id = 2854}
+SECTION ADDITIONAL
+ns.sub.example.com. IN A 1.2.4.6
+ENTRY_END
+
+RANGE_END
+
+; ns.sub.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.4.6
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+sub.example.com. IN DNSKEY
+SECTION ANSWER
+sub.example.com. 3600 IN DNSKEY 256 3 5 AwEAAbrzxhWzLVhOSmsCj1rysaYFaF6NLfPmXdhjppCOzDb2LxQUZ5tE yiTKViI/ZUSMDKKLk1IdDGpIniYzx3vrUQ7KzA+p8p/XR3qvD8T496Us mdAB/8Dflk5mK36kRCBp5GEKI+yz1R5Z5VolpZFnIuRLB/hXJlt7EzDz zcFMIgzT ;{id = 30899 (zsk), size = 512b}
+sub.example.com. 3600 IN RRSIG DNSKEY 5 3 3600 20181230101751 20181130101751 12981 sub.example.com. INVALIDrmQur/BRNwZ5dVdqehHNP4Egt16bO/qdYL7UE/GRfwWWImAKQ Z924Lmk7qrZfF8+a16+R6YgVQJoUX+qqVNSdjTyC4NT0IKx82qdamZSZ dTVktU5cCeE5A1WhXQHq4zcwO+EQaCyOEUf+X+wMtYkGQBjpcWP5rui8 KPM= ;{id = 30899}
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+sub.example.com. IN NS
+SECTION ANSWER
+sub.example.com. IN NS ns.sub.example.com.
+sub.example.com. IN NS ns.foo.com.
+sub.example.com. 3600 IN RRSIG NS 5 3 3600 20181230101751 20181130101751 12981 sub.example.com. INVALIDUqmkkbSsCNDKsisAfl4+R/0Ozg8kLqlWjwkd7QTcfu4WsOZUk johg9ESaatO13/isxiqa3W2dD6W+68LnxSflkppanaMBZYRfMmiFf3Fr u3tf4cNFk7KoGt7WL4svoeW8qnkxyKZk16ro6whu6RGO7tpv+mXrIvLZ /1A= ;{id = 30899}
+SECTION ADDITIONAL
+ns.sub.example.com. IN A 1.2.4.6
+ns.sub.example.com. 3600 IN RRSIG A 5 4 3600 20181230101751 20181130101751 12981 sub.example.com. INVALIDDipjtxEH1NcbqQ9whB09kjjWlrYPNoRx9M1Es7x67D5JLvLdP MaCo//BnF9COEXFwlAq/Gg+MJ2I7ge7b+kJMYFxoSUSg+6zD8pP5RuOv 6wxdc+OtTuB/zY3qNpwQZPGhJC5ruBRFQuPsX8JXJXwHAadZcQ3KX+Vq xQc= ;{id = 30899}
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns.sub.example.com. IN A
+SECTION ANSWER
+ns.sub.example.com. IN A 1.2.4.6
+ns.sub.example.com. 3600 IN RRSIG A 5 4 3600 20181230101751 20181130101751 12981 sub.example.com. INVALIDDipjtxEH1NcbqQ9whB09kjjWlrYPNoRx9M1Es7x67D5JLvLdP MaCo//BnF9COEXFwlAq/Gg+MJ2I7ge7b+kJMYFxoSUSg+6zD8pP5RuOv 6wxdc+OtTuB/zY3qNpwQZPGhJC5ruBRFQuPsX8JXJXwHAadZcQ3KX+Vq xQc= ;{id = 30899}
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns.sub.example.com. IN AAAA
+SECTION AUTHORITY
+ns.sub.example.com. IN NSEC nt.sub.example.com. NSEC RRSIG A
+ns.sub.example.com. 3600 IN RRSIG NSEC 5 4 5 20181230101751 20181130101751 12981 sub.example.com. INVALIDRk0CTvXrjV0AGQ0GM3ygY020B+A4GrVPsZa6DwqnTCff13R1M SQ8u+yl71YPh+5HFMbIOFdYoPMSPvU3FyOCwPK/4Mo0z86QT5nkjx6X3 T4YLX+LRfLJ+sqJtRIyA7Mjg7xIratVCa+RYrxbYbXHwSkBScQDKdew9 g5E= ;{id = 30899}
+sub.example.com. IN SOA sub.example.com. hostmaster.sub.example.com. 1 2 3 4 5
+sub.example.com. 3600 IN RRSIG SOA 5 3 3600 20181230101751 20181130101751 12981 sub.example.com. INVALIDjhKCum7m/PdpryrXY4ASNLfnZS38i+CnJXopIY8CWfaRDeU/k fpj9cBRzGafJAbef4ePxLqTNgWsmzQPZaIFsVIu/vjTMj5JVYmHYcvk/ SyAcQzGV4iqes/8T9z7iQTpDbWH3bD8vZdccdTRAfWi1Tl6t4+phCYVj lAI= ;{id = 30899}
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www.sub.example.com. IN A
+SECTION ANSWER
+www.sub.example.com. IN A 10.20.30.40
+www.sub.example.com. 3600 IN RRSIG A 5 4 3600 20181230101751 20181130101751 12981 sub.example.com. INVALIDaXA+cM1tLnfVLmVuZPugapKRSUYG/DrYzm0UQ08nuvptESpcz 6ZAP5DP9oPuoHiwPd+rvdwOtX3dWj1BfPDQ0RfAlkHMPXR2Sez3p5kI7 XNuo/FDMs337F52eij9iWSDTzgzeeBusqJPfJMRwao1THKAmDbFsvTne qpQ= ;{id = 30899}
+ENTRY_END
+
+RANGE_END
+
+; ns.foo.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.4.7
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+sub.example.com. IN DNSKEY
+SECTION ANSWER
+sub.example.com. 3600 IN DNSKEY 256 3 5 AwEAAbrzxhWzLVhOSmsCj1rysaYFaF6NLfPmXdhjppCOzDb2LxQUZ5tE yiTKViI/ZUSMDKKLk1IdDGpIniYzx3vrUQ7KzA+p8p/XR3qvD8T496Us mdAB/8Dflk5mK36kRCBp5GEKI+yz1R5Z5VolpZFnIuRLB/hXJlt7EzDz zcFMIgzT ;{id = 30899 (zsk), size = 512b}
+sub.example.com. 3600 IN RRSIG DNSKEY 5 3 3600 20181230101751 20181130101751 12981 sub.example.com. piLZqA+rmQur/BRNwZ5dVdqehHNP4Egt16bO/qdYL7UE/GRfwWWImAKQ Z924Lmk7qrZfF8+a16+R6YgVQJoUX+qqVNSdjTyC4NT0IKx82qdamZSZ dTVktU5cCeE5A1WhXQHq4zcwO+EQaCyOEUf+X+wMtYkGQBjpcWP5rui8 KPM= ;{id = 30899}
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+sub.example.com. IN NS
+SECTION ANSWER
+sub.example.com. IN NS ns.sub.example.com.
+sub.example.com. IN NS ns.foo.com.
+sub.example.com. 3600 IN RRSIG NS 5 3 3600 20181230101751 20181130101751 12981 sub.example.com. YVs4zyrUqmkkbSsCNDKsisAfl4+R/0Ozg8kLqlWjwkd7QTcfu4WsOZUk johg9ESaatO13/isxiqa3W2dD6W+68LnxSflkppanaMBZYRfMmiFf3Fr u3tf4cNFk7KoGt7WL4svoeW8qnkxyKZk16ro6whu6RGO7tpv+mXrIvLZ /1A= ;{id = 30899}
+SECTION ADDITIONAL
+ns.sub.example.com. IN A 1.2.4.6
+ns.sub.example.com. 3600 IN RRSIG A 5 4 3600 20181230101751 20181130101751 12981 sub.example.com. nhOqrjoDipjtxEH1NcbqQ9whB09kjjWlrYPNoRx9M1Es7x67D5JLvLdP MaCo//BnF9COEXFwlAq/Gg+MJ2I7ge7b+kJMYFxoSUSg+6zD8pP5RuOv 6wxdc+OtTuB/zY3qNpwQZPGhJC5ruBRFQuPsX8JXJXwHAadZcQ3KX+Vq xQc= ;{id = 30899}
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns.sub.example.com. IN A
+SECTION ANSWER
+ns.sub.example.com. IN A 1.2.4.6
+ns.sub.example.com. 3600 IN RRSIG A 5 4 3600 20181230101751 20181130101751 12981 sub.example.com. nhOqrjoDipjtxEH1NcbqQ9whB09kjjWlrYPNoRx9M1Es7x67D5JLvLdP MaCo//BnF9COEXFwlAq/Gg+MJ2I7ge7b+kJMYFxoSUSg+6zD8pP5RuOv 6wxdc+OtTuB/zY3qNpwQZPGhJC5ruBRFQuPsX8JXJXwHAadZcQ3KX+Vq xQc= ;{id = 30899}
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns.sub.example.com. IN AAAA
+SECTION AUTHORITY
+ns.sub.example.com. IN NSEC nt.sub.example.com. NSEC RRSIG A
+ns.sub.example.com. 3600 IN RRSIG NSEC 5 4 5 20181230101751 20181130101751 12981 sub.example.com. ESWHtKvRk0CTvXrjV0AGQ0GM3ygY020B+A4GrVPsZa6DwqnTCff13R1M SQ8u+yl71YPh+5HFMbIOFdYoPMSPvU3FyOCwPK/4Mo0z86QT5nkjx6X3 T4YLX+LRfLJ+sqJtRIyA7Mjg7xIratVCa+RYrxbYbXHwSkBScQDKdew9 g5E= ;{id = 30899}
+sub.example.com. IN SOA sub.example.com. hostmaster.sub.example.com. 1 2 3 4 5
+sub.example.com. 3600 IN RRSIG SOA 5 3 3600 20181230101751 20181130101751 12981 sub.example.com. HGuneHQjhKCum7m/PdpryrXY4ASNLfnZS38i+CnJXopIY8CWfaRDeU/k fpj9cBRzGafJAbef4ePxLqTNgWsmzQPZaIFsVIu/vjTMj5JVYmHYcvk/ SyAcQzGV4iqes/8T9z7iQTpDbWH3bD8vZdccdTRAfWi1Tl6t4+phCYVj lAI= ;{id = 30899}
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www.sub.example.com. IN A
+SECTION ANSWER
+www.sub.example.com. IN A 10.20.30.40
+www.sub.example.com. 3600 IN RRSIG A 5 4 3600 20181230101751 20181130101751 12981 sub.example.com. YYrHYSUaXA+cM1tLnfVLmVuZPugapKRSUYG/DrYzm0UQ08nuvptESpcz 6ZAP5DP9oPuoHiwPd+rvdwOtX3dWj1BfPDQ0RfAlkHMPXR2Sez3p5kI7 XNuo/FDMs337F52eij9iWSDTzgzeeBusqJPfJMRwao1THKAmDbFsvTne qpQ= ;{id = 30899}
+ENTRY_END
+
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.sub.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+www.sub.example.com. IN A
+SECTION ANSWER
+www.sub.example.com. IN A 10.20.30.40
+www.sub.example.com. 3600 IN RRSIG A 5 4 3600 20181230101751 20181130101751 12981 sub.example.com. YYrHYSUaXA+cM1tLnfVLmVuZPugapKRSUYG/DrYzm0UQ08nuvptESpcz 6ZAP5DP9oPuoHiwPd+rvdwOtX3dWj1BfPDQ0RfAlkHMPXR2Sez3p5kI7 XNuo/FDMs337F52eij9iWSDTzgzeeBusqJPfJMRwao1THKAmDbFsvTne qpQ= ;{id = 30899}
+ENTRY_END
+
+; remove pending ns.blabla.com AAAA msg
+STEP 30 QUERY
+ENTRY_BEGIN
+REPLY RD DO CD
+SECTION QUESTION
+ns.blabla.com. IN AAAA
+ENTRY_END
+
+; recursion happens here.
+STEP 40 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD CD RA DO NOERROR
+SECTION QUESTION
+ns.blabla.com. IN AAAA
+SECTION ANSWER
+SECTION AUTHORITY
+com. IN SOA com. com. 2009100100 28800 7200 604800 3600
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/black_ds.rpl b/tests/integration/deckard/sets/resolver/black_ds.rpl
new file mode 100644
index 0000000..cb8e74f
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/black_ds.rpl
@@ -0,0 +1,431 @@
+do-ip6: no
+
+; config options
+; The island of trust is at example.com
+;server:
+ trust-anchor: "example.com. 3600 IN DS 14258 7 1 302A703D2FFDA8133175342B41DCA895E435127E "
+val-override-date: "20181130121755"
+; target-fetch-policy: "0 0 0 0 0"
+; fake-sha1: yes
+
+;stub-zone:
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+query-minimization: off
+CONFIG_END
+
+SCENARIO_BEGIN Test validator with blacklist for DS response
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.blabla.com. IN A
+SECTION ANSWER
+ns.blabla.com. IN A 1.2.3.5
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.blabla.com. IN AAAA
+SECTION AUTHORITY
+com. IN SOA com. com. 2009100100 28800 7200 604800 3600
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. IN NS ns.blabla.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+; no ns.blabla.com, try that later
+ENTRY_END
+
+; Mark foo.com. tree as nonexistent since resolvers can ask for it
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NXDOMAIN
+SECTION QUESTION
+foo.com. IN NS
+SECTION AUTHORITY
+com. IN SOA com. com. 2009100100 28800 7200 604800 3600
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+example.com. IN NS ns.blabla.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20181230101755 20181130101755 14258 example.com. INVALIDQC9pyzvYZmfK3dtYLZ1wsDoVp9IuIe+Wsg94hQLWoVOnWCka1 u5KkOHalzUtwKA8bhO9PxViMkuxJzzUFNmuKVA+bZHi1wCvD5jgkC1Lq YN+ZKno6BS3LIQb9DoEHsgwuTz96K18+dXw8An9SAL2ovo+1UCb8p576 jY4= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101755 20181130101755 14258 example.com. INVALIDTC6i4BvdOLg51xRwq6PBThrC54g5XrEAizTg9H7w55qbEes/9 +ojie/elleI3WydgCNbSFC4Ax/4wsmOF4RwN0qbG0s38FHZVtuI5PANs QB40JZJftnaW2KVSyr5WiwyaRJFsootBULdUF3XjGG89oo+EF7gnm2Tz GhI= ;{id = 2854}
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.com. IN A
+SECTION ANSWER
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101755 20181130101755 14258 example.com. INVALIDTC6i4BvdOLg51xRwq6PBThrC54g5XrEAizTg9H7w55qbEes/9 +ojie/elleI3WydgCNbSFC4Ax/4wsmOF4RwN0qbG0s38FHZVtuI5PANs QB40JZJftnaW2KVSyr5WiwyaRJFsootBULdUF3XjGG89oo+EF7gnm2Tz GhI= ;{id = 2854}
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.com. IN AAAA
+SECTION ANSWER
+SECTION ADDITIONAL
+ns.example.com. IN NSEC oof.example.com. NSEC RRSIG A
+ns.example.com. 3600 IN RRSIG NSEC 7 3 3600 20181230101755 20181130101755 14258 example.com. INVALID55oT5mRBOVu3pgdzPpDcXGj/B1OmH/ZKM+M/PavxyoI74HUXX 2MJUaa4D0T2t5EuvFnie54ts6+yQbOqqVAw7/0wEDjnG0x7AyGMocsI9 sncRGe5cF4DAidhLaXUjEh7isWTaMK4x7CZUMSSgQCM1iBnhzh78XIBy aEo= ;{id = 2854}
+ENTRY_END
+
+; response to DNSKEY priming query
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN DNSKEY
+SECTION ANSWER
+example.com. 3600 IN DNSKEY 256 3 7 AwEAAat4hP1sUv+0zcKCDkb0Bj2Lg4irrLl884ks+sFXcdS9lwFIsWoD C4i91QW1AQk6/ajuxJ5fqUT0GRiQAlmsqmFFnPpUtpf2YAQh3Scfe1dg xhluZjUQfrjKpob0vwqcZK9gbMfPjygdZSkgdhOga7Ru0vQKCTj+lfTg jIwNsQgX ;{id = 2854 (zsk), size = 1688b}
+; make priming query succeed
+example.com. 3600 IN RRSIG DNSKEY 7 2 3600 20181230101755 20181130101755 14258 example.com. ZeB6Y/3u/MPCxdJmrn5A5/JN0/z5ueHGXJsi9/EBe43o9TN+/CotY4Lu 9/4t45Sb3qmpJyW8Y5Jch267TUTuFe++hfaYXO3ytBRmHgaFinoDg0ca MXPdYUa1RqL2NGHCZmBnQbSuL/9wWAk1KEpKpugNlhPM4iGfbulzR0FK CMg= ;{id = 2854}
+;example.com. 3600 IN RRSIG DNSKEY 3 2 3600 20030926134150 20030829134150 2854 example.com. AG21xE8CFQzTq6XtHErg28b9EAmqPsoYCUcFPEAoAjFybM6AY4/bMOo= ;{id = 2854}
+SECTION AUTHORITY
+;example.com. IN NS ns.example.com.
+;example.com. IN NS ns.blabla.com.
+;example.com. 3600 IN RRSIG NS 3 2 3600 20030926134150 20030829134150 2854 example.com. ACiWu7zjBHqgEX3iUoOF7rfpOmIAHj1npKQ+XDIaNlmdkfJxoCwFl04= ;{id = 2854}
+SECTION ADDITIONAL
+;ns.example.com. IN A 1.2.3.4
+;ns.example.com. 3600 IN RRSIG A 3 3 3600 20030926134150 20030829134150 2854 example.com. ACmAsKTf7hqDaYK8CQ7FL1cGYPW+blTCnzZGkExFtEUAGrHeze87o+A= ;{id = 2854}
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+www.example.com. 3600 IN RRSIG A 7 3 3600 20181230101755 20181130101755 14258 example.com. INVALID2GlTjlgoOmmH3XWO69HN9yK61kg9JS3oFNJcWhTUolF/YwFTV 4NL3xYixn2XVRh7YppvYqviK8C5fxP8kYnNn2gijdWC19bTqbjON/d7f n79Fj6yHjQWftVVIclF+d2o7yDhjwPwtsako8FMbeYFcQ+QdSMTvLw8D czE= ;{id = 2854}
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. IN NS ns.blabla.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20181230101755 20181130101755 14258 example.com. INVALIDQC9pyzvYZmfK3dtYLZ1wsDoVp9IuIe+Wsg94hQLWoVOnWCka1 u5KkOHalzUtwKA8bhO9PxViMkuxJzzUFNmuKVA+bZHi1wCvD5jgkC1Lq YN+ZKno6BS3LIQb9DoEHsgwuTz96K18+dXw8An9SAL2ovo+1UCb8p576 jY4= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101755 20181130101755 14258 example.com. INVALIDTC6i4BvdOLg51xRwq6PBThrC54g5XrEAizTg9H7w55qbEes/9 +ojie/elleI3WydgCNbSFC4Ax/4wsmOF4RwN0qbG0s38FHZVtuI5PANs QB40JZJftnaW2KVSyr5WiwyaRJFsootBULdUF3XjGG89oo+EF7gnm2Tz GhI= ;{id = 2854}
+ENTRY_END
+
+; DS request
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+sub.example.com. IN DS
+SECTION ANSWER
+sub.example.com. 3600 IN DS 34461 5 1 40F060ED2F80CC6C1D7DC32A7A8926D15E2F96C7
+sub.example.com. 3600 IN RRSIG DS 7 3 3600 20181230101755 20181130101755 14258 example.com. INVALIDblSANjCrSIUHXdZ4a8gKy8OXu7TQH9r/CSJ5y01ha9IMgHwEt i5bmQRTPAZjp0DsmFQZAyqW6zu9HXI4o/dtvg1kqNJnQQoGmlKv87OG6 +yVuydaRudH17v9ETVxlaGg+qdYdN+RtlpDcfb5VQvUMXX4xT01gVLtc wLY= ;{id = 2854}
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR AA NOERROR
+SECTION QUESTION
+sub.example.com. IN NS
+SECTION AUTHORITY
+sub.example.com. IN NS ns.sub.example.com.
+sub.example.com. IN NS ns.foo.com.
+sub.example.com. 3600 IN DS 34461 5 1 40F060ED2F80CC6C1D7DC32A7A8926D15E2F96C7
+sub.example.com. 3600 IN RRSIG DS 7 3 3600 20181230101755 20181130101755 14258 example.com. INVALIDblSANjCrSIUHXdZ4a8gKy8OXu7TQH9r/CSJ5y01ha9IMgHwEt i5bmQRTPAZjp0DsmFQZAyqW6zu9HXI4o/dtvg1kqNJnQQoGmlKv87OG6 +yVuydaRudH17v9ETVxlaGg+qdYdN+RtlpDcfb5VQvUMXX4xT01gVLtc wLY= ;{id = 2854}
+SECTION ADDITIONAL
+ns.sub.example.com. IN A 1.2.4.6
+ENTRY_END
+
+RANGE_END
+
+; ns.blabla.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.5
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+example.com. IN NS ns.blabla.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20181230101755 20181130101755 14258 example.com. TNep4HmQC9pyzvYZmfK3dtYLZ1wsDoVp9IuIe+Wsg94hQLWoVOnWCka1 u5KkOHalzUtwKA8bhO9PxViMkuxJzzUFNmuKVA+bZHi1wCvD5jgkC1Lq YN+ZKno6BS3LIQb9DoEHsgwuTz96K18+dXw8An9SAL2ovo+1UCb8p576 jY4= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101755 20181130101755 14258 example.com. IwIqfkUTC6i4BvdOLg51xRwq6PBThrC54g5XrEAizTg9H7w55qbEes/9 +ojie/elleI3WydgCNbSFC4Ax/4wsmOF4RwN0qbG0s38FHZVtuI5PANs QB40JZJftnaW2KVSyr5WiwyaRJFsootBULdUF3XjGG89oo+EF7gnm2Tz GhI= ;{id = 2854}
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.com. IN A
+SECTION ANSWER
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101755 20181130101755 14258 example.com. IwIqfkUTC6i4BvdOLg51xRwq6PBThrC54g5XrEAizTg9H7w55qbEes/9 +ojie/elleI3WydgCNbSFC4Ax/4wsmOF4RwN0qbG0s38FHZVtuI5PANs QB40JZJftnaW2KVSyr5WiwyaRJFsootBULdUF3XjGG89oo+EF7gnm2Tz GhI= ;{id = 2854}
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.com. IN AAAA
+SECTION ANSWER
+SECTION ADDITIONAL
+ns.example.com. IN NSEC oof.example.com. NSEC RRSIG A
+ns.example.com. 3600 IN RRSIG NSEC 7 3 3600 20181230101755 20181130101755 14258 example.com. MdF5+Lt55oT5mRBOVu3pgdzPpDcXGj/B1OmH/ZKM+M/PavxyoI74HUXX 2MJUaa4D0T2t5EuvFnie54ts6+yQbOqqVAw7/0wEDjnG0x7AyGMocsI9 sncRGe5cF4DAidhLaXUjEh7isWTaMK4x7CZUMSSgQCM1iBnhzh78XIBy aEo= ;{id = 2854}
+ENTRY_END
+
+; response to DNSKEY priming query
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN DNSKEY
+SECTION ANSWER
+example.com. 3600 IN DNSKEY 256 3 7 AwEAAat4hP1sUv+0zcKCDkb0Bj2Lg4irrLl884ks+sFXcdS9lwFIsWoD C4i91QW1AQk6/ajuxJ5fqUT0GRiQAlmsqmFFnPpUtpf2YAQh3Scfe1dg xhluZjUQfrjKpob0vwqcZK9gbMfPjygdZSkgdhOga7Ru0vQKCTj+lfTg jIwNsQgX ;{id = 2854 (zsk), size = 1688b}
+example.com. 3600 IN RRSIG DNSKEY 7 2 3600 20181230101755 20181130101755 14258 example.com. ZeB6Y/3u/MPCxdJmrn5A5/JN0/z5ueHGXJsi9/EBe43o9TN+/CotY4Lu 9/4t45Sb3qmpJyW8Y5Jch267TUTuFe++hfaYXO3ytBRmHgaFinoDg0ca MXPdYUa1RqL2NGHCZmBnQbSuL/9wWAk1KEpKpugNlhPM4iGfbulzR0FK CMg= ;{id = 2854}
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. IN NS ns.blabla.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20181230101755 20181130101755 14258 example.com. TNep4HmQC9pyzvYZmfK3dtYLZ1wsDoVp9IuIe+Wsg94hQLWoVOnWCka1 u5KkOHalzUtwKA8bhO9PxViMkuxJzzUFNmuKVA+bZHi1wCvD5jgkC1Lq YN+ZKno6BS3LIQb9DoEHsgwuTz96K18+dXw8An9SAL2ovo+1UCb8p576 jY4= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101755 20181130101755 14258 example.com. IwIqfkUTC6i4BvdOLg51xRwq6PBThrC54g5XrEAizTg9H7w55qbEes/9 +ojie/elleI3WydgCNbSFC4Ax/4wsmOF4RwN0qbG0s38FHZVtuI5PANs QB40JZJftnaW2KVSyr5WiwyaRJFsootBULdUF3XjGG89oo+EF7gnm2Tz GhI= ;{id = 2854}
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+www.example.com. 3600 IN RRSIG A 7 3 3600 20181230101755 20181130101755 14258 example.com. OIh7nTI2GlTjlgoOmmH3XWO69HN9yK61kg9JS3oFNJcWhTUolF/YwFTV 4NL3xYixn2XVRh7YppvYqviK8C5fxP8kYnNn2gijdWC19bTqbjON/d7f n79Fj6yHjQWftVVIclF+d2o7yDhjwPwtsako8FMbeYFcQ+QdSMTvLw8D czE= ;{id = 2854}
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. IN NS ns.blabla.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20181230101755 20181130101755 14258 example.com. TNep4HmQC9pyzvYZmfK3dtYLZ1wsDoVp9IuIe+Wsg94hQLWoVOnWCka1 u5KkOHalzUtwKA8bhO9PxViMkuxJzzUFNmuKVA+bZHi1wCvD5jgkC1Lq YN+ZKno6BS3LIQb9DoEHsgwuTz96K18+dXw8An9SAL2ovo+1UCb8p576 jY4= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101755 20181130101755 14258 example.com. IwIqfkUTC6i4BvdOLg51xRwq6PBThrC54g5XrEAizTg9H7w55qbEes/9 +ojie/elleI3WydgCNbSFC4Ax/4wsmOF4RwN0qbG0s38FHZVtuI5PANs QB40JZJftnaW2KVSyr5WiwyaRJFsootBULdUF3XjGG89oo+EF7gnm2Tz GhI= ;{id = 2854}
+ENTRY_END
+
+; DS request
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+sub.example.com. IN DS
+SECTION ANSWER
+sub.example.com. 3600 IN DS 34461 5 1 40F060ED2F80CC6C1D7DC32A7A8926D15E2F96C7
+sub.example.com. 3600 IN RRSIG DS 7 3 3600 20181230101755 20181130101755 14258 example.com. Mf7vpHZblSANjCrSIUHXdZ4a8gKy8OXu7TQH9r/CSJ5y01ha9IMgHwEt i5bmQRTPAZjp0DsmFQZAyqW6zu9HXI4o/dtvg1kqNJnQQoGmlKv87OG6 +yVuydaRudH17v9ETVxlaGg+qdYdN+RtlpDcfb5VQvUMXX4xT01gVLtc wLY= ;{id = 2854}
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR AA NOERROR
+SECTION QUESTION
+sub.example.com. IN NS
+SECTION AUTHORITY
+sub.example.com. IN NS ns.sub.example.com.
+sub.example.com. IN NS ns.foo.com.
+sub.example.com. 3600 IN DS 34461 5 1 40F060ED2F80CC6C1D7DC32A7A8926D15E2F96C7
+sub.example.com. 3600 IN RRSIG DS 7 3 3600 20181230101755 20181130101755 14258 example.com. Mf7vpHZblSANjCrSIUHXdZ4a8gKy8OXu7TQH9r/CSJ5y01ha9IMgHwEt i5bmQRTPAZjp0DsmFQZAyqW6zu9HXI4o/dtvg1kqNJnQQoGmlKv87OG6 +yVuydaRudH17v9ETVxlaGg+qdYdN+RtlpDcfb5VQvUMXX4xT01gVLtc wLY= ;{id = 2854}
+SECTION ADDITIONAL
+ns.sub.example.com. IN A 1.2.4.6
+ENTRY_END
+
+RANGE_END
+
+; ns.sub.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.4.6
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+sub.example.com. IN DNSKEY
+SECTION ANSWER
+sub.example.com. 3600 IN DNSKEY 256 3 5 AwEAAcJc2r+SCY+fkRzchGj7gEfuutF+Gwt7H0/4EnOKxIwlf0LthG7p 9xyHAuEGFN9aSkVyg0S/edWEODCGL583yRXnaJ6Ryc90H1SfSX1Wytdd XrBENgFI/B2vf4IZxm4tutwJwvMh8CXhMIGGhRzROIwijNB+eABCKu6z duD8nxL1 ;{id = 30899 (zsk), size = 512b}
+sub.example.com. 3600 IN RRSIG DNSKEY 5 3 3600 20181230101754 20181130101754 34461 sub.example.com. CbEKDlQCkG0clRptCLxKpUt6yiydTYdLmjwocdAcJOZ2MMI0joFuyPvV 89+l5xzSsvhA9CLLD5COcIhymMUtNLqF87GmnvtN/NSBTSQoOA+Ujr7t 3zp0FOWNasL/xIuORU7HBZvXq9saCjwnuRckXCouTop01Fr25ht+jYfj A6o= ;{id = 30899}
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+sub.example.com. IN NS
+SECTION ANSWER
+sub.example.com. IN NS ns.sub.example.com.
+sub.example.com. IN NS ns.foo.com.
+sub.example.com. 3600 IN RRSIG NS 5 3 3600 20181230101754 20181130101754 34461 sub.example.com. hZbI8UiV3LAHw6Rchr6vYqHkuURNG7fAzlQAvxxdqyHQKNd1EUZwPulE knjiklD+Ke5kk4PEWQaWlmBlfmhOkYA3bdLeDKIMi9jsVTPLAwUmPZOV uAMbvnrEvnqdxTHNRgtwoDD/20mMJqaNEmGLayc1Yf5zmOMQQ+m68DGx Ths= ;{id = 30899}
+SECTION ADDITIONAL
+ns.sub.example.com. IN A 1.2.4.6
+ns.sub.example.com. 3600 IN RRSIG A 5 4 3600 20181230101754 20181130101754 34461 sub.example.com. J48RT+8rS2wShNJabUbeeKSsXi7v808iOwI0UQbAGg4QXzKIgDZR32dy ClKPkSAId20AfrGotJWz1kJyUAH7EDD9BVpX7PlF5BKfTJD0VRmBu+FF BSarqtziyTaNRsQwzgf74Gj2xRQmEfiGwLSyX1SXNC1sl4Wv+tGnH8M1 VOU= ;{id = 30899}
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns.sub.example.com. IN A
+SECTION ANSWER
+ns.sub.example.com. IN A 1.2.4.6
+ns.sub.example.com. 3600 IN RRSIG A 5 4 3600 20181230101754 20181130101754 34461 sub.example.com. J48RT+8rS2wShNJabUbeeKSsXi7v808iOwI0UQbAGg4QXzKIgDZR32dy ClKPkSAId20AfrGotJWz1kJyUAH7EDD9BVpX7PlF5BKfTJD0VRmBu+FF BSarqtziyTaNRsQwzgf74Gj2xRQmEfiGwLSyX1SXNC1sl4Wv+tGnH8M1 VOU= ;{id = 30899}
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns.sub.example.com. IN AAAA
+SECTION AUTHORITY
+ns.sub.example.com. IN NSEC nt.sub.example.com. NSEC RRSIG A
+ns.sub.example.com. 3600 IN RRSIG NSEC 5 4 5 20181230101754 20181130101754 34461 sub.example.com. Jsa5cpk3YApRVWatd1d3E7g6Rh1iqyxw8IzY9hBX5HkxBm0gaRZ0B7F3 np27mEtQi7Ca7dYzjhMAPJtki5AwFhG9TQq3nEm9mhFQy4M5JdqnKcPX uIy7QZAhlBgg3EiFlMER/VHWWTGie1aOdS11EW9uAoLP3jGxRuVod9YK Vno= ;{id = 30899}
+sub.example.com. IN SOA sub.example.com. hostmaster.sub.example.com. 1 2 3 4 5
+sub.example.com. 3600 IN RRSIG SOA 5 3 3600 20181230101754 20181130101754 34461 sub.example.com. gRW+r5SnhDYodC44XwY0qc4M5AV7f2UsX0BMdxnBc6BOoo/TwmWfY1YU TCf50YQMfE/aoRrFpnzy/IMFHzgzWiWMBYgQ07jZFaYaT21JV90orXnA PEmAQ7BTwnvEA7kM6uNAYVYJeE5sh0/ILZ+HpCVh+oHC3GX2BCcEUK4p F0o= ;{id = 30899}
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www.sub.example.com. IN A
+SECTION ANSWER
+www.sub.example.com. IN A 10.20.30.40
+www.sub.example.com. 3600 IN RRSIG A 5 4 3600 20181230101754 20181130101754 34461 sub.example.com. vKBtMjGLMImbm4KKVDbVeiShF7NWxnoSKKVEefhpH7x/sG8xKK2v3LYV Fc0KX+kPTYrXJCEQiwMPNqH4YdldjH3OEVP5C1oOIx3EoB+nRwFIHBxu JjoS/7XV/tdDqJ17FIOCDsARmWbLz6tJteFwRZyLvaozVNDl0z8VHAQB 7cE= ;{id = 30899}
+ENTRY_END
+
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.sub.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+www.sub.example.com. IN A
+SECTION ANSWER
+www.sub.example.com. IN A 10.20.30.40
+www.sub.example.com. 3600 IN RRSIG A 5 4 3600 20181230101754 20181130101754 34461 sub.example.com. vKBtMjGLMImbm4KKVDbVeiShF7NWxnoSKKVEefhpH7x/sG8xKK2v3LYV Fc0KX+kPTYrXJCEQiwMPNqH4YdldjH3OEVP5C1oOIx3EoB+nRwFIHBxu JjoS/7XV/tdDqJ17FIOCDsARmWbLz6tJteFwRZyLvaozVNDl0z8VHAQB 7cE= ;{id = 30899}
+ENTRY_END
+
+; remove pending ns.blabla.com AAAA msg
+STEP 30 QUERY
+ENTRY_BEGIN
+REPLY RD DO CD
+SECTION QUESTION
+ns.blabla.com. IN AAAA
+ENTRY_END
+
+; recursion happens here.
+STEP 40 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD CD RA DO NOERROR
+SECTION QUESTION
+ns.blabla.com. IN AAAA
+SECTION ANSWER
+SECTION AUTHORITY
+com. IN SOA com. com. 2009100100 28800 7200 604800 3600
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/black_ent.rpl b/tests/integration/deckard/sets/resolver/black_ent.rpl
new file mode 100644
index 0000000..b52d9b8
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/black_ent.rpl
@@ -0,0 +1,464 @@
+do-ip6: no
+
+; config options
+; The island of trust is at example.com
+;server:
+ trust-anchor: "example.com. 3600 IN DS 5459 7 1 40E1D493C25150C341D3AB775BCF908C857DDF7D "
+val-override-date: "20181130121757"
+; target-fetch-policy: "0 0 0 0 0"
+; fake-sha1: yes
+
+;stub-zone:
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+query-minimization: off
+CONFIG_END
+
+SCENARIO_BEGIN Test validator with blacklist for ENT response
+; 'ENT' Empty Non Terminal
+; which needs a valid NSEC(3) proof.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.blabla.com. IN A
+SECTION ANSWER
+ns.blabla.com. IN A 1.2.3.5
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.blabla.com. IN AAAA
+SECTION AUTHORITY
+com. IN SOA com. com. 2009100100 28800 7200 604800 3600
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. IN NS ns.blabla.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+; no ns.blabla.com, try that later
+ENTRY_END
+
+; Mark foo.com. tree as nonexistent since resolvers can ask for it
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NXDOMAIN
+SECTION QUESTION
+foo.com. IN NS
+SECTION AUTHORITY
+com. IN SOA com. com. 2009100100 28800 7200 604800 3600
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+example.com. IN NS ns.blabla.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20181230101756 20181130101756 5459 example.com. INVALIDQk6CQ0GBHNByUfF9s7kXOl2Qflh74erA5oFkrlK0/fJFRAkMb Edgmrs4FjvrlJJ1Gi5BWqv0avoyPUWVhwYz15VhjJjXP6jLuVn1j/EnT J5t55UU6hGf2R9NHvLRdeebJDOMryVW+1r9UWQYuabdCkxtnT+xcw9Or nDs= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101756 20181130101756 5459 example.com. INVALIDa0BQlJUnglecaUzphiHPw9ozBTu5v4Lx2ppQLqUZf4AXPgetm 5WjHUVJIqU9e0AwyHiqq3vKK6kDrUcdtI3Ygyn9O5WgCeGUd1UNXrx9h 2SLESwVt5MWFfFP3M0vKwgWrvWS4eZKD6Uc1VUm5tzIo5VRb6Q839qGw yKU= ;{id = 2854}
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.com. IN A
+SECTION ANSWER
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101756 20181130101756 5459 example.com. INVALIDa0BQlJUnglecaUzphiHPw9ozBTu5v4Lx2ppQLqUZf4AXPgetm 5WjHUVJIqU9e0AwyHiqq3vKK6kDrUcdtI3Ygyn9O5WgCeGUd1UNXrx9h 2SLESwVt5MWFfFP3M0vKwgWrvWS4eZKD6Uc1VUm5tzIo5VRb6Q839qGw yKU= ;{id = 2854}
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.com. IN AAAA
+SECTION ANSWER
+SECTION ADDITIONAL
+ns.example.com. IN NSEC oof.example.com. NSEC RRSIG A
+ns.example.com. 3600 IN RRSIG NSEC 7 3 3600 20181230101756 20181130101756 5459 example.com. INVALIDGlYtmk/wVLfWyqGwo4vbo8fGaD7DoGnJGFpICmoM8v7mcs4Pd UyZv9CPBMy9gYNM1wWcNVofQu2IC5gUgEpkuhluJji5BeocqOGzIuHW+ AVIHJjN4m9z12swsCrAq71vO+UEfWqPO4JOu40vVkSsDiaINYd8FRWkr yfg= ;{id = 2854}
+ENTRY_END
+
+; response to DNSKEY priming query
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN DNSKEY
+SECTION ANSWER
+example.com. 3600 IN DNSKEY 256 3 7 AwEAAaQAmPhsPdOjFE6SGc95hYvPxUHoNkUetYpu81j7j9WXUsvn8Y6M DrHOnLrVd9uV7+1Aj2nkLY+6BvLxsPcp3yBO7UPB6Mv1ZfYCP0D7qCcs Jg6NjLWD5+2owvglTk7XveTztZLFIgDGo2sxZ4/wKE2fhsmh6/Hn7GiW ySEwHURb ;{id = 2854 (zsk), size = 1688b}
+; make priming query succeed
+example.com. 3600 IN RRSIG DNSKEY 7 2 3600 20181230101756 20181130101756 5459 example.com. INVALID2oppL26sSLAFSTTkOken2ZlU+bJwpH3ipCz6BTCIm8zHjk/u7 IPyX6RiKEgVwUKEoNIXSYxkZg4Q2OHOINwRhARgQR5XOZaVN9s4acmYK yPcZHteq2YChTbLreIj4xGgoIIzW9G3e98FAvgzMyMw7b8s6678hLA7S EW8= ;{id = 2854}
+;example.com. 3600 IN RRSIG DNSKEY 3 2 3600 20030926134150 20030829134150 2854 example.com. AG21xE8CFQzTq6XtHErg28b9EAmqPsoYCUcFPEAoAjFybM6AY4/bMOo= ;{id = 2854}
+SECTION AUTHORITY
+;example.com. IN NS ns.example.com.
+;example.com. IN NS ns.blabla.com.
+;example.com. 3600 IN RRSIG NS 3 2 3600 20030926134150 20030829134150 2854 example.com. ACiWu7zjBHqgEX3iUoOF7rfpOmIAHj1npKQ+XDIaNlmdkfJxoCwFl04= ;{id = 2854}
+SECTION ADDITIONAL
+;ns.example.com. IN A 1.2.3.4
+;ns.example.com. 3600 IN RRSIG A 3 3 3600 20030926134150 20030829134150 2854 example.com. ACmAsKTf7hqDaYK8CQ7FL1cGYPW+blTCnzZGkExFtEUAGrHeze87o+A= ;{id = 2854}
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+www.example.com. 3600 IN RRSIG A 7 3 3600 20181230101756 20181130101756 5459 example.com. INVALIDG8XsVXX6xqSkSeqhDauNtAK1fnTgt1qdGf1+TFJuqPjHmEBr3 I8u381FKJaGPF2ZKH+A5oSPy6jPLQLe4TipFgnTZptq4IZ53holOKlx9 RSjz5kovs5wYafSeBBM+cjX6LJogyP8vrnPuSJ/Z8Uk2+Ojhd1j7sR2C PwY= ;{id = 2854}
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. IN NS ns.blabla.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20181230101756 20181130101756 5459 example.com. INVALIDQk6CQ0GBHNByUfF9s7kXOl2Qflh74erA5oFkrlK0/fJFRAkMb Edgmrs4FjvrlJJ1Gi5BWqv0avoyPUWVhwYz15VhjJjXP6jLuVn1j/EnT J5t55UU6hGf2R9NHvLRdeebJDOMryVW+1r9UWQYuabdCkxtnT+xcw9Or nDs= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101756 20181130101756 5459 example.com. INVALIDa0BQlJUnglecaUzphiHPw9ozBTu5v4Lx2ppQLqUZf4AXPgetm 5WjHUVJIqU9e0AwyHiqq3vKK6kDrUcdtI3Ygyn9O5WgCeGUd1UNXrx9h 2SLESwVt5MWFfFP3M0vKwgWrvWS4eZKD6Uc1VUm5tzIo5VRb6Q839qGw yKU= ;{id = 2854}
+ENTRY_END
+
+; ENT request
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+sub.example.com. IN DS
+SECTION AUTHORITY
+rub.example.com. IN NSEC sub.sub.example.com. RRSIG NSEC A
+rub.example.com. 3600 IN RRSIG NSEC 7 3 3600 20181230101756 20181130101756 5459 example.com. INVALIDOA5KoYz7wy2512fZqTzWTdfRdL2VQU6+v+k39hMpVvBbRbW3R 8X1YFrbl+gKMbzhtH3kKkjibwlKethd71p8xZKwIw4df1u3kdJygijuH +BvwG6jCIzF8wBLh8Uuv14KJOybmqJXzUdVKAU9MyQNvnfJk+Ekdj/sY MEw= ;{id = 2854}
+; extraneous DS
+sub.sub.example.com. IN NSEC tub.example.com. RRSIG NSEC DS
+sub.sub.example.com. 3600 IN RRSIG NSEC 7 4 3600 20181230101756 20181130101756 5459 example.com. INVALIDq8vIslggd50/mnc5rV+OKchIZPUdrVjVpGZjsieh50UoM1+bV ChGrxwDNUYvs7vzztSaZ+oyBErPiGzkK6/nUQ5P8fhxMyPMaFrCNtHCC +tZsImjSbiwVm3bLpdcoNEDRHjiVb0Y7ztScMQji2QyN6iFLPrXXXNaW HXU= ;{id = 2854}
+ENTRY_END
+
+; DS request
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+sub.sub.example.com. IN DS
+SECTION ANSWER
+sub.sub.example.com. 3600 IN DS 14511 5 1 9C23483B120C7BCAB7E9BD00BCA7F30B38F92E1A
+sub.sub.example.com. 3600 IN RRSIG DS 7 4 3600 20181230101756 20181130101756 5459 example.com. INVALIDNgvdoBxXKSiTVnmofgublfIQPCqrHwEDMCzs1WbIJWWEmzmxX 7dzupiSnVPlVQfKLXzEbSqM/QGxmU/bBn2lUAYNLpM2kFm85TVEXCLf8 u12NeWbBupsr1UctfzF2WtaUGxVfDZ+J86ka3qqQnmYYYAbz4MlnKvyQ p5c= ;{id = 2854}
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR AA NOERROR
+SECTION QUESTION
+sub.sub.example.com. IN NS
+SECTION AUTHORITY
+sub.sub.example.com. IN NS ns.sub.sub.example.com.
+sub.sub.example.com. IN NS ns.foo.com.
+sub.sub.example.com. 3600 IN DS 14511 5 1 9C23483B120C7BCAB7E9BD00BCA7F30B38F92E1A
+sub.sub.example.com. 3600 IN RRSIG DS 7 4 3600 20181230101756 20181130101756 5459 example.com. INVALIDNgvdoBxXKSiTVnmofgublfIQPCqrHwEDMCzs1WbIJWWEmzmxX 7dzupiSnVPlVQfKLXzEbSqM/QGxmU/bBn2lUAYNLpM2kFm85TVEXCLf8 u12NeWbBupsr1UctfzF2WtaUGxVfDZ+J86ka3qqQnmYYYAbz4MlnKvyQ p5c= ;{id = 2854}
+SECTION ADDITIONAL
+ns.sub.sub.example.com. IN A 1.2.4.6
+ENTRY_END
+
+RANGE_END
+
+; ns.blabla.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.5
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+example.com. IN NS ns.blabla.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20181230101756 20181130101756 5459 example.com. MGpbBGEQk6CQ0GBHNByUfF9s7kXOl2Qflh74erA5oFkrlK0/fJFRAkMb Edgmrs4FjvrlJJ1Gi5BWqv0avoyPUWVhwYz15VhjJjXP6jLuVn1j/EnT J5t55UU6hGf2R9NHvLRdeebJDOMryVW+1r9UWQYuabdCkxtnT+xcw9Or nDs= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101756 20181130101756 5459 example.com. aAhY236a0BQlJUnglecaUzphiHPw9ozBTu5v4Lx2ppQLqUZf4AXPgetm 5WjHUVJIqU9e0AwyHiqq3vKK6kDrUcdtI3Ygyn9O5WgCeGUd1UNXrx9h 2SLESwVt5MWFfFP3M0vKwgWrvWS4eZKD6Uc1VUm5tzIo5VRb6Q839qGw yKU= ;{id = 2854}
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.com. IN A
+SECTION ANSWER
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101756 20181130101756 5459 example.com. aAhY236a0BQlJUnglecaUzphiHPw9ozBTu5v4Lx2ppQLqUZf4AXPgetm 5WjHUVJIqU9e0AwyHiqq3vKK6kDrUcdtI3Ygyn9O5WgCeGUd1UNXrx9h 2SLESwVt5MWFfFP3M0vKwgWrvWS4eZKD6Uc1VUm5tzIo5VRb6Q839qGw yKU= ;{id = 2854}
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.com. IN AAAA
+SECTION ANSWER
+SECTION ADDITIONAL
+ns.example.com. IN NSEC oof.example.com. NSEC RRSIG A
+ns.example.com. 3600 IN RRSIG NSEC 7 3 3600 20181230101756 20181130101756 5459 example.com. WM9C+vSGlYtmk/wVLfWyqGwo4vbo8fGaD7DoGnJGFpICmoM8v7mcs4Pd UyZv9CPBMy9gYNM1wWcNVofQu2IC5gUgEpkuhluJji5BeocqOGzIuHW+ AVIHJjN4m9z12swsCrAq71vO+UEfWqPO4JOu40vVkSsDiaINYd8FRWkr yfg= ;{id = 2854}
+ENTRY_END
+
+; response to DNSKEY priming query
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN DNSKEY
+SECTION ANSWER
+example.com. 3600 IN DNSKEY 256 3 7 AwEAAaQAmPhsPdOjFE6SGc95hYvPxUHoNkUetYpu81j7j9WXUsvn8Y6M DrHOnLrVd9uV7+1Aj2nkLY+6BvLxsPcp3yBO7UPB6Mv1ZfYCP0D7qCcs Jg6NjLWD5+2owvglTk7XveTztZLFIgDGo2sxZ4/wKE2fhsmh6/Hn7GiW ySEwHURb ;{id = 2854 (zsk), size = 1688b}
+example.com. 3600 IN RRSIG DNSKEY 7 2 3600 20181230101756 20181130101756 5459 example.com. Pfl3n2c2oppL26sSLAFSTTkOken2ZlU+bJwpH3ipCz6BTCIm8zHjk/u7 IPyX6RiKEgVwUKEoNIXSYxkZg4Q2OHOINwRhARgQR5XOZaVN9s4acmYK yPcZHteq2YChTbLreIj4xGgoIIzW9G3e98FAvgzMyMw7b8s6678hLA7S EW8= ;{id = 2854}
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. IN NS ns.blabla.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20181230101756 20181130101756 5459 example.com. MGpbBGEQk6CQ0GBHNByUfF9s7kXOl2Qflh74erA5oFkrlK0/fJFRAkMb Edgmrs4FjvrlJJ1Gi5BWqv0avoyPUWVhwYz15VhjJjXP6jLuVn1j/EnT J5t55UU6hGf2R9NHvLRdeebJDOMryVW+1r9UWQYuabdCkxtnT+xcw9Or nDs= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101756 20181130101756 5459 example.com. aAhY236a0BQlJUnglecaUzphiHPw9ozBTu5v4Lx2ppQLqUZf4AXPgetm 5WjHUVJIqU9e0AwyHiqq3vKK6kDrUcdtI3Ygyn9O5WgCeGUd1UNXrx9h 2SLESwVt5MWFfFP3M0vKwgWrvWS4eZKD6Uc1VUm5tzIo5VRb6Q839qGw yKU= ;{id = 2854}
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101756 20181130101756 5459 example.com. aAhY236a0BQlJUnglecaUzphiHPw9ozBTu5v4Lx2ppQLqUZf4AXPgetm 5WjHUVJIqU9e0AwyHiqq3vKK6kDrUcdtI3Ygyn9O5WgCeGUd1UNXrx9h 2SLESwVt5MWFfFP3M0vKwgWrvWS4eZKD6Uc1VUm5tzIo5VRb6Q839qGw yKU= ;{id = 2854}
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. IN NS ns.blabla.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20181230101756 20181130101756 5459 example.com. MGpbBGEQk6CQ0GBHNByUfF9s7kXOl2Qflh74erA5oFkrlK0/fJFRAkMb Edgmrs4FjvrlJJ1Gi5BWqv0avoyPUWVhwYz15VhjJjXP6jLuVn1j/EnT J5t55UU6hGf2R9NHvLRdeebJDOMryVW+1r9UWQYuabdCkxtnT+xcw9Or nDs= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+www.example.com. 3600 IN RRSIG A 7 3 3600 20181230101756 20181130101756 5459 example.com. UJ98Ev1G8XsVXX6xqSkSeqhDauNtAK1fnTgt1qdGf1+TFJuqPjHmEBr3 I8u381FKJaGPF2ZKH+A5oSPy6jPLQLe4TipFgnTZptq4IZ53holOKlx9 RSjz5kovs5wYafSeBBM+cjX6LJogyP8vrnPuSJ/Z8Uk2+Ojhd1j7sR2C PwY= ;{id = 2854}
+ENTRY_END
+
+; ENT request
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+sub.example.com. IN DS
+SECTION AUTHORITY
+rub.example.com. IN NSEC sub.sub.example.com. RRSIG NSEC A
+rub.example.com. 3600 IN RRSIG NSEC 7 3 3600 20181230101756 20181130101756 5459 example.com. LxXDGCPOA5KoYz7wy2512fZqTzWTdfRdL2VQU6+v+k39hMpVvBbRbW3R 8X1YFrbl+gKMbzhtH3kKkjibwlKethd71p8xZKwIw4df1u3kdJygijuH +BvwG6jCIzF8wBLh8Uuv14KJOybmqJXzUdVKAU9MyQNvnfJk+Ekdj/sY MEw= ;{id = 2854}
+; extraneous DS
+sub.sub.example.com. IN NSEC tub.example.com. RRSIG NSEC DS
+sub.sub.example.com. 3600 IN RRSIG NSEC 7 4 3600 20181230101756 20181130101756 5459 example.com. RoMochVq8vIslggd50/mnc5rV+OKchIZPUdrVjVpGZjsieh50UoM1+bV ChGrxwDNUYvs7vzztSaZ+oyBErPiGzkK6/nUQ5P8fhxMyPMaFrCNtHCC +tZsImjSbiwVm3bLpdcoNEDRHjiVb0Y7ztScMQji2QyN6iFLPrXXXNaW HXU= ;{id = 2854}
+ENTRY_END
+
+; DS request
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+sub.sub.example.com. IN DS
+SECTION ANSWER
+sub.sub.example.com. 3600 IN DS 14511 5 1 9C23483B120C7BCAB7E9BD00BCA7F30B38F92E1A
+sub.sub.example.com. 3600 IN RRSIG DS 7 4 3600 20181230101756 20181130101756 5459 example.com. jkShmezNgvdoBxXKSiTVnmofgublfIQPCqrHwEDMCzs1WbIJWWEmzmxX 7dzupiSnVPlVQfKLXzEbSqM/QGxmU/bBn2lUAYNLpM2kFm85TVEXCLf8 u12NeWbBupsr1UctfzF2WtaUGxVfDZ+J86ka3qqQnmYYYAbz4MlnKvyQ p5c= ;{id = 2854}
+
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR AA NOERROR
+SECTION QUESTION
+sub.sub.example.com. IN NS
+SECTION AUTHORITY
+sub.sub.example.com. IN NS ns.sub.sub.example.com.
+sub.sub.example.com. IN NS ns.foo.com.
+sub.sub.example.com. 3600 IN DS 14511 5 1 9C23483B120C7BCAB7E9BD00BCA7F30B38F92E1A
+sub.sub.example.com. 3600 IN RRSIG DS 7 4 3600 20181230101756 20181130101756 5459 example.com. jkShmezNgvdoBxXKSiTVnmofgublfIQPCqrHwEDMCzs1WbIJWWEmzmxX 7dzupiSnVPlVQfKLXzEbSqM/QGxmU/bBn2lUAYNLpM2kFm85TVEXCLf8 u12NeWbBupsr1UctfzF2WtaUGxVfDZ+J86ka3qqQnmYYYAbz4MlnKvyQ p5c= ;{id = 2854}
+SECTION ADDITIONAL
+ns.sub.sub.example.com. IN A 1.2.4.6
+ENTRY_END
+
+RANGE_END
+
+; ns.sub.sub.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.4.6
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+sub.sub.example.com. IN DNSKEY
+SECTION ANSWER
+sub.sub.example.com. 3600 IN DNSKEY 256 3 5 AwEAAabTZ4z4UwwLP6+/SGL9K8q35Xrmey7BMhj0ljyMLM3SGf+2syaV eLubZDwaFf6mO7/hc4HOVrXsdl9mWm8kvuKj8zcj/hi26dcUUfd4OAyR Fy1qrnyutzHJkB/9Ahau0/ORuQXAAstUaQERk1u2RQI2u/iWmuEN5o1H Tf4CUruX ;{id = 30899 (zsk), size = 512b}
+sub.sub.example.com. 3600 IN RRSIG DNSKEY 5 4 3600 20181230101756 20181130101756 14511 sub.sub.example.com. jTL8Io/JECEwS06P0rTJquZjpFzONP/UKmSPscICI+yI6aOLc+Fa1ig9 OC+XLfBmbnpN/W+KAtpJGwkDzFiXMWLB+Q3BnAVnqQvsDHv0CKIDyN4k Vo7rVqMuDM5bFYsoPhojltZ+2ZP/m6c/ylxwj5Yr0tuRpJSiyj4rEKRv Ohs= ;{id = 30899}
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+sub.sub.example.com. IN NS
+SECTION ANSWER
+sub.sub.example.com. IN NS ns.sub.sub.example.com.
+sub.sub.example.com. IN NS ns.foo.com.
+sub.sub.example.com. 3600 IN RRSIG NS 5 4 3600 20181230101756 20181130101756 14511 sub.sub.example.com. I4VuZ180mFDV4B2YK7gWXaFYYxJE+Mt4X12/azYSudLBesx/NR99GYNc dQbrE03JEGvDRmTataRE1za7RdpR7HkJfUfY+2Wa/CtmdIvLkxnDkK0G AexLq0ws8ozntfMdrI1Ahz9mMj8/tifrlvNSMA0ifjtmjENZX0HyBuYX OwI= ;{id = 30899}
+SECTION ADDITIONAL
+ns.sub.sub.example.com. IN A 1.2.4.6
+ns.sub.sub.example.com. 3600 IN RRSIG A 5 5 3600 20181230101756 20181130101756 14511 sub.sub.example.com. eWvgi1EsYq54z+3NIjhwoeq+qGmJ/5GUnXAE024QLD8J/a1fN1QB4WR4 awo3UuhPeYd3LHntFQ1LuJDcxqLwT2C4c7mN/EQu39zrnlKwJS2kOyAo eolcUtsEkmf37VY3ZpUXviQZlOtJfEXaAajWeksXMeVAmzuO9l0SOD1O QzQ= ;{id = 30899}
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns.sub.sub.example.com. IN A
+SECTION ANSWER
+ns.sub.sub.example.com. IN A 1.2.4.6
+ns.sub.sub.example.com. 3600 IN RRSIG A 5 5 3600 20181230101756 20181130101756 14511 sub.sub.example.com. eWvgi1EsYq54z+3NIjhwoeq+qGmJ/5GUnXAE024QLD8J/a1fN1QB4WR4 awo3UuhPeYd3LHntFQ1LuJDcxqLwT2C4c7mN/EQu39zrnlKwJS2kOyAo eolcUtsEkmf37VY3ZpUXviQZlOtJfEXaAajWeksXMeVAmzuO9l0SOD1O QzQ= ;{id = 30899}
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns.sub.sub.example.com. IN AAAA
+SECTION AUTHORITY
+ns.sub.sub.example.com. IN NSEC nt.sub.sub.example.com. NSEC RRSIG A
+ns.sub.sub.example.com. 3600 IN RRSIG NSEC 5 5 5 20181230101756 20181130101756 14511 sub.sub.example.com. HcRO6gIx6vkwVAXfGG/OmN7eBBbzjEy1Em3iOwsZT0SuCzcPWJOMS/n2 HnocrKbR/k4seuodrppyUF3nfDcGWJ85gC7HprofbJNgmjVJSErb6Y2Q eGzDf7SJULRKLX5lHmqYY7UUWHmAQKjnnrN7SSnCb8RigPi1DcGUlS5N GzU= ;{id = 30899}
+sub.sub.example.com. IN SOA sub.sub.example.com. hostmaster.sub.sub.example.com. 1 2 3 4 5
+sub.sub.example.com. 3600 IN RRSIG SOA 5 4 3600 20181230101756 20181130101756 14511 sub.sub.example.com. etcKdUzigtePis7MO2hVK0runIUOnpCD59J+2ne554YZk7OYi68IIoZB wvmeJoz6nqEu2V0ciZflj8gX9DAHDqV+mTWSr8ZXqp800hJkbxJ66C7q Q7M+bfMq8QN3+JwjosvjGBYmR6s6AMA/AmgYNA/mN1pCjkY4LpDMDmYU Mks= ;{id = 30899}
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www.sub.sub.example.com. IN A
+SECTION ANSWER
+www.sub.sub.example.com. IN A 10.20.30.40
+www.sub.sub.example.com. 3600 IN RRSIG A 5 5 3600 20181230101756 20181130101756 14511 sub.sub.example.com. iOC5Z07Y0wVz7U9rRUqUNZeBopg2GVInGSR7qfn6bhSrvygmhKdayL1Y SZ3urbmXRrv3syTb61Iqy4N6Di2Swj4sLmdUaSobyIzWAQ6XZwKHXBRc 5yDjigDXSR7TTMSSSzQpYtR1P3tIFT5Ppdp4xAiX0CgjQlDs29fPUaQ9 Vx4= ;{id = 30899}
+ENTRY_END
+
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.sub.sub.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+www.sub.sub.example.com. IN A
+SECTION ANSWER
+www.sub.sub.example.com. IN A 10.20.30.40
+www.sub.sub.example.com. 3600 IN RRSIG A 5 5 3600 20181230101756 20181130101756 14511 sub.sub.example.com. iOC5Z07Y0wVz7U9rRUqUNZeBopg2GVInGSR7qfn6bhSrvygmhKdayL1Y SZ3urbmXRrv3syTb61Iqy4N6Di2Swj4sLmdUaSobyIzWAQ6XZwKHXBRc 5yDjigDXSR7TTMSSSzQpYtR1P3tIFT5Ppdp4xAiX0CgjQlDs29fPUaQ9 Vx4= ;{id = 30899}
+ENTRY_END
+
+; remove pending ns.blabla.com AAAA msg
+STEP 30 QUERY
+ENTRY_BEGIN
+REPLY RD DO CD
+SECTION QUESTION
+ns.blabla.com. IN AAAA
+ENTRY_END
+
+; recursion happens here.
+STEP 40 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD CD RA DO NOERROR
+SECTION QUESTION
+ns.blabla.com. IN AAAA
+SECTION ANSWER
+SECTION AUTHORITY
+com. IN SOA com. com. 2009100100 28800 7200 604800 3600
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/black_prime.rpl b/tests/integration/deckard/sets/resolver/black_prime.rpl
new file mode 100644
index 0000000..65a67bb
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/black_prime.rpl
@@ -0,0 +1,302 @@
+do-ip6: no
+
+; config options
+; The island of trust is at example.com
+;server:
+ trust-anchor: "example.com. 3600 IN DS 62942 7 1 04D720E4CAB3C4AC2049BE5EE7599BF920269624 "
+val-override-date: "20181130121801"
+; target-fetch-policy: "0 0 0 0 0"
+; fake-sha1: yes
+
+;stub-zone:
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+query-minimization: off
+CONFIG_END
+
+SCENARIO_BEGIN Test validator with blacklist for prime response
+; the data response needs a blacklist action as well, since it also
+; comes from an 'expired signatures' name server.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.blabla.com. IN A
+SECTION ANSWER
+ns.blabla.com. IN A 1.2.3.5
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.blabla.com. IN AAAA
+SECTION AUTHORITY
+com. IN SOA com. com. 2009100100 28800 7200 604800 3600
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. IN NS ns.blabla.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+; no ns.blabla.com, try that later
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+example.com. IN NS ns.blabla.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20181230101800 20181130101800 62942 example.com. INVALIDvKtMSxWX+8K3dKRRvFHxAcxe0bHtpZjiFn9dpUpsvo/CZ2nSV rrZ53C6WRIKA0i7Z2Q7CzeKjnOpXqVXfZ2rZyFaWQs23AbXLAIhpoG+7 g+9xCRkXED5kgkCjsyg5CmzFx5G68bZj9IOZNna/ZNfij8vaiJPO3IW9 mmM= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101800 20181130101800 62942 example.com. INVALIDU8LVsNTK2uldzRU89po6ti/vnp94h9lo7TYI7Z+lGtBIXK23H nFL4/DBbcAChUB0xTeXRm6LHt3lI2M/cpGCQ7fcByBzv7cFDeIuJ3BZ9 ufbJBkmTmw9292zjMoDqP+9tGgSIDV3amJdP39C0VC1qhOjG+crIlEKB XIg= ;{id = 2854}
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.com. IN A
+SECTION ANSWER
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101800 20181130101800 62942 example.com. INVALIDU8LVsNTK2uldzRU89po6ti/vnp94h9lo7TYI7Z+lGtBIXK23H nFL4/DBbcAChUB0xTeXRm6LHt3lI2M/cpGCQ7fcByBzv7cFDeIuJ3BZ9 ufbJBkmTmw9292zjMoDqP+9tGgSIDV3amJdP39C0VC1qhOjG+crIlEKB XIg= ;{id = 2854}
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.com. IN AAAA
+SECTION ANSWER
+SECTION ADDITIONAL
+ns.example.com. IN NSEC oof.example.com. NSEC RRSIG A
+ns.example.com. 3600 IN RRSIG NSEC 7 3 3600 20181230101800 20181130101800 62942 example.com. INVALIDawCQcg5K+EPIlU4ekUeIqvDSxV7ZaPsC2P4IxJaLpCUMQJk54 aF+XCCpedBTbAoe8WBws/mxySdY2CYt0WfUjUhl6hWt+sINX8XXoH87O NKidHTC7z+/lzzEYoqMEJxCc7KdNxM3Y+6QaHshZzg4NYFiw5P62oOev NaE= ;{id = 2854}
+ENTRY_END
+
+; response to DNSKEY priming query
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN DNSKEY
+SECTION ANSWER
+example.com. 3600 IN DNSKEY 256 3 7 AwEAAdBMHE0Pz/DMrzxL+gmpcUrQJr7lLVUreB+a1rQrMicGVF/5/88V Hu+kDKaPvRHq4x22Ja8ZMmiNrfozQWoszAzhMlupQX1vXF44aSZbElqZ DNYhLyIaC8xBUPJ3qrcBPZOILu/2ylTx3xXfSPDVoX2L8fqODOOIjCim lumwbb5H ;{id = 2854 (zsk), size = 1688b}
+example.com. 3600 IN RRSIG DNSKEY 7 2 3600 20181230101800 20181130101800 62942 example.com. INVALIDgZL/1kcEKkulqQF7XlT8kCswdtvH3coWkCBGGprMYZ5sJKGP9 mk8lcEXG9vXujUz++YtJ2l1U23MMAr8stnoJ0xRlTMO2VwoLlTnW68ng F12n5eeQs7GNq1hDz6xnLAF0flpI8qfTIABqnw8M7LmYoqEbwNHPtVDt nfE= ;{id = 2854}
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. IN NS ns.blabla.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20181230101800 20181130101800 62942 example.com. INVALIDvKtMSxWX+8K3dKRRvFHxAcxe0bHtpZjiFn9dpUpsvo/CZ2nSV rrZ53C6WRIKA0i7Z2Q7CzeKjnOpXqVXfZ2rZyFaWQs23AbXLAIhpoG+7 g+9xCRkXED5kgkCjsyg5CmzFx5G68bZj9IOZNna/ZNfij8vaiJPO3IW9 mmM= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101800 20181130101800 62942 example.com. INVALIDU8LVsNTK2uldzRU89po6ti/vnp94h9lo7TYI7Z+lGtBIXK23H nFL4/DBbcAChUB0xTeXRm6LHt3lI2M/cpGCQ7fcByBzv7cFDeIuJ3BZ9 ufbJBkmTmw9292zjMoDqP+9tGgSIDV3amJdP39C0VC1qhOjG+crIlEKB XIg= ;{id = 2854}
+ENTRY_END
+
+; response to query of interest
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+www.example.com. 3600 IN RRSIG A 7 3 3600 20181230101800 20181130101800 62942 example.com. INVALIDQDlhENCeWp7RaqU6N0CaVPCgOJLpdkVh7+Q6swyKe/Ponmgia SZ44kBtXXt91EIsaJgDU/Rhwq7zCmHT1XOHGNdNjPfHdOAOjtL42rVKU lnhS0rjcFn4SN9zgE1kiQIiu3zgIlkimNaL6JqgtUpbaIrTE6Ol9PMWU 6v8= ;{id = 2854}
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. IN NS ns.blabla.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20181230101800 20181130101800 62942 example.com. INVALIDvKtMSxWX+8K3dKRRvFHxAcxe0bHtpZjiFn9dpUpsvo/CZ2nSV rrZ53C6WRIKA0i7Z2Q7CzeKjnOpXqVXfZ2rZyFaWQs23AbXLAIhpoG+7 g+9xCRkXED5kgkCjsyg5CmzFx5G68bZj9IOZNna/ZNfij8vaiJPO3IW9 mmM= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101800 20181130101800 62942 example.com. INVALIDU8LVsNTK2uldzRU89po6ti/vnp94h9lo7TYI7Z+lGtBIXK23H nFL4/DBbcAChUB0xTeXRm6LHt3lI2M/cpGCQ7fcByBzv7cFDeIuJ3BZ9 ufbJBkmTmw9292zjMoDqP+9tGgSIDV3amJdP39C0VC1qhOjG+crIlEKB XIg= ;{id = 2854}
+ENTRY_END
+RANGE_END
+
+; ns.blabla.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.5
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+example.com. IN NS ns.blabla.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20181230101800 20181130101800 62942 example.com. qmB12jqvKtMSxWX+8K3dKRRvFHxAcxe0bHtpZjiFn9dpUpsvo/CZ2nSV rrZ53C6WRIKA0i7Z2Q7CzeKjnOpXqVXfZ2rZyFaWQs23AbXLAIhpoG+7 g+9xCRkXED5kgkCjsyg5CmzFx5G68bZj9IOZNna/ZNfij8vaiJPO3IW9 mmM= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101800 20181130101800 62942 example.com. KDQYC0xU8LVsNTK2uldzRU89po6ti/vnp94h9lo7TYI7Z+lGtBIXK23H nFL4/DBbcAChUB0xTeXRm6LHt3lI2M/cpGCQ7fcByBzv7cFDeIuJ3BZ9 ufbJBkmTmw9292zjMoDqP+9tGgSIDV3amJdP39C0VC1qhOjG+crIlEKB XIg= ;{id = 2854}
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.com. IN A
+SECTION ANSWER
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101800 20181130101800 62942 example.com. KDQYC0xU8LVsNTK2uldzRU89po6ti/vnp94h9lo7TYI7Z+lGtBIXK23H nFL4/DBbcAChUB0xTeXRm6LHt3lI2M/cpGCQ7fcByBzv7cFDeIuJ3BZ9 ufbJBkmTmw9292zjMoDqP+9tGgSIDV3amJdP39C0VC1qhOjG+crIlEKB XIg= ;{id = 2854}
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.com. IN AAAA
+SECTION ANSWER
+SECTION ADDITIONAL
+ns.example.com. IN NSEC oof.example.com. NSEC RRSIG A
+ns.example.com. 3600 IN RRSIG NSEC 7 3 3600 20181230101800 20181130101800 62942 example.com. j4fGEdXawCQcg5K+EPIlU4ekUeIqvDSxV7ZaPsC2P4IxJaLpCUMQJk54 aF+XCCpedBTbAoe8WBws/mxySdY2CYt0WfUjUhl6hWt+sINX8XXoH87O NKidHTC7z+/lzzEYoqMEJxCc7KdNxM3Y+6QaHshZzg4NYFiw5P62oOev NaE= ;{id = 2854}
+ENTRY_END
+
+; response to DNSKEY priming query
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN DNSKEY
+SECTION ANSWER
+example.com. 3600 IN DNSKEY 256 3 7 AwEAAdBMHE0Pz/DMrzxL+gmpcUrQJr7lLVUreB+a1rQrMicGVF/5/88V Hu+kDKaPvRHq4x22Ja8ZMmiNrfozQWoszAzhMlupQX1vXF44aSZbElqZ DNYhLyIaC8xBUPJ3qrcBPZOILu/2ylTx3xXfSPDVoX2L8fqODOOIjCim lumwbb5H ;{id = 2854 (zsk), size = 1688b}
+example.com. 3600 IN RRSIG DNSKEY 7 2 3600 20181230101800 20181130101800 62942 example.com. KECGylKgZL/1kcEKkulqQF7XlT8kCswdtvH3coWkCBGGprMYZ5sJKGP9 mk8lcEXG9vXujUz++YtJ2l1U23MMAr8stnoJ0xRlTMO2VwoLlTnW68ng F12n5eeQs7GNq1hDz6xnLAF0flpI8qfTIABqnw8M7LmYoqEbwNHPtVDt nfE= ;{id = 2854}
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. IN NS ns.blabla.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20181230101800 20181130101800 62942 example.com. qmB12jqvKtMSxWX+8K3dKRRvFHxAcxe0bHtpZjiFn9dpUpsvo/CZ2nSV rrZ53C6WRIKA0i7Z2Q7CzeKjnOpXqVXfZ2rZyFaWQs23AbXLAIhpoG+7 g+9xCRkXED5kgkCjsyg5CmzFx5G68bZj9IOZNna/ZNfij8vaiJPO3IW9 mmM= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101800 20181130101800 62942 example.com. KDQYC0xU8LVsNTK2uldzRU89po6ti/vnp94h9lo7TYI7Z+lGtBIXK23H nFL4/DBbcAChUB0xTeXRm6LHt3lI2M/cpGCQ7fcByBzv7cFDeIuJ3BZ9 ufbJBkmTmw9292zjMoDqP+9tGgSIDV3amJdP39C0VC1qhOjG+crIlEKB XIg= ;{id = 2854}
+ENTRY_END
+
+; response to query of interest
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+www.example.com. 3600 IN RRSIG A 7 3 3600 20181230101800 20181130101800 62942 example.com. cN4kzlqQDlhENCeWp7RaqU6N0CaVPCgOJLpdkVh7+Q6swyKe/Ponmgia SZ44kBtXXt91EIsaJgDU/Rhwq7zCmHT1XOHGNdNjPfHdOAOjtL42rVKU lnhS0rjcFn4SN9zgE1kiQIiu3zgIlkimNaL6JqgtUpbaIrTE6Ol9PMWU 6v8= ;{id = 2854}
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. IN NS ns.blabla.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20181230101800 20181130101800 62942 example.com. qmB12jqvKtMSxWX+8K3dKRRvFHxAcxe0bHtpZjiFn9dpUpsvo/CZ2nSV rrZ53C6WRIKA0i7Z2Q7CzeKjnOpXqVXfZ2rZyFaWQs23AbXLAIhpoG+7 g+9xCRkXED5kgkCjsyg5CmzFx5G68bZj9IOZNna/ZNfij8vaiJPO3IW9 mmM= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101800 20181130101800 62942 example.com. KDQYC0xU8LVsNTK2uldzRU89po6ti/vnp94h9lo7TYI7Z+lGtBIXK23H nFL4/DBbcAChUB0xTeXRm6LHt3lI2M/cpGCQ7fcByBzv7cFDeIuJ3BZ9 ufbJBkmTmw9292zjMoDqP+9tGgSIDV3amJdP39C0VC1qhOjG+crIlEKB XIg= ;{id = 2854}
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH opcode rcode flags question answer
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+www.example.com. 3600 IN RRSIG A 7 3 3600 20181230101800 20181130101800 62942 example.com. cN4kzlqQDlhENCeWp7RaqU6N0CaVPCgOJLpdkVh7+Q6swyKe/Ponmgia SZ44kBtXXt91EIsaJgDU/Rhwq7zCmHT1XOHGNdNjPfHdOAOjtL42rVKU lnhS0rjcFn4SN9zgE1kiQIiu3zgIlkimNaL6JqgtUpbaIrTE6Ol9PMWU 6v8= ;{id = 2854}
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+; remove pending ns.blabla.com AAAA msg
+STEP 30 QUERY
+ENTRY_BEGIN
+REPLY RD DO CD
+SECTION QUESTION
+ns.blabla.com. IN AAAA
+ENTRY_END
+
+; recursion happens here.
+STEP 40 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD CD RA DO NOERROR
+SECTION QUESTION
+ns.blabla.com. IN AAAA
+SECTION ANSWER
+SECTION AUTHORITY
+com. IN SOA com. com. 2009100100 28800 7200 604800 3600
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/fwd_val_cname_sibling.rpl b/tests/integration/deckard/sets/resolver/fwd_val_cname_sibling.rpl
new file mode 100644
index 0000000..df8079c
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/fwd_val_cname_sibling.rpl
@@ -0,0 +1,168 @@
+ trust-anchor: ". IN DS 20326 8 2 E06D44B80B8F1D39A95C0B0D7C65D08458E880409BBC683457104237C7F8EC8D"
+ val-override-date: 20201021100500
+ forward-addr: 192.0.2.1
+CONFIG_END
+
+SCENARIO_BEGIN CNAME points to a sibling domain in a separate zone on the same auth server. (Forwarding test case.)
+
+; forwarder
+RANGE_BEGIN 0 1000000
+ ADDRESS 192.0.2.1
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR RD RA CD NOERROR
+SECTION QUESTION
+. IN DNSKEY
+SECTION ANSWER
+. 172655 IN DNSKEY 256 3 8 AwEAAfC/6HLClwss6h7rPfoG2cliv4/S PJRd2HPEglRsvKZRbPP2RLfiobeAkczc dqaD5q8loEt14lcTgDqwzOISZ3YvSVkM 4JRMFwKzcjukKo5CsDVbMmhTD0C0yxWI CRQ1M+Y5/XkZAT7mt4cb3fWcN9xgyq1w EXQX+zdLQHrNEVQSiL5SoA5cOtCSoQ45 n8bKDXdw/0jjP9Rw1FVKsdzLVkQSrVMm 8k30WUkHm/SK/n/954KENkdQOA6Li2vO 9nicQdegyAkDeNJCdPN/p3jEhCTQLyO4 AlAmyaPcDHeeo7OXr/VsYu4NTDde9hBu S0zx/rewD+BvSnmnNHNmH2FjUE8=
+. 172655 IN DNSKEY 257 3 8 AwEAAaz/tAm8yTn4Mfeh5eyI96WSVexT BAvkMgJzkKTOiW1vkIbzxeF3+/4RgWOq 7HrxRixHlFlExOLAJr5emLvN7SWXgnLh 4+B5xQlNVz8Og8kvArMtNROxVQuCaSnI DdD5LKyWbRd2n9WGe2R8PzgCmr3EgVLr jyBxWezF0jLHwVN8efS3rCj/EWgvIWgb 9tarpVUDK/b58Da+sqqls3eNbuv7pr+e oZG+SrDK6nWeL3c6H5Apxz7LjVc1uTId sIXxuOLYA4/ilBmSVIzuDWfdRUfhHdY6 +cn8HFRm+2hM8AnXGXws9555KrUB5qih ylGa8subX2Nn6UwNR1AkUTV74bU=
+. 172655 IN RRSIG DNSKEY 8 0 172800 20201111000000 20201021000000 20326 . UfytpVL3Ka5rmqF/Lm/9frJl/ygXTjW0 MEaGgecsmHbmLfTrJF3XAgPS5Tp/xc9T kaDf9HCEzk48R4cfHOI22Ul9AnyBGZX7 FiVfVo0NaseADRwt6G3K9jsMwHMIuVmA MTnvFfR32/+CwMMgmXGhBXdZJVXR71aA RAMKZlSgJK7DlOia8h2yC+RaWK0DvHML wqyA+uwAeLxixmrtu3Olj2Rzmx2MSNDZ ZUP9I+vghq7K0rzK7CYrXiAgY2q5Wvwt KjJPw6T/qB8Ojqru/XN1LxSa2zYeITAq 58IyijgLr6EupAdA6HB3iPPfhHGKiwaf smcfcRcds90WfxG7UQFAMg==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR RD RA CD NOERROR
+SECTION QUESTION
+nET. IN DS
+SECTION ANSWER
+nET. 86255 IN DS 35886 8 2 7862b27f5f516ebe19680444d4ce5e762981931842c465f00236401d8bd973ee
+nET. 86255 IN RRSIG DS 8 1 86400 20201103050000 20201021040000 26116 . lIxl/gQWfvagN52COhMXKbDfchR30HWF DiVQKdr9AmJNFm+zf1DLp3+NE0IPgI/d XtUP68KWReE1DXfX21aejVAYkIF/4tMo jgXMgbL8qIX4qXGjC/d+L7qx/v0p9u1l wheBjDM4+YjwvuGIOBme0bcqGtZnUukz PUjmE09XB7GJ3lVjcpP5ixbn61haLTYs etBntl0+xKCtkSO6GkLidp24U78pa+T4 YPM91hC3P+d50wXoAo07p+BHvSv7wJDA eZ5FBnuAXzBY9he5MGOWFYidN+RkmiHN y/7kQAndgvzoEtcYtzdpkB3TWS+0CEfY Gz6Qtp/Sll7VG9CTGUoqFw==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR RD RA CD NXDOMAIN
+SECTION QUESTION
+_tA-4F66. IN NULL
+SECTION AUTHORITY
+. 86255 IN NSEC aaa. NS SOA RRSIG NSEC DNSKEY
+. 86255 IN RRSIG NSEC 8 0 86400 20201103050000 20201021040000 26116 . aFw/f+wkcYkkNG6C2+mo5qtwIbYwc/RK obIHPfc169RhFZjY7lsd5Tc/t4mc8uxf k/3CIeyQ7F2gnmfy4xrHYdIwsTrrrZPQ 76GWRrugqZjK+1Haj8ceLiAq2qnvXUk2 LaUbbsozXW/7agSCCcX6cFJU0gTUEoJT mFcrlBZs6m8LowGus/1j2EBpXE9Na1+Q abI0I66ALRa3fdizo+EHplyVBuYqb1vW KSV1oANfjbkWb/YToiIupMP59xzkOhCh kodjxr/LFL8Z84Q/dCvF7zUjk8jw97wj KSc2eWTUA5E1bjdFTNtoaEFh9wdhi99f v6/3f/MfBZ1Wycm92KCXoA==
+. 86255 IN RRSIG SOA 8 0 86400 20201103050000 20201021040000 26116 . cOrDJLvyiYhtFH+bRInd3YAKzur8j6Xa V2pJ4rDFjT4ILWdMaijIuUwJRsAgSP+9 sQyhgKPB0AgSji+vCLf60Jsb7UThgkd+ Xxk5puEYi6le7X2UyRp4YmsrU/AjLTlQ nKGtKfhQ0aar3/I3IDLCwAM445Fc5Pc/ 8Cn+9aSH1Fd1MUhcWadDzqc7FlGzYqpm ERIaOynVIzko5JDDcqzR8URx03jNpKbE Wap85SLT2EDAyTDt6ZG/7nArnaKQDLnd QGpvPLRc1077UPpFBJssOH1NYt9Opx/d +n5YYOxqiRn7dlZ90BgRK+8yBF9FVBUd AxO7BpWVJX2Zd5rE0Qqvqw==
+. 86255 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2020102100 1800 900 604800 86400
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR RD RA CD NOERROR
+SECTION QUESTION
+NeT. IN DNSKEY
+SECTION ANSWER
+NeT. 86255 IN DNSKEY 256 3 8 AQOt+wvb6EAal6dwI2ItyurnFlcdFJk5 Y6jzSr8oJwibSIN5cs75UYYBwXxhRBxS /M5DQ0/Ti9WRC7B5P9LuwxgG+/+fdakf Sy7jjWDRlRLRphg28YDU/F1Cmh6klcNX n8qjptqLAbqIp3t6mRRhk8W+YpD/TjXG eFXJB9o3pVF58lXhC9jCjS3wL9i98k8/ 2GzvqsdK13JAXX2ZFEDPFdH1
+NeT. 86255 IN DNSKEY 257 3 8 AQOYBnzqWXIEj6mlgXg4LWC0HP2n8eK8 XqgHlmJ/69iuIHsa1TrHDG6TcOra/pye GKwH0nKZhTmXSuUFGh9BCNiwVDuyyb6O BGy2Nte9Kr8NwWg4q+zhSoOf4D+gC9dE zg0yFdwT0DKEvmNPt0K4jbQDS4Yimb+u PKuF6yieWWrPYYCrv8C9KC8JMze2uT6N uWBfsl2fDUoV4l65qMww06D7n+p7Rbdw WkAZ0fA63mXVXBZF6kpDtsYD7SUB9jhh fLQE/r85bvg3FaSs5Wi2BaqN06SzGWI1 DHu7axthIOeHwg00zxlhTpoYCH0ldoQz +S65zWYi/fRJiyLSBb6JZOvn
+NeT. 86255 IN RRSIG DNSKEY 8 1 86400 20201026162830 20201011162330 35886 net. S/TJUz3GCaTkCcZ/sXB6+GR3Dl1I4qSx 57CjqRzFc53CvuLiPhGoXX3l2kwx528P nswsOGOiifweIsPJ6VmKmi/Gz4PbqOR3 qGje74yksbxuIKp0/O/kO3G2G83bomaS Uy/aL/xqY3VgVEWA6p8bZItIjgMHugJa rgdtw/3NCHs/5R2S9hHkR6Quywi2hVNp aSt1ETSIK+JOw3BtQ3dckrxGA9E399TZ PLLouDv89kwYYF2B/aHrgD+XkpJBzCz6 0Q8XTx+aanvl4LskAVefry1gByhAayMO e62p/wDRj8CvZwL0PwM6oOZke0TFmHE7 HYR27XhbU752i8bNwm5LOQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR RD RA CD NOERROR
+SECTION QUESTION
+Dns-OARC.nET. IN DS
+SECTION ANSWER
+Dns-OARC.nET. 86259 IN DS 20899 8 1 6714ff6879371c5dc19bb0389f9d497520448a2e
+Dns-OARC.nET. 86259 IN RRSIG DS 8 2 86400 20201028065126 20201021054126 15314 net. EPgbOCokif3vBrPW0vF/en/xfVF7yADV Z+I9mz8MXNAVALDz9TyytRPNvHWfMZaR dSlCDBlwvtFqhDk3xxQzw9tgsDo8x23y rihX2hFLN8JzEbi85SPolcpPO4TLOV+2 5GWO7PXgeImRe7FMv71QhXv3f18T8sVg zm+Ip+SEOe5UBpt5eV/DHP7nHzusgOcC ulsZy2GhMbO4SZFMAsDzdw==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR RD RA CD NOERROR
+SECTION QUESTION
+dnS-OArc.NeT. IN DNSKEY
+SECTION ANSWER
+dnS-OArc.NeT. 120 IN DNSKEY 256 3 8 AwEAAZfYbwjqZ7RPJpY2Ww6gBymYzKoP hZop/jzt4mU7fjJs212EdYcPHGyO2Kv+ 01V6g3Ad81lAKL4LdqdiJuqp6K8KBm93 SyOkZss+JQtQ+NU41KXcn9/v0lGw0zzx 0yiEkhN8mtGI3rFcAxWumzCeDGiscBno uc8PCK0gz/WGxGOF
+dnS-OArc.NeT. 120 IN DNSKEY 256 3 8 AwEAAdbQVxljv2fkmYFzMbOAmMOPbwIh ui66dZdF4Z5z1HXmYYVaStzrEoDo2yij 2ZLsMdGuyflZyupR7rAWY0uhg39UinEo c8h8Jy3pvq0/g+/evNyfk0yM6kElf9Ef Lo9+0GNMC7c7xwXBdFWNGielE6XrWc30 7V8ywOa23FhmqCuz
+dnS-OArc.NeT. 120 IN DNSKEY 257 3 8 AwEAAcjX8/jP9Vuyuoniz3BX3riZ1QD1 GR2OF0yxVPcqLfzLMqbagFx6k9lWtmcC nkb3P56dsd+OqtQPAvTkoB2NloTdlIvh 0I/upTg40a53AHeKdUv7x56AP7kLQVB/ n2HvTfTcy/k0bsumn7KHJQgE6PT2alVc x9sOs80Nn6ntVttO7QyJUtJ2sVbC75Yw IlzbtmQ5HDm7mQ7W0E3/4w472ClEKcoN Hmvg+6C/dp2biUEI66ngck/YHhJzR+6r /rQ0p8LWFjtkWdvhm4ow7TseAsw48VMW 0tAkcGl1bo+VoToLOLEs4bGIiiTXjuDj xr3AqIvASNtVwDbPG98xBEK6BX394Tvi JYC4hmPzKMgWKDnzdjXOzHxQVWKz55vt jR/9I5bq/IfuAV9UreoB+oPBCY1sNK3e 6AEKQBR+F+X9h0a5jn+bmnYZ0C0+MsV9 yT7jS9a764NBYczW9fd4uqHfcsmQ8Rfu HBVvRpBsqGSJd/WHHhkHRhW2bE+BQLXs X85izbt66RUzRlDNmjTG9i4CYhKIHqLu fYRmSQ4ralJC3kpVUxixjZtegLG8AmFx Li6/qiQ08mN69WpYAKYEFMYksqrq5RcX 23KsxNhoq5xc/o9rlKmOT+KA47dcldbq t5hDo02z2ohB/ZymPgWjwoaHfhkL093M 4Dfk8n9PVq1e5bzx
+dnS-OArc.NeT. 120 IN RRSIG DNSKEY 8 2 120 20201119101102 20201020091102 12093 dns-oarc.net. fXMVPntr6cNE2mYil/UWRakU/y1+18qk 1+0LSf3uGypeCFAGRKI4p0i9jGnQjECc c+2EVOw4uVj/8BG2cZOhIBFy9w2i076p 3F6bLqBo/OmtyuytNhT/+au6ghdmU+yb inb0uSe6HFyM2z+wceJL+OLJ85VOCTUw 4edkxeQ49lw=
+dnS-OArc.NeT. 120 IN RRSIG DNSKEY 8 2 120 20201119101102 20201020091102 20899 dns-oarc.net. UFb7etfvWhS6ebbVTfleAH55pSfqbSwv hGsk61dZ4RuFkqcpHczM9Iq2yf9oI19G SzdnQXlpJyoXS8UFr/w2WlFJ9g8iJztF 1FUus2WSmsNeEX58CDDtVXImJAY73lFN W0znzlzdSEu5ctgo5TljI6RUx4REF4ia 5ePCsR6fi/aqkWNxg1CDrL3kiX4EeZkj 4lz6BnNYwhu4vcp6HEQ6jIiOqQwZ4khX 3CiZpx6bEgpE5jQaY4kHBfowPhci7Fre n7hfPNWKlaPvrCcTd7VCrm1lqKq4lM/J EqGUUPD7nHVDCxi+09T/KEXCPXChpb7k r7fxrMQaSKGnKXVCcSErK8MzysnuOdBm Uq8JpSMH/H/xzMNHY3gn1JNQs5jJlIMQ b/hT0wG0+BGHcHotn7+RTqYlbUaOWIfm /KoGai+jelQmpLzy1+UZRWpSp/SSFHfG gsFK5mlaZFi4NZBs9Nbt6N13tjTzGLx0 Yzo/aWWBHYRRHQEas38mWrDnnLzakaID 4z0nKIgwAk8akkPG2mUkqkhNjWOGLjaB 0gc+iYcmh7d11+rd1AcME7PwtnSCVII2 Eb/rMwRiKZSvXOEF1EXe1+w/7aLb8sB/ 4cPKcoCNihEN0P4OK8e3uwUxak3lRLRD B6cdFDio228k8kzYVxRVWAgm02UQ1Ogn cECehi3gze8=
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR RD RA CD NOERROR
+SECTION QUESTION
+RATe.DNs-OARC.NEt. IN A
+SECTION ANSWER
+RATe.DNs-OARC.NEt. 120 IN CNAME dev.DNs-OARC.NEt.
+RATe.DNs-OARC.NEt. 120 IN RRSIG CNAME 8 3 120 20201119101102 20201020091102 12093 dns-oarc.net. CKVz/VGf0tLvcU6WUoklgwGyZVovcADy DAZiy1O2OI0UFutX6eo2xLTMKrK7cQTI dMpdxw26Du5Fl1HPh6ObDqORBT2pIc1d LJOeNVPDwECPC4F/ZeAZV5ZGNePbi345 iBa+K7aK/iZH0U3c+PH2AX3xApX/w/SP dhNT/qe3SW4=
+dev.DNs-OARC.NEt. 161 IN A 77.72.225.245
+dev.DNs-OARC.NEt. 161 IN RRSIG A 8 3 300 20201118021701 20201021021701 25608 dev.dns-oarc.net. gdXgdTbF22sM8CIYgiDysnUTAJ41Hb52 SsUoz7Gt+e9P69IrYnH9R4gSgujFGqbb Oe9Xj5gAlMGiMzbjXOQ28KMnJxK+Bar6 VJbbGFm93CUL9eGb6CS8D6UVakJjK9MC hPIp69w8eJxuKOvFbizBvwyR40nHsDvz uHox7yhNFuk=
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR RD RA CD NOERROR
+SECTION QUESTION
+rATe.DNs-OarC.Net. IN DS
+SECTION ANSWER
+dev.DNs-OarC.Net. 300 IN DS 65191 8 2 7202e542ec7177402116be5eabb2366eaa1eee8196a03934b2870a11df174102
+dev.DNs-OarC.Net. 300 IN RRSIG DS 8 3 300 20201119101102 20201020091102 12093 dns-oarc.net. OMptv0I6JsGqguumbAgy2yQ6vSS9PpPj d2kSZK0Ajq1tCMeYuMx745fUoHraSmQ1 BSa2vp/6V/kRUfP2/APXKDRuMUPA18xm /ZREDW7i8ZB/f+hRX2G/CPXi0JgKp0Zc mEj1HRJH7Kd5fLBJBXgNn72wauh8SqcR mkOcLC/ntJE=
+rATe.DNs-OarC.Net. 120 IN CNAME dev.DNs-OarC.Net.
+rATe.DNs-OarC.Net. 120 IN RRSIG CNAME 8 3 120 20201119101102 20201020091102 12093 dns-oarc.net. CKVz/VGf0tLvcU6WUoklgwGyZVovcADy DAZiy1O2OI0UFutX6eo2xLTMKrK7cQTI dMpdxw26Du5Fl1HPh6ObDqORBT2pIc1d LJOeNVPDwECPC4F/ZeAZV5ZGNePbi345 iBa+K7aK/iZH0U3c+PH2AX3xApX/w/SP dhNT/qe3SW4=
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR RD RA CD NOERROR
+SECTION QUESTION
+dev.dns-oarc.net. IN A
+SECTION ANSWER
+dev.dns-oarc.net. 161 IN A 77.72.225.245
+dev.dns-oarc.net. 161 IN RRSIG A 8 3 300 20201118021701 20201021021701 25608 dev.dns-oarc.net. gdXgdTbF22sM8CIYgiDysnUTAJ41Hb52 SsUoz7Gt+e9P69IrYnH9R4gSgujFGqbb Oe9Xj5gAlMGiMzbjXOQ28KMnJxK+Bar6 VJbbGFm93CUL9eGb6CS8D6UVakJjK9MC hPIp69w8eJxuKOvFbizBvwyR40nHsDvz uHox7yhNFuk=
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR RD RA CD NOERROR
+SECTION QUESTION
+dev.dns-oarc.net. IN DS
+SECTION ANSWER
+dev.DNs-OarC.Net. 300 IN DS 65191 8 2 7202e542ec7177402116be5eabb2366eaa1eee8196a03934b2870a11df174102
+dev.DNs-OarC.Net. 300 IN RRSIG DS 8 3 300 20201119101102 20201020091102 12093 dns-oarc.net. OMptv0I6JsGqguumbAgy2yQ6vSS9PpPj d2kSZK0Ajq1tCMeYuMx745fUoHraSmQ1 BSa2vp/6V/kRUfP2/APXKDRuMUPA18xm /ZREDW7i8ZB/f+hRX2G/CPXi0JgKp0Zc mEj1HRJH7Kd5fLBJBXgNn72wauh8SqcR mkOcLC/ntJE=
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR RD RA CD NOERROR
+SECTION QUESTION
+dev.dns-oarc.net. IN DNSKEY
+SECTION ANSWER
+dev.dns-oarc.net. 300 IN DNSKEY 256 3 8 AwEAAaIM29u9BqEVYbmmB8CEIFNjpRMZG+ry/RMoYW/u7IOuE+4kW4+k QJf3uOnFQHq+/sVUfHRUwEvWnz0oxxPneXo10QnTMXowvK7TbLN3ftQZ t5Ohl8CLAOXPlx3XTvqU+lfZunB3BqrmlXyAT85/H6UR0IEO8tvGlDbn WQYzU82R
+dev.dns-oarc.net. 300 IN DNSKEY 257 3 8 AwEAAb8OxdNwuYv1oVBBqMO2Ee8/y56uEFi+b6oaVZ5n8Sf+tYlPpJvc sEtBnpn/5iuzZNdySQuvSzUCbnfiH0wtDVSsM09GQyUm1aOOjPWW77NV l+ATseXTf4qQEcL8ncEAg3YOFHUKKdvs+QA455evaeN/mQ1RpBHx0h+f /weG4a1dsCtlCDf1CQgt43u7D8wVdwkJsO3dIrO0uiRa0m9Pgx2FSLCx dIunj46wm9x2TN+uF4mCwvzcQZrEPSCpqVVZeag4g58+TafjMy8p5k3D YOyQscocXNv446Qcgi7mHj7kqcfX1n2Q683KD5N2qcFVDBrERzDv3TdR cMd0QzUfACk=
+dev.dns-oarc.net. 300 IN RRSIG DNSKEY 8 3 300 20201118021701 20201021021701 65191 dev.dns-oarc.net. S8ynO7TrZvfZWymJcARFl7x7gRsBQ+EN7tK4+nvylUI5i5CoH4/X4kk0 NJk6R+ThczC70k81YEsXslhWkHU8Rk4rzEihmY6S7aGPWX8kgPa4QRIO ULemPX8tLi4zUnuLNVjx3JrBvuIqBnbcLglU893e8zCpB/YcX50h/nNI FH7GJtKqzgXy82UZl9Br6HcqyVX80r75/ApK3DLk7qdCk6oe+sPQrWp5 LT8ZRauJO+cP9dN0srn0nlUollFC3wzB9wfYacqfcxtElpmzb50KbMY0 ejmGzFKnO0vzk9v5PhPUuXqKuRMIPPd9Vubk9rLFH/9wGP/uDLHY0woH RoJRiw==
+ENTRY_END
+
+
+RANGE_END
+
+STEP 10 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+rate.dns-oarc.net. IN A
+ENTRY_END
+
+STEP 11 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH opcode rcode flags question answer
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+rate.dns-oarc.net. IN A
+SECTION ANSWER
+rate.dns-oarc.net. 120 IN CNAME dev.dns-oarc.net.
+rate.dns-oarc.net. 120 IN RRSIG CNAME 8 3 120 20201119101102 20201020091102 12093 dns-oarc.net. CKVz/VGf0tLvcU6WUoklgwGyZVovcADy DAZiy1O2OI0UFutX6eo2xLTMKrK7cQTI dMpdxw26Du5Fl1HPh6ObDqORBT2pIc1d LJOeNVPDwECPC4F/ZeAZV5ZGNePbi345 iBa+K7aK/iZH0U3c+PH2AX3xApX/w/SP dhNT/qe3SW4=
+dev.dns-oarc.net. 161 IN A 77.72.225.245
+dev.dns-oarc.net. 161 IN RRSIG A 8 3 300 20201118021701 20201021021701 25608 dev.dns-oarc.net. gdXgdTbF22sM8CIYgiDysnUTAJ41Hb52 SsUoz7Gt+e9P69IrYnH9R4gSgujFGqbb Oe9Xj5gAlMGiMzbjXOQ28KMnJxK+Bar6 VJbbGFm93CUL9eGb6CS8D6UVakJjK9MC hPIp69w8eJxuKOvFbizBvwyR40nHsDvz uHox7yhNFuk=
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/iter_badglue.rpl b/tests/integration/deckard/sets/resolver/iter_badglue.rpl
new file mode 100644
index 0000000..17f99a3
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/iter_badglue.rpl
@@ -0,0 +1,274 @@
+do-ip6: no
+
+stub-addr: 1.1.1.1
+CONFIG_END
+
+SCENARIO_BEGIN Test not using cached glue records
+
+;root server
+RANGE_BEGIN 0 100
+ ADDRESS 1.1.1.1
+
+ENTRY_BEGIN
+MATCH opcode qname qtype
+ADJUST copy_id
+REPLY QR RD NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS k.root-servers.net.
+SECTION ADDITIONAL
+k.root-servers.net. IN A 1.1.1.1
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR RD NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION AUTHORITY
+com. IN NS ns.com.
+SECTION ADDITIONAL
+ns.com. IN A 2.2.2.2
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR RD NOERROR
+SECTION QUESTION
+net. IN NS
+SECTION AUTHORITY
+net. IN NS ns.net.
+SECTION ADDITIONAL
+ns.net IN A 3.3.3.3
+ENTRY_END
+RANGE_END
+
+;ns.com.
+RANGE_BEGIN 0 100
+ ADDRESS 2.2.2.2
+ENTRY_BEGIN
+MATCH opcode qname qtype
+ADJUST copy_id copy_query
+REPLY QR RD NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS ns.com.
+SECTION ADDITIONAL
+ns.com. IN A 2.2.2.2
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname qtype
+ADJUST copy_id
+REPLY QR RD NOERROR
+SECTION QUESTION
+ns.com. IN A
+SECTION ANSWER
+ns.com. IN A 2.2.2.2
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname qtype
+ADJUST copy_id
+REPLY QR RD NOERROR
+SECTION QUESTION
+ns.com. IN AAAA
+SECTION AUTHORITY
+com. IN SOA . . 1487352364 1800 900 604800 86400
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR RD NOERROR
+SECTION QUESTION
+a.com. IN NS
+SECTION AUTHORITY
+a.com. IN NS ns-a.net. ; out-of-bailwick nameservers
+a.com. IN NS ns-obsolete.net.
+SECTION ADDITIONAL
+ns-a.net. IN A 4.4.4.4
+ns-obsolete.net. IN A 6.6.6.6 ; dead address in glue records
+ENTRY_END
+RANGE_END
+
+;ns.net.
+RANGE_BEGIN 0 100
+ ADDRESS 3.3.3.3
+ENTRY_BEGIN
+MATCH opcode qname qtype
+ADJUST copy_id
+REPLY QR RD NOERROR
+SECTION QUESTION
+net. IN NS
+SECTION ANSWER
+net. IN NS ns.net.
+SECTION ADDITIONAL
+ns.net. IN A 3.3.3.3
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname qtype
+ADJUST copy_id
+REPLY QR RD NOERROR
+SECTION QUESTION
+ns.net. IN A
+SECTION ANSWER
+ns.net. IN A 3.3.3.3
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname qtype
+ADJUST copy_id
+REPLY QR RD NOERROR
+SECTION QUESTION
+ns.net. IN AAAA
+SECTION AUTHORITY
+net. IN SOA . . 1487352364 1800 900 604800 86400
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR RD NOERROR
+SECTION QUESTION
+root-servers.net. IN A
+SECTION AUTHORITY
+net. 900 IN SOA . . 1487352364 1800 900 604800 86400
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RD NOERROR
+SECTION QUESTION
+k.root-servers.net. IN A
+SECTION ANSWER
+ns-a.net. IN A 1.1.1.1
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RD NOERROR
+SECTION QUESTION
+k.root-servers.net. IN AAAA
+SECTION AUTHORITY
+net. 900 IN SOA . . 1487352364 1800 900 604800 86400
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RD NOERROR
+SECTION QUESTION
+ns-a.net. IN A
+SECTION ANSWER
+ns-a.net. IN A 4.4.4.4
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RD NOERROR
+SECTION QUESTION
+ns-obsolete.net. IN A
+SECTION ANSWER
+ns-obsolete.net. IN A 9.9.9.9 ; working address
+ENTRY_END
+
+; no IPv6
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RD NOERROR
+SECTION QUESTION
+ns-a.net. IN AAAA
+SECTION AUTHORITY
+net. 900 IN SOA . . 1487352364 1800 900 604800 86400
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RD NOERROR
+SECTION QUESTION
+ns-obsolete.net. IN AAAA
+SECTION AUTHORITY
+net. 900 IN SOA . . 1487352364 1800 900 604800 86400
+ENTRY_END
+RANGE_END
+
+;ns-a.net
+RANGE_BEGIN 0 100
+ ADDRESS 4.4.4.4
+ ADDRESS 9.9.9.9
+
+ENTRY_BEGIN
+MATCH opcode qname qtype
+ADJUST copy_id
+REPLY QR RD NOERROR
+SECTION QUESTION
+a.com. IN NS
+SECTION ANSWER
+a.com. IN NS ns-a.net. ; out-of-bailwick nameservers
+a.com. IN NS ns-obsolete.net.
+SECTION ADDITIONAL
+ns-a.net. IN A 4.4.4.4
+ns-obsolete.net. IN A 9.9.9.9 ; the new (functional) address
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RD NOERROR
+SECTION QUESTION
+; phony target used to pollute resolver's cache
+www.a.com. IN A
+SECTION ANSWER
+www.a.com. IN A 5.5.5.5
+ENTRY_END
+RANGE_END
+
+; ask for phony target to pollute resolver's cache
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.a.com. IN A
+ENTRY_END
+
+; we don't actually care about this answer
+STEP 2 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.a.com. IN A
+SECTION ANSWER
+www.a.com. IN A 5.5.5.5
+ENTRY_END
+
+; check if obsolete data from glue records is returned to the client
+STEP 3 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+ns-obsolete.net. IN A
+ENTRY_END
+
+STEP 4 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+ns-obsolete.net. IN A
+SECTION ANSWER
+ns-obsolete.net. IN A 9.9.9.9 ; 6.6.6.6 should not be here
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/iter_badraw.rpl b/tests/integration/deckard/sets/resolver/iter_badraw.rpl
new file mode 100644
index 0000000..563d39f
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/iter_badraw.rpl
@@ -0,0 +1,18839 @@
+do-ip6: no
+
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN raw queries from inbound.
+
+STEP 10 QUERY
+ENTRY_BEGIN
+RAW
+00000000700240004aa200000204059801010402
+ENTRY_END
+
+STEP 20 QUERY
+ENTRY_BEGIN
+RAW
+b5c9ca3d50104320f4120000000000000000
+ENTRY_END
+
+STEP 30 QUERY
+ENTRY_BEGIN
+RAW
+b5c9ca3d5018432054550000009010c0000000010001000000000f313231393737303731323038322d330000f900010f313231393737303731323038322d330000f900ff00000000005403677373096d6963726f736f667403636f6d00403afe52403c4fd20003000000314e544c4d535350000100000097b208e0060006002b0000000b000b00200000004441525941534552564552544157414e410000
+ENTRY_END
+
+STEP 40 QUERY
+ENTRY_BEGIN
+RAW
+b5c9ca4b50114312f37f0000000000000000
+ENTRY_END
+
+STEP 50 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400026fc00000204059801010402
+ENTRY_END
+
+STEP 60 QUERY
+ENTRY_BEGIN
+RAW
+b5c9ca4c50104312f37e0000000000000000
+ENTRY_END
+
+STEP 70 QUERY
+ENTRY_BEGIN
+RAW
+b5ca72d85010432027d10000000000000000
+ENTRY_END
+
+STEP 80 QUERY
+ENTRY_BEGIN
+RAW
+b5ca72d8501843209a9300000090ff40000000010001000000000f313231393737303731323038322d320000f900010f313231393737303731323038322d320000f900ff00000000005403677373096d6963726f736f667403636f6d00403afe52403c4fd20003000000314e544c4d535350000100000097b208e0060006002b0000000b000b00200000004441525941534552564552544157414e410000
+ENTRY_END
+
+STEP 90 QUERY
+ENTRY_BEGIN
+RAW
+b5ca72e650114312273e0000000000000000
+ENTRY_END
+
+STEP 100 QUERY
+ENTRY_BEGIN
+RAW
+00000000700240006b1b00000204059801010402
+ENTRY_END
+
+STEP 110 QUERY
+ENTRY_BEGIN
+RAW
+b5ca72e750104312273d0000000000000000
+ENTRY_END
+
+STEP 120 QUERY
+ENTRY_BEGIN
+RAW
+b5cb35d550104320a8f20000000000000000
+ENTRY_END
+
+STEP 130 QUERY
+ENTRY_BEGIN
+RAW
+b5cb35d550184320a275000000907880000000010001000000000f313231393737303731323038322d320000f900010f313231393737303731323038322d320000f900ff00000000005403677373096d6963726f736f667403636f6d00403afe52403c4fd20003000000314e544c4d535350000100000097b208e0060006002b0000000b000b00200000004441525941534552564552544157414e410000
+ENTRY_END
+
+STEP 140 QUERY
+ENTRY_BEGIN
+RAW
+b5cb35e350114312a85f0000000000000000
+ENTRY_END
+
+STEP 150 QUERY
+ENTRY_BEGIN
+RAW
+b5cb35e450104312a85e0000000000000000
+ENTRY_END
+
+STEP 160 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf0362600000204057801010402
+ENTRY_END
+
+STEP 170 QUERY
+ENTRY_BEGIN
+RAW
+b5cf40235010fb906c0b0000000000000000
+ENTRY_END
+
+STEP 180 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000671b0000020405b401010402
+ENTRY_END
+
+STEP 190 QUERY
+ENTRY_BEGIN
+RAW
+b5cf40235018fb90fce000000090c500000000010001000000000e3839333335333139373538362d330000f900010e3839333335333139373538362d330000f900ff00000000005603677373096d6963726f736f667403636f6d00403afcd1403c4e510003000000334e544c4d535350000100000097b208e00b000b0028000000080008002000000057524b53544e3036484f54454c414c4d454c4f0000
+ENTRY_END
+
+STEP 200 QUERY
+ENTRY_BEGIN
+RAW
+b5d0233950104470b6550000000000000000
+ENTRY_END
+
+STEP 210 QUERY
+ENTRY_BEGIN
+RAW
+b5d023395018447066590000008e2a0f000000010001000000000f313131363639313439363937382d330000f900010f313131363639313439363937382d330000f900ff00000000005203677373096d6963726f736f667403636f6d00403afcd0403c4e5000030000002f4e544c4d535350000100000097b200c009000900260000000600060020000000544f544f524f434f524e574f524c440000
+ENTRY_END
+
+STEP 220 QUERY
+ENTRY_BEGIN
+RAW
+b5cf40315011fb826b780000000000000000
+ENTRY_END
+
+STEP 230 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf08db400000204057801010402
+ENTRY_END
+
+STEP 240 QUERY
+ENTRY_BEGIN
+RAW
+b5d0234750114462b5c40000000000000000
+ENTRY_END
+
+STEP 250 QUERY
+ENTRY_BEGIN
+RAW
+b5cf40325010fb826b770000000000000000
+ENTRY_END
+
+STEP 260 QUERY
+ENTRY_BEGIN
+RAW
+b5d0234850104462b5c30000000000000000
+ENTRY_END
+
+STEP 270 QUERY
+ENTRY_BEGIN
+RAW
+b5d0e1385010fb9022830000000000000000
+ENTRY_END
+
+STEP 280 QUERY
+ENTRY_BEGIN
+RAW
+b5d0e1385018fb908a5800000090f000000000010001000000000e3839333335333139373538362d320000f900010e3839333335333139373538362d320000f900ff00000000005603677373096d6963726f736f667403636f6d00403afcd1403c4e510003000000334e544c4d535350000100000097b208e00b000b0028000000080008002000000057524b53544e3036484f54454c414c4d454c4f0000
+ENTRY_END
+
+STEP 290 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000dff20000020405b401010402
+ENTRY_END
+
+STEP 300 QUERY
+ENTRY_BEGIN
+RAW
+b5d0e1465011fb8221f00000000000000000
+ENTRY_END
+
+STEP 310 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf0310300000204057801010402
+ENTRY_END
+
+STEP 320 QUERY
+ENTRY_BEGIN
+RAW
+b5d188c150104470c9a30000000000000000
+ENTRY_END
+
+STEP 330 QUERY
+ENTRY_BEGIN
+RAW
+b5d0e1475010fb8221ef0000000000000000
+ENTRY_END
+
+STEP 340 QUERY
+ENTRY_BEGIN
+RAW
+b5d188c1501844701fee0000008e84c9000000010001000000000f313131363639313439363937382d320000f900010f313131363639313439363937382d320000f900ff00000000005203677373096d6963726f736f667403636f6d00403afcd0403c4e5000030000002f4e544c4d535350000100000097b200c009000900260000000600060020000000544f544f524f434f524e574f524c440000
+ENTRY_END
+
+STEP 350 QUERY
+ENTRY_BEGIN
+RAW
+b5d2225d5010fb9084ab0000000000000000
+ENTRY_END
+
+STEP 360 QUERY
+ENTRY_BEGIN
+RAW
+b4745fb5501144625f360000000000000000
+ENTRY_END
+
+STEP 370 QUERY
+ENTRY_BEGIN
+RAW
+b5d2225d5018fb909e01000000903e80000000010001000000000e3839333335333139373538362d320000f900010e3839333335333139373538362d320000f900ff00000000005603677373096d6963726f736f667403636f6d00403afcd1403c4e510003000000334e544c4d535350000100000097b208e00b000b0028000000080008002000000057524b53544e3036484f54454c414c4d454c4f0000
+ENTRY_END
+
+STEP 380 QUERY
+ENTRY_BEGIN
+RAW
+b5d188cf50114462c9120000000000000000
+ENTRY_END
+
+STEP 390 QUERY
+ENTRY_BEGIN
+RAW
+b5d188d050104462c9110000000000000000
+ENTRY_END
+
+STEP 400 QUERY
+ENTRY_BEGIN
+RAW
+b5d2226b5011fb8284180000000000000000
+ENTRY_END
+
+STEP 410 QUERY
+ENTRY_BEGIN
+RAW
+b5d2226c5010fb8284170000000000000000
+ENTRY_END
+
+STEP 420 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000ad730000020405b401010402
+ENTRY_END
+
+STEP 430 QUERY
+ENTRY_BEGIN
+RAW
+b5d3163f5010447009a50000000000000000
+ENTRY_END
+
+STEP 440 QUERY
+ENTRY_BEGIN
+RAW
+b4745fb6501044625f350000000000000000
+ENTRY_END
+
+STEP 450 QUERY
+ENTRY_BEGIN
+RAW
+b5d3163f5018447005350000008edf83000000010001000000000f313131363639313439363937382d320000f900010f313131363639313439363937382d320000f900ff00000000005203677373096d6963726f736f667403636f6d00403afcd0403c4e5000030000002f4e544c4d535350000100000097b200c009000900260000000600060020000000544f544f524f434f524e574f524c440000
+ENTRY_END
+
+STEP 460 QUERY
+ENTRY_BEGIN
+RAW
+b5d3164d5011446209140000000000000000
+ENTRY_END
+
+STEP 470 QUERY
+ENTRY_BEGIN
+RAW
+b5d3164e5010446209130000000000000000
+ENTRY_END
+
+;STEP 480 QUERY
+;ENTRY_BEGIN
+;RAW
+;13f6000000010000000000001664696572656e61727473656e6f697374657277696a6b026e6c00000f0001c0
+;ENTRY_END
+
+STEP 490 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000c81100000204055001010402
+ENTRY_END
+
+STEP 500 QUERY
+ENTRY_BEGIN
+RAW
+b5d6cf7c5010451069fe0000000000000000
+ENTRY_END
+
+STEP 510 QUERY
+ENTRY_BEGIN
+RAW
+b5d6cf7c501845104c27000000931280000000010001000000000f313231393737303731323038322d330000f900010f313231393737303731323038322d330000f900ff00000000005703677373096d6963726f736f667403636f6d00403afed1403c50510003000000344e544c4d535350000100000097b200e0090009002b0000000b000b002000000046494c4553455256455231444d4e4d554c4445520000
+ENTRY_END
+
+STEP 520 QUERY
+ENTRY_BEGIN
+RAW
+b5d6cf8a5011450269680000000000000000
+ENTRY_END
+
+STEP 530 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400002c300000204055001010402
+ENTRY_END
+
+STEP 540 QUERY
+ENTRY_BEGIN
+RAW
+b5d6cf8b5010450269670000000000000000
+ENTRY_END
+
+STEP 550 QUERY
+ENTRY_BEGIN
+RAW
+b5d7afb650104510c4740000000000000000
+ENTRY_END
+
+STEP 560 QUERY
+ENTRY_BEGIN
+RAW
+b5d7afb650184510e85d00000093d1c0000000010001000000000f313231393737303731323038322d320000f900010f313231393737303731323038322d320000f900ff00000000005703677373096d6963726f736f667403636f6d00403afed1403c50510003000000344e544c4d535350000100000097b200e0090009002b0000000b000b002000000046494c4553455256455231444d4e4d554c4445520000
+ENTRY_END
+
+STEP 570 QUERY
+ENTRY_BEGIN
+RAW
+b5d7afc450114502c3de0000000000000000
+ENTRY_END
+
+STEP 580 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000463d00000204055001010402
+ENTRY_END
+
+STEP 590 QUERY
+ENTRY_BEGIN
+RAW
+b5d7afc550104502c3dd0000000000000000
+ENTRY_END
+
+STEP 600 QUERY
+ENTRY_BEGIN
+RAW
+b5d8998b501045101e190000000000000000
+ENTRY_END
+
+STEP 610 QUERY
+ENTRY_BEGIN
+RAW
+b5d8998b5018451082c2000000939100000000010001000000000f313231393737303731323038322d320000f900010f313231393737303731323038322d320000f900ff00000000005703677373096d6963726f736f667403636f6d00403afed1403c50510003000000344e544c4d535350000100000097b200e0090009002b0000000b000b002000000046494c4553455256455231444d4e4d554c4445520000
+ENTRY_END
+
+STEP 620 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf04e890000020405b401010402
+ENTRY_END
+
+STEP 630 QUERY
+ENTRY_BEGIN
+RAW
+b5d89999501145021d830000000000000000
+ENTRY_END
+
+STEP 640 QUERY
+ENTRY_BEGIN
+RAW
+b5d8999a501045021d820000000000000000
+ENTRY_END
+
+STEP 650 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400060f900000204055001010402
+ENTRY_END
+
+STEP 660 QUERY
+ENTRY_BEGIN
+RAW
+b5d95492501045107dcd0000000000000000
+ENTRY_END
+
+STEP 670 QUERY
+ENTRY_BEGIN
+RAW
+b5d954925018451062f6000000930f80000000010001000000000f313231393737303731323038322d330000f900010f313231393737303731323038322d330000f900ff00000000005703677373096d6963726f736f667403636f6d00403afed1403c50510003000000344e544c4d535350000100000097b200e0090009002b0000000b000b002000000046494c4553455256455231444d4e4d554c4445520000
+ENTRY_END
+
+STEP 680 QUERY
+ENTRY_BEGIN
+RAW
+b5d954a0501145027d370000000000000000
+ENTRY_END
+
+STEP 690 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000784600000204055001010402
+ENTRY_END
+
+STEP 700 QUERY
+ENTRY_BEGIN
+RAW
+b5d954a1501045027d360000000000000000
+ENTRY_END
+
+STEP 710 QUERY
+ENTRY_BEGIN
+RAW
+b5da034150104510e66a0000000000000000
+ENTRY_END
+
+STEP 720 QUERY
+ENTRY_BEGIN
+RAW
+b5da03415018451059540000009382c0000000010001000000000f313231393737303731323038322d320000f900010f313231393737303731323038322d320000f900ff00000000005703677373096d6963726f736f667403636f6d00403afed1403c50510003000000344e544c4d535350000100000097b200e0090009002b0000000b000b002000000046494c4553455256455231444d4e4d554c4445520000
+ENTRY_END
+
+STEP 730 QUERY
+ENTRY_BEGIN
+RAW
+b5da034f50114502e5d40000000000000000
+ENTRY_END
+
+STEP 740 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000e0de00000204055001010402
+ENTRY_END
+
+;STEP 750 QUERY
+;ENTRY_BEGIN
+;RAW
+;1f64000000010000000000000e6875676f63617273797374656d73026e6c00000f000100
+;ENTRY_END
+
+STEP 760 QUERY
+ENTRY_BEGIN
+RAW
+b5da035050104502e5d30000000000000000
+ENTRY_END
+
+STEP 770 QUERY
+ENTRY_BEGIN
+RAW
+b5dadc785010451075cb0000000000000000
+ENTRY_END
+
+STEP 780 QUERY
+ENTRY_BEGIN
+RAW
+b5dadc78501845102975000000934200000000010001000000000f313231393737303731323038322d320000f900010f313231393737303731323038322d320000f900ff00000000005703677373096d6963726f736f667403636f6d00403afed1403c50510003000000344e544c4d535350000100000097b200e0090009002b0000000b000b002000000046494c4553455256455231444d4e4d554c4445520000
+ENTRY_END
+
+STEP 790 QUERY
+ENTRY_BEGIN
+RAW
+b5dadc865011450275350000000000000000
+ENTRY_END
+
+STEP 800 QUERY
+ENTRY_BEGIN
+RAW
+b5dadc875010450275340000000000000000
+ENTRY_END
+
+STEP 810 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf04ab80000020405b401010402
+ENTRY_END
+
+STEP 820 QUERY
+ENTRY_BEGIN
+RAW
+b5dd4b595010faf076350000000000000000
+ENTRY_END
+
+STEP 830 QUERY
+ENTRY_BEGIN
+RAW
+b5dd4b595018faf05667000000931680000000010001000000000f313038323333313735383631302d330000f900010f313038323333313735383631302d330000f900ff00000000005703677373096d6963726f736f667403636f6d00403afce2403c4e620003000000344e544c4d535350000100000097b208e00a000a002a0000000a000a0020000000422d5345525645523031425552474552544a45530000
+ENTRY_END
+
+STEP 840 QUERY
+ENTRY_BEGIN
+RAW
+b5dd4b675011fae2759f0000000000000000
+ENTRY_END
+
+STEP 850 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf017e30000020405b401010402
+ENTRY_END
+
+STEP 860 QUERY
+ENTRY_BEGIN
+RAW
+b5dd4b685010fae2759e0000000000000000
+ENTRY_END
+
+STEP 870 QUERY
+ENTRY_BEGIN
+RAW
+b5de11195010faf07d9f0000000000000000
+ENTRY_END
+
+STEP 880 QUERY
+ENTRY_BEGIN
+RAW
+b5de11195018faf04852000000932d00000000010001000000000f313038323333313735383631302d320000f900010f313038323333313735383631302d320000f900ff00000000005703677373096d6963726f736f667403636f6d00403afce2403c4e620003000000344e544c4d535350000100000097b208e00a000a002a0000000a000a0020000000422d5345525645523031425552474552544a45530000
+ENTRY_END
+
+STEP 890 QUERY
+ENTRY_BEGIN
+RAW
+b5de11275011fae27d090000000000000000
+ENTRY_END
+
+STEP 900 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf0325f0000020405b401010402
+ENTRY_END
+
+STEP 910 QUERY
+ENTRY_BEGIN
+RAW
+b5de11285010fae27d080000000000000000
+ENTRY_END
+
+STEP 920 QUERY
+ENTRY_BEGIN
+RAW
+b5decd685010faf0dbcb0000000000000000
+ENTRY_END
+
+STEP 930 QUERY
+ENTRY_BEGIN
+RAW
+b5decd685018faf08b7e000000934800000000010001000000000f313038323333313735383631302d320000f900010f313038323333313735383631302d320000f900ff00000000005703677373096d6963726f736f667403636f6d00403afce2403c4e620003000000344e544c4d535350000100000097b208e00a000a002a0000000a000a0020000000422d5345525645523031425552474552544a45530000
+ENTRY_END
+
+STEP 940 QUERY
+ENTRY_BEGIN
+RAW
+b5decd765011fae2db350000000000000000
+ENTRY_END
+
+STEP 950 QUERY
+ENTRY_BEGIN
+RAW
+b5decd775010fae2db340000000000000000
+ENTRY_END
+
+STEP 960 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000ae090000020405ac01010402
+ENTRY_END
+
+STEP 970 QUERY
+ENTRY_BEGIN
+RAW
+b5e1b72b5010441069980000000000000000
+ENTRY_END
+
+STEP 980 QUERY
+ENTRY_BEGIN
+RAW
+b5e1b72b501844100ec700000094cb29000000010001000000000f313031333631323238313837342d330000f900010f313031333631323238313837342d330000f900ff00000000005803677373096d6963726f736f667403636f6d00403af729403c48a90003000000354e544c4d535350000100000097b200c00f000f002600000006000600200000004e49454c53314b52454e53434f4e53554c54414e430000
+ENTRY_END
+
+STEP 990 QUERY
+ENTRY_BEGIN
+RAW
+b5e1b7395011440269010000000000000000
+ENTRY_END
+
+STEP 1000 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000be8d0000020405ac01010402
+ENTRY_END
+
+STEP 1010 QUERY
+ENTRY_BEGIN
+RAW
+b5e1b73a5010440269000000000000000000
+ENTRY_END
+
+STEP 1020 QUERY
+ENTRY_BEGIN
+RAW
+b5e2af585010441081ee0000000000000000
+ENTRY_END
+
+STEP 1030 QUERY
+ENTRY_BEGIN
+RAW
+b5e2af58501844109df6000000945551000000010001000000000f313031333631323238313837342d320000f900010f313031333631323238313837342d320000f900ff00000000005803677373096d6963726f736f667403636f6d00403af729403c48a90003000000354e544c4d535350000100000097b200c00f000f002600000006000600200000004e49454c53314b52454e53434f4e53554c54414e430000
+ENTRY_END
+
+STEP 1040 QUERY
+ENTRY_BEGIN
+RAW
+b5e2af665011440281570000000000000000
+ENTRY_END
+
+STEP 1050 QUERY
+ENTRY_BEGIN
+RAW
+b5e2af675010440281560000000000000000
+ENTRY_END
+
+STEP 1060 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000cc0a0000020405b401010402
+ENTRY_END
+
+STEP 1070 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf089fb0000020405b401010402
+ENTRY_END
+
+STEP 1080 QUERY
+ENTRY_BEGIN
+RAW
+b5e6ab0d50104470935a0000000000000000
+ENTRY_END
+
+STEP 1090 QUERY
+ENTRY_BEGIN
+RAW
+b5e6ab0d5018447076b20000008998c8000000010001000000000f313036353135313838393432362d330000f900010f313036353135313838393432362d330000f900ff00000000004d03677373096d6963726f736f667403636f6d00403b7de0403ccf6000030000002a4e544c4d535350000100000097b200c004000400260000000600060020000000534552564552574151460000
+ENTRY_END
+
+STEP 1100 QUERY
+ENTRY_BEGIN
+RAW
+b5e73d7d5010faf0c34a0000000000000000
+ENTRY_END
+
+STEP 1110 QUERY
+ENTRY_BEGIN
+RAW
+b5e73d7d5018faf01ee00000009431b8000000010001000000000f313039393531313632373739342d330000f900010f313039393531313632373739342d330000f900ff00000000005803677373096d6963726f736f667403636f6d00403afb18403c4c980003000000354e544c4d535350000100000097b208e00e000e00270000000700070020000000544553542d41444b4148554e412d544553544c41420000
+ENTRY_END
+
+STEP 1120 QUERY
+ENTRY_BEGIN
+RAW
+b5e73d8b5011fae2c2b30000000000000000
+ENTRY_END
+
+STEP 1130 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf09e490000020405b401010402
+ENTRY_END
+
+STEP 1140 QUERY
+ENTRY_BEGIN
+RAW
+b5e6ab1b5011446292ce0000000000000000
+ENTRY_END
+
+STEP 1150 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000d7b30000020405b401010402
+ENTRY_END
+
+STEP 1160 QUERY
+ENTRY_BEGIN
+RAW
+b5e73d8c5010fae2c2b20000000000000000
+ENTRY_END
+
+STEP 1170 QUERY
+ENTRY_BEGIN
+RAW
+b5e829da5010faf0eb3a0000000000000000
+ENTRY_END
+
+STEP 1180 QUERY
+ENTRY_BEGIN
+RAW
+b5e829da5018faf0c24a00000094b73e000000010001000000000f313039393531313632373739342d320000f900010f313039393531313632373739342d320000f900ff00000000005803677373096d6963726f736f667403636f6d00403afb18403c4c980003000000354e544c4d535350000100000097b208e00e000e00270000000700070020000000544553542d41444b4148554e412d544553544c41420000
+ENTRY_END
+
+STEP 1190 QUERY
+ENTRY_BEGIN
+RAW
+b5e6ab1c5010446292cd0000000000000000
+ENTRY_END
+
+STEP 1200 QUERY
+ENTRY_BEGIN
+RAW
+b5e8ed83501044705c8b0000000000000000
+ENTRY_END
+
+STEP 1210 QUERY
+ENTRY_BEGIN
+RAW
+b5e829e85011fae2eaa30000000000000000
+ENTRY_END
+
+STEP 1220 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf067190000020405b401010402
+ENTRY_END
+
+STEP 1230 QUERY
+ENTRY_BEGIN
+RAW
+b5e8ed8350184470d094000000890918000000010001000000000f313036353135313838393432362d320000f900010f313036353135313838393432362d320000f900ff00000000004d03677373096d6963726f736f667403636f6d00403b7de0403ccf6000030000002a4e544c4d535350000100000097b200c004000400260000000600060020000000534552564552574151460000
+ENTRY_END
+
+STEP 1240 QUERY
+ENTRY_BEGIN
+RAW
+b5e829e95010fae2eaa20000000000000000
+ENTRY_END
+
+STEP 1250 QUERY
+ENTRY_BEGIN
+RAW
+b5e978885010faf0655b0000000000000000
+ENTRY_END
+
+STEP 1260 QUERY
+ENTRY_BEGIN
+RAW
+b5e978885018faf0052b00000094ee7e000000010001000000000f313039393531313632373739342d320000f900010f313039393531313632373739342d320000f900ff00000000005803677373096d6963726f736f667403636f6d00403afb18403c4c980003000000354e544c4d535350000100000097b208e00e000e00270000000700070020000000544553542d41444b4148554e412d544553544c41420000
+ENTRY_END
+
+STEP 1270 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000e51f00000204059801010402
+ENTRY_END
+
+STEP 1280 QUERY
+ENTRY_BEGIN
+RAW
+b5e8ed91501144625bff0000000000000000
+ENTRY_END
+
+STEP 1290 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400000aa0000020405b401010402
+ENTRY_END
+
+STEP 1300 QUERY
+ENTRY_BEGIN
+RAW
+b5e978965011fae264c40000000000000000
+ENTRY_END
+
+STEP 1310 QUERY
+ENTRY_BEGIN
+RAW
+b5ea6c7550104320ec370000000000000000
+ENTRY_END
+
+STEP 1320 QUERY
+ENTRY_BEGIN
+RAW
+b5e978975010fae264c30000000000000000
+ENTRY_END
+
+STEP 1330 QUERY
+ENTRY_BEGIN
+RAW
+b5e8ed92501044625bfe0000000000000000
+ENTRY_END
+
+STEP 1340 QUERY
+ENTRY_BEGIN
+RAW
+b5ea6c755018432081b900000090d180000000010001000000000f313231393737303731323038322d330000f900010f313231393737303731323038322d330000f900ff00000000005403677373096d6963726f736f667403636f6d00403afe57403c4fd70003000000314e544c4d535350000100000097b208e0060006002b0000000b000b00200000004441525941534552564552544157414e410000
+ENTRY_END
+
+STEP 1350 QUERY
+ENTRY_BEGIN
+RAW
+b5eb227d5010447050850000000000000000
+ENTRY_END
+
+STEP 1360 QUERY
+ENTRY_BEGIN
+RAW
+b5eb227d50184470f82900000089d57c000000010001000000000f313036353135313838393432362d320000f900010f313036353135313838393432362d320000f900ff00000000004d03677373096d6963726f736f667403636f6d00403b7de0403ccf6000030000002a4e544c4d535350000100000097b200c004000400260000000600060020000000534552564552574151460000
+ENTRY_END
+
+STEP 1370 QUERY
+ENTRY_BEGIN
+RAW
+b5ea6c8350114312eba40000000000000000
+ENTRY_END
+
+STEP 1380 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000ad7200000204059801010402
+ENTRY_END
+
+STEP 1390 QUERY
+ENTRY_BEGIN
+RAW
+b5eb228b501144624ff90000000000000000
+ENTRY_END
+
+STEP 1400 QUERY
+ENTRY_BEGIN
+RAW
+b5ea6c8450104312eba30000000000000000
+ENTRY_END
+
+STEP 1410 QUERY
+ENTRY_BEGIN
+RAW
+b5ebebc85010432035360000000000000000
+ENTRY_END
+
+STEP 1420 QUERY
+ENTRY_BEGIN
+RAW
+b5ebebc850184320dd3800000090c000000000010001000000000f313231393737303731323038322d320000f900010f313231393737303731323038322d320000f900ff00000000005403677373096d6963726f736f667403636f6d00403afe57403c4fd70003000000314e544c4d535350000100000097b208e0060006002b0000000b000b00200000004441525941534552564552544157414e410000
+ENTRY_END
+
+STEP 1430 QUERY
+ENTRY_BEGIN
+RAW
+b5eb228c501044624ff80000000000000000
+ENTRY_END
+
+STEP 1440 QUERY
+ENTRY_BEGIN
+RAW
+b5ebebd65011431234a30000000000000000
+ENTRY_END
+
+STEP 1450 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000ce3800000204059801010402
+ENTRY_END
+
+STEP 1460 QUERY
+ENTRY_BEGIN
+RAW
+b5ebebd75010431234a20000000000000000
+ENTRY_END
+
+STEP 1470 QUERY
+ENTRY_BEGIN
+RAW
+b5ec666650104320db5d0000000000000000
+ENTRY_END
+
+STEP 1480 QUERY
+ENTRY_BEGIN
+RAW
+b5ec6666501843202b61000000901800000000010001000000000f313231393737303731323038322d320000f900010f313231393737303731323038322d320000f900ff00000000005403677373096d6963726f736f667403636f6d00403afe57403c4fd70003000000314e544c4d535350000100000097b208e0060006002b0000000b000b00200000004441525941534552564552544157414e410000
+ENTRY_END
+
+STEP 1490 QUERY
+ENTRY_BEGIN
+RAW
+b5ec667450114312daca0000000000000000
+ENTRY_END
+
+STEP 1500 QUERY
+ENTRY_BEGIN
+RAW
+b5ec667550104312dac90000000000000000
+ENTRY_END
+
+STEP 1510 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000595000000204055001010402
+ENTRY_END
+
+STEP 1520 QUERY
+ENTRY_BEGIN
+RAW
+b5ee16d850104510b3c90000000000000000
+ENTRY_END
+
+STEP 1530 QUERY
+ENTRY_BEGIN
+RAW
+b5ee16d85018451089d00000008a63db000000010001000000000e3839333335333139373538362d330000f900010e3839333335333139373538362d330000f900ff00000000005003677373096d6963726f736f667403636f6d00403afc58403c4dd800030000002d4e544c4d535350000100000097b200e0060006002700000007000700200000004d414e55454c414150484c414e0000
+ENTRY_END
+
+STEP 1540 QUERY
+ENTRY_BEGIN
+RAW
+b5ee16e650114502b33c0000000000000000
+ENTRY_END
+
+STEP 1550 QUERY
+ENTRY_BEGIN
+RAW
+b5ee16e750104502b33b0000000000000000
+ENTRY_END
+
+STEP 1560 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000b1fd00000204055001010402
+ENTRY_END
+
+STEP 1570 QUERY
+ENTRY_BEGIN
+RAW
+b5eecbbd5010451057910000000000000000
+ENTRY_END
+
+STEP 1580 QUERY
+ENTRY_BEGIN
+RAW
+b5eecbbd50184510b3ed0000008adf85000000010001000000000e3839333335333139373538362d320000f900010e3839333335333139373538362d320000f900ff00000000005003677373096d6963726f736f667403636f6d00403afc58403c4dd800030000002d4e544c4d535350000100000097b200e0060006002700000007000700200000004d414e55454c414150484c414e0000
+ENTRY_END
+
+STEP 1590 QUERY
+ENTRY_BEGIN
+RAW
+b5eecbcb5011450257040000000000000000
+ENTRY_END
+
+STEP 1600 QUERY
+ENTRY_BEGIN
+RAW
+b5eecbcc5010450257030000000000000000
+ENTRY_END
+
+STEP 1610 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000be5c00000204055001010402
+ENTRY_END
+
+STEP 1620 QUERY
+ENTRY_BEGIN
+RAW
+b5ef8d0d50104510a29f0000000000000000
+ENTRY_END
+
+STEP 1630 QUERY
+ENTRY_BEGIN
+RAW
+b5ef8d0d501845100bfa0000008ad287000000010001000000000e3839333335333139373538362d320000f900010e3839333335333139373538362d320000f900ff00000000005003677373096d6963726f736f667403636f6d00403afc58403c4dd800030000002d4e544c4d535350000100000097b200e0060006002700000007000700200000004d414e55454c414150484c414e0000
+ENTRY_END
+
+STEP 1640 QUERY
+ENTRY_BEGIN
+RAW
+b5ef8d1b50114502a2120000000000000000
+ENTRY_END
+
+STEP 1650 QUERY
+ENTRY_BEGIN
+RAW
+b5ef8d1c50104502a2110000000000000000
+ENTRY_END
+
+STEP 1660 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf0c0510000020405b401010402
+ENTRY_END
+
+STEP 1670 QUERY
+ENTRY_BEGIN
+RAW
+b5f18dd25010faf0a9410000000000000000
+ENTRY_END
+
+STEP 1680 QUERY
+ENTRY_BEGIN
+RAW
+b5f18dd25018faf0e1bb0000008eeec4000000010001000000000f313237313331303331393633342d330000f900010f313237313331303331393633342d330000f900ff00000000005203677373096d6963726f736f667403636f6d00403b04ae403c562e00030000002f4e544c4d535350000100000097b208e0070007002800000008000800200000005345525645522d31545247524f55500000
+ENTRY_END
+
+STEP 1690 QUERY
+ENTRY_BEGIN
+RAW
+b5f18de05011fae2a8b00000000000000000
+ENTRY_END
+
+STEP 1700 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf08ee30000020405b401010402
+ENTRY_END
+
+STEP 1710 QUERY
+ENTRY_BEGIN
+RAW
+b5f18de15010fae2a8af0000000000000000
+ENTRY_END
+
+STEP 1720 QUERY
+ENTRY_BEGIN
+RAW
+b5f277b05010faf08df40000000000000000
+ENTRY_END
+
+STEP 1730 QUERY
+ENTRY_BEGIN
+RAW
+b5f277b05018faf064b80000008e517c000000010001000000000f313237313331303331393633342d320000f900010f313237313331303331393633342d320000f900ff00000000005203677373096d6963726f736f667403636f6d00403b04ae403c562e00030000002f4e544c4d535350000100000097b208e0070007002800000008000800200000005345525645522d31545247524f55500000
+ENTRY_END
+
+STEP 1740 QUERY
+ENTRY_BEGIN
+RAW
+b5f277be5011fae28d630000000000000000
+ENTRY_END
+
+STEP 1750 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf06fb10000020405b401010402
+ENTRY_END
+
+STEP 1760 QUERY
+ENTRY_BEGIN
+RAW
+b5f277bf5010fae28d620000000000000000
+ENTRY_END
+
+STEP 1770 QUERY
+ENTRY_BEGIN
+RAW
+b5f2f44d5010faf0f2240000000000000000
+ENTRY_END
+
+STEP 1780 QUERY
+ENTRY_BEGIN
+RAW
+b5f2f44d5018faf05e280000008ebc3c000000010001000000000f313237313331303331393633342d320000f900010f313237313331303331393633342d320000f900ff00000000005203677373096d6963726f736f667403636f6d00403b04ae403c562e00030000002f4e544c4d535350000100000097b208e0070007002800000008000800200000005345525645522d31545247524f55500000
+ENTRY_END
+
+STEP 1790 QUERY
+ENTRY_BEGIN
+RAW
+b5f2f45b5011fae2f1930000000000000000
+ENTRY_END
+
+STEP 1800 QUERY
+ENTRY_BEGIN
+RAW
+b5f2f45c5010fae2f1920000000000000000
+ENTRY_END
+
+;STEP 1810 QUERY
+;ENTRY_BEGIN
+;RAW
+;076a000000010000000000000e6875676f63617273797374656d73026e6c00000f000100
+;ENTRY_END
+
+STEP 1820 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf0764800000204056401010402
+ENTRY_END
+
+STEP 1830 QUERY
+ENTRY_BEGIN
+RAW
+b5f550df5010fd5c996b0000000000000000
+ENTRY_END
+
+STEP 1840 QUERY
+ENTRY_BEGIN
+RAW
+b5f550df5018fd5c34450000008ed972000000010001000000000f313231393737303731323038322d330000f900010f313231393737303731323038322d330000f900ff00000000005203677373096d6963726f736f667403636f6d00403afd93403c4f1300030000002f4e544c4d535350000100000097b208e007000700280000000800080020000000444330314856534c4f424856534c530000
+ENTRY_END
+
+STEP 1850 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000df860000020405b401010402
+ENTRY_END
+
+STEP 1860 QUERY
+ENTRY_BEGIN
+RAW
+b5f550ed5011fd4e98da0000000000000000
+ENTRY_END
+
+STEP 1870 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf05a7600000204056401010402
+ENTRY_END
+
+STEP 1880 QUERY
+ENTRY_BEGIN
+RAW
+b5f5d4c8501044707d0c0000000000000000
+ENTRY_END
+
+STEP 1890 QUERY
+ENTRY_BEGIN
+RAW
+b5f5d4c850184470f2d3000000992a30000000010001000000000f313038323333313735383631302d330000f900010f313038323333313735383631302d330000f900ff00000000005d03677373096d6963726f736f667403636f6d00403acda1403c1f2100030000003a4e544c4d535350000100000097b208e00c000c002e0000000e000e00200000005343414e4449542d5345525645525343414e44495453525630310000
+ENTRY_END
+
+STEP 1900 QUERY
+ENTRY_BEGIN
+RAW
+b5f550ee5010fd4e98d90000000000000000
+ENTRY_END
+
+STEP 1910 QUERY
+ENTRY_BEGIN
+RAW
+b5f6a7075010fd5c27700000000000000000
+ENTRY_END
+
+STEP 1920 QUERY
+ENTRY_BEGIN
+RAW
+b5f6a7075018fd5c47b70000008e5506000000010001000000000f313231393737303731323038322d320000f900010f313231393737303731323038322d320000f900ff00000000005203677373096d6963726f736f667403636f6d00403afd93403c4f1300030000002f4e544c4d535350000100000097b208e007000700280000000800080020000000444330314856534c4f424856534c530000
+ENTRY_END
+
+STEP 1930 QUERY
+ENTRY_BEGIN
+RAW
+b5f5d4d6501144627c700000000000000000
+ENTRY_END
+
+STEP 1940 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400033c60000020405b401010402
+ENTRY_END
+
+STEP 1950 QUERY
+ENTRY_BEGIN
+RAW
+b5f6a7155011fd4e26df0000000000000000
+ENTRY_END
+
+STEP 1960 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf08f9300000204056401010402
+ENTRY_END
+
+STEP 1970 QUERY
+ENTRY_BEGIN
+RAW
+b5f5d4d7501044627c6f0000000000000000
+ENTRY_END
+
+STEP 1980 QUERY
+ENTRY_BEGIN
+RAW
+b5f74ebe5010447057540000000000000000
+ENTRY_END
+
+STEP 1990 QUERY
+ENTRY_BEGIN
+RAW
+b5f6a7165010fd4e26de0000000000000000
+ENTRY_END
+
+STEP 2000 QUERY
+ENTRY_BEGIN
+RAW
+b5f74ebe5018447031ec00000099c660000000010001000000000f313038323333313735383631302d320000f900010f313038323333313735383631302d320000f900ff00000000005d03677373096d6963726f736f667403636f6d00403acda1403c1f2100030000003a4e544c4d535350000100000097b208e00c000c002e0000000e000e00200000005343414e4449542d5345525645525343414e44495453525630310000
+ENTRY_END
+
+STEP 2010 QUERY
+ENTRY_BEGIN
+RAW
+b5f822bd5010fd5ce0d50000000000000000
+ENTRY_END
+
+STEP 2020 QUERY
+ENTRY_BEGIN
+RAW
+b5f822bd5018fd5cb3f20000008ea230000000010001000000000f313231393737303731323038322d320000f900010f313231393737303731323038322d320000f900ff00000000005203677373096d6963726f736f667403636f6d00403afd93403c4f1300030000002f4e544c4d535350000100000097b208e007000700280000000800080020000000444330314856534c4f424856534c530000
+ENTRY_END
+
+STEP 2030 QUERY
+ENTRY_BEGIN
+RAW
+b5f74ecc5011446256b80000000000000000
+ENTRY_END
+
+STEP 2040 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000ebf80000020405b401010402
+ENTRY_END
+
+STEP 2050 QUERY
+ENTRY_BEGIN
+RAW
+b5f822cb5011fd4ee0440000000000000000
+ENTRY_END
+
+STEP 2060 QUERY
+ENTRY_BEGIN
+RAW
+b5f74ecd5010446256b70000000000000000
+ENTRY_END
+
+STEP 2070 QUERY
+ENTRY_BEGIN
+RAW
+b5f8bd2750104470a11c0000000000000000
+ENTRY_END
+
+STEP 2080 QUERY
+ENTRY_BEGIN
+RAW
+b5f8bd27501844703755000000990ac0000000010001000000000f313038323333313735383631302d320000f900010f313038323333313735383631302d320000f900ff00000000005d03677373096d6963726f736f667403636f6d00403acda1403c1f2100030000003a4e544c4d535350000100000097b208e00c000c002e0000000e000e00200000005343414e4449542d5345525645525343414e44495453525630310000
+ENTRY_END
+
+STEP 2090 QUERY
+ENTRY_BEGIN
+RAW
+b5f822cc5010fd4ee0430000000000000000
+ENTRY_END
+
+STEP 2100 QUERY
+ENTRY_BEGIN
+RAW
+b5f8bd3550114462a0800000000000000000
+ENTRY_END
+
+STEP 2110 QUERY
+ENTRY_BEGIN
+RAW
+b5f8bd3650104462a07f0000000000000000
+ENTRY_END
+
+STEP 2120 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000e4bf0000020405b401010402
+ENTRY_END
+
+STEP 2130 QUERY
+ENTRY_BEGIN
+RAW
+b5f94cd4501044700a360000000000000000
+ENTRY_END
+
+STEP 2140 QUERY
+ENTRY_BEGIN
+RAW
+b5f94cd450184470a70a0000008ebfc0000000010001000000000f313033303739323135313035382d330000f900010f313033303739323135313035382d330000f900ff00000000005203677373096d6963726f736f667403636f6d00403af9aa403c4b2a00030000002f4e544c4d535350000100000097b200e0080008002700000007000700200000004445454e4b41414445454e4b4141300000
+ENTRY_END
+
+STEP 2150 QUERY
+ENTRY_BEGIN
+RAW
+b5f94ce25011446209a50000000000000000
+ENTRY_END
+
+STEP 2160 QUERY
+ENTRY_BEGIN
+RAW
+b5f94ce35010446209a40000000000000000
+ENTRY_END
+
+STEP 2170 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400012600000020405b401010402
+ENTRY_END
+
+STEP 2180 QUERY
+ENTRY_BEGIN
+RAW
+b5f9f08b50104470941e0000000000000000
+ENTRY_END
+
+STEP 2190 QUERY
+ENTRY_BEGIN
+RAW
+b5f9f08b50184470b7f40000008e39c0000000010001000000000f313033303739323135313035382d320000f900010f313033303739323135313035382d320000f900ff00000000005203677373096d6963726f736f667403636f6d00403af9aa403c4b2a00030000002f4e544c4d535350000100000097b200e0080008002700000007000700200000004445454e4b41414445454e4b4141300000
+ENTRY_END
+
+STEP 2200 QUERY
+ENTRY_BEGIN
+RAW
+b5f9f09950114462938d0000000000000000
+ENTRY_END
+
+STEP 2210 QUERY
+ENTRY_BEGIN
+RAW
+b5f9f09a50104462938c0000000000000000
+ENTRY_END
+
+STEP 2220 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400009cf0000020405b401010402
+ENTRY_END
+
+STEP 2230 QUERY
+ENTRY_BEGIN
+RAW
+b5fc831750104470f8fe0000000000000000
+ENTRY_END
+
+STEP 2240 QUERY
+ENTRY_BEGIN
+RAW
+b5fc83175018447044550000008e1240000000010001000000000f313033303739323135313035382d320000f900010f313033303739323135313035382d320000f900ff00000000005203677373096d6963726f736f667403636f6d00403af9aa403c4b2a00030000002f4e544c4d535350000100000097b200e0080008002700000007000700200000004445454e4b41414445454e4b4141300000
+ENTRY_END
+
+STEP 2250 QUERY
+ENTRY_BEGIN
+RAW
+b5fc832550114462f86d0000000000000000
+ENTRY_END
+
+STEP 2260 QUERY
+ENTRY_BEGIN
+RAW
+b5fc832650104462f86c0000000000000000
+ENTRY_END
+
+STEP 2270 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400018250000020405ac01010402
+ENTRY_END
+
+STEP 2280 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf09f980000020405b401010402
+ENTRY_END
+
+STEP 2290 QUERY
+ENTRY_BEGIN
+RAW
+b5fde23c5010fbec33160000000000000000
+ENTRY_END
+
+STEP 2300 QUERY
+ENTRY_BEGIN
+RAW
+b5fd4fd4501044103aef0000000000000000
+ENTRY_END
+
+STEP 2310 QUERY
+ENTRY_BEGIN
+RAW
+b5fde23c5018fbece71a0000008d8180000000010001000000000f313131363639313439363937382d330000f900010f313131363639313439363937382d330000f900ff00000000005103677373096d6963726f736f667403636f6d00403aff2f403c50af00030000002e4e544c4d535350000100000097b208e005000500290000000900090020000000494e5445524e455431454c414e320000
+ENTRY_END
+
+STEP 2320 QUERY
+ENTRY_BEGIN
+RAW
+b5fd4fd45018441087bb00000094248d000000010001000000000f313031333631323238313837342d320000f900010f313031333631323238313837342d320000f900ff00000000005803677373096d6963726f736f667403636f6d00403af729403c48a90003000000354e544c4d535350000100000097b200c00f000f002600000006000600200000004e49454c53314b52454e53434f4e53554c54414e430000
+ENTRY_END
+
+STEP 2330 QUERY
+ENTRY_BEGIN
+RAW
+b5fde24a5011fbde32860000000000000000
+ENTRY_END
+
+STEP 2340 QUERY
+ENTRY_BEGIN
+RAW
+b5fd4fe2501144023a580000000000000000
+ENTRY_END
+
+STEP 2350 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf0eeb60000020405b401010402
+ENTRY_END
+
+STEP 2360 QUERY
+ENTRY_BEGIN
+RAW
+b5fde24b5010fbde32850000000000000000
+ENTRY_END
+
+STEP 2370 QUERY
+ENTRY_BEGIN
+RAW
+b5fd4fe3501044023a570000000000000000
+ENTRY_END
+
+STEP 2380 QUERY
+ENTRY_BEGIN
+RAW
+b5feceaf5010fbec95c00000000000000000
+ENTRY_END
+
+STEP 2390 QUERY
+ENTRY_BEGIN
+RAW
+b5feceaf5018fbecfa450000008dd200000000010001000000000f313131363639313439363937382d320000f900010f313131363639313439363937382d320000f900ff00000000005103677373096d6963726f736f667403636f6d00403aff2f403c50af00030000002e4e544c4d535350000100000097b208e005000500290000000900090020000000494e5445524e455431454c414e320000
+ENTRY_END
+
+STEP 2400 QUERY
+ENTRY_BEGIN
+RAW
+b5fecebd5011fbde95300000000000000000
+ENTRY_END
+
+STEP 2410 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf0f3a80000020405b401010402
+ENTRY_END
+
+STEP 2420 QUERY
+ENTRY_BEGIN
+RAW
+b5fecebe5010fbde952f0000000000000000
+ENTRY_END
+
+STEP 2430 QUERY
+ENTRY_BEGIN
+RAW
+b5ff56835010fbec12de0000000000000000
+ENTRY_END
+
+STEP 2440 QUERY
+ENTRY_BEGIN
+RAW
+b5ff56835018fbec30e40000008d1880000000010001000000000f313131363639313439363937382d320000f900010f313131363639313439363937382d320000f900ff00000000005103677373096d6963726f736f667403636f6d00403aff2f403c50af00030000002e4e544c4d535350000100000097b208e005000500290000000900090020000000494e5445524e455431454c414e320000
+ENTRY_END
+
+STEP 2450 QUERY
+ENTRY_BEGIN
+RAW
+b5ff56915011fbde124e0000000000000000
+ENTRY_END
+
+STEP 2460 QUERY
+ENTRY_BEGIN
+RAW
+b5ff56925010fbde124d0000000000000000
+ENTRY_END
+
+STEP 2470 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf0467900000204056401010402
+ENTRY_END
+
+STEP 2480 QUERY
+ENTRY_BEGIN
+RAW
+b6062f415010fd5c8b290000000000000000
+ENTRY_END
+
+STEP 2490 QUERY
+ENTRY_BEGIN
+RAW
+b6062f415018fd5c71600000008f9dd8000000010001000000000f313231393737303731323038322d330000f900010f313231393737303731323038322d330000f900ff00000000005303677373096d6963726f736f667403636f6d00403afcc8403c4e480003000000304e544c4d535350000100000097b208e0050005002b0000000b000b00200000005a5745524d5345525645525a5745524d0000
+ENTRY_END
+
+STEP 2500 QUERY
+ENTRY_BEGIN
+RAW
+b6062f4f5011fd4e8a970000000000000000
+ENTRY_END
+
+STEP 2510 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf0b12900000204056401010402
+ENTRY_END
+
+STEP 2520 QUERY
+ENTRY_BEGIN
+RAW
+b6062f505010fd4e8a960000000000000000
+ENTRY_END
+
+STEP 2530 QUERY
+ENTRY_BEGIN
+RAW
+b6071d2d5010fd5c07ed0000000000000000
+ENTRY_END
+
+STEP 2540 QUERY
+ENTRY_BEGIN
+RAW
+b6071d2d5018fd5c32830000008f5a7a000000010001000000000f313231393737303731323038322d320000f900010f313231393737303731323038322d320000f900ff00000000005303677373096d6963726f736f667403636f6d00403afcc8403c4e480003000000304e544c4d535350000100000097b208e0050005002b0000000b000b00200000005a5745524d5345525645525a5745524d0000
+ENTRY_END
+
+STEP 2550 QUERY
+ENTRY_BEGIN
+RAW
+b6071d3b5011fd4e075b0000000000000000
+ENTRY_END
+
+STEP 2560 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf08f9300000204056401010402
+ENTRY_END
+
+STEP 2570 QUERY
+ENTRY_BEGIN
+RAW
+b6071d3c5010fd4e075a0000000000000000
+ENTRY_END
+
+STEP 2580 QUERY
+ENTRY_BEGIN
+RAW
+b607bf705010fd5c44130000000000000000
+ENTRY_END
+
+STEP 2590 QUERY
+ENTRY_BEGIN
+RAW
+b607bf705018fd5c5fe70000008f693c000000010001000000000f313231393737303731323038322d320000f900010f313231393737303731323038322d320000f900ff00000000005303677373096d6963726f736f667403636f6d00403afcc8403c4e480003000000304e544c4d535350000100000097b208e0050005002b0000000b000b00200000005a5745524d5345525645525a5745524d0000
+ENTRY_END
+
+STEP 2600 QUERY
+ENTRY_BEGIN
+RAW
+b607bf7e5011fd4e43810000000000000000
+ENTRY_END
+
+STEP 2610 QUERY
+ENTRY_BEGIN
+RAW
+b607bf7f5010fd4e43800000000000000000
+ENTRY_END
+
+;STEP 2620 QUERY
+;ENTRY_BEGIN
+;RAW
+;0774000000010000000000000b7374617274706167696e61026e6c00000f000100
+;ENTRY_END
+
+STEP 2630 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000aa5b0000020405b401010402
+ENTRY_END
+
+STEP 2640 QUERY
+ENTRY_BEGIN
+RAW
+b6099d2a501044707f6b0000000000000000
+ENTRY_END
+
+STEP 2650 QUERY
+ENTRY_BEGIN
+RAW
+b6099d2a50184470d042000000994920000000010001000000000f313038323333313735383631302d330000f900010f313038323333313735383631302d330000f900ff00000000005d03677373096d6963726f736f667403636f6d00403acda4403c1f2400030000003a4e544c4d535350000100000097b208e00c000c002e0000000e000e00200000005343414e4449542d5345525645525343414e44495453525630310000
+ENTRY_END
+
+STEP 2660 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf04e890000020405b401010402
+ENTRY_END
+
+STEP 2670 QUERY
+ENTRY_BEGIN
+RAW
+b6099d38501144627ecf0000000000000000
+ENTRY_END
+
+STEP 2680 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000c30f0000020405b401010402
+ENTRY_END
+
+STEP 2690 QUERY
+ENTRY_BEGIN
+RAW
+b6099d39501044627ece0000000000000000
+ENTRY_END
+
+STEP 2700 QUERY
+ENTRY_BEGIN
+RAW
+b60a3e1850104470f7300000000000000000
+ENTRY_END
+
+STEP 2710 QUERY
+ENTRY_BEGIN
+RAW
+b60a3e1850184470acd800000099e550000000010001000000000f313038323333313735383631302d320000f900010f313038323333313735383631302d320000f900ff00000000005d03677373096d6963726f736f667403636f6d00403acda4403c1f2400030000003a4e544c4d535350000100000097b208e00c000c002e0000000e000e00200000005343414e4449542d5345525645525343414e44495453525630310000
+ENTRY_END
+
+STEP 2720 QUERY
+ENTRY_BEGIN
+RAW
+b60a3e2650114462f6940000000000000000
+ENTRY_END
+
+STEP 2730 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000c42f0000020405b401010402
+ENTRY_END
+
+STEP 2740 QUERY
+ENTRY_BEGIN
+RAW
+b60a3e2750104462f6930000000000000000
+ENTRY_END
+
+STEP 2750 QUERY
+ENTRY_BEGIN
+RAW
+b60b1d975010447018d10000000000000000
+ENTRY_END
+
+STEP 2760 QUERY
+ENTRY_BEGIN
+RAW
+b60b1d97501844708c99000000992530000000010001000000000f313038323333313735383631302d320000f900010f313038323333313735383631302d320000f900ff00000000005d03677373096d6963726f736f667403636f6d00403acda5403c1f2500030000003a4e544c4d535350000100000097b208e00c000c002e0000000e000e00200000005343414e4449542d5345525645525343414e44495453525630310000
+ENTRY_END
+
+STEP 2770 QUERY
+ENTRY_BEGIN
+RAW
+b60b1da55011446218350000000000000000
+ENTRY_END
+
+STEP 2780 QUERY
+ENTRY_BEGIN
+RAW
+b60b1da65010446218340000000000000000
+ENTRY_END
+
+;STEP 2790 QUERY
+;ENTRY_BEGIN
+;RAW
+;2bfa01000001000000000000056b6f726e6f026e6c00000f000100
+;ENTRY_END
+
+STEP 2800 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400088c600000204057a01010402
+ENTRY_END
+
+STEP 2810 QUERY
+ENTRY_BEGIN
+RAW
+b610654e501041b898290000000000000000
+ENTRY_END
+
+STEP 2820 QUERY
+ENTRY_BEGIN
+RAW
+b610654e501841b8139400000090d480000000010001000000000f313131363639313439363937382d330000f900010f313131363639313439363937382d330000f900ff00000000005403677373096d6963726f736f667403636f6d00403aff54403c50d40003000000314e544c4d535350000100000097b208e00a000a002700000007000700200000005345525645523453504f525443495459340000
+ENTRY_END
+
+STEP 2830 QUERY
+ENTRY_BEGIN
+RAW
+b610655c501141aa97960000000000000000
+ENTRY_END
+
+STEP 2840 QUERY
+ENTRY_BEGIN
+RAW
+b610655d501041aa97950000000000000000
+ENTRY_END
+
+STEP 2850 QUERY
+ENTRY_BEGIN
+RAW
+00000000700240008aa700000204057a01010402
+ENTRY_END
+
+STEP 2860 QUERY
+ENTRY_BEGIN
+RAW
+b6125547501041b8aa0f0000000000000000
+ENTRY_END
+
+STEP 2870 QUERY
+ENTRY_BEGIN
+RAW
+b6125547501841b804fb00000090f600000000010001000000000f313131363639313439363937382d320000f900010f313131363639313439363937382d320000f900ff00000000005403677373096d6963726f736f667403636f6d00403aff54403c50d40003000000314e544c4d535350000100000097b208e00a000a002700000007000700200000005345525645523453504f525443495459340000
+ENTRY_END
+
+STEP 2880 QUERY
+ENTRY_BEGIN
+RAW
+b6125555501141aaa97c0000000000000000
+ENTRY_END
+
+STEP 2890 QUERY
+ENTRY_BEGIN
+RAW
+b6125556501041aaa97b0000000000000000
+ENTRY_END
+
+STEP 2900 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000e70d00000204057a01010402
+ENTRY_END
+
+STEP 2910 QUERY
+ENTRY_BEGIN
+RAW
+b6132124501041b83a980000000000000000
+ENTRY_END
+
+STEP 2920 QUERY
+ENTRY_BEGIN
+RAW
+b6132124501841b871c40000009019c0000000010001000000000f313131363639313439363937382d320000f900010f313131363639313439363937382d320000f900ff00000000005403677373096d6963726f736f667403636f6d00403aff54403c50d40003000000314e544c4d535350000100000097b208e00a000a002700000007000700200000005345525645523453504f525443495459340000
+ENTRY_END
+
+STEP 2930 QUERY
+ENTRY_BEGIN
+RAW
+b6132132501141aa3a050000000000000000
+ENTRY_END
+
+STEP 2940 QUERY
+ENTRY_BEGIN
+RAW
+b6132133501041aa3a040000000000000000
+ENTRY_END
+
+STEP 2950 QUERY
+ENTRY_BEGIN
+RAW
+5b2f083d50040000c2170000000000000000
+ENTRY_END
+
+STEP 2960 QUERY
+ENTRY_BEGIN
+RAW
+0000000060025e38cd070000020405b40000
+ENTRY_END
+
+STEP 2970 QUERY
+ENTRY_BEGIN
+RAW
+b6185ae050102da004540000000000000000
+ENTRY_END
+
+STEP 2980 QUERY
+ENTRY_BEGIN
+RAW
+b6185ae050102da081160000008c4dd3000000010001000000000e3932373731323933353935342d330000f900010e3932373731323933353935342d330000f900ff00000000005203677373096d6963726f736f667403636f6d00403afd65403c4ee500030000002f4e544c4d535350000100000097b200e0050005002a0000000a000a0020000000434f4d505554455231384e504942560000
+ENTRY_END
+
+STEP 2990 QUERY
+ENTRY_BEGIN
+RAW
+b6185aee501027ec096c0000000000000000
+ENTRY_END
+
+STEP 3000 QUERY
+ENTRY_BEGIN
+RAW
+b6185aee50112da003b70000000000000000
+ENTRY_END
+
+STEP 3010 QUERY
+ENTRY_BEGIN
+RAW
+b6185aee50102da003b70000000000000000
+ENTRY_END
+
+STEP 3020 QUERY
+ENTRY_BEGIN
+RAW
+0000000060025e3872b90000020405b40000
+ENTRY_END
+
+STEP 3030 QUERY
+ENTRY_BEGIN
+RAW
+b61b831350102da081cf0000000000000000
+ENTRY_END
+
+STEP 3040 QUERY
+ENTRY_BEGIN
+RAW
+b61b831350102da0dc970000008c6fcd000000010001000000000e3932373731323933353935342d320000f900010e3932373731323933353935342d320000f900ff00000000005203677373096d6963726f736f667403636f6d00403afd66403c4ee600030000002f4e544c4d535350000100000097b200e0050005002a0000000a000a0020000000434f4d505554455231384e504942560000
+ENTRY_END
+
+STEP 3050 QUERY
+ENTRY_BEGIN
+RAW
+b61b8321501027ec86e70000000000000000
+ENTRY_END
+
+STEP 3060 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf093c900000204059801010402
+ENTRY_END
+
+STEP 3070 QUERY
+ENTRY_BEGIN
+RAW
+b61d400b5010fbb8c9700000000000000000
+ENTRY_END
+
+STEP 3080 QUERY
+ENTRY_BEGIN
+RAW
+b61d400b5018fbb85398000000946438000000010001000000000f313237313331303331393633342d330000f900010f313237313331303331393633342d330000f900ff00000000005803677373096d6963726f736f667403636f6d00403af8e4403c4a640003000000354e544c4d535350000100000097b208e0080008002d0000000d000d00200000005345525645522d434f4d5041514b4545524b4144450000
+ENTRY_END
+
+STEP 3090 QUERY
+ENTRY_BEGIN
+RAW
+b61d40195011fbaac8d90000000000000000
+ENTRY_END
+
+STEP 3100 QUERY
+ENTRY_BEGIN
+RAW
+b61d401a5010fbaac8d80000000000000000
+ENTRY_END
+
+STEP 3110 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf0abe200000204059801010402
+ENTRY_END
+
+STEP 3120 QUERY
+ENTRY_BEGIN
+RAW
+b6185aef50102da003b60000000000000000
+ENTRY_END
+
+STEP 3130 QUERY
+ENTRY_BEGIN
+RAW
+b61f52c65010fbb8cecc0000000000000000
+ENTRY_END
+
+STEP 3140 QUERY
+ENTRY_BEGIN
+RAW
+b61f52c65018fbb8714c000000944ae1000000010001000000000f313237313331303331393633342d320000f900010f313237313331303331393633342d320000f900ff00000000005803677373096d6963726f736f667403636f6d00403af8e5403c4a650003000000354e544c4d535350000100000097b208e0080008002d0000000d000d00200000005345525645522d434f4d5041514b4545524b4144450000
+ENTRY_END
+
+STEP 3150 QUERY
+ENTRY_BEGIN
+RAW
+b61f52d45011fbaace350000000000000000
+ENTRY_END
+
+STEP 3160 QUERY
+ENTRY_BEGIN
+RAW
+b61f52d55010fbaace340000000000000000
+ENTRY_END
+
+STEP 3170 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf06bd800000204059801010402
+ENTRY_END
+
+STEP 3180 QUERY
+ENTRY_BEGIN
+RAW
+b62004255010fbb8dd620000000000000000
+ENTRY_END
+
+STEP 3190 QUERY
+ENTRY_BEGIN
+RAW
+b62004255018fbb8ea1f00000094e0a3000000010001000000000f313237313331303331393633342d320000f900010f313237313331303331393633342d320000f900ff00000000005803677373096d6963726f736f667403636f6d00403af8e5403c4a650003000000354e544c4d535350000100000097b208e0080008002d0000000d000d00200000005345525645522d434f4d5041514b4545524b4144450000
+ENTRY_END
+
+STEP 3200 QUERY
+ENTRY_BEGIN
+RAW
+b62004335011fbaadccb0000000000000000
+ENTRY_END
+
+STEP 3210 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf02c3a0000020405b401010402
+ENTRY_END
+
+STEP 3220 QUERY
+ENTRY_BEGIN
+RAW
+b62004345010fbaadcca0000000000000000
+ENTRY_END
+
+STEP 3230 QUERY
+ENTRY_BEGIN
+RAW
+b620f85c5010faf0aa700000000000000000
+ENTRY_END
+
+STEP 3240 QUERY
+ENTRY_BEGIN
+RAW
+b620f85c5018faf073ec00000095ab9c000000010001000000000f313036353135313838393432362d330000f900010f313036353135313838393432362d330000f900ff00000000005903677373096d6963726f736f667403636f6d00403afc88403c4e080003000000364e544c4d535350000100000097b208e0080008002e0000000e000e002000000050484149522d52544d2d4d41494e504841495252544d0000
+ENTRY_END
+
+;STEP 3250 QUERY
+;ENTRY_BEGIN
+;RAW
+;00780000000100000000000007736d756c776562026e6c00000f0001c0
+;ENTRY_END
+
+STEP 3260 QUERY
+ENTRY_BEGIN
+RAW
+b620f86a5011fae2a9d80000000000000000
+ENTRY_END
+
+STEP 3270 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf0d0ad0000020405b401010402
+ENTRY_END
+
+STEP 3280 QUERY
+ENTRY_BEGIN
+RAW
+b620f86b5010fae2a9d70000000000000000
+ENTRY_END
+
+STEP 3290 QUERY
+ENTRY_BEGIN
+RAW
+b621d5c55010faf0717a0000000000000000
+ENTRY_END
+
+STEP 3300 QUERY
+ENTRY_BEGIN
+RAW
+b621d5c55018faf0905b000000955738000000010001000000000f313036353135313838393432362d320000f900010f313036353135313838393432362d320000f900ff00000000005903677373096d6963726f736f667403636f6d00403afc88403c4e080003000000364e544c4d535350000100000097b208e0080008002e0000000e000e002000000050484149522d52544d2d4d41494e504841495252544d0000
+ENTRY_END
+
+STEP 3310 QUERY
+ENTRY_BEGIN
+RAW
+b61b832150112da081320000000000000000
+ENTRY_END
+
+STEP 3320 QUERY
+ENTRY_BEGIN
+RAW
+b621d5d35011fae270e20000000000000000
+ENTRY_END
+
+STEP 3330 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf04b080000020405b401010402
+ENTRY_END
+
+STEP 3340 QUERY
+ENTRY_BEGIN
+RAW
+b621d5d45010fae270e10000000000000000
+ENTRY_END
+
+STEP 3350 QUERY
+ENTRY_BEGIN
+RAW
+0000000060025e38547f0000020405b40000
+ENTRY_END
+
+STEP 3360 QUERY
+ENTRY_BEGIN
+RAW
+b62289055010faf038940000000000000000
+ENTRY_END
+
+STEP 3370 QUERY
+ENTRY_BEGIN
+RAW
+b6234c9c50102da09a040000000000000000
+ENTRY_END
+
+STEP 3380 QUERY
+ENTRY_BEGIN
+RAW
+b62289055018faf0abd90000009502d4000000010001000000000f313036353135313838393432362d320000f900010f313036353135313838393432362d320000f900ff00000000005903677373096d6963726f736f667403636f6d00403afc88403c4e080003000000364e544c4d535350000100000097b208e0080008002e0000000e000e002000000050484149522d52544d2d4d41494e504841495252544d0000
+ENTRY_END
+
+STEP 3390 QUERY
+ENTRY_BEGIN
+RAW
+b62289135011fae237fc0000000000000000
+ENTRY_END
+
+STEP 3400 QUERY
+ENTRY_BEGIN
+RAW
+b62289145010fae237fb0000000000000000
+ENTRY_END
+
+STEP 3410 QUERY
+ENTRY_BEGIN
+RAW
+b6234c9c50102da027580000008c3b42000000010001000000000e3932373731323933353935342d320000f900010e3932373731323933353935342d320000f900ff00000000005203677373096d6963726f736f667403636f6d00403afd67403c4ee700030000002f4e544c4d535350000100000097b200e0050005002a0000000a000a0020000000434f4d505554455231384e504942560000
+ENTRY_END
+
+STEP 3420 QUERY
+ENTRY_BEGIN
+RAW
+b6234caa501027ec9f1c0000000000000000
+ENTRY_END
+
+STEP 3430 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf0f8cf0000020405b401010402
+ENTRY_END
+
+STEP 3440 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000deb700000204059801010402
+ENTRY_END
+
+STEP 3450 QUERY
+ENTRY_BEGIN
+RAW
+b62553b65010faf01ba80000000000000000
+ENTRY_END
+
+STEP 3460 QUERY
+ENTRY_BEGIN
+RAW
+b625d01e5010432081eb0000000000000000
+ENTRY_END
+
+STEP 3470 QUERY
+ENTRY_BEGIN
+RAW
+b625d01e50184320ce84000000850690000000010001000000000f313034373937323032303234322d330000f900010f313034373937323032303234322d330000f900ff00000000004903677373096d6963726f736f667403636f6d00403af8be403c4a3e0003000000264e544c4d535350000100000097b200e0030003002300000003000300200000004653345441300000
+ENTRY_END
+
+STEP 3480 QUERY
+ENTRY_BEGIN
+RAW
+b62553b65018faf087e70000009508d9000000010001000000000f313036353135313838393432362d330000f900010f313036353135313838393432362d330000f900ff00000000005903677373096d6963726f736f667403636f6d00403afc88403c4e080003000000364e544c4d535350000100000097b208e0080008002e0000000e000e002000000050484149522d52544d2d4d41494e504841495252544d0000
+ENTRY_END
+
+STEP 3490 QUERY
+ENTRY_BEGIN
+RAW
+b625d02c5011431281630000000000000000
+ENTRY_END
+
+STEP 3500 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000cc4600000204059801010402
+ENTRY_END
+
+STEP 3510 QUERY
+ENTRY_BEGIN
+RAW
+b625d02d5010431281620000000000000000
+ENTRY_END
+
+STEP 3520 QUERY
+ENTRY_BEGIN
+RAW
+b62553c45011fae21b100000000000000000
+ENTRY_END
+
+STEP 3530 QUERY
+ENTRY_BEGIN
+RAW
+b6267f7450104320c0230000000000000000
+ENTRY_END
+
+STEP 3540 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf0ccf40000020405b401010402
+ENTRY_END
+
+STEP 3550 QUERY
+ENTRY_BEGIN
+RAW
+b6267f74501843201fcd00000085f480000000010001000000000f313034373937323032303234322d320000f900010f313034373937323032303234322d320000f900ff00000000004903677373096d6963726f736f667403636f6d00403af8be403c4a3e0003000000264e544c4d535350000100000097b200e0030003002300000003000300200000004653345441300000
+ENTRY_END
+
+STEP 3560 QUERY
+ENTRY_BEGIN
+RAW
+b6267f8250114312bf9b0000000000000000
+ENTRY_END
+
+STEP 3570 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400033b600000204059801010402
+ENTRY_END
+
+STEP 3580 QUERY
+ENTRY_BEGIN
+RAW
+b62553c55010fae21b0f0000000000000000
+ENTRY_END
+
+STEP 3590 QUERY
+ENTRY_BEGIN
+RAW
+b6267f8350104312bf9a0000000000000000
+ENTRY_END
+
+STEP 3600 QUERY
+ENTRY_BEGIN
+RAW
+b629a6275010432000dd0000000000000000
+ENTRY_END
+
+STEP 3610 QUERY
+ENTRY_BEGIN
+RAW
+b629a62750184320d786000000857d80000000010001000000000f313034373937323032303234322d320000f900010f313034373937323032303234322d320000f900ff00000000004903677373096d6963726f736f667403636f6d00403af8be403c4a3e0003000000264e544c4d535350000100000097b200e0030003002300000003000300200000004653345441300000
+ENTRY_END
+
+STEP 3620 QUERY
+ENTRY_BEGIN
+RAW
+b629a6355011431200550000000000000000
+ENTRY_END
+
+STEP 3630 QUERY
+ENTRY_BEGIN
+RAW
+b61b832250102da081310000000000000000
+ENTRY_END
+
+STEP 3640 QUERY
+ENTRY_BEGIN
+RAW
+b627516b5010faf0f2150000000000000000
+ENTRY_END
+
+STEP 3650 QUERY
+ENTRY_BEGIN
+RAW
+b629a6365010431200540000000000000000
+ENTRY_END
+
+STEP 3660 QUERY
+ENTRY_BEGIN
+RAW
+b627516b5018faf0847000000095e1be000000010001000000000f313036353135313838393432362d320000f900010f313036353135313838393432362d320000f900ff00000000005903677373096d6963726f736f667403636f6d00403afc89403c4e090003000000364e544c4d535350000100000097b208e0080008002e0000000e000e002000000050484149522d52544d2d4d41494e504841495252544d0000
+ENTRY_END
+
+STEP 3670 QUERY
+ENTRY_BEGIN
+RAW
+b62751795011fae2f17d0000000000000000
+ENTRY_END
+
+STEP 3680 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf094de0000020405b401010402
+ENTRY_END
+
+STEP 3690 QUERY
+ENTRY_BEGIN
+RAW
+b627517a5010fae2f17c0000000000000000
+ENTRY_END
+
+STEP 3700 QUERY
+ENTRY_BEGIN
+RAW
+b62a382a5010faf0d33d0000000000000000
+ENTRY_END
+
+STEP 3710 QUERY
+ENTRY_BEGIN
+RAW
+b62a382a5018faf0b9fc000000958d5a000000010001000000000f313036353135313838393432362d320000f900010f313036353135313838393432362d320000f900ff00000000005903677373096d6963726f736f667403636f6d00403afc89403c4e090003000000364e544c4d535350000100000097b208e0080008002e0000000e000e002000000050484149522d52544d2d4d41494e504841495252544d0000
+ENTRY_END
+
+STEP 3720 QUERY
+ENTRY_BEGIN
+RAW
+b62a38385011fae2d2a50000000000000000
+ENTRY_END
+
+STEP 3730 QUERY
+ENTRY_BEGIN
+RAW
+b62a38395010fae2d2a40000000000000000
+ENTRY_END
+
+STEP 3740 QUERY
+ENTRY_BEGIN
+RAW
+b6234caa50112da099670000000000000000
+ENTRY_END
+
+;STEP 3750 QUERY
+;ENTRY_BEGIN
+;RAW
+;17a00000000100000000000009726f7a656e62757267026e6c00000f000100
+;ENTRY_END
+
+STEP 3760 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000eb890000020405b401010402
+ENTRY_END
+
+STEP 3770 QUERY
+ENTRY_BEGIN
+RAW
+b62c80b350104470dced0000000000000000
+ENTRY_END
+
+STEP 3780 QUERY
+ENTRY_BEGIN
+RAW
+b62c80b3501844706614000000979708000000010001000000000f313432353932393134323239302d330000f900010f313432353932393134323239302d330000f900ff00000000005b03677373096d6963726f736f667403636f6d00403afbe2403c4d620003000000384e544c4d535350000100000097b208e00a000a002e0000000e000e0020000000454c5354414c4144414d2d535256454c5354414c4144414d0000
+ENTRY_END
+
+STEP 3790 QUERY
+ENTRY_BEGIN
+RAW
+b62c80c150114462dc530000000000000000
+ENTRY_END
+
+STEP 3800 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000beea0000020405b401010402
+ENTRY_END
+
+STEP 3810 QUERY
+ENTRY_BEGIN
+RAW
+b6234cab50102da099660000000000000000
+ENTRY_END
+
+STEP 3820 QUERY
+ENTRY_BEGIN
+RAW
+b62c80c250104462dc520000000000000000
+ENTRY_END
+
+STEP 3830 QUERY
+ENTRY_BEGIN
+RAW
+b62f3e5b50104470f2a30000000000000000
+ENTRY_END
+
+STEP 3840 QUERY
+ENTRY_BEGIN
+RAW
+b62f3e5b50184470267d00000097ed56000000010001000000000f313432353932393134323239302d320000f900010f313432353932393134323239302d320000f900ff00000000005b03677373096d6963726f736f667403636f6d00403afbe2403c4d620003000000384e544c4d535350000100000097b208e00a000a002e0000000e000e0020000000454c5354414c4144414d2d535256454c5354414c4144414d0000
+ENTRY_END
+
+STEP 3850 QUERY
+ENTRY_BEGIN
+RAW
+b62f3e6950114462f2090000000000000000
+ENTRY_END
+
+STEP 3860 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000d4da0000020405b401010402
+ENTRY_END
+
+STEP 3870 QUERY
+ENTRY_BEGIN
+RAW
+b62f3e6a50104462f2080000000000000000
+ENTRY_END
+
+STEP 3880 QUERY
+ENTRY_BEGIN
+RAW
+b62fc881501044707e6d0000000000000000
+ENTRY_END
+
+STEP 3890 QUERY
+ENTRY_BEGIN
+RAW
+b62fc88150184470880000000097179d000000010001000000000f313432353932393134323239302d320000f900010f313432353932393134323239302d320000f900ff00000000005b03677373096d6963726f736f667403636f6d00403afbe2403c4d620003000000384e544c4d535350000100000097b208e00a000a002e0000000e000e0020000000454c5354414c4144414d2d535256454c5354414c4144414d0000
+ENTRY_END
+
+STEP 3900 QUERY
+ENTRY_BEGIN
+RAW
+b62fc88f501144627dd30000000000000000
+ENTRY_END
+
+STEP 3910 QUERY
+ENTRY_BEGIN
+RAW
+b62fc890501044627dd20000000000000000
+ENTRY_END
+
+STEP 3920 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000ace50000020405b401010402
+ENTRY_END
+
+STEP 3930 QUERY
+ENTRY_BEGIN
+RAW
+b630894a5010447095ae0000000000000000
+ENTRY_END
+
+STEP 3940 QUERY
+ENTRY_BEGIN
+RAW
+b630894a50184470b7ad00000097fe2f000000010001000000000f313432353932393134323239302d330000f900010f313432353932393134323239302d330000f900ff00000000005b03677373096d6963726f736f667403636f6d00403afbe2403c4d620003000000384e544c4d535350000100000097b208e00a000a002e0000000e000e0020000000454c5354414c4144414d2d535256454c5354414c4144414d0000
+ENTRY_END
+
+STEP 3950 QUERY
+ENTRY_BEGIN
+RAW
+b63089585011446295140000000000000000
+ENTRY_END
+
+STEP 3960 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000dc510000020405b401010402
+ENTRY_END
+
+STEP 3970 QUERY
+ENTRY_BEGIN
+RAW
+b63089595010446295130000000000000000
+ENTRY_END
+
+STEP 3980 QUERY
+ENTRY_BEGIN
+RAW
+b63142c6501044700b9e0000000000000000
+ENTRY_END
+
+STEP 3990 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000e78400000204056401010402
+ENTRY_END
+
+STEP 4000 QUERY
+ENTRY_BEGIN
+RAW
+b63142c650184470ef4d000000973d80000000010001000000000f313432353932393134323239302d320000f900010f313432353932393134323239302d320000f900ff00000000005b03677373096d6963726f736f667403636f6d00403afbe2403c4d620003000000384e544c4d535350000100000097b208e00a000a002e0000000e000e0020000000454c5354414c4144414d2d535256454c5354414c4144414d0000
+ENTRY_END
+
+STEP 4010 QUERY
+ENTRY_BEGIN
+RAW
+b631e3bb501040b0794b0000000000000000
+ENTRY_END
+
+STEP 4020 QUERY
+ENTRY_BEGIN
+RAW
+b631e3bb501840b0823000000084dc00000000010001000000000e3839333335333139373538362d330000f900010e3839333335333139373538362d330000f900ff00000000004a03677373096d6963726f736f667403636f6d00403afd0c403c4e8c0003000000274e544c4d535350000100000097b200c003000300240000000400040020000000534441374445500000
+ENTRY_END
+
+STEP 4030 QUERY
+ENTRY_BEGIN
+RAW
+b631e3c9501140a278c40000000000000000
+ENTRY_END
+
+STEP 4040 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000012100000204056401010402
+ENTRY_END
+
+STEP 4050 QUERY
+ENTRY_BEGIN
+RAW
+b63142d4501144620b040000000000000000
+ENTRY_END
+
+STEP 4060 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000cfba0000020405b401010402
+ENTRY_END
+
+STEP 4070 QUERY
+ENTRY_BEGIN
+RAW
+b631e3ca501040a278c30000000000000000
+ENTRY_END
+
+STEP 4080 QUERY
+ENTRY_BEGIN
+RAW
+b632940b501040b0e2960000000000000000
+ENTRY_END
+
+STEP 4090 QUERY
+ENTRY_BEGIN
+RAW
+b632940b501840b0167c00000084b300000000010001000000000e3839333335333139373538362d320000f900010e3839333335333139373538362d320000f900ff00000000004a03677373096d6963726f736f667403636f6d00403afd0c403c4e8c0003000000274e544c4d535350000100000097b200c003000300240000000400040020000000534441374445500000
+ENTRY_END
+
+STEP 4100 QUERY
+ENTRY_BEGIN
+RAW
+b6329419501140a2e20f0000000000000000
+ENTRY_END
+
+STEP 4110 QUERY
+ENTRY_BEGIN
+RAW
+b63142d5501044620b030000000000000000
+ENTRY_END
+
+STEP 4120 QUERY
+ENTRY_BEGIN
+RAW
+b632941a501040a2e20e0000000000000000
+ENTRY_END
+
+STEP 4130 QUERY
+ENTRY_BEGIN
+RAW
+00000000700240004da000000204056401010402
+ENTRY_END
+
+STEP 4140 QUERY
+ENTRY_BEGIN
+RAW
+b63367f650104470d9d40000000000000000
+ENTRY_END
+
+STEP 4150 QUERY
+ENTRY_BEGIN
+RAW
+b6345892501040b06a8d0000000000000000
+ENTRY_END
+
+STEP 4160 QUERY
+ENTRY_BEGIN
+RAW
+b6345892501840b0dbf2000000847580000000010001000000000e3839333335333139373538362d320000f900010e3839333335333139373538362d320000f900ff00000000004a03677373096d6963726f736f667403636f6d00403afd0c403c4e8c0003000000274e544c4d535350000100000097b200c003000300240000000400040020000000534441374445500000
+ENTRY_END
+
+STEP 4170 QUERY
+ENTRY_BEGIN
+RAW
+b63367f650184470f6430000009704c1000000010001000000000f313432353932393134323239302d320000f900010f313432353932393134323239302d320000f900ff00000000005b03677373096d6963726f736f667403636f6d00403afbe2403c4d620003000000384e544c4d535350000100000097b208e00a000a002e0000000e000e0020000000454c5354414c4144414d2d535256454c5354414c4144414d0000
+ENTRY_END
+
+STEP 4180 QUERY
+ENTRY_BEGIN
+RAW
+b63458a0501140a26a060000000000000000
+ENTRY_END
+
+STEP 4190 QUERY
+ENTRY_BEGIN
+RAW
+b63458a1501040a26a050000000000000000
+ENTRY_END
+
+STEP 4200 QUERY
+ENTRY_BEGIN
+RAW
+b633680450114462d93a0000000000000000
+ENTRY_END
+
+STEP 4210 QUERY
+ENTRY_BEGIN
+RAW
+b633680550104462d9390000000000000000
+ENTRY_END
+
+STEP 4220 QUERY
+ENTRY_BEGIN
+RAW
+000000007002ff0045bd00000204055001010402
+ENTRY_END
+
+STEP 4230 QUERY
+ENTRY_BEGIN
+RAW
+b6392e195010ff008dba0000000000000000
+ENTRY_END
+
+STEP 4240 QUERY
+ENTRY_BEGIN
+RAW
+b6392e195018ff0004e90000008fedfc000000010001000000000f313034373937323032303234322d330000f900010f313034373937323032303234322d330000f900ff00000000005303677373096d6963726f736f667403636f6d00403afdf0403c4f700003000000304e544c4d535350000100000097b208e0060006002a0000000a000a0020000000524f4353455256455232524f435655450000
+ENTRY_END
+
+;STEP 4250 QUERY
+;ENTRY_BEGIN
+;RAW
+;044f00000001000000000000076275726d656573026e6c00000f000100
+;ENTRY_END
+
+STEP 4260 QUERY
+ENTRY_BEGIN
+RAW
+b6392e275011fef28d280000000000000000
+ENTRY_END
+
+STEP 4270 QUERY
+ENTRY_BEGIN
+RAW
+000000007002ff0080c700000204055001010402
+ENTRY_END
+
+STEP 4280 QUERY
+ENTRY_BEGIN
+RAW
+b6392e285010fef28d270000000000000000
+ENTRY_END
+
+STEP 4290 QUERY
+ENTRY_BEGIN
+RAW
+b63a092c5010ff00edb00000000000000000
+ENTRY_END
+
+STEP 4300 QUERY
+ENTRY_BEGIN
+RAW
+b63a092c5018ff0081700000008fd26c000000010001000000000f313034373937323032303234322d320000f900010f313034373937323032303234322d320000f900ff00000000005303677373096d6963726f736f667403636f6d00403afdf0403c4f700003000000304e544c4d535350000100000097b208e0060006002a0000000a000a0020000000524f4353455256455232524f435655450000
+ENTRY_END
+
+STEP 4310 QUERY
+ENTRY_BEGIN
+RAW
+b63a093a5011fef2ed1e0000000000000000
+ENTRY_END
+
+STEP 4320 QUERY
+ENTRY_BEGIN
+RAW
+000000007002ff008e7500000204055001010402
+ENTRY_END
+
+STEP 4330 QUERY
+ENTRY_BEGIN
+RAW
+b63a093b5010fef2ed1d0000000000000000
+ENTRY_END
+
+STEP 4340 QUERY
+ENTRY_BEGIN
+RAW
+b63adcf25010ff0027980000000000000000
+ENTRY_END
+
+STEP 4350 QUERY
+ENTRY_BEGIN
+RAW
+b63adcf25018ff0091310000008ffc92000000010001000000000f313034373937323032303234322d320000f900010f313034373937323032303234322d320000f900ff00000000005303677373096d6963726f736f667403636f6d00403afdf0403c4f700003000000304e544c4d535350000100000097b208e0060006002a0000000a000a0020000000524f4353455256455232524f435655450000
+ENTRY_END
+
+STEP 4360 QUERY
+ENTRY_BEGIN
+RAW
+b63add005011fef227060000000000000000
+ENTRY_END
+
+STEP 4370 QUERY
+ENTRY_BEGIN
+RAW
+b63add015010fef227050000000000000000
+ENTRY_END
+
+STEP 4380 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000aeff0000020405b401010402
+ENTRY_END
+
+STEP 4390 QUERY
+ENTRY_BEGIN
+RAW
+b63fd61a5010080087590000000000000000
+ENTRY_END
+
+STEP 4400 QUERY
+ENTRY_BEGIN
+RAW
+b63fd61a501044704ae90000000000000000
+ENTRY_END
+
+STEP 4410 QUERY
+ENTRY_BEGIN
+RAW
+b63fd61a50184470a0020000008f603e000000010001000000000e3839333335333139373538362d330000f900010e3839333335333139373538362d330000f900ff00000000005503677373096d6963726f736f667403636f6d00403afc48403c4dc80003000000324e544c4d535350000100000097b208e0050005002d0000000d000d0020000000434f4d5345525645523230303041442d4d420000
+ENTRY_END
+
+STEP 4420 QUERY
+ENTRY_BEGIN
+RAW
+b63fd628501144624a570000000000000000
+ENTRY_END
+
+STEP 4430 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400083b30000020405b401010402
+ENTRY_END
+
+STEP 4440 QUERY
+ENTRY_BEGIN
+RAW
+b63fd629501044624a560000000000000000
+ENTRY_END
+
+STEP 4450 QUERY
+ENTRY_BEGIN
+RAW
+b6409f8850100800929e0000000000000000
+ENTRY_END
+
+STEP 4460 QUERY
+ENTRY_BEGIN
+RAW
+b6409f8850104470562e0000000000000000
+ENTRY_END
+
+STEP 4470 QUERY
+ENTRY_BEGIN
+RAW
+b6409f885018447052af0000008fbad6000000010001000000000e3839333335333139373538362d320000f900010e3839333335333139373538362d320000f900ff00000000005503677373096d6963726f736f667403636f6d00403afc48403c4dc80003000000324e544c4d535350000100000097b208e0050005002d0000000d000d0020000000434f4d5345525645523230303041442d4d420000
+ENTRY_END
+
+STEP 4480 QUERY
+ENTRY_BEGIN
+RAW
+b6409f9650114462559c0000000000000000
+ENTRY_END
+
+STEP 4490 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400034540000020405b401010402
+ENTRY_END
+
+STEP 4500 QUERY
+ENTRY_BEGIN
+RAW
+b6409f9750104462559b0000000000000000
+ENTRY_END
+
+STEP 4510 QUERY
+ENTRY_BEGIN
+RAW
+b64185ae501008005d180000000000000000
+ENTRY_END
+
+STEP 4520 QUERY
+ENTRY_BEGIN
+RAW
+b64185ae5010447020a80000000000000000
+ENTRY_END
+
+STEP 4530 QUERY
+ENTRY_BEGIN
+RAW
+b64185ae5018447000890000008fd776000000010001000000000e3839333335333139373538362d320000f900010e3839333335333139373538362d320000f900ff00000000005503677373096d6963726f736f667403636f6d00403afc48403c4dc80003000000324e544c4d535350000100000097b208e0050005002d0000000d000d0020000000434f4d5345525645523230303041442d4d420000
+ENTRY_END
+
+STEP 4540 QUERY
+ENTRY_BEGIN
+RAW
+b64185bc5011446220160000000000000000
+ENTRY_END
+
+STEP 4550 QUERY
+ENTRY_BEGIN
+RAW
+b64185bd5010446220150000000000000000
+ENTRY_END
+
+STEP 4560 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf0f7cc00000204056401010402
+ENTRY_END
+
+STEP 4570 QUERY
+ENTRY_BEGIN
+RAW
+b643986d5010fd5cd3130000000000000000
+ENTRY_END
+
+STEP 4580 QUERY
+ENTRY_BEGIN
+RAW
+b643986d5018fd5cc6f90000008e6466000000010001000000000f313231393737303731323038322d330000f900010f313231393737303731323038322d330000f900ff00000000005203677373096d6963726f736f667403636f6d00403afda1403c4f2100030000002f4e544c4d535350000100000097b208e007000700280000000800080020000000444330314856534c4f424856534c530000
+ENTRY_END
+
+STEP 4590 QUERY
+ENTRY_BEGIN
+RAW
+b643987b5011fd4ed2820000000000000000
+ENTRY_END
+
+STEP 4600 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf01fca00000204056401010402
+ENTRY_END
+
+STEP 4610 QUERY
+ENTRY_BEGIN
+RAW
+b643987c5010fd4ed2810000000000000000
+ENTRY_END
+
+STEP 4620 QUERY
+ENTRY_BEGIN
+RAW
+b6441ee65010fd5c74970000000000000000
+ENTRY_END
+
+STEP 4630 QUERY
+ENTRY_BEGIN
+RAW
+b6441ee65018fd5ccbe40000008e0000000000010001000000000f313231393737303731323038322d320000f900010f313231393737303731323038322d320000f900ff00000000005203677373096d6963726f736f667403636f6d00403afda2403c4f2200030000002f4e544c4d535350000100000097b208e007000700280000000800080020000000444330314856534c4f424856534c530000
+ENTRY_END
+
+STEP 4640 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000b61d0000020405b401010402
+ENTRY_END
+
+STEP 4650 QUERY
+ENTRY_BEGIN
+RAW
+b6441ef45011fd4e74060000000000000000
+ENTRY_END
+
+STEP 4660 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf08df200000204056401010402
+ENTRY_END
+
+STEP 4670 QUERY
+ENTRY_BEGIN
+RAW
+b645129150104470158b0000000000000000
+ENTRY_END
+
+STEP 4680 QUERY
+ENTRY_BEGIN
+RAW
+b645129150184470ce2a000000975080000000010001000000000f313337343338393533343733382d330000f900010f313337343338393533343733382d330000f900ff00000000005b03677373096d6963726f736f667403636f6d00403afbe6403c4d660003000000384e544c4d535350000100000097b208e00a000a002e0000000e000e0020000000454c5354414c4144414d2d535256454c5354414c4144414d0000
+ENTRY_END
+
+STEP 4690 QUERY
+ENTRY_BEGIN
+RAW
+b6441ef55010fd4e74050000000000000000
+ENTRY_END
+
+STEP 4700 QUERY
+ENTRY_BEGIN
+RAW
+b645dd1c5010fd5c24880000000000000000
+ENTRY_END
+
+STEP 4710 QUERY
+ENTRY_BEGIN
+RAW
+b645dd1c5018fd5c00410000008e7b94000000010001000000000f313231393737303731323038322d320000f900010f313231393737303731323038322d320000f900ff00000000005203677373096d6963726f736f667403636f6d00403afda2403c4f2200030000002f4e544c4d535350000100000097b208e007000700280000000800080020000000444330314856534c4f424856534c530000
+ENTRY_END
+
+STEP 4720 QUERY
+ENTRY_BEGIN
+RAW
+b645129f5011446214f10000000000000000
+ENTRY_END
+
+STEP 4730 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000a3460000020405b401010402
+ENTRY_END
+
+STEP 4740 QUERY
+ENTRY_BEGIN
+RAW
+b645dd2a5011fd4e23f70000000000000000
+ENTRY_END
+
+STEP 4750 QUERY
+ENTRY_BEGIN
+RAW
+b645dd2b5010fd4e23f60000000000000000
+ENTRY_END
+
+STEP 4760 QUERY
+ENTRY_BEGIN
+RAW
+b64512a05010446214f00000000000000000
+ENTRY_END
+
+STEP 4770 QUERY
+ENTRY_BEGIN
+RAW
+b646af605010447065e30000000000000000
+ENTRY_END
+
+STEP 4780 QUERY
+ENTRY_BEGIN
+RAW
+b646af60501844707b4300000097f4c0000000010001000000000f313337343338393533343733382d320000f900010f313337343338393533343733382d320000f900ff00000000005b03677373096d6963726f736f667403636f6d00403afbe6403c4d660003000000384e544c4d535350000100000097b208e00a000a002e0000000e000e0020000000454c5354414c4144414d2d535256454c5354414c4144414d0000
+ENTRY_END
+
+STEP 4790 QUERY
+ENTRY_BEGIN
+RAW
+b646af6e5011446265490000000000000000
+ENTRY_END
+
+STEP 4800 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400061b00000020405b401010402
+ENTRY_END
+
+STEP 4810 QUERY
+ENTRY_BEGIN
+RAW
+b646af6f5010446265480000000000000000
+ENTRY_END
+
+STEP 4820 QUERY
+ENTRY_BEGIN
+RAW
+b6473a8f50104470991d0000000000000000
+ENTRY_END
+
+STEP 4830 QUERY
+ENTRY_BEGIN
+RAW
+b6473a8f50184470b9bd00000097e980000000010001000000000f313337343338393533343733382d320000f900010f313337343338393533343733382d320000f900ff00000000005b03677373096d6963726f736f667403636f6d00403afbe6403c4d660003000000384e544c4d535350000100000097b208e00a000a002e0000000e000e0020000000454c5354414c4144414d2d535256454c5354414c4144414d0000
+ENTRY_END
+
+STEP 4840 QUERY
+ENTRY_BEGIN
+RAW
+b6473a9d5011446298830000000000000000
+ENTRY_END
+
+STEP 4850 QUERY
+ENTRY_BEGIN
+RAW
+b6473a9e5010446298820000000000000000
+ENTRY_END
+
+STEP 4860 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000e0620000020405b401010402
+ENTRY_END
+
+STEP 4870 QUERY
+ENTRY_BEGIN
+RAW
+b6498c2050104470c63c0000000000000000
+ENTRY_END
+
+STEP 4880 QUERY
+ENTRY_BEGIN
+RAW
+b6498c2050184470e776000000893428000000010001000000000f313230323539303834323839382d330000f900010f313230323539303834323839382d330000f900ff00000000004d03677373096d6963726f736f667403636f6d00403afefc403c507c00030000002a4e544c4d535350000100000097b208e0060006002400000004000400200000004e5453313233435a30300000
+ENTRY_END
+
+STEP 4890 QUERY
+ENTRY_BEGIN
+RAW
+b6498c2e50114462c5b00000000000000000
+ENTRY_END
+
+STEP 4900 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000ad0d0000020405b401010402
+ENTRY_END
+
+STEP 4910 QUERY
+ENTRY_BEGIN
+RAW
+b6498c2f50104462c5af0000000000000000
+ENTRY_END
+
+STEP 4920 QUERY
+ENTRY_BEGIN
+RAW
+b64a5b3a50104470c3cc0000000000000000
+ENTRY_END
+
+STEP 4930 QUERY
+ENTRY_BEGIN
+RAW
+b64a5b3a50184470cb9f000000894e90000000010001000000000f313230323539303834323839382d320000f900010f313230323539303834323839382d320000f900ff00000000004d03677373096d6963726f736f667403636f6d00403afefc403c507c00030000002a4e544c4d535350000100000097b208e0060006002400000004000400200000004e5453313233435a30300000
+ENTRY_END
+
+STEP 4940 QUERY
+ENTRY_BEGIN
+RAW
+b64a5b4850114462c3400000000000000000
+ENTRY_END
+
+STEP 4950 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400026120000020405b401010402
+ENTRY_END
+
+STEP 4960 QUERY
+ENTRY_BEGIN
+RAW
+b64a5b4950104462c33f0000000000000000
+ENTRY_END
+
+STEP 4970 QUERY
+ENTRY_BEGIN
+RAW
+b64b06c050104470914a0000000000000000
+ENTRY_END
+
+STEP 4980 QUERY
+ENTRY_BEGIN
+RAW
+b64b06c050184470367d00000089b130000000010001000000000f313230323539303834323839382d320000f900010f313230323539303834323839382d320000f900ff00000000004d03677373096d6963726f736f667403636f6d00403afefc403c507c00030000002a4e544c4d535350000100000097b208e0060006002400000004000400200000004e5453313233435a30300000
+ENTRY_END
+
+STEP 4990 QUERY
+ENTRY_BEGIN
+RAW
+b64b06ce5011446290be0000000000000000
+ENTRY_END
+
+STEP 5000 QUERY
+ENTRY_BEGIN
+RAW
+b64b06cf5010446290bd0000000000000000
+ENTRY_END
+
+STEP 5010 QUERY
+ENTRY_BEGIN
+RAW
+186e0000000100000000000006736d7470303603777873026e6c00000f000100
+ENTRY_END
+
+STEP 5020 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400028290000020405b401010402
+ENTRY_END
+
+STEP 5030 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000d1f10000020405b401010402
+ENTRY_END
+
+STEP 5040 QUERY
+ENTRY_BEGIN
+RAW
+b64dd61350104470c40b0000000000000000
+ENTRY_END
+
+STEP 5050 QUERY
+ENTRY_BEGIN
+RAW
+b64ea29c50104470a14a0000000000000000
+ENTRY_END
+
+STEP 5060 QUERY
+ENTRY_BEGIN
+RAW
+b64ea29c501844707cb60000009574fc000000010001000000000f313235343133303435303435302d330000f900010f313235343133303435303435302d330000f900ff00000000005903677373096d6963726f736f667403636f6d00403afd90403c4f100003000000364e544c4d535350000100000097b208e00d000d00290000000900090020000000524942454d412d4e4c5343484f434b5f524942454d410000
+ENTRY_END
+
+STEP 5070 QUERY
+ENTRY_BEGIN
+RAW
+b64dd61350184470dab1000000893cbc000000010001000000000f313230323539303834323839382d330000f900010f313230323539303834323839382d330000f900ff00000000004d03677373096d6963726f736f667403636f6d00403afefd403c507d00030000002a4e544c4d535350000100000097b208e0060006002400000004000400200000004e5453313233435a30300000
+ENTRY_END
+
+STEP 5080 QUERY
+ENTRY_BEGIN
+RAW
+b64ea2aa50114462a0b20000000000000000
+ENTRY_END
+
+STEP 5090 QUERY
+ENTRY_BEGIN
+RAW
+00000000700240008bd00000020405b401010402
+ENTRY_END
+
+STEP 5100 QUERY
+ENTRY_BEGIN
+RAW
+b64dd62150114462c37f0000000000000000
+ENTRY_END
+
+STEP 5110 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000031c0000020405b401010402
+ENTRY_END
+
+STEP 5120 QUERY
+ENTRY_BEGIN
+RAW
+b64ea2ab50104462a0b10000000000000000
+ENTRY_END
+
+STEP 5130 QUERY
+ENTRY_BEGIN
+RAW
+b64f4bce50104470b1f60000000000000000
+ENTRY_END
+
+STEP 5140 QUERY
+ENTRY_BEGIN
+RAW
+b64f4bce50184470dc7f0000009526e0000000010001000000000f313235343133303435303435302d320000f900010f313235343133303435303435302d320000f900ff00000000005903677373096d6963726f736f667403636f6d00403afd90403c4f100003000000364e544c4d535350000100000097b208e00d000d00290000000900090020000000524942454d412d4e4c5343484f434b5f524942454d410000
+ENTRY_END
+
+STEP 5150 QUERY
+ENTRY_BEGIN
+RAW
+b64dd62250104462c37e0000000000000000
+ENTRY_END
+
+STEP 5160 QUERY
+ENTRY_BEGIN
+RAW
+040b00000001000000000000116672616e6b656e656e76616e7765657274026e6c00000f000100
+ENTRY_END
+
+STEP 5170 QUERY
+ENTRY_BEGIN
+RAW
+b64fffa85010447075670000000000000000
+ENTRY_END
+
+STEP 5180 QUERY
+ENTRY_BEGIN
+RAW
+b64f4bdc50114462b15e0000000000000000
+ENTRY_END
+
+STEP 5190 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400091e30000020405b401010402
+ENTRY_END
+
+STEP 5200 QUERY
+ENTRY_BEGIN
+RAW
+b64fffa8501844702a6e000000899f5c000000010001000000000f313230323539303834323839382d320000f900010f313230323539303834323839382d320000f900ff00000000004d03677373096d6963726f736f667403636f6d00403afefd403c507d00030000002a4e544c4d535350000100000097b208e0060006002400000004000400200000004e5453313233435a30300000
+ENTRY_END
+
+STEP 5210 QUERY
+ENTRY_BEGIN
+RAW
+b64f4bdd50104462b15d0000000000000000
+ENTRY_END
+
+STEP 5220 QUERY
+ENTRY_BEGIN
+RAW
+b6509596501044706e400000000000000000
+ENTRY_END
+
+STEP 5230 QUERY
+ENTRY_BEGIN
+RAW
+b65095965018447032c5000000958ce4000000010001000000000f313235343133303435303435302d320000f900010f313235343133303435303435302d320000f900ff00000000005903677373096d6963726f736f667403636f6d00403afd90403c4f100003000000364e544c4d535350000100000097b208e00d000d00290000000900090020000000524942454d412d4e4c5343484f434b5f524942454d410000
+ENTRY_END
+
+STEP 5240 QUERY
+ENTRY_BEGIN
+RAW
+b64fffb65011446274db0000000000000000
+ENTRY_END
+
+STEP 5250 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000c1350000020405b401010402
+ENTRY_END
+
+STEP 5260 QUERY
+ENTRY_BEGIN
+RAW
+b65095a4501144626da80000000000000000
+ENTRY_END
+
+STEP 5270 QUERY
+ENTRY_BEGIN
+RAW
+b65095a5501044626da70000000000000000
+ENTRY_END
+
+STEP 5280 QUERY
+ENTRY_BEGIN
+RAW
+b64fffb75010446274da0000000000000000
+ENTRY_END
+
+STEP 5290 QUERY
+ENTRY_BEGIN
+RAW
+b651696f50104470c9b80000000000000000
+ENTRY_END
+
+STEP 5300 QUERY
+ENTRY_BEGIN
+RAW
+00000000700240006ba70000020405b401010402
+ENTRY_END
+
+STEP 5310 QUERY
+ENTRY_BEGIN
+RAW
+b651696f501844701c200000008901fc000000010001000000000f313230323539303834323839382d320000f900010f313230323539303834323839382d320000f900ff00000000004d03677373096d6963726f736f667403636f6d00403afefd403c507d00030000002a4e544c4d535350000100000097b208e0060006002400000004000400200000004e5453313233435a30300000
+ENTRY_END
+
+STEP 5320 QUERY
+ENTRY_BEGIN
+RAW
+b652266c50104470b72c0000000000000000
+ENTRY_END
+
+STEP 5330 QUERY
+ENTRY_BEGIN
+RAW
+b652266c50184470065900000095013c000000010001000000000f313235343133303435303435302d330000f900010f313235343133303435303435302d330000f900ff00000000005903677373096d6963726f736f667403636f6d00403afd90403c4f100003000000364e544c4d535350000100000097b208e00d000d00290000000900090020000000524942454d412d4e4c5343484f434b5f524942454d410000
+ENTRY_END
+
+STEP 5340 QUERY
+ENTRY_BEGIN
+RAW
+b651697d50114462c92c0000000000000000
+ENTRY_END
+
+STEP 5350 QUERY
+ENTRY_BEGIN
+RAW
+b652267a50114462b6940000000000000000
+ENTRY_END
+
+STEP 5360 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400080fc0000020405b401010402
+ENTRY_END
+
+STEP 5370 QUERY
+ENTRY_BEGIN
+RAW
+b652267b50104462b6930000000000000000
+ENTRY_END
+
+STEP 5380 QUERY
+ENTRY_BEGIN
+RAW
+b652bfd55010447033180000000000000000
+ENTRY_END
+
+STEP 5390 QUERY
+ENTRY_BEGIN
+RAW
+b651697e50104462c92b0000000000000000
+ENTRY_END
+
+STEP 5400 QUERY
+ENTRY_BEGIN
+RAW
+b652bfd550184470abf600000095d88a000000010001000000000f313235343133303435303435302d320000f900010f313235343133303435303435302d320000f900ff00000000005903677373096d6963726f736f667403636f6d00403afd90403c4f100003000000364e544c4d535350000100000097b208e00d000d00290000000900090020000000524942454d412d4e4c5343484f434b5f524942454d410000
+ENTRY_END
+
+STEP 5410 QUERY
+ENTRY_BEGIN
+RAW
+b652bfe35011446232800000000000000000
+ENTRY_END
+
+STEP 5420 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000729e0000020405b401010402
+ENTRY_END
+
+STEP 5430 QUERY
+ENTRY_BEGIN
+RAW
+b652bfe450104462327f0000000000000000
+ENTRY_END
+
+STEP 5440 QUERY
+ENTRY_BEGIN
+RAW
+b65534ff50104470af8d0000000000000000
+ENTRY_END
+
+STEP 5450 QUERY
+ENTRY_BEGIN
+RAW
+b65534ff50184470511e00000095afd8000000010001000000000f313235343133303435303435302d320000f900010f313235343133303435303435302d320000f900ff00000000005903677373096d6963726f736f667403636f6d00403afd90403c4f100003000000364e544c4d535350000100000097b208e00d000d00290000000900090020000000524942454d412d4e4c5343484f434b5f524942454d410000
+ENTRY_END
+
+STEP 5460 QUERY
+ENTRY_BEGIN
+RAW
+b655350d50114462aef50000000000000000
+ENTRY_END
+
+STEP 5470 QUERY
+ENTRY_BEGIN
+RAW
+b655350e50104462aef40000000000000000
+ENTRY_END
+
+STEP 5480 QUERY
+ENTRY_BEGIN
+RAW
+000000005004faf0e84a0000000000000000
+ENTRY_END
+
+STEP 5490 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000385c0000020405b401010402
+ENTRY_END
+
+STEP 5500 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000905f00000204057a01010402
+ENTRY_END
+
+STEP 5510 QUERY
+ENTRY_BEGIN
+RAW
+b658c73e50104470e3080000000000000000
+ENTRY_END
+
+STEP 5520 QUERY
+ENTRY_BEGIN
+RAW
+b6596076501041b8a4510000000000000000
+ENTRY_END
+
+STEP 5530 QUERY
+ENTRY_BEGIN
+RAW
+b6596076501841b838880000009068f4000000010001000000000f313034373937323032303234322d330000f900010f313034373937323032303234322d330000f900ff00000000005403677373096d6963726f736f667403636f6d00403af9b5403c4b350003000000314e544c4d535350000100000097b208e0080008002900000009000900200000004242425345525645524242422d4144414d0000
+ENTRY_END
+
+STEP 5540 QUERY
+ENTRY_BEGIN
+RAW
+b658c73e501844701fbb000000879ffc000000010001000000000e3931303533333036363737302d330000f900010e3931303533333036363737302d330000f900ff00000000004d03677373096d6963726f736f667403636f6d00403afcd7403c4e5700030000002a4e544c4d535350000100000097b200c004000400260000000600060020000000434553473031434553470000
+ENTRY_END
+
+STEP 5550 QUERY
+ENTRY_BEGIN
+RAW
+b6596084501141aaa3be0000000000000000
+ENTRY_END
+
+STEP 5560 QUERY
+ENTRY_BEGIN
+RAW
+00000000700240009c2d00000204057a01010402
+ENTRY_END
+
+STEP 5570 QUERY
+ENTRY_BEGIN
+RAW
+b6596085501041aaa3bd0000000000000000
+ENTRY_END
+
+STEP 5580 QUERY
+ENTRY_BEGIN
+RAW
+b659f314501041b81d810000000000000000
+ENTRY_END
+
+STEP 5590 QUERY
+ENTRY_BEGIN
+RAW
+b659f314501841b8513400000090ca78000000010001000000000f313034373937323032303234322d320000f900010f313034373937323032303234322d320000f900ff00000000005403677373096d6963726f736f667403636f6d00403af9b5403c4b350003000000314e544c4d535350000100000097b208e0080008002900000009000900200000004242425345525645524242422d4144414d0000
+ENTRY_END
+
+STEP 5600 QUERY
+ENTRY_BEGIN
+RAW
+b658c74c50114462e27e0000000000000000
+ENTRY_END
+
+STEP 5610 QUERY
+ENTRY_BEGIN
+RAW
+b659f322501141aa1cee0000000000000000
+ENTRY_END
+
+STEP 5620 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000ec0c0000020405b401010402
+ENTRY_END
+
+STEP 5630 QUERY
+ENTRY_BEGIN
+RAW
+00000000700240004d1c00000204057a01010402
+ENTRY_END
+
+STEP 5640 QUERY
+ENTRY_BEGIN
+RAW
+b659f323501041aa1ced0000000000000000
+ENTRY_END
+
+STEP 5650 QUERY
+ENTRY_BEGIN
+RAW
+b65ba67a501041b81b080000000000000000
+ENTRY_END
+
+STEP 5660 QUERY
+ENTRY_BEGIN
+RAW
+b65ba67a501841b8ed37000000902bfc000000010001000000000f313034373937323032303234322d320000f900010f313034373937323032303234322d320000f900ff00000000005403677373096d6963726f736f667403636f6d00403af9b5403c4b350003000000314e544c4d535350000100000097b208e0080008002900000009000900200000004242425345525645524242422d4144414d0000
+ENTRY_END
+
+STEP 5670 QUERY
+ENTRY_BEGIN
+RAW
+b658c74d50104462e27d0000000000000000
+ENTRY_END
+
+STEP 5680 QUERY
+ENTRY_BEGIN
+RAW
+b65ba688501141aa1a750000000000000000
+ENTRY_END
+
+STEP 5690 QUERY
+ENTRY_BEGIN
+RAW
+b65ad9b55010447084400000000000000000
+ENTRY_END
+
+STEP 5700 QUERY
+ENTRY_BEGIN
+RAW
+b65ba689501041aa1a740000000000000000
+ENTRY_END
+
+STEP 5710 QUERY
+ENTRY_BEGIN
+RAW
+b65ad9b550184470c70a000000879be4000000010001000000000e3931303533333036363737302d320000f900010e3931303533333036363737302d320000f900ff00000000004d03677373096d6963726f736f667403636f6d00403afcd7403c4e5700030000002a4e544c4d535350000100000097b200c004000400260000000600060020000000434553473031434553470000
+ENTRY_END
+
+STEP 5720 QUERY
+ENTRY_BEGIN
+RAW
+b65ad9c35011446283b60000000000000000
+ENTRY_END
+
+STEP 5730 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000ebab0000020405b401010402
+ENTRY_END
+
+STEP 5740 QUERY
+ENTRY_BEGIN
+RAW
+b65ad9c45010446283b50000000000000000
+ENTRY_END
+
+STEP 5750 QUERY
+ENTRY_BEGIN
+RAW
+b65c2b0a5010447032890000000000000000
+ENTRY_END
+
+STEP 5760 QUERY
+ENTRY_BEGIN
+RAW
+b65c2b0a50184470796b0000008797cc000000010001000000000e3931303533333036363737302d320000f900010e3931303533333036363737302d320000f900ff00000000004d03677373096d6963726f736f667403636f6d00403afcd7403c4e5700030000002a4e544c4d535350000100000097b200c004000400260000000600060020000000434553473031434553470000
+ENTRY_END
+
+STEP 5770 QUERY
+ENTRY_BEGIN
+RAW
+b65c2b185011446231ff0000000000000000
+ENTRY_END
+
+STEP 5780 QUERY
+ENTRY_BEGIN
+RAW
+b65c2b195010446231fe0000000000000000
+ENTRY_END
+
+STEP 5790 QUERY
+ENTRY_BEGIN
+RAW
+28ed00000001000000000000066d6978666978026e6c00000f000100
+ENTRY_END
+
+STEP 5800 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400069e100000204056401010402
+ENTRY_END
+
+STEP 5810 QUERY
+ENTRY_BEGIN
+RAW
+b6630195501040b0dd9c0000000000000000
+ENTRY_END
+
+STEP 5820 QUERY
+ENTRY_BEGIN
+RAW
+b6630195501840b030e7000000900ca7000000010001000000000f313136383233313130343533302d330000f900010f313136383233313130343533302d330000f900ff00000000005403677373096d6963726f736f667403636f6d00403afdf8403c4f780003000000314e544c4d535350000100000097b200e00a000a0027000000070007002000000044564d544b475344564d454449414b47530000
+ENTRY_END
+
+STEP 5830 QUERY
+ENTRY_BEGIN
+RAW
+b66301a3501140a2dd090000000000000000
+ENTRY_END
+
+STEP 5840 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000ecb600000204056401010402
+ENTRY_END
+
+STEP 5850 QUERY
+ENTRY_BEGIN
+RAW
+b66301a4501040a2dd080000000000000000
+ENTRY_END
+
+STEP 5860 QUERY
+ENTRY_BEGIN
+RAW
+000000007002fc00a4280000020405b401010402
+ENTRY_END
+
+STEP 5870 QUERY
+ENTRY_BEGIN
+RAW
+b663a87e501040b0b9880000000000000000
+ENTRY_END
+
+STEP 5880 QUERY
+ENTRY_BEGIN
+RAW
+b66453ed5010fc00c68a0000000000000000
+ENTRY_END
+
+STEP 5890 QUERY
+ENTRY_BEGIN
+RAW
+b66453ed5018fc0070e60000008abe78000000010001000000000e3939363433323431323639302d330000f900010e3939363433323431323639302d330000f900ff00000000005003677373096d6963726f736f667403636f6d00403af9c5403c4b4500030000002d4e544c4d535350000100000097b200e00600060027000000070007002000000057494e324b50434b50544553540000
+ENTRY_END
+
+STEP 5900 QUERY
+ENTRY_BEGIN
+RAW
+b66453fb5011fbf2c5fd0000000000000000
+ENTRY_END
+
+STEP 5910 QUERY
+ENTRY_BEGIN
+RAW
+b663a87e501840b0d705000000904375000000010001000000000f313136383233313130343533302d320000f900010f313136383233313130343533302d320000f900ff00000000005403677373096d6963726f736f667403636f6d00403afdf8403c4f780003000000314e544c4d535350000100000097b200e00a000a0027000000070007002000000044564d544b475344564d454449414b47530000
+ENTRY_END
+
+STEP 5920 QUERY
+ENTRY_BEGIN
+RAW
+b66453fc5010fbf2c5fc0000000000000000
+ENTRY_END
+
+STEP 5930 QUERY
+ENTRY_BEGIN
+RAW
+000000007002fc00de6d0000020405b401010402
+ENTRY_END
+
+STEP 5940 QUERY
+ENTRY_BEGIN
+RAW
+b6654c635010fc0008590000000000000000
+ENTRY_END
+
+STEP 5950 QUERY
+ENTRY_BEGIN
+RAW
+b663a88c501140a2b8f50000000000000000
+ENTRY_END
+
+STEP 5960 QUERY
+ENTRY_BEGIN
+RAW
+b6654c635018fc00072d0000008a6c00000000010001000000000e3939363433323431323639302d320000f900010e3939363433323431323639302d320000f900ff00000000005003677373096d6963726f736f667403636f6d00403af9c5403c4b4500030000002d4e544c4d535350000100000097b200e00600060027000000070007002000000057494e324b50434b50544553540000
+ENTRY_END
+
+STEP 5970 QUERY
+ENTRY_BEGIN
+RAW
+00000000700240002f9000000204056401010402
+ENTRY_END
+
+STEP 5980 QUERY
+ENTRY_BEGIN
+RAW
+b6654c715011fbf207cc0000000000000000
+ENTRY_END
+
+STEP 5990 QUERY
+ENTRY_BEGIN
+RAW
+b6654c725010fbf207cb0000000000000000
+ENTRY_END
+
+STEP 6000 QUERY
+ENTRY_BEGIN
+RAW
+b663a88d501040a2b8f40000000000000000
+ENTRY_END
+
+STEP 6010 QUERY
+ENTRY_BEGIN
+RAW
+000000007002fc0083840000020405b401010402
+ENTRY_END
+
+STEP 6020 QUERY
+ENTRY_BEGIN
+RAW
+b6663c2f501040b068ae0000000000000000
+ENTRY_END
+
+STEP 6030 QUERY
+ENTRY_BEGIN
+RAW
+b666fe1c5010fc00fbb40000000000000000
+ENTRY_END
+
+STEP 6040 QUERY
+ENTRY_BEGIN
+RAW
+b666fe1c5018fc007cc80000008ae9c0000000010001000000000e3939363433323431323639302d320000f900010e3939363433323431323639302d320000f900ff00000000005003677373096d6963726f736f667403636f6d00403af9c5403c4b4500030000002d4e544c4d535350000100000097b200e00600060027000000070007002000000057494e324b50434b50544553540000
+ENTRY_END
+
+STEP 6050 QUERY
+ENTRY_BEGIN
+RAW
+b666fe2a5011fbf2fb270000000000000000
+ENTRY_END
+
+STEP 6060 QUERY
+ENTRY_BEGIN
+RAW
+b666fe2b5010fbf2fb260000000000000000
+ENTRY_END
+
+STEP 6070 QUERY
+ENTRY_BEGIN
+RAW
+b6663c2f501840b04f5d000000907a43000000010001000000000f313136383233313130343533302d320000f900010f313136383233313130343533302d320000f900ff00000000005403677373096d6963726f736f667403636f6d00403afdf8403c4f780003000000314e544c4d535350000100000097b200e00a000a0027000000070007002000000044564d544b475344564d454449414b47530000
+ENTRY_END
+
+STEP 6080 QUERY
+ENTRY_BEGIN
+RAW
+b6663c3d501140a2681b0000000000000000
+ENTRY_END
+
+STEP 6090 QUERY
+ENTRY_BEGIN
+RAW
+b6663c3e501040a2681a0000000000000000
+ENTRY_END
+
+STEP 6100 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf02ae300000204057a01010402
+ENTRY_END
+
+STEP 6110 QUERY
+ENTRY_BEGIN
+RAW
+b66a29aa5010fbec764c0000000000000000
+ENTRY_END
+
+STEP 6120 QUERY
+ENTRY_BEGIN
+RAW
+b66a29aa5018fbeca98c0000008f5105000000010001000000000f313033303739323135313035382d330000f900010f313033303739323135313035382d330000f900ff00000000005303677373096d6963726f736f667403636f6d00403b06fa403c587a0003000000304e544c4d535350000100000097b208e00900090027000000070007002000000057494e3230303047494f504e54444f4d0000
+ENTRY_END
+
+STEP 6130 QUERY
+ENTRY_BEGIN
+RAW
+b66a29b85011fbde75ba0000000000000000
+ENTRY_END
+
+STEP 6140 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000a2200000020405b401010402
+ENTRY_END
+
+STEP 6150 QUERY
+ENTRY_BEGIN
+RAW
+b66a29b95010fbde75b90000000000000000
+ENTRY_END
+
+STEP 6160 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf0f29900000204057a01010402
+ENTRY_END
+
+STEP 6170 QUERY
+ENTRY_BEGIN
+RAW
+b66acd7f50104470467a0000000000000000
+ENTRY_END
+
+STEP 6180 QUERY
+ENTRY_BEGIN
+RAW
+b66acd7f50184470c7f40000008d352e000000010001000000000f313031333631323238313837342d330000f900010f313031333631323238313837342d330000f900ff00000000005103677373096d6963726f736f667403636f6d00403afce9403c4e6900030000002e4e544c4d535350000100000097b208e0050005002900000009000900200000005345525645522d4343435952454b0000
+ENTRY_END
+
+STEP 6190 QUERY
+ENTRY_BEGIN
+RAW
+b66acd8d5011446245ea0000000000000000
+ENTRY_END
+
+STEP 6200 QUERY
+ENTRY_BEGIN
+RAW
+b66bbecf5010fbeca8dc0000000000000000
+ENTRY_END
+
+STEP 6210 QUERY
+ENTRY_BEGIN
+RAW
+b66bbecf5018fbecf6930000008f378f000000010001000000000f313033303739323135313035382d320000f900010f313033303739323135313035382d320000f900ff00000000005303677373096d6963726f736f667403636f6d00403b06fa403c587a0003000000304e544c4d535350000100000097b208e00900090027000000070007002000000057494e3230303047494f504e54444f4d0000
+ENTRY_END
+
+STEP 6220 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400067760000020405b401010402
+ENTRY_END
+
+STEP 6230 QUERY
+ENTRY_BEGIN
+RAW
+b66acd8e5010446245e90000000000000000
+ENTRY_END
+
+STEP 6240 QUERY
+ENTRY_BEGIN
+RAW
+b66bbedd5011fbdea84a0000000000000000
+ENTRY_END
+
+STEP 6250 QUERY
+ENTRY_BEGIN
+RAW
+b66c83605010447055ed0000000000000000
+ENTRY_END
+
+STEP 6260 QUERY
+ENTRY_BEGIN
+RAW
+b66c83605018447026c40000008de6d2000000010001000000000f313031333631323238313837342d320000f900010f313031333631323238313837342d320000f900ff00000000005103677373096d6963726f736f667403636f6d00403afce9403c4e6900030000002e4e544c4d535350000100000097b208e0050005002900000009000900200000005345525645522d4343435952454b0000
+ENTRY_END
+
+STEP 6270 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf0d34200000204057a01010402
+ENTRY_END
+
+STEP 6280 QUERY
+ENTRY_BEGIN
+RAW
+b66c836e50114462555d0000000000000000
+ENTRY_END
+
+STEP 6290 QUERY
+ENTRY_BEGIN
+RAW
+b66bbede5010fbdea8490000000000000000
+ENTRY_END
+
+STEP 6300 QUERY
+ENTRY_BEGIN
+RAW
+b66d191c5010fbec2f370000000000000000
+ENTRY_END
+
+STEP 6310 QUERY
+ENTRY_BEGIN
+RAW
+b66d191c5018fbecc6460000008fee36000000010001000000000f313033303739323135313035382d320000f900010f313033303739323135313035382d320000f900ff00000000005303677373096d6963726f736f667403636f6d00403b06fa403c587a0003000000304e544c4d535350000100000097b208e00900090027000000070007002000000057494e3230303047494f504e54444f4d0000
+ENTRY_END
+
+STEP 6320 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000810b0000020405b401010402
+ENTRY_END
+
+STEP 6330 QUERY
+ENTRY_BEGIN
+RAW
+b66c836f50104462555c0000000000000000
+ENTRY_END
+
+STEP 6340 QUERY
+ENTRY_BEGIN
+RAW
+b66da42b501044704eb60000000000000000
+ENTRY_END
+
+STEP 6350 QUERY
+ENTRY_BEGIN
+RAW
+b66da42b501844706de90000008d9876000000010001000000000f313031333631323238313837342d320000f900010f313031333631323238313837342d320000f900ff00000000005103677373096d6963726f736f667403636f6d00403afce9403c4e6900030000002e4e544c4d535350000100000097b208e0050005002900000009000900200000005345525645522d4343435952454b0000
+ENTRY_END
+
+STEP 6360 QUERY
+ENTRY_BEGIN
+RAW
+b66d192a5011fbde2ea50000000000000000
+ENTRY_END
+
+STEP 6370 QUERY
+ENTRY_BEGIN
+RAW
+b66da439501144624e260000000000000000
+ENTRY_END
+
+STEP 6380 QUERY
+ENTRY_BEGIN
+RAW
+b66d192b5010fbde2ea40000000000000000
+ENTRY_END
+
+STEP 6390 QUERY
+ENTRY_BEGIN
+RAW
+b66da43a501044624e250000000000000000
+ENTRY_END
+
+STEP 6400 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf0e71c0000020405b401010402
+ENTRY_END
+
+STEP 6410 QUERY
+ENTRY_BEGIN
+RAW
+b66e311b5010faf02c470000000000000000
+ENTRY_END
+
+STEP 6420 QUERY
+ENTRY_BEGIN
+RAW
+000000007002fc00ee0b00000204057801010402
+ENTRY_END
+
+STEP 6430 QUERY
+ENTRY_BEGIN
+RAW
+b6719dda5010fc00c6370000000000000000
+ENTRY_END
+
+STEP 6440 QUERY
+ENTRY_BEGIN
+RAW
+b6719dda5018fc006c5e00000091d5b0000000010001000000000e3932373731323933353935342d330000f900010e3932373731323933353935342d330000f900ff00000000005703677373096d6963726f736f667403636f6d00403afc98403c4e180003000000344e544c4d535350000100000097b208e0080008002c0000000c000c0020000000504c414e4e494e472d494e544e4b4f45524945520000
+ENTRY_END
+
+STEP 6450 QUERY
+ENTRY_BEGIN
+RAW
+b6719de85011fbf2c5a30000000000000000
+ENTRY_END
+
+STEP 6460 QUERY
+ENTRY_BEGIN
+RAW
+000000007002fc00095d00000204057801010402
+ENTRY_END
+
+STEP 6470 QUERY
+ENTRY_BEGIN
+RAW
+b6719de95010fbf2c5a20000000000000000
+ENTRY_END
+
+STEP 6480 QUERY
+ENTRY_BEGIN
+RAW
+b6722e745010fc0050ee0000000000000000
+ENTRY_END
+
+STEP 6490 QUERY
+ENTRY_BEGIN
+RAW
+b6722e745018fc00071f00000091c7a6000000010001000000000e3932373731323933353935342d320000f900010e3932373731323933353935342d320000f900ff00000000005703677373096d6963726f736f667403636f6d00403afc98403c4e180003000000344e544c4d535350000100000097b208e0080008002c0000000c000c0020000000504c414e4e494e472d494e544e4b4f45524945520000
+ENTRY_END
+
+STEP 6500 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000b5a300000204057a01010402
+ENTRY_END
+
+STEP 6510 QUERY
+ENTRY_BEGIN
+RAW
+b673057f501041b824730000000000000000
+ENTRY_END
+
+STEP 6520 QUERY
+ENTRY_BEGIN
+RAW
+b673057f501841b86c7200000095bcc0000000010001000000000f313133333837313336363136322d330000f900010f313133333837313336363136322d330000f900ff00000000005903677373096d6963726f736f667403636f6d00403afcec403c4e6c0003000000364e544c4d535350000100000097b200e0070007002f0000000f000f00200000004453412d323030302d534552564552445341323030300000
+ENTRY_END
+
+STEP 6530 QUERY
+ENTRY_BEGIN
+RAW
+b673058d501141aa23db0000000000000000
+ENTRY_END
+
+STEP 6540 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400032f400000204057a01010402
+ENTRY_END
+
+STEP 6550 QUERY
+ENTRY_BEGIN
+RAW
+b6722e825011fbf2505a0000000000000000
+ENTRY_END
+
+STEP 6560 QUERY
+ENTRY_BEGIN
+RAW
+b673058e501041aa23da0000000000000000
+ENTRY_END
+
+STEP 6570 QUERY
+ENTRY_BEGIN
+RAW
+b673a2cf501041b804730000000000000000
+ENTRY_END
+
+STEP 6580 QUERY
+ENTRY_BEGIN
+RAW
+b673a2cf501841b8d533000000953500000000010001000000000f313133333837313336363136322d320000f900010f313133333837313336363136322d320000f900ff00000000005903677373096d6963726f736f667403636f6d00403afcec403c4e6c0003000000364e544c4d535350000100000097b200e0070007002f0000000f000f00200000004453412d323030302d534552564552445341323030300000
+ENTRY_END
+
+STEP 6590 QUERY
+ENTRY_BEGIN
+RAW
+000000007002fc00bb6f00000204057801010402
+ENTRY_END
+
+STEP 6600 QUERY
+ENTRY_BEGIN
+RAW
+b673a2dd501141aa03db0000000000000000
+ENTRY_END
+
+STEP 6610 QUERY
+ENTRY_BEGIN
+RAW
+00000000700240004e5b00000204057a01010402
+ENTRY_END
+
+STEP 6620 QUERY
+ENTRY_BEGIN
+RAW
+b6722e835010fbf250590000000000000000
+ENTRY_END
+
+STEP 6630 QUERY
+ENTRY_BEGIN
+RAW
+b673a2de501041aa03da0000000000000000
+ENTRY_END
+
+STEP 6640 QUERY
+ENTRY_BEGIN
+RAW
+b674f779501041b8cb2e0000000000000000
+ENTRY_END
+
+STEP 6650 QUERY
+ENTRY_BEGIN
+RAW
+b674f779501841b823af00000095ad40000000010001000000000f313133333837313336363136322d320000f900010f313133333837313336363136322d320000f900ff00000000005903677373096d6963726f736f667403636f6d00403afcec403c4e6c0003000000364e544c4d535350000100000097b200e0070007002f0000000f000f00200000004453412d323030302d534552564552445341323030300000
+ENTRY_END
+
+STEP 6660 QUERY
+ENTRY_BEGIN
+RAW
+b674f787501141aaca960000000000000000
+ENTRY_END
+
+STEP 6670 QUERY
+ENTRY_BEGIN
+RAW
+b674219e5010fc000fd50000000000000000
+ENTRY_END
+
+STEP 6680 QUERY
+ENTRY_BEGIN
+RAW
+b674f788501041aaca950000000000000000
+ENTRY_END
+
+STEP 6690 QUERY
+ENTRY_BEGIN
+RAW
+b674219e5018fc0075b20000009117fa000000010001000000000e3932373731323933353935342d320000f900010e3932373731323933353935342d320000f900ff00000000005703677373096d6963726f736f667403636f6d00403afc98403c4e180003000000344e544c4d535350000100000097b208e0080008002c0000000c000c0020000000504c414e4e494e472d494e544e4b4f45524945520000
+ENTRY_END
+
+STEP 6700 QUERY
+ENTRY_BEGIN
+RAW
+00000000700240005e6e00000204057a01010402
+ENTRY_END
+
+STEP 6710 QUERY
+ENTRY_BEGIN
+RAW
+b6758667501041b84c530000000000000000
+ENTRY_END
+
+STEP 6720 QUERY
+ENTRY_BEGIN
+RAW
+b6758667501841b83393000000951d80000000010001000000000f313133333837313336363136322d330000f900010f313133333837313336363136322d330000f900ff00000000005903677373096d6963726f736f667403636f6d00403afcec403c4e6c0003000000364e544c4d535350000100000097b200e0070007002f0000000f000f00200000004453412d323030302d534552564552445341323030300000
+ENTRY_END
+
+STEP 6730 QUERY
+ENTRY_BEGIN
+RAW
+b67421ac5011fbf20f410000000000000000
+ENTRY_END
+
+STEP 6740 QUERY
+ENTRY_BEGIN
+RAW
+b6758675501141aa4bbb0000000000000000
+ENTRY_END
+
+STEP 6750 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000834f00000204057a01010402
+ENTRY_END
+
+STEP 6760 QUERY
+ENTRY_BEGIN
+RAW
+b6758676501041aa4bba0000000000000000
+ENTRY_END
+
+STEP 6770 QUERY
+ENTRY_BEGIN
+RAW
+b6764c30501041b8ab6a0000000000000000
+ENTRY_END
+
+STEP 6780 QUERY
+ENTRY_BEGIN
+RAW
+b6764c30501841b81b6b0000009595c0000000010001000000000f313133333837313336363136322d320000f900010f313133333837313336363136322d320000f900ff00000000005903677373096d6963726f736f667403636f6d00403afcec403c4e6c0003000000364e544c4d535350000100000097b200e0070007002f0000000f000f00200000004453412d323030302d534552564552445341323030300000
+ENTRY_END
+
+STEP 6790 QUERY
+ENTRY_BEGIN
+RAW
+b67421ad5010fbf20f400000000000000000
+ENTRY_END
+
+STEP 6800 QUERY
+ENTRY_BEGIN
+RAW
+b6764c3e501141aaaad20000000000000000
+ENTRY_END
+
+STEP 6810 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000b5d500000204057a01010402
+ENTRY_END
+
+STEP 6820 QUERY
+ENTRY_BEGIN
+RAW
+b6764c3f501041aaaad10000000000000000
+ENTRY_END
+
+STEP 6830 QUERY
+ENTRY_BEGIN
+RAW
+b676e889501041b841970000000000000000
+ENTRY_END
+
+STEP 6840 QUERY
+ENTRY_BEGIN
+RAW
+b676e889501841b83958000000950e00000000010001000000000f313133333837313336363136322d320000f900010f313133333837313336363136322d320000f900ff00000000005903677373096d6963726f736f667403636f6d00403afcec403c4e6c0003000000364e544c4d535350000100000097b200e0070007002f0000000f000f00200000004453412d323030302d534552564552445341323030300000
+ENTRY_END
+
+STEP 6850 QUERY
+ENTRY_BEGIN
+RAW
+b676e897501141aa40ff0000000000000000
+ENTRY_END
+
+STEP 6860 QUERY
+ENTRY_BEGIN
+RAW
+b676e898501041aa40fe0000000000000000
+ENTRY_END
+
+STEP 6870 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400095d800000204056401010402
+ENTRY_END
+
+STEP 6880 QUERY
+ENTRY_BEGIN
+RAW
+b67b1e67501040b0eca90000000000000000
+ENTRY_END
+
+STEP 6890 QUERY
+ENTRY_BEGIN
+RAW
+b67b1e67501840b0d66800000089f180000000010001000000000e3931303533333036363737302d330000f900010e3931303533333036363737302d330000f900ff00000000004f03677373096d6963726f736f667403636f6d00403afd03403c4e8300030000002c4e544c4d535350000100000097b200e0060006002600000006000600200000004641585352564241494c45590000
+ENTRY_END
+
+STEP 6900 QUERY
+ENTRY_BEGIN
+RAW
+b67b1e75501140a2ec1d0000000000000000
+ENTRY_END
+
+STEP 6910 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000693a00000204056401010402
+ENTRY_END
+
+STEP 6920 QUERY
+ENTRY_BEGIN
+RAW
+b67b1e76501040a2ec1c0000000000000000
+ENTRY_END
+
+STEP 6930 QUERY
+ENTRY_BEGIN
+RAW
+b67bf069501040b0ee080000000000000000
+ENTRY_END
+
+STEP 6940 QUERY
+ENTRY_BEGIN
+RAW
+b67bf069501840b024c800000089a680000000010001000000000e3931303533333036363737302d320000f900010e3931303533333036363737302d320000f900ff00000000004f03677373096d6963726f736f667403636f6d00403afd03403c4e8300030000002c4e544c4d535350000100000097b200e0060006002600000006000600200000004641585352564241494c45590000
+ENTRY_END
+
+STEP 6950 QUERY
+ENTRY_BEGIN
+RAW
+b67bf077501140a2ed7c0000000000000000
+ENTRY_END
+
+STEP 6960 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000124a00000204056401010402
+ENTRY_END
+
+STEP 6970 QUERY
+ENTRY_BEGIN
+RAW
+b67bf078501040a2ed7b0000000000000000
+ENTRY_END
+
+STEP 6980 QUERY
+ENTRY_BEGIN
+RAW
+b67d7555501040b0122b0000000000000000
+ENTRY_END
+
+STEP 6990 QUERY
+ENTRY_BEGIN
+RAW
+b67d7555501840b0906a000000895d00000000010001000000000e3931303533333036363737302d320000f900010e3931303533333036363737302d320000f900ff00000000004f03677373096d6963726f736f667403636f6d00403afd04403c4e8400030000002c4e544c4d535350000100000097b200e0060006002600000006000600200000004641585352564241494c45590000
+ENTRY_END
+
+STEP 7000 QUERY
+ENTRY_BEGIN
+RAW
+b67d7563501140a2119f0000000000000000
+ENTRY_END
+
+STEP 7010 QUERY
+ENTRY_BEGIN
+RAW
+b67d7564501040a2119e0000000000000000
+ENTRY_END
+
+STEP 7020 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf0d9cd00000204051e01010402
+ENTRY_END
+
+STEP 7030 QUERY
+ENTRY_BEGIN
+RAW
+b67e3beb5010ffdc0e960000000000000000
+ENTRY_END
+
+STEP 7040 QUERY
+ENTRY_BEGIN
+RAW
+b67e3beb5018ffdc1df400000099934e000000010001000000000f313135313035313233353334362d330000f900010f313135313035313233353334362d330000f900ff00000000005d03677373096d6963726f736f667403636f6d00403afd1b403c4e9b00030000003a4e544c4d535350000100000097b208e00c000c002e0000000e000e00200000004e504552535045435449454630314e50455253504543544945460000
+ENTRY_END
+
+STEP 7050 QUERY
+ENTRY_BEGIN
+RAW
+b67e3bf95011ffce0dfa0000000000000000
+ENTRY_END
+
+STEP 7060 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf0182100000204051e01010402
+ENTRY_END
+
+STEP 7070 QUERY
+ENTRY_BEGIN
+RAW
+b67e3bfa5010ffce0df90000000000000000
+ENTRY_END
+
+STEP 7080 QUERY
+ENTRY_BEGIN
+RAW
+b67edec85010ffdcaa0b0000000000000000
+ENTRY_END
+
+STEP 7090 QUERY
+ENTRY_BEGIN
+RAW
+b67edec85018ffdc9cbb00000099b0fd000000010001000000000f313135313035313233353334362d320000f900010f313135313035313233353334362d320000f900ff00000000005d03677373096d6963726f736f667403636f6d00403afd1b403c4e9b00030000003a4e544c4d535350000100000097b208e00c000c002e0000000e000e00200000004e504552535045435449454630314e50455253504543544945460000
+ENTRY_END
+
+STEP 7100 QUERY
+ENTRY_BEGIN
+RAW
+b67eded65011ffcea96f0000000000000000
+ENTRY_END
+
+STEP 7110 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf066bc00000204051e01010402
+ENTRY_END
+
+STEP 7120 QUERY
+ENTRY_BEGIN
+RAW
+b67eded75010ffcea96e0000000000000000
+ENTRY_END
+
+STEP 7130 QUERY
+ENTRY_BEGIN
+RAW
+b67fb3b25010ffdc23bc0000000000000000
+ENTRY_END
+
+STEP 7140 QUERY
+ENTRY_BEGIN
+RAW
+b67fb3b25018ffdca0cd00000099269c000000010001000000000f313135313035313233353334362d320000f900010f313135313035313233353334362d320000f900ff00000000005d03677373096d6963726f736f667403636f6d00403afd1b403c4e9b00030000003a4e544c4d535350000100000097b208e00c000c002e0000000e000e00200000004e504552535045435449454630314e50455253504543544945460000
+ENTRY_END
+
+STEP 7150 QUERY
+ENTRY_BEGIN
+RAW
+b67fb3c05011ffce23200000000000000000
+ENTRY_END
+
+STEP 7160 QUERY
+ENTRY_BEGIN
+RAW
+b67fb3c15010ffce231f0000000000000000
+ENTRY_END
+
+STEP 7170 QUERY
+ENTRY_BEGIN
+RAW
+b66e311b5018faf02f370000008d25c0000000010001000000000f313036353135313838393432362d330000f900010f313036353135313838393432362d330000f900ff00000000005103677373096d6963726f736f667403636f6d00403afd13403c4e9300030000002e4e544c4d535350000100000097b208e0070007002700000007000700200000005245545f4653315245544152434f0000
+ENTRY_END
+
+STEP 7180 QUERY
+ENTRY_BEGIN
+RAW
+b66e311b5018faf02f370000008d25c0000000010001000000000f313036353135313838393432362d330000f900010f313036353135313838393432362d330000f900ff00000000005103677373096d6963726f736f667403636f6d00403afd13403c4e9300030000002e4e544c4d535350000100000097b208e0070007002700000007000700200000005245545f4653315245544152434f0000
+ENTRY_END
+
+STEP 7190 QUERY
+ENTRY_BEGIN
+RAW
+b66e31295011fae22bb70000000000000000
+ENTRY_END
+
+STEP 7200 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf0a80c0000020405b401010402
+ENTRY_END
+
+STEP 7210 QUERY
+ENTRY_BEGIN
+RAW
+b66e312a5010fae22bb60000000000000000
+ENTRY_END
+
+STEP 7220 QUERY
+ENTRY_BEGIN
+RAW
+b68303575010faf01ae60000000000000000
+ENTRY_END
+
+STEP 7230 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf091b40000020405b401010402
+ENTRY_END
+
+STEP 7240 QUERY
+ENTRY_BEGIN
+RAW
+b683c2c05010faf045240000000000000000
+ENTRY_END
+
+STEP 7250 QUERY
+ENTRY_BEGIN
+RAW
+b683c2c05018faf0f2860000008e4bdc000000010001000000000f313237313331303331393633342d330000f900010f313237313331303331393633342d330000f900ff00000000005203677373096d6963726f736f667403636f6d00403b04c5403c564500030000002f4e544c4d535350000100000097b208e0070007002800000008000800200000005345525645522d31545247524f55500000
+ENTRY_END
+
+STEP 7260 QUERY
+ENTRY_BEGIN
+RAW
+b683c2ce5011fae244930000000000000000
+ENTRY_END
+
+STEP 7270 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf044dc0000020405b401010402
+ENTRY_END
+
+STEP 7280 QUERY
+ENTRY_BEGIN
+RAW
+b683c2cf5010fae244920000000000000000
+ENTRY_END
+
+STEP 7290 QUERY
+ENTRY_BEGIN
+RAW
+b6844daf5010faf06d5c0000000000000000
+ENTRY_END
+
+STEP 7300 QUERY
+ENTRY_BEGIN
+RAW
+b6844daf5018faf0669c0000008e0100000000010001000000000f313237313331303331393633342d320000f900010f313237313331303331393633342d320000f900ff00000000005203677373096d6963726f736f667403636f6d00403b04c5403c564500030000002f4e544c4d535350000100000097b208e0070007002800000008000800200000005345525645522d31545247524f55500000
+ENTRY_END
+
+STEP 7310 QUERY
+ENTRY_BEGIN
+RAW
+b6844dbd5011fae26ccb0000000000000000
+ENTRY_END
+
+STEP 7320 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf058a60000020405b401010402
+ENTRY_END
+
+STEP 7330 QUERY
+ENTRY_BEGIN
+RAW
+b6844dbe5010fae26cca0000000000000000
+ENTRY_END
+
+STEP 7340 QUERY
+ENTRY_BEGIN
+RAW
+b686ac6c5010faf022670000000000000000
+ENTRY_END
+
+STEP 7350 QUERY
+ENTRY_BEGIN
+RAW
+b686ac6c5018faf065460000008eb560000000010001000000000f313237313331303331393633342d320000f900010f313237313331303331393633342d320000f900ff00000000005203677373096d6963726f736f667403636f6d00403b04c6403c564600030000002f4e544c4d535350000100000097b208e0070007002800000008000800200000005345525645522d31545247524f55500000
+ENTRY_END
+
+STEP 7360 QUERY
+ENTRY_BEGIN
+RAW
+b686ac7a5011fae221d60000000000000000
+ENTRY_END
+
+STEP 7370 QUERY
+ENTRY_BEGIN
+RAW
+b686ac7b5010fae221d50000000000000000
+ENTRY_END
+
+STEP 7380 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000bdaf0000020405b401010402
+ENTRY_END
+
+STEP 7390 QUERY
+ENTRY_BEGIN
+RAW
+b68abd075010447072610000000000000000
+ENTRY_END
+
+STEP 7400 QUERY
+ENTRY_BEGIN
+RAW
+b68abd0750184470b7c30000008d553b000000010001000000000f313231393737303731323038322d330000f900010f313231393737303731323038322d330000f900ff00000000005103677373096d6963726f736f667403636f6d00403afcf1403c4e7100030000002e4e544c4d535350000100000097b200e00700070027000000070007002000000053455256455231534954544152440000
+ENTRY_END
+
+STEP 7410 QUERY
+ENTRY_BEGIN
+RAW
+b68abd155011446271d10000000000000000
+ENTRY_END
+
+STEP 7420 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000c6270000020405b401010402
+ENTRY_END
+
+STEP 7430 QUERY
+ENTRY_BEGIN
+RAW
+b68abd165010446271d00000000000000000
+ENTRY_END
+
+STEP 7440 QUERY
+ENTRY_BEGIN
+RAW
+b68bafe25010447087fd0000000000000000
+ENTRY_END
+
+STEP 7450 QUERY
+ENTRY_BEGIN
+RAW
+b68bafe25018447063a10000008dbffa000000010001000000000f313231393737303731323038322d320000f900010f313231393737303731323038322d320000f900ff00000000005103677373096d6963726f736f667403636f6d00403afcf1403c4e7100030000002e4e544c4d535350000100000097b200e00700070027000000070007002000000053455256455231534954544152440000
+ENTRY_END
+
+STEP 7460 QUERY
+ENTRY_BEGIN
+RAW
+b68baff050114462876d0000000000000000
+ENTRY_END
+
+STEP 7470 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000803f0000020405b401010402
+ENTRY_END
+
+STEP 7480 QUERY
+ENTRY_BEGIN
+RAW
+b68baff150104462876c0000000000000000
+ENTRY_END
+
+STEP 7490 QUERY
+ENTRY_BEGIN
+RAW
+b68c3a0a50104470b7ec0000000000000000
+ENTRY_END
+
+STEP 7500 QUERY
+ENTRY_BEGIN
+RAW
+b68c3a0a501844701e530000008d3538000000010001000000000f313231393737303731323038322d320000f900010f313231393737303731323038322d320000f900ff00000000005103677373096d6963726f736f667403636f6d00403afcf1403c4e7100030000002e4e544c4d535350000100000097b200e00700070027000000070007002000000053455256455231534954544152440000
+ENTRY_END
+
+STEP 7510 QUERY
+ENTRY_BEGIN
+RAW
+b68c3a1850114462b75c0000000000000000
+ENTRY_END
+
+STEP 7520 QUERY
+ENTRY_BEGIN
+RAW
+b68c3a1950104462b75b0000000000000000
+ENTRY_END
+
+STEP 7530 QUERY
+ENTRY_BEGIN
+RAW
+000000006002223800990000020405b40000
+ENTRY_END
+
+STEP 7540 QUERY
+ENTRY_BEGIN
+RAW
+b68efdc55010223863f10000000000000000
+ENTRY_END
+
+STEP 7550 QUERY
+ENTRY_BEGIN
+RAW
+b68efdc550182238a3690000001d92300000000100000000000008736c61676572696a026e6c0000060001
+ENTRY_END
+
+STEP 7560 QUERY
+ENTRY_BEGIN
+RAW
+b68efe335010223863640000000000000000
+ENTRY_END
+
+STEP 7570 QUERY
+ENTRY_BEGIN
+RAW
+b68efe335011223863630000000000000000
+ENTRY_END
+
+STEP 7580 QUERY
+ENTRY_BEGIN
+RAW
+b68efe345010223863620000000000000000
+ENTRY_END
+
+STEP 7590 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000bd7e0000020405b401010402
+ENTRY_END
+
+STEP 7600 QUERY
+ENTRY_BEGIN
+RAW
+b68f86c850104470a86a0000000000000000
+ENTRY_END
+
+STEP 7610 QUERY
+ENTRY_BEGIN
+RAW
+b68f86c8501844702e0000000092d500000000010001000000000f313038323333313735383631302d330000f900010f313038323333313735383631302d330000f900ff00000000005603677373096d6963726f736f667403636f6d00403afd41403c4ec10003000000334e544c4d535350000100000097b208e00e000e002500000005000500200000004e414f4d494e45544c494a4e4e45545745524b0000
+ENTRY_END
+
+STEP 7620 QUERY
+ENTRY_BEGIN
+RAW
+b68f86d650114462a7d50000000000000000
+ENTRY_END
+
+STEP 7630 QUERY
+ENTRY_BEGIN
+RAW
+00000000700240000ff90000020405b401010402
+ENTRY_END
+
+STEP 7640 QUERY
+ENTRY_BEGIN
+RAW
+b68f86d750104462a7d40000000000000000
+ENTRY_END
+
+STEP 7650 QUERY
+ENTRY_BEGIN
+RAW
+b6902691501044705b1b0000000000000000
+ENTRY_END
+
+STEP 7660 QUERY
+ENTRY_BEGIN
+RAW
+b690269150184470c6b100000092f000000000010001000000000f313038323333313735383631302d320000f900010f313038323333313735383631302d320000f900ff00000000005603677373096d6963726f736f667403636f6d00403afd41403c4ec10003000000334e544c4d535350000100000097b208e00e000e002500000005000500200000004e414f4d494e45544c494a4e4e45545745524b0000
+ENTRY_END
+
+STEP 7670 QUERY
+ENTRY_BEGIN
+RAW
+b690269f501144625a860000000000000000
+ENTRY_END
+
+STEP 7680 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400057280000020405b401010402
+ENTRY_END
+
+STEP 7690 QUERY
+ENTRY_BEGIN
+RAW
+b69026a0501044625a850000000000000000
+ENTRY_END
+
+STEP 7700 QUERY
+ENTRY_BEGIN
+RAW
+b69105e050104470c2fa0000000000000000
+ENTRY_END
+
+STEP 7710 QUERY
+ENTRY_BEGIN
+RAW
+b69105e050184470c511000000925980000000010001000000000f313038323333313735383631302d320000f900010f313038323333313735383631302d320000f900ff00000000005603677373096d6963726f736f667403636f6d00403afd41403c4ec10003000000334e544c4d535350000100000097b208e00e000e002500000005000500200000004e414f4d494e45544c494a4e4e45545745524b0000
+ENTRY_END
+
+STEP 7720 QUERY
+ENTRY_BEGIN
+RAW
+0000000060022238210a0000020405b40000
+ENTRY_END
+
+STEP 7730 QUERY
+ENTRY_BEGIN
+RAW
+b69105ee50114462c2650000000000000000
+ENTRY_END
+
+;STEP 7740 QUERY
+;ENTRY_BEGIN
+;RAW
+;2c0901000001000000000000056b6f726e6f026e6c00000f000100
+;ENTRY_END
+
+STEP 7750 QUERY
+ENTRY_BEGIN
+RAW
+b691d4ec50102238ad380000000000000000
+ENTRY_END
+
+STEP 7760 QUERY
+ENTRY_BEGIN
+RAW
+b691d4ec501822387976000000264f0c00000001000000000000116f6e7477696b6b656c696e6773696e7374026e6c0000060001
+ENTRY_END
+
+STEP 7770 QUERY
+ENTRY_BEGIN
+RAW
+b69105ef50104462c2640000000000000000
+ENTRY_END
+
+STEP 7780 QUERY
+ENTRY_BEGIN
+RAW
+b691d55650102238aca60000000000000000
+ENTRY_END
+
+STEP 7790 QUERY
+ENTRY_BEGIN
+RAW
+b691d55650112238aca50000000000000000
+ENTRY_END
+
+STEP 7800 QUERY
+ENTRY_BEGIN
+RAW
+b691d55750102238aca40000000000000000
+ENTRY_END
+
+STEP 7810 QUERY
+ENTRY_BEGIN
+RAW
+0000000070022238543a0000020405b401010402
+ENTRY_END
+
+STEP 7820 QUERY
+ENTRY_BEGIN
+RAW
+00000000600222387a780000020405b40000
+ENTRY_END
+
+STEP 7830 QUERY
+ENTRY_BEGIN
+RAW
+b69320c750102238baca0000000000000000
+ENTRY_END
+
+STEP 7840 QUERY
+ENTRY_BEGIN
+RAW
+b69320c75018223807270000001c1125000000010000000000000774617861746965026e6c0000060001
+ENTRY_END
+
+STEP 7850 QUERY
+ENTRY_BEGIN
+RAW
+b693211d50102238ba560000000000000000
+ENTRY_END
+
+STEP 7860 QUERY
+ENTRY_BEGIN
+RAW
+b693211d50112238ba550000000000000000
+ENTRY_END
+
+STEP 7870 QUERY
+ENTRY_BEGIN
+RAW
+b693211e50102238ba540000000000000000
+ENTRY_END
+
+STEP 7880 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf036a60000020405b401010402
+ENTRY_END
+
+STEP 7890 QUERY
+ENTRY_BEGIN
+RAW
+b69592cf5010faf019f50000000000000000
+ENTRY_END
+
+STEP 7900 QUERY
+ENTRY_BEGIN
+RAW
+b69592cf5018faf0921a0000008e6b08000000010001000000000f313034373937323032303234322d330000f900010f313034373937323032303234322d330000f900ff00000000005203677373096d6963726f736f667403636f6d00403afcc7403c4e4700030000002f4e544c4d535350000100000097b208e0090009002600000006000600200000005345525645524f534f5345525645520000
+ENTRY_END
+
+STEP 7910 QUERY
+ENTRY_BEGIN
+RAW
+b69592dd5011fae219640000000000000000
+ENTRY_END
+
+STEP 7920 QUERY
+ENTRY_BEGIN
+RAW
+b69592de5010fae219630000000000000000
+ENTRY_END
+
+STEP 7930 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf0f88d0000020405b401010402
+ENTRY_END
+
+STEP 7940 QUERY
+ENTRY_BEGIN
+RAW
+b696589b5010faf016100000000000000000
+ENTRY_END
+
+STEP 7950 QUERY
+ENTRY_BEGIN
+RAW
+b696589b5018faf0eca60000008e0d98000000010001000000000f313034373937323032303234322d320000f900010f313034373937323032303234322d320000f900ff00000000005203677373096d6963726f736f667403636f6d00403afcc7403c4e4700030000002f4e544c4d535350000100000097b208e0090009002600000006000600200000005345525645524f534f5345525645520000
+ENTRY_END
+
+STEP 7960 QUERY
+ENTRY_BEGIN
+RAW
+b69658a95011fae2157f0000000000000000
+ENTRY_END
+
+STEP 7970 QUERY
+ENTRY_BEGIN
+RAW
+b69658aa5010fae2157e0000000000000000
+ENTRY_END
+
+STEP 7980 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf0d1d60000020405b401010402
+ENTRY_END
+
+STEP 7990 QUERY
+ENTRY_BEGIN
+RAW
+b6925a485010223870130000000000000000
+ENTRY_END
+
+STEP 8000 QUERY
+ENTRY_BEGIN
+RAW
+b6973bb55010faf00c3e0000000000000000
+ENTRY_END
+
+STEP 8010 QUERY
+ENTRY_BEGIN
+RAW
+b6973bb55018faf0ee6c0000008e0000000000010001000000000f313034373937323032303234322d320000f900010f313034373937323032303234322d320000f900ff00000000005203677373096d6963726f736f667403636f6d00403afcc8403c4e4800030000002f4e544c4d535350000100000097b208e0090009002600000006000600200000005345525645524f534f5345525645520000
+ENTRY_END
+
+STEP 8020 QUERY
+ENTRY_BEGIN
+RAW
+b6925a48501822385efc00000096a91f000000010001000000000f313033303739323135313035382d330000f900010f313033303739323135313035382d330000f900ff00000000005a03677373096d6963726f736f667403636f6d00403afcf6403c4e760003000000374e544c4d535350000100000097b200e0080008002f0000000f000f00200000004b4d57452d4345335648394a4450504b4d57452d5553500000
+ENTRY_END
+
+STEP 8030 QUERY
+ENTRY_BEGIN
+RAW
+b6973bc35011fae20bad0000000000000000
+ENTRY_END
+
+STEP 8040 QUERY
+ENTRY_BEGIN
+RAW
+b6973bc45010fae20bac0000000000000000
+ENTRY_END
+
+STEP 8050 QUERY
+ENTRY_BEGIN
+RAW
+b6925a565011222a6f7a0000000000000000
+ENTRY_END
+
+STEP 8060 QUERY
+ENTRY_BEGIN
+RAW
+000000007002223860470000020405b401010402
+ENTRY_END
+
+STEP 8070 QUERY
+ENTRY_BEGIN
+RAW
+b6925a575010222a6f790000000000000000
+ENTRY_END
+
+STEP 8080 QUERY
+ENTRY_BEGIN
+RAW
+b698080850102238ce5a0000000000000000
+ENTRY_END
+
+STEP 8090 QUERY
+ENTRY_BEGIN
+RAW
+b69808085018223875ef00000096f174000000010001000000000f313033303739323135313035382d320000f900010f313033303739323135313035382d320000f900ff00000000005a03677373096d6963726f736f667403636f6d00403afcf6403c4e760003000000374e544c4d535350000100000097b200e0080008002f0000000f000f00200000004b4d57452d4345335648394a4450504b4d57452d5553500000
+ENTRY_END
+
+STEP 8100 QUERY
+ENTRY_BEGIN
+RAW
+000000006002223824c20000020405b40000
+ENTRY_END
+
+STEP 8110 QUERY
+ENTRY_BEGIN
+RAW
+b698ca5350102238bb820000000000000000
+ENTRY_END
+
+STEP 8120 QUERY
+ENTRY_BEGIN
+RAW
+b698ca535018223813cf000000236e56000000010000000000000e6761642d676f6f692d7665636874026e6c0000060001
+ENTRY_END
+
+STEP 8130 QUERY
+ENTRY_BEGIN
+RAW
+b698caba50102238baf60000000000000000
+ENTRY_END
+
+STEP 8140 QUERY
+ENTRY_BEGIN
+RAW
+b698caba50112238baf50000000000000000
+ENTRY_END
+
+STEP 8150 QUERY
+ENTRY_BEGIN
+RAW
+b698cabb50102238baf40000000000000000
+ENTRY_END
+
+STEP 8160 QUERY
+ENTRY_BEGIN
+RAW
+b69808165011222acdc10000000000000000
+ENTRY_END
+
+STEP 8170 QUERY
+ENTRY_BEGIN
+RAW
+00000000700222386f010000020405b401010402
+ENTRY_END
+
+STEP 8180 QUERY
+ENTRY_BEGIN
+RAW
+00000000600222389deb0000020405b40000
+ENTRY_END
+
+STEP 8190 QUERY
+ENTRY_BEGIN
+RAW
+b69becab5010223812510000000000000000
+ENTRY_END
+
+STEP 8200 QUERY
+ENTRY_BEGIN
+RAW
+b69becab50182238cab200000024e7b1000000010000000000000f68656d6572742d676f72696368656d026e6c0000060001
+ENTRY_END
+
+STEP 8210 QUERY
+ENTRY_BEGIN
+RAW
+b69bed135010223811c30000000000000000
+ENTRY_END
+
+STEP 8220 QUERY
+ENTRY_BEGIN
+RAW
+b69bed135011223811c20000000000000000
+ENTRY_END
+
+STEP 8230 QUERY
+ENTRY_BEGIN
+RAW
+b69bed145010223811c10000000000000000
+ENTRY_END
+
+STEP 8240 QUERY
+ENTRY_BEGIN
+RAW
+0000000060022238b4740000020405b40000
+ENTRY_END
+
+STEP 8250 QUERY
+ENTRY_BEGIN
+RAW
+0000000060022238b67e0000020405b40000
+ENTRY_END
+
+STEP 8260 QUERY
+ENTRY_BEGIN
+RAW
+b69cc8d1501022384cb30000000000000000
+ENTRY_END
+
+STEP 8270 QUERY
+ENTRY_BEGIN
+RAW
+b69cc8d1501822382c12000000209f3f000000010000000000000b76657a656c68656e6e6570026e6c0000060001
+ENTRY_END
+
+STEP 8280 QUERY
+ENTRY_BEGIN
+RAW
+b69d9e7350102238791a0000000000000000
+ENTRY_END
+
+STEP 8290 QUERY
+ENTRY_BEGIN
+RAW
+b69d9e7350182238ea300000001eaf1000000001000000000000096f6f672d726164696f026e6c0000060001
+ENTRY_END
+
+STEP 8300 QUERY
+ENTRY_BEGIN
+RAW
+b69cc935501022384c2d0000000000000000
+ENTRY_END
+
+STEP 8310 QUERY
+ENTRY_BEGIN
+RAW
+b69cc935501122384c2c0000000000000000
+ENTRY_END
+
+STEP 8320 QUERY
+ENTRY_BEGIN
+RAW
+b69d9ed55010223878980000000000000000
+ENTRY_END
+
+STEP 8330 QUERY
+ENTRY_BEGIN
+RAW
+b69d9ed55011223878970000000000000000
+ENTRY_END
+
+STEP 8340 QUERY
+ENTRY_BEGIN
+RAW
+b69808175010222acdc00000000000000000
+ENTRY_END
+
+STEP 8350 QUERY
+ENTRY_BEGIN
+RAW
+b69b68b4501022387c650000000000000000
+ENTRY_END
+
+STEP 8360 QUERY
+ENTRY_BEGIN
+RAW
+b69b68b450182238179600000096fbd8000000010001000000000f313033303739323135313035382d320000f900010f313033303739323135313035382d320000f900ff00000000005a03677373096d6963726f736f667403636f6d00403afcf7403c4e770003000000374e544c4d535350000100000097b200e0080008002f0000000f000f00200000004b4d57452d4345335648394a4450504b4d57452d5553500000
+ENTRY_END
+
+STEP 8370 QUERY
+ENTRY_BEGIN
+RAW
+b69d9ed65010223878960000000000000000
+ENTRY_END
+
+STEP 8380 QUERY
+ENTRY_BEGIN
+RAW
+b69b68c25011222a7bcc0000000000000000
+ENTRY_END
+
+STEP 8390 QUERY
+ENTRY_BEGIN
+RAW
+0000000060022238f8440000020405b40000
+ENTRY_END
+
+STEP 8400 QUERY
+ENTRY_BEGIN
+RAW
+b69e234c5010223836070000000000000000
+ENTRY_END
+
+STEP 8410 QUERY
+ENTRY_BEGIN
+RAW
+b69e234c50182238a76e0000001cec240000000100000000000007646574616e6574026e6c0000060001
+ENTRY_END
+
+STEP 8420 QUERY
+ENTRY_BEGIN
+RAW
+b69e23a25010223835930000000000000000
+ENTRY_END
+
+STEP 8430 QUERY
+ENTRY_BEGIN
+RAW
+b69e23a25011223835920000000000000000
+ENTRY_END
+
+STEP 8440 QUERY
+ENTRY_BEGIN
+RAW
+b69e23a35010223835910000000000000000
+ENTRY_END
+
+STEP 8450 QUERY
+ENTRY_BEGIN
+RAW
+0000000060022238dcbc0000020405b40000
+ENTRY_END
+
+STEP 8460 QUERY
+ENTRY_BEGIN
+RAW
+b69ef086501022384d440000000000000000
+ENTRY_END
+
+STEP 8470 QUERY
+ENTRY_BEGIN
+RAW
+b69ef08650182238ae2500000022a14e000000010000000000000d726567627772667279736c616e026e6c0000060001
+ENTRY_END
+
+STEP 8480 QUERY
+ENTRY_BEGIN
+RAW
+b69ef0ec501022384cba0000000000000000
+ENTRY_END
+
+STEP 8490 QUERY
+ENTRY_BEGIN
+RAW
+b69ef0ec501122384cb90000000000000000
+ENTRY_END
+
+STEP 8500 QUERY
+ENTRY_BEGIN
+RAW
+b69ef0ed501022384cb80000000000000000
+ENTRY_END
+
+STEP 8510 QUERY
+ENTRY_BEGIN
+RAW
+b69b68c35010222a7bcb0000000000000000
+ENTRY_END
+
+STEP 8520 QUERY
+ENTRY_BEGIN
+RAW
+b68303575018faf04b560000008df340000000010001000000000f313036353135313838393432362d320000f900010f313036353135313838393432362d320000f900ff00000000005103677373096d6963726f736f667403636f6d00403afd16403c4e9600030000002e4e544c4d535350000100000097b208e0070007002700000007000700200000005245545f4653315245544152434f0000
+ENTRY_END
+
+STEP 8530 QUERY
+ENTRY_BEGIN
+RAW
+b68303575018faf04b560000008df340000000010001000000000f313036353135313838393432362d320000f900010f313036353135313838393432362d320000f900ff00000000005103677373096d6963726f736f667403636f6d00403afd16403c4e9600030000002e4e544c4d535350000100000097b208e0070007002700000007000700200000005245545f4653315245544152434f0000
+ENTRY_END
+
+STEP 8540 QUERY
+ENTRY_BEGIN
+RAW
+b68303655011fae21a560000000000000000
+ENTRY_END
+
+STEP 8550 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf041b60000020405b401010402
+ENTRY_END
+
+STEP 8560 QUERY
+ENTRY_BEGIN
+RAW
+b68303665010fae21a550000000000000000
+ENTRY_END
+
+STEP 8570 QUERY
+ENTRY_BEGIN
+RAW
+b69faca65010faf00b240000000000000000
+ENTRY_END
+
+STEP 8580 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000b3a50000020405b401010402
+ENTRY_END
+
+STEP 8590 QUERY
+ENTRY_BEGIN
+RAW
+b6a1a840501044707d070000000000000000
+ENTRY_END
+
+STEP 8600 QUERY
+ENTRY_BEGIN
+RAW
+b6a1a84050184470f4c200000089cc64000000010001000000000f313036353135313838393432362d330000f900010f313036353135313838393432362d330000f900ff00000000004d03677373096d6963726f736f667403636f6d00403b7dfc403ccf7c00030000002a4e544c4d535350000100000097b200c004000400260000000600060020000000534552564552574151460000
+ENTRY_END
+
+STEP 8610 QUERY
+ENTRY_BEGIN
+RAW
+b6a1a84e501144627c7b0000000000000000
+ENTRY_END
+
+STEP 8620 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000ecb50000020405b401010402
+ENTRY_END
+
+STEP 8630 QUERY
+ENTRY_BEGIN
+RAW
+b6a1a84f501044627c7a0000000000000000
+ENTRY_END
+
+STEP 8640 QUERY
+ENTRY_BEGIN
+RAW
+b6a27e2c50104470e02a0000000000000000
+ENTRY_END
+
+STEP 8650 QUERY
+ENTRY_BEGIN
+RAW
+b6a27e2c501844708c830000008998c8000000010001000000000f313036353135313838393432362d320000f900010f313036353135313838393432362d320000f900ff00000000004d03677373096d6963726f736f667403636f6d00403b7dfc403ccf7c00030000002a4e544c4d535350000100000097b200c004000400260000000600060020000000534552564552574151460000
+ENTRY_END
+
+STEP 8660 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400050a700000204055001010402
+ENTRY_END
+
+STEP 8670 QUERY
+ENTRY_BEGIN
+RAW
+b6a27e3a50114462df9e0000000000000000
+ENTRY_END
+
+STEP 8680 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000b8ba0000020405b401010402
+ENTRY_END
+
+STEP 8690 QUERY
+ENTRY_BEGIN
+RAW
+0000000060022238473c0000020405b40000
+ENTRY_END
+
+STEP 8700 QUERY
+ENTRY_BEGIN
+RAW
+b6a2fbb450104510c58f0000000000000000
+ENTRY_END
+
+STEP 8710 QUERY
+ENTRY_BEGIN
+RAW
+b6a27e3b50104462df9d0000000000000000
+ENTRY_END
+
+STEP 8720 QUERY
+ENTRY_BEGIN
+RAW
+b6a2fbb4501845108d3c0000008b6710000000010001000000000f313238383439303138383831382d330000f900010f313238383439303138383831382d330000f900ff00000000004f03677373096d6963726f736f667403636f6d00403afc3b403c4dbb00030000002c4e544c4d535350000100000097b208e0060006002600000006000600200000005345525645524b4f525055540000
+ENTRY_END
+
+STEP 8730 QUERY
+ENTRY_BEGIN
+RAW
+b6a4048e50102238a3b60000000000000000
+ENTRY_END
+
+STEP 8740 QUERY
+ENTRY_BEGIN
+RAW
+b6a4048e5018223847ff000000213084000000010000000000000c636f7379636f6d7061676e79026e6c0000060001
+ENTRY_END
+
+STEP 8750 QUERY
+ENTRY_BEGIN
+RAW
+b6a3836950104470a6f10000000000000000
+ENTRY_END
+
+STEP 8760 QUERY
+ENTRY_BEGIN
+RAW
+b6a2fbc250114502c5010000000000000000
+ENTRY_END
+
+STEP 8770 QUERY
+ENTRY_BEGIN
+RAW
+b6a38369501844702ad200000089c140000000010001000000000f313036353135313838393432362d320000f900010f313036353135313838393432362d320000f900ff00000000004d03677373096d6963726f736f667403636f6d00403b7dfc403ccf7c00030000002a4e544c4d535350000100000097b200c004000400260000000600060020000000534552564552574151460000
+ENTRY_END
+
+STEP 8780 QUERY
+ENTRY_BEGIN
+RAW
+b6a404f350102238a32e0000000000000000
+ENTRY_END
+
+STEP 8790 QUERY
+ENTRY_BEGIN
+RAW
+b6a404f350112238a32d0000000000000000
+ENTRY_END
+
+STEP 8800 QUERY
+ENTRY_BEGIN
+RAW
+b6a2fbc350104502c5000000000000000000
+ENTRY_END
+
+STEP 8810 QUERY
+ENTRY_BEGIN
+RAW
+b6a404f450102238a32c0000000000000000
+ENTRY_END
+
+STEP 8820 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400097e000000204055001010402
+ENTRY_END
+
+STEP 8830 QUERY
+ENTRY_BEGIN
+RAW
+b6a3837750114462a6650000000000000000
+ENTRY_END
+
+STEP 8840 QUERY
+ENTRY_BEGIN
+RAW
+b6a4a43f50104510643c0000000000000000
+ENTRY_END
+
+STEP 8850 QUERY
+ENTRY_BEGIN
+RAW
+b6a4a43f50184510f6e30000008b9d16000000010001000000000f313238383439303138383831382d320000f900010f313238383439303138383831382d320000f900ff00000000004f03677373096d6963726f736f667403636f6d00403afc3b403c4dbb00030000002c4e544c4d535350000100000097b208e0060006002600000006000600200000005345525645524b4f525055540000
+ENTRY_END
+
+STEP 8860 QUERY
+ENTRY_BEGIN
+RAW
+b6a3837850104462a6640000000000000000
+ENTRY_END
+
+STEP 8870 QUERY
+ENTRY_BEGIN
+RAW
+b6a4a44d5011450263ae0000000000000000
+ENTRY_END
+
+STEP 8880 QUERY
+ENTRY_BEGIN
+RAW
+b6a4a44e5010450263ad0000000000000000
+ENTRY_END
+
+STEP 8890 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000b33700000204055001010402
+ENTRY_END
+
+STEP 8900 QUERY
+ENTRY_BEGIN
+RAW
+b6a5493c50104510da950000000000000000
+ENTRY_END
+
+STEP 8910 QUERY
+ENTRY_BEGIN
+RAW
+b6a5493c5018451037370000008bd31c000000010001000000000f313238383439303138383831382d320000f900010f313238383439303138383831382d320000f900ff00000000004f03677373096d6963726f736f667403636f6d00403afc3b403c4dbb00030000002c4e544c4d535350000100000097b208e0060006002600000006000600200000005345525645524b4f525055540000
+ENTRY_END
+
+STEP 8920 QUERY
+ENTRY_BEGIN
+RAW
+b6a5494a50114502da070000000000000000
+ENTRY_END
+
+STEP 8930 QUERY
+ENTRY_BEGIN
+RAW
+b6a5494b50104502da060000000000000000
+ENTRY_END
+
+STEP 8940 QUERY
+ENTRY_BEGIN
+RAW
+00000000700240004ad60000020405b401010402
+ENTRY_END
+
+STEP 8950 QUERY
+ENTRY_BEGIN
+RAW
+b6a82dab501044708ec60000000000000000
+ENTRY_END
+
+STEP 8960 QUERY
+ENTRY_BEGIN
+RAW
+b6a82dab50184470944f0000008b9351000000010001000000000e3839333335333139373538362d330000f900010e3839333335333139373538362d330000f900ff00000000005103677373096d6963726f736f667403636f6d00403afa97403c4c1700030000002e4e544c4d535350000100000097b200c0060006002800000008000800200000004c4150544f5037415a50444550330000
+ENTRY_END
+
+STEP 8970 QUERY
+ENTRY_BEGIN
+RAW
+b6a82db9501144628e380000000000000000
+ENTRY_END
+
+STEP 8980 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000adc20000020405b401010402
+ENTRY_END
+
+STEP 8990 QUERY
+ENTRY_BEGIN
+RAW
+b6a82dba501044628e370000000000000000
+ENTRY_END
+
+STEP 9000 QUERY
+ENTRY_BEGIN
+RAW
+b6a8c206501044705d570000000000000000
+ENTRY_END
+
+STEP 9010 QUERY
+ENTRY_BEGIN
+RAW
+b6a8c206501844702ecc0000008bc965000000010001000000000e3839333335333139373538362d320000f900010e3839333335333139373538362d320000f900ff00000000005103677373096d6963726f736f667403636f6d00403afa97403c4c1700030000002e4e544c4d535350000100000097b200c0060006002800000008000800200000004c4150544f5037415a50444550330000
+ENTRY_END
+
+STEP 9020 QUERY
+ENTRY_BEGIN
+RAW
+b6a8c214501144625cc90000000000000000
+ENTRY_END
+
+STEP 9030 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000c87d0000020405b401010402
+ENTRY_END
+
+STEP 9040 QUERY
+ENTRY_BEGIN
+RAW
+b6a8c215501044625cc80000000000000000
+ENTRY_END
+
+STEP 9050 QUERY
+ENTRY_BEGIN
+RAW
+b6a93e2050104470fbf70000000000000000
+ENTRY_END
+
+STEP 9060 QUERY
+ENTRY_BEGIN
+RAW
+b6a93e205018447049070000008b4bcb000000010001000000000e3839333335333139373538362d320000f900010e3839333335333139373538362d320000f900ff00000000005103677373096d6963726f736f667403636f6d00403afa98403c4c1800030000002e4e544c4d535350000100000097b200c0060006002800000008000800200000004c4150544f5037415a50444550330000
+ENTRY_END
+
+STEP 9070 QUERY
+ENTRY_BEGIN
+RAW
+b6a93e2e50114462fb690000000000000000
+ENTRY_END
+
+STEP 9080 QUERY
+ENTRY_BEGIN
+RAW
+b6a93e2f50104462fb680000000000000000
+ENTRY_END
+
+STEP 9090 QUERY
+ENTRY_BEGIN
+RAW
+b69cc936501022384c2b0000000000000000
+ENTRY_END
+
+STEP 9100 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf0235a0000020405b401010402
+ENTRY_END
+
+STEP 9110 QUERY
+ENTRY_BEGIN
+RAW
+b6ab2c4f5010faf06d130000000000000000
+ENTRY_END
+
+STEP 9120 QUERY
+ENTRY_BEGIN
+RAW
+b6ab2c4f5018faf057b60000008ece11000000010001000000000f313133333837313336363136322d330000f900010f313133333837313336363136322d330000f900ff00000000005203677373096d6963726f736f667403636f6d00403af4fb403c467b00030000002f4e544c4d535350000100000097b208e00600060029000000090009002000000049572d303031373232544b544553540000
+ENTRY_END
+
+STEP 9130 QUERY
+ENTRY_BEGIN
+RAW
+b6ab2c5d5011fae26c820000000000000000
+ENTRY_END
+
+STEP 9140 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf0d00e0000020405b401010402
+ENTRY_END
+
+STEP 9150 QUERY
+ENTRY_BEGIN
+RAW
+b6ab2c5e5010fae26c810000000000000000
+ENTRY_END
+
+STEP 9160 QUERY
+ENTRY_BEGIN
+RAW
+b6aba8ae5010faf09d680000000000000000
+ENTRY_END
+
+STEP 9170 QUERY
+ENTRY_BEGIN
+RAW
+b6aba8ae5018faf09fa00000008eb77d000000010001000000000f313133333837313336363136322d320000f900010f313133333837313336363136322d320000f900ff00000000005203677373096d6963726f736f667403636f6d00403af4fb403c467b00030000002f4e544c4d535350000100000097b208e00600060029000000090009002000000049572d303031373232544b544553540000
+ENTRY_END
+
+STEP 9180 QUERY
+ENTRY_BEGIN
+RAW
+b6aba8bc5011fae29cd70000000000000000
+ENTRY_END
+
+STEP 9190 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf0ca480000020405b401010402
+ENTRY_END
+
+STEP 9200 QUERY
+ENTRY_BEGIN
+RAW
+b6aba8bd5010fae29cd60000000000000000
+ENTRY_END
+
+STEP 9210 QUERY
+ENTRY_BEGIN
+RAW
+b6ac8a535010faf0b5fc0000000000000000
+ENTRY_END
+
+STEP 9220 QUERY
+ENTRY_BEGIN
+RAW
+b6ac8a535018faf07d360000008ef27b000000010001000000000f313133333837313336363136322d320000f900010f313133333837313336363136322d320000f900ff00000000005203677373096d6963726f736f667403636f6d00403af4fb403c467b00030000002f4e544c4d535350000100000097b208e00600060029000000090009002000000049572d303031373232544b544553540000
+ENTRY_END
+
+STEP 9230 QUERY
+ENTRY_BEGIN
+RAW
+b6ac8a615011fae2b56b0000000000000000
+ENTRY_END
+
+STEP 9240 QUERY
+ENTRY_BEGIN
+RAW
+b6ac8a625010fae2b56a0000000000000000
+ENTRY_END
+
+STEP 9250 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf0d5990000020405b401010402
+ENTRY_END
+
+STEP 9260 QUERY
+ENTRY_BEGIN
+RAW
+b6ad439b5010faf008050000000000000000
+ENTRY_END
+
+STEP 9270 QUERY
+ENTRY_BEGIN
+RAW
+b6ad439b5018faf01c6c0000009404ed000000010001000000000f313038323333313735383631302d330000f900010f313038323333313735383631302d330000f900ff00000000005803677373096d6963726f736f667403636f6d00403afd46403c4ec60003000000354e544c4d535350000100000097b208e00c000c0029000000090009002000000057454253455256455244455749542d424f454b454c0000
+ENTRY_END
+
+STEP 9280 QUERY
+ENTRY_BEGIN
+RAW
+b6ad43a95011fae2076e0000000000000000
+ENTRY_END
+
+STEP 9290 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf0c84e0000020405b401010402
+ENTRY_END
+
+STEP 9300 QUERY
+ENTRY_BEGIN
+RAW
+b6ad43aa5010fae2076d0000000000000000
+ENTRY_END
+
+STEP 9310 QUERY
+ENTRY_BEGIN
+RAW
+b6af01195010faf03d3a0000000000000000
+ENTRY_END
+
+STEP 9320 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf015f200000204057a01010402
+ENTRY_END
+
+STEP 9330 QUERY
+ENTRY_BEGIN
+RAW
+b6afec4b5010fbec9e740000000000000000
+ENTRY_END
+
+STEP 9340 QUERY
+ENTRY_BEGIN
+RAW
+b6afec4b5018fbec1c5700000091d900000000010001000000000f313133333837313336363136322d330000f900010f313133333837313336363136322d330000f900ff00000000005503677373096d6963726f736f667403636f6d00403afed7403c50570003000000324e544c4d535350000100000097b208e00900090029000000090009002000000045422d5345525645524555524f42595445320000
+ENTRY_END
+
+STEP 9350 QUERY
+ENTRY_BEGIN
+RAW
+b6afec595011fbde9de00000000000000000
+ENTRY_END
+
+STEP 9360 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf040ad00000204057a01010402
+ENTRY_END
+
+STEP 9370 QUERY
+ENTRY_BEGIN
+RAW
+b6afec5a5010fbde9ddf0000000000000000
+ENTRY_END
+
+STEP 9380 QUERY
+ENTRY_BEGIN
+RAW
+00000000700240001ed00000020405b401010402
+ENTRY_END
+
+STEP 9390 QUERY
+ENTRY_BEGIN
+RAW
+b6b09cca5010fbec18b00000000000000000
+ENTRY_END
+
+STEP 9400 QUERY
+ENTRY_BEGIN
+RAW
+b6b09cca5018fbece393000000918d00000000010001000000000f313133333837313336363136322d320000f900010f313133333837313336363136322d320000f900ff00000000005503677373096d6963726f736f667403636f6d00403afed7403c50570003000000324e544c4d535350000100000097b208e00900090029000000090009002000000045422d5345525645524555524f42595445320000
+ENTRY_END
+
+STEP 9410 QUERY
+ENTRY_BEGIN
+RAW
+b6b17c0a5010447014580000000000000000
+ENTRY_END
+
+STEP 9420 QUERY
+ENTRY_BEGIN
+RAW
+b6b17c0a501844707e9d0000008bacbd000000010001000000000e3931303533333036363737302d330000f900010e3931303533333036363737302d330000f900ff00000000005103677373096d6963726f736f667403636f6d00403afd5b403c4edb00030000002e4e544c4d535350000100000097b200c00900090025000000050005002000000050432d3035574f524b47524f55500000
+ENTRY_END
+
+STEP 9430 QUERY
+ENTRY_BEGIN
+RAW
+b6b09cd85011fbde181c0000000000000000
+ENTRY_END
+
+STEP 9440 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf085cb00000204057a01010402
+ENTRY_END
+
+STEP 9450 QUERY
+ENTRY_BEGIN
+RAW
+b6b09cd95010fbde181b0000000000000000
+ENTRY_END
+
+STEP 9460 QUERY
+ENTRY_BEGIN
+RAW
+b6b17c185011446213ca0000000000000000
+ENTRY_END
+
+STEP 9470 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000f4030000020405b401010402
+ENTRY_END
+
+STEP 9480 QUERY
+ENTRY_BEGIN
+RAW
+b6b2661c5010fbec947a0000000000000000
+ENTRY_END
+
+STEP 9490 QUERY
+ENTRY_BEGIN
+RAW
+b6b2661c5018fbecab5e000000914100000000010001000000000f313133333837313336363136322d320000f900010f313133333837313336363136322d320000f900ff00000000005503677373096d6963726f736f667403636f6d00403afed7403c50570003000000324e544c4d535350000100000097b208e00900090029000000090009002000000045422d5345525645524555524f42595445320000
+ENTRY_END
+
+STEP 9500 QUERY
+ENTRY_BEGIN
+RAW
+b6b17c195010446213c90000000000000000
+ENTRY_END
+
+STEP 9510 QUERY
+ENTRY_BEGIN
+RAW
+b6b3418b5010447024090000000000000000
+ENTRY_END
+
+STEP 9520 QUERY
+ENTRY_BEGIN
+RAW
+b6b3418b5018447033d70000008b0935000000010001000000000e3931303533333036363737302d320000f900010e3931303533333036363737302d320000f900ff00000000005103677373096d6963726f736f667403636f6d00403afd5b403c4edb00030000002e4e544c4d535350000100000097b200c00900090025000000050005002000000050432d3035574f524b47524f55500000
+ENTRY_END
+
+STEP 9530 QUERY
+ENTRY_BEGIN
+RAW
+b6b2662a5011fbde93e60000000000000000
+ENTRY_END
+
+STEP 9540 QUERY
+ENTRY_BEGIN
+RAW
+00000000700240000c4d0000020405b401010402
+ENTRY_END
+
+STEP 9550 QUERY
+ENTRY_BEGIN
+RAW
+b6b3419950114462237b0000000000000000
+ENTRY_END
+
+STEP 9560 QUERY
+ENTRY_BEGIN
+RAW
+b6b2662b5010fbde93e50000000000000000
+ENTRY_END
+
+STEP 9570 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400045b80000020405b401010402
+ENTRY_END
+
+STEP 9580 QUERY
+ENTRY_BEGIN
+RAW
+b6b3419a50104462237a0000000000000000
+ENTRY_END
+
+STEP 9590 QUERY
+ENTRY_BEGIN
+RAW
+b6b4f31650104470c4300000000000000000
+ENTRY_END
+
+STEP 9600 QUERY
+ENTRY_BEGIN
+RAW
+b6b42daf50104470502d0000000000000000
+ENTRY_END
+
+STEP 9610 QUERY
+ENTRY_BEGIN
+RAW
+b6b4f3165018447077860000008b65ad000000010001000000000e3931303533333036363737302d320000f900010e3931303533333036363737302d320000f900ff00000000005103677373096d6963726f736f667403636f6d00403afd5b403c4edb00030000002e4e544c4d535350000100000097b200c00900090025000000050005002000000050432d3035574f524b47524f55500000
+ENTRY_END
+
+STEP 9620 QUERY
+ENTRY_BEGIN
+RAW
+b6b42daf5018447031a50000008fb8e6000000010001000000000f313238383439303138383831382d330000f900010f313238383439303138383831382d330000f900ff00000000005303677373096d6963726f736f667403636f6d00403afccd403c4e4d0003000000304e544c4d535350000100000097b208e0040004002c0000000c000c002000000044432d505245434953494f4e465331410000
+ENTRY_END
+
+STEP 9630 QUERY
+ENTRY_BEGIN
+RAW
+b6b4f32450114462c3a20000000000000000
+ENTRY_END
+
+STEP 9640 QUERY
+ENTRY_BEGIN
+RAW
+b6b42dbd501144624f9b0000000000000000
+ENTRY_END
+
+STEP 9650 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400016260000020405b401010402
+ENTRY_END
+
+STEP 9660 QUERY
+ENTRY_BEGIN
+RAW
+b6b4f32550104462c3a10000000000000000
+ENTRY_END
+
+STEP 9670 QUERY
+ENTRY_BEGIN
+RAW
+b6b42dbe501044624f9a0000000000000000
+ENTRY_END
+
+STEP 9680 QUERY
+ENTRY_BEGIN
+RAW
+b6b57d3e501044700a760000000000000000
+ENTRY_END
+
+STEP 9690 QUERY
+ENTRY_BEGIN
+RAW
+b6b57d3e501844703aa10000008f6b34000000010001000000000f313238383439303138383831382d320000f900010f313238383439303138383831382d320000f900ff00000000005303677373096d6963726f736f667403636f6d00403afccd403c4e4d0003000000304e544c4d535350000100000097b208e0040004002c0000000c000c002000000044432d505245434953494f4e465331410000
+ENTRY_END
+
+STEP 9700 QUERY
+ENTRY_BEGIN
+RAW
+b6b57d4c5011446209e40000000000000000
+ENTRY_END
+
+STEP 9710 QUERY
+ENTRY_BEGIN
+RAW
+00000000700240002b9e0000020405b401010402
+ENTRY_END
+
+STEP 9720 QUERY
+ENTRY_BEGIN
+RAW
+b6b57d4d5010446209e30000000000000000
+ENTRY_END
+
+STEP 9730 QUERY
+ENTRY_BEGIN
+RAW
+b6b667875010447035a40000000000000000
+ENTRY_END
+
+STEP 9740 QUERY
+ENTRY_BEGIN
+RAW
+b6b66787501844704d880000008f837b000000010001000000000f313238383439303138383831382d320000f900010f313238383439303138383831382d320000f900ff00000000005303677373096d6963726f736f667403636f6d00403afccd403c4e4d0003000000304e544c4d535350000100000097b208e0040004002c0000000c000c002000000044432d505245434953494f4e465331410000
+ENTRY_END
+
+STEP 9750 QUERY
+ENTRY_BEGIN
+RAW
+b6b667955011446235120000000000000000
+ENTRY_END
+
+STEP 9760 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf07fea0000020405b401010402
+ENTRY_END
+
+STEP 9770 QUERY
+ENTRY_BEGIN
+RAW
+b6b8e7615010faf00e840000000000000000
+ENTRY_END
+
+STEP 9780 QUERY
+ENTRY_BEGIN
+RAW
+b6b8e7615018faf014680000009b3a67000000010001000000000f313138353431303937333731342d330000f900010f313138353431303937333731342d330000f900ff00000000005f03677373096d6963726f736f667403636f6d00403af52c403c46ac00030000003c4e544c4d535350000100000097b208e00d000d002f0000000f000f0020000000474f52494e4348454d324b2d5342535656562d474f52494e4348454d0000
+ENTRY_END
+
+STEP 9790 QUERY
+ENTRY_BEGIN
+RAW
+b6b8e76f5011fae20de60000000000000000
+ENTRY_END
+
+STEP 9800 QUERY
+ENTRY_BEGIN
+RAW
+b6b8e7705010fae20de50000000000000000
+ENTRY_END
+
+STEP 9810 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf0f2b90000020405b401010402
+ENTRY_END
+
+STEP 9820 QUERY
+ENTRY_BEGIN
+RAW
+b6b964ca5010faf003ea0000000000000000
+ENTRY_END
+
+STEP 9830 QUERY
+ENTRY_BEGIN
+RAW
+b6b964ca5018faf076f60000009bce3f000000010001000000000f313138353431303937333731342d320000f900010f313138353431303937333731342d320000f900ff00000000005f03677373096d6963726f736f667403636f6d00403af52c403c46ac00030000003c4e544c4d535350000100000097b208e00d000d002f0000000f000f0020000000474f52494e4348454d324b2d5342535656562d474f52494e4348454d0000
+ENTRY_END
+
+STEP 9840 QUERY
+ENTRY_BEGIN
+RAW
+b6b964d85011fae2034c0000000000000000
+ENTRY_END
+
+STEP 9850 QUERY
+ENTRY_BEGIN
+RAW
+b6b964d95010fae2034b0000000000000000
+ENTRY_END
+
+STEP 9860 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf0cbb80000020405b401010402
+ENTRY_END
+
+STEP 9870 QUERY
+ENTRY_BEGIN
+RAW
+b6ba546e5010faf0ed430000000000000000
+ENTRY_END
+
+STEP 9880 QUERY
+ENTRY_BEGIN
+RAW
+b6ba546e5018faf0e7820000009b470d000000010001000000000f313138353431303937333731342d320000f900010f313138353431303937333731342d320000f900ff00000000005f03677373096d6963726f736f667403636f6d00403af52c403c46ac00030000003c4e544c4d535350000100000097b208e00d000d002f0000000f000f0020000000474f52494e4348454d324b2d5342535656562d474f52494e4348454d0000
+ENTRY_END
+
+STEP 9890 QUERY
+ENTRY_BEGIN
+RAW
+b6ba547c5011fae2eca50000000000000000
+ENTRY_END
+
+STEP 9900 QUERY
+ENTRY_BEGIN
+RAW
+b6b667965010446235110000000000000000
+ENTRY_END
+
+STEP 9910 QUERY
+ENTRY_BEGIN
+RAW
+b6ba547d5010fae2eca40000000000000000
+ENTRY_END
+
+STEP 9920 QUERY
+ENTRY_BEGIN
+RAW
+301400000001000000000000056162632d64026e6c00000f000100
+ENTRY_END
+
+STEP 9930 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400033180000020405b401010402
+ENTRY_END
+
+STEP 9940 QUERY
+ENTRY_BEGIN
+RAW
+b6bc703d5010447034620000000000000000
+ENTRY_END
+
+STEP 9950 QUERY
+ENTRY_BEGIN
+RAW
+b6bc703d50184470bc270000008b5640000000010001000000000f313138353431303937333731342d330000f900010f313138353431303937333731342d330000f900ff00000000004f03677373096d6963726f736f667403636f6d00403aff88403c510800030000002c4e544c4d535350000100000097b200e0060006002600000006000600200000004f4b465330314f4b42414e4b0000
+ENTRY_END
+
+STEP 9960 QUERY
+ENTRY_BEGIN
+RAW
+b6bc704b5011446233d40000000000000000
+ENTRY_END
+
+STEP 9970 QUERY
+ENTRY_BEGIN
+RAW
+00000000700240000f670000020405b401010402
+ENTRY_END
+
+STEP 9980 QUERY
+ENTRY_BEGIN
+RAW
+b6bc704c5010446233d30000000000000000
+ENTRY_END
+
+STEP 9990 QUERY
+ENTRY_BEGIN
+RAW
+b6bd08a65010447078470000000000000000
+ENTRY_END
+
+STEP 10000 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000a9bc0000020405b401010402
+ENTRY_END
+
+STEP 10010 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000db0500000204059801010402
+ENTRY_END
+
+STEP 10020 QUERY
+ENTRY_BEGIN
+RAW
+b6bd08a650184470054e0000008b5200000000010001000000000f313138353431303937333731342d320000f900010f313138353431303937333731342d320000f900ff00000000004f03677373096d6963726f736f667403636f6d00403aff88403c510800030000002c4e544c4d535350000100000097b200e0060006002600000006000600200000004f4b465330314f4b42414e4b0000
+ENTRY_END
+
+STEP 10030 QUERY
+ENTRY_BEGIN
+RAW
+b6bd08b45011446277b90000000000000000
+ENTRY_END
+
+STEP 10040 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400064bd0000020405b401010402
+ENTRY_END
+
+STEP 10050 QUERY
+ENTRY_BEGIN
+RAW
+b6be7cc050104320d0fe0000000000000000
+ENTRY_END
+
+STEP 10060 QUERY
+ENTRY_BEGIN
+RAW
+b6be7cc050184320edb00000008b052a000000010001000000000f313235343133303435303435302d330000f900010f313235343133303435303435302d330000f900ff00000000004f03677373096d6963726f736f667403636f6d00403afcf2403c4e7200030000002c4e544c4d535350000100000097b208e006000600260000000600060020000000564247495341564247444f4d0000
+ENTRY_END
+
+STEP 10070 QUERY
+ENTRY_BEGIN
+RAW
+b6bdaa435010447070ff0000000000000000
+ENTRY_END
+
+STEP 10080 QUERY
+ENTRY_BEGIN
+RAW
+b6bd08b55010446277b80000000000000000
+ENTRY_END
+
+STEP 10090 QUERY
+ENTRY_BEGIN
+RAW
+b6bf1e6b50104470b7d60000000000000000
+ENTRY_END
+
+STEP 10100 QUERY
+ENTRY_BEGIN
+RAW
+b6bdaa43501844701b0c0000008fee51000000010001000000000f313238383439303138383831382d330000f900010f313238383439303138383831382d330000f900ff00000000005303677373096d6963726f736f667403636f6d00403afcce403c4e4e0003000000304e544c4d535350000100000097b208e0040004002c0000000c000c002000000044432d505245434953494f4e465331410000
+ENTRY_END
+
+STEP 10110 QUERY
+ENTRY_BEGIN
+RAW
+b6bf1e6b5018447094dd0000008b0000000000010001000000000f313138353431303937333731342d320000f900010f313138353431303937333731342d320000f900ff00000000004f03677373096d6963726f736f667403636f6d00403aff89403c510900030000002c4e544c4d535350000100000097b200e0060006002600000006000600200000004f4b465330314f4b42414e4b0000
+ENTRY_END
+
+STEP 10120 QUERY
+ENTRY_BEGIN
+RAW
+b6be7cce50114312d0700000000000000000
+ENTRY_END
+
+STEP 10130 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000f0e400000204059801010402
+ENTRY_END
+
+STEP 10140 QUERY
+ENTRY_BEGIN
+RAW
+b6bf1e7950114462b7480000000000000000
+ENTRY_END
+
+STEP 10150 QUERY
+ENTRY_BEGIN
+RAW
+b6be7ccf50104312d06f0000000000000000
+ENTRY_END
+
+STEP 10160 QUERY
+ENTRY_BEGIN
+RAW
+b6c012365010432051660000000000000000
+ENTRY_END
+
+STEP 10170 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000502d0000020405b401010402
+ENTRY_END
+
+STEP 10180 QUERY
+ENTRY_BEGIN
+RAW
+b6bdaa5150114462706d0000000000000000
+ENTRY_END
+
+STEP 10190 QUERY
+ENTRY_BEGIN
+RAW
+b6c01236501843209f6a0000008bd4d8000000010001000000000f313235343133303435303435302d320000f900010f313235343133303435303435302d320000f900ff00000000004f03677373096d6963726f736f667403636f6d00403afcf2403c4e7200030000002c4e544c4d535350000100000097b208e006000600260000000600060020000000564247495341564247444f4d0000
+ENTRY_END
+
+STEP 10200 QUERY
+ENTRY_BEGIN
+RAW
+b6bf1e7a50104462b7470000000000000000
+ENTRY_END
+
+STEP 10210 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400049720000020405b401010402
+ENTRY_END
+
+STEP 10220 QUERY
+ENTRY_BEGIN
+RAW
+b6c0be4f5010447003610000000000000000
+ENTRY_END
+
+STEP 10230 QUERY
+ENTRY_BEGIN
+RAW
+b6c012445011431250d80000000000000000
+ENTRY_END
+
+STEP 10240 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400006b200000204059801010402
+ENTRY_END
+
+STEP 10250 QUERY
+ENTRY_BEGIN
+RAW
+b6c0be4f501844704c7700000098a800000000010001000000000f313034373937323032303234322d330000f900010f313034373937323032303234322d330000f900ff00000000005c03677373096d6963726f736f667403636f6d00403b3488403c86080003000000394e544c4d535350000100000097b200e00b000b002e0000000e000e00200000005352564e53485549534b414d45524445485549534b414d45520000
+ENTRY_END
+
+STEP 10260 QUERY
+ENTRY_BEGIN
+RAW
+b6bdaa5250104462706c0000000000000000
+ENTRY_END
+
+STEP 10270 QUERY
+ENTRY_BEGIN
+RAW
+b6c15b51501044705fa30000000000000000
+ENTRY_END
+
+STEP 10280 QUERY
+ENTRY_BEGIN
+RAW
+b6c0be5d5011446202c60000000000000000
+ENTRY_END
+
+STEP 10290 QUERY
+ENTRY_BEGIN
+RAW
+b6c012455010431250d70000000000000000
+ENTRY_END
+
+STEP 10300 QUERY
+ENTRY_BEGIN
+RAW
+b6c242d15010432036960000000000000000
+ENTRY_END
+
+STEP 10310 QUERY
+ENTRY_BEGIN
+RAW
+b6c15b515018447058630000008fa09f000000010001000000000f313238383439303138383831382d320000f900010f313238383439303138383831382d320000f900ff00000000005303677373096d6963726f736f667403636f6d00403afcce403c4e4e0003000000304e544c4d535350000100000097b208e0040004002c0000000c000c002000000044432d505245434953494f4e465331410000
+ENTRY_END
+
+STEP 10320 QUERY
+ENTRY_BEGIN
+RAW
+b6c242d1501843208bcc0000008bcda6000000010001000000000f313235343133303435303435302d320000f900010f313235343133303435303435302d320000f900ff00000000004f03677373096d6963726f736f667403636f6d00403afcf2403c4e7200030000002c4e544c4d535350000100000097b208e006000600260000000600060020000000564247495341564247444f4d0000
+ENTRY_END
+
+STEP 10330 QUERY
+ENTRY_BEGIN
+RAW
+b6c0be5e5010446202c50000000000000000
+ENTRY_END
+
+STEP 10340 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400051f60000020405b401010402
+ENTRY_END
+
+STEP 10350 QUERY
+ENTRY_BEGIN
+RAW
+b6c242df5011431236080000000000000000
+ENTRY_END
+
+STEP 10360 QUERY
+ENTRY_BEGIN
+RAW
+b6c2c4ef50104470fe870000000000000000
+ENTRY_END
+
+STEP 10370 QUERY
+ENTRY_BEGIN
+RAW
+b6c15b5f501144625f110000000000000000
+ENTRY_END
+
+STEP 10380 QUERY
+ENTRY_BEGIN
+RAW
+b6c2c4ef501844709c1f000000985480000000010001000000000f313034373937323032303234322d320000f900010f313034373937323032303234322d320000f900ff00000000005c03677373096d6963726f736f667403636f6d00403b3488403c86080003000000394e544c4d535350000100000097b200e00b000b002e0000000e000e00200000005352564e53485549534b414d45524445485549534b414d45520000
+ENTRY_END
+
+STEP 10390 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400028970000020405b401010402
+ENTRY_END
+
+STEP 10400 QUERY
+ENTRY_BEGIN
+RAW
+b6c242e05010431236070000000000000000
+ENTRY_END
+
+STEP 10410 QUERY
+ENTRY_BEGIN
+RAW
+b6c2c4fd50114462fdec0000000000000000
+ENTRY_END
+
+STEP 10420 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000c2030000020405b401010402
+ENTRY_END
+
+STEP 10430 QUERY
+ENTRY_BEGIN
+RAW
+b6c15b60501044625f100000000000000000
+ENTRY_END
+
+STEP 10440 QUERY
+ENTRY_BEGIN
+RAW
+b6c34b44501044704ed30000000000000000
+ENTRY_END
+
+STEP 10450 QUERY
+ENTRY_BEGIN
+RAW
+b6c3f5a6501044703ddd0000000000000000
+ENTRY_END
+
+STEP 10460 QUERY
+ENTRY_BEGIN
+RAW
+b6c34b44501844702f4c0000008fb8e6000000010001000000000f313238383439303138383831382d320000f900010f313238383439303138383831382d320000f900ff00000000005303677373096d6963726f736f667403636f6d00403afcce403c4e4e0003000000304e544c4d535350000100000097b208e0040004002c0000000c000c002000000044432d505245434953494f4e465331410000
+ENTRY_END
+
+STEP 10470 QUERY
+ENTRY_BEGIN
+RAW
+b6c3f5a650184470517400000098de80000000010001000000000f313034373937323032303234322d320000f900010f313034373937323032303234322d320000f900ff00000000005c03677373096d6963726f736f667403636f6d00403b3488403c86080003000000394e544c4d535350000100000097b200e00b000b002e0000000e000e00200000005352564e53485549534b414d45524445485549534b414d45520000
+ENTRY_END
+
+STEP 10480 QUERY
+ENTRY_BEGIN
+RAW
+b6c2c4fe50104462fdeb0000000000000000
+ENTRY_END
+
+STEP 10490 QUERY
+ENTRY_BEGIN
+RAW
+b6c3f5b4501144623d420000000000000000
+ENTRY_END
+
+STEP 10500 QUERY
+ENTRY_BEGIN
+RAW
+b6c34b52501144624e410000000000000000
+ENTRY_END
+
+STEP 10510 QUERY
+ENTRY_BEGIN
+RAW
+b6c3f5b5501044623d410000000000000000
+ENTRY_END
+
+STEP 10520 QUERY
+ENTRY_BEGIN
+RAW
+b6c34b53501044624e400000000000000000
+ENTRY_END
+
+STEP 10530 QUERY
+ENTRY_BEGIN
+RAW
+b69faca65018faf061d40000008dc500000000010001000000000f313036353135313838393432362d320000f900010f313036353135313838393432362d320000f900ff00000000005103677373096d6963726f736f667403636f6d00403afd1a403c4e9a00030000002e4e544c4d535350000100000097b208e0070007002700000007000700200000005245545f4653315245544152434f0000
+ENTRY_END
+
+STEP 10540 QUERY
+ENTRY_BEGIN
+RAW
+b69faca65018faf061d40000008dc500000000010001000000000f313036353135313838393432362d320000f900010f313036353135313838393432362d320000f900ff00000000005103677373096d6963726f736f667403636f6d00403afd1a403c4e9a00030000002e4e544c4d535350000100000097b208e0070007002700000007000700200000005245545f4653315245544152434f0000
+ENTRY_END
+
+STEP 10550 QUERY
+ENTRY_BEGIN
+RAW
+b69facb45011fae20a940000000000000000
+ENTRY_END
+
+STEP 10560 QUERY
+ENTRY_BEGIN
+RAW
+b69facb55010fae20a930000000000000000
+ENTRY_END
+
+STEP 10570 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf0b64800000204057a01010402
+ENTRY_END
+
+STEP 10580 QUERY
+ENTRY_BEGIN
+RAW
+b6c93a3c5010fbecf0c00000000000000000
+ENTRY_END
+
+STEP 10590 QUERY
+ENTRY_BEGIN
+RAW
+b6c93a3c5018fbecb7d2000000934464000000010001000000000f313133333837313336363136322d330000f900010f313133333837313336363136322d330000f900ff00000000005703677373096d6963726f736f667403636f6d00403af9e3403c4b630003000000344e544c4d535350000100000097b208e00a000a002a0000000a000a0020000000504f4d504f454d2d4d4d504f4d504f454e2d4d4d0000
+ENTRY_END
+
+STEP 10600 QUERY
+ENTRY_BEGIN
+RAW
+b6c93a4a5011fbdef02a0000000000000000
+ENTRY_END
+
+STEP 10610 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf0c71200000204057a01010402
+ENTRY_END
+
+STEP 10620 QUERY
+ENTRY_BEGIN
+RAW
+b6c93a4b5010fbdef0290000000000000000
+ENTRY_END
+
+STEP 10630 QUERY
+ENTRY_BEGIN
+RAW
+b6c9f1515010fbec4a750000000000000000
+ENTRY_END
+
+STEP 10640 QUERY
+ENTRY_BEGIN
+RAW
+b6c9f1515018fbec5e5f00000093f88c000000010001000000000f313133333837313336363136322d320000f900010f313133333837313336363136322d320000f900ff00000000005703677373096d6963726f736f667403636f6d00403af9e3403c4b630003000000344e544c4d535350000100000097b208e00a000a002a0000000a000a0020000000504f4d504f454d2d4d4d504f4d504f454e2d4d4d0000
+ENTRY_END
+
+STEP 10650 QUERY
+ENTRY_BEGIN
+RAW
+b6c9f15f5011fbde49df0000000000000000
+ENTRY_END
+
+STEP 10660 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf0e90c00000204057a01010402
+ENTRY_END
+
+STEP 10670 QUERY
+ENTRY_BEGIN
+RAW
+b6c9f1605010fbde49de0000000000000000
+ENTRY_END
+
+STEP 10680 QUERY
+ENTRY_BEGIN
+RAW
+b6cab1035010fbecacbc0000000000000000
+ENTRY_END
+
+STEP 10690 QUERY
+ENTRY_BEGIN
+RAW
+b6cab1035018fbec0c7f00000093acb4000000010001000000000f313133333837313336363136322d320000f900010f313133333837313336363136322d320000f900ff00000000005703677373096d6963726f736f667403636f6d00403af9e3403c4b630003000000344e544c4d535350000100000097b208e00a000a002a0000000a000a0020000000504f4d504f454d2d4d4d504f4d504f454e2d4d4d0000
+ENTRY_END
+
+STEP 10700 QUERY
+ENTRY_BEGIN
+RAW
+b6cab1115011fbdeac260000000000000000
+ENTRY_END
+
+STEP 10710 QUERY
+ENTRY_BEGIN
+RAW
+b6cab1125010fbdeac250000000000000000
+ENTRY_END
+
+STEP 10720 QUERY
+ENTRY_BEGIN
+RAW
+b6af01195018faf0d037000000948757000000010001000000000f313038323333313735383631302d320000f900010f313038323333313735383631302d320000f900ff00000000005803677373096d6963726f736f667403636f6d00403afd46403c4ec60003000000354e544c4d535350000100000097b208e00c000c0029000000090009002000000057454253455256455244455749542d424f454b454c0000
+ENTRY_END
+
+STEP 10730 QUERY
+ENTRY_BEGIN
+RAW
+b6af01275011fae23ca30000000000000000
+ENTRY_END
+
+STEP 10740 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf0b1b20000020405b401010402
+ENTRY_END
+
+STEP 10750 QUERY
+ENTRY_BEGIN
+RAW
+b6af01285010fae23ca20000000000000000
+ENTRY_END
+
+STEP 10760 QUERY
+ENTRY_BEGIN
+RAW
+b6cd10ad5010faf016ec0000000000000000
+ENTRY_END
+
+STEP 10770 QUERY
+ENTRY_BEGIN
+RAW
+b6cd10ad5018faf0499600000094e1aa000000010001000000000f313038323333313735383631302d320000f900010f313038323333313735383631302d320000f900ff00000000005803677373096d6963726f736f667403636f6d00403afd49403c4ec90003000000354e544c4d535350000100000097b208e00c000c0029000000090009002000000057454253455256455244455749542d424f454b454c0000
+ENTRY_END
+
+STEP 10780 QUERY
+ENTRY_BEGIN
+RAW
+b6cd10bb5011fae216550000000000000000
+ENTRY_END
+
+STEP 10790 QUERY
+ENTRY_BEGIN
+RAW
+b6cd10bc5010fae216540000000000000000
+ENTRY_END
+
+STEP 10800 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400090d30000020405b401010402
+ENTRY_END
+
+STEP 10810 QUERY
+ENTRY_BEGIN
+RAW
+b6cda384501008009b350000000000000000
+ENTRY_END
+
+STEP 10820 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf0a8680000020405b401010402
+ENTRY_END
+
+STEP 10830 QUERY
+ENTRY_BEGIN
+RAW
+b6cda384501044705ec50000000000000000
+ENTRY_END
+
+STEP 10840 QUERY
+ENTRY_BEGIN
+RAW
+b6ce7def5010faf0a05e0000000000000000
+ENTRY_END
+
+STEP 10850 QUERY
+ENTRY_BEGIN
+RAW
+b6ce7def5018faf0e2720000008b24c2000000010001000000000e3931303533333036363737302d330000f900010e3931303533333036363737302d330000f900ff00000000005103677373096d6963726f736f667403636f6d00403afab8403c4c3800030000002e4e544c4d535350000100000097b208e0080008002600000006000600200000005a374a3847374555524f4c494e450000
+ENTRY_END
+
+STEP 10860 QUERY
+ENTRY_BEGIN
+RAW
+b6cda384501844708c0d0000009b7900000000010001000000000f313038323333313735383631302d330000f900010f313038323333313735383631302d330000f900ff00000000005f03677373096d6963726f736f667403636f6d00403afcf3403c4e7300030000003c4e544c4d535350000100000097b200c00d000d002f0000000f000f00200000004148414e4f4f52442d5052494d55534148414e4f4f5244474f5557450000
+ENTRY_END
+
+STEP 10870 QUERY
+ENTRY_BEGIN
+RAW
+b6ce7dfd5011fae29fd00000000000000000
+ENTRY_END
+
+STEP 10880 QUERY
+ENTRY_BEGIN
+RAW
+b6ce7dfe5010fae29fcf0000000000000000
+ENTRY_END
+
+STEP 10890 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf0fa060000020405b401010402
+ENTRY_END
+
+STEP 10900 QUERY
+ENTRY_BEGIN
+RAW
+b6cda392501144625e270000000000000000
+ENTRY_END
+
+STEP 10910 QUERY
+ENTRY_BEGIN
+RAW
+b6cf35215010faf03aca0000000000000000
+ENTRY_END
+
+STEP 10920 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400097f50000020405b401010402
+ENTRY_END
+
+STEP 10930 QUERY
+ENTRY_BEGIN
+RAW
+b6cf35215018faf0e0430000008bc35c000000010001000000000e3931303533333036363737302d320000f900010e3931303533333036363737302d320000f900ff00000000005103677373096d6963726f736f667403636f6d00403afab8403c4c3800030000002e4e544c4d535350000100000097b208e0080008002600000006000600200000005a374a3847374555524f4c494e450000
+ENTRY_END
+
+STEP 10940 QUERY
+ENTRY_BEGIN
+RAW
+b6cf352f5011fae23a3c0000000000000000
+ENTRY_END
+
+STEP 10950 QUERY
+ENTRY_BEGIN
+RAW
+b6cda393501044625e260000000000000000
+ENTRY_END
+
+STEP 10960 QUERY
+ENTRY_BEGIN
+RAW
+b6cfdbce501008006a0b0000000000000000
+ENTRY_END
+
+STEP 10970 QUERY
+ENTRY_BEGIN
+RAW
+b6cfdbce501044702d9b0000000000000000
+ENTRY_END
+
+STEP 10980 QUERY
+ENTRY_BEGIN
+RAW
+b6cf35305010fae23a3b0000000000000000
+ENTRY_END
+
+STEP 10990 QUERY
+ENTRY_BEGIN
+RAW
+b6cfdbce5018447011640000009bc180000000010001000000000f313038323333313735383631302d320000f900010f313038323333313735383631302d320000f900ff00000000005f03677373096d6963726f736f667403636f6d00403afcf4403c4e7400030000003c4e544c4d535350000100000097b200c00d000d002f0000000f000f00200000004148414e4f4f52442d5052494d55534148414e4f4f5244474f5557450000
+ENTRY_END
+
+STEP 11000 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf04c930000020405b401010402
+ENTRY_END
+
+STEP 11010 QUERY
+ENTRY_BEGIN
+RAW
+b6d071415010faf051350000000000000000
+ENTRY_END
+
+STEP 11020 QUERY
+ENTRY_BEGIN
+RAW
+b6d071415018faf08e770000008b2b94000000010001000000000e3931303533333036363737302d320000f900010e3931303533333036363737302d320000f900ff00000000005103677373096d6963726f736f667403636f6d00403afab8403c4c3800030000002e4e544c4d535350000100000097b208e0080008002600000006000600200000005a374a3847374555524f4c494e450000
+ENTRY_END
+
+STEP 11030 QUERY
+ENTRY_BEGIN
+RAW
+b6d0714f5011fae250a70000000000000000
+ENTRY_END
+
+STEP 11040 QUERY
+ENTRY_BEGIN
+RAW
+b6cfdbdc501144622cfd0000000000000000
+ENTRY_END
+
+STEP 11050 QUERY
+ENTRY_BEGIN
+RAW
+b6d071505010fae250a60000000000000000
+ENTRY_END
+
+STEP 11060 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000ab920000020405b401010402
+ENTRY_END
+
+STEP 11070 QUERY
+ENTRY_BEGIN
+RAW
+b6cfdbdd501044622cfc0000000000000000
+ENTRY_END
+
+STEP 11080 QUERY
+ENTRY_BEGIN
+RAW
+b6d1320d5010080027680000000000000000
+ENTRY_END
+
+STEP 11090 QUERY
+ENTRY_BEGIN
+RAW
+b6d1320d50104470eaf70000000000000000
+ENTRY_END
+
+STEP 11100 QUERY
+ENTRY_BEGIN
+RAW
+b6d1320d50184470d5800000009bbac0000000010001000000000f313038323333313735383631302d320000f900010f313038323333313735383631302d320000f900ff00000000005f03677373096d6963726f736f667403636f6d00403afcf4403c4e7400030000003c4e544c4d535350000100000097b200c00d000d002f0000000f000f00200000004148414e4f4f52442d5052494d55534148414e4f4f5244474f5557450000
+ENTRY_END
+
+STEP 11110 QUERY
+ENTRY_BEGIN
+RAW
+b6d1321b50114462ea590000000000000000
+ENTRY_END
+
+STEP 11120 QUERY
+ENTRY_BEGIN
+RAW
+b6d1321c50104462ea580000000000000000
+ENTRY_END
+
+STEP 11130 QUERY
+ENTRY_BEGIN
+RAW
+301500000001000000000000056162632d64026e6c00000f000100
+ENTRY_END
+
+STEP 11140 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400082ad0000020405b401010402
+ENTRY_END
+
+STEP 11150 QUERY
+ENTRY_BEGIN
+RAW
+b6d481b85010447072640000000000000000
+ENTRY_END
+
+STEP 11160 QUERY
+ENTRY_BEGIN
+RAW
+b6d481b85010447072640000000000000000
+ENTRY_END
+
+STEP 11170 QUERY
+ENTRY_BEGIN
+RAW
+b6d481b8501844700b7c000000909cca000000010001000000000f313034373937323032303234322d330000f900010f313034373937323032303234322d330000f900ff00000000005403677373096d6963726f736f667403636f6d00403aff7d403c50fd0003000000314e544c4d535350000100000097b200e0080008002900000009000900200000004e542d53455256455248554c53424f55570000
+ENTRY_END
+
+STEP 11180 QUERY
+ENTRY_BEGIN
+RAW
+b6d481c65011446271d10000000000000000
+ENTRY_END
+
+STEP 11190 QUERY
+ENTRY_BEGIN
+RAW
+00000000700240008dc10000020405b401010402
+ENTRY_END
+
+STEP 11200 QUERY
+ENTRY_BEGIN
+RAW
+b6d481c75010446271d00000000000000000
+ENTRY_END
+
+STEP 11210 QUERY
+ENTRY_BEGIN
+RAW
+b6d481c75010446271d00000000000000000
+ENTRY_END
+
+STEP 11220 QUERY
+ENTRY_BEGIN
+RAW
+b6d75f37501044709ff60000000000000000
+ENTRY_END
+
+STEP 11230 QUERY
+ENTRY_BEGIN
+RAW
+b6d75f37501044709ff60000000000000000
+ENTRY_END
+
+STEP 11240 QUERY
+ENTRY_BEGIN
+RAW
+b6d75f37501844703a11000000909cc8000000010001000000000f313034373937323032303234322d320000f900010f313034373937323032303234322d320000f900ff00000000005403677373096d6963726f736f667403636f6d00403aff7d403c50fd0003000000314e544c4d535350000100000097b200e0080008002900000009000900200000004e542d53455256455248554c53424f55570000
+ENTRY_END
+
+STEP 11250 QUERY
+ENTRY_BEGIN
+RAW
+b6d75f45501144629f630000000000000000
+ENTRY_END
+
+STEP 11260 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000bf550000020405b401010402
+ENTRY_END
+
+STEP 11270 QUERY
+ENTRY_BEGIN
+RAW
+b6d75f46501044629f620000000000000000
+ENTRY_END
+
+STEP 11280 QUERY
+ENTRY_BEGIN
+RAW
+b6d75f46501044629f620000000000000000
+ENTRY_END
+
+STEP 11290 QUERY
+ENTRY_BEGIN
+RAW
+b6d84c5e50104470e4620000000000000000
+ENTRY_END
+
+STEP 11300 QUERY
+ENTRY_BEGIN
+RAW
+b6d84c5e50104470e4620000000000000000
+ENTRY_END
+
+STEP 11310 QUERY
+ENTRY_BEGIN
+RAW
+b6d84c5e501844707e7f000000909cc6000000010001000000000f313034373937323032303234322d320000f900010f313034373937323032303234322d320000f900ff00000000005403677373096d6963726f736f667403636f6d00403aff7d403c50fd0003000000314e544c4d535350000100000097b200e0080008002900000009000900200000004e542d53455256455248554c53424f55570000
+ENTRY_END
+
+STEP 11320 QUERY
+ENTRY_BEGIN
+RAW
+b6d84c6c50114462e3cf0000000000000000
+ENTRY_END
+
+STEP 11330 QUERY
+ENTRY_BEGIN
+RAW
+b6d84c6d50104462e3ce0000000000000000
+ENTRY_END
+
+STEP 11340 QUERY
+ENTRY_BEGIN
+RAW
+b6d84c6d50104462e3ce0000000000000000
+ENTRY_END
+
+STEP 11350 QUERY
+ENTRY_BEGIN
+RAW
+19400000000100000000000007616e74656e6e61026e6c00000f0001c0
+ENTRY_END
+
+STEP 11360 QUERY
+ENTRY_BEGIN
+RAW
+00000000700240002fa400000204057a01010402
+ENTRY_END
+
+STEP 11370 QUERY
+ENTRY_BEGIN
+RAW
+b6d9d267501041b8d1240000000000000000
+ENTRY_END
+
+STEP 11380 QUERY
+ENTRY_BEGIN
+RAW
+b6d9d267501841b8b41f000000945b40000000010001000000000f313034373937323032303234322d330000f900010f313034373937323032303234322d330000f900ff00000000005803677373096d6963726f736f667403636f6d00403afe2d403c4fad0003000000354e544c4d535350000100000097b200e0090009002c0000000c000c0020000000535445524e2d534552564552534552564552424f4c0000
+ENTRY_END
+
+STEP 11390 QUERY
+ENTRY_BEGIN
+RAW
+b6d9d275501141aad08d0000000000000000
+ENTRY_END
+
+STEP 11400 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400024ae00000204057a01010402
+ENTRY_END
+
+STEP 11410 QUERY
+ENTRY_BEGIN
+RAW
+b6d9d276501041aad08c0000000000000000
+ENTRY_END
+
+STEP 11420 QUERY
+ENTRY_BEGIN
+RAW
+b6da64c0501041b833d50000000000000000
+ENTRY_END
+
+STEP 11430 QUERY
+ENTRY_BEGIN
+RAW
+b6da64c0501841b84611000000942d00000000010001000000000f313034373937323032303234322d320000f900010f313034373937323032303234322d320000f900ff00000000005803677373096d6963726f736f667403636f6d00403afe2d403c4fad0003000000354e544c4d535350000100000097b200e0090009002c0000000c000c0020000000535445524e2d534552564552534552564552424f4c0000
+ENTRY_END
+
+STEP 11440 QUERY
+ENTRY_BEGIN
+RAW
+b6da64ce501141aa333e0000000000000000
+ENTRY_END
+
+STEP 11450 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000572500000204057a01010402
+ENTRY_END
+
+STEP 11460 QUERY
+ENTRY_BEGIN
+RAW
+b6da64cf501041aa333d0000000000000000
+ENTRY_END
+
+STEP 11470 QUERY
+ENTRY_BEGIN
+RAW
+b6db160b501041b8b5000000000000000000
+ENTRY_END
+
+STEP 11480 QUERY
+ENTRY_BEGIN
+RAW
+b6db160b501841b8ff3b00000094f500000000010001000000000f313034373937323032303234322d320000f900010f313034373937323032303234322d320000f900ff00000000005803677373096d6963726f736f667403636f6d00403afe2d403c4fad0003000000354e544c4d535350000100000097b200e0090009002c0000000c000c0020000000535445524e2d534552564552534552564552424f4c0000
+ENTRY_END
+
+STEP 11490 QUERY
+ENTRY_BEGIN
+RAW
+b6db1619501141aab4690000000000000000
+ENTRY_END
+
+STEP 11500 QUERY
+ENTRY_BEGIN
+RAW
+b6db161a501041aab4680000000000000000
+ENTRY_END
+
+STEP 11510 QUERY
+ENTRY_BEGIN
+RAW
+00000000700240009bd60000020405b401010402
+ENTRY_END
+
+STEP 11520 QUERY
+ENTRY_BEGIN
+RAW
+b6dcb7745010447055c90000000000000000
+ENTRY_END
+
+STEP 11530 QUERY
+ENTRY_BEGIN
+RAW
+b6dcb77450184470b7940000008af31e000000010001000000000f313133333837313336363136322d330000f900010f313133333837313336363136322d330000f900ff00000000004e03677373096d6963726f736f667403636f6d00403afd52403c4ed200030000002b4e544c4d535350000100000097b208e00400040027000000070007002000000050535257465331505352570000
+ENTRY_END
+
+STEP 11540 QUERY
+ENTRY_BEGIN
+RAW
+b6dcb78250114462553c0000000000000000
+ENTRY_END
+
+STEP 11550 QUERY
+ENTRY_BEGIN
+RAW
+b6dcb78350104462553b0000000000000000
+ENTRY_END
+
+STEP 11560 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000de930000020405b401010402
+ENTRY_END
+
+STEP 11570 QUERY
+ENTRY_BEGIN
+RAW
+b6dd42c2501044700d380000000000000000
+ENTRY_END
+
+STEP 11580 QUERY
+ENTRY_BEGIN
+RAW
+b6dd42c2501844709dac0000008ac576000000010001000000000f313133333837313336363136322d320000f900010f313133333837313336363136322d320000f900ff00000000004e03677373096d6963726f736f667403636f6d00403afd52403c4ed200030000002b4e544c4d535350000100000097b208e00400040027000000070007002000000050535257465331505352570000
+ENTRY_END
+
+STEP 11590 QUERY
+ENTRY_BEGIN
+RAW
+b6dd42d0501144620cab0000000000000000
+ENTRY_END
+
+STEP 11600 QUERY
+ENTRY_BEGIN
+RAW
+00000000700240002fe800000204056401010402
+ENTRY_END
+
+STEP 11610 QUERY
+ENTRY_BEGIN
+RAW
+b6dd42d1501044620caa0000000000000000
+ENTRY_END
+
+STEP 11620 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000d64a0000020405b401010402
+ENTRY_END
+
+STEP 11630 QUERY
+ENTRY_BEGIN
+RAW
+b6de7c0150104470cbae0000000000000000
+ENTRY_END
+
+STEP 11640 QUERY
+ENTRY_BEGIN
+RAW
+b6dde32a501040b0c1930000000000000000
+ENTRY_END
+
+STEP 11650 QUERY
+ENTRY_BEGIN
+RAW
+b6de7c015018447089cb0000008a97ce000000010001000000000f313133333837313336363136322d320000f900010f313133333837313336363136322d320000f900ff00000000004e03677373096d6963726f736f667403636f6d00403afd52403c4ed200030000002b4e544c4d535350000100000097b208e00400040027000000070007002000000050535257465331505352570000
+ENTRY_END
+
+STEP 11660 QUERY
+ENTRY_BEGIN
+RAW
+b6dde32a501840b028ec000000953809000000010001000000000f313135313035313233353334362d330000f900010f313135313035313233353334362d330000f900ff00000000005903677373096d6963726f736f667403636f6d00403b0270403c53f00003000000364e544c4d535350000100000097b200e00c000c002a0000000a000a00200000004f4d44454e4f4f522d314f4d44454e4f4f52442d48530000
+ENTRY_END
+
+STEP 11670 QUERY
+ENTRY_BEGIN
+RAW
+b6de7c0f50114462cb210000000000000000
+ENTRY_END
+
+STEP 11680 QUERY
+ENTRY_BEGIN
+RAW
+b6dde338501140a2c0fb0000000000000000
+ENTRY_END
+
+STEP 11690 QUERY
+ENTRY_BEGIN
+RAW
+b6de7c1050104462cb200000000000000000
+ENTRY_END
+
+STEP 11700 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000beb100000204056401010402
+ENTRY_END
+
+STEP 11710 QUERY
+ENTRY_BEGIN
+RAW
+b6dde339501040a2c0fa0000000000000000
+ENTRY_END
+
+STEP 11720 QUERY
+ENTRY_BEGIN
+RAW
+b6df39ac501040b0f9d90000000000000000
+ENTRY_END
+
+STEP 11730 QUERY
+ENTRY_BEGIN
+RAW
+b6df39ac501840b0a77000000095f2cb000000010001000000000f313135313035313233353334362d320000f900010f313135313035313233353334362d320000f900ff00000000005903677373096d6963726f736f667403636f6d00403b0270403c53f00003000000364e544c4d535350000100000097b200e00c000c002a0000000a000a00200000004f4d44454e4f4f522d314f4d44454e4f4f52442d48530000
+ENTRY_END
+
+STEP 11740 QUERY
+ENTRY_BEGIN
+RAW
+b6df39ba501140a2f9410000000000000000
+ENTRY_END
+
+STEP 11750 QUERY
+ENTRY_BEGIN
+RAW
+00000000700240008b4100000204056401010402
+ENTRY_END
+
+STEP 11760 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000e8b40000020405b401010402
+ENTRY_END
+
+STEP 11770 QUERY
+ENTRY_BEGIN
+RAW
+b6df39bb501040a2f9400000000000000000
+ENTRY_END
+
+STEP 11780 QUERY
+ENTRY_BEGIN
+RAW
+b6e211a950104470486d0000000000000000
+ENTRY_END
+
+STEP 11790 QUERY
+ENTRY_BEGIN
+RAW
+b6e12eb0501040b0d1630000000000000000
+ENTRY_END
+
+STEP 11800 QUERY
+ENTRY_BEGIN
+RAW
+b6e12eb0501840b0219a00000095502c000000010001000000000f313135313035313233353334362d320000f900010f313135313035313233353334362d320000f900ff00000000005903677373096d6963726f736f667403636f6d00403b0270403c53f00003000000364e544c4d535350000100000097b200e00c000c002a0000000a000a00200000004f4d44454e4f4f522d314f4d44454e4f4f52442d48530000
+ENTRY_END
+
+STEP 11810 QUERY
+ENTRY_BEGIN
+RAW
+b6e211a95018447060d90000008a3c7e000000010001000000000f313133333837313336363136322d330000f900010f313133333837313336363136322d330000f900ff00000000004e03677373096d6963726f736f667403636f6d00403afd52403c4ed200030000002b4e544c4d535350000100000097b208e00400040027000000070007002000000050535257465331505352570000
+ENTRY_END
+
+STEP 11820 QUERY
+ENTRY_BEGIN
+RAW
+b6e211b75011446247e00000000000000000
+ENTRY_END
+
+STEP 11830 QUERY
+ENTRY_BEGIN
+RAW
+b6e12ebe501140a2d0cb0000000000000000
+ENTRY_END
+
+STEP 11840 QUERY
+ENTRY_BEGIN
+RAW
+b6e211b85010446247df0000000000000000
+ENTRY_END
+
+STEP 11850 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000f6aa0000020405b401010402
+ENTRY_END
+
+STEP 11860 QUERY
+ENTRY_BEGIN
+RAW
+b6e2fd18501044706af30000000000000000
+ENTRY_END
+
+STEP 11870 QUERY
+ENTRY_BEGIN
+RAW
+b6e12ebf501040a2d0ca0000000000000000
+ENTRY_END
+
+STEP 11880 QUERY
+ENTRY_BEGIN
+RAW
+b6e2fd1850184470bff90000008a00e5000000010001000000000f313133333837313336363136322d320000f900010f313133333837313336363136322d320000f900ff00000000004e03677373096d6963726f736f667403636f6d00403afd52403c4ed200030000002b4e544c4d535350000100000097b208e00400040027000000070007002000000050535257465331505352570000
+ENTRY_END
+
+STEP 11890 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf077cb00000204057a01010402
+ENTRY_END
+
+STEP 11900 QUERY
+ENTRY_BEGIN
+RAW
+b6e2fd26501144626a660000000000000000
+ENTRY_END
+
+STEP 11910 QUERY
+ENTRY_BEGIN
+RAW
+b6e3b1255010fbec3b400000000000000000
+ENTRY_END
+
+STEP 11920 QUERY
+ENTRY_BEGIN
+RAW
+b6e3b1255018fbec7f23000000910700000000010001000000000f313133333837313336363136322d330000f900010f313133333837313336363136322d330000f900ff00000000005503677373096d6963726f736f667403636f6d00403afedd403c505d0003000000324e544c4d535350000100000097b208e00900090029000000090009002000000045422d5345525645524555524f42595445320000
+ENTRY_END
+
+STEP 11930 QUERY
+ENTRY_BEGIN
+RAW
+b6e2fd27501044626a650000000000000000
+ENTRY_END
+
+STEP 11940 QUERY
+ENTRY_BEGIN
+RAW
+00000000700240003b130000020405b401010402
+ENTRY_END
+
+STEP 11950 QUERY
+ENTRY_BEGIN
+RAW
+b6e476715010447036010000000000000000
+ENTRY_END
+
+STEP 11960 QUERY
+ENTRY_BEGIN
+RAW
+b6e3b1335011fbde3aac0000000000000000
+ENTRY_END
+
+STEP 11970 QUERY
+ENTRY_BEGIN
+RAW
+b6e4767150184470b8ae0000008ad33d000000010001000000000f313133333837313336363136322d320000f900010f313133333837313336363136322d320000f900ff00000000004e03677373096d6963726f736f667403636f6d00403afd52403c4ed200030000002b4e544c4d535350000100000097b208e00400040027000000070007002000000050535257465331505352570000
+ENTRY_END
+
+STEP 11980 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf053c700000204057a01010402
+ENTRY_END
+
+STEP 11990 QUERY
+ENTRY_BEGIN
+RAW
+b6e3b1345010fbde3aab0000000000000000
+ENTRY_END
+
+STEP 12000 QUERY
+ENTRY_BEGIN
+RAW
+b6e4767f5011446235740000000000000000
+ENTRY_END
+
+STEP 12010 QUERY
+ENTRY_BEGIN
+RAW
+b6e4f3175010fbecd5480000000000000000
+ENTRY_END
+
+STEP 12020 QUERY
+ENTRY_BEGIN
+RAW
+b6e476805010446235730000000000000000
+ENTRY_END
+
+STEP 12030 QUERY
+ENTRY_BEGIN
+RAW
+b6e4f3175018fbec01ad000000911f80000000010001000000000f313133333837313336363136322d320000f900010f313133333837313336363136322d320000f900ff00000000005503677373096d6963726f736f667403636f6d00403afedd403c505d0003000000324e544c4d535350000100000097b208e00900090029000000090009002000000045422d5345525645524555524f42595445320000
+ENTRY_END
+
+STEP 12040 QUERY
+ENTRY_BEGIN
+RAW
+b6e4f3255011fbded4b40000000000000000
+ENTRY_END
+
+STEP 12050 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf06dd600000204057a01010402
+ENTRY_END
+
+STEP 12060 QUERY
+ENTRY_BEGIN
+RAW
+b6e4f3265010fbded4b30000000000000000
+ENTRY_END
+
+STEP 12070 QUERY
+ENTRY_BEGIN
+RAW
+b6e56de55010fbec74890000000000000000
+ENTRY_END
+
+STEP 12080 QUERY
+ENTRY_BEGIN
+RAW
+b6e56de55018fbececec00000091d380000000010001000000000f313133333837313336363136322d320000f900010f313133333837313336363136322d320000f900ff00000000005503677373096d6963726f736f667403636f6d00403afedd403c505d0003000000324e544c4d535350000100000097b208e00900090029000000090009002000000045422d5345525645524555524f42595445320000
+ENTRY_END
+
+STEP 12090 QUERY
+ENTRY_BEGIN
+RAW
+0000000060022238f39c0000020405b40000
+ENTRY_END
+
+STEP 12100 QUERY
+ENTRY_BEGIN
+RAW
+b6e63c915010223817d20000000000000000
+ENTRY_END
+
+STEP 12110 QUERY
+ENTRY_BEGIN
+RAW
+b6e63c9150182238da820000001c90e30000000100000000000007636f6d616e6574026e6c0000060001
+ENTRY_END
+
+STEP 12120 QUERY
+ENTRY_BEGIN
+RAW
+b6e63cf15010223817540000000000000000
+ENTRY_END
+
+STEP 12130 QUERY
+ENTRY_BEGIN
+RAW
+b6e63cf15011223817530000000000000000
+ENTRY_END
+
+STEP 12140 QUERY
+ENTRY_BEGIN
+RAW
+b6e63cf25010223817520000000000000000
+ENTRY_END
+
+STEP 12150 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf03c730000020405b401010402
+ENTRY_END
+
+STEP 12160 QUERY
+ENTRY_BEGIN
+RAW
+b6e7f9de5010faf0b8600000000000000000
+ENTRY_END
+
+STEP 12170 QUERY
+ENTRY_BEGIN
+RAW
+b6e7f9de5018faf0c19a0000008b27c9000000010001000000000f313135313035313233353334362d330000f900010f313135313035313233353334362d330000f900ff00000000004f03677373096d6963726f736f667403636f6d00403afd58403c4ed800030000002c4e544c4d535350000100000097b208e00900090023000000030003002000000042494b42494b4d554c4445520000
+ENTRY_END
+
+STEP 12180 QUERY
+ENTRY_BEGIN
+RAW
+b6e7f9ec5011fae2b7d20000000000000000
+ENTRY_END
+
+STEP 12190 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf034940000020405b401010402
+ENTRY_END
+
+STEP 12200 QUERY
+ENTRY_BEGIN
+RAW
+b6e7f9ed5010fae2b7d10000000000000000
+ENTRY_END
+
+STEP 12210 QUERY
+ENTRY_BEGIN
+RAW
+b6e8bf205010faf0eb3e0000000000000000
+ENTRY_END
+
+STEP 12220 QUERY
+ENTRY_BEGIN
+RAW
+b6e8bf205018faf0b5f60000008b674c000000010001000000000f313135313035313233353334362d320000f900010f313135313035313233353334362d320000f900ff00000000004f03677373096d6963726f736f667403636f6d00403afd58403c4ed800030000002c4e544c4d535350000100000097b208e00900090023000000030003002000000042494b42494b4d554c4445520000
+ENTRY_END
+
+STEP 12230 QUERY
+ENTRY_BEGIN
+RAW
+b6e8bf2e5011fae2eab00000000000000000
+ENTRY_END
+
+STEP 12240 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf0aa3b0000020405b401010402
+ENTRY_END
+
+STEP 12250 QUERY
+ENTRY_BEGIN
+RAW
+b6e8bf2f5010fae2eaaf0000000000000000
+ENTRY_END
+
+STEP 12260 QUERY
+ENTRY_BEGIN
+RAW
+b6e9a47b5010faf07b8a0000000000000000
+ENTRY_END
+
+STEP 12270 QUERY
+ENTRY_BEGIN
+RAW
+b6e9a47b5018faf0b67b0000008bf712000000010001000000000f313135313035313233353334362d320000f900010f313135313035313233353334362d320000f900ff00000000004f03677373096d6963726f736f667403636f6d00403afd58403c4ed800030000002c4e544c4d535350000100000097b208e00900090023000000030003002000000042494b42494b4d554c4445520000
+ENTRY_END
+
+STEP 12280 QUERY
+ENTRY_BEGIN
+RAW
+b6e9a4895011fae27afc0000000000000000
+ENTRY_END
+
+STEP 12290 QUERY
+ENTRY_BEGIN
+RAW
+b6e9a48a5010fae27afb0000000000000000
+ENTRY_END
+
+STEP 12300 QUERY
+ENTRY_BEGIN
+RAW
+000000007002fc0080570000020405b401010402
+ENTRY_END
+
+STEP 12310 QUERY
+ENTRY_BEGIN
+RAW
+b6ebe7a65010fc000e790000000000000000
+ENTRY_END
+
+STEP 12320 QUERY
+ENTRY_BEGIN
+RAW
+b6ebe7a65004fc000e850000000000000000
+ENTRY_END
+
+STEP 12330 QUERY
+ENTRY_BEGIN
+RAW
+b6e56df35011fbde73f50000000000000000
+ENTRY_END
+
+STEP 12340 QUERY
+ENTRY_BEGIN
+RAW
+b6e56df45010fbde73f40000000000000000
+ENTRY_END
+
+STEP 12350 QUERY
+ENTRY_BEGIN
+RAW
+00000000700240001ad30000020405b401010402
+ENTRY_END
+
+STEP 12360 QUERY
+ENTRY_BEGIN
+RAW
+b6eddfed50104470ac3b0000000000000000
+ENTRY_END
+
+STEP 12370 QUERY
+ENTRY_BEGIN
+RAW
+b6eddfed50104470ac3b0000000000000000
+ENTRY_END
+
+STEP 12380 QUERY
+ENTRY_BEGIN
+RAW
+b6eddfed5018447026ab00000090b572000000010001000000000f313034373937323032303234322d330000f900010f313034373937323032303234322d330000f900ff00000000005403677373096d6963726f736f667403636f6d00403aff80403c51000003000000314e544c4d535350000100000097b200e0080008002900000009000900200000004e542d53455256455248554c53424f55570000
+ENTRY_END
+
+STEP 12390 QUERY
+ENTRY_BEGIN
+RAW
+b6eddffb50114462aba80000000000000000
+ENTRY_END
+
+STEP 12400 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000d8ab0000020405b401010402
+ENTRY_END
+
+STEP 12410 QUERY
+ENTRY_BEGIN
+RAW
+b6eddffc50104462aba70000000000000000
+ENTRY_END
+
+STEP 12420 QUERY
+ENTRY_BEGIN
+RAW
+b6eddffc50104462aba70000000000000000
+ENTRY_END
+
+STEP 12430 QUERY
+ENTRY_BEGIN
+RAW
+b6eed8705010447071900000000000000000
+ENTRY_END
+
+STEP 12440 QUERY
+ENTRY_BEGIN
+RAW
+b6eed8705010447071900000000000000000
+ENTRY_END
+
+STEP 12450 QUERY
+ENTRY_BEGIN
+RAW
+b6eed87050184470e4c000000090bdb2000000010001000000000f313034373937323032303234322d320000f900010f313034373937323032303234322d320000f900ff00000000005403677373096d6963726f736f667403636f6d00403aff80403c51000003000000314e544c4d535350000100000097b200e0080008002900000009000900200000004e542d53455256455248554c53424f55570000
+ENTRY_END
+
+STEP 12460 QUERY
+ENTRY_BEGIN
+RAW
+b6eed87e5011446270fd0000000000000000
+ENTRY_END
+
+STEP 12470 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000edab0000020405b401010402
+ENTRY_END
+
+STEP 12480 QUERY
+ENTRY_BEGIN
+RAW
+b6eed87f5010446270fc0000000000000000
+ENTRY_END
+
+STEP 12490 QUERY
+ENTRY_BEGIN
+RAW
+b6eed87f5010446270fc0000000000000000
+ENTRY_END
+
+STEP 12500 QUERY
+ENTRY_BEGIN
+RAW
+b6f167c150104470f73c0000000000000000
+ENTRY_END
+
+STEP 12510 QUERY
+ENTRY_BEGIN
+RAW
+b6f167c150104470f73c0000000000000000
+ENTRY_END
+
+STEP 12520 QUERY
+ENTRY_BEGIN
+RAW
+b6f167c150184470686f00000090bdb0000000010001000000000f313034373937323032303234322d320000f900010f313034373937323032303234322d320000f900ff00000000005403677373096d6963726f736f667403636f6d00403aff81403c51010003000000314e544c4d535350000100000097b200e0080008002900000009000900200000004e542d53455256455248554c53424f55570000
+ENTRY_END
+
+STEP 12530 QUERY
+ENTRY_BEGIN
+RAW
+b6f167cf50114462f6a90000000000000000
+ENTRY_END
+
+STEP 12540 QUERY
+ENTRY_BEGIN
+RAW
+b6f167d050104462f6a80000000000000000
+ENTRY_END
+
+STEP 12550 QUERY
+ENTRY_BEGIN
+RAW
+b6f167d050104462f6a80000000000000000
+ENTRY_END
+
+STEP 12560 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000bf770000020405b401010402
+ENTRY_END
+
+STEP 12570 QUERY
+ENTRY_BEGIN
+RAW
+b6f24c8350104470e4450000000000000000
+ENTRY_END
+
+STEP 12580 QUERY
+ENTRY_BEGIN
+RAW
+b6f24c8350184470a15400000096b1a8000000010001000000000f313135313035313233353334362d330000f900010f313135313035313233353334362d330000f900ff00000000005a03677373096d6963726f736f667403636f6d00403b0084403c52040003000000374e544c4d535350000100000097b208e00b000b002c0000000c000c00200000005748495a5a444f4d504443305748495a5a444f4d5044430000
+ENTRY_END
+
+STEP 12590 QUERY
+ENTRY_BEGIN
+RAW
+b6f24c9150114462e3ac0000000000000000
+ENTRY_END
+
+STEP 12600 QUERY
+ENTRY_BEGIN
+RAW
+b6f24c9250104462e3ab0000000000000000
+ENTRY_END
+
+STEP 12610 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000f0f20000020405b401010402
+ENTRY_END
+
+STEP 12620 QUERY
+ENTRY_BEGIN
+RAW
+b6f339b750104470288c0000000000000000
+ENTRY_END
+
+STEP 12630 QUERY
+ENTRY_BEGIN
+RAW
+b6f339b750184470906c0000009607d8000000010001000000000f313135313035313233353334362d320000f900010f313135313035313233353334362d320000f900ff00000000005a03677373096d6963726f736f667403636f6d00403b0084403c52040003000000374e544c4d535350000100000097b208e00b000b002c0000000c000c00200000005748495a5a444f4d504443305748495a5a444f4d5044430000
+ENTRY_END
+
+STEP 12640 QUERY
+ENTRY_BEGIN
+RAW
+b6f339c55011446227f30000000000000000
+ENTRY_END
+
+STEP 12650 QUERY
+ENTRY_BEGIN
+RAW
+b6f339c65010446227f20000000000000000
+ENTRY_END
+
+STEP 12660 QUERY
+ENTRY_BEGIN
+RAW
+00000000700240004f5f0000020405b401010402
+ENTRY_END
+
+STEP 12670 QUERY
+ENTRY_BEGIN
+RAW
+b6f41c4a50104470a4640000000000000000
+ENTRY_END
+
+STEP 12680 QUERY
+ENTRY_BEGIN
+RAW
+b6f41c4a50184470d9f4000000963a28000000010001000000000f313135313035313233353334362d320000f900010f313135313035313233353334362d320000f900ff00000000005a03677373096d6963726f736f667403636f6d00403b0084403c52040003000000374e544c4d535350000100000097b208e00b000b002c0000000c000c00200000005748495a5a444f4d504443305748495a5a444f4d5044430000
+ENTRY_END
+
+STEP 12690 QUERY
+ENTRY_BEGIN
+RAW
+b6f41c5850114462a3cb0000000000000000
+ENTRY_END
+
+STEP 12700 QUERY
+ENTRY_BEGIN
+RAW
+b6f41c5950104462a3ca0000000000000000
+ENTRY_END
+
+STEP 12710 QUERY
+ENTRY_BEGIN
+RAW
+00000000700222389b1f00000204057801010402
+ENTRY_END
+
+STEP 12720 QUERY
+ENTRY_BEGIN
+RAW
+b6f6588a50102648b4060000000000000000
+ENTRY_END
+
+STEP 12730 QUERY
+ENTRY_BEGIN
+RAW
+b6f6588a50182648a8900000008d3800000000010001000000000f313133333837313336363136322d330000f900010f313133333837313336363136322d330000f900ff00000000005103677373096d6963726f736f667403636f6d00403afca8403c4e2800030000002e4e544c4d535350000100000097b200e0080008002600000006000600200000005345525645524e4b4f45524945520000
+ENTRY_END
+
+STEP 12740 QUERY
+ENTRY_BEGIN
+RAW
+b6f658985011263ab3760000000000000000
+ENTRY_END
+
+STEP 12750 QUERY
+ENTRY_BEGIN
+RAW
+0000000070022238a91f00000204057801010402
+ENTRY_END
+
+STEP 12760 QUERY
+ENTRY_BEGIN
+RAW
+b6f658995010263ab3750000000000000000
+ENTRY_END
+
+STEP 12770 QUERY
+ENTRY_BEGIN
+RAW
+b6f74bfb50102648ce940000000000000000
+ENTRY_END
+
+STEP 12780 QUERY
+ENTRY_BEGIN
+RAW
+b6f74bfb50182648241f0000008dd800000000010001000000000f313133333837313336363136322d320000f900010f313133333837313336363136322d320000f900ff00000000005103677373096d6963726f736f667403636f6d00403afca8403c4e2800030000002e4e544c4d535350000100000097b200e0080008002600000006000600200000005345525645524e4b4f45524945520000
+ENTRY_END
+
+STEP 12790 QUERY
+ENTRY_BEGIN
+RAW
+b6f74c095011263ace040000000000000000
+ENTRY_END
+
+STEP 12800 QUERY
+ENTRY_BEGIN
+RAW
+0000000070022238c24f00000204057801010402
+ENTRY_END
+
+STEP 12810 QUERY
+ENTRY_BEGIN
+RAW
+b6f74c0a5010263ace030000000000000000
+ENTRY_END
+
+STEP 12820 QUERY
+ENTRY_BEGIN
+RAW
+b6f99ca65010264897170000000000000000
+ENTRY_END
+
+STEP 12830 QUERY
+ENTRY_BEGIN
+RAW
+b6f99ca6501826484ca20000008d7800000000010001000000000f313133333837313336363136322d320000f900010f313133333837313336363136322d320000f900ff00000000005103677373096d6963726f736f667403636f6d00403afca8403c4e2800030000002e4e544c4d535350000100000097b200e0080008002600000006000600200000005345525645524e4b4f45524945520000
+ENTRY_END
+
+STEP 12840 QUERY
+ENTRY_BEGIN
+RAW
+b6f99cb45011263a96870000000000000000
+ENTRY_END
+
+STEP 12850 QUERY
+ENTRY_BEGIN
+RAW
+b6f99cb55010263a96860000000000000000
+ENTRY_END
+
+STEP 12860 QUERY
+ENTRY_BEGIN
+RAW
+000000005014000081b30000636b6f000000
+ENTRY_END
+
+STEP 12870 QUERY
+ENTRY_BEGIN
+RAW
+0000000050140000f51e0000636b6f000000
+ENTRY_END
+
+STEP 12880 QUERY
+ENTRY_BEGIN
+RAW
+0000000050140000c43b0000636b6f000000
+ENTRY_END
+
+STEP 12890 QUERY
+ENTRY_BEGIN
+RAW
+00000000600222386cca0000020405b40000
+ENTRY_END
+
+STEP 12900 QUERY
+ENTRY_BEGIN
+RAW
+b6fbb85a5010223815210000000000000000
+ENTRY_END
+
+STEP 12910 QUERY
+ENTRY_BEGIN
+RAW
+b6fbb85a50182238a12f0000001e88140000000100000000000009766f6f67642d6b6f6b026e6c0000060001
+ENTRY_END
+
+STEP 12920 QUERY
+ENTRY_BEGIN
+RAW
+b6fbb8bc50102238149f0000000000000000
+ENTRY_END
+
+STEP 12930 QUERY
+ENTRY_BEGIN
+RAW
+b6fbb8bc50112238149e0000000000000000
+ENTRY_END
+
+STEP 12940 QUERY
+ENTRY_BEGIN
+RAW
+b6fbb8bd50102238149d0000000000000000
+ENTRY_END
+
+STEP 12950 QUERY
+ENTRY_BEGIN
+RAW
+0000000060022238dfe20000020405b40000
+ENTRY_END
+
+STEP 12960 QUERY
+ENTRY_BEGIN
+RAW
+b6fc71d950102238ceb90000000000000000
+ENTRY_END
+
+STEP 12970 QUERY
+ENTRY_BEGIN
+RAW
+b6fc71d950182238f94a0000002502290000000100000000000010766974616c6974656974736b756e6465026e6c0000060001
+ENTRY_END
+
+STEP 12980 QUERY
+ENTRY_BEGIN
+RAW
+b6fc724d50102238ce1e0000000000000000
+ENTRY_END
+
+STEP 12990 QUERY
+ENTRY_BEGIN
+RAW
+b6fc724d50112238ce1d0000000000000000
+ENTRY_END
+
+STEP 13000 QUERY
+ENTRY_BEGIN
+RAW
+b6fc724e50102238ce1c0000000000000000
+ENTRY_END
+
+STEP 13010 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000b9a300000204059801010402
+ENTRY_END
+
+STEP 13020 QUERY
+ENTRY_BEGIN
+RAW
+b6fe92d65010432099460000000000000000
+ENTRY_END
+
+STEP 13030 QUERY
+ENTRY_BEGIN
+RAW
+b6fe92d6501843209c2f000000851640000000010001000000000f313034373937323032303234322d330000f900010f313034373937323032303234322d330000f900ff00000000004903677373096d6963726f736f667403636f6d00403af8db403c4a5b0003000000264e544c4d535350000100000097b200e0030003002300000003000300200000004653345441300000
+ENTRY_END
+
+STEP 13040 QUERY
+ENTRY_BEGIN
+RAW
+000000007002fc0094110000020405b401010402
+ENTRY_END
+
+STEP 13050 QUERY
+ENTRY_BEGIN
+RAW
+b6fe92e45011431298be0000000000000000
+ENTRY_END
+
+STEP 13060 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400067be00000204059801010402
+ENTRY_END
+
+STEP 13070 QUERY
+ENTRY_BEGIN
+RAW
+000000006002223858200000020405b40000
+ENTRY_END
+
+STEP 13080 QUERY
+ENTRY_BEGIN
+RAW
+b6fe92e55010431298bd0000000000000000
+ENTRY_END
+
+STEP 13090 QUERY
+ENTRY_BEGIN
+RAW
+b70041ea50104320984b0000000000000000
+ENTRY_END
+
+STEP 13100 QUERY
+ENTRY_BEGIN
+RAW
+b701101d50102238a8ae0000000000000000
+ENTRY_END
+
+STEP 13110 QUERY
+ENTRY_BEGIN
+RAW
+b701101d50182238b793000000291b200000000100000000000014636f6d707574657272657061697263656e746572026e6c0000060001
+ENTRY_END
+
+STEP 13120 QUERY
+ENTRY_BEGIN
+RAW
+b70041ea50184320f17400000085c100000000010001000000000f313034373937323032303234322d320000f900010f313034373937323032303234322d320000f900ff00000000004903677373096d6963726f736f667403636f6d00403af8db403c4a5b0003000000264e544c4d535350000100000097b200e0030003002300000003000300200000004653345441300000
+ENTRY_END
+
+STEP 13130 QUERY
+ENTRY_BEGIN
+RAW
+b6ff4e015010fc00bbc40000000000000000
+ENTRY_END
+
+STEP 13140 QUERY
+ENTRY_BEGIN
+RAW
+b6ff4e015004fc00bbd00000000000000000
+ENTRY_END
+
+STEP 13150 QUERY
+ENTRY_BEGIN
+RAW
+b701108a50102238a8160000000000000000
+ENTRY_END
+
+STEP 13160 QUERY
+ENTRY_BEGIN
+RAW
+b701108a50112238a8150000000000000000
+ENTRY_END
+
+STEP 13170 QUERY
+ENTRY_BEGIN
+RAW
+b701108b50102238a8140000000000000000
+ENTRY_END
+
+STEP 13180 QUERY
+ENTRY_BEGIN
+RAW
+b70041f85011431297c30000000000000000
+ENTRY_END
+
+STEP 13190 QUERY
+ENTRY_BEGIN
+RAW
+00000000700240009fb600000204059801010402
+ENTRY_END
+
+STEP 13200 QUERY
+ENTRY_BEGIN
+RAW
+b70041f95010431297c20000000000000000
+ENTRY_END
+
+STEP 13210 QUERY
+ENTRY_BEGIN
+RAW
+b7018bc85010432086640000000000000000
+ENTRY_END
+
+STEP 13220 QUERY
+ENTRY_BEGIN
+RAW
+b7018bc8501843202e0e000000857280000000010001000000000f313034373937323032303234322d320000f900010f313034373937323032303234322d320000f900ff00000000004903677373096d6963726f736f667403636f6d00403af8db403c4a5b0003000000264e544c4d535350000100000097b200e0030003002300000003000300200000004653345441300000
+ENTRY_END
+
+STEP 13230 QUERY
+ENTRY_BEGIN
+RAW
+b7018bd65011431285dc0000000000000000
+ENTRY_END
+
+STEP 13240 QUERY
+ENTRY_BEGIN
+RAW
+000000006002223866280000020405b40000
+ENTRY_END
+
+STEP 13250 QUERY
+ENTRY_BEGIN
+RAW
+b7018bd75010431285db0000000000000000
+ENTRY_END
+
+STEP 13260 QUERY
+ENTRY_BEGIN
+RAW
+b7020e2c50102238b8a60000000000000000
+ENTRY_END
+
+STEP 13270 QUERY
+ENTRY_BEGIN
+RAW
+b7020e2c50182238cf5c000000253225000000010000000000001065766f6c7574696f6e2d64657369676e026e6c0000060001
+ENTRY_END
+
+STEP 13280 QUERY
+ENTRY_BEGIN
+RAW
+b7020e9550102238b8160000000000000000
+ENTRY_END
+
+STEP 13290 QUERY
+ENTRY_BEGIN
+RAW
+b7020e9550112238b8150000000000000000
+ENTRY_END
+
+STEP 13300 QUERY
+ENTRY_BEGIN
+RAW
+b7020e9650102238b8140000000000000000
+ENTRY_END
+
+STEP 13310 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400090c60000020405b401010402
+ENTRY_END
+
+STEP 13320 QUERY
+ENTRY_BEGIN
+RAW
+b70494e8501044706d1d0000000000000000
+ENTRY_END
+
+STEP 13330 QUERY
+ENTRY_BEGIN
+RAW
+b70494e8501844709bfe0000008b7900000000010001000000000f313133333837313336363136322d330000f900010f313133333837313336363136322d330000f900ff00000000004f03677373096d6963726f736f667403636f6d00403b0322403c54a200030000002c4e544c4d535350000100000097b200c006000600260000000600060020000000534552564552444f4d41494e0000
+ENTRY_END
+
+STEP 13340 QUERY
+ENTRY_BEGIN
+RAW
+b70494f6501144626c8f0000000000000000
+ENTRY_END
+
+STEP 13350 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400004750000020405b401010402
+ENTRY_END
+
+STEP 13360 QUERY
+ENTRY_BEGIN
+RAW
+b70494f7501044626c8e0000000000000000
+ENTRY_END
+
+STEP 13370 QUERY
+ENTRY_BEGIN
+RAW
+b705694f501044700c640000000000000000
+ENTRY_END
+
+STEP 13380 QUERY
+ENTRY_BEGIN
+RAW
+b705694f5018447094460000008b2100000000010001000000000f313133333837313336363136322d320000f900010f313133333837313336363136322d320000f900ff00000000004f03677373096d6963726f736f667403636f6d00403b0322403c54a200030000002c4e544c4d535350000100000097b200c006000600260000000600060020000000534552564552444f4d41494e0000
+ENTRY_END
+
+STEP 13390 QUERY
+ENTRY_BEGIN
+RAW
+b705695d501144620bd60000000000000000
+ENTRY_END
+
+STEP 13400 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400017e90000020405b401010402
+ENTRY_END
+
+STEP 13410 QUERY
+ENTRY_BEGIN
+RAW
+b705695e501044620bd50000000000000000
+ENTRY_END
+
+STEP 13420 QUERY
+ENTRY_BEGIN
+RAW
+b7061c44501044706ce20000000000000000
+ENTRY_END
+
+STEP 13430 QUERY
+ENTRY_BEGIN
+RAW
+b7061c4450184470b6c40000008b5f00000000010001000000000f313133333837313336363136322d320000f900010f313133333837313336363136322d320000f900ff00000000004f03677373096d6963726f736f667403636f6d00403b0322403c54a200030000002c4e544c4d535350000100000097b200c006000600260000000600060020000000534552564552444f4d41494e0000
+ENTRY_END
+
+STEP 13440 QUERY
+ENTRY_BEGIN
+RAW
+b7061c52501144626c540000000000000000
+ENTRY_END
+
+STEP 13450 QUERY
+ENTRY_BEGIN
+RAW
+b7061c53501044626c530000000000000000
+ENTRY_END
+
+STEP 13460 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf0117200000204057a01010402
+ENTRY_END
+
+STEP 13470 QUERY
+ENTRY_BEGIN
+RAW
+b706a5135010fbece0d50000000000000000
+ENTRY_END
+
+STEP 13480 QUERY
+ENTRY_BEGIN
+RAW
+b706a5135018fbec03ff00000093d84c000000010001000000000f313133333837313336363136322d330000f900010f313133333837313336363136322d330000f900ff00000000005703677373096d6963726f736f667403636f6d00403af9eb403c4b6b0003000000344e544c4d535350000100000097b208e00a000a002a0000000a000a0020000000504f4d504f454d2d4d4d504f4d504f454e2d4d4d0000
+ENTRY_END
+
+STEP 13490 QUERY
+ENTRY_BEGIN
+RAW
+b706a5215011fbdee03f0000000000000000
+ENTRY_END
+
+STEP 13500 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf0127e00000204057a01010402
+ENTRY_END
+
+STEP 13510 QUERY
+ENTRY_BEGIN
+RAW
+b706a5225010fbdee03e0000000000000000
+ENTRY_END
+
+STEP 13520 QUERY
+ENTRY_BEGIN
+RAW
+b70783b25010fbec03420000000000000000
+ENTRY_END
+
+STEP 13530 QUERY
+ENTRY_BEGIN
+RAW
+b70783b25018fbec7344000000938c74000000010001000000000f313133333837313336363136322d320000f900010f313133333837313336363136322d320000f900ff00000000005703677373096d6963726f736f667403636f6d00403af9eb403c4b6b0003000000344e544c4d535350000100000097b208e00a000a002a0000000a000a0020000000504f4d504f454d2d4d4d504f4d504f454e2d4d4d0000
+ENTRY_END
+
+STEP 13540 QUERY
+ENTRY_BEGIN
+RAW
+b70783c05011fbde02ac0000000000000000
+ENTRY_END
+
+STEP 13550 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf0facb00000204057a01010402
+ENTRY_END
+
+STEP 13560 QUERY
+ENTRY_BEGIN
+RAW
+b70783c15010fbde02ab0000000000000000
+ENTRY_END
+
+STEP 13570 QUERY
+ENTRY_BEGIN
+RAW
+b70825495010fbec49f80000000000000000
+ENTRY_END
+
+STEP 13580 QUERY
+ENTRY_BEGIN
+RAW
+b70825495018fbec05d300000093409c000000010001000000000f313133333837313336363136322d320000f900010f313133333837313336363136322d320000f900ff00000000005703677373096d6963726f736f667403636f6d00403af9eb403c4b6b0003000000344e544c4d535350000100000097b208e00a000a002a0000000a000a0020000000504f4d504f454d2d4d4d504f4d504f454e2d4d4d0000
+ENTRY_END
+
+STEP 13590 QUERY
+ENTRY_BEGIN
+RAW
+b70825575011fbde49620000000000000000
+ENTRY_END
+
+STEP 13600 QUERY
+ENTRY_BEGIN
+RAW
+22fc000000010000000000000b6361726565726665766572026e6c00000f000100
+ENTRY_END
+
+STEP 13610 QUERY
+ENTRY_BEGIN
+RAW
+b70825585010fbde49610000000000000000
+ENTRY_END
+
+STEP 13620 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf0e78d0000020405b401010402
+ENTRY_END
+
+STEP 13630 QUERY
+ENTRY_BEGIN
+RAW
+b70d802c5010faf0dd070000000000000000
+ENTRY_END
+
+STEP 13640 QUERY
+ENTRY_BEGIN
+RAW
+b70d802c5018faf0dbdc000000962509000000010001000000000f313131363639313439363937382d330000f900010f313131363639313439363937382d330000f900ff00000000005a03677373096d6963726f736f667403636f6d00403afd92403c4f120003000000374e544c4d535350000100000097b208e00e000e0029000000090009002000000053422d5345525645525a4f4e4e4556454c442d474f45530000
+ENTRY_END
+
+STEP 13650 QUERY
+ENTRY_BEGIN
+RAW
+b70d803a5011fae2dc6e0000000000000000
+ENTRY_END
+
+STEP 13660 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf053ff0000020405b401010402
+ENTRY_END
+
+STEP 13670 QUERY
+ENTRY_BEGIN
+RAW
+b70d803b5010fae2dc6d0000000000000000
+ENTRY_END
+
+STEP 13680 QUERY
+ENTRY_BEGIN
+RAW
+b70e3fda5010faf089ca0000000000000000
+ENTRY_END
+
+STEP 13690 QUERY
+ENTRY_BEGIN
+RAW
+b70e3fda5018faf0e04d00000096ce5b000000010001000000000f313131363639313439363937382d320000f900010f313131363639313439363937382d320000f900ff00000000005a03677373096d6963726f736f667403636f6d00403afd92403c4f120003000000374e544c4d535350000100000097b208e00e000e0029000000090009002000000053422d5345525645525a4f4e4e4556454c442d474f45530000
+ENTRY_END
+
+STEP 13700 QUERY
+ENTRY_BEGIN
+RAW
+b70e3fe85011fae289310000000000000000
+ENTRY_END
+
+STEP 13710 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf067a30000020405b401010402
+ENTRY_END
+
+STEP 13720 QUERY
+ENTRY_BEGIN
+RAW
+b70e3fe95010fae289300000000000000000
+ENTRY_END
+
+STEP 13730 QUERY
+ENTRY_BEGIN
+RAW
+b70f07c45010faf0d5830000000000000000
+ENTRY_END
+
+STEP 13740 QUERY
+ENTRY_BEGIN
+RAW
+b70f07c45018faf0907e0000009669e4000000010001000000000f313131363639313439363937382d320000f900010f313131363639313439363937382d320000f900ff00000000005a03677373096d6963726f736f667403636f6d00403afd92403c4f120003000000374e544c4d535350000100000097b208e00e000e0029000000090009002000000053422d5345525645525a4f4e4e4556454c442d474f45530000
+ENTRY_END
+
+STEP 13750 QUERY
+ENTRY_BEGIN
+RAW
+b70f07d25011fae2d4ea0000000000000000
+ENTRY_END
+
+STEP 13760 QUERY
+ENTRY_BEGIN
+RAW
+b70f07d35010fae2d4e90000000000000000
+ENTRY_END
+
+STEP 13770 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000d69200000204055001010402
+ENTRY_END
+
+STEP 13780 QUERY
+ENTRY_BEGIN
+RAW
+b711831550104510c3ab0000000000000000
+ENTRY_END
+
+STEP 13790 QUERY
+ENTRY_BEGIN
+RAW
+b711831550184510e4a100000096a500000000010001000000000f313231393737303731323038322d330000f900010f313231393737303731323038322d330000f900ff00000000005a03677373096d6963726f736f667403636f6d00403afd50403c4ed00003000000374e544c4d535350000100000097b200e00b000b002c0000000c000c002000000045584143542d534552564552515549434b4f46464943450000
+ENTRY_END
+
+STEP 13800 QUERY
+ENTRY_BEGIN
+RAW
+b711832350114502c3120000000000000000
+ENTRY_END
+
+STEP 13810 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000542500000204055001010402
+ENTRY_END
+
+STEP 13820 QUERY
+ENTRY_BEGIN
+RAW
+b711832450104502c3110000000000000000
+ENTRY_END
+
+STEP 13830 QUERY
+ENTRY_BEGIN
+RAW
+b7125b4b5010451069070000000000000000
+ENTRY_END
+
+STEP 13840 QUERY
+ENTRY_BEGIN
+RAW
+b7125b4b5018451033fe00000096fc00000000010001000000000f313231393737303731323038322d320000f900010f313231393737303731323038322d320000f900ff00000000005a03677373096d6963726f736f667403636f6d00403afd50403c4ed00003000000374e544c4d535350000100000097b200e00b000b002c0000000c000c002000000045584143542d534552564552515549434b4f46464943450000
+ENTRY_END
+
+STEP 13850 QUERY
+ENTRY_BEGIN
+RAW
+b7125b5950114502686e0000000000000000
+ENTRY_END
+
+STEP 13860 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000682c00000204055001010402
+ENTRY_END
+
+STEP 13870 QUERY
+ENTRY_BEGIN
+RAW
+b7125b5a50104502686d0000000000000000
+ENTRY_END
+
+STEP 13880 QUERY
+ENTRY_BEGIN
+RAW
+b71325bc50104510b29c0000000000000000
+ENTRY_END
+
+STEP 13890 QUERY
+ENTRY_BEGIN
+RAW
+b71325bc501845105d94000000961c00000000010001000000000f313231393737303731323038322d320000f900010f313231393737303731323038322d320000f900ff00000000005a03677373096d6963726f736f667403636f6d00403afd50403c4ed00003000000374e544c4d535350000100000097b200e00b000b002c0000000c000c002000000045584143542d534552564552515549434b4f46464943450000
+ENTRY_END
+
+STEP 13900 QUERY
+ENTRY_BEGIN
+RAW
+b71325ca50114502b2030000000000000000
+ENTRY_END
+
+STEP 13910 QUERY
+ENTRY_BEGIN
+RAW
+b71325cb50104502b2020000000000000000
+ENTRY_END
+
+STEP 13920 QUERY
+ENTRY_BEGIN
+RAW
+00000000700240000baa0000020405b401010402
+ENTRY_END
+
+STEP 13930 QUERY
+ENTRY_BEGIN
+RAW
+b71514c55010447068130000000000000000
+ENTRY_END
+
+STEP 13940 QUERY
+ENTRY_BEGIN
+RAW
+b71514c550184470206000000096ac6a000000010001000000000f313135313035313233353334362d330000f900010f313135313035313233353334362d330000f900ff00000000005a03677373096d6963726f736f667403636f6d00403b0089403c52090003000000374e544c4d535350000100000097b208e00b000b002c0000000c000c00200000005748495a5a444f4d504443305748495a5a444f4d5044430000
+ENTRY_END
+
+STEP 13950 QUERY
+ENTRY_BEGIN
+RAW
+b71514d350114462677a0000000000000000
+ENTRY_END
+
+STEP 13960 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400028780000020405b401010402
+ENTRY_END
+
+STEP 13970 QUERY
+ENTRY_BEGIN
+RAW
+b71514d45010446267790000000000000000
+ENTRY_END
+
+STEP 13980 QUERY
+ENTRY_BEGIN
+RAW
+b715995c50104470004a0000000000000000
+ENTRY_END
+
+STEP 13990 QUERY
+ENTRY_BEGIN
+RAW
+b715995c50184470d805000000968dfc000000010001000000000f313135313035313233353334362d320000f900010f313135313035313233353334362d320000f900ff00000000005a03677373096d6963726f736f667403636f6d00403b0089403c52090003000000374e544c4d535350000100000097b208e00b000b002c0000000c000c00200000005748495a5a444f4d504443305748495a5a444f4d5044430000
+ENTRY_END
+
+STEP 14000 QUERY
+ENTRY_BEGIN
+RAW
+b715996a50114462ffb00000000000000000
+ENTRY_END
+
+STEP 14010 QUERY
+ENTRY_BEGIN
+RAW
+b715996b50104462ffaf0000000000000000
+ENTRY_END
+
+STEP 14020 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000382b0000020405b401010402
+ENTRY_END
+
+STEP 14030 QUERY
+ENTRY_BEGIN
+RAW
+b71666215010447043370000000000000000
+ENTRY_END
+
+STEP 14040 QUERY
+ENTRY_BEGIN
+RAW
+b716662150184470b65200000096f29c000000010001000000000f313135313035313233353334362d320000f900010f313135313035313233353334362d320000f900ff00000000005a03677373096d6963726f736f667403636f6d00403b0089403c52090003000000374e544c4d535350000100000097b208e00b000b002c0000000c000c00200000005748495a5a444f4d504443305748495a5a444f4d5044430000
+ENTRY_END
+
+STEP 14050 QUERY
+ENTRY_BEGIN
+RAW
+b716662f50114462429e0000000000000000
+ENTRY_END
+
+STEP 14060 QUERY
+ENTRY_BEGIN
+RAW
+b716663050104462429d0000000000000000
+ENTRY_END
+
+STEP 14070 QUERY
+ENTRY_BEGIN
+RAW
+360d00000001000000000000076f62646e772d6e026e6c00000f000100
+ENTRY_END
+
+STEP 14080 QUERY
+ENTRY_BEGIN
+RAW
+000000007002fc009d690000020405b401010402
+ENTRY_END
+
+STEP 14090 QUERY
+ENTRY_BEGIN
+RAW
+b716edb85010fc00254e0000000000000000
+ENTRY_END
+
+STEP 14100 QUERY
+ENTRY_BEGIN
+RAW
+b716edb85004fc00255a0000000000000000
+ENTRY_END
+
+STEP 14110 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000b2e800000204059801010402
+ENTRY_END
+
+STEP 14120 QUERY
+ENTRY_BEGIN
+RAW
+b717c4505010432060f80000000000000000
+ENTRY_END
+
+STEP 14130 QUERY
+ENTRY_BEGIN
+RAW
+b717c450501843209c70000000905f78000000010001000000000f313131363639313439363937382d330000f900010f313131363639313439363937382d330000f900ff00000000005403677373096d6963726f736f667403636f6d00403affca403c514a0003000000314e544c4d535350000100000097b208e00e000e002300000003000300200000004653314245524b454e424f5343484e45540000
+ENTRY_END
+
+STEP 14140 QUERY
+ENTRY_BEGIN
+RAW
+b717c45e5011431260650000000000000000
+ENTRY_END
+
+STEP 14150 QUERY
+ENTRY_BEGIN
+RAW
+b717c45f5010431260640000000000000000
+ENTRY_END
+
+STEP 14160 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000514e00000204059801010402
+ENTRY_END
+
+STEP 14170 QUERY
+ENTRY_BEGIN
+RAW
+b71a45bc501043207def0000000000000000
+ENTRY_END
+
+STEP 14180 QUERY
+ENTRY_BEGIN
+RAW
+b71a45bc501843207c38000000909da8000000010001000000000f313131363639313439363937382d320000f900010f313131363639313439363937382d320000f900ff00000000005403677373096d6963726f736f667403636f6d00403affca403c514a0003000000314e544c4d535350000100000097b208e00e000e002300000003000300200000004653314245524b454e424f5343484e45540000
+ENTRY_END
+
+STEP 14190 QUERY
+ENTRY_BEGIN
+RAW
+b71a45ca501143127d5c0000000000000000
+ENTRY_END
+
+STEP 14200 QUERY
+ENTRY_BEGIN
+RAW
+b71a45cb501043127d5b0000000000000000
+ENTRY_END
+
+STEP 14210 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400019b400000204059801010402
+ENTRY_END
+
+STEP 14220 QUERY
+ENTRY_BEGIN
+RAW
+b71b20f9501043206b170000000000000000
+ENTRY_END
+
+STEP 14230 QUERY
+ENTRY_BEGIN
+RAW
+b71b20f9501843202b3000000090dbd8000000010001000000000f313131363639313439363937382d320000f900010f313131363639313439363937382d320000f900ff00000000005403677373096d6963726f736f667403636f6d00403affca403c514a0003000000314e544c4d535350000100000097b208e00e000e002300000003000300200000004653314245524b454e424f5343484e45540000
+ENTRY_END
+
+STEP 14240 QUERY
+ENTRY_BEGIN
+RAW
+b71b2107501143126a840000000000000000
+ENTRY_END
+
+STEP 14250 QUERY
+ENTRY_BEGIN
+RAW
+b71b2108501043126a830000000000000000
+ENTRY_END
+
+STEP 14260 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000c1f20000020405b401010402
+ENTRY_END
+
+STEP 14270 QUERY
+ENTRY_BEGIN
+RAW
+b71bae6b5010447084af0000000000000000
+ENTRY_END
+
+STEP 14280 QUERY
+ENTRY_BEGIN
+RAW
+b71bae6b50184470db5a0000008f3280000000010001000000000f313230323539303834323839382d330000f900010f313230323539303834323839382d330000f900ff00000000005303677373096d6963726f736f667403636f6d00403afdc9403c4f490003000000304e544c4d535350000100000097b200c0060006002a0000000a000a00200000004459534f53455256455244594e534f4c0000
+ENTRY_END
+
+STEP 14290 QUERY
+ENTRY_BEGIN
+RAW
+b71bae7950114462841d0000000000000000
+ENTRY_END
+
+STEP 14300 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400076f80000020405b401010402
+ENTRY_END
+
+STEP 14310 QUERY
+ENTRY_BEGIN
+RAW
+b71bae7a50104462841c0000000000000000
+ENTRY_END
+
+STEP 14320 QUERY
+ENTRY_BEGIN
+RAW
+b71c76fc5010447071230000000000000000
+ENTRY_END
+
+STEP 14330 QUERY
+ENTRY_BEGIN
+RAW
+b71c76fc5018447011cf0000008fe780000000010001000000000f313230323539303834323839382d320000f900010f313230323539303834323839382d320000f900ff00000000005303677373096d6963726f736f667403636f6d00403afdca403c4f4a0003000000304e544c4d535350000100000097b200c0060006002a0000000a000a00200000004459534f53455256455244594e534f4c0000
+ENTRY_END
+
+STEP 14340 QUERY
+ENTRY_BEGIN
+RAW
+b71c770a5011446270910000000000000000
+ENTRY_END
+
+STEP 14350 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400026c80000020405b401010402
+ENTRY_END
+
+STEP 14360 QUERY
+ENTRY_BEGIN
+RAW
+b71c770b5010446270900000000000000000
+ENTRY_END
+
+STEP 14370 QUERY
+ENTRY_BEGIN
+RAW
+3b00000000010000000000000b6361726565726665766572026e6c00000f000100
+ENTRY_END
+
+STEP 14380 QUERY
+ENTRY_BEGIN
+RAW
+b71e36195010447061d40000000000000000
+ENTRY_END
+
+STEP 14390 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000ab3200000204059801010402
+ENTRY_END
+
+STEP 14400 QUERY
+ENTRY_BEGIN
+RAW
+0524000000010000000000000c7065616e75747367616d6573026e6c00000f000100
+ENTRY_END
+
+STEP 14410 QUERY
+ENTRY_BEGIN
+RAW
+b71ee7585010432036330000000000000000
+ENTRY_END
+
+STEP 14420 QUERY
+ENTRY_BEGIN
+RAW
+b71ee758501843200b2b00000090c5f8000000010001000000000f313131363639313439363937382d330000f900010f313131363639313439363937382d330000f900ff00000000005403677373096d6963726f736f667403636f6d00403affca403c514a0003000000314e544c4d535350000100000097b208e00e000e002300000003000300200000004653314245524b454e424f5343484e45540000
+ENTRY_END
+
+STEP 14430 QUERY
+ENTRY_BEGIN
+RAW
+b71e361950184470a9800000008f4080000000010001000000000f313230323539303834323839382d320000f900010f313230323539303834323839382d320000f900ff00000000005303677373096d6963726f736f667403636f6d00403afdca403c4f4a0003000000304e544c4d535350000100000097b200c0060006002a0000000a000a00200000004459534f53455256455244594e534f4c0000
+ENTRY_END
+
+STEP 14440 QUERY
+ENTRY_BEGIN
+RAW
+b71ee7665011431235a00000000000000000
+ENTRY_END
+
+STEP 14450 QUERY
+ENTRY_BEGIN
+RAW
+b71e36275011446261420000000000000000
+ENTRY_END
+
+STEP 14460 QUERY
+ENTRY_BEGIN
+RAW
+b71ee76750104312359f0000000000000000
+ENTRY_END
+
+STEP 14470 QUERY
+ENTRY_BEGIN
+RAW
+b71e36285010446261410000000000000000
+ENTRY_END
+
+STEP 14480 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400054a900000204059801010402
+ENTRY_END
+
+STEP 14490 QUERY
+ENTRY_BEGIN
+RAW
+b71f842f5010432042d20000000000000000
+ENTRY_END
+
+STEP 14500 QUERY
+ENTRY_BEGIN
+RAW
+b71f842f50184320da9b000000900428000000010001000000000f313131363639313439363937382d320000f900010f313131363639313439363937382d320000f900ff00000000005403677373096d6963726f736f667403636f6d00403affca403c514a0003000000314e544c4d535350000100000097b208e00e000e002300000003000300200000004653314245524b454e424f5343484e45540000
+ENTRY_END
+
+STEP 14510 QUERY
+ENTRY_BEGIN
+RAW
+b71f843d50114312423f0000000000000000
+ENTRY_END
+
+STEP 14520 QUERY
+ENTRY_BEGIN
+RAW
+b71f843e50104312423e0000000000000000
+ENTRY_END
+
+STEP 14530 QUERY
+ENTRY_BEGIN
+RAW
+00000000700240005bc700000204059801010402
+ENTRY_END
+
+STEP 14540 QUERY
+ENTRY_BEGIN
+RAW
+b71fffa150104320ce7d0000000000000000
+ENTRY_END
+
+STEP 14550 QUERY
+ENTRY_BEGIN
+RAW
+0000000060022238ed610000020405b40000
+ENTRY_END
+
+STEP 14560 QUERY
+ENTRY_BEGIN
+RAW
+b71fffa150184320b59e00000090b4d0000000010001000000000f313131363639313439363937382d320000f900010f313131363639313439363937382d320000f900ff00000000005403677373096d6963726f736f667403636f6d00403affca403c514a0003000000314e544c4d535350000100000097b208e00e000e002300000003000300200000004653314245524b454e424f5343484e45540000
+ENTRY_END
+
+STEP 14570 QUERY
+ENTRY_BEGIN
+RAW
+b720f253501022385b9a0000000000000000
+ENTRY_END
+
+STEP 14580 QUERY
+ENTRY_BEGIN
+RAW
+b720f25350182238373e000000253f7f000000010000000000001074726f66656f2d616c6661726f6d656f026e6c0000060001
+ENTRY_END
+
+STEP 14590 QUERY
+ENTRY_BEGIN
+RAW
+b71fffaf50114312cdea0000000000000000
+ENTRY_END
+
+STEP 14600 QUERY
+ENTRY_BEGIN
+RAW
+b720f2bc501022385b0a0000000000000000
+ENTRY_END
+
+STEP 14610 QUERY
+ENTRY_BEGIN
+RAW
+b720f2bc501122385b090000000000000000
+ENTRY_END
+
+STEP 14620 QUERY
+ENTRY_BEGIN
+RAW
+b71fffb050104312cde90000000000000000
+ENTRY_END
+
+STEP 14630 QUERY
+ENTRY_BEGIN
+RAW
+b720f2bd501022385b080000000000000000
+ENTRY_END
+
+STEP 14640 QUERY
+ENTRY_BEGIN
+RAW
+16b8000000010000000000000b6379636c696e6732303030026e6c00000f000100
+ENTRY_END
+
+STEP 14650 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400044d80000020405b401010402
+ENTRY_END
+
+STEP 14660 QUERY
+ENTRY_BEGIN
+RAW
+b72633b05010447082450000000000000000
+ENTRY_END
+
+STEP 14670 QUERY
+ENTRY_BEGIN
+RAW
+b72633b050184470f04800000089b41c000000010001000000000f313036353135313838393432362d330000f900010f313036353135313838393432362d330000f900ff00000000004d03677373096d6963726f736f667403636f6d00403b7e0d403ccf8d00030000002a4e544c4d535350000100000097b200c004000400260000000600060020000000534552564552574151460000
+ENTRY_END
+
+STEP 14680 QUERY
+ENTRY_BEGIN
+RAW
+b72633be5011446281b90000000000000000
+ENTRY_END
+
+STEP 14690 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400033630000020405b401010402
+ENTRY_END
+
+STEP 14700 QUERY
+ENTRY_BEGIN
+RAW
+b72633bf5010446281b80000000000000000
+ENTRY_END
+
+STEP 14710 QUERY
+ENTRY_BEGIN
+RAW
+b726ed2d50104470b7520000000000000000
+ENTRY_END
+
+STEP 14720 QUERY
+ENTRY_BEGIN
+RAW
+b726ed2d5018447083f1000000895682000000010001000000000f313036353135313838393432362d320000f900010f313036353135313838393432362d320000f900ff00000000004d03677373096d6963726f736f667403636f6d00403b7e0d403ccf8d00030000002a4e544c4d535350000100000097b200c004000400260000000600060020000000534552564552574151460000
+ENTRY_END
+
+STEP 14730 QUERY
+ENTRY_BEGIN
+RAW
+b726ed3b50114462b6c60000000000000000
+ENTRY_END
+
+STEP 14740 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400037b50000020405b401010402
+ENTRY_END
+
+STEP 14750 QUERY
+ENTRY_BEGIN
+RAW
+b726ed3c50104462b6c50000000000000000
+ENTRY_END
+
+STEP 14760 QUERY
+ENTRY_BEGIN
+RAW
+b727b1b350104470f71d0000000000000000
+ENTRY_END
+
+STEP 14770 QUERY
+ENTRY_BEGIN
+RAW
+b727b1b350184470f7580000008922e6000000010001000000000f313036353135313838393432362d320000f900010f313036353135313838393432362d320000f900ff00000000004d03677373096d6963726f736f667403636f6d00403b7e0d403ccf8d00030000002a4e544c4d535350000100000097b200c004000400260000000600060020000000534552564552574151460000
+ENTRY_END
+
+STEP 14780 QUERY
+ENTRY_BEGIN
+RAW
+b727b1c150114462f6910000000000000000
+ENTRY_END
+
+STEP 14790 QUERY
+ENTRY_BEGIN
+RAW
+b727b1c250104462f6900000000000000000
+ENTRY_END
+
+STEP 14800 QUERY
+ENTRY_BEGIN
+RAW
+00000000700240008d750000020405b401010402
+ENTRY_END
+
+STEP 14810 QUERY
+ENTRY_BEGIN
+RAW
+b729774550104470874a0000000000000000
+ENTRY_END
+
+STEP 14820 QUERY
+ENTRY_BEGIN
+RAW
+b729774550184470362b0000008bed00000000010001000000000f313133333837313336363136322d330000f900010f313133333837313336363136322d330000f900ff00000000004f03677373096d6963726f736f667403636f6d00403b0328403c54a800030000002c4e544c4d535350000100000097b200c006000600260000000600060020000000534552564552444f4d41494e0000
+ENTRY_END
+
+STEP 14830 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf067e800000204056401010402
+ENTRY_END
+
+STEP 14840 QUERY
+ENTRY_BEGIN
+RAW
+b72977535011446286bc0000000000000000
+ENTRY_END
+
+STEP 14850 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000a8b50000020405b401010402
+ENTRY_END
+
+STEP 14860 QUERY
+ENTRY_BEGIN
+RAW
+b72a677e5010fd5c73370000000000000000
+ENTRY_END
+
+STEP 14870 QUERY
+ENTRY_BEGIN
+RAW
+b72977545010446286bb0000000000000000
+ENTRY_END
+
+STEP 14880 QUERY
+ENTRY_BEGIN
+RAW
+b72b311750104470e8b60000000000000000
+ENTRY_END
+
+STEP 14890 QUERY
+ENTRY_BEGIN
+RAW
+b72b311750184470f0980000008b9500000000010001000000000f313133333837313336363136322d320000f900010f313133333837313336363136322d320000f900ff00000000004f03677373096d6963726f736f667403636f6d00403b0328403c54a800030000002c4e544c4d535350000100000097b200c006000600260000000600060020000000534552564552444f4d41494e0000
+ENTRY_END
+
+STEP 14900 QUERY
+ENTRY_BEGIN
+RAW
+b72b312550114462e8280000000000000000
+ENTRY_END
+
+STEP 14910 QUERY
+ENTRY_BEGIN
+RAW
+b72a677e5018fd5c94760000008f430e000000010001000000000e3931303533333036363737302d330000f900010e3931303533333036363737302d330000f900ff00000000005503677373096d6963726f736f667403636f6d00403af354403c44d40003000000324e544c4d535350000100000097b208e00a000a0028000000080008002000000050434f4f535431364f4f535445494e4445520000
+ENTRY_END
+
+STEP 14920 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000c1d20000020405b401010402
+ENTRY_END
+
+STEP 14930 QUERY
+ENTRY_BEGIN
+RAW
+b72b312650104462e8270000000000000000
+ENTRY_END
+
+STEP 14940 QUERY
+ENTRY_BEGIN
+RAW
+b72c139b501044701f4f0000000000000000
+ENTRY_END
+
+STEP 14950 QUERY
+ENTRY_BEGIN
+RAW
+b72c139b50184470e9300000008bd300000000010001000000000f313133333837313336363136322d320000f900010f313133333837313336363136322d320000f900ff00000000004f03677373096d6963726f736f667403636f6d00403b0328403c54a800030000002c4e544c4d535350000100000097b200c006000600260000000600060020000000534552564552444f4d41494e0000
+ENTRY_END
+
+STEP 14960 QUERY
+ENTRY_BEGIN
+RAW
+b72a678c5011fd4e72a50000000000000000
+ENTRY_END
+
+STEP 14970 QUERY
+ENTRY_BEGIN
+RAW
+00000000700240006be700000204059801010402
+ENTRY_END
+
+STEP 14980 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf0a28e00000204056401010402
+ENTRY_END
+
+STEP 14990 QUERY
+ENTRY_BEGIN
+RAW
+b72c13a9501144621ec10000000000000000
+ENTRY_END
+
+STEP 15000 QUERY
+ENTRY_BEGIN
+RAW
+b72a678d5010fd4e72a40000000000000000
+ENTRY_END
+
+STEP 15010 QUERY
+ENTRY_BEGIN
+RAW
+b72cd229501043200c090000000000000000
+ENTRY_END
+
+STEP 15020 QUERY
+ENTRY_BEGIN
+RAW
+b72c13aa501044621ec00000000000000000
+ENTRY_END
+
+STEP 15030 QUERY
+ENTRY_BEGIN
+RAW
+b72cd2295018432050a20000008bbf42000000010001000000000f313235343133303435303435302d330000f900010f313235343133303435303435302d330000f900ff00000000004f03677373096d6963726f736f667403636f6d00403afd01403c4e8100030000002c4e544c4d535350000100000097b208e006000600260000000600060020000000564247495341564247444f4d0000
+ENTRY_END
+
+STEP 15040 QUERY
+ENTRY_BEGIN
+RAW
+b72da6d95010fd5c6e7f0000000000000000
+ENTRY_END
+
+STEP 15050 QUERY
+ENTRY_BEGIN
+RAW
+b72cd237501143120b7b0000000000000000
+ENTRY_END
+
+STEP 15060 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000577700000204059801010402
+ENTRY_END
+
+STEP 15070 QUERY
+ENTRY_BEGIN
+RAW
+b72da6d95018fd5cf1950000008fe336000000010001000000000e3931303533333036363737302d320000f900010e3931303533333036363737302d320000f900ff00000000005503677373096d6963726f736f667403636f6d00403af354403c44d40003000000324e544c4d535350000100000097b208e00a000a0028000000080008002000000050434f4f535431364f4f535445494e4445520000
+ENTRY_END
+
+STEP 15080 QUERY
+ENTRY_BEGIN
+RAW
+b72cd238501043120b7a0000000000000000
+ENTRY_END
+
+STEP 15090 QUERY
+ENTRY_BEGIN
+RAW
+b72e32b150104320970f0000000000000000
+ENTRY_END
+
+STEP 15100 QUERY
+ENTRY_BEGIN
+RAW
+b72e32b150184320e3db0000008bb810000000010001000000000f313235343133303435303435302d320000f900010f313235343133303435303435302d320000f900ff00000000004f03677373096d6963726f736f667403636f6d00403afd01403c4e8100030000002c4e544c4d535350000100000097b208e006000600260000000600060020000000564247495341564247444f4d0000
+ENTRY_END
+
+STEP 15110 QUERY
+ENTRY_BEGIN
+RAW
+b72da6e75011fd4e6ded0000000000000000
+ENTRY_END
+
+STEP 15120 QUERY
+ENTRY_BEGIN
+RAW
+b72e32bf5011431296810000000000000000
+ENTRY_END
+
+STEP 15130 QUERY
+ENTRY_BEGIN
+RAW
+00000000700240007aec00000204059801010402
+ENTRY_END
+
+STEP 15140 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf03bc200000204056401010402
+ENTRY_END
+
+STEP 15150 QUERY
+ENTRY_BEGIN
+RAW
+b72e32c05010431296800000000000000000
+ENTRY_END
+
+STEP 15160 QUERY
+ENTRY_BEGIN
+RAW
+b72ec244501043202af10000000000000000
+ENTRY_END
+
+STEP 15170 QUERY
+ENTRY_BEGIN
+RAW
+b72ec24450184320a80f0000008b87be000000010001000000000f313235343133303435303435302d320000f900010f313235343133303435303435302d320000f900ff00000000004f03677373096d6963726f736f667403636f6d00403afd01403c4e8100030000002c4e544c4d535350000100000097b208e006000600260000000600060020000000564247495341564247444f4d0000
+ENTRY_END
+
+STEP 15180 QUERY
+ENTRY_BEGIN
+RAW
+b72da6e85010fd4e6dec0000000000000000
+ENTRY_END
+
+STEP 15190 QUERY
+ENTRY_BEGIN
+RAW
+b72f4ee65010fd5c5fa40000000000000000
+ENTRY_END
+
+STEP 15200 QUERY
+ENTRY_BEGIN
+RAW
+b72ec252501143122a630000000000000000
+ENTRY_END
+
+STEP 15210 QUERY
+ENTRY_BEGIN
+RAW
+b72ec253501043122a620000000000000000
+ENTRY_END
+
+STEP 15220 QUERY
+ENTRY_BEGIN
+RAW
+b72f4ee65018fd5c51cb0000008f7426000000010001000000000e3931303533333036363737302d320000f900010e3931303533333036363737302d320000f900ff00000000005503677373096d6963726f736f667403636f6d00403af354403c44d40003000000324e544c4d535350000100000097b208e00a000a0028000000080008002000000050434f4f535431364f4f535445494e4445520000
+ENTRY_END
+
+STEP 15230 QUERY
+ENTRY_BEGIN
+RAW
+b72f4ef45011fd4e5f120000000000000000
+ENTRY_END
+
+STEP 15240 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000192e00000204057a01010402
+ENTRY_END
+
+STEP 15250 QUERY
+ENTRY_BEGIN
+RAW
+b72f4ef55010fd4e5f110000000000000000
+ENTRY_END
+
+STEP 15260 QUERY
+ENTRY_BEGIN
+RAW
+b7315009501041b83cb50000000000000000
+ENTRY_END
+
+STEP 15270 QUERY
+ENTRY_BEGIN
+RAW
+b7315009501841b8edef000000947700000000010001000000000f313034373937323032303234322d330000f900010f313034373937323032303234322d330000f900ff00000000005803677373096d6963726f736f667403636f6d00403afe38403c4fb80003000000354e544c4d535350000100000097b200e0090009002c0000000c000c0020000000535445524e2d534552564552534552564552424f4c0000
+ENTRY_END
+
+STEP 15280 QUERY
+ENTRY_BEGIN
+RAW
+b7315017501141aa3c1e0000000000000000
+ENTRY_END
+
+STEP 15290 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000f64500000204057a01010402
+ENTRY_END
+
+STEP 15300 QUERY
+ENTRY_BEGIN
+RAW
+b7315018501041aa3c1d0000000000000000
+ENTRY_END
+
+STEP 15310 QUERY
+ENTRY_BEGIN
+RAW
+b731dfc4501041b88a110000000000000000
+ENTRY_END
+
+STEP 15320 QUERY
+ENTRY_BEGIN
+RAW
+b731dfc4501841b8ce8c00000094e4c0000000010001000000000f313034373937323032303234322d320000f900010f313034373937323032303234322d320000f900ff00000000005803677373096d6963726f736f667403636f6d00403afe38403c4fb80003000000354e544c4d535350000100000097b200e0090009002c0000000c000c0020000000535445524e2d534552564552534552564552424f4c0000
+ENTRY_END
+
+STEP 15330 QUERY
+ENTRY_BEGIN
+RAW
+b731dfd2501141aa897a0000000000000000
+ENTRY_END
+
+STEP 15340 QUERY
+ENTRY_BEGIN
+RAW
+00000000700240000d5b00000204057a01010402
+ENTRY_END
+
+STEP 15350 QUERY
+ENTRY_BEGIN
+RAW
+b731dfd3501041aa89790000000000000000
+ENTRY_END
+
+STEP 15360 QUERY
+ENTRY_BEGIN
+RAW
+b732a88d501041b8d85c0000000000000000
+ENTRY_END
+
+STEP 15370 QUERY
+ENTRY_BEGIN
+RAW
+b732a88d501841b854d800000094acc0000000010001000000000f313034373937323032303234322d320000f900010f313034373937323032303234322d320000f900ff00000000005803677373096d6963726f736f667403636f6d00403afe38403c4fb80003000000354e544c4d535350000100000097b200e0090009002c0000000c000c0020000000535445524e2d534552564552534552564552424f4c0000
+ENTRY_END
+
+STEP 15380 QUERY
+ENTRY_BEGIN
+RAW
+b732a89b501141aad7c50000000000000000
+ENTRY_END
+
+STEP 15390 QUERY
+ENTRY_BEGIN
+RAW
+b732a89c501041aad7c40000000000000000
+ENTRY_END
+
+STEP 15400 QUERY
+ENTRY_BEGIN
+RAW
+316f000000010000000000000a6970336538336237333105737065656406706c616e6574026e6c00000f000100
+ENTRY_END
+
+STEP 15410 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400089e200000204055001010402
+ENTRY_END
+
+STEP 15420 QUERY
+ENTRY_BEGIN
+RAW
+b7367d1a501045107cd10000000000000000
+ENTRY_END
+
+STEP 15430 QUERY
+ENTRY_BEGIN
+RAW
+b7367d1a5018451088c700000096ae00000000010001000000000f313231393737303731323038322d330000f900010f313231393737303731323038322d330000f900ff00000000005a03677373096d6963726f736f667403636f6d00403afd56403c4ed60003000000374e544c4d535350000100000097b200e00b000b002c0000000c000c002000000045584143542d534552564552515549434b4f46464943450000
+ENTRY_END
+
+STEP 15440 QUERY
+ENTRY_BEGIN
+RAW
+b7367d28501145027c380000000000000000
+ENTRY_END
+
+STEP 15450 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000c2d500000204055001010402
+ENTRY_END
+
+STEP 15460 QUERY
+ENTRY_BEGIN
+RAW
+b7367d29501045027c370000000000000000
+ENTRY_END
+
+STEP 15470 QUERY
+ENTRY_BEGIN
+RAW
+b738f642501045103c9a0000000000000000
+ENTRY_END
+
+STEP 15480 QUERY
+ENTRY_BEGIN
+RAW
+b738f64250184510f291000000960500000000010001000000000f313231393737303731323038322d320000f900010f313231393737303731323038322d320000f900ff00000000005a03677373096d6963726f736f667403636f6d00403afd56403c4ed60003000000374e544c4d535350000100000097b200e00b000b002c0000000c000c002000000045584143542d534552564552515549434b4f46464943450000
+ENTRY_END
+
+STEP 15490 QUERY
+ENTRY_BEGIN
+RAW
+b738f650501145023c010000000000000000
+ENTRY_END
+
+STEP 15500 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000b71600000204055001010402
+ENTRY_END
+
+STEP 15510 QUERY
+ENTRY_BEGIN
+RAW
+b738f651501045023c000000000000000000
+ENTRY_END
+
+STEP 15520 QUERY
+ENTRY_BEGIN
+RAW
+b7398bf1501045109b2b0000000000000000
+ENTRY_END
+
+STEP 15530 QUERY
+ENTRY_BEGIN
+RAW
+b7398bf1501845103123000000962500000000010001000000000f313231393737303731323038322d320000f900010f313231393737303731323038322d320000f900ff00000000005a03677373096d6963726f736f667403636f6d00403afd56403c4ed60003000000374e544c4d535350000100000097b200e00b000b002c0000000c000c002000000045584143542d534552564552515549434b4f46464943450000
+ENTRY_END
+
+STEP 15540 QUERY
+ENTRY_BEGIN
+RAW
+b7398bff501145029a920000000000000000
+ENTRY_END
+
+STEP 15550 QUERY
+ENTRY_BEGIN
+RAW
+b7398c00501045029a910000000000000000
+ENTRY_END
+
+STEP 15560 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000c30100000204056401010402
+ENTRY_END
+
+STEP 15570 QUERY
+ENTRY_BEGIN
+RAW
+b73c34e1501040b002980000000000000000
+ENTRY_END
+
+STEP 15580 QUERY
+ENTRY_BEGIN
+RAW
+b73c34e1501840b0dbc60000008c2e7d000000010001000000000f313133333837313336363136322d330000f900010f313133333837313336363136322d330000f900ff00000000005003677373096d6963726f736f667403636f6d00403afae7403c4c6700030000002d4e544c4d535350000100000097b200c007000700260000000600060020000000534552564552525542594445430000
+ENTRY_END
+
+STEP 15590 QUERY
+ENTRY_BEGIN
+RAW
+b73c34ef501140a202090000000000000000
+ENTRY_END
+
+STEP 15600 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000e88100000204056401010402
+ENTRY_END
+
+STEP 15610 QUERY
+ENTRY_BEGIN
+RAW
+b73c34f0501040a202080000000000000000
+ENTRY_END
+
+STEP 15620 QUERY
+ENTRY_BEGIN
+RAW
+b73d0406501040b058f20000000000000000
+ENTRY_END
+
+STEP 15630 QUERY
+ENTRY_BEGIN
+RAW
+b73d0406501840b0ded30000008c82cb000000010001000000000f313133333837313336363136322d320000f900010f313133333837313336363136322d320000f900ff00000000005003677373096d6963726f736f667403636f6d00403afae7403c4c6700030000002d4e544c4d535350000100000097b200c007000700260000000600060020000000534552564552525542594445430000
+ENTRY_END
+
+STEP 15640 QUERY
+ENTRY_BEGIN
+RAW
+b73d0414501140a258630000000000000000
+ENTRY_END
+
+STEP 15650 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000ab0400000204056401010402
+ENTRY_END
+
+STEP 15660 QUERY
+ENTRY_BEGIN
+RAW
+b73d0415501040a258620000000000000000
+ENTRY_END
+
+STEP 15670 QUERY
+ENTRY_BEGIN
+RAW
+b73dab04501040b074760000000000000000
+ENTRY_END
+
+STEP 15680 QUERY
+ENTRY_BEGIN
+RAW
+b73dab04501840b0a6090000008cd719000000010001000000000f313133333837313336363136322d320000f900010f313133333837313336363136322d320000f900ff00000000005003677373096d6963726f736f667403636f6d00403afae7403c4c6700030000002d4e544c4d535350000100000097b200c007000700260000000600060020000000534552564552525542594445430000
+ENTRY_END
+
+STEP 15690 QUERY
+ENTRY_BEGIN
+RAW
+b73dab12501140a273e70000000000000000
+ENTRY_END
+
+STEP 15700 QUERY
+ENTRY_BEGIN
+RAW
+b73dab13501040a273e60000000000000000
+ENTRY_END
+
+STEP 15710 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000badf0000020405b401010402
+ENTRY_END
+
+STEP 15720 QUERY
+ENTRY_BEGIN
+RAW
+00000000700240008d210000020405b401010402
+ENTRY_END
+
+STEP 15730 QUERY
+ENTRY_BEGIN
+RAW
+b744e8ca5010447015560000000000000000
+ENTRY_END
+
+STEP 15740 QUERY
+ENTRY_BEGIN
+RAW
+b744e8ca50184470b35000000091ec00000000010001000000000f313135313035313233353334362d330000f900010f313135313035313233353334362d330000f900ff00000000005503677373096d6963726f736f667403636f6d00403afd2a403c4eaa0003000000324e544c4d535350000100000097b208e00c000c0026000000060006002000000045434f4e454c4b554e5354454e5a414b454e0000
+ENTRY_END
+
+STEP 15750 QUERY
+ENTRY_BEGIN
+RAW
+b744e8d85011446214c20000000000000000
+ENTRY_END
+
+STEP 15760 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf0d1eb0000020405b401010402
+ENTRY_END
+
+STEP 15770 QUERY
+ENTRY_BEGIN
+RAW
+b74563a75010faf0e3b20000000000000000
+ENTRY_END
+
+STEP 15780 QUERY
+ENTRY_BEGIN
+RAW
+b74563a75018faf096e00000008e0000000000010001000000000f313034373937323032303234322d330000f900010f313034373937323032303234322d330000f900ff00000000005203677373096d6963726f736f667403636f6d00403afcdf403c4e5f00030000002f4e544c4d535350000100000097b208e0090009002600000006000600200000005345525645524f534f5345525645520000
+ENTRY_END
+
+STEP 15790 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400008010000020405b401010402
+ENTRY_END
+
+STEP 15800 QUERY
+ENTRY_BEGIN
+RAW
+b74563b55011fae2e3210000000000000000
+ENTRY_END
+
+STEP 15810 QUERY
+ENTRY_BEGIN
+RAW
+b74563b65010fae2e3200000000000000000
+ENTRY_END
+
+STEP 15820 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf002cf0000020405b401010402
+ENTRY_END
+
+STEP 15830 QUERY
+ENTRY_BEGIN
+RAW
+b744e8d95010446214c10000000000000000
+ENTRY_END
+
+STEP 15840 QUERY
+ENTRY_BEGIN
+RAW
+b74725ec5010faf0524f0000000000000000
+ENTRY_END
+
+STEP 15850 QUERY
+ENTRY_BEGIN
+RAW
+b74725ec5018faf08e160000008e7867000000010001000000000f313034373937323032303234322d320000f900010f313034373937323032303234322d320000f900ff00000000005203677373096d6963726f736f667403636f6d00403afcdf403c4e5f00030000002f4e544c4d535350000100000097b208e0090009002600000006000600200000005345525645524f534f5345525645520000
+ENTRY_END
+
+STEP 15860 QUERY
+ENTRY_BEGIN
+RAW
+b746472d5010447031d10000000000000000
+ENTRY_END
+
+STEP 15870 QUERY
+ENTRY_BEGIN
+RAW
+b74725fa5011fae251be0000000000000000
+ENTRY_END
+
+STEP 15880 QUERY
+ENTRY_BEGIN
+RAW
+b746472d50184470ec4c00000091ce80000000010001000000000f313135313035313233353334362d320000f900010f313135313035313233353334362d320000f900ff00000000005503677373096d6963726f736f667403636f6d00403afd2b403c4eab0003000000324e544c4d535350000100000097b208e00c000c0026000000060006002000000045434f4e454c4b554e5354454e5a414b454e0000
+ENTRY_END
+
+STEP 15890 QUERY
+ENTRY_BEGIN
+RAW
+b74725fb5010fae251bd0000000000000000
+ENTRY_END
+
+STEP 15900 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf0e9570000020405b401010402
+ENTRY_END
+
+STEP 15910 QUERY
+ENTRY_BEGIN
+RAW
+b748136e5010faf04b550000000000000000
+ENTRY_END
+
+STEP 15920 QUERY
+ENTRY_BEGIN
+RAW
+b748136e5018faf0e48c0000008e1af7000000010001000000000f313034373937323032303234322d320000f900010f313034373937323032303234322d320000f900ff00000000005203677373096d6963726f736f667403636f6d00403afcdf403c4e5f00030000002f4e544c4d535350000100000097b208e0090009002600000006000600200000005345525645524f534f5345525645520000
+ENTRY_END
+
+STEP 15930 QUERY
+ENTRY_BEGIN
+RAW
+b748137c5011fae24ac40000000000000000
+ENTRY_END
+
+STEP 15940 QUERY
+ENTRY_BEGIN
+RAW
+b746473b50114462313d0000000000000000
+ENTRY_END
+
+STEP 15950 QUERY
+ENTRY_BEGIN
+RAW
+b748137d5010fae24ac30000000000000000
+ENTRY_END
+
+STEP 15960 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000f14c0000020405b401010402
+ENTRY_END
+
+STEP 15970 QUERY
+ENTRY_BEGIN
+RAW
+b746473c50104462313c0000000000000000
+ENTRY_END
+
+STEP 15980 QUERY
+ENTRY_BEGIN
+RAW
+b748a93150104470b9160000000000000000
+ENTRY_END
+
+STEP 15990 QUERY
+ENTRY_BEGIN
+RAW
+b748a93150184470dd12000000916500000000010001000000000f313135313035313233353334362d320000f900010f313135313035313233353334362d320000f900ff00000000005503677373096d6963726f736f667403636f6d00403afd2b403c4eab0003000000324e544c4d535350000100000097b208e00c000c0026000000060006002000000045434f4e454c4b554e5354454e5a414b454e0000
+ENTRY_END
+
+STEP 16000 QUERY
+ENTRY_BEGIN
+RAW
+b748a93f50114462b8820000000000000000
+ENTRY_END
+
+STEP 16010 QUERY
+ENTRY_BEGIN
+RAW
+b742be80501044706d600000000000000000
+ENTRY_END
+
+STEP 16020 QUERY
+ENTRY_BEGIN
+RAW
+b742be80501844708594000000962eb5000000010001000000000f313038323333313735383631302d330000f900010f313038323333313735383631302d330000f900ff00000000005a03677373096d6963726f736f667403636f6d00403afe17403c4f970003000000374e544c4d535350000100000097b208e00e000e002900000009000900200000004f4e5a45564144455252495050455244415041524b32390000
+ENTRY_END
+
+STEP 16030 QUERY
+ENTRY_BEGIN
+RAW
+b748a94050104462b8810000000000000000
+ENTRY_END
+
+STEP 16040 QUERY
+ENTRY_BEGIN
+RAW
+00000000700240008d4000000204058c01010402
+ENTRY_END
+
+STEP 16050 QUERY
+ENTRY_BEGIN
+RAW
+b749679e5010429098540000000000000000
+ENTRY_END
+
+STEP 16060 QUERY
+ENTRY_BEGIN
+RAW
+b749679e50184290705700000091e4db000000010001000000000e3931303533333036363737302d330000f900010e3931303533333036363737302d330000f900ff00000000005703677373096d6963726f736f667403636f6d00403afd9c403c4f1c0003000000344e544c4d535350000100000097b200c00d000d002700000007000700200000005641524b4a4553444953545249564552533033410000
+ENTRY_END
+
+STEP 16070 QUERY
+ENTRY_BEGIN
+RAW
+b74967ac5011428297c00000000000000000
+ENTRY_END
+
+STEP 16080 QUERY
+ENTRY_BEGIN
+RAW
+b74967ad5010428297bf0000000000000000
+ENTRY_END
+
+STEP 16090 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000f46000000204058c01010402
+ENTRY_END
+
+STEP 16100 QUERY
+ENTRY_BEGIN
+RAW
+b74a49ae501042901d640000000000000000
+ENTRY_END
+
+STEP 16110 QUERY
+ENTRY_BEGIN
+RAW
+b74a49ae5018429054610000009187e1000000010001000000000e3931303533333036363737302d320000f900010e3931303533333036363737302d320000f900ff00000000005703677373096d6963726f736f667403636f6d00403afd9c403c4f1c0003000000344e544c4d535350000100000097b200c00d000d002700000007000700200000005641524b4a4553444953545249564552533033410000
+ENTRY_END
+
+STEP 16120 QUERY
+ENTRY_BEGIN
+RAW
+b74a49bc501142821cd00000000000000000
+ENTRY_END
+
+STEP 16130 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000fa2700000204058c01010402
+ENTRY_END
+
+STEP 16140 QUERY
+ENTRY_BEGIN
+RAW
+b74a49bd501042821ccf0000000000000000
+ENTRY_END
+
+STEP 16150 QUERY
+ENTRY_BEGIN
+RAW
+b74ac63f50104290a6990000000000000000
+ENTRY_END
+
+STEP 16160 QUERY
+ENTRY_BEGIN
+RAW
+b74ac63f50184290a35700000091c220000000010001000000000e3931303533333036363737302d320000f900010e3931303533333036363737302d320000f900ff00000000005703677373096d6963726f736f667403636f6d00403afd9c403c4f1c0003000000344e544c4d535350000100000097b200c00d000d002700000007000700200000005641524b4a4553444953545249564552533033410000
+ENTRY_END
+
+STEP 16170 QUERY
+ENTRY_BEGIN
+RAW
+b74ac64d50114282a6050000000000000000
+ENTRY_END
+
+STEP 16180 QUERY
+ENTRY_BEGIN
+RAW
+b74ac64e50104282a6040000000000000000
+ENTRY_END
+
+STEP 16190 QUERY
+ENTRY_BEGIN
+RAW
+b742be8e501144626cc70000000000000000
+ENTRY_END
+
+STEP 16200 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400079c20000020405b401010402
+ENTRY_END
+
+STEP 16210 QUERY
+ENTRY_BEGIN
+RAW
+b742be8f501044626cc60000000000000000
+ENTRY_END
+
+STEP 16220 QUERY
+ENTRY_BEGIN
+RAW
+b74cd39f50104470171a0000000000000000
+ENTRY_END
+
+STEP 16230 QUERY
+ENTRY_BEGIN
+RAW
+b74cd39f501844705a7f000000960285000000010001000000000f313038323333313735383631302d320000f900010f313038323333313735383631302d320000f900ff00000000005a03677373096d6963726f736f667403636f6d00403afe18403c4f980003000000374e544c4d535350000100000097b208e00e000e002900000009000900200000004f4e5a45564144455252495050455244415041524b32390000
+ENTRY_END
+
+STEP 16240 QUERY
+ENTRY_BEGIN
+RAW
+00000000700240009a450000020405b401010402
+ENTRY_END
+
+STEP 16250 QUERY
+ENTRY_BEGIN
+RAW
+b74eb5d65010447055640000000000000000
+ENTRY_END
+
+STEP 16260 QUERY
+ENTRY_BEGIN
+RAW
+b74eb5d650184470e49e000000958e00000000010001000000000f343236303630373535373635302d330000f900010f343236303630373535373635302d330000f900ff00000000005903677373096d6963726f736f667403636f6d00403afd07403c4e870003000000364e544c4d535350000100000097b200e00e000e002800000008000800200000004e54534552564552574547484f5253542d4f4c494b4f0000
+ENTRY_END
+
+STEP 16270 QUERY
+ENTRY_BEGIN
+RAW
+b74eb5e45011446254cc0000000000000000
+ENTRY_END
+
+STEP 16280 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400048fc0000020405b401010402
+ENTRY_END
+
+STEP 16290 QUERY
+ENTRY_BEGIN
+RAW
+b74eb5e55010446254cb0000000000000000
+ENTRY_END
+
+STEP 16300 QUERY
+ENTRY_BEGIN
+RAW
+b7513e29501044707bc50000000000000000
+ENTRY_END
+
+STEP 16310 QUERY
+ENTRY_BEGIN
+RAW
+b7513e29501844706001000000953a00000000010001000000000f343236303630373535373635302d320000f900010f343236303630373535373635302d320000f900ff00000000005903677373096d6963726f736f667403636f6d00403afd07403c4e870003000000364e544c4d535350000100000097b200e00e000e002800000008000800200000004e54534552564552574547484f5253542d4f4c494b4f0000
+ENTRY_END
+
+STEP 16320 QUERY
+ENTRY_BEGIN
+RAW
+b74cd3ad5011446216810000000000000000
+ENTRY_END
+
+STEP 16330 QUERY
+ENTRY_BEGIN
+RAW
+00000000700240002efe0000020405b401010402
+ENTRY_END
+
+STEP 16340 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000278d0000020405b401010402
+ENTRY_END
+
+STEP 16350 QUERY
+ENTRY_BEGIN
+RAW
+b7513e37501144627b2d0000000000000000
+ENTRY_END
+
+STEP 16360 QUERY
+ENTRY_BEGIN
+RAW
+b75201fb501044709df40000000000000000
+ENTRY_END
+
+STEP 16370 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000b08d0000020405b401010402
+ENTRY_END
+
+STEP 16380 QUERY
+ENTRY_BEGIN
+RAW
+b75201fb50184470261b000000966bb0000000010001000000000f313233363935303538313236362d330000f900010f313233363935303538313236362d330000f900ff00000000005a03677373096d6963726f736f667403636f6d00403afd07403c4e870003000000374e544c4d535350000100000097b208e00a000a002d0000000d000d0020000000504443544f5047524f57455253544f5047524f574552530000
+ENTRY_END
+
+STEP 16390 QUERY
+ENTRY_BEGIN
+RAW
+b7513e38501044627b2c0000000000000000
+ENTRY_END
+
+STEP 16400 QUERY
+ENTRY_BEGIN
+RAW
+b75342ad50104470ded00000000000000000
+ENTRY_END
+
+STEP 16410 QUERY
+ENTRY_BEGIN
+RAW
+b7520209501144629d5b0000000000000000
+ENTRY_END
+
+STEP 16420 QUERY
+ENTRY_BEGIN
+RAW
+b75342ad501844700d0c00000095f000000000010001000000000f343236303630373535373635302d320000f900010f343236303630373535373635302d320000f900ff00000000005903677373096d6963726f736f667403636f6d00403afd07403c4e870003000000364e544c4d535350000100000097b200e00e000e002800000008000800200000004e54534552564552574547484f5253542d4f4c494b4f0000
+ENTRY_END
+
+STEP 16430 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400087df0000020405b401010402
+ENTRY_END
+
+STEP 16440 QUERY
+ENTRY_BEGIN
+RAW
+b752020a501044629d5a0000000000000000
+ENTRY_END
+
+STEP 16450 QUERY
+ENTRY_BEGIN
+RAW
+b75342bb50114462de380000000000000000
+ENTRY_END
+
+STEP 16460 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000d3c000000204056401010402
+ENTRY_END
+
+STEP 16470 QUERY
+ENTRY_BEGIN
+RAW
+b754104050104470e88e0000000000000000
+ENTRY_END
+
+STEP 16480 QUERY
+ENTRY_BEGIN
+RAW
+b754104050184470e8b900000096f4ac000000010001000000000f313233363935303538313236362d320000f900010f313233363935303538313236362d320000f900ff00000000005a03677373096d6963726f736f667403636f6d00403afd07403c4e870003000000374e544c4d535350000100000097b208e00a000a002d0000000d000d0020000000504443544f5047524f57455253544f5047524f574552530000
+ENTRY_END
+
+STEP 16490 QUERY
+ENTRY_BEGIN
+RAW
+b75342bc50104462de370000000000000000
+ENTRY_END
+
+STEP 16500 QUERY
+ENTRY_BEGIN
+RAW
+b7549d5b501040b0aac40000000000000000
+ENTRY_END
+
+STEP 16510 QUERY
+ENTRY_BEGIN
+RAW
+b754104e50114462e7f50000000000000000
+ENTRY_END
+
+STEP 16520 QUERY
+ENTRY_BEGIN
+RAW
+b7549d5b501840b095820000008c16ee000000010001000000000f313133333837313336363136322d330000f900010f313133333837313336363136322d330000f900ff00000000005003677373096d6963726f736f667403636f6d00403afaea403c4c6a00030000002d4e544c4d535350000100000097b200c007000700260000000600060020000000534552564552525542594445430000
+ENTRY_END
+
+STEP 16530 QUERY
+ENTRY_BEGIN
+RAW
+00000000700240005e4c0000020405b401010402
+ENTRY_END
+
+STEP 16540 QUERY
+ENTRY_BEGIN
+RAW
+b7549d69501140a2aa350000000000000000
+ENTRY_END
+
+STEP 16550 QUERY
+ENTRY_BEGIN
+RAW
+b754104f50104462e7f40000000000000000
+ENTRY_END
+
+STEP 16560 QUERY
+ENTRY_BEGIN
+RAW
+b755265350104470a8e70000000000000000
+ENTRY_END
+
+STEP 16570 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400038b600000204056401010402
+ENTRY_END
+
+STEP 16580 QUERY
+ENTRY_BEGIN
+RAW
+b7552653501844702017000000967da8000000010001000000000f313233363935303538313236362d320000f900010f313233363935303538313236362d320000f900ff00000000005a03677373096d6963726f736f667403636f6d00403afd07403c4e870003000000374e544c4d535350000100000097b208e00a000a002d0000000d000d0020000000504443544f5047524f57455253544f5047524f574552530000
+ENTRY_END
+
+STEP 16590 QUERY
+ENTRY_BEGIN
+RAW
+b7549d6a501040a2aa340000000000000000
+ENTRY_END
+
+STEP 16600 QUERY
+ENTRY_BEGIN
+RAW
+b75604ad501040b0a8660000000000000000
+ENTRY_END
+
+STEP 16610 QUERY
+ENTRY_BEGIN
+RAW
+b75604ad501840b03fd70000008c6b3c000000010001000000000f313133333837313336363136322d320000f900010f313133333837313336363136322d320000f900ff00000000005003677373096d6963726f736f667403636f6d00403afaea403c4c6a00030000002d4e544c4d535350000100000097b200c007000700260000000600060020000000534552564552525542594445430000
+ENTRY_END
+
+STEP 16620 QUERY
+ENTRY_BEGIN
+RAW
+b755266150114462a84e0000000000000000
+ENTRY_END
+
+STEP 16630 QUERY
+ENTRY_BEGIN
+RAW
+b755266250104462a84d0000000000000000
+ENTRY_END
+
+STEP 16640 QUERY
+ENTRY_BEGIN
+RAW
+b75604bb501140a2a7d70000000000000000
+ENTRY_END
+
+STEP 16650 QUERY
+ENTRY_BEGIN
+RAW
+00000000700240003d8b00000204056401010402
+ENTRY_END
+
+STEP 16660 QUERY
+ENTRY_BEGIN
+RAW
+b75604bc501040a2a7d60000000000000000
+ENTRY_END
+
+STEP 16670 QUERY
+ENTRY_BEGIN
+RAW
+b756ec01501040b0c5e60000000000000000
+ENTRY_END
+
+STEP 16680 QUERY
+ENTRY_BEGIN
+RAW
+b756ec01501840b069190000008c5f7a000000010001000000000f313133333837313336363136322d320000f900010f313133333837313336363136322d320000f900ff00000000005003677373096d6963726f736f667403636f6d00403afaea403c4c6a00030000002d4e544c4d535350000100000097b200c007000700260000000600060020000000534552564552525542594445430000
+ENTRY_END
+
+STEP 16690 QUERY
+ENTRY_BEGIN
+RAW
+b756ec0f501140a2c5570000000000000000
+ENTRY_END
+
+STEP 16700 QUERY
+ENTRY_BEGIN
+RAW
+b756ec10501040a2c5560000000000000000
+ENTRY_END
+
+STEP 16710 QUERY
+ENTRY_BEGIN
+RAW
+00000000700240005c4d00000204059801010402
+ENTRY_END
+
+STEP 16720 QUERY
+ENTRY_BEGIN
+RAW
+b757c385501043200ae80000000000000000
+ENTRY_END
+
+STEP 16730 QUERY
+ENTRY_BEGIN
+RAW
+b757c3855018432080320000008b0bc0000000010001000000000f313135313035313233353334362d330000f900010f313135313035313233353334362d330000f900ff00000000004f03677373096d6963726f736f667403636f6d00403afb43403c4cc300030000002c4e544c4d535350000100000097b200e0060006002600000006000600200000004d415243454c4845444546410000
+ENTRY_END
+
+STEP 16740 QUERY
+ENTRY_BEGIN
+RAW
+b757c393501143120a5a0000000000000000
+ENTRY_END
+
+STEP 16750 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000908b00000204059801010402
+ENTRY_END
+
+STEP 16760 QUERY
+ENTRY_BEGIN
+RAW
+b757c394501043120a590000000000000000
+ENTRY_END
+
+STEP 16770 QUERY
+ENTRY_BEGIN
+RAW
+b75a5de550104320a4c30000000000000000
+ENTRY_END
+
+STEP 16780 QUERY
+ENTRY_BEGIN
+RAW
+b75a5de550184320cace0000008b5c00000000010001000000000f313135313035313233353334362d320000f900010f313135313035313233353334362d320000f900ff00000000004f03677373096d6963726f736f667403636f6d00403afb43403c4cc300030000002c4e544c4d535350000100000097b200e0060006002600000006000600200000004d415243454c4845444546410000
+ENTRY_END
+
+STEP 16790 QUERY
+ENTRY_BEGIN
+RAW
+b74cd3ae5010446216800000000000000000
+ENTRY_END
+
+STEP 16800 QUERY
+ENTRY_BEGIN
+RAW
+b7529bd750104470fca60000000000000000
+ENTRY_END
+
+STEP 16810 QUERY
+ENTRY_BEGIN
+RAW
+b7529bd750184470c07c000000968014000000010001000000000f313038323333313735383631302d320000f900010f313038323333313735383631302d320000f900ff00000000005a03677373096d6963726f736f667403636f6d00403afe19403c4f990003000000374e544c4d535350000100000097b208e00e000e002900000009000900200000004f4e5a45564144455252495050455244415041524b32390000
+ENTRY_END
+
+STEP 16820 QUERY
+ENTRY_BEGIN
+RAW
+b75a5df350114312a4350000000000000000
+ENTRY_END
+
+STEP 16830 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000539000000204059801010402
+ENTRY_END
+
+STEP 16840 QUERY
+ENTRY_BEGIN
+RAW
+b75a5df450104312a4340000000000000000
+ENTRY_END
+
+STEP 16850 QUERY
+ENTRY_BEGIN
+RAW
+b75b2958501043209c540000000000000000
+ENTRY_END
+
+STEP 16860 QUERY
+ENTRY_BEGIN
+RAW
+b75b29585018432011e00000008b0c80000000010001000000000f313135313035313233353334362d320000f900010f313135313035313233353334362d320000f900ff00000000004f03677373096d6963726f736f667403636f6d00403afb43403c4cc300030000002c4e544c4d535350000100000097b200e0060006002600000006000600200000004d415243454c4845444546410000
+ENTRY_END
+
+STEP 16870 QUERY
+ENTRY_BEGIN
+RAW
+b75b2966501143129bc60000000000000000
+ENTRY_END
+
+STEP 16880 QUERY
+ENTRY_BEGIN
+RAW
+b75b2967501043129bc50000000000000000
+ENTRY_END
+
+STEP 16890 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000fcd600000204059801010402
+ENTRY_END
+
+STEP 16900 QUERY
+ENTRY_BEGIN
+RAW
+b75bfc9650104320725c0000000000000000
+ENTRY_END
+
+STEP 16910 QUERY
+ENTRY_BEGIN
+RAW
+b75bfc965018432095e60000008b5d80000000010001000000000f313135313035313233353334362d330000f900010f313135313035313233353334362d330000f900ff00000000004f03677373096d6963726f736f667403636f6d00403afb43403c4cc300030000002c4e544c4d535350000100000097b200e0060006002600000006000600200000004d415243454c4845444546410000
+ENTRY_END
+
+STEP 16920 QUERY
+ENTRY_BEGIN
+RAW
+b75bfca45011431271ce0000000000000000
+ENTRY_END
+
+STEP 16930 QUERY
+ENTRY_BEGIN
+RAW
+00000000700240005ff400000204059801010402
+ENTRY_END
+
+STEP 16940 QUERY
+ENTRY_BEGIN
+RAW
+b75bfca55010431271cd0000000000000000
+ENTRY_END
+
+STEP 16950 QUERY
+ENTRY_BEGIN
+RAW
+b75c9580501043203c8f0000000000000000
+ENTRY_END
+
+STEP 16960 QUERY
+ENTRY_BEGIN
+RAW
+b75c958050184320b09a0000008b0e00000000010001000000000f313135313035313233353334362d320000f900010f313135313035313233353334362d320000f900ff00000000004f03677373096d6963726f736f667403636f6d00403afb43403c4cc300030000002c4e544c4d535350000100000097b200e0060006002600000006000600200000004d415243454c4845444546410000
+ENTRY_END
+
+STEP 16970 QUERY
+ENTRY_BEGIN
+RAW
+b75c958e501143123c010000000000000000
+ENTRY_END
+
+STEP 16980 QUERY
+ENTRY_BEGIN
+RAW
+00000000700240007c5400000204059801010402
+ENTRY_END
+
+STEP 16990 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000c5670000020405b401010402
+ENTRY_END
+
+STEP 17000 QUERY
+ENTRY_BEGIN
+RAW
+b75e3db250104470f89a0000000000000000
+ENTRY_END
+
+STEP 17010 QUERY
+ENTRY_BEGIN
+RAW
+b75e3db2501844700e7f0000008c90b3000000010001000000000f313039393531313632373739342d330000f900010f313039393531313632373739342d330000f900ff00000000005003677373096d6963726f736f667403636f6d00403afc24403c4da400030000002d4e544c4d535350000100000097b200c0070007002600000006000600200000005345525645524d4b424144414d0000
+ENTRY_END
+
+STEP 17020 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400070f40000020405b401010402
+ENTRY_END
+
+STEP 17030 QUERY
+ENTRY_BEGIN
+RAW
+b75c958f501043123c000000000000000000
+ENTRY_END
+
+STEP 17040 QUERY
+ENTRY_BEGIN
+RAW
+b75d4d2450104320a14a0000000000000000
+ENTRY_END
+
+STEP 17050 QUERY
+ENTRY_BEGIN
+RAW
+b75e3dc050114462f80b0000000000000000
+ENTRY_END
+
+STEP 17060 QUERY
+ENTRY_BEGIN
+RAW
+b75d4d2450184320c9150000008b5840000000010001000000000f313135313035313233353334362d320000f900010f313135313035313233353334362d320000f900ff00000000004f03677373096d6963726f736f667403636f6d00403afb44403c4cc400030000002c4e544c4d535350000100000097b200e0060006002600000006000600200000004d415243454c4845444546410000
+ENTRY_END
+
+STEP 17070 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000e0850000020405b401010402
+ENTRY_END
+
+STEP 17080 QUERY
+ENTRY_BEGIN
+RAW
+b75e3dc150104462f80a0000000000000000
+ENTRY_END
+
+STEP 17090 QUERY
+ENTRY_BEGIN
+RAW
+b75f940b50104470bd5e0000000000000000
+ENTRY_END
+
+STEP 17100 QUERY
+ENTRY_BEGIN
+RAW
+b75ecb745010447016650000000000000000
+ENTRY_END
+
+STEP 17110 QUERY
+ENTRY_BEGIN
+RAW
+b75f940b501844701be40000008c4913000000010001000000000f313039393531313632373739342d320000f900010f313039393531313632373739342d320000f900ff00000000005003677373096d6963726f736f667403636f6d00403afc24403c4da400030000002d4e544c4d535350000100000097b200c0070007002600000006000600200000005345525645524d4b424144414d0000
+ENTRY_END
+
+STEP 17120 QUERY
+ENTRY_BEGIN
+RAW
+b75d4d3250114312a0bc0000000000000000
+ENTRY_END
+
+STEP 17130 QUERY
+ENTRY_BEGIN
+RAW
+b75f941950114462bccf0000000000000000
+ENTRY_END
+
+STEP 17140 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400051fa0000020405b401010402
+ENTRY_END
+
+STEP 17150 QUERY
+ENTRY_BEGIN
+RAW
+b75f941a50104462bcce0000000000000000
+ENTRY_END
+
+STEP 17160 QUERY
+ENTRY_BEGIN
+RAW
+b7604675501044707c680000000000000000
+ENTRY_END
+
+STEP 17170 QUERY
+ENTRY_BEGIN
+RAW
+b75ecb7450184470e98f0000008fa200000000010001000000000f313230323539303834323839382d330000f900010f313230323539303834323839382d330000f900ff00000000005303677373096d6963726f736f667403636f6d00403afdd3403c4f530003000000304e544c4d535350000100000097b200c0060006002a0000000a000a00200000004459534f53455256455244594e534f4c0000
+ENTRY_END
+
+STEP 17180 QUERY
+ENTRY_BEGIN
+RAW
+b760467550184470bc800000008c6780000000010001000000000f313039393531313632373739342d320000f900010f313039393531313632373739342d320000f900ff00000000005003677373096d6963726f736f667403636f6d00403afc24403c4da400030000002d4e544c4d535350000100000097b200c0070007002600000006000600200000005345525645524d4b424144414d0000
+ENTRY_END
+
+STEP 17190 QUERY
+ENTRY_BEGIN
+RAW
+b75d4d3350104312a0bb0000000000000000
+ENTRY_END
+
+STEP 17200 QUERY
+ENTRY_BEGIN
+RAW
+b7604683501144627bd90000000000000000
+ENTRY_END
+
+STEP 17210 QUERY
+ENTRY_BEGIN
+RAW
+b7604684501044627bd80000000000000000
+ENTRY_END
+
+STEP 17220 QUERY
+ENTRY_BEGIN
+RAW
+b75ecb825011446215d30000000000000000
+ENTRY_END
+
+STEP 17230 QUERY
+ENTRY_BEGIN
+RAW
+00000000700240005d5e0000020405b401010402
+ENTRY_END
+
+STEP 17240 QUERY
+ENTRY_BEGIN
+RAW
+b75ecb835010446215d20000000000000000
+ENTRY_END
+
+STEP 17250 QUERY
+ENTRY_BEGIN
+RAW
+b7630c6050104470c1de0000000000000000
+ENTRY_END
+
+STEP 17260 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000829700000204059801010402
+ENTRY_END
+
+STEP 17270 QUERY
+ENTRY_BEGIN
+RAW
+b7529be550114462fc0d0000000000000000
+ENTRY_END
+
+STEP 17280 QUERY
+ENTRY_BEGIN
+RAW
+b763eae35010432009c80000000000000000
+ENTRY_END
+
+STEP 17290 QUERY
+ENTRY_BEGIN
+RAW
+b7630c60501844703d0a0000008ffb00000000010001000000000f313230323539303834323839382d320000f900010f313230323539303834323839382d320000f900ff00000000005303677373096d6963726f736f667403636f6d00403afdd3403c4f530003000000304e544c4d535350000100000097b200c0060006002a0000000a000a00200000004459534f53455256455244594e534f4c0000
+ENTRY_END
+
+STEP 17300 QUERY
+ENTRY_BEGIN
+RAW
+b763eae3501843202fd20000008b5900000000010001000000000f313135313035313233353334362d330000f900010f313135313035313233353334362d330000f900ff00000000004f03677373096d6963726f736f667403636f6d00403afb44403c4cc400030000002c4e544c4d535350000100000097b200e0060006002600000006000600200000004d415243454c4845444546410000
+ENTRY_END
+
+STEP 17310 QUERY
+ENTRY_BEGIN
+RAW
+b7630c6e50114462c14c0000000000000000
+ENTRY_END
+
+STEP 17320 QUERY
+ENTRY_BEGIN
+RAW
+b763eaf150114312093a0000000000000000
+ENTRY_END
+
+STEP 17330 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400073a600000204059801010402
+ENTRY_END
+
+STEP 17340 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400026de0000020405b401010402
+ENTRY_END
+
+STEP 17350 QUERY
+ENTRY_BEGIN
+RAW
+b7630c6f50104462c14b0000000000000000
+ENTRY_END
+
+STEP 17360 QUERY
+ENTRY_BEGIN
+RAW
+b763eaf25010431209390000000000000000
+ENTRY_END
+
+STEP 17370 QUERY
+ENTRY_BEGIN
+RAW
+b765999a50104470fe210000000000000000
+ENTRY_END
+
+STEP 17380 QUERY
+ENTRY_BEGIN
+RAW
+b764c59f50104320201a0000000000000000
+ENTRY_END
+
+STEP 17390 QUERY
+ENTRY_BEGIN
+RAW
+b764c59f501843209aa50000008b0580000000010001000000000f313135313035313233353334362d320000f900010f313135313035313233353334362d320000f900ff00000000004f03677373096d6963726f736f667403636f6d00403afb44403c4cc400030000002c4e544c4d535350000100000097b200e0060006002600000006000600200000004d415243454c4845444546410000
+ENTRY_END
+
+STEP 17400 QUERY
+ENTRY_BEGIN
+RAW
+b765999a50184470204e0000008f5400000000010001000000000f313230323539303834323839382d320000f900010f313230323539303834323839382d320000f900ff00000000005303677373096d6963726f736f667403636f6d00403afdd3403c4f530003000000304e544c4d535350000100000097b200c0060006002a0000000a000a00200000004459534f53455256455244594e534f4c0000
+ENTRY_END
+
+STEP 17410 QUERY
+ENTRY_BEGIN
+RAW
+b764c5ad501143121f8c0000000000000000
+ENTRY_END
+
+STEP 17420 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000865700000204059801010402
+ENTRY_END
+
+STEP 17430 QUERY
+ENTRY_BEGIN
+RAW
+b76599a850114462fd8f0000000000000000
+ENTRY_END
+
+STEP 17440 QUERY
+ENTRY_BEGIN
+RAW
+b764c5ae501043121f8b0000000000000000
+ENTRY_END
+
+STEP 17450 QUERY
+ENTRY_BEGIN
+RAW
+b7668f535010432069150000000000000000
+ENTRY_END
+
+STEP 17460 QUERY
+ENTRY_BEGIN
+RAW
+b7668f535018432033200000008bb600000000010001000000000f313135313035313233353334362d320000f900010f313135313035313233353334362d320000f900ff00000000004f03677373096d6963726f736f667403636f6d00403afb44403c4cc400030000002c4e544c4d535350000100000097b200e0060006002600000006000600200000004d415243454c4845444546410000
+ENTRY_END
+
+STEP 17470 QUERY
+ENTRY_BEGIN
+RAW
+b76599a950104462fd8e0000000000000000
+ENTRY_END
+
+STEP 17480 QUERY
+ENTRY_BEGIN
+RAW
+2030000000010000000000000d726f616461697274726176656c026e6c00000f000100
+ENTRY_END
+
+STEP 17490 QUERY
+ENTRY_BEGIN
+RAW
+b7668f615011431268870000000000000000
+ENTRY_END
+
+STEP 17500 QUERY
+ENTRY_BEGIN
+RAW
+b7668f625010431268860000000000000000
+ENTRY_END
+
+STEP 17510 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000677200000204059801010402
+ENTRY_END
+
+STEP 17520 QUERY
+ENTRY_BEGIN
+RAW
+b76739db501043209fa70000000000000000
+ENTRY_END
+
+STEP 17530 QUERY
+ENTRY_BEGIN
+RAW
+b76739db501843206bf10000008bb2c0000000010001000000000f313135313035313233353334362d330000f900010f313135313035313233353334362d330000f900ff00000000004f03677373096d6963726f736f667403636f6d00403afb44403c4cc400030000002c4e544c4d535350000100000097b200e0060006002600000006000600200000004d415243454c4845444546410000
+ENTRY_END
+
+STEP 17540 QUERY
+ENTRY_BEGIN
+RAW
+b76739e9501143129f190000000000000000
+ENTRY_END
+
+STEP 17550 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000556e00000204059801010402
+ENTRY_END
+
+STEP 17560 QUERY
+ENTRY_BEGIN
+RAW
+b76739ea501043129f180000000000000000
+ENTRY_END
+
+STEP 17570 QUERY
+ENTRY_BEGIN
+RAW
+b76820ed50104320a6900000000000000000
+ENTRY_END
+
+STEP 17580 QUERY
+ENTRY_BEGIN
+RAW
+b76820ed50184320239c0000008b0300000000010001000000000f313135313035313233353334362d320000f900010f313135313035313233353334362d320000f900ff00000000004f03677373096d6963726f736f667403636f6d00403afb44403c4cc400030000002c4e544c4d535350000100000097b200e0060006002600000006000600200000004d415243454c4845444546410000
+ENTRY_END
+
+STEP 17590 QUERY
+ENTRY_BEGIN
+RAW
+b76820fb50114312a6020000000000000000
+ENTRY_END
+
+STEP 17600 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400072f800000204059801010402
+ENTRY_END
+
+STEP 17610 QUERY
+ENTRY_BEGIN
+RAW
+b76820fc50104312a6010000000000000000
+ENTRY_END
+
+STEP 17620 QUERY
+ENTRY_BEGIN
+RAW
+b768f16a50104320f39c0000000000000000
+ENTRY_END
+
+STEP 17630 QUERY
+ENTRY_BEGIN
+RAW
+b768f16a50184320c0270000008bb380000000010001000000000f313135313035313233353334362d320000f900010f313135313035313233353334362d320000f900ff00000000004f03677373096d6963726f736f667403636f6d00403afb44403c4cc400030000002c4e544c4d535350000100000097b200e0060006002600000006000600200000004d415243454c4845444546410000
+ENTRY_END
+
+STEP 17640 QUERY
+ENTRY_BEGIN
+RAW
+b768f17850114312f30e0000000000000000
+ENTRY_END
+
+STEP 17650 QUERY
+ENTRY_BEGIN
+RAW
+b768f17950104312f30d0000000000000000
+ENTRY_END
+
+STEP 17660 QUERY
+ENTRY_BEGIN
+RAW
+b7529be650104462fc0c0000000000000000
+ENTRY_END
+
+STEP 17670 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000fae400000204056401010402
+ENTRY_END
+
+STEP 17680 QUERY
+ENTRY_BEGIN
+RAW
+b76b4fdb501040b01f520000000000000000
+ENTRY_END
+
+STEP 17690 QUERY
+ENTRY_BEGIN
+RAW
+b76b4fdb501840b0d54e00000095c564000000010001000000000f313135313035313233353334362d330000f900010f313135313035313233353334362d330000f900ff00000000005903677373096d6963726f736f667403636f6d00403b0282403c54020003000000364e544c4d535350000100000097b200e00c000c002a0000000a000a00200000004f4d44454e4f4f522d314f4d44454e4f4f52442d48530000
+ENTRY_END
+
+STEP 17700 QUERY
+ENTRY_BEGIN
+RAW
+b76b4fe9501140a21eba0000000000000000
+ENTRY_END
+
+STEP 17710 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400048dc00000204056401010402
+ENTRY_END
+
+STEP 17720 QUERY
+ENTRY_BEGIN
+RAW
+b76b4fea501040a21eb90000000000000000
+ENTRY_END
+
+STEP 17730 QUERY
+ENTRY_BEGIN
+RAW
+b76bccee501040b0f0350000000000000000
+ENTRY_END
+
+STEP 17740 QUERY
+ENTRY_BEGIN
+RAW
+b76bccee501840b021e3000000954ab5000000010001000000000f313135313035313233353334362d320000f900010f313135313035313233353334362d320000f900ff00000000005903677373096d6963726f736f667403636f6d00403b0282403c54020003000000364e544c4d535350000100000097b200e00c000c002a0000000a000a00200000004f4d44454e4f4f522d314f4d44454e4f4f52442d48530000
+ENTRY_END
+
+STEP 17750 QUERY
+ENTRY_BEGIN
+RAW
+b76bccfc501140a2ef9d0000000000000000
+ENTRY_END
+
+STEP 17760 QUERY
+ENTRY_BEGIN
+RAW
+00000000700240002ee600000204056401010402
+ENTRY_END
+
+STEP 17770 QUERY
+ENTRY_BEGIN
+RAW
+b76bccfd501040a2ef9c0000000000000000
+ENTRY_END
+
+STEP 17780 QUERY
+ENTRY_BEGIN
+RAW
+b76cc0f1501040b0e23b0000000000000000
+ENTRY_END
+
+STEP 17790 QUERY
+ENTRY_BEGIN
+RAW
+b76cc0f1501840b0b68700000095a816000000010001000000000f313135313035313233353334362d320000f900010f313135313035313233353334362d320000f900ff00000000005903677373096d6963726f736f667403636f6d00403b0282403c54020003000000364e544c4d535350000100000097b200e00c000c002a0000000a000a00200000004f4d44454e4f4f522d314f4d44454e4f4f52442d48530000
+ENTRY_END
+
+STEP 17800 QUERY
+ENTRY_BEGIN
+RAW
+b76cc0ff501140a2e1a30000000000000000
+ENTRY_END
+
+STEP 17810 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000e53c0000020405b401010402
+ENTRY_END
+
+STEP 17820 QUERY
+ENTRY_BEGIN
+RAW
+b76cc100501040a2e1a20000000000000000
+ENTRY_END
+
+STEP 17830 QUERY
+ENTRY_BEGIN
+RAW
+b76d3ff750104470161c0000000000000000
+ENTRY_END
+
+STEP 17840 QUERY
+ENTRY_BEGIN
+RAW
+b76d3ff7501844706a97000000912d80000000010001000000000f313135313035313233353334362d330000f900010f313135313035313233353334362d330000f900ff00000000005503677373096d6963726f736f667403636f6d00403afd2e403c4eae0003000000324e544c4d535350000100000097b208e00c000c0026000000060006002000000045434f4e454c4b554e5354454e5a414b454e0000
+ENTRY_END
+
+STEP 17850 QUERY
+ENTRY_BEGIN
+RAW
+b76d40055011446215880000000000000000
+ENTRY_END
+
+STEP 17860 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000eddd0000020405b401010402
+ENTRY_END
+
+STEP 17870 QUERY
+ENTRY_BEGIN
+RAW
+b76d40065010446215870000000000000000
+ENTRY_END
+
+STEP 17880 QUERY
+ENTRY_BEGIN
+RAW
+b76dbaf750104470a3bc0000000000000000
+ENTRY_END
+
+STEP 17890 QUERY
+ENTRY_BEGIN
+RAW
+b76dbaf750184470fab8000000912c00000000010001000000000f313135313035313233353334362d320000f900010f313135313035313233353334362d320000f900ff00000000005503677373096d6963726f736f667403636f6d00403afd2e403c4eae0003000000324e544c4d535350000100000097b208e00c000c0026000000060006002000000045434f4e454c4b554e5354454e5a414b454e0000
+ENTRY_END
+
+STEP 17900 QUERY
+ENTRY_BEGIN
+RAW
+b76dbb0550114462a3280000000000000000
+ENTRY_END
+
+STEP 17910 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000a6000000020405b401010402
+ENTRY_END
+
+STEP 17920 QUERY
+ENTRY_BEGIN
+RAW
+b76dbb0650104462a3270000000000000000
+ENTRY_END
+
+STEP 17930 QUERY
+ENTRY_BEGIN
+RAW
+b76e739b50104470a33a0000000000000000
+ENTRY_END
+
+STEP 17940 QUERY
+ENTRY_BEGIN
+RAW
+b76e739b50184470fbb6000000912a80000000010001000000000f313135313035313233353334362d320000f900010f313135313035313233353334362d320000f900ff00000000005503677373096d6963726f736f667403636f6d00403afd2e403c4eae0003000000324e544c4d535350000100000097b208e00c000c0026000000060006002000000045434f4e454c4b554e5354454e5a414b454e0000
+ENTRY_END
+
+STEP 17950 QUERY
+ENTRY_BEGIN
+RAW
+b76e73a950114462a2a60000000000000000
+ENTRY_END
+
+STEP 17960 QUERY
+ENTRY_BEGIN
+RAW
+b76e73aa50104462a2a50000000000000000
+ENTRY_END
+
+STEP 17970 QUERY
+ENTRY_BEGIN
+RAW
+01c9000000010000000000000a636974726f656e616972026e6c00000f0001c0
+ENTRY_END
+
+STEP 17980 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000ee6c0000020405b401010402
+ENTRY_END
+
+STEP 17990 QUERY
+ENTRY_BEGIN
+RAW
+b77479f150104470e54a0000000000000000
+ENTRY_END
+
+STEP 18000 QUERY
+ENTRY_BEGIN
+RAW
+b77479f150184470b9b70000008d453c000000010001000000000f313133333837313336363136322d330000f900010f313133333837313336363136322d330000f900ff00000000005103677373096d6963726f736f667403636f6d00403b01d7403c535700030000002e4e544c4d535350000100000097b200e00700070027000000070007002000000053425332303030484f4c50524f430000
+ENTRY_END
+
+STEP 18010 QUERY
+ENTRY_BEGIN
+RAW
+b77479ff50114462e4ba0000000000000000
+ENTRY_END
+
+STEP 18020 QUERY
+ENTRY_BEGIN
+RAW
+b7747a0050104462e4b90000000000000000
+ENTRY_END
+
+STEP 18030 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000727d00000204059801010402
+ENTRY_END
+
+STEP 18040 QUERY
+ENTRY_BEGIN
+RAW
+b778d534501043200f480000000000000000
+ENTRY_END
+
+STEP 18050 QUERY
+ENTRY_BEGIN
+RAW
+b778d53450184320a10d00000096811c000000010001000000000f313133333837313336363136322d330000f900010f313133333837313336363136322d330000f900ff00000000005a03677373096d6963726f736f667403636f6d00403afd47403c4ec70003000000374e544c4d535350000100000097b208e00b000b002c0000000c000c0020000000504f574552454447452d53424f5352444f4d45494e2d310000
+ENTRY_END
+
+STEP 18060 QUERY
+ENTRY_BEGIN
+RAW
+b778d542501143120eaf0000000000000000
+ENTRY_END
+
+STEP 18070 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000c9ec00000204059801010402
+ENTRY_END
+
+STEP 18080 QUERY
+ENTRY_BEGIN
+RAW
+b778d543501043120eae0000000000000000
+ENTRY_END
+
+STEP 18090 QUERY
+ENTRY_BEGIN
+RAW
+b7799c6a501043209f800000000000000000
+ENTRY_END
+
+STEP 18100 QUERY
+ENTRY_BEGIN
+RAW
+b7799c6a50184320239b000000968fc8000000010001000000000f313133333837313336363136322d320000f900010f313133333837313336363136322d320000f900ff00000000005a03677373096d6963726f736f667403636f6d00403afd47403c4ec70003000000374e544c4d535350000100000097b208e00b000b002c0000000c000c0020000000504f574552454447452d53424f5352444f4d45494e2d310000
+ENTRY_END
+
+STEP 18110 QUERY
+ENTRY_BEGIN
+RAW
+b7799c78501143129ee70000000000000000
+ENTRY_END
+
+STEP 18120 QUERY
+ENTRY_BEGIN
+RAW
+00000000700240008c0d00000204059801010402
+ENTRY_END
+
+STEP 18130 QUERY
+ENTRY_BEGIN
+RAW
+b7799c79501043129ee60000000000000000
+ENTRY_END
+
+STEP 18140 QUERY
+ENTRY_BEGIN
+RAW
+b77a3c4a50104320c1c00000000000000000
+ENTRY_END
+
+STEP 18150 QUERY
+ENTRY_BEGIN
+RAW
+b77a3c4a50184320372f000000969e74000000010001000000000f313133333837313336363136322d320000f900010f313133333837313336363136322d320000f900ff00000000005a03677373096d6963726f736f667403636f6d00403afd47403c4ec70003000000374e544c4d535350000100000097b208e00b000b002c0000000c000c0020000000504f574552454447452d53424f5352444f4d45494e2d310000
+ENTRY_END
+
+STEP 18160 QUERY
+ENTRY_BEGIN
+RAW
+b77a3c5850114312c1270000000000000000
+ENTRY_END
+
+STEP 18170 QUERY
+ENTRY_BEGIN
+RAW
+b77a3c5950104312c1260000000000000000
+ENTRY_END
+
+STEP 18180 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000baf20000020405b401010402
+ENTRY_END
+
+STEP 18190 QUERY
+ENTRY_BEGIN
+RAW
+b77c30cc50104470faed0000000000000000
+ENTRY_END
+
+STEP 18200 QUERY
+ENTRY_BEGIN
+RAW
+b77c30cc50184470e39a0000008e4390000000010001000000000f313133333837313336363136322d330000f900010f313133333837313336363136322d330000f900ff00000000005203677373096d6963726f736f667403636f6d00403afd2f403c4eaf00030000002f4e544c4d535350000100000097b208e00900090026000000060006002000000056444c4d475256444c4d455441414c0000
+ENTRY_END
+
+STEP 18210 QUERY
+ENTRY_BEGIN
+RAW
+b77c30da50114462fa5c0000000000000000
+ENTRY_END
+
+STEP 18220 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000d8d00000020405b401010402
+ENTRY_END
+
+STEP 18230 QUERY
+ENTRY_BEGIN
+RAW
+b77c30db50104462fa5b0000000000000000
+ENTRY_END
+
+STEP 18240 QUERY
+ENTRY_BEGIN
+RAW
+b77d061b50104470437c0000000000000000
+ENTRY_END
+
+STEP 18250 QUERY
+ENTRY_BEGIN
+RAW
+b77d061b501844701c460000008e5474000000010001000000000f313133333837313336363136322d320000f900010f313133333837313336363136322d320000f900ff00000000005203677373096d6963726f736f667403636f6d00403afd2f403c4eaf00030000002f4e544c4d535350000100000097b208e00900090026000000060006002000000056444c4d475256444c4d455441414c0000
+ENTRY_END
+
+STEP 18260 QUERY
+ENTRY_BEGIN
+RAW
+b77d06295011446242eb0000000000000000
+ENTRY_END
+
+STEP 18270 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400050950000020405b401010402
+ENTRY_END
+
+STEP 18280 QUERY
+ENTRY_BEGIN
+RAW
+b77d062a5010446242ea0000000000000000
+ENTRY_END
+
+STEP 18290 QUERY
+ENTRY_BEGIN
+RAW
+b77dd9ff50104470e75b0000000000000000
+ENTRY_END
+
+STEP 18300 QUERY
+ENTRY_BEGIN
+RAW
+b77dd9ff501844701b610000008ef938000000010001000000000f313133333837313336363136322d320000f900010f313133333837313336363136322d320000f900ff00000000005203677373096d6963726f736f667403636f6d00403afd2f403c4eaf00030000002f4e544c4d535350000100000097b208e00900090026000000060006002000000056444c4d475256444c4d455441414c0000
+ENTRY_END
+
+STEP 18310 QUERY
+ENTRY_BEGIN
+RAW
+b77dda0d50114462e6ca0000000000000000
+ENTRY_END
+
+STEP 18320 QUERY
+ENTRY_BEGIN
+RAW
+b77dda0e50104462e6c90000000000000000
+ENTRY_END
+
+STEP 18330 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000b66a00000204053401010402
+ENTRY_END
+
+STEP 18340 QUERY
+ENTRY_BEGIN
+RAW
+b77f5e2550104470c8890000000000000000
+ENTRY_END
+
+STEP 18350 QUERY
+ENTRY_BEGIN
+RAW
+b77f5e2550184470c1d00000009411de000000010001000000000f313133333837313336363136322d330000f900010f313133333837313336363136322d330000f900ff00000000005803677373096d6963726f736f667403636f6d00403b03d4403c55540003000000354e544c4d535350000100000097b208e00f000f0026000000060006002000000053455256455256414e44494a4b43534144564f43410000
+ENTRY_END
+
+STEP 18360 QUERY
+ENTRY_BEGIN
+RAW
+b77f5e3350114462c7f20000000000000000
+ENTRY_END
+
+STEP 18370 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000625d00000204053401010402
+ENTRY_END
+
+STEP 18380 QUERY
+ENTRY_BEGIN
+RAW
+b77f5e3450104462c7f10000000000000000
+ENTRY_END
+
+STEP 18390 QUERY
+ENTRY_BEGIN
+RAW
+b7821b2150104470b77d0000000000000000
+ENTRY_END
+
+STEP 18400 QUERY
+ENTRY_BEGIN
+RAW
+b7821b2150184470cf8800000094f41a000000010001000000000f313133333837313336363136322d320000f900010f313133333837313336363136322d320000f900ff00000000005803677373096d6963726f736f667403636f6d00403b03d4403c55540003000000354e544c4d535350000100000097b208e00f000f0026000000060006002000000053455256455256414e44494a4b43534144564f43410000
+ENTRY_END
+
+STEP 18410 QUERY
+ENTRY_BEGIN
+RAW
+b7821b2f50114462b6e60000000000000000
+ENTRY_END
+
+STEP 18420 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000723e00000204053401010402
+ENTRY_END
+
+STEP 18430 QUERY
+ENTRY_BEGIN
+RAW
+b7821b3050104462b6e50000000000000000
+ENTRY_END
+
+STEP 18440 QUERY
+ENTRY_BEGIN
+RAW
+b782ac965010447035e90000000000000000
+ENTRY_END
+
+STEP 18450 QUERY
+ENTRY_BEGIN
+RAW
+b782ac9650184470f0ae000000945160000000010001000000000f313133333837313336363136322d320000f900010f313133333837313336363136322d320000f900ff00000000005803677373096d6963726f736f667403636f6d00403b03d4403c55540003000000354e544c4d535350000100000097b208e00f000f0026000000060006002000000053455256455256414e44494a4b43534144564f43410000
+ENTRY_END
+
+STEP 18460 QUERY
+ENTRY_BEGIN
+RAW
+b782aca45011446235520000000000000000
+ENTRY_END
+
+STEP 18470 QUERY
+ENTRY_BEGIN
+RAW
+b782aca55010446235510000000000000000
+ENTRY_END
+
+STEP 18480 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400090520000020405b401010402
+ENTRY_END
+
+STEP 18490 QUERY
+ENTRY_BEGIN
+RAW
+b786466a50104470baa50000000000000000
+ENTRY_END
+
+STEP 18500 QUERY
+ENTRY_BEGIN
+RAW
+b786466a501844706f640000008d65eb000000010001000000000f313133333837313336363136322d320000f900010f313133333837313336363136322d320000f900ff00000000005103677373096d6963726f736f667403636f6d00403b01d7403c535700030000002e4e544c4d535350000100000097b200e00700070027000000070007002000000053425332303030484f4c50524f430000
+ENTRY_END
+
+STEP 18510 QUERY
+ENTRY_BEGIN
+RAW
+b786467850114462ba150000000000000000
+ENTRY_END
+
+STEP 18520 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000908a0000020405b401010402
+ENTRY_END
+
+STEP 18530 QUERY
+ENTRY_BEGIN
+RAW
+b786467950104462ba140000000000000000
+ENTRY_END
+
+STEP 18540 QUERY
+ENTRY_BEGIN
+RAW
+b787260850104470db3e0000000000000000
+ENTRY_END
+
+STEP 18550 QUERY
+ENTRY_BEGIN
+RAW
+b787260850184470b2ad0000008d3b3b000000010001000000000f313133333837313336363136322d320000f900010f313133333837313336363136322d320000f900ff00000000005103677373096d6963726f736f667403636f6d00403b01db403c535b00030000002e4e544c4d535350000100000097b200e00700070027000000070007002000000053425332303030484f4c50524f430000
+ENTRY_END
+
+STEP 18560 QUERY
+ENTRY_BEGIN
+RAW
+b787261650114462daae0000000000000000
+ENTRY_END
+
+STEP 18570 QUERY
+ENTRY_BEGIN
+RAW
+b787261750104462daad0000000000000000
+ENTRY_END
+
+STEP 18580 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000c82d0000020405b401010402
+ENTRY_END
+
+STEP 18590 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000a61c0000020405b401010402
+ENTRY_END
+
+STEP 18600 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf0f9bf00000204057801010402
+ENTRY_END
+
+STEP 18610 QUERY
+ENTRY_BEGIN
+RAW
+b78b571050104470bfc40000000000000000
+ENTRY_END
+
+STEP 18620 QUERY
+ENTRY_BEGIN
+RAW
+b78b5710501844704cc600000097e600000000010001000000000f313231393737303731323038322d330000f900010f313231393737303731323038322d330000f900ff00000000005b03677373096d6963726f736f667403636f6d00403afc56403c4dd60003000000384e544c4d535350000100000097b200e00f000f0029000000090009002000000046532d535445494a4c535445494a4c45522d444f4d45494e0000
+ENTRY_END
+
+STEP 18630 QUERY
+ENTRY_BEGIN
+RAW
+b78c39d15010fb90343a0000000000000000
+ENTRY_END
+
+STEP 18640 QUERY
+ENTRY_BEGIN
+RAW
+b78c39d15018fb909ce6000000909f24000000010001000000000e3931303533333036363737302d330000f900010e3931303533333036363737302d330000f900ff00000000005603677373096d6963726f736f667403636f6d00403afd0f403c4e8f0003000000334e544c4d535350000100000097b208e00b000b0028000000080008002000000056494e4743415244484f54454c414c4d454c4f0000
+ENTRY_END
+
+STEP 18650 QUERY
+ENTRY_BEGIN
+RAW
+b78b571e50114462bf2a0000000000000000
+ENTRY_END
+
+STEP 18660 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400008150000020405b401010402
+ENTRY_END
+
+STEP 18670 QUERY
+ENTRY_BEGIN
+RAW
+b78c39df5011fb8233a70000000000000000
+ENTRY_END
+
+STEP 18680 QUERY
+ENTRY_BEGIN
+RAW
+b78b571f50104462bf290000000000000000
+ENTRY_END
+
+STEP 18690 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf0c9e400000204057801010402
+ENTRY_END
+
+STEP 18700 QUERY
+ENTRY_BEGIN
+RAW
+b78cbc5650104470bc750000000000000000
+ENTRY_END
+
+STEP 18710 QUERY
+ENTRY_BEGIN
+RAW
+b78cbc5650184470607800000097d000000000010001000000000f313231393737303731323038322d320000f900010f313231393737303731323038322d320000f900ff00000000005b03677373096d6963726f736f667403636f6d00403afc56403c4dd60003000000384e544c4d535350000100000097b200e00f000f0029000000090009002000000046532d535445494a4c535445494a4c45522d444f4d45494e0000
+ENTRY_END
+
+STEP 18720 QUERY
+ENTRY_BEGIN
+RAW
+b78c39e05010fb8233a60000000000000000
+ENTRY_END
+
+STEP 18730 QUERY
+ENTRY_BEGIN
+RAW
+b78da4565010fb9099d80000000000000000
+ENTRY_END
+
+STEP 18740 QUERY
+ENTRY_BEGIN
+RAW
+b78cbc6450114462bbdb0000000000000000
+ENTRY_END
+
+STEP 18750 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000228f0000020405b401010402
+ENTRY_END
+
+STEP 18760 QUERY
+ENTRY_BEGIN
+RAW
+b78da4565018fb901ec30000009084e6000000010001000000000e3931303533333036363737302d320000f900010e3931303533333036363737302d320000f900ff00000000005603677373096d6963726f736f667403636f6d00403afd0f403c4e8f0003000000334e544c4d535350000100000097b208e00b000b0028000000080008002000000056494e4743415244484f54454c414c4d454c4f0000
+ENTRY_END
+
+STEP 18770 QUERY
+ENTRY_BEGIN
+RAW
+b78cbc6550104462bbda0000000000000000
+ENTRY_END
+
+STEP 18780 QUERY
+ENTRY_BEGIN
+RAW
+b78e75ee501044701d560000000000000000
+ENTRY_END
+
+STEP 18790 QUERY
+ENTRY_BEGIN
+RAW
+b78da4645011fb8299450000000000000000
+ENTRY_END
+
+STEP 18800 QUERY
+ENTRY_BEGIN
+RAW
+b78e75ee50184470d75800000097ba00000000010001000000000f313231393737303731323038322d320000f900010f313231393737303731323038322d320000f900ff00000000005b03677373096d6963726f736f667403636f6d00403afc56403c4dd60003000000384e544c4d535350000100000097b200e00f000f0029000000090009002000000046532d535445494a4c535445494a4c45522d444f4d45494e0000
+ENTRY_END
+
+STEP 18810 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf0089000000204057801010402
+ENTRY_END
+
+STEP 18820 QUERY
+ENTRY_BEGIN
+RAW
+b78da4655010fb8299440000000000000000
+ENTRY_END
+
+STEP 18830 QUERY
+ENTRY_BEGIN
+RAW
+b78e75fc501144621cbc0000000000000000
+ENTRY_END
+
+STEP 18840 QUERY
+ENTRY_BEGIN
+RAW
+b78f54175010fb9028c10000000000000000
+ENTRY_END
+
+STEP 18850 QUERY
+ENTRY_BEGIN
+RAW
+b78f54175018fb9063c900000090cec8000000010001000000000e3931303533333036363737302d320000f900010e3931303533333036363737302d320000f900ff00000000005603677373096d6963726f736f667403636f6d00403afd0f403c4e8f0003000000334e544c4d535350000100000097b208e00b000b0028000000080008002000000056494e4743415244484f54454c414c4d454c4f0000
+ENTRY_END
+
+STEP 18860 QUERY
+ENTRY_BEGIN
+RAW
+b78e75fd501044621cbb0000000000000000
+ENTRY_END
+
+STEP 18870 QUERY
+ENTRY_BEGIN
+RAW
+b78f54255011fb82282e0000000000000000
+ENTRY_END
+
+STEP 18880 QUERY
+ENTRY_BEGIN
+RAW
+b78f54265010fb82282d0000000000000000
+ENTRY_END
+
+STEP 18890 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000300a0000020405b401010402
+ENTRY_END
+
+STEP 18900 QUERY
+ENTRY_BEGIN
+RAW
+b79029f35010447076ca0000000000000000
+ENTRY_END
+
+STEP 18910 QUERY
+ENTRY_BEGIN
+RAW
+b79029f3501844703bcc00000097ae00000000010001000000000f313231393737303731323038322d330000f900010f313231393737303731323038322d330000f900ff00000000005b03677373096d6963726f736f667403636f6d00403afc56403c4dd60003000000384e544c4d535350000100000097b200e00f000f0029000000090009002000000046532d535445494a4c535445494a4c45522d444f4d45494e0000
+ENTRY_END
+
+STEP 18920 QUERY
+ENTRY_BEGIN
+RAW
+b7902a015011446276300000000000000000
+ENTRY_END
+
+STEP 18930 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000652c0000020405b401010402
+ENTRY_END
+
+STEP 18940 QUERY
+ENTRY_BEGIN
+RAW
+b7902a0250104462762f0000000000000000
+ENTRY_END
+
+STEP 18950 QUERY
+ENTRY_BEGIN
+RAW
+b790f1e050104470e3fe0000000000000000
+ENTRY_END
+
+STEP 18960 QUERY
+ENTRY_BEGIN
+RAW
+b790f1e050184470c001000000979800000000010001000000000f313231393737303731323038322d320000f900010f313231393737303731323038322d320000f900ff00000000005b03677373096d6963726f736f667403636f6d00403afc56403c4dd60003000000384e544c4d535350000100000097b200e00f000f0029000000090009002000000046532d535445494a4c535445494a4c45522d444f4d45494e0000
+ENTRY_END
+
+STEP 18970 QUERY
+ENTRY_BEGIN
+RAW
+b790f1ee50114462e3640000000000000000
+ENTRY_END
+
+STEP 18980 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400068eb0000020405b401010402
+ENTRY_END
+
+STEP 18990 QUERY
+ENTRY_BEGIN
+RAW
+b790f1ef50104462e3630000000000000000
+ENTRY_END
+
+STEP 19000 QUERY
+ENTRY_BEGIN
+RAW
+b79170fc5010447068a10000000000000000
+ENTRY_END
+
+STEP 19010 QUERY
+ENTRY_BEGIN
+RAW
+b79170fc50184470faa300000097e200000000010001000000000f313231393737303731323038322d320000f900010f313231393737303731323038322d320000f900ff00000000005b03677373096d6963726f736f667403636f6d00403afc56403c4dd60003000000384e544c4d535350000100000097b200e00f000f0029000000090009002000000046532d535445494a4c535445494a4c45522d444f4d45494e0000
+ENTRY_END
+
+STEP 19020 QUERY
+ENTRY_BEGIN
+RAW
+b791710a5011446268070000000000000000
+ENTRY_END
+
+STEP 19030 QUERY
+ENTRY_BEGIN
+RAW
+b791710b5010446268060000000000000000
+ENTRY_END
+
+STEP 19040 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400020bf0000020405b401010402
+ENTRY_END
+
+STEP 19050 QUERY
+ENTRY_BEGIN
+RAW
+b793c2aa50104470cec40000000000000000
+ENTRY_END
+
+STEP 19060 QUERY
+ENTRY_BEGIN
+RAW
+b793c2aa50184470cbc6000000977600000000010001000000000f313231393737303731323038322d330000f900010f313231393737303731323038322d330000f900ff00000000005b03677373096d6963726f736f667403636f6d00403afc56403c4dd60003000000384e544c4d535350000100000097b200e00f000f0029000000090009002000000046532d535445494a4c535445494a4c45522d444f4d45494e0000
+ENTRY_END
+
+STEP 19070 QUERY
+ENTRY_BEGIN
+RAW
+b793c2b850114462ce2a0000000000000000
+ENTRY_END
+
+STEP 19080 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000dbf20000020405b401010402
+ENTRY_END
+
+STEP 19090 QUERY
+ENTRY_BEGIN
+RAW
+b793c2b950104462ce290000000000000000
+ENTRY_END
+
+STEP 19100 QUERY
+ENTRY_BEGIN
+RAW
+b794500950104470fc980000000000000000
+ENTRY_END
+
+STEP 19110 QUERY
+ENTRY_BEGIN
+RAW
+b794500950184470109c000000976000000000010001000000000f313231393737303731323038322d320000f900010f313231393737303731323038322d320000f900ff00000000005b03677373096d6963726f736f667403636f6d00403afc56403c4dd60003000000384e544c4d535350000100000097b200e00f000f0029000000090009002000000046532d535445494a4c535445494a4c45522d444f4d45494e0000
+ENTRY_END
+
+STEP 19120 QUERY
+ENTRY_BEGIN
+RAW
+b78ab6a950104470823d0000000000000000
+ENTRY_END
+
+STEP 19130 QUERY
+ENTRY_BEGIN
+RAW
+b78ab6a95018447098b1000000961c75000000010001000000000f313038323333313735383631302d330000f900010f313038323333313735383631302d330000f900ff00000000005a03677373096d6963726f736f667403636f6d00403afe21403c4fa10003000000374e544c4d535350000100000097b208e00e000e002900000009000900200000004f4e5a45564144455252495050455244415041524b32390000
+ENTRY_END
+
+STEP 19140 QUERY
+ENTRY_BEGIN
+RAW
+b794501750114462fbfe0000000000000000
+ENTRY_END
+
+STEP 19150 QUERY
+ENTRY_BEGIN
+RAW
+00000000700240005a800000020405b401010402
+ENTRY_END
+
+STEP 19160 QUERY
+ENTRY_BEGIN
+RAW
+b794501850104462fbfd0000000000000000
+ENTRY_END
+
+STEP 19170 QUERY
+ENTRY_BEGIN
+RAW
+b7952a9c50104470a0920000000000000000
+ENTRY_END
+
+STEP 19180 QUERY
+ENTRY_BEGIN
+RAW
+b7952a9c501844706a9500000097aa00000000010001000000000f313231393737303731323038322d320000f900010f313231393737303731323038322d320000f900ff00000000005b03677373096d6963726f736f667403636f6d00403afc56403c4dd60003000000384e544c4d535350000100000097b200e00f000f0029000000090009002000000046532d535445494a4c535445494a4c45522d444f4d45494e0000
+ENTRY_END
+
+STEP 19190 QUERY
+ENTRY_BEGIN
+RAW
+b7952aaa501144629ff80000000000000000
+ENTRY_END
+
+STEP 19200 QUERY
+ENTRY_BEGIN
+RAW
+b7952aab501044629ff70000000000000000
+ENTRY_END
+
+STEP 19210 QUERY
+ENTRY_BEGIN
+RAW
+00000000700240005b800000020405b401010402
+ENTRY_END
+
+STEP 19220 QUERY
+ENTRY_BEGIN
+RAW
+b795b7cb5010447014630000000000000000
+ENTRY_END
+
+STEP 19230 QUERY
+ENTRY_BEGIN
+RAW
+b795b7cb501844701f65000000976800000000010001000000000f313231393737303731323038322d330000f900010f313231393737303731323038322d330000f900ff00000000005b03677373096d6963726f736f667403636f6d00403afc56403c4dd60003000000384e544c4d535350000100000097b200e00f000f0029000000090009002000000046532d535445494a4c535445494a4c45522d444f4d45494e0000
+ENTRY_END
+
+STEP 19240 QUERY
+ENTRY_BEGIN
+RAW
+b795b7d95011446213c90000000000000000
+ENTRY_END
+
+STEP 19250 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400082b20000020405b401010402
+ENTRY_END
+
+STEP 19260 QUERY
+ENTRY_BEGIN
+RAW
+b795b7da5010446213c80000000000000000
+ENTRY_END
+
+STEP 19270 QUERY
+ENTRY_BEGIN
+RAW
+b7963fba50104470b3a50000000000000000
+ENTRY_END
+
+STEP 19280 QUERY
+ENTRY_BEGIN
+RAW
+b7963fba5018447075a800000097b200000000010001000000000f313231393737303731323038322d320000f900010f313231393737303731323038322d320000f900ff00000000005b03677373096d6963726f736f667403636f6d00403afc56403c4dd60003000000384e544c4d535350000100000097b200e00f000f0029000000090009002000000046532d535445494a4c535445494a4c45522d444f4d45494e0000
+ENTRY_END
+
+STEP 19290 QUERY
+ENTRY_BEGIN
+RAW
+b7963fc850114462b30b0000000000000000
+ENTRY_END
+
+STEP 19300 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000b50f0000020405b401010402
+ENTRY_END
+
+STEP 19310 QUERY
+ENTRY_BEGIN
+RAW
+b7963fc950104462b30a0000000000000000
+ENTRY_END
+
+STEP 19320 QUERY
+ENTRY_BEGIN
+RAW
+b797006150104470255b0000000000000000
+ENTRY_END
+
+STEP 19330 QUERY
+ENTRY_BEGIN
+RAW
+b797006150184470275e000000977200000000010001000000000f313231393737303731323038322d320000f900010f313231393737303731323038322d320000f900ff00000000005b03677373096d6963726f736f667403636f6d00403afc56403c4dd60003000000384e544c4d535350000100000097b200e00f000f0029000000090009002000000046532d535445494a4c535445494a4c45522d444f4d45494e0000
+ENTRY_END
+
+STEP 19340 QUERY
+ENTRY_BEGIN
+RAW
+b797006f5011446224c10000000000000000
+ENTRY_END
+
+STEP 19350 QUERY
+ENTRY_BEGIN
+RAW
+b79700705010446224c00000000000000000
+ENTRY_END
+
+STEP 19360 QUERY
+ENTRY_BEGIN
+RAW
+b78ab6b75011446281a40000000000000000
+ENTRY_END
+
+STEP 19370 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000a5620000020405b401010402
+ENTRY_END
+
+STEP 19380 QUERY
+ENTRY_BEGIN
+RAW
+b78ab6b85010446281a30000000000000000
+ENTRY_END
+
+STEP 19390 QUERY
+ENTRY_BEGIN
+RAW
+b799061e501044700fef0000000000000000
+ENTRY_END
+
+STEP 19400 QUERY
+ENTRY_BEGIN
+RAW
+b799061e50184470a7d4000000969a04000000010001000000000f313038323333313735383631302d320000f900010f313038323333313735383631302d320000f900ff00000000005a03677373096d6963726f736f667403636f6d00403afe22403c4fa20003000000374e544c4d535350000100000097b208e00e000e002900000009000900200000004f4e5a45564144455252495050455244415041524b32390000
+ENTRY_END
+
+STEP 19410 QUERY
+ENTRY_BEGIN
+RAW
+b799062c501144620f560000000000000000
+ENTRY_END
+
+STEP 19420 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400003530000020405b401010402
+ENTRY_END
+
+STEP 19430 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400097ba00000204050201010402
+ENTRY_END
+
+STEP 19440 QUERY
+ENTRY_BEGIN
+RAW
+b79cddf25010411a2d130000000000000000
+ENTRY_END
+
+STEP 19450 QUERY
+ENTRY_BEGIN
+RAW
+b79cddf25018411a5cde0000008c9fd3000000010001000000000f313036353135313838393432362d330000f900010f313036353135313838393432362d330000f900ff00000000005003677373096d6963726f736f667403636f6d00403b010f403c528f00030000002d4e544c4d535350000100000097b200e0060006002700000007000700200000004441422d4856534441424856530000
+ENTRY_END
+
+STEP 19460 QUERY
+ENTRY_BEGIN
+RAW
+b79cde005011410c2c840000000000000000
+ENTRY_END
+
+STEP 19470 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000a37900000204050201010402
+ENTRY_END
+
+STEP 19480 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf0aab600000204055001010402
+ENTRY_END
+
+STEP 19490 QUERY
+ENTRY_BEGIN
+RAW
+b79cde015010410c2c830000000000000000
+ENTRY_END
+
+STEP 19500 QUERY
+ENTRY_BEGIN
+RAW
+b79d77645010411a9f5f0000000000000000
+ENTRY_END
+
+STEP 19510 QUERY
+ENTRY_BEGIN
+RAW
+b79e06435010ff0015150000000000000000
+ENTRY_END
+
+STEP 19520 QUERY
+ENTRY_BEGIN
+RAW
+b79d77645018411a70710000008cff8d000000010001000000000f313036353135313838393432362d320000f900010f313036353135313838393432362d320000f900ff00000000005003677373096d6963726f736f667403636f6d00403b010f403c528f00030000002d4e544c4d535350000100000097b200e0060006002700000007000700200000004441422d4856534441424856530000
+ENTRY_END
+
+STEP 19530 QUERY
+ENTRY_BEGIN
+RAW
+b79e06435018ff005db30000009294e1000000010001000000000f313531313832383438383231302d330000f900010f313531313832383438383231302d330000f900ff00000000005603677373096d6963726f736f667403636f6d00403b000c403c518c0003000000334e544c4d535350000100000097b208e0090009002a0000000a000a002000000057324b5345525645523150524b564457494c440000
+ENTRY_END
+
+STEP 19540 QUERY
+ENTRY_BEGIN
+RAW
+b79e06515011fef214800000000000000000
+ENTRY_END
+
+STEP 19550 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf050e100000204055001010402
+ENTRY_END
+
+STEP 19560 QUERY
+ENTRY_BEGIN
+RAW
+b79d77725011410c9ed00000000000000000
+ENTRY_END
+
+STEP 19570 QUERY
+ENTRY_BEGIN
+RAW
+b79e06525010fef2147f0000000000000000
+ENTRY_END
+
+STEP 19580 QUERY
+ENTRY_BEGIN
+RAW
+00000000700240009ac800000204050201010402
+ENTRY_END
+
+STEP 19590 QUERY
+ENTRY_BEGIN
+RAW
+b79ebf905010ff0001f20000000000000000
+ENTRY_END
+
+STEP 19600 QUERY
+ENTRY_BEGIN
+RAW
+b79ebf905018ff008473000000925bff000000010001000000000f313531313832383438383231302d320000f900010f313531313832383438383231302d320000f900ff00000000005603677373096d6963726f736f667403636f6d00403b000c403c518c0003000000334e544c4d535350000100000097b208e0090009002a0000000a000a002000000057324b5345525645523150524b564457494c440000
+ENTRY_END
+
+STEP 19610 QUERY
+ENTRY_BEGIN
+RAW
+b79ebf9e5011fef2015d0000000000000000
+ENTRY_END
+
+STEP 19620 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf0b1da00000204055001010402
+ENTRY_END
+
+STEP 19630 QUERY
+ENTRY_BEGIN
+RAW
+b79d77735010410c9ecf0000000000000000
+ENTRY_END
+
+STEP 19640 QUERY
+ENTRY_BEGIN
+RAW
+b79fb44e5010411a59c20000000000000000
+ENTRY_END
+
+STEP 19650 QUERY
+ENTRY_BEGIN
+RAW
+b79ebf9f5010fef2015c0000000000000000
+ENTRY_END
+
+STEP 19660 QUERY
+ENTRY_BEGIN
+RAW
+b7a08dfc5010ff00947d0000000000000000
+ENTRY_END
+
+STEP 19670 QUERY
+ENTRY_BEGIN
+RAW
+b79fb44e5018411a6a970000008cbfca000000010001000000000f313036353135313838393432362d320000f900010f313036353135313838393432362d320000f900ff00000000005003677373096d6963726f736f667403636f6d00403b010f403c528f00030000002d4e544c4d535350000100000097b200e0060006002700000007000700200000004441422d4856534441424856530000
+ENTRY_END
+
+STEP 19680 QUERY
+ENTRY_BEGIN
+RAW
+b7a08dfc5018ff004fe100000092231d000000010001000000000f313531313832383438383231302d320000f900010f313531313832383438383231302d320000f900ff00000000005603677373096d6963726f736f667403636f6d00403b000c403c518c0003000000334e544c4d535350000100000097b208e0090009002a0000000a000a002000000057324b5345525645523150524b564457494c440000
+ENTRY_END
+
+STEP 19690 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000bed00000020405b401010402
+ENTRY_END
+
+STEP 19700 QUERY
+ENTRY_BEGIN
+RAW
+b7a08e0a5011fef293e80000000000000000
+ENTRY_END
+
+STEP 19710 QUERY
+ENTRY_BEGIN
+RAW
+b79fb45c5011410c59330000000000000000
+ENTRY_END
+
+STEP 19720 QUERY
+ENTRY_BEGIN
+RAW
+b7a14a0750104470e56b0000000000000000
+ENTRY_END
+
+STEP 19730 QUERY
+ENTRY_BEGIN
+RAW
+b7a08e0b5010fef293e70000000000000000
+ENTRY_END
+
+STEP 19740 QUERY
+ENTRY_BEGIN
+RAW
+b7a14a0750184470b1d600000090026f000000010001000000000f313230323539303834323839382d330000f900010f313230323539303834323839382d330000f900ff00000000005403677373096d6963726f736f667403636f6d00403b0439403c55b90003000000314e544c4d535350000100000097b200c009000900280000000800080020000000534c4f5453504543534c4f5453504543300000
+ENTRY_END
+
+STEP 19750 QUERY
+ENTRY_BEGIN
+RAW
+b7a14a1550114462e4d80000000000000000
+ENTRY_END
+
+STEP 19760 QUERY
+ENTRY_BEGIN
+RAW
+00000000700240002ebf0000020405b401010402
+ENTRY_END
+
+STEP 19770 QUERY
+ENTRY_BEGIN
+RAW
+b79fb45d5010410c59320000000000000000
+ENTRY_END
+
+STEP 19780 QUERY
+ENTRY_BEGIN
+RAW
+b7a14a1650104462e4d70000000000000000
+ENTRY_END
+
+STEP 19790 QUERY
+ENTRY_BEGIN
+RAW
+b7a1da0550104470c55b0000000000000000
+ENTRY_END
+
+STEP 19800 QUERY
+ENTRY_BEGIN
+RAW
+b7a1da0550184470ef6c00000090a5c9000000010001000000000f313230323539303834323839382d320000f900010f313230323539303834323839382d320000f900ff00000000005403677373096d6963726f736f667403636f6d00403b0439403c55b90003000000314e544c4d535350000100000097b200c009000900280000000800080020000000534c4f5453504543534c4f5453504543300000
+ENTRY_END
+
+STEP 19810 QUERY
+ENTRY_BEGIN
+RAW
+b7a1da1350114462c4c80000000000000000
+ENTRY_END
+
+STEP 19820 QUERY
+ENTRY_BEGIN
+RAW
+00000000700240009c3d0000020405b401010402
+ENTRY_END
+
+STEP 19830 QUERY
+ENTRY_BEGIN
+RAW
+b7a1da1450104462c4c70000000000000000
+ENTRY_END
+
+STEP 19840 QUERY
+ENTRY_BEGIN
+RAW
+b7a2547350104470b86b0000000000000000
+ENTRY_END
+
+STEP 19850 QUERY
+ENTRY_BEGIN
+RAW
+b7a25473501844705e05000000902a41000000010001000000000f313230323539303834323839382d320000f900010f313230323539303834323839382d320000f900ff00000000005403677373096d6963726f736f667403636f6d00403b0439403c55b90003000000314e544c4d535350000100000097b200c009000900280000000800080020000000534c4f5453504543534c4f5453504543300000
+ENTRY_END
+
+STEP 19860 QUERY
+ENTRY_BEGIN
+RAW
+00000000700240006c7000000204050201010402
+ENTRY_END
+
+STEP 19870 QUERY
+ENTRY_BEGIN
+RAW
+b7a2548150114462b7d80000000000000000
+ENTRY_END
+
+STEP 19880 QUERY
+ENTRY_BEGIN
+RAW
+b7a2548250104462b7d70000000000000000
+ENTRY_END
+
+STEP 19890 QUERY
+ENTRY_BEGIN
+RAW
+b7a310eb5010411acec90000000000000000
+ENTRY_END
+
+STEP 19900 QUERY
+ENTRY_BEGIN
+RAW
+b7a310eb5018411a16fa0000008c876e000000010001000000000f313036353135313838393432362d330000f900010f313036353135313838393432362d330000f900ff00000000005003677373096d6963726f736f667403636f6d00403b010f403c528f00030000002d4e544c4d535350000100000097b200e0060006002700000007000700200000004441422d4856534441424856530000
+ENTRY_END
+
+STEP 19910 QUERY
+ENTRY_BEGIN
+RAW
+b7a310f95011410cce3a0000000000000000
+ENTRY_END
+
+STEP 19920 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400033b900000204050201010402
+ENTRY_END
+
+STEP 19930 QUERY
+ENTRY_BEGIN
+RAW
+b7a310fa5010410cce390000000000000000
+ENTRY_END
+
+STEP 19940 QUERY
+ENTRY_BEGIN
+RAW
+b7a40ad35010411a9c290000000000000000
+ENTRY_END
+
+STEP 19950 QUERY
+ENTRY_BEGIN
+RAW
+b7a40ad35018411a2d4e0000008c3f7b000000010001000000000f313036353135313838393432362d320000f900010f313036353135313838393432362d320000f900ff00000000005003677373096d6963726f736f667403636f6d00403b010f403c528f00030000002d4e544c4d535350000100000097b200e0060006002700000007000700200000004441422d4856534441424856530000
+ENTRY_END
+
+STEP 19960 QUERY
+ENTRY_BEGIN
+RAW
+b7a40ae15011410c9b9a0000000000000000
+ENTRY_END
+
+STEP 19970 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000654c00000204050201010402
+ENTRY_END
+
+STEP 19980 QUERY
+ENTRY_BEGIN
+RAW
+b7a40ae25010410c9b990000000000000000
+ENTRY_END
+
+STEP 19990 QUERY
+ENTRY_BEGIN
+RAW
+b7a4fbf25010411adc9c0000000000000000
+ENTRY_END
+
+STEP 20000 QUERY
+ENTRY_BEGIN
+RAW
+b7a4fbf25018411aab3c0000008c0000000000010001000000000f313036353135313838393432362d320000f900010f313036353135313838393432362d320000f900ff00000000005003677373096d6963726f736f667403636f6d00403b0110403c529000030000002d4e544c4d535350000100000097b200e0060006002700000007000700200000004441422d4856534441424856530000
+ENTRY_END
+
+STEP 20010 QUERY
+ENTRY_BEGIN
+RAW
+b7a4fc005011410cdc0d0000000000000000
+ENTRY_END
+
+STEP 20020 QUERY
+ENTRY_BEGIN
+RAW
+b7a4fc015010410cdc0c0000000000000000
+ENTRY_END
+
+STEP 20030 QUERY
+ENTRY_BEGIN
+RAW
+b799062d501044620f550000000000000000
+ENTRY_END
+
+STEP 20040 QUERY
+ENTRY_BEGIN
+RAW
+b79c1b875010447058730000000000000000
+ENTRY_END
+
+STEP 20050 QUERY
+ENTRY_BEGIN
+RAW
+b79c1b87501844701a89000000966dd4000000010001000000000f313038323333313735383631302d320000f900010f313038323333313735383631302d320000f900ff00000000005a03677373096d6963726f736f667403636f6d00403afe23403c4fa30003000000374e544c4d535350000100000097b208e00e000e002900000009000900200000004f4e5a45564144455252495050455244415041524b32390000
+ENTRY_END
+
+STEP 20060 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400042ef0000020405b401010402
+ENTRY_END
+
+STEP 20070 QUERY
+ENTRY_BEGIN
+RAW
+b7a68eff50104470248d0000000000000000
+ENTRY_END
+
+STEP 20080 QUERY
+ENTRY_BEGIN
+RAW
+b7a68eff501844701c1f0000008614fc000000010001000000000f313131363639313439363937382d330000f900010f313131363639313439363937382d330000f900ff00000000004a03677373096d6963726f736f667403636f6d00403b094d403c5acd0003000000274e544c4d535350000100000097b200e0040004002300000003000300200000004b55424b5542320000
+ENTRY_END
+
+STEP 20090 QUERY
+ENTRY_BEGIN
+RAW
+b7a68f0d5011446224040000000000000000
+ENTRY_END
+
+STEP 20100 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000b00b0000020405b401010402
+ENTRY_END
+
+STEP 20110 QUERY
+ENTRY_BEGIN
+RAW
+b7a772d750104470add00000000000000000
+ENTRY_END
+
+STEP 20120 QUERY
+ENTRY_BEGIN
+RAW
+b7a772d7501844709517000000862648000000010001000000000f313131363639313439363937382d320000f900010f313131363639313439363937382d320000f900ff00000000004a03677373096d6963726f736f667403636f6d00403b094d403c5acd0003000000274e544c4d535350000100000097b200e0040004002300000003000300200000004b55424b5542320000
+ENTRY_END
+
+STEP 20130 QUERY
+ENTRY_BEGIN
+RAW
+b7a68f0e5010446224030000000000000000
+ENTRY_END
+
+STEP 20140 QUERY
+ENTRY_BEGIN
+RAW
+b79c1b955011446257da0000000000000000
+ENTRY_END
+
+STEP 20150 QUERY
+ENTRY_BEGIN
+RAW
+b7a772e550114462ad470000000000000000
+ENTRY_END
+
+STEP 20160 QUERY
+ENTRY_BEGIN
+RAW
+00000000700240008c7e0000020405b401010402
+ENTRY_END
+
+STEP 20170 QUERY
+ENTRY_BEGIN
+RAW
+b7a772e650104462ad460000000000000000
+ENTRY_END
+
+STEP 20180 QUERY
+ENTRY_BEGIN
+RAW
+b7a956ee50104470a62a0000000000000000
+ENTRY_END
+
+STEP 20190 QUERY
+ENTRY_BEGIN
+RAW
+b7a956ee50184470f94200000086ba76000000010001000000000f313131363639313439363937382d320000f900010f313131363639313439363937382d320000f900ff00000000004a03677373096d6963726f736f667403636f6d00403b094d403c5acd0003000000274e544c4d535350000100000097b200e0040004002300000003000300200000004b55424b5542320000
+ENTRY_END
+
+STEP 20200 QUERY
+ENTRY_BEGIN
+RAW
+b7a956fc50114462a5a10000000000000000
+ENTRY_END
+
+STEP 20210 QUERY
+ENTRY_BEGIN
+RAW
+b7a956fd50104462a5a00000000000000000
+ENTRY_END
+
+STEP 20220 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000e5980000020405b401010402
+ENTRY_END
+
+STEP 20230 QUERY
+ENTRY_BEGIN
+RAW
+b7aa19b2501044703c800000000000000000
+ENTRY_END
+
+STEP 20240 QUERY
+ENTRY_BEGIN
+RAW
+b7aa19b250184470b1f40000008ddd28000000010001000000000f313231393737303731323038322d330000f900010f313231393737303731323038322d330000f900ff00000000005103677373096d6963726f736f667403636f6d00403afd15403c4e9500030000002e4e544c4d535350000100000097b200e00700070027000000070007002000000053455256455231534954544152440000
+ENTRY_END
+
+STEP 20250 QUERY
+ENTRY_BEGIN
+RAW
+b7aa19c0501144623bf00000000000000000
+ENTRY_END
+
+STEP 20260 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400058f40000020405b401010402
+ENTRY_END
+
+STEP 20270 QUERY
+ENTRY_BEGIN
+RAW
+b7aa19c1501044623bef0000000000000000
+ENTRY_END
+
+STEP 20280 QUERY
+ENTRY_BEGIN
+RAW
+b7ab053050104470c45c0000000000000000
+ENTRY_END
+
+STEP 20290 QUERY
+ENTRY_BEGIN
+RAW
+b7ab053050184470d0130000008d47e7000000010001000000000f313231393737303731323038322d320000f900010f313231393737303731323038322d320000f900ff00000000005103677373096d6963726f736f667403636f6d00403afd15403c4e9500030000002e4e544c4d535350000100000097b200e00700070027000000070007002000000053455256455231534954544152440000
+ENTRY_END
+
+STEP 20300 QUERY
+ENTRY_BEGIN
+RAW
+b7ab053e50114462c3cc0000000000000000
+ENTRY_END
+
+STEP 20310 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400017040000020405b401010402
+ENTRY_END
+
+STEP 20320 QUERY
+ENTRY_BEGIN
+RAW
+b7ab053f50104462c3cb0000000000000000
+ENTRY_END
+
+STEP 20330 QUERY
+ENTRY_BEGIN
+RAW
+b7ab93d850104470f3c30000000000000000
+ENTRY_END
+
+STEP 20340 QUERY
+ENTRY_BEGIN
+RAW
+b79c1b965010446257d90000000000000000
+ENTRY_END
+
+STEP 20350 QUERY
+ENTRY_BEGIN
+RAW
+b7ab93d8501844708a3c0000008dbd25000000010001000000000f313231393737303731323038322d320000f900010f313231393737303731323038322d320000f900ff00000000005103677373096d6963726f736f667403636f6d00403afd15403c4e9500030000002e4e544c4d535350000100000097b200e00700070027000000070007002000000053455256455231534954544152440000
+ENTRY_END
+
+STEP 20360 QUERY
+ENTRY_BEGIN
+RAW
+b7ab93e650114462f3330000000000000000
+ENTRY_END
+
+STEP 20370 QUERY
+ENTRY_BEGIN
+RAW
+00000000700240001bf80000020405b401010402
+ENTRY_END
+
+STEP 20380 QUERY
+ENTRY_BEGIN
+RAW
+b7ab93e750104462f3320000000000000000
+ENTRY_END
+
+STEP 20390 QUERY
+ENTRY_BEGIN
+RAW
+b7ac6f7a501044701d150000000000000000
+ENTRY_END
+
+STEP 20400 QUERY
+ENTRY_BEGIN
+RAW
+b7ac6f7a501844708c1a00000091ecce000000010001000000000f313034373937323032303234322d330000f900010f313034373937323032303234322d330000f900ff00000000005503677373096d6963726f736f667403636f6d00403afd3e403c4ebe0003000000324e544c4d535350000100000097b208e00b000b00270000000700070020000000495345525645524b5356494e5445524e45540000
+ENTRY_END
+
+STEP 20410 QUERY
+ENTRY_BEGIN
+RAW
+b7ac6f88501144621c810000000000000000
+ENTRY_END
+
+STEP 20420 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000de780000020405b401010402
+ENTRY_END
+
+STEP 20430 QUERY
+ENTRY_BEGIN
+RAW
+b7ac6f89501044621c800000000000000000
+ENTRY_END
+
+STEP 20440 QUERY
+ENTRY_BEGIN
+RAW
+b7aef16c501044705da10000000000000000
+ENTRY_END
+
+STEP 20450 QUERY
+ENTRY_BEGIN
+RAW
+b7aef16c501844706076000000915800000000010001000000000f313034373937323032303234322d320000f900010f313034373937323032303234322d320000f900ff00000000005503677373096d6963726f736f667403636f6d00403afd3f403c4ebf0003000000324e544c4d535350000100000097b208e00b000b00270000000700070020000000495345525645524b5356494e5445524e45540000
+ENTRY_END
+
+STEP 20460 QUERY
+ENTRY_BEGIN
+RAW
+b7aef17a501144625d0d0000000000000000
+ENTRY_END
+
+STEP 20470 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000ce160000020405b401010402
+ENTRY_END
+
+STEP 20480 QUERY
+ENTRY_BEGIN
+RAW
+b7aef17b501044625d0c0000000000000000
+ENTRY_END
+
+STEP 20490 QUERY
+ENTRY_BEGIN
+RAW
+b7af8e0150104470b0a90000000000000000
+ENTRY_END
+
+STEP 20500 QUERY
+ENTRY_BEGIN
+RAW
+b7af8e0150184470ff7e000000910c00000000010001000000000f313034373937323032303234322d320000f900010f313034373937323032303234322d320000f900ff00000000005503677373096d6963726f736f667403636f6d00403afd3f403c4ebf0003000000324e544c4d535350000100000097b208e00b000b00270000000700070020000000495345525645524b5356494e5445524e45540000
+ENTRY_END
+
+STEP 20510 QUERY
+ENTRY_BEGIN
+RAW
+b7af8e0f50114462b0150000000000000000
+ENTRY_END
+
+STEP 20520 QUERY
+ENTRY_BEGIN
+RAW
+b7af8e1050104462b0140000000000000000
+ENTRY_END
+
+STEP 20530 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf08ad60000020405b401010402
+ENTRY_END
+
+STEP 20540 QUERY
+ENTRY_BEGIN
+RAW
+b7b2120c5010faf0edcb0000000000000000
+ENTRY_END
+
+STEP 20550 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400026770000020405ac01010402
+ENTRY_END
+
+STEP 20560 QUERY
+ENTRY_BEGIN
+RAW
+b7b516e85010441080750000000000000000
+ENTRY_END
+
+STEP 20570 QUERY
+ENTRY_BEGIN
+RAW
+b7b516e8501844102fb1000000943310000000010001000000000f313036353135313838393432362d330000f900010f313036353135313838393432362d330000f900ff00000000005803677373096d6963726f736f667403636f6d00403af76a403c48ea0003000000354e544c4d535350000100000097b200c00f000f002600000006000600200000004e49454c53314b52454e53434f4e53554c54414e430000
+ENTRY_END
+
+STEP 20580 QUERY
+ENTRY_BEGIN
+RAW
+b7b516f6501144027fde0000000000000000
+ENTRY_END
+
+STEP 20590 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000603d0000020405ac01010402
+ENTRY_END
+
+STEP 20600 QUERY
+ENTRY_BEGIN
+RAW
+b7b516f7501044027fdd0000000000000000
+ENTRY_END
+
+STEP 20610 QUERY
+ENTRY_BEGIN
+RAW
+b7b59189501044103f9a0000000000000000
+ENTRY_END
+
+STEP 20620 QUERY
+ENTRY_BEGIN
+RAW
+b7b59189501844103ef200000094e3f4000000010001000000000f313036353135313838393432362d320000f900010f313036353135313838393432362d320000f900ff00000000005803677373096d6963726f736f667403636f6d00403af76a403c48ea0003000000354e544c4d535350000100000097b200c00f000f002600000006000600200000004e49454c53314b52454e53434f4e53554c54414e430000
+ENTRY_END
+
+STEP 20630 QUERY
+ENTRY_BEGIN
+RAW
+b7b59197501144023f030000000000000000
+ENTRY_END
+
+STEP 20640 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400004800000020405ac01010402
+ENTRY_END
+
+STEP 20650 QUERY
+ENTRY_BEGIN
+RAW
+b7b59198501044023f020000000000000000
+ENTRY_END
+
+STEP 20660 QUERY
+ENTRY_BEGIN
+RAW
+b7b677b150104410fdb30000000000000000
+ENTRY_END
+
+STEP 20670 QUERY
+ENTRY_BEGIN
+RAW
+b7b677b150184410f59300000094eb6c000000010001000000000f313036353135313838393432362d320000f900010f313036353135313838393432362d320000f900ff00000000005803677373096d6963726f736f667403636f6d00403af76a403c48ea0003000000354e544c4d535350000100000097b200c00f000f002600000006000600200000004e49454c53314b52454e53434f4e53554c54414e430000
+ENTRY_END
+
+STEP 20680 QUERY
+ENTRY_BEGIN
+RAW
+b7b677bf50114402fd1c0000000000000000
+ENTRY_END
+
+STEP 20690 QUERY
+ENTRY_BEGIN
+RAW
+b7b677c050104402fd1b0000000000000000
+ENTRY_END
+
+STEP 20700 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000f20a0000020405b401010402
+ENTRY_END
+
+STEP 20710 QUERY
+ENTRY_BEGIN
+RAW
+b7b8ebb55010447076e00000000000000000
+ENTRY_END
+
+STEP 20720 QUERY
+ENTRY_BEGIN
+RAW
+b7b8ebb550184470510a00000096c39e000000010001000000000f313133333837313336363136322d330000f900010f313133333837313336363136322d330000f900ff00000000005a03677373096d6963726f736f667403636f6d003707bbc937090d490003000000374e544c4d535350000100000097b200c00a000a002d0000000d000d002000000057494e32303030534552564552323030305345525645520000
+ENTRY_END
+
+STEP 20730 QUERY
+ENTRY_BEGIN
+RAW
+b7b8ebc35011446276470000000000000000
+ENTRY_END
+
+STEP 20740 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400081a30000020405b401010402
+ENTRY_END
+
+STEP 20750 QUERY
+ENTRY_BEGIN
+RAW
+00000000700222386dc500000204057801010402
+ENTRY_END
+
+STEP 20760 QUERY
+ENTRY_BEGIN
+RAW
+b7bc37fc50102648a6740000000000000000
+ENTRY_END
+
+STEP 20770 QUERY
+ENTRY_BEGIN
+RAW
+b7bc37fc50182648d4fd0000008dc800000000010001000000000f313133333837313336363136322d330000f900010f313133333837313336363136322d330000f900ff00000000005103677373096d6963726f736f667403636f6d00403afcc3403c4e4300030000002e4e544c4d535350000100000097b200e0080008002600000006000600200000005345525645524e4b4f45524945520000
+ENTRY_END
+
+STEP 20780 QUERY
+ENTRY_BEGIN
+RAW
+b7bc380a5011263aa5e40000000000000000
+ENTRY_END
+
+STEP 20790 QUERY
+ENTRY_BEGIN
+RAW
+0000000070022238873c00000204057801010402
+ENTRY_END
+
+STEP 20800 QUERY
+ENTRY_BEGIN
+RAW
+b7b8ebc45010446276460000000000000000
+ENTRY_END
+
+STEP 20810 QUERY
+ENTRY_BEGIN
+RAW
+b7bb91ca5010447060610000000000000000
+ENTRY_END
+
+STEP 20820 QUERY
+ENTRY_BEGIN
+RAW
+b7bb91ca501844700c3000000096f2fa000000010001000000000f313133333837313336363136322d320000f900010f313133333837313336363136322d320000f900ff00000000005a03677373096d6963726f736f667403636f6d003707bbc937090d490003000000374e544c4d535350000100000097b200c00a000a002d0000000d000d002000000057494e32303030534552564552323030305345525645520000
+ENTRY_END
+
+STEP 20830 QUERY
+ENTRY_BEGIN
+RAW
+b7bc380b5010263aa5e30000000000000000
+ENTRY_END
+
+STEP 20840 QUERY
+ENTRY_BEGIN
+RAW
+b7bcf5915010264802560000000000000000
+ENTRY_END
+
+STEP 20850 QUERY
+ENTRY_BEGIN
+RAW
+b7bcf5915018264891e00000008d6800000000010001000000000f313133333837313336363136322d320000f900010f313133333837313336363136322d320000f900ff00000000005103677373096d6963726f736f667403636f6d00403afcc3403c4e4300030000002e4e544c4d535350000100000097b200e0080008002600000006000600200000005345525645524e4b4f45524945520000
+ENTRY_END
+
+STEP 20860 QUERY
+ENTRY_BEGIN
+RAW
+b7bcf59f5011263a01c60000000000000000
+ENTRY_END
+
+STEP 20870 QUERY
+ENTRY_BEGIN
+RAW
+0000000070022238650600000204057801010402
+ENTRY_END
+
+STEP 20880 QUERY
+ENTRY_BEGIN
+RAW
+b7bcf5a05010263a01c50000000000000000
+ENTRY_END
+
+STEP 20890 QUERY
+ENTRY_BEGIN
+RAW
+b7bd858150102648502f0000000000000000
+ENTRY_END
+
+STEP 20900 QUERY
+ENTRY_BEGIN
+RAW
+b7bd8581501826483fba0000008d0800000000010001000000000f313133333837313336363136322d320000f900010f313133333837313336363136322d320000f900ff00000000005103677373096d6963726f736f667403636f6d00403afcc3403c4e4300030000002e4e544c4d535350000100000097b200e0080008002600000006000600200000005345525645524e4b4f45524945520000
+ENTRY_END
+
+STEP 20910 QUERY
+ENTRY_BEGIN
+RAW
+b7bd858f5011263a4f9f0000000000000000
+ENTRY_END
+
+STEP 20920 QUERY
+ENTRY_BEGIN
+RAW
+00000000700240001a7a00000204056401010402
+ENTRY_END
+
+STEP 20930 QUERY
+ENTRY_BEGIN
+RAW
+b7bd85905010263a4f9e0000000000000000
+ENTRY_END
+
+STEP 20940 QUERY
+ENTRY_BEGIN
+RAW
+b7bb91d8501144625fc80000000000000000
+ENTRY_END
+
+STEP 20950 QUERY
+ENTRY_BEGIN
+RAW
+00000000700240007ebd0000020405b401010402
+ENTRY_END
+
+STEP 20960 QUERY
+ENTRY_BEGIN
+RAW
+b7be6078501040b02df70000000000000000
+ENTRY_END
+
+STEP 20970 QUERY
+ENTRY_BEGIN
+RAW
+b7be6078501840b0aa3800000092fb2e000000010001000000000f313138353431303937333731342d330000f900010f313138353431303937333731342d330000f900ff00000000005603677373096d6963726f736f667403636f6d00403afbc4403c4d440003000000334e544c4d535350000100000097b200e0080008002b0000000b000b00200000005342534d4f4e53494e41494d4f4e53494e41490000
+ENTRY_END
+
+STEP 20980 QUERY
+ENTRY_BEGIN
+RAW
+b7be6086501140a22d620000000000000000
+ENTRY_END
+
+STEP 20990 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000ced900000204056401010402
+ENTRY_END
+
+STEP 21000 QUERY
+ENTRY_BEGIN
+RAW
+b7be6087501040a22d610000000000000000
+ENTRY_END
+
+STEP 21010 QUERY
+ENTRY_BEGIN
+RAW
+b7bf9d98501040b0a5350000000000000000
+ENTRY_END
+
+STEP 21020 QUERY
+ENTRY_BEGIN
+RAW
+b7bf9d98501840b0870a00000092969c000000010001000000000f313138353431303937333731342d320000f900010f313138353431303937333731342d320000f900ff00000000005603677373096d6963726f736f667403636f6d00403afbc4403c4d440003000000334e544c4d535350000100000097b200e0080008002b0000000b000b00200000005342534d4f4e53494e41494d4f4e53494e41490000
+ENTRY_END
+
+STEP 21030 QUERY
+ENTRY_BEGIN
+RAW
+b7bf9da6501140a2a4a00000000000000000
+ENTRY_END
+
+STEP 21040 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000319000000204056401010402
+ENTRY_END
+
+STEP 21050 QUERY
+ENTRY_BEGIN
+RAW
+b7bf9da7501040a2a49f0000000000000000
+ENTRY_END
+
+STEP 21060 QUERY
+ENTRY_BEGIN
+RAW
+b7bb91d9501044625fc70000000000000000
+ENTRY_END
+
+STEP 21070 QUERY
+ENTRY_BEGIN
+RAW
+b7bf057450104470e9cd0000000000000000
+ENTRY_END
+
+STEP 21080 QUERY
+ENTRY_BEGIN
+RAW
+b7bf057450184470c0c800000096c7ce000000010001000000000f313133333837313336363136322d320000f900010f313133333837313336363136322d320000f900ff00000000005a03677373096d6963726f736f667403636f6d003707bbc937090d490003000000374e544c4d535350000100000097b200c00a000a002d0000000d000d002000000057494e32303030534552564552323030305345525645520000
+ENTRY_END
+
+STEP 21090 QUERY
+ENTRY_BEGIN
+RAW
+b7c1a905501040b0fc7c0000000000000000
+ENTRY_END
+
+STEP 21100 QUERY
+ENTRY_BEGIN
+RAW
+b7c1a905501840b0a16400000092d389000000010001000000000f313138353431303937333731342d320000f900010f313138353431303937333731342d320000f900ff00000000005603677373096d6963726f736f667403636f6d00403afbc4403c4d440003000000334e544c4d535350000100000097b200e0080008002b0000000b000b00200000005342534d4f4e53494e41494d4f4e53494e41490000
+ENTRY_END
+
+STEP 21110 QUERY
+ENTRY_BEGIN
+RAW
+b7c1a913501140a2fbe70000000000000000
+ENTRY_END
+
+STEP 21120 QUERY
+ENTRY_BEGIN
+RAW
+b7c1a914501040a2fbe60000000000000000
+ENTRY_END
+
+STEP 21130 QUERY
+ENTRY_BEGIN
+RAW
+b7bf058250114462e9340000000000000000
+ENTRY_END
+
+STEP 21140 QUERY
+ENTRY_BEGIN
+RAW
+b7bf058350104462e9330000000000000000
+ENTRY_END
+
+;STEP 21150 QUERY
+;ENTRY_BEGIN
+;RAW
+;2c2a01000001000000000000056b6f726e6f026e6c00000f000100
+;ENTRY_END
+
+STEP 21160 QUERY
+ENTRY_BEGIN
+RAW
+b7b2120c5018faf03b6f0000008d7b00000000010001000000000f313131363639313439363937382d330000f900010f313131363639313439363937382d330000f900ff00000000005103677373096d6963726f736f667403636f6d00403afd3d403c4ebd00030000002e4e544c4d535350000100000097b208e0070007002700000007000700200000005245545f4653315245544152434f0000
+ENTRY_END
+
+STEP 21170 QUERY
+ENTRY_BEGIN
+RAW
+b7b2120c5018faf03b6f0000008d7b00000000010001000000000f313131363639313439363937382d330000f900010f313131363639313439363937382d330000f900ff00000000005103677373096d6963726f736f667403636f6d00403afd3d403c4ebd00030000002e4e544c4d535350000100000097b208e0070007002700000007000700200000005245545f4653315245544152434f0000
+ENTRY_END
+
+STEP 21180 QUERY
+ENTRY_BEGIN
+RAW
+b7b2121a5011fae2ed3b0000000000000000
+ENTRY_END
+
+STEP 21190 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf072e80000020405b401010402
+ENTRY_END
+
+STEP 21200 QUERY
+ENTRY_BEGIN
+RAW
+b7b2121b5010fae2ed3a0000000000000000
+ENTRY_END
+
+STEP 21210 QUERY
+ENTRY_BEGIN
+RAW
+b7c35b315010faf08ca70000000000000000
+ENTRY_END
+
+STEP 21220 QUERY
+ENTRY_BEGIN
+RAW
+b7c35b315018faf0d04b0000008d8000000000010001000000000f313131363639313439363937382d320000f900010f313131363639313439363937382d320000f900ff00000000005103677373096d6963726f736f667403636f6d00403afd40403c4ec000030000002e4e544c4d535350000100000097b208e0070007002700000007000700200000005245545f4653315245544152434f0000
+ENTRY_END
+
+STEP 21230 QUERY
+ENTRY_BEGIN
+RAW
+b7c35b3f5011fae28c170000000000000000
+ENTRY_END
+
+STEP 21240 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf033120000020405b401010402
+ENTRY_END
+
+STEP 21250 QUERY
+ENTRY_BEGIN
+RAW
+b7c35b405010fae28c160000000000000000
+ENTRY_END
+
+STEP 21260 QUERY
+ENTRY_BEGIN
+RAW
+b7c5cd275010faf0dad80000000000000000
+ENTRY_END
+
+STEP 21270 QUERY
+ENTRY_BEGIN
+RAW
+b7c5cd275018faf0a87c0000008df600000000010001000000000f313131363639313439363937382d320000f900010f313131363639313439363937382d320000f900ff00000000005103677373096d6963726f736f667403636f6d00403afd40403c4ec000030000002e4e544c4d535350000100000097b208e0070007002700000007000700200000005245545f4653315245544152434f0000
+ENTRY_END
+
+STEP 21280 QUERY
+ENTRY_BEGIN
+RAW
+b7c5cd355011fae2da480000000000000000
+ENTRY_END
+
+STEP 21290 QUERY
+ENTRY_BEGIN
+RAW
+b7c5cd365010fae2da470000000000000000
+ENTRY_END
+
+STEP 21300 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000de6f0000020405ac01010402
+ENTRY_END
+
+STEP 21310 QUERY
+ENTRY_BEGIN
+RAW
+b7c6575050104410f7f40000000000000000
+ENTRY_END
+
+STEP 21320 QUERY
+ENTRY_BEGIN
+RAW
+b7c6575050184410ed5700000094e8e8000000010001000000000f313036353135313838393432362d330000f900010f313036353135313838393432362d330000f900ff00000000005803677373096d6963726f736f667403636f6d00403af76c403c48ec0003000000354e544c4d535350000100000097b200c00f000f002600000006000600200000004e49454c53314b52454e53434f4e53554c54414e430000
+ENTRY_END
+
+STEP 21330 QUERY
+ENTRY_BEGIN
+RAW
+b7c6575e50114402f75d0000000000000000
+ENTRY_END
+
+STEP 21340 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000f46f0000020405ac01010402
+ENTRY_END
+
+STEP 21350 QUERY
+ENTRY_BEGIN
+RAW
+b7c6575f50104402f75c0000000000000000
+ENTRY_END
+
+STEP 21360 QUERY
+ENTRY_BEGIN
+RAW
+b7c7018a5010441063ba0000000000000000
+ENTRY_END
+
+STEP 21370 QUERY
+ENTRY_BEGIN
+RAW
+b7c7018a5018441052a600000094f060000000010001000000000f313036353135313838393432362d320000f900010f313036353135313838393432362d320000f900ff00000000005803677373096d6963726f736f667403636f6d00403af76c403c48ec0003000000354e544c4d535350000100000097b200c00f000f002600000006000600200000004e49454c53314b52454e53434f4e53554c54414e430000
+ENTRY_END
+
+STEP 21380 QUERY
+ENTRY_BEGIN
+RAW
+b7c701985011440263230000000000000000
+ENTRY_END
+
+STEP 21390 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400010880000020405ac01010402
+ENTRY_END
+
+STEP 21400 QUERY
+ENTRY_BEGIN
+RAW
+b7c701995010440263220000000000000000
+ENTRY_END
+
+STEP 21410 QUERY
+ENTRY_BEGIN
+RAW
+b7c7ca4a50104410b7110000000000000000
+ENTRY_END
+
+STEP 21420 QUERY
+ENTRY_BEGIN
+RAW
+b7c7ca4a50184410f51900000094a144000000010001000000000f313036353135313838393432362d320000f900010f313036353135313838393432362d320000f900ff00000000005803677373096d6963726f736f667403636f6d00403af76c403c48ec0003000000354e544c4d535350000100000097b200c00f000f002600000006000600200000004e49454c53314b52454e53434f4e53554c54414e430000
+ENTRY_END
+
+STEP 21430 QUERY
+ENTRY_BEGIN
+RAW
+b7c7ca5850114402b67a0000000000000000
+ENTRY_END
+
+STEP 21440 QUERY
+ENTRY_BEGIN
+RAW
+b7c7ca5950104402b6790000000000000000
+ENTRY_END
+
+STEP 21450 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000ced600000204053401010402
+ENTRY_END
+
+STEP 21460 QUERY
+ENTRY_BEGIN
+RAW
+b7c8652e50104470d9a30000000000000000
+ENTRY_END
+
+STEP 21470 QUERY
+ENTRY_BEGIN
+RAW
+b7c8652e50184470a322000000942da6000000010001000000000f313133333837313336363136322d330000f900010f313133333837313336363136322d330000f900ff00000000005803677373096d6963726f736f667403636f6d00403b03de403c555e0003000000354e544c4d535350000100000097b208e00f000f0026000000060006002000000053455256455256414e44494a4b43534144564f43410000
+ENTRY_END
+
+STEP 21480 QUERY
+ENTRY_BEGIN
+RAW
+b7c8653c50114462d90c0000000000000000
+ENTRY_END
+
+STEP 21490 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000d21800000204053401010402
+ENTRY_END
+
+STEP 21500 QUERY
+ENTRY_BEGIN
+RAW
+b7c8653d50104462d90b0000000000000000
+ENTRY_END
+
+STEP 21510 QUERY
+ENTRY_BEGIN
+RAW
+b7cad8d15010447069400000000000000000
+ENTRY_END
+
+STEP 21520 QUERY
+ENTRY_BEGIN
+RAW
+b7cad8d150184470d679000000948aec000000010001000000000f313133333837313336363136322d320000f900010f313133333837313336363136322d320000f900ff00000000005803677373096d6963726f736f667403636f6d00403b03de403c555e0003000000354e544c4d535350000100000097b208e00f000f0026000000060006002000000053455256455256414e44494a4b43534144564f43410000
+ENTRY_END
+
+STEP 21530 QUERY
+ENTRY_BEGIN
+RAW
+b7cad8df5011446268a90000000000000000
+ENTRY_END
+
+STEP 21540 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000c1d700000204053401010402
+ENTRY_END
+
+STEP 21550 QUERY
+ENTRY_BEGIN
+RAW
+b7cad8e05010446268a80000000000000000
+ENTRY_END
+
+STEP 21560 QUERY
+ENTRY_BEGIN
+RAW
+b7cbb4fa501044707cd50000000000000000
+ENTRY_END
+
+STEP 21570 QUERY
+ENTRY_BEGIN
+RAW
+b7cbb4fa50184470aa8c00000094ca6e000000010001000000000f313133333837313336363136322d320000f900010f313133333837313336363136322d320000f900ff00000000005803677373096d6963726f736f667403636f6d00403b03de403c555e0003000000354e544c4d535350000100000097b208e00f000f0026000000060006002000000053455256455256414e44494a4b43534144564f43410000
+ENTRY_END
+
+STEP 21580 QUERY
+ENTRY_BEGIN
+RAW
+b7cbb508501144627c3e0000000000000000
+ENTRY_END
+
+STEP 21590 QUERY
+ENTRY_BEGIN
+RAW
+b7cbb509501044627c3d0000000000000000
+ENTRY_END
+
+STEP 21600 QUERY
+ENTRY_BEGIN
+RAW
+163800000001000000000000076f62646e772d6e026e6c00000f000100
+ENTRY_END
+
+STEP 21610 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000ff160000020405b401010402
+ENTRY_END
+
+STEP 21620 QUERY
+ENTRY_BEGIN
+RAW
+b7cebe2650104470b1650000000000000000
+ENTRY_END
+
+STEP 21630 QUERY
+ENTRY_BEGIN
+RAW
+b7cebe2650184470d07c0000008c6780000000010001000000000f313039393531313632373739342d330000f900010f313039393531313632373739342d330000f900ff00000000005003677373096d6963726f736f667403636f6d00403afc34403c4db400030000002d4e544c4d535350000100000097b200c0070007002600000006000600200000005345525645524d4b424144414d0000
+ENTRY_END
+
+STEP 21640 QUERY
+ENTRY_BEGIN
+RAW
+b7cebe3450114462b0d60000000000000000
+ENTRY_END
+
+STEP 21650 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000734a0000020405b401010402
+ENTRY_END
+
+STEP 21660 QUERY
+ENTRY_BEGIN
+RAW
+b7cebe3550104462b0d50000000000000000
+ENTRY_END
+
+STEP 21670 QUERY
+ENTRY_BEGIN
+RAW
+b7cf52485010447091760000000000000000
+ENTRY_END
+
+STEP 21680 QUERY
+ENTRY_BEGIN
+RAW
+b7cf524850184470b6f10000008c621d000000010001000000000f313039393531313632373739342d320000f900010f313039393531313632373739342d320000f900ff00000000005003677373096d6963726f736f667403636f6d00403afc34403c4db400030000002d4e544c4d535350000100000097b200c0070007002600000006000600200000005345525645524d4b424144414d0000
+ENTRY_END
+
+STEP 21690 QUERY
+ENTRY_BEGIN
+RAW
+3614000000010000000000000663617374656c026e6c00000f0001c00c000f0001
+ENTRY_END
+
+STEP 21700 QUERY
+ENTRY_BEGIN
+RAW
+2618000000010000000000000663617374656c026e6c00000f0001c00c000f0001
+ENTRY_END
+
+STEP 21710 QUERY
+ENTRY_BEGIN
+RAW
+3e24000000010000000000000663617374656c026e6c00000f0001c00c000f0001
+ENTRY_END
+
+STEP 21720 QUERY
+ENTRY_BEGIN
+RAW
+b7cf52565011446290e70000000000000000
+ENTRY_END
+
+STEP 21730 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400058000000020405b401010402
+ENTRY_END
+
+STEP 21740 QUERY
+ENTRY_BEGIN
+RAW
+262a000000010000000000000663617374656c026e6c00000f0001c00c000f0001
+ENTRY_END
+
+STEP 21750 QUERY
+ENTRY_BEGIN
+RAW
+3e36000000010000000000000663617374656c026e6c00000f0001c00c000f0001
+ENTRY_END
+
+STEP 21760 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400047b900000204056401010402
+ENTRY_END
+
+STEP 21770 QUERY
+ENTRY_BEGIN
+RAW
+b7cf52575010446290e60000000000000000
+ENTRY_END
+
+STEP 21780 QUERY
+ENTRY_BEGIN
+RAW
+b7d1f65650104470d21b0000000000000000
+ENTRY_END
+
+STEP 21790 QUERY
+ENTRY_BEGIN
+RAW
+3654000000010000000000000663617374656c026e6c0000010001c00c00010001
+ENTRY_END
+
+STEP 21800 QUERY
+ENTRY_BEGIN
+RAW
+b7d1f656501844703f370000008c1a7d000000010001000000000f313039393531313632373739342d320000f900010f313039393531313632373739342d320000f900ff00000000005003677373096d6963726f736f667403636f6d00403afc34403c4db400030000002d4e544c4d535350000100000097b200c0070007002600000006000600200000005345525645524d4b424144414d0000
+ENTRY_END
+
+STEP 21810 QUERY
+ENTRY_BEGIN
+RAW
+b7d27a61501040b041390000000000000000
+ENTRY_END
+
+STEP 21820 QUERY
+ENTRY_BEGIN
+RAW
+b7d1f66450114462d18c0000000000000000
+ENTRY_END
+
+STEP 21830 QUERY
+ENTRY_BEGIN
+RAW
+b7d27a61501840b0204f00000087126e000000010001000000000e3939363433323431323639302d330000f900010e3939363433323431323639302d330000f900ff00000000004d03677373096d6963726f736f667403636f6d00403afba9403c4d2900030000002a4e544c4d535350000100000097b200e003000300270000000700070020000000545249455354454243430000
+ENTRY_END
+
+STEP 21840 QUERY
+ENTRY_BEGIN
+RAW
+b7d27a6f501140a240af0000000000000000
+ENTRY_END
+
+STEP 21850 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000ddcf00000204056401010402
+ENTRY_END
+
+STEP 21860 QUERY
+ENTRY_BEGIN
+RAW
+b7d1f66550104462d18b0000000000000000
+ENTRY_END
+
+STEP 21870 QUERY
+ENTRY_BEGIN
+RAW
+b7d37167501040b0e0480000000000000000
+ENTRY_END
+
+STEP 21880 QUERY
+ENTRY_BEGIN
+RAW
+b7d27a70501040a240ae0000000000000000
+ENTRY_END
+
+STEP 21890 QUERY
+ENTRY_BEGIN
+RAW
+b7d37167501840b09f7f00000087344d000000010001000000000e3939363433323431323639302d320000f900010e3939363433323431323639302d320000f900ff00000000004d03677373096d6963726f736f667403636f6d00403afba9403c4d2900030000002a4e544c4d535350000100000097b200e003000300270000000700070020000000545249455354454243430000
+ENTRY_END
+
+STEP 21900 QUERY
+ENTRY_BEGIN
+RAW
+b7d37175501140a2dfbe0000000000000000
+ENTRY_END
+
+STEP 21910 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000d32800000204056401010402
+ENTRY_END
+
+STEP 21920 QUERY
+ENTRY_BEGIN
+RAW
+b7d37176501040a2dfbd0000000000000000
+ENTRY_END
+
+STEP 21930 QUERY
+ENTRY_BEGIN
+RAW
+b7d40c73501040b03a950000000000000000
+ENTRY_END
+
+STEP 21940 QUERY
+ENTRY_BEGIN
+RAW
+b7d40c73501840b0d7ec00000087562c000000010001000000000e3939363433323431323639302d320000f900010e3939363433323431323639302d320000f900ff00000000004d03677373096d6963726f736f667403636f6d00403afba9403c4d2900030000002a4e544c4d535350000100000097b200e003000300270000000700070020000000545249455354454243430000
+ENTRY_END
+
+STEP 21950 QUERY
+ENTRY_BEGIN
+RAW
+b7d40c81501140a23a0b0000000000000000
+ENTRY_END
+
+STEP 21960 QUERY
+ENTRY_BEGIN
+RAW
+b7d40c82501040a23a0a0000000000000000
+ENTRY_END
+
+STEP 21970 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000e2920000020405b401010402
+ENTRY_END
+
+STEP 21980 QUERY
+ENTRY_BEGIN
+RAW
+b7d4ac7950104470a6880000000000000000
+ENTRY_END
+
+STEP 21990 QUERY
+ENTRY_BEGIN
+RAW
+b7d4ac79501844709f9c0000008a49f8000000010001000000000e3839333335333139373538362d330000f900010e3839333335333139373538362d330000f900ff00000000005003677373096d6963726f736f667403636f6d00403afac0403c4c4000030000002d4e544c4d535350000100000097b200e0060006002700000007000700200000004c4150544f50315a50444550330000
+ENTRY_END
+
+STEP 22000 QUERY
+ENTRY_BEGIN
+RAW
+b7d4ac8750114462a5fb0000000000000000
+ENTRY_END
+
+STEP 22010 QUERY
+ENTRY_BEGIN
+RAW
+b7d4ac8850104462a5fa0000000000000000
+ENTRY_END
+
+STEP 22020 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000e45c0000020405b401010402
+ENTRY_END
+
+STEP 22030 QUERY
+ENTRY_BEGIN
+RAW
+b7d5987150104470bc590000000000000000
+ENTRY_END
+
+STEP 22040 QUERY
+ENTRY_BEGIN
+RAW
+b7d598715018447072e10000008a8e84000000010001000000000e3839333335333139373538362d320000f900010e3839333335333139373538362d320000f900ff00000000005003677373096d6963726f736f667403636f6d00403afac0403c4c4000030000002d4e544c4d535350000100000097b200e0060006002700000007000700200000004c4150544f50315a50444550330000
+ENTRY_END
+
+STEP 22050 QUERY
+ENTRY_BEGIN
+RAW
+b7d5987f50114462bbcc0000000000000000
+ENTRY_END
+
+STEP 22060 QUERY
+ENTRY_BEGIN
+RAW
+b7d5988050104462bbcb0000000000000000
+ENTRY_END
+
+STEP 22070 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000630d0000020405b401010402
+ENTRY_END
+
+STEP 22080 QUERY
+ENTRY_BEGIN
+RAW
+b7d7d13f50104470023a0000000000000000
+ENTRY_END
+
+STEP 22090 QUERY
+ENTRY_BEGIN
+RAW
+b7d7d13f50184470f3c90000008a537c000000010001000000000e3839333335333139373538362d320000f900010e3839333335333139373538362d320000f900ff00000000005003677373096d6963726f736f667403636f6d00403afac0403c4c4000030000002d4e544c4d535350000100000097b200e0060006002700000007000700200000004c4150544f50315a50444550330000
+ENTRY_END
+
+STEP 22100 QUERY
+ENTRY_BEGIN
+RAW
+b7d7d14d5011446201ad0000000000000000
+ENTRY_END
+
+STEP 22110 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400068980000020405b401010402
+ENTRY_END
+
+STEP 22120 QUERY
+ENTRY_BEGIN
+RAW
+b7d9fb5b50104470dda60000000000000000
+ENTRY_END
+
+STEP 22130 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf005e600000204057a01010402
+ENTRY_END
+
+STEP 22140 QUERY
+ENTRY_BEGIN
+RAW
+b7d9fb5b501844704b8a0000008f928b000000010001000000000f313133333837313336363136322d330000f900010f313133333837313336363136322d330000f900ff00000000005303677373096d6963726f736f667403636f6d00403afead403c502d0003000000304e544c4d535350000100000097b208e009000900270000000700070020000000425241564f31314a4a432d425241564f0000
+ENTRY_END
+
+STEP 22150 QUERY
+ENTRY_BEGIN
+RAW
+b7dae9b25010fbec8fd60000000000000000
+ENTRY_END
+
+STEP 22160 QUERY
+ENTRY_BEGIN
+RAW
+b7d9fb6950114462dd140000000000000000
+ENTRY_END
+
+STEP 22170 QUERY
+ENTRY_BEGIN
+RAW
+b7dae9b25018fbec4c120000008f6809000000010001000000000f313033303739323135313035382d330000f900010f313033303739323135313035382d330000f900ff00000000005303677373096d6963726f736f667403636f6d00403b072a403c58aa0003000000304e544c4d535350000100000097b208e00900090027000000070007002000000057494e3230303047494f504e54444f4d0000
+ENTRY_END
+
+STEP 22180 QUERY
+ENTRY_BEGIN
+RAW
+00000000700240006cef0000020405b401010402
+ENTRY_END
+
+STEP 22190 QUERY
+ENTRY_BEGIN
+RAW
+b7d9fb6a50104462dd130000000000000000
+ENTRY_END
+
+STEP 22200 QUERY
+ENTRY_BEGIN
+RAW
+b7dae9c05011fbde8f440000000000000000
+ENTRY_END
+
+STEP 22210 QUERY
+ENTRY_BEGIN
+RAW
+b7db85ea50104470576d0000000000000000
+ENTRY_END
+
+STEP 22220 QUERY
+ENTRY_BEGIN
+RAW
+b7db85ea501844707ce10000008fd3fb000000010001000000000f313133333837313336363136322d320000f900010f313133333837313336363136322d320000f900ff00000000005303677373096d6963726f736f667403636f6d00403afeb1403c50310003000000304e544c4d535350000100000097b208e009000900270000000700070020000000425241564f31314a4a432d425241564f0000
+ENTRY_END
+
+STEP 22230 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf0b33800000204057a01010402
+ENTRY_END
+
+STEP 22240 QUERY
+ENTRY_BEGIN
+RAW
+b7dae9c15010fbde8f430000000000000000
+ENTRY_END
+
+STEP 22250 QUERY
+ENTRY_BEGIN
+RAW
+b7dc2ffb5010fbecf6de0000000000000000
+ENTRY_END
+
+STEP 22260 QUERY
+ENTRY_BEGIN
+RAW
+b7db85f85011446256db0000000000000000
+ENTRY_END
+
+STEP 22270 QUERY
+ENTRY_BEGIN
+RAW
+b7dc2ffb5018fbeccd910000008f4e93000000010001000000000f313033303739323135313035382d320000f900010f313033303739323135313035382d320000f900ff00000000005303677373096d6963726f736f667403636f6d00403b072a403c58aa0003000000304e544c4d535350000100000097b208e00900090027000000070007002000000057494e3230303047494f504e54444f4d0000
+ENTRY_END
+
+STEP 22280 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400060bf0000020405b401010402
+ENTRY_END
+
+STEP 22290 QUERY
+ENTRY_BEGIN
+RAW
+b7dc30095011fbdef64c0000000000000000
+ENTRY_END
+
+STEP 22300 QUERY
+ENTRY_BEGIN
+RAW
+b7db85f95010446256da0000000000000000
+ENTRY_END
+
+STEP 22310 QUERY
+ENTRY_BEGIN
+RAW
+b7dcf17a50104470dfab0000000000000000
+ENTRY_END
+
+STEP 22320 QUERY
+ENTRY_BEGIN
+RAW
+b7dcf17a501844707aa10000008f5e7a000000010001000000000f313133333837313336363136322d320000f900010f313133333837313336363136322d320000f900ff00000000005303677373096d6963726f736f667403636f6d00403afeb1403c50310003000000304e544c4d535350000100000097b208e009000900270000000700070020000000425241564f31314a4a432d425241564f0000
+ENTRY_END
+
+STEP 22330 QUERY
+ENTRY_BEGIN
+RAW
+b7dcf18850114462df190000000000000000
+ENTRY_END
+
+STEP 22340 QUERY
+ENTRY_BEGIN
+RAW
+b7dcf18950104462df180000000000000000
+ENTRY_END
+
+STEP 22350 QUERY
+ENTRY_BEGIN
+RAW
+b7dc300a5010fbdef64b0000000000000000
+ENTRY_END
+
+STEP 22360 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf0f7bc00000204057a01010402
+ENTRY_END
+
+STEP 22370 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000d1bd00000204058201010402
+ENTRY_END
+
+STEP 22380 QUERY
+ENTRY_BEGIN
+RAW
+b7ddead25010fbec808a0000000000000000
+ENTRY_END
+
+STEP 22390 QUERY
+ENTRY_BEGIN
+RAW
+b7ddead25018fbec70b30000008f351d000000010001000000000f313033303739323135313035382d320000f900010f313033303739323135313035382d320000f900ff00000000005303677373096d6963726f736f667403636f6d00403b072a403c58aa0003000000304e544c4d535350000100000097b208e00900090027000000070007002000000057494e3230303047494f504e54444f4d0000
+ENTRY_END
+
+STEP 22400 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400063600000020405b401010402
+ENTRY_END
+
+STEP 22410 QUERY
+ENTRY_BEGIN
+RAW
+b7de811e50104218c32a0000000000000000
+ENTRY_END
+
+STEP 22420 QUERY
+ENTRY_BEGIN
+RAW
+b7de811e50184218042a0000008bafdf000000010001000000000f313138353431303937333731342d330000f900010f313138353431303937333731342d330000f900ff00000000004f03677373096d6963726f736f667403636f6d00403afdf7403c4f7700030000002c4e544c4d535350000100000097b200c006000600260000000600060020000000534552564552524f4d4d454c0000
+ENTRY_END
+
+STEP 22430 QUERY
+ENTRY_BEGIN
+RAW
+b7ddeae05011fbde7ff80000000000000000
+ENTRY_END
+
+STEP 22440 QUERY
+ENTRY_BEGIN
+RAW
+b7de812c5011420ac29c0000000000000000
+ENTRY_END
+
+STEP 22450 QUERY
+ENTRY_BEGIN
+RAW
+00000000700240001a6800000204058201010402
+ENTRY_END
+
+STEP 22460 QUERY
+ENTRY_BEGIN
+RAW
+b7df5ab25010447079120000000000000000
+ENTRY_END
+
+STEP 22470 QUERY
+ENTRY_BEGIN
+RAW
+b7df5ab2501844709b1b0000008fd665000000010001000000000f313133333837313336363136322d330000f900010f313133333837313336363136322d330000f900ff00000000005303677373096d6963726f736f667403636f6d00403afeb1403c50310003000000304e544c4d535350000100000097b208e009000900270000000700070020000000425241564f31314a4a432d425241564f0000
+ENTRY_END
+
+STEP 22480 QUERY
+ENTRY_BEGIN
+RAW
+b7de812d5010420ac29b0000000000000000
+ENTRY_END
+
+STEP 22490 QUERY
+ENTRY_BEGIN
+RAW
+b7e193f550104218f8fa0000000000000000
+ENTRY_END
+
+STEP 22500 QUERY
+ENTRY_BEGIN
+RAW
+b7e193f55018421846bf0000008ba41b000000010001000000000f313138353431303937333731342d320000f900010f313138353431303937333731342d320000f900ff00000000004f03677373096d6963726f736f667403636f6d00403afdf7403c4f7700030000002c4e544c4d535350000100000097b200c006000600260000000600060020000000534552564552524f4d4d454c0000
+ENTRY_END
+
+STEP 22510 QUERY
+ENTRY_BEGIN
+RAW
+b7ddeae15010fbde7ff70000000000000000
+ENTRY_END
+
+STEP 22520 QUERY
+ENTRY_BEGIN
+RAW
+b7e194035011420af86c0000000000000000
+ENTRY_END
+
+STEP 22530 QUERY
+ENTRY_BEGIN
+RAW
+b7df5ac05011446278800000000000000000
+ENTRY_END
+
+STEP 22540 QUERY
+ENTRY_BEGIN
+RAW
+00000000700240000f3900000204058201010402
+ENTRY_END
+
+STEP 22550 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400079d00000020405b401010402
+ENTRY_END
+
+STEP 22560 QUERY
+ENTRY_BEGIN
+RAW
+b7e194045010420af86b0000000000000000
+ENTRY_END
+
+STEP 22570 QUERY
+ENTRY_BEGIN
+RAW
+b7e2188c5010421869340000000000000000
+ENTRY_END
+
+STEP 22580 QUERY
+ENTRY_BEGIN
+RAW
+b7df5ac150104462787f0000000000000000
+ENTRY_END
+
+STEP 22590 QUERY
+ENTRY_BEGIN
+RAW
+b7e2188c501842183cdb0000008b1e39000000010001000000000f313138353431303937333731342d320000f900010f313138353431303937333731342d320000f900ff00000000004f03677373096d6963726f736f667403636f6d00403afdf7403c4f7700030000002c4e544c4d535350000100000097b200c006000600260000000600060020000000534552564552524f4d4d454c0000
+ENTRY_END
+
+STEP 22600 QUERY
+ENTRY_BEGIN
+RAW
+b7e304b250104470e57e0000000000000000
+ENTRY_END
+
+STEP 22610 QUERY
+ENTRY_BEGIN
+RAW
+b7e304b25018447021fa0000008fbcf4000000010001000000000f313133333837313336363136322d320000f900010f313133333837313336363136322d320000f900ff00000000005303677373096d6963726f736f667403636f6d00403afeb1403c50310003000000304e544c4d535350000100000097b208e009000900270000000700070020000000425241564f31314a4a432d425241564f0000
+ENTRY_END
+
+STEP 22620 QUERY
+ENTRY_BEGIN
+RAW
+b7e2189a5011420a68a60000000000000000
+ENTRY_END
+
+STEP 22630 QUERY
+ENTRY_BEGIN
+RAW
+b7e304c050114462e4ec0000000000000000
+ENTRY_END
+
+STEP 22640 QUERY
+ENTRY_BEGIN
+RAW
+b7e2189b5010420a68a50000000000000000
+ENTRY_END
+
+STEP 22650 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400091100000020405b401010402
+ENTRY_END
+
+STEP 22660 QUERY
+ENTRY_BEGIN
+RAW
+b7e304c150104462e4eb0000000000000000
+ENTRY_END
+
+STEP 22670 QUERY
+ENTRY_BEGIN
+RAW
+b7e3c233501044703f3d0000000000000000
+ENTRY_END
+
+STEP 22680 QUERY
+ENTRY_BEGIN
+RAW
+b7e3c23350184470d6fa0000008f61b2000000010001000000000f313133333837313336363136322d320000f900010f313133333837313336363136322d320000f900ff00000000005303677373096d6963726f736f667403636f6d00403afeb1403c50310003000000304e544c4d535350000100000097b208e009000900270000000700070020000000425241564f31314a4a432d425241564f0000
+ENTRY_END
+
+STEP 22690 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000bdff00000204058201010402
+ENTRY_END
+
+STEP 22700 QUERY
+ENTRY_BEGIN
+RAW
+b7e3c241501144623eab0000000000000000
+ENTRY_END
+
+STEP 22710 QUERY
+ENTRY_BEGIN
+RAW
+b7e443e550104218ec9f0000000000000000
+ENTRY_END
+
+STEP 22720 QUERY
+ENTRY_BEGIN
+RAW
+b7e443e550184218d6cd0000008b06b1000000010001000000000f313138353431303937333731342d330000f900010f313138353431303937333731342d330000f900ff00000000004f03677373096d6963726f736f667403636f6d00403afdf7403c4f7700030000002c4e544c4d535350000100000097b200c006000600260000000600060020000000534552564552524f4d4d454c0000
+ENTRY_END
+
+STEP 22730 QUERY
+ENTRY_BEGIN
+RAW
+b7e443f35011420aec110000000000000000
+ENTRY_END
+
+STEP 22740 QUERY
+ENTRY_BEGIN
+RAW
+b7e3c242501044623eaa0000000000000000
+ENTRY_END
+
+STEP 22750 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000d9ff00000204058201010402
+ENTRY_END
+
+STEP 22760 QUERY
+ENTRY_BEGIN
+RAW
+b7e443f45010420aec100000000000000000
+ENTRY_END
+
+STEP 22770 QUERY
+ENTRY_BEGIN
+RAW
+b7e5104a501042183c3a0000000000000000
+ENTRY_END
+
+STEP 22780 QUERY
+ENTRY_BEGIN
+RAW
+b7e5104a501842182f400000008bfed9000000010001000000000f313138353431303937333731342d320000f900010f313138353431303937333731342d320000f900ff00000000004f03677373096d6963726f736f667403636f6d00403afdf7403c4f7700030000002c4e544c4d535350000100000097b200c006000600260000000600060020000000534552564552524f4d4d454c0000
+ENTRY_END
+
+STEP 22790 QUERY
+ENTRY_BEGIN
+RAW
+b7e510585011420a3bac0000000000000000
+ENTRY_END
+
+STEP 22800 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000818300000204058201010402
+ENTRY_END
+
+STEP 22810 QUERY
+ENTRY_BEGIN
+RAW
+b7e510595010420a3bab0000000000000000
+ENTRY_END
+
+STEP 22820 QUERY
+ENTRY_BEGIN
+RAW
+b7e5f01a5010421803ed0000000000000000
+ENTRY_END
+
+STEP 22830 QUERY
+ENTRY_BEGIN
+RAW
+b7e5f01a5018421838b30000008bbb19000000010001000000000f313138353431303937333731342d320000f900010f313138353431303937333731342d320000f900ff00000000004f03677373096d6963726f736f667403636f6d00403afdf8403c4f7800030000002c4e544c4d535350000100000097b200c006000600260000000600060020000000534552564552524f4d4d454c0000
+ENTRY_END
+
+STEP 22840 QUERY
+ENTRY_BEGIN
+RAW
+b7e5f0285011420a035f0000000000000000
+ENTRY_END
+
+STEP 22850 QUERY
+ENTRY_BEGIN
+RAW
+b7e5f0295010420a035e0000000000000000
+ENTRY_END
+
+STEP 22860 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400094360000020405b401010402
+ENTRY_END
+
+STEP 22870 QUERY
+ENTRY_BEGIN
+RAW
+b7e6be1850104470467b0000000000000000
+ENTRY_END
+
+STEP 22880 QUERY
+ENTRY_BEGIN
+RAW
+00000000700240007ffe00000204058201010402
+ENTRY_END
+
+STEP 22890 QUERY
+ENTRY_BEGIN
+RAW
+b7e7a1a25010421850de0000000000000000
+ENTRY_END
+
+STEP 22900 QUERY
+ENTRY_BEGIN
+RAW
+b7e7a1a2501842181a360000008b2587000000010001000000000f313138353431303937333731342d330000f900010f313138353431303937333731342d330000f900ff00000000004f03677373096d6963726f736f667403636f6d00403afdf8403c4f7800030000002c4e544c4d535350000100000097b200c006000600260000000600060020000000534552564552524f4d4d454c0000
+ENTRY_END
+
+STEP 22910 QUERY
+ENTRY_BEGIN
+RAW
+b7e6be185018447063d90000008c6106000000010001000000000f313133333837313336363136322d330000f900010f313133333837313336363136322d330000f900ff00000000005003677373096d6963726f736f667403636f6d00403afd19403c4e9900030000002d4e544c4d535350000100000097b208e007000700260000000600060020000000574e54504d4d574e545f504d4d0000
+ENTRY_END
+
+STEP 22920 QUERY
+ENTRY_BEGIN
+RAW
+b7e7a1b05011420a50500000000000000000
+ENTRY_END
+
+STEP 22930 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000d0c800000204058201010402
+ENTRY_END
+
+STEP 22940 QUERY
+ENTRY_BEGIN
+RAW
+b7e6be265011446245ec0000000000000000
+ENTRY_END
+
+STEP 22950 QUERY
+ENTRY_BEGIN
+RAW
+b7e7a1b15010420a504f0000000000000000
+ENTRY_END
+
+STEP 22960 QUERY
+ENTRY_BEGIN
+RAW
+b7e8222b50104218211f0000000000000000
+ENTRY_END
+
+STEP 22970 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000a6450000020405b401010402
+ENTRY_END
+
+STEP 22980 QUERY
+ENTRY_BEGIN
+RAW
+b7e8222b50184218f34f0000008b1daf000000010001000000000f313138353431303937333731342d320000f900010f313138353431303937333731342d320000f900ff00000000004f03677373096d6963726f736f667403636f6d00403afdf8403c4f7800030000002c4e544c4d535350000100000097b200c006000600260000000600060020000000534552564552524f4d4d454c0000
+ENTRY_END
+
+STEP 22990 QUERY
+ENTRY_BEGIN
+RAW
+b7e822395011420a20910000000000000000
+ENTRY_END
+
+STEP 23000 QUERY
+ENTRY_BEGIN
+RAW
+b7e6be275010446245eb0000000000000000
+ENTRY_END
+
+STEP 23010 QUERY
+ENTRY_BEGIN
+RAW
+b7e8b9fe501044705ca20000000000000000
+ENTRY_END
+
+STEP 23020 QUERY
+ENTRY_BEGIN
+RAW
+00000000700240008ecb00000204058201010402
+ENTRY_END
+
+STEP 23030 QUERY
+ENTRY_BEGIN
+RAW
+b7e8223a5010420a20900000000000000000
+ENTRY_END
+
+STEP 23040 QUERY
+ENTRY_BEGIN
+RAW
+b7e96bb55010421895960000000000000000
+ENTRY_END
+
+STEP 23050 QUERY
+ENTRY_BEGIN
+RAW
+b7e8b9fe50184470c0470000008c1bc0000000010001000000000f313133333837313336363136322d320000f900010f313133333837313336363136322d320000f900ff00000000005003677373096d6963726f736f667403636f6d00403afd19403c4e9900030000002d4e544c4d535350000100000097b208e007000700260000000600060020000000574e54504d4d574e545f504d4d0000
+ENTRY_END
+
+STEP 23060 QUERY
+ENTRY_BEGIN
+RAW
+b7e96bb5501842187c9e0000008b08d8000000010001000000000f313138353431303937333731342d320000f900010f313138353431303937333731342d320000f900ff00000000004f03677373096d6963726f736f667403636f6d00403afdf8403c4f7800030000002c4e544c4d535350000100000097b200c006000600260000000600060020000000534552564552524f4d4d454c0000
+ENTRY_END
+
+STEP 23070 QUERY
+ENTRY_BEGIN
+RAW
+b7e96bc35011420a95080000000000000000
+ENTRY_END
+
+STEP 23080 QUERY
+ENTRY_BEGIN
+RAW
+b7e96bc45010420a95070000000000000000
+ENTRY_END
+
+STEP 23090 QUERY
+ENTRY_BEGIN
+RAW
+b7e8ba0c501144625c130000000000000000
+ENTRY_END
+
+STEP 23100 QUERY
+ENTRY_BEGIN
+RAW
+63097b1c50040000f11a0000000000000000
+ENTRY_END
+
+STEP 23110 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000ec7e0000020405b401010402
+ENTRY_END
+
+STEP 23120 QUERY
+ENTRY_BEGIN
+RAW
+b7e8ba0d501044625c120000000000000000
+ENTRY_END
+
+STEP 23130 QUERY
+ENTRY_BEGIN
+RAW
+b7ec28565010447034800000000000000000
+ENTRY_END
+
+STEP 23140 QUERY
+ENTRY_BEGIN
+RAW
+b7ec285650184470d6a40000008cdd40000000010001000000000f313133333837313336363136322d320000f900010f313133333837313336363136322d320000f900ff00000000005003677373096d6963726f736f667403636f6d00403afd19403c4e9900030000002d4e544c4d535350000100000097b208e007000700260000000600060020000000574e54504d4d574e545f504d4d0000
+ENTRY_END
+
+STEP 23150 QUERY
+ENTRY_BEGIN
+RAW
+b7ec28645011446233f10000000000000000
+ENTRY_END
+
+STEP 23160 QUERY
+ENTRY_BEGIN
+RAW
+b7ec28655010446233f00000000000000000
+ENTRY_END
+
+STEP 23170 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf0032000000204056401010402
+ENTRY_END
+
+STEP 23180 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf043bb0000020405b401010402
+ENTRY_END
+
+STEP 23190 QUERY
+ENTRY_BEGIN
+RAW
+b7eca26f5010fd5cd2bb0000000000000000
+ENTRY_END
+
+STEP 23200 QUERY
+ENTRY_BEGIN
+RAW
+b7eca26f5018fd5c445900000092c3e6000000010001000000000f313138353431303937333731342d330000f900010f313138353431303937333731342d330000f900ff00000000005603677373096d6963726f736f667403636f6d00403afe5d403c4fdd0003000000334e544c4d535350000100000097b208e0090009002a0000000a000a00200000005044435347524156454e4f425347524156454e0000
+ENTRY_END
+
+STEP 23210 QUERY
+ENTRY_BEGIN
+RAW
+b7eca27d5011fd4ed2260000000000000000
+ENTRY_END
+
+STEP 23220 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf00b5800000204056401010402
+ENTRY_END
+
+STEP 23230 QUERY
+ENTRY_BEGIN
+RAW
+b7eca27e5010fd4ed2250000000000000000
+ENTRY_END
+
+STEP 23240 QUERY
+ENTRY_BEGIN
+RAW
+b7ee6dad5010fd5c0fb40000000000000000
+ENTRY_END
+
+STEP 23250 QUERY
+ENTRY_BEGIN
+RAW
+b7ee6dad5018fd5c0976000000923cc3000000010001000000000f313138353431303937333731342d320000f900010f313138353431303937333731342d320000f900ff00000000005603677373096d6963726f736f667403636f6d00403afe5d403c4fdd0003000000334e544c4d535350000100000097b208e0090009002a0000000a000a00200000005044435347524156454e4f425347524156454e0000
+ENTRY_END
+
+STEP 23260 QUERY
+ENTRY_BEGIN
+RAW
+b7ee6dbb5011fd4e0f1f0000000000000000
+ENTRY_END
+
+STEP 23270 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf0682600000204056401010402
+ENTRY_END
+
+STEP 23280 QUERY
+ENTRY_BEGIN
+RAW
+b7ee6dbc5010fd4e0f1e0000000000000000
+ENTRY_END
+
+STEP 23290 QUERY
+ENTRY_BEGIN
+RAW
+b7ef54e85010fd5c85460000000000000000
+ENTRY_END
+
+STEP 23300 QUERY
+ENTRY_BEGIN
+RAW
+b7ef54e85018fd5c2cde000000928ced000000010001000000000f313138353431303937333731342d320000f900010f313138353431303937333731342d320000f900ff00000000005603677373096d6963726f736f667403636f6d00403afe5e403c4fde0003000000334e544c4d535350000100000097b208e0090009002a0000000a000a00200000005044435347524156454e4f425347524156454e0000
+ENTRY_END
+
+STEP 23310 QUERY
+ENTRY_BEGIN
+RAW
+b7ef54f65011fd4e84b10000000000000000
+ENTRY_END
+
+STEP 23320 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000bd400000020405b401010402
+ENTRY_END
+
+STEP 23330 QUERY
+ENTRY_BEGIN
+RAW
+b7ef54f75010fd4e84b00000000000000000
+ENTRY_END
+
+STEP 23340 QUERY
+ENTRY_BEGIN
+RAW
+b7f00ee7501044701ead0000000000000000
+ENTRY_END
+
+STEP 23350 QUERY
+ENTRY_BEGIN
+RAW
+b7f00ee7501844705c81000000910c00000000010001000000000f313034373937323032303234322d330000f900010f313034373937323032303234322d330000f900ff00000000005503677373096d6963726f736f667403636f6d00403afd47403c4ec70003000000324e544c4d535350000100000097b208e00b000b00270000000700070020000000495345525645524b5356494e5445524e45540000
+ENTRY_END
+
+STEP 23360 QUERY
+ENTRY_BEGIN
+RAW
+2e4000000001000000000000076f62646e772d6e026e6c00000f000100
+ENTRY_END
+
+STEP 23370 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf020de00000204056401010402
+ENTRY_END
+
+STEP 23380 QUERY
+ENTRY_BEGIN
+RAW
+b7f00ef5501144621e190000000000000000
+ENTRY_END
+
+STEP 23390 QUERY
+ENTRY_BEGIN
+RAW
+b7f0ad405010fd5ce5a40000000000000000
+ENTRY_END
+
+STEP 23400 QUERY
+ENTRY_BEGIN
+RAW
+b7f0ad405018fd5ca524000000927404000000010001000000000f313138353431303937333731342d330000f900010f313138353431303937333731342d330000f900ff00000000005603677373096d6963726f736f667403636f6d00403afe5e403c4fde0003000000334e544c4d535350000100000097b208e0090009002a0000000a000a00200000005044435347524156454e4f425347524156454e0000
+ENTRY_END
+
+STEP 23410 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400096fb0000020405b401010402
+ENTRY_END
+
+STEP 23420 QUERY
+ENTRY_BEGIN
+RAW
+b7f00ef6501044621e180000000000000000
+ENTRY_END
+
+STEP 23430 QUERY
+ENTRY_BEGIN
+RAW
+b7f0ad4e5011fd4ee50f0000000000000000
+ENTRY_END
+
+STEP 23440 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf0f72200000204056401010402
+ENTRY_END
+
+STEP 23450 QUERY
+ENTRY_BEGIN
+RAW
+b7f1a62250104470612b0000000000000000
+ENTRY_END
+
+STEP 23460 QUERY
+ENTRY_BEGIN
+RAW
+b7f0ad4f5010fd4ee50e0000000000000000
+ENTRY_END
+
+STEP 23470 QUERY
+ENTRY_BEGIN
+RAW
+b7f1a622501844703700000000917500000000010001000000000f313034373937323032303234322d320000f900010f313034373937323032303234322d320000f900ff00000000005503677373096d6963726f736f667403636f6d00403afd47403c4ec70003000000324e544c4d535350000100000097b208e00b000b00270000000700070020000000495345525645524b5356494e5445524e45540000
+ENTRY_END
+
+STEP 23480 QUERY
+ENTRY_BEGIN
+RAW
+b7f350355010fd5c18f20000000000000000
+ENTRY_END
+
+STEP 23490 QUERY
+ENTRY_BEGIN
+RAW
+b7f350355018fd5cbfda000000928d9c000000010001000000000f313138353431303937333731342d320000f900010f313138353431303937333731342d320000f900ff00000000005603677373096d6963726f736f667403636f6d00403afe5e403c4fde0003000000334e544c4d535350000100000097b208e0090009002a0000000a000a00200000005044435347524156454e4f425347524156454e0000
+ENTRY_END
+
+STEP 23500 QUERY
+ENTRY_BEGIN
+RAW
+b7f1a6305011446260970000000000000000
+ENTRY_END
+
+STEP 23510 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000c07900000204057801010402
+ENTRY_END
+
+STEP 23520 QUERY
+ENTRY_BEGIN
+RAW
+b7f350435011fd4e185d0000000000000000
+ENTRY_END
+
+STEP 23530 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf0f5eb00000204056401010402
+ENTRY_END
+
+STEP 23540 QUERY
+ENTRY_BEGIN
+RAW
+b7f3f803501041a03b5a0000000000000000
+ENTRY_END
+
+STEP 23550 QUERY
+ENTRY_BEGIN
+RAW
+b7f3f803501841a0e3ed0000008c7123000000010001000000000f313038323333313735383631302d330000f900010f313038323333313735383631302d330000f900ff00000000005003677373096d6963726f736f667403636f6d00403b00f1403c527100030000002d4e544c4d535350000100000097b208e00700070026000000060006002000000049434441544149432d5445414d0000
+ENTRY_END
+
+STEP 23560 QUERY
+ENTRY_BEGIN
+RAW
+b7f350445010fd4e185c0000000000000000
+ENTRY_END
+
+STEP 23570 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400071960000020405b401010402
+ENTRY_END
+
+STEP 23580 QUERY
+ENTRY_BEGIN
+RAW
+b7f3f811501141923acb0000000000000000
+ENTRY_END
+
+STEP 23590 QUERY
+ENTRY_BEGIN
+RAW
+b7f4c0fc5010fd5ca6f20000000000000000
+ENTRY_END
+
+STEP 23600 QUERY
+ENTRY_BEGIN
+RAW
+b7f4c0fc5018fd5ca5cf0000009235a8000000010001000000000f313138353431303937333731342d320000f900010f313138353431303937333731342d320000f900ff00000000005603677373096d6963726f736f667403636f6d00403afe5e403c4fde0003000000334e544c4d535350000100000097b208e0090009002a0000000a000a00200000005044435347524156454e4f425347524156454e0000
+ENTRY_END
+
+STEP 23610 QUERY
+ENTRY_BEGIN
+RAW
+b7f1a6315010446260960000000000000000
+ENTRY_END
+
+STEP 23620 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400048b30000020405b401010402
+ENTRY_END
+
+STEP 23630 QUERY
+ENTRY_BEGIN
+RAW
+b7f580c05010447061240000000000000000
+ENTRY_END
+
+STEP 23640 QUERY
+ENTRY_BEGIN
+RAW
+b7f3f812501041923aca0000000000000000
+ENTRY_END
+
+STEP 23650 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000833b00000204057801010402
+ENTRY_END
+
+STEP 23660 QUERY
+ENTRY_BEGIN
+RAW
+b7f580c050184470c704000000916300000000010001000000000f313133333837313336363136322d330000f900010f313133333837313336363136322d330000f900ff00000000005503677373096d6963726f736f667403636f6d00403afafd403c4c7d0003000000324e544c4d535350000100000097b200e00c000c0026000000060006002000000053455256455253544546465953574f524c440000
+ENTRY_END
+
+STEP 23670 QUERY
+ENTRY_BEGIN
+RAW
+b7f73e35501041a0b7e60000000000000000
+ENTRY_END
+
+STEP 23680 QUERY
+ENTRY_BEGIN
+RAW
+b7f73e35501841a0aecc0000008c23d2000000010001000000000f313038323333313735383631302d320000f900010f313038323333313735383631302d320000f900ff00000000005003677373096d6963726f736f667403636f6d00403b00f1403c527100030000002d4e544c4d535350000100000097b208e00700070026000000060006002000000049434441544149432d5445414d0000
+ENTRY_END
+
+STEP 23690 QUERY
+ENTRY_BEGIN
+RAW
+b7f4c10a5011fd4ea65d0000000000000000
+ENTRY_END
+
+STEP 23700 QUERY
+ENTRY_BEGIN
+RAW
+b7f580ce5011446260900000000000000000
+ENTRY_END
+
+STEP 23710 QUERY
+ENTRY_BEGIN
+RAW
+b7f67a07501044703ef90000000000000000
+ENTRY_END
+
+STEP 23720 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000c9110000020405b401010402
+ENTRY_END
+
+STEP 23730 QUERY
+ENTRY_BEGIN
+RAW
+b7f73e4350114192b7570000000000000000
+ENTRY_END
+
+STEP 23740 QUERY
+ENTRY_BEGIN
+RAW
+b7f67a0750184470abcd00000091de00000000010001000000000f313034373937323032303234322d320000f900010f313034373937323032303234322d320000f900ff00000000005503677373096d6963726f736f667403636f6d00403afd47403c4ec70003000000324e544c4d535350000100000097b208e00b000b00270000000700070020000000495345525645524b5356494e5445524e45540000
+ENTRY_END
+
+STEP 23750 QUERY
+ENTRY_BEGIN
+RAW
+b7f580cf50104462608f0000000000000000
+ENTRY_END
+
+STEP 23760 QUERY
+ENTRY_BEGIN
+RAW
+b7f7f95250104470400b0000000000000000
+ENTRY_END
+
+STEP 23770 QUERY
+ENTRY_BEGIN
+RAW
+b7f73e4450104192b7560000000000000000
+ENTRY_END
+
+STEP 23780 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000fcc200000204057801010402
+ENTRY_END
+
+STEP 23790 QUERY
+ENTRY_BEGIN
+RAW
+b7f7f9525018447060ec00000091a900000000010001000000000f313133333837313336363136322d320000f900010f313133333837313336363136322d320000f900ff00000000005503677373096d6963726f736f667403636f6d00403afafd403c4c7d0003000000324e544c4d535350000100000097b200e00c000c0026000000060006002000000053455256455253544546465953574f524c440000
+ENTRY_END
+
+STEP 23800 QUERY
+ENTRY_BEGIN
+RAW
+b7f4c10b5010fd4ea65c0000000000000000
+ENTRY_END
+
+STEP 23810 QUERY
+ENTRY_BEGIN
+RAW
+b7f886a3501041a0e8fe0000000000000000
+ENTRY_END
+
+STEP 23820 QUERY
+ENTRY_BEGIN
+RAW
+b7f67a15501144623e650000000000000000
+ENTRY_END
+
+STEP 23830 QUERY
+ENTRY_BEGIN
+RAW
+b7f886a3501841a085450000008c7e71000000010001000000000f313038323333313735383631302d320000f900010f313038323333313735383631302d320000f900ff00000000005003677373096d6963726f736f667403636f6d00403b00f1403c527100030000002d4e544c4d535350000100000097b208e00700070026000000060006002000000049434441544149432d5445414d0000
+ENTRY_END
+
+STEP 23840 QUERY
+ENTRY_BEGIN
+RAW
+b7f7f960501144623f770000000000000000
+ENTRY_END
+
+STEP 23850 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000e70c0000020405b401010402
+ENTRY_END
+
+STEP 23860 QUERY
+ENTRY_BEGIN
+RAW
+b7f886b150114192e86f0000000000000000
+ENTRY_END
+
+STEP 23870 QUERY
+ENTRY_BEGIN
+RAW
+b7f7f961501044623f760000000000000000
+ENTRY_END
+
+STEP 23880 QUERY
+ENTRY_BEGIN
+RAW
+b7f886b250104192e86e0000000000000000
+ENTRY_END
+
+STEP 23890 QUERY
+ENTRY_BEGIN
+RAW
+b7f92d3c501044702a1b0000000000000000
+ENTRY_END
+
+STEP 23900 QUERY
+ENTRY_BEGIN
+RAW
+b7f92d3c5018447004fc00000091ef00000000010001000000000f313133333837313336363136322d320000f900010f313133333837313336363136322d320000f900ff00000000005503677373096d6963726f736f667403636f6d00403afafd403c4c7d0003000000324e544c4d535350000100000097b200e00c000c0026000000060006002000000053455256455253544546465953574f524c440000
+ENTRY_END
+
+STEP 23910 QUERY
+ENTRY_BEGIN
+RAW
+b7f67a16501044623e640000000000000000
+ENTRY_END
+
+STEP 23920 QUERY
+ENTRY_BEGIN
+RAW
+b7f92d4a5011446229870000000000000000
+ENTRY_END
+
+STEP 23930 QUERY
+ENTRY_BEGIN
+RAW
+b7f92d4b5010446229860000000000000000
+ENTRY_END
+
+STEP 23940 QUERY
+ENTRY_BEGIN
+RAW
+00000000700240001be000000204056401010402
+ENTRY_END
+
+STEP 23950 QUERY
+ENTRY_BEGIN
+RAW
+b7fa1fad501040b06fec0000000000000000
+ENTRY_END
+
+STEP 23960 QUERY
+ENTRY_BEGIN
+RAW
+b7fa1fad501840b0d4e20000008c8580000000010001000000000f313131363639313439363937382d330000f900010f313131363639313439363937382d330000f900ff00000000005003677373096d6963726f736f667403636f6d00403aff69403c50e900030000002d4e544c4d535350000100000097b200e007000700260000000600060020000000534552564552444556414552540000
+ENTRY_END
+
+STEP 23970 QUERY
+ENTRY_BEGIN
+RAW
+b7fa1fbb501140a26f5d0000000000000000
+ENTRY_END
+
+STEP 23980 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400033e800000204056401010402
+ENTRY_END
+
+STEP 23990 QUERY
+ENTRY_BEGIN
+RAW
+00000000700240008d7c0000020405b401010402
+ENTRY_END
+
+STEP 24000 QUERY
+ENTRY_BEGIN
+RAW
+00000000700240007e4f0000020405b401010402
+ENTRY_END
+
+STEP 24010 QUERY
+ENTRY_BEGIN
+RAW
+b7fbf06c501044700d580000000000000000
+ENTRY_END
+
+STEP 24020 QUERY
+ENTRY_BEGIN
+RAW
+b7fbf06c501844706038000000917600000000010001000000000f313133333837313336363136322d330000f900010f313133333837313336363136322d330000f900ff00000000005503677373096d6963726f736f667403636f6d00403afafd403c4c7d0003000000324e544c4d535350000100000097b200e00c000c0026000000060006002000000053455256455253544546465953574f524c440000
+ENTRY_END
+
+STEP 24030 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000deaa0000020405b401010402
+ENTRY_END
+
+STEP 24040 QUERY
+ENTRY_BEGIN
+RAW
+b7fa1fbc501040a26f5c0000000000000000
+ENTRY_END
+
+STEP 24050 QUERY
+ENTRY_BEGIN
+RAW
+b7faff1c501040b0a8840000000000000000
+ENTRY_END
+
+STEP 24060 QUERY
+ENTRY_BEGIN
+RAW
+b7faff1c501840b0bffb0000008cd400000000010001000000000f313131363639313439363937382d320000f900010f313131363639313439363937382d320000f900ff00000000005003677373096d6963726f736f667403636f6d00403aff69403c50e900030000002d4e544c4d535350000100000097b200e007000700260000000600060020000000534552564552444556414552540000
+ENTRY_END
+
+STEP 24070 QUERY
+ENTRY_BEGIN
+RAW
+b7fbf07a501144620cc40000000000000000
+ENTRY_END
+
+STEP 24080 QUERY
+ENTRY_BEGIN
+RAW
+b7fcabad5010447042e90000000000000000
+ENTRY_END
+
+STEP 24090 QUERY
+ENTRY_BEGIN
+RAW
+b7fd5e2d50104470f0c30000000000000000
+ENTRY_END
+
+STEP 24100 QUERY
+ENTRY_BEGIN
+RAW
+b7fcabad50184470e1cf000000940d40000000010001000000000f313036353135313838393432362d330000f900010f313036353135313838393432362d330000f900ff00000000005803677373096d6963726f736f667403636f6d00403afd77403c4ef70003000000354e544c4d535350000100000097b200c00f000f00260000000600060020000000534552564552444f5649414e55534b414e544f4f520000
+ENTRY_END
+
+STEP 24110 QUERY
+ENTRY_BEGIN
+RAW
+b7fd5e2d50184470679700000091d300000000010001000000000f313034373937323032303234322d330000f900010f313034373937323032303234322d330000f900ff00000000005503677373096d6963726f736f667403636f6d00403afd47403c4ec70003000000324e544c4d535350000100000097b208e00b000b00270000000700070020000000495345525645524b5356494e5445524e45540000
+ENTRY_END
+
+STEP 24120 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400001a90000020405b401010402
+ENTRY_END
+
+STEP 24130 QUERY
+ENTRY_BEGIN
+RAW
+b7faff2a501140a2a7f50000000000000000
+ENTRY_END
+
+STEP 24140 QUERY
+ENTRY_BEGIN
+RAW
+b7fbf07b501044620cc30000000000000000
+ENTRY_END
+
+STEP 24150 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000d5fd00000204056401010402
+ENTRY_END
+
+STEP 24160 QUERY
+ENTRY_BEGIN
+RAW
+b7fddb875010447096670000000000000000
+ENTRY_END
+
+STEP 24170 QUERY
+ENTRY_BEGIN
+RAW
+b7fddb8750184470a44800000091bc00000000010001000000000f313133333837313336363136322d320000f900010f313133333837313336363136322d320000f900ff00000000005503677373096d6963726f736f667403636f6d00403afafd403c4c7d0003000000324e544c4d535350000100000097b200e00c000c0026000000060006002000000053455256455253544546465953574f524c440000
+ENTRY_END
+
+STEP 24180 QUERY
+ENTRY_BEGIN
+RAW
+b7fcabbb5011446242520000000000000000
+ENTRY_END
+
+STEP 24190 QUERY
+ENTRY_BEGIN
+RAW
+b7faff2b501040a2a7f40000000000000000
+ENTRY_END
+
+STEP 24200 QUERY
+ENTRY_BEGIN
+RAW
+00000000700240005a9d0000020405b401010402
+ENTRY_END
+
+STEP 24210 QUERY
+ENTRY_BEGIN
+RAW
+b7fe9a2d501040b0af850000000000000000
+ENTRY_END
+
+STEP 24220 QUERY
+ENTRY_BEGIN
+RAW
+b7fddb955011446295d30000000000000000
+ENTRY_END
+
+STEP 24230 QUERY
+ENTRY_BEGIN
+RAW
+b7fe9a2d501840b0787d0000008c2280000000010001000000000f313131363639313439363937382d320000f900010f313131363639313439363937382d320000f900ff00000000005003677373096d6963726f736f667403636f6d00403aff69403c50e900030000002d4e544c4d535350000100000097b200e007000700260000000600060020000000534552564552444556414552540000
+ENTRY_END
+
+STEP 24240 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000c2190000020405b401010402
+ENTRY_END
+
+STEP 24250 QUERY
+ENTRY_BEGIN
+RAW
+b7fcabbc5010446242510000000000000000
+ENTRY_END
+
+STEP 24260 QUERY
+ENTRY_BEGIN
+RAW
+b7ff23a450104470a73d0000000000000000
+ENTRY_END
+
+STEP 24270 QUERY
+ENTRY_BEGIN
+RAW
+b7fddb965010446295d20000000000000000
+ENTRY_END
+
+STEP 24280 QUERY
+ENTRY_BEGIN
+RAW
+b7fe9a3b501140a2aef60000000000000000
+ENTRY_END
+
+STEP 24290 QUERY
+ENTRY_BEGIN
+RAW
+b7ff23a45018447075a400000094dcc0000000010001000000000f313036353135313838393432362d320000f900010f313036353135313838393432362d320000f900ff00000000005803677373096d6963726f736f667403636f6d00403afd78403c4ef80003000000354e544c4d535350000100000097b200c00f000f00260000000600060020000000534552564552444f5649414e55534b414e544f4f520000
+ENTRY_END
+
+STEP 24300 QUERY
+ENTRY_BEGIN
+RAW
+b7fd5e3b50114462f02f0000000000000000
+ENTRY_END
+
+STEP 24310 QUERY
+ENTRY_BEGIN
+RAW
+b7fff478501044703de50000000000000000
+ENTRY_END
+
+STEP 24320 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000ab080000020405b401010402
+ENTRY_END
+
+STEP 24330 QUERY
+ENTRY_BEGIN
+RAW
+b7fff4785018447043c600000091c400000000010001000000000f313133333837313336363136322d320000f900010f313133333837313336363136322d320000f900ff00000000005503677373096d6963726f736f667403636f6d00403afafd403c4c7d0003000000324e544c4d535350000100000097b200e00c000c0026000000060006002000000053455256455253544546465953574f524c440000
+ENTRY_END
+
+STEP 24340 QUERY
+ENTRY_BEGIN
+RAW
+b7fe9a3c501040a2aef50000000000000000
+ENTRY_END
+
+STEP 24350 QUERY
+ENTRY_BEGIN
+RAW
+b7ff23b250114462a6a60000000000000000
+ENTRY_END
+
+STEP 24360 QUERY
+ENTRY_BEGIN
+RAW
+b7fff486501144623d510000000000000000
+ENTRY_END
+
+STEP 24370 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400093ce0000020405b401010402
+ENTRY_END
+
+STEP 24380 QUERY
+ENTRY_BEGIN
+RAW
+b7fd5e3c50104462f02e0000000000000000
+ENTRY_END
+
+STEP 24390 QUERY
+ENTRY_BEGIN
+RAW
+b8008be0501044708f6b0000000000000000
+ENTRY_END
+
+STEP 24400 QUERY
+ENTRY_BEGIN
+RAW
+b7fff487501044623d500000000000000000
+ENTRY_END
+
+STEP 24410 QUERY
+ENTRY_BEGIN
+RAW
+b8008be050184470c140000000911900000000010001000000000f313034373937323032303234322d320000f900010f313034373937323032303234322d320000f900ff00000000005503677373096d6963726f736f667403636f6d00403afd47403c4ec70003000000324e544c4d535350000100000097b208e00b000b00270000000700070020000000495345525645524b5356494e5445524e45540000
+ENTRY_END
+
+STEP 24420 QUERY
+ENTRY_BEGIN
+RAW
+b7ff23b350104462a6a50000000000000000
+ENTRY_END
+
+STEP 24430 QUERY
+ENTRY_BEGIN
+RAW
+b8013f7f50104470c4910000000000000000
+ENTRY_END
+
+STEP 24440 QUERY
+ENTRY_BEGIN
+RAW
+b8008bee501144628ed70000000000000000
+ENTRY_END
+
+STEP 24450 QUERY
+ENTRY_BEGIN
+RAW
+b8013f7f501844705a39000000941580000000010001000000000f313036353135313838393432362d320000f900010f313036353135313838393432362d320000f900ff00000000005803677373096d6963726f736f667403636f6d00403afd78403c4ef80003000000354e544c4d535350000100000097b200c00f000f00260000000600060020000000534552564552444f5649414e55534b414e544f4f520000
+ENTRY_END
+
+STEP 24460 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400087580000020405b401010402
+ENTRY_END
+
+STEP 24470 QUERY
+ENTRY_BEGIN
+RAW
+b8013f8d50114462c3fa0000000000000000
+ENTRY_END
+
+STEP 24480 QUERY
+ENTRY_BEGIN
+RAW
+b8013f8e50104462c3f90000000000000000
+ENTRY_END
+
+STEP 24490 QUERY
+ENTRY_BEGIN
+RAW
+b8008bef501044628ed60000000000000000
+ENTRY_END
+
+STEP 24500 QUERY
+ENTRY_BEGIN
+RAW
+b80237e650104470bfb30000000000000000
+ENTRY_END
+
+STEP 24510 QUERY
+ENTRY_BEGIN
+RAW
+b80237e650184470d108000000913980000000010001000000000f313034373937323032303234322d320000f900010f313034373937323032303234322d320000f900ff00000000005503677373096d6963726f736f667403636f6d00403afd47403c4ec70003000000324e544c4d535350000100000097b208e00b000b00270000000700070020000000495345525645524b5356494e5445524e45540000
+ENTRY_END
+
+STEP 24520 QUERY
+ENTRY_BEGIN
+RAW
+b80237f450114462bf1f0000000000000000
+ENTRY_END
+
+STEP 24530 QUERY
+ENTRY_BEGIN
+RAW
+b80237f550104462bf1e0000000000000000
+ENTRY_END
+
+STEP 24540 QUERY
+ENTRY_BEGIN
+RAW
+00000000700240006a560000020405b401010402
+ENTRY_END
+
+STEP 24550 QUERY
+ENTRY_BEGIN
+RAW
+b80679815010447061120000000000000000
+ENTRY_END
+
+STEP 24560 QUERY
+ENTRY_BEGIN
+RAW
+b806798150184470b338000000945600000000010001000000000f313036353135313838393432362d330000f900010f313036353135313838393432362d330000f900ff00000000005803677373096d6963726f736f667403636f6d00403afd79403c4ef90003000000354e544c4d535350000100000097b200c00f000f00260000000600060020000000534552564552444f5649414e55534b414e544f4f520000
+ENTRY_END
+
+STEP 24570 QUERY
+ENTRY_BEGIN
+RAW
+b806798f50114462607b0000000000000000
+ENTRY_END
+
+STEP 24580 QUERY
+ENTRY_BEGIN
+RAW
+00000000700240009e400000020405b401010402
+ENTRY_END
+
+STEP 24590 QUERY
+ENTRY_BEGIN
+RAW
+b806799050104462607a0000000000000000
+ENTRY_END
+
+STEP 24600 QUERY
+ENTRY_BEGIN
+RAW
+b8070e5a5010447000230000000000000000
+ENTRY_END
+
+STEP 24610 QUERY
+ENTRY_BEGIN
+RAW
+b8070e5a501844701a8a000000948ec0000000010001000000000f313036353135313838393432362d320000f900010f313036353135313838393432362d320000f900ff00000000005803677373096d6963726f736f667403636f6d00403afd79403c4ef90003000000354e544c4d535350000100000097b200c00f000f00260000000600060020000000534552564552444f5649414e55534b414e544f4f520000
+ENTRY_END
+
+STEP 24620 QUERY
+ENTRY_BEGIN
+RAW
+b8070e6850114462ff8b0000000000000000
+ENTRY_END
+
+STEP 24630 QUERY
+ENTRY_BEGIN
+RAW
+00000000700240009a4a0000020405b401010402
+ENTRY_END
+
+STEP 24640 QUERY
+ENTRY_BEGIN
+RAW
+b8070e6950104462ff8a0000000000000000
+ENTRY_END
+
+STEP 24650 QUERY
+ENTRY_BEGIN
+RAW
+b807ad57501044705d2f0000000000000000
+ENTRY_END
+
+STEP 24660 QUERY
+ENTRY_BEGIN
+RAW
+b807ad5750184470d616000000943040000000010001000000000f313036353135313838393432362d320000f900010f313036353135313838393432362d320000f900ff00000000005803677373096d6963726f736f667403636f6d00403afd79403c4ef90003000000354e544c4d535350000100000097b200c00f000f00260000000600060020000000534552564552444f5649414e55534b414e544f4f520000
+ENTRY_END
+
+STEP 24670 QUERY
+ENTRY_BEGIN
+RAW
+b807ad65501144625c980000000000000000
+ENTRY_END
+
+STEP 24680 QUERY
+ENTRY_BEGIN
+RAW
+b807ad66501044625c970000000000000000
+ENTRY_END
+
+STEP 24690 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000b5a30000020405b401010402
+ENTRY_END
+
+STEP 24700 QUERY
+ENTRY_BEGIN
+RAW
+b8083fa650104470e6380000000000000000
+ENTRY_END
+
+STEP 24710 QUERY
+ENTRY_BEGIN
+RAW
+b8083fa650184470331f000000945b40000000010001000000000f313036353135313838393432362d330000f900010f313036353135313838393432362d330000f900ff00000000005803677373096d6963726f736f667403636f6d00403afd79403c4ef90003000000354e544c4d535350000100000097b200c00f000f00260000000600060020000000534552564552444f5649414e55534b414e544f4f520000
+ENTRY_END
+
+STEP 24720 QUERY
+ENTRY_BEGIN
+RAW
+b8083fb450114462e5a10000000000000000
+ENTRY_END
+
+STEP 24730 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000ab0a0000020405b401010402
+ENTRY_END
+
+STEP 24740 QUERY
+ENTRY_BEGIN
+RAW
+b8083fb550104462e5a00000000000000000
+ENTRY_END
+
+STEP 24750 QUERY
+ENTRY_BEGIN
+RAW
+b80933a250104470e7a20000000000000000
+ENTRY_END
+
+STEP 24760 QUERY
+ENTRY_BEGIN
+RAW
+b80933a250184470fcc9000000949400000000010001000000000f313036353135313838393432362d320000f900010f313036353135313838393432362d320000f900ff00000000005803677373096d6963726f736f667403636f6d00403afd79403c4ef90003000000354e544c4d535350000100000097b200c00f000f00260000000600060020000000534552564552444f5649414e55534b414e544f4f520000
+ENTRY_END
+
+STEP 24770 QUERY
+ENTRY_BEGIN
+RAW
+b80933b050114462e70b0000000000000000
+ENTRY_END
+
+STEP 24780 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000fdbe0000020405b401010402
+ENTRY_END
+
+STEP 24790 QUERY
+ENTRY_BEGIN
+RAW
+b80b2b8e5010447042690000000000000000
+ENTRY_END
+
+STEP 24800 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000a29f0000020405b401010402
+ENTRY_END
+
+STEP 24810 QUERY
+ENTRY_BEGIN
+RAW
+b80b2b8e5018447092d00000009458c0000000010001000000000f313036353135313838393432362d320000f900010f313036353135313838393432362d320000f900ff00000000005803677373096d6963726f736f667403636f6d00403afd79403c4ef90003000000354e544c4d535350000100000097b200c00f000f00260000000600060020000000534552564552444f5649414e55534b414e544f4f520000
+ENTRY_END
+
+STEP 24820 QUERY
+ENTRY_BEGIN
+RAW
+b80933b150104462e70a0000000000000000
+ENTRY_END
+
+STEP 24830 QUERY
+ENTRY_BEGIN
+RAW
+b80b2b9c5011446241d20000000000000000
+ENTRY_END
+
+STEP 24840 QUERY
+ENTRY_BEGIN
+RAW
+b80c085d501044700a7a0000000000000000
+ENTRY_END
+
+STEP 24850 QUERY
+ENTRY_BEGIN
+RAW
+b80b2b9d5010446241d10000000000000000
+ENTRY_END
+
+STEP 24860 QUERY
+ENTRY_BEGIN
+RAW
+b80c085d5018447053cd0000008b07ac000000010001000000000f313034373937323032303234322d330000f900010f313034373937323032303234322d330000f900ff00000000004f03677373096d6963726f736f667403636f6d00403afd53403c4ed300030000002c4e544c4d535350000100000097b200c0060006002600000006000600200000004c4150544f504a41434f42530000
+ENTRY_END
+
+STEP 24870 QUERY
+ENTRY_BEGIN
+RAW
+b80c086b5011446209ec0000000000000000
+ENTRY_END
+
+STEP 24880 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000ab970000020405b401010402
+ENTRY_END
+
+STEP 24890 QUERY
+ENTRY_BEGIN
+RAW
+b80c086c5010446209eb0000000000000000
+ENTRY_END
+
+STEP 24900 QUERY
+ENTRY_BEGIN
+RAW
+b80c8b7b5010447090530000000000000000
+ENTRY_END
+
+STEP 24910 QUERY
+ENTRY_BEGIN
+RAW
+b80c8b7b501844702c170000008bb43c000000010001000000000f313034373937323032303234322d320000f900010f313034373937323032303234322d320000f900ff00000000004f03677373096d6963726f736f667403636f6d00403afd54403c4ed400030000002c4e544c4d535350000100000097b200c0060006002600000006000600200000004c4150544f504a41434f42530000
+ENTRY_END
+
+STEP 24920 QUERY
+ENTRY_BEGIN
+RAW
+b80c8b89501144628fc50000000000000000
+ENTRY_END
+
+STEP 24930 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400063ad0000020405b401010402
+ENTRY_END
+
+STEP 24940 QUERY
+ENTRY_BEGIN
+RAW
+b80c8b8a501044628fc40000000000000000
+ENTRY_END
+
+STEP 24950 QUERY
+ENTRY_BEGIN
+RAW
+b80d337550104470a06e0000000000000000
+ENTRY_END
+
+STEP 24960 QUERY
+ENTRY_BEGIN
+RAW
+b80d337550184470f99b0000008bf6d2000000010001000000000f313034373937323032303234322d320000f900010f313034373937323032303234322d320000f900ff00000000004f03677373096d6963726f736f667403636f6d00403afd54403c4ed400030000002c4e544c4d535350000100000097b200c0060006002600000006000600200000004c4150544f504a41434f42530000
+ENTRY_END
+
+STEP 24970 QUERY
+ENTRY_BEGIN
+RAW
+b80d3383501144629fe00000000000000000
+ENTRY_END
+
+STEP 24980 QUERY
+ENTRY_BEGIN
+RAW
+b80d3384501044629fdf0000000000000000
+ENTRY_END
+
+STEP 24990 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400007cf0000020405b401010402
+ENTRY_END
+
+STEP 25000 QUERY
+ENTRY_BEGIN
+RAW
+b80f1979501044705e8a0000000000000000
+ENTRY_END
+
+STEP 25010 QUERY
+ENTRY_BEGIN
+RAW
+b80f19795018447087170000008ba547000000010001000000000e3839333335333139373538362d330000f900010e3839333335333139373538362d330000f900ff00000000005103677373096d6963726f736f667403636f6d00403afbd2403c4d5200030000002e4e544c4d535350000100000097b208e0080008002600000006000600200000005343484f4c534848454e545a454e0000
+ENTRY_END
+
+STEP 25020 QUERY
+ENTRY_BEGIN
+RAW
+b80f1987501144625dfc0000000000000000
+ENTRY_END
+
+STEP 25030 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400013fa0000020405b401010402
+ENTRY_END
+
+STEP 25040 QUERY
+ENTRY_BEGIN
+RAW
+b80f1988501044625dfb0000000000000000
+ENTRY_END
+
+STEP 25050 QUERY
+ENTRY_BEGIN
+RAW
+b8100fa250104470748b0000000000000000
+ENTRY_END
+
+STEP 25060 QUERY
+ENTRY_BEGIN
+RAW
+b8100fa250184470efe20000008b547d000000010001000000000e3839333335333139373538362d320000f900010e3839333335333139373538362d320000f900ff00000000005103677373096d6963726f736f667403636f6d00403afbd2403c4d5200030000002e4e544c4d535350000100000097b208e0080008002600000006000600200000005343484f4c534848454e545a454e0000
+ENTRY_END
+
+STEP 25070 QUERY
+ENTRY_BEGIN
+RAW
+b8100fb05011446273fd0000000000000000
+ENTRY_END
+
+STEP 25080 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400030df0000020405b401010402
+ENTRY_END
+
+STEP 25090 QUERY
+ENTRY_BEGIN
+RAW
+b8100fb15010446273fc0000000000000000
+ENTRY_END
+
+STEP 25100 QUERY
+ENTRY_BEGIN
+RAW
+b81096d8501044700a3a0000000000000000
+ENTRY_END
+
+STEP 25110 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf043bb0000020405b401010402
+ENTRY_END
+
+STEP 25120 QUERY
+ENTRY_BEGIN
+RAW
+b81096d8501844706e000000008b6c0e000000010001000000000e3839333335333139373538362d320000f900010e3839333335333139373538362d320000f900ff00000000005103677373096d6963726f736f667403636f6d00403afbd2403c4d5200030000002e4e544c4d535350000100000097b208e0080008002600000006000600200000005343484f4c534848454e545a454e0000
+ENTRY_END
+
+STEP 25130 QUERY
+ENTRY_BEGIN
+RAW
+b81096e65011446209ac0000000000000000
+ENTRY_END
+
+STEP 25140 QUERY
+ENTRY_BEGIN
+RAW
+b81096e75010446209ab0000000000000000
+ENTRY_END
+
+STEP 25150 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400074a10000020405b401010402
+ENTRY_END
+
+STEP 25160 QUERY
+ENTRY_BEGIN
+RAW
+b812ca7a501044701a580000000000000000
+ENTRY_END
+
+STEP 25170 QUERY
+ENTRY_BEGIN
+RAW
+b812ca7a50184470b4fb00000090ef06000000010001000000000f313038323333313735383631302d330000f900010f313038323333313735383631302d330000f900ff00000000005403677373096d6963726f736f667403636f6d004039b1fb403b037b0003000000314e544c4d535350000100000097b200c00a000a0027000000070007002000000042414e4b4a414e4753492d444f4d41494e0000
+ENTRY_END
+
+STEP 25180 QUERY
+ENTRY_BEGIN
+RAW
+b812ca885011446219c50000000000000000
+ENTRY_END
+
+STEP 25190 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000d8060000020405b401010402
+ENTRY_END
+
+STEP 25200 QUERY
+ENTRY_BEGIN
+RAW
+b812ca895010446219c40000000000000000
+ENTRY_END
+
+STEP 25210 QUERY
+ENTRY_BEGIN
+RAW
+b81344c45010447003730000000000000000
+ENTRY_END
+
+STEP 25220 QUERY
+ENTRY_BEGIN
+RAW
+b81344c450184470d4fb00000090b722000000010001000000000f313038323333313735383631302d320000f900010f313038323333313735383631302d320000f900ff00000000005403677373096d6963726f736f667403636f6d004039b1fc403b037c0003000000314e544c4d535350000100000097b200c00a000a0027000000070007002000000042414e4b4a414e4753492d444f4d41494e0000
+ENTRY_END
+
+STEP 25230 QUERY
+ENTRY_BEGIN
+RAW
+b81344d25011446202e00000000000000000
+ENTRY_END
+
+STEP 25240 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000aad60000020405b401010402
+ENTRY_END
+
+STEP 25250 QUERY
+ENTRY_BEGIN
+RAW
+b81344d35010446202df0000000000000000
+ENTRY_END
+
+STEP 25260 QUERY
+ENTRY_BEGIN
+RAW
+b813e03f501044703ac70000000000000000
+ENTRY_END
+
+STEP 25270 QUERY
+ENTRY_BEGIN
+RAW
+b813e03f50184470df7500000090e3fc000000010001000000000f313038323333313735383631302d320000f900010f313038323333313735383631302d320000f900ff00000000005403677373096d6963726f736f667403636f6d004039b1fc403b037c0003000000314e544c4d535350000100000097b200c00a000a0027000000070007002000000042414e4b4a414e4753492d444f4d41494e0000
+ENTRY_END
+
+STEP 25280 QUERY
+ENTRY_BEGIN
+RAW
+b813e04d501144623a340000000000000000
+ENTRY_END
+
+STEP 25290 QUERY
+ENTRY_BEGIN
+RAW
+b813e04e501044623a330000000000000000
+ENTRY_END
+
+STEP 25300 QUERY
+ENTRY_BEGIN
+RAW
+1a4e00000001000000000000087461786932303030026e6c00000f000100
+ENTRY_END
+
+STEP 25310 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000322000000204057a01010402
+ENTRY_END
+
+STEP 25320 QUERY
+ENTRY_BEGIN
+RAW
+b81609ca501041b89b010000000000000000
+ENTRY_END
+
+STEP 25330 QUERY
+ENTRY_BEGIN
+RAW
+b81609ca501841b82920000000944f25000000010001000000000f313133333837313336363136322d330000f900010f313133333837313336363136322d330000f900ff00000000005803677373096d6963726f736f667403636f6d00403afa6a403c4bea0003000000354e544c4d535350000100000097b200e0090009002c0000000c000c0020000000534253504952414d4944454e504952414d4944454e0000
+ENTRY_END
+
+STEP 25340 QUERY
+ENTRY_BEGIN
+RAW
+b81609d8501141aa9a6a0000000000000000
+ENTRY_END
+
+STEP 25350 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000436000000204057a01010402
+ENTRY_END
+
+STEP 25360 QUERY
+ENTRY_BEGIN
+RAW
+b81609d9501041aa9a690000000000000000
+ENTRY_END
+
+STEP 25370 QUERY
+ENTRY_BEGIN
+RAW
+b81695d2501041b820390000000000000000
+ENTRY_END
+
+STEP 25380 QUERY
+ENTRY_BEGIN
+RAW
+b81695d2501841b87aad0000009483d0000000010001000000000f313133333837313336363136322d320000f900010f313133333837313336363136322d320000f900ff00000000005803677373096d6963726f736f667403636f6d00403afa6a403c4bea0003000000354e544c4d535350000100000097b200e0090009002c0000000c000c0020000000534253504952414d4944454e504952414d4944454e0000
+ENTRY_END
+
+STEP 25390 QUERY
+ENTRY_BEGIN
+RAW
+b81695e0501141aa1fa20000000000000000
+ENTRY_END
+
+STEP 25400 QUERY
+ENTRY_BEGIN
+RAW
+00000000700240000b3700000204057a01010402
+ENTRY_END
+
+STEP 25410 QUERY
+ENTRY_BEGIN
+RAW
+b81695e1501041aa1fa10000000000000000
+ENTRY_END
+
+STEP 25420 QUERY
+ENTRY_BEGIN
+RAW
+b8171898501041b865490000000000000000
+ENTRY_END
+
+STEP 25430 QUERY
+ENTRY_BEGIN
+RAW
+b8171898501841b8206e000000942320000000010001000000000f313133333837313336363136322d320000f900010f313133333837313336363136322d320000f900ff00000000005803677373096d6963726f736f667403636f6d00403afa6a403c4bea0003000000354e544c4d535350000100000097b200e0090009002c0000000c000c0020000000534253504952414d4944454e504952414d4944454e0000
+ENTRY_END
+
+STEP 25440 QUERY
+ENTRY_BEGIN
+RAW
+b81718a6501141aa64b20000000000000000
+ENTRY_END
+
+STEP 25450 QUERY
+ENTRY_BEGIN
+RAW
+b81718a7501041aa64b10000000000000000
+ENTRY_END
+
+STEP 25460 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf052f200000204057a01010402
+ENTRY_END
+
+STEP 25470 QUERY
+ENTRY_BEGIN
+RAW
+b817bc735010fbec09e50000000000000000
+ENTRY_END
+
+STEP 25480 QUERY
+ENTRY_BEGIN
+RAW
+b817bc735018fbecebda00000091c518000000010001000000000f313131363639313439363937382d330000f900010f313131363639313439363937382d330000f900ff00000000005503677373096d6963726f736f667403636f6d00403af82a403c49aa0003000000324e544c4d535350000100000097b208e0080008002a0000000a000a00200000004a4844454c49455230314a4844454c4945520000
+ENTRY_END
+
+STEP 25490 QUERY
+ENTRY_BEGIN
+RAW
+b817bc815011fbde09510000000000000000
+ENTRY_END
+
+STEP 25500 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf0d21400000204057a01010402
+ENTRY_END
+
+STEP 25510 QUERY
+ENTRY_BEGIN
+RAW
+b817bc825010fbde09500000000000000000
+ENTRY_END
+
+STEP 25520 QUERY
+ENTRY_BEGIN
+RAW
+b818a4a45010fbeca0d50000000000000000
+ENTRY_END
+
+STEP 25530 QUERY
+ENTRY_BEGIN
+RAW
+b818a4a45018fbec05b5000000914330000000010001000000000f313131363639313439363937382d320000f900010f313131363639313439363937382d320000f900ff00000000005503677373096d6963726f736f667403636f6d00403af82a403c49aa0003000000324e544c4d535350000100000097b208e0080008002a0000000a000a00200000004a4844454c49455230314a4844454c4945520000
+ENTRY_END
+
+STEP 25540 QUERY
+ENTRY_BEGIN
+RAW
+b818a4b25011fbdea0410000000000000000
+ENTRY_END
+
+STEP 25550 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf01cad00000204057a01010402
+ENTRY_END
+
+STEP 25560 QUERY
+ENTRY_BEGIN
+RAW
+b818a4b35010fbdea0400000000000000000
+ENTRY_END
+
+STEP 25570 QUERY
+ENTRY_BEGIN
+RAW
+b8198d495010fbec02c80000000000000000
+ENTRY_END
+
+STEP 25580 QUERY
+ENTRY_BEGIN
+RAW
+b8198d495018fbeccd2600000091ddb0000000010001000000000f313131363639313439363937382d320000f900010f313131363639313439363937382d320000f900ff00000000005503677373096d6963726f736f667403636f6d00403af82a403c49aa0003000000324e544c4d535350000100000097b208e0080008002a0000000a000a00200000004a4844454c49455230314a4844454c4945520000
+ENTRY_END
+
+STEP 25590 QUERY
+ENTRY_BEGIN
+RAW
+b8198d575011fbde02340000000000000000
+ENTRY_END
+
+STEP 25600 QUERY
+ENTRY_BEGIN
+RAW
+b8198d585010fbde02330000000000000000
+ENTRY_END
+
+STEP 25610 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf0686900000204055001010402
+ENTRY_END
+
+STEP 25620 QUERY
+ENTRY_BEGIN
+RAW
+b81b91965010ff0046f70000000000000000
+ENTRY_END
+
+STEP 25630 QUERY
+ENTRY_BEGIN
+RAW
+b81b91965018ff00d263000000923613000000010001000000000f313531313832383438383231302d330000f900010f313531313832383438383231302d330000f900ff00000000005603677373096d6963726f736f667403636f6d00403b001a403c519a0003000000334e544c4d535350000100000097b208e0090009002a0000000a000a002000000057324b5345525645523150524b564457494c440000
+ENTRY_END
+
+STEP 25640 QUERY
+ENTRY_BEGIN
+RAW
+00000000700240008b6f0000020405b401010402
+ENTRY_END
+
+STEP 25650 QUERY
+ENTRY_BEGIN
+RAW
+b81b91a45011fef246620000000000000000
+ENTRY_END
+
+STEP 25660 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf0c61600000204055001010402
+ENTRY_END
+
+STEP 25670 QUERY
+ENTRY_BEGIN
+RAW
+b81b91a55010fef246610000000000000000
+ENTRY_END
+
+STEP 25680 QUERY
+ENTRY_BEGIN
+RAW
+b81cbbfa5010ff007a3f0000000000000000
+ENTRY_END
+
+STEP 25690 QUERY
+ENTRY_BEGIN
+RAW
+b81c194650104470e2500000000000000000
+ENTRY_END
+
+STEP 25700 QUERY
+ENTRY_BEGIN
+RAW
+b81cbbfa5018ff003f8e00000092fd31000000010001000000000f313531313832383438383231302d320000f900010f313531313832383438383231302d320000f900ff00000000005603677373096d6963726f736f667403636f6d00403b001a403c519a0003000000334e544c4d535350000100000097b208e0090009002a0000000a000a002000000057324b5345525645523150524b564457494c440000
+ENTRY_END
+
+STEP 25710 QUERY
+ENTRY_BEGIN
+RAW
+b81cbc085011fef279aa0000000000000000
+ENTRY_END
+
+STEP 25720 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf0092500000204055001010402
+ENTRY_END
+
+STEP 25730 QUERY
+ENTRY_BEGIN
+RAW
+b81c1946501844707e040000008cd8b0000000010001000000000f313133333837313336363136322d330000f900010f313133333837313336363136322d330000f900ff00000000005003677373096d6963726f736f667403636f6d00403afd1e403c4e9e00030000002d4e544c4d535350000100000097b208e007000700260000000600060020000000574e54504d4d574e545f504d4d0000
+ENTRY_END
+
+STEP 25740 QUERY
+ENTRY_BEGIN
+RAW
+b81da63a5010ff00d30c0000000000000000
+ENTRY_END
+
+STEP 25750 QUERY
+ENTRY_BEGIN
+RAW
+b81da63a5018ff00d13d00000092c44f000000010001000000000f313531313832383438383231302d320000f900010f313531313832383438383231302d320000f900ff00000000005603677373096d6963726f736f667403636f6d00403b001a403c519a0003000000334e544c4d535350000100000097b208e0090009002a0000000a000a002000000057324b5345525645523150524b564457494c440000
+ENTRY_END
+
+STEP 25760 QUERY
+ENTRY_BEGIN
+RAW
+b81da6485011fef2d2770000000000000000
+ENTRY_END
+
+STEP 25770 QUERY
+ENTRY_BEGIN
+RAW
+b81c195450114462e1c10000000000000000
+ENTRY_END
+
+STEP 25780 QUERY
+ENTRY_BEGIN
+RAW
+b81da6495010fef2d2760000000000000000
+ENTRY_END
+
+STEP 25790 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000572f0000020405b401010402
+ENTRY_END
+
+STEP 25800 QUERY
+ENTRY_BEGIN
+RAW
+b81c195550104462e1c00000000000000000
+ENTRY_END
+
+STEP 25810 QUERY
+ENTRY_BEGIN
+RAW
+b81e3ea55010447088af0000000000000000
+ENTRY_END
+
+STEP 25820 QUERY
+ENTRY_BEGIN
+RAW
+b81e3ea550184470b8510000008c45c3000000010001000000000f313133333837313336363136322d320000f900010f313133333837313336363136322d320000f900ff00000000005003677373096d6963726f736f667403636f6d00403afd1e403c4e9e00030000002d4e544c4d535350000100000097b208e007000700260000000600060020000000574e54504d4d574e545f504d4d0000
+ENTRY_END
+
+STEP 25830 QUERY
+ENTRY_BEGIN
+RAW
+b81e3eb35011446288200000000000000000
+ENTRY_END
+
+STEP 25840 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400007d90000020405b401010402
+ENTRY_END
+
+STEP 25850 QUERY
+ENTRY_BEGIN
+RAW
+b81e3eb450104462881f0000000000000000
+ENTRY_END
+
+STEP 25860 QUERY
+ENTRY_BEGIN
+RAW
+b81eec12501044708beb0000000000000000
+ENTRY_END
+
+STEP 25870 QUERY
+ENTRY_BEGIN
+RAW
+b81eec125018447092a40000008c6eac000000010001000000000f313133333837313336363136322d320000f900010f313133333837313336363136322d320000f900ff00000000005003677373096d6963726f736f667403636f6d00403afd1e403c4e9e00030000002d4e544c4d535350000100000097b208e007000700260000000600060020000000574e54504d4d574e545f504d4d0000
+ENTRY_END
+
+STEP 25880 QUERY
+ENTRY_BEGIN
+RAW
+b81eec20501144628b5c0000000000000000
+ENTRY_END
+
+STEP 25890 QUERY
+ENTRY_BEGIN
+RAW
+b81eec21501044628b5b0000000000000000
+ENTRY_END
+
+STEP 25900 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400010370000020405b401010402
+ENTRY_END
+
+STEP 25910 QUERY
+ENTRY_BEGIN
+RAW
+b820ebd95010447094800000000000000000
+ENTRY_END
+
+STEP 25920 QUERY
+ENTRY_BEGIN
+RAW
+b820ebd950184470da910000008ef600000000010001000000000f313131363639313439363937382d330000f900010f313131363639313439363937382d330000f900ff00000000005203677373096d6963726f736f667403636f6d00403afd1f403c4e9f00030000002f4e544c4d535350000100000097b200c009000900260000000600060020000000544f544f524f434f524e574f524c440000
+ENTRY_END
+
+STEP 25930 QUERY
+ENTRY_BEGIN
+RAW
+b820ebe75011446293ef0000000000000000
+ENTRY_END
+
+STEP 25940 QUERY
+ENTRY_BEGIN
+RAW
+b820ebe85010446293ee0000000000000000
+ENTRY_END
+
+STEP 25950 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000cbcf0000020405b401010402
+ENTRY_END
+
+STEP 25960 QUERY
+ENTRY_BEGIN
+RAW
+b821db135010447060de0000000000000000
+ENTRY_END
+
+STEP 25970 QUERY
+ENTRY_BEGIN
+RAW
+b821db13501844703ff10000008e5e00000000010001000000000f313131363639313439363937382d320000f900010f313131363639313439363937382d320000f900ff00000000005203677373096d6963726f736f667403636f6d00403afd1f403c4e9f00030000002f4e544c4d535350000100000097b200c009000900260000000600060020000000544f544f524f434f524e574f524c440000
+ENTRY_END
+
+STEP 25980 QUERY
+ENTRY_BEGIN
+RAW
+b821db2150114462604d0000000000000000
+ENTRY_END
+
+STEP 25990 QUERY
+ENTRY_BEGIN
+RAW
+b821db2250104462604c0000000000000000
+ENTRY_END
+
+STEP 26000 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400024f30000020405b401010402
+ENTRY_END
+
+STEP 26010 QUERY
+ENTRY_BEGIN
+RAW
+b8229fc850104470f54b0000000000000000
+ENTRY_END
+
+STEP 26020 QUERY
+ENTRY_BEGIN
+RAW
+b8229fc850184470795e0000008eb900000000010001000000000f313131363639313439363937382d320000f900010f313131363639313439363937382d320000f900ff00000000005203677373096d6963726f736f667403636f6d00403afd1f403c4e9f00030000002f4e544c4d535350000100000097b200c009000900260000000600060020000000544f544f524f434f524e574f524c440000
+ENTRY_END
+
+STEP 26030 QUERY
+ENTRY_BEGIN
+RAW
+b8229fd650114462f4ba0000000000000000
+ENTRY_END
+
+STEP 26040 QUERY
+ENTRY_BEGIN
+RAW
+b8229fd750104462f4b90000000000000000
+ENTRY_END
+
+STEP 26050 QUERY
+ENTRY_BEGIN
+RAW
+00000000700240007f1e00000204057801010402
+ENTRY_END
+
+STEP 26060 QUERY
+ENTRY_BEGIN
+RAW
+b82500fd501041a0f0d30000000000000000
+ENTRY_END
+
+STEP 26070 QUERY
+ENTRY_BEGIN
+RAW
+b82500fd501841a0fa410000008d6f40000000010001000000000f313036353135313838393432362d330000f900010f313036353135313838393432362d330000f900ff00000000005103677373096d6963726f736f667403636f6d00403aef20403c40a000030000002e4e544c4d535350000100000097b200c008000800260000000600060020000000534552564552434f42424c4552310000
+ENTRY_END
+
+STEP 26080 QUERY
+ENTRY_BEGIN
+RAW
+b825010b50114192f0430000000000000000
+ENTRY_END
+
+STEP 26090 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400048c400000204057801010402
+ENTRY_END
+
+STEP 26100 QUERY
+ENTRY_BEGIN
+RAW
+b825010c50104192f0420000000000000000
+ENTRY_END
+
+STEP 26110 QUERY
+ENTRY_BEGIN
+RAW
+b825ba8a501041a000ec0000000000000000
+ENTRY_END
+
+STEP 26120 QUERY
+ENTRY_BEGIN
+RAW
+b825ba8a501841a08ada0000008defc0000000010001000000000f313036353135313838393432362d320000f900010f313036353135313838393432362d320000f900ff00000000005103677373096d6963726f736f667403636f6d00403aef20403c40a000030000002e4e544c4d535350000100000097b200c008000800260000000600060020000000534552564552434f42424c4552310000
+ENTRY_END
+
+STEP 26130 QUERY
+ENTRY_BEGIN
+RAW
+b825ba9850114192005c0000000000000000
+ENTRY_END
+
+STEP 26140 QUERY
+ENTRY_BEGIN
+RAW
+00000000700240004f1300000204057801010402
+ENTRY_END
+
+STEP 26150 QUERY
+ENTRY_BEGIN
+RAW
+b825ba9950104192005b0000000000000000
+ENTRY_END
+
+STEP 26160 QUERY
+ENTRY_BEGIN
+RAW
+b8269830501041a029940000000000000000
+ENTRY_END
+
+STEP 26170 QUERY
+ENTRY_BEGIN
+RAW
+b8269830501841a08f030000008d1440000000010001000000000f313036353135313838393432362d320000f900010f313036353135313838393432362d320000f900ff00000000005103677373096d6963726f736f667403636f6d00403aef20403c40a000030000002e4e544c4d535350000100000097b200c008000800260000000600060020000000534552564552434f42424c4552310000
+ENTRY_END
+
+STEP 26180 QUERY
+ENTRY_BEGIN
+RAW
+b826983e5011419229040000000000000000
+ENTRY_END
+
+STEP 26190 QUERY
+ENTRY_BEGIN
+RAW
+b826983f5010419229030000000000000000
+ENTRY_END
+
+STEP 26200 QUERY
+ENTRY_BEGIN
+RAW
+b81cbc0950100000789c0000000000000000
+ENTRY_END
+
+STEP 26210 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000945300000204057a01010402
+ENTRY_END
+
+STEP 26220 QUERY
+ENTRY_BEGIN
+RAW
+b8289ecf501041b8681d0000000000000000
+ENTRY_END
+
+STEP 26230 QUERY
+ENTRY_BEGIN
+RAW
+b8289ecf501841b8c24a0000008eaff4000000010001000000000f313034373937323032303234322d330000f900010f313034373937323032303234322d330000f900ff00000000005203677373096d6963726f736f667403636f6d00403a9d3f403beebf00030000002f4e544c4d535350000100000097b200e0090009002600000006000600200000004144455749544152494544455749540000
+ENTRY_END
+
+STEP 26240 QUERY
+ENTRY_BEGIN
+RAW
+b8289edd501141aa678c0000000000000000
+ENTRY_END
+
+STEP 26250 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000c58e00000204057a01010402
+ENTRY_END
+
+STEP 26260 QUERY
+ENTRY_BEGIN
+RAW
+b8289ede501041aa678b0000000000000000
+ENTRY_END
+
+STEP 26270 QUERY
+ENTRY_BEGIN
+RAW
+b829975b501041b8a0cb0000000000000000
+ENTRY_END
+
+STEP 26280 QUERY
+ENTRY_BEGIN
+RAW
+b829975b501841b87ebc0000008e2d32000000010001000000000f313034373937323032303234322d320000f900010f313034373937323032303234322d320000f900ff00000000005203677373096d6963726f736f667403636f6d00403a9d3f403beebf00030000002f4e544c4d535350000100000097b200e0090009002600000006000600200000004144455749544152494544455749540000
+ENTRY_END
+
+STEP 26290 QUERY
+ENTRY_BEGIN
+RAW
+b8299769501141aaa03a0000000000000000
+ENTRY_END
+
+STEP 26300 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400035ff00000204057a01010402
+ENTRY_END
+
+STEP 26310 QUERY
+ENTRY_BEGIN
+RAW
+b829976a501041aaa0390000000000000000
+ENTRY_END
+
+STEP 26320 QUERY
+ENTRY_BEGIN
+RAW
+b82a2f49501041b8794d0000000000000000
+ENTRY_END
+
+STEP 26330 QUERY
+ENTRY_BEGIN
+RAW
+b82a2f49501841b8d9ff0000008eaa70000000010001000000000f313034373937323032303234322d320000f900010f313034373937323032303234322d320000f900ff00000000005203677373096d6963726f736f667403636f6d00403a9d3f403beebf00030000002f4e544c4d535350000100000097b200e0090009002600000006000600200000004144455749544152494544455749540000
+ENTRY_END
+
+STEP 26340 QUERY
+ENTRY_BEGIN
+RAW
+b82a2f57501141aa78bc0000000000000000
+ENTRY_END
+
+STEP 26350 QUERY
+ENTRY_BEGIN
+RAW
+b82a2f58501041aa78bb0000000000000000
+ENTRY_END
+
+STEP 26360 QUERY
+ENTRY_BEGIN
+RAW
+00000000b002832c24a30000010303010101080a11235f89000000000101040202040564
+ENTRY_END
+
+STEP 26370 QUERY
+ENTRY_BEGIN
+RAW
+b82b27518010859879ee00000101080a11235f8a0128080f
+ENTRY_END
+
+;STEP 26380 QUERY
+;ENTRY_BEGIN
+;RAW
+;2c3901000001000000000000056b6f726e6f026e6c00000f000100
+;ENTRY_END
+
+STEP 26390 QUERY
+ENTRY_BEGIN
+RAW
+b82b275180188598d42e00000101080a11235f9a0128080f008e55dc000000010001000000000f313330353637303035383030322d330000f900010f313330353637303035383030322d330000f900ff00000000005203677373096d6963726f736f667403636f6d00403afc71403c4df100030000002f4e544c4d535350000100000097b208e0090009002600000006000600200000004c4150544f505745524b47524f45500000
+ENTRY_END
+
+STEP 26400 QUERY
+ENTRY_BEGIN
+RAW
+b82b275f80108598793f00000101080a11235f9b0128080f
+ENTRY_END
+
+STEP 26410 QUERY
+ENTRY_BEGIN
+RAW
+b82b275f8011859878e700000101080a11235ff20128080f
+ENTRY_END
+
+STEP 26420 QUERY
+ENTRY_BEGIN
+RAW
+b82b27608010859878e300000101080a11235ff301280811
+ENTRY_END
+
+STEP 26430 QUERY
+ENTRY_BEGIN
+RAW
+000000007002fca499ac00000204057e01010402
+ENTRY_END
+
+STEP 26440 QUERY
+ENTRY_BEGIN
+RAW
+b82fe4a45010fca429560000000000000000
+ENTRY_END
+
+STEP 26450 QUERY
+ENTRY_BEGIN
+RAW
+b82fe4a45018fca4909e000000927690000000010001000000000f313138353431303937333731342d330000f900010f313138353431303937333731342d330000f900ff00000000005603677373096d6963726f736f667403636f6d00403afd22403c4ea20003000000334e544c4d535350000100000097b208e00a000a0029000000090009002000000043454445522d444331434544455244524545460000
+ENTRY_END
+
+STEP 26460 QUERY
+ENTRY_BEGIN
+RAW
+b82fe4b25011fc9628c10000000000000000
+ENTRY_END
+
+STEP 26470 QUERY
+ENTRY_BEGIN
+RAW
+b82fe4b35010fc9628c00000000000000000
+ENTRY_END
+
+STEP 26480 QUERY
+ENTRY_BEGIN
+RAW
+000000007002fca4a2d800000204057e01010402
+ENTRY_END
+
+STEP 26490 QUERY
+ENTRY_BEGIN
+RAW
+b830dc6f5010fca43ab60000000000000000
+ENTRY_END
+
+STEP 26500 QUERY
+ENTRY_BEGIN
+RAW
+b830dc6f5018fca4199f00000092fff0000000010001000000000f313138353431303937333731342d320000f900010f313138353431303937333731342d320000f900ff00000000005603677373096d6963726f736f667403636f6d00403afd22403c4ea20003000000334e544c4d535350000100000097b208e00a000a0029000000090009002000000043454445522d444331434544455244524545460000
+ENTRY_END
+
+STEP 26510 QUERY
+ENTRY_BEGIN
+RAW
+b830dc7d5011fc963a210000000000000000
+ENTRY_END
+
+STEP 26520 QUERY
+ENTRY_BEGIN
+RAW
+b830dc7e5010fc963a200000000000000000
+ENTRY_END
+
+STEP 26530 QUERY
+ENTRY_BEGIN
+RAW
+000000007002fca4bdb400000204057e01010402
+ENTRY_END
+
+STEP 26540 QUERY
+ENTRY_BEGIN
+RAW
+b831aa875010fca487790000000000000000
+ENTRY_END
+
+STEP 26550 QUERY
+ENTRY_BEGIN
+RAW
+b831aa875018fca4dd02000000928950000000010001000000000f313138353431303937333731342d320000f900010f313138353431303937333731342d320000f900ff00000000005603677373096d6963726f736f667403636f6d00403afd22403c4ea20003000000334e544c4d535350000100000097b208e00a000a0029000000090009002000000043454445522d444331434544455244524545460000
+ENTRY_END
+
+STEP 26560 QUERY
+ENTRY_BEGIN
+RAW
+b831aa955011fc9686e40000000000000000
+ENTRY_END
+
+STEP 26570 QUERY
+ENTRY_BEGIN
+RAW
+00000000b002832c74fc0000010303010101080a11236035000000000101040202040564
+ENTRY_END
+
+STEP 26580 QUERY
+ENTRY_BEGIN
+RAW
+b8324e3480108598a35a00000101080a1123603601280812
+ENTRY_END
+
+STEP 26590 QUERY
+ENTRY_BEGIN
+RAW
+b831aa965010fc9686e30000000000000000
+ENTRY_END
+
+STEP 26600 QUERY
+ENTRY_BEGIN
+RAW
+b8324e34801885988e7200000101080a1123604b01280812008ec200000000010001000000000f313330353637303035383030322d320000f900010f313330353637303035383030322d320000f900ff00000000005203677373096d6963726f736f667403636f6d00403afc73403c4df300030000002f4e544c4d535350000100000097b208e0090009002600000006000600200000004c4150544f505745524b47524f45500000
+ENTRY_END
+
+STEP 26610 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf0747000000204056401010402
+ENTRY_END
+
+STEP 26620 QUERY
+ENTRY_BEGIN
+RAW
+b8324e4280108598a2a600000101080a1123604b01280813
+ENTRY_END
+
+STEP 26630 QUERY
+ENTRY_BEGIN
+RAW
+b8344c685010fd5c99cb0000000000000000
+ENTRY_END
+
+STEP 26640 QUERY
+ENTRY_BEGIN
+RAW
+b8344c685018fd5c25800000008e4c97000000010001000000000f313231393737303731323038322d330000f900010f313231393737303731323038322d330000f900ff00000000005203677373096d6963726f736f667403636f6d00403afde1403c4f6100030000002f4e544c4d535350000100000097b208e007000700280000000800080020000000444330314856534c4f424856534c530000
+ENTRY_END
+
+STEP 26650 QUERY
+ENTRY_BEGIN
+RAW
+b8344c765011fd4e993a0000000000000000
+ENTRY_END
+
+STEP 26660 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf063ec00000204056401010402
+ENTRY_END
+
+STEP 26670 QUERY
+ENTRY_BEGIN
+RAW
+b8344c775010fd4e99390000000000000000
+ENTRY_END
+
+STEP 26680 QUERY
+ENTRY_BEGIN
+RAW
+b83533955010fd5ca2190000000000000000
+ENTRY_END
+
+STEP 26690 QUERY
+ENTRY_BEGIN
+RAW
+b83533955018fd5c53880000008e27de000000010001000000000f313231393737303731323038322d320000f900010f313231393737303731323038322d320000f900ff00000000005203677373096d6963726f736f667403636f6d00403afde1403c4f6100030000002f4e544c4d535350000100000097b208e007000700280000000800080020000000444330314856534c4f424856534c530000
+ENTRY_END
+
+STEP 26700 QUERY
+ENTRY_BEGIN
+RAW
+b83533a35011fd4ea1880000000000000000
+ENTRY_END
+
+STEP 26710 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf0873e00000204056401010402
+ENTRY_END
+
+STEP 26720 QUERY
+ENTRY_BEGIN
+RAW
+b83533a45010fd4ea1870000000000000000
+ENTRY_END
+
+STEP 26730 QUERY
+ENTRY_BEGIN
+RAW
+b835f3265010fd5c05da0000000000000000
+ENTRY_END
+
+STEP 26740 QUERY
+ENTRY_BEGIN
+RAW
+b835f3265018fd5c0b910000008ed395000000010001000000000f313231393737303731323038322d320000f900010f313231393737303731323038322d320000f900ff00000000005203677373096d6963726f736f667403636f6d00403afde1403c4f6100030000002f4e544c4d535350000100000097b208e007000700280000000800080020000000444330314856534c4f424856534c530000
+ENTRY_END
+
+STEP 26750 QUERY
+ENTRY_BEGIN
+RAW
+b835f3345011fd4e05490000000000000000
+ENTRY_END
+
+STEP 26760 QUERY
+ENTRY_BEGIN
+RAW
+b835f3355010fd4e05480000000000000000
+ENTRY_END
+
+STEP 26770 QUERY
+ENTRY_BEGIN
+RAW
+b8324e4280118598a25e00000101080a1123609201280813
+ENTRY_END
+
+STEP 26780 QUERY
+ENTRY_BEGIN
+RAW
+b8324e4380108598a25b00000101080a1123609301280814
+ENTRY_END
+
+STEP 26790 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf06f4c0000020405b401010402
+ENTRY_END
+
+STEP 26800 QUERY
+ENTRY_BEGIN
+RAW
+b83838215010faf0aba60000000000000000
+ENTRY_END
+
+STEP 26810 QUERY
+ENTRY_BEGIN
+RAW
+b83838215018faf04ae500000088c200000000010001000000000f313432353932393134323239302d330000f900010f313432353932393134323239302d330000f900ff00000000004c03677373096d6963726f736f667403636f6d00403afe84403c50040003000000294e544c4d535350000100000097b208e0030003002600000006000600200000005345525645524442470000
+ENTRY_END
+
+STEP 26820 QUERY
+ENTRY_BEGIN
+RAW
+b838382f5011fae2ab1b0000000000000000
+ENTRY_END
+
+STEP 26830 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf09b570000020405b401010402
+ENTRY_END
+
+STEP 26840 QUERY
+ENTRY_BEGIN
+RAW
+b83838305010fae2ab1a0000000000000000
+ENTRY_END
+
+STEP 26850 QUERY
+ENTRY_BEGIN
+RAW
+b83916d95010faf0f8f80000000000000000
+ENTRY_END
+
+STEP 26860 QUERY
+ENTRY_BEGIN
+RAW
+b83916d95018faf0b1dc00000088a95c000000010001000000000f313432353932393134323239302d320000f900010f313432353932393134323239302d320000f900ff00000000004c03677373096d6963726f736f667403636f6d00403afe84403c50040003000000294e544c4d535350000100000097b208e0030003002600000006000600200000005345525645524442470000
+ENTRY_END
+
+STEP 26870 QUERY
+ENTRY_BEGIN
+RAW
+b83916e75011fae2f86d0000000000000000
+ENTRY_END
+
+STEP 26880 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf0b4fb0000020405b401010402
+ENTRY_END
+
+STEP 26890 QUERY
+ENTRY_BEGIN
+RAW
+b83916e85010fae2f86c0000000000000000
+ENTRY_END
+
+STEP 26900 QUERY
+ENTRY_BEGIN
+RAW
+b83af3e45010faf035900000000000000000
+ENTRY_END
+
+STEP 26910 QUERY
+ENTRY_BEGIN
+RAW
+b83af3e45018faf02fd0000000886800000000010001000000000f313432353932393134323239302d320000f900010f313432353932393134323239302d320000f900ff00000000004c03677373096d6963726f736f667403636f6d00403afe84403c50040003000000294e544c4d535350000100000097b208e0030003002600000006000600200000005345525645524442470000
+ENTRY_END
+
+STEP 26920 QUERY
+ENTRY_BEGIN
+RAW
+b83af3f25011fae235050000000000000000
+ENTRY_END
+
+STEP 26930 QUERY
+ENTRY_BEGIN
+RAW
+b83af3f35010fae235040000000000000000
+ENTRY_END
+
+STEP 26940 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000796d00000204057a01010402
+ENTRY_END
+
+STEP 26950 QUERY
+ENTRY_BEGIN
+RAW
+b83be921501041b802d20000000000000000
+ENTRY_END
+
+STEP 26960 QUERY
+ENTRY_BEGIN
+RAW
+b83be921501841b8a70b0000008e5fe8000000010001000000000f313034373937323032303234322d330000f900010f313034373937323032303234322d330000f900ff00000000005203677373096d6963726f736f667403636f6d00403a9d42403beec200030000002f4e544c4d535350000100000097b200e0090009002600000006000600200000004144455749544152494544455749540000
+ENTRY_END
+
+STEP 26970 QUERY
+ENTRY_BEGIN
+RAW
+b83be92f501141aa02410000000000000000
+ENTRY_END
+
+STEP 26980 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000882000000204057a01010402
+ENTRY_END
+
+STEP 26990 QUERY
+ENTRY_BEGIN
+RAW
+b83be930501041aa02400000000000000000
+ENTRY_END
+
+STEP 27000 QUERY
+ENTRY_BEGIN
+RAW
+b83cde58501041b81c4d0000000000000000
+ENTRY_END
+
+STEP 27010 QUERY
+ENTRY_BEGIN
+RAW
+b83cde58501841b844490000008edd26000000010001000000000f313034373937323032303234322d320000f900010f313034373937323032303234322d320000f900ff00000000005203677373096d6963726f736f667403636f6d00403a9d42403beec200030000002f4e544c4d535350000100000097b200e0090009002600000006000600200000004144455749544152494544455749540000
+ENTRY_END
+
+STEP 27020 QUERY
+ENTRY_BEGIN
+RAW
+b83cde66501141aa1bbc0000000000000000
+ENTRY_END
+
+STEP 27030 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000f57d00000204057a01010402
+ENTRY_END
+
+STEP 27040 QUERY
+ENTRY_BEGIN
+RAW
+b83cde67501041aa1bbb0000000000000000
+ENTRY_END
+
+STEP 27050 QUERY
+ENTRY_BEGIN
+RAW
+b83db28d501041b8b5740000000000000000
+ENTRY_END
+
+STEP 27060 QUERY
+ENTRY_BEGIN
+RAW
+b83db28d501841b830130000008e8a84000000010001000000000f313034373937323032303234322d320000f900010f313034373937323032303234322d320000f900ff00000000005203677373096d6963726f736f667403636f6d00403a9d42403beec200030000002f4e544c4d535350000100000097b200e0090009002600000006000600200000004144455749544152494544455749540000
+ENTRY_END
+
+STEP 27070 QUERY
+ENTRY_BEGIN
+RAW
+b83db29b501141aab4e30000000000000000
+ENTRY_END
+
+STEP 27080 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000dd470000020405b401010402
+ENTRY_END
+
+STEP 27090 QUERY
+ENTRY_BEGIN
+RAW
+b83db29c501041aab4e20000000000000000
+ENTRY_END
+
+STEP 27100 QUERY
+ENTRY_BEGIN
+RAW
+b83e9b2e50104470b21e0000000000000000
+ENTRY_END
+
+STEP 27110 QUERY
+ENTRY_BEGIN
+RAW
+b83e9b2e50184470d9ec0000008e0c44000000010001000000000f313131363639313439363937382d330000f900010f313131363639313439363937382d330000f900ff00000000005203677373096d6963726f736f667403636f6d00403afd23403c4ea300030000002f4e544c4d535350000100000097b200c009000900260000000600060020000000544f544f524f434f524e574f524c440000
+ENTRY_END
+
+STEP 27120 QUERY
+ENTRY_BEGIN
+RAW
+b83e9b3c50114462b18d0000000000000000
+ENTRY_END
+
+STEP 27130 QUERY
+ENTRY_BEGIN
+RAW
+b83e9b3d50104462b18c0000000000000000
+ENTRY_END
+
+STEP 27140 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000e2d50000020405b401010402
+ENTRY_END
+
+STEP 27150 QUERY
+ENTRY_BEGIN
+RAW
+b83f3c0b5010447016cf0000000000000000
+ENTRY_END
+
+STEP 27160 QUERY
+ENTRY_BEGIN
+RAW
+b83f3c0b50184470e4e30000008e66fe000000010001000000000f313131363639313439363937382d320000f900010f313131363639313439363937382d320000f900ff00000000005203677373096d6963726f736f667403636f6d00403afd23403c4ea300030000002f4e544c4d535350000100000097b200c009000900260000000600060020000000544f544f524f434f524e574f524c440000
+ENTRY_END
+
+STEP 27170 QUERY
+ENTRY_BEGIN
+RAW
+b83f3c1950114462163e0000000000000000
+ENTRY_END
+
+STEP 27180 QUERY
+ENTRY_BEGIN
+RAW
+b83f3c1a50104462163d0000000000000000
+ENTRY_END
+
+STEP 27190 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000a9590000020405b401010402
+ENTRY_END
+
+STEP 27200 QUERY
+ENTRY_BEGIN
+RAW
+b841d41050104470454b0000000000000000
+ENTRY_END
+
+STEP 27210 QUERY
+ENTRY_BEGIN
+RAW
+b841d41050184470b8a50000008ec1b8000000010001000000000f313131363639313439363937382d320000f900010f313131363639313439363937382d320000f900ff00000000005203677373096d6963726f736f667403636f6d00403afd23403c4ea300030000002f4e544c4d535350000100000097b200c009000900260000000600060020000000544f544f524f434f524e574f524c440000
+ENTRY_END
+
+STEP 27220 QUERY
+ENTRY_BEGIN
+RAW
+b841d41e5011446244ba0000000000000000
+ENTRY_END
+
+STEP 27230 QUERY
+ENTRY_BEGIN
+RAW
+b841d41f5010446244b90000000000000000
+ENTRY_END
+
+STEP 27240 QUERY
+ENTRY_BEGIN
+RAW
+00000000b002832c6d8b0000010303010101080a11236100000000000101040202040564
+ENTRY_END
+
+STEP 27250 QUERY
+ENTRY_BEGIN
+RAW
+b843dd9f801085980c6800000101080a1123610101280817
+ENTRY_END
+
+STEP 27260 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf043bb0000020405b401010402
+ENTRY_END
+
+STEP 27270 QUERY
+ENTRY_BEGIN
+RAW
+b843dd9f801885981a0800000101080a1123610e01280817008e9b80000000010001000000000f313330353637303035383030322d320000f900010f313330353637303035383030322d320000f900ff00000000005203677373096d6963726f736f667403636f6d00403afc75403c4df500030000002f4e544c4d535350000100000097b208e0090009002600000006000600200000004c4150544f505745524b47524f45500000
+ENTRY_END
+
+STEP 27280 QUERY
+ENTRY_BEGIN
+RAW
+b843ddad801085980bbd00000101080a1123610e01280817
+ENTRY_END
+
+STEP 27290 QUERY
+ENTRY_BEGIN
+RAW
+b843ddad801185980b7b00000101080a1123614f01280817
+ENTRY_END
+
+STEP 27300 QUERY
+ENTRY_BEGIN
+RAW
+b843ddae801085980b7900000101080a1123614f01280818
+ENTRY_END
+
+STEP 27310 QUERY
+ENTRY_BEGIN
+RAW
+00000000700240006bdd0000020405b401010402
+ENTRY_END
+
+STEP 27320 QUERY
+ENTRY_BEGIN
+RAW
+b84c97eb5010447043e90000000000000000
+ENTRY_END
+
+STEP 27330 QUERY
+ENTRY_BEGIN
+RAW
+b84c97eb50184470cee50000008b150c000000010001000000000f313133333837313336363136322d330000f900010f313133333837313336363136322d330000f900ff00000000004f03677373096d6963726f736f667403636f6d00403afd28403c4ea800030000002c4e544c4d535350000100000097b200e0050005002700000007000700200000005348494e4530315348494e450000
+ENTRY_END
+
+STEP 27340 QUERY
+ENTRY_BEGIN
+RAW
+b84c97f950114462435b0000000000000000
+ENTRY_END
+
+STEP 27350 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400088fe0000020405b401010402
+ENTRY_END
+
+STEP 27360 QUERY
+ENTRY_BEGIN
+RAW
+b84c97fa50104462435a0000000000000000
+ENTRY_END
+
+STEP 27370 QUERY
+ENTRY_BEGIN
+RAW
+b84d1a6450104470de900000000000000000
+ENTRY_END
+
+STEP 27380 QUERY
+ENTRY_BEGIN
+RAW
+b84d1a645018447024660000008b5b34000000010001000000000f313133333837313336363136322d320000f900010f313133333837313336363136322d320000f900ff00000000004f03677373096d6963726f736f667403636f6d00403afd28403c4ea800030000002c4e544c4d535350000100000097b200e0050005002700000007000700200000005348494e4530315348494e450000
+ENTRY_END
+
+STEP 27390 QUERY
+ENTRY_BEGIN
+RAW
+b84d1a7250114462de020000000000000000
+ENTRY_END
+
+STEP 27400 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400086c40000020405b401010402
+ENTRY_END
+
+STEP 27410 QUERY
+ENTRY_BEGIN
+RAW
+b84d1a7350104462de010000000000000000
+ENTRY_END
+
+STEP 27420 QUERY
+ENTRY_BEGIN
+RAW
+b84df49e50104470021c0000000000000000
+ENTRY_END
+
+STEP 27430 QUERY
+ENTRY_BEGIN
+RAW
+b84df49e5018447001c90000008ba15c000000010001000000000f313133333837313336363136322d320000f900010f313133333837313336363136322d320000f900ff00000000004f03677373096d6963726f736f667403636f6d00403afd28403c4ea800030000002c4e544c4d535350000100000097b200e0050005002700000007000700200000005348494e4530315348494e450000
+ENTRY_END
+
+STEP 27440 QUERY
+ENTRY_BEGIN
+RAW
+b84df4ac50114462018e0000000000000000
+ENTRY_END
+
+STEP 27450 QUERY
+ENTRY_BEGIN
+RAW
+b84df4ad50104462018d0000000000000000
+ENTRY_END
+
+STEP 27460 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf0205200000204057a01010402
+ENTRY_END
+
+STEP 27470 QUERY
+ENTRY_BEGIN
+RAW
+b8501b4d5010fbec78320000000000000000
+ENTRY_END
+
+STEP 27480 QUERY
+ENTRY_BEGIN
+RAW
+b8501b4d5018fbec917400000089a7cd000000010001000000000e3932373731323933353935342d330000f900010e3932373731323933353935342d330000f900ff00000000004f03677373096d6963726f736f667403636f6d00403afd09403c4e8900030000002c4e544c4d535350000100000097b208e0050005002700000007000700200000004a5550495445525a494348540000
+ENTRY_END
+
+STEP 27490 QUERY
+ENTRY_BEGIN
+RAW
+b8501b5b5011fbde77a60000000000000000
+ENTRY_END
+
+STEP 27500 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf0503500000204057a01010402
+ENTRY_END
+
+STEP 27510 QUERY
+ENTRY_BEGIN
+RAW
+b8501b5c5010fbde77a50000000000000000
+ENTRY_END
+
+STEP 27520 QUERY
+ENTRY_BEGIN
+RAW
+b850aee15010fbec14810000000000000000
+ENTRY_END
+
+STEP 27530 QUERY
+ENTRY_BEGIN
+RAW
+b850aee15018fbecf3a500000089e3ea000000010001000000000e3932373731323933353935342d320000f900010e3932373731323933353935342d320000f900ff00000000004f03677373096d6963726f736f667403636f6d00403afd09403c4e8900030000002c4e544c4d535350000100000097b208e0050005002700000007000700200000004a5550495445525a494348540000
+ENTRY_END
+
+STEP 27540 QUERY
+ENTRY_BEGIN
+RAW
+b850aeef5011fbde13f50000000000000000
+ENTRY_END
+
+STEP 27550 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf05e3000000204057a01010402
+ENTRY_END
+
+STEP 27560 QUERY
+ENTRY_BEGIN
+RAW
+b850aef05010fbde13f40000000000000000
+ENTRY_END
+
+STEP 27570 QUERY
+ENTRY_BEGIN
+RAW
+b8519e465010fbec33160000000000000000
+ENTRY_END
+
+STEP 27580 QUERY
+ENTRY_BEGIN
+RAW
+b8519e465018fbec89db000000896c4a000000010001000000000e3932373731323933353935342d320000f900010e3932373731323933353935342d320000f900ff00000000004f03677373096d6963726f736f667403636f6d00403afd09403c4e8900030000002c4e544c4d535350000100000097b208e0050005002700000007000700200000004a5550495445525a494348540000
+ENTRY_END
+
+STEP 27590 QUERY
+ENTRY_BEGIN
+RAW
+b8519e545011fbde328a0000000000000000
+ENTRY_END
+
+STEP 27600 QUERY
+ENTRY_BEGIN
+RAW
+b8519e555010fbde32890000000000000000
+ENTRY_END
+
+STEP 27610 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000fee80000020405b401010402
+ENTRY_END
+
+STEP 27620 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf0e84d00000204059801010402
+ENTRY_END
+
+STEP 27630 QUERY
+ENTRY_BEGIN
+RAW
+b8557ee25010fbb8dce50000000000000000
+ENTRY_END
+
+STEP 27640 QUERY
+ENTRY_BEGIN
+RAW
+b854aa3250104470c4a50000000000000000
+ENTRY_END
+
+STEP 27650 QUERY
+ENTRY_BEGIN
+RAW
+b854aa32501844703b560000008e31a0000000010001000000000f313238383439303138383831382d330000f900010f313238383439303138383831382d330000f900ff00000000005203677373096d6963726f736f667403636f6d00403afce5403c4e6500030000002f4e544c4d535350000100000097b200e00800080027000000070007002000000047454c44455232494e5445524e45540000
+ENTRY_END
+
+STEP 27660 QUERY
+ENTRY_BEGIN
+RAW
+b8557ee25018fbb819b500000094158a000000010001000000000f313231393737303731323038322d330000f900010f313231393737303731323038322d330000f900ff00000000005803677373096d6963726f736f667403636f6d00403af92f403c4aaf0003000000354e544c4d535350000100000097b208e0080008002d0000000d000d00200000005345525645522d434f4d5041514b4545524b4144450000
+ENTRY_END
+
+STEP 27670 QUERY
+ENTRY_BEGIN
+RAW
+b8557ef05011fbaadc4e0000000000000000
+ENTRY_END
+
+STEP 27680 QUERY
+ENTRY_BEGIN
+RAW
+b854aa4050114462c4140000000000000000
+ENTRY_END
+
+STEP 27690 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000f6150000020405b401010402
+ENTRY_END
+
+STEP 27700 QUERY
+ENTRY_BEGIN
+RAW
+b8557ef15010fbaadc4d0000000000000000
+ENTRY_END
+
+STEP 27710 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf0a5b400000204059801010402
+ENTRY_END
+
+STEP 27720 QUERY
+ENTRY_BEGIN
+RAW
+b856f8ee5010fbb8203f0000000000000000
+ENTRY_END
+
+STEP 27730 QUERY
+ENTRY_BEGIN
+RAW
+b854aa4150104462c4130000000000000000
+ENTRY_END
+
+STEP 27740 QUERY
+ENTRY_BEGIN
+RAW
+b85652805010447013830000000000000000
+ENTRY_END
+
+STEP 27750 QUERY
+ENTRY_BEGIN
+RAW
+b856f8ee5018fbb8972200000094dc76000000010001000000000f313231393737303731323038322d320000f900010f313231393737303731323038322d320000f900ff00000000005803677373096d6963726f736f667403636f6d00403af92f403c4aaf0003000000354e544c4d535350000100000097b208e0080008002d0000000d000d00200000005345525645522d434f4d5041514b4545524b4144450000
+ENTRY_END
+
+STEP 27760 QUERY
+ENTRY_BEGIN
+RAW
+b8565280501844705c5c0000008e6078000000010001000000000f313238383439303138383831382d320000f900010f313238383439303138383831382d320000f900ff00000000005203677373096d6963726f736f667403636f6d00403afce5403c4e6500030000002f4e544c4d535350000100000097b200e00800080027000000070007002000000047454c44455232494e5445524e45540000
+ENTRY_END
+
+STEP 27770 QUERY
+ENTRY_BEGIN
+RAW
+b856f8fc5011fbaa1fa80000000000000000
+ENTRY_END
+
+STEP 27780 QUERY
+ENTRY_BEGIN
+RAW
+b856528e5011446212f20000000000000000
+ENTRY_END
+
+STEP 27790 QUERY
+ENTRY_BEGIN
+RAW
+b856f8fd5010fbaa1fa70000000000000000
+ENTRY_END
+
+STEP 27800 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000d2440000020405b401010402
+ENTRY_END
+
+STEP 27810 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf0e5ea00000204059801010402
+ENTRY_END
+
+STEP 27820 QUERY
+ENTRY_BEGIN
+RAW
+b856528f5010446212f10000000000000000
+ENTRY_END
+
+STEP 27830 QUERY
+ENTRY_BEGIN
+RAW
+b8583c905010fbb81cd20000000000000000
+ENTRY_END
+
+STEP 27840 QUERY
+ENTRY_BEGIN
+RAW
+b857977e50104470aab20000000000000000
+ENTRY_END
+
+STEP 27850 QUERY
+ENTRY_BEGIN
+RAW
+b857977e50184470f99f0000008e5a64000000010001000000000f313238383439303138383831382d320000f900010f313238383439303138383831382d320000f900ff00000000005203677373096d6963726f736f667403636f6d00403afce5403c4e6500030000002f4e544c4d535350000100000097b200e00800080027000000070007002000000047454c44455232494e5445524e45540000
+ENTRY_END
+
+STEP 27860 QUERY
+ENTRY_BEGIN
+RAW
+b8583c905018fbb876ff00000094f92c000000010001000000000f313231393737303731323038322d320000f900010f313231393737303731323038322d320000f900ff00000000005803677373096d6963726f736f667403636f6d00403af92f403c4aaf0003000000354e544c4d535350000100000097b208e0080008002d0000000d000d00200000005345525645522d434f4d5041514b4545524b4144450000
+ENTRY_END
+
+STEP 27870 QUERY
+ENTRY_BEGIN
+RAW
+b8583c9e5011fbaa1c3b0000000000000000
+ENTRY_END
+
+STEP 27880 QUERY
+ENTRY_BEGIN
+RAW
+b857978c50114462aa210000000000000000
+ENTRY_END
+
+STEP 27890 QUERY
+ENTRY_BEGIN
+RAW
+b8583c9f5010fbaa1c3a0000000000000000
+ENTRY_END
+
+STEP 27900 QUERY
+ENTRY_BEGIN
+RAW
+b857978d50104462aa200000000000000000
+ENTRY_END
+
+STEP 27910 QUERY
+ENTRY_BEGIN
+RAW
+000000007002223853ff00000204057801010402
+ENTRY_END
+
+STEP 27920 QUERY
+ENTRY_BEGIN
+RAW
+b85a8a295010264839e30000000000000000
+ENTRY_END
+
+STEP 27930 QUERY
+ENTRY_BEGIN
+RAW
+b85a8a2950182648986c0000008d7000000000010001000000000f313133333837313336363136322d330000f900010f313133333837313336363136322d330000f900ff00000000005103677373096d6963726f736f667403636f6d00403afcd7403c4e5700030000002e4e544c4d535350000100000097b200e0080008002600000006000600200000005345525645524e4b4f45524945520000
+ENTRY_END
+
+STEP 27940 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf02bcb0000020405b401010402
+ENTRY_END
+
+STEP 27950 QUERY
+ENTRY_BEGIN
+RAW
+b85a8a375011263a39530000000000000000
+ENTRY_END
+
+STEP 27960 QUERY
+ENTRY_BEGIN
+RAW
+b85b16615010faf089c20000000000000000
+ENTRY_END
+
+STEP 27970 QUERY
+ENTRY_BEGIN
+RAW
+00000000700222384d0d00000204057801010402
+ENTRY_END
+
+STEP 27980 QUERY
+ENTRY_BEGIN
+RAW
+b85b16615018faf0b5f40000009ba618000000010001000000000f313138353431303937333731342d330000f900010f313138353431303937333731342d330000f900ff00000000005f03677373096d6963726f736f667403636f6d00403af563403c46e300030000003c4e544c4d535350000100000097b208e00d000d002f0000000f000f0020000000474f52494e4348454d324b2d5342535656562d474f52494e4348454d0000
+ENTRY_END
+
+STEP 27990 QUERY
+ENTRY_BEGIN
+RAW
+b85b166f5011fae289240000000000000000
+ENTRY_END
+
+STEP 28000 QUERY
+ENTRY_BEGIN
+RAW
+b85b16705010fae289230000000000000000
+ENTRY_END
+
+STEP 28010 QUERY
+ENTRY_BEGIN
+RAW
+b85a8a385010263a39520000000000000000
+ENTRY_END
+
+STEP 28020 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf087d30000020405b401010402
+ENTRY_END
+
+STEP 28030 QUERY
+ENTRY_BEGIN
+RAW
+b85bdfe450102648dd340000000000000000
+ENTRY_END
+
+STEP 28040 QUERY
+ENTRY_BEGIN
+RAW
+b85cb74e5010faf044dc0000000000000000
+ENTRY_END
+
+STEP 28050 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400075820000020405b401010402
+ENTRY_END
+
+STEP 28060 QUERY
+ENTRY_BEGIN
+RAW
+b85cb74e5018faf0b5e70000009b6240000000010001000000000f313138353431303937333731342d320000f900010f313138353431303937333731342d320000f900ff00000000005f03677373096d6963726f736f667403636f6d00403af563403c46e300030000003c4e544c4d535350000100000097b208e00d000d002f0000000f000f0020000000474f52494e4348454d324b2d5342535656562d474f52494e4348454d0000
+ENTRY_END
+
+STEP 28070 QUERY
+ENTRY_BEGIN
+RAW
+b85bdfe4501826489cbf0000008d1000000000010001000000000f313133333837313336363136322d320000f900010f313133333837313336363136322d320000f900ff00000000005103677373096d6963726f736f667403636f6d00403afcd7403c4e5700030000002e4e544c4d535350000100000097b200e0080008002600000006000600200000005345525645524e4b4f45524945520000
+ENTRY_END
+
+STEP 28080 QUERY
+ENTRY_BEGIN
+RAW
+b85cb75c5011fae2443e0000000000000000
+ENTRY_END
+
+STEP 28090 QUERY
+ENTRY_BEGIN
+RAW
+b85d4c1f5010447099490000000000000000
+ENTRY_END
+
+STEP 28100 QUERY
+ENTRY_BEGIN
+RAW
+b85d4c1f5018447060e70000008aa150000000010001000000000e3931303533333036363737302d330000f900010e3931303533333036363737302d330000f900ff00000000005003677373096d6963726f736f667403636f6d00403afd59403c4ed900030000002d4e544c4d535350000100000097b200c00b000b002200000002000200200000004153544543484e4f50414e454c0000
+ENTRY_END
+
+STEP 28110 QUERY
+ENTRY_BEGIN
+RAW
+b85cb75d5010fae2443d0000000000000000
+ENTRY_END
+
+STEP 28120 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf03cb70000020405b401010402
+ENTRY_END
+
+STEP 28130 QUERY
+ENTRY_BEGIN
+RAW
+b85dec5d5010faf0c4af0000000000000000
+ENTRY_END
+
+STEP 28140 QUERY
+ENTRY_BEGIN
+RAW
+b85d4c2d5011446298bc0000000000000000
+ENTRY_END
+
+STEP 28150 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000dacd0000020405b401010402
+ENTRY_END
+
+STEP 28160 QUERY
+ENTRY_BEGIN
+RAW
+b85dec5d5018faf08a890000009b0d72000000010001000000000f313138353431303937333731342d320000f900010f313138353431303937333731342d320000f900ff00000000005f03677373096d6963726f736f667403636f6d00403af563403c46e300030000003c4e544c4d535350000100000097b208e00d000d002f0000000f000f0020000000474f52494e4348454d324b2d5342535656562d474f52494e4348454d0000
+ENTRY_END
+
+STEP 28170 QUERY
+ENTRY_BEGIN
+RAW
+b85bdff25011263adca40000000000000000
+ENTRY_END
+
+STEP 28180 QUERY
+ENTRY_BEGIN
+RAW
+0000000070022238441700000204057801010402
+ENTRY_END
+
+STEP 28190 QUERY
+ENTRY_BEGIN
+RAW
+b85dec6b5011fae2c4110000000000000000
+ENTRY_END
+
+STEP 28200 QUERY
+ENTRY_BEGIN
+RAW
+b85d4c2e5010446298bb0000000000000000
+ENTRY_END
+
+STEP 28210 QUERY
+ENTRY_BEGIN
+RAW
+b85ec015501044708a9d0000000000000000
+ENTRY_END
+
+STEP 28220 QUERY
+ENTRY_BEGIN
+RAW
+b85dec6c5010fae2c4100000000000000000
+ENTRY_END
+
+STEP 28230 QUERY
+ENTRY_BEGIN
+RAW
+b85ec0155018447027ef0000008acd9c000000010001000000000e3931303533333036363737302d320000f900010e3931303533333036363737302d320000f900ff00000000005003677373096d6963726f736f667403636f6d00403afd59403c4ed900030000002d4e544c4d535350000100000097b200c00b000b002200000002000200200000004153544543484e4f50414e454c0000
+ENTRY_END
+
+STEP 28240 QUERY
+ENTRY_BEGIN
+RAW
+b85bdff35010263adca30000000000000000
+ENTRY_END
+
+STEP 28250 QUERY
+ENTRY_BEGIN
+RAW
+b85ec023501144628a100000000000000000
+ENTRY_END
+
+STEP 28260 QUERY
+ENTRY_BEGIN
+RAW
+b85f89fe501026482a210000000000000000
+ENTRY_END
+
+STEP 28270 QUERY
+ENTRY_BEGIN
+RAW
+00000000700240007f700000020405b401010402
+ENTRY_END
+
+STEP 28280 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400035fd0000020405b401010402
+ENTRY_END
+
+STEP 28290 QUERY
+ENTRY_BEGIN
+RAW
+b860b22450104470f3bb0000000000000000
+ENTRY_END
+
+STEP 28300 QUERY
+ENTRY_BEGIN
+RAW
+b85ec024501044628a0f0000000000000000
+ENTRY_END
+
+STEP 28310 QUERY
+ENTRY_BEGIN
+RAW
+b85f89fe50182648b9ab0000008d4000000000010001000000000f313133333837313336363136322d320000f900010f313133333837313336363136322d320000f900ff00000000005103677373096d6963726f736f667403636f6d00403afcd7403c4e5700030000002e4e544c4d535350000100000097b200e0080008002600000006000600200000005345525645524e4b4f45524945520000
+ENTRY_END
+
+STEP 28320 QUERY
+ENTRY_BEGIN
+RAW
+b860b224501844700a5d0000008b8567000000010001000000000f313133333837313336363136322d330000f900010f313133333837313336363136322d330000f900ff00000000004f03677373096d6963726f736f667403636f6d00403afd2a403c4eaa00030000002c4e544c4d535350000100000097b200e0050005002700000007000700200000005348494e4530315348494e450000
+ENTRY_END
+
+STEP 28330 QUERY
+ENTRY_BEGIN
+RAW
+b8600c6350104470e2f00000000000000000
+ENTRY_END
+
+STEP 28340 QUERY
+ENTRY_BEGIN
+RAW
+b8600c6350184470bba00000008a903e000000010001000000000e3931303533333036363737302d320000f900010e3931303533333036363737302d320000f900ff00000000005003677373096d6963726f736f667403636f6d00403afd5a403c4eda00030000002d4e544c4d535350000100000097b200c00b000b002200000002000200200000004153544543484e4f50414e454c0000
+ENTRY_END
+
+STEP 28350 QUERY
+ENTRY_BEGIN
+RAW
+b860b23250114462f32d0000000000000000
+ENTRY_END
+
+STEP 28360 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000aa9b0000020405b401010402
+ENTRY_END
+
+STEP 28370 QUERY
+ENTRY_BEGIN
+RAW
+b860b23350104462f32c0000000000000000
+ENTRY_END
+
+STEP 28380 QUERY
+ENTRY_BEGIN
+RAW
+b8600c7150114462e2630000000000000000
+ENTRY_END
+
+STEP 28390 QUERY
+ENTRY_BEGIN
+RAW
+b861437f50104470d6fe0000000000000000
+ENTRY_END
+
+STEP 28400 QUERY
+ENTRY_BEGIN
+RAW
+b861437f50184470a8780000008bcb8f000000010001000000000f313133333837313336363136322d320000f900010f313133333837313336363136322d320000f900ff00000000004f03677373096d6963726f736f667403636f6d00403afd2a403c4eaa00030000002c4e544c4d535350000100000097b200e0050005002700000007000700200000005348494e4530315348494e450000
+ENTRY_END
+
+STEP 28410 QUERY
+ENTRY_BEGIN
+RAW
+b85f8a0c5011263a29910000000000000000
+ENTRY_END
+
+STEP 28420 QUERY
+ENTRY_BEGIN
+RAW
+b861438d50114462d6700000000000000000
+ENTRY_END
+
+STEP 28430 QUERY
+ENTRY_BEGIN
+RAW
+b8600c7250104462e2620000000000000000
+ENTRY_END
+
+STEP 28440 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000229f0000020405b401010402
+ENTRY_END
+
+STEP 28450 QUERY
+ENTRY_BEGIN
+RAW
+b861438e50104462d66f0000000000000000
+ENTRY_END
+
+STEP 28460 QUERY
+ENTRY_BEGIN
+RAW
+b863aebd50104470e3c10000000000000000
+ENTRY_END
+
+STEP 28470 QUERY
+ENTRY_BEGIN
+RAW
+b85f8a0d5010263a29900000000000000000
+ENTRY_END
+
+STEP 28480 QUERY
+ENTRY_BEGIN
+RAW
+b863aebd501844706f140000008b11b7000000010001000000000f313133333837313336363136322d320000f900010f313133333837313336363136322d320000f900ff00000000004f03677373096d6963726f736f667403636f6d00403afd2a403c4eaa00030000002c4e544c4d535350000100000097b200e0050005002700000007000700200000005348494e4530315348494e450000
+ENTRY_END
+
+STEP 28490 QUERY
+ENTRY_BEGIN
+RAW
+b863aecb50114462e3330000000000000000
+ENTRY_END
+
+STEP 28500 QUERY
+ENTRY_BEGIN
+RAW
+b863aecc50104462e3320000000000000000
+ENTRY_END
+
+STEP 28510 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf0e1130000020405b401010402
+ENTRY_END
+
+STEP 28520 QUERY
+ENTRY_BEGIN
+RAW
+b8676c6a5010faf0e8f50000000000000000
+ENTRY_END
+
+STEP 28530 QUERY
+ENTRY_BEGIN
+RAW
+b8676c6a5018faf0d99f0000008f5be8000000010001000000000f313034373937323032303234322d330000f900010f313034373937323032303234322d330000f900ff00000000005303677373096d6963726f736f667403636f6d00403afda7403c4f270003000000304e544c4d535350000100000097b208e0060006002a0000000a000a0020000000444330314148584c30324148584c30320000
+ENTRY_END
+
+STEP 28540 QUERY
+ENTRY_BEGIN
+RAW
+b8676c785011fae2e8630000000000000000
+ENTRY_END
+
+STEP 28550 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf0b9b20000020405b401010402
+ENTRY_END
+
+STEP 28560 QUERY
+ENTRY_BEGIN
+RAW
+b8676c795010fae2e8620000000000000000
+ENTRY_END
+
+STEP 28570 QUERY
+ENTRY_BEGIN
+RAW
+b8684f895010faf0de740000000000000000
+ENTRY_END
+
+STEP 28580 QUERY
+ENTRY_BEGIN
+RAW
+b8684f895018faf0a85b0000008f83ac000000010001000000000f313034373937323032303234322d320000f900010f313034373937323032303234322d320000f900ff00000000005303677373096d6963726f736f667403636f6d00403afda7403c4f270003000000304e544c4d535350000100000097b208e0060006002a0000000a000a0020000000444330314148584c30324148584c30320000
+ENTRY_END
+
+STEP 28590 QUERY
+ENTRY_BEGIN
+RAW
+b8684f975011fae2dde20000000000000000
+ENTRY_END
+
+STEP 28600 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf096770000020405b401010402
+ENTRY_END
+
+STEP 28610 QUERY
+ENTRY_BEGIN
+RAW
+b8684f985010fae2dde10000000000000000
+ENTRY_END
+
+STEP 28620 QUERY
+ENTRY_BEGIN
+RAW
+b868d4a65010faf0361c0000000000000000
+ENTRY_END
+
+STEP 28630 QUERY
+ENTRY_BEGIN
+RAW
+b868d4a65018faf0bc1c0000008fc792000000010001000000000f313034373937323032303234322d320000f900010f313034373937323032303234322d320000f900ff00000000005303677373096d6963726f736f667403636f6d00403afda7403c4f270003000000304e544c4d535350000100000097b208e0060006002a0000000a000a0020000000444330314148584c30324148584c30320000
+ENTRY_END
+
+STEP 28640 QUERY
+ENTRY_BEGIN
+RAW
+b868d4b45011fae2358a0000000000000000
+ENTRY_END
+
+STEP 28650 QUERY
+ENTRY_BEGIN
+RAW
+b868d4b55010fae235890000000000000000
+ENTRY_END
+
+STEP 28660 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf0285d0000020405b401010402
+ENTRY_END
+
+STEP 28670 QUERY
+ENTRY_BEGIN
+RAW
+b86a79785010faf0232e0000000000000000
+ENTRY_END
+
+STEP 28680 QUERY
+ENTRY_BEGIN
+RAW
+b86a79785018faf049cd0000008da9c3000000010001000000000e3839333335333139373538362d330000f900010e3839333335333139373538362d330000f900ff00000000005303677373096d6963726f736f667403636f6d00403afdb8403c4f380003000000304e544c4d535350000100000097b208e00700070029000000090009002000000050435f50494554455248414d41544e4c0000
+ENTRY_END
+
+STEP 28690 QUERY
+ENTRY_BEGIN
+RAW
+b86a79865011fae2229e0000000000000000
+ENTRY_END
+
+STEP 28700 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf025ca0000020405b401010402
+ENTRY_END
+
+STEP 28710 QUERY
+ENTRY_BEGIN
+RAW
+b86a79875010fae2229d0000000000000000
+ENTRY_END
+
+STEP 28720 QUERY
+ENTRY_BEGIN
+RAW
+b86b60fc5010faf039160000000000000000
+ENTRY_END
+
+STEP 28730 QUERY
+ENTRY_BEGIN
+RAW
+b86b60fc5018faf03bd00000008dcfa8000000010001000000000e3839333335333139373538362d320000f900010e3839333335333139373538362d320000f900ff00000000005303677373096d6963726f736f667403636f6d00403afdb8403c4f380003000000304e544c4d535350000100000097b208e00700070029000000090009002000000050435f50494554455248414d41544e4c0000
+ENTRY_END
+
+STEP 28740 QUERY
+ENTRY_BEGIN
+RAW
+b86b610a5011fae238860000000000000000
+ENTRY_END
+
+STEP 28750 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf0f53f0000020405b401010402
+ENTRY_END
+
+STEP 28760 QUERY
+ENTRY_BEGIN
+RAW
+b86b610b5010fae238850000000000000000
+ENTRY_END
+
+STEP 28770 QUERY
+ENTRY_BEGIN
+RAW
+b86bf32d5010faf0765a0000000000000000
+ENTRY_END
+
+STEP 28780 QUERY
+ENTRY_BEGIN
+RAW
+b86bf32d5018faf05d640000008deb58000000010001000000000e3839333335333139373538362d320000f900010e3839333335333139373538362d320000f900ff00000000005303677373096d6963726f736f667403636f6d00403afdb8403c4f380003000000304e544c4d535350000100000097b208e00700070029000000090009002000000050435f50494554455248414d41544e4c0000
+ENTRY_END
+
+STEP 28790 QUERY
+ENTRY_BEGIN
+RAW
+b86bf33b5011fae275ca0000000000000000
+ENTRY_END
+
+STEP 28800 QUERY
+ENTRY_BEGIN
+RAW
+b86bf33c5010fae275c90000000000000000
+ENTRY_END
+
+STEP 28810 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf085460000020405b401010402
+ENTRY_END
+
+STEP 28820 QUERY
+ENTRY_BEGIN
+RAW
+b86cc7b65010fbec30db0000000000000000
+ENTRY_END
+
+STEP 28830 QUERY
+ENTRY_BEGIN
+RAW
+b86cc7b65018fbecbc930000008d0bd8000000010001000000000f313036353135313838393432362d330000f900010f313036353135313838393432362d330000f900ff00000000005103677373096d6963726f736f667403636f6d00403aff84403c510400030000002e4e544c4d535350000100000097b208e005000500290000000900090020000000494e5445524e455431454c414e320000
+ENTRY_END
+
+STEP 28840 QUERY
+ENTRY_BEGIN
+RAW
+b86cc7c45011fbde304b0000000000000000
+ENTRY_END
+
+STEP 28850 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf003060000020405b401010402
+ENTRY_END
+
+STEP 28860 QUERY
+ENTRY_BEGIN
+RAW
+b86cc7c55010fbde304a0000000000000000
+ENTRY_END
+
+STEP 28870 QUERY
+ENTRY_BEGIN
+RAW
+b86eaaeb5010fbeccb630000000000000000
+ENTRY_END
+
+STEP 28880 QUERY
+ENTRY_BEGIN
+RAW
+b86eaaeb5018fbec587d0000008d0b78000000010001000000000f313036353135313838393432362d320000f900010f313036353135313838393432362d320000f900ff00000000005103677373096d6963726f736f667403636f6d00403aff84403c510400030000002e4e544c4d535350000100000097b208e005000500290000000900090020000000494e5445524e455431454c414e320000
+ENTRY_END
+
+STEP 28890 QUERY
+ENTRY_BEGIN
+RAW
+b86eaaf95011fbdecad30000000000000000
+ENTRY_END
+
+STEP 28900 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf0d33e0000020405b401010402
+ENTRY_END
+
+STEP 28910 QUERY
+ENTRY_BEGIN
+RAW
+b86eaafa5010fbdecad20000000000000000
+ENTRY_END
+
+STEP 28920 QUERY
+ENTRY_BEGIN
+RAW
+b86f5d985010fbece8ee0000000000000000
+ENTRY_END
+
+STEP 28930 QUERY
+ENTRY_BEGIN
+RAW
+b86f5d985018fbec36500000008d4b30000000010001000000000f313036353135313838393432362d320000f900010f313036353135313838393432362d320000f900ff00000000005103677373096d6963726f736f667403636f6d00403aff84403c510400030000002e4e544c4d535350000100000097b208e005000500290000000900090020000000494e5445524e455431454c414e320000
+ENTRY_END
+
+STEP 28940 QUERY
+ENTRY_BEGIN
+RAW
+b86f5da65011fbdee85e0000000000000000
+ENTRY_END
+
+STEP 28950 QUERY
+ENTRY_BEGIN
+RAW
+b86f5da75010fbdee85d0000000000000000
+ENTRY_END
+
+STEP 28960 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000ddd30000020405b401010402
+ENTRY_END
+
+STEP 28970 QUERY
+ENTRY_BEGIN
+RAW
+b86ffc6a50104470513d0000000000000000
+ENTRY_END
+
+STEP 28980 QUERY
+ENTRY_BEGIN
+RAW
+b86ffc6a50184470fc390000009600da000000010001000000000f313233363935303538313236362d330000f900010f313233363935303538313236362d330000f900ff00000000005a03677373096d6963726f736f667403636f6d00403afd2b403c4eab0003000000374e544c4d535350000100000097b208e00a000a002d0000000d000d0020000000504443544f5047524f57455253544f5047524f574552530000
+ENTRY_END
+
+STEP 28990 QUERY
+ENTRY_BEGIN
+RAW
+b86ffc785011446250a40000000000000000
+ENTRY_END
+
+STEP 29000 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000f56e0000020405b401010402
+ENTRY_END
+
+STEP 29010 QUERY
+ENTRY_BEGIN
+RAW
+b86ffc795010446250a30000000000000000
+ENTRY_END
+
+STEP 29020 QUERY
+ENTRY_BEGIN
+RAW
+b870e1475010447083fa0000000000000000
+ENTRY_END
+
+STEP 29030 QUERY
+ENTRY_BEGIN
+RAW
+b870e147501844709691000000969a40000000010001000000000f313233363935303538313236362d320000f900010f313233363935303538313236362d320000f900ff00000000005a03677373096d6963726f736f667403636f6d00403afd2b403c4eab0003000000374e544c4d535350000100000097b208e00a000a002d0000000d000d0020000000504443544f5047524f57455253544f5047524f574552530000
+ENTRY_END
+
+STEP 29040 QUERY
+ENTRY_BEGIN
+RAW
+b870e1555011446283610000000000000000
+ENTRY_END
+
+STEP 29050 QUERY
+ENTRY_BEGIN
+RAW
+000000007002400031f30000020405b401010402
+ENTRY_END
+
+STEP 29060 QUERY
+ENTRY_BEGIN
+RAW
+b870e1565010446283600000000000000000
+ENTRY_END
+
+STEP 29070 QUERY
+ENTRY_BEGIN
+RAW
+b871b54f50104470ec750000000000000000
+ENTRY_END
+
+STEP 29080 QUERY
+ENTRY_BEGIN
+RAW
+b871b54f50184470e88c00000096b0c0000000010001000000000f313233363935303538313236362d320000f900010f313233363935303538313236362d320000f900ff00000000005a03677373096d6963726f736f667403636f6d00403afd2b403c4eab0003000000374e544c4d535350000100000097b208e00a000a002d0000000d000d0020000000504443544f5047524f57455253544f5047524f574552530000
+ENTRY_END
+
+STEP 29090 QUERY
+ENTRY_BEGIN
+RAW
+b871b55d50114462ebdc0000000000000000
+ENTRY_END
+
+STEP 29100 QUERY
+ENTRY_BEGIN
+RAW
+b871b55e50104462ebdb0000000000000000
+ENTRY_END
+
+STEP 29110 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf0225800000204055001010402
+ENTRY_END
+
+STEP 29120 QUERY
+ENTRY_BEGIN
+RAW
+b873d47b5010ff00bda80000000000000000
+ENTRY_END
+
+STEP 29130 QUERY
+ENTRY_BEGIN
+RAW
+b873d47b5018ff002785000000923da3000000010001000000000f313531313832383438383231302d330000f900010f313531313832383438383231302d330000f900ff00000000005603677373096d6963726f736f667403636f6d00403b0027403c51a70003000000334e544c4d535350000100000097b208e0090009002a0000000a000a002000000057324b5345525645523150524b564457494c440000
+ENTRY_END
+
+STEP 29140 QUERY
+ENTRY_BEGIN
+RAW
+b873d4895011fef2bd130000000000000000
+ENTRY_END
+
+STEP 29150 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf0f7480000020405b401010402
+ENTRY_END
+
+STEP 29160 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf0332200000204055001010402
+ENTRY_END
+
+STEP 29170 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf07aff0000020405b401010402
+ENTRY_END
+
+STEP 29180 QUERY
+ENTRY_BEGIN
+RAW
+b873d48a5010fef2bd120000000000000000
+ENTRY_END
+
+STEP 29190 QUERY
+ENTRY_BEGIN
+RAW
+b8756c445010ff0036a80000000000000000
+ENTRY_END
+
+STEP 29200 QUERY
+ENTRY_BEGIN
+RAW
+b8760bd75010faf0e3650000000000000000
+ENTRY_END
+
+STEP 29210 QUERY
+ENTRY_BEGIN
+RAW
+b874af045010faf0bc830000000000000000
+ENTRY_END
+
+STEP 29220 QUERY
+ENTRY_BEGIN
+RAW
+b8756c445018ff00da670000009204c1000000010001000000000f313531313832383438383231302d320000f900010f313531313832383438383231302d320000f900ff00000000005603677373096d6963726f736f667403636f6d00403b0027403c51a70003000000334e544c4d535350000100000097b208e0090009002a0000000a000a002000000057324b5345525645523150524b564457494c440000
+ENTRY_END
+
+STEP 29230 QUERY
+ENTRY_BEGIN
+RAW
+b874af045018faf097a50000009250ac000000010001000000000f313330353637303035383030322d330000f900010f313330353637303035383030322d330000f900ff00000000005603677373096d6963726f736f667403636f6d00403afd0f403c4e8f0003000000334e544c4d535350000100000097b208e0080008002b0000000b000b002000000047454d534c44573230303047454d534c44324b0000
+ENTRY_END
+
+STEP 29240 QUERY
+ENTRY_BEGIN
+RAW
+b8760bd75018faf0c670000000955c40000000010001000000000f313231393737303731323038322d330000f900010f313231393737303731323038322d330000f900ff00000000005903677373096d6963726f736f667403636f6d00403afd89403c4f090003000000364e544c4d535350000100000097b208e00b000b002b0000000b000b002000000044432d48554e54534d414e424953475645524f4c4d450000
+ENTRY_END
+
+STEP 29250 QUERY
+ENTRY_BEGIN
+RAW
+b8760be55011fae2e2cd0000000000000000
+ENTRY_END
+
+STEP 29260 QUERY
+ENTRY_BEGIN
+RAW
+b8756c525011fef236130000000000000000
+ENTRY_END
+
+STEP 29270 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf0cc390000020405b401010402
+ENTRY_END
+
+STEP 29280 QUERY
+ENTRY_BEGIN
+RAW
+b874af125011fae2bbee0000000000000000
+ENTRY_END
+
+STEP 29290 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf0865700000204055001010402
+ENTRY_END
+
+STEP 29300 QUERY
+ENTRY_BEGIN
+RAW
+b8760be65010fae2e2cc0000000000000000
+ENTRY_END
+
+STEP 29310 QUERY
+ENTRY_BEGIN
+RAW
+b87704245010faf03c520000000000000000
+ENTRY_END
+
+STEP 29320 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf0d3060000020405b401010402
+ENTRY_END
+
+STEP 29330 QUERY
+ENTRY_BEGIN
+RAW
+b8756c535010fef236120000000000000000
+ENTRY_END
+
+STEP 29340 QUERY
+ENTRY_BEGIN
+RAW
+b8778b1f5010ff006b000000000000000000
+ENTRY_END
+
+STEP 29350 QUERY
+ENTRY_BEGIN
+RAW
+b87704245018faf0c21d00000095ba80000000010001000000000f313231393737303731323038322d320000f900010f313231393737303731323038322d320000f900ff00000000005903677373096d6963726f736f667403636f6d00403afd89403c4f090003000000364e544c4d535350000100000097b208e00b000b002b0000000b000b002000000044432d48554e54534d414e424953475645524f4c4d450000
+ENTRY_END
+
+STEP 29360 QUERY
+ENTRY_BEGIN
+RAW
+b874af135010fae2bbed0000000000000000
+ENTRY_END
+
+STEP 29370 QUERY
+ENTRY_BEGIN
+RAW
+b8778b1f5018ff007616000000929d6a000000010001000000000f313531313832383438383231302d320000f900010f313531313832383438383231302d320000f900ff00000000005603677373096d6963726f736f667403636f6d00403b0027403c51a70003000000334e544c4d535350000100000097b208e0090009002a0000000a000a002000000057324b5345525645523150524b564457494c440000
+ENTRY_END
+
+STEP 29380 QUERY
+ENTRY_BEGIN
+RAW
+b87704325011fae23bba0000000000000000
+ENTRY_END
+
+STEP 29390 QUERY
+ENTRY_BEGIN
+RAW
+b8784b705010faf0fbd10000000000000000
+ENTRY_END
+
+STEP 29400 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf035460000020405b401010402
+ENTRY_END
+
+STEP 29410 QUERY
+ENTRY_BEGIN
+RAW
+b8784b705018faf060fe00000092c7a2000000010001000000000f313330353637303035383030322d320000f900010f313330353637303035383030322d320000f900ff00000000005603677373096d6963726f736f667403636f6d00403afd0f403c4e8f0003000000334e544c4d535350000100000097b208e0080008002b0000000b000b002000000047454d534c44573230303047454d534c44324b0000
+ENTRY_END
+
+STEP 29420 QUERY
+ENTRY_BEGIN
+RAW
+b8778b2d5011fef26a6b0000000000000000
+ENTRY_END
+
+STEP 29430 QUERY
+ENTRY_BEGIN
+RAW
+b87704335010fae23bb90000000000000000
+ENTRY_END
+
+STEP 29440 QUERY
+ENTRY_BEGIN
+RAW
+b878f3165010faf0b66a0000000000000000
+ENTRY_END
+
+STEP 29450 QUERY
+ENTRY_BEGIN
+RAW
+b8778b2e5010fef26a6a0000000000000000
+ENTRY_END
+
+STEP 29460 QUERY
+ENTRY_BEGIN
+RAW
+b878f3165018faf0a036000000955680000000010001000000000f313231393737303731323038322d320000f900010f313231393737303731323038322d320000f900ff00000000005903677373096d6963726f736f667403636f6d00403afd89403c4f090003000000364e544c4d535350000100000097b208e00b000b002b0000000b000b002000000044432d48554e54534d414e424953475645524f4c4d450000
+ENTRY_END
+
+STEP 29470 QUERY
+ENTRY_BEGIN
+RAW
+b8784b7e5011fae2fb3c0000000000000000
+ENTRY_END
+
+STEP 29480 QUERY
+ENTRY_BEGIN
+RAW
+b878f3245011fae2b5d20000000000000000
+ENTRY_END
+
+STEP 29490 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf0ea1e0000020405b401010402
+ENTRY_END
+
+STEP 29500 QUERY
+ENTRY_BEGIN
+RAW
+b8784b7f5010fae2fb3b0000000000000000
+ENTRY_END
+
+STEP 29510 QUERY
+ENTRY_BEGIN
+RAW
+b878f3255010fae2b5d10000000000000000
+ENTRY_END
+
+STEP 29520 QUERY
+ENTRY_BEGIN
+RAW
+b87984425010faf0da160000000000000000
+ENTRY_END
+
+STEP 29530 QUERY
+ENTRY_BEGIN
+RAW
+b87984425018faf0c84d000000923e98000000010001000000000f313330353637303035383030322d320000f900010f313330353637303035383030322d320000f900ff00000000005603677373096d6963726f736f667403636f6d00403afd0f403c4e8f0003000000334e544c4d535350000100000097b208e0080008002b0000000b000b002000000047454d534c44573230303047454d534c44324b0000
+ENTRY_END
+
+STEP 29540 QUERY
+ENTRY_BEGIN
+RAW
+b87984505011fae2d9810000000000000000
+ENTRY_END
+
+STEP 29550 QUERY
+ENTRY_BEGIN
+RAW
+b87984515010fae2d9800000000000000000
+ENTRY_END
+
+STEP 29560 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf05a680000020405b401010402
+ENTRY_END
+
+STEP 29570 QUERY
+ENTRY_BEGIN
+RAW
+b87a075c5010faf0c7450000000000000000
+ENTRY_END
+
+STEP 29580 QUERY
+ENTRY_BEGIN
+RAW
+b87a075c5018faf0598400000088bd00000000010001000000000f313432353932393134323239302d330000f900010f313432353932393134323239302d330000f900ff00000000004c03677373096d6963726f736f667403636f6d00403afe8d403c500d0003000000294e544c4d535350000100000097b208e0030003002600000006000600200000005345525645524442470000
+ENTRY_END
+
+STEP 29590 QUERY
+ENTRY_BEGIN
+RAW
+b87a076a5011fae2c6ba0000000000000000
+ENTRY_END
+
+STEP 29600 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf01b310000020405b401010402
+ENTRY_END
+
+STEP 29610 QUERY
+ENTRY_BEGIN
+RAW
+b87a076b5010fae2c6b90000000000000000
+ENTRY_END
+
+STEP 29620 QUERY
+ENTRY_BEGIN
+RAW
+b87c49885010faf045e00000000000000000
+ENTRY_END
+
+STEP 29630 QUERY
+ENTRY_BEGIN
+RAW
+b87c49885018faf02e20000000886800000000010001000000000f313432353932393134323239302d320000f900010f313432353932393134323239302d320000f900ff00000000004c03677373096d6963726f736f667403636f6d00403afe8d403c500d0003000000294e544c4d535350000100000097b208e0030003002600000006000600200000005345525645524442470000
+ENTRY_END
+
+STEP 29640 QUERY
+ENTRY_BEGIN
+RAW
+b87c49965011fae245550000000000000000
+ENTRY_END
+
+STEP 29650 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf02f960000020405b401010402
+ENTRY_END
+
+STEP 29660 QUERY
+ENTRY_BEGIN
+RAW
+b87c49975010fae245540000000000000000
+ENTRY_END
+
+STEP 29670 QUERY
+ENTRY_BEGIN
+RAW
+b87d3c4e5010faf0677e0000000000000000
+ENTRY_END
+
+STEP 29680 QUERY
+ENTRY_BEGIN
+RAW
+b87d3c4e5018faf05abe000000885b00000000010001000000000f313432353932393134323239302d320000f900010f313432353932393134323239302d320000f900ff00000000004c03677373096d6963726f736f667403636f6d00403afe8e403c500e0003000000294e544c4d535350000100000097b208e0030003002600000006000600200000005345525645524442470000
+ENTRY_END
+
+STEP 29690 QUERY
+ENTRY_BEGIN
+RAW
+b87d3c5c5011fae266f30000000000000000
+ENTRY_END
+
+STEP 29700 QUERY
+ENTRY_BEGIN
+RAW
+b87d3c5d5010fae266f20000000000000000
+ENTRY_END
+
+STEP 29710 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000eb4a0000020405b401010402
+ENTRY_END
+
+STEP 29720 QUERY
+ENTRY_BEGIN
+RAW
+b87f0582501005b494490000000000000000
+ENTRY_END
+
+STEP 29730 QUERY
+ENTRY_BEGIN
+RAW
+b87f058250184470519b0000008cc780000000010001000000000f313036353135313838393432362d330000f900010f313036353135313838393432362d330000f900ff00000000005003677373096d6963726f736f667403636f6d00403af2f9403c447900030000002d4e544c4d535350000100000097b200e0080008002500000005000500200000004c55584f52494e5445524e45540000
+ENTRY_END
+
+STEP 29740 QUERY
+ENTRY_BEGIN
+RAW
+00000000700240000e870000020405b401010402
+ENTRY_END
+
+STEP 29750 QUERY
+ENTRY_BEGIN
+RAW
+b87f97b7501005b425500000000000000000
+ENTRY_END
+
+STEP 29760 QUERY
+ENTRY_BEGIN
+RAW
+b87f97b75018447052630000008c58c0000000010001000000000f313036353135313838393432362d320000f900010f313036353135313838393432362d320000f900ff00000000005003677373096d6963726f736f667403636f6d00403af2f9403c447900030000002d4e544c4d535350000100000097b200e0080008002500000005000500200000004c55584f52494e5445524e45540000
+ENTRY_END
+
+STEP 29770 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf0bdf60000020405b401010402
+ENTRY_END
+
+STEP 29780 QUERY
+ENTRY_BEGIN
+RAW
+b8807c0e5010faf0b61b0000000000000000
+ENTRY_END
+
+STEP 29790 QUERY
+ENTRY_BEGIN
+RAW
+b8807c0e5018faf0e626000000950d40000000010001000000000f313231393737303731323038322d330000f900010f313231393737303731323038322d330000f900ff00000000005903677373096d6963726f736f667403636f6d00403afd8a403c4f0a0003000000364e544c4d535350000100000097b208e00b000b002b0000000b000b002000000044432d48554e54534d414e424953475645524f4c4d450000
+ENTRY_END
+
+STEP 29800 QUERY
+ENTRY_BEGIN
+RAW
+b8807c1c5011fae2b5830000000000000000
+ENTRY_END
+
+STEP 29810 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf0c3a40000020405b401010402
+ENTRY_END
+
+STEP 29820 QUERY
+ENTRY_BEGIN
+RAW
+b8807c1d5010fae2b5820000000000000000
+ENTRY_END
+
+STEP 29830 QUERY
+ENTRY_BEGIN
+RAW
+b88124355010faf013a20000000000000000
+ENTRY_END
+
+STEP 29840 QUERY
+ENTRY_BEGIN
+RAW
+b88124355018faf0e66d000000956b80000000010001000000000f313231393737303731323038322d320000f900010f313231393737303731323038322d320000f900ff00000000005903677373096d6963726f736f667403636f6d00403afd8a403c4f0a0003000000364e544c4d535350000100000097b208e00b000b002b0000000b000b002000000044432d48554e54534d414e424953475645524f4c4d450000
+ENTRY_END
+
+STEP 29850 QUERY
+ENTRY_BEGIN
+RAW
+b88124435011fae2130a0000000000000000
+ENTRY_END
+
+STEP 29860 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf018ba0000020405b401010402
+ENTRY_END
+
+STEP 29870 QUERY
+ENTRY_BEGIN
+RAW
+b88124445010fae213090000000000000000
+ENTRY_END
+
+STEP 29880 QUERY
+ENTRY_BEGIN
+RAW
+b881d8d95010faf0b4120000000000000000
+ENTRY_END
+
+STEP 29890 QUERY
+ENTRY_BEGIN
+RAW
+b881d8d95018faf04ede00000095a380000000010001000000000f313231393737303731323038322d320000f900010f313231393737303731323038322d320000f900ff00000000005903677373096d6963726f736f667403636f6d00403afd8a403c4f0a0003000000364e544c4d535350000100000097b208e00b000b002b0000000b000b002000000044432d48554e54534d414e424953475645524f4c4d450000
+ENTRY_END
+
+STEP 29900 QUERY
+ENTRY_BEGIN
+RAW
+b881d8e75011fae2b37a0000000000000000
+ENTRY_END
+
+STEP 29910 QUERY
+ENTRY_BEGIN
+RAW
+b881d8e85010fae2b3790000000000000000
+ENTRY_END
+
+STEP 29920 QUERY
+ENTRY_BEGIN
+RAW
+b87f97c550114462e6040000000000000000
+ENTRY_END
+
+STEP 29930 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000e5880000020405b401010402
+ENTRY_END
+
+STEP 29940 QUERY
+ENTRY_BEGIN
+RAW
+b87f97c650104462e6030000000000000000
+ENTRY_END
+
+STEP 29950 QUERY
+ENTRY_BEGIN
+RAW
+b8866f32501005b424d00000000000000000
+ENTRY_END
+
+STEP 29960 QUERY
+ENTRY_BEGIN
+RAW
+b8866f3250184470a3e30000008c04c0000000010001000000000f313036353135313838393432362d320000f900010f313036353135313838393432362d320000f900ff00000000005003677373096d6963726f736f667403636f6d00403af2fa403c447a00030000002d4e544c4d535350000100000097b200e0080008002500000005000500200000004c55584f52494e5445524e45540000
+ENTRY_END
+
+STEP 29970 QUERY
+ENTRY_BEGIN
+RAW
+b8866f4050114462e5840000000000000000
+ENTRY_END
+
+STEP 29980 QUERY
+ENTRY_BEGIN
+RAW
+b8866f4150104462e5830000000000000000
+ENTRY_END
+
+STEP 29990 QUERY
+ENTRY_BEGIN
+RAW
+000000007002ff00758500000204055001010402
+ENTRY_END
+
+STEP 30000 QUERY
+ENTRY_BEGIN
+RAW
+b8873df25010ff00ab5b0000000000000000
+ENTRY_END
+
+STEP 30010 QUERY
+ENTRY_BEGIN
+RAW
+b8873df25018ff001b780000008f5b0e000000010001000000000f313034373937323032303234322d330000f900010f313034373937323032303234322d330000f900ff00000000005303677373096d6963726f736f667403636f6d00403afe3d403c4fbd0003000000304e544c4d535350000100000097b208e0060006002a0000000a000a0020000000524f4353455256455232524f435655450000
+ENTRY_END
+
+STEP 30020 QUERY
+ENTRY_BEGIN
+RAW
+b8873e005011fef2aac90000000000000000
+ENTRY_END
+
+STEP 30030 QUERY
+ENTRY_BEGIN
+RAW
+000000007002ff001e8b00000204055001010402
+ENTRY_END
+
+STEP 30040 QUERY
+ENTRY_BEGIN
+RAW
+b8873e015010fef2aac80000000000000000
+ENTRY_END
+
+STEP 30050 QUERY
+ENTRY_BEGIN
+RAW
+b887f30b5010ff009f470000000000000000
+ENTRY_END
+
+STEP 30060 QUERY
+ENTRY_BEGIN
+RAW
+b87f05905010446254fe0000000000000000
+ENTRY_END
+
+STEP 30070 QUERY
+ENTRY_BEGIN
+RAW
+00000000700240003e080000020405b401010402
+ENTRY_END
+
+STEP 30080 QUERY
+ENTRY_BEGIN
+RAW
+b8888b9e5010447022250000000000000000
+ENTRY_END
+
+STEP 30090 QUERY
+ENTRY_BEGIN
+RAW
+b8888b9e50184470c7750000008e386c000000010001000000000e3936323037323637343332322d330000f900010e3936323037323637343332322d330000f900ff00000000005403677373096d6963726f736f667403636f6d0032f53d9532f68f150003000000314e544c4d535350000100000097b200c00b000b002600000006000600200000004d455849434f57454e4e454b45534e45540000
+ENTRY_END
+
+STEP 30100 QUERY
+ENTRY_BEGIN
+RAW
+b8888bac5011446221940000000000000000
+ENTRY_END
+
+STEP 30110 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000a7870000020405b401010402
+ENTRY_END
+
+STEP 30120 QUERY
+ENTRY_BEGIN
+RAW
+b8888bad5010446221930000000000000000
+ENTRY_END
+
+STEP 30130 QUERY
+ENTRY_BEGIN
+RAW
+b88953b450104470c38d0000000000000000
+ENTRY_END
+
+STEP 30140 QUERY
+ENTRY_BEGIN
+RAW
+b88953b450184470223e0000008e810c000000010001000000000e3936323037323637343332322d320000f900010e3936323037323637343332322d320000f900ff00000000005403677373096d6963726f736f667403636f6d0032f53d9532f68f150003000000314e544c4d535350000100000097b200c00b000b002600000006000600200000004d455849434f57454e4e454b45534e45540000
+ENTRY_END
+
+STEP 30150 QUERY
+ENTRY_BEGIN
+RAW
+b88953c250114462c2fc0000000000000000
+ENTRY_END
+
+STEP 30160 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000525e0000020405b401010402
+ENTRY_END
+
+STEP 30170 QUERY
+ENTRY_BEGIN
+RAW
+b88953c350104462c2fb0000000000000000
+ENTRY_END
+
+STEP 30180 QUERY
+ENTRY_BEGIN
+RAW
+b88b7a195010447047fd0000000000000000
+ENTRY_END
+
+STEP 30190 QUERY
+ENTRY_BEGIN
+RAW
+b88b7a195018447009840000008e1e36000000010001000000000e3936323037323637343332322d320000f900010e3936323037323637343332322d320000f900ff00000000005403677373096d6963726f736f667403636f6d0032f53d9532f68f150003000000314e544c4d535350000100000097b200c00b000b002600000006000600200000004d455849434f57454e4e454b45534e45540000
+ENTRY_END
+
+STEP 30200 QUERY
+ENTRY_BEGIN
+RAW
+b88b7a2750114462476c0000000000000000
+ENTRY_END
+
+STEP 30210 QUERY
+ENTRY_BEGIN
+RAW
+b88b7a2850104462476b0000000000000000
+ENTRY_END
+
+STEP 30220 QUERY
+ENTRY_BEGIN
+RAW
+b87f05905011446254fe0000000000000000
+ENTRY_END
+
+STEP 30230 QUERY
+ENTRY_BEGIN
+RAW
+b87f05915010446254fd0000000000000000
+ENTRY_END
+
+STEP 30240 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf089aa00000204055001010402
+ENTRY_END
+
+STEP 30250 QUERY
+ENTRY_BEGIN
+RAW
+b89059d55010ff009f840000000000000000
+ENTRY_END
+
+STEP 30260 QUERY
+ENTRY_BEGIN
+RAW
+b89059d55018ff00bd6e000000927286000000010001000000000f313436303238383838303635382d330000f900010f313436303238383838303635382d330000f900ff00000000005603677373096d6963726f736f667403636f6d00403b002b403c51ab0003000000334e544c4d535350000100000097b208e0090009002a0000000a000a002000000057324b5345525645523150524b564457494c440000
+ENTRY_END
+
+STEP 30270 QUERY
+ENTRY_BEGIN
+RAW
+b89059e35011fef29eef0000000000000000
+ENTRY_END
+
+STEP 30280 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf08e5d00000204055001010402
+ENTRY_END
+
+STEP 30290 QUERY
+ENTRY_BEGIN
+RAW
+b89059e45010fef29eee0000000000000000
+ENTRY_END
+
+STEP 30300 QUERY
+ENTRY_BEGIN
+RAW
+b89138d85010ff00c5330000000000000000
+ENTRY_END
+
+STEP 30310 QUERY
+ENTRY_BEGIN
+RAW
+b89138d85018ff00a8dc00000092adc8000000010001000000000f313436303238383838303635382d320000f900010f313436303238383838303635382d320000f900ff00000000005603677373096d6963726f736f667403636f6d00403b002b403c51ab0003000000334e544c4d535350000100000097b208e0090009002a0000000a000a002000000057324b5345525645523150524b564457494c440000
+ENTRY_END
+
+STEP 30320 QUERY
+ENTRY_BEGIN
+RAW
+b89138e65011fef2c49e0000000000000000
+ENTRY_END
+
+STEP 30330 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf0622900000204055001010402
+ENTRY_END
+
+STEP 30340 QUERY
+ENTRY_BEGIN
+RAW
+b89138e75010fef2c49d0000000000000000
+ENTRY_END
+
+STEP 30350 QUERY
+ENTRY_BEGIN
+RAW
+b893d5bc5010ff00fc180000000000000000
+ENTRY_END
+
+STEP 30360 QUERY
+ENTRY_BEGIN
+RAW
+b893d5bc5018ff004d31000000924059000000010001000000000f313436303238383838303635382d320000f900010f313436303238383838303635382d320000f900ff00000000005603677373096d6963726f736f667403636f6d00403b002b403c51ab0003000000334e544c4d535350000100000097b208e0090009002a0000000a000a002000000057324b5345525645523150524b564457494c440000
+ENTRY_END
+
+STEP 30370 QUERY
+ENTRY_BEGIN
+RAW
+b893d5ca5011fef2fb830000000000000000
+ENTRY_END
+
+STEP 30380 QUERY
+ENTRY_BEGIN
+RAW
+b893d5cb5010fef2fb820000000000000000
+ENTRY_END
+
+;STEP 30390 QUERY
+;ENTRY_BEGIN
+;RAW
+;2c4801000001000000000000056b6f726e6f026e6c00000f000100
+;ENTRY_END
+
+STEP 30400 QUERY
+ENTRY_BEGIN
+RAW
+00000000700240005b1100000204055001010402
+ENTRY_END
+
+STEP 30410 QUERY
+ENTRY_BEGIN
+RAW
+b887f30b5018ff0072d80000008ff89a000000010001000000000f313034373937323032303234322d320000f900010f313034373937323032303234322d320000f900ff00000000005303677373096d6963726f736f667403636f6d00403afe3d403c4fbd0003000000304e544c4d535350000100000097b208e0060006002a0000000a000a0020000000524f4353455256455232524f435655450000
+ENTRY_END
+
+STEP 30420 QUERY
+ENTRY_BEGIN
+RAW
+b887f3195011fef29eb50000000000000000
+ENTRY_END
+
+STEP 30430 QUERY
+ENTRY_BEGIN
+RAW
+000000007002ff00e15100000204055001010402
+ENTRY_END
+
+STEP 30440 QUERY
+ENTRY_BEGIN
+RAW
+b887f31a5010fef29eb40000000000000000
+ENTRY_END
+
+STEP 30450 QUERY
+ENTRY_BEGIN
+RAW
+b8971ae65010ff003a240000000000000000
+ENTRY_END
+
+STEP 30460 QUERY
+ENTRY_BEGIN
+RAW
+b8971ae65018ff00a9f90000008f5656000000010001000000000f313034373937323032303234322d320000f900010f313034373937323032303234322d320000f900ff00000000005303677373096d6963726f736f667403636f6d00403afe40403c4fc00003000000304e544c4d535350000100000097b208e0060006002a0000000a000a0020000000524f4353455256455232524f435655450000
+ENTRY_END
+
+STEP 30470 QUERY
+ENTRY_BEGIN
+RAW
+b8971af45011fef239920000000000000000
+ENTRY_END
+
+STEP 30480 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf06fb40000020405b401010402
+ENTRY_END
+
+STEP 30490 QUERY
+ENTRY_BEGIN
+RAW
+b8971af55010fef239910000000000000000
+ENTRY_END
+
+STEP 30500 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf07bee0000020405b401010402
+ENTRY_END
+
+STEP 30510 QUERY
+ENTRY_BEGIN
+RAW
+b898e9c85010faf006410000000000000000
+ENTRY_END
+
+STEP 30520 QUERY
+ENTRY_BEGIN
+RAW
+00000000700240002fbf00000204057a01010402
+ENTRY_END
+
+STEP 30530 QUERY
+ENTRY_BEGIN
+RAW
+b89baf9f501041b8f2450000000000000000
+ENTRY_END
+
+STEP 30540 QUERY
+ENTRY_BEGIN
+RAW
+b89baf9f501841b8f68800000094b100000000010001000000000f313133333837313336363136322d330000f900010f313133333837313336363136322d330000f900ff00000000005803677373096d6963726f736f667403636f6d00403afa7e403c4bfe0003000000354e544c4d535350000100000097b200e0090009002c0000000c000c0020000000534253504952414d4944454e504952414d4944454e0000
+ENTRY_END
+
+STEP 30550 QUERY
+ENTRY_BEGIN
+RAW
+b89bafad501141aaf1ae0000000000000000
+ENTRY_END
+
+STEP 30560 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000a23a00000204057a01010402
+ENTRY_END
+
+STEP 30570 QUERY
+ENTRY_BEGIN
+RAW
+b89bafae501041aaf1ad0000000000000000
+ENTRY_END
+
+STEP 30580 QUERY
+ENTRY_BEGIN
+RAW
+b89c5852501041b8bc0d0000000000000000
+ENTRY_END
+
+STEP 30590 QUERY
+ENTRY_BEGIN
+RAW
+b89c5852501841b8f051000000948200000000010001000000000f313133333837313336363136322d320000f900010f313133333837313336363136322d320000f900ff00000000005803677373096d6963726f736f667403636f6d00403afa7e403c4bfe0003000000354e544c4d535350000100000097b200e0090009002c0000000c000c0020000000534253504952414d4944454e504952414d4944454e0000
+ENTRY_END
+
+STEP 30600 QUERY
+ENTRY_BEGIN
+RAW
+b89c5860501141aabb760000000000000000
+ENTRY_END
+
+STEP 30610 QUERY
+ENTRY_BEGIN
+RAW
+0000000070024000da6600000204057a01010402
+ENTRY_END
+
+STEP 30620 QUERY
+ENTRY_BEGIN
+RAW
+b89c5861501041aabb750000000000000000
+ENTRY_END
+
+STEP 30630 QUERY
+ENTRY_BEGIN
+RAW
+b89cfce5501041b84fa60000000000000000
+ENTRY_END
+
+STEP 30640 QUERY
+ENTRY_BEGIN
+RAW
+b89cfce5501841b8b2ea000000945300000000010001000000000f313133333837313336363136322d320000f900010f313133333837313336363136322d320000f900ff00000000005803677373096d6963726f736f667403636f6d00403afa7e403c4bfe0003000000354e544c4d535350000100000097b200e0090009002c0000000c000c0020000000534253504952414d4944454e504952414d4944454e0000
+ENTRY_END
+
+STEP 30650 QUERY
+ENTRY_BEGIN
+RAW
+b89cfcf3501141aa4f0f0000000000000000
+ENTRY_END
+
+STEP 30660 QUERY
+ENTRY_BEGIN
+RAW
+b89cfcf4501041aa4f0e0000000000000000
+ENTRY_END
+
+STEP 30670 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf06c420000020405b401010402
+ENTRY_END
+
+STEP 30680 QUERY
+ENTRY_BEGIN
+RAW
+b89f748d5010faf06bc90000000000000000
+ENTRY_END
+
+STEP 30690 QUERY
+ENTRY_BEGIN
+RAW
+b89f748d5018faf029bd0000008ed048000000010001000000000f313038323333313735383631302d330000f900010f313038323333313735383631302d330000f900ff00000000005203677373096d6963726f736f667403636f6d00403af976403c4af600030000002f4e544c4d535350000100000097b208e0090009002600000006000600200000005453444f43554f4c59534c414745520000
+ENTRY_END
+
+STEP 30700 QUERY
+ENTRY_BEGIN
+RAW
+b89f749b5011fae26b380000000000000000
+ENTRY_END
+
+STEP 30710 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf091260000020405b401010402
+ENTRY_END
+
+STEP 30720 QUERY
+ENTRY_BEGIN
+RAW
+b89f749c5010fae26b370000000000000000
+ENTRY_END
+
+STEP 30730 QUERY
+ENTRY_BEGIN
+RAW
+b8a055e75010faf0af520000000000000000
+ENTRY_END
+
+STEP 30740 QUERY
+ENTRY_BEGIN
+RAW
+b8a055e75018faf0a56c0000008e9923000000010001000000000f313038323333313735383631302d320000f900010f313038323333313735383631302d320000f900ff00000000005203677373096d6963726f736f667403636f6d00403af976403c4af600030000002f4e544c4d535350000100000097b208e0090009002600000006000600200000005453444f43554f4c59534c414745520000
+ENTRY_END
+
+STEP 30750 QUERY
+ENTRY_BEGIN
+RAW
+b8a055f55011fae2aec10000000000000000
+ENTRY_END
+
+STEP 30760 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf0a72f0000020405b401010402
+ENTRY_END
+
+STEP 30770 QUERY
+ENTRY_BEGIN
+RAW
+b8a055f65010fae2aec00000000000000000
+ENTRY_END
+
+STEP 30780 QUERY
+ENTRY_BEGIN
+RAW
+b8a134165010faf0e72b0000000000000000
+ENTRY_END
+
+STEP 30790 QUERY
+ENTRY_BEGIN
+RAW
+b8a134165018faf0631b0000008e134e000000010001000000000f313038323333313735383631302d320000f900010f313038323333313735383631302d320000f900ff00000000005203677373096d6963726f736f667403636f6d00403af976403c4af600030000002f4e544c4d535350000100000097b208e0090009002600000006000600200000005453444f43554f4c59534c414745520000
+ENTRY_END
+
+STEP 30800 QUERY
+ENTRY_BEGIN
+RAW
+b8a134245011fae2e69a0000000000000000
+ENTRY_END
+
+STEP 30810 QUERY
+ENTRY_BEGIN
+RAW
+b8a134255010fae2e6990000000000000000
+ENTRY_END
+
+STEP 30820 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf0b79b0000020405b401010402
+ENTRY_END
+
+STEP 30830 QUERY
+ENTRY_BEGIN
+RAW
+b8a596575010faf095520000000000000000
+ENTRY_END
+
+STEP 30840 QUERY
+ENTRY_BEGIN
+RAW
+b8a596575018faf088240000008e42e5000000010001000000000f313038323333313735383631302d330000f900010f313038323333313735383631302d330000f900ff00000000005203677373096d6963726f736f667403636f6d00403af53e403c46be00030000002f4e544c4d535350000100000097b208e00600060029000000090009002000000049572d303031373232544b544553540000
+ENTRY_END
+
+STEP 30850 QUERY
+ENTRY_BEGIN
+RAW
+b8a596655011fae294c10000000000000000
+ENTRY_END
+
+STEP 30860 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf07bfa00000204056401010402
+ENTRY_END
+
+STEP 30870 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf0ae140000020405b401010402
+ENTRY_END
+
+STEP 30880 QUERY
+ENTRY_BEGIN
+RAW
+b8a596665010fae294c00000000000000000
+ENTRY_END
+
+STEP 30890 QUERY
+ENTRY_BEGIN
+RAW
+b8a674795010fd5c78d20000000000000000
+ENTRY_END
+
+STEP 30900 QUERY
+ENTRY_BEGIN
+RAW
+b8a70de15010faf014400000000000000000
+ENTRY_END
+
+STEP 30910 QUERY
+ENTRY_BEGIN
+RAW
+b8a70de15018faf0b7340000008e93c3000000010001000000000f313038323333313735383631302d320000f900010f313038323333313735383631302d320000f900ff00000000005203677373096d6963726f736f667403636f6d00403af53e403c46be00030000002f4e544c4d535350000100000097b208e00600060029000000090009002000000049572d303031373232544b544553540000
+ENTRY_END
+
+STEP 30920 QUERY
+ENTRY_BEGIN
+RAW
+b8a674795018fd5c78830000008f059c000000010001000000000e3931303533333036363737302d330000f900010e3931303533333036363737302d330000f900ff00000000005503677373096d6963726f736f667403636f6d00403af386403c45060003000000324e544c4d535350000100000097b208e00a000a0028000000080008002000000050434f4f535431314f4f535445494e4445520000
+ENTRY_END
+
+STEP 30930 QUERY
+ENTRY_BEGIN
+RAW
+b8a70def5011fae213af0000000000000000
+ENTRY_END
+
+STEP 30940 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf0e3ce0000020405b401010402
+ENTRY_END
+
+STEP 30950 QUERY
+ENTRY_BEGIN
+RAW
+b8a674875011fd4e78400000000000000000
+ENTRY_END
+
+STEP 30960 QUERY
+ENTRY_BEGIN
+RAW
+000000007002faf0fefc00000204056401010402
+ENTRY_END
+
+STEP 30970 QUERY
+ENTRY_BEGIN
+RAW
+b8a70df05010fae213ae0000000000000000
+ENTRY_END
+
+STEP 30980 QUERY
+ENTRY_BEGIN
+RAW
+b8a674885010fd4e783f0000000000000000
+ENTRY_END
+
+STEP 30990 QUERY
+ENTRY_BEGIN
+RAW
+b8a7ad145010faf0aac60000000000000000
+ENTRY_END
+
+STEP 31000 QUERY
+ENTRY_BEGIN
+RAW
+b8a87d065010fd5cf3450000000000000000
+ENTRY_END
+
+STEP 31010 QUERY
+ENTRY_BEGIN
+RAW
+b8a7ad145018faf0518f0000008e8fef000000010001000000000f313038323333313735383631302d320000f900010f313038323333313735383631302d320000f900ff00000000005203677373096d6963726f736f667403636f6d00403af53e403c46be00030000002f4e544c4d535350000100000097b208e00600060029000000090009002000000049572d303031373232544b544553540000
+ENTRY_END
+
+STEP 31020 QUERY
+ENTRY_BEGIN
+RAW
+b8a87d065018fd5cc9920000008f3100000000010001000000000e3931303533333036363737302d320000f900010e3931303533333036363737302d320000f900ff00000000005503677373096d6963726f736f667403636f6d00403af386403c45060003000000324e544c4d535350000100000097b208e00a000a0028000000080008002000000050434f4f535431314f4f535445494e4445520000
+ENTRY_END
+
+STEP 31030 QUERY
+ENTRY_BEGIN
+RAW
+b8a7ad225011fae2aa350000000000000000
+ENTRY_END
+
+
+
+; finally we check basic function by a copy of ./iter_resolve.rpl (steps +123000)
+RANGE_BEGIN 123000 123100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+; net.
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+net. IN NS
+SECTION AUTHORITY
+. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+; root-servers.net.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+root-servers.net. IN NS
+SECTION ANSWER
+root-servers.net. IN NS k.root-servers.net.
+SECTION ADDITIONAL
+k.root-servers.net. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+root-servers.net. IN A
+SECTION AUTHORITY
+root-servers.net. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+k.root-servers.net. IN A
+SECTION ANSWER
+k.root-servers.net. IN A 193.0.14.129
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+k.root-servers.net. IN AAAA
+SECTION AUTHORITY
+root-servers.net. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+; gtld-servers.net.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+gtld-servers.net. IN NS
+SECTION ANSWER
+gtld-servers.net. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+gtld-servers.net. IN A
+SECTION AUTHORITY
+gtld-servers.net. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+a.gtld-servers.net. IN A
+SECTION ANSWER
+a.gtld-servers.net. IN A 192.5.6.30
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+a.gtld-servers.net. IN AAAA
+SECTION AUTHORITY
+gtld-servers.net. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+
+
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 123000 123100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 123000 123100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+STEP 123001 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 123010 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+;SECTION AUTHORITY
+;example.com. IN NS ns.example.com.
+;SECTION ADDITIONAL
+;ns.example.com. IN A 1.2.3.4
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/iter_cname_badauth.rpl b/tests/integration/deckard/sets/resolver/iter_cname_badauth.rpl
new file mode 100644
index 0000000..187fd07
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/iter_cname_badauth.rpl
@@ -0,0 +1,269 @@
+do-ip6: no
+
+; config options
+; target-fetch-policy: "3 2 1 0 0"
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test iterator with NS sending CNAME answer and authority of CNAME target.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+au. IN NS
+SECTION AUTHORITY
+au. SOA bla bla 1 2 3 4 5
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com.au. IN NS
+SECTION AUTHORITY
+com.au. SOA bla bla 1 2 3 4 5
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION AUTHORITY
+com. SOA bla bla 1 2 3 4 5
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+nstld.com. IN NS
+SECTION AUTHORITY
+nstld.com. SOA bla bla 1 2 3 4 5
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+K.ROOT-SERVERS.NET. IN A
+SECTION ANSWER
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+K.ROOT-SERVERS.NET. IN AAAA
+SECTION AUTHORITY
+. SOA bla bla 1 2 3 4 5
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+net. IN NS
+SECTION AUTHORITY
+net. SOA bla bla 1 2 3 4 5
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+root-servers.net. IN NS
+SECTION AUTHORITY
+root-servers.net. SOA bla bla 1 2 3 4 5
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+ncfphywebgtm01-c.ingdirect.com.au. IN AAAA
+SECTION AUTHORITY
+. SOA bla bla 1 2 3 4 5
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR AA NOERROR
+SECTION QUESTION
+ingdirect.com.au. IN A
+SECTION AUTHORITY
+ingdirect.com.au. IN NS l4.nstld.com.
+SECTION ADDITIONAL
+l4.nstld.com. IN A 209.112.114.33
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+l4.nstld.com. IN A
+SECTION ANSWER
+l4.nstld.com. IN A 209.112.114.33
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+l4.nstld.com. IN AAAA
+SECTION AUTHORITY
+. SOA bla bla 1 2 3 4 5
+ENTRY_END
+
+RANGE_END
+
+; l4.nstld.com.
+RANGE_BEGIN 0 100
+ ADDRESS 209.112.114.33
+
+ENTRY_BEGIN
+MATCH opcode qname qtype
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ingdirect.com.au. IN NS
+SECTION ANSWER
+ingdirect.com.au. IN NS l4.nstld.com.
+SECTION ADDITIONAL
+l4.nstld.com. IN A 209.112.114.33
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+www.ingdirect.com.au. IN A
+SECTION ANSWER
+www.ingdirect.com.au. IN CNAME www.clb.ingdirect.com.au.
+SECTION AUTHORITY
+clb.ingdirect.com.au. IN NS ncfphywebgtm01-c.ingdirect.com.au.
+SECTION ADDITIONAL
+ncfphywebgtm01-c.ingdirect.com.au. IN A 203.92.27.132
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+clb.ingdirect.com.au. IN A
+SECTION AUTHORITY
+clb.ingdirect.com.au. IN NS ncfphywebgtm01-c.ingdirect.com.au.
+SECTION ADDITIONAL
+ncfphywebgtm01-c.ingdirect.com.au. IN A 203.92.27.132
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname qtype
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ncfphywebgtm01-c.ingdirect.com.au. IN A
+SECTION ANSWER
+ncfphywebgtm01-c.ingdirect.com.au. IN A 203.92.27.132
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname qtype
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ncfphywebgtm01-c.ingdirect.com.au. IN AAAA
+SECTION AUTHORITY
+ingdirect.com.au. IN SOA bla bla 1 2 3 4 5
+ENTRY_END
+
+RANGE_END
+
+; ncfphywebgtm01-c.ingdirect.com.au.
+RANGE_BEGIN 0 100
+ ADDRESS 203.92.27.132
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+clb.ingdirect.com.au. IN NS
+SECTION AUTHORITY
+clb.ingdirect.com.au. IN NS ncfphywebgtm01-c.ingdirect.com.au.
+SECTION ADDITIONAL
+ncfphywebgtm01-c.ingdirect.com.au. IN A 203.92.27.132
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id copy_query
+REPLY QR AA NOERROR
+SECTION QUESTION
+www.clb.ingdirect.com.au. IN A
+SECTION ANSWER
+www.clb.ingdirect.com.au. IN A 203.31.183.134
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id copy_query
+REPLY QR REFUSED
+SECTION QUESTION
+www.ingdirect.com.au. IN A
+ENTRY_END
+
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.ingdirect.com.au. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.ingdirect.com.au. IN A
+SECTION ANSWER
+www.ingdirect.com.au. IN CNAME www.clb.ingdirect.com.au.
+www.clb.ingdirect.com.au. IN A 203.31.183.134
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/iter_cname_cache.rpl b/tests/integration/deckard/sets/resolver/iter_cname_cache.rpl
new file mode 100644
index 0000000..9af140d
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/iter_cname_cache.rpl
@@ -0,0 +1,299 @@
+do-ip6: no
+
+; config options
+; target-fetch-policy: "0 0 0 0 0"
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+;test from testbound
+
+SCENARIO_BEGIN Test iterative resolve with cached cname for nameserver
+; example.com NS ns.example.com en ns2.example.com
+; ns.example.com CNAME ns.bla.nl
+; ns.bla.nl A ....
+; dan timeout van A record uit cache - refetch.
+; ns2.example.com timeed niet uit ; maar geeft altijd servfail.
+
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+a.gtld-servers.net. IN AAAA
+SECTION ANSWER
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+nl. IN A
+SECTION AUTHORITY
+nl. IN NS ns2.nic.nl.
+SECTION ADDITIONAL
+ns2.nic.nl. IN A 192.1.1.2
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net. ".com"
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. IN NS ns2.example.com.
+SECTION ADDITIONAL
+;;; but really a CNAME in child server
+ns.example.com. 1 IN A 1.2.3.4
+ns2.example.com. IN A 1.2.3.5
+ns2.example.com. IN A 2.0.2.5
+ENTRY_END
+
+; lame answers back to root for .nl (.com server not authoritative for .nl)
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+nl. IN A
+SECTION AUTHORITY
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+RANGE_END
+
+; ns2.nic.nl ".nl"
+RANGE_BEGIN 0 100
+ ADDRESS 192.1.1.2
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+bla.nl. IN A
+SECTION AUTHORITY
+bla.nl. IN NS ns.bla.nl.
+SECTION ADDITIONAL
+ns.bla.nl. IN A 1.2.3.6
+ENTRY_END
+
+RANGE_END
+
+; ns.bla.nl "bla..nl"
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.6
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+ns.bla.nl. IN A
+SECTION ANSWER
+ns.bla.nl. IN A 1.2.3.6
+SECTION AUTHORITY
+bla.nl. IN NS ns.bla.nl.
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+ns.bla.nl. IN AAAA
+SECTION ANSWER
+SECTION AUTHORITY
+bla.nl. IN SOA bla.nl. bla.nl. 1 2 3 4 5
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+ns.bla.nl. IN MX
+SECTION ANSWER
+ns.bla.nl. IN MX 10 bla.nl.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+ENTRY_END
+RANGE_END
+
+; ns.example.com "example.com"
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.com. IN MX
+SECTION ANSWER
+ns.example.com IN CNAME ns.bla.nl.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+ENTRY_END
+RANGE_END
+
+; ns2.example.com "example.com"
+; bad failing server
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.5
+ENTRY_BEGIN
+MATCH opcode
+ADJUST copy_id copy_query
+REPLY QR SERVFAIL
+SECTION QUESTION
+ns.example.com. IN MX
+SECTION ANSWER
+ENTRY_END
+RANGE_END
+
+; ns2.example.com "example.com"
+; bad failing server
+RANGE_BEGIN 0 100
+ ADDRESS 2.0.2.5
+ENTRY_BEGIN
+MATCH opcode
+ADJUST copy_id copy_query
+REPLY QR SERVFAIL
+SECTION QUESTION
+ns.example.com. IN MX
+SECTION ANSWER
+ENTRY_END
+RANGE_END
+
+; get cname in cache. use MX query
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+ns.example.com. IN MX
+ENTRY_END
+
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+ns.example.com. IN MX
+SECTION ANSWER
+ns.example.com. IN CNAME ns.bla.nl
+ns.bla.nl. IN MX 10 bla.nl.
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+; get seconds to pass to timeout the A record
+STEP 15 TIME_PASSES ELAPSE 5
+
+; get into trouble getting cname for nameserver.
+STEP 20 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+STEP 30 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+; there may still be pending ns.bla.nl AAAA queries ; get rid of them like this
+STEP 40 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+ns.bla.nl. IN AAAA
+ENTRY_END
+
+STEP 50 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+ns.bla.nl. IN AAAA
+SECTION ANSWER
+SECTION AUTHORITY
+bla.nl. IN SOA bla.nl. bla.nl. 1 2 3 4 5
+;SECTION ADDITIONAL
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/iter_cname_double.rpl b/tests/integration/deckard/sets/resolver/iter_cname_double.rpl
new file mode 100644
index 0000000..1f02b9c
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/iter_cname_double.rpl
@@ -0,0 +1,296 @@
+do-ip6: no
+
+; config options
+; target-fetch-policy: "0 0 0 0 0"
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test double cname in reply.
+; this is in response to an error report from Robert Edmonds,
+; about resolution of images-na.ssl-images-amazon.com.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+net. IN A
+SECTION AUTHORITY
+net. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+net. IN NS
+SECTION ANSWER
+net. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+; gtld-servers.net.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+gtld-servers.net. IN NS
+SECTION ANSWER
+gtld-servers.net. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+gtld-servers.net. IN A
+SECTION AUTHORITY
+gtld-servers.net. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+a.gtld-servers.net. IN A
+SECTION ANSWER
+a.gtld-servers.net. IN A 192.5.6.30
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+a.gtld-servers.net. IN AAAA
+SECTION AUTHORITY
+gtld-servers.net. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+; root-servers.net.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+root-servers.net. IN NS
+SECTION ANSWER
+root-servers.net. IN NS k.root-servers.net.
+SECTION ADDITIONAL
+k.root-servers.net. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+root-servers.net. IN A
+SECTION AUTHORITY
+root-servers.net. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+k.root-servers.net. IN A
+SECTION ANSWER
+k.root-servers.net. IN A 193.0.14.129
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+k.root-servers.net. IN AAAA
+SECTION AUTHORITY
+root-servers.net. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+; test domains
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+next.com. IN A
+SECTION AUTHORITY
+next.com. IN NS ns.next.com.
+SECTION ADDITIONAL
+ns.next.com. IN A 1.2.3.5
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname qtype
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.com. IN A
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname qtype
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.com. IN AAAA
+SECTION ADDITIONAL
+example.com. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+; two CNAMEs for one name?
+www.example.com. IN CNAME www.next.com.
+www.example.com. IN CNAME www.next.com.
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+; ns.next.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.5
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA
+SECTION QUESTION
+www.next.com. IN A
+SECTION ANSWER
+www.next.com. IN A 10.20.30.40
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+next.com. IN NS
+SECTION ANSWER
+next.com. IN NS ns.next.com.
+SECTION ADDITIONAL
+ns.next.com. IN A 1.2.3.5
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN CNAME www.next.com.
+www.next.com. IN A 10.20.30.40
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/iter_cname_nx.rpl b/tests/integration/deckard/sets/resolver/iter_cname_nx.rpl
new file mode 100644
index 0000000..37c6300
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/iter_cname_nx.rpl
@@ -0,0 +1,290 @@
+do-ip6: no
+
+; config options
+; target-fetch-policy: "0 0 0 0 0"
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test cname followed by nxdomain reply rcode.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+net. IN A
+SECTION AUTHORITY
+net. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+net. IN NS
+SECTION ANSWER
+net. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+; gtld-servers.net.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+gtld-servers.net. IN NS
+SECTION ANSWER
+gtld-servers.net. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+gtld-servers.net. IN A
+SECTION AUTHORITY
+gtld-servers.net. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+a.gtld-servers.net. IN A
+SECTION ANSWER
+a.gtld-servers.net. IN A 192.5.6.30
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+a.gtld-servers.net. IN AAAA
+SECTION ANSWER
+SECTION ADDITIONAL
+ENTRY_END
+
+; root-servers.net.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+root-servers.net. IN NS
+SECTION ANSWER
+root-servers.net. IN NS k.root-servers.net.
+SECTION ADDITIONAL
+k.root-servers.net. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+root-servers.net. IN A
+SECTION AUTHORITY
+root-servers.net. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+k.root-servers.net. IN A
+SECTION ANSWER
+k.root-servers.net. IN A 193.0.14.129
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+k.root-servers.net. IN AAAA
+SECTION AUTHORITY
+root-servers.net. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+; test domains
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+next.com. IN A
+SECTION AUTHORITY
+next.com. IN NS ns.next.com.
+SECTION ADDITIONAL
+ns.next.com. IN A 1.2.3.5
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname qtype
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.com. IN A
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname qtype
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.com. IN AAAA
+SECTION ADDITIONAL
+example.com. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN CNAME www.next.com.
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+; ns.next.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.5
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NXDOMAIN
+SECTION QUESTION
+www.next.com. IN A
+SECTION ANSWER
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+next.com. IN NS
+SECTION ANSWER
+next.com. IN NS ns.next.com.
+SECTION ADDITIONAL
+ns.next.com. IN A 1.2.3.5
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NXDOMAIN
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN CNAME www.next.com.
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/iter_cname_qnamecopy.rpl b/tests/integration/deckard/sets/resolver/iter_cname_qnamecopy.rpl
new file mode 100644
index 0000000..30c3b68
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/iter_cname_qnamecopy.rpl
@@ -0,0 +1,356 @@
+do-ip6: no
+
+; config options
+; target-fetch-policy: "0 0 0 0 0"
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test cname to nodata and if qname is set to orig after prepend
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+net. IN A
+SECTION AUTHORITY
+net. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+net. IN NS
+SECTION ANSWER
+net. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+
+; gtld-servers.net.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+gtld-servers.net. IN NS
+SECTION ANSWER
+gtld-servers.net. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+gtld-servers.net. IN A
+SECTION AUTHORITY
+gtld-servers.net. IN SOA . . 0 0 0 0 0
+ENTRY_END
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+a.gtld-servers.net. IN A
+SECTION ANSWER
+a.gtld-servers.net. IN A 192.5.6.30
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+a.gtld-servers.net. IN AAAA
+SECTION ANSWER
+SECTION ADDITIONAL
+ENTRY_END
+
+; root-servers.net.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+root-servers.net. IN NS
+SECTION ANSWER
+root-servers.net. IN NS k.root-servers.net.
+SECTION ADDITIONAL
+k.root-servers.net. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+root-servers.net. IN A
+SECTION AUTHORITY
+root-servers.net. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+k.root-servers.net. IN A
+SECTION ANSWER
+k.root-servers.net. IN A 193.0.14.129
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+k.root-servers.net. IN AAAA
+SECTION AUTHORITY
+root-servers.net. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+next.com. IN A
+SECTION AUTHORITY
+next.com. IN NS ns.next.com.
+SECTION ADDITIONAL
+ns.next.com. IN A 1.2.3.5
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname qtype
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns.example.com. IN A
+SECTION ANSWER
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname qtype
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns.example.com. IN AAAA
+SECTION ADDITIONAL
+example.com. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN CNAME www.next.com.
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+RANGE_END
+
+; ns.next.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.5
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www.next.com. IN A
+SECTION ANSWER
+SECTION AUTHORITY
+next.com. IN SOA next.com. next.com. 2007090400 28800 7200 604800 18000
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+next.com. IN NS
+SECTION ANSWER
+next.com. IN NS ns.next.com.
+SECTION ADDITIONAL
+ns.next.com. IN A 1.2.3.5
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns.next.com. IN A
+SECTION ANSWER
+ns.next.com. IN A 1.2.3.5
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns.next.com. IN AAAA
+SECTION ANSWER
+SECTION AUTHORITY
+next.com. IN SOA next.com. next.com. 2007090400 28800 7200 604800 18000
+SECTION ADDITIONAL
+ENTRY_END
+
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD CD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 3 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD CD RA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN CNAME www.next.com.
+SECTION AUTHORITY
+next.com. IN SOA next.com. next.com. 2007090400 28800 7200 604800 18000
+SECTION ADDITIONAL
+ENTRY_END
+
+; query it from cache again
+STEP 5 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+STEP 7 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN CNAME www.next.com.
+SECTION AUTHORITY
+next.com. IN SOA next.com. next.com. 2007090400 28800 7200 604800 18000
+SECTION ADDITIONAL
+ENTRY_END
+
+; query answer to cname from cache again, test if stored under wrong qname.
+STEP 9 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.next.com. IN A
+ENTRY_END
+
+STEP 11 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.next.com. IN A
+SECTION ANSWER
+SECTION AUTHORITY
+next.com. IN SOA next.com. next.com. 2007090400 28800 7200 604800 18000
+SECTION ADDITIONAL
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/iter_cycle.rpl b/tests/integration/deckard/sets/resolver/iter_cycle.rpl
new file mode 100644
index 0000000..78417d1
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/iter_cycle.rpl
@@ -0,0 +1,260 @@
+do-ip6: no
+
+; config options
+; target-fetch-policy: "0 0 0 0 0"
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test resolution with dependency cycle
+; query for ns.example.com, needs ns.example.net, needs ns.example.com.
+
+; Invalid server
+RANGE_BEGIN 0 100 1.2.3.1
+
+ENTRY_BEGIN
+ADJUST copy_id copy_query
+REPLY QR SERVFAIL
+ENTRY_END
+
+RANGE_END
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+net. IN A
+SECTION AUTHORITY
+net. IN NS e.gtld-servers.net.
+SECTION ADDITIONAL
+e.gtld-servers.net. IN A 192.12.94.30
+ENTRY_END
+
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.com. IN AAAA
+SECTION AUTHORITY
+example.com. IN NS ns.example.net.
+SECTION ADDITIONAL
+; note this will be scrubbed off
+ns.example.net. IN A 1.2.3.1
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns.example.net.
+SECTION ADDITIONAL
+; note this will be scrubbed off
+ns.example.net. IN A 1.2.3.1
+ENTRY_END
+
+RANGE_END
+
+; e.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.12.94.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+net. IN NS
+SECTION ANSWER
+net. IN NS e.gtld-servers.net.
+SECTION ADDITIONAL
+e.gtld-servers.net. IN A 192.12.94.30
+ENTRY_END
+
+; root-servers.net.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+root-servers.net. IN NS
+SECTION ANSWER
+root-servers.net. IN NS k.root-servers.net.
+SECTION ADDITIONAL
+k.root-servers.net. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+root-servers.net. IN A
+SECTION AUTHORITY
+root-servers.net. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+k.root-servers.net. IN A
+SECTION ANSWER
+k.root-servers.net. IN A 193.0.14.129
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+k.root-servers.net. IN AAAA
+SECTION AUTHORITY
+root-servers.net. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+; gtld-servers.net.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+gtld-servers.net. IN NS
+SECTION ANSWER
+gtld-servers.net. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+gtld-servers.net. IN A
+SECTION AUTHORITY
+gtld-servers.net. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+a.gtld-servers.net. IN A
+SECTION ANSWER
+a.gtld-servers.net. IN A 192.5.6.30
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+a.gtld-servers.net. IN AAAA
+SECTION AUTHORITY
+gtld-servers.net. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+e.gtld-servers.net. IN A
+SECTION ANSWER
+e.gtld-servers.net. IN A 192.12.94.30
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+e.gtld-servers.net. IN AAAA
+SECTION AUTHORITY
+gtld-servers.net. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.net. IN A
+SECTION AUTHORITY
+example.net. IN NS ns.example.com.
+SECTION ADDITIONAL
+; note this will be scrubbed off
+ns.example.com. IN A 1.2.3.2
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+ns.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+; cycle detected and it fails.
+STEP 20 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA SERVFAIL
+SECTION QUESTION
+ns.example.com. IN A
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/iter_cycle_noh.rpl b/tests/integration/deckard/sets/resolver/iter_cycle_noh.rpl
new file mode 100644
index 0000000..863d3a1
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/iter_cycle_noh.rpl
@@ -0,0 +1,416 @@
+do-ip6: no
+
+; config options
+ harden-glue: "no"
+; target-fetch-policy: "0 0 0 0 0"
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test resolution where disabled scrubber avoids cycle
+; query for ns.example.com, needs ns.example.net, needs ns.example.com.
+; scrubber disabled, so extra glue is trusted.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.net. IN AAAA
+SECTION AUTHORITY
+net. IN NS e.gtld-servers.net.
+SECTION ADDITIONAL
+e.gtld-servers.net. IN A 192.12.94.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+net. IN A
+SECTION AUTHORITY
+net. IN NS e.gtld-servers.net.
+SECTION ADDITIONAL
+e.gtld-servers.net. IN A 192.12.94.30
+ENTRY_END
+
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.net. IN A 1.2.3.1
+ENTRY_END
+
+; gtld-servers.net.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+gtld-servers.net. IN NS
+SECTION ANSWER
+gtld-servers.net. IN NS a.gtld-servers.net.
+gtld-servers.net. IN NS e.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+e.gtld-servers.net. IN A 192.12.94.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+gtld-servers.net. IN A
+SECTION AUTHORITY
+gtld-servers.net. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+a.gtld-servers.net. IN A
+SECTION ANSWER
+a.gtld-servers.net. IN A 192.5.6.30
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+a.gtld-servers.net. IN AAAA
+SECTION AUTHORITY
+gtld-servers.net. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+e.gtld-servers.net. IN A
+SECTION ANSWER
+e.gtld-servers.net. IN A 192.12.94.30
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+e.gtld-servers.net. IN AAAA
+SECTION AUTHORITY
+gtld-servers.net. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+
+; root-servers.net.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+root-servers.net. IN NS
+SECTION ANSWER
+root-servers.net. IN NS k.root-servers.net.
+SECTION ADDITIONAL
+k.root-servers.net. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+root-servers.net. IN A
+SECTION AUTHORITY
+root-servers.net. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+k.root-servers.net. IN A
+SECTION ANSWER
+k.root-servers.net. IN A 193.0.14.129
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+k.root-servers.net. IN AAAA
+SECTION AUTHORITY
+root-servers.net. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+RANGE_END
+
+; e.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.12.94.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+net. IN NS
+SECTION ANSWER
+net. IN NS e.gtld-servers.net.
+SECTION ADDITIONAL
+e.gtld-servers.net. IN A 192.12.94.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.net. IN A
+SECTION AUTHORITY
+example.net. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.2
+ENTRY_END
+
+; gtld-servers.net.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+gtld-servers.net. IN NS
+SECTION ANSWER
+gtld-servers.net. IN NS a.gtld-servers.net.
+gtld-servers.net. IN NS e.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+e.gtld-servers.net. IN A 192.12.94.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+gtld-servers.net. IN A
+SECTION AUTHORITY
+gtld-servers.net. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+a.gtld-servers.net. IN A
+SECTION ANSWER
+a.gtld-servers.net. IN A 192.5.6.30
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+a.gtld-servers.net. IN AAAA
+SECTION AUTHORITY
+gtld-servers.net. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+e.gtld-servers.net. IN A
+SECTION ANSWER
+e.gtld-servers.net. IN A 192.12.94.30
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+e.gtld-servers.net. IN AAAA
+SECTION AUTHORITY
+gtld-servers.net. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+
+
+; root-servers.net.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+root-servers.net. IN NS
+SECTION ANSWER
+root-servers.net. IN NS k.root-servers.net.
+SECTION ADDITIONAL
+k.root-servers.net. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+root-servers.net. IN A
+SECTION AUTHORITY
+root-servers.net. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+k.root-servers.net. IN A
+SECTION ANSWER
+k.root-servers.net. IN A 193.0.14.129
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+k.root-servers.net. IN AAAA
+SECTION AUTHORITY
+root-servers.net. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+RANGE_END
+
+; ns.example.net.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.1
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.net. IN NS
+SECTION ANSWER
+example.net. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.2
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.net. IN A 1.2.3.1
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.com. IN A
+SECTION ANSWER
+ns.example.com. IN A 1.2.3.2
+SECTION AUTHORITY
+example.com. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.net. IN A 1.2.3.1
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+ns.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+; cycle detected and it fails.
+STEP 20 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA
+SECTION QUESTION
+ns.example.com. IN A
+SECTION ANSWER
+ns.example.com. IN A 1.2.3.2
+;SECTION AUTHORITY
+;example.com. IN NS ns.example.net.
+; scrubbed off
+; SECTION ADDITIONAL
+; ns.example.net. IN A 1.2.3.1
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/iter_dname_insec.rpl b/tests/integration/deckard/sets/resolver/iter_dname_insec.rpl
new file mode 100644
index 0000000..b011008
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/iter_dname_insec.rpl
@@ -0,0 +1,1138 @@
+do-ip6: no
+
+stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test scrub of insecure DNAME in answer section
+
+; root infrastucture
+RANGE_BEGIN 0 10000000
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH qname qtype opcode
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH qname qtype opcode
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+shortloop. IN TXT
+SECTION ANSWER
+shortloop. IN TXT "shortloop end"
+ENTRY_END
+
+; this is an invalid entry:
+; RFC 6672 section 2.4 defines DNAME as sigleton type
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+test.twodnames. IN DNAME
+SECTION ANSWER
+twodnames. IN DNAME .
+twodnames. IN DNAME com.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH qname qtype opcode
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+K.ROOT-SERVERS.NET. IN A
+SECTION ANSWER
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH qname qtype opcode
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+K.ROOT-SERVERS.NET. IN AAAA
+SECTION ANSWER
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH subdomain opcode
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH subdomain opcode
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+x. IN A
+SECTION AUTHORITY
+x. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+long. IN NS
+SECTION AUTHORITY
+long. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+60o-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx. IN NS
+SECTION AUTHORITY
+60o-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH qname qtype opcode
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+a.gtld-servers.net. IN A
+SECTION ANSWER
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH qname qtype opcode
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+a.gtld-servers.net. IN AAAA
+SECTION ANSWER
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH subdomain opcode
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+net. IN A
+SECTION AUTHORITY
+net. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+; end of root infrastucture
+
+; a.gtld-servers.net. (com. net. x.)
+RANGE_BEGIN 0 10000000
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH qname qtype opcode
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+a.gtld-servers.net. IN A
+SECTION ANSWER
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH qname qtype opcode
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+a.gtld-servers.net. IN AAAA
+SECTION ANSWER
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH qname qtype opcode
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH qname qtype opcode
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+net. IN NS
+SECTION AUTHORITY
+net. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns1.example.com.
+SECTION ADDITIONAL
+ns1.example.com. IN A 168.192.2.2
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.net. IN A
+SECTION AUTHORITY
+example.net. IN NS ns1.example.net.
+SECTION ADDITIONAL
+ns1.example.net. IN A 168.192.3.3
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH qname qtype opcode
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+x. IN NS
+SECTION AUTHORITY
+x. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH qname qtype opcode
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+x. IN DNAME
+SECTION AUTHORITY
+x. IN DNAME .
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+; QNAME minimization
+ENTRY_BEGIN
+MATCH qname qtype opcode
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+x.x. IN NS
+SECTION AUTHORITY
+x. IN DNAME .
+x.x. IN CNAME x.
+x. IN NS a.gtld-servers.net.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH qname opcode
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+shortloop.x.x. IN CNAME
+SECTION ANSWER
+x. DNAME .
+shortloop.x.x. IN CNAME shortloop.x.
+shortloop.x. IN CNAME shortloop.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH qname opcode
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+shortloop.x. IN CNAME
+SECTION ANSWER
+x. DNAME .
+shortloop.x. IN CNAME shortloop.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH qname qtype opcode
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+60o-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx. IN NS
+SECTION AUTHORITY
+60o-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH qname qtype opcode
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+long. IN NS
+SECTION AUTHORITY
+long. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+; DNAME at zone apex, allowed by RFC 6672 section 2.3
+ENTRY_BEGIN
+MATCH qname qtype opcode
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+long. IN DNAME
+SECTION ANSWER
+long. 3600 IN DNAME 63o-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.63o-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.63o-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.60o-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH qname qtype opcode
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+x.long. IN A
+SECTION ANSWER
+long. 3600 IN DNAME 63o-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.63o-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.63o-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.60o-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.
+x.long. 3600 IN CNAME x.63o-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.63o-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.63o-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.60o-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.
+x.63o-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.63o-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.63o-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.60o-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx. 3600 IN A 192.0.2.1
+ENTRY_END
+
+; empty non-terminal, because of QNAME minimization
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR AA NOERROR
+SECTION QUESTION
+63o-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.60o-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx. IN NS
+SECTION ANSWER
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH qname qtype opcode
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+x.63o-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.63o-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.63o-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.60o-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx. IN A
+SECTION ANSWER
+x.63o-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.63o-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.63o-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.60o-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx. 3600 IN A 192.0.2.1
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH qname opcode
+ADJUST copy_id copy_query
+REPLY QR AA YXDOMAIN
+SECTION QUESTION
+too.long. IN A
+SECTION ANSWER
+long. 3600 IN DNAME 63o-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.63o-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.63o-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.60o-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.
+ENTRY_END
+RANGE_END
+; end of a.gtld-servers.net.
+
+; RFC 6672 section 2.2. The DNAME Substitution table tests
+;# QNAME owner DNAME target result
+;-- ---------------- -------------- -------------- -----------------
+;1 com. example.com. example.net. <no match>
+;2 example.com. example.com. example.net. [0]
+;3 a.example.com. example.com. example.net. a.example.net.
+;4 a.b.example.com. example.com. example.net. a.b.example.net.
+;5 ab.example.com. b.example.com. example.net. <no match>
+;6 foo.example.com. example.com. example.net. foo.example.net.
+;7 a.x.example.com. x.example.com. example.net. a.example.net.
+;8 a.example.com. example.com. y.example.net. a.y.example.net.
+;9 cyc.example.com. example.com. example.com. cyc.example.com.
+;10 cyc.example.com. example.com. c.example.com. cyc.c.example.com.
+;11 shortloop.x.x. x. . shortloop.x.
+;12 shortloop.x. x. . shortloop.
+;
+; [0] The result depends on the QTYPE. If the QTYPE = DNAME, then
+; the result is "example.com.", else "<no match>".
+;
+; Table 1. DNAME Substitution Examples
+
+; line no. 1 is mostly for authoritative server
+; line no. 2 QTYPE != DNAME
+; covers RFC 6672 section 2.3 as well
+STEP 220201 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+example.com. IN NS
+ENTRY_END
+
+STEP 220202 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH rcode flags question answer
+REPLY QR RD RA DO
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns1.example.com.
+ENTRY_END
+
+; line no. 2 QTYPE == DNAME
+STEP 220203 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+example.com. IN DNAME
+ENTRY_END
+
+STEP 220204 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH rcode flags question answer
+REPLY QR RD RA DO
+SECTION QUESTION
+example.com. IN DNAME
+SECTION ANSWER
+example.com. IN DNAME example.net.
+ENTRY_END
+
+
+;# QNAME owner DNAME target result
+;-- ---------------- -------------- -------------- -----------------
+;3 a.example.com. example.com. example.net. a.example.net.
+
+STEP 220301 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+a.example.com. IN A
+ENTRY_END
+
+STEP 220302 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH rcode question answer
+SECTION QUESTION
+a.example.com. IN A
+SECTION ANSWER
+example.com. IN DNAME example.net.
+a.example.com. IN CNAME a.example.net.
+a.example.net. IN A 10.0.0.97
+ENTRY_END
+
+;# QNAME owner DNAME target result
+;-- ---------------- -------------- -------------- -----------------
+;4 a.b.example.com. example.com. example.net. a.b.example.net.
+
+STEP 220401 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+a.b.example.com. IN A
+ENTRY_END
+
+STEP 220402 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH rcode question answer
+SECTION QUESTION
+a.b.example.com. IN A
+SECTION ANSWER
+example.com. IN DNAME example.net.
+a.b.example.com. IN CNAME a.b.example.net.
+a.b.example.net. IN A 10.0.97.98
+ENTRY_END
+
+;# QNAME owner DNAME target result
+;-- ---------------- -------------- -------------- -----------------
+;5 ab.example.com. b.example.com. example.net. <no match>
+;6 foo.example.com. example.com. example.net. foo.example.net.
+
+; line no. 5 is mostly for authoritative server
+; line no. 6 is basically the same as line no. 3
+
+; ns1.example.com.
+RANGE_BEGIN 220000 220699
+ ADDRESS 168.192.2.2
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns1.example.com.
+SECTION ADDITIONAL
+ns1.example.com. IN A 168.192.2.2
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns1.example.com. IN A
+SECTION ANSWER
+ns1.example.com. IN A 168.192.2.2
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns1.example.com. IN AAAA
+SECTION ANSWER
+ENTRY_END
+
+; line 2 DNAME
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+example.com. IN DNAME
+SECTION ANSWER
+example.com. IN DNAME example.net.
+ENTRY_END
+
+; line 3
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+a.example.com. IN A
+SECTION ANSWER
+example.com. IN DNAME example.net.
+a.example.com. IN CNAME a.example.net.
+ENTRY_END
+
+; line 4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+a.b.example.com. IN A
+SECTION ANSWER
+example.com. IN DNAME example.net.
+a.b.example.com. IN CNAME a.b.example.net.
+ENTRY_END
+RANGE_END
+; end of ns1.example.com.
+
+
+STEP 220700 TIME_PASSES ELAPSE 4000 ; need to expire example.com. DNAME
+;# QNAME owner DNAME target result
+;-- ---------------- -------------- -------------- -----------------
+;7 a.x.example.com. x.example.com. example.net. a.example.net.
+
+STEP 220701 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+a.x.example.com. IN A
+ENTRY_END
+
+STEP 220702 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH rcode question answer
+SECTION QUESTION
+a.x.example.com. IN A
+SECTION ANSWER
+x.example.com. IN DNAME example.net.
+a.x.example.com. IN CNAME a.example.net.
+a.example.net. IN A 10.0.0.97
+ENTRY_END
+
+; ns1.example.com.
+RANGE_BEGIN 220700 220799
+ ADDRESS 168.192.2.2
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns1.example.com.
+SECTION ADDITIONAL
+ns1.example.com. IN A 168.192.2.2
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns1.example.com. IN A
+SECTION ANSWER
+ns1.example.com. IN A 168.192.2.2
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns1.example.com. IN AAAA
+SECTION ANSWER
+ENTRY_END
+
+; line 7 DNAME
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+x.example.com. IN DNAME
+SECTION ANSWER
+x.example.com. IN DNAME example.net.
+ENTRY_END
+
+; no other types than DNAME, because of QNAME minimization
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR AA NOERROR
+SECTION QUESTION
+x.example.com. IN NS
+SECTION ANSWER
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+a.x.example.com. IN A
+SECTION ANSWER
+x.example.com. IN DNAME example.net.
+a.x.example.com. IN CNAME a.example.net.
+ENTRY_END
+RANGE_END
+; end of ns1.example.com.
+
+;# QNAME owner DNAME target result
+;-- ---------------- -------------- -------------- -----------------
+;8 a.example.com. example.com. y.example.net. a.y.example.net.
+;
+; a.example.com. was renamed to a2.example.com. to avoid cache clashes
+; on the synthetized CNAME (caching CNAMEs is allowed by RFC 6672 section 3.4)
+
+STEP 220801 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+a2.example.com. IN A
+ENTRY_END
+
+STEP 220802 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH rcode question answer
+SECTION QUESTION
+a2.example.com. IN A
+SECTION ANSWER
+example.com. IN DNAME y.example.net.
+a2.example.com. IN CNAME a2.y.example.net.
+a2.y.example.net. IN A 10.97.50.121
+ENTRY_END
+
+; ns1.example.com.
+RANGE_BEGIN 220800 220899
+ ADDRESS 168.192.2.2
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns1.example.com.
+SECTION ADDITIONAL
+ns1.example.com. IN A 168.192.2.2
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns1.example.com. IN A
+SECTION ANSWER
+ns1.example.com. IN A 168.192.2.2
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns1.example.com. IN AAAA
+SECTION ANSWER
+ENTRY_END
+
+; line 8 DNAME
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+example.com. IN DNAME
+SECTION ANSWER
+example.com. IN DNAME y.example.net.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+a2.example.com. IN A
+SECTION ANSWER
+example.com. IN DNAME y.example.net.
+a2.example.com. IN CNAME a2.y.example.net.
+ENTRY_END
+RANGE_END
+; end of ns1.example.com.
+
+
+STEP 220900 TIME_PASSES ELAPSE 4000 ; need to expire example.com. DNAME
+;# QNAME owner DNAME target result
+;-- ---------------- -------------- -------------- -----------------
+;9 cyc.example.com. example.com. example.com. cyc.example.com.
+
+STEP 220901 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+cyc.example.com. IN A
+ENTRY_END
+
+; Expected result is defined by RFC 1034 section 3.6.2:
+; CNAME chains should be followed and CNAME loops signalled as an error
+STEP 220902 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH rcode question answer
+REPLY SERVFAIL
+SECTION QUESTION
+cyc.example.com. IN A
+SECTION ANSWER
+example.com. IN DNAME example.com.
+cyc.example.com. IN CNAME cyc.example.com.
+ENTRY_END
+
+; ns1.example.com.
+RANGE_BEGIN 220900 220999
+ ADDRESS 168.192.2.2
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns1.example.com.
+SECTION ADDITIONAL
+ns1.example.com. IN A 168.192.2.2
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns1.example.com. IN A
+SECTION ANSWER
+ns1.example.com. IN A 168.192.2.2
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns1.example.com. IN AAAA
+SECTION ANSWER
+ENTRY_END
+
+; line 9 DNAME
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+example.com. IN DNAME
+SECTION ANSWER
+example.com. IN DNAME example.com.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+cyc.example.com. IN A
+SECTION ANSWER
+example.com. IN DNAME example.com.
+cyc.example.com. IN CNAME cyc.example.com.
+ENTRY_END
+RANGE_END
+; end of ns1.example.com.
+
+STEP 221000 TIME_PASSES ELAPSE 4000 ; need to expire example.com. DNAME
+
+;# QNAME owner DNAME target result
+;-- ---------------- -------------- -------------- -----------------
+; RFC original
+;10 cyc.example.com. example.com. c.example.com. cyc.c.example.com.
+;
+; our version
+; cyc2.example.com. example.com. cyc2.example.net.
+;
+; cyc.example.com. was renamed to cyc2.example.com. to avoid cache clashes
+; on the synthetized CNAME (caching CNAMEs is allowed by RFC 6672 section 3.4)
+; target c.example.com. was renamed to cyc2.example.net.
+; to limit number of pre-canned answers required for the test
+
+STEP 221001 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+cyc2.example.com. IN A
+ENTRY_END
+
+; Expected result is defined by RFC 1034 section 3.6.2:
+; CNAME chains should be followed and CNAME loops signalled as an error
+STEP 221002 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH rcode question answer
+REPLY SERVFAIL
+SECTION QUESTION
+cyc2.example.com. IN A
+SECTION ANSWER
+example.com. IN DNAME cyc2.example.net.
+cyc2.example.com. IN CNAME cyc2.cyc2.example.net.
+cyc2.example.net. IN DNAME example.com.
+cyc2.cyc2.example.net. IN CNAME cyc2.example.com.
+ENTRY_END
+
+; ns1.example.com.
+RANGE_BEGIN 221000 221099
+ ADDRESS 168.192.2.2
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns1.example.com.
+SECTION ADDITIONAL
+ns1.example.com. IN A 168.192.2.2
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns1.example.com. IN A
+SECTION ANSWER
+ns1.example.com. IN A 168.192.2.2
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns1.example.com. IN AAAA
+SECTION ANSWER
+ENTRY_END
+
+; line 10 DNAME
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+example.com. IN DNAME
+SECTION ANSWER
+example.com. IN DNAME cyc2.example.net.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR AA NOERROR
+SECTION QUESTION
+cyc2.example.com. IN A
+SECTION ANSWER
+example.com. IN DNAME cyc2.example.net.
+cyc2.example.com. IN CNAME cyc2.cyc2.example.net.
+ENTRY_END
+RANGE_END
+; end of ns1.example.com.
+
+;# QNAME owner DNAME target result
+;-- ---------------- -------------- -------------- -----------------
+;11 shortloop.x.x. x. . shortloop.x.
+
+STEP 221101 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+shortloop.x.x. TXT
+ENTRY_END
+
+STEP 221102 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH rcode question answer
+SECTION QUESTION
+shortloop.x.x. IN TXT
+SECTION ANSWER
+x. IN DNAME .
+shortloop.x.x. IN CNAME shortloop.x.
+shortloop.x. IN CNAME shortloop.
+shortloop. IN TXT "shortloop end"
+ENTRY_END
+
+;# QNAME owner DNAME target result
+;-- ---------------- -------------- -------------- -----------------
+;12 shortloop.x. x. . shortloop.
+
+; expire potentically cached CNAMEs for shortloop.x. from cache
+STEP 221200 TIME_PASSES ELAPSE 10000
+
+STEP 221201 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+shortloop.x. TXT
+ENTRY_END
+
+STEP 221202 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH rcode question answer
+SECTION QUESTION
+shortloop.x. IN TXT
+SECTION ANSWER
+x. IN DNAME .
+shortloop.x. IN CNAME shortloop.
+shortloop. IN TXT "shortloop end"
+ENTRY_END
+
+
+; ns1.example.net. (data shared by whole 22xxxx range)
+RANGE_BEGIN 220000 229999
+ ADDRESS 168.192.3.3
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+example.net. IN NS
+SECTION ANSWER
+example.net. IN NS ns1.example.net.
+SECTION ADDITIONAL
+example.net. IN A 168.192.3.3
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns1.example.net. IN A
+SECTION ANSWER
+ns1.example.net. IN A 168.192.3.3
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns1.example.net. IN AAAA
+SECTION ANSWER
+ENTRY_END
+
+; line 3
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+a.example.net. IN A
+SECTION ANSWER
+a.example.net. IN A 10.0.0.97
+ENTRY_END
+
+; line 4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+a.b.example.net. IN A
+SECTION ANSWER
+a.b.example.net. IN A 10.0.97.98
+ENTRY_END
+
+; empty non-terminal for QNAME minimization
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR AA NOERROR
+SECTION QUESTION
+y.example.net. IN NS
+SECTION ANSWER
+ENTRY_END
+
+; empty non-terminal for QNAME minimization
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR AA NOERROR
+SECTION QUESTION
+b.example.net. IN NS
+SECTION ANSWER
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+a2.y.example.net. IN A
+SECTION ANSWER
+a2.y.example.net. IN A 10.97.50.121
+ENTRY_END
+
+; line 10
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+cyc2.example.net. IN DNAME
+SECTION ANSWER
+cyc2.example.net. IN DNAME example.com.
+ENTRY_END
+
+; no other types, for QNAME minimization
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR AA NOERROR
+SECTION QUESTION
+cyc2.example.net. IN NS
+SECTION ANSWER
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+cyc2.cyc2.example.net. IN A
+SECTION ANSWER
+cyc2.example.net. IN DNAME example.com.
+cyc2.cyc2.example.net. IN CNAME cyc2.example.com.
+ENTRY_END
+RANGE_END
+; end of ns1.example.net.
+
+
+; RFC 6672 section 2.2: YXDOMAIN answers for too long results for substitution
+; RFC 6672 section 2.3: DNAME can be at zone apex: zone apex = long.
+STEP 229001 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+x.long. IN A
+ENTRY_END
+
+; query returning maximal permissible length - should work
+STEP 229002 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH rcode question answer
+SECTION QUESTION
+x.long. IN A
+SECTION ANSWER
+long. 3600 IN DNAME 63o-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.63o-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.63o-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.60o-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.
+x.long. 3600 IN CNAME x.63o-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.63o-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.63o-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.60o-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.
+x.63o-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.63o-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.63o-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.60o-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx. 3600 IN A 192.0.2.1
+ENTRY_END
+
+; result of substitution has too long name
+; YXDOMAIN should be propagated to the client
+STEP 229003 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+too.long. IN A
+ENTRY_END
+
+STEP 229004 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH rcode question answer
+REPLY YXDOMAIN
+SECTION QUESTION
+too.long. IN A
+SECTION ANSWER
+long. 3600 IN DNAME 63o-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.63o-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.63o-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.60o-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.
+ENTRY_END
+
+; YXDOMAIN should work even if the cache is empty
+STEP 229005 TIME_PASSES ELAPSE 4000
+
+STEP 229006 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+too.long. IN A
+ENTRY_END
+
+STEP 229007 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH rcode question answer
+REPLY YXDOMAIN
+SECTION QUESTION
+too.long. IN A
+SECTION ANSWER
+long. 3600 IN DNAME 63o-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.63o-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.63o-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.60o-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.
+ENTRY_END
+
+; TODO: two DNAMEs at the same owner = invalid data?
+;STEP 240021 QUERY
+;ENTRY_BEGIN
+;REPLY RD DO
+;SECTION QUESTION
+;test.twodnames. IN A
+;ENTRY_END
+;
+;STEP 240022 CHECK_ANSWER
+;ENTRY_BEGIN
+;MATCH rcode question answer
+;REPLY QR SERVFAIL
+;SECTION QUESTION
+;test.twodnames. IN A
+;ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/iter_dnsseclame_ds_ok.rpl b/tests/integration/deckard/sets/resolver/iter_dnsseclame_ds_ok.rpl
new file mode 100644
index 0000000..670879b
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/iter_dnsseclame_ds_ok.rpl
@@ -0,0 +1,371 @@
+do-ip6: no
+
+; config options
+;server:
+ trust-anchor: "example.com. 3600 IN DS 8378 7 1 0FCD3F3031F437036CA53411FD4B43BAB303B450 "
+val-override-date: "20181130121807"
+; target-fetch-policy: "0 0 0 0 0"
+; fake-sha1: yes
+
+;stub-zone:
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+
+query-minimization: off
+CONFIG_END
+
+SCENARIO_BEGIN Test dnssec-lame detection at ds point, which is ok.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.sub.example.com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.net. IN A
+SECTION AUTHORITY
+net. IN NS e.gtld-servers.net.
+SECTION ADDITIONAL
+e.gtld-servers.net. IN A 192.12.94.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.net. IN AAAA
+SECTION AUTHORITY
+net. IN NS e.gtld-servers.net.
+SECTION ADDITIONAL
+e.gtld-servers.net. IN A 192.12.94.30
+ENTRY_END
+
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.sub.example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.55
+ENTRY_END
+RANGE_END
+
+; e.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.12.94.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+net. IN NS
+SECTION ANSWER
+net. IN NS e.gtld-servers.net.
+SECTION ADDITIONAL
+e.gtld-servers.net. IN A 192.12.94.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.net. IN A
+SECTION AUTHORITY
+example.net. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.net. IN A 1.2.3.44
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.net. IN AAAA
+SECTION AUTHORITY
+example.net. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.net. IN A 1.2.3.44
+ENTRY_END
+RANGE_END
+
+; ns.example.net.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.44
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.net. IN NS
+SECTION ANSWER
+example.net. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.net. IN A 1.2.3.44
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns.example.net. IN A
+SECTION ANSWER
+ns.example.net. IN A 1.2.3.44
+SECTION AUTHORITY
+example.net. IN NS ns.example.net.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns.example.net. IN AAAA
+SECTION AUTHORITY
+example.net. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.net. IN A 1.2.3.44
+ENTRY_END
+
+; response to DNSKEY priming query
+; sub.example.com. 3600 IN DS 54180 5 1 67360E6697A9066D6904EE6E9879FB5990C6A724
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+sub.example.com. IN DNSKEY
+SECTION ANSWER
+sub.example.com. 3600 IN DNSKEY 256 3 5 AwEAAcXhoXQxDzxHC1U3t6ayuYVk2ufLVk59LEzGA2fYWBQiPbx0ay46 r0cuafuY1ueEB2KavEO7Esb9Tvo9ynWKg0DOIOpV4iNDVMUoNbZQj8X1 0WKgBHdaXc2aGC+EM9ozSnLKuV02+eNT/PxPsijqzkC7cJ32k4n1+sZ1 5Cywbo3Z ;{id = 30899 (zsk), size = 512b}
+sub.example.com. 3600 IN RRSIG DNSKEY 5 3 3600 20181230101806 20181130101806 54180 sub.example.com. unaHKPTSK0hncZIN8FVjcCtELPlo968TVskOpvMjhe3IgiTXMoVzBzW8 XNalW4wnelZVv1PYW0+6MGukDBBzJBRn9qKKrFyayMppIelbpC52SFqI H58AhMUJb2GlPJW9Xg19eF7FmSLrrYO0GMkfH5pAvd1aNOCckj4LJ1PS Sfg= ;{id = 30899}
+SECTION AUTHORITY
+; no NS set. not needed for this test.
+SECTION ADDITIONAL
+ns.sub.example.com. IN A 1.2.3.6
+ns.sub.example.com. 3600 IN RRSIG A 5 4 3600 20181230101806 20181130101806 54180 sub.example.com. dtxWwVO+T0vfjdrU9/COBJR6oshgdO8gkGusq573eBe8QzaXrV1cRLya Zj3qXUBrn61iOi2xEu0yEtfJx8++XGtzHrmTIFUGWOQW3BoyfLAVZC3b WrNKVljMMVAIWzwOBQguIVczW7vLAG6QAMICrI/es5xx8IMTYmoZOgXN RMo= ;{id = 30899}
+ENTRY_END
+
+; response to query of interest
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www.sub.example.com. IN A
+SECTION ANSWER
+www.sub.example.com. IN A 11.11.11.11
+www.sub.example.com. 3600 IN RRSIG A 5 4 3600 20181230101806 20181130101806 54180 sub.example.com. oGdNeh2GTFMtDsCIuJ6dTfwWjb7IpslFiUnH71I2a0X5E3acfvQ/3Xhs Paivy1SbIb2kaf3DMXYAbLBIhcyWGP45kXaP+5CRXkyt69gDcSVxKdZP rugy6m4LwaitTRlV44jDu6GxVZjXlAjd2d4rrz8qixRQIfEfk8IMX0L4 30U= ;{id = 30899}
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.55
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.55
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns.example.com. IN A
+SECTION ANSWER
+ns.example.com. IN A 1.2.3.55
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns.example.com. IN AAAA
+ENTRY_END
+
+; fine DNSKEY response.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+example.com. IN DNSKEY
+SECTION ANSWER
+example.com. 3600 IN DNSKEY 256 3 7 AwEAAcPpAFo67izrkhRxtGyVSpusyG5WmkRQ5UaJ+wdgqCFiDZtZoaY2 TLWnxkqm1shmK2ef+M9aUpbz2L8LpdDPJcUf+9tcR37/vVh5+RzhjAkD /V/wVQw4DincwuSXtk6yOfXXUyRBx9JDV9Y+R7Dg0MUeSDYwwd2ne2tz 5v8D+Hi/ ;{id = 2854 (zsk), size = 1688b}
+example.com. 3600 IN RRSIG DNSKEY 7 2 3600 20181230101806 20181130101806 8378 example.com. d54yctvAg31OPD9tML4Boh4u8/T9SZZtQfSaEyXq8Ean4MYtdVYzPp72 ZW6OuUXHxjPULWLoHA/y/vSNOmC5O5M9LZ1vU1kbPRwR/p7lzFtQuVYv Nmhpr8ohNuqms+wZue9akZXTv5gN8HL3eg/nqEuqVPHwrNhLX+okuNLK E50= ;{id = 2854}
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20181230101806 20181130101806 8378 example.com. d8xIochwH3oB29TjGvSXOsJOzdBm+5O/Yttdbcxy2S0psh/IBAyMZBqH QVkubqiM0Fj7kDdcEJFFqiDDZzKSlREQyaU9TY78bSjga5ZYXnoiy1Kc KKkvvwIXfzWkqyG1vm4wZtEOBDO9ho1sKoZrGVg/rEVhAnZTj/a25B9Q Ka8= ;{id = 2854}
+ENTRY_END
+
+; correct delegation with DS
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www.sub.example.com. IN A
+SECTION ANSWER
+SECTION AUTHORITY
+sub.example.com. IN NS ns.sub.example.com.
+sub.example.com. IN NS ns.example.net.
+sub.example.com. 3600 IN DS 54180 5 1 67360E6697A9066D6904EE6E9879FB5990C6A724
+sub.example.com. 3600 IN RRSIG DS 7 3 3600 20181230101806 20181130101806 8378 example.com. hnexEP0ej6KmZ3BYYOAqs8WgbSFS0psOYvcjJdeQPymmFYJgXdkkHznV cxTL8TrsS+2uD8gUEC/g4k8eEPc4my1wswalm1+d+KYan15inHzkRrko oC7kD705RvSEl6F5L7NbpmEYgqVjZb3PJAhppS54UYxsRdqhEZop3MmV KuA= ;{id = 2854}
+SECTION ADDITIONAL
+ns.sub.example.com. IN A 1.2.3.6
+ENTRY_END
+
+; response for delegation to sub.example.com.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+sub.example.com. IN DNSKEY
+SECTION ANSWER
+SECTION AUTHORITY
+sub.example.com. IN NS ns.sub.example.com.
+sub.example.com. IN NS ns.example.net.
+sub.example.com. 3600 IN DS 54180 5 1 67360E6697A9066D6904EE6E9879FB5990C6A724
+sub.example.com. 3600 IN RRSIG DS 7 3 3600 20181230101806 20181130101806 8378 example.com. hnexEP0ej6KmZ3BYYOAqs8WgbSFS0psOYvcjJdeQPymmFYJgXdkkHznV cxTL8TrsS+2uD8gUEC/g4k8eEPc4my1wswalm1+d+KYan15inHzkRrko oC7kD705RvSEl6F5L7NbpmEYgqVjZb3PJAhppS54UYxsRdqhEZop3MmV KuA= ;{id = 2854}
+SECTION ADDITIONAL
+ns.sub.example.com. IN A 1.2.3.6
+ENTRY_END
+RANGE_END
+
+; server is not DNSSEC lame.
+; ns.sub.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.6
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+sub.example.com. IN NS
+SECTION ANSWER
+sub.example.com. IN NS ns.sub.example.com.
+sub.example.com. IN NS ns.example.net.
+sub.example.com. 3600 IN RRSIG NS 5 3 3600 20181230101806 20181130101806 54180 sub.example.com. mCLLh1oDYHUCNY9nRUCe/j0yxPZDidmpNcoeIJlH9JxwV2TqHKgjBLzo awGJukxoAQgyY9v76ITVSRGreDKYe5GQ7beDKq/nIsZSB3S4kIDqXHGz 4Rr2GQvyNWuWRfsnqW09SL3yKET8QYkaIxdXarJrw/dA2gR/g0BGnv39 iEI= ;{id = 30899}
+SECTION ADDITIONAL
+ns.sub.example.com. IN A 1.2.3.6
+ns.sub.example.com. 3600 IN RRSIG A 5 4 3600 20181230101806 20181130101806 54180 sub.example.com. dtxWwVO+T0vfjdrU9/COBJR6oshgdO8gkGusq573eBe8QzaXrV1cRLya Zj3qXUBrn61iOi2xEu0yEtfJx8++XGtzHrmTIFUGWOQW3BoyfLAVZC3b WrNKVljMMVAIWzwOBQguIVczW7vLAG6QAMICrI/es5xx8IMTYmoZOgXN RMo= ;{id = 30899}
+ENTRY_END
+
+; response to DNSKEY priming query
+; sub.example.com. 3600 IN DS 54180 5 1 67360E6697A9066D6904EE6E9879FB5990C6A724
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+sub.example.com. IN DNSKEY
+SECTION ANSWER
+sub.example.com. 3600 IN DNSKEY 256 3 5 AwEAAcXhoXQxDzxHC1U3t6ayuYVk2ufLVk59LEzGA2fYWBQiPbx0ay46 r0cuafuY1ueEB2KavEO7Esb9Tvo9ynWKg0DOIOpV4iNDVMUoNbZQj8X1 0WKgBHdaXc2aGC+EM9ozSnLKuV02+eNT/PxPsijqzkC7cJ32k4n1+sZ1 5Cywbo3Z ;{id = 30899 (zsk), size = 512b}
+sub.example.com. 3600 IN RRSIG DNSKEY 5 3 3600 20181230101806 20181130101806 54180 sub.example.com. unaHKPTSK0hncZIN8FVjcCtELPlo968TVskOpvMjhe3IgiTXMoVzBzW8 XNalW4wnelZVv1PYW0+6MGukDBBzJBRn9qKKrFyayMppIelbpC52SFqI H58AhMUJb2GlPJW9Xg19eF7FmSLrrYO0GMkfH5pAvd1aNOCckj4LJ1PS Sfg= ;{id = 30899}
+ENTRY_END
+
+; response to query of interest
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www.sub.example.com. IN A
+SECTION ANSWER
+www.sub.example.com. IN A 11.11.11.11
+www.sub.example.com. 3600 IN RRSIG A 5 4 3600 20181230101806 20181130101806 54180 sub.example.com. oGdNeh2GTFMtDsCIuJ6dTfwWjb7IpslFiUnH71I2a0X5E3acfvQ/3Xhs Paivy1SbIb2kaf3DMXYAbLBIhcyWGP45kXaP+5CRXkyt69gDcSVxKdZP rugy6m4LwaitTRlV44jDu6GxVZjXlAjd2d4rrz8qixRQIfEfk8IMX0L4 30U= ;{id = 30899}
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns.sub.example.com. IN AAAA
+SECTION ANSWER
+ENTRY_END
+RANGE_END
+
+
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.sub.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 20 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+www.sub.example.com. IN A
+SECTION ANSWER
+www.sub.example.com. IN A 11.11.11.11
+www.sub.example.com. 3600 IN RRSIG A 5 4 3600 20181230101806 20181130101806 54180 sub.example.com. oGdNeh2GTFMtDsCIuJ6dTfwWjb7IpslFiUnH71I2a0X5E3acfvQ/3Xhs Paivy1SbIb2kaf3DMXYAbLBIhcyWGP45kXaP+5CRXkyt69gDcSVxKdZP rugy6m4LwaitTRlV44jDu6GxVZjXlAjd2d4rrz8qixRQIfEfk8IMX0L4 30U= ;{id = 30899}
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/iter_dnsseclame_ta_ok.rpl b/tests/integration/deckard/sets/resolver/iter_dnsseclame_ta_ok.rpl
new file mode 100644
index 0000000..bb2053e
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/iter_dnsseclame_ta_ok.rpl
@@ -0,0 +1,307 @@
+do-ip6: no
+
+; config options
+;server:
+ trust-anchor: "example.com. 3600 IN DS 63215 7 1 9B2A4B4CE971A6D1A2DFD23C03467F053F1D2D9C "
+val-override-date: "20181130121809"
+; target-fetch-policy: "0 0 0 0 0"
+; fake-sha1: yes
+
+;stub-zone:
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+
+query-minimization: off
+CONFIG_END
+
+SCENARIO_BEGIN Test dnssec-lame detection with anchor point that is ok.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.net. IN A
+SECTION AUTHORITY
+net. IN NS e.gtld-servers.net.
+SECTION ADDITIONAL
+e.gtld-servers.net. IN A 192.12.94.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.net. IN AAAA
+SECTION AUTHORITY
+net. IN NS e.gtld-servers.net.
+SECTION ADDITIONAL
+e.gtld-servers.net. IN A 192.12.94.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.55
+ENTRY_END
+RANGE_END
+
+; e.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.12.94.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+net. IN NS
+SECTION ANSWER
+net. IN NS e.gtld-servers.net.
+SECTION ADDITIONAL
+e.gtld-servers.net. IN A 192.12.94.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.net. IN A
+SECTION AUTHORITY
+example.net. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.net. IN A 1.2.3.44
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.net. IN AAAA
+SECTION AUTHORITY
+example.net. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.net. IN A 1.2.3.44
+ENTRY_END
+RANGE_END
+
+; ns.example.net.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.44
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.net. IN NS
+SECTION ANSWER
+example.net. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.net. IN A 1.2.3.44
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns.example.net. IN A
+SECTION ANSWER
+ns.example.net. IN A 1.2.3.44
+SECTION AUTHORITY
+example.net. IN NS ns.example.net.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns.example.net. IN AAAA
+SECTION AUTHORITY
+example.net. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.net. IN A 1.2.3.44
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+example.com. IN NS ns.example.net.
+example.com. 3600 IN RRSIG NS 7 2 3600 20181230101809 20181130101809 63215 example.com. ldaJ3pZ4qtnwcT+SudZ4G05ye0+FbtGoXuAxjRUVef/nee+8pgMLtK1a 0j1Ejg3IAit/nUKD58Ccfuo45Qwf/BnJvKeKltksGhOSEw+yoqD+QOHN ByiphD1qsmaECbLHgXm/1Wmrp5kLm15HvErBJv1nGp6aALaHkao3tkl4 ZAY= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.55
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101809 20181130101809 63215 example.com. dwaG446dWfL78qWJxkp9MO1SeV4xEt6MF3jYcpM6HGWgmn0peGy+zvzq TpeyMRCQFi52+MIGDPOnRtVVYpFnsUmH9dkoYGG+5ut9RUoyef4p7EsE BJncC/S5iMYaeEoU9yIwV/CZq/cdz465RroMKKJuI2NQW9gZn+MbFojY T3E= ;{id = 2854}
+ENTRY_END
+
+; response to DNSKEY priming query
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+example.com. IN DNSKEY
+SECTION ANSWER
+example.com. 3600 IN DNSKEY 256 3 7 AwEAAbeLIHEf7lEpCP1+GPvzCTJUDjUCMggHlkNWFbsT2xQsG3QVKInt h6KWLbfdgKp9RU1L5vyerphhEIsRwAGF/PZsIWc/kQsdXMWyiKcRwLHS l3JNydyTkl5oIhWu6SDaK51KWSaopxwhLZAtKWoQRKSRSdnlQg9B98sj ZWpAhm6V ;{id = 2854 (zsk), size = 1688b}
+example.com. 3600 IN RRSIG DNSKEY 7 2 3600 20181230101809 20181130101809 63215 example.com. PxtUfqGNISnTuabiNbxdZcPABScYoElxSp6CC5TIN8MNkMCsq4mMKqHw ECFdHX+s4K9frWEOVZT0uSvJFsVdhomtOR6zfc1jcc4p+SuDlIRfrAEL jREika0hP04tPwzDnQzZbswJK9lpwAglTvH4OSjZhHUEMuelZxTF8GyA WMc= ;{id = 2854}
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+www.example.com. 3600 IN RRSIG A 7 3 3600 20181230101809 20181130101809 63215 example.com. gRONsGpAzHBTe8PKGcxPo9mmvZZNOjZC/4Xn/36WIe8VTf1T67KDPHuz zeYpkxT6x1Fc5JzBWPOTvL+leugJ2p4N0tFTnYWmu0gVcYqRCa4KX5Yz ek9wkGdDS9yTZhQFWXe0ckWulaZb5f9Hxq/UpE2LdnLSLwUcmRATefML TvE= ;{id = 2854}
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns.example.com. IN AAAA
+SECTION ANSWER
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.55
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns.example.com. IN A
+SECTION ANSWER
+ns.example.com. IN A 1.2.3.55
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns.example.com. IN AAAA
+ENTRY_END
+
+; the response is not lame at all.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+example.com. IN DNSKEY
+SECTION ANSWER
+example.com. 3600 IN DNSKEY 256 3 7 AwEAAbeLIHEf7lEpCP1+GPvzCTJUDjUCMggHlkNWFbsT2xQsG3QVKInt h6KWLbfdgKp9RU1L5vyerphhEIsRwAGF/PZsIWc/kQsdXMWyiKcRwLHS l3JNydyTkl5oIhWu6SDaK51KWSaopxwhLZAtKWoQRKSRSdnlQg9B98sj ZWpAhm6V ;{id = 2854 (zsk), size = 1688b}
+example.com. 3600 IN RRSIG DNSKEY 7 2 3600 20181230101809 20181130101809 63215 example.com. PxtUfqGNISnTuabiNbxdZcPABScYoElxSp6CC5TIN8MNkMCsq4mMKqHw ECFdHX+s4K9frWEOVZT0uSvJFsVdhomtOR6zfc1jcc4p+SuDlIRfrAEL jREika0hP04tPwzDnQzZbswJK9lpwAglTvH4OSjZhHUEMuelZxTF8GyA WMc= ;{id = 2854}
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+example.com. IN NS ns.example.net.
+example.com. 3600 IN RRSIG NS 7 2 3600 20181230101809 20181130101809 63215 example.com. ldaJ3pZ4qtnwcT+SudZ4G05ye0+FbtGoXuAxjRUVef/nee+8pgMLtK1a 0j1Ejg3IAit/nUKD58Ccfuo45Qwf/BnJvKeKltksGhOSEw+yoqD+QOHN ByiphD1qsmaECbLHgXm/1Wmrp5kLm15HvErBJv1nGp6aALaHkao3tkl4 ZAY= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.55
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101809 20181130101809 63215 example.com. dwaG446dWfL78qWJxkp9MO1SeV4xEt6MF3jYcpM6HGWgmn0peGy+zvzq TpeyMRCQFi52+MIGDPOnRtVVYpFnsUmH9dkoYGG+5ut9RUoyef4p7EsE BJncC/S5iMYaeEoU9yIwV/CZq/cdz465RroMKKJuI2NQW9gZn+MbFojY T3E= ;{id = 2854}
+ENTRY_END
+
+; response is not lame.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+www.example.com. 3600 IN RRSIG A 7 3 3600 20181230101809 20181130101809 63215 example.com. gRONsGpAzHBTe8PKGcxPo9mmvZZNOjZC/4Xn/36WIe8VTf1T67KDPHuz zeYpkxT6x1Fc5JzBWPOTvL+leugJ2p4N0tFTnYWmu0gVcYqRCa4KX5Yz ek9wkGdDS9yTZhQFWXe0ckWulaZb5f9Hxq/UpE2LdnLSLwUcmRATefML TvE= ;{id = 2854}
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 20 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+www.example.com. 3600 IN RRSIG A 7 3 3600 20181230101809 20181130101809 63215 example.com. gRONsGpAzHBTe8PKGcxPo9mmvZZNOjZC/4Xn/36WIe8VTf1T67KDPHuz zeYpkxT6x1Fc5JzBWPOTvL+leugJ2p4N0tFTnYWmu0gVcYqRCa4KX5Yz ek9wkGdDS9yTZhQFWXe0ckWulaZb5f9Hxq/UpE2LdnLSLwUcmRATefML TvE= ;{id = 2854}
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/iter_domain_sale.rpl b/tests/integration/deckard/sets/resolver/iter_domain_sale.rpl
new file mode 100644
index 0000000..9ab1330
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/iter_domain_sale.rpl
@@ -0,0 +1,271 @@
+do-ip6: no
+
+; config options
+; target-fetch-policy: "0 0 0 0 0"
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test resolver with a domain sale
+; and the old operator is nasty, keeps running his server with the old data.
+; and lots of lookups keep going towards the domain.
+; eventually, the NS record has to timeout.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net. (before sale of domain)
+RANGE_BEGIN 0 20
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net. (after sale of domain)
+RANGE_BEGIN 30 200
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 8.8.8.8
+ENTRY_END
+RANGE_END
+
+; ns.example.com. first owner
+RANGE_BEGIN 0 200
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR AA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. 3600 IN A 10.20.30.40
+SECTION AUTHORITY
+example.com. 3600 IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. 3600 IN A 1.2.3.4
+ENTRY_END
+
+; nxdomains for any name,type
+; last in RANGE so that it matches everything left over.
+; it includes the NS record.
+ENTRY_BEGIN
+MATCH opcode
+ADJUST copy_id copy_query
+REPLY QR AA NXDOMAIN
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+SECTION AUTHORITY
+example.com. 3600 IN SOA a. b. 1 2 3 4 5
+example.com. 3600 IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. 3600 IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+; ns.example.com. new owner
+RANGE_BEGIN 0 200
+ ADDRESS 8.8.8.8
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 8.8.8.8
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. 3600 IN A 88.88.88.88
+SECTION AUTHORITY
+example.com. 3600 IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. 3600 IN A 8.8.8.8
+ENTRY_END
+RANGE_END
+
+; Fetch the old record from the old owner.
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+; recursion happens here.
+STEP 5 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. 3600 IN A 10.20.30.40
+;SECTION AUTHORITY
+;example.com. 3600 IN NS ns.example.com.
+;SECTION ADDITIONAL
+;ns.example.com. 3600 IN A 1.2.3.4
+ENTRY_END
+
+; the domain is sold (right at this time).
+; but the information stays in the cache.
+
+; after 1800 secs still the cached answer
+STEP 20 TIME_PASSES ELAPSE 1800
+
+STEP 30 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+; recursion happens here.
+STEP 40 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. 1800 IN A 10.20.30.40
+;SECTION AUTHORITY
+;example.com. 1800 IN NS ns.example.com.
+;SECTION ADDITIONAL
+;ns.example.com. 1800 IN A 1.2.3.4
+ENTRY_END
+
+; and ask another query
+STEP 50 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+nx1.example.com. IN A
+ENTRY_END
+; recursion happens here.
+STEP 60 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NXDOMAIN
+SECTION QUESTION
+nx1.example.com. IN A
+SECTION ANSWER
+SECTION AUTHORITY
+example.com. 3600 IN SOA a. b. 1 2 3 4 5
+example.com. 3600 IN NS ns.example.com.
+;SECTION ADDITIONAL
+;ns.example.com. 1800 IN A 1.2.3.4
+ENTRY_END
+
+; after another 1900 seconds the domain must have timed out.
+STEP 70 TIME_PASSES ELAPSE 1900
+
+; the NS record should have timed out.
+STEP 80 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+; recursion happens here.
+STEP 90 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. 3600 IN A 88.88.88.88
+;SECTION AUTHORITY
+;example.com. 3600 IN NS ns.example.com.
+;SECTION ADDITIONAL
+;ns.example.com. 3600 IN A 8.8.8.8
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/iter_domain_sale_nschange.rpl b/tests/integration/deckard/sets/resolver/iter_domain_sale_nschange.rpl
new file mode 100644
index 0000000..96d2114
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/iter_domain_sale_nschange.rpl
@@ -0,0 +1,350 @@
+do-ip6: no
+
+; config options
+; target-fetch-policy: "0 0 0 0 0"
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test resolver with a domain sale and NS changes
+; and the old operator is nasty, keeps running his server with the old data.
+; and lots of lookups keep going towards the domain.
+; and the old server is changing the NS record of the old domain.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net. (before sale of domain)
+RANGE_BEGIN 0 20
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+a.gtld-servers.net. IN AAAA
+SECTION AUTHORITY
+. SOA bla bla 1 2 3 4 5
+ENTRY_END
+
+RANGE_END
+
+; a.gtld-servers.net. (after sale of domain)
+RANGE_BEGIN 30 200
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 8.8.8.8
+ENTRY_END
+RANGE_END
+
+; ns.example.com. first owner
+RANGE_BEGIN 0 30
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR AA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. 3600 IN A 10.20.30.40
+SECTION AUTHORITY
+example.com. 3600 IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. 3600 IN A 1.2.3.4
+ENTRY_END
+
+; nxdomains for any name,type
+; last in RANGE so that it matches everything left over.
+; it includes the NS record.
+ENTRY_BEGIN
+MATCH opcode
+ADJUST copy_id copy_query
+REPLY QR AA NXDOMAIN
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+SECTION AUTHORITY
+example.com. 3600 IN SOA a. b. 1 2 3 4 5
+example.com. 3600 IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. 3600 IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+; ns.example.com. first owner, NS changed
+RANGE_BEGIN 40 200
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS nsb.example.com.
+SECTION ADDITIONAL
+nsb.example.com. IN A 1.2.3.4
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR AA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. 3600 IN A 10.20.30.40
+SECTION AUTHORITY
+example.com. 3600 IN NS nsb.example.com.
+SECTION ADDITIONAL
+nsb.example.com. 3600 IN A 1.2.3.4
+ENTRY_END
+
+; nxdomains for any name,type
+; last in RANGE so that it matches everything left over.
+; it includes the NS record.
+ENTRY_BEGIN
+MATCH opcode
+ADJUST copy_id copy_query
+REPLY QR AA NXDOMAIN
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+SECTION AUTHORITY
+example.com. 3600 IN SOA a. b. 1 2 3 4 5
+example.com. 3600 IN NS nsb.example.com.
+SECTION ADDITIONAL
+nsb.example.com. 3600 IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+; ns.example.com. new owner
+RANGE_BEGIN 0 200
+ ADDRESS 8.8.8.8
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 8.8.8.8
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. 3600 IN A 88.88.88.88
+SECTION AUTHORITY
+example.com. 3600 IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. 3600 IN A 8.8.8.8
+ENTRY_END
+RANGE_END
+
+; Fetch the old record from the old owner.
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+; recursion happens here.
+STEP 5 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. 3600 IN A 10.20.30.40
+;SECTION AUTHORITY
+;example.com. 3600 IN NS ns.example.com.
+;SECTION ADDITIONAL
+;ns.example.com. 3600 IN A 1.2.3.4
+ENTRY_END
+
+; the domain is sold (right at this time).
+; but the information stays in the cache.
+
+; after 1800 secs still the cached answer
+STEP 20 TIME_PASSES ELAPSE 1800
+
+STEP 30 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+; recursion happens here.
+STEP 40 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. 1800 IN A 10.20.30.40
+;SECTION AUTHORITY
+;example.com. 1800 IN NS ns.example.com.
+;SECTION ADDITIONAL
+;ns.example.com. 1800 IN A 1.2.3.4
+ENTRY_END
+
+; and ask another query
+STEP 50 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+nx1.example.com. IN A
+ENTRY_END
+; recursion happens here.
+STEP 60 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NXDOMAIN
+SECTION QUESTION
+nx1.example.com. IN A
+SECTION ANSWER
+SECTION AUTHORITY
+example.com. 3600 IN SOA a. b. 1 2 3 4 5
+example.com. 3600 IN NS nsb.example.com.
+;SECTION ADDITIONAL
+;nsb.example.com. 3600 IN A 1.2.3.4
+ENTRY_END
+
+STEP 62 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+nx1.example.com. IN A
+ENTRY_END
+; recursion happens here.
+STEP 63 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NXDOMAIN
+SECTION QUESTION
+nx1.example.com. IN A
+SECTION ANSWER
+SECTION AUTHORITY
+example.com. 3600 IN SOA a. b. 1 2 3 4 5
+example.com. 3600 IN NS nsb.example.com.
+;SECTION ADDITIONAL
+;nsb.example.com. 3600 IN A 1.2.3.4
+ENTRY_END
+
+; after another 1900 seconds the domain must have timed out.
+STEP 70 TIME_PASSES ELAPSE 1900
+
+; the NS record should have timed out.
+STEP 80 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+; recursion happens here.
+STEP 90 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. 3600 IN A 88.88.88.88
+;SECTION AUTHORITY
+;example.com. 3600 IN NS ns.example.com.
+;SECTION ADDITIONAL
+;ns.example.com. 3600 IN A 8.8.8.8
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/iter_donotq127.rpl b/tests/integration/deckard/sets/resolver/iter_donotq127.rpl
new file mode 100644
index 0000000..6cc01ab
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/iter_donotq127.rpl
@@ -0,0 +1,198 @@
+do-ip6: no
+
+; config options
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test iterator donotquery of 127/8.
+; The scenario presents an iteration chain that has 127.0.0.2 and
+; 127.255.255.255 as nameserver IPs, like a spam-blocklist.
+; these are 127/8 localhost and should be blocked, causing servfail.
+; if not blocked, they cause a lookup, but this file does not specify
+; 127.* responses, so testbound will fail the test.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+net. IN AAAA
+SECTION AUTHORITY
+. SOA bla bla 1 2 3 4 5
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+gtld-servers.net. IN AAAA
+SECTION AUTHORITY
+. SOA bla bla 1 2 3 4 5
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+a.gtld-servers.net. IN A
+SECTION ANSWER
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+a.gtld-servers.net. IN AAAA
+SECTION AUTHORITY
+. SOA bla bla 1 2 3 4 5
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id copy_query
+REPLY QR SERVFAIL
+SECTION QUESTION
+ns.example.com. IN AAAA
+SECTION AUTHORITY
+com. SOA bla bla 1 2 3 4 5
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id copy_query
+REPLY QR SERVFAIL
+SECTION QUESTION
+ns2.example.com. IN AAAA
+SECTION AUTHORITY
+com. SOA bla bla 1 2 3 4 5
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. IN NS ns2.example.com.
+SECTION ADDITIONAL
+;ns.example.com. IN A 1.2.3.4
+ns.example.com. IN A 127.255.255.255
+ns2.example.com. IN A 127.0.0.2
+ENTRY_END
+
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+example.com. IN NS ns2.example.com.
+SECTION ADDITIONAL
+;ns.example.com. IN A 1.2.3.4
+ns.example.com. IN A 127.255.255.255
+ns2.example.com. IN A 127.0.0.2
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+
+RANGE_END
+
+; ns.example.com trap
+RANGE_BEGIN 0 100
+ ADDRESS 127.255.255.255
+RANGE_END
+
+; ns.example.com trap
+RANGE_BEGIN 0 100
+ ADDRESS 127.0.0.2
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA SERVFAIL
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/iter_ds_locate_ns.rpl b/tests/integration/deckard/sets/resolver/iter_ds_locate_ns.rpl
new file mode 100644
index 0000000..732c0f4
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/iter_ds_locate_ns.rpl
@@ -0,0 +1,146 @@
+do-ip6: no
+
+; config options
+;server:
+; target-fetch-policy: "0 0 0 0 0"
+
+;stub-zone:
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test locate of NS records for parent nameservers of DS
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+; content of root-servers.net
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+root-servers.net. IN NS
+SECTION ANSWER
+root-servers.net. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+k.root-servers.net. IN A
+SECTION ANSWER
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+SECTION AUTHORITY
+root-servers.net. IN NS K.ROOT-SERVERS.NET.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+k.root-servers.net. IN AAAA
+SECTION ANSWER
+SECTION AUTHORITY
+root-servers.net. IN SOA K.ROOT-SERVERS.NET. hostmaster. 1 2 3 4 5
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+root-servers.net. IN DS
+SECTION ANSWER
+SECTION AUTHORITY
+root-servers.net. IN SOA K.ROOT-SERVERS.NET. hostmaster. 1 2 3 4 5
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+net. IN A
+SECTION AUTHORITY
+net. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+net. IN NS
+SECTION ANSWER
+net. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+root-servers.net. IN DS
+SECTION AUTHORITY
+net. IN SOA a.gtld-servers.net. hostmaster. 2 3 4 5 6
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+root-servers.net. IN A
+SECTION AUTHORITY
+root-servers.net. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+root-servers.net. IN DS
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH opcode qname flags rcode question answer
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+root-servers.net. IN DS
+SECTION ANSWER
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/iter_ds_locate_ns_nosoa.rpl b/tests/integration/deckard/sets/resolver/iter_ds_locate_ns_nosoa.rpl
new file mode 100644
index 0000000..932e321
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/iter_ds_locate_ns_nosoa.rpl
@@ -0,0 +1,146 @@
+do-ip6: no
+
+; config options
+;server:
+; target-fetch-policy: "0 0 0 0 0"
+
+;stub-zone:
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test locate of NS records for DS without a SOA record
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+; content of root-servers.net
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+root-servers.net. IN NS
+SECTION ANSWER
+root-servers.net. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+k.root-servers.net. IN A
+SECTION ANSWER
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+SECTION AUTHORITY
+root-servers.net. IN NS K.ROOT-SERVERS.NET.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+k.root-servers.net. IN AAAA
+SECTION ANSWER
+SECTION AUTHORITY
+root-servers.net. IN SOA K.ROOT-SERVERS.NET. hostmaster. 1 2 3 4 5
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+root-servers.net. IN DS
+SECTION ANSWER
+SECTION AUTHORITY
+;root-servers.net. IN SOA K.ROOT-SERVERS.NET. hostmaster. 1 2 3 4 5
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+net. IN A
+SECTION AUTHORITY
+net. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+net. IN NS
+SECTION ANSWER
+net. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+root-servers.net. IN DS
+SECTION AUTHORITY
+net. IN SOA a.gtld-servers.net. hostmaster. 2 3 4 5 6
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+root-servers.net. IN A
+SECTION AUTHORITY
+root-servers.net. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+root-servers.net. IN DS
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH opcode qname flags rcode question answer
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+root-servers.net. IN DS
+SECTION ANSWER
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/iter_escape_bailiwick.rpl b/tests/integration/deckard/sets/resolver/iter_escape_bailiwick.rpl
new file mode 100644
index 0000000..ae57c32
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/iter_escape_bailiwick.rpl
@@ -0,0 +1,220 @@
+do-ip6: no
+
+stub-addr: 193.0.14.129
+CONFIG_END
+SCENARIO_BEGIN Test a case where parent NS advertises non-existent zone cut, and the final NS tries to answer from its parent's zone cut.
+; That is treated as an attempt to escape bailiwick and is treated specially.
+; The NS from final answer MUST NOT be cached, but it should still be used for resolution.
+
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+; net.
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+net. IN NS
+SECTION AUTHORITY
+. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+; root-servers.net.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+root-servers.net. IN NS
+SECTION ANSWER
+root-servers.net. IN NS k.root-servers.net.
+SECTION ADDITIONAL
+k.root-servers.net. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+root-servers.net. IN A
+SECTION AUTHORITY
+root-servers.net. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+k.root-servers.net. IN A
+SECTION ANSWER
+k.root-servers.net. IN A 193.0.14.129
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+k.root-servers.net. IN AAAA
+SECTION AUTHORITY
+root-servers.net. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+; gtld-servers.net.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+gtld-servers.net. IN NS
+SECTION ANSWER
+gtld-servers.net. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+gtld-servers.net. IN A
+SECTION AUTHORITY
+gtld-servers.net. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+a.gtld-servers.net. IN A
+SECTION ANSWER
+a.gtld-servers.net. IN A 192.5.6.30
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+a.gtld-servers.net. IN AAAA
+SECTION AUTHORITY
+gtld-servers.net. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN A
+SECTION AUTHORITY
+com. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION AUTHORITY
+www.example.com. IN NS ns.example.com. ; Introduce non-existing zone cut
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/iter_hint_lame.rpl b/tests/integration/deckard/sets/resolver/iter_hint_lame.rpl
new file mode 100644
index 0000000..5529269
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/iter_hint_lame.rpl
@@ -0,0 +1,172 @@
+do-ip6: no
+
+; config options
+; target-fetch-policy: "0 0 0 0 0"
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+ ; minimization does not affect priming query
+ query-minimization: off
+CONFIG_END
+
+SCENARIO_BEGIN Test iterative resolve with lame hints (RA flag on but no AA flag)
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+; flags are intentionally weird: it should have AA instead of RA
+REPLY QR RA NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RA NOERROR
+SECTION QUESTION
+K.ROOT-SERVERS.NET. IN A
+SECTION ANSWER
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RA NOERROR
+SECTION QUESTION
+K.ROOT-SERVERS.NET. IN AAAA
+SECTION AUTHORITY
+. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RA NOERROR
+SECTION QUESTION
+a.gtld-servers.net. IN A
+SECTION ANSWER
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RA NOERROR
+SECTION QUESTION
+a.gtld-servers.net. IN AAAA
+SECTION AUTHORITY
+. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR RA NOERROR
+SECTION QUESTION
+com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.com IN A
+SECTION ANSWER
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH flags rcode question answer
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+;SECTION AUTHORITY
+;example.com. IN NS ns.example.com.
+;SECTION ADDITIONAL
+;ns.example.com. IN A 1.2.3.4
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/iter_lame_aaaa.rpl b/tests/integration/deckard/sets/resolver/iter_lame_aaaa.rpl
new file mode 100644
index 0000000..18697b4
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/iter_lame_aaaa.rpl
@@ -0,0 +1,180 @@
+do-ip6: no
+
+; config options
+; target-fetch-policy: "0 0 0 0 0"
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+;test from testbound
+
+SCENARIO_BEGIN Test iterator lameness detection of AAAA-only lameness
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN AAAA
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN AAAA
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.com. IN AAAA
+SECTION ANSWER
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.com. IN A
+SECTION ANSWER
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+
+
+; response to AAAA query
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+example.com. IN AAAA
+SECTION ANSWER
+SECTION AUTHORITY
+. 3600000 IN NS a.root-servers.net.
+. 3600000 IN NS b.root-servers.net.
+. 3600000 IN NS c.root-servers.net.
+. 3600000 IN NS d.root-servers.net.
+. 3600000 IN NS e.root-servers.net.
+. 3600000 IN NS f.root-servers.net.
+. 3600000 IN NS g.root-servers.net.
+. 3600000 IN NS h.root-servers.net.
+. 3600000 IN NS i.root-servers.net.
+. 3600000 IN NS j.root-servers.net.
+. 3600000 IN NS k.root-servers.net.
+. 3600000 IN NS l.root-servers.net.
+. 3600000 IN NS m.root-servers.net.
+SECTION ADDITIONAL
+a.root-servers.net. 3600000 IN A 198.41.0.4
+b.root-servers.net. 3600000 IN A 128.9.0.107
+c.root-servers.net. 3600000 IN A 192.33.4.12
+ENTRY_END
+
+; response to A query
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+example.com. IN A
+SECTION ANSWER
+example.com. 120 IN A 204.14.213.188
+ENTRY_END
+RANGE_END
+
+; Now try the A type, which works, and is not LAME.
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+example.com. IN A
+ENTRY_END
+
+; this doesn't fail
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+example.com. IN A
+SECTION ANSWER
+example.com. 120 IN A 204.14.213.188
+ENTRY_END
+
+; this fails; it is LAME
+STEP 20 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+example.com. IN AAAA
+ENTRY_END
+
+STEP 30 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA SERVFAIL
+SECTION QUESTION
+example.com. IN AAAA
+SECTION ANSWER
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/iter_lame_noaa.rpl b/tests/integration/deckard/sets/resolver/iter_lame_noaa.rpl
new file mode 100644
index 0000000..af964fb
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/iter_lame_noaa.rpl
@@ -0,0 +1,126 @@
+do-ip6: no
+
+; config options
+; harden-referral-path: no
+; target-fetch-policy: "0 0 0 0 0"
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+ ; test with pre-scripted replies does not make sense with qmin
+ query-minimization: off
+CONFIG_END
+
+SCENARIO_BEGIN Test lame detection if AA bit is omitted
+; the query is answered with a reply that has
+; no AA bit
+; no SOA record
+; noanswer/noerror
+; NS record in there which is not a down delegation (==).
+; the query is not sent to a forward zone
+
+STEP 10 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+; root prime is sent
+STEP 30 REPLY
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+; query sent to root server
+STEP 50 REPLY
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+; query sent to .com server
+STEP 70 REPLY
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns1.example.com.
+example.com. IN NS ns2.example.com.
+SECTION ADDITIONAL
+ns1.example.com. IN A 168.192.2.2
+ns2.example.com. IN A 168.192.3.3
+ENTRY_END
+
+; no matter which one the iterator tries first, we present it as 'lame'
+; query to ns1.example.com or ns2.example.com.
+STEP 90 REPLY
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION AUTHORITY
+; This is the BROKEN ANSWER here.
+; it is lame. A delegation to example.com. itself.
+example.com. IN NS ns1.example.com.
+example.com. IN NS ns2.example.com.
+SECTION ADDITIONAL
+ns1.example.com. IN A 168.192.2.2
+ns2.example.com. IN A 168.192.3.3
+ENTRY_END
+
+; iterator should try again and ask the other nameserver.
+STEP 110 REPLY
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+SECTION AUTHORITY
+example.com. IN NS ns1.example.com.
+example.com. IN NS ns2.example.com.
+SECTION ADDITIONAL
+ns1.example.com. IN A 168.192.2.2
+ns2.example.com. IN A 168.192.3.3
+ENTRY_END
+
+
+; is the final answer correct?
+STEP 200 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+;SECTION AUTHORITY
+;example.com. IN NS ns1.example.com.
+;example.com. IN NS ns2.example.com.
+;SECTION ADDITIONAL
+;ns1.example.com. IN A 168.192.2.2
+;ns2.example.com. IN A 168.192.3.3
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/iter_lame_nosoa.rpl b/tests/integration/deckard/sets/resolver/iter_lame_nosoa.rpl
new file mode 100644
index 0000000..632ac72
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/iter_lame_nosoa.rpl
@@ -0,0 +1,293 @@
+do-ip6: no
+
+; config options
+; target-fetch-policy: "0 0 0 0 0"
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test resolution with lame reply looks like nodata with noSOA
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+net. IN NS
+SECTION AUTHORITY
+net. IN NS e.gtld-servers.net.
+SECTION ADDITIONAL
+e.gtld-servers.net. IN A 192.12.94.30
+ENTRY_END
+
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.55
+ENTRY_END
+RANGE_END
+
+; e.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.12.94.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+net. IN NS
+SECTION ANSWER
+net. IN NS e.gtld-servers.net.
+SECTION ADDITIONAL
+e.gtld-servers.net. IN A 192.12.94.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.net. IN NS
+SECTION AUTHORITY
+example.net. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.net. IN A 1.2.3.44
+ENTRY_END
+RANGE_END
+
+; ns.example.net.
+; advertises +RA so it is REC_LAME.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.44
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RA NOERROR
+SECTION QUESTION
+example.net. IN NS
+SECTION ANSWER
+example.net. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.net. IN A 1.2.3.44
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RA NOERROR
+SECTION QUESTION
+ns.example.net. IN A
+SECTION ANSWER
+ns.example.net. IN A 1.2.3.44
+SECTION AUTHORITY
+example.net. IN NS ns.example.net.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RA NOERROR
+SECTION QUESTION
+ns.example.net. IN AAAA
+SECTION AUTHORITY
+example.net. IN NS ns.example.net.
+SECTION ADDITIONAL
+www.example.net. IN A 1.2.3.44
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RA NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.net.
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.55
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RA NOERROR
+SECTION QUESTION
+ns.example.com. IN AAAA
+SECTION ANSWER
+SECTION AUTHORITY
+example.com. IN NS ns.example.net.
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.55
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RA NOERROR
+SECTION QUESTION
+ns.example.com. IN A
+SECTION ANSWER
+ns.example.com. IN A 1.2.3.55
+SECTION AUTHORITY
+example.com. IN NS ns.example.net.
+example.com. IN NS ns.example.com.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+SECTION AUTHORITY
+example.com. IN NS ns.example.net.
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.55
+ns.example.net IN A 1.2.3.44
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RA NOERROR
+SECTION QUESTION
+mail.example.com. IN A
+SECTION ANSWER
+SECTION AUTHORITY
+example.com. IN NS ns.example.net.
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.55
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+; is like a BIND server that is LAME, authoritative for other domains,
+; but not this one, and somehow got this NS record in its cache.
+; trying to give 'lame referral' but to the same name, not up.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.55
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ENTRY_END
+RANGE_END
+
+; store bad timing for one server to influence server selection
+; 1.2.3.44 (ns.example.net) gets 900 msec.
+; so the 376 ns.example.com is preferred.
+;STEP 1 INFRA_RTT 1.2.3.44 example.net. 900
+
+STEP 10 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 20 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+;SECTION AUTHORITY
+;example.com. IN NS ns.example.net.
+;example.com. IN NS ns.example.com.
+;SECTION ADDITIONAL
+;ns.example.com. IN A 1.2.3.55
+; scrubbed off
+;ns.example.net IN A 1.2.3.44
+ENTRY_END
+
+; query to recursion-lame server
+STEP 30 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+mail.example.com. IN A
+ENTRY_END
+
+; It's somewhat OK if resolver accepts the only upstream lame server,
+; it's also OK if it ignores lame upstream, because it's not
+; provably authoritative for this zone. (kresd is the latter)
+STEP 40 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA SERVFAIL
+SECTION QUESTION
+mail.example.com. IN A
+SECTION ANSWER
+;SECTION AUTHORITY
+;example.com. IN NS ns.example.net.
+;example.com. IN NS ns.example.com.
+;SECTION ADDITIONAL
+ENTRY_END
+
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/iter_lame_root.rpl b/tests/integration/deckard/sets/resolver/iter_lame_root.rpl
new file mode 100644
index 0000000..35fc83d
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/iter_lame_root.rpl
@@ -0,0 +1,35 @@
+do-ip6: no
+
+stub-addr: 193.0.14.129
+CONFIG_END
+SCENARIO_BEGIN Test iterative resolve with lame root.
+
+; broken root server: K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode
+ADJUST copy_id copy_query
+REPLY QR RA SERVFAIL
+SECTION QUESTION
+. IN NS
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA SERVFAIL
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/iter_lamescrub.rpl b/tests/integration/deckard/sets/resolver/iter_lamescrub.rpl
new file mode 100644
index 0000000..6b4c9ce
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/iter_lamescrub.rpl
@@ -0,0 +1,152 @@
+do-ip6: no
+
+; config options
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+;test from testbound
+
+SCENARIO_BEGIN Test lameness detection after scrubber.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+a.gtld-servers.net. IN AAAA
+SECTION ANSWER
+ENTRY_END
+ENTRY_BEGIN
+
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+a.gtld-servers.net. IN A
+SECTION ANSWER
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+; This server is Lame!
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode
+ADJUST copy_id copy_query
+REPLY QR RD NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+SECTION AUTHORITY
+com. 155182 IN NS a.gtld-servers.net.
+com. 155182 IN NS b.gtld-servers.net.
+com. 155182 IN NS c.gtld-servers.net.
+com. 155182 IN NS d.gtld-servers.net.
+com. 155182 IN NS e.gtld-servers.net.
+com. 155182 IN NS f.gtld-servers.net.
+com. 155182 IN NS g.gtld-servers.net.
+com. 155182 IN NS h.gtld-servers.net.
+com. 155182 IN NS i.gtld-servers.net.
+com. 155182 IN NS j.gtld-servers.net.
+com. 155182 IN NS k.gtld-servers.net.
+com. 155182 IN NS l.gtld-servers.net.
+com. 155182 IN NS m.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. 155182 IN A 192.5.6.30
+b.gtld-servers.net. 155182 IN A 192.33.14.30
+c.gtld-servers.net. 155182 IN A 192.26.92.30
+d.gtld-servers.net. 155182 IN A 192.31.80.30
+e.gtld-servers.net. 155182 IN A 192.12.94.30
+f.gtld-servers.net. 155182 IN A 192.35.51.30
+g.gtld-servers.net. 155182 IN A 192.42.93.30
+h.gtld-servers.net. 155182 IN A 192.54.112.30
+i.gtld-servers.net. 155182 IN A 192.43.172.30
+j.gtld-servers.net. 155182 IN A 192.48.79.30
+k.gtld-servers.net. 155182 IN A 192.52.178.30
+l.gtld-servers.net. 155182 IN A 192.41.162.30
+m.gtld-servers.net. 155182 IN A 192.55.83.30
+a.gtld-servers.net. 155182 IN AAAA 2001:503:a83e::2:30
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+; recursin happens here
+
+; check that the answer is a failure (lame server)
+; and not a nodata-noerror message (false answer classification).
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA SERVFAIL
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/iter_minim_a.rpl b/tests/integration/deckard/sets/resolver/iter_minim_a.rpl
new file mode 100644
index 0000000..40280e5
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/iter_minim_a.rpl
@@ -0,0 +1,95 @@
+do-ip6: no
+
+; config options
+; target-fetch-policy: "0 0 0 0 0"
+ query-minimization: on
+; name: "."
+ stub-addr: 127.0.0.10 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test basic query minimization www.example.com.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 127.0.0.10
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 127.0.0.10
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/iter_minim_a_nxdomain.rpl b/tests/integration/deckard/sets/resolver/iter_minim_a_nxdomain.rpl
new file mode 100644
index 0000000..a61ce59
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/iter_minim_a_nxdomain.rpl
@@ -0,0 +1,106 @@
+do-ip6: no
+
+; config options
+; target-fetch-policy: "0 0 0 0 0"
+ query-minimization: on
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test basic query minimization sub.www.example.com. when NS doesn't show empty non-terminal.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NXDOMAIN
+SECTION QUESTION
+www.example.com. IN NS
+SECTION ANSWER
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+sub.www.example.com. IN A
+SECTION ANSWER
+sub.www.example.com. IN A 10.20.30.40
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+sub.www.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+sub.www.example.com. IN A
+SECTION ANSWER
+sub.www.example.com. IN A 10.20.30.40
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/iter_minim_nonempty.rpl b/tests/integration/deckard/sets/resolver/iter_minim_nonempty.rpl
new file mode 100644
index 0000000..6b0c89e
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/iter_minim_nonempty.rpl
@@ -0,0 +1,134 @@
+do-ip6: no
+
+; config options
+; target-fetch-policy: "0 0 0 0 0"
+ query-minimization: on
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test query minimization with terminal in resolution path.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+net. IN NS
+SECTION ANSWER
+net. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+gtld-servers.net. IN NS
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+a.gtld-servers.net. IN AAAA
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION AUTHORITY
+com. IN NS lame-addr.gtld-servers.net.
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+lame-addr.gtld-servers.net. IN A 1.1.1.1
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; lame.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 1.1.1.1
+
+ENTRY_BEGIN
+MATCH opcode
+ADJUST copy_id copy_query
+REPLY QR SERVFAIL
+SECTION QUESTION
+. IN NS
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY AA QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN CNAME nowhere.cdn.example.com.
+SECTION AUTHORITY
+; Suggest authority of 'nowhere' (which must not be followed)
+cdn.example.com. IN NS ns01.cdn.example.com.
+SECTION ADDITIONAL
+ns01.cdn.example.com. IN A 1.1.1.1
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www.example.com. IN NS
+SECTION ANSWER
+www.example.com. IN NS blackhole.
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+ENTRY_END
+
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+FLAGS RD
+SECTION QUESTION
+www.example.com. IN NS
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.example.com. IN NS
+SECTION ANSWER
+www.example.com. IN NS blackhole.
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/iter_minim_ns.rpl b/tests/integration/deckard/sets/resolver/iter_minim_ns.rpl
new file mode 100644
index 0000000..4f4a241
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/iter_minim_ns.rpl
@@ -0,0 +1,128 @@
+do-ip6: no
+
+; config options
+; target-fetch-policy: "0 0 0 0 0"
+ query-minimization: on
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test query minimization with empty-nonterminal in path.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+net. IN NS
+SECTION ANSWER
+net. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+gtld-servers.net. IN NS
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+a.gtld-servers.net. IN AAAA
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION AUTHORITY
+com. IN NS lame-addr.gtld-servers.net.
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+lame-addr.gtld-servers.net. IN A 1.1.1.1
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; lame.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 1.1.1.1
+
+ENTRY_BEGIN
+MATCH opcode
+ADJUST copy_id copy_query
+REPLY QR SERVFAIL
+ENTRY_END
+
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www.example.com. IN NS
+SECTION ANSWER
+www.example.com. IN NS blackhole.
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+ENTRY_END
+
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN NS
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.example.com. IN NS
+SECTION ANSWER
+www.example.com. IN NS blackhole.
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/iter_minmaxttl.rpl b/tests/integration/deckard/sets/resolver/iter_minmaxttl.rpl
new file mode 100644
index 0000000..bebf616
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/iter_minmaxttl.rpl
@@ -0,0 +1,194 @@
+do-ip6: no
+
+; config options
+ features: min_ttl = 300
+ features: max_ttl = 600
+ ; the test is purely about cache so we do not need qmin complexity
+ query-minimization: off
+ stub-addr: 1.2.3.4
+CONFIG_END
+
+SCENARIO_BEGIN Test configurable minimum and maximum TTL
+
+; minimum TTL
+; time 0
+RANGE_BEGIN 1 2
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RD NOERROR
+SECTION QUESTION
+example.com. IN A
+SECTION ANSWER
+example.com. 0 IN A 5.6.7.8 ; TTL smaller than min_ttl
+ENTRY_END
+RANGE_END
+
+RANGE_BEGIN 4 8
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RD NOERROR
+SECTION QUESTION
+example.com. IN A
+SECTION ANSWER
+example.com. 0 IN A 9.10.11.12
+ENTRY_END
+RANGE_END
+
+
+
+
+; maximum TTL
+; time 0
+RANGE_BEGIN 9 10
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RD NOERROR
+SECTION QUESTION
+example.cz. IN A
+SECTION ANSWER
+example.cz. 3600 IN A 13.14.15.16 ; TTL bigger than max_ttl
+ENTRY_END
+RANGE_END
+
+RANGE_BEGIN 12 16
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RD NOERROR
+SECTION QUESTION
+example.cz. IN A
+SECTION ANSWER
+example.cz. 3600 IN A 17.18.19.20
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+example.com. IN A
+ENTRY_END
+
+STEP 2 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+example.com. IN A
+SECTION ANSWER
+example.com. IN A 5.6.7.8
+ENTRY_END
+
+
+STEP 3 TIME_PASSES ELAPSE 200
+; time 200
+
+STEP 4 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+example.com. IN A
+ENTRY_END
+
+; time 200 < min_ttl 300: returns cached answer
+STEP 5 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+example.com. IN A
+SECTION ANSWER
+example.com. IN A 5.6.7.8
+ENTRY_END
+
+STEP 6 TIME_PASSES ELAPSE 200
+; time 400
+
+STEP 7 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+example.com. IN A
+ENTRY_END
+
+; time 400 > min_ttl 300: returns new answer
+STEP 8 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+example.com. IN A
+SECTION ANSWER
+example.com. IN A 9.10.11.12
+ENTRY_END
+
+
+STEP 9 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+example.cz. IN A
+ENTRY_END
+
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+example.cz. IN A
+SECTION ANSWER
+example.cz. IN A 13.14.15.16
+ENTRY_END
+
+
+STEP 11 TIME_PASSES ELAPSE 500
+; time 500
+
+STEP 12 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+example.cz. IN A
+ENTRY_END
+
+; time 500 < max_ttl 600: returns cached answer
+STEP 13 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+example.cz. IN A
+SECTION ANSWER
+example.cz. IN A 13.14.15.16
+ENTRY_END
+
+STEP 14 TIME_PASSES ELAPSE 500
+; time 1000
+
+STEP 15 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+example.cz. IN A
+ENTRY_END
+
+; time 1000 > max_ttl 600: returns new answer
+STEP 16 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+example.cz. IN A
+SECTION ANSWER
+example.cz. IN A 17.18.19.20
+ENTRY_END
+
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/iter_mod.rpl b/tests/integration/deckard/sets/resolver/iter_mod.rpl
new file mode 100644
index 0000000..a78ace7
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/iter_mod.rpl
@@ -0,0 +1,219 @@
+do-ip6: no
+
+; config options
+; target-fetch-policy: "0 0 0 0 0"
+; module-config: "iterator"
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test basic iterative resolve without validator module
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+; net.
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+net. IN NS
+SECTION AUTHORITY
+. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+; root-servers.net.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+root-servers.net. IN NS
+SECTION ANSWER
+root-servers.net. IN NS k.root-servers.net.
+SECTION ADDITIONAL
+k.root-servers.net. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+root-servers.net. IN A
+SECTION AUTHORITY
+root-servers.net. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+k.root-servers.net. IN A
+SECTION ANSWER
+k.root-servers.net. IN A 193.0.14.129
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+k.root-servers.net. IN AAAA
+SECTION AUTHORITY
+root-servers.net. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+; gtld-servers.net.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+gtld-servers.net. IN NS
+SECTION ANSWER
+gtld-servers.net. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+gtld-servers.net. IN A
+SECTION AUTHORITY
+gtld-servers.net. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+a.gtld-servers.net. IN A
+SECTION ANSWER
+a.gtld-servers.net. IN A 192.5.6.30
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+a.gtld-servers.net. IN AAAA
+SECTION AUTHORITY
+gtld-servers.net. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+;SECTION AUTHORITY
+;example.com. IN NS ns.example.com.
+;SECTION ADDITIONAL
+;ns.example.com. IN A 1.2.3.4
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/iter_multiple_A.rpl b/tests/integration/deckard/sets/resolver/iter_multiple_A.rpl
new file mode 100644
index 0000000..d9c90a5
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/iter_multiple_A.rpl
@@ -0,0 +1,172 @@
+do-ip6: no
+
+; config options
+; The island of trust is at example.com
+;server:
+ trust-anchor: "example.com. IN DS 438 10 2 33F8133EB48EDB093839E985600EB7B7009EB5AC312D11CCA9007F6B 71D94D7B"
+ val-override-date: "20160308103040"
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Multiple A records test.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. 3600 IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 10 2 3600 20251231235959 20160308093040 2843 example.com. boNVuXxyhW+Gmiu+4ip1QQvIGqFNVsFfg1v+ywgc4+37ieQ5t+qJsHVm fJITRZrJxYQ6T/MkZKhpxLCemgFeKU6syWwoCfypnGino2G1urvqThna WTImSPhY/QsOj1ALy51d9Q+Mb5vt69XJt6SQvtNf6imepIFOT6CPSfjx BJ4=
+SECTION ADDITIONAL
+ns.example.com. 3600 IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 10 3 3600 20251231235959 20160308093040 2843 example.com. VSq+DkxJYr9Z+uh3KgpyPNwtuim4WVXnTdhRW7HX90CP5tyOVjDDTehA UmCxB8iFjUFE3hlwDx0Y71g+8Oso1t0JGkvDtWf5RDx1w+4K/1pQ2JMG lZTh7juaGJzXtltxqBoY67z1FBp9MI59O0hkABtz1CElj9LrhDr9wQa4 OUo=
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+example.com. IN DNSKEY
+SECTION ANSWER
+example.com. 3600 IN DNSKEY 256 3 10 AwEAAcOHC7D2ZcG5M6MK5If/60+vvBM67BC8qUx04f6Kcvhx9GBMIMYz 87m6m2P5WKafW5AN1K9jY37m2fU/TdACQNzqu4wyVsOQefke/v2fgswg NgneP/C7cpyBVuK+8BUHjrorfLORClD3mbQMQldaaO2h6+OArAGHlFNI oFsuCjyR
+example.com. 3600 IN DNSKEY 257 3 10 AwEAAc4VCSEu1C1lAxuZMC8tSyissZNXC2lgS3zNvAvFdLtAsSbhB1cj dLCtTWUv1Ki/T+iWn10iemLQJ0S6z8wK+a7maC3ELZP1qoSFln+FiAsZ xYK72/XDEYMMp01F0gxgzZ2alWx3WKm2mELXf/ezEx+7X2ZNbwum5TKt FxtvotmT
+example.com. 3600 IN RRSIG DNSKEY 10 2 3600 20251231235959 20160308093040 438 example.com. cas8JKwtLUIItwOgrDrDG9pSkqiYw3r+8vyvt962kjHFBNG0D7AeegaO GMSWRziqA4L8xdgP750rLR5CRFQ9oPQlr/RWnsebGdJ3Yohwwa04HE6n OvR+o0u0oqNQ+P5KinxVKSv0Ru+BVMPHRDfIXN/FD5p9+nvIrnjXQlI3 vvM=
+example.com. 3600 IN RRSIG DNSKEY 10 2 3600 20251231235959 20160308093040 2843 example.com. uDLTMMTvJCcetKr6THEJ8Rn0gMLPFZTbOGJBZyZ2E5F9KkPSS01Nm6/P e+j0R3ObYXodqnZIY19fzXJKS2dJktoXkqNLBW/SpWTlFzpfHKCvTbJS VLrJ/lrEunE5cgSAqBrbAAuJrFpX/gaavqokElnUv1Mki2agTH1dTZyn X8M=
+SECTION AUTHORITY
+example.com. 3600 IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 10 2 3600 20251231235959 20160308093040 2843 example.com. boNVuXxyhW+Gmiu+4ip1QQvIGqFNVsFfg1v+ywgc4+37ieQ5t+qJsHVm fJITRZrJxYQ6T/MkZKhpxLCemgFeKU6syWwoCfypnGino2G1urvqThna WTImSPhY/QsOj1ALy51d9Q+Mb5vt69XJt6SQvtNf6imepIFOT6CPSfjx BJ4=
+SECTION ADDITIONAL
+ns.example.com. 3600 IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 10 3 3600 20251231235959 20160308093040 2843 example.com. VSq+DkxJYr9Z+uh3KgpyPNwtuim4WVXnTdhRW7HX90CP5tyOVjDDTehA UmCxB8iFjUFE3hlwDx0Y71g+8Oso1t0JGkvDtWf5RDx1w+4K/1pQ2JMG lZTh7juaGJzXtltxqBoY67z1FBp9MI59O0hkABtz1CElj9LrhDr9wQa4 OUo=
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+a.example.com. IN A
+SECTION ANSWER
+a.example.com. 3600 IN CNAME b.example.com.
+a.example.com. 3600 IN RRSIG CNAME 10 3 3600 20251231235959 20160308093040 2843 example.com. uiI9SNK74X//ACbllDC5LD49gjTmyL08CrtK1++I3rNPFFRChyJYAkUM wXBOXVW+fqBWOrXr835KCvUK/JJiSy/vvqE2+xI370OL8d9MvjR9vjIw Y2VusLWr3KmI4ixR7bAdG+FnMedapykOi8CJnbpkltU60QprQetcKGSv /Gk=
+b.example.com. 3600 IN A 1.2.3.5
+b.example.com. 3600 IN A 1.2.3.6
+b.example.com. 3600 IN A 1.2.3.7
+b.example.com. 3600 IN RRSIG A 10 3 3600 20251231235959 20160308093040 2843 example.com. s5QtOdtBldJK1tdYNeWfQjoqVALI8eqcCRGOD1VocXRfDs3pgzowqtu5 rU/5vUxcN535/Z8nRPXEF7Ub5pgzEWupETiUvpEQP/Y+mNTaXrsgHTlc YCsCqbaPDNJ6wxfaicTiSYL9i2DDpMyNot+HUfhrYdyfaVcNsfy2/z2R TZ0=
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+RANGE_END
+
+STEP 10 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+a.example.com. IN A
+ENTRY_END
+
+STEP 20 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+a.example.com. IN A
+SECTION ANSWER
+a.example.com. 3600 IN CNAME b.example.com.
+a.example.com. 3600 IN RRSIG CNAME 10 3 3600 20251231235959 20160308093040 2843 example.com. uiI9SNK74X//ACbllDC5LD49gjTmyL08CrtK1++I3rNPFFRChyJYAkUM wXBOXVW+fqBWOrXr835KCvUK/JJiSy/vvqE2+xI370OL8d9MvjR9vjIw Y2VusLWr3KmI4ixR7bAdG+FnMedapykOi8CJnbpkltU60QprQetcKGSv /Gk=
+b.example.com. 3600 IN A 1.2.3.5
+b.example.com. 3600 IN A 1.2.3.6
+b.example.com. 3600 IN A 1.2.3.7
+b.example.com. 3600 IN RRSIG A 10 3 3600 20251231235959 20160308093040 2843 example.com. s5QtOdtBldJK1tdYNeWfQjoqVALI8eqcCRGOD1VocXRfDs3pgzowqtu5 rU/5vUxcN535/Z8nRPXEF7Ub5pgzEWupETiUvpEQP/Y+mNTaXrsgHTlc YCsCqbaPDNJ6wxfaicTiSYL9i2DDpMyNot+HUfhrYdyfaVcNsfy2/z2R TZ0=
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+; Cache hit
+STEP 30 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+a.example.com. IN A
+ENTRY_END
+
+STEP 40 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+a.example.com. IN A
+SECTION ANSWER
+a.example.com. 3600 IN CNAME b.example.com.
+a.example.com. 3600 IN RRSIG CNAME 10 3 3600 20251231235959 20160308093040 2843 example.com. uiI9SNK74X//ACbllDC5LD49gjTmyL08CrtK1++I3rNPFFRChyJYAkUM wXBOXVW+fqBWOrXr835KCvUK/JJiSy/vvqE2+xI370OL8d9MvjR9vjIw Y2VusLWr3KmI4ixR7bAdG+FnMedapykOi8CJnbpkltU60QprQetcKGSv /Gk=
+b.example.com. 3600 IN A 1.2.3.5
+b.example.com. 3600 IN A 1.2.3.6
+b.example.com. 3600 IN A 1.2.3.7
+b.example.com. 3600 IN RRSIG A 10 3 3600 20251231235959 20160308093040 2843 example.com. s5QtOdtBldJK1tdYNeWfQjoqVALI8eqcCRGOD1VocXRfDs3pgzowqtu5 rU/5vUxcN535/Z8nRPXEF7Ub5pgzEWupETiUvpEQP/Y+mNTaXrsgHTlc YCsCqbaPDNJ6wxfaicTiSYL9i2DDpMyNot+HUfhrYdyfaVcNsfy2/z2R TZ0=
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/iter_ns_badaa.rpl b/tests/integration/deckard/sets/resolver/iter_ns_badaa.rpl
new file mode 100644
index 0000000..fc584f1
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/iter_ns_badaa.rpl
@@ -0,0 +1,176 @@
+do-ip6: no
+
+; config options
+; target-fetch-policy: "3 2 1 0 0"
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test iterator with NS falsely declaring referral answer as authoritative.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+; net.
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+net. IN NS
+SECTION AUTHORITY
+. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+; root-servers.net.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+root-servers.net. IN NS
+SECTION ANSWER
+root-servers.net. IN NS k.root-servers.net.
+SECTION ADDITIONAL
+k.root-servers.net. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+root-servers.net. IN A
+SECTION AUTHORITY
+root-servers.net. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+k.root-servers.net. IN A
+SECTION ANSWER
+k.root-servers.net. IN A 193.0.14.129
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+k.root-servers.net. IN AAAA
+SECTION AUTHORITY
+root-servers.net. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+; gtld-servers.net.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+gtld-servers.net. IN NS
+SECTION ANSWER
+gtld-servers.net. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+gtld-servers.net. IN A
+SECTION AUTHORITY
+gtld-servers.net. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+a.gtld-servers.net. IN A
+SECTION ANSWER
+a.gtld-servers.net. IN A 192.5.6.30
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+a.gtld-servers.net. IN AAAA
+SECTION AUTHORITY
+gtld-servers.net. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+; False declaration here
+REPLY QR AA NOERROR
+SECTION QUESTION
+MORECOWBELL. IN A
+SECTION AUTHORITY
+MORECOWBELL. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id copy_query
+REPLY QR AA NOERROR
+SECTION QUESTION
+CATALYST.MORECOWBELL. IN A
+SECTION ANSWER
+CATALYST.MORECOWBELL. IN A 10.20.30.40
+SECTION AUTHORITY
+CATALYST.MORECOWBELL. IN NS a.gtld-servers.net.
+ENTRY_END
+
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+catalyst.morecowbell. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+catalyst.morecowbell. IN A
+SECTION ANSWER
+catalyst.morecowbell. IN A 10.20.30.40
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/iter_ns_badglue.rpl b/tests/integration/deckard/sets/resolver/iter_ns_badglue.rpl
new file mode 100644
index 0000000..0ceec9f
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/iter_ns_badglue.rpl
@@ -0,0 +1,240 @@
+do-ip6: no
+
+; config options
+; target-fetch-policy: "3 2 1 0 0"
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test iterator with delagation with bad glue.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+; net.
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+net. IN NS
+SECTION AUTHORITY
+. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+; root-servers.net.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+root-servers.net. IN NS
+SECTION ANSWER
+root-servers.net. IN NS k.root-servers.net.
+SECTION ADDITIONAL
+k.root-servers.net. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+root-servers.net. IN A
+SECTION AUTHORITY
+root-servers.net. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+k.root-servers.net. IN A
+SECTION ANSWER
+k.root-servers.net. IN A 193.0.14.129
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+k.root-servers.net. IN AAAA
+SECTION AUTHORITY
+root-servers.net. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+; gtld-servers.net.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+gtld-servers.net. IN NS
+SECTION ANSWER
+gtld-servers.net. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+gtld-servers.net. IN A
+SECTION AUTHORITY
+gtld-servers.net. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+a.gtld-servers.net. IN A
+SECTION ANSWER
+a.gtld-servers.net. IN A 192.5.6.30
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+a.gtld-servers.net. IN AAAA
+SECTION AUTHORITY
+gtld-servers.net. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+x.gtld-servers.net. IN A
+SECTION ANSWER
+x.gtld-servers.net. IN A 192.5.6.31
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+x.gtld-servers.net. IN AAAA
+SECTION AUTHORITY
+gtld-servers.net. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN A
+SECTION AUTHORITY
+; This is the offending NS (it must be ignored)
+com. IN NS x.gtld-servers.net.
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+x.gtld-servers.net. IN A 192.5.6.31
+ENTRY_END
+
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id copy_query
+REPLY AA QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. 3600 IN NS a.gtld-servers.net.
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id copy_query
+REPLY AA QR NOERROR
+SECTION QUESTION
+foo.com. IN NS
+SECTION ANSWER
+foo.com. 3600 IN NS a.gtld-servers.net.
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id copy_query
+REPLY AA QR NOERROR
+SECTION QUESTION
+www.foo.com. IN A
+SECTION ANSWER
+www.foo.com. 10 IN A 10.20.30.40
+SECTION AUTHORITY
+www.foo.com. 3600 IN NS a.gtld-servers.net.
+ENTRY_END
+
+RANGE_END
+
+; x.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.31
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION AUTHORITY
+com. IN NS x.gtld-servers.net.
+SECTION ADDITIONAL
+; Keep suggesting address records for this server
+x.gtld-servers.net. IN A 192.5.6.31
+ENTRY_END
+
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.foo.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.foo.com. IN A
+SECTION ANSWER
+www.foo.com. 10 IN A 10.20.30.40
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/iter_ns_badip.rpl b/tests/integration/deckard/sets/resolver/iter_ns_badip.rpl
new file mode 100644
index 0000000..a432f8f
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/iter_ns_badip.rpl
@@ -0,0 +1,270 @@
+; config options
+; target-fetch-policy: "3 2 1 0 0"
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test iterator with delagation with bad IP address
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+K.ROOT-SERVERS.NET. IN AAAA
+SECTION ANSWER
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR AA NOERROR
+SECTION QUESTION
+net. IN A
+SECTION ANSWER
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+gtld-servers.net. IN A
+SECTION ANSWER
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id copy_query
+REPLY QR AA NOERROR
+SECTION QUESTION
+a.gtld-servers.net. IN A
+SECTION ANSWER
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id copy_query
+REPLY QR AA NOERROR
+SECTION QUESTION
+a.gtld-servers.net. IN AAAA
+SECTION ANSWER
+; Intentional bad address
+a.gtld-servers.net. IN AAAA 1:2:3::4
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net. - intentionally broken over IPv6
+RANGE_BEGIN 0 100
+ ADDRESS 1:2:3::4
+
+ENTRY_BEGIN
+MATCH opcode
+ADJUST copy_id copy_query
+REPLY QR AA SERVFAIL
+SECTION QUESTION
+. IN A
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net. - works over IPv4
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. IN NS ns2.example.com.
+SECTION ADDITIONAL
+ns.example.com. 10 IN A 1.2.3.4
+ns2.example.com. 3600 IN A 1.2.3.5
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+foo.com. IN A
+SECTION AUTHORITY
+foo.com. IN NS ns.example.com.
+foo.com. IN NS ns2.example.com.
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. 10 IN A 10.20.30.40
+SECTION AUTHORITY
+example.com. 3600 IN NS ns.example.com.
+example.com. 3600 IN NS ns2.example.com.
+SECTION ADDITIONAL
+ns.example.com. 10 IN A 1.2.3.4
+ns2.example.com. 3600 IN A 1.2.3.5
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.com. IN A
+SECTION ANSWER
+ns.example.com. 10 IN A 1.2.3.4
+SECTION AUTHORITY
+example.com. 3600 IN NS ns.example.com.
+example.com. 3600 IN NS ns2.example.com.
+SECTION ADDITIONAL
+ns2.example.com. 3600 IN A 1.2.3.5
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns2.example.com. IN A
+SECTION ANSWER
+ns2.example.com. 3600 IN A 1.2.3.5
+SECTION AUTHORITY
+example.com. 3600 IN NS ns.example.com.
+example.com. 3600 IN NS ns2.example.com.
+SECTION ADDITIONAL
+ns.example.com. 10 IN A 1.2.3.4
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.com. IN AAAA
+SECTION ANSWER
+SECTION AUTHORITY
+example.com. 3600 IN SOA bla. bla. 1 2 3 4 5
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns2.example.com. IN AAAA
+SECTION ANSWER
+SECTION AUTHORITY
+example.com. 3600 IN SOA bla. bla. 1 2 3 4 5
+ENTRY_END
+
+; foo.com contents.
+ENTRY_BEGIN
+ADJUST copy_id
+MATCH opcode qtype qname
+REPLY QR NOERROR
+SECTION QUESTION
+www.foo.com. IN A
+SECTION ANSWER
+www.foo.com. 10 IN A 10.20.30.40
+SECTION AUTHORITY
+foo.com. 3600 IN NS ns.example.com.
+foo.com. 3600 IN NS ns2.example.com.
+ENTRY_END
+
+RANGE_END
+
+; ns2.example.com. (lame)
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.5
+ENTRY_BEGIN
+MATCH opcode
+ADJUST copy_id copy_query
+REPLY QR SERVFAIL
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.foo.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH flags rcode question answer
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.foo.com. IN A
+SECTION ANSWER
+www.foo.com. 10 IN A 10.20.30.40
+;SECTION AUTHORITY
+;foo.com. 3600 IN NS ns.example.com.
+;foo.com. 3600 IN NS ns2.example.com.
+ENTRY_END
+
+; Now move the time so good server times out and bad remains.
+STEP 20 TIME_PASSES ELAPSE 20
+
+; Try query again.
+STEP 30 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.foo.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 40 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH flags rcode question answer
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.foo.com. IN A
+SECTION ANSWER
+www.foo.com. 10 IN A 10.20.30.40
+;SECTION AUTHORITY
+;foo.com. 3600 IN NS ns.example.com.
+;foo.com. 3600 IN NS ns2.example.com.
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/iter_ns_noglue.rpl b/tests/integration/deckard/sets/resolver/iter_ns_noglue.rpl
new file mode 100644
index 0000000..7d8dbfc
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/iter_ns_noglue.rpl
@@ -0,0 +1,222 @@
+do-ip6: no
+
+; config options
+; target-fetch-policy: "3 2 1 0 0"
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test iterator with delagation with missing mandatory glue.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN A
+SECTION AUTHORITY
+; This is the offending NS (it must be ignored)
+com. IN NS a.gtld-servers.com.
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+ENTRY_END
+
+; net.
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+net. IN NS
+SECTION AUTHORITY
+. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+; root-servers.net.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+root-servers.net. IN NS
+SECTION ANSWER
+root-servers.net. IN NS k.root-servers.net.
+SECTION ADDITIONAL
+k.root-servers.net. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+root-servers.net. IN A
+SECTION AUTHORITY
+root-servers.net. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+k.root-servers.net. IN A
+SECTION ANSWER
+k.root-servers.net. IN A 193.0.14.129
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+k.root-servers.net. IN AAAA
+SECTION AUTHORITY
+root-servers.net. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+; gtld-servers.net.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+gtld-servers.net. IN NS
+SECTION ANSWER
+gtld-servers.net. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+gtld-servers.net. IN A
+SECTION AUTHORITY
+gtld-servers.net. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+a.gtld-servers.net. IN A
+SECTION ANSWER
+a.gtld-servers.net. IN A 192.5.6.30
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+a.gtld-servers.net. IN AAAA
+SECTION AUTHORITY
+gtld-servers.net. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+; False declaration here
+REPLY QR AA NOERROR
+SECTION QUESTION
+MORECOWBELL. IN A
+SECTION AUTHORITY
+MORECOWBELL. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+
+ENTRY_BEGIN
+MATCH opcode qname qtype
+ADJUST copy_id
+REPLY AA QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION AUTHORITY
+; This is the offending NS (it must be ignored)
+com. IN NS a.gtld-servers.com.
+com. IN NS a.gtld-servers.net.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY AA QR NOERROR
+SECTION QUESTION
+gtld-servers.com. IN NS
+SECTION AUTHORITY
+com. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY AA QR NOERROR
+SECTION QUESTION
+foo.com. IN NS
+SECTION AUTHORITY
+foo.com. 3600 IN NS a.gtld-servers.net.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id copy_query
+REPLY AA QR NOERROR
+SECTION QUESTION
+foo.com. IN A
+SECTION ANSWER
+foo.com. 10 IN A 10.20.30.40
+SECTION AUTHORITY
+foo.com. 3600 IN NS a.gtld-servers.net.
+ENTRY_END
+
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+foo.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+foo.com. IN A
+SECTION ANSWER
+foo.com. 10 IN A 10.20.30.40
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/iter_ns_spoof.rpl b/tests/integration/deckard/sets/resolver/iter_ns_spoof.rpl
new file mode 100644
index 0000000..fea164e
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/iter_ns_spoof.rpl
@@ -0,0 +1,276 @@
+do-ip6: no
+
+; config options
+; harden-referral-path: yes
+; target-fetch-policy: "0 0 0 0 0"
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test NS record spoof protection.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+; for simplicity the root server is authoritative for root-servers.net
+; and also for gtld-servers.net
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+K.ROOT-SERVERS.NET. IN A
+SECTION ANSWER
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+a.gtld-servers.net. IN A
+SECTION ANSWER
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+mail.example.com. IN A
+SECTION ANSWER
+mail.example.com. IN A 10.20.30.50
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns.example.com. IN A
+SECTION ANSWER
+ns.example.com. IN A 1.2.3.4
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+ENTRY_END
+
+;; answer to the spoofed query ; spoofed reply answer.
+; here we put it in the nameserver for ease.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+bad123.example.com. IN A
+SECTION ANSWER
+bad123.example.com. IN A 6.6.6.6
+SECTION AUTHORITY
+; evil NS set.
+example.com. IN NS bad123.example.com.
+ENTRY_END
+
+RANGE_END
+
+; evil server
+RANGE_BEGIN 0 100
+ ADDRESS 6.6.6.6
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 6.6.6.6
+SECTION AUTHORITY
+example.com. IN NS bad123.example.com.
+SECTION ADDITIONAL
+bad123.example.com. IN A 6.6.6.6
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+mail.example.com. IN A
+SECTION ANSWER
+mail.example.com. IN A 6.6.6.6
+SECTION AUTHORITY
+example.com. IN NS bad123.example.com.
+SECTION ADDITIONAL
+bad123.example.com. IN A 6.6.6.6
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+bad123.example.com. IN A
+SECTION ANSWER
+bad123.example.com. IN A 6.6.6.6
+SECTION AUTHORITY
+; evil NS set.
+example.com. IN NS bad123.example.com.
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+;SECTION AUTHORITY
+;example.com. IN NS ns.example.com.
+;SECTION ADDITIONAL
+;ns.example.com. IN A 1.2.3.4
+ENTRY_END
+
+; spoofed query
+STEP 20 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+bad123.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+; resolver gets address to spoofed server here
+STEP 30 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+bad123.example.com. IN A
+SECTION ANSWER
+bad123.example.com. IN A 6.6.6.6
+;SECTION AUTHORITY
+;example.com. IN NS ns.example.com.
+;SECTION ADDITIONAL
+;ns.example.com. IN A 1.2.3.4
+ENTRY_END
+
+; a new query
+STEP 40 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+mail.example.com. IN A
+ENTRY_END
+
+STEP 50 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+mail.example.com. IN A
+SECTION ANSWER
+mail.example.com. IN A 10.20.30.50
+;SECTION AUTHORITY
+;example.com. IN NS ns.example.com.
+;SECTION ADDITIONAL
+;ns.example.com. IN A 1.2.3.4
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/iter_pc_a.rpl b/tests/integration/deckard/sets/resolver/iter_pc_a.rpl
new file mode 100644
index 0000000..79dc86d
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/iter_pc_a.rpl
@@ -0,0 +1,232 @@
+do-ip6: no
+
+; config options
+; target-fetch-policy: "0 0 0 0 0"
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test resolution with parent child differ for type A.
+; the parent has the correct A record.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.44
+ENTRY_END
+RANGE_END
+
+; the working version.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.44
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY AA QR NOERROR
+SECTION QUESTION
+ns.example.com. IN A
+SECTION ANSWER
+ns.example.com. IN A 1.2.3.55
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY AA QR NOERROR
+SECTION QUESTION
+ns.example.com. IN AAAA
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.55
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY AA QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.55
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY AA QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.55
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY AA QR NOERROR
+SECTION QUESTION
+mail.example.com. IN A
+SECTION ANSWER
+mail.example.com. IN A 10.20.30.20
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.55
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY AA QR NOERROR
+SECTION QUESTION
+ftp.example.com. IN A
+SECTION ANSWER
+ftp.example.com. IN A 10.20.30.10
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.55
+ENTRY_END
+RANGE_END
+
+; Broken. Does not respond to anything (servfail instead
+; of timeouts since this is easier to encode in .rpl file format).
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.55
+ENTRY_BEGIN
+MATCH opcode
+ADJUST copy_id copy_query
+REPLY QR SERVFAIL
+SECTION QUESTION
+example.net. IN NS
+SECTION ANSWER
+ENTRY_END
+
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 20 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+;SECTION AUTHORITY
+;example.com. IN NS ns.example.com.
+;SECTION ADDITIONAL
+;ns.example.com. IN A 1.2.3.55
+ENTRY_END
+
+; now that the bad child NS record is in cache, ask something else.
+STEP 30 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+mail.example.com. IN A
+ENTRY_END
+
+STEP 40 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+mail.example.com. IN A
+SECTION ANSWER
+mail.example.com. IN A 10.20.30.20
+;SECTION AUTHORITY
+;example.com. IN NS ns.example.com.
+;SECTION ADDITIONAL
+;ns.example.com. IN A 1.2.3.55
+ENTRY_END
+
+; test cache of parent data
+STEP 50 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+ftp.example.com. IN A
+ENTRY_END
+
+STEP 60 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+ftp.example.com. IN A
+SECTION ANSWER
+ftp.example.com. IN A 10.20.30.10
+;SECTION AUTHORITY
+;example.com. IN NS ns.example.com.
+;SECTION ADDITIONAL
+;ns.example.com. IN A 1.2.3.55
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/iter_pc_aaaa.rpl b/tests/integration/deckard/sets/resolver/iter_pc_aaaa.rpl
new file mode 100644
index 0000000..58502a4
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/iter_pc_aaaa.rpl
@@ -0,0 +1,284 @@
+; config options
+; target-fetch-policy: "0 0 0 0 0"
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test resolution with parent child differ for type AAAA.
+; the parent has the correct A record.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+K.ROOT-SERVERS.NET. IN AAAA
+SECTION ANSWER
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+net. IN NS
+SECTION AUTHORITY
+net. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+ROOT-SERVERS.NET IN NS
+SECTION ANSWER
+ROOT-SERVERS.NET. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+a.gtld-servers.net. IN AAAA
+SECTION ANSWER
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+gtld-servers.net. IN NS
+SECTION AUTHORITY
+gtld-servers.net. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN AAAA 2002:b44d::44
+ENTRY_END
+RANGE_END
+
+; the working version.
+RANGE_BEGIN 0 100
+ ADDRESS 2002:b44d::44
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY AA QR NOERROR
+SECTION QUESTION
+ns.example.com. IN AAAA
+SECTION ANSWER
+ns.example.com. IN AAAA 2002:b44d::55
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY AA QR NOERROR
+SECTION QUESTION
+ns.example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN AAAA 2002:b44d::55
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY AA QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN AAAA 2002:b44d::55
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY AA QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN AAAA 2002:b44d::55
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY AA QR NOERROR
+SECTION QUESTION
+mail.example.com. IN A
+SECTION ANSWER
+mail.example.com. IN A 10.20.30.20
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN AAAA 2002:b44d::55
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY AA QR NOERROR
+SECTION QUESTION
+ftp.example.com. IN A
+SECTION ANSWER
+ftp.example.com. IN A 10.20.30.10
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN AAAA 2002:b44d::55
+ENTRY_END
+RANGE_END
+
+; Broken. Does not respond to anything (servfail instead
+; of timeouts since this is easier to encode in .rpl file format).
+RANGE_BEGIN 0 100
+ ADDRESS 2002:b44d::55
+ENTRY_BEGIN
+MATCH opcode
+ADJUST copy_id copy_query
+REPLY QR SERVFAIL
+SECTION QUESTION
+example.net. IN NS
+SECTION ANSWER
+ENTRY_END
+
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 20 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+;SECTION AUTHORITY
+;example.com. IN NS ns.example.com.
+;SECTION ADDITIONAL
+;ns.example.com. IN AAAA 2002:b44d::55
+ENTRY_END
+
+; now that the bad child NS record is in cache, ask something else.
+STEP 30 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+mail.example.com. IN A
+ENTRY_END
+
+STEP 40 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+mail.example.com. IN A
+SECTION ANSWER
+mail.example.com. IN A 10.20.30.20
+;SECTION AUTHORITY
+;example.com. IN NS ns.example.com.
+;SECTION ADDITIONAL
+;ns.example.com. IN AAAA 2002:b44d::55
+ENTRY_END
+
+; test cache of parent data
+STEP 50 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+ftp.example.com. IN A
+ENTRY_END
+
+STEP 60 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+ftp.example.com. IN A
+SECTION ANSWER
+ftp.example.com. IN A 10.20.30.10
+;SECTION AUTHORITY
+;example.com. IN NS ns.example.com.
+;SECTION ADDITIONAL
+;ns.example.com. IN AAAA 2002:b44d::55
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/iter_pcdiff.rpl b/tests/integration/deckard/sets/resolver/iter_pcdiff.rpl
new file mode 100644
index 0000000..5841801
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/iter_pcdiff.rpl
@@ -0,0 +1,210 @@
+do-ip6: no
+
+; config options
+;server:
+; target-fetch-policy: "0 0 0 0 0"
+
+;stub-zone:
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test resolution with recursion and parent child differ.
+; and the child gives bad information.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+net. IN NS
+SECTION AUTHORITY
+net. IN NS e.gtld-servers.net.
+SECTION ADDITIONAL
+e.gtld-servers.net. IN A 192.12.94.30
+ENTRY_END
+
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION AUTHORITY
+example.com. IN NS ns.example.net.
+ENTRY_END
+RANGE_END
+
+; e.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.12.94.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+net. IN NS
+SECTION ANSWER
+net. IN NS e.gtld-servers.net.
+SECTION ADDITIONAL
+e.gtld-servers.net. IN A 192.12.94.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.net. IN NS
+SECTION AUTHORITY
+example.net. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.net. IN A 1.2.3.44
+ENTRY_END
+
+RANGE_END
+
+; ns.example.net.
+; The parent-IP version
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.44
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY AA QR NOERROR
+SECTION QUESTION
+example.net. IN NS
+SECTION ANSWER
+example.net. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.net. IN A 1.2.3.55
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY AA QR NOERROR
+SECTION QUESTION
+ns.example.net. IN A
+SECTION ANSWER
+ns.example.net. IN A 1.2.3.55
+SECTION AUTHORITY
+example.net. IN NS ns.example.net.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY AA QR NOERROR
+SECTION QUESTION
+ns.example.net. IN AAAA
+SECTION AUTHORITY
+example.net. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.net. IN A 1.2.3.55
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY AA QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.net.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY AA QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+SECTION AUTHORITY
+example.com. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.net IN A 1.2.3.55
+ENTRY_END
+RANGE_END
+
+; ns.example.net
+; The child IP version. Does not respond to anything (servfail instead
+; of timeouts since this is easier to encode in .rpl file format).
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.55
+ENTRY_BEGIN
+MATCH opcode
+ADJUST copy_id copy_query
+REPLY QR SERVFAIL
+SECTION QUESTION
+example.net. IN NS
+SECTION ANSWER
+ENTRY_END
+
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 20 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH opcode qname flags rcode question answer
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/iter_pcdirect.rpl b/tests/integration/deckard/sets/resolver/iter_pcdirect.rpl
new file mode 100644
index 0000000..3483960
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/iter_pcdirect.rpl
@@ -0,0 +1,313 @@
+do-ip6: no
+
+; config options
+; target-fetch-policy: "0 0 0 0 0"
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test resolver with parent-child diff for direct impact
+; the trouble is resolving this right away.
+; otherwise it gets picked out of the cache.
+; i.e. on a failed lookup, pickup lame stuff from the cache.
+; the nameserver lookup may have failed but produced some (lame) addresses.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+; net.
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+net. IN NS
+SECTION AUTHORITY
+. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+; root-servers.net.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+root-servers.net. IN NS
+SECTION ANSWER
+root-servers.net. IN NS k.root-servers.net.
+SECTION ADDITIONAL
+k.root-servers.net. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+root-servers.net. IN A
+SECTION AUTHORITY
+root-servers.net. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+k.root-servers.net. IN A
+SECTION ANSWER
+k.root-servers.net. IN A 193.0.14.129
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+k.root-servers.net. IN AAAA
+SECTION AUTHORITY
+root-servers.net. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+; gtld-servers.net.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+gtld-servers.net. IN NS
+SECTION ANSWER
+gtld-servers.net. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+gtld-servers.net. IN A
+SECTION AUTHORITY
+gtld-servers.net. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+a.gtld-servers.net. IN A
+SECTION ANSWER
+a.gtld-servers.net. IN A 192.5.6.30
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+a.gtld-servers.net. IN AAAA
+SECTION AUTHORITY
+gtld-servers.net. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.net. IN A
+SECTION AUTHORITY
+example.net. IN NS ns.example.net.
+SECTION ADDITIONAL
+; parent-side working address.
+ns.example.net. IN A 1.2.3.4
+ENTRY_END
+
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns.example.net.
+ENTRY_END
+RANGE_END
+
+; a0.org.afilias-nst.org.
+RANGE_BEGIN 0 100
+ ADDRESS 199.19.56.1
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+org. IN NS
+SECTION ANSWER
+org. IN NS a0.org.afilias-nst.org.
+SECTION ADDITIONAL
+a0.org.afilias-nst.org. IN A 199.19.56.1
+ENTRY_END
+
+
+RANGE_END
+
+; ns.example.net.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.net.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.net. IN NS
+SECTION ANSWER
+example.net. IN NS ns.example.net.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA RA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+SECTION AUTHORITY
+example.com. IN NS ns.example.net.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA RA NOERROR
+SECTION QUESTION
+mail.example.com. IN A
+SECTION ANSWER
+mail.example.com. IN A 10.20.30.50
+SECTION AUTHORITY
+example.com. IN NS ns.example.net.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR RA NOERROR
+SECTION QUESTION
+ns.example.net. IN A
+SECTION ANSWER
+; correct answer: ns.example.net. IN A 1.2.3.4
+SECTION AUTHORITY
+ns.example.net. IN NS 1.2.3.4.example.net.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR AA RA NXDOMAIN
+SECTION QUESTION
+4.example.net. IN A
+SECTION ANSWER
+SECTION AUTHORITY
+example.net. IN SOA ns.example.net. root.example.net. 2009111400 14400 3600 1209600 86400
+ENTRY_END
+
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+;SECTION AUTHORITY
+;example.com. IN NS ns.example.net.
+ENTRY_END
+
+; perhaps some messages are still pending - allow those to resolve.
+STEP 20 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+mail.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 30 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+mail.example.com. IN A
+SECTION ANSWER
+mail.example.com. IN A 10.20.30.50
+;SECTION AUTHORITY
+;example.com. IN NS ns.example.net.
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/iter_pcname.rpl b/tests/integration/deckard/sets/resolver/iter_pcname.rpl
new file mode 100644
index 0000000..b99e04f
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/iter_pcname.rpl
@@ -0,0 +1,278 @@
+do-ip6: no
+
+; config options
+; target-fetch-policy: "0 0 0 0 0"
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test resolution with parent child differ in names.
+; the parent has an extra name that is the only working one.
+; To understand the commented-out authority records see
+; https://mailarchive.ietf.org/arch/msg/dnsop/CYjPDlwtpxzdQV_qycB-WfnW6CI
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+net. IN NS
+SECTION AUTHORITY
+net. IN NS e.gtld-servers.net.
+SECTION ADDITIONAL
+e.gtld-servers.net. IN A 192.12.94.30
+ENTRY_END
+
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.55
+ENTRY_END
+RANGE_END
+
+; e.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.12.94.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+net. IN NS
+SECTION ANSWER
+net. IN NS e.gtld-servers.net.
+SECTION ADDITIONAL
+e.gtld-servers.net. IN A 192.12.94.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.net. IN NS
+SECTION AUTHORITY
+example.net. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.net. IN A 1.2.3.44
+ENTRY_END
+
+RANGE_END
+
+; ns.example.net.
+; the working version.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.44
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY AA QR NOERROR
+SECTION QUESTION
+example.net. IN NS
+SECTION ANSWER
+example.net. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.net. IN A 1.2.3.44
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY AA QR NOERROR
+SECTION QUESTION
+ns.example.net. IN A
+SECTION ANSWER
+ns.example.net. IN A 1.2.3.44
+SECTION AUTHORITY
+example.net. IN NS ns.example.net.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY AA QR NOERROR
+SECTION QUESTION
+ns.example.net. IN AAAA
+SECTION AUTHORITY
+example.net. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.net. IN A 1.2.3.44
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY AA QR NOERROR
+SECTION QUESTION
+ns.example.com. IN A
+SECTION ANSWER
+ns.example.com. IN A 1.2.3.55
+SECTION AUTHORITY
+;example.com. IN NS ns.example.com.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY AA QR NOERROR
+SECTION QUESTION
+ns.example.com. IN AAAA
+SECTION AUTHORITY
+;example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.55
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY AA QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.55
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY AA QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+SECTION AUTHORITY
+;example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.55
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY AA QR NOERROR
+SECTION QUESTION
+mail.example.com. IN A
+SECTION ANSWER
+mail.example.com. IN A 10.20.30.20
+SECTION AUTHORITY
+;example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.55
+ENTRY_END
+RANGE_END
+
+; ns.example.net
+; Broken. Does not respond to anything (servfail instead
+; of timeouts since this is easier to encode in .rpl file format).
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.55
+ENTRY_BEGIN
+MATCH opcode
+ADJUST copy_id copy_query
+REPLY QR SERVFAIL
+SECTION QUESTION
+example.net. IN NS
+SECTION ANSWER
+ENTRY_END
+
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 20 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+;SECTION AUTHORITY
+;example.com. IN NS ns.example.com.
+;SECTION ADDITIONAL
+;ns.example.com. IN A 1.2.3.55
+ENTRY_END
+
+; now that the bad child NS record is in cache, ask something else.
+STEP 30 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+mail.example.com. IN A
+ENTRY_END
+
+STEP 40 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+mail.example.com. IN A
+SECTION ANSWER
+mail.example.com. IN A 10.20.30.20
+;SECTION AUTHORITY
+;example.com. IN NS ns.example.com.
+;SECTION ADDITIONAL
+;ns.example.com. IN A 1.2.3.55
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/iter_pcnamech.rpl b/tests/integration/deckard/sets/resolver/iter_pcnamech.rpl
new file mode 100644
index 0000000..89059f0
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/iter_pcnamech.rpl
@@ -0,0 +1,423 @@
+do-ip6: no
+
+; config options
+; target-fetch-policy: "0 0 0 0 0"
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test resolution with parent child differ with extra child name.
+; child has extra name and it has to be used once the other one stops working.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+net. IN NS
+SECTION AUTHORITY
+net. IN NS e.gtld-servers.net.
+SECTION ADDITIONAL
+e.gtld-servers.net. IN A 192.12.94.30
+ENTRY_END
+
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.44
+ENTRY_END
+RANGE_END
+
+; e.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.12.94.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+net. IN NS
+SECTION ANSWER
+net. IN NS e.gtld-servers.net.
+SECTION ADDITIONAL
+e.gtld-servers.net. IN A 192.12.94.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.net. IN NS
+SECTION AUTHORITY
+example.net. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.net. IN A 1.2.3.55
+ENTRY_END
+
+RANGE_END
+
+; the working version, until time 50.
+RANGE_BEGIN 0 50
+ ADDRESS 1.2.3.44
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY AA QR NOERROR
+SECTION QUESTION
+example.net. IN NS
+SECTION ANSWER
+example.net. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.net. IN A 1.2.3.55
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY AA QR NOERROR
+SECTION QUESTION
+ns.example.net. IN A
+SECTION ANSWER
+ns.example.net. IN A 1.2.3.55
+SECTION AUTHORITY
+example.net. IN NS ns.example.net.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY AA QR NOERROR
+SECTION QUESTION
+ns.example.net. IN AAAA
+SECTION AUTHORITY
+example.net. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.net. IN A 1.2.3.55
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY AA QR NOERROR
+SECTION QUESTION
+ns.example.com. IN A
+SECTION ANSWER
+ns.example.com. IN A 1.2.3.44
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. IN NS ns.example.net.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY AA QR NOERROR
+SECTION QUESTION
+ns.example.com. IN AAAA
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.44
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY AA QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+example.com. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.44
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY AA QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.44
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY AA QR NOERROR
+SECTION QUESTION
+mail.example.com. IN A
+SECTION ANSWER
+mail.example.com. IN A 10.20.30.20
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.44
+ENTRY_END
+RANGE_END
+
+; Broken. Does not respond to anything (servfail instead
+; of timeouts since this is easier to encode in .rpl file format).
+RANGE_BEGIN 0 50
+ ADDRESS 1.2.3.55
+ENTRY_BEGIN
+MATCH opcode
+ADJUST copy_id copy_query
+REPLY QR SERVFAIL
+SECTION QUESTION
+example.net. IN NS
+SECTION ANSWER
+ENTRY_END
+RANGE_END
+
+RANGE_BEGIN 50 100
+ ADDRESS 1.2.3.44
+ENTRY_BEGIN
+MATCH opcode
+ADJUST copy_id copy_query
+REPLY QR SERVFAIL
+SECTION QUESTION
+example.net. IN NS
+SECTION ANSWER
+ENTRY_END
+RANGE_END
+
+RANGE_BEGIN 50 100
+ ADDRESS 1.2.3.55
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY AA QR NOERROR
+SECTION QUESTION
+example.net. IN NS
+SECTION ANSWER
+example.net. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.net. IN A 1.2.3.55
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY AA QR NOERROR
+SECTION QUESTION
+ns.example.net. IN A
+SECTION ANSWER
+ns.example.net. IN A 1.2.3.55
+SECTION AUTHORITY
+example.net. IN NS ns.example.net.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY AA QR NOERROR
+SECTION QUESTION
+ns.example.net. IN AAAA
+SECTION AUTHORITY
+example.net. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.net. IN A 1.2.3.55
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY AA QR NOERROR
+SECTION QUESTION
+ns.example.com. IN A
+SECTION ANSWER
+ns.example.com. IN A 1.2.3.44
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. IN NS ns.example.net.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY AA QR NOERROR
+SECTION QUESTION
+ns.example.com. IN AAAA
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.44
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY AA QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+example.com. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.44
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY AA QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.44
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY AA QR NOERROR
+SECTION QUESTION
+mail.example.com. IN A
+SECTION ANSWER
+mail.example.com. IN A 10.20.30.20
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.44
+ENTRY_END
+RANGE_END
+
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 20 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH flags rcode question answer
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+;SECTION AUTHORITY
+;example.com. IN NS ns.example.com.
+;example.com. IN NS ns.example.net.
+;SECTION ADDITIONAL
+;ns.example.com. IN A 1.2.3.44
+ENTRY_END
+
+; server stops working.
+
+STEP 50 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+mail.example.com. IN A
+ENTRY_END
+
+STEP 60 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH flags rcode question answer
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+mail.example.com. IN A
+SECTION ANSWER
+mail.example.com. IN A 10.20.30.20
+;SECTION AUTHORITY
+;example.com. IN NS ns.example.com.
+;example.com. IN NS ns.example.net.
+;SECTION ADDITIONAL
+;ns.example.com. IN A 1.2.3.44
+ENTRY_END
+
+; still pending query needs removal.
+STEP 70 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+ns.example.net. IN AAAA
+ENTRY_END
+
+STEP 71 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH flags rcode question answer
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+ns.example.net. IN AAAA
+SECTION ANSWER
+;SECTION AUTHORITY
+;example.net. IN NS ns.example.net.
+;SECTION ADDITIONAL
+;ns.example.net. IN A 1.2.3.55
+ENTRY_END
+
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/iter_pcnamechrec.rpl b/tests/integration/deckard/sets/resolver/iter_pcnamechrec.rpl
new file mode 100644
index 0000000..afc0ec3
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/iter_pcnamechrec.rpl
@@ -0,0 +1,402 @@
+do-ip6: no
+
+; config options
+; target-fetch-policy: "0 0 0 0 0"
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test resolution with parent child differ with pc child name.
+; child has extra name and it has to be used once the other one stops working.
+; the extra child name has parent-child trouble and needs its parent version.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+net. IN NS
+SECTION AUTHORITY
+net. IN NS e.gtld-servers.net.
+SECTION ADDITIONAL
+e.gtld-servers.net. IN A 192.12.94.30
+ENTRY_END
+
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.44
+ENTRY_END
+RANGE_END
+
+; e.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.12.94.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+net. IN NS
+SECTION ANSWER
+net. IN NS e.gtld-servers.net.
+SECTION ADDITIONAL
+e.gtld-servers.net. IN A 192.12.94.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.net. IN NS
+SECTION AUTHORITY
+example.net. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.net. IN A 1.2.3.55
+ENTRY_END
+
+RANGE_END
+
+; the working version, until time 50.
+RANGE_BEGIN 0 50
+ ADDRESS 1.2.3.44
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY AA QR NOERROR
+SECTION QUESTION
+example.net. IN NS
+SECTION ANSWER
+example.net. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.net. IN A 1.2.3.44
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY AA QR NOERROR
+SECTION QUESTION
+ns.example.net. IN A
+SECTION ANSWER
+ns.example.net. IN A 1.2.3.44
+SECTION AUTHORITY
+example.net. IN NS ns.example.net.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY AA QR NOERROR
+SECTION QUESTION
+ns.example.net. IN AAAA
+SECTION AUTHORITY
+example.net. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.net. IN A 1.2.3.44
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY AA QR NOERROR
+SECTION QUESTION
+ns.example.com. IN A
+SECTION ANSWER
+ns.example.com. IN A 1.2.3.44
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. IN NS ns.example.net.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY AA QR NOERROR
+SECTION QUESTION
+ns.example.com. IN AAAA
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.44
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY AA QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+example.com. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.44
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY AA QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.44
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY AA QR NOERROR
+SECTION QUESTION
+mail.example.com. IN A
+SECTION ANSWER
+mail.example.com. IN A 10.20.30.20
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.44
+ENTRY_END
+RANGE_END
+
+; Broken. Does not respond to anything (servfail instead
+; of timeouts since this is easier to encode in .rpl file format).
+RANGE_BEGIN 0 50
+ ADDRESS 1.2.3.55
+ENTRY_BEGIN
+MATCH opcode
+ADJUST copy_id copy_query
+REPLY QR SERVFAIL
+SECTION QUESTION
+example.net. IN NS
+SECTION ANSWER
+ENTRY_END
+RANGE_END
+
+RANGE_BEGIN 50 100
+ ADDRESS 1.2.3.44
+ENTRY_BEGIN
+MATCH opcode
+ADJUST copy_id copy_query
+REPLY QR SERVFAIL
+SECTION QUESTION
+example.net. IN NS
+SECTION ANSWER
+ENTRY_END
+RANGE_END
+
+RANGE_BEGIN 50 100
+ ADDRESS 1.2.3.55
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY AA QR NOERROR
+SECTION QUESTION
+example.net. IN NS
+SECTION ANSWER
+example.net. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.net. IN A 1.2.3.44
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY AA QR NOERROR
+SECTION QUESTION
+ns.example.net. IN A
+SECTION ANSWER
+ns.example.net. IN A 1.2.3.44
+SECTION AUTHORITY
+example.net. IN NS ns.example.net.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY AA QR NOERROR
+SECTION QUESTION
+ns.example.net. IN AAAA
+SECTION AUTHORITY
+example.net. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.net. IN A 1.2.3.44
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY AA QR NOERROR
+SECTION QUESTION
+ns.example.com. IN A
+SECTION ANSWER
+ns.example.com. IN A 1.2.3.44
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. IN NS ns.example.net.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY AA QR NOERROR
+SECTION QUESTION
+ns.example.com. IN AAAA
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.44
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY AA QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+example.com. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.44
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY AA QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.44
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY AA QR NOERROR
+SECTION QUESTION
+mail.example.com. IN A
+SECTION ANSWER
+mail.example.com. IN A 10.20.30.20
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.44
+ENTRY_END
+RANGE_END
+
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 20 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+;SECTION AUTHORITY
+;example.com. IN NS ns.example.com.
+;example.com. IN NS ns.example.net.
+;SECTION ADDITIONAL
+;ns.example.com. IN A 1.2.3.44
+ENTRY_END
+
+; server stops working.
+
+STEP 50 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+mail.example.com. IN A
+ENTRY_END
+
+STEP 60 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+mail.example.com. IN A
+SECTION ANSWER
+mail.example.com. IN A 10.20.30.20
+;SECTION AUTHORITY
+;example.com. IN NS ns.example.com.
+;example.com. IN NS ns.example.net.
+;SECTION ADDITIONAL
+;ns.example.com. IN A 1.2.3.44
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/iter_pcnamerec.rpl b/tests/integration/deckard/sets/resolver/iter_pcnamerec.rpl
new file mode 100644
index 0000000..7431505
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/iter_pcnamerec.rpl
@@ -0,0 +1,276 @@
+do-ip6: no
+
+; config options
+;server:
+; target-fetch-policy: "0 0 0 0 0"
+
+;stub-zone:
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test resolution with parent child differ names recursive.
+; the parent has an extra name that is the only working one.
+; and that name needs its parent-side glue to work.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+net. IN NS
+SECTION AUTHORITY
+net. IN NS e.gtld-servers.net.
+SECTION ADDITIONAL
+e.gtld-servers.net. IN A 192.12.94.30
+ENTRY_END
+
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.55
+ENTRY_END
+RANGE_END
+
+; e.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.12.94.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+net. IN NS
+SECTION ANSWER
+net. IN NS e.gtld-servers.net.
+SECTION ADDITIONAL
+e.gtld-servers.net. IN A 192.12.94.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.net. IN NS
+SECTION AUTHORITY
+example.net. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.net. IN A 1.2.3.44
+ENTRY_END
+
+RANGE_END
+
+; ns.example.net.
+; the working version.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.44
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY AA QR NOERROR
+SECTION QUESTION
+example.net. IN NS
+SECTION ANSWER
+example.net. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.net. IN A 1.2.3.55
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY AA QR NOERROR
+SECTION QUESTION
+ns.example.net. IN A
+SECTION ANSWER
+ns.example.net. IN A 1.2.3.55
+SECTION AUTHORITY
+example.net. IN NS ns.example.net.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY AA QR NOERROR
+SECTION QUESTION
+ns.example.net. IN AAAA
+SECTION AUTHORITY
+example.net. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.net. IN A 1.2.3.55
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY AA QR NOERROR
+SECTION QUESTION
+ns.example.com. IN A
+SECTION ANSWER
+ns.example.com. IN A 1.2.3.55
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY AA QR NOERROR
+SECTION QUESTION
+ns.example.com. IN AAAA
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.55
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY AA QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.55
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY AA QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.55
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY AA QR NOERROR
+SECTION QUESTION
+mail.example.com. IN A
+SECTION ANSWER
+mail.example.com. IN A 10.20.30.20
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.55
+ENTRY_END
+RANGE_END
+
+; ns.example.net
+; Broken. Does not respond to anything (servfail instead
+; of timeouts since this is easier to encode in .rpl file format).
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.55
+ENTRY_BEGIN
+MATCH opcode
+ADJUST copy_id copy_query
+REPLY QR SERVFAIL
+SECTION QUESTION
+example.net. IN NS
+SECTION ANSWER
+ENTRY_END
+
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 20 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH opcode qname flags rcode question answer
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+; now that the bad child NS record is in cache, ask something else.
+STEP 30 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+mail.example.com. IN A
+ENTRY_END
+
+STEP 40 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH opcode qname flags rcode question answer
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+mail.example.com. IN A
+SECTION ANSWER
+mail.example.com. IN A 10.20.30.20
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/iter_pcttl.rpl b/tests/integration/deckard/sets/resolver/iter_pcttl.rpl
new file mode 100644
index 0000000..7378d56
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/iter_pcttl.rpl
@@ -0,0 +1,355 @@
+do-ip6: no
+
+; config options
+; target-fetch-policy: "0 0 0 0 0"
+; do-ip6: no
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test cache ttls where parent child differ in ttl
+; and the lameness for parent suddenly becomes the only information point.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+net. IN NS
+SECTION AUTHORITY
+net. IN NS e.gtld-servers.net.
+SECTION ADDITIONAL
+e.gtld-servers.net. IN A 192.12.94.30
+ENTRY_END
+
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION AUTHORITY
+example.com. IN NS ns.foo.com.
+SECTION ADDITIONAL
+;ns.foo.com. 200 IN A 1.2.3.44
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+foo.com. IN NS
+SECTION AUTHORITY
+foo.com. 200 IN NS ns.foo.com.
+SECTION ADDITIONAL
+ns.foo.com. 200 IN A 1.2.3.44
+ENTRY_END
+
+RANGE_END
+
+; e.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.12.94.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+net. IN NS
+SECTION ANSWER
+net. IN NS e.gtld-servers.net.
+SECTION ADDITIONAL
+e.gtld-servers.net. IN A 192.12.94.30
+ENTRY_END
+
+; gtld-servers.net.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+gtld-servers.net. IN NS
+SECTION ANSWER
+gtld-servers.net. IN NS e.gtld-servers.net.
+SECTION ADDITIONAL
+e.gtld-servers.net. IN A 192.12.94.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+gtld-servers.net. IN A
+SECTION AUTHORITY
+gtld-servers.net. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+a.gtld-servers.net. IN A
+SECTION ANSWER
+a.gtld-servers.net. IN A 192.5.6.30
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+a.gtld-servers.net. IN AAAA
+SECTION ANSWER
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+e.gtld-servers.net. IN A
+SECTION ANSWER
+e.gtld-servers.net. IN A 192.12.94.30
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+e.gtld-servers.net. IN AAAA
+SECTION ANSWER
+SECTION ADDITIONAL
+ENTRY_END
+
+; root-servers.net.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+root-servers.net. IN NS
+SECTION ANSWER
+root-servers.net. IN NS k.root-servers.net.
+SECTION ADDITIONAL
+k.root-servers.net. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+root-servers.net. IN A
+SECTION AUTHORITY
+root-servers.net. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+k.root-servers.net. IN A
+SECTION ANSWER
+k.root-servers.net. IN A 193.0.14.129
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+k.root-servers.net. IN AAAA
+SECTION AUTHORITY
+root-servers.net. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+
+
+RANGE_END
+
+; ns.foo.com.
+; The parent-IP version
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.44
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY AA QR NOERROR
+SECTION QUESTION
+foo.com. IN NS
+SECTION ANSWER
+foo.com. 200 IN NS ns.foo.com.
+SECTION ADDITIONAL
+ns.foo.com. 100 IN A 1.2.3.44
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY AA QR NOERROR
+SECTION QUESTION
+ns.foo.com. IN A
+SECTION ANSWER
+ns.foo.com. 100 IN A 1.2.3.44
+SECTION AUTHORITY
+foo.com. 200 IN NS ns.foo.com.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY AA QR NOERROR
+SECTION QUESTION
+ns.foo.com. IN AAAA
+SECTION AUTHORITY
+foo.com. 100 IN SOA . . 1 2 3 4 5
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY AA QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. 200 IN NS ns.foo.com.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY AA QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. 100 IN A 10.20.30.40
+SECTION AUTHORITY
+example.com. 200 IN NS ns.foo.com.
+SECTION ADDITIONAL
+ns.foo.com 100 IN A 1.2.3.44
+ENTRY_END
+RANGE_END
+
+; NOT USED. The parent side equals child side but not in the cache.
+; and they have different TTLs only.
+; ns.foo.com
+; The child IP version. Does not respond to anything (servfail instead
+; of timeouts since this is easier to encode in .rpl file format).
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.55
+ENTRY_BEGIN
+MATCH opcode
+ADJUST copy_id copy_query
+REPLY QR SERVFAIL
+SECTION QUESTION
+foo.com. IN NS
+SECTION ANSWER
+ENTRY_END
+
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 20 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. 100 IN A 10.20.30.40
+;SECTION AUTHORITY
+;example.com. 100 IN NS ns.foo.com.
+; scrubbed off
+;SECTION ADDITIONAL
+;ns.foo.com IN A 1.2.3.44
+ENTRY_END
+
+; Now we wait 101 seconds, and the child data is gone,
+; but the parent-side was cached for 200 and it still there.
+
+STEP 30 TIME_PASSES ELAPSE 101
+
+STEP 40 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 50 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. 100 IN A 10.20.30.40
+;SECTION AUTHORITY
+;example.com. 100 IN NS ns.foo.com.
+; scrubbed off
+;SECTION ADDITIONAL
+;ns.foo.com IN A 1.2.3.44
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/iter_reclame_one.rpl b/tests/integration/deckard/sets/resolver/iter_reclame_one.rpl
new file mode 100644
index 0000000..f4730e7
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/iter_reclame_one.rpl
@@ -0,0 +1,318 @@
+do-ip6: no
+
+; config options
+; target-fetch-policy: "0 0 0 0 0"
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test iterative resolve with a recursion lame server.
+; The scenario has a domain with two servers, one is lame the other doesn't
+; so depending on the randomly chosen server that goes first, it may
+; select the nonlame or the lame server first.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+; net.
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+net. IN NS
+SECTION AUTHORITY
+. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+; root-servers.net.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+root-servers.net. IN NS
+SECTION ANSWER
+root-servers.net. IN NS k.root-servers.net.
+SECTION ADDITIONAL
+k.root-servers.net. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+root-servers.net. IN A
+SECTION AUTHORITY
+root-servers.net. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+k.root-servers.net. IN A
+SECTION ANSWER
+k.root-servers.net. IN A 193.0.14.129
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+k.root-servers.net. IN AAAA
+SECTION AUTHORITY
+root-servers.net. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+; gtld-servers.net.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+gtld-servers.net. IN NS
+SECTION ANSWER
+gtld-servers.net. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+gtld-servers.net. IN A
+SECTION AUTHORITY
+gtld-servers.net. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+a.gtld-servers.net. IN A
+SECTION ANSWER
+a.gtld-servers.net. IN A 192.5.6.30
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+a.gtld-servers.net. IN AAAA
+SECTION AUTHORITY
+gtld-servers.net. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.net. IN A
+SECTION AUTHORITY
+example.net. IN NS ns.example.net.
+SECTION ADDITIONAL
+; parent-side working address.
+ns.example.net. IN A 1.2.3.4
+ENTRY_END
+
+
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. IN NS lame.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+lame.example.com. IN A 1.2.3.5
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+example.com. IN NS lame.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+lame.example.com. IN A 1.2.3.5
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns.example.com. IN A
+SECTION ANSWER
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns.example.com. IN AAAA
+SECTION AUTHORITY
+example.com. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+lame.example.com. IN A
+SECTION ANSWER
+lame.example.com. IN A 1.2.3.5
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+lame.example.com. IN AAAA
+SECTION AUTHORITY
+example.com. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. IN NS lame.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+lame.example.com. IN A 1.2.3.5
+ENTRY_END
+RANGE_END
+
+; lame.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.5
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RA NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+example.com. IN NS lame.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+lame.example.com. IN A 1.2.3.5
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. IN NS lame.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+lame.example.com. IN A 1.2.3.5
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+;SECTION AUTHORITY
+;example.com. IN NS ns.example.com.
+;example.com. IN NS lame.example.com.
+;SECTION ADDITIONAL
+;ns.example.com. IN A 1.2.3.4
+;lame.example.com. IN A 1.2.3.5
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/iter_reclame_two.rpl b/tests/integration/deckard/sets/resolver/iter_reclame_two.rpl
new file mode 100644
index 0000000..5bf07ee
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/iter_reclame_two.rpl
@@ -0,0 +1,357 @@
+do-ip6: no
+
+; config options
+; target-fetch-policy: "0 0 0 0 0"
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test iterative resolve with two recursion lame servers.
+; both servers are recursion lame. The iterator tries both servers,
+; but they are both lame. Then it concludes that it only has reclame.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+; net.
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+net. IN NS
+SECTION AUTHORITY
+. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+; root-servers.net.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+root-servers.net. IN NS
+SECTION ANSWER
+root-servers.net. IN NS k.root-servers.net.
+SECTION ADDITIONAL
+k.root-servers.net. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+root-servers.net. IN A
+SECTION AUTHORITY
+root-servers.net. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+k.root-servers.net. IN A
+SECTION ANSWER
+k.root-servers.net. IN A 193.0.14.129
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+k.root-servers.net. IN AAAA
+SECTION AUTHORITY
+root-servers.net. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+; gtld-servers.net.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+gtld-servers.net. IN NS
+SECTION ANSWER
+gtld-servers.net. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+gtld-servers.net. IN A
+SECTION AUTHORITY
+gtld-servers.net. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+a.gtld-servers.net. IN A
+SECTION ANSWER
+a.gtld-servers.net. IN A 192.5.6.30
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+a.gtld-servers.net. IN AAAA
+SECTION AUTHORITY
+gtld-servers.net. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.net. IN A
+SECTION AUTHORITY
+example.net. IN NS ns.example.net.
+SECTION ADDITIONAL
+; parent-side working address.
+ns.example.net. IN A 1.2.3.4
+ENTRY_END
+
+
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. IN NS lame.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+lame.example.com. IN A 1.2.3.5
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RA NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+example.com. IN NS lame.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+lame.example.com. IN A 1.2.3.5
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RA NOERROR
+SECTION QUESTION
+ns.example.com. IN A
+SECTION ANSWER
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RA NOERROR
+SECTION QUESTION
+ns.example.com. IN AAAA
+SECTION AUTHORITY
+example.com. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RA NOERROR
+SECTION QUESTION
+lame.example.com. IN A
+SECTION ANSWER
+lame.example.com. IN A 1.2.3.5
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RA NOERROR
+SECTION QUESTION
+lame.example.com. IN AAAA
+SECTION AUTHORITY
+example.com. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. IN NS lame.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+lame.example.com. IN A 1.2.3.5
+ENTRY_END
+RANGE_END
+
+; lame.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.5
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RA NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+example.com. IN NS lame.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+lame.example.com. IN A 1.2.3.5
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. IN NS lame.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+lame.example.com. IN A 1.2.3.5
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RA NOERROR
+SECTION QUESTION
+ns.example.com. IN A
+SECTION ANSWER
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RA NOERROR
+SECTION QUESTION
+ns.example.com. IN AAAA
+SECTION AUTHORITY
+example.com. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RA NOERROR
+SECTION QUESTION
+lame.example.com. IN A
+SECTION ANSWER
+lame.example.com. IN A 1.2.3.5
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RA NOERROR
+SECTION QUESTION
+lame.example.com. IN AAAA
+SECTION AUTHORITY
+example.com. IN SOA . . 0 0 0 0 0
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+;SECTION AUTHORITY
+;example.com. IN NS ns.example.com.
+;example.com. IN NS lame.example.com.
+;SECTION ADDITIONAL
+;ns.example.com. IN A 1.2.3.4
+;lame.example.com. IN A 1.2.3.5
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/iter_recurse.rpl b/tests/integration/deckard/sets/resolver/iter_recurse.rpl
new file mode 100644
index 0000000..20b0db1
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/iter_recurse.rpl
@@ -0,0 +1,314 @@
+do-ip6: no
+
+; config options
+; target-fetch-policy: "0 0 0 0 0"
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test resolution with recursion for NS target.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+net. IN A
+SECTION AUTHORITY
+net. IN NS e.gtld-servers.net.
+SECTION ADDITIONAL
+e.gtld-servers.net. IN A 192.12.94.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns.example.net.
+ENTRY_END
+RANGE_END
+
+; e.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.12.94.30
+
+; net.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+net. IN NS
+SECTION ANSWER
+net. IN NS e.gtld-servers.net.
+SECTION ADDITIONAL
+e.gtld-servers.net. IN A 192.12.94.30
+ENTRY_END
+
+; root-servers.net.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+root-servers.net. IN NS
+SECTION ANSWER
+root-servers.net. IN NS k.root-servers.net.
+SECTION ADDITIONAL
+k.root-servers.net. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+root-servers.net. IN A
+SECTION AUTHORITY
+root-servers.net. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+k.root-servers.net. IN A
+SECTION ANSWER
+k.root-servers.net. IN A 193.0.14.129
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+k.root-servers.net. IN AAAA
+SECTION AUTHORITY
+root-servers.net. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+; gtld-servers.net.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+gtld-servers.net. IN NS
+SECTION ANSWER
+gtld-servers.net. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+gtld-servers.net. IN A
+SECTION AUTHORITY
+gtld-servers.net. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+a.gtld-servers.net. IN A
+SECTION ANSWER
+a.gtld-servers.net. IN A 192.5.6.30
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+a.gtld-servers.net. IN AAAA
+SECTION AUTHORITY
+gtld-servers.net. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+e.gtld-servers.net. IN A
+SECTION ANSWER
+e.gtld-servers.net. IN A 192.12.94.30
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+e.gtld-servers.net. IN AAAA
+SECTION AUTHORITY
+gtld-servers.net. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.net. IN A
+SECTION AUTHORITY
+example.net. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.net. IN A 1.2.3.44
+ENTRY_END
+
+RANGE_END
+
+; ns.example.net.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.44
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.net. IN NS
+SECTION ANSWER
+example.net. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.net. IN A 1.2.3.44
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.net. IN A
+SECTION ANSWER
+ns.example.net. IN A 1.2.3.44
+SECTION AUTHORITY
+example.net. IN NS ns.example.net.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.net. IN AAAA
+SECTION AUTHORITY
+example.net. IN NS ns.example.net.
+SECTION ADDITIONAL
+www.example.net. IN A 1.2.3.44
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.net.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+SECTION AUTHORITY
+example.com. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.net IN A 1.2.3.44
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 20 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+;SECTION AUTHORITY
+;example.com. IN NS ns.example.net.
+; scrubbed off
+;SECTION ADDITIONAL
+;ns.example.net IN A 1.2.3.44
+ENTRY_END
+
+; due to ordering of answer packets, this is still outstanding, remove it
+STEP 21 CHECK_OUT_QUERY
+ENTRY_BEGIN
+ADJUST copy_id
+MATCH qname qtype
+REPLY QR
+SECTION QUESTION
+ns.example.net IN AAAA
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/iter_req_qname.rpl b/tests/integration/deckard/sets/resolver/iter_req_qname.rpl
new file mode 100644
index 0000000..ea4d184
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/iter_req_qname.rpl
@@ -0,0 +1,122 @@
+do-ip6: no
+
+; config options
+;server:
+; target-fetch-policy: "0 0 0 0 0"
+
+;stub-zone:
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+;test from testbound
+
+SCENARIO_BEGIN Test a query name in the reply is required by resolver
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+
+; always the same reply since we cannot match anything from the qsection.
+ENTRY_BEGIN
+MATCH opcode
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+; no query section!
+; www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+
+; the query name is echoed properly to *our* client
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA SERVFAIL
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/iter_resolve.rpl b/tests/integration/deckard/sets/resolver/iter_resolve.rpl
new file mode 100644
index 0000000..b2f6311
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/iter_resolve.rpl
@@ -0,0 +1,221 @@
+do-ip6: no
+
+; config options
+; target-fetch-policy: "0 0 0 0 0"
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test basic iterative resolve of www.example.com.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+; net.
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+net. IN NS
+SECTION AUTHORITY
+. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+; root-servers.net.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+root-servers.net. IN NS
+SECTION ANSWER
+root-servers.net. IN NS k.root-servers.net.
+SECTION ADDITIONAL
+k.root-servers.net. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+root-servers.net. IN A
+SECTION AUTHORITY
+root-servers.net. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+k.root-servers.net. IN A
+SECTION ANSWER
+k.root-servers.net. IN A 193.0.14.129
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+k.root-servers.net. IN AAAA
+SECTION AUTHORITY
+root-servers.net. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+; gtld-servers.net.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+gtld-servers.net. IN NS
+SECTION ANSWER
+gtld-servers.net. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+gtld-servers.net. IN A
+SECTION AUTHORITY
+gtld-servers.net. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+a.gtld-servers.net. IN A
+SECTION ANSWER
+a.gtld-servers.net. IN A 192.5.6.30
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+a.gtld-servers.net. IN AAAA
+SECTION AUTHORITY
+gtld-servers.net. IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+
+
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+;SECTION AUTHORITY
+;example.com. IN NS ns.example.com.
+;SECTION ADDITIONAL
+;ns.example.com. IN A 1.2.3.4
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/iter_tcbit.rpl b/tests/integration/deckard/sets/resolver/iter_tcbit.rpl
new file mode 100644
index 0000000..89c45a5
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/iter_tcbit.rpl
@@ -0,0 +1,89 @@
+do-ip6: no
+
+; config options
+; harden-referral-path: no
+; target-fetch-policy: "0 0 0 0 0"
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test TCP failover when reply contains TC=1.
+
+STEP 10 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+cz. IN A
+ENTRY_END
+
+; root prime
+STEP 30 REPLY
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+; query sent to root server
+STEP 50 REPLY
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+cz. IN A
+SECTION AUTHORITY
+cz. IN NS ns1.cz.
+cz. IN NS ns2.cz.
+SECTION ADDITIONAL
+ns1.cz. IN A 168.192.2.2
+ns2.cz. IN A 168.192.3.3
+ENTRY_END
+
+; this is the truncated answer
+STEP 60 REPLY
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA TC NOERROR
+SECTION QUESTION
+cz. IN A
+SECTION ANSWER
+ENTRY_END
+
+; this is the correct answer
+STEP 70 REPLY
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+cz. IN A
+SECTION ANSWER
+cz. IN A 10.20.30.40
+SECTION AUTHORITY
+cz. IN NS ns1.cz.
+cz. IN NS ns2.cz.
+SECTION ADDITIONAL
+ns1.cz. IN A 168.192.2.2
+ns2.cz. IN A 168.192.3.3
+ENTRY_END
+
+; is the final answer correct?
+STEP 100 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA
+SECTION QUESTION
+cz. IN A
+SECTION ANSWER
+cz. IN A 10.20.30.40
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/iter_timeouted_ns.rpl b/tests/integration/deckard/sets/resolver/iter_timeouted_ns.rpl
new file mode 100644
index 0000000..fa1b8de
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/iter_timeouted_ns.rpl
@@ -0,0 +1,318 @@
+do-ip6: no
+
+; config options
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN fail.net has two NSs in different zones. One of them suddently stop responding, address of other one is unknown.
+
+RANGE_BEGIN 1 100 193.0.14.129; root
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+. NS
+SECTION ANSWER
+. NS k.root-servers.net
+SECTION ADDITIONAL
+k.root-servers.net A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+net NS
+SECTION AUTHORITY
+net NS m.gtld-servers.net.
+SECTION ADDITIONAL
+m.gtld-servers.net. A 192.55.83.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com NS
+SECTION AUTHORITY
+com NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+RANGE_BEGIN 1 100 192.55.83.30; net
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+net NS
+SECTION ANSWER
+net NS m.gtld-servers.net.
+SECTION ADDITIONAL
+m.gtld-servers.net. A 192.55.83.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+m.gtld-servers.net. A
+SECTION ANSWER
+m.gtld-servers.net. A 192.55.83.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+fail.net NS
+SECTION AUTHORITY
+fail.net NS ns.fail.net
+fail.net NS ns.fail.com
+SECTION ADDITIONAL
+ns.fail.net 20 A 1.1.1.1
+ENTRY_END
+RANGE_END
+
+RANGE_BEGIN 1 100 192.5.6.30; com
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+com NS
+SECTION ANSWER
+com NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+a.gtld-servers.net. A
+SECTION ANSWER
+a.gtld-servers.net. A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+fail.com NS
+SECTION AUTHORITY
+fail.com NS ns.fail.com
+SECTION ADDITIONAL
+ns.fail.com 10 A 1.1.2.1
+ENTRY_END
+RANGE_END
+
+RANGE_BEGIN 1 10 1.1.1.1; fail.net
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+fail.net NS
+SECTION ANSWER
+fail.net NS ns.fail.net
+fail.net NS ns.fail.com
+SECTION ADDITIONAL
+ns.fail.net 20 A 1.1.1.1
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns.fail.net A
+SECTION ANSWER
+ns.fail.net 20 A 1.1.1.1
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns.fail.net AAAA
+SECTION ANSWER
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+fail.net A
+SECTION ANSWER
+fail.net 10 A 1.1.1.2
+ENTRY_END
+RANGE_END
+
+RANGE_BEGIN 1 100 1.1.2.1; fail.com & fail.net
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+fail.net NS
+SECTION ANSWER
+fail.net NS ns.fail.net
+fail.net NS ns.fail.com
+SECTION ADDITIONAL
+ns.fail.com 10 A 1.1.2.1
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns.fail.net A
+SECTION ANSWER
+ns.fail.net 20 A 1.1.1.1
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns.fail.net AAAA
+SECTION ANSWER
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+fail.com NS
+SECTION AUTHORITY
+fail.com NS ns.fail.com
+SECTION ADDITIONAL
+ns.fail.com 10 A 1.1.2.1
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns.fail.com A
+SECTION ANSWER
+ns.fail.com 10 A 1.1.2.1
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns.fail.com AAAA
+SECTION ANSWER
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+fail.net A
+SECTION ANSWER
+fail.net 10 A 1.1.1.2
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+fail.com A
+SECTION ANSWER
+fail.com 10 A 1.1.2.2
+ENTRY_END
+RANGE_END
+
+RANGE_BEGIN 11 20 1.1.1.1; fail.net
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query do_not_answer
+REPLY QR AA NOERROR
+SECTION QUESTION
+fail.net A
+SECTION ANSWER
+fail.net 10 A 1.1.1.2
+ENTRY_END
+RANGE_END
+
+; Cache zonecuts for fail.net and fail.com
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+fail.net A
+ENTRY_END
+
+STEP 2 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH rcode flags question answer
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+fail.net A
+SECTION ANSWER
+fail.net 10 A 1.1.1.2
+ENTRY_END
+
+STEP 3 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+fail.com A
+ENTRY_END
+
+STEP 4 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH rcode flags question answer
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+fail.com A
+SECTION ANSWER
+fail.com 10 A 1.1.2.2
+ENTRY_END
+
+; Allow to expire ns.fail.com, fail.net, fail.com
+; Note that ns.fail.net isn't expired yet
+STEP 5 TIME_PASSES ELAPSE 15
+
+; Allow ns.fail.net to be timeouted
+; kresd must get right answer using ns.fail.com
+STEP 11 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+fail.net A
+ENTRY_END
+
+STEP 12 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH rcode flags question answer
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+fail.net A
+SECTION ANSWER
+fail.net 10 A 1.1.1.2
+ENTRY_END
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/iter_unexpectedrrtype.rpl b/tests/integration/deckard/sets/resolver/iter_unexpectedrrtype.rpl
new file mode 100644
index 0000000..34b377f
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/iter_unexpectedrrtype.rpl
@@ -0,0 +1,61 @@
+do-ip6: no
+
+stub-addr: 1.1.1.1
+CONFIG_END
+
+SCENARIO_BEGIN Test ignoring answers with unexpected RRType
+
+RANGE_BEGIN 0 100
+ ADDRESS 1.1.1.1
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RD NOERROR
+SECTION QUESTION
+example.com. IN AAAA
+SECTION ANSWER
+example.com. 0 IN A 2.2.2.2 ; returns A record
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname qtype
+ADJUST copy_id
+REPLY QR RD NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS k.root-servers.net.
+SECTION ADDITIONAL
+k.root-servers.net. IN A 1.1.1.1
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR RD NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION AUTHORITY
+com. IN NS k.root-servers.net.
+SECTION ADDITIONAL
+k.root-servers.net. IN A 1.1.1.1
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+example.com. IN AAAA
+ENTRY_END
+
+STEP 2 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+example.com. IN AAAA
+SECTION ANSWER
+ENTRY_END
+
+SCENARIO_END \ No newline at end of file
diff --git a/tests/integration/deckard/sets/resolver/iter_validate.rpl b/tests/integration/deckard/sets/resolver/iter_validate.rpl
new file mode 100644
index 0000000..d3725e4
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/iter_validate.rpl
@@ -0,0 +1,211 @@
+do-ip6: no
+
+; config options
+;server:
+ trust-anchor: ". 3600 IN DS 19036 8 2 49AAC11D7B6F6446702E54A1607371607A1A41855200FD2CE1CDDE32F24E8FB5"
+ val-override-timestamp: "1437625000"
+
+;stub-zone:
+; name: "."
+ stub-addr: 198.41.0.4 # a.root-servers.net.
+CONFIG_END
+
+SCENARIO_BEGIN Test basic validation of NS cz. (two levels)
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 198.41.0.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. 518400 IN NS a.root-servers.net.
+. 518400 IN NS b.root-servers.net.
+. 518400 IN NS c.root-servers.net.
+. 518400 IN NS d.root-servers.net.
+. 518400 IN NS e.root-servers.net.
+. 518400 IN NS f.root-servers.net.
+. 518400 IN NS g.root-servers.net.
+. 518400 IN NS h.root-servers.net.
+. 518400 IN NS i.root-servers.net.
+. 518400 IN NS j.root-servers.net.
+. 518400 IN NS k.root-servers.net.
+. 518400 IN NS l.root-servers.net.
+. 518400 IN NS m.root-servers.net.
+. 518400 IN RRSIG NS 8 0 518400 20150802050000 20150723040000 1518 . JSoL4/wQXh7vzoY/m98WYbpr2/S66u4RQi/UhkSrR3JmPZaWRRERDFm6 RRrFY6GWt4CP61X9rvshuVT+0OhluXqYpEatoHEDgur+PKf3+dTAmcgQ 4RzsahwhQ42Y9fDgJ2nNVMcN97HEIH+qMv0FWjU9b7wJ2iYlDL1ZoAVu TKE=
+SECTION ADDITIONAL
+a.root-servers.net. 518400 IN A 198.41.0.4
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+. IN DNSKEY
+SECTION ANSWER
+. 172800 IN DNSKEY 256 3 8 AwEAAa67bQck1JjopOOFc+iMISFcp/osWrEst2wbKbuQSUWu77QC9UHL ipiHgWN7JlqVAEjKITZz49hhkLmOpmLK55pTq+RD2kwoyNWk9cvpc+tS nIxT7i93O+3oVeLYjMWrkDAz7K45rObbHDuSBwYZKrcSIUCZnCpNMUtn PFl/04cb
+. 172800 IN DNSKEY 257 3 8 AwEAAagAIKlVZrpC6Ia7gEzahOR+9W29euxhJhVVLOyQbSEW0O8gcCjF FVQUTf6v58fLjwBd0YI0EzrAcQqBGCzh/RStIoO8g0NfnfL2MTJRkxoX bfDaUeVPQuYEhg37NZWAJQ9VnMVDxP/VHL496M/QZxkjf5/Efucp2gaD X6RS6CXpoY68LsvPVjR0ZSwzz1apAzvN9dlzEheX7ICJBBtuA6G3LQpz W5hOA2hzCTMjJPJ8LbqF6dsV6DoBQzgul0sGIcGOYl7OyQdXfZ57relS Qageu+ipAdTTJ25AsRTAoub8ONGcLmqrAmRLKBP1dfwhYB4N7knNnulq QxA+Uk1ihz0=
+. 172800 IN RRSIG DNSKEY 8 0 172800 20150804235959 20150721000000 19036 . n9FwNj80Zik2Rr2zTB4F17ydFpiZfUIv8v/XAz4EbSgRxQgFT+TCz3FW i4O7tW5REXUVNHtULiS7fxKLsHZNDPev8DA20DXAw3eEIDi9pDi01O/e 4GnljpkPnP8d5zA62Dob4cxgmhjjFTvhIjtDsH5Dd4jmyHsgBboy4grZ uJNdsez76gD4Ad6WlosZn5Hj5JwqaxZlRph/6I3va4rkp4c32w5DwaQ7 WSne8ffMHX9r7Dn6EbT3FfvnXFDNPE1P6r+qzTzC0t+M/F4R3H+VOdqg cRJcBG6zGCh9ZErhAeoiJh1WAfpjpzx+TUMzqxZCjSC/XL+l2YMKVHtF 8WNg/w==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+cz. IN NS
+SECTION AUTHORITY
+cz. 172800 IN NS a.ns.nic.cz.
+cz. 86400 IN DS 54576 10 2 397E50C85EDE9CDE33F363A9E66FD1B216D788F8DD438A57A423A386 869C8F06
+cz. 86400 IN RRSIG DS 8 1 86400 20150802050000 20150723040000 1518 . fEz3NpYRzgeBjKrLMpht3KFOQ0t6U2wikIaOt1HcmFvurxtPkZVvqdb0 QBQfvh8DoEXDbvpcikzMIO9XYLzzs10X/m91ybGiWzcTVcU+prVGZJP9 zZrvYAIWrpxoC4deKD+vOoNZXGnLfffi6lmGn7QRZaH0LVKjn33cIaPQ 9EM=
+SECTION ADDITIONAL
+a.ns.nic.cz. 172800 IN A 194.0.12.1
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+cz. IN DS
+SECTION ANSWER
+cz. 86400 IN DS 54576 10 2 397E50C85EDE9CDE33F363A9E66FD1B216D788F8DD438A57A423A386 869C8F06
+cz. 86400 IN RRSIG DS 8 1 86400 20150802050000 20150723040000 1518 . fEz3NpYRzgeBjKrLMpht3KFOQ0t6U2wikIaOt1HcmFvurxtPkZVvqdb0 QBQfvh8DoEXDbvpcikzMIO9XYLzzs10X/m91ybGiWzcTVcU+prVGZJP9 zZrvYAIWrpxoC4deKD+vOoNZXGnLfffi6lmGn7QRZaH0LVKjn33cIaPQ 9EM=
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+cz. IN RRSIG
+SECTION AUTHORITY
+cz. 172800 IN NS a.ns.nic.cz.
+cz. 86400 IN DS 54576 10 2 397E50C85EDE9CDE33F363A9E66FD1B216D788F8DD438A57A423A386 869C8F06
+cz. 86400 IN RRSIG DS 8 1 86400 20150802050000 20150723040000 1518 . fEz3NpYRzgeBjKrLMpht3KFOQ0t6U2wikIaOt1HcmFvurxtPkZVvqdb0 QBQfvh8DoEXDbvpcikzMIO9XYLzzs10X/m91ybGiWzcTVcU+prVGZJP9 zZrvYAIWrpxoC4deKD+vOoNZXGnLfffi6lmGn7QRZaH0LVKjn33cIaPQ 9EM=
+SECTION ADDITIONAL
+a.ns.nic.cz. 172800 IN A 194.0.12.1
+ENTRY_END
+
+RANGE_END
+
+;a.ns.nic.cz.
+RANGE_BEGIN 0 100
+ ADDRESS 194.0.12.1
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+cz. IN DNSKEY
+SECTION ANSWER
+cz. 18000 IN DNSKEY 256 3 10 AwEAAbwKeyKB5fuLe16/N5MR6OoG/PO8uxEob7HoIjK0w0wNjwINYb2w edLtzhVlA4HJ0AUUBuZiNj41hlJ474SOBlsAA7BQdtbL1V0Ksk8IC5Z8 3ldU9Mp+ynkj9p9Cl2UOBmoVFYfkbwz0BsOptcXruYA52Ayc9rHrmDPI /0Y8gZAL
+cz. 18000 IN DNSKEY 257 3 10 AwEAAay0hi4HN2r/BqMQTpIPIVDyjmyF+9ZWvr5Lewx+q+947o/GrRv4 FGFfkZxf9CFfYVUf0jG5Yq4i06pGVNwJl81HS9Ux2oeHRXUvgtLnl5He RVLL+zgI5byx9HSNr4bPO8ZEn5OjoayhkNyGSFr4VWrzQk/K02vLP4d1 cCEzUQy30eyZto2/tG5ZwCU/iRkS1PJOcOW98hiFIfFDZv1XjbEpqEYh T2PATs6rt+BKwSHKGISmg1PNdg+y0rItemYMWr1f9BGAdtTWoPCPCYPj OZMPoIyA4tMscD+ww54Jf/QNoHccY4hO1yHiuAXG7SUn8jo0IKQ9W7JJ xES0aqFCX/0=
+cz. 18000 IN RRSIG DNSKEY 10 1 18000 20150802000000 20150719000000 54576 cz. K04ONpLX3wseqHhUu2QLBY7wzSUszVlut5mC6jpCAqbfhgIvGMnyoWP5 lKwSvCLmjie0j1HSv8Q4OmoYGz8L+P/FGAzK4LhMturHrDtHkpuGvQJ6 //UsHQhf4iwCg5tEeHI4ZvaMmqRZI3FhBnSh0OyFjGO73FRbBU9nDrOM sPB1iCUfRfZhQU0sB/rj82ykBUma280sO1aRp3gmQHc/SVNbFfCL1Z8D htBP6sy4Jh0z3Z40d4CFZ8ZCBsIloHO44/GvXGePtr2dW4gJsoU1619B Jz+6cuTRh5RJBiweUNb/nwjBP8fNRkzH1CbjomC2FpDMnBXw7jE1GUiY vLW9Gg==
+cz. 18000 IN RRSIG DNSKEY 10 1 18000 20150805131929 20150723140842 39788 cz. KhyRPt4TYVYH7VAsfn39tY66+5P8bgZhG83d33oogLuqQEPgsxt/tu0c snrUA11Ub+4wOK3MslD5/gTyBuDtT9dk4FbRr3WeUZ4DNn5laYO3AcYx SAU3Vn3dZ8orWFxEwTKNhH5QthPdHj8p8097KRHiPo/DGEnFpYdocEws WJ4=
+ENTRY_END
+
+; a.ns.nic.cz.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+cz. IN NS
+SECTION ANSWER
+cz. 18000 IN NS a.ns.nic.cz.
+cz. 18000 IN NS b.ns.nic.cz.
+cz. 18000 IN NS c.ns.nic.cz.
+cz. 18000 IN NS d.ns.nic.cz.
+cz. 18000 IN RRSIG NS 10 1 18000 20150802132511 20150721120844 39788 cz. pf5UzinUesHzGQTav/1NxGW0AifCmzLW3S8X9tWDRwx7XSKGac7QVXgp nMNyb/NiSho9oj+ZTaQpBZQaTri+brHT4W/nE0TofqZlyYiaABb9xgxJ LgjLkt+OVcJsM3a+q+QEGSt+skNlZVDQeR+sztbuORiZXAqhxumxD8iy zZ8=
+SECTION ADDITIONAL
+a.ns.nic.cz. 18000 IN A 194.0.12.1
+b.ns.nic.cz. 18000 IN A 194.0.12.1
+c.ns.nic.cz. 18000 IN A 194.0.12.1
+d.ns.nic.cz. 18000 IN A 194.0.12.1
+ENTRY_END
+
+; a.ns.nic.cz.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+cz. IN RRSIG
+SECTION ANSWER
+; It's okay to lie here as the resolver can't check if we have provided every RRSIG, because there is no RRSIG of RRSIGs
+cz. 18000 IN RRSIG SOA 10 1 18000 20151221212655 20151208120941 37310 cz. ZsKG0TImVm+nAuWvn+Kg61WIet0E++Bt1mxIIywCxtZs/JQlhbjzFPvA ICdYLoqZ06JTwit1nD9xx6jdrfguSVB55G3LGuQiXz4JwEdCWhoVcC3Y Aq6jG1Eor3dhAF8dSIYkE21J3A6oC3O1rDYymKiXpkekFMaaBE0JEvUJ ut8=
+ENTRY_END
+
+RANGE_END
+
+;STEP 0 TIME_PASSES ELAPSE 1000
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+cz. IN RRSIG
+ENTRY_END
+
+; check that it answers a query for RRSIG (unauthenticated)
+; digests are swapped, i.e. signatures are invalid, server shouldn't use them later
+STEP 2 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+cz. IN RRSIG
+SECTION ANSWER
+cz. 18000 IN RRSIG SOA 10 1 18000 20151221212655 20151208120941 37310 cz. ZsKG0TImVm+nAuWvn+Kg61WIet0E++Bt1mxIIywCxtZs/JQlhbjzFPvA ICdYLoqZ06JTwit1nD9xx6jdrfguSVB55G3LGuQiXz4JwEdCWhoVcC3Y Aq6jG1Eor3dhAF8dSIYkE21J3A6oC3O1rDYymKiXpkekFMaaBE0JEvUJ ut8=
+ENTRY_END
+
+STEP 3 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+cz. IN NS
+ENTRY_END
+
+; check that it answers a plain query
+STEP 4 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+cz. IN NS
+SECTION ANSWER
+cz. 18000 IN NS a.ns.nic.cz.
+cz. 18000 IN NS b.ns.nic.cz.
+cz. 18000 IN NS c.ns.nic.cz.
+cz. 18000 IN NS d.ns.nic.cz.
+ENTRY_END
+
+STEP 5 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+cz. IN NS
+ENTRY_END
+
+; recursion happens here.
+STEP 6 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA AD NOERROR
+SECTION QUESTION
+cz. IN NS
+SECTION ANSWER
+cz. 18000 IN NS a.ns.nic.cz.
+cz. 18000 IN NS b.ns.nic.cz.
+cz. 18000 IN NS c.ns.nic.cz.
+cz. 18000 IN NS d.ns.nic.cz.
+cz. 18000 IN RRSIG NS 10 1 18000 20150802132511 20150721120844 39788 cz. pf5UzinUesHzGQTav/1NxGW0AifCmzLW3S8X9tWDRwx7XSKGac7QVXgp nMNyb/NiSho9oj+ZTaQpBZQaTri+brHT4W/nE0TofqZlyYiaABb9xgxJ LgjLkt+OVcJsM3a+q+QEGSt+skNlZVDQeR+sztbuORiZXAqhxumxD8iy zZ8=
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/iter_validate_child_zone_noaddr.rpl b/tests/integration/deckard/sets/resolver/iter_validate_child_zone_noaddr.rpl
new file mode 100644
index 0000000..1c228f5
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/iter_validate_child_zone_noaddr.rpl
@@ -0,0 +1,209 @@
+do-ip6: no
+
+; config options
+;server:
+ trust-anchor: ". 3600 IN DS 19036 8 2 49AAC11D7B6F6446702E54A1607371607A1A41855200FD2CE1CDDE32F24E8FB5"
+ val-override-timestamp: "1441892800"
+ query-minimization: off
+
+;stub-zone:
+; name: "."
+ stub-addr: 198.41.0.4 # a.root-servers.net.
+CONFIG_END
+
+SCENARIO_BEGIN Test basic validation of AAAA nic.cz.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 198.41.0.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. 518400 IN NS l.root-servers.net.
+. 518400 IN NS i.root-servers.net.
+. 518400 IN NS m.root-servers.net.
+. 518400 IN NS f.root-servers.net.
+. 518400 IN NS d.root-servers.net.
+. 518400 IN NS k.root-servers.net.
+. 518400 IN NS e.root-servers.net.
+. 518400 IN NS h.root-servers.net.
+. 518400 IN NS b.root-servers.net.
+. 518400 IN NS j.root-servers.net.
+. 518400 IN NS c.root-servers.net.
+. 518400 IN NS a.root-servers.net.
+. 518400 IN NS g.root-servers.net.
+. 518400 IN RRSIG NS 8 0 518400 20150920050000 20150910040000 1518 . ZCytFZO9aWv+135mNVaH+qdlXz1t2VyhaOx4GVbydiRuEMVKvjauxXMb OfnCK451G95AjxaL00eCi68Z19B3+pa6Ud8X81M69fHeB4/Eh+KIjl+d YvmUw3DxVQJknj/sHBVihjgsiMsiw03lE+dX+g2ms9TQbOo5VohLPgpC 82A=
+SECTION ADDITIONAL
+a.root-servers.net. 518400 IN A 198.41.0.4
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+. IN DNSKEY
+SECTION ANSWER
+. 172800 IN DNSKEY 257 3 8 AwEAAagAIKlVZrpC6Ia7gEzahOR+9W29euxhJhVVLOyQbSEW0O8gcCjF FVQUTf6v58fLjwBd0YI0EzrAcQqBGCzh/RStIoO8g0NfnfL2MTJRkxoX bfDaUeVPQuYEhg37NZWAJQ9VnMVDxP/VHL496M/QZxkjf5/Efucp2gaD X6RS6CXpoY68LsvPVjR0ZSwzz1apAzvN9dlzEheX7ICJBBtuA6G3LQpz W5hOA2hzCTMjJPJ8LbqF6dsV6DoBQzgul0sGIcGOYl7OyQdXfZ57relS Qageu+ipAdTTJ25AsRTAoub8ONGcLmqrAmRLKBP1dfwhYB4N7knNnulq QxA+Uk1ihz0=
+. 172800 IN DNSKEY 256 3 8 AwEAAa67bQck1JjopOOFc+iMISFcp/osWrEst2wbKbuQSUWu77QC9UHL ipiHgWN7JlqVAEjKITZz49hhkLmOpmLK55pTq+RD2kwoyNWk9cvpc+tS nIxT7i93O+3oVeLYjMWrkDAz7K45rObbHDuSBwYZKrcSIUCZnCpNMUtn PFl/04cb
+. 172800 IN RRSIG DNSKEY 8 0 172800 20150924000000 20150909000000 19036 . XGBRtnftNzxfk4LFyMzQXv9ZSV//SuiHlUYfnK8i0Hg3bHuOR2oEJ+JN P5HBlg+BGLTYHYBTuQYwn0FZd81gF7nVPDcQmHPwPzgwPWH00RDt46dK J1LwJ5KsAbNT5FOVuYRO2Rm15eajwaYGtJHSOyxHEegzuklvMgVVSiBr rPbNTF2/1Qi4c1y1gPXuxkifENbxlbHMvWxcVnG0v2xko/MazQnzSStv i1TtKUKDNT/jLyAv24wALWsPhOcNoVl1uRr9IJX7Ov9wbvSVCoEuBeKC hgy0KO1lRffnqR1YRRqjabKXB161T/fepLkwkxqa0Uidk+rRL3jxulJa nL2TMQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+nic.cz. IN MX
+SECTION AUTHORITY
+cz. 172800 IN NS a.ns.nic.cz.
+cz. 86400 IN DS 54576 10 2 397E50C85EDE9CDE33F363A9E66FD1B216D788F8DD438A57A423A386 869C8F06
+cz. 86400 IN RRSIG DS 8 1 86400 20150920050000 20150910040000 1518 . LRx9WQ8KhcUHOCe+eY7jvw1QIm1aRrin02Qn9YtImOGf4V1MVhf1ZYoF mP7GOBDXAbAJhrb5fPKumLsuRLgmA+5VyFhBMmzgqwRjdec1Tu7mWHoQ EukoZp4y2Mmw4NuAs1pBJQOZzLxhYUk+vbjK9mZm5u+mTtt/EFUu8QfG bp8=
+SECTION ADDITIONAL
+a.ns.nic.cz. 172800 IN A 194.0.12.1
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+nic.cz. IN DS
+SECTION AUTHORITY
+cz. 172800 IN NS a.ns.nic.cz.
+cz. 86400 IN DS 54576 10 2 397E50C85EDE9CDE33F363A9E66FD1B216D788F8DD438A57A423A386 869C8F06
+cz. 86400 IN RRSIG DS 8 1 86400 20150920050000 20150910040000 1518 . LRx9WQ8KhcUHOCe+eY7jvw1QIm1aRrin02Qn9YtImOGf4V1MVhf1ZYoF mP7GOBDXAbAJhrb5fPKumLsuRLgmA+5VyFhBMmzgqwRjdec1Tu7mWHoQ EukoZp4y2Mmw4NuAs1pBJQOZzLxhYUk+vbjK9mZm5u+mTtt/EFUu8QfG bp8=
+SECTION ADDITIONAL
+a.ns.nic.cz. 172800 IN A 194.0.12.1
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+nic.cz. IN DNSKEY
+SECTION AUTHORITY
+cz. 172800 IN NS a.ns.nic.cz.
+cz. 86400 IN DS 54576 10 2 397E50C85EDE9CDE33F363A9E66FD1B216D788F8DD438A57A423A386 869C8F06
+cz. 86400 IN RRSIG DS 8 1 86400 20150920050000 20150910040000 1518 . LRx9WQ8KhcUHOCe+eY7jvw1QIm1aRrin02Qn9YtImOGf4V1MVhf1ZYoF mP7GOBDXAbAJhrb5fPKumLsuRLgmA+5VyFhBMmzgqwRjdec1Tu7mWHoQ EukoZp4y2Mmw4NuAs1pBJQOZzLxhYUk+vbjK9mZm5u+mTtt/EFUu8QfG bp8=
+SECTION ADDITIONAL
+a.ns.nic.cz. 172800 IN A 194.0.12.1
+ENTRY_END
+
+RANGE_END
+
+;a.ns.nic.cz.
+RANGE_BEGIN 0 100
+ ADDRESS 194.0.12.1
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+cz. IN DNSKEY
+SECTION ANSWER
+cz. 18000 IN DNSKEY 256 3 10 AwEAAdORJsCVmI4NZRmgtDDRoULmnP6JsA/wR68Z5gO8XD/awSiqsKEB 6BXNC2jvBiPFA94oXroeLXxCjLN+GS/fE1zCKklKfdY5wOHNIlfekWOO 4rbgJtmDzL3IuTbGmNSSIZ0TJkk5NVzpo+Zon9peX2nPdacytQ36hHup GlJMKTxH
+cz. 18000 IN DNSKEY 257 3 10 AwEAAay0hi4HN2r/BqMQTpIPIVDyjmyF+9ZWvr5Lewx+q+947o/GrRv4 FGFfkZxf9CFfYVUf0jG5Yq4i06pGVNwJl81HS9Ux2oeHRXUvgtLnl5He RVLL+zgI5byx9HSNr4bPO8ZEn5OjoayhkNyGSFr4VWrzQk/K02vLP4d1 cCEzUQy30eyZto2/tG5ZwCU/iRkS1PJOcOW98hiFIfFDZv1XjbEpqEYh T2PATs6rt+BKwSHKGISmg1PNdg+y0rItemYMWr1f9BGAdtTWoPCPCYPj OZMPoIyA4tMscD+ww54Jf/QNoHccY4hO1yHiuAXG7SUn8jo0IKQ9W7JJ xES0aqFCX/0=
+cz. 18000 IN RRSIG DNSKEY 10 1 18000 20150917000000 20150903000000 54576 cz. Ei0P45gSw4Vp4u4/H74vm58ehU5JlB4SGLnXXw1U6qVq8EwYrRHv3gV6 9RrUt2GgCqfUlvlJr1Q4WYAJkkiW5zhXJAzCzamtHGuxo3lZuqV1oyw2 zzL4khvmzT0wMxm13TaeSqjbrAEth/00oHIJPqDzrhYlJX74V1q49mD/ 2VoMIVctnTOyE4A+swlyMLOBD8mmjXr47+a5VuwE3bkzBKn1rdHiePl5 MJQjT9Es+qcyMEFZb31/ZOa6MWci1+P28bKFG6mKLVyyiK8sDCkqw/l3 1CTlxRyFdxQc6cBc5KrZwsfApNi5bXXuaJvuOW/YSRbI72HGUNtbbN2v ttsiBw==
+cz. 18000 IN RRSIG DNSKEY 10 1 18000 20150922144030 20150910120939 45182 cz. CajFqhmkoOnO9S1HG/o5TTz2nk8fuaKYSZw6aW7vBcVsUAu3PB2fBCpj zRA2JNtX9ebwXPP4WQR+DPgh+hkOneSUK0hNkp5CguUUr+kiJy8a2IXm 3mmvt7yldkq3Xr3Ygqk9yGW5Sd7NiXT4jOXSMmBueNJFnPf9WThEPpqV zc4=
+ENTRY_END
+
+; a.ns.nic.cz.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+nic.cz. IN MX
+SECTION ANSWER
+nic.cz. 1800 IN MX 20 mx.nic.cz.
+nic.cz. 1800 IN MX 30 bh.nic.cz.
+nic.cz. 1800 IN MX 10 mail.nic.cz.
+nic.cz. 1800 IN RRSIG MX 5 2 1800 20150917230532 20150904125503 46296 nic.cz. qzyjltVcO33Jisn5RVxSAy8D8QHv71hpKgX9D4TBKe/Yrr7aI7rB6tLQ JCLJlYdq7m0w2N+QZCczV67OK3ZTDPErl/N0IKbxK84EVp5/NqgzKivl h95Z1T1jRf9iGdauDMjz8QTFpnOs62/CuOuEJwAIXeIuH2eT25AoBRDe sXM=
+SECTION AUTHORITY
+nic.cz. 1800 IN NS b.ns.nic.cz.
+nic.cz. 1800 IN NS a.ns.nic.cz.
+nic.cz. 1800 IN NS d.ns.nic.cz.
+nic.cz. 1800 IN RRSIG NS 5 2 1800 20150917134944 20150904125503 46296 nic.cz. gPCmMHvHl+76p6ERWuKS9tH/xwD5Or0ZON866yRy1hM0YCzOO0lIsSU9 fxHTKlx3gx0pgz4EGH3Doi54lT9XRZDyp/XiZ6j4+q+583cFJ05ISQHM Sp4QTMqAYCN1XchH2li+YWCgZqUqK1C+D+OO4Zbfu3YVTEaox82+OkCg 0Uo=
+SECTION ADDITIONAL
+a.ns.nic.cz. 18000 IN A 194.0.12.1
+b.ns.nic.cz. 18000 IN A 194.0.12.1
+d.ns.nic.cz. 18000 IN A 194.0.12.1
+ENTRY_END
+
+; a.ns.nic.cz.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+nic.cz. IN DS
+SECTION ANSWER
+nic.cz. 18000 IN DS 59916 5 1 144130216E45C4EC2BB8595E817916E8B060D87B
+nic.cz. 18000 IN RRSIG DS 10 2 18000 20150918193553 20150905063845 45182 cz. leMkrTPUUrO6CmBU9pTMTT2f+0V4DV8P/uY8ZyDa0YHSUZVoFzW4cXZy xzZfgE0y/Q6eJYOeqPOPOoFKs4g8JhdcmFwOrf6Pnmfk5eOhgJVtg5nX xW+j1G3n24a2H4u6ITEzheTcYj00/l8tfPPzS+JW+2yyPALxmQqx4pKP N6I=
+ENTRY_END
+
+;a.ns.nic.cz.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+nic.cz. IN DNSKEY
+SECTION ANSWER
+nic.cz. 1800 IN DNSKEY 257 3 5 BQEAAAABt3LenoCVTV0okqKYPDnnVJqvwCD9MKJNXg8fcOCdLQYncyoe hpwM5RK2UkZDcDxWkMo7yMa35ej+Mhpaji9si4xXD+Syl4Q06LFiFkdN /5GlVlrIdE3GW7zC7Z4sS14Vz8FbYfcRmhsh19Ob718jGZneGfw2UPbv kyxUR8wD7mguZn02fQ6tjj/Ktp4uSW9tpz3bjGMo2rX+iZk4xgbPaesA OlR/AaHdatGZsWC9CPon8mnLZeu6czm8CBDgBmnf3PE8c5+uyWj1Pw4p p0VQmnX5UrnuGpErg7qXhJm7wY2CRVRMcLX3zmjVWXW1uT9JFh2G+/pZ zxnASfKKltZpuw==
+nic.cz. 1800 IN DNSKEY 256 3 5 AwEAAcrwqogrgLUrCRzhbXoMEBPy/55Zeg+yyOYodLGT9ts9UhGYRSgI BJQq6aX/6QOf042niK809bglBRid56ioSV7BlMQeuJx9+87AEiqEupS1 Zg5CzLHx/JLGloCWeCT5bwL4hAmT8gCu8xjHvLFqQjr4QX71Et4MfrJG rOgGpcRJ
+nic.cz. 1800 IN RRSIG DNSKEY 5 2 1800 20150918013842 20150904125503 46296 nic.cz. J92bm8JmPiF3JVyqlmXpBMgVkiIxLfZq+M1fpRMTiemSrC/S5Fj8RHXU 4qVy/wbToegcd6ivqxKNa4IjIrjQ7L5FSfBjcVkBxarWgXp70k7UEc23 K1ZvLHGwa6efmb/RILjdi2YptQzA52f43mwF5qHfWFkEWVXVgNbqm+Zu arY=
+nic.cz. 1800 IN RRSIG DNSKEY 5 2 1800 20150918082556 20150904125503 59916 nic.cz. Zc5XVLTa41lxbOhRkL+PsY3HIpBe43yTrvr9qKRMMuZeyhWsN8YDzUho Otsq3ujf6HyRhJVZrh9Y0Eh2yrvvi+lVSc1ez1kMaqmB+MZxx+d7/f3E 150jW4nGm6T09pyLcKR0sOPV2dRcdgLeeI29wA1S99jr+FWc4AWmQ8/c jjWOW+78EFlDhSu76gUEHi+R/VYhhzW97R4kqaKzqITLhG4luql2s/5E MuHX3MAbFFq6bq5RqS4rxuqxj59VvUSGSWhsxS0HGDrJIsYsrqvRFcg/ yWiEIhTPr/RvmDkNf57p+wWEbI9GkUDE4K53RSKz2jg+z8kcw/FiO731 yMvdcQ==
+ENTRY_END
+
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+nic.cz. IN DNSKEY
+ENTRY_END
+
+; check if fetching DNSKEY works (tests processing with same server authoritative for both parent and child)
+STEP 2 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA AD NOERROR
+SECTION QUESTION
+nic.cz. IN DNSKEY
+SECTION ANSWER
+nic.cz. 1800 IN DNSKEY 256 3 5 AwEAAcrwqogrgLUrCRzhbXoMEBPy/55Zeg+yyOYodLGT9ts9UhGYRSgI BJQq6aX/6QOf042niK809bglBRid56ioSV7BlMQeuJx9+87AEiqEupS1 Zg5CzLHx/JLGloCWeCT5bwL4hAmT8gCu8xjHvLFqQjr4QX71Et4MfrJG rOgGpcRJ
+nic.cz. 1800 IN DNSKEY 257 3 5 BQEAAAABt3LenoCVTV0okqKYPDnnVJqvwCD9MKJNXg8fcOCdLQYncyoe hpwM5RK2UkZDcDxWkMo7yMa35ej+Mhpaji9si4xXD+Syl4Q06LFiFkdN /5GlVlrIdE3GW7zC7Z4sS14Vz8FbYfcRmhsh19Ob718jGZneGfw2UPbv kyxUR8wD7mguZn02fQ6tjj/Ktp4uSW9tpz3bjGMo2rX+iZk4xgbPaesA OlR/AaHdatGZsWC9CPon8mnLZeu6czm8CBDgBmnf3PE8c5+uyWj1Pw4p p0VQmnX5UrnuGpErg7qXhJm7wY2CRVRMcLX3zmjVWXW1uT9JFh2G+/pZ zxnASfKKltZpuw==
+nic.cz. 1800 IN RRSIG DNSKEY 5 2 1800 20150918013842 20150904125503 46296 nic.cz. J92bm8JmPiF3JVyqlmXpBMgVkiIxLfZq+M1fpRMTiemSrC/S5Fj8RHXU 4qVy/wbToegcd6ivqxKNa4IjIrjQ7L5FSfBjcVkBxarWgXp70k7UEc23 K1ZvLHGwa6efmb/RILjdi2YptQzA52f43mwF5qHfWFkEWVXVgNbqm+Zu arY=
+nic.cz. 1800 IN RRSIG DNSKEY 5 2 1800 20150918082556 20150904125503 59916 nic.cz. Zc5XVLTa41lxbOhRkL+PsY3HIpBe43yTrvr9qKRMMuZeyhWsN8YDzUho Otsq3ujf6HyRhJVZrh9Y0Eh2yrvvi+lVSc1ez1kMaqmB+MZxx+d7/f3E 150jW4nGm6T09pyLcKR0sOPV2dRcdgLeeI29wA1S99jr+FWc4AWmQ8/c jjWOW+78EFlDhSu76gUEHi+R/VYhhzW97R4kqaKzqITLhG4luql2s/5E MuHX3MAbFFq6bq5RqS4rxuqxj59VvUSGSWhsxS0HGDrJIsYsrqvRFcg/ yWiEIhTPr/RvmDkNf57p+wWEbI9GkUDE4K53RSKz2jg+z8kcw/FiO731 yMvdcQ==
+ENTRY_END
+
+STEP 3 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+nic.cz. IN MX
+ENTRY_END
+
+; recursion happens here.
+STEP 4 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA AD NOERROR
+SECTION QUESTION
+nic.cz. IN MX
+SECTION ANSWER
+nic.cz. 1800 IN MX 20 mx.nic.cz.
+nic.cz. 1800 IN MX 30 bh.nic.cz.
+nic.cz. 1800 IN MX 10 mail.nic.cz.
+nic.cz. 1800 IN RRSIG MX 5 2 1800 20150917230532 20150904125503 46296 nic.cz. qzyjltVcO33Jisn5RVxSAy8D8QHv71hpKgX9D4TBKe/Yrr7aI7rB6tLQ JCLJlYdq7m0w2N+QZCczV67OK3ZTDPErl/N0IKbxK84EVp5/NqgzKivl h95Z1T1jRf9iGdauDMjz8QTFpnOs62/CuOuEJwAIXeIuH2eT25AoBRDe sXM=
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/iter_validate_extradata.rpl b/tests/integration/deckard/sets/resolver/iter_validate_extradata.rpl
new file mode 100644
index 0000000..c2fcd9c
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/iter_validate_extradata.rpl
@@ -0,0 +1,214 @@
+do-ip6: no
+
+; config options
+;server:
+ trust-anchor: ". 3600 IN DS 19036 8 2 49AAC11D7B6F6446702E54A1607371607A1A41855200FD2CE1CDDE32F24E8FB5"
+ val-override-timestamp: "1437625000"
+
+;stub-zone:
+; name: "."
+ stub-addr: 198.41.0.4 # a.root-servers.net.
+CONFIG_END
+
+SCENARIO_BEGIN Test basic validation, answer contains an extra A record which must be ignored.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 198.41.0.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. 518400 IN NS a.root-servers.net.
+. 518400 IN NS b.root-servers.net.
+. 518400 IN NS c.root-servers.net.
+. 518400 IN NS d.root-servers.net.
+. 518400 IN NS e.root-servers.net.
+. 518400 IN NS f.root-servers.net.
+. 518400 IN NS g.root-servers.net.
+. 518400 IN NS h.root-servers.net.
+. 518400 IN NS i.root-servers.net.
+. 518400 IN NS j.root-servers.net.
+. 518400 IN NS k.root-servers.net.
+. 518400 IN NS l.root-servers.net.
+. 518400 IN NS m.root-servers.net.
+. 518400 IN RRSIG NS 8 0 518400 20150802050000 20150723040000 1518 . JSoL4/wQXh7vzoY/m98WYbpr2/S66u4RQi/UhkSrR3JmPZaWRRERDFm6 RRrFY6GWt4CP61X9rvshuVT+0OhluXqYpEatoHEDgur+PKf3+dTAmcgQ 4RzsahwhQ42Y9fDgJ2nNVMcN97HEIH+qMv0FWjU9b7wJ2iYlDL1ZoAVu TKE=
+SECTION ADDITIONAL
+a.root-servers.net. 518400 IN A 198.41.0.4
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+. IN DNSKEY
+SECTION ANSWER
+. 172800 IN DNSKEY 256 3 8 AwEAAa67bQck1JjopOOFc+iMISFcp/osWrEst2wbKbuQSUWu77QC9UHL ipiHgWN7JlqVAEjKITZz49hhkLmOpmLK55pTq+RD2kwoyNWk9cvpc+tS nIxT7i93O+3oVeLYjMWrkDAz7K45rObbHDuSBwYZKrcSIUCZnCpNMUtn PFl/04cb
+. 172800 IN DNSKEY 257 3 8 AwEAAagAIKlVZrpC6Ia7gEzahOR+9W29euxhJhVVLOyQbSEW0O8gcCjF FVQUTf6v58fLjwBd0YI0EzrAcQqBGCzh/RStIoO8g0NfnfL2MTJRkxoX bfDaUeVPQuYEhg37NZWAJQ9VnMVDxP/VHL496M/QZxkjf5/Efucp2gaD X6RS6CXpoY68LsvPVjR0ZSwzz1apAzvN9dlzEheX7ICJBBtuA6G3LQpz W5hOA2hzCTMjJPJ8LbqF6dsV6DoBQzgul0sGIcGOYl7OyQdXfZ57relS Qageu+ipAdTTJ25AsRTAoub8ONGcLmqrAmRLKBP1dfwhYB4N7knNnulq QxA+Uk1ihz0=
+. 172800 IN RRSIG DNSKEY 8 0 172800 20150804235959 20150721000000 19036 . n9FwNj80Zik2Rr2zTB4F17ydFpiZfUIv8v/XAz4EbSgRxQgFT+TCz3FW i4O7tW5REXUVNHtULiS7fxKLsHZNDPev8DA20DXAw3eEIDi9pDi01O/e 4GnljpkPnP8d5zA62Dob4cxgmhjjFTvhIjtDsH5Dd4jmyHsgBboy4grZ uJNdsez76gD4Ad6WlosZn5Hj5JwqaxZlRph/6I3va4rkp4c32w5DwaQ7 WSne8ffMHX9r7Dn6EbT3FfvnXFDNPE1P6r+qzTzC0t+M/F4R3H+VOdqg cRJcBG6zGCh9ZErhAeoiJh1WAfpjpzx+TUMzqxZCjSC/XL+l2YMKVHtF 8WNg/w==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+cz. IN NS
+SECTION AUTHORITY
+cz. 172800 IN NS a.ns.nic.cz.
+cz. 86400 IN DS 54576 10 2 397E50C85EDE9CDE33F363A9E66FD1B216D788F8DD438A57A423A386 869C8F06
+cz. 86400 IN RRSIG DS 8 1 86400 20150802050000 20150723040000 1518 . fEz3NpYRzgeBjKrLMpht3KFOQ0t6U2wikIaOt1HcmFvurxtPkZVvqdb0 QBQfvh8DoEXDbvpcikzMIO9XYLzzs10X/m91ybGiWzcTVcU+prVGZJP9 zZrvYAIWrpxoC4deKD+vOoNZXGnLfffi6lmGn7QRZaH0LVKjn33cIaPQ 9EM=
+SECTION ADDITIONAL
+a.ns.nic.cz. 172800 IN A 194.0.12.1
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+cz. IN DS
+SECTION ANSWER
+cz. 86400 IN DS 54576 10 2 397E50C85EDE9CDE33F363A9E66FD1B216D788F8DD438A57A423A386 869C8F06
+cz. 86400 IN RRSIG DS 8 1 86400 20150802050000 20150723040000 1518 . fEz3NpYRzgeBjKrLMpht3KFOQ0t6U2wikIaOt1HcmFvurxtPkZVvqdb0 QBQfvh8DoEXDbvpcikzMIO9XYLzzs10X/m91ybGiWzcTVcU+prVGZJP9 zZrvYAIWrpxoC4deKD+vOoNZXGnLfffi6lmGn7QRZaH0LVKjn33cIaPQ 9EM=
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+cz. IN RRSIG
+SECTION AUTHORITY
+cz. 172800 IN NS a.ns.nic.cz.
+cz. 86400 IN DS 54576 10 2 397E50C85EDE9CDE33F363A9E66FD1B216D788F8DD438A57A423A386 869C8F06
+cz. 86400 IN RRSIG DS 8 1 86400 20150802050000 20150723040000 1518 . fEz3NpYRzgeBjKrLMpht3KFOQ0t6U2wikIaOt1HcmFvurxtPkZVvqdb0 QBQfvh8DoEXDbvpcikzMIO9XYLzzs10X/m91ybGiWzcTVcU+prVGZJP9 zZrvYAIWrpxoC4deKD+vOoNZXGnLfffi6lmGn7QRZaH0LVKjn33cIaPQ 9EM=
+SECTION ADDITIONAL
+a.ns.nic.cz. 172800 IN A 194.0.12.1
+ENTRY_END
+
+RANGE_END
+
+;a.ns.nic.cz.
+RANGE_BEGIN 0 100
+ ADDRESS 194.0.12.1
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+cz. IN DNSKEY
+SECTION ANSWER
+cz. 18000 IN DNSKEY 256 3 10 AwEAAbwKeyKB5fuLe16/N5MR6OoG/PO8uxEob7HoIjK0w0wNjwINYb2w edLtzhVlA4HJ0AUUBuZiNj41hlJ474SOBlsAA7BQdtbL1V0Ksk8IC5Z8 3ldU9Mp+ynkj9p9Cl2UOBmoVFYfkbwz0BsOptcXruYA52Ayc9rHrmDPI /0Y8gZAL
+cz. 18000 IN DNSKEY 257 3 10 AwEAAay0hi4HN2r/BqMQTpIPIVDyjmyF+9ZWvr5Lewx+q+947o/GrRv4 FGFfkZxf9CFfYVUf0jG5Yq4i06pGVNwJl81HS9Ux2oeHRXUvgtLnl5He RVLL+zgI5byx9HSNr4bPO8ZEn5OjoayhkNyGSFr4VWrzQk/K02vLP4d1 cCEzUQy30eyZto2/tG5ZwCU/iRkS1PJOcOW98hiFIfFDZv1XjbEpqEYh T2PATs6rt+BKwSHKGISmg1PNdg+y0rItemYMWr1f9BGAdtTWoPCPCYPj OZMPoIyA4tMscD+ww54Jf/QNoHccY4hO1yHiuAXG7SUn8jo0IKQ9W7JJ xES0aqFCX/0=
+cz. 18000 IN RRSIG DNSKEY 10 1 18000 20150802000000 20150719000000 54576 cz. K04ONpLX3wseqHhUu2QLBY7wzSUszVlut5mC6jpCAqbfhgIvGMnyoWP5 lKwSvCLmjie0j1HSv8Q4OmoYGz8L+P/FGAzK4LhMturHrDtHkpuGvQJ6 //UsHQhf4iwCg5tEeHI4ZvaMmqRZI3FhBnSh0OyFjGO73FRbBU9nDrOM sPB1iCUfRfZhQU0sB/rj82ykBUma280sO1aRp3gmQHc/SVNbFfCL1Z8D htBP6sy4Jh0z3Z40d4CFZ8ZCBsIloHO44/GvXGePtr2dW4gJsoU1619B Jz+6cuTRh5RJBiweUNb/nwjBP8fNRkzH1CbjomC2FpDMnBXw7jE1GUiY vLW9Gg==
+cz. 18000 IN RRSIG DNSKEY 10 1 18000 20150805131929 20150723140842 39788 cz. KhyRPt4TYVYH7VAsfn39tY66+5P8bgZhG83d33oogLuqQEPgsxt/tu0c snrUA11Ub+4wOK3MslD5/gTyBuDtT9dk4FbRr3WeUZ4DNn5laYO3AcYx SAU3Vn3dZ8orWFxEwTKNhH5QthPdHj8p8097KRHiPo/DGEnFpYdocEws WJ4=
+ENTRY_END
+
+; a.ns.nic.cz.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+cz. IN NS
+SECTION ANSWER
+cz. 18000 IN NS a.ns.nic.cz.
+cz. 18000 IN NS b.ns.nic.cz.
+cz. 18000 IN NS c.ns.nic.cz.
+cz. 18000 IN NS d.ns.nic.cz.
+cz. 18000 IN RRSIG NS 10 1 18000 20150802132511 20150721120844 39788 cz. pf5UzinUesHzGQTav/1NxGW0AifCmzLW3S8X9tWDRwx7XSKGac7QVXgp nMNyb/NiSho9oj+ZTaQpBZQaTri+brHT4W/nE0TofqZlyYiaABb9xgxJ LgjLkt+OVcJsM3a+q+QEGSt+skNlZVDQeR+sztbuORiZXAqhxumxD8iy zZ8=
+SECTION AUTHORITY
+extra-a. 3600 IN A 1.2.3.4
+extra-ns. 3600 IN NS target-extra-ns.
+SECTION ADDITIONAL
+a.ns.nic.cz. 18000 IN A 194.0.12.1
+b.ns.nic.cz. 18000 IN A 194.0.12.1
+c.ns.nic.cz. 18000 IN A 194.0.12.1
+d.ns.nic.cz. 18000 IN A 194.0.12.1
+ENTRY_END
+
+; a.ns.nic.cz.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+cz. IN RRSIG
+SECTION ANSWER
+; It's okay to lie here as the resolver can't check if we have provided every RRSIG, because there is no RRSIG of RRSIGs
+cz. 18000 IN RRSIG SOA 10 1 18000 20151221212655 20151208120941 37310 cz. ZsKG0TImVm+nAuWvn+Kg61WIet0E++Bt1mxIIywCxtZs/JQlhbjzFPvA ICdYLoqZ06JTwit1nD9xx6jdrfguSVB55G3LGuQiXz4JwEdCWhoVcC3Y Aq6jG1Eor3dhAF8dSIYkE21J3A6oC3O1rDYymKiXpkekFMaaBE0JEvUJ ut8=
+ENTRY_END
+
+RANGE_END
+
+;STEP 0 TIME_PASSES ELAPSE 1000
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+cz. IN RRSIG
+ENTRY_END
+
+; check that it answers a query for RRSIG (unauthenticated)
+; digests are swapped, i.e. signatures are invalid, server shouldn't use them later
+STEP 2 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+cz. IN RRSIG
+SECTION ANSWER
+cz. 18000 IN RRSIG SOA 10 1 18000 20151221212655 20151208120941 37310 cz. ZsKG0TImVm+nAuWvn+Kg61WIet0E++Bt1mxIIywCxtZs/JQlhbjzFPvA ICdYLoqZ06JTwit1nD9xx6jdrfguSVB55G3LGuQiXz4JwEdCWhoVcC3Y Aq6jG1Eor3dhAF8dSIYkE21J3A6oC3O1rDYymKiXpkekFMaaBE0JEvUJ ut8=
+ENTRY_END
+
+STEP 3 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+cz. IN NS
+ENTRY_END
+
+; check that it answers a plain query
+STEP 4 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+cz. IN NS
+SECTION ANSWER
+cz. 18000 IN NS a.ns.nic.cz.
+cz. 18000 IN NS b.ns.nic.cz.
+cz. 18000 IN NS c.ns.nic.cz.
+cz. 18000 IN NS d.ns.nic.cz.
+ENTRY_END
+
+STEP 5 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+cz. IN NS
+ENTRY_END
+
+; recursion happens here.
+STEP 6 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA AD NOERROR
+SECTION QUESTION
+cz. IN NS
+SECTION ANSWER
+cz. 18000 IN NS a.ns.nic.cz.
+cz. 18000 IN NS b.ns.nic.cz.
+cz. 18000 IN NS c.ns.nic.cz.
+cz. 18000 IN NS d.ns.nic.cz.
+cz. 18000 IN RRSIG NS 10 1 18000 20150802132511 20150721120844 39788 cz. pf5UzinUesHzGQTav/1NxGW0AifCmzLW3S8X9tWDRwx7XSKGac7QVXgp nMNyb/NiSho9oj+ZTaQpBZQaTri+brHT4W/nE0TofqZlyYiaABb9xgxJ LgjLkt+OVcJsM3a+q+QEGSt+skNlZVDQeR+sztbuORiZXAqhxumxD8iy zZ8=
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/iter_validate_nsec_nxdomain.rpl b/tests/integration/deckard/sets/resolver/iter_validate_nsec_nxdomain.rpl
new file mode 100644
index 0000000..3e8fc8c
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/iter_validate_nsec_nxdomain.rpl
@@ -0,0 +1,154 @@
+do-ip6: no
+
+; config options
+;server:
+ trust-anchor: ". 3600 IN DS 19036 8 2 49AAC11D7B6F6446702E54A1607371607A1A41855200FD2CE1CDDE32F24E8FB5"
+ val-override-timestamp: "1438783903"
+ query-minimization: off
+
+;stub-zone:
+; name: "."
+ stub-addr: 198.41.0.4 # a.root-servers.net.
+CONFIG_END
+
+SCENARIO_BEGIN Test basic validation of MX xxx.nic.cz.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 198.41.0.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. 518400 IN NS a.root-servers.net.
+. 518400 IN NS b.root-servers.net.
+. 518400 IN NS c.root-servers.net.
+. 518400 IN NS d.root-servers.net.
+. 518400 IN NS e.root-servers.net.
+. 518400 IN NS f.root-servers.net.
+. 518400 IN NS g.root-servers.net.
+. 518400 IN NS h.root-servers.net.
+. 518400 IN NS i.root-servers.net.
+. 518400 IN NS j.root-servers.net.
+. 518400 IN NS k.root-servers.net.
+. 518400 IN NS l.root-servers.net.
+. 518400 IN NS m.root-servers.net.
+. 518400 IN RRSIG NS 8 0 518400 20150809050000 20150730040000 1518 . ntWgyA7SjlVedxDStbRA6fXl0Hq5pyBgVtBb6l+LbqgLs8/2mwPhzaEw A/BMM+wr7KQLvNSyxTl/SZny94uMVu7o2fnI6+bCP5C+lo7PWni/GvMU yj3JSq2hPv3iO/D1ch8yaKddtYL/NCwPBn9CgpW0jWIWp8FvwwCR4RAs GzA=
+SECTION ADDITIONAL
+a.root-servers.net. 518400 IN A 198.41.0.4
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+. IN DNSKEY
+SECTION ANSWER
+. 172800 IN DNSKEY 256 3 8 AwEAAa67bQck1JjopOOFc+iMISFcp/osWrEst2wbKbuQSUWu77QC9UHL ipiHgWN7JlqVAEjKITZz49hhkLmOpmLK55pTq+RD2kwoyNWk9cvpc+tS nIxT7i93O+3oVeLYjMWrkDAz7K45rObbHDuSBwYZKrcSIUCZnCpNMUtn PFl/04cb
+. 172800 IN DNSKEY 257 3 8 AwEAAagAIKlVZrpC6Ia7gEzahOR+9W29euxhJhVVLOyQbSEW0O8gcCjF FVQUTf6v58fLjwBd0YI0EzrAcQqBGCzh/RStIoO8g0NfnfL2MTJRkxoX bfDaUeVPQuYEhg37NZWAJQ9VnMVDxP/VHL496M/QZxkjf5/Efucp2gaD X6RS6CXpoY68LsvPVjR0ZSwzz1apAzvN9dlzEheX7ICJBBtuA6G3LQpz W5hOA2hzCTMjJPJ8LbqF6dsV6DoBQzgul0sGIcGOYl7OyQdXfZ57relS Qageu+ipAdTTJ25AsRTAoub8ONGcLmqrAmRLKBP1dfwhYB4N7knNnulq QxA+Uk1ihz0=
+. 172800 IN RRSIG DNSKEY 8 0 172800 20150814235959 20150731000000 19036 . GW5z3/PgUahqXvFy4UKqc+gxl6b1T4MwHP6E08PUd1KSyFAy/7cltOP6 dfavtYwP9HWIadti7w0GkK560vWEe0aneJCqn9VvSWLI7wrrTLTDd03v WRFk0qxEaVZ22MxqA2AxHMEnEgbLJ9oTJL8eUZDRetKeCgk3w8zypq4f 3xnh0QO7p5F8mBUlAcrCy8B20ZqItvq9irdeeWOSvvJWs35XnPY497xz WVLrF4hOLQnhmgxJpIDwNRGlkqmbNAmVIICOkrG9S9mvZdhhQqogzHhn k6T7Ws1ZQ2FTYBLc5/QA3urEAn8H6TCm5D+wURcfy5x++hXBOIxipkyh 4yfsgw==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+missing.nic.cz. IN MX
+SECTION AUTHORITY
+cz. 172800 IN NS a.ns.nic.cz.
+cz. 86400 IN DS 54576 10 2 397E50C85EDE9CDE33F363A9E66FD1B216D788F8DD438A57A423A386 869C8F06
+cz. 86400 IN RRSIG DS 8 1 86400 20150815050000 20150805040000 1518 . jeryA8jj+yf2X9exz5Ka/Nfifr+k5++Se1klItsut3Jvy1d0X6TI5pjr ABzXbhOUGz6M4cUKhLjM3XDTRspu/VT4DhJUE2pRITKBzeAabDN6dkO/ KHbB/Klrc5DjSeq3RNA3zj39U/TxT+gO8F/fzn6FQKIGkcxwSzSD4Xov K5Q=
+SECTION ADDITIONAL
+a.ns.nic.cz. 172800 IN A 194.0.12.1
+ENTRY_END
+RANGE_END
+
+;a.ns.nic.cz.
+RANGE_BEGIN 0 100
+ ADDRESS 194.0.12.1
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+cz. IN DNSKEY
+SECTION ANSWER
+cz. 18000 IN DNSKEY 256 3 10 AwEAAbwKeyKB5fuLe16/N5MR6OoG/PO8uxEob7HoIjK0w0wNjwINYb2w edLtzhVlA4HJ0AUUBuZiNj41hlJ474SOBlsAA7BQdtbL1V0Ksk8IC5Z8 3ldU9Mp+ynkj9p9Cl2UOBmoVFYfkbwz0BsOptcXruYA52Ayc9rHrmDPI /0Y8gZAL
+cz. 18000 IN DNSKEY 257 3 10 AwEAAay0hi4HN2r/BqMQTpIPIVDyjmyF+9ZWvr5Lewx+q+947o/GrRv4 FGFfkZxf9CFfYVUf0jG5Yq4i06pGVNwJl81HS9Ux2oeHRXUvgtLnl5He RVLL+zgI5byx9HSNr4bPO8ZEn5OjoayhkNyGSFr4VWrzQk/K02vLP4d1 cCEzUQy30eyZto2/tG5ZwCU/iRkS1PJOcOW98hiFIfFDZv1XjbEpqEYh T2PATs6rt+BKwSHKGISmg1PNdg+y0rItemYMWr1f9BGAdtTWoPCPCYPj OZMPoIyA4tMscD+ww54Jf/QNoHccY4hO1yHiuAXG7SUn8jo0IKQ9W7JJ xES0aqFCX/0=
+cz. 18000 IN RRSIG DNSKEY 10 1 18000 20150814000000 20150731000000 54576 cz. T/q1zripqILs8CdStXtf/GRpDhgbduHC6AEoGfnK+lfxk9okn6amwhho j464OUtH1wGlS9pikWQ02O6BX5CRaaaZjgMeIJugj3w4MZMPbSk1tV5y JaRXaec/uZI5h91iJtQzNAP5rbMj5liIYQV02nrN8+5SVBwxnrJ9JvQ/ tOetsoP2eh1wlgb+Tu+GgrYVrO/4EwOUk+5RUuMVKofGvY+vyYaEuRip rr6pSjH+dhjKegMv2IQ9rBEI1MKWcFA3+6ZqaMazNShgeEJgBI3GKPog AFiZFijDl5Pd5+4/HftGYpXnUlon266ilvCCS1RzE3pynnHPFFRVBmd6 Q38sIQ==
+cz. 18000 IN RRSIG DNSKEY 10 1 18000 20150818181624 20150805140846 39788 cz. dmYD4pzcswSWyVEqEaCKXN1a58uP2b7/fscNn24wAhQ891sTZi3kNhS8 BvoYIncoAppi+Kkw9vRfXNB26YhBgalCDBxHdwg1vxMD/uHiTrQ1KFFM ZjeM+CYTmULK6PY06NN8IyauL87gcx8k2/r9GVr71yUC1nNjNum4ZRZD EiQ=
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NXDOMAIN
+SECTION QUESTION
+missing.nic.cz. IN MX
+SECTION AUTHORITY
+nic.cz. 1800 IN SOA a.ns.nic.cz. hostmaster.nic.cz. 1438786503 10800 3600 1209600 7200
+nic.cz. 1800 IN RRSIG SOA 5 2 1800 20150819080542 20150805135503 24582 nic.cz. TDX7klpEuTI2vUQdmNzacxND0p828AD1HNxzTop0MJqKTehn8XgPoSK0 ZRWITLIMTtmC9UFLh/nb9I06HqUVdirxCKWvSzO840wjoVF7SjLWZysB 3VhPn84NA/9m8N8dmpTIt2IpN2N/T0lZVIIg/SSeru/dPNKH1uNtKekv 1eg=
+nic.cz. 7200 IN NSEC 6to4.nic.cz. A NS SOA MX AAAA RRSIG NSEC DNSKEY
+nic.cz. 7200 IN RRSIG NSEC 5 2 7200 20150818164706 20150805135503 24582 nic.cz. dqZiT0kHOtrap/aNq/M4u6KCGAS+f1yrAa6aDVBnqIopJ4DJJjnh67WF LedeHae5JLDNwuZV8SlkicIwW5K2ET4//2bJ6FCJcw89s40s3h/QnVxB +wV6hNhqfVnOjtHO4TWK96uNhf/B+A4N/voSpA21zYBMTV8mFvynj7oy ozk=
+*.mirrors.nic.cz. 7200 IN NSEC akuma.mnt.nic.cz. CNAME RRSIG NSEC
+*.mirrors.nic.cz. 7200 IN RRSIG NSEC 5 3 7200 20150819054509 20150805135503 24582 nic.cz. BDT/Rw1F7/QJd76/KWL0jdkdHkzWNxxZ2Hdgba6o1okc0mgqz2ag1P3s BkYtzWMwql4U7Au/KcLtq6P8X2/T9xytqmYfpn2O1dCaBzHubeTiz/aP wcPaYEC+jPR7JwmHpZlxs+KirS4yo7aVF1OPP7ZjtuqDeNLvmF4W7mHl r/A=
+ENTRY_END
+
+; a.ns.nic.cz.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+nic.cz. IN DS
+SECTION ANSWER
+nic.cz. 18000 IN DS 59916 5 1 144130216E45C4EC2BB8595E817916E8B060D87B
+nic.cz. 18000 IN RRSIG DS 10 2 18000 20150817213510 20150804233901 39788 cz. sxyJEb5Aqpk65VNqxI6bIbyB2UweVjAMf4YvyMJh6MAOGeii8tRbHoJN CntFpaW8sDrw1dgv/xQMFB04Yl3B518n1vMHspweuT3GX5MVV8dEED+9 MdDC0LvhrcPhcoY7ZEz4koywHN39J51tzeSiAPIyQPpMv/b1E3YLwPou lOQ=
+ENTRY_END
+
+;a.ns.nic.cz.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+nic.cz. IN DNSKEY
+SECTION ANSWER
+nic.cz. 1800 IN DNSKEY 256 3 5 AwEAAatglK6e9CpmATmEDtjQfOMqSEGB2KT3xciP+ZuBH3qYQDggHxao Hk9cfL5uXHxEr8AqmiTNA2CJ9oVm2wlZFCTUtQS2Vxz+i30XQpIPoh1y 0fU/XHKmrVmdVGzc9OdgDyZT+8CbUInAyUin+tWM9M7ekUXAllUw5bd8 VC4SJO3z
+nic.cz. 1800 IN DNSKEY 257 3 5 BQEAAAABt3LenoCVTV0okqKYPDnnVJqvwCD9MKJNXg8fcOCdLQYncyoe hpwM5RK2UkZDcDxWkMo7yMa35ej+Mhpaji9si4xXD+Syl4Q06LFiFkdN /5GlVlrIdE3GW7zC7Z4sS14Vz8FbYfcRmhsh19Ob718jGZneGfw2UPbv kyxUR8wD7mguZn02fQ6tjj/Ktp4uSW9tpz3bjGMo2rX+iZk4xgbPaesA OlR/AaHdatGZsWC9CPon8mnLZeu6czm8CBDgBmnf3PE8c5+uyWj1Pw4p p0VQmnX5UrnuGpErg7qXhJm7wY2CRVRMcLX3zmjVWXW1uT9JFh2G+/pZ zxnASfKKltZpuw==
+nic.cz. 1800 IN RRSIG DNSKEY 5 2 1800 20150818153605 20150805135503 59916 nic.cz. iDP/U4c8zJF085/V/CAlRU4Hs1RugPkzJdaYVCXwnpZ5vjArAY5wzUtx 88626FvBgVD/hnCUrSoN8eNz8ISSsyk3Ql3bTp5Cmxi+hgIqWd1Q3H3u RY3TlsMM0rpsVBalz3f77pia8s7e3kFsjee2z7iadj/ILSfzYQTghSaO 0B6pDaWoUhhwbGWR1Fz0YdhaiYO21Tvxa5/DD3R3fsTWZQ773GENhNhE 1LM6L82770F+VGfbIhG/wBqiRM1FXiikPixvbmgRco2dff/3w/ns2WXI yFjlr7WwaHlrlyIhgI30CYDs3Xe3jI+sxwNG64XqnwVgBIaN7GVbUulb 9RFxkg==
+nic.cz. 1800 IN RRSIG DNSKEY 5 2 1800 20150818221347 20150805135503 24582 nic.cz. nrW0y70a7urskICTXafO/39Dd+sWU9gY/xQeeMLHuOTyJc5xPeKfPY61 6xUrfZveYy/dj3quDP+RB5hZCxK2gBDjRDBoDfJayaWmGoPJ4ima42KF wpyR8MMbcnha2Z+hP82Q/pVs7DsC3rJFg9Q5VHP5qzyQcRONYXWBjnM7 y54=
+ENTRY_END
+RANGE_END
+
+;STEP 0 TIME_PASSES ELAPSE 1000
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+missing.nic.cz. IN MX
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA AD NXDOMAIN
+SECTION QUESTION
+missing.nic.cz. IN MX
+SECTION AUTHORITY
+nic.cz. 1800 IN SOA a.ns.nic.cz. hostmaster.nic.cz. 1438786503 10800 3600 1209600 7200
+nic.cz. 1800 IN RRSIG SOA 5 2 1800 20150819080542 20150805135503 24582 nic.cz. TDX7klpEuTI2vUQdmNzacxND0p828AD1HNxzTop0MJqKTehn8XgPoSK0 ZRWITLIMTtmC9UFLh/nb9I06HqUVdirxCKWvSzO840wjoVF7SjLWZysB 3VhPn84NA/9m8N8dmpTIt2IpN2N/T0lZVIIg/SSeru/dPNKH1uNtKekv 1eg=
+nic.cz. 7200 IN NSEC 6to4.nic.cz. A NS SOA MX AAAA RRSIG NSEC DNSKEY
+nic.cz. 7200 IN RRSIG NSEC 5 2 7200 20150818164706 20150805135503 24582 nic.cz. dqZiT0kHOtrap/aNq/M4u6KCGAS+f1yrAa6aDVBnqIopJ4DJJjnh67WF LedeHae5JLDNwuZV8SlkicIwW5K2ET4//2bJ6FCJcw89s40s3h/QnVxB +wV6hNhqfVnOjtHO4TWK96uNhf/B+A4N/voSpA21zYBMTV8mFvynj7oy ozk=
+*.mirrors.nic.cz. 7200 IN NSEC akuma.mnt.nic.cz. CNAME RRSIG NSEC
+*.mirrors.nic.cz. 7200 IN RRSIG NSEC 5 3 7200 20150819054509 20150805135503 24582 nic.cz. BDT/Rw1F7/QJd76/KWL0jdkdHkzWNxxZ2Hdgba6o1okc0mgqz2ag1P3s BkYtzWMwql4U7Au/KcLtq6P8X2/T9xytqmYfpn2O1dCaBzHubeTiz/aP wcPaYEC+jPR7JwmHpZlxs+KirS4yo7aVF1OPP7ZjtuqDeNLvmF4W7mHl r/A=
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/module_dns64.rpl b/tests/integration/deckard/sets/resolver/module_dns64.rpl
new file mode 100644
index 0000000..59718a0
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/module_dns64.rpl
@@ -0,0 +1,206 @@
+do-ip6: no
+
+; config options
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+ features: dns64_prefix = fe80::21b:aabb:0:0
+CONFIG_END
+
+SCENARIO_BEGIN Test dns64 features
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+cz. IN NS
+SECTION AUTHORITY
+cz. IN NS d.ns.nic.cz.
+SECTION ADDITIONAL
+d.ns.nic.cz. IN A 193.29.206.1
+;d.ns.nic.cz. IN AAAA 2001:678:1::1
+ENTRY_END
+RANGE_END
+
+RANGE_BEGIN 0 100
+ ADDRESS 193.29.206.1
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.cz. IN NS
+SECTION AUTHORITY
+example.cz. IN NS ns.example.cz.
+SECTION ADDITIONAL
+ns.example.cz. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.cz. IN A
+SECTION ANSWER
+www.example.cz. IN A 1.2.3.5
+www.example.cz. IN A 1.2.3.6
+SECTION AUTHORITY
+example.cz. IN NS ns.example.cz.
+SECTION ADDITIONAL
+ns.example.cz. IN A 1.2.3.4
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname qtype
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.cz. IN AAAA
+SECTION AUTHORITY
+example.cz. 3600 IN SOA bla. bla. 1 2 3 4 5
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname qtype
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www6.example.cz. IN AAAA
+SECTION ANSWER
+www6.example.cz. 3600 IN AAAA 2001:db8::1
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+cname.example.cz. IN CNAME
+SECTION ANSWER
+cname.example.cz. IN CNAME www.example.cz.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname qtype
+ADJUST copy_id
+REPLY QR REFUSED
+SECTION QUESTION
+fail6.example.cz. IN AAAA
+SECTION ANSWER
+ENTRY_END
+RANGE_END
+
+
+STEP 10 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.cz. IN AAAA
+ENTRY_END
+
+STEP 11 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH flags rcode question answer
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.example.cz. IN AAAA
+SECTION ANSWER
+www.example.cz. IN AAAA fe80::21b:aabb:102:305
+www.example.cz. IN AAAA fe80::21b:aabb:102:306
+ENTRY_END
+
+; Do not synthesize on +CD queries, sec. 5.5.3.
+STEP 12 QUERY
+ENTRY_BEGIN
+REPLY RD DO CD
+SECTION QUESTION
+www.example.cz. IN AAAA
+ENTRY_END
+
+STEP 13 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH flags rcode question answer authority
+REPLY QR RD RA DO CD NOERROR
+SECTION QUESTION
+www.example.cz. IN AAAA
+SECTION ANSWER
+SECTION AUTHORITY
+example.cz. 3600 IN SOA bla. bla. 1 2 3 4 5
+ENTRY_END
+
+; Do not synthesize if AAAA exists.
+STEP 14 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www6.example.cz. IN AAAA
+ENTRY_END
+
+STEP 15 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH flags rcode question answer
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www6.example.cz. IN AAAA
+SECTION ANSWER
+www6.example.cz. 3600 IN AAAA 2001:db8::1
+ENTRY_END
+
+; Generate from simple NODATA behind a CNAME.
+STEP 16 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+cname.example.cz. IN AAAA
+ENTRY_END
+
+STEP 17 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH flags rcode question answer
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+cname.example.cz. IN AAAA
+SECTION ANSWER
+cname.example.cz. IN CNAME www.example.cz.
+www.example.cz. IN AAAA fe80::21b:aabb:102:305
+www.example.cz. IN AAAA fe80::21b:aabb:102:306
+ENTRY_END
+
+; Fail for AAAA won't cause query for A (answer not defined).
+STEP 18 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+fail6.example.cz. IN AAAA
+ENTRY_END
+
+STEP 19 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH flags rcode question answer
+REPLY QR RD RA SERVFAIL
+SECTION QUESTION
+fail6.example.cz. IN AAAA
+SECTION ANSWER
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/module_hint_static.rpl b/tests/integration/deckard/sets/resolver/module_hint_static.rpl
new file mode 100644
index 0000000..a166132
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/module_hint_static.rpl
@@ -0,0 +1,45 @@
+do-ip6: no
+
+; config options
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+ features: static_hint_name = www.nic.cz
+ features: static_hint_addr = 1.2.3.4
+CONFIG_END
+
+SCENARIO_BEGIN Simple static hint test
+
+STEP 10 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.nic.cz. IN A
+ENTRY_END
+
+STEP 20 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.nic.cz. IN A
+SECTION ANSWER
+www.nic.cz. IN A 1.2.3.4
+ENTRY_END
+
+STEP 30 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+4.3.2.1.in-addr.arpa. IN PTR
+ENTRY_END
+
+STEP 40 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+4.3.2.1.in-addr.arpa. IN PTR
+SECTION ANSWER
+4.3.2.1.in-addr.arpa. IN PTR www.nic.cz
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/module_policy_deny_all.rpl b/tests/integration/deckard/sets/resolver/module_policy_deny_all.rpl
new file mode 100644
index 0000000..1d44dae
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/module_policy_deny_all.rpl
@@ -0,0 +1,98 @@
+do-ip6: no
+
+; config options
+ stub-addr: 1.2.3.4
+ trust-anchor: "example.com. IN DS 438 10 2 33F8133EB48EDB093839E985600EB7B7009EB5AC312D11CCA9007F6B 71D94D7B"
+ feature-list: policy=policy:add(policy.all(policy.DENY))
+CONFIG_END
+
+SCENARIO_BEGIN DENY policy test, uses policy.all
+
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+dummy.example.cz. IN A
+SECTION ANSWER
+dummy.example.cz. IN A 5.6.7.8
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+dummy.nic.cz. IN A
+SECTION ANSWER
+dummy.nic.cz. IN A 9.10.11.12
+ENTRY_END
+RANGE_END
+
+STEP 10 QUERY
+ENTRY_BEGIN
+REPLY RD AD DO
+SECTION QUESTION
+example.cz. IN A
+ENTRY_END
+
+STEP 20 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH flags rcode question answer
+REPLY QR RD RA AA NXDOMAIN
+SECTION QUESTION
+example.cz. IN A
+SECTION ANSWER
+ENTRY_END
+
+STEP 30 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+dummy.example.cz. IN A
+ENTRY_END
+
+STEP 40 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH flags rcode question answer
+REPLY QR RD RA AA NXDOMAIN
+SECTION QUESTION
+dummy.example.cz. IN A
+SECTION ANSWER
+ENTRY_END
+
+STEP 50 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+nic.cz. IN A
+ENTRY_END
+
+STEP 60 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH flags rcode question answer
+REPLY QR RD RA AA NXDOMAIN
+SECTION QUESTION
+nic.cz. IN A
+SECTION ANSWER
+ENTRY_END
+
+STEP 70 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+dummy.nic.cz. IN A
+ENTRY_END
+
+STEP 80 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH flags rcode question answer
+REPLY QR RD RA AA NXDOMAIN
+SECTION QUESTION
+dummy.nic.cz. IN A
+SECTION ANSWER
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/module_policy_deny_suff_comm.rpl b/tests/integration/deckard/sets/resolver/module_policy_deny_suff_comm.rpl
new file mode 100644
index 0000000..8cfbb33
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/module_policy_deny_suff_comm.rpl
@@ -0,0 +1,150 @@
+do-ip6: no
+
+; config options
+ stub-addr: 1.2.3.4
+ trust-anchor: "example.com. IN DS 438 10 2 33F8133EB48EDB093839E985600EB7B7009EB5AC312D11CCA9007F6B 71D94D7B"
+ feature-list: policy=policy:add(policy.suffix_common(policy.DENY, policy.todnames({'example.cz', 'nic.cz'}), todname('cz')))
+ query-minimization: off
+CONFIG_END
+
+SCENARIO_BEGIN DENY policy test, uses policy.common_suffix and policy.todnames
+
+RANGE_BEGIN 0 110
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+example.cz. IN A
+SECTION ANSWER
+example.cz. IN A 5.6.7.8
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+dummy.example.cz. IN A
+SECTION ANSWER
+dummy.example.cz. IN A 9.10.11.12
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+nic.cz. IN A
+SECTION ANSWER
+nic.cz. IN A 13.14.15.16
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+dummy.nic.cz. IN A
+SECTION ANSWER
+dummy.nic.cz. IN A 17.18.19.20
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+example.com. IN A
+SECTION ANSWER
+example.com. IN A 21.22.23.24
+ENTRY_END
+RANGE_END
+
+; blocked by policy, must return NXDOMAIN
+STEP 10 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+example.cz. IN A
+ENTRY_END
+
+STEP 20 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH flags rcode question answer
+REPLY QR RD RA AA NXDOMAIN
+SECTION QUESTION
+example.cz. IN A
+SECTION ANSWER
+ENTRY_END
+
+; blocked by policy, must return NXDOMAIN
+STEP 30 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+dummy.example.cz. IN A
+ENTRY_END
+
+STEP 40 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH flags rcode question answer
+REPLY QR RD RA AA NXDOMAIN
+SECTION QUESTION
+dummy.example.cz. IN A
+SECTION ANSWER
+ENTRY_END
+
+; blocked by policy, must return NXDOMAIN
+STEP 50 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+nic.cz. IN A
+ENTRY_END
+
+STEP 60 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH flags rcode question answer
+REPLY QR RD RA AA NXDOMAIN
+SECTION QUESTION
+nic.cz. IN A
+SECTION ANSWER
+ENTRY_END
+
+; blocked by policy, must return NXDOMAIN
+STEP 70 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+dummy.nic.cz. IN A
+ENTRY_END
+
+STEP 80 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH flags rcode question answer
+REPLY QR RD RA AA NXDOMAIN
+SECTION QUESTION
+dummy.nic.cz. IN A
+SECTION ANSWER
+ENTRY_END
+
+; does not match the policy, so script must retun valid answer
+STEP 90 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+example.com. IN A
+ENTRY_END
+
+STEP 100 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH flags rcode question answer
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+example.com. IN A
+SECTION ANSWER
+example.com. IN A 21.22.23.24
+ENTRY_END
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/module_policy_deny_suff_patt.rpl b/tests/integration/deckard/sets/resolver/module_policy_deny_suff_patt.rpl
new file mode 100644
index 0000000..0197fc2
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/module_policy_deny_suff_patt.rpl
@@ -0,0 +1,150 @@
+do-ip6: no
+
+; config options
+ stub-addr: 1.2.3.4
+ feature-list: policy=policy:add(policy.suffix(policy.DENY, {todname('nic.cz')}))
+ feature-list: policy=policy:add(policy.pattern(policy.DENY, '\8example[0-8]\2cz'))
+ query-minimization: off
+CONFIG_END
+
+SCENARIO_BEGIN DENY policy test; uses policy.suffix, policy.pattern, todname
+
+RANGE_BEGIN 0 110
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+nic.cz. IN A
+SECTION ANSWER
+nic.cz. IN A 5.6.7.8
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+dummy.nic.cz. IN A
+SECTION ANSWER
+dummy.nic.cz. IN A 9.10.11.12
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+example0.cz. IN A
+SECTION ANSWER
+example0.cz. IN A 13.14.15.16
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+dummy.example0.cz. IN A
+SECTION ANSWER
+dummy.example0.cz. IN A 17.18.19.20
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+example9.cz. IN A
+SECTION ANSWER
+example9.cz. IN A 21.22.23.24
+ENTRY_END
+RANGE_END
+
+; denied by policy.suffix(policy.DENY, {todname('nic.cz')})
+STEP 10 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+nic.cz. IN A
+ENTRY_END
+
+STEP 20 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH flags rcode question answer
+REPLY QR RD RA AA NXDOMAIN
+SECTION QUESTION
+nic.cz. IN A
+SECTION ANSWER
+ENTRY_END
+
+; denied by policy.suffix(policy.DENY, {todname('nic.cz')})
+STEP 30 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+dummy.nic.cz. IN A
+ENTRY_END
+
+STEP 40 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH flags rcode question answer
+REPLY QR RD RA AA NXDOMAIN
+SECTION QUESTION
+dummy.nic.cz. IN A
+SECTION ANSWER
+ENTRY_END
+
+; denied by policy.pattern(policy.DENY, todname('example[0-8].cz')
+STEP 50 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+example0.cz. IN A
+ENTRY_END
+
+STEP 60 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH flags rcode question answer
+REPLY QR RD RA AA NXDOMAIN
+SECTION QUESTION
+example0.cz. IN A
+SECTION ANSWER
+ENTRY_END
+
+; denied by policy.pattern(policy.DENY, todname('example[0-8].cz')
+STEP 70 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+dummy.example0.cz. IN A
+ENTRY_END
+
+STEP 80 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH flags rcode question answer
+REPLY QR RD RA AA NXDOMAIN
+SECTION QUESTION
+dummy.example0.cz. IN A
+SECTION ANSWER
+ENTRY_END
+
+; does not match any policy; allowed
+STEP 90 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+example9.cz. IN A
+ENTRY_END
+
+STEP 100 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH flags rcode question answer
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+example9.cz. IN A
+SECTION ANSWER
+example9.cz. IN A 21.22.23.24
+ENTRY_END
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/module_policy_drop.rpl b/tests/integration/deckard/sets/resolver/module_policy_drop.rpl
new file mode 100644
index 0000000..5e30582
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/module_policy_drop.rpl
@@ -0,0 +1,26 @@
+do-ip6: no
+
+; config options
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+ feature-list: policy=policy:add(policy.suffix(policy.DROP, {todname('example.cz')}))
+CONFIG_END
+
+SCENARIO_BEGIN Simple policy test
+
+STEP 10 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.cz. IN A
+ENTRY_END
+
+STEP 20 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA SERVFAIL
+SECTION QUESTION
+www.example.cz. IN A
+SECTION ANSWER
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/module_policy_forward.rpl b/tests/integration/deckard/sets/resolver/module_policy_forward.rpl
new file mode 100644
index 0000000..a5fbdd3
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/module_policy_forward.rpl
@@ -0,0 +1,40 @@
+do-ip6: no
+
+; config options
+ stub-addr: 1.2.3.4
+ feature-list: policy=policy:add(policy.suffix(policy.FORWARD('1.2.3.4'), {todname('example.cz')}))
+CONFIG_END
+
+SCENARIO_BEGIN Simple policy test
+
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.example.cz. IN A
+SECTION ANSWER
+www.example.cz. IN A 5.6.7.8
+ENTRY_END
+RANGE_END
+
+STEP 10 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.cz. IN A
+ENTRY_END
+
+STEP 20 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.example.cz. IN A
+SECTION ANSWER
+www.example.cz. IN A 5.6.7.8
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/module_policy_pass_deny.rpl b/tests/integration/deckard/sets/resolver/module_policy_pass_deny.rpl
new file mode 100644
index 0000000..fb8cb69
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/module_policy_pass_deny.rpl
@@ -0,0 +1,69 @@
+do-ip6: no
+
+; config options
+ stub-addr: 1.2.3.4
+ feature-list: policy=policy:add(policy.pattern(policy.PASS, todname('dummy.example.cz')))
+ feature-list: policy=policy:add(policy.suffix(policy.DENY, {todname('example.cz')}))
+ query-minimization: off
+CONFIG_END
+
+SCENARIO_BEGIN PASS, DENY policy test; uses policy.pattern and policy.suffix
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+fake.example.cz. IN A
+SECTION ANSWER
+fake.example.cz. IN A 5.6.7.8
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+dummy.example.cz. IN A
+SECTION ANSWER
+dummy.example.cz. IN A 9.10.11.12
+ENTRY_END
+
+RANGE_END
+
+STEP 10 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+fake.example.cz. IN A
+ENTRY_END
+
+STEP 20 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH flags rcode question answer
+REPLY QR RD RA AA NXDOMAIN
+SECTION QUESTION
+fake.example.cz. IN A
+SECTION ANSWER
+ENTRY_END
+
+STEP 30 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+dummy.example.cz. IN A
+ENTRY_END
+
+STEP 40 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH flags rcode question answer
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+dummy.example.cz. IN A
+SECTION ANSWER
+dummy.example.cz. IN A 9.10.11.12
+ENTRY_END
+
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/module_policy_tc.rpl b/tests/integration/deckard/sets/resolver/module_policy_tc.rpl
new file mode 100644
index 0000000..17f7619
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/module_policy_tc.rpl
@@ -0,0 +1,26 @@
+do-ip6: no
+
+; config options
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+ feature-list: policy=policy:add(policy.suffix(policy.TC, {todname('example.cz')}))
+CONFIG_END
+
+SCENARIO_BEGIN Simple policy test
+
+STEP 10 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.cz. IN A
+ENTRY_END
+
+STEP 20 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR TC RD RA
+SECTION QUESTION
+www.example.cz. IN A
+SECTION ANSWER
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/module_renumber.rpl b/tests/integration/deckard/sets/resolver/module_renumber.rpl
new file mode 100644
index 0000000..94b2920
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/module_renumber.rpl
@@ -0,0 +1,88 @@
+do-ip6: no
+
+; config options
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+ features: renumber_src = 1.2.3.0/24; renumber_dst = 4.5.6.0
+ query-minimization: off
+CONFIG_END
+
+SCENARIO_BEGIN Simple renumber module test
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+cz. IN NS
+SECTION AUTHORITY
+cz. IN NS d.ns.nic.cz.
+SECTION ADDITIONAL
+d.ns.nic.cz. IN A 193.29.206.1
+ENTRY_END
+RANGE_END
+
+RANGE_BEGIN 0 100
+ ADDRESS 193.29.206.1
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.cz. IN NS
+SECTION AUTHORITY
+example.cz. IN NS ns.example.cz.
+SECTION ADDITIONAL
+ns.example.cz. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.cz. IN A
+SECTION ANSWER
+www.example.cz. IN A 1.2.3.5
+SECTION AUTHORITY
+example.cz. IN NS ns.example.cz.
+SECTION ADDITIONAL
+ns.example.cz. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.cz. IN A
+ENTRY_END
+
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.example.cz. IN A
+SECTION ANSWER
+www.example.cz. IN A 4.5.6.5
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/module_workarounds_disable_0x20.rpl b/tests/integration/deckard/sets/resolver/module_workarounds_disable_0x20.rpl
new file mode 100644
index 0000000..bf6ad7f
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/module_workarounds_disable_0x20.rpl
@@ -0,0 +1,83 @@
+do-ip6: no
+
+; config options
+ features: workarounds = true
+ stub-addr: 1.1.1.1
+CONFIG_END
+
+SCENARIO_BEGIN Test module workarounds disabling 0x20 for certain domains
+RANGE_BEGIN 0 100
+ ADDRESS 1.1.1.1
+ENTRY_BEGIN
+MATCH opcode qtype qcase ; case sensitive comparison
+ADJUST copy_id copy_query
+REPLY QR RD NOERROR
+SECTION QUESTION
+b-0.19-23003008.1481.1518.19cf.3ea1.410.0.ekzijnekvvvg7gb38qcwur561b.avqs.mcafee.com. IN A ; all lowercase
+SECTION ANSWER
+b-0.19-23003008.1481.1518.19cf.3ea1.410.0.ekzijnekvvvg7gb38qcwur561b.avqs.mcafee.com. IN A 2.2.2.2
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname qtype
+ADJUST copy_id
+REPLY QR RD NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS k.root-servers.net.
+SECTION ADDITIONAL
+k.root-servers.net. IN A 1.1.1.1
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR RD NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION AUTHORITY
+com. IN NS k.root-servers.net.
+SECTION ADDITIONAL
+k.root-servers.net. IN A 1.1.1.1
+ENTRY_END
+RANGE_END
+
+STEP 10 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+b-0.19-23003008.1481.1518.19cf.3ea1.410.0.ekzijnekvvvg7gb38qcwur561b.avqs.mcafee.com. IN A ; all lowercase: tests that 0x20 won't be used
+ENTRY_END
+
+STEP 11 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+b-0.19-23003008.1481.1518.19cf.3ea1.410.0.ekzijnekvvvg7gb38qcwur561b.avqs.mcafee.com. IN A
+SECTION ANSWER
+b-0.19-23003008.1481.1518.19cf.3ea1.410.0.ekzijnekvvvg7gb38qcwur561b.avqs.mcafee.com. IN A 2.2.2.2
+ENTRY_END
+
+; expire cached results
+STEP 22 TIME_PASSES ELAPSE 4000
+
+STEP 30 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+b-0.19-23003008.1481.1518.19cf.3ea1.410.0.ekzijnekvvvg7gb38qcwur561b.avqs.mcafee.COM. IN A ; upper case in the TLD: tests making the name lowercase before sending the query
+ENTRY_END
+
+STEP 31 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+b-0.19-23003008.1481.1518.19cf.3ea1.410.0.ekzijnekvvvg7gb38qcwur561b.avqs.mcafee.com. IN A
+SECTION ANSWER
+b-0.19-23003008.1481.1518.19cf.3ea1.410.0.ekzijnekvvvg7gb38qcwur561b.avqs.mcafee.com. IN A 2.2.2.2
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/nsec3_aggr_cache.rpl b/tests/integration/deckard/sets/resolver/nsec3_aggr_cache.rpl
new file mode 100644
index 0000000..b1c3edb
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/nsec3_aggr_cache.rpl
@@ -0,0 +1,5281 @@
+do-ip4: no
+ trust-anchor: ". IN DS 19036 8 2 49AAC11D7B6F6446702E54A1607371607A1A41855200FD2CE1CDDE32F24E8FB5"
+ trust-anchor: ". IN DS 20326 8 2 E06D44B80B8F1D39A95C0B0D7C65D08458E880409BBC683457104237C7F8EC8D"
+ val-override-date: 20180727104904
+ stub-addr: 2001:7fe::53
+CONFIG_END
+
+SCENARIO_BEGIN qlist
+
+; Scope ".
+
+; Server names:
+; f.root-servers.net.
+; a.root-servers.net.
+; j.root-servers.net.
+; e.root-servers.net.
+; i.root-servers.net.
+; d.root-servers.net.
+; m.root-servers.net.
+; h.root-servers.net.
+; c.root-servers.net.
+; l.root-servers.net.
+; g.root-servers.net.
+; b.root-servers.net.
+; k.root-servers.net.
+RANGE_BEGIN 0 1000
+ ADDRESS 192.36.148.17
+ ADDRESS 2001:7fe::53
+ ADDRESS 198.97.190.53
+ ADDRESS 2001:500:1::53
+ ADDRESS 2001:503:ba3e::2:30
+ ADDRESS 2001:503:c27::2:30
+ ADDRESS 2001:500:a8::e
+ ADDRESS 2001:7fd::1
+ ADDRESS 192.112.36.4
+ ADDRESS 2001:500:12::d0d
+ ADDRESS 199.7.91.13
+ ADDRESS 2001:500:2::c
+ ADDRESS 198.41.0.4
+ ADDRESS 2001:500:2d::d
+ ADDRESS 202.12.27.33
+ ADDRESS 2001:500:9f::42
+ ADDRESS 2001:dc3::35
+ ADDRESS 192.5.5.241
+ ADDRESS 192.33.4.12
+ ADDRESS 2001:500:2f::f
+ ADDRESS 199.7.83.42
+ ADDRESS 192.58.128.30
+ ADDRESS 192.203.230.10
+ ADDRESS 2001:500:200::b
+ ADDRESS 199.9.14.201
+ ADDRESS 193.0.14.129
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. 518400 IN NS a.root-servers.net.
+. 518400 IN NS b.root-servers.net.
+. 518400 IN NS c.root-servers.net.
+. 518400 IN NS d.root-servers.net.
+. 518400 IN NS e.root-servers.net.
+. 518400 IN NS f.root-servers.net.
+. 518400 IN NS g.root-servers.net.
+. 518400 IN NS h.root-servers.net.
+. 518400 IN NS i.root-servers.net.
+. 518400 IN NS j.root-servers.net.
+. 518400 IN NS k.root-servers.net.
+. 518400 IN NS l.root-servers.net.
+. 518400 IN NS m.root-servers.net.
+. 518400 IN RRSIG NS 8 0 518400 20180809050000 20180727040000 41656 . iPYXlPdWqSGLIBjkBHYPCkA7LpjtEq2l 3IxdgesYUMxKFrYsdxgySnyBHQ9YzAQc bl3fCtLvlx6msHw/cCqMRHhCCjDnqTa/ NqBRtr1hr8ZbPrb3pZf+1hjX+9eohhHQ OiyAiP1hVaEIBIiSt7W8aPYvjZRogQAy YPApw3dwsfTFWzTnd+EDZsuZeMz0k74x BEJmC/tzTjnzvNK8fU95Mv+pKLm09Hda eXP2i+zrAwguTZBUt30dnsrYA7dxkQcP s+SdFhfPlGYS2EWOoJsik3DGRHQpTHI5 N9sjytXS7IqWetnaNJyFL0KSpG1YdEyB JvYqCrUI6YLDopcgUSRjrA==
+SECTION ADDITIONAL
+a.root-servers.net. 3600000 IN A 198.41.0.4
+a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30
+b.root-servers.net. 3600000 IN A 199.9.14.201
+b.root-servers.net. 3600000 IN AAAA 2001:500:200::b
+c.root-servers.net. 3600000 IN A 192.33.4.12
+c.root-servers.net. 3600000 IN AAAA 2001:500:2::c
+d.root-servers.net. 3600000 IN A 199.7.91.13
+d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d
+e.root-servers.net. 3600000 IN A 192.203.230.10
+e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e
+f.root-servers.net. 3600000 IN A 192.5.5.241
+f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f
+g.root-servers.net. 3600000 IN A 192.112.36.4
+g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d
+h.root-servers.net. 3600000 IN A 198.97.190.53
+h.root-servers.net. 3600000 IN AAAA 2001:500:1::53
+i.root-servers.net. 3600000 IN A 192.36.148.17
+i.root-servers.net. 3600000 IN AAAA 2001:7fe::53
+j.root-servers.net. 3600000 IN A 192.58.128.30
+j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+l.root-servers.net. 3600000 IN A 199.7.83.42
+l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42
+m.root-servers.net. 3600000 IN A 202.12.27.33
+m.root-servers.net. 3600000 IN AAAA 2001:dc3::35
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+. IN DNSKEY
+SECTION ANSWER
+. 172800 IN DNSKEY 256 3 8 AwEAAfaifSqh+9ItxYRCwuiY0FY2NkaE wd/zmyVvakixDgTOkgG/PUzlEauAiKzl xGwezjqbKFPSwrY3qHmbbsSTY6G8hZtn a8k26eCwy59Chh573cu8qtBkmUIXMYG3 fSdlUReP+uhBWBfKI2aGwhRmQYR0zSmg 7PGOde34c/rOItK1ebJhjTAJ6TmnON7q Mfk/lKvH4qOvYtzstLhr7Pn9ZOVLx/WU KQpU/nEyFyTduRbz1nZqkp6yMuHwWVsA BK8lUYXSaUrDAsuMSldhafmR/A15BxNh v9M7mzJj7UH2RVME9JbYinBEzWwW9Gpn Y+ZmBWgZiRVTaDuemCTJ5ZJWLRs=
+. 172800 IN DNSKEY 257 3 8 AwEAAagAIKlVZrpC6Ia7gEzahOR+9W29 euxhJhVVLOyQbSEW0O8gcCjFFVQUTf6v 58fLjwBd0YI0EzrAcQqBGCzh/RStIoO8 g0NfnfL2MTJRkxoXbfDaUeVPQuYEhg37 NZWAJQ9VnMVDxP/VHL496M/QZxkjf5/E fucp2gaDX6RS6CXpoY68LsvPVjR0ZSwz z1apAzvN9dlzEheX7ICJBBtuA6G3LQpz W5hOA2hzCTMjJPJ8LbqF6dsV6DoBQzgu l0sGIcGOYl7OyQdXfZ57relSQageu+ip AdTTJ25AsRTAoub8ONGcLmqrAmRLKBP1 dfwhYB4N7knNnulqQxA+Uk1ihz0=
+. 172800 IN DNSKEY 257 3 8 AwEAAaz/tAm8yTn4Mfeh5eyI96WSVexT BAvkMgJzkKTOiW1vkIbzxeF3+/4RgWOq 7HrxRixHlFlExOLAJr5emLvN7SWXgnLh 4+B5xQlNVz8Og8kvArMtNROxVQuCaSnI DdD5LKyWbRd2n9WGe2R8PzgCmr3EgVLr jyBxWezF0jLHwVN8efS3rCj/EWgvIWgb 9tarpVUDK/b58Da+sqqls3eNbuv7pr+e oZG+SrDK6nWeL3c6H5Apxz7LjVc1uTId sIXxuOLYA4/ilBmSVIzuDWfdRUfhHdY6 +cn8HFRm+2hM8AnXGXws9555KrUB5qih ylGa8subX2Nn6UwNR1AkUTV74bU=
+. 172800 IN RRSIG DNSKEY 8 0 172800 20180811000000 20180721000000 19036 . U2thj3DQzTGRF8m2ZytqANs9YF9PYb1B QC5bDHi+d7apJve5u3Ik1cCeYg9AlW2v 2vstMSUtTR0eI2mzBeZ8aBHLwPylyDhS jbe6lwxnaoZhncO4oM9bJTUha1ovCXPO oZm5dKhfI6FradAaitRfMaC7s/+XZ/Dh nlLQNe08F0qepkG52RsUJZEyiQkkOK5a /hNkV5gyKdMecjtJ7eiR1w68vWwP6iGp ohuLDlapbEniJXHhEysUtRJbE3EFYgwG EGeKwEQC3tDCb8ABYnbrkMg/OqhGP1cX aYfZwhEIUOvsplTdXU1tsVbPjGtbVBjy 4aKLY+pjsvWuT2dzMac18A==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR RD NOERROR
+SECTION QUESTION
+cz. IN NULL
+SECTION AUTHORITY
+cz. 172800 IN NS a.ns.nic.cz.
+cz. 172800 IN NS b.ns.nic.cz.
+cz. 172800 IN NS c.ns.nic.cz.
+cz. 172800 IN NS d.ns.nic.cz.
+cz. 86400 IN DS 20237 13 2 cff0f3ecdbc529c1f0031ba1840bfb835853b9209ed1e508fff48451d7b778e2
+cz. 86400 IN RRSIG DS 8 1 86400 20180809050000 20180727040000 41656 . BkGaXhVOBlSGZkRo6m6xYxeXSEIqVZKa 7wHxKdNn+6F/DDJoD0aEgEg6H7yhjKs2 tt4uyp9l8/L8r/mWoFPjYsSsQgc2hpxJ Ql2wTDRNaRpQ+spbiefndoyr1/5YBMFv mItzzMSg93ekx3gebfVqMpe0fpvs7NjA +33vGJO3e3ficaYDIf9HY/npnHgjOtpE wiFPYmLTb+zLlIHd4hhXOXg/Kv5CNGvN aBdBE2s2GXJbYI3Zd5FDHxhZ+qLuhL5J qjtrGDokRgM0Jk8dDroIk0yQHfNU022s ZAhIeEZJhwiuh4bNuJJCKoB+a5UIiNx+ rCUU2ntIsqLbxbnpKLamow==
+SECTION ADDITIONAL
+a.ns.nic.cz. 172800 IN A 194.0.12.1
+a.ns.nic.cz. 172800 IN AAAA 2001:678:f::1
+b.ns.nic.cz. 172800 IN A 194.0.13.1
+b.ns.nic.cz. 172800 IN AAAA 2001:678:10::1
+c.ns.nic.cz. 172800 IN A 194.0.14.1
+c.ns.nic.cz. 172800 IN AAAA 2001:678:11::1
+d.ns.nic.cz. 172800 IN A 193.29.206.1
+d.ns.nic.cz. 172800 IN AAAA 2001:678:1::1
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR RD NOERROR
+SECTION QUESTION
+cz. IN DNSKEY
+SECTION AUTHORITY
+cz. 172800 IN NS a.ns.nic.cz.
+cz. 172800 IN NS b.ns.nic.cz.
+cz. 172800 IN NS c.ns.nic.cz.
+cz. 172800 IN NS d.ns.nic.cz.
+cz. 86400 IN DS 20237 13 2 cff0f3ecdbc529c1f0031ba1840bfb835853b9209ed1e508fff48451d7b778e2
+cz. 86400 IN RRSIG DS 8 1 86400 20180809050000 20180727040000 41656 . BkGaXhVOBlSGZkRo6m6xYxeXSEIqVZKa 7wHxKdNn+6F/DDJoD0aEgEg6H7yhjKs2 tt4uyp9l8/L8r/mWoFPjYsSsQgc2hpxJ Ql2wTDRNaRpQ+spbiefndoyr1/5YBMFv mItzzMSg93ekx3gebfVqMpe0fpvs7NjA +33vGJO3e3ficaYDIf9HY/npnHgjOtpE wiFPYmLTb+zLlIHd4hhXOXg/Kv5CNGvN aBdBE2s2GXJbYI3Zd5FDHxhZ+qLuhL5J qjtrGDokRgM0Jk8dDroIk0yQHfNU022s ZAhIeEZJhwiuh4bNuJJCKoB+a5UIiNx+ rCUU2ntIsqLbxbnpKLamow==
+SECTION ADDITIONAL
+a.ns.nic.cz. 172800 IN A 194.0.12.1
+a.ns.nic.cz. 172800 IN AAAA 2001:678:f::1
+b.ns.nic.cz. 172800 IN A 194.0.13.1
+b.ns.nic.cz. 172800 IN AAAA 2001:678:10::1
+c.ns.nic.cz. 172800 IN A 194.0.14.1
+c.ns.nic.cz. 172800 IN AAAA 2001:678:11::1
+d.ns.nic.cz. 172800 IN A 193.29.206.1
+d.ns.nic.cz. 172800 IN AAAA 2001:678:1::1
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+cz. IN DS
+SECTION ANSWER
+cz. 86400 IN DS 20237 13 2 cff0f3ecdbc529c1f0031ba1840bfb835853b9209ed1e508fff48451d7b778e2
+cz. 86400 IN RRSIG DS 8 1 86400 20180809050000 20180727040000 41656 . BkGaXhVOBlSGZkRo6m6xYxeXSEIqVZKa 7wHxKdNn+6F/DDJoD0aEgEg6H7yhjKs2 tt4uyp9l8/L8r/mWoFPjYsSsQgc2hpxJ Ql2wTDRNaRpQ+spbiefndoyr1/5YBMFv mItzzMSg93ekx3gebfVqMpe0fpvs7NjA +33vGJO3e3ficaYDIf9HY/npnHgjOtpE wiFPYmLTb+zLlIHd4hhXOXg/Kv5CNGvN aBdBE2s2GXJbYI3Zd5FDHxhZ+qLuhL5J qjtrGDokRgM0Jk8dDroIk0yQHfNU022s ZAhIeEZJhwiuh4bNuJJCKoB+a5UIiNx+ rCUU2ntIsqLbxbnpKLamow==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR RD NOERROR
+SECTION QUESTION
+cz. IN A
+SECTION AUTHORITY
+cz. 172800 IN NS a.ns.nic.cz.
+cz. 172800 IN NS b.ns.nic.cz.
+cz. 172800 IN NS c.ns.nic.cz.
+cz. 172800 IN NS d.ns.nic.cz.
+cz. 86400 IN DS 20237 13 2 cff0f3ecdbc529c1f0031ba1840bfb835853b9209ed1e508fff48451d7b778e2
+cz. 86400 IN RRSIG DS 8 1 86400 20180809050000 20180727040000 41656 . BkGaXhVOBlSGZkRo6m6xYxeXSEIqVZKa 7wHxKdNn+6F/DDJoD0aEgEg6H7yhjKs2 tt4uyp9l8/L8r/mWoFPjYsSsQgc2hpxJ Ql2wTDRNaRpQ+spbiefndoyr1/5YBMFv mItzzMSg93ekx3gebfVqMpe0fpvs7NjA +33vGJO3e3ficaYDIf9HY/npnHgjOtpE wiFPYmLTb+zLlIHd4hhXOXg/Kv5CNGvN aBdBE2s2GXJbYI3Zd5FDHxhZ+qLuhL5J qjtrGDokRgM0Jk8dDroIk0yQHfNU022s ZAhIeEZJhwiuh4bNuJJCKoB+a5UIiNx+ rCUU2ntIsqLbxbnpKLamow==
+SECTION ADDITIONAL
+a.ns.nic.cz. 172800 IN A 194.0.12.1
+a.ns.nic.cz. 172800 IN AAAA 2001:678:f::1
+b.ns.nic.cz. 172800 IN A 194.0.13.1
+b.ns.nic.cz. 172800 IN AAAA 2001:678:10::1
+c.ns.nic.cz. 172800 IN A 194.0.14.1
+c.ns.nic.cz. 172800 IN AAAA 2001:678:11::1
+d.ns.nic.cz. 172800 IN A 193.29.206.1
+d.ns.nic.cz. 172800 IN AAAA 2001:678:1::1
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR RD NOERROR
+SECTION QUESTION
+net. IN A
+SECTION AUTHORITY
+net. 172800 IN NS a.gtld-servers.net.
+net. 172800 IN NS b.gtld-servers.net.
+net. 172800 IN NS c.gtld-servers.net.
+net. 172800 IN NS d.gtld-servers.net.
+net. 172800 IN NS e.gtld-servers.net.
+net. 172800 IN NS f.gtld-servers.net.
+net. 172800 IN NS g.gtld-servers.net.
+net. 172800 IN NS h.gtld-servers.net.
+net. 172800 IN NS i.gtld-servers.net.
+net. 172800 IN NS j.gtld-servers.net.
+net. 172800 IN NS k.gtld-servers.net.
+net. 172800 IN NS l.gtld-servers.net.
+net. 172800 IN NS m.gtld-servers.net.
+net. 86400 IN DS 35886 8 2 7862b27f5f516ebe19680444d4ce5e762981931842c465f00236401d8bd973ee
+net. 86400 IN RRSIG DS 8 1 86400 20180809050000 20180727040000 41656 . 0Uvgipa8bRqTwVpcmpPngKx1brdQ0rIB H8QbEl4KyFE+CI8nB3jNk9rHF15WYQm1 Xov0E1uCMvYfv1w96LvC+N4w7hPsCpgG sK3+pT90vhsLRqoP7dws5MU0fsXfpmGP X3utMPZGwk7JDSUhQAbIWiCD81JAi05y I5xbaeveUSSvMbyXJKyzsbHWVP6997BX 4Las1O8H/1Eds743+Cfc5hPULqH5ZUWB EPIKN+MZQM9DjmgUUJSlktWQwK42BeXU 9O4DUGP2oxwbQ8uw4PlRhhxYp3UCP9b5 B2d4fqlaalhiPY86u7TkzEbEJJlW2tf+ 3bGAiX9a9icfbsrdS9hsuw==
+SECTION ADDITIONAL
+a.gtld-servers.net. 172800 IN A 192.5.6.30
+a.gtld-servers.net. 172800 IN AAAA 2001:503:a83e::2:30
+b.gtld-servers.net. 172800 IN A 192.33.14.30
+b.gtld-servers.net. 172800 IN AAAA 2001:503:231d::2:30
+c.gtld-servers.net. 172800 IN A 192.26.92.30
+c.gtld-servers.net. 172800 IN AAAA 2001:503:83eb::30
+d.gtld-servers.net. 172800 IN A 192.31.80.30
+d.gtld-servers.net. 172800 IN AAAA 2001:500:856e::30
+e.gtld-servers.net. 172800 IN A 192.12.94.30
+e.gtld-servers.net. 172800 IN AAAA 2001:502:1ca1::30
+f.gtld-servers.net. 172800 IN A 192.35.51.30
+f.gtld-servers.net. 172800 IN AAAA 2001:503:d414::30
+g.gtld-servers.net. 172800 IN A 192.42.93.30
+g.gtld-servers.net. 172800 IN AAAA 2001:503:eea3::30
+h.gtld-servers.net. 172800 IN A 192.54.112.30
+h.gtld-servers.net. 172800 IN AAAA 2001:502:8cc::30
+i.gtld-servers.net. 172800 IN A 192.43.172.30
+i.gtld-servers.net. 172800 IN AAAA 2001:503:39c1::30
+j.gtld-servers.net. 172800 IN A 192.48.79.30
+j.gtld-servers.net. 172800 IN AAAA 2001:502:7094::30
+k.gtld-servers.net. 172800 IN A 192.52.178.30
+k.gtld-servers.net. 172800 IN AAAA 2001:503:d2d::30
+l.gtld-servers.net. 172800 IN A 192.41.162.30
+l.gtld-servers.net. 172800 IN AAAA 2001:500:d937::30
+m.gtld-servers.net. 172800 IN A 192.55.83.30
+m.gtld-servers.net. 172800 IN AAAA 2001:501:b1f9::30
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR RD NOERROR
+SECTION QUESTION
+net. IN DNSKEY
+SECTION AUTHORITY
+net. 172800 IN NS a.gtld-servers.net.
+net. 172800 IN NS b.gtld-servers.net.
+net. 172800 IN NS c.gtld-servers.net.
+net. 172800 IN NS d.gtld-servers.net.
+net. 172800 IN NS e.gtld-servers.net.
+net. 172800 IN NS f.gtld-servers.net.
+net. 172800 IN NS g.gtld-servers.net.
+net. 172800 IN NS h.gtld-servers.net.
+net. 172800 IN NS i.gtld-servers.net.
+net. 172800 IN NS j.gtld-servers.net.
+net. 172800 IN NS k.gtld-servers.net.
+net. 172800 IN NS l.gtld-servers.net.
+net. 172800 IN NS m.gtld-servers.net.
+net. 86400 IN DS 35886 8 2 7862b27f5f516ebe19680444d4ce5e762981931842c465f00236401d8bd973ee
+net. 86400 IN RRSIG DS 8 1 86400 20180809050000 20180727040000 41656 . 0Uvgipa8bRqTwVpcmpPngKx1brdQ0rIB H8QbEl4KyFE+CI8nB3jNk9rHF15WYQm1 Xov0E1uCMvYfv1w96LvC+N4w7hPsCpgG sK3+pT90vhsLRqoP7dws5MU0fsXfpmGP X3utMPZGwk7JDSUhQAbIWiCD81JAi05y I5xbaeveUSSvMbyXJKyzsbHWVP6997BX 4Las1O8H/1Eds743+Cfc5hPULqH5ZUWB EPIKN+MZQM9DjmgUUJSlktWQwK42BeXU 9O4DUGP2oxwbQ8uw4PlRhhxYp3UCP9b5 B2d4fqlaalhiPY86u7TkzEbEJJlW2tf+ 3bGAiX9a9icfbsrdS9hsuw==
+SECTION ADDITIONAL
+a.gtld-servers.net. 172800 IN A 192.5.6.30
+a.gtld-servers.net. 172800 IN AAAA 2001:503:a83e::2:30
+b.gtld-servers.net. 172800 IN A 192.33.14.30
+b.gtld-servers.net. 172800 IN AAAA 2001:503:231d::2:30
+c.gtld-servers.net. 172800 IN A 192.26.92.30
+c.gtld-servers.net. 172800 IN AAAA 2001:503:83eb::30
+d.gtld-servers.net. 172800 IN A 192.31.80.30
+d.gtld-servers.net. 172800 IN AAAA 2001:500:856e::30
+e.gtld-servers.net. 172800 IN A 192.12.94.30
+e.gtld-servers.net. 172800 IN AAAA 2001:502:1ca1::30
+f.gtld-servers.net. 172800 IN A 192.35.51.30
+f.gtld-servers.net. 172800 IN AAAA 2001:503:d414::30
+g.gtld-servers.net. 172800 IN A 192.42.93.30
+g.gtld-servers.net. 172800 IN AAAA 2001:503:eea3::30
+h.gtld-servers.net. 172800 IN A 192.54.112.30
+h.gtld-servers.net. 172800 IN AAAA 2001:502:8cc::30
+i.gtld-servers.net. 172800 IN A 192.43.172.30
+i.gtld-servers.net. 172800 IN AAAA 2001:503:39c1::30
+j.gtld-servers.net. 172800 IN A 192.48.79.30
+j.gtld-servers.net. 172800 IN AAAA 2001:502:7094::30
+k.gtld-servers.net. 172800 IN A 192.52.178.30
+k.gtld-servers.net. 172800 IN AAAA 2001:503:d2d::30
+l.gtld-servers.net. 172800 IN A 192.41.162.30
+l.gtld-servers.net. 172800 IN AAAA 2001:500:d937::30
+m.gtld-servers.net. 172800 IN A 192.55.83.30
+m.gtld-servers.net. 172800 IN AAAA 2001:501:b1f9::30
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+net. IN DS
+SECTION ANSWER
+net. 86400 IN DS 35886 8 2 7862b27f5f516ebe19680444d4ce5e762981931842c465f00236401d8bd973ee
+net. 86400 IN RRSIG DS 8 1 86400 20180809050000 20180727040000 41656 . 0Uvgipa8bRqTwVpcmpPngKx1brdQ0rIB H8QbEl4KyFE+CI8nB3jNk9rHF15WYQm1 Xov0E1uCMvYfv1w96LvC+N4w7hPsCpgG sK3+pT90vhsLRqoP7dws5MU0fsXfpmGP X3utMPZGwk7JDSUhQAbIWiCD81JAi05y I5xbaeveUSSvMbyXJKyzsbHWVP6997BX 4Las1O8H/1Eds743+Cfc5hPULqH5ZUWB EPIKN+MZQM9DjmgUUJSlktWQwK42BeXU 9O4DUGP2oxwbQ8uw4PlRhhxYp3UCP9b5 B2d4fqlaalhiPY86u7TkzEbEJJlW2tf+ 3bGAiX9a9icfbsrdS9hsuw==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+f.root-servers.net. IN A
+SECTION ANSWER
+f.root-servers.net. 3600000 IN A 192.5.5.241
+SECTION AUTHORITY
+root-servers.net. 3600000 IN NS a.root-servers.net.
+root-servers.net. 3600000 IN NS b.root-servers.net.
+root-servers.net. 3600000 IN NS c.root-servers.net.
+root-servers.net. 3600000 IN NS d.root-servers.net.
+root-servers.net. 3600000 IN NS e.root-servers.net.
+root-servers.net. 3600000 IN NS f.root-servers.net.
+root-servers.net. 3600000 IN NS g.root-servers.net.
+root-servers.net. 3600000 IN NS h.root-servers.net.
+root-servers.net. 3600000 IN NS i.root-servers.net.
+root-servers.net. 3600000 IN NS j.root-servers.net.
+root-servers.net. 3600000 IN NS k.root-servers.net.
+root-servers.net. 3600000 IN NS l.root-servers.net.
+root-servers.net. 3600000 IN NS m.root-servers.net.
+SECTION ADDITIONAL
+a.root-servers.net. 3600000 IN A 198.41.0.4
+a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30
+b.root-servers.net. 3600000 IN A 199.9.14.201
+b.root-servers.net. 3600000 IN AAAA 2001:500:200::b
+c.root-servers.net. 3600000 IN A 192.33.4.12
+c.root-servers.net. 3600000 IN AAAA 2001:500:2::c
+d.root-servers.net. 3600000 IN A 199.7.91.13
+d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d
+e.root-servers.net. 3600000 IN A 192.203.230.10
+e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e
+f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f
+g.root-servers.net. 3600000 IN A 192.112.36.4
+g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d
+h.root-servers.net. 3600000 IN A 198.97.190.53
+h.root-servers.net. 3600000 IN AAAA 2001:500:1::53
+i.root-servers.net. 3600000 IN A 192.36.148.17
+i.root-servers.net. 3600000 IN AAAA 2001:7fe::53
+j.root-servers.net. 3600000 IN A 192.58.128.30
+j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+l.root-servers.net. 3600000 IN A 199.7.83.42
+l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42
+m.root-servers.net. 3600000 IN A 202.12.27.33
+m.root-servers.net. 3600000 IN AAAA 2001:dc3::35
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+f.root-servers.net. IN DNSKEY
+SECTION AUTHORITY
+root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018070900 14400 7200 1209600 3600000
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+f.root-servers.net. IN NS
+SECTION AUTHORITY
+root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018070900 14400 7200 1209600 3600000
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+f.root-servers.net. IN DS
+SECTION AUTHORITY
+root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018070900 14400 7200 1209600 3600000
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+f.root-servers.net. IN AAAA
+SECTION ANSWER
+f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f
+SECTION AUTHORITY
+root-servers.net. 3600000 IN NS a.root-servers.net.
+root-servers.net. 3600000 IN NS b.root-servers.net.
+root-servers.net. 3600000 IN NS c.root-servers.net.
+root-servers.net. 3600000 IN NS d.root-servers.net.
+root-servers.net. 3600000 IN NS e.root-servers.net.
+root-servers.net. 3600000 IN NS f.root-servers.net.
+root-servers.net. 3600000 IN NS g.root-servers.net.
+root-servers.net. 3600000 IN NS h.root-servers.net.
+root-servers.net. 3600000 IN NS i.root-servers.net.
+root-servers.net. 3600000 IN NS j.root-servers.net.
+root-servers.net. 3600000 IN NS k.root-servers.net.
+root-servers.net. 3600000 IN NS l.root-servers.net.
+root-servers.net. 3600000 IN NS m.root-servers.net.
+SECTION ADDITIONAL
+a.root-servers.net. 3600000 IN A 198.41.0.4
+a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30
+b.root-servers.net. 3600000 IN A 199.9.14.201
+b.root-servers.net. 3600000 IN AAAA 2001:500:200::b
+c.root-servers.net. 3600000 IN A 192.33.4.12
+c.root-servers.net. 3600000 IN AAAA 2001:500:2::c
+d.root-servers.net. 3600000 IN A 199.7.91.13
+d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d
+e.root-servers.net. 3600000 IN A 192.203.230.10
+e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e
+f.root-servers.net. 3600000 IN A 192.5.5.241
+g.root-servers.net. 3600000 IN A 192.112.36.4
+g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d
+h.root-servers.net. 3600000 IN A 198.97.190.53
+h.root-servers.net. 3600000 IN AAAA 2001:500:1::53
+i.root-servers.net. 3600000 IN A 192.36.148.17
+i.root-servers.net. 3600000 IN AAAA 2001:7fe::53
+j.root-servers.net. 3600000 IN A 192.58.128.30
+j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+l.root-servers.net. 3600000 IN A 199.7.83.42
+l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42
+m.root-servers.net. 3600000 IN A 202.12.27.33
+m.root-servers.net. 3600000 IN AAAA 2001:dc3::35
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+a.root-servers.net. IN A
+SECTION ANSWER
+a.root-servers.net. 3600000 IN A 198.41.0.4
+SECTION AUTHORITY
+root-servers.net. 3600000 IN NS a.root-servers.net.
+root-servers.net. 3600000 IN NS b.root-servers.net.
+root-servers.net. 3600000 IN NS c.root-servers.net.
+root-servers.net. 3600000 IN NS d.root-servers.net.
+root-servers.net. 3600000 IN NS e.root-servers.net.
+root-servers.net. 3600000 IN NS f.root-servers.net.
+root-servers.net. 3600000 IN NS g.root-servers.net.
+root-servers.net. 3600000 IN NS h.root-servers.net.
+root-servers.net. 3600000 IN NS i.root-servers.net.
+root-servers.net. 3600000 IN NS j.root-servers.net.
+root-servers.net. 3600000 IN NS k.root-servers.net.
+root-servers.net. 3600000 IN NS l.root-servers.net.
+root-servers.net. 3600000 IN NS m.root-servers.net.
+SECTION ADDITIONAL
+a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30
+b.root-servers.net. 3600000 IN A 199.9.14.201
+b.root-servers.net. 3600000 IN AAAA 2001:500:200::b
+c.root-servers.net. 3600000 IN A 192.33.4.12
+c.root-servers.net. 3600000 IN AAAA 2001:500:2::c
+d.root-servers.net. 3600000 IN A 199.7.91.13
+d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d
+e.root-servers.net. 3600000 IN A 192.203.230.10
+e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e
+f.root-servers.net. 3600000 IN A 192.5.5.241
+f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f
+g.root-servers.net. 3600000 IN A 192.112.36.4
+g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d
+h.root-servers.net. 3600000 IN A 198.97.190.53
+h.root-servers.net. 3600000 IN AAAA 2001:500:1::53
+i.root-servers.net. 3600000 IN A 192.36.148.17
+i.root-servers.net. 3600000 IN AAAA 2001:7fe::53
+j.root-servers.net. 3600000 IN A 192.58.128.30
+j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+l.root-servers.net. 3600000 IN A 199.7.83.42
+l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42
+m.root-servers.net. 3600000 IN A 202.12.27.33
+m.root-servers.net. 3600000 IN AAAA 2001:dc3::35
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+a.root-servers.net. IN DNSKEY
+SECTION AUTHORITY
+root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018070900 14400 7200 1209600 3600000
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+a.root-servers.net. IN NS
+SECTION AUTHORITY
+root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018070900 14400 7200 1209600 3600000
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+a.root-servers.net. IN DS
+SECTION AUTHORITY
+root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018070900 14400 7200 1209600 3600000
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+a.root-servers.net. IN AAAA
+SECTION ANSWER
+a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30
+SECTION AUTHORITY
+root-servers.net. 3600000 IN NS a.root-servers.net.
+root-servers.net. 3600000 IN NS b.root-servers.net.
+root-servers.net. 3600000 IN NS c.root-servers.net.
+root-servers.net. 3600000 IN NS d.root-servers.net.
+root-servers.net. 3600000 IN NS e.root-servers.net.
+root-servers.net. 3600000 IN NS f.root-servers.net.
+root-servers.net. 3600000 IN NS g.root-servers.net.
+root-servers.net. 3600000 IN NS h.root-servers.net.
+root-servers.net. 3600000 IN NS i.root-servers.net.
+root-servers.net. 3600000 IN NS j.root-servers.net.
+root-servers.net. 3600000 IN NS k.root-servers.net.
+root-servers.net. 3600000 IN NS l.root-servers.net.
+root-servers.net. 3600000 IN NS m.root-servers.net.
+SECTION ADDITIONAL
+a.root-servers.net. 3600000 IN A 198.41.0.4
+b.root-servers.net. 3600000 IN A 199.9.14.201
+b.root-servers.net. 3600000 IN AAAA 2001:500:200::b
+c.root-servers.net. 3600000 IN A 192.33.4.12
+c.root-servers.net. 3600000 IN AAAA 2001:500:2::c
+d.root-servers.net. 3600000 IN A 199.7.91.13
+d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d
+e.root-servers.net. 3600000 IN A 192.203.230.10
+e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e
+f.root-servers.net. 3600000 IN A 192.5.5.241
+f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f
+g.root-servers.net. 3600000 IN A 192.112.36.4
+g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d
+h.root-servers.net. 3600000 IN A 198.97.190.53
+h.root-servers.net. 3600000 IN AAAA 2001:500:1::53
+i.root-servers.net. 3600000 IN A 192.36.148.17
+i.root-servers.net. 3600000 IN AAAA 2001:7fe::53
+j.root-servers.net. 3600000 IN A 192.58.128.30
+j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+l.root-servers.net. 3600000 IN A 199.7.83.42
+l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42
+m.root-servers.net. 3600000 IN A 202.12.27.33
+m.root-servers.net. 3600000 IN AAAA 2001:dc3::35
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+j.root-servers.net. IN A
+SECTION ANSWER
+j.root-servers.net. 3600000 IN A 192.58.128.30
+SECTION AUTHORITY
+root-servers.net. 3600000 IN NS a.root-servers.net.
+root-servers.net. 3600000 IN NS b.root-servers.net.
+root-servers.net. 3600000 IN NS c.root-servers.net.
+root-servers.net. 3600000 IN NS d.root-servers.net.
+root-servers.net. 3600000 IN NS e.root-servers.net.
+root-servers.net. 3600000 IN NS f.root-servers.net.
+root-servers.net. 3600000 IN NS g.root-servers.net.
+root-servers.net. 3600000 IN NS h.root-servers.net.
+root-servers.net. 3600000 IN NS i.root-servers.net.
+root-servers.net. 3600000 IN NS j.root-servers.net.
+root-servers.net. 3600000 IN NS k.root-servers.net.
+root-servers.net. 3600000 IN NS l.root-servers.net.
+root-servers.net. 3600000 IN NS m.root-servers.net.
+SECTION ADDITIONAL
+a.root-servers.net. 3600000 IN A 198.41.0.4
+a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30
+b.root-servers.net. 3600000 IN A 199.9.14.201
+b.root-servers.net. 3600000 IN AAAA 2001:500:200::b
+c.root-servers.net. 3600000 IN A 192.33.4.12
+c.root-servers.net. 3600000 IN AAAA 2001:500:2::c
+d.root-servers.net. 3600000 IN A 199.7.91.13
+d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d
+e.root-servers.net. 3600000 IN A 192.203.230.10
+e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e
+f.root-servers.net. 3600000 IN A 192.5.5.241
+f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f
+g.root-servers.net. 3600000 IN A 192.112.36.4
+g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d
+h.root-servers.net. 3600000 IN A 198.97.190.53
+h.root-servers.net. 3600000 IN AAAA 2001:500:1::53
+i.root-servers.net. 3600000 IN A 192.36.148.17
+i.root-servers.net. 3600000 IN AAAA 2001:7fe::53
+j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+l.root-servers.net. 3600000 IN A 199.7.83.42
+l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42
+m.root-servers.net. 3600000 IN A 202.12.27.33
+m.root-servers.net. 3600000 IN AAAA 2001:dc3::35
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+j.root-servers.net. IN DNSKEY
+SECTION AUTHORITY
+root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018070900 14400 7200 1209600 3600000
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+j.root-servers.net. IN NS
+SECTION AUTHORITY
+root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018070900 14400 7200 1209600 3600000
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+j.root-servers.net. IN DS
+SECTION AUTHORITY
+root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018070900 14400 7200 1209600 3600000
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+j.root-servers.net. IN AAAA
+SECTION ANSWER
+j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30
+SECTION AUTHORITY
+root-servers.net. 3600000 IN NS a.root-servers.net.
+root-servers.net. 3600000 IN NS b.root-servers.net.
+root-servers.net. 3600000 IN NS c.root-servers.net.
+root-servers.net. 3600000 IN NS d.root-servers.net.
+root-servers.net. 3600000 IN NS e.root-servers.net.
+root-servers.net. 3600000 IN NS f.root-servers.net.
+root-servers.net. 3600000 IN NS g.root-servers.net.
+root-servers.net. 3600000 IN NS h.root-servers.net.
+root-servers.net. 3600000 IN NS i.root-servers.net.
+root-servers.net. 3600000 IN NS j.root-servers.net.
+root-servers.net. 3600000 IN NS k.root-servers.net.
+root-servers.net. 3600000 IN NS l.root-servers.net.
+root-servers.net. 3600000 IN NS m.root-servers.net.
+SECTION ADDITIONAL
+a.root-servers.net. 3600000 IN A 198.41.0.4
+a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30
+b.root-servers.net. 3600000 IN A 199.9.14.201
+b.root-servers.net. 3600000 IN AAAA 2001:500:200::b
+c.root-servers.net. 3600000 IN A 192.33.4.12
+c.root-servers.net. 3600000 IN AAAA 2001:500:2::c
+d.root-servers.net. 3600000 IN A 199.7.91.13
+d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d
+e.root-servers.net. 3600000 IN A 192.203.230.10
+e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e
+f.root-servers.net. 3600000 IN A 192.5.5.241
+f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f
+g.root-servers.net. 3600000 IN A 192.112.36.4
+g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d
+h.root-servers.net. 3600000 IN A 198.97.190.53
+h.root-servers.net. 3600000 IN AAAA 2001:500:1::53
+i.root-servers.net. 3600000 IN A 192.36.148.17
+i.root-servers.net. 3600000 IN AAAA 2001:7fe::53
+j.root-servers.net. 3600000 IN A 192.58.128.30
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+l.root-servers.net. 3600000 IN A 199.7.83.42
+l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42
+m.root-servers.net. 3600000 IN A 202.12.27.33
+m.root-servers.net. 3600000 IN AAAA 2001:dc3::35
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+e.root-servers.net. IN A
+SECTION ANSWER
+e.root-servers.net. 3600000 IN A 192.203.230.10
+SECTION AUTHORITY
+root-servers.net. 3600000 IN NS a.root-servers.net.
+root-servers.net. 3600000 IN NS b.root-servers.net.
+root-servers.net. 3600000 IN NS c.root-servers.net.
+root-servers.net. 3600000 IN NS d.root-servers.net.
+root-servers.net. 3600000 IN NS e.root-servers.net.
+root-servers.net. 3600000 IN NS f.root-servers.net.
+root-servers.net. 3600000 IN NS g.root-servers.net.
+root-servers.net. 3600000 IN NS h.root-servers.net.
+root-servers.net. 3600000 IN NS i.root-servers.net.
+root-servers.net. 3600000 IN NS j.root-servers.net.
+root-servers.net. 3600000 IN NS k.root-servers.net.
+root-servers.net. 3600000 IN NS l.root-servers.net.
+root-servers.net. 3600000 IN NS m.root-servers.net.
+SECTION ADDITIONAL
+a.root-servers.net. 3600000 IN A 198.41.0.4
+a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30
+b.root-servers.net. 3600000 IN A 199.9.14.201
+b.root-servers.net. 3600000 IN AAAA 2001:500:200::b
+c.root-servers.net. 3600000 IN A 192.33.4.12
+c.root-servers.net. 3600000 IN AAAA 2001:500:2::c
+d.root-servers.net. 3600000 IN A 199.7.91.13
+d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d
+e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e
+f.root-servers.net. 3600000 IN A 192.5.5.241
+f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f
+g.root-servers.net. 3600000 IN A 192.112.36.4
+g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d
+h.root-servers.net. 3600000 IN A 198.97.190.53
+h.root-servers.net. 3600000 IN AAAA 2001:500:1::53
+i.root-servers.net. 3600000 IN A 192.36.148.17
+i.root-servers.net. 3600000 IN AAAA 2001:7fe::53
+j.root-servers.net. 3600000 IN A 192.58.128.30
+j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+l.root-servers.net. 3600000 IN A 199.7.83.42
+l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42
+m.root-servers.net. 3600000 IN A 202.12.27.33
+m.root-servers.net. 3600000 IN AAAA 2001:dc3::35
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+e.root-servers.net. IN DNSKEY
+SECTION AUTHORITY
+root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018070900 14400 7200 1209600 3600000
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+e.root-servers.net. IN NS
+SECTION AUTHORITY
+root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018070900 14400 7200 1209600 3600000
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+e.root-servers.net. IN DS
+SECTION AUTHORITY
+root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018070900 14400 7200 1209600 3600000
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+e.root-servers.net. IN AAAA
+SECTION ANSWER
+e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e
+SECTION AUTHORITY
+root-servers.net. 3600000 IN NS a.root-servers.net.
+root-servers.net. 3600000 IN NS b.root-servers.net.
+root-servers.net. 3600000 IN NS c.root-servers.net.
+root-servers.net. 3600000 IN NS d.root-servers.net.
+root-servers.net. 3600000 IN NS e.root-servers.net.
+root-servers.net. 3600000 IN NS f.root-servers.net.
+root-servers.net. 3600000 IN NS g.root-servers.net.
+root-servers.net. 3600000 IN NS h.root-servers.net.
+root-servers.net. 3600000 IN NS i.root-servers.net.
+root-servers.net. 3600000 IN NS j.root-servers.net.
+root-servers.net. 3600000 IN NS k.root-servers.net.
+root-servers.net. 3600000 IN NS l.root-servers.net.
+root-servers.net. 3600000 IN NS m.root-servers.net.
+SECTION ADDITIONAL
+a.root-servers.net. 3600000 IN A 198.41.0.4
+a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30
+b.root-servers.net. 3600000 IN A 199.9.14.201
+b.root-servers.net. 3600000 IN AAAA 2001:500:200::b
+c.root-servers.net. 3600000 IN A 192.33.4.12
+c.root-servers.net. 3600000 IN AAAA 2001:500:2::c
+d.root-servers.net. 3600000 IN A 199.7.91.13
+d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d
+e.root-servers.net. 3600000 IN A 192.203.230.10
+f.root-servers.net. 3600000 IN A 192.5.5.241
+f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f
+g.root-servers.net. 3600000 IN A 192.112.36.4
+g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d
+h.root-servers.net. 3600000 IN A 198.97.190.53
+h.root-servers.net. 3600000 IN AAAA 2001:500:1::53
+i.root-servers.net. 3600000 IN A 192.36.148.17
+i.root-servers.net. 3600000 IN AAAA 2001:7fe::53
+j.root-servers.net. 3600000 IN A 192.58.128.30
+j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+l.root-servers.net. 3600000 IN A 199.7.83.42
+l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42
+m.root-servers.net. 3600000 IN A 202.12.27.33
+m.root-servers.net. 3600000 IN AAAA 2001:dc3::35
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+i.root-servers.net. IN A
+SECTION ANSWER
+i.root-servers.net. 3600000 IN A 192.36.148.17
+SECTION AUTHORITY
+root-servers.net. 3600000 IN NS a.root-servers.net.
+root-servers.net. 3600000 IN NS b.root-servers.net.
+root-servers.net. 3600000 IN NS c.root-servers.net.
+root-servers.net. 3600000 IN NS d.root-servers.net.
+root-servers.net. 3600000 IN NS e.root-servers.net.
+root-servers.net. 3600000 IN NS f.root-servers.net.
+root-servers.net. 3600000 IN NS g.root-servers.net.
+root-servers.net. 3600000 IN NS h.root-servers.net.
+root-servers.net. 3600000 IN NS i.root-servers.net.
+root-servers.net. 3600000 IN NS j.root-servers.net.
+root-servers.net. 3600000 IN NS k.root-servers.net.
+root-servers.net. 3600000 IN NS l.root-servers.net.
+root-servers.net. 3600000 IN NS m.root-servers.net.
+SECTION ADDITIONAL
+a.root-servers.net. 3600000 IN A 198.41.0.4
+a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30
+b.root-servers.net. 3600000 IN A 199.9.14.201
+b.root-servers.net. 3600000 IN AAAA 2001:500:200::b
+c.root-servers.net. 3600000 IN A 192.33.4.12
+c.root-servers.net. 3600000 IN AAAA 2001:500:2::c
+d.root-servers.net. 3600000 IN A 199.7.91.13
+d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d
+e.root-servers.net. 3600000 IN A 192.203.230.10
+e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e
+f.root-servers.net. 3600000 IN A 192.5.5.241
+f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f
+g.root-servers.net. 3600000 IN A 192.112.36.4
+g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d
+h.root-servers.net. 3600000 IN A 198.97.190.53
+h.root-servers.net. 3600000 IN AAAA 2001:500:1::53
+i.root-servers.net. 3600000 IN AAAA 2001:7fe::53
+j.root-servers.net. 3600000 IN A 192.58.128.30
+j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+l.root-servers.net. 3600000 IN A 199.7.83.42
+l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42
+m.root-servers.net. 3600000 IN A 202.12.27.33
+m.root-servers.net. 3600000 IN AAAA 2001:dc3::35
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+i.root-servers.net. IN DNSKEY
+SECTION AUTHORITY
+root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018070900 14400 7200 1209600 3600000
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+i.root-servers.net. IN NS
+SECTION AUTHORITY
+root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018070900 14400 7200 1209600 3600000
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+i.root-servers.net. IN DS
+SECTION AUTHORITY
+root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018070900 14400 7200 1209600 3600000
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+i.root-servers.net. IN AAAA
+SECTION ANSWER
+i.root-servers.net. 3600000 IN AAAA 2001:7fe::53
+SECTION AUTHORITY
+root-servers.net. 3600000 IN NS a.root-servers.net.
+root-servers.net. 3600000 IN NS b.root-servers.net.
+root-servers.net. 3600000 IN NS c.root-servers.net.
+root-servers.net. 3600000 IN NS d.root-servers.net.
+root-servers.net. 3600000 IN NS e.root-servers.net.
+root-servers.net. 3600000 IN NS f.root-servers.net.
+root-servers.net. 3600000 IN NS g.root-servers.net.
+root-servers.net. 3600000 IN NS h.root-servers.net.
+root-servers.net. 3600000 IN NS i.root-servers.net.
+root-servers.net. 3600000 IN NS j.root-servers.net.
+root-servers.net. 3600000 IN NS k.root-servers.net.
+root-servers.net. 3600000 IN NS l.root-servers.net.
+root-servers.net. 3600000 IN NS m.root-servers.net.
+SECTION ADDITIONAL
+a.root-servers.net. 3600000 IN A 198.41.0.4
+a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30
+b.root-servers.net. 3600000 IN A 199.9.14.201
+b.root-servers.net. 3600000 IN AAAA 2001:500:200::b
+c.root-servers.net. 3600000 IN A 192.33.4.12
+c.root-servers.net. 3600000 IN AAAA 2001:500:2::c
+d.root-servers.net. 3600000 IN A 199.7.91.13
+d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d
+e.root-servers.net. 3600000 IN A 192.203.230.10
+e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e
+f.root-servers.net. 3600000 IN A 192.5.5.241
+f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f
+g.root-servers.net. 3600000 IN A 192.112.36.4
+g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d
+h.root-servers.net. 3600000 IN A 198.97.190.53
+h.root-servers.net. 3600000 IN AAAA 2001:500:1::53
+i.root-servers.net. 3600000 IN A 192.36.148.17
+j.root-servers.net. 3600000 IN A 192.58.128.30
+j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+l.root-servers.net. 3600000 IN A 199.7.83.42
+l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42
+m.root-servers.net. 3600000 IN A 202.12.27.33
+m.root-servers.net. 3600000 IN AAAA 2001:dc3::35
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+d.root-servers.net. IN A
+SECTION ANSWER
+d.root-servers.net. 3600000 IN A 199.7.91.13
+SECTION AUTHORITY
+root-servers.net. 3600000 IN NS a.root-servers.net.
+root-servers.net. 3600000 IN NS b.root-servers.net.
+root-servers.net. 3600000 IN NS c.root-servers.net.
+root-servers.net. 3600000 IN NS d.root-servers.net.
+root-servers.net. 3600000 IN NS e.root-servers.net.
+root-servers.net. 3600000 IN NS f.root-servers.net.
+root-servers.net. 3600000 IN NS g.root-servers.net.
+root-servers.net. 3600000 IN NS h.root-servers.net.
+root-servers.net. 3600000 IN NS i.root-servers.net.
+root-servers.net. 3600000 IN NS j.root-servers.net.
+root-servers.net. 3600000 IN NS k.root-servers.net.
+root-servers.net. 3600000 IN NS l.root-servers.net.
+root-servers.net. 3600000 IN NS m.root-servers.net.
+SECTION ADDITIONAL
+a.root-servers.net. 3600000 IN A 198.41.0.4
+a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30
+b.root-servers.net. 3600000 IN A 199.9.14.201
+b.root-servers.net. 3600000 IN AAAA 2001:500:200::b
+c.root-servers.net. 3600000 IN A 192.33.4.12
+c.root-servers.net. 3600000 IN AAAA 2001:500:2::c
+d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d
+e.root-servers.net. 3600000 IN A 192.203.230.10
+e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e
+f.root-servers.net. 3600000 IN A 192.5.5.241
+f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f
+g.root-servers.net. 3600000 IN A 192.112.36.4
+g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d
+h.root-servers.net. 3600000 IN A 198.97.190.53
+h.root-servers.net. 3600000 IN AAAA 2001:500:1::53
+i.root-servers.net. 3600000 IN A 192.36.148.17
+i.root-servers.net. 3600000 IN AAAA 2001:7fe::53
+j.root-servers.net. 3600000 IN A 192.58.128.30
+j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+l.root-servers.net. 3600000 IN A 199.7.83.42
+l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42
+m.root-servers.net. 3600000 IN A 202.12.27.33
+m.root-servers.net. 3600000 IN AAAA 2001:dc3::35
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+d.root-servers.net. IN DNSKEY
+SECTION AUTHORITY
+root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018070900 14400 7200 1209600 3600000
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+d.root-servers.net. IN NS
+SECTION AUTHORITY
+root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018070900 14400 7200 1209600 3600000
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+d.root-servers.net. IN DS
+SECTION AUTHORITY
+root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018070900 14400 7200 1209600 3600000
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+d.root-servers.net. IN AAAA
+SECTION ANSWER
+d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d
+SECTION AUTHORITY
+root-servers.net. 3600000 IN NS a.root-servers.net.
+root-servers.net. 3600000 IN NS b.root-servers.net.
+root-servers.net. 3600000 IN NS c.root-servers.net.
+root-servers.net. 3600000 IN NS d.root-servers.net.
+root-servers.net. 3600000 IN NS e.root-servers.net.
+root-servers.net. 3600000 IN NS f.root-servers.net.
+root-servers.net. 3600000 IN NS g.root-servers.net.
+root-servers.net. 3600000 IN NS h.root-servers.net.
+root-servers.net. 3600000 IN NS i.root-servers.net.
+root-servers.net. 3600000 IN NS j.root-servers.net.
+root-servers.net. 3600000 IN NS k.root-servers.net.
+root-servers.net. 3600000 IN NS l.root-servers.net.
+root-servers.net. 3600000 IN NS m.root-servers.net.
+SECTION ADDITIONAL
+a.root-servers.net. 3600000 IN A 198.41.0.4
+a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30
+b.root-servers.net. 3600000 IN A 199.9.14.201
+b.root-servers.net. 3600000 IN AAAA 2001:500:200::b
+c.root-servers.net. 3600000 IN A 192.33.4.12
+c.root-servers.net. 3600000 IN AAAA 2001:500:2::c
+d.root-servers.net. 3600000 IN A 199.7.91.13
+e.root-servers.net. 3600000 IN A 192.203.230.10
+e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e
+f.root-servers.net. 3600000 IN A 192.5.5.241
+f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f
+g.root-servers.net. 3600000 IN A 192.112.36.4
+g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d
+h.root-servers.net. 3600000 IN A 198.97.190.53
+h.root-servers.net. 3600000 IN AAAA 2001:500:1::53
+i.root-servers.net. 3600000 IN A 192.36.148.17
+i.root-servers.net. 3600000 IN AAAA 2001:7fe::53
+j.root-servers.net. 3600000 IN A 192.58.128.30
+j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+l.root-servers.net. 3600000 IN A 199.7.83.42
+l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42
+m.root-servers.net. 3600000 IN A 202.12.27.33
+m.root-servers.net. 3600000 IN AAAA 2001:dc3::35
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+m.root-servers.net. IN A
+SECTION ANSWER
+m.root-servers.net. 3600000 IN A 202.12.27.33
+SECTION AUTHORITY
+root-servers.net. 3600000 IN NS a.root-servers.net.
+root-servers.net. 3600000 IN NS b.root-servers.net.
+root-servers.net. 3600000 IN NS c.root-servers.net.
+root-servers.net. 3600000 IN NS d.root-servers.net.
+root-servers.net. 3600000 IN NS e.root-servers.net.
+root-servers.net. 3600000 IN NS f.root-servers.net.
+root-servers.net. 3600000 IN NS g.root-servers.net.
+root-servers.net. 3600000 IN NS h.root-servers.net.
+root-servers.net. 3600000 IN NS i.root-servers.net.
+root-servers.net. 3600000 IN NS j.root-servers.net.
+root-servers.net. 3600000 IN NS k.root-servers.net.
+root-servers.net. 3600000 IN NS l.root-servers.net.
+root-servers.net. 3600000 IN NS m.root-servers.net.
+SECTION ADDITIONAL
+a.root-servers.net. 3600000 IN A 198.41.0.4
+a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30
+b.root-servers.net. 3600000 IN A 199.9.14.201
+b.root-servers.net. 3600000 IN AAAA 2001:500:200::b
+c.root-servers.net. 3600000 IN A 192.33.4.12
+c.root-servers.net. 3600000 IN AAAA 2001:500:2::c
+d.root-servers.net. 3600000 IN A 199.7.91.13
+d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d
+e.root-servers.net. 3600000 IN A 192.203.230.10
+e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e
+f.root-servers.net. 3600000 IN A 192.5.5.241
+f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f
+g.root-servers.net. 3600000 IN A 192.112.36.4
+g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d
+h.root-servers.net. 3600000 IN A 198.97.190.53
+h.root-servers.net. 3600000 IN AAAA 2001:500:1::53
+i.root-servers.net. 3600000 IN A 192.36.148.17
+i.root-servers.net. 3600000 IN AAAA 2001:7fe::53
+j.root-servers.net. 3600000 IN A 192.58.128.30
+j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+l.root-servers.net. 3600000 IN A 199.7.83.42
+l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42
+m.root-servers.net. 3600000 IN AAAA 2001:dc3::35
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+m.root-servers.net. IN DNSKEY
+SECTION AUTHORITY
+root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018070900 14400 7200 1209600 3600000
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+m.root-servers.net. IN NS
+SECTION AUTHORITY
+root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018070900 14400 7200 1209600 3600000
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+m.root-servers.net. IN DS
+SECTION AUTHORITY
+root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018070900 14400 7200 1209600 3600000
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+m.root-servers.net. IN AAAA
+SECTION ANSWER
+m.root-servers.net. 3600000 IN AAAA 2001:dc3::35
+SECTION AUTHORITY
+root-servers.net. 3600000 IN NS a.root-servers.net.
+root-servers.net. 3600000 IN NS b.root-servers.net.
+root-servers.net. 3600000 IN NS c.root-servers.net.
+root-servers.net. 3600000 IN NS d.root-servers.net.
+root-servers.net. 3600000 IN NS e.root-servers.net.
+root-servers.net. 3600000 IN NS f.root-servers.net.
+root-servers.net. 3600000 IN NS g.root-servers.net.
+root-servers.net. 3600000 IN NS h.root-servers.net.
+root-servers.net. 3600000 IN NS i.root-servers.net.
+root-servers.net. 3600000 IN NS j.root-servers.net.
+root-servers.net. 3600000 IN NS k.root-servers.net.
+root-servers.net. 3600000 IN NS l.root-servers.net.
+root-servers.net. 3600000 IN NS m.root-servers.net.
+SECTION ADDITIONAL
+a.root-servers.net. 3600000 IN A 198.41.0.4
+a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30
+b.root-servers.net. 3600000 IN A 199.9.14.201
+b.root-servers.net. 3600000 IN AAAA 2001:500:200::b
+c.root-servers.net. 3600000 IN A 192.33.4.12
+c.root-servers.net. 3600000 IN AAAA 2001:500:2::c
+d.root-servers.net. 3600000 IN A 199.7.91.13
+d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d
+e.root-servers.net. 3600000 IN A 192.203.230.10
+e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e
+f.root-servers.net. 3600000 IN A 192.5.5.241
+f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f
+g.root-servers.net. 3600000 IN A 192.112.36.4
+g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d
+h.root-servers.net. 3600000 IN A 198.97.190.53
+h.root-servers.net. 3600000 IN AAAA 2001:500:1::53
+i.root-servers.net. 3600000 IN A 192.36.148.17
+i.root-servers.net. 3600000 IN AAAA 2001:7fe::53
+j.root-servers.net. 3600000 IN A 192.58.128.30
+j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+l.root-servers.net. 3600000 IN A 199.7.83.42
+l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42
+m.root-servers.net. 3600000 IN A 202.12.27.33
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+h.root-servers.net. IN A
+SECTION ANSWER
+h.root-servers.net. 3600000 IN A 198.97.190.53
+SECTION AUTHORITY
+root-servers.net. 3600000 IN NS a.root-servers.net.
+root-servers.net. 3600000 IN NS b.root-servers.net.
+root-servers.net. 3600000 IN NS c.root-servers.net.
+root-servers.net. 3600000 IN NS d.root-servers.net.
+root-servers.net. 3600000 IN NS e.root-servers.net.
+root-servers.net. 3600000 IN NS f.root-servers.net.
+root-servers.net. 3600000 IN NS g.root-servers.net.
+root-servers.net. 3600000 IN NS h.root-servers.net.
+root-servers.net. 3600000 IN NS i.root-servers.net.
+root-servers.net. 3600000 IN NS j.root-servers.net.
+root-servers.net. 3600000 IN NS k.root-servers.net.
+root-servers.net. 3600000 IN NS l.root-servers.net.
+root-servers.net. 3600000 IN NS m.root-servers.net.
+SECTION ADDITIONAL
+a.root-servers.net. 3600000 IN A 198.41.0.4
+a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30
+b.root-servers.net. 3600000 IN A 199.9.14.201
+b.root-servers.net. 3600000 IN AAAA 2001:500:200::b
+c.root-servers.net. 3600000 IN A 192.33.4.12
+c.root-servers.net. 3600000 IN AAAA 2001:500:2::c
+d.root-servers.net. 3600000 IN A 199.7.91.13
+d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d
+e.root-servers.net. 3600000 IN A 192.203.230.10
+e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e
+f.root-servers.net. 3600000 IN A 192.5.5.241
+f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f
+g.root-servers.net. 3600000 IN A 192.112.36.4
+g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d
+h.root-servers.net. 3600000 IN AAAA 2001:500:1::53
+i.root-servers.net. 3600000 IN A 192.36.148.17
+i.root-servers.net. 3600000 IN AAAA 2001:7fe::53
+j.root-servers.net. 3600000 IN A 192.58.128.30
+j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+l.root-servers.net. 3600000 IN A 199.7.83.42
+l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42
+m.root-servers.net. 3600000 IN A 202.12.27.33
+m.root-servers.net. 3600000 IN AAAA 2001:dc3::35
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+h.root-servers.net. IN DNSKEY
+SECTION AUTHORITY
+root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018070900 14400 7200 1209600 3600000
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+h.root-servers.net. IN NS
+SECTION AUTHORITY
+root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018070900 14400 7200 1209600 3600000
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+h.root-servers.net. IN DS
+SECTION AUTHORITY
+root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018070900 14400 7200 1209600 3600000
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+h.root-servers.net. IN AAAA
+SECTION ANSWER
+h.root-servers.net. 3600000 IN AAAA 2001:500:1::53
+SECTION AUTHORITY
+root-servers.net. 3600000 IN NS a.root-servers.net.
+root-servers.net. 3600000 IN NS b.root-servers.net.
+root-servers.net. 3600000 IN NS c.root-servers.net.
+root-servers.net. 3600000 IN NS d.root-servers.net.
+root-servers.net. 3600000 IN NS e.root-servers.net.
+root-servers.net. 3600000 IN NS f.root-servers.net.
+root-servers.net. 3600000 IN NS g.root-servers.net.
+root-servers.net. 3600000 IN NS h.root-servers.net.
+root-servers.net. 3600000 IN NS i.root-servers.net.
+root-servers.net. 3600000 IN NS j.root-servers.net.
+root-servers.net. 3600000 IN NS k.root-servers.net.
+root-servers.net. 3600000 IN NS l.root-servers.net.
+root-servers.net. 3600000 IN NS m.root-servers.net.
+SECTION ADDITIONAL
+a.root-servers.net. 3600000 IN A 198.41.0.4
+a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30
+b.root-servers.net. 3600000 IN A 199.9.14.201
+b.root-servers.net. 3600000 IN AAAA 2001:500:200::b
+c.root-servers.net. 3600000 IN A 192.33.4.12
+c.root-servers.net. 3600000 IN AAAA 2001:500:2::c
+d.root-servers.net. 3600000 IN A 199.7.91.13
+d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d
+e.root-servers.net. 3600000 IN A 192.203.230.10
+e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e
+f.root-servers.net. 3600000 IN A 192.5.5.241
+f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f
+g.root-servers.net. 3600000 IN A 192.112.36.4
+g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d
+h.root-servers.net. 3600000 IN A 198.97.190.53
+i.root-servers.net. 3600000 IN A 192.36.148.17
+i.root-servers.net. 3600000 IN AAAA 2001:7fe::53
+j.root-servers.net. 3600000 IN A 192.58.128.30
+j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+l.root-servers.net. 3600000 IN A 199.7.83.42
+l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42
+m.root-servers.net. 3600000 IN A 202.12.27.33
+m.root-servers.net. 3600000 IN AAAA 2001:dc3::35
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+c.root-servers.net. IN A
+SECTION ANSWER
+c.root-servers.net. 3600000 IN A 192.33.4.12
+SECTION AUTHORITY
+root-servers.net. 3600000 IN NS a.root-servers.net.
+root-servers.net. 3600000 IN NS b.root-servers.net.
+root-servers.net. 3600000 IN NS c.root-servers.net.
+root-servers.net. 3600000 IN NS d.root-servers.net.
+root-servers.net. 3600000 IN NS e.root-servers.net.
+root-servers.net. 3600000 IN NS f.root-servers.net.
+root-servers.net. 3600000 IN NS g.root-servers.net.
+root-servers.net. 3600000 IN NS h.root-servers.net.
+root-servers.net. 3600000 IN NS i.root-servers.net.
+root-servers.net. 3600000 IN NS j.root-servers.net.
+root-servers.net. 3600000 IN NS k.root-servers.net.
+root-servers.net. 3600000 IN NS l.root-servers.net.
+root-servers.net. 3600000 IN NS m.root-servers.net.
+SECTION ADDITIONAL
+a.root-servers.net. 3600000 IN A 198.41.0.4
+a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30
+b.root-servers.net. 3600000 IN A 199.9.14.201
+b.root-servers.net. 3600000 IN AAAA 2001:500:200::b
+c.root-servers.net. 3600000 IN AAAA 2001:500:2::c
+d.root-servers.net. 3600000 IN A 199.7.91.13
+d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d
+e.root-servers.net. 3600000 IN A 192.203.230.10
+e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e
+f.root-servers.net. 3600000 IN A 192.5.5.241
+f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f
+g.root-servers.net. 3600000 IN A 192.112.36.4
+g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d
+h.root-servers.net. 3600000 IN A 198.97.190.53
+h.root-servers.net. 3600000 IN AAAA 2001:500:1::53
+i.root-servers.net. 3600000 IN A 192.36.148.17
+i.root-servers.net. 3600000 IN AAAA 2001:7fe::53
+j.root-servers.net. 3600000 IN A 192.58.128.30
+j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+l.root-servers.net. 3600000 IN A 199.7.83.42
+l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42
+m.root-servers.net. 3600000 IN A 202.12.27.33
+m.root-servers.net. 3600000 IN AAAA 2001:dc3::35
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+c.root-servers.net. IN DNSKEY
+SECTION AUTHORITY
+root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018070900 14400 7200 1209600 3600000
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+c.root-servers.net. IN NS
+SECTION AUTHORITY
+root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018070900 14400 7200 1209600 3600000
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+c.root-servers.net. IN DS
+SECTION AUTHORITY
+root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018070900 14400 7200 1209600 3600000
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+c.root-servers.net. IN AAAA
+SECTION ANSWER
+c.root-servers.net. 3600000 IN AAAA 2001:500:2::c
+SECTION AUTHORITY
+root-servers.net. 3600000 IN NS a.root-servers.net.
+root-servers.net. 3600000 IN NS b.root-servers.net.
+root-servers.net. 3600000 IN NS c.root-servers.net.
+root-servers.net. 3600000 IN NS d.root-servers.net.
+root-servers.net. 3600000 IN NS e.root-servers.net.
+root-servers.net. 3600000 IN NS f.root-servers.net.
+root-servers.net. 3600000 IN NS g.root-servers.net.
+root-servers.net. 3600000 IN NS h.root-servers.net.
+root-servers.net. 3600000 IN NS i.root-servers.net.
+root-servers.net. 3600000 IN NS j.root-servers.net.
+root-servers.net. 3600000 IN NS k.root-servers.net.
+root-servers.net. 3600000 IN NS l.root-servers.net.
+root-servers.net. 3600000 IN NS m.root-servers.net.
+SECTION ADDITIONAL
+a.root-servers.net. 3600000 IN A 198.41.0.4
+a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30
+b.root-servers.net. 3600000 IN A 199.9.14.201
+b.root-servers.net. 3600000 IN AAAA 2001:500:200::b
+c.root-servers.net. 3600000 IN A 192.33.4.12
+d.root-servers.net. 3600000 IN A 199.7.91.13
+d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d
+e.root-servers.net. 3600000 IN A 192.203.230.10
+e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e
+f.root-servers.net. 3600000 IN A 192.5.5.241
+f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f
+g.root-servers.net. 3600000 IN A 192.112.36.4
+g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d
+h.root-servers.net. 3600000 IN A 198.97.190.53
+h.root-servers.net. 3600000 IN AAAA 2001:500:1::53
+i.root-servers.net. 3600000 IN A 192.36.148.17
+i.root-servers.net. 3600000 IN AAAA 2001:7fe::53
+j.root-servers.net. 3600000 IN A 192.58.128.30
+j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+l.root-servers.net. 3600000 IN A 199.7.83.42
+l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42
+m.root-servers.net. 3600000 IN A 202.12.27.33
+m.root-servers.net. 3600000 IN AAAA 2001:dc3::35
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+l.root-servers.net. IN A
+SECTION ANSWER
+l.root-servers.net. 3600000 IN A 199.7.83.42
+SECTION AUTHORITY
+root-servers.net. 3600000 IN NS a.root-servers.net.
+root-servers.net. 3600000 IN NS b.root-servers.net.
+root-servers.net. 3600000 IN NS c.root-servers.net.
+root-servers.net. 3600000 IN NS d.root-servers.net.
+root-servers.net. 3600000 IN NS e.root-servers.net.
+root-servers.net. 3600000 IN NS f.root-servers.net.
+root-servers.net. 3600000 IN NS g.root-servers.net.
+root-servers.net. 3600000 IN NS h.root-servers.net.
+root-servers.net. 3600000 IN NS i.root-servers.net.
+root-servers.net. 3600000 IN NS j.root-servers.net.
+root-servers.net. 3600000 IN NS k.root-servers.net.
+root-servers.net. 3600000 IN NS l.root-servers.net.
+root-servers.net. 3600000 IN NS m.root-servers.net.
+SECTION ADDITIONAL
+a.root-servers.net. 3600000 IN A 198.41.0.4
+a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30
+b.root-servers.net. 3600000 IN A 199.9.14.201
+b.root-servers.net. 3600000 IN AAAA 2001:500:200::b
+c.root-servers.net. 3600000 IN A 192.33.4.12
+c.root-servers.net. 3600000 IN AAAA 2001:500:2::c
+d.root-servers.net. 3600000 IN A 199.7.91.13
+d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d
+e.root-servers.net. 3600000 IN A 192.203.230.10
+e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e
+f.root-servers.net. 3600000 IN A 192.5.5.241
+f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f
+g.root-servers.net. 3600000 IN A 192.112.36.4
+g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d
+h.root-servers.net. 3600000 IN A 198.97.190.53
+h.root-servers.net. 3600000 IN AAAA 2001:500:1::53
+i.root-servers.net. 3600000 IN A 192.36.148.17
+i.root-servers.net. 3600000 IN AAAA 2001:7fe::53
+j.root-servers.net. 3600000 IN A 192.58.128.30
+j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42
+m.root-servers.net. 3600000 IN A 202.12.27.33
+m.root-servers.net. 3600000 IN AAAA 2001:dc3::35
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+l.root-servers.net. IN DNSKEY
+SECTION AUTHORITY
+root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018070900 14400 7200 1209600 3600000
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+l.root-servers.net. IN NS
+SECTION AUTHORITY
+root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018070900 14400 7200 1209600 3600000
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+l.root-servers.net. IN DS
+SECTION AUTHORITY
+root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018070900 14400 7200 1209600 3600000
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+l.root-servers.net. IN AAAA
+SECTION ANSWER
+l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42
+SECTION AUTHORITY
+root-servers.net. 3600000 IN NS a.root-servers.net.
+root-servers.net. 3600000 IN NS b.root-servers.net.
+root-servers.net. 3600000 IN NS c.root-servers.net.
+root-servers.net. 3600000 IN NS d.root-servers.net.
+root-servers.net. 3600000 IN NS e.root-servers.net.
+root-servers.net. 3600000 IN NS f.root-servers.net.
+root-servers.net. 3600000 IN NS g.root-servers.net.
+root-servers.net. 3600000 IN NS h.root-servers.net.
+root-servers.net. 3600000 IN NS i.root-servers.net.
+root-servers.net. 3600000 IN NS j.root-servers.net.
+root-servers.net. 3600000 IN NS k.root-servers.net.
+root-servers.net. 3600000 IN NS l.root-servers.net.
+root-servers.net. 3600000 IN NS m.root-servers.net.
+SECTION ADDITIONAL
+a.root-servers.net. 3600000 IN A 198.41.0.4
+a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30
+b.root-servers.net. 3600000 IN A 199.9.14.201
+b.root-servers.net. 3600000 IN AAAA 2001:500:200::b
+c.root-servers.net. 3600000 IN A 192.33.4.12
+c.root-servers.net. 3600000 IN AAAA 2001:500:2::c
+d.root-servers.net. 3600000 IN A 199.7.91.13
+d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d
+e.root-servers.net. 3600000 IN A 192.203.230.10
+e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e
+f.root-servers.net. 3600000 IN A 192.5.5.241
+f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f
+g.root-servers.net. 3600000 IN A 192.112.36.4
+g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d
+h.root-servers.net. 3600000 IN A 198.97.190.53
+h.root-servers.net. 3600000 IN AAAA 2001:500:1::53
+i.root-servers.net. 3600000 IN A 192.36.148.17
+i.root-servers.net. 3600000 IN AAAA 2001:7fe::53
+j.root-servers.net. 3600000 IN A 192.58.128.30
+j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+l.root-servers.net. 3600000 IN A 199.7.83.42
+m.root-servers.net. 3600000 IN A 202.12.27.33
+m.root-servers.net. 3600000 IN AAAA 2001:dc3::35
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+g.root-servers.net. IN A
+SECTION ANSWER
+g.root-servers.net. 3600000 IN A 192.112.36.4
+SECTION AUTHORITY
+root-servers.net. 3600000 IN NS a.root-servers.net.
+root-servers.net. 3600000 IN NS b.root-servers.net.
+root-servers.net. 3600000 IN NS c.root-servers.net.
+root-servers.net. 3600000 IN NS d.root-servers.net.
+root-servers.net. 3600000 IN NS e.root-servers.net.
+root-servers.net. 3600000 IN NS f.root-servers.net.
+root-servers.net. 3600000 IN NS g.root-servers.net.
+root-servers.net. 3600000 IN NS h.root-servers.net.
+root-servers.net. 3600000 IN NS i.root-servers.net.
+root-servers.net. 3600000 IN NS j.root-servers.net.
+root-servers.net. 3600000 IN NS k.root-servers.net.
+root-servers.net. 3600000 IN NS l.root-servers.net.
+root-servers.net. 3600000 IN NS m.root-servers.net.
+SECTION ADDITIONAL
+a.root-servers.net. 3600000 IN A 198.41.0.4
+a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30
+b.root-servers.net. 3600000 IN A 199.9.14.201
+b.root-servers.net. 3600000 IN AAAA 2001:500:200::b
+c.root-servers.net. 3600000 IN A 192.33.4.12
+c.root-servers.net. 3600000 IN AAAA 2001:500:2::c
+d.root-servers.net. 3600000 IN A 199.7.91.13
+d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d
+e.root-servers.net. 3600000 IN A 192.203.230.10
+e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e
+f.root-servers.net. 3600000 IN A 192.5.5.241
+f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f
+g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d
+h.root-servers.net. 3600000 IN A 198.97.190.53
+h.root-servers.net. 3600000 IN AAAA 2001:500:1::53
+i.root-servers.net. 3600000 IN A 192.36.148.17
+i.root-servers.net. 3600000 IN AAAA 2001:7fe::53
+j.root-servers.net. 3600000 IN A 192.58.128.30
+j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+l.root-servers.net. 3600000 IN A 199.7.83.42
+l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42
+m.root-servers.net. 3600000 IN A 202.12.27.33
+m.root-servers.net. 3600000 IN AAAA 2001:dc3::35
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+g.root-servers.net. IN DNSKEY
+SECTION AUTHORITY
+root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018070900 14400 7200 1209600 3600000
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+g.root-servers.net. IN NS
+SECTION AUTHORITY
+root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018070900 14400 7200 1209600 3600000
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+g.root-servers.net. IN DS
+SECTION AUTHORITY
+root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018070900 14400 7200 1209600 3600000
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+g.root-servers.net. IN AAAA
+SECTION ANSWER
+g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d
+SECTION AUTHORITY
+root-servers.net. 3600000 IN NS a.root-servers.net.
+root-servers.net. 3600000 IN NS b.root-servers.net.
+root-servers.net. 3600000 IN NS c.root-servers.net.
+root-servers.net. 3600000 IN NS d.root-servers.net.
+root-servers.net. 3600000 IN NS e.root-servers.net.
+root-servers.net. 3600000 IN NS f.root-servers.net.
+root-servers.net. 3600000 IN NS g.root-servers.net.
+root-servers.net. 3600000 IN NS h.root-servers.net.
+root-servers.net. 3600000 IN NS i.root-servers.net.
+root-servers.net. 3600000 IN NS j.root-servers.net.
+root-servers.net. 3600000 IN NS k.root-servers.net.
+root-servers.net. 3600000 IN NS l.root-servers.net.
+root-servers.net. 3600000 IN NS m.root-servers.net.
+SECTION ADDITIONAL
+a.root-servers.net. 3600000 IN A 198.41.0.4
+a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30
+b.root-servers.net. 3600000 IN A 199.9.14.201
+b.root-servers.net. 3600000 IN AAAA 2001:500:200::b
+c.root-servers.net. 3600000 IN A 192.33.4.12
+c.root-servers.net. 3600000 IN AAAA 2001:500:2::c
+d.root-servers.net. 3600000 IN A 199.7.91.13
+d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d
+e.root-servers.net. 3600000 IN A 192.203.230.10
+e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e
+f.root-servers.net. 3600000 IN A 192.5.5.241
+f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f
+g.root-servers.net. 3600000 IN A 192.112.36.4
+h.root-servers.net. 3600000 IN A 198.97.190.53
+h.root-servers.net. 3600000 IN AAAA 2001:500:1::53
+i.root-servers.net. 3600000 IN A 192.36.148.17
+i.root-servers.net. 3600000 IN AAAA 2001:7fe::53
+j.root-servers.net. 3600000 IN A 192.58.128.30
+j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+l.root-servers.net. 3600000 IN A 199.7.83.42
+l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42
+m.root-servers.net. 3600000 IN A 202.12.27.33
+m.root-servers.net. 3600000 IN AAAA 2001:dc3::35
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+b.root-servers.net. IN A
+SECTION ANSWER
+b.root-servers.net. 3600000 IN A 199.9.14.201
+SECTION AUTHORITY
+root-servers.net. 3600000 IN NS a.root-servers.net.
+root-servers.net. 3600000 IN NS b.root-servers.net.
+root-servers.net. 3600000 IN NS c.root-servers.net.
+root-servers.net. 3600000 IN NS d.root-servers.net.
+root-servers.net. 3600000 IN NS e.root-servers.net.
+root-servers.net. 3600000 IN NS f.root-servers.net.
+root-servers.net. 3600000 IN NS g.root-servers.net.
+root-servers.net. 3600000 IN NS h.root-servers.net.
+root-servers.net. 3600000 IN NS i.root-servers.net.
+root-servers.net. 3600000 IN NS j.root-servers.net.
+root-servers.net. 3600000 IN NS k.root-servers.net.
+root-servers.net. 3600000 IN NS l.root-servers.net.
+root-servers.net. 3600000 IN NS m.root-servers.net.
+SECTION ADDITIONAL
+a.root-servers.net. 3600000 IN A 198.41.0.4
+a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30
+b.root-servers.net. 3600000 IN AAAA 2001:500:200::b
+c.root-servers.net. 3600000 IN A 192.33.4.12
+c.root-servers.net. 3600000 IN AAAA 2001:500:2::c
+d.root-servers.net. 3600000 IN A 199.7.91.13
+d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d
+e.root-servers.net. 3600000 IN A 192.203.230.10
+e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e
+f.root-servers.net. 3600000 IN A 192.5.5.241
+f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f
+g.root-servers.net. 3600000 IN A 192.112.36.4
+g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d
+h.root-servers.net. 3600000 IN A 198.97.190.53
+h.root-servers.net. 3600000 IN AAAA 2001:500:1::53
+i.root-servers.net. 3600000 IN A 192.36.148.17
+i.root-servers.net. 3600000 IN AAAA 2001:7fe::53
+j.root-servers.net. 3600000 IN A 192.58.128.30
+j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+l.root-servers.net. 3600000 IN A 199.7.83.42
+l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42
+m.root-servers.net. 3600000 IN A 202.12.27.33
+m.root-servers.net. 3600000 IN AAAA 2001:dc3::35
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+b.root-servers.net. IN DNSKEY
+SECTION AUTHORITY
+root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018070900 14400 7200 1209600 3600000
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+b.root-servers.net. IN NS
+SECTION AUTHORITY
+root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018070900 14400 7200 1209600 3600000
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+b.root-servers.net. IN DS
+SECTION AUTHORITY
+root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018070900 14400 7200 1209600 3600000
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+b.root-servers.net. IN AAAA
+SECTION ANSWER
+b.root-servers.net. 3600000 IN AAAA 2001:500:200::b
+SECTION AUTHORITY
+root-servers.net. 3600000 IN NS a.root-servers.net.
+root-servers.net. 3600000 IN NS b.root-servers.net.
+root-servers.net. 3600000 IN NS c.root-servers.net.
+root-servers.net. 3600000 IN NS d.root-servers.net.
+root-servers.net. 3600000 IN NS e.root-servers.net.
+root-servers.net. 3600000 IN NS f.root-servers.net.
+root-servers.net. 3600000 IN NS g.root-servers.net.
+root-servers.net. 3600000 IN NS h.root-servers.net.
+root-servers.net. 3600000 IN NS i.root-servers.net.
+root-servers.net. 3600000 IN NS j.root-servers.net.
+root-servers.net. 3600000 IN NS k.root-servers.net.
+root-servers.net. 3600000 IN NS l.root-servers.net.
+root-servers.net. 3600000 IN NS m.root-servers.net.
+SECTION ADDITIONAL
+a.root-servers.net. 3600000 IN A 198.41.0.4
+a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30
+b.root-servers.net. 3600000 IN A 199.9.14.201
+c.root-servers.net. 3600000 IN A 192.33.4.12
+c.root-servers.net. 3600000 IN AAAA 2001:500:2::c
+d.root-servers.net. 3600000 IN A 199.7.91.13
+d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d
+e.root-servers.net. 3600000 IN A 192.203.230.10
+e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e
+f.root-servers.net. 3600000 IN A 192.5.5.241
+f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f
+g.root-servers.net. 3600000 IN A 192.112.36.4
+g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d
+h.root-servers.net. 3600000 IN A 198.97.190.53
+h.root-servers.net. 3600000 IN AAAA 2001:500:1::53
+i.root-servers.net. 3600000 IN A 192.36.148.17
+i.root-servers.net. 3600000 IN AAAA 2001:7fe::53
+j.root-servers.net. 3600000 IN A 192.58.128.30
+j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+l.root-servers.net. 3600000 IN A 199.7.83.42
+l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42
+m.root-servers.net. 3600000 IN A 202.12.27.33
+m.root-servers.net. 3600000 IN AAAA 2001:dc3::35
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+k.root-servers.net. IN A
+SECTION ANSWER
+k.root-servers.net. 3600000 IN A 193.0.14.129
+SECTION AUTHORITY
+root-servers.net. 3600000 IN NS a.root-servers.net.
+root-servers.net. 3600000 IN NS b.root-servers.net.
+root-servers.net. 3600000 IN NS c.root-servers.net.
+root-servers.net. 3600000 IN NS d.root-servers.net.
+root-servers.net. 3600000 IN NS e.root-servers.net.
+root-servers.net. 3600000 IN NS f.root-servers.net.
+root-servers.net. 3600000 IN NS g.root-servers.net.
+root-servers.net. 3600000 IN NS h.root-servers.net.
+root-servers.net. 3600000 IN NS i.root-servers.net.
+root-servers.net. 3600000 IN NS j.root-servers.net.
+root-servers.net. 3600000 IN NS k.root-servers.net.
+root-servers.net. 3600000 IN NS l.root-servers.net.
+root-servers.net. 3600000 IN NS m.root-servers.net.
+SECTION ADDITIONAL
+a.root-servers.net. 3600000 IN A 198.41.0.4
+a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30
+b.root-servers.net. 3600000 IN A 199.9.14.201
+b.root-servers.net. 3600000 IN AAAA 2001:500:200::b
+c.root-servers.net. 3600000 IN A 192.33.4.12
+c.root-servers.net. 3600000 IN AAAA 2001:500:2::c
+d.root-servers.net. 3600000 IN A 199.7.91.13
+d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d
+e.root-servers.net. 3600000 IN A 192.203.230.10
+e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e
+f.root-servers.net. 3600000 IN A 192.5.5.241
+f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f
+g.root-servers.net. 3600000 IN A 192.112.36.4
+g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d
+h.root-servers.net. 3600000 IN A 198.97.190.53
+h.root-servers.net. 3600000 IN AAAA 2001:500:1::53
+i.root-servers.net. 3600000 IN A 192.36.148.17
+i.root-servers.net. 3600000 IN AAAA 2001:7fe::53
+j.root-servers.net. 3600000 IN A 192.58.128.30
+j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+l.root-servers.net. 3600000 IN A 199.7.83.42
+l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42
+m.root-servers.net. 3600000 IN A 202.12.27.33
+m.root-servers.net. 3600000 IN AAAA 2001:dc3::35
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+k.root-servers.net. IN DNSKEY
+SECTION AUTHORITY
+root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018070900 14400 7200 1209600 3600000
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+k.root-servers.net. IN NS
+SECTION AUTHORITY
+root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018070900 14400 7200 1209600 3600000
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+k.root-servers.net. IN DS
+SECTION AUTHORITY
+root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018070900 14400 7200 1209600 3600000
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+k.root-servers.net. IN AAAA
+SECTION ANSWER
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+SECTION AUTHORITY
+root-servers.net. 3600000 IN NS a.root-servers.net.
+root-servers.net. 3600000 IN NS b.root-servers.net.
+root-servers.net. 3600000 IN NS c.root-servers.net.
+root-servers.net. 3600000 IN NS d.root-servers.net.
+root-servers.net. 3600000 IN NS e.root-servers.net.
+root-servers.net. 3600000 IN NS f.root-servers.net.
+root-servers.net. 3600000 IN NS g.root-servers.net.
+root-servers.net. 3600000 IN NS h.root-servers.net.
+root-servers.net. 3600000 IN NS i.root-servers.net.
+root-servers.net. 3600000 IN NS j.root-servers.net.
+root-servers.net. 3600000 IN NS k.root-servers.net.
+root-servers.net. 3600000 IN NS l.root-servers.net.
+root-servers.net. 3600000 IN NS m.root-servers.net.
+SECTION ADDITIONAL
+a.root-servers.net. 3600000 IN A 198.41.0.4
+a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30
+b.root-servers.net. 3600000 IN A 199.9.14.201
+b.root-servers.net. 3600000 IN AAAA 2001:500:200::b
+c.root-servers.net. 3600000 IN A 192.33.4.12
+c.root-servers.net. 3600000 IN AAAA 2001:500:2::c
+d.root-servers.net. 3600000 IN A 199.7.91.13
+d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d
+e.root-servers.net. 3600000 IN A 192.203.230.10
+e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e
+f.root-servers.net. 3600000 IN A 192.5.5.241
+f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f
+g.root-servers.net. 3600000 IN A 192.112.36.4
+g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d
+h.root-servers.net. 3600000 IN A 198.97.190.53
+h.root-servers.net. 3600000 IN AAAA 2001:500:1::53
+i.root-servers.net. 3600000 IN A 192.36.148.17
+i.root-servers.net. 3600000 IN AAAA 2001:7fe::53
+j.root-servers.net. 3600000 IN A 192.58.128.30
+j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30
+k.root-servers.net. 3600000 IN A 193.0.14.129
+l.root-servers.net. 3600000 IN A 199.7.83.42
+l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42
+m.root-servers.net. 3600000 IN A 202.12.27.33
+m.root-servers.net. 3600000 IN AAAA 2001:dc3::35
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR RD NOERROR
+SECTION QUESTION
+com. IN A
+SECTION AUTHORITY
+com. 172800 IN NS a.gtld-servers.net.
+com. 172800 IN NS b.gtld-servers.net.
+com. 172800 IN NS c.gtld-servers.net.
+com. 172800 IN NS d.gtld-servers.net.
+com. 172800 IN NS e.gtld-servers.net.
+com. 172800 IN NS f.gtld-servers.net.
+com. 172800 IN NS g.gtld-servers.net.
+com. 172800 IN NS h.gtld-servers.net.
+com. 172800 IN NS i.gtld-servers.net.
+com. 172800 IN NS j.gtld-servers.net.
+com. 172800 IN NS k.gtld-servers.net.
+com. 172800 IN NS l.gtld-servers.net.
+com. 172800 IN NS m.gtld-servers.net.
+com. 86400 IN DS 30909 8 2 e2d3c916f6deeac73294e8268fb5885044a833fc5459588f4a9184cfc41a5766
+com. 86400 IN RRSIG DS 8 1 86400 20180809050000 20180727040000 41656 . eGyv2a7tzQdljtzCX0sF211why7uD3PI c1rSQxJKfd0AbhZKvcl6jQW+rRHHQHui ljjsXG1fp35P7P02269xj5Hbu2eNV5vr jRdXTzAQ+waZZHBn87mNOiURZwh0sG44 7XQYdpkC656acDJ8TP6Szox1gCkBo6eM /SquL8Jmtl6IQSszxT71auHUytVRL8NR bv57T/PXQ9fSAjq5+lgZ7ZVvCs6sVjRl KvtaGLixnb7pR9C08jLWA/j2jAG0RBV2 pOz7BVDm7V34FIjJ9yd8BbSKeEJFcQWl m9x26nQREBmpKp8AmUiUoxfyuZvMxu// EGVxIEh71OHxT46+AhCipg==
+SECTION ADDITIONAL
+a.gtld-servers.net. 172800 IN A 192.5.6.30
+a.gtld-servers.net. 172800 IN AAAA 2001:503:a83e::2:30
+b.gtld-servers.net. 172800 IN A 192.33.14.30
+b.gtld-servers.net. 172800 IN AAAA 2001:503:231d::2:30
+c.gtld-servers.net. 172800 IN A 192.26.92.30
+c.gtld-servers.net. 172800 IN AAAA 2001:503:83eb::30
+d.gtld-servers.net. 172800 IN A 192.31.80.30
+d.gtld-servers.net. 172800 IN AAAA 2001:500:856e::30
+e.gtld-servers.net. 172800 IN A 192.12.94.30
+e.gtld-servers.net. 172800 IN AAAA 2001:502:1ca1::30
+f.gtld-servers.net. 172800 IN A 192.35.51.30
+f.gtld-servers.net. 172800 IN AAAA 2001:503:d414::30
+g.gtld-servers.net. 172800 IN A 192.42.93.30
+g.gtld-servers.net. 172800 IN AAAA 2001:503:eea3::30
+h.gtld-servers.net. 172800 IN A 192.54.112.30
+h.gtld-servers.net. 172800 IN AAAA 2001:502:8cc::30
+i.gtld-servers.net. 172800 IN A 192.43.172.30
+i.gtld-servers.net. 172800 IN AAAA 2001:503:39c1::30
+j.gtld-servers.net. 172800 IN A 192.48.79.30
+j.gtld-servers.net. 172800 IN AAAA 2001:502:7094::30
+k.gtld-servers.net. 172800 IN A 192.52.178.30
+k.gtld-servers.net. 172800 IN AAAA 2001:503:d2d::30
+l.gtld-servers.net. 172800 IN A 192.41.162.30
+l.gtld-servers.net. 172800 IN AAAA 2001:500:d937::30
+m.gtld-servers.net. 172800 IN A 192.55.83.30
+m.gtld-servers.net. 172800 IN AAAA 2001:501:b1f9::30
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR RD NOERROR
+SECTION QUESTION
+com. IN DNSKEY
+SECTION AUTHORITY
+com. 172800 IN NS a.gtld-servers.net.
+com. 172800 IN NS b.gtld-servers.net.
+com. 172800 IN NS c.gtld-servers.net.
+com. 172800 IN NS d.gtld-servers.net.
+com. 172800 IN NS e.gtld-servers.net.
+com. 172800 IN NS f.gtld-servers.net.
+com. 172800 IN NS g.gtld-servers.net.
+com. 172800 IN NS h.gtld-servers.net.
+com. 172800 IN NS i.gtld-servers.net.
+com. 172800 IN NS j.gtld-servers.net.
+com. 172800 IN NS k.gtld-servers.net.
+com. 172800 IN NS l.gtld-servers.net.
+com. 172800 IN NS m.gtld-servers.net.
+com. 86400 IN DS 30909 8 2 e2d3c916f6deeac73294e8268fb5885044a833fc5459588f4a9184cfc41a5766
+com. 86400 IN RRSIG DS 8 1 86400 20180809050000 20180727040000 41656 . eGyv2a7tzQdljtzCX0sF211why7uD3PI c1rSQxJKfd0AbhZKvcl6jQW+rRHHQHui ljjsXG1fp35P7P02269xj5Hbu2eNV5vr jRdXTzAQ+waZZHBn87mNOiURZwh0sG44 7XQYdpkC656acDJ8TP6Szox1gCkBo6eM /SquL8Jmtl6IQSszxT71auHUytVRL8NR bv57T/PXQ9fSAjq5+lgZ7ZVvCs6sVjRl KvtaGLixnb7pR9C08jLWA/j2jAG0RBV2 pOz7BVDm7V34FIjJ9yd8BbSKeEJFcQWl m9x26nQREBmpKp8AmUiUoxfyuZvMxu// EGVxIEh71OHxT46+AhCipg==
+SECTION ADDITIONAL
+a.gtld-servers.net. 172800 IN A 192.5.6.30
+a.gtld-servers.net. 172800 IN AAAA 2001:503:a83e::2:30
+b.gtld-servers.net. 172800 IN A 192.33.14.30
+b.gtld-servers.net. 172800 IN AAAA 2001:503:231d::2:30
+c.gtld-servers.net. 172800 IN A 192.26.92.30
+c.gtld-servers.net. 172800 IN AAAA 2001:503:83eb::30
+d.gtld-servers.net. 172800 IN A 192.31.80.30
+d.gtld-servers.net. 172800 IN AAAA 2001:500:856e::30
+e.gtld-servers.net. 172800 IN A 192.12.94.30
+e.gtld-servers.net. 172800 IN AAAA 2001:502:1ca1::30
+f.gtld-servers.net. 172800 IN A 192.35.51.30
+f.gtld-servers.net. 172800 IN AAAA 2001:503:d414::30
+g.gtld-servers.net. 172800 IN A 192.42.93.30
+g.gtld-servers.net. 172800 IN AAAA 2001:503:eea3::30
+h.gtld-servers.net. 172800 IN A 192.54.112.30
+h.gtld-servers.net. 172800 IN AAAA 2001:502:8cc::30
+i.gtld-servers.net. 172800 IN A 192.43.172.30
+i.gtld-servers.net. 172800 IN AAAA 2001:503:39c1::30
+j.gtld-servers.net. 172800 IN A 192.48.79.30
+j.gtld-servers.net. 172800 IN AAAA 2001:502:7094::30
+k.gtld-servers.net. 172800 IN A 192.52.178.30
+k.gtld-servers.net. 172800 IN AAAA 2001:503:d2d::30
+l.gtld-servers.net. 172800 IN A 192.41.162.30
+l.gtld-servers.net. 172800 IN AAAA 2001:500:d937::30
+m.gtld-servers.net. 172800 IN A 192.55.83.30
+m.gtld-servers.net. 172800 IN AAAA 2001:501:b1f9::30
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+com. IN DS
+SECTION ANSWER
+com. 86400 IN DS 30909 8 2 e2d3c916f6deeac73294e8268fb5885044a833fc5459588f4a9184cfc41a5766
+com. 86400 IN RRSIG DS 8 1 86400 20180809050000 20180727040000 41656 . eGyv2a7tzQdljtzCX0sF211why7uD3PI c1rSQxJKfd0AbhZKvcl6jQW+rRHHQHui ljjsXG1fp35P7P02269xj5Hbu2eNV5vr jRdXTzAQ+waZZHBn87mNOiURZwh0sG44 7XQYdpkC656acDJ8TP6Szox1gCkBo6eM /SquL8Jmtl6IQSszxT71auHUytVRL8NR bv57T/PXQ9fSAjq5+lgZ7ZVvCs6sVjRl KvtaGLixnb7pR9C08jLWA/j2jAG0RBV2 pOz7BVDm7V34FIjJ9yd8BbSKeEJFcQWl m9x26nQREBmpKp8AmUiUoxfyuZvMxu// EGVxIEh71OHxT46+AhCipg==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+root-servers.net. IN DNSKEY
+SECTION AUTHORITY
+root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018070900 14400 7200 1209600 3600000
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH subdomain
+ADJUST copy_id copy_query
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+root-servers.net. IN NS
+SECTION ANSWER
+root-servers.net. 3600000 IN NS a.root-servers.net.
+root-servers.net. 3600000 IN NS b.root-servers.net.
+root-servers.net. 3600000 IN NS c.root-servers.net.
+root-servers.net. 3600000 IN NS d.root-servers.net.
+root-servers.net. 3600000 IN NS e.root-servers.net.
+root-servers.net. 3600000 IN NS f.root-servers.net.
+root-servers.net. 3600000 IN NS g.root-servers.net.
+root-servers.net. 3600000 IN NS h.root-servers.net.
+root-servers.net. 3600000 IN NS i.root-servers.net.
+root-servers.net. 3600000 IN NS j.root-servers.net.
+root-servers.net. 3600000 IN NS k.root-servers.net.
+root-servers.net. 3600000 IN NS l.root-servers.net.
+root-servers.net. 3600000 IN NS m.root-servers.net.
+SECTION ADDITIONAL
+a.root-servers.net. 3600000 IN A 198.41.0.4
+a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30
+b.root-servers.net. 3600000 IN A 199.9.14.201
+b.root-servers.net. 3600000 IN AAAA 2001:500:200::b
+c.root-servers.net. 3600000 IN A 192.33.4.12
+c.root-servers.net. 3600000 IN AAAA 2001:500:2::c
+d.root-servers.net. 3600000 IN A 199.7.91.13
+d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d
+e.root-servers.net. 3600000 IN A 192.203.230.10
+e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e
+f.root-servers.net. 3600000 IN A 192.5.5.241
+f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f
+g.root-servers.net. 3600000 IN A 192.112.36.4
+g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d
+h.root-servers.net. 3600000 IN A 198.97.190.53
+h.root-servers.net. 3600000 IN AAAA 2001:500:1::53
+i.root-servers.net. 3600000 IN A 192.36.148.17
+i.root-servers.net. 3600000 IN AAAA 2001:7fe::53
+j.root-servers.net. 3600000 IN A 192.58.128.30
+j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+l.root-servers.net. 3600000 IN A 199.7.83.42
+l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42
+m.root-servers.net. 3600000 IN A 202.12.27.33
+m.root-servers.net. 3600000 IN AAAA 2001:dc3::35
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH subdomain
+ADJUST copy_id copy_query
+REPLY QR RD NOERROR
+SECTION QUESTION
+cz. IN NS
+SECTION AUTHORITY
+cz. 172800 IN NS a.ns.nic.cz.
+cz. 172800 IN NS b.ns.nic.cz.
+cz. 172800 IN NS c.ns.nic.cz.
+cz. 172800 IN NS d.ns.nic.cz.
+cz. 86400 IN DS 20237 13 2 cff0f3ecdbc529c1f0031ba1840bfb835853b9209ed1e508fff48451d7b778e2
+cz. 86400 IN RRSIG DS 8 1 86400 20180809050000 20180727040000 41656 . BkGaXhVOBlSGZkRo6m6xYxeXSEIqVZKa 7wHxKdNn+6F/DDJoD0aEgEg6H7yhjKs2 tt4uyp9l8/L8r/mWoFPjYsSsQgc2hpxJ Ql2wTDRNaRpQ+spbiefndoyr1/5YBMFv mItzzMSg93ekx3gebfVqMpe0fpvs7NjA +33vGJO3e3ficaYDIf9HY/npnHgjOtpE wiFPYmLTb+zLlIHd4hhXOXg/Kv5CNGvN aBdBE2s2GXJbYI3Zd5FDHxhZ+qLuhL5J qjtrGDokRgM0Jk8dDroIk0yQHfNU022s ZAhIeEZJhwiuh4bNuJJCKoB+a5UIiNx+ rCUU2ntIsqLbxbnpKLamow==
+SECTION ADDITIONAL
+a.ns.nic.cz. 172800 IN A 194.0.12.1
+a.ns.nic.cz. 172800 IN AAAA 2001:678:f::1
+b.ns.nic.cz. 172800 IN A 194.0.13.1
+b.ns.nic.cz. 172800 IN AAAA 2001:678:10::1
+c.ns.nic.cz. 172800 IN A 194.0.14.1
+c.ns.nic.cz. 172800 IN AAAA 2001:678:11::1
+d.ns.nic.cz. 172800 IN A 193.29.206.1
+d.ns.nic.cz. 172800 IN AAAA 2001:678:1::1
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH subdomain
+ADJUST copy_id copy_query
+REPLY QR RD NOERROR
+SECTION QUESTION
+net. IN NS
+SECTION AUTHORITY
+net. 172800 IN NS a.gtld-servers.net.
+net. 172800 IN NS b.gtld-servers.net.
+net. 172800 IN NS c.gtld-servers.net.
+net. 172800 IN NS d.gtld-servers.net.
+net. 172800 IN NS e.gtld-servers.net.
+net. 172800 IN NS f.gtld-servers.net.
+net. 172800 IN NS g.gtld-servers.net.
+net. 172800 IN NS h.gtld-servers.net.
+net. 172800 IN NS i.gtld-servers.net.
+net. 172800 IN NS j.gtld-servers.net.
+net. 172800 IN NS k.gtld-servers.net.
+net. 172800 IN NS l.gtld-servers.net.
+net. 172800 IN NS m.gtld-servers.net.
+net. 86400 IN DS 35886 8 2 7862b27f5f516ebe19680444d4ce5e762981931842c465f00236401d8bd973ee
+net. 86400 IN RRSIG DS 8 1 86400 20180809050000 20180727040000 41656 . 0Uvgipa8bRqTwVpcmpPngKx1brdQ0rIB H8QbEl4KyFE+CI8nB3jNk9rHF15WYQm1 Xov0E1uCMvYfv1w96LvC+N4w7hPsCpgG sK3+pT90vhsLRqoP7dws5MU0fsXfpmGP X3utMPZGwk7JDSUhQAbIWiCD81JAi05y I5xbaeveUSSvMbyXJKyzsbHWVP6997BX 4Las1O8H/1Eds743+Cfc5hPULqH5ZUWB EPIKN+MZQM9DjmgUUJSlktWQwK42BeXU 9O4DUGP2oxwbQ8uw4PlRhhxYp3UCP9b5 B2d4fqlaalhiPY86u7TkzEbEJJlW2tf+ 3bGAiX9a9icfbsrdS9hsuw==
+SECTION ADDITIONAL
+a.gtld-servers.net. 172800 IN A 192.5.6.30
+a.gtld-servers.net. 172800 IN AAAA 2001:503:a83e::2:30
+b.gtld-servers.net. 172800 IN A 192.33.14.30
+b.gtld-servers.net. 172800 IN AAAA 2001:503:231d::2:30
+c.gtld-servers.net. 172800 IN A 192.26.92.30
+c.gtld-servers.net. 172800 IN AAAA 2001:503:83eb::30
+d.gtld-servers.net. 172800 IN A 192.31.80.30
+d.gtld-servers.net. 172800 IN AAAA 2001:500:856e::30
+e.gtld-servers.net. 172800 IN A 192.12.94.30
+e.gtld-servers.net. 172800 IN AAAA 2001:502:1ca1::30
+f.gtld-servers.net. 172800 IN A 192.35.51.30
+f.gtld-servers.net. 172800 IN AAAA 2001:503:d414::30
+g.gtld-servers.net. 172800 IN A 192.42.93.30
+g.gtld-servers.net. 172800 IN AAAA 2001:503:eea3::30
+h.gtld-servers.net. 172800 IN A 192.54.112.30
+h.gtld-servers.net. 172800 IN AAAA 2001:502:8cc::30
+i.gtld-servers.net. 172800 IN A 192.43.172.30
+i.gtld-servers.net. 172800 IN AAAA 2001:503:39c1::30
+j.gtld-servers.net. 172800 IN A 192.48.79.30
+j.gtld-servers.net. 172800 IN AAAA 2001:502:7094::30
+k.gtld-servers.net. 172800 IN A 192.52.178.30
+k.gtld-servers.net. 172800 IN AAAA 2001:503:d2d::30
+l.gtld-servers.net. 172800 IN A 192.41.162.30
+l.gtld-servers.net. 172800 IN AAAA 2001:500:d937::30
+m.gtld-servers.net. 172800 IN A 192.55.83.30
+m.gtld-servers.net. 172800 IN AAAA 2001:501:b1f9::30
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH subdomain
+ADJUST copy_id copy_query
+REPLY QR RD NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION AUTHORITY
+com. 172800 IN NS a.gtld-servers.net.
+com. 172800 IN NS b.gtld-servers.net.
+com. 172800 IN NS c.gtld-servers.net.
+com. 172800 IN NS d.gtld-servers.net.
+com. 172800 IN NS e.gtld-servers.net.
+com. 172800 IN NS f.gtld-servers.net.
+com. 172800 IN NS g.gtld-servers.net.
+com. 172800 IN NS h.gtld-servers.net.
+com. 172800 IN NS i.gtld-servers.net.
+com. 172800 IN NS j.gtld-servers.net.
+com. 172800 IN NS k.gtld-servers.net.
+com. 172800 IN NS l.gtld-servers.net.
+com. 172800 IN NS m.gtld-servers.net.
+com. 86400 IN DS 30909 8 2 e2d3c916f6deeac73294e8268fb5885044a833fc5459588f4a9184cfc41a5766
+com. 86400 IN RRSIG DS 8 1 86400 20180809050000 20180727040000 41656 . eGyv2a7tzQdljtzCX0sF211why7uD3PI c1rSQxJKfd0AbhZKvcl6jQW+rRHHQHui ljjsXG1fp35P7P02269xj5Hbu2eNV5vr jRdXTzAQ+waZZHBn87mNOiURZwh0sG44 7XQYdpkC656acDJ8TP6Szox1gCkBo6eM /SquL8Jmtl6IQSszxT71auHUytVRL8NR bv57T/PXQ9fSAjq5+lgZ7ZVvCs6sVjRl KvtaGLixnb7pR9C08jLWA/j2jAG0RBV2 pOz7BVDm7V34FIjJ9yd8BbSKeEJFcQWl m9x26nQREBmpKp8AmUiUoxfyuZvMxu// EGVxIEh71OHxT46+AhCipg==
+SECTION ADDITIONAL
+a.gtld-servers.net. 172800 IN A 192.5.6.30
+a.gtld-servers.net. 172800 IN AAAA 2001:503:a83e::2:30
+b.gtld-servers.net. 172800 IN A 192.33.14.30
+b.gtld-servers.net. 172800 IN AAAA 2001:503:231d::2:30
+c.gtld-servers.net. 172800 IN A 192.26.92.30
+c.gtld-servers.net. 172800 IN AAAA 2001:503:83eb::30
+d.gtld-servers.net. 172800 IN A 192.31.80.30
+d.gtld-servers.net. 172800 IN AAAA 2001:500:856e::30
+e.gtld-servers.net. 172800 IN A 192.12.94.30
+e.gtld-servers.net. 172800 IN AAAA 2001:502:1ca1::30
+f.gtld-servers.net. 172800 IN A 192.35.51.30
+f.gtld-servers.net. 172800 IN AAAA 2001:503:d414::30
+g.gtld-servers.net. 172800 IN A 192.42.93.30
+g.gtld-servers.net. 172800 IN AAAA 2001:503:eea3::30
+h.gtld-servers.net. 172800 IN A 192.54.112.30
+h.gtld-servers.net. 172800 IN AAAA 2001:502:8cc::30
+i.gtld-servers.net. 172800 IN A 192.43.172.30
+i.gtld-servers.net. 172800 IN AAAA 2001:503:39c1::30
+j.gtld-servers.net. 172800 IN A 192.48.79.30
+j.gtld-servers.net. 172800 IN AAAA 2001:502:7094::30
+k.gtld-servers.net. 172800 IN A 192.52.178.30
+k.gtld-servers.net. 172800 IN AAAA 2001:503:d2d::30
+l.gtld-servers.net. 172800 IN A 192.41.162.30
+l.gtld-servers.net. 172800 IN AAAA 2001:500:d937::30
+m.gtld-servers.net. 172800 IN A 192.55.83.30
+m.gtld-servers.net. 172800 IN AAAA 2001:501:b1f9::30
+ENTRY_END
+
+
+RANGE_END
+
+
+; Scope "com.
+
+; Server names:
+; a.gtld-servers.net.
+; j.gtld-servers.net.
+; e.gtld-servers.net.
+; i.gtld-servers.net.
+; d.gtld-servers.net.
+; m.gtld-servers.net.
+; h.gtld-servers.net.
+; c.gtld-servers.net.
+; l.gtld-servers.net.
+; g.gtld-servers.net.
+; b.gtld-servers.net.
+; k.gtld-servers.net.
+; f.gtld-servers.net.
+RANGE_BEGIN 0 1000
+ ADDRESS 2001:503:d2d::30
+ ADDRESS 192.31.80.30
+ ADDRESS 2001:502:7094::30
+ ADDRESS 2001:501:b1f9::30
+ ADDRESS 192.35.51.30
+ ADDRESS 2001:503:39c1::30
+ ADDRESS 2001:502:1ca1::30
+ ADDRESS 2001:503:a83e::2:30
+ ADDRESS 192.55.83.30
+ ADDRESS 192.26.92.30
+ ADDRESS 2001:503:eea3::30
+ ADDRESS 192.12.94.30
+ ADDRESS 192.42.93.30
+ ADDRESS 2001:502:8cc::30
+ ADDRESS 2001:503:d414::30
+ ADDRESS 2001:503:83eb::30
+ ADDRESS 192.52.178.30
+ ADDRESS 192.54.112.30
+ ADDRESS 2001:500:856e::30
+ ADDRESS 192.5.6.30
+ ADDRESS 192.41.162.30
+ ADDRESS 192.43.172.30
+ ADDRESS 192.48.79.30
+ ADDRESS 192.33.14.30
+ ADDRESS 2001:500:d937::30
+ ADDRESS 2001:503:231d::2:30
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR RD NOERROR
+SECTION QUESTION
+root-servers.net. IN A
+SECTION AUTHORITY
+A1RT98BS5QGC9NFI51S9HCI47ULJG6JH.net. 86400 IN NSEC3 1 1 0 - a1ruuffjkct2q54p78f8ejgj8jbk7i8b NS SOA RRSIG DNSKEY NSEC3PARAM
+A1RT98BS5QGC9NFI51S9HCI47ULJG6JH.net. 86400 IN RRSIG NSEC3 8 2 86400 20180731053505 20180724042505 7934 net. aQ1+tOFuT3esonx3VUVqcQGwUlcby0Wa Rit1P1ikFjowshfV9AUsn/bkka2dFgxC PgDtmMiQ6TzAKiwciFJ5mZitfFZSEoS/ Z3pnsZsvB062GrKNup9+x4SBiRB3HH8T xMMd6sVV9LjOE2iOm4ekIUHieMwJjfnY 7yG7obH6OFI=
+T2UF21DR03E0BNPB42UQMVUF38P2TA8D.net. 86400 IN NSEC3 1 1 0 - t2ukct9k5i0uhv7b3m3na6jaigdjm0gr NS DS RRSIG
+T2UF21DR03E0BNPB42UQMVUF38P2TA8D.net. 86400 IN RRSIG NSEC3 8 2 86400 20180802052514 20180726041514 7934 net. LDVOVqnK+2HRKN6dUmVP3pP2RE0dCKTQ oE0d2w1AiDAOhn3Ye9Aq0yUjkz+frcUj ZqvTdiC58q0mXpyLUbqWiGmazUVG5qT7 zx5mhp1Leetq1wVJH8KGYLEmTstTCT56 oMbtWugGmZeY2B47rCsCeaWPNdH/b8qb UrwpfdPbhJE=
+root-servers.net. 172800 IN NS a.root-servers.net.
+root-servers.net. 172800 IN NS b.root-servers.net.
+root-servers.net. 172800 IN NS c.root-servers.net.
+root-servers.net. 172800 IN NS d.root-servers.net.
+root-servers.net. 172800 IN NS e.root-servers.net.
+root-servers.net. 172800 IN NS f.root-servers.net.
+root-servers.net. 172800 IN NS g.root-servers.net.
+root-servers.net. 172800 IN NS h.root-servers.net.
+root-servers.net. 172800 IN NS i.root-servers.net.
+root-servers.net. 172800 IN NS j.root-servers.net.
+root-servers.net. 172800 IN NS k.root-servers.net.
+root-servers.net. 172800 IN NS l.root-servers.net.
+root-servers.net. 172800 IN NS m.root-servers.net.
+SECTION ADDITIONAL
+a.root-servers.net. 172800 IN A 198.41.0.4
+a.root-servers.net. 172800 IN AAAA 2001:503:ba3e::2:30
+b.root-servers.net. 172800 IN A 199.9.14.201
+b.root-servers.net. 172800 IN AAAA 2001:500:200::b
+c.root-servers.net. 172800 IN A 192.33.4.12
+c.root-servers.net. 172800 IN AAAA 2001:500:2::c
+d.root-servers.net. 172800 IN A 199.7.91.13
+d.root-servers.net. 172800 IN AAAA 2001:500:2d::d
+e.root-servers.net. 172800 IN A 192.203.230.10
+e.root-servers.net. 172800 IN AAAA 2001:500:a8::e
+f.root-servers.net. 172800 IN A 192.5.5.241
+f.root-servers.net. 172800 IN AAAA 2001:500:2f::f
+g.root-servers.net. 172800 IN A 192.112.36.4
+g.root-servers.net. 172800 IN AAAA 2001:500:12::d0d
+h.root-servers.net. 172800 IN A 198.97.190.53
+h.root-servers.net. 172800 IN AAAA 2001:500:1::53
+i.root-servers.net. 172800 IN A 192.36.148.17
+i.root-servers.net. 172800 IN AAAA 2001:7fe::53
+j.root-servers.net. 172800 IN A 192.58.128.30
+j.root-servers.net. 172800 IN AAAA 2001:503:c27::2:30
+k.root-servers.net. 172800 IN A 193.0.14.129
+k.root-servers.net. 172800 IN AAAA 2001:7fd::1
+l.root-servers.net. 172800 IN A 199.7.83.42
+l.root-servers.net. 172800 IN AAAA 2001:500:9f::42
+m.root-servers.net. 172800 IN A 202.12.27.33
+m.root-servers.net. 172800 IN AAAA 2001:dc3::35
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR RD NOERROR
+SECTION QUESTION
+root-servers.net. IN DNSKEY
+SECTION AUTHORITY
+A1RT98BS5QGC9NFI51S9HCI47ULJG6JH.net. 86400 IN NSEC3 1 1 0 - a1ruuffjkct2q54p78f8ejgj8jbk7i8b NS SOA RRSIG DNSKEY NSEC3PARAM
+A1RT98BS5QGC9NFI51S9HCI47ULJG6JH.net. 86400 IN RRSIG NSEC3 8 2 86400 20180731053505 20180724042505 7934 net. aQ1+tOFuT3esonx3VUVqcQGwUlcby0Wa Rit1P1ikFjowshfV9AUsn/bkka2dFgxC PgDtmMiQ6TzAKiwciFJ5mZitfFZSEoS/ Z3pnsZsvB062GrKNup9+x4SBiRB3HH8T xMMd6sVV9LjOE2iOm4ekIUHieMwJjfnY 7yG7obH6OFI=
+T2UF21DR03E0BNPB42UQMVUF38P2TA8D.net. 86400 IN NSEC3 1 1 0 - t2ukct9k5i0uhv7b3m3na6jaigdjm0gr NS DS RRSIG
+T2UF21DR03E0BNPB42UQMVUF38P2TA8D.net. 86400 IN RRSIG NSEC3 8 2 86400 20180802052514 20180726041514 7934 net. LDVOVqnK+2HRKN6dUmVP3pP2RE0dCKTQ oE0d2w1AiDAOhn3Ye9Aq0yUjkz+frcUj ZqvTdiC58q0mXpyLUbqWiGmazUVG5qT7 zx5mhp1Leetq1wVJH8KGYLEmTstTCT56 oMbtWugGmZeY2B47rCsCeaWPNdH/b8qb UrwpfdPbhJE=
+root-servers.net. 172800 IN NS a.root-servers.net.
+root-servers.net. 172800 IN NS b.root-servers.net.
+root-servers.net. 172800 IN NS c.root-servers.net.
+root-servers.net. 172800 IN NS d.root-servers.net.
+root-servers.net. 172800 IN NS e.root-servers.net.
+root-servers.net. 172800 IN NS f.root-servers.net.
+root-servers.net. 172800 IN NS g.root-servers.net.
+root-servers.net. 172800 IN NS h.root-servers.net.
+root-servers.net. 172800 IN NS i.root-servers.net.
+root-servers.net. 172800 IN NS j.root-servers.net.
+root-servers.net. 172800 IN NS k.root-servers.net.
+root-servers.net. 172800 IN NS l.root-servers.net.
+root-servers.net. 172800 IN NS m.root-servers.net.
+SECTION ADDITIONAL
+a.root-servers.net. 172800 IN A 198.41.0.4
+a.root-servers.net. 172800 IN AAAA 2001:503:ba3e::2:30
+b.root-servers.net. 172800 IN A 199.9.14.201
+b.root-servers.net. 172800 IN AAAA 2001:500:200::b
+c.root-servers.net. 172800 IN A 192.33.4.12
+c.root-servers.net. 172800 IN AAAA 2001:500:2::c
+d.root-servers.net. 172800 IN A 199.7.91.13
+d.root-servers.net. 172800 IN AAAA 2001:500:2d::d
+e.root-servers.net. 172800 IN A 192.203.230.10
+e.root-servers.net. 172800 IN AAAA 2001:500:a8::e
+f.root-servers.net. 172800 IN A 192.5.5.241
+f.root-servers.net. 172800 IN AAAA 2001:500:2f::f
+g.root-servers.net. 172800 IN A 192.112.36.4
+g.root-servers.net. 172800 IN AAAA 2001:500:12::d0d
+h.root-servers.net. 172800 IN A 198.97.190.53
+h.root-servers.net. 172800 IN AAAA 2001:500:1::53
+i.root-servers.net. 172800 IN A 192.36.148.17
+i.root-servers.net. 172800 IN AAAA 2001:7fe::53
+j.root-servers.net. 172800 IN A 192.58.128.30
+j.root-servers.net. 172800 IN AAAA 2001:503:c27::2:30
+k.root-servers.net. 172800 IN A 193.0.14.129
+k.root-servers.net. 172800 IN AAAA 2001:7fd::1
+l.root-servers.net. 172800 IN A 199.7.83.42
+l.root-servers.net. 172800 IN AAAA 2001:500:9f::42
+m.root-servers.net. 172800 IN A 202.12.27.33
+m.root-servers.net. 172800 IN AAAA 2001:dc3::35
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+root-servers.net. IN DS
+SECTION AUTHORITY
+A1RT98BS5QGC9NFI51S9HCI47ULJG6JH.net. 86400 IN NSEC3 1 1 0 - a1ruuffjkct2q54p78f8ejgj8jbk7i8b NS SOA RRSIG DNSKEY NSEC3PARAM
+A1RT98BS5QGC9NFI51S9HCI47ULJG6JH.net. 86400 IN RRSIG NSEC3 8 2 86400 20180731053505 20180724042505 7934 net. aQ1+tOFuT3esonx3VUVqcQGwUlcby0Wa Rit1P1ikFjowshfV9AUsn/bkka2dFgxC PgDtmMiQ6TzAKiwciFJ5mZitfFZSEoS/ Z3pnsZsvB062GrKNup9+x4SBiRB3HH8T xMMd6sVV9LjOE2iOm4ekIUHieMwJjfnY 7yG7obH6OFI=
+T2UF21DR03E0BNPB42UQMVUF38P2TA8D.net. 86400 IN NSEC3 1 1 0 - t2ukct9k5i0uhv7b3m3na6jaigdjm0gr NS DS RRSIG
+T2UF21DR03E0BNPB42UQMVUF38P2TA8D.net. 86400 IN RRSIG NSEC3 8 2 86400 20180802052514 20180726041514 7934 net. LDVOVqnK+2HRKN6dUmVP3pP2RE0dCKTQ oE0d2w1AiDAOhn3Ye9Aq0yUjkz+frcUj ZqvTdiC58q0mXpyLUbqWiGmazUVG5qT7 zx5mhp1Leetq1wVJH8KGYLEmTstTCT56 oMbtWugGmZeY2B47rCsCeaWPNdH/b8qb UrwpfdPbhJE=
+net. 900 IN RRSIG SOA 8 1 900 20180803084842 20180727073842 7934 net. GaMDNiWJZrDpU6uLTjDm3xG9RH1Ltojc knesMgzdxlcYAtennPH8HUtc3lsCIKUI 0uU22sXG/dSakls2ihWIrPXm13mGjYio UdCPTCEHyBApbe5Xh6m+wMWlbI8yxSYy b6bFCsH/2fgLlGHZ7DwQy+Cji5d/1H8x iTDVF1WfLvo=
+net. 900 IN SOA a.gtld-servers.net. nstld.verisign-grs.com. 1532681322 1800 900 604800 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR RD NOERROR
+SECTION QUESTION
+gtld-servers.net. IN A
+SECTION AUTHORITY
+5QD8VL68T2I9KOBD32KJ8LJVH5OH2PQ0.net. 86400 IN NSEC3 1 1 0 - 5qdppotuk27kkp9ligtrb0k1cbvm9cim NS DS RRSIG
+5QD8VL68T2I9KOBD32KJ8LJVH5OH2PQ0.net. 86400 IN RRSIG NSEC3 8 2 86400 20180801102320 20180725091320 7934 net. ZKWDEle0ZQbeLFqJNnGWN9zZNZ4qXpns WEmuTMy1Ou9IRpBl0YU1RQRdjRJ4aFWM 5Kcl/UIOgeN4yD+B8HludqzhxRGDxqZ1 N1ObndmMNLbokcgyIYVnmhoe3doOnedK KRU5F6YcJpEOQ4jcJsjQd9ekQTB9aBP3 j33L4T3A1PM=
+A1RT98BS5QGC9NFI51S9HCI47ULJG6JH.net. 86400 IN NSEC3 1 1 0 - a1ruuffjkct2q54p78f8ejgj8jbk7i8b NS SOA RRSIG DNSKEY NSEC3PARAM
+A1RT98BS5QGC9NFI51S9HCI47ULJG6JH.net. 86400 IN RRSIG NSEC3 8 2 86400 20180731053505 20180724042505 7934 net. aQ1+tOFuT3esonx3VUVqcQGwUlcby0Wa Rit1P1ikFjowshfV9AUsn/bkka2dFgxC PgDtmMiQ6TzAKiwciFJ5mZitfFZSEoS/ Z3pnsZsvB062GrKNup9+x4SBiRB3HH8T xMMd6sVV9LjOE2iOm4ekIUHieMwJjfnY 7yG7obH6OFI=
+gtld-servers.net. 172800 IN NS av1.nstld.com.
+gtld-servers.net. 172800 IN NS av2.nstld.com.
+gtld-servers.net. 172800 IN NS av3.nstld.com.
+gtld-servers.net. 172800 IN NS av4.nstld.com.
+SECTION ADDITIONAL
+av1.nstld.com. 172800 IN A 192.42.177.30
+av1.nstld.com. 172800 IN AAAA 2001:500:124::30
+av2.nstld.com. 172800 IN A 192.42.178.30
+av2.nstld.com. 172800 IN AAAA 2001:500:125::30
+av3.nstld.com. 172800 IN A 192.82.133.30
+av3.nstld.com. 172800 IN AAAA 2001:500:126::30
+av4.nstld.com. 172800 IN A 192.82.134.30
+av4.nstld.com. 172800 IN AAAA 2001:500:127::30
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR RD NOERROR
+SECTION QUESTION
+gtld-servers.net. IN DNSKEY
+SECTION AUTHORITY
+5QD8VL68T2I9KOBD32KJ8LJVH5OH2PQ0.net. 86400 IN NSEC3 1 1 0 - 5qdppotuk27kkp9ligtrb0k1cbvm9cim NS DS RRSIG
+5QD8VL68T2I9KOBD32KJ8LJVH5OH2PQ0.net. 86400 IN RRSIG NSEC3 8 2 86400 20180801102320 20180725091320 7934 net. ZKWDEle0ZQbeLFqJNnGWN9zZNZ4qXpns WEmuTMy1Ou9IRpBl0YU1RQRdjRJ4aFWM 5Kcl/UIOgeN4yD+B8HludqzhxRGDxqZ1 N1ObndmMNLbokcgyIYVnmhoe3doOnedK KRU5F6YcJpEOQ4jcJsjQd9ekQTB9aBP3 j33L4T3A1PM=
+A1RT98BS5QGC9NFI51S9HCI47ULJG6JH.net. 86400 IN NSEC3 1 1 0 - a1ruuffjkct2q54p78f8ejgj8jbk7i8b NS SOA RRSIG DNSKEY NSEC3PARAM
+A1RT98BS5QGC9NFI51S9HCI47ULJG6JH.net. 86400 IN RRSIG NSEC3 8 2 86400 20180731053505 20180724042505 7934 net. aQ1+tOFuT3esonx3VUVqcQGwUlcby0Wa Rit1P1ikFjowshfV9AUsn/bkka2dFgxC PgDtmMiQ6TzAKiwciFJ5mZitfFZSEoS/ Z3pnsZsvB062GrKNup9+x4SBiRB3HH8T xMMd6sVV9LjOE2iOm4ekIUHieMwJjfnY 7yG7obH6OFI=
+gtld-servers.net. 172800 IN NS av1.nstld.com.
+gtld-servers.net. 172800 IN NS av2.nstld.com.
+gtld-servers.net. 172800 IN NS av3.nstld.com.
+gtld-servers.net. 172800 IN NS av4.nstld.com.
+SECTION ADDITIONAL
+av1.nstld.com. 172800 IN A 192.42.177.30
+av1.nstld.com. 172800 IN AAAA 2001:500:124::30
+av2.nstld.com. 172800 IN A 192.42.178.30
+av2.nstld.com. 172800 IN AAAA 2001:500:125::30
+av3.nstld.com. 172800 IN A 192.82.133.30
+av3.nstld.com. 172800 IN AAAA 2001:500:126::30
+av4.nstld.com. 172800 IN A 192.82.134.30
+av4.nstld.com. 172800 IN AAAA 2001:500:127::30
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+gtld-servers.net. IN DS
+SECTION AUTHORITY
+5QD8VL68T2I9KOBD32KJ8LJVH5OH2PQ0.net. 86400 IN NSEC3 1 1 0 - 5qdppotuk27kkp9ligtrb0k1cbvm9cim NS DS RRSIG
+5QD8VL68T2I9KOBD32KJ8LJVH5OH2PQ0.net. 86400 IN RRSIG NSEC3 8 2 86400 20180801102320 20180725091320 7934 net. ZKWDEle0ZQbeLFqJNnGWN9zZNZ4qXpns WEmuTMy1Ou9IRpBl0YU1RQRdjRJ4aFWM 5Kcl/UIOgeN4yD+B8HludqzhxRGDxqZ1 N1ObndmMNLbokcgyIYVnmhoe3doOnedK KRU5F6YcJpEOQ4jcJsjQd9ekQTB9aBP3 j33L4T3A1PM=
+A1RT98BS5QGC9NFI51S9HCI47ULJG6JH.net. 86400 IN NSEC3 1 1 0 - a1ruuffjkct2q54p78f8ejgj8jbk7i8b NS SOA RRSIG DNSKEY NSEC3PARAM
+A1RT98BS5QGC9NFI51S9HCI47ULJG6JH.net. 86400 IN RRSIG NSEC3 8 2 86400 20180731053505 20180724042505 7934 net. aQ1+tOFuT3esonx3VUVqcQGwUlcby0Wa Rit1P1ikFjowshfV9AUsn/bkka2dFgxC PgDtmMiQ6TzAKiwciFJ5mZitfFZSEoS/ Z3pnsZsvB062GrKNup9+x4SBiRB3HH8T xMMd6sVV9LjOE2iOm4ekIUHieMwJjfnY 7yG7obH6OFI=
+net. 900 IN RRSIG SOA 8 1 900 20180803084842 20180727073842 7934 net. GaMDNiWJZrDpU6uLTjDm3xG9RH1Ltojc knesMgzdxlcYAtennPH8HUtc3lsCIKUI 0uU22sXG/dSakls2ihWIrPXm13mGjYio UdCPTCEHyBApbe5Xh6m+wMWlbI8yxSYy b6bFCsH/2fgLlGHZ7DwQy+Cji5d/1H8x iTDVF1WfLvo=
+net. 900 IN SOA a.gtld-servers.net. nstld.verisign-grs.com. 1532681322 1800 900 604800 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR RD NOERROR
+SECTION QUESTION
+nstld.com. IN A
+SECTION AUTHORITY
+5V12UURISSGGLPAS52GE1V3R0V7KR5BS.com. 86400 IN NSEC3 1 1 0 - 5v13q049b9ittui4fbdtm34dtev47bgj NS DS RRSIG
+5V12UURISSGGLPAS52GE1V3R0V7KR5BS.com. 86400 IN RRSIG NSEC3 8 2 86400 20180802050635 20180726035635 46475 com. lF01rDWQAlm2v2Pfut1so+I6lSb4bLUA SXn21EAw0lSKAMPg5sOQHElu8EEcJInY zTFRpTOtCs6QGRlk//3+IpFK3nNunJrD GFS9A8XP5l4z8Z4/ZtQDsPhrfSZTizwA M7Un8JL9LniZ1ueo8409gEFbA8Xqw4sP ojwW8QIrt7Y=
+CK0POJMG874LJREF7EFN8430QVIT8BSM.com. 86400 IN NSEC3 1 1 0 - ck0q1gin43n1arrc9osm6qpqr81h5m9a NS SOA RRSIG DNSKEY NSEC3PARAM
+CK0POJMG874LJREF7EFN8430QVIT8BSM.com. 86400 IN RRSIG NSEC3 8 2 86400 20180731044815 20180724033815 46475 com. fM3ga8tkCx9ZVu/L/hQGXNcPxPVEGLfC gCgTtsJyUNefVSPOCMdqneA70UMVn06T bkGLDe85cA8ZViEnqc3iG6zhZIAwqas1 /5G509o4Ppf4lDI5CsH3iEhL5ofH+xfL t+wWEaTCLsUtmJN/VrSdqwpgJTNIJCcM QNF5A4J5btQ=
+nstld.com. 172800 IN NS av1.nstld.com.
+nstld.com. 172800 IN NS av2.nstld.com.
+nstld.com. 172800 IN NS av3.nstld.com.
+nstld.com. 172800 IN NS av4.nstld.com.
+SECTION ADDITIONAL
+av1.nstld.com. 172800 IN A 192.42.177.30
+av1.nstld.com. 172800 IN AAAA 2001:500:124::30
+av2.nstld.com. 172800 IN A 192.42.178.30
+av2.nstld.com. 172800 IN AAAA 2001:500:125::30
+av3.nstld.com. 172800 IN A 192.82.133.30
+av3.nstld.com. 172800 IN AAAA 2001:500:126::30
+av4.nstld.com. 172800 IN A 192.82.134.30
+av4.nstld.com. 172800 IN AAAA 2001:500:127::30
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR RD NOERROR
+SECTION QUESTION
+nstld.com. IN DNSKEY
+SECTION AUTHORITY
+5V12UURISSGGLPAS52GE1V3R0V7KR5BS.com. 86400 IN NSEC3 1 1 0 - 5v13q049b9ittui4fbdtm34dtev47bgj NS DS RRSIG
+5V12UURISSGGLPAS52GE1V3R0V7KR5BS.com. 86400 IN RRSIG NSEC3 8 2 86400 20180802050635 20180726035635 46475 com. lF01rDWQAlm2v2Pfut1so+I6lSb4bLUA SXn21EAw0lSKAMPg5sOQHElu8EEcJInY zTFRpTOtCs6QGRlk//3+IpFK3nNunJrD GFS9A8XP5l4z8Z4/ZtQDsPhrfSZTizwA M7Un8JL9LniZ1ueo8409gEFbA8Xqw4sP ojwW8QIrt7Y=
+CK0POJMG874LJREF7EFN8430QVIT8BSM.com. 86400 IN NSEC3 1 1 0 - ck0q1gin43n1arrc9osm6qpqr81h5m9a NS SOA RRSIG DNSKEY NSEC3PARAM
+CK0POJMG874LJREF7EFN8430QVIT8BSM.com. 86400 IN RRSIG NSEC3 8 2 86400 20180731044815 20180724033815 46475 com. fM3ga8tkCx9ZVu/L/hQGXNcPxPVEGLfC gCgTtsJyUNefVSPOCMdqneA70UMVn06T bkGLDe85cA8ZViEnqc3iG6zhZIAwqas1 /5G509o4Ppf4lDI5CsH3iEhL5ofH+xfL t+wWEaTCLsUtmJN/VrSdqwpgJTNIJCcM QNF5A4J5btQ=
+nstld.com. 172800 IN NS av1.nstld.com.
+nstld.com. 172800 IN NS av2.nstld.com.
+nstld.com. 172800 IN NS av3.nstld.com.
+nstld.com. 172800 IN NS av4.nstld.com.
+SECTION ADDITIONAL
+av1.nstld.com. 172800 IN A 192.42.177.30
+av1.nstld.com. 172800 IN AAAA 2001:500:124::30
+av2.nstld.com. 172800 IN A 192.42.178.30
+av2.nstld.com. 172800 IN AAAA 2001:500:125::30
+av3.nstld.com. 172800 IN A 192.82.133.30
+av3.nstld.com. 172800 IN AAAA 2001:500:126::30
+av4.nstld.com. 172800 IN A 192.82.134.30
+av4.nstld.com. 172800 IN AAAA 2001:500:127::30
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+nstld.com. IN DS
+SECTION AUTHORITY
+5V12UURISSGGLPAS52GE1V3R0V7KR5BS.com. 86400 IN NSEC3 1 1 0 - 5v13q049b9ittui4fbdtm34dtev47bgj NS DS RRSIG
+5V12UURISSGGLPAS52GE1V3R0V7KR5BS.com. 86400 IN RRSIG NSEC3 8 2 86400 20180802050635 20180726035635 46475 com. lF01rDWQAlm2v2Pfut1so+I6lSb4bLUA SXn21EAw0lSKAMPg5sOQHElu8EEcJInY zTFRpTOtCs6QGRlk//3+IpFK3nNunJrD GFS9A8XP5l4z8Z4/ZtQDsPhrfSZTizwA M7Un8JL9LniZ1ueo8409gEFbA8Xqw4sP ojwW8QIrt7Y=
+CK0POJMG874LJREF7EFN8430QVIT8BSM.com. 86400 IN NSEC3 1 1 0 - ck0q1gin43n1arrc9osm6qpqr81h5m9a NS SOA RRSIG DNSKEY NSEC3PARAM
+CK0POJMG874LJREF7EFN8430QVIT8BSM.com. 86400 IN RRSIG NSEC3 8 2 86400 20180731044815 20180724033815 46475 com. fM3ga8tkCx9ZVu/L/hQGXNcPxPVEGLfC gCgTtsJyUNefVSPOCMdqneA70UMVn06T bkGLDe85cA8ZViEnqc3iG6zhZIAwqas1 /5G509o4Ppf4lDI5CsH3iEhL5ofH+xfL t+wWEaTCLsUtmJN/VrSdqwpgJTNIJCcM QNF5A4J5btQ=
+com. 900 IN RRSIG SOA 8 1 900 20180803084843 20180727073843 46475 com. wzmp/pygt6idgcjTbWpXcNftz17R3m2G 3IPBt3h54AEI1BEwbI7oPRO+NZjmHN/W 9hsD0KUoDiHMOLndA8gJIV2ZG7ACTHvD HtRgvKIxqE1KvxDU7mmxULrWPNjNZgcg PlBUehxbf774Xcn4wE/aFNMZEjn5B2re A6MYOJoNby0=
+com. 900 IN SOA a.gtld-servers.net. nstld.verisign-grs.com. 1532681323 1800 900 604800 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+net. IN DNSKEY
+SECTION ANSWER
+net. 86400 IN DNSKEY 256 3 8 AQO6ELLy73I+l1XTVPuW3zfQkw5nublx oY4QgdTVOfUjdv6ooKTMRMgfKb+alpX5 8L5pfhndd+o7hisIwgiH2b6aqjdljzTf dV4XeZ/2CROv1ki/BRWwD61P/w688bpu Bl/u3vsTjvjq6FdVZVf3/afMXtSO1RR7 uaQ7qn8oupY/6w==
+net. 86400 IN DNSKEY 257 3 8 AQOYBnzqWXIEj6mlgXg4LWC0HP2n8eK8 XqgHlmJ/69iuIHsa1TrHDG6TcOra/pye GKwH0nKZhTmXSuUFGh9BCNiwVDuyyb6O BGy2Nte9Kr8NwWg4q+zhSoOf4D+gC9dE zg0yFdwT0DKEvmNPt0K4jbQDS4Yimb+u PKuF6yieWWrPYYCrv8C9KC8JMze2uT6N uWBfsl2fDUoV4l65qMww06D7n+p7Rbdw WkAZ0fA63mXVXBZF6kpDtsYD7SUB9jhh fLQE/r85bvg3FaSs5Wi2BaqN06SzGWI1 DHu7axthIOeHwg00zxlhTpoYCH0ldoQz +S65zWYi/fRJiyLSBb6JZOvn
+net. 86400 IN RRSIG DNSKEY 8 1 86400 20180808153857 20180724153357 35886 net. lmab/pWDgNRz6BN1BFZmkwiZz0qay0rz +46JXwgzI/g8eadEAev1OaIfsply91iM Sn+87NMPDN1Spjr3LKSXQB7+nc8n3yrf h1gxPRsjwuWxvPc3dJwlB4P8NvXTk4B5 vzjSpcfzvb+6YuAoC171yFcIcER1RN5d j3y1NRx1EAnuanMfoHIm+2dcu14a2hKn fB0zc/hm4L/rO/Qm8c3z97d1OffQs0L0 MGCU/kBDm/UyjymSFobMlIcn0bIha7A1 QN753OY+LEOWq0flQgUrKeuXvAe2o46g GebT+8euJahn/HmgmHD/bCNn+GC/KRJJ L1wFQH3x8uqlq9loQMPjwQ==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+com. IN DNSKEY
+SECTION ANSWER
+com. 86400 IN DNSKEY 256 3 8 AQPeabgR6Fgrk5FSLilDYUedwsHA0HH2 2e8+Zp/uvp4aj1dVDAy5C9bkRA+xot3s G1KaT5hvgoE7eNV93F7pBW9rvVE3A/BN vJbLXxKhkAJV5KMFC10NRcdb+xF+sM4X TMPESPrYwTLUEpSFntMIVLAtUzLaBo6Y pTVR20osgGgc3Q==
+com. 86400 IN DNSKEY 257 3 8 AQPDzldNmMvZFX4NcNJ0uEnKDg7tmv/F 3MyQR0lpBmVcNcsIszxNFxsBfKNW9JYC Yqpik8366LE7VbIcNRzfp2h9OO8HRl+H +E08zauK8k7evWEmu/6od+2boggPoiEf GNyvNPaSI7FOIroDsnw/taggzHRX1Z7S OiOiPWPNIwSUyWOZ79VmcQ1GLkC6NlYv G3HwYmynQv6oFwGv/KELSw7ZSdrbTQ0H XvZbqMUI7BaMskmvgm1G7oKZ1YiF7O9i oVNc0+7ASbqmZN7Z98EGU/Qh2K/BgUe8 Hs0XVcdPKrtyYnoQHd2ynKPcMMlTEih2 /2HDHjRPJ2aywIpKNnv4oPo/
+com. 86400 IN RRSIG DNSKEY 8 1 86400 20180810182533 20180726182033 30909 com. pytllCSmnIFN69hPKx3IcJSV3ZD+4qoF CXIuN+LXSJpkWmpD4gOWKgAytIBMImbh iUrfLECS2c3TJkjWjthKjL+GpYIHN1Z/ UY2zdSqKr0JqBQjHs456zBsJIrRriQKh e7MEFWV+JLSYAHQi/8+ot3l9GKO9nSK6 zqP+FrMtkPtZbJeNo1muSQ4lrdvYw4/t k0FADV0DK8p8/D/OQEPg2+Mpwx9GjCVN VOlKS5vuGHGAKI0gXlhJoe28i5McJVc5 O/evqbRX37xmfX01F8W4f6lZBt3qVIVq gW9iJAjY5vd4l4m53lTzYKTLeJTFH358 TsJO93q0NpaWL78xLxkVrg==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH subdomain
+ADJUST copy_id copy_query
+REPLY QR RD NOERROR
+SECTION QUESTION
+root-servers.net. IN NS
+SECTION AUTHORITY
+A1RT98BS5QGC9NFI51S9HCI47ULJG6JH.net. 86400 IN NSEC3 1 1 0 - a1ruuffjkct2q54p78f8ejgj8jbk7i8b NS SOA RRSIG DNSKEY NSEC3PARAM
+A1RT98BS5QGC9NFI51S9HCI47ULJG6JH.net. 86400 IN RRSIG NSEC3 8 2 86400 20180731053505 20180724042505 7934 net. aQ1+tOFuT3esonx3VUVqcQGwUlcby0Wa Rit1P1ikFjowshfV9AUsn/bkka2dFgxC PgDtmMiQ6TzAKiwciFJ5mZitfFZSEoS/ Z3pnsZsvB062GrKNup9+x4SBiRB3HH8T xMMd6sVV9LjOE2iOm4ekIUHieMwJjfnY 7yG7obH6OFI=
+T2UF21DR03E0BNPB42UQMVUF38P2TA8D.net. 86400 IN NSEC3 1 1 0 - t2ukct9k5i0uhv7b3m3na6jaigdjm0gr NS DS RRSIG
+T2UF21DR03E0BNPB42UQMVUF38P2TA8D.net. 86400 IN RRSIG NSEC3 8 2 86400 20180802052514 20180726041514 7934 net. LDVOVqnK+2HRKN6dUmVP3pP2RE0dCKTQ oE0d2w1AiDAOhn3Ye9Aq0yUjkz+frcUj ZqvTdiC58q0mXpyLUbqWiGmazUVG5qT7 zx5mhp1Leetq1wVJH8KGYLEmTstTCT56 oMbtWugGmZeY2B47rCsCeaWPNdH/b8qb UrwpfdPbhJE=
+root-servers.net. 172800 IN NS a.root-servers.net.
+root-servers.net. 172800 IN NS b.root-servers.net.
+root-servers.net. 172800 IN NS c.root-servers.net.
+root-servers.net. 172800 IN NS d.root-servers.net.
+root-servers.net. 172800 IN NS e.root-servers.net.
+root-servers.net. 172800 IN NS f.root-servers.net.
+root-servers.net. 172800 IN NS g.root-servers.net.
+root-servers.net. 172800 IN NS h.root-servers.net.
+root-servers.net. 172800 IN NS i.root-servers.net.
+root-servers.net. 172800 IN NS j.root-servers.net.
+root-servers.net. 172800 IN NS k.root-servers.net.
+root-servers.net. 172800 IN NS l.root-servers.net.
+root-servers.net. 172800 IN NS m.root-servers.net.
+SECTION ADDITIONAL
+a.root-servers.net. 172800 IN A 198.41.0.4
+a.root-servers.net. 172800 IN AAAA 2001:503:ba3e::2:30
+b.root-servers.net. 172800 IN A 199.9.14.201
+b.root-servers.net. 172800 IN AAAA 2001:500:200::b
+c.root-servers.net. 172800 IN A 192.33.4.12
+c.root-servers.net. 172800 IN AAAA 2001:500:2::c
+d.root-servers.net. 172800 IN A 199.7.91.13
+d.root-servers.net. 172800 IN AAAA 2001:500:2d::d
+e.root-servers.net. 172800 IN A 192.203.230.10
+e.root-servers.net. 172800 IN AAAA 2001:500:a8::e
+f.root-servers.net. 172800 IN A 192.5.5.241
+f.root-servers.net. 172800 IN AAAA 2001:500:2f::f
+g.root-servers.net. 172800 IN A 192.112.36.4
+g.root-servers.net. 172800 IN AAAA 2001:500:12::d0d
+h.root-servers.net. 172800 IN A 198.97.190.53
+h.root-servers.net. 172800 IN AAAA 2001:500:1::53
+i.root-servers.net. 172800 IN A 192.36.148.17
+i.root-servers.net. 172800 IN AAAA 2001:7fe::53
+j.root-servers.net. 172800 IN A 192.58.128.30
+j.root-servers.net. 172800 IN AAAA 2001:503:c27::2:30
+k.root-servers.net. 172800 IN A 193.0.14.129
+k.root-servers.net. 172800 IN AAAA 2001:7fd::1
+l.root-servers.net. 172800 IN A 199.7.83.42
+l.root-servers.net. 172800 IN AAAA 2001:500:9f::42
+m.root-servers.net. 172800 IN A 202.12.27.33
+m.root-servers.net. 172800 IN AAAA 2001:dc3::35
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH subdomain
+ADJUST copy_id copy_query
+REPLY QR RD NOERROR
+SECTION QUESTION
+gtld-servers.net. IN NS
+SECTION AUTHORITY
+5QD8VL68T2I9KOBD32KJ8LJVH5OH2PQ0.net. 86400 IN NSEC3 1 1 0 - 5qdppotuk27kkp9ligtrb0k1cbvm9cim NS DS RRSIG
+5QD8VL68T2I9KOBD32KJ8LJVH5OH2PQ0.net. 86400 IN RRSIG NSEC3 8 2 86400 20180801102320 20180725091320 7934 net. ZKWDEle0ZQbeLFqJNnGWN9zZNZ4qXpns WEmuTMy1Ou9IRpBl0YU1RQRdjRJ4aFWM 5Kcl/UIOgeN4yD+B8HludqzhxRGDxqZ1 N1ObndmMNLbokcgyIYVnmhoe3doOnedK KRU5F6YcJpEOQ4jcJsjQd9ekQTB9aBP3 j33L4T3A1PM=
+A1RT98BS5QGC9NFI51S9HCI47ULJG6JH.net. 86400 IN NSEC3 1 1 0 - a1ruuffjkct2q54p78f8ejgj8jbk7i8b NS SOA RRSIG DNSKEY NSEC3PARAM
+A1RT98BS5QGC9NFI51S9HCI47ULJG6JH.net. 86400 IN RRSIG NSEC3 8 2 86400 20180731053505 20180724042505 7934 net. aQ1+tOFuT3esonx3VUVqcQGwUlcby0Wa Rit1P1ikFjowshfV9AUsn/bkka2dFgxC PgDtmMiQ6TzAKiwciFJ5mZitfFZSEoS/ Z3pnsZsvB062GrKNup9+x4SBiRB3HH8T xMMd6sVV9LjOE2iOm4ekIUHieMwJjfnY 7yG7obH6OFI=
+gtld-servers.net. 172800 IN NS av1.nstld.com.
+gtld-servers.net. 172800 IN NS av2.nstld.com.
+gtld-servers.net. 172800 IN NS av3.nstld.com.
+gtld-servers.net. 172800 IN NS av4.nstld.com.
+SECTION ADDITIONAL
+av1.nstld.com. 172800 IN A 192.42.177.30
+av1.nstld.com. 172800 IN AAAA 2001:500:124::30
+av2.nstld.com. 172800 IN A 192.42.178.30
+av2.nstld.com. 172800 IN AAAA 2001:500:125::30
+av3.nstld.com. 172800 IN A 192.82.133.30
+av3.nstld.com. 172800 IN AAAA 2001:500:126::30
+av4.nstld.com. 172800 IN A 192.82.134.30
+av4.nstld.com. 172800 IN AAAA 2001:500:127::30
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH subdomain
+ADJUST copy_id copy_query
+REPLY QR RD NOERROR
+SECTION QUESTION
+nstld.com. IN NS
+SECTION AUTHORITY
+5V12UURISSGGLPAS52GE1V3R0V7KR5BS.com. 86400 IN NSEC3 1 1 0 - 5v13q049b9ittui4fbdtm34dtev47bgj NS DS RRSIG
+5V12UURISSGGLPAS52GE1V3R0V7KR5BS.com. 86400 IN RRSIG NSEC3 8 2 86400 20180802050635 20180726035635 46475 com. lF01rDWQAlm2v2Pfut1so+I6lSb4bLUA SXn21EAw0lSKAMPg5sOQHElu8EEcJInY zTFRpTOtCs6QGRlk//3+IpFK3nNunJrD GFS9A8XP5l4z8Z4/ZtQDsPhrfSZTizwA M7Un8JL9LniZ1ueo8409gEFbA8Xqw4sP ojwW8QIrt7Y=
+CK0POJMG874LJREF7EFN8430QVIT8BSM.com. 86400 IN NSEC3 1 1 0 - ck0q1gin43n1arrc9osm6qpqr81h5m9a NS SOA RRSIG DNSKEY NSEC3PARAM
+CK0POJMG874LJREF7EFN8430QVIT8BSM.com. 86400 IN RRSIG NSEC3 8 2 86400 20180731044815 20180724033815 46475 com. fM3ga8tkCx9ZVu/L/hQGXNcPxPVEGLfC gCgTtsJyUNefVSPOCMdqneA70UMVn06T bkGLDe85cA8ZViEnqc3iG6zhZIAwqas1 /5G509o4Ppf4lDI5CsH3iEhL5ofH+xfL t+wWEaTCLsUtmJN/VrSdqwpgJTNIJCcM QNF5A4J5btQ=
+nstld.com. 172800 IN NS av1.nstld.com.
+nstld.com. 172800 IN NS av2.nstld.com.
+nstld.com. 172800 IN NS av3.nstld.com.
+nstld.com. 172800 IN NS av4.nstld.com.
+SECTION ADDITIONAL
+av1.nstld.com. 172800 IN A 192.42.177.30
+av1.nstld.com. 172800 IN AAAA 2001:500:124::30
+av2.nstld.com. 172800 IN A 192.42.178.30
+av2.nstld.com. 172800 IN AAAA 2001:500:125::30
+av3.nstld.com. 172800 IN A 192.82.133.30
+av3.nstld.com. 172800 IN AAAA 2001:500:126::30
+av4.nstld.com. 172800 IN A 192.82.134.30
+av4.nstld.com. 172800 IN AAAA 2001:500:127::30
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH subdomain
+ADJUST copy_id copy_query
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+net. IN NS
+SECTION ANSWER
+net. 172800 IN NS a.gtld-servers.net.
+net. 172800 IN NS b.gtld-servers.net.
+net. 172800 IN NS c.gtld-servers.net.
+net. 172800 IN NS d.gtld-servers.net.
+net. 172800 IN NS e.gtld-servers.net.
+net. 172800 IN NS f.gtld-servers.net.
+net. 172800 IN NS g.gtld-servers.net.
+net. 172800 IN NS h.gtld-servers.net.
+net. 172800 IN NS i.gtld-servers.net.
+net. 172800 IN NS j.gtld-servers.net.
+net. 172800 IN NS k.gtld-servers.net.
+net. 172800 IN NS l.gtld-servers.net.
+net. 172800 IN NS m.gtld-servers.net.
+net. 172800 IN RRSIG NS 8 1 172800 20180802053055 20180726042055 7934 net. KR3mBpGrNgRPgB/LuPhUC4sjhy9F+GPU BXemSi46ZJlIWc7sK40AQ2rccrU5MDSa puWa2pVvx74pSU2w3gqeW9RH9E3wNh9t toAxJYJBNvTlXv3D1qG0LIXEsold+cvQ 0VqnFhVePojFFtFqE19H5OHaa87LVUOB Ib0gTx7i73Y=
+SECTION ADDITIONAL
+a.gtld-servers.net. 172800 IN A 192.5.6.30
+a.gtld-servers.net. 172800 IN AAAA 2001:503:a83e::2:30
+b.gtld-servers.net. 172800 IN A 192.33.14.30
+b.gtld-servers.net. 172800 IN AAAA 2001:503:231d::2:30
+c.gtld-servers.net. 172800 IN A 192.26.92.30
+c.gtld-servers.net. 172800 IN AAAA 2001:503:83eb::30
+d.gtld-servers.net. 172800 IN A 192.31.80.30
+d.gtld-servers.net. 172800 IN AAAA 2001:500:856e::30
+e.gtld-servers.net. 172800 IN A 192.12.94.30
+e.gtld-servers.net. 172800 IN AAAA 2001:502:1ca1::30
+f.gtld-servers.net. 172800 IN A 192.35.51.30
+f.gtld-servers.net. 172800 IN AAAA 2001:503:d414::30
+g.gtld-servers.net. 172800 IN A 192.42.93.30
+g.gtld-servers.net. 172800 IN AAAA 2001:503:eea3::30
+h.gtld-servers.net. 172800 IN A 192.54.112.30
+h.gtld-servers.net. 172800 IN AAAA 2001:502:8cc::30
+i.gtld-servers.net. 172800 IN A 192.43.172.30
+i.gtld-servers.net. 172800 IN AAAA 2001:503:39c1::30
+j.gtld-servers.net. 172800 IN A 192.48.79.30
+j.gtld-servers.net. 172800 IN AAAA 2001:502:7094::30
+k.gtld-servers.net. 172800 IN A 192.52.178.30
+k.gtld-servers.net. 172800 IN AAAA 2001:503:d2d::30
+l.gtld-servers.net. 172800 IN A 192.41.162.30
+l.gtld-servers.net. 172800 IN AAAA 2001:500:d937::30
+m.gtld-servers.net. 172800 IN A 192.55.83.30
+m.gtld-servers.net. 172800 IN AAAA 2001:501:b1f9::30
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH subdomain
+ADJUST copy_id copy_query
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. 172800 IN NS a.gtld-servers.net.
+com. 172800 IN NS b.gtld-servers.net.
+com. 172800 IN NS c.gtld-servers.net.
+com. 172800 IN NS d.gtld-servers.net.
+com. 172800 IN NS e.gtld-servers.net.
+com. 172800 IN NS f.gtld-servers.net.
+com. 172800 IN NS g.gtld-servers.net.
+com. 172800 IN NS h.gtld-servers.net.
+com. 172800 IN NS i.gtld-servers.net.
+com. 172800 IN NS j.gtld-servers.net.
+com. 172800 IN NS k.gtld-servers.net.
+com. 172800 IN NS l.gtld-servers.net.
+com. 172800 IN NS m.gtld-servers.net.
+com. 172800 IN RRSIG NS 8 1 172800 20180731044815 20180724033815 46475 com. JgH5uVQ8OQlpGeX/UJQRQHvQJjXOlQoZ o87eG2e/PP2y1R5Td93n/BckALIzqxT9 UyZsfIKDbRbK5junHSwV8FL5HC+3Hj0K QX8k4+yrpeYB1EM/Upkb5Db1E6F4NCcs iUyDsLNUS3trL+X7/ohrTM3ScPKdMux0 a0kAzuZMWJk=
+SECTION ADDITIONAL
+a.gtld-servers.net. 172800 IN A 192.5.6.30
+a.gtld-servers.net. 172800 IN AAAA 2001:503:a83e::2:30
+b.gtld-servers.net. 172800 IN A 192.33.14.30
+b.gtld-servers.net. 172800 IN AAAA 2001:503:231d::2:30
+c.gtld-servers.net. 172800 IN A 192.26.92.30
+c.gtld-servers.net. 172800 IN AAAA 2001:503:83eb::30
+d.gtld-servers.net. 172800 IN A 192.31.80.30
+d.gtld-servers.net. 172800 IN AAAA 2001:500:856e::30
+e.gtld-servers.net. 172800 IN A 192.12.94.30
+e.gtld-servers.net. 172800 IN AAAA 2001:502:1ca1::30
+f.gtld-servers.net. 172800 IN A 192.35.51.30
+f.gtld-servers.net. 172800 IN AAAA 2001:503:d414::30
+g.gtld-servers.net. 172800 IN A 192.42.93.30
+g.gtld-servers.net. 172800 IN AAAA 2001:503:eea3::30
+h.gtld-servers.net. 172800 IN A 192.54.112.30
+h.gtld-servers.net. 172800 IN AAAA 2001:502:8cc::30
+i.gtld-servers.net. 172800 IN A 192.43.172.30
+i.gtld-servers.net. 172800 IN AAAA 2001:503:39c1::30
+j.gtld-servers.net. 172800 IN A 192.48.79.30
+j.gtld-servers.net. 172800 IN AAAA 2001:502:7094::30
+k.gtld-servers.net. 172800 IN A 192.52.178.30
+k.gtld-servers.net. 172800 IN AAAA 2001:503:d2d::30
+l.gtld-servers.net. 172800 IN A 192.41.162.30
+l.gtld-servers.net. 172800 IN AAAA 2001:500:d937::30
+m.gtld-servers.net. 172800 IN A 192.55.83.30
+m.gtld-servers.net. 172800 IN AAAA 2001:501:b1f9::30
+ENTRY_END
+
+
+RANGE_END
+
+
+; Scope "nstld.com.
+
+; Server names:
+; av1.nstld.com.
+; av2.nstld.com.
+; av3.nstld.com.
+; av4.nstld.com.
+RANGE_BEGIN 0 1000
+ ADDRESS 2001:500:126::30
+ ADDRESS 2001:500:124::30
+ ADDRESS 192.82.134.30
+ ADDRESS 192.82.133.30
+ ADDRESS 2001:500:125::30
+ ADDRESS 2001:500:127::30
+ ADDRESS 192.42.177.30
+ ADDRESS 192.42.178.30
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+a.gtld-servers.net. IN A
+SECTION ANSWER
+a.gtld-servers.net. 86400 IN A 192.5.6.30
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN NS av1.nstld.com.
+gtld-servers.net. 86400 IN NS av2.nstld.com.
+gtld-servers.net. 86400 IN NS av3.nstld.com.
+gtld-servers.net. 86400 IN NS av4.nstld.com.
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+a.gtld-servers.net. IN DNSKEY
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+a.gtld-servers.net. IN NS
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+a.gtld-servers.net. IN DS
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+a.gtld-servers.net. IN AAAA
+SECTION ANSWER
+a.gtld-servers.net. 86400 IN AAAA 2001:503:a83e::2:30
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN NS av1.nstld.com.
+gtld-servers.net. 86400 IN NS av2.nstld.com.
+gtld-servers.net. 86400 IN NS av3.nstld.com.
+gtld-servers.net. 86400 IN NS av4.nstld.com.
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+j.gtld-servers.net. IN A
+SECTION ANSWER
+j.gtld-servers.net. 86400 IN A 192.48.79.30
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN NS av1.nstld.com.
+gtld-servers.net. 86400 IN NS av2.nstld.com.
+gtld-servers.net. 86400 IN NS av3.nstld.com.
+gtld-servers.net. 86400 IN NS av4.nstld.com.
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+j.gtld-servers.net. IN DNSKEY
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+j.gtld-servers.net. IN NS
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+j.gtld-servers.net. IN DS
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+j.gtld-servers.net. IN AAAA
+SECTION ANSWER
+j.gtld-servers.net. 86400 IN AAAA 2001:502:7094::30
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN NS av1.nstld.com.
+gtld-servers.net. 86400 IN NS av2.nstld.com.
+gtld-servers.net. 86400 IN NS av3.nstld.com.
+gtld-servers.net. 86400 IN NS av4.nstld.com.
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+e.gtld-servers.net. IN A
+SECTION ANSWER
+e.gtld-servers.net. 86400 IN A 192.12.94.30
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN NS av1.nstld.com.
+gtld-servers.net. 86400 IN NS av2.nstld.com.
+gtld-servers.net. 86400 IN NS av3.nstld.com.
+gtld-servers.net. 86400 IN NS av4.nstld.com.
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+e.gtld-servers.net. IN DNSKEY
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+e.gtld-servers.net. IN NS
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+e.gtld-servers.net. IN DS
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+e.gtld-servers.net. IN AAAA
+SECTION ANSWER
+e.gtld-servers.net. 86400 IN AAAA 2001:502:1ca1::30
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN NS av1.nstld.com.
+gtld-servers.net. 86400 IN NS av2.nstld.com.
+gtld-servers.net. 86400 IN NS av3.nstld.com.
+gtld-servers.net. 86400 IN NS av4.nstld.com.
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+i.gtld-servers.net. IN A
+SECTION ANSWER
+i.gtld-servers.net. 86400 IN A 192.43.172.30
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN NS av1.nstld.com.
+gtld-servers.net. 86400 IN NS av2.nstld.com.
+gtld-servers.net. 86400 IN NS av3.nstld.com.
+gtld-servers.net. 86400 IN NS av4.nstld.com.
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+i.gtld-servers.net. IN DNSKEY
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+i.gtld-servers.net. IN NS
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+i.gtld-servers.net. IN DS
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+i.gtld-servers.net. IN AAAA
+SECTION ANSWER
+i.gtld-servers.net. 86400 IN AAAA 2001:503:39c1::30
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN NS av1.nstld.com.
+gtld-servers.net. 86400 IN NS av2.nstld.com.
+gtld-servers.net. 86400 IN NS av3.nstld.com.
+gtld-servers.net. 86400 IN NS av4.nstld.com.
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+d.gtld-servers.net. IN A
+SECTION ANSWER
+d.gtld-servers.net. 86400 IN A 192.31.80.30
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN NS av1.nstld.com.
+gtld-servers.net. 86400 IN NS av2.nstld.com.
+gtld-servers.net. 86400 IN NS av3.nstld.com.
+gtld-servers.net. 86400 IN NS av4.nstld.com.
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+d.gtld-servers.net. IN DNSKEY
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+d.gtld-servers.net. IN NS
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+d.gtld-servers.net. IN DS
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+d.gtld-servers.net. IN AAAA
+SECTION ANSWER
+d.gtld-servers.net. 86400 IN AAAA 2001:500:856e::30
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN NS av1.nstld.com.
+gtld-servers.net. 86400 IN NS av2.nstld.com.
+gtld-servers.net. 86400 IN NS av3.nstld.com.
+gtld-servers.net. 86400 IN NS av4.nstld.com.
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+m.gtld-servers.net. IN A
+SECTION ANSWER
+m.gtld-servers.net. 86400 IN A 192.55.83.30
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN NS av1.nstld.com.
+gtld-servers.net. 86400 IN NS av2.nstld.com.
+gtld-servers.net. 86400 IN NS av3.nstld.com.
+gtld-servers.net. 86400 IN NS av4.nstld.com.
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+m.gtld-servers.net. IN DNSKEY
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+m.gtld-servers.net. IN NS
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+m.gtld-servers.net. IN DS
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+m.gtld-servers.net. IN AAAA
+SECTION ANSWER
+m.gtld-servers.net. 86400 IN AAAA 2001:501:b1f9::30
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN NS av1.nstld.com.
+gtld-servers.net. 86400 IN NS av2.nstld.com.
+gtld-servers.net. 86400 IN NS av3.nstld.com.
+gtld-servers.net. 86400 IN NS av4.nstld.com.
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+h.gtld-servers.net. IN A
+SECTION ANSWER
+h.gtld-servers.net. 86400 IN A 192.54.112.30
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN NS av1.nstld.com.
+gtld-servers.net. 86400 IN NS av2.nstld.com.
+gtld-servers.net. 86400 IN NS av3.nstld.com.
+gtld-servers.net. 86400 IN NS av4.nstld.com.
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+h.gtld-servers.net. IN DNSKEY
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+h.gtld-servers.net. IN NS
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+h.gtld-servers.net. IN DS
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+h.gtld-servers.net. IN AAAA
+SECTION ANSWER
+h.gtld-servers.net. 86400 IN AAAA 2001:502:8cc::30
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN NS av1.nstld.com.
+gtld-servers.net. 86400 IN NS av2.nstld.com.
+gtld-servers.net. 86400 IN NS av3.nstld.com.
+gtld-servers.net. 86400 IN NS av4.nstld.com.
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+c.gtld-servers.net. IN A
+SECTION ANSWER
+c.gtld-servers.net. 86400 IN A 192.26.92.30
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN NS av1.nstld.com.
+gtld-servers.net. 86400 IN NS av2.nstld.com.
+gtld-servers.net. 86400 IN NS av3.nstld.com.
+gtld-servers.net. 86400 IN NS av4.nstld.com.
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+c.gtld-servers.net. IN DNSKEY
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+c.gtld-servers.net. IN NS
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+c.gtld-servers.net. IN DS
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+c.gtld-servers.net. IN AAAA
+SECTION ANSWER
+c.gtld-servers.net. 86400 IN AAAA 2001:503:83eb::30
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN NS av1.nstld.com.
+gtld-servers.net. 86400 IN NS av2.nstld.com.
+gtld-servers.net. 86400 IN NS av3.nstld.com.
+gtld-servers.net. 86400 IN NS av4.nstld.com.
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+l.gtld-servers.net. IN A
+SECTION ANSWER
+l.gtld-servers.net. 86400 IN A 192.41.162.30
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN NS av1.nstld.com.
+gtld-servers.net. 86400 IN NS av2.nstld.com.
+gtld-servers.net. 86400 IN NS av3.nstld.com.
+gtld-servers.net. 86400 IN NS av4.nstld.com.
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+l.gtld-servers.net. IN DNSKEY
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+l.gtld-servers.net. IN NS
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+l.gtld-servers.net. IN DS
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+l.gtld-servers.net. IN AAAA
+SECTION ANSWER
+l.gtld-servers.net. 86400 IN AAAA 2001:500:d937::30
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN NS av1.nstld.com.
+gtld-servers.net. 86400 IN NS av2.nstld.com.
+gtld-servers.net. 86400 IN NS av3.nstld.com.
+gtld-servers.net. 86400 IN NS av4.nstld.com.
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+g.gtld-servers.net. IN A
+SECTION ANSWER
+g.gtld-servers.net. 86400 IN A 192.42.93.30
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN NS av1.nstld.com.
+gtld-servers.net. 86400 IN NS av2.nstld.com.
+gtld-servers.net. 86400 IN NS av3.nstld.com.
+gtld-servers.net. 86400 IN NS av4.nstld.com.
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+g.gtld-servers.net. IN DNSKEY
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+g.gtld-servers.net. IN NS
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+g.gtld-servers.net. IN DS
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+g.gtld-servers.net. IN AAAA
+SECTION ANSWER
+g.gtld-servers.net. 86400 IN AAAA 2001:503:eea3::30
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN NS av1.nstld.com.
+gtld-servers.net. 86400 IN NS av2.nstld.com.
+gtld-servers.net. 86400 IN NS av3.nstld.com.
+gtld-servers.net. 86400 IN NS av4.nstld.com.
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+b.gtld-servers.net. IN A
+SECTION ANSWER
+b.gtld-servers.net. 86400 IN A 192.33.14.30
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN NS av1.nstld.com.
+gtld-servers.net. 86400 IN NS av2.nstld.com.
+gtld-servers.net. 86400 IN NS av3.nstld.com.
+gtld-servers.net. 86400 IN NS av4.nstld.com.
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+b.gtld-servers.net. IN DNSKEY
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+b.gtld-servers.net. IN NS
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+b.gtld-servers.net. IN DS
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+b.gtld-servers.net. IN AAAA
+SECTION ANSWER
+b.gtld-servers.net. 86400 IN AAAA 2001:503:231d::2:30
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN NS av1.nstld.com.
+gtld-servers.net. 86400 IN NS av2.nstld.com.
+gtld-servers.net. 86400 IN NS av3.nstld.com.
+gtld-servers.net. 86400 IN NS av4.nstld.com.
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+k.gtld-servers.net. IN A
+SECTION ANSWER
+k.gtld-servers.net. 86400 IN A 192.52.178.30
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN NS av1.nstld.com.
+gtld-servers.net. 86400 IN NS av2.nstld.com.
+gtld-servers.net. 86400 IN NS av3.nstld.com.
+gtld-servers.net. 86400 IN NS av4.nstld.com.
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+k.gtld-servers.net. IN DNSKEY
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+k.gtld-servers.net. IN NS
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+k.gtld-servers.net. IN DS
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+k.gtld-servers.net. IN AAAA
+SECTION ANSWER
+k.gtld-servers.net. 86400 IN AAAA 2001:503:d2d::30
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN NS av1.nstld.com.
+gtld-servers.net. 86400 IN NS av2.nstld.com.
+gtld-servers.net. 86400 IN NS av3.nstld.com.
+gtld-servers.net. 86400 IN NS av4.nstld.com.
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+f.gtld-servers.net. IN A
+SECTION ANSWER
+f.gtld-servers.net. 86400 IN A 192.35.51.30
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN NS av1.nstld.com.
+gtld-servers.net. 86400 IN NS av2.nstld.com.
+gtld-servers.net. 86400 IN NS av3.nstld.com.
+gtld-servers.net. 86400 IN NS av4.nstld.com.
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+f.gtld-servers.net. IN DNSKEY
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+f.gtld-servers.net. IN NS
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+f.gtld-servers.net. IN DS
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+f.gtld-servers.net. IN AAAA
+SECTION ANSWER
+f.gtld-servers.net. 86400 IN AAAA 2001:503:d414::30
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN NS av1.nstld.com.
+gtld-servers.net. 86400 IN NS av2.nstld.com.
+gtld-servers.net. 86400 IN NS av3.nstld.com.
+gtld-servers.net. 86400 IN NS av4.nstld.com.
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+av1.nstld.com. IN A
+SECTION ANSWER
+av1.nstld.com. 300 IN A 192.42.177.30
+SECTION AUTHORITY
+nstld.com. 86400 IN NS av1.nstld.com.
+nstld.com. 86400 IN NS av2.nstld.com.
+nstld.com. 86400 IN NS av3.nstld.com.
+nstld.com. 86400 IN NS av4.nstld.com.
+SECTION ADDITIONAL
+av1.nstld.com. 300 IN AAAA 2001:500:124::30
+av2.nstld.com. 300 IN A 192.42.178.30
+av2.nstld.com. 300 IN AAAA 2001:500:125::30
+av3.nstld.com. 300 IN A 192.82.133.30
+av3.nstld.com. 300 IN AAAA 2001:500:126::30
+av4.nstld.com. 300 IN A 192.82.134.30
+av4.nstld.com. 300 IN AAAA 2001:500:127::30
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+av1.nstld.com. IN DNSKEY
+SECTION AUTHORITY
+nstld.com. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2018062000 7200 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+av1.nstld.com. IN NS
+SECTION AUTHORITY
+nstld.com. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2018062000 7200 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+av1.nstld.com. IN DS
+SECTION AUTHORITY
+nstld.com. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2018062000 7200 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+av1.nstld.com. IN AAAA
+SECTION ANSWER
+av1.nstld.com. 300 IN AAAA 2001:500:124::30
+SECTION AUTHORITY
+nstld.com. 86400 IN NS av1.nstld.com.
+nstld.com. 86400 IN NS av2.nstld.com.
+nstld.com. 86400 IN NS av3.nstld.com.
+nstld.com. 86400 IN NS av4.nstld.com.
+SECTION ADDITIONAL
+av1.nstld.com. 300 IN A 192.42.177.30
+av2.nstld.com. 300 IN A 192.42.178.30
+av2.nstld.com. 300 IN AAAA 2001:500:125::30
+av3.nstld.com. 300 IN A 192.82.133.30
+av3.nstld.com. 300 IN AAAA 2001:500:126::30
+av4.nstld.com. 300 IN A 192.82.134.30
+av4.nstld.com. 300 IN AAAA 2001:500:127::30
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+av2.nstld.com. IN A
+SECTION ANSWER
+av2.nstld.com. 300 IN A 192.42.178.30
+SECTION AUTHORITY
+nstld.com. 86400 IN NS av1.nstld.com.
+nstld.com. 86400 IN NS av2.nstld.com.
+nstld.com. 86400 IN NS av3.nstld.com.
+nstld.com. 86400 IN NS av4.nstld.com.
+SECTION ADDITIONAL
+av1.nstld.com. 300 IN A 192.42.177.30
+av1.nstld.com. 300 IN AAAA 2001:500:124::30
+av2.nstld.com. 300 IN AAAA 2001:500:125::30
+av3.nstld.com. 300 IN A 192.82.133.30
+av3.nstld.com. 300 IN AAAA 2001:500:126::30
+av4.nstld.com. 300 IN A 192.82.134.30
+av4.nstld.com. 300 IN AAAA 2001:500:127::30
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+av2.nstld.com. IN DNSKEY
+SECTION AUTHORITY
+nstld.com. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2018062000 7200 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+av2.nstld.com. IN NS
+SECTION AUTHORITY
+nstld.com. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2018062000 7200 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+av2.nstld.com. IN DS
+SECTION AUTHORITY
+nstld.com. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2018062000 7200 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+av2.nstld.com. IN AAAA
+SECTION ANSWER
+av2.nstld.com. 300 IN AAAA 2001:500:125::30
+SECTION AUTHORITY
+nstld.com. 86400 IN NS av1.nstld.com.
+nstld.com. 86400 IN NS av2.nstld.com.
+nstld.com. 86400 IN NS av3.nstld.com.
+nstld.com. 86400 IN NS av4.nstld.com.
+SECTION ADDITIONAL
+av1.nstld.com. 300 IN A 192.42.177.30
+av1.nstld.com. 300 IN AAAA 2001:500:124::30
+av2.nstld.com. 300 IN A 192.42.178.30
+av3.nstld.com. 300 IN A 192.82.133.30
+av3.nstld.com. 300 IN AAAA 2001:500:126::30
+av4.nstld.com. 300 IN A 192.82.134.30
+av4.nstld.com. 300 IN AAAA 2001:500:127::30
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+av3.nstld.com. IN A
+SECTION ANSWER
+av3.nstld.com. 300 IN A 192.82.133.30
+SECTION AUTHORITY
+nstld.com. 86400 IN NS av1.nstld.com.
+nstld.com. 86400 IN NS av2.nstld.com.
+nstld.com. 86400 IN NS av3.nstld.com.
+nstld.com. 86400 IN NS av4.nstld.com.
+SECTION ADDITIONAL
+av1.nstld.com. 300 IN A 192.42.177.30
+av1.nstld.com. 300 IN AAAA 2001:500:124::30
+av2.nstld.com. 300 IN A 192.42.178.30
+av2.nstld.com. 300 IN AAAA 2001:500:125::30
+av3.nstld.com. 300 IN AAAA 2001:500:126::30
+av4.nstld.com. 300 IN A 192.82.134.30
+av4.nstld.com. 300 IN AAAA 2001:500:127::30
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+av3.nstld.com. IN DNSKEY
+SECTION AUTHORITY
+nstld.com. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2018062000 7200 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+av3.nstld.com. IN NS
+SECTION AUTHORITY
+nstld.com. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2018062000 7200 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+av3.nstld.com. IN DS
+SECTION AUTHORITY
+nstld.com. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2018062000 7200 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+av3.nstld.com. IN AAAA
+SECTION ANSWER
+av3.nstld.com. 300 IN AAAA 2001:500:126::30
+SECTION AUTHORITY
+nstld.com. 86400 IN NS av1.nstld.com.
+nstld.com. 86400 IN NS av2.nstld.com.
+nstld.com. 86400 IN NS av3.nstld.com.
+nstld.com. 86400 IN NS av4.nstld.com.
+SECTION ADDITIONAL
+av1.nstld.com. 300 IN A 192.42.177.30
+av1.nstld.com. 300 IN AAAA 2001:500:124::30
+av2.nstld.com. 300 IN A 192.42.178.30
+av2.nstld.com. 300 IN AAAA 2001:500:125::30
+av3.nstld.com. 300 IN A 192.82.133.30
+av4.nstld.com. 300 IN A 192.82.134.30
+av4.nstld.com. 300 IN AAAA 2001:500:127::30
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+av4.nstld.com. IN A
+SECTION ANSWER
+av4.nstld.com. 300 IN A 192.82.134.30
+SECTION AUTHORITY
+nstld.com. 86400 IN NS av1.nstld.com.
+nstld.com. 86400 IN NS av2.nstld.com.
+nstld.com. 86400 IN NS av3.nstld.com.
+nstld.com. 86400 IN NS av4.nstld.com.
+SECTION ADDITIONAL
+av1.nstld.com. 300 IN A 192.42.177.30
+av1.nstld.com. 300 IN AAAA 2001:500:124::30
+av2.nstld.com. 300 IN A 192.42.178.30
+av2.nstld.com. 300 IN AAAA 2001:500:125::30
+av3.nstld.com. 300 IN A 192.82.133.30
+av3.nstld.com. 300 IN AAAA 2001:500:126::30
+av4.nstld.com. 300 IN AAAA 2001:500:127::30
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+av4.nstld.com. IN DNSKEY
+SECTION AUTHORITY
+nstld.com. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2018062000 7200 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+av4.nstld.com. IN NS
+SECTION AUTHORITY
+nstld.com. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2018062000 7200 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+av4.nstld.com. IN DS
+SECTION AUTHORITY
+nstld.com. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2018062000 7200 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+av4.nstld.com. IN AAAA
+SECTION ANSWER
+av4.nstld.com. 300 IN AAAA 2001:500:127::30
+SECTION AUTHORITY
+nstld.com. 86400 IN NS av1.nstld.com.
+nstld.com. 86400 IN NS av2.nstld.com.
+nstld.com. 86400 IN NS av3.nstld.com.
+nstld.com. 86400 IN NS av4.nstld.com.
+SECTION ADDITIONAL
+av1.nstld.com. 300 IN A 192.42.177.30
+av1.nstld.com. 300 IN AAAA 2001:500:124::30
+av2.nstld.com. 300 IN A 192.42.178.30
+av2.nstld.com. 300 IN AAAA 2001:500:125::30
+av3.nstld.com. 300 IN A 192.82.133.30
+av3.nstld.com. 300 IN AAAA 2001:500:126::30
+av4.nstld.com. 300 IN A 192.82.134.30
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+gtld-servers.net. IN DNSKEY
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+nstld.com. IN DNSKEY
+SECTION AUTHORITY
+nstld.com. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2018062000 7200 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH subdomain
+ADJUST copy_id copy_query
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+gtld-servers.net. IN NS
+SECTION ANSWER
+gtld-servers.net. 86400 IN NS av1.nstld.com.
+gtld-servers.net. 86400 IN NS av2.nstld.com.
+gtld-servers.net. 86400 IN NS av3.nstld.com.
+gtld-servers.net. 86400 IN NS av4.nstld.com.
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH subdomain
+ADJUST copy_id copy_query
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+nstld.com. IN NS
+SECTION ANSWER
+nstld.com. 86400 IN NS av1.nstld.com.
+nstld.com. 86400 IN NS av2.nstld.com.
+nstld.com. 86400 IN NS av3.nstld.com.
+nstld.com. 86400 IN NS av4.nstld.com.
+SECTION ADDITIONAL
+av1.nstld.com. 300 IN A 192.42.177.30
+av1.nstld.com. 300 IN AAAA 2001:500:124::30
+av2.nstld.com. 300 IN A 192.42.178.30
+av2.nstld.com. 300 IN AAAA 2001:500:125::30
+av3.nstld.com. 300 IN A 192.82.133.30
+av3.nstld.com. 300 IN AAAA 2001:500:126::30
+av4.nstld.com. 300 IN A 192.82.134.30
+av4.nstld.com. 300 IN AAAA 2001:500:127::30
+ENTRY_END
+
+
+RANGE_END
+
+
+; Scope "cz.
+
+; Server names:
+; b.ns.nic.cz.
+; d.ns.nic.cz.
+; a.ns.nic.cz.
+; c.ns.nic.cz.
+RANGE_BEGIN 0 1000
+ ADDRESS 193.29.206.1
+ ADDRESS 2001:678:1::1
+ ADDRESS 2001:678:11::1
+ ADDRESS 194.0.12.1
+ ADDRESS 194.0.13.1
+ ADDRESS 2001:678:f::1
+ ADDRESS 2001:678:10::1
+ ADDRESS 194.0.14.1
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+knot-resolver.cz. IN NULL
+SECTION AUTHORITY
+0b1klvkf05j25j32u97kue78u2ejhm0s.knot-resolver.cz. 7200 IN NSEC3 1 0 10 f49e445b0b4ad67f ei8u933svpm4qdfn713b66buji430uc7 A NS SOA MX AAAA RRSIG DNSKEY NSEC3PARAM CDS CDNSKEY
+0b1klvkf05j25j32u97kue78u2ejhm0s.knot-resolver.cz. 7200 IN RRSIG NSEC3 13 3 7200 20180809085235 20180726072235 34376 knot-resolver.cz. KjH6+xM1sFW05x4sND+cIr2KTttyKiux 2/X8SwY2PmrcK/ff6wmFejIrGUHvrG1U NS9icqQqTV3swNymGz4Dbw==
+knot-resolver.cz. 1800 IN RRSIG SOA 13 2 1800 20180809085235 20180726072235 34376 knot-resolver.cz. Yvpm+c/R4Y/Kj1a2Bz3JQBu+5admt4mh yueV6+fJI1V5N3dEoczePO5yBZiffk91 Xi2d4aYHRf2DLyfEX0HDVA==
+knot-resolver.cz. 1800 IN SOA knot-s-01.nic.cz. hostmaster.nic.cz. 2018042353 10800 3600 1209600 7200
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+knot-resolver.cz. IN DNSKEY
+SECTION ANSWER
+knot-resolver.cz. 1800 IN DNSKEY 256 3 13 a85wAU1EB4C7Xl82/BuF/gkkNwrQPdAF w1f9uqkz3qjLXK3S+21F4SJOSWHgIW6I 8GHuBZeCMvimvj/KscrVhw==
+knot-resolver.cz. 1800 IN DNSKEY 257 3 13 KDAJfPGWgvNAEHUMzmmSa+c3gHfoGIsX nhIO1iAYGTAyVBo+CLTyIk3wxDtt4Yn3 eCrCiYsEAHBJgQvA3pwJ8w==
+knot-resolver.cz. 1800 IN RRSIG DNSKEY 13 2 1800 20180808043000 20180725030000 54959 knot-resolver.cz. Yc3LFy9LfuakNaC9AJDIikUtjDocgdUV WiQ2b/A3YQ7+uExdT5oJHTY0JDfhdHXt 4bSy8G+yYlIYYKXUPIToBg==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+knot-resolver.cz. IN DS
+SECTION ANSWER
+knot-resolver.cz. 3600 IN DS 54959 13 2 a4e5db1e2e4607243c4fe4ee79a77d3538791b7ecab85a52290878de1224d7d4
+knot-resolver.cz. 3600 IN RRSIG DS 13 2 3600 20180803113206 20180720153540 62295 cz. ttYnNfVXQw5sKc2YobPQ1rknQjPi2a5f smkJssgzQOpMT16RKyZML9SpmNM17Xng bPpPseWR94HuFgIME4A+YA==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+knot-resolver.cz. IN A
+SECTION ANSWER
+knot-resolver.cz. 1800 IN A 217.31.192.18
+knot-resolver.cz. 1800 IN RRSIG A 13 2 1800 20180808033000 20180725020000 34376 knot-resolver.cz. uO0N7ttfRoQsS9McxAWJTIZqyJOl3WAo Pkc9QJrlrS/UG0KwJzBFBCWMxX+k5o7n C2Fi5GaDwmrcG1l+f+TTtA==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+knot-resolver.cz. IN AAAA
+SECTION ANSWER
+knot-resolver.cz. 1800 IN AAAA 2001:1488:ac15:ff30::18
+knot-resolver.cz. 1800 IN RRSIG AAAA 13 2 1800 20180808033000 20180725020000 34376 knot-resolver.cz. Y/wxR2e0nfYSfpYGJV6CMekYSuIIt2Jl bFl/oOhE9eiSTlXSEfT8GWxy5Q8dhhkR en+NEXApI31ZX4I5EGEXtg==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+nic.cz. IN A
+SECTION ANSWER
+nic.cz. 1800 IN A 217.31.205.50
+nic.cz. 1800 IN RRSIG A 13 2 1800 20180809122156 20180727064002 33494 nic.cz. p0uxXNMUIA1Zf6x/wqAdlNTSiLKrYs8P nNYlBe0SPQ8kTSGp49BlEaiy+B9ewcYp YbPTgjIpmvoMFeIOShUqgw==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+nic.cz. IN DNSKEY
+SECTION ANSWER
+nic.cz. 1800 IN DNSKEY 256 3 13 a10sJr/8DQL8M1nLPzWfNoASGTsm4cKE P577ZX3c3lruiWZiUL78fUp0B2YJh8U9 DyiZsq18i6CM9eYTDVemzA==
+nic.cz. 1800 IN DNSKEY 257 3 13 LM4zvjUgZi2XZKsYooDE0HFYGfWp242f KB+O8sLsuox8S6MJTowY8lBDjZD7JKbm aNot3+1H8zU9TrDzWmmHwQ==
+nic.cz. 1800 IN RRSIG DNSKEY 13 2 1800 20180809084714 20180727064002 61281 nic.cz. zotLLX9vPojjz21OSVfMGNspvWIVzzcW ZGJTTYOPlIHmrxAfE3GxHqV7QK8QO1W5 8rGsf9eebQw3+aJ+QGaNSA==
+nic.cz. 1800 IN RRSIG DNSKEY 13 2 1800 20180810022459 20180727064002 33494 nic.cz. Ol85KlI1HVLYmVRmD2q0QBCqLZM5bUDr sECC2XN0gmtkbEPfI1HmhylvM9sur3kE 4kCxCKOAOCozExhDZtgV2w==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+nic.cz. IN DS
+SECTION ANSWER
+nic.cz. 3600 IN DS 61281 13 2 4104d40c8fe2030bf7a09a199fcf37b36f7ec8ddd16f5a84f2e61c248d3afd0f
+nic.cz. 3600 IN RRSIG DS 13 2 3600 20180805030735 20180722073550 62295 cz. iF+/iu01Jx4ls0md5OHm25GHCuaLkEmd U4N8pzQRw0WYTmP71ZuMEqd4e5KPeGS2 hLqh134rBssNSGagGazLNw==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NXDOMAIN
+SECTION QUESTION
+knot-s-01.nic.cz. IN A
+SECTION AUTHORITY
+01bgrmosedn3jh21oq2cq3obvl9q56k8.nic.cz. 7200 IN NSEC3 1 0 10 6d024fda550cdd61 03keq03alogetpm9cgasqk7bremd66d1 A RRSIG
+01bgrmosedn3jh21oq2cq3obvl9q56k8.nic.cz. 7200 IN RRSIG NSEC3 13 3 7200 20180810043745 20180727064002 33494 nic.cz. qfSOy12hZJf/gtPn3k+34fhT3RTZgsq2 27nLVIx4DBHB2vzVTnXiZyqyU7D7LrO8 jXu43W5aNvtZzOK8RWPwkA==
+4g0hefga47i70br94ljss5us62b0ln71.nic.cz. 7200 IN NSEC3 1 0 10 6d024fda550cdd61 4i3o1eq9upce2qv1rkubgt7v5qgb90s4 A NS SOA MX AAAA RRSIG DNSKEY NSEC3PARAM
+4g0hefga47i70br94ljss5us62b0ln71.nic.cz. 7200 IN RRSIG NSEC3 13 3 7200 20180810054917 20180727064002 33494 nic.cz. SVSQya2mV73pXk5HeXrJXgKSGRiVo/LP PcCjihQqRzfQKK5XWDRgas7+Ve7khf/H wMBk2jSTLOKbvHJLW14K+Q==
+l80r74a5vjicpcbvnlpa2bk6bbvs5jjn.nic.cz. 7200 IN NSEC3 1 0 10 6d024fda550cdd61 lb5verduef1iorjs8glp93io39d6aib4 A AAAA RRSIG
+l80r74a5vjicpcbvnlpa2bk6bbvs5jjn.nic.cz. 7200 IN RRSIG NSEC3 13 3 7200 20180810063920 20180727064002 33494 nic.cz. p8egKoFkZcK1M81lCEaestRHkuFWxp4k lmNZv05NdyCSZd4juLFGGgfWcl49eE/j UyIOQwouuaVrn5OjuvBilA==
+nic.cz. 1800 IN RRSIG SOA 13 2 1800 20180809064029 20180727064002 33494 nic.cz. fErlGowdWxs4Fouw84ToJt02qqX+qnY+ ieVzHu+w01jj0z3tMK8uLid0G04ZRLA2 CHnO0NKCAPfRVX+K5X+yFQ==
+nic.cz. 1800 IN SOA a.ns.nic.cz. hostmaster.nic.cz. 1532677202 10800 3600 1209600 7200
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NXDOMAIN
+SECTION QUESTION
+knot-s-01.nic.cz. IN DNSKEY
+SECTION AUTHORITY
+01bgrmosedn3jh21oq2cq3obvl9q56k8.nic.cz. 7200 IN NSEC3 1 0 10 6d024fda550cdd61 03keq03alogetpm9cgasqk7bremd66d1 A RRSIG
+01bgrmosedn3jh21oq2cq3obvl9q56k8.nic.cz. 7200 IN RRSIG NSEC3 13 3 7200 20180810043745 20180727064002 33494 nic.cz. qfSOy12hZJf/gtPn3k+34fhT3RTZgsq2 27nLVIx4DBHB2vzVTnXiZyqyU7D7LrO8 jXu43W5aNvtZzOK8RWPwkA==
+4g0hefga47i70br94ljss5us62b0ln71.nic.cz. 7200 IN NSEC3 1 0 10 6d024fda550cdd61 4i3o1eq9upce2qv1rkubgt7v5qgb90s4 A NS SOA MX AAAA RRSIG DNSKEY NSEC3PARAM
+4g0hefga47i70br94ljss5us62b0ln71.nic.cz. 7200 IN RRSIG NSEC3 13 3 7200 20180810054917 20180727064002 33494 nic.cz. SVSQya2mV73pXk5HeXrJXgKSGRiVo/LP PcCjihQqRzfQKK5XWDRgas7+Ve7khf/H wMBk2jSTLOKbvHJLW14K+Q==
+l80r74a5vjicpcbvnlpa2bk6bbvs5jjn.nic.cz. 7200 IN NSEC3 1 0 10 6d024fda550cdd61 lb5verduef1iorjs8glp93io39d6aib4 A AAAA RRSIG
+l80r74a5vjicpcbvnlpa2bk6bbvs5jjn.nic.cz. 7200 IN RRSIG NSEC3 13 3 7200 20180810063920 20180727064002 33494 nic.cz. p8egKoFkZcK1M81lCEaestRHkuFWxp4k lmNZv05NdyCSZd4juLFGGgfWcl49eE/j UyIOQwouuaVrn5OjuvBilA==
+nic.cz. 1800 IN RRSIG SOA 13 2 1800 20180809064029 20180727064002 33494 nic.cz. fErlGowdWxs4Fouw84ToJt02qqX+qnY+ ieVzHu+w01jj0z3tMK8uLid0G04ZRLA2 CHnO0NKCAPfRVX+K5X+yFQ==
+nic.cz. 1800 IN SOA a.ns.nic.cz. hostmaster.nic.cz. 1532677202 10800 3600 1209600 7200
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NXDOMAIN
+SECTION QUESTION
+knot-s-01.nic.cz. IN NS
+SECTION AUTHORITY
+01bgrmosedn3jh21oq2cq3obvl9q56k8.nic.cz. 7200 IN NSEC3 1 0 10 6d024fda550cdd61 03keq03alogetpm9cgasqk7bremd66d1 A RRSIG
+01bgrmosedn3jh21oq2cq3obvl9q56k8.nic.cz. 7200 IN RRSIG NSEC3 13 3 7200 20180810043745 20180727064002 33494 nic.cz. qfSOy12hZJf/gtPn3k+34fhT3RTZgsq2 27nLVIx4DBHB2vzVTnXiZyqyU7D7LrO8 jXu43W5aNvtZzOK8RWPwkA==
+4g0hefga47i70br94ljss5us62b0ln71.nic.cz. 7200 IN NSEC3 1 0 10 6d024fda550cdd61 4i3o1eq9upce2qv1rkubgt7v5qgb90s4 A NS SOA MX AAAA RRSIG DNSKEY NSEC3PARAM
+4g0hefga47i70br94ljss5us62b0ln71.nic.cz. 7200 IN RRSIG NSEC3 13 3 7200 20180810054917 20180727064002 33494 nic.cz. SVSQya2mV73pXk5HeXrJXgKSGRiVo/LP PcCjihQqRzfQKK5XWDRgas7+Ve7khf/H wMBk2jSTLOKbvHJLW14K+Q==
+l80r74a5vjicpcbvnlpa2bk6bbvs5jjn.nic.cz. 7200 IN NSEC3 1 0 10 6d024fda550cdd61 lb5verduef1iorjs8glp93io39d6aib4 A AAAA RRSIG
+l80r74a5vjicpcbvnlpa2bk6bbvs5jjn.nic.cz. 7200 IN RRSIG NSEC3 13 3 7200 20180810063920 20180727064002 33494 nic.cz. p8egKoFkZcK1M81lCEaestRHkuFWxp4k lmNZv05NdyCSZd4juLFGGgfWcl49eE/j UyIOQwouuaVrn5OjuvBilA==
+nic.cz. 1800 IN RRSIG SOA 13 2 1800 20180809064029 20180727064002 33494 nic.cz. fErlGowdWxs4Fouw84ToJt02qqX+qnY+ ieVzHu+w01jj0z3tMK8uLid0G04ZRLA2 CHnO0NKCAPfRVX+K5X+yFQ==
+nic.cz. 1800 IN SOA a.ns.nic.cz. hostmaster.nic.cz. 1532677202 10800 3600 1209600 7200
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NXDOMAIN
+SECTION QUESTION
+knot-s-01.nic.cz. IN DS
+SECTION AUTHORITY
+01bgrmosedn3jh21oq2cq3obvl9q56k8.nic.cz. 7200 IN NSEC3 1 0 10 6d024fda550cdd61 03keq03alogetpm9cgasqk7bremd66d1 A RRSIG
+01bgrmosedn3jh21oq2cq3obvl9q56k8.nic.cz. 7200 IN RRSIG NSEC3 13 3 7200 20180810043745 20180727064002 33494 nic.cz. qfSOy12hZJf/gtPn3k+34fhT3RTZgsq2 27nLVIx4DBHB2vzVTnXiZyqyU7D7LrO8 jXu43W5aNvtZzOK8RWPwkA==
+4g0hefga47i70br94ljss5us62b0ln71.nic.cz. 7200 IN NSEC3 1 0 10 6d024fda550cdd61 4i3o1eq9upce2qv1rkubgt7v5qgb90s4 A NS SOA MX AAAA RRSIG DNSKEY NSEC3PARAM
+4g0hefga47i70br94ljss5us62b0ln71.nic.cz. 7200 IN RRSIG NSEC3 13 3 7200 20180810054917 20180727064002 33494 nic.cz. SVSQya2mV73pXk5HeXrJXgKSGRiVo/LP PcCjihQqRzfQKK5XWDRgas7+Ve7khf/H wMBk2jSTLOKbvHJLW14K+Q==
+l80r74a5vjicpcbvnlpa2bk6bbvs5jjn.nic.cz. 7200 IN NSEC3 1 0 10 6d024fda550cdd61 lb5verduef1iorjs8glp93io39d6aib4 A AAAA RRSIG
+l80r74a5vjicpcbvnlpa2bk6bbvs5jjn.nic.cz. 7200 IN RRSIG NSEC3 13 3 7200 20180810063920 20180727064002 33494 nic.cz. p8egKoFkZcK1M81lCEaestRHkuFWxp4k lmNZv05NdyCSZd4juLFGGgfWcl49eE/j UyIOQwouuaVrn5OjuvBilA==
+nic.cz. 1800 IN RRSIG SOA 13 2 1800 20180809064029 20180727064002 33494 nic.cz. fErlGowdWxs4Fouw84ToJt02qqX+qnY+ ieVzHu+w01jj0z3tMK8uLid0G04ZRLA2 CHnO0NKCAPfRVX+K5X+yFQ==
+nic.cz. 1800 IN SOA a.ns.nic.cz. hostmaster.nic.cz. 1532677202 10800 3600 1209600 7200
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NXDOMAIN
+SECTION QUESTION
+knot-s-01.nic.cz. IN AAAA
+SECTION AUTHORITY
+01bgrmosedn3jh21oq2cq3obvl9q56k8.nic.cz. 7200 IN NSEC3 1 0 10 6d024fda550cdd61 03keq03alogetpm9cgasqk7bremd66d1 A RRSIG
+01bgrmosedn3jh21oq2cq3obvl9q56k8.nic.cz. 7200 IN RRSIG NSEC3 13 3 7200 20180810043745 20180727064002 33494 nic.cz. qfSOy12hZJf/gtPn3k+34fhT3RTZgsq2 27nLVIx4DBHB2vzVTnXiZyqyU7D7LrO8 jXu43W5aNvtZzOK8RWPwkA==
+4g0hefga47i70br94ljss5us62b0ln71.nic.cz. 7200 IN NSEC3 1 0 10 6d024fda550cdd61 4i3o1eq9upce2qv1rkubgt7v5qgb90s4 A NS SOA MX AAAA RRSIG DNSKEY NSEC3PARAM
+4g0hefga47i70br94ljss5us62b0ln71.nic.cz. 7200 IN RRSIG NSEC3 13 3 7200 20180810054917 20180727064002 33494 nic.cz. SVSQya2mV73pXk5HeXrJXgKSGRiVo/LP PcCjihQqRzfQKK5XWDRgas7+Ve7khf/H wMBk2jSTLOKbvHJLW14K+Q==
+l80r74a5vjicpcbvnlpa2bk6bbvs5jjn.nic.cz. 7200 IN NSEC3 1 0 10 6d024fda550cdd61 lb5verduef1iorjs8glp93io39d6aib4 A AAAA RRSIG
+l80r74a5vjicpcbvnlpa2bk6bbvs5jjn.nic.cz. 7200 IN RRSIG NSEC3 13 3 7200 20180810063920 20180727064002 33494 nic.cz. p8egKoFkZcK1M81lCEaestRHkuFWxp4k lmNZv05NdyCSZd4juLFGGgfWcl49eE/j UyIOQwouuaVrn5OjuvBilA==
+nic.cz. 1800 IN RRSIG SOA 13 2 1800 20180809064029 20180727064002 33494 nic.cz. fErlGowdWxs4Fouw84ToJt02qqX+qnY+ ieVzHu+w01jj0z3tMK8uLid0G04ZRLA2 CHnO0NKCAPfRVX+K5X+yFQ==
+nic.cz. 1800 IN SOA a.ns.nic.cz. hostmaster.nic.cz. 1532677202 10800 3600 1209600 7200
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NXDOMAIN
+SECTION QUESTION
+nonexistent1123.knot-resolver.cz. IN A
+SECTION AUTHORITY
+0b1klvkf05j25j32u97kue78u2ejhm0s.knot-resolver.cz. 7200 IN NSEC3 1 0 10 f49e445b0b4ad67f ei8u933svpm4qdfn713b66buji430uc7 A NS SOA MX AAAA RRSIG DNSKEY NSEC3PARAM CDS CDNSKEY
+0b1klvkf05j25j32u97kue78u2ejhm0s.knot-resolver.cz. 7200 IN RRSIG NSEC3 13 3 7200 20180809085235 20180726072235 34376 knot-resolver.cz. KjH6+xM1sFW05x4sND+cIr2KTttyKiux 2/X8SwY2PmrcK/ff6wmFejIrGUHvrG1U NS9icqQqTV3swNymGz4Dbw==
+ei8u933svpm4qdfn713b66buji430uc7.knot-resolver.cz. 7200 IN NSEC3 1 0 10 f49e445b0b4ad67f rgofdsarih9kv8kcht41osd09tkl8o7v NS DS RRSIG
+ei8u933svpm4qdfn713b66buji430uc7.knot-resolver.cz. 7200 IN RRSIG NSEC3 13 3 7200 20180809085235 20180726072235 34376 knot-resolver.cz. 6wMAvVzU6xeyDZV1bDa/Av4n9k0kRB/x /H4aDF24oVFrRn2XTNNghu2OzmcVJV0E QlNIHd8aXfdQwLEz4FUAhw==
+knot-resolver.cz. 1800 IN RRSIG SOA 13 2 1800 20180809085235 20180726072235 34376 knot-resolver.cz. Yvpm+c/R4Y/Kj1a2Bz3JQBu+5admt4mh yueV6+fJI1V5N3dEoczePO5yBZiffk91 Xi2d4aYHRf2DLyfEX0HDVA==
+knot-resolver.cz. 1800 IN SOA knot-s-01.nic.cz. hostmaster.nic.cz. 2018042353 10800 3600 1209600 7200
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NXDOMAIN
+SECTION QUESTION
+nonexistent1123.knot-resolver.cz. IN DNSKEY
+SECTION AUTHORITY
+0b1klvkf05j25j32u97kue78u2ejhm0s.knot-resolver.cz. 7200 IN NSEC3 1 0 10 f49e445b0b4ad67f ei8u933svpm4qdfn713b66buji430uc7 A NS SOA MX AAAA RRSIG DNSKEY NSEC3PARAM CDS CDNSKEY
+0b1klvkf05j25j32u97kue78u2ejhm0s.knot-resolver.cz. 7200 IN RRSIG NSEC3 13 3 7200 20180809085235 20180726072235 34376 knot-resolver.cz. KjH6+xM1sFW05x4sND+cIr2KTttyKiux 2/X8SwY2PmrcK/ff6wmFejIrGUHvrG1U NS9icqQqTV3swNymGz4Dbw==
+ei8u933svpm4qdfn713b66buji430uc7.knot-resolver.cz. 7200 IN NSEC3 1 0 10 f49e445b0b4ad67f rgofdsarih9kv8kcht41osd09tkl8o7v NS DS RRSIG
+ei8u933svpm4qdfn713b66buji430uc7.knot-resolver.cz. 7200 IN RRSIG NSEC3 13 3 7200 20180809085235 20180726072235 34376 knot-resolver.cz. 6wMAvVzU6xeyDZV1bDa/Av4n9k0kRB/x /H4aDF24oVFrRn2XTNNghu2OzmcVJV0E QlNIHd8aXfdQwLEz4FUAhw==
+knot-resolver.cz. 1800 IN RRSIG SOA 13 2 1800 20180809085235 20180726072235 34376 knot-resolver.cz. Yvpm+c/R4Y/Kj1a2Bz3JQBu+5admt4mh yueV6+fJI1V5N3dEoczePO5yBZiffk91 Xi2d4aYHRf2DLyfEX0HDVA==
+knot-resolver.cz. 1800 IN SOA knot-s-01.nic.cz. hostmaster.nic.cz. 2018042353 10800 3600 1209600 7200
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NXDOMAIN
+SECTION QUESTION
+nonexistent1123.knot-resolver.cz. IN NS
+SECTION AUTHORITY
+0b1klvkf05j25j32u97kue78u2ejhm0s.knot-resolver.cz. 7200 IN NSEC3 1 0 10 f49e445b0b4ad67f ei8u933svpm4qdfn713b66buji430uc7 A NS SOA MX AAAA RRSIG DNSKEY NSEC3PARAM CDS CDNSKEY
+0b1klvkf05j25j32u97kue78u2ejhm0s.knot-resolver.cz. 7200 IN RRSIG NSEC3 13 3 7200 20180809085235 20180726072235 34376 knot-resolver.cz. KjH6+xM1sFW05x4sND+cIr2KTttyKiux 2/X8SwY2PmrcK/ff6wmFejIrGUHvrG1U NS9icqQqTV3swNymGz4Dbw==
+ei8u933svpm4qdfn713b66buji430uc7.knot-resolver.cz. 7200 IN NSEC3 1 0 10 f49e445b0b4ad67f rgofdsarih9kv8kcht41osd09tkl8o7v NS DS RRSIG
+ei8u933svpm4qdfn713b66buji430uc7.knot-resolver.cz. 7200 IN RRSIG NSEC3 13 3 7200 20180809085235 20180726072235 34376 knot-resolver.cz. 6wMAvVzU6xeyDZV1bDa/Av4n9k0kRB/x /H4aDF24oVFrRn2XTNNghu2OzmcVJV0E QlNIHd8aXfdQwLEz4FUAhw==
+knot-resolver.cz. 1800 IN RRSIG SOA 13 2 1800 20180809085235 20180726072235 34376 knot-resolver.cz. Yvpm+c/R4Y/Kj1a2Bz3JQBu+5admt4mh yueV6+fJI1V5N3dEoczePO5yBZiffk91 Xi2d4aYHRf2DLyfEX0HDVA==
+knot-resolver.cz. 1800 IN SOA knot-s-01.nic.cz. hostmaster.nic.cz. 2018042353 10800 3600 1209600 7200
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NXDOMAIN
+SECTION QUESTION
+nonexistent1123.knot-resolver.cz. IN DS
+SECTION AUTHORITY
+0b1klvkf05j25j32u97kue78u2ejhm0s.knot-resolver.cz. 7200 IN NSEC3 1 0 10 f49e445b0b4ad67f ei8u933svpm4qdfn713b66buji430uc7 A NS SOA MX AAAA RRSIG DNSKEY NSEC3PARAM CDS CDNSKEY
+0b1klvkf05j25j32u97kue78u2ejhm0s.knot-resolver.cz. 7200 IN RRSIG NSEC3 13 3 7200 20180809085235 20180726072235 34376 knot-resolver.cz. KjH6+xM1sFW05x4sND+cIr2KTttyKiux 2/X8SwY2PmrcK/ff6wmFejIrGUHvrG1U NS9icqQqTV3swNymGz4Dbw==
+ei8u933svpm4qdfn713b66buji430uc7.knot-resolver.cz. 7200 IN NSEC3 1 0 10 f49e445b0b4ad67f rgofdsarih9kv8kcht41osd09tkl8o7v NS DS RRSIG
+ei8u933svpm4qdfn713b66buji430uc7.knot-resolver.cz. 7200 IN RRSIG NSEC3 13 3 7200 20180809085235 20180726072235 34376 knot-resolver.cz. 6wMAvVzU6xeyDZV1bDa/Av4n9k0kRB/x /H4aDF24oVFrRn2XTNNghu2OzmcVJV0E QlNIHd8aXfdQwLEz4FUAhw==
+knot-resolver.cz. 1800 IN RRSIG SOA 13 2 1800 20180809085235 20180726072235 34376 knot-resolver.cz. Yvpm+c/R4Y/Kj1a2Bz3JQBu+5admt4mh yueV6+fJI1V5N3dEoczePO5yBZiffk91 Xi2d4aYHRf2DLyfEX0HDVA==
+knot-resolver.cz. 1800 IN SOA knot-s-01.nic.cz. hostmaster.nic.cz. 2018042353 10800 3600 1209600 7200
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NXDOMAIN
+SECTION QUESTION
+nonexistent1123.knot-resolver.cz. IN AAAA
+SECTION AUTHORITY
+0b1klvkf05j25j32u97kue78u2ejhm0s.knot-resolver.cz. 7200 IN NSEC3 1 0 10 f49e445b0b4ad67f ei8u933svpm4qdfn713b66buji430uc7 A NS SOA MX AAAA RRSIG DNSKEY NSEC3PARAM CDS CDNSKEY
+0b1klvkf05j25j32u97kue78u2ejhm0s.knot-resolver.cz. 7200 IN RRSIG NSEC3 13 3 7200 20180809085235 20180726072235 34376 knot-resolver.cz. KjH6+xM1sFW05x4sND+cIr2KTttyKiux 2/X8SwY2PmrcK/ff6wmFejIrGUHvrG1U NS9icqQqTV3swNymGz4Dbw==
+ei8u933svpm4qdfn713b66buji430uc7.knot-resolver.cz. 7200 IN NSEC3 1 0 10 f49e445b0b4ad67f rgofdsarih9kv8kcht41osd09tkl8o7v NS DS RRSIG
+ei8u933svpm4qdfn713b66buji430uc7.knot-resolver.cz. 7200 IN RRSIG NSEC3 13 3 7200 20180809085235 20180726072235 34376 knot-resolver.cz. 6wMAvVzU6xeyDZV1bDa/Av4n9k0kRB/x /H4aDF24oVFrRn2XTNNghu2OzmcVJV0E QlNIHd8aXfdQwLEz4FUAhw==
+knot-resolver.cz. 1800 IN RRSIG SOA 13 2 1800 20180809085235 20180726072235 34376 knot-resolver.cz. Yvpm+c/R4Y/Kj1a2Bz3JQBu+5admt4mh yueV6+fJI1V5N3dEoczePO5yBZiffk91 Xi2d4aYHRf2DLyfEX0HDVA==
+knot-resolver.cz. 1800 IN SOA knot-s-01.nic.cz. hostmaster.nic.cz. 2018042353 10800 3600 1209600 7200
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+labs.nic.cz. IN A
+SECTION ANSWER
+labs.nic.cz. 1800 IN A 217.31.192.130
+labs.nic.cz. 1800 IN RRSIG A 13 3 1800 20180808225840 20180725212840 5070 labs.nic.cz. GYUF3qBsSa9Zi8ijUnwijskJxjtVlUHC fj5qMOCg1tfsg7jf2nV8Au4llaWEAsxp AR0Hh/R808odDxyONg2wwA==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+labs.nic.cz. IN DNSKEY
+SECTION ANSWER
+labs.nic.cz. 1800 IN DNSKEY 256 3 13 EGR6/v4U4maTcZF6Gprv1oXZPmph09UL 5AX1gwt5AaIPh6X8Eti7ccgMH5vsHdvQ isdW1HmgGLPwEQAyO/W/MA==
+labs.nic.cz. 1800 IN DNSKEY 257 3 13 3Lk0VNzQzj9EDPJQwSPCVixCc+oyz0nr Uzik6UqtvCA0OLDd4v4sQjXmwxWniPrm aSGlEHCOXkrnQ455xgT2Pg==
+labs.nic.cz. 1800 IN RRSIG DNSKEY 13 3 1800 20180808235840 20180725222840 13482 labs.nic.cz. yCe+PodZZ4pqopxX0gTKf3LEKhOnDaV6 23kCc0Op4mzV+fASs6NrrkQVVSsdfv0G qAi/ThM3yXLvnsGB0XVnIA==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+labs.nic.cz. IN DS
+SECTION ANSWER
+labs.nic.cz. 1800 IN DS 13482 13 2 708b193611d70021885f8499d3b3de25b3c11a6c6801d62ef74cc87905428dc6
+labs.nic.cz. 1800 IN RRSIG DS 13 3 1800 20180810013825 20180727064002 33494 nic.cz. aM0ZTi5msMd2UOKvJv7sTQWLZP22B5dj NqfuvLf88vuW46gKokVGkOOSAgx7CeaH VVq7Ma4bzMuuXCqnjQiDcQ==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+nonexistent7.labs.nic.cz. IN A
+SECTION ANSWER
+gitlab.labs.nic.cz. 1800 IN A 217.31.192.133
+gitlab.labs.nic.cz. 1800 IN RRSIG A 13 4 1800 20180808062633 20180725045633 5070 labs.nic.cz. vIOy8SJPTE1CdRk71JAo+MxzbVhDvnh/ NQfkgdY5KOW081Jhrz74HJsAUsfJk4dD bTKY1DFVoUYYX49o0R7GGA==
+nonexistent7.labs.nic.cz. 30 IN CNAME gitlab.labs.nic.cz.
+nonexistent7.labs.nic.cz. 30 IN RRSIG CNAME 13 3 30 20180808062633 20180725045633 5070 labs.nic.cz. UPdL0dAWPX68OawblUE27nbM3drLu3yE 4jTQpefbhjTTmjs3I1dJ9IXgO6AEXHFx eWnlfK2r/45KZF7v/1NN6A==
+SECTION AUTHORITY
+4o5ekull1peq8leuf98l9iudrraqmqs4.labs.nic.cz. 7200 IN NSEC3 1 0 10 31ae62a0971eb1e7 61q3lko2dr2vnmncn1sh2vdiv449lmg3 A RRSIG
+4o5ekull1peq8leuf98l9iudrraqmqs4.labs.nic.cz. 7200 IN RRSIG NSEC3 13 4 7200 20180808122435 20180725105435 5070 labs.nic.cz. jrf7jm1Bc6YgN7WsYv1OBPFsOIfFxc2e kZZC9n2oMuyUgXV6KzYTJaHr8fvGOCKR GUWpo16osMQI1mdfcHskTw==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+nonexistent7.labs.nic.cz. IN DNSKEY
+SECTION ANSWER
+nonexistent7.labs.nic.cz. 30 IN CNAME gitlab.labs.nic.cz.
+nonexistent7.labs.nic.cz. 30 IN RRSIG CNAME 13 3 30 20180808062633 20180725045633 5070 labs.nic.cz. UPdL0dAWPX68OawblUE27nbM3drLu3yE 4jTQpefbhjTTmjs3I1dJ9IXgO6AEXHFx eWnlfK2r/45KZF7v/1NN6A==
+SECTION AUTHORITY
+4o5ekull1peq8leuf98l9iudrraqmqs4.labs.nic.cz. 7200 IN NSEC3 1 0 10 31ae62a0971eb1e7 61q3lko2dr2vnmncn1sh2vdiv449lmg3 A RRSIG
+4o5ekull1peq8leuf98l9iudrraqmqs4.labs.nic.cz. 7200 IN RRSIG NSEC3 13 4 7200 20180808122435 20180725105435 5070 labs.nic.cz. jrf7jm1Bc6YgN7WsYv1OBPFsOIfFxc2e kZZC9n2oMuyUgXV6KzYTJaHr8fvGOCKR GUWpo16osMQI1mdfcHskTw==
+labs.nic.cz. 1800 IN RRSIG SOA 13 3 1800 20180809143632 20180726130632 5070 labs.nic.cz. 3ZHmg1c9QRZSwroHmnLMYkJsxl2OiaS9 jPsfDZ2Ckm7MiQXUS4lXqXf+sfqMhcyP gpHwqhckCJOemCyaV/thfw==
+labs.nic.cz. 1800 IN SOA a.ns.nic.cz. hostmaster.nic.cz. 1532615793 10800 3600 1209600 7200
+pqats6gslj1en2mqjg1nok27ljrn62r3.labs.nic.cz. 7200 IN NSEC3 1 0 10 31ae62a0971eb1e7 pts6cg332bg2eqir8ga7efdju4elnad0 A AAAA SSHFP RRSIG
+pqats6gslj1en2mqjg1nok27ljrn62r3.labs.nic.cz. 7200 IN RRSIG NSEC3 13 4 7200 20180803103542 20180720090542 5070 labs.nic.cz. GK/DcFwOUvYfq02jwezQWLZhTSH1xSfl 8o1v0bi+7Vy40W70tra5ZvO6+UlQxnNN j5s6Fw5eenYl5qa/AmsNow==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+nonexistent7.labs.nic.cz. IN NS
+SECTION ANSWER
+nonexistent7.labs.nic.cz. 30 IN CNAME gitlab.labs.nic.cz.
+nonexistent7.labs.nic.cz. 30 IN RRSIG CNAME 13 3 30 20180808062633 20180725045633 5070 labs.nic.cz. UPdL0dAWPX68OawblUE27nbM3drLu3yE 4jTQpefbhjTTmjs3I1dJ9IXgO6AEXHFx eWnlfK2r/45KZF7v/1NN6A==
+SECTION AUTHORITY
+4o5ekull1peq8leuf98l9iudrraqmqs4.labs.nic.cz. 7200 IN NSEC3 1 0 10 31ae62a0971eb1e7 61q3lko2dr2vnmncn1sh2vdiv449lmg3 A RRSIG
+4o5ekull1peq8leuf98l9iudrraqmqs4.labs.nic.cz. 7200 IN RRSIG NSEC3 13 4 7200 20180808122435 20180725105435 5070 labs.nic.cz. jrf7jm1Bc6YgN7WsYv1OBPFsOIfFxc2e kZZC9n2oMuyUgXV6KzYTJaHr8fvGOCKR GUWpo16osMQI1mdfcHskTw==
+labs.nic.cz. 1800 IN RRSIG SOA 13 3 1800 20180809143632 20180726130632 5070 labs.nic.cz. 3ZHmg1c9QRZSwroHmnLMYkJsxl2OiaS9 jPsfDZ2Ckm7MiQXUS4lXqXf+sfqMhcyP gpHwqhckCJOemCyaV/thfw==
+labs.nic.cz. 1800 IN SOA a.ns.nic.cz. hostmaster.nic.cz. 1532615793 10800 3600 1209600 7200
+pqats6gslj1en2mqjg1nok27ljrn62r3.labs.nic.cz. 7200 IN NSEC3 1 0 10 31ae62a0971eb1e7 pts6cg332bg2eqir8ga7efdju4elnad0 A AAAA SSHFP RRSIG
+pqats6gslj1en2mqjg1nok27ljrn62r3.labs.nic.cz. 7200 IN RRSIG NSEC3 13 4 7200 20180803103542 20180720090542 5070 labs.nic.cz. GK/DcFwOUvYfq02jwezQWLZhTSH1xSfl 8o1v0bi+7Vy40W70tra5ZvO6+UlQxnNN j5s6Fw5eenYl5qa/AmsNow==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+nonexistent7.labs.nic.cz. IN DS
+SECTION ANSWER
+nonexistent7.labs.nic.cz. 30 IN CNAME gitlab.labs.nic.cz.
+nonexistent7.labs.nic.cz. 30 IN RRSIG CNAME 13 3 30 20180808062633 20180725045633 5070 labs.nic.cz. UPdL0dAWPX68OawblUE27nbM3drLu3yE 4jTQpefbhjTTmjs3I1dJ9IXgO6AEXHFx eWnlfK2r/45KZF7v/1NN6A==
+SECTION AUTHORITY
+4o5ekull1peq8leuf98l9iudrraqmqs4.labs.nic.cz. 7200 IN NSEC3 1 0 10 31ae62a0971eb1e7 61q3lko2dr2vnmncn1sh2vdiv449lmg3 A RRSIG
+4o5ekull1peq8leuf98l9iudrraqmqs4.labs.nic.cz. 7200 IN RRSIG NSEC3 13 4 7200 20180808122435 20180725105435 5070 labs.nic.cz. jrf7jm1Bc6YgN7WsYv1OBPFsOIfFxc2e kZZC9n2oMuyUgXV6KzYTJaHr8fvGOCKR GUWpo16osMQI1mdfcHskTw==
+labs.nic.cz. 1800 IN RRSIG SOA 13 3 1800 20180809143632 20180726130632 5070 labs.nic.cz. 3ZHmg1c9QRZSwroHmnLMYkJsxl2OiaS9 jPsfDZ2Ckm7MiQXUS4lXqXf+sfqMhcyP gpHwqhckCJOemCyaV/thfw==
+labs.nic.cz. 1800 IN SOA a.ns.nic.cz. hostmaster.nic.cz. 1532615793 10800 3600 1209600 7200
+pqats6gslj1en2mqjg1nok27ljrn62r3.labs.nic.cz. 7200 IN NSEC3 1 0 10 31ae62a0971eb1e7 pts6cg332bg2eqir8ga7efdju4elnad0 A AAAA SSHFP RRSIG
+pqats6gslj1en2mqjg1nok27ljrn62r3.labs.nic.cz. 7200 IN RRSIG NSEC3 13 4 7200 20180803103542 20180720090542 5070 labs.nic.cz. GK/DcFwOUvYfq02jwezQWLZhTSH1xSfl 8o1v0bi+7Vy40W70tra5ZvO6+UlQxnNN j5s6Fw5eenYl5qa/AmsNow==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+nonexistent7.labs.nic.cz. IN AAAA
+SECTION ANSWER
+gitlab.labs.nic.cz. 1800 IN AAAA 2001:1488:ac15:ff90::133
+gitlab.labs.nic.cz. 1800 IN RRSIG AAAA 13 4 1800 20180808062633 20180725045633 5070 labs.nic.cz. MkeWa5P2vNXqAxc1B7u8OEdbtadhLbsY Yy8IRlOcb6y2pn9xyjFyplyDqDMskX/6 J9kILbyTQCvxv2dOZ9prDQ==
+nonexistent7.labs.nic.cz. 30 IN CNAME gitlab.labs.nic.cz.
+nonexistent7.labs.nic.cz. 30 IN RRSIG CNAME 13 3 30 20180808062633 20180725045633 5070 labs.nic.cz. UPdL0dAWPX68OawblUE27nbM3drLu3yE 4jTQpefbhjTTmjs3I1dJ9IXgO6AEXHFx eWnlfK2r/45KZF7v/1NN6A==
+SECTION AUTHORITY
+4o5ekull1peq8leuf98l9iudrraqmqs4.labs.nic.cz. 7200 IN NSEC3 1 0 10 31ae62a0971eb1e7 61q3lko2dr2vnmncn1sh2vdiv449lmg3 A RRSIG
+4o5ekull1peq8leuf98l9iudrraqmqs4.labs.nic.cz. 7200 IN RRSIG NSEC3 13 4 7200 20180808122435 20180725105435 5070 labs.nic.cz. jrf7jm1Bc6YgN7WsYv1OBPFsOIfFxc2e kZZC9n2oMuyUgXV6KzYTJaHr8fvGOCKR GUWpo16osMQI1mdfcHskTw==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+gitlab.labs.nic.cz. IN A
+SECTION ANSWER
+gitlab.labs.nic.cz. 1800 IN A 217.31.192.133
+gitlab.labs.nic.cz. 1800 IN RRSIG A 13 4 1800 20180808062633 20180725045633 5070 labs.nic.cz. vIOy8SJPTE1CdRk71JAo+MxzbVhDvnh/ NQfkgdY5KOW081Jhrz74HJsAUsfJk4dD bTKY1DFVoUYYX49o0R7GGA==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+gitlab.labs.nic.cz. IN DNSKEY
+SECTION AUTHORITY
+labs.nic.cz. 1800 IN RRSIG SOA 13 3 1800 20180809143632 20180726130632 5070 labs.nic.cz. 3ZHmg1c9QRZSwroHmnLMYkJsxl2OiaS9 jPsfDZ2Ckm7MiQXUS4lXqXf+sfqMhcyP gpHwqhckCJOemCyaV/thfw==
+labs.nic.cz. 1800 IN SOA a.ns.nic.cz. hostmaster.nic.cz. 1532615793 10800 3600 1209600 7200
+pqats6gslj1en2mqjg1nok27ljrn62r3.labs.nic.cz. 7200 IN NSEC3 1 0 10 31ae62a0971eb1e7 pts6cg332bg2eqir8ga7efdju4elnad0 A AAAA SSHFP RRSIG
+pqats6gslj1en2mqjg1nok27ljrn62r3.labs.nic.cz. 7200 IN RRSIG NSEC3 13 4 7200 20180803103542 20180720090542 5070 labs.nic.cz. GK/DcFwOUvYfq02jwezQWLZhTSH1xSfl 8o1v0bi+7Vy40W70tra5ZvO6+UlQxnNN j5s6Fw5eenYl5qa/AmsNow==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+gitlab.labs.nic.cz. IN NS
+SECTION AUTHORITY
+labs.nic.cz. 1800 IN RRSIG SOA 13 3 1800 20180809143632 20180726130632 5070 labs.nic.cz. 3ZHmg1c9QRZSwroHmnLMYkJsxl2OiaS9 jPsfDZ2Ckm7MiQXUS4lXqXf+sfqMhcyP gpHwqhckCJOemCyaV/thfw==
+labs.nic.cz. 1800 IN SOA a.ns.nic.cz. hostmaster.nic.cz. 1532615793 10800 3600 1209600 7200
+pqats6gslj1en2mqjg1nok27ljrn62r3.labs.nic.cz. 7200 IN NSEC3 1 0 10 31ae62a0971eb1e7 pts6cg332bg2eqir8ga7efdju4elnad0 A AAAA SSHFP RRSIG
+pqats6gslj1en2mqjg1nok27ljrn62r3.labs.nic.cz. 7200 IN RRSIG NSEC3 13 4 7200 20180803103542 20180720090542 5070 labs.nic.cz. GK/DcFwOUvYfq02jwezQWLZhTSH1xSfl 8o1v0bi+7Vy40W70tra5ZvO6+UlQxnNN j5s6Fw5eenYl5qa/AmsNow==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+gitlab.labs.nic.cz. IN DS
+SECTION AUTHORITY
+labs.nic.cz. 1800 IN RRSIG SOA 13 3 1800 20180809143632 20180726130632 5070 labs.nic.cz. 3ZHmg1c9QRZSwroHmnLMYkJsxl2OiaS9 jPsfDZ2Ckm7MiQXUS4lXqXf+sfqMhcyP gpHwqhckCJOemCyaV/thfw==
+labs.nic.cz. 1800 IN SOA a.ns.nic.cz. hostmaster.nic.cz. 1532615793 10800 3600 1209600 7200
+pqats6gslj1en2mqjg1nok27ljrn62r3.labs.nic.cz. 7200 IN NSEC3 1 0 10 31ae62a0971eb1e7 pts6cg332bg2eqir8ga7efdju4elnad0 A AAAA SSHFP RRSIG
+pqats6gslj1en2mqjg1nok27ljrn62r3.labs.nic.cz. 7200 IN RRSIG NSEC3 13 4 7200 20180803103542 20180720090542 5070 labs.nic.cz. GK/DcFwOUvYfq02jwezQWLZhTSH1xSfl 8o1v0bi+7Vy40W70tra5ZvO6+UlQxnNN j5s6Fw5eenYl5qa/AmsNow==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+gitlab.labs.nic.cz. IN AAAA
+SECTION ANSWER
+gitlab.labs.nic.cz. 1800 IN AAAA 2001:1488:ac15:ff90::133
+gitlab.labs.nic.cz. 1800 IN RRSIG AAAA 13 4 1800 20180808062633 20180725045633 5070 labs.nic.cz. MkeWa5P2vNXqAxc1B7u8OEdbtadhLbsY Yy8IRlOcb6y2pn9xyjFyplyDqDMskX/6 J9kILbyTQCvxv2dOZ9prDQ==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+ns.nic.cz. IN A
+SECTION AUTHORITY
+7d87lcrpk6rt27kalh4sqt2rurekmmti.nic.cz. 7200 IN NSEC3 1 0 10 6d024fda550cdd61 7dios8rb1rae9ugm9mubblifgm1pdql0
+7d87lcrpk6rt27kalh4sqt2rurekmmti.nic.cz. 7200 IN RRSIG NSEC3 13 3 7200 20180809215742 20180727064002 33494 nic.cz. rGSwaAjCkz0BBxXgIv+Aq1rq/0gAnxkr Kx+eOR6h0iJDuUKoOogBdCD/XbNihwEr 3RjU+GlaxFjDVqb59fPE4g==
+nic.cz. 1800 IN RRSIG SOA 13 2 1800 20180809064029 20180727064002 33494 nic.cz. fErlGowdWxs4Fouw84ToJt02qqX+qnY+ ieVzHu+w01jj0z3tMK8uLid0G04ZRLA2 CHnO0NKCAPfRVX+K5X+yFQ==
+nic.cz. 1800 IN SOA a.ns.nic.cz. hostmaster.nic.cz. 1532677202 10800 3600 1209600 7200
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+ns.nic.cz. IN DNSKEY
+SECTION AUTHORITY
+7d87lcrpk6rt27kalh4sqt2rurekmmti.nic.cz. 7200 IN NSEC3 1 0 10 6d024fda550cdd61 7dios8rb1rae9ugm9mubblifgm1pdql0
+7d87lcrpk6rt27kalh4sqt2rurekmmti.nic.cz. 7200 IN RRSIG NSEC3 13 3 7200 20180809215742 20180727064002 33494 nic.cz. rGSwaAjCkz0BBxXgIv+Aq1rq/0gAnxkr Kx+eOR6h0iJDuUKoOogBdCD/XbNihwEr 3RjU+GlaxFjDVqb59fPE4g==
+nic.cz. 1800 IN RRSIG SOA 13 2 1800 20180809064029 20180727064002 33494 nic.cz. fErlGowdWxs4Fouw84ToJt02qqX+qnY+ ieVzHu+w01jj0z3tMK8uLid0G04ZRLA2 CHnO0NKCAPfRVX+K5X+yFQ==
+nic.cz. 1800 IN SOA a.ns.nic.cz. hostmaster.nic.cz. 1532677202 10800 3600 1209600 7200
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+ns.nic.cz. IN NS
+SECTION AUTHORITY
+7d87lcrpk6rt27kalh4sqt2rurekmmti.nic.cz. 7200 IN NSEC3 1 0 10 6d024fda550cdd61 7dios8rb1rae9ugm9mubblifgm1pdql0
+7d87lcrpk6rt27kalh4sqt2rurekmmti.nic.cz. 7200 IN RRSIG NSEC3 13 3 7200 20180809215742 20180727064002 33494 nic.cz. rGSwaAjCkz0BBxXgIv+Aq1rq/0gAnxkr Kx+eOR6h0iJDuUKoOogBdCD/XbNihwEr 3RjU+GlaxFjDVqb59fPE4g==
+nic.cz. 1800 IN RRSIG SOA 13 2 1800 20180809064029 20180727064002 33494 nic.cz. fErlGowdWxs4Fouw84ToJt02qqX+qnY+ ieVzHu+w01jj0z3tMK8uLid0G04ZRLA2 CHnO0NKCAPfRVX+K5X+yFQ==
+nic.cz. 1800 IN SOA a.ns.nic.cz. hostmaster.nic.cz. 1532677202 10800 3600 1209600 7200
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+ns.nic.cz. IN DS
+SECTION AUTHORITY
+7d87lcrpk6rt27kalh4sqt2rurekmmti.nic.cz. 7200 IN NSEC3 1 0 10 6d024fda550cdd61 7dios8rb1rae9ugm9mubblifgm1pdql0
+7d87lcrpk6rt27kalh4sqt2rurekmmti.nic.cz. 7200 IN RRSIG NSEC3 13 3 7200 20180809215742 20180727064002 33494 nic.cz. rGSwaAjCkz0BBxXgIv+Aq1rq/0gAnxkr Kx+eOR6h0iJDuUKoOogBdCD/XbNihwEr 3RjU+GlaxFjDVqb59fPE4g==
+nic.cz. 1800 IN RRSIG SOA 13 2 1800 20180809064029 20180727064002 33494 nic.cz. fErlGowdWxs4Fouw84ToJt02qqX+qnY+ ieVzHu+w01jj0z3tMK8uLid0G04ZRLA2 CHnO0NKCAPfRVX+K5X+yFQ==
+nic.cz. 1800 IN SOA a.ns.nic.cz. hostmaster.nic.cz. 1532677202 10800 3600 1209600 7200
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+a.ns.nic.cz. IN A
+SECTION ANSWER
+a.ns.nic.cz. 1800 IN A 194.0.12.1
+a.ns.nic.cz. 1800 IN RRSIG A 13 4 1800 20180810011809 20180727064002 33494 nic.cz. dlRCgD1PxXFCid2m1djf5URx+SbMMFtR aaeNB5G7jj9nqFv252cwhnOz7NLPqEBG yr+h8eEOqFKbV92ZfzygLw==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+a.ns.nic.cz. IN DNSKEY
+SECTION AUTHORITY
+0peaur41j22dbmn7u135fq4ftaucujhf.nic.cz. 7200 IN NSEC3 1 0 10 6d024fda550cdd61 0pr0tt6lsanr7gh1a7b43qfgll0ce3m7 A AAAA RRSIG
+0peaur41j22dbmn7u135fq4ftaucujhf.nic.cz. 7200 IN RRSIG NSEC3 13 3 7200 20180809114457 20180727064002 33494 nic.cz. JVwfhA8YvpMShhq+ZkjOjPwGTwqw0U+7 vgK0Dt+RaW9KhFydcmohq0YLO207c0Sm UnYvWvDBSu+PHAOSL+Hgkw==
+nic.cz. 1800 IN RRSIG SOA 13 2 1800 20180809064029 20180727064002 33494 nic.cz. fErlGowdWxs4Fouw84ToJt02qqX+qnY+ ieVzHu+w01jj0z3tMK8uLid0G04ZRLA2 CHnO0NKCAPfRVX+K5X+yFQ==
+nic.cz. 1800 IN SOA a.ns.nic.cz. hostmaster.nic.cz. 1532677202 10800 3600 1209600 7200
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+a.ns.nic.cz. IN NS
+SECTION AUTHORITY
+0peaur41j22dbmn7u135fq4ftaucujhf.nic.cz. 7200 IN NSEC3 1 0 10 6d024fda550cdd61 0pr0tt6lsanr7gh1a7b43qfgll0ce3m7 A AAAA RRSIG
+0peaur41j22dbmn7u135fq4ftaucujhf.nic.cz. 7200 IN RRSIG NSEC3 13 3 7200 20180809114457 20180727064002 33494 nic.cz. JVwfhA8YvpMShhq+ZkjOjPwGTwqw0U+7 vgK0Dt+RaW9KhFydcmohq0YLO207c0Sm UnYvWvDBSu+PHAOSL+Hgkw==
+nic.cz. 1800 IN RRSIG SOA 13 2 1800 20180809064029 20180727064002 33494 nic.cz. fErlGowdWxs4Fouw84ToJt02qqX+qnY+ ieVzHu+w01jj0z3tMK8uLid0G04ZRLA2 CHnO0NKCAPfRVX+K5X+yFQ==
+nic.cz. 1800 IN SOA a.ns.nic.cz. hostmaster.nic.cz. 1532677202 10800 3600 1209600 7200
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+a.ns.nic.cz. IN DS
+SECTION AUTHORITY
+0peaur41j22dbmn7u135fq4ftaucujhf.nic.cz. 7200 IN NSEC3 1 0 10 6d024fda550cdd61 0pr0tt6lsanr7gh1a7b43qfgll0ce3m7 A AAAA RRSIG
+0peaur41j22dbmn7u135fq4ftaucujhf.nic.cz. 7200 IN RRSIG NSEC3 13 3 7200 20180809114457 20180727064002 33494 nic.cz. JVwfhA8YvpMShhq+ZkjOjPwGTwqw0U+7 vgK0Dt+RaW9KhFydcmohq0YLO207c0Sm UnYvWvDBSu+PHAOSL+Hgkw==
+nic.cz. 1800 IN RRSIG SOA 13 2 1800 20180809064029 20180727064002 33494 nic.cz. fErlGowdWxs4Fouw84ToJt02qqX+qnY+ ieVzHu+w01jj0z3tMK8uLid0G04ZRLA2 CHnO0NKCAPfRVX+K5X+yFQ==
+nic.cz. 1800 IN SOA a.ns.nic.cz. hostmaster.nic.cz. 1532677202 10800 3600 1209600 7200
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+a.ns.nic.cz. IN AAAA
+SECTION ANSWER
+a.ns.nic.cz. 1800 IN AAAA 2001:678:f::1
+a.ns.nic.cz. 1800 IN RRSIG AAAA 13 4 1800 20180809213334 20180727064002 33494 nic.cz. TQvt6opeQKp4V/VTYgEsw25AFAD3l9I6 UE5HhJUVGpnn8YzmZZs1QTNC1ZVf0MCs Flr3H2mTNm0r/Mb3m6Q+Yw==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+b.ns.nic.cz. IN A
+SECTION ANSWER
+b.ns.nic.cz. 1800 IN A 194.0.13.1
+b.ns.nic.cz. 1800 IN RRSIG A 13 4 1800 20180809112828 20180727064002 33494 nic.cz. GO5Wc2EWoV4yRvc3ktazw+lNZ7nGtR6S 4MsumQDKuADSGMLAhwm+htASUXxWZtV+ wWv74LD2g2cNjHpXHH1PBg==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+b.ns.nic.cz. IN DNSKEY
+SECTION AUTHORITY
+nic.cz. 1800 IN RRSIG SOA 13 2 1800 20180809064029 20180727064002 33494 nic.cz. fErlGowdWxs4Fouw84ToJt02qqX+qnY+ ieVzHu+w01jj0z3tMK8uLid0G04ZRLA2 CHnO0NKCAPfRVX+K5X+yFQ==
+nic.cz. 1800 IN SOA a.ns.nic.cz. hostmaster.nic.cz. 1532677202 10800 3600 1209600 7200
+qo01qt0th20ivkdanq04f4g7v2eaj3ur.nic.cz. 7200 IN NSEC3 1 0 10 6d024fda550cdd61 qrn61qbmo7ba8fufp4f15q8v233rd7s1 A AAAA RRSIG
+qo01qt0th20ivkdanq04f4g7v2eaj3ur.nic.cz. 7200 IN RRSIG NSEC3 13 3 7200 20180810053445 20180727064002 33494 nic.cz. NPU0frxy34iY0tCv3Kvgew+zKlulbVF9 4y1Ml0ohKTr659CYBmX0y0C9Kt9vBfzz oDoYnIslWIwouM+u7186yw==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+b.ns.nic.cz. IN NS
+SECTION AUTHORITY
+nic.cz. 1800 IN RRSIG SOA 13 2 1800 20180809064029 20180727064002 33494 nic.cz. fErlGowdWxs4Fouw84ToJt02qqX+qnY+ ieVzHu+w01jj0z3tMK8uLid0G04ZRLA2 CHnO0NKCAPfRVX+K5X+yFQ==
+nic.cz. 1800 IN SOA a.ns.nic.cz. hostmaster.nic.cz. 1532677202 10800 3600 1209600 7200
+qo01qt0th20ivkdanq04f4g7v2eaj3ur.nic.cz. 7200 IN NSEC3 1 0 10 6d024fda550cdd61 qrn61qbmo7ba8fufp4f15q8v233rd7s1 A AAAA RRSIG
+qo01qt0th20ivkdanq04f4g7v2eaj3ur.nic.cz. 7200 IN RRSIG NSEC3 13 3 7200 20180810053445 20180727064002 33494 nic.cz. NPU0frxy34iY0tCv3Kvgew+zKlulbVF9 4y1Ml0ohKTr659CYBmX0y0C9Kt9vBfzz oDoYnIslWIwouM+u7186yw==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+b.ns.nic.cz. IN DS
+SECTION AUTHORITY
+nic.cz. 1800 IN RRSIG SOA 13 2 1800 20180809064029 20180727064002 33494 nic.cz. fErlGowdWxs4Fouw84ToJt02qqX+qnY+ ieVzHu+w01jj0z3tMK8uLid0G04ZRLA2 CHnO0NKCAPfRVX+K5X+yFQ==
+nic.cz. 1800 IN SOA a.ns.nic.cz. hostmaster.nic.cz. 1532677202 10800 3600 1209600 7200
+qo01qt0th20ivkdanq04f4g7v2eaj3ur.nic.cz. 7200 IN NSEC3 1 0 10 6d024fda550cdd61 qrn61qbmo7ba8fufp4f15q8v233rd7s1 A AAAA RRSIG
+qo01qt0th20ivkdanq04f4g7v2eaj3ur.nic.cz. 7200 IN RRSIG NSEC3 13 3 7200 20180810053445 20180727064002 33494 nic.cz. NPU0frxy34iY0tCv3Kvgew+zKlulbVF9 4y1Ml0ohKTr659CYBmX0y0C9Kt9vBfzz oDoYnIslWIwouM+u7186yw==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+b.ns.nic.cz. IN AAAA
+SECTION ANSWER
+b.ns.nic.cz. 1800 IN AAAA 2001:678:10::1
+b.ns.nic.cz. 1800 IN RRSIG AAAA 13 4 1800 20180809130835 20180727064002 33494 nic.cz. sesuNekVgD2YLYl51sKLEYZeDmcxtQKl oFYnpXMUBVlqLTUGjn0RRcDvpJCxj/Ac isifFcEwvZ4W0B5/Ry1oVQ==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+c.ns.nic.cz. IN A
+SECTION ANSWER
+c.ns.nic.cz. 1800 IN A 194.0.14.1
+c.ns.nic.cz. 1800 IN RRSIG A 13 4 1800 20180809230245 20180727064002 33494 nic.cz. vlIESyKHWExpovMlpGstO7X8Qk1YnJYc w8i6u28JjABo/2qa20s3wFXVgenziyEn 3VTsenqk6TTTi8RutaSmhA==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+c.ns.nic.cz. IN DNSKEY
+SECTION AUTHORITY
+ccueinlfu0s4ji2bgsprv30rcletotkq.nic.cz. 7200 IN NSEC3 1 0 10 6d024fda550cdd61 cem50d1dfrtnfqk2gdjo4405j9lvostb A AAAA RRSIG
+ccueinlfu0s4ji2bgsprv30rcletotkq.nic.cz. 7200 IN RRSIG NSEC3 13 3 7200 20180809155831 20180727064002 33494 nic.cz. 9kekS/gKCcN1h0h5JhWV+r+tq9p0RpY4 QXT8aVrcxaD0LbXR+tGc8laMcdxOmrbd kXCxuSt6FVPmueKlCZj1Kw==
+nic.cz. 1800 IN RRSIG SOA 13 2 1800 20180809064029 20180727064002 33494 nic.cz. fErlGowdWxs4Fouw84ToJt02qqX+qnY+ ieVzHu+w01jj0z3tMK8uLid0G04ZRLA2 CHnO0NKCAPfRVX+K5X+yFQ==
+nic.cz. 1800 IN SOA a.ns.nic.cz. hostmaster.nic.cz. 1532677202 10800 3600 1209600 7200
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+c.ns.nic.cz. IN NS
+SECTION AUTHORITY
+ccueinlfu0s4ji2bgsprv30rcletotkq.nic.cz. 7200 IN NSEC3 1 0 10 6d024fda550cdd61 cem50d1dfrtnfqk2gdjo4405j9lvostb A AAAA RRSIG
+ccueinlfu0s4ji2bgsprv30rcletotkq.nic.cz. 7200 IN RRSIG NSEC3 13 3 7200 20180809155831 20180727064002 33494 nic.cz. 9kekS/gKCcN1h0h5JhWV+r+tq9p0RpY4 QXT8aVrcxaD0LbXR+tGc8laMcdxOmrbd kXCxuSt6FVPmueKlCZj1Kw==
+nic.cz. 1800 IN RRSIG SOA 13 2 1800 20180809064029 20180727064002 33494 nic.cz. fErlGowdWxs4Fouw84ToJt02qqX+qnY+ ieVzHu+w01jj0z3tMK8uLid0G04ZRLA2 CHnO0NKCAPfRVX+K5X+yFQ==
+nic.cz. 1800 IN SOA a.ns.nic.cz. hostmaster.nic.cz. 1532677202 10800 3600 1209600 7200
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+c.ns.nic.cz. IN DS
+SECTION AUTHORITY
+ccueinlfu0s4ji2bgsprv30rcletotkq.nic.cz. 7200 IN NSEC3 1 0 10 6d024fda550cdd61 cem50d1dfrtnfqk2gdjo4405j9lvostb A AAAA RRSIG
+ccueinlfu0s4ji2bgsprv30rcletotkq.nic.cz. 7200 IN RRSIG NSEC3 13 3 7200 20180809155831 20180727064002 33494 nic.cz. 9kekS/gKCcN1h0h5JhWV+r+tq9p0RpY4 QXT8aVrcxaD0LbXR+tGc8laMcdxOmrbd kXCxuSt6FVPmueKlCZj1Kw==
+nic.cz. 1800 IN RRSIG SOA 13 2 1800 20180809064029 20180727064002 33494 nic.cz. fErlGowdWxs4Fouw84ToJt02qqX+qnY+ ieVzHu+w01jj0z3tMK8uLid0G04ZRLA2 CHnO0NKCAPfRVX+K5X+yFQ==
+nic.cz. 1800 IN SOA a.ns.nic.cz. hostmaster.nic.cz. 1532677202 10800 3600 1209600 7200
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+c.ns.nic.cz. IN AAAA
+SECTION ANSWER
+c.ns.nic.cz. 1800 IN AAAA 2001:678:11::1
+c.ns.nic.cz. 1800 IN RRSIG AAAA 13 4 1800 20180809162728 20180727064002 33494 nic.cz. QRpoOGOlRV5YZkfr8rvOdGVZDqaFY4hV WsjpEl2cB1A9Rkw9/aX2toXhBoHTD7SX djgg2xiJzfNqtbBZNcpCrw==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+d.ns.nic.cz. IN A
+SECTION ANSWER
+d.ns.nic.cz. 1800 IN A 193.29.206.1
+d.ns.nic.cz. 1800 IN RRSIG A 13 4 1800 20180809211641 20180727064002 33494 nic.cz. yLSqZnGG2G5+StFxEPpuV3I5slNKLF3o 7QahlX4mKk/iN74C7zh62cR+Q/s3SDxE fFF2M/owNT3T2wspOh4L/g==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+d.ns.nic.cz. IN DNSKEY
+SECTION AUTHORITY
+nic.cz. 1800 IN RRSIG SOA 13 2 1800 20180809064029 20180727064002 33494 nic.cz. fErlGowdWxs4Fouw84ToJt02qqX+qnY+ ieVzHu+w01jj0z3tMK8uLid0G04ZRLA2 CHnO0NKCAPfRVX+K5X+yFQ==
+nic.cz. 1800 IN SOA a.ns.nic.cz. hostmaster.nic.cz. 1532677202 10800 3600 1209600 7200
+vf5fp77trrd78patqgiavtggum6cajh9.nic.cz. 7200 IN NSEC3 1 0 10 6d024fda550cdd61 vg8e7aak4v5n8qc7q065is15lgndiok5 A AAAA RRSIG
+vf5fp77trrd78patqgiavtggum6cajh9.nic.cz. 7200 IN RRSIG NSEC3 13 3 7200 20180809144711 20180727064002 33494 nic.cz. qGRXKiwS8f+uEggVDFRUqt27euEuDV+T 2rrwkPqlCXvHiaKYI/P0eTkHe2SamKZT Fe2nbLIeuppDRzKo9DPx+g==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+d.ns.nic.cz. IN NS
+SECTION AUTHORITY
+nic.cz. 1800 IN RRSIG SOA 13 2 1800 20180809064029 20180727064002 33494 nic.cz. fErlGowdWxs4Fouw84ToJt02qqX+qnY+ ieVzHu+w01jj0z3tMK8uLid0G04ZRLA2 CHnO0NKCAPfRVX+K5X+yFQ==
+nic.cz. 1800 IN SOA a.ns.nic.cz. hostmaster.nic.cz. 1532677202 10800 3600 1209600 7200
+vf5fp77trrd78patqgiavtggum6cajh9.nic.cz. 7200 IN NSEC3 1 0 10 6d024fda550cdd61 vg8e7aak4v5n8qc7q065is15lgndiok5 A AAAA RRSIG
+vf5fp77trrd78patqgiavtggum6cajh9.nic.cz. 7200 IN RRSIG NSEC3 13 3 7200 20180809144711 20180727064002 33494 nic.cz. qGRXKiwS8f+uEggVDFRUqt27euEuDV+T 2rrwkPqlCXvHiaKYI/P0eTkHe2SamKZT Fe2nbLIeuppDRzKo9DPx+g==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+d.ns.nic.cz. IN DS
+SECTION AUTHORITY
+nic.cz. 1800 IN RRSIG SOA 13 2 1800 20180809064029 20180727064002 33494 nic.cz. fErlGowdWxs4Fouw84ToJt02qqX+qnY+ ieVzHu+w01jj0z3tMK8uLid0G04ZRLA2 CHnO0NKCAPfRVX+K5X+yFQ==
+nic.cz. 1800 IN SOA a.ns.nic.cz. hostmaster.nic.cz. 1532677202 10800 3600 1209600 7200
+vf5fp77trrd78patqgiavtggum6cajh9.nic.cz. 7200 IN NSEC3 1 0 10 6d024fda550cdd61 vg8e7aak4v5n8qc7q065is15lgndiok5 A AAAA RRSIG
+vf5fp77trrd78patqgiavtggum6cajh9.nic.cz. 7200 IN RRSIG NSEC3 13 3 7200 20180809144711 20180727064002 33494 nic.cz. qGRXKiwS8f+uEggVDFRUqt27euEuDV+T 2rrwkPqlCXvHiaKYI/P0eTkHe2SamKZT Fe2nbLIeuppDRzKo9DPx+g==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+d.ns.nic.cz. IN AAAA
+SECTION ANSWER
+d.ns.nic.cz. 1800 IN AAAA 2001:678:1::1
+d.ns.nic.cz. 1800 IN RRSIG AAAA 13 4 1800 20180809225253 20180727064002 33494 nic.cz. Rm0kQ0l//ZsEDNi1M3Hmns4C2aWzcGI/ oUBN92egsGSvQ0EGVgZMWZp/Pun+Tgr/ AHHCsD4lW8ZNNxHh5CCtZQ==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+cz. IN DNSKEY
+SECTION ANSWER
+cz. 18000 IN DNSKEY 256 3 13 LSpU2wluEwbQLak1XGlg3KEYygKfIiAu Q8iJxgDDSKuPLIA/BIn40LC1nPzfLwoa zmL7sPJRetzjxwtErBLCmw==
+cz. 18000 IN DNSKEY 257 3 13 nqzH7xP1QU5UOVy/VvxFSlrB/XgX9JDJ zj51PzIj35TXjZTyalTlAT/f7PAfaSD5 mEG1N8Vk9NmI2nxgQqhzDQ==
+cz. 18000 IN RRSIG DNSKEY 13 1 18000 20180803000000 20180720000000 20237 cz. 2KI6brDc06P9gKXv+omp0NDfgxwMa2DD NnMNf7sE97/vGyCVdu0FkA3NdtpUs3UC RwD3Nb5+jh7O45sLwyu6yw==
+cz. 18000 IN RRSIG DNSKEY 13 1 18000 20180808205901 20180727070544 62295 cz. ICIV0ZsxkXXW4GBBHszAaNu09H00KyVB MNm6/DZOBzz/hwnkM9XUYVboyEwrXoSC FfMdDZlHNmrhpseHnkKjYg==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH subdomain
+ADJUST copy_id copy_query
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+labs.nic.cz. IN NS
+SECTION ANSWER
+labs.nic.cz. 1800 IN NS a.ns.nic.cz.
+labs.nic.cz. 1800 IN NS b.ns.nic.cz.
+labs.nic.cz. 1800 IN NS d.ns.nic.cz.
+labs.nic.cz. 1800 IN RRSIG NS 13 3 1800 20180808225840 20180725212840 5070 labs.nic.cz. 4jhEp7GYmfxSSYschJjwKX8W/m03rDut 926G5kUJNNhaZLxTz4ORJ6IEMUz9OS6m 8tijL+7grvRjTk7bY6XQkQ==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH subdomain
+ADJUST copy_id copy_query
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+knot-resolver.cz. IN NS
+SECTION ANSWER
+knot-resolver.cz. 1800 IN NS a.ns.nic.cz.
+knot-resolver.cz. 1800 IN NS b.ns.nic.cz.
+knot-resolver.cz. 1800 IN NS d.ns.nic.cz.
+knot-resolver.cz. 1800 IN RRSIG NS 13 2 1800 20180808033000 20180725020000 34376 knot-resolver.cz. R/b3f4usP/+xCuNPKdTmG1twtSrvTOeM s9xyUn9538B2PPEhV0SHdnuzDMcgFgbw AmnDJMLqEMNce2Io76txDA==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH subdomain
+ADJUST copy_id copy_query
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+nic.cz. IN NS
+SECTION ANSWER
+nic.cz. 1800 IN NS a.ns.nic.cz.
+nic.cz. 1800 IN NS b.ns.nic.cz.
+nic.cz. 1800 IN NS d.ns.nic.cz.
+nic.cz. 1800 IN RRSIG NS 13 2 1800 20180809162254 20180727064002 33494 nic.cz. UOY4VdLFGrtMr22EaYes+1lbCAjFkhlt N5Q+0jpGucbyEFXrbxN4lFoQGpkX/+aU IWuKxWQI8VVmBKYLFBqSTw==
+SECTION ADDITIONAL
+a.ns.nic.cz. 1800 IN A 194.0.12.1
+a.ns.nic.cz. 1800 IN AAAA 2001:678:f::1
+a.ns.nic.cz. 1800 IN RRSIG A 13 4 1800 20180810011809 20180727064002 33494 nic.cz. dlRCgD1PxXFCid2m1djf5URx+SbMMFtR aaeNB5G7jj9nqFv252cwhnOz7NLPqEBG yr+h8eEOqFKbV92ZfzygLw==
+a.ns.nic.cz. 1800 IN RRSIG AAAA 13 4 1800 20180809213334 20180727064002 33494 nic.cz. TQvt6opeQKp4V/VTYgEsw25AFAD3l9I6 UE5HhJUVGpnn8YzmZZs1QTNC1ZVf0MCs Flr3H2mTNm0r/Mb3m6Q+Yw==
+b.ns.nic.cz. 1800 IN A 194.0.13.1
+b.ns.nic.cz. 1800 IN AAAA 2001:678:10::1
+b.ns.nic.cz. 1800 IN RRSIG A 13 4 1800 20180809112828 20180727064002 33494 nic.cz. GO5Wc2EWoV4yRvc3ktazw+lNZ7nGtR6S 4MsumQDKuADSGMLAhwm+htASUXxWZtV+ wWv74LD2g2cNjHpXHH1PBg==
+b.ns.nic.cz. 1800 IN RRSIG AAAA 13 4 1800 20180809130835 20180727064002 33494 nic.cz. sesuNekVgD2YLYl51sKLEYZeDmcxtQKl oFYnpXMUBVlqLTUGjn0RRcDvpJCxj/Ac isifFcEwvZ4W0B5/Ry1oVQ==
+d.ns.nic.cz. 1800 IN A 193.29.206.1
+d.ns.nic.cz. 1800 IN AAAA 2001:678:1::1
+d.ns.nic.cz. 1800 IN RRSIG A 13 4 1800 20180809211641 20180727064002 33494 nic.cz. yLSqZnGG2G5+StFxEPpuV3I5slNKLF3o 7QahlX4mKk/iN74C7zh62cR+Q/s3SDxE fFF2M/owNT3T2wspOh4L/g==
+d.ns.nic.cz. 1800 IN RRSIG AAAA 13 4 1800 20180809225253 20180727064002 33494 nic.cz. Rm0kQ0l//ZsEDNi1M3Hmns4C2aWzcGI/ oUBN92egsGSvQ0EGVgZMWZp/Pun+Tgr/ AHHCsD4lW8ZNNxHh5CCtZQ==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH subdomain
+ADJUST copy_id copy_query
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+cz. IN NS
+SECTION ANSWER
+cz. 3600 IN NS a.ns.nic.cz.
+cz. 3600 IN NS b.ns.nic.cz.
+cz. 3600 IN NS c.ns.nic.cz.
+cz. 3600 IN NS d.ns.nic.cz.
+cz. 3600 IN RRSIG NS 13 1 3600 20180806013233 20180724063548 62295 cz. NYwbiceGXv+yKrhwwMPUO5WihpVt4nip dQpjpbVxJfUp4s+j5lOHsxcbCm4EEaBx x1+UXCK6Gnw9TCnaZaOiBQ==
+SECTION ADDITIONAL
+a.ns.nic.cz. 3600 IN A 194.0.12.1
+a.ns.nic.cz. 3600 IN AAAA 2001:678:f::1
+b.ns.nic.cz. 3600 IN A 194.0.13.1
+b.ns.nic.cz. 3600 IN AAAA 2001:678:10::1
+d.ns.nic.cz. 3600 IN A 193.29.206.1
+d.ns.nic.cz. 3600 IN AAAA 2001:678:1::1
+ENTRY_END
+
+
+RANGE_END
+
+; fill in cache with negative proofs
+
+; name exists but RRtype NULL does not
+STEP 10 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+knot-resolver.cz. IN NULL
+ENTRY_END
+
+STEP 11 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH flags question rcode
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+knot-resolver.cz. IN NULL
+ENTRY_END
+
+; name does not exist
+; NSEC3 interval ei8u933svpm4qdfn713b66buji430uc7..rgofdsarih9kv8kcht41osd09tkl8o7v
+STEP 20 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+nonexistent1123.knot-resolver.cz. IN A
+ENTRY_END
+
+STEP 21 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH flags rcode question
+REPLY QR RD RA NXDOMAIN
+SECTION QUESTION
+nonexistent1123.knot-resolver.cz. IN A
+ENTRY_END
+
+; name does not exist BUT wildcard exists
+; NSEC3 interval 4o5ekull1peq8leuf98l9iudrraqmqs4..61q3lko2dr2vnmncn1sh2vdiv449lmg3
+STEP 31 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+nonexistent7.labs.nic.cz. IN A
+ENTRY_END
+
+STEP 32 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH flags rcode question answer
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+nonexistent7.labs.nic.cz. IN A
+SECTION ANSWER
+gitlab.labs.nic.cz. 1800 IN A 217.31.192.133
+;gitlab.labs.nic.cz. 1800 IN RRSIG A 13 4 1800 20180808062633 20180725045633 5070 labs.nic.cz. vIOy8SJPTE1CdRk71JAo+MxzbVhDvnh/ NQfkgdY5KOW081Jhrz74HJsAUsfJk4dD bTKY1DFVoUYYX49o0R7GGA==
+nonexistent7.labs.nic.cz. 30 IN CNAME gitlab.labs.nic.cz.
+ENTRY_END
+
+
+; check that other negative answers are generated from cache
+; (authoritative servers do not respond anymore)
+
+; name exists but RRtype TYPE65534 does not
+STEP 1010 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+knot-resolver.cz. IN TYPE65534
+ENTRY_END
+
+STEP 1011 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH rcode flags question
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+knot-resolver.cz. IN TYPE65534
+ENTRY_END
+
+
+; second name which does not exist - must be synthesized because it is in the same
+; NSEC3 interval ei8u933svpm4qdfn713b66buji430uc7..rgofdsarih9kv8kcht41osd09tkl8o7v
+STEP 1020 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+nonexistent2.knot-resolver.cz. IN A
+ENTRY_END
+
+STEP 1021 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH rcode flags question
+REPLY QR RD RA AD NXDOMAIN
+SECTION QUESTION
+nonexistent2.knot-resolver.cz. IN A
+ENTRY_END
+
+; deeper names from the same
+; NSEC3 interval ei8u933svpm4qdfn713b66buji430uc7..rgofdsarih9kv8kcht41osd09tkl8o7v
+STEP 1022 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+deep.nonexistent5.knot-resolver.cz. IN A
+ENTRY_END
+
+STEP 1023 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH rcode flags question authority
+REPLY QR RD RA DO AD NXDOMAIN
+SECTION QUESTION
+deep.nonexistent5.knot-resolver.cz. IN A
+SECTION AUTHORITY
+knot-resolver.cz. IN SOA knot-s-01.nic.cz. hostmaster.nic.cz. 2018042353 10800 3600 1209600 7200
+knot-resolver.cz. IN RRSIG SOA 13 2 1800 20180809085235 20180726072235 34376 knot-resolver.cz. Yvpm+c/R4Y/Kj1a2Bz3JQBu+5admt4mhyueV6+fJI1V5N3dEoczePO5y BZiffk91Xi2d4aYHRf2DLyfEX0HDVA==
+0b1klvkf05j25j32u97kue78u2ejhm0s.knot-resolver.cz. 1800 IN RRSIG NSEC3 13 3 7200 20180809085235 20180726072235 34376 knot-resolver.cz. KjH6+xM1sFW05x4sND+cIr2KTttyKiux2/X8SwY2PmrcK/ff6wmFejIr GUHvrG1UNS9icqQqTV3swNymGz4Dbw==
+0b1klvkf05j25j32u97kue78u2ejhm0s.knot-resolver.cz. IN NSEC3 1 0 10 F49E445B0B4AD67F EI8U933SVPM4QDFN713B66BUJI430UC7 A NS SOA MX AAAA RRSIG DNSKEY NSEC3PARAM CDS CDNSKEY
+ei8u933svpm4qdfn713b66buji430uc7.knot-resolver.cz. IN RRSIG NSEC3 13 3 7200 20180809085235 20180726072235 34376 knot-resolver.cz. 6wMAvVzU6xeyDZV1bDa/Av4n9k0kRB/x/H4aDF24oVFrRn2XTNNghu2O zmcVJV0EQlNIHd8aXfdQwLEz4FUAhw==
+ei8u933svpm4qdfn713b66buji430uc7.knot-resolver.cz. IN NSEC3 1 0 10 F49E445B0B4AD67F RGOFDSARIH9KV8KCHT41OSD09TKL8O7V NS DS RRSIG
+ENTRY_END
+
+STEP 1024 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+deeper.deep.nonexistent5.knot-resolver.cz. IN A
+ENTRY_END
+
+STEP 1025 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH rcode flags question authority
+REPLY QR RD RA DO AD NXDOMAIN
+SECTION QUESTION
+deeper.deep.nonexistent5.knot-resolver.cz. IN A
+SECTION AUTHORITY
+knot-resolver.cz. IN SOA knot-s-01.nic.cz. hostmaster.nic.cz. 2018042353 10800 3600 1209600 7200
+knot-resolver.cz. IN RRSIG SOA 13 2 1800 20180809085235 20180726072235 34376 knot-resolver.cz. Yvpm+c/R4Y/Kj1a2Bz3JQBu+5admt4mhyueV6+fJI1V5N3dEoczePO5y BZiffk91Xi2d4aYHRf2DLyfEX0HDVA==
+0b1klvkf05j25j32u97kue78u2ejhm0s.knot-resolver.cz. 1800 IN RRSIG NSEC3 13 3 7200 20180809085235 20180726072235 34376 knot-resolver.cz. KjH6+xM1sFW05x4sND+cIr2KTttyKiux2/X8SwY2PmrcK/ff6wmFejIr GUHvrG1UNS9icqQqTV3swNymGz4Dbw==
+0b1klvkf05j25j32u97kue78u2ejhm0s.knot-resolver.cz. IN NSEC3 1 0 10 F49E445B0B4AD67F EI8U933SVPM4QDFN713B66BUJI430UC7 A NS SOA MX AAAA RRSIG DNSKEY NSEC3PARAM CDS CDNSKEY
+ei8u933svpm4qdfn713b66buji430uc7.knot-resolver.cz. IN RRSIG NSEC3 13 3 7200 20180809085235 20180726072235 34376 knot-resolver.cz. 6wMAvVzU6xeyDZV1bDa/Av4n9k0kRB/x/H4aDF24oVFrRn2XTNNghu2O zmcVJV0EQlNIHd8aXfdQwLEz4FUAhw==
+ei8u933svpm4qdfn713b66buji430uc7.knot-resolver.cz. IN NSEC3 1 0 10 F49E445B0B4AD67F RGOFDSARIH9KV8KCHT41OSD09TKL8O7V NS DS RRSIG
+ENTRY_END
+
+
+; name does not exist BUT wildcard exists - must be synthesized from the same
+; NSEC3 interval 4o5ekull1peq8leuf98l9iudrraqmqs4..61q3lko2dr2vnmncn1sh2vdiv449lmg3
+STEP 1031 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+nonexistent899.labs.nic.cz. IN A
+ENTRY_END
+
+STEP 1032 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH rcode flags question answer
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+nonexistent899.labs.nic.cz. IN A
+SECTION ANSWER
+gitlab.labs.nic.cz. 1800 IN A 217.31.192.133
+gitlab.labs.nic.cz. 1800 IN RRSIG A 13 4 1800 20180808062633 20180725045633 5070 labs.nic.cz. vIOy8SJPTE1CdRk71JAo+MxzbVhDvnh/ NQfkgdY5KOW081Jhrz74HJsAUsfJk4dD bTKY1DFVoUYYX49o0R7GGA==
+nonexistent899.labs.nic.cz. 30 IN CNAME gitlab.labs.nic.cz.
+nonexistent899.labs.nic.cz. 30 IN RRSIG CNAME 13 3 30 20180808062633 20180725045633 5070 labs.nic.cz. UPdL0dAWPX68OawblUE27nbM3drLu3yE 4jTQpefbhjTTmjs3I1dJ9IXgO6AEXHFx eWnlfK2r/45KZF7v/1NN6A==
+ENTRY_END
+
+; wildcard synthesis for deeper names from the same
+; NSEC3 interval 4o5ekull1peq8leuf98l9iudrraqmqs4..61q3lko2dr2vnmncn1sh2vdiv449lmg3
+STEP 1033 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+deep.nonexistent47.labs.nic.cz. IN A
+ENTRY_END
+
+STEP 1034 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH rcode flags question answer
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+deep.nonexistent47.labs.nic.cz. IN A
+SECTION ANSWER
+gitlab.labs.nic.cz. 1800 IN A 217.31.192.133
+gitlab.labs.nic.cz. 1800 IN RRSIG A 13 4 1800 20180808062633 20180725045633 5070 labs.nic.cz. vIOy8SJPTE1CdRk71JAo+MxzbVhDvnh/ NQfkgdY5KOW081Jhrz74HJsAUsfJk4dD bTKY1DFVoUYYX49o0R7GGA==
+deep.nonexistent47.labs.nic.cz. 30 IN CNAME gitlab.labs.nic.cz.
+deep.nonexistent47.labs.nic.cz. 30 IN RRSIG CNAME 13 3 30 20180808062633 20180725045633 5070 labs.nic.cz. UPdL0dAWPX68OawblUE27nbM3drLu3yE 4jTQpefbhjTTmjs3I1dJ9IXgO6AEXHFx eWnlfK2r/45KZF7v/1NN6A==
+ENTRY_END
+
+STEP 1035 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+deeper.deep.nonexistent73.labs.nic.cz. IN A
+ENTRY_END
+
+STEP 1036 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH rcode flags question answer
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+deeper.deep.nonexistent73.labs.nic.cz. IN A
+SECTION ANSWER
+gitlab.labs.nic.cz. 1800 IN A 217.31.192.133
+gitlab.labs.nic.cz. 1800 IN RRSIG A 13 4 1800 20180808062633 20180725045633 5070 labs.nic.cz. vIOy8SJPTE1CdRk71JAo+MxzbVhDvnh/ NQfkgdY5KOW081Jhrz74HJsAUsfJk4dD bTKY1DFVoUYYX49o0R7GGA==
+deeper.deep.nonexistent73.labs.nic.cz. 30 IN CNAME gitlab.labs.nic.cz.
+deeper.deep.nonexistent73.labs.nic.cz. 30 IN RRSIG CNAME 13 3 30 20180808062633 20180725045633 5070 labs.nic.cz. UPdL0dAWPX68OawblUE27nbM3drLu3yE 4jTQpefbhjTTmjs3I1dJ9IXgO6AEXHFx eWnlfK2r/45KZF7v/1NN6A==
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/nsec3_wildcard_no_data_response.rpl b/tests/integration/deckard/sets/resolver/nsec3_wildcard_no_data_response.rpl
new file mode 100644
index 0000000..22c681f
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/nsec3_wildcard_no_data_response.rpl
@@ -0,0 +1,112 @@
+do-ip6: no
+
+; config options
+;server:
+ stub-addr: 193.0.14.129
+ trust-anchor: ". 3600 IN DS 19036 8 2 49AAC11D7B6F6446702E54A1607371607A1A41855200FD2CE1CDDE32F24E8FB5"
+ val-override-timestamp: "1450794800"
+ query-minimization: off
+CONFIG_END
+
+SCENARIO_BEGIN Test validation of NSEC wildcard answer response.
+
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+. IN DNSKEY
+SECTION ANSWER
+. 15182 IN DNSKEY 256 3 8 AwEAAbr/RV0stAWYbmKOldjShp4AOQGOyY3ATI1NUpP4X1qBs6lsXpc+1ABgv6zkg02IktjZrHnmD0HsElu3wqXMrT5KL1W7Spmg0Pou9WZ8QttdTKXwrVXrASsaGI2z/pLBSnK8EdzqUrTVxY4TEGZtxV519isM06CCMihxTn5cfFBF
+. 15182 IN DNSKEY 256 3 8 AwEAAbgVvZmZibtBpha3AIykU0OY4gcCXTcskYJUxGsdmV/awfmKcHlSrjNMioSgy4sByj+HpcbsyrZVGPp+JBXzYwwuEF/6w1k7vKYTK6vMSqgVcgooNkfb5MaRF2y7MEpPxfStnfwu8knE24ExB0hYE1URxJ9CqB3zMSl/vicXYXXl
+. 15182 IN DNSKEY 257 3 8 AwEAAagAIKlVZrpC6Ia7gEzahOR+9W29euxhJhVVLOyQbSEW0O8gcCjFFVQUTf6v58fLjwBd0YI0EzrAcQqBGCzh/RStIoO8g0NfnfL2MTJRkxoXbfDaUeVPQuYEhg37NZWAJQ9VnMVDxP/VHL496M/QZxkjf5/Efucp2gaDX6RS6CXpoY68LsvPVjR0ZSwzz1apAzvN9dlzEheX7ICJBBtuA6G3LQpzW5hOA2hzCTMjJPJ8LbqF6dsV6DoBQzgul0sGIcGOYl7OyQdXfZ57relSQageu+ipAdTTJ25AsRTAoub8ONGcLmqrAmRLKBP1dfwhYB4N7knNnulqQxA+Uk1ihz0=
+. 15182 IN RRSIG DNSKEY 8 0 172800 20160105235959 20151221000000 19036 . BfU0HEA1JUuZA0+4EXsFhwW7iH03vwPD+u9DtjF5mmeITV7kkJyg8IguzAlPsLDNFfe+hudz+NZafgaGq1bMUT3Ax4/qlH5qxVBfJi/n8fWeF4hEcyGtIsDVBsTUwqez7ZXVVoUffHcLAE+xuXaKeqdiz9bU70vsCMNu+DmIWXi8G1AFV/fjqtN1UtxF91R2XajWvSFm2tfOnGUJ6iS4tvxWe2Qi133CNMP1P3zd7oWiFg2bTwt2OjlhGH3CAg2WvDt72t/9hGNDy/dk2ukOZv4V1lsv2X4cW5NVN6ZmVf/UMyTdD/YGumHkTMbGKHHbTyBlJjYdBf0yXBTXD9Hulg==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+cz. IN DS
+SECTION ANSWER
+cz. 86400 IN DS 54576 10 2 397E50C85EDE9CDE33F363A9E66FD1B216D788F8DD438A57A423A386869C8F06
+cz. 86400 IN RRSIG DS 8 1 86400 20160101050000 20151222040000 62530 . RW66z4Mh1Z97WHCw9exQB24SvNQ9nFC6zYZ+Ta6MuiLXLQnrn5OcEeZia0cotsa1W/7N55a/JzS0PCOBuQoGEZyRhWva9Cdl6PcKzAskD4UEWLeWnBDZfSL21a+fxl/aPDslfxhG78ZB7nTj0PRdqE6HK97DHwDyF5HNNzq7r4E=
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RD NOERROR
+SECTION QUESTION
+qwr.cz. IN A
+SECTION AUTHORITY
+cz. 172800 IN NS a.ns.nic.cz.
+cz. 86400 IN DS 54576 10 2 397E50C85EDE9CDE33F363A9E66FD1B216D788F8DD438A57A423A386869C8F06
+cz. 86400 IN RRSIG DS 8 1 86400 20160101050000 20151222040000 62530 . RW66z4Mh1Z97WHCw9exQB24SvNQ9nFC6zYZ+Ta6MuiLXLQnrn5OcEeZia0cotsa1W/7N55a/JzS0PCOBuQoGEZyRhWva9Cdl6PcKzAskD4UEWLeWnBDZfSL21a+fxl/aPDslfxhG78ZB7nTj0PRdqE6HK97DHwDyF5HNNzq7r4E=
+SECTION ADDITIONAL
+a.ns.nic.cz. 172800 IN A 194.0.12.1
+ENTRY_END
+RANGE_END
+
+RANGE_BEGIN 0 100
+ ADDRESS 194.0.12.1
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+cz. IN DNSKEY
+SECTION ANSWER
+cz. 18000 IN DNSKEY 256 3 10 AwEAAdptcFzJsHzR4xeGi3Cyq5FG9N0S3Ch9qrSIa3rQHsKwsdgfNZ5UX5v91AROH9lZo60d/fIxtuDefnID+uIJDAsiwIAzWFzJbmCBPJ24jqhCJ03N6ejrIM1qvvwjnoh655wh2LfaejnDMdjPth0L+q+vRoJL0cjv0dhdDs532ch/
+cz. 18000 IN DNSKEY 257 3 10 AwEAAay0hi4HN2r/BqMQTpIPIVDyjmyF+9ZWvr5Lewx+q+947o/GrRv4FGFfkZxf9CFfYVUf0jG5Yq4i06pGVNwJl81HS9Ux2oeHRXUvgtLnl5HeRVLL+zgI5byx9HSNr4bPO8ZEn5OjoayhkNyGSFr4VWrzQk/K02vLP4d1cCEzUQy30eyZto2/tG5ZwCU/iRkS1PJOcOW98hiFIfFDZv1XjbEpqEYhT2PATs6rt+BKwSHKGISmg1PNdg+y0rItemYMWr1f9BGAdtTWoPCPCYPjOZMPoIyA4tMscD+ww54Jf/QNoHccY4hO1yHiuAXG7SUn8jo0IKQ9W7JJxES0aqFCX/0=
+cz. 18000 IN RRSIG DNSKEY 10 1 18000 20151230000000 20151216000000 54576 cz. d1tJTXuUjtEa5JO07K7clczFvUgSNHHO0o6LT8HL2i0a2K6P6A9g9pWywarBNYpRJrwlq243Pub5cU2Tr+MNwzyYgORVO7gFPTTLDZlRAWmE3ujGNrzsVcalQHBQzwji5JN20ujnps1jj7Xy17pHJCLbnNEZP6HkQR4b7GkSI5iAFYSZ8vYzWup5Ei57EIlpPRVJtB6K6Sa4vPaRhXQgwFZBtcmgfBLMI7YQrMpjKMftpHsabzB4gjTB8TLofJR8hPWCR2x7+X9HMtj9O6U93WyIYCC41hCCLON8yNIxhp8tjKN/ZxTy5JycElxMHvGaxFl8kuVBAySdVRsxx+Ffwg==
+cz. 18000 IN RRSIG DNSKEY 10 1 18000 20160105041723 20151222140958 50870 cz. sr+1HKa9BqRSNLDF8hpcKL9MVm6vR3WMeEpOokYK4ij2wCGcv8fzdFJg6Wc7dSKhs5Jt3+toq4ypFtkcIjN7UTgokWD87Du3oKeZUsrISCSpoMpz3Q5ozpLSU/aqmuXrAFqMKNAXQ6uEf6vfJoHuESmouH7r9muNv9AetYCG0S4=
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA RD NXDOMAIN
+SECTION QUESTION
+qwr.cz. IN A
+SECTION AUTHORITY
+cz. 900 IN SOA a.ns.nic.cz. hostmaster.nic.cz. 1450796998 900 300 604800 900
+e07bsbm6cddl06sj99fmff7td56savbn.cz. 900 IN NSEC3 1 0 10 FC6C06CB130A4809 E07G4NAI26HIBP3R8NEJGTUVV1JPT11N NS SOA RRSIG DNSKEY NSEC3PARAM
+9tjfc6416bffr8mbna7d52ke1hpes293.cz. 900 IN NSEC3 1 0 10 FC6C06CB130A4809 9TJLDJIGE8VDG8MMHORIG0DCLM4NA5F5 NS
+4qk800tsde3b9rihkgedb581mv504cha.cz. 900 IN NSEC3 1 0 10 FC6C06CB130A4809 4QK94GS2KQ6T0C5HTJROTGVJMBQK7RFC NS
+cz. 18000 IN RRSIG SOA 10 1 18000 20160104010623 20151222140958 50870 cz. RhhKmE9ZAoqiAFoSH6ZFSomqVFmHF99xKgPGxf+3QSLrohPOYiuLL/CVEEjUxiITDd7g3jfRN/ZzHNOm6cU0kLqmSf4kaOfBE+bJ/5w6NBAARvWsirk3M//IVJ7G603Dizsykt9fkEaLpstAtJXdhLq1pUqAEXYmyEOKlgYOe+A=
+e07bsbm6cddl06sj99fmff7td56savbn.cz. 900 IN RRSIG NSEC3 10 2 900 20160104070356 20151222070953 50870 cz. yzP9bcqgS1KoHJCY7qi/NEvtkUAKTN70dbMJKZAWAmNJX9RYsGEV+VNg2D8ifZ2jxxcMXbO0kPjFiJXNg7Jz1ekmpEBC+wYMVvgVhtVhKzAIfMIweiSwiOqKFTmyyb0Tk/WukrYAqDFaeQ7nTJzl+kLU8sH72yOiYyWUJDDQHpo=
+9tjfc6416bffr8mbna7d52ke1hpes293.cz. 900 IN RRSIG NSEC3 10 2 900 20151230104714 20151216200951 50870 cz. n4hQwoX3aOVNNEei/46RCkR+J4TOwCq9Pe+ikEIsXBrj+xOOf0bAd/bthUq2wBX05e2SVem6YnzW9UyaRqwOS0pRvtypAdcmgrTXtaKVI+0+EiwaZHPF1fLi3+p9kxrGkJ5wkyKiFUrfa4zstEoQMnMxTU4eQUBDYgN3LlrEQcc=
+4qk800tsde3b9rihkgedb581mv504cha.cz. 900 IN RRSIG NSEC3 10 2 900 20151230070920 20151217171007 50870 cz. ZR76bT+u5t5tJ1qoYhS8Ak6OgHRfY9T0FjQrEuRd9U7ROTytxGDupH+nZZfnMyTC48ELrZRCHvxwFYskbI2XtBWyE3Vaid43ntq9b+eAvjqYYXJu5V1wC8+K56LlmStdCL/U4OEliwfPHuUnS/AcX0hci2XSslGWRfJzTVLjQcc=
+ENTRY_END
+RANGE_END
+
+STEP 10 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+qwr.cz. IN A
+ENTRY_END
+
+STEP 20 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA AD NXDOMAIN
+SECTION QUESTION
+qwr.cz. IN A
+SECTION AUTHORITY
+cz. 900 IN SOA a.ns.nic.cz. hostmaster.nic.cz. 1450796998 900 300 604800 900
+e07bsbm6cddl06sj99fmff7td56savbn.cz. 900 IN NSEC3 1 0 10 FC6C06CB130A4809 E07G4NAI26HIBP3R8NEJGTUVV1JPT11N NS SOA RRSIG DNSKEY NSEC3PARAM
+9tjfc6416bffr8mbna7d52ke1hpes293.cz. 900 IN NSEC3 1 0 10 FC6C06CB130A4809 9TJLDJIGE8VDG8MMHORIG0DCLM4NA5F5 NS
+4qk800tsde3b9rihkgedb581mv504cha.cz. 900 IN NSEC3 1 0 10 FC6C06CB130A4809 4QK94GS2KQ6T0C5HTJROTGVJMBQK7RFC NS
+cz. 18000 IN RRSIG SOA 10 1 18000 20160104010623 20151222140958 50870 cz. RhhKmE9ZAoqiAFoSH6ZFSomqVFmHF99xKgPGxf+3QSLrohPOYiuLL/CVEEjUxiITDd7g3jfRN/ZzHNOm6cU0kLqmSf4kaOfBE+bJ/5w6NBAARvWsirk3M//IVJ7G603Dizsykt9fkEaLpstAtJXdhLq1pUqAEXYmyEOKlgYOe+A=
+e07bsbm6cddl06sj99fmff7td56savbn.cz. 900 IN RRSIG NSEC3 10 2 900 20160104070356 20151222070953 50870 cz. yzP9bcqgS1KoHJCY7qi/NEvtkUAKTN70dbMJKZAWAmNJX9RYsGEV+VNg2D8ifZ2jxxcMXbO0kPjFiJXNg7Jz1ekmpEBC+wYMVvgVhtVhKzAIfMIweiSwiOqKFTmyyb0Tk/WukrYAqDFaeQ7nTJzl+kLU8sH72yOiYyWUJDDQHpo=
+9tjfc6416bffr8mbna7d52ke1hpes293.cz. 900 IN RRSIG NSEC3 10 2 900 20151230104714 20151216200951 50870 cz. n4hQwoX3aOVNNEei/46RCkR+J4TOwCq9Pe+ikEIsXBrj+xOOf0bAd/bthUq2wBX05e2SVem6YnzW9UyaRqwOS0pRvtypAdcmgrTXtaKVI+0+EiwaZHPF1fLi3+p9kxrGkJ5wkyKiFUrfa4zstEoQMnMxTU4eQUBDYgN3LlrEQcc=
+4qk800tsde3b9rihkgedb581mv504cha.cz. 900 IN RRSIG NSEC3 10 2 900 20151230070920 20151217171007 50870 cz. ZR76bT+u5t5tJ1qoYhS8Ak6OgHRfY9T0FjQrEuRd9U7ROTytxGDupH+nZZfnMyTC48ELrZRCHvxwFYskbI2XtBWyE3Vaid43ntq9b+eAvjqYYXJu5V1wC8+K56LlmStdCL/U4OEliwfPHuUnS/AcX0hci2XSslGWRfJzTVLjQcc=
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/nsec_aggr_cache.rpl b/tests/integration/deckard/sets/resolver/nsec_aggr_cache.rpl
new file mode 100644
index 0000000..9c3a5fe
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/nsec_aggr_cache.rpl
@@ -0,0 +1,6395 @@
+ trust-anchor: ". IN DS 19036 8 2 49AAC11D7B6F6446702E54A1607371607A1A41855200FD2CE1CDDE32F24E8FB5"
+ trust-anchor: ". IN DS 20326 8 2 E06D44B80B8F1D39A95C0B0D7C65D08458E880409BBC683457104237C7F8EC8D"
+ val-override-date: 20180727184403
+ stub-addr: 2001:7fe::53
+ do-ip4: no
+CONFIG_END
+
+SCENARIO_BEGIN qlist
+
+; Scope ".
+
+; Server names:
+; f.root-servers.net.
+; a.root-servers.net.
+; j.root-servers.net.
+; e.root-servers.net.
+; i.root-servers.net.
+; d.root-servers.net.
+; m.root-servers.net.
+; h.root-servers.net.
+; c.root-servers.net.
+; l.root-servers.net.
+; g.root-servers.net.
+; b.root-servers.net.
+; k.root-servers.net.
+RANGE_BEGIN 0 1000
+ ADDRESS 2001:7fe::53
+ ADDRESS 192.203.230.10
+ ADDRESS 2001:500:2d::d
+ ADDRESS 193.0.14.129
+ ADDRESS 202.12.27.33
+ ADDRESS 192.112.36.4
+ ADDRESS 2001:500:2f::f
+ ADDRESS 198.97.190.53
+ ADDRESS 192.5.5.241
+ ADDRESS 199.7.91.13
+ ADDRESS 199.9.14.201
+ ADDRESS 192.58.128.30
+ ADDRESS 2001:500:a8::e
+ ADDRESS 198.41.0.4
+ ADDRESS 2001:500:9f::42
+ ADDRESS 2001:dc3::35
+ ADDRESS 192.33.4.12
+ ADDRESS 199.7.83.42
+ ADDRESS 2001:500:1::53
+ ADDRESS 2001:503:ba3e::2:30
+ ADDRESS 2001:7fd::1
+ ADDRESS 2001:500:2::c
+ ADDRESS 2001:500:200::b
+ ADDRESS 2001:503:c27::2:30
+ ADDRESS 2001:500:12::d0d
+ ADDRESS 192.36.148.17
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+hm. IN DS
+SECTION AUTHORITY
+. 86400 IN RRSIG SOA 8 0 86400 20180809050000 20180727040000 41656 . zo+cNHA1N9Av53qwpB/bCmnTxAWj6ubo 58W4VkEPk9jzrOKvCm9dVJv7P+JJOX5C t5yx4zch+DBRSRR1U9mmrbegEX4hXtec L3Ev9ZpxYAYUFd7gQ/oM5ZyrUZ08wLYg pYV6vE4qYdxP58dtknbpGUQKz4H3l0SQ eWoSyhOtYK9nNovCNN0swXdkmogEhDxP gY1nhEZiLXFH8W8/G96IgAa2hineMnqV 0z8/K2m7EGjwszDOyCD05Z77cMAryvjL X6Jm7I83+D8UwtfAck8ZGDJFz3l+w08G oeB9ntD1OicidpLtHmeSsN+1nuEL3s1M U47kwIJMAHu8bcyvm4HGRw==
+. 86400 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018072700 1800 900 604800 86400
+hm. 86400 IN NSEC hn. NS RRSIG NSEC
+hm. 86400 IN RRSIG NSEC 8 1 86400 20180809050000 20180727040000 41656 . vI+rf8FDWlQOpAPeJTvoMH7bceC0qe2U hzdXApcCQK50pacs356TAcnKRKsNu+wa qR0+pM51vnG1AT+pPSK0M70soXrbh8uI TfFMV6u+/6qgU9TzzzQk49UK4Ww6m4l6 uh7/I302reJjTsc9mpCrjkRX7lk96c31 xzcYMlbADfzQsCfofoZDw7bS45mY6nRH /zTNUuEtFZGef0XtkNK9Op32Sf7Qqqqu YuzKBWa1irDaYCCLeyaqSmXQDzl7xKQa szrWtZeA1pwxJ2KKzCfuaYsRk/R6INLv i4tfJ73oKHl7nhKxH/K1fWUrWTuxkR1q R1zQb7VOg0Jf9GUqXxPVXg==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR RD NOERROR
+SECTION QUESTION
+hm. IN DNSKEY
+SECTION AUTHORITY
+hm. 172800 IN NS ns1.registry.hm.
+hm. 172800 IN NS ns2.registry.hm.
+hm. 172800 IN NS ns3.registry.hm.
+hm. 86400 IN NSEC hn. NS RRSIG NSEC
+hm. 86400 IN RRSIG NSEC 8 1 86400 20180809050000 20180727040000 41656 . vI+rf8FDWlQOpAPeJTvoMH7bceC0qe2U hzdXApcCQK50pacs356TAcnKRKsNu+wa qR0+pM51vnG1AT+pPSK0M70soXrbh8uI TfFMV6u+/6qgU9TzzzQk49UK4Ww6m4l6 uh7/I302reJjTsc9mpCrjkRX7lk96c31 xzcYMlbADfzQsCfofoZDw7bS45mY6nRH /zTNUuEtFZGef0XtkNK9Op32Sf7Qqqqu YuzKBWa1irDaYCCLeyaqSmXQDzl7xKQa szrWtZeA1pwxJ2KKzCfuaYsRk/R6INLv i4tfJ73oKHl7nhKxH/K1fWUrWTuxkR1q R1zQb7VOg0Jf9GUqXxPVXg==
+SECTION ADDITIONAL
+ns1.registry.hm. 172800 IN A 208.70.79.25
+ns2.registry.hm. 172800 IN A 208.70.79.24
+ns3.registry.hm. 172800 IN A 128.199.180.188
+ns1.registry.hm. 172800 IN AAAA 1::1
+ns2.registry.hm. 172800 IN AAAA 1::2
+ns3.registry.hm. 172800 IN AAAA 1::3
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR RD NOERROR
+SECTION QUESTION
+hm. IN A
+SECTION AUTHORITY
+hm. 172800 IN NS ns1.registry.hm.
+hm. 172800 IN NS ns2.registry.hm.
+hm. 172800 IN NS ns3.registry.hm.
+hm. 86400 IN NSEC hn. NS RRSIG NSEC
+hm. 86400 IN RRSIG NSEC 8 1 86400 20180809050000 20180727040000 41656 . vI+rf8FDWlQOpAPeJTvoMH7bceC0qe2U hzdXApcCQK50pacs356TAcnKRKsNu+wa qR0+pM51vnG1AT+pPSK0M70soXrbh8uI TfFMV6u+/6qgU9TzzzQk49UK4Ww6m4l6 uh7/I302reJjTsc9mpCrjkRX7lk96c31 xzcYMlbADfzQsCfofoZDw7bS45mY6nRH /zTNUuEtFZGef0XtkNK9Op32Sf7Qqqqu YuzKBWa1irDaYCCLeyaqSmXQDzl7xKQa szrWtZeA1pwxJ2KKzCfuaYsRk/R6INLv i4tfJ73oKHl7nhKxH/K1fWUrWTuxkR1q R1zQb7VOg0Jf9GUqXxPVXg==
+SECTION ADDITIONAL
+ns1.registry.hm. 172800 IN A 208.70.79.25
+ns2.registry.hm. 172800 IN A 208.70.79.24
+ns3.registry.hm. 172800 IN A 128.199.180.188
+ns1.registry.hm. 172800 IN AAAA 1::1
+ns2.registry.hm. 172800 IN AAAA 1::2
+ns3.registry.hm. 172800 IN AAAA 1::3
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR RD NOERROR
+SECTION QUESTION
+hm. IN SOA
+SECTION AUTHORITY
+hm. 172800 IN NS ns1.registry.hm.
+hm. 172800 IN NS ns2.registry.hm.
+hm. 172800 IN NS ns3.registry.hm.
+hm. 86400 IN NSEC hn. NS RRSIG NSEC
+hm. 86400 IN RRSIG NSEC 8 1 86400 20180809050000 20180727040000 41656 . vI+rf8FDWlQOpAPeJTvoMH7bceC0qe2U hzdXApcCQK50pacs356TAcnKRKsNu+wa qR0+pM51vnG1AT+pPSK0M70soXrbh8uI TfFMV6u+/6qgU9TzzzQk49UK4Ww6m4l6 uh7/I302reJjTsc9mpCrjkRX7lk96c31 xzcYMlbADfzQsCfofoZDw7bS45mY6nRH /zTNUuEtFZGef0XtkNK9Op32Sf7Qqqqu YuzKBWa1irDaYCCLeyaqSmXQDzl7xKQa szrWtZeA1pwxJ2KKzCfuaYsRk/R6INLv i4tfJ73oKHl7nhKxH/K1fWUrWTuxkR1q R1zQb7VOg0Jf9GUqXxPVXg==
+SECTION ADDITIONAL
+ns1.registry.hm. 172800 IN A 208.70.79.25
+ns2.registry.hm. 172800 IN A 208.70.79.24
+ns3.registry.hm. 172800 IN A 128.199.180.188
+ns1.registry.hm. 172800 IN AAAA 1::1
+ns2.registry.hm. 172800 IN AAAA 1::2
+ns3.registry.hm. 172800 IN AAAA 1::3
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NXDOMAIN
+SECTION QUESTION
+sk2. IN DS
+SECTION AUTHORITY
+. 86400 IN NSEC aaa. NS SOA RRSIG NSEC DNSKEY
+. 86400 IN RRSIG NSEC 8 0 86400 20180809050000 20180727040000 41656 . CU1vfnY07l8A4bd60jFERRzilD9G1Glp Cx5l/o65fIh2fvCTt/pn4C1W1MfpHIOv j23gN/HS3m64+UE6lYPbJlrOcCLOslgK C+8tfmqWjDbI2C5jnDK0shibLIU2MW3L +0PxOZWOeU2a6XRUYYkqyI9jpfQIEDcZ fuQWiBXOtneXsLKNfQf4YxwC+WCxHGPu mc1g9hza83iziIfgmzxFU5Hg05HjAnni Uw4PL8sNrAZsv4sRZqtfoM6KHo84RCP+ Y2pIR97bPW0dspAtTjD9WAbTz0DpvC3f o3flnVlnWxdJhDEBRASUzAGc2d4FwzPO JdbCJNde9bc9VKSx1jEHpQ==
+. 86400 IN RRSIG SOA 8 0 86400 20180809050000 20180727040000 41656 . zo+cNHA1N9Av53qwpB/bCmnTxAWj6ubo 58W4VkEPk9jzrOKvCm9dVJv7P+JJOX5C t5yx4zch+DBRSRR1U9mmrbegEX4hXtec L3Ev9ZpxYAYUFd7gQ/oM5ZyrUZ08wLYg pYV6vE4qYdxP58dtknbpGUQKz4H3l0SQ eWoSyhOtYK9nNovCNN0swXdkmogEhDxP gY1nhEZiLXFH8W8/G96IgAa2hineMnqV 0z8/K2m7EGjwszDOyCD05Z77cMAryvjL X6Jm7I83+D8UwtfAck8ZGDJFz3l+w08G oeB9ntD1OicidpLtHmeSsN+1nuEL3s1M U47kwIJMAHu8bcyvm4HGRw==
+. 86400 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018072700 1800 900 604800 86400
+sk. 86400 IN NSEC ski. NS RRSIG NSEC
+sk. 86400 IN RRSIG NSEC 8 1 86400 20180809050000 20180727040000 41656 . Z7ihB8GIbqYBTvBPWxq22UkxSfJf/1I5 eIQ0E3cCVB+srJs2mECa3FmiPkzaYEZv mGzDNGlr5T2BHunJHWVED3gN6Y9Mn0YD 8v+0sIfPTTO74uWxHZFQsudZSzBqWaEI S2zHlM8VTiE6/x6QrAyDNIdjLSI5563X q/qVCsYxx10bRKIog4g73ZwBvlmwd1wa Rd/IIaEDCRO/ed6yFMOL5dhhMERrcJVY HdbNCpSb27LT4HFoqXtBMt1Z8VJVqDI3 NMojUq7a0JWMrFhBEiNwgNJ5xHCiiDuc 4nvszt1wiZAebsr8Qcniy4PrDDs+3XOg lBDRhozaOZYS436/Bs27Xw==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NXDOMAIN
+SECTION QUESTION
+sk2. IN DNSKEY
+SECTION AUTHORITY
+. 86400 IN NSEC aaa. NS SOA RRSIG NSEC DNSKEY
+. 86400 IN RRSIG NSEC 8 0 86400 20180809050000 20180727040000 41656 . CU1vfnY07l8A4bd60jFERRzilD9G1Glp Cx5l/o65fIh2fvCTt/pn4C1W1MfpHIOv j23gN/HS3m64+UE6lYPbJlrOcCLOslgK C+8tfmqWjDbI2C5jnDK0shibLIU2MW3L +0PxOZWOeU2a6XRUYYkqyI9jpfQIEDcZ fuQWiBXOtneXsLKNfQf4YxwC+WCxHGPu mc1g9hza83iziIfgmzxFU5Hg05HjAnni Uw4PL8sNrAZsv4sRZqtfoM6KHo84RCP+ Y2pIR97bPW0dspAtTjD9WAbTz0DpvC3f o3flnVlnWxdJhDEBRASUzAGc2d4FwzPO JdbCJNde9bc9VKSx1jEHpQ==
+. 86400 IN RRSIG SOA 8 0 86400 20180809050000 20180727040000 41656 . zo+cNHA1N9Av53qwpB/bCmnTxAWj6ubo 58W4VkEPk9jzrOKvCm9dVJv7P+JJOX5C t5yx4zch+DBRSRR1U9mmrbegEX4hXtec L3Ev9ZpxYAYUFd7gQ/oM5ZyrUZ08wLYg pYV6vE4qYdxP58dtknbpGUQKz4H3l0SQ eWoSyhOtYK9nNovCNN0swXdkmogEhDxP gY1nhEZiLXFH8W8/G96IgAa2hineMnqV 0z8/K2m7EGjwszDOyCD05Z77cMAryvjL X6Jm7I83+D8UwtfAck8ZGDJFz3l+w08G oeB9ntD1OicidpLtHmeSsN+1nuEL3s1M U47kwIJMAHu8bcyvm4HGRw==
+. 86400 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018072700 1800 900 604800 86400
+sk. 86400 IN NSEC ski. NS RRSIG NSEC
+sk. 86400 IN RRSIG NSEC 8 1 86400 20180809050000 20180727040000 41656 . Z7ihB8GIbqYBTvBPWxq22UkxSfJf/1I5 eIQ0E3cCVB+srJs2mECa3FmiPkzaYEZv mGzDNGlr5T2BHunJHWVED3gN6Y9Mn0YD 8v+0sIfPTTO74uWxHZFQsudZSzBqWaEI S2zHlM8VTiE6/x6QrAyDNIdjLSI5563X q/qVCsYxx10bRKIog4g73ZwBvlmwd1wa Rd/IIaEDCRO/ed6yFMOL5dhhMERrcJVY HdbNCpSb27LT4HFoqXtBMt1Z8VJVqDI3 NMojUq7a0JWMrFhBEiNwgNJ5xHCiiDuc 4nvszt1wiZAebsr8Qcniy4PrDDs+3XOg lBDRhozaOZYS436/Bs27Xw==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NXDOMAIN
+SECTION QUESTION
+sk2. IN NS
+SECTION AUTHORITY
+. 86400 IN NSEC aaa. NS SOA RRSIG NSEC DNSKEY
+. 86400 IN RRSIG NSEC 8 0 86400 20180809050000 20180727040000 41656 . CU1vfnY07l8A4bd60jFERRzilD9G1Glp Cx5l/o65fIh2fvCTt/pn4C1W1MfpHIOv j23gN/HS3m64+UE6lYPbJlrOcCLOslgK C+8tfmqWjDbI2C5jnDK0shibLIU2MW3L +0PxOZWOeU2a6XRUYYkqyI9jpfQIEDcZ fuQWiBXOtneXsLKNfQf4YxwC+WCxHGPu mc1g9hza83iziIfgmzxFU5Hg05HjAnni Uw4PL8sNrAZsv4sRZqtfoM6KHo84RCP+ Y2pIR97bPW0dspAtTjD9WAbTz0DpvC3f o3flnVlnWxdJhDEBRASUzAGc2d4FwzPO JdbCJNde9bc9VKSx1jEHpQ==
+. 86400 IN RRSIG SOA 8 0 86400 20180809050000 20180727040000 41656 . zo+cNHA1N9Av53qwpB/bCmnTxAWj6ubo 58W4VkEPk9jzrOKvCm9dVJv7P+JJOX5C t5yx4zch+DBRSRR1U9mmrbegEX4hXtec L3Ev9ZpxYAYUFd7gQ/oM5ZyrUZ08wLYg pYV6vE4qYdxP58dtknbpGUQKz4H3l0SQ eWoSyhOtYK9nNovCNN0swXdkmogEhDxP gY1nhEZiLXFH8W8/G96IgAa2hineMnqV 0z8/K2m7EGjwszDOyCD05Z77cMAryvjL X6Jm7I83+D8UwtfAck8ZGDJFz3l+w08G oeB9ntD1OicidpLtHmeSsN+1nuEL3s1M U47kwIJMAHu8bcyvm4HGRw==
+. 86400 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018072700 1800 900 604800 86400
+sk. 86400 IN NSEC ski. NS RRSIG NSEC
+sk. 86400 IN RRSIG NSEC 8 1 86400 20180809050000 20180727040000 41656 . Z7ihB8GIbqYBTvBPWxq22UkxSfJf/1I5 eIQ0E3cCVB+srJs2mECa3FmiPkzaYEZv mGzDNGlr5T2BHunJHWVED3gN6Y9Mn0YD 8v+0sIfPTTO74uWxHZFQsudZSzBqWaEI S2zHlM8VTiE6/x6QrAyDNIdjLSI5563X q/qVCsYxx10bRKIog4g73ZwBvlmwd1wa Rd/IIaEDCRO/ed6yFMOL5dhhMERrcJVY HdbNCpSb27LT4HFoqXtBMt1Z8VJVqDI3 NMojUq7a0JWMrFhBEiNwgNJ5xHCiiDuc 4nvszt1wiZAebsr8Qcniy4PrDDs+3XOg lBDRhozaOZYS436/Bs27Xw==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NXDOMAIN
+SECTION QUESTION
+sk2. IN A
+SECTION AUTHORITY
+. 86400 IN NSEC aaa. NS SOA RRSIG NSEC DNSKEY
+. 86400 IN RRSIG NSEC 8 0 86400 20180809050000 20180727040000 41656 . CU1vfnY07l8A4bd60jFERRzilD9G1Glp Cx5l/o65fIh2fvCTt/pn4C1W1MfpHIOv j23gN/HS3m64+UE6lYPbJlrOcCLOslgK C+8tfmqWjDbI2C5jnDK0shibLIU2MW3L +0PxOZWOeU2a6XRUYYkqyI9jpfQIEDcZ fuQWiBXOtneXsLKNfQf4YxwC+WCxHGPu mc1g9hza83iziIfgmzxFU5Hg05HjAnni Uw4PL8sNrAZsv4sRZqtfoM6KHo84RCP+ Y2pIR97bPW0dspAtTjD9WAbTz0DpvC3f o3flnVlnWxdJhDEBRASUzAGc2d4FwzPO JdbCJNde9bc9VKSx1jEHpQ==
+. 86400 IN RRSIG SOA 8 0 86400 20180809050000 20180727040000 41656 . zo+cNHA1N9Av53qwpB/bCmnTxAWj6ubo 58W4VkEPk9jzrOKvCm9dVJv7P+JJOX5C t5yx4zch+DBRSRR1U9mmrbegEX4hXtec L3Ev9ZpxYAYUFd7gQ/oM5ZyrUZ08wLYg pYV6vE4qYdxP58dtknbpGUQKz4H3l0SQ eWoSyhOtYK9nNovCNN0swXdkmogEhDxP gY1nhEZiLXFH8W8/G96IgAa2hineMnqV 0z8/K2m7EGjwszDOyCD05Z77cMAryvjL X6Jm7I83+D8UwtfAck8ZGDJFz3l+w08G oeB9ntD1OicidpLtHmeSsN+1nuEL3s1M U47kwIJMAHu8bcyvm4HGRw==
+. 86400 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018072700 1800 900 604800 86400
+sk. 86400 IN NSEC ski. NS RRSIG NSEC
+sk. 86400 IN RRSIG NSEC 8 1 86400 20180809050000 20180727040000 41656 . Z7ihB8GIbqYBTvBPWxq22UkxSfJf/1I5 eIQ0E3cCVB+srJs2mECa3FmiPkzaYEZv mGzDNGlr5T2BHunJHWVED3gN6Y9Mn0YD 8v+0sIfPTTO74uWxHZFQsudZSzBqWaEI S2zHlM8VTiE6/x6QrAyDNIdjLSI5563X q/qVCsYxx10bRKIog4g73ZwBvlmwd1wa Rd/IIaEDCRO/ed6yFMOL5dhhMERrcJVY HdbNCpSb27LT4HFoqXtBMt1Z8VJVqDI3 NMojUq7a0JWMrFhBEiNwgNJ5xHCiiDuc 4nvszt1wiZAebsr8Qcniy4PrDDs+3XOg lBDRhozaOZYS436/Bs27Xw==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NXDOMAIN
+SECTION QUESTION
+sk2. IN AAAA
+SECTION AUTHORITY
+. 86400 IN NSEC aaa. NS SOA RRSIG NSEC DNSKEY
+. 86400 IN RRSIG NSEC 8 0 86400 20180809050000 20180727040000 41656 . CU1vfnY07l8A4bd60jFERRzilD9G1Glp Cx5l/o65fIh2fvCTt/pn4C1W1MfpHIOv j23gN/HS3m64+UE6lYPbJlrOcCLOslgK C+8tfmqWjDbI2C5jnDK0shibLIU2MW3L +0PxOZWOeU2a6XRUYYkqyI9jpfQIEDcZ fuQWiBXOtneXsLKNfQf4YxwC+WCxHGPu mc1g9hza83iziIfgmzxFU5Hg05HjAnni Uw4PL8sNrAZsv4sRZqtfoM6KHo84RCP+ Y2pIR97bPW0dspAtTjD9WAbTz0DpvC3f o3flnVlnWxdJhDEBRASUzAGc2d4FwzPO JdbCJNde9bc9VKSx1jEHpQ==
+. 86400 IN RRSIG SOA 8 0 86400 20180809050000 20180727040000 41656 . zo+cNHA1N9Av53qwpB/bCmnTxAWj6ubo 58W4VkEPk9jzrOKvCm9dVJv7P+JJOX5C t5yx4zch+DBRSRR1U9mmrbegEX4hXtec L3Ev9ZpxYAYUFd7gQ/oM5ZyrUZ08wLYg pYV6vE4qYdxP58dtknbpGUQKz4H3l0SQ eWoSyhOtYK9nNovCNN0swXdkmogEhDxP gY1nhEZiLXFH8W8/G96IgAa2hineMnqV 0z8/K2m7EGjwszDOyCD05Z77cMAryvjL X6Jm7I83+D8UwtfAck8ZGDJFz3l+w08G oeB9ntD1OicidpLtHmeSsN+1nuEL3s1M U47kwIJMAHu8bcyvm4HGRw==
+. 86400 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018072700 1800 900 604800 86400
+sk. 86400 IN NSEC ski. NS RRSIG NSEC
+sk. 86400 IN RRSIG NSEC 8 1 86400 20180809050000 20180727040000 41656 . Z7ihB8GIbqYBTvBPWxq22UkxSfJf/1I5 eIQ0E3cCVB+srJs2mECa3FmiPkzaYEZv mGzDNGlr5T2BHunJHWVED3gN6Y9Mn0YD 8v+0sIfPTTO74uWxHZFQsudZSzBqWaEI S2zHlM8VTiE6/x6QrAyDNIdjLSI5563X q/qVCsYxx10bRKIog4g73ZwBvlmwd1wa Rd/IIaEDCRO/ed6yFMOL5dhhMERrcJVY HdbNCpSb27LT4HFoqXtBMt1Z8VJVqDI3 NMojUq7a0JWMrFhBEiNwgNJ5xHCiiDuc 4nvszt1wiZAebsr8Qcniy4PrDDs+3XOg lBDRhozaOZYS436/Bs27Xw==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR RD NOERROR
+SECTION QUESTION
+cz. IN TYPE65535
+SECTION AUTHORITY
+cz. 172800 IN NS a.ns.nic.cz.
+cz. 172800 IN NS b.ns.nic.cz.
+cz. 172800 IN NS c.ns.nic.cz.
+cz. 172800 IN NS d.ns.nic.cz.
+cz. 86400 IN DS 20237 13 2 cff0f3ecdbc529c1f0031ba1840bfb835853b9209ed1e508fff48451d7b778e2
+cz. 86400 IN RRSIG DS 8 1 86400 20180809050000 20180727040000 41656 . BkGaXhVOBlSGZkRo6m6xYxeXSEIqVZKa 7wHxKdNn+6F/DDJoD0aEgEg6H7yhjKs2 tt4uyp9l8/L8r/mWoFPjYsSsQgc2hpxJ Ql2wTDRNaRpQ+spbiefndoyr1/5YBMFv mItzzMSg93ekx3gebfVqMpe0fpvs7NjA +33vGJO3e3ficaYDIf9HY/npnHgjOtpE wiFPYmLTb+zLlIHd4hhXOXg/Kv5CNGvN aBdBE2s2GXJbYI3Zd5FDHxhZ+qLuhL5J qjtrGDokRgM0Jk8dDroIk0yQHfNU022s ZAhIeEZJhwiuh4bNuJJCKoB+a5UIiNx+ rCUU2ntIsqLbxbnpKLamow==
+SECTION ADDITIONAL
+a.ns.nic.cz. 172800 IN A 194.0.12.1
+a.ns.nic.cz. 172800 IN AAAA 2001:678:f::1
+b.ns.nic.cz. 172800 IN A 194.0.13.1
+b.ns.nic.cz. 172800 IN AAAA 2001:678:10::1
+c.ns.nic.cz. 172800 IN A 194.0.14.1
+c.ns.nic.cz. 172800 IN AAAA 2001:678:11::1
+d.ns.nic.cz. 172800 IN A 193.29.206.1
+d.ns.nic.cz. 172800 IN AAAA 2001:678:1::1
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR RD NOERROR
+SECTION QUESTION
+cz. IN DNSKEY
+SECTION AUTHORITY
+cz. 172800 IN NS a.ns.nic.cz.
+cz. 172800 IN NS b.ns.nic.cz.
+cz. 172800 IN NS c.ns.nic.cz.
+cz. 172800 IN NS d.ns.nic.cz.
+cz. 86400 IN DS 20237 13 2 cff0f3ecdbc529c1f0031ba1840bfb835853b9209ed1e508fff48451d7b778e2
+cz. 86400 IN RRSIG DS 8 1 86400 20180809050000 20180727040000 41656 . BkGaXhVOBlSGZkRo6m6xYxeXSEIqVZKa 7wHxKdNn+6F/DDJoD0aEgEg6H7yhjKs2 tt4uyp9l8/L8r/mWoFPjYsSsQgc2hpxJ Ql2wTDRNaRpQ+spbiefndoyr1/5YBMFv mItzzMSg93ekx3gebfVqMpe0fpvs7NjA +33vGJO3e3ficaYDIf9HY/npnHgjOtpE wiFPYmLTb+zLlIHd4hhXOXg/Kv5CNGvN aBdBE2s2GXJbYI3Zd5FDHxhZ+qLuhL5J qjtrGDokRgM0Jk8dDroIk0yQHfNU022s ZAhIeEZJhwiuh4bNuJJCKoB+a5UIiNx+ rCUU2ntIsqLbxbnpKLamow==
+SECTION ADDITIONAL
+a.ns.nic.cz. 172800 IN A 194.0.12.1
+a.ns.nic.cz. 172800 IN AAAA 2001:678:f::1
+b.ns.nic.cz. 172800 IN A 194.0.13.1
+b.ns.nic.cz. 172800 IN AAAA 2001:678:10::1
+c.ns.nic.cz. 172800 IN A 194.0.14.1
+c.ns.nic.cz. 172800 IN AAAA 2001:678:11::1
+d.ns.nic.cz. 172800 IN A 193.29.206.1
+d.ns.nic.cz. 172800 IN AAAA 2001:678:1::1
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+cz. IN DS
+SECTION ANSWER
+cz. 86400 IN DS 20237 13 2 cff0f3ecdbc529c1f0031ba1840bfb835853b9209ed1e508fff48451d7b778e2
+cz. 86400 IN RRSIG DS 8 1 86400 20180809050000 20180727040000 41656 . BkGaXhVOBlSGZkRo6m6xYxeXSEIqVZKa 7wHxKdNn+6F/DDJoD0aEgEg6H7yhjKs2 tt4uyp9l8/L8r/mWoFPjYsSsQgc2hpxJ Ql2wTDRNaRpQ+spbiefndoyr1/5YBMFv mItzzMSg93ekx3gebfVqMpe0fpvs7NjA +33vGJO3e3ficaYDIf9HY/npnHgjOtpE wiFPYmLTb+zLlIHd4hhXOXg/Kv5CNGvN aBdBE2s2GXJbYI3Zd5FDHxhZ+qLuhL5J qjtrGDokRgM0Jk8dDroIk0yQHfNU022s ZAhIeEZJhwiuh4bNuJJCKoB+a5UIiNx+ rCUU2ntIsqLbxbnpKLamow==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR RD NOERROR
+SECTION QUESTION
+cz. IN A
+SECTION AUTHORITY
+cz. 172800 IN NS a.ns.nic.cz.
+cz. 172800 IN NS b.ns.nic.cz.
+cz. 172800 IN NS c.ns.nic.cz.
+cz. 172800 IN NS d.ns.nic.cz.
+cz. 86400 IN DS 20237 13 2 cff0f3ecdbc529c1f0031ba1840bfb835853b9209ed1e508fff48451d7b778e2
+cz. 86400 IN RRSIG DS 8 1 86400 20180809050000 20180727040000 41656 . BkGaXhVOBlSGZkRo6m6xYxeXSEIqVZKa 7wHxKdNn+6F/DDJoD0aEgEg6H7yhjKs2 tt4uyp9l8/L8r/mWoFPjYsSsQgc2hpxJ Ql2wTDRNaRpQ+spbiefndoyr1/5YBMFv mItzzMSg93ekx3gebfVqMpe0fpvs7NjA +33vGJO3e3ficaYDIf9HY/npnHgjOtpE wiFPYmLTb+zLlIHd4hhXOXg/Kv5CNGvN aBdBE2s2GXJbYI3Zd5FDHxhZ+qLuhL5J qjtrGDokRgM0Jk8dDroIk0yQHfNU022s ZAhIeEZJhwiuh4bNuJJCKoB+a5UIiNx+ rCUU2ntIsqLbxbnpKLamow==
+SECTION ADDITIONAL
+a.ns.nic.cz. 172800 IN A 194.0.12.1
+a.ns.nic.cz. 172800 IN AAAA 2001:678:f::1
+b.ns.nic.cz. 172800 IN A 194.0.13.1
+b.ns.nic.cz. 172800 IN AAAA 2001:678:10::1
+c.ns.nic.cz. 172800 IN A 194.0.14.1
+c.ns.nic.cz. 172800 IN AAAA 2001:678:11::1
+d.ns.nic.cz. 172800 IN A 193.29.206.1
+d.ns.nic.cz. 172800 IN AAAA 2001:678:1::1
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR RD NOERROR
+SECTION QUESTION
+net. IN A
+SECTION AUTHORITY
+net. 172800 IN NS a.gtld-servers.net.
+net. 172800 IN NS b.gtld-servers.net.
+net. 172800 IN NS c.gtld-servers.net.
+net. 172800 IN NS d.gtld-servers.net.
+net. 172800 IN NS e.gtld-servers.net.
+net. 172800 IN NS f.gtld-servers.net.
+net. 172800 IN NS g.gtld-servers.net.
+net. 172800 IN NS h.gtld-servers.net.
+net. 172800 IN NS i.gtld-servers.net.
+net. 172800 IN NS j.gtld-servers.net.
+net. 172800 IN NS k.gtld-servers.net.
+net. 172800 IN NS l.gtld-servers.net.
+net. 172800 IN NS m.gtld-servers.net.
+net. 86400 IN DS 35886 8 2 7862b27f5f516ebe19680444d4ce5e762981931842c465f00236401d8bd973ee
+net. 86400 IN RRSIG DS 8 1 86400 20180809050000 20180727040000 41656 . 0Uvgipa8bRqTwVpcmpPngKx1brdQ0rIB H8QbEl4KyFE+CI8nB3jNk9rHF15WYQm1 Xov0E1uCMvYfv1w96LvC+N4w7hPsCpgG sK3+pT90vhsLRqoP7dws5MU0fsXfpmGP X3utMPZGwk7JDSUhQAbIWiCD81JAi05y I5xbaeveUSSvMbyXJKyzsbHWVP6997BX 4Las1O8H/1Eds743+Cfc5hPULqH5ZUWB EPIKN+MZQM9DjmgUUJSlktWQwK42BeXU 9O4DUGP2oxwbQ8uw4PlRhhxYp3UCP9b5 B2d4fqlaalhiPY86u7TkzEbEJJlW2tf+ 3bGAiX9a9icfbsrdS9hsuw==
+SECTION ADDITIONAL
+a.gtld-servers.net. 172800 IN A 192.5.6.30
+a.gtld-servers.net. 172800 IN AAAA 2001:503:a83e::2:30
+b.gtld-servers.net. 172800 IN A 192.33.14.30
+b.gtld-servers.net. 172800 IN AAAA 2001:503:231d::2:30
+c.gtld-servers.net. 172800 IN A 192.26.92.30
+c.gtld-servers.net. 172800 IN AAAA 2001:503:83eb::30
+d.gtld-servers.net. 172800 IN A 192.31.80.30
+d.gtld-servers.net. 172800 IN AAAA 2001:500:856e::30
+e.gtld-servers.net. 172800 IN A 192.12.94.30
+e.gtld-servers.net. 172800 IN AAAA 2001:502:1ca1::30
+f.gtld-servers.net. 172800 IN A 192.35.51.30
+f.gtld-servers.net. 172800 IN AAAA 2001:503:d414::30
+g.gtld-servers.net. 172800 IN A 192.42.93.30
+g.gtld-servers.net. 172800 IN AAAA 2001:503:eea3::30
+h.gtld-servers.net. 172800 IN A 192.54.112.30
+h.gtld-servers.net. 172800 IN AAAA 2001:502:8cc::30
+i.gtld-servers.net. 172800 IN A 192.43.172.30
+i.gtld-servers.net. 172800 IN AAAA 2001:503:39c1::30
+j.gtld-servers.net. 172800 IN A 192.48.79.30
+j.gtld-servers.net. 172800 IN AAAA 2001:502:7094::30
+k.gtld-servers.net. 172800 IN A 192.52.178.30
+k.gtld-servers.net. 172800 IN AAAA 2001:503:d2d::30
+l.gtld-servers.net. 172800 IN A 192.41.162.30
+l.gtld-servers.net. 172800 IN AAAA 2001:500:d937::30
+m.gtld-servers.net. 172800 IN A 192.55.83.30
+m.gtld-servers.net. 172800 IN AAAA 2001:501:b1f9::30
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR RD NOERROR
+SECTION QUESTION
+net. IN DNSKEY
+SECTION AUTHORITY
+net. 172800 IN NS a.gtld-servers.net.
+net. 172800 IN NS b.gtld-servers.net.
+net. 172800 IN NS c.gtld-servers.net.
+net. 172800 IN NS d.gtld-servers.net.
+net. 172800 IN NS e.gtld-servers.net.
+net. 172800 IN NS f.gtld-servers.net.
+net. 172800 IN NS g.gtld-servers.net.
+net. 172800 IN NS h.gtld-servers.net.
+net. 172800 IN NS i.gtld-servers.net.
+net. 172800 IN NS j.gtld-servers.net.
+net. 172800 IN NS k.gtld-servers.net.
+net. 172800 IN NS l.gtld-servers.net.
+net. 172800 IN NS m.gtld-servers.net.
+net. 86400 IN DS 35886 8 2 7862b27f5f516ebe19680444d4ce5e762981931842c465f00236401d8bd973ee
+net. 86400 IN RRSIG DS 8 1 86400 20180809050000 20180727040000 41656 . 0Uvgipa8bRqTwVpcmpPngKx1brdQ0rIB H8QbEl4KyFE+CI8nB3jNk9rHF15WYQm1 Xov0E1uCMvYfv1w96LvC+N4w7hPsCpgG sK3+pT90vhsLRqoP7dws5MU0fsXfpmGP X3utMPZGwk7JDSUhQAbIWiCD81JAi05y I5xbaeveUSSvMbyXJKyzsbHWVP6997BX 4Las1O8H/1Eds743+Cfc5hPULqH5ZUWB EPIKN+MZQM9DjmgUUJSlktWQwK42BeXU 9O4DUGP2oxwbQ8uw4PlRhhxYp3UCP9b5 B2d4fqlaalhiPY86u7TkzEbEJJlW2tf+ 3bGAiX9a9icfbsrdS9hsuw==
+SECTION ADDITIONAL
+a.gtld-servers.net. 172800 IN A 192.5.6.30
+a.gtld-servers.net. 172800 IN AAAA 2001:503:a83e::2:30
+b.gtld-servers.net. 172800 IN A 192.33.14.30
+b.gtld-servers.net. 172800 IN AAAA 2001:503:231d::2:30
+c.gtld-servers.net. 172800 IN A 192.26.92.30
+c.gtld-servers.net. 172800 IN AAAA 2001:503:83eb::30
+d.gtld-servers.net. 172800 IN A 192.31.80.30
+d.gtld-servers.net. 172800 IN AAAA 2001:500:856e::30
+e.gtld-servers.net. 172800 IN A 192.12.94.30
+e.gtld-servers.net. 172800 IN AAAA 2001:502:1ca1::30
+f.gtld-servers.net. 172800 IN A 192.35.51.30
+f.gtld-servers.net. 172800 IN AAAA 2001:503:d414::30
+g.gtld-servers.net. 172800 IN A 192.42.93.30
+g.gtld-servers.net. 172800 IN AAAA 2001:503:eea3::30
+h.gtld-servers.net. 172800 IN A 192.54.112.30
+h.gtld-servers.net. 172800 IN AAAA 2001:502:8cc::30
+i.gtld-servers.net. 172800 IN A 192.43.172.30
+i.gtld-servers.net. 172800 IN AAAA 2001:503:39c1::30
+j.gtld-servers.net. 172800 IN A 192.48.79.30
+j.gtld-servers.net. 172800 IN AAAA 2001:502:7094::30
+k.gtld-servers.net. 172800 IN A 192.52.178.30
+k.gtld-servers.net. 172800 IN AAAA 2001:503:d2d::30
+l.gtld-servers.net. 172800 IN A 192.41.162.30
+l.gtld-servers.net. 172800 IN AAAA 2001:500:d937::30
+m.gtld-servers.net. 172800 IN A 192.55.83.30
+m.gtld-servers.net. 172800 IN AAAA 2001:501:b1f9::30
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+net. IN DS
+SECTION ANSWER
+net. 86400 IN DS 35886 8 2 7862b27f5f516ebe19680444d4ce5e762981931842c465f00236401d8bd973ee
+net. 86400 IN RRSIG DS 8 1 86400 20180809050000 20180727040000 41656 . 0Uvgipa8bRqTwVpcmpPngKx1brdQ0rIB H8QbEl4KyFE+CI8nB3jNk9rHF15WYQm1 Xov0E1uCMvYfv1w96LvC+N4w7hPsCpgG sK3+pT90vhsLRqoP7dws5MU0fsXfpmGP X3utMPZGwk7JDSUhQAbIWiCD81JAi05y I5xbaeveUSSvMbyXJKyzsbHWVP6997BX 4Las1O8H/1Eds743+Cfc5hPULqH5ZUWB EPIKN+MZQM9DjmgUUJSlktWQwK42BeXU 9O4DUGP2oxwbQ8uw4PlRhhxYp3UCP9b5 B2d4fqlaalhiPY86u7TkzEbEJJlW2tf+ 3bGAiX9a9icfbsrdS9hsuw==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+f.root-servers.net. IN A
+SECTION ANSWER
+f.root-servers.net. 3600000 IN A 192.5.5.241
+SECTION AUTHORITY
+root-servers.net. 3600000 IN NS a.root-servers.net.
+root-servers.net. 3600000 IN NS b.root-servers.net.
+root-servers.net. 3600000 IN NS c.root-servers.net.
+root-servers.net. 3600000 IN NS d.root-servers.net.
+root-servers.net. 3600000 IN NS e.root-servers.net.
+root-servers.net. 3600000 IN NS f.root-servers.net.
+root-servers.net. 3600000 IN NS g.root-servers.net.
+root-servers.net. 3600000 IN NS h.root-servers.net.
+root-servers.net. 3600000 IN NS i.root-servers.net.
+root-servers.net. 3600000 IN NS j.root-servers.net.
+root-servers.net. 3600000 IN NS k.root-servers.net.
+root-servers.net. 3600000 IN NS l.root-servers.net.
+root-servers.net. 3600000 IN NS m.root-servers.net.
+SECTION ADDITIONAL
+a.root-servers.net. 3600000 IN A 198.41.0.4
+a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30
+b.root-servers.net. 3600000 IN A 199.9.14.201
+b.root-servers.net. 3600000 IN AAAA 2001:500:200::b
+c.root-servers.net. 3600000 IN A 192.33.4.12
+c.root-servers.net. 3600000 IN AAAA 2001:500:2::c
+d.root-servers.net. 3600000 IN A 199.7.91.13
+d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d
+e.root-servers.net. 3600000 IN A 192.203.230.10
+e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e
+f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f
+g.root-servers.net. 3600000 IN A 192.112.36.4
+g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d
+h.root-servers.net. 3600000 IN A 198.97.190.53
+h.root-servers.net. 3600000 IN AAAA 2001:500:1::53
+i.root-servers.net. 3600000 IN A 192.36.148.17
+i.root-servers.net. 3600000 IN AAAA 2001:7fe::53
+j.root-servers.net. 3600000 IN A 192.58.128.30
+j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+l.root-servers.net. 3600000 IN A 199.7.83.42
+l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42
+m.root-servers.net. 3600000 IN A 202.12.27.33
+m.root-servers.net. 3600000 IN AAAA 2001:dc3::35
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+f.root-servers.net. IN DNSKEY
+SECTION AUTHORITY
+root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018070900 14400 7200 1209600 3600000
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+f.root-servers.net. IN NS
+SECTION AUTHORITY
+root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018070900 14400 7200 1209600 3600000
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+f.root-servers.net. IN DS
+SECTION AUTHORITY
+root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018070900 14400 7200 1209600 3600000
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+f.root-servers.net. IN AAAA
+SECTION ANSWER
+f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f
+SECTION AUTHORITY
+root-servers.net. 3600000 IN NS a.root-servers.net.
+root-servers.net. 3600000 IN NS b.root-servers.net.
+root-servers.net. 3600000 IN NS c.root-servers.net.
+root-servers.net. 3600000 IN NS d.root-servers.net.
+root-servers.net. 3600000 IN NS e.root-servers.net.
+root-servers.net. 3600000 IN NS f.root-servers.net.
+root-servers.net. 3600000 IN NS g.root-servers.net.
+root-servers.net. 3600000 IN NS h.root-servers.net.
+root-servers.net. 3600000 IN NS i.root-servers.net.
+root-servers.net. 3600000 IN NS j.root-servers.net.
+root-servers.net. 3600000 IN NS k.root-servers.net.
+root-servers.net. 3600000 IN NS l.root-servers.net.
+root-servers.net. 3600000 IN NS m.root-servers.net.
+SECTION ADDITIONAL
+a.root-servers.net. 3600000 IN A 198.41.0.4
+a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30
+b.root-servers.net. 3600000 IN A 199.9.14.201
+b.root-servers.net. 3600000 IN AAAA 2001:500:200::b
+c.root-servers.net. 3600000 IN A 192.33.4.12
+c.root-servers.net. 3600000 IN AAAA 2001:500:2::c
+d.root-servers.net. 3600000 IN A 199.7.91.13
+d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d
+e.root-servers.net. 3600000 IN A 192.203.230.10
+e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e
+f.root-servers.net. 3600000 IN A 192.5.5.241
+g.root-servers.net. 3600000 IN A 192.112.36.4
+g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d
+h.root-servers.net. 3600000 IN A 198.97.190.53
+h.root-servers.net. 3600000 IN AAAA 2001:500:1::53
+i.root-servers.net. 3600000 IN A 192.36.148.17
+i.root-servers.net. 3600000 IN AAAA 2001:7fe::53
+j.root-servers.net. 3600000 IN A 192.58.128.30
+j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+l.root-servers.net. 3600000 IN A 199.7.83.42
+l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42
+m.root-servers.net. 3600000 IN A 202.12.27.33
+m.root-servers.net. 3600000 IN AAAA 2001:dc3::35
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+a.root-servers.net. IN A
+SECTION ANSWER
+a.root-servers.net. 3600000 IN A 198.41.0.4
+SECTION AUTHORITY
+root-servers.net. 3600000 IN NS a.root-servers.net.
+root-servers.net. 3600000 IN NS b.root-servers.net.
+root-servers.net. 3600000 IN NS c.root-servers.net.
+root-servers.net. 3600000 IN NS d.root-servers.net.
+root-servers.net. 3600000 IN NS e.root-servers.net.
+root-servers.net. 3600000 IN NS f.root-servers.net.
+root-servers.net. 3600000 IN NS g.root-servers.net.
+root-servers.net. 3600000 IN NS h.root-servers.net.
+root-servers.net. 3600000 IN NS i.root-servers.net.
+root-servers.net. 3600000 IN NS j.root-servers.net.
+root-servers.net. 3600000 IN NS k.root-servers.net.
+root-servers.net. 3600000 IN NS l.root-servers.net.
+root-servers.net. 3600000 IN NS m.root-servers.net.
+SECTION ADDITIONAL
+a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30
+b.root-servers.net. 3600000 IN A 199.9.14.201
+b.root-servers.net. 3600000 IN AAAA 2001:500:200::b
+c.root-servers.net. 3600000 IN A 192.33.4.12
+c.root-servers.net. 3600000 IN AAAA 2001:500:2::c
+d.root-servers.net. 3600000 IN A 199.7.91.13
+d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d
+e.root-servers.net. 3600000 IN A 192.203.230.10
+e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e
+f.root-servers.net. 3600000 IN A 192.5.5.241
+f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f
+g.root-servers.net. 3600000 IN A 192.112.36.4
+g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d
+h.root-servers.net. 3600000 IN A 198.97.190.53
+h.root-servers.net. 3600000 IN AAAA 2001:500:1::53
+i.root-servers.net. 3600000 IN A 192.36.148.17
+i.root-servers.net. 3600000 IN AAAA 2001:7fe::53
+j.root-servers.net. 3600000 IN A 192.58.128.30
+j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+l.root-servers.net. 3600000 IN A 199.7.83.42
+l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42
+m.root-servers.net. 3600000 IN A 202.12.27.33
+m.root-servers.net. 3600000 IN AAAA 2001:dc3::35
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+a.root-servers.net. IN DNSKEY
+SECTION AUTHORITY
+root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018070900 14400 7200 1209600 3600000
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+a.root-servers.net. IN NS
+SECTION AUTHORITY
+root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018070900 14400 7200 1209600 3600000
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+a.root-servers.net. IN DS
+SECTION AUTHORITY
+root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018070900 14400 7200 1209600 3600000
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+a.root-servers.net. IN AAAA
+SECTION ANSWER
+a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30
+SECTION AUTHORITY
+root-servers.net. 3600000 IN NS a.root-servers.net.
+root-servers.net. 3600000 IN NS b.root-servers.net.
+root-servers.net. 3600000 IN NS c.root-servers.net.
+root-servers.net. 3600000 IN NS d.root-servers.net.
+root-servers.net. 3600000 IN NS e.root-servers.net.
+root-servers.net. 3600000 IN NS f.root-servers.net.
+root-servers.net. 3600000 IN NS g.root-servers.net.
+root-servers.net. 3600000 IN NS h.root-servers.net.
+root-servers.net. 3600000 IN NS i.root-servers.net.
+root-servers.net. 3600000 IN NS j.root-servers.net.
+root-servers.net. 3600000 IN NS k.root-servers.net.
+root-servers.net. 3600000 IN NS l.root-servers.net.
+root-servers.net. 3600000 IN NS m.root-servers.net.
+SECTION ADDITIONAL
+a.root-servers.net. 3600000 IN A 198.41.0.4
+b.root-servers.net. 3600000 IN A 199.9.14.201
+b.root-servers.net. 3600000 IN AAAA 2001:500:200::b
+c.root-servers.net. 3600000 IN A 192.33.4.12
+c.root-servers.net. 3600000 IN AAAA 2001:500:2::c
+d.root-servers.net. 3600000 IN A 199.7.91.13
+d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d
+e.root-servers.net. 3600000 IN A 192.203.230.10
+e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e
+f.root-servers.net. 3600000 IN A 192.5.5.241
+f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f
+g.root-servers.net. 3600000 IN A 192.112.36.4
+g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d
+h.root-servers.net. 3600000 IN A 198.97.190.53
+h.root-servers.net. 3600000 IN AAAA 2001:500:1::53
+i.root-servers.net. 3600000 IN A 192.36.148.17
+i.root-servers.net. 3600000 IN AAAA 2001:7fe::53
+j.root-servers.net. 3600000 IN A 192.58.128.30
+j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+l.root-servers.net. 3600000 IN A 199.7.83.42
+l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42
+m.root-servers.net. 3600000 IN A 202.12.27.33
+m.root-servers.net. 3600000 IN AAAA 2001:dc3::35
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+j.root-servers.net. IN A
+SECTION ANSWER
+j.root-servers.net. 3600000 IN A 192.58.128.30
+SECTION AUTHORITY
+root-servers.net. 3600000 IN NS a.root-servers.net.
+root-servers.net. 3600000 IN NS b.root-servers.net.
+root-servers.net. 3600000 IN NS c.root-servers.net.
+root-servers.net. 3600000 IN NS d.root-servers.net.
+root-servers.net. 3600000 IN NS e.root-servers.net.
+root-servers.net. 3600000 IN NS f.root-servers.net.
+root-servers.net. 3600000 IN NS g.root-servers.net.
+root-servers.net. 3600000 IN NS h.root-servers.net.
+root-servers.net. 3600000 IN NS i.root-servers.net.
+root-servers.net. 3600000 IN NS j.root-servers.net.
+root-servers.net. 3600000 IN NS k.root-servers.net.
+root-servers.net. 3600000 IN NS l.root-servers.net.
+root-servers.net. 3600000 IN NS m.root-servers.net.
+SECTION ADDITIONAL
+a.root-servers.net. 3600000 IN A 198.41.0.4
+a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30
+b.root-servers.net. 3600000 IN A 199.9.14.201
+b.root-servers.net. 3600000 IN AAAA 2001:500:200::b
+c.root-servers.net. 3600000 IN A 192.33.4.12
+c.root-servers.net. 3600000 IN AAAA 2001:500:2::c
+d.root-servers.net. 3600000 IN A 199.7.91.13
+d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d
+e.root-servers.net. 3600000 IN A 192.203.230.10
+e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e
+f.root-servers.net. 3600000 IN A 192.5.5.241
+f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f
+g.root-servers.net. 3600000 IN A 192.112.36.4
+g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d
+h.root-servers.net. 3600000 IN A 198.97.190.53
+h.root-servers.net. 3600000 IN AAAA 2001:500:1::53
+i.root-servers.net. 3600000 IN A 192.36.148.17
+i.root-servers.net. 3600000 IN AAAA 2001:7fe::53
+j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+l.root-servers.net. 3600000 IN A 199.7.83.42
+l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42
+m.root-servers.net. 3600000 IN A 202.12.27.33
+m.root-servers.net. 3600000 IN AAAA 2001:dc3::35
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+j.root-servers.net. IN DNSKEY
+SECTION AUTHORITY
+root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018070900 14400 7200 1209600 3600000
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+j.root-servers.net. IN NS
+SECTION AUTHORITY
+root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018070900 14400 7200 1209600 3600000
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+j.root-servers.net. IN DS
+SECTION AUTHORITY
+root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018070900 14400 7200 1209600 3600000
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+j.root-servers.net. IN AAAA
+SECTION ANSWER
+j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30
+SECTION AUTHORITY
+root-servers.net. 3600000 IN NS a.root-servers.net.
+root-servers.net. 3600000 IN NS b.root-servers.net.
+root-servers.net. 3600000 IN NS c.root-servers.net.
+root-servers.net. 3600000 IN NS d.root-servers.net.
+root-servers.net. 3600000 IN NS e.root-servers.net.
+root-servers.net. 3600000 IN NS f.root-servers.net.
+root-servers.net. 3600000 IN NS g.root-servers.net.
+root-servers.net. 3600000 IN NS h.root-servers.net.
+root-servers.net. 3600000 IN NS i.root-servers.net.
+root-servers.net. 3600000 IN NS j.root-servers.net.
+root-servers.net. 3600000 IN NS k.root-servers.net.
+root-servers.net. 3600000 IN NS l.root-servers.net.
+root-servers.net. 3600000 IN NS m.root-servers.net.
+SECTION ADDITIONAL
+a.root-servers.net. 3600000 IN A 198.41.0.4
+a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30
+b.root-servers.net. 3600000 IN A 199.9.14.201
+b.root-servers.net. 3600000 IN AAAA 2001:500:200::b
+c.root-servers.net. 3600000 IN A 192.33.4.12
+c.root-servers.net. 3600000 IN AAAA 2001:500:2::c
+d.root-servers.net. 3600000 IN A 199.7.91.13
+d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d
+e.root-servers.net. 3600000 IN A 192.203.230.10
+e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e
+f.root-servers.net. 3600000 IN A 192.5.5.241
+f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f
+g.root-servers.net. 3600000 IN A 192.112.36.4
+g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d
+h.root-servers.net. 3600000 IN A 198.97.190.53
+h.root-servers.net. 3600000 IN AAAA 2001:500:1::53
+i.root-servers.net. 3600000 IN A 192.36.148.17
+i.root-servers.net. 3600000 IN AAAA 2001:7fe::53
+j.root-servers.net. 3600000 IN A 192.58.128.30
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+l.root-servers.net. 3600000 IN A 199.7.83.42
+l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42
+m.root-servers.net. 3600000 IN A 202.12.27.33
+m.root-servers.net. 3600000 IN AAAA 2001:dc3::35
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+e.root-servers.net. IN A
+SECTION ANSWER
+e.root-servers.net. 3600000 IN A 192.203.230.10
+SECTION AUTHORITY
+root-servers.net. 3600000 IN NS a.root-servers.net.
+root-servers.net. 3600000 IN NS b.root-servers.net.
+root-servers.net. 3600000 IN NS c.root-servers.net.
+root-servers.net. 3600000 IN NS d.root-servers.net.
+root-servers.net. 3600000 IN NS e.root-servers.net.
+root-servers.net. 3600000 IN NS f.root-servers.net.
+root-servers.net. 3600000 IN NS g.root-servers.net.
+root-servers.net. 3600000 IN NS h.root-servers.net.
+root-servers.net. 3600000 IN NS i.root-servers.net.
+root-servers.net. 3600000 IN NS j.root-servers.net.
+root-servers.net. 3600000 IN NS k.root-servers.net.
+root-servers.net. 3600000 IN NS l.root-servers.net.
+root-servers.net. 3600000 IN NS m.root-servers.net.
+SECTION ADDITIONAL
+a.root-servers.net. 3600000 IN A 198.41.0.4
+a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30
+b.root-servers.net. 3600000 IN A 199.9.14.201
+b.root-servers.net. 3600000 IN AAAA 2001:500:200::b
+c.root-servers.net. 3600000 IN A 192.33.4.12
+c.root-servers.net. 3600000 IN AAAA 2001:500:2::c
+d.root-servers.net. 3600000 IN A 199.7.91.13
+d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d
+e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e
+f.root-servers.net. 3600000 IN A 192.5.5.241
+f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f
+g.root-servers.net. 3600000 IN A 192.112.36.4
+g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d
+h.root-servers.net. 3600000 IN A 198.97.190.53
+h.root-servers.net. 3600000 IN AAAA 2001:500:1::53
+i.root-servers.net. 3600000 IN A 192.36.148.17
+i.root-servers.net. 3600000 IN AAAA 2001:7fe::53
+j.root-servers.net. 3600000 IN A 192.58.128.30
+j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+l.root-servers.net. 3600000 IN A 199.7.83.42
+l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42
+m.root-servers.net. 3600000 IN A 202.12.27.33
+m.root-servers.net. 3600000 IN AAAA 2001:dc3::35
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+e.root-servers.net. IN DNSKEY
+SECTION AUTHORITY
+root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018070900 14400 7200 1209600 3600000
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+e.root-servers.net. IN NS
+SECTION AUTHORITY
+root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018070900 14400 7200 1209600 3600000
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+e.root-servers.net. IN DS
+SECTION AUTHORITY
+root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018070900 14400 7200 1209600 3600000
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+e.root-servers.net. IN AAAA
+SECTION ANSWER
+e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e
+SECTION AUTHORITY
+root-servers.net. 3600000 IN NS a.root-servers.net.
+root-servers.net. 3600000 IN NS b.root-servers.net.
+root-servers.net. 3600000 IN NS c.root-servers.net.
+root-servers.net. 3600000 IN NS d.root-servers.net.
+root-servers.net. 3600000 IN NS e.root-servers.net.
+root-servers.net. 3600000 IN NS f.root-servers.net.
+root-servers.net. 3600000 IN NS g.root-servers.net.
+root-servers.net. 3600000 IN NS h.root-servers.net.
+root-servers.net. 3600000 IN NS i.root-servers.net.
+root-servers.net. 3600000 IN NS j.root-servers.net.
+root-servers.net. 3600000 IN NS k.root-servers.net.
+root-servers.net. 3600000 IN NS l.root-servers.net.
+root-servers.net. 3600000 IN NS m.root-servers.net.
+SECTION ADDITIONAL
+a.root-servers.net. 3600000 IN A 198.41.0.4
+a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30
+b.root-servers.net. 3600000 IN A 199.9.14.201
+b.root-servers.net. 3600000 IN AAAA 2001:500:200::b
+c.root-servers.net. 3600000 IN A 192.33.4.12
+c.root-servers.net. 3600000 IN AAAA 2001:500:2::c
+d.root-servers.net. 3600000 IN A 199.7.91.13
+d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d
+e.root-servers.net. 3600000 IN A 192.203.230.10
+f.root-servers.net. 3600000 IN A 192.5.5.241
+f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f
+g.root-servers.net. 3600000 IN A 192.112.36.4
+g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d
+h.root-servers.net. 3600000 IN A 198.97.190.53
+h.root-servers.net. 3600000 IN AAAA 2001:500:1::53
+i.root-servers.net. 3600000 IN A 192.36.148.17
+i.root-servers.net. 3600000 IN AAAA 2001:7fe::53
+j.root-servers.net. 3600000 IN A 192.58.128.30
+j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+l.root-servers.net. 3600000 IN A 199.7.83.42
+l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42
+m.root-servers.net. 3600000 IN A 202.12.27.33
+m.root-servers.net. 3600000 IN AAAA 2001:dc3::35
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+i.root-servers.net. IN A
+SECTION ANSWER
+i.root-servers.net. 3600000 IN A 192.36.148.17
+SECTION AUTHORITY
+root-servers.net. 3600000 IN NS a.root-servers.net.
+root-servers.net. 3600000 IN NS b.root-servers.net.
+root-servers.net. 3600000 IN NS c.root-servers.net.
+root-servers.net. 3600000 IN NS d.root-servers.net.
+root-servers.net. 3600000 IN NS e.root-servers.net.
+root-servers.net. 3600000 IN NS f.root-servers.net.
+root-servers.net. 3600000 IN NS g.root-servers.net.
+root-servers.net. 3600000 IN NS h.root-servers.net.
+root-servers.net. 3600000 IN NS i.root-servers.net.
+root-servers.net. 3600000 IN NS j.root-servers.net.
+root-servers.net. 3600000 IN NS k.root-servers.net.
+root-servers.net. 3600000 IN NS l.root-servers.net.
+root-servers.net. 3600000 IN NS m.root-servers.net.
+SECTION ADDITIONAL
+a.root-servers.net. 3600000 IN A 198.41.0.4
+a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30
+b.root-servers.net. 3600000 IN A 199.9.14.201
+b.root-servers.net. 3600000 IN AAAA 2001:500:200::b
+c.root-servers.net. 3600000 IN A 192.33.4.12
+c.root-servers.net. 3600000 IN AAAA 2001:500:2::c
+d.root-servers.net. 3600000 IN A 199.7.91.13
+d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d
+e.root-servers.net. 3600000 IN A 192.203.230.10
+e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e
+f.root-servers.net. 3600000 IN A 192.5.5.241
+f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f
+g.root-servers.net. 3600000 IN A 192.112.36.4
+g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d
+h.root-servers.net. 3600000 IN A 198.97.190.53
+h.root-servers.net. 3600000 IN AAAA 2001:500:1::53
+i.root-servers.net. 3600000 IN AAAA 2001:7fe::53
+j.root-servers.net. 3600000 IN A 192.58.128.30
+j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+l.root-servers.net. 3600000 IN A 199.7.83.42
+l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42
+m.root-servers.net. 3600000 IN A 202.12.27.33
+m.root-servers.net. 3600000 IN AAAA 2001:dc3::35
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+i.root-servers.net. IN DNSKEY
+SECTION AUTHORITY
+root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018070900 14400 7200 1209600 3600000
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+i.root-servers.net. IN NS
+SECTION AUTHORITY
+root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018070900 14400 7200 1209600 3600000
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+i.root-servers.net. IN DS
+SECTION AUTHORITY
+root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018070900 14400 7200 1209600 3600000
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+i.root-servers.net. IN AAAA
+SECTION ANSWER
+i.root-servers.net. 3600000 IN AAAA 2001:7fe::53
+SECTION AUTHORITY
+root-servers.net. 3600000 IN NS a.root-servers.net.
+root-servers.net. 3600000 IN NS b.root-servers.net.
+root-servers.net. 3600000 IN NS c.root-servers.net.
+root-servers.net. 3600000 IN NS d.root-servers.net.
+root-servers.net. 3600000 IN NS e.root-servers.net.
+root-servers.net. 3600000 IN NS f.root-servers.net.
+root-servers.net. 3600000 IN NS g.root-servers.net.
+root-servers.net. 3600000 IN NS h.root-servers.net.
+root-servers.net. 3600000 IN NS i.root-servers.net.
+root-servers.net. 3600000 IN NS j.root-servers.net.
+root-servers.net. 3600000 IN NS k.root-servers.net.
+root-servers.net. 3600000 IN NS l.root-servers.net.
+root-servers.net. 3600000 IN NS m.root-servers.net.
+SECTION ADDITIONAL
+a.root-servers.net. 3600000 IN A 198.41.0.4
+a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30
+b.root-servers.net. 3600000 IN A 199.9.14.201
+b.root-servers.net. 3600000 IN AAAA 2001:500:200::b
+c.root-servers.net. 3600000 IN A 192.33.4.12
+c.root-servers.net. 3600000 IN AAAA 2001:500:2::c
+d.root-servers.net. 3600000 IN A 199.7.91.13
+d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d
+e.root-servers.net. 3600000 IN A 192.203.230.10
+e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e
+f.root-servers.net. 3600000 IN A 192.5.5.241
+f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f
+g.root-servers.net. 3600000 IN A 192.112.36.4
+g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d
+h.root-servers.net. 3600000 IN A 198.97.190.53
+h.root-servers.net. 3600000 IN AAAA 2001:500:1::53
+i.root-servers.net. 3600000 IN A 192.36.148.17
+j.root-servers.net. 3600000 IN A 192.58.128.30
+j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+l.root-servers.net. 3600000 IN A 199.7.83.42
+l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42
+m.root-servers.net. 3600000 IN A 202.12.27.33
+m.root-servers.net. 3600000 IN AAAA 2001:dc3::35
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+d.root-servers.net. IN A
+SECTION ANSWER
+d.root-servers.net. 3600000 IN A 199.7.91.13
+SECTION AUTHORITY
+root-servers.net. 3600000 IN NS a.root-servers.net.
+root-servers.net. 3600000 IN NS b.root-servers.net.
+root-servers.net. 3600000 IN NS c.root-servers.net.
+root-servers.net. 3600000 IN NS d.root-servers.net.
+root-servers.net. 3600000 IN NS e.root-servers.net.
+root-servers.net. 3600000 IN NS f.root-servers.net.
+root-servers.net. 3600000 IN NS g.root-servers.net.
+root-servers.net. 3600000 IN NS h.root-servers.net.
+root-servers.net. 3600000 IN NS i.root-servers.net.
+root-servers.net. 3600000 IN NS j.root-servers.net.
+root-servers.net. 3600000 IN NS k.root-servers.net.
+root-servers.net. 3600000 IN NS l.root-servers.net.
+root-servers.net. 3600000 IN NS m.root-servers.net.
+SECTION ADDITIONAL
+a.root-servers.net. 3600000 IN A 198.41.0.4
+a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30
+b.root-servers.net. 3600000 IN A 199.9.14.201
+b.root-servers.net. 3600000 IN AAAA 2001:500:200::b
+c.root-servers.net. 3600000 IN A 192.33.4.12
+c.root-servers.net. 3600000 IN AAAA 2001:500:2::c
+d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d
+e.root-servers.net. 3600000 IN A 192.203.230.10
+e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e
+f.root-servers.net. 3600000 IN A 192.5.5.241
+f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f
+g.root-servers.net. 3600000 IN A 192.112.36.4
+g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d
+h.root-servers.net. 3600000 IN A 198.97.190.53
+h.root-servers.net. 3600000 IN AAAA 2001:500:1::53
+i.root-servers.net. 3600000 IN A 192.36.148.17
+i.root-servers.net. 3600000 IN AAAA 2001:7fe::53
+j.root-servers.net. 3600000 IN A 192.58.128.30
+j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+l.root-servers.net. 3600000 IN A 199.7.83.42
+l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42
+m.root-servers.net. 3600000 IN A 202.12.27.33
+m.root-servers.net. 3600000 IN AAAA 2001:dc3::35
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+d.root-servers.net. IN DNSKEY
+SECTION AUTHORITY
+root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018070900 14400 7200 1209600 3600000
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+d.root-servers.net. IN NS
+SECTION AUTHORITY
+root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018070900 14400 7200 1209600 3600000
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+d.root-servers.net. IN DS
+SECTION AUTHORITY
+root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018070900 14400 7200 1209600 3600000
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+d.root-servers.net. IN AAAA
+SECTION ANSWER
+d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d
+SECTION AUTHORITY
+root-servers.net. 3600000 IN NS a.root-servers.net.
+root-servers.net. 3600000 IN NS b.root-servers.net.
+root-servers.net. 3600000 IN NS c.root-servers.net.
+root-servers.net. 3600000 IN NS d.root-servers.net.
+root-servers.net. 3600000 IN NS e.root-servers.net.
+root-servers.net. 3600000 IN NS f.root-servers.net.
+root-servers.net. 3600000 IN NS g.root-servers.net.
+root-servers.net. 3600000 IN NS h.root-servers.net.
+root-servers.net. 3600000 IN NS i.root-servers.net.
+root-servers.net. 3600000 IN NS j.root-servers.net.
+root-servers.net. 3600000 IN NS k.root-servers.net.
+root-servers.net. 3600000 IN NS l.root-servers.net.
+root-servers.net. 3600000 IN NS m.root-servers.net.
+SECTION ADDITIONAL
+a.root-servers.net. 3600000 IN A 198.41.0.4
+a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30
+b.root-servers.net. 3600000 IN A 199.9.14.201
+b.root-servers.net. 3600000 IN AAAA 2001:500:200::b
+c.root-servers.net. 3600000 IN A 192.33.4.12
+c.root-servers.net. 3600000 IN AAAA 2001:500:2::c
+d.root-servers.net. 3600000 IN A 199.7.91.13
+e.root-servers.net. 3600000 IN A 192.203.230.10
+e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e
+f.root-servers.net. 3600000 IN A 192.5.5.241
+f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f
+g.root-servers.net. 3600000 IN A 192.112.36.4
+g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d
+h.root-servers.net. 3600000 IN A 198.97.190.53
+h.root-servers.net. 3600000 IN AAAA 2001:500:1::53
+i.root-servers.net. 3600000 IN A 192.36.148.17
+i.root-servers.net. 3600000 IN AAAA 2001:7fe::53
+j.root-servers.net. 3600000 IN A 192.58.128.30
+j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+l.root-servers.net. 3600000 IN A 199.7.83.42
+l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42
+m.root-servers.net. 3600000 IN A 202.12.27.33
+m.root-servers.net. 3600000 IN AAAA 2001:dc3::35
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+m.root-servers.net. IN A
+SECTION ANSWER
+m.root-servers.net. 3600000 IN A 202.12.27.33
+SECTION AUTHORITY
+root-servers.net. 3600000 IN NS a.root-servers.net.
+root-servers.net. 3600000 IN NS b.root-servers.net.
+root-servers.net. 3600000 IN NS c.root-servers.net.
+root-servers.net. 3600000 IN NS d.root-servers.net.
+root-servers.net. 3600000 IN NS e.root-servers.net.
+root-servers.net. 3600000 IN NS f.root-servers.net.
+root-servers.net. 3600000 IN NS g.root-servers.net.
+root-servers.net. 3600000 IN NS h.root-servers.net.
+root-servers.net. 3600000 IN NS i.root-servers.net.
+root-servers.net. 3600000 IN NS j.root-servers.net.
+root-servers.net. 3600000 IN NS k.root-servers.net.
+root-servers.net. 3600000 IN NS l.root-servers.net.
+root-servers.net. 3600000 IN NS m.root-servers.net.
+SECTION ADDITIONAL
+a.root-servers.net. 3600000 IN A 198.41.0.4
+a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30
+b.root-servers.net. 3600000 IN A 199.9.14.201
+b.root-servers.net. 3600000 IN AAAA 2001:500:200::b
+c.root-servers.net. 3600000 IN A 192.33.4.12
+c.root-servers.net. 3600000 IN AAAA 2001:500:2::c
+d.root-servers.net. 3600000 IN A 199.7.91.13
+d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d
+e.root-servers.net. 3600000 IN A 192.203.230.10
+e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e
+f.root-servers.net. 3600000 IN A 192.5.5.241
+f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f
+g.root-servers.net. 3600000 IN A 192.112.36.4
+g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d
+h.root-servers.net. 3600000 IN A 198.97.190.53
+h.root-servers.net. 3600000 IN AAAA 2001:500:1::53
+i.root-servers.net. 3600000 IN A 192.36.148.17
+i.root-servers.net. 3600000 IN AAAA 2001:7fe::53
+j.root-servers.net. 3600000 IN A 192.58.128.30
+j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+l.root-servers.net. 3600000 IN A 199.7.83.42
+l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42
+m.root-servers.net. 3600000 IN AAAA 2001:dc3::35
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+m.root-servers.net. IN DNSKEY
+SECTION AUTHORITY
+root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018070900 14400 7200 1209600 3600000
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+m.root-servers.net. IN NS
+SECTION AUTHORITY
+root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018070900 14400 7200 1209600 3600000
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+m.root-servers.net. IN DS
+SECTION AUTHORITY
+root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018070900 14400 7200 1209600 3600000
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+m.root-servers.net. IN AAAA
+SECTION ANSWER
+m.root-servers.net. 3600000 IN AAAA 2001:dc3::35
+SECTION AUTHORITY
+root-servers.net. 3600000 IN NS a.root-servers.net.
+root-servers.net. 3600000 IN NS b.root-servers.net.
+root-servers.net. 3600000 IN NS c.root-servers.net.
+root-servers.net. 3600000 IN NS d.root-servers.net.
+root-servers.net. 3600000 IN NS e.root-servers.net.
+root-servers.net. 3600000 IN NS f.root-servers.net.
+root-servers.net. 3600000 IN NS g.root-servers.net.
+root-servers.net. 3600000 IN NS h.root-servers.net.
+root-servers.net. 3600000 IN NS i.root-servers.net.
+root-servers.net. 3600000 IN NS j.root-servers.net.
+root-servers.net. 3600000 IN NS k.root-servers.net.
+root-servers.net. 3600000 IN NS l.root-servers.net.
+root-servers.net. 3600000 IN NS m.root-servers.net.
+SECTION ADDITIONAL
+a.root-servers.net. 3600000 IN A 198.41.0.4
+a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30
+b.root-servers.net. 3600000 IN A 199.9.14.201
+b.root-servers.net. 3600000 IN AAAA 2001:500:200::b
+c.root-servers.net. 3600000 IN A 192.33.4.12
+c.root-servers.net. 3600000 IN AAAA 2001:500:2::c
+d.root-servers.net. 3600000 IN A 199.7.91.13
+d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d
+e.root-servers.net. 3600000 IN A 192.203.230.10
+e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e
+f.root-servers.net. 3600000 IN A 192.5.5.241
+f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f
+g.root-servers.net. 3600000 IN A 192.112.36.4
+g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d
+h.root-servers.net. 3600000 IN A 198.97.190.53
+h.root-servers.net. 3600000 IN AAAA 2001:500:1::53
+i.root-servers.net. 3600000 IN A 192.36.148.17
+i.root-servers.net. 3600000 IN AAAA 2001:7fe::53
+j.root-servers.net. 3600000 IN A 192.58.128.30
+j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+l.root-servers.net. 3600000 IN A 199.7.83.42
+l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42
+m.root-servers.net. 3600000 IN A 202.12.27.33
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+h.root-servers.net. IN A
+SECTION ANSWER
+h.root-servers.net. 3600000 IN A 198.97.190.53
+SECTION AUTHORITY
+root-servers.net. 3600000 IN NS a.root-servers.net.
+root-servers.net. 3600000 IN NS b.root-servers.net.
+root-servers.net. 3600000 IN NS c.root-servers.net.
+root-servers.net. 3600000 IN NS d.root-servers.net.
+root-servers.net. 3600000 IN NS e.root-servers.net.
+root-servers.net. 3600000 IN NS f.root-servers.net.
+root-servers.net. 3600000 IN NS g.root-servers.net.
+root-servers.net. 3600000 IN NS h.root-servers.net.
+root-servers.net. 3600000 IN NS i.root-servers.net.
+root-servers.net. 3600000 IN NS j.root-servers.net.
+root-servers.net. 3600000 IN NS k.root-servers.net.
+root-servers.net. 3600000 IN NS l.root-servers.net.
+root-servers.net. 3600000 IN NS m.root-servers.net.
+SECTION ADDITIONAL
+a.root-servers.net. 3600000 IN A 198.41.0.4
+a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30
+b.root-servers.net. 3600000 IN A 199.9.14.201
+b.root-servers.net. 3600000 IN AAAA 2001:500:200::b
+c.root-servers.net. 3600000 IN A 192.33.4.12
+c.root-servers.net. 3600000 IN AAAA 2001:500:2::c
+d.root-servers.net. 3600000 IN A 199.7.91.13
+d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d
+e.root-servers.net. 3600000 IN A 192.203.230.10
+e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e
+f.root-servers.net. 3600000 IN A 192.5.5.241
+f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f
+g.root-servers.net. 3600000 IN A 192.112.36.4
+g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d
+h.root-servers.net. 3600000 IN AAAA 2001:500:1::53
+i.root-servers.net. 3600000 IN A 192.36.148.17
+i.root-servers.net. 3600000 IN AAAA 2001:7fe::53
+j.root-servers.net. 3600000 IN A 192.58.128.30
+j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+l.root-servers.net. 3600000 IN A 199.7.83.42
+l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42
+m.root-servers.net. 3600000 IN A 202.12.27.33
+m.root-servers.net. 3600000 IN AAAA 2001:dc3::35
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+h.root-servers.net. IN DNSKEY
+SECTION AUTHORITY
+root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018070900 14400 7200 1209600 3600000
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+h.root-servers.net. IN NS
+SECTION AUTHORITY
+root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018070900 14400 7200 1209600 3600000
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+h.root-servers.net. IN DS
+SECTION AUTHORITY
+root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018070900 14400 7200 1209600 3600000
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+h.root-servers.net. IN AAAA
+SECTION ANSWER
+h.root-servers.net. 3600000 IN AAAA 2001:500:1::53
+SECTION AUTHORITY
+root-servers.net. 3600000 IN NS a.root-servers.net.
+root-servers.net. 3600000 IN NS b.root-servers.net.
+root-servers.net. 3600000 IN NS c.root-servers.net.
+root-servers.net. 3600000 IN NS d.root-servers.net.
+root-servers.net. 3600000 IN NS e.root-servers.net.
+root-servers.net. 3600000 IN NS f.root-servers.net.
+root-servers.net. 3600000 IN NS g.root-servers.net.
+root-servers.net. 3600000 IN NS h.root-servers.net.
+root-servers.net. 3600000 IN NS i.root-servers.net.
+root-servers.net. 3600000 IN NS j.root-servers.net.
+root-servers.net. 3600000 IN NS k.root-servers.net.
+root-servers.net. 3600000 IN NS l.root-servers.net.
+root-servers.net. 3600000 IN NS m.root-servers.net.
+SECTION ADDITIONAL
+a.root-servers.net. 3600000 IN A 198.41.0.4
+a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30
+b.root-servers.net. 3600000 IN A 199.9.14.201
+b.root-servers.net. 3600000 IN AAAA 2001:500:200::b
+c.root-servers.net. 3600000 IN A 192.33.4.12
+c.root-servers.net. 3600000 IN AAAA 2001:500:2::c
+d.root-servers.net. 3600000 IN A 199.7.91.13
+d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d
+e.root-servers.net. 3600000 IN A 192.203.230.10
+e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e
+f.root-servers.net. 3600000 IN A 192.5.5.241
+f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f
+g.root-servers.net. 3600000 IN A 192.112.36.4
+g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d
+h.root-servers.net. 3600000 IN A 198.97.190.53
+i.root-servers.net. 3600000 IN A 192.36.148.17
+i.root-servers.net. 3600000 IN AAAA 2001:7fe::53
+j.root-servers.net. 3600000 IN A 192.58.128.30
+j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+l.root-servers.net. 3600000 IN A 199.7.83.42
+l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42
+m.root-servers.net. 3600000 IN A 202.12.27.33
+m.root-servers.net. 3600000 IN AAAA 2001:dc3::35
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+c.root-servers.net. IN A
+SECTION ANSWER
+c.root-servers.net. 3600000 IN A 192.33.4.12
+SECTION AUTHORITY
+root-servers.net. 3600000 IN NS a.root-servers.net.
+root-servers.net. 3600000 IN NS b.root-servers.net.
+root-servers.net. 3600000 IN NS c.root-servers.net.
+root-servers.net. 3600000 IN NS d.root-servers.net.
+root-servers.net. 3600000 IN NS e.root-servers.net.
+root-servers.net. 3600000 IN NS f.root-servers.net.
+root-servers.net. 3600000 IN NS g.root-servers.net.
+root-servers.net. 3600000 IN NS h.root-servers.net.
+root-servers.net. 3600000 IN NS i.root-servers.net.
+root-servers.net. 3600000 IN NS j.root-servers.net.
+root-servers.net. 3600000 IN NS k.root-servers.net.
+root-servers.net. 3600000 IN NS l.root-servers.net.
+root-servers.net. 3600000 IN NS m.root-servers.net.
+SECTION ADDITIONAL
+a.root-servers.net. 3600000 IN A 198.41.0.4
+a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30
+b.root-servers.net. 3600000 IN A 199.9.14.201
+b.root-servers.net. 3600000 IN AAAA 2001:500:200::b
+c.root-servers.net. 3600000 IN AAAA 2001:500:2::c
+d.root-servers.net. 3600000 IN A 199.7.91.13
+d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d
+e.root-servers.net. 3600000 IN A 192.203.230.10
+e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e
+f.root-servers.net. 3600000 IN A 192.5.5.241
+f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f
+g.root-servers.net. 3600000 IN A 192.112.36.4
+g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d
+h.root-servers.net. 3600000 IN A 198.97.190.53
+h.root-servers.net. 3600000 IN AAAA 2001:500:1::53
+i.root-servers.net. 3600000 IN A 192.36.148.17
+i.root-servers.net. 3600000 IN AAAA 2001:7fe::53
+j.root-servers.net. 3600000 IN A 192.58.128.30
+j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+l.root-servers.net. 3600000 IN A 199.7.83.42
+l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42
+m.root-servers.net. 3600000 IN A 202.12.27.33
+m.root-servers.net. 3600000 IN AAAA 2001:dc3::35
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+c.root-servers.net. IN DNSKEY
+SECTION AUTHORITY
+root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018070900 14400 7200 1209600 3600000
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+c.root-servers.net. IN NS
+SECTION AUTHORITY
+root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018070900 14400 7200 1209600 3600000
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+c.root-servers.net. IN DS
+SECTION AUTHORITY
+root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018070900 14400 7200 1209600 3600000
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+c.root-servers.net. IN AAAA
+SECTION ANSWER
+c.root-servers.net. 3600000 IN AAAA 2001:500:2::c
+SECTION AUTHORITY
+root-servers.net. 3600000 IN NS a.root-servers.net.
+root-servers.net. 3600000 IN NS b.root-servers.net.
+root-servers.net. 3600000 IN NS c.root-servers.net.
+root-servers.net. 3600000 IN NS d.root-servers.net.
+root-servers.net. 3600000 IN NS e.root-servers.net.
+root-servers.net. 3600000 IN NS f.root-servers.net.
+root-servers.net. 3600000 IN NS g.root-servers.net.
+root-servers.net. 3600000 IN NS h.root-servers.net.
+root-servers.net. 3600000 IN NS i.root-servers.net.
+root-servers.net. 3600000 IN NS j.root-servers.net.
+root-servers.net. 3600000 IN NS k.root-servers.net.
+root-servers.net. 3600000 IN NS l.root-servers.net.
+root-servers.net. 3600000 IN NS m.root-servers.net.
+SECTION ADDITIONAL
+a.root-servers.net. 3600000 IN A 198.41.0.4
+a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30
+b.root-servers.net. 3600000 IN A 199.9.14.201
+b.root-servers.net. 3600000 IN AAAA 2001:500:200::b
+c.root-servers.net. 3600000 IN A 192.33.4.12
+d.root-servers.net. 3600000 IN A 199.7.91.13
+d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d
+e.root-servers.net. 3600000 IN A 192.203.230.10
+e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e
+f.root-servers.net. 3600000 IN A 192.5.5.241
+f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f
+g.root-servers.net. 3600000 IN A 192.112.36.4
+g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d
+h.root-servers.net. 3600000 IN A 198.97.190.53
+h.root-servers.net. 3600000 IN AAAA 2001:500:1::53
+i.root-servers.net. 3600000 IN A 192.36.148.17
+i.root-servers.net. 3600000 IN AAAA 2001:7fe::53
+j.root-servers.net. 3600000 IN A 192.58.128.30
+j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+l.root-servers.net. 3600000 IN A 199.7.83.42
+l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42
+m.root-servers.net. 3600000 IN A 202.12.27.33
+m.root-servers.net. 3600000 IN AAAA 2001:dc3::35
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+l.root-servers.net. IN A
+SECTION ANSWER
+l.root-servers.net. 3600000 IN A 199.7.83.42
+SECTION AUTHORITY
+root-servers.net. 3600000 IN NS a.root-servers.net.
+root-servers.net. 3600000 IN NS b.root-servers.net.
+root-servers.net. 3600000 IN NS c.root-servers.net.
+root-servers.net. 3600000 IN NS d.root-servers.net.
+root-servers.net. 3600000 IN NS e.root-servers.net.
+root-servers.net. 3600000 IN NS f.root-servers.net.
+root-servers.net. 3600000 IN NS g.root-servers.net.
+root-servers.net. 3600000 IN NS h.root-servers.net.
+root-servers.net. 3600000 IN NS i.root-servers.net.
+root-servers.net. 3600000 IN NS j.root-servers.net.
+root-servers.net. 3600000 IN NS k.root-servers.net.
+root-servers.net. 3600000 IN NS l.root-servers.net.
+root-servers.net. 3600000 IN NS m.root-servers.net.
+SECTION ADDITIONAL
+a.root-servers.net. 3600000 IN A 198.41.0.4
+a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30
+b.root-servers.net. 3600000 IN A 199.9.14.201
+b.root-servers.net. 3600000 IN AAAA 2001:500:200::b
+c.root-servers.net. 3600000 IN A 192.33.4.12
+c.root-servers.net. 3600000 IN AAAA 2001:500:2::c
+d.root-servers.net. 3600000 IN A 199.7.91.13
+d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d
+e.root-servers.net. 3600000 IN A 192.203.230.10
+e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e
+f.root-servers.net. 3600000 IN A 192.5.5.241
+f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f
+g.root-servers.net. 3600000 IN A 192.112.36.4
+g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d
+h.root-servers.net. 3600000 IN A 198.97.190.53
+h.root-servers.net. 3600000 IN AAAA 2001:500:1::53
+i.root-servers.net. 3600000 IN A 192.36.148.17
+i.root-servers.net. 3600000 IN AAAA 2001:7fe::53
+j.root-servers.net. 3600000 IN A 192.58.128.30
+j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42
+m.root-servers.net. 3600000 IN A 202.12.27.33
+m.root-servers.net. 3600000 IN AAAA 2001:dc3::35
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+l.root-servers.net. IN DNSKEY
+SECTION AUTHORITY
+root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018070900 14400 7200 1209600 3600000
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+l.root-servers.net. IN NS
+SECTION AUTHORITY
+root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018070900 14400 7200 1209600 3600000
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+l.root-servers.net. IN DS
+SECTION AUTHORITY
+root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018070900 14400 7200 1209600 3600000
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+l.root-servers.net. IN AAAA
+SECTION ANSWER
+l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42
+SECTION AUTHORITY
+root-servers.net. 3600000 IN NS a.root-servers.net.
+root-servers.net. 3600000 IN NS b.root-servers.net.
+root-servers.net. 3600000 IN NS c.root-servers.net.
+root-servers.net. 3600000 IN NS d.root-servers.net.
+root-servers.net. 3600000 IN NS e.root-servers.net.
+root-servers.net. 3600000 IN NS f.root-servers.net.
+root-servers.net. 3600000 IN NS g.root-servers.net.
+root-servers.net. 3600000 IN NS h.root-servers.net.
+root-servers.net. 3600000 IN NS i.root-servers.net.
+root-servers.net. 3600000 IN NS j.root-servers.net.
+root-servers.net. 3600000 IN NS k.root-servers.net.
+root-servers.net. 3600000 IN NS l.root-servers.net.
+root-servers.net. 3600000 IN NS m.root-servers.net.
+SECTION ADDITIONAL
+a.root-servers.net. 3600000 IN A 198.41.0.4
+a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30
+b.root-servers.net. 3600000 IN A 199.9.14.201
+b.root-servers.net. 3600000 IN AAAA 2001:500:200::b
+c.root-servers.net. 3600000 IN A 192.33.4.12
+c.root-servers.net. 3600000 IN AAAA 2001:500:2::c
+d.root-servers.net. 3600000 IN A 199.7.91.13
+d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d
+e.root-servers.net. 3600000 IN A 192.203.230.10
+e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e
+f.root-servers.net. 3600000 IN A 192.5.5.241
+f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f
+g.root-servers.net. 3600000 IN A 192.112.36.4
+g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d
+h.root-servers.net. 3600000 IN A 198.97.190.53
+h.root-servers.net. 3600000 IN AAAA 2001:500:1::53
+i.root-servers.net. 3600000 IN A 192.36.148.17
+i.root-servers.net. 3600000 IN AAAA 2001:7fe::53
+j.root-servers.net. 3600000 IN A 192.58.128.30
+j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+l.root-servers.net. 3600000 IN A 199.7.83.42
+m.root-servers.net. 3600000 IN A 202.12.27.33
+m.root-servers.net. 3600000 IN AAAA 2001:dc3::35
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+g.root-servers.net. IN A
+SECTION ANSWER
+g.root-servers.net. 3600000 IN A 192.112.36.4
+SECTION AUTHORITY
+root-servers.net. 3600000 IN NS a.root-servers.net.
+root-servers.net. 3600000 IN NS b.root-servers.net.
+root-servers.net. 3600000 IN NS c.root-servers.net.
+root-servers.net. 3600000 IN NS d.root-servers.net.
+root-servers.net. 3600000 IN NS e.root-servers.net.
+root-servers.net. 3600000 IN NS f.root-servers.net.
+root-servers.net. 3600000 IN NS g.root-servers.net.
+root-servers.net. 3600000 IN NS h.root-servers.net.
+root-servers.net. 3600000 IN NS i.root-servers.net.
+root-servers.net. 3600000 IN NS j.root-servers.net.
+root-servers.net. 3600000 IN NS k.root-servers.net.
+root-servers.net. 3600000 IN NS l.root-servers.net.
+root-servers.net. 3600000 IN NS m.root-servers.net.
+SECTION ADDITIONAL
+a.root-servers.net. 3600000 IN A 198.41.0.4
+a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30
+b.root-servers.net. 3600000 IN A 199.9.14.201
+b.root-servers.net. 3600000 IN AAAA 2001:500:200::b
+c.root-servers.net. 3600000 IN A 192.33.4.12
+c.root-servers.net. 3600000 IN AAAA 2001:500:2::c
+d.root-servers.net. 3600000 IN A 199.7.91.13
+d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d
+e.root-servers.net. 3600000 IN A 192.203.230.10
+e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e
+f.root-servers.net. 3600000 IN A 192.5.5.241
+f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f
+g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d
+h.root-servers.net. 3600000 IN A 198.97.190.53
+h.root-servers.net. 3600000 IN AAAA 2001:500:1::53
+i.root-servers.net. 3600000 IN A 192.36.148.17
+i.root-servers.net. 3600000 IN AAAA 2001:7fe::53
+j.root-servers.net. 3600000 IN A 192.58.128.30
+j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+l.root-servers.net. 3600000 IN A 199.7.83.42
+l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42
+m.root-servers.net. 3600000 IN A 202.12.27.33
+m.root-servers.net. 3600000 IN AAAA 2001:dc3::35
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+g.root-servers.net. IN DNSKEY
+SECTION AUTHORITY
+root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018070900 14400 7200 1209600 3600000
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+g.root-servers.net. IN NS
+SECTION AUTHORITY
+root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018070900 14400 7200 1209600 3600000
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+g.root-servers.net. IN DS
+SECTION AUTHORITY
+root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018070900 14400 7200 1209600 3600000
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+g.root-servers.net. IN AAAA
+SECTION ANSWER
+g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d
+SECTION AUTHORITY
+root-servers.net. 3600000 IN NS a.root-servers.net.
+root-servers.net. 3600000 IN NS b.root-servers.net.
+root-servers.net. 3600000 IN NS c.root-servers.net.
+root-servers.net. 3600000 IN NS d.root-servers.net.
+root-servers.net. 3600000 IN NS e.root-servers.net.
+root-servers.net. 3600000 IN NS f.root-servers.net.
+root-servers.net. 3600000 IN NS g.root-servers.net.
+root-servers.net. 3600000 IN NS h.root-servers.net.
+root-servers.net. 3600000 IN NS i.root-servers.net.
+root-servers.net. 3600000 IN NS j.root-servers.net.
+root-servers.net. 3600000 IN NS k.root-servers.net.
+root-servers.net. 3600000 IN NS l.root-servers.net.
+root-servers.net. 3600000 IN NS m.root-servers.net.
+SECTION ADDITIONAL
+a.root-servers.net. 3600000 IN A 198.41.0.4
+a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30
+b.root-servers.net. 3600000 IN A 199.9.14.201
+b.root-servers.net. 3600000 IN AAAA 2001:500:200::b
+c.root-servers.net. 3600000 IN A 192.33.4.12
+c.root-servers.net. 3600000 IN AAAA 2001:500:2::c
+d.root-servers.net. 3600000 IN A 199.7.91.13
+d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d
+e.root-servers.net. 3600000 IN A 192.203.230.10
+e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e
+f.root-servers.net. 3600000 IN A 192.5.5.241
+f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f
+g.root-servers.net. 3600000 IN A 192.112.36.4
+h.root-servers.net. 3600000 IN A 198.97.190.53
+h.root-servers.net. 3600000 IN AAAA 2001:500:1::53
+i.root-servers.net. 3600000 IN A 192.36.148.17
+i.root-servers.net. 3600000 IN AAAA 2001:7fe::53
+j.root-servers.net. 3600000 IN A 192.58.128.30
+j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+l.root-servers.net. 3600000 IN A 199.7.83.42
+l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42
+m.root-servers.net. 3600000 IN A 202.12.27.33
+m.root-servers.net. 3600000 IN AAAA 2001:dc3::35
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+b.root-servers.net. IN A
+SECTION ANSWER
+b.root-servers.net. 3600000 IN A 199.9.14.201
+SECTION AUTHORITY
+root-servers.net. 3600000 IN NS a.root-servers.net.
+root-servers.net. 3600000 IN NS b.root-servers.net.
+root-servers.net. 3600000 IN NS c.root-servers.net.
+root-servers.net. 3600000 IN NS d.root-servers.net.
+root-servers.net. 3600000 IN NS e.root-servers.net.
+root-servers.net. 3600000 IN NS f.root-servers.net.
+root-servers.net. 3600000 IN NS g.root-servers.net.
+root-servers.net. 3600000 IN NS h.root-servers.net.
+root-servers.net. 3600000 IN NS i.root-servers.net.
+root-servers.net. 3600000 IN NS j.root-servers.net.
+root-servers.net. 3600000 IN NS k.root-servers.net.
+root-servers.net. 3600000 IN NS l.root-servers.net.
+root-servers.net. 3600000 IN NS m.root-servers.net.
+SECTION ADDITIONAL
+a.root-servers.net. 3600000 IN A 198.41.0.4
+a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30
+b.root-servers.net. 3600000 IN AAAA 2001:500:200::b
+c.root-servers.net. 3600000 IN A 192.33.4.12
+c.root-servers.net. 3600000 IN AAAA 2001:500:2::c
+d.root-servers.net. 3600000 IN A 199.7.91.13
+d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d
+e.root-servers.net. 3600000 IN A 192.203.230.10
+e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e
+f.root-servers.net. 3600000 IN A 192.5.5.241
+f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f
+g.root-servers.net. 3600000 IN A 192.112.36.4
+g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d
+h.root-servers.net. 3600000 IN A 198.97.190.53
+h.root-servers.net. 3600000 IN AAAA 2001:500:1::53
+i.root-servers.net. 3600000 IN A 192.36.148.17
+i.root-servers.net. 3600000 IN AAAA 2001:7fe::53
+j.root-servers.net. 3600000 IN A 192.58.128.30
+j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+l.root-servers.net. 3600000 IN A 199.7.83.42
+l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42
+m.root-servers.net. 3600000 IN A 202.12.27.33
+m.root-servers.net. 3600000 IN AAAA 2001:dc3::35
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+b.root-servers.net. IN DNSKEY
+SECTION AUTHORITY
+root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018070900 14400 7200 1209600 3600000
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+b.root-servers.net. IN NS
+SECTION AUTHORITY
+root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018070900 14400 7200 1209600 3600000
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+b.root-servers.net. IN DS
+SECTION AUTHORITY
+root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018070900 14400 7200 1209600 3600000
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+b.root-servers.net. IN AAAA
+SECTION ANSWER
+b.root-servers.net. 3600000 IN AAAA 2001:500:200::b
+SECTION AUTHORITY
+root-servers.net. 3600000 IN NS a.root-servers.net.
+root-servers.net. 3600000 IN NS b.root-servers.net.
+root-servers.net. 3600000 IN NS c.root-servers.net.
+root-servers.net. 3600000 IN NS d.root-servers.net.
+root-servers.net. 3600000 IN NS e.root-servers.net.
+root-servers.net. 3600000 IN NS f.root-servers.net.
+root-servers.net. 3600000 IN NS g.root-servers.net.
+root-servers.net. 3600000 IN NS h.root-servers.net.
+root-servers.net. 3600000 IN NS i.root-servers.net.
+root-servers.net. 3600000 IN NS j.root-servers.net.
+root-servers.net. 3600000 IN NS k.root-servers.net.
+root-servers.net. 3600000 IN NS l.root-servers.net.
+root-servers.net. 3600000 IN NS m.root-servers.net.
+SECTION ADDITIONAL
+a.root-servers.net. 3600000 IN A 198.41.0.4
+a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30
+b.root-servers.net. 3600000 IN A 199.9.14.201
+c.root-servers.net. 3600000 IN A 192.33.4.12
+c.root-servers.net. 3600000 IN AAAA 2001:500:2::c
+d.root-servers.net. 3600000 IN A 199.7.91.13
+d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d
+e.root-servers.net. 3600000 IN A 192.203.230.10
+e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e
+f.root-servers.net. 3600000 IN A 192.5.5.241
+f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f
+g.root-servers.net. 3600000 IN A 192.112.36.4
+g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d
+h.root-servers.net. 3600000 IN A 198.97.190.53
+h.root-servers.net. 3600000 IN AAAA 2001:500:1::53
+i.root-servers.net. 3600000 IN A 192.36.148.17
+i.root-servers.net. 3600000 IN AAAA 2001:7fe::53
+j.root-servers.net. 3600000 IN A 192.58.128.30
+j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+l.root-servers.net. 3600000 IN A 199.7.83.42
+l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42
+m.root-servers.net. 3600000 IN A 202.12.27.33
+m.root-servers.net. 3600000 IN AAAA 2001:dc3::35
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+k.root-servers.net. IN A
+SECTION ANSWER
+k.root-servers.net. 3600000 IN A 193.0.14.129
+SECTION AUTHORITY
+root-servers.net. 3600000 IN NS a.root-servers.net.
+root-servers.net. 3600000 IN NS b.root-servers.net.
+root-servers.net. 3600000 IN NS c.root-servers.net.
+root-servers.net. 3600000 IN NS d.root-servers.net.
+root-servers.net. 3600000 IN NS e.root-servers.net.
+root-servers.net. 3600000 IN NS f.root-servers.net.
+root-servers.net. 3600000 IN NS g.root-servers.net.
+root-servers.net. 3600000 IN NS h.root-servers.net.
+root-servers.net. 3600000 IN NS i.root-servers.net.
+root-servers.net. 3600000 IN NS j.root-servers.net.
+root-servers.net. 3600000 IN NS k.root-servers.net.
+root-servers.net. 3600000 IN NS l.root-servers.net.
+root-servers.net. 3600000 IN NS m.root-servers.net.
+SECTION ADDITIONAL
+a.root-servers.net. 3600000 IN A 198.41.0.4
+a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30
+b.root-servers.net. 3600000 IN A 199.9.14.201
+b.root-servers.net. 3600000 IN AAAA 2001:500:200::b
+c.root-servers.net. 3600000 IN A 192.33.4.12
+c.root-servers.net. 3600000 IN AAAA 2001:500:2::c
+d.root-servers.net. 3600000 IN A 199.7.91.13
+d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d
+e.root-servers.net. 3600000 IN A 192.203.230.10
+e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e
+f.root-servers.net. 3600000 IN A 192.5.5.241
+f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f
+g.root-servers.net. 3600000 IN A 192.112.36.4
+g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d
+h.root-servers.net. 3600000 IN A 198.97.190.53
+h.root-servers.net. 3600000 IN AAAA 2001:500:1::53
+i.root-servers.net. 3600000 IN A 192.36.148.17
+i.root-servers.net. 3600000 IN AAAA 2001:7fe::53
+j.root-servers.net. 3600000 IN A 192.58.128.30
+j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+l.root-servers.net. 3600000 IN A 199.7.83.42
+l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42
+m.root-servers.net. 3600000 IN A 202.12.27.33
+m.root-servers.net. 3600000 IN AAAA 2001:dc3::35
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+k.root-servers.net. IN DNSKEY
+SECTION AUTHORITY
+root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018070900 14400 7200 1209600 3600000
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+k.root-servers.net. IN NS
+SECTION AUTHORITY
+root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018070900 14400 7200 1209600 3600000
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+k.root-servers.net. IN DS
+SECTION AUTHORITY
+root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018070900 14400 7200 1209600 3600000
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+k.root-servers.net. IN AAAA
+SECTION ANSWER
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+SECTION AUTHORITY
+root-servers.net. 3600000 IN NS a.root-servers.net.
+root-servers.net. 3600000 IN NS b.root-servers.net.
+root-servers.net. 3600000 IN NS c.root-servers.net.
+root-servers.net. 3600000 IN NS d.root-servers.net.
+root-servers.net. 3600000 IN NS e.root-servers.net.
+root-servers.net. 3600000 IN NS f.root-servers.net.
+root-servers.net. 3600000 IN NS g.root-servers.net.
+root-servers.net. 3600000 IN NS h.root-servers.net.
+root-servers.net. 3600000 IN NS i.root-servers.net.
+root-servers.net. 3600000 IN NS j.root-servers.net.
+root-servers.net. 3600000 IN NS k.root-servers.net.
+root-servers.net. 3600000 IN NS l.root-servers.net.
+root-servers.net. 3600000 IN NS m.root-servers.net.
+SECTION ADDITIONAL
+a.root-servers.net. 3600000 IN A 198.41.0.4
+a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30
+b.root-servers.net. 3600000 IN A 199.9.14.201
+b.root-servers.net. 3600000 IN AAAA 2001:500:200::b
+c.root-servers.net. 3600000 IN A 192.33.4.12
+c.root-servers.net. 3600000 IN AAAA 2001:500:2::c
+d.root-servers.net. 3600000 IN A 199.7.91.13
+d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d
+e.root-servers.net. 3600000 IN A 192.203.230.10
+e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e
+f.root-servers.net. 3600000 IN A 192.5.5.241
+f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f
+g.root-servers.net. 3600000 IN A 192.112.36.4
+g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d
+h.root-servers.net. 3600000 IN A 198.97.190.53
+h.root-servers.net. 3600000 IN AAAA 2001:500:1::53
+i.root-servers.net. 3600000 IN A 192.36.148.17
+i.root-servers.net. 3600000 IN AAAA 2001:7fe::53
+j.root-servers.net. 3600000 IN A 192.58.128.30
+j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30
+k.root-servers.net. 3600000 IN A 193.0.14.129
+l.root-servers.net. 3600000 IN A 199.7.83.42
+l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42
+m.root-servers.net. 3600000 IN A 202.12.27.33
+m.root-servers.net. 3600000 IN AAAA 2001:dc3::35
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR RD NOERROR
+SECTION QUESTION
+com. IN A
+SECTION AUTHORITY
+com. 172800 IN NS a.gtld-servers.net.
+com. 172800 IN NS b.gtld-servers.net.
+com. 172800 IN NS c.gtld-servers.net.
+com. 172800 IN NS d.gtld-servers.net.
+com. 172800 IN NS e.gtld-servers.net.
+com. 172800 IN NS f.gtld-servers.net.
+com. 172800 IN NS g.gtld-servers.net.
+com. 172800 IN NS h.gtld-servers.net.
+com. 172800 IN NS i.gtld-servers.net.
+com. 172800 IN NS j.gtld-servers.net.
+com. 172800 IN NS k.gtld-servers.net.
+com. 172800 IN NS l.gtld-servers.net.
+com. 172800 IN NS m.gtld-servers.net.
+com. 86400 IN DS 30909 8 2 e2d3c916f6deeac73294e8268fb5885044a833fc5459588f4a9184cfc41a5766
+com. 86400 IN RRSIG DS 8 1 86400 20180809050000 20180727040000 41656 . eGyv2a7tzQdljtzCX0sF211why7uD3PI c1rSQxJKfd0AbhZKvcl6jQW+rRHHQHui ljjsXG1fp35P7P02269xj5Hbu2eNV5vr jRdXTzAQ+waZZHBn87mNOiURZwh0sG44 7XQYdpkC656acDJ8TP6Szox1gCkBo6eM /SquL8Jmtl6IQSszxT71auHUytVRL8NR bv57T/PXQ9fSAjq5+lgZ7ZVvCs6sVjRl KvtaGLixnb7pR9C08jLWA/j2jAG0RBV2 pOz7BVDm7V34FIjJ9yd8BbSKeEJFcQWl m9x26nQREBmpKp8AmUiUoxfyuZvMxu// EGVxIEh71OHxT46+AhCipg==
+SECTION ADDITIONAL
+a.gtld-servers.net. 172800 IN A 192.5.6.30
+a.gtld-servers.net. 172800 IN AAAA 2001:503:a83e::2:30
+b.gtld-servers.net. 172800 IN A 192.33.14.30
+b.gtld-servers.net. 172800 IN AAAA 2001:503:231d::2:30
+c.gtld-servers.net. 172800 IN A 192.26.92.30
+c.gtld-servers.net. 172800 IN AAAA 2001:503:83eb::30
+d.gtld-servers.net. 172800 IN A 192.31.80.30
+d.gtld-servers.net. 172800 IN AAAA 2001:500:856e::30
+e.gtld-servers.net. 172800 IN A 192.12.94.30
+e.gtld-servers.net. 172800 IN AAAA 2001:502:1ca1::30
+f.gtld-servers.net. 172800 IN A 192.35.51.30
+f.gtld-servers.net. 172800 IN AAAA 2001:503:d414::30
+g.gtld-servers.net. 172800 IN A 192.42.93.30
+g.gtld-servers.net. 172800 IN AAAA 2001:503:eea3::30
+h.gtld-servers.net. 172800 IN A 192.54.112.30
+h.gtld-servers.net. 172800 IN AAAA 2001:502:8cc::30
+i.gtld-servers.net. 172800 IN A 192.43.172.30
+i.gtld-servers.net. 172800 IN AAAA 2001:503:39c1::30
+j.gtld-servers.net. 172800 IN A 192.48.79.30
+j.gtld-servers.net. 172800 IN AAAA 2001:502:7094::30
+k.gtld-servers.net. 172800 IN A 192.52.178.30
+k.gtld-servers.net. 172800 IN AAAA 2001:503:d2d::30
+l.gtld-servers.net. 172800 IN A 192.41.162.30
+l.gtld-servers.net. 172800 IN AAAA 2001:500:d937::30
+m.gtld-servers.net. 172800 IN A 192.55.83.30
+m.gtld-servers.net. 172800 IN AAAA 2001:501:b1f9::30
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR RD NOERROR
+SECTION QUESTION
+com. IN DNSKEY
+SECTION AUTHORITY
+com. 172800 IN NS a.gtld-servers.net.
+com. 172800 IN NS b.gtld-servers.net.
+com. 172800 IN NS c.gtld-servers.net.
+com. 172800 IN NS d.gtld-servers.net.
+com. 172800 IN NS e.gtld-servers.net.
+com. 172800 IN NS f.gtld-servers.net.
+com. 172800 IN NS g.gtld-servers.net.
+com. 172800 IN NS h.gtld-servers.net.
+com. 172800 IN NS i.gtld-servers.net.
+com. 172800 IN NS j.gtld-servers.net.
+com. 172800 IN NS k.gtld-servers.net.
+com. 172800 IN NS l.gtld-servers.net.
+com. 172800 IN NS m.gtld-servers.net.
+com. 86400 IN DS 30909 8 2 e2d3c916f6deeac73294e8268fb5885044a833fc5459588f4a9184cfc41a5766
+com. 86400 IN RRSIG DS 8 1 86400 20180809050000 20180727040000 41656 . eGyv2a7tzQdljtzCX0sF211why7uD3PI c1rSQxJKfd0AbhZKvcl6jQW+rRHHQHui ljjsXG1fp35P7P02269xj5Hbu2eNV5vr jRdXTzAQ+waZZHBn87mNOiURZwh0sG44 7XQYdpkC656acDJ8TP6Szox1gCkBo6eM /SquL8Jmtl6IQSszxT71auHUytVRL8NR bv57T/PXQ9fSAjq5+lgZ7ZVvCs6sVjRl KvtaGLixnb7pR9C08jLWA/j2jAG0RBV2 pOz7BVDm7V34FIjJ9yd8BbSKeEJFcQWl m9x26nQREBmpKp8AmUiUoxfyuZvMxu// EGVxIEh71OHxT46+AhCipg==
+SECTION ADDITIONAL
+a.gtld-servers.net. 172800 IN A 192.5.6.30
+a.gtld-servers.net. 172800 IN AAAA 2001:503:a83e::2:30
+b.gtld-servers.net. 172800 IN A 192.33.14.30
+b.gtld-servers.net. 172800 IN AAAA 2001:503:231d::2:30
+c.gtld-servers.net. 172800 IN A 192.26.92.30
+c.gtld-servers.net. 172800 IN AAAA 2001:503:83eb::30
+d.gtld-servers.net. 172800 IN A 192.31.80.30
+d.gtld-servers.net. 172800 IN AAAA 2001:500:856e::30
+e.gtld-servers.net. 172800 IN A 192.12.94.30
+e.gtld-servers.net. 172800 IN AAAA 2001:502:1ca1::30
+f.gtld-servers.net. 172800 IN A 192.35.51.30
+f.gtld-servers.net. 172800 IN AAAA 2001:503:d414::30
+g.gtld-servers.net. 172800 IN A 192.42.93.30
+g.gtld-servers.net. 172800 IN AAAA 2001:503:eea3::30
+h.gtld-servers.net. 172800 IN A 192.54.112.30
+h.gtld-servers.net. 172800 IN AAAA 2001:502:8cc::30
+i.gtld-servers.net. 172800 IN A 192.43.172.30
+i.gtld-servers.net. 172800 IN AAAA 2001:503:39c1::30
+j.gtld-servers.net. 172800 IN A 192.48.79.30
+j.gtld-servers.net. 172800 IN AAAA 2001:502:7094::30
+k.gtld-servers.net. 172800 IN A 192.52.178.30
+k.gtld-servers.net. 172800 IN AAAA 2001:503:d2d::30
+l.gtld-servers.net. 172800 IN A 192.41.162.30
+l.gtld-servers.net. 172800 IN AAAA 2001:500:d937::30
+m.gtld-servers.net. 172800 IN A 192.55.83.30
+m.gtld-servers.net. 172800 IN AAAA 2001:501:b1f9::30
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+com. IN DS
+SECTION ANSWER
+com. 86400 IN DS 30909 8 2 e2d3c916f6deeac73294e8268fb5885044a833fc5459588f4a9184cfc41a5766
+com. 86400 IN RRSIG DS 8 1 86400 20180809050000 20180727040000 41656 . eGyv2a7tzQdljtzCX0sF211why7uD3PI c1rSQxJKfd0AbhZKvcl6jQW+rRHHQHui ljjsXG1fp35P7P02269xj5Hbu2eNV5vr jRdXTzAQ+waZZHBn87mNOiURZwh0sG44 7XQYdpkC656acDJ8TP6Szox1gCkBo6eM /SquL8Jmtl6IQSszxT71auHUytVRL8NR bv57T/PXQ9fSAjq5+lgZ7ZVvCs6sVjRl KvtaGLixnb7pR9C08jLWA/j2jAG0RBV2 pOz7BVDm7V34FIjJ9yd8BbSKeEJFcQWl m9x26nQREBmpKp8AmUiUoxfyuZvMxu// EGVxIEh71OHxT46+AhCipg==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. 518400 IN NS a.root-servers.net.
+. 518400 IN NS b.root-servers.net.
+. 518400 IN NS c.root-servers.net.
+. 518400 IN NS d.root-servers.net.
+. 518400 IN NS e.root-servers.net.
+. 518400 IN NS f.root-servers.net.
+. 518400 IN NS g.root-servers.net.
+. 518400 IN NS h.root-servers.net.
+. 518400 IN NS i.root-servers.net.
+. 518400 IN NS j.root-servers.net.
+. 518400 IN NS k.root-servers.net.
+. 518400 IN NS l.root-servers.net.
+. 518400 IN NS m.root-servers.net.
+. 518400 IN RRSIG NS 8 0 518400 20180809050000 20180727040000 41656 . iPYXlPdWqSGLIBjkBHYPCkA7LpjtEq2l 3IxdgesYUMxKFrYsdxgySnyBHQ9YzAQc bl3fCtLvlx6msHw/cCqMRHhCCjDnqTa/ NqBRtr1hr8ZbPrb3pZf+1hjX+9eohhHQ OiyAiP1hVaEIBIiSt7W8aPYvjZRogQAy YPApw3dwsfTFWzTnd+EDZsuZeMz0k74x BEJmC/tzTjnzvNK8fU95Mv+pKLm09Hda eXP2i+zrAwguTZBUt30dnsrYA7dxkQcP s+SdFhfPlGYS2EWOoJsik3DGRHQpTHI5 N9sjytXS7IqWetnaNJyFL0KSpG1YdEyB JvYqCrUI6YLDopcgUSRjrA==
+SECTION ADDITIONAL
+a.root-servers.net. 3600000 IN A 198.41.0.4
+a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30
+b.root-servers.net. 3600000 IN A 199.9.14.201
+b.root-servers.net. 3600000 IN AAAA 2001:500:200::b
+c.root-servers.net. 3600000 IN A 192.33.4.12
+c.root-servers.net. 3600000 IN AAAA 2001:500:2::c
+d.root-servers.net. 3600000 IN A 199.7.91.13
+d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d
+e.root-servers.net. 3600000 IN A 192.203.230.10
+e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e
+f.root-servers.net. 3600000 IN A 192.5.5.241
+f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f
+g.root-servers.net. 3600000 IN A 192.112.36.4
+g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d
+h.root-servers.net. 3600000 IN A 198.97.190.53
+h.root-servers.net. 3600000 IN AAAA 2001:500:1::53
+i.root-servers.net. 3600000 IN A 192.36.148.17
+i.root-servers.net. 3600000 IN AAAA 2001:7fe::53
+j.root-servers.net. 3600000 IN A 192.58.128.30
+j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+l.root-servers.net. 3600000 IN A 199.7.83.42
+l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42
+m.root-servers.net. 3600000 IN A 202.12.27.33
+m.root-servers.net. 3600000 IN AAAA 2001:dc3::35
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+. IN DNSKEY
+SECTION ANSWER
+. 172800 IN DNSKEY 256 3 8 AwEAAfaifSqh+9ItxYRCwuiY0FY2NkaE wd/zmyVvakixDgTOkgG/PUzlEauAiKzl xGwezjqbKFPSwrY3qHmbbsSTY6G8hZtn a8k26eCwy59Chh573cu8qtBkmUIXMYG3 fSdlUReP+uhBWBfKI2aGwhRmQYR0zSmg 7PGOde34c/rOItK1ebJhjTAJ6TmnON7q Mfk/lKvH4qOvYtzstLhr7Pn9ZOVLx/WU KQpU/nEyFyTduRbz1nZqkp6yMuHwWVsA BK8lUYXSaUrDAsuMSldhafmR/A15BxNh v9M7mzJj7UH2RVME9JbYinBEzWwW9Gpn Y+ZmBWgZiRVTaDuemCTJ5ZJWLRs=
+. 172800 IN DNSKEY 257 3 8 AwEAAagAIKlVZrpC6Ia7gEzahOR+9W29 euxhJhVVLOyQbSEW0O8gcCjFFVQUTf6v 58fLjwBd0YI0EzrAcQqBGCzh/RStIoO8 g0NfnfL2MTJRkxoXbfDaUeVPQuYEhg37 NZWAJQ9VnMVDxP/VHL496M/QZxkjf5/E fucp2gaDX6RS6CXpoY68LsvPVjR0ZSwz z1apAzvN9dlzEheX7ICJBBtuA6G3LQpz W5hOA2hzCTMjJPJ8LbqF6dsV6DoBQzgu l0sGIcGOYl7OyQdXfZ57relSQageu+ip AdTTJ25AsRTAoub8ONGcLmqrAmRLKBP1 dfwhYB4N7knNnulqQxA+Uk1ihz0=
+. 172800 IN DNSKEY 257 3 8 AwEAAaz/tAm8yTn4Mfeh5eyI96WSVexT BAvkMgJzkKTOiW1vkIbzxeF3+/4RgWOq 7HrxRixHlFlExOLAJr5emLvN7SWXgnLh 4+B5xQlNVz8Og8kvArMtNROxVQuCaSnI DdD5LKyWbRd2n9WGe2R8PzgCmr3EgVLr jyBxWezF0jLHwVN8efS3rCj/EWgvIWgb 9tarpVUDK/b58Da+sqqls3eNbuv7pr+e oZG+SrDK6nWeL3c6H5Apxz7LjVc1uTId sIXxuOLYA4/ilBmSVIzuDWfdRUfhHdY6 +cn8HFRm+2hM8AnXGXws9555KrUB5qih ylGa8subX2Nn6UwNR1AkUTV74bU=
+. 172800 IN RRSIG DNSKEY 8 0 172800 20180811000000 20180721000000 19036 . U2thj3DQzTGRF8m2ZytqANs9YF9PYb1B QC5bDHi+d7apJve5u3Ik1cCeYg9AlW2v 2vstMSUtTR0eI2mzBeZ8aBHLwPylyDhS jbe6lwxnaoZhncO4oM9bJTUha1ovCXPO oZm5dKhfI6FradAaitRfMaC7s/+XZ/Dh nlLQNe08F0qepkG52RsUJZEyiQkkOK5a /hNkV5gyKdMecjtJ7eiR1w68vWwP6iGp ohuLDlapbEniJXHhEysUtRJbE3EFYgwG EGeKwEQC3tDCb8ABYnbrkMg/OqhGP1cX aYfZwhEIUOvsplTdXU1tsVbPjGtbVBjy 4aKLY+pjsvWuT2dzMac18A==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+root-servers.net. IN DNSKEY
+SECTION AUTHORITY
+root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018070900 14400 7200 1209600 3600000
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH subdomain
+ADJUST copy_id copy_query
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+root-servers.net. IN NS
+SECTION ANSWER
+root-servers.net. 3600000 IN NS a.root-servers.net.
+root-servers.net. 3600000 IN NS b.root-servers.net.
+root-servers.net. 3600000 IN NS c.root-servers.net.
+root-servers.net. 3600000 IN NS d.root-servers.net.
+root-servers.net. 3600000 IN NS e.root-servers.net.
+root-servers.net. 3600000 IN NS f.root-servers.net.
+root-servers.net. 3600000 IN NS g.root-servers.net.
+root-servers.net. 3600000 IN NS h.root-servers.net.
+root-servers.net. 3600000 IN NS i.root-servers.net.
+root-servers.net. 3600000 IN NS j.root-servers.net.
+root-servers.net. 3600000 IN NS k.root-servers.net.
+root-servers.net. 3600000 IN NS l.root-servers.net.
+root-servers.net. 3600000 IN NS m.root-servers.net.
+SECTION ADDITIONAL
+a.root-servers.net. 3600000 IN A 198.41.0.4
+a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30
+b.root-servers.net. 3600000 IN A 199.9.14.201
+b.root-servers.net. 3600000 IN AAAA 2001:500:200::b
+c.root-servers.net. 3600000 IN A 192.33.4.12
+c.root-servers.net. 3600000 IN AAAA 2001:500:2::c
+d.root-servers.net. 3600000 IN A 199.7.91.13
+d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d
+e.root-servers.net. 3600000 IN A 192.203.230.10
+e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e
+f.root-servers.net. 3600000 IN A 192.5.5.241
+f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f
+g.root-servers.net. 3600000 IN A 192.112.36.4
+g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d
+h.root-servers.net. 3600000 IN A 198.97.190.53
+h.root-servers.net. 3600000 IN AAAA 2001:500:1::53
+i.root-servers.net. 3600000 IN A 192.36.148.17
+i.root-servers.net. 3600000 IN AAAA 2001:7fe::53
+j.root-servers.net. 3600000 IN A 192.58.128.30
+j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+l.root-servers.net. 3600000 IN A 199.7.83.42
+l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42
+m.root-servers.net. 3600000 IN A 202.12.27.33
+m.root-servers.net. 3600000 IN AAAA 2001:dc3::35
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH subdomain
+ADJUST copy_id copy_query
+REPLY QR RD NOERROR
+SECTION QUESTION
+hm. IN NS
+SECTION AUTHORITY
+hm. 172800 IN NS ns1.registry.hm.
+hm. 172800 IN NS ns2.registry.hm.
+hm. 172800 IN NS ns3.registry.hm.
+hm. 86400 IN NSEC hn. NS RRSIG NSEC
+hm. 86400 IN RRSIG NSEC 8 1 86400 20180809050000 20180727040000 41656 . vI+rf8FDWlQOpAPeJTvoMH7bceC0qe2U hzdXApcCQK50pacs356TAcnKRKsNu+wa qR0+pM51vnG1AT+pPSK0M70soXrbh8uI TfFMV6u+/6qgU9TzzzQk49UK4Ww6m4l6 uh7/I302reJjTsc9mpCrjkRX7lk96c31 xzcYMlbADfzQsCfofoZDw7bS45mY6nRH /zTNUuEtFZGef0XtkNK9Op32Sf7Qqqqu YuzKBWa1irDaYCCLeyaqSmXQDzl7xKQa szrWtZeA1pwxJ2KKzCfuaYsRk/R6INLv i4tfJ73oKHl7nhKxH/K1fWUrWTuxkR1q R1zQb7VOg0Jf9GUqXxPVXg==
+SECTION ADDITIONAL
+ns1.registry.hm. 172800 IN A 208.70.79.25
+ns2.registry.hm. 172800 IN A 208.70.79.24
+ns3.registry.hm. 172800 IN A 128.199.180.188
+ns1.registry.hm. 172800 IN AAAA 1::1
+ns2.registry.hm. 172800 IN AAAA 1::2
+ns3.registry.hm. 172800 IN AAAA 1::3
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH subdomain
+ADJUST copy_id copy_query
+REPLY QR RD NOERROR
+SECTION QUESTION
+cz. IN NS
+SECTION AUTHORITY
+cz. 172800 IN NS a.ns.nic.cz.
+cz. 172800 IN NS b.ns.nic.cz.
+cz. 172800 IN NS c.ns.nic.cz.
+cz. 172800 IN NS d.ns.nic.cz.
+cz. 86400 IN DS 20237 13 2 cff0f3ecdbc529c1f0031ba1840bfb835853b9209ed1e508fff48451d7b778e2
+cz. 86400 IN RRSIG DS 8 1 86400 20180809050000 20180727040000 41656 . BkGaXhVOBlSGZkRo6m6xYxeXSEIqVZKa 7wHxKdNn+6F/DDJoD0aEgEg6H7yhjKs2 tt4uyp9l8/L8r/mWoFPjYsSsQgc2hpxJ Ql2wTDRNaRpQ+spbiefndoyr1/5YBMFv mItzzMSg93ekx3gebfVqMpe0fpvs7NjA +33vGJO3e3ficaYDIf9HY/npnHgjOtpE wiFPYmLTb+zLlIHd4hhXOXg/Kv5CNGvN aBdBE2s2GXJbYI3Zd5FDHxhZ+qLuhL5J qjtrGDokRgM0Jk8dDroIk0yQHfNU022s ZAhIeEZJhwiuh4bNuJJCKoB+a5UIiNx+ rCUU2ntIsqLbxbnpKLamow==
+SECTION ADDITIONAL
+a.ns.nic.cz. 172800 IN A 194.0.12.1
+a.ns.nic.cz. 172800 IN AAAA 2001:678:f::1
+b.ns.nic.cz. 172800 IN A 194.0.13.1
+b.ns.nic.cz. 172800 IN AAAA 2001:678:10::1
+c.ns.nic.cz. 172800 IN A 194.0.14.1
+c.ns.nic.cz. 172800 IN AAAA 2001:678:11::1
+d.ns.nic.cz. 172800 IN A 193.29.206.1
+d.ns.nic.cz. 172800 IN AAAA 2001:678:1::1
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH subdomain
+ADJUST copy_id copy_query
+REPLY QR RD NOERROR
+SECTION QUESTION
+net. IN NS
+SECTION AUTHORITY
+net. 172800 IN NS a.gtld-servers.net.
+net. 172800 IN NS b.gtld-servers.net.
+net. 172800 IN NS c.gtld-servers.net.
+net. 172800 IN NS d.gtld-servers.net.
+net. 172800 IN NS e.gtld-servers.net.
+net. 172800 IN NS f.gtld-servers.net.
+net. 172800 IN NS g.gtld-servers.net.
+net. 172800 IN NS h.gtld-servers.net.
+net. 172800 IN NS i.gtld-servers.net.
+net. 172800 IN NS j.gtld-servers.net.
+net. 172800 IN NS k.gtld-servers.net.
+net. 172800 IN NS l.gtld-servers.net.
+net. 172800 IN NS m.gtld-servers.net.
+net. 86400 IN DS 35886 8 2 7862b27f5f516ebe19680444d4ce5e762981931842c465f00236401d8bd973ee
+net. 86400 IN RRSIG DS 8 1 86400 20180809050000 20180727040000 41656 . 0Uvgipa8bRqTwVpcmpPngKx1brdQ0rIB H8QbEl4KyFE+CI8nB3jNk9rHF15WYQm1 Xov0E1uCMvYfv1w96LvC+N4w7hPsCpgG sK3+pT90vhsLRqoP7dws5MU0fsXfpmGP X3utMPZGwk7JDSUhQAbIWiCD81JAi05y I5xbaeveUSSvMbyXJKyzsbHWVP6997BX 4Las1O8H/1Eds743+Cfc5hPULqH5ZUWB EPIKN+MZQM9DjmgUUJSlktWQwK42BeXU 9O4DUGP2oxwbQ8uw4PlRhhxYp3UCP9b5 B2d4fqlaalhiPY86u7TkzEbEJJlW2tf+ 3bGAiX9a9icfbsrdS9hsuw==
+SECTION ADDITIONAL
+a.gtld-servers.net. 172800 IN A 192.5.6.30
+a.gtld-servers.net. 172800 IN AAAA 2001:503:a83e::2:30
+b.gtld-servers.net. 172800 IN A 192.33.14.30
+b.gtld-servers.net. 172800 IN AAAA 2001:503:231d::2:30
+c.gtld-servers.net. 172800 IN A 192.26.92.30
+c.gtld-servers.net. 172800 IN AAAA 2001:503:83eb::30
+d.gtld-servers.net. 172800 IN A 192.31.80.30
+d.gtld-servers.net. 172800 IN AAAA 2001:500:856e::30
+e.gtld-servers.net. 172800 IN A 192.12.94.30
+e.gtld-servers.net. 172800 IN AAAA 2001:502:1ca1::30
+f.gtld-servers.net. 172800 IN A 192.35.51.30
+f.gtld-servers.net. 172800 IN AAAA 2001:503:d414::30
+g.gtld-servers.net. 172800 IN A 192.42.93.30
+g.gtld-servers.net. 172800 IN AAAA 2001:503:eea3::30
+h.gtld-servers.net. 172800 IN A 192.54.112.30
+h.gtld-servers.net. 172800 IN AAAA 2001:502:8cc::30
+i.gtld-servers.net. 172800 IN A 192.43.172.30
+i.gtld-servers.net. 172800 IN AAAA 2001:503:39c1::30
+j.gtld-servers.net. 172800 IN A 192.48.79.30
+j.gtld-servers.net. 172800 IN AAAA 2001:502:7094::30
+k.gtld-servers.net. 172800 IN A 192.52.178.30
+k.gtld-servers.net. 172800 IN AAAA 2001:503:d2d::30
+l.gtld-servers.net. 172800 IN A 192.41.162.30
+l.gtld-servers.net. 172800 IN AAAA 2001:500:d937::30
+m.gtld-servers.net. 172800 IN A 192.55.83.30
+m.gtld-servers.net. 172800 IN AAAA 2001:501:b1f9::30
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH subdomain
+ADJUST copy_id copy_query
+REPLY QR RD NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION AUTHORITY
+com. 172800 IN NS a.gtld-servers.net.
+com. 172800 IN NS b.gtld-servers.net.
+com. 172800 IN NS c.gtld-servers.net.
+com. 172800 IN NS d.gtld-servers.net.
+com. 172800 IN NS e.gtld-servers.net.
+com. 172800 IN NS f.gtld-servers.net.
+com. 172800 IN NS g.gtld-servers.net.
+com. 172800 IN NS h.gtld-servers.net.
+com. 172800 IN NS i.gtld-servers.net.
+com. 172800 IN NS j.gtld-servers.net.
+com. 172800 IN NS k.gtld-servers.net.
+com. 172800 IN NS l.gtld-servers.net.
+com. 172800 IN NS m.gtld-servers.net.
+com. 86400 IN DS 30909 8 2 e2d3c916f6deeac73294e8268fb5885044a833fc5459588f4a9184cfc41a5766
+com. 86400 IN RRSIG DS 8 1 86400 20180809050000 20180727040000 41656 . eGyv2a7tzQdljtzCX0sF211why7uD3PI c1rSQxJKfd0AbhZKvcl6jQW+rRHHQHui ljjsXG1fp35P7P02269xj5Hbu2eNV5vr jRdXTzAQ+waZZHBn87mNOiURZwh0sG44 7XQYdpkC656acDJ8TP6Szox1gCkBo6eM /SquL8Jmtl6IQSszxT71auHUytVRL8NR bv57T/PXQ9fSAjq5+lgZ7ZVvCs6sVjRl KvtaGLixnb7pR9C08jLWA/j2jAG0RBV2 pOz7BVDm7V34FIjJ9yd8BbSKeEJFcQWl m9x26nQREBmpKp8AmUiUoxfyuZvMxu// EGVxIEh71OHxT46+AhCipg==
+SECTION ADDITIONAL
+a.gtld-servers.net. 172800 IN A 192.5.6.30
+a.gtld-servers.net. 172800 IN AAAA 2001:503:a83e::2:30
+b.gtld-servers.net. 172800 IN A 192.33.14.30
+b.gtld-servers.net. 172800 IN AAAA 2001:503:231d::2:30
+c.gtld-servers.net. 172800 IN A 192.26.92.30
+c.gtld-servers.net. 172800 IN AAAA 2001:503:83eb::30
+d.gtld-servers.net. 172800 IN A 192.31.80.30
+d.gtld-servers.net. 172800 IN AAAA 2001:500:856e::30
+e.gtld-servers.net. 172800 IN A 192.12.94.30
+e.gtld-servers.net. 172800 IN AAAA 2001:502:1ca1::30
+f.gtld-servers.net. 172800 IN A 192.35.51.30
+f.gtld-servers.net. 172800 IN AAAA 2001:503:d414::30
+g.gtld-servers.net. 172800 IN A 192.42.93.30
+g.gtld-servers.net. 172800 IN AAAA 2001:503:eea3::30
+h.gtld-servers.net. 172800 IN A 192.54.112.30
+h.gtld-servers.net. 172800 IN AAAA 2001:502:8cc::30
+i.gtld-servers.net. 172800 IN A 192.43.172.30
+i.gtld-servers.net. 172800 IN AAAA 2001:503:39c1::30
+j.gtld-servers.net. 172800 IN A 192.48.79.30
+j.gtld-servers.net. 172800 IN AAAA 2001:502:7094::30
+k.gtld-servers.net. 172800 IN A 192.52.178.30
+k.gtld-servers.net. 172800 IN AAAA 2001:503:d2d::30
+l.gtld-servers.net. 172800 IN A 192.41.162.30
+l.gtld-servers.net. 172800 IN AAAA 2001:500:d937::30
+m.gtld-servers.net. 172800 IN A 192.55.83.30
+m.gtld-servers.net. 172800 IN AAAA 2001:501:b1f9::30
+ENTRY_END
+
+
+RANGE_END
+
+; Scope "com.
+
+; Server names:
+; a.gtld-servers.net.
+; j.gtld-servers.net.
+; e.gtld-servers.net.
+; i.gtld-servers.net.
+; d.gtld-servers.net.
+; m.gtld-servers.net.
+; h.gtld-servers.net.
+; c.gtld-servers.net.
+; l.gtld-servers.net.
+; g.gtld-servers.net.
+; b.gtld-servers.net.
+; k.gtld-servers.net.
+; f.gtld-servers.net.
+RANGE_BEGIN 0 1000
+ ADDRESS 2001:500:d937::30
+ ADDRESS 2001:503:eea3::30
+ ADDRESS 192.26.92.30
+ ADDRESS 192.33.14.30
+ ADDRESS 192.54.112.30
+ ADDRESS 2001:503:d414::30
+ ADDRESS 2001:503:231d::2:30
+ ADDRESS 192.42.93.30
+ ADDRESS 2001:502:7094::30
+ ADDRESS 192.43.172.30
+ ADDRESS 192.41.162.30
+ ADDRESS 192.12.94.30
+ ADDRESS 192.31.80.30
+ ADDRESS 192.35.51.30
+ ADDRESS 192.48.79.30
+ ADDRESS 2001:501:b1f9::30
+ ADDRESS 192.55.83.30
+ ADDRESS 2001:503:a83e::2:30
+ ADDRESS 192.5.6.30
+ ADDRESS 2001:503:83eb::30
+ ADDRESS 192.52.178.30
+ ADDRESS 2001:502:8cc::30
+ ADDRESS 2001:503:39c1::30
+ ADDRESS 2001:500:856e::30
+ ADDRESS 2001:502:1ca1::30
+ ADDRESS 2001:503:d2d::30
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR RD NOERROR
+SECTION QUESTION
+root-servers.net. IN A
+SECTION AUTHORITY
+A1RT98BS5QGC9NFI51S9HCI47ULJG6JH.net. 86400 IN NSEC3 1 1 0 - a1ruuffjkct2q54p78f8ejgj8jbk7i8b NS SOA RRSIG DNSKEY NSEC3PARAM
+A1RT98BS5QGC9NFI51S9HCI47ULJG6JH.net. 86400 IN RRSIG NSEC3 8 2 86400 20180731053505 20180724042505 7934 net. aQ1+tOFuT3esonx3VUVqcQGwUlcby0Wa Rit1P1ikFjowshfV9AUsn/bkka2dFgxC PgDtmMiQ6TzAKiwciFJ5mZitfFZSEoS/ Z3pnsZsvB062GrKNup9+x4SBiRB3HH8T xMMd6sVV9LjOE2iOm4ekIUHieMwJjfnY 7yG7obH6OFI=
+T2UF21DR03E0BNPB42UQMVUF38P2TA8D.net. 86400 IN NSEC3 1 1 0 - t2ukct9k5i0uhv7b3m3na6jaigdjm0gr NS DS RRSIG
+T2UF21DR03E0BNPB42UQMVUF38P2TA8D.net. 86400 IN RRSIG NSEC3 8 2 86400 20180802052514 20180726041514 7934 net. LDVOVqnK+2HRKN6dUmVP3pP2RE0dCKTQ oE0d2w1AiDAOhn3Ye9Aq0yUjkz+frcUj ZqvTdiC58q0mXpyLUbqWiGmazUVG5qT7 zx5mhp1Leetq1wVJH8KGYLEmTstTCT56 oMbtWugGmZeY2B47rCsCeaWPNdH/b8qb UrwpfdPbhJE=
+root-servers.net. 172800 IN NS a.root-servers.net.
+root-servers.net. 172800 IN NS b.root-servers.net.
+root-servers.net. 172800 IN NS c.root-servers.net.
+root-servers.net. 172800 IN NS d.root-servers.net.
+root-servers.net. 172800 IN NS e.root-servers.net.
+root-servers.net. 172800 IN NS f.root-servers.net.
+root-servers.net. 172800 IN NS g.root-servers.net.
+root-servers.net. 172800 IN NS h.root-servers.net.
+root-servers.net. 172800 IN NS i.root-servers.net.
+root-servers.net. 172800 IN NS j.root-servers.net.
+root-servers.net. 172800 IN NS k.root-servers.net.
+root-servers.net. 172800 IN NS l.root-servers.net.
+root-servers.net. 172800 IN NS m.root-servers.net.
+SECTION ADDITIONAL
+a.root-servers.net. 172800 IN A 198.41.0.4
+a.root-servers.net. 172800 IN AAAA 2001:503:ba3e::2:30
+b.root-servers.net. 172800 IN A 199.9.14.201
+b.root-servers.net. 172800 IN AAAA 2001:500:200::b
+c.root-servers.net. 172800 IN A 192.33.4.12
+c.root-servers.net. 172800 IN AAAA 2001:500:2::c
+d.root-servers.net. 172800 IN A 199.7.91.13
+d.root-servers.net. 172800 IN AAAA 2001:500:2d::d
+e.root-servers.net. 172800 IN A 192.203.230.10
+e.root-servers.net. 172800 IN AAAA 2001:500:a8::e
+f.root-servers.net. 172800 IN A 192.5.5.241
+f.root-servers.net. 172800 IN AAAA 2001:500:2f::f
+g.root-servers.net. 172800 IN A 192.112.36.4
+g.root-servers.net. 172800 IN AAAA 2001:500:12::d0d
+h.root-servers.net. 172800 IN A 198.97.190.53
+h.root-servers.net. 172800 IN AAAA 2001:500:1::53
+i.root-servers.net. 172800 IN A 192.36.148.17
+i.root-servers.net. 172800 IN AAAA 2001:7fe::53
+j.root-servers.net. 172800 IN A 192.58.128.30
+j.root-servers.net. 172800 IN AAAA 2001:503:c27::2:30
+k.root-servers.net. 172800 IN A 193.0.14.129
+k.root-servers.net. 172800 IN AAAA 2001:7fd::1
+l.root-servers.net. 172800 IN A 199.7.83.42
+l.root-servers.net. 172800 IN AAAA 2001:500:9f::42
+m.root-servers.net. 172800 IN A 202.12.27.33
+m.root-servers.net. 172800 IN AAAA 2001:dc3::35
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR RD NOERROR
+SECTION QUESTION
+root-servers.net. IN DNSKEY
+SECTION AUTHORITY
+A1RT98BS5QGC9NFI51S9HCI47ULJG6JH.net. 86400 IN NSEC3 1 1 0 - a1ruuffjkct2q54p78f8ejgj8jbk7i8b NS SOA RRSIG DNSKEY NSEC3PARAM
+A1RT98BS5QGC9NFI51S9HCI47ULJG6JH.net. 86400 IN RRSIG NSEC3 8 2 86400 20180731053505 20180724042505 7934 net. aQ1+tOFuT3esonx3VUVqcQGwUlcby0Wa Rit1P1ikFjowshfV9AUsn/bkka2dFgxC PgDtmMiQ6TzAKiwciFJ5mZitfFZSEoS/ Z3pnsZsvB062GrKNup9+x4SBiRB3HH8T xMMd6sVV9LjOE2iOm4ekIUHieMwJjfnY 7yG7obH6OFI=
+T2UF21DR03E0BNPB42UQMVUF38P2TA8D.net. 86400 IN NSEC3 1 1 0 - t2ukct9k5i0uhv7b3m3na6jaigdjm0gr NS DS RRSIG
+T2UF21DR03E0BNPB42UQMVUF38P2TA8D.net. 86400 IN RRSIG NSEC3 8 2 86400 20180802052514 20180726041514 7934 net. LDVOVqnK+2HRKN6dUmVP3pP2RE0dCKTQ oE0d2w1AiDAOhn3Ye9Aq0yUjkz+frcUj ZqvTdiC58q0mXpyLUbqWiGmazUVG5qT7 zx5mhp1Leetq1wVJH8KGYLEmTstTCT56 oMbtWugGmZeY2B47rCsCeaWPNdH/b8qb UrwpfdPbhJE=
+root-servers.net. 172800 IN NS a.root-servers.net.
+root-servers.net. 172800 IN NS b.root-servers.net.
+root-servers.net. 172800 IN NS c.root-servers.net.
+root-servers.net. 172800 IN NS d.root-servers.net.
+root-servers.net. 172800 IN NS e.root-servers.net.
+root-servers.net. 172800 IN NS f.root-servers.net.
+root-servers.net. 172800 IN NS g.root-servers.net.
+root-servers.net. 172800 IN NS h.root-servers.net.
+root-servers.net. 172800 IN NS i.root-servers.net.
+root-servers.net. 172800 IN NS j.root-servers.net.
+root-servers.net. 172800 IN NS k.root-servers.net.
+root-servers.net. 172800 IN NS l.root-servers.net.
+root-servers.net. 172800 IN NS m.root-servers.net.
+SECTION ADDITIONAL
+a.root-servers.net. 172800 IN A 198.41.0.4
+a.root-servers.net. 172800 IN AAAA 2001:503:ba3e::2:30
+b.root-servers.net. 172800 IN A 199.9.14.201
+b.root-servers.net. 172800 IN AAAA 2001:500:200::b
+c.root-servers.net. 172800 IN A 192.33.4.12
+c.root-servers.net. 172800 IN AAAA 2001:500:2::c
+d.root-servers.net. 172800 IN A 199.7.91.13
+d.root-servers.net. 172800 IN AAAA 2001:500:2d::d
+e.root-servers.net. 172800 IN A 192.203.230.10
+e.root-servers.net. 172800 IN AAAA 2001:500:a8::e
+f.root-servers.net. 172800 IN A 192.5.5.241
+f.root-servers.net. 172800 IN AAAA 2001:500:2f::f
+g.root-servers.net. 172800 IN A 192.112.36.4
+g.root-servers.net. 172800 IN AAAA 2001:500:12::d0d
+h.root-servers.net. 172800 IN A 198.97.190.53
+h.root-servers.net. 172800 IN AAAA 2001:500:1::53
+i.root-servers.net. 172800 IN A 192.36.148.17
+i.root-servers.net. 172800 IN AAAA 2001:7fe::53
+j.root-servers.net. 172800 IN A 192.58.128.30
+j.root-servers.net. 172800 IN AAAA 2001:503:c27::2:30
+k.root-servers.net. 172800 IN A 193.0.14.129
+k.root-servers.net. 172800 IN AAAA 2001:7fd::1
+l.root-servers.net. 172800 IN A 199.7.83.42
+l.root-servers.net. 172800 IN AAAA 2001:500:9f::42
+m.root-servers.net. 172800 IN A 202.12.27.33
+m.root-servers.net. 172800 IN AAAA 2001:dc3::35
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+root-servers.net. IN DS
+SECTION AUTHORITY
+A1RT98BS5QGC9NFI51S9HCI47ULJG6JH.net. 86400 IN NSEC3 1 1 0 - a1ruuffjkct2q54p78f8ejgj8jbk7i8b NS SOA RRSIG DNSKEY NSEC3PARAM
+A1RT98BS5QGC9NFI51S9HCI47ULJG6JH.net. 86400 IN RRSIG NSEC3 8 2 86400 20180731053505 20180724042505 7934 net. aQ1+tOFuT3esonx3VUVqcQGwUlcby0Wa Rit1P1ikFjowshfV9AUsn/bkka2dFgxC PgDtmMiQ6TzAKiwciFJ5mZitfFZSEoS/ Z3pnsZsvB062GrKNup9+x4SBiRB3HH8T xMMd6sVV9LjOE2iOm4ekIUHieMwJjfnY 7yG7obH6OFI=
+T2UF21DR03E0BNPB42UQMVUF38P2TA8D.net. 86400 IN NSEC3 1 1 0 - t2ukct9k5i0uhv7b3m3na6jaigdjm0gr NS DS RRSIG
+T2UF21DR03E0BNPB42UQMVUF38P2TA8D.net. 86400 IN RRSIG NSEC3 8 2 86400 20180802052514 20180726041514 7934 net. LDVOVqnK+2HRKN6dUmVP3pP2RE0dCKTQ oE0d2w1AiDAOhn3Ye9Aq0yUjkz+frcUj ZqvTdiC58q0mXpyLUbqWiGmazUVG5qT7 zx5mhp1Leetq1wVJH8KGYLEmTstTCT56 oMbtWugGmZeY2B47rCsCeaWPNdH/b8qb UrwpfdPbhJE=
+net. 900 IN RRSIG SOA 8 1 900 20180803164343 20180727153343 7934 net. saMkeHnnZmFjMmrWJIcMIWfKP8XuvHyF 9S27EbEZJOze88EKxPoMirhwWptR9wge NZraLn79mYdFOYaxEWG3BmxablU7/0e4 4UUivo2svI8/0olxwD2jb7/VtF9e7FCv RpUuMeQZMarVejw343R4GcKPDMbpeEyh 0SbIk3mrhng=
+net. 900 IN SOA a.gtld-servers.net. nstld.verisign-grs.com. 1532709823 1800 900 604800 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR RD NOERROR
+SECTION QUESTION
+gtld-servers.net. IN A
+SECTION AUTHORITY
+5QD8VL68T2I9KOBD32KJ8LJVH5OH2PQ0.net. 86400 IN NSEC3 1 1 0 - 5qdppotuk27kkp9ligtrb0k1cbvm9cim NS DS RRSIG
+5QD8VL68T2I9KOBD32KJ8LJVH5OH2PQ0.net. 86400 IN RRSIG NSEC3 8 2 86400 20180801102320 20180725091320 7934 net. ZKWDEle0ZQbeLFqJNnGWN9zZNZ4qXpns WEmuTMy1Ou9IRpBl0YU1RQRdjRJ4aFWM 5Kcl/UIOgeN4yD+B8HludqzhxRGDxqZ1 N1ObndmMNLbokcgyIYVnmhoe3doOnedK KRU5F6YcJpEOQ4jcJsjQd9ekQTB9aBP3 j33L4T3A1PM=
+A1RT98BS5QGC9NFI51S9HCI47ULJG6JH.net. 86400 IN NSEC3 1 1 0 - a1ruuffjkct2q54p78f8ejgj8jbk7i8b NS SOA RRSIG DNSKEY NSEC3PARAM
+A1RT98BS5QGC9NFI51S9HCI47ULJG6JH.net. 86400 IN RRSIG NSEC3 8 2 86400 20180731053505 20180724042505 7934 net. aQ1+tOFuT3esonx3VUVqcQGwUlcby0Wa Rit1P1ikFjowshfV9AUsn/bkka2dFgxC PgDtmMiQ6TzAKiwciFJ5mZitfFZSEoS/ Z3pnsZsvB062GrKNup9+x4SBiRB3HH8T xMMd6sVV9LjOE2iOm4ekIUHieMwJjfnY 7yG7obH6OFI=
+gtld-servers.net. 172800 IN NS av1.nstld.com.
+gtld-servers.net. 172800 IN NS av2.nstld.com.
+gtld-servers.net. 172800 IN NS av3.nstld.com.
+gtld-servers.net. 172800 IN NS av4.nstld.com.
+SECTION ADDITIONAL
+av1.nstld.com. 172800 IN A 192.42.177.30
+av1.nstld.com. 172800 IN AAAA 2001:500:124::30
+av2.nstld.com. 172800 IN A 192.42.178.30
+av2.nstld.com. 172800 IN AAAA 2001:500:125::30
+av3.nstld.com. 172800 IN A 192.82.133.30
+av3.nstld.com. 172800 IN AAAA 2001:500:126::30
+av4.nstld.com. 172800 IN A 192.82.134.30
+av4.nstld.com. 172800 IN AAAA 2001:500:127::30
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR RD NOERROR
+SECTION QUESTION
+gtld-servers.net. IN DNSKEY
+SECTION AUTHORITY
+5QD8VL68T2I9KOBD32KJ8LJVH5OH2PQ0.net. 86400 IN NSEC3 1 1 0 - 5qdppotuk27kkp9ligtrb0k1cbvm9cim NS DS RRSIG
+5QD8VL68T2I9KOBD32KJ8LJVH5OH2PQ0.net. 86400 IN RRSIG NSEC3 8 2 86400 20180801102320 20180725091320 7934 net. ZKWDEle0ZQbeLFqJNnGWN9zZNZ4qXpns WEmuTMy1Ou9IRpBl0YU1RQRdjRJ4aFWM 5Kcl/UIOgeN4yD+B8HludqzhxRGDxqZ1 N1ObndmMNLbokcgyIYVnmhoe3doOnedK KRU5F6YcJpEOQ4jcJsjQd9ekQTB9aBP3 j33L4T3A1PM=
+A1RT98BS5QGC9NFI51S9HCI47ULJG6JH.net. 86400 IN NSEC3 1 1 0 - a1ruuffjkct2q54p78f8ejgj8jbk7i8b NS SOA RRSIG DNSKEY NSEC3PARAM
+A1RT98BS5QGC9NFI51S9HCI47ULJG6JH.net. 86400 IN RRSIG NSEC3 8 2 86400 20180731053505 20180724042505 7934 net. aQ1+tOFuT3esonx3VUVqcQGwUlcby0Wa Rit1P1ikFjowshfV9AUsn/bkka2dFgxC PgDtmMiQ6TzAKiwciFJ5mZitfFZSEoS/ Z3pnsZsvB062GrKNup9+x4SBiRB3HH8T xMMd6sVV9LjOE2iOm4ekIUHieMwJjfnY 7yG7obH6OFI=
+gtld-servers.net. 172800 IN NS av1.nstld.com.
+gtld-servers.net. 172800 IN NS av2.nstld.com.
+gtld-servers.net. 172800 IN NS av3.nstld.com.
+gtld-servers.net. 172800 IN NS av4.nstld.com.
+SECTION ADDITIONAL
+av1.nstld.com. 172800 IN A 192.42.177.30
+av1.nstld.com. 172800 IN AAAA 2001:500:124::30
+av2.nstld.com. 172800 IN A 192.42.178.30
+av2.nstld.com. 172800 IN AAAA 2001:500:125::30
+av3.nstld.com. 172800 IN A 192.82.133.30
+av3.nstld.com. 172800 IN AAAA 2001:500:126::30
+av4.nstld.com. 172800 IN A 192.82.134.30
+av4.nstld.com. 172800 IN AAAA 2001:500:127::30
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+gtld-servers.net. IN DS
+SECTION AUTHORITY
+5QD8VL68T2I9KOBD32KJ8LJVH5OH2PQ0.net. 86400 IN NSEC3 1 1 0 - 5qdppotuk27kkp9ligtrb0k1cbvm9cim NS DS RRSIG
+5QD8VL68T2I9KOBD32KJ8LJVH5OH2PQ0.net. 86400 IN RRSIG NSEC3 8 2 86400 20180801102320 20180725091320 7934 net. ZKWDEle0ZQbeLFqJNnGWN9zZNZ4qXpns WEmuTMy1Ou9IRpBl0YU1RQRdjRJ4aFWM 5Kcl/UIOgeN4yD+B8HludqzhxRGDxqZ1 N1ObndmMNLbokcgyIYVnmhoe3doOnedK KRU5F6YcJpEOQ4jcJsjQd9ekQTB9aBP3 j33L4T3A1PM=
+A1RT98BS5QGC9NFI51S9HCI47ULJG6JH.net. 86400 IN NSEC3 1 1 0 - a1ruuffjkct2q54p78f8ejgj8jbk7i8b NS SOA RRSIG DNSKEY NSEC3PARAM
+A1RT98BS5QGC9NFI51S9HCI47ULJG6JH.net. 86400 IN RRSIG NSEC3 8 2 86400 20180731053505 20180724042505 7934 net. aQ1+tOFuT3esonx3VUVqcQGwUlcby0Wa Rit1P1ikFjowshfV9AUsn/bkka2dFgxC PgDtmMiQ6TzAKiwciFJ5mZitfFZSEoS/ Z3pnsZsvB062GrKNup9+x4SBiRB3HH8T xMMd6sVV9LjOE2iOm4ekIUHieMwJjfnY 7yG7obH6OFI=
+net. 900 IN RRSIG SOA 8 1 900 20180803164328 20180727153328 7934 net. ZWXeaMxei6TLZhNkc4cXpocES6HhF1gb COvQ/kMTDUs5xK/d9gxxKcKje1hWmbUM 4rx00UkmCD6LrMkBKA0dfNFQVcQ1RAkN TWw21eotUZ0zisthm4LD2vG9fQ9q9X1n MhurnN4hOURgFcaeBzTcK63HXA/iMziH ICsuOHsJxa4=
+net. 900 IN SOA a.gtld-servers.net. nstld.verisign-grs.com. 1532709808 1800 900 604800 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR RD NOERROR
+SECTION QUESTION
+nstld.com. IN A
+SECTION AUTHORITY
+5V12UURISSGGLPAS52GE1V3R0V7KR5BS.com. 86400 IN NSEC3 1 1 0 - 5v13q049b9ittui4fbdtm34dtev47bgj NS DS RRSIG
+5V12UURISSGGLPAS52GE1V3R0V7KR5BS.com. 86400 IN RRSIG NSEC3 8 2 86400 20180802050635 20180726035635 46475 com. lF01rDWQAlm2v2Pfut1so+I6lSb4bLUA SXn21EAw0lSKAMPg5sOQHElu8EEcJInY zTFRpTOtCs6QGRlk//3+IpFK3nNunJrD GFS9A8XP5l4z8Z4/ZtQDsPhrfSZTizwA M7Un8JL9LniZ1ueo8409gEFbA8Xqw4sP ojwW8QIrt7Y=
+CK0POJMG874LJREF7EFN8430QVIT8BSM.com. 86400 IN NSEC3 1 1 0 - ck0q1gin43n1arrc9osm6qpqr81h5m9a NS SOA RRSIG DNSKEY NSEC3PARAM
+CK0POJMG874LJREF7EFN8430QVIT8BSM.com. 86400 IN RRSIG NSEC3 8 2 86400 20180731044815 20180724033815 46475 com. fM3ga8tkCx9ZVu/L/hQGXNcPxPVEGLfC gCgTtsJyUNefVSPOCMdqneA70UMVn06T bkGLDe85cA8ZViEnqc3iG6zhZIAwqas1 /5G509o4Ppf4lDI5CsH3iEhL5ofH+xfL t+wWEaTCLsUtmJN/VrSdqwpgJTNIJCcM QNF5A4J5btQ=
+nstld.com. 172800 IN NS av1.nstld.com.
+nstld.com. 172800 IN NS av2.nstld.com.
+nstld.com. 172800 IN NS av3.nstld.com.
+nstld.com. 172800 IN NS av4.nstld.com.
+SECTION ADDITIONAL
+av1.nstld.com. 172800 IN A 192.42.177.30
+av1.nstld.com. 172800 IN AAAA 2001:500:124::30
+av2.nstld.com. 172800 IN A 192.42.178.30
+av2.nstld.com. 172800 IN AAAA 2001:500:125::30
+av3.nstld.com. 172800 IN A 192.82.133.30
+av3.nstld.com. 172800 IN AAAA 2001:500:126::30
+av4.nstld.com. 172800 IN A 192.82.134.30
+av4.nstld.com. 172800 IN AAAA 2001:500:127::30
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR RD NOERROR
+SECTION QUESTION
+nstld.com. IN DNSKEY
+SECTION AUTHORITY
+5V12UURISSGGLPAS52GE1V3R0V7KR5BS.com. 86400 IN NSEC3 1 1 0 - 5v13q049b9ittui4fbdtm34dtev47bgj NS DS RRSIG
+5V12UURISSGGLPAS52GE1V3R0V7KR5BS.com. 86400 IN RRSIG NSEC3 8 2 86400 20180802050635 20180726035635 46475 com. lF01rDWQAlm2v2Pfut1so+I6lSb4bLUA SXn21EAw0lSKAMPg5sOQHElu8EEcJInY zTFRpTOtCs6QGRlk//3+IpFK3nNunJrD GFS9A8XP5l4z8Z4/ZtQDsPhrfSZTizwA M7Un8JL9LniZ1ueo8409gEFbA8Xqw4sP ojwW8QIrt7Y=
+CK0POJMG874LJREF7EFN8430QVIT8BSM.com. 86400 IN NSEC3 1 1 0 - ck0q1gin43n1arrc9osm6qpqr81h5m9a NS SOA RRSIG DNSKEY NSEC3PARAM
+CK0POJMG874LJREF7EFN8430QVIT8BSM.com. 86400 IN RRSIG NSEC3 8 2 86400 20180731044815 20180724033815 46475 com. fM3ga8tkCx9ZVu/L/hQGXNcPxPVEGLfC gCgTtsJyUNefVSPOCMdqneA70UMVn06T bkGLDe85cA8ZViEnqc3iG6zhZIAwqas1 /5G509o4Ppf4lDI5CsH3iEhL5ofH+xfL t+wWEaTCLsUtmJN/VrSdqwpgJTNIJCcM QNF5A4J5btQ=
+nstld.com. 172800 IN NS av1.nstld.com.
+nstld.com. 172800 IN NS av2.nstld.com.
+nstld.com. 172800 IN NS av3.nstld.com.
+nstld.com. 172800 IN NS av4.nstld.com.
+SECTION ADDITIONAL
+av1.nstld.com. 172800 IN A 192.42.177.30
+av1.nstld.com. 172800 IN AAAA 2001:500:124::30
+av2.nstld.com. 172800 IN A 192.42.178.30
+av2.nstld.com. 172800 IN AAAA 2001:500:125::30
+av3.nstld.com. 172800 IN A 192.82.133.30
+av3.nstld.com. 172800 IN AAAA 2001:500:126::30
+av4.nstld.com. 172800 IN A 192.82.134.30
+av4.nstld.com. 172800 IN AAAA 2001:500:127::30
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+nstld.com. IN DS
+SECTION AUTHORITY
+5V12UURISSGGLPAS52GE1V3R0V7KR5BS.com. 86400 IN NSEC3 1 1 0 - 5v13q049b9ittui4fbdtm34dtev47bgj NS DS RRSIG
+5V12UURISSGGLPAS52GE1V3R0V7KR5BS.com. 86400 IN RRSIG NSEC3 8 2 86400 20180802050635 20180726035635 46475 com. lF01rDWQAlm2v2Pfut1so+I6lSb4bLUA SXn21EAw0lSKAMPg5sOQHElu8EEcJInY zTFRpTOtCs6QGRlk//3+IpFK3nNunJrD GFS9A8XP5l4z8Z4/ZtQDsPhrfSZTizwA M7Un8JL9LniZ1ueo8409gEFbA8Xqw4sP ojwW8QIrt7Y=
+CK0POJMG874LJREF7EFN8430QVIT8BSM.com. 86400 IN NSEC3 1 1 0 - ck0q1gin43n1arrc9osm6qpqr81h5m9a NS SOA RRSIG DNSKEY NSEC3PARAM
+CK0POJMG874LJREF7EFN8430QVIT8BSM.com. 86400 IN RRSIG NSEC3 8 2 86400 20180731044815 20180724033815 46475 com. fM3ga8tkCx9ZVu/L/hQGXNcPxPVEGLfC gCgTtsJyUNefVSPOCMdqneA70UMVn06T bkGLDe85cA8ZViEnqc3iG6zhZIAwqas1 /5G509o4Ppf4lDI5CsH3iEhL5ofH+xfL t+wWEaTCLsUtmJN/VrSdqwpgJTNIJCcM QNF5A4J5btQ=
+com. 900 IN RRSIG SOA 8 1 900 20180803164344 20180727153344 46475 com. mBKTxHc1L8vSbi+fiS0UNrRFChdlnFyM 63qD+GwUugwtsu9uNhTA+9SrwhgSdM1O MOwX2B/Erqt7e68Ur+4BfCzD9SuaZVS2 7rfb5wFQeumdHJs4wZyXk/jL9DbjdnHL 5y8b0uGkv8H2YmnWMEVo7pCWQbOphrhz pbNXp+c3mb8=
+com. 900 IN SOA a.gtld-servers.net. nstld.verisign-grs.com. 1532709824 1800 900 604800 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+net. IN DNSKEY
+SECTION ANSWER
+net. 86400 IN DNSKEY 256 3 8 AQO6ELLy73I+l1XTVPuW3zfQkw5nublx oY4QgdTVOfUjdv6ooKTMRMgfKb+alpX5 8L5pfhndd+o7hisIwgiH2b6aqjdljzTf dV4XeZ/2CROv1ki/BRWwD61P/w688bpu Bl/u3vsTjvjq6FdVZVf3/afMXtSO1RR7 uaQ7qn8oupY/6w==
+net. 86400 IN DNSKEY 257 3 8 AQOYBnzqWXIEj6mlgXg4LWC0HP2n8eK8 XqgHlmJ/69iuIHsa1TrHDG6TcOra/pye GKwH0nKZhTmXSuUFGh9BCNiwVDuyyb6O BGy2Nte9Kr8NwWg4q+zhSoOf4D+gC9dE zg0yFdwT0DKEvmNPt0K4jbQDS4Yimb+u PKuF6yieWWrPYYCrv8C9KC8JMze2uT6N uWBfsl2fDUoV4l65qMww06D7n+p7Rbdw WkAZ0fA63mXVXBZF6kpDtsYD7SUB9jhh fLQE/r85bvg3FaSs5Wi2BaqN06SzGWI1 DHu7axthIOeHwg00zxlhTpoYCH0ldoQz +S65zWYi/fRJiyLSBb6JZOvn
+net. 86400 IN RRSIG DNSKEY 8 1 86400 20180808153857 20180724153357 35886 net. lmab/pWDgNRz6BN1BFZmkwiZz0qay0rz +46JXwgzI/g8eadEAev1OaIfsply91iM Sn+87NMPDN1Spjr3LKSXQB7+nc8n3yrf h1gxPRsjwuWxvPc3dJwlB4P8NvXTk4B5 vzjSpcfzvb+6YuAoC171yFcIcER1RN5d j3y1NRx1EAnuanMfoHIm+2dcu14a2hKn fB0zc/hm4L/rO/Qm8c3z97d1OffQs0L0 MGCU/kBDm/UyjymSFobMlIcn0bIha7A1 QN753OY+LEOWq0flQgUrKeuXvAe2o46g GebT+8euJahn/HmgmHD/bCNn+GC/KRJJ L1wFQH3x8uqlq9loQMPjwQ==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+com. IN DNSKEY
+SECTION ANSWER
+com. 86400 IN DNSKEY 256 3 8 AQPeabgR6Fgrk5FSLilDYUedwsHA0HH2 2e8+Zp/uvp4aj1dVDAy5C9bkRA+xot3s G1KaT5hvgoE7eNV93F7pBW9rvVE3A/BN vJbLXxKhkAJV5KMFC10NRcdb+xF+sM4X TMPESPrYwTLUEpSFntMIVLAtUzLaBo6Y pTVR20osgGgc3Q==
+com. 86400 IN DNSKEY 257 3 8 AQPDzldNmMvZFX4NcNJ0uEnKDg7tmv/F 3MyQR0lpBmVcNcsIszxNFxsBfKNW9JYC Yqpik8366LE7VbIcNRzfp2h9OO8HRl+H +E08zauK8k7evWEmu/6od+2boggPoiEf GNyvNPaSI7FOIroDsnw/taggzHRX1Z7S OiOiPWPNIwSUyWOZ79VmcQ1GLkC6NlYv G3HwYmynQv6oFwGv/KELSw7ZSdrbTQ0H XvZbqMUI7BaMskmvgm1G7oKZ1YiF7O9i oVNc0+7ASbqmZN7Z98EGU/Qh2K/BgUe8 Hs0XVcdPKrtyYnoQHd2ynKPcMMlTEih2 /2HDHjRPJ2aywIpKNnv4oPo/
+com. 86400 IN RRSIG DNSKEY 8 1 86400 20180810182533 20180726182033 30909 com. pytllCSmnIFN69hPKx3IcJSV3ZD+4qoF CXIuN+LXSJpkWmpD4gOWKgAytIBMImbh iUrfLECS2c3TJkjWjthKjL+GpYIHN1Z/ UY2zdSqKr0JqBQjHs456zBsJIrRriQKh e7MEFWV+JLSYAHQi/8+ot3l9GKO9nSK6 zqP+FrMtkPtZbJeNo1muSQ4lrdvYw4/t k0FADV0DK8p8/D/OQEPg2+Mpwx9GjCVN VOlKS5vuGHGAKI0gXlhJoe28i5McJVc5 O/evqbRX37xmfX01F8W4f6lZBt3qVIVq gW9iJAjY5vd4l4m53lTzYKTLeJTFH358 TsJO93q0NpaWL78xLxkVrg==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH subdomain
+ADJUST copy_id copy_query
+REPLY QR RD NOERROR
+SECTION QUESTION
+root-servers.net. IN NS
+SECTION AUTHORITY
+A1RT98BS5QGC9NFI51S9HCI47ULJG6JH.net. 86400 IN NSEC3 1 1 0 - a1ruuffjkct2q54p78f8ejgj8jbk7i8b NS SOA RRSIG DNSKEY NSEC3PARAM
+A1RT98BS5QGC9NFI51S9HCI47ULJG6JH.net. 86400 IN RRSIG NSEC3 8 2 86400 20180731053505 20180724042505 7934 net. aQ1+tOFuT3esonx3VUVqcQGwUlcby0Wa Rit1P1ikFjowshfV9AUsn/bkka2dFgxC PgDtmMiQ6TzAKiwciFJ5mZitfFZSEoS/ Z3pnsZsvB062GrKNup9+x4SBiRB3HH8T xMMd6sVV9LjOE2iOm4ekIUHieMwJjfnY 7yG7obH6OFI=
+T2UF21DR03E0BNPB42UQMVUF38P2TA8D.net. 86400 IN NSEC3 1 1 0 - t2ukct9k5i0uhv7b3m3na6jaigdjm0gr NS DS RRSIG
+T2UF21DR03E0BNPB42UQMVUF38P2TA8D.net. 86400 IN RRSIG NSEC3 8 2 86400 20180802052514 20180726041514 7934 net. LDVOVqnK+2HRKN6dUmVP3pP2RE0dCKTQ oE0d2w1AiDAOhn3Ye9Aq0yUjkz+frcUj ZqvTdiC58q0mXpyLUbqWiGmazUVG5qT7 zx5mhp1Leetq1wVJH8KGYLEmTstTCT56 oMbtWugGmZeY2B47rCsCeaWPNdH/b8qb UrwpfdPbhJE=
+root-servers.net. 172800 IN NS a.root-servers.net.
+root-servers.net. 172800 IN NS b.root-servers.net.
+root-servers.net. 172800 IN NS c.root-servers.net.
+root-servers.net. 172800 IN NS d.root-servers.net.
+root-servers.net. 172800 IN NS e.root-servers.net.
+root-servers.net. 172800 IN NS f.root-servers.net.
+root-servers.net. 172800 IN NS g.root-servers.net.
+root-servers.net. 172800 IN NS h.root-servers.net.
+root-servers.net. 172800 IN NS i.root-servers.net.
+root-servers.net. 172800 IN NS j.root-servers.net.
+root-servers.net. 172800 IN NS k.root-servers.net.
+root-servers.net. 172800 IN NS l.root-servers.net.
+root-servers.net. 172800 IN NS m.root-servers.net.
+SECTION ADDITIONAL
+a.root-servers.net. 172800 IN A 198.41.0.4
+a.root-servers.net. 172800 IN AAAA 2001:503:ba3e::2:30
+b.root-servers.net. 172800 IN A 199.9.14.201
+b.root-servers.net. 172800 IN AAAA 2001:500:200::b
+c.root-servers.net. 172800 IN A 192.33.4.12
+c.root-servers.net. 172800 IN AAAA 2001:500:2::c
+d.root-servers.net. 172800 IN A 199.7.91.13
+d.root-servers.net. 172800 IN AAAA 2001:500:2d::d
+e.root-servers.net. 172800 IN A 192.203.230.10
+e.root-servers.net. 172800 IN AAAA 2001:500:a8::e
+f.root-servers.net. 172800 IN A 192.5.5.241
+f.root-servers.net. 172800 IN AAAA 2001:500:2f::f
+g.root-servers.net. 172800 IN A 192.112.36.4
+g.root-servers.net. 172800 IN AAAA 2001:500:12::d0d
+h.root-servers.net. 172800 IN A 198.97.190.53
+h.root-servers.net. 172800 IN AAAA 2001:500:1::53
+i.root-servers.net. 172800 IN A 192.36.148.17
+i.root-servers.net. 172800 IN AAAA 2001:7fe::53
+j.root-servers.net. 172800 IN A 192.58.128.30
+j.root-servers.net. 172800 IN AAAA 2001:503:c27::2:30
+k.root-servers.net. 172800 IN A 193.0.14.129
+k.root-servers.net. 172800 IN AAAA 2001:7fd::1
+l.root-servers.net. 172800 IN A 199.7.83.42
+l.root-servers.net. 172800 IN AAAA 2001:500:9f::42
+m.root-servers.net. 172800 IN A 202.12.27.33
+m.root-servers.net. 172800 IN AAAA 2001:dc3::35
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH subdomain
+ADJUST copy_id copy_query
+REPLY QR RD NOERROR
+SECTION QUESTION
+gtld-servers.net. IN NS
+SECTION AUTHORITY
+5QD8VL68T2I9KOBD32KJ8LJVH5OH2PQ0.net. 86400 IN NSEC3 1 1 0 - 5qdppotuk27kkp9ligtrb0k1cbvm9cim NS DS RRSIG
+5QD8VL68T2I9KOBD32KJ8LJVH5OH2PQ0.net. 86400 IN RRSIG NSEC3 8 2 86400 20180801102320 20180725091320 7934 net. ZKWDEle0ZQbeLFqJNnGWN9zZNZ4qXpns WEmuTMy1Ou9IRpBl0YU1RQRdjRJ4aFWM 5Kcl/UIOgeN4yD+B8HludqzhxRGDxqZ1 N1ObndmMNLbokcgyIYVnmhoe3doOnedK KRU5F6YcJpEOQ4jcJsjQd9ekQTB9aBP3 j33L4T3A1PM=
+A1RT98BS5QGC9NFI51S9HCI47ULJG6JH.net. 86400 IN NSEC3 1 1 0 - a1ruuffjkct2q54p78f8ejgj8jbk7i8b NS SOA RRSIG DNSKEY NSEC3PARAM
+A1RT98BS5QGC9NFI51S9HCI47ULJG6JH.net. 86400 IN RRSIG NSEC3 8 2 86400 20180731053505 20180724042505 7934 net. aQ1+tOFuT3esonx3VUVqcQGwUlcby0Wa Rit1P1ikFjowshfV9AUsn/bkka2dFgxC PgDtmMiQ6TzAKiwciFJ5mZitfFZSEoS/ Z3pnsZsvB062GrKNup9+x4SBiRB3HH8T xMMd6sVV9LjOE2iOm4ekIUHieMwJjfnY 7yG7obH6OFI=
+gtld-servers.net. 172800 IN NS av1.nstld.com.
+gtld-servers.net. 172800 IN NS av2.nstld.com.
+gtld-servers.net. 172800 IN NS av3.nstld.com.
+gtld-servers.net. 172800 IN NS av4.nstld.com.
+SECTION ADDITIONAL
+av1.nstld.com. 172800 IN A 192.42.177.30
+av1.nstld.com. 172800 IN AAAA 2001:500:124::30
+av2.nstld.com. 172800 IN A 192.42.178.30
+av2.nstld.com. 172800 IN AAAA 2001:500:125::30
+av3.nstld.com. 172800 IN A 192.82.133.30
+av3.nstld.com. 172800 IN AAAA 2001:500:126::30
+av4.nstld.com. 172800 IN A 192.82.134.30
+av4.nstld.com. 172800 IN AAAA 2001:500:127::30
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH subdomain
+ADJUST copy_id copy_query
+REPLY QR RD NOERROR
+SECTION QUESTION
+nstld.com. IN NS
+SECTION AUTHORITY
+5V12UURISSGGLPAS52GE1V3R0V7KR5BS.com. 86400 IN NSEC3 1 1 0 - 5v13q049b9ittui4fbdtm34dtev47bgj NS DS RRSIG
+5V12UURISSGGLPAS52GE1V3R0V7KR5BS.com. 86400 IN RRSIG NSEC3 8 2 86400 20180802050635 20180726035635 46475 com. lF01rDWQAlm2v2Pfut1so+I6lSb4bLUA SXn21EAw0lSKAMPg5sOQHElu8EEcJInY zTFRpTOtCs6QGRlk//3+IpFK3nNunJrD GFS9A8XP5l4z8Z4/ZtQDsPhrfSZTizwA M7Un8JL9LniZ1ueo8409gEFbA8Xqw4sP ojwW8QIrt7Y=
+CK0POJMG874LJREF7EFN8430QVIT8BSM.com. 86400 IN NSEC3 1 1 0 - ck0q1gin43n1arrc9osm6qpqr81h5m9a NS SOA RRSIG DNSKEY NSEC3PARAM
+CK0POJMG874LJREF7EFN8430QVIT8BSM.com. 86400 IN RRSIG NSEC3 8 2 86400 20180731044815 20180724033815 46475 com. fM3ga8tkCx9ZVu/L/hQGXNcPxPVEGLfC gCgTtsJyUNefVSPOCMdqneA70UMVn06T bkGLDe85cA8ZViEnqc3iG6zhZIAwqas1 /5G509o4Ppf4lDI5CsH3iEhL5ofH+xfL t+wWEaTCLsUtmJN/VrSdqwpgJTNIJCcM QNF5A4J5btQ=
+nstld.com. 172800 IN NS av1.nstld.com.
+nstld.com. 172800 IN NS av2.nstld.com.
+nstld.com. 172800 IN NS av3.nstld.com.
+nstld.com. 172800 IN NS av4.nstld.com.
+SECTION ADDITIONAL
+av1.nstld.com. 172800 IN A 192.42.177.30
+av1.nstld.com. 172800 IN AAAA 2001:500:124::30
+av2.nstld.com. 172800 IN A 192.42.178.30
+av2.nstld.com. 172800 IN AAAA 2001:500:125::30
+av3.nstld.com. 172800 IN A 192.82.133.30
+av3.nstld.com. 172800 IN AAAA 2001:500:126::30
+av4.nstld.com. 172800 IN A 192.82.134.30
+av4.nstld.com. 172800 IN AAAA 2001:500:127::30
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH subdomain
+ADJUST copy_id copy_query
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+net. IN NS
+SECTION ANSWER
+net. 172800 IN NS a.gtld-servers.net.
+net. 172800 IN NS b.gtld-servers.net.
+net. 172800 IN NS c.gtld-servers.net.
+net. 172800 IN NS d.gtld-servers.net.
+net. 172800 IN NS e.gtld-servers.net.
+net. 172800 IN NS f.gtld-servers.net.
+net. 172800 IN NS g.gtld-servers.net.
+net. 172800 IN NS h.gtld-servers.net.
+net. 172800 IN NS i.gtld-servers.net.
+net. 172800 IN NS j.gtld-servers.net.
+net. 172800 IN NS k.gtld-servers.net.
+net. 172800 IN NS l.gtld-servers.net.
+net. 172800 IN NS m.gtld-servers.net.
+net. 172800 IN RRSIG NS 8 1 172800 20180802053055 20180726042055 7934 net. KR3mBpGrNgRPgB/LuPhUC4sjhy9F+GPU BXemSi46ZJlIWc7sK40AQ2rccrU5MDSa puWa2pVvx74pSU2w3gqeW9RH9E3wNh9t toAxJYJBNvTlXv3D1qG0LIXEsold+cvQ 0VqnFhVePojFFtFqE19H5OHaa87LVUOB Ib0gTx7i73Y=
+SECTION ADDITIONAL
+a.gtld-servers.net. 172800 IN A 192.5.6.30
+a.gtld-servers.net. 172800 IN AAAA 2001:503:a83e::2:30
+b.gtld-servers.net. 172800 IN A 192.33.14.30
+b.gtld-servers.net. 172800 IN AAAA 2001:503:231d::2:30
+c.gtld-servers.net. 172800 IN A 192.26.92.30
+c.gtld-servers.net. 172800 IN AAAA 2001:503:83eb::30
+d.gtld-servers.net. 172800 IN A 192.31.80.30
+d.gtld-servers.net. 172800 IN AAAA 2001:500:856e::30
+e.gtld-servers.net. 172800 IN A 192.12.94.30
+e.gtld-servers.net. 172800 IN AAAA 2001:502:1ca1::30
+f.gtld-servers.net. 172800 IN A 192.35.51.30
+f.gtld-servers.net. 172800 IN AAAA 2001:503:d414::30
+g.gtld-servers.net. 172800 IN A 192.42.93.30
+g.gtld-servers.net. 172800 IN AAAA 2001:503:eea3::30
+h.gtld-servers.net. 172800 IN A 192.54.112.30
+h.gtld-servers.net. 172800 IN AAAA 2001:502:8cc::30
+i.gtld-servers.net. 172800 IN A 192.43.172.30
+i.gtld-servers.net. 172800 IN AAAA 2001:503:39c1::30
+j.gtld-servers.net. 172800 IN A 192.48.79.30
+j.gtld-servers.net. 172800 IN AAAA 2001:502:7094::30
+k.gtld-servers.net. 172800 IN A 192.52.178.30
+k.gtld-servers.net. 172800 IN AAAA 2001:503:d2d::30
+l.gtld-servers.net. 172800 IN A 192.41.162.30
+l.gtld-servers.net. 172800 IN AAAA 2001:500:d937::30
+m.gtld-servers.net. 172800 IN A 192.55.83.30
+m.gtld-servers.net. 172800 IN AAAA 2001:501:b1f9::30
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH subdomain
+ADJUST copy_id copy_query
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. 172800 IN NS a.gtld-servers.net.
+com. 172800 IN NS b.gtld-servers.net.
+com. 172800 IN NS c.gtld-servers.net.
+com. 172800 IN NS d.gtld-servers.net.
+com. 172800 IN NS e.gtld-servers.net.
+com. 172800 IN NS f.gtld-servers.net.
+com. 172800 IN NS g.gtld-servers.net.
+com. 172800 IN NS h.gtld-servers.net.
+com. 172800 IN NS i.gtld-servers.net.
+com. 172800 IN NS j.gtld-servers.net.
+com. 172800 IN NS k.gtld-servers.net.
+com. 172800 IN NS l.gtld-servers.net.
+com. 172800 IN NS m.gtld-servers.net.
+com. 172800 IN RRSIG NS 8 1 172800 20180731044815 20180724033815 46475 com. JgH5uVQ8OQlpGeX/UJQRQHvQJjXOlQoZ o87eG2e/PP2y1R5Td93n/BckALIzqxT9 UyZsfIKDbRbK5junHSwV8FL5HC+3Hj0K QX8k4+yrpeYB1EM/Upkb5Db1E6F4NCcs iUyDsLNUS3trL+X7/ohrTM3ScPKdMux0 a0kAzuZMWJk=
+SECTION ADDITIONAL
+a.gtld-servers.net. 172800 IN A 192.5.6.30
+a.gtld-servers.net. 172800 IN AAAA 2001:503:a83e::2:30
+b.gtld-servers.net. 172800 IN A 192.33.14.30
+b.gtld-servers.net. 172800 IN AAAA 2001:503:231d::2:30
+c.gtld-servers.net. 172800 IN A 192.26.92.30
+c.gtld-servers.net. 172800 IN AAAA 2001:503:83eb::30
+d.gtld-servers.net. 172800 IN A 192.31.80.30
+d.gtld-servers.net. 172800 IN AAAA 2001:500:856e::30
+e.gtld-servers.net. 172800 IN A 192.12.94.30
+e.gtld-servers.net. 172800 IN AAAA 2001:502:1ca1::30
+f.gtld-servers.net. 172800 IN A 192.35.51.30
+f.gtld-servers.net. 172800 IN AAAA 2001:503:d414::30
+g.gtld-servers.net. 172800 IN A 192.42.93.30
+g.gtld-servers.net. 172800 IN AAAA 2001:503:eea3::30
+h.gtld-servers.net. 172800 IN A 192.54.112.30
+h.gtld-servers.net. 172800 IN AAAA 2001:502:8cc::30
+i.gtld-servers.net. 172800 IN A 192.43.172.30
+i.gtld-servers.net. 172800 IN AAAA 2001:503:39c1::30
+j.gtld-servers.net. 172800 IN A 192.48.79.30
+j.gtld-servers.net. 172800 IN AAAA 2001:502:7094::30
+k.gtld-servers.net. 172800 IN A 192.52.178.30
+k.gtld-servers.net. 172800 IN AAAA 2001:503:d2d::30
+l.gtld-servers.net. 172800 IN A 192.41.162.30
+l.gtld-servers.net. 172800 IN AAAA 2001:500:d937::30
+m.gtld-servers.net. 172800 IN A 192.55.83.30
+m.gtld-servers.net. 172800 IN AAAA 2001:501:b1f9::30
+ENTRY_END
+
+
+RANGE_END
+
+
+; Scope "nstld.com.
+
+; Server names:
+; av1.nstld.com.
+; av2.nstld.com.
+; av3.nstld.com.
+; av4.nstld.com.
+RANGE_BEGIN 0 1000
+ ADDRESS 2001:500:124::30
+ ADDRESS 2001:500:126::30
+ ADDRESS 192.42.177.30
+ ADDRESS 192.82.134.30
+ ADDRESS 2001:500:127::30
+ ADDRESS 2001:500:125::30
+ ADDRESS 192.42.178.30
+ ADDRESS 192.82.133.30
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+a.gtld-servers.net. IN A
+SECTION ANSWER
+a.gtld-servers.net. 86400 IN A 192.5.6.30
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN NS av1.nstld.com.
+gtld-servers.net. 86400 IN NS av2.nstld.com.
+gtld-servers.net. 86400 IN NS av3.nstld.com.
+gtld-servers.net. 86400 IN NS av4.nstld.com.
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+a.gtld-servers.net. IN DNSKEY
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+a.gtld-servers.net. IN NS
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+a.gtld-servers.net. IN DS
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+a.gtld-servers.net. IN AAAA
+SECTION ANSWER
+a.gtld-servers.net. 86400 IN AAAA 2001:503:a83e::2:30
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN NS av1.nstld.com.
+gtld-servers.net. 86400 IN NS av2.nstld.com.
+gtld-servers.net. 86400 IN NS av3.nstld.com.
+gtld-servers.net. 86400 IN NS av4.nstld.com.
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+j.gtld-servers.net. IN A
+SECTION ANSWER
+j.gtld-servers.net. 86400 IN A 192.48.79.30
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN NS av1.nstld.com.
+gtld-servers.net. 86400 IN NS av2.nstld.com.
+gtld-servers.net. 86400 IN NS av3.nstld.com.
+gtld-servers.net. 86400 IN NS av4.nstld.com.
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+j.gtld-servers.net. IN DNSKEY
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+j.gtld-servers.net. IN NS
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+j.gtld-servers.net. IN DS
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+j.gtld-servers.net. IN AAAA
+SECTION ANSWER
+j.gtld-servers.net. 86400 IN AAAA 2001:502:7094::30
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN NS av1.nstld.com.
+gtld-servers.net. 86400 IN NS av2.nstld.com.
+gtld-servers.net. 86400 IN NS av3.nstld.com.
+gtld-servers.net. 86400 IN NS av4.nstld.com.
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+e.gtld-servers.net. IN A
+SECTION ANSWER
+e.gtld-servers.net. 86400 IN A 192.12.94.30
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN NS av1.nstld.com.
+gtld-servers.net. 86400 IN NS av2.nstld.com.
+gtld-servers.net. 86400 IN NS av3.nstld.com.
+gtld-servers.net. 86400 IN NS av4.nstld.com.
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+e.gtld-servers.net. IN DNSKEY
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+e.gtld-servers.net. IN NS
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+e.gtld-servers.net. IN DS
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+e.gtld-servers.net. IN AAAA
+SECTION ANSWER
+e.gtld-servers.net. 86400 IN AAAA 2001:502:1ca1::30
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN NS av1.nstld.com.
+gtld-servers.net. 86400 IN NS av2.nstld.com.
+gtld-servers.net. 86400 IN NS av3.nstld.com.
+gtld-servers.net. 86400 IN NS av4.nstld.com.
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+i.gtld-servers.net. IN A
+SECTION ANSWER
+i.gtld-servers.net. 86400 IN A 192.43.172.30
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN NS av1.nstld.com.
+gtld-servers.net. 86400 IN NS av2.nstld.com.
+gtld-servers.net. 86400 IN NS av3.nstld.com.
+gtld-servers.net. 86400 IN NS av4.nstld.com.
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+i.gtld-servers.net. IN DNSKEY
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+i.gtld-servers.net. IN NS
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+i.gtld-servers.net. IN DS
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+i.gtld-servers.net. IN AAAA
+SECTION ANSWER
+i.gtld-servers.net. 86400 IN AAAA 2001:503:39c1::30
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN NS av1.nstld.com.
+gtld-servers.net. 86400 IN NS av2.nstld.com.
+gtld-servers.net. 86400 IN NS av3.nstld.com.
+gtld-servers.net. 86400 IN NS av4.nstld.com.
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+d.gtld-servers.net. IN A
+SECTION ANSWER
+d.gtld-servers.net. 86400 IN A 192.31.80.30
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN NS av1.nstld.com.
+gtld-servers.net. 86400 IN NS av2.nstld.com.
+gtld-servers.net. 86400 IN NS av3.nstld.com.
+gtld-servers.net. 86400 IN NS av4.nstld.com.
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+d.gtld-servers.net. IN DNSKEY
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+d.gtld-servers.net. IN NS
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+d.gtld-servers.net. IN DS
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+d.gtld-servers.net. IN AAAA
+SECTION ANSWER
+d.gtld-servers.net. 86400 IN AAAA 2001:500:856e::30
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN NS av1.nstld.com.
+gtld-servers.net. 86400 IN NS av2.nstld.com.
+gtld-servers.net. 86400 IN NS av3.nstld.com.
+gtld-servers.net. 86400 IN NS av4.nstld.com.
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+m.gtld-servers.net. IN A
+SECTION ANSWER
+m.gtld-servers.net. 86400 IN A 192.55.83.30
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN NS av1.nstld.com.
+gtld-servers.net. 86400 IN NS av2.nstld.com.
+gtld-servers.net. 86400 IN NS av3.nstld.com.
+gtld-servers.net. 86400 IN NS av4.nstld.com.
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+m.gtld-servers.net. IN DNSKEY
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+m.gtld-servers.net. IN NS
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+m.gtld-servers.net. IN DS
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+m.gtld-servers.net. IN AAAA
+SECTION ANSWER
+m.gtld-servers.net. 86400 IN AAAA 2001:501:b1f9::30
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN NS av1.nstld.com.
+gtld-servers.net. 86400 IN NS av2.nstld.com.
+gtld-servers.net. 86400 IN NS av3.nstld.com.
+gtld-servers.net. 86400 IN NS av4.nstld.com.
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+h.gtld-servers.net. IN A
+SECTION ANSWER
+h.gtld-servers.net. 86400 IN A 192.54.112.30
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN NS av1.nstld.com.
+gtld-servers.net. 86400 IN NS av2.nstld.com.
+gtld-servers.net. 86400 IN NS av3.nstld.com.
+gtld-servers.net. 86400 IN NS av4.nstld.com.
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+h.gtld-servers.net. IN DNSKEY
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+h.gtld-servers.net. IN NS
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+h.gtld-servers.net. IN DS
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+h.gtld-servers.net. IN AAAA
+SECTION ANSWER
+h.gtld-servers.net. 86400 IN AAAA 2001:502:8cc::30
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN NS av1.nstld.com.
+gtld-servers.net. 86400 IN NS av2.nstld.com.
+gtld-servers.net. 86400 IN NS av3.nstld.com.
+gtld-servers.net. 86400 IN NS av4.nstld.com.
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+c.gtld-servers.net. IN A
+SECTION ANSWER
+c.gtld-servers.net. 86400 IN A 192.26.92.30
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN NS av1.nstld.com.
+gtld-servers.net. 86400 IN NS av2.nstld.com.
+gtld-servers.net. 86400 IN NS av3.nstld.com.
+gtld-servers.net. 86400 IN NS av4.nstld.com.
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+c.gtld-servers.net. IN DNSKEY
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+c.gtld-servers.net. IN NS
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+c.gtld-servers.net. IN DS
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+c.gtld-servers.net. IN AAAA
+SECTION ANSWER
+c.gtld-servers.net. 86400 IN AAAA 2001:503:83eb::30
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN NS av1.nstld.com.
+gtld-servers.net. 86400 IN NS av2.nstld.com.
+gtld-servers.net. 86400 IN NS av3.nstld.com.
+gtld-servers.net. 86400 IN NS av4.nstld.com.
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+l.gtld-servers.net. IN A
+SECTION ANSWER
+l.gtld-servers.net. 86400 IN A 192.41.162.30
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN NS av1.nstld.com.
+gtld-servers.net. 86400 IN NS av2.nstld.com.
+gtld-servers.net. 86400 IN NS av3.nstld.com.
+gtld-servers.net. 86400 IN NS av4.nstld.com.
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+l.gtld-servers.net. IN DNSKEY
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+l.gtld-servers.net. IN NS
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+l.gtld-servers.net. IN DS
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+l.gtld-servers.net. IN AAAA
+SECTION ANSWER
+l.gtld-servers.net. 86400 IN AAAA 2001:500:d937::30
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN NS av1.nstld.com.
+gtld-servers.net. 86400 IN NS av2.nstld.com.
+gtld-servers.net. 86400 IN NS av3.nstld.com.
+gtld-servers.net. 86400 IN NS av4.nstld.com.
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+g.gtld-servers.net. IN A
+SECTION ANSWER
+g.gtld-servers.net. 86400 IN A 192.42.93.30
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN NS av1.nstld.com.
+gtld-servers.net. 86400 IN NS av2.nstld.com.
+gtld-servers.net. 86400 IN NS av3.nstld.com.
+gtld-servers.net. 86400 IN NS av4.nstld.com.
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+g.gtld-servers.net. IN DNSKEY
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+g.gtld-servers.net. IN NS
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+g.gtld-servers.net. IN DS
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+g.gtld-servers.net. IN AAAA
+SECTION ANSWER
+g.gtld-servers.net. 86400 IN AAAA 2001:503:eea3::30
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN NS av1.nstld.com.
+gtld-servers.net. 86400 IN NS av2.nstld.com.
+gtld-servers.net. 86400 IN NS av3.nstld.com.
+gtld-servers.net. 86400 IN NS av4.nstld.com.
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+b.gtld-servers.net. IN A
+SECTION ANSWER
+b.gtld-servers.net. 86400 IN A 192.33.14.30
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN NS av1.nstld.com.
+gtld-servers.net. 86400 IN NS av2.nstld.com.
+gtld-servers.net. 86400 IN NS av3.nstld.com.
+gtld-servers.net. 86400 IN NS av4.nstld.com.
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+b.gtld-servers.net. IN DNSKEY
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+b.gtld-servers.net. IN NS
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+b.gtld-servers.net. IN DS
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+b.gtld-servers.net. IN AAAA
+SECTION ANSWER
+b.gtld-servers.net. 86400 IN AAAA 2001:503:231d::2:30
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN NS av1.nstld.com.
+gtld-servers.net. 86400 IN NS av2.nstld.com.
+gtld-servers.net. 86400 IN NS av3.nstld.com.
+gtld-servers.net. 86400 IN NS av4.nstld.com.
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+k.gtld-servers.net. IN A
+SECTION ANSWER
+k.gtld-servers.net. 86400 IN A 192.52.178.30
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN NS av1.nstld.com.
+gtld-servers.net. 86400 IN NS av2.nstld.com.
+gtld-servers.net. 86400 IN NS av3.nstld.com.
+gtld-servers.net. 86400 IN NS av4.nstld.com.
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+k.gtld-servers.net. IN DNSKEY
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+k.gtld-servers.net. IN NS
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+k.gtld-servers.net. IN DS
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+k.gtld-servers.net. IN AAAA
+SECTION ANSWER
+k.gtld-servers.net. 86400 IN AAAA 2001:503:d2d::30
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN NS av1.nstld.com.
+gtld-servers.net. 86400 IN NS av2.nstld.com.
+gtld-servers.net. 86400 IN NS av3.nstld.com.
+gtld-servers.net. 86400 IN NS av4.nstld.com.
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+f.gtld-servers.net. IN A
+SECTION ANSWER
+f.gtld-servers.net. 86400 IN A 192.35.51.30
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN NS av1.nstld.com.
+gtld-servers.net. 86400 IN NS av2.nstld.com.
+gtld-servers.net. 86400 IN NS av3.nstld.com.
+gtld-servers.net. 86400 IN NS av4.nstld.com.
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+f.gtld-servers.net. IN DNSKEY
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+f.gtld-servers.net. IN NS
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+f.gtld-servers.net. IN DS
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+f.gtld-servers.net. IN AAAA
+SECTION ANSWER
+f.gtld-servers.net. 86400 IN AAAA 2001:503:d414::30
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN NS av1.nstld.com.
+gtld-servers.net. 86400 IN NS av2.nstld.com.
+gtld-servers.net. 86400 IN NS av3.nstld.com.
+gtld-servers.net. 86400 IN NS av4.nstld.com.
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+av1.nstld.com. IN A
+SECTION ANSWER
+av1.nstld.com. 300 IN A 192.42.177.30
+SECTION AUTHORITY
+nstld.com. 86400 IN NS av1.nstld.com.
+nstld.com. 86400 IN NS av2.nstld.com.
+nstld.com. 86400 IN NS av3.nstld.com.
+nstld.com. 86400 IN NS av4.nstld.com.
+SECTION ADDITIONAL
+av1.nstld.com. 300 IN AAAA 2001:500:124::30
+av2.nstld.com. 300 IN A 192.42.178.30
+av2.nstld.com. 300 IN AAAA 2001:500:125::30
+av3.nstld.com. 300 IN A 192.82.133.30
+av3.nstld.com. 300 IN AAAA 2001:500:126::30
+av4.nstld.com. 300 IN A 192.82.134.30
+av4.nstld.com. 300 IN AAAA 2001:500:127::30
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+av1.nstld.com. IN DNSKEY
+SECTION AUTHORITY
+nstld.com. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2018062000 7200 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+av1.nstld.com. IN NS
+SECTION AUTHORITY
+nstld.com. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2018062000 7200 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+av1.nstld.com. IN DS
+SECTION AUTHORITY
+nstld.com. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2018062000 7200 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+av1.nstld.com. IN AAAA
+SECTION ANSWER
+av1.nstld.com. 300 IN AAAA 2001:500:124::30
+SECTION AUTHORITY
+nstld.com. 86400 IN NS av1.nstld.com.
+nstld.com. 86400 IN NS av2.nstld.com.
+nstld.com. 86400 IN NS av3.nstld.com.
+nstld.com. 86400 IN NS av4.nstld.com.
+SECTION ADDITIONAL
+av1.nstld.com. 300 IN A 192.42.177.30
+av2.nstld.com. 300 IN A 192.42.178.30
+av2.nstld.com. 300 IN AAAA 2001:500:125::30
+av3.nstld.com. 300 IN A 192.82.133.30
+av3.nstld.com. 300 IN AAAA 2001:500:126::30
+av4.nstld.com. 300 IN A 192.82.134.30
+av4.nstld.com. 300 IN AAAA 2001:500:127::30
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+av2.nstld.com. IN A
+SECTION ANSWER
+av2.nstld.com. 300 IN A 192.42.178.30
+SECTION AUTHORITY
+nstld.com. 86400 IN NS av1.nstld.com.
+nstld.com. 86400 IN NS av2.nstld.com.
+nstld.com. 86400 IN NS av3.nstld.com.
+nstld.com. 86400 IN NS av4.nstld.com.
+SECTION ADDITIONAL
+av1.nstld.com. 300 IN A 192.42.177.30
+av1.nstld.com. 300 IN AAAA 2001:500:124::30
+av2.nstld.com. 300 IN AAAA 2001:500:125::30
+av3.nstld.com. 300 IN A 192.82.133.30
+av3.nstld.com. 300 IN AAAA 2001:500:126::30
+av4.nstld.com. 300 IN A 192.82.134.30
+av4.nstld.com. 300 IN AAAA 2001:500:127::30
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+av2.nstld.com. IN DNSKEY
+SECTION AUTHORITY
+nstld.com. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2018062000 7200 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+av2.nstld.com. IN NS
+SECTION AUTHORITY
+nstld.com. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2018062000 7200 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+av2.nstld.com. IN DS
+SECTION AUTHORITY
+nstld.com. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2018062000 7200 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+av2.nstld.com. IN AAAA
+SECTION ANSWER
+av2.nstld.com. 300 IN AAAA 2001:500:125::30
+SECTION AUTHORITY
+nstld.com. 86400 IN NS av1.nstld.com.
+nstld.com. 86400 IN NS av2.nstld.com.
+nstld.com. 86400 IN NS av3.nstld.com.
+nstld.com. 86400 IN NS av4.nstld.com.
+SECTION ADDITIONAL
+av1.nstld.com. 300 IN A 192.42.177.30
+av1.nstld.com. 300 IN AAAA 2001:500:124::30
+av2.nstld.com. 300 IN A 192.42.178.30
+av3.nstld.com. 300 IN A 192.82.133.30
+av3.nstld.com. 300 IN AAAA 2001:500:126::30
+av4.nstld.com. 300 IN A 192.82.134.30
+av4.nstld.com. 300 IN AAAA 2001:500:127::30
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+av3.nstld.com. IN A
+SECTION ANSWER
+av3.nstld.com. 300 IN A 192.82.133.30
+SECTION AUTHORITY
+nstld.com. 86400 IN NS av1.nstld.com.
+nstld.com. 86400 IN NS av2.nstld.com.
+nstld.com. 86400 IN NS av3.nstld.com.
+nstld.com. 86400 IN NS av4.nstld.com.
+SECTION ADDITIONAL
+av1.nstld.com. 300 IN A 192.42.177.30
+av1.nstld.com. 300 IN AAAA 2001:500:124::30
+av2.nstld.com. 300 IN A 192.42.178.30
+av2.nstld.com. 300 IN AAAA 2001:500:125::30
+av3.nstld.com. 300 IN AAAA 2001:500:126::30
+av4.nstld.com. 300 IN A 192.82.134.30
+av4.nstld.com. 300 IN AAAA 2001:500:127::30
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+av3.nstld.com. IN DNSKEY
+SECTION AUTHORITY
+nstld.com. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2018062000 7200 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+av3.nstld.com. IN NS
+SECTION AUTHORITY
+nstld.com. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2018062000 7200 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+av3.nstld.com. IN DS
+SECTION AUTHORITY
+nstld.com. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2018062000 7200 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+av3.nstld.com. IN AAAA
+SECTION ANSWER
+av3.nstld.com. 300 IN AAAA 2001:500:126::30
+SECTION AUTHORITY
+nstld.com. 86400 IN NS av1.nstld.com.
+nstld.com. 86400 IN NS av2.nstld.com.
+nstld.com. 86400 IN NS av3.nstld.com.
+nstld.com. 86400 IN NS av4.nstld.com.
+SECTION ADDITIONAL
+av1.nstld.com. 300 IN A 192.42.177.30
+av1.nstld.com. 300 IN AAAA 2001:500:124::30
+av2.nstld.com. 300 IN A 192.42.178.30
+av2.nstld.com. 300 IN AAAA 2001:500:125::30
+av3.nstld.com. 300 IN A 192.82.133.30
+av4.nstld.com. 300 IN A 192.82.134.30
+av4.nstld.com. 300 IN AAAA 2001:500:127::30
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+av4.nstld.com. IN A
+SECTION ANSWER
+av4.nstld.com. 300 IN A 192.82.134.30
+SECTION AUTHORITY
+nstld.com. 86400 IN NS av1.nstld.com.
+nstld.com. 86400 IN NS av2.nstld.com.
+nstld.com. 86400 IN NS av3.nstld.com.
+nstld.com. 86400 IN NS av4.nstld.com.
+SECTION ADDITIONAL
+av1.nstld.com. 300 IN A 192.42.177.30
+av1.nstld.com. 300 IN AAAA 2001:500:124::30
+av2.nstld.com. 300 IN A 192.42.178.30
+av2.nstld.com. 300 IN AAAA 2001:500:125::30
+av3.nstld.com. 300 IN A 192.82.133.30
+av3.nstld.com. 300 IN AAAA 2001:500:126::30
+av4.nstld.com. 300 IN AAAA 2001:500:127::30
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+av4.nstld.com. IN DNSKEY
+SECTION AUTHORITY
+nstld.com. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2018062000 7200 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+av4.nstld.com. IN NS
+SECTION AUTHORITY
+nstld.com. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2018062000 7200 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+av4.nstld.com. IN DS
+SECTION AUTHORITY
+nstld.com. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2018062000 7200 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+av4.nstld.com. IN AAAA
+SECTION ANSWER
+av4.nstld.com. 300 IN AAAA 2001:500:127::30
+SECTION AUTHORITY
+nstld.com. 86400 IN NS av1.nstld.com.
+nstld.com. 86400 IN NS av2.nstld.com.
+nstld.com. 86400 IN NS av3.nstld.com.
+nstld.com. 86400 IN NS av4.nstld.com.
+SECTION ADDITIONAL
+av1.nstld.com. 300 IN A 192.42.177.30
+av1.nstld.com. 300 IN AAAA 2001:500:124::30
+av2.nstld.com. 300 IN A 192.42.178.30
+av2.nstld.com. 300 IN AAAA 2001:500:125::30
+av3.nstld.com. 300 IN A 192.82.133.30
+av3.nstld.com. 300 IN AAAA 2001:500:126::30
+av4.nstld.com. 300 IN A 192.82.134.30
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+gtld-servers.net. IN DNSKEY
+SECTION AUTHORITY
+gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+nstld.com. IN DNSKEY
+SECTION AUTHORITY
+nstld.com. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2018062000 7200 900 1209600 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH subdomain
+ADJUST copy_id copy_query
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+gtld-servers.net. IN NS
+SECTION ANSWER
+gtld-servers.net. 86400 IN NS av1.nstld.com.
+gtld-servers.net. 86400 IN NS av2.nstld.com.
+gtld-servers.net. 86400 IN NS av3.nstld.com.
+gtld-servers.net. 86400 IN NS av4.nstld.com.
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH subdomain
+ADJUST copy_id copy_query
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+nstld.com. IN NS
+SECTION ANSWER
+nstld.com. 86400 IN NS av1.nstld.com.
+nstld.com. 86400 IN NS av2.nstld.com.
+nstld.com. 86400 IN NS av3.nstld.com.
+nstld.com. 86400 IN NS av4.nstld.com.
+SECTION ADDITIONAL
+av1.nstld.com. 300 IN A 192.42.177.30
+av1.nstld.com. 300 IN AAAA 2001:500:124::30
+av2.nstld.com. 300 IN A 192.42.178.30
+av2.nstld.com. 300 IN AAAA 2001:500:125::30
+av3.nstld.com. 300 IN A 192.82.133.30
+av3.nstld.com. 300 IN AAAA 2001:500:126::30
+av4.nstld.com. 300 IN A 192.82.134.30
+av4.nstld.com. 300 IN AAAA 2001:500:127::30
+ENTRY_END
+
+
+RANGE_END
+
+
+; Scope "cz.
+
+; Server names:
+; b.ns.nic.cz.
+; d.ns.nic.cz.
+; a.ns.nic.cz.
+; c.ns.nic.cz.
+RANGE_BEGIN 0 1000
+ ADDRESS 2001:678:11::1
+ ADDRESS 193.29.206.1
+ ADDRESS 2001:678:10::1
+ ADDRESS 2001:678:f::1
+ ADDRESS 194.0.12.1
+ ADDRESS 217.31.205.50
+ ADDRESS 2001:678:1::1
+ ADDRESS 194.0.14.1
+ ADDRESS 194.0.13.1
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR RD NOERROR
+SECTION QUESTION
+root.cz. IN TYPE65535
+SECTION AUTHORITY
+root.cz. 3600 IN DS 21523 5 2 b73053df8858181e1940ee6160e75d5339103264b9e56a9a1ecd64adabb2e54f
+root.cz. 3600 IN NS ns.iinfo.cz.
+root.cz. 3600 IN NS ns6.adminit.cz.
+root.cz. 3600 IN RRSIG DS 13 2 3600 20180809020236 20180727093611 62295 cz. vQCM/GJGJky3kC1IcQZpFddgl0iTTvzq EPV6FPEttgS59K3TnAd9jHKqQrXi7cEW yQ8eO7k27czWZ1UyA4wM2g==
+SECTION ADDITIONAL
+ns.iinfo.cz. 3600 IN A 91.213.160.5
+ns.iinfo.cz. 3600 IN AAAA 2001:67c:68::5
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR RD NOERROR
+SECTION QUESTION
+root.cz. IN DNSKEY
+SECTION AUTHORITY
+root.cz. 3600 IN DS 21523 5 2 b73053df8858181e1940ee6160e75d5339103264b9e56a9a1ecd64adabb2e54f
+root.cz. 3600 IN NS ns.iinfo.cz.
+root.cz. 3600 IN NS ns6.adminit.cz.
+root.cz. 3600 IN RRSIG DS 13 2 3600 20180809020236 20180727093611 62295 cz. vQCM/GJGJky3kC1IcQZpFddgl0iTTvzq EPV6FPEttgS59K3TnAd9jHKqQrXi7cEW yQ8eO7k27czWZ1UyA4wM2g==
+SECTION ADDITIONAL
+ns.iinfo.cz. 3600 IN A 91.213.160.5
+ns.iinfo.cz. 3600 IN AAAA 2001:67c:68::5
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+root.cz. IN DS
+SECTION ANSWER
+root.cz. 3600 IN DS 21523 5 2 b73053df8858181e1940ee6160e75d5339103264b9e56a9a1ecd64adabb2e54f
+root.cz. 3600 IN RRSIG DS 13 2 3600 20180809020236 20180727093611 62295 cz. vQCM/GJGJky3kC1IcQZpFddgl0iTTvzq EPV6FPEttgS59K3TnAd9jHKqQrXi7cEW yQ8eO7k27czWZ1UyA4wM2g==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR RD NOERROR
+SECTION QUESTION
+iinfo.cz. IN A
+SECTION AUTHORITY
+iinfo.cz. 3600 IN DS 21523 5 2 1f3ad3f9eace2aacf2cca9464e6642fe4bafce5a2817da25faef31e59c1fb74e
+iinfo.cz. 3600 IN NS ns.iinfo.cz.
+iinfo.cz. 3600 IN NS ns6.adminit.cz.
+iinfo.cz. 3600 IN RRSIG DS 13 2 3600 20180809121603 20180727063545 62295 cz. 7Y0LIeZxiEPiUqrOxA+SOmEdSCKjlehi hq+64xyIatKjPMWIK77Hh/rywef10beV NzWngBAx6lCKKj0jQJZn8Q==
+SECTION ADDITIONAL
+ns.iinfo.cz. 3600 IN A 91.213.160.5
+ns.iinfo.cz. 3600 IN AAAA 2001:67c:68::5
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR RD NOERROR
+SECTION QUESTION
+iinfo.cz. IN DNSKEY
+SECTION AUTHORITY
+iinfo.cz. 3600 IN DS 21523 5 2 1f3ad3f9eace2aacf2cca9464e6642fe4bafce5a2817da25faef31e59c1fb74e
+iinfo.cz. 3600 IN NS ns.iinfo.cz.
+iinfo.cz. 3600 IN NS ns6.adminit.cz.
+iinfo.cz. 3600 IN RRSIG DS 13 2 3600 20180809121603 20180727063545 62295 cz. 7Y0LIeZxiEPiUqrOxA+SOmEdSCKjlehi hq+64xyIatKjPMWIK77Hh/rywef10beV NzWngBAx6lCKKj0jQJZn8Q==
+SECTION ADDITIONAL
+ns.iinfo.cz. 3600 IN A 91.213.160.5
+ns.iinfo.cz. 3600 IN AAAA 2001:67c:68::5
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+iinfo.cz. IN DS
+SECTION ANSWER
+iinfo.cz. 3600 IN DS 21523 5 2 1f3ad3f9eace2aacf2cca9464e6642fe4bafce5a2817da25faef31e59c1fb74e
+iinfo.cz. 3600 IN RRSIG DS 13 2 3600 20180809121603 20180727063545 62295 cz. 7Y0LIeZxiEPiUqrOxA+SOmEdSCKjlehi hq+64xyIatKjPMWIK77Hh/rywef10beV NzWngBAx6lCKKj0jQJZn8Q==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR RD NOERROR
+SECTION QUESTION
+root.cz. IN A
+SECTION AUTHORITY
+root.cz. 3600 IN DS 21523 5 2 b73053df8858181e1940ee6160e75d5339103264b9e56a9a1ecd64adabb2e54f
+root.cz. 3600 IN NS ns.iinfo.cz.
+root.cz. 3600 IN NS ns6.adminit.cz.
+root.cz. 3600 IN RRSIG DS 13 2 3600 20180809020236 20180727093611 62295 cz. vQCM/GJGJky3kC1IcQZpFddgl0iTTvzq EPV6FPEttgS59K3TnAd9jHKqQrXi7cEW yQ8eO7k27czWZ1UyA4wM2g==
+SECTION ADDITIONAL
+ns.iinfo.cz. 3600 IN A 91.213.160.5
+ns.iinfo.cz. 3600 IN AAAA 2001:67c:68::5
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+nic.cz. IN A
+SECTION ANSWER
+nic.cz. 1800 IN A 217.31.205.50
+nic.cz. 1800 IN RRSIG A 13 2 1800 20180809122156 20180727064002 33494 nic.cz. p0uxXNMUIA1Zf6x/wqAdlNTSiLKrYs8P nNYlBe0SPQ8kTSGp49BlEaiy+B9ewcYp YbPTgjIpmvoMFeIOShUqgw==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+nic.cz. IN DNSKEY
+SECTION ANSWER
+nic.cz. 1800 IN DNSKEY 256 3 13 a10sJr/8DQL8M1nLPzWfNoASGTsm4cKE P577ZX3c3lruiWZiUL78fUp0B2YJh8U9 DyiZsq18i6CM9eYTDVemzA==
+nic.cz. 1800 IN DNSKEY 257 3 13 LM4zvjUgZi2XZKsYooDE0HFYGfWp242f KB+O8sLsuox8S6MJTowY8lBDjZD7JKbm aNot3+1H8zU9TrDzWmmHwQ==
+nic.cz. 1800 IN RRSIG DNSKEY 13 2 1800 20180809084714 20180727064002 61281 nic.cz. zotLLX9vPojjz21OSVfMGNspvWIVzzcW ZGJTTYOPlIHmrxAfE3GxHqV7QK8QO1W5 8rGsf9eebQw3+aJ+QGaNSA==
+nic.cz. 1800 IN RRSIG DNSKEY 13 2 1800 20180810022459 20180727064002 33494 nic.cz. Ol85KlI1HVLYmVRmD2q0QBCqLZM5bUDr sECC2XN0gmtkbEPfI1HmhylvM9sur3kE 4kCxCKOAOCozExhDZtgV2w==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+nic.cz. IN DS
+SECTION ANSWER
+nic.cz. 3600 IN DS 61281 13 2 4104d40c8fe2030bf7a09a199fcf37b36f7ec8ddd16f5a84f2e61c248d3afd0f
+nic.cz. 3600 IN RRSIG DS 13 2 3600 20180805030735 20180722073550 62295 cz. iF+/iu01Jx4ls0md5OHm25GHCuaLkEmd U4N8pzQRw0WYTmP71ZuMEqd4e5KPeGS2 hLqh134rBssNSGagGazLNw==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+ns.nic.cz. IN A
+SECTION AUTHORITY
+7D87LCRPK6RT27KALH4SQT2RUREKMMTI.nic.cz. 7200 IN NSEC3 1 0 10 6d024fda550cdd61 7dios8rb1rae9ugm9mubblifgm1pdql0
+7D87LCRPK6RT27KALH4SQT2RUREKMMTI.nic.cz. 7200 IN RRSIG NSEC3 13 3 7200 20180809215742 20180727064002 33494 nic.cz. rGSwaAjCkz0BBxXgIv+Aq1rq/0gAnxkr Kx+eOR6h0iJDuUKoOogBdCD/XbNihwEr 3RjU+GlaxFjDVqb59fPE4g==
+nic.cz. 1800 IN RRSIG SOA 13 2 1800 20180809064029 20180727064002 33494 nic.cz. fErlGowdWxs4Fouw84ToJt02qqX+qnY+ ieVzHu+w01jj0z3tMK8uLid0G04ZRLA2 CHnO0NKCAPfRVX+K5X+yFQ==
+nic.cz. 1800 IN SOA a.ns.nic.cz. hostmaster.nic.cz. 1532677202 10800 3600 1209600 7200
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+ns.nic.cz. IN DNSKEY
+SECTION AUTHORITY
+7d87lcrpk6rt27kalh4sqt2rurekmmti.nic.cz. 7200 IN NSEC3 1 0 10 6d024fda550cdd61 7dios8rb1rae9ugm9mubblifgm1pdql0
+7d87lcrpk6rt27kalh4sqt2rurekmmti.nic.cz. 7200 IN RRSIG NSEC3 13 3 7200 20180809215742 20180727064002 33494 nic.cz. rGSwaAjCkz0BBxXgIv+Aq1rq/0gAnxkr Kx+eOR6h0iJDuUKoOogBdCD/XbNihwEr 3RjU+GlaxFjDVqb59fPE4g==
+nic.cz. 1800 IN RRSIG SOA 13 2 1800 20180809064029 20180727064002 33494 nic.cz. fErlGowdWxs4Fouw84ToJt02qqX+qnY+ ieVzHu+w01jj0z3tMK8uLid0G04ZRLA2 CHnO0NKCAPfRVX+K5X+yFQ==
+nic.cz. 1800 IN SOA a.ns.nic.cz. hostmaster.nic.cz. 1532677202 10800 3600 1209600 7200
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+ns.nic.cz. IN NS
+SECTION AUTHORITY
+7D87LCRPK6RT27KALH4SQT2RUREKMMTI.nic.cz. 7200 IN NSEC3 1 0 10 6d024fda550cdd61 7dios8rb1rae9ugm9mubblifgm1pdql0
+7D87LCRPK6RT27KALH4SQT2RUREKMMTI.nic.cz. 7200 IN RRSIG NSEC3 13 3 7200 20180809215742 20180727064002 33494 nic.cz. rGSwaAjCkz0BBxXgIv+Aq1rq/0gAnxkr Kx+eOR6h0iJDuUKoOogBdCD/XbNihwEr 3RjU+GlaxFjDVqb59fPE4g==
+nic.cz. 1800 IN RRSIG SOA 13 2 1800 20180809064029 20180727064002 33494 nic.cz. fErlGowdWxs4Fouw84ToJt02qqX+qnY+ ieVzHu+w01jj0z3tMK8uLid0G04ZRLA2 CHnO0NKCAPfRVX+K5X+yFQ==
+nic.cz. 1800 IN SOA a.ns.nic.cz. hostmaster.nic.cz. 1532677202 10800 3600 1209600 7200
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+ns.nic.cz. IN DS
+SECTION AUTHORITY
+7D87LCRPK6RT27KALH4SQT2RUREKMMTI.nic.cz. 7200 IN NSEC3 1 0 10 6d024fda550cdd61 7dios8rb1rae9ugm9mubblifgm1pdql0
+7D87LCRPK6RT27KALH4SQT2RUREKMMTI.nic.cz. 7200 IN RRSIG NSEC3 13 3 7200 20180809215742 20180727064002 33494 nic.cz. rGSwaAjCkz0BBxXgIv+Aq1rq/0gAnxkr Kx+eOR6h0iJDuUKoOogBdCD/XbNihwEr 3RjU+GlaxFjDVqb59fPE4g==
+nic.cz. 1800 IN RRSIG SOA 13 2 1800 20180809064029 20180727064002 33494 nic.cz. fErlGowdWxs4Fouw84ToJt02qqX+qnY+ ieVzHu+w01jj0z3tMK8uLid0G04ZRLA2 CHnO0NKCAPfRVX+K5X+yFQ==
+nic.cz. 1800 IN SOA a.ns.nic.cz. hostmaster.nic.cz. 1532677202 10800 3600 1209600 7200
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+a.ns.nic.cz. IN A
+SECTION ANSWER
+a.ns.nic.cz. 1800 IN A 194.0.12.1
+a.ns.nic.cz. 1800 IN RRSIG A 13 4 1800 20180810011809 20180727064002 33494 nic.cz. dlRCgD1PxXFCid2m1djf5URx+SbMMFtR aaeNB5G7jj9nqFv252cwhnOz7NLPqEBG yr+h8eEOqFKbV92ZfzygLw==
+SECTION AUTHORITY
+nic.cz. 1800 IN NS a.ns.nic.cz.
+nic.cz. 1800 IN NS b.ns.nic.cz.
+nic.cz. 1800 IN NS d.ns.nic.cz.
+nic.cz. 1800 IN RRSIG NS 13 2 1800 20180809162254 20180727064002 33494 nic.cz. UOY4VdLFGrtMr22EaYes+1lbCAjFkhlt N5Q+0jpGucbyEFXrbxN4lFoQGpkX/+aU IWuKxWQI8VVmBKYLFBqSTw==
+SECTION ADDITIONAL
+a.ns.nic.cz. 1800 IN AAAA 2001:678:f::1
+a.ns.nic.cz. 1800 IN RRSIG AAAA 13 4 1800 20180809213334 20180727064002 33494 nic.cz. TQvt6opeQKp4V/VTYgEsw25AFAD3l9I6 UE5HhJUVGpnn8YzmZZs1QTNC1ZVf0MCs Flr3H2mTNm0r/Mb3m6Q+Yw==
+b.ns.nic.cz. 1800 IN A 194.0.13.1
+b.ns.nic.cz. 1800 IN AAAA 2001:678:10::1
+b.ns.nic.cz. 1800 IN RRSIG A 13 4 1800 20180809112828 20180727064002 33494 nic.cz. GO5Wc2EWoV4yRvc3ktazw+lNZ7nGtR6S 4MsumQDKuADSGMLAhwm+htASUXxWZtV+ wWv74LD2g2cNjHpXHH1PBg==
+b.ns.nic.cz. 1800 IN RRSIG AAAA 13 4 1800 20180809130835 20180727064002 33494 nic.cz. sesuNekVgD2YLYl51sKLEYZeDmcxtQKl oFYnpXMUBVlqLTUGjn0RRcDvpJCxj/Ac isifFcEwvZ4W0B5/Ry1oVQ==
+d.ns.nic.cz. 1800 IN A 193.29.206.1
+d.ns.nic.cz. 1800 IN AAAA 2001:678:1::1
+d.ns.nic.cz. 1800 IN RRSIG A 13 4 1800 20180809211641 20180727064002 33494 nic.cz. yLSqZnGG2G5+StFxEPpuV3I5slNKLF3o 7QahlX4mKk/iN74C7zh62cR+Q/s3SDxE fFF2M/owNT3T2wspOh4L/g==
+d.ns.nic.cz. 1800 IN RRSIG AAAA 13 4 1800 20180809225253 20180727064002 33494 nic.cz. Rm0kQ0l//ZsEDNi1M3Hmns4C2aWzcGI/ oUBN92egsGSvQ0EGVgZMWZp/Pun+Tgr/ AHHCsD4lW8ZNNxHh5CCtZQ==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+a.ns.nic.cz. IN DNSKEY
+SECTION AUTHORITY
+0peaur41j22dbmn7u135fq4ftaucujhf.nic.cz. 7200 IN NSEC3 1 0 10 6d024fda550cdd61 0pr0tt6lsanr7gh1a7b43qfgll0ce3m7 A AAAA RRSIG
+0peaur41j22dbmn7u135fq4ftaucujhf.nic.cz. 7200 IN RRSIG NSEC3 13 3 7200 20180809114457 20180727064002 33494 nic.cz. JVwfhA8YvpMShhq+ZkjOjPwGTwqw0U+7 vgK0Dt+RaW9KhFydcmohq0YLO207c0Sm UnYvWvDBSu+PHAOSL+Hgkw==
+nic.cz. 1800 IN RRSIG SOA 13 2 1800 20180809064029 20180727064002 33494 nic.cz. fErlGowdWxs4Fouw84ToJt02qqX+qnY+ ieVzHu+w01jj0z3tMK8uLid0G04ZRLA2 CHnO0NKCAPfRVX+K5X+yFQ==
+nic.cz. 1800 IN SOA a.ns.nic.cz. hostmaster.nic.cz. 1532677202 10800 3600 1209600 7200
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+a.ns.nic.cz. IN NS
+SECTION AUTHORITY
+0PEAUR41J22DBMN7U135FQ4FTAUCUJHF.nic.cz. 7200 IN NSEC3 1 0 10 6d024fda550cdd61 0pr0tt6lsanr7gh1a7b43qfgll0ce3m7 A AAAA RRSIG
+0PEAUR41J22DBMN7U135FQ4FTAUCUJHF.nic.cz. 7200 IN RRSIG NSEC3 13 3 7200 20180809114457 20180727064002 33494 nic.cz. JVwfhA8YvpMShhq+ZkjOjPwGTwqw0U+7 vgK0Dt+RaW9KhFydcmohq0YLO207c0Sm UnYvWvDBSu+PHAOSL+Hgkw==
+nic.cz. 1800 IN RRSIG SOA 13 2 1800 20180809064029 20180727064002 33494 nic.cz. fErlGowdWxs4Fouw84ToJt02qqX+qnY+ ieVzHu+w01jj0z3tMK8uLid0G04ZRLA2 CHnO0NKCAPfRVX+K5X+yFQ==
+nic.cz. 1800 IN SOA a.ns.nic.cz. hostmaster.nic.cz. 1532677202 10800 3600 1209600 7200
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+a.ns.nic.cz. IN DS
+SECTION AUTHORITY
+0peaur41j22dbmn7u135fq4ftaucujhf.nic.cz. 7200 IN NSEC3 1 0 10 6d024fda550cdd61 0pr0tt6lsanr7gh1a7b43qfgll0ce3m7 A AAAA RRSIG
+0peaur41j22dbmn7u135fq4ftaucujhf.nic.cz. 7200 IN RRSIG NSEC3 13 3 7200 20180809114457 20180727064002 33494 nic.cz. JVwfhA8YvpMShhq+ZkjOjPwGTwqw0U+7 vgK0Dt+RaW9KhFydcmohq0YLO207c0Sm UnYvWvDBSu+PHAOSL+Hgkw==
+nic.cz. 1800 IN RRSIG SOA 13 2 1800 20180809064029 20180727064002 33494 nic.cz. fErlGowdWxs4Fouw84ToJt02qqX+qnY+ ieVzHu+w01jj0z3tMK8uLid0G04ZRLA2 CHnO0NKCAPfRVX+K5X+yFQ==
+nic.cz. 1800 IN SOA a.ns.nic.cz. hostmaster.nic.cz. 1532677202 10800 3600 1209600 7200
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+a.ns.nic.cz. IN AAAA
+SECTION ANSWER
+a.ns.nic.cz. 1800 IN AAAA 2001:678:f::1
+a.ns.nic.cz. 1800 IN RRSIG AAAA 13 4 1800 20180809213334 20180727064002 33494 nic.cz. TQvt6opeQKp4V/VTYgEsw25AFAD3l9I6 UE5HhJUVGpnn8YzmZZs1QTNC1ZVf0MCs Flr3H2mTNm0r/Mb3m6Q+Yw==
+SECTION AUTHORITY
+nic.cz. 1800 IN NS a.ns.nic.cz.
+nic.cz. 1800 IN NS b.ns.nic.cz.
+nic.cz. 1800 IN NS d.ns.nic.cz.
+nic.cz. 1800 IN RRSIG NS 13 2 1800 20180809162254 20180727064002 33494 nic.cz. UOY4VdLFGrtMr22EaYes+1lbCAjFkhlt N5Q+0jpGucbyEFXrbxN4lFoQGpkX/+aU IWuKxWQI8VVmBKYLFBqSTw==
+SECTION ADDITIONAL
+a.ns.nic.cz. 1800 IN A 194.0.12.1
+a.ns.nic.cz. 1800 IN RRSIG A 13 4 1800 20180810011809 20180727064002 33494 nic.cz. dlRCgD1PxXFCid2m1djf5URx+SbMMFtR aaeNB5G7jj9nqFv252cwhnOz7NLPqEBG yr+h8eEOqFKbV92ZfzygLw==
+b.ns.nic.cz. 1800 IN A 194.0.13.1
+b.ns.nic.cz. 1800 IN AAAA 2001:678:10::1
+b.ns.nic.cz. 1800 IN RRSIG A 13 4 1800 20180809112828 20180727064002 33494 nic.cz. GO5Wc2EWoV4yRvc3ktazw+lNZ7nGtR6S 4MsumQDKuADSGMLAhwm+htASUXxWZtV+ wWv74LD2g2cNjHpXHH1PBg==
+b.ns.nic.cz. 1800 IN RRSIG AAAA 13 4 1800 20180809130835 20180727064002 33494 nic.cz. sesuNekVgD2YLYl51sKLEYZeDmcxtQKl oFYnpXMUBVlqLTUGjn0RRcDvpJCxj/Ac isifFcEwvZ4W0B5/Ry1oVQ==
+d.ns.nic.cz. 1800 IN A 193.29.206.1
+d.ns.nic.cz. 1800 IN AAAA 2001:678:1::1
+d.ns.nic.cz. 1800 IN RRSIG A 13 4 1800 20180809211641 20180727064002 33494 nic.cz. yLSqZnGG2G5+StFxEPpuV3I5slNKLF3o 7QahlX4mKk/iN74C7zh62cR+Q/s3SDxE fFF2M/owNT3T2wspOh4L/g==
+d.ns.nic.cz. 1800 IN RRSIG AAAA 13 4 1800 20180809225253 20180727064002 33494 nic.cz. Rm0kQ0l//ZsEDNi1M3Hmns4C2aWzcGI/ oUBN92egsGSvQ0EGVgZMWZp/Pun+Tgr/ AHHCsD4lW8ZNNxHh5CCtZQ==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+b.ns.nic.cz. IN A
+SECTION ANSWER
+b.ns.nic.cz. 1800 IN A 194.0.13.1
+b.ns.nic.cz. 1800 IN RRSIG A 13 4 1800 20180809112828 20180727064002 33494 nic.cz. GO5Wc2EWoV4yRvc3ktazw+lNZ7nGtR6S 4MsumQDKuADSGMLAhwm+htASUXxWZtV+ wWv74LD2g2cNjHpXHH1PBg==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+b.ns.nic.cz. IN DNSKEY
+SECTION AUTHORITY
+QO01QT0TH20IVKDANQ04F4G7V2EAJ3UR.nic.cz. 7200 IN NSEC3 1 0 10 6d024fda550cdd61 qrn61qbmo7ba8fufp4f15q8v233rd7s1 A AAAA RRSIG
+QO01QT0TH20IVKDANQ04F4G7V2EAJ3UR.nic.cz. 7200 IN RRSIG NSEC3 13 3 7200 20180810053445 20180727064002 33494 nic.cz. NPU0frxy34iY0tCv3Kvgew+zKlulbVF9 4y1Ml0ohKTr659CYBmX0y0C9Kt9vBfzz oDoYnIslWIwouM+u7186yw==
+nic.cz. 1800 IN RRSIG SOA 13 2 1800 20180809064029 20180727064002 33494 nic.cz. fErlGowdWxs4Fouw84ToJt02qqX+qnY+ ieVzHu+w01jj0z3tMK8uLid0G04ZRLA2 CHnO0NKCAPfRVX+K5X+yFQ==
+nic.cz. 1800 IN SOA a.ns.nic.cz. hostmaster.nic.cz. 1532677202 10800 3600 1209600 7200
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+b.ns.nic.cz. IN NS
+SECTION AUTHORITY
+nic.cz. 1800 IN RRSIG SOA 13 2 1800 20180809064029 20180727064002 33494 nic.cz. fErlGowdWxs4Fouw84ToJt02qqX+qnY+ ieVzHu+w01jj0z3tMK8uLid0G04ZRLA2 CHnO0NKCAPfRVX+K5X+yFQ==
+nic.cz. 1800 IN SOA a.ns.nic.cz. hostmaster.nic.cz. 1532677202 10800 3600 1209600 7200
+qo01qt0th20ivkdanq04f4g7v2eaj3ur.nic.cz. 7200 IN NSEC3 1 0 10 6d024fda550cdd61 qrn61qbmo7ba8fufp4f15q8v233rd7s1 A AAAA RRSIG
+qo01qt0th20ivkdanq04f4g7v2eaj3ur.nic.cz. 7200 IN RRSIG NSEC3 13 3 7200 20180810053445 20180727064002 33494 nic.cz. NPU0frxy34iY0tCv3Kvgew+zKlulbVF9 4y1Ml0ohKTr659CYBmX0y0C9Kt9vBfzz oDoYnIslWIwouM+u7186yw==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+b.ns.nic.cz. IN DS
+SECTION AUTHORITY
+QO01QT0TH20IVKDANQ04F4G7V2EAJ3UR.nic.cz. 7200 IN NSEC3 1 0 10 6d024fda550cdd61 qrn61qbmo7ba8fufp4f15q8v233rd7s1 A AAAA RRSIG
+QO01QT0TH20IVKDANQ04F4G7V2EAJ3UR.nic.cz. 7200 IN RRSIG NSEC3 13 3 7200 20180810053445 20180727064002 33494 nic.cz. NPU0frxy34iY0tCv3Kvgew+zKlulbVF9 4y1Ml0ohKTr659CYBmX0y0C9Kt9vBfzz oDoYnIslWIwouM+u7186yw==
+nic.cz. 1800 IN RRSIG SOA 13 2 1800 20180809064029 20180727064002 33494 nic.cz. fErlGowdWxs4Fouw84ToJt02qqX+qnY+ ieVzHu+w01jj0z3tMK8uLid0G04ZRLA2 CHnO0NKCAPfRVX+K5X+yFQ==
+nic.cz. 1800 IN SOA a.ns.nic.cz. hostmaster.nic.cz. 1532677202 10800 3600 1209600 7200
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+b.ns.nic.cz. IN AAAA
+SECTION ANSWER
+b.ns.nic.cz. 1800 IN AAAA 2001:678:10::1
+b.ns.nic.cz. 1800 IN RRSIG AAAA 13 4 1800 20180809130835 20180727064002 33494 nic.cz. sesuNekVgD2YLYl51sKLEYZeDmcxtQKl oFYnpXMUBVlqLTUGjn0RRcDvpJCxj/Ac isifFcEwvZ4W0B5/Ry1oVQ==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+c.ns.nic.cz. IN A
+SECTION ANSWER
+c.ns.nic.cz. 1800 IN A 194.0.14.1
+c.ns.nic.cz. 1800 IN RRSIG A 13 4 1800 20180809230245 20180727064002 33494 nic.cz. vlIESyKHWExpovMlpGstO7X8Qk1YnJYc w8i6u28JjABo/2qa20s3wFXVgenziyEn 3VTsenqk6TTTi8RutaSmhA==
+SECTION AUTHORITY
+nic.cz. 1800 IN NS a.ns.nic.cz.
+nic.cz. 1800 IN NS b.ns.nic.cz.
+nic.cz. 1800 IN NS d.ns.nic.cz.
+nic.cz. 1800 IN RRSIG NS 13 2 1800 20180809162254 20180727064002 33494 nic.cz. UOY4VdLFGrtMr22EaYes+1lbCAjFkhlt N5Q+0jpGucbyEFXrbxN4lFoQGpkX/+aU IWuKxWQI8VVmBKYLFBqSTw==
+SECTION ADDITIONAL
+a.ns.nic.cz. 1800 IN A 194.0.12.1
+a.ns.nic.cz. 1800 IN AAAA 2001:678:f::1
+a.ns.nic.cz. 1800 IN RRSIG A 13 4 1800 20180810011809 20180727064002 33494 nic.cz. dlRCgD1PxXFCid2m1djf5URx+SbMMFtR aaeNB5G7jj9nqFv252cwhnOz7NLPqEBG yr+h8eEOqFKbV92ZfzygLw==
+a.ns.nic.cz. 1800 IN RRSIG AAAA 13 4 1800 20180809213334 20180727064002 33494 nic.cz. TQvt6opeQKp4V/VTYgEsw25AFAD3l9I6 UE5HhJUVGpnn8YzmZZs1QTNC1ZVf0MCs Flr3H2mTNm0r/Mb3m6Q+Yw==
+b.ns.nic.cz. 1800 IN A 194.0.13.1
+b.ns.nic.cz. 1800 IN AAAA 2001:678:10::1
+b.ns.nic.cz. 1800 IN RRSIG A 13 4 1800 20180809112828 20180727064002 33494 nic.cz. GO5Wc2EWoV4yRvc3ktazw+lNZ7nGtR6S 4MsumQDKuADSGMLAhwm+htASUXxWZtV+ wWv74LD2g2cNjHpXHH1PBg==
+b.ns.nic.cz. 1800 IN RRSIG AAAA 13 4 1800 20180809130835 20180727064002 33494 nic.cz. sesuNekVgD2YLYl51sKLEYZeDmcxtQKl oFYnpXMUBVlqLTUGjn0RRcDvpJCxj/Ac isifFcEwvZ4W0B5/Ry1oVQ==
+d.ns.nic.cz. 1800 IN A 193.29.206.1
+d.ns.nic.cz. 1800 IN AAAA 2001:678:1::1
+d.ns.nic.cz. 1800 IN RRSIG A 13 4 1800 20180809211641 20180727064002 33494 nic.cz. yLSqZnGG2G5+StFxEPpuV3I5slNKLF3o 7QahlX4mKk/iN74C7zh62cR+Q/s3SDxE fFF2M/owNT3T2wspOh4L/g==
+d.ns.nic.cz. 1800 IN RRSIG AAAA 13 4 1800 20180809225253 20180727064002 33494 nic.cz. Rm0kQ0l//ZsEDNi1M3Hmns4C2aWzcGI/ oUBN92egsGSvQ0EGVgZMWZp/Pun+Tgr/ AHHCsD4lW8ZNNxHh5CCtZQ==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+c.ns.nic.cz. IN DNSKEY
+SECTION AUTHORITY
+ccueinlfu0s4ji2bgsprv30rcletotkq.nic.cz. 7200 IN NSEC3 1 0 10 6d024fda550cdd61 cem50d1dfrtnfqk2gdjo4405j9lvostb A AAAA RRSIG
+ccueinlfu0s4ji2bgsprv30rcletotkq.nic.cz. 7200 IN RRSIG NSEC3 13 3 7200 20180809155831 20180727064002 33494 nic.cz. 9kekS/gKCcN1h0h5JhWV+r+tq9p0RpY4 QXT8aVrcxaD0LbXR+tGc8laMcdxOmrbd kXCxuSt6FVPmueKlCZj1Kw==
+nic.cz. 1800 IN RRSIG SOA 13 2 1800 20180809064029 20180727064002 33494 nic.cz. fErlGowdWxs4Fouw84ToJt02qqX+qnY+ ieVzHu+w01jj0z3tMK8uLid0G04ZRLA2 CHnO0NKCAPfRVX+K5X+yFQ==
+nic.cz. 1800 IN SOA a.ns.nic.cz. hostmaster.nic.cz. 1532677202 10800 3600 1209600 7200
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+c.ns.nic.cz. IN NS
+SECTION AUTHORITY
+CCUEINLFU0S4JI2BGSPRV30RCLETOTKQ.nic.cz. 7200 IN NSEC3 1 0 10 6d024fda550cdd61 cem50d1dfrtnfqk2gdjo4405j9lvostb A AAAA RRSIG
+CCUEINLFU0S4JI2BGSPRV30RCLETOTKQ.nic.cz. 7200 IN RRSIG NSEC3 13 3 7200 20180809155831 20180727064002 33494 nic.cz. 9kekS/gKCcN1h0h5JhWV+r+tq9p0RpY4 QXT8aVrcxaD0LbXR+tGc8laMcdxOmrbd kXCxuSt6FVPmueKlCZj1Kw==
+nic.cz. 1800 IN RRSIG SOA 13 2 1800 20180809064029 20180727064002 33494 nic.cz. fErlGowdWxs4Fouw84ToJt02qqX+qnY+ ieVzHu+w01jj0z3tMK8uLid0G04ZRLA2 CHnO0NKCAPfRVX+K5X+yFQ==
+nic.cz. 1800 IN SOA a.ns.nic.cz. hostmaster.nic.cz. 1532677202 10800 3600 1209600 7200
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+c.ns.nic.cz. IN DS
+SECTION AUTHORITY
+CCUEINLFU0S4JI2BGSPRV30RCLETOTKQ.nic.cz. 7200 IN NSEC3 1 0 10 6d024fda550cdd61 cem50d1dfrtnfqk2gdjo4405j9lvostb A AAAA RRSIG
+CCUEINLFU0S4JI2BGSPRV30RCLETOTKQ.nic.cz. 7200 IN RRSIG NSEC3 13 3 7200 20180809155831 20180727064002 33494 nic.cz. 9kekS/gKCcN1h0h5JhWV+r+tq9p0RpY4 QXT8aVrcxaD0LbXR+tGc8laMcdxOmrbd kXCxuSt6FVPmueKlCZj1Kw==
+nic.cz. 1800 IN RRSIG SOA 13 2 1800 20180809064029 20180727064002 33494 nic.cz. fErlGowdWxs4Fouw84ToJt02qqX+qnY+ ieVzHu+w01jj0z3tMK8uLid0G04ZRLA2 CHnO0NKCAPfRVX+K5X+yFQ==
+nic.cz. 1800 IN SOA a.ns.nic.cz. hostmaster.nic.cz. 1532677202 10800 3600 1209600 7200
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+c.ns.nic.cz. IN AAAA
+SECTION ANSWER
+c.ns.nic.cz. 1800 IN AAAA 2001:678:11::1
+c.ns.nic.cz. 1800 IN RRSIG AAAA 13 4 1800 20180809162728 20180727064002 33494 nic.cz. QRpoOGOlRV5YZkfr8rvOdGVZDqaFY4hV WsjpEl2cB1A9Rkw9/aX2toXhBoHTD7SX djgg2xiJzfNqtbBZNcpCrw==
+SECTION AUTHORITY
+nic.cz. 1800 IN NS a.ns.nic.cz.
+nic.cz. 1800 IN NS b.ns.nic.cz.
+nic.cz. 1800 IN NS d.ns.nic.cz.
+nic.cz. 1800 IN RRSIG NS 13 2 1800 20180809162254 20180727064002 33494 nic.cz. UOY4VdLFGrtMr22EaYes+1lbCAjFkhlt N5Q+0jpGucbyEFXrbxN4lFoQGpkX/+aU IWuKxWQI8VVmBKYLFBqSTw==
+SECTION ADDITIONAL
+a.ns.nic.cz. 1800 IN A 194.0.12.1
+a.ns.nic.cz. 1800 IN AAAA 2001:678:f::1
+a.ns.nic.cz. 1800 IN RRSIG A 13 4 1800 20180810011809 20180727064002 33494 nic.cz. dlRCgD1PxXFCid2m1djf5URx+SbMMFtR aaeNB5G7jj9nqFv252cwhnOz7NLPqEBG yr+h8eEOqFKbV92ZfzygLw==
+a.ns.nic.cz. 1800 IN RRSIG AAAA 13 4 1800 20180809213334 20180727064002 33494 nic.cz. TQvt6opeQKp4V/VTYgEsw25AFAD3l9I6 UE5HhJUVGpnn8YzmZZs1QTNC1ZVf0MCs Flr3H2mTNm0r/Mb3m6Q+Yw==
+b.ns.nic.cz. 1800 IN A 194.0.13.1
+b.ns.nic.cz. 1800 IN AAAA 2001:678:10::1
+b.ns.nic.cz. 1800 IN RRSIG A 13 4 1800 20180809112828 20180727064002 33494 nic.cz. GO5Wc2EWoV4yRvc3ktazw+lNZ7nGtR6S 4MsumQDKuADSGMLAhwm+htASUXxWZtV+ wWv74LD2g2cNjHpXHH1PBg==
+b.ns.nic.cz. 1800 IN RRSIG AAAA 13 4 1800 20180809130835 20180727064002 33494 nic.cz. sesuNekVgD2YLYl51sKLEYZeDmcxtQKl oFYnpXMUBVlqLTUGjn0RRcDvpJCxj/Ac isifFcEwvZ4W0B5/Ry1oVQ==
+d.ns.nic.cz. 1800 IN A 193.29.206.1
+d.ns.nic.cz. 1800 IN AAAA 2001:678:1::1
+d.ns.nic.cz. 1800 IN RRSIG A 13 4 1800 20180809211641 20180727064002 33494 nic.cz. yLSqZnGG2G5+StFxEPpuV3I5slNKLF3o 7QahlX4mKk/iN74C7zh62cR+Q/s3SDxE fFF2M/owNT3T2wspOh4L/g==
+d.ns.nic.cz. 1800 IN RRSIG AAAA 13 4 1800 20180809225253 20180727064002 33494 nic.cz. Rm0kQ0l//ZsEDNi1M3Hmns4C2aWzcGI/ oUBN92egsGSvQ0EGVgZMWZp/Pun+Tgr/ AHHCsD4lW8ZNNxHh5CCtZQ==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+d.ns.nic.cz. IN A
+SECTION ANSWER
+d.ns.nic.cz. 1800 IN A 193.29.206.1
+d.ns.nic.cz. 1800 IN RRSIG A 13 4 1800 20180809211641 20180727064002 33494 nic.cz. yLSqZnGG2G5+StFxEPpuV3I5slNKLF3o 7QahlX4mKk/iN74C7zh62cR+Q/s3SDxE fFF2M/owNT3T2wspOh4L/g==
+SECTION AUTHORITY
+nic.cz. 1800 IN NS a.ns.nic.cz.
+nic.cz. 1800 IN NS b.ns.nic.cz.
+nic.cz. 1800 IN NS d.ns.nic.cz.
+nic.cz. 1800 IN RRSIG NS 13 2 1800 20180809162254 20180727064002 33494 nic.cz. UOY4VdLFGrtMr22EaYes+1lbCAjFkhlt N5Q+0jpGucbyEFXrbxN4lFoQGpkX/+aU IWuKxWQI8VVmBKYLFBqSTw==
+SECTION ADDITIONAL
+a.ns.nic.cz. 1800 IN A 194.0.12.1
+a.ns.nic.cz. 1800 IN AAAA 2001:678:f::1
+a.ns.nic.cz. 1800 IN RRSIG A 13 4 1800 20180810011809 20180727064002 33494 nic.cz. dlRCgD1PxXFCid2m1djf5URx+SbMMFtR aaeNB5G7jj9nqFv252cwhnOz7NLPqEBG yr+h8eEOqFKbV92ZfzygLw==
+a.ns.nic.cz. 1800 IN RRSIG AAAA 13 4 1800 20180809213334 20180727064002 33494 nic.cz. TQvt6opeQKp4V/VTYgEsw25AFAD3l9I6 UE5HhJUVGpnn8YzmZZs1QTNC1ZVf0MCs Flr3H2mTNm0r/Mb3m6Q+Yw==
+b.ns.nic.cz. 1800 IN A 194.0.13.1
+b.ns.nic.cz. 1800 IN AAAA 2001:678:10::1
+b.ns.nic.cz. 1800 IN RRSIG A 13 4 1800 20180809112828 20180727064002 33494 nic.cz. GO5Wc2EWoV4yRvc3ktazw+lNZ7nGtR6S 4MsumQDKuADSGMLAhwm+htASUXxWZtV+ wWv74LD2g2cNjHpXHH1PBg==
+b.ns.nic.cz. 1800 IN RRSIG AAAA 13 4 1800 20180809130835 20180727064002 33494 nic.cz. sesuNekVgD2YLYl51sKLEYZeDmcxtQKl oFYnpXMUBVlqLTUGjn0RRcDvpJCxj/Ac isifFcEwvZ4W0B5/Ry1oVQ==
+d.ns.nic.cz. 1800 IN AAAA 2001:678:1::1
+d.ns.nic.cz. 1800 IN RRSIG AAAA 13 4 1800 20180809225253 20180727064002 33494 nic.cz. Rm0kQ0l//ZsEDNi1M3Hmns4C2aWzcGI/ oUBN92egsGSvQ0EGVgZMWZp/Pun+Tgr/ AHHCsD4lW8ZNNxHh5CCtZQ==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+d.ns.nic.cz. IN DNSKEY
+SECTION AUTHORITY
+nic.cz. 1800 IN RRSIG SOA 13 2 1800 20180809064029 20180727064002 33494 nic.cz. fErlGowdWxs4Fouw84ToJt02qqX+qnY+ ieVzHu+w01jj0z3tMK8uLid0G04ZRLA2 CHnO0NKCAPfRVX+K5X+yFQ==
+nic.cz. 1800 IN SOA a.ns.nic.cz. hostmaster.nic.cz. 1532677202 10800 3600 1209600 7200
+vf5fp77trrd78patqgiavtggum6cajh9.nic.cz. 7200 IN NSEC3 1 0 10 6d024fda550cdd61 vg8e7aak4v5n8qc7q065is15lgndiok5 A AAAA RRSIG
+vf5fp77trrd78patqgiavtggum6cajh9.nic.cz. 7200 IN RRSIG NSEC3 13 3 7200 20180809144711 20180727064002 33494 nic.cz. qGRXKiwS8f+uEggVDFRUqt27euEuDV+T 2rrwkPqlCXvHiaKYI/P0eTkHe2SamKZT Fe2nbLIeuppDRzKo9DPx+g==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+d.ns.nic.cz. IN NS
+SECTION AUTHORITY
+VF5FP77TRRD78PATQGIAVTGGUM6CAJH9.nic.cz. 7200 IN NSEC3 1 0 10 6d024fda550cdd61 vg8e7aak4v5n8qc7q065is15lgndiok5 A AAAA RRSIG
+VF5FP77TRRD78PATQGIAVTGGUM6CAJH9.nic.cz. 7200 IN RRSIG NSEC3 13 3 7200 20180809144711 20180727064002 33494 nic.cz. qGRXKiwS8f+uEggVDFRUqt27euEuDV+T 2rrwkPqlCXvHiaKYI/P0eTkHe2SamKZT Fe2nbLIeuppDRzKo9DPx+g==
+nic.cz. 1800 IN RRSIG SOA 13 2 1800 20180809064029 20180727064002 33494 nic.cz. fErlGowdWxs4Fouw84ToJt02qqX+qnY+ ieVzHu+w01jj0z3tMK8uLid0G04ZRLA2 CHnO0NKCAPfRVX+K5X+yFQ==
+nic.cz. 1800 IN SOA a.ns.nic.cz. hostmaster.nic.cz. 1532677202 10800 3600 1209600 7200
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+d.ns.nic.cz. IN DS
+SECTION AUTHORITY
+nic.cz. 1800 IN RRSIG SOA 13 2 1800 20180809064029 20180727064002 33494 nic.cz. fErlGowdWxs4Fouw84ToJt02qqX+qnY+ ieVzHu+w01jj0z3tMK8uLid0G04ZRLA2 CHnO0NKCAPfRVX+K5X+yFQ==
+nic.cz. 1800 IN SOA a.ns.nic.cz. hostmaster.nic.cz. 1532677202 10800 3600 1209600 7200
+vf5fp77trrd78patqgiavtggum6cajh9.nic.cz. 7200 IN NSEC3 1 0 10 6d024fda550cdd61 vg8e7aak4v5n8qc7q065is15lgndiok5 A AAAA RRSIG
+vf5fp77trrd78patqgiavtggum6cajh9.nic.cz. 7200 IN RRSIG NSEC3 13 3 7200 20180809144711 20180727064002 33494 nic.cz. qGRXKiwS8f+uEggVDFRUqt27euEuDV+T 2rrwkPqlCXvHiaKYI/P0eTkHe2SamKZT Fe2nbLIeuppDRzKo9DPx+g==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+d.ns.nic.cz. IN AAAA
+SECTION ANSWER
+d.ns.nic.cz. 1800 IN AAAA 2001:678:1::1
+d.ns.nic.cz. 1800 IN RRSIG AAAA 13 4 1800 20180809225253 20180727064002 33494 nic.cz. Rm0kQ0l//ZsEDNi1M3Hmns4C2aWzcGI/ oUBN92egsGSvQ0EGVgZMWZp/Pun+Tgr/ AHHCsD4lW8ZNNxHh5CCtZQ==
+SECTION AUTHORITY
+nic.cz. 1800 IN NS a.ns.nic.cz.
+nic.cz. 1800 IN NS b.ns.nic.cz.
+nic.cz. 1800 IN NS d.ns.nic.cz.
+nic.cz. 1800 IN RRSIG NS 13 2 1800 20180809162254 20180727064002 33494 nic.cz. UOY4VdLFGrtMr22EaYes+1lbCAjFkhlt N5Q+0jpGucbyEFXrbxN4lFoQGpkX/+aU IWuKxWQI8VVmBKYLFBqSTw==
+SECTION ADDITIONAL
+a.ns.nic.cz. 1800 IN A 194.0.12.1
+a.ns.nic.cz. 1800 IN AAAA 2001:678:f::1
+a.ns.nic.cz. 1800 IN RRSIG A 13 4 1800 20180810011809 20180727064002 33494 nic.cz. dlRCgD1PxXFCid2m1djf5URx+SbMMFtR aaeNB5G7jj9nqFv252cwhnOz7NLPqEBG yr+h8eEOqFKbV92ZfzygLw==
+a.ns.nic.cz. 1800 IN RRSIG AAAA 13 4 1800 20180809213334 20180727064002 33494 nic.cz. TQvt6opeQKp4V/VTYgEsw25AFAD3l9I6 UE5HhJUVGpnn8YzmZZs1QTNC1ZVf0MCs Flr3H2mTNm0r/Mb3m6Q+Yw==
+b.ns.nic.cz. 1800 IN A 194.0.13.1
+b.ns.nic.cz. 1800 IN AAAA 2001:678:10::1
+b.ns.nic.cz. 1800 IN RRSIG A 13 4 1800 20180809112828 20180727064002 33494 nic.cz. GO5Wc2EWoV4yRvc3ktazw+lNZ7nGtR6S 4MsumQDKuADSGMLAhwm+htASUXxWZtV+ wWv74LD2g2cNjHpXHH1PBg==
+b.ns.nic.cz. 1800 IN RRSIG AAAA 13 4 1800 20180809130835 20180727064002 33494 nic.cz. sesuNekVgD2YLYl51sKLEYZeDmcxtQKl oFYnpXMUBVlqLTUGjn0RRcDvpJCxj/Ac isifFcEwvZ4W0B5/Ry1oVQ==
+d.ns.nic.cz. 1800 IN A 193.29.206.1
+d.ns.nic.cz. 1800 IN RRSIG A 13 4 1800 20180809211641 20180727064002 33494 nic.cz. yLSqZnGG2G5+StFxEPpuV3I5slNKLF3o 7QahlX4mKk/iN74C7zh62cR+Q/s3SDxE fFF2M/owNT3T2wspOh4L/g==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR RD NOERROR
+SECTION QUESTION
+adminit.cz. IN A
+SECTION AUTHORITY
+9HFKLGVAURTDMCOTLK0NH1NSRJ43DEJE.cz. 900 IN NSEC3 1 0 10 10e824b15ffa0abd 9hfku52m3alurnj3eavfg458gn3418f6 NS
+9HFKLGVAURTDMCOTLK0NH1NSRJ43DEJE.cz. 900 IN RRSIG NSEC3 13 2 900 20180804023913 20180721053541 62295 cz. rJ/nyZPYNwZxgjf7asIyASKmSX+dHt4S nIRGX3ROuIqHp5k9TVkeW0XxAOYgRpAJ Gm1C9gayX3JGikaPZeYXuQ==
+adminit.cz. 3600 IN NS ns.adminit.cz.
+adminit.cz. 3600 IN NS ns.iinfo.cz.
+SECTION ADDITIONAL
+ns.adminit.cz. 3600 IN A 89.185.231.140
+ns.iinfo.cz. 3600 IN A 91.213.160.5
+ns.iinfo.cz. 3600 IN AAAA 2001:67c:68::5
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR RD NOERROR
+SECTION QUESTION
+adminit.cz. IN DNSKEY
+SECTION AUTHORITY
+9HFKLGVAURTDMCOTLK0NH1NSRJ43DEJE.cz. 900 IN NSEC3 1 0 10 10e824b15ffa0abd 9hfku52m3alurnj3eavfg458gn3418f6 NS
+9HFKLGVAURTDMCOTLK0NH1NSRJ43DEJE.cz. 900 IN RRSIG NSEC3 13 2 900 20180804023913 20180721053541 62295 cz. rJ/nyZPYNwZxgjf7asIyASKmSX+dHt4S nIRGX3ROuIqHp5k9TVkeW0XxAOYgRpAJ Gm1C9gayX3JGikaPZeYXuQ==
+adminit.cz. 3600 IN NS ns.adminit.cz.
+adminit.cz. 3600 IN NS ns.iinfo.cz.
+SECTION ADDITIONAL
+ns.adminit.cz. 3600 IN A 89.185.231.140
+ns.iinfo.cz. 3600 IN A 91.213.160.5
+ns.iinfo.cz. 3600 IN AAAA 2001:67c:68::5
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+adminit.cz. IN DS
+SECTION AUTHORITY
+9hfklgvaurtdmcotlk0nh1nsrj43deje.cz. 900 IN NSEC3 1 0 10 10e824b15ffa0abd 9hfku52m3alurnj3eavfg458gn3418f6 NS
+9hfklgvaurtdmcotlk0nh1nsrj43deje.cz. 900 IN RRSIG NSEC3 13 2 900 20180804023913 20180721053541 62295 cz. rJ/nyZPYNwZxgjf7asIyASKmSX+dHt4S nIRGX3ROuIqHp5k9TVkeW0XxAOYgRpAJ Gm1C9gayX3JGikaPZeYXuQ==
+cz. 900 IN RRSIG SOA 13 1 3600 20180809150540 20180727150545 62295 cz. UEx5NuZh+/viBicZcEp4A+zBy93jYDYL TW5QjK7B1NW978PJ+KY1so6ErplYU51Q ME8009WszzXXObYR3+kwdw==
+cz. 900 IN SOA a.ns.nic.cz. hostmaster.nic.cz. 1532707545 900 300 604800 900
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+cz. IN DNSKEY
+SECTION ANSWER
+cz. 18000 IN DNSKEY 256 3 13 LSpU2wluEwbQLak1XGlg3KEYygKfIiAu Q8iJxgDDSKuPLIA/BIn40LC1nPzfLwoa zmL7sPJRetzjxwtErBLCmw==
+cz. 18000 IN DNSKEY 257 3 13 nqzH7xP1QU5UOVy/VvxFSlrB/XgX9JDJ zj51PzIj35TXjZTyalTlAT/f7PAfaSD5 mEG1N8Vk9NmI2nxgQqhzDQ==
+cz. 18000 IN RRSIG DNSKEY 13 1 18000 20180803000000 20180720000000 20237 cz. 2KI6brDc06P9gKXv+omp0NDfgxwMa2DD NnMNf7sE97/vGyCVdu0FkA3NdtpUs3UC RwD3Nb5+jh7O45sLwyu6yw==
+cz. 18000 IN RRSIG DNSKEY 13 1 18000 20180809010634 20180727150545 62295 cz. RlVw07JKCfgZCR2i09sgK7V43KFl7xpb Rzyg0Z9pD9nO/bvenRHgnpWUyFXM+1Ma kjVQkrHxmw5vVvDu8Er/fA==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH subdomain
+ADJUST copy_id copy_query
+REPLY QR RD NOERROR
+SECTION QUESTION
+root.cz. IN NS
+SECTION AUTHORITY
+root.cz. 3600 IN DS 21523 5 2 b73053df8858181e1940ee6160e75d5339103264b9e56a9a1ecd64adabb2e54f
+root.cz. 3600 IN NS ns.iinfo.cz.
+root.cz. 3600 IN NS ns6.adminit.cz.
+root.cz. 3600 IN RRSIG DS 13 2 3600 20180809020236 20180727093611 62295 cz. vQCM/GJGJky3kC1IcQZpFddgl0iTTvzq EPV6FPEttgS59K3TnAd9jHKqQrXi7cEW yQ8eO7k27czWZ1UyA4wM2g==
+SECTION ADDITIONAL
+ns.iinfo.cz. 3600 IN A 91.213.160.5
+ns.iinfo.cz. 3600 IN AAAA 2001:67c:68::5
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH subdomain
+ADJUST copy_id copy_query
+REPLY QR RD NOERROR
+SECTION QUESTION
+iinfo.cz. IN NS
+SECTION AUTHORITY
+iinfo.cz. 3600 IN DS 21523 5 2 1f3ad3f9eace2aacf2cca9464e6642fe4bafce5a2817da25faef31e59c1fb74e
+iinfo.cz. 3600 IN NS ns.iinfo.cz.
+iinfo.cz. 3600 IN NS ns6.adminit.cz.
+iinfo.cz. 3600 IN RRSIG DS 13 2 3600 20180809121603 20180727063545 62295 cz. 7Y0LIeZxiEPiUqrOxA+SOmEdSCKjlehi hq+64xyIatKjPMWIK77Hh/rywef10beV NzWngBAx6lCKKj0jQJZn8Q==
+SECTION ADDITIONAL
+ns.iinfo.cz. 3600 IN A 91.213.160.5
+ns.iinfo.cz. 3600 IN AAAA 2001:67c:68::5
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH subdomain
+ADJUST copy_id copy_query
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+nic.cz. IN NS
+SECTION ANSWER
+nic.cz. 1800 IN NS a.ns.nic.cz.
+nic.cz. 1800 IN NS b.ns.nic.cz.
+nic.cz. 1800 IN NS d.ns.nic.cz.
+nic.cz. 1800 IN RRSIG NS 13 2 1800 20180809162254 20180727064002 33494 nic.cz. UOY4VdLFGrtMr22EaYes+1lbCAjFkhlt N5Q+0jpGucbyEFXrbxN4lFoQGpkX/+aU IWuKxWQI8VVmBKYLFBqSTw==
+SECTION ADDITIONAL
+a.ns.nic.cz. 1800 IN A 194.0.12.1
+a.ns.nic.cz. 1800 IN AAAA 2001:678:f::1
+a.ns.nic.cz. 1800 IN RRSIG A 13 4 1800 20180810011809 20180727064002 33494 nic.cz. dlRCgD1PxXFCid2m1djf5URx+SbMMFtR aaeNB5G7jj9nqFv252cwhnOz7NLPqEBG yr+h8eEOqFKbV92ZfzygLw==
+a.ns.nic.cz. 1800 IN RRSIG AAAA 13 4 1800 20180809213334 20180727064002 33494 nic.cz. TQvt6opeQKp4V/VTYgEsw25AFAD3l9I6 UE5HhJUVGpnn8YzmZZs1QTNC1ZVf0MCs Flr3H2mTNm0r/Mb3m6Q+Yw==
+b.ns.nic.cz. 1800 IN A 194.0.13.1
+b.ns.nic.cz. 1800 IN AAAA 2001:678:10::1
+b.ns.nic.cz. 1800 IN RRSIG A 13 4 1800 20180809112828 20180727064002 33494 nic.cz. GO5Wc2EWoV4yRvc3ktazw+lNZ7nGtR6S 4MsumQDKuADSGMLAhwm+htASUXxWZtV+ wWv74LD2g2cNjHpXHH1PBg==
+b.ns.nic.cz. 1800 IN RRSIG AAAA 13 4 1800 20180809130835 20180727064002 33494 nic.cz. sesuNekVgD2YLYl51sKLEYZeDmcxtQKl oFYnpXMUBVlqLTUGjn0RRcDvpJCxj/Ac isifFcEwvZ4W0B5/Ry1oVQ==
+d.ns.nic.cz. 1800 IN A 193.29.206.1
+d.ns.nic.cz. 1800 IN AAAA 2001:678:1::1
+d.ns.nic.cz. 1800 IN RRSIG A 13 4 1800 20180809211641 20180727064002 33494 nic.cz. yLSqZnGG2G5+StFxEPpuV3I5slNKLF3o 7QahlX4mKk/iN74C7zh62cR+Q/s3SDxE fFF2M/owNT3T2wspOh4L/g==
+d.ns.nic.cz. 1800 IN RRSIG AAAA 13 4 1800 20180809225253 20180727064002 33494 nic.cz. Rm0kQ0l//ZsEDNi1M3Hmns4C2aWzcGI/ oUBN92egsGSvQ0EGVgZMWZp/Pun+Tgr/ AHHCsD4lW8ZNNxHh5CCtZQ==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH subdomain
+ADJUST copy_id copy_query
+REPLY QR RD NOERROR
+SECTION QUESTION
+adminit.cz. IN NS
+SECTION AUTHORITY
+9HFKLGVAURTDMCOTLK0NH1NSRJ43DEJE.cz. 900 IN NSEC3 1 0 10 10e824b15ffa0abd 9hfku52m3alurnj3eavfg458gn3418f6 NS
+9HFKLGVAURTDMCOTLK0NH1NSRJ43DEJE.cz. 900 IN RRSIG NSEC3 13 2 900 20180804023913 20180721053541 62295 cz. rJ/nyZPYNwZxgjf7asIyASKmSX+dHt4S nIRGX3ROuIqHp5k9TVkeW0XxAOYgRpAJ Gm1C9gayX3JGikaPZeYXuQ==
+adminit.cz. 3600 IN NS ns.adminit.cz.
+adminit.cz. 3600 IN NS ns.iinfo.cz.
+SECTION ADDITIONAL
+ns.adminit.cz. 3600 IN A 89.185.231.140
+ns.iinfo.cz. 3600 IN A 91.213.160.5
+ns.iinfo.cz. 3600 IN AAAA 2001:67c:68::5
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH subdomain
+ADJUST copy_id copy_query
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+cz. IN NS
+SECTION ANSWER
+cz. 3600 IN NS a.ns.nic.cz.
+cz. 3600 IN NS b.ns.nic.cz.
+cz. 3600 IN NS c.ns.nic.cz.
+cz. 3600 IN NS d.ns.nic.cz.
+cz. 3600 IN RRSIG NS 13 1 3600 20180806013233 20180724063548 62295 cz. NYwbiceGXv+yKrhwwMPUO5WihpVt4nip dQpjpbVxJfUp4s+j5lOHsxcbCm4EEaBx x1+UXCK6Gnw9TCnaZaOiBQ==
+SECTION ADDITIONAL
+a.ns.nic.cz. 3600 IN A 194.0.12.1
+a.ns.nic.cz. 3600 IN AAAA 2001:678:f::1
+b.ns.nic.cz. 3600 IN A 194.0.13.1
+b.ns.nic.cz. 3600 IN AAAA 2001:678:10::1
+d.ns.nic.cz. 3600 IN A 193.29.206.1
+d.ns.nic.cz. 3600 IN AAAA 2001:678:1::1
+ENTRY_END
+
+
+RANGE_END
+
+
+; Scope "root.cz.
+
+; Server names:
+; ns6.adminit.cz.
+; ns.iinfo.cz.
+RANGE_BEGIN 0 1000
+ ADDRESS 46.101.163.95
+ ADDRESS 2001:67c:68::5
+ ADDRESS 91.213.160.5
+ ADDRESS 2a03:b0c0:3:d0::4c:2001
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+root.cz. IN A
+SECTION ANSWER
+root.cz. 600 IN A 91.213.160.118
+root.cz. 600 IN RRSIG A 5 2 600 20190528123431 20180528123431 8130 root.cz. VbfAvnvnwmW04evIkjQTSeJN5J9Gtfum 2m13VOQCetKK01G4h5yS18qS5Yl4dZQh zftnYpQ1WJlkM6a3RXAgPw==
+SECTION AUTHORITY
+root.cz. 600 IN NS ns.iinfo.cz.
+root.cz. 600 IN NS ns6.adminit.cz.
+root.cz. 600 IN RRSIG NS 5 2 600 20190528123431 20180528123431 8130 root.cz. SXqkv2rcKBDAYKzsn3FL+2djE4ob+BbJ OjNcHcihIQFaCLHfvTpmh7bKDyDrtyBj xAB/EPVJWdn1Gvu8PUKGOA==
+SECTION ADDITIONAL
+ns.iinfo.cz. 360 IN A 91.213.160.5
+ns.iinfo.cz. 360 IN AAAA 2001:67c:68::5
+ns.iinfo.cz. 360 IN RRSIG A 5 3 360 20190528123437 20180528123437 8130 iinfo.cz. Rf//ObuX0E/s5d7Z1Ld0MjHa+q+tVdl8 GwY4pZTW7DHRivIEij+owDnmDNID62EB MpURuInEPV5FaF/9sT6X8A==
+ns.iinfo.cz. 360 IN RRSIG AAAA 5 3 360 20190528123437 20180528123437 8130 iinfo.cz. q5hoFF0ldADkVxxKTgXgh3RUL+JseejX tcUvRqaD+VTwbJO5J0Kl+tJufKw7tRVt EJP8opneZsIsKamQhdWrDg==
+ns6.adminit.cz. 600 IN A 46.101.163.95
+ns6.adminit.cz. 600 IN AAAA 2a03:b0c0:3:d0::4c:2001
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+root.cz. IN AAAA
+SECTION ANSWER
+root.cz. 600 IN AAAA 2001:67c:68::76
+root.cz. 600 IN RRSIG AAAA 5 2 600 20190528123431 20180528123431 8130 root.cz. DUKH/DmP1XFWtKXHpCLJ49786krOOqO0 cIeEn+5sFsKx+ZS96WRyNpYyy0VQyvqm /D+y2HwZFpxRQMM3oAa+IQ==
+SECTION AUTHORITY
+root.cz. 600 IN NS ns.iinfo.cz.
+root.cz. 600 IN NS ns6.adminit.cz.
+root.cz. 600 IN RRSIG NS 5 2 600 20190528123431 20180528123431 8130 root.cz. SXqkv2rcKBDAYKzsn3FL+2djE4ob+BbJ OjNcHcihIQFaCLHfvTpmh7bKDyDrtyBj xAB/EPVJWdn1Gvu8PUKGOA==
+SECTION ADDITIONAL
+ns.iinfo.cz. 360 IN A 91.213.160.5
+ns.iinfo.cz. 360 IN AAAA 2001:67c:68::5
+ns.iinfo.cz. 360 IN RRSIG A 5 3 360 20190528123437 20180528123437 8130 iinfo.cz. Rf//ObuX0E/s5d7Z1Ld0MjHa+q+tVdl8 GwY4pZTW7DHRivIEij+owDnmDNID62EB MpURuInEPV5FaF/9sT6X8A==
+ns.iinfo.cz. 360 IN RRSIG AAAA 5 3 360 20190528123437 20180528123437 8130 iinfo.cz. q5hoFF0ldADkVxxKTgXgh3RUL+JseejX tcUvRqaD+VTwbJO5J0Kl+tJufKw7tRVt EJP8opneZsIsKamQhdWrDg==
+ns6.adminit.cz. 600 IN A 46.101.163.95
+ns6.adminit.cz. 600 IN AAAA 2a03:b0c0:3:d0::4c:2001
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+root.cz. IN TYPE65535
+SECTION AUTHORITY
+root.cz. 600 IN NSEC 10.root.cz. A NS SOA MX TXT AAAA RRSIG NSEC DNSKEY
+root.cz. 600 IN RRSIG NSEC 5 2 600 20190528123431 20180528123431 8130 root.cz. zyNxcRCooKSKBrLYS+o8ZXZXqN+OakCK 3/A06vZsprPaKyy1Q67Zu7J8I1WW0faX SB5Zvv7ka+TeoE4HfYZmQQ==
+root.cz. 600 IN RRSIG SOA 5 2 600 20190528123431 20180528123431 8130 root.cz. BEf0O/YUhGy6Xoh15SYLu5K/BKmlOW/x g39vk0ficFELb7FYzHUEKghXaSCAtjzL 41ZhRQqB6yHXMBSxujHxeA==
+root.cz. 600 IN SOA ns.iinfo.cz. hostmaster.iinfo.cz. 2018052801 86400 3600 3600000 600
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+ns.iinfo.cz. IN A
+SECTION ANSWER
+ns.iinfo.cz. 360 IN A 91.213.160.5
+ns.iinfo.cz. 360 IN RRSIG A 5 3 360 20190528123437 20180528123437 8130 iinfo.cz. Rf//ObuX0E/s5d7Z1Ld0MjHa+q+tVdl8 GwY4pZTW7DHRivIEij+owDnmDNID62EB MpURuInEPV5FaF/9sT6X8A==
+SECTION AUTHORITY
+iinfo.cz. 600 IN NS ns.iinfo.cz.
+iinfo.cz. 600 IN NS ns6.adminit.cz.
+iinfo.cz. 600 IN RRSIG NS 5 2 600 20190528123437 20180528123437 8130 iinfo.cz. pnOulEq9+lsY62m4J7rnsVL5JojezXVo BpX0aNCbJ/L4786RSE4no5KBZPfLvDns gmWQqT/WaMqYQTWQd/AfyA==
+SECTION ADDITIONAL
+ns.iinfo.cz. 360 IN AAAA 2001:67c:68::5
+ns.iinfo.cz. 360 IN RRSIG AAAA 5 3 360 20190528123437 20180528123437 8130 iinfo.cz. q5hoFF0ldADkVxxKTgXgh3RUL+JseejX tcUvRqaD+VTwbJO5J0Kl+tJufKw7tRVt EJP8opneZsIsKamQhdWrDg==
+ns6.adminit.cz. 600 IN A 46.101.163.95
+ns6.adminit.cz. 600 IN AAAA 2a03:b0c0:3:d0::4c:2001
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+ns.iinfo.cz. IN DNSKEY
+SECTION AUTHORITY
+iinfo.cz. 600 IN RRSIG SOA 5 2 600 20190528123437 20180528123437 8130 iinfo.cz. j0qa9fTHdIXHZl72BcOfokHxk8LzxxpY x3LULH7xBsRMEGgBg9BYDYyJChyibjoo PSACAn8wfCATJbaST26lbQ==
+iinfo.cz. 600 IN SOA ns.iinfo.cz. hostmaster.iinfo.cz. 2018052801 1800 3600 604800 600
+ns.iinfo.cz. 600 IN NSEC ocelot.iinfo.cz. A AAAA RRSIG NSEC
+ns.iinfo.cz. 600 IN RRSIG NSEC 5 3 600 20190528123437 20180528123437 8130 iinfo.cz. s5VnlUMkC1MVFJooQRhhZ6abt5pBvvfl hiMWNjrE13MeSpdjwQho4aTTIlvV+ewR Vo5rr1uj+h3Z5TA2eClzWg==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+ns.iinfo.cz. IN NS
+SECTION AUTHORITY
+iinfo.cz. 600 IN RRSIG SOA 5 2 600 20190528123437 20180528123437 8130 iinfo.cz. j0qa9fTHdIXHZl72BcOfokHxk8LzxxpY x3LULH7xBsRMEGgBg9BYDYyJChyibjoo PSACAn8wfCATJbaST26lbQ==
+iinfo.cz. 600 IN SOA ns.iinfo.cz. hostmaster.iinfo.cz. 2018052801 1800 3600 604800 600
+ns.iinfo.cz. 600 IN NSEC ocelot.iinfo.cz. A AAAA RRSIG NSEC
+ns.iinfo.cz. 600 IN RRSIG NSEC 5 3 600 20190528123437 20180528123437 8130 iinfo.cz. s5VnlUMkC1MVFJooQRhhZ6abt5pBvvfl hiMWNjrE13MeSpdjwQho4aTTIlvV+ewR Vo5rr1uj+h3Z5TA2eClzWg==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+ns.iinfo.cz. IN DS
+SECTION AUTHORITY
+iinfo.cz. 600 IN RRSIG SOA 5 2 600 20190528123437 20180528123437 8130 iinfo.cz. j0qa9fTHdIXHZl72BcOfokHxk8LzxxpY x3LULH7xBsRMEGgBg9BYDYyJChyibjoo PSACAn8wfCATJbaST26lbQ==
+iinfo.cz. 600 IN SOA ns.iinfo.cz. hostmaster.iinfo.cz. 2018052801 1800 3600 604800 600
+ns.iinfo.cz. 600 IN NSEC ocelot.iinfo.cz. A AAAA RRSIG NSEC
+ns.iinfo.cz. 600 IN RRSIG NSEC 5 3 600 20190528123437 20180528123437 8130 iinfo.cz. s5VnlUMkC1MVFJooQRhhZ6abt5pBvvfl hiMWNjrE13MeSpdjwQho4aTTIlvV+ewR Vo5rr1uj+h3Z5TA2eClzWg==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+ns.iinfo.cz. IN AAAA
+SECTION ANSWER
+ns.iinfo.cz. 360 IN AAAA 2001:67c:68::5
+ns.iinfo.cz. 360 IN RRSIG AAAA 5 3 360 20190528123437 20180528123437 8130 iinfo.cz. q5hoFF0ldADkVxxKTgXgh3RUL+JseejX tcUvRqaD+VTwbJO5J0Kl+tJufKw7tRVt EJP8opneZsIsKamQhdWrDg==
+SECTION AUTHORITY
+iinfo.cz. 600 IN NS ns.iinfo.cz.
+iinfo.cz. 600 IN NS ns6.adminit.cz.
+iinfo.cz. 600 IN RRSIG NS 5 2 600 20190528123437 20180528123437 8130 iinfo.cz. pnOulEq9+lsY62m4J7rnsVL5JojezXVo BpX0aNCbJ/L4786RSE4no5KBZPfLvDns gmWQqT/WaMqYQTWQd/AfyA==
+SECTION ADDITIONAL
+ns.iinfo.cz. 360 IN A 91.213.160.5
+ns.iinfo.cz. 360 IN RRSIG A 5 3 360 20190528123437 20180528123437 8130 iinfo.cz. Rf//ObuX0E/s5d7Z1Ld0MjHa+q+tVdl8 GwY4pZTW7DHRivIEij+owDnmDNID62EB MpURuInEPV5FaF/9sT6X8A==
+ns6.adminit.cz. 600 IN A 46.101.163.95
+ns6.adminit.cz. 600 IN AAAA 2a03:b0c0:3:d0::4c:2001
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+blog.root.cz. IN A
+SECTION ANSWER
+blog.root.cz. 600 IN CNAME root.cz.
+blog.root.cz. 600 IN RRSIG CNAME 5 3 600 20190528123431 20180528123431 8130 root.cz. DSHP4iTt49vRSsPjtBBxXj876UXSZukv 5Uko/B3GfLujWV/fOwZIQaHJTmfwzmT0 l4I+FSGkhwwHRQpCpqvzOQ==
+root.cz. 600 IN A 91.213.160.118
+root.cz. 600 IN RRSIG A 5 2 600 20190528123431 20180528123431 8130 root.cz. VbfAvnvnwmW04evIkjQTSeJN5J9Gtfum 2m13VOQCetKK01G4h5yS18qS5Yl4dZQh zftnYpQ1WJlkM6a3RXAgPw==
+SECTION AUTHORITY
+root.cz. 600 IN NS ns.iinfo.cz.
+root.cz. 600 IN NS ns6.adminit.cz.
+root.cz. 600 IN RRSIG NS 5 2 600 20190528123431 20180528123431 8130 root.cz. SXqkv2rcKBDAYKzsn3FL+2djE4ob+BbJ OjNcHcihIQFaCLHfvTpmh7bKDyDrtyBj xAB/EPVJWdn1Gvu8PUKGOA==
+SECTION ADDITIONAL
+ns.iinfo.cz. 360 IN A 91.213.160.5
+ns.iinfo.cz. 360 IN AAAA 2001:67c:68::5
+ns.iinfo.cz. 360 IN RRSIG A 5 3 360 20190528123437 20180528123437 8130 iinfo.cz. Rf//ObuX0E/s5d7Z1Ld0MjHa+q+tVdl8 GwY4pZTW7DHRivIEij+owDnmDNID62EB MpURuInEPV5FaF/9sT6X8A==
+ns.iinfo.cz. 360 IN RRSIG AAAA 5 3 360 20190528123437 20180528123437 8130 iinfo.cz. q5hoFF0ldADkVxxKTgXgh3RUL+JseejX tcUvRqaD+VTwbJO5J0Kl+tJufKw7tRVt EJP8opneZsIsKamQhdWrDg==
+ns6.adminit.cz. 600 IN A 46.101.163.95
+ns6.adminit.cz. 600 IN AAAA 2a03:b0c0:3:d0::4c:2001
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+blog.root.cz. IN DNSKEY
+SECTION ANSWER
+blog.root.cz. 600 IN CNAME root.cz.
+blog.root.cz. 600 IN RRSIG CNAME 5 3 600 20190528123431 20180528123431 8130 root.cz. DSHP4iTt49vRSsPjtBBxXj876UXSZukv 5Uko/B3GfLujWV/fOwZIQaHJTmfwzmT0 l4I+FSGkhwwHRQpCpqvzOQ==
+root.cz. 600 IN DNSKEY 256 3 5 AwEAAdX9H0Z0zTYKmh4NjmMARj16ThCn et8JUvivs+/+0QidPtCyW8ww0CUDyeqo rXOw0CI5otOccm2Es4v1SuFwMPs=
+root.cz. 600 IN DNSKEY 257 3 5 AwEAAd0gb4uhOraiCsHKE6JjR6HKOeRq Ry8Nxj4cg2AmKtaSF78rmvN27vtU8tKD LUGtiGgg33pcAOp+bvtd9ACu5s//Dch0 MHJpCDHFGoR4WVLbqBz9isTs3DLVLxWQ luMKeo/Kxed7sR3fMyPxAP1+FFi3esdX xANsVur/h9gGI5WVNtyXhq+qkWqLX0Y6 Q0jGzIuDrd5I4cVrWOei1OM4xV53Gh6D h98lptCA2ek35RuW3tPb7zHGXF3s+Baf gq7H8QJjnWmcFJh8ACdmbT63afQchYWT oyWdWUOeSpm/Uu0JOcbodAUD4m44P1Ed V1hzwwrHQIFUfdyA6He8mBPxS1k=
+root.cz. 600 IN RRSIG DNSKEY 5 2 600 20190528123431 20180528123431 21523 root.cz. FifAZ5ePqDd5e5/oMiUeCZ2wA0OAqz03 I5ZkHb1OgKnZEpbI3yCHnF+3V4RS7ILu qJB/j04fXTiBwLsbBB+ZITUJ/PMA0VJ+ EA5hPJ0Cyei9cWKHw71peaLLCbH1T06g BntUshxxtKhGVjzhvaBqKw039HDu/2m3 RCj/pKSw71Lc+uLwR9lkaxmLeO9YfK/m 8SHdP6EOhadPIe4525iPGktWiLCDbdey DbdrlF8k1nXLtzWwFTwYl/L2n2NrJxSy GNJ7iHFzvfNCm6EWvhvdSijA9hSaFl2S D1IgD0kdix1F4wzRZpyzNlB2LsCYAH9q WkMyoKF0aH67YraYre44Nw==
+root.cz. 600 IN RRSIG DNSKEY 5 2 600 20190528123431 20180528123431 8130 root.cz. GBADhpGGSxw8B+ke+K0rOAYwYL3KmweD j1PKaSleBOmftpFjb8gyvKX3LJgn66m/ UrKAOccPTriwkN+4ZJgq7g==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+blog.root.cz. IN DS
+SECTION ANSWER
+blog.root.cz. 600 IN CNAME root.cz.
+blog.root.cz. 600 IN RRSIG CNAME 5 3 600 20190528123431 20180528123431 8130 root.cz. DSHP4iTt49vRSsPjtBBxXj876UXSZukv 5Uko/B3GfLujWV/fOwZIQaHJTmfwzmT0 l4I+FSGkhwwHRQpCpqvzOQ==
+SECTION AUTHORITY
+root.cz. 600 IN NSEC 10.root.cz. A NS SOA MX TXT AAAA RRSIG NSEC DNSKEY
+root.cz. 600 IN RRSIG NSEC 5 2 600 20190528123431 20180528123431 8130 root.cz. zyNxcRCooKSKBrLYS+o8ZXZXqN+OakCK 3/A06vZsprPaKyy1Q67Zu7J8I1WW0faX SB5Zvv7ka+TeoE4HfYZmQQ==
+root.cz. 600 IN RRSIG SOA 5 2 600 20190528123431 20180528123431 8130 root.cz. BEf0O/YUhGy6Xoh15SYLu5K/BKmlOW/x g39vk0ficFELb7FYzHUEKghXaSCAtjzL 41ZhRQqB6yHXMBSxujHxeA==
+root.cz. 600 IN SOA ns.iinfo.cz. hostmaster.iinfo.cz. 2018052801 86400 3600 3600000 600
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+random1.blog.root.cz. IN A
+SECTION ANSWER
+blog.root.cz. 600 IN CNAME root.cz.
+blog.root.cz. 600 IN RRSIG CNAME 5 3 600 20190528123431 20180528123431 8130 root.cz. DSHP4iTt49vRSsPjtBBxXj876UXSZukv 5Uko/B3GfLujWV/fOwZIQaHJTmfwzmT0 l4I+FSGkhwwHRQpCpqvzOQ==
+random1.blog.root.cz. 600 IN CNAME blog.root.cz.
+random1.blog.root.cz. 600 IN RRSIG CNAME 5 3 600 20190528123431 20180528123431 8130 root.cz. db6OwEqbgywxPO8tTqz/nh9yj1mY/hYZ KmHhH4HH1v2eH1wIU/S1jvD1ZHGAssVw xbh9LoY0x0mSPdCciX1WvQ==
+root.cz. 600 IN A 91.213.160.118
+root.cz. 600 IN RRSIG A 5 2 600 20190528123431 20180528123431 8130 root.cz. VbfAvnvnwmW04evIkjQTSeJN5J9Gtfum 2m13VOQCetKK01G4h5yS18qS5Yl4dZQh zftnYpQ1WJlkM6a3RXAgPw==
+SECTION AUTHORITY
+*.blog.root.cz. 600 IN NSEC blog-beta.root.cz. CNAME RRSIG NSEC
+*.blog.root.cz. 600 IN RRSIG NSEC 5 3 600 20190528123431 20180528123431 8130 root.cz. dq9cWL5b4ogXMDfVhICOc6uBAuV8YnlA +eNB09aH8vjwJlNtiKPZknER3foS8bVx OEhJrYXGtldnMFP3rLlcKA==
+root.cz. 600 IN NS ns.iinfo.cz.
+root.cz. 600 IN NS ns6.adminit.cz.
+root.cz. 600 IN RRSIG NS 5 2 600 20190528123431 20180528123431 8130 root.cz. SXqkv2rcKBDAYKzsn3FL+2djE4ob+BbJ OjNcHcihIQFaCLHfvTpmh7bKDyDrtyBj xAB/EPVJWdn1Gvu8PUKGOA==
+SECTION ADDITIONAL
+ns.iinfo.cz. 360 IN A 91.213.160.5
+ns.iinfo.cz. 360 IN AAAA 2001:67c:68::5
+ns.iinfo.cz. 360 IN RRSIG A 5 3 360 20190528123437 20180528123437 8130 iinfo.cz. Rf//ObuX0E/s5d7Z1Ld0MjHa+q+tVdl8 GwY4pZTW7DHRivIEij+owDnmDNID62EB MpURuInEPV5FaF/9sT6X8A==
+ns.iinfo.cz. 360 IN RRSIG AAAA 5 3 360 20190528123437 20180528123437 8130 iinfo.cz. q5hoFF0ldADkVxxKTgXgh3RUL+JseejX tcUvRqaD+VTwbJO5J0Kl+tJufKw7tRVt EJP8opneZsIsKamQhdWrDg==
+ns6.adminit.cz. 600 IN A 46.101.163.95
+ns6.adminit.cz. 600 IN AAAA 2a03:b0c0:3:d0::4c:2001
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+random1.blog.root.cz. IN DNSKEY
+SECTION ANSWER
+blog.root.cz. 600 IN CNAME root.cz.
+blog.root.cz. 600 IN RRSIG CNAME 5 3 600 20190528123431 20180528123431 8130 root.cz. DSHP4iTt49vRSsPjtBBxXj876UXSZukv 5Uko/B3GfLujWV/fOwZIQaHJTmfwzmT0 l4I+FSGkhwwHRQpCpqvzOQ==
+random1.blog.root.cz. 600 IN CNAME blog.root.cz.
+random1.blog.root.cz. 600 IN RRSIG CNAME 5 3 600 20190528123431 20180528123431 8130 root.cz. db6OwEqbgywxPO8tTqz/nh9yj1mY/hYZ KmHhH4HH1v2eH1wIU/S1jvD1ZHGAssVw xbh9LoY0x0mSPdCciX1WvQ==
+root.cz. 600 IN DNSKEY 256 3 5 AwEAAdX9H0Z0zTYKmh4NjmMARj16ThCn et8JUvivs+/+0QidPtCyW8ww0CUDyeqo rXOw0CI5otOccm2Es4v1SuFwMPs=
+root.cz. 600 IN DNSKEY 257 3 5 AwEAAd0gb4uhOraiCsHKE6JjR6HKOeRq Ry8Nxj4cg2AmKtaSF78rmvN27vtU8tKD LUGtiGgg33pcAOp+bvtd9ACu5s//Dch0 MHJpCDHFGoR4WVLbqBz9isTs3DLVLxWQ luMKeo/Kxed7sR3fMyPxAP1+FFi3esdX xANsVur/h9gGI5WVNtyXhq+qkWqLX0Y6 Q0jGzIuDrd5I4cVrWOei1OM4xV53Gh6D h98lptCA2ek35RuW3tPb7zHGXF3s+Baf gq7H8QJjnWmcFJh8ACdmbT63afQchYWT oyWdWUOeSpm/Uu0JOcbodAUD4m44P1Ed V1hzwwrHQIFUfdyA6He8mBPxS1k=
+root.cz. 600 IN RRSIG DNSKEY 5 2 600 20190528123431 20180528123431 21523 root.cz. FifAZ5ePqDd5e5/oMiUeCZ2wA0OAqz03 I5ZkHb1OgKnZEpbI3yCHnF+3V4RS7ILu qJB/j04fXTiBwLsbBB+ZITUJ/PMA0VJ+ EA5hPJ0Cyei9cWKHw71peaLLCbH1T06g BntUshxxtKhGVjzhvaBqKw039HDu/2m3 RCj/pKSw71Lc+uLwR9lkaxmLeO9YfK/m 8SHdP6EOhadPIe4525iPGktWiLCDbdey DbdrlF8k1nXLtzWwFTwYl/L2n2NrJxSy GNJ7iHFzvfNCm6EWvhvdSijA9hSaFl2S D1IgD0kdix1F4wzRZpyzNlB2LsCYAH9q WkMyoKF0aH67YraYre44Nw==
+root.cz. 600 IN RRSIG DNSKEY 5 2 600 20190528123431 20180528123431 8130 root.cz. GBADhpGGSxw8B+ke+K0rOAYwYL3KmweD j1PKaSleBOmftpFjb8gyvKX3LJgn66m/ UrKAOccPTriwkN+4ZJgq7g==
+SECTION AUTHORITY
+*.blog.root.cz. 600 IN NSEC blog-beta.root.cz. CNAME RRSIG NSEC
+*.blog.root.cz. 600 IN RRSIG NSEC 5 3 600 20190528123431 20180528123431 8130 root.cz. dq9cWL5b4ogXMDfVhICOc6uBAuV8YnlA +eNB09aH8vjwJlNtiKPZknER3foS8bVx OEhJrYXGtldnMFP3rLlcKA==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+random1.blog.root.cz. IN DS
+SECTION ANSWER
+blog.root.cz. 600 IN CNAME root.cz.
+blog.root.cz. 600 IN RRSIG CNAME 5 3 600 20190528123431 20180528123431 8130 root.cz. DSHP4iTt49vRSsPjtBBxXj876UXSZukv 5Uko/B3GfLujWV/fOwZIQaHJTmfwzmT0 l4I+FSGkhwwHRQpCpqvzOQ==
+random1.blog.root.cz. 600 IN CNAME blog.root.cz.
+random1.blog.root.cz. 600 IN RRSIG CNAME 5 3 600 20190528123431 20180528123431 8130 root.cz. db6OwEqbgywxPO8tTqz/nh9yj1mY/hYZ KmHhH4HH1v2eH1wIU/S1jvD1ZHGAssVw xbh9LoY0x0mSPdCciX1WvQ==
+SECTION AUTHORITY
+*.blog.root.cz. 600 IN NSEC blog-beta.root.cz. CNAME RRSIG NSEC
+*.blog.root.cz. 600 IN RRSIG NSEC 5 3 600 20190528123431 20180528123431 8130 root.cz. dq9cWL5b4ogXMDfVhICOc6uBAuV8YnlA +eNB09aH8vjwJlNtiKPZknER3foS8bVx OEhJrYXGtldnMFP3rLlcKA==
+root.cz. 600 IN NSEC 10.root.cz. A NS SOA MX TXT AAAA RRSIG NSEC DNSKEY
+root.cz. 600 IN RRSIG NSEC 5 2 600 20190528123431 20180528123431 8130 root.cz. zyNxcRCooKSKBrLYS+o8ZXZXqN+OakCK 3/A06vZsprPaKyy1Q67Zu7J8I1WW0faX SB5Zvv7ka+TeoE4HfYZmQQ==
+root.cz. 600 IN RRSIG SOA 5 2 600 20190528123431 20180528123431 8130 root.cz. BEf0O/YUhGy6Xoh15SYLu5K/BKmlOW/x g39vk0ficFELb7FYzHUEKghXaSCAtjzL 41ZhRQqB6yHXMBSxujHxeA==
+root.cz. 600 IN SOA ns.iinfo.cz. hostmaster.iinfo.cz. 2018052801 86400 3600 3600000 600
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+random1.blog.root.cz. IN AAAA
+SECTION ANSWER
+blog.root.cz. 600 IN CNAME root.cz.
+blog.root.cz. 600 IN RRSIG CNAME 5 3 600 20190528123431 20180528123431 8130 root.cz. DSHP4iTt49vRSsPjtBBxXj876UXSZukv 5Uko/B3GfLujWV/fOwZIQaHJTmfwzmT0 l4I+FSGkhwwHRQpCpqvzOQ==
+random1.blog.root.cz. 600 IN CNAME blog.root.cz.
+random1.blog.root.cz. 600 IN RRSIG CNAME 5 3 600 20190528123431 20180528123431 8130 root.cz. db6OwEqbgywxPO8tTqz/nh9yj1mY/hYZ KmHhH4HH1v2eH1wIU/S1jvD1ZHGAssVw xbh9LoY0x0mSPdCciX1WvQ==
+root.cz. 600 IN AAAA 2001:67c:68::76
+root.cz. 600 IN RRSIG AAAA 5 2 600 20190528123431 20180528123431 8130 root.cz. DUKH/DmP1XFWtKXHpCLJ49786krOOqO0 cIeEn+5sFsKx+ZS96WRyNpYyy0VQyvqm /D+y2HwZFpxRQMM3oAa+IQ==
+SECTION AUTHORITY
+*.blog.root.cz. 600 IN NSEC blog-beta.root.cz. CNAME RRSIG NSEC
+*.blog.root.cz. 600 IN RRSIG NSEC 5 3 600 20190528123431 20180528123431 8130 root.cz. dq9cWL5b4ogXMDfVhICOc6uBAuV8YnlA +eNB09aH8vjwJlNtiKPZknER3foS8bVx OEhJrYXGtldnMFP3rLlcKA==
+root.cz. 600 IN NS ns.iinfo.cz.
+root.cz. 600 IN NS ns6.adminit.cz.
+root.cz. 600 IN RRSIG NS 5 2 600 20190528123431 20180528123431 8130 root.cz. SXqkv2rcKBDAYKzsn3FL+2djE4ob+BbJ OjNcHcihIQFaCLHfvTpmh7bKDyDrtyBj xAB/EPVJWdn1Gvu8PUKGOA==
+SECTION ADDITIONAL
+ns.iinfo.cz. 360 IN A 91.213.160.5
+ns.iinfo.cz. 360 IN AAAA 2001:67c:68::5
+ns.iinfo.cz. 360 IN RRSIG A 5 3 360 20190528123437 20180528123437 8130 iinfo.cz. Rf//ObuX0E/s5d7Z1Ld0MjHa+q+tVdl8 GwY4pZTW7DHRivIEij+owDnmDNID62EB MpURuInEPV5FaF/9sT6X8A==
+ns.iinfo.cz. 360 IN RRSIG AAAA 5 3 360 20190528123437 20180528123437 8130 iinfo.cz. q5hoFF0ldADkVxxKTgXgh3RUL+JseejX tcUvRqaD+VTwbJO5J0Kl+tJufKw7tRVt EJP8opneZsIsKamQhdWrDg==
+ns6.adminit.cz. 600 IN A 46.101.163.95
+ns6.adminit.cz. 600 IN AAAA 2a03:b0c0:3:d0::4c:2001
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+blog.root.cz. IN AAAA
+SECTION ANSWER
+blog.root.cz. 600 IN CNAME root.cz.
+blog.root.cz. 600 IN RRSIG CNAME 5 3 600 20190528123431 20180528123431 8130 root.cz. DSHP4iTt49vRSsPjtBBxXj876UXSZukv 5Uko/B3GfLujWV/fOwZIQaHJTmfwzmT0 l4I+FSGkhwwHRQpCpqvzOQ==
+root.cz. 600 IN AAAA 2001:67c:68::76
+root.cz. 600 IN RRSIG AAAA 5 2 600 20190528123431 20180528123431 8130 root.cz. DUKH/DmP1XFWtKXHpCLJ49786krOOqO0 cIeEn+5sFsKx+ZS96WRyNpYyy0VQyvqm /D+y2HwZFpxRQMM3oAa+IQ==
+SECTION AUTHORITY
+root.cz. 600 IN NS ns.iinfo.cz.
+root.cz. 600 IN NS ns6.adminit.cz.
+root.cz. 600 IN RRSIG NS 5 2 600 20190528123431 20180528123431 8130 root.cz. SXqkv2rcKBDAYKzsn3FL+2djE4ob+BbJ OjNcHcihIQFaCLHfvTpmh7bKDyDrtyBj xAB/EPVJWdn1Gvu8PUKGOA==
+SECTION ADDITIONAL
+ns.iinfo.cz. 360 IN A 91.213.160.5
+ns.iinfo.cz. 360 IN AAAA 2001:67c:68::5
+ns.iinfo.cz. 360 IN RRSIG A 5 3 360 20190528123437 20180528123437 8130 iinfo.cz. Rf//ObuX0E/s5d7Z1Ld0MjHa+q+tVdl8 GwY4pZTW7DHRivIEij+owDnmDNID62EB MpURuInEPV5FaF/9sT6X8A==
+ns.iinfo.cz. 360 IN RRSIG AAAA 5 3 360 20190528123437 20180528123437 8130 iinfo.cz. q5hoFF0ldADkVxxKTgXgh3RUL+JseejX tcUvRqaD+VTwbJO5J0Kl+tJufKw7tRVt EJP8opneZsIsKamQhdWrDg==
+ns6.adminit.cz. 600 IN A 46.101.163.95
+ns6.adminit.cz. 600 IN AAAA 2a03:b0c0:3:d0::4c:2001
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+blog.root.cz. IN TYPE65535
+SECTION ANSWER
+blog.root.cz. 600 IN CNAME root.cz.
+blog.root.cz. 600 IN RRSIG CNAME 5 3 600 20190528123431 20180528123431 8130 root.cz. DSHP4iTt49vRSsPjtBBxXj876UXSZukv 5Uko/B3GfLujWV/fOwZIQaHJTmfwzmT0 l4I+FSGkhwwHRQpCpqvzOQ==
+SECTION AUTHORITY
+root.cz. 600 IN NSEC 10.root.cz. A NS SOA MX TXT AAAA RRSIG NSEC DNSKEY
+root.cz. 600 IN RRSIG NSEC 5 2 600 20190528123431 20180528123431 8130 root.cz. zyNxcRCooKSKBrLYS+o8ZXZXqN+OakCK 3/A06vZsprPaKyy1Q67Zu7J8I1WW0faX SB5Zvv7ka+TeoE4HfYZmQQ==
+root.cz. 600 IN RRSIG SOA 5 2 600 20190528123431 20180528123431 8130 root.cz. BEf0O/YUhGy6Xoh15SYLu5K/BKmlOW/x g39vk0ficFELb7FYzHUEKghXaSCAtjzL 41ZhRQqB6yHXMBSxujHxeA==
+root.cz. 600 IN SOA ns.iinfo.cz. hostmaster.iinfo.cz. 2018052801 86400 3600 3600000 600
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+random1.blog.root.cz. IN TYPE65535
+SECTION ANSWER
+blog.root.cz. 600 IN CNAME root.cz.
+blog.root.cz. 600 IN RRSIG CNAME 5 3 600 20190528123431 20180528123431 8130 root.cz. DSHP4iTt49vRSsPjtBBxXj876UXSZukv 5Uko/B3GfLujWV/fOwZIQaHJTmfwzmT0 l4I+FSGkhwwHRQpCpqvzOQ==
+random1.blog.root.cz. 600 IN CNAME blog.root.cz.
+random1.blog.root.cz. 600 IN RRSIG CNAME 5 3 600 20190528123431 20180528123431 8130 root.cz. db6OwEqbgywxPO8tTqz/nh9yj1mY/hYZ KmHhH4HH1v2eH1wIU/S1jvD1ZHGAssVw xbh9LoY0x0mSPdCciX1WvQ==
+SECTION AUTHORITY
+*.blog.root.cz. 600 IN NSEC blog-beta.root.cz. CNAME RRSIG NSEC
+*.blog.root.cz. 600 IN RRSIG NSEC 5 3 600 20190528123431 20180528123431 8130 root.cz. dq9cWL5b4ogXMDfVhICOc6uBAuV8YnlA +eNB09aH8vjwJlNtiKPZknER3foS8bVx OEhJrYXGtldnMFP3rLlcKA==
+root.cz. 600 IN NSEC 10.root.cz. A NS SOA MX TXT AAAA RRSIG NSEC DNSKEY
+root.cz. 600 IN RRSIG NSEC 5 2 600 20190528123431 20180528123431 8130 root.cz. zyNxcRCooKSKBrLYS+o8ZXZXqN+OakCK 3/A06vZsprPaKyy1Q67Zu7J8I1WW0faX SB5Zvv7ka+TeoE4HfYZmQQ==
+root.cz. 600 IN RRSIG SOA 5 2 600 20190528123431 20180528123431 8130 root.cz. BEf0O/YUhGy6Xoh15SYLu5K/BKmlOW/x g39vk0ficFELb7FYzHUEKghXaSCAtjzL 41ZhRQqB6yHXMBSxujHxeA==
+root.cz. 600 IN SOA ns.iinfo.cz. hostmaster.iinfo.cz. 2018052801 86400 3600 3600000 600
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+ns6.adminit.cz. IN A
+SECTION ANSWER
+ns6.adminit.cz. 600 IN A 46.101.163.95
+SECTION AUTHORITY
+adminit.cz. 600 IN NS ns.adminit.cz.
+adminit.cz. 600 IN NS ns.iinfo.cz.
+SECTION ADDITIONAL
+ns.adminit.cz. 600 IN A 89.185.231.140
+ns.iinfo.cz. 360 IN A 91.213.160.5
+ns.iinfo.cz. 360 IN AAAA 2001:67c:68::5
+ns.iinfo.cz. 360 IN RRSIG A 5 3 360 20190528123437 20180528123437 8130 iinfo.cz. Rf//ObuX0E/s5d7Z1Ld0MjHa+q+tVdl8 GwY4pZTW7DHRivIEij+owDnmDNID62EB MpURuInEPV5FaF/9sT6X8A==
+ns.iinfo.cz. 360 IN RRSIG AAAA 5 3 360 20190528123437 20180528123437 8130 iinfo.cz. q5hoFF0ldADkVxxKTgXgh3RUL+JseejX tcUvRqaD+VTwbJO5J0Kl+tJufKw7tRVt EJP8opneZsIsKamQhdWrDg==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+ns6.adminit.cz. IN DNSKEY
+SECTION AUTHORITY
+adminit.cz. 600 IN SOA ns.adminit.cz. hostmaster.adminit.cz. 2018072003 10800 3600 604800 600
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+ns6.adminit.cz. IN NS
+SECTION AUTHORITY
+adminit.cz. 600 IN SOA ns.adminit.cz. hostmaster.adminit.cz. 2018072003 10800 3600 604800 600
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+ns6.adminit.cz. IN DS
+SECTION AUTHORITY
+adminit.cz. 600 IN SOA ns.adminit.cz. hostmaster.adminit.cz. 2018072003 10800 3600 604800 600
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+ns6.adminit.cz. IN AAAA
+SECTION ANSWER
+ns6.adminit.cz. 600 IN AAAA 2a03:b0c0:3:d0::4c:2001
+SECTION AUTHORITY
+adminit.cz. 600 IN NS ns.adminit.cz.
+adminit.cz. 600 IN NS ns.iinfo.cz.
+SECTION ADDITIONAL
+ns.adminit.cz. 600 IN A 89.185.231.140
+ns.iinfo.cz. 360 IN A 91.213.160.5
+ns.iinfo.cz. 360 IN AAAA 2001:67c:68::5
+ns.iinfo.cz. 360 IN RRSIG A 5 3 360 20190528123437 20180528123437 8130 iinfo.cz. Rf//ObuX0E/s5d7Z1Ld0MjHa+q+tVdl8 GwY4pZTW7DHRivIEij+owDnmDNID62EB MpURuInEPV5FaF/9sT6X8A==
+ns.iinfo.cz. 360 IN RRSIG AAAA 5 3 360 20190528123437 20180528123437 8130 iinfo.cz. q5hoFF0ldADkVxxKTgXgh3RUL+JseejX tcUvRqaD+VTwbJO5J0Kl+tJufKw7tRVt EJP8opneZsIsKamQhdWrDg==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+ns.adminit.cz. IN A
+SECTION ANSWER
+ns.adminit.cz. 600 IN A 89.185.231.140
+SECTION AUTHORITY
+adminit.cz. 600 IN NS ns.adminit.cz.
+adminit.cz. 600 IN NS ns.iinfo.cz.
+SECTION ADDITIONAL
+ns.iinfo.cz. 360 IN A 91.213.160.5
+ns.iinfo.cz. 360 IN AAAA 2001:67c:68::5
+ns.iinfo.cz. 360 IN RRSIG A 5 3 360 20190528123437 20180528123437 8130 iinfo.cz. Rf//ObuX0E/s5d7Z1Ld0MjHa+q+tVdl8 GwY4pZTW7DHRivIEij+owDnmDNID62EB MpURuInEPV5FaF/9sT6X8A==
+ns.iinfo.cz. 360 IN RRSIG AAAA 5 3 360 20190528123437 20180528123437 8130 iinfo.cz. q5hoFF0ldADkVxxKTgXgh3RUL+JseejX tcUvRqaD+VTwbJO5J0Kl+tJufKw7tRVt EJP8opneZsIsKamQhdWrDg==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+ns.adminit.cz. IN DNSKEY
+SECTION AUTHORITY
+adminit.cz. 600 IN SOA ns.adminit.cz. hostmaster.adminit.cz. 2018072003 10800 3600 604800 600
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+ns.adminit.cz. IN NS
+SECTION AUTHORITY
+adminit.cz. 600 IN SOA ns.adminit.cz. hostmaster.adminit.cz. 2018072003 10800 3600 604800 600
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+ns.adminit.cz. IN DS
+SECTION AUTHORITY
+adminit.cz. 600 IN SOA ns.adminit.cz. hostmaster.adminit.cz. 2018072003 10800 3600 604800 600
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+ns.adminit.cz. IN AAAA
+SECTION AUTHORITY
+adminit.cz. 600 IN SOA ns.adminit.cz. hostmaster.adminit.cz. 2018072003 10800 3600 604800 600
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+root.cz. IN DNSKEY
+SECTION ANSWER
+root.cz. 600 IN DNSKEY 256 3 5 AwEAAdX9H0Z0zTYKmh4NjmMARj16ThCn et8JUvivs+/+0QidPtCyW8ww0CUDyeqo rXOw0CI5otOccm2Es4v1SuFwMPs=
+root.cz. 600 IN DNSKEY 257 3 5 AwEAAd0gb4uhOraiCsHKE6JjR6HKOeRq Ry8Nxj4cg2AmKtaSF78rmvN27vtU8tKD LUGtiGgg33pcAOp+bvtd9ACu5s//Dch0 MHJpCDHFGoR4WVLbqBz9isTs3DLVLxWQ luMKeo/Kxed7sR3fMyPxAP1+FFi3esdX xANsVur/h9gGI5WVNtyXhq+qkWqLX0Y6 Q0jGzIuDrd5I4cVrWOei1OM4xV53Gh6D h98lptCA2ek35RuW3tPb7zHGXF3s+Baf gq7H8QJjnWmcFJh8ACdmbT63afQchYWT oyWdWUOeSpm/Uu0JOcbodAUD4m44P1Ed V1hzwwrHQIFUfdyA6He8mBPxS1k=
+root.cz. 600 IN RRSIG DNSKEY 5 2 600 20190528123431 20180528123431 21523 root.cz. FifAZ5ePqDd5e5/oMiUeCZ2wA0OAqz03 I5ZkHb1OgKnZEpbI3yCHnF+3V4RS7ILu qJB/j04fXTiBwLsbBB+ZITUJ/PMA0VJ+ EA5hPJ0Cyei9cWKHw71peaLLCbH1T06g BntUshxxtKhGVjzhvaBqKw039HDu/2m3 RCj/pKSw71Lc+uLwR9lkaxmLeO9YfK/m 8SHdP6EOhadPIe4525iPGktWiLCDbdey DbdrlF8k1nXLtzWwFTwYl/L2n2NrJxSy GNJ7iHFzvfNCm6EWvhvdSijA9hSaFl2S D1IgD0kdix1F4wzRZpyzNlB2LsCYAH9q WkMyoKF0aH67YraYre44Nw==
+root.cz. 600 IN RRSIG DNSKEY 5 2 600 20190528123431 20180528123431 8130 root.cz. GBADhpGGSxw8B+ke+K0rOAYwYL3KmweD j1PKaSleBOmftpFjb8gyvKX3LJgn66m/ UrKAOccPTriwkN+4ZJgq7g==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+iinfo.cz. IN DNSKEY
+SECTION ANSWER
+iinfo.cz. 600 IN DNSKEY 256 3 5 AwEAAdX9H0Z0zTYKmh4NjmMARj16ThCn et8JUvivs+/+0QidPtCyW8ww0CUDyeqo rXOw0CI5otOccm2Es4v1SuFwMPs=
+iinfo.cz. 600 IN DNSKEY 257 3 5 AwEAAd0gb4uhOraiCsHKE6JjR6HKOeRq Ry8Nxj4cg2AmKtaSF78rmvN27vtU8tKD LUGtiGgg33pcAOp+bvtd9ACu5s//Dch0 MHJpCDHFGoR4WVLbqBz9isTs3DLVLxWQ luMKeo/Kxed7sR3fMyPxAP1+FFi3esdX xANsVur/h9gGI5WVNtyXhq+qkWqLX0Y6 Q0jGzIuDrd5I4cVrWOei1OM4xV53Gh6D h98lptCA2ek35RuW3tPb7zHGXF3s+Baf gq7H8QJjnWmcFJh8ACdmbT63afQchYWT oyWdWUOeSpm/Uu0JOcbodAUD4m44P1Ed V1hzwwrHQIFUfdyA6He8mBPxS1k=
+iinfo.cz. 600 IN RRSIG DNSKEY 5 2 600 20190528123437 20180528123437 21523 iinfo.cz. gK/B0ceILXhEGpXHL9o/0aAAw9FWKa8T 2775dB9FlzpfQsmmhedDY+swXpYpieXp nHtchHe0n0AiWjmQ4pYQ9f+ABX9/1w6e kmsQEQ4BH7oD2iHWFzCwEnjbGfE78nVx rcGyaq6VQ50yoRFn6KdVSvydtHtR7jtN 4cAzz9z6AgL41goi89SEUMB6XtA1puKZ yOq9QXXQ31bU/3pb9oitGIh8hrpaPnpC APLHMdNo9ixQCzdOY4zHXOYRoSkeoh0E skWuBDw9xaA3PpiAhW1YuWRqsM5ogn2T wF4NCOhQD8JP7o8jbCS75+KySaWILznl vapvUu8P//OVfLvb3KmQBA==
+iinfo.cz. 600 IN RRSIG DNSKEY 5 2 600 20190528123437 20180528123437 8130 iinfo.cz. uFrBPh3dsFIbmOE5m9VuHeuxhPEnNQE0 DwoeoZsre7RwSPWtqEvENypioV1goDIf 0cZmsNrK5Q5lgIBOo4rKug==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+adminit.cz. IN DNSKEY
+SECTION AUTHORITY
+adminit.cz. 600 IN SOA ns.adminit.cz. hostmaster.adminit.cz. 2018072003 10800 3600 604800 600
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH subdomain
+ADJUST copy_id copy_query
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+random1.blog.root.cz. IN NS
+SECTION ANSWER
+blog.root.cz. 600 IN CNAME root.cz.
+blog.root.cz. 600 IN RRSIG CNAME 5 3 600 20190528123431 20180528123431 8130 root.cz. DSHP4iTt49vRSsPjtBBxXj876UXSZukv 5Uko/B3GfLujWV/fOwZIQaHJTmfwzmT0 l4I+FSGkhwwHRQpCpqvzOQ==
+random1.blog.root.cz. 600 IN CNAME blog.root.cz.
+random1.blog.root.cz. 600 IN RRSIG CNAME 5 3 600 20190528123431 20180528123431 8130 root.cz. db6OwEqbgywxPO8tTqz/nh9yj1mY/hYZ KmHhH4HH1v2eH1wIU/S1jvD1ZHGAssVw xbh9LoY0x0mSPdCciX1WvQ==
+root.cz. 600 IN NS ns.iinfo.cz.
+root.cz. 600 IN NS ns6.adminit.cz.
+root.cz. 600 IN RRSIG NS 5 2 600 20190528123431 20180528123431 8130 root.cz. SXqkv2rcKBDAYKzsn3FL+2djE4ob+BbJ OjNcHcihIQFaCLHfvTpmh7bKDyDrtyBj xAB/EPVJWdn1Gvu8PUKGOA==
+SECTION AUTHORITY
+*.blog.root.cz. 600 IN NSEC blog-beta.root.cz. CNAME RRSIG NSEC
+*.blog.root.cz. 600 IN RRSIG NSEC 5 3 600 20190528123431 20180528123431 8130 root.cz. dq9cWL5b4ogXMDfVhICOc6uBAuV8YnlA +eNB09aH8vjwJlNtiKPZknER3foS8bVx OEhJrYXGtldnMFP3rLlcKA==
+SECTION ADDITIONAL
+ns.iinfo.cz. 360 IN A 91.213.160.5
+ns.iinfo.cz. 360 IN AAAA 2001:67c:68::5
+ns.iinfo.cz. 360 IN RRSIG A 5 3 360 20190528123437 20180528123437 8130 iinfo.cz. Rf//ObuX0E/s5d7Z1Ld0MjHa+q+tVdl8 GwY4pZTW7DHRivIEij+owDnmDNID62EB MpURuInEPV5FaF/9sT6X8A==
+ns.iinfo.cz. 360 IN RRSIG AAAA 5 3 360 20190528123437 20180528123437 8130 iinfo.cz. q5hoFF0ldADkVxxKTgXgh3RUL+JseejX tcUvRqaD+VTwbJO5J0Kl+tJufKw7tRVt EJP8opneZsIsKamQhdWrDg==
+ns6.adminit.cz. 600 IN A 46.101.163.95
+ns6.adminit.cz. 600 IN AAAA 2a03:b0c0:3:d0::4c:2001
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH subdomain
+ADJUST copy_id copy_query
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+blog.root.cz. IN NS
+SECTION ANSWER
+blog.root.cz. 600 IN CNAME root.cz.
+blog.root.cz. 600 IN RRSIG CNAME 5 3 600 20190528123431 20180528123431 8130 root.cz. DSHP4iTt49vRSsPjtBBxXj876UXSZukv 5Uko/B3GfLujWV/fOwZIQaHJTmfwzmT0 l4I+FSGkhwwHRQpCpqvzOQ==
+root.cz. 600 IN NS ns.iinfo.cz.
+root.cz. 600 IN NS ns6.adminit.cz.
+root.cz. 600 IN RRSIG NS 5 2 600 20190528123431 20180528123431 8130 root.cz. SXqkv2rcKBDAYKzsn3FL+2djE4ob+BbJ OjNcHcihIQFaCLHfvTpmh7bKDyDrtyBj xAB/EPVJWdn1Gvu8PUKGOA==
+SECTION ADDITIONAL
+ns.iinfo.cz. 360 IN A 91.213.160.5
+ns.iinfo.cz. 360 IN AAAA 2001:67c:68::5
+ns.iinfo.cz. 360 IN RRSIG A 5 3 360 20190528123437 20180528123437 8130 iinfo.cz. Rf//ObuX0E/s5d7Z1Ld0MjHa+q+tVdl8 GwY4pZTW7DHRivIEij+owDnmDNID62EB MpURuInEPV5FaF/9sT6X8A==
+ns.iinfo.cz. 360 IN RRSIG AAAA 5 3 360 20190528123437 20180528123437 8130 iinfo.cz. q5hoFF0ldADkVxxKTgXgh3RUL+JseejX tcUvRqaD+VTwbJO5J0Kl+tJufKw7tRVt EJP8opneZsIsKamQhdWrDg==
+ns6.adminit.cz. 600 IN A 46.101.163.95
+ns6.adminit.cz. 600 IN AAAA 2a03:b0c0:3:d0::4c:2001
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH subdomain
+ADJUST copy_id copy_query
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+root.cz. IN NS
+SECTION ANSWER
+root.cz. 600 IN NS ns.iinfo.cz.
+root.cz. 600 IN NS ns6.adminit.cz.
+root.cz. 600 IN RRSIG NS 5 2 600 20190528123431 20180528123431 8130 root.cz. SXqkv2rcKBDAYKzsn3FL+2djE4ob+BbJ OjNcHcihIQFaCLHfvTpmh7bKDyDrtyBj xAB/EPVJWdn1Gvu8PUKGOA==
+SECTION ADDITIONAL
+ns.iinfo.cz. 360 IN A 91.213.160.5
+ns.iinfo.cz. 360 IN AAAA 2001:67c:68::5
+ns.iinfo.cz. 360 IN RRSIG A 5 3 360 20190528123437 20180528123437 8130 iinfo.cz. Rf//ObuX0E/s5d7Z1Ld0MjHa+q+tVdl8 GwY4pZTW7DHRivIEij+owDnmDNID62EB MpURuInEPV5FaF/9sT6X8A==
+ns.iinfo.cz. 360 IN RRSIG AAAA 5 3 360 20190528123437 20180528123437 8130 iinfo.cz. q5hoFF0ldADkVxxKTgXgh3RUL+JseejX tcUvRqaD+VTwbJO5J0Kl+tJufKw7tRVt EJP8opneZsIsKamQhdWrDg==
+ns6.adminit.cz. 600 IN A 46.101.163.95
+ns6.adminit.cz. 600 IN AAAA 2a03:b0c0:3:d0::4c:2001
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH subdomain
+ADJUST copy_id copy_query
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+iinfo.cz. IN NS
+SECTION ANSWER
+iinfo.cz. 600 IN NS ns.iinfo.cz.
+iinfo.cz. 600 IN NS ns6.adminit.cz.
+iinfo.cz. 600 IN RRSIG NS 5 2 600 20190528123437 20180528123437 8130 iinfo.cz. pnOulEq9+lsY62m4J7rnsVL5JojezXVo BpX0aNCbJ/L4786RSE4no5KBZPfLvDns gmWQqT/WaMqYQTWQd/AfyA==
+SECTION ADDITIONAL
+ns.iinfo.cz. 360 IN A 91.213.160.5
+ns.iinfo.cz. 360 IN AAAA 2001:67c:68::5
+ns.iinfo.cz. 360 IN RRSIG A 5 3 360 20190528123437 20180528123437 8130 iinfo.cz. Rf//ObuX0E/s5d7Z1Ld0MjHa+q+tVdl8 GwY4pZTW7DHRivIEij+owDnmDNID62EB MpURuInEPV5FaF/9sT6X8A==
+ns.iinfo.cz. 360 IN RRSIG AAAA 5 3 360 20190528123437 20180528123437 8130 iinfo.cz. q5hoFF0ldADkVxxKTgXgh3RUL+JseejX tcUvRqaD+VTwbJO5J0Kl+tJufKw7tRVt EJP8opneZsIsKamQhdWrDg==
+ns6.adminit.cz. 600 IN A 46.101.163.95
+ns6.adminit.cz. 600 IN AAAA 2a03:b0c0:3:d0::4c:2001
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH subdomain
+ADJUST copy_id copy_query
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+adminit.cz. IN NS
+SECTION ANSWER
+adminit.cz. 600 IN NS ns.adminit.cz.
+adminit.cz. 600 IN NS ns.iinfo.cz.
+SECTION ADDITIONAL
+ns.adminit.cz. 600 IN A 89.185.231.140
+ns.iinfo.cz. 360 IN A 91.213.160.5
+ns.iinfo.cz. 360 IN AAAA 2001:67c:68::5
+ns.iinfo.cz. 360 IN RRSIG A 5 3 360 20190528123437 20180528123437 8130 iinfo.cz. Rf//ObuX0E/s5d7Z1Ld0MjHa+q+tVdl8 GwY4pZTW7DHRivIEij+owDnmDNID62EB MpURuInEPV5FaF/9sT6X8A==
+ns.iinfo.cz. 360 IN RRSIG AAAA 5 3 360 20190528123437 20180528123437 8130 iinfo.cz. q5hoFF0ldADkVxxKTgXgh3RUL+JseejX tcUvRqaD+VTwbJO5J0Kl+tJufKw7tRVt EJP8opneZsIsKamQhdWrDg==
+ENTRY_END
+
+
+RANGE_END
+
+
+; Scope "hm.
+
+; Server names:
+; ns1.registry.hm.
+; ns2.registry.hm.
+; ns3.registry.hm.
+RANGE_BEGIN 0 1000
+ ADDRESS 208.70.79.24
+ ADDRESS 208.70.79.25
+ ADDRESS 128.199.180.188
+ ADDRESS 1::1
+ ADDRESS 1::2
+ ADDRESS 1::3
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+hm. IN A
+SECTION AUTHORITY
+hm. 86400 IN SOA ns1.registry.hm. hostmaster.registry.hm. 2018072709 10800 600 6048000 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+hm. IN DS
+SECTION AUTHORITY
+hm. 86400 IN SOA ns1.registry.hm. hostmaster.registry.hm. 2018072709 10800 600 6048000 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+hm. IN AAAA
+SECTION AUTHORITY
+hm. 86400 IN SOA ns1.registry.hm. hostmaster.registry.hm. 2018072709 10800 600 6048000 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+registry.hm. IN A
+SECTION ANSWER
+registry.hm. 86400 IN A 208.70.79.55
+SECTION AUTHORITY
+registry.hm. 86400 IN NS ns1.registry.hm.
+registry.hm. 86400 IN NS ns2.registry.hm.
+registry.hm. 86400 IN NS ns3.registry.hm.
+SECTION ADDITIONAL
+ns1.registry.hm. 172800 IN A 208.70.79.25
+ns2.registry.hm. 172800 IN A 208.70.79.24
+ns3.registry.hm. 172800 IN A 128.199.180.188
+ns1.registry.hm. 172800 IN AAAA 1::1
+ns2.registry.hm. 172800 IN AAAA 1::2
+ns3.registry.hm. 172800 IN AAAA 1::3
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+registry.hm. IN DNSKEY
+SECTION AUTHORITY
+registry.hm. 3600 IN SOA ns1.registry.hm. hostmaster.registry.hm. 2015072302 10800 3600 604800 3600
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+registry.hm. IN DS
+SECTION AUTHORITY
+hm. 86400 IN SOA ns1.registry.hm. hostmaster.registry.hm. 2018072709 10800 600 6048000 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+ns1.registry.hm. IN A
+SECTION ANSWER
+ns1.registry.hm. 86400 IN A 208.70.79.25
+SECTION AUTHORITY
+registry.hm. 86400 IN NS ns1.registry.hm.
+registry.hm. 86400 IN NS ns2.registry.hm.
+registry.hm. 86400 IN NS ns3.registry.hm.
+SECTION ADDITIONAL
+ns1.registry.hm. 172800 IN A 208.70.79.25
+ns2.registry.hm. 172800 IN A 208.70.79.24
+ns3.registry.hm. 172800 IN A 128.199.180.188
+ns1.registry.hm. 172800 IN AAAA 1::1
+ns2.registry.hm. 172800 IN AAAA 1::2
+ns3.registry.hm. 172800 IN AAAA 1::3
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+ns1.registry.hm. IN DNSKEY
+SECTION AUTHORITY
+registry.hm. 3600 IN SOA ns1.registry.hm. hostmaster.registry.hm. 2015072302 10800 3600 604800 3600
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+ns1.registry.hm. IN NS
+SECTION AUTHORITY
+registry.hm. 3600 IN SOA ns1.registry.hm. hostmaster.registry.hm. 2015072302 10800 3600 604800 3600
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+ns1.registry.hm. IN DS
+SECTION AUTHORITY
+registry.hm. 3600 IN SOA ns1.registry.hm. hostmaster.registry.hm. 2015072302 10800 3600 604800 3600
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+ns1.registry.hm. IN AAAA
+SECTION AUTHORITY
+ns1.registry.hm. 86400 IN AAAA 1::1
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+hm. IN SOA
+SECTION ANSWER
+hm. 86400 IN SOA ns1.registry.hm. hostmaster.registry.hm. 2018072709 10800 600 6048000 86400
+SECTION AUTHORITY
+hm. 86400 IN NS ns1.registry.hm.
+hm. 86400 IN NS ns2.registry.hm.
+hm. 86400 IN NS ns3.registry.hm.
+SECTION ADDITIONAL
+ns1.registry.hm. 172800 IN A 208.70.79.25
+ns2.registry.hm. 172800 IN A 208.70.79.24
+ns3.registry.hm. 172800 IN A 128.199.180.188
+ns1.registry.hm. 172800 IN AAAA 1::1
+ns2.registry.hm. 172800 IN AAAA 1::2
+ns3.registry.hm. 172800 IN AAAA 1::3
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+ns2.registry.hm. IN A
+SECTION ANSWER
+ns2.registry.hm. 86400 IN A 208.70.79.24
+SECTION AUTHORITY
+registry.hm. 86400 IN NS ns1.registry.hm.
+registry.hm. 86400 IN NS ns2.registry.hm.
+registry.hm. 86400 IN NS ns3.registry.hm.
+SECTION ADDITIONAL
+ns1.registry.hm. 172800 IN A 208.70.79.25
+ns2.registry.hm. 172800 IN A 208.70.79.24
+ns3.registry.hm. 172800 IN A 128.199.180.188
+ns1.registry.hm. 172800 IN AAAA 1::1
+ns2.registry.hm. 172800 IN AAAA 1::2
+ns3.registry.hm. 172800 IN AAAA 1::3
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+ns2.registry.hm. IN DNSKEY
+SECTION AUTHORITY
+registry.hm. 3600 IN SOA ns1.registry.hm. hostmaster.registry.hm. 2015072302 10800 3600 604800 3600
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+ns2.registry.hm. IN NS
+SECTION AUTHORITY
+registry.hm. 3600 IN SOA ns1.registry.hm. hostmaster.registry.hm. 2015072302 10800 3600 604800 3600
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+ns2.registry.hm. IN DS
+SECTION AUTHORITY
+registry.hm. 3600 IN SOA ns1.registry.hm. hostmaster.registry.hm. 2015072302 10800 3600 604800 3600
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+ns2.registry.hm. IN AAAA
+SECTION AUTHORITY
+ns2.registry.hm. 86400 IN AAAA 1::2
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+ns3.registry.hm. IN A
+SECTION ANSWER
+ns3.registry.hm. 86400 IN A 128.199.180.188
+SECTION AUTHORITY
+registry.hm. 86400 IN NS ns1.registry.hm.
+registry.hm. 86400 IN NS ns2.registry.hm.
+registry.hm. 86400 IN NS ns3.registry.hm.
+SECTION ADDITIONAL
+ns1.registry.hm. 172800 IN A 208.70.79.25
+ns2.registry.hm. 172800 IN A 208.70.79.24
+ns3.registry.hm. 172800 IN A 128.199.180.188
+ns1.registry.hm. 172800 IN AAAA 1::1
+ns2.registry.hm. 172800 IN AAAA 1::2
+ns3.registry.hm. 172800 IN AAAA 1::3
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+ns3.registry.hm. IN DNSKEY
+SECTION AUTHORITY
+registry.hm. 3600 IN SOA ns1.registry.hm. hostmaster.registry.hm. 2015072302 10800 3600 604800 3600
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+ns3.registry.hm. IN NS
+SECTION AUTHORITY
+registry.hm. 3600 IN SOA ns1.registry.hm. hostmaster.registry.hm. 2015072302 10800 3600 604800 3600
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+ns3.registry.hm. IN DS
+SECTION AUTHORITY
+registry.hm. 3600 IN SOA ns1.registry.hm. hostmaster.registry.hm. 2015072302 10800 3600 604800 3600
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+ns3.registry.hm. IN AAAA
+SECTION AUTHORITY
+ns3.registry.hm. 86400 IN AAAA 1::3
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname qtype
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+hm. IN DNSKEY
+SECTION AUTHORITY
+hm. 86400 IN SOA ns1.registry.hm. hostmaster.registry.hm. 2018072709 10800 600 6048000 86400
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH subdomain
+ADJUST copy_id copy_query
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+registry.hm. IN NS
+SECTION ANSWER
+registry.hm. 86400 IN NS ns1.registry.hm.
+registry.hm. 86400 IN NS ns2.registry.hm.
+registry.hm. 86400 IN NS ns3.registry.hm.
+SECTION ADDITIONAL
+ns1.registry.hm. 172800 IN A 208.70.79.25
+ns2.registry.hm. 172800 IN A 208.70.79.24
+ns3.registry.hm. 172800 IN A 128.199.180.188
+ns1.registry.hm. 172800 IN AAAA 1::1
+ns2.registry.hm. 172800 IN AAAA 1::2
+ns3.registry.hm. 172800 IN AAAA 1::3
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH subdomain
+ADJUST copy_id copy_query
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+hm. IN NS
+SECTION ANSWER
+hm. 86400 IN NS ns1.registry.hm.
+hm. 86400 IN NS ns2.registry.hm.
+hm. 86400 IN NS ns3.registry.hm.
+SECTION ADDITIONAL
+ns1.registry.hm. 172800 IN A 208.70.79.25
+ns2.registry.hm. 172800 IN A 208.70.79.24
+ns3.registry.hm. 172800 IN A 128.199.180.188
+ns1.registry.hm. 172800 IN AAAA 1::1
+ns2.registry.hm. 172800 IN AAAA 1::2
+ns3.registry.hm. 172800 IN AAAA 1::3
+ENTRY_END
+
+
+RANGE_END
+
+
+
+; hm. DS in the root does not exist
+STEP 100 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+hm. IN DS
+ENTRY_END
+
+STEP 101 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH flags rcode question answer authority
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+hm. IN DS
+SECTION ANSWER
+SECTION AUTHORITY
+. 86400 IN RRSIG SOA 8 0 86400 20180809050000 20180727040000 41656 . zo+cNHA1N9Av53qwpB/bCmnTxAWj6ubo 58W4VkEPk9jzrOKvCm9dVJv7P+JJOX5C t5yx4zch+DBRSRR1U9mmrbegEX4hXtec L3Ev9ZpxYAYUFd7gQ/oM5ZyrUZ08wLYg pYV6vE4qYdxP58dtknbpGUQKz4H3l0SQ eWoSyhOtYK9nNovCNN0swXdkmogEhDxP gY1nhEZiLXFH8W8/G96IgAa2hineMnqV 0z8/K2m7EGjwszDOyCD05Z77cMAryvjL X6Jm7I83+D8UwtfAck8ZGDJFz3l+w08G oeB9ntD1OicidpLtHmeSsN+1nuEL3s1M U47kwIJMAHu8bcyvm4HGRw==
+. 86400 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018072700 1800 900 604800 86400
+hm. 86400 IN NSEC hn. NS RRSIG NSEC
+hm. 86400 IN RRSIG NSEC 8 1 86400 20180809050000 20180727040000 41656 . vI+rf8FDWlQOpAPeJTvoMH7bceC0qe2U hzdXApcCQK50pacs356TAcnKRKsNu+wa qR0+pM51vnG1AT+pPSK0M70soXrbh8uI TfFMV6u+/6qgU9TzzzQk49UK4Ww6m4l6 uh7/I302reJjTsc9mpCrjkRX7lk96c31 xzcYMlbADfzQsCfofoZDw7bS45mY6nRH /zTNUuEtFZGef0XtkNK9Op32Sf7Qqqqu YuzKBWa1irDaYCCLeyaqSmXQDzl7xKQa szrWtZeA1pwxJ2KKzCfuaYsRk/R6INLv i4tfJ73oKHl7nhKxH/K1fWUrWTuxkR1q R1zQb7VOg0Jf9GUqXxPVXg==
+ENTRY_END
+
+; negative cache in parent zone must not mask data in child
+STEP 102 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+hm. IN SOA
+ENTRY_END
+
+STEP 103 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH flags rcode question answer
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+hm. IN SOA
+SECTION ANSWER
+hm. 86400 IN SOA ns1.registry.hm. hostmaster.registry.hm. 2018072709 10800 600 6048000 86400
+ENTRY_END
+
+
+; fill new NSEC interval sk..ski
+STEP 200 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+sk2. IN DS
+ENTRY_END
+
+STEP 201 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH flags rcode question authority
+REPLY QR RD RA AD DO NXDOMAIN
+SECTION QUESTION
+sk2. IN DS
+SECTION AUTHORITY
+. 86400 IN NSEC aaa. NS SOA RRSIG NSEC DNSKEY
+. 86400 IN RRSIG NSEC 8 0 86400 20180809050000 20180727040000 41656 . CU1vfnY07l8A4bd60jFERRzilD9G1Glp Cx5l/o65fIh2fvCTt/pn4C1W1MfpHIOv j23gN/HS3m64+UE6lYPbJlrOcCLOslgK C+8tfmqWjDbI2C5jnDK0shibLIU2MW3L +0PxOZWOeU2a6XRUYYkqyI9jpfQIEDcZ fuQWiBXOtneXsLKNfQf4YxwC+WCxHGPu mc1g9hza83iziIfgmzxFU5Hg05HjAnni Uw4PL8sNrAZsv4sRZqtfoM6KHo84RCP+ Y2pIR97bPW0dspAtTjD9WAbTz0DpvC3f o3flnVlnWxdJhDEBRASUzAGc2d4FwzPO JdbCJNde9bc9VKSx1jEHpQ==
+. 86400 IN RRSIG SOA 8 0 86400 20180809050000 20180727040000 41656 . zo+cNHA1N9Av53qwpB/bCmnTxAWj6ubo 58W4VkEPk9jzrOKvCm9dVJv7P+JJOX5C t5yx4zch+DBRSRR1U9mmrbegEX4hXtec L3Ev9ZpxYAYUFd7gQ/oM5ZyrUZ08wLYg pYV6vE4qYdxP58dtknbpGUQKz4H3l0SQ eWoSyhOtYK9nNovCNN0swXdkmogEhDxP gY1nhEZiLXFH8W8/G96IgAa2hineMnqV 0z8/K2m7EGjwszDOyCD05Z77cMAryvjL X6Jm7I83+D8UwtfAck8ZGDJFz3l+w08G oeB9ntD1OicidpLtHmeSsN+1nuEL3s1M U47kwIJMAHu8bcyvm4HGRw==
+. 86400 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018072700 1800 900 604800 86400
+sk. 86400 IN NSEC ski. NS RRSIG NSEC
+sk. 86400 IN RRSIG NSEC 8 1 86400 20180809050000 20180727040000 41656 . Z7ihB8GIbqYBTvBPWxq22UkxSfJf/1I5 eIQ0E3cCVB+srJs2mECa3FmiPkzaYEZv mGzDNGlr5T2BHunJHWVED3gN6Y9Mn0YD 8v+0sIfPTTO74uWxHZFQsudZSzBqWaEI S2zHlM8VTiE6/x6QrAyDNIdjLSI5563X q/qVCsYxx10bRKIog4g73ZwBvlmwd1wa Rd/IIaEDCRO/ed6yFMOL5dhhMERrcJVY HdbNCpSb27LT4HFoqXtBMt1Z8VJVqDI3 NMojUq7a0JWMrFhBEiNwgNJ5xHCiiDuc 4nvszt1wiZAebsr8Qcniy4PrDDs+3XOg lBDRhozaOZYS436/Bs27Xw==
+ENTRY_END
+
+; deeper answers for interval sk..ski must be generated from cache
+STEP 202 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+deep.sk2. IN A
+ENTRY_END
+
+STEP 203 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH flags rcode question authority
+REPLY QR RD RA AD DO NXDOMAIN
+SECTION QUESTION
+deep.sk2. IN A
+SECTION AUTHORITY
+. 86400 IN NSEC aaa. NS SOA RRSIG NSEC DNSKEY
+. 86400 IN RRSIG NSEC 8 0 86400 20180809050000 20180727040000 41656 . CU1vfnY07l8A4bd60jFERRzilD9G1Glp Cx5l/o65fIh2fvCTt/pn4C1W1MfpHIOv j23gN/HS3m64+UE6lYPbJlrOcCLOslgK C+8tfmqWjDbI2C5jnDK0shibLIU2MW3L +0PxOZWOeU2a6XRUYYkqyI9jpfQIEDcZ fuQWiBXOtneXsLKNfQf4YxwC+WCxHGPu mc1g9hza83iziIfgmzxFU5Hg05HjAnni Uw4PL8sNrAZsv4sRZqtfoM6KHo84RCP+ Y2pIR97bPW0dspAtTjD9WAbTz0DpvC3f o3flnVlnWxdJhDEBRASUzAGc2d4FwzPO JdbCJNde9bc9VKSx1jEHpQ==
+. 86400 IN RRSIG SOA 8 0 86400 20180809050000 20180727040000 41656 . zo+cNHA1N9Av53qwpB/bCmnTxAWj6ubo 58W4VkEPk9jzrOKvCm9dVJv7P+JJOX5C t5yx4zch+DBRSRR1U9mmrbegEX4hXtec L3Ev9ZpxYAYUFd7gQ/oM5ZyrUZ08wLYg pYV6vE4qYdxP58dtknbpGUQKz4H3l0SQ eWoSyhOtYK9nNovCNN0swXdkmogEhDxP gY1nhEZiLXFH8W8/G96IgAa2hineMnqV 0z8/K2m7EGjwszDOyCD05Z77cMAryvjL X6Jm7I83+D8UwtfAck8ZGDJFz3l+w08G oeB9ntD1OicidpLtHmeSsN+1nuEL3s1M U47kwIJMAHu8bcyvm4HGRw==
+. 86400 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018072700 1800 900 604800 86400
+sk. 86400 IN NSEC ski. NS RRSIG NSEC
+sk. 86400 IN RRSIG NSEC 8 1 86400 20180809050000 20180727040000 41656 . Z7ihB8GIbqYBTvBPWxq22UkxSfJf/1I5 eIQ0E3cCVB+srJs2mECa3FmiPkzaYEZv mGzDNGlr5T2BHunJHWVED3gN6Y9Mn0YD 8v+0sIfPTTO74uWxHZFQsudZSzBqWaEI S2zHlM8VTiE6/x6QrAyDNIdjLSI5563X q/qVCsYxx10bRKIog4g73ZwBvlmwd1wa Rd/IIaEDCRO/ed6yFMOL5dhhMERrcJVY HdbNCpSb27LT4HFoqXtBMt1Z8VJVqDI3 NMojUq7a0JWMrFhBEiNwgNJ5xHCiiDuc 4nvszt1wiZAebsr8Qcniy4PrDDs+3XOg lBDRhozaOZYS436/Bs27Xw==
+ENTRY_END
+
+STEP 204 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+deeper.deep.sk2. IN DS
+ENTRY_END
+
+STEP 205 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH flags rcode question authority
+REPLY QR RD RA AD DO NXDOMAIN
+SECTION QUESTION
+deeper.deep.sk2. IN DS
+SECTION AUTHORITY
+. 86400 IN NSEC aaa. NS SOA RRSIG NSEC DNSKEY
+. 86400 IN RRSIG NSEC 8 0 86400 20180809050000 20180727040000 41656 . CU1vfnY07l8A4bd60jFERRzilD9G1Glp Cx5l/o65fIh2fvCTt/pn4C1W1MfpHIOv j23gN/HS3m64+UE6lYPbJlrOcCLOslgK C+8tfmqWjDbI2C5jnDK0shibLIU2MW3L +0PxOZWOeU2a6XRUYYkqyI9jpfQIEDcZ fuQWiBXOtneXsLKNfQf4YxwC+WCxHGPu mc1g9hza83iziIfgmzxFU5Hg05HjAnni Uw4PL8sNrAZsv4sRZqtfoM6KHo84RCP+ Y2pIR97bPW0dspAtTjD9WAbTz0DpvC3f o3flnVlnWxdJhDEBRASUzAGc2d4FwzPO JdbCJNde9bc9VKSx1jEHpQ==
+. 86400 IN RRSIG SOA 8 0 86400 20180809050000 20180727040000 41656 . zo+cNHA1N9Av53qwpB/bCmnTxAWj6ubo 58W4VkEPk9jzrOKvCm9dVJv7P+JJOX5C t5yx4zch+DBRSRR1U9mmrbegEX4hXtec L3Ev9ZpxYAYUFd7gQ/oM5ZyrUZ08wLYg pYV6vE4qYdxP58dtknbpGUQKz4H3l0SQ eWoSyhOtYK9nNovCNN0swXdkmogEhDxP gY1nhEZiLXFH8W8/G96IgAa2hineMnqV 0z8/K2m7EGjwszDOyCD05Z77cMAryvjL X6Jm7I83+D8UwtfAck8ZGDJFz3l+w08G oeB9ntD1OicidpLtHmeSsN+1nuEL3s1M U47kwIJMAHu8bcyvm4HGRw==
+. 86400 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018072700 1800 900 604800 86400
+sk. 86400 IN NSEC ski. NS RRSIG NSEC
+sk. 86400 IN RRSIG NSEC 8 1 86400 20180809050000 20180727040000 41656 . Z7ihB8GIbqYBTvBPWxq22UkxSfJf/1I5 eIQ0E3cCVB+srJs2mECa3FmiPkzaYEZv mGzDNGlr5T2BHunJHWVED3gN6Y9Mn0YD 8v+0sIfPTTO74uWxHZFQsudZSzBqWaEI S2zHlM8VTiE6/x6QrAyDNIdjLSI5563X q/qVCsYxx10bRKIog4g73ZwBvlmwd1wa Rd/IIaEDCRO/ed6yFMOL5dhhMERrcJVY HdbNCpSb27LT4HFoqXtBMt1Z8VJVqDI3 NMojUq7a0JWMrFhBEiNwgNJ5xHCiiDuc 4nvszt1wiZAebsr8Qcniy4PrDDs+3XOg lBDRhozaOZYS436/Bs27Xw==
+ENTRY_END
+
+; sk. DS record does not exist in root and this answer must be synthesized from cache as well
+STEP 206 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+sk. IN DS
+ENTRY_END
+
+STEP 207 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH flags rcode question authority
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+sk. IN DS
+SECTION AUTHORITY
+. 86400 IN RRSIG SOA 8 0 86400 20180809050000 20180727040000 41656 . zo+cNHA1N9Av53qwpB/bCmnTxAWj6ubo 58W4VkEPk9jzrOKvCm9dVJv7P+JJOX5C t5yx4zch+DBRSRR1U9mmrbegEX4hXtec L3Ev9ZpxYAYUFd7gQ/oM5ZyrUZ08wLYg pYV6vE4qYdxP58dtknbpGUQKz4H3l0SQ eWoSyhOtYK9nNovCNN0swXdkmogEhDxP gY1nhEZiLXFH8W8/G96IgAa2hineMnqV 0z8/K2m7EGjwszDOyCD05Z77cMAryvjL X6Jm7I83+D8UwtfAck8ZGDJFz3l+w08G oeB9ntD1OicidpLtHmeSsN+1nuEL3s1M U47kwIJMAHu8bcyvm4HGRw==
+. 86400 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018072700 1800 900 604800 86400
+sk. 86400 IN NSEC ski. NS RRSIG NSEC
+sk. 86400 IN RRSIG NSEC 8 1 86400 20180809050000 20180727040000 41656 . Z7ihB8GIbqYBTvBPWxq22UkxSfJf/1I5 eIQ0E3cCVB+srJs2mECa3FmiPkzaYEZv mGzDNGlr5T2BHunJHWVED3gN6Y9Mn0YD 8v+0sIfPTTO74uWxHZFQsudZSzBqWaEI S2zHlM8VTiE6/x6QrAyDNIdjLSI5563X q/qVCsYxx10bRKIog4g73ZwBvlmwd1wa Rd/IIaEDCRO/ed6yFMOL5dhhMERrcJVY HdbNCpSb27LT4HFoqXtBMt1Z8VJVqDI3 NMojUq7a0JWMrFhBEiNwgNJ5xHCiiDuc 4nvszt1wiZAebsr8Qcniy4PrDDs+3XOg lBDRhozaOZYS436/Bs27Xw==
+ENTRY_END
+
+
+; ask for type which does not exist
+STEP 400 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+root.cz. IN TYPE65535
+ENTRY_END
+
+STEP 401 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH flags rcode question
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+root.cz. IN TYPE65535
+ENTRY_END
+
+; ask for another type which does not exist
+; answer must be generated from cache (is not present in any RANGE)
+STEP 402 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+root.cz. IN TYPE65530
+ENTRY_END
+
+STEP 403 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH flags rcode question answer authority
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+root.cz. IN TYPE65530
+SECTION ANSWER
+SECTION AUTHORITY
+root.cz. 600 IN NSEC 10.root.cz. A NS SOA MX TXT AAAA RRSIG NSEC DNSKEY
+root.cz. 600 IN RRSIG NSEC 5 2 600 20190528123431 20180528123431 8130 root.cz. zyNxcRCooKSKBrLYS+o8ZXZXqN+OakCK 3/A06vZsprPaKyy1Q67Zu7J8I1WW0faX SB5Zvv7ka+TeoE4HfYZmQQ==
+root.cz. 600 IN RRSIG SOA 5 2 600 20190528123431 20180528123431 8130 root.cz. BEf0O/YUhGy6Xoh15SYLu5K/BKmlOW/x g39vk0ficFELb7FYzHUEKghXaSCAtjzL 41ZhRQqB6yHXMBSxujHxeA==
+root.cz. 600 IN SOA ns.iinfo.cz. hostmaster.iinfo.cz. 2018052801 86400 3600 3600000 600
+ENTRY_END
+
+; synthesized answer must not block other data at the same node
+STEP 405 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+root.cz. IN A
+ENTRY_END
+
+STEP 406 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH flags rcode question answer
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+root.cz. IN A
+SECTION ANSWER
+root.cz. 600 IN A 91.213.160.118
+ENTRY_END
+
+; fill cache with *.blog.root.cz. CNAME
+STEP 501 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+random1.blog.root.cz. IN A
+ENTRY_END
+
+STEP 502 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH flags rcode question answer
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+random1.blog.root.cz. IN A
+SECTION ANSWER
+blog.root.cz. 600 IN CNAME root.cz.
+random1.blog.root.cz. 600 IN CNAME blog.root.cz.
+root.cz. 600 IN A 91.213.160.118
+ENTRY_END
+
+; test final NODATA answer from wildcard
+STEP 503 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+random1.blog.root.cz. IN TYPE65535
+ENTRY_END
+
+STEP 504 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH flags rcode question answer
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+random1.blog.root.cz. IN TYPE65535
+SECTION ANSWER
+blog.root.cz. 600 IN CNAME root.cz.
+random1.blog.root.cz. 600 IN CNAME blog.root.cz.
+ENTRY_END
+
+; complete answer must be synthesized from wildcard
+STEP 505 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+random2.blog.root.cz. IN A
+ENTRY_END
+
+STEP 506 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH flags rcode question answer authority
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+random2.blog.root.cz. IN A
+SECTION ANSWER
+blog.root.cz. 600 IN CNAME root.cz.
+blog.root.cz. 600 IN RRSIG CNAME 5 3 600 20190528123431 20180528123431 8130 root.cz. DSHP4iTt49vRSsPjtBBxXj876UXSZukv 5Uko/B3GfLujWV/fOwZIQaHJTmfwzmT0 l4I+FSGkhwwHRQpCpqvzOQ==
+random2.blog.root.cz. 600 IN CNAME blog.root.cz.
+random2.blog.root.cz. 600 IN RRSIG CNAME 5 3 600 20190528123431 20180528123431 8130 root.cz. db6OwEqbgywxPO8tTqz/nh9yj1mY/hYZ KmHhH4HH1v2eH1wIU/S1jvD1ZHGAssVw xbh9LoY0x0mSPdCciX1WvQ==
+root.cz. 600 IN A 91.213.160.118
+root.cz. 600 IN RRSIG A 5 2 600 20190528123431 20180528123431 8130 root.cz. VbfAvnvnwmW04evIkjQTSeJN5J9Gtfum 2m13VOQCetKK01G4h5yS18qS5Yl4dZQh zftnYpQ1WJlkM6a3RXAgPw==
+SECTION AUTHORITY
+*.blog.root.cz. 600 IN NSEC blog-beta.root.cz. CNAME RRSIG NSEC
+*.blog.root.cz. 600 IN RRSIG NSEC 5 3 600 20190528123431 20180528123431 8130 root.cz. dq9cWL5b4ogXMDfVhICOc6uBAuV8YnlA +eNB09aH8vjwJlNtiKPZknER3foS8bVx OEhJrYXGtldnMFP3rLlcKA==
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/nsec_name_error_response-part2.rpl b/tests/integration/deckard/sets/resolver/nsec_name_error_response-part2.rpl
new file mode 100644
index 0000000..7aa0a43
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/nsec_name_error_response-part2.rpl
@@ -0,0 +1,229 @@
+do-ip6: no
+
+; config options
+;server:
+ trust-anchor: ". 3600 IN DS 17272 13 4 B87AD8C76DC2244E7AA57285057BF533F2E248CC8D7E1A071D8A3837A711A5EA705C4707E6E8911DA653BE1AE019927B"
+ val-override-timestamp: "1442323400"
+ do-not-query-localhost: off
+
+;stub-zone:
+; name: "."
+ stub-addr: 127.0.0.1 # ns.
+CONFIG_END
+
+SCENARIO_BEGIN Test validation of NSEC name error responses.
+
+; ns.
+RANGE_BEGIN 0 100
+ ADDRESS 127.0.0.1
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. 3600 IN NS ns.
+. 3600 IN RRSIG NS 13 0 3600 20151014142315 20150914142315 17272 . aEIYUS4S8Hd7vAVYvHwFyV97lKx4xt2PgAUbM4A7JUXHkTJDHUQEDVQh LWGxK6e+AUeuq4qlDo4vSz3IedmOBQ==
+SECTION ADDITIONAL
+ns. 3600 IN A 127.0.0.1
+ns. 3600 IN RRSIG A 13 1 3600 20151014142315 20150914142315 17272 . 27h0pFJyb5t/2cZsFjynp0TRIdUlQwPYcAwCer2UbXTiBBaD8n15hfh8 PFU0if8X0ikqHusz6rCNTx/aBraYdQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+. IN DNSKEY
+SECTION ANSWER
+. 3600 IN DNSKEY 256 3 13 qKlBZ0TvdY8C8+7bTcdnQdrLZxEwvxEwlGmIOTd/ccL5Jiei1whNktoE /Qzo1lJ0cXfVssy4EVMaqEdzIa+pkA==
+. 3600 IN RRSIG DNSKEY 13 0 3600 20151014142315 20150914142315 17272 . FaY+kslqSPIRZsk65z8SrROt7kfx+RGUEBGbVgLQxKruJxc9+MMrl4e4 +RefYIlwpecj4jXwb75RTbT0g7OGGg==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example. IN MX
+SECTION AUTHORITY
+example. 3600 IN NS ns.example.
+example. 3600 IN DS 11225 13 4 B4BDAB0B3751300BFB9D0D240649279B4BA0E67A308E1B0BFE2931D9 47F7FD71A2BD807D84CDE24286D955A35752484F
+example. 3600 IN RRSIG DS 13 1 3600 20151014143533 20150914143533 17272 . b0+fXKmsBBXkzf+Myr5eRsXWDvY75oMlr4Yi5j+3iF7cOviVGKz3Dw8u bfKW+OmyHiuTeL71gez/84P+vHEvHA==
+SECTION ADDITIONAL
+ns.example. 3600 IN A 127.0.0.2
+ENTRY_END
+
+RANGE_END
+
+; ns.example.
+RANGE_BEGIN 0 100
+ ADDRESS 127.0.0.2
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+example. IN NS
+SECTION ANSWER
+example. 3600 IN NS ns.example.
+example. 3600 IN RRSIG NS 13 1 3600 20151014143225 20150914143225 11225 example. C6KOyVJzeRh/3KL9BxSVOVZN0RIyBhlBmmmnVEFT5qPUrn3m5FjcIBtI hi7cAl2FeY1rqstztvKAY6UOBE0kGQ==
+SECTION ADDITIONAL
+ns.example. 3600 IN A 127.0.0.2
+ns.example. 3600 IN RRSIG A 13 2 3600 20151014143225 20150914143225 11225 example. fM/mwUOtyIbKTxgxaekZf5A8kV3qYIFADtvhcQi0TUh09nfkHQtUqhew zVBXCEtjKMnYFvNhWF6PyiirtOeM8w==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+example. IN DNSKEY
+SECTION ANSWER
+example. 3600 IN DNSKEY 256 3 13 d9Qb4Tj90Y2cvdWcZfu45clfoLKqGbJn2vQKqZv07nc4FMf2oRkrNXtP fixVTLfbbWAFtbbFf3mhCNUsetRUVQ==
+example. 3600 IN RRSIG DNSKEY 13 1 3600 20151015124839 20150915124839 11225 example. 4DemFjvys9Gfq+gG1i8IB6GPBUw9lIv3F082JwW7O8tqNIn45n2z14gg ieeJTRhU9xXOVIfj6amITZWbjvGyFA==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+nsec.example. IN MX
+SECTION AUTHORITY
+nsec.example. 3600 IN NS ns.nsec.example.
+nsec.example. 3600 IN DS 54343 13 4 90ABD4FB9F053CF67F6D838DD2437FB16104B8BF127319706223004F 2ED72AF2872B4E507EB483A303BF60BF08C87364
+nsec.example. 3600 IN RRSIG DS 13 2 3600 20151015124611 20150915124611 11225 example. HYzlEdyYugggsEwUVyyY4XHFVUZZ8yiIh4vnuViGBQQJP+yryYh1aLyN ap2Q51nkmSG1fXDb2IySiAYuqUJyLw==
+SECTION ADDITIONAL
+ns.nsec.example. 3600 IN A 127.0.0.3
+ENTRY_END
+
+RANGE_END
+
+; ns.nsec.example.
+RANGE_BEGIN 0 100
+ ADDRESS 127.0.0.3
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+nsec.example. IN NS
+SECTION ANSWER
+nsec.example. 3600 IN NS ns.nsec.example.
+nsec.example. 3600 IN RRSIG NS 13 2 3600 20151015124917 20150915124917 54343 nsec.example. 6s75LEuylIKAxqAbcPmmnkOMC7jxF6cPZGW5EFbhOOeR63ENyh642GE1 71WtJc7Ta4Y/PsnAT+/dTv8NSTDCHQ==
+SECTION ADDITIONAL
+ns.nsec.example. 3600 IN A 127.0.0.3
+ns.nsec.example. 3600 IN RRSIG A 13 3 3600 20151015124917 20150915124917 54343 nsec.example. oJpF87bjXR0DjIoNvEAo+Wu+p9jF+URX5lxi+g53OFCX1Q1lxqj5ujGd KOPsNAbKvTCsoFFW4tQyhCYJYD1HlQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+nsec.example. IN DNSKEY
+SECTION ANSWER
+nsec.example. 3600 IN DNSKEY 256 3 13 HA6nKf+X7/mYkmmRO8qS2tIKT0B60P7COAiRs25xKs/rAP+tDtGWkrkG NQx2D3ajccC9whjRaKz2JVS3ItTFQg==
+nsec.example. 3600 IN RRSIG DNSKEY 13 2 3600 20151015124917 20150915124917 54343 nsec.example. 965Mfxs1QtgxwzyhfxXyKyOZ9iT1DXpvypBBR10sLyjHe/w7cRhgcyev Cza6K+2jJwHJBmbknc3Qhi+1dd+AJw==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NXDOMAIN
+SECTION QUESTION
+aaa.nsec.example. IN MX
+SECTION AUTHORITY
+nsec.example. 3600 IN SOA ns.nsec.example. root.nsec.example. 2 60 60 120 3600
+nsec.example. 3600 IN NSEC alias.nsec.example. A NS SOA MX AAAA RRSIG NSEC DNSKEY
+nsec.example. 3600 IN RRSIG SOA 13 2 3600 20151015124917 20150915124917 54343 nsec.example. AcjIOhRgJMRILo06O2yl/G4Q6gTuA0NIGpnejpgcoVHg8kZy6xmURhTc kYf//qbx/WPB9k+8j+ymmQPe1phJCQ==
+nsec.example. 3600 IN RRSIG NSEC 13 2 3600 20151015124917 20150915124917 54343 nsec.example. STcV7Lc1a794i9DTgflI+d0N0KXTMws0G8VGc0Wo4tVI8lvFJcG1SFXW /jJaXkQstdZ2EM63fIs/u1hhBaV2Gw==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NXDOMAIN
+SECTION QUESTION
+missing.nsec.example. IN MX
+SECTION AUTHORITY
+nsec.example. 3600 IN SOA ns.nsec.example. root.nsec.example. 2 60 60 120 3600
+mail.nsec.example. 3600 IN NSEC multiple.nsec.example. A AAAA RRSIG NSEC
+nsec.example. 3600 IN NSEC alias.nsec.example. A NS SOA MX AAAA RRSIG NSEC DNSKEY
+nsec.example. 3600 IN RRSIG SOA 13 2 3600 20151015124917 20150915124917 54343 nsec.example. AcjIOhRgJMRILo06O2yl/G4Q6gTuA0NIGpnejpgcoVHg8kZy6xmURhTc kYf//qbx/WPB9k+8j+ymmQPe1phJCQ==
+mail.nsec.example. 3600 IN RRSIG NSEC 13 3 3600 20151015124917 20150915124917 54343 nsec.example. kM+Z63RDn377szwbOqPPinkH98BuCljY7hoeM8jGJcnQ90fA3NFi72Jg k/0T1bo4r0cNMn6lm9OUotawa6BOqw==
+nsec.example. 3600 IN RRSIG NSEC 13 2 3600 20151015124917 20150915124917 54343 nsec.example. STcV7Lc1a794i9DTgflI+d0N0KXTMws0G8VGc0Wo4tVI8lvFJcG1SFXW /jJaXkQstdZ2EM63fIs/u1hhBaV2Gw==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NXDOMAIN
+SECTION QUESTION
+missing1.nsec.example. IN MX
+SECTION AUTHORITY
+nsec.example. 3600 IN SOA ns.nsec.example. root.nsec.example. 2 60 60 120 3600
+nsec.example. 3600 IN NSEC alias.nsec.example. A NS SOA MX AAAA RRSIG NSEC DNSKEY
+nsec.example. 3600 IN RRSIG SOA 13 2 3600 20151015124917 20150915124917 54343 nsec.example. AcjIOhRgJMRILo06O2yl/G4Q6gTuA0NIGpnejpgcoVHg8kZy6xmURhTc kYf//qbx/WPB9k+8j+ymmQPe1phJCQ==
+nsec.example. 3600 IN RRSIG NSEC 13 2 3600 20151015124917 20150915124917 54343 nsec.example. STcV7Lc1a794i9DTgflI+d0N0KXTMws0G8VGc0Wo4tVI8lvFJcG1SFXW /jJaXkQstdZ2EM63fIs/u1hhBaV2Gw==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NXDOMAIN
+SECTION QUESTION
+missing2.nsec.example. IN MX
+SECTION AUTHORITY
+nsec.example. 3600 IN SOA ns.nsec.example. root.nsec.example. 2 60 60 120 3600
+mail.nsec.example. 3600 IN NSEC multiple.nsec.example. A AAAA RRSIG NSEC
+nsec.example. 3600 IN RRSIG SOA 13 2 3600 20151015124917 20150915124917 54343 nsec.example. AcjIOhRgJMRILo06O2yl/G4Q6gTuA0NIGpnejpgcoVHg8kZy6xmURhTc kYf//qbx/WPB9k+8j+ymmQPe1phJCQ==
+mail.nsec.example. 3600 IN RRSIG NSEC 13 3 3600 20151015124917 20150915124917 54343 nsec.example. kM+Z63RDn377szwbOqPPinkH98BuCljY7hoeM8jGJcnQ90fA3NFi72Jg k/0T1bo4r0cNMn6lm9OUotawa6BOqw==
+ENTRY_END
+
+RANGE_END
+
+;STEP 0 TIME_PASSES ELAPSE 1000
+
+
+
+STEP 5 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+missing1.nsec.example. IN MX
+ENTRY_END
+
+STEP 6 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+ADJUST copy_id
+REPLY QR RD RA SERVFAIL
+SECTION QUESTION
+missing1.nsec.example. IN MX
+SECTION AUTHORITY
+ENTRY_END
+
+STEP 7 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+missing2.nsec.example. IN MX
+ENTRY_END
+
+STEP 8 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+ADJUST copy_id
+REPLY QR RD RA SERVFAIL
+SECTION QUESTION
+missing2.nsec.example. IN MX
+SECTION AUTHORITY
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/nsec_name_error_response.rpl b/tests/integration/deckard/sets/resolver/nsec_name_error_response.rpl
new file mode 100644
index 0000000..95e6784
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/nsec_name_error_response.rpl
@@ -0,0 +1,242 @@
+do-ip6: no
+
+; config options
+;server:
+ trust-anchor: ". 3600 IN DS 17272 13 4 B87AD8C76DC2244E7AA57285057BF533F2E248CC8D7E1A071D8A3837A711A5EA705C4707E6E8911DA653BE1AE019927B"
+ val-override-timestamp: "1442323400"
+ do-not-query-localhost: off
+
+;stub-zone:
+; name: "."
+ stub-addr: 127.0.0.1 # ns.
+CONFIG_END
+
+SCENARIO_BEGIN Test validation of NSEC name error responses.
+
+; ns.
+RANGE_BEGIN 0 100
+ ADDRESS 127.0.0.1
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. 3600 IN NS ns.
+. 3600 IN RRSIG NS 13 0 3600 20151014142315 20150914142315 17272 . aEIYUS4S8Hd7vAVYvHwFyV97lKx4xt2PgAUbM4A7JUXHkTJDHUQEDVQh LWGxK6e+AUeuq4qlDo4vSz3IedmOBQ==
+SECTION ADDITIONAL
+ns. 3600 IN A 127.0.0.1
+ns. 3600 IN RRSIG A 13 1 3600 20151014142315 20150914142315 17272 . 27h0pFJyb5t/2cZsFjynp0TRIdUlQwPYcAwCer2UbXTiBBaD8n15hfh8 PFU0if8X0ikqHusz6rCNTx/aBraYdQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+. IN DNSKEY
+SECTION ANSWER
+. 3600 IN DNSKEY 256 3 13 qKlBZ0TvdY8C8+7bTcdnQdrLZxEwvxEwlGmIOTd/ccL5Jiei1whNktoE /Qzo1lJ0cXfVssy4EVMaqEdzIa+pkA==
+. 3600 IN RRSIG DNSKEY 13 0 3600 20151014142315 20150914142315 17272 . FaY+kslqSPIRZsk65z8SrROt7kfx+RGUEBGbVgLQxKruJxc9+MMrl4e4 +RefYIlwpecj4jXwb75RTbT0g7OGGg==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example. IN MX
+SECTION AUTHORITY
+example. 3600 IN NS ns.example.
+example. 3600 IN DS 11225 13 4 B4BDAB0B3751300BFB9D0D240649279B4BA0E67A308E1B0BFE2931D9 47F7FD71A2BD807D84CDE24286D955A35752484F
+example. 3600 IN RRSIG DS 13 1 3600 20151014143533 20150914143533 17272 . b0+fXKmsBBXkzf+Myr5eRsXWDvY75oMlr4Yi5j+3iF7cOviVGKz3Dw8u bfKW+OmyHiuTeL71gez/84P+vHEvHA==
+SECTION ADDITIONAL
+ns.example. 3600 IN A 127.0.0.2
+ENTRY_END
+
+RANGE_END
+
+; ns.example.
+RANGE_BEGIN 0 100
+ ADDRESS 127.0.0.2
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+example. IN NS
+SECTION ANSWER
+example. 3600 IN NS ns.example.
+example. 3600 IN RRSIG NS 13 1 3600 20151014143225 20150914143225 11225 example. C6KOyVJzeRh/3KL9BxSVOVZN0RIyBhlBmmmnVEFT5qPUrn3m5FjcIBtI hi7cAl2FeY1rqstztvKAY6UOBE0kGQ==
+SECTION ADDITIONAL
+ns.example. 3600 IN A 127.0.0.2
+ns.example. 3600 IN RRSIG A 13 2 3600 20151014143225 20150914143225 11225 example. fM/mwUOtyIbKTxgxaekZf5A8kV3qYIFADtvhcQi0TUh09nfkHQtUqhew zVBXCEtjKMnYFvNhWF6PyiirtOeM8w==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+example. IN DNSKEY
+SECTION ANSWER
+example. 3600 IN DNSKEY 256 3 13 d9Qb4Tj90Y2cvdWcZfu45clfoLKqGbJn2vQKqZv07nc4FMf2oRkrNXtP fixVTLfbbWAFtbbFf3mhCNUsetRUVQ==
+example. 3600 IN RRSIG DNSKEY 13 1 3600 20151015124839 20150915124839 11225 example. 4DemFjvys9Gfq+gG1i8IB6GPBUw9lIv3F082JwW7O8tqNIn45n2z14gg ieeJTRhU9xXOVIfj6amITZWbjvGyFA==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+nsec.example. IN MX
+SECTION AUTHORITY
+nsec.example. 3600 IN NS ns.nsec.example.
+nsec.example. 3600 IN DS 54343 13 4 90ABD4FB9F053CF67F6D838DD2437FB16104B8BF127319706223004F 2ED72AF2872B4E507EB483A303BF60BF08C87364
+nsec.example. 3600 IN RRSIG DS 13 2 3600 20151015124611 20150915124611 11225 example. HYzlEdyYugggsEwUVyyY4XHFVUZZ8yiIh4vnuViGBQQJP+yryYh1aLyN ap2Q51nkmSG1fXDb2IySiAYuqUJyLw==
+SECTION ADDITIONAL
+ns.nsec.example. 3600 IN A 127.0.0.3
+ENTRY_END
+
+RANGE_END
+
+; ns.nsec.example.
+RANGE_BEGIN 0 100
+ ADDRESS 127.0.0.3
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+nsec.example. IN NS
+SECTION ANSWER
+nsec.example. 3600 IN NS ns.nsec.example.
+nsec.example. 3600 IN RRSIG NS 13 2 3600 20151015124917 20150915124917 54343 nsec.example. 6s75LEuylIKAxqAbcPmmnkOMC7jxF6cPZGW5EFbhOOeR63ENyh642GE1 71WtJc7Ta4Y/PsnAT+/dTv8NSTDCHQ==
+SECTION ADDITIONAL
+ns.nsec.example. 3600 IN A 127.0.0.3
+ns.nsec.example. 3600 IN RRSIG A 13 3 3600 20151015124917 20150915124917 54343 nsec.example. oJpF87bjXR0DjIoNvEAo+Wu+p9jF+URX5lxi+g53OFCX1Q1lxqj5ujGd KOPsNAbKvTCsoFFW4tQyhCYJYD1HlQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+nsec.example. IN DNSKEY
+SECTION ANSWER
+nsec.example. 3600 IN DNSKEY 256 3 13 HA6nKf+X7/mYkmmRO8qS2tIKT0B60P7COAiRs25xKs/rAP+tDtGWkrkG NQx2D3ajccC9whjRaKz2JVS3ItTFQg==
+nsec.example. 3600 IN RRSIG DNSKEY 13 2 3600 20151015124917 20150915124917 54343 nsec.example. 965Mfxs1QtgxwzyhfxXyKyOZ9iT1DXpvypBBR10sLyjHe/w7cRhgcyev Cza6K+2jJwHJBmbknc3Qhi+1dd+AJw==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NXDOMAIN
+SECTION QUESTION
+aaa.nsec.example. IN MX
+SECTION AUTHORITY
+nsec.example. 3600 IN SOA ns.nsec.example. root.nsec.example. 2 60 60 120 3600
+nsec.example. 3600 IN NSEC alias.nsec.example. A NS SOA MX AAAA RRSIG NSEC DNSKEY
+nsec.example. 3600 IN RRSIG SOA 13 2 3600 20151015124917 20150915124917 54343 nsec.example. AcjIOhRgJMRILo06O2yl/G4Q6gTuA0NIGpnejpgcoVHg8kZy6xmURhTc kYf//qbx/WPB9k+8j+ymmQPe1phJCQ==
+nsec.example. 3600 IN RRSIG NSEC 13 2 3600 20151015124917 20150915124917 54343 nsec.example. STcV7Lc1a794i9DTgflI+d0N0KXTMws0G8VGc0Wo4tVI8lvFJcG1SFXW /jJaXkQstdZ2EM63fIs/u1hhBaV2Gw==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NXDOMAIN
+SECTION QUESTION
+missing.nsec.example. IN MX
+SECTION AUTHORITY
+nsec.example. 3600 IN SOA ns.nsec.example. root.nsec.example. 2 60 60 120 3600
+mail.nsec.example. 3600 IN NSEC multiple.nsec.example. A AAAA RRSIG NSEC
+nsec.example. 3600 IN NSEC alias.nsec.example. A NS SOA MX AAAA RRSIG NSEC DNSKEY
+nsec.example. 3600 IN RRSIG SOA 13 2 3600 20151015124917 20150915124917 54343 nsec.example. AcjIOhRgJMRILo06O2yl/G4Q6gTuA0NIGpnejpgcoVHg8kZy6xmURhTc kYf//qbx/WPB9k+8j+ymmQPe1phJCQ==
+mail.nsec.example. 3600 IN RRSIG NSEC 13 3 3600 20151015124917 20150915124917 54343 nsec.example. kM+Z63RDn377szwbOqPPinkH98BuCljY7hoeM8jGJcnQ90fA3NFi72Jg k/0T1bo4r0cNMn6lm9OUotawa6BOqw==
+nsec.example. 3600 IN RRSIG NSEC 13 2 3600 20151015124917 20150915124917 54343 nsec.example. STcV7Lc1a794i9DTgflI+d0N0KXTMws0G8VGc0Wo4tVI8lvFJcG1SFXW /jJaXkQstdZ2EM63fIs/u1hhBaV2Gw==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NXDOMAIN
+SECTION QUESTION
+missing1.nsec.example. IN MX
+SECTION AUTHORITY
+nsec.example. 3600 IN SOA ns.nsec.example. root.nsec.example. 2 60 60 120 3600
+nsec.example. 3600 IN NSEC alias.nsec.example. A NS SOA MX AAAA RRSIG NSEC DNSKEY
+nsec.example. 3600 IN RRSIG SOA 13 2 3600 20151015124917 20150915124917 54343 nsec.example. AcjIOhRgJMRILo06O2yl/G4Q6gTuA0NIGpnejpgcoVHg8kZy6xmURhTc kYf//qbx/WPB9k+8j+ymmQPe1phJCQ==
+nsec.example. 3600 IN RRSIG NSEC 13 2 3600 20151015124917 20150915124917 54343 nsec.example. STcV7Lc1a794i9DTgflI+d0N0KXTMws0G8VGc0Wo4tVI8lvFJcG1SFXW /jJaXkQstdZ2EM63fIs/u1hhBaV2Gw==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NXDOMAIN
+SECTION QUESTION
+missing2.nsec.example. IN MX
+SECTION AUTHORITY
+nsec.example. 3600 IN SOA ns.nsec.example. root.nsec.example. 2 60 60 120 3600
+mail.nsec.example. 3600 IN NSEC multiple.nsec.example. A AAAA RRSIG NSEC
+nsec.example. 3600 IN RRSIG SOA 13 2 3600 20151015124917 20150915124917 54343 nsec.example. AcjIOhRgJMRILo06O2yl/G4Q6gTuA0NIGpnejpgcoVHg8kZy6xmURhTc kYf//qbx/WPB9k+8j+ymmQPe1phJCQ==
+mail.nsec.example. 3600 IN RRSIG NSEC 13 3 3600 20151015124917 20150915124917 54343 nsec.example. kM+Z63RDn377szwbOqPPinkH98BuCljY7hoeM8jGJcnQ90fA3NFi72Jg k/0T1bo4r0cNMn6lm9OUotawa6BOqw==
+ENTRY_END
+
+RANGE_END
+
+;STEP 0 TIME_PASSES ELAPSE 1000
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+aaa.nsec.example. IN MX
+ENTRY_END
+
+; recursion happens here.
+STEP 2 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+ADJUST copy_id
+REPLY QR RD RA AD NXDOMAIN
+SECTION QUESTION
+aaa.nsec.example. IN MX
+SECTION AUTHORITY
+nsec.example. 3600 IN SOA ns.nsec.example. root.nsec.example. 2 60 60 120 3600
+nsec.example. 3600 IN NSEC alias.nsec.example. A NS SOA MX AAAA RRSIG NSEC DNSKEY
+nsec.example. 3600 IN RRSIG SOA 13 2 3600 20151015124917 20150915124917 54343 nsec.example. AcjIOhRgJMRILo06O2yl/G4Q6gTuA0NIGpnejpgcoVHg8kZy6xmURhTc kYf//qbx/WPB9k+8j+ymmQPe1phJCQ==
+nsec.example. 3600 IN RRSIG NSEC 13 2 3600 20151015124917 20150915124917 54343 nsec.example. STcV7Lc1a794i9DTgflI+d0N0KXTMws0G8VGc0Wo4tVI8lvFJcG1SFXW /jJaXkQstdZ2EM63fIs/u1hhBaV2Gw==
+ENTRY_END
+
+STEP 3 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+missing.nsec.example. IN MX
+ENTRY_END
+
+STEP 4 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+ADJUST copy_id
+REPLY QR RD RA AD NXDOMAIN
+SECTION QUESTION
+missing.nsec.example. IN MX
+SECTION AUTHORITY
+nsec.example. 3600 IN SOA ns.nsec.example. root.nsec.example. 2 60 60 120 3600
+mail.nsec.example. 3600 IN NSEC multiple.nsec.example. A AAAA RRSIG NSEC
+nsec.example. 3600 IN NSEC alias.nsec.example. A NS SOA MX AAAA RRSIG NSEC DNSKEY
+nsec.example. 3600 IN RRSIG SOA 13 2 3600 20151015124917 20150915124917 54343 nsec.example. AcjIOhRgJMRILo06O2yl/G4Q6gTuA0NIGpnejpgcoVHg8kZy6xmURhTc kYf//qbx/WPB9k+8j+ymmQPe1phJCQ==
+mail.nsec.example. 3600 IN RRSIG NSEC 13 3 3600 20151015124917 20150915124917 54343 nsec.example. kM+Z63RDn377szwbOqPPinkH98BuCljY7hoeM8jGJcnQ90fA3NFi72Jg k/0T1bo4r0cNMn6lm9OUotawa6BOqw==
+nsec.example. 3600 IN RRSIG NSEC 13 2 3600 20151015124917 20150915124917 54343 nsec.example. STcV7Lc1a794i9DTgflI+d0N0KXTMws0G8VGc0Wo4tVI8lvFJcG1SFXW /jJaXkQstdZ2EM63fIs/u1hhBaV2Gw==
+ENTRY_END
+
+;; TODO: use INCLUDE when it's available.
+;; Aggressive cache can answer STEP 5 and 7 without asking,
+;; from the record in previous answer, as `missing*` is between `mail` and `multiple`.
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/nsec_no_data_response.rpl b/tests/integration/deckard/sets/resolver/nsec_no_data_response.rpl
new file mode 100644
index 0000000..07c4a84
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/nsec_no_data_response.rpl
@@ -0,0 +1,203 @@
+do-ip6: no
+
+; config options
+;server:
+ trust-anchor: ". 3600 IN DS 17272 13 4 B87AD8C76DC2244E7AA57285057BF533F2E248CC8D7E1A071D8A3837A711A5EA705C4707E6E8911DA653BE1AE019927B"
+ val-override-timestamp: "1442839270"
+ do-not-query-localhost: off
+
+;stub-zone:
+; name: "."
+ stub-addr: 127.0.0.1 # ns.
+CONFIG_END
+
+SCENARIO_BEGIN Test validation of NSEC name error responses.
+
+; ns.
+RANGE_BEGIN 0 100
+ ADDRESS 127.0.0.1
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. 3600 IN NS ns.
+. 3600 IN RRSIG NS 13 0 3600 20151014142315 20150914142315 17272 . aEIYUS4S8Hd7vAVYvHwFyV97lKx4xt2PgAUbM4A7JUXHkTJDHUQEDVQh LWGxK6e+AUeuq4qlDo4vSz3IedmOBQ==
+SECTION ADDITIONAL
+ns. 3600 IN A 127.0.0.1
+ns. 3600 IN RRSIG A 13 1 3600 20151014142315 20150914142315 17272 . 27h0pFJyb5t/2cZsFjynp0TRIdUlQwPYcAwCer2UbXTiBBaD8n15hfh8 PFU0if8X0ikqHusz6rCNTx/aBraYdQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+. IN DNSKEY
+SECTION ANSWER
+. 3600 IN DNSKEY 256 3 13 qKlBZ0TvdY8C8+7bTcdnQdrLZxEwvxEwlGmIOTd/ccL5Jiei1whNktoE /Qzo1lJ0cXfVssy4EVMaqEdzIa+pkA==
+. 3600 IN RRSIG DNSKEY 13 0 3600 20151014142315 20150914142315 17272 . FaY+kslqSPIRZsk65z8SrROt7kfx+RGUEBGbVgLQxKruJxc9+MMrl4e4 +RefYIlwpecj4jXwb75RTbT0g7OGGg==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example. IN NS
+SECTION AUTHORITY
+example. 3600 IN NS ns.example.
+example. 3600 IN DS 11225 13 4 B4BDAB0B3751300BFB9D0D240649279B4BA0E67A308E1B0BFE2931D9 47F7FD71A2BD807D84CDE24286D955A35752484F
+example. 3600 IN RRSIG DS 13 1 3600 20151014143533 20150914143533 17272 . b0+fXKmsBBXkzf+Myr5eRsXWDvY75oMlr4Yi5j+3iF7cOviVGKz3Dw8u bfKW+OmyHiuTeL71gez/84P+vHEvHA==
+SECTION ADDITIONAL
+ns.example. 3600 IN A 127.0.0.2
+ENTRY_END
+
+RANGE_END
+
+; ns.example.
+RANGE_BEGIN 0 100
+ ADDRESS 127.0.0.2
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+example. IN NS
+SECTION ANSWER
+example. 3600 IN NS ns.example.
+example. 3600 IN RRSIG NS 13 1 3600 20151014143225 20150914143225 11225 example. C6KOyVJzeRh/3KL9BxSVOVZN0RIyBhlBmmmnVEFT5qPUrn3m5FjcIBtI hi7cAl2FeY1rqstztvKAY6UOBE0kGQ==
+SECTION ADDITIONAL
+ns.example. 3600 IN A 127.0.0.2
+ns.example. 3600 IN RRSIG A 13 2 3600 20151014143225 20150914143225 11225 example. fM/mwUOtyIbKTxgxaekZf5A8kV3qYIFADtvhcQi0TUh09nfkHQtUqhew zVBXCEtjKMnYFvNhWF6PyiirtOeM8w==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+example. IN DNSKEY
+SECTION ANSWER
+example. 3600 IN DNSKEY 256 3 13 d9Qb4Tj90Y2cvdWcZfu45clfoLKqGbJn2vQKqZv07nc4FMf2oRkrNXtP fixVTLfbbWAFtbbFf3mhCNUsetRUVQ==
+example. 3600 IN RRSIG DNSKEY 13 1 3600 20151015124839 20150915124839 11225 example. 4DemFjvys9Gfq+gG1i8IB6GPBUw9lIv3F082JwW7O8tqNIn45n2z14gg ieeJTRhU9xXOVIfj6amITZWbjvGyFA==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+nsec.example. IN CNAME
+SECTION AUTHORITY
+nsec.example. 3600 IN NS ns.nsec.example.
+nsec.example. 3600 IN DS 54343 13 4 90ABD4FB9F053CF67F6D838DD2437FB16104B8BF127319706223004F 2ED72AF2872B4E507EB483A303BF60BF08C87364
+nsec.example. 3600 IN RRSIG DS 13 2 3600 20151015124611 20150915124611 11225 example. HYzlEdyYugggsEwUVyyY4XHFVUZZ8yiIh4vnuViGBQQJP+yryYh1aLyN ap2Q51nkmSG1fXDb2IySiAYuqUJyLw==
+SECTION ADDITIONAL
+ns.nsec.example. 3600 IN A 127.0.0.3
+ENTRY_END
+
+RANGE_END
+
+; ns.nsec.example.
+RANGE_BEGIN 0 100
+ ADDRESS 127.0.0.3
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+nsec.example. IN NS
+SECTION ANSWER
+nsec.example. 3600 IN NS ns.nsec.example.
+nsec.example. 3600 IN RRSIG NS 13 2 3600 20151015124917 20150915124917 54343 nsec.example. 6s75LEuylIKAxqAbcPmmnkOMC7jxF6cPZGW5EFbhOOeR63ENyh642GE1 71WtJc7Ta4Y/PsnAT+/dTv8NSTDCHQ==
+SECTION ADDITIONAL
+ns.nsec.example. 3600 IN A 127.0.0.3
+ns.nsec.example. 3600 IN RRSIG A 13 3 3600 20151015124917 20150915124917 54343 nsec.example. oJpF87bjXR0DjIoNvEAo+Wu+p9jF+URX5lxi+g53OFCX1Q1lxqj5ujGd KOPsNAbKvTCsoFFW4tQyhCYJYD1HlQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+nsec.example. IN DNSKEY
+SECTION ANSWER
+nsec.example. 3600 IN DNSKEY 256 3 13 HA6nKf+X7/mYkmmRO8qS2tIKT0B60P7COAiRs25xKs/rAP+tDtGWkrkG NQx2D3ajccC9whjRaKz2JVS3ItTFQg==
+nsec.example. 3600 IN RRSIG DNSKEY 13 2 3600 20151015124917 20150915124917 54343 nsec.example. 965Mfxs1QtgxwzyhfxXyKyOZ9iT1DXpvypBBR10sLyjHe/w7cRhgcyev Cza6K+2jJwHJBmbknc3Qhi+1dd+AJw==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+nsec.example. IN CNAME
+SECTION AUTHORITY
+nsec.example. 3600 IN SOA ns.nsec.example. root.nsec.example. 6 60 60 120 3600
+nsec.example. 3600 IN NSEC alias.nsec.example. A NS SOA MX AAAA RRSIG NSEC DNSKEY
+nsec.example. 3600 IN RRSIG SOA 13 2 3600 20151017113144 20150917113144 54343 nsec.example. /3orb3cezQbBCZsFP9rx6Col9AB2QxHQtzQ32BYe09MfN7YZxtTE/HZJ aSXGWD3D7sLBdEkg8TGP8JPQtbW2yQ==
+nsec.example. 3600 IN RRSIG NSEC 13 2 3600 20151015124917 20150915124917 54343 nsec.example. STcV7Lc1a794i9DTgflI+d0N0KXTMws0G8VGc0Wo4tVI8lvFJcG1SFXW /jJaXkQstdZ2EM63fIs/u1hhBaV2Gw==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+nsec.example. IN TYPE1000
+SECTION AUTHORITY
+nsec.example. 3600 IN SOA ns.nsec.example. root.nsec.example. 6 60 60 120 3600
+nsec.example. 3600 IN RRSIG SOA 13 2 3600 20151017113144 20150917113144 54343 nsec.example. /3orb3cezQbBCZsFP9rx6Col9AB2QxHQtzQ32BYe09MfN7YZxtTE/HZJ aSXGWD3D7sLBdEkg8TGP8JPQtbW2yQ==
+ENTRY_END
+
+RANGE_END
+
+;STEP 0 TIME_PASSES ELAPSE 1000
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+nsec.example. IN CNAME
+ENTRY_END
+
+; recursion happens here.
+STEP 2 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+ADJUST copy_id
+REPLY QR RD RA AD NOERROR
+SECTION QUESTION
+nsec.example. IN CNAME
+SECTION AUTHORITY
+nsec.example. 3600 IN SOA ns.nsec.example. root.nsec.example. 6 60 60 120 3600
+nsec.example. 3600 IN NSEC alias.nsec.example. A NS SOA MX AAAA RRSIG NSEC DNSKEY
+nsec.example. 3600 IN RRSIG SOA 13 2 3600 20151017113144 20150917113144 54343 nsec.example. /3orb3cezQbBCZsFP9rx6Col9AB2QxHQtzQ32BYe09MfN7YZxtTE/HZJ aSXGWD3D7sLBdEkg8TGP8JPQtbW2yQ==
+nsec.example. 3600 IN RRSIG NSEC 13 2 3600 20151015124917 20150915124917 54343 nsec.example. STcV7Lc1a794i9DTgflI+d0N0KXTMws0G8VGc0Wo4tVI8lvFJcG1SFXW /jJaXkQstdZ2EM63fIs/u1hhBaV2Gw==
+ENTRY_END
+
+; TODO: aggressive caching can return the same answer as in STEP 2, without asking again.
+;STEP 3 QUERY
+;ENTRY_BEGIN
+;REPLY RD DO
+;SECTION QUESTION
+;nsec.example. IN TYPE1000
+;ENTRY_END
+;
+;STEP 4 CHECK_ANSWER
+;ENTRY_BEGIN
+;MATCH all
+;ADJUST copy_id
+;REPLY QR RD RA SERVFAIL
+;SECTION QUESTION
+;nsec.example. IN TYPE1000
+;SECTION AUTHORITY
+;ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/nsec_ref_to_unsigned1.rpl b/tests/integration/deckard/sets/resolver/nsec_ref_to_unsigned1.rpl
new file mode 100644
index 0000000..4ea5f5c
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/nsec_ref_to_unsigned1.rpl
@@ -0,0 +1,198 @@
+do-ip6: no
+
+; config options
+; The island of trust is at example.com
+;server:
+ trust-anchor: "example.com. IN DS 438 10 2 33F8133EB48EDB093839E985600EB7B7009EB5AC312D11CCA9007F6B 71D94D7B"
+ val-override-date: "20160308103040"
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+ query-minimization: off
+CONFIG_END
+
+SCENARIO_BEGIN NSEC, referral to unsigned subzone, no ds, nsec.
+
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA SERVFAIL
+SECTION QUESTION
+ns.example.com. IN A
+SECTION ANSWER
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA SERVFAIL
+SECTION QUESTION
+ns.example.com. IN AAAA
+SECTION ANSWER
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. 3600 IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 10 2 3600 20251231235959 20160308093040 2843 example.com. boNVuXxyhW+Gmiu+4ip1QQvIGqFNVsFfg1v+ywgc4+37ieQ5t+qJsHVm fJITRZrJxYQ6T/MkZKhpxLCemgFeKU6syWwoCfypnGino2G1urvqThna WTImSPhY/QsOj1ALy51d9Q+Mb5vt69XJt6SQvtNf6imepIFOT6CPSfjx BJ4=
+SECTION ADDITIONAL
+ns.example.com. 3600 IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 10 3 3600 20251231235959 20160308093040 2843 example.com. VSq+DkxJYr9Z+uh3KgpyPNwtuim4WVXnTdhRW7HX90CP5tyOVjDDTehA UmCxB8iFjUFE3hlwDx0Y71g+8Oso1t0JGkvDtWf5RDx1w+4K/1pQ2JMG lZTh7juaGJzXtltxqBoY67z1FBp9MI59O0hkABtz1CElj9LrhDr9wQa4 OUo=
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+a.sub.example.com. IN A
+SECTION AUTHORITY
+sub.example.com. 3600 IN NS ns.sub.example.com.
+sub.example.com. 3600 IN NSEC example.com. NS RRSIG NSEC
+sub.example.com. 3600 IN RRSIG NSEC 10 3 18000 20251231235959 20160308093040 2843 example.com. extoqd9mqaALMQf5kY5deuxZDL6INjsEKEUSfDibHTEAdNxfnmOJ9wcf hfpQfmgFLUAHsN0V/YB8qq6JhzkEkMV9f7BI/nZpuKCbSHo4ZOEUTflX mGM+VRBQc8gb25K03N0nwb6AvueSVA1PRizrRpQm/wvVWfDNZ+rM/lO6 +i4=
+SECTION ADDITIONAL
+ns.sub.example.com. 3600 IN A 1.2.3.10
+ENTRY_END
+
+; response to DNSKEY priming query
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+example.com. IN DNSKEY
+SECTION ANSWER
+example.com. 3600 IN DNSKEY 256 3 10 AwEAAcOHC7D2ZcG5M6MK5If/60+vvBM67BC8qUx04f6Kcvhx9GBMIMYz 87m6m2P5WKafW5AN1K9jY37m2fU/TdACQNzqu4wyVsOQefke/v2fgswg NgneP/C7cpyBVuK+8BUHjrorfLORClD3mbQMQldaaO2h6+OArAGHlFNI oFsuCjyR
+example.com. 3600 IN DNSKEY 257 3 10 AwEAAc4VCSEu1C1lAxuZMC8tSyissZNXC2lgS3zNvAvFdLtAsSbhB1cj dLCtTWUv1Ki/T+iWn10iemLQJ0S6z8wK+a7maC3ELZP1qoSFln+FiAsZ xYK72/XDEYMMp01F0gxgzZ2alWx3WKm2mELXf/ezEx+7X2ZNbwum5TKt FxtvotmT
+example.com. 3600 IN RRSIG DNSKEY 10 2 3600 20251231235959 20160308093040 438 example.com. cas8JKwtLUIItwOgrDrDG9pSkqiYw3r+8vyvt962kjHFBNG0D7AeegaO GMSWRziqA4L8xdgP750rLR5CRFQ9oPQlr/RWnsebGdJ3Yohwwa04HE6n OvR+o0u0oqNQ+P5KinxVKSv0Ru+BVMPHRDfIXN/FD5p9+nvIrnjXQlI3 vvM=
+example.com. 3600 IN RRSIG DNSKEY 10 2 3600 20251231235959 20160308093040 2843 example.com. uDLTMMTvJCcetKr6THEJ8Rn0gMLPFZTbOGJBZyZ2E5F9KkPSS01Nm6/P e+j0R3ObYXodqnZIY19fzXJKS2dJktoXkqNLBW/SpWTlFzpfHKCvTbJS VLrJ/lrEunE5cgSAqBrbAAuJrFpX/gaavqokElnUv1Mki2agTH1dTZyn X8M=
+SECTION AUTHORITY
+example.com. 3600 IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 10 2 3600 20251231235959 20160308093040 2843 example.com. boNVuXxyhW+Gmiu+4ip1QQvIGqFNVsFfg1v+ywgc4+37ieQ5t+qJsHVm fJITRZrJxYQ6T/MkZKhpxLCemgFeKU6syWwoCfypnGino2G1urvqThna WTImSPhY/QsOj1ALy51d9Q+Mb5vt69XJt6SQvtNf6imepIFOT6CPSfjx BJ4=
+SECTION ADDITIONAL
+ns.example.com. 3600 IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 10 3 3600 20251231235959 20160308093040 2843 example.com. VSq+DkxJYr9Z+uh3KgpyPNwtuim4WVXnTdhRW7HX90CP5tyOVjDDTehA UmCxB8iFjUFE3hlwDx0Y71g+8Oso1t0JGkvDtWf5RDx1w+4K/1pQ2JMG lZTh7juaGJzXtltxqBoY67z1FBp9MI59O0hkABtz1CElj9LrhDr9wQa4 OUo=
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+sub.example.com. IN DS
+SECTION AUTHORITY
+example.com. 3600 IN SOA ns.example.com. hostmaster.example.com. 2016022600 28800 7200 604800 18000
+example.com. 3600 IN RRSIG SOA 10 2 3600 20251231235959 20160308093040 2843 example.com. s3pCq6ZK3DEUkWYX3XKvr5v9Z4AhbJ4P7/AKQkhe3zymnTba7Bo5Uhmb Vav/A+u8gsoo9yBumReXLAv047btO+jdCOLD/yXvmaSt/yGGcipFoX6r 4kQWzUHby4NlQEdO3YykiZx7FtCGsMp0cfwPae4glkDsAPnIhhQurzzE VP4=
+sub.example.com. 3600 IN NSEC example.com. NS RRSIG NSEC
+sub.example.com. 3600 IN RRSIG NSEC 10 3 18000 20251231235959 20160308093040 2843 example.com. extoqd9mqaALMQf5kY5deuxZDL6INjsEKEUSfDibHTEAdNxfnmOJ9wcf hfpQfmgFLUAHsN0V/YB8qq6JhzkEkMV9f7BI/nZpuKCbSHo4ZOEUTflX mGM+VRBQc8gb25K03N0nwb6AvueSVA1PRizrRpQm/wvVWfDNZ+rM/lO6 +i4=
+ENTRY_END
+RANGE_END
+
+; ns.sub.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.10
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+sub.example.com. IN NS
+SECTION ANSWER
+sub.example.com. 3600 IN NS ns.sub.example.com.
+SECTION ADDITIONAL
+ns.sub.example.com. 3600 IN A 1.2.3.10
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+a.sub.example.com. IN A
+SECTION ANSWER
+a.sub.example.com. 3600 IN A 1.2.3.11
+ENTRY_END
+
+RANGE_END
+
+STEP 10 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+a.sub.example.com. IN A
+ENTRY_END
+
+STEP 20 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH opcode qname flags rcode question answer
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+a.sub.example.com. IN A
+SECTION ANSWER
+a.sub.example.com. 3600 IN A 1.2.3.11
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/nsec_ref_to_unsigned2.rpl b/tests/integration/deckard/sets/resolver/nsec_ref_to_unsigned2.rpl
new file mode 100644
index 0000000..4a0208a
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/nsec_ref_to_unsigned2.rpl
@@ -0,0 +1,199 @@
+do-ip6: no
+
+; config options
+; The island of trust is at example.com
+;server:
+ trust-anchor: "example.com. IN DS 438 10 2 33F8133EB48EDB093839E985600EB7B7009EB5AC312D11CCA9007F6B 71D94D7B"
+ val-override-date: "20160308103040"
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+ query-minimization: off
+CONFIG_END
+
+SCENARIO_BEGIN NSEC, referral to unsigned subzone, no ds, no nsec, ds soa.
+
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA SERVFAIL
+SECTION QUESTION
+ns.example.com. IN A
+SECTION ANSWER
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA SERVFAIL
+SECTION QUESTION
+ns.example.com. IN AAAA
+SECTION ANSWER
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. 3600 IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 10 2 3600 20251231235959 20160308093040 2843 example.com. boNVuXxyhW+Gmiu+4ip1QQvIGqFNVsFfg1v+ywgc4+37ieQ5t+qJsHVm fJITRZrJxYQ6T/MkZKhpxLCemgFeKU6syWwoCfypnGino2G1urvqThna WTImSPhY/QsOj1ALy51d9Q+Mb5vt69XJt6SQvtNf6imepIFOT6CPSfjx BJ4=
+SECTION ADDITIONAL
+ns.example.com. 3600 IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 10 3 3600 20251231235959 20160308093040 2843 example.com. VSq+DkxJYr9Z+uh3KgpyPNwtuim4WVXnTdhRW7HX90CP5tyOVjDDTehA UmCxB8iFjUFE3hlwDx0Y71g+8Oso1t0JGkvDtWf5RDx1w+4K/1pQ2JMG lZTh7juaGJzXtltxqBoY67z1FBp9MI59O0hkABtz1CElj9LrhDr9wQa4 OUo=
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+a.sub.example.com. IN A
+SECTION AUTHORITY
+sub.example.com. 3600 IN NS ns.sub.example.com.
+; no ds, no nsec
+;sub.example.com. 3600 IN NSEC example.com. NS RRSIG NSEC
+;sub.example.com. 3600 IN RRSIG NSEC 10 3 18000 20251231235959 20160308093040 2843 example.com. extoqd9mqaALMQf5kY5deuxZDL6INjsEKEUSfDibHTEAdNxfnmOJ9wcf hfpQfmgFLUAHsN0V/YB8qq6JhzkEkMV9f7BI/nZpuKCbSHo4ZOEUTflX mGM+VRBQc8gb25K03N0nwb6AvueSVA1PRizrRpQm/wvVWfDNZ+rM/lO6 +i4=
+SECTION ADDITIONAL
+ns.sub.example.com. 3600 IN A 1.2.3.10
+ENTRY_END
+
+; response to DNSKEY priming query
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+example.com. IN DNSKEY
+SECTION ANSWER
+example.com. 3600 IN DNSKEY 256 3 10 AwEAAcOHC7D2ZcG5M6MK5If/60+vvBM67BC8qUx04f6Kcvhx9GBMIMYz 87m6m2P5WKafW5AN1K9jY37m2fU/TdACQNzqu4wyVsOQefke/v2fgswg NgneP/C7cpyBVuK+8BUHjrorfLORClD3mbQMQldaaO2h6+OArAGHlFNI oFsuCjyR
+example.com. 3600 IN DNSKEY 257 3 10 AwEAAc4VCSEu1C1lAxuZMC8tSyissZNXC2lgS3zNvAvFdLtAsSbhB1cj dLCtTWUv1Ki/T+iWn10iemLQJ0S6z8wK+a7maC3ELZP1qoSFln+FiAsZ xYK72/XDEYMMp01F0gxgzZ2alWx3WKm2mELXf/ezEx+7X2ZNbwum5TKt FxtvotmT
+example.com. 3600 IN RRSIG DNSKEY 10 2 3600 20251231235959 20160308093040 438 example.com. cas8JKwtLUIItwOgrDrDG9pSkqiYw3r+8vyvt962kjHFBNG0D7AeegaO GMSWRziqA4L8xdgP750rLR5CRFQ9oPQlr/RWnsebGdJ3Yohwwa04HE6n OvR+o0u0oqNQ+P5KinxVKSv0Ru+BVMPHRDfIXN/FD5p9+nvIrnjXQlI3 vvM=
+example.com. 3600 IN RRSIG DNSKEY 10 2 3600 20251231235959 20160308093040 2843 example.com. uDLTMMTvJCcetKr6THEJ8Rn0gMLPFZTbOGJBZyZ2E5F9KkPSS01Nm6/P e+j0R3ObYXodqnZIY19fzXJKS2dJktoXkqNLBW/SpWTlFzpfHKCvTbJS VLrJ/lrEunE5cgSAqBrbAAuJrFpX/gaavqokElnUv1Mki2agTH1dTZyn X8M=
+SECTION AUTHORITY
+example.com. 3600 IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 10 2 3600 20251231235959 20160308093040 2843 example.com. boNVuXxyhW+Gmiu+4ip1QQvIGqFNVsFfg1v+ywgc4+37ieQ5t+qJsHVm fJITRZrJxYQ6T/MkZKhpxLCemgFeKU6syWwoCfypnGino2G1urvqThna WTImSPhY/QsOj1ALy51d9Q+Mb5vt69XJt6SQvtNf6imepIFOT6CPSfjx BJ4=
+SECTION ADDITIONAL
+ns.example.com. 3600 IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 10 3 3600 20251231235959 20160308093040 2843 example.com. VSq+DkxJYr9Z+uh3KgpyPNwtuim4WVXnTdhRW7HX90CP5tyOVjDDTehA UmCxB8iFjUFE3hlwDx0Y71g+8Oso1t0JGkvDtWf5RDx1w+4K/1pQ2JMG lZTh7juaGJzXtltxqBoY67z1FBp9MI59O0hkABtz1CElj9LrhDr9wQa4 OUo=
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+sub.example.com. IN DS
+SECTION AUTHORITY
+example.com. 3600 IN SOA ns.example.com. hostmaster.example.com. 2016022600 28800 7200 604800 18000
+example.com. 3600 IN RRSIG SOA 10 2 3600 20251231235959 20160308093040 2843 example.com. s3pCq6ZK3DEUkWYX3XKvr5v9Z4AhbJ4P7/AKQkhe3zymnTba7Bo5Uhmb Vav/A+u8gsoo9yBumReXLAv047btO+jdCOLD/yXvmaSt/yGGcipFoX6r 4kQWzUHby4NlQEdO3YykiZx7FtCGsMp0cfwPae4glkDsAPnIhhQurzzE VP4=
+sub.example.com. 3600 IN NSEC example.com. NS RRSIG NSEC
+sub.example.com. 3600 IN RRSIG NSEC 10 3 18000 20251231235959 20160308093040 2843 example.com. extoqd9mqaALMQf5kY5deuxZDL6INjsEKEUSfDibHTEAdNxfnmOJ9wcf hfpQfmgFLUAHsN0V/YB8qq6JhzkEkMV9f7BI/nZpuKCbSHo4ZOEUTflX mGM+VRBQc8gb25K03N0nwb6AvueSVA1PRizrRpQm/wvVWfDNZ+rM/lO6 +i4=
+ENTRY_END
+RANGE_END
+
+; ns.sub.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.10
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+sub.example.com. IN NS
+SECTION ANSWER
+sub.example.com. 3600 IN NS ns.sub.example.com.
+SECTION ADDITIONAL
+ns.sub.example.com. 3600 IN A 1.2.3.10
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+a.sub.example.com. IN A
+SECTION ANSWER
+a.sub.example.com. 3600 IN A 1.2.3.11
+ENTRY_END
+
+RANGE_END
+
+STEP 10 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+a.sub.example.com. IN A
+ENTRY_END
+
+STEP 20 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH opcode qname flags rcode question answer
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+a.sub.example.com. IN A
+SECTION ANSWER
+a.sub.example.com. 3600 IN A 1.2.3.11
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/nsec_ref_to_unsigned3.rpl b/tests/integration/deckard/sets/resolver/nsec_ref_to_unsigned3.rpl
new file mode 100644
index 0000000..cc23a31
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/nsec_ref_to_unsigned3.rpl
@@ -0,0 +1,199 @@
+do-ip6: no
+
+; config options
+; The island of trust is at example.com
+;server:
+ trust-anchor: "example.com. IN DS 438 10 2 33F8133EB48EDB093839E985600EB7B7009EB5AC312D11CCA9007F6B 71D94D7B"
+ val-override-date: "20160308103040"
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+ query-minimization: off
+CONFIG_END
+
+SCENARIO_BEGIN NSEC, referral to unsigned subzone, no ds, no nsec, bad ds soa.
+
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA SERVFAIL
+SECTION QUESTION
+ns.example.com. IN A
+SECTION ANSWER
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA SERVFAIL
+SECTION QUESTION
+ns.example.com. IN AAAA
+SECTION ANSWER
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. 3600 IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 10 2 3600 20251231235959 20160308093040 2843 example.com. boNVuXxyhW+Gmiu+4ip1QQvIGqFNVsFfg1v+ywgc4+37ieQ5t+qJsHVm fJITRZrJxYQ6T/MkZKhpxLCemgFeKU6syWwoCfypnGino2G1urvqThna WTImSPhY/QsOj1ALy51d9Q+Mb5vt69XJt6SQvtNf6imepIFOT6CPSfjx BJ4=
+SECTION ADDITIONAL
+ns.example.com. 3600 IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 10 3 3600 20251231235959 20160308093040 2843 example.com. VSq+DkxJYr9Z+uh3KgpyPNwtuim4WVXnTdhRW7HX90CP5tyOVjDDTehA UmCxB8iFjUFE3hlwDx0Y71g+8Oso1t0JGkvDtWf5RDx1w+4K/1pQ2JMG lZTh7juaGJzXtltxqBoY67z1FBp9MI59O0hkABtz1CElj9LrhDr9wQa4 OUo=
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+a.sub.example.com. IN A
+SECTION AUTHORITY
+sub.example.com. 3600 IN NS ns.sub.example.com.
+; no ds, no nsec
+;sub.example.com. 3600 IN NSEC example.com. NS RRSIG NSEC
+;sub.example.com. 3600 IN RRSIG NSEC 10 3 18000 20251231235959 20160308093040 2843 example.com. extoqd9mqaALMQf5kY5deuxZDL6INjsEKEUSfDibHTEAdNxfnmOJ9wcf hfpQfmgFLUAHsN0V/YB8qq6JhzkEkMV9f7BI/nZpuKCbSHo4ZOEUTflX mGM+VRBQc8gb25K03N0nwb6AvueSVA1PRizrRpQm/wvVWfDNZ+rM/lO6 +i4=
+SECTION ADDITIONAL
+ns.sub.example.com. 3600 IN A 1.2.3.10
+ENTRY_END
+
+; response to DNSKEY priming query
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+example.com. IN DNSKEY
+SECTION ANSWER
+example.com. 3600 IN DNSKEY 256 3 10 AwEAAcOHC7D2ZcG5M6MK5If/60+vvBM67BC8qUx04f6Kcvhx9GBMIMYz 87m6m2P5WKafW5AN1K9jY37m2fU/TdACQNzqu4wyVsOQefke/v2fgswg NgneP/C7cpyBVuK+8BUHjrorfLORClD3mbQMQldaaO2h6+OArAGHlFNI oFsuCjyR
+example.com. 3600 IN DNSKEY 257 3 10 AwEAAc4VCSEu1C1lAxuZMC8tSyissZNXC2lgS3zNvAvFdLtAsSbhB1cj dLCtTWUv1Ki/T+iWn10iemLQJ0S6z8wK+a7maC3ELZP1qoSFln+FiAsZ xYK72/XDEYMMp01F0gxgzZ2alWx3WKm2mELXf/ezEx+7X2ZNbwum5TKt FxtvotmT
+example.com. 3600 IN RRSIG DNSKEY 10 2 3600 20251231235959 20160308093040 438 example.com. cas8JKwtLUIItwOgrDrDG9pSkqiYw3r+8vyvt962kjHFBNG0D7AeegaO GMSWRziqA4L8xdgP750rLR5CRFQ9oPQlr/RWnsebGdJ3Yohwwa04HE6n OvR+o0u0oqNQ+P5KinxVKSv0Ru+BVMPHRDfIXN/FD5p9+nvIrnjXQlI3 vvM=
+example.com. 3600 IN RRSIG DNSKEY 10 2 3600 20251231235959 20160308093040 2843 example.com. uDLTMMTvJCcetKr6THEJ8Rn0gMLPFZTbOGJBZyZ2E5F9KkPSS01Nm6/P e+j0R3ObYXodqnZIY19fzXJKS2dJktoXkqNLBW/SpWTlFzpfHKCvTbJS VLrJ/lrEunE5cgSAqBrbAAuJrFpX/gaavqokElnUv1Mki2agTH1dTZyn X8M=
+SECTION AUTHORITY
+example.com. 3600 IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 10 2 3600 20251231235959 20160308093040 2843 example.com. boNVuXxyhW+Gmiu+4ip1QQvIGqFNVsFfg1v+ywgc4+37ieQ5t+qJsHVm fJITRZrJxYQ6T/MkZKhpxLCemgFeKU6syWwoCfypnGino2G1urvqThna WTImSPhY/QsOj1ALy51d9Q+Mb5vt69XJt6SQvtNf6imepIFOT6CPSfjx BJ4=
+SECTION ADDITIONAL
+ns.example.com. 3600 IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 10 3 3600 20251231235959 20160308093040 2843 example.com. VSq+DkxJYr9Z+uh3KgpyPNwtuim4WVXnTdhRW7HX90CP5tyOVjDDTehA UmCxB8iFjUFE3hlwDx0Y71g+8Oso1t0JGkvDtWf5RDx1w+4K/1pQ2JMG lZTh7juaGJzXtltxqBoY67z1FBp9MI59O0hkABtz1CElj9LrhDr9wQa4 OUo=
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+sub.example.com. IN DS
+SECTION AUTHORITY
+example.com. 3600 IN SOA ns.example.com. hostmaster.example.com. 2016022600 28800 7200 604800 18000
+example.com. 3600 IN RRSIG SOA 10 2 3600 20251231235959 20160308093040 2843 example.com. s3pCq6ZK3DEUkWYX3XKvr5v9Z4AhbJ4P7/AKQkhe3zymnTba7Bo5Uhmb Vav/A+u8gsoo9yBumReXLAv047btO+jdCOLD/yXvmaSt/yGGcipFoX6r 4kQWzUHby4NlQEdO3YykiZx7FtCGsMp0cfwPae4glkDsAPnIhhQurzzE VP4=
+; no nsec
+;sub.example.com. 3600 IN NSEC example.com. NS RRSIG NSEC
+;sub.example.com. 3600 IN RRSIG NSEC 10 3 18000 20251231235959 20160308093040 2843 example.com. extoqd9mqaALMQf5kY5deuxZDL6INjsEKEUSfDibHTEAdNxfnmOJ9wcf hfpQfmgFLUAHsN0V/YB8qq6JhzkEkMV9f7BI/nZpuKCbSHo4ZOEUTflX mGM+VRBQc8gb25K03N0nwb6AvueSVA1PRizrRpQm/wvVWfDNZ+rM/lO6 +i4=
+ENTRY_END
+RANGE_END
+
+; ns.sub.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.10
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+sub.example.com. IN NS
+SECTION ANSWER
+sub.example.com. 3600 IN NS ns.sub.example.com.
+SECTION ADDITIONAL
+ns.sub.example.com. 3600 IN A 1.2.3.10
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+a.sub.example.com. IN A
+SECTION ANSWER
+a.sub.example.com. 3600 IN A 1.2.3.11
+ENTRY_END
+
+RANGE_END
+
+STEP 10 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+a.sub.example.com. IN A
+ENTRY_END
+
+STEP 20 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH opcode qname flags rcode question
+REPLY QR RD RA SERVFAIL
+SECTION QUESTION
+a.sub.example.com. IN A
+SECTION ANSWER
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/nsec_wildcard_answer_response.rpl b/tests/integration/deckard/sets/resolver/nsec_wildcard_answer_response.rpl
new file mode 100644
index 0000000..8684c83
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/nsec_wildcard_answer_response.rpl
@@ -0,0 +1,420 @@
+do-ip6: no
+
+; config options
+;server:
+ trust-anchor: ". IN DS 41524 8 2 5175938255D97A88F9D16A5A46ED3AE373441DF5058C1666D953005D A6BD57F3"
+ val-override-date: "20170401000000"
+
+;stub-zone:
+; name: "."
+ stub-addr: 192.0.2.1 # ns.
+CONFIG_END
+
+SCENARIO_BEGIN Test validation of NSEC wildcard answer response.
+
+; ns.
+RANGE_BEGIN 0 100
+ ADDRESS 192.0.2.1
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. 3600 IN NS ns.
+. 3600 IN RRSIG NS 8 0 3600 20170418124934 20170319124934 41524 . cclqaWsABHoHHSVEjxvWUkj7WBJQGdxvEj2/brtPw9wh42JsedoAsu9g e7885/LSxVOSFf5mZ3eHN1dfxHF5QLYVO2oKgDOl8kM7Hyb3rkqmOp7L lqVS4v4iH4etaonhIW6qwqZTLlets59Z48sF/qurX6EVE/xTc7Kc917c 7oUgHoPoKa8RXkBvXFOuSgXA+OkewLrBcdGaokSLD92/+wZKLAWopc32 mTbZMSImdywm4CvePEZUyXeeQASc7H4eCKE6LFw/4577YrHzDYp2QVnq meJfYg46NXm7xC4bJni/zHmnjKxIS+vi2CdqA7uJviTFpj5XF3g+73aj LHI99Q==
+SECTION ADDITIONAL
+ns. 3600 IN A 192.0.2.1
+ns. 3600 IN RRSIG A 8 1 3600 20170418124934 20170319124934 41524 . r+kPV+Qp088ifM2RRJd9/kTwlFV4Ejuhb8G8VAPmWwkiXSJSrS7HXR9n xkO1CHSzwGYumIDoZsPqZ+RQwY4EBd6xPuAdMAmN/zbebmz+UtNTGLz3 8KVjZoRsJt0BftJs/o3SogiV6cfUtFVnRJN4sCRzAQcyywtKxhtKgHjX 1A47NKzjkbkm2TlUeVwXJjkp0FleZaiNP6wEoxE2cr1hKX4HutXzegzr PaiNGgQhY3yLohBmoSozFLYUN8YPMw6BTf0CLAqyU6N51fVaPZIlARbd V9Ia48AGz44324WrvssuaW2wb0OQie0RAPrHlXg5Ly5I9DeE6m6Czc+M fHBZUQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns. IN A
+SECTION ANSWER
+ns. 3600 IN A 192.0.2.1
+ns. 3600 IN RRSIG A 8 1 3600 20170418124934 20170319124934 41524 . r+kPV+Qp088ifM2RRJd9/kTwlFV4Ejuhb8G8VAPmWwkiXSJSrS7HXR9n xkO1CHSzwGYumIDoZsPqZ+RQwY4EBd6xPuAdMAmN/zbebmz+UtNTGLz3 8KVjZoRsJt0BftJs/o3SogiV6cfUtFVnRJN4sCRzAQcyywtKxhtKgHjX 1A47NKzjkbkm2TlUeVwXJjkp0FleZaiNP6wEoxE2cr1hKX4HutXzegzr PaiNGgQhY3yLohBmoSozFLYUN8YPMw6BTf0CLAqyU6N51fVaPZIlARbd V9Ia48AGz44324WrvssuaW2wb0OQie0RAPrHlXg5Ly5I9DeE6m6Czc+M fHBZUQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns. IN AAAA
+SECTION AUTHORITY
+. 0 IN SOA . . 0 0 0 0 0
+ns. 0 IN NSEC . A RRSIG NSEC
+. 3600 IN RRSIG SOA 8 0 3600 20170418124934 20170319124934 41524 . njTin0/F2e0rVDB1tR4Qf3Fy7yFhsEQBjBP0tLbjAGxkXXmkf3RQAQI6 2OzbNgFH+v+SlupN03LwNbGgxVpvgpEC9X9wh5/l6t+YgMFEHwzVu5Qv 9Mybiqe0gMU8KBtYnTcFkUGs+gE+t7Z/DhPx88zBixYTNGXbDNUWI5nl /xq4FlIAcEb1r+bKpFbpAHyVTrqjy1ZIpn5lYrQPwfrQ/g0iL76SgwT+ 8oBF9LDmrgeVZA5lzzjfu7jp7/N7eYAA6YYZCaK6tca33xTc2RUbmyKQ VJMN8wets+iPxrwAAbHVc5FmxmdlDVQlh4AXkgDahFoUtZwzvLCuphj/ D66dsA==
+ns. 0 IN RRSIG NSEC 8 1 0 20170418124934 20170319124934 41524 . ELuSBQbX8wpCTnUBj2OC/if7HEc0DyekwfNccg84kG9vCfn4PS+AcwJB ZbjJjRWGIIYJBesXuRbaZ1P0yYWSlPfwqbWhO1amSmqOgKEMKgVDmQ3g Qc3e3qqRi5YiGpAnQen7EOnbtUuFKH/OTd5Valq+sKxaYVpJxz53tgTm 42nYuWJg/9aDr9P6NNtl1XoTV+84ApFSxQ9EM9WHsYkVzYTrLZQhMmlQ K1zAsUoUcLISTf5q0T7npsMY7bjaoWfNvGeuUT2VMz44sevivR39Wy3o utWn9zcXa2hXPXW3XXrzIQfkQN9CDkJ5IAwKRPWq1a5vFmbyXN8GfBR3 6le6qA==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+. IN DNSKEY
+SECTION ANSWER
+. 3600 IN DNSKEY 257 3 8 AwEAAbgyvYQ2Vlff/inpv4NZLlIk2+l1sL0JoeOUlWHZ3eeWXZKxQJak QIXyGi8xsuANzu/YStLp31SfU/Fj4piUciqA+U74Lot1S/jcM7/1eczh 69YqGUAPZkreZ3z2DpWzBN4lgPR/w0OvTada3D42uV2bzuSK/nXMiMpZ vP1vZ1ykNRmbksTzA+HnrefRi2yuMSUqMHbtfbfFwqVTQ1ddVwSK7qIJ 02jo95YJUSZDPUUQlczIsFsa7Zxn6gQZl+iaRuDY6nLxxStYYlcqZhVA G5U8Dx4IznQ0FkEJp9RXtv5rmtClcQpudCl1gE0GC/W+TTUAa3hD597f onH+s/OfdCE=
+. 3600 IN RRSIG DNSKEY 8 0 3600 20170418124934 20170319124934 41524 . j/TFYuMrE2Hw4fVUjyIeawIGjuPSGYpmaPQO6fo6B36LG+Fi+GsdrR8x 0OltpfgM7K6QXXZvvPe8IiBACfwPhjUbDgocjkT3VfXONO2wg3xI4pbh rBP7va2otZxPKnnOHWg78l9wcDdaJePOvRv9XjqW6TxO1tugskUy612/ fZpaCrqqQPnCxmjxso8VbKYJHy5dRJFVGX0q2BTsoK55x6+Ecao4eDFo d5VFP9R+oMFlMHV9GPF+NPpfWp3lvQa+6jEikJlZXIExx4x0vUzHgrfZ 2V+4C8Hn0Bc9JfyLqYk6aulbfqkxs+Ao9fm+aNkQVJR4+1PLXnqSCH+/ iP0FVQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example. IN NS
+SECTION AUTHORITY
+. 0 IN SOA . . 0 0 0 0 0
+. 0 IN NSEC *.nsec.example. NS SOA RRSIG NSEC DNSKEY
+. 3600 IN RRSIG SOA 8 0 3600 20170418145253 20170319145253 41524 . GrQu0mY+qRcyVrfn2tp3IpLLZhXUEVCEIg6oVa+wlS5eNULJIJ4xZLG8 T8Dt/ca7XYiWz5Hbv5FP2UG8vbME9Qi3W4pghCSeUq+r0Z+sKJ//BS20 wcX9gpv3KeenLCiLggZDuDvhIJ0Ce8V+p9p+BFbpL4rSESEOLR7VDt5q 2bXgra5ukVp94OF6mCuMSTv2uPfgoNV5b53waJ2TS98E2yOPnNd/LgYa XWqao2a0en3odQPGy+5sdg+Z+UkLS1ySn6hB50Xl6f1CMYVPU7X8+bub g2bHD3yK2Sy5bkNipyohcW8P7tNnR78HhlJyOOGeHzOS2975B6E34mjV zSumrA==
+. 0 IN RRSIG NSEC 8 0 0 20170418145253 20170319145253 41524 . C0tKsifl3qXK5OqpVW4boQleYwtWtT3P7UeVZhBSqEMAIV7UcEWMnnUW wUgtgA181pwvyqwcDYmbz1sM+1GfewfjQY1ulZyj3bjgOy7/w+0BT8JX +FFXrE6j2vRvHFHF0nyfNHwJHAYxaoEl1m5uobPYQy8Cb61MfbRGfj1Q rF5OcSI1O0ExXoPIcIuS3WN2wAqLGLwzSsrltp6K8N81+bbMHZD4TIlA ED3Rl+hL6eg/kx1IcY5PEKI+T6gaqbRlfXicyk+Z4ZYnMn5nH7k5s6Hw CaMUYMsJLpU5ZUfjgQUFbUyKOU5ivTbPQEcujy9yXJ5dX3K2JP4u7MrY sIpuCA==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+name.example. IN NS
+SECTION AUTHORITY
+. 0 IN SOA . . 0 0 0 0 0
+. 0 IN NSEC *.nsec.example. NS SOA RRSIG NSEC DNSKEY
+. 3600 IN RRSIG SOA 8 0 3600 20170418145253 20170319145253 41524 . GrQu0mY+qRcyVrfn2tp3IpLLZhXUEVCEIg6oVa+wlS5eNULJIJ4xZLG8 T8Dt/ca7XYiWz5Hbv5FP2UG8vbME9Qi3W4pghCSeUq+r0Z+sKJ//BS20 wcX9gpv3KeenLCiLggZDuDvhIJ0Ce8V+p9p+BFbpL4rSESEOLR7VDt5q 2bXgra5ukVp94OF6mCuMSTv2uPfgoNV5b53waJ2TS98E2yOPnNd/LgYa XWqao2a0en3odQPGy+5sdg+Z+UkLS1ySn6hB50Xl6f1CMYVPU7X8+bub g2bHD3yK2Sy5bkNipyohcW8P7tNnR78HhlJyOOGeHzOS2975B6E34mjV zSumrA==
+. 0 IN RRSIG NSEC 8 0 0 20170418145253 20170319145253 41524 . C0tKsifl3qXK5OqpVW4boQleYwtWtT3P7UeVZhBSqEMAIV7UcEWMnnUW wUgtgA181pwvyqwcDYmbz1sM+1GfewfjQY1ulZyj3bjgOy7/w+0BT8JX +FFXrE6j2vRvHFHF0nyfNHwJHAYxaoEl1m5uobPYQy8Cb61MfbRGfj1Q rF5OcSI1O0ExXoPIcIuS3WN2wAqLGLwzSsrltp6K8N81+bbMHZD4TIlA ED3Rl+hL6eg/kx1IcY5PEKI+T6gaqbRlfXicyk+Z4ZYnMn5nH7k5s6Hw CaMUYMsJLpU5ZUfjgQUFbUyKOU5ivTbPQEcujy9yXJ5dX3K2JP4u7MrY sIpuCA==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+nsec.example. IN NS
+SECTION AUTHORITY
+. 0 IN SOA . . 0 0 0 0 0
+. 0 IN NSEC *.nsec.example. NS SOA RRSIG NSEC DNSKEY
+*.nsec.example. 0 IN NSEC explicita.nsec.example. A RRSIG NSEC
+. 3600 IN RRSIG SOA 8 0 3600 20170418145253 20170319145253 41524 . GrQu0mY+qRcyVrfn2tp3IpLLZhXUEVCEIg6oVa+wlS5eNULJIJ4xZLG8 T8Dt/ca7XYiWz5Hbv5FP2UG8vbME9Qi3W4pghCSeUq+r0Z+sKJ//BS20 wcX9gpv3KeenLCiLggZDuDvhIJ0Ce8V+p9p+BFbpL4rSESEOLR7VDt5q 2bXgra5ukVp94OF6mCuMSTv2uPfgoNV5b53waJ2TS98E2yOPnNd/LgYa XWqao2a0en3odQPGy+5sdg+Z+UkLS1ySn6hB50Xl6f1CMYVPU7X8+bub g2bHD3yK2Sy5bkNipyohcW8P7tNnR78HhlJyOOGeHzOS2975B6E34mjV zSumrA==
+. 0 IN RRSIG NSEC 8 0 0 20170418145253 20170319145253 41524 . C0tKsifl3qXK5OqpVW4boQleYwtWtT3P7UeVZhBSqEMAIV7UcEWMnnUW wUgtgA181pwvyqwcDYmbz1sM+1GfewfjQY1ulZyj3bjgOy7/w+0BT8JX +FFXrE6j2vRvHFHF0nyfNHwJHAYxaoEl1m5uobPYQy8Cb61MfbRGfj1Q rF5OcSI1O0ExXoPIcIuS3WN2wAqLGLwzSsrltp6K8N81+bbMHZD4TIlA ED3Rl+hL6eg/kx1IcY5PEKI+T6gaqbRlfXicyk+Z4ZYnMn5nH7k5s6Hw CaMUYMsJLpU5ZUfjgQUFbUyKOU5ivTbPQEcujy9yXJ5dX3K2JP4u7MrY sIpuCA==
+*.nsec.example. 0 IN RRSIG NSEC 8 2 0 20170418145253 20170319145253 41524 . A60R/W7nJnrOGnESzKm1//8kydq91hlsk9+2r5z/AT3vuyLdrDVRmmZg LzIdcJ/9qIt4XrfvaGWmqhs2qmm5EbjFoXh+AoRqaetaK1auuAGHqH9U KdMOuxlkoJ4z6sDpSxumbgVxKq7kj7nKGYF/dyCHTcJhKuo498XYh+MQ MDKu82CfmLPdwroqgQyyux/9oimLbYDo/fz09w+/uzApnOWgyM5WiE/M Q6tgHL+UTi5hdZ7jIF2gCtp+V5YcWLI/wcmuJ7lkCh3B9UoCy0box8PB V4U2chvK7pR3DG8slgEaag5wiPto6fwru7PShfp0oC6d6m0x4jsuT6u1 j6GmIw==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname qtype
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+local.nsec.example. IN A
+SECTION ANSWER
+local.nsec.example. 3600 IN A 10.6.6.6
+local.nsec.example. 3600 IN RRSIG A 8 2 3600 20170418145253 20170319145253 41524 . aHyII7vYA6ELENm2C+88GLhJ0D+WBO/TaabT4jnHpyPaVlg+KXOg7Ar1 s04vcPDczmzft178ZcQYbeY2/UR7LsDZoj8j+86MTkVP/FIyNt/8rHch r/AFQQvXvjqD1XTho+3Fyk1HLD+VKI8Rkq894cfc9rAPb1+H3PPz6JWb EwM7S6Ox2OixUEVNKStrsEIDzYSyWmdpRXFC8CVR5zEv1OxBlNBUvza2 KNJHTxwEIcFQY5MdKkGIa25TckAYhncboI1j79VdRa0xqymO81E7AR/D HTBVLD/gENvgN7HGAduC834SuZ1ReDhlbSD1KHw5GPgBGw9e7kzpsoYH MASASg==
+SECTION AUTHORITY
+explicita2.nsec.example. 0 IN NSEC ns. A RRSIG NSEC
+explicita2.nsec.example. 0 IN RRSIG NSEC 8 3 0 20170418145253 20170319145253 41524 . kam1hKBwoeTPR0wpvPs2Jyik3hB+Q0Ek4rpD3BNhUa+gTbBk1Z0q5yEs RFVsp6EZlpcP357QiipC2wrPfd3SunGVTVfAD4h6gn1/e5mPN4kJJfOa nMgwZQATF/vilnGu2+5Xtup3blFhg43UJB//iyTcn8c+phMaySbyT5uG xXaM1Gv2maHeJQNOB8cwFWHpYy/Uoph5rpEcZoxGjGkTLNE8pvhlSAgB wYEtMvli3KJH6hjBnOzhMAtOl+ZHy3VFo/UVm/Lwyzmlg+OQ8LCz+NY0 kmAH8z7ZNKZMxyvBpLzxAU2O+j4uSmp5ENuLcqvEyofr2xrq5Fm7OSoH qZvQ1A==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+local.nsec.example. IN NS
+SECTION AUTHORITY
+. 0 IN SOA . . 0 0 0 0 0
+*.nsec.example. 0 IN NSEC explicita.nsec.example. A RRSIG NSEC
+explicita2.nsec.example. 0 IN NSEC ns. A RRSIG NSEC
+. 3600 IN RRSIG SOA 8 0 3600 20170418145253 20170319145253 41524 . GrQu0mY+qRcyVrfn2tp3IpLLZhXUEVCEIg6oVa+wlS5eNULJIJ4xZLG8 T8Dt/ca7XYiWz5Hbv5FP2UG8vbME9Qi3W4pghCSeUq+r0Z+sKJ//BS20 wcX9gpv3KeenLCiLggZDuDvhIJ0Ce8V+p9p+BFbpL4rSESEOLR7VDt5q 2bXgra5ukVp94OF6mCuMSTv2uPfgoNV5b53waJ2TS98E2yOPnNd/LgYa XWqao2a0en3odQPGy+5sdg+Z+UkLS1ySn6hB50Xl6f1CMYVPU7X8+bub g2bHD3yK2Sy5bkNipyohcW8P7tNnR78HhlJyOOGeHzOS2975B6E34mjV zSumrA==
+*.nsec.example. 0 IN RRSIG NSEC 8 2 0 20170418145253 20170319145253 41524 . A60R/W7nJnrOGnESzKm1//8kydq91hlsk9+2r5z/AT3vuyLdrDVRmmZg LzIdcJ/9qIt4XrfvaGWmqhs2qmm5EbjFoXh+AoRqaetaK1auuAGHqH9U KdMOuxlkoJ4z6sDpSxumbgVxKq7kj7nKGYF/dyCHTcJhKuo498XYh+MQ MDKu82CfmLPdwroqgQyyux/9oimLbYDo/fz09w+/uzApnOWgyM5WiE/M Q6tgHL+UTi5hdZ7jIF2gCtp+V5YcWLI/wcmuJ7lkCh3B9UoCy0box8PB V4U2chvK7pR3DG8slgEaag5wiPto6fwru7PShfp0oC6d6m0x4jsuT6u1 j6GmIw==
+explicita2.nsec.example. 0 IN RRSIG NSEC 8 3 0 20170418145253 20170319145253 41524 . kam1hKBwoeTPR0wpvPs2Jyik3hB+Q0Ek4rpD3BNhUa+gTbBk1Z0q5yEs RFVsp6EZlpcP357QiipC2wrPfd3SunGVTVfAD4h6gn1/e5mPN4kJJfOa nMgwZQATF/vilnGu2+5Xtup3blFhg43UJB//iyTcn8c+phMaySbyT5uG xXaM1Gv2maHeJQNOB8cwFWHpYy/Uoph5rpEcZoxGjGkTLNE8pvhlSAgB wYEtMvli3KJH6hjBnOzhMAtOl+ZHy3VFo/UVm/Lwyzmlg+OQ8LCz+NY0 kmAH8z7ZNKZMxyvBpLzxAU2O+j4uSmp5ENuLcqvEyofr2xrq5Fm7OSoH qZvQ1A==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+a.local.nsec.example. IN A
+SECTION ANSWER
+a.local.nsec.example. 3600 IN A 10.6.6.6
+a.local.nsec.example. 3600 IN RRSIG A 8 2 3600 20170418134059 20170319134059 41524 . KMkFd5M1F8wVtVhXUnyPZMhY6dGj3g54tX+wgRiGSnqlRICCUdc8NCKG w+lJ1HvDrfNduth5De82MwCfgu2qORDGRF1H0DaoLlYOzy7pNPV1kA9R sXals6EyoFw0pEJkdW/pI5/EJz611c5Oy94iz5LbhkM/kwosmtK1ln3Z N+zGGDRj8xAaWsvmAvPXQoIJhHEblPp/Mcs4V6vX0b7plfkdDxa0hCgf 4UYipsqHo6BXksCEkRznIlDWym9jpVqD7TNAIbO/03TpvhnD50C0Wusb k75cTy24NDD7PTmAZwBlT6qZGnODdc1/ECTnq3kYniN6ceevMZQYEVqw S9haUg==
+SECTION AUTHORITY
+explicita2.nsec.example. 0 IN NSEC ns. A RRSIG NSEC
+explicita2.nsec.example. 0 IN RRSIG NSEC 8 3 0 20170418145253 20170319145253 41524 . kam1hKBwoeTPR0wpvPs2Jyik3hB+Q0Ek4rpD3BNhUa+gTbBk1Z0q5yEs RFVsp6EZlpcP357QiipC2wrPfd3SunGVTVfAD4h6gn1/e5mPN4kJJfOa nMgwZQATF/vilnGu2+5Xtup3blFhg43UJB//iyTcn8c+phMaySbyT5uG xXaM1Gv2maHeJQNOB8cwFWHpYy/Uoph5rpEcZoxGjGkTLNE8pvhlSAgB wYEtMvli3KJH6hjBnOzhMAtOl+ZHy3VFo/UVm/Lwyzmlg+OQ8LCz+NY0 kmAH8z7ZNKZMxyvBpLzxAU2O+j4uSmp5ENuLcqvEyofr2xrq5Fm7OSoH qZvQ1A==
+ENTRY_END
+
+; Missing NSEC covering the wildcard.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+missing-nsec.local.nsec.example. IN A
+SECTION ANSWER
+missing-nsec.local.nsec.example. 3600 IN A 10.6.6.6
+missing-nsec.local.nsec.example. 3600 IN RRSIG A 8 2 3600 20170418134059 20170319134059 41524 . KMkFd5M1F8wVtVhXUnyPZMhY6dGj3g54tX+wgRiGSnqlRICCUdc8NCKG w+lJ1HvDrfNduth5De82MwCfgu2qORDGRF1H0DaoLlYOzy7pNPV1kA9R sXals6EyoFw0pEJkdW/pI5/EJz611c5Oy94iz5LbhkM/kwosmtK1ln3Z N+zGGDRj8xAaWsvmAvPXQoIJhHEblPp/Mcs4V6vX0b7plfkdDxa0hCgf 4UYipsqHo6BXksCEkRznIlDWym9jpVqD7TNAIbO/03TpvhnD50C0Wusb k75cTy24NDD7PTmAZwBlT6qZGnODdc1/ECTnq3kYniN6ceevMZQYEVqw S9haUg==
+ENTRY_END
+
+; kresd will detect validation failure and query for RRSIG
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+missing-nsec.local.nsec.example. IN RRSIG
+SECTION ANSWER
+missing-nsec.local.nsec.example. 3600 IN RRSIG A 8 2 3600 20170418134059 20170319134059 41524 . KMkFd5M1F8wVtVhXUnyPZMhY6dGj3g54tX+wgRiGSnqlRICCUdc8NCKG w+lJ1HvDrfNduth5De82MwCfgu2qORDGRF1H0DaoLlYOzy7pNPV1kA9R sXals6EyoFw0pEJkdW/pI5/EJz611c5Oy94iz5LbhkM/kwosmtK1ln3Z N+zGGDRj8xAaWsvmAvPXQoIJhHEblPp/Mcs4V6vX0b7plfkdDxa0hCgf 4UYipsqHo6BXksCEkRznIlDWym9jpVqD7TNAIbO/03TpvhnD50C0Wusb k75cTy24NDD7PTmAZwBlT6qZGnODdc1/ECTnq3kYniN6ceevMZQYEVqw S9haUg==
+ENTRY_END
+
+; NSEC record was attached to another answer created by copying wildcard data to different owner name
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+incorrect.name.example. IN A
+SECTION ANSWER
+incorrect.name.example. 3600 IN A 10.6.6.6
+incorrect.name.example. 3600 IN RRSIG A 8 2 3600 20170418134059 20170319134059 41524 . KMkFd5M1F8wVtVhXUnyPZMhY6dGj3g54tX+wgRiGSnqlRICCUdc8NCKG w+lJ1HvDrfNduth5De82MwCfgu2qORDGRF1H0DaoLlYOzy7pNPV1kA9R sXals6EyoFw0pEJkdW/pI5/EJz611c5Oy94iz5LbhkM/kwosmtK1ln3Z N+zGGDRj8xAaWsvmAvPXQoIJhHEblPp/Mcs4V6vX0b7plfkdDxa0hCgf 4UYipsqHo6BXksCEkRznIlDWym9jpVqD7TNAIbO/03TpvhnD50C0Wusb k75cTy24NDD7PTmAZwBlT6qZGnODdc1/ECTnq3kYniN6ceevMZQYEVqw S9haUg==
+SECTION AUTHORITY
+explicita2.nsec.example. 0 IN NSEC ns. A RRSIG NSEC
+explicita2.nsec.example. 0 IN RRSIG NSEC 8 3 0 20170418145253 20170319145253 41524 . kam1hKBwoeTPR0wpvPs2Jyik3hB+Q0Ek4rpD3BNhUa+gTbBk1Z0q5yEs RFVsp6EZlpcP357QiipC2wrPfd3SunGVTVfAD4h6gn1/e5mPN4kJJfOa nMgwZQATF/vilnGu2+5Xtup3blFhg43UJB//iyTcn8c+phMaySbyT5uG xXaM1Gv2maHeJQNOB8cwFWHpYy/Uoph5rpEcZoxGjGkTLNE8pvhlSAgB wYEtMvli3KJH6hjBnOzhMAtOl+ZHy3VFo/UVm/Lwyzmlg+OQ8LCz+NY0 kmAH8z7ZNKZMxyvBpLzxAU2O+j4uSmp5ENuLcqvEyofr2xrq5Fm7OSoH qZvQ1A==
+ENTRY_END
+
+; kresd will detect validation failure and query for RRSIG
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+incorrect.name.example. IN RRSIG
+SECTION ANSWER
+incorrect.name.example. 3600 IN RRSIG A 8 2 3600 20170418134059 20170319134059 41524 . KMkFd5M1F8wVtVhXUnyPZMhY6dGj3g54tX+wgRiGSnqlRICCUdc8NCKG w+lJ1HvDrfNduth5De82MwCfgu2qORDGRF1H0DaoLlYOzy7pNPV1kA9R sXals6EyoFw0pEJkdW/pI5/EJz611c5Oy94iz5LbhkM/kwosmtK1ln3Z N+zGGDRj8xAaWsvmAvPXQoIJhHEblPp/Mcs4V6vX0b7plfkdDxa0hCgf 4UYipsqHo6BXksCEkRznIlDWym9jpVqD7TNAIbO/03TpvhnD50C0Wusb k75cTy24NDD7PTmAZwBlT6qZGnODdc1/ECTnq3kYniN6ceevMZQYEVqw S9haUg==
+ENTRY_END
+
+; explicita.nsec.example.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+explicita.nsec.example. IN A
+SECTION ANSWER
+explicita.nsec.example. 3600 IN A 203.0.113.1
+explicita.nsec.example. 3600 IN RRSIG A 8 3 3600 20170418134059 20170319134059 41524 . Nn0DZ1gwzj0FLrgmoeePfKJbvJvTpwtmw6CPehUHyNW7pUOYG8HE45qt tcvx4LWvzYAKy9TY6B7c4D5eMu8+rXXyLg21DX3zFKABEYIeMaJPqPpF WxYqhbP0qQwI/w29B7n3blzzbMOkNvNI4y4RZyBqyqBBfKu/xXYljZG2 MyDlRyEAeV1vewMdhlr6TJoclE6PqYvxiMuXc1f9Nu/TwB22Pp29OTrN A3HFieYVbfWM1F3HtoO6aAk2FVCEveYQOsQ81mgweMKF2OMIK4rjCwlL ffziuSYwF5TcheNATYlaQQZTxKhKsdmGM4BZNprQ/MzoutqIS7j7Vdxs O4N+1Q==
+ENTRY_END
+
+; explicita2.nsec.example. - fake answer attempting to replace explicit record with wildcard data
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+explicita2.nsec.example. IN A
+SECTION ANSWER
+; this was copied from wildcard answer for a.local.nsec.example. IN A
+explicits2.nsec.example. 3600 IN A 10.6.6.6
+explicita2.nsec.example. 3600 IN RRSIG A 8 2 3600 20170418134059 20170319134059 41524 . KMkFd5M1F8wVtVhXUnyPZMhY6dGj3g54tX+wgRiGSnqlRICCUdc8NCKG w+lJ1HvDrfNduth5De82MwCfgu2qORDGRF1H0DaoLlYOzy7pNPV1kA9R sXals6EyoFw0pEJkdW/pI5/EJz611c5Oy94iz5LbhkM/kwosmtK1ln3Z N+zGGDRj8xAaWsvmAvPXQoIJhHEblPp/Mcs4V6vX0b7plfkdDxa0hCgf 4UYipsqHo6BXksCEkRznIlDWym9jpVqD7TNAIbO/03TpvhnD50C0Wusb k75cTy24NDD7PTmAZwBlT6qZGnODdc1/ECTnq3kYniN6ceevMZQYEVqw S9haUg==
+SECTION AUTHORITY
+explicita2.nsec.example. 0 IN NSEC ns. A RRSIG NSEC
+explicita2.nsec.example. 0 IN RRSIG NSEC 8 3 0 20170418145253 20170319145253 41524 . kam1hKBwoeTPR0wpvPs2Jyik3hB+Q0Ek4rpD3BNhUa+gTbBk1Z0q5yEs RFVsp6EZlpcP357QiipC2wrPfd3SunGVTVfAD4h6gn1/e5mPN4kJJfOa nMgwZQATF/vilnGu2+5Xtup3blFhg43UJB//iyTcn8c+phMaySbyT5uG xXaM1Gv2maHeJQNOB8cwFWHpYy/Uoph5rpEcZoxGjGkTLNE8pvhlSAgB wYEtMvli3KJH6hjBnOzhMAtOl+ZHy3VFo/UVm/Lwyzmlg+OQ8LCz+NY0 kmAH8z7ZNKZMxyvBpLzxAU2O+j4uSmp5ENuLcqvEyofr2xrq5Fm7OSoH qZvQ1A==
+ENTRY_END
+
+RANGE_END
+
+STEP 10 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+a.local.nsec.example. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 11 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA AD NOERROR
+SECTION QUESTION
+a.local.nsec.example. IN A
+SECTION ANSWER
+a.local.nsec.example. 3600 IN A 10.6.6.6
+a.local.nsec.example. 3600 IN RRSIG A 8 2 3600 20170418134059 20170319134059 41524 . KMkFd5M1F8wVtVhXUnyPZMhY6dGj3g54tX+wgRiGSnqlRICCUdc8NCKG w+lJ1HvDrfNduth5De82MwCfgu2qORDGRF1H0DaoLlYOzy7pNPV1kA9R sXals6EyoFw0pEJkdW/pI5/EJz611c5Oy94iz5LbhkM/kwosmtK1ln3Z N+zGGDRj8xAaWsvmAvPXQoIJhHEblPp/Mcs4V6vX0b7plfkdDxa0hCgf 4UYipsqHo6BXksCEkRznIlDWym9jpVqD7TNAIbO/03TpvhnD50C0Wusb k75cTy24NDD7PTmAZwBlT6qZGnODdc1/ECTnq3kYniN6ceevMZQYEVqw S9haUg==
+SECTION AUTHORITY
+explicita2.nsec.example. 0 IN NSEC ns. A RRSIG NSEC
+explicita2.nsec.example. 0 IN RRSIG NSEC 8 3 0 20170418145253 20170319145253 41524 . kam1hKBwoeTPR0wpvPs2Jyik3hB+Q0Ek4rpD3BNhUa+gTbBk1Z0q5yEs RFVsp6EZlpcP357QiipC2wrPfd3SunGVTVfAD4h6gn1/e5mPN4kJJfOa nMgwZQATF/vilnGu2+5Xtup3blFhg43UJB//iyTcn8c+phMaySbyT5uG xXaM1Gv2maHeJQNOB8cwFWHpYy/Uoph5rpEcZoxGjGkTLNE8pvhlSAgB wYEtMvli3KJH6hjBnOzhMAtOl+ZHy3VFo/UVm/Lwyzmlg+OQ8LCz+NY0 kmAH8z7ZNKZMxyvBpLzxAU2O+j4uSmp5ENuLcqvEyofr2xrq5Fm7OSoH qZvQ1A==
+ENTRY_END
+
+; test answer from cache
+STEP 12 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+a.local.nsec.example. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 13 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA AD NOERROR
+SECTION QUESTION
+a.local.nsec.example. IN A
+SECTION ANSWER
+a.local.nsec.example. 3600 IN A 10.6.6.6
+a.local.nsec.example. 3600 IN RRSIG A 8 2 3600 20170418134059 20170319134059 41524 . KMkFd5M1F8wVtVhXUnyPZMhY6dGj3g54tX+wgRiGSnqlRICCUdc8NCKG w+lJ1HvDrfNduth5De82MwCfgu2qORDGRF1H0DaoLlYOzy7pNPV1kA9R sXals6EyoFw0pEJkdW/pI5/EJz611c5Oy94iz5LbhkM/kwosmtK1ln3Z N+zGGDRj8xAaWsvmAvPXQoIJhHEblPp/Mcs4V6vX0b7plfkdDxa0hCgf 4UYipsqHo6BXksCEkRznIlDWym9jpVqD7TNAIbO/03TpvhnD50C0Wusb k75cTy24NDD7PTmAZwBlT6qZGnODdc1/ECTnq3kYniN6ceevMZQYEVqw S9haUg==
+SECTION AUTHORITY
+explicita2.nsec.example. 0 IN NSEC ns. A RRSIG NSEC
+explicita2.nsec.example. 0 IN RRSIG NSEC 8 3 0 20170418145253 20170319145253 41524 . kam1hKBwoeTPR0wpvPs2Jyik3hB+Q0Ek4rpD3BNhUa+gTbBk1Z0q5yEs RFVsp6EZlpcP357QiipC2wrPfd3SunGVTVfAD4h6gn1/e5mPN4kJJfOa nMgwZQATF/vilnGu2+5Xtup3blFhg43UJB//iyTcn8c+phMaySbyT5uG xXaM1Gv2maHeJQNOB8cwFWHpYy/Uoph5rpEcZoxGjGkTLNE8pvhlSAgB wYEtMvli3KJH6hjBnOzhMAtOl+ZHy3VFo/UVm/Lwyzmlg+OQ8LCz+NY0 kmAH8z7ZNKZMxyvBpLzxAU2O+j4uSmp5ENuLcqvEyofr2xrq5Fm7OSoH qZvQ1A==
+ENTRY_END
+
+; missing-nsec.local.nsec.example. is covered by explicita2.nsec.example. -> ns.
+; and then the *.nsec.example. wildcard applies (both from the last answer above)
+; kresd by default caches even zero-TTL records for 5 seconds, so let's expire those,
+; so that the aggressive cache won't use them.
+STEP 19 TIME_PASSES ELAPSE 10
+
+; NSEC record is missing
+STEP 20 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+missing-nsec.local.nsec.example. IN A
+ENTRY_END
+
+STEP 21 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA SERVFAIL
+SECTION QUESTION
+missing-nsec.local.nsec.example. IN A
+ENTRY_END
+
+STEP 22 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+missing-nsec.local.nsec.example. IN A
+ENTRY_END
+
+; test answer from cache
+STEP 23 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA SERVFAIL
+SECTION QUESTION
+missing-nsec.local.nsec.example. IN A
+ENTRY_END
+
+
+; NSEC answer was copied to another name in the same zone
+STEP 30 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+incorrect.name.example. IN A
+ENTRY_END
+
+STEP 31 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA SERVFAIL
+SECTION QUESTION
+incorrect.name.example. IN A
+ENTRY_END
+
+; test answer from cache
+STEP 32 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+incorrect.name.example. IN A
+ENTRY_END
+
+STEP 33 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA SERVFAIL
+SECTION QUESTION
+incorrect.name.example. IN A
+ENTRY_END
+
+; explicitly defined records gets properly validated even with cached wildcard
+STEP 40 QUERY
+ENTRY_BEGIN
+REPLY RD DO AD
+SECTION QUESTION
+explicita.nsec.example. IN A
+ENTRY_END
+
+STEP 41 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA DO AD
+SECTION QUESTION
+explicita.nsec.example. IN A
+SECTION ANSWER
+explicita.nsec.example. 3600 IN A 203.0.113.1
+explicita.nsec.example. 3600 IN RRSIG A 8 3 3600 20170418134059 20170319134059 41524 . Nn0DZ1gwzj0FLrgmoeePfKJbvJvTpwtmw6CPehUHyNW7pUOYG8HE45qt tcvx4LWvzYAKy9TY6B7c4D5eMu8+rXXyLg21DX3zFKABEYIeMaJPqPpF WxYqhbP0qQwI/w29B7n3blzzbMOkNvNI4y4RZyBqyqBBfKu/xXYljZG2 MyDlRyEAeV1vewMdhlr6TJoclE6PqYvxiMuXc1f9Nu/TwB22Pp29OTrN A3HFieYVbfWM1F3HtoO6aAk2FVCEveYQOsQ81mgweMKF2OMIK4rjCwlL ffziuSYwF5TcheNATYlaQQZTxKhKsdmGM4BZNprQ/MzoutqIS7j7Vdxs O4N+1Q==
+ENTRY_END
+
+; test answer from cache
+STEP 42 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+explicita.nsec.example. IN A
+ENTRY_END
+
+STEP 43 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA DO AD
+SECTION QUESTION
+explicita.nsec.example. IN A
+SECTION ANSWER
+explicita.nsec.example. 3600 IN A 203.0.113.1
+explicita.nsec.example. 3600 IN RRSIG A 8 3 3600 20170418134059 20170319134059 41524 . Nn0DZ1gwzj0FLrgmoeePfKJbvJvTpwtmw6CPehUHyNW7pUOYG8HE45qt tcvx4LWvzYAKy9TY6B7c4D5eMu8+rXXyLg21DX3zFKABEYIeMaJPqPpF WxYqhbP0qQwI/w29B7n3blzzbMOkNvNI4y4RZyBqyqBBfKu/xXYljZG2 MyDlRyEAeV1vewMdhlr6TJoclE6PqYvxiMuXc1f9Nu/TwB22Pp29OTrN A3HFieYVbfWM1F3HtoO6aAk2FVCEveYQOsQ81mgweMKF2OMIK4rjCwlL ffziuSYwF5TcheNATYlaQQZTxKhKsdmGM4BZNprQ/MzoutqIS7j7Vdxs O4N+1Q==
+ENTRY_END
+
+; check that explicit record cannot be masked by wildcard
+STEP 50 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+explicita2.nsec.example. IN A
+ENTRY_END
+
+STEP 51 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA SERVFAIL
+SECTION QUESTION
+explicita2.nsec.example. IN A
+ENTRY_END
+
+; it has to work even if wildcard is not in the cache
+STEP 53 TIME_PASSES ELAPSE 4000
+
+STEP 54 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+explicita2.nsec.example. IN A
+ENTRY_END
+
+STEP 55 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA SERVFAIL
+SECTION QUESTION
+explicita2.nsec.example. IN A
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/nsec_wildcard_answer_response/K.+008+41524.key b/tests/integration/deckard/sets/resolver/nsec_wildcard_answer_response/K.+008+41524.key
new file mode 100644
index 0000000..1511e45
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/nsec_wildcard_answer_response/K.+008+41524.key
@@ -0,0 +1,5 @@
+; This is a key-signing key, keyid 41524, for .
+; Created: 20170319134901 (Sun Mar 19 14:49:01 2017)
+; Publish: 20170319134901 (Sun Mar 19 14:49:01 2017)
+; Activate: 20170319134901 (Sun Mar 19 14:49:01 2017)
+. IN DNSKEY 257 3 8 AwEAAbgyvYQ2Vlff/inpv4NZLlIk2+l1sL0JoeOUlWHZ3eeWXZKxQJak QIXyGi8xsuANzu/YStLp31SfU/Fj4piUciqA+U74Lot1S/jcM7/1eczh 69YqGUAPZkreZ3z2DpWzBN4lgPR/w0OvTada3D42uV2bzuSK/nXMiMpZ vP1vZ1ykNRmbksTzA+HnrefRi2yuMSUqMHbtfbfFwqVTQ1ddVwSK7qIJ 02jo95YJUSZDPUUQlczIsFsa7Zxn6gQZl+iaRuDY6nLxxStYYlcqZhVA G5U8Dx4IznQ0FkEJp9RXtv5rmtClcQpudCl1gE0GC/W+TTUAa3hD597f onH+s/OfdCE=
diff --git a/tests/integration/deckard/sets/resolver/nsec_wildcard_answer_response/K.+008+41524.private b/tests/integration/deckard/sets/resolver/nsec_wildcard_answer_response/K.+008+41524.private
new file mode 100644
index 0000000..2811b2b
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/nsec_wildcard_answer_response/K.+008+41524.private
@@ -0,0 +1,13 @@
+Private-key-format: v1.3
+Algorithm: 8 (RSASHA256)
+Modulus: uDK9hDZWV9/+Kem/g1kuUiTb6XWwvQmh45SVYdnd55ZdkrFAlqRAhfIaLzGy4A3O79hK0unfVJ9T8WPimJRyKoD5Tvgui3VL+Nwzv/V5zOHr1ioZQA9mSt5nfPYOlbME3iWA9H/DQ69Np1rcPja5XZvO5Ir+dcyIylm8/W9nXKQ1GZuSxPMD4eet59GLbK4xJSowdu19t8XCpVNDV11XBIruognTaOj3lglRJkM9RRCVzMiwWxrtnGfqBBmX6JpG4NjqcvHFK1hiVypmFUAblTwPHgjOdDQWQQmn1Fe2/mua0KVxCm50KXWATQYL9b5NNQBreEPn3t+icf6z8590IQ==
+PublicExponent: AQAB
+PrivateExponent: HEH8fPnxCQ4d6cQoUzgtOQDak9gwQu/lXAqBWD+aIVsaA9UZeYK9O09G4RKYxHKZ2oWuBOlID61ZrWCLdKjhUs/yb0D3swFNpGHztnEsPFg0W+idcwxpvvabnboJxsFt776FJ/0psYqFOTVhMFIo4clzVfBU1TGJkrFtotuiWb28eZ85pFJiQUR+agbWjstXaXMmXeSRPYAueBD/bo6u5DqDagH1fzNxhKUxC9nhpeoIj1AtH4bJuO0v4oxq6yrcGEn6Jus5wku9goLCJqykfRikYwQzyUCP/AQMVC++qiQJ89A66psa0F2lcmps5/2skBEM9QB5Vv12jbIw6j6TeQ==
+Prime1: 6AkeSU4ZcvsxDem0IJLhC4zYEpCN+ZAr/757pkv6oIfQv2PhJmXQ1bmiCsYD/uoRDUFNtNGOFjIlmnGHKIefvCSHlZRxCDDzDAvZ6IthkMQEzDcSQkZIpprCt7QMl1Kz2gjEs84+DNxozB54UbEYG908PrF7CF7ix3RHHEDcX6M=
+Prime2: yzjUYzFjM52Q5cwtMHL8gHnacpzQSUidYLZF+xA4dYjc0pjSRMo87sfp2r6wdm3ZOcfOy0SZl4LvO0Kcrz/VB2v0yiBqanDcM3SBg6n7lz/l5Xaoj5rw9JmYj981nJe8vcerZvJl8MLT00uikr1gqoABxKIvHyt7kYcYB2qqSWs=
+Exponent1: Sjzgm8OJEOidQT5Miz9zESb22rm1MuuVqDVhiks03LeXaiSinI5mynqiBaBlFuH8oqkKG5gQRbm1njxEags6aA+n8YuUvnIq0OfZyDUP+ik8/7l+9gVWqTdKpUvN23xyXof/pyeNYsACJ4x4Imrus7uM0uIl4v+4vufM+JUn7NE=
+Exponent2: HUmqakVC27x4lnWviYz40Pc+wUfSSM17SOXb/gvfZyj7UiqOGzXeRDdxf4H94oOAS/B84BSZ4hkPq0W1WRhk9jXbyImVbJOpWI0Q4U3NIYYm9sP8FP4qfcXpE8sCafgAToWJMUP75w/dAVWkL2u1k7zxBEqvadmVbGrAzsjTk9M=
+Coefficient: ms+SW3tNI975ejCbI1vIB31uUqVfvVvxv7eWtzJEdyxBVQKb0aQnXaTMdXiESNc+H5HMau3lbDOw5IcQkp79fKdxLt3SjMYPdnQmBWg7StY3fV1FJcPEEJeFQjWXxioY8rdvMUTMk1FfjxlllBkCyMWuIE4cbRTNdcq76ozM60g=
+Created: 20170319134901
+Publish: 20170319134901
+Activate: 20170319134901
diff --git a/tests/integration/deckard/sets/resolver/nsec_wildcard_answer_response/root.zone b/tests/integration/deckard/sets/resolver/nsec_wildcard_answer_response/root.zone
new file mode 100644
index 0000000..557c92a
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/nsec_wildcard_answer_response/root.zone
@@ -0,0 +1,8 @@
+*.nsec.example. 3600 IN A 10.6.6.6
+
+explicita.nsec.example. 3600 IN A 203.0.113.1
+explicita2.nsec.example. 3600 IN A 203.0.113.2
+
+. 3600 IN SOA . . 0 0 0 0 0
+. 3600 IN NS ns.
+ns. 3600 IN A 192.0.2.1
diff --git a/tests/integration/deckard/sets/resolver/nsec_wildcard_no_data_response-part2.rpl b/tests/integration/deckard/sets/resolver/nsec_wildcard_no_data_response-part2.rpl
new file mode 100644
index 0000000..79a31d2
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/nsec_wildcard_no_data_response-part2.rpl
@@ -0,0 +1,259 @@
+do-ip6: no
+
+; config options
+;server:
+ trust-anchor: "nsec.example. IN DS 41524 8 2 D6B102667845D6CDDC05B44466426D9CCC189989BF67ADB23605EED0 BFE2A443"
+ val-override-date: "20170401000000"
+
+;stub-zone:
+; name: "."
+ stub-addr: 192.0.2.1 # ns.
+CONFIG_END
+
+SCENARIO_BEGIN Test validation of NSEC name error responses.
+
+; ns.
+RANGE_BEGIN 0 100
+ ADDRESS 192.0.2.1
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. 3600 IN NS ns.
+SECTION ADDITIONAL
+ns. 3600 IN A 192.0.2.1
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns. IN A
+SECTION ANSWER
+ns. 3600 IN A 192.0.2.1
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname qtype
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns. IN AAAA
+SECTION AUTHORITY
+. 3600 IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example. IN CNAME
+SECTION AUTHORITY
+example. 3600 IN NS ns.example.
+SECTION ADDITIONAL
+ns.example. 3600 IN A 192.0.2.2
+ENTRY_END
+
+RANGE_END
+
+; ns.example.
+RANGE_BEGIN 0 100
+ ADDRESS 192.0.2.2
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+example. IN NS
+SECTION ANSWER
+example. 3600 IN NS ns.example.
+SECTION ADDITIONAL
+ns.example. 3600 IN A 192.0.2.2
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns.example. IN A
+SECTION ANSWER
+ns.example. 3600 IN A 192.0.2.2
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns.example. IN AAAA
+SECTION AUTHORITY
+example. 3600 IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+nsec.example. IN CNAME
+SECTION AUTHORITY
+nsec.example. 3600 IN NS ns.nsec.example.
+SECTION ADDITIONAL
+ns.nsec.example. 3600 IN A 192.0.2.3
+ENTRY_END
+
+RANGE_END
+
+; ns.nsec.example.
+RANGE_BEGIN 0 100
+ ADDRESS 192.0.2.3
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+nsec.example. IN NS
+SECTION ANSWER
+nsec.example. 3600 IN NS ns.nsec.example.
+nsec.example. 3600 IN RRSIG NS 8 2 3600 20170419140236 20170320140236 41524 nsec.example. KECif/B3ckfo5d9Qd/5dtIDt/8nIpTfTMxeJU3qw1U8jzQ/+nQ6qZAvr GH4MeGwY0M9kj2Jj3h2tdI+uhfLaGC7LStXIG0Q+PfalGdddDQwwd/p0 oOQ6bt0eilZN5OKF7Frzn4jmV1x7R/iieWp65xB7OByvguYoXOlzuoU1 ikaL43rm/whxn6iHf0K7NfaVqQwO26N/P3EBFFZMwuhHOB2+bVXKoE7r O4bC04tF7wG7CRUlc44xNs08L512RXRuFIrkHg932BFVlEYmPwbflE6+ zfpZafFzYutEHx7XZw2+gAklynmcAXltPCOiqThkDJzw2rpyUmiH0ztm lG76Tg==
+SECTION ADDITIONAL
+ns.nsec.example. 3600 IN A 192.0.2.3
+ns.nsec.example. 3600 IN RRSIG A 8 3 3600 20170419140236 20170320140236 41524 nsec.example. E6Cx+MIElwAbw4Hg48Ee4CC4pKSjPkW8fmcHVoTqNwMyRs4Jjyymf1tE mNdjYkoN0kxI8PEgbGxzuwlFLpGncQhuZ0dyTzCPvnYFPLIkDmdtyIcj 4MVZiJpdyc5yRTC+Aja1Ik9cQ25QsSGAg4z54Zv0o6uqodppCHILgBzm Q833AQFh6hOQE3BFM3c8h3PCsH6HJOOIlgqculfT5d0S1XPFGmtjVW4G gZNsNeBtLB/SkvYKzNS+Yw38J9VTtWMlgTUwkjVXzC+f83AgzXHM3neq QhRhf72VO/xP5sd33VXDVBtOqbFSDZHLpGLfaXJSrnzKX5H8nCMuIXbs kWK60w==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns.nsec.example. IN A
+SECTION ANSWER
+ns.nsec.example. 3600 IN A 192.0.2.3
+ns.nsec.example. 3600 IN RRSIG A 8 3 3600 20170419140236 20170320140236 41524 nsec.example. E6Cx+MIElwAbw4Hg48Ee4CC4pKSjPkW8fmcHVoTqNwMyRs4Jjyymf1tE mNdjYkoN0kxI8PEgbGxzuwlFLpGncQhuZ0dyTzCPvnYFPLIkDmdtyIcj 4MVZiJpdyc5yRTC+Aja1Ik9cQ25QsSGAg4z54Zv0o6uqodppCHILgBzm Q833AQFh6hOQE3BFM3c8h3PCsH6HJOOIlgqculfT5d0S1XPFGmtjVW4G gZNsNeBtLB/SkvYKzNS+Yw38J9VTtWMlgTUwkjVXzC+f83AgzXHM3neq QhRhf72VO/xP5sd33VXDVBtOqbFSDZHLpGLfaXJSrnzKX5H8nCMuIXbs kWK60w==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns.nsec.example. IN AAAA
+SECTION AUTHORITY
+nsec.example. 3600 IN SOA ns.nsec.example. root.nsec.example. 6 60 60 120 3600
+ns.nsec.example. 3600 IN NSEC nsec.example. A RRSIG NSEC
+nsec.example. 3600 IN RRSIG SOA 8 2 3600 20170419140236 20170320140236 41524 nsec.example. gZCIxxFWL04vgzuNbZYq3Ghb7OZsZCp1WCcByM602yEgf0IUk8KSqkol pTem3IXQELhFTzbddGFV3Cis5MxZq8XjNbSwXelbUkOkKE4EzDcpldtR yqGnp+ZdZhBrymZvS8dOhwOGllF6AobXx7iFHaY7wtC17XvODduxOBdV mQ/t2QDUnl+Io3s1KfDRf4e22WvtatlQNr9NW+PueeGtGhEdDeyR7VMA fxEqL6Lds7NWN7DPKfsCVgUNkwHzy9opQ64AyVyQAmwRohuon652jKiu MbvJ1vaLxJLeDBnnT3hbMrI/CIfmjqucSOgM9JNXXggIcfBxok5Ze2R5 SL35VA==
+ns.nsec.example. 3600 IN RRSIG NSEC 8 3 3600 20170419140236 20170320140236 41524 nsec.example. iOfnQqIT9V87emJsd/Aym6JqU4H8bzjNq3cbWUmiohgdKr2pkqdt3RV1 r/LGbhSm+seWC/xWuBinEH2WAwXwQMUGrYi5htGazk9C97gkSvle/gXT NZweNC7SkrkBv1VXHG/PrinzFP/YWRn7zMn7fOj/uYWDaYAi0Fzh+Ctn fx2hsHIXC9LduIs+Uv9B58tr9tkF5JNYapoZO59Wtiz1GPaPnfUg9X2u 2T+J5rWpYHJkzKulW+yi0YpipfJY+9J9KWGr2PorChm/W1mc83MptyK2 Po+IbX/I0YStNv+nCLccBo94y/DGOLVnF0XpJZnR5ZDcb8ZmbZIP7uD3 GBFKMg==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+nsec.example. IN DNSKEY
+SECTION ANSWER
+nsec.example. 3600 IN DNSKEY 257 3 8 AwEAAbgyvYQ2Vlff/inpv4NZLlIk2+l1sL0JoeOUlWHZ3eeWXZKxQJak QIXyGi8xsuANzu/YStLp31SfU/Fj4piUciqA+U74Lot1S/jcM7/1eczh 69YqGUAPZkreZ3z2DpWzBN4lgPR/w0OvTada3D42uV2bzuSK/nXMiMpZ vP1vZ1ykNRmbksTzA+HnrefRi2yuMSUqMHbtfbfFwqVTQ1ddVwSK7qIJ 02jo95YJUSZDPUUQlczIsFsa7Zxn6gQZl+iaRuDY6nLxxStYYlcqZhVA G5U8Dx4IznQ0FkEJp9RXtv5rmtClcQpudCl1gE0GC/W+TTUAa3hD597f onH+s/OfdCE=
+nsec.example. 3600 IN RRSIG DNSKEY 8 2 3600 20170419140236 20170320140236 41524 nsec.example. Z1kUmre0LJX76zuKEYhCN5bNNPvXONZK8LElwgNqEQW4kPApz8+vfLmb 4Xlz6D9ChG6J0Pp/JHdKn+S+Le4B5dUOPzuOksfkHTmRsh9oN2ccSEq3 eJK1VhWwRN69xs1LZgXzVJk7DnDnPVUyIbDpb5piBCJHQVwkrIa1Ykeh hexHJb7YZBmF1B6GqTl7K9QwIvfnpKH+iM83QngepAJqpJuHSEPNWCbQ S9rfuP1SObyZD4L/Z3hBFpaZL9N25ThH7znfTc60xNCitmNMFfq68X2/ JoSrVrFLNv9nlneYNkihorhzDMlzN/i/EhrtBkdaSiRlEODnY7zN4Eax m3JkFQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname qtype
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+local.nsec.example. IN A
+SECTION ANSWER
+local.nsec.example. 3600 IN A 10.6.6.6
+local.nsec.example. 3600 IN RRSIG A 8 2 3600 20170419140236 20170320140236 41524 nsec.example. H6auzgGxcWIcfhki7px+Iza4QRw5V47GXpPFDofXoORBdGtVYOhx+ILM pYA8ng4rzYCRFh/g9j8lIzU9y9WDfJyy8CMAJUsjiin/b9iJ0heQQU9r GmV1v+MvNxlcfMdJrec2O31RKBt7bK/FFesD4l3c3+XauwsOIsry+4t6 48uzUO48QVsbuw0PPDH82fPpSNgWyiAIEVwzz/tgrekk4eDwTVUkle4A 9ntjr5CFyKuoeDVTr0rZdJ90W6j4KYRUuk3x1V5w8eil7pNIN3arBzEv OXg4Du3AYskQ98a1VWz7MO/MX9u5WciXSbpDdI/2VtxMeKzkPotDds65 zLIsTA==
+SECTION AUTHORITY
+*.nsec.example. 3600 IN NSEC ns.nsec.example. A RRSIG NSEC
+*.nsec.example. 3600 IN RRSIG NSEC 8 2 3600 20170419140236 20170320140236 41524 nsec.example. Hp/6sgDgYZuewpSkAugLRERgVAGgAIAN9vAqfuAGcqCxfQXLIXcXD8ji o4rjuSMmAaRw0AQ70pEWldc2Yqre+++/lnEJt5tpGrIhH2raJU9RS/Ix NaN40vwspRdN7tDNLH1T0oTDll76bVc/D4VFtnpGOlM3eIGjFVVdACvZ V0oVW8xp686xwB3uP2DqA0fxMjs4p9PC1FrnTAlGvTX0ThgZR6EmmWJH HCy4kpjfTFR93k/nuAendDVVZNkHL+EncojmUX+U0PRSZPXWBWXbb0kq h1OVaT4HpyWKet+PxKkTGaoNbXRk0BAKC/4Qg4A/+kRk+1OXG4dQMdsS zLnt/Q==
+ENTRY_END
+
+; missing NSEC proof
+ENTRY_BEGIN
+MATCH opcode qname qtype
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+missing-nsec-nodata.local.nsec.example. IN CNAME
+SECTION ANSWER
+nsec.example. 3600 IN SOA ns.nsec.example. root.nsec.example. 6 60 60 120 3600
+nsec.example. 3600 IN RRSIG SOA 8 2 3600 20170419140236 20170320140236 41524 nsec.example. gZCIxxFWL04vgzuNbZYq3Ghb7OZsZCp1WCcByM602yEgf0IUk8KSqkol pTem3IXQELhFTzbddGFV3Cis5MxZq8XjNbSwXelbUkOkKE4EzDcpldtR yqGnp+ZdZhBrymZvS8dOhwOGllF6AobXx7iFHaY7wtC17XvODduxOBdV mQ/t2QDUnl+Io3s1KfDRf4e22WvtatlQNr9NW+PueeGtGhEdDeyR7VMA fxEqL6Lds7NWN7DPKfsCVgUNkwHzy9opQ64AyVyQAmwRohuon652jKiu MbvJ1vaLxJLeDBnnT3hbMrI/CIfmjqucSOgM9JNXXggIcfBxok5Ze2R5 SL35VA==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname qtype
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+missing-nsec-nodata.local.nsec.example. IN RRSIG
+SECTION ANSWER
+missing-nsec-nodata.local.nsec.example. 3600 IN RRSIG A 8 2 3600 20170419140236 20170320140236 41524 nsec.example. H6auzgGxcWIcfhki7px+Iza4QRw5V47GXpPFDofXoORBdGtVYOhx+ILM pYA8ng4rzYCRFh/g9j8lIzU9y9WDfJyy8CMAJUsjiin/b9iJ0heQQU9r GmV1v+MvNxlcfMdJrec2O31RKBt7bK/FFesD4l3c3+XauwsOIsry+4t6 48uzUO48QVsbuw0PPDH82fPpSNgWyiAIEVwzz/tgrekk4eDwTVUkle4A 9ntjr5CFyKuoeDVTr0rZdJ90W6j4KYRUuk3x1V5w8eil7pNIN3arBzEv OXg4Du3AYskQ98a1VWz7MO/MX9u5WciXSbpDdI/2VtxMeKzkPotDds65 zLIsTA==
+ENTRY_END
+
+; synthesized A record was removed and replaced with SOA but no NSEC
+ENTRY_BEGIN
+MATCH opcode qname qtype
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+missing-nsec-masked-data.local.nsec.example. IN A
+SECTION ANSWER
+nsec.example. 3600 IN SOA ns.nsec.example. root.nsec.example. 6 60 60 120 3600
+nsec.example. 3600 IN RRSIG SOA 8 2 3600 20170419140236 20170320140236 41524 nsec.example. gZCIxxFWL04vgzuNbZYq3Ghb7OZsZCp1WCcByM602yEgf0IUk8KSqkol pTem3IXQELhFTzbddGFV3Cis5MxZq8XjNbSwXelbUkOkKE4EzDcpldtR yqGnp+ZdZhBrymZvS8dOhwOGllF6AobXx7iFHaY7wtC17XvODduxOBdV mQ/t2QDUnl+Io3s1KfDRf4e22WvtatlQNr9NW+PueeGtGhEdDeyR7VMA fxEqL6Lds7NWN7DPKfsCVgUNkwHzy9opQ64AyVyQAmwRohuon652jKiu MbvJ1vaLxJLeDBnnT3hbMrI/CIfmjqucSOgM9JNXXggIcfBxok5Ze2R5 SL35VA==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname qtype
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+missing-nsec-masked-data.local.nsec.example. IN RRSIG
+SECTION ANSWER
+missing-nsec-masked-data.local.nsec.example. 3600 IN RRSIG A 8 2 3600 20170419140236 20170320140236 41524 nsec.example. H6auzgGxcWIcfhki7px+Iza4QRw5V47GXpPFDofXoORBdGtVYOhx+ILM pYA8ng4rzYCRFh/g9j8lIzU9y9WDfJyy8CMAJUsjiin/b9iJ0heQQU9r GmV1v+MvNxlcfMdJrec2O31RKBt7bK/FFesD4l3c3+XauwsOIsry+4t6 48uzUO48QVsbuw0PPDH82fPpSNgWyiAIEVwzz/tgrekk4eDwTVUkle4A 9ntjr5CFyKuoeDVTr0rZdJ90W6j4KYRUuk3x1V5w8eil7pNIN3arBzEv OXg4Du3AYskQ98a1VWz7MO/MX9u5WciXSbpDdI/2VtxMeKzkPotDds65 zLIsTA==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR AA NOERROR
+SECTION QUESTION
+local.nsec.example. IN NS
+SECTION AUTHORITY
+nsec.example. 3600 IN SOA ns.nsec.example. root.nsec.example. 6 60 60 120 3600
+*.nsec.example. 3600 IN NSEC ns.nsec.example. A RRSIG NSEC
+nsec.example. 3600 IN RRSIG SOA 8 2 3600 20170419140236 20170320140236 41524 nsec.example. gZCIxxFWL04vgzuNbZYq3Ghb7OZsZCp1WCcByM602yEgf0IUk8KSqkol pTem3IXQELhFTzbddGFV3Cis5MxZq8XjNbSwXelbUkOkKE4EzDcpldtR yqGnp+ZdZhBrymZvS8dOhwOGllF6AobXx7iFHaY7wtC17XvODduxOBdV mQ/t2QDUnl+Io3s1KfDRf4e22WvtatlQNr9NW+PueeGtGhEdDeyR7VMA fxEqL6Lds7NWN7DPKfsCVgUNkwHzy9opQ64AyVyQAmwRohuon652jKiu MbvJ1vaLxJLeDBnnT3hbMrI/CIfmjqucSOgM9JNXXggIcfBxok5Ze2R5 SL35VA==
+*.nsec.example. 3600 IN RRSIG NSEC 8 2 3600 20170419140236 20170320140236 41524 nsec.example. Hp/6sgDgYZuewpSkAugLRERgVAGgAIAN9vAqfuAGcqCxfQXLIXcXD8ji o4rjuSMmAaRw0AQ70pEWldc2Yqre+++/lnEJt5tpGrIhH2raJU9RS/Ix NaN40vwspRdN7tDNLH1T0oTDll76bVc/D4VFtnpGOlM3eIGjFVVdACvZ V0oVW8xp686xwB3uP2DqA0fxMjs4p9PC1FrnTAlGvTX0ThgZR6EmmWJH HCy4kpjfTFR93k/nuAendDVVZNkHL+EncojmUX+U0PRSZPXWBWXbb0kq h1OVaT4HpyWKet+PxKkTGaoNbXRk0BAKC/4Qg4A/+kRk+1OXG4dQMdsS zLnt/Q==
+ENTRY_END
+
+RANGE_END
+
+
+STEP 20 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+missing-nsec-nodata.local.nsec.example. IN CNAME
+ENTRY_END
+
+STEP 21 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+ADJUST copy_id
+REPLY QR RD RA SERVFAIL
+SECTION QUESTION
+missing-nsec-nodata.local.nsec.example. IN CNAME
+ENTRY_END
+
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/nsec_wildcard_no_data_response.rpl b/tests/integration/deckard/sets/resolver/nsec_wildcard_no_data_response.rpl
new file mode 100644
index 0000000..0eb45b0
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/nsec_wildcard_no_data_response.rpl
@@ -0,0 +1,284 @@
+do-ip6: no
+
+; config options
+;server:
+ trust-anchor: "nsec.example. IN DS 41524 8 2 D6B102667845D6CDDC05B44466426D9CCC189989BF67ADB23605EED0 BFE2A443"
+ val-override-date: "20170401000000"
+
+;stub-zone:
+; name: "."
+ stub-addr: 192.0.2.1 # ns.
+CONFIG_END
+
+SCENARIO_BEGIN Test validation of NSEC name error responses.
+
+; ns.
+RANGE_BEGIN 0 100
+ ADDRESS 192.0.2.1
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. 3600 IN NS ns.
+SECTION ADDITIONAL
+ns. 3600 IN A 192.0.2.1
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns. IN A
+SECTION ANSWER
+ns. 3600 IN A 192.0.2.1
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname qtype
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns. IN AAAA
+SECTION AUTHORITY
+. 3600 IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example. IN CNAME
+SECTION AUTHORITY
+example. 3600 IN NS ns.example.
+SECTION ADDITIONAL
+ns.example. 3600 IN A 192.0.2.2
+ENTRY_END
+
+RANGE_END
+
+; ns.example.
+RANGE_BEGIN 0 100
+ ADDRESS 192.0.2.2
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+example. IN NS
+SECTION ANSWER
+example. 3600 IN NS ns.example.
+SECTION ADDITIONAL
+ns.example. 3600 IN A 192.0.2.2
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns.example. IN A
+SECTION ANSWER
+ns.example. 3600 IN A 192.0.2.2
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns.example. IN AAAA
+SECTION AUTHORITY
+example. 3600 IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+nsec.example. IN CNAME
+SECTION AUTHORITY
+nsec.example. 3600 IN NS ns.nsec.example.
+SECTION ADDITIONAL
+ns.nsec.example. 3600 IN A 192.0.2.3
+ENTRY_END
+
+RANGE_END
+
+; ns.nsec.example.
+RANGE_BEGIN 0 100
+ ADDRESS 192.0.2.3
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+nsec.example. IN NS
+SECTION ANSWER
+nsec.example. 3600 IN NS ns.nsec.example.
+nsec.example. 3600 IN RRSIG NS 8 2 3600 20170419140236 20170320140236 41524 nsec.example. KECif/B3ckfo5d9Qd/5dtIDt/8nIpTfTMxeJU3qw1U8jzQ/+nQ6qZAvr GH4MeGwY0M9kj2Jj3h2tdI+uhfLaGC7LStXIG0Q+PfalGdddDQwwd/p0 oOQ6bt0eilZN5OKF7Frzn4jmV1x7R/iieWp65xB7OByvguYoXOlzuoU1 ikaL43rm/whxn6iHf0K7NfaVqQwO26N/P3EBFFZMwuhHOB2+bVXKoE7r O4bC04tF7wG7CRUlc44xNs08L512RXRuFIrkHg932BFVlEYmPwbflE6+ zfpZafFzYutEHx7XZw2+gAklynmcAXltPCOiqThkDJzw2rpyUmiH0ztm lG76Tg==
+SECTION ADDITIONAL
+ns.nsec.example. 3600 IN A 192.0.2.3
+ns.nsec.example. 3600 IN RRSIG A 8 3 3600 20170419140236 20170320140236 41524 nsec.example. E6Cx+MIElwAbw4Hg48Ee4CC4pKSjPkW8fmcHVoTqNwMyRs4Jjyymf1tE mNdjYkoN0kxI8PEgbGxzuwlFLpGncQhuZ0dyTzCPvnYFPLIkDmdtyIcj 4MVZiJpdyc5yRTC+Aja1Ik9cQ25QsSGAg4z54Zv0o6uqodppCHILgBzm Q833AQFh6hOQE3BFM3c8h3PCsH6HJOOIlgqculfT5d0S1XPFGmtjVW4G gZNsNeBtLB/SkvYKzNS+Yw38J9VTtWMlgTUwkjVXzC+f83AgzXHM3neq QhRhf72VO/xP5sd33VXDVBtOqbFSDZHLpGLfaXJSrnzKX5H8nCMuIXbs kWK60w==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns.nsec.example. IN A
+SECTION ANSWER
+ns.nsec.example. 3600 IN A 192.0.2.3
+ns.nsec.example. 3600 IN RRSIG A 8 3 3600 20170419140236 20170320140236 41524 nsec.example. E6Cx+MIElwAbw4Hg48Ee4CC4pKSjPkW8fmcHVoTqNwMyRs4Jjyymf1tE mNdjYkoN0kxI8PEgbGxzuwlFLpGncQhuZ0dyTzCPvnYFPLIkDmdtyIcj 4MVZiJpdyc5yRTC+Aja1Ik9cQ25QsSGAg4z54Zv0o6uqodppCHILgBzm Q833AQFh6hOQE3BFM3c8h3PCsH6HJOOIlgqculfT5d0S1XPFGmtjVW4G gZNsNeBtLB/SkvYKzNS+Yw38J9VTtWMlgTUwkjVXzC+f83AgzXHM3neq QhRhf72VO/xP5sd33VXDVBtOqbFSDZHLpGLfaXJSrnzKX5H8nCMuIXbs kWK60w==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns.nsec.example. IN AAAA
+SECTION AUTHORITY
+nsec.example. 3600 IN SOA ns.nsec.example. root.nsec.example. 6 60 60 120 3600
+ns.nsec.example. 3600 IN NSEC nsec.example. A RRSIG NSEC
+nsec.example. 3600 IN RRSIG SOA 8 2 3600 20170419140236 20170320140236 41524 nsec.example. gZCIxxFWL04vgzuNbZYq3Ghb7OZsZCp1WCcByM602yEgf0IUk8KSqkol pTem3IXQELhFTzbddGFV3Cis5MxZq8XjNbSwXelbUkOkKE4EzDcpldtR yqGnp+ZdZhBrymZvS8dOhwOGllF6AobXx7iFHaY7wtC17XvODduxOBdV mQ/t2QDUnl+Io3s1KfDRf4e22WvtatlQNr9NW+PueeGtGhEdDeyR7VMA fxEqL6Lds7NWN7DPKfsCVgUNkwHzy9opQ64AyVyQAmwRohuon652jKiu MbvJ1vaLxJLeDBnnT3hbMrI/CIfmjqucSOgM9JNXXggIcfBxok5Ze2R5 SL35VA==
+ns.nsec.example. 3600 IN RRSIG NSEC 8 3 3600 20170419140236 20170320140236 41524 nsec.example. iOfnQqIT9V87emJsd/Aym6JqU4H8bzjNq3cbWUmiohgdKr2pkqdt3RV1 r/LGbhSm+seWC/xWuBinEH2WAwXwQMUGrYi5htGazk9C97gkSvle/gXT NZweNC7SkrkBv1VXHG/PrinzFP/YWRn7zMn7fOj/uYWDaYAi0Fzh+Ctn fx2hsHIXC9LduIs+Uv9B58tr9tkF5JNYapoZO59Wtiz1GPaPnfUg9X2u 2T+J5rWpYHJkzKulW+yi0YpipfJY+9J9KWGr2PorChm/W1mc83MptyK2 Po+IbX/I0YStNv+nCLccBo94y/DGOLVnF0XpJZnR5ZDcb8ZmbZIP7uD3 GBFKMg==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+nsec.example. IN DNSKEY
+SECTION ANSWER
+nsec.example. 3600 IN DNSKEY 257 3 8 AwEAAbgyvYQ2Vlff/inpv4NZLlIk2+l1sL0JoeOUlWHZ3eeWXZKxQJak QIXyGi8xsuANzu/YStLp31SfU/Fj4piUciqA+U74Lot1S/jcM7/1eczh 69YqGUAPZkreZ3z2DpWzBN4lgPR/w0OvTada3D42uV2bzuSK/nXMiMpZ vP1vZ1ykNRmbksTzA+HnrefRi2yuMSUqMHbtfbfFwqVTQ1ddVwSK7qIJ 02jo95YJUSZDPUUQlczIsFsa7Zxn6gQZl+iaRuDY6nLxxStYYlcqZhVA G5U8Dx4IznQ0FkEJp9RXtv5rmtClcQpudCl1gE0GC/W+TTUAa3hD597f onH+s/OfdCE=
+nsec.example. 3600 IN RRSIG DNSKEY 8 2 3600 20170419140236 20170320140236 41524 nsec.example. Z1kUmre0LJX76zuKEYhCN5bNNPvXONZK8LElwgNqEQW4kPApz8+vfLmb 4Xlz6D9ChG6J0Pp/JHdKn+S+Le4B5dUOPzuOksfkHTmRsh9oN2ccSEq3 eJK1VhWwRN69xs1LZgXzVJk7DnDnPVUyIbDpb5piBCJHQVwkrIa1Ykeh hexHJb7YZBmF1B6GqTl7K9QwIvfnpKH+iM83QngepAJqpJuHSEPNWCbQ S9rfuP1SObyZD4L/Z3hBFpaZL9N25ThH7znfTc60xNCitmNMFfq68X2/ JoSrVrFLNv9nlneYNkihorhzDMlzN/i/EhrtBkdaSiRlEODnY7zN4Eax m3JkFQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname qtype
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+local.nsec.example. IN A
+SECTION ANSWER
+local.nsec.example. 3600 IN A 10.6.6.6
+local.nsec.example. 3600 IN RRSIG A 8 2 3600 20170419140236 20170320140236 41524 nsec.example. H6auzgGxcWIcfhki7px+Iza4QRw5V47GXpPFDofXoORBdGtVYOhx+ILM pYA8ng4rzYCRFh/g9j8lIzU9y9WDfJyy8CMAJUsjiin/b9iJ0heQQU9r GmV1v+MvNxlcfMdJrec2O31RKBt7bK/FFesD4l3c3+XauwsOIsry+4t6 48uzUO48QVsbuw0PPDH82fPpSNgWyiAIEVwzz/tgrekk4eDwTVUkle4A 9ntjr5CFyKuoeDVTr0rZdJ90W6j4KYRUuk3x1V5w8eil7pNIN3arBzEv OXg4Du3AYskQ98a1VWz7MO/MX9u5WciXSbpDdI/2VtxMeKzkPotDds65 zLIsTA==
+SECTION AUTHORITY
+*.nsec.example. 3600 IN NSEC ns.nsec.example. A RRSIG NSEC
+*.nsec.example. 3600 IN RRSIG NSEC 8 2 3600 20170419140236 20170320140236 41524 nsec.example. Hp/6sgDgYZuewpSkAugLRERgVAGgAIAN9vAqfuAGcqCxfQXLIXcXD8ji o4rjuSMmAaRw0AQ70pEWldc2Yqre+++/lnEJt5tpGrIhH2raJU9RS/Ix NaN40vwspRdN7tDNLH1T0oTDll76bVc/D4VFtnpGOlM3eIGjFVVdACvZ V0oVW8xp686xwB3uP2DqA0fxMjs4p9PC1FrnTAlGvTX0ThgZR6EmmWJH HCy4kpjfTFR93k/nuAendDVVZNkHL+EncojmUX+U0PRSZPXWBWXbb0kq h1OVaT4HpyWKet+PxKkTGaoNbXRk0BAKC/4Qg4A/+kRk+1OXG4dQMdsS zLnt/Q==
+ENTRY_END
+
+; missing NSEC proof
+ENTRY_BEGIN
+MATCH opcode qname qtype
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+missing-nsec-nodata.local.nsec.example. IN CNAME
+SECTION ANSWER
+nsec.example. 3600 IN SOA ns.nsec.example. root.nsec.example. 6 60 60 120 3600
+nsec.example. 3600 IN RRSIG SOA 8 2 3600 20170419140236 20170320140236 41524 nsec.example. gZCIxxFWL04vgzuNbZYq3Ghb7OZsZCp1WCcByM602yEgf0IUk8KSqkol pTem3IXQELhFTzbddGFV3Cis5MxZq8XjNbSwXelbUkOkKE4EzDcpldtR yqGnp+ZdZhBrymZvS8dOhwOGllF6AobXx7iFHaY7wtC17XvODduxOBdV mQ/t2QDUnl+Io3s1KfDRf4e22WvtatlQNr9NW+PueeGtGhEdDeyR7VMA fxEqL6Lds7NWN7DPKfsCVgUNkwHzy9opQ64AyVyQAmwRohuon652jKiu MbvJ1vaLxJLeDBnnT3hbMrI/CIfmjqucSOgM9JNXXggIcfBxok5Ze2R5 SL35VA==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname qtype
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+missing-nsec-nodata.local.nsec.example. IN RRSIG
+SECTION ANSWER
+missing-nsec-nodata.local.nsec.example. 3600 IN RRSIG A 8 2 3600 20170419140236 20170320140236 41524 nsec.example. H6auzgGxcWIcfhki7px+Iza4QRw5V47GXpPFDofXoORBdGtVYOhx+ILM pYA8ng4rzYCRFh/g9j8lIzU9y9WDfJyy8CMAJUsjiin/b9iJ0heQQU9r GmV1v+MvNxlcfMdJrec2O31RKBt7bK/FFesD4l3c3+XauwsOIsry+4t6 48uzUO48QVsbuw0PPDH82fPpSNgWyiAIEVwzz/tgrekk4eDwTVUkle4A 9ntjr5CFyKuoeDVTr0rZdJ90W6j4KYRUuk3x1V5w8eil7pNIN3arBzEv OXg4Du3AYskQ98a1VWz7MO/MX9u5WciXSbpDdI/2VtxMeKzkPotDds65 zLIsTA==
+ENTRY_END
+
+; synthesized A record was removed and replaced with SOA but no NSEC
+ENTRY_BEGIN
+MATCH opcode qname qtype
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+missing-nsec-masked-data.local.nsec.example. IN A
+SECTION ANSWER
+nsec.example. 3600 IN SOA ns.nsec.example. root.nsec.example. 6 60 60 120 3600
+nsec.example. 3600 IN RRSIG SOA 8 2 3600 20170419140236 20170320140236 41524 nsec.example. gZCIxxFWL04vgzuNbZYq3Ghb7OZsZCp1WCcByM602yEgf0IUk8KSqkol pTem3IXQELhFTzbddGFV3Cis5MxZq8XjNbSwXelbUkOkKE4EzDcpldtR yqGnp+ZdZhBrymZvS8dOhwOGllF6AobXx7iFHaY7wtC17XvODduxOBdV mQ/t2QDUnl+Io3s1KfDRf4e22WvtatlQNr9NW+PueeGtGhEdDeyR7VMA fxEqL6Lds7NWN7DPKfsCVgUNkwHzy9opQ64AyVyQAmwRohuon652jKiu MbvJ1vaLxJLeDBnnT3hbMrI/CIfmjqucSOgM9JNXXggIcfBxok5Ze2R5 SL35VA==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname qtype
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+missing-nsec-masked-data.local.nsec.example. IN RRSIG
+SECTION ANSWER
+missing-nsec-masked-data.local.nsec.example. 3600 IN RRSIG A 8 2 3600 20170419140236 20170320140236 41524 nsec.example. H6auzgGxcWIcfhki7px+Iza4QRw5V47GXpPFDofXoORBdGtVYOhx+ILM pYA8ng4rzYCRFh/g9j8lIzU9y9WDfJyy8CMAJUsjiin/b9iJ0heQQU9r GmV1v+MvNxlcfMdJrec2O31RKBt7bK/FFesD4l3c3+XauwsOIsry+4t6 48uzUO48QVsbuw0PPDH82fPpSNgWyiAIEVwzz/tgrekk4eDwTVUkle4A 9ntjr5CFyKuoeDVTr0rZdJ90W6j4KYRUuk3x1V5w8eil7pNIN3arBzEv OXg4Du3AYskQ98a1VWz7MO/MX9u5WciXSbpDdI/2VtxMeKzkPotDds65 zLIsTA==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR AA NOERROR
+SECTION QUESTION
+local.nsec.example. IN NS
+SECTION AUTHORITY
+nsec.example. 3600 IN SOA ns.nsec.example. root.nsec.example. 6 60 60 120 3600
+*.nsec.example. 3600 IN NSEC ns.nsec.example. A RRSIG NSEC
+nsec.example. 3600 IN RRSIG SOA 8 2 3600 20170419140236 20170320140236 41524 nsec.example. gZCIxxFWL04vgzuNbZYq3Ghb7OZsZCp1WCcByM602yEgf0IUk8KSqkol pTem3IXQELhFTzbddGFV3Cis5MxZq8XjNbSwXelbUkOkKE4EzDcpldtR yqGnp+ZdZhBrymZvS8dOhwOGllF6AobXx7iFHaY7wtC17XvODduxOBdV mQ/t2QDUnl+Io3s1KfDRf4e22WvtatlQNr9NW+PueeGtGhEdDeyR7VMA fxEqL6Lds7NWN7DPKfsCVgUNkwHzy9opQ64AyVyQAmwRohuon652jKiu MbvJ1vaLxJLeDBnnT3hbMrI/CIfmjqucSOgM9JNXXggIcfBxok5Ze2R5 SL35VA==
+*.nsec.example. 3600 IN RRSIG NSEC 8 2 3600 20170419140236 20170320140236 41524 nsec.example. Hp/6sgDgYZuewpSkAugLRERgVAGgAIAN9vAqfuAGcqCxfQXLIXcXD8ji o4rjuSMmAaRw0AQ70pEWldc2Yqre+++/lnEJt5tpGrIhH2raJU9RS/Ix NaN40vwspRdN7tDNLH1T0oTDll76bVc/D4VFtnpGOlM3eIGjFVVdACvZ V0oVW8xp686xwB3uP2DqA0fxMjs4p9PC1FrnTAlGvTX0ThgZR6EmmWJH HCy4kpjfTFR93k/nuAendDVVZNkHL+EncojmUX+U0PRSZPXWBWXbb0kq h1OVaT4HpyWKet+PxKkTGaoNbXRk0BAKC/4Qg4A/+kRk+1OXG4dQMdsS zLnt/Q==
+ENTRY_END
+
+RANGE_END
+
+STEP 10 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+aaa.local.nsec.example. IN CNAME
+ENTRY_END
+
+; recursion happens here, we expect NODATA with wildcard proof
+STEP 11 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+ADJUST copy_id
+REPLY QR RD RA AD NOERROR
+SECTION QUESTION
+aaa.local.nsec.example. IN CNAME
+SECTION AUTHORITY
+nsec.example. 3600 IN SOA ns.nsec.example. root.nsec.example. 6 60 60 120 3600
+*.nsec.example. 3600 IN NSEC ns.nsec.example. A RRSIG NSEC
+nsec.example. 3600 IN RRSIG SOA 8 2 3600 20170419140236 20170320140236 41524 nsec.example. gZCIxxFWL04vgzuNbZYq3Ghb7OZsZCp1WCcByM602yEgf0IUk8KSqkol pTem3IXQELhFTzbddGFV3Cis5MxZq8XjNbSwXelbUkOkKE4EzDcpldtR yqGnp+ZdZhBrymZvS8dOhwOGllF6AobXx7iFHaY7wtC17XvODduxOBdV mQ/t2QDUnl+Io3s1KfDRf4e22WvtatlQNr9NW+PueeGtGhEdDeyR7VMA fxEqL6Lds7NWN7DPKfsCVgUNkwHzy9opQ64AyVyQAmwRohuon652jKiu MbvJ1vaLxJLeDBnnT3hbMrI/CIfmjqucSOgM9JNXXggIcfBxok5Ze2R5 SL35VA==
+*.nsec.example. 3600 IN RRSIG NSEC 8 2 3600 20170419140236 20170320140236 41524 nsec.example. Hp/6sgDgYZuewpSkAugLRERgVAGgAIAN9vAqfuAGcqCxfQXLIXcXD8ji o4rjuSMmAaRw0AQ70pEWldc2Yqre+++/lnEJt5tpGrIhH2raJU9RS/Ix NaN40vwspRdN7tDNLH1T0oTDll76bVc/D4VFtnpGOlM3eIGjFVVdACvZ V0oVW8xp686xwB3uP2DqA0fxMjs4p9PC1FrnTAlGvTX0ThgZR6EmmWJH HCy4kpjfTFR93k/nuAendDVVZNkHL+EncojmUX+U0PRSZPXWBWXbb0kq h1OVaT4HpyWKet+PxKkTGaoNbXRk0BAKC/4Qg4A/+kRk+1OXG4dQMdsS zLnt/Q==
+ENTRY_END
+
+;; TODO: use INCLUDE when it's available.
+;; Aggressive cache can answer STEP20 without asking,
+;; from the record in previous answer, so it has been split-out for now.
+
+; missing data in NOERROR answer synthtesized from wildcard must be detected
+STEP 30 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+missing-nsec-masked-data.local.nsec.example. IN A
+ENTRY_END
+
+STEP 31 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+ADJUST copy_id
+REPLY QR RD RA SERVFAIL
+SECTION QUESTION
+missing-nsec-masked-data.local.nsec.example. IN A
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/val_ad_qtype_ds.rpl b/tests/integration/deckard/sets/resolver/val_ad_qtype_ds.rpl
new file mode 100644
index 0000000..4066f3d
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_ad_qtype_ds.rpl
@@ -0,0 +1,198 @@
+do-ip6: no
+
+; config options
+ stub-addr: 193.0.14.129
+ trust-anchor: ". IN DS 49060 8 2 E7B1EB56D7D5791B3D45630FEAA9C823DB84B385ACEEAC5F44DD0888 5C36700F"
+ val-override-date: "20170807130000"
+CONFIG_END
+
+SCENARIO_BEGIN Test setting AD bit in secured answer which contains proof of DS record non-existence
+
+RANGE_BEGIN 1 2
+ ADDRESS 193.0.14.129 ;k.root-servers.net
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RD RA AD NOERROR
+SECTION QUESTION
+. IN SOA
+SECTION ANSWER
+. 86400 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2017030902 1800 900 604800 86400
+. 86400 IN RRSIG SOA 8 0 86400 20170831093859 20170801093859 20661 . wYDoBQrcHODYzOxqM+P+gOfgi4HCFNtdhnIZtuoc2vujg6J9U3zYUg3H u78cOyqEJ/H6iTxnVGmJvGYSh+Cf0TiDfgDL0TbQrfisTtAKOGNbLVb0 wfGzroQ08c2i/R2xXyN6ZA/0ywYdyJe1bhRlWcDGhbUTDpKBhMAFxCZe NaIt/gT1TCODgjgHsRMjj3uxxtPef3/A3+x4iUt9PdQxTJoPXo21nEin PY4ByO80QYYa8iomOJG7PauhhZk4/md03bSU1F+AlniiuiFHNsvdpyxO qimsB9sQW5sr1wVgQ25BKlUrwwqeTE+gEECR5BGF29YjRHLN5OEban4N 1Lv3SA==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RD RA AD NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. 518400 IN NS k.root-servers.net.
+. 518400 IN RRSIG NS 8 0 518400 20170831093859 20170801093859 20661 . tRUB/UNRUgLH8jn9wda2CjPW3+2IuahZXB3LyPiP+ENd8Tu37WuYr9R9 a0Pi1/WSrliQtmxNCbmbPi36EBo0Wi4YXAEuaD6ip3ARC0QBWstzlMnN ea1IgiWoP61NtauuElQzRb6PL03cmg1ouElvlncMNkhkzupHIee060Ok OSHPk4scXnAaxJ4dASLZCYza6C2k0VqCMI2qJ8kDlfm2/Lt8PPFyhGYa bQaO4zzOecg2dvDDSdw4STBjL3K84enZ/ilTo81zrM1O4SNe2TYm8C37 cMlNXQ+XB0O4+18UzjNDKCMfJ1H6rXt6A52MU2ZONOT6U+eanM7RKfZd 6NSTYw==
+
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RD RA AD NOERROR
+SECTION QUESTION
+. IN DNSKEY
+SECTION ANSWER
+. 3600000 IN DNSKEY 256 3 8 AwEAAe1oA46eOLNris1CtS0qM5TdMESK6i4hpalqa6JDv57eOUkaOeje ZW1tIFUokmaK7kuKEFEosddA89CYM8rt2RbC+sfKalbHAWOus0tXZyAL efb2sW95QRzyG6LNul0jQFn9eYWBUHrVe5Wqd0zrFCbTQLUhELSfrlkI UBpO/xKaGinRHX2JjyOnle4aPZY3bEVa/+KyY2ZU6UC4SBo3aHXanP26 ok91rOTmpTWp64ybsMdCXOU8deyuQFQf6q8DhIDmJrkymhX1MXWQQlE0 fAYIYf8/t9OCwucg8oEg4FPU8Gb4Zm/l6PgO4HFkFjBT6iGFCQt3qXe2 Qe3alUWoATc=
+. 3600000 IN DNSKEY 257 3 8 AwEAAb8sZgVVa02muJ+/+SVhJAvz2EWKGEGquhPbQXuF6ALBYoF4KWTO bZVF8sIVTGoaX5+UWkwwHthg7RwS1DALT/AJymYeHhUwA04gLsfCZ/cv BjmRy5RozeSJ1uxAhoCYHCT2hQBZ0cH0n8roXFXI2Y+6708pO1IBkTPT 9MpAGfezTtGYOortbSn+vqT/Zu8jOpNwkleXON4rlZRBZPd4JUMGL9Y5 N/j6+ClYeM+eFQTKXrLi1oC+0yK1sG5OlqrBDhAhBnz+IhfZz4TOkqJ9 Li2BVMatHBeB9GQHtu0FZuC3J0EQgiZxvq1RgkefFJAiB+5uVRN8U7up 5mLDxSgmT0M=
+. 2592000 IN RRSIG DNSKEY 8 0 3600000 20170831093859 20170801093859 20661 . q3gs2/4X9gIYWZ0nR/ADRFFgeJaaJ/jmXysnMa2I+uuuPutjegwudOCe qEG7NKc/S0Sb90KspvAfWBb4E8UeBlkgNk4aGrzM5lNWinEJ7lszUn7Z 3kpg7m1xyzgt0YxOxrQiyznA4x2wom/66G7Bc8XkajSV7+6+ZIHxQqid hVFq2zg2UdfNVMTXHfaCrtQrTxQJZ19M+IJmGIjFjomIyrE4BEiL6IcM vyK9/kdWL892wMwYxlAoMWIHPz2mU5WbmOPqgEzd8Wwc7RwTZFgE6wqL vo6JZDRME70ScN4iIXQHfVcJMYJscoFiMfhnrlOfbeB1dDKjBcWimCf4 uJ2hDw==
+. 2592000 IN RRSIG DNSKEY 8 0 3600000 20170831093859 20170801093859 49060 . lpsdS4U/p63Jl4YimV5+S0jxuMZoFPGiskKCUOhdUS6pN2yoFAHDVsx6 MmbswhIw9NFSmjuxuWvz4iSuLIEL4L7CFSK0g/RNJx2MabJJS40ZONJy sDFRNvBROwPI8AgOdXuimWausYHwJU3MG+q15GC0k31WTA3JPhDXpfCx ULusODH4FwjrvuQMVSZId0hF7LLrH4/rTEVE/EkXohQ2/all51v8OEn3 8zulw9nol1w0rAYpGV3BNWUYtHKY64eZHOxlArvWFZbf5R1JV0MAsa2U zqjBwI3dMTyVPIerLcR77dPNCMXNxo/81Ye37YA/H8ABTda67SPhD+hf GcP6Tg==
+
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RD RA REFUSED
+SECTION QUESTION
+. IN RRSIG
+SECTION ANSWER
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RD RA AD NOERROR
+SECTION QUESTION
+test. IN NS
+SECTION ANSWER
+test. IN NS ns.net
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+test. IN DS
+SECTION AUTHORITY
+. 86400 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2017030902 1800 900 604800 86400
+test. 86400 IN NSEC . NS RRSIG NSEC
+. 86400 IN RRSIG SOA 8 0 86400 20170831093859 20170801093859 20661 . wYDoBQrcHODYzOxqM+P+gOfgi4HCFNtdhnIZtuoc2vujg6J9U3zYUg3H u78cOyqEJ/H6iTxnVGmJvGYSh+Cf0TiDfgDL0TbQrfisTtAKOGNbLVb0 wfGzroQ08c2i/R2xXyN6ZA/0ywYdyJe1bhRlWcDGhbUTDpKBhMAFxCZe NaIt/gT1TCODgjgHsRMjj3uxxtPef3/A3+x4iUt9PdQxTJoPXo21nEin PY4ByO80QYYa8iomOJG7PauhhZk4/md03bSU1F+AlniiuiFHNsvdpyxO qimsB9sQW5sr1wVgQ25BKlUrwwqeTE+gEECR5BGF29YjRHLN5OEban4N 1Lv3SA==
+test. 86400 IN RRSIG NSEC 8 1 86400 20170831093859 20170801093859 20661 . BjSarwsXmvmeIXuEZyCKpFpB6eU8w+Nz98pGxp7B18BZGysjjAHEV+Y+ +aqGX0KP9S3ZdKO4zc8p4iBUbCzprN80Zkn/1eIZnbil4zZsnxkqXgZG 0hcUK/H2ximacRtL0ITEmQ0iTykFzo9OVgv+OgKigyBqZvziahPVhN8/ zl/wbqGdVx8UUgvvMUsTITSWdfZt3UK6KKVpQIrwuJroaVLvc69uxkLm 1ZCHe1FTf385yf7pKLD3vkJ2rWh4MZHwls6YQXUCDv4jf7D+rXIde/Jk SB9yko98xcu+ccdoCoFWzoBI2Ep0Io4bV40Izq+NwiYmMOpPL03SQrOq WRImyQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RD RA REFUSED
+SECTION QUESTION
+test. IN RRSIG
+SECTION ANSWER
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RD RA AD NOERROR
+SECTION QUESTION
+net. IN NS
+SECTION AUTHORITY
+. 86400 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2017030902 1800 900 604800 86400
+. 86400 IN RRSIG SOA 8 0 86400 20170831093859 20170801093859 20661 . wYDoBQrcHODYzOxqM+P+gOfgi4HCFNtdhnIZtuoc2vujg6J9U3zYUg3H u78cOyqEJ/H6iTxnVGmJvGYSh+Cf0TiDfgDL0TbQrfisTtAKOGNbLVb0 wfGzroQ08c2i/R2xXyN6ZA/0ywYdyJe1bhRlWcDGhbUTDpKBhMAFxCZe NaIt/gT1TCODgjgHsRMjj3uxxtPef3/A3+x4iUt9PdQxTJoPXo21nEin PY4ByO80QYYa8iomOJG7PauhhZk4/md03bSU1F+AlniiuiFHNsvdpyxO qimsB9sQW5sr1wVgQ25BKlUrwwqeTE+gEECR5BGF29YjRHLN5OEban4N
+. 86400 IN NSEC ns.net. NS SOA RRSIG NSEC DNSKEY
+. 86400 IN RRSIG NSEC 8 0 86400 20170831093859 20170801093859 20661 . o4mpXOChyzVuB08Yu18oUFyNw+rYlia6nNe05ESNkW3sx+umUTX7SvzO 4QrpOIGqflr2Jxks5kLMK6b3q0pDq/d1Z5zAMIlOHsjtMYvVqz4LJHiu kqsoKKBSxY6LEfsalcRE02VhSNuQLZXiUDbeErO1kBU05fIAc7lfefS1 iNqUvZ2u6u3SiEJISWu0l7+IVPCd/0DaoQUsp2ja3MuYOM36sYsa8yxE /lDqHzgSj+qBn2fMUcu9CEzNwVXhAK65ngu6rSlbhG+NdAkpHRgsKXxL qSC/iFoGm2cZ1idMCijIdoj6/qf2aMPh7ThrfXaHmf5ZhePXxdqIrmPO IpU3Ww==
+
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RD RA AD NOERROR
+SECTION QUESTION
+root-servers.net. IN NS
+SECTION AUTHORITY
+. 86400 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2017030902 1800 900 604800 86400
+. 86400 IN RRSIG SOA 8 0 86400 20170831093859 20170801093859 20661 . wYDoBQrcHODYzOxqM+P+gOfgi4HCFNtdhnIZtuoc2vujg6J9U3zYUg3H u78cOyqEJ/H6iTxnVGmJvGYSh+Cf0TiDfgDL0TbQrfisTtAKOGNbLVb0 wfGzroQ08c2i/R2xXyN6ZA/0ywYdyJe1bhRlWcDGhbUTDpKBhMAFxCZe NaIt/gT1TCODgjgHsRMjj3uxxtPef3/A3+x4iUt9PdQxTJoPXo21nEin PY4ByO80QYYa8iomOJG7PauhhZk4/md03bSU1F+AlniiuiFHNsvdpyxO qimsB9sQW5sr1wVgQ25BKlUrwwqeTE+gEECR5BGF29YjRHLN5OEban4N
+. 86400 IN NSEC ns.net. NS SOA RRSIG NSEC DNSKEY
+. 86400 IN RRSIG NSEC 8 0 86400 20170831093859 20170801093859 20661 . o4mpXOChyzVuB08Yu18oUFyNw+rYlia6nNe05ESNkW3sx+umUTX7SvzO 4QrpOIGqflr2Jxks5kLMK6b3q0pDq/d1Z5zAMIlOHsjtMYvVqz4LJHiu kqsoKKBSxY6LEfsalcRE02VhSNuQLZXiUDbeErO1kBU05fIAc7lfefS1 iNqUvZ2u6u3SiEJISWu0l7+IVPCd/0DaoQUsp2ja3MuYOM36sYsa8yxE /lDqHzgSj+qBn2fMUcu9CEzNwVXhAK65ngu6rSlbhG+NdAkpHRgsKXxL qSC/iFoGm2cZ1idMCijIdoj6/qf2aMPh7ThrfXaHmf5ZhePXxdqIrmPO IpU3Ww==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RD RA AD NOERROR
+SECTION QUESTION
+ns.net. IN A
+SECTION ANSWER
+ns.net. 600 IN A 1.1.1.1
+ns.net. 600 IN RRSIG A 8 2 600 20170831093859 20170801093859 20661 . mOCn7tQWemwBfXtGUSexyMARUQFmWH6Sk6Z6U1HRB3dn7yZxHYf+tw/+ 3bLHv38zeqdOU0cgUMDsthWkzFfKDL+CgW/dNO6oY/9UmX0p8mqgQ5Yw J4uH82il0TBlbnr4TkNz27EQgGiQvKdOyEPW5/+Ogh1M0b228jMY0DzV gzk9shaGZGH7mzJyKX9JPtG+sEvx6YsNTN3MP4s5JBaIk3sMczz+szb4 nmx+AvIuJnTQXq/dH/emTR/JzPsSZryadtf/Y+zOQnVg3YcaUs9yaIFj 4aq1aRMPPX6asCKliOeixC4qPR/fJkaVtN7Q3oiE0M3ci2jAj1JJLL6g /fDfZA==
+
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RD RA AD NOERROR
+SECTION QUESTION
+k.root-servers.net. IN A
+SECTION ANSWER
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 2592000 IN RRSIG A 8 3 3600000 20170831093859 20170801093859 20661 . WkAHLRnyepbR5iqggYRyFmUIgXhZpnyEL/CUlQ/AEf5c6so1cmWlzVXd TuuUtkNbkVEq8bbvOxa1jFF01vVituLlwn1wEuTdfpgOBDOHxf5/jASm CZ+/31Lln3scmDVRuAyKDO9tvR0O6N/WKFOYcGhrtfQ21P4f58aFLy11 F4kKpARwyhBMhB4/MpmOMKcWhTx8Fyackwl20uBZMi85+aBhR2eJMloN YEvphzLvBwvNTaNrXBlDrtz6Kbrr0akRdd2jFoyRe+0DGSEvI7ujaMuo +v+yxg6qW6q125R7++69vis2HRbm1Hjb23EbH+AH7H9mL+royo0+GY3C 5fYUeg==
+
+ENTRY_END
+RANGE_END
+
+RANGE_BEGIN 1 2
+ ADDRESS 1.1.1.1 ;ns.net
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+test. IN SOA
+SECTION ANSWER
+test. 86400 IN SOA ns.net. hostmaster.example.com. 1234 1800 900 604800 86400
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+test. IN NS
+SECTION ANSWER
+test. IN NS ns.net
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+ns.net. IN A
+SECTION ANSWER
+ns.net. 86400 IN A 1.1.1.1
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD AD DO
+SECTION QUESTION
+test. IN DS
+ENTRY_END
+
+STEP 2 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA AD NOERROR ; AD flag is set
+SECTION QUESTION
+test. IN DS
+SECTION ANSWER
+SECTION AUTHORITY
+. 86400 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2017030902 1800 900 604800 86400
+test. 86400 IN NSEC . NS RRSIG NSEC
+. 86400 IN RRSIG SOA 8 0 86400 20170831093859 20170801093859 20661 . wYDoBQrcHODYzOxqM+P+gOfgi4HCFNtdhnIZtuoc2vujg6J9U3zYUg3H u78cOyqEJ/H6iTxnVGmJvGYSh+Cf0TiDfgDL0TbQrfisTtAKOGNbLVb0 wfGzroQ08c2i/R2xXyN6ZA/0ywYdyJe1bhRlWcDGhbUTDpKBhMAFxCZe NaIt/gT1TCODgjgHsRMjj3uxxtPef3/A3+x4iUt9PdQxTJoPXo21nEin PY4ByO80QYYa8iomOJG7PauhhZk4/md03bSU1F+AlniiuiFHNsvdpyxO qimsB9sQW5sr1wVgQ25BKlUrwwqeTE+gEECR5BGF29YjRHLN5OEban4N 1Lv3SA==
+test. 86400 IN RRSIG NSEC 8 1 86400 20170831093859 20170801093859 20661 . BjSarwsXmvmeIXuEZyCKpFpB6eU8w+Nz98pGxp7B18BZGysjjAHEV+Y+ +aqGX0KP9S3ZdKO4zc8p4iBUbCzprN80Zkn/1eIZnbil4zZsnxkqXgZG 0hcUK/H2ximacRtL0ITEmQ0iTykFzo9OVgv+OgKigyBqZvziahPVhN8/ zl/wbqGdVx8UUgvvMUsTITSWdfZt3UK6KKVpQIrwuJroaVLvc69uxkLm 1ZCHe1FTf385yf7pKLD3vkJ2rWh4MZHwls6YQXUCDv4jf7D+rXIde/Jk SB9yko98xcu+ccdoCoFWzoBI2Ep0Io4bV40Izq+NwiYmMOpPL03SQrOq WRImyQ==
+
+ENTRY_END
+
+SCENARIO_END \ No newline at end of file
diff --git a/tests/integration/deckard/sets/resolver/val_adbit.rpl b/tests/integration/deckard/sets/resolver/val_adbit.rpl
new file mode 100644
index 0000000..a4eb5de
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_adbit.rpl
@@ -0,0 +1,174 @@
+do-ip6: no
+
+; config options
+; The island of trust is at example.com
+;server:
+ trust-anchor: "example.com. 3600 IN DS 6224 7 1 79120CA22E585593836A1F7F261ED6295627C77A "
+val-override-date: "20181130121814"
+; target-fetch-policy: "0 0 0 0 0"
+; fake-sha1: yes
+
+;stub-zone:
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+query-minimization: off
+CONFIG_END
+
+SCENARIO_BEGIN Test validator AD bit signaling
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20181230101814 20181130101814 6224 example.com. ESn6yJxsNZI197N+QTzEanisVKGGIc6mUugEBCcFOA7UUL6mbqx7It1k Yg/sFKnjpsmRYCPVR7Wa3K5f2yj7HOKXEcJ+7iNJ3lNG2QtgtaAIkBqa f9BFs1JVJqnlJ3w6XCUfxTmjtLepYKXgOwGg+SGI3GNLGx7EBkOJie1F JYo= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101814 20181130101814 6224 example.com. lgLIbRjRpUYJ6WuSWSpOljVYdDoWQiC+NndpFpPb9EIlk3tXgbE3gmpk hbQ4Nj2tRoje9UpDV3GNath1ZBZEKBovVGCCb8n7d5e+VvuIJMHreD3i 33VTfIaM3NOS6v+vZM5ZUGC7QTkczqHwrC8SPZMUqM9EA4cABYhkSMFy yoU= ;{id = 2854}
+ENTRY_END
+
+; response to DNSKEY priming query
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN DNSKEY
+SECTION ANSWER
+example.com. 3600 IN DNSKEY 256 3 7 AwEAAa+IW+C5GZhaOvN6/UjjowGAVDC2/BoGwILcFw5c6RL/30LHrM1f b3Qs9s9Z2u8xZz0VVwrb70eQlYkcdgMUXqI+eplu0OdXI2skN4nHkSkr OeEfA1ISNCchqRmLdONRobPTcBEYYbJWDiuwDmShpitVYT4KZhpIJErh Vzqf5e2V ;{id = 2854 (zsk), size = 1688b}
+example.com. 3600 IN RRSIG DNSKEY 7 2 3600 20181230101814 20181130101814 6224 example.com. WidInu/eUjNWNA6oF+TspmaUHXTx3TLpmA2ET4QPeRVvH3K0YIBGuVfA NLZvawiKvWfkwZfgVj9As/T2PBOK+9HENOMIXkxMQWcXVBy8KompOGOR T9ENoMWto3CXZEmc7kMtYZtxr5CXsGf4eEJ4AKZNbnwFCaHCtIhlhSIP pa8= ;{id = 2854}
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20181230101814 20181130101814 6224 example.com. ESn6yJxsNZI197N+QTzEanisVKGGIc6mUugEBCcFOA7UUL6mbqx7It1k Yg/sFKnjpsmRYCPVR7Wa3K5f2yj7HOKXEcJ+7iNJ3lNG2QtgtaAIkBqa f9BFs1JVJqnlJ3w6XCUfxTmjtLepYKXgOwGg+SGI3GNLGx7EBkOJie1F JYo= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101814 20181130101814 6224 example.com. lgLIbRjRpUYJ6WuSWSpOljVYdDoWQiC+NndpFpPb9EIlk3tXgbE3gmpk hbQ4Nj2tRoje9UpDV3GNath1ZBZEKBovVGCCb8n7d5e+VvuIJMHreD3i 33VTfIaM3NOS6v+vZM5ZUGC7QTkczqHwrC8SPZMUqM9EA4cABYhkSMFy yoU= ;{id = 2854}
+ENTRY_END
+
+; response to query of interest
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+www.example.com. 3600 IN RRSIG A 7 3 3600 20181230101814 20181130101814 6224 example.com. WBUrYLsgHSpl6O4O0WsXydo4AfgF3n2YbLQV9ViOv7CQIeucPMKedjqZ hpr1rmmd8gZU+IGd/RBwIXsiNyC0Y7npNnuBX8Na3FOTWXRiJaorboxh 1UpP6cyEvgMWuV5JqeAql75/8m5Qo/e7pcTQllUoooRuS+HJejkU6R66 Bjo= ;{id = 2854}
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20181230101814 20181130101814 6224 example.com. ESn6yJxsNZI197N+QTzEanisVKGGIc6mUugEBCcFOA7UUL6mbqx7It1k Yg/sFKnjpsmRYCPVR7Wa3K5f2yj7HOKXEcJ+7iNJ3lNG2QtgtaAIkBqa f9BFs1JVJqnlJ3w6XCUfxTmjtLepYKXgOwGg+SGI3GNLGx7EBkOJie1F JYo= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101814 20181130101814 6224 example.com. lgLIbRjRpUYJ6WuSWSpOljVYdDoWQiC+NndpFpPb9EIlk3tXgbE3gmpk hbQ4Nj2tRoje9UpDV3GNath1ZBZEKBovVGCCb8n7d5e+VvuIJMHreD3i 33VTfIaM3NOS6v+vZM5ZUGC7QTkczqHwrC8SPZMUqM9EA4cABYhkSMFy yoU= ;{id = 2854}
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA AD NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+;SECTION AUTHORITY
+;example.com. IN NS ns.example.com.
+;SECTION ADDITIONAL
+;ns.example.com. IN A 1.2.3.4
+ENTRY_END
+
+; ask from cache too
+STEP 21 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+STEP 23 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA AD NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+;SECTION AUTHORITY
+;example.com. IN NS ns.example.com.
+;SECTION ADDITIONAL
+;ns.example.com. IN A 1.2.3.4
+ENTRY_END
+
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/val_adcopy.rpl b/tests/integration/deckard/sets/resolver/val_adcopy.rpl
new file mode 100644
index 0000000..cb7542c
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_adcopy.rpl
@@ -0,0 +1,166 @@
+do-ip6: no
+
+; config options
+; The island of trust is at example.com
+;server:
+; trust-anchor: "example.com. 3600 IN DS 2854 3 1 46e4ffc6e9a4793b488954bd3f0cc6af0dfb201b"
+ val-override-date: "20070916134226"
+; target-fetch-policy: "0 0 0 0 0"
+; fake-sha1: yes
+
+;stub-zone:
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+ query-minimization: off
+CONFIG_END
+
+SCENARIO_BEGIN Test validator AD bit sent by untrusted upstream
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA RA AD NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854}
+ENTRY_END
+
+; response to DNSKEY priming query
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA RA AD NOERROR
+SECTION QUESTION
+example.com. IN DNSKEY
+SECTION ANSWER
+example.com. 3600 IN DNSKEY 256 3 3 ALXLUsWqUrY3JYER3T4TBJII s70j+sDS/UT2QRp61SE7S3E EXopNXoFE73JLRmvpi/UrOO/Vz4Se 6wXv/CYCKjGw06U4WRgR YXcpEhJROyNapmdIKSx hOzfLVE1gqA0PweZR8d tY3aNQSRn3sPpwJr6Mi /PqQKAMMrZ9ckJpf1+b QMOOvxgzz2U1GS18b3y ZKcgTMEaJzd/GZYzi/B N2DzQ0MsrSwYXfsNLFO Bbs8PJMW4LYIxeeOe6rUgkWOF 7CC9Dh/dduQ1QrsJhmZAEFfd6ByYV+ ;{id = 2854 (zsk), size = 1688b}
+example.com. 3600 IN RRSIG DNSKEY 3 2 3600 20070926134802 20070829134802 2854 example.com. MCwCFG1yhRNtTEa3Eno2zhVVuy2EJX3wAhQeLyUp6+UXcpC5qGNu9tkrTEgPUg== ;{id = 2854}
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854}
+ENTRY_END
+
+; response to query of interest
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA RA AD NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCQMyTjn7WWwpwAR1LlVeLpRgZGuQIUCcJDEkwAuzytTDRlYK7nIMwH1CM= ;{id = 2854}
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+www.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFC99iE9K5y2WNgI0gFvBWaTi9wm6AhUAoUqOpDtG5Zct+Qr9F3mSdnbc6V4= ;{id = 2854}
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH opcode qname flags rcode question answer
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+ENTRY_END
+
+; ask from cache too
+STEP 21 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+STEP 23 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH opcode qname flags rcode question answer
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+ENTRY_END
+
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/val_anchor_nx_nosig.rpl b/tests/integration/deckard/sets/resolver/val_anchor_nx_nosig.rpl
new file mode 100644
index 0000000..3322fc0
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_anchor_nx_nosig.rpl
@@ -0,0 +1,220 @@
+do-ip6: no
+
+; config options
+; The island of trust is at example.com
+;server:
+ trust-anchor: "sub.example.com. 3600 IN DS 30899 RSASHA1 1 f7ed618f24d5e5202927e1d27bc2e84a141cb4b3"
+ val-override-date: "20070916134226"
+; target-fetch-policy: "0 0 0 0 0"
+; fake-sha1: yes
+ query-minimization: off
+
+;stub-zone:
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test validator with unsigned denial of trust anchor
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.sub.example.com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.sub.example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854}
+ENTRY_END
+
+; response to DNSKEY priming query
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN DNSKEY
+SECTION ANSWER
+example.com. 3600 IN DNSKEY 256 3 3 ALXLUsWqUrY3JYER3T4TBJII s70j+sDS/UT2QRp61SE7S3E EXopNXoFE73JLRmvpi/UrOO/Vz4Se 6wXv/CYCKjGw06U4WRgR YXcpEhJROyNapmdIKSx hOzfLVE1gqA0PweZR8d tY3aNQSRn3sPpwJr6Mi /PqQKAMMrZ9ckJpf1+b QMOOvxgzz2U1GS18b3y ZKcgTMEaJzd/GZYzi/B N2DzQ0MsrSwYXfsNLFO Bbs8PJMW4LYIxeeOe6rUgkWOF 7CC9Dh/dduQ1QrsJhmZAEFfd6ByYV+ ;{id = 2854 (zsk), size = 1688b}
+example.com. 3600 IN RRSIG DNSKEY DSA 2 3600 20070926134150 20070829134150 2854 example.com. MCwCFBQRtlR4BEv9ohi+PGFjp+AHsJuHAhRCvz0shggvnvI88DFnBDCczHUcVA== ;{id = 2854}
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854}
+ENTRY_END
+
+; response for sub.example.com.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NXDOMAIN
+SECTION QUESTION
+www.sub.example.com. IN A
+SECTION AUTHORITY
+example.com. SOA ns.example.com. h.example.com. 2007090504 1800 1800 2419200 7200
+example.com. 3600 IN RRSIG SOA 3 2 3600 20070926134150 20070829134150 2854 example.com. MCwCFC5uwIHSehZtetK2CMNXttSFUB0XAhROFDAgy/FaxR8zFXJzyPdpQG93Sw== ;{id = 2854}
+blub.example.com. NSEC znub.example.com. A MX RRSIG NSEC
+blub.example.com. 3600 IN RRSIG NSEC 3 3 3600 20070926134150 20070829134150 2854 example.com. MCwCFCic/WwyMtdDE/84g8l0S0M8AOtnAhR88hQEp5cD5XQ3EmQ79RUuNTCgdg== ;{id = 2854}
+example.com. NSEC blub.example.com. SOA NS MX DNSKEY RRSIG NSEC
+example.com. 3600 IN RRSIG NSEC 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFFYX7iNIlT79gNFFlvnn44Ittm6HAhUAg7u0hZ4to87qyfkonZu2jVLW3xw= ;{id = 2854}
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NXDOMAIN
+SECTION QUESTION
+www.sub.example.com. IN DS
+SECTION AUTHORITY
+example.com. SOA ns.example.com. h.example.com. 2007090504 1800 1800 2419200 7200
+example.com. 3600 IN RRSIG SOA 3 2 3600 20070926134150 20070829134150 2854 example.com. MCwCFC5uwIHSehZtetK2CMNXttSFUB0XAhROFDAgy/FaxR8zFXJzyPdpQG93Sw== ;{id = 2854}
+blub.example.com. NSEC znub.example.com. A MX RRSIG NSEC
+blub.example.com. 3600 IN RRSIG NSEC 3 3 3600 20070926134150 20070829134150 2854 example.com. MCwCFCic/WwyMtdDE/84g8l0S0M8AOtnAhR88hQEp5cD5XQ3EmQ79RUuNTCgdg== ;{id = 2854}
+example.com. NSEC blub.example.com. SOA NS MX DNSKEY RRSIG NSEC
+example.com. 3600 IN RRSIG NSEC 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFFYX7iNIlT79gNFFlvnn44Ittm6HAhUAg7u0hZ4to87qyfkonZu2jVLW3xw= ;{id = 2854}
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NXDOMAIN
+SECTION QUESTION
+sub.example.com. IN DNSKEY
+SECTION AUTHORITY
+example.com. SOA ns.example.com. h.example.com. 2007090504 1800 1800 2419200 7200
+example.com. 3600 IN RRSIG SOA 3 2 3600 20070926134150 20070829134150 2854 example.com. MCwCFC5uwIHSehZtetK2CMNXttSFUB0XAhROFDAgy/FaxR8zFXJzyPdpQG93Sw== ;{id = 2854}
+blub.example.com. NSEC znub.example.com. A MX RRSIG NSEC
+blub.example.com. 3600 IN RRSIG NSEC 3 3 3600 20070926134150 20070829134150 2854 example.com. MCwCFCic/WwyMtdDE/84g8l0S0M8AOtnAhR88hQEp5cD5XQ3EmQ79RUuNTCgdg== ;{id = 2854}
+example.com. NSEC blub.example.com. SOA NS MX DNSKEY RRSIG NSEC
+example.com. 3600 IN RRSIG NSEC 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFFYX7iNIlT79gNFFlvnn44Ittm6HAhUAg7u0hZ4to87qyfkonZu2jVLW3xw= ;{id = 2854}
+ENTRY_END
+RANGE_END
+
+; ns.sub.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.6
+
+; response to DNSKEY priming query
+; sub.example.com. 3600 IN DS 30899 RSASHA1 1 f7ed618f24d5e5202927e1d27bc2e84a141cb4b3
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+sub.example.com. IN DNSKEY
+SECTION ANSWER
+sub.example.com. 3600 IN DNSKEY 256 3 5 AQPQ41chR9DEHt/aIzIFAqanbDlRflJoRs5yz1jFsoRIT7dWf0r+PeDuewdxkszNH6wnU4QL8pfKFRh5PIYVBLK3 ;{id = 30899 (zsk), size = 512b}
+sub.example.com. 3600 IN RRSIG DNSKEY 5 3 3600 20070926134150 20070829134150 30899 sub.example.com. uNGp99iznjD7oOX02XnQbDnbg75UwBHRvZSKYUorTKvPUnCWMHKdRsQ+mf+Fx3GZ+Fz9BVjoCmQqpnfgXLEYqw== ;{id = 30899}
+SECTION AUTHORITY
+sub.example.com. IN NS ns.sub.example.com.
+sub.example.com. 3600 IN RRSIG NS 5 3 3600 20070926134150 20070829134150 30899 sub.example.com. wcpHeBILHfo8C9uxMhcW03gcURZeUffiKdSTb50ZjzTHgMNhRyMfpcvSpXEd9548A9UTmWKeLZChfr5Z/glONw== ;{id = 30899}
+SECTION ADDITIONAL
+ns.sub.example.com. IN A 1.2.3.6
+ns.sub.example.com. 3600 IN RRSIG A 5 4 3600 20070926134150 20070829134150 30899 sub.example.com. UF7shD/gt1FOp2UHgLTNbPzVykklSXFMEtJ1xD+Hholwf/PIzd7zoaIttIYibNa4fUXCqMg22H9P7MRhfmFe6g== ;{id = 30899}
+ENTRY_END
+
+; response to query of interest
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.sub.example.com. IN A
+SECTION ANSWER
+www.sub.example.com. IN A 11.11.11.11
+www.sub.example.com. 3600 IN RRSIG A 5 4 3600 20070926134150 20070829134150 30899 sub.example.com. 0DqqRfRtm7VSEQ4mmBbzrKRqQAay3JAE8DPDGmjtokrrjN9F1G/HxozDV7bjdIh2EChlQea8FPwf/GepJMUVxg== ;{id = 30899}
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.sub.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA DO NXDOMAIN
+SECTION QUESTION
+www.sub.example.com. IN A
+SECTION ANSWER
+SECTION AUTHORITY
+example.com. SOA ns.example.com. h.example.com. 2007090504 1800 1800 2419200 7200
+example.com. 3600 IN RRSIG SOA 3 2 3600 20070926134150 20070829134150 2854 example.com. MCwCFC5uwIHSehZtetK2CMNXttSFUB0XAhROFDAgy/FaxR8zFXJzyPdpQG93Sw== ;{id = 2854}
+blub.example.com. NSEC znub.example.com. A MX RRSIG NSEC
+blub.example.com. 3600 IN RRSIG NSEC 3 3 3600 20070926134150 20070829134150 2854 example.com. MCwCFCic/WwyMtdDE/84g8l0S0M8AOtnAhR88hQEp5cD5XQ3EmQ79RUuNTCgdg== ;{id = 2854}
+example.com. NSEC blub.example.com. SOA NS MX DNSKEY RRSIG NSEC
+example.com. 3600 IN RRSIG NSEC 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFFYX7iNIlT79gNFFlvnn44Ittm6HAhUAg7u0hZ4to87qyfkonZu2jVLW3xw= ;{id = 2854}
+SECTION ADDITIONAL
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/val_ans_dsent.rpl b/tests/integration/deckard/sets/resolver/val_ans_dsent.rpl
new file mode 100644
index 0000000..0c4f0c0
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_ans_dsent.rpl
@@ -0,0 +1,248 @@
+do-ip6: no
+
+; config options
+; The island of trust is at example.com
+;server:
+ trust-anchor: "example.com. 3600 IN DS 5969 7 1 A4AC909154F325EA3F437CD0626ABB2C039E9C50 "
+val-override-date: "20181130121817"
+; target-fetch-policy: "0 0 0 0 0"
+; fake-sha1: yes
+
+;stub-zone:
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+query-minimization: off
+CONFIG_END
+
+SCENARIO_BEGIN Test validator with empty nonterminals on the trust chain.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+328.0.0.194.example.com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+328.0.0.194.example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20181230101817 20181130101817 5969 example.com. Wg9pfH674/AQOaiB7c4EKHYPJp81/v3o5w4GreQBjCr6nx759rE74DLg uLyeldgMaAO+PZD6EXcyuV9acrfLbR+unhUbWHXRktkRrUwJf/5+WsCp yITuzmCezNL7bRrW+f8mxa5pkm7IfaSAoUmu54c/dP5QnbwGZoUK3ObY Ztg= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101817 20181130101817 5969 example.com. TYw9E6WMcbN6izjKoga5IEBGweWCXVpgKEjcWYZcBkEcFZX/hr7eyHok qnGsOi+hHwyMt6EatU2JU0A9WAQzosDxw3xib8F9mk2GlNlpbmrsRwec x6MuPCD5Ur4+GKwevmQOe8mxsqMXdbLKXT56WU2tPBtKsFxQlAS7JA9t pAY= ;{id = 2854}
+ENTRY_END
+
+; response to DNSKEY priming query
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN DNSKEY
+SECTION ANSWER
+example.com. 3600 IN DNSKEY 256 3 7 AwEAAeDMFHMvUzUDUFCAAJryyhH1w3V/mHk+Y2wpcMy37G+Ur1JTrIS+ fz1USHOaoNO+ynyCq3XqRbik8vXHUi3oOyLjEu+xTRjLuEgtB4GrEZSV 8umKzMVJZI335YOuAfvPrvA+Ish2hRg+H0otRnNAwqUshFgMRGX1UnjL oo9EwWu1 ;{id = 2854 (zsk), size = 1688b}
+example.com. 3600 IN RRSIG DNSKEY 7 2 3600 20181230101817 20181130101817 5969 example.com. jHGQFzBToq7eUEWW30SDECUfcQJagrP8IbREf+hwKBHEWLEY2E0acQN6 ce/+3DJJHwVF0VTX4Jdo0l43hlOp+bRUBLzsvoWToWtdt2S3nJy1Ay4e +DdockqRbUvs4X16HuYBIL2wxnispH1PRoUUvnF6Aeq4egCQiIx4+SOF pRs= ;{id = 2854}
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20181230101817 20181130101817 5969 example.com. Wg9pfH674/AQOaiB7c4EKHYPJp81/v3o5w4GreQBjCr6nx759rE74DLg uLyeldgMaAO+PZD6EXcyuV9acrfLbR+unhUbWHXRktkRrUwJf/5+WsCp yITuzmCezNL7bRrW+f8mxa5pkm7IfaSAoUmu54c/dP5QnbwGZoUK3ObY Ztg= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101817 20181130101817 5969 example.com. TYw9E6WMcbN6izjKoga5IEBGweWCXVpgKEjcWYZcBkEcFZX/hr7eyHok qnGsOi+hHwyMt6EatU2JU0A9WAQzosDxw3xib8F9mk2GlNlpbmrsRwec x6MuPCD5Ur4+GKwevmQOe8mxsqMXdbLKXT56WU2tPBtKsFxQlAS7JA9t pAY= ;{id = 2854}
+ENTRY_END
+
+; responses to DS empty nonterminal queries.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+194.example.com. IN DS
+SECTION AUTHORITY
+example.com. 3600 IN SOA ns.example.com. host.example.com. 2007091980 3600 7200 1209600 7200
+example.com. 3600 IN RRSIG SOA 7 2 3600 20181230101817 20181130101817 5969 example.com. CdUsF1NFbkBgKLO10zT/ecIDU/059ZKRK/qsMTp2mTDMLY5BL4Q1cV+f HZWXLkz7eCgvQw4jhaycEKh65I+LdBPFGQBOPM6IJzzqjpMNZkNIAiC/ 98FfWN5MQCD9Rf/Xary2oRbQ6Hzacvc9sRABX1sY9w0n/xIpeRXQ4Zaf eV8= ;{id = 2854}
+
+; This NSEC proves the NOERROR/NODATA case.
+194.example.com. IN NSEC 0.0.194.example.com. A RRSIG NSEC
+194.example.com. 3600 IN RRSIG NSEC 7 3 7200 20181230101817 20181130101817 5969 example.com. r/fKSY1tFbI3PkF/OvDavn08S6YCx0HJDk5Qyi0mt2sOcD2/c/Rqe+d3 FqR4OFAPQcf405CV7oScQ1/rWMqNFeJxRX1CisY3bRwFhCckXLgCCLKD dZbGNidxQtc7WbiFKZMMmfqEmS1UbpaXNycmlbH7oDmLpqLdzURKFVDM kTw= ;{id = 2854}
+
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+; this should be NOERROR.
+REPLY QR AA NOERROR
+SECTION QUESTION
+0.194.example.com. IN DS
+SECTION AUTHORITY
+example.com. 3600 IN SOA ns.example.com. host.example.com. 2007091980 3600 7200 1209600 7200
+example.com. 3600 IN RRSIG SOA 7 2 3600 20181230101817 20181130101817 5969 example.com. CdUsF1NFbkBgKLO10zT/ecIDU/059ZKRK/qsMTp2mTDMLY5BL4Q1cV+f HZWXLkz7eCgvQw4jhaycEKh65I+LdBPFGQBOPM6IJzzqjpMNZkNIAiC/ 98FfWN5MQCD9Rf/Xary2oRbQ6Hzacvc9sRABX1sY9w0n/xIpeRXQ4Zaf eV8= ;{id = 2854}
+
+; This NSEC proves the NOERROR/NODATA case.
+194.example.com. IN NSEC 0.0.194.example.com. A RRSIG NSEC
+194.example.com. 3600 IN RRSIG NSEC 7 3 7200 20181230101817 20181130101817 5969 example.com. r/fKSY1tFbI3PkF/OvDavn08S6YCx0HJDk5Qyi0mt2sOcD2/c/Rqe+d3 FqR4OFAPQcf405CV7oScQ1/rWMqNFeJxRX1CisY3bRwFhCckXLgCCLKD dZbGNidxQtc7WbiFKZMMmfqEmS1UbpaXNycmlbH7oDmLpqLdzURKFVDM kTw= ;{id = 2854}
+
+ENTRY_END
+
+; response for delegation to sub zone.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+328.0.0.194.example.com. IN A
+SECTION ANSWER
+SECTION AUTHORITY
+0.0.194.example.com. IN NS ns.sub.example.com.
+0.0.194.example.com. 3600 IN DS 23400 5 1 F98448C953B01B087D505FB4FCA99DFF9FF37DBD
+0.0.194.example.com. 3600 IN RRSIG DS 7 5 3600 20181230101817 20181130101817 5969 example.com. 1V7MTc/3CMbqswXWDzxwRM9sTNVKNt+W9fTWu6Zn72xDl26r3GRhYgAV 5L7JI/qmDsMSebz6qXojzf58Ev1EO9avxemg6cNQBK+Lrxo1LhFzbzyC LYwRRShPP2D+eTNlgBh6TBNpUfeBDUHGt7hOPqDUqKm7Iru3kvAEY9T1 Fqk= ;{id = 2854}
+SECTION ADDITIONAL
+ns.sub.example.com. IN A 1.2.3.6
+ENTRY_END
+
+; response for delegation to sub zone
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+0.0.194.example.com. IN DNSKEY
+SECTION ANSWER
+SECTION AUTHORITY
+0.0.194.example.com. IN NS ns.sub.example.com.
+0.0.194.example.com. 3600 IN DS 23400 5 1 F98448C953B01B087D505FB4FCA99DFF9FF37DBD
+0.0.194.example.com. 3600 IN RRSIG DS 7 5 3600 20181230101817 20181130101817 5969 example.com. 1V7MTc/3CMbqswXWDzxwRM9sTNVKNt+W9fTWu6Zn72xDl26r3GRhYgAV 5L7JI/qmDsMSebz6qXojzf58Ev1EO9avxemg6cNQBK+Lrxo1LhFzbzyC LYwRRShPP2D+eTNlgBh6TBNpUfeBDUHGt7hOPqDUqKm7Iru3kvAEY9T1 Fqk= ;{id = 2854}
+SECTION ADDITIONAL
+ns.sub.example.com. IN A 1.2.3.6
+ENTRY_END
+RANGE_END
+
+; ns.sub.example.com. for zone 0.0.194.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.6
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+0.0.194.example.com. IN NS
+SECTION ANSWER
+0.0.194.example.com. IN NS ns.sub.example.com.
+0.0.194.example.com. 3600 IN RRSIG NS 5 5 3600 20181230101817 20181130101817 23400 0.0.194.example.com. cUuqSDfttEihyAPLyjzQgLqo5j3dtmQE+xNJ9stwFFL4bNr7bjlux3MS mZcGzOY5skzIK2B+ufkXh+XJVk0HOD/VjEdSyTQCO8elzKbSv6pjsx5E 48FA5scTeX67GFdiJji9Ssk/dQtIWrsmoRLzWITtVANxtrN6mvSHCKVM gHc= ;{id = 30899}
+SECTION ADDITIONAL
+ns.sub.example.com. IN A 1.2.3.6
+ENTRY_END
+
+
+; response to DNSKEY priming query
+; 0.0.194.example.com. 3600 IN DS 23400 5 1 F98448C953B01B087D505FB4FCA99DFF9FF37DBD
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+0.0.194.example.com. IN DNSKEY
+SECTION ANSWER
+0.0.194.example.com. 3600 IN DNSKEY 256 3 5 AwEAAccLvnsSmtCYMulOPc34e+ZK1eQM6EyCmCZ0hh1dD1MD5tCR2qu5 AROP3GARZDnC14wcTFuTmX7U9JJGw7UXb+V7bNHw91v/DTr3dJkJkqYY wL08wwLPbl9jK9q6P+GcZErucXwugK+eSDdWdwZ3u0DHllby0euw7VM1 o+3oFvsZ ;{id = 30899 (zsk), size = 512b}
+0.0.194.example.com. 3600 IN RRSIG DNSKEY 5 5 3600 20181230101817 20181130101817 23400 0.0.194.example.com. EBz3F9s6y1zo2TT21XqfMmqddYaiicUjDSDDYgqTCnocF+8It4AXAf+X 85zJV08+x4APyCs5ROcYkcdtwXMC7Uj5sgPtn5UkxIF8G1UkdQzh5WSr yr0DBhqQOGNTEntIz35xQv+r3GfoXnsE2BqV8TBQ7V1AM6bnfHmQ2lHs F5I= ;{id = 30899}
+SECTION AUTHORITY
+0.0.194.example.com. IN NS ns.sub.example.com.
+0.0.194.example.com. 3600 IN RRSIG NS 5 5 3600 20181230101817 20181130101817 23400 0.0.194.example.com. cUuqSDfttEihyAPLyjzQgLqo5j3dtmQE+xNJ9stwFFL4bNr7bjlux3MS mZcGzOY5skzIK2B+ufkXh+XJVk0HOD/VjEdSyTQCO8elzKbSv6pjsx5E 48FA5scTeX67GFdiJji9Ssk/dQtIWrsmoRLzWITtVANxtrN6mvSHCKVM gHc= ;{id = 30899}
+SECTION ADDITIONAL
+ns.sub.example.com. IN A 1.2.3.6
+ENTRY_END
+
+; response to query of interest
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+328.0.0.194.example.com. IN A
+SECTION ANSWER
+328.0.0.194.example.com. IN A 11.11.11.11
+328.0.0.194.example.com. 3600 IN RRSIG A 5 6 3600 20181230101817 20181130101817 23400 0.0.194.example.com. XqdIgy6JxkR9DYPhI4hJHZqWbHVyoqLk4Arq69Sa7SSvnIhE/Nsf0BrF /EK1XMoepiN8kR9QMnrQWk7fsE9w3PzzcecWQrQ/4Bps8g+gu6DtgNOx k5Cm6b+caRJ2oT3z+n2/7r7VdPndk1bzHOwQINOUJiQN1Q1ya4M5Nw/I c9U= ;{id = 30899}
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+328.0.0.194.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+328.0.0.194.example.com. IN A
+SECTION ANSWER
+328.0.0.194.example.com. 3600 IN A 11.11.11.11
+328.0.0.194.example.com. 3600 IN RRSIG A 5 6 3600 20181230101817 20181130101817 23400 0.0.194.example.com. XqdIgy6JxkR9DYPhI4hJHZqWbHVyoqLk4Arq69Sa7SSvnIhE/Nsf0BrF /EK1XMoepiN8kR9QMnrQWk7fsE9w3PzzcecWQrQ/4Bps8g+gu6DtgNOx k5Cm6b+caRJ2oT3z+n2/7r7VdPndk1bzHOwQINOUJiQN1Q1ya4M5Nw/I c9U= ;{id = 30899}
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/val_ans_nx.rpl b/tests/integration/deckard/sets/resolver/val_ans_nx.rpl
new file mode 100644
index 0000000..77cc5b0
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_ans_nx.rpl
@@ -0,0 +1,250 @@
+do-ip6: no
+
+; config options
+; The island of trust is at example.com
+;server:
+ trust-anchor: "example.com. 3600 IN DS 53207 7 1 ED9E33A0CCBFAE631929D9064C69EAF91E9872E3 "
+val-override-date: "20181130121819"
+; target-fetch-policy: "0 0 0 0 0"
+; fake-sha1: yes
+
+;stub-zone:
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+query-minimization: off
+CONFIG_END
+
+SCENARIO_BEGIN Test validator with DS nodata as nxdomain on trust chain
+; This is a bug in ANS 2.8.1.0 where it gives an NXDOMAIN instead of
+; NOERROR for an empty nonterminal DS query. The proof for this NXDOMAIN
+; is the NSEC that proves emptynonterminal.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+328.0.0.194.example.com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+328.0.0.194.example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20181230101819 20181130101819 53207 example.com. 0lXU7ewAPEKEpwxF+qH+N99cfG/SFw3S+BGgky/UFgtFpzQip2o+xkOB 0Kr2e8coW7MTMMAtb4XNFqk26liB2klncvAmy8OrZBgCoz0n9RMDpiU5 5U3DCdJOonBkLZp7r/QjdwIY2RAN2ooTR5CnBxTvU8TqsFuK+qvIPZoc 1GU= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101819 20181130101819 53207 example.com. ro/KUUe+1uPXGO0Y/sbylsbh26miTgZgLEBLhQPrKLpjl1l4Jcuph+4m NRYJoOnXwsqYHoAZiNIGCagi2LqIZ8hgiLSZnkFSI21xw7uZ1UKjw1yx MY0UXtWf7tF2NGY8wXctKRXkLPkP0D0vZXDIiVHRmAA3RJILXV6VSuyk ZQs= ;{id = 2854}
+ENTRY_END
+
+; response to DNSKEY priming query
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN DNSKEY
+SECTION ANSWER
+example.com. 3600 IN DNSKEY 256 3 7 AwEAAeENZGV8/uWkUDIdb5on+NfJs19ejJpnPECDh8pR++7WQl8fk0xm 87kirUT8v1gZzwsbr0Vb0zBi4YewFG3Xe8Ei1d57cJRHKf2uoJ6L93xm C+IPfurFRcGfJDUIWdMH1lth6GbEilxesKdt3lnqSNOln0/rU99jZ+kJ QGGn+M+7 ;{id = 2854 (zsk), size = 1688b}
+example.com. 3600 IN RRSIG DNSKEY 7 2 3600 20181230101819 20181130101819 53207 example.com. ScZ8gDOVfCumrFANbTXFgFFp+0uOR6r9MzJJQWYQZY1omSXUrc8dpx8a 6MEP+hJGydmMjXmL09l2ZzsKlzjGm7kdCtXZLBAnJiZ0e3+tQdpb/mJ4 cRUIrGfQF7VOckzN0oW7hlTqJjkdbfvKW7paRgMBil97Y9J0AcMj0GjW UIA= ;{id = 2854}
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20181230101819 20181130101819 53207 example.com. 0lXU7ewAPEKEpwxF+qH+N99cfG/SFw3S+BGgky/UFgtFpzQip2o+xkOB 0Kr2e8coW7MTMMAtb4XNFqk26liB2klncvAmy8OrZBgCoz0n9RMDpiU5 5U3DCdJOonBkLZp7r/QjdwIY2RAN2ooTR5CnBxTvU8TqsFuK+qvIPZoc 1GU= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101819 20181130101819 53207 example.com. ro/KUUe+1uPXGO0Y/sbylsbh26miTgZgLEBLhQPrKLpjl1l4Jcuph+4m NRYJoOnXwsqYHoAZiNIGCagi2LqIZ8hgiLSZnkFSI21xw7uZ1UKjw1yx MY0UXtWf7tF2NGY8wXctKRXkLPkP0D0vZXDIiVHRmAA3RJILXV6VSuyk ZQs= ;{id = 2854}
+ENTRY_END
+
+; responses to DS empty nonterminal queries.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+194.example.com. IN DS
+SECTION AUTHORITY
+example.com. 3600 IN SOA ns.example.com. host.example.com. 2007091980 3600 7200 1209600 7200
+example.com. 3600 IN RRSIG SOA 7 2 3600 20181230101819 20181130101819 53207 example.com. ypY/mUi4F0lXJ5dp2XmUG2yiP/CN5EPvCHTNUCxkXGkFYA298WkvA16V u3yj/DLzDXm0x70QHWzLqNawdo3v8GzRGRJmvVSf7dXzNzOxC/SUyTdT ad8H/5XwYpQDAMy5pLlk6DC8I8xXyQIChv133eCIn6uVqjIH/Nr1lj6j +n8= ;{id = 2854}
+
+; This NSEC proves the NOERROR/NODATA case.
+194.example.com. IN NSEC 0.0.194.example.com. A RRSIG NSEC
+194.example.com. 3600 IN RRSIG NSEC 7 3 7200 20181230101819 20181130101819 53207 example.com. mVuTRbUXm5qZJZzH980ndaNBJDgUJ57o30lNKeir6AhM2GY4Fkttntz3 p1FWDkWCX5PGBVdnUsMxA9d5tMU+hQKuAD1pv41xq8KuQYc5Csbk0GgX N0HJ5gqP9SRXdSIvHl+DM5euM3b9eA/p0a7oCJ24dwMw4mRd5vdL7CD5 SAA= ;{id = 2854}
+
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+; Bad NXDOMAIN response, this should be NOERROR.
+REPLY QR AA NXDOMAIN
+SECTION QUESTION
+0.194.example.com. IN DS
+SECTION AUTHORITY
+example.com. 3600 IN SOA ns.example.com. host.example.com. 2007091980 3600 7200 1209600 7200
+example.com. 3600 IN RRSIG SOA 7 2 3600 20181230101819 20181130101819 53207 example.com. ypY/mUi4F0lXJ5dp2XmUG2yiP/CN5EPvCHTNUCxkXGkFYA298WkvA16V u3yj/DLzDXm0x70QHWzLqNawdo3v8GzRGRJmvVSf7dXzNzOxC/SUyTdT ad8H/5XwYpQDAMy5pLlk6DC8I8xXyQIChv133eCIn6uVqjIH/Nr1lj6j +n8= ;{id = 2854}
+
+; This NSEC proves the NOERROR/NODATA case.
+194.example.com. IN NSEC 0.0.194.example.com. A RRSIG NSEC
+194.example.com. 3600 IN RRSIG NSEC 7 3 7200 20181230101819 20181130101819 53207 example.com. mVuTRbUXm5qZJZzH980ndaNBJDgUJ57o30lNKeir6AhM2GY4Fkttntz3 p1FWDkWCX5PGBVdnUsMxA9d5tMU+hQKuAD1pv41xq8KuQYc5Csbk0GgX N0HJ5gqP9SRXdSIvHl+DM5euM3b9eA/p0a7oCJ24dwMw4mRd5vdL7CD5 SAA= ;{id = 2854}
+
+ENTRY_END
+
+; response for delegation to sub zone.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+328.0.0.194.example.com. IN A
+SECTION ANSWER
+SECTION AUTHORITY
+0.0.194.example.com. IN NS ns.sub.example.com.
+0.0.194.example.com. 3600 IN DS 22635 5 1 042026877E24C586D775608A2AFEE6179F5C43AF
+0.0.194.example.com. 3600 IN RRSIG DS 7 5 3600 20181230101819 20181130101819 53207 example.com. NxLJhRVh78CARarasz3Ks4lanafpN8+AsJgbiYnCQQPmn9X3fq9jbG5n KO0AlyvvcCy/W7z7KMFsMNVD1CvKCDzM2DKbTm17HaPAGXONkxGj53a1 OLn1+hXQ3O+4Th2lNfsUDmk0cMCIyRJetNVBTnz0ywXBHNiQIfyzsGHY UEs= ;{id = 2854}
+SECTION ADDITIONAL
+ns.sub.example.com. IN A 1.2.3.6
+ENTRY_END
+
+; response for delegation to sub zone
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+0.0.194.example.com. IN DNSKEY
+SECTION ANSWER
+SECTION AUTHORITY
+0.0.194.example.com. IN NS ns.sub.example.com.
+0.0.194.example.com. 3600 IN DS 22635 5 1 042026877E24C586D775608A2AFEE6179F5C43AF
+0.0.194.example.com. 3600 IN RRSIG DS 7 5 3600 20181230101819 20181130101819 53207 example.com. NxLJhRVh78CARarasz3Ks4lanafpN8+AsJgbiYnCQQPmn9X3fq9jbG5n KO0AlyvvcCy/W7z7KMFsMNVD1CvKCDzM2DKbTm17HaPAGXONkxGj53a1 OLn1+hXQ3O+4Th2lNfsUDmk0cMCIyRJetNVBTnz0ywXBHNiQIfyzsGHY UEs= ;{id = 2854}
+SECTION ADDITIONAL
+ns.sub.example.com. IN A 1.2.3.6
+ENTRY_END
+RANGE_END
+
+; ns.sub.example.com. for zone 0.0.194.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.6
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+0.0.194.example.com. IN NS
+SECTION ANSWER
+0.0.194.example.com. IN NS ns.sub.example.com.
+0.0.194.example.com. 3600 IN RRSIG NS 5 5 3600 20181230101818 20181130101818 22635 0.0.194.example.com. OEIHwyYg+Yp9hF/P10nwxq5Lv0pz5RLjtv3hP3N4dpUPQTEwKL0e4hVG 68s6d6RSKNMzhOFrO7PA+QePRzC4ksC7+2SgKA+XvaGP9kRsjWou9jv0 8SdyaV8Agjx7OwRpbZNFs//wdX0l0RU6XHcQ0ZwkcfseK0RE6btI/YvL oA4= ;{id = 30899}
+SECTION ADDITIONAL
+ns.sub.example.com. IN A 1.2.3.6
+ENTRY_END
+
+; response to DNSKEY priming query
+; 0.0.194.example.com. 3600 IN DS 22635 5 1 042026877E24C586D775608A2AFEE6179F5C43AF
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+0.0.194.example.com. IN DNSKEY
+SECTION ANSWER
+0.0.194.example.com. 3600 IN DNSKEY 256 3 5 AwEAAdYRWdf35UAjLYIYyuKr5Cnb17qGYZ3mC1CZjOt3j7muMunvFjGw a75XHGOUVj4CXW4J4TqjeL86foJx8DcqLbwreTHPfJyqcjsjGIVhSDyB Xjb0vImIj7baOOaFnXlolcx8ljob3GUIv5R/sTGcPIQGVk5T0VHLqrnp bdNyyk9/ ;{id = 30899 (zsk), size = 512b}
+0.0.194.example.com. 3600 IN RRSIG DNSKEY 5 5 3600 20181230101818 20181130101818 22635 0.0.194.example.com. OaXVEJcwCQwfYS1QFfPz8Se0NN7uEPUHUk3Ty0eiO0j40mKwCvm7ZFzl Q1xufxJATYXO9rV1wZl1dzN+Vv68tQmmByinvEomUpqsyuAtVbFqsNDT NOSK6TwKYKDo9/g7Xr10KfjCvLXdR4BgUYQwG9XZu+t1z4Qgu4vob0iq bLw= ;{id = 30899}
+SECTION AUTHORITY
+0.0.194.example.com. IN NS ns.sub.example.com.
+0.0.194.example.com. 3600 IN RRSIG NS 5 5 3600 20181230101818 20181130101818 22635 0.0.194.example.com. OEIHwyYg+Yp9hF/P10nwxq5Lv0pz5RLjtv3hP3N4dpUPQTEwKL0e4hVG 68s6d6RSKNMzhOFrO7PA+QePRzC4ksC7+2SgKA+XvaGP9kRsjWou9jv0 8SdyaV8Agjx7OwRpbZNFs//wdX0l0RU6XHcQ0ZwkcfseK0RE6btI/YvL oA4= ;{id = 30899}
+SECTION ADDITIONAL
+ns.sub.example.com. IN A 1.2.3.6
+ENTRY_END
+
+; response to query of interest
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+328.0.0.194.example.com. IN A
+SECTION ANSWER
+328.0.0.194.example.com. IN A 11.11.11.11
+328.0.0.194.example.com. 3600 IN RRSIG A 5 6 3600 20181230101818 20181130101818 22635 0.0.194.example.com. gQKa5rIogGvzHsC+oKjjNY5X1wp3NGUm8jj7Dxn8/x0wd8z7GmcMQCVV 6xR18r8t5m6uCFQ2USLFadWPWei6OnPmMw0KDKxrTs3sG6HKe4yMtLcO NY1IZ6pdHpCc8btAhw5DfYEilo+6Mod2KD6ulRJKcY4rE7jFosLdpwM7 5hw= ;{id = 30899}
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+328.0.0.194.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+328.0.0.194.example.com. IN A
+SECTION ANSWER
+328.0.0.194.example.com. 3600 IN A 11.11.11.11
+328.0.0.194.example.com. 3600 IN RRSIG A 5 6 3600 20181230101818 20181130101818 22635 0.0.194.example.com. gQKa5rIogGvzHsC+oKjjNY5X1wp3NGUm8jj7Dxn8/x0wd8z7GmcMQCVV 6xR18r8t5m6uCFQ2USLFadWPWei6OnPmMw0KDKxrTs3sG6HKe4yMtLcO NY1IZ6pdHpCc8btAhw5DfYEilo+6Mod2KD6ulRJKcY4rE7jFosLdpwM7 5hw= ;{id = 30899}
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/val_bogus_nodata.rpl b/tests/integration/deckard/sets/resolver/val_bogus_nodata.rpl
new file mode 100644
index 0000000..d2160aa
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_bogus_nodata.rpl
@@ -0,0 +1,247 @@
+do-ip6: no
+
+; config options
+ stub-addr: 193.0.14.129
+ trust-anchor: ". IN DS 9352 8 2 14FBAADCF21A64138B28F41424812B0A2BDEEF443F5680D6CF337F72 B556998C "
+val-override-date: "20180823175219"
+CONFIG_END
+
+SCENARIO_BEGIN Test that bogus RRsets do not leak into SERVFAIL answers
+
+RANGE_BEGIN 1 999999
+ ADDRESS 193.0.14.129 ;k.root-servers.net
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RD RA AD NOERROR
+SECTION QUESTION
+. IN SOA
+SECTION ANSWER
+. 86400 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2017030902 1800 900 604800 86400
+. 86400 IN RRSIG SOA 8 0 86400 20180922145219 20180823145219 61125 . oUmzRZlxlk8WMI6EVAVqveSrD7gY7dxog/KF0xIsUgb4wuw7ysD4C1E7 GCKA8UqFXKsJn+RpKJHiHAASLctCL8Ewnger2ebeRtTNENEuqyvWlJwW HIY9Bk9YvMr5RzNdTfyLS+EGFGQzk2G793DOoi0DuNFaFK1AkN/jDDzD uGxwK/9oZ4X9Sk2mKeZfjKWIoXaPhMonfnWtX+6rKeMvgSjMZYEXz0+E XYHeHwvtUIPYzMfO2iCrEfCABH04OG61NP5N9W+IiOKP1KAmT8id3JyF JACHjSP6BeEIv6Ydzz3M9vq4B4pj0Cr9ePH0GnNC0Sg8uOfHzjC5bHld oaJs4g==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RD RA AD NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. 518400 IN NS k.root-servers.net.
+. 518400 IN RRSIG NS 8 0 518400 20180922145219 20180823145219 61125 . UKsrW4CGfH+NEKsm3fmOZJye/Z7OkLvzSOWT3awvZ8ZBDUTtC1Ah+JD1 Rm6+NJ7fRi+eXIpsI7Cp+rwYWPF44M7WDpVUjxVjsndIcQZhcMZ2p65p zBNgNbVZFvQ9Vl4SICIMp3Chx95B/hgfsDRdjba8+hzb5LI56ICErGws QOb8BjamTdSv3L3K5kCNPMed9xLlOat7njjH5jlrvmTecP1t6ObuEXML GCMBRorS8ICzoCErQE/0Zmya4tQOzBwobdeRvmLy48EtBd20YflIeTfu NvN9fE0WK57dB4MS+hi7Fkraw0JLBId13Ke+OGMLQQwGlGMw8vI+tpbI aWfKhQ==
+
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RD RA AD NOERROR
+SECTION QUESTION
+. IN DNSKEY
+SECTION ANSWER
+. 3600000 IN DNSKEY 256 3 8 AwEAAdTYhQKdlbsOqK0aFv0MllAAp1CCRr8p2eRjYjBvwonAudx2GtjN QJ0DubuKzZC1URUgYL0d3mwijsuWrlQMaI27hSNMK7nYAuDHtPsNp7ix 2TITCRTG4+yAPse8mX95qkynGxDL7VWRPBxdrzVpNzYgtKKwm1+7v1HT S0bhr0vEbQrg8ESblmdtSvwvHIasanH5ISL9XahixmW6AkTuFwHGZF1G hjzY+4wop0IOlGpim/kbyLDOs3bDhpOAB6OEddlq22zGBAK5pOc3XfzE 2emCyMXTLz6ElGO9H5/Yza3SK/BD13Wu+f6t5Ia2XBsC7GjdIAUkSL6J xtRWc3DvOVM=
+. 3600000 IN DNSKEY 257 3 8 AwEAAaSG9FXnaJQp8BkrUzCV4TG4gbtanXZkcDFdNeIh3cKT3Kn0uElT 20W1Q4cQN2OM3rSrhkLCVa9bNGYWsleva4n7cdQFfTCMfu13EhtMVkeT /aylvhzqsiwtEDZHAb1J01CaQt25YeQCKuRvDIRbaGRvrw3P308X+rGD /eU1Oc9CMCVTX8Aqz/4g908yDNxTnM1PiU5CFNp5QgXnMive9MNcRyFE Yzb4U9YPRo/jOQGsqkqyWrFimGAYqWfjToKax4PuFiL4LSdevVMwoMLI gJ37fMHn1bnnq80FS93EBUcOD1uzeAkvleQwAd8/FarJAlK6mCCOaokt nu5x2m47E2U=
+. 2592000 IN RRSIG DNSKEY 8 0 3600 20180922145219 20180823145219 61125 . yYkUPTM8xs0TtYt1B6ch0puEzlVbzS2CENuBXBzGAg0TExiEtn8PPvsQ 4A6bWGg8Z4FXgs54d/mlGgSLdMQZgZQ+aNsALNqzyJ9J95SR+vOxWMqm 5+2zEn5cLmze1N6KbbbylMki7haLs9URqgM7Dt7QaT7k2zbqSqrNK64M El3Zz7wG7L0In1ZHIeSBWBXA7C9SMv7Nu+wGAiX6hR0GqTLByHdXm+J7 yfNIk3qpLTUz6c0Z7YZlwyIHF6eXHzRrdTZlU1m0M163RHQrxASDhBCz uNbbfdWp1hcG5AQ+XQNKoH7fg3yfYeHjPcTIrAmXnJdz0SnnqT6CYafr vm+9xw==
+. 2592000 IN RRSIG DNSKEY 8 0 3600 20180922145219 20180823145219 9352 . IqvhBDyacS6gSy4+tC1M07nBjlf7MU+41vE96fnyz3L3LcF7O1n71GWm MaB4fOzwFnTeUgTiW4egmj5HAxdYzBS00lyj0N2xALdmsG5r7rGdcjFR 5Lrwz/5xVw6ovoiYiocI+atIS1ZQuXnxQ8i+xwJGstHfoWjnw5+sY7xZ HBG1GZpJxL3pyKI5dFpC0K0wEtPgeFU/V4toA3sCejFjWeb4w7VPLKkH vhy7KoIEhcL5BZzDjBKGU5Oqp45zUo60Kogtquo+xTo8jZxTqKrU9XrX G1/hVquxJo5tDnM5YZK1Y5LZEciQalsalY+CYxpGE9TTiMS99vXGUiRc Sme0Fw==
+
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RD RA REFUSED
+SECTION QUESTION
+. IN RRSIG
+SECTION ANSWER
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RD RA AD NOERROR
+SECTION QUESTION
+test. IN NS
+SECTION ANSWER
+test. IN NS ns.net
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+test. IN DS
+SECTION AUTHORITY
+. 86400 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2017030902 1800 900 604800 86400
+test. 86400 IN NSEC . NS RRSIG NSEC
+. 86400 IN RRSIG SOA 8 0 86400 20180922145219 20180823145219 61125 . oUmzRZlxlk8WMI6EVAVqveSrD7gY7dxog/KF0xIsUgb4wuw7ysD4C1E7 GCKA8UqFXKsJn+RpKJHiHAASLctCL8Ewnger2ebeRtTNENEuqyvWlJwW HIY9Bk9YvMr5RzNdTfyLS+EGFGQzk2G793DOoi0DuNFaFK1AkN/jDDzD uGxwK/9oZ4X9Sk2mKeZfjKWIoXaPhMonfnWtX+6rKeMvgSjMZYEXz0+E XYHeHwvtUIPYzMfO2iCrEfCABH04OG61NP5N9W+IiOKP1KAmT8id3JyF JACHjSP6BeEIv6Ydzz3M9vq4B4pj0Cr9ePH0GnNC0Sg8uOfHzjC5bHld oaJs4g==
+test. 86400 IN RRSIG NSEC 8 1 86400 20180922145219 20180823145219 61125 . Fgq94cQgkH4LhB0NFRSzqZT09eLTr4JdP+xV+s5HEPiipfmaRSy3Y1Zo ihtofwjO+LObPVLmyPz7WUWmJBCu3bPRS0GU4LtqYmpBpUxjuaVqbiw0 7/GO3IS6nLD1IVYpuXzktncdJDkwalkPb/qMtrMTSEzH5V6a9CJErKJR IEn36Ypg6+hvKXJT5uJyqcTseqFXnHDXBzIQjlc6rm7gPCdUCzxx9UrP SxVeNfLSYUV96RA2G1NgksCejP7TPpIiheRXDIItvl/XtQy5pdaPsdE+ bJHQaxC2uTabzvGPoLHRahfCjtH2XxuFsWCSm7ad0bRQH4v1o05CB8Cv 9JkDEQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RD RA REFUSED
+SECTION QUESTION
+test. IN RRSIG
+SECTION ANSWER
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RD RA AD NOERROR
+SECTION QUESTION
+net. IN NS
+SECTION AUTHORITY
+. 86400 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2017030902 1800 900 604800 86400
+. 86400 IN RRSIG SOA 8 0 86400 20180922145219 20180823145219 61125 . oUmzRZlxlk8WMI6EVAVqveSrD7gY7dxog/KF0xIsUgb4wuw7ysD4C1E7 GCKA8UqFXKsJn+RpKJHiHAASLctCL8Ewnger2ebeRtTNENEuqyvWlJwW HIY9Bk9YvMr5RzNdTfyLS+EGFGQzk2G793DOoi0DuNFaFK1AkN/jDDzD uGxwK/9oZ4X9Sk2mKeZfjKWIoXaPhMonfnWtX+6rKeMvgSjMZYEXz0+E XYHeHwvtUIPYzMfO2iCrEfCABH04OG61NP5N9W+IiOKP1KAmT8id3JyF JACHjSP6BeEIv6Ydzz3M9vq4B4pj0Cr9ePH0GnNC0Sg8uOfHzjC5bHld oaJs4g==
+. 86400 IN NSEC ns.net. NS SOA RRSIG NSEC DNSKEY
+. 86400 IN RRSIG NSEC 8 0 86400 20180922145219 20180823145219 61125 . LytyS0hCj2ICPHpIrXTjRNITmlSKgokGjR6ByELloAedBkJZ/wEbQPDO U6mJ4aS3b0gXawe6/OKbdLg38WpyUgfPVsKoGiiWDjAxq4/VBSnsSQec cr0jnBobqGGcskxGZGxIKmWOVR0lSiMNWxdlMhAiDIQRpZ3NZx57OmW/ zpI+sL1E1T0difRa2+qnPzmvJZ3k0m8VLHcavHv43SacLwfYkYmyyfTF itQQ8yxJ26atReXemFScOEZuVtkdWzBlHgzN8p5mZhzGc6lJEu51ncFI pJ9gLHAdSzxotyYpto73FW7siw2N7sQwcV0c9lIVhAa61yGSHfDza1jj p0CFDg==
+
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RD RA AD NOERROR
+SECTION QUESTION
+root-servers.net. IN NS
+SECTION AUTHORITY
+. 86400 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2017030902 1800 900 604800 86400
+. 86400 IN RRSIG SOA 8 0 86400 20180922145219 20180823145219 61125 . oUmzRZlxlk8WMI6EVAVqveSrD7gY7dxog/KF0xIsUgb4wuw7ysD4C1E7 GCKA8UqFXKsJn+RpKJHiHAASLctCL8Ewnger2ebeRtTNENEuqyvWlJwW HIY9Bk9YvMr5RzNdTfyLS+EGFGQzk2G793DOoi0DuNFaFK1AkN/jDDzD uGxwK/9oZ4X9Sk2mKeZfjKWIoXaPhMonfnWtX+6rKeMvgSjMZYEXz0+E XYHeHwvtUIPYzMfO2iCrEfCABH04OG61NP5N9W+IiOKP1KAmT8id3JyF JACHjSP6BeEIv6Ydzz3M9vq4B4pj0Cr9ePH0GnNC0Sg8uOfHzjC5bHld oaJs4g==
+. 86400 IN NSEC ns.net. NS SOA RRSIG NSEC DNSKEY
+. 86400 IN RRSIG NSEC 8 0 86400 20180922145219 20180823145219 61125 . LytyS0hCj2ICPHpIrXTjRNITmlSKgokGjR6ByELloAedBkJZ/wEbQPDO U6mJ4aS3b0gXawe6/OKbdLg38WpyUgfPVsKoGiiWDjAxq4/VBSnsSQec cr0jnBobqGGcskxGZGxIKmWOVR0lSiMNWxdlMhAiDIQRpZ3NZx57OmW/ zpI+sL1E1T0difRa2+qnPzmvJZ3k0m8VLHcavHv43SacLwfYkYmyyfTF itQQ8yxJ26atReXemFScOEZuVtkdWzBlHgzN8p5mZhzGc6lJEu51ncFI pJ9gLHAdSzxotyYpto73FW7siw2N7sQwcV0c9lIVhAa61yGSHfDza1jj p0CFDg==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RD RA AD NOERROR
+SECTION QUESTION
+ns.net. IN A
+SECTION ANSWER
+ns.net. 600 IN A 1.1.1.1
+ns.net. 600 IN RRSIG A 8 2 600 20180922145219 20180823145219 61125 . lMTAJQzlIGSXxDXyx9v7D/sOblhpmaKEJocdracgxNdq139K1uY6nc7G mL0BOu4laDokHm2likkjkxd8zgMl9Q+4Py5prCS0nlxPSE1Rek7rGqGY DAx9nSyrpBY+MyMSlnaGEDEhBNKTZYnF6x5/aGs9u3TlqNI6nDB/00eP 8gXU4OoioARTQKvk7IHsbqjfwTlExbPbbT2Ojj0vJfGbLAsUmxfH8wmD ZO2psneD6JZW+fs1SIsxe/SpBn71j2kp9DDVFZVFmsMldlDHueKK/Drr D3bY0UQLlPgRLBiIAMFD6b8RxdxLKhSqYffFXDuJRpIWmVwF4LpdfrA/ IwPnng==
+
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RD RA AD NOERROR
+SECTION QUESTION
+k.root-servers.net. IN A
+SECTION ANSWER
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 2592000 IN RRSIG A 8 3 3600000 20180922145219 20180823145219 61125 . fp2r9FQp7w/05L5fnChzb4wtVbPOlzmCFINieJGTaB+0qrXoNpgWR9Uo gWgEiT+t6QyAEi4Ls2oUId+iJZPJ9xUV55ClpiWDEcr+/xLTrCQRgtih Z6bQS7xOaGMlX4ARWUEBEbWxQtcos1SEPDyWzay/b+/oS1+obuY6Q9H9 1/K6D1Dlu26Hxj6v7zk+h3g2oD3QNZk0OH1a0f7PndevNcF6BuqUHW9j 9MiUGXZbvM1pKK8ReCOgy7jsuhhnyCSqPTXJEZV7Ankygfg8hr4kLhOu Ek1siTIQFUgLoyCDS3JwX9i5Kunboksp04NYWKH2jqM/rsKyskT5mEJG Ab5vGQ==
+
+ENTRY_END
+RANGE_END
+
+RANGE_BEGIN 1 999999
+ ADDRESS 1.1.1.1 ;ns.net
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+test. IN SOA
+SECTION ANSWER
+test. 86400 IN SOA ns.net. hostmaster.example.com. 1234 1800 900 604800 86400
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+test. IN NS
+SECTION ANSWER
+test. IN NS ns.net
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+ns.net. IN A
+SECTION ANSWER
+ns.net. 86400 IN A 1.1.1.1
+ENTRY_END
+RANGE_END
+
+; cache miss - wrong SOA RRSIG in answer section
+STEP 101 QUERY
+ENTRY_BEGIN
+REPLY RD AD DO
+SECTION QUESTION
+. IN SOA
+ENTRY_END
+
+STEP 102 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA SERVFAIL
+SECTION QUESTION
+. IN SOA
+SECTION ANSWER
+SECTION AUTHORITY
+ENTRY_END
+
+; cache hit - wrong SOA RRSIG in answer section
+STEP 201 QUERY
+ENTRY_BEGIN
+REPLY RD AD DO
+SECTION QUESTION
+. IN SOA
+ENTRY_END
+
+STEP 202 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA SERVFAIL
+SECTION QUESTION
+. IN SOA
+SECTION ANSWER
+SECTION AUTHORITY
+ENTRY_END
+
+; cache miss - wrong SOA RRSIG in authority section
+STEP 301 QUERY
+ENTRY_BEGIN
+REPLY RD AD DO
+SECTION QUESTION
+test. IN DS
+ENTRY_END
+
+STEP 302 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA SERVFAIL
+SECTION QUESTION
+test. IN DS
+SECTION ANSWER
+SECTION AUTHORITY
+ENTRY_END
+
+; cache hit - wrong SOA RRSIG in authority section
+STEP 401 QUERY
+ENTRY_BEGIN
+REPLY RD AD DO
+SECTION QUESTION
+test. IN DS
+ENTRY_END
+
+STEP 402 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA SERVFAIL
+SECTION QUESTION
+test. IN DS
+SECTION ANSWER
+SECTION AUTHORITY
+ENTRY_END
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/val_cname_loop1.rpl b/tests/integration/deckard/sets/resolver/val_cname_loop1.rpl
new file mode 100644
index 0000000..2b09721
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_cname_loop1.rpl
@@ -0,0 +1,144 @@
+do-ip6: no
+
+; config options
+; The island of trust is at example.com
+;server:
+ trust-anchor: "example.com. IN DS 438 10 2 33F8133EB48EDB093839E985600EB7B7009EB5AC312D11CCA9007F6B 71D94D7B"
+ val-override-date: "20160308103040"
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN CNAME loop.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. 3600 IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 10 2 3600 20251231235959 20160308093040 2843 example.com. boNVuXxyhW+Gmiu+4ip1QQvIGqFNVsFfg1v+ywgc4+37ieQ5t+qJsHVm fJITRZrJxYQ6T/MkZKhpxLCemgFeKU6syWwoCfypnGino2G1urvqThna WTImSPhY/QsOj1ALy51d9Q+Mb5vt69XJt6SQvtNf6imepIFOT6CPSfjx BJ4=
+SECTION ADDITIONAL
+ns.example.com. 3600 IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 10 3 3600 20251231235959 20160308093040 2843 example.com. VSq+DkxJYr9Z+uh3KgpyPNwtuim4WVXnTdhRW7HX90CP5tyOVjDDTehA UmCxB8iFjUFE3hlwDx0Y71g+8Oso1t0JGkvDtWf5RDx1w+4K/1pQ2JMG lZTh7juaGJzXtltxqBoY67z1FBp9MI59O0hkABtz1CElj9LrhDr9wQa4 OUo=
+ENTRY_END
+
+; response to DNSKEY priming query
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+example.com. IN DNSKEY
+SECTION ANSWER
+example.com. 3600 IN DNSKEY 256 3 10 AwEAAcOHC7D2ZcG5M6MK5If/60+vvBM67BC8qUx04f6Kcvhx9GBMIMYz 87m6m2P5WKafW5AN1K9jY37m2fU/TdACQNzqu4wyVsOQefke/v2fgswg NgneP/C7cpyBVuK+8BUHjrorfLORClD3mbQMQldaaO2h6+OArAGHlFNI oFsuCjyR
+example.com. 3600 IN DNSKEY 257 3 10 AwEAAc4VCSEu1C1lAxuZMC8tSyissZNXC2lgS3zNvAvFdLtAsSbhB1cj dLCtTWUv1Ki/T+iWn10iemLQJ0S6z8wK+a7maC3ELZP1qoSFln+FiAsZ xYK72/XDEYMMp01F0gxgzZ2alWx3WKm2mELXf/ezEx+7X2ZNbwum5TKt FxtvotmT
+example.com. 3600 IN RRSIG DNSKEY 10 2 3600 20251231235959 20160308093040 438 example.com. cas8JKwtLUIItwOgrDrDG9pSkqiYw3r+8vyvt962kjHFBNG0D7AeegaO GMSWRziqA4L8xdgP750rLR5CRFQ9oPQlr/RWnsebGdJ3Yohwwa04HE6n OvR+o0u0oqNQ+P5KinxVKSv0Ru+BVMPHRDfIXN/FD5p9+nvIrnjXQlI3 vvM=
+example.com. 3600 IN RRSIG DNSKEY 10 2 3600 20251231235959 20160308093040 2843 example.com. uDLTMMTvJCcetKr6THEJ8Rn0gMLPFZTbOGJBZyZ2E5F9KkPSS01Nm6/P e+j0R3ObYXodqnZIY19fzXJKS2dJktoXkqNLBW/SpWTlFzpfHKCvTbJS VLrJ/lrEunE5cgSAqBrbAAuJrFpX/gaavqokElnUv1Mki2agTH1dTZyn X8M=
+SECTION AUTHORITY
+example.com. 3600 IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 10 2 3600 20251231235959 20160308093040 2843 example.com. boNVuXxyhW+Gmiu+4ip1QQvIGqFNVsFfg1v+ywgc4+37ieQ5t+qJsHVm fJITRZrJxYQ6T/MkZKhpxLCemgFeKU6syWwoCfypnGino2G1urvqThna WTImSPhY/QsOj1ALy51d9Q+Mb5vt69XJt6SQvtNf6imepIFOT6CPSfjx BJ4=
+SECTION ADDITIONAL
+ns.example.com. 3600 IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 10 3 3600 20251231235959 20160308093040 2843 example.com. VSq+DkxJYr9Z+uh3KgpyPNwtuim4WVXnTdhRW7HX90CP5tyOVjDDTehA UmCxB8iFjUFE3hlwDx0Y71g+8Oso1t0JGkvDtWf5RDx1w+4K/1pQ2JMG lZTh7juaGJzXtltxqBoY67z1FBp9MI59O0hkABtz1CElj9LrhDr9wQa4 OUo=
+ENTRY_END
+
+; response to query of interest
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. 3600 IN CNAME www.example.com.
+www.example.com. 3600 IN RRSIG CNAME 10 3 3600 20251231235959 20160308093040 438 example.com. gMjZEEynrC1cW2t6s6bpRRxSmlq2Jt+7+vIHYP4pq9pqGHg6EM+Nexob au3wmIJv7c5vMmlQmk2z63HLXIEYHFjSzAHgyhfRVM9iEkK8Ules0k6H y5xuE3Z4aE3kGU5d7oNOQs4RlcNEI13bF7dxQ6c+41mNd3ihX9ZqCeXF O8E=
+SECTION AUTHORITY
+example.com. 3600 IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 10 2 3600 20251231235959 20160308093040 2843 example.com. boNVuXxyhW+Gmiu+4ip1QQvIGqFNVsFfg1v+ywgc4+37ieQ5t+qJsHVm fJITRZrJxYQ6T/MkZKhpxLCemgFeKU6syWwoCfypnGino2G1urvqThna WTImSPhY/QsOj1ALy51d9Q+Mb5vt69XJt6SQvtNf6imepIFOT6CPSfjx BJ4=
+SECTION ADDITIONAL
+ns.example.com. 3600 IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 10 3 3600 20251231235959 20160308093040 2843 example.com. VSq+DkxJYr9Z+uh3KgpyPNwtuim4WVXnTdhRW7HX90CP5tyOVjDDTehA UmCxB8iFjUFE3hlwDx0Y71g+8Oso1t0JGkvDtWf5RDx1w+4K/1pQ2JMG lZTh7juaGJzXtltxqBoY67z1FBp9MI59O0hkABtz1CElj9LrhDr9wQa4 OUo=
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH opcode qname flags rcode question
+REPLY QR RD RA DO SERVFAIL
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/val_cname_loop1_3.rpl b/tests/integration/deckard/sets/resolver/val_cname_loop1_3.rpl
new file mode 100644
index 0000000..617c76c
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_cname_loop1_3.rpl
@@ -0,0 +1,184 @@
+do-ip6: no
+
+; config options
+; The island of trust is at example.com
+;server:
+ trust-anchor: "example.com. IN DS 438 10 2 33F8133EB48EDB093839E985600EB7B7009EB5AC312D11CCA9007F6B 71D94D7B"
+ val-override-date: "20160308103040"
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN CNAME loop.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. 3600 IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 10 2 3600 20251231235959 20160308093040 2843 example.com. boNVuXxyhW+Gmiu+4ip1QQvIGqFNVsFfg1v+ywgc4+37ieQ5t+qJsHVm fJITRZrJxYQ6T/MkZKhpxLCemgFeKU6syWwoCfypnGino2G1urvqThna WTImSPhY/QsOj1ALy51d9Q+Mb5vt69XJt6SQvtNf6imepIFOT6CPSfjx BJ4=
+SECTION ADDITIONAL
+ns.example.com. 3600 IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 10 3 3600 20251231235959 20160308093040 2843 example.com. VSq+DkxJYr9Z+uh3KgpyPNwtuim4WVXnTdhRW7HX90CP5tyOVjDDTehA UmCxB8iFjUFE3hlwDx0Y71g+8Oso1t0JGkvDtWf5RDx1w+4K/1pQ2JMG lZTh7juaGJzXtltxqBoY67z1FBp9MI59O0hkABtz1CElj9LrhDr9wQa4 OUo=
+ENTRY_END
+
+; response to DNSKEY priming query
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+example.com. IN DNSKEY
+SECTION ANSWER
+example.com. 3600 IN DNSKEY 256 3 10 AwEAAcOHC7D2ZcG5M6MK5If/60+vvBM67BC8qUx04f6Kcvhx9GBMIMYz 87m6m2P5WKafW5AN1K9jY37m2fU/TdACQNzqu4wyVsOQefke/v2fgswg NgneP/C7cpyBVuK+8BUHjrorfLORClD3mbQMQldaaO2h6+OArAGHlFNI oFsuCjyR
+example.com. 3600 IN DNSKEY 257 3 10 AwEAAc4VCSEu1C1lAxuZMC8tSyissZNXC2lgS3zNvAvFdLtAsSbhB1cj dLCtTWUv1Ki/T+iWn10iemLQJ0S6z8wK+a7maC3ELZP1qoSFln+FiAsZ xYK72/XDEYMMp01F0gxgzZ2alWx3WKm2mELXf/ezEx+7X2ZNbwum5TKt FxtvotmT
+example.com. 3600 IN RRSIG DNSKEY 10 2 3600 20251231235959 20160308093040 438 example.com. cas8JKwtLUIItwOgrDrDG9pSkqiYw3r+8vyvt962kjHFBNG0D7AeegaO GMSWRziqA4L8xdgP750rLR5CRFQ9oPQlr/RWnsebGdJ3Yohwwa04HE6n OvR+o0u0oqNQ+P5KinxVKSv0Ru+BVMPHRDfIXN/FD5p9+nvIrnjXQlI3 vvM=
+example.com. 3600 IN RRSIG DNSKEY 10 2 3600 20251231235959 20160308093040 2843 example.com. uDLTMMTvJCcetKr6THEJ8Rn0gMLPFZTbOGJBZyZ2E5F9KkPSS01Nm6/P e+j0R3ObYXodqnZIY19fzXJKS2dJktoXkqNLBW/SpWTlFzpfHKCvTbJS VLrJ/lrEunE5cgSAqBrbAAuJrFpX/gaavqokElnUv1Mki2agTH1dTZyn X8M=
+SECTION AUTHORITY
+example.com. 3600 IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 10 2 3600 20251231235959 20160308093040 2843 example.com. boNVuXxyhW+Gmiu+4ip1QQvIGqFNVsFfg1v+ywgc4+37ieQ5t+qJsHVm fJITRZrJxYQ6T/MkZKhpxLCemgFeKU6syWwoCfypnGino2G1urvqThna WTImSPhY/QsOj1ALy51d9Q+Mb5vt69XJt6SQvtNf6imepIFOT6CPSfjx BJ4=
+SECTION ADDITIONAL
+ns.example.com. 3600 IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 10 3 3600 20251231235959 20160308093040 2843 example.com. VSq+DkxJYr9Z+uh3KgpyPNwtuim4WVXnTdhRW7HX90CP5tyOVjDDTehA UmCxB8iFjUFE3hlwDx0Y71g+8Oso1t0JGkvDtWf5RDx1w+4K/1pQ2JMG lZTh7juaGJzXtltxqBoY67z1FBp9MI59O0hkABtz1CElj9LrhDr9wQa4 OUo=
+ENTRY_END
+
+; response to query of interest
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+bar.example.com. 3600 IN CNAME www.example.com.
+bar.example.com. 3600 IN RRSIG CNAME 10 3 3600 20251231235959 20160308093040 438 example.com. azRcQFNDdj0HVMR4CS4cSX1039MJIqsFPP2Fxnr1DLwlvTPxOkqWGumu PKhBkcnX8JMFyJpVBD+3qHrOOuz7BOKvu6Subj0ku+qCdVmrDsdxwabP 7lf63j92EE0ofGoYtN7sdkH6c89OHxTfR5CsALFyT+syABYjyl/tKx9n 8JA=
+foo.example.com. 3600 IN CNAME bar.example.com.
+foo.example.com. 3600 IN RRSIG CNAME 10 3 3600 20251231235959 20160308093040 438 example.com. ke8Jzx4GK1yIfiVJjMTrhP5OJihx0g3iwBGk9qz8XiV4/K9Z6KztlPut KVAqlKIXWgvKshyvWG/fGrCr9NZZ2+h8LfxRopvYRArh5mP2QN5kLV6O DhRkKJFYthsyU0swGZXJAd2CZ2plz1qauQYmrzGCRK336vu4+b/lzJP8 D4M=
+www.example.com. 3600 IN CNAME foo.example.com.
+www.example.com. 3600 IN RRSIG CNAME 10 3 3600 20251231235959 20160308093040 438 example.com. Bn3zMkt2HEfIt5kLCEmcT6Kj/20qcvob2RdQaaTtZD+xrbDmqjFkiW09 d+RGP4g7ydXxIDczs4d3dTaSjEp2mgzd8GG0yegG1wiLzObp+gXTLaIT LLz53neab4yS0ZOaformDeWSCx3//U8guRRfOSnPHLQGAmqrVG7Dr30D RKU=
+SECTION AUTHORITY
+example.com. 3600 IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 10 2 3600 20251231235959 20160308093040 2843 example.com. boNVuXxyhW+Gmiu+4ip1QQvIGqFNVsFfg1v+ywgc4+37ieQ5t+qJsHVm fJITRZrJxYQ6T/MkZKhpxLCemgFeKU6syWwoCfypnGino2G1urvqThna WTImSPhY/QsOj1ALy51d9Q+Mb5vt69XJt6SQvtNf6imepIFOT6CPSfjx BJ4=
+SECTION ADDITIONAL
+ns.example.com. 3600 IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 10 3 3600 20251231235959 20160308093040 2843 example.com. VSq+DkxJYr9Z+uh3KgpyPNwtuim4WVXnTdhRW7HX90CP5tyOVjDDTehA UmCxB8iFjUFE3hlwDx0Y71g+8Oso1t0JGkvDtWf5RDx1w+4K/1pQ2JMG lZTh7juaGJzXtltxqBoY67z1FBp9MI59O0hkABtz1CElj9LrhDr9wQa4 OUo=
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+foo.example.com. IN A
+SECTION ANSWER
+foo.example.com. 3600 IN CNAME bar.example.com.
+foo.example.com. 3600 IN RRSIG CNAME 10 3 3600 20251231235959 20160308093040 438 example.com. ke8Jzx4GK1yIfiVJjMTrhP5OJihx0g3iwBGk9qz8XiV4/K9Z6KztlPut KVAqlKIXWgvKshyvWG/fGrCr9NZZ2+h8LfxRopvYRArh5mP2QN5kLV6O DhRkKJFYthsyU0swGZXJAd2CZ2plz1qauQYmrzGCRK336vu4+b/lzJP8 D4M=
+www.example.com. 3600 IN CNAME foo.example.com.
+www.example.com. 3600 IN RRSIG CNAME 10 3 3600 20251231235959 20160308093040 438 example.com. Bn3zMkt2HEfIt5kLCEmcT6Kj/20qcvob2RdQaaTtZD+xrbDmqjFkiW09 d+RGP4g7ydXxIDczs4d3dTaSjEp2mgzd8GG0yegG1wiLzObp+gXTLaIT LLz53neab4yS0ZOaformDeWSCx3//U8guRRfOSnPHLQGAmqrVG7Dr30D RKU=
+SECTION AUTHORITY
+example.com. 3600 IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 10 2 3600 20251231235959 20160308093040 2843 example.com. boNVuXxyhW+Gmiu+4ip1QQvIGqFNVsFfg1v+ywgc4+37ieQ5t+qJsHVm fJITRZrJxYQ6T/MkZKhpxLCemgFeKU6syWwoCfypnGino2G1urvqThna WTImSPhY/QsOj1ALy51d9Q+Mb5vt69XJt6SQvtNf6imepIFOT6CPSfjx BJ4=
+SECTION ADDITIONAL
+ns.example.com. 3600 IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 10 3 3600 20251231235959 20160308093040 2843 example.com. VSq+DkxJYr9Z+uh3KgpyPNwtuim4WVXnTdhRW7HX90CP5tyOVjDDTehA UmCxB8iFjUFE3hlwDx0Y71g+8Oso1t0JGkvDtWf5RDx1w+4K/1pQ2JMG lZTh7juaGJzXtltxqBoY67z1FBp9MI59O0hkABtz1CElj9LrhDr9wQa4 OUo=
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+bar.example.com. IN A
+SECTION ANSWER
+bar.example.com. 3600 IN CNAME www.example.com.
+bar.example.com. 3600 IN RRSIG CNAME 10 3 3600 20251231235959 20160308093040 438 example.com. azRcQFNDdj0HVMR4CS4cSX1039MJIqsFPP2Fxnr1DLwlvTPxOkqWGumu PKhBkcnX8JMFyJpVBD+3qHrOOuz7BOKvu6Subj0ku+qCdVmrDsdxwabP 7lf63j92EE0ofGoYtN7sdkH6c89OHxTfR5CsALFyT+syABYjyl/tKx9n 8JA=
+SECTION AUTHORITY
+example.com. 3600 IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 10 2 3600 20251231235959 20160308093040 2843 example.com. boNVuXxyhW+Gmiu+4ip1QQvIGqFNVsFfg1v+ywgc4+37ieQ5t+qJsHVm fJITRZrJxYQ6T/MkZKhpxLCemgFeKU6syWwoCfypnGino2G1urvqThna WTImSPhY/QsOj1ALy51d9Q+Mb5vt69XJt6SQvtNf6imepIFOT6CPSfjx BJ4=
+SECTION ADDITIONAL
+ns.example.com. 3600 IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 10 3 3600 20251231235959 20160308093040 2843 example.com. VSq+DkxJYr9Z+uh3KgpyPNwtuim4WVXnTdhRW7HX90CP5tyOVjDDTehA UmCxB8iFjUFE3hlwDx0Y71g+8Oso1t0JGkvDtWf5RDx1w+4K/1pQ2JMG lZTh7juaGJzXtltxqBoY67z1FBp9MI59O0hkABtz1CElj9LrhDr9wQa4 OUo=
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH opcode qname flags rcode question
+REPLY QR RD RA DO SERVFAIL
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/val_cname_loop3.rpl b/tests/integration/deckard/sets/resolver/val_cname_loop3.rpl
new file mode 100644
index 0000000..00c5cd3
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_cname_loop3.rpl
@@ -0,0 +1,166 @@
+do-ip6: no
+
+; config options
+; The island of trust is at example.com
+;server:
+ trust-anchor: "example.com. IN DS 438 10 2 33F8133EB48EDB093839E985600EB7B7009EB5AC312D11CCA9007F6B 71D94D7B"
+ val-override-date: "20160308103040"
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN CNAME loop.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. 3600 IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 10 2 3600 20251231235959 20160308093040 2843 example.com. boNVuXxyhW+Gmiu+4ip1QQvIGqFNVsFfg1v+ywgc4+37ieQ5t+qJsHVm fJITRZrJxYQ6T/MkZKhpxLCemgFeKU6syWwoCfypnGino2G1urvqThna WTImSPhY/QsOj1ALy51d9Q+Mb5vt69XJt6SQvtNf6imepIFOT6CPSfjx BJ4=
+SECTION ADDITIONAL
+ns.example.com. 3600 IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 10 3 3600 20251231235959 20160308093040 2843 example.com. VSq+DkxJYr9Z+uh3KgpyPNwtuim4WVXnTdhRW7HX90CP5tyOVjDDTehA UmCxB8iFjUFE3hlwDx0Y71g+8Oso1t0JGkvDtWf5RDx1w+4K/1pQ2JMG lZTh7juaGJzXtltxqBoY67z1FBp9MI59O0hkABtz1CElj9LrhDr9wQa4 OUo=
+ENTRY_END
+
+; response to DNSKEY priming query
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+example.com. IN DNSKEY
+SECTION ANSWER
+example.com. 3600 IN DNSKEY 256 3 10 AwEAAcOHC7D2ZcG5M6MK5If/60+vvBM67BC8qUx04f6Kcvhx9GBMIMYz 87m6m2P5WKafW5AN1K9jY37m2fU/TdACQNzqu4wyVsOQefke/v2fgswg NgneP/C7cpyBVuK+8BUHjrorfLORClD3mbQMQldaaO2h6+OArAGHlFNI oFsuCjyR
+example.com. 3600 IN DNSKEY 257 3 10 AwEAAc4VCSEu1C1lAxuZMC8tSyissZNXC2lgS3zNvAvFdLtAsSbhB1cj dLCtTWUv1Ki/T+iWn10iemLQJ0S6z8wK+a7maC3ELZP1qoSFln+FiAsZ xYK72/XDEYMMp01F0gxgzZ2alWx3WKm2mELXf/ezEx+7X2ZNbwum5TKt FxtvotmT
+example.com. 3600 IN RRSIG DNSKEY 10 2 3600 20251231235959 20160308093040 438 example.com. cas8JKwtLUIItwOgrDrDG9pSkqiYw3r+8vyvt962kjHFBNG0D7AeegaO GMSWRziqA4L8xdgP750rLR5CRFQ9oPQlr/RWnsebGdJ3Yohwwa04HE6n OvR+o0u0oqNQ+P5KinxVKSv0Ru+BVMPHRDfIXN/FD5p9+nvIrnjXQlI3 vvM=
+example.com. 3600 IN RRSIG DNSKEY 10 2 3600 20251231235959 20160308093040 2843 example.com. uDLTMMTvJCcetKr6THEJ8Rn0gMLPFZTbOGJBZyZ2E5F9KkPSS01Nm6/P e+j0R3ObYXodqnZIY19fzXJKS2dJktoXkqNLBW/SpWTlFzpfHKCvTbJS VLrJ/lrEunE5cgSAqBrbAAuJrFpX/gaavqokElnUv1Mki2agTH1dTZyn X8M=
+SECTION AUTHORITY
+example.com. 3600 IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 10 2 3600 20251231235959 20160308093040 2843 example.com. boNVuXxyhW+Gmiu+4ip1QQvIGqFNVsFfg1v+ywgc4+37ieQ5t+qJsHVm fJITRZrJxYQ6T/MkZKhpxLCemgFeKU6syWwoCfypnGino2G1urvqThna WTImSPhY/QsOj1ALy51d9Q+Mb5vt69XJt6SQvtNf6imepIFOT6CPSfjx BJ4=
+SECTION ADDITIONAL
+ns.example.com. 3600 IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 10 3 3600 20251231235959 20160308093040 2843 example.com. VSq+DkxJYr9Z+uh3KgpyPNwtuim4WVXnTdhRW7HX90CP5tyOVjDDTehA UmCxB8iFjUFE3hlwDx0Y71g+8Oso1t0JGkvDtWf5RDx1w+4K/1pQ2JMG lZTh7juaGJzXtltxqBoY67z1FBp9MI59O0hkABtz1CElj9LrhDr9wQa4 OUo=
+ENTRY_END
+
+; response to query of interest
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. 3600 IN CNAME foo.example.com.
+www.example.com. 3600 IN RRSIG CNAME 10 3 3600 20251231235959 20160308093040 438 example.com. Bn3zMkt2HEfIt5kLCEmcT6Kj/20qcvob2RdQaaTtZD+xrbDmqjFkiW09 d+RGP4g7ydXxIDczs4d3dTaSjEp2mgzd8GG0yegG1wiLzObp+gXTLaIT LLz53neab4yS0ZOaformDeWSCx3//U8guRRfOSnPHLQGAmqrVG7Dr30D RKU=
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+foo.example.com. IN A
+SECTION ANSWER
+foo.example.com. 3600 IN CNAME bar.example.com.
+foo.example.com. 3600 IN RRSIG CNAME 10 3 3600 20251231235959 20160308093040 438 example.com. ke8Jzx4GK1yIfiVJjMTrhP5OJihx0g3iwBGk9qz8XiV4/K9Z6KztlPut KVAqlKIXWgvKshyvWG/fGrCr9NZZ2+h8LfxRopvYRArh5mP2QN5kLV6O DhRkKJFYthsyU0swGZXJAd2CZ2plz1qauQYmrzGCRK336vu4+b/lzJP8 D4M=
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+bar.example.com. IN A
+SECTION ANSWER
+bar.example.com. 3600 IN CNAME www.example.com.
+bar.example.com. 3600 IN RRSIG CNAME 10 3 3600 20251231235959 20160308093040 438 example.com. azRcQFNDdj0HVMR4CS4cSX1039MJIqsFPP2Fxnr1DLwlvTPxOkqWGumu PKhBkcnX8JMFyJpVBD+3qHrOOuz7BOKvu6Subj0ku+qCdVmrDsdxwabP 7lf63j92EE0ofGoYtN7sdkH6c89OHxTfR5CsALFyT+syABYjyl/tKx9n 8JA=
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH opcode qname flags rcode question
+REPLY QR RD RA DO SERVFAIL
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/val_cname_new_signer.rpl b/tests/integration/deckard/sets/resolver/val_cname_new_signer.rpl
new file mode 100644
index 0000000..82a3e23
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_cname_new_signer.rpl
@@ -0,0 +1,241 @@
+do-ip6: no
+
+; config options
+; The island of trust is at example.com
+;server:
+ trust-anchor: "example.com. IN DS 438 10 2 33F8133EB48EDB093839E985600EB7B7009EB5AC312D11CCA9007F6B 71D94D7B"
+ val-override-date: "20160308103040"
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN CNAME chain with different signer names in RRSIGs.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. 3600 IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. 3600 IN A 1.2.3.4
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+sub.example.com. IN NS
+SECTION ANSWER
+sub.example.com. 3600 IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. 3600 IN A 1.2.3.4
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+sub.example.com. IN DS
+SECTION ANSWER
+sub.example.com. 3600 IN DS 38364 7 1 66DC14443014B2727261B50B447170DE18CF43A9
+sub.example.com. 3600 IN DS 38364 7 2 719A6680950A624D2C71A67981A7AF884C23E3C21074FF1CF8FB7EFE 20C52F97
+sub.example.com. 3600 IN RRSIG DS 10 3 3600 20251231235959 20160308093040 438 example.com. mu/x2yR8nFrwOnnfN7dMQ2e2MAAuZigua0wakXaPT0j4pe5AjQhriZXU pWLk5z77ck8Kswt+O23v1sUxmq1bUsIc2kw6N02UyiHnPoxmcu0rg0Kc ustfA++YT5/L+fpq5PRm3kKfHLo81WdZ/VJoaafH/kXHnZTcP62ZoteQ sqw=
+sub.example.com. 3600 IN RRSIG DS 10 3 3600 20251231235959 20160308093040 2843 example.com. ZLx28ZpzPpaafVH3hqV9h6AZJH7Zn0ELOfFxodogJfWue86xjuWhzpBV O9jCOqyURitiBgKNYazghmciNw4wzANbz+hhtc4rIPsfOr/8Vn3pjyev yScX227d16hXKBNKTrAeKNvM8fVPT0E7cG3CY0mzVp3SVqrr+6hl+dgb gXU=
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+example.com. IN DNSKEY
+SECTION ANSWER
+example.com. 3600 IN DNSKEY 256 3 10 AwEAAcOHC7D2ZcG5M6MK5If/60+vvBM67BC8qUx04f6Kcvhx9GBMIMYz 87m6m2P5WKafW5AN1K9jY37m2fU/TdACQNzqu4wyVsOQefke/v2fgswg NgneP/C7cpyBVuK+8BUHjrorfLORClD3mbQMQldaaO2h6+OArAGHlFNI oFsuCjyR
+example.com. 3600 IN DNSKEY 257 3 10 AwEAAc4VCSEu1C1lAxuZMC8tSyissZNXC2lgS3zNvAvFdLtAsSbhB1cj dLCtTWUv1Ki/T+iWn10iemLQJ0S6z8wK+a7maC3ELZP1qoSFln+FiAsZ xYK72/XDEYMMp01F0gxgzZ2alWx3WKm2mELXf/ezEx+7X2ZNbwum5TKt FxtvotmT
+example.com. 3600 IN RRSIG DNSKEY 10 2 3600 20251231235959 20160308093040 438 example.com. cas8JKwtLUIItwOgrDrDG9pSkqiYw3r+8vyvt962kjHFBNG0D7AeegaO GMSWRziqA4L8xdgP750rLR5CRFQ9oPQlr/RWnsebGdJ3Yohwwa04HE6n OvR+o0u0oqNQ+P5KinxVKSv0Ru+BVMPHRDfIXN/FD5p9+nvIrnjXQlI3 vvM=
+example.com. 3600 IN RRSIG DNSKEY 10 2 3600 20251231235959 20160308093040 2843 example.com. uDLTMMTvJCcetKr6THEJ8Rn0gMLPFZTbOGJBZyZ2E5F9KkPSS01Nm6/P e+j0R3ObYXodqnZIY19fzXJKS2dJktoXkqNLBW/SpWTlFzpfHKCvTbJS VLrJ/lrEunE5cgSAqBrbAAuJrFpX/gaavqokElnUv1Mki2agTH1dTZyn X8M=
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. 3600 IN CNAME foo.example.com.
+www.example.com. 3600 IN RRSIG CNAME 10 3 3600 20251231235959 20160308093040 438 example.com. Bn3zMkt2HEfIt5kLCEmcT6Kj/20qcvob2RdQaaTtZD+xrbDmqjFkiW09 d+RGP4g7ydXxIDczs4d3dTaSjEp2mgzd8GG0yegG1wiLzObp+gXTLaIT LLz53neab4yS0ZOaformDeWSCx3//U8guRRfOSnPHLQGAmqrVG7Dr30D RKU=
+www.example.com. 3600 IN RRSIG CNAME 10 3 3600 20251231235959 20160308093040 2843 example.com. FpyDEo49Y1b5Hb112BDCohW+93sDTmBrYc1rRfI8QrfLPXRwpMFVZBhU fDk8aG6qyKVlCa3DhpcHRyPi9SAz1nNPNhstcSqmmj7vNWjBVY5wtt1m 9AqEXFca5liXxVhuijpW9GBMm1LFyNYzuNqQszyje8/NZSumaIbqJiJy f6c=
+foo.example.com. 3600 IN CNAME foo.sub.example.com.
+foo.example.com. 3600 IN RRSIG CNAME 10 3 3600 20251231235959 20160308093040 438 example.com. aD8FHTvx3sL/prnJ5tfeZG1Tb7gUknU7GGJg8H5W4MkZKteMsF+Vydy9 LI/yTMjk+43Hmsim1lqtzL4GLoegG9xJCMVo14QVqsAwSzzyA/ySfWox Hw/tiltI8VBfOmRDL9V3qRhW6ZaYbXFHY1AbIapIsO/gFPcJ/nVsnugZ tHc=
+foo.example.com. 3600 IN RRSIG CNAME 10 3 3600 20251231235959 20160308093040 2843 example.com. ht4bE1Q5IevG+F0qvLDjbEaRvNRsnEKnEm3ntcXemtrtIpCLM5KsM2Bc oPrl3+ayQAv2NJM8GsJM9xWzZYAKEQk+THhusCE4j8/lX6Ngmb4M3x0R CI6sBxmN84v4HFXqk4W7dMW7BL9NlEMY2bgQe9g2kUcfA7FHaUQofrqS ASQ=
+foo.sub.example.com. 3600 IN CNAME www.sub.example.com.
+foo.sub.example.com. 3600 IN RRSIG CNAME 7 4 3600 20251231235959 20160308093040 27527 sub.example.com. vd1rVNNnARpWt7AmfKL1Kt2tqD5/v52tmwJHabpDegmMZ9sW3cZ3u+VF zypg545TnxtRBJAKmhEooDAOt4oNaP7u8K83HUCwlZOYz2bu0lrZU5wL ALi4jX880lWc/AR9z1FzG6ZXEcK9lu+1nC5x09jedaUFOG5bEMSMmdN+ 2N1Rdf75l3CiJIigiUE2y5pS4rDemsTJqgF/QK8XBbBNaz6c2f6XRKnc fC40jsfcufR0wTrhZw7/7FthKoaLBi/xE11mItQkBGDbCAgyM3ftV3mZ ArmlCg8expcTRuGIvhpvMbTf4m3/zBHPxsxO75QvD84ysBz0C6hnquJH 1BfrNA==
+www.sub.example.com. 3600 IN A 1.2.3.123
+www.sub.example.com. 3600 IN RRSIG A 7 4 3600 20251231235959 20160308093040 27527 sub.example.com. QiGpNqXdMQWFYzXMk0FhqEJuzAYijUHOywSUS/hgDxoxBRXBam/tfb3d 1Yqv4+ZVI06ZzOvC2YHRCULjBqjzsQbxxqzPtkfBWbAP/urRFsuwo1zx OSbW9xSUYmHbHicRLFxijvZhuJXX/11tja4dj9ZOeYF/HdWP3r38H4WT /8w3vKr7h2StmL2fY43LxqQm23voNiqJ1dsXLtjyoeIqH40jdMqeLKB+ PJ9p4d3HzOg7uIhLSQYi9slUBWQ10a4uxEBEXmeCI5gLQPot8ijBxF2t TsIOMMPieGC5Zlt9YeT6fsdM6HiUDrfCGbuf9TdlmQqNwRcd8orW58HV SgGalg==
+SECTION AUTHORITY
+sub.example.com. 3600 IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. 3600 IN A 1.2.3.4
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+foo.example.com. IN A
+SECTION ANSWER
+foo.example.com. 3600 IN CNAME foo.sub.example.com.
+foo.example.com. 3600 IN RRSIG CNAME 10 3 3600 20251231235959 20160308093040 438 example.com. aD8FHTvx3sL/prnJ5tfeZG1Tb7gUknU7GGJg8H5W4MkZKteMsF+Vydy9 LI/yTMjk+43Hmsim1lqtzL4GLoegG9xJCMVo14QVqsAwSzzyA/ySfWox Hw/tiltI8VBfOmRDL9V3qRhW6ZaYbXFHY1AbIapIsO/gFPcJ/nVsnugZ tHc=
+foo.example.com. 3600 IN RRSIG CNAME 10 3 3600 20251231235959 20160308093040 2843 example.com. ht4bE1Q5IevG+F0qvLDjbEaRvNRsnEKnEm3ntcXemtrtIpCLM5KsM2Bc oPrl3+ayQAv2NJM8GsJM9xWzZYAKEQk+THhusCE4j8/lX6Ngmb4M3x0R CI6sBxmN84v4HFXqk4W7dMW7BL9NlEMY2bgQe9g2kUcfA7FHaUQofrqS ASQ=
+foo.sub.example.com. 3600 IN CNAME www.sub.example.com.
+foo.sub.example.com. 3600 IN RRSIG CNAME 7 4 3600 20251231235959 20160308093040 27527 sub.example.com. vd1rVNNnARpWt7AmfKL1Kt2tqD5/v52tmwJHabpDegmMZ9sW3cZ3u+VF zypg545TnxtRBJAKmhEooDAOt4oNaP7u8K83HUCwlZOYz2bu0lrZU5wL ALi4jX880lWc/AR9z1FzG6ZXEcK9lu+1nC5x09jedaUFOG5bEMSMmdN+ 2N1Rdf75l3CiJIigiUE2y5pS4rDemsTJqgF/QK8XBbBNaz6c2f6XRKnc fC40jsfcufR0wTrhZw7/7FthKoaLBi/xE11mItQkBGDbCAgyM3ftV3mZ ArmlCg8expcTRuGIvhpvMbTf4m3/zBHPxsxO75QvD84ysBz0C6hnquJH 1BfrNA==
+www.sub.example.com. 3600 IN A 1.2.3.123
+www.sub.example.com. 3600 IN RRSIG A 7 4 3600 20251231235959 20160308093040 27527 sub.example.com. QiGpNqXdMQWFYzXMk0FhqEJuzAYijUHOywSUS/hgDxoxBRXBam/tfb3d 1Yqv4+ZVI06ZzOvC2YHRCULjBqjzsQbxxqzPtkfBWbAP/urRFsuwo1zx OSbW9xSUYmHbHicRLFxijvZhuJXX/11tja4dj9ZOeYF/HdWP3r38H4WT /8w3vKr7h2StmL2fY43LxqQm23voNiqJ1dsXLtjyoeIqH40jdMqeLKB+ PJ9p4d3HzOg7uIhLSQYi9slUBWQ10a4uxEBEXmeCI5gLQPot8ijBxF2t TsIOMMPieGC5Zlt9YeT6fsdM6HiUDrfCGbuf9TdlmQqNwRcd8orW58HV SgGalg==
+SECTION AUTHORITY
+sub.example.com. 3600 IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. 3600 IN A 1.2.3.4
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+sub.example.com. IN DNSKEY
+SECTION ANSWER
+sub.example.com. 3600 IN DNSKEY 256 3 7 AwEAAfXXu2eDy9QsjLuHgEMWmG03TVauwmITCq520ANujsTZlPKyQKJe xyrYm61e0RuQJb5dB5JnE0O3YYJOpnrl8keieAqVt1efnNtcn8V1em48 et146ZYFAUb/PMdTOgd2XJnhVEWD3VsZbWNMCxP1KcJTATAaLDVCY//E sc9K3CvGUizNcSoTK2rGS73A6GqmvVNnGir6AQIZifkvb6PKzF/hVpS8 cgvKF/UP8hu+0Glbq1YYTFrXMUBzKUH+X19lRvk3eLHurSvGjDEM3ZO6 tp1QdpzIRPzYKENG+qs07dhgCZyb4zqwEycmL9/Vot0ByTGbeHvHN93P PrLxcM5zlVk=
+sub.example.com. 3600 IN DNSKEY 257 3 7 AwEAAfTD+gzZ2g7c9VoOUR2ekQiPNEyqcyl0MZ4sD3bleU8D8hQdDgAI 1G38raY3xmNea8yLCQYF0x00QbmKtzMjpZqKfsCFZDX6lBV5dP8IwJ0D F6L4hjO819IInf6upH9tfQNnueflWyKzfg2zitV+ILZ4YtZViyCKqayw CSPE8OkFlszZyCESzhrXqoPdJ0oHdZCG4lOlRIgZfrMLC4yTI56iiwFc UsKy7BhNPW+hcc4r+0WB9BCpsiei/FjPMcyeMrx1W+s/xgW7/55Nq+dM PUn9v24uCptZUupn/7CRgMGM5DmWe94QIswAQjH2mXNfOgVPOiceLYzU mcNoKudvSUu1hbzJbVHA4UNWDm2vvsdsEzrOEzqO0ZVczLoZzWU4WpLf IlKm481OKkzAP9Y5F4iTTSIrbVcAuEW/iz5zfqWirgGniiTCszAie8lH u1EPBgGnfotqhq9IbNA6aKNUreJPLvJnds7J/aQmiSdm15pAq71B26X5 BmoZVhbNmh6MHXkq99EIt0yRMEOfPLRN7euza8Idd4mA+E8jpdgtYdJD LC7f2SoQxaN4RMr5MC/Z1ENQgLMYRkd87pEQycAlNAoWMPJMuoDNdwhV 15F8+pvkvfu5cm9FoEWvgS+onibUM9EC9L9EDdfDdW1Hf1QfUinVoMf/ Szf1urkPVNl0nNYF
+sub.example.com. 3600 IN RRSIG DNSKEY 7 3 3600 20251231235959 20160308093040 27527 sub.example.com. CzB+UmU98ArL/HRIOMyHV87PPYoH3G/KKdJlbjtNZAaHG+K6Lad0pKW5 wZR3By1AMlIN9ta8374q+nCEtY+ryM7yBFpzSTmBqrf7ZhkxWh2OSnrI CllC3CsSeltsOq/AEQZwJLQG/gQiCqqQnJY4mneKhcg0Bzc0hpe8c1Dq C5eaHKqt7BaVRO1Ix6OKqEqjHzwd5HpKd2pzU91HyfvHsWrOnKyIwHJP nyOcuHESKN97YLey9Onw0eXjUYdbG5GM12OV1qawShOthcm7XUQiJ0Xl V7y0pNekCxXZdQQI/XhVj8XyLa5pLy8PaOLqypbMBg19J5diLUZYAt/f Dj/EzQ==
+sub.example.com. 3600 IN RRSIG DNSKEY 7 3 3600 20251231235959 20160308093040 38364 sub.example.com. xzyO85eLRwVsg9VI4RnXnjrwf0/TCMub7UcOr7TWWhwt9iR8KFSenx17 EVG1OlgEzRrdZLQWJBPlNBR5aLpsNlzUj+cnCpdG6NtUjcdqRJxb+64Y RktG5Hz35AV7Iegs3L6tFdE4J2moGCDC0y8Rm9wyL+mCUNylpnXUOo8D NDpd7VcYKoieGWxLd8OK5aCYUlB2ziL9yIMOZR+sGEPZWR6ABXDbUF6S ddj7lbZ7y+GHp2XpjDvpmbRSrznNmopzn71O59sCiog8obnGif02EXEn 3L2a8eGx3tMhCZZAPaqJrocTIAmye0vLt0xT22WFPxmcButV1UYZd00m KwJaKgUB450wdub4aAXVvtTx7Us++6zRepZ3VtXARDT+qGzBUkISEuSM FbLHlqqdQeLTcfdu7azEfyCWudoDTbXejFQjFtWkSo6SwEV8sC64rMV6 AFytMBvksBD0tjGrWvPkdDxWa43SQja8BiTlKugtM7zJgqBH9pi1MN4o asc3hyBHBKEiX8ilK7GBTqFph8tdRxawWsaK273pATBLeQfHM2jKcg5p ULhSLxYDvJ+TgYKJkFyFd4C78HffgrashJvrxNsK1QQk05bpTGk9j6ja fzzyB6mDhWGLux1/i++akwTOKsWmFnNe6MXKTN1gnEw4pny3m7zBmh0x gFkbfEo1aDU=
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+foo.sub.example.com. IN A
+SECTION ANSWER
+foo.sub.example.com. 3600 IN CNAME www.sub.example.com.
+foo.sub.example.com. 3600 IN RRSIG CNAME 7 4 3600 20251231235959 20160308093040 27527 sub.example.com. vd1rVNNnARpWt7AmfKL1Kt2tqD5/v52tmwJHabpDegmMZ9sW3cZ3u+VF zypg545TnxtRBJAKmhEooDAOt4oNaP7u8K83HUCwlZOYz2bu0lrZU5wL ALi4jX880lWc/AR9z1FzG6ZXEcK9lu+1nC5x09jedaUFOG5bEMSMmdN+ 2N1Rdf75l3CiJIigiUE2y5pS4rDemsTJqgF/QK8XBbBNaz6c2f6XRKnc fC40jsfcufR0wTrhZw7/7FthKoaLBi/xE11mItQkBGDbCAgyM3ftV3mZ ArmlCg8expcTRuGIvhpvMbTf4m3/zBHPxsxO75QvD84ysBz0C6hnquJH 1BfrNA==
+www.sub.example.com. 3600 IN A 1.2.3.123
+www.sub.example.com. 3600 IN RRSIG A 7 4 3600 20251231235959 20160308093040 27527 sub.example.com. QiGpNqXdMQWFYzXMk0FhqEJuzAYijUHOywSUS/hgDxoxBRXBam/tfb3d 1Yqv4+ZVI06ZzOvC2YHRCULjBqjzsQbxxqzPtkfBWbAP/urRFsuwo1zx OSbW9xSUYmHbHicRLFxijvZhuJXX/11tja4dj9ZOeYF/HdWP3r38H4WT /8w3vKr7h2StmL2fY43LxqQm23voNiqJ1dsXLtjyoeIqH40jdMqeLKB+ PJ9p4d3HzOg7uIhLSQYi9slUBWQ10a4uxEBEXmeCI5gLQPot8ijBxF2t TsIOMMPieGC5Zlt9YeT6fsdM6HiUDrfCGbuf9TdlmQqNwRcd8orW58HV SgGalg==
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www.sub.example.com. IN A
+SECTION ANSWER
+www.sub.example.com. 3600 IN A 1.2.3.123
+www.sub.example.com. 3600 IN RRSIG A 7 4 3600 20251231235959 20160308093040 27527 sub.example.com. QiGpNqXdMQWFYzXMk0FhqEJuzAYijUHOywSUS/hgDxoxBRXBam/tfb3d 1Yqv4+ZVI06ZzOvC2YHRCULjBqjzsQbxxqzPtkfBWbAP/urRFsuwo1zx OSbW9xSUYmHbHicRLFxijvZhuJXX/11tja4dj9ZOeYF/HdWP3r38H4WT /8w3vKr7h2StmL2fY43LxqQm23voNiqJ1dsXLtjyoeIqH40jdMqeLKB+ PJ9p4d3HzOg7uIhLSQYi9slUBWQ10a4uxEBEXmeCI5gLQPot8ijBxF2t TsIOMMPieGC5Zlt9YeT6fsdM6HiUDrfCGbuf9TdlmQqNwRcd8orW58HV SgGalg==
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH opcode qname flags rcode question answer
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. 3600 IN CNAME foo.example.com.
+www.example.com. 3600 IN RRSIG CNAME 10 3 3600 20251231235959 20160308093040 438 example.com. Bn3zMkt2HEfIt5kLCEmcT6Kj/20qcvob2RdQaaTtZD+xrbDmqjFkiW09 d+RGP4g7ydXxIDczs4d3dTaSjEp2mgzd8GG0yegG1wiLzObp+gXTLaIT LLz53neab4yS0ZOaformDeWSCx3//U8guRRfOSnPHLQGAmqrVG7Dr30D RKU=
+www.example.com. 3600 IN RRSIG CNAME 10 3 3600 20251231235959 20160308093040 2843 example.com. FpyDEo49Y1b5Hb112BDCohW+93sDTmBrYc1rRfI8QrfLPXRwpMFVZBhU fDk8aG6qyKVlCa3DhpcHRyPi9SAz1nNPNhstcSqmmj7vNWjBVY5wtt1m 9AqEXFca5liXxVhuijpW9GBMm1LFyNYzuNqQszyje8/NZSumaIbqJiJy f6c=
+foo.example.com. 3600 IN CNAME foo.sub.example.com.
+foo.example.com. 3600 IN RRSIG CNAME 10 3 3600 20251231235959 20160308093040 438 example.com. aD8FHTvx3sL/prnJ5tfeZG1Tb7gUknU7GGJg8H5W4MkZKteMsF+Vydy9 LI/yTMjk+43Hmsim1lqtzL4GLoegG9xJCMVo14QVqsAwSzzyA/ySfWox Hw/tiltI8VBfOmRDL9V3qRhW6ZaYbXFHY1AbIapIsO/gFPcJ/nVsnugZ tHc=
+foo.example.com. 3600 IN RRSIG CNAME 10 3 3600 20251231235959 20160308093040 2843 example.com. ht4bE1Q5IevG+F0qvLDjbEaRvNRsnEKnEm3ntcXemtrtIpCLM5KsM2Bc oPrl3+ayQAv2NJM8GsJM9xWzZYAKEQk+THhusCE4j8/lX6Ngmb4M3x0R CI6sBxmN84v4HFXqk4W7dMW7BL9NlEMY2bgQe9g2kUcfA7FHaUQofrqS ASQ=
+foo.sub.example.com. 3600 IN CNAME www.sub.example.com.
+foo.sub.example.com. 3600 IN RRSIG CNAME 7 4 3600 20251231235959 20160308093040 27527 sub.example.com. vd1rVNNnARpWt7AmfKL1Kt2tqD5/v52tmwJHabpDegmMZ9sW3cZ3u+VF zypg545TnxtRBJAKmhEooDAOt4oNaP7u8K83HUCwlZOYz2bu0lrZU5wL ALi4jX880lWc/AR9z1FzG6ZXEcK9lu+1nC5x09jedaUFOG5bEMSMmdN+ 2N1Rdf75l3CiJIigiUE2y5pS4rDemsTJqgF/QK8XBbBNaz6c2f6XRKnc fC40jsfcufR0wTrhZw7/7FthKoaLBi/xE11mItQkBGDbCAgyM3ftV3mZ ArmlCg8expcTRuGIvhpvMbTf4m3/zBHPxsxO75QvD84ysBz0C6hnquJH 1BfrNA==
+www.sub.example.com. 3600 IN A 1.2.3.123
+www.sub.example.com. 3600 IN RRSIG A 7 4 3600 20251231235959 20160308093040 27527 sub.example.com. QiGpNqXdMQWFYzXMk0FhqEJuzAYijUHOywSUS/hgDxoxBRXBam/tfb3d 1Yqv4+ZVI06ZzOvC2YHRCULjBqjzsQbxxqzPtkfBWbAP/urRFsuwo1zx OSbW9xSUYmHbHicRLFxijvZhuJXX/11tja4dj9ZOeYF/HdWP3r38H4WT /8w3vKr7h2StmL2fY43LxqQm23voNiqJ1dsXLtjyoeIqH40jdMqeLKB+ PJ9p4d3HzOg7uIhLSQYi9slUBWQ10a4uxEBEXmeCI5gLQPot8ijBxF2t TsIOMMPieGC5Zlt9YeT6fsdM6HiUDrfCGbuf9TdlmQqNwRcd8orW58HV SgGalg==
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/val_cname_oob.rpl b/tests/integration/deckard/sets/resolver/val_cname_oob.rpl
new file mode 100644
index 0000000..27ca786
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_cname_oob.rpl
@@ -0,0 +1,183 @@
+do-ip6: no
+
+; config options
+; The island of trust is at example.com
+;server:
+ trust-anchor: "example.com. IN DS 438 10 2 33F8133EB48EDB093839E985600EB7B7009EB5AC312D11CCA9007F6B 71D94D7B"
+ val-override-date: "20160308103040"
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+ query-minimization: off
+CONFIG_END
+
+SCENARIO_BEGIN OOB CNAME to wrong name.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+net. IN A
+SECTION AUTHORITY
+net. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+a.gtld-servers.net. IN A
+SECTION ANSWER
+a.gtld-servers.net. IN A 192.5.6.30
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+a.gtld-servers.net. IN AAAA
+SECTION ANSWER
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR AA NXDOMAIN
+SECTION QUESTION
+farfaraway.com. IN A
+SECTION AUTHORITY
+com. 900 IN SOA a.gtld-servers.net. nstld.verisign-grs.com. 1479809979 1800 900 604800 86400
+SECTION ADDITIONAL
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. 3600 IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 10 2 3600 20251231235959 20160308093040 2843 example.com. boNVuXxyhW+Gmiu+4ip1QQvIGqFNVsFfg1v+ywgc4+37ieQ5t+qJsHVm fJITRZrJxYQ6T/MkZKhpxLCemgFeKU6syWwoCfypnGino2G1urvqThna WTImSPhY/QsOj1ALy51d9Q+Mb5vt69XJt6SQvtNf6imepIFOT6CPSfjx BJ4=
+SECTION ADDITIONAL
+ns.example.com. 3600 IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 10 3 3600 20251231235959 20160308093040 2843 example.com. VSq+DkxJYr9Z+uh3KgpyPNwtuim4WVXnTdhRW7HX90CP5tyOVjDDTehA UmCxB8iFjUFE3hlwDx0Y71g+8Oso1t0JGkvDtWf5RDx1w+4K/1pQ2JMG lZTh7juaGJzXtltxqBoY67z1FBp9MI59O0hkABtz1CElj9LrhDr9wQa4 OUo=
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+example.com. IN DNSKEY
+SECTION ANSWER
+example.com. 3600 IN DNSKEY 256 3 10 AwEAAcOHC7D2ZcG5M6MK5If/60+vvBM67BC8qUx04f6Kcvhx9GBMIMYz 87m6m2P5WKafW5AN1K9jY37m2fU/TdACQNzqu4wyVsOQefke/v2fgswg NgneP/C7cpyBVuK+8BUHjrorfLORClD3mbQMQldaaO2h6+OArAGHlFNI oFsuCjyR
+example.com. 3600 IN DNSKEY 257 3 10 AwEAAc4VCSEu1C1lAxuZMC8tSyissZNXC2lgS3zNvAvFdLtAsSbhB1cj dLCtTWUv1Ki/T+iWn10iemLQJ0S6z8wK+a7maC3ELZP1qoSFln+FiAsZ xYK72/XDEYMMp01F0gxgzZ2alWx3WKm2mELXf/ezEx+7X2ZNbwum5TKt FxtvotmT
+example.com. 3600 IN RRSIG DNSKEY 10 2 3600 20251231235959 20160308093040 438 example.com. cas8JKwtLUIItwOgrDrDG9pSkqiYw3r+8vyvt962kjHFBNG0D7AeegaO GMSWRziqA4L8xdgP750rLR5CRFQ9oPQlr/RWnsebGdJ3Yohwwa04HE6n OvR+o0u0oqNQ+P5KinxVKSv0Ru+BVMPHRDfIXN/FD5p9+nvIrnjXQlI3 vvM=
+example.com. 3600 IN RRSIG DNSKEY 10 2 3600 20251231235959 20160308093040 2843 example.com. uDLTMMTvJCcetKr6THEJ8Rn0gMLPFZTbOGJBZyZ2E5F9KkPSS01Nm6/P e+j0R3ObYXodqnZIY19fzXJKS2dJktoXkqNLBW/SpWTlFzpfHKCvTbJS VLrJ/lrEunE5cgSAqBrbAAuJrFpX/gaavqokElnUv1Mki2agTH1dTZyn X8M=
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+alfa.example.com. IN A
+SECTION ANSWER
+alfa.example.com. 3600 IN CNAME www.farfaraway.com.
+alfa.example.com. 3600 IN RRSIG CNAME 10 3 3600 20251231235959 20160308093040 438 example.com. yKZk1/bXS2mjUqJ9bS2KVrf1Cq/bsNoHj7VD3R8sp2Rn63vBEoxzqBxo 8lYuXlNw3sMAQFQYhaloVrNnDPwlAfY+qXuLutsAtKxql/FxdRWIjjMk fvO9zNbqzCpP1FtCO0PpFgJXYH5wkkq8/sBDRW8CbDotruSJPbJ1/OGn JPc=
+alfa.example.com. 3600 IN RRSIG CNAME 10 3 3600 20251231235959 20160308093040 2843 example.com. SglKK7SovflRnQVz1leE94Dez+obX9nWR5eAQ6ggun2xkZbUjK22UHbl ihP5F0PpqnTdgPNyEgCR1P/HON2VYMlB1CT2J/fm3ZriLyBEOEils98J UkWZYy5Kt3eXcye17YKBXIW9ivIWTh5brRWaPEbzXy73ID3HZYyKVM52 3UU=
+www.farfaraway.com. 3600 IN A 1.2.3.123
+www.farfaraway.com. 3600 IN RRSIG A 10 3 3600 20251231235959 20160308093040 2843 example.com. 11111111111111111111111111111111 11111111111111111111111111111111 11111111111111111111111111111111 11111111111111111111111111111111 11111111111111111111111111111111 11111111110=
+SECTION AUTHORITY
+farfaraway.com. 3600 IN NS ns.farfaraway.com.
+SECTION ADDITIONAL
+ns.farfaraway.com. 3600 IN A 1.2.3.10
+ENTRY_END
+
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+alfa.example.com. IN A
+ENTRY_END
+
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH opcode qname flags rcode question
+REPLY QR RD RA DO NXDOMAIN
+SECTION QUESTION
+alfa.example.com. IN A
+SECTION ANSWER
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/val_cname_to_unsigned.rpl b/tests/integration/deckard/sets/resolver/val_cname_to_unsigned.rpl
new file mode 100644
index 0000000..a1ed4cd
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_cname_to_unsigned.rpl
@@ -0,0 +1,204 @@
+do-ip6: no
+
+; config options
+; The island of trust is at example.com
+;server:
+ trust-anchor: "example.com. IN DS 438 10 2 33F8133EB48EDB093839E985600EB7B7009EB5AC312D11CCA9007F6B 71D94D7B"
+ val-override-date: "20160308103040"
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN CNAME to unsigned subzone.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. 3600 IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 10 2 3600 20251231235959 20160308093040 2843 example.com. boNVuXxyhW+Gmiu+4ip1QQvIGqFNVsFfg1v+ywgc4+37ieQ5t+qJsHVm fJITRZrJxYQ6T/MkZKhpxLCemgFeKU6syWwoCfypnGino2G1urvqThna WTImSPhY/QsOj1ALy51d9Q+Mb5vt69XJt6SQvtNf6imepIFOT6CPSfjx BJ4=
+SECTION ADDITIONAL
+ns.example.com. 3600 IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 10 3 3600 20251231235959 20160308093040 2843 example.com. VSq+DkxJYr9Z+uh3KgpyPNwtuim4WVXnTdhRW7HX90CP5tyOVjDDTehA UmCxB8iFjUFE3hlwDx0Y71g+8Oso1t0JGkvDtWf5RDx1w+4K/1pQ2JMG lZTh7juaGJzXtltxqBoY67z1FBp9MI59O0hkABtz1CElj9LrhDr9wQa4 OUo=
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+example.com. IN DNSKEY
+SECTION ANSWER
+example.com. 3600 IN DNSKEY 256 3 10 AwEAAcOHC7D2ZcG5M6MK5If/60+vvBM67BC8qUx04f6Kcvhx9GBMIMYz 87m6m2P5WKafW5AN1K9jY37m2fU/TdACQNzqu4wyVsOQefke/v2fgswg NgneP/C7cpyBVuK+8BUHjrorfLORClD3mbQMQldaaO2h6+OArAGHlFNI oFsuCjyR
+example.com. 3600 IN DNSKEY 257 3 10 AwEAAc4VCSEu1C1lAxuZMC8tSyissZNXC2lgS3zNvAvFdLtAsSbhB1cj dLCtTWUv1Ki/T+iWn10iemLQJ0S6z8wK+a7maC3ELZP1qoSFln+FiAsZ xYK72/XDEYMMp01F0gxgzZ2alWx3WKm2mELXf/ezEx+7X2ZNbwum5TKt FxtvotmT
+example.com. 3600 IN RRSIG DNSKEY 10 2 3600 20251231235959 20160308093040 438 example.com. cas8JKwtLUIItwOgrDrDG9pSkqiYw3r+8vyvt962kjHFBNG0D7AeegaO GMSWRziqA4L8xdgP750rLR5CRFQ9oPQlr/RWnsebGdJ3Yohwwa04HE6n OvR+o0u0oqNQ+P5KinxVKSv0Ru+BVMPHRDfIXN/FD5p9+nvIrnjXQlI3 vvM=
+example.com. 3600 IN RRSIG DNSKEY 10 2 3600 20251231235959 20160308093040 2843 example.com. uDLTMMTvJCcetKr6THEJ8Rn0gMLPFZTbOGJBZyZ2E5F9KkPSS01Nm6/P e+j0R3ObYXodqnZIY19fzXJKS2dJktoXkqNLBW/SpWTlFzpfHKCvTbJS VLrJ/lrEunE5cgSAqBrbAAuJrFpX/gaavqokElnUv1Mki2agTH1dTZyn X8M=
+SECTION AUTHORITY
+example.com. 3600 IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 10 2 3600 20251231235959 20160308093040 2843 example.com. boNVuXxyhW+Gmiu+4ip1QQvIGqFNVsFfg1v+ywgc4+37ieQ5t+qJsHVm fJITRZrJxYQ6T/MkZKhpxLCemgFeKU6syWwoCfypnGino2G1urvqThna WTImSPhY/QsOj1ALy51d9Q+Mb5vt69XJt6SQvtNf6imepIFOT6CPSfjx BJ4=
+SECTION ADDITIONAL
+ns.example.com. 3600 IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 10 3 3600 20251231235959 20160308093040 2843 example.com. VSq+DkxJYr9Z+uh3KgpyPNwtuim4WVXnTdhRW7HX90CP5tyOVjDDTehA UmCxB8iFjUFE3hlwDx0Y71g+8Oso1t0JGkvDtWf5RDx1w+4K/1pQ2JMG lZTh7juaGJzXtltxqBoY67z1FBp9MI59O0hkABtz1CElj9LrhDr9wQa4 OUo=
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. 3600 IN CNAME www.sub.example.com.
+www.example.com. 3600 IN RRSIG CNAME 10 3 3600 20251231235959 20160308093040 2843 example.com. msZaF29s99toR+WhRyQsRR63Nclwvic7dOMKH3KW3g/mamiN22g9dJ7L VPdG1FX9+4qosyn37d/+jUXy2UIryBXuXBojpPU3UrPq/gJOYtp1y23e dHgeGpCv7Tmp/TDDWJPNSUL/rWjl64MK1Dkd+O4plU+SMgqN1wuTgBg8 fsk=
+ENTRY_END
+
+ENTRY_BEGIN
+MANDATORY
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+sub.example.com. IN DS
+SECTION ANSWER
+SECTION AUTHORITY
+example.com. 3600 IN SOA ns.example.com. hostmaster.example.com. 2016022600 28800 7200 604800 18000
+example.com. 3600 IN RRSIG SOA 10 2 3600 20251231235959 20160308093040 2843 example.com. s3pCq6ZK3DEUkWYX3XKvr5v9Z4AhbJ4P7/AKQkhe3zymnTba7Bo5Uhmb Vav/A+u8gsoo9yBumReXLAv047btO+jdCOLD/yXvmaSt/yGGcipFoX6r 4kQWzUHby4NlQEdO3YykiZx7FtCGsMp0cfwPae4glkDsAPnIhhQurzzE VP4=
+sub.example.com. 18000 IN NSEC www.example.com. NS RRSIG NSEC
+sub.example.com. 18000 IN RRSIG NSEC 10 3 18000 20251231235959 20160308093040 2843 example.com. vA2GpUEeAnbvg8t35VEZybJoJvxlu9UGXHNEzIohxKetvLTp761NaCW5 NIhYnVv/b9GDmu5sU9cvQxN+7nEGqLXKnzlGbzIdSedrzBgjOnQNOGO5 BJTollsCG71OfTs2/4kzi04N11yWqSaJyidWLXPH2lElTFQX/3dMcP2m 5uE=
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+sub.example.com. IN A
+SECTION AUTHORITY
+sub.example.com. 3600 IN NS ns.sub.example.com.
+SECTION ADDITIONAL
+ns.sub.example.com. 3600 IN A 1.2.3.5
+ENTRY_END
+
+RANGE_END
+
+
+; ns.sub.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.5
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www.sub.example.com. IN A
+SECTION ANSWER
+www.sub.example.com. 3600 IN A 1.2.3.123
+ENTRY_END
+RANGE_END
+
+
+STEP 10 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+STEP 20 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA DO NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. 3600 IN CNAME www.sub.example.com.
+www.example.com. 3600 IN RRSIG CNAME 10 3 3600 20251231235959 20160308093040 2843 example.com. msZaF29s99toR+WhRyQsRR63Nclwvic7dOMKH3KW3g/mamiN22g9dJ7L VPdG1FX9+4qosyn37d/+jUXy2UIryBXuXBojpPU3UrPq/gJOYtp1y23e dHgeGpCv7Tmp/TDDWJPNSUL/rWjl64MK1Dkd+O4plU+SMgqN1wuTgBg8 fsk=
+www.sub.example.com. 3600 IN A 1.2.3.123
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+; Cache hit
+STEP 30 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+STEP 40 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA DO NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. 3600 IN CNAME www.sub.example.com.
+www.example.com. 3600 IN RRSIG CNAME 10 3 3600 20251231235959 20160308093040 2843 example.com. msZaF29s99toR+WhRyQsRR63Nclwvic7dOMKH3KW3g/mamiN22g9dJ7L VPdG1FX9+4qosyn37d/+jUXy2UIryBXuXBojpPU3UrPq/gJOYtp1y23e dHgeGpCv7Tmp/TDDWJPNSUL/rWjl64MK1Dkd+O4plU+SMgqN1wuTgBg8 fsk=
+www.sub.example.com. 3600 IN A 1.2.3.123
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/val_cname_to_unsigned_fake_rrsig.rpl b/tests/integration/deckard/sets/resolver/val_cname_to_unsigned_fake_rrsig.rpl
new file mode 100644
index 0000000..fdd4ff1
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_cname_to_unsigned_fake_rrsig.rpl
@@ -0,0 +1,215 @@
+do-ip6: no
+
+; config options
+; The island of trust is at example.com
+;server:
+ trust-anchor: "example.com. IN DS 438 10 2 33F8133EB48EDB093839E985600EB7B7009EB5AC312D11CCA9007F6B 71D94D7B"
+ val-override-date: "20160308103040"
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+ query-minimization: off
+CONFIG_END
+
+SCENARIO_BEGIN CNAME with invalid RRSIG to unsigned subzone must produce SERVFAIL
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. 3600 IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 10 2 3600 20251231235959 20160308093040 2843 example.com. boNVuXxyhW+Gmiu+4ip1QQvIGqFNVsFfg1v+ywgc4+37ieQ5t+qJsHVm fJITRZrJxYQ6T/MkZKhpxLCemgFeKU6syWwoCfypnGino2G1urvqThna WTImSPhY/QsOj1ALy51d9Q+Mb5vt69XJt6SQvtNf6imepIFOT6CPSfjx BJ4=
+SECTION ADDITIONAL
+ns.example.com. 3600 IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 10 3 3600 20251231235959 20160308093040 2843 example.com. VSq+DkxJYr9Z+uh3KgpyPNwtuim4WVXnTdhRW7HX90CP5tyOVjDDTehA UmCxB8iFjUFE3hlwDx0Y71g+8Oso1t0JGkvDtWf5RDx1w+4K/1pQ2JMG lZTh7juaGJzXtltxqBoY67z1FBp9MI59O0hkABtz1CElj9LrhDr9wQa4 OUo=
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+example.com. IN DNSKEY
+SECTION ANSWER
+example.com. 3600 IN DNSKEY 256 3 10 AwEAAcOHC7D2ZcG5M6MK5If/60+vvBM67BC8qUx04f6Kcvhx9GBMIMYz 87m6m2P5WKafW5AN1K9jY37m2fU/TdACQNzqu4wyVsOQefke/v2fgswg NgneP/C7cpyBVuK+8BUHjrorfLORClD3mbQMQldaaO2h6+OArAGHlFNI oFsuCjyR
+example.com. 3600 IN DNSKEY 257 3 10 AwEAAc4VCSEu1C1lAxuZMC8tSyissZNXC2lgS3zNvAvFdLtAsSbhB1cj dLCtTWUv1Ki/T+iWn10iemLQJ0S6z8wK+a7maC3ELZP1qoSFln+FiAsZ xYK72/XDEYMMp01F0gxgzZ2alWx3WKm2mELXf/ezEx+7X2ZNbwum5TKt FxtvotmT
+example.com. 3600 IN RRSIG DNSKEY 10 2 3600 20251231235959 20160308093040 438 example.com. cas8JKwtLUIItwOgrDrDG9pSkqiYw3r+8vyvt962kjHFBNG0D7AeegaO GMSWRziqA4L8xdgP750rLR5CRFQ9oPQlr/RWnsebGdJ3Yohwwa04HE6n OvR+o0u0oqNQ+P5KinxVKSv0Ru+BVMPHRDfIXN/FD5p9+nvIrnjXQlI3 vvM=
+example.com. 3600 IN RRSIG DNSKEY 10 2 3600 20251231235959 20160308093040 2843 example.com. uDLTMMTvJCcetKr6THEJ8Rn0gMLPFZTbOGJBZyZ2E5F9KkPSS01Nm6/P e+j0R3ObYXodqnZIY19fzXJKS2dJktoXkqNLBW/SpWTlFzpfHKCvTbJS VLrJ/lrEunE5cgSAqBrbAAuJrFpX/gaavqokElnUv1Mki2agTH1dTZyn X8M=
+SECTION AUTHORITY
+example.com. 3600 IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 10 2 3600 20251231235959 20160308093040 2843 example.com. boNVuXxyhW+Gmiu+4ip1QQvIGqFNVsFfg1v+ywgc4+37ieQ5t+qJsHVm fJITRZrJxYQ6T/MkZKhpxLCemgFeKU6syWwoCfypnGino2G1urvqThna WTImSPhY/QsOj1ALy51d9Q+Mb5vt69XJt6SQvtNf6imepIFOT6CPSfjx BJ4=
+SECTION ADDITIONAL
+ns.example.com. 3600 IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 10 3 3600 20251231235959 20160308093040 2843 example.com. VSq+DkxJYr9Z+uh3KgpyPNwtuim4WVXnTdhRW7HX90CP5tyOVjDDTehA UmCxB8iFjUFE3hlwDx0Y71g+8Oso1t0JGkvDtWf5RDx1w+4K/1pQ2JMG lZTh7juaGJzXtltxqBoY67z1FBp9MI59O0hkABtz1CElj9LrhDr9wQa4 OUo=
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. 3600 IN CNAME fake.sub.example.com.
+; following RRSIG was generated for www.example.com. 3600 IN CNAME www.sub.example.com.
+; -> rdata "fake.sub.example.com." == an attack!
+www.example.com. 3600 IN RRSIG CNAME 10 3 3600 20251231235959 20160308093040 2843 example.com. msZaF29s99toR+WhRyQsRR63Nclwvic7dOMKH3KW3g/mamiN22g9dJ7L VPdG1FX9+4qosyn37d/+jUXy2UIryBXuXBojpPU3UrPq/gJOYtp1y23e dHgeGpCv7Tmp/TDDWJPNSUL/rWjl64MK1Dkd+O4plU+SMgqN1wuTgBg8 fsk=
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN RRSIG
+SECTION ANSWER
+; following RRSIG was generated for www.example.com. 3600 IN CNAME www.sub.example.com.
+; -> rdata "fake.sub.example.com." obtained from previous query == an attack!
+www.example.com. 3600 IN RRSIG CNAME 10 3 3600 20251231235959 20160308093040 2843 example.com. msZaF29s99toR+WhRyQsRR63Nclwvic7dOMKH3KW3g/mamiN22g9dJ7L VPdG1FX9+4qosyn37d/+jUXy2UIryBXuXBojpPU3UrPq/gJOYtp1y23e dHgeGpCv7Tmp/TDDWJPNSUL/rWjl64MK1Dkd+O4plU+SMgqN1wuTgBg8 fsk=
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+fake.sub.example.com. IN A
+SECTION ANSWER
+SECTION AUTHORITY
+sub.example.com. 3600 IN NS ns.sub.example.com.
+SECTION ADDITIONAL
+ns.sub.example.com. 3600 IN A 1.2.3.5
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+sub.example.com. IN DS
+SECTION ANSWER
+SECTION AUTHORITY
+example.com. 3600 IN SOA ns.example.com. hostmaster.example.com. 2016022600 28800 7200 604800 18000
+example.com. 3600 IN RRSIG SOA 10 2 3600 20251231235959 20160308093040 2843 example.com. s3pCq6ZK3DEUkWYX3XKvr5v9Z4AhbJ4P7/AKQkhe3zymnTba7Bo5Uhmb Vav/A+u8gsoo9yBumReXLAv047btO+jdCOLD/yXvmaSt/yGGcipFoX6r 4kQWzUHby4NlQEdO3YykiZx7FtCGsMp0cfwPae4glkDsAPnIhhQurzzE VP4=
+sub.example.com. 18000 IN NSEC www.example.com. NS RRSIG NSEC
+sub.example.com. 18000 IN RRSIG NSEC 10 3 18000 20251231235959 20160308093040 2843 example.com. vA2GpUEeAnbvg8t35VEZybJoJvxlu9UGXHNEzIohxKetvLTp761NaCW5 NIhYnVv/b9GDmu5sU9cvQxN+7nEGqLXKnzlGbzIdSedrzBgjOnQNOGO5 BJTollsCG71OfTs2/4kzi04N11yWqSaJyidWLXPH2lElTFQX/3dMcP2m 5uE=
+ENTRY_END
+
+RANGE_END
+
+; ns.sub.example.com.
+; it should not be reached because of invalid RRSIG
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.5
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+fake.sub.example.com. IN A
+SECTION ANSWER
+fake.sub.example.com. 3600 IN A 1.2.3.123
+ENTRY_END
+RANGE_END
+
+
+; empty cache
+STEP 10 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+STEP 20 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA DO SERVFAIL
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+; Cache hit
+STEP 30 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+STEP 40 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA DO SERVFAIL
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/val_cname_trust_domains.rpl b/tests/integration/deckard/sets/resolver/val_cname_trust_domains.rpl
new file mode 100644
index 0000000..ef71b28
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_cname_trust_domains.rpl
@@ -0,0 +1,440 @@
+do-ip6: no
+
+; config options
+; The island of trust is at example.com and example.net; example.org is insecure
+trust-anchor: "example.com. 3600 IN DS 11901 7 1 4b5c9e50ad931b35fc507e0a20d141a056c19227"
+trust-anchor: "example.net. 3600 IN DS 59835 7 1 1fb3f5d45f4ffbf160e0f4fb75e3a1e8d34b6a67"
+val-override-date: "20170214000000"
+stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test validator with a CNAMEs between sub-trees with different TAs
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+; subtree with own trust anchor
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+; subtree with own trust anchor
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+net. IN A
+SECTION AUTHORITY
+net. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+; insecure subtree
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+org. IN A
+SECTION AUTHORITY
+org. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+net. IN NS
+SECTION ANSWER
+net. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+org. IN NS
+SECTION ANSWER
+org. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.net. IN A
+SECTION AUTHORITY
+example.net. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.net. IN A 1.2.3.5
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.org. IN A
+SECTION AUTHORITY
+example.org. IN NS ns.example.org.
+SECTION ADDITIONAL
+ns.example.org. IN A 1.2.3.6
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. 3600 IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20170313131924 20170213131924 11901 example.com. B4VToCUqVSDSaOG1sK+p+WC1Ece0tB+0UZTBfD+zgfbkHv+nI0ehsBEFlcubMiWZ9qZJ37824b44qapOOvfzuuhtkk/z5VPVljfWz4vj/t+fYQjWqfNN+oVp+ul7ULsDNNNWO6rPJmtmEjUq/7QrGb1iFereC5oaH2J5D13y5hCMPxtepQ7EjsGSHGhT0nAuWJwV5iNcUUm0kRIiBZqIGCVx16G5S3kxBebcoDA+yjMiA5xmFoxEf4I4Vk0Ut7rh4TOStEQdZAW6VCD4e65gWwNu2dTHpdqctA8ppjOA3nVamjPlVQ0z0Cqxm6UHj+su7CnS7lg2fjGYfP0ebUTSYg==
+SECTION ADDITIONAL
+ns.example.com. 3600 IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20170313131924 20170213131924 11901 example.com. LEvYqarAR/IXWSOknuV7DobkmjcvIIe1lFlJSucRp9v2GkdE384vMrSPmvRxItpEWgnnKlEZIYvMDcKT71muIlv7+0PmIPMtdBkB2rBL0s5dZxH//u9tWmgPAkG+BLJelr5iB63w8VhXJsiRiNGjCBc6t5MJHk7nTNK/8LLUZYDyi8YsiIxxy+emUwOW/LLfSECSBlz4QbyD1tQ0dErk48jAH56GwLJehmtMKbyF/negRLO9jOrzSOGiszw3VjyLfzkkfLJBNheSECGo3aN+/r/GPHr2CisgfROeR46PXs56ooGkO4x/PsplFTc+eZQioHuIPkv4sScyz2/2shxTLA==
+ENTRY_END
+
+; response to DNSKEY priming query
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN DNSKEY
+SECTION ANSWER
+example.com. 3600 IN DNSKEY 257 3 7 AwEAAb7hP8/oYI+DGLG/Khpe0roTWUdmAEMRAaUbiFAMrMf1AiSTBf5oNrVPMFvM/MmqoAZ6Ku2AhyAnb6pfCrG1TQq5uuFYrp4h2u6jUxFT3OPNHb+gDlKRSqDzOXBImCf1SDz7bx4xw+zS/rYOF2mPk8YWi+jI3HzIkqCjw++oIu+Zwzcmc9fRTruDMDhFGcVMvdD97CbD0QpBDvgh2vQikZvmD4wwzrvjJC7SmkNPTYA2RaJj2GSggnYMcgPBNHBJzLqfCbciU1jUBazsAafQbnXfy3jz5Eh/X6vKlAtejMhoCqd9iXE7EqYWI9F4ny/a/17z/aEYrWsJsVIlnJ10nlE= ;{id = 11901 (ksk), size = 2048b}
+example.com. 3600 IN RRSIG DNSKEY 7 2 3600 20170313131924 20170213131924 11901 example.com. V99TYdJIpoy6pJuFQx/VgK05YifhPcuuqdTzHM67ORzhpOpQj/2/aFWYPu7WoRhNOw895I41VIDuX0ljKXNUbAl+YF7+eRWDyrRsnWWhxWcTL0yWH71/b8U0IHFus++HKiYU+6pq148k0Pk4LmINWv7qDqOv+XVdfLqjRSWgZxEEXOaRgNp6m6UTJy9n9qvXejdxXBFLLsSRTHXBM3amyEl2LyXLyG4C8MNJPMMcwmBQASlj9AaUxewXQssacbagHy9CJtZcUjwco76dfyM/X2tgRfdXrVz1QCuA8D1o8FRtddnRugOSUqfF73dBVEoljWYNm6V2xR5uXnFyRZdyAQ==
+SECTION AUTHORITY
+example.com. 3600 IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20170313131924 20170213131924 11901 example.com. B4VToCUqVSDSaOG1sK+p+WC1Ece0tB+0UZTBfD+zgfbkHv+nI0ehsBEFlcubMiWZ9qZJ37824b44qapOOvfzuuhtkk/z5VPVljfWz4vj/t+fYQjWqfNN+oVp+ul7ULsDNNNWO6rPJmtmEjUq/7QrGb1iFereC5oaH2J5D13y5hCMPxtepQ7EjsGSHGhT0nAuWJwV5iNcUUm0kRIiBZqIGCVx16G5S3kxBebcoDA+yjMiA5xmFoxEf4I4Vk0Ut7rh4TOStEQdZAW6VCD4e65gWwNu2dTHpdqctA8ppjOA3nVamjPlVQ0z0Cqxm6UHj+su7CnS7lg2fjGYfP0ebUTSYg==
+SECTION ADDITIONAL
+ns.example.com. 3600 IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20170313131924 20170213131924 11901 example.com. LEvYqarAR/IXWSOknuV7DobkmjcvIIe1lFlJSucRp9v2GkdE384vMrSPmvRxItpEWgnnKlEZIYvMDcKT71muIlv7+0PmIPMtdBkB2rBL0s5dZxH//u9tWmgPAkG+BLJelr5iB63w8VhXJsiRiNGjCBc6t5MJHk7nTNK/8LLUZYDyi8YsiIxxy+emUwOW/LLfSECSBlz4QbyD1tQ0dErk48jAH56GwLJehmtMKbyF/negRLO9jOrzSOGiszw3VjyLfzkkfLJBNheSECGo3aN+/r/GPHr2CisgfROeR46PXs56ooGkO4x/PsplFTc+eZQioHuIPkv4sScyz2/2shxTLA==
+ENTRY_END
+
+; response to query of interest
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. 3600 IN CNAME www.example.net.
+www.example.com. 3600 IN RRSIG CNAME 7 3 3600 20170313131924 20170213131924 11901 example.com. TyWar/GZu4Vw5t4YTnxF8XRJAmHTWAA0snal0I6qH4pBxqmmYMHdFuGmiKwQNUpNlntOaAHj2UElkHa07eF+/Hb7mwf926bzGa13of2zS3rmwaqNi0nDns6PNWmzmpG65jKXqug5X7QrKIO00KeFWPM3T6LXp3TyZ9v1c5wtze1UGvK3OsSBs9aV9ovRcMjGA8ttPZbStM6VlblzdWfha+RY9Yt61OkAbS1ooQ2TRB1esGyd3EZgV0jTMtkbymitPog7XXEViIl5lp76clBOvUHCRhSO3XhU9ir840pQ+SOFTQBRK5OOhKOar2IX/n3smk+teqRbZ1zEa0cyrV/2Fg==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+insecure.example.com. IN A
+SECTION ANSWER
+insecure.example.com. 3600 IN CNAME insecure.example.net.
+insecure.example.com. 3600 IN RRSIG CNAME 7 3 3600 20170313140157 20170213140157 11901 example.com. PwYkM20oqzXrK+48AJgJUQP5MNbVjV9Xt9PG5ag2U7DrckQbVvuZ6dorouqUbVvLXhpbfInGazxgGGSE+hObhkhJcrRcmg2pKHWbRpBJqNnMeXk/w5zzlIOBq+Hu+ZpyUsbfJeax0S+gOyKLSeqRLDzOxWsSiFfPD2PSdfHcdslDxWLt92J8Yr2/wqh5aW7HOYDRZbvZkfP+0J4FWfWI6j25flbR7/Kt8SBAcqvg4cFREVua847iAItKGZGqa6XWnUX9JSskBl97RG0T3jBel+nz3MjMVSDl5HYaazv+VuUcF4NbjIcZHt8QxVOLw6IF/XxwPunqLPGByIYrBreUJQ==
+ENTRY_END
+
+RANGE_END
+
+; ns.example.net.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.5
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.net. IN NS
+SECTION ANSWER
+example.net. 3600 IN NS ns.example.net.
+example.net. 3600 IN RRSIG NS 7 2 3600 20170313131043 20170213131043 59835 example.net. XLDyXC3D0yyq3VOwjbHlI5QBl5pvmiGw 72k1nZIZbBSj6xJkGl0LXzRBO8gXbvYJ 2N1K2DwNQzR2ZPxoDzo60Mwe2gt7RjJt xMgLny0p6qWCvW1VYEyODvvnKrwcDvKm fbMPXmUaf2UuCj4OlaljJXDYACUG9+X2 yA+ipcop7rR+z4spnOfQIao1dzsH8itp yCRkV+X4jzDNaj9CN6nDfpCJsDDt4//5 V//3LQfAwmBBFOesnM3r68uCRqQySRzj UILvpWnu7T71FEHqIHSQmRUHAZRBsxGu IgWrEEHbcg5+eCvVe3X5lNMFAuU5ysXb mb2ENkyFPhfmytLLE/a96A==
+SECTION ADDITIONAL
+ns.example.net. 3600 IN A 1.2.3.5
+ns.example.net. 3600 IN RRSIG A 7 3 3600 20170313131043 20170213131043 59835 example.net. ewYu0740p/BWH2RRU+L7QXhj44AnFNaobCCSYxl3gEqLNQI3MSJffXle2JVsEpgMySHfDZQSBy5iAqOA7zQLUmtABWCjKb74nlngPWklneibxQiSGphf8OyVJTrYtcNvk458eBfyyMWQy7HYwDYtYBlGIqHzU7FUkONHteDGlb5aGtAbqib9LzsHExfJdRuy5l1NX+/cLqHeRDceSX4g7F2Xn+i4SLBTHa4HODiklB8ugjHuFHLVBJAm55aIDSmrSrDliL2QZ/aXtVhRh1lMaD+YdsaW7Gny9EGygnFGolmzmVxjeCQ1sfmAjd8VS+x979VLy9tT2GWQWv39dfBejA==
+ENTRY_END
+
+; response to DNSKEY priming query
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.net. IN DNSKEY
+SECTION ANSWER
+example.net. 3600 IN DNSKEY 257 3 7 AwEAAZiIoYj0BuA2FiduSeydlfGOpKfK38KvFB5jHASrr1YIXOB3ky1WMzedwL6sti6EtMDNBZTnqr+4+b01zuAGDDuQvsVrd5y07lrc+8Y1S61s4QVo2r5P1+I54AucFCX+ZeqGhKkEhhu74LHbmKn32d9MUGHbazZ2+l7hrROVEljmrL/2waHOVu1flHxN5TfIcA9+UghA/aoT9p/oT8EzJ/oEbX2GT7hfvOmmOVUfEIgBlIKwwqaYIxjjzex2bPzkm/SN3oU3gwVcJv6q3R5a+4AeLv5lrsNL1qc7Juth4miiiwJpv8COBSFgBEhSqAjkurx+cXzYClBz+yxJJSsRYFs= ;{id = 59835 (ksk), size = 2048b}
+example.net. 3600 IN RRSIG DNSKEY 7 2 3600 20170313131043 20170213131043 59835 example.net. aQLRerV6GBcQY6dm4bYr7cCr6rkdl+GYPyyfw09d20FW/JuqiljvqKMQtfzVXBrqYIB/DMdGkSJ87w19vlPzey8CtI8oXk1AFwHD/aFqS3cv/2oFS71cm/eGhmf87led51NrqW6dQPkQZ2xOZ4cDxtmkrLMJy3OWIwH8+1rpy4dOg/aHw4+K7qARWJtj3iS9GmiZW88LRdSvJR14reAlM4XYhivdGZcEe+UQNymz+NY7KG1DwWU2AQCBq/QID+f5Zpxbfw2fEH7X1aMzjEj/HGZ3BXcXahM0wGQzRXmXNcXYqzST/RhrJ1g34xsgMFLk/Kfj+cQCOW8aK7/Zt9vRIg==
+SECTION AUTHORITY
+example.net. 3600 IN NS ns.example.net.
+example.net. 3600 IN RRSIG NS 7 2 3600 20170313131043 20170213131043 59835 example.net. XLDyXC3D0yyq3VOwjbHlI5QBl5pvmiGw 72k1nZIZbBSj6xJkGl0LXzRBO8gXbvYJ 2N1K2DwNQzR2ZPxoDzo60Mwe2gt7RjJt xMgLny0p6qWCvW1VYEyODvvnKrwcDvKm fbMPXmUaf2UuCj4OlaljJXDYACUG9+X2 yA+ipcop7rR+z4spnOfQIao1dzsH8itp yCRkV+X4jzDNaj9CN6nDfpCJsDDt4//5 V//3LQfAwmBBFOesnM3r68uCRqQySRzj UILvpWnu7T71FEHqIHSQmRUHAZRBsxGu IgWrEEHbcg5+eCvVe3X5lNMFAuU5ysXb mb2ENkyFPhfmytLLE/a96A==
+SECTION ADDITIONAL
+ns.example.net. 3600 IN A 1.2.3.5
+ns.example.net. 3600 IN RRSIG A 7 3 3600 20170313131043 20170213131043 59835 example.net. ewYu0740p/BWH2RRU+L7QXhj44AnFNaobCCSYxl3gEqLNQI3MSJffXle2JVsEpgMySHfDZQSBy5iAqOA7zQLUmtABWCjKb74nlngPWklneibxQiSGphf8OyVJTrYtcNvk458eBfyyMWQy7HYwDYtYBlGIqHzU7FUkONHteDGlb5aGtAbqib9LzsHExfJdRuy5l1NX+/cLqHeRDceSX4g7F2Xn+i4SLBTHa4HODiklB8ugjHuFHLVBJAm55aIDSmrSrDliL2QZ/aXtVhRh1lMaD+YdsaW7Gny9EGygnFGolmzmVxjeCQ1sfmAjd8VS+x979VLy9tT2GWQWv39dfBejA==
+ENTRY_END
+
+; response to query of interest
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR DO NOERROR
+SECTION QUESTION
+www.example.net. IN A
+SECTION ANSWER
+www.example.net. 3600 IN A 10.0.0.1
+www.example.net. 3600 IN RRSIG A 7 3 3600 20170313131043 20170213131043 59835 example.net. F0OiqJtl9nOonZePqV+boFuj5i1zTyDdj5yxZ80J7BQOoB0wGvcx105mriIW3mAQPmgq2K/lK317IejuP+kKBr8oGr82apCyP7NihAHr/dnqe4cTJJjQU1cjLJcIJHY6jg99DR6HkCZFRjEA8TI761E2GBfvxK0yPKEW1m8N9G9Wl5KZOHq8pQ1ZNDm4MR0rt2lvsuVaf+iGiw4HJkaD7Kceq3y9ukilsuP6Zl0dWMIeTqcs7UT3OS16HV21A9VL3rJGRLUonmJo7mUq8hpxKnFYK6/96IfXCf/XX1YI6rK0DVp1OE0S8s+teLG4UsE2p2+dC2arVwhHUGzlZMvO/A==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR DO NOERROR
+SECTION QUESTION
+insecure.example.net. IN A
+SECTION ANSWER
+insecure.example.net. 3600 IN CNAME insecure.example.org.
+insecure.example.net. 3600 IN RRSIG CNAME 7 3 3600 20170313140150 20170213140150 59835 example.net. L1NmsrbewJeWS4ZC07jR9EWPg5QqKwH8BklJIWnMYlfR1xaLcMS5hHeDQN3OUK8D79mxmoBQVIXPMig3CLJPkewJoOZMKD/UwHVosFbG9NbRbWtY6tTZtQnzLy45+AsoQeF0tnoJM+5pvE3wMyXLBgZWbZDGRd0/Uk5/wxddu7NkxAZ0U3zarFxpVnQgP+MKifaplfHko599psQ58BnoSMUB1FjeFsy78zkXd3PjX/VWevGNlABGmlpvWdQou8c6V9ihGVRmsha6ABW04cLgevDjgorrn1AAI88c1H/pRDoWjO5zyQ9PPFPusCTYTEWcuSDpN43RFCxrA7ENP2g1rw==
+ENTRY_END
+
+RANGE_END
+
+
+; ns.example.org.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.6
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.org. IN NS
+SECTION ANSWER
+example.org. 3600 IN NS ns.example.org.
+SECTION ADDITIONAL
+ns.example.org. 3600 IN A 1.2.3.6
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.org. IN A
+SECTION ANSWER
+www.example.org. 3600 IN CNAME www.example.com.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname qtype
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+insecure.example.org. IN A
+SECTION ANSWER
+insecure.example.org. 3600 IN A 10.2.2.2
+ENTRY_END
+RANGE_END
+
+
+; CNAME from one trusted sub-tree to another trusted sub-tree
+STEP 10 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 11 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. 3600 IN CNAME www.example.net.
+www.example.com. 3600 IN RRSIG CNAME 7 3 3600 20170313131924 20170213131924 11901 example.com. TyWar/GZu4Vw5t4YTnxF8XRJAmHTWAA0snal0I6qH4pBxqmmYMHdFuGmiKwQNUpNlntOaAHj2UElkHa07eF+/Hb7mwf926bzGa13of2zS3rmwaqNi0nDns6PNWmzmpG65jKXqug5X7QrKIO00KeFWPM3T6LXp3TyZ9v1c5wtze1UGvK3OsSBs9aV9ovRcMjGA8ttPZbStM6VlblzdWfha+RY9Yt61OkAbS1ooQ2TRB1esGyd3EZgV0jTMtkbymitPog7XXEViIl5lp76clBOvUHCRhSO3XhU9ir840pQ+SOFTQBRK5OOhKOar2IX/n3smk+teqRbZ1zEa0cyrV/2Fg==
+www.example.net. 3600 IN A 10.0.0.1
+www.example.net. 3600 IN RRSIG A 7 3 3600 20170313131043 20170213131043 59835 example.net. F0OiqJtl9nOonZePqV+boFuj5i1zTyDdj5yxZ80J7BQOoB0wGvcx105mriIW3mAQPmgq2K/lK317IejuP+kKBr8oGr82apCyP7NihAHr/dnqe4cTJJjQU1cjLJcIJHY6jg99DR6HkCZFRjEA8TI761E2GBfvxK0yPKEW1m8N9G9Wl5KZOHq8pQ1ZNDm4MR0rt2lvsuVaf+iGiw4HJkaD7Kceq3y9ukilsuP6Zl0dWMIeTqcs7UT3OS16HV21A9VL3rJGRLUonmJo7mUq8hpxKnFYK6/96IfXCf/XX1YI6rK0DVp1OE0S8s+teLG4UsE2p2+dC2arVwhHUGzlZMvO/A==
+ENTRY_END
+
+; cache test
+STEP 12 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 13 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. 3600 IN CNAME www.example.net.
+www.example.com. 3600 IN RRSIG CNAME 7 3 3600 20170313131924 20170213131924 11901 example.com. TyWar/GZu4Vw5t4YTnxF8XRJAmHTWAA0snal0I6qH4pBxqmmYMHdFuGmiKwQNUpNlntOaAHj2UElkHa07eF+/Hb7mwf926bzGa13of2zS3rmwaqNi0nDns6PNWmzmpG65jKXqug5X7QrKIO00KeFWPM3T6LXp3TyZ9v1c5wtze1UGvK3OsSBs9aV9ovRcMjGA8ttPZbStM6VlblzdWfha+RY9Yt61OkAbS1ooQ2TRB1esGyd3EZgV0jTMtkbymitPog7XXEViIl5lp76clBOvUHCRhSO3XhU9ir840pQ+SOFTQBRK5OOhKOar2IX/n3smk+teqRbZ1zEa0cyrV/2Fg==
+www.example.net. 3600 IN A 10.0.0.1
+www.example.net. 3600 IN RRSIG A 7 3 3600 20170313131043 20170213131043 59835 example.net. F0OiqJtl9nOonZePqV+boFuj5i1zTyDdj5yxZ80J7BQOoB0wGvcx105mriIW3mAQPmgq2K/lK317IejuP+kKBr8oGr82apCyP7NihAHr/dnqe4cTJJjQU1cjLJcIJHY6jg99DR6HkCZFRjEA8TI761E2GBfvxK0yPKEW1m8N9G9Wl5KZOHq8pQ1ZNDm4MR0rt2lvsuVaf+iGiw4HJkaD7Kceq3y9ukilsuP6Zl0dWMIeTqcs7UT3OS16HV21A9VL3rJGRLUonmJo7mUq8hpxKnFYK6/96IfXCf/XX1YI6rK0DVp1OE0S8s+teLG4UsE2p2+dC2arVwhHUGzlZMvO/A==
+ENTRY_END
+
+
+; CNAME from untrusted to trusted sub-tree
+STEP 20 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.example.org. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 21 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA DO NOERROR
+SECTION QUESTION
+www.example.org. IN A
+SECTION ANSWER
+www.example.org. IN CNAME www.example.com.
+www.example.com. 3600 IN CNAME www.example.net.
+www.example.com. 3600 IN RRSIG CNAME 7 3 3600 20170313131924 20170213131924 11901 example.com. TyWar/GZu4Vw5t4YTnxF8XRJAmHTWAA0snal0I6qH4pBxqmmYMHdFuGmiKwQNUpNlntOaAHj2UElkHa07eF+/Hb7mwf926bzGa13of2zS3rmwaqNi0nDns6PNWmzmpG65jKXqug5X7QrKIO00KeFWPM3T6LXp3TyZ9v1c5wtze1UGvK3OsSBs9aV9ovRcMjGA8ttPZbStM6VlblzdWfha+RY9Yt61OkAbS1ooQ2TRB1esGyd3EZgV0jTMtkbymitPog7XXEViIl5lp76clBOvUHCRhSO3XhU9ir840pQ+SOFTQBRK5OOhKOar2IX/n3smk+teqRbZ1zEa0cyrV/2Fg==
+www.example.net. 3600 IN A 10.0.0.1
+www.example.net. 3600 IN RRSIG A 7 3 3600 20170313131043 20170213131043 59835 example.net. F0OiqJtl9nOonZePqV+boFuj5i1zTyDdj5yxZ80J7BQOoB0wGvcx105mriIW3mAQPmgq2K/lK317IejuP+kKBr8oGr82apCyP7NihAHr/dnqe4cTJJjQU1cjLJcIJHY6jg99DR6HkCZFRjEA8TI761E2GBfvxK0yPKEW1m8N9G9Wl5KZOHq8pQ1ZNDm4MR0rt2lvsuVaf+iGiw4HJkaD7Kceq3y9ukilsuP6Zl0dWMIeTqcs7UT3OS16HV21A9VL3rJGRLUonmJo7mUq8hpxKnFYK6/96IfXCf/XX1YI6rK0DVp1OE0S8s+teLG4UsE2p2+dC2arVwhHUGzlZMvO/A==
+ENTRY_END
+
+; cache test
+STEP 22 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.example.org. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 23 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA DO NOERROR
+SECTION QUESTION
+www.example.org. IN A
+SECTION ANSWER
+www.example.org. IN CNAME www.example.com.
+www.example.com. 3600 IN CNAME www.example.net.
+www.example.com. 3600 IN RRSIG CNAME 7 3 3600 20170313131924 20170213131924 11901 example.com. TyWar/GZu4Vw5t4YTnxF8XRJAmHTWAA0snal0I6qH4pBxqmmYMHdFuGmiKwQNUpNlntOaAHj2UElkHa07eF+/Hb7mwf926bzGa13of2zS3rmwaqNi0nDns6PNWmzmpG65jKXqug5X7QrKIO00KeFWPM3T6LXp3TyZ9v1c5wtze1UGvK3OsSBs9aV9ovRcMjGA8ttPZbStM6VlblzdWfha+RY9Yt61OkAbS1ooQ2TRB1esGyd3EZgV0jTMtkbymitPog7XXEViIl5lp76clBOvUHCRhSO3XhU9ir840pQ+SOFTQBRK5OOhKOar2IX/n3smk+teqRbZ1zEa0cyrV/2Fg==
+www.example.net. 3600 IN A 10.0.0.1
+www.example.net. 3600 IN RRSIG A 7 3 3600 20170313131043 20170213131043 59835 example.net. F0OiqJtl9nOonZePqV+boFuj5i1zTyDdj5yxZ80J7BQOoB0wGvcx105mriIW3mAQPmgq2K/lK317IejuP+kKBr8oGr82apCyP7NihAHr/dnqe4cTJJjQU1cjLJcIJHY6jg99DR6HkCZFRjEA8TI761E2GBfvxK0yPKEW1m8N9G9Wl5KZOHq8pQ1ZNDm4MR0rt2lvsuVaf+iGiw4HJkaD7Kceq3y9ukilsuP6Zl0dWMIeTqcs7UT3OS16HV21A9VL3rJGRLUonmJo7mUq8hpxKnFYK6/96IfXCf/XX1YI6rK0DVp1OE0S8s+teLG4UsE2p2+dC2arVwhHUGzlZMvO/A==
+ENTRY_END
+
+
+; CNAME from trusted to untrusted sub-tree
+STEP 30 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+insecure.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 31 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA DO NOERROR
+SECTION QUESTION
+insecure.example.com. IN A
+SECTION ANSWER
+insecure.example.com. 3600 IN CNAME insecure.example.net.
+insecure.example.com. 3600 IN RRSIG CNAME 7 3 3600 20170313140157 20170213140157 11901 example.com. PwYkM20oqzXrK+48AJgJUQP5MNbVjV9Xt9PG5ag2U7DrckQbVvuZ6dorouqUbVvLXhpbfInGazxgGGSE+hObhkhJcrRcmg2pKHWbRpBJqNnMeXk/w5zzlIOBq+Hu+ZpyUsbfJeax0S+gOyKLSeqRLDzOxWsSiFfPD2PSdfHcdslDxWLt92J8Yr2/wqh5aW7HOYDRZbvZkfP+0J4FWfWI6j25flbR7/Kt8SBAcqvg4cFREVua847iAItKGZGqa6XWnUX9JSskBl97RG0T3jBel+nz3MjMVSDl5HYaazv+VuUcF4NbjIcZHt8QxVOLw6IF/XxwPunqLPGByIYrBreUJQ==
+insecure.example.net. 3600 IN CNAME insecure.example.org.
+insecure.example.net. 3600 IN RRSIG CNAME 7 3 3600 20170313140150 20170213140150 59835 example.net. L1NmsrbewJeWS4ZC07jR9EWPg5QqKwH8BklJIWnMYlfR1xaLcMS5hHeDQN3OUK8D79mxmoBQVIXPMig3CLJPkewJoOZMKD/UwHVosFbG9NbRbWtY6tTZtQnzLy45+AsoQeF0tnoJM+5pvE3wMyXLBgZWbZDGRd0/Uk5/wxddu7NkxAZ0U3zarFxpVnQgP+MKifaplfHko599psQ58BnoSMUB1FjeFsy78zkXd3PjX/VWevGNlABGmlpvWdQou8c6V9ihGVRmsha6ABW04cLgevDjgorrn1AAI88c1H/pRDoWjO5zyQ9PPFPusCTYTEWcuSDpN43RFCxrA7ENP2g1rw==
+insecure.example.org. 3600 IN A 10.2.2.2
+ENTRY_END
+
+; cache test
+STEP 32 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+insecure.example.com. IN A
+ENTRY_END
+
+STEP 33 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA DO NOERROR
+SECTION QUESTION
+insecure.example.com. IN A
+SECTION ANSWER
+insecure.example.com. 3600 IN CNAME insecure.example.net.
+insecure.example.com. 3600 IN RRSIG CNAME 7 3 3600 20170313140157 20170213140157 11901 example.com. PwYkM20oqzXrK+48AJgJUQP5MNbVjV9Xt9PG5ag2U7DrckQbVvuZ6dorouqUbVvLXhpbfInGazxgGGSE+hObhkhJcrRcmg2pKHWbRpBJqNnMeXk/w5zzlIOBq+Hu+ZpyUsbfJeax0S+gOyKLSeqRLDzOxWsSiFfPD2PSdfHcdslDxWLt92J8Yr2/wqh5aW7HOYDRZbvZkfP+0J4FWfWI6j25flbR7/Kt8SBAcqvg4cFREVua847iAItKGZGqa6XWnUX9JSskBl97RG0T3jBel+nz3MjMVSDl5HYaazv+VuUcF4NbjIcZHt8QxVOLw6IF/XxwPunqLPGByIYrBreUJQ==
+insecure.example.net. 3600 IN CNAME insecure.example.org.
+insecure.example.net. 3600 IN RRSIG CNAME 7 3 3600 20170313140150 20170213140150 59835 example.net. L1NmsrbewJeWS4ZC07jR9EWPg5QqKwH8BklJIWnMYlfR1xaLcMS5hHeDQN3OUK8D79mxmoBQVIXPMig3CLJPkewJoOZMKD/UwHVosFbG9NbRbWtY6tTZtQnzLy45+AsoQeF0tnoJM+5pvE3wMyXLBgZWbZDGRd0/Uk5/wxddu7NkxAZ0U3zarFxpVnQgP+MKifaplfHko599psQ58BnoSMUB1FjeFsy78zkXd3PjX/VWevGNlABGmlpvWdQou8c6V9ihGVRmsha6ABW04cLgevDjgorrn1AAI88c1H/pRDoWjO5zyQ9PPFPusCTYTEWcuSDpN43RFCxrA7ENP2g1rw==
+insecure.example.org. 3600 IN A 10.2.2.2
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/val_cnamenx_dblnsec.rpl b/tests/integration/deckard/sets/resolver/val_cnamenx_dblnsec.rpl
new file mode 100644
index 0000000..eadb47b
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_cnamenx_dblnsec.rpl
@@ -0,0 +1,180 @@
+do-ip6: no
+
+; config options
+; The island of trust is at example.com
+;server:
+ trust-anchor: "example.com. 3600 IN DS 21485 7 1 D0AED7DEAE346B008881F31F9ABBB055DF94CBD5 "
+val-override-date: "20181130121821"
+; target-fetch-policy: "0 0 0 0 0"
+; fake-sha1: yes
+
+;stub-zone:
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+query-minimization: off
+CONFIG_END
+
+SCENARIO_BEGIN Test validator with cname-nxdomain for duplicate NSEC detection
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+cname.example.com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+cname.example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20181230101821 20181130101821 21485 example.com. cdC5PUdx8wOzA3Ffx0jI2KrGMpU0VmxM/Y7RpFM0JgCMO3aeYsGbtcpR pvS6i9sSFUTA3XNp0tiGqpS1iH07CJy67U0g1qKh/peHn07TWCrR9Kqy 0OXGlNfZQL4BG5i7hq0VXvUeBvyquMeTd0c6n/yni8DDFx0l95lvu5nr k5w= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101821 20181130101821 21485 example.com. soIpMtGzUOKCj5F6RjqQxrrhSJwhWLv9plOIEfGyI9OLgTYaTYgqC1R9 /4IIVPjzk4mB5VJSLcLNN2/QP8Qa/gO/dIb5o6nnHKdfDS4IPpG6ikeM T9cS2EMJ0+5rI5nLTCIofvGmsYTtjMuT3ysJ8xM4/9p1A7yjd49Mrkeb JWo= ;{id = 2854}
+ENTRY_END
+
+; response to DNSKEY priming query
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN DNSKEY
+SECTION ANSWER
+example.com. 3600 IN DNSKEY 256 3 7 AwEAAdHIjtVPYHtA3eUV5xOLpXVDAxdm16vsbjbfA4zFA9h2i1snUhCo fZV3hnOzn6WGpJkn/K2FBioTbwqhtQgEKnAg4+wxr+FnE/D89hdTF3CJ av/DRtw5pOu7PK5LbVZWWE2ztmok57RoMr31ecQGJ3S/B2rCZDaEDbYg EK+MoKHZ ;{id = 2854 (zsk), size = 1688b}
+example.com. 3600 IN RRSIG DNSKEY 7 2 3600 20181230101821 20181130101821 21485 example.com. gHeTNDlfGHqlxNke2s0TIm4x6fFdV64FgkCyc9CVf+eR5gMqpnhkRBk5 DdDK1Gi5MO3XnbzRcUrC2Y+7i20M+nTA+KD9ZlQsXWszevLYJY3TJmnQ cz9d5hQJexrAx1+G0C78vDO6vWZNJz3J0LzvDQcmH23R3j9ow2wM1W7x f4k= ;{id = 2854}
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20181230101821 20181130101821 21485 example.com. cdC5PUdx8wOzA3Ffx0jI2KrGMpU0VmxM/Y7RpFM0JgCMO3aeYsGbtcpR pvS6i9sSFUTA3XNp0tiGqpS1iH07CJy67U0g1qKh/peHn07TWCrR9Kqy 0OXGlNfZQL4BG5i7hq0VXvUeBvyquMeTd0c6n/yni8DDFx0l95lvu5nr k5w= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101821 20181130101821 21485 example.com. soIpMtGzUOKCj5F6RjqQxrrhSJwhWLv9plOIEfGyI9OLgTYaTYgqC1R9 /4IIVPjzk4mB5VJSLcLNN2/QP8Qa/gO/dIb5o6nnHKdfDS4IPpG6ikeM T9cS2EMJ0+5rI5nLTCIofvGmsYTtjMuT3ysJ8xM4/9p1A7yjd49Mrkeb JWo= ;{id = 2854}
+ENTRY_END
+
+; response to query of interest
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NXDOMAIN
+SECTION QUESTION
+cname.example.com. IN A
+SECTION ANSWER
+cname.example.com. 3600 IN CNAME www.example.com.
+cname.example.com. 3600 IN RRSIG CNAME 7 3 3600 20181230101821 20181130101821 21485 example.com. KSB4An66g0tVndlXTHPjpRzQmsM6TMvV54THQJmiPqiI9UNTQwIwgEPI zSG5lUZwqORK7h4fTStwAosDl+dKFtPWoiW3yV0XytaJqJBfB5eOr6/X 665Qp876He3ZhVBYfekFVZnO+amzv8oycjngPsSHxpMZ760HNFRSgacy bDc= ;{id = 2854}
+SECTION AUTHORITY
+; already includes the necessary NSECs
+example.com. IN SOA ns.example.com. hostmaster.example.com. 2007090400 28800 7200 604800 18000
+example.com. 3600 IN RRSIG SOA 7 2 3600 20181230101821 20181130101821 21485 example.com. kvapB5PKSev/ZKLrVqexb3HPFftCrdE7a5fYzzAlSmW85Wzj4b7Pi3pU Jyh6W+9Wo7iTkT9NdBy93RgApoW38CHVh4/FiGJlbIs+cJFgpMfG1kdu Q2j3xn5P4TUlRX9PNtkjDdy13FqpiSMPHNU1ZdLq5oQ/wL2vNSsJ83zq ZZw= ;{id = 2854}
+; wildcard denial
+example.com. IN NSEC abc.example.com. SOA NS DNSKEY NSEC RRSIG
+example.com. 3600 IN RRSIG NSEC 7 2 18000 20181230101821 20181130101821 21485 example.com. W4RWRKbmCTSKQZuIaDybI+dEwB+wKs24C9f5h01XRuhj9OKTEeomaHCN 4AsK+DdsU7Z6QBYedn+rbYjaCjbTQqztc7Qi8fAF/dw9wRG+WMdATnqD 0uJGRsQLzJmzjttKp64Njtgl4eiNuhOwYzsZpDANKwMv1Rlg7P7HVsZU T+g= ;{id = 2854}
+; qname denial
+wab.example.com. IN NSEC wzz.example.com. A NSEC RRSIG
+wab.example.com. 3600 IN RRSIG NSEC 7 3 18000 20181230101821 20181130101821 21485 example.com. WFil25/HtvZtJ3QUa9toox+C+qcJOKJwcZ2ylTOlSJzJrJB99oTKN1ZW XLDIRHPX81TTEp0edigErhyLO+xna1+L96Ze4tN9nP/0+N7gzY3bhzmg sms/ojtjuqKSf0ac1ZAUU3aGSdA/rgBYfeTh/2wMaLcQC1BUBZFsztAs sUg= ;{id = 2854}
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NXDOMAIN
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+SECTION AUTHORITY
+example.com. IN SOA ns.example.com. hostmaster.example.com. 2007090400 28800 7200 604800 18000
+example.com. 3600 IN RRSIG SOA 7 2 3600 20181230101821 20181130101821 21485 example.com. kvapB5PKSev/ZKLrVqexb3HPFftCrdE7a5fYzzAlSmW85Wzj4b7Pi3pU Jyh6W+9Wo7iTkT9NdBy93RgApoW38CHVh4/FiGJlbIs+cJFgpMfG1kdu Q2j3xn5P4TUlRX9PNtkjDdy13FqpiSMPHNU1ZdLq5oQ/wL2vNSsJ83zq ZZw= ;{id = 2854}
+; wildcard denial
+example.com. IN NSEC abc.example.com. SOA NS DNSKEY NSEC RRSIG
+example.com. 3600 IN RRSIG NSEC 7 2 18000 20181230101821 20181130101821 21485 example.com. W4RWRKbmCTSKQZuIaDybI+dEwB+wKs24C9f5h01XRuhj9OKTEeomaHCN 4AsK+DdsU7Z6QBYedn+rbYjaCjbTQqztc7Qi8fAF/dw9wRG+WMdATnqD 0uJGRsQLzJmzjttKp64Njtgl4eiNuhOwYzsZpDANKwMv1Rlg7P7HVsZU T+g= ;{id = 2854}
+; qname denial
+wab.example.com. IN NSEC wzz.example.com. A NSEC RRSIG
+wab.example.com. 3600 IN RRSIG NSEC 7 3 18000 20181230101821 20181130101821 21485 example.com. WFil25/HtvZtJ3QUa9toox+C+qcJOKJwcZ2ylTOlSJzJrJB99oTKN1ZW XLDIRHPX81TTEp0edigErhyLO+xna1+L96Ze4tN9nP/0+N7gzY3bhzmg sms/ojtjuqKSf0ac1ZAUU3aGSdA/rgBYfeTh/2wMaLcQC1BUBZFsztAs sUg= ;{id = 2854}
+SECTION ADDITIONAL
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+cname.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA AD DO NXDOMAIN
+SECTION QUESTION
+cname.example.com. IN A
+SECTION ANSWER
+cname.example.com. 3600 IN CNAME www.example.com.
+cname.example.com. 3600 IN RRSIG CNAME 7 3 3600 20181230101821 20181130101821 21485 example.com. KSB4An66g0tVndlXTHPjpRzQmsM6TMvV54THQJmiPqiI9UNTQwIwgEPI zSG5lUZwqORK7h4fTStwAosDl+dKFtPWoiW3yV0XytaJqJBfB5eOr6/X 665Qp876He3ZhVBYfekFVZnO+amzv8oycjngPsSHxpMZ760HNFRSgacy bDc= ;{id = 2854}
+SECTION AUTHORITY
+example.com. IN SOA ns.example.com. hostmaster.example.com. 2007090400 28800 7200 604800 18000
+example.com. 3600 IN RRSIG SOA 7 2 3600 20181230101821 20181130101821 21485 example.com. kvapB5PKSev/ZKLrVqexb3HPFftCrdE7a5fYzzAlSmW85Wzj4b7Pi3pU Jyh6W+9Wo7iTkT9NdBy93RgApoW38CHVh4/FiGJlbIs+cJFgpMfG1kdu Q2j3xn5P4TUlRX9PNtkjDdy13FqpiSMPHNU1ZdLq5oQ/wL2vNSsJ83zq ZZw= ;{id = 2854}
+example.com. IN NSEC abc.example.com. SOA NS DNSKEY NSEC RRSIG
+example.com. 3600 IN RRSIG NSEC 7 2 18000 20181230101821 20181130101821 21485 example.com. W4RWRKbmCTSKQZuIaDybI+dEwB+wKs24C9f5h01XRuhj9OKTEeomaHCN 4AsK+DdsU7Z6QBYedn+rbYjaCjbTQqztc7Qi8fAF/dw9wRG+WMdATnqD 0uJGRsQLzJmzjttKp64Njtgl4eiNuhOwYzsZpDANKwMv1Rlg7P7HVsZU T+g= ;{id = 2854}
+wab.example.com. IN NSEC wzz.example.com. A NSEC RRSIG
+wab.example.com. 3600 IN RRSIG NSEC 7 3 18000 20181230101821 20181130101821 21485 example.com. WFil25/HtvZtJ3QUa9toox+C+qcJOKJwcZ2ylTOlSJzJrJB99oTKN1ZW XLDIRHPX81TTEp0edigErhyLO+xna1+L96Ze4tN9nP/0+N7gzY3bhzmg sms/ojtjuqKSf0ac1ZAUU3aGSdA/rgBYfeTh/2wMaLcQC1BUBZFsztAs sUg= ;{id = 2854}
+SECTION ADDITIONAL
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/val_cnameqtype.rpl b/tests/integration/deckard/sets/resolver/val_cnameqtype.rpl
new file mode 100644
index 0000000..678932d
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_cnameqtype.rpl
@@ -0,0 +1,232 @@
+do-ip6: no
+
+; config options
+; The island of trust is at example.com
+;server:
+ trust-anchor: "example.com. 3600 IN DS 6497 7 1 E91FB78CB1A0ADB57A05FC8B495EA748B24375AB "
+ trust-anchor: "example.net. 3600 IN DNSKEY 256 3 5 AwEAAcpXb9Fxep3BvyNndHR3k28yz1zSqgGntKz60tQf8t2jm2l1F3LO 7Oc3FdllY/FS8VACyIZTbU4WiEfoOToHF6KX5mj8n82wJKkZLKx0w52x jrUbASX0sm2rEwwcjAsDkXSIGUkSm5b7SY5KvXpuwTYl7Ql1gxdTgqou vnSCK+99 ;{id = 30899 (zsk), size = 512b}"
+val-override-date: "20181130121824"
+; target-fetch-policy: "0 0 0 0 0"
+; fake-sha1: yes
+
+;stub-zone:
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+query-minimization: off
+CONFIG_END
+
+SCENARIO_BEGIN Test validator with a query for type cname
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN CNAME
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.net. IN CNAME
+SECTION AUTHORITY
+net. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+net. IN NS
+SECTION ANSWER
+net. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN CNAME
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.net. IN A
+SECTION AUTHORITY
+example.net. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.net. IN A 1.2.3.5
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20181230101823 20181130101823 6497 example.com. ky4ZB/3l28EQx3cFbU4lWHNp5GI+Ca9S9z+M6kr9UqOkPk+bJN4VilR0 ng8u9D36mLzYJtWktdnrexcIGyba+c5dVul1yJYBQNxca1+Gdv0ObVb5 hhIAZ9psrKJglkAMTnsrokHgdDryfzII8mlZNWJCQHGPnIJLf583nYxe pks= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101823 20181130101823 6497 example.com. kj86vWDY5SK8oz/F3sbJjU1sVfdRjD90zUGS7xB0TI31UVel6Ww7PB36 nyHddUcTQ3SEJOETsnub6x8ZtOhxd2kRgkORhz84EeN+1bnOQLpnpTXQ wY7yOXIgf1sY1JzWTIhxXUnDftvpn05Y/C3Srfou1uFnv/5V29P1Q0Or GN0= ;{id = 2854}
+ENTRY_END
+
+; response to DNSKEY priming query
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN DNSKEY
+SECTION ANSWER
+example.com. 3600 IN DNSKEY 256 3 7 AwEAAbosaUoM51nu1Bfb1SBXWBd5RLicFoYgKEoqBVkd0gpyTQV2hwLx wIhKx5m5hYBmy9MU8zT2vTaYsafTNhYABl4gzMjLV4h2gx6P3o0OCcBq Fl6xuYEzbdrbavedO3wSzGNk8tBhmtQW8hbBsbEkFBgZaM06Y4T5D89a Wroa46nh ;{id = 2854 (zsk), size = 1688b}
+example.com. 3600 IN RRSIG DNSKEY 7 2 3600 20181230101823 20181130101823 6497 example.com. Iompwlf1+hL5mUrLLUTki8/zwt8CDLsLjAMyZfx4ojiTTR9y1uIDuJm+ qgSkS69OOVjaEw9ZaBRTZh7Km4xjLauZsRdBf6jFJeDttkDsASQDHG4T ooMAF/pNYjBK5+4YSJexbfr9KY1ICrBslJUKMFgVOdu5ICLZdon5kOBc wVo= ;{id = 2854}
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20181230101823 20181130101823 6497 example.com. ky4ZB/3l28EQx3cFbU4lWHNp5GI+Ca9S9z+M6kr9UqOkPk+bJN4VilR0 ng8u9D36mLzYJtWktdnrexcIGyba+c5dVul1yJYBQNxca1+Gdv0ObVb5 hhIAZ9psrKJglkAMTnsrokHgdDryfzII8mlZNWJCQHGPnIJLf583nYxe pks= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101823 20181130101823 6497 example.com. kj86vWDY5SK8oz/F3sbJjU1sVfdRjD90zUGS7xB0TI31UVel6Ww7PB36 nyHddUcTQ3SEJOETsnub6x8ZtOhxd2kRgkORhz84EeN+1bnOQLpnpTXQ wY7yOXIgf1sY1JzWTIhxXUnDftvpn05Y/C3Srfou1uFnv/5V29P1Q0Or GN0= ;{id = 2854}
+ENTRY_END
+
+; response to query of interest
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN CNAME
+SECTION ANSWER
+www.example.com. IN CNAME www.example.net.
+www.example.com. 3600 IN RRSIG CNAME 7 3 3600 20181230101823 20181130101823 6497 example.com. QFHRboEy5RNC87lRlKaXgWDJFzQXl3GKED1G4xvCRl3BfSK3toI9ADRE ykjnW1XgmQ5YJrP9aQBHDognOrvJ6sMYArRsbH1HSWjyeYgWibhkZvwl JNzCdNhptCjTJw7fP7sc1XMqMO5REBzFmW7lWIgrzwRJhCLLQ1g7D+46 38U= ;{id = 2854}
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+RANGE_END
+
+; ns.example.net.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.5
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.net. IN NS
+SECTION ANSWER
+example.net. IN NS ns.example.net.
+example.net. 3600 IN RRSIG NS 5 2 3600 20181230101823 20181130101823 31500 example.net. akNwK5ythyddy+MMl0/n3DPfIVGM31xj3TCE3xr9N6l0Ue9puoc2ad5U QwNUp0F+7DJABPnx8DKBsctPJSR4dSJ02s7IVAueLWjzUiBTE+NEioEC pfmzBaNqjt0JrdtZgwz5oCxfqovfnHC7sQTtnArlpMcmnTghuHKeWRaj yYQ= ;{id = 30899}
+SECTION ADDITIONAL
+ns.example.net. IN A 1.2.3.5
+ns.example.net. 3600 IN RRSIG A 5 3 3600 20181230101823 20181130101823 31500 example.net. gDeBSHmtmO4x9o4X7A9YLCAprLak7E79QR//ajPY+Ih2OAx1EKVK8ftJ 2ihAdt4IR80akLJizbGf/iCTRaSkUwYwCZB/nwRaxO0Z9cH1h3HENFSt WmM4GybIHk8Q6uC3Jowirenjfhm4EnR813FMLmrwYcxs5YbyN3kl7tqu PrY= ;{id = 30899}
+ENTRY_END
+
+; response to DNSKEY priming query
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.net. IN DNSKEY
+SECTION ANSWER
+example.net. 3600 IN DNSKEY 256 3 5 AwEAAcpXb9Fxep3BvyNndHR3k28yz1zSqgGntKz60tQf8t2jm2l1F3LO 7Oc3FdllY/FS8VACyIZTbU4WiEfoOToHF6KX5mj8n82wJKkZLKx0w52x jrUbASX0sm2rEwwcjAsDkXSIGUkSm5b7SY5KvXpuwTYl7Ql1gxdTgqou vnSCK+99 ;{id = 30899 (zsk), size = 512b}
+example.net. 3600 IN RRSIG DNSKEY 5 2 3600 20181230101823 20181130101823 31500 example.net. p3olaCEfXPEmJR5JS9DrYRbzIrPWAE5VBVPRHCKZ1geQNjCgSTr956oI p64LHodGZRc5dUWA79DYdK1xNtUZIJVpw5CudQGn/c11QJRSdT57A7yZ G7ikneZrkJHMn5+fbJLPeLhxTOKjKRXAHiohG7jEH+2q70KfZCobQ0GX +e4= ;{id = 30899}
+SECTION AUTHORITY
+example.net. IN NS ns.example.net.
+example.net. 3600 IN RRSIG NS 5 2 3600 20181230101823 20181130101823 31500 example.net. akNwK5ythyddy+MMl0/n3DPfIVGM31xj3TCE3xr9N6l0Ue9puoc2ad5U QwNUp0F+7DJABPnx8DKBsctPJSR4dSJ02s7IVAueLWjzUiBTE+NEioEC pfmzBaNqjt0JrdtZgwz5oCxfqovfnHC7sQTtnArlpMcmnTghuHKeWRaj yYQ= ;{id = 30899}
+SECTION ADDITIONAL
+ns.example.net. IN A 1.2.3.5
+ns.example.net. 3600 IN RRSIG A 5 3 3600 20181230101823 20181130101823 31500 example.net. gDeBSHmtmO4x9o4X7A9YLCAprLak7E79QR//ajPY+Ih2OAx1EKVK8ftJ 2ihAdt4IR80akLJizbGf/iCTRaSkUwYwCZB/nwRaxO0Z9cH1h3HENFSt WmM4GybIHk8Q6uC3Jowirenjfhm4EnR813FMLmrwYcxs5YbyN3kl7tqu PrY= ;{id = 30899}
+ENTRY_END
+
+; response to query of interest
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.net. IN A
+SECTION ANSWER
+www.example.net. IN A 11.12.13.14
+www.example.net. 3600 IN RRSIG A 5 3 3600 20181230101823 20181130101823 31500 example.net. J+nuJ0xEW3wgDh0lO6sVMfcY1NGvM9gtd3dV+nc2wBKmnGfeJfGDDcVq SibPV3NXo1N9vj3Cp8v0oT2e/vGzc20VpeWi7e24tchRL4DLnP8YvFjE P4pEoCv4J0pikYz3L2AdH0PYtpJR1KsweZbeDC3XgpPi/uqcGOLzs4gK JIE= ;{id = 30899}
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.example.com. IN CNAME
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+www.example.com. IN CNAME
+SECTION ANSWER
+www.example.com. IN CNAME www.example.net.
+www.example.com. 3600 IN RRSIG CNAME 7 3 3600 20181230101823 20181130101823 6497 example.com. QFHRboEy5RNC87lRlKaXgWDJFzQXl3GKED1G4xvCRl3BfSK3toI9ADRE ykjnW1XgmQ5YJrP9aQBHDognOrvJ6sMYArRsbH1HSWjyeYgWibhkZvwl JNzCdNhptCjTJw7fP7sc1XMqMO5REBzFmW7lWIgrzwRJhCLLQ1g7D+46 38U= ;{id = 2854}
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/val_deleg_nons.rpl b/tests/integration/deckard/sets/resolver/val_deleg_nons.rpl
new file mode 100644
index 0000000..e9b296a
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_deleg_nons.rpl
@@ -0,0 +1,273 @@
+do-ip6: no
+
+; config options
+; The island of trust is at example.com
+;server:
+ trust-anchor: "example.com. 3600 IN DS 2854 3 1 46e4ffc6e9a4793b488954bd3f0cc6af0dfb201b"
+ val-override-date: "20070916134226"
+; target-fetch-policy: "0 0 0 0 0"
+; fake-sha1: yes
+
+;stub-zone:
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+;test from testbound
+
+SCENARIO_BEGIN Test validator with unsigned delegation with no NS bit in NSEC
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns.example.com. IN AAAA
+SECTION ANSWER
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.com. IN AAAA
+SECTION ANSWER
+SECTION AUTHORITY
+example.com. IN SOA alfa.ns.example.com.cz. hostmaster.example.com. 2010030800 10800 86400 604800 86400
+example.com. 3600 IN RRSIG SOA 3 2 3600 20070926134150 20070829134150 2854 example.com. ADsxLOHjxFzwFmwIiGOubqD9nKWAp4RccRIXQ0+EAUGfSDZMCB0ZiFA= ;{id = 2854}
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns3.example.com. IN AAAA
+SECTION ANSWER
+SECTION AUTHORITY
+example.com. IN SOA alfa.ns.example.com.cz. hostmaster.example.com. 2010030800 10800 86400 604800 86400
+example.com. 3600 IN RRSIG SOA 3 2 3600 20070926134150 20070829134150 2854 example.com. ADsxLOHjxFzwFmwIiGOubqD9nKWAp4RccRIXQ0+EAUGfSDZMCB0ZiFA= ;{id = 2854}
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.com. IN A
+SECTION ANSWER
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854}
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854}
+ENTRY_END
+
+; response to DNSKEY priming query
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN DNSKEY
+SECTION ANSWER
+example.com. 3600 IN DNSKEY 256 3 3 ALXLUsWqUrY3JYER3T4TBJII s70j+sDS/UT2QRp61SE7S3E EXopNXoFE73JLRmvpi/UrOO/Vz4Se 6wXv/CYCKjGw06U4WRgR YXcpEhJROyNapmdIKSx hOzfLVE1gqA0PweZR8d tY3aNQSRn3sPpwJr6Mi /PqQKAMMrZ9ckJpf1+b QMOOvxgzz2U1GS18b3y ZKcgTMEaJzd/GZYzi/B N2DzQ0MsrSwYXfsNLFO Bbs8PJMW4LYIxeeOe6rUgkWOF 7CC9Dh/dduQ1QrsJhmZAEFfd6ByYV+ ;{id = 2854 (zsk), size = 1688b}
+example.com. 3600 IN RRSIG DNSKEY 3 2 3600 20070926134802 20070829134802 2854 example.com. MCwCFG1yhRNtTEa3Eno2zhVVuy2EJX3wAhQeLyUp6+UXcpC5qGNu9tkrTEgPUg== ;{id = 2854}
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854}
+ENTRY_END
+
+; response to query of interest
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+foo.www.example.com. IN A
+SECTION ANSWER
+foo.www.example.com. IN A 1.2.3.4
+; unsigned, no delegation.
+ENTRY_END
+
+; DS query
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www.example.com. IN DS
+SECTION ANSWER
+SECTION AUTHORITY
+; NSEC3 here: 1 0 1 1234
+; www.example.com. -> h8c0nvkuibedn7ia997iegdl7h0i6h8b.
+h8c0nvkuibedn7ia997iegdl7h0i6h8b.example.com. IN NSEC3 1 0 1 1234 h8c0nvkuibedn7ia997iegdl7h0i6h8c TXT
+h8c0nvkuibedn7ia997iegdl7h0i6h8b.example.com. 3600 IN RRSIG NSEC3 3 3 3600 20070926134150 20070829134150 2854 example.com. AH+bPQZST3COwJ1vSe05N7E5BM2GmXzJUKsiWwXKrmm/XjYKSxSuNPE=
+
+;www.example.com. IN NSEC zzz.example.com. RRSIG NSEC
+;www.example.com. 3600 IN RRSIG NSEC 3 3 3600 20070926134150 20070829134150 2854 example.com. AA9Dm626WvHXHPQXJkVyjyTqJ/dCHfZgt6PWCn9gd8ZmPxyl3STW3iI=
+example.com. IN SOA alfa.ns.example.com.cz. hostmaster.example.com. 2010030800 10800 86400 604800 86400
+example.com. 3600 IN RRSIG SOA 3 2 3600 20070926134150 20070829134150 2854 example.com. ADsxLOHjxFzwFmwIiGOubqD9nKWAp4RccRIXQ0+EAUGfSDZMCB0ZiFA= ;{id = 2854}
+SECTION ADDITIONAL
+ENTRY_END
+
+; DS query for foo.www.example.com returns the referral without record.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+foo.www.example.com. IN DS
+SECTION ANSWER
+SECTION AUTHORITY
+mipf0g23547qunto04vboegh9vadsrpo.example.com. IN NSEC3 1 0 1 1234 mipf0g23547qunto04vboegh9vadsrpq TXT
+mipf0g23547qunto04vboegh9vadsrpo.example.com. 3600 IN RRSIG NSEC3 3 3 3600 20070926134150 20070829134150 2854 example.com. ADc6JrdKuTmIJe4sAjpKZSUZKdHdfhmREk2F5A5cftU9053b0/3ILQM=
+
+example.com. IN SOA alfa.ns.example.com.cz. hostmaster.example.com. 2010030800 10800 86400 604800 86400
+example.com. 3600 IN RRSIG SOA 3 2 3600 20070926134150 20070829134150 2854 example.com. ADsxLOHjxFzwFmwIiGOubqD9nKWAp4RccRIXQ0+EAUGfSDZMCB0ZiFA= ;{id = 2854}
+
+
+;www.example.com. IN NS ns3.example.com.
+;h8c0nvkuibedn7ia997iegdl7h0i6h8b.example.com. IN NSEC3 1 0 1 1234 h8c0nvkuibedn7ia997iegdl7h0i6h8c TXT
+;h8c0nvkuibedn7ia997iegdl7h0i6h8b.example.com. 3600 IN RRSIG NSEC3 3 3 3600 20070926134150 20070829134150 2854 example.com. AH+bPQZST3COwJ1vSe05N7E5BM2GmXzJUKsiWwXKrmm/XjYKSxSuNPE=
+;SECTION ADDITIONAL
+;ns3.example.com. IN A 1.2.3.5
+
+
+; NSEC3 here: 1 0 1 1234
+; www.example.com. -> h8c0nvkuibedn7ia997iegdl7h0i6h8b.
+; *.www.example.com. -> cg2lpgpr8k7ck69h7bqu3od9pkht2o79.
+; foo.www.example.com. -> mipf0g23547qunto04vboegh9vadsrpo.
+
+;h8c0nvkuibedn7ia997iegdl7h0i6h8b.example.com. IN NSEC3 1 0 1 1234 h8c0nvkuibedn7ia997iegdl7h0i6h8c TXT
+;h8c0nvkuibedn7ia997iegdl7h0i6h8b.example.com. 3600 IN RRSIG NSEC3 3 3 3600 20070926134150 20070829134150 2854 example.com. AH+bPQZST3COwJ1vSe05N7E5BM2GmXzJUKsiWwXKrmm/XjYKSxSuNPE=
+;cg2lpgpr8k7ck69h7bqu3od9pkht2o78.example.com. IN NSEC3 1 0 1 1234 cg2lpgpr8k7ck69h7bqu3od9pkht2o89 TXT
+;cg2lpgpr8k7ck69h7bqu3od9pkht2o78.example.com. 3600 IN RRSIG NSEC3 3 3 3600 20070926134150 20070829134150 2854 example.com. ACzxBHMyDB5tTrXijboPSsB0ws1lJe3/B62QNAMcZv7l9DYNDEDKsXY=
+;mipf0g23547qunto04vboegh9vadsrph.example.com. IN NSEC3 1 0 1 1234 mipf0g23547qunto04vboegh9vadsrpp TXT
+;mipf0g23547qunto04vboegh9vadsrph.example.com. 3600 IN RRSIG NSEC3 3 3 3600 20070926134150 20070829134150 2854 example.com. AG2B7lrIVtBgg+WIt0yNYekGDBKkY7xkKfI0GLQ8q3brGy/+jubxba0=
+
+;www.example.com. IN NSEC zzz.example.com. RRSIG NSEC
+;www.example.com. 3600 IN RRSIG NSEC 3 3 3600 20070926134150 20070829134150 2854 example.com. AA9Dm626WvHXHPQXJkVyjyTqJ/dCHfZgt6PWCn9gd8ZmPxyl3STW3iI=
+
+;example.com. IN SOA alfa.ns.example.com.cz. hostmaster.example.com. 2010030800 10800 86400 604800 86400
+;example.com. 3600 IN RRSIG SOA 3 2 3600 20070926134150 20070829134150 2854 example.com. ADsxLOHjxFzwFmwIiGOubqD9nKWAp4RccRIXQ0+EAUGfSDZMCB0ZiFA= ;{id = 2854}
+SECTION ADDITIONAL
+ENTRY_END
+
+RANGE_END
+
+; ns3.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.5
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+foo.www.example.com. IN DS
+SECTION ANSWER
+SECTION AUTHORITY
+foo.www.example.com. IN SOA alfa.ns.example.com.cz. hostmaster.example.com. 2010030800 10800 86400 604800 86400
+SECTION ADDITIONAL
+ENTRY_END
+RANGE_END
+
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+foo.www.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA DO SERVFAIL
+SECTION QUESTION
+foo.www.example.com. IN A
+SECTION ANSWER
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/val_dname.rpl b/tests/integration/deckard/sets/resolver/val_dname.rpl
new file mode 100644
index 0000000..e34d59a
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_dname.rpl
@@ -0,0 +1,318 @@
+do-ip6: no
+
+; config options
+trust-anchor: ". IN DS 37471 5 1 da74e4e0fe4067c2afd1d4a3cceb852a3c0d4401"
+stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+val-override-date: "20170301000000"
+CONFIG_END
+
+SCENARIO_BEGIN Test DNAME validation
+
+; all the data are on the "root servers"
+RANGE_BEGIN 0 10000000
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH qname qtype opcode
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. 360000 IN NS K.ROOT-SERVERS.NET.
+. 360000 IN RRSIG NS 5 0 3600 20170315140518 20170215140518 37471 . izsEk9W7bSaEcIzfa+ks0fl1OsW64yiRLdy6fWh674WQcxs/C6k/FViAPsUCtUOysSWqiZgT+KZrRXOLEbNLzKp5gYkySXW+B9LR49vtUzu4r2zAGyqiTkSH2+TYHo98fPr+wzdB1w7c2S3FIjYAsBanYaSW0emffB2a+nkPy4BClu9+4kpjpsE7FetenOqTUst0v6kdPQ+yaun+fbhBSSU4vlXPmDEolsfXM6tnOXljynUcFCNZfF3g9O0BzU34ev0eDUIdn20e2So4f7wZ1Xw6X6cv7Gt7xKOOBzYQBbeyaHiaUaHlFqSSZ07AfMIntE8fCSAhEOsDSNtVBpLD9w==
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. 360000 IN A 193.0.14.129
+k.root-servers.net. 360000 IN RRSIG A 5 3 3600 20170315140518 20170215140518 37471 . nFA+6UiLEGaw3p112+wsa7P+jucQ2RahwXkzSGPfF+ljqLpNnktPj0UUhW9urI+I/lK5idV9ffHISjrhTS+0fgoJb6CfDZBSAxQj6ccZ+Sd5HsqYO/GvqZ3eYL5AmXm/FVNhWgtk/5zLczTRqqseo7YVk6d+osVQe0GS/MNAMed4G9ZagmY4xihu2xkX1a8h+JT8KaIV50wAmKLtDx6cXHJqThZs5S9QIpm9a9AB7jC1vjtn87d5E6cgxlNGFviEzUs5THHHJkId+EBAyhS2QAxJCswVD1ELWsIc8srVuFhk5gBzfB6rIlw4sB4dRrGd0fs+McnTZmYBJqIbcYcrCQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH qname qtype opcode
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+. IN DNSKEY
+SECTION ANSWER
+. 86400 IN DNSKEY 257 3 5 AwEAAcgM97sxsTSBW9OAvo3Xmu4BPa8Egpk4TbpCnTwzIC3jU7/0D9xI6fWvFl2HVMNICJw+6fiPKwBWYIOd1OI2lsVXNvV26QoSEQwAh5zZjfE8M1cjIJxV/NY7svRL87YwGChgDI2Y00+CSsXyuPIFzJL1BSXCFdJqzIAHsBXmww9JGQZ/t3oxqIfykzTLEDWi0rwb27dk29kHdUf3QIK20CcC+13rNZUYY4sz8Jrr5M/MstT5QcXyFuACzJRS7pdzpz9dNJqBnx/nGADAWgzL89S/FUUrMRmF8ol0Lqq3h03dtmCsYlyBUsbUGyktf6YYE5tE0s4MyKzSGLUGp6mqoJk= ;{id = 37471 (ksk), size = 2048b}
+. 86400 IN RRSIG DNSKEY 5 0 86400 20170315140518 20170215140518 37471 . AVx9OlHQ4OkaRNi2YYy5HVOXdAqE3P/+mj92wVTl4/Sn54Z0C0vc0nDKt+vDDlJhJneJiWoJmoeGURK7uV0Rv7XZkxa+Nw/2EwplflFlicK7g50EdHjTfHCJdnJdEWQGqEcqLc2E8YUsNCsf9vBrFxyzWSOT9D0VzWy78IxHHoyRvcxtjBEqri+yosJ5iO/SFT0ZFXV1BmZ7VXFkxd+4gLNWgkIcebaD0Unq8R+oALELDEO7tJGdAvv5vTyXSIsvsrB8GTH5sLFi5MpAZ1IRh1TxMYKdrg/dVJ4mcdDx7fahz/9w/IddFazpMxRQufSmQcmuG7BlmRzbj2gSPL73Iw==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH qname qtype opcode
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+K.ROOT-SERVERS.NET. IN A
+SECTION ANSWER
+K.ROOT-SERVERS.NET. 360000 IN A 193.0.14.129
+k.root-servers.net. 360000 IN RRSIG A 5 3 3600 20170315140518 20170215140518 37471 . nFA+6UiLEGaw3p112+wsa7P+jucQ2RahwXkzSGPfF+ljqLpNnktPj0UUhW9urI+I/lK5idV9ffHISjrhTS+0fgoJb6CfDZBSAxQj6ccZ+Sd5HsqYO/GvqZ3eYL5AmXm/FVNhWgtk/5zLczTRqqseo7YVk6d+osVQe0GS/MNAMed4G9ZagmY4xihu2xkX1a8h+JT8KaIV50wAmKLtDx6cXHJqThZs5S9QIpm9a9AB7jC1vjtn87d5E6cgxlNGFviEzUs5THHHJkId+EBAyhS2QAxJCswVD1ELWsIc8srVuFhk5gBzfB6rIlw4sB4dRrGd0fs+McnTZmYBJqIbcYcrCQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH qname qtype opcode
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+K.ROOT-SERVERS.NET. IN AAAA
+SECTION AUTHORITY
+. 86400 IN SOA . . 2017021500 1800 900 604800 86400
+. 86400 IN RRSIG SOA 5 0 86400 20170315140518 20170215140518 37471 . drrv7SjrOkuNwlILiziPxHTuIKs/tO2WcVEdipA/LNkt0h09zuWbr3Rk5gtEDTSECbZEXYTa4YaeJs3ODmikzVaJd5EVLsDdGnV3mZ/w7WYHA0Uc1GH5HZm1uQwA4DlwY5e5Ry80pIhInZ1Lqiz1ut9yWbHzODdcUOdpE+XiPzYCKR1hRWi099dIQtDhZYottvQNXXmsJDY41PwvWaxqbXGYgiQCX3cN/W5PM0hs7xMxAjanKh32PXKcHSfTeko87BvERMZnibc2O8efl7S62Zp68Q4guMfe4P++ue22PctjwfeR5nDi31c3+USi63ujrKSDGujaIsIMyIHNFm1/zQ==
+K.ROOT-SERVERS.NET. 86400 IN NSEC shortloop. A RRSIG NSEC
+k.root-servers.net. 86400 IN RRSIG NSEC 5 3 86400 20170315140518 20170215140518 37471 . eAxOWct9VumUnYLk9w+Z8Us7u70VNgjTlVlilZSCifvIEQ2Q2BOfuS9UbpwOGPIaDkXRpDQyXTZ3IxPaVb3XVtJdUNgbIjkQnbu4FE+jf6qCSMONgR531ykW+n8HvodRaGnhp/OZobt4TtMEFzZwjq7E35dnn6krBpy+uZ/X31Wt0MI2U7JupLW5zO5AeeDYxNpaAXdw9MrZrzCtRojz0q2Z8ax/6SPBOBxhhqx8zyXhwWM3HDNSP7D8pcFx6Vz4nq7MCbqivDzm6oRM31Kg3585+ivht+d6WssmdYiRgYjKUuSk51srESwy5K6uS9PZ8Y284j/cFNZsJdNpYTLzyQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH qname qtype opcode
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+shortloop. IN TXT
+SECTION ANSWER
+;. 86400 IN SOA . . 2017021500 1800 900 604800 86400
+;. 86400 IN RRSIG SOA 5 0 86400 20170315140518 20170215140518 37471 . drrv7SjrOkuNwlILiziPxHTuIKs/tO2WcVEdipA/LNkt0h09zuWbr3Rk5gtEDTSECbZEXYTa4YaeJs3ODmikzVaJd5EVLsDdGnV3mZ/w7WYHA0Uc1GH5HZm1uQwA4DlwY5e5Ry80pIhInZ1Lqiz1ut9yWbHzODdcUOdpE+XiPzYCKR1hRWi099dIQtDhZYottvQNXXmsJDY41PwvWaxqbXGYgiQCX3cN/W5PM0hs7xMxAjanKh32PXKcHSfTeko87BvERMZnibc2O8efl7S62Zp68Q4guMfe4P++ue22PctjwfeR5nDi31c3+USi63ujrKSDGujaIsIMyIHNFm1/zQ==
+shortloop. 3600 IN TXT "shortloop end"
+shortloop. 3600 IN RRSIG TXT 5 1 3600 20170315140518 20170215140518 37471 . EJaF7yRFRv01nvv6I9HYaxGukSu92cuRXHYQGTRUtj0TNVI53SmNNs89Vk+8L34vhtw+fy1e62WZ3JSat5xAVVRWVmvp220+RlF9FAYltqpPblVXKQraDACWkO31YftgI2obGqmwByAgh7yW1Kfwq6JgUzwjT8LKeove6HNMRc0jipDXXEIRsWd3I6Yjx66YewVeHU55/UrKCeeozOQ4lMJZF0OBQsmTukfq72j6wIXjrjS8vx6Dz8o3pgGy14LG8NQCKcYbQysD1tmtiDDKDbNmwDCfbu+AA3Xd1XNiQpZUjUOxQpWtOxYA/qG7nJmY9VMdoXJ2wIW91B2vv+xbxw==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH qname opcode
+ADJUST copy_id copy_query
+REPLY QR AA NOERROR
+SECTION QUESTION
+shortloop. IN DS
+SECTION AUTHORITY
+. 86400 IN SOA . . 2017021500 1800 900 604800 86400
+. 86400 IN RRSIG SOA 5 0 86400 20170315140518 20170215140518 37471 . drrv7SjrOkuNwlILiziPxHTuIKs/tO2WcVEdipA/LNkt0h09zuWbr3Rk5gtEDTSECbZEXYTa4YaeJs3ODmikzVaJd5EVLsDdGnV3mZ/w7WYHA0Uc1GH5HZm1uQwA4DlwY5e5Ry80pIhInZ1Lqiz1ut9yWbHzODdcUOdpE+XiPzYCKR1hRWi099dIQtDhZYottvQNXXmsJDY41PwvWaxqbXGYgiQCX3cN/W5PM0hs7xMxAjanKh32PXKcHSfTeko87BvERMZnibc2O8efl7S62Zp68Q4guMfe4P++ue22PctjwfeR5nDi31c3+USi63ujrKSDGujaIsIMyIHNFm1/zQ==
+shortloop. 86400 IN NSEC x. TXT RRSIG NSEC
+shortloop. 86400 IN RRSIG NSEC 5 1 86400 20170315140518 20170215140518 37471 . BO48qjNHF9l46CUOeZVG9TV+DRwd7bP60likdnICAx6OMHX/sC5lxd+bQVYqG9DEh+HySqiwE4GnXKGxvdYIQUHuyM/OWQ2NkJPUU++FbXkDCNFPjpX16ejyc244aLOL3gXIOS1aILG9uSbz/0LFQ+N0P9Pq57Cv9I5cc6z0Xa/x8s2fIM8GAP9NoaFAMCdocYW8yckvbyxBoHLqlo0MZQIhiZh1ahorJTDxbJ2BbPRN5cf71PCztEjSjPn2zVlAsfp0XWJG79P3IZiWwBG8aFED1KvUP1+MWxGL+cb0d1bb60U4MzZIt4iWGM5r+wdc27L8vINFCug6RwETQHAJpg==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH qname qtype opcode
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+x. IN DNAME
+SECTION ANSWER
+x. 3600 IN DNAME .
+x. 3600 IN RRSIG DNAME 5 1 3600 20170315140518 20170215140518 37471 . ao9vqbmh78RP84/nOaFaI/bxPk+Y/Qsknt+WWtBIY2qcPZb1I+ZCxh9g9cYo1RKQuOriAJKrHkrv9ObAc9fse/2tNM+vtjemLWIGBvPtSo3vOwZGTTwI8spvFvMa+f6wnI5Oj9Phvdk17d+FnX9nIl6NRZb84bIxUjqSuhBIMJRmSGXWM0beQqEf0PNLQBTpeI6tUXsOwtFxrnG/zGzpB/W/1whh0nSmLf39lxyA+441H2o1OjSRu6ijmVrCDwOrbb/SXj+LZTGThEcIepbVb3ol+Mft2Kff5IcIhLM9I2YfBtgRwqHmue8v6z12AA9GuXBB/xvTkwFhUOXxNbSh+w==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH qname opcode
+ADJUST copy_id copy_query
+REPLY QR AA NOERROR
+SECTION QUESTION
+x. IN DS
+SECTION AUTHORITY
+. 3600 IN SOA . . 2017021500 1800 900 604800 86400
+. 3600 IN RRSIG SOA 5 0 86400 20170315140518 20170215140518 37471 . drrv7SjrOkuNwlILiziPxHTuIKs/tO2WcVEdipA/LNkt0h09zuWbr3Rk5gtEDTSECbZEXYTa4YaeJs3ODmikzVaJd5EVLsDdGnV3mZ/w7WYHA0Uc1GH5HZm1uQwA4DlwY5e5Ry80pIhInZ1Lqiz1ut9yWbHzODdcUOdpE+XiPzYCKR1hRWi099dIQtDhZYottvQNXXmsJDY41PwvWaxqbXGYgiQCX3cN/W5PM0hs7xMxAjanKh32PXKcHSfTeko87BvERMZnibc2O8efl7S62Zp68Q4guMfe4P++ue22PctjwfeR5nDi31c3+USi63ujrKSDGujaIsIMyIHNFm1/zQ==
+x. 3600 IN NSEC . DNAME RRSIG NSEC
+x. 3600 IN RRSIG NSEC 5 1 86400 20170315140518 20170215140518 37471 . TqFcpOvTT2x64L4gKTI43EJV4cMO+ys2BV8EILftXVID9wZTKK9SI0n4Pxfl5EIwnTpaWev1ZzIyAQ20ROi0t8E6qFuWKW6450k9qBb1d0HgR9dUMByHpQqcusg0kIkId9yHvb3FsKDimpn+5bDq4wT5Ijb/FHb5YpdY+F7Z8xfQpIplr+HYHkEADstqmDcHz3nbIuCjOQTdOongkzNj3IOHCcILU3GFLr5PPhhtx6M1N+EPkJQe92ukjlav/KdZQx+/D8/VLMqi7MKH9eDuEpzGeyRS6wm+Uuwf/DzWRgkImIMfWHXaTi/RZpa5UxNFzRchfucfNxAL9MjPT+NqAQ==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname opcode
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+shortloop.x.x. IN CNAME
+SECTION ANSWER
+x. 3600 IN DNAME .
+x. 3600 IN RRSIG DNAME 5 1 3600 20170315140518 20170215140518 37471 . ao9vqbmh78RP84/nOaFaI/bxPk+Y/Qsknt+WWtBIY2qcPZb1I+ZCxh9g9cYo1RKQuOriAJKrHkrv9ObAc9fse/2tNM+vtjemLWIGBvPtSo3vOwZGTTwI8spvFvMa+f6wnI5Oj9Phvdk17d+FnX9nIl6NRZb84bIxUjqSuhBIMJRmSGXWM0beQqEf0PNLQBTpeI6tUXsOwtFxrnG/zGzpB/W/1whh0nSmLf39lxyA+441H2o1OjSRu6ijmVrCDwOrbb/SXj+LZTGThEcIepbVb3ol+Mft2Kff5IcIhLM9I2YfBtgRwqHmue8v6z12AA9GuXBB/xvTkwFhUOXxNbSh+w==
+shortloop.x.x. IN CNAME shortloop.x.
+shortloop.x. IN CNAME shortloop.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH qname opcode
+ADJUST copy_id copy_query
+REPLY QR AA NOERROR
+SECTION QUESTION
+shortloop.x. IN CNAME
+SECTION ANSWER
+x. 3600 IN DNAME .
+x. 3600 IN RRSIG DNAME 5 1 3600 20170315140518 20170215140518 37471 . ao9vqbmh78RP84/nOaFaI/bxPk+Y/Qsknt+WWtBIY2qcPZb1I+ZCxh9g9cYo1RKQuOriAJKrHkrv9ObAc9fse/2tNM+vtjemLWIGBvPtSo3vOwZGTTwI8spvFvMa+f6wnI5Oj9Phvdk17d+FnX9nIl6NRZb84bIxUjqSuhBIMJRmSGXWM0beQqEf0PNLQBTpeI6tUXsOwtFxrnG/zGzpB/W/1whh0nSmLf39lxyA+441H2o1OjSRu6ijmVrCDwOrbb/SXj+LZTGThEcIepbVb3ol+Mft2Kff5IcIhLM9I2YfBtgRwqHmue8v6z12AA9GuXBB/xvTkwFhUOXxNbSh+w==
+shortloop.x. 3600 IN CNAME shortloop.
+SECTION AUTHORITY
+. 86400 IN SOA . . 2017021500 1800 900 604800 86400
+shortloop. 86400 IN NSEC x. TXT RRSIG NSEC
+. 86400 IN RRSIG SOA 5 0 86400 20170315140518 20170215140518 37471 . drrv7SjrOkuNwlILiziPxHTuIKs/tO2WcVEdipA/LNkt0h09zuWbr3Rk 5gtEDTSECbZEXYTa4YaeJs3ODmikzVaJd5EVLsDdGnV3mZ/w7WYHA0Uc 1GH5HZm1uQwA4DlwY5e5Ry80pIhInZ1Lqiz1ut9yWbHzODdcUOdpE+Xi PzYCKR1hRWi099dIQtDhZYottvQNXXmsJDY41PwvWaxqbXGYgiQCX3cN /W5PM0hs7xMxAjanKh32PXKcHSfTeko87BvERMZnibc2O8efl7S62Zp6 8Q4guMfe4P++ue22PctjwfeR5nDi31c3+USi63ujrKSDGujaIsIMyIHN Fm1/zQ==
+shortloop. 86400 IN RRSIG NSEC 5 1 86400 20170315140518 20170215140518 37471 . BO48qjNHF9l46CUOeZVG9TV+DRwd7bP60likdnICAx6OMHX/sC5lxd+b QVYqG9DEh+HySqiwE4GnXKGxvdYIQUHuyM/OWQ2NkJPUU++FbXkDCNFP jpX16ejyc244aLOL3gXIOS1aILG9uSbz/0LFQ+N0P9Pq57Cv9I5cc6z0 Xa/x8s2fIM8GAP9NoaFAMCdocYW8yckvbyxBoHLqlo0MZQIhiZh1ahor JTDxbJ2BbPRN5cf71PCztEjSjPn2zVlAsfp0XWJG79P3IZiWwBG8aFED 1KvUP1+MWxGL+cb0d1bb60U4MzZIt4iWGM5r+wdc27L8vINFCug6RwET QHAJpg==
+ENTRY_END
+
+RANGE_END
+; end of a.gtld-servers.net.
+
+; RFC 6672 section 2.2. The DNAME Substitution table tests
+;# QNAME owner DNAME target result
+;-- ---------------- -------------- -------------- -----------------
+;11 shortloop.x.x. x. . shortloop.x.
+;12 shortloop.x. x. . shortloop.
+; Table 1. DNAME Substitution Examples
+
+STEP 221101 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+shortloop.x.x. TXT
+ENTRY_END
+
+STEP 221102 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY NOERROR QR RD RA AD
+SECTION QUESTION
+shortloop.x.x. IN TXT
+SECTION ANSWER
+x. 3600 IN DNAME .
+x. 3600 IN RRSIG DNAME 5 1 3600 20170315140518 20170215140518 37471 . ao9vqbmh78RP84/nOaFaI/bxPk+Y/Qsknt+WWtBIY2qcPZb1I+ZCxh9g9cYo1RKQuOriAJKrHkrv9ObAc9fse/2tNM+vtjemLWIGBvPtSo3vOwZGTTwI8spvFvMa+f6wnI5Oj9Phvdk17d+FnX9nIl6NRZb84bIxUjqSuhBIMJRmSGXWM0beQqEf0PNLQBTpeI6tUXsOwtFxrnG/zGzpB/W/1whh0nSmLf39lxyA+441H2o1OjSRu6ijmVrCDwOrbb/SXj+LZTGThEcIepbVb3ol+Mft2Kff5IcIhLM9I2YfBtgRwqHmue8v6z12AA9GuXBB/xvTkwFhUOXxNbSh+w==
+shortloop.x.x. IN CNAME shortloop.x.
+shortloop.x. IN CNAME shortloop.
+shortloop. 3600 IN TXT "shortloop end"
+shortloop. 3600 IN RRSIG TXT 5 1 3600 20170315140518 20170215140518 37471 . EJaF7yRFRv01nvv6I9HYaxGukSu92cuRXHYQGTRUtj0TNVI53SmNNs89Vk+8L34vhtw+fy1e62WZ3JSat5xAVVRWVmvp220+RlF9FAYltqpPblVXKQraDACWkO31YftgI2obGqmwByAgh7yW1Kfwq6JgUzwjT8LKeove6HNMRc0jipDXXEIRsWd3I6Yjx66YewVeHU55/UrKCeeozOQ4lMJZF0OBQsmTukfq72j6wIXjrjS8vx6Dz8o3pgGy14LG8NQCKcYbQysD1tmtiDDKDbNmwDCfbu+AA3Xd1XNiQpZUjUOxQpWtOxYA/qG7nJmY9VMdoXJ2wIW91B2vv+xbxw==
+ENTRY_END
+
+;# QNAME owner DNAME target result
+;-- ---------------- -------------- -------------- -----------------
+;12 shortloop.x. x. . shortloop.
+STEP 221201 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+shortloop.x. CNAME
+ENTRY_END
+
+STEP 221202 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY NOERROR QR RD RA AD
+SECTION QUESTION
+shortloop.x. IN CNAME
+SECTION ANSWER
+x. 3600 IN DNAME .
+x. 3600 IN RRSIG DNAME 5 1 3600 20170315140518 20170215140518 37471 . ao9vqbmh78RP84/nOaFaI/bxPk+Y/Qsknt+WWtBIY2qcPZb1I+ZCxh9g9cYo1RKQuOriAJKrHkrv9ObAc9fse/2tNM+vtjemLWIGBvPtSo3vOwZGTTwI8spvFvMa+f6wnI5Oj9Phvdk17d+FnX9nIl6NRZb84bIxUjqSuhBIMJRmSGXWM0beQqEf0PNLQBTpeI6tUXsOwtFxrnG/zGzpB/W/1whh0nSmLf39lxyA+441H2o1OjSRu6ijmVrCDwOrbb/SXj+LZTGThEcIepbVb3ol+Mft2Kff5IcIhLM9I2YfBtgRwqHmue8v6z12AA9GuXBB/xvTkwFhUOXxNbSh+w==
+shortloop.x. IN CNAME shortloop.
+ENTRY_END
+
+STEP 221213 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+shortloop.x. TXT
+ENTRY_END
+
+STEP 221214 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY NOERROR QR RD RA AD
+SECTION QUESTION
+shortloop.x. IN TXT
+SECTION ANSWER
+x. 3600 IN DNAME .
+x. 3600 IN RRSIG DNAME 5 1 3600 20170315140518 20170215140518 37471 . ao9vqbmh78RP84/nOaFaI/bxPk+Y/Qsknt+WWtBIY2qcPZb1I+ZCxh9g9cYo1RKQuOriAJKrHkrv9ObAc9fse/2tNM+vtjemLWIGBvPtSo3vOwZGTTwI8spvFvMa+f6wnI5Oj9Phvdk17d+FnX9nIl6NRZb84bIxUjqSuhBIMJRmSGXWM0beQqEf0PNLQBTpeI6tUXsOwtFxrnG/zGzpB/W/1whh0nSmLf39lxyA+441H2o1OjSRu6ijmVrCDwOrbb/SXj+LZTGThEcIepbVb3ol+Mft2Kff5IcIhLM9I2YfBtgRwqHmue8v6z12AA9GuXBB/xvTkwFhUOXxNbSh+w==
+shortloop.x. IN CNAME shortloop.
+shortloop. 3600 IN TXT "shortloop end"
+shortloop. 3600 IN RRSIG TXT 5 1 3600 20170315140518 20170215140518 37471 . EJaF7yRFRv01nvv6I9HYaxGukSu92cuRXHYQGTRUtj0TNVI53SmNNs89Vk+8L34vhtw+fy1e62WZ3JSat5xAVVRWVmvp220+RlF9FAYltqpPblVXKQraDACWkO31YftgI2obGqmwByAgh7yW1Kfwq6JgUzwjT8LKeove6HNMRc0jipDXXEIRsWd3I6Yjx66YewVeHU55/UrKCeeozOQ4lMJZF0OBQsmTukfq72j6wIXjrjS8vx6Dz8o3pgGy14LG8NQCKcYbQysD1tmtiDDKDbNmwDCfbu+AA3Xd1XNiQpZUjUOxQpWtOxYA/qG7nJmY9VMdoXJ2wIW91B2vv+xbxw==
+ENTRY_END
+
+; make sure all caches expired
+STEP 900000 TIME_PASSES ELAPSE 4000
+
+
+; simulate situaction when DNAME expires at different time than synthetized CNAMEs
+; put only the DNAME into the cache
+STEP 900001 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+x. IN DNAME
+ENTRY_END
+
+STEP 900002 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY NOERROR QR RD RA AD
+SECTION QUESTION
+x. IN DNAME
+SECTION ANSWER
+x. 3600 IN DNAME .
+x. 3600 IN RRSIG DNAME 5 1 3600 20170315140518 20170215140518 37471 . ao9vqbmh78RP84/nOaFaI/bxPk+Y/Qsknt+WWtBIY2qcPZb1I+ZCxh9g9cYo1RKQuOriAJKrHkrv9ObAc9fse/2tNM+vtjemLWIGBvPtSo3vOwZGTTwI8spvFvMa+f6wnI5Oj9Phvdk17d+FnX9nIl6NRZb84bIxUjqSuhBIMJRmSGXWM0beQqEf0PNLQBTpeI6tUXsOwtFxrnG/zGzpB/W/1whh0nSmLf39lxyA+441H2o1OjSRu6ijmVrCDwOrbb/SXj+LZTGThEcIepbVb3ol+Mft2Kff5IcIhLM9I2YfBtgRwqHmue8v6z12AA9GuXBB/xvTkwFhUOXxNbSh+w==
+ENTRY_END
+
+;; let half of DNAME TTL pass
+STEP 900005 TIME_PASSES ELAPSE 2000
+
+; now fill cache with rest of the records from CNAME chain
+; this should renew TTL on DNAME
+STEP 900100 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+shortloop.x. TXT
+ENTRY_END
+
+STEP 900101 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY NOERROR QR RD RA AD
+SECTION QUESTION
+shortloop.x. IN TXT
+SECTION ANSWER
+x. 3600 IN DNAME .
+x. 3600 IN RRSIG DNAME 5 1 3600 20170315140518 20170215140518 37471 . ao9vqbmh78RP84/nOaFaI/bxPk+Y/Qsknt+WWtBIY2qcPZb1I+ZCxh9g9cYo1RKQuOriAJKrHkrv9ObAc9fse/2tNM+vtjemLWIGBvPtSo3vOwZGTTwI8spvFvMa+f6wnI5Oj9Phvdk17d+FnX9nIl6NRZb84bIxUjqSuhBIMJRmSGXWM0beQqEf0PNLQBTpeI6tUXsOwtFxrnG/zGzpB/W/1whh0nSmLf39lxyA+441H2o1OjSRu6ijmVrCDwOrbb/SXj+LZTGThEcIepbVb3ol+Mft2Kff5IcIhLM9I2YfBtgRwqHmue8v6z12AA9GuXBB/xvTkwFhUOXxNbSh+w==
+shortloop.x. IN CNAME shortloop.
+shortloop. 3600 IN TXT "shortloop end"
+shortloop. 3600 IN RRSIG TXT 5 1 3600 20170315140518 20170215140518 37471 . EJaF7yRFRv01nvv6I9HYaxGukSu92cuRXHYQGTRUtj0TNVI53SmNNs89Vk+8L34vhtw+fy1e62WZ3JSat5xAVVRWVmvp220+RlF9FAYltqpPblVXKQraDACWkO31YftgI2obGqmwByAgh7yW1Kfwq6JgUzwjT8LKeove6HNMRc0jipDXXEIRsWd3I6Yjx66YewVeHU55/UrKCeeozOQ4lMJZF0OBQsmTukfq72j6wIXjrjS8vx6Dz8o3pgGy14LG8NQCKcYbQysD1tmtiDDKDbNmwDCfbu+AA3Xd1XNiQpZUjUOxQpWtOxYA/qG7nJmY9VMdoXJ2wIW91B2vv+xbxw==
+ENTRY_END
+
+; let DNAME expire from cache but keep CNAMEs in cache
+STEP 900200 TIME_PASSES ELAPSE 2000
+
+; check that chain of synthetized CNAMEs is properly validated
+; bad things would happen if DNAME expired from cache (and was not renewed)
+STEP 900201 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+shortloop.x. TXT
+ENTRY_END
+
+STEP 900202 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY NOERROR QR RD RA AD
+SECTION QUESTION
+shortloop.x. IN TXT
+SECTION ANSWER
+x. 3600 IN DNAME .
+x. 3600 IN RRSIG DNAME 5 1 3600 20170315140518 20170215140518 37471 . ao9vqbmh78RP84/nOaFaI/bxPk+Y/Qsknt+WWtBIY2qcPZb1I+ZCxh9g9cYo1RKQuOriAJKrHkrv9ObAc9fse/2tNM+vtjemLWIGBvPtSo3vOwZGTTwI8spvFvMa+f6wnI5Oj9Phvdk17d+FnX9nIl6NRZb84bIxUjqSuhBIMJRmSGXWM0beQqEf0PNLQBTpeI6tUXsOwtFxrnG/zGzpB/W/1whh0nSmLf39lxyA+441H2o1OjSRu6ijmVrCDwOrbb/SXj+LZTGThEcIepbVb3ol+Mft2Kff5IcIhLM9I2YfBtgRwqHmue8v6z12AA9GuXBB/xvTkwFhUOXxNbSh+w==
+shortloop.x. IN CNAME shortloop.
+shortloop. 3600 IN TXT "shortloop end"
+shortloop. 3600 IN RRSIG TXT 5 1 3600 20170315140518 20170215140518 37471 . EJaF7yRFRv01nvv6I9HYaxGukSu92cuRXHYQGTRUtj0TNVI53SmNNs89Vk+8L34vhtw+fy1e62WZ3JSat5xAVVRWVmvp220+RlF9FAYltqpPblVXKQraDACWkO31YftgI2obGqmwByAgh7yW1Kfwq6JgUzwjT8LKeove6HNMRc0jipDXXEIRsWd3I6Yjx66YewVeHU55/UrKCeeozOQ4lMJZF0OBQsmTukfq72j6wIXjrjS8vx6Dz8o3pgGy14LG8NQCKcYbQysD1tmtiDDKDbNmwDCfbu+AA3Xd1XNiQpZUjUOxQpWtOxYA/qG7nJmY9VMdoXJ2wIW91B2vv+xbxw==
+ENTRY_END
+
+
+; check that query for the synthetized CNAMEs is properly validated
+STEP 900301 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+shortloop.x. CNAME
+ENTRY_END
+
+STEP 900302 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY NOERROR QR RD RA AD
+SECTION QUESTION
+shortloop.x. IN CNAME
+SECTION ANSWER
+x. 3600 IN DNAME .
+x. 3600 IN RRSIG DNAME 5 1 3600 20170315140518 20170215140518 37471 . ao9vqbmh78RP84/nOaFaI/bxPk+Y/Qsknt+WWtBIY2qcPZb1I+ZCxh9g9cYo1RKQuOriAJKrHkrv9ObAc9fse/2tNM+vtjemLWIGBvPtSo3vOwZGTTwI8spvFvMa+f6wnI5Oj9Phvdk17d+FnX9nIl6NRZb84bIxUjqSuhBIMJRmSGXWM0beQqEf0PNLQBTpeI6tUXsOwtFxrnG/zGzpB/W/1whh0nSmLf39lxyA+441H2o1OjSRu6ijmVrCDwOrbb/SXj+LZTGThEcIepbVb3ol+Mft2Kff5IcIhLM9I2YfBtgRwqHmue8v6z12AA9GuXBB/xvTkwFhUOXxNbSh+w==
+shortloop.x. IN CNAME shortloop.
+ENTRY_END
+
+
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/val_dname_bogus.rpl b/tests/integration/deckard/sets/resolver/val_dname_bogus.rpl
new file mode 100644
index 0000000..6180320
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_dname_bogus.rpl
@@ -0,0 +1,319 @@
+do-ip6: no
+
+; config options
+trust-anchor: ". IN DS 37471 5 1 da74e4e0fe4067c2afd1d4a3cceb852a3c0d4401"
+stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+val-override-date: "20170301000000"
+query-minimization: off # missing net. NS proof for NODATA, so we'd need to resign everything
+CONFIG_END
+
+SCENARIO_BEGIN Test DNAME validation
+
+; all the data are on the "root servers"
+RANGE_BEGIN 0 10000000
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH qname qtype opcode
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. 360000 IN NS K.ROOT-SERVERS.NET.
+. 360000 IN RRSIG NS 5 0 3600 20170315140518 20170215140518 37471 . izsEk9W7bSaEcIzfa+ks0fl1OsW64yiRLdy6fWh674WQcxs/C6k/FViAPsUCtUOysSWqiZgT+KZrRXOLEbNLzKp5gYkySXW+B9LR49vtUzu4r2zAGyqiTkSH2+TYHo98fPr+wzdB1w7c2S3FIjYAsBanYaSW0emffB2a+nkPy4BClu9+4kpjpsE7FetenOqTUst0v6kdPQ+yaun+fbhBSSU4vlXPmDEolsfXM6tnOXljynUcFCNZfF3g9O0BzU34ev0eDUIdn20e2So4f7wZ1Xw6X6cv7Gt7xKOOBzYQBbeyaHiaUaHlFqSSZ07AfMIntE8fCSAhEOsDSNtVBpLD9w==
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. 360000 IN A 193.0.14.129
+k.root-servers.net. 360000 IN RRSIG A 5 3 3600 20170315140518 20170215140518 37471 . nFA+6UiLEGaw3p112+wsa7P+jucQ2RahwXkzSGPfF+ljqLpNnktPj0UUhW9urI+I/lK5idV9ffHISjrhTS+0fgoJb6CfDZBSAxQj6ccZ+Sd5HsqYO/GvqZ3eYL5AmXm/FVNhWgtk/5zLczTRqqseo7YVk6d+osVQe0GS/MNAMed4G9ZagmY4xihu2xkX1a8h+JT8KaIV50wAmKLtDx6cXHJqThZs5S9QIpm9a9AB7jC1vjtn87d5E6cgxlNGFviEzUs5THHHJkId+EBAyhS2QAxJCswVD1ELWsIc8srVuFhk5gBzfB6rIlw4sB4dRrGd0fs+McnTZmYBJqIbcYcrCQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH qname qtype opcode
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+. IN DNSKEY
+SECTION ANSWER
+. 86400 IN DNSKEY 257 3 5 AwEAAcgM97sxsTSBW9OAvo3Xmu4BPa8Egpk4TbpCnTwzIC3jU7/0D9xI6fWvFl2HVMNICJw+6fiPKwBWYIOd1OI2lsVXNvV26QoSEQwAh5zZjfE8M1cjIJxV/NY7svRL87YwGChgDI2Y00+CSsXyuPIFzJL1BSXCFdJqzIAHsBXmww9JGQZ/t3oxqIfykzTLEDWi0rwb27dk29kHdUf3QIK20CcC+13rNZUYY4sz8Jrr5M/MstT5QcXyFuACzJRS7pdzpz9dNJqBnx/nGADAWgzL89S/FUUrMRmF8ol0Lqq3h03dtmCsYlyBUsbUGyktf6YYE5tE0s4MyKzSGLUGp6mqoJk= ;{id = 37471 (ksk), size = 2048b}
+. 86400 IN RRSIG DNSKEY 5 0 86400 20170315140518 20170215140518 37471 . AVx9OlHQ4OkaRNi2YYy5HVOXdAqE3P/+mj92wVTl4/Sn54Z0C0vc0nDKt+vDDlJhJneJiWoJmoeGURK7uV0Rv7XZkxa+Nw/2EwplflFlicK7g50EdHjTfHCJdnJdEWQGqEcqLc2E8YUsNCsf9vBrFxyzWSOT9D0VzWy78IxHHoyRvcxtjBEqri+yosJ5iO/SFT0ZFXV1BmZ7VXFkxd+4gLNWgkIcebaD0Unq8R+oALELDEO7tJGdAvv5vTyXSIsvsrB8GTH5sLFi5MpAZ1IRh1TxMYKdrg/dVJ4mcdDx7fahz/9w/IddFazpMxRQufSmQcmuG7BlmRzbj2gSPL73Iw==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH qname qtype opcode
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+K.ROOT-SERVERS.NET. IN A
+SECTION ANSWER
+K.ROOT-SERVERS.NET. 360000 IN A 193.0.14.129
+k.root-servers.net. 360000 IN RRSIG A 5 3 3600 20170315140518 20170215140518 37471 . nFA+6UiLEGaw3p112+wsa7P+jucQ2RahwXkzSGPfF+ljqLpNnktPj0UUhW9urI+I/lK5idV9ffHISjrhTS+0fgoJb6CfDZBSAxQj6ccZ+Sd5HsqYO/GvqZ3eYL5AmXm/FVNhWgtk/5zLczTRqqseo7YVk6d+osVQe0GS/MNAMed4G9ZagmY4xihu2xkX1a8h+JT8KaIV50wAmKLtDx6cXHJqThZs5S9QIpm9a9AB7jC1vjtn87d5E6cgxlNGFviEzUs5THHHJkId+EBAyhS2QAxJCswVD1ELWsIc8srVuFhk5gBzfB6rIlw4sB4dRrGd0fs+McnTZmYBJqIbcYcrCQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH qname opcode
+ADJUST copy_id copy_query
+REPLY QR AA NOERROR
+SECTION QUESTION
+K.ROOT-SERVERS.NET. IN AAAA
+SECTION AUTHORITY
+. 86400 IN SOA . . 2017021500 1800 900 604800 86400
+. 86400 IN RRSIG SOA 5 0 86400 20170315140518 20170215140518 37471 . drrv7SjrOkuNwlILiziPxHTuIKs/tO2WcVEdipA/LNkt0h09zuWbr3Rk5gtEDTSECbZEXYTa4YaeJs3ODmikzVaJd5EVLsDdGnV3mZ/w7WYHA0Uc1GH5HZm1uQwA4DlwY5e5Ry80pIhInZ1Lqiz1ut9yWbHzODdcUOdpE+XiPzYCKR1hRWi099dIQtDhZYottvQNXXmsJDY41PwvWaxqbXGYgiQCX3cN/W5PM0hs7xMxAjanKh32PXKcHSfTeko87BvERMZnibc2O8efl7S62Zp68Q4guMfe4P++ue22PctjwfeR5nDi31c3+USi63ujrKSDGujaIsIMyIHNFm1/zQ==
+K.ROOT-SERVERS.NET. 86400 IN NSEC shortloop. A RRSIG NSEC
+k.root-servers.net. 86400 IN RRSIG NSEC 5 3 86400 20170315140518 20170215140518 37471 . eAxOWct9VumUnYLk9w+Z8Us7u70VNgjTlVlilZSCifvIEQ2Q2BOfuS9UbpwOGPIaDkXRpDQyXTZ3IxPaVb3XVtJdUNgbIjkQnbu4FE+jf6qCSMONgR531ykW+n8HvodRaGnhp/OZobt4TtMEFzZwjq7E35dnn6krBpy+uZ/X31Wt0MI2U7JupLW5zO5AeeDYxNpaAXdw9MrZrzCtRojz0q2Z8ax/6SPBOBxhhqx8zyXhwWM3HDNSP7D8pcFx6Vz4nq7MCbqivDzm6oRM31Kg3585+ivht+d6WssmdYiRgYjKUuSk51srESwy5K6uS9PZ8Y284j/cFNZsJdNpYTLzyQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH qname qtype opcode
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+shortloop. IN TXT
+SECTION ANSWER
+;. 86400 IN SOA . . 2017021500 1800 900 604800 86400
+;. 86400 IN RRSIG SOA 5 0 86400 20170315140518 20170215140518 37471 . drrv7SjrOkuNwlILiziPxHTuIKs/tO2WcVEdipA/LNkt0h09zuWbr3Rk5gtEDTSECbZEXYTa4YaeJs3ODmikzVaJd5EVLsDdGnV3mZ/w7WYHA0Uc1GH5HZm1uQwA4DlwY5e5Ry80pIhInZ1Lqiz1ut9yWbHzODdcUOdpE+XiPzYCKR1hRWi099dIQtDhZYottvQNXXmsJDY41PwvWaxqbXGYgiQCX3cN/W5PM0hs7xMxAjanKh32PXKcHSfTeko87BvERMZnibc2O8efl7S62Zp68Q4guMfe4P++ue22PctjwfeR5nDi31c3+USi63ujrKSDGujaIsIMyIHNFm1/zQ==
+shortloop. 3600 IN TXT "shortloop end"
+shortloop. 3600 IN RRSIG TXT 5 1 3600 20170315140518 20170215140518 37471 . EJaF7yRFRv01nvv6I9HYaxGukSu92cuRXHYQGTRUtj0TNVI53SmNNs89Vk+8L34vhtw+fy1e62WZ3JSat5xAVVRWVmvp220+RlF9FAYltqpPblVXKQraDACWkO31YftgI2obGqmwByAgh7yW1Kfwq6JgUzwjT8LKeove6HNMRc0jipDXXEIRsWd3I6Yjx66YewVeHU55/UrKCeeozOQ4lMJZF0OBQsmTukfq72j6wIXjrjS8vx6Dz8o3pgGy14LG8NQCKcYbQysD1tmtiDDKDbNmwDCfbu+AA3Xd1XNiQpZUjUOxQpWtOxYA/qG7nJmY9VMdoXJ2wIW91B2vv+xbxw==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH qname opcode
+ADJUST copy_id copy_query
+REPLY QR AA NOERROR
+SECTION QUESTION
+shortloop. IN DS
+SECTION AUTHORITY
+. 86400 IN SOA . . 2017021500 1800 900 604800 86400
+. 86400 IN RRSIG SOA 5 0 86400 20170315140518 20170215140518 37471 . drrv7SjrOkuNwlILiziPxHTuIKs/tO2WcVEdipA/LNkt0h09zuWbr3Rk5gtEDTSECbZEXYTa4YaeJs3ODmikzVaJd5EVLsDdGnV3mZ/w7WYHA0Uc1GH5HZm1uQwA4DlwY5e5Ry80pIhInZ1Lqiz1ut9yWbHzODdcUOdpE+XiPzYCKR1hRWi099dIQtDhZYottvQNXXmsJDY41PwvWaxqbXGYgiQCX3cN/W5PM0hs7xMxAjanKh32PXKcHSfTeko87BvERMZnibc2O8efl7S62Zp68Q4guMfe4P++ue22PctjwfeR5nDi31c3+USi63ujrKSDGujaIsIMyIHNFm1/zQ==
+shortloop. 86400 IN NSEC x. TXT RRSIG NSEC
+shortloop. 86400 IN RRSIG NSEC 5 1 86400 20170315140518 20170215140518 37471 . BO48qjNHF9l46CUOeZVG9TV+DRwd7bP60likdnICAx6OMHX/sC5lxd+bQVYqG9DEh+HySqiwE4GnXKGxvdYIQUHuyM/OWQ2NkJPUU++FbXkDCNFPjpX16ejyc244aLOL3gXIOS1aILG9uSbz/0LFQ+N0P9Pq57Cv9I5cc6z0Xa/x8s2fIM8GAP9NoaFAMCdocYW8yckvbyxBoHLqlo0MZQIhiZh1ahorJTDxbJ2BbPRN5cf71PCztEjSjPn2zVlAsfp0XWJG79P3IZiWwBG8aFED1KvUP1+MWxGL+cb0d1bb60U4MzZIt4iWGM5r+wdc27L8vINFCug6RwETQHAJpg==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH qname qtype opcode
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+x. IN DNAME
+SECTION ANSWER
+x. 3600 IN DNAME .
+x. 3600 IN RRSIG DNAME 5 1 3600 20170315140518 20170215140518 37471 . ao9vqbmh78RP84/nOaFaI/bxPk+Y/Qsknt+WWtBIY2qcPZb1I+ZCxh9g9cYo1RKQuOriAJKrHkrv9ObAc9fse/2tNM+vtjemLWIGBvPtSo3vOwZGTTwI8spvFvMa+f6wnI5Oj9Phvdk17d+FnX9nIl6NRZb84bIxUjqSuhBIMJRmSGXWM0beQqEf0PNLQBTpeI6tUXsOwtFxrnG/zGzpB/W/1whh0nSmLf39lxyA+441H2o1OjSRu6ijmVrCDwOrbb/SXj+LZTGThEcIepbVb3ol+Mft2Kff5IcIhLM9I2YfBtgRwqHmue8v6z12AA9GuXBB/xvTkwFhUOXxNbSh+w==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH qname opcode
+ADJUST copy_id copy_query
+REPLY QR AA NOERROR
+SECTION QUESTION
+x. IN DS
+SECTION AUTHORITY
+. 3600 IN SOA . . 2017021500 1800 900 604800 86400
+. 3600 IN RRSIG SOA 5 0 86400 20170315140518 20170215140518 37471 . drrv7SjrOkuNwlILiziPxHTuIKs/tO2WcVEdipA/LNkt0h09zuWbr3Rk5gtEDTSECbZEXYTa4YaeJs3ODmikzVaJd5EVLsDdGnV3mZ/w7WYHA0Uc1GH5HZm1uQwA4DlwY5e5Ry80pIhInZ1Lqiz1ut9yWbHzODdcUOdpE+XiPzYCKR1hRWi099dIQtDhZYottvQNXXmsJDY41PwvWaxqbXGYgiQCX3cN/W5PM0hs7xMxAjanKh32PXKcHSfTeko87BvERMZnibc2O8efl7S62Zp68Q4guMfe4P++ue22PctjwfeR5nDi31c3+USi63ujrKSDGujaIsIMyIHNFm1/zQ==
+x. 3600 IN NSEC . DNAME RRSIG NSEC
+x. 3600 IN RRSIG NSEC 5 1 86400 20170315140518 20170215140518 37471 . TqFcpOvTT2x64L4gKTI43EJV4cMO+ys2BV8EILftXVID9wZTKK9SI0n4Pxfl5EIwnTpaWev1ZzIyAQ20ROi0t8E6qFuWKW6450k9qBb1d0HgR9dUMByHpQqcusg0kIkId9yHvb3FsKDimpn+5bDq4wT5Ijb/FHb5YpdY+F7Z8xfQpIplr+HYHkEADstqmDcHz3nbIuCjOQTdOongkzNj3IOHCcILU3GFLr5PPhhtx6M1N+EPkJQe92ukjlav/KdZQx+/D8/VLMqi7MKH9eDuEpzGeyRS6wm+Uuwf/DzWRgkImIMfWHXaTi/RZpa5UxNFzRchfucfNxAL9MjPT+NqAQ==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH qname opcode
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+shortloop.x.x. IN CNAME
+SECTION ANSWER
+x. 3600 IN DNAME .
+x. 3600 IN RRSIG DNAME 5 1 3600 20170315140518 20170215140518 37471 . ao9vqbmh78RP84/nOaFaI/bxPk+Y/Qsknt+WWtBIY2qcPZb1I+ZCxh9g9cYo1RKQuOriAJKrHkrv9ObAc9fse/2tNM+vtjemLWIGBvPtSo3vOwZGTTwI8spvFvMa+f6wnI5Oj9Phvdk17d+FnX9nIl6NRZb84bIxUjqSuhBIMJRmSGXWM0beQqEf0PNLQBTpeI6tUXsOwtFxrnG/zGzpB/W/1whh0nSmLf39lxyA+441H2o1OjSRu6ijmVrCDwOrbb/SXj+LZTGThEcIepbVb3ol+Mft2Kff5IcIhLM9I2YfBtgRwqHmue8v6z12AA9GuXBB/xvTkwFhUOXxNbSh+w==
+; attack! CNAME was modified to point elsewhere
+shortloop.x.x. 3600 IN CNAME K.ROOT-SERVERS.NET.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH qname opcode
+ADJUST copy_id copy_query
+REPLY QR AA NOERROR
+SECTION QUESTION
+shortloop.x. IN CNAME
+SECTION ANSWER
+x. 3600 IN DNAME .
+x. 3600 IN RRSIG DNAME 5 1 3600 20170315140518 20170215140518 37471 . ao9vqbmh78RP84/nOaFaI/bxPk+Y/Qsknt+WWtBIY2qcPZb1I+ZCxh9g9cYo1RKQuOriAJKrHkrv9ObAc9fse/2tNM+vtjemLWIGBvPtSo3vOwZGTTwI8spvFvMa+f6wnI5Oj9Phvdk17d+FnX9nIl6NRZb84bIxUjqSuhBIMJRmSGXWM0beQqEf0PNLQBTpeI6tUXsOwtFxrnG/zGzpB/W/1whh0nSmLf39lxyA+441H2o1OjSRu6ijmVrCDwOrbb/SXj+LZTGThEcIepbVb3ol+Mft2Kff5IcIhLM9I2YfBtgRwqHmue8v6z12AA9GuXBB/xvTkwFhUOXxNbSh+w==
+; attack! CNAME was modified to point elsewhere
+shortloop.x. 3600 IN CNAME K.ROOT-SERVERS.NET.
+SECTION AUTHORITY
+. 86400 IN SOA . . 2017021500 1800 900 604800 86400
+shortloop. 86400 IN NSEC x. TXT RRSIG NSEC
+. 86400 IN RRSIG SOA 5 0 86400 20170315140518 20170215140518 37471 . drrv7SjrOkuNwlILiziPxHTuIKs/tO2WcVEdipA/LNkt0h09zuWbr3Rk 5gtEDTSECbZEXYTa4YaeJs3ODmikzVaJd5EVLsDdGnV3mZ/w7WYHA0Uc 1GH5HZm1uQwA4DlwY5e5Ry80pIhInZ1Lqiz1ut9yWbHzODdcUOdpE+Xi PzYCKR1hRWi099dIQtDhZYottvQNXXmsJDY41PwvWaxqbXGYgiQCX3cN /W5PM0hs7xMxAjanKh32PXKcHSfTeko87BvERMZnibc2O8efl7S62Zp6 8Q4guMfe4P++ue22PctjwfeR5nDi31c3+USi63ujrKSDGujaIsIMyIHN Fm1/zQ==
+shortloop. 86400 IN RRSIG NSEC 5 1 86400 20170315140518 20170215140518 37471 . BO48qjNHF9l46CUOeZVG9TV+DRwd7bP60likdnICAx6OMHX/sC5lxd+b QVYqG9DEh+HySqiwE4GnXKGxvdYIQUHuyM/OWQ2NkJPUU++FbXkDCNFP jpX16ejyc244aLOL3gXIOS1aILG9uSbz/0LFQ+N0P9Pq57Cv9I5cc6z0 Xa/x8s2fIM8GAP9NoaFAMCdocYW8yckvbyxBoHLqlo0MZQIhiZh1ahor JTDxbJ2BbPRN5cf71PCztEjSjPn2zVlAsfp0XWJG79P3IZiWwBG8aFED 1KvUP1+MWxGL+cb0d1bb60U4MzZIt4iWGM5r+wdc27L8vINFCug6RwET QHAJpg==
+ENTRY_END
+
+RANGE_END
+; end of a.gtld-servers.net.
+
+; RFC 6672 section 2.2. The DNAME Substitution table tests
+;# QNAME owner DNAME target result
+;-- ---------------- -------------- -------------- -----------------
+;11 shortloop.x.x. x. . shortloop.x.
+;12 shortloop.x. x. . shortloop.
+; Table 1. DNAME Substitution Examples
+
+STEP 221101 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+shortloop.x.x. A
+ENTRY_END
+
+; attacker spoofed shortloop.x.x. CNAME so we end up with SERVFAIL
+STEP 221102 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY SERVFAIL QR RD RA
+SECTION QUESTION
+shortloop.x.x. IN A
+SECTION ANSWER
+ENTRY_END
+
+;# QNAME owner DNAME target result
+;-- ---------------- -------------- -------------- -----------------
+;12 shortloop.x. x. . shortloop.
+
+STEP 221201 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+shortloop.x.x. TXT
+ENTRY_END
+
+; We now reuse cached secure RRset x. DNAME . from the previous query
+; so we do not hit the bogus answer again. Of course we must get correct data
+; and not the spoofed entry.
+STEP 221202 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY NOERROR QR RD RA AD
+SECTION QUESTION
+shortloop.x.x. IN TXT
+SECTION ANSWER
+x. 3600 IN DNAME .
+x. 3600 IN RRSIG DNAME 5 1 3600 20170315140518 20170215140518 37471 . ao9vqbmh78RP84/nOaFaI/bxPk+Y/Qsknt+WWtBIY2qcPZb1I+ZCxh9g9cYo1RKQuOriAJKrHkrv9ObAc9fse/2tNM+vtjemLWIGBvPtSo3vOwZGTTwI8spvFvMa+f6wnI5Oj9Phvdk17d+FnX9nIl6NRZb84bIxUjqSuhBIMJRmSGXWM0beQqEf0PNLQBTpeI6tUXsOwtFxrnG/zGzpB/W/1whh0nSmLf39lxyA+441H2o1OjSRu6ijmVrCDwOrbb/SXj+LZTGThEcIepbVb3ol+Mft2Kff5IcIhLM9I2YfBtgRwqHmue8v6z12AA9GuXBB/xvTkwFhUOXxNbSh+w==
+shortloop.x.x. 3600 IN CNAME shortloop.x.
+shortloop.x. 3600 IN CNAME shortloop.
+shortloop. 3600 IN TXT "shortloop end"
+shortloop. 3600 IN RRSIG TXT 5 1 3600 20170315140518 20170215140518 37471 . EJaF7yRFRv01nvv6I9HYaxGukSu92cuRXHYQGTRUtj0TNVI53SmNNs89Vk+8L34vhtw+fy1e62WZ3JSat5xAVVRWVmvp220+RlF9FAYltqpPblVXKQraDACWkO31YftgI2obGqmwByAgh7yW1Kfwq6JgUzwjT8LKeove6HNMRc0jipDXXEIRsWd3I6Yjx66YewVeHU55/UrKCeeozOQ4lMJZF0OBQsmTukfq72j6wIXjrjS8vx6Dz8o3pgGy14LG8NQCKcYbQysD1tmtiDDKDbNmwDCfbu+AA3Xd1XNiQpZUjUOxQpWtOxYA/qG7nJmY9VMdoXJ2wIW91B2vv+xbxw==
+ENTRY_END
+
+STEP 221213 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+shortloop.x. TXT
+ENTRY_END
+
+; non-exact match
+; We again reuse cached secure RRset x. DNAME . from the first query
+; so we do not hit the bogus answer again. Of course we must get correct data
+; and not the spoofed entry.
+STEP 221214 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY NOERROR QR RD RA AD
+SECTION QUESTION
+shortloop.x. IN TXT
+SECTION ANSWER
+x. 3600 IN DNAME .
+x. 3600 IN RRSIG DNAME 5 1 3600 20170315140518 20170215140518 37471 . ao9vqbmh78RP84/nOaFaI/bxPk+Y/Qsknt+WWtBIY2qcPZb1I+ZCxh9g9cYo1RKQuOriAJKrHkrv9ObAc9fse/2tNM+vtjemLWIGBvPtSo3vOwZGTTwI8spvFvMa+f6wnI5Oj9Phvdk17d+FnX9nIl6NRZb84bIxUjqSuhBIMJRmSGXWM0beQqEf0PNLQBTpeI6tUXsOwtFxrnG/zGzpB/W/1whh0nSmLf39lxyA+441H2o1OjSRu6ijmVrCDwOrbb/SXj+LZTGThEcIepbVb3ol+Mft2Kff5IcIhLM9I2YfBtgRwqHmue8v6z12AA9GuXBB/xvTkwFhUOXxNbSh+w==
+shortloop.x. 3600 IN CNAME shortloop.
+shortloop. 3600 IN TXT "shortloop end"
+shortloop. 3600 IN RRSIG TXT 5 1 3600 20170315140518 20170215140518 37471 . EJaF7yRFRv01nvv6I9HYaxGukSu92cuRXHYQGTRUtj0TNVI53SmNNs89Vk+8L34vhtw+fy1e62WZ3JSat5xAVVRWVmvp220+RlF9FAYltqpPblVXKQraDACWkO31YftgI2obGqmwByAgh7yW1Kfwq6JgUzwjT8LKeove6HNMRc0jipDXXEIRsWd3I6Yjx66YewVeHU55/UrKCeeozOQ4lMJZF0OBQsmTukfq72j6wIXjrjS8vx6Dz8o3pgGy14LG8NQCKcYbQysD1tmtiDDKDbNmwDCfbu+AA3Xd1XNiQpZUjUOxQpWtOxYA/qG7nJmY9VMdoXJ2wIW91B2vv+xbxw==
+ENTRY_END
+
+; make sure all caches expired
+STEP 900000 TIME_PASSES ELAPSE 4000
+
+
+; simulate situation when DNAME expires at different time than synthetized CNAMEs
+; put only the DNAME into the cache
+STEP 900001 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+x. IN DNAME
+ENTRY_END
+
+STEP 900002 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY NOERROR QR RD RA AD
+SECTION QUESTION
+x. IN DNAME
+SECTION ANSWER
+x. 3600 IN DNAME .
+x. 3600 IN RRSIG DNAME 5 1 3600 20170315140518 20170215140518 37471 . ao9vqbmh78RP84/nOaFaI/bxPk+Y/Qsknt+WWtBIY2qcPZb1I+ZCxh9g9cYo1RKQuOriAJKrHkrv9ObAc9fse/2tNM+vtjemLWIGBvPtSo3vOwZGTTwI8spvFvMa+f6wnI5Oj9Phvdk17d+FnX9nIl6NRZb84bIxUjqSuhBIMJRmSGXWM0beQqEf0PNLQBTpeI6tUXsOwtFxrnG/zGzpB/W/1whh0nSmLf39lxyA+441H2o1OjSRu6ijmVrCDwOrbb/SXj+LZTGThEcIepbVb3ol+Mft2Kff5IcIhLM9I2YfBtgRwqHmue8v6z12AA9GuXBB/xvTkwFhUOXxNbSh+w==
+ENTRY_END
+
+;; let half of DNAME TTL pass
+STEP 900005 TIME_PASSES ELAPSE 2000
+
+; now fill cache with rest of the records from CNAME chain
+; this should renew TTL on DNAME
+STEP 900100 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+shortloop.x. TXT
+ENTRY_END
+
+STEP 900101 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY NOERROR QR RD RA AD
+SECTION QUESTION
+shortloop.x. IN TXT
+SECTION ANSWER
+x. 3600 IN DNAME .
+x. 3600 IN RRSIG DNAME 5 1 3600 20170315140518 20170215140518 37471 . ao9vqbmh78RP84/nOaFaI/bxPk+Y/Qsknt+WWtBIY2qcPZb1I+ZCxh9g9cYo1RKQuOriAJKrHkrv9ObAc9fse/2tNM+vtjemLWIGBvPtSo3vOwZGTTwI8spvFvMa+f6wnI5Oj9Phvdk17d+FnX9nIl6NRZb84bIxUjqSuhBIMJRmSGXWM0beQqEf0PNLQBTpeI6tUXsOwtFxrnG/zGzpB/W/1whh0nSmLf39lxyA+441H2o1OjSRu6ijmVrCDwOrbb/SXj+LZTGThEcIepbVb3ol+Mft2Kff5IcIhLM9I2YfBtgRwqHmue8v6z12AA9GuXBB/xvTkwFhUOXxNbSh+w==
+shortloop.x. 3600 IN CNAME shortloop.
+shortloop. 3600 IN TXT "shortloop end"
+shortloop. 3600 IN RRSIG TXT 5 1 3600 20170315140518 20170215140518 37471 . EJaF7yRFRv01nvv6I9HYaxGukSu92cuRXHYQGTRUtj0TNVI53SmNNs89Vk+8L34vhtw+fy1e62WZ3JSat5xAVVRWVmvp220+RlF9FAYltqpPblVXKQraDACWkO31YftgI2obGqmwByAgh7yW1Kfwq6JgUzwjT8LKeove6HNMRc0jipDXXEIRsWd3I6Yjx66YewVeHU55/UrKCeeozOQ4lMJZF0OBQsmTukfq72j6wIXjrjS8vx6Dz8o3pgGy14LG8NQCKcYbQysD1tmtiDDKDbNmwDCfbu+AA3Xd1XNiQpZUjUOxQpWtOxYA/qG7nJmY9VMdoXJ2wIW91B2vv+xbxw==
+ENTRY_END
+
+; let DNAME expire from cache but keep CNAMEs in cache
+STEP 900200 TIME_PASSES ELAPSE 2000
+
+; check that fake CNAME is properly validated even if DNAME if already expired
+STEP 900201 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+shortloop.x. TXT
+ENTRY_END
+
+; attacker spoofed shortloop.x. CNAME so we end up with SERVFAIL
+STEP 900202 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY SERVFAIL QR RD RA
+SECTION QUESTION
+shortloop.x. IN TXT
+SECTION ANSWER
+ENTRY_END
+
+
+; check that query for the synthetized CNAMEs does not return the fake data
+STEP 900301 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+shortloop.x. CNAME
+ENTRY_END
+
+STEP 900302 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY NOERROR QR RD RA AD
+SECTION QUESTION
+shortloop.x. IN CNAME
+SECTION ANSWER
+x. 3600 IN DNAME .
+x. 3600 IN RRSIG DNAME 5 1 3600 20170315140518 20170215140518 37471 . ao9vqbmh78RP84/nOaFaI/bxPk+Y/Qsknt+WWtBIY2qcPZb1I+ZCxh9g9cYo1RKQuOriAJKrHkrv9ObAc9fse/2tNM+vtjemLWIGBvPtSo3vOwZGTTwI8spvFvMa+f6wnI5Oj9Phvdk17d+FnX9nIl6NRZb84bIxUjqSuhBIMJRmSGXWM0beQqEf0PNLQBTpeI6tUXsOwtFxrnG/zGzpB/W/1whh0nSmLf39lxyA+441H2o1OjSRu6ijmVrCDwOrbb/SXj+LZTGThEcIepbVb3ol+Mft2Kff5IcIhLM9I2YfBtgRwqHmue8v6z12AA9GuXBB/xvTkwFhUOXxNbSh+w==
+shortloop.x. 3600 IN CNAME shortloop.
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/val_ds_afterprime.rpl b/tests/integration/deckard/sets/resolver/val_ds_afterprime.rpl
new file mode 100644
index 0000000..1d8134b
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_ds_afterprime.rpl
@@ -0,0 +1,183 @@
+do-ip6: no
+
+; config options
+; The island of trust is at example.com
+;server:
+ trust-anchor: "example.com. 3600 IN DS 15287 7 1 19F0E0DB8795AEC6205262B1E0CBF978874E2179 "
+val-override-date: "20181130121843"
+; target-fetch-policy: "0 0 0 0 0"
+; fake-sha1: yes
+
+;stub-zone:
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+query-minimization: off
+query-minimization: off
+query-minimization: off
+CONFIG_END
+
+SCENARIO_BEGIN Test DS lookup after key prime is done.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN DS
+SECTION AUTHORITY
+com. 900 IN SOA a.gtld-servers.net. nstld.verisign-grs.com. 1251367385 1800 900 604800 86400
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20181230101842 20181130101842 15287 example.com. byFJB2kc/MA/v3BaJzKJduu+yUO8CGmW5P9hJv21Ha5O2pfbWg8ykdc1 XzBuWCis2rvVoVXaurZNjaqc/WGxSHWG1MM16vz28Y3SsE3f0FouMkXe cgfoIb2S2FTF4yttMw9u7fnOCOqqar7i/bxp7y60Ep+oNrpZ5wOSr4Vv 1co= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101842 20181130101842 15287 example.com. B3wtuzeTzVA5dMZPNKhGQtI4DXkirjI4MxsBMC0MYw7LX3hBddYCHTMF DwshRpz19PHU+0neisSXxYo1PScJW46nCjixwf5gPHhKR8up1d4evM+l ciKW0FAGIBkpvrpnoSXlk6FBGvkyNdyrEdBuZxC/SWrLQizndZ+we8LQ cJc= ;{id = 2854}
+ENTRY_END
+
+; response to DNSKEY priming query
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN DNSKEY
+SECTION ANSWER
+example.com. 3600 IN DNSKEY 256 3 7 AwEAAdi6IgbGvRjV6ufAZtyfKXEV/rzEUm/zOYwcpLnpNkof20KxdX+g Tv0SJpdlbH/cRjnpIyeeKhTDfaHwG+3NXeJ01SR+tFl1sBNZOWDEu8wy htRv7Q/J+ZwzXCg4yBXSAuVzxfdyOTZK/r1HSHXeY1KJ+naBZXEPvkCY 8OqPkNSN ;{id = 2854 (zsk), size = 1688b}
+example.com. 3600 IN RRSIG DNSKEY 7 2 3600 20181230101842 20181130101842 15287 example.com. IK5CbBIOLacwoEzRk0SFvd4MV6SLh8N0muBFd4uDaZ5nllUfX9umT4iN YlkIdkeXNVGsHzo4u8oxYfg/dL1FAtuJGjRQUijngKuWP5qzj3+niDvB BDDHHrukFLteNs/taAOILuGgyccTpWLXbAyK77QbsMMVAsZH5s9Kqhws XOU= ;{id = 2854}
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20181230101842 20181130101842 15287 example.com. byFJB2kc/MA/v3BaJzKJduu+yUO8CGmW5P9hJv21Ha5O2pfbWg8ykdc1 XzBuWCis2rvVoVXaurZNjaqc/WGxSHWG1MM16vz28Y3SsE3f0FouMkXe cgfoIb2S2FTF4yttMw9u7fnOCOqqar7i/bxp7y60Ep+oNrpZ5wOSr4Vv 1co= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101842 20181130101842 15287 example.com. B3wtuzeTzVA5dMZPNKhGQtI4DXkirjI4MxsBMC0MYw7LX3hBddYCHTMF DwshRpz19PHU+0neisSXxYo1PScJW46nCjixwf5gPHhKR8up1d4evM+l ciKW0FAGIBkpvrpnoSXlk6FBGvkyNdyrEdBuZxC/SWrLQizndZ+we8LQ cJc= ;{id = 2854}
+ENTRY_END
+
+; response to query of interest
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+www.example.com. 3600 IN RRSIG A 7 3 3600 20181230101842 20181130101842 15287 example.com. IcYBBoimvXzuLUujq3+nt7mmKK6Qk1bxGi4KV0011efmrvo0voeRNb9G 5ZEPtYilUGYOKUu3PMKcCnXlPYARm4dUChaDKkjG/rCvWumVv6YgZquc YqnrMBOurMoqEeMST42v61RuLUqlQDqSdMTKoTRi4Q5EjHSpqnrzG1a3 8SY= ;{id = 2854}
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20181230101842 20181130101842 15287 example.com. byFJB2kc/MA/v3BaJzKJduu+yUO8CGmW5P9hJv21Ha5O2pfbWg8ykdc1 XzBuWCis2rvVoVXaurZNjaqc/WGxSHWG1MM16vz28Y3SsE3f0FouMkXe cgfoIb2S2FTF4yttMw9u7fnOCOqqar7i/bxp7y60Ep+oNrpZ5wOSr4Vv 1co= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101842 20181130101842 15287 example.com. B3wtuzeTzVA5dMZPNKhGQtI4DXkirjI4MxsBMC0MYw7LX3hBddYCHTMF DwshRpz19PHU+0neisSXxYo1PScJW46nCjixwf5gPHhKR8up1d4evM+l ciKW0FAGIBkpvrpnoSXlk6FBGvkyNdyrEdBuZxC/SWrLQizndZ+we8LQ cJc= ;{id = 2854}
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+www.example.com. 3600 IN RRSIG A 7 3 3600 20181230101842 20181130101842 15287 example.com. IcYBBoimvXzuLUujq3+nt7mmKK6Qk1bxGi4KV0011efmrvo0voeRNb9G 5ZEPtYilUGYOKUu3PMKcCnXlPYARm4dUChaDKkjG/rCvWumVv6YgZquc YqnrMBOurMoqEeMST42v61RuLUqlQDqSdMTKoTRi4Q5EjHSpqnrzG1a3 8SY= ;{id = 2854}
+;SECTION AUTHORITY
+;example.com. IN NS ns.example.com.
+;example.com. 3600 IN RRSIG NS 7 2 3600 20181230101842 20181130101842 15287 example.com. byFJB2kc/MA/v3BaJzKJduu+yUO8CGmW5P9hJv21Ha5O2pfbWg8ykdc1 XzBuWCis2rvVoVXaurZNjaqc/WGxSHWG1MM16vz28Y3SsE3f0FouMkXe cgfoIb2S2FTF4yttMw9u7fnOCOqqar7i/bxp7y60Ep+oNrpZ5wOSr4Vv 1co= ;{id = 2854}
+;SECTION ADDITIONAL
+;ns.example.com. IN A 1.2.3.4
+;ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101842 20181130101842 15287 example.com. B3wtuzeTzVA5dMZPNKhGQtI4DXkirjI4MxsBMC0MYw7LX3hBddYCHTMF DwshRpz19PHU+0neisSXxYo1PScJW46nCjixwf5gPHhKR8up1d4evM+l ciKW0FAGIBkpvrpnoSXlk6FBGvkyNdyrEdBuZxC/SWrLQizndZ+we8LQ cJc= ;{id = 2854}
+ENTRY_END
+
+STEP 20 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+example.com. IN DS
+ENTRY_END
+
+STEP 30 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA DO NOERROR
+SECTION QUESTION
+example.com. IN DS
+SECTION AUTHORITY
+com. 900 IN SOA a.gtld-servers.net. nstld.verisign-grs.com. 1251367385 1800 900 604800 86400
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/val_ds_cname.rpl b/tests/integration/deckard/sets/resolver/val_ds_cname.rpl
new file mode 100644
index 0000000..8dc9da9
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_ds_cname.rpl
@@ -0,0 +1,206 @@
+do-ip6: no
+
+; config options
+; The island of trust is at example.com
+;server:
+ trust-anchor: "example.com. 3600 IN DS 55850 7 1 B3DEDE56E5386B588339D978A1B173B8B10366B8 "
+val-override-date: "20181130121844"
+; target-fetch-policy: "0 0 0 0 0"
+; fake-sha1: yes
+
+;stub-zone:
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+query-minimization: off
+CONFIG_END
+
+SCENARIO_BEGIN Test validator with CNAME response to DS
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns.example.com. IN AAAA
+SECTION ANSWER
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.com. IN AAAA
+SECTION ANSWER
+; not legal NOERROR/NODATA response, but leniently accepted (not validated)
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20181230101843 20181130101843 55850 example.com. rSyN+LKU0kF6GBRW/L0R1siq0SrS0s/zOJge//1VXqRit+vtrRFjoHVa EytY4CfTZKj8YKkFnTIvKL30/Uxi2+t4uTtYLCBAnFFINRpjzuXhntiB +QWfkQruu/9NgFSb9Jb4xbSqB8khHxV3vN8lLr3WIFIAHbMWyBYmerm+ g3c= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101843 20181130101843 55850 example.com. Mi0XLYyAfzvfbudd7gfWE5aBeY5cmQVIcgoJMeduX5Z9/bWeLepyFvaW ClDqbNz59yms4xxhOKg5xLS/rzTneVk3Y1VtoiZBbr0h6fSkEYoMAk52 lWKFTjEJujKCb6rxeh9lKh7XrKELbJEC90in+0ESILIvnNfltK4aCbKS 3aY= ;{id = 2854}
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20181230101843 20181130101843 55850 example.com. rSyN+LKU0kF6GBRW/L0R1siq0SrS0s/zOJge//1VXqRit+vtrRFjoHVa EytY4CfTZKj8YKkFnTIvKL30/Uxi2+t4uTtYLCBAnFFINRpjzuXhntiB +QWfkQruu/9NgFSb9Jb4xbSqB8khHxV3vN8lLr3WIFIAHbMWyBYmerm+ g3c= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101843 20181130101843 55850 example.com. Mi0XLYyAfzvfbudd7gfWE5aBeY5cmQVIcgoJMeduX5Z9/bWeLepyFvaW ClDqbNz59yms4xxhOKg5xLS/rzTneVk3Y1VtoiZBbr0h6fSkEYoMAk52 lWKFTjEJujKCb6rxeh9lKh7XrKELbJEC90in+0ESILIvnNfltK4aCbKS 3aY= ;{id = 2854}
+ENTRY_END
+
+; response to DNSKEY priming query
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN DNSKEY
+SECTION ANSWER
+example.com. 3600 IN DNSKEY 256 3 7 AwEAAbm150kVuAzpvRlnxNCv10c1j7JIhpap2sCGfPpvMEr8jB6lxYQz GhnnnpD58hcuKwVQpptSKM+AOiyN4ZM72GWSKchxxBL8/9MBLCPY9BI8 I3d447MlB6FKnnJlN30MBUql17gIh8zAvdgGFj6tPzUkQDCHZuMASXLy 8OE2LdtL ;{id = 2854 (zsk), size = 1688b}
+example.com. 3600 IN RRSIG DNSKEY 7 2 3600 20181230101843 20181130101843 55850 example.com. LAKGmWjHK74ndtynMkRHPUTLrQJSW6me7CFTWTXtlfa1e510cFCA/0XY quFECNj6qzqUNIgsoLOv4Rox29SrvhBHBvbCt98ylWr29DPY6UofvZhC 7g5Ss89GFEzj+RV/ffdqnts1Lxpd2PGzUZIAFWwfx7h1/Jxw89Vl7YFK /3U= ;{id = 2854}
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20181230101843 20181130101843 55850 example.com. rSyN+LKU0kF6GBRW/L0R1siq0SrS0s/zOJge//1VXqRit+vtrRFjoHVa EytY4CfTZKj8YKkFnTIvKL30/Uxi2+t4uTtYLCBAnFFINRpjzuXhntiB +QWfkQruu/9NgFSb9Jb4xbSqB8khHxV3vN8lLr3WIFIAHbMWyBYmerm+ g3c= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101843 20181130101843 55850 example.com. Mi0XLYyAfzvfbudd7gfWE5aBeY5cmQVIcgoJMeduX5Z9/bWeLepyFvaW ClDqbNz59yms4xxhOKg5xLS/rzTneVk3Y1VtoiZBbr0h6fSkEYoMAk52 lWKFTjEJujKCb6rxeh9lKh7XrKELbJEC90in+0ESILIvnNfltK4aCbKS 3aY= ;{id = 2854}
+ENTRY_END
+
+; response to query of interest
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+; nothing here, not even NSECs
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20181230101843 20181130101843 55850 example.com. rSyN+LKU0kF6GBRW/L0R1siq0SrS0s/zOJge//1VXqRit+vtrRFjoHVa EytY4CfTZKj8YKkFnTIvKL30/Uxi2+t4uTtYLCBAnFFINRpjzuXhntiB +QWfkQruu/9NgFSb9Jb4xbSqB8khHxV3vN8lLr3WIFIAHbMWyBYmerm+ g3c= ;{id = 2854}
+SECTION ADDITIONAL
+ENTRY_END
+
+; DS query
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www.example.com. IN DS
+SECTION ANSWER
+www.example.com. IN CNAME zzz.example.com.
+www.example.com. 3600 IN RRSIG CNAME 7 3 3600 20181230101843 20181130101843 55850 example.com. T7yHaZwPh18N8a+6811mVm4r9MBcBMWHEnUnpKi6ZYZRrwVzLBJLB6Bz DQxg6oy5qmdWaij595a4U22vV6aX4eIROGa3vUkGE6xaiwyry/YNCDdf fCnNBpAAUcmMdnYTE8pbQi7yrR00xUjC7qYO7kzOSJ0kIhHTINrqzoZd XNw= ;{id = 2854}
+;*.example.com. IN CNAME zzz.example.com.
+;*.example.com. 3600 IN RRSIG CNAME 7 3 3600 20181230101843 20181130101843 55850 example.com. T7yHaZwPh18N8a+6811mVm4r9MBcBMWHEnUnpKi6ZYZRrwVzLBJLB6Bz DQxg6oy5qmdWaij595a4U22vV6aX4eIROGa3vUkGE6xaiwyry/YNCDdf fCnNBpAAUcmMdnYTE8pbQi7yrR00xUjC7qYO7kzOSJ0kIhHTINrqzoZd XNw= ;{id = 2854}
+
+SECTION AUTHORITY
+*.example.com. IN NSEC zzz.example.com. CNAME RRSIG NSEC
+*.example.com. 3600 IN RRSIG NSEC 7 2 86400 20181230101843 20181130101843 55850 example.com. PMydg/KuumF/r2eVJNxYyi58Ft+wPHRBYFEXyuDHtFel39O/vhvx8cWB oQvX7FhDp3LdODA056gtcpQsgGSX3sTuKdUpDnR4jdJv9XIXRxrYtGa/ MOuS/4+gE67xmEzhZ2Ezyn3IDVPfVfEiUFPqdOHukSiCyqWnjnj2rOgd kUY= ;{id = 2854}
+zzz.example.com. IN NSEC *.zzz.example.com. A RRSIG NSEC
+zzz.example.com. 3600 IN RRSIG NSEC 7 3 86400 20181230101843 20181130101843 55850 example.com. DwFmG+fJOcWCO33ulBLIifA8OHgVQd9hmCU8K4OSH+pI+25U4dSPXwBT blkuyU2/1GFD2OQnyG6EpwFYMnX/JmnNr70J8pd6xtL7EGb2n9DNrJHK 0i0fxbJffVVbn59dCuFsi8unHhOVRknG6nLaEny2S6CisVSRSs3uX7n+ P3A= ;{id = 2854}
+example.com. IN SOA alfa.ns.example.com.cz. hostmaster.example.com. 2010030800 10800 86400 604800 86400
+example.com. 3600 IN RRSIG SOA 7 2 3600 20181230101843 20181130101843 55850 example.com. JrM30NcE8xwejtIaExsewzwtN7A2rfnpn2nVJuYBKkm6xIQSgoxv0Sz2 5SuA1ilGzUr8gmgLJET+s5qSAi3ow9tkll4mcnBrruIhGJsK+3782V1f KJaFHGVWJUbfeIastg6KOImfmH1mTNIoN7g5maNIsF0qx2W05N9/LGpC CaU= ;{id = 2854}
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+zzz.example.com. IN DS
+SECTION ANSWER
+SECTION AUTHORITY
+zzz.example.com. IN NSEC *.zzz.example.com. A RRSIG NSEC
+zzz.example.com. 3600 IN RRSIG NSEC 7 3 86400 20181230101843 20181130101843 55850 example.com. DwFmG+fJOcWCO33ulBLIifA8OHgVQd9hmCU8K4OSH+pI+25U4dSPXwBT blkuyU2/1GFD2OQnyG6EpwFYMnX/JmnNr70J8pd6xtL7EGb2n9DNrJHK 0i0fxbJffVVbn59dCuFsi8unHhOVRknG6nLaEny2S6CisVSRSs3uX7n+ P3A= ;{id = 2854}
+example.com. IN SOA alfa.ns.example.com.cz. hostmaster.example.com. 2010030800 10800 86400 604800 86400
+example.com. 3600 IN RRSIG SOA 7 2 3600 20181230101843 20181130101843 55850 example.com. JrM30NcE8xwejtIaExsewzwtN7A2rfnpn2nVJuYBKkm6xIQSgoxv0Sz2 5SuA1ilGzUr8gmgLJET+s5qSAi3ow9tkll4mcnBrruIhGJsK+3782V1f KJaFHGVWJUbfeIastg6KOImfmH1mTNIoN7g5maNIsF0qx2W05N9/LGpC CaU= ;{id = 2854}
+SECTION ADDITIONAL
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA DO SERVFAIL
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/val_ds_cnamesub.rpl b/tests/integration/deckard/sets/resolver/val_ds_cnamesub.rpl
new file mode 100644
index 0000000..6c53c2f
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_ds_cnamesub.rpl
@@ -0,0 +1,279 @@
+do-ip6: no
+
+; config options
+; The island of trust is at example.com
+;server:
+ trust-anchor: "example.com. 3600 IN DS 33632 7 1 5497C677E6B860E0BC545C7D559AC3402095D6D1 "
+val-override-date: "20181130121845"
+; target-fetch-policy: "0 0 0 0 0"
+; fake-sha1: yes
+
+;stub-zone:
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+query-minimization: off
+CONFIG_END
+
+SCENARIO_BEGIN Test validator with CNAME response to DS in chain of trust
+; the CNAME is at a nonempty nonterminal name in the parent zone.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+net. IN A
+SECTION AUTHORITY
+net. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns.example.com. IN AAAA
+SECTION ANSWER
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR AA NOERROR
+SECTION QUESTION
+example.net. IN A
+SECTION AUTHORITY
+example.net. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.net. IN A 1.2.3.6
+ENTRY_END
+
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.com. IN AAAA
+SECTION ANSWER
+; not legal NOERROR/NODATA response, but leniently accepted (not validated)
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20181230101845 20181130101845 33632 example.com. KltuV+6jsjOXtJMKJapjnppUaOZRfkShElT2nsKnwMK4h2K3h7/BteWG JtuSF43IlDDGgifXDXpfEU+ITQyT4Oqa6ruzVDV8s6oRw1rKlAXMTT5a vmRhjoOw0qUJ5gc46QkLPGfsjTib5x61geF/fx+G/U0+b35W2rqj29jo vPc= ;{id = 2854}
+;example.com. IN SOA alfa.ns.example.com.cz. hostmaster.example.com. 2010030800 10800 86400 604800 86400
+;example.com. 3600 IN RRSIG SOA 3 2 3600 20070926134150 20070829134150 2854 example.com. ADsxLOHjxFzwFmwIiGOubqD9nKWAp4RccRIXQ0+EAUGfSDZMCB0ZiFA= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101845 20181130101845 33632 example.com. NcdCcqG4gcDU808aZADHpHjkuo7O2j2t9UVQ9KycVPClncUyqMzxmAPy BjsG3MVr0y/H2Q6GT+IpDwK7L8CvLS2hUzczIDhAY2f2N3KATcfuNbYr 9BKenU0KgSPCunIpPGCFJSMfgaC8L30Uk/ilPSAJfwAsVbzu7qQPbftN T3M= ;{id = 2854}
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20181230101845 20181130101845 33632 example.com. KltuV+6jsjOXtJMKJapjnppUaOZRfkShElT2nsKnwMK4h2K3h7/BteWG JtuSF43IlDDGgifXDXpfEU+ITQyT4Oqa6ruzVDV8s6oRw1rKlAXMTT5a vmRhjoOw0qUJ5gc46QkLPGfsjTib5x61geF/fx+G/U0+b35W2rqj29jo vPc= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101845 20181130101845 33632 example.com. NcdCcqG4gcDU808aZADHpHjkuo7O2j2t9UVQ9KycVPClncUyqMzxmAPy BjsG3MVr0y/H2Q6GT+IpDwK7L8CvLS2hUzczIDhAY2f2N3KATcfuNbYr 9BKenU0KgSPCunIpPGCFJSMfgaC8L30Uk/ilPSAJfwAsVbzu7qQPbftN T3M= ;{id = 2854}
+ENTRY_END
+
+; response to DNSKEY priming query
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN DNSKEY
+SECTION ANSWER
+example.com. 3600 IN DNSKEY 256 3 7 AwEAAc9yX6nFxFJ1PsA6b4GsM4jKCqA3cHZn6sbszgw57mXD8g/Amn21 +tYDBzdJwv6SspmXhLO8UPJ8C1+6zoW2CZuKTIp8mjUimWLOaJjl/IlZ 2BAFoSSBsyJSr8619eqQxVH4guLIAO1wzK5lcQSFpiLXh7/hDdpDciCR M8Y9PmZd ;{id = 2854 (zsk), size = 1688b}
+example.com. 3600 IN RRSIG DNSKEY 7 2 3600 20181230101845 20181130101845 33632 example.com. ioMECLagEkWue617lYuaQl4KgRURblcPcoc/4uhapKgY0ZTYGH42SQ/Z 7ez9ViwMi4IpP6DS8QNOEnaVd8EHjPOMRPvwiPIoUPbqzz/3KlaZgMOg FhhgfLzMPORsvDqPT7mJ2QGsqc4WhUAawSOyhytDCauK2TO50Oi/UpQt FwY= ;{id = 2854}
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20181230101845 20181130101845 33632 example.com. KltuV+6jsjOXtJMKJapjnppUaOZRfkShElT2nsKnwMK4h2K3h7/BteWG JtuSF43IlDDGgifXDXpfEU+ITQyT4Oqa6ruzVDV8s6oRw1rKlAXMTT5a vmRhjoOw0qUJ5gc46QkLPGfsjTib5x61geF/fx+G/U0+b35W2rqj29jo vPc= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101845 20181130101845 33632 example.com. NcdCcqG4gcDU808aZADHpHjkuo7O2j2t9UVQ9KycVPClncUyqMzxmAPy BjsG3MVr0y/H2Q6GT+IpDwK7L8CvLS2hUzczIDhAY2f2N3KATcfuNbYr 9BKenU0KgSPCunIpPGCFJSMfgaC8L30Uk/ilPSAJfwAsVbzu7qQPbftN T3M= ;{id = 2854}
+ENTRY_END
+
+; response to DS query for a.example.com, a CNAME
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+a.example.com. IN DS
+SECTION ANSWER
+a.example.com. IN CNAME zzz.example.net.
+a.example.com. 3600 IN RRSIG CNAME 7 3 3600 20181230101845 20181130101845 33632 example.com. aV8SmzDUh1bLt0FEiUKIC7BZKdzTB+TcpraOLn5CSwIFsnG/2itqavJo u2BEYP0Hay1AYeBwhA7/LJaqa4WVZUl02ExlsrNc8qxTFvs+qhNtR9fG vXCB4PrwWlABaD4/T2Uvc98+cFArn6o8JMONZIWzg8yuRkNDo9hxWHEI XR4=
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+; response to DS query for sub.a.example.com.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+sub.a.example.com. IN DS
+SECTION ANSWER
+sub.a.example.com. 3600 IN DS 32886 7 1 05B70AC8C521B130A865EDE411A06135C5BC49E2
+sub.a.example.com. 3600 IN RRSIG DS 7 4 3600 20181230101845 20181130101845 33632 example.com. YX6ThbV357iGXSf8J/D67wCUf6YQWO3cQnrX46Ws6mbtVqDPTryLUM5D h+UHJyQZRb5uI8cc/l9H2JGbhK1GoeI0vpPj+MBVHuDIIwlZIH6KjXAx tp2V8Wrq6Po4Gr3ZQrRCRKdR7kDiUbUzSRSZ1wVBpWFDvHPUQd5Vli2m ntU=
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+; delegation down
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+sub.a.example.com. IN NS
+SECTION ANSWER
+SECTION AUTHORITY
+sub.a.example.com. 3600 IN DS 32886 7 1 05B70AC8C521B130A865EDE411A06135C5BC49E2
+sub.a.example.com. 3600 IN RRSIG DS 7 4 3600 20181230101845 20181130101845 33632 example.com. YX6ThbV357iGXSf8J/D67wCUf6YQWO3cQnrX46Ws6mbtVqDPTryLUM5D h+UHJyQZRb5uI8cc/l9H2JGbhK1GoeI0vpPj+MBVHuDIIwlZIH6KjXAx tp2V8Wrq6Po4Gr3ZQrRCRKdR7kDiUbUzSRSZ1wVBpWFDvHPUQd5Vli2m ntU=
+sub.a.example.com. IN NS ns.sub.a.example.com.
+SECTION ADDITIONAL
+ns.sub.a.example.com. IN A 1.2.3.5
+ENTRY_END
+RANGE_END
+
+; ns.sub.a.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.5
+
+; DNSKEY query
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+sub.a.example.com. IN DNSKEY
+SECTION ANSWER
+sub.a.example.com. 3600 IN DNSKEY 257 3 7 AwEAAbNmn9l9d8I1+gHbWag6QBE0tXQs7mZL+H3jB8qWaQRa5cYgFAah aQ/93LsJZK1i5Bk6dkmUcVxuKlTwP3nHp1HBoG66A8DdRmUfqWQy1hZ4 oMGcnoqXCy8+8q61JPhtpYQoiHR/Jwy7+RjrVtUr2LCwtO2S8r//YJZF D4R6KdtH ;{id = 57024 (ksk), size = 1024b}
+sub.a.example.com. 3600 IN RRSIG DNSKEY 7 4 3600 20181230101844 20181130101844 32886 sub.a.example.com. k/zVTR2I9Xg8tIksStQ2JJDQuPjA3RFuYUbJ8nyzLtIL+Hpn2Sv4G2zl NuHSWGcuSZPe6fNzBHEg6faRLCgtfHxPLcgt+OSA6KSOj7iUjcaB8ap9 cKgemoj/njtcj/vDj0KoJWI0MHCDu5jAK1ZYsYouB3hTWBX0wFN/Mj2j H34=
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+; query of interest
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www.sub.a.example.com. IN A
+SECTION ANSWER
+www.sub.a.example.com. IN A 10.20.30.40
+www.sub.a.example.com. 3600 IN RRSIG A 7 5 3600 20181230101844 20181130101844 32886 sub.a.example.com. Brrsf7sDDtwR/oga9dwwIAAMjQrfVxNdpnrj1N/KNafuCm7/YIEjoLXp ftRwHF7j083djazS2ud2vTckxo1GKXbPIs4/G0ACwu6bCwuL9BimGnhj 0fdLE6WzALExHwVu/HTR0d0JvitdnmwuIZLtJXbAA04jO3wYtZx3Dler YDU=
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+RANGE_END
+
+; ns.example.net.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.6
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+zzz.example.net. IN DS
+SECTION ANSWER
+SECTION AUTHORITY
+example.net. IN SOA root. host. 1 2 3 4 5
+SECTION ADDITIONAL
+ENTRY_END
+RANGE_END
+
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.sub.a.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+www.sub.a.example.com. IN A
+SECTION ANSWER
+www.sub.a.example.com. 3600 IN A 10.20.30.40
+www.sub.a.example.com. 3600 IN RRSIG A 7 5 3600 20181230101844 20181130101844 32886 sub.a.example.com. Brrsf7sDDtwR/oga9dwwIAAMjQrfVxNdpnrj1N/KNafuCm7/YIEjoLXp ftRwHF7j083djazS2ud2vTckxo1GKXbPIs4/G0ACwu6bCwuL9BimGnhj 0fdLE6WzALExHwVu/HTR0d0JvitdnmwuIZLtJXbAA04jO3wYtZx3Dler YDU=
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/val_faildnskey.rpl b/tests/integration/deckard/sets/resolver/val_faildnskey.rpl
new file mode 100644
index 0000000..f99d235
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_faildnskey.rpl
@@ -0,0 +1,173 @@
+do-ip6: no
+
+; config options
+; The island of trust is at example.com
+;server:
+ trust-anchor: "example.com. 3600 IN DS 2854 3 1 46e4ffc6e9a4793b488954bd3f0cc6af0dfb201b"
+ val-override-date: "20070916134226"
+; target-fetch-policy: "0 0 0 0 0"
+ # test that default value of harden-dnssec-stripped is still yes.
+; fake-sha1: yes
+
+;stub-zone:
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+;test from testbound
+
+SCENARIO_BEGIN Test validator with failed DNSKEY request
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854}
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.com. IN A
+SECTION ANSWER
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854}
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
+ENTRY_END
+
+; response to DNSKEY priming query
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+;REPLY QR AA NOERROR
+REPLY QR AA SERVFAIL
+SECTION QUESTION
+example.com. IN DNSKEY
+SECTION ANSWER
+;example.com. 3600 IN DNSKEY 256 3 3 ALXLUsWqUrY3JYER3T4TBJII s70j+sDS/UT2QRp61SE7S3E EXopNXoFE73JLRmvpi/UrOO/Vz4Se 6wXv/CYCKjGw06U4WRgR YXcpEhJROyNapmdIKSx hOzfLVE1gqA0PweZR8d tY3aNQSRn3sPpwJr6Mi /PqQKAMMrZ9ckJpf1+b QMOOvxgzz2U1GS18b3y ZKcgTMEaJzd/GZYzi/B N2DzQ0MsrSwYXfsNLFO Bbs8PJMW4LYIxeeOe6rUgkWOF 7CC9Dh/dduQ1QrsJhmZAEFfd6ByYV+ ;{id = 2854 (zsk), size = 1688b}
+;example.com. 3600 IN RRSIG DNSKEY 3 2 3600 20070926134802 20070829134802 2854 example.com. MCwCFG1yhRNtTEa3Eno2zhVVuy2EJX3wAhQeLyUp6+UXcpC5qGNu9tkrTEgPUg== ;{id = 2854}
+;SECTION AUTHORITY
+;example.com. IN NS ns.example.com.
+;example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
+;SECTION ADDITIONAL
+;ns.example.com. IN A 1.2.3.4
+;ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854}
+ENTRY_END
+
+; response to query of interest
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCQMyTjn7WWwpwAR1LlVeLpRgZGuQIUCcJDEkwAuzytTDRlYK7nIMwH1CM= ;{id = 2854}
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+www.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFC99iE9K5y2WNgI0gFvBWaTi9wm6AhUAoUqOpDtG5Zct+Qr9F3mSdnbc6V4= ;{id = 2854}
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.com. IN AAAA
+SECTION ANSWER
+ENTRY_END
+
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA DO SERVFAIL
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/val_iter_high.rpl b/tests/integration/deckard/sets/resolver/val_iter_high.rpl
new file mode 100644
index 0000000..179eda3
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_iter_high.rpl
@@ -0,0 +1,239 @@
+do-ip6: no
+
+query-minimization: off
+; config options
+; The island of trust is at example.com
+;server:
+ trust-anchor: "example.com. 86400 IN DS 56216 13 2 60E5A8A0A2959A0E65A79A6C149FF5E1D68C866C5F5462DB21032AF5185B728A"
+val-override-date: "20210501000000"
+; target-fetch-policy: "0 0 0 0 0"
+; fake-sha1: yes
+
+;stub-zone:
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+query-minimization: off
+CONFIG_END
+
+SCENARIO_BEGIN Test validating NSEC3 with too many iterations
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+K.ROOT-SERVERS.NET. IN A
+SECTION ANSWER
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+a.gtld-servers.net. IN A
+SECTION ANSWER
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns1.example.com.
+SECTION ADDITIONAL
+ns1.example.com. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+; ns1.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+;;; Generated by starting knotd with this simple zone file and then querying it with kdig.
+;$ORIGIN example.com.
+;$TTL 86400
+;@ SOA ns1.example.com. hostmaster.example.com. (
+; 1 ; serial
+; 21600 ; refresh after 6 hours
+; 3600 ; retry after 1 hour
+; 604800 ; expire after 1 week
+; 86400 ) ; minimum TTL of 1 day
+;@ NS ns1.example.com.
+;ns1.example.com. A 1.2.3.4
+;*.wild.example.com. TXT "wildcard"
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. 86400 NS ns1.example.com.
+example.com. 86400 RRSIG NS 13 2 86400 20210514155807 20210430142807 28964 example.com. k80kgr7N/MPVZhv4MT8CqEQBUG1Oth9buWh6d7nwO64DR7f7WJnH1yvBeQcFSXBxQcv/f0V8SJzqdcD6EmWzsw==
+SECTION ADDITIONAL
+ns1.example.com. 86400 A 1.2.3.4
+ns1.example.com. 86400 RRSIG A 13 3 86400 20210514155807 20210430142807 28964 example.com. sGykdbHcEy4gnMAhIu4KGA96KS5hZKNM/C3yr61gyOOqgkV+6nAzuLBYvGxe4AexM/qA/Zpv0IyLg7bi9iufhg==
+ENTRY_END
+
+; response to DNSKEY priming query
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+example.com. IN DNSKEY
+SECTION ANSWER
+example.com. 86400 DNSKEY 256 3 13 MN1ctIwG9m3p1fuH3Vn18XFLz4k6TUy1uXg/BF+7i+NrMkfbm4PLhhWflVElgowiQv/2103uHcW7a78ZaNP44g==
+example.com. 86400 DNSKEY 257 3 13 d7yF/Xsdi0i8bUwN8FyCOIu9XGuoVlyuW2ZtVXEfdfwDpJxoHPjG3DImr8iLK2PMu75SMqj8+nwsP9dHiKYo9A==
+example.com. 86400 RRSIG DNSKEY 13 2 86400 20210514155807 20210430142807 56216 example.com. BiPljLSmTP+uY5YrQ9mzxZhDsE33Bz3tBZaED8O+U3bmAfXNnZ1h8yN0FqOrJ7iRxmfK3ffNIgl3eANYi29z7A==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns1.example.com. IN A
+SECTION ANSWER
+ns1.example.com. 86400 A 1.2.3.4
+ns1.example.com. 86400 RRSIG A 13 3 86400 20210514155807 20210430142807 28964 example.com. sGykdbHcEy4gnMAhIu4KGA96KS5hZKNM/C3yr61gyOOqgkV+6nAzuLBYvGxe4AexM/qA/Zpv0IyLg7bi9iufhg==
+ENTRY_END
+
+; response to the simple query of interest
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR AA NXDOMAIN
+SECTION QUESTION
+nxdomain.example.com. IN A
+SECTION AUTHORITY
+example.com. 86400 SOA ns1.example.com. hostmaster.example.com. 3 21600 3600 604800 86400
+1cl7h356uun3lupr5ul5ok6puohj998d.example.com. 86400 NSEC3 1 0 65535 D7F1DC453FCD0B67 cf2t29nn8sqbpn6p9d1euo8k1emtvg6d NS SOA RRSIG DNSKEY NSEC3PARAM CDS CDNSKEY
+cf2t29nn8sqbpn6p9d1euo8k1emtvg6d.example.com. 86400 NSEC3 1 0 65535 D7F1DC453FCD0B67 marb4pbbo27u50b2jb062rmee7hu5h0d
+example.com. 86400 RRSIG SOA 13 2 86400 20210514161125 20210430144125 28964 example.com. cepCaZukRNjqLn52iIiH3I7C9MzosmjOaBNIgcmre8owxYyUC0Ur/lkNt0PVIGYYNGq0ZxstynleoZfebu+Hag==
+1cl7h356uun3lupr5ul5ok6puohj998d.example.com. 86400 RRSIG NSEC3 13 3 86400 20210514161125 20210430144125 28964 example.com. +L2sxEcpXKOurY/KM5jL3WsaoNl3fuQYSfkF0hat/Qi7cVCFMmVVPa5nuuAaE4L6dYDyuVnJ7CkSZaJD0cYQXA==
+cf2t29nn8sqbpn6p9d1euo8k1emtvg6d.example.com. 86400 RRSIG NSEC3 13 3 86400 20210514161125 20210430144125 28964 example.com. I8qbPSgWDvKstK2b1QZs9ukdih1+mYLmdtZg+Y4gLJscpSgss8Ydz8L8jyvNTb079QwajT5FKPHRHJxGZZiCkQ==
+ENTRY_END
+
+; response to the wildcard query of interest
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR AA NOERROR
+SECTION QUESTION
+foo.wild.example.com. IN TXT
+SECTION ANSWER
+foo.wild.example.com. 86400 TXT "wildcard"
+foo.wild.example.com. 86400 RRSIG TXT 13 3 86400 20210514161125 20210430144125 28964 example.com. sN/uAISiZueMg3yoRqnHpRw5Qayb0HDxht8XVvyY/C1H/DO6cBvyskTyBIU7S1B+hIOvaIKUAqd9D1+VIr58bA==
+SECTION AUTHORITY
+ti6egnlv8nsi9js84c1mv3ec7sq4293g.example.com. 86400 NSEC3 1 0 65535 D7F1DC453FCD0B67 1cl7h356uun3lupr5ul5ok6puohj998d TXT RRSIG
+ti6egnlv8nsi9js84c1mv3ec7sq4293g.example.com. 86400 RRSIG NSEC3 13 3 86400 20210514161125 20210430144125 28964 example.com. zeA5x5Fcqcvqq8deQT93Fa8ZOtgLA+zIZ/uKED5e4vjtNEg5cCJ6/4+YM4/ztwYnkSzkkKbzrzF7qanJNSlk3w==
+ENTRY_END
+RANGE_END
+
+
+STEP 10 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+ns1.example.com. IN A
+ENTRY_END
+
+; recursion happens here
+STEP 11 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA AD NOERROR
+SECTION QUESTION
+ns1.example.com. IN A
+SECTION ANSWER
+ns1.example.com. 86400 IN A 1.2.3.4
+ENTRY_END
+
+; now simple non-existing entry
+STEP 21 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+nxdomain.example.com. IN A
+ENTRY_END
+
+; it should get downgraded
+STEP 22 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NXDOMAIN
+SECTION QUESTION
+nxdomain.example.com. IN A
+SECTION AUTHORITY
+example.com. 86400 IN SOA ns1.example.com. hostmaster.example.com. 3 21600 3600 604800 86400
+ENTRY_END
+
+; more difficult: positive wildcard expansion
+STEP 31 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+foo.wild.example.com. IN TXT
+ENTRY_END
+
+STEP 32 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+foo.wild.example.com. IN TXT
+SECTION ANSWER
+foo.wild.example.com. 86400 TXT "wildcard"
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/val_mal_wc.rpl b/tests/integration/deckard/sets/resolver/val_mal_wc.rpl
new file mode 100644
index 0000000..15a2a7c
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_mal_wc.rpl
@@ -0,0 +1,153 @@
+do-ip6: no
+
+; config options
+; The island of trust is at example.com
+;server:
+ trust-anchor: "example.com. 3600 IN DS 16907 7 1 15491CE8EE9AC1D17E48D226C0460219546181CD "
+val-override-date: "20181130121851"
+; target-fetch-policy: "0 0 0 0 0"
+; fake-sha1: yes
+
+;stub-zone:
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+query-minimization: off
+CONFIG_END
+
+SCENARIO_BEGIN Test validator with nodata, wildcards and ENT
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+b.example.com. IN DS
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+b.example.com. IN DS
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20181230101851 20181130101851 16907 example.com. KXsKhCme80OQl4qekE+q0KvymkhEelk+OdOsajCsGmfG5eeCEkN58gVw 5fBgtR2Ekp15KLsV1elsyVL8i7W5Hp5f2G70/plqSQ+78n3Al5jXONgN oVFSOuf8N179F2uf3k20MpnlxQQ7W/VX6SpuAOejyVpp6il6dm2YwRHH nX4= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101851 20181130101851 16907 example.com. KqDPciNi+sv+8MOP2P0C3qWpFCHjw8eu213ztGMvVDZsEvJLz9QRXkgI XuwhZIEUiKaV9C7jG+aMyOc1amX0Uo8kp+UXuL5k43gjSi0PbhO72aTG QSOZV4S1/Pa/ZN/phWItlN18HGWqBQvx26K16AzziwQvVuL7nUmu/KUj MIY= ;{id = 2854}
+ENTRY_END
+
+; response to DNSKEY priming query
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN DNSKEY
+SECTION ANSWER
+example.com. 3600 IN DNSKEY 256 3 7 AwEAAef0Gt81KzrbFGbFmk6VeEzLLcRbnKiDjdMBO7R+HsQWCO9YpPGx 20mBEV7ISCLva+LZulf584i30ga7qMeVsarsdh9xCYtyMXd4Ex5nMEXx V9f2Or+FjihPduL2TnAlWpvL8oc1oKVI2RISTT1yf8IYy6X/FpfmMP81 9WBN2Kit ;{id = 2854 (zsk), size = 1688b}
+example.com. 3600 IN RRSIG DNSKEY 7 2 3600 20181230101851 20181130101851 16907 example.com. RPXAcaVjBdtk/geHTdTg9ZOKREpAdjZAopRE/5Kk9fdFYQWwg0uRxexL PJ11jXjnp9MKOp1FehctyvE/mm1lB/J6+YepHu3tRAzzJ9YfjVxJjUpp Qv/nA/fU55MHWYhdhXwKn7F+PXD8+MFlAqPyFz9mYZEO89lI4P2/Wf4x pv4= ;{id = 2854}
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20181230101851 20181130101851 16907 example.com. KXsKhCme80OQl4qekE+q0KvymkhEelk+OdOsajCsGmfG5eeCEkN58gVw 5fBgtR2Ekp15KLsV1elsyVL8i7W5Hp5f2G70/plqSQ+78n3Al5jXONgN oVFSOuf8N179F2uf3k20MpnlxQQ7W/VX6SpuAOejyVpp6il6dm2YwRHH nX4= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101851 20181130101851 16907 example.com. KqDPciNi+sv+8MOP2P0C3qWpFCHjw8eu213ztGMvVDZsEvJLz9QRXkgI XuwhZIEUiKaV9C7jG+aMyOc1amX0Uo8kp+UXuL5k43gjSi0PbhO72aTG QSOZV4S1/Pa/ZN/phWItlN18HGWqBQvx26K16AzziwQvVuL7nUmu/KUj MIY= ;{id = 2854}
+ENTRY_END
+
+; response to query of interest
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+b.example.com. IN DS
+SECTION ANSWER
+SECTION AUTHORITY
+example.com. 86394 IN SOA NS.IANA.ORG. NSTLD.IANA.ORG. 2007092000 1800 900 604800 86400
+example.com. 86394 IN RRSIG SOA 7 2 86394 20181230101851 20181130101851 16907 example.com. uQjgfvlcxQLPfqetqWjTgKTbDOK3BoqbdmrqudrEl/X/S3OR8uhTQu7P EsrJm7IP7lmKcsbF4LAFjBNRp28G4at8v5cnCpvZfKFDzO3JzCubaVnn 18rSZj9gM1e4CN5ms/aAlr5I2hDhIQnsKmhxQBTrngyTcpGgf/YQuruM RKw= ;{id = 2854}
+
+; note that b.example.com. is an empty nonterminal
+*.example.com. 3600 IN NSEC *.b.example.com. A MX RRSIG NSEC
+*.example.com. 3600 IN RRSIG NSEC 7 2 86400 20181230101851 20181130101851 16907 example.com. 5NyjMTv7p0jvYrfxQzTJXvTlf1Uy2tMSmYKEWZoBq87u6mLNBtRgpKl9 1gpVvT8o+uA2XAznujnFZYgLdE9Swk87KqQQSWkyM81458SuSVwB5hma 9afCrB38FH9D9aOCN1nfqIuoEsQi3Bu3Uvtr+eV7oE97ViROSy/1pyyK g9A= ;{id = 2854}
+
+SECTION ADDITIONAL
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+b.example.com. IN DS
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+b.example.com. IN DS
+SECTION ANSWER
+SECTION AUTHORITY
+example.com. 86394 IN SOA NS.IANA.ORG. NSTLD.IANA.ORG. 2007092000 1800 900 604800 86400
+example.com. 86394 IN RRSIG SOA 7 2 86394 20181230101851 20181130101851 16907 example.com. uQjgfvlcxQLPfqetqWjTgKTbDOK3BoqbdmrqudrEl/X/S3OR8uhTQu7P EsrJm7IP7lmKcsbF4LAFjBNRp28G4at8v5cnCpvZfKFDzO3JzCubaVnn 18rSZj9gM1e4CN5ms/aAlr5I2hDhIQnsKmhxQBTrngyTcpGgf/YQuruM RKw= ;{id = 2854}
+*.example.com. 3600 IN NSEC *.b.example.com. A MX RRSIG NSEC
+*.example.com. 3600 IN RRSIG NSEC 7 2 86400 20181230101851 20181130101851 16907 example.com. 5NyjMTv7p0jvYrfxQzTJXvTlf1Uy2tMSmYKEWZoBq87u6mLNBtRgpKl9 1gpVvT8o+uA2XAznujnFZYgLdE9Swk87KqQQSWkyM81458SuSVwB5hma 9afCrB38FH9D9aOCN1nfqIuoEsQi3Bu3Uvtr+eV7oE97ViROSy/1pyyK g9A= ;{id = 2854}
+SECTION ADDITIONAL
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/val_minimal_anotherdomainsignature.rpl b/tests/integration/deckard/sets/resolver/val_minimal_anotherdomainsignature.rpl
new file mode 100644
index 0000000..a1cb63e
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_minimal_anotherdomainsignature.rpl
@@ -0,0 +1,99 @@
+ trust-anchor: ". IN DS 49060 8 2 E7B1EB56D7D5791B3D45630FEAA9C823DB84B385ACEEAC5F44DD08885C36700F"
+ val-override-date: "20170401000000"
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+ query-minimization: off
+CONFIG_END
+
+SCENARIO_BEGIN Signature belongs to another domain.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ ADDRESS 2001:7fd::1
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. 518400 IN NS k.root-servers.net.
+. 518400 IN RRSIG NS 8 0 518400 20170409093827 20170310093827 20661 . uBuJpbRh1NYVciSKK0r3SA6NFnqE4s/+CqLfTXu26/HrY5c1aOhQHXZM cCDDjfPGFa7Eh4mqF0i9I+i+bFbYQitI1Heexye599VE19REbVsK4qaU xkArvt9k6HVqd/7BXXUyzLN1N0CScdyuT5tiEI9154SDNVpnC+z8i2u0 9hW8JEk4qqVWX/I1MYQB/UOcFSeDhD1Qku/26opqDuLl/1eaShxhMQ/c rjzOb5ZYzD0x+TUJZMYSOMwAraaFuYTT84oe6QYY+EGctAk1b50nA/5E C3Tm/xGuo9ioVtYhTwoo1XDUVeHmghdILjQZvR4pOSZoRGGP9ovb08Qg OmPXuQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+. IN DNSKEY
+SECTION ANSWER
+. IN DNSKEY 256 3 8 AwEAAe1oA46eOLNris1CtS0qM5TdMESK6i4hpalqa6JDv57eOUkaOeje ZW1tIFUokmaK7kuKEFEosddA89CYM8rt2RbC+sfKalbHAWOus0tXZyAL efb2sW95QRzyG6LNul0jQFn9eYWBUHrVe5Wqd0zrFCbTQLUhELSfrlkI UBpO/xKaGinRHX2JjyOnle4aPZY3bEVa/+KyY2ZU6UC4SBo3aHXanP26 ok91rOTmpTWp64ybsMdCXOU8deyuQFQf6q8DhIDmJrkymhX1MXWQQlE0 fAYIYf8/t9OCwucg8oEg4FPU8Gb4Zm/l6PgO4HFkFjBT6iGFCQt3qXe2 Qe3alUWoATc=
+. IN DNSKEY 257 3 8 AwEAAb8sZgVVa02muJ+/+SVhJAvz2EWKGEGquhPbQXuF6ALBYoF4KWTO bZVF8sIVTGoaX5+UWkwwHthg7RwS1DALT/AJymYeHhUwA04gLsfCZ/cv BjmRy5RozeSJ1uxAhoCYHCT2hQBZ0cH0n8roXFXI2Y+6708pO1IBkTPT 9MpAGfezTtGYOortbSn+vqT/Zu8jOpNwkleXON4rlZRBZPd4JUMGL9Y5 N/j6+ClYeM+eFQTKXrLi1oC+0yK1sG5OlqrBDhAhBnz+IhfZz4TOkqJ9 Li2BVMatHBeB9GQHtu0FZuC3J0EQgiZxvq1RgkefFJAiB+5uVRN8U7up 5mLDxSgmT0M=
+. 2592000 IN RRSIG DNSKEY 8 0 3600000 20170409093827 20170310093827 49060 . G7s3QiWNgOsl+LoG6OKjdBHPcFyhmCS17GFnaKjfJNdPQaFL5nM/vrXo eUIIdJXAvjj62TY7wTyFlnx3yjK93RVGKEEySpGC/1gkn5AdjVoQszog IxYjKzubizULSaX7SQ3/Ar+uHLxakdS1qgNdFu6hHCl857LJPtmC8SJt iFUmm5HFyARokMrfA88VrFRKEqojcCWajeZMfRtgBipFJZoYgPUCaFlz 8OupNdNUWCbGhnDWrXCWMzeKVXTQVlJf75PXXgtkuBUmr5RSWu7AYr+c wTJ4E4610goRqYxnZ33efKE/MuhKeY66xelPh0sirPrBMR5JAlyjV3k1 qDzhcQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+k.root-servers.net. IN AAAA
+SECTION ANSWER
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+k.root-servers.net. 2592000 IN RRSIG AAAA 8 3 3600000 20170409093827 20170310093827 20661 . qjVXwuxzmoRhdrXyQvKfrrzFxGiYuTTJHxwZPasJ1nVmN48dPyU6wA55 JeqoJv1Jm+XvIL1q0WtX6Zh6KLt6vVjHuMkhmFuIZYkFi/dmsEwFY8C0 ebyXyztQT5+6FOSVTAKacYc40LfBo8FqEn8RYlCu1mkAd8ANvvLrdLWW W03LVOY7JlCzyrKlAlmPmuV8z+e9PxNkUh6KfTEvAReoAAX7wYZkdefg 2d64c7rNWXvYm6LxBX6qeQ39d5WyKc8v+G01DJuDzs2Tx368QoK86vm/ qo9ERdT7koRt+gBZNYv8V4fh2SjaFsy2TJq/tiYcSia9snGDTFj6LWVM 6sBCYQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+k.root-servers.net. IN A
+SECTION ANSWER
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 2592000 IN RRSIG A 8 3 3600000 20170409093827 20170310093827 20661 . feIXXjskcsyH+ALZu67GVDaPWXjUGTWsTlDwzgJcLBzSuRVY/GVD5Z1Q B4/oUW99rLKB5bNS1MuasZ+nZFV67sBwJk1+SqNB2bAe7G5Tv1sR2Qgi qDAoB37YDVk5JGHfuxByLYbAVG9PrPXT60BN17OYrD/TFPzprye65gk3 7l9kPpAlblcsqdvh5piKrWc7VBcyMhlp56qdASNAl+Lrb+i0DZYyJXh+ b8LV5g5zp9FaVGKe0Gi4+yDXVjcM6VEtuNRAu2+flLoc3ho6qQF1Po4Y wueL72I+yFoUxkIOJvK47eWb+YUBIBK/L8/ORjYoLBRsrbc79wb0I3Zj Xy6O4Q==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+x.root-servers.net. IN A
+SECTION ANSWER
+x.root-servers.net. 3600000 IN A 193.0.14.129
+x.root-servers.net. 2592000 IN RRSIG A 8 3 3600000 20170409093827 20170310093827 20661 . feIXXjskcsyH+ALZu67GVDaPWXjUGTWsTlDwzgJcLBzSuRVY/GVD5Z1Q B4/oUW99rLKB5bNS1MuasZ+nZFV67sBwJk1+SqNB2bAe7G5Tv1sR2Qgi qDAoB37YDVk5JGHfuxByLYbAVG9PrPXT60BN17OYrD/TFPzprye65gk3 7l9kPpAlblcsqdvh5piKrWc7VBcyMhlp56qdASNAl+Lrb+i0DZYyJXh+ b8LV5g5zp9FaVGKe0Gi4+yDXVjcM6VEtuNRAu2+flLoc3ho6qQF1Po4Y wueL72I+yFoUxkIOJvK47eWb+YUBIBK/L8/ORjYoLBRsrbc79wb0I3Zj Xy6O4Q==
+ ; valid signature of k.root-servers.net IN A
+ENTRY_END
+
+; QTYPE == RRSIG is not supported, https://tools.ietf.org/html/draft-ietf-dnsop-refuse-any-04#section-7
+ENTRY_BEGIN
+MATCH opcode qtype
+ADJUST copy_id copy_query
+REPLY QR AA REFUSED
+SECTION QUESTION
+. IN RRSIG
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+x.root-servers.net IN A
+ENTRY_END
+
+
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA DO SERVFAIL
+SECTION QUESTION
+x.root-servers.net IN A
+SECTION ANSWER
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/val_minimal_anotherrrtypesignature.rpl b/tests/integration/deckard/sets/resolver/val_minimal_anotherrrtypesignature.rpl
new file mode 100644
index 0000000..562987a
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_minimal_anotherrrtypesignature.rpl
@@ -0,0 +1,87 @@
+ trust-anchor: ". IN DS 49060 8 2 E7B1EB56D7D5791B3D45630FEAA9C823DB84B385ACEEAC5F44DD08885C36700F"
+ val-override-date: "20170401000000"
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+ query-minimization: off
+CONFIG_END
+
+SCENARIO_BEGIN Signature belongs to another RR type of the domain.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ ADDRESS 2001:7fd::1
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. 518400 IN NS k.root-servers.net.
+. 518400 IN RRSIG NS 8 0 518400 20170409093827 20170310093827 20661 . uBuJpbRh1NYVciSKK0r3SA6NFnqE4s/+CqLfTXu26/HrY5c1aOhQHXZM cCDDjfPGFa7Eh4mqF0i9I+i+bFbYQitI1Heexye599VE19REbVsK4qaU xkArvt9k6HVqd/7BXXUyzLN1N0CScdyuT5tiEI9154SDNVpnC+z8i2u0 9hW8JEk4qqVWX/I1MYQB/UOcFSeDhD1Qku/26opqDuLl/1eaShxhMQ/c rjzOb5ZYzD0x+TUJZMYSOMwAraaFuYTT84oe6QYY+EGctAk1b50nA/5E C3Tm/xGuo9ioVtYhTwoo1XDUVeHmghdILjQZvR4pOSZoRGGP9ovb08Qg OmPXuQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+. IN DNSKEY
+SECTION ANSWER
+. IN DNSKEY 256 3 8 AwEAAe1oA46eOLNris1CtS0qM5TdMESK6i4hpalqa6JDv57eOUkaOeje ZW1tIFUokmaK7kuKEFEosddA89CYM8rt2RbC+sfKalbHAWOus0tXZyAL efb2sW95QRzyG6LNul0jQFn9eYWBUHrVe5Wqd0zrFCbTQLUhELSfrlkI UBpO/xKaGinRHX2JjyOnle4aPZY3bEVa/+KyY2ZU6UC4SBo3aHXanP26 ok91rOTmpTWp64ybsMdCXOU8deyuQFQf6q8DhIDmJrkymhX1MXWQQlE0 fAYIYf8/t9OCwucg8oEg4FPU8Gb4Zm/l6PgO4HFkFjBT6iGFCQt3qXe2 Qe3alUWoATc=
+. IN DNSKEY 257 3 8 AwEAAb8sZgVVa02muJ+/+SVhJAvz2EWKGEGquhPbQXuF6ALBYoF4KWTO bZVF8sIVTGoaX5+UWkwwHthg7RwS1DALT/AJymYeHhUwA04gLsfCZ/cv BjmRy5RozeSJ1uxAhoCYHCT2hQBZ0cH0n8roXFXI2Y+6708pO1IBkTPT 9MpAGfezTtGYOortbSn+vqT/Zu8jOpNwkleXON4rlZRBZPd4JUMGL9Y5 N/j6+ClYeM+eFQTKXrLi1oC+0yK1sG5OlqrBDhAhBnz+IhfZz4TOkqJ9 Li2BVMatHBeB9GQHtu0FZuC3J0EQgiZxvq1RgkefFJAiB+5uVRN8U7up 5mLDxSgmT0M=
+. 2592000 IN RRSIG DNSKEY 8 0 3600000 20170409093827 20170310093827 49060 . G7s3QiWNgOsl+LoG6OKjdBHPcFyhmCS17GFnaKjfJNdPQaFL5nM/vrXo eUIIdJXAvjj62TY7wTyFlnx3yjK93RVGKEEySpGC/1gkn5AdjVoQszog IxYjKzubizULSaX7SQ3/Ar+uHLxakdS1qgNdFu6hHCl857LJPtmC8SJt iFUmm5HFyARokMrfA88VrFRKEqojcCWajeZMfRtgBipFJZoYgPUCaFlz 8OupNdNUWCbGhnDWrXCWMzeKVXTQVlJf75PXXgtkuBUmr5RSWu7AYr+c wTJ4E4610goRqYxnZ33efKE/MuhKeY66xelPh0sirPrBMR5JAlyjV3k1 qDzhcQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+k.root-servers.net. IN AAAA
+SECTION ANSWER
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+k.root-servers.net. 2592000 IN RRSIG AAAA 8 3 3600000 20170409093827 20170310093827 20661 . qjVXwuxzmoRhdrXyQvKfrrzFxGiYuTTJHxwZPasJ1nVmN48dPyU6wA55 JeqoJv1Jm+XvIL1q0WtX6Zh6KLt6vVjHuMkhmFuIZYkFi/dmsEwFY8C0 ebyXyztQT5+6FOSVTAKacYc40LfBo8FqEn8RYlCu1mkAd8ANvvLrdLWW W03LVOY7JlCzyrKlAlmPmuV8z+e9PxNkUh6KfTEvAReoAAX7wYZkdefg 2d64c7rNWXvYm6LxBX6qeQ39d5WyKc8v+G01DJuDzs2Tx368QoK86vm/ qo9ERdT7koRt+gBZNYv8V4fh2SjaFsy2TJq/tiYcSia9snGDTFj6LWVM 6sBCYQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+k.root-servers.net. IN A
+SECTION ANSWER
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 2592000 IN RRSIG A 8 3 3600000 20170409093827 20170310093827 20661 . qjVXwuxzmoRhdrXyQvKfrrzFxGiYuTTJHxwZPasJ1nVmN48dPyU6wA55 JeqoJv1Jm+XvIL1q0WtX6Zh6KLt6vVjHuMkhmFuIZYkFi/dmsEwFY8C0 ebyXyztQT5+6FOSVTAKacYc40LfBo8FqEn8RYlCu1mkAd8ANvvLrdLWW W03LVOY7JlCzyrKlAlmPmuV8z+e9PxNkUh6KfTEvAReoAAX7wYZkdefg 2d64c7rNWXvYm6LxBX6qeQ39d5WyKc8v+G01DJuDzs2Tx368QoK86vm/ qo9ERdT7koRt+gBZNYv8V4fh2SjaFsy2TJq/tiYcSia9snGDTFj6LWVM 6sBCYQ== ; valid signature of k.root-servers.net IN AAAA
+ENTRY_END
+
+; QTYPE == RRSIG is not supported, https://tools.ietf.org/html/draft-ietf-dnsop-refuse-any-04#section-7
+ENTRY_BEGIN
+MATCH opcode qtype
+ADJUST copy_id copy_query
+REPLY QR AA REFUSED
+SECTION QUESTION
+. IN RRSIG
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+k.root-servers.net IN A
+ENTRY_END
+
+
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA DO SERVFAIL
+SECTION QUESTION
+k.root-servers.net IN A
+SECTION ANSWER
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/val_minimal_baddnskeyalgorithm.rpl b/tests/integration/deckard/sets/resolver/val_minimal_baddnskeyalgorithm.rpl
new file mode 100644
index 0000000..089db88
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_minimal_baddnskeyalgorithm.rpl
@@ -0,0 +1,88 @@
+ trust-anchor: ". IN DS 49060 8 2 E7B1EB56D7D5791B3D45630FEAA9C823DB84B385ACEEAC5F44DD08885C36700F"
+ val-override-date: "20170401000000"
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+ query-minimization: off
+CONFIG_END
+
+SCENARIO_BEGIN Changed DNSKEY algorithm.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ ADDRESS 2001:7fd::1
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. 518400 IN NS k.root-servers.net.
+. 518400 IN RRSIG NS 8 0 518400 20170409093827 20170310093827 20661 . uBuJpbRh1NYVciSKK0r3SA6NFnqE4s/+CqLfTXu26/HrY5c1aOhQHXZM cCDDjfPGFa7Eh4mqF0i9I+i+bFbYQitI1Heexye599VE19REbVsK4qaU xkArvt9k6HVqd/7BXXUyzLN1N0CScdyuT5tiEI9154SDNVpnC+z8i2u0 9hW8JEk4qqVWX/I1MYQB/UOcFSeDhD1Qku/26opqDuLl/1eaShxhMQ/c rjzOb5ZYzD0x+TUJZMYSOMwAraaFuYTT84oe6QYY+EGctAk1b50nA/5E C3Tm/xGuo9ioVtYhTwoo1XDUVeHmghdILjQZvR4pOSZoRGGP9ovb08Qg OmPXuQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+. IN DNSKEY
+SECTION ANSWER
+. 3600000 IN DNSKEY 256 3 7 AwEAAe1oA46eOLNris1CtS0qM5TdMESK6i4hpalqa6JDv57eOUkaOeje ZW1tIFUokmaK7kuKEFEosddA89CYM8rt2RbC+sfKalbHAWOus0tXZyAL efb2sW95QRzyG6LNul0jQFn9eYWBUHrVe5Wqd0zrFCbTQLUhELSfrlkI UBpO/xKaGinRHX2JjyOnle4aPZY3bEVa/+KyY2ZU6UC4SBo3aHXanP26 ok91rOTmpTWp64ybsMdCXOU8deyuQFQf6q8DhIDmJrkymhX1MXWQQlE0 fAYIYf8/t9OCwucg8oEg4FPU8Gb4Zm/l6PgO4HFkFjBT6iGFCQt3qXe2 Qe3alUWoATc= ; algorithm changed from 8 to 7
+. 3600000 IN DNSKEY 257 3 8 AwEAAb8sZgVVa02muJ+/+SVhJAvz2EWKGEGquhPbQXuF6ALBYoF4KWTO bZVF8sIVTGoaX5+UWkwwHthg7RwS1DALT/AJymYeHhUwA04gLsfCZ/cv BjmRy5RozeSJ1uxAhoCYHCT2hQBZ0cH0n8roXFXI2Y+6708pO1IBkTPT 9MpAGfezTtGYOortbSn+vqT/Zu8jOpNwkleXON4rlZRBZPd4JUMGL9Y5 N/j6+ClYeM+eFQTKXrLi1oC+0yK1sG5OlqrBDhAhBnz+IhfZz4TOkqJ9 Li2BVMatHBeB9GQHtu0FZuC3J0EQgiZxvq1RgkefFJAiB+5uVRN8U7up 5mLDxSgmT0M=
+. 2592000 IN RRSIG DNSKEY 8 0 3600000 20170409093827 20170310093827 49060 . G7s3QiWNgOsl+LoG6OKjdBHPcFyhmCS17GFnaKjfJNdPQaFL5nM/vrXo eUIIdJXAvjj62TY7wTyFlnx3yjK93RVGKEEySpGC/1gkn5AdjVoQszog IxYjKzubizULSaX7SQ3/Ar+uHLxakdS1qgNdFu6hHCl857LJPtmC8SJt iFUmm5HFyARokMrfA88VrFRKEqojcCWajeZMfRtgBipFJZoYgPUCaFlz 8OupNdNUWCbGhnDWrXCWMzeKVXTQVlJf75PXXgtkuBUmr5RSWu7AYr+c wTJ4E4610goRqYxnZ33efKE/MuhKeY66xelPh0sirPrBMR5JAlyjV3k1 qDzhcQ==
+
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+k.root-servers.net. IN AAAA
+SECTION ANSWER
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+k.root-servers.net. 2592000 IN RRSIG AAAA 8 3 3600000 20170409093827 20170310093827 20661 . qjVXwuxzmoRhdrXyQvKfrrzFxGiYuTTJHxwZPasJ1nVmN48dPyU6wA55 JeqoJv1Jm+XvIL1q0WtX6Zh6KLt6vVjHuMkhmFuIZYkFi/dmsEwFY8C0 ebyXyztQT5+6FOSVTAKacYc40LfBo8FqEn8RYlCu1mkAd8ANvvLrdLWW W03LVOY7JlCzyrKlAlmPmuV8z+e9PxNkUh6KfTEvAReoAAX7wYZkdefg 2d64c7rNWXvYm6LxBX6qeQ39d5WyKc8v+G01DJuDzs2Tx368QoK86vm/ qo9ERdT7koRt+gBZNYv8V4fh2SjaFsy2TJq/tiYcSia9snGDTFj6LWVM 6sBCYQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+k.root-servers.net. IN A
+SECTION ANSWER
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 2592000 IN RRSIG A 8 3 3600000 20170409093827 20170310093827 20661 . feIXXjskcsyH+ALZu67GVDaPWXjUGTWsTlDwzgJcLBzSuRVY/GVD5Z1Q B4/oUW99rLKB5bNS1MuasZ+nZFV67sBwJk1+SqNB2bAe7G5Tv1sR2Qgi qDAoB37YDVk5JGHfuxByLYbAVG9PrPXT60BN17OYrD/TFPzprye65gk3 7l9kPpAlblcsqdvh5piKrWc7VBcyMhlp56qdASNAl+Lrb+i0DZYyJXh+ b8LV5g5zp9FaVGKe0Gi4+yDXVjcM6VEtuNRAu2+flLoc3ho6qQF1Po4Y wueL72I+yFoUxkIOJvK47eWb+YUBIBK/L8/ORjYoLBRsrbc79wb0I3Zj Xy6O4Q==
+ENTRY_END
+
+; QTYPE == RRSIG is not supported, https://tools.ietf.org/html/draft-ietf-dnsop-refuse-any-04#section-7
+ENTRY_BEGIN
+MATCH opcode qtype
+ADJUST copy_id copy_query
+REPLY QR AA REFUSED
+SECTION QUESTION
+. IN RRSIG
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+. IN NS
+ENTRY_END
+
+
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA DO SERVFAIL
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/val_minimal_baddnskeyflags.rpl b/tests/integration/deckard/sets/resolver/val_minimal_baddnskeyflags.rpl
new file mode 100644
index 0000000..3f8e48d
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_minimal_baddnskeyflags.rpl
@@ -0,0 +1,88 @@
+ trust-anchor: ". IN DS 49060 8 2 E7B1EB56D7D5791B3D45630FEAA9C823DB84B385ACEEAC5F44DD08885C36700F"
+ val-override-date: "20170401000000"
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+ query-minimization: off
+CONFIG_END
+
+SCENARIO_BEGIN Changed DNSKEY flags.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ ADDRESS 2001:7fd::1
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. 518400 IN NS k.root-servers.net.
+. 518400 IN RRSIG NS 8 0 518400 20170409093827 20170310093827 20661 . uBuJpbRh1NYVciSKK0r3SA6NFnqE4s/+CqLfTXu26/HrY5c1aOhQHXZM cCDDjfPGFa7Eh4mqF0i9I+i+bFbYQitI1Heexye599VE19REbVsK4qaU xkArvt9k6HVqd/7BXXUyzLN1N0CScdyuT5tiEI9154SDNVpnC+z8i2u0 9hW8JEk4qqVWX/I1MYQB/UOcFSeDhD1Qku/26opqDuLl/1eaShxhMQ/c rjzOb5ZYzD0x+TUJZMYSOMwAraaFuYTT84oe6QYY+EGctAk1b50nA/5E C3Tm/xGuo9ioVtYhTwoo1XDUVeHmghdILjQZvR4pOSZoRGGP9ovb08Qg OmPXuQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+. IN DNSKEY
+SECTION ANSWER
+. 3600000 IN DNSKEY 254 3 8 AwEAAe1oA46eOLNris1CtS0qM5TdMESK6i4hpalqa6JDv57eOUkaOeje ZW1tIFUokmaK7kuKEFEosddA89CYM8rt2RbC+sfKalbHAWOus0tXZyAL efb2sW95QRzyG6LNul0jQFn9eYWBUHrVe5Wqd0zrFCbTQLUhELSfrlkI UBpO/xKaGinRHX2JjyOnle4aPZY3bEVa/+KyY2ZU6UC4SBo3aHXanP26 ok91rOTmpTWp64ybsMdCXOU8deyuQFQf6q8DhIDmJrkymhX1MXWQQlE0 fAYIYf8/t9OCwucg8oEg4FPU8Gb4Zm/l6PgO4HFkFjBT6iGFCQt3qXe2 Qe3alUWoATc= ; flags changed from 256 to 254
+. 3600000 IN DNSKEY 257 3 8 AwEAAb8sZgVVa02muJ+/+SVhJAvz2EWKGEGquhPbQXuF6ALBYoF4KWTO bZVF8sIVTGoaX5+UWkwwHthg7RwS1DALT/AJymYeHhUwA04gLsfCZ/cv BjmRy5RozeSJ1uxAhoCYHCT2hQBZ0cH0n8roXFXI2Y+6708pO1IBkTPT 9MpAGfezTtGYOortbSn+vqT/Zu8jOpNwkleXON4rlZRBZPd4JUMGL9Y5 N/j6+ClYeM+eFQTKXrLi1oC+0yK1sG5OlqrBDhAhBnz+IhfZz4TOkqJ9 Li2BVMatHBeB9GQHtu0FZuC3J0EQgiZxvq1RgkefFJAiB+5uVRN8U7up 5mLDxSgmT0M=
+. 2592000 IN RRSIG DNSKEY 8 0 3600000 20170409093827 20170310093827 49060 . G7s3QiWNgOsl+LoG6OKjdBHPcFyhmCS17GFnaKjfJNdPQaFL5nM/vrXo eUIIdJXAvjj62TY7wTyFlnx3yjK93RVGKEEySpGC/1gkn5AdjVoQszog IxYjKzubizULSaX7SQ3/Ar+uHLxakdS1qgNdFu6hHCl857LJPtmC8SJt iFUmm5HFyARokMrfA88VrFRKEqojcCWajeZMfRtgBipFJZoYgPUCaFlz 8OupNdNUWCbGhnDWrXCWMzeKVXTQVlJf75PXXgtkuBUmr5RSWu7AYr+c wTJ4E4610goRqYxnZ33efKE/MuhKeY66xelPh0sirPrBMR5JAlyjV3k1 qDzhcQ==
+
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+k.root-servers.net. IN AAAA
+SECTION ANSWER
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+k.root-servers.net. 2592000 IN RRSIG AAAA 8 3 3600000 20170409093827 20170310093827 20661 . qjVXwuxzmoRhdrXyQvKfrrzFxGiYuTTJHxwZPasJ1nVmN48dPyU6wA55 JeqoJv1Jm+XvIL1q0WtX6Zh6KLt6vVjHuMkhmFuIZYkFi/dmsEwFY8C0 ebyXyztQT5+6FOSVTAKacYc40LfBo8FqEn8RYlCu1mkAd8ANvvLrdLWW W03LVOY7JlCzyrKlAlmPmuV8z+e9PxNkUh6KfTEvAReoAAX7wYZkdefg 2d64c7rNWXvYm6LxBX6qeQ39d5WyKc8v+G01DJuDzs2Tx368QoK86vm/ qo9ERdT7koRt+gBZNYv8V4fh2SjaFsy2TJq/tiYcSia9snGDTFj6LWVM 6sBCYQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+k.root-servers.net. IN A
+SECTION ANSWER
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 2592000 IN RRSIG A 8 3 3600000 20170409093827 20170310093827 20661 . feIXXjskcsyH+ALZu67GVDaPWXjUGTWsTlDwzgJcLBzSuRVY/GVD5Z1Q B4/oUW99rLKB5bNS1MuasZ+nZFV67sBwJk1+SqNB2bAe7G5Tv1sR2Qgi qDAoB37YDVk5JGHfuxByLYbAVG9PrPXT60BN17OYrD/TFPzprye65gk3 7l9kPpAlblcsqdvh5piKrWc7VBcyMhlp56qdASNAl+Lrb+i0DZYyJXh+ b8LV5g5zp9FaVGKe0Gi4+yDXVjcM6VEtuNRAu2+flLoc3ho6qQF1Po4Y wueL72I+yFoUxkIOJvK47eWb+YUBIBK/L8/ORjYoLBRsrbc79wb0I3Zj Xy6O4Q==
+ENTRY_END
+
+; QTYPE == RRSIG is not supported, https://tools.ietf.org/html/draft-ietf-dnsop-refuse-any-04#section-7
+ENTRY_BEGIN
+MATCH opcode qtype
+ADJUST copy_id copy_query
+REPLY QR AA REFUSED
+SECTION QUESTION
+. IN RRSIG
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+. IN NS
+ENTRY_END
+
+
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA DO SERVFAIL
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/val_minimal_baddnskeyprotocol.rpl b/tests/integration/deckard/sets/resolver/val_minimal_baddnskeyprotocol.rpl
new file mode 100644
index 0000000..9a6d65b
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_minimal_baddnskeyprotocol.rpl
@@ -0,0 +1,88 @@
+ trust-anchor: ". IN DS 49060 8 2 E7B1EB56D7D5791B3D45630FEAA9C823DB84B385ACEEAC5F44DD08885C36700F"
+ val-override-date: "20170401000000"
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+ query-minimization: off
+CONFIG_END
+
+SCENARIO_BEGIN Changed DNSKEY protocol.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ ADDRESS 2001:7fd::1
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. 518400 IN NS k.root-servers.net.
+. 518400 IN RRSIG NS 8 0 518400 20170409093827 20170310093827 20661 . uBuJpbRh1NYVciSKK0r3SA6NFnqE4s/+CqLfTXu26/HrY5c1aOhQHXZM cCDDjfPGFa7Eh4mqF0i9I+i+bFbYQitI1Heexye599VE19REbVsK4qaU xkArvt9k6HVqd/7BXXUyzLN1N0CScdyuT5tiEI9154SDNVpnC+z8i2u0 9hW8JEk4qqVWX/I1MYQB/UOcFSeDhD1Qku/26opqDuLl/1eaShxhMQ/c rjzOb5ZYzD0x+TUJZMYSOMwAraaFuYTT84oe6QYY+EGctAk1b50nA/5E C3Tm/xGuo9ioVtYhTwoo1XDUVeHmghdILjQZvR4pOSZoRGGP9ovb08Qg OmPXuQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+. IN DNSKEY
+SECTION ANSWER
+. 3600000 IN DNSKEY 256 2 8 AwEAAe1oA46eOLNris1CtS0qM5TdMESK6i4hpalqa6JDv57eOUkaOeje ZW1tIFUokmaK7kuKEFEosddA89CYM8rt2RbC+sfKalbHAWOus0tXZyAL efb2sW95QRzyG6LNul0jQFn9eYWBUHrVe5Wqd0zrFCbTQLUhELSfrlkI UBpO/xKaGinRHX2JjyOnle4aPZY3bEVa/+KyY2ZU6UC4SBo3aHXanP26 ok91rOTmpTWp64ybsMdCXOU8deyuQFQf6q8DhIDmJrkymhX1MXWQQlE0 fAYIYf8/t9OCwucg8oEg4FPU8Gb4Zm/l6PgO4HFkFjBT6iGFCQt3qXe2 Qe3alUWoATc= ; protocol changed from 3 to 2
+. 3600000 IN DNSKEY 257 3 8 AwEAAb8sZgVVa02muJ+/+SVhJAvz2EWKGEGquhPbQXuF6ALBYoF4KWTO bZVF8sIVTGoaX5+UWkwwHthg7RwS1DALT/AJymYeHhUwA04gLsfCZ/cv BjmRy5RozeSJ1uxAhoCYHCT2hQBZ0cH0n8roXFXI2Y+6708pO1IBkTPT 9MpAGfezTtGYOortbSn+vqT/Zu8jOpNwkleXON4rlZRBZPd4JUMGL9Y5 N/j6+ClYeM+eFQTKXrLi1oC+0yK1sG5OlqrBDhAhBnz+IhfZz4TOkqJ9 Li2BVMatHBeB9GQHtu0FZuC3J0EQgiZxvq1RgkefFJAiB+5uVRN8U7up 5mLDxSgmT0M=
+. 2592000 IN RRSIG DNSKEY 8 0 3600000 20170409093827 20170310093827 49060 . G7s3QiWNgOsl+LoG6OKjdBHPcFyhmCS17GFnaKjfJNdPQaFL5nM/vrXo eUIIdJXAvjj62TY7wTyFlnx3yjK93RVGKEEySpGC/1gkn5AdjVoQszog IxYjKzubizULSaX7SQ3/Ar+uHLxakdS1qgNdFu6hHCl857LJPtmC8SJt iFUmm5HFyARokMrfA88VrFRKEqojcCWajeZMfRtgBipFJZoYgPUCaFlz 8OupNdNUWCbGhnDWrXCWMzeKVXTQVlJf75PXXgtkuBUmr5RSWu7AYr+c wTJ4E4610goRqYxnZ33efKE/MuhKeY66xelPh0sirPrBMR5JAlyjV3k1 qDzhcQ==
+
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+k.root-servers.net. IN AAAA
+SECTION ANSWER
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+k.root-servers.net. 2592000 IN RRSIG AAAA 8 3 3600000 20170409093827 20170310093827 20661 . qjVXwuxzmoRhdrXyQvKfrrzFxGiYuTTJHxwZPasJ1nVmN48dPyU6wA55 JeqoJv1Jm+XvIL1q0WtX6Zh6KLt6vVjHuMkhmFuIZYkFi/dmsEwFY8C0 ebyXyztQT5+6FOSVTAKacYc40LfBo8FqEn8RYlCu1mkAd8ANvvLrdLWW W03LVOY7JlCzyrKlAlmPmuV8z+e9PxNkUh6KfTEvAReoAAX7wYZkdefg 2d64c7rNWXvYm6LxBX6qeQ39d5WyKc8v+G01DJuDzs2Tx368QoK86vm/ qo9ERdT7koRt+gBZNYv8V4fh2SjaFsy2TJq/tiYcSia9snGDTFj6LWVM 6sBCYQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+k.root-servers.net. IN A
+SECTION ANSWER
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 2592000 IN RRSIG A 8 3 3600000 20170409093827 20170310093827 20661 . feIXXjskcsyH+ALZu67GVDaPWXjUGTWsTlDwzgJcLBzSuRVY/GVD5Z1Q B4/oUW99rLKB5bNS1MuasZ+nZFV67sBwJk1+SqNB2bAe7G5Tv1sR2Qgi qDAoB37YDVk5JGHfuxByLYbAVG9PrPXT60BN17OYrD/TFPzprye65gk3 7l9kPpAlblcsqdvh5piKrWc7VBcyMhlp56qdASNAl+Lrb+i0DZYyJXh+ b8LV5g5zp9FaVGKe0Gi4+yDXVjcM6VEtuNRAu2+flLoc3ho6qQF1Po4Y wueL72I+yFoUxkIOJvK47eWb+YUBIBK/L8/ORjYoLBRsrbc79wb0I3Zj Xy6O4Q==
+ENTRY_END
+
+; QTYPE == RRSIG is not supported, https://tools.ietf.org/html/draft-ietf-dnsop-refuse-any-04#section-7
+ENTRY_BEGIN
+MATCH opcode qtype
+ADJUST copy_id copy_query
+REPLY QR AA REFUSED
+SECTION QUESTION
+. IN RRSIG
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+. IN NS
+ENTRY_END
+
+
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA DO SERVFAIL
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/val_minimal_baddsalgorithm.rpl b/tests/integration/deckard/sets/resolver/val_minimal_baddsalgorithm.rpl
new file mode 100644
index 0000000..83fe386
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_minimal_baddsalgorithm.rpl
@@ -0,0 +1,87 @@
+ trust-anchor: ". IN DS 49060 7 2 E7B1EB56D7D5791B3D45630FEAA9C823DB84B385ACEEAC5F44DD08885C36700F" # algorithm changed from 8 to 7
+ val-override-date: "20170401000000"
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+ query-minimization: off
+CONFIG_END
+
+SCENARIO_BEGIN Changed algorithm of trust anchor.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ ADDRESS 2001:7fd::1
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. 518400 IN NS k.root-servers.net.
+. 518400 IN RRSIG NS 8 0 518400 20170409093827 20170310093827 20661 . uBuJpbRh1NYVciSKK0r3SA6NFnqE4s/+CqLfTXu26/HrY5c1aOhQHXZM cCDDjfPGFa7Eh4mqF0i9I+i+bFbYQitI1Heexye599VE19REbVsK4qaU xkArvt9k6HVqd/7BXXUyzLN1N0CScdyuT5tiEI9154SDNVpnC+z8i2u0 9hW8JEk4qqVWX/I1MYQB/UOcFSeDhD1Qku/26opqDuLl/1eaShxhMQ/c rjzOb5ZYzD0x+TUJZMYSOMwAraaFuYTT84oe6QYY+EGctAk1b50nA/5E C3Tm/xGuo9ioVtYhTwoo1XDUVeHmghdILjQZvR4pOSZoRGGP9ovb08Qg OmPXuQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+. IN DNSKEY
+SECTION ANSWER
+. IN DNSKEY 256 3 8 AwEAAe1oA46eOLNris1CtS0qM5TdMESK6i4hpalqa6JDv57eOUkaOeje ZW1tIFUokmaK7kuKEFEosddA89CYM8rt2RbC+sfKalbHAWOus0tXZyAL efb2sW95QRzyG6LNul0jQFn9eYWBUHrVe5Wqd0zrFCbTQLUhELSfrlkI UBpO/xKaGinRHX2JjyOnle4aPZY3bEVa/+KyY2ZU6UC4SBo3aHXanP26 ok91rOTmpTWp64ybsMdCXOU8deyuQFQf6q8DhIDmJrkymhX1MXWQQlE0 fAYIYf8/t9OCwucg8oEg4FPU8Gb4Zm/l6PgO4HFkFjBT6iGFCQt3qXe2 Qe3alUWoATc=
+. IN DNSKEY 257 3 8 AwEAAb8sZgVVa02muJ+/+SVhJAvz2EWKGEGquhPbQXuF6ALBYoF4KWTO bZVF8sIVTGoaX5+UWkwwHthg7RwS1DALT/AJymYeHhUwA04gLsfCZ/cv BjmRy5RozeSJ1uxAhoCYHCT2hQBZ0cH0n8roXFXI2Y+6708pO1IBkTPT 9MpAGfezTtGYOortbSn+vqT/Zu8jOpNwkleXON4rlZRBZPd4JUMGL9Y5 N/j6+ClYeM+eFQTKXrLi1oC+0yK1sG5OlqrBDhAhBnz+IhfZz4TOkqJ9 Li2BVMatHBeB9GQHtu0FZuC3J0EQgiZxvq1RgkefFJAiB+5uVRN8U7up 5mLDxSgmT0M=
+. 2592000 IN RRSIG DNSKEY 8 0 3600000 20170409093827 20170310093827 49060 . G7s3QiWNgOsl+LoG6OKjdBHPcFyhmCS17GFnaKjfJNdPQaFL5nM/vrXo eUIIdJXAvjj62TY7wTyFlnx3yjK93RVGKEEySpGC/1gkn5AdjVoQszog IxYjKzubizULSaX7SQ3/Ar+uHLxakdS1qgNdFu6hHCl857LJPtmC8SJt iFUmm5HFyARokMrfA88VrFRKEqojcCWajeZMfRtgBipFJZoYgPUCaFlz 8OupNdNUWCbGhnDWrXCWMzeKVXTQVlJf75PXXgtkuBUmr5RSWu7AYr+c wTJ4E4610goRqYxnZ33efKE/MuhKeY66xelPh0sirPrBMR5JAlyjV3k1 qDzhcQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+k.root-servers.net. IN AAAA
+SECTION ANSWER
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+k.root-servers.net. 2592000 IN RRSIG AAAA 8 3 3600000 20170409093827 20170310093827 20661 . qjVXwuxzmoRhdrXyQvKfrrzFxGiYuTTJHxwZPasJ1nVmN48dPyU6wA55 JeqoJv1Jm+XvIL1q0WtX6Zh6KLt6vVjHuMkhmFuIZYkFi/dmsEwFY8C0 ebyXyztQT5+6FOSVTAKacYc40LfBo8FqEn8RYlCu1mkAd8ANvvLrdLWW W03LVOY7JlCzyrKlAlmPmuV8z+e9PxNkUh6KfTEvAReoAAX7wYZkdefg 2d64c7rNWXvYm6LxBX6qeQ39d5WyKc8v+G01DJuDzs2Tx368QoK86vm/ qo9ERdT7koRt+gBZNYv8V4fh2SjaFsy2TJq/tiYcSia9snGDTFj6LWVM 6sBCYQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+k.root-servers.net. IN A
+SECTION ANSWER
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 2592000 IN RRSIG A 8 3 3600000 20170409093827 20170310093827 20661 . feIXXjskcsyH+ALZu67GVDaPWXjUGTWsTlDwzgJcLBzSuRVY/GVD5Z1Q B4/oUW99rLKB5bNS1MuasZ+nZFV67sBwJk1+SqNB2bAe7G5Tv1sR2Qgi qDAoB37YDVk5JGHfuxByLYbAVG9PrPXT60BN17OYrD/TFPzprye65gk3 7l9kPpAlblcsqdvh5piKrWc7VBcyMhlp56qdASNAl+Lrb+i0DZYyJXh+ b8LV5g5zp9FaVGKe0Gi4+yDXVjcM6VEtuNRAu2+flLoc3ho6qQF1Po4Y wueL72I+yFoUxkIOJvK47eWb+YUBIBK/L8/ORjYoLBRsrbc79wb0I3Zj Xy6O4Q==
+ENTRY_END
+
+; QTYPE == RRSIG is not supported, https://tools.ietf.org/html/draft-ietf-dnsop-refuse-any-04#section-7
+ENTRY_BEGIN
+MATCH opcode qtype
+ADJUST copy_id copy_query
+REPLY QR AA REFUSED
+SECTION QUESTION
+. IN RRSIG
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+. IN NS
+ENTRY_END
+
+
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA DO SERVFAIL
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/val_minimal_baddsdigest.rpl b/tests/integration/deckard/sets/resolver/val_minimal_baddsdigest.rpl
new file mode 100644
index 0000000..e365d21
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_minimal_baddsdigest.rpl
@@ -0,0 +1,87 @@
+ trust-anchor: ". IN DS 49060 8 2 A7B1EB56D7D5791B3D45630FEAA9C823DB84B385ACEEAC5F44DD08885C36700F" # digest changed
+ val-override-date: "20170401000000"
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+ query-minimization: off
+CONFIG_END
+
+SCENARIO_BEGIN Changed digest of trust anchor.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ ADDRESS 2001:7fd::1
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. 518400 IN NS k.root-servers.net.
+. 518400 IN RRSIG NS 8 0 518400 20170409093827 20170310093827 20661 . uBuJpbRh1NYVciSKK0r3SA6NFnqE4s/+CqLfTXu26/HrY5c1aOhQHXZM cCDDjfPGFa7Eh4mqF0i9I+i+bFbYQitI1Heexye599VE19REbVsK4qaU xkArvt9k6HVqd/7BXXUyzLN1N0CScdyuT5tiEI9154SDNVpnC+z8i2u0 9hW8JEk4qqVWX/I1MYQB/UOcFSeDhD1Qku/26opqDuLl/1eaShxhMQ/c rjzOb5ZYzD0x+TUJZMYSOMwAraaFuYTT84oe6QYY+EGctAk1b50nA/5E C3Tm/xGuo9ioVtYhTwoo1XDUVeHmghdILjQZvR4pOSZoRGGP9ovb08Qg OmPXuQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+. IN DNSKEY
+SECTION ANSWER
+. IN DNSKEY 256 3 8 AwEAAe1oA46eOLNris1CtS0qM5TdMESK6i4hpalqa6JDv57eOUkaOeje ZW1tIFUokmaK7kuKEFEosddA89CYM8rt2RbC+sfKalbHAWOus0tXZyAL efb2sW95QRzyG6LNul0jQFn9eYWBUHrVe5Wqd0zrFCbTQLUhELSfrlkI UBpO/xKaGinRHX2JjyOnle4aPZY3bEVa/+KyY2ZU6UC4SBo3aHXanP26 ok91rOTmpTWp64ybsMdCXOU8deyuQFQf6q8DhIDmJrkymhX1MXWQQlE0 fAYIYf8/t9OCwucg8oEg4FPU8Gb4Zm/l6PgO4HFkFjBT6iGFCQt3qXe2 Qe3alUWoATc=
+. IN DNSKEY 257 3 8 AwEAAb8sZgVVa02muJ+/+SVhJAvz2EWKGEGquhPbQXuF6ALBYoF4KWTO bZVF8sIVTGoaX5+UWkwwHthg7RwS1DALT/AJymYeHhUwA04gLsfCZ/cv BjmRy5RozeSJ1uxAhoCYHCT2hQBZ0cH0n8roXFXI2Y+6708pO1IBkTPT 9MpAGfezTtGYOortbSn+vqT/Zu8jOpNwkleXON4rlZRBZPd4JUMGL9Y5 N/j6+ClYeM+eFQTKXrLi1oC+0yK1sG5OlqrBDhAhBnz+IhfZz4TOkqJ9 Li2BVMatHBeB9GQHtu0FZuC3J0EQgiZxvq1RgkefFJAiB+5uVRN8U7up 5mLDxSgmT0M=
+. 2592000 IN RRSIG DNSKEY 8 0 3600000 20170409093827 20170310093827 49060 . G7s3QiWNgOsl+LoG6OKjdBHPcFyhmCS17GFnaKjfJNdPQaFL5nM/vrXo eUIIdJXAvjj62TY7wTyFlnx3yjK93RVGKEEySpGC/1gkn5AdjVoQszog IxYjKzubizULSaX7SQ3/Ar+uHLxakdS1qgNdFu6hHCl857LJPtmC8SJt iFUmm5HFyARokMrfA88VrFRKEqojcCWajeZMfRtgBipFJZoYgPUCaFlz 8OupNdNUWCbGhnDWrXCWMzeKVXTQVlJf75PXXgtkuBUmr5RSWu7AYr+c wTJ4E4610goRqYxnZ33efKE/MuhKeY66xelPh0sirPrBMR5JAlyjV3k1 qDzhcQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+k.root-servers.net. IN AAAA
+SECTION ANSWER
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+k.root-servers.net. 2592000 IN RRSIG AAAA 8 3 3600000 20170409093827 20170310093827 20661 . qjVXwuxzmoRhdrXyQvKfrrzFxGiYuTTJHxwZPasJ1nVmN48dPyU6wA55 JeqoJv1Jm+XvIL1q0WtX6Zh6KLt6vVjHuMkhmFuIZYkFi/dmsEwFY8C0 ebyXyztQT5+6FOSVTAKacYc40LfBo8FqEn8RYlCu1mkAd8ANvvLrdLWW W03LVOY7JlCzyrKlAlmPmuV8z+e9PxNkUh6KfTEvAReoAAX7wYZkdefg 2d64c7rNWXvYm6LxBX6qeQ39d5WyKc8v+G01DJuDzs2Tx368QoK86vm/ qo9ERdT7koRt+gBZNYv8V4fh2SjaFsy2TJq/tiYcSia9snGDTFj6LWVM 6sBCYQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+k.root-servers.net. IN A
+SECTION ANSWER
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 2592000 IN RRSIG A 8 3 3600000 20170409093827 20170310093827 20661 . feIXXjskcsyH+ALZu67GVDaPWXjUGTWsTlDwzgJcLBzSuRVY/GVD5Z1Q B4/oUW99rLKB5bNS1MuasZ+nZFV67sBwJk1+SqNB2bAe7G5Tv1sR2Qgi qDAoB37YDVk5JGHfuxByLYbAVG9PrPXT60BN17OYrD/TFPzprye65gk3 7l9kPpAlblcsqdvh5piKrWc7VBcyMhlp56qdASNAl+Lrb+i0DZYyJXh+ b8LV5g5zp9FaVGKe0Gi4+yDXVjcM6VEtuNRAu2+flLoc3ho6qQF1Po4Y wueL72I+yFoUxkIOJvK47eWb+YUBIBK/L8/ORjYoLBRsrbc79wb0I3Zj Xy6O4Q==
+ENTRY_END
+
+; QTYPE == RRSIG is not supported, https://tools.ietf.org/html/draft-ietf-dnsop-refuse-any-04#section-7
+ENTRY_BEGIN
+MATCH opcode qtype
+ADJUST copy_id copy_query
+REPLY QR AA REFUSED
+SECTION QUESTION
+. IN RRSIG
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+. IN NS
+ENTRY_END
+
+
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA DO SERVFAIL
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/val_minimal_baddsdigesttype.rpl b/tests/integration/deckard/sets/resolver/val_minimal_baddsdigesttype.rpl
new file mode 100644
index 0000000..5f2401e
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_minimal_baddsdigesttype.rpl
@@ -0,0 +1,87 @@
+ trust-anchor: ". IN DS 49060 8 1 E7B1EB56D7D5791B3D45630FEAA9C823DB84B385ACEEAC5F44DD08885C36700F" # digest type changed from 2 to 1
+ val-override-date: "20170401000000"
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+ query-minimization: off
+CONFIG_END
+
+SCENARIO_BEGIN Changed digest type of trust anchor.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ ADDRESS 2001:7fd::1
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. 518400 IN NS k.root-servers.net.
+. 518400 IN RRSIG NS 8 0 518400 20170409093827 20170310093827 20661 . uBuJpbRh1NYVciSKK0r3SA6NFnqE4s/+CqLfTXu26/HrY5c1aOhQHXZM cCDDjfPGFa7Eh4mqF0i9I+i+bFbYQitI1Heexye599VE19REbVsK4qaU xkArvt9k6HVqd/7BXXUyzLN1N0CScdyuT5tiEI9154SDNVpnC+z8i2u0 9hW8JEk4qqVWX/I1MYQB/UOcFSeDhD1Qku/26opqDuLl/1eaShxhMQ/c rjzOb5ZYzD0x+TUJZMYSOMwAraaFuYTT84oe6QYY+EGctAk1b50nA/5E C3Tm/xGuo9ioVtYhTwoo1XDUVeHmghdILjQZvR4pOSZoRGGP9ovb08Qg OmPXuQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+. IN DNSKEY
+SECTION ANSWER
+. IN DNSKEY 256 3 8 AwEAAe1oA46eOLNris1CtS0qM5TdMESK6i4hpalqa6JDv57eOUkaOeje ZW1tIFUokmaK7kuKEFEosddA89CYM8rt2RbC+sfKalbHAWOus0tXZyAL efb2sW95QRzyG6LNul0jQFn9eYWBUHrVe5Wqd0zrFCbTQLUhELSfrlkI UBpO/xKaGinRHX2JjyOnle4aPZY3bEVa/+KyY2ZU6UC4SBo3aHXanP26 ok91rOTmpTWp64ybsMdCXOU8deyuQFQf6q8DhIDmJrkymhX1MXWQQlE0 fAYIYf8/t9OCwucg8oEg4FPU8Gb4Zm/l6PgO4HFkFjBT6iGFCQt3qXe2 Qe3alUWoATc=
+. IN DNSKEY 257 3 8 AwEAAb8sZgVVa02muJ+/+SVhJAvz2EWKGEGquhPbQXuF6ALBYoF4KWTO bZVF8sIVTGoaX5+UWkwwHthg7RwS1DALT/AJymYeHhUwA04gLsfCZ/cv BjmRy5RozeSJ1uxAhoCYHCT2hQBZ0cH0n8roXFXI2Y+6708pO1IBkTPT 9MpAGfezTtGYOortbSn+vqT/Zu8jOpNwkleXON4rlZRBZPd4JUMGL9Y5 N/j6+ClYeM+eFQTKXrLi1oC+0yK1sG5OlqrBDhAhBnz+IhfZz4TOkqJ9 Li2BVMatHBeB9GQHtu0FZuC3J0EQgiZxvq1RgkefFJAiB+5uVRN8U7up 5mLDxSgmT0M=
+. 2592000 IN RRSIG DNSKEY 8 0 3600000 20170409093827 20170310093827 49060 . G7s3QiWNgOsl+LoG6OKjdBHPcFyhmCS17GFnaKjfJNdPQaFL5nM/vrXo eUIIdJXAvjj62TY7wTyFlnx3yjK93RVGKEEySpGC/1gkn5AdjVoQszog IxYjKzubizULSaX7SQ3/Ar+uHLxakdS1qgNdFu6hHCl857LJPtmC8SJt iFUmm5HFyARokMrfA88VrFRKEqojcCWajeZMfRtgBipFJZoYgPUCaFlz 8OupNdNUWCbGhnDWrXCWMzeKVXTQVlJf75PXXgtkuBUmr5RSWu7AYr+c wTJ4E4610goRqYxnZ33efKE/MuhKeY66xelPh0sirPrBMR5JAlyjV3k1 qDzhcQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+k.root-servers.net. IN AAAA
+SECTION ANSWER
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+k.root-servers.net. 2592000 IN RRSIG AAAA 8 3 3600000 20170409093827 20170310093827 20661 . qjVXwuxzmoRhdrXyQvKfrrzFxGiYuTTJHxwZPasJ1nVmN48dPyU6wA55 JeqoJv1Jm+XvIL1q0WtX6Zh6KLt6vVjHuMkhmFuIZYkFi/dmsEwFY8C0 ebyXyztQT5+6FOSVTAKacYc40LfBo8FqEn8RYlCu1mkAd8ANvvLrdLWW W03LVOY7JlCzyrKlAlmPmuV8z+e9PxNkUh6KfTEvAReoAAX7wYZkdefg 2d64c7rNWXvYm6LxBX6qeQ39d5WyKc8v+G01DJuDzs2Tx368QoK86vm/ qo9ERdT7koRt+gBZNYv8V4fh2SjaFsy2TJq/tiYcSia9snGDTFj6LWVM 6sBCYQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+k.root-servers.net. IN A
+SECTION ANSWER
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 2592000 IN RRSIG A 8 3 3600000 20170409093827 20170310093827 20661 . feIXXjskcsyH+ALZu67GVDaPWXjUGTWsTlDwzgJcLBzSuRVY/GVD5Z1Q B4/oUW99rLKB5bNS1MuasZ+nZFV67sBwJk1+SqNB2bAe7G5Tv1sR2Qgi qDAoB37YDVk5JGHfuxByLYbAVG9PrPXT60BN17OYrD/TFPzprye65gk3 7l9kPpAlblcsqdvh5piKrWc7VBcyMhlp56qdASNAl+Lrb+i0DZYyJXh+ b8LV5g5zp9FaVGKe0Gi4+yDXVjcM6VEtuNRAu2+flLoc3ho6qQF1Po4Y wueL72I+yFoUxkIOJvK47eWb+YUBIBK/L8/ORjYoLBRsrbc79wb0I3Zj Xy6O4Q==
+ENTRY_END
+
+; QTYPE == RRSIG is not supported, https://tools.ietf.org/html/draft-ietf-dnsop-refuse-any-04#section-7
+ENTRY_BEGIN
+MATCH opcode qtype
+ADJUST copy_id copy_query
+REPLY QR AA REFUSED
+SECTION QUESTION
+. IN RRSIG
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+. IN NS
+ENTRY_END
+
+
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA DO SERVFAIL
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/val_minimal_baddskeytag.rpl b/tests/integration/deckard/sets/resolver/val_minimal_baddskeytag.rpl
new file mode 100644
index 0000000..50ae41a
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_minimal_baddskeytag.rpl
@@ -0,0 +1,87 @@
+ trust-anchor: ". IN DS 49061 8 2 E7B1EB56D7D5791B3D45630FEAA9C823DB84B385ACEEAC5F44DD08885C36700F" # key tag changed from 49060 to 49061
+ val-override-date: "20170401000000"
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+ query-minimization: off
+CONFIG_END
+
+SCENARIO_BEGIN Chnged key tag of trust anchor.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ ADDRESS 2001:7fd::1
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. 518400 IN NS k.root-servers.net.
+. 518400 IN RRSIG NS 8 0 518400 20170409093827 20170310093827 20661 . uBuJpbRh1NYVciSKK0r3SA6NFnqE4s/+CqLfTXu26/HrY5c1aOhQHXZM cCDDjfPGFa7Eh4mqF0i9I+i+bFbYQitI1Heexye599VE19REbVsK4qaU xkArvt9k6HVqd/7BXXUyzLN1N0CScdyuT5tiEI9154SDNVpnC+z8i2u0 9hW8JEk4qqVWX/I1MYQB/UOcFSeDhD1Qku/26opqDuLl/1eaShxhMQ/c rjzOb5ZYzD0x+TUJZMYSOMwAraaFuYTT84oe6QYY+EGctAk1b50nA/5E C3Tm/xGuo9ioVtYhTwoo1XDUVeHmghdILjQZvR4pOSZoRGGP9ovb08Qg OmPXuQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+. IN DNSKEY
+SECTION ANSWER
+. IN DNSKEY 256 3 8 AwEAAe1oA46eOLNris1CtS0qM5TdMESK6i4hpalqa6JDv57eOUkaOeje ZW1tIFUokmaK7kuKEFEosddA89CYM8rt2RbC+sfKalbHAWOus0tXZyAL efb2sW95QRzyG6LNul0jQFn9eYWBUHrVe5Wqd0zrFCbTQLUhELSfrlkI UBpO/xKaGinRHX2JjyOnle4aPZY3bEVa/+KyY2ZU6UC4SBo3aHXanP26 ok91rOTmpTWp64ybsMdCXOU8deyuQFQf6q8DhIDmJrkymhX1MXWQQlE0 fAYIYf8/t9OCwucg8oEg4FPU8Gb4Zm/l6PgO4HFkFjBT6iGFCQt3qXe2 Qe3alUWoATc=
+. IN DNSKEY 257 3 8 AwEAAb8sZgVVa02muJ+/+SVhJAvz2EWKGEGquhPbQXuF6ALBYoF4KWTO bZVF8sIVTGoaX5+UWkwwHthg7RwS1DALT/AJymYeHhUwA04gLsfCZ/cv BjmRy5RozeSJ1uxAhoCYHCT2hQBZ0cH0n8roXFXI2Y+6708pO1IBkTPT 9MpAGfezTtGYOortbSn+vqT/Zu8jOpNwkleXON4rlZRBZPd4JUMGL9Y5 N/j6+ClYeM+eFQTKXrLi1oC+0yK1sG5OlqrBDhAhBnz+IhfZz4TOkqJ9 Li2BVMatHBeB9GQHtu0FZuC3J0EQgiZxvq1RgkefFJAiB+5uVRN8U7up 5mLDxSgmT0M=
+. 2592000 IN RRSIG DNSKEY 8 0 3600000 20170409093827 20170310093827 49060 . G7s3QiWNgOsl+LoG6OKjdBHPcFyhmCS17GFnaKjfJNdPQaFL5nM/vrXo eUIIdJXAvjj62TY7wTyFlnx3yjK93RVGKEEySpGC/1gkn5AdjVoQszog IxYjKzubizULSaX7SQ3/Ar+uHLxakdS1qgNdFu6hHCl857LJPtmC8SJt iFUmm5HFyARokMrfA88VrFRKEqojcCWajeZMfRtgBipFJZoYgPUCaFlz 8OupNdNUWCbGhnDWrXCWMzeKVXTQVlJf75PXXgtkuBUmr5RSWu7AYr+c wTJ4E4610goRqYxnZ33efKE/MuhKeY66xelPh0sirPrBMR5JAlyjV3k1 qDzhcQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+k.root-servers.net. IN AAAA
+SECTION ANSWER
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+k.root-servers.net. 2592000 IN RRSIG AAAA 8 3 3600000 20170409093827 20170310093827 20661 . qjVXwuxzmoRhdrXyQvKfrrzFxGiYuTTJHxwZPasJ1nVmN48dPyU6wA55 JeqoJv1Jm+XvIL1q0WtX6Zh6KLt6vVjHuMkhmFuIZYkFi/dmsEwFY8C0 ebyXyztQT5+6FOSVTAKacYc40LfBo8FqEn8RYlCu1mkAd8ANvvLrdLWW W03LVOY7JlCzyrKlAlmPmuV8z+e9PxNkUh6KfTEvAReoAAX7wYZkdefg 2d64c7rNWXvYm6LxBX6qeQ39d5WyKc8v+G01DJuDzs2Tx368QoK86vm/ qo9ERdT7koRt+gBZNYv8V4fh2SjaFsy2TJq/tiYcSia9snGDTFj6LWVM 6sBCYQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+k.root-servers.net. IN A
+SECTION ANSWER
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 2592000 IN RRSIG A 8 3 3600000 20170409093827 20170310093827 20661 . feIXXjskcsyH+ALZu67GVDaPWXjUGTWsTlDwzgJcLBzSuRVY/GVD5Z1Q B4/oUW99rLKB5bNS1MuasZ+nZFV67sBwJk1+SqNB2bAe7G5Tv1sR2Qgi qDAoB37YDVk5JGHfuxByLYbAVG9PrPXT60BN17OYrD/TFPzprye65gk3 7l9kPpAlblcsqdvh5piKrWc7VBcyMhlp56qdASNAl+Lrb+i0DZYyJXh+ b8LV5g5zp9FaVGKe0Gi4+yDXVjcM6VEtuNRAu2+flLoc3ho6qQF1Po4Y wueL72I+yFoUxkIOJvK47eWb+YUBIBK/L8/ORjYoLBRsrbc79wb0I3Zj Xy6O4Q==
+ENTRY_END
+
+; QTYPE == RRSIG is not supported, https://tools.ietf.org/html/draft-ietf-dnsop-refuse-any-04#section-7
+ENTRY_BEGIN
+MATCH opcode qtype
+ADJUST copy_id copy_query
+REPLY QR AA REFUSED
+SECTION QUESTION
+. IN RRSIG
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+. IN NS
+ENTRY_END
+
+
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA DO SERVFAIL
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/val_minimal_badpublickey.rpl b/tests/integration/deckard/sets/resolver/val_minimal_badpublickey.rpl
new file mode 100644
index 0000000..dfca431
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_minimal_badpublickey.rpl
@@ -0,0 +1,88 @@
+ trust-anchor: ". IN DS 49060 8 2 E7B1EB56D7D5791B3D45630FEAA9C823DB84B385ACEEAC5F44DD08885C36700F"
+ val-override-date: "20170401000000"
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+ query-minimization: off
+CONFIG_END
+
+SCENARIO_BEGIN Changed public key.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ ADDRESS 2001:7fd::1
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. 518400 IN NS k.root-servers.net.
+. 518400 IN RRSIG NS 8 0 518400 20170409093827 20170310093827 20661 . uBuJpbRh1NYVciSKK0r3SA6NFnqE4s/+CqLfTXu26/HrY5c1aOhQHXZM cCDDjfPGFa7Eh4mqF0i9I+i+bFbYQitI1Heexye599VE19REbVsK4qaU xkArvt9k6HVqd/7BXXUyzLN1N0CScdyuT5tiEI9154SDNVpnC+z8i2u0 9hW8JEk4qqVWX/I1MYQB/UOcFSeDhD1Qku/26opqDuLl/1eaShxhMQ/c rjzOb5ZYzD0x+TUJZMYSOMwAraaFuYTT84oe6QYY+EGctAk1b50nA/5E C3Tm/xGuo9ioVtYhTwoo1XDUVeHmghdILjQZvR4pOSZoRGGP9ovb08Qg OmPXuQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+. IN DNSKEY
+SECTION ANSWER
+. 3600000 IN DNSKEY 256 3 8 BwEAAe1oA46eOLNris1CtS0qM5TdMESK6i4hpalqa6JDv57eOUkaOeje ZW1tIFUokmaK7kuKEFEosddA89CYM8rt2RbC+sfKalbHAWOus0tXZyAL efb2sW95QRzyG6LNul0jQFn9eYWBUHrVe5Wqd0zrFCbTQLUhELSfrlkI UBpO/xKaGinRHX2JjyOnle4aPZY3bEVa/+KyY2ZU6UC4SBo3aHXanP26 ok91rOTmpTWp64ybsMdCXOU8deyuQFQf6q8DhIDmJrkymhX1MXWQQlE0 fAYIYf8/t9OCwucg8oEg4FPU8Gb4Zm/l6PgO4HFkFjBT6iGFCQt3qXe2 Qe3alUWoATc= ; changed public key
+. 3600000 IN DNSKEY 257 3 8 AwEAAb8sZgVVa02muJ+/+SVhJAvz2EWKGEGquhPbQXuF6ALBYoF4KWTO bZVF8sIVTGoaX5+UWkwwHthg7RwS1DALT/AJymYeHhUwA04gLsfCZ/cv BjmRy5RozeSJ1uxAhoCYHCT2hQBZ0cH0n8roXFXI2Y+6708pO1IBkTPT 9MpAGfezTtGYOortbSn+vqT/Zu8jOpNwkleXON4rlZRBZPd4JUMGL9Y5 N/j6+ClYeM+eFQTKXrLi1oC+0yK1sG5OlqrBDhAhBnz+IhfZz4TOkqJ9 Li2BVMatHBeB9GQHtu0FZuC3J0EQgiZxvq1RgkefFJAiB+5uVRN8U7up 5mLDxSgmT0M=
+. 2592000 IN RRSIG DNSKEY 8 0 3600000 20170409093827 20170310093827 49060 . G7s3QiWNgOsl+LoG6OKjdBHPcFyhmCS17GFnaKjfJNdPQaFL5nM/vrXo eUIIdJXAvjj62TY7wTyFlnx3yjK93RVGKEEySpGC/1gkn5AdjVoQszog IxYjKzubizULSaX7SQ3/Ar+uHLxakdS1qgNdFu6hHCl857LJPtmC8SJt iFUmm5HFyARokMrfA88VrFRKEqojcCWajeZMfRtgBipFJZoYgPUCaFlz 8OupNdNUWCbGhnDWrXCWMzeKVXTQVlJf75PXXgtkuBUmr5RSWu7AYr+c wTJ4E4610goRqYxnZ33efKE/MuhKeY66xelPh0sirPrBMR5JAlyjV3k1 qDzhcQ==
+
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+k.root-servers.net. IN AAAA
+SECTION ANSWER
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+k.root-servers.net. 2592000 IN RRSIG AAAA 8 3 3600000 20170409093827 20170310093827 20661 . qjVXwuxzmoRhdrXyQvKfrrzFxGiYuTTJHxwZPasJ1nVmN48dPyU6wA55 JeqoJv1Jm+XvIL1q0WtX6Zh6KLt6vVjHuMkhmFuIZYkFi/dmsEwFY8C0 ebyXyztQT5+6FOSVTAKacYc40LfBo8FqEn8RYlCu1mkAd8ANvvLrdLWW W03LVOY7JlCzyrKlAlmPmuV8z+e9PxNkUh6KfTEvAReoAAX7wYZkdefg 2d64c7rNWXvYm6LxBX6qeQ39d5WyKc8v+G01DJuDzs2Tx368QoK86vm/ qo9ERdT7koRt+gBZNYv8V4fh2SjaFsy2TJq/tiYcSia9snGDTFj6LWVM 6sBCYQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+k.root-servers.net. IN A
+SECTION ANSWER
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 2592000 IN RRSIG A 8 3 3600000 20170409093827 20170310093827 20661 . feIXXjskcsyH+ALZu67GVDaPWXjUGTWsTlDwzgJcLBzSuRVY/GVD5Z1Q B4/oUW99rLKB5bNS1MuasZ+nZFV67sBwJk1+SqNB2bAe7G5Tv1sR2Qgi qDAoB37YDVk5JGHfuxByLYbAVG9PrPXT60BN17OYrD/TFPzprye65gk3 7l9kPpAlblcsqdvh5piKrWc7VBcyMhlp56qdASNAl+Lrb+i0DZYyJXh+ b8LV5g5zp9FaVGKe0Gi4+yDXVjcM6VEtuNRAu2+flLoc3ho6qQF1Po4Y wueL72I+yFoUxkIOJvK47eWb+YUBIBK/L8/ORjYoLBRsrbc79wb0I3Zj Xy6O4Q==
+ENTRY_END
+
+; QTYPE == RRSIG is not supported, https://tools.ietf.org/html/draft-ietf-dnsop-refuse-any-04#section-7
+ENTRY_BEGIN
+MATCH opcode qtype
+ADJUST copy_id copy_query
+REPLY QR AA REFUSED
+SECTION QUESTION
+. IN RRSIG
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+. IN NS
+ENTRY_END
+
+
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA DO SERVFAIL
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/val_minimal_badrrsigalgorithm.rpl b/tests/integration/deckard/sets/resolver/val_minimal_badrrsigalgorithm.rpl
new file mode 100644
index 0000000..7e562ce
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_minimal_badrrsigalgorithm.rpl
@@ -0,0 +1,88 @@
+ trust-anchor: ". IN DS 49060 8 2 E7B1EB56D7D5791B3D45630FEAA9C823DB84B385ACEEAC5F44DD08885C36700F"
+ val-override-date: "20170401000000"
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+ query-minimization: off
+CONFIG_END
+
+SCENARIO_BEGIN Changed RRSIG algorithm.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ ADDRESS 2001:7fd::1
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. 518400 IN NS k.root-servers.net.
+. 518400 IN RRSIG NS 7 0 518400 20170409093827 20170310093827 20661 . uBuJpbRh1NYVciSKK0r3SA6NFnqE4s/+CqLfTXu26/HrY5c1aOhQHXZM cCDDjfPGFa7Eh4mqF0i9I+i+bFbYQitI1Heexye599VE19REbVsK4qaU xkArvt9k6HVqd/7BXXUyzLN1N0CScdyuT5tiEI9154SDNVpnC+z8i2u0 9hW8JEk4qqVWX/I1MYQB/UOcFSeDhD1Qku/26opqDuLl/1eaShxhMQ/c rjzOb5ZYzD0x+TUJZMYSOMwAraaFuYTT84oe6QYY+EGctAk1b50nA/5E C3Tm/xGuo9ioVtYhTwoo1XDUVeHmghdILjQZvR4pOSZoRGGP9ovb08Qg OmPXuQ== ; algorithm changed from 8 to 7
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+. IN DNSKEY
+SECTION ANSWER
+. 3600000 IN DNSKEY 256 3 8 AwEAAe1oA46eOLNris1CtS0qM5TdMESK6i4hpalqa6JDv57eOUkaOeje ZW1tIFUokmaK7kuKEFEosddA89CYM8rt2RbC+sfKalbHAWOus0tXZyAL efb2sW95QRzyG6LNul0jQFn9eYWBUHrVe5Wqd0zrFCbTQLUhELSfrlkI UBpO/xKaGinRHX2JjyOnle4aPZY3bEVa/+KyY2ZU6UC4SBo3aHXanP26 ok91rOTmpTWp64ybsMdCXOU8deyuQFQf6q8DhIDmJrkymhX1MXWQQlE0 fAYIYf8/t9OCwucg8oEg4FPU8Gb4Zm/l6PgO4HFkFjBT6iGFCQt3qXe2 Qe3alUWoATc=
+. 3600000 IN DNSKEY 257 3 8 AwEAAb8sZgVVa02muJ+/+SVhJAvz2EWKGEGquhPbQXuF6ALBYoF4KWTO bZVF8sIVTGoaX5+UWkwwHthg7RwS1DALT/AJymYeHhUwA04gLsfCZ/cv BjmRy5RozeSJ1uxAhoCYHCT2hQBZ0cH0n8roXFXI2Y+6708pO1IBkTPT 9MpAGfezTtGYOortbSn+vqT/Zu8jOpNwkleXON4rlZRBZPd4JUMGL9Y5 N/j6+ClYeM+eFQTKXrLi1oC+0yK1sG5OlqrBDhAhBnz+IhfZz4TOkqJ9 Li2BVMatHBeB9GQHtu0FZuC3J0EQgiZxvq1RgkefFJAiB+5uVRN8U7up 5mLDxSgmT0M=
+. 2592000 IN RRSIG DNSKEY 8 0 3600000 20170409093827 20170310093827 49060 . G7s3QiWNgOsl+LoG6OKjdBHPcFyhmCS17GFnaKjfJNdPQaFL5nM/vrXo eUIIdJXAvjj62TY7wTyFlnx3yjK93RVGKEEySpGC/1gkn5AdjVoQszog IxYjKzubizULSaX7SQ3/Ar+uHLxakdS1qgNdFu6hHCl857LJPtmC8SJt iFUmm5HFyARokMrfA88VrFRKEqojcCWajeZMfRtgBipFJZoYgPUCaFlz 8OupNdNUWCbGhnDWrXCWMzeKVXTQVlJf75PXXgtkuBUmr5RSWu7AYr+c wTJ4E4610goRqYxnZ33efKE/MuhKeY66xelPh0sirPrBMR5JAlyjV3k1 qDzhcQ==
+
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+k.root-servers.net. IN AAAA
+SECTION ANSWER
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+k.root-servers.net. 2592000 IN RRSIG AAAA 8 3 3600000 20170409093827 20170310093827 20661 . qjVXwuxzmoRhdrXyQvKfrrzFxGiYuTTJHxwZPasJ1nVmN48dPyU6wA55 JeqoJv1Jm+XvIL1q0WtX6Zh6KLt6vVjHuMkhmFuIZYkFi/dmsEwFY8C0 ebyXyztQT5+6FOSVTAKacYc40LfBo8FqEn8RYlCu1mkAd8ANvvLrdLWW W03LVOY7JlCzyrKlAlmPmuV8z+e9PxNkUh6KfTEvAReoAAX7wYZkdefg 2d64c7rNWXvYm6LxBX6qeQ39d5WyKc8v+G01DJuDzs2Tx368QoK86vm/ qo9ERdT7koRt+gBZNYv8V4fh2SjaFsy2TJq/tiYcSia9snGDTFj6LWVM 6sBCYQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+k.root-servers.net. IN A
+SECTION ANSWER
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 2592000 IN RRSIG A 8 3 3600000 20170409093827 20170310093827 20661 . feIXXjskcsyH+ALZu67GVDaPWXjUGTWsTlDwzgJcLBzSuRVY/GVD5Z1Q B4/oUW99rLKB5bNS1MuasZ+nZFV67sBwJk1+SqNB2bAe7G5Tv1sR2Qgi qDAoB37YDVk5JGHfuxByLYbAVG9PrPXT60BN17OYrD/TFPzprye65gk3 7l9kPpAlblcsqdvh5piKrWc7VBcyMhlp56qdASNAl+Lrb+i0DZYyJXh+ b8LV5g5zp9FaVGKe0Gi4+yDXVjcM6VEtuNRAu2+flLoc3ho6qQF1Po4Y wueL72I+yFoUxkIOJvK47eWb+YUBIBK/L8/ORjYoLBRsrbc79wb0I3Zj Xy6O4Q==
+ENTRY_END
+
+; QTYPE == RRSIG is not supported, https://tools.ietf.org/html/draft-ietf-dnsop-refuse-any-04#section-7
+ENTRY_BEGIN
+MATCH opcode qtype
+ADJUST copy_id copy_query
+REPLY QR AA REFUSED
+SECTION QUESTION
+. IN RRSIG
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+. IN NS
+ENTRY_END
+
+
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA DO SERVFAIL
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/val_minimal_badrrsigexpiration.rpl b/tests/integration/deckard/sets/resolver/val_minimal_badrrsigexpiration.rpl
new file mode 100644
index 0000000..771c818
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_minimal_badrrsigexpiration.rpl
@@ -0,0 +1,88 @@
+ trust-anchor: ". IN DS 49060 8 2 E7B1EB56D7D5791B3D45630FEAA9C823DB84B385ACEEAC5F44DD08885C36700F"
+ val-override-date: "20170401000000"
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+ query-minimization: off
+CONFIG_END
+
+SCENARIO_BEGIN Changed RRSIG expiration.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ ADDRESS 2001:7fd::1
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. 518400 IN NS k.root-servers.net.
+. 518400 IN RRSIG NS 8 0 518400 20170409093828 20170310093827 20661 . uBuJpbRh1NYVciSKK0r3SA6NFnqE4s/+CqLfTXu26/HrY5c1aOhQHXZM cCDDjfPGFa7Eh4mqF0i9I+i+bFbYQitI1Heexye599VE19REbVsK4qaU xkArvt9k6HVqd/7BXXUyzLN1N0CScdyuT5tiEI9154SDNVpnC+z8i2u0 9hW8JEk4qqVWX/I1MYQB/UOcFSeDhD1Qku/26opqDuLl/1eaShxhMQ/c rjzOb5ZYzD0x+TUJZMYSOMwAraaFuYTT84oe6QYY+EGctAk1b50nA/5E C3Tm/xGuo9ioVtYhTwoo1XDUVeHmghdILjQZvR4pOSZoRGGP9ovb08Qg OmPXuQ== ; expiration changed from 20170409093827 to 20170409093828
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+. IN DNSKEY
+SECTION ANSWER
+. 3600000 IN DNSKEY 256 3 8 AwEAAe1oA46eOLNris1CtS0qM5TdMESK6i4hpalqa6JDv57eOUkaOeje ZW1tIFUokmaK7kuKEFEosddA89CYM8rt2RbC+sfKalbHAWOus0tXZyAL efb2sW95QRzyG6LNul0jQFn9eYWBUHrVe5Wqd0zrFCbTQLUhELSfrlkI UBpO/xKaGinRHX2JjyOnle4aPZY3bEVa/+KyY2ZU6UC4SBo3aHXanP26 ok91rOTmpTWp64ybsMdCXOU8deyuQFQf6q8DhIDmJrkymhX1MXWQQlE0 fAYIYf8/t9OCwucg8oEg4FPU8Gb4Zm/l6PgO4HFkFjBT6iGFCQt3qXe2 Qe3alUWoATc=
+. 3600000 IN DNSKEY 257 3 8 AwEAAb8sZgVVa02muJ+/+SVhJAvz2EWKGEGquhPbQXuF6ALBYoF4KWTO bZVF8sIVTGoaX5+UWkwwHthg7RwS1DALT/AJymYeHhUwA04gLsfCZ/cv BjmRy5RozeSJ1uxAhoCYHCT2hQBZ0cH0n8roXFXI2Y+6708pO1IBkTPT 9MpAGfezTtGYOortbSn+vqT/Zu8jOpNwkleXON4rlZRBZPd4JUMGL9Y5 N/j6+ClYeM+eFQTKXrLi1oC+0yK1sG5OlqrBDhAhBnz+IhfZz4TOkqJ9 Li2BVMatHBeB9GQHtu0FZuC3J0EQgiZxvq1RgkefFJAiB+5uVRN8U7up 5mLDxSgmT0M=
+. 2592000 IN RRSIG DNSKEY 8 0 3600000 20170409093827 20170310093827 49060 . G7s3QiWNgOsl+LoG6OKjdBHPcFyhmCS17GFnaKjfJNdPQaFL5nM/vrXo eUIIdJXAvjj62TY7wTyFlnx3yjK93RVGKEEySpGC/1gkn5AdjVoQszog IxYjKzubizULSaX7SQ3/Ar+uHLxakdS1qgNdFu6hHCl857LJPtmC8SJt iFUmm5HFyARokMrfA88VrFRKEqojcCWajeZMfRtgBipFJZoYgPUCaFlz 8OupNdNUWCbGhnDWrXCWMzeKVXTQVlJf75PXXgtkuBUmr5RSWu7AYr+c wTJ4E4610goRqYxnZ33efKE/MuhKeY66xelPh0sirPrBMR5JAlyjV3k1 qDzhcQ==
+
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+k.root-servers.net. IN AAAA
+SECTION ANSWER
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+k.root-servers.net. 2592000 IN RRSIG AAAA 8 3 3600000 20170409093827 20170310093827 20661 . qjVXwuxzmoRhdrXyQvKfrrzFxGiYuTTJHxwZPasJ1nVmN48dPyU6wA55 JeqoJv1Jm+XvIL1q0WtX6Zh6KLt6vVjHuMkhmFuIZYkFi/dmsEwFY8C0 ebyXyztQT5+6FOSVTAKacYc40LfBo8FqEn8RYlCu1mkAd8ANvvLrdLWW W03LVOY7JlCzyrKlAlmPmuV8z+e9PxNkUh6KfTEvAReoAAX7wYZkdefg 2d64c7rNWXvYm6LxBX6qeQ39d5WyKc8v+G01DJuDzs2Tx368QoK86vm/ qo9ERdT7koRt+gBZNYv8V4fh2SjaFsy2TJq/tiYcSia9snGDTFj6LWVM 6sBCYQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+k.root-servers.net. IN A
+SECTION ANSWER
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 2592000 IN RRSIG A 8 3 3600000 20170409093827 20170310093827 20661 . feIXXjskcsyH+ALZu67GVDaPWXjUGTWsTlDwzgJcLBzSuRVY/GVD5Z1Q B4/oUW99rLKB5bNS1MuasZ+nZFV67sBwJk1+SqNB2bAe7G5Tv1sR2Qgi qDAoB37YDVk5JGHfuxByLYbAVG9PrPXT60BN17OYrD/TFPzprye65gk3 7l9kPpAlblcsqdvh5piKrWc7VBcyMhlp56qdASNAl+Lrb+i0DZYyJXh+ b8LV5g5zp9FaVGKe0Gi4+yDXVjcM6VEtuNRAu2+flLoc3ho6qQF1Po4Y wueL72I+yFoUxkIOJvK47eWb+YUBIBK/L8/ORjYoLBRsrbc79wb0I3Zj Xy6O4Q==
+ENTRY_END
+
+; QTYPE == RRSIG is not supported, https://tools.ietf.org/html/draft-ietf-dnsop-refuse-any-04#section-7
+ENTRY_BEGIN
+MATCH opcode qtype
+ADJUST copy_id copy_query
+REPLY QR AA REFUSED
+SECTION QUESTION
+. IN RRSIG
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+. IN NS
+ENTRY_END
+
+
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA DO SERVFAIL
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/val_minimal_badrrsiginception.rpl b/tests/integration/deckard/sets/resolver/val_minimal_badrrsiginception.rpl
new file mode 100644
index 0000000..ad8e739
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_minimal_badrrsiginception.rpl
@@ -0,0 +1,88 @@
+ trust-anchor: ". IN DS 49060 8 2 E7B1EB56D7D5791B3D45630FEAA9C823DB84B385ACEEAC5F44DD08885C36700F"
+ val-override-date: "20170401000000"
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+ query-minimization: off
+CONFIG_END
+
+SCENARIO_BEGIN Changed RRSIG inception.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ ADDRESS 2001:7fd::1
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. 518400 IN NS k.root-servers.net.
+. 518400 IN RRSIG NS 8 0 518400 20170409093827 20170310093828 20661 . uBuJpbRh1NYVciSKK0r3SA6NFnqE4s/+CqLfTXu26/HrY5c1aOhQHXZM cCDDjfPGFa7Eh4mqF0i9I+i+bFbYQitI1Heexye599VE19REbVsK4qaU xkArvt9k6HVqd/7BXXUyzLN1N0CScdyuT5tiEI9154SDNVpnC+z8i2u0 9hW8JEk4qqVWX/I1MYQB/UOcFSeDhD1Qku/26opqDuLl/1eaShxhMQ/c rjzOb5ZYzD0x+TUJZMYSOMwAraaFuYTT84oe6QYY+EGctAk1b50nA/5E C3Tm/xGuo9ioVtYhTwoo1XDUVeHmghdILjQZvR4pOSZoRGGP9ovb08Qg OmPXuQ== ; inception changed from 20170310093827 to 20170310093828
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+. IN DNSKEY
+SECTION ANSWER
+. 3600000 IN DNSKEY 256 3 8 AwEAAe1oA46eOLNris1CtS0qM5TdMESK6i4hpalqa6JDv57eOUkaOeje ZW1tIFUokmaK7kuKEFEosddA89CYM8rt2RbC+sfKalbHAWOus0tXZyAL efb2sW95QRzyG6LNul0jQFn9eYWBUHrVe5Wqd0zrFCbTQLUhELSfrlkI UBpO/xKaGinRHX2JjyOnle4aPZY3bEVa/+KyY2ZU6UC4SBo3aHXanP26 ok91rOTmpTWp64ybsMdCXOU8deyuQFQf6q8DhIDmJrkymhX1MXWQQlE0 fAYIYf8/t9OCwucg8oEg4FPU8Gb4Zm/l6PgO4HFkFjBT6iGFCQt3qXe2 Qe3alUWoATc=
+. 3600000 IN DNSKEY 257 3 8 AwEAAb8sZgVVa02muJ+/+SVhJAvz2EWKGEGquhPbQXuF6ALBYoF4KWTO bZVF8sIVTGoaX5+UWkwwHthg7RwS1DALT/AJymYeHhUwA04gLsfCZ/cv BjmRy5RozeSJ1uxAhoCYHCT2hQBZ0cH0n8roXFXI2Y+6708pO1IBkTPT 9MpAGfezTtGYOortbSn+vqT/Zu8jOpNwkleXON4rlZRBZPd4JUMGL9Y5 N/j6+ClYeM+eFQTKXrLi1oC+0yK1sG5OlqrBDhAhBnz+IhfZz4TOkqJ9 Li2BVMatHBeB9GQHtu0FZuC3J0EQgiZxvq1RgkefFJAiB+5uVRN8U7up 5mLDxSgmT0M=
+. 2592000 IN RRSIG DNSKEY 8 0 3600000 20170409093827 20170310093827 49060 . G7s3QiWNgOsl+LoG6OKjdBHPcFyhmCS17GFnaKjfJNdPQaFL5nM/vrXo eUIIdJXAvjj62TY7wTyFlnx3yjK93RVGKEEySpGC/1gkn5AdjVoQszog IxYjKzubizULSaX7SQ3/Ar+uHLxakdS1qgNdFu6hHCl857LJPtmC8SJt iFUmm5HFyARokMrfA88VrFRKEqojcCWajeZMfRtgBipFJZoYgPUCaFlz 8OupNdNUWCbGhnDWrXCWMzeKVXTQVlJf75PXXgtkuBUmr5RSWu7AYr+c wTJ4E4610goRqYxnZ33efKE/MuhKeY66xelPh0sirPrBMR5JAlyjV3k1 qDzhcQ==
+
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+k.root-servers.net. IN AAAA
+SECTION ANSWER
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+k.root-servers.net. 2592000 IN RRSIG AAAA 8 3 3600000 20170409093827 20170310093827 20661 . qjVXwuxzmoRhdrXyQvKfrrzFxGiYuTTJHxwZPasJ1nVmN48dPyU6wA55 JeqoJv1Jm+XvIL1q0WtX6Zh6KLt6vVjHuMkhmFuIZYkFi/dmsEwFY8C0 ebyXyztQT5+6FOSVTAKacYc40LfBo8FqEn8RYlCu1mkAd8ANvvLrdLWW W03LVOY7JlCzyrKlAlmPmuV8z+e9PxNkUh6KfTEvAReoAAX7wYZkdefg 2d64c7rNWXvYm6LxBX6qeQ39d5WyKc8v+G01DJuDzs2Tx368QoK86vm/ qo9ERdT7koRt+gBZNYv8V4fh2SjaFsy2TJq/tiYcSia9snGDTFj6LWVM 6sBCYQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+k.root-servers.net. IN A
+SECTION ANSWER
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 2592000 IN RRSIG A 8 3 3600000 20170409093827 20170310093827 20661 . feIXXjskcsyH+ALZu67GVDaPWXjUGTWsTlDwzgJcLBzSuRVY/GVD5Z1Q B4/oUW99rLKB5bNS1MuasZ+nZFV67sBwJk1+SqNB2bAe7G5Tv1sR2Qgi qDAoB37YDVk5JGHfuxByLYbAVG9PrPXT60BN17OYrD/TFPzprye65gk3 7l9kPpAlblcsqdvh5piKrWc7VBcyMhlp56qdASNAl+Lrb+i0DZYyJXh+ b8LV5g5zp9FaVGKe0Gi4+yDXVjcM6VEtuNRAu2+flLoc3ho6qQF1Po4Y wueL72I+yFoUxkIOJvK47eWb+YUBIBK/L8/ORjYoLBRsrbc79wb0I3Zj Xy6O4Q==
+ENTRY_END
+
+; QTYPE == RRSIG is not supported, https://tools.ietf.org/html/draft-ietf-dnsop-refuse-any-04#section-7
+ENTRY_BEGIN
+MATCH opcode qtype
+ADJUST copy_id copy_query
+REPLY QR AA REFUSED
+SECTION QUESTION
+. IN RRSIG
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+. IN NS
+ENTRY_END
+
+
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA DO SERVFAIL
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/val_minimal_badrrsiglabels.rpl b/tests/integration/deckard/sets/resolver/val_minimal_badrrsiglabels.rpl
new file mode 100644
index 0000000..af15124
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_minimal_badrrsiglabels.rpl
@@ -0,0 +1,88 @@
+ trust-anchor: ". IN DS 49060 8 2 E7B1EB56D7D5791B3D45630FEAA9C823DB84B385ACEEAC5F44DD08885C36700F"
+ val-override-date: "20170401000000"
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+ query-minimization: off
+CONFIG_END
+
+SCENARIO_BEGIN Changed RRSIG labels.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ ADDRESS 2001:7fd::1
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. 518400 IN NS k.root-servers.net.
+. 518400 IN RRSIG NS 8 1 518400 20170409093827 20170310093827 20661 . uBuJpbRh1NYVciSKK0r3SA6NFnqE4s/+CqLfTXu26/HrY5c1aOhQHXZM cCDDjfPGFa7Eh4mqF0i9I+i+bFbYQitI1Heexye599VE19REbVsK4qaU xkArvt9k6HVqd/7BXXUyzLN1N0CScdyuT5tiEI9154SDNVpnC+z8i2u0 9hW8JEk4qqVWX/I1MYQB/UOcFSeDhD1Qku/26opqDuLl/1eaShxhMQ/c rjzOb5ZYzD0x+TUJZMYSOMwAraaFuYTT84oe6QYY+EGctAk1b50nA/5E C3Tm/xGuo9ioVtYhTwoo1XDUVeHmghdILjQZvR4pOSZoRGGP9ovb08Qg OmPXuQ== ; labels changed from 0 to 1
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+. IN DNSKEY
+SECTION ANSWER
+. 3600000 IN DNSKEY 256 3 8 AwEAAe1oA46eOLNris1CtS0qM5TdMESK6i4hpalqa6JDv57eOUkaOeje ZW1tIFUokmaK7kuKEFEosddA89CYM8rt2RbC+sfKalbHAWOus0tXZyAL efb2sW95QRzyG6LNul0jQFn9eYWBUHrVe5Wqd0zrFCbTQLUhELSfrlkI UBpO/xKaGinRHX2JjyOnle4aPZY3bEVa/+KyY2ZU6UC4SBo3aHXanP26 ok91rOTmpTWp64ybsMdCXOU8deyuQFQf6q8DhIDmJrkymhX1MXWQQlE0 fAYIYf8/t9OCwucg8oEg4FPU8Gb4Zm/l6PgO4HFkFjBT6iGFCQt3qXe2 Qe3alUWoATc=
+. 3600000 IN DNSKEY 257 3 8 AwEAAb8sZgVVa02muJ+/+SVhJAvz2EWKGEGquhPbQXuF6ALBYoF4KWTO bZVF8sIVTGoaX5+UWkwwHthg7RwS1DALT/AJymYeHhUwA04gLsfCZ/cv BjmRy5RozeSJ1uxAhoCYHCT2hQBZ0cH0n8roXFXI2Y+6708pO1IBkTPT 9MpAGfezTtGYOortbSn+vqT/Zu8jOpNwkleXON4rlZRBZPd4JUMGL9Y5 N/j6+ClYeM+eFQTKXrLi1oC+0yK1sG5OlqrBDhAhBnz+IhfZz4TOkqJ9 Li2BVMatHBeB9GQHtu0FZuC3J0EQgiZxvq1RgkefFJAiB+5uVRN8U7up 5mLDxSgmT0M=
+. 2592000 IN RRSIG DNSKEY 8 0 3600000 20170409093827 20170310093827 49060 . G7s3QiWNgOsl+LoG6OKjdBHPcFyhmCS17GFnaKjfJNdPQaFL5nM/vrXo eUIIdJXAvjj62TY7wTyFlnx3yjK93RVGKEEySpGC/1gkn5AdjVoQszog IxYjKzubizULSaX7SQ3/Ar+uHLxakdS1qgNdFu6hHCl857LJPtmC8SJt iFUmm5HFyARokMrfA88VrFRKEqojcCWajeZMfRtgBipFJZoYgPUCaFlz 8OupNdNUWCbGhnDWrXCWMzeKVXTQVlJf75PXXgtkuBUmr5RSWu7AYr+c wTJ4E4610goRqYxnZ33efKE/MuhKeY66xelPh0sirPrBMR5JAlyjV3k1 qDzhcQ==
+
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+k.root-servers.net. IN AAAA
+SECTION ANSWER
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+k.root-servers.net. 2592000 IN RRSIG AAAA 8 3 3600000 20170409093827 20170310093827 20661 . qjVXwuxzmoRhdrXyQvKfrrzFxGiYuTTJHxwZPasJ1nVmN48dPyU6wA55 JeqoJv1Jm+XvIL1q0WtX6Zh6KLt6vVjHuMkhmFuIZYkFi/dmsEwFY8C0 ebyXyztQT5+6FOSVTAKacYc40LfBo8FqEn8RYlCu1mkAd8ANvvLrdLWW W03LVOY7JlCzyrKlAlmPmuV8z+e9PxNkUh6KfTEvAReoAAX7wYZkdefg 2d64c7rNWXvYm6LxBX6qeQ39d5WyKc8v+G01DJuDzs2Tx368QoK86vm/ qo9ERdT7koRt+gBZNYv8V4fh2SjaFsy2TJq/tiYcSia9snGDTFj6LWVM 6sBCYQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+k.root-servers.net. IN A
+SECTION ANSWER
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 2592000 IN RRSIG A 8 3 3600000 20170409093827 20170310093827 20661 . feIXXjskcsyH+ALZu67GVDaPWXjUGTWsTlDwzgJcLBzSuRVY/GVD5Z1Q B4/oUW99rLKB5bNS1MuasZ+nZFV67sBwJk1+SqNB2bAe7G5Tv1sR2Qgi qDAoB37YDVk5JGHfuxByLYbAVG9PrPXT60BN17OYrD/TFPzprye65gk3 7l9kPpAlblcsqdvh5piKrWc7VBcyMhlp56qdASNAl+Lrb+i0DZYyJXh+ b8LV5g5zp9FaVGKe0Gi4+yDXVjcM6VEtuNRAu2+flLoc3ho6qQF1Po4Y wueL72I+yFoUxkIOJvK47eWb+YUBIBK/L8/ORjYoLBRsrbc79wb0I3Zj Xy6O4Q==
+ENTRY_END
+
+; QTYPE == RRSIG is not supported, https://tools.ietf.org/html/draft-ietf-dnsop-refuse-any-04#section-7
+ENTRY_BEGIN
+MATCH opcode qtype
+ADJUST copy_id copy_query
+REPLY QR AA REFUSED
+SECTION QUESTION
+. IN RRSIG
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+. IN NS
+ENTRY_END
+
+
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA DO SERVFAIL
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/val_minimal_badrrsigsignature.rpl b/tests/integration/deckard/sets/resolver/val_minimal_badrrsigsignature.rpl
new file mode 100644
index 0000000..61c5e16
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_minimal_badrrsigsignature.rpl
@@ -0,0 +1,88 @@
+ trust-anchor: ". IN DS 49060 8 2 E7B1EB56D7D5791B3D45630FEAA9C823DB84B385ACEEAC5F44DD08885C36700F"
+ val-override-date: "20170401000000"
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+ query-minimization: off
+CONFIG_END
+
+SCENARIO_BEGIN Changed RRSIG signature.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ ADDRESS 2001:7fd::1
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. 518400 IN NS k.root-servers.net.
+. 518400 IN RRSIG NS 8 0 518400 20170409093827 20170310093827 20661 . ABuJpbRh1NYVciSKK0r3SA6NFnqE4s/+CqLfTXu26/HrY5c1aOhQHXZM cCDDjfPGFa7Eh4mqF0i9I+i+bFbYQitI1Heexye599VE19REbVsK4qaU xkArvt9k6HVqd/7BXXUyzLN1N0CScdyuT5tiEI9154SDNVpnC+z8i2u0 9hW8JEk4qqVWX/I1MYQB/UOcFSeDhD1Qku/26opqDuLl/1eaShxhMQ/c rjzOb5ZYzD0x+TUJZMYSOMwAraaFuYTT84oe6QYY+EGctAk1b50nA/5E C3Tm/xGuo9ioVtYhTwoo1XDUVeHmghdILjQZvR4pOSZoRGGP9ovb08Qg OmPXuQ== ; changed signature
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+. IN DNSKEY
+SECTION ANSWER
+. 3600000 IN DNSKEY 256 3 8 AwEAAe1oA46eOLNris1CtS0qM5TdMESK6i4hpalqa6JDv57eOUkaOeje ZW1tIFUokmaK7kuKEFEosddA89CYM8rt2RbC+sfKalbHAWOus0tXZyAL efb2sW95QRzyG6LNul0jQFn9eYWBUHrVe5Wqd0zrFCbTQLUhELSfrlkI UBpO/xKaGinRHX2JjyOnle4aPZY3bEVa/+KyY2ZU6UC4SBo3aHXanP26 ok91rOTmpTWp64ybsMdCXOU8deyuQFQf6q8DhIDmJrkymhX1MXWQQlE0 fAYIYf8/t9OCwucg8oEg4FPU8Gb4Zm/l6PgO4HFkFjBT6iGFCQt3qXe2 Qe3alUWoATc=
+. 3600000 IN DNSKEY 257 3 8 AwEAAb8sZgVVa02muJ+/+SVhJAvz2EWKGEGquhPbQXuF6ALBYoF4KWTO bZVF8sIVTGoaX5+UWkwwHthg7RwS1DALT/AJymYeHhUwA04gLsfCZ/cv BjmRy5RozeSJ1uxAhoCYHCT2hQBZ0cH0n8roXFXI2Y+6708pO1IBkTPT 9MpAGfezTtGYOortbSn+vqT/Zu8jOpNwkleXON4rlZRBZPd4JUMGL9Y5 N/j6+ClYeM+eFQTKXrLi1oC+0yK1sG5OlqrBDhAhBnz+IhfZz4TOkqJ9 Li2BVMatHBeB9GQHtu0FZuC3J0EQgiZxvq1RgkefFJAiB+5uVRN8U7up 5mLDxSgmT0M=
+. 2592000 IN RRSIG DNSKEY 8 0 3600000 20170409093827 20170310093827 49060 . G7s3QiWNgOsl+LoG6OKjdBHPcFyhmCS17GFnaKjfJNdPQaFL5nM/vrXo eUIIdJXAvjj62TY7wTyFlnx3yjK93RVGKEEySpGC/1gkn5AdjVoQszog IxYjKzubizULSaX7SQ3/Ar+uHLxakdS1qgNdFu6hHCl857LJPtmC8SJt iFUmm5HFyARokMrfA88VrFRKEqojcCWajeZMfRtgBipFJZoYgPUCaFlz 8OupNdNUWCbGhnDWrXCWMzeKVXTQVlJf75PXXgtkuBUmr5RSWu7AYr+c wTJ4E4610goRqYxnZ33efKE/MuhKeY66xelPh0sirPrBMR5JAlyjV3k1 qDzhcQ==
+
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+k.root-servers.net. IN AAAA
+SECTION ANSWER
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+k.root-servers.net. 2592000 IN RRSIG AAAA 8 3 3600000 20170409093827 20170310093827 20661 . qjVXwuxzmoRhdrXyQvKfrrzFxGiYuTTJHxwZPasJ1nVmN48dPyU6wA55 JeqoJv1Jm+XvIL1q0WtX6Zh6KLt6vVjHuMkhmFuIZYkFi/dmsEwFY8C0 ebyXyztQT5+6FOSVTAKacYc40LfBo8FqEn8RYlCu1mkAd8ANvvLrdLWW W03LVOY7JlCzyrKlAlmPmuV8z+e9PxNkUh6KfTEvAReoAAX7wYZkdefg 2d64c7rNWXvYm6LxBX6qeQ39d5WyKc8v+G01DJuDzs2Tx368QoK86vm/ qo9ERdT7koRt+gBZNYv8V4fh2SjaFsy2TJq/tiYcSia9snGDTFj6LWVM 6sBCYQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+k.root-servers.net. IN A
+SECTION ANSWER
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 2592000 IN RRSIG A 8 3 3600000 20170409093827 20170310093827 20661 . feIXXjskcsyH+ALZu67GVDaPWXjUGTWsTlDwzgJcLBzSuRVY/GVD5Z1Q B4/oUW99rLKB5bNS1MuasZ+nZFV67sBwJk1+SqNB2bAe7G5Tv1sR2Qgi qDAoB37YDVk5JGHfuxByLYbAVG9PrPXT60BN17OYrD/TFPzprye65gk3 7l9kPpAlblcsqdvh5piKrWc7VBcyMhlp56qdASNAl+Lrb+i0DZYyJXh+ b8LV5g5zp9FaVGKe0Gi4+yDXVjcM6VEtuNRAu2+flLoc3ho6qQF1Po4Y wueL72I+yFoUxkIOJvK47eWb+YUBIBK/L8/ORjYoLBRsrbc79wb0I3Zj Xy6O4Q==
+ENTRY_END
+
+; QTYPE == RRSIG is not supported, https://tools.ietf.org/html/draft-ietf-dnsop-refuse-any-04#section-7
+ENTRY_BEGIN
+MATCH opcode qtype
+ADJUST copy_id copy_query
+REPLY QR AA REFUSED
+SECTION QUESTION
+. IN RRSIG
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+. IN NS
+ENTRY_END
+
+
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA DO SERVFAIL
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/val_minimal_badrrsigtag.rpl b/tests/integration/deckard/sets/resolver/val_minimal_badrrsigtag.rpl
new file mode 100644
index 0000000..e587c2c
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_minimal_badrrsigtag.rpl
@@ -0,0 +1,88 @@
+ trust-anchor: ". IN DS 49060 8 2 E7B1EB56D7D5791B3D45630FEAA9C823DB84B385ACEEAC5F44DD08885C36700F"
+ val-override-date: "20170401000000"
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+ query-minimization: off
+CONFIG_END
+
+SCENARIO_BEGIN Changed RRSIG tag.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ ADDRESS 2001:7fd::1
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. 518400 IN NS k.root-servers.net.
+. 518400 IN RRSIG NS 8 0 518400 20170409093827 20170310093827 20662 . uBuJpbRh1NYVciSKK0r3SA6NFnqE4s/+CqLfTXu26/HrY5c1aOhQHXZM cCDDjfPGFa7Eh4mqF0i9I+i+bFbYQitI1Heexye599VE19REbVsK4qaU xkArvt9k6HVqd/7BXXUyzLN1N0CScdyuT5tiEI9154SDNVpnC+z8i2u0 9hW8JEk4qqVWX/I1MYQB/UOcFSeDhD1Qku/26opqDuLl/1eaShxhMQ/c rjzOb5ZYzD0x+TUJZMYSOMwAraaFuYTT84oe6QYY+EGctAk1b50nA/5E C3Tm/xGuo9ioVtYhTwoo1XDUVeHmghdILjQZvR4pOSZoRGGP9ovb08Qg OmPXuQ== ; tag changed from 20661 to 20662
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+. IN DNSKEY
+SECTION ANSWER
+. 3600000 IN DNSKEY 256 3 8 AwEAAe1oA46eOLNris1CtS0qM5TdMESK6i4hpalqa6JDv57eOUkaOeje ZW1tIFUokmaK7kuKEFEosddA89CYM8rt2RbC+sfKalbHAWOus0tXZyAL efb2sW95QRzyG6LNul0jQFn9eYWBUHrVe5Wqd0zrFCbTQLUhELSfrlkI UBpO/xKaGinRHX2JjyOnle4aPZY3bEVa/+KyY2ZU6UC4SBo3aHXanP26 ok91rOTmpTWp64ybsMdCXOU8deyuQFQf6q8DhIDmJrkymhX1MXWQQlE0 fAYIYf8/t9OCwucg8oEg4FPU8Gb4Zm/l6PgO4HFkFjBT6iGFCQt3qXe2 Qe3alUWoATc=
+. 3600000 IN DNSKEY 257 3 8 AwEAAb8sZgVVa02muJ+/+SVhJAvz2EWKGEGquhPbQXuF6ALBYoF4KWTO bZVF8sIVTGoaX5+UWkwwHthg7RwS1DALT/AJymYeHhUwA04gLsfCZ/cv BjmRy5RozeSJ1uxAhoCYHCT2hQBZ0cH0n8roXFXI2Y+6708pO1IBkTPT 9MpAGfezTtGYOortbSn+vqT/Zu8jOpNwkleXON4rlZRBZPd4JUMGL9Y5 N/j6+ClYeM+eFQTKXrLi1oC+0yK1sG5OlqrBDhAhBnz+IhfZz4TOkqJ9 Li2BVMatHBeB9GQHtu0FZuC3J0EQgiZxvq1RgkefFJAiB+5uVRN8U7up 5mLDxSgmT0M=
+. 2592000 IN RRSIG DNSKEY 8 0 3600000 20170409093827 20170310093827 49060 . G7s3QiWNgOsl+LoG6OKjdBHPcFyhmCS17GFnaKjfJNdPQaFL5nM/vrXo eUIIdJXAvjj62TY7wTyFlnx3yjK93RVGKEEySpGC/1gkn5AdjVoQszog IxYjKzubizULSaX7SQ3/Ar+uHLxakdS1qgNdFu6hHCl857LJPtmC8SJt iFUmm5HFyARokMrfA88VrFRKEqojcCWajeZMfRtgBipFJZoYgPUCaFlz 8OupNdNUWCbGhnDWrXCWMzeKVXTQVlJf75PXXgtkuBUmr5RSWu7AYr+c wTJ4E4610goRqYxnZ33efKE/MuhKeY66xelPh0sirPrBMR5JAlyjV3k1 qDzhcQ==
+
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+k.root-servers.net. IN AAAA
+SECTION ANSWER
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+k.root-servers.net. 2592000 IN RRSIG AAAA 8 3 3600000 20170409093827 20170310093827 20661 . qjVXwuxzmoRhdrXyQvKfrrzFxGiYuTTJHxwZPasJ1nVmN48dPyU6wA55 JeqoJv1Jm+XvIL1q0WtX6Zh6KLt6vVjHuMkhmFuIZYkFi/dmsEwFY8C0 ebyXyztQT5+6FOSVTAKacYc40LfBo8FqEn8RYlCu1mkAd8ANvvLrdLWW W03LVOY7JlCzyrKlAlmPmuV8z+e9PxNkUh6KfTEvAReoAAX7wYZkdefg 2d64c7rNWXvYm6LxBX6qeQ39d5WyKc8v+G01DJuDzs2Tx368QoK86vm/ qo9ERdT7koRt+gBZNYv8V4fh2SjaFsy2TJq/tiYcSia9snGDTFj6LWVM 6sBCYQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+k.root-servers.net. IN A
+SECTION ANSWER
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 2592000 IN RRSIG A 8 3 3600000 20170409093827 20170310093827 20661 . feIXXjskcsyH+ALZu67GVDaPWXjUGTWsTlDwzgJcLBzSuRVY/GVD5Z1Q B4/oUW99rLKB5bNS1MuasZ+nZFV67sBwJk1+SqNB2bAe7G5Tv1sR2Qgi qDAoB37YDVk5JGHfuxByLYbAVG9PrPXT60BN17OYrD/TFPzprye65gk3 7l9kPpAlblcsqdvh5piKrWc7VBcyMhlp56qdASNAl+Lrb+i0DZYyJXh+ b8LV5g5zp9FaVGKe0Gi4+yDXVjcM6VEtuNRAu2+flLoc3ho6qQF1Po4Y wueL72I+yFoUxkIOJvK47eWb+YUBIBK/L8/ORjYoLBRsrbc79wb0I3Zj Xy6O4Q==
+ENTRY_END
+
+; QTYPE == RRSIG is not supported, https://tools.ietf.org/html/draft-ietf-dnsop-refuse-any-04#section-7
+ENTRY_BEGIN
+MATCH opcode qtype
+ADJUST copy_id copy_query
+REPLY QR AA REFUSED
+SECTION QUESTION
+. IN RRSIG
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+. IN NS
+ENTRY_END
+
+
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA DO SERVFAIL
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/val_minimal_badrrsigttl.rpl b/tests/integration/deckard/sets/resolver/val_minimal_badrrsigttl.rpl
new file mode 100644
index 0000000..ac39109
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_minimal_badrrsigttl.rpl
@@ -0,0 +1,88 @@
+ trust-anchor: ". IN DS 49060 8 2 E7B1EB56D7D5791B3D45630FEAA9C823DB84B385ACEEAC5F44DD08885C36700F"
+ val-override-date: "20170401000000"
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+ query-minimization: off
+CONFIG_END
+
+SCENARIO_BEGIN Changed RRSIG original TTL.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ ADDRESS 2001:7fd::1
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. 518400 IN NS k.root-servers.net.
+. 518400 IN RRSIG NS 8 0 518401 20170409093827 20170310093827 20661 . uBuJpbRh1NYVciSKK0r3SA6NFnqE4s/+CqLfTXu26/HrY5c1aOhQHXZM cCDDjfPGFa7Eh4mqF0i9I+i+bFbYQitI1Heexye599VE19REbVsK4qaU xkArvt9k6HVqd/7BXXUyzLN1N0CScdyuT5tiEI9154SDNVpnC+z8i2u0 9hW8JEk4qqVWX/I1MYQB/UOcFSeDhD1Qku/26opqDuLl/1eaShxhMQ/c rjzOb5ZYzD0x+TUJZMYSOMwAraaFuYTT84oe6QYY+EGctAk1b50nA/5E C3Tm/xGuo9ioVtYhTwoo1XDUVeHmghdILjQZvR4pOSZoRGGP9ovb08Qg OmPXuQ== ; original TTL changed from 518400 to 518401
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+. IN DNSKEY
+SECTION ANSWER
+. 3600000 IN DNSKEY 256 3 8 AwEAAe1oA46eOLNris1CtS0qM5TdMESK6i4hpalqa6JDv57eOUkaOeje ZW1tIFUokmaK7kuKEFEosddA89CYM8rt2RbC+sfKalbHAWOus0tXZyAL efb2sW95QRzyG6LNul0jQFn9eYWBUHrVe5Wqd0zrFCbTQLUhELSfrlkI UBpO/xKaGinRHX2JjyOnle4aPZY3bEVa/+KyY2ZU6UC4SBo3aHXanP26 ok91rOTmpTWp64ybsMdCXOU8deyuQFQf6q8DhIDmJrkymhX1MXWQQlE0 fAYIYf8/t9OCwucg8oEg4FPU8Gb4Zm/l6PgO4HFkFjBT6iGFCQt3qXe2 Qe3alUWoATc=
+. 3600000 IN DNSKEY 257 3 8 AwEAAb8sZgVVa02muJ+/+SVhJAvz2EWKGEGquhPbQXuF6ALBYoF4KWTO bZVF8sIVTGoaX5+UWkwwHthg7RwS1DALT/AJymYeHhUwA04gLsfCZ/cv BjmRy5RozeSJ1uxAhoCYHCT2hQBZ0cH0n8roXFXI2Y+6708pO1IBkTPT 9MpAGfezTtGYOortbSn+vqT/Zu8jOpNwkleXON4rlZRBZPd4JUMGL9Y5 N/j6+ClYeM+eFQTKXrLi1oC+0yK1sG5OlqrBDhAhBnz+IhfZz4TOkqJ9 Li2BVMatHBeB9GQHtu0FZuC3J0EQgiZxvq1RgkefFJAiB+5uVRN8U7up 5mLDxSgmT0M=
+. 2592000 IN RRSIG DNSKEY 8 0 3600000 20170409093827 20170310093827 49060 . G7s3QiWNgOsl+LoG6OKjdBHPcFyhmCS17GFnaKjfJNdPQaFL5nM/vrXo eUIIdJXAvjj62TY7wTyFlnx3yjK93RVGKEEySpGC/1gkn5AdjVoQszog IxYjKzubizULSaX7SQ3/Ar+uHLxakdS1qgNdFu6hHCl857LJPtmC8SJt iFUmm5HFyARokMrfA88VrFRKEqojcCWajeZMfRtgBipFJZoYgPUCaFlz 8OupNdNUWCbGhnDWrXCWMzeKVXTQVlJf75PXXgtkuBUmr5RSWu7AYr+c wTJ4E4610goRqYxnZ33efKE/MuhKeY66xelPh0sirPrBMR5JAlyjV3k1 qDzhcQ==
+
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+k.root-servers.net. IN AAAA
+SECTION ANSWER
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+k.root-servers.net. 2592000 IN RRSIG AAAA 8 3 3600000 20170409093827 20170310093827 20661 . qjVXwuxzmoRhdrXyQvKfrrzFxGiYuTTJHxwZPasJ1nVmN48dPyU6wA55 JeqoJv1Jm+XvIL1q0WtX6Zh6KLt6vVjHuMkhmFuIZYkFi/dmsEwFY8C0 ebyXyztQT5+6FOSVTAKacYc40LfBo8FqEn8RYlCu1mkAd8ANvvLrdLWW W03LVOY7JlCzyrKlAlmPmuV8z+e9PxNkUh6KfTEvAReoAAX7wYZkdefg 2d64c7rNWXvYm6LxBX6qeQ39d5WyKc8v+G01DJuDzs2Tx368QoK86vm/ qo9ERdT7koRt+gBZNYv8V4fh2SjaFsy2TJq/tiYcSia9snGDTFj6LWVM 6sBCYQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+k.root-servers.net. IN A
+SECTION ANSWER
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 2592000 IN RRSIG A 8 3 3600000 20170409093827 20170310093827 20661 . feIXXjskcsyH+ALZu67GVDaPWXjUGTWsTlDwzgJcLBzSuRVY/GVD5Z1Q B4/oUW99rLKB5bNS1MuasZ+nZFV67sBwJk1+SqNB2bAe7G5Tv1sR2Qgi qDAoB37YDVk5JGHfuxByLYbAVG9PrPXT60BN17OYrD/TFPzprye65gk3 7l9kPpAlblcsqdvh5piKrWc7VBcyMhlp56qdASNAl+Lrb+i0DZYyJXh+ b8LV5g5zp9FaVGKe0Gi4+yDXVjcM6VEtuNRAu2+flLoc3ho6qQF1Po4Y wueL72I+yFoUxkIOJvK47eWb+YUBIBK/L8/ORjYoLBRsrbc79wb0I3Zj Xy6O4Q==
+ENTRY_END
+
+; QTYPE == RRSIG is not supported, https://tools.ietf.org/html/draft-ietf-dnsop-refuse-any-04#section-7
+ENTRY_BEGIN
+MATCH opcode qtype
+ADJUST copy_id copy_query
+REPLY QR AA REFUSED
+SECTION QUESTION
+. IN RRSIG
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+. IN NS
+ENTRY_END
+
+
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA DO SERVFAIL
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/val_minimal_beforeinception.rpl b/tests/integration/deckard/sets/resolver/val_minimal_beforeinception.rpl
new file mode 100644
index 0000000..04820aa
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_minimal_beforeinception.rpl
@@ -0,0 +1,87 @@
+ trust-anchor: ". IN DS 49060 8 2 E7B1EB56D7D5791B3D45630FEAA9C823DB84B385ACEEAC5F44DD08885C36700F"
+ val-override-date: "20170308000000"
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+ query-minimization: off
+CONFIG_END
+
+SCENARIO_BEGIN Date after expiration of signatures.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ ADDRESS 2001:7fd::1
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. 518400 IN NS k.root-servers.net.
+. 518400 IN RRSIG NS 8 0 518400 20170409093827 20170310093827 20661 . uBuJpbRh1NYVciSKK0r3SA6NFnqE4s/+CqLfTXu26/HrY5c1aOhQHXZM cCDDjfPGFa7Eh4mqF0i9I+i+bFbYQitI1Heexye599VE19REbVsK4qaU xkArvt9k6HVqd/7BXXUyzLN1N0CScdyuT5tiEI9154SDNVpnC+z8i2u0 9hW8JEk4qqVWX/I1MYQB/UOcFSeDhD1Qku/26opqDuLl/1eaShxhMQ/c rjzOb5ZYzD0x+TUJZMYSOMwAraaFuYTT84oe6QYY+EGctAk1b50nA/5E C3Tm/xGuo9ioVtYhTwoo1XDUVeHmghdILjQZvR4pOSZoRGGP9ovb08Qg OmPXuQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+. IN DNSKEY
+SECTION ANSWER
+. IN DNSKEY 256 3 8 AwEAAe1oA46eOLNris1CtS0qM5TdMESK6i4hpalqa6JDv57eOUkaOeje ZW1tIFUokmaK7kuKEFEosddA89CYM8rt2RbC+sfKalbHAWOus0tXZyAL efb2sW95QRzyG6LNul0jQFn9eYWBUHrVe5Wqd0zrFCbTQLUhELSfrlkI UBpO/xKaGinRHX2JjyOnle4aPZY3bEVa/+KyY2ZU6UC4SBo3aHXanP26 ok91rOTmpTWp64ybsMdCXOU8deyuQFQf6q8DhIDmJrkymhX1MXWQQlE0 fAYIYf8/t9OCwucg8oEg4FPU8Gb4Zm/l6PgO4HFkFjBT6iGFCQt3qXe2 Qe3alUWoATc=
+. IN DNSKEY 257 3 8 AwEAAb8sZgVVa02muJ+/+SVhJAvz2EWKGEGquhPbQXuF6ALBYoF4KWTO bZVF8sIVTGoaX5+UWkwwHthg7RwS1DALT/AJymYeHhUwA04gLsfCZ/cv BjmRy5RozeSJ1uxAhoCYHCT2hQBZ0cH0n8roXFXI2Y+6708pO1IBkTPT 9MpAGfezTtGYOortbSn+vqT/Zu8jOpNwkleXON4rlZRBZPd4JUMGL9Y5 N/j6+ClYeM+eFQTKXrLi1oC+0yK1sG5OlqrBDhAhBnz+IhfZz4TOkqJ9 Li2BVMatHBeB9GQHtu0FZuC3J0EQgiZxvq1RgkefFJAiB+5uVRN8U7up 5mLDxSgmT0M=
+. 2592000 IN RRSIG DNSKEY 8 0 3600000 20170409093827 20170310093827 49060 . G7s3QiWNgOsl+LoG6OKjdBHPcFyhmCS17GFnaKjfJNdPQaFL5nM/vrXo eUIIdJXAvjj62TY7wTyFlnx3yjK93RVGKEEySpGC/1gkn5AdjVoQszog IxYjKzubizULSaX7SQ3/Ar+uHLxakdS1qgNdFu6hHCl857LJPtmC8SJt iFUmm5HFyARokMrfA88VrFRKEqojcCWajeZMfRtgBipFJZoYgPUCaFlz 8OupNdNUWCbGhnDWrXCWMzeKVXTQVlJf75PXXgtkuBUmr5RSWu7AYr+c wTJ4E4610goRqYxnZ33efKE/MuhKeY66xelPh0sirPrBMR5JAlyjV3k1 qDzhcQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+k.root-servers.net. IN AAAA
+SECTION ANSWER
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+k.root-servers.net. 2592000 IN RRSIG AAAA 8 3 3600000 20170409093827 20170310093827 20661 . qjVXwuxzmoRhdrXyQvKfrrzFxGiYuTTJHxwZPasJ1nVmN48dPyU6wA55 JeqoJv1Jm+XvIL1q0WtX6Zh6KLt6vVjHuMkhmFuIZYkFi/dmsEwFY8C0 ebyXyztQT5+6FOSVTAKacYc40LfBo8FqEn8RYlCu1mkAd8ANvvLrdLWW W03LVOY7JlCzyrKlAlmPmuV8z+e9PxNkUh6KfTEvAReoAAX7wYZkdefg 2d64c7rNWXvYm6LxBX6qeQ39d5WyKc8v+G01DJuDzs2Tx368QoK86vm/ qo9ERdT7koRt+gBZNYv8V4fh2SjaFsy2TJq/tiYcSia9snGDTFj6LWVM 6sBCYQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+k.root-servers.net. IN A
+SECTION ANSWER
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 2592000 IN RRSIG A 8 3 3600000 20170409093827 20170310093827 20661 . feIXXjskcsyH+ALZu67GVDaPWXjUGTWsTlDwzgJcLBzSuRVY/GVD5Z1Q B4/oUW99rLKB5bNS1MuasZ+nZFV67sBwJk1+SqNB2bAe7G5Tv1sR2Qgi qDAoB37YDVk5JGHfuxByLYbAVG9PrPXT60BN17OYrD/TFPzprye65gk3 7l9kPpAlblcsqdvh5piKrWc7VBcyMhlp56qdASNAl+Lrb+i0DZYyJXh+ b8LV5g5zp9FaVGKe0Gi4+yDXVjcM6VEtuNRAu2+flLoc3ho6qQF1Po4Y wueL72I+yFoUxkIOJvK47eWb+YUBIBK/L8/ORjYoLBRsrbc79wb0I3Zj Xy6O4Q==
+ENTRY_END
+
+; QTYPE == RRSIG is not supported, https://tools.ietf.org/html/draft-ietf-dnsop-refuse-any-04#section-7
+ENTRY_BEGIN
+MATCH opcode qtype
+ADJUST copy_id copy_query
+REPLY QR AA REFUSED
+SECTION QUESTION
+. IN RRSIG
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+. IN NS
+ENTRY_END
+
+
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA DO SERVFAIL
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/val_minimal_expiredsignature.rpl b/tests/integration/deckard/sets/resolver/val_minimal_expiredsignature.rpl
new file mode 100644
index 0000000..b271518
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_minimal_expiredsignature.rpl
@@ -0,0 +1,87 @@
+ trust-anchor: ". IN DS 49060 8 2 E7B1EB56D7D5791B3D45630FEAA9C823DB84B385ACEEAC5F44DD08885C36700F"
+ val-override-date: "20170410000000"
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+ query-minimization: off
+CONFIG_END
+
+SCENARIO_BEGIN Date after expiration of signatures.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ ADDRESS 2001:7fd::1
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. 518400 IN NS k.root-servers.net.
+. 518400 IN RRSIG NS 8 0 518400 20170409093827 20170310093827 20661 . uBuJpbRh1NYVciSKK0r3SA6NFnqE4s/+CqLfTXu26/HrY5c1aOhQHXZM cCDDjfPGFa7Eh4mqF0i9I+i+bFbYQitI1Heexye599VE19REbVsK4qaU xkArvt9k6HVqd/7BXXUyzLN1N0CScdyuT5tiEI9154SDNVpnC+z8i2u0 9hW8JEk4qqVWX/I1MYQB/UOcFSeDhD1Qku/26opqDuLl/1eaShxhMQ/c rjzOb5ZYzD0x+TUJZMYSOMwAraaFuYTT84oe6QYY+EGctAk1b50nA/5E C3Tm/xGuo9ioVtYhTwoo1XDUVeHmghdILjQZvR4pOSZoRGGP9ovb08Qg OmPXuQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+. IN DNSKEY
+SECTION ANSWER
+. IN DNSKEY 256 3 8 AwEAAe1oA46eOLNris1CtS0qM5TdMESK6i4hpalqa6JDv57eOUkaOeje ZW1tIFUokmaK7kuKEFEosddA89CYM8rt2RbC+sfKalbHAWOus0tXZyAL efb2sW95QRzyG6LNul0jQFn9eYWBUHrVe5Wqd0zrFCbTQLUhELSfrlkI UBpO/xKaGinRHX2JjyOnle4aPZY3bEVa/+KyY2ZU6UC4SBo3aHXanP26 ok91rOTmpTWp64ybsMdCXOU8deyuQFQf6q8DhIDmJrkymhX1MXWQQlE0 fAYIYf8/t9OCwucg8oEg4FPU8Gb4Zm/l6PgO4HFkFjBT6iGFCQt3qXe2 Qe3alUWoATc=
+. IN DNSKEY 257 3 8 AwEAAb8sZgVVa02muJ+/+SVhJAvz2EWKGEGquhPbQXuF6ALBYoF4KWTO bZVF8sIVTGoaX5+UWkwwHthg7RwS1DALT/AJymYeHhUwA04gLsfCZ/cv BjmRy5RozeSJ1uxAhoCYHCT2hQBZ0cH0n8roXFXI2Y+6708pO1IBkTPT 9MpAGfezTtGYOortbSn+vqT/Zu8jOpNwkleXON4rlZRBZPd4JUMGL9Y5 N/j6+ClYeM+eFQTKXrLi1oC+0yK1sG5OlqrBDhAhBnz+IhfZz4TOkqJ9 Li2BVMatHBeB9GQHtu0FZuC3J0EQgiZxvq1RgkefFJAiB+5uVRN8U7up 5mLDxSgmT0M=
+. 2592000 IN RRSIG DNSKEY 8 0 3600000 20170409093827 20170310093827 49060 . G7s3QiWNgOsl+LoG6OKjdBHPcFyhmCS17GFnaKjfJNdPQaFL5nM/vrXo eUIIdJXAvjj62TY7wTyFlnx3yjK93RVGKEEySpGC/1gkn5AdjVoQszog IxYjKzubizULSaX7SQ3/Ar+uHLxakdS1qgNdFu6hHCl857LJPtmC8SJt iFUmm5HFyARokMrfA88VrFRKEqojcCWajeZMfRtgBipFJZoYgPUCaFlz 8OupNdNUWCbGhnDWrXCWMzeKVXTQVlJf75PXXgtkuBUmr5RSWu7AYr+c wTJ4E4610goRqYxnZ33efKE/MuhKeY66xelPh0sirPrBMR5JAlyjV3k1 qDzhcQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+k.root-servers.net. IN AAAA
+SECTION ANSWER
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+k.root-servers.net. 2592000 IN RRSIG AAAA 8 3 3600000 20170409093827 20170310093827 20661 . qjVXwuxzmoRhdrXyQvKfrrzFxGiYuTTJHxwZPasJ1nVmN48dPyU6wA55 JeqoJv1Jm+XvIL1q0WtX6Zh6KLt6vVjHuMkhmFuIZYkFi/dmsEwFY8C0 ebyXyztQT5+6FOSVTAKacYc40LfBo8FqEn8RYlCu1mkAd8ANvvLrdLWW W03LVOY7JlCzyrKlAlmPmuV8z+e9PxNkUh6KfTEvAReoAAX7wYZkdefg 2d64c7rNWXvYm6LxBX6qeQ39d5WyKc8v+G01DJuDzs2Tx368QoK86vm/ qo9ERdT7koRt+gBZNYv8V4fh2SjaFsy2TJq/tiYcSia9snGDTFj6LWVM 6sBCYQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+k.root-servers.net. IN A
+SECTION ANSWER
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 2592000 IN RRSIG A 8 3 3600000 20170409093827 20170310093827 20661 . feIXXjskcsyH+ALZu67GVDaPWXjUGTWsTlDwzgJcLBzSuRVY/GVD5Z1Q B4/oUW99rLKB5bNS1MuasZ+nZFV67sBwJk1+SqNB2bAe7G5Tv1sR2Qgi qDAoB37YDVk5JGHfuxByLYbAVG9PrPXT60BN17OYrD/TFPzprye65gk3 7l9kPpAlblcsqdvh5piKrWc7VBcyMhlp56qdASNAl+Lrb+i0DZYyJXh+ b8LV5g5zp9FaVGKe0Gi4+yDXVjcM6VEtuNRAu2+flLoc3ho6qQF1Po4Y wueL72I+yFoUxkIOJvK47eWb+YUBIBK/L8/ORjYoLBRsrbc79wb0I3Zj Xy6O4Q==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype
+ADJUST copy_id copy_query
+REPLY QR AA REFUSED
+SECTION QUESTION
+. IN RRSIG
+SECTION ANSWER
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+. IN NS
+ENTRY_END
+
+
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA DO SERVFAIL
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/val_minimal_noerror.rpl b/tests/integration/deckard/sets/resolver/val_minimal_noerror.rpl
new file mode 100644
index 0000000..193d3ca
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_minimal_noerror.rpl
@@ -0,0 +1,89 @@
+ trust-anchor: ". IN DS 49060 8 2 E7B1EB56D7D5791B3D45630FEAA9C823DB84B385ACEEAC5F44DD08885C36700F"
+ val-override-date: "20170401000000"
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+ query-minimization: off
+CONFIG_END
+
+SCENARIO_BEGIN Right signed zone.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ ADDRESS 2001:7fd::1
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. 518400 IN NS k.root-servers.net.
+. 518400 IN RRSIG NS 8 0 518400 20170409093827 20170310093827 20661 . uBuJpbRh1NYVciSKK0r3SA6NFnqE4s/+CqLfTXu26/HrY5c1aOhQHXZM cCDDjfPGFa7Eh4mqF0i9I+i+bFbYQitI1Heexye599VE19REbVsK4qaU xkArvt9k6HVqd/7BXXUyzLN1N0CScdyuT5tiEI9154SDNVpnC+z8i2u0 9hW8JEk4qqVWX/I1MYQB/UOcFSeDhD1Qku/26opqDuLl/1eaShxhMQ/c rjzOb5ZYzD0x+TUJZMYSOMwAraaFuYTT84oe6QYY+EGctAk1b50nA/5E C3Tm/xGuo9ioVtYhTwoo1XDUVeHmghdILjQZvR4pOSZoRGGP9ovb08Qg OmPXuQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+. IN DNSKEY
+SECTION ANSWER
+. IN DNSKEY 256 3 8 AwEAAe1oA46eOLNris1CtS0qM5TdMESK6i4hpalqa6JDv57eOUkaOeje ZW1tIFUokmaK7kuKEFEosddA89CYM8rt2RbC+sfKalbHAWOus0tXZyAL efb2sW95QRzyG6LNul0jQFn9eYWBUHrVe5Wqd0zrFCbTQLUhELSfrlkI UBpO/xKaGinRHX2JjyOnle4aPZY3bEVa/+KyY2ZU6UC4SBo3aHXanP26 ok91rOTmpTWp64ybsMdCXOU8deyuQFQf6q8DhIDmJrkymhX1MXWQQlE0 fAYIYf8/t9OCwucg8oEg4FPU8Gb4Zm/l6PgO4HFkFjBT6iGFCQt3qXe2 Qe3alUWoATc=
+. IN DNSKEY 257 3 8 AwEAAb8sZgVVa02muJ+/+SVhJAvz2EWKGEGquhPbQXuF6ALBYoF4KWTO bZVF8sIVTGoaX5+UWkwwHthg7RwS1DALT/AJymYeHhUwA04gLsfCZ/cv BjmRy5RozeSJ1uxAhoCYHCT2hQBZ0cH0n8roXFXI2Y+6708pO1IBkTPT 9MpAGfezTtGYOortbSn+vqT/Zu8jOpNwkleXON4rlZRBZPd4JUMGL9Y5 N/j6+ClYeM+eFQTKXrLi1oC+0yK1sG5OlqrBDhAhBnz+IhfZz4TOkqJ9 Li2BVMatHBeB9GQHtu0FZuC3J0EQgiZxvq1RgkefFJAiB+5uVRN8U7up 5mLDxSgmT0M=
+. 2592000 IN RRSIG DNSKEY 8 0 3600000 20170409093827 20170310093827 49060 . G7s3QiWNgOsl+LoG6OKjdBHPcFyhmCS17GFnaKjfJNdPQaFL5nM/vrXo eUIIdJXAvjj62TY7wTyFlnx3yjK93RVGKEEySpGC/1gkn5AdjVoQszog IxYjKzubizULSaX7SQ3/Ar+uHLxakdS1qgNdFu6hHCl857LJPtmC8SJt iFUmm5HFyARokMrfA88VrFRKEqojcCWajeZMfRtgBipFJZoYgPUCaFlz 8OupNdNUWCbGhnDWrXCWMzeKVXTQVlJf75PXXgtkuBUmr5RSWu7AYr+c wTJ4E4610goRqYxnZ33efKE/MuhKeY66xelPh0sirPrBMR5JAlyjV3k1 qDzhcQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+k.root-servers.net. IN AAAA
+SECTION ANSWER
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+k.root-servers.net. 2592000 IN RRSIG AAAA 8 3 3600000 20170409093827 20170310093827 20661 . qjVXwuxzmoRhdrXyQvKfrrzFxGiYuTTJHxwZPasJ1nVmN48dPyU6wA55 JeqoJv1Jm+XvIL1q0WtX6Zh6KLt6vVjHuMkhmFuIZYkFi/dmsEwFY8C0 ebyXyztQT5+6FOSVTAKacYc40LfBo8FqEn8RYlCu1mkAd8ANvvLrdLWW W03LVOY7JlCzyrKlAlmPmuV8z+e9PxNkUh6KfTEvAReoAAX7wYZkdefg 2d64c7rNWXvYm6LxBX6qeQ39d5WyKc8v+G01DJuDzs2Tx368QoK86vm/ qo9ERdT7koRt+gBZNYv8V4fh2SjaFsy2TJq/tiYcSia9snGDTFj6LWVM 6sBCYQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+k.root-servers.net. IN A
+SECTION ANSWER
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 2592000 IN RRSIG A 8 3 3600000 20170409093827 20170310093827 20661 . feIXXjskcsyH+ALZu67GVDaPWXjUGTWsTlDwzgJcLBzSuRVY/GVD5Z1Q B4/oUW99rLKB5bNS1MuasZ+nZFV67sBwJk1+SqNB2bAe7G5Tv1sR2Qgi qDAoB37YDVk5JGHfuxByLYbAVG9PrPXT60BN17OYrD/TFPzprye65gk3 7l9kPpAlblcsqdvh5piKrWc7VBcyMhlp56qdASNAl+Lrb+i0DZYyJXh+ b8LV5g5zp9FaVGKe0Gi4+yDXVjcM6VEtuNRAu2+flLoc3ho6qQF1Po4Y wueL72I+yFoUxkIOJvK47eWb+YUBIBK/L8/ORjYoLBRsrbc79wb0I3Zj Xy6O4Q==
+ENTRY_END
+
+; QTYPE == RRSIG is not supported, https://tools.ietf.org/html/draft-ietf-dnsop-refuse-any-04#section-7
+ENTRY_BEGIN
+MATCH opcode qtype
+ADJUST copy_id copy_query
+REPLY QR AA REFUSED
+SECTION QUESTION
+. IN RRSIG
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+. IN NS
+ENTRY_END
+
+
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH opcode qname flags rcode question answer
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. 518400 IN NS k.root-servers.net.
+. 518400 IN RRSIG NS 8 0 518400 20170409093827 20170310093827 20661 . uBuJpbRh1NYVciSKK0r3SA6NFnqE4s/+CqLfTXu26/HrY5c1aOhQHXZM cCDDjfPGFa7Eh4mqF0i9I+i+bFbYQitI1Heexye599VE19REbVsK4qaU xkArvt9k6HVqd/7BXXUyzLN1N0CScdyuT5tiEI9154SDNVpnC+z8i2u0 9hW8JEk4qqVWX/I1MYQB/UOcFSeDhD1Qku/26opqDuLl/1eaShxhMQ/c rjzOb5ZYzD0x+TUJZMYSOMwAraaFuYTT84oe6QYY+EGctAk1b50nA/5E C3Tm/xGuo9ioVtYhTwoo1XDUVeHmghdILjQZvR4pOSZoRGGP9ovb08Qg OmPXuQ==
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/val_negcache_ds.rpl b/tests/integration/deckard/sets/resolver/val_negcache_ds.rpl
new file mode 100644
index 0000000..56d963a
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_negcache_ds.rpl
@@ -0,0 +1,217 @@
+do-ip6: no
+
+; config options
+; The island of trust is at example.com
+;server:
+ trust-anchor: "example.com. 3600 IN DS 41069 7 1 2003A31BABD184BB6DB61EE19E99D1E5D2438043 "
+val-override-date: "20181130121852"
+; target-fetch-policy: "0 0 0 0 0"
+; fake-sha1: yes
+
+;stub-zone:
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+query-minimization: off
+CONFIG_END
+
+SCENARIO_BEGIN Test validator with negative cache DS response
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.sub.example.com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.sub.example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20181230101851 20181130101851 41069 example.com. nJ/h5Gx/vjvbFWq49FnmgYc4SdelzNqF67pN5NbGXkH80uKPdGAj5Lue 9WQb/mCExxU7LjjIZjjAnAmIKKHyK8xLY27W7eRVR9YkmQVt0XWNN1eL 1QUjURFxIFhzpadH9ympDvgS1B8siYu+vdLR1Guxip4+JgYfYFBInZG/ cPA= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101851 20181130101851 41069 example.com. azi1io9bz4KCJ+6AF17yTFwjaGM6mnU9bdR91pD6lrYxMjBPERzBsUIo 5KlAxZD0PBH5/FQviucA33GVAuP3iYc9954yVF7GyjzUy4ZYgQAGb6W8 ddF8aHdi4qV4FJczROo+RDUqmsDV+KAvdGssLN2rN6zL+3yOEbwfKpjc NEk= ;{id = 2854}
+ENTRY_END
+
+; response to DNSKEY priming query
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN DNSKEY
+SECTION ANSWER
+example.com. 3600 IN DNSKEY 256 3 7 AwEAAdbidAf3mIouRWd2XVH6Z5t+ZGClkU6bv0oAZO8Hmv5PlG8Wve8v q40Pa4F5dtODadwB3ap9Z5ELJGDJDAGCgpiOXy34xtquF0VKCBezCdyA X3fWni7EQIqV79G1T3J4cM6WXvbz6T0lJa42Um/YkjTixBnYbj/4Tsgf Szx/k/XL ;{id = 2854 (zsk), size = 1688b}
+example.com. 3600 IN RRSIG DNSKEY 7 2 3600 20181230101851 20181130101851 41069 example.com. jI52HJoPTs1of36Q+d9zpdu9B0iaKd+IQtIkmW6VIliOwX0+6O47sHcf mhz8Htny/B16C2nsBnB3yoOM/j27MRLW1RNmb/TqF2QVIsn+5DnP+UMp 7sZ/3BG0Gdjg8QzY7bFGmsalAVk/BjWmVEXTeAlJRaGUsa2gWQk/6lTG nT4= ;{id = 2854}
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20181230101851 20181130101851 41069 example.com. nJ/h5Gx/vjvbFWq49FnmgYc4SdelzNqF67pN5NbGXkH80uKPdGAj5Lue 9WQb/mCExxU7LjjIZjjAnAmIKKHyK8xLY27W7eRVR9YkmQVt0XWNN1eL 1QUjURFxIFhzpadH9ympDvgS1B8siYu+vdLR1Guxip4+JgYfYFBInZG/ cPA= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101851 20181130101851 41069 example.com. azi1io9bz4KCJ+6AF17yTFwjaGM6mnU9bdR91pD6lrYxMjBPERzBsUIo 5KlAxZD0PBH5/FQviucA33GVAuP3iYc9954yVF7GyjzUy4ZYgQAGb6W8 ddF8aHdi4qV4FJczROo+RDUqmsDV+KAvdGssLN2rN6zL+3yOEbwfKpjc NEk= ;{id = 2854}
+ENTRY_END
+
+; response for delegation to sub.example.com.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.sub.example.com. IN A
+SECTION ANSWER
+SECTION AUTHORITY
+sub.example.com. IN NS ns.sub.example.com.
+sub.example.com. IN NSEC www.example.com. NS RRSIG NSEC
+sub.example.com. 3600 IN RRSIG NSEC 7 3 7200 20181230101851 20181130101851 41069 example.com. zirafH0rQfSxurfz8wUi/N6vgt5BR6ll2oAb+mFE6PgAU+9R1WharUpV JsfI2StXTg6uD/TMYDU02OxQFu44OaZMb6GUZBr7AUAE0fVsUDJAdOgn QdnNajsOZXi5rq6uEcnMdmyUVmNvtcc+yfG26aC/CiJ1dpXoglxM89TO FOw= ;{id = 2854}
+SECTION ADDITIONAL
+ns.sub.example.com. IN A 1.2.3.6
+ENTRY_END
+
+; query for missing DS record.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+sub.example.com. IN DS
+SECTION ANSWER
+SECTION AUTHORITY
+example.com. IN SOA ns.example.com. h.example.com. 2007090504 1800 1800 2419200 7200
+example.com. 3600 IN RRSIG SOA 7 2 3600 20181230101851 20181130101851 41069 example.com. sq8e1vA5GgxT0z5+ubqTW8IjWJEvwJ0vlHXALLeSYHng7oVQ6mr+soTr vxov5kAockUaJ/rFJpBkcx0q2o5Z6RSsWl6OPxdURRe2IAQlyyX7xpcV 5RVHPoCL5PvA8HMFL94TigKTRoDIOkWnbVDJ0Ju3GwurpbrXP6E6KjzG Xus= ;{id = 2854}
+sub.example.com. IN NSEC www.example.com. NS RRSIG NSEC
+sub.example.com. 3600 IN RRSIG NSEC 7 3 7200 20181230101851 20181130101851 41069 example.com. zirafH0rQfSxurfz8wUi/N6vgt5BR6ll2oAb+mFE6PgAU+9R1WharUpV JsfI2StXTg6uD/TMYDU02OxQFu44OaZMb6GUZBr7AUAE0fVsUDJAdOgn QdnNajsOZXi5rq6uEcnMdmyUVmNvtcc+yfG26aC/CiJ1dpXoglxM89TO FOw= ;{id = 2854}
+SECTION ADDITIONAL
+ns.sub.example.com. IN A 1.2.3.6
+ENTRY_END
+
+
+RANGE_END
+
+; ns.sub.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.6
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+sub.example.com. IN NS
+SECTION ANSWER
+sub.example.com. IN NS ns.sub.example.com.
+SECTION ADDITIONAL
+ns.sub.example.com. IN A 1.2.3.6
+ENTRY_END
+
+; response to query of interest
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.sub.example.com. IN A
+SECTION ANSWER
+www.sub.example.com. IN A 11.11.11.11
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.sub.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA DO NOERROR
+SECTION QUESTION
+www.sub.example.com. IN A
+SECTION ANSWER
+www.sub.example.com. 3600 IN A 11.11.11.11
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+; the downstream validator wants the DS record.
+STEP 20 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+sub.example.com. IN DS
+ENTRY_END
+
+STEP 30 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+sub.example.com. IN DS
+SECTION ANSWER
+SECTION AUTHORITY
+example.com. IN SOA ns.example.com. h.example.com. 2007090504 1800 1800 2419200 7200
+example.com. 3600 IN RRSIG SOA 7 2 3600 20181230101851 20181130101851 41069 example.com. sq8e1vA5GgxT0z5+ubqTW8IjWJEvwJ0vlHXALLeSYHng7oVQ6mr+soTr vxov5kAockUaJ/rFJpBkcx0q2o5Z6RSsWl6OPxdURRe2IAQlyyX7xpcV 5RVHPoCL5PvA8HMFL94TigKTRoDIOkWnbVDJ0Ju3GwurpbrXP6E6KjzG Xus= ;{id = 2854}
+sub.example.com. IN NSEC www.example.com. NS RRSIG NSEC
+sub.example.com. 3600 IN RRSIG NSEC 7 3 7200 20181230101851 20181130101851 41069 example.com. zirafH0rQfSxurfz8wUi/N6vgt5BR6ll2oAb+mFE6PgAU+9R1WharUpV JsfI2StXTg6uD/TMYDU02OxQFu44OaZMb6GUZBr7AUAE0fVsUDJAdOgn QdnNajsOZXi5rq6uEcnMdmyUVmNvtcc+yfG26aC/CiJ1dpXoglxM89TO FOw= ;{id = 2854}
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/val_noadwhennodo.rpl b/tests/integration/deckard/sets/resolver/val_noadwhennodo.rpl
new file mode 100644
index 0000000..50d3650
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_noadwhennodo.rpl
@@ -0,0 +1,149 @@
+do-ip6: no
+
+; config options
+; The island of trust is at example.com
+;server:
+ trust-anchor: "example.com. 3600 IN DS 5513 7 1 A82FBB092D154DB2AC65B85480D5D7722589FE65 "
+val-override-date: "20181130100653"
+; target-fetch-policy: "0 0 0 0 0"
+; fake-sha1: yes
+ query-minimization: off
+
+;stub-zone:
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test if AD bit is returned on non-DO query.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20181230080653 20181130080653 5513 example.com. E31KJFA+CenP19oImp7zKXfMcxyoOmUyPTrE81u3qDB0wu8FgNft/Qs6 FQTG5gWDpg8i2E9BB7CbVKx/Dt5RNa7yehtc4MOEhKOMvvH48p0TdkgO sWrUr+Z5wkzst2Hrb4TN6IEM5QqXXs3GApbFsG0vXGMs1aH9+Yo6KZ7H bMA= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230080653 20181130080653 5513 example.com. m42szfJDR/duAI+0VQm2okWxeaVRzSsnWztVF1lHuiZZfljYKFzZEdEp DDSpXbjtq7cobcO/9+ZQhLPrmLhhx2sj96wE06Gd3smqzykaH7PJ5Q63 vkLubkRkJ1X8j+tdykGELk2RUxfzoB5qdf34PY6aIdhX/VVTx8n051cu T+U= ;{id = 2854}
+ENTRY_END
+
+; response to DNSKEY priming query
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN DNSKEY
+SECTION ANSWER
+example.com. 3600 IN DNSKEY 256 3 7 AwEAAcZSP3HQqzpGyFkoyriJHSRJlS8JDx3TsrnFRhbsM/Wy/gp9ubgz BPum/s/4Plb+wGz1ndpcpuhwqNahL2VGleJgEQrkeIqjj1K4lYvPSmr4 yfTcfD5O/zpzqCxrCIjWEa6/Vg7ldNA05KoV0ptx5rVXhox/Fo3BEGaq i5fVjbDf ;{id = 2854 (zsk), size = 1688b}
+example.com. 3600 IN RRSIG DNSKEY 7 2 3600 20181230080653 20181130080653 5513 example.com. fKyryysxkfOMonchYec/4g2y3qtsf6O6ilnBVcBX4f0WAvNtib/eZrTm retDviutAXM2E44rvTpitvBXMOXQ2jz4EV7/m6ZuIkdoOJ3GLk0W08wn 3TPR36VK5160sOxOH9KgWjvrfi4F24qxV30cNqOJYSXUG0nHosuKoEYx Hsg= ;{id = 2854}
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20181230080653 20181130080653 5513 example.com. E31KJFA+CenP19oImp7zKXfMcxyoOmUyPTrE81u3qDB0wu8FgNft/Qs6 FQTG5gWDpg8i2E9BB7CbVKx/Dt5RNa7yehtc4MOEhKOMvvH48p0TdkgO sWrUr+Z5wkzst2Hrb4TN6IEM5QqXXs3GApbFsG0vXGMs1aH9+Yo6KZ7H bMA= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230080653 20181130080653 5513 example.com. m42szfJDR/duAI+0VQm2okWxeaVRzSsnWztVF1lHuiZZfljYKFzZEdEp DDSpXbjtq7cobcO/9+ZQhLPrmLhhx2sj96wE06Gd3smqzykaH7PJ5Q63 vkLubkRkJ1X8j+tdykGELk2RUxfzoB5qdf34PY6aIdhX/VVTx8n051cu T+U= ;{id = 2854}
+ENTRY_END
+
+; response to query of interest
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+www.example.com. 3600 IN RRSIG A 7 3 3600 20181230080653 20181130080653 5513 example.com. S4vtvQL7JD5LDzhFuXU7xlUbr7COF3JxT5XA1kzHJRLPKQEnvTl7+Z2K bgDYOf4TC2Li+W9ptnmodVaidLvNBwiA9d/MPVJ4QQmJK6TlaLuyL0du 079NyGnSiSz5CZvVZ61Vjrt7XgpSyLiJHdq3gR0YAZ6i7ouPu8px7vgW iJQ= ;{id = 2854}
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20181230080653 20181130080653 5513 example.com. E31KJFA+CenP19oImp7zKXfMcxyoOmUyPTrE81u3qDB0wu8FgNft/Qs6 FQTG5gWDpg8i2E9BB7CbVKx/Dt5RNa7yehtc4MOEhKOMvvH48p0TdkgO sWrUr+Z5wkzst2Hrb4TN6IEM5QqXXs3GApbFsG0vXGMs1aH9+Yo6KZ7H bMA= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230080653 20181130080653 5513 example.com. m42szfJDR/duAI+0VQm2okWxeaVRzSsnWztVF1lHuiZZfljYKFzZEdEp DDSpXbjtq7cobcO/9+ZQhLPrmLhhx2sj96wE06Gd3smqzykaH7PJ5Q63 vkLubkRkJ1X8j+tdykGELk2RUxfzoB5qdf34PY6aIdhX/VVTx8n051cu T+U= ;{id = 2854}
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+; it is validated, but no AD bit, because no AD was requested.
+; (this is a copy of val_positive.rpl).
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH opcode rcode flags question answer
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/val_nodata_hasdata.rpl b/tests/integration/deckard/sets/resolver/val_nodata_hasdata.rpl
new file mode 100644
index 0000000..60e05e9
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_nodata_hasdata.rpl
@@ -0,0 +1,165 @@
+do-ip6: no
+
+; config options
+; The island of trust is at example.com
+;server:
+ trust-anchor: "example.com. 3600 IN DS 56837 7 1 FBEED5DCAEAE367243C36AEB8251D00C0088872A "
+val-override-date: "20181130121856"
+; target-fetch-policy: "0 0 0 0 0"
+; fake-sha1: yes
+
+;stub-zone:
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+query-minimization: off
+CONFIG_END
+
+SCENARIO_BEGIN Test validator with nodata response, that proves the data.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA REFUSED
+SECTION QUESTION
+ns.example.com. IN A
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA REFUSED
+SECTION QUESTION
+ns.example.com. IN AAAA
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20181230101855 20181130101855 56837 example.com. y/lP3Ognxh+WgcwtSqo0bLUWeko1sjpCXylRLERxsTSyVSK5L8yenuB2 94iqM8fVlk7SpDg1BiuNuAPsinDMgjR8726ECJMMgSxXohiZgQSUfwQi NYxDmTq9qN/JfCrJUsdYpH387vSkjGuvvNic9k70FzDhPfI4YAjf4ZbJ E0c= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101855 20181130101855 56837 example.com. AtisROBfgsg6OEetN69p9eEAQSKwovhdbOv3lZ8dq4cHryLDO4q4O2aF +h3cSpLpOO6wti94eqTbpB6HZ7eIEYqHEQKSYEGL59HuVf4N0nyTp8lN 3UAZT7DtsmDdt0NyUExh1tuHvFwYvtX3vCyvJs3F1MGCTySSK6wALmHm TLs= ;{id = 2854}
+ENTRY_END
+
+; response to DNSKEY priming query
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN DNSKEY
+SECTION ANSWER
+example.com. 3600 IN DNSKEY 256 3 7 AwEAAdIzTUQVujDsSlkC61+pWGNqk3O6YIoP6XbaGwwKTUHx7yXf95gb 93UNAJFLt/G6ORySmAYfW/l3EYvKMX4x2YnaQeq+xXUguPq4nMMxfwyd xYubOaRd5DgETj1BEug2OV/z5PbaSuWiCqxQCJ4x9wuA04388n6r+/WR dz9uPVyl ;{id = 2854 (zsk), size = 1688b}
+example.com. 3600 IN RRSIG DNSKEY 7 2 3600 20181230101855 20181130101855 56837 example.com. SsiDl8A1jtsqhA0v/wL5Hes0qRR8//xhIMPrQuBHJVSTRg5dq4EJYjIF 3rtJ+YwlLW/bfDg19sXLj/67/resY106RtI7zFdoQFoWXCkui9o+ZPJF UM+FHgjnFt4OOwNpQpJuhXeUGj6NDIgpsJhYDH8BaESNGcb0eN7bfYaH d/E= ;{id = 2854}
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20181230101855 20181130101855 56837 example.com. y/lP3Ognxh+WgcwtSqo0bLUWeko1sjpCXylRLERxsTSyVSK5L8yenuB2 94iqM8fVlk7SpDg1BiuNuAPsinDMgjR8726ECJMMgSxXohiZgQSUfwQi NYxDmTq9qN/JfCrJUsdYpH387vSkjGuvvNic9k70FzDhPfI4YAjf4ZbJ E0c= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101855 20181130101855 56837 example.com. AtisROBfgsg6OEetN69p9eEAQSKwovhdbOv3lZ8dq4cHryLDO4q4O2aF +h3cSpLpOO6wti94eqTbpB6HZ7eIEYqHEQKSYEGL59HuVf4N0nyTp8lN 3UAZT7DtsmDdt0NyUExh1tuHvFwYvtX3vCyvJs3F1MGCTySSK6wALmHm TLs= ;{id = 2854}
+ENTRY_END
+
+; response to query of interest
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+SECTION AUTHORITY
+; SOA record is missing in reply.
+; Denies A, note this is the end of the NSEC chain.
+www.example.com. IN NSEC example.com. A RRSIG NSEC
+www.example.com. 3600 IN RRSIG NSEC 7 3 3600 20181230101855 20181130101855 56837 example.com. NgtD5aVHLUHE1yGKHrarb7A1P5sqfwdgUjxBCEn8BwX7FW9h9QiVZs9+ jCVF7hT+wPs2PRqy5T/a5OjwZZJRtabxN6b3d6J7FSppTWTxP/8sjAf6 1c1TRf7aq4alJ8gAk/p9Yk8AsylIw15kMWjnOeiFCCKKYRHzfJi7wnAR efI= ;{id = 2854}
+; Denies wildcard
+example.com. IN NSEC ns.example.com. NS SOA RRSIG NSEC DNSKEY
+example.com. 3600 IN RRSIG NSEC 7 2 3600 20181230101855 20181130101855 56837 example.com. nIcNEt/oTPiVa0mopVp5BXGVnCxn3hmv233yJ0oQCRkpZV0PKVCp6p+S GyMuh+osAYNT+duVa3zs8o6pyrZjQLAZJMEeOMBoAQP33iNu4axkYGio IkW/wdabOdBAFGgtApcjUh8rk9FCNAu0Rp+knqhq9BHV89aRROqGzdkd kp0= ;{id = 2854}
+SECTION ADDITIONAL
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA SERVFAIL
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/val_nodata_zonecut.rpl b/tests/integration/deckard/sets/resolver/val_nodata_zonecut.rpl
new file mode 100644
index 0000000..cdd0eac
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_nodata_zonecut.rpl
@@ -0,0 +1,163 @@
+do-ip6: no
+
+; config options
+; The island of trust is at example.com
+;server:
+ trust-anchor: "example.com. 3600 IN DS 7508 7 1 74F83028EFB9ADE1737F8D4ABC38B6B24B820FEA "
+val-override-date: "20181130121859"
+; target-fetch-policy: "0 0 0 0 0"
+; fake-sha1: yes
+
+;stub-zone:
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+query-minimization: off
+CONFIG_END
+
+SCENARIO_BEGIN Test validator with nodata response from wrong side of zonecut
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA REFUSED
+SECTION QUESTION
+ns.example.com. IN A
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA REFUSED
+SECTION QUESTION
+ns.example.com. IN AAAA
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20181230101859 20181130101859 7508 example.com. LtglVhv8M0yIXb/0El6Zuq5YlKzOiI4ELiK9UE7MgTr2taXCWzC1tng6 a5UqZXWwrxd0a8vaVy6ZcAPQkY6HeZ/IAO9ej3L+EzKyLlEJxnYXkNXb InMHUcUk99jZ1edOvaVPtaDqWdm8iuGcm5mHHpTopf7lG9L6SwdPxX6h 9DE= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101859 20181130101859 7508 example.com. yQB0cOEETYV1iE6sDl3zwJX+aqZFyzomqn0Y+KLfMgBmKZmwQWx5tA0w 3KTT3EmuW0X1TAY0gK4NiJ9DAIs0Lx8CYKEtDXa8bIQ/pelMIwZFAI7c Xj2dapGiAJXK5GDakoIeSna26Uoxebuji1ON1DbWbGno7Nl+SrGDvwsX WRY= ;{id = 2854}
+ENTRY_END
+
+; response to DNSKEY priming query
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN DNSKEY
+SECTION ANSWER
+example.com. 3600 IN DNSKEY 256 3 7 AwEAAeKwMBC0t6W4iXUPMRDrAn6oLaKcQQxzs7kU6eSabnPSrKiK1866 PzscrkXkkPIGNW1DXMexV+b39NavDoXzAaG3sCsQToq8ZVA/VKz6BQ5h Qy8CzzJ/fbg7eQmujS1bh0TATkKEtgVYmlfooSWniQ9wAaId/jLbeF6q C6g1nuWt ;{id = 2854 (zsk), size = 1688b}
+example.com. 3600 IN RRSIG DNSKEY 7 2 3600 20181230101859 20181130101859 7508 example.com. yDhUfBwaWgV/QKLUEQ8B7ZeE/81qSJoo0mFD2zs/0PJnQey/Bi2vNZDv 7W3nIkzHtNRC3D9brV1YXi+NbfCID7nNyU90/4Js1VQAbGzxGuv9dlvx GjHfniS8UIdu8R3iqV2URi1Ux/YMFfEv2VfUInOh6hfB9nwhDKetsbAs kwc= ;{id = 2854}
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20181230101859 20181130101859 7508 example.com. LtglVhv8M0yIXb/0El6Zuq5YlKzOiI4ELiK9UE7MgTr2taXCWzC1tng6 a5UqZXWwrxd0a8vaVy6ZcAPQkY6HeZ/IAO9ej3L+EzKyLlEJxnYXkNXb InMHUcUk99jZ1edOvaVPtaDqWdm8iuGcm5mHHpTopf7lG9L6SwdPxX6h 9DE= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101859 20181130101859 7508 example.com. yQB0cOEETYV1iE6sDl3zwJX+aqZFyzomqn0Y+KLfMgBmKZmwQWx5tA0w 3KTT3EmuW0X1TAY0gK4NiJ9DAIs0Lx8CYKEtDXa8bIQ/pelMIwZFAI7c Xj2dapGiAJXK5GDakoIeSna26Uoxebuji1ON1DbWbGno7Nl+SrGDvwsX WRY= ;{id = 2854}
+ENTRY_END
+
+; response to query of interest
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+SECTION AUTHORITY
+; SOA record is missing in reply.
+; Denies A, note this is the end of the NSEC chain.
+; from wrong side of zone-cut
+www.example.com. 3600 IN NSEC example.com. NS DS RRSIG NSEC
+www.example.com. 3600 IN RRSIG NSEC 7 3 3600 20181230101859 20181130101859 7508 example.com. pZVPW2nRsyzqbXJ0ulwP3mS+F6s2IT87uIdfZXAYvKc4mxfVN4fVIV4d 38i2/19vWBf0JbMumZTDunzpL5+8T4ydH6AVv2UYcQh154JHi1q3Ec4G 0VTQa5bl8+fvS3rY5jmn/Pj6nqNWkYdnZPEelzzz0cLHJLdfI279a7n0 T00= ;{id = 2854}
+SECTION ADDITIONAL
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA SERVFAIL
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/val_nodatawc_badce.rpl b/tests/integration/deckard/sets/resolver/val_nodatawc_badce.rpl
new file mode 100644
index 0000000..5e9ed98
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_nodatawc_badce.rpl
@@ -0,0 +1,165 @@
+do-ip6: no
+
+; config options
+; The island of trust is at example.com
+;server:
+ trust-anchor: "example.com. 3600 IN DS 65510 7 1 562BB481B567CC7A69CA48A9020450D3EA52B6BC "
+val-override-date: "20181130121857"
+; target-fetch-policy: "0 0 0 0 0"
+; fake-sha1: yes
+
+;stub-zone:
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+query-minimization: off
+CONFIG_END
+
+SCENARIO_BEGIN Test validator with wildcard nodata, bad closest encloser
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA REFUSED
+SECTION QUESTION
+ns.example.com. IN A
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA REFUSED
+SECTION QUESTION
+ns.example.com. IN AAAA
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20181230101857 20181130101857 65510 example.com. zBeDPiE4zoUW4DnyrOXKvEKUaouz2xpD9UGCkQ2iDeNl+2ASPv9fyxY9 ChpOOcgOsM6PEonEwm013L0oPK19WOAduuZw+9IgPFFxXlo5Sq80vdtM OEKqhvy4dId/aeF+hWcFm1ug9+4f56eBP0MyeohXpm46b0qaK7756B6i pyg= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101857 20181130101857 65510 example.com. sQPchlz34VJeeRFowgrOAWcfNGuSXSzeuH2/wZ/1qFdYF6m8uf8Xl/Vy ThP1axfBvk1pKItnZZR3bQd0gnCInnmNUt70vXg/w1AjrULNiMxqs0Mj fBPhFk3/9oK+KogQfLYS0SPESU+C3raPG8MnDe0uJ6sd5SDDp3w57qan J+Y= ;{id = 2854}
+ENTRY_END
+
+; response to DNSKEY priming query
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN DNSKEY
+SECTION ANSWER
+example.com. 3600 IN DNSKEY 256 3 7 AwEAAdUDKuLOwzbmS7/7hQIK5FyLAu5XnovMNiBRfF8u8+W7RfQ+KutQ FlDcF2GSvLzi/oN70crUU45XslCGF5hHiTPu3x9tMpO75tvzZxvo8Zvm 6cTUqa+/94vco9THeTxy6LtY93Ay5h1Y6sqfUtTBUbU1b/O18EgM1XBu Z61vzdFn ;{id = 2854 (zsk), size = 1688b}
+example.com. 3600 IN RRSIG DNSKEY 7 2 3600 20181230101857 20181130101857 65510 example.com. OGov/2XXr24GVeXbdT4WcHDiAV5mKmBFYlNWjwE+FOOI7LdL0DPg1CFD AnyW5Fadn9DCkDh+zLMeKQIVSFG4vkKzjqjIOxCxninPkpSA1S6caW5q i7Xlxtbqc9U3ZZB0A9uCWqYeVL1B+dRvm+rgOEvklA4FoW5QyCpL5U83 vL8= ;{id = 2854}
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20181230101857 20181130101857 65510 example.com. zBeDPiE4zoUW4DnyrOXKvEKUaouz2xpD9UGCkQ2iDeNl+2ASPv9fyxY9 ChpOOcgOsM6PEonEwm013L0oPK19WOAduuZw+9IgPFFxXlo5Sq80vdtM OEKqhvy4dId/aeF+hWcFm1ug9+4f56eBP0MyeohXpm46b0qaK7756B6i pyg= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101857 20181130101857 65510 example.com. sQPchlz34VJeeRFowgrOAWcfNGuSXSzeuH2/wZ/1qFdYF6m8uf8Xl/Vy ThP1axfBvk1pKItnZZR3bQd0gnCInnmNUt70vXg/w1AjrULNiMxqs0Mj fBPhFk3/9oK+KogQfLYS0SPESU+C3raPG8MnDe0uJ6sd5SDDp3w57qan J+Y= ;{id = 2854}
+ENTRY_END
+
+; response to query of interest
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+SECTION AUTHORITY
+; SOA record is missing in reply.
+; wildcard is *.com,
+*.com. IN NSEC com. RRSIG NSEC
+*.com. 3600 IN RRSIG NSEC 7 1 3600 20181230101857 20181130101857 65510 example.com. VkoFvmky3udLkzvZPQ7Kgb8wgWKtyHJlL4j4aWmgxeGM3jgJn+LF21yZ EA4EnrlxbPwAjyNSjpPFEGfn9b/nFnxIELvaw4JEmVAC11fJcS6LOyjP W0TAtZfaugzN1N5IoTEKC5Jd5h3oBLj98jYDnUeCJ1Rs44bku85Xlwwq Vsw= ;{id = 2854}
+; this NSEC denies original query name from a different zone
+ns.example.com. IN NSEC zork.example.com. A RRSIG NSEC
+ns.example.com. 3600 IN RRSIG NSEC 7 3 3600 20181230101857 20181130101857 65510 example.com. IhNXLScxp0p14+47J2kp4g3Q4SziflqJaBn9cjIvjOO4pYlw6ZCd6bKK foP9Ye6IUriidmrAP45C50mqx3uIJsS5S+tuIk/gPFr8qcDbynLWUQj7 U7x3XQdztNTxqwAMse/84UGxPg5aCCAqrySFJ0qTz2mo0dihI5xgEpRi 70Q= ;{id = 2854}
+SECTION ADDITIONAL
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA SERVFAIL
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/val_nokeyprime.rpl b/tests/integration/deckard/sets/resolver/val_nokeyprime.rpl
new file mode 100644
index 0000000..694f776
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_nokeyprime.rpl
@@ -0,0 +1,166 @@
+do-ip6: no
+
+; config options
+; The island of trust is at example.com
+;server:
+ trust-anchor: "example.com. 3600 IN DS 2854 3 1 46e4ffc6e9a4793b488954bd3f0cc6af0dfb201b"
+ val-override-date: "20070916134226"
+; target-fetch-policy: "0 0 0 0 0"
+; fake-sha1: yes
+
+;stub-zone:
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+;test from testbound
+
+SCENARIO_BEGIN Test validator with failed key prime, no keys.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854}
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.com. IN A
+SECTION ANSWER
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854}
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
+ENTRY_END
+
+; barely valid nodata for AAAA
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.com. IN AAAA
+SECTION ANSWER
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
+ENTRY_END
+
+
+; response to DNSKEY priming query
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+example.com. IN DNSKEY
+SECTION ANSWER
+SECTION AUTHORITY
+example.com. IN SOA ns.example.com. hostmaster.example.com. 2007101500 28800 7200 604800 18000
+SECTION ADDITIONAL
+ENTRY_END
+
+; response to query of interest
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA DO SERVFAIL
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/val_nsec3_b1_nameerror.rpl b/tests/integration/deckard/sets/resolver/val_nsec3_b1_nameerror.rpl
new file mode 100644
index 0000000..ade5ecd
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_nsec3_b1_nameerror.rpl
@@ -0,0 +1,163 @@
+do-ip6: no
+
+; config options
+;server:
+ trust-anchor: "example. DNSKEY 257 3 7 AwEAAcUlFV1vhmqx6NSOUOq2R/dsR7Xm3upJ ( j7IommWSpJABVfW8Q0rOvXdM6kzt+TAu92L9 AbsUdblMFin8CVF3n4s= )"
+ val-override-date: "20120420235959"
+; target-fetch-policy: "0 0 0 0 0"
+ query-minimization: off ; RFC 5155 section B.1 does not contain information necessary to cover query-minimization
+
+;stub-zone:
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test validator NSEC3 B.1 name error.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example. IN A
+SECTION AUTHORITY
+example. IN NS ns1.example.
+; leave out to make unbound take ns1
+;example. IN NS ns2.example.
+SECTION ADDITIONAL
+ns1.example. IN A 192.0.2.1
+; leave out to make unbound take ns1
+;ns2.example. IN A 192.0.2.2
+ENTRY_END
+RANGE_END
+
+; ns1.example.
+RANGE_BEGIN 0 100
+ ADDRESS 192.0.2.1
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id copy_query
+REPLY QR REFUSED
+SECTION QUESTION
+example. IN NS
+SECTION ANSWER
+ENTRY_END
+
+; response to DNSKEY priming query
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example. IN DNSKEY
+SECTION ANSWER
+example. DNSKEY 256 3 7 AwEAAaetidLzsKWUt4swWR8yu0wPHPiUi8LU ( sAD0QPWU+wzt89epO6tHzkMBVDkC7qphQO2h TY4hHn9npWFRw5BYubE= )
+example. DNSKEY 257 3 7 AwEAAcUlFV1vhmqx6NSOUOq2R/dsR7Xm3upJ ( j7IommWSpJABVfW8Q0rOvXdM6kzt+TAu92L9 AbsUdblMFin8CVF3n4s= )
+example. RRSIG DNSKEY 7 1 3600 20150420235959 ( 20051021000000 12708 example. AuU4juU9RaxescSmStrQks3Gh9FblGBlVU31 uzMZ/U/FpsUb8aC6QZS+sTsJXnLnz7flGOsm MGQZf3bH+QsCtg== )
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA DO NXDOMAIN
+SECTION QUESTION
+a.c.x.w.example. IN A
+SECTION AUTHORITY
+example. SOA ns1.example. bugs.x.w.example. 1 3600 300 ( 3600000 3600 )
+example. RRSIG SOA 7 1 3600 20150420235959 20051021000000 ( 40430 example. Hu25UIyNPmvPIVBrldN+9Mlp9Zql39qaUd8i q4ZLlYWfUUbbAS41pG+68z81q1xhkYAcEyHd VI2LmKusbZsT0Q== )
+
+;; NSEC3 RR that covers the "next closer" name (c.x.w.example)
+;; H(c.x.w.example) = 0va5bpr2ou0vk0lbqeeljri88laipsfh
+
+0p9mhaveqvm6t7vbl5lop2u3t2rp3tom.example. NSEC3 1 1 12 aabbccdd ( 2t7b4g4vsa5smi47k61mv5bv1a22bojr MX DNSKEY NS SOA NSEC3PARAM RRSIG )
+0p9mhaveqvm6t7vbl5lop2u3t2rp3tom.example. RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 ( 40430 example. OSgWSm26B+cS+dDL8b5QrWr/dEWhtCsKlwKL IBHYH6blRxK9rC0bMJPwQ4mLIuw85H2EY762 BOCXJZMnpuwhpA== )
+
+;; NSEC3 RR that matches the closest encloser (x.w.example)
+;; H(x.w.example) = b4um86eghhds6nea196smvmlo4ors995
+
+b4um86eghhds6nea196smvmlo4ors995.example. NSEC3 1 1 12 aabbccdd ( gjeqe526plbf1g8mklp59enfd789njgi MX RRSIG )
+b4um86eghhds6nea196smvmlo4ors995.example. RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 ( 40430 example. ZkPG3M32lmoHM6pa3D6gZFGB/rhL//Bs3Omh 5u4m/CUiwtblEVOaAKKZd7S959OeiX43aLX3 pOv0TSTyiTxIZg== )
+
+;; NSEC3 RR that covers wildcard at the closest encloser (*.x.w.example)
+;; H(*.x.w.example) = 92pqneegtaue7pjatc3l3qnk738c6v5m
+
+35mthgpgcu1qg68fab165klnsnk3dpvl.example. NSEC3 1 1 12 aabbccdd ( b4um86eghhds6nea196smvmlo4ors995 NS DS RRSIG )
+35mthgpgcu1qg68fab165klnsnk3dpvl.example. RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 ( 40430 example. g6jPUUpduAJKRljUsN8gB4UagAX0NxY9shwQ Aynzo8EUWH+z6hEIBlUTPGj15eZll6VhQqgZ XtAIR3chwgW+SA== )
+SECTION ADDITIONAL
+ENTRY_END
+
+RANGE_END
+
+STEP 10 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+a.c.x.w.example. IN A
+ENTRY_END
+
+; recursion happens here.
+; no AD flag due to optout, RFC5155 9.2
+STEP 20 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA DO NXDOMAIN
+SECTION QUESTION
+a.c.x.w.example. IN A
+SECTION ANSWER
+SECTION AUTHORITY
+example. SOA ns1.example. bugs.x.w.example. 1 3600 300 ( 3600000 3600 )
+example. RRSIG SOA 7 1 3600 20150420235959 20051021000000 ( 40430 example. Hu25UIyNPmvPIVBrldN+9Mlp9Zql39qaUd8i q4ZLlYWfUUbbAS41pG+68z81q1xhkYAcEyHd VI2LmKusbZsT0Q== )
+0p9mhaveqvm6t7vbl5lop2u3t2rp3tom.example. NSEC3 1 1 12 aabbccdd ( 2t7b4g4vsa5smi47k61mv5bv1a22bojr MX DNSKEY NS SOA NSEC3PARAM RRSIG )
+0p9mhaveqvm6t7vbl5lop2u3t2rp3tom.example. RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 ( 40430 example. OSgWSm26B+cS+dDL8b5QrWr/dEWhtCsKlwKL IBHYH6blRxK9rC0bMJPwQ4mLIuw85H2EY762 BOCXJZMnpuwhpA== )
+b4um86eghhds6nea196smvmlo4ors995.example. NSEC3 1 1 12 aabbccdd ( gjeqe526plbf1g8mklp59enfd789njgi MX RRSIG )
+b4um86eghhds6nea196smvmlo4ors995.example. RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 ( 40430 example. ZkPG3M32lmoHM6pa3D6gZFGB/rhL//Bs3Omh 5u4m/CUiwtblEVOaAKKZd7S959OeiX43aLX3 pOv0TSTyiTxIZg== )
+35mthgpgcu1qg68fab165klnsnk3dpvl.example. NSEC3 1 1 12 aabbccdd ( b4um86eghhds6nea196smvmlo4ors995 NS DS RRSIG )
+35mthgpgcu1qg68fab165klnsnk3dpvl.example. RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 ( 40430 example. g6jPUUpduAJKRljUsN8gB4UagAX0NxY9shwQ Aynzo8EUWH+z6hEIBlUTPGj15eZll6VhQqgZ XtAIR3chwgW+SA== )
+SECTION ADDITIONAL
+ENTRY_END
+
+STEP 30 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+a.c.x.w.example. IN A
+ENTRY_END
+
+;cached answer
+STEP 40 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA DO NXDOMAIN
+SECTION QUESTION
+a.c.x.w.example. IN A
+SECTION ANSWER
+SECTION AUTHORITY
+example. SOA ns1.example. bugs.x.w.example. 1 3600 300 ( 3600000 3600 )
+example. RRSIG SOA 7 1 3600 20150420235959 20051021000000 ( 40430 example. Hu25UIyNPmvPIVBrldN+9Mlp9Zql39qaUd8i q4ZLlYWfUUbbAS41pG+68z81q1xhkYAcEyHd VI2LmKusbZsT0Q== )
+0p9mhaveqvm6t7vbl5lop2u3t2rp3tom.example. NSEC3 1 1 12 aabbccdd ( 2t7b4g4vsa5smi47k61mv5bv1a22bojr MX DNSKEY NS SOA NSEC3PARAM RRSIG )
+0p9mhaveqvm6t7vbl5lop2u3t2rp3tom.example. RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 ( 40430 example. OSgWSm26B+cS+dDL8b5QrWr/dEWhtCsKlwKL IBHYH6blRxK9rC0bMJPwQ4mLIuw85H2EY762 BOCXJZMnpuwhpA== )
+b4um86eghhds6nea196smvmlo4ors995.example. NSEC3 1 1 12 aabbccdd ( gjeqe526plbf1g8mklp59enfd789njgi MX RRSIG )
+b4um86eghhds6nea196smvmlo4ors995.example. RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 ( 40430 example. ZkPG3M32lmoHM6pa3D6gZFGB/rhL//Bs3Omh 5u4m/CUiwtblEVOaAKKZd7S959OeiX43aLX3 pOv0TSTyiTxIZg== )
+35mthgpgcu1qg68fab165klnsnk3dpvl.example. NSEC3 1 1 12 aabbccdd ( b4um86eghhds6nea196smvmlo4ors995 NS DS RRSIG )
+35mthgpgcu1qg68fab165klnsnk3dpvl.example. RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 ( 40430 example. g6jPUUpduAJKRljUsN8gB4UagAX0NxY9shwQ Aynzo8EUWH+z6hEIBlUTPGj15eZll6VhQqgZ XtAIR3chwgW+SA== )
+SECTION ADDITIONAL
+ENTRY_END
+
+SCENARIO_END
+
diff --git a/tests/integration/deckard/sets/resolver/val_nsec3_b1_nameerror_noce.rpl b/tests/integration/deckard/sets/resolver/val_nsec3_b1_nameerror_noce.rpl
new file mode 100644
index 0000000..f89e46e
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_nsec3_b1_nameerror_noce.rpl
@@ -0,0 +1,147 @@
+do-ip6: no
+
+; config options
+;server:
+ trust-anchor: "example. DNSKEY 257 3 7 AwEAAcUlFV1vhmqx6NSOUOq2R/dsR7Xm3upJ ( j7IommWSpJABVfW8Q0rOvXdM6kzt+TAu92L9 AbsUdblMFin8CVF3n4s= )"
+ val-override-date: "20120420235959"
+; target-fetch-policy: "0 0 0 0 0"
+ query-minimization: off
+
+;stub-zone:
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test validator NSEC3 B.1 name error without ce NSEC3.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example. IN A
+SECTION AUTHORITY
+example. IN NS ns1.example.
+; leave out to make unbound take ns1
+;example. IN NS ns2.example.
+SECTION ADDITIONAL
+ns1.example. IN A 192.0.2.1
+; leave out to make unbound take ns1
+;ns2.example. IN A 192.0.2.2
+ENTRY_END
+RANGE_END
+
+; ns1.example.
+RANGE_BEGIN 0 100
+ ADDRESS 192.0.2.1
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id copy_query
+REPLY QR REFUSED
+SECTION QUESTION
+ns1.example. IN A
+SECTION ANSWER
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id copy_query
+REPLY QR REFUSED
+SECTION QUESTION
+ns1.example. IN AAAA
+SECTION ANSWER
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id copy_query
+REPLY QR REFUSED
+SECTION QUESTION
+example. IN NS
+SECTION ANSWER
+ENTRY_END
+
+; response to DNSKEY priming query
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example. IN DNSKEY
+SECTION ANSWER
+example. DNSKEY 256 3 7 AwEAAaetidLzsKWUt4swWR8yu0wPHPiUi8LU ( sAD0QPWU+wzt89epO6tHzkMBVDkC7qphQO2h TY4hHn9npWFRw5BYubE= )
+example. DNSKEY 257 3 7 AwEAAcUlFV1vhmqx6NSOUOq2R/dsR7Xm3upJ ( j7IommWSpJABVfW8Q0rOvXdM6kzt+TAu92L9 AbsUdblMFin8CVF3n4s= )
+example. RRSIG DNSKEY 7 1 3600 20150420235959 ( 20051021000000 12708 example. AuU4juU9RaxescSmStrQks3Gh9FblGBlVU31 uzMZ/U/FpsUb8aC6QZS+sTsJXnLnz7flGOsm MGQZf3bH+QsCtg== )
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA DO NXDOMAIN
+SECTION QUESTION
+a.c.x.w.example. IN A
+SECTION AUTHORITY
+example. SOA ns1.example. bugs.x.w.example. 1 3600 300 ( 3600000 3600 )
+example. RRSIG SOA 7 1 3600 20150420235959 20051021000000 ( 40430 example. Hu25UIyNPmvPIVBrldN+9Mlp9Zql39qaUd8i q4ZLlYWfUUbbAS41pG+68z81q1xhkYAcEyHd VI2LmKusbZsT0Q== )
+
+;; NSEC3 RR that covers the "next closer" name (c.x.w.example)
+;; H(c.x.w.example) = 0va5bpr2ou0vk0lbqeeljri88laipsfh
+
+0p9mhaveqvm6t7vbl5lop2u3t2rp3tom.example. NSEC3 1 1 12 aabbccdd ( 2t7b4g4vsa5smi47k61mv5bv1a22bojr MX DNSKEY NS SOA NSEC3PARAM RRSIG )
+0p9mhaveqvm6t7vbl5lop2u3t2rp3tom.example. RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 ( 40430 example. OSgWSm26B+cS+dDL8b5QrWr/dEWhtCsKlwKL IBHYH6blRxK9rC0bMJPwQ4mLIuw85H2EY762 BOCXJZMnpuwhpA== )
+
+;; NSEC3 RR that matches the closest encloser (x.w.example)
+;; H(x.w.example) = b4um86eghhds6nea196smvmlo4ors995
+
+; b4um86eghhds6nea196smvmlo4ors995.example. NSEC3 1 1 12 aabbccdd ( gjeqe526plbf1g8mklp59enfd789njgi MX RRSIG )
+; b4um86eghhds6nea196smvmlo4ors995.example. RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 ( 40430 example. ZkPG3M32lmoHM6pa3D6gZFGB/rhL//Bs3Omh 5u4m/CUiwtblEVOaAKKZd7S959OeiX43aLX3 pOv0TSTyiTxIZg== )
+
+;; NSEC3 RR that covers wildcard at the closest encloser (*.x.w.example)
+;; H(*.x.w.example) = 92pqneegtaue7pjatc3l3qnk738c6v5m
+
+35mthgpgcu1qg68fab165klnsnk3dpvl.example. NSEC3 1 1 12 aabbccdd ( b4um86eghhds6nea196smvmlo4ors995 NS DS RRSIG )
+35mthgpgcu1qg68fab165klnsnk3dpvl.example. RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 ( 40430 example. g6jPUUpduAJKRljUsN8gB4UagAX0NxY9shwQ Aynzo8EUWH+z6hEIBlUTPGj15eZll6VhQqgZ XtAIR3chwgW+SA== )
+SECTION ADDITIONAL
+ENTRY_END
+
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+a.c.x.w.example. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+;MATCH all
+;do not compare authority
+MATCH opcode qname flags rcode question answer additional
+REPLY QR RD RA SERVFAIL
+SECTION QUESTION
+a.c.x.w.example. IN A
+SECTION ANSWER
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+SCENARIO_END
+
diff --git a/tests/integration/deckard/sets/resolver/val_nsec3_b1_nameerror_nonc.rpl b/tests/integration/deckard/sets/resolver/val_nsec3_b1_nameerror_nonc.rpl
new file mode 100644
index 0000000..8974a97
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_nsec3_b1_nameerror_nonc.rpl
@@ -0,0 +1,149 @@
+do-ip6: no
+
+; config options
+;server:
+ trust-anchor: "example. DNSKEY 257 3 7 AwEAAcUlFV1vhmqx6NSOUOq2R/dsR7Xm 3upJ ( j7IommWSpJABVfW8Q0rOvXdM6kzt+TAu92L9 AbsUdblMFin8CVF3n4s= )"
+ val-override-date: "20120420235959"
+; target-fetch-policy: "0 0 0 0 0"
+ query-minimization: off
+
+;stub-zone:
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test validator NSEC3 B.1 name error without nc NSEC3.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example. IN A
+SECTION AUTHORITY
+example. IN NS ns1.example.
+; leave out to make unbound take ns1
+;example. IN NS ns2.example.
+SECTION ADDITIONAL
+ns1.example. IN A 192.0.2.1
+; leave out to make unbound take ns1
+;ns2.example. IN A 192.0.2.2
+ENTRY_END
+RANGE_END
+
+; ns1.example.
+RANGE_BEGIN 0 100
+ ADDRESS 192.0.2.1
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id copy_query
+REPLY QR REFUSED
+SECTION QUESTION
+ns1.example. IN A
+SECTION ANSWER
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id copy_query
+REPLY QR REFUSED
+SECTION QUESTION
+ns1.example. IN AAAA
+SECTION ANSWER
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id copy_query
+REPLY QR REFUSED
+SECTION QUESTION
+example. IN NS
+SECTION ANSWER
+ENTRY_END
+
+; response to DNSKEY priming query
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example. IN DNSKEY
+SECTION ANSWER
+example. DNSKEY 256 3 7 AwEAAaetidLzsKWUt4swWR8yu0wPHPiUi8LU ( sAD0QPWU+wzt89ep O6tHzkMBVDkC7qphQO2h TY4hHn9npWFRw5BYubE= )
+example. DNSKEY 257 3 7 AwEAAcUlFV1vhmqx6NSOUOq2R/dsR7Xm3upJ ( j7IommWSpJABVfW8 Q0rOvXdM6kzt+TAu92L9 AbsUdblMFin8CVF3n4s= )
+example. RRSIG DNSKEY 7 1 3600 20150420235959 ( 20051021000000 12708 example. AuU4juU9RaxescSmStrQks3Gh9FblGBlVU31 uzMZ/U/FpsUb8aC6QZS+sTsJXnLnz7flGOsm MGQZf 3bH+QsCtg== )
+
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA DO NXDOMAIN
+SECTION QUESTION
+a.c.x.w.example. IN A
+SECTION AUTHORITY
+example. SOA ns1.example. bugs.x.w.example. 1 3600 300 ( 3600000 3600 )
+example. RRSIG SOA 7 1 3600 20150420235959 20051021000000 ( 40430 example. Hu25UIyNPmvPIVBrldN+9Mlp9Zql39qaUd8i q4ZLlYWfUUbbAS41pG+68z81q1xhkYAcEyHd V I2LmKusbZsT0Q== )
+
+;; NSEC3 RR that covers the "next closer" name (c.x.w.example)
+;; H(c.x.w.example) = 0va5bpr2ou0vk0lbqeeljri88laipsfh
+
+;0p9mhaveqvm6t7vbl5lop2u3t2rp3tom.example. NSEC3 1 1 12 aabbccdd ( 2t7b4g4vsa5smi 47k61mv5bv1a22bojr MX DNSKEY NS SOA NSEC3PARAM RRSIG )
+;0p9mhaveqvm6t7vbl5lop2u3t2rp3tom.example. RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 ( 40430 example. OSgWSm26B+cS+dDL8b5QrWr/dEWhtCsKlwKL IBHYH6blRx K9rC0bMJPwQ4mLIuw85H2EY762 BOCXJZMnpuwhpA== )
+
+;; NSEC3 RR that matches the closest encloser (x.w.example)
+;; H(x.w.example) = b4um86eghhds6nea196smvmlo4ors995
+
+b4um86eghhds6nea196smvmlo4ors995.example. NSEC3 1 1 12 aabbccdd ( gjeqe526plbf1g8mklp59enfd789njgi MX RRSIG )
+b4um86eghhds6nea196smvmlo4ors995.example. RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 ( 40430 example. ZkPG3M32lmoHM6pa3D6gZFGB/rhL//Bs3Omh 5u4m/CUi wtblEVOaAKKZd7S959OeiX43aLX3 pOv0TSTyiTxIZg== )
+
+;; NSEC3 RR that covers wildcard at the closest encloser (*.x.w.example)
+;; H(*.x.w.example) = 92pqneegtaue7pjatc3l3qnk738c6v5m
+
+35mthgpgcu1qg68fab165klnsnk3dpvl.example. NSEC3 1 1 12 aabbccdd ( b4um86eghhds6nea196smvmlo4ors995 NS DS RRSIG )
+35mthgpgcu1qg68fab165klnsnk3dpvl.example. RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 ( 40430 example. g6jPUUpduAJKRljUsN8gB4UagAX0NxY9shwQ Aynzo8EUWH +z6hEIBlUTPGj15eZll6VhQqgZ XtAIR3chwgW+SA== )
+
+SECTION ADDITIONAL
+ENTRY_END
+
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+a.c.x.w.example. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+;MATCH all
+;do not compare authority
+MATCH opcode qname flags rcode question answer additional
+REPLY QR RD RA SERVFAIL
+SECTION QUESTION
+a.c.x.w.example. IN A
+SECTION ANSWER
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+SCENARIO_END
+
diff --git a/tests/integration/deckard/sets/resolver/val_nsec3_b1_nameerror_nowc.rpl b/tests/integration/deckard/sets/resolver/val_nsec3_b1_nameerror_nowc.rpl
new file mode 100644
index 0000000..3b1e6fc
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_nsec3_b1_nameerror_nowc.rpl
@@ -0,0 +1,154 @@
+do-ip6: no
+
+; config options
+;server:
+ trust-anchor: "example. DNSKEY 257 3 7 AwEAAcUlFV1vhmqx6NSOUOq2R/dsR7Xm3upJ ( j7IommWSpJABVfW8Q0rOvXdM6kzt+TAu92L9 AbsUdblMFin8CVF3n4s= )"
+ val-override-date: "20120420235959"
+; target-fetch-policy: "0 0 0 0 0"
+ query-minimization: off
+
+;stub-zone:
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test validator NSEC3 B.1 name error without wc NSEC3.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example. IN A
+SECTION AUTHORITY
+example. IN NS ns1.example.
+; leave out to make unbound take ns1
+;example. IN NS ns2.example.
+SECTION ADDITIONAL
+ns1.example. IN A 192.0.2.1
+; leave out to make unbound take ns1
+;ns2.example. IN A 192.0.2.2
+ENTRY_END
+RANGE_END
+
+; ns1.example.
+RANGE_BEGIN 0 100
+ ADDRESS 192.0.2.1
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id copy_query
+REPLY QR REFUSED
+SECTION QUESTION
+ns1.example. IN A
+SECTION ANSWER
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id copy_query
+REPLY QR REFUSED
+SECTION QUESTION
+ns1.example. IN AAAA
+SECTION ANSWER
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id copy_query
+REPLY QR REFUSED
+SECTION QUESTION
+example. IN NS
+SECTION ANSWER
+ENTRY_END
+
+; response to DNSKEY priming query
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example. IN DNSKEY
+SECTION ANSWER
+example. DNSKEY 256 3 7 AwEAAaetidLzsKWUt4swWR8yu0wPHPiUi8LU ( sAD0QPWU+wzt89epO6tHzkMBVDkC7qphQO2h TY4hHn9npWFRw5BYubE= )
+example. DNSKEY 257 3 7 AwEAAcUlFV1vhmqx6NSOUOq2R/dsR7Xm3upJ ( j7IommWSpJABVfW8Q0rOvXdM6kzt+TAu92L9 AbsUdblMFin8CVF3n4s= )
+example. RRSIG DNSKEY 7 1 3600 20150420235959 ( 20051021000000 12708 example. AuU4juU9RaxescSmStrQks3Gh9FblGBlVU31 uzMZ/U/FpsUb8aC6QZS+sTsJXnLnz7flGOsm MGQZf3bH+QsCtg== )
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA DO NXDOMAIN
+SECTION QUESTION
+a.c.x.w.example. IN A
+SECTION AUTHORITY
+example. SOA ns1.example. bugs.x.w.example. 1 3600 300 ( 3600000 3600 )
+example. RRSIG SOA 7 1 3600 20150420235959 20051021000000 ( 40430 example. Hu25UIyNPmvPIVBrldN+9Mlp9Zql39qaUd8i q4ZLlYWfUUbbAS41pG+68z81q1xhkYAcEyHd VI2LmKusbZsT0Q== )
+
+;; NSEC3 RR that covers the "next closer" name (c.x.w.example)
+;; H(c.x.w.example) = 0va5bpr2ou0vk0lbqeeljri88laipsfh
+
+0p9mhaveqvm6t7vbl5lop2u3t2rp3tom.example. NSEC3 1 1 12 aabbccdd ( 2t7b4g4vsa5smi47k61mv5bv1a22bojr MX DNSKEY NS SOA NSEC3PARAM RRSIG )
+0p9mhaveqvm6t7vbl5lop2u3t2rp3tom.example. RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 ( 40430 example. OSgWSm26B+cS+dDL8b5QrWr/dEWhtCsKlwKL IBHYH6blRxK9rC0bMJPwQ4mLIuw85H2EY762 BOCXJZMnpuwhpA== )
+
+;; NSEC3 RR that matches the closest encloser (x.w.example)
+;; H(x.w.example) = b4um86eghhds6nea196smvmlo4ors995
+
+b4um86eghhds6nea196smvmlo4ors995.example. NSEC3 1 1 12 aabbccdd ( gjeqe526plbf1g8mklp59enfd789njgi MX RRSIG )
+b4um86eghhds6nea196smvmlo4ors995.example. RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 ( 40430 example. ZkPG3M32lmoHM6pa3D6gZFGB/rhL//Bs3Omh 5u4m/CUiwtblEVOaAKKZd7S959OeiX43aLX3 pOv0TSTyiTxIZg== )
+
+;; NSEC3 RR that covers wildcard at the closest encloser (*.x.w.example)
+;; H(*.x.w.example) = 92pqneegtaue7pjatc3l3qnk738c6v5m
+
+
+;35mthgpgcu1qg68fab165klnsnk3dpvl.example. NSEC3 1 1 12 aabbccdd ( b4um86eghhds6nea196smvmlo4ors995 NS DS RRSIG )
+;35mthgpgcu1qg68fab165klnsnk3dpvl.example. RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 ( 40430 example. g6jPUUpduAJKRljUsN8gB4UagAX0NxY9shwQ Aynzo8EUWH+z6hEIBlUTPGj15eZll6VhQqgZ XtAIR3chwgW+SA== )
+SECTION ADDITIONAL
+ENTRY_END
+
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+a.c.x.w.example. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+;do not compare authority
+;MATCH all
+MATCH opcode qname flags rcode question answer additional
+REPLY QR RD RA DO SERVFAIL
+SECTION QUESTION
+a.c.x.w.example. IN A
+SECTION ANSWER
+SECTION AUTHORITY
+; example. SOA ns1.example. bugs.x.w.example. 1 3600 300 ( 3600000 3600 )
+; example. RRSIG SOA 7 1 3600 20150420235959 20051021000000 ( 40430 example. Hu25UIyNPmvPIVBrldN+9Mlp9Zql39qaUd8i q4ZLlYWfUUbbAS41pG+68z81q1xhkYAcEyHd VI2LmKusbZsT0Q== )
+; 0p9mhaveqvm6t7vbl5lop2u3t2rp3tom.example. NSEC3 1 1 12 aabbccdd ( 2t7b4g4vsa5smi47k61mv5bv1a22bojr MX DNSKEY NS SOA NSEC3PARAM RRSIG )
+; 0p9mhaveqvm6t7vbl5lop2u3t2rp3tom.example. RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 ( 40430 example. OSgWSm26B+cS+dDL8b5QrWr/dEWhtCsKlwKL IBHYH6blRxK9rC0bMJPwQ4mLIuw85H2EY762 BOCXJZMnpuwhpA== )
+; b4um86eghhds6nea196smvmlo4ors995.example. NSEC3 1 1 12 aabbccdd ( gjeqe526plbf1g8mklp59enfd789njgi MX RRSIG )
+; b4um86eghhds6nea196smvmlo4ors995.example. RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 ( 40430 example. ZkPG3M32lmoHM6pa3D6gZFGB/rhL//Bs3Omh 5u4m/CUiwtblEVOaAKKZd7S959OeiX43aLX3 pOv0TSTyiTxIZg== )
+SECTION ADDITIONAL
+ENTRY_END
+
+SCENARIO_END
+
diff --git a/tests/integration/deckard/sets/resolver/val_nsec3_b21_nodataent.rpl b/tests/integration/deckard/sets/resolver/val_nsec3_b21_nodataent.rpl
new file mode 100644
index 0000000..06f914e
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_nsec3_b21_nodataent.rpl
@@ -0,0 +1,118 @@
+do-ip6: no
+
+; config options
+;server:
+ trust-anchor: "example. DNSKEY 257 3 7 AwEAAcUlFV1vhmqx6NSOUOq2R/dsR7Xm3upJ ( j7IommWSpJABVfW8Q0rOvXdM6kzt+TAu92L9 AbsUdblMFin8CVF3n4s= )"
+ val-override-date: "20120420235959"
+; target-fetch-policy: "0 0 0 0 0"
+ query-minimization: off
+
+;stub-zone:
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test validator NSEC3 B.2.1 no data empty nonterminal.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+. IN A
+SECTION AUTHORITY
+example. IN NS ns1.example.
+; leave out to make unbound take ns1
+;example. IN NS ns2.example.
+SECTION ADDITIONAL
+ns1.example. IN A 192.0.2.1
+; leave out to make unbound take ns1
+;ns2.example. IN A 192.0.2.2
+ENTRY_END
+RANGE_END
+
+; ns1.example.
+RANGE_BEGIN 0 100
+ ADDRESS 192.0.2.1
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id copy_query
+REPLY QR REFUSED
+SECTION QUESTION
+example. IN NS
+SECTION ANSWER
+ENTRY_END
+
+; response to DNSKEY priming query
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example. IN DNSKEY
+SECTION ANSWER
+example. DNSKEY 256 3 7 AwEAAaetidLzsKWUt4swWR8yu0wPHPiUi8LU ( sAD0QPWU+wzt89epO6tHzkMBVDkC7qphQO2h TY4hHn9npWFRw5BYubE= )
+example. DNSKEY 257 3 7 AwEAAcUlFV1vhmqx6NSOUOq2R/dsR7Xm3upJ ( j7IommWSpJABVfW8Q0rOvXdM6kzt+TAu92L9 AbsUdblMFin8CVF3n4s= )
+example. RRSIG DNSKEY 7 1 3600 20150420235959 ( 20051021000000 12708 example. AuU4juU9RaxescSmStrQks3Gh9FblGBlVU31 uzMZ/U/FpsUb8aC6QZS+sTsJXnLnz7flGOsm MGQZf3bH+QsCtg== )
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA DO NOERROR
+SECTION QUESTION
+y.w.example. IN A
+SECTION AUTHORITY
+example. SOA ns1.example. bugs.x.w.example. 1 3600 300 ( 3600000 3600 )
+example. RRSIG SOA 7 1 3600 20150420235959 20051021000000 ( 40430 example. Hu25UIyNPmvPIVBrldN+9Mlp9Zql39qaUd8i q4ZLlYWfUUbbAS41pG+68z81q1xhkYAcEyHd VI2LmKusbZsT0Q== )
+
+;; NSEC3 RR matches the QNAME and shows that the A type bit is not set.
+ji6neoaepv8b5o6k4ev33abha8ht9fgc.example. NSEC3 1 1 12 aabbccdd ( k8udemvp1j2f7eg6jebps17vp3n8i58h )
+ji6neoaepv8b5o6k4ev33abha8ht9fgc.example. RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 ( 40430 example. gPkFp1s2QDQ6wQzcg1uSebZ61W33rUBDcTj7 2F3kQ490fEdp7k1BUIfbcZtPbX3YCpE+sIt0 MpzVSKfTwx4uYA== )
+
+SECTION ADDITIONAL
+ENTRY_END
+
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+y.w.example. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+y.w.example. IN A
+SECTION ANSWER
+SECTION AUTHORITY
+example. SOA ns1.example. bugs.x.w.example. 1 3600 300 ( 3600000 3600 )
+example. RRSIG SOA 7 1 3600 20150420235959 20051021000000 ( 40430 example. Hu25UIyNPmvPIVBrldN+9Mlp9Zql39qaUd8i q4ZLlYWfUUbbAS41pG+68z81q1xhkYAcEyHd VI2LmKusbZsT0Q== )
+ji6neoaepv8b5o6k4ev33abha8ht9fgc.example. NSEC3 1 1 12 aabbccdd ( k8udemvp1j2f7eg6jebps17vp3n8i58h )
+ji6neoaepv8b5o6k4ev33abha8ht9fgc.example. RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 ( 40430 example. gPkFp1s2QDQ6wQzcg1uSebZ61W33rUBDcTj7 2F3kQ490fEdp7k1BUIfbcZtPbX3YCpE+sIt0 MpzVSKfTwx4uYA== )
+SECTION ADDITIONAL
+ENTRY_END
+
+SCENARIO_END
+
diff --git a/tests/integration/deckard/sets/resolver/val_nsec3_b21_nodataent_wr.rpl b/tests/integration/deckard/sets/resolver/val_nsec3_b21_nodataent_wr.rpl
new file mode 100644
index 0000000..bd1e1f8
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_nsec3_b21_nodataent_wr.rpl
@@ -0,0 +1,138 @@
+do-ip6: no
+
+; config options
+;server:
+ trust-anchor: "example. DNSKEY 257 3 7 AwEAAcUlFV1vhmqx6NSOUOq2R/dsR7Xm3upJ ( j7IommWSpJABVfW8Q0rOvXdM6kzt+TAu92L9 AbsUdblMFin8CVF3n4s= )"
+ val-override-date: "20120420235959"
+; target-fetch-policy: "0 0 0 0 0"
+ query-minimization: off
+
+;stub-zone:
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test validator NSEC3 B.2.1 no data empty nonterminal, wrong rr.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example. IN A
+SECTION AUTHORITY
+example. IN NS ns1.example.
+; leave out to make unbound take ns1
+;example. IN NS ns2.example.
+SECTION ADDITIONAL
+ns1.example. IN A 192.0.2.1
+; leave out to make unbound take ns1
+;ns2.example. IN A 192.0.2.2
+ENTRY_END
+RANGE_END
+
+; ns1.example.
+RANGE_BEGIN 0 100
+ ADDRESS 192.0.2.1
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id copy_query
+REPLY QR REFUSED
+SECTION QUESTION
+ns1.example. IN A
+SECTION ANSWER
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id copy_query
+REPLY QR REFUSED
+SECTION QUESTION
+ns1.example. IN AAAA
+SECTION ANSWER
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id copy_query
+REPLY QR REFUSED
+SECTION QUESTION
+example. IN NS
+SECTION ANSWER
+ENTRY_END
+
+; response to DNSKEY priming query
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example. IN DNSKEY
+SECTION ANSWER
+example. DNSKEY 256 3 7 AwEAAaetidLzsKWUt4swWR8yu0wPHPiUi8LU ( sAD0QPWU+wzt89epO6tHzkMBVDkC7qphQO2h TY4hHn9npWFRw5BYubE= )
+example. DNSKEY 257 3 7 AwEAAcUlFV1vhmqx6NSOUOq2R/dsR7Xm3upJ ( j7IommWSpJABVfW8Q0rOvXdM6kzt+TAu92L9 AbsUdblMFin8CVF3n4s= )
+example. RRSIG DNSKEY 7 1 3600 20150420235959 ( 20051021000000 12708 example. AuU4juU9RaxescSmStrQks3Gh9FblGBlVU31 uzMZ/U/FpsUb8aC6QZS+sTsJXnLnz7flGOsm MGQZf3bH+QsCtg== )
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA DO NOERROR
+SECTION QUESTION
+y.w.example. IN A
+SECTION AUTHORITY
+example. SOA ns1.example. bugs.x.w.example. 1 3600 300 ( 3600000 3600 )
+example. RRSIG SOA 7 1 3600 20150420235959 20051021000000 ( 40430 example. Hu25UIyNPmvPIVBrldN+9Mlp9Zql39qaUd8i q4ZLlYWfUUbbAS41pG+68z81q1xhkYAcEyHd VI2LmKusbZsT0Q== )
+
+;; NSEC3 RR matches the QNAME and shows that the A type bit is not set.
+;ji6neoaepv8b5o6k4ev33abha8ht9fgc.example. NSEC3 1 1 12 aabbccdd ( k8udemvp1j2f7eg6jebps17vp3n8i58h )
+;ji6neoaepv8b5o6k4ev33abha8ht9fgc.example. RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 ( 40430 example. gPkFp1s2QDQ6wQzcg1uSebZ61W33rUBDcTj7 2F3kQ490fEdp7k1BUIfbcZtPbX3YCpE+sIt0 MpzVSKfTwx4uYA== )
+
+; instead the wrong NSEC3 rr is included
+35mthgpgcu1qg68fab165klnsnk3dpvl.example. NSEC3 1 1 12 aabbccdd ( b4um86eghhds6nea196smvmlo4ors995 NS DS RRSIG )
+35mthgpgcu1qg68fab165klnsnk3dpvl.example. RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 ( 40430 example. g6jPUUpduAJKRljUsN8gB4UagAX0NxY9shwQ Aynzo8EUWH+z6hEIBlUTPGj15eZll6VhQqgZ XtAIR3chwgW+SA== )
+
+SECTION ADDITIONAL
+ENTRY_END
+
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+y.w.example. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+;MATCH all
+;do not compare authority
+MATCH opcode qname flags rcode question answer additional
+REPLY QR RD RA SERVFAIL
+SECTION QUESTION
+y.w.example. IN A
+SECTION ANSWER
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+SCENARIO_END
+
diff --git a/tests/integration/deckard/sets/resolver/val_nsec3_b2_nodata.rpl b/tests/integration/deckard/sets/resolver/val_nsec3_b2_nodata.rpl
new file mode 100644
index 0000000..6df531f
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_nsec3_b2_nodata.rpl
@@ -0,0 +1,119 @@
+do-ip6: no
+
+; config options
+;server:
+ trust-anchor: "example. DNSKEY 257 3 7 AwEAAcUlFV1vhmqx6NSOUOq2R/dsR7Xm3upJ ( j7IommWSpJABVfW8Q0rOvXdM6kzt+TAu92L9 AbsUdblMFin8CVF3n4s= )"
+ val-override-date: "20120420235959"
+; target-fetch-policy: "0 0 0 0 0"
+; fake-sha1: yes
+
+;stub-zone:
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+;test from testbound
+
+SCENARIO_BEGIN Test validator NSEC3 B.2 no data.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+. IN A
+SECTION AUTHORITY
+example. IN NS ns1.example.
+; leave out to make unbound take ns1
+;example. IN NS ns2.example.
+SECTION ADDITIONAL
+ns1.example. IN A 192.0.2.1
+; leave out to make unbound take ns1
+;ns2.example. IN A 192.0.2.2
+ENTRY_END
+RANGE_END
+
+; ns1.example.
+RANGE_BEGIN 0 100
+ ADDRESS 192.0.2.1
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id copy_query
+REPLY QR REFUSED
+SECTION QUESTION
+example. IN NS
+SECTION ANSWER
+ENTRY_END
+
+; response to DNSKEY priming query
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example. IN DNSKEY
+SECTION ANSWER
+example. DNSKEY 256 3 7 AwEAAaetidLzsKWUt4swWR8yu0wPHPiUi8LU ( sAD0QPWU+wzt89epO6tHzkMBVDkC7qphQO2h TY4hHn9npWFRw5BYubE= )
+example. DNSKEY 257 3 7 AwEAAcUlFV1vhmqx6NSOUOq2R/dsR7Xm3upJ ( j7IommWSpJABVfW8Q0rOvXdM6kzt+TAu92L9 AbsUdblMFin8CVF3n4s= )
+example. RRSIG DNSKEY 7 1 3600 20150420235959 ( 20051021000000 12708 example. AuU4juU9RaxescSmStrQks3Gh9FblGBlVU31 uzMZ/U/FpsUb8aC6QZS+sTsJXnLnz7flGOsm MGQZf3bH+QsCtg== )
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA DO NOERROR
+SECTION QUESTION
+ns1.example. IN MX
+SECTION AUTHORITY
+example. SOA ns1.example. bugs.x.w.example. 1 3600 300 ( 3600000 3600 )
+example. RRSIG SOA 7 1 3600 20150420235959 20051021000000 ( 40430 example. Hu25UIyNPmvPIVBrldN+9Mlp9Zql39qaUd8i q4ZLlYWfUUbbAS41pG+68z81q1xhkYAcEyHd VI2LmKusbZsT0Q== )
+
+;; NSEC3 RR matches the QNAME and shows that the MX type bit is not set.
+2t7b4g4vsa5smi47k61mv5bv1a22bojr.example. NSEC3 1 1 12 aabbccdd ( 2vptu5timamqttgl4luu9kg21e0aor3s A RRSIG )
+2t7b4g4vsa5smi47k61mv5bv1a22bojr.example. RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 ( 40430 example. OmBvJ1Vgg1hCKMXHFiNeIYHK9XVW0iLDLwJN 4TFoNxZuP03gAXEI634YwOc4YBNITrj413iq NI6mRk/r1dOSUw== )
+
+SECTION ADDITIONAL
+ENTRY_END
+
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+ns1.example. IN MX
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+ns1.example. IN MX
+SECTION ANSWER
+SECTION AUTHORITY
+example. SOA ns1.example. bugs.x.w.example. 1 3600 300 ( 3600000 3600 )
+example. RRSIG SOA 7 1 3600 20150420235959 20051021000000 ( 40430 example. Hu25UIyNPmvPIVBrldN+9Mlp9Zql39qaUd8i q4ZLlYWfUUbbAS41pG+68z81q1xhkYAcEyHd VI2LmKusbZsT0Q== )
+2t7b4g4vsa5smi47k61mv5bv1a22bojr.example. NSEC3 1 1 12 aabbccdd ( 2vptu5timamqttgl4luu9kg21e0aor3s A RRSIG )
+2t7b4g4vsa5smi47k61mv5bv1a22bojr.example. RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 ( 40430 example. OmBvJ1Vgg1hCKMXHFiNeIYHK9XVW0iLDLwJN 4TFoNxZuP03gAXEI634YwOc4YBNITrj413iq NI6mRk/r1dOSUw== )
+SECTION ADDITIONAL
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/val_nsec3_b2_nodata_nons.rpl b/tests/integration/deckard/sets/resolver/val_nsec3_b2_nodata_nons.rpl
new file mode 100644
index 0000000..5bc1fd6
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_nsec3_b2_nodata_nons.rpl
@@ -0,0 +1,144 @@
+do-ip6: no
+
+; config options
+;server:
+ trust-anchor: "example. DNSKEY 257 3 7 AwEAAcUlFV1vhmqx6NSOUOq2R/dsR7Xm3upJ ( j7IommWSpJABVfW8Q0rOvXdM6kzt+TAu92L9 AbsUdblMFin8CVF3n4s= )"
+ val-override-date: "20120420235959"
+; target-fetch-policy: "0 0 0 0 0"
+; fake-sha1: yes
+
+;stub-zone:
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+;test from testbound
+
+SCENARIO_BEGIN Test validator NSEC3 B.2 no data, without NSEC3.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example. IN A
+SECTION AUTHORITY
+example. IN NS ns1.example.
+; leave out to make unbound take ns1
+;example. IN NS ns2.example.
+SECTION ADDITIONAL
+ns1.example. IN A 192.0.2.1
+; leave out to make unbound take ns1
+;ns2.example. IN A 192.0.2.2
+ENTRY_END
+RANGE_END
+
+; ns1.example.
+RANGE_BEGIN 0 100
+ ADDRESS 192.0.2.1
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id copy_query
+REPLY QR REFUSED
+SECTION QUESTION
+ns1.example. IN A
+SECTION ANSWER
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id copy_query
+REPLY QR REFUSED
+SECTION QUESTION
+ns1.example. IN AAAA
+SECTION ANSWER
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id copy_query
+REPLY QR REFUSED
+SECTION QUESTION
+example. IN NS
+SECTION ANSWER
+ENTRY_END
+
+; response to DNSKEY priming query
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example. IN DNSKEY
+SECTION ANSWER
+example. DNSKEY 256 3 7 AwEAAaetidLzsKWUt4swWR8yu0wPHPiUi8LU ( sAD0QPWU+wzt89epO6tHzkMBVDkC7qphQO2h TY4hHn9npWFRw5BYubE= )
+example. DNSKEY 257 3 7 AwEAAcUlFV1vhmqx6NSOUOq2R/dsR7Xm3upJ ( j7IommWSpJABVfW8Q0rOvXdM6kzt+TAu92L9 AbsUdblMFin8CVF3n4s= )
+example. RRSIG DNSKEY 7 1 3600 20150420235959 ( 20051021000000 12708 example. AuU4juU9RaxescSmStrQks3Gh9FblGBlVU31 uzMZ/U/FpsUb8aC6QZS+sTsJXnLnz7flGOsm MGQZf3bH+QsCtg== )
+ENTRY_END
+
+; response to DS query
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA DO NOERROR
+SECTION QUESTION
+ns1.example. IN DS
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA DO NOERROR
+SECTION QUESTION
+ns1.example. IN MX
+SECTION AUTHORITY
+example. SOA ns1.example. bugs.x.w.example. 1 3600 300 ( 3600000 3600 )
+example. RRSIG SOA 7 1 3600 20150420235959 20051021000000 ( 40430 example. Hu25UIyNPmvPIVBrldN+9Mlp9Zql39qaUd8i q4ZLlYWfUUbbAS41pG+68z81q1xhkYAcEyHd VI2LmKusbZsT0Q== )
+
+;; NSEC3 RR matches the QNAME and shows that the MX type bit is not set.
+;2t7b4g4vsa5smi47k61mv5bv1a22bojr.example. NSEC3 1 1 12 aabbccdd ( 2vptu5timamqttgl4luu9kg21e0aor3s A RRSIG )
+;2t7b4g4vsa5smi47k61mv5bv1a22bojr.example. RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 ( 40430 example. OmBvJ1Vgg1hCKMXHFiNeIYHK9XVW0iLDLwJN 4TFoNxZuP03gAXEI634YwOc4YBNITrj413iq NI6mRk/r1dOSUw== )
+
+SECTION ADDITIONAL
+ENTRY_END
+
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+ns1.example. IN MX
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+;MATCH all
+;do not compare authority
+MATCH opcode qname flags rcode question answer additional
+REPLY QR RD RA DO SERVFAIL
+SECTION QUESTION
+ns1.example. IN MX
+SECTION ANSWER
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/val_nsec3_b3_optout.rpl b/tests/integration/deckard/sets/resolver/val_nsec3_b3_optout.rpl
new file mode 100644
index 0000000..6ab5c9e
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_nsec3_b3_optout.rpl
@@ -0,0 +1,208 @@
+do-ip6: no
+
+; config options
+;server:
+ trust-anchor: "example. DNSKEY 257 3 7 AwEAAcUlFV1vhmqx6NSOUOq2R/dsR7Xm3upJ ( j7IommWSpJABVfW8Q0rOvXdM6kzt+TAu92L9 AbsUdblMFin8CVF3n4s= )"
+ val-override-date: "20120420235959"
+; target-fetch-policy: "0 0 0 0 0"
+ query-minimization: off
+
+;stub-zone:
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test validator NSEC3 B.3 referral to optout unsigned zone.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+. IN A
+SECTION AUTHORITY
+example. IN NS ns1.example.
+; leave out to make unbound take ns1
+;example. IN NS ns2.example.
+SECTION ADDITIONAL
+ns1.example. IN A 192.0.2.1
+; leave out to make unbound take ns1
+;ns2.example. IN A 192.0.2.2
+ENTRY_END
+RANGE_END
+
+; ns1.example.
+RANGE_BEGIN 0 100
+ ADDRESS 192.0.2.1
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id copy_query
+REPLY QR REFUSED
+SECTION QUESTION
+example. IN NS
+SECTION ANSWER
+ENTRY_END
+
+; response to DNSKEY priming query
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example. IN DNSKEY
+SECTION ANSWER
+example. DNSKEY 256 3 7 AwEAAaetidLzsKWUt4swWR8yu0wPHPiUi8LU ( sAD0QPWU+wzt89epO6tHzkMBVDkC7qphQO2h TY4hHn9npWFRw5BYubE= )
+example. DNSKEY 257 3 7 AwEAAcUlFV1vhmqx6NSOUOq2R/dsR7Xm3upJ ( j7IommWSpJABVfW8Q0rOvXdM6kzt+TAu92L9 AbsUdblMFin8CVF3n4s= )
+example. RRSIG DNSKEY 7 1 3600 20150420235959 ( 20051021000000 12708 example. AuU4juU9RaxescSmStrQks3Gh9FblGBlVU31 uzMZ/U/FpsUb8aC6QZS+sTsJXnLnz7flGOsm MGQZf3bH+QsCtg== )
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR DO NOERROR
+SECTION QUESTION
+mc.c.example. IN MX
+SECTION AUTHORITY
+c.example. NS ns1.c.example.
+c.example. NS ns2.c.example.
+
+;; NSEC3 RR that covers the "next closer" name (c.example)
+;; H(c.example) = 4g6p9u5gvfshp30pqecj98b3maqbn1ck
+35mthgpgcu1qg68fab165klnsnk3dpvl.example. NSEC3 1 1 12 aabbccdd ( b4um86eghhds6nea196smvmlo4ors995 NS DS RRSIG )
+35mthgpgcu1qg68fab165klnsnk3dpvl.example. RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 ( 40430 example. g6jPUUpduAJKRljUsN8gB4UagAX0NxY9shwQ Aynzo8EUWH+z6hEIBlUTPGj15eZll6VhQqgZ XtAIR3chwgW+SA== )
+
+;; NSEC3 RR that matches the closest encloser (example)
+;; H(example) = 0p9mhaveqvm6t7vbl5lop2u3t2rp3tom
+0p9mhaveqvm6t7vbl5lop2u3t2rp3tom.example. NSEC3 1 1 12 aabbccdd ( 2t7b4g4vsa5smi47k61mv5bv1a22bojr MX DNSKEY NS SOA NSEC3PARAM RRSIG )
+0p9mhaveqvm6t7vbl5lop2u3t2rp3tom.example. RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 ( 40430 example. OSgWSm26B+cS+dDL8b5QrWr/dEWhtCsKlwKL IBHYH6blRxK9rC0bMJPwQ4mLIuw85H2EY762 BOCXJZMnpuwhpA== )
+
+SECTION ADDITIONAL
+ns1.c.example. A 192.0.2.7
+ns2.c.example. A 192.0.2.8
+
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA DO NOERROR
+SECTION QUESTION
+c.example. IN DS
+SECTION AUTHORITY
+;; NSEC3 RR that covers the "next closer" name (c.example)
+;; H(c.example) = 4g6p9u5gvfshp30pqecj98b3maqbn1ck
+35mthgpgcu1qg68fab165klnsnk3dpvl.example. NSEC3 1 1 12 aabbccdd ( b4um86eghhds6nea196smvmlo4ors995 NS DS RRSIG )
+35mthgpgcu1qg68fab165klnsnk3dpvl.example. RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 ( 40430 example. g6jPUUpduAJKRljUsN8gB4UagAX0NxY9shwQ Aynzo8EUWH+z6hEIBlUTPGj15eZll6VhQqgZ XtAIR3chwgW+SA== )
+
+;; NSEC3 RR that matches the closest encloser (example)
+;; H(example) = 0p9mhaveqvm6t7vbl5lop2u3t2rp3tom
+0p9mhaveqvm6t7vbl5lop2u3t2rp3tom.example. NSEC3 1 1 12 aabbccdd ( 2t7b4g4vsa5smi47k61mv5bv1a22bojr MX DNSKEY NS SOA NSEC3PARAM RRSIG )
+0p9mhaveqvm6t7vbl5lop2u3t2rp3tom.example. RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 ( 40430 example. OSgWSm26B+cS+dDL8b5QrWr/dEWhtCsKlwKL IBHYH6blRxK9rC0bMJPwQ4mLIuw85H2EY762 BOCXJZMnpuwhpA== )
+ENTRY_END
+
+RANGE_END
+
+; ns1.c.example.
+RANGE_BEGIN 0 100
+ ADDRESS 192.0.2.7
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+c.example. IN NS
+SECTION ANSWER
+c.example. NS ns1.c.example.
+c.example. NS ns2.c.example.
+SECTION ADDITIONAL
+ns1.c.example. A 192.0.2.7
+ns2.c.example. A 192.0.2.8
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+mc.c.example. IN MX
+SECTION ANSWER
+mc.c.example. IN MX 50 mx.c.example.
+SECTION AUTHORITY
+c.example. NS ns1.c.example.
+c.example. NS ns2.c.example.
+SECTION ADDITIONAL
+ns1.c.example. A 192.0.2.7
+ns2.c.example. A 192.0.2.8
+ENTRY_END
+RANGE_END
+
+; ns2.c.example.
+RANGE_BEGIN 0 100
+ ADDRESS 192.0.2.8
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+c.example. IN NS
+SECTION ANSWER
+c.example. NS ns1.c.example.
+c.example. NS ns2.c.example.
+SECTION ADDITIONAL
+ns1.c.example. A 192.0.2.7
+ns2.c.example. A 192.0.2.8
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+mc.c.example. IN MX
+SECTION ANSWER
+mc.c.example. IN MX 50 mx.c.example.
+SECTION AUTHORITY
+c.example. NS ns1.c.example.
+c.example. NS ns2.c.example.
+SECTION ADDITIONAL
+ns1.c.example. A 192.0.2.7
+ns2.c.example. A 192.0.2.8
+ENTRY_END
+RANGE_END
+
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+mc.c.example. IN MX
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA DO NOERROR
+SECTION QUESTION
+mc.c.example. IN MX
+SECTION ANSWER
+mc.c.example. IN MX 50 mx.c.example.
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/val_nsec3_b3_optout_negcache.rpl b/tests/integration/deckard/sets/resolver/val_nsec3_b3_optout_negcache.rpl
new file mode 100644
index 0000000..24b5ef9
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_nsec3_b3_optout_negcache.rpl
@@ -0,0 +1,211 @@
+do-ip6: no
+
+; config options
+;server:
+ trust-anchor: "example. DNSKEY 257 3 7 AwEAAcUlFV1vhmqx6NSOUOq2R/dsR7Xm3upJ ( j7IommWSpJABVfW8Q0rOvXdM6kzt+TAu92L9 AbsUdblMFin8CVF3n4s= )"
+ val-override-date: "20120420235959"
+; target-fetch-policy: "0 0 0 0 0"
+; fake-sha1: yes
+ query-minimization: off
+
+;stub-zone:
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test validator NSEC3 B.3 referral optout with negative cache.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+. IN A
+SECTION AUTHORITY
+example. IN NS ns1.example.
+; leave out to make unbound take ns1
+;example. IN NS ns2.example.
+SECTION ADDITIONAL
+ns1.example. IN A 192.0.2.1
+; leave out to make unbound take ns1
+;ns2.example. IN A 192.0.2.2
+ENTRY_END
+RANGE_END
+
+; ns1.example.
+RANGE_BEGIN 0 100
+ ADDRESS 192.0.2.1
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id copy_query
+REPLY QR REFUSED
+SECTION QUESTION
+example. IN NS
+SECTION ANSWER
+ENTRY_END
+
+; response to DNSKEY priming query
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example. IN DNSKEY
+SECTION ANSWER
+example. DNSKEY 256 3 7 AwEAAaetidLzsKWUt4swWR8yu0wPHPiUi8LU ( sAD0QPWU+wzt89epO6tHzkMBVDkC7qphQO2h TY4hHn9npWFRw5BYubE= )
+example. DNSKEY 257 3 7 AwEAAcUlFV1vhmqx6NSOUOq2R/dsR7Xm3upJ ( j7IommWSpJABVfW8Q0rOvXdM6kzt+TAu92L9 AbsUdblMFin8CVF3n4s= )
+example. RRSIG DNSKEY 7 1 3600 20150420235959 ( 20051021000000 12708 example. AuU4juU9RaxescSmStrQks3Gh9FblGBlVU31 uzMZ/U/FpsUb8aC6QZS+sTsJXnLnz7flGOsm MGQZf3bH+QsCtg== )
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA DO NOERROR
+SECTION QUESTION
+mc.c.example. IN MX
+SECTION AUTHORITY
+c.example. NS ns1.c.example.
+c.example. NS ns2.c.example.
+
+;; NSEC3 RR that covers the "next closer" name (c.example)
+;; H(c.example) = 4g6p9u5gvfshp30pqecj98b3maqbn1ck
+35mthgpgcu1qg68fab165klnsnk3dpvl.example. NSEC3 1 1 12 aabbccdd ( b4um86eghhds6nea196smvmlo4ors995 NS DS RRSIG )
+35mthgpgcu1qg68fab165klnsnk3dpvl.example. RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 ( 40430 example. g6jPUUpduAJKRljUsN8gB4UagAX0NxY9shwQ Aynzo8EUWH+z6hEIBlUTPGj15eZll6VhQqgZ XtAIR3chwgW+SA== )
+
+;; NSEC3 RR that matches the closest encloser (example)
+;; H(example) = 0p9mhaveqvm6t7vbl5lop2u3t2rp3tom
+0p9mhaveqvm6t7vbl5lop2u3t2rp3tom.example. NSEC3 1 1 12 aabbccdd ( 2t7b4g4vsa5smi47k61mv5bv1a22bojr MX DNSKEY NS SOA NSEC3PARAM RRSIG )
+0p9mhaveqvm6t7vbl5lop2u3t2rp3tom.example. RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 ( 40430 example. OSgWSm26B+cS+dDL8b5QrWr/dEWhtCsKlwKL IBHYH6blRxK9rC0bMJPwQ4mLIuw85H2EY762 BOCXJZMnpuwhpA== )
+
+SECTION ADDITIONAL
+ns1.c.example. A 192.0.2.7
+ns2.c.example. A 192.0.2.8
+
+ENTRY_END
+
+
+; DS must be gotten from neg cache
+; ENTRY_BEGIN
+; MATCH opcode qtype qname
+; ADJUST copy_id
+; REPLY QR AA DO NOERROR
+; SECTION QUESTION
+; c.example. IN DS
+; SECTION AUTHORITY
+; ;; NSEC3 RR that covers the "next closer" name (c.example)
+; ;; H(c.example) = 4g6p9u5gvfshp30pqecj98b3maqbn1ck
+; 35mthgpgcu1qg68fab165klnsnk3dpvl.example. NSEC3 1 1 12 aabbccdd ( b4um86eghhds6nea196smvmlo4ors995 NS DS RRSIG )
+; 35mthgpgcu1qg68fab165klnsnk3dpvl.example. RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 ( 40430 example. g6jPUUpduAJKRljUsN8gB4UagAX0NxY9shwQ Aynzo8EUWH+z6hEIBlUTPGj15eZll6VhQqgZ XtAIR3chwgW+SA== )
+;
+; ;; NSEC3 RR that matches the closest encloser (example)
+; ;; H(example) = 0p9mhaveqvm6t7vbl5lop2u3t2rp3tom
+; 0p9mhaveqvm6t7vbl5lop2u3t2rp3tom.example. NSEC3 1 1 12 aabbccdd ( 2t7b4g4vsa5smi47k61mv5bv1a22bojr MX DNSKEY NS SOA NSEC3PARAM RRSIG )
+; 0p9mhaveqvm6t7vbl5lop2u3t2rp3tom.example. RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 ( 40430 example. OSgWSm26B+cS+dDL8b5QrWr/dEWhtCsKlwKL IBHYH6blRxK9rC0bMJPwQ4mLIuw85H2EY762 BOCXJZMnpuwhpA== )
+; ENTRY_END
+
+RANGE_END
+
+; ns1.c.example.
+RANGE_BEGIN 0 100
+ ADDRESS 192.0.2.7
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+c.example. IN NS
+SECTION ANSWER
+c.example. NS ns1.c.example.
+c.example. NS ns2.c.example.
+SECTION ADDITIONAL
+ns1.c.example. A 192.0.2.7
+ns2.c.example. A 192.0.2.8
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+mc.c.example. IN MX
+SECTION ANSWER
+mc.c.example. IN MX 50 mx.c.example.
+SECTION AUTHORITY
+c.example. NS ns1.c.example.
+c.example. NS ns2.c.example.
+SECTION ADDITIONAL
+ns1.c.example. A 192.0.2.7
+ns2.c.example. A 192.0.2.8
+ENTRY_END
+RANGE_END
+
+; ns2.c.example.
+RANGE_BEGIN 0 100
+ ADDRESS 192.0.2.8
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+c.example. IN NS
+SECTION ANSWER
+c.example. NS ns1.c.example.
+c.example. NS ns2.c.example.
+SECTION ADDITIONAL
+ns1.c.example. A 192.0.2.7
+ns2.c.example. A 192.0.2.8
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+mc.c.example. IN MX
+SECTION ANSWER
+mc.c.example. IN MX 50 mx.c.example.
+SECTION AUTHORITY
+c.example. NS ns1.c.example.
+c.example. NS ns2.c.example.
+SECTION ADDITIONAL
+ns1.c.example. A 192.0.2.7
+ns2.c.example. A 192.0.2.8
+ENTRY_END
+RANGE_END
+
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+mc.c.example. IN MX
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH opcode qname flags rcode question answer
+REPLY QR RD RA DO NOERROR
+SECTION QUESTION
+mc.c.example. IN MX
+SECTION ANSWER
+mc.c.example. IN MX 50 mx.c.example.
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/val_nsec3_b3_optout_noce.rpl b/tests/integration/deckard/sets/resolver/val_nsec3_b3_optout_noce.rpl
new file mode 100644
index 0000000..569f019
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_nsec3_b3_optout_noce.rpl
@@ -0,0 +1,257 @@
+do-ip6: no
+
+; config options
+;server:
+ trust-anchor: "example. DNSKEY 257 3 7 AwEAAcUlFV1vhmqx6NSOUOq2R/dsR7Xm3upJ ( j7IommWSpJABVfW8Q0rOvXdM6kzt+TAu92L9 AbsUdblMFin8CVF3n4s= )"
+ val-override-date: "20120420235959"
+; target-fetch-policy: "0 0 0 0 0"
+; fake-sha1: yes
+
+;stub-zone:
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+;test from testbound
+
+SCENARIO_BEGIN Test validator NSEC3 B.3 optout unsigned, without ce.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example. IN A
+SECTION AUTHORITY
+example. IN NS ns1.example.
+; leave out to make unbound take ns1
+;example. IN NS ns2.example.
+SECTION ADDITIONAL
+ns1.example. IN A 192.0.2.1
+; leave out to make unbound take ns1
+;ns2.example. IN A 192.0.2.2
+ENTRY_END
+RANGE_END
+
+; ns1.example.
+RANGE_BEGIN 0 100
+ ADDRESS 192.0.2.1
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id copy_query
+REPLY QR REFUSED
+SECTION QUESTION
+ns1.example. IN A
+SECTION ANSWER
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id copy_query
+REPLY QR REFUSED
+SECTION QUESTION
+ns1.example. IN AAAA
+SECTION ANSWER
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id copy_query
+REPLY QR REFUSED
+SECTION QUESTION
+example. IN NS
+SECTION ANSWER
+ENTRY_END
+
+; response to DNSKEY priming query
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example. IN DNSKEY
+SECTION ANSWER
+example. DNSKEY 256 3 7 AwEAAaetidLzsKWUt4swWR8yu0wPHPiUi8LU ( sAD0QPWU+wzt89epO6tHzkMBVDkC7qphQO2h TY4hHn9npWFRw5BYubE= )
+example. DNSKEY 257 3 7 AwEAAcUlFV1vhmqx6NSOUOq2R/dsR7Xm3upJ ( j7IommWSpJABVfW8Q0rOvXdM6kzt+TAu92L9 AbsUdblMFin8CVF3n4s= )
+example. RRSIG DNSKEY 7 1 3600 20150420235959 ( 20051021000000 12708 example. AuU4juU9RaxescSmStrQks3Gh9FblGBlVU31 uzMZ/U/FpsUb8aC6QZS+sTsJXnLnz7flGOsm MGQZf3bH+QsCtg== )
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA DO NOERROR
+SECTION QUESTION
+c.example. IN DS
+SECTION AUTHORITY
+;; NSEC3 RR that covers the "next closer" name (c.example)
+;; H(c.example) = 4g6p9u5gvfshp30pqecj98b3maqbn1ck
+35mthgpgcu1qg68fab165klnsnk3dpvl.example. NSEC3 1 1 12 aabbccdd ( b4um86eghhds6nea196smvmlo4ors995 NS DS RRSIG )
+35mthgpgcu1qg68fab165klnsnk3dpvl.example. RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 ( 40430 example. g6jPUUpduAJKRljUsN8gB4UagAX0NxY9shwQ Aynzo8EUWH+z6hEIBlUTPGj15eZll6VhQqgZ XtAIR3chwgW+SA== )
+
+;; NSEC3 RR that matches the closest encloser (example)
+;; H(example) = 0p9mhaveqvm6t7vbl5lop2u3t2rp3tom
+;0p9mhaveqvm6t7vbl5lop2u3t2rp3tom.example. NSEC3 1 1 12 aabbccdd ( 2t7b4g4vsa5smi47k61mv5bv1a22bojr MX DNSKEY NS SOA NSEC3PARAM RRSIG )
+;0p9mhaveqvm6t7vbl5lop2u3t2rp3tom.example. RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 ( 40430 example. OSgWSm26B+cS+dDL8b5QrWr/dEWhtCsKlwKL IBHYH6blRxK9rC0bMJPwQ4mLIuw85H2EY762 BOCXJZMnpuwhpA== )
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR AA DO NOERROR
+SECTION QUESTION
+c.example. IN MX
+SECTION AUTHORITY
+c.example. NS ns1.c.example.
+c.example. NS ns2.c.example.
+
+;; NSEC3 RR that covers the "next closer" name (c.example)
+;; H(c.example) = 4g6p9u5gvfshp30pqecj98b3maqbn1ck
+35mthgpgcu1qg68fab165klnsnk3dpvl.example. NSEC3 1 1 12 aabbccdd ( b4um86eghhds6nea196smvmlo4ors995 NS DS RRSIG )
+35mthgpgcu1qg68fab165klnsnk3dpvl.example. RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 ( 40430 example. g6jPUUpduAJKRljUsN8gB4UagAX0NxY9shwQ Aynzo8EUWH+z6hEIBlUTPGj15eZll6VhQqgZ XtAIR3chwgW+SA== )
+
+;; NSEC3 RR that matches the closest encloser (example)
+;; H(example) = 0p9mhaveqvm6t7vbl5lop2u3t2rp3tom
+; 0p9mhaveqvm6t7vbl5lop2u3t2rp3tom.example. NSEC3 1 1 12 aabbccdd ( 2t7b4g4vsa5smi47k61mv5bv1a22bojr MX DNSKEY NS SOA NSEC3PARAM RRSIG )
+; 0p9mhaveqvm6t7vbl5lop2u3t2rp3tom.example. RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 ( 40430 example. OSgWSm26B+cS+dDL8b5QrWr/dEWhtCsKlwKL IBHYH6blRxK9rC0bMJPwQ4mLIuw85H2EY762 BOCXJZMnpuwhpA== )
+
+SECTION ADDITIONAL
+ns1.c.example. A 192.0.2.7
+ns2.c.example. A 192.0.2.8
+
+ENTRY_END
+RANGE_END
+
+; ns1.c.example.
+RANGE_BEGIN 0 100
+ ADDRESS 192.0.2.7
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA REFUSED
+SECTION QUESTION
+ns1.c.example. IN AAAA
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA REFUSED
+SECTION QUESTION
+ns2.c.example. IN AAAA
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+c.example. IN NS
+SECTION ANSWER
+c.example. NS ns1.c.example.
+c.example. NS ns2.c.example.
+SECTION ADDITIONAL
+ns1.c.example. A 192.0.2.7
+ns2.c.example. A 192.0.2.8
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+mc.c.example. IN MX
+SECTION ANSWER
+mc.c.example. IN MX 50 mx.c.example.
+SECTION AUTHORITY
+c.example. NS ns1.c.example.
+c.example. NS ns2.c.example.
+SECTION ADDITIONAL
+ns1.c.example. A 192.0.2.7
+ns2.c.example. A 192.0.2.8
+ENTRY_END
+RANGE_END
+
+; ns2.c.example.
+RANGE_BEGIN 0 100
+ ADDRESS 192.0.2.8
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA REFUSED
+SECTION QUESTION
+ns1.c.example. IN AAAA
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA REFUSED
+SECTION QUESTION
+ns2.c.example. IN AAAA
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+c.example. IN NS
+SECTION ANSWER
+c.example. NS ns1.c.example.
+c.example. NS ns2.c.example.
+SECTION ADDITIONAL
+ns1.c.example. A 192.0.2.7
+ns2.c.example. A 192.0.2.8
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+mc.c.example. IN MX
+SECTION ANSWER
+mc.c.example. IN MX 50 mx.c.example.
+SECTION AUTHORITY
+c.example. NS ns1.c.example.
+c.example. NS ns2.c.example.
+SECTION ADDITIONAL
+ns1.c.example. A 192.0.2.7
+ns2.c.example. A 192.0.2.8
+ENTRY_END
+RANGE_END
+
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+mc.c.example. IN MX
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA SERVFAIL
+SECTION QUESTION
+mc.c.example. IN MX
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/val_nsec3_b3_optout_nonc.rpl b/tests/integration/deckard/sets/resolver/val_nsec3_b3_optout_nonc.rpl
new file mode 100644
index 0000000..271ceb1
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_nsec3_b3_optout_nonc.rpl
@@ -0,0 +1,258 @@
+do-ip6: no
+
+; config options
+;server:
+ trust-anchor: "example. DNSKEY 257 3 7 AwEAAcUlFV1vhmqx6NSOUOq2R/dsR7Xm3upJ ( j7IommWSpJABVfW8Q0rOvXdM6kzt+TAu92L9 AbsUdblMFin8CVF3n4s= )"
+ val-override-date: "20120420235959"
+; target-fetch-policy: "0 0 0 0 0"
+; fake-sha1: yes
+
+;stub-zone:
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+;test from testbound
+
+SCENARIO_BEGIN Test validator NSEC3 B.3 optout unsigned, without nc.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example. IN A
+SECTION AUTHORITY
+example. IN NS ns1.example.
+; leave out to make unbound take ns1
+;example. IN NS ns2.example.
+SECTION ADDITIONAL
+ns1.example. IN A 192.0.2.1
+; leave out to make unbound take ns1
+;ns2.example. IN A 192.0.2.2
+ENTRY_END
+RANGE_END
+
+; ns1.example.
+RANGE_BEGIN 0 100
+ ADDRESS 192.0.2.1
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id copy_query
+REPLY QR REFUSED
+SECTION QUESTION
+ns1.example. IN A
+SECTION ANSWER
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id copy_query
+REPLY QR REFUSED
+SECTION QUESTION
+ns1.example. IN AAAA
+SECTION ANSWER
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id copy_query
+REPLY QR REFUSED
+SECTION QUESTION
+example. IN NS
+SECTION ANSWER
+ENTRY_END
+
+; response to DNSKEY priming query
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example. IN DNSKEY
+SECTION ANSWER
+example. DNSKEY 256 3 7 AwEAAaetidLzsKWUt4swWR8yu0wPHPiUi8LU ( sAD0QPWU+wzt89epO6tHzkMBVDkC7qphQO2h TY4hHn9npWFRw5BYubE= )
+example. DNSKEY 257 3 7 AwEAAcUlFV1vhmqx6NSOUOq2R/dsR7Xm3upJ ( j7IommWSpJABVfW8Q0rOvXdM6kzt+TAu92L9 AbsUdblMFin8CVF3n4s= )
+example. RRSIG DNSKEY 7 1 3600 20150420235959 ( 20051021000000 12708 example. AuU4juU9RaxescSmStrQks3Gh9FblGBlVU31 uzMZ/U/FpsUb8aC6QZS+sTsJXnLnz7flGOsm MGQZf3bH+QsCtg== )
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA DO NOERROR
+SECTION QUESTION
+c.example. IN DS
+SECTION AUTHORITY
+;; NSEC3 RR that covers the "next closer" name (c.example)
+;; H(c.example) = 4g6p9u5gvfshp30pqecj98b3maqbn1ck
+;35mthgpgcu1qg68fab165klnsnk3dpvl.example. NSEC3 1 1 12 aabbccdd ( b4um86eghhds6nea196smvmlo4ors995 NS DS RRSIG )
+;35mthgpgcu1qg68fab165klnsnk3dpvl.example. RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 ( 40430 example. g6jPUUpduAJKRljUsN8gB4UagAX0NxY9shwQ Aynzo8EUWH+z6hEIBlUTPGj15eZll6VhQqgZ XtAIR3chwgW+SA== )
+
+;; NSEC3 RR that matches the closest encloser (example)
+;; H(example) = 0p9mhaveqvm6t7vbl5lop2u3t2rp3tom
+0p9mhaveqvm6t7vbl5lop2u3t2rp3tom.example. NSEC3 1 1 12 aabbccdd ( 2t7b4g4vsa5smi47k61mv5bv1a22bojr MX DNSKEY NS SOA NSEC3PARAM RRSIG )
+0p9mhaveqvm6t7vbl5lop2u3t2rp3tom.example. RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 ( 40430 example. OSgWSm26B+cS+dDL8b5QrWr/dEWhtCsKlwKL IBHYH6blRxK9rC0bMJPwQ4mLIuw85H2EY762 BOCXJZMnpuwhpA== )
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR AA DO NOERROR
+SECTION QUESTION
+c.example. IN MX
+SECTION AUTHORITY
+c.example. NS ns1.c.example.
+c.example. NS ns2.c.example.
+
+;; NSEC3 RR that covers the "next closer" name (c.example)
+;; H(c.example) = 4g6p9u5gvfshp30pqecj98b3maqbn1ck
+; 35mthgpgcu1qg68fab165klnsnk3dpvl.example. NSEC3 1 1 12 aabbccdd ( b4um86eghhds6nea196smvmlo4ors995 NS DS RRSIG )
+; 35mthgpgcu1qg68fab165klnsnk3dpvl.example. RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 ( 40430 example. g6jPUUpduAJKRljUsN8gB4UagAX0NxY9shwQ Aynzo8EUWH+z6hEIBlUTPGj15eZll6VhQqgZ XtAIR3chwgW+SA== )
+
+;; NSEC3 RR that matches the closest encloser (example)
+;; H(example) = 0p9mhaveqvm6t7vbl5lop2u3t2rp3tom
+0p9mhaveqvm6t7vbl5lop2u3t2rp3tom.example. NSEC3 1 1 12 aabbccdd ( 2t7b4g4vsa5smi47k61mv5bv1a22bojr MX DNSKEY NS SOA NSEC3PARAM RRSIG )
+0p9mhaveqvm6t7vbl5lop2u3t2rp3tom.example. RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 ( 40430 example. OSgWSm26B+cS+dDL8b5QrWr/dEWhtCsKlwKL IBHYH6blRxK9rC0bMJPwQ4mLIuw85H2EY762 BOCXJZMnpuwhpA== )
+
+SECTION ADDITIONAL
+ns1.c.example. A 192.0.2.7
+ns2.c.example. A 192.0.2.8
+
+ENTRY_END
+
+RANGE_END
+
+; ns1.c.example.
+RANGE_BEGIN 0 100
+ ADDRESS 192.0.2.7
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA REFUSED
+SECTION QUESTION
+ns1.c.example. IN AAAA
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA REFUSED
+SECTION QUESTION
+ns2.c.example. IN AAAA
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+c.example. IN NS
+SECTION ANSWER
+c.example. NS ns1.c.example.
+c.example. NS ns2.c.example.
+SECTION ADDITIONAL
+ns1.c.example. A 192.0.2.7
+ns2.c.example. A 192.0.2.8
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+mc.c.example. IN MX
+SECTION ANSWER
+mc.c.example. IN MX 50 mx.c.example.
+SECTION AUTHORITY
+c.example. NS ns1.c.example.
+c.example. NS ns2.c.example.
+SECTION ADDITIONAL
+ns1.c.example. A 192.0.2.7
+ns2.c.example. A 192.0.2.8
+ENTRY_END
+RANGE_END
+
+; ns2.c.example.
+RANGE_BEGIN 0 100
+ ADDRESS 192.0.2.8
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA REFUSED
+SECTION QUESTION
+ns1.c.example. IN AAAA
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA REFUSED
+SECTION QUESTION
+ns2.c.example. IN AAAA
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+c.example. IN NS
+SECTION ANSWER
+c.example. NS ns1.c.example.
+c.example. NS ns2.c.example.
+SECTION ADDITIONAL
+ns1.c.example. A 192.0.2.7
+ns2.c.example. A 192.0.2.8
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+mc.c.example. IN MX
+SECTION ANSWER
+mc.c.example. IN MX 50 mx.c.example.
+SECTION AUTHORITY
+c.example. NS ns1.c.example.
+c.example. NS ns2.c.example.
+SECTION ADDITIONAL
+ns1.c.example. A 192.0.2.7
+ns2.c.example. A 192.0.2.8
+ENTRY_END
+RANGE_END
+
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+mc.c.example. IN MX
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA SERVFAIL
+SECTION QUESTION
+mc.c.example. IN MX
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/val_nsec3_b4_wild.rpl b/tests/integration/deckard/sets/resolver/val_nsec3_b4_wild.rpl
new file mode 100644
index 0000000..e471dfb
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_nsec3_b4_wild.rpl
@@ -0,0 +1,176 @@
+do-ip6: no
+
+; config options
+;server:
+ trust-anchor: "example. DNSKEY 257 3 7 AwEAAcUlFV1vhmqx6NSOUOq2R/dsR7Xm3upJ ( j7IommWSpJABVfW8Q0rOvXdM6kzt+TAu92L9 AbsUdblMFin8CVF3n4s= )"
+ val-override-date: "20120420235959"
+; target-fetch-policy: "0 0 0 0 0"
+ query-minimization: off
+
+;stub-zone:
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test validator NSEC3 B.4 wildcard expansion.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+. IN A
+SECTION AUTHORITY
+example. IN NS ns1.example.
+; leave out to make unbound take ns1
+;example. IN NS ns2.example.
+SECTION ADDITIONAL
+ns1.example. IN A 192.0.2.1
+; leave out to make unbound take ns1
+;ns2.example. IN A 192.0.2.2
+ENTRY_END
+RANGE_END
+
+; ns1.example.
+RANGE_BEGIN 0 100
+ ADDRESS 192.0.2.1
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id copy_query
+REPLY QR REFUSED
+SECTION QUESTION
+example. IN NS
+SECTION ANSWER
+ENTRY_END
+
+; response to DNSKEY priming query
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example. IN DNSKEY
+SECTION ANSWER
+example. DNSKEY 256 3 7 AwEAAaetidLzsKWUt4swWR8yu0wPHPiUi8LU ( sAD0QPWU+wzt89epO6tHzkMBVDkC7qphQO2h TY4hHn9npWFRw5BYubE= )
+example. DNSKEY 257 3 7 AwEAAcUlFV1vhmqx6NSOUOq2R/dsR7Xm3upJ ( j7IommWSpJABVfW8Q0rOvXdM6kzt+TAu92L9 AbsUdblMFin8CVF3n4s= )
+example. RRSIG DNSKEY 7 1 3600 20150420235959 ( 20051021000000 12708 example. AuU4juU9RaxescSmStrQks3Gh9FblGBlVU31 uzMZ/U/FpsUb8aC6QZS+sTsJXnLnz7flGOsm MGQZf3bH+QsCtg== )
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA DO NOERROR
+SECTION QUESTION
+a.z.w.example. IN MX
+SECTION ANSWER
+a.z.w.example. MX 1 ai.example.
+a.z.w.example. RRSIG MX 7 2 3600 20150420235959 20051021000000 ( 40430 example. CikebjQwGQPwijVcxgcZcSJKtfynugtlBiKb 9FcBTrmOoyQ4InoWVudhCWsh/URX3lc4WRUM ivEBP6+4KS3ldA== )
+SECTION AUTHORITY
+;; NSEC3 RR that covers the "next closer" name (z.w.example)
+;; H(z.w.example) = qlu7gtfaeh0ek0c05ksfhdpbcgglbe03
+q04jkcevqvmu85r014c7dkba38o0ji5r.example. NSEC3 1 1 12 aabbccdd ( r53bq7cc2uvmubfu5ocmm6pers9tk9en A RRSIG )
+q04jkcevqvmu85r014c7dkba38o0ji5r.example. RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 ( 40430 example. hV5I89b+4FHJDATp09g4bbN0R1F845CaXpL3 ZxlMKimoPAyqletMlEWwLfFia7sdpSzn+ZlN NlkxWcLsIlMmUg== )
+
+SECTION ADDITIONAL
+ai.example. A 192.0.2.9
+ai.example. RRSIG A 7 2 3600 20150420235959 20051021000000 ( 40430 example. hVe+wKYMlObTRPhX0NL67GxeZfdxqr/QeR6F tfdAj5+FgYxyzPEjIzvKWy00hWIl6wD3Vws+ rznEn8sQ64UdqA== )
+ai.example. AAAA 2001:db8:0:0:0:0:f00:baa9
+ai.example. RRSIG AAAA 7 2 3600 20150420235959 20051021000000 ( 40430 example. LcdxKaCB5bGZwPDg+3JJ4O02zoMBrjxqlf6W uaHQZZfTUpb9Nf2nxFGe2XRPfR5tpJT6GdRG cHueLuXkMjBArQ== )
+ENTRY_END
+
+; catch glue queries
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA DO NOERROR
+SECTION QUESTION
+ns2.example. IN A
+SECTION ANSWER
+; nothing to make sure the ns1 server is used for queries.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA DO NOERROR
+SECTION QUESTION
+ns2.example. IN AAAA
+SECTION ANSWER
+; nothing to make sure the ns1 server is used for queries.
+ENTRY_END
+
+
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+a.z.w.example. IN MX
+ENTRY_END
+
+; recursion happens here.
+; answer has no AD since NSEC3 has optout
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH opcode qname flags rcode question answer
+REPLY QR RD RA DO NOERROR
+SECTION QUESTION
+a.z.w.example. IN MX
+SECTION ANSWER
+a.z.w.example. MX 1 ai.example.
+a.z.w.example. RRSIG MX 7 2 3600 20150420235959 20051021000000 ( 40430 example. CikebjQwGQPwijVcxgcZcSJKtfynugtlBiKb 9FcBTrmOoyQ4InoWVudhCWsh/URX3lc4WRUM ivEBP6+4KS3ldA== )
+; SECTION AUTHORITY
+; q04jkcevqvmu85r014c7dkba38o0ji5r.example. NSEC3 1 1 12 aabbccdd ( r53bq7cc2uvmubfu5ocmm6pers9tk9en A RRSIG )
+; q04jkcevqvmu85r014c7dkba38o0ji5r.example. RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 ( 40430 example. hV5I89b+4FHJDATp09g4bbN0R1F845CaXpL3 ZxlMKimoPAyqletMlEWwLfFia7sdpSzn+ZlN NlkxWcLsIlMmUg== )
+; SECTION ADDITIONAL
+; ai.example. A 192.0.2.9
+; ai.example. RRSIG A 7 2 3600 20150420235959 20051021000000 ( 40430 example. hVe+wKYMlObTRPhX0NL67GxeZfdxqr/QeR6F tfdAj5+FgYxyzPEjIzvKWy00hWIl6wD3Vws+ rznEn8sQ64UdqA== )
+; ai.example. AAAA 2001:db8:0:0:0:0:f00:baa9
+; ai.example. RRSIG AAAA 7 2 3600 20150420235959 20051021000000 ( 40430 example. LcdxKaCB5bGZwPDg+3JJ4O02zoMBrjxqlf6W uaHQZZfTUpb9Nf2nxFGe2XRPfR5tpJT6GdRG cHueLuXkMjBArQ== )
+ENTRY_END
+
+; check for cached answer
+STEP 20 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+a.z.w.example. IN MX
+ENTRY_END
+
+STEP 30 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH opcode qname flags rcode question answer
+REPLY QR RD RA DO NOERROR
+SECTION QUESTION
+a.z.w.example. IN MX
+SECTION ANSWER
+a.z.w.example. MX 1 ai.example.
+a.z.w.example. RRSIG MX 7 2 3600 20150420235959 20051021000000 ( 40430 example. CikebjQwGQPwijVcxgcZcSJKtfynugtlBiKb 9FcBTrmOoyQ4InoWVudhCWsh/URX3lc4WRUM ivEBP6+4KS3ldA== )
+; SECTION AUTHORITY
+; q04jkcevqvmu85r014c7dkba38o0ji5r.example. NSEC3 1 1 12 aabbccdd ( r53bq7cc2uvmubfu5ocmm6pers9tk9en A RRSIG )
+; q04jkcevqvmu85r014c7dkba38o0ji5r.example. RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 ( 40430 example. hV5I89b+4FHJDATp09g4bbN0R1F845CaXpL3 ZxlMKimoPAyqletMlEWwLfFia7sdpSzn+ZlN NlkxWcLsIlMmUg== )
+; SECTION ADDITIONAL
+; ai.example. A 192.0.2.9
+; ai.example. RRSIG A 7 2 3600 20150420235959 20051021000000 ( 40430 example. hVe+wKYMlObTRPhX0NL67GxeZfdxqr/QeR6F tfdAj5+FgYxyzPEjIzvKWy00hWIl6wD3Vws+ rznEn8sQ64UdqA== )
+; ai.example. AAAA 2001:db8:0:0:0:0:f00:baa9
+; ai.example. RRSIG AAAA 7 2 3600 20150420235959 20051021000000 ( 40430 example. LcdxKaCB5bGZwPDg+3JJ4O02zoMBrjxqlf6W uaHQZZfTUpb9Nf2nxFGe2XRPfR5tpJT6GdRG cHueLuXkMjBArQ== )
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/val_nsec3_b5_wcnodata.rpl b/tests/integration/deckard/sets/resolver/val_nsec3_b5_wcnodata.rpl
new file mode 100644
index 0000000..149a29f
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_nsec3_b5_wcnodata.rpl
@@ -0,0 +1,157 @@
+do-ip6: no
+
+; config options
+;server:
+ trust-anchor: "example. DNSKEY 257 3 7 AwEAAcUlFV1vhmqx6NSOUOq2R/dsR7Xm3upJ ( j7IommWSpJABVfW8Q0rOvXdM6kzt+TAu92L9 AbsUdblMFin8CVF3n4s= )"
+ val-override-date: "20120420235959"
+; target-fetch-policy: "0 0 0 0 0"
+ query-minimization: off
+
+;stub-zone:
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test validator NSEC3 B.5 wildcard nodata.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+. IN A
+SECTION AUTHORITY
+example. IN NS ns1.example.
+; leave out to make unbound take ns1
+;example. IN NS ns2.example.
+SECTION ADDITIONAL
+ns1.example. IN A 192.0.2.1
+; leave out to make unbound take ns1
+;ns2.example. IN A 192.0.2.2
+ENTRY_END
+RANGE_END
+
+; ns1.example.
+RANGE_BEGIN 0 100
+ ADDRESS 192.0.2.1
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id copy_query
+REPLY QR REFUSED
+SECTION QUESTION
+example. IN NS
+SECTION ANSWER
+ENTRY_END
+
+; response to DNSKEY priming query
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example. IN DNSKEY
+SECTION ANSWER
+example. DNSKEY 256 3 7 AwEAAaetidLzsKWUt4swWR8yu0wPHPiUi8LU ( sAD0QPWU+wzt89epO6tHzkMBVDkC7qphQO2h TY4hHn9npWFRw5BYubE= )
+example. DNSKEY 257 3 7 AwEAAcUlFV1vhmqx6NSOUOq2R/dsR7Xm3upJ ( j7IommWSpJABVfW8Q0rOvXdM6kzt+TAu92L9 AbsUdblMFin8CVF3n4s= )
+example. RRSIG DNSKEY 7 1 3600 20150420235959 ( 20051021000000 12708 example. AuU4juU9RaxescSmStrQks3Gh9FblGBlVU31 uzMZ/U/FpsUb8aC6QZS+sTsJXnLnz7flGOsm MGQZf3bH+QsCtg== )
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA DO NOERROR
+SECTION QUESTION
+a.z.w.example. IN AAAA
+SECTION ANSWER
+SECTION AUTHORITY
+example. SOA ns1.example. bugs.x.w.example. 1 3600 300 ( 3600000 3600 )
+example. RRSIG SOA 7 1 3600 20150420235959 20051021000000 ( 40430 example. Hu25UIyNPmvPIVBrldN+9Mlp9Zql39qaUd8i q4ZLlYWfUUbbAS41pG+68z81q1xhkYAcEyHd VI2LmKusbZsT0Q== )
+
+;; NSEC3 RR that matches the closest encloser (w.example)
+;; H(w.example) = k8udemvp1j2f7eg6jebps17vp3n8i58h
+k8udemvp1j2f7eg6jebps17vp3n8i58h.example. NSEC3 1 1 12 aabbccdd ( kohar7mbb8dc2ce8a9qvl8hon4k53uhi )
+k8udemvp1j2f7eg6jebps17vp3n8i58h.example. RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 ( 40430 example. FtXGbvF0+wf8iWkyo73enAuVx03klN+pILBK S6qCcftVtfH4yVzsEZquJ27NHR7ruxJWDNMt Otx7w9WfcIg62A== )
+
+;; NSEC3 RR that covers the "next closer" name (z.w.example)
+;; H(z.w.example) = qlu7gtfaeh0ek0c05ksfhdpbcgglbe03
+q04jkcevqvmu85r014c7dkba38o0ji5r.example. NSEC3 1 1 12 aabbccdd ( r53bq7cc2uvmubfu5ocmm6pers9tk9en A RRSIG )
+q04jkcevqvmu85r014c7dkba38o0ji5r.example. RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 ( 40430 example. hV5I89b+4FHJDATp09g4bbN0R1F845CaXpL3 ZxlMKimoPAyqletMlEWwLfFia7sdpSzn+ZlN NlkxWcLsIlMmUg== )
+
+;; NSEC3 RR that matches a wildcard at the closest encloser.
+;; H(*.w.example) = r53bq7cc2uvmubfu5ocmm6pers9tk9en
+r53bq7cc2uvmubfu5ocmm6pers9tk9en.example. NSEC3 1 1 12 aabbccdd ( t644ebqk9bibcna874givr6joj62mlhv MX RRSIG )
+r53bq7cc2uvmubfu5ocmm6pers9tk9en.example. RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 ( 40430 example. aupviViruXs4bDg9rCbezzBMf9h1ZlDvbW/C ZFKulIGXXLj8B/fsDJarXVDA9bnUoRhEbKp+ HF1FWKW7RIJdtQ== )
+
+SECTION ADDITIONAL
+ENTRY_END
+
+; catch glue queries
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA DO NOERROR
+SECTION QUESTION
+ns2.example. IN A
+SECTION ANSWER
+; nothing to make sure the ns1 server is used for queries.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA DO NOERROR
+SECTION QUESTION
+ns2.example. IN AAAA
+SECTION ANSWER
+; nothing to make sure the ns1 server is used for queries.
+ENTRY_END
+
+
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+a.z.w.example. IN AAAA
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+; AD is missed due to optout
+REPLY QR RD RA DO NOERROR
+SECTION QUESTION
+a.z.w.example. IN AAAA
+SECTION ANSWER
+SECTION AUTHORITY
+example. SOA ns1.example. bugs.x.w.example. 1 3600 300 ( 3600000 3600 )
+example. RRSIG SOA 7 1 3600 20150420235959 20051021000000 ( 40430 example. Hu25UIyNPmvPIVBrldN+9Mlp9Zql39qaUd8i q4ZLlYWfUUbbAS41pG+68z81q1xhkYAcEyHd VI2LmKusbZsT0Q== )
+k8udemvp1j2f7eg6jebps17vp3n8i58h.example. NSEC3 1 1 12 aabbccdd ( kohar7mbb8dc2ce8a9qvl8hon4k53uhi )
+k8udemvp1j2f7eg6jebps17vp3n8i58h.example. RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 ( 40430 example. FtXGbvF0+wf8iWkyo73enAuVx03klN+pILBK S6qCcftVtfH4yVzsEZquJ27NHR7ruxJWDNMt Otx7w9WfcIg62A== )
+q04jkcevqvmu85r014c7dkba38o0ji5r.example. NSEC3 1 1 12 aabbccdd ( r53bq7cc2uvmubfu5ocmm6pers9tk9en A RRSIG )
+q04jkcevqvmu85r014c7dkba38o0ji5r.example. RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 ( 40430 example. hV5I89b+4FHJDATp09g4bbN0R1F845CaXpL3 ZxlMKimoPAyqletMlEWwLfFia7sdpSzn+ZlN NlkxWcLsIlMmUg== )
+r53bq7cc2uvmubfu5ocmm6pers9tk9en.example. NSEC3 1 1 12 aabbccdd ( t644ebqk9bibcna874givr6joj62mlhv MX RRSIG )
+r53bq7cc2uvmubfu5ocmm6pers9tk9en.example. RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 ( 40430 example. aupviViruXs4bDg9rCbezzBMf9h1ZlDvbW/C ZFKulIGXXLj8B/fsDJarXVDA9bnUoRhEbKp+ HF1FWKW7RIJdtQ== )
+
+SECTION ADDITIONAL
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/val_nsec3_b5_wcnodata_noce.rpl b/tests/integration/deckard/sets/resolver/val_nsec3_b5_wcnodata_noce.rpl
new file mode 100644
index 0000000..4bc59cd
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_nsec3_b5_wcnodata_noce.rpl
@@ -0,0 +1,167 @@
+do-ip6: no
+
+; config options
+;server:
+ trust-anchor: "example. DNSKEY 257 3 7 AwEAAcUlFV1vhmqx6NSOUOq2R/dsR7Xm3upJ ( j7IommWSpJABVfW8Q0rOvXdM6kzt+TAu92L9 AbsUdblMFin8CVF3n4s= )"
+ val-override-date: "20120420235959"
+; target-fetch-policy: "0 0 0 0 0"
+ query-minimization: off
+
+;stub-zone:
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test validator NSEC3 B.5 wildcard nodata, without ce.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example. IN A
+SECTION AUTHORITY
+example. IN NS ns1.example.
+; leave out to make unbound take ns1
+;example. IN NS ns2.example.
+SECTION ADDITIONAL
+ns1.example. IN A 192.0.2.1
+; leave out to make unbound take ns1
+;ns2.example. IN A 192.0.2.2
+ENTRY_END
+RANGE_END
+
+; ns1.example.
+RANGE_BEGIN 0 100
+ ADDRESS 192.0.2.1
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id copy_query
+REPLY QR REFUSED
+SECTION QUESTION
+ns1.example. IN A
+SECTION ANSWER
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id copy_query
+REPLY QR REFUSED
+SECTION QUESTION
+ns1.example. IN AAAA
+SECTION ANSWER
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id copy_query
+REPLY QR REFUSED
+SECTION QUESTION
+example. IN NS
+SECTION ANSWER
+ENTRY_END
+
+; response to DNSKEY priming query
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example. IN DNSKEY
+SECTION ANSWER
+example. DNSKEY 256 3 7 AwEAAaetidLzsKWUt4swWR8yu0wPHPiUi8LU ( sAD0QPWU+wzt89epO6tHzkMBVDkC7qphQO2h TY4hHn9npWFRw5BYubE= )
+example. DNSKEY 257 3 7 AwEAAcUlFV1vhmqx6NSOUOq2R/dsR7Xm3upJ ( j7IommWSpJABVfW8Q0rOvXdM6kzt+TAu92L9 AbsUdblMFin8CVF3n4s= )
+example. RRSIG DNSKEY 7 1 3600 20150420235959 ( 20051021000000 12708 example. AuU4juU9RaxescSmStrQks3Gh9FblGBlVU31 uzMZ/U/FpsUb8aC6QZS+sTsJXnLnz7flGOsm MGQZf3bH+QsCtg== )
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA DO NOERROR
+SECTION QUESTION
+a.z.w.example. IN AAAA
+SECTION ANSWER
+SECTION AUTHORITY
+example. SOA ns1.example. bugs.x.w.example. 1 3600 300 ( 3600000 3600 )
+example. RRSIG SOA 7 1 3600 20150420235959 20051021000000 ( 40430 example. Hu25UIyNPmvPIVBrldN+9Mlp9Zql39qaUd8i q4ZLlYWfUUbbAS41pG+68z81q1xhkYAcEyHd VI2LmKusbZsT0Q== )
+
+;; NSEC3 RR that matches the closest encloser (w.example)
+;; H(w.example) = k8udemvp1j2f7eg6jebps17vp3n8i58h
+;k8udemvp1j2f7eg6jebps17vp3n8i58h.example. NSEC3 1 1 12 aabbccdd ( kohar7mbb8dc2ce8a9qvl8hon4k53uhi )
+;k8udemvp1j2f7eg6jebps17vp3n8i58h.example. RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 ( 40430 example. FtXGbvF0+wf8iWkyo73enAuVx03klN+pILBK S6qCcftVtfH4yVzsEZquJ27NHR7ruxJWDNMt Otx7w9WfcIg62A== )
+
+;; NSEC3 RR that covers the "next closer" name (z.w.example)
+;; H(z.w.example) = qlu7gtfaeh0ek0c05ksfhdpbcgglbe03
+q04jkcevqvmu85r014c7dkba38o0ji5r.example. NSEC3 1 1 12 aabbccdd ( r53bq7cc2uvmubfu5ocmm6pers9tk9en A RRSIG )
+q04jkcevqvmu85r014c7dkba38o0ji5r.example. RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 ( 40430 example. hV5I89b+4FHJDATp09g4bbN0R1F845CaXpL3 ZxlMKimoPAyqletMlEWwLfFia7sdpSzn+ZlN NlkxWcLsIlMmUg== )
+
+;; NSEC3 RR that matches a wildcard at the closest encloser.
+;; H(*.w.example) = r53bq7cc2uvmubfu5ocmm6pers9tk9en
+r53bq7cc2uvmubfu5ocmm6pers9tk9en.example. NSEC3 1 1 12 aabbccdd ( t644ebqk9bibcna874givr6joj62mlhv MX RRSIG )
+r53bq7cc2uvmubfu5ocmm6pers9tk9en.example. RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 ( 40430 example. aupviViruXs4bDg9rCbezzBMf9h1ZlDvbW/C ZFKulIGXXLj8B/fsDJarXVDA9bnUoRhEbKp+ HF1FWKW7RIJdtQ== )
+
+SECTION ADDITIONAL
+ENTRY_END
+
+; catch glue queries
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA DO NOERROR
+SECTION QUESTION
+ns2.example. IN A
+SECTION ANSWER
+; nothing to make sure the ns1 server is used for queries.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA DO NOERROR
+SECTION QUESTION
+ns2.example. IN AAAA
+SECTION ANSWER
+; nothing to make sure the ns1 server is used for queries.
+ENTRY_END
+
+
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+a.z.w.example. IN AAAA
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+;MATCH all
+;do not compare authority
+MATCH opcode qname flags rcode question answer additional
+REPLY QR RD RA SERVFAIL
+SECTION QUESTION
+a.z.w.example. IN AAAA
+SECTION ANSWER
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/val_nsec3_b5_wcnodata_nonc.rpl b/tests/integration/deckard/sets/resolver/val_nsec3_b5_wcnodata_nonc.rpl
new file mode 100644
index 0000000..e82c961
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_nsec3_b5_wcnodata_nonc.rpl
@@ -0,0 +1,167 @@
+do-ip6: no
+
+; config options
+;server:
+ trust-anchor: "example. DNSKEY 257 3 7 AwEAAcUlFV1vhmqx6NSOUOq2R/dsR7Xm3upJ ( j7IommWSpJABVfW8Q0rOvXdM6kzt+TAu92L9 AbsUdblMFin8CVF3n4s= )"
+ val-override-date: "20120420235959"
+; target-fetch-policy: "0 0 0 0 0"
+ query-minimization: off
+
+;stub-zone:
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test validator NSEC3 B.5 wildcard nodata, without nc.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example. IN A
+SECTION AUTHORITY
+example. IN NS ns1.example.
+; leave out to make unbound take ns1
+;example. IN NS ns2.example.
+SECTION ADDITIONAL
+ns1.example. IN A 192.0.2.1
+; leave out to make unbound take ns1
+;ns2.example. IN A 192.0.2.2
+ENTRY_END
+RANGE_END
+
+; ns1.example.
+RANGE_BEGIN 0 100
+ ADDRESS 192.0.2.1
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id copy_query
+REPLY QR REFUSED
+SECTION QUESTION
+ns1.example. IN A
+SECTION ANSWER
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id copy_query
+REPLY QR REFUSED
+SECTION QUESTION
+ns1.example. IN AAAA
+SECTION ANSWER
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id copy_query
+REPLY QR REFUSED
+SECTION QUESTION
+example. IN NS
+SECTION ANSWER
+ENTRY_END
+
+; response to DNSKEY priming query
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example. IN DNSKEY
+SECTION ANSWER
+example. DNSKEY 256 3 7 AwEAAaetidLzsKWUt4swWR8yu0wPHPiUi8LU ( sAD0QPWU+wzt89epO6tHzkMBVDkC7qphQO2h TY4hHn9npWFRw5BYubE= )
+example. DNSKEY 257 3 7 AwEAAcUlFV1vhmqx6NSOUOq2R/dsR7Xm3upJ ( j7IommWSpJABVfW8Q0rOvXdM6kzt+TAu92L9 AbsUdblMFin8CVF3n4s= )
+example. RRSIG DNSKEY 7 1 3600 20150420235959 ( 20051021000000 12708 example. AuU4juU9RaxescSmStrQks3Gh9FblGBlVU31 uzMZ/U/FpsUb8aC6QZS+sTsJXnLnz7flGOsm MGQZf3bH+QsCtg== )
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA DO NOERROR
+SECTION QUESTION
+a.z.w.example. IN AAAA
+SECTION ANSWER
+SECTION AUTHORITY
+example. SOA ns1.example. bugs.x.w.example. 1 3600 300 ( 3600000 3600 )
+example. RRSIG SOA 7 1 3600 20150420235959 20051021000000 ( 40430 example. Hu25UIyNPmvPIVBrldN+9Mlp9Zql39qaUd8i q4ZLlYWfUUbbAS41pG+68z81q1xhkYAcEyHd VI2LmKusbZsT0Q== )
+
+;; NSEC3 RR that matches the closest encloser (w.example)
+;; H(w.example) = k8udemvp1j2f7eg6jebps17vp3n8i58h
+k8udemvp1j2f7eg6jebps17vp3n8i58h.example. NSEC3 1 1 12 aabbccdd ( kohar7mbb8dc2ce8a9qvl8hon4k53uhi )
+k8udemvp1j2f7eg6jebps17vp3n8i58h.example. RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 ( 40430 example. FtXGbvF0+wf8iWkyo73enAuVx03klN+pILBK S6qCcftVtfH4yVzsEZquJ27NHR7ruxJWDNMt Otx7w9WfcIg62A== )
+
+;; NSEC3 RR that covers the "next closer" name (z.w.example)
+;; H(z.w.example) = qlu7gtfaeh0ek0c05ksfhdpbcgglbe03
+;q04jkcevqvmu85r014c7dkba38o0ji5r.example. NSEC3 1 1 12 aabbccdd ( r53bq7cc2uvmubfu5ocmm6pers9tk9en A RRSIG )
+;q04jkcevqvmu85r014c7dkba38o0ji5r.example. RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 ( 40430 example. hV5I89b+4FHJDATp09g4bbN0R1F845CaXpL3 ZxlMKimoPAyqletMlEWwLfFia7sdpSzn+ZlN NlkxWcLsIlMmUg== )
+
+;; NSEC3 RR that matches a wildcard at the closest encloser.
+;; H(*.w.example) = r53bq7cc2uvmubfu5ocmm6pers9tk9en
+r53bq7cc2uvmubfu5ocmm6pers9tk9en.example. NSEC3 1 1 12 aabbccdd ( t644ebqk9bibcna874givr6joj62mlhv MX RRSIG )
+r53bq7cc2uvmubfu5ocmm6pers9tk9en.example. RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 ( 40430 example. aupviViruXs4bDg9rCbezzBMf9h1ZlDvbW/C ZFKulIGXXLj8B/fsDJarXVDA9bnUoRhEbKp+ HF1FWKW7RIJdtQ== )
+
+SECTION ADDITIONAL
+ENTRY_END
+
+; catch glue queries
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA DO NOERROR
+SECTION QUESTION
+ns2.example. IN A
+SECTION ANSWER
+; nothing to make sure the ns1 server is used for queries.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA DO NOERROR
+SECTION QUESTION
+ns2.example. IN AAAA
+SECTION ANSWER
+; nothing to make sure the ns1 server is used for queries.
+ENTRY_END
+
+
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+a.z.w.example. IN AAAA
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+;MATCH all
+;do not compare authority
+MATCH opcode qname flags rcode question answer additional
+REPLY QR RD RA SERVFAIL
+SECTION QUESTION
+a.z.w.example. IN AAAA
+SECTION ANSWER
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/val_nsec3_b5_wcnodata_nowc.rpl b/tests/integration/deckard/sets/resolver/val_nsec3_b5_wcnodata_nowc.rpl
new file mode 100644
index 0000000..5b235e7
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_nsec3_b5_wcnodata_nowc.rpl
@@ -0,0 +1,167 @@
+do-ip6: no
+
+; config options
+;server:
+ trust-anchor: "example. DNSKEY 257 3 7 AwEAAcUlFV1vhmqx6NSOUOq2R/dsR7Xm3upJ ( j7IommWSpJABVfW8Q0rOvXdM6kzt+TAu92L9 AbsUdblMFin8CVF3n4s= )"
+ val-override-date: "20120420235959"
+; target-fetch-policy: "0 0 0 0 0"
+ query-minimization: off
+
+;stub-zone:
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test validator NSEC3 B.5 wildcard nodata, without wc.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example. IN A
+SECTION AUTHORITY
+example. IN NS ns1.example.
+; leave out to make unbound take ns1
+;example. IN NS ns2.example.
+SECTION ADDITIONAL
+ns1.example. IN A 192.0.2.1
+; leave out to make unbound take ns1
+;ns2.example. IN A 192.0.2.2
+ENTRY_END
+RANGE_END
+
+; ns1.example.
+RANGE_BEGIN 0 100
+ ADDRESS 192.0.2.1
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id copy_query
+REPLY QR REFUSED
+SECTION QUESTION
+ns1.example. IN A
+SECTION ANSWER
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id copy_query
+REPLY QR REFUSED
+SECTION QUESTION
+ns1.example. IN AAAA
+SECTION ANSWER
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id copy_query
+REPLY QR REFUSED
+SECTION QUESTION
+example. IN NS
+SECTION ANSWER
+ENTRY_END
+
+; response to DNSKEY priming query
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example. IN DNSKEY
+SECTION ANSWER
+example. DNSKEY 256 3 7 AwEAAaetidLzsKWUt4swWR8yu0wPHPiUi8LU ( sAD0QPWU+wzt89epO6tHzkMBVDkC7qphQO2h TY4hHn9npWFRw5BYubE= )
+example. DNSKEY 257 3 7 AwEAAcUlFV1vhmqx6NSOUOq2R/dsR7Xm3upJ ( j7IommWSpJABVfW8Q0rOvXdM6kzt+TAu92L9 AbsUdblMFin8CVF3n4s= )
+example. RRSIG DNSKEY 7 1 3600 20150420235959 ( 20051021000000 12708 example. AuU4juU9RaxescSmStrQks3Gh9FblGBlVU31 uzMZ/U/FpsUb8aC6QZS+sTsJXnLnz7flGOsm MGQZf3bH+QsCtg== )
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA DO NOERROR
+SECTION QUESTION
+a.z.w.example. IN AAAA
+SECTION ANSWER
+SECTION AUTHORITY
+example. SOA ns1.example. bugs.x.w.example. 1 3600 300 ( 3600000 3600 )
+example. RRSIG SOA 7 1 3600 20150420235959 20051021000000 ( 40430 example. Hu25UIyNPmvPIVBrldN+9Mlp9Zql39qaUd8i q4ZLlYWfUUbbAS41pG+68z81q1xhkYAcEyHd VI2LmKusbZsT0Q== )
+
+;; NSEC3 RR that matches the closest encloser (w.example)
+;; H(w.example) = k8udemvp1j2f7eg6jebps17vp3n8i58h
+k8udemvp1j2f7eg6jebps17vp3n8i58h.example. NSEC3 1 1 12 aabbccdd ( kohar7mbb8dc2ce8a9qvl8hon4k53uhi )
+k8udemvp1j2f7eg6jebps17vp3n8i58h.example. RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 ( 40430 example. FtXGbvF0+wf8iWkyo73enAuVx03klN+pILBK S6qCcftVtfH4yVzsEZquJ27NHR7ruxJWDNMt Otx7w9WfcIg62A== )
+
+;; NSEC3 RR that covers the "next closer" name (z.w.example)
+;; H(z.w.example) = qlu7gtfaeh0ek0c05ksfhdpbcgglbe03
+q04jkcevqvmu85r014c7dkba38o0ji5r.example. NSEC3 1 1 12 aabbccdd ( r53bq7cc2uvmubfu5ocmm6pers9tk9en A RRSIG )
+q04jkcevqvmu85r014c7dkba38o0ji5r.example. RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 ( 40430 example. hV5I89b+4FHJDATp09g4bbN0R1F845CaXpL3 ZxlMKimoPAyqletMlEWwLfFia7sdpSzn+ZlN NlkxWcLsIlMmUg== )
+
+;; NSEC3 RR that matches a wildcard at the closest encloser.
+;; H(*.w.example) = r53bq7cc2uvmubfu5ocmm6pers9tk9en
+;r53bq7cc2uvmubfu5ocmm6pers9tk9en.example. NSEC3 1 1 12 aabbccdd ( t644ebqk9bibcna874givr6joj62mlhv MX RRSIG )
+;r53bq7cc2uvmubfu5ocmm6pers9tk9en.example. RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 ( 40430 example. aupviViruXs4bDg9rCbezzBMf9h1ZlDvbW/C ZFKulIGXXLj8B/fsDJarXVDA9bnUoRhEbKp+ HF1FWKW7RIJdtQ== )
+
+SECTION ADDITIONAL
+ENTRY_END
+
+; catch glue queries
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA DO NOERROR
+SECTION QUESTION
+ns2.example. IN A
+SECTION ANSWER
+; nothing to make sure the ns1 server is used for queries.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA DO NOERROR
+SECTION QUESTION
+ns2.example. IN AAAA
+SECTION ANSWER
+; nothing to make sure the ns1 server is used for queries.
+ENTRY_END
+
+
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+a.z.w.example. IN AAAA
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+; insecure! not bogus! (due to optout)
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+a.z.w.example. IN AAAA
+SECTION ANSWER
+SECTION AUTHORITY
+example. 3600 IN SOA ns1.example. bugs.x.w.example. 1 3600 300 3600000 3600
+SECTION ADDITIONAL
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/val_nsec3_cnametocnamewctoposwc.rpl b/tests/integration/deckard/sets/resolver/val_nsec3_cnametocnamewctoposwc.rpl
new file mode 100644
index 0000000..0385412
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_nsec3_cnametocnamewctoposwc.rpl
@@ -0,0 +1,244 @@
+do-ip6: no
+
+; config options
+; The island of trust is at example.com
+;server:
+ trust-anchor: "example.com. IN DNSKEY 257 3 8 AwEAAdL6YJdvoKQJEt/SgB6MrbQ2RDwnrcQQb6bDE8FpGgLen6hvF31ntVsZ3RZzhCmwL6lvumOLFIRKaP9ZBEVutT9iMoF2dNRbT0TCUrv6uQNHcuCZ0BJhuDNBU42f3yOnfFv7PKxd0NP+yFHJkvDQAVLMB5GeUQuYnvgQGeZsf/3b"
+ val-override-date: "20121116123249"
+; target-fetch-policy: "0 0 0 0 0"
+ query-minimization: off
+
+;stub-zone:
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test validator with a regular cname to wildcard cname to wildcard response
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+start.example.com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+start.example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. 120 IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. 3600 IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 8 2 3600 20121126123249 20121029123249 64050 example.com. cpLjgKPacNxVIGo59tYMZ98GVYpH28WHRWj3AeIHK0StYFcAlflGLdkae1LEgMwfUmzrayrA5GMe3AH8LyuTgA2Dn1oNFxGfuShQvK2MFQ+LxvQfiuoqlAlL5Aa94IWcSoU/wLrr66I1K8oSB2yK1Tyyv73c2N40D1mBbzIE70U=
+SECTION ADDITIONAL
+ns.example.com. 3600 IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 8 2 3600 20121126123249 20121029123249 64050 example.com. zxGyimwFsd39j8T7jJ+tSAQPwZ7tjk6HHmzosTMCRePM4k4newbLb5HbrpucSiW/plaEZvjRTDTJ6bPkw0msPXjPCI/22Zh236XO5vhGtMOlxDgAEazuhifVF6UsM7GZwONPBCvw705HgWQyCR1YlTK2w9ffH3GopU9f4oP7Pmk=
+ENTRY_END
+
+; response to DNSKEY priming query
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN DNSKEY
+SECTION ANSWER
+example.com. 3600 IN DNSKEY 256 3 8 AwEAAdWzfjQD2bfQuoQGNYuS0ByosBxiTkoKcy9kMoWOQ/jx9rvTRhHImWxTxFtIyZOoRgn6E6mE71e5Y1q1nuyH544Em+4rNRMMW4bzecQmMmPk+B97MqW9aW6e4BwiCTt52IGfL++5GORYcaITw9UOlQLYH1oHHUNUC6ebHENofLTj ;{id = 64050 (zsk), size = 1024b}
+example.com. 3600 IN DNSKEY 257 3 8 AwEAAdL6YJdvoKQJEt/SgB6MrbQ2RDwnrcQQb6bDE8FpGgLen6hvF31ntVsZ3RZzhCmwL6lvumOLFIRKaP9ZBEVutT9iMoF2dNRbT0TCUrv6uQNHcuCZ0BJhuDNBU42f3yOnfFv7PKxd0NP+yFHJkvDQAVLMB5GeUQuYnvgQGeZsf/3b ;{id = 46426 (ksk), size = 1024b}
+example.com. 3600 IN RRSIG DNSKEY 8 2 3600 20121126123249 20121029123249 46426 example.com. pisNb/A40XDEiMpcYtxc+yO6osISyfpqz+0UZ61pd70+TLXMF197zr9SqOVJHyRI6G2lSnFggxYrZDpxLbxOW0RY/KfjD3xlI14M/2DieJ1NdlQuYFGgTwxcoINUJ/wRd4YUxkF4JS0D4NBdQ0yQYR0KqDr84oyhnULEHX6WB7s=
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+; response to query of interest
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+start.example.com. IN A
+SECTION ANSWER
+start.example.com. 3600 IN CNAME x.y.z.wc.example.com.
+start.example.com. 3600 IN RRSIG CNAME 8 3 3600 20121126123316 20121029123316 64050 example.com. LHpx5n++Z0Jgjjalac+e7wdYSbfurqSDpLRAOI1PybTJkwrMvgDKfp0ycT4HwsLVy7spumZ/Ahg/5II9pai7jCiqv1Iyh6fx19ZVeClTFMOLotCK8xMHACYJIY39BhTwD2D3r9BxbK+RopUlXypwV02yzdY2xEnPCBJVDUn5d0g=
+x.y.z.wc.example.com. 3600 IN CNAME x.y.z.end.example.com.
+x.y.z.wc.example.com. 3600 IN RRSIG CNAME 8 3 3600 20121126123316 20121029123316 64050 example.com. BCnT6CIuqvF1U9LfiHIovgvXIVFJsCXqQWmnjHtbFvzUlTlfGj+56YBSOEpyCep4CBJ0CBgZ8gl5kWip8N+sTlveU/UWMv4FAkqLXRYjp4CZegslmJIuXU5uS+Q0GlLbWdSB9ZCZcbbO0qrOtUfrJ2ozcSTCS+D+oIZ+CkwvDlQ=
+x.y.z.end.example.com. 3600 IN A 1.2.3.5
+x.y.z.end.example.com. 3600 IN RRSIG A 8 3 3600 20121126123249 20121029123249 64050 example.com. MyXXd3MvXtEYVNqWDepM3+Ra/j/b63QehzSHXZe5gL954WxW8KGHPYmeWyhDtruThpZS6s6jeARY2xt0lmEDnMgNyPJGA6UWwTIgvGD0u9Qw5kocCq3ZH4cSG4xu4rmZoi+h8OGrHxUb4jIKzipzAQDxhnAcp/wKF7e+p+OE+Fo=
+SECTION AUTHORITY
+; H(z.wc.example.com.) = isn85psesctb6afn2q105mv966tqqepi.
+isjq5aarcp8p5sukc56g961cccjus5u2.example.com. 86400 IN NSEC3 1 0 1 abcd isoaarjsq14bkqaamivn1t1milkv95lc A RRSIG
+isjq5aarcp8p5sukc56g961cccjus5u2.example.com. 86400 IN RRSIG NSEC3 8 3 86400 20121126123259 20121029123259 64050 example.com. Cxwzq1DUQvhkTVHEJHlb92c511Y+uJy/C0yL9br6W/5lB/usuSiK2DjW58ibPh2kLH1P3SpGqd1Y7LigptdXoPBDFakcNcimPWCN93R3J80+vrHHPkPyIsBaywwYI3SNGgfnHfPF+wmH+tZ1vfEHbigOxqPFK+T0ntKq7dkSndg=
+; H(z.end.example.com.) = a62608t4becqb6233m87ar7a3648rj3b.
+a61sejfu6am5a36p628t4s089s309o44.example.com. 86400 IN NSEC3 1 0 1 abcd a64lt5ij9a1up15h5cdsn1u2071901hu A RRSIG
+a61sejfu6am5a36p628t4s089s309o44.example.com. 86400 IN RRSIG NSEC3 8 3 86400 20121126123315 20121029123315 64050 example.com. gfBu4oqo9cVxJbqrw2Ly7mK638kGPOF8l8eh7ovalniwkU3F+PNYJyfSE9yGX8tMGbXrkEW9mAzAh39igr2+Bbzi9WPTRp4RDVM0qw+eyMmQRPWKt7FeanDtP+OcdVp0Hf2aPzsgmgTdS6s0AboUq1rX53H2M6F8xAiwPrBJXDQ=
+example.com. 3600 IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 8 2 3600 20121126123249 20121029123249 64050 example.com. cpLjgKPacNxVIGo59tYMZ98GVYpH28WHRWj3AeIHK0StYFcAlflGLdkae1LEgMwfUmzrayrA5GMe3AH8LyuTgA2Dn1oNFxGfuShQvK2MFQ+LxvQfiuoqlAlL5Aa94IWcSoU/wLrr66I1K8oSB2yK1Tyyv73c2N40D1mBbzIE70U=
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+x.y.z.wc.example.com. IN A
+SECTION ANSWER
+x.y.z.wc.example.com. 3600 IN CNAME x.y.z.end.example.com.
+x.y.z.wc.example.com. 3600 IN RRSIG CNAME 8 3 3600 20121126123316 20121029123316 64050 example.com. BCnT6CIuqvF1U9LfiHIovgvXIVFJsCXqQWmnjHtbFvzUlTlfGj+56YBSOEpyCep4CBJ0CBgZ8gl5kWip8N+sTlveU/UWMv4FAkqLXRYjp4CZegslmJIuXU5uS+Q0GlLbWdSB9ZCZcbbO0qrOtUfrJ2ozcSTCS+D+oIZ+CkwvDlQ=
+x.y.z.end.example.com. 3600 IN A 1.2.3.5
+x.y.z.end.example.com. 3600 IN RRSIG A 8 3 3600 20121126123249 20121029123249 64050 example.com. MyXXd3MvXtEYVNqWDepM3+Ra/j/b63QehzSHXZe5gL954WxW8KGHPYmeWyhDtruThpZS6s6jeARY2xt0lmEDnMgNyPJGA6UWwTIgvGD0u9Qw5kocCq3ZH4cSG4xu4rmZoi+h8OGrHxUb4jIKzipzAQDxhnAcp/wKF7e+p+OE+Fo=
+SECTION AUTHORITY
+isjq5aarcp8p5sukc56g961cccjus5u2.example.com. 86400 IN NSEC3 1 0 1 abcd isoaarjsq14bkqaamivn1t1milkv95lc A RRSIG
+isjq5aarcp8p5sukc56g961cccjus5u2.example.com. 86400 IN RRSIG NSEC3 8 3 86400 20121126123259 20121029123259 64050 example.com. Cxwzq1DUQvhkTVHEJHlb92c511Y+uJy/C0yL9br6W/5lB/usuSiK2DjW58ibPh2kLH1P3SpGqd1Y7LigptdXoPBDFakcNcimPWCN93R3J80+vrHHPkPyIsBaywwYI3SNGgfnHfPF+wmH+tZ1vfEHbigOxqPFK+T0ntKq7dkSndg=
+a61sejfu6am5a36p628t4s089s309o44.example.com. 86400 IN NSEC3 1 0 1 abcd a64lt5ij9a1up15h5cdsn1u2071901hu A RRSIG
+a61sejfu6am5a36p628t4s089s309o44.example.com. 86400 IN RRSIG NSEC3 8 3 86400 20121126123315 20121029123315 64050 example.com. gfBu4oqo9cVxJbqrw2Ly7mK638kGPOF8l8eh7ovalniwkU3F+PNYJyfSE9yGX8tMGbXrkEW9mAzAh39igr2+Bbzi9WPTRp4RDVM0qw+eyMmQRPWKt7FeanDtP+OcdVp0Hf2aPzsgmgTdS6s0AboUq1rX53H2M6F8xAiwPrBJXDQ=
+example.com. 3600 IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 8 2 3600 20121126123249 20121029123249 64050 example.com. cpLjgKPacNxVIGo59tYMZ98GVYpH28WHRWj3AeIHK0StYFcAlflGLdkae1LEgMwfUmzrayrA5GMe3AH8LyuTgA2Dn1oNFxGfuShQvK2MFQ+LxvQfiuoqlAlL5Aa94IWcSoU/wLrr66I1K8oSB2yK1Tyyv73c2N40D1mBbzIE70U=
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+x.y.z.end.example.com. IN A
+SECTION ANSWER
+x.y.z.end.example.com. 3600 IN A 1.2.3.5
+x.y.z.end.example.com. 3600 IN RRSIG A 8 3 3600 20121126123249 20121029123249 64050 example.com. MyXXd3MvXtEYVNqWDepM3+Ra/j/b63QehzSHXZe5gL954WxW8KGHPYmeWyhDtruThpZS6s6jeARY2xt0lmEDnMgNyPJGA6UWwTIgvGD0u9Qw5kocCq3ZH4cSG4xu4rmZoi+h8OGrHxUb4jIKzipzAQDxhnAcp/wKF7e+p+OE+Fo=
+SECTION AUTHORITY
+a61sejfu6am5a36p628t4s089s309o44.example.com. 86400 IN NSEC3 1 0 1 abcd a64lt5ij9a1up15h5cdsn1u2071901hu A RRSIG
+a61sejfu6am5a36p628t4s089s309o44.example.com. 86400 IN RRSIG NSEC3 8 3 86400 20121126123315 20121029123315 64050 example.com. gfBu4oqo9cVxJbqrw2Ly7mK638kGPOF8l8eh7ovalniwkU3F+PNYJyfSE9yGX8tMGbXrkEW9mAzAh39igr2+Bbzi9WPTRp4RDVM0qw+eyMmQRPWKt7FeanDtP+OcdVp0Hf2aPzsgmgTdS6s0AboUq1rX53H2M6F8xAiwPrBJXDQ=
+example.com. 3600 IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 8 2 3600 20121126123249 20121029123249 64050 example.com. cpLjgKPacNxVIGo59tYMZ98GVYpH28WHRWj3AeIHK0StYFcAlflGLdkae1LEgMwfUmzrayrA5GMe3AH8LyuTgA2Dn1oNFxGfuShQvK2MFQ+LxvQfiuoqlAlL5Aa94IWcSoU/wLrr66I1K8oSB2yK1Tyyv73c2N40D1mBbzIE70U=
+SECTION ADDITIONAL
+ns.example.com. 3600 IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 8 2 3600 20121126123249 20121029123249 64050 example.com. zxGyimwFsd39j8T7jJ+tSAQPwZ7tjk6HHmzosTMCRePM4k4newbLb5HbrpucSiW/plaEZvjRTDTJ6bPkw0msPXjPCI/22Zh236XO5vhGtMOlxDgAEazuhifVF6UsM7GZwONPBCvw705HgWQyCR1YlTK2w9ffH3GopU9f4oP7Pmk=
+ENTRY_END
+RANGE_END
+
+
+
+STEP 10 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+start.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 20 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH opcode qname flags rcode question answer authority
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+start.example.com. IN A
+SECTION ANSWER
+start.example.com. 3600 IN CNAME x.y.z.wc.example.com.
+start.example.com. 3600 IN RRSIG CNAME 8 3 3600 20121126123316 20121029123316 64050 example.com. LHpx5n++Z0Jgjjalac+e7wdYSbfurqSDpLRAOI1PybTJkwrMvgDKfp0ycT4HwsLVy7spumZ/Ahg/5II9pai7jCiqv1Iyh6fx19ZVeClTFMOLotCK8xMHACYJIY39BhTwD2D3r9BxbK+RopUlXypwV02yzdY2xEnPCBJVDUn5d0g=
+x.y.z.wc.example.com. 3600 IN CNAME x.y.z.end.example.com.
+x.y.z.wc.example.com. 3600 IN RRSIG CNAME 8 3 3600 20121126123316 20121029123316 64050 example.com. BCnT6CIuqvF1U9LfiHIovgvXIVFJsCXqQWmnjHtbFvzUlTlfGj+56YBSOEpyCep4CBJ0CBgZ8gl5kWip8N+sTlveU/UWMv4FAkqLXRYjp4CZegslmJIuXU5uS+Q0GlLbWdSB9ZCZcbbO0qrOtUfrJ2ozcSTCS+D+oIZ+CkwvDlQ=
+x.y.z.end.example.com. 3600 IN A 1.2.3.5
+x.y.z.end.example.com. 3600 IN RRSIG A 8 3 3600 20121126123249 20121029123249 64050 example.com. MyXXd3MvXtEYVNqWDepM3+Ra/j/b63QehzSHXZe5gL954WxW8KGHPYmeWyhDtruThpZS6s6jeARY2xt0lmEDnMgNyPJGA6UWwTIgvGD0u9Qw5kocCq3ZH4cSG4xu4rmZoi+h8OGrHxUb4jIKzipzAQDxhnAcp/wKF7e+p+OE+Fo=
+SECTION AUTHORITY
+isjq5aarcp8p5sukc56g961cccjus5u2.example.com. 86400 IN NSEC3 1 0 1 abcd isoaarjsq14bkqaamivn1t1milkv95lc A RRSIG
+isjq5aarcp8p5sukc56g961cccjus5u2.example.com. 86400 IN RRSIG NSEC3 8 3 86400 20121126123259 20121029123259 64050 example.com. Cxwzq1DUQvhkTVHEJHlb92c511Y+uJy/C0yL9br6W/5lB/usuSiK2DjW58ibPh2kLH1P3SpGqd1Y7LigptdXoPBDFakcNcimPWCN93R3J80+vrHHPkPyIsBaywwYI3SNGgfnHfPF+wmH+tZ1vfEHbigOxqPFK+T0ntKq7dkSndg=
+a61sejfu6am5a36p628t4s089s309o44.example.com. 86400 IN NSEC3 1 0 1 abcd a64lt5ij9a1up15h5cdsn1u2071901hu A RRSIG
+a61sejfu6am5a36p628t4s089s309o44.example.com. 86400 IN RRSIG NSEC3 8 3 86400 20121126123315 20121029123315 64050 example.com. gfBu4oqo9cVxJbqrw2Ly7mK638kGPOF8l8eh7ovalniwkU3F+PNYJyfSE9yGX8tMGbXrkEW9mAzAh39igr2+Bbzi9WPTRp4RDVM0qw+eyMmQRPWKt7FeanDtP+OcdVp0Hf2aPzsgmgTdS6s0AboUq1rX53H2M6F8xAiwPrBJXDQ=
+;example.com. 3600 IN NS ns.example.com.
+;example.com. 3600 IN RRSIG NS 8 2 3600 20121126123249 20121029123249 64050 example.com. cpLjgKPacNxVIGo59tYMZ98GVYpH28WHRWj3AeIHK0StYFcAlflGLdkae1LEgMwfUmzrayrA5GMe3AH8LyuTgA2Dn1oNFxGfuShQvK2MFQ+LxvQfiuoqlAlL5Aa94IWcSoU/wLrr66I1K8oSB2yK1Tyyv73c2N40D1mBbzIE70U=
+SECTION ADDITIONAL
+;ns.example.com. 3600 IN A 1.2.3.4
+;ns.example.com. 3600 IN RRSIG A 8 2 3600 20121126123249 20121029123249 64050 example.com. zxGyimwFsd39j8T7jJ+tSAQPwZ7tjk6HHmzosTMCRePM4k4newbLb5HbrpucSiW/plaEZvjRTDTJ6bPkw0msPXjPCI/22Zh236XO5vhGtMOlxDgAEazuhifVF6UsM7GZwONPBCvw705HgWQyCR1YlTK2w9ffH3GopU9f4oP7Pmk=
+ENTRY_END
+
+; check for cached answer
+STEP 30 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+start.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 40 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH opcode qname flags rcode question answer authority
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+start.example.com. IN A
+SECTION ANSWER
+start.example.com. 3600 IN CNAME x.y.z.wc.example.com.
+start.example.com. 3600 IN RRSIG CNAME 8 3 3600 20121126123316 20121029123316 64050 example.com. LHpx5n++Z0Jgjjalac+e7wdYSbfurqSDpLRAOI1PybTJkwrMvgDKfp0ycT4HwsLVy7spumZ/Ahg/5II9pai7jCiqv1Iyh6fx19ZVeClTFMOLotCK8xMHACYJIY39BhTwD2D3r9BxbK+RopUlXypwV02yzdY2xEnPCBJVDUn5d0g=
+x.y.z.wc.example.com. 3600 IN CNAME x.y.z.end.example.com.
+x.y.z.wc.example.com. 3600 IN RRSIG CNAME 8 3 3600 20121126123316 20121029123316 64050 example.com. BCnT6CIuqvF1U9LfiHIovgvXIVFJsCXqQWmnjHtbFvzUlTlfGj+56YBSOEpyCep4CBJ0CBgZ8gl5kWip8N+sTlveU/UWMv4FAkqLXRYjp4CZegslmJIuXU5uS+Q0GlLbWdSB9ZCZcbbO0qrOtUfrJ2ozcSTCS+D+oIZ+CkwvDlQ=
+x.y.z.end.example.com. 3600 IN A 1.2.3.5
+x.y.z.end.example.com. 3600 IN RRSIG A 8 3 3600 20121126123249 20121029123249 64050 example.com. MyXXd3MvXtEYVNqWDepM3+Ra/j/b63QehzSHXZe5gL954WxW8KGHPYmeWyhDtruThpZS6s6jeARY2xt0lmEDnMgNyPJGA6UWwTIgvGD0u9Qw5kocCq3ZH4cSG4xu4rmZoi+h8OGrHxUb4jIKzipzAQDxhnAcp/wKF7e+p+OE+Fo=
+SECTION AUTHORITY
+isjq5aarcp8p5sukc56g961cccjus5u2.example.com. 86400 IN NSEC3 1 0 1 abcd isoaarjsq14bkqaamivn1t1milkv95lc A RRSIG
+isjq5aarcp8p5sukc56g961cccjus5u2.example.com. 86400 IN RRSIG NSEC3 8 3 86400 20121126123259 20121029123259 64050 example.com. Cxwzq1DUQvhkTVHEJHlb92c511Y+uJy/C0yL9br6W/5lB/usuSiK2DjW58ibPh2kLH1P3SpGqd1Y7LigptdXoPBDFakcNcimPWCN93R3J80+vrHHPkPyIsBaywwYI3SNGgfnHfPF+wmH+tZ1vfEHbigOxqPFK+T0ntKq7dkSndg=
+a61sejfu6am5a36p628t4s089s309o44.example.com. 86400 IN NSEC3 1 0 1 abcd a64lt5ij9a1up15h5cdsn1u2071901hu A RRSIG
+a61sejfu6am5a36p628t4s089s309o44.example.com. 86400 IN RRSIG NSEC3 8 3 86400 20121126123315 20121029123315 64050 example.com. gfBu4oqo9cVxJbqrw2Ly7mK638kGPOF8l8eh7ovalniwkU3F+PNYJyfSE9yGX8tMGbXrkEW9mAzAh39igr2+Bbzi9WPTRp4RDVM0qw+eyMmQRPWKt7FeanDtP+OcdVp0Hf2aPzsgmgTdS6s0AboUq1rX53H2M6F8xAiwPrBJXDQ=
+;example.com. 3600 IN NS ns.example.com.
+;example.com. 3600 IN RRSIG NS 8 2 3600 20121126123249 20121029123249 64050 example.com. cpLjgKPacNxVIGo59tYMZ98GVYpH28WHRWj3AeIHK0StYFcAlflGLdkae1LEgMwfUmzrayrA5GMe3AH8LyuTgA2Dn1oNFxGfuShQvK2MFQ+LxvQfiuoqlAlL5Aa94IWcSoU/wLrr66I1K8oSB2yK1Tyyv73c2N40D1mBbzIE70U=
+SECTION ADDITIONAL
+;ns.example.com. 3600 IN A 1.2.3.4
+;ns.example.com. 3600 IN RRSIG A 8 2 3600 20121126123249 20121029123249 64050 example.com. zxGyimwFsd39j8T7jJ+tSAQPwZ7tjk6HHmzosTMCRePM4k4newbLb5HbrpucSiW/plaEZvjRTDTJ6bPkw0msPXjPCI/22Zh236XO5vhGtMOlxDgAEazuhifVF6UsM7GZwONPBCvw705HgWQyCR1YlTK2w9ffH3GopU9f4oP7Pmk=
+ENTRY_END
+
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/val_nsec3_entnodata_optout_badopt.rpl b/tests/integration/deckard/sets/resolver/val_nsec3_entnodata_optout_badopt.rpl
new file mode 100644
index 0000000..83cc566
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_nsec3_entnodata_optout_badopt.rpl
@@ -0,0 +1,201 @@
+do-ip6: no
+
+; config options
+; The island of trust is at example.com
+;server:
+ trust-anchor: "example.com. 3600 IN DS 2854 3 1 46e4ffc6e9a4793b488954bd3f0cc6af0dfb201b"
+ val-override-date: "20070916134226"
+; target-fetch-policy: "0 0 0 0 0"
+; fake-sha1: yes
+
+;stub-zone:
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+;test from testbound
+
+SCENARIO_BEGIN Test validator with NSEC3 response for NODATA ENT with optout.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA REFUSED
+SECTION QUESTION
+ns.example.com. IN A
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA REFUSED
+SECTION QUESTION
+ns.example.com. IN AAAA
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854}
+ENTRY_END
+
+; response to DNSKEY priming query
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN DNSKEY
+SECTION ANSWER
+example.com. 3600 IN DNSKEY 256 3 3 ALXLUsWqUrY3JYER3T4TBJII s70j+sDS/UT2QRp61SE7S3E EXopNXoFE73JLRmvpi/UrOO/Vz4Se 6wXv/CYCKjGw06U4WRgR YXcpEhJROyNapmdIKSx hOzfLVE1gqA0PweZR8d tY3aNQSRn3sPpwJr6Mi /PqQKAMMrZ9ckJpf1+b QMOOvxgzz2U1GS18b3y ZKcgTMEaJzd/GZYzi/B N2DzQ0MsrSwYXfsNLFO Bbs8PJMW4LYIxeeOe6rUgkWOF 7CC9Dh/dduQ1QrsJhmZAEFfd6ByYV+ ;{id = 2854 (zsk), size = 1688b}
+example.com. 3600 IN RRSIG DNSKEY 3 2 3600 20070926134802 20070829134802 2854 example.com. MCwCFG1yhRNtTEa3Eno2zhVVuy2EJX3wAhQeLyUp6+UXcpC5qGNu9tkrTEgPUg== ;{id = 2854}
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854}
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION AUTHORITY
+example.com. IN SOA ns.example.com. hostmaster.example.com. 2007090400 28800 7200 604800 18000
+example.com. 3600 IN RRSIG SOA 3 2 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCM6lsu9byZIQ1yYjJmyYfFWM2RWAIUcR5t84r2La824oWCkLjmHXRQlco= ;{id = 2854}
+
+; NODATA response. H(www.example.com.) = s1unhcti19bkdr98fegs0v46mbu3t4m3
+s1unhcti19bkdr98fegs0v46mbu3t4m3.example.com. IN NSEC3 1 1 123 aabb00123456bbccdd s1unhcti19bkdr98fegs0v46mbu3t4m4 MX RRSIG
+s1unhcti19bkdr98fegs0v46mbu3t4m3.example.com. 3600 IN RRSIG NSEC3 3 3 3600 20070926135752 20070829135752 2854 example.com. MCwCFE/a24nsY2luhQmZjY/ObAIgNSMkAhQWd4MUOUVK55bD6AbMHWrDA0yvEA== ;{id = 2854}
+
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ent.example.com. IN DS
+SECTION AUTHORITY
+; example.com. -> b6fuorg741ufili49mg9j4328ig53sqg.
+; OPTOUT
+b6fuorg741ufili49mg9j4328ig53sqg.example.com. IN NSEC3 1 1 123 aabb00123456bbccdd b6fuorg741ufili49mg9j4328ig54sqg NS SOA DNSKEY RRSIG
+b6fuorg741ufili49mg9j4328ig53sqg.example.com. 3600 IN RRSIG NSEC3 3 3 3600 20070926135752 20070829135752 2854 example.com. AHNLlpOM8cBFBBdzUO9nQC/O6mw3rDUrqcdiSwMKAIckd3k5WZvoP78=
+
+; ent.example.com. -> 2kekcu37chvrqjb272ptidu9jhk8oqag.
+; the span does not have OPTOUT
+2kekcu37chvrqjb272ptidu9jhk7oqag.example.com. IN NSEC3 1 0 123 aabb00123456bbccdd 2kekcu37chvrqjb272ptidu9jhk9oqag
+2kekcu37chvrqjb272ptidu9jhk7oqag.example.com. 3600 IN RRSIG NSEC3 3 3 3600 20070926135752 20070829135752 2854 example.com. AAaGjBrmbElksOWsOAU0vdNwbRKsbsQgOwhFkONaynSk9M+2QpJQ6+k=
+ENTRY_END
+
+; refer to server one down
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+ent.example.com. IN A
+SECTION AUTHORITY
+; example.com. -> b6fuorg741ufili49mg9j4328ig53sqg.
+; OPTOUT
+b6fuorg741ufili49mg9j4328ig53sqg.example.com. IN NSEC3 1 1 123 aabb00123456bbccdd b6fuorg741ufili49mg9j4328ig54sqg NS SOA DNSKEY RRSIG
+b6fuorg741ufili49mg9j4328ig53sqg.example.com. 3600 IN RRSIG NSEC3 3 3 3600 20070926135752 20070829135752 2854 example.com. AHNLlpOM8cBFBBdzUO9nQC/O6mw3rDUrqcdiSwMKAIckd3k5WZvoP78=
+
+; ent.example.com. -> 2kekcu37chvrqjb272ptidu9jhk8oqag.
+; the span does not have OPTOUT
+2kekcu37chvrqjb272ptidu9jhk7oqag.example.com. IN NSEC3 1 0 123 aabb00123456bbccdd 2kekcu37chvrqjb272ptidu9jhk9oqag
+2kekcu37chvrqjb272ptidu9jhk7oqag.example.com. 3600 IN RRSIG NSEC3 3 3 3600 20070926135752 20070829135752 2854 example.com. AAaGjBrmbElksOWsOAU0vdNwbRKsbsQgOwhFkONaynSk9M+2QpJQ6+k=
+ENTRY_END
+
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+ent.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA DO SERVFAIL
+SECTION QUESTION
+ent.example.com. IN A
+SECTION ANSWER
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/val_nsec3_nods_badsig.rpl b/tests/integration/deckard/sets/resolver/val_nsec3_nods_badsig.rpl
new file mode 100644
index 0000000..be5b592
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_nsec3_nods_badsig.rpl
@@ -0,0 +1,240 @@
+do-ip6: no
+
+; config options
+; The island of trust is at example.com
+;server:
+ trust-anchor: "example.com. 3600 IN DS 2854 3 1 46e4ffc6e9a4793b488954bd3f0cc6af0dfb201b"
+ val-override-date: "20070916134226"
+; target-fetch-policy: "0 0 0 0 0"
+; fake-sha1: yes
+
+;stub-zone:
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+;test from testbound
+
+SCENARIO_BEGIN Test validator with NSEC3 with no DS referral with bad signature.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA REFUSED
+SECTION QUESTION
+ns.example.com. IN A
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA REFUSED
+SECTION QUESTION
+ns.example.com. IN AAAA
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854}
+ENTRY_END
+
+; response to DNSKEY priming query
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN DNSKEY
+SECTION ANSWER
+example.com. 3600 IN DNSKEY 256 3 3 ALXLUsWqUrY3JYER3T4TBJII s70j+sDS/UT2QRp61SE7S3E EXopNXoFE73JLRmvpi/UrOO/Vz4Se 6wXv/CYCKjGw06U4WRgR YXcpEhJROyNapmdIKSx hOzfLVE1gqA0PweZR8d tY3aNQSRn3sPpwJr6Mi /PqQKAMMrZ9ckJpf1+b QMOOvxgzz2U1GS18b3y ZKcgTMEaJzd/GZYzi/B N2DzQ0MsrSwYXfsNLFO Bbs8PJMW4LYIxeeOe6rUgkWOF 7CC9Dh/dduQ1QrsJhmZAEFfd6ByYV+ ;{id = 2854 (zsk), size = 1688b}
+example.com. 3600 IN RRSIG DNSKEY 3 2 3600 20070926134802 20070829134802 2854 example.com. MCwCFG1yhRNtTEa3Eno2zhVVuy2EJX3wAhQeLyUp6+UXcpC5qGNu9tkrTEgPUg== ;{id = 2854}
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854}
+ENTRY_END
+
+; response to query of interest
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION AUTHORITY
+example.com. IN SOA ns.example.com. hostmaster.example.com. 2007090400 28800 7200 604800 18000
+example.com. 3600 IN RRSIG SOA 3 2 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCM6lsu9byZIQ1yYjJmyYfFWM2RWAIUcR5t84r2La824oWCkLjmHXRQlco= ;{id = 2854}
+
+; NODATA response. H(www.example.com.) = s1unhcti19bkdr98fegs0v46mbu3t4m3
+s1unhcti19bkdr98fegs0v46mbu3t4m3.example.com. IN NSEC3 1 1 123 aabb00123456bbccdd s1unhcti19bkdr98fegs0v46mbu3t4m4 MX RRSIG
+s1unhcti19bkdr98fegs0v46mbu3t4m3.example.com. 3600 IN RRSIG NSEC3 3 3 3600 20070926135752 20070829135752 2854 example.com. MCwCFE/a24nsY2luhQmZjY/ObAIgNSMkAhQWd4MUOUVK55bD6AbMHWrDA0yvEA== ;{id = 2854}
+
+ENTRY_END
+
+; refer to server one down
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.sub.example.com. IN A
+SECTION AUTHORITY
+sub.example.com. IN NS ns.sub.example.com.
+; proof that there is no DS here.
+;sub.example.com. 3600 IN DS 2854 DSA 1 be4d46cd7489cce25a31af0dff2968ce0425dd31
+;sub.example.com. 3600 IN RRSIG DS 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQC1WMTfb25sTgeUEXCFR4+YiJqecwIUc2R/jrO4amyQxovSnld2reg8eyo= ;{id = 2854}
+; sub.example.com. -> 8r1f0ieoutlnjc03meng9e3bn2n0o9pd.
+8r1f0ieoutlnjc03meng9e3bn2n0o9pd.example.com. IN NSEC3 1 1 123 aabb00123456bbccdd 8r1f0ieoutlnjc03meng9e3bn3n0o9pd NS RRSIG
+; bad signature:
+8r1f0ieoutlnjc03meng9e3bn2n0o9pd.example.com. 3600 IN RRSIG NSEC3 3 3 3600 20010926135752 20010829135752 2854 example.com. MC0CFEC78oZJjqlV6kVyQb4X0o6tsUpUAhUAk+bgth7eeN+aO8ts2+yLSyzSX9g= ;{id = 2854}
+;8r1f0ieoutlnjc03meng9e3bn2n0o9pd.example.com. 3600 IN RRSIG NSEC3 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFEC78oZJjqlV6kVyQb4X0o6tsUpUAhUAk+bgth7eeN+aO8ts2+yLSyzSX9g= ;{id = 2854}
+SECTION ADDITIONAL
+ns.sub.example.com. IN A 1.2.3.10
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+sub.example.com. IN DS
+SECTION AUTHORITY
+; proof that there is no DS here.
+;sub.example.com. 3600 IN DS 2854 DSA 1 be4d46cd7489cce25a31af0dff2968ce0425dd31
+;sub.example.com. 3600 IN RRSIG DS 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQC1WMTfb25sTgeUEXCFR4+YiJqecwIUc2R/jrO4amyQxovSnld2reg8eyo= ;{id = 2854}
+; sub.example.com. -> 8r1f0ieoutlnjc03meng9e3bn2n0o9pd.
+8r1f0ieoutlnjc03meng9e3bn2n0o9pd.example.com. IN NSEC3 1 1 123 aabb00123456bbccdd 8r1f0ieoutlnjc03meng9e3bn3n0o9pd NS RRSIG
+; bad signature
+8r1f0ieoutlnjc03meng9e3bn2n0o9pd.example.com. 3600 IN RRSIG NSEC3 3 3 3600 20010926135752 20010829135752 2854 example.com. MC0CFEC78oZJjqlV6kVyQb4X0o6tsUpUAhUAk+bgth7eeN+aO8ts2+yLSyzSX9g= ;{id = 2854}
+;8r1f0ieoutlnjc03meng9e3bn2n0o9pd.example.com. 3600 IN RRSIG NSEC3 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFEC78oZJjqlV6kVyQb4X0o6tsUpUAhUAk+bgth7eeN+aO8ts2+yLSyzSX9g= ;{id = 2854}
+ENTRY_END
+RANGE_END
+
+; ns.sub.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.10
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR REFUSED
+SECTION QUESTION
+sub.example.com. IN NS
+SECTION ANSWER
+ENTRY_END
+
+
+; response to DNSKEY priming query
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+sub.example.com. IN DNSKEY
+SECTION ANSWER
+sub.example.com. 3600 IN DNSKEY 256 3 3 ALXLUsWqUrY3JYER3T4TBJII s70j+sDS/UT2QRp61SE7S3E EXopNXoFE73JLRmvpi/UrOO/Vz4Se 6wXv/CYCKjGw06U4WRgR YXcpEhJROyNapmdIKSx hOzfLVE1gqA0PweZR8d tY3aNQSRn3sPpwJr6Mi /PqQKAMMrZ9ckJpf1+b QMOOvxgzz2U1GS18b3y ZKcgTMEaJzd/GZYzi/B N2DzQ0MsrSwYXfsNLFO Bbs8PJMW4LYIxeeOe6rUgkWOF 7CC9Dh/dduQ1QrsJhmZAEFfd6ByYV+ ;{id = 2854 (zsk), size = 1688b}
+sub.example.com. 3600 IN RRSIG DNSKEY 3 3 3600 20070926135752 20070829135752 2854 sub.example.com. MCwCFBznBTYM/SrdUnjQdBnLtRO79KAaAhQReG5nRuL7Xsdf6D0KKwPa1GpWyQ== ;{id = 2854}
+
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.sub.example.com. IN A
+SECTION ANSWER
+www.sub.example.com. IN A 1.2.3.123
+www.sub.example.com. 3600 IN RRSIG A 3 4 3600 20070926135752 20070829135752 2854 sub.example.com. MC0CFEExteiCsLkRi/md6o5K8BhRJAKFAhUAgg2tkvwaDn8Xbm9q+5xnjvgIB8k= ;{id = 2854}
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.sub.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA DO SERVFAIL
+SECTION QUESTION
+www.sub.example.com. IN A
+SECTION ANSWER
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/val_nsec3_nods_soa.rpl b/tests/integration/deckard/sets/resolver/val_nsec3_nods_soa.rpl
new file mode 100644
index 0000000..866da59
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_nsec3_nods_soa.rpl
@@ -0,0 +1,256 @@
+do-ip6: no
+
+; config options
+; The island of trust is at example.com
+;server:
+ trust-anchor: "example.com. 3600 IN DS 2854 3 1 46e4ffc6e9a4793b488954bd3f0cc6af0dfb201b"
+ val-override-date: "20070916134226"
+; target-fetch-policy: "0 0 0 0 0"
+; fake-sha1: yes
+
+;stub-zone:
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+;test from testbound
+
+SCENARIO_BEGIN Test validator with NSEC3 with no DS referral abuse of apex.
+; abusing subzone apex NSEC3.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA SERVFAIL
+SECTION QUESTION
+ns.example.com. IN A
+SECTION ANSWER
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA SERVFAIL
+SECTION QUESTION
+ns.example.com. IN AAAA
+SECTION ANSWER
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854}
+ENTRY_END
+
+; response to DNSKEY priming query
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN DNSKEY
+SECTION ANSWER
+example.com. 3600 IN DNSKEY 256 3 3 ALXLUsWqUrY3JYER3T4TBJII s70j+sDS/UT2QRp61SE7S3E EXopNXoFE73JLRmvpi/UrOO/Vz4Se 6wXv/CYCKjGw06U4WRgR YXcpEhJROyNapmdIKSx hOzfLVE1gqA0PweZR8d tY3aNQSRn3sPpwJr6Mi /PqQKAMMrZ9ckJpf1+b QMOOvxgzz2U1GS18b3y ZKcgTMEaJzd/GZYzi/B N2DzQ0MsrSwYXfsNLFO Bbs8PJMW4LYIxeeOe6rUgkWOF 7CC9Dh/dduQ1QrsJhmZAEFfd6ByYV+ ;{id = 2854 (zsk), size = 1688b}
+example.com. 3600 IN RRSIG DNSKEY 3 2 3600 20070926134802 20070829134802 2854 example.com. MCwCFG1yhRNtTEa3Eno2zhVVuy2EJX3wAhQeLyUp6+UXcpC5qGNu9tkrTEgPUg== ;{id = 2854}
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854}
+ENTRY_END
+
+; response to query of interest
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION AUTHORITY
+example.com. IN SOA ns.example.com. hostmaster.example.com. 2007090400 28800 7200 604800 18000
+example.com. 3600 IN RRSIG SOA 3 2 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCM6lsu9byZIQ1yYjJmyYfFWM2RWAIUcR5t84r2La824oWCkLjmHXRQlco= ;{id = 2854}
+
+; NODATA response. H(www.example.com.) = s1unhcti19bkdr98fegs0v46mbu3t4m3
+s1unhcti19bkdr98fegs0v46mbu3t4m3.example.com. IN NSEC3 1 1 123 aabb00123456bbccdd s1unhcti19bkdr98fegs0v46mbu3t4m4 MX RRSIG
+s1unhcti19bkdr98fegs0v46mbu3t4m3.example.com. 3600 IN RRSIG NSEC3 3 3 3600 20070926135752 20070829135752 2854 example.com. MCwCFE/a24nsY2luhQmZjY/ObAIgNSMkAhQWd4MUOUVK55bD6AbMHWrDA0yvEA== ;{id = 2854}
+
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+sub.example.com. IN DS
+SECTION AUTHORITY
+; proof that there is no DS here.
+;sub.example.com. 3600 IN DS 2854 DSA 1 be4d46cd7489cce25a31af0dff2968ce0425dd31
+;sub.example.com. 3600 IN RRSIG DS 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQC1WMTfb25sTgeUEXCFR4+YiJqecwIUc2R/jrO4amyQxovSnld2reg8eyo= ;{id = 2854}
+; sub.example.com. -> 8r1f0ieoutlnjc03meng9e3bn2n0o9pd.
+8r1f0ieoutlnjc03meng9e3bn2n0o9pd.example.com. IN NSEC3 1 1 123 aabb00123456bbccdd 8r1f0ieoutlnjc03meng9e3bn3n0o9pd NS SOA DNSKEY RRSIG
+8r1f0ieoutlnjc03meng9e3bn2n0o9pd.example.com. 3600 IN RRSIG NSEC3 3 3 3600 20070926135752 20070829135752 2854 example.com. MC4CFQCeKcyw76yvOvfa2+qtxv8bKcEyJwIVAJBeIGST4Y8Tk8YkQI0suee3Bxb1 ;{id = 2854}
+ENTRY_END
+
+; refer to server one down
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+sub.example.com. IN A
+SECTION AUTHORITY
+sub.example.com. IN NS ns.sub.example.com.
+; proof that there is no DS here.
+;sub.example.com. 3600 IN DS 2854 DSA 1 be4d46cd7489cce25a31af0dff2968ce0425dd31
+;sub.example.com. 3600 IN RRSIG DS 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQC1WMTfb25sTgeUEXCFR4+YiJqecwIUc2R/jrO4amyQxovSnld2reg8eyo= ;{id = 2854}
+; sub.example.com. -> 8r1f0ieoutlnjc03meng9e3bn2n0o9pd.
+8r1f0ieoutlnjc03meng9e3bn2n0o9pd.example.com. IN NSEC3 1 1 123 aabb00123456bbccdd 8r1f0ieoutlnjc03meng9e3bn3n0o9pd NS SOA DNSKEY RRSIG
+8r1f0ieoutlnjc03meng9e3bn2n0o9pd.example.com. 3600 IN RRSIG NSEC3 3 3 3600 20070926135752 20070829135752 2854 example.com. MC4CFQCeKcyw76yvOvfa2+qtxv8bKcEyJwIVAJBeIGST4Y8Tk8YkQI0suee3Bxb1 ;{id = 2854}
+
+SECTION ADDITIONAL
+ns.sub.example.com. IN A 1.2.3.10
+ENTRY_END
+RANGE_END
+
+; ns.sub.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.10
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA REFUSED
+SECTION QUESTION
+ns.sub.example.com. IN A
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA REFUSED
+SECTION QUESTION
+ns.sub.example.com. IN AAAA
+SECTION ANSWER
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR REFUSED
+SECTION QUESTION
+sub.example.com. IN NS
+SECTION ANSWER
+ENTRY_END
+
+; response to DNSKEY priming query
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+sub.example.com. IN DNSKEY
+SECTION ANSWER
+sub.example.com. 3600 IN DNSKEY 256 3 3 ALXLUsWqUrY3JYER3T4TBJII s70j+sDS/UT2QRp61SE7S3E EXopNXoFE73JLRmvpi/UrOO/Vz4Se 6wXv/CYCKjGw06U4WRgR YXcpEhJROyNapmdIKSx hOzfLVE1gqA0PweZR8d tY3aNQSRn3sPpwJr6Mi /PqQKAMMrZ9ckJpf1+b QMOOvxgzz2U1GS18b3y ZKcgTMEaJzd/GZYzi/B N2DzQ0MsrSwYXfsNLFO Bbs8PJMW4LYIxeeOe6rUgkWOF 7CC9Dh/dduQ1QrsJhmZAEFfd6ByYV+ ;{id = 2854 (zsk), size = 1688b}
+sub.example.com. 3600 IN RRSIG DNSKEY 3 3 3600 20070926135752 20070829135752 2854 sub.example.com. MCwCFBznBTYM/SrdUnjQdBnLtRO79KAaAhQReG5nRuL7Xsdf6D0KKwPa1GpWyQ== ;{id = 2854}
+
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.sub.example.com. IN A
+SECTION ANSWER
+www.sub.example.com. IN A 1.2.3.123
+www.sub.example.com. 3600 IN RRSIG A 3 4 3600 20070926135752 20070829135752 2854 sub.example.com. MC0CFEExteiCsLkRi/md6o5K8BhRJAKFAhUAgg2tkvwaDn8Xbm9q+5xnjvgIB8k= ;{id = 2854}
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.sub.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA SERVFAIL
+SECTION QUESTION
+www.sub.example.com. IN A
+SECTION ANSWER
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/val_nsec3_noopt_ref.rpl b/tests/integration/deckard/sets/resolver/val_nsec3_noopt_ref.rpl
new file mode 100644
index 0000000..f541c28
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_nsec3_noopt_ref.rpl
@@ -0,0 +1,232 @@
+do-ip6: no
+
+; config options
+; The island of trust is at example.com
+;server:
+ trust-anchor: "example.com. IN DS 438 10 2 33F8133EB48EDB093839E985600EB7B7009EB5AC312D11CCA9007F6B 71D94D7B"
+ val-override-date: "20160308103040"
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN NSEC3 referral to unsigned subzone, no optout.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA SERVFAIL
+SECTION QUESTION
+ns.example.com. IN A
+SECTION ANSWER
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA SERVFAIL
+SECTION QUESTION
+ns.example.com. IN AAAA
+SECTION ANSWER
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. 3600 IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 10 2 3600 20251231235959 20160308093040 2843 example.com. boNVuXxyhW+Gmiu+4ip1QQvIGqFNVsFfg1v+ywgc4+37ieQ5t+qJsHVm fJITRZrJxYQ6T/MkZKhpxLCemgFeKU6syWwoCfypnGino2G1urvqThna WTImSPhY/QsOj1ALy51d9Q+Mb5vt69XJt6SQvtNf6imepIFOT6CPSfjx BJ4=
+SECTION ADDITIONAL
+ns.example.com. 3600 IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 10 3 3600 20251231235959 20160308093040 2843 example.com. VSq+DkxJYr9Z+uh3KgpyPNwtuim4WVXnTdhRW7HX90CP5tyOVjDDTehA UmCxB8iFjUFE3hlwDx0Y71g+8Oso1t0JGkvDtWf5RDx1w+4K/1pQ2JMG lZTh7juaGJzXtltxqBoY67z1FBp9MI59O0hkABtz1CElj9LrhDr9wQa4 OUo=
+ENTRY_END
+
+; response to DNSKEY priming query
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+example.com. IN DNSKEY
+SECTION ANSWER
+example.com. 3600 IN DNSKEY 256 3 10 AwEAAcOHC7D2ZcG5M6MK5If/60+vvBM67BC8qUx04f6Kcvhx9GBMIMYz 87m6m2P5WKafW5AN1K9jY37m2fU/TdACQNzqu4wyVsOQefke/v2fgswg NgneP/C7cpyBVuK+8BUHjrorfLORClD3mbQMQldaaO2h6+OArAGHlFNI oFsuCjyR
+example.com. 3600 IN DNSKEY 257 3 10 AwEAAc4VCSEu1C1lAxuZMC8tSyissZNXC2lgS3zNvAvFdLtAsSbhB1cj dLCtTWUv1Ki/T+iWn10iemLQJ0S6z8wK+a7maC3ELZP1qoSFln+FiAsZ xYK72/XDEYMMp01F0gxgzZ2alWx3WKm2mELXf/ezEx+7X2ZNbwum5TKt FxtvotmT
+example.com. 3600 IN RRSIG DNSKEY 10 2 3600 20251231235959 20160308093040 438 example.com. cas8JKwtLUIItwOgrDrDG9pSkqiYw3r+8vyvt962kjHFBNG0D7AeegaO GMSWRziqA4L8xdgP750rLR5CRFQ9oPQlr/RWnsebGdJ3Yohwwa04HE6n OvR+o0u0oqNQ+P5KinxVKSv0Ru+BVMPHRDfIXN/FD5p9+nvIrnjXQlI3 vvM=
+example.com. 3600 IN RRSIG DNSKEY 10 2 3600 20251231235959 20160308093040 2843 example.com. uDLTMMTvJCcetKr6THEJ8Rn0gMLPFZTbOGJBZyZ2E5F9KkPSS01Nm6/P e+j0R3ObYXodqnZIY19fzXJKS2dJktoXkqNLBW/SpWTlFzpfHKCvTbJS VLrJ/lrEunE5cgSAqBrbAAuJrFpX/gaavqokElnUv1Mki2agTH1dTZyn X8M=
+SECTION AUTHORITY
+example.com. 3600 IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 10 2 3600 20251231235959 20160308093040 2843 example.com. boNVuXxyhW+Gmiu+4ip1QQvIGqFNVsFfg1v+ywgc4+37ieQ5t+qJsHVm fJITRZrJxYQ6T/MkZKhpxLCemgFeKU6syWwoCfypnGino2G1urvqThna WTImSPhY/QsOj1ALy51d9Q+Mb5vt69XJt6SQvtNf6imepIFOT6CPSfjx BJ4=
+SECTION ADDITIONAL
+ns.example.com. 3600 IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 10 3 3600 20251231235959 20160308093040 2843 example.com. VSq+DkxJYr9Z+uh3KgpyPNwtuim4WVXnTdhRW7HX90CP5tyOVjDDTehA UmCxB8iFjUFE3hlwDx0Y71g+8Oso1t0JGkvDtWf5RDx1w+4K/1pQ2JMG lZTh7juaGJzXtltxqBoY67z1FBp9MI59O0hkABtz1CElj9LrhDr9wQa4 OUo=
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+sub.example.com. IN DS
+SECTION AUTHORITY
+; sub.example.com. -> po0bgjsa0o6vivtr1pvp9ra8s54qpnsb.
+PO0BGJSA0O6VIVTR1PVP9RA8S54QPNSB.example.com. 18000 IN NSEC3 1 0 10 A7AD1394BEB94E45 CO0J7N2E081RL10GCBQ31EDR3OE33LNC NS
+PO0BGJSA0O6VIVTR1PVP9RA8S54QPNSB.example.com. 18000 IN RRSIG NSEC3 10 3 18000 20251231235959 20160308093040 2843 example.com. WepNJEmwXlC107N7E4G0qpUYBVLjLGcYSqJtFFyWU0n8wS9Mw6eH4IZY esAjOdkezqjwpDQny/z9GuTMtpKdIZvzEa8mHn9I/Bv6Gq2U9Yc5w0z8 jqRMi/0Rvy4IAAQoHZOntfcfx4ZRVd/55VeQaJevM2DQLaP6Z4e/rhPs cRs=
+ENTRY_END
+
+; refer to server one down
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+sub.example.com. IN A
+SECTION AUTHORITY
+sub.example.com. IN NS ns.sub.example.com.
+; no DS here.
+; sub.example.com. 3600 IN DS 38364 7 1 66DC14443014B2727261B50B447170DE18CF43A9
+; sub.example.com. 3600 IN DS 38364 7 2 719A6680950A624D2C71A67981A7AF884C23E3C21074FF1CF8FB7EFE 20C52F97
+; sub.example.com. 3600 IN RRSIG DS 10 3 3600 20251231235959 20160308101119 2843 example.com. nAH1Nc1yq6EfzKLq48mLOEo2ocQrxkDFVAYIl+7ZMQJ1ZXHSmwePVH+m MAxdJ8xMl9BV/EcScn3vgSG+GfKfpl6txCS59Hxc30k27x6ac/6vL+ll YS99nEZMkc9JpBk3gziLj6hH8qv0G84264lNWAP2XGv1jO/AYrXL6wti Lxg=
+; sub.example.com. -> po0bgjsa0o6vivtr1pvp9ra8s54qpnsb.
+PO0BGJSA0O6VIVTR1PVP9RA8S54QPNSB.example.com. 18000 IN NSEC3 1 0 10 A7AD1394BEB94E45 CO0J7N2E081RL10GCBQ31EDR3OE33LNC NS
+PO0BGJSA0O6VIVTR1PVP9RA8S54QPNSB.example.com. 18000 IN RRSIG NSEC3 10 3 18000 20251231235959 20160308093040 2843 example.com. WepNJEmwXlC107N7E4G0qpUYBVLjLGcYSqJtFFyWU0n8wS9Mw6eH4IZY esAjOdkezqjwpDQny/z9GuTMtpKdIZvzEa8mHn9I/Bv6Gq2U9Yc5w0z8 jqRMi/0Rvy4IAAQoHZOntfcfx4ZRVd/55VeQaJevM2DQLaP6Z4e/rhPs cRs=
+SECTION ADDITIONAL
+ns.sub.example.com. IN A 1.2.3.10
+ENTRY_END
+RANGE_END
+
+; ns.sub.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.10
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA REFUSED
+SECTION QUESTION
+ns.sub.example.com. IN A
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA REFUSED
+SECTION QUESTION
+ns.sub.example.com. IN AAAA
+SECTION ANSWER
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA REFUSED
+SECTION QUESTION
+sub.example.com. IN NS
+SECTION ANSWER
+ENTRY_END
+
+; response to DNSKEY priming query
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+sub.example.com. IN DNSKEY
+SECTION ANSWER
+sub.example.com. 3600 IN DNSKEY 256 3 7 AwEAAfXXu2eDy9QsjLuHgEMWmG03TVauwmITCq520ANujsTZlPKyQKJe xyrYm61e0RuQJb5dB5JnE0O3YYJOpnrl8keieAqVt1efnNtcn8V1em48 et146ZYFAUb/PMdTOgd2XJnhVEWD3VsZbWNMCxP1KcJTATAaLDVCY//E sc9K3CvGUizNcSoTK2rGS73A6GqmvVNnGir6AQIZifkvb6PKzF/hVpS8 cgvKF/UP8hu+0Glbq1YYTFrXMUBzKUH+X19lRvk3eLHurSvGjDEM3ZO6 tp1QdpzIRPzYKENG+qs07dhgCZyb4zqwEycmL9/Vot0ByTGbeHvHN93P PrLxcM5zlVk=
+sub.example.com. 3600 IN DNSKEY 257 3 7 AwEAAfTD+gzZ2g7c9VoOUR2ekQiPNEyqcyl0MZ4sD3bleU8D8hQdDgAI 1G38raY3xmNea8yLCQYF0x00QbmKtzMjpZqKfsCFZDX6lBV5dP8IwJ0D F6L4hjO819IInf6upH9tfQNnueflWyKzfg2zitV+ILZ4YtZViyCKqayw CSPE8OkFlszZyCESzhrXqoPdJ0oHdZCG4lOlRIgZfrMLC4yTI56iiwFc UsKy7BhNPW+hcc4r+0WB9BCpsiei/FjPMcyeMrx1W+s/xgW7/55Nq+dM PUn9v24uCptZUupn/7CRgMGM5DmWe94QIswAQjH2mXNfOgVPOiceLYzU mcNoKudvSUu1hbzJbVHA4UNWDm2vvsdsEzrOEzqO0ZVczLoZzWU4WpLf IlKm481OKkzAP9Y5F4iTTSIrbVcAuEW/iz5zfqWirgGniiTCszAie8lH u1EPBgGnfotqhq9IbNA6aKNUreJPLvJnds7J/aQmiSdm15pAq71B26X5 BmoZVhbNmh6MHXkq99EIt0yRMEOfPLRN7euza8Idd4mA+E8jpdgtYdJD LC7f2SoQxaN4RMr5MC/Z1ENQgLMYRkd87pEQycAlNAoWMPJMuoDNdwhV 15F8+pvkvfu5cm9FoEWvgS+onibUM9EC9L9EDdfDdW1Hf1QfUinVoMf/ Szf1urkPVNl0nNYF
+sub.example.com. 3600 IN RRSIG DNSKEY 7 3 3600 20251231235959 20160308100552 27527 sub.example.com. yUIM3oBl8hkj8/NkHw79wpS0EHWTNA+tW8qDv3IhzpRXWQ78QjRvcLt/ PkoUpaVXydM4xwf61oy0C9nNhakiaTw99icmqbIRfOL4ZQAIEtyzKrP4 Dww/ySI8YJx5ebbEALueAOTQQG4VHk3hEfLlFgUOje01y8usi2QjiX84 uSLfW3DtHODNPWuumTBKrysWC8rs2jiXuDTcViP6IGZnZ1X4E9F8m3J6 gv7kOgqUJp9PRuwSQUuWBk2drl8psZzWuk99g/dnN1SY8B3iBc2DE4/S CHUYrHfdp5YjuKsSg8HTmPS83aks/TeKAogRZ5bEUyxO5VHMnywZUZtl YLuyJg==
+sub.example.com. 3600 IN RRSIG DNSKEY 7 3 3600 20251231235959 20160308100552 38364 sub.example.com. ewivalJKy9ahD0p0ca871A3rM302OafX1qYe6K9CjBTvFFWl3JR+tEIY idHyVBwANAS4W2LxP2jrweQ3POL9+I/a3EvadWYnaVGrSHuQr42yPL44 jPO1SBkbTKCTHTlNDgllIaOiszkjZNwE9vTiKxz+5s1kVXnGHPGQfNts LVhFgWZmcZ9AlDbieAOjS2F/P7YWp3NG8lLR3v+JWaD1S+TgClwAFWAl kEOBQ0xltRQ7MFZ92cWudJ24FnYlBEpy51XmfYx3ExmCXpGF2vKYoLGR 76CvsC5anrsaYY1znfACrdt2tYvkEE+TwYuO6/Rm1Ay+whI5wzFWpWf2 xTysJEDcx6TK5rm9PpAiPcdbahhEZPyIm8SIbHSXs9X70wqNpZwtrez5 46F2lefZZ6z9q9+o9hicTXGgPz/nITQ693nbphAl/B713kXVhgeBIcX+ ZqjFnXYQBwliU6ae22hWsFl3l+lN0S7o0w2uzMZiChA0VP3H7LKSO1e2 G17Z1bfVfMZoM2hhLOJuWozLorPJR81DrIAO1JpIKGSxP6clBIE6lhjk hvRjQAmxt/rLsebhVNpXNAEkWwxM4OatK5d5zv2HlvL9QA8Nm4NlZ9Fu pKqoRKijUr1ny4O4nwb3aQVxwCP2+MHuH7XQOtpEFxWeoDPFbu9WIunb dONPnl9ZB8Y=
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www.sub.example.com. IN A
+SECTION ANSWER
+www.sub.example.com. 3600 IN A 1.2.3.123
+www.sub.example.com. 3600 IN RRSIG A 7 4 3600 20251231235959 20160308100552 27527 sub.example.com. h6RhBN/xWlVYrQVt0TNbFd2/6bvQx9oAYJFyKvzZZbcEbd2giEud1gcW B05TZDwK5p36GcyoGdA6DB9kEGFNqH44OqTsUqtOmqysFw2nsAHXGBId UetoOxT1JOvJlqd7qwC1cBhDmlRB+1u83PBCJyjb2nJ4HwEDSAf/5SRN DQJQmGTGD4FIb9ixHOH2Y3f6U2YaDz35RpJSko2j65erEcOH65dXsAiU OkKNh7g3esbQCGNnY85RyhCPGSFJ4MxLsIa+ZqTY9tvtKL0mDSrqd/51 bhNcKa2Dl99cDOwH3kXFqO+L+DdTXU5WbRxRe74SFzoum/lnyQhcrKN5 029iOA==
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.sub.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.sub.example.com. IN A
+SECTION ANSWER
+www.sub.example.com. IN A 1.2.3.123
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/val_nsec3_optout_ad.rpl b/tests/integration/deckard/sets/resolver/val_nsec3_optout_ad.rpl
new file mode 100644
index 0000000..880c2d4
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_nsec3_optout_ad.rpl
@@ -0,0 +1,363 @@
+do-ip6: no
+
+; config options
+; The island of trust is at example.com
+;server:
+ trust-anchor: "example.com. DS 57024 7 1 46d134be319b2cc910b9938f1cb25dc41abb27bf"
+ val-override-date: "20070916134226"
+; target-fetch-policy: "0 0 0 0 0"
+; fake-sha1: yes
+ query-minimization: off
+
+;stub-zone:
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test validator with optout NSEC3 response that gets no AD.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20070926134150 20070829134150 57024 example.com. fIE3H2v3wAm3GPajsdgJn+A8R4Cp7dMXf1PSUQ8BfklzMBMJjpc0oM/S7u/HVLYQs1jx8CMdw2TZEpIPfo6Rl0TekDqNtVk6IBw1H+zxDFwf3v7UdOjm8s6FfoEJcZ5yEFV/Lps82NzHCR9uqprhv6ddQdAeVNA5QHis1c5Y1P0= ;{id = 57024}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20070926134150 20070829134150 57024 example.com. b0iX5vuTqngB5F0ORFrFLx8sAeTHGJVcPpD34iNFY71ZoFnHrHfAMWC3RAWz+nQ1NmH1oDdA8NTYN/aQQNzwEz4VmVYA2PANBSiwSY3q3gp9PWZU6CfRNf2dU/210H0y35FroQpADszmwC+Hlbcvll+bQj3fSyT2W/69kRVssj4= ;{id = 57024}
+ENTRY_END
+
+; response to DNSKEY priming query
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN DNSKEY
+SECTION ANSWER
+example.com. 3600 IN DNSKEY 257 3 7 AwEAAbvre/wK/WVeoj0SiwVkTD+NefvHPru9YIqLWY0m+0E5NYOpJZdc+PGQQYRzFNOlugVZtFirmv5Lmz7GNiASXtG/IFi//SlE30DxEKQOjt2F6qSZTZ1nZ5XOIMGTwWyp4OoI0egk5JavC5mQbyXqcj82ywt6F5Z3CmnThVl6MtOv ;{id = 57024 (ksk), size = 1024b}
+example.com. 3600 IN RRSIG DNSKEY 7 2 3600 20070926134150 20070829134150 57024 example.com. lqOo8W7UffLZIKBoIJg8OAPkmCWptnstiLIg1bAtzuEZDZFr2KNZGv+5k6hbRJKYnZRLReY4v8G9Eg0GCC/44gLm8BZlnh/4jLOjMH9MKusFV/jNqz/HABITYn1pBwvVak7lzqN+bmL0KMyWf1MzPWilx4fM9YWinsQFILVLPL0= ;{id = 57024}
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20070926134150 20070829134150 57024 example.com. fIE3H2v3wAm3GPajsdgJn+A8R4Cp7dMXf1PSUQ8BfklzMBMJjpc0oM/S7u/HVLYQs1jx8CMdw2TZEpIPfo6Rl0TekDqNtVk6IBw1H+zxDFwf3v7UdOjm8s6FfoEJcZ5yEFV/Lps82NzHCR9uqprhv6ddQdAeVNA5QHis1c5Y1P0= ;{id = 57024}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20070926134150 20070829134150 57024 example.com. b0iX5vuTqngB5F0ORFrFLx8sAeTHGJVcPpD34iNFY71ZoFnHrHfAMWC3RAWz+nQ1NmH1oDdA8NTYN/aQQNzwEz4VmVYA2PANBSiwSY3q3gp9PWZU6CfRNf2dU/210H0y35FroQpADszmwC+Hlbcvll+bQj3fSyT2W/69kRVssj4= ;{id = 57024}
+ENTRY_END
+
+; response to query of interest
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+sub.example.com. IN DS
+SECTION ANSWER
+SECTION AUTHORITY
+example.com. IN SOA ns.example.com. noc.example.com. 2009310622 1800 900 604800 86400
+example.com. 3600 IN RRSIG SOA 7 2 3600 20070926134150 20070829134150 57024 example.com. HlyER7bYPiSJ9jdjjRBucQexYr932Oor1TvxSLPWw5fuWvr/fFitKVnLqC+lqBIeOby44KiDr0rIk+ZqYjWWKNjaLm5wMfhQzbsAgGTQxmO07jnYOGQG9SI6DSbR9GJdZ7imu5sx5oo5dze73MxgLMZIethGaFMkktYN53+AzG0= ;{id = 57024}
+
+; optout
+; example.com. -> onib9mgub9h0rml3cdf5bgrj59dkjhvk.
+; sub.example.com. -> kg19n32806c832kijdnglq8p9m2r5mdj.
+; *.example.com. -> 4f3cnt8cu22tngec382jj4gde4rb47ub.
+onib9mgub9h0rml3cdf5bgrj59dkjhvk.example.com. NSEC3 1 1 0 - pnib9mgub9h0rml3cdf5bgrj59dkjhvk NS SOA RRSIG DNSKEY NSEC3PARAM
+jg19n32806c832kijdnglq8p9m2r5mdj.example.com. NSEC3 1 1 0 - lg19n32806c832kijdnglq8p9m2r5mdj NS DS RRSIG
+
+onib9mgub9h0rml3cdf5bgrj59dkjhvk.example.com. 3600 IN RRSIG NSEC3 7 3 3600 20070926134150 20070829134150 57024 example.com. jHrF+lnyRL1LE/Bwz6C+jZg3E/2qQkVSboGxya6iX71v0zA3eUsob9m9l3gHNlhwhyahbamHUKx+OMvtYuzRa+RMv4ObuLRIt8StdixeXaUU+rx7C2qCKOFsa5q4HzK4bLYPfyb5T9w67HbzHPLEllXPA7tghzyzCM9qBtbvwK4= ;{id = 57024}
+jg19n32806c832kijdnglq8p9m2r5mdj.example.com. 3600 IN RRSIG NSEC3 7 3 3600 20070926134150 20070829134150 57024 example.com. f7ZSCahAuKOLXquM0jpdU6I9AX31CgGicRiB3aU4jvqQp/EygbCNn5kfpyXY0FvZvzggpl8naXSStOPN9dy3bb0NwGQkJcYD94NEw307T8uEunOvx1ug5TuakBAwqjY8xKM3xab3LnWYRtx4zdln/3ZDHvBUwfzkxUZrzeKjpiI= ;{id = 57024}
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+sub.example.com. IN MX
+SECTION ANSWER
+SECTION AUTHORITY
+example.com. IN SOA ns.example.com. noc.example.com. 2009310622 1800 900 604800 86400
+example.com. 3600 IN RRSIG SOA 7 2 3600 20070926134150 20070829134150 57024 example.com. HlyER7bYPiSJ9jdjjRBucQexYr932Oor1TvxSLPWw5fuWvr/fFitKVnLqC+lqBIeOby44KiDr0rIk+ZqYjWWKNjaLm5wMfhQzbsAgGTQxmO07jnYOGQG9SI6DSbR9GJdZ7imu5sx5oo5dze73MxgLMZIethGaFMkktYN53+AzG0= ;{id = 57024}
+
+; optout
+; example.com. -> onib9mgub9h0rml3cdf5bgrj59dkjhvk.
+; sub.example.com. -> kg19n32806c832kijdnglq8p9m2r5mdj.
+; *.example.com. -> 4f3cnt8cu22tngec382jj4gde4rb47ub.
+onib9mgub9h0rml3cdf5bgrj59dkjhvk.example.com. NSEC3 1 1 0 - pnib9mgub9h0rml3cdf5bgrj59dkjhvk NS SOA RRSIG DNSKEY NSEC3PARAM
+jg19n32806c832kijdnglq8p9m2r5mdj.example.com. NSEC3 1 1 0 - lg19n32806c832kijdnglq8p9m2r5mdj NS DS RRSIG
+
+onib9mgub9h0rml3cdf5bgrj59dkjhvk.example.com. 3600 IN RRSIG NSEC3 7 3 3600 20070926134150 20070829134150 57024 example.com. jHrF+lnyRL1LE/Bwz6C+jZg3E/2qQkVSboGxya6iX71v0zA3eUsob9m9l3gHNlhwhyahbamHUKx+OMvtYuzRa+RMv4ObuLRIt8StdixeXaUU+rx7C2qCKOFsa5q4HzK4bLYPfyb5T9w67HbzHPLEllXPA7tghzyzCM9qBtbvwK4= ;{id = 57024}
+jg19n32806c832kijdnglq8p9m2r5mdj.example.com. 3600 IN RRSIG NSEC3 7 3 3600 20070926134150 20070829134150 57024 example.com. f7ZSCahAuKOLXquM0jpdU6I9AX31CgGicRiB3aU4jvqQp/EygbCNn5kfpyXY0FvZvzggpl8naXSStOPN9dy3bb0NwGQkJcYD94NEw307T8uEunOvx1ug5TuakBAwqjY8xKM3xab3LnWYRtx4zdln/3ZDHvBUwfzkxUZrzeKjpiI= ;{id = 57024}
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NXDOMAIN
+SECTION QUESTION
+rub.example.com. IN A
+SECTION ANSWER
+SECTION AUTHORITY
+example.com. IN SOA ns.example.com. noc.example.com. 2009310622 1800 900 604800 86400
+example.com. 3600 IN RRSIG SOA 7 2 3600 20070926134150 20070829134150 57024 example.com. HlyER7bYPiSJ9jdjjRBucQexYr932Oor1TvxSLPWw5fuWvr/fFitKVnLqC+lqBIeOby44KiDr0rIk+ZqYjWWKNjaLm5wMfhQzbsAgGTQxmO07jnYOGQG9SI6DSbR9GJdZ7imu5sx5oo5dze73MxgLMZIethGaFMkktYN53+AzG0= ;{id = 57024}
+
+; optout
+; example.com. -> onib9mgub9h0rml3cdf5bgrj59dkjhvk.
+; rub.example.com. -> c2bqk3tb4foaenfbp1v0pdk6mor3r7vo.
+; *.example.com. -> 4f3cnt8cu22tngec382jj4gde4rb47ub.
+onib9mgub9h0rml3cdf5bgrj59dkjhvk.example.com. NSEC3 1 1 0 - pnib9mgub9h0rml3cdf5bgrj59dkjhvk NS SOA RRSIG DNSKEY NSEC3PARAM
+22bqk3tb4foaenfbp1v0pdk6mor3r7vo.example.com. NSEC3 1 1 0 - f2bqk3tb4foaenfbp1v0pdk6mor3r7vo NS RRSIG
+
+onib9mgub9h0rml3cdf5bgrj59dkjhvk.example.com. 3600 IN RRSIG NSEC3 7 3 3600 20070926134150 20070829134150 57024 example.com. jHrF+lnyRL1LE/Bwz6C+jZg3E/2qQkVSboGxya6iX71v0zA3eUsob9m9l3gHNlhwhyahbamHUKx+OMvtYuzRa+RMv4ObuLRIt8StdixeXaUU+rx7C2qCKOFsa5q4HzK4bLYPfyb5T9w67HbzHPLEllXPA7tghzyzCM9qBtbvwK4= ;{id = 57024}
+22bqk3tb4foaenfbp1v0pdk6mor3r7vo.example.com. 3600 IN RRSIG NSEC3 7 3 3600 20070926134150 20070829134150 57024 example.com. jk6EYU9qTrmNeeKuQRG7iKyfNJnBt45MToPVpAQ+LoGDC3muy4bkWeKspj68cN9E5wNijfmm1eFK3khSSEnM50mfJbpiwlbKgL0VZz33Zn+Wu8b7sTtdDwDH7MUBLRwHeb7W+NtQIEXPLs4Z3BXHzAXy5ZpSjQ3PJZn6zBx4/dw= ;{id = 57024}
+SECTION ADDITIONAL
+ENTRY_END
+
+; wildcard expansion
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+a.wild.example.com. IN A
+SECTION ANSWER
+; *.wild.example.com. IN A 77.88.99.0
+a.wild.example.com. IN A 77.88.99.0
+a.wild.example.com. 3600 IN RRSIG A 7 3 3600 20070926134150 20070829134150 57024 example.com. GWV6cQprrpAsaYla5z7N9tppdb+X0ZjOsiWBuBueSACHU8CzsYPMbwKUZlTNbQ4mSVRRDa0rM1niYoZF9oqyAfbn5HBLi62TRjrBLHfvatDgSiZCa4mauUfzUS+U7FfUXikNIigG0aN0xdpJ//urmecjNSKg2aW4M0DYsm7keMI= ;{id = 57024}
+SECTION AUTHORITY
+; a.wild.example.com -> ad1535hlgg914unuuaei9jfh4ofr44uo. covered by optout
+ac1535hlgg914unuuaei9jfh4ofr44uo.example.com. IN NSEC3 1 1 0 - ae1535hlgg914unuuaei9jfh4ofr44uo NS RRSIG
+ac1535hlgg914unuuaei9jfh4ofr44uo.example.com. 3600 IN RRSIG NSEC3 7 3 3600 20070926134150 20070829134150 57024 example.com. imoxsXE1c3FaXu6uSantJfMPGBgsauf1GhmNpS1lLuaNRjXOhf1PDXwt/GoD/dm2GXJAlWT8u6EK3RXkFwlDIsP7vYFuDfUNCQ/hvYq300sXl1nfW0O1bsoBJahQJuNM+xcbwbnQf0krCTxNthyi2cuiY7RYug6ZTZ3gz4DMkhU= ;{id = 57024}
+; for wild.example.com the closest encloser
+; wild.example.com -> 8aeigskl5tmraedgji7v1lqbmqs8qv7u.
+8aeigskl5tmraedgji7v1lqbmqs8qv7u.example.com. IN NSEC3 1 1 0 - 9aeigskl5tmraedgji7v1lqbmqs8qv7u
+8aeigskl5tmraedgji7v1lqbmqs8qv7u.example.com. 3600 IN RRSIG NSEC3 7 3 3600 20070926134150 20070829134150 57024 example.com. afV7c9knpxmD5c6UKrqw5J/06eokPwSb3HZi3TI63tzFcswuMjj4d7NKJmdpA+uo0aweVZgcOp+O+v9urgNYNYbxOy02qqOetLph8YWH7MQTftaGBwKD7gZMbnUArryPCtrlJz0i0GzoWvVTZnsjrrlDtP/ogLDnCKyi7Q0si+k= ;{id = 57024}
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+a.wild.example.com. IN MX
+SECTION ANSWER
+SECTION AUTHORITY
+; wildcard no data
+example.com. IN SOA ns.example.com. noc.example.com. 2009310622 1800 900 604800 86400
+example.com. 3600 IN RRSIG SOA 7 2 3600 20070926134150 20070829134150 57024 example.com. HlyER7bYPiSJ9jdjjRBucQexYr932Oor1TvxSLPWw5fuWvr/fFitKVnLqC+lqBIeOby44KiDr0rIk+ZqYjWWKNjaLm5wMfhQzbsAgGTQxmO07jnYOGQG9SI6DSbR9GJdZ7imu5sx5oo5dze73MxgLMZIethGaFMkktYN53+AzG0= ;{id = 57024}
+; wild.example.com -> 8aeigskl5tmraedgji7v1lqbmqs8qv7u.
+; *.wild.example.com. -> nvec78au1hpuma9eebeji5n06eq33gbk.
+; the NSEC3 for the wildcard *.wild.example.com. , with optout, A RRSIG
+nvec78au1hpuma9eebeji5n06eq33gbk.example.com. IN NSEC3 1 1 0 - ovec78au1hpuma9eebeji5n06eq33gbk A RRSIG
+nvec78au1hpuma9eebeji5n06eq33gbk.example.com. 3600 IN RRSIG NSEC3 7 3 3600 20070926134150 20070829134150 57024 example.com. jE+b5p+stQumm+tLZdaBT+KBpwYI7wRXijRHWcqiUp2SY1uV7HxBdW8aedVTqpFe8kYbMUgI3pCOAitmiI9R6SJg3q7022QOb9y+0/xSmIDqxATVPTJbkzVBInfWrulRtn7o3HmOyoIc9/w7NnNxFYpwtFL08jTBRr8XRTWDM7Q= ;{id = 57024}
+; NSEC3 for the closest encloser, wild.example.com. (an empty nonterminal)
+8aeigskl5tmraedgji7v1lqbmqs8qv7u.example.com. IN NSEC3 1 1 0 - 9aeigskl5tmraedgji7v1lqbmqs8qv7u
+8aeigskl5tmraedgji7v1lqbmqs8qv7u.example.com. 3600 IN RRSIG NSEC3 7 3 3600 20070926134150 20070829134150 57024 example.com. afV7c9knpxmD5c6UKrqw5J/06eokPwSb3HZi3TI63tzFcswuMjj4d7NKJmdpA+uo0aweVZgcOp+O+v9urgNYNYbxOy02qqOetLph8YWH7MQTftaGBwKD7gZMbnUArryPCtrlJz0i0GzoWvVTZnsjrrlDtP/ogLDnCKyi7Q0si+k= ;{id = 57024}
+; a.wild.example.com -> ad1535hlgg914unuuaei9jfh4ofr44uo. covered by optout
+ac1535hlgg914unuuaei9jfh4ofr44uo.example.com. IN NSEC3 1 1 0 - ae1535hlgg914unuuaei9jfh4ofr44uo NS RRSIG
+ac1535hlgg914unuuaei9jfh4ofr44uo.example.com. 3600 IN RRSIG NSEC3 7 3 3600 20070926134150 20070829134150 57024 example.com. imoxsXE1c3FaXu6uSantJfMPGBgsauf1GhmNpS1lLuaNRjXOhf1PDXwt/GoD/dm2GXJAlWT8u6EK3RXkFwlDIsP7vYFuDfUNCQ/hvYq300sXl1nfW0O1bsoBJahQJuNM+xcbwbnQf0krCTxNthyi2cuiY7RYug6ZTZ3gz4DMkhU= ;{id = 57024}
+ENTRY_END
+
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+sub.example.com. IN MX
+ENTRY_END
+
+; recursion happens here.
+; no AD flag on this because an optout NSEC3 is used.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA DO NOERROR
+SECTION QUESTION
+sub.example.com. IN MX
+SECTION ANSWER
+SECTION AUTHORITY
+example.com. IN SOA ns.example.com. noc.example.com. 2009310622 1800 900 604800 86400
+example.com. 3600 IN RRSIG SOA 7 2 3600 20070926134150 20070829134150 57024 example.com. HlyER7bYPiSJ9jdjjRBucQexYr932Oor1TvxSLPWw5fuWvr/fFitKVnLqC+lqBIeOby44KiDr0rIk+ZqYjWWKNjaLm5wMfhQzbsAgGTQxmO07jnYOGQG9SI6DSbR9GJdZ7imu5sx5oo5dze73MxgLMZIethGaFMkktYN53+AzG0= ;{id = 57024}
+onib9mgub9h0rml3cdf5bgrj59dkjhvk.example.com. NSEC3 1 1 0 - pnib9mgub9h0rml3cdf5bgrj59dkjhvk NS SOA RRSIG DNSKEY NSEC3PARAM
+onib9mgub9h0rml3cdf5bgrj59dkjhvk.example.com. 3600 IN RRSIG NSEC3 7 3 3600 20070926134150 20070829134150 57024 example.com. jHrF+lnyRL1LE/Bwz6C+jZg3E/2qQkVSboGxya6iX71v0zA3eUsob9m9l3gHNlhwhyahbamHUKx+OMvtYuzRa+RMv4ObuLRIt8StdixeXaUU+rx7C2qCKOFsa5q4HzK4bLYPfyb5T9w67HbzHPLEllXPA7tghzyzCM9qBtbvwK4= ;{id = 57024}
+jg19n32806c832kijdnglq8p9m2r5mdj.example.com. NSEC3 1 1 0 - lg19n32806c832kijdnglq8p9m2r5mdj NS DS RRSIG
+jg19n32806c832kijdnglq8p9m2r5mdj.example.com. 3600 IN RRSIG NSEC3 7 3 3600 20070926134150 20070829134150 57024 example.com. f7ZSCahAuKOLXquM0jpdU6I9AX31CgGicRiB3aU4jvqQp/EygbCNn5kfpyXY0FvZvzggpl8naXSStOPN9dy3bb0NwGQkJcYD94NEw307T8uEunOvx1ug5TuakBAwqjY8xKM3xab3LnWYRtx4zdln/3ZDHvBUwfzkxUZrzeKjpiI= ;{id = 57024}
+SECTION ADDITIONAL
+ENTRY_END
+
+STEP 20 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+sub.example.com. IN DS
+ENTRY_END
+
+; recursion happens here.
+; no AD flag here because of RFC5155 9.2 section.
+; even though we are sure there is no DS, this is what the RFC says.
+STEP 30 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA DO NOERROR
+SECTION QUESTION
+sub.example.com. IN DS
+SECTION ANSWER
+SECTION AUTHORITY
+example.com. IN SOA ns.example.com. noc.example.com. 2009310622 1800 900 604800 86400
+example.com. 3600 IN RRSIG SOA 7 2 3600 20070926134150 20070829134150 57024 example.com. HlyER7bYPiSJ9jdjjRBucQexYr932Oor1TvxSLPWw5fuWvr/fFitKVnLqC+lqBIeOby44KiDr0rIk+ZqYjWWKNjaLm5wMfhQzbsAgGTQxmO07jnYOGQG9SI6DSbR9GJdZ7imu5sx5oo5dze73MxgLMZIethGaFMkktYN53+AzG0= ;{id = 57024}
+onib9mgub9h0rml3cdf5bgrj59dkjhvk.example.com. NSEC3 1 1 0 - pnib9mgub9h0rml3cdf5bgrj59dkjhvk NS SOA RRSIG DNSKEY NSEC3PARAM
+onib9mgub9h0rml3cdf5bgrj59dkjhvk.example.com. 3600 IN RRSIG NSEC3 7 3 3600 20070926134150 20070829134150 57024 example.com. jHrF+lnyRL1LE/Bwz6C+jZg3E/2qQkVSboGxya6iX71v0zA3eUsob9m9l3gHNlhwhyahbamHUKx+OMvtYuzRa+RMv4ObuLRIt8StdixeXaUU+rx7C2qCKOFsa5q4HzK4bLYPfyb5T9w67HbzHPLEllXPA7tghzyzCM9qBtbvwK4= ;{id = 57024}
+jg19n32806c832kijdnglq8p9m2r5mdj.example.com. NSEC3 1 1 0 - lg19n32806c832kijdnglq8p9m2r5mdj NS DS RRSIG
+jg19n32806c832kijdnglq8p9m2r5mdj.example.com. 3600 IN RRSIG NSEC3 7 3 3600 20070926134150 20070829134150 57024 example.com. f7ZSCahAuKOLXquM0jpdU6I9AX31CgGicRiB3aU4jvqQp/EygbCNn5kfpyXY0FvZvzggpl8naXSStOPN9dy3bb0NwGQkJcYD94NEw307T8uEunOvx1ug5TuakBAwqjY8xKM3xab3LnWYRtx4zdln/3ZDHvBUwfzkxUZrzeKjpiI= ;{id = 57024}
+SECTION ADDITIONAL
+ENTRY_END
+
+STEP 40 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+rub.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+; no AD flag here because of RFC5155 9.2 section.
+; also for NXDOMAIN
+STEP 50 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA DO NXDOMAIN
+SECTION QUESTION
+rub.example.com. IN A
+SECTION ANSWER
+SECTION AUTHORITY
+example.com. IN SOA ns.example.com. noc.example.com. 2009310622 1800 900 604800 86400
+example.com. 3600 IN RRSIG SOA 7 2 3600 20070926134150 20070829134150 57024 example.com. HlyER7bYPiSJ9jdjjRBucQexYr932Oor1TvxSLPWw5fuWvr/fFitKVnLqC+lqBIeOby44KiDr0rIk+ZqYjWWKNjaLm5wMfhQzbsAgGTQxmO07jnYOGQG9SI6DSbR9GJdZ7imu5sx5oo5dze73MxgLMZIethGaFMkktYN53+AzG0= ;{id = 57024}
+onib9mgub9h0rml3cdf5bgrj59dkjhvk.example.com. NSEC3 1 1 0 - pnib9mgub9h0rml3cdf5bgrj59dkjhvk NS SOA RRSIG DNSKEY NSEC3PARAM
+onib9mgub9h0rml3cdf5bgrj59dkjhvk.example.com. 3600 IN RRSIG NSEC3 7 3 3600 20070926134150 20070829134150 57024 example.com. jHrF+lnyRL1LE/Bwz6C+jZg3E/2qQkVSboGxya6iX71v0zA3eUsob9m9l3gHNlhwhyahbamHUKx+OMvtYuzRa+RMv4ObuLRIt8StdixeXaUU+rx7C2qCKOFsa5q4HzK4bLYPfyb5T9w67HbzHPLEllXPA7tghzyzCM9qBtbvwK4= ;{id = 57024}
+22bqk3tb4foaenfbp1v0pdk6mor3r7vo.example.com. NSEC3 1 1 0 - f2bqk3tb4foaenfbp1v0pdk6mor3r7vo NS RRSIG
+22bqk3tb4foaenfbp1v0pdk6mor3r7vo.example.com. 3600 IN RRSIG NSEC3 7 3 3600 20070926134150 20070829134150 57024 example.com. jk6EYU9qTrmNeeKuQRG7iKyfNJnBt45MToPVpAQ+LoGDC3muy4bkWeKspj68cN9E5wNijfmm1eFK3khSSEnM50mfJbpiwlbKgL0VZz33Zn+Wu8b7sTtdDwDH7MUBLRwHeb7W+NtQIEXPLs4Z3BXHzAXy5ZpSjQ3PJZn6zBx4/dw= ;{id = 57024}
+SECTION ADDITIONAL
+ENTRY_END
+
+STEP 60 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+a.wild.example.com. IN A
+ENTRY_END
+
+; query is a wildcard expansion, covered by optout.
+; hence it is without AD flag (even though we are sure this wildcard exists,
+; we are not sure that there is no delegation covered by the optout span
+; with the name a.wild.example.com).
+STEP 70 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA DO NOERROR
+SECTION QUESTION
+a.wild.example.com. IN A
+SECTION ANSWER
+a.wild.example.com. IN A 77.88.99.0
+a.wild.example.com. 3600 IN RRSIG A 7 3 3600 20070926134150 20070829134150 57024 example.com. GWV6cQprrpAsaYla5z7N9tppdb+X0ZjOsiWBuBueSACHU8CzsYPMbwKUZlTNbQ4mSVRRDa0rM1niYoZF9oqyAfbn5HBLi62TRjrBLHfvatDgSiZCa4mauUfzUS+U7FfUXikNIigG0aN0xdpJ//urmecjNSKg2aW4M0DYsm7keMI= ;{id = 57024}
+SECTION AUTHORITY
+ac1535hlgg914unuuaei9jfh4ofr44uo.example.com. IN NSEC3 1 1 0 - ae1535hlgg914unuuaei9jfh4ofr44uo NS RRSIG
+ac1535hlgg914unuuaei9jfh4ofr44uo.example.com. 3600 IN RRSIG NSEC3 7 3 3600 20070926134150 20070829134150 57024 example.com. imoxsXE1c3FaXu6uSantJfMPGBgsauf1GhmNpS1lLuaNRjXOhf1PDXwt/GoD/dm2GXJAlWT8u6EK3RXkFwlDIsP7vYFuDfUNCQ/hvYq300sXl1nfW0O1bsoBJahQJuNM+xcbwbnQf0krCTxNthyi2cuiY7RYug6ZTZ3gz4DMkhU= ;{id = 57024}
+8aeigskl5tmraedgji7v1lqbmqs8qv7u.example.com. IN NSEC3 1 1 0 - 9aeigskl5tmraedgji7v1lqbmqs8qv7u
+8aeigskl5tmraedgji7v1lqbmqs8qv7u.example.com. 3600 IN RRSIG NSEC3 7 3 3600 20070926134150 20070829134150 57024 example.com. afV7c9knpxmD5c6UKrqw5J/06eokPwSb3HZi3TI63tzFcswuMjj4d7NKJmdpA+uo0aweVZgcOp+O+v9urgNYNYbxOy02qqOetLph8YWH7MQTftaGBwKD7gZMbnUArryPCtrlJz0i0GzoWvVTZnsjrrlDtP/ogLDnCKyi7Q0si+k= ;{id = 57024}
+ENTRY_END
+
+STEP 80 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+a.wild.example.com. IN MX
+ENTRY_END
+
+; nodata wildcard expansion, we are sure that the wildcard does not have
+; the data that is requested, but there an optout flag set on the wildcard
+; expansion denial, thus we are not sure of a.wild.example.com delegation
+; under the optout.
+STEP 90 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA DO NOERROR
+SECTION QUESTION
+a.wild.example.com. IN MX
+SECTION ANSWER
+SECTION AUTHORITY
+example.com. IN SOA ns.example.com. noc.example.com. 2009310622 1800 900 604800 86400
+example.com. 3600 IN RRSIG SOA 7 2 3600 20070926134150 20070829134150 57024 example.com. HlyER7bYPiSJ9jdjjRBucQexYr932Oor1TvxSLPWw5fuWvr/fFitKVnLqC+lqBIeOby44KiDr0rIk+ZqYjWWKNjaLm5wMfhQzbsAgGTQxmO07jnYOGQG9SI6DSbR9GJdZ7imu5sx5oo5dze73MxgLMZIethGaFMkktYN53+AzG0= ;{id = 57024}
+nvec78au1hpuma9eebeji5n06eq33gbk.example.com. IN NSEC3 1 1 0 - ovec78au1hpuma9eebeji5n06eq33gbk A RRSIG
+nvec78au1hpuma9eebeji5n06eq33gbk.example.com. 3600 IN RRSIG NSEC3 7 3 3600 20070926134150 20070829134150 57024 example.com. jE+b5p+stQumm+tLZdaBT+KBpwYI7wRXijRHWcqiUp2SY1uV7HxBdW8aedVTqpFe8kYbMUgI3pCOAitmiI9R6SJg3q7022QOb9y+0/xSmIDqxATVPTJbkzVBInfWrulRtn7o3HmOyoIc9/w7NnNxFYpwtFL08jTBRr8XRTWDM7Q= ;{id = 57024}
+8aeigskl5tmraedgji7v1lqbmqs8qv7u.example.com. IN NSEC3 1 1 0 - 9aeigskl5tmraedgji7v1lqbmqs8qv7u
+8aeigskl5tmraedgji7v1lqbmqs8qv7u.example.com. 3600 IN RRSIG NSEC3 7 3 3600 20070926134150 20070829134150 57024 example.com. afV7c9knpxmD5c6UKrqw5J/06eokPwSb3HZi3TI63tzFcswuMjj4d7NKJmdpA+uo0aweVZgcOp+O+v9urgNYNYbxOy02qqOetLph8YWH7MQTftaGBwKD7gZMbnUArryPCtrlJz0i0GzoWvVTZnsjrrlDtP/ogLDnCKyi7Q0si+k= ;{id = 57024}
+ac1535hlgg914unuuaei9jfh4ofr44uo.example.com. IN NSEC3 1 1 0 - ae1535hlgg914unuuaei9jfh4ofr44uo NS RRSIG
+ac1535hlgg914unuuaei9jfh4ofr44uo.example.com. 3600 IN RRSIG NSEC3 7 3 3600 20070926134150 20070829134150 57024 example.com. imoxsXE1c3FaXu6uSantJfMPGBgsauf1GhmNpS1lLuaNRjXOhf1PDXwt/GoD/dm2GXJAlWT8u6EK3RXkFwlDIsP7vYFuDfUNCQ/hvYq300sXl1nfW0O1bsoBJahQJuNM+xcbwbnQf0krCTxNthyi2cuiY7RYug6ZTZ3gz4DMkhU= ;{id = 57024}
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/val_nsec3_optout_ns_ad.rpl b/tests/integration/deckard/sets/resolver/val_nsec3_optout_ns_ad.rpl
new file mode 100644
index 0000000..038a199
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_nsec3_optout_ns_ad.rpl
@@ -0,0 +1,205 @@
+do-ip6: no
+
+; config options
+ stub-addr: 193.0.14.129
+ trust-anchor: ". IN DS 49060 8 2 E7B1EB56D7D5791B3D45630FEAA9C823DB84B385ACEEAC5F44DD08885C36700F"
+ val-override-date: "20170807130000"
+ query-minimization: off
+ harden-glue: off
+CONFIG_END
+
+SCENARIO_BEGIN Test not setting AD bit for answer which contains proof of nonexistence of NS record using NSEC3 with opt-out
+
+RANGE_BEGIN 1 2
+ ADDRESS 193.0.14.129 ;k.root-servers.net
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RD AA AD NOERROR
+SECTION QUESTION
+. IN SOA
+SECTION ANSWER
+. 86400 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2017030902 1800 900 604800 86400
+. 86400 IN RRSIG SOA 8 0 86400 20170901125744 20170802125744 20661 . uhdJY+sNwlQSb8TtF3WffXadfjNp3/XguyeJ7FKF1Rxr7WPG2asG70U+ Ltj1GFZkpcS+75ifMTJ7Ykc082KSRyh1pmMKQSiY9lPdiOX6muq+kBdX h6jkwI+FrCcrBDzhrH6A4XMcTlNj3lBxrUI7lsQyw2I/nwzsTEiTI+1/ mK5zQKA/pnMepKr4CUSS78f/tT955wm3slms5laQSfxqrakPCSwkRtlM xrXPJnjc34MLVpiItgzuQqCrCb+Rak2QNAVkNKfkvBMxJDmRXoz5BTTQ 4huaJWeOFyvIomZwBseFBDSyS5QYCEfMLo0+R/xc/KjzfVuYG8J0dClM kjnMEw==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RD AA AD NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. 518400 IN NS k.root-servers.net.
+. 518400 IN RRSIG NS 8 0 518400 20170901125744 20170802125744 20661 . VDSzCYw6B8u9cLz5BJuzDtRfmc/iGmD3Vei9TPthggi2lwE4HJ6uxYPt HRuczjHOYJcBzJSL1vh/myUHZXysGiGtEASbKZyWnk0uGf//68sPyQLX +QbhvrjHHP17HOsH8ZaCQUvGD2q7yhTtiGlLPRRxUUA7TQ4e7HRMfzo7 R2g/U3mbzfvJctGrng08r2VPdFndE7H7deef9YJjQ32vJSaDzp0qVtwA q0RO6xfMcUHvAzxFVWkWqUkhbXoBv08xz9O182g2a7lCJlxKD1NbbJ9Y Ob4PFtvK9bL8PUlS3DK4GMsZ8XpTLX2lEUedulX4Jn0fHz5pYk2TEMF6 YuJAWA==
+
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RD AA AD NOERROR
+SECTION QUESTION
+. IN DNSKEY
+SECTION ANSWER
+. 3600000 IN DNSKEY 256 3 8 AwEAAe1oA46eOLNris1CtS0qM5TdMESK6i4hpalqa6JDv57eOUkaOeje ZW1tIFUokmaK7kuKEFEosddA89CYM8rt2RbC+sfKalbHAWOus0tXZyAL efb2sW95QRzyG6LNul0jQFn9eYWBUHrVe5Wqd0zrFCbTQLUhELSfrlkI UBpO/xKaGinRHX2JjyOnle4aPZY3bEVa/+KyY2ZU6UC4SBo3aHXanP26 ok91rOTmpTWp64ybsMdCXOU8deyuQFQf6q8DhIDmJrkymhX1MXWQQlE0 fAYIYf8/t9OCwucg8oEg4FPU8Gb4Zm/l6PgO4HFkFjBT6iGFCQt3qXe2 Qe3alUWoATc=
+. 3600000 IN DNSKEY 257 3 8 AwEAAb8sZgVVa02muJ+/+SVhJAvz2EWKGEGquhPbQXuF6ALBYoF4KWTO bZVF8sIVTGoaX5+UWkwwHthg7RwS1DALT/AJymYeHhUwA04gLsfCZ/cv BjmRy5RozeSJ1uxAhoCYHCT2hQBZ0cH0n8roXFXI2Y+6708pO1IBkTPT 9MpAGfezTtGYOortbSn+vqT/Zu8jOpNwkleXON4rlZRBZPd4JUMGL9Y5 N/j6+ClYeM+eFQTKXrLi1oC+0yK1sG5OlqrBDhAhBnz+IhfZz4TOkqJ9 Li2BVMatHBeB9GQHtu0FZuC3J0EQgiZxvq1RgkefFJAiB+5uVRN8U7up 5mLDxSgmT0M=
+. 2592000 IN RRSIG DNSKEY 8 0 3600000 20170901125744 20170802125744 20661 . Oq/hUNG3VoToA2eT4gd32ALxOCXcR8TQwr+vSXEe6/hReGQdANdbyhFU stwNldw61ZD61MBUORY4YEmlpOsOAEpFB9pw2Me41GHdbtLCwcr5RTD4 6e/qBAdthoglLG53jObrp0nBJclLgoWfm4Rmn3DPIKcMoch/W5MmdWGj 7bC4xChMBWDYLPaqYm5PWgpMdHl60Sq9H/dkkWBvRuqPrN2ATBCoHjUE 6UGZM60AZPRuhqHogqvSiNEEEweqN7KK60dQy65dIMFh0iUCaw2/HDB5 NS30lMqxdJY6xAX1uNMIf6UhdFYFBqHClRUqJcOA7IqskkKel6ZC8Rpg 3qruFg==
+. 2592000 IN RRSIG DNSKEY 8 0 3600000 20170901125744 20170802125744 49060 . eYrzIaVlmMtByHu35+Fu1yUlRkfwZLEPQXspIq7dZzL06H8gBz11/FBE YAvpgYrACeLmEuj3NrWp+2odPrWo23usyvbDiUC1U242trYa4F5qUBKt JtXiHVwMhu+Xg4D5JAXU27itt0XHIKyOAZx6ifuZUvYTvfEtgPm+2Bal uenCi7/ZsBLpOOvB+Wjr+xpxMJILIABvfdgPWCCRh5JiYdhhldJCTA6J MQ5yUlf57OvFOQdnUP6xz+FjTAJWPO2rlc47sRaucKr1i/cQzLaqT2ui +zlunVo7lFq2zNZPRz7zRktO1iDp2Bz7rX+o4DTFVk2gxbcF2x3VAckM +dIgWw==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype
+ADJUST copy_id copy_query
+REPLY QR RD AA REFUSED
+SECTION QUESTION
+. IN RRSIG
+SECTION ANSWER
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RD AA AD NXDOMAIN
+SECTION QUESTION
+li. IN NS
+SECTION AUTHORITY
+. 86400 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2017030902 1800 900 604800 86400
+. 86400 IN RRSIG SOA 8 0 86400 20170901125744 20170802125744 20661 . uhdJY+sNwlQSb8TtF3WffXadfjNp3/XguyeJ7FKF1Rxr7WPG2asG70U+ Ltj1GFZkpcS+75ifMTJ7Ykc082KSRyh1pmMKQSiY9lPdiOX6muq+kBdX h6jkwI+FrCcrBDzhrH6A4XMcTlNj3lBxrUI7lsQyw2I/nwzsTEiTI+1/ mK5zQKA/pnMepKr4CUSS78f/tT955wm3slms5laQSfxqrakPCSwkRtlM xrXPJnjc34MLVpiItgzuQqCrCb+Rak2QNAVkNKfkvBMxJDmRXoz5BTTQ 4huaJWeOFyvIomZwBseFBDSyS5QYCEfMLo0+R/xc/KjzfVuYG8J0dClM kjnMEw==
+ca5qlot3gsobijfasusg7dvc5kdtgp4e. 86400 IN NSEC3 1 1 10 AE83CC9CD22A4A92 QVMFNLQ9AOEGUQEMOCFD5HGN8L8VAPHO NS SOA RRSIG DNSKEY NSEC3PARAM
+ca5qlot3gsobijfasusg7dvc5kdtgp4e. 86400 IN RRSIG NSEC3 8 1 86400 20170901125744 20170802125744 20661 . TLye07FnnjtPSZ0pUMJ4OToH9evHpuj7Yb6ktj1W1bDLqxYcmbTc1jZu IWe4wn/pLz5/78sigR+KKkP6L/Ki0ZVG8fcmR546Jp4o0+fGVkAqbRyc /kckl4QsHqR4UiMrIDhc/MQHnaje/bNrGka+7pQOnvmRyUo0jSHuVfFI LdKMZpk5seTZKI0k/WgmrDYuFii4HqT8+RB9/uoFVPlSSI/rYJ2G4Wgt t81732pO5Kqcwp7DFKvkkj7yU84zlDXtT7RuF21OCACAUseiCX/GOTGf 8OvZp8Rdfs1wT5LjjWl5Gb23Arr9o4soGsyEbXeaoyw7OVYZzXlEko1l yBm5+g==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RD AA AD NOERROR
+SECTION QUESTION
+net. IN NS
+SECTION AUTHORITY
+. 86400 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2017030902 1800 900 604800 86400
+22n8oi3qtiud0dier2bbl2ktforlp60c. 86400 IN NSEC3 1 1 10 AE83CC9CD22A4A92 8HBQQS31TETVRFABEIIF3K7LHPOL93GD
+. 86400 IN RRSIG SOA 8 0 86400 20170901125744 20170802125744 20661 . uhdJY+sNwlQSb8TtF3WffXadfjNp3/XguyeJ7FKF1Rxr7WPG2asG70U+ Ltj1GFZkpcS+75ifMTJ7Ykc082KSRyh1pmMKQSiY9lPdiOX6muq+kBdX h6jkwI+FrCcrBDzhrH6A4XMcTlNj3lBxrUI7lsQyw2I/nwzsTEiTI+1/ mK5zQKA/pnMepKr4CUSS78f/tT955wm3slms5laQSfxqrakPCSwkRtlM xrXPJnjc34MLVpiItgzuQqCrCb+Rak2QNAVkNKfkvBMxJDmRXoz5BTTQ 4huaJWeOFyvIomZwBseFBDSyS5QYCEfMLo0+R/xc/KjzfVuYG8J0dClM kjnMEw==
+22n8oi3qtiud0dier2bbl2ktforlp60c. 86400 IN RRSIG NSEC3 8 1 86400 20170901125744 20170802125744 20661 . K4bXakkrwj5gxNs4JzI/vEjHAKIyT5uYmh56g1pN8r/fOpiarYqtCAue 9oRIK7uk9p3R75n/HYZGfZnF8sfxPKOdTmFDhHtdNbQsqzAz1AOzk1bD 6US62xZQHApINFCHSLJzBch2V3o4/Vb2k5aQQp2mGe5HQzTvCn9JKgRY eRgfJbnN3acVtjT46ggIp7wqQAWNKNakaV2+ad9TgyoOO9/64IDF9Z4a oehlzT+iMHzDk9noOlf67Qvmx79x1pvUCRVA57VQpw0mNnDQCvVQ2Avq IJGiM4SQxyGyeSFqJpLTzboCl8uLy6DaSaeJvtAYIRj3x2kDrW9NfUL3 EQHBOg==
+
+
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RD AA AD NOERROR
+SECTION QUESTION
+root-servers.net. IN NS
+SECTION AUTHORITY
+. 86400 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2017030902 1800 900 604800 86400
+22n8oi3qtiud0dier2bbl2ktforlp60c. 86400 IN NSEC3 1 1 10 AE83CC9CD22A4A92 8HBQQS31TETVRFABEIIF3K7LHPOL93GD
+. 86400 IN RRSIG SOA 8 0 86400 20170901125744 20170802125744 20661 . uhdJY+sNwlQSb8TtF3WffXadfjNp3/XguyeJ7FKF1Rxr7WPG2asG70U+ Ltj1GFZkpcS+75ifMTJ7Ykc082KSRyh1pmMKQSiY9lPdiOX6muq+kBdX h6jkwI+FrCcrBDzhrH6A4XMcTlNj3lBxrUI7lsQyw2I/nwzsTEiTI+1/ mK5zQKA/pnMepKr4CUSS78f/tT955wm3slms5laQSfxqrakPCSwkRtlM xrXPJnjc34MLVpiItgzuQqCrCb+Rak2QNAVkNKfkvBMxJDmRXoz5BTTQ 4huaJWeOFyvIomZwBseFBDSyS5QYCEfMLo0+R/xc/KjzfVuYG8J0dClM kjnMEw==
+22n8oi3qtiud0dier2bbl2ktforlp60c. 86400 IN RRSIG NSEC3 8 1 86400 20170901125744 20170802125744 20661 . K4bXakkrwj5gxNs4JzI/vEjHAKIyT5uYmh56g1pN8r/fOpiarYqtCAue 9oRIK7uk9p3R75n/HYZGfZnF8sfxPKOdTmFDhHtdNbQsqzAz1AOzk1bD 6US62xZQHApINFCHSLJzBch2V3o4/Vb2k5aQQp2mGe5HQzTvCn9JKgRY eRgfJbnN3acVtjT46ggIp7wqQAWNKNakaV2+ad9TgyoOO9/64IDF9Z4a oehlzT+iMHzDk9noOlf67Qvmx79x1pvUCRVA57VQpw0mNnDQCvVQ2Avq IJGiM4SQxyGyeSFqJpLTzboCl8uLy6DaSaeJvtAYIRj3x2kDrW9NfUL3 EQHBOg==
+
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RD AA AD NOERROR
+SECTION QUESTION
+ns.net. IN A
+SECTION ANSWER
+ns.net. 600 IN A 1.1.1.1
+ns.net. 600 IN RRSIG A 8 2 600 20170901125744 20170802125744 20661 . Z0VIqlE9FUERy2IRsAQ5Nv8JYhr4Mn6kz29NyAaxVQqokEf3pF760PyA UEpSoBENsnWU+x/2XDSkdlyyJQbUpwZhLDAdXgLQUCg+E+1CFFj1A9Zg zCf0oZ6PsCKyTrHCshyHDQNe+iIWO8Qn3qwoAeytIc3ztSQTkP2s8Tys ZoG/+5dqaCICPOoiVVh7usl7WC8SZn4hVRnU64w+Wxziy3anROZ/pUq9 9DI+7+zb2vEteA0sM151akjAtekFiRuqzjgnBpUiH6j4hgGkoH5NCvkD HD37jMZg4D9jmE7O7X3puAuson2DURvjuoHtZRsLRypglRDmlaRThoff l0BmAw==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RD AA AD NOERROR
+SECTION QUESTION
+k.root-servers.net. IN A
+SECTION ANSWER
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 2592000 IN RRSIG A 8 3 3600000 20170901125744 20170802125744 20661 . s+A2gmeRqZMgJZsuv7hn8qeHk/DIpoH1ZC5resAX7yhZwCxcQM+mNJ7E Jy7qC9PYBrta7rdeNuDKYuHJBlFZECaV/HZ7+f3SBPEiW9DYUI3SnNOR qyBaJGvuTjoQTWU4FVGe2T/ybroq6HzSx0xKSSHyMQeQFxk9wI86npjF cWm19ddCCwJ2uOrJspZwN8jidDbR//G8ntolmU2RzLKDqInLLqoBs1VF SE5Dqzx9eg4boKmUM3IQIJkVQppyGuMSIDNTh1IbPxZrtMgsh3+o9rds ZcIe5A8TRumEaRrXyJiTXQ25kZkZ0ilPyxWrjFRhjfHFcNX+aFpvwhtH cU6BSw==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RD AA AD NXDOMAIN
+SECTION QUESTION
+k.root-servers.net. IN AAAA
+SECTION AUTHORITY
+. 86400 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2017030902 1800 900 604800 86400
+c27sd6l4gd20p5e9ttq5br5a4q7scnf7. 86400 IN NSEC3 1 1 10 AE83CC9CD22A4A92 CA5QLOT3GSOBIJFASUSG7DVC5KDTGP4E A RRSIG
+. 86400 IN RRSIG SOA 8 0 86400 20170901125744 20170802125744 20661 . uhdJY+sNwlQSb8TtF3WffXadfjNp3/XguyeJ7FKF1Rxr7WPG2asG70U+ Ltj1GFZkpcS+75ifMTJ7Ykc082KSRyh1pmMKQSiY9lPdiOX6muq+kBdX h6jkwI+FrCcrBDzhrH6A4XMcTlNj3lBxrUI7lsQyw2I/nwzsTEiTI+1/ mK5zQKA/pnMepKr4CUSS78f/tT955wm3slms5laQSfxqrakPCSwkRtlM xrXPJnjc34MLVpiItgzuQqCrCb+Rak2QNAVkNKfkvBMxJDmRXoz5BTTQ 4huaJWeOFyvIomZwBseFBDSyS5QYCEfMLo0+R/xc/KjzfVuYG8J0dClM kjnMEw==
+c27sd6l4gd20p5e9ttq5br5a4q7scnf7. 86400 IN RRSIG NSEC3 8 1 86400 20170901125744 20170802125744 20661 . NN5tdEbFFwesLYRPUETJb3VNm+90RDAG2OmIvAIheZ8aD3rHp+n3WpWm xoQKDjYBLN49jLBz6zutZVdk5xJ4xfeuyKpckwn3L/sz0ej7XTTZrlpP yvatidBHR7MAwqUiGBLWOLtU2xt+DpIp5GLDLVlQs/pE/kfO/0WF7xZB 8Cf9QFl+eGSAOcsKK5aS0evT4PCM/YMpdzVcUhbS13apzEtyroAghpoy gOx6rNc3svzYYpRpt7Is9qlAY+d7EiFUCv0hnx7MwqkGuRqZFonA4dzt D5ds/+VwPvbo5o1TPQ74ZrToiD9Lkv/x/+qRYR3z1iKaXrUWEh5kLTpb UzSJ8A==
+
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RD AA AD NOERROR
+SECTION QUESTION
+. IN NSEC3PARAM
+SECTION ANSWER
+. 0 IN NSEC3PARAM 1 0 10 AE83CC9CD22A4A92
+. 0 IN RRSIG NSEC3PARAM 8 0 0 20170901125744 20170802125744 20661 . A11gI2rfHcW4SLbUVRCc2sg9wtgzICywN1hQNTyI2Un880S7PKiVzjEW woCBfSK/t1hMTtGOxSnkSGT7OILY200HZo3fJ9xEhXoeamdrtV2Ht7y2 GIO+MQ9B6y95y/N6PGNTDQIY7LC4D6JNeiSDg1j6joEiQ2LV4vwmYGQt Dl6N+Qx6S2ZSCiXCL4Gg1wvSGQK4DyDGDjYQd9KHsFnHjL6sqwHS5G09 s0JHvigAuYR0sG9/mqb0t+JyKXazpUS/MeaMYIIQnmQqDh37IZSDEPy9 IMbNd8x6El+DtCjC5TQGfDE1iCBr8NTxgkIM5zGLxl5pLzo5H4Z5QYZ2 TUy7DA==
+
+ENTRY_END
+RANGE_END
+
+RANGE_BEGIN 1 2
+ ADDRESS 1.1.1.1 ;ns.net
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RD AA NOERROR
+SECTION QUESTION
+li. IN SOA
+SECTION ANSWER
+li. 86400 IN SOA ns.net. hostmaster.example.com. 1234 1800 900 604800 86400
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RD AA NOERROR
+SECTION QUESTION
+li. IN NS
+SECTION ANSWER
+li. IN NS ns.net
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RD AA NOERROR
+SECTION QUESTION
+ns.net. IN A
+SECTION ANSWER
+ns.net. 86400 IN A 1.1.1.1
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD AD DO
+SECTION QUESTION
+li. IN NS
+ENTRY_END
+
+STEP 2 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NXDOMAIN ; AD flag is not set
+SECTION QUESTION
+li. IN NS
+SECTION ANSWER
+SECTION AUTHORITY
+. 86400 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2017030902 1800 900 604800 86400
+. 86400 IN RRSIG SOA 8 0 86400 20170901125744 20170802125744 20661 . uhdJY+sNwlQSb8TtF3WffXadfjNp3/XguyeJ7FKF1Rxr7WPG2asG70U+ Ltj1GFZkpcS+75ifMTJ7Ykc082KSRyh1pmMKQSiY9lPdiOX6muq+kBdX h6jkwI+FrCcrBDzhrH6A4XMcTlNj3lBxrUI7lsQyw2I/nwzsTEiTI+1/ mK5zQKA/pnMepKr4CUSS78f/tT955wm3slms5laQSfxqrakPCSwkRtlM xrXPJnjc34MLVpiItgzuQqCrCb+Rak2QNAVkNKfkvBMxJDmRXoz5BTTQ 4huaJWeOFyvIomZwBseFBDSyS5QYCEfMLo0+R/xc/KjzfVuYG8J0dClM kjnMEw==
+ca5qlot3gsobijfasusg7dvc5kdtgp4e. 86400 IN NSEC3 1 1 10 AE83CC9CD22A4A92 QVMFNLQ9AOEGUQEMOCFD5HGN8L8VAPHO NS SOA RRSIG DNSKEY NSEC3PARAM
+ca5qlot3gsobijfasusg7dvc5kdtgp4e. 86400 IN RRSIG NSEC3 8 1 86400 20170901125744 20170802125744 20661 . TLye07FnnjtPSZ0pUMJ4OToH9evHpuj7Yb6ktj1W1bDLqxYcmbTc1jZu IWe4wn/pLz5/78sigR+KKkP6L/Ki0ZVG8fcmR546Jp4o0+fGVkAqbRyc /kckl4QsHqR4UiMrIDhc/MQHnaje/bNrGka+7pQOnvmRyUo0jSHuVfFI LdKMZpk5seTZKI0k/WgmrDYuFii4HqT8+RB9/uoFVPlSSI/rYJ2G4Wgt t81732pO5Kqcwp7DFKvkkj7yU84zlDXtT7RuF21OCACAUseiCX/GOTGf 8OvZp8Rdfs1wT5LjjWl5Gb23Arr9o4soGsyEbXeaoyw7OVYZzXlEko1l yBm5+g==
+ENTRY_END
+
+SCENARIO_END \ No newline at end of file
diff --git a/tests/integration/deckard/sets/resolver/val_nsec3_optout_unsec_cache.rpl b/tests/integration/deckard/sets/resolver/val_nsec3_optout_unsec_cache.rpl
new file mode 100644
index 0000000..ad2f920
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_nsec3_optout_unsec_cache.rpl
@@ -0,0 +1,256 @@
+do-ip6: no
+
+; config options
+ trust-anchor: ". IN DS 19036 8 2 49AAC11D7B6F6446702E54A1607371607A1A41855200FD2CE1CDDE32F24E8FB5"
+ val-override-date: "20160220000000"
+ stub-addr: 202.12.27.33 # M.ROOT-SERVERS.NET.
+ query-minimization: off
+CONFIG_END
+
+SCENARIO_BEGIN Test validator NSEC3 B.3 referral to optout unsigned zone, cache timeout.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 202.12.27.33
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. 518400 IN NS a.root-servers.net.
+. 518400 IN NS b.root-servers.net.
+. 518400 IN NS c.root-servers.net.
+. 518400 IN NS d.root-servers.net.
+. 518400 IN NS e.root-servers.net.
+. 518400 IN NS f.root-servers.net.
+. 518400 IN NS g.root-servers.net.
+. 518400 IN NS h.root-servers.net.
+. 518400 IN NS i.root-servers.net.
+. 518400 IN NS j.root-servers.net.
+. 518400 IN NS k.root-servers.net.
+. 518400 IN NS l.root-servers.net.
+. 518400 IN NS m.root-servers.net.
+. 518400 IN RRSIG NS 8 0 518400 20160227170000 20160217160000 54549 . Qtgnr2k192gjdx3bLZgzkvqoEhTE4LXfFcPtrGPKawn/78LX6M4LuCZh rSXYMJERXVDQcQbX88EYh8kN3ALgLKpGdyu8HJ6B0vZiDc8yMbn2TuA0 RDqEPTp5om1LbQ0nEWa5XnrTi1fJTNzhT6eBJlcmkJ1/jMfmPG9J4dKJ x/Q=
+SECTION ADDITIONAL
+M.ROOT-SERVERS.NET. IN A 202.12.27.33
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RD RA AD
+SECTION QUESTION
+. IN DNSKEY
+SECTION ANSWER
+. 13943 IN DNSKEY 256 3 8 AwEAAbr/RV0stAWYbmKOldjShp4AOQGOyY3ATI1NUpP4X1qBs6lsXpc+1ABgv6zkg02IktjZrHnmD0HsElu3wqXMrT5KL1W7Spmg0Pou9WZ8QttdTKXwrVXrASsaGI2z/pLBSnK8EdzqUrTVxY4TEGZtxV519isM06CCMihxTn5cfFBF
+. 13943 IN DNSKEY 257 3 8 AwEAAagAIKlVZrpC6Ia7gEzahOR+9W29euxhJhVVLOyQbSEW0O8gcCjFFVQUTf6v58fLjwBd0YI0EzrAcQqBGCzh/RStIoO8g0NfnfL2MTJRkxoXbfDaUeVPQuYEhg37NZWAJQ9VnMVDxP/VHL496M/QZxkjf5/Efucp2gaDX6RS6CXpoY68LsvPVjR0ZSwzz1apAzvN9dlzEheX7ICJBBtuA6G3LQpzW5hOA2hzCTMjJPJ8LbqF6dsV6DoBQzgul0sGIcGOYl7OyQdXfZ57relSQageu+ipAdTTJ25AsRTAoub8ONGcLmqrAmRLKBP1dfwhYB4N7knNnulqQxA+Uk1ihz0=
+. 13943 IN RRSIG DNSKEY 8 0 172800 20160224235959 20160210000000 19036 . Y2Ktm7gpEXcFg02ZlPNaRhO+GUPSvB2z8tsqe199vO9Rx7tIT/8F2A6OBjiyR6GqPGcPKaXADAt+QjmV174123QJ6UDrk2cPiGPXfEleDlJVtBV5oAVaBedeZxqnmw9WpVCIV6cY5wZbO8mYltA5oZMg8XInokVm6qGPA4wo2Miai5st/KhY+2Ke29StiXeVDdQ4p3e25dE4z1QW3ISxJ0zqvkTMHgQZZiP7IlfXKlCyyrd/Ddrxd22GWY53/oy9/Bry4K8naAw4m5+Q5tEf2zvtiAoaIbi2cM3Lf8AzQU25I6zaERJeQXhyA8cqn4WrbsAANn128Q+9Aibyiol9xg==
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+a.b.sample.net. IN A
+SECTION ANSWER
+SECTION AUTHORITY
+net. 172800 IN NS a.gtld-servers.net.
+net. 86400 IN DS 35886 8 2 7862B27F5F516EBE19680444D4CE5E762981931842C465F00236401D8BD973EE
+net. 86400 IN RRSIG DS 8 1 86400 20160228050000 20160218040000 54549 . HXdj4gjShkf/LpyxcxthJyRJE/YAB+NHsbwkfoMJvcdJa6u6J0H4K55BSB5UdR6vFGtY5NHl8tnEQIUeHOrxqMzDoMLofs05So9CdphNhsOdR25sCXLAIAL6l9KfI0+oEFXrCNA2GpU1S6SjNmk0NPzslYBSjAVY8RkTNDJGwqE=
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+net. IN DNSKEY
+SECTION ANSWER
+net. 86400 IN DNSKEY 257 3 8 AQOYBnzqWXIEj6mlgXg4LWC0HP2n8eK8XqgHlmJ/69iuIHsa1TrHDG6TcOra/pyeGKwH0nKZhTmXSuUFGh9BCNiwVDuyyb6OBGy2Nte9Kr8NwWg4q+zhSoOf4D+gC9dEzg0yFdwT0DKEvmNPt0K4jbQDS4Yimb+uPKuF6yieWWrPYYCrv8C9KC8JMze2uT6NuWBfsl2fDUoV4l65qMww06D7n+p7RbdwWkAZ0fA63mXVXBZF6kpDtsYD7SUB9jhhfLQE/r85bvg3FaSs5Wi2BaqN06SzGWI1DHu7axthIOeHwg00zxlhTpoYCH0ldoQz+S65zWYi/fRJiyLSBb6JZOvn
+net. 86400 IN DNSKEY 256 3 8 AQPAQAy1b2gx5xTywO8c6kI7OGIMt8yhN1iAemwNkd67cv8CAqNuDi0M3uOIrsVofliQFwp5HgNeIHFWbf8KxUlueZ6Wol2LTe/LnK9QKrczPSHr+q+lEH0cCoe8Cwmuc9y3GwkxqFWGHPCsHLZyVMuvdr3cenc0fvk1dDL7Rg7AlQ==
+net. 86400 IN RRSIG DNSKEY 8 1 86400 20160301173857 20160215173357 35886 net. BHm4lkpvTReitAK4JpVCLStI+JBswb9OEEmdKCCiiGe8zt3aVb6A+b2YCaJcWSA/RRrzASaOWvW7Lb5gyqxV/quEdLgB+xrMlnVUUQclLsF4EvdPMRzm+i8fVK//uo3IPDp/uyzVwR8dRpbPuJud1Mhttt0JZTNg0KqJZQEbq0odNdVWGln6PrvXd8f7L4VUaEJQI5H2SiUD8Iz56+EGmV9a6KIEJDKC0tiwPd1gQChaa5JcJBE9z1baSDX3H1f/tprOz/2H2kr0SDAL4Pztik5uer3bETQtmUK0s9Bq16AKSb3Fjs31LF/7bVwWyOVzIZJlfGk19w7c0seBr7f4gA==SECTION AUTHORITY
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+a.b.sample.net. IN A
+SECTION ANSWER
+SECTION AUTHORITY
+sample.net. 172800 IN NS ns.sample.net.
+a1rt98bs5qgc9nfi51s9hci47uljg6jh.net. 86400 IN NSEC3 1 1 0 - A1RUUFFJKCT2Q54P78F8EJGJ8JBK7I8B NS SOA RRSIG DNSKEY NSEC3PARAM
+a1rt98bs5qgc9nfi51s9hci47uljg6jh.net. 86400 IN RRSIG NSEC3 8 2 86400 20160224061807 20160217050807 51128 net. N9aNNHsSDLSSXMHpw1Bo200V2dqtDc68f4JyCg4ZFCvIKSs5lNeiptWrdfbluQJmdhJK9gz6t3ITbFsnnJjLqwihBiiFbwd1FPctuMK3bGUpZfGXem+3zu4mGKzozQ8nr8KjDUX6fYoLri2vOuCv82a7vbp8RF/6QU6MqvsT4Qw=
+55j4p0id76bnr9pf6341vkh0aga83vi2.net. 86400 IN NSEC3 1 1 0 - 55JHR77O5IJ0MSJFOSIA68OGIQIN5N15 NS DS RRSIG
+55j4p0id76bnr9pf6341vkh0aga83vi2.net. 86400 IN RRSIG NSEC3 8 2 86400 20160223061458 20160216050458 51128 net. QGDWMjAF7ziCridkheQEMH42INj+mHGnPuor/UvkNr2nZz1DDSewqG6/6uQR9FFSzRXINCZT6fdwhoIyTfxfLlNNXxABSqauTFXJ4ZXaBvDh0kwPwFBYOGSeKFukNLDiBhiUVLeMa1Va0M3H7ehWcOn1jsH301KTwu+6F5n6b/Q=
+SECTION ADDITIONAL
+ns.sample.net. 172800 IN A 192.0.2.1
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+sample.net. IN DS
+SECTION ANSWER
+SECTION AUTHORITY
+a1rt98bs5qgc9nfi51s9hci47uljg6jh.net. 86400 IN NSEC3 1 1 0 - A1RUUFFJKCT2Q54P78F8EJGJ8JBK7I8B NS SOA RRSIG DNSKEY NSEC3PARAM
+a1rt98bs5qgc9nfi51s9hci47uljg6jh.net. 86400 IN RRSIG NSEC3 8 2 86400 20160224061807 20160217050807 51128 net. N9aNNHsSDLSSXMHpw1Bo200V2dqtDc68f4JyCg4ZFCvIKSs5lNeiptWrdfbluQJmdhJK9gz6t3ITbFsnnJjLqwihBiiFbwd1FPctuMK3bGUpZfGXem+3zu4mGKzozQ8nr8KjDUX6fYoLri2vOuCv82a7vbp8RF/6QU6MqvsT4Qw=
+net. 900 IN SOA a.gtld-servers.net. nstld.verisign-grs.com. 1455877597 1800 900 604800 86400
+net. 900 IN RRSIG SOA 8 1 900 20160226102637 20160219091637 51128 net. TDZlVntb/Dun6Ng0o5eeaXhJw+3HqEcoAEjwrd+xs1D1/+JlhIoP/bnrpcW0pkDxBf8Byg+Jx6J+y7jfPiEboL6aWzSZhX+bqgLGlKlU4oHf3ahUtuyEHxBZ0m/pPDGZQGW35U/9iZ3a1Ga1aPR4zsxoXfQLwwRpDfr3lGKGCrw=
+55j4p0id76bnr9pf6341vkh0aga83vi2.net. 86400 IN NSEC3 1 1 0 - 55JHR77O5IJ0MSJFOSIA68OGIQIN5N15 NS DS RRSIG
+55j4p0id76bnr9pf6341vkh0aga83vi2.net. 86400 IN RRSIG NSEC3 8 2 86400 20160223061458 20160216050458 51128 net. QGDWMjAF7ziCridkheQEMH42INj+mHGnPuor/UvkNr2nZz1DDSewqG6/6uQR9FFSzRXINCZT6fdwhoIyTfxfLlNNXxABSqauTFXJ4ZXaBvDh0kwPwFBYOGSeKFukNLDiBhiUVLeMa1Va0M3H7ehWcOn1jsH301KTwu+6F5n6b/Q=
+SECTION ADDITIONAL
+ENTRY_END
+RANGE_END
+
+RANGE_BEGIN 0 100
+ ADDRESS 192.0.2.1
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+a.b.sample.net. IN A
+SECTION ANSWER
+SECTION AUTHORITY
+b.sample.net. 6000 IN NS ns.b.sample.net
+SECTION ADDITIONAL
+ns.b.sample.net 6000 IN A 192.0.2.2
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+b.sample.net. IN DS
+SECTION ANSWER
+SECTION AUTHORITY
+sample.net. 180 IN SOA internal.sample.net. hostmaster.sample.com. 1455875127 90000 90000 90000 180
+SECTION ADDITIONAL
+ENTRY_END
+RANGE_END
+
+RANGE_BEGIN 10 10
+ ADDRESS 192.0.2.2
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+a.b.sample.net. IN A
+SECTION ANSWER
+a.b.sample.net. 20 IN A 192.0.2.3
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+RANGE_END
+
+;; must not be fetched due to cache
+RANGE_BEGIN 30 30
+ ADDRESS 192.0.2.2
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+a.b.sample.net. IN A
+SECTION ANSWER
+a.b.sample.net. 20 IN A 192.0.2.4
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+RANGE_END
+
+RANGE_BEGIN 50 50
+ ADDRESS 192.0.2.2
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+a.b.sample.net. IN A
+SECTION ANSWER
+a.b.sample.net. 20 IN A 192.0.2.5
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+RANGE_END
+
+
+STEP 10 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+a.b.sample.net. IN A
+ENTRY_END
+
+STEP 20 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH flags rcode question answer additional authority
+REPLY QR RD RA
+SECTION QUESTION
+a.b.sample.net. IN A
+SECTION ANSWER
+a.b.sample.net. IN A 192.0.2.3
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+;; cache hit
+STEP 30 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+a.b.sample.net. IN A
+ENTRY_END
+
+STEP 40 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH flags rcode question answer additional authority
+REPLY QR RD RA
+SECTION QUESTION
+a.b.sample.net. IN A
+SECTION ANSWER
+a.b.sample.net. IN A 192.0.2.3
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+STEP 45 TIME_PASSES ELAPSE 25
+
+STEP 50 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+a.b.sample.net. IN A
+ENTRY_END
+
+STEP 60 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH flags rcode question answer additional authority
+REPLY QR RD RA
+SECTION QUESTION
+a.b.sample.net. IN A
+SECTION ANSWER
+a.b.sample.net. IN A 192.0.2.5
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/val_nx.rpl b/tests/integration/deckard/sets/resolver/val_nx.rpl
new file mode 100644
index 0000000..902f713
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_nx.rpl
@@ -0,0 +1,156 @@
+do-ip6: no
+
+; config options
+; The island of trust is at example.com
+;server:
+ trust-anchor: "example.com. 3600 IN DS 2423 7 1 EA4E6A7A91013E6852DE309CC3CB764A4D09361A "
+val-override-date: "20181130121906"
+; target-fetch-policy: "0 0 0 0 0"
+; fake-sha1: yes
+
+;stub-zone:
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+query-minimization: off
+CONFIG_END
+
+SCENARIO_BEGIN Test validator with nxdomain response
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20181230101906 20181130101906 2423 example.com. jO3CKvk4qwSCUloEXF+oavs3JC3qE0RZZpYvlitBH6SBQXn7hUDkxJha DfeLHeqKGg+hexpwxAqQZ4yHtqJbyUKVrT5S+VulRJhM99iJeG86Tc23 2z+QjyNSjtvorngs6uRCavwDbazenVLaJtnUkduMQcLIUKEQKCT4bc7z x/s= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101906 20181130101906 2423 example.com. iR4Bz61Q80rARS0h/K5W2YcrJPz9Ng7Ho+s1WxWpMnJdvGKHziITbME6 RhWgUlNZr2iu+mUvNEbU/C9Oim97BuAvTHD2RoL94ztOM4JbvsxXA4x3 REaw97F+pRGWwHU2vkm51bhldjBkSzDVMcLUNZUCChaP3QwMy6+BS3UF se4= ;{id = 2854}
+ENTRY_END
+
+; response to DNSKEY priming query
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN DNSKEY
+SECTION ANSWER
+example.com. 3600 IN DNSKEY 256 3 7 AwEAAbtGXI8lGuiA26SCDh5c8/EkJP83aCerq4k9SGznAo4HuBlpvGLN 4m8hM0sdFIcTQLoBPyTYJi98VoXN5JcFaChlMERdnP5BSJubfPaqMYqJ EEh3knoelJrwddlgft9gC8J6n126ylu9ZYhZtadGaBshLOKHsfPDyfMn t2oJO0bV ;{id = 2854 (zsk), size = 1688b}
+example.com. 3600 IN RRSIG DNSKEY 7 2 3600 20181230101906 20181130101906 2423 example.com. G+PLIk1lfmNAvY64DUKXrsRP/EKyEyQC0Zma86KvQREH+IzAOYhcFF1W eLs0ZAAbbiUspz2xj8H2UNkWI2/1nPSHCYfKZuCfkqRONb/HaBhwS7AT gs0Jw/XmFSdVKZ4rgZqA8fRLiugZKIIhp96vu2begq8g6Z8hCkmSUyUP cyM= ;{id = 2854}
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20181230101906 20181130101906 2423 example.com. jO3CKvk4qwSCUloEXF+oavs3JC3qE0RZZpYvlitBH6SBQXn7hUDkxJha DfeLHeqKGg+hexpwxAqQZ4yHtqJbyUKVrT5S+VulRJhM99iJeG86Tc23 2z+QjyNSjtvorngs6uRCavwDbazenVLaJtnUkduMQcLIUKEQKCT4bc7z x/s= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101906 20181130101906 2423 example.com. iR4Bz61Q80rARS0h/K5W2YcrJPz9Ng7Ho+s1WxWpMnJdvGKHziITbME6 RhWgUlNZr2iu+mUvNEbU/C9Oim97BuAvTHD2RoL94ztOM4JbvsxXA4x3 REaw97F+pRGWwHU2vkm51bhldjBkSzDVMcLUNZUCChaP3QwMy6+BS3UF se4= ;{id = 2854}
+ENTRY_END
+
+; response to query of interest
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NXDOMAIN
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+SECTION AUTHORITY
+example.com. IN SOA ns.example.com. hostmaster.example.com. 2007090400 28800 7200 604800 18000
+example.com. 3600 IN RRSIG SOA 7 2 3600 20181230101906 20181130101906 2423 example.com. nvDfwhtBRatdQHu2tyCfoaE2HkgAXCm97CZOOx8Bg36MUblQDgwm55mP gaJQKsXxU9fOG9Nd7wkXZEYPvhnKFcUxtrFhHog9ouZtEsuS0w+E9cJX HqrI9L8m7URlQ7FZBaUjqlJGJNFgQbwZzfOvWDzSSzgBqj8emafNwOBg eQ4= ;{id = 2854}
+; wildcard denial
+example.com. IN NSEC abc.example.com. SOA NS DNSKEY NSEC RRSIG
+example.com. 3600 IN RRSIG NSEC 7 2 18000 20181230101906 20181130101906 2423 example.com. dabtLPYkmc3k6LXDJbp1LEi76vYrIBSvZnCl+CQeN4mNCwyu6gFotv8V GyRfSCNsA8LfCpLo3eD+3AzjzT9ZOHdGuRQriOZYPGPS4LiiU2RzzbBc crgeoPk6l+O5trLXDoZA9nxKze4Ef5lYRfw8hxDlimvkned/k2JyMfBz 8OM= ;{id = 2854}
+; qname denial
+wab.example.com. IN NSEC wzz.example.com. A NSEC RRSIG
+wab.example.com. 3600 IN RRSIG NSEC 7 3 18000 20181230101906 20181130101906 2423 example.com. jmkDgBxYtJJx9FuanN3mhTiTQ0ETrhY28v02vyYRw2mgFG80YNsLTq57 tw7pYxb9XBLQpZN1P+1y419pwLVNKiYMONyvjqJbvaiSxzS0xGOrhDpb kEaensygo2GvoyEnO8J7BGRhhJCxVsqC8SCeMZijkWTrNQMGazgCc2Ra n5k= ;{id = 2854}
+SECTION ADDITIONAL
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA AD DO NXDOMAIN
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+SECTION AUTHORITY
+example.com. IN SOA ns.example.com. hostmaster.example.com. 2007090400 28800 7200 604800 18000
+example.com. 3600 IN RRSIG SOA 7 2 3600 20181230101906 20181130101906 2423 example.com. nvDfwhtBRatdQHu2tyCfoaE2HkgAXCm97CZOOx8Bg36MUblQDgwm55mP gaJQKsXxU9fOG9Nd7wkXZEYPvhnKFcUxtrFhHog9ouZtEsuS0w+E9cJX HqrI9L8m7URlQ7FZBaUjqlJGJNFgQbwZzfOvWDzSSzgBqj8emafNwOBg eQ4= ;{id = 2854}
+example.com. IN NSEC abc.example.com. SOA NS DNSKEY NSEC RRSIG
+example.com. 3600 IN RRSIG NSEC 7 2 18000 20181230101906 20181130101906 2423 example.com. dabtLPYkmc3k6LXDJbp1LEi76vYrIBSvZnCl+CQeN4mNCwyu6gFotv8V GyRfSCNsA8LfCpLo3eD+3AzjzT9ZOHdGuRQriOZYPGPS4LiiU2RzzbBc crgeoPk6l+O5trLXDoZA9nxKze4Ef5lYRfw8hxDlimvkned/k2JyMfBz 8OM= ;{id = 2854}
+wab.example.com. IN NSEC wzz.example.com. A NSEC RRSIG
+wab.example.com. 3600 IN RRSIG NSEC 7 3 18000 20181230101906 20181130101906 2423 example.com. jmkDgBxYtJJx9FuanN3mhTiTQ0ETrhY28v02vyYRw2mgFG80YNsLTq57 tw7pYxb9XBLQpZN1P+1y419pwLVNKiYMONyvjqJbvaiSxzS0xGOrhDpb kEaensygo2GvoyEnO8J7BGRhhJCxVsqC8SCeMZijkWTrNQMGazgCc2Ra n5k= ;{id = 2854}
+SECTION ADDITIONAL
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/val_nx_nodeny.rpl b/tests/integration/deckard/sets/resolver/val_nx_nodeny.rpl
new file mode 100644
index 0000000..3431dee
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_nx_nodeny.rpl
@@ -0,0 +1,166 @@
+do-ip6: no
+
+; config options
+; The island of trust is at example.com
+;server:
+ trust-anchor: "example.com. 3600 IN DS 46865 7 1 E6C7351C70AA8F888DACB2C1875AD1945CB22C39 "
+val-override-date: "20181130121902"
+; target-fetch-policy: "0 0 0 0 0"
+; fake-sha1: yes
+
+;stub-zone:
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+query-minimization: off
+CONFIG_END
+
+SCENARIO_BEGIN Test validator with nxdomain response missing qname denial
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA REFUSED
+SECTION QUESTION
+ns.example.com. IN A
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA REFUSED
+SECTION QUESTION
+ns.example.com. IN AAAA
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20181230101902 20181130101902 46865 example.com. k6TtlPvoChJFxi4exzlziiPGCdzNU7I0y5Z1cwfskP0Hc6nGbOEw5pVP TXK15AVJ+kIjeqcUbgFRu8/DPolJbWT+yHfuYE2OhjCqxJCt+vVDrMl0 maBTa7UwJeMkR76DqzjSbPsEpRSSXKvzjtlavk/TYbv/sz6yHsVhhYW8 Wu4= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101902 20181130101902 46865 example.com. WMO3vMt0WSaOXvL28iNxMK7xr7DgQLejluyrB3VrK7E8Dg3rhWxFZyJ4 ARxGCJEALLugWvH7kPBw9D2vzZh+qHBQ4X7OnHmUOPdwLQUrWfHQ535o /IEnrLWGQKbQUo5+yw+Un0RaovPvkxc6h/Qrpzz67Urx3m7XQoXITO+5 FIM= ;{id = 2854}
+ENTRY_END
+
+; response to DNSKEY priming query
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN DNSKEY
+SECTION ANSWER
+example.com. 3600 IN DNSKEY 256 3 7 AwEAAcJUKdcSvbPNRyNs/8EtvSsu/QIVXYkAxNxhqFi2TqHG0jWCoRy4 PdX0xSd3ve4PRx0jAi/FK8oWtThJevGGmM5aM+X/ZjFBAImSEo6gP9dB G7oGlou76JfwtSC2l3GHM+WOM/D/mc0I3mmd59AOzzpTnbeLL9EQqUWS nxSsYu4L ;{id = 2854 (zsk), size = 1688b}
+example.com. 3600 IN RRSIG DNSKEY 7 2 3600 20181230101902 20181130101902 46865 example.com. ZZmEktIT3fcwMOhV3G8cKabicLmqykXtEdZXGVAuCn5Di/zq/5y8l3rZ uhrolnlmPf1Zp9myG7HF/oDmbxyEEw9Vo//YMQGnQp/U7149m0kIpHbz /Os2z5qmxtfyIBIB3tfeQ9ixlBjzn/vCElQTUB83a24tWq+yhtgHIFjr L2k= ;{id = 2854}
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20181230101902 20181130101902 46865 example.com. k6TtlPvoChJFxi4exzlziiPGCdzNU7I0y5Z1cwfskP0Hc6nGbOEw5pVP TXK15AVJ+kIjeqcUbgFRu8/DPolJbWT+yHfuYE2OhjCqxJCt+vVDrMl0 maBTa7UwJeMkR76DqzjSbPsEpRSSXKvzjtlavk/TYbv/sz6yHsVhhYW8 Wu4= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101902 20181130101902 46865 example.com. WMO3vMt0WSaOXvL28iNxMK7xr7DgQLejluyrB3VrK7E8Dg3rhWxFZyJ4 ARxGCJEALLugWvH7kPBw9D2vzZh+qHBQ4X7OnHmUOPdwLQUrWfHQ535o /IEnrLWGQKbQUo5+yw+Un0RaovPvkxc6h/Qrpzz67Urx3m7XQoXITO+5 FIM= ;{id = 2854}
+ENTRY_END
+
+; response to query of interest
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NXDOMAIN
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+SECTION AUTHORITY
+example.com. IN SOA ns.example.com. hostmaster.example.com. 2007090400 28800 7200 604800 18000
+example.com. 3600 IN RRSIG SOA 7 2 3600 20181230101902 20181130101902 46865 example.com. KNiFDTdPOEF0+bhorTXrxLGvim8tHyRaVMXfLxP8CVVzWfnoHjVoy7Jo R/l9tVx1wkdQqtOzzBmbbhMMQSylKDii17zWStZFSoA99M1DhT11y47W gjYNT9TXe28IqWEMu/yNr+T0xyWHLRwuDUKiKMxMpPBdEcmMrBghVlcB 2tg= ;{id = 2854}
+; wildcard denial
+example.com. IN NSEC abc.example.com. SOA NS DNSKEY NSEC RRSIG
+example.com. 3600 IN RRSIG NSEC 7 2 18000 20181230101902 20181130101902 46865 example.com. EuaPkCgzpVTILpSBd4X9JMmXLaLFG3zKrXxCqUC/kZbVPgkZSA+4tDt2 Y48mmb8gicjCpe4pszczA0i/CeL+BE0ucdI1iV8GJdR7cBv5e9rG2c36 +F5oQ03pj+FQBbtKJ347XBVkxA/hy6pOFUppsXzV37MeT+VzoMLdCeir JQA= ;{id = 2854}
+; qname denial
+;wab.example.com. IN NSEC wzz.example.com. A NSEC RRSIG
+;wab.example.com. 3600 IN RRSIG NSEC 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFG5DZSEIZC088rjcB1e6sQx8nQz4AhUAtQ09tP1YYLJkhL/Wg1KV2pW4Ivk= ;{id = 2854}
+SECTION ADDITIONAL
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA SERVFAIL
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/val_nx_nowc.rpl b/tests/integration/deckard/sets/resolver/val_nx_nowc.rpl
new file mode 100644
index 0000000..2de363a
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_nx_nowc.rpl
@@ -0,0 +1,166 @@
+do-ip6: no
+
+; config options
+; The island of trust is at example.com
+;server:
+ trust-anchor: "example.com. 3600 IN DS 22469 7 1 9A6B45A912CC69BF1BBAE8E890A6351643B58FB9 "
+val-override-date: "20181130121903"
+; target-fetch-policy: "0 0 0 0 0"
+; fake-sha1: yes
+
+;stub-zone:
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+query-minimization: off
+CONFIG_END
+
+SCENARIO_BEGIN Test validator with nxdomain response missing wildcard denial
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA REFUSED
+SECTION QUESTION
+ns.example.com. IN A
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA REFUSED
+SECTION QUESTION
+ns.example.com. IN AAAA
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20181230101903 20181130101903 22469 example.com. AG9VohvKoHDb5Gg+uauHsyBo4TbM8Fc2jS6uNXykvzCnDBaz8Pv4jVgv X5Heqh0V1owcg4pEc4ntAfjAJPObpaR4nVrsR8WOozv1NKiXTixc7gIX NHC1VSo4mT1F/m9GhtyKjKAiZ+b2qE4DqwFfyq6+SC88zMEJtxBBHDF6 SYk= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101903 20181130101903 22469 example.com. AZ+ObbOQ6F/mliTCsbEaqwodaInWAUN0iYp0doBdKv1SaiBbmtJnnD48 Jpm1sJtGOR9H9n4xjQ7oOdL1p56eBqyn3pOV1bc+xLIDnOa4OqtufYqW rkcuT/odtTvd76YGe+Qtw9m7+Rh8i+qnTHPm8Hv/C28mdswEAoyVYvvG LqI= ;{id = 2854}
+ENTRY_END
+
+; response to DNSKEY priming query
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN DNSKEY
+SECTION ANSWER
+example.com. 3600 IN DNSKEY 256 3 7 AwEAAcvGZqYpdUE7YjWyWyH4xuqH8Ano6gh3qy/zez5uKDL69HDXO7Cc I4tw3FNDtqGbTF0pR1WLQZG9h6VFIHL8IoLpiwvQz9Qc66gtY3RGxa3B OBDhIO3g4QSbGgxnopzko/PgBBhrva4Z/VtjyBZbTak4+oNKcyjDZbuk 5IK9i3wH ;{id = 2854 (zsk), size = 1688b}
+example.com. 3600 IN RRSIG DNSKEY 7 2 3600 20181230101903 20181130101903 22469 example.com. xaPftZOaUQQuhq5aRlI24hX/reFOtX60Nvb8fZw0FE+bliPrsyQuwFia Rt6u8IT+URHRQJ7h+Vku8XYVdKBmufPVuVqZ7nsCtYAW5sj0OTTUK+y1 U3qH1vm2V+L/pUKPrlC1GtIk/SQzm+sLAsQzUzP8J5jU378IvEOOIDWW qXA= ;{id = 2854}
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20181230101903 20181130101903 22469 example.com. AG9VohvKoHDb5Gg+uauHsyBo4TbM8Fc2jS6uNXykvzCnDBaz8Pv4jVgv X5Heqh0V1owcg4pEc4ntAfjAJPObpaR4nVrsR8WOozv1NKiXTixc7gIX NHC1VSo4mT1F/m9GhtyKjKAiZ+b2qE4DqwFfyq6+SC88zMEJtxBBHDF6 SYk= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101903 20181130101903 22469 example.com. AZ+ObbOQ6F/mliTCsbEaqwodaInWAUN0iYp0doBdKv1SaiBbmtJnnD48 Jpm1sJtGOR9H9n4xjQ7oOdL1p56eBqyn3pOV1bc+xLIDnOa4OqtufYqW rkcuT/odtTvd76YGe+Qtw9m7+Rh8i+qnTHPm8Hv/C28mdswEAoyVYvvG LqI= ;{id = 2854}
+ENTRY_END
+
+; response to query of interest
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NXDOMAIN
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+SECTION AUTHORITY
+example.com. IN SOA ns.example.com. hostmaster.example.com. 2007090400 28800 7200 604800 18000
+example.com. 3600 IN RRSIG SOA 7 2 3600 20181230101903 20181130101903 22469 example.com. r1Wz8XdHbfNhO+pR75oSYz7/WB6z/YtcKOYE0SP03AYnS7sUbiEXMBxV VxgpMjfSGi55EMQQwdWIapvveRk847U5/8wAz076VCjJ0pPWOd8IC2d/ iRjjRmWZF/+7Pl+VTCGr6TXf4ioUU9UfKPOXAFOFNW/R+yTreT0KPnOW As0= ;{id = 2854}
+; wildcard denial
+;example.com. IN NSEC abc.example.com. SOA NS DNSKEY NSEC RRSIG
+;example.com. 3600 IN RRSIG NSEC 3 2 3600 20070926134150 20070829134150 2854 example.com. MCwCFHV2IBWyTmDJvZ+sT+WsGrJX0op/AhQkAijjnjPAtx/tNub2FAGqcexJSg== ;{id = 2854}
+; qname denial
+wab.example.com. IN NSEC wzz.example.com. A NSEC RRSIG
+wab.example.com. 3600 IN RRSIG NSEC 7 3 18000 20181230101903 20181130101903 22469 example.com. gelBI3JNXZKxtv9CIzlZbHUz1lTb3cN62Kvz/UOjv9+KxPfEG0TFUrQE jSRNdGL2v42x7RMYTzyf+aGmKT8esdgJ+mXcyfsqw4gUfvdQwoc9RVB9 qz24F84u8VGmXrclzHHpn1LBO+mzkz7S4LF1QNhqbvLP3eltC6IfzCPv /xw= ;{id = 2854}
+SECTION ADDITIONAL
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA SERVFAIL
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/val_pos_truncns.rpl b/tests/integration/deckard/sets/resolver/val_pos_truncns.rpl
new file mode 100644
index 0000000..3cf4f01
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_pos_truncns.rpl
@@ -0,0 +1,152 @@
+do-ip6: no
+
+; config options
+; The island of trust is at example.com
+;server:
+ trust-anchor: "example.com. 3600 IN DS 8912 7 1 D78A09971CE199BEF5C312E4ABAB6D80BB05A2C3 "
+val-override-date: "20181130121910"
+; target-fetch-policy: "0 0 0 0 0"
+; fake-sha1: yes
+
+;stub-zone:
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+query-minimization: off
+CONFIG_END
+
+SCENARIO_BEGIN Test validator with badly truncated positive response
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20181230101910 20181130101910 8912 example.com. irQCG3d04884eHBfTSrzbc9DK5otN8Nx5P90cwT89btFCHG6r1RzpCmT sm4tW+KoIunBREWkhCDx2y6zDmoWyERWan0fBXaIfgbYol+qehDuynR8 ZlVXbrUr7Aou4eCHiyi/4r3zGX8jy4Ujk5fJk6TS8P4/L9fP0ZSNyMYk dEU= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101910 20181130101910 8912 example.com. lrvd15HZ6FBa6JE9Me8tjyHvJ2Tgk2Dv/QkeFNOtBNC0RFEuZtRcXFTg +YaQIN1uQ3MGNscJc6vGcMewZTi0bAWfOnizrffhoTnf0eeBA+DMn+JX tGTVBtFKSS+qpF8Hg9iQj49AoM/ciNkwFdXzDqgNbI93+Z0qYRKJ2P0A bFI= ;{id = 2854}
+ENTRY_END
+
+; response to DNSKEY priming query
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN DNSKEY
+SECTION ANSWER
+example.com. 3600 IN DNSKEY 256 3 7 AwEAAa5f2vT9N+xcqZex8uKEC7ZMlGN5i+m7TqRu0xtp61GCGe6i83WF gFkmJ9FMHiv22mKJv2YvKgs7MM6peBDuBL/Qjdf17ENba3wT90koD/zM 0XoE61m1oGskzdt04rUTM+T7oTbYekFVILn00V7ZQKUzJTDAbW70fm/9 U5RZM6KT ;{id = 2854 (zsk), size = 1688b}
+example.com. 3600 IN RRSIG DNSKEY 7 2 3600 20181230101910 20181130101910 8912 example.com. dRH3WVzuN5/hZ07WHCbn6ZMmNONBFfv3oP5BgHQDR8+gRmuwAIPMmHjZ XbKcB8/m6IjClkTEe4zKCBr5Fm3aqYR4pOq29igUVWnd8FbnDIa73vEH JnG+x9h2XgcfAA/5sL1ldv+5maNUDrbNuIa9niGUlYvgXhxrLqCEUJOp C3E= ;{id = 2854}
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20181230101910 20181130101910 8912 example.com. irQCG3d04884eHBfTSrzbc9DK5otN8Nx5P90cwT89btFCHG6r1RzpCmT sm4tW+KoIunBREWkhCDx2y6zDmoWyERWan0fBXaIfgbYol+qehDuynR8 ZlVXbrUr7Aou4eCHiyi/4r3zGX8jy4Ujk5fJk6TS8P4/L9fP0ZSNyMYk dEU= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101910 20181130101910 8912 example.com. lrvd15HZ6FBa6JE9Me8tjyHvJ2Tgk2Dv/QkeFNOtBNC0RFEuZtRcXFTg +YaQIN1uQ3MGNscJc6vGcMewZTi0bAWfOnizrffhoTnf0eeBA+DMn+JX tGTVBtFKSS+qpF8Hg9iQj49AoM/ciNkwFdXzDqgNbI93+Z0qYRKJ2P0A bFI= ;{id = 2854}
+ENTRY_END
+
+; response to query of interest
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+www.example.com. 3600 IN RRSIG A 7 3 3600 20181230101910 20181130101910 8912 example.com. TDZElBJgT6bazaVj6uIGz2lqvth/j9xNwgWPGtweEUMTTjYvnolL63h8 P47D6vwKxGgxQSJ84U9PpjtsyqzmLxdK+9KEz7iWfzOtUO1pdSOoCrmI a68mCi3GgAJ0raEIWmzE1rPAv+plDIYluJgzy3bCula9vdI1bdN4x/vS Bsk= ;{id = 2854}
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+
+; Truncated, no signature for NS record.
+;;;example.com. 3600 IN RRSIG NS 7 2 3600 20181230101910 20181130101910 8912 example.com. irQCG3d04884eHBfTSrzbc9DK5otN8Nx5P90cwT89btFCHG6r1RzpCmT sm4tW+KoIunBREWkhCDx2y6zDmoWyERWan0fBXaIfgbYol+qehDuynR8 ZlVXbrUr7Aou4eCHiyi/4r3zGX8jy4Ujk5fJk6TS8P4/L9fP0ZSNyMYk dEU= ;{id = 2854}
+;;;SECTION ADDITIONAL
+;;;ns.example.com. IN A 1.2.3.4
+;;;ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCQMyTjn7WWwpwAR1LlVeLpRgZGuQIUCcJDEkwAuzytTDRlYK7nIMwH1CM= ;{id = 2854}
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+www.example.com. 3600 IN RRSIG A 7 3 3600 20181230101910 20181130101910 8912 example.com. TDZElBJgT6bazaVj6uIGz2lqvth/j9xNwgWPGtweEUMTTjYvnolL63h8 P47D6vwKxGgxQSJ84U9PpjtsyqzmLxdK+9KEz7iWfzOtUO1pdSOoCrmI a68mCi3GgAJ0raEIWmzE1rPAv+plDIYluJgzy3bCula9vdI1bdN4x/vS Bsk= ;{id = 2854}
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/val_positive_nosigs.rpl b/tests/integration/deckard/sets/resolver/val_positive_nosigs.rpl
new file mode 100644
index 0000000..fc736d5
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_positive_nosigs.rpl
@@ -0,0 +1,184 @@
+do-ip6: no
+
+; config options
+; The island of trust is at example.com
+;server:
+ trust-anchor: "example.com. 3600 IN DS 2854 3 1 46e4ffc6e9a4793b488954bd3f0cc6af0dfb201b"
+ val-override-date: "20070916134226"
+; target-fetch-policy: "0 0 0 0 0"
+; fake-sha1: yes
+
+;stub-zone:
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+;test from testbound
+
+SCENARIO_BEGIN Test validator with positive response, signatures removed.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854}
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.com. IN A
+SECTION ANSWER
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854}
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
+ENTRY_END
+
+; barely valid nodata for AAAA
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.com. IN AAAA
+SECTION ANSWER
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
+ENTRY_END
+
+
+; response to DNSKEY priming query
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN DNSKEY
+SECTION ANSWER
+example.com. 3600 IN DNSKEY 256 3 3 ALXLUsWqUrY3JYER3T4TBJII s70j+sDS/UT2QRp61SE7S3E EXopNXoFE73JLRmvpi/UrOO/Vz4Se 6wXv/CYCKjGw06U4WRgR YXcpEhJROyNapmdIKSx hOzfLVE1gqA0PweZR8d tY3aNQSRn3sPpwJr6Mi /PqQKAMMrZ9ckJpf1+b QMOOvxgzz2U1GS18b3y ZKcgTMEaJzd/GZYzi/B N2DzQ0MsrSwYXfsNLFO Bbs8PJMW4LYIxeeOe6rUgkWOF 7CC9Dh/dduQ1QrsJhmZAEFfd6ByYV+ ;{id = 2854 (zsk), size = 1688b}
+example.com. 3600 IN RRSIG DNSKEY 3 2 3600 20070926134802 20070829134802 2854 example.com. MCwCFG1yhRNtTEa3Eno2zhVVuy2EJX3wAhQeLyUp6+UXcpC5qGNu9tkrTEgPUg== ;{id = 2854}
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854}
+ENTRY_END
+
+; response to DS query for subzone
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN DS
+SECTION ANSWER
+ENTRY_END
+
+; response to query of interest
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AD NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA SERVFAIL
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/val_qds_oneanc.rpl b/tests/integration/deckard/sets/resolver/val_qds_oneanc.rpl
new file mode 100644
index 0000000..b5a2610
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_qds_oneanc.rpl
@@ -0,0 +1,224 @@
+do-ip6: no
+
+; config options
+; The island of trust is at example.com
+;server:
+ trust-anchor: "example.com. 3600 IN DS 34694 7 1 6051ACF3BE1C7E91C09614E6237A3B6AEF997EEA "
+val-override-date: "20181130121911"
+; target-fetch-policy: "0 0 0 0 0"
+; fake-sha1: yes
+
+;stub-zone:
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+query-minimization: off
+CONFIG_END
+
+SCENARIO_BEGIN Test validator with DS query and one anchor
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+sub.example.com. IN DS
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+sub.example.com. IN DS
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20181230101911 20181130101911 34694 example.com. u92Oy+hcQjhnkA7+giV6gJlDovDUmmUrhwN3ayf9/de3EFymsGWns3rW uVBy9p9MiGuq5Gh1eBGYgBLsuxYjVQfiF3iqoXldc1La7VjmR+5YzTw0 CnTiabybAXUnEOLlyonnbCeNhN9cvn6nYLN87yPSRuzGeB2T3aFXgkUk p20= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101911 20181130101911 34694 example.com. a/cISMkpWJgOLQuAmo05DxcjxUwsets7jV2y+rYMkFn+KZh7pjUDRTvd 52pCzgWlDJPVKrBcNRUQn8D1xVwp+MO/4MjonQRuhGORwdsbuqfMD55+ zeAgEJGGi7ygt5/kFr2gioZejqj1A236IXbLfFiLTmlHtV1Y2A/mvWsP cTA= ;{id = 2854}
+ENTRY_END
+
+; response to DNSKEY priming query
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN DNSKEY
+SECTION ANSWER
+example.com. 3600 IN DNSKEY 256 3 7 AwEAAdoXMIS/blyIEUB9xHus+B60jFsJiPvHgIhOgFTmLHqwZ5mhFxug q/O9k/iKhf/3HttKed9lvZwJ9XUPzDqJFAXz5nS1oRsGBGtUMwoF/nM3 kU7Ko4oy9Gtjb1/iFuEhTkjGyom9e5m/pA9BW5eX37knNlbHSOpRlcWP zYH213gz ;{id = 2854 (zsk), size = 1688b}
+example.com. 3600 IN RRSIG DNSKEY 7 2 3600 20181230101911 20181130101911 34694 example.com. HE6kf6hmJBAaDvfG9I5ZhGq7ICr5byQcYDmtEcMQwzMHPjV6bFX6G5dO ttXbxCbFh6XvznDXnsboTXSuX8YGIqtVt0IY7FsyfbF8fKmbKWCfivrb Z1Z5CG6ToA0vCx1sHMF17oa3P8moVPejicDJqOVkz9XzS9zHJxmJIWx2 8fM= ;{id = 2854}
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20181230101911 20181130101911 34694 example.com. u92Oy+hcQjhnkA7+giV6gJlDovDUmmUrhwN3ayf9/de3EFymsGWns3rW uVBy9p9MiGuq5Gh1eBGYgBLsuxYjVQfiF3iqoXldc1La7VjmR+5YzTw0 CnTiabybAXUnEOLlyonnbCeNhN9cvn6nYLN87yPSRuzGeB2T3aFXgkUk p20= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101911 20181130101911 34694 example.com. a/cISMkpWJgOLQuAmo05DxcjxUwsets7jV2y+rYMkFn+KZh7pjUDRTvd 52pCzgWlDJPVKrBcNRUQn8D1xVwp+MO/4MjonQRuhGORwdsbuqfMD55+ zeAgEJGGi7ygt5/kFr2gioZejqj1A236IXbLfFiLTmlHtV1Y2A/mvWsP cTA= ;{id = 2854}
+ENTRY_END
+
+; response for delegation to sub.example.com.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.sub.example.com. IN A
+SECTION ANSWER
+SECTION AUTHORITY
+sub.example.com. IN NS ns.sub.example.com.
+sub.example.com. 3600 IN DS 36540 5 1 040C7E6D3E183A894CDECC56F6A33086409692F2
+sub.example.com. 3600 IN RRSIG DS 7 3 3600 20181230101911 20181130101911 34694 example.com. t8Ktq66BvanAwL00D3hzwIIJQXJ6NzsTBzi0Um8bESfFdxlN2WIjSVd5 hfNruVRDEsTCDlOd2r6cG3Q003NGDn7ulOUR8RLL29a4Tj9YkIJnizEw WrMUhdUU9CqbxZSq8aAKO8tIoI56NfK8FqYObZKR4aqXHOBPf0QkvPKr i+E= ;{id = 2854}
+SECTION ADDITIONAL
+ns.sub.example.com. IN A 1.2.3.6
+ENTRY_END
+
+; response for delegation to sub.example.com.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+sub.example.com. IN DNSKEY
+SECTION ANSWER
+SECTION AUTHORITY
+sub.example.com. IN NS ns.sub.example.com.
+sub.example.com. 3600 IN DS 36540 5 1 040C7E6D3E183A894CDECC56F6A33086409692F2
+sub.example.com. 3600 IN RRSIG DS 7 3 3600 20181230101911 20181130101911 34694 example.com. t8Ktq66BvanAwL00D3hzwIIJQXJ6NzsTBzi0Um8bESfFdxlN2WIjSVd5 hfNruVRDEsTCDlOd2r6cG3Q003NGDn7ulOUR8RLL29a4Tj9YkIJnizEw WrMUhdUU9CqbxZSq8aAKO8tIoI56NfK8FqYObZKR4aqXHOBPf0QkvPKr i+E= ;{id = 2854}
+SECTION ADDITIONAL
+ns.sub.example.com. IN A 1.2.3.6
+ENTRY_END
+
+; response to DS query
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+sub.example.com. IN DS
+SECTION ANSWER
+sub.example.com. 3600 IN DS 36540 5 1 040C7E6D3E183A894CDECC56F6A33086409692F2
+sub.example.com. 3600 IN RRSIG DS 7 3 3600 20181230101911 20181130101911 34694 example.com. t8Ktq66BvanAwL00D3hzwIIJQXJ6NzsTBzi0Um8bESfFdxlN2WIjSVd5 hfNruVRDEsTCDlOd2r6cG3Q003NGDn7ulOUR8RLL29a4Tj9YkIJnizEw WrMUhdUU9CqbxZSq8aAKO8tIoI56NfK8FqYObZKR4aqXHOBPf0QkvPKr i+E= ;{id = 2854}
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20181230101911 20181130101911 34694 example.com. u92Oy+hcQjhnkA7+giV6gJlDovDUmmUrhwN3ayf9/de3EFymsGWns3rW uVBy9p9MiGuq5Gh1eBGYgBLsuxYjVQfiF3iqoXldc1La7VjmR+5YzTw0 CnTiabybAXUnEOLlyonnbCeNhN9cvn6nYLN87yPSRuzGeB2T3aFXgkUk p20= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101911 20181130101911 34694 example.com. a/cISMkpWJgOLQuAmo05DxcjxUwsets7jV2y+rYMkFn+KZh7pjUDRTvd 52pCzgWlDJPVKrBcNRUQn8D1xVwp+MO/4MjonQRuhGORwdsbuqfMD55+ zeAgEJGGi7ygt5/kFr2gioZejqj1A236IXbLfFiLTmlHtV1Y2A/mvWsP cTA= ;{id = 2854}
+ENTRY_END
+RANGE_END
+
+; ns.sub.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.6
+
+; response to DNSKEY priming query
+; sub.example.com. 3600 IN DS 36540 5 1 040C7E6D3E183A894CDECC56F6A33086409692F2
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+sub.example.com. IN DNSKEY
+SECTION ANSWER
+sub.example.com. 3600 IN DNSKEY 256 3 5 AwEAAba60cKYqTClLVdFbBubhTqnnfJ3Kkbyd96JlGBAMHJ5IQ9fONnF KQYGtOZ8FkF9HBOHoz+WCqlG8mRHuuqkZ/6zei6/DP70JHUcP/cbT6NY RwDqUvAvDXr4tZPKD5yjJKCLqOI+TQo48RlGNVZjZpL5BgiEnM/lguxP DNQri8tP ;{id = 30899 (zsk), size = 512b}
+sub.example.com. 3600 IN RRSIG DNSKEY 5 3 3600 20181230101911 20181130101911 36540 sub.example.com. fRAswfvVrez7A0MBgmusYZSOFMIhSobJlEC620/y9SrnBHc2eiWsQOFa AGaqkdprGNopP6Nzsjoz6CCzIFrTmPKizi22Df8CkSBYXdFObWbvAopQ JkFmDH82DwGjEHOu/HhhFN7IPHRXrmDltecCWSIvWD/hjyqEfi0hm0CR 27A= ;{id = 30899}
+SECTION AUTHORITY
+sub.example.com. IN NS ns.sub.example.com.
+sub.example.com. 3600 IN RRSIG NS 5 3 3600 20181230101911 20181130101911 36540 sub.example.com. J3ttMFY5LNe6C2X8qpji9Fbn9ms5iUR06VyB4mySCThZqmfaTstShe/k c/Es1nTXgH7ThbnZSE+3bCGfjBD8qu10Nmd5Q0oy8oetwQXIKtEwTETL ces7EjOQLm0XozSe4V0pQlUX5DzxSZhQYx0mTfOCvSqFeZ07Cqzk0lpj ouI= ;{id = 30899}
+SECTION ADDITIONAL
+ns.sub.example.com. IN A 1.2.3.6
+ns.sub.example.com. 3600 IN RRSIG A 5 4 3600 20181230101911 20181130101911 36540 sub.example.com. mXWfA0N8BIwMdmqIVmmyGc9qvW22Nlo2MChpvC/dwwzXYp9ZX51QUagG D6LzinILleQa3Jz4tb8Z7x/oU57Tz4j1erUvXhnqxLdM66rRi2xk+v8C zkHk3f9GgcjOtrEBy09dIJuppg0mAsBWO8oVwR5BYpGO0KGBUqcvffJt Vv0= ;{id = 30899}
+ENTRY_END
+
+; response to query of interest
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.sub.example.com. IN A
+SECTION ANSWER
+www.sub.example.com. IN A 11.11.11.11
+www.sub.example.com. 3600 IN RRSIG A 5 4 3600 20181230101911 20181130101911 36540 sub.example.com. LLCuevrbnFrzvF80jykui0rHv9Xsi7RF/qVbp6CP+xD6ywWLsUk7Uy9O p6pcq1B0/i0eWImGJT9TiFr1xlNyhtFRnM6KJveih2a/8KtFzJ/ZGgoD OwMNpGqKv+bMcJQEE5Iv4x00ReN49CxSTFm6JM8JKtpR6+WM2ydRns2R CIY= ;{id = 30899}
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+sub.example.com. IN DS
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH opcode rcode flags question answer
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+sub.example.com. IN DS
+SECTION ANSWER
+sub.example.com. 3600 IN DS 36540 5 1 040C7E6D3E183A894CDECC56F6A33086409692F2
+sub.example.com. 3600 IN RRSIG DS 7 3 3600 20181230101911 20181130101911 34694 example.com. t8Ktq66BvanAwL00D3hzwIIJQXJ6NzsTBzi0Um8bESfFdxlN2WIjSVd5 hfNruVRDEsTCDlOd2r6cG3Q003NGDn7ulOUR8RLL29a4Tj9YkIJnizEw WrMUhdUU9CqbxZSq8aAKO8tIoI56NfK8FqYObZKR4aqXHOBPf0QkvPKr i+E= ;{id = 2854}
+;SECTION AUTHORITY
+;example.com. IN NS ns.example.com.
+;example.com. 3600 IN RRSIG NS 7 2 3600 20181230101911 20181130101911 34694 example.com. u92Oy+hcQjhnkA7+giV6gJlDovDUmmUrhwN3ayf9/de3EFymsGWns3rW uVBy9p9MiGuq5Gh1eBGYgBLsuxYjVQfiF3iqoXldc1La7VjmR+5YzTw0 CnTiabybAXUnEOLlyonnbCeNhN9cvn6nYLN87yPSRuzGeB2T3aFXgkUk p20= ;{id = 2854}
+;SECTION ADDITIONAL
+;ns.example.com. IN A 1.2.3.4
+;ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101911 20181130101911 34694 example.com. a/cISMkpWJgOLQuAmo05DxcjxUwsets7jV2y+rYMkFn+KZh7pjUDRTvd 52pCzgWlDJPVKrBcNRUQn8D1xVwp+MO/4MjonQRuhGORwdsbuqfMD55+ zeAgEJGGi7ygt5/kFr2gioZejqj1A236IXbLfFiLTmlHtV1Y2A/mvWsP cTA= ;{id = 2854}
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/val_qds_twoanc.rpl b/tests/integration/deckard/sets/resolver/val_qds_twoanc.rpl
new file mode 100644
index 0000000..597016a
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_qds_twoanc.rpl
@@ -0,0 +1,225 @@
+do-ip6: no
+
+; config options
+; The island of trust is at example.com
+;server:
+ trust-anchor: "example.com. 3600 IN DS 56744 7 1 0B6FC412DE574014C6231DF6C97C2A370903297A "
+ trust-anchor: "sub.example.com. 3600 IN DS 42960 5 1 C430C3DFF8F700A924DB9F0EB1589D47E804631B "
+val-override-date: "20181130121913"
+; target-fetch-policy: "0 0 0 0 0"
+; fake-sha1: yes
+
+;stub-zone:
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+query-minimization: off
+CONFIG_END
+
+SCENARIO_BEGIN Test validator with DS query and two anchors
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+sub.example.com. IN DS
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+sub.example.com. IN DS
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20181230101913 20181130101913 56744 example.com. PbI0TTbOc1OZsplLREnmRXl3zYbj4CMIk7LgavRNp9+diDWksiR1nxWo szKMYfwjN6dxlwowAgL+frC6esvLvbV5BeDhR+emsf4ayKO6OSrCHJUK 5af7jtKkrLYuVCn3Ad1RZxlecv9IIJc6cjUg5FMm3+Riuq/PrekrDZqz Si0= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101913 20181130101913 56744 example.com. KgRA0DGIjVXsmx+oLWqWNrDhoTI4doL+wm1+BufgJkfcm8LstWnCre+M sY6rV9o+DM5RvtPj+5pwhrgAMJqaLgMTrEXCWsbFvEQU1jLhYpLRNJ5L 69AMOtfVUquxrdviPcXjzR8VbB+KvH5Vg1NlsuNlxtMbqS3Lex10LKlU NA0= ;{id = 2854}
+ENTRY_END
+
+; response to DNSKEY priming query
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN DNSKEY
+SECTION ANSWER
+example.com. 3600 IN DNSKEY 256 3 7 AwEAAbKuypu/H/0cr6HwVXfbaS+Xu3Rx5bq0Sfi/lfJP+36jPL2u478E NMk9VBPqVV40r5Y/RZWUZ7YvtbQzWuFSU2jqNUtjamyfzX8AF+tUDf4C FLFUQ0sCx+/cK1t0h4+TQkYOrlR0Xkqw4+bsr0ThsxtL7ypJh2D2Ny0V YtNkob4Z ;{id = 2854 (zsk), size = 1688b}
+example.com. 3600 IN RRSIG DNSKEY 7 2 3600 20181230101913 20181130101913 56744 example.com. lZJ7diaUg1AHnAljugMYZkZFKhOm/Op363Ott+kXuSPWKFPzXbD/Ezyh g8lpGPjwhxrf3mJgqLiPCkRYsnn5E+ebeCvjwB2OgKuxS09mD7NNUYF+ eYakSNa9zztYavw82dwBVT9frvLqqQg0gyeRc1W0eq7cnyy1pK4lpapl 1eA= ;{id = 2854}
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20181230101913 20181130101913 56744 example.com. PbI0TTbOc1OZsplLREnmRXl3zYbj4CMIk7LgavRNp9+diDWksiR1nxWo szKMYfwjN6dxlwowAgL+frC6esvLvbV5BeDhR+emsf4ayKO6OSrCHJUK 5af7jtKkrLYuVCn3Ad1RZxlecv9IIJc6cjUg5FMm3+Riuq/PrekrDZqz Si0= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101913 20181130101913 56744 example.com. KgRA0DGIjVXsmx+oLWqWNrDhoTI4doL+wm1+BufgJkfcm8LstWnCre+M sY6rV9o+DM5RvtPj+5pwhrgAMJqaLgMTrEXCWsbFvEQU1jLhYpLRNJ5L 69AMOtfVUquxrdviPcXjzR8VbB+KvH5Vg1NlsuNlxtMbqS3Lex10LKlU NA0= ;{id = 2854}
+ENTRY_END
+
+; response for delegation to sub.example.com.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.sub.example.com. IN A
+SECTION ANSWER
+SECTION AUTHORITY
+sub.example.com. IN NS ns.sub.example.com.
+sub.example.com. 3600 IN DS 42960 5 1 C430C3DFF8F700A924DB9F0EB1589D47E804631B
+sub.example.com. 3600 IN RRSIG DS 7 3 3600 20181230101913 20181130101913 56744 example.com. G/ri3P6noC+ftYdFA35MrhZv0D/gHUISBYSuLVBir2+Bt9JukeVhqd9i zdjSXCIrxUdJUaPwSSEyLHvVOXJpR8SdtjnHR97YcxM69RSoinBpvBc4 Ey1ahaG1pOH12ipqVIwkJRIlh9C08sdyFTDALw4MwHVd8P+K+oSTEpO/ 0V4= ;{id = 2854}
+SECTION ADDITIONAL
+ns.sub.example.com. IN A 1.2.3.6
+ENTRY_END
+
+; response for delegation to sub.example.com.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+sub.example.com. IN DNSKEY
+SECTION ANSWER
+SECTION AUTHORITY
+sub.example.com. IN NS ns.sub.example.com.
+sub.example.com. 3600 IN DS 42960 5 1 C430C3DFF8F700A924DB9F0EB1589D47E804631B
+sub.example.com. 3600 IN RRSIG DS 7 3 3600 20181230101913 20181130101913 56744 example.com. G/ri3P6noC+ftYdFA35MrhZv0D/gHUISBYSuLVBir2+Bt9JukeVhqd9i zdjSXCIrxUdJUaPwSSEyLHvVOXJpR8SdtjnHR97YcxM69RSoinBpvBc4 Ey1ahaG1pOH12ipqVIwkJRIlh9C08sdyFTDALw4MwHVd8P+K+oSTEpO/ 0V4= ;{id = 2854}
+SECTION ADDITIONAL
+ns.sub.example.com. IN A 1.2.3.6
+ENTRY_END
+
+; response to DS query
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+sub.example.com. IN DS
+SECTION ANSWER
+sub.example.com. 3600 IN DS 42960 5 1 C430C3DFF8F700A924DB9F0EB1589D47E804631B
+sub.example.com. 3600 IN RRSIG DS 7 3 3600 20181230101913 20181130101913 56744 example.com. G/ri3P6noC+ftYdFA35MrhZv0D/gHUISBYSuLVBir2+Bt9JukeVhqd9i zdjSXCIrxUdJUaPwSSEyLHvVOXJpR8SdtjnHR97YcxM69RSoinBpvBc4 Ey1ahaG1pOH12ipqVIwkJRIlh9C08sdyFTDALw4MwHVd8P+K+oSTEpO/ 0V4= ;{id = 2854}
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20181230101913 20181130101913 56744 example.com. PbI0TTbOc1OZsplLREnmRXl3zYbj4CMIk7LgavRNp9+diDWksiR1nxWo szKMYfwjN6dxlwowAgL+frC6esvLvbV5BeDhR+emsf4ayKO6OSrCHJUK 5af7jtKkrLYuVCn3Ad1RZxlecv9IIJc6cjUg5FMm3+Riuq/PrekrDZqz Si0= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101913 20181130101913 56744 example.com. KgRA0DGIjVXsmx+oLWqWNrDhoTI4doL+wm1+BufgJkfcm8LstWnCre+M sY6rV9o+DM5RvtPj+5pwhrgAMJqaLgMTrEXCWsbFvEQU1jLhYpLRNJ5L 69AMOtfVUquxrdviPcXjzR8VbB+KvH5Vg1NlsuNlxtMbqS3Lex10LKlU NA0= ;{id = 2854}
+ENTRY_END
+RANGE_END
+
+; ns.sub.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.6
+
+; response to DNSKEY priming query
+; sub.example.com. 3600 IN DS 42960 5 1 C430C3DFF8F700A924DB9F0EB1589D47E804631B
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+sub.example.com. IN DNSKEY
+SECTION ANSWER
+sub.example.com. 3600 IN DNSKEY 256 3 5 AwEAAaVxPE0OCr9YJP75+8+TRRBbeizDX1Hc5HP92FgPdh3kglwHm7c0 2LCApXpaKOZrz8ZVAgZDMHarw1N1ADD0u4Ie9OFflkNqFc7dkNENQcqA dKFioClHFAnaUbEtphlduco7etDaoR4QPCas3YOWcRrA75z0XlYXVrf6 mqRwVqFT ;{id = 30899 (zsk), size = 512b}
+sub.example.com. 3600 IN RRSIG DNSKEY 5 3 3600 20181230101912 20181130101912 42960 sub.example.com. iho097OZdVbSYY9CuLXsn5C6Sq5laVdU717ueVcTomb9i6aLern28/SL 1AzZbTtAkMfidyM3F9mmwfe80Mm4i+sjGfgrZXV/L8m42sdTfCPZNdCs eAP4jpr+Q8CdxdHzABFthLxFuzA0ZdtiwD3Zq3a4XBVuJQn4XH0+SxL4 Eek= ;{id = 30899}
+SECTION AUTHORITY
+sub.example.com. IN NS ns.sub.example.com.
+sub.example.com. 3600 IN RRSIG NS 5 3 3600 20181230101912 20181130101912 42960 sub.example.com. AxXFbEMc9iDGhK8EiQMuDUgpk4heb/P71IlEVQHdQM+XVgZDdLgp7iyP CTH/v0vGjPZsmyJJBjoRNl+m6IinLEF/lf6TJ7Rcir2BCoMvPRojZs7X f9M23LTRLQWaFqIk5N2gt9noR5j997VXK/E/GQ64sit8X2F/LQ+x/1Gq MEw= ;{id = 30899}
+SECTION ADDITIONAL
+ns.sub.example.com. IN A 1.2.3.6
+ns.sub.example.com. 3600 IN RRSIG A 5 4 3600 20181230101912 20181130101912 42960 sub.example.com. EAtvAOPXd+lgKXYbMzvKC1ahxQtIw15k35+6kgcR/vU7xGLqHkpU0fu0 pG1cFvhDNuxA3E16TNt8dgnNL6GIJI+OE1VgXy9wj1C+9H3ERXcl46xq 9mGG9M4YDMD/TdZMta1ZkR6aiuLeaEAXe9XF5ZfFsEABdrLhB3Diup4G w74= ;{id = 30899}
+ENTRY_END
+
+; response to query of interest
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.sub.example.com. IN A
+SECTION ANSWER
+www.sub.example.com. IN A 11.11.11.11
+www.sub.example.com. 3600 IN RRSIG A 5 4 3600 20181230101912 20181130101912 42960 sub.example.com. U4Z/wPmkVfsoxVnjWpY3nzOOq/w7lUvP+CCbVPQpIWML628yTOTbgIBs Uf/iYRarxaZEF5LwJ0lJ0gHmiw4xpEv1B1Lk0UWLiOmQP0auWUKpTufM L6y3HLeav2yuAi7klfeD/8boTzNxr2GEAcgQ4OlrrcGHkNGnzFwWY9a1 Tis= ;{id = 30899}
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+sub.example.com. IN DS
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH opcode rcode flags question answer
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+sub.example.com. IN DS
+SECTION ANSWER
+sub.example.com. 3600 IN DS 42960 5 1 C430C3DFF8F700A924DB9F0EB1589D47E804631B
+sub.example.com. 3600 IN RRSIG DS 7 3 3600 20181230101913 20181130101913 56744 example.com. G/ri3P6noC+ftYdFA35MrhZv0D/gHUISBYSuLVBir2+Bt9JukeVhqd9i zdjSXCIrxUdJUaPwSSEyLHvVOXJpR8SdtjnHR97YcxM69RSoinBpvBc4 Ey1ahaG1pOH12ipqVIwkJRIlh9C08sdyFTDALw4MwHVd8P+K+oSTEpO/ 0V4= ;{id = 2854}
+;SECTION AUTHORITY
+;example.com. IN NS ns.example.com.
+;example.com. 3600 IN RRSIG NS 7 2 3600 20181230101913 20181130101913 56744 example.com. PbI0TTbOc1OZsplLREnmRXl3zYbj4CMIk7LgavRNp9+diDWksiR1nxWo szKMYfwjN6dxlwowAgL+frC6esvLvbV5BeDhR+emsf4ayKO6OSrCHJUK 5af7jtKkrLYuVCn3Ad1RZxlecv9IIJc6cjUg5FMm3+Riuq/PrekrDZqz Si0= ;{id = 2854}
+;SECTION ADDITIONAL
+;ns.example.com. IN A 1.2.3.4
+;ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101913 20181130101913 56744 example.com. KgRA0DGIjVXsmx+oLWqWNrDhoTI4doL+wm1+BufgJkfcm8LstWnCre+M sY6rV9o+DM5RvtPj+5pwhrgAMJqaLgMTrEXCWsbFvEQU1jLhYpLRNJ5L 69AMOtfVUquxrdviPcXjzR8VbB+KvH5Vg1NlsuNlxtMbqS3Lex10LKlU NA0= ;{id = 2854}
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/val_referral_nods.rpl b/tests/integration/deckard/sets/resolver/val_referral_nods.rpl
new file mode 100644
index 0000000..ab9a3ac
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_referral_nods.rpl
@@ -0,0 +1,207 @@
+do-ip6: no
+
+; config options
+; The island of trust is at example.com
+;server:
+ trust-anchor: "example.com. IN DS 438 10 2 33F8133EB48EDB093839E985600EB7B7009EB5AC312D11CCA9007F6B 71D94D7B"
+ val-override-date: "20160309103040"
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+ query-minimization: off
+CONFIG_END
+
+SCENARIO_BEGIN Referral without DS.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+www.sub.example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. 3600 IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 10 2 3600 20251231235959 20160308093040 438 example.com. MNa4O8/p0DQiRYjWaq7wxo5AYNHyQ7Ts6Awh3qXTr4nm6xm9pVuqOXsX CJlxHRIYZyZfbp3iQGxuUGq9Ks+/4MocFz1O4f+LNLOjVK0mjrnuJUnP Bj3+CLv0RSYmdtvClSu9I2GOTYIa3c29TTQNHjnVSe7ZdPjjsQkn1rW1 gtU=
+example.com. 3600 IN RRSIG NS 10 2 3600 20251231235959 20160308093040 2843 example.com. boNVuXxyhW+Gmiu+4ip1QQvIGqFNVsFfg1v+ywgc4+37ieQ5t+qJsHVm fJITRZrJxYQ6T/MkZKhpxLCemgFeKU6syWwoCfypnGino2G1urvqThna WTImSPhY/QsOj1ALy51d9Q+Mb5vt69XJt6SQvtNf6imepIFOT6CPSfjx BJ4=
+SECTION ADDITIONAL
+ns.example.com. 3600 IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 10 3 3600 20251231235959 20160308093040 438 example.com. QKgtWex7PxeyCWG2pVw6kQNxWGr8u8hxtD8Zbc5Khu6q4cMFhoiBY9aA KaJCMnxn9GbSBtaCXARk6DKPfNGVZWeqVSap0uVqmlYJGNP1EGaNBRWJ FTYCHc6HCdtvEsuuhd+VX0YCBLfCt53+zdC3bYQH0U5PxduPkUMmdBvH F+k=
+ns.example.com. 3600 IN RRSIG A 10 3 3600 20251231235959 20160308093040 2843 example.com. VSq+DkxJYr9Z+uh3KgpyPNwtuim4WVXnTdhRW7HX90CP5tyOVjDDTehA UmCxB8iFjUFE3hlwDx0Y71g+8Oso1t0JGkvDtWf5RDx1w+4K/1pQ2JMG lZTh7juaGJzXtltxqBoY67z1FBp9MI59O0hkABtz1CElj9LrhDr9wQa4 OUo=
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+sub.example.com. IN DS
+SECTION ANSWER
+sub.example.com. 3600 IN DS 38364 7 1 66DC14443014B2727261B50B447170DE18CF43A9
+sub.example.com. 3600 IN DS 38364 7 2 719A6680950A624D2C71A67981A7AF884C23E3C21074FF1CF8FB7EFE 20C52F97
+sub.example.com. 3600 IN RRSIG DS 10 3 3600 20251231235959 20160308093040 438 example.com. mu/x2yR8nFrwOnnfN7dMQ2e2MAAuZigua0wakXaPT0j4pe5AjQhriZXU pWLk5z77ck8Kswt+O23v1sUxmq1bUsIc2kw6N02UyiHnPoxmcu0rg0Kc ustfA++YT5/L+fpq5PRm3kKfHLo81WdZ/VJoaafH/kXHnZTcP62ZoteQ sqw=
+sub.example.com. 3600 IN RRSIG DS 10 3 3600 20251231235959 20160308093040 2843 example.com. ZLx28ZpzPpaafVH3hqV9h6AZJH7Zn0ELOfFxodogJfWue86xjuWhzpBV O9jCOqyURitiBgKNYazghmciNw4wzANbz+hhtc4rIPsfOr/8Vn3pjyev yScX227d16hXKBNKTrAeKNvM8fVPT0E7cG3CY0mzVp3SVqrr+6hl+dgb gXU=
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+example.com. IN DNSKEY
+SECTION ANSWER
+example.com. 3600 IN DNSKEY 256 3 10 AwEAAcOHC7D2ZcG5M6MK5If/60+vvBM67BC8qUx04f6Kcvhx9GBMIMYz 87m6m2P5WKafW5AN1K9jY37m2fU/TdACQNzqu4wyVsOQefke/v2fgswg NgneP/C7cpyBVuK+8BUHjrorfLORClD3mbQMQldaaO2h6+OArAGHlFNI oFsuCjyR
+example.com. 3600 IN DNSKEY 257 3 10 AwEAAc4VCSEu1C1lAxuZMC8tSyissZNXC2lgS3zNvAvFdLtAsSbhB1cj dLCtTWUv1Ki/T+iWn10iemLQJ0S6z8wK+a7maC3ELZP1qoSFln+FiAsZ xYK72/XDEYMMp01F0gxgzZ2alWx3WKm2mELXf/ezEx+7X2ZNbwum5TKt FxtvotmT
+example.com. 3600 IN RRSIG DNSKEY 10 2 3600 20251231235959 20160308093040 438 example.com. cas8JKwtLUIItwOgrDrDG9pSkqiYw3r+8vyvt962kjHFBNG0D7AeegaO GMSWRziqA4L8xdgP750rLR5CRFQ9oPQlr/RWnsebGdJ3Yohwwa04HE6n OvR+o0u0oqNQ+P5KinxVKSv0Ru+BVMPHRDfIXN/FD5p9+nvIrnjXQlI3 vvM=
+example.com. 3600 IN RRSIG DNSKEY 10 2 3600 20251231235959 20160308093040 2843 example.com. uDLTMMTvJCcetKr6THEJ8Rn0gMLPFZTbOGJBZyZ2E5F9KkPSS01Nm6/P e+j0R3ObYXodqnZIY19fzXJKS2dJktoXkqNLBW/SpWTlFzpfHKCvTbJS VLrJ/lrEunE5cgSAqBrbAAuJrFpX/gaavqokElnUv1Mki2agTH1dTZyn X8M=
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.sub.example.com. IN A
+SECTION ANSWER
+SECTION AUTHORITY
+sub.example.com. 3600 IN NS ns.sub.example.com.
+SECTION ADDITIONAL
+ns.sub.example.com. 3600 IN A 1.2.3.10
+ENTRY_END
+RANGE_END
+
+; sub.ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.10
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+sub.example.com. IN DNSKEY
+SECTION ANSWER
+sub.example.com. 3600 IN DNSKEY 256 3 7 AwEAAfXXu2eDy9QsjLuHgEMWmG03TVauwmITCq520ANujsTZlPKyQKJe xyrYm61e0RuQJb5dB5JnE0O3YYJOpnrl8keieAqVt1efnNtcn8V1em48 et146ZYFAUb/PMdTOgd2XJnhVEWD3VsZbWNMCxP1KcJTATAaLDVCY//E sc9K3CvGUizNcSoTK2rGS73A6GqmvVNnGir6AQIZifkvb6PKzF/hVpS8 cgvKF/UP8hu+0Glbq1YYTFrXMUBzKUH+X19lRvk3eLHurSvGjDEM3ZO6 tp1QdpzIRPzYKENG+qs07dhgCZyb4zqwEycmL9/Vot0ByTGbeHvHN93P PrLxcM5zlVk=
+sub.example.com. 3600 IN DNSKEY 257 3 7 AwEAAfTD+gzZ2g7c9VoOUR2ekQiPNEyqcyl0MZ4sD3bleU8D8hQdDgAI 1G38raY3xmNea8yLCQYF0x00QbmKtzMjpZqKfsCFZDX6lBV5dP8IwJ0D F6L4hjO819IInf6upH9tfQNnueflWyKzfg2zitV+ILZ4YtZViyCKqayw CSPE8OkFlszZyCESzhrXqoPdJ0oHdZCG4lOlRIgZfrMLC4yTI56iiwFc UsKy7BhNPW+hcc4r+0WB9BCpsiei/FjPMcyeMrx1W+s/xgW7/55Nq+dM PUn9v24uCptZUupn/7CRgMGM5DmWe94QIswAQjH2mXNfOgVPOiceLYzU mcNoKudvSUu1hbzJbVHA4UNWDm2vvsdsEzrOEzqO0ZVczLoZzWU4WpLf IlKm481OKkzAP9Y5F4iTTSIrbVcAuEW/iz5zfqWirgGniiTCszAie8lH u1EPBgGnfotqhq9IbNA6aKNUreJPLvJnds7J/aQmiSdm15pAq71B26X5 BmoZVhbNmh6MHXkq99EIt0yRMEOfPLRN7euza8Idd4mA+E8jpdgtYdJD LC7f2SoQxaN4RMr5MC/Z1ENQgLMYRkd87pEQycAlNAoWMPJMuoDNdwhV 15F8+pvkvfu5cm9FoEWvgS+onibUM9EC9L9EDdfDdW1Hf1QfUinVoMf/ Szf1urkPVNl0nNYF
+sub.example.com. 3600 IN RRSIG DNSKEY 7 3 3600 20251231235959 20160308093040 27527 sub.example.com. CzB+UmU98ArL/HRIOMyHV87PPYoH3G/KKdJlbjtNZAaHG+K6Lad0pKW5 wZR3By1AMlIN9ta8374q+nCEtY+ryM7yBFpzSTmBqrf7ZhkxWh2OSnrI CllC3CsSeltsOq/AEQZwJLQG/gQiCqqQnJY4mneKhcg0Bzc0hpe8c1Dq C5eaHKqt7BaVRO1Ix6OKqEqjHzwd5HpKd2pzU91HyfvHsWrOnKyIwHJP nyOcuHESKN97YLey9Onw0eXjUYdbG5GM12OV1qawShOthcm7XUQiJ0Xl V7y0pNekCxXZdQQI/XhVj8XyLa5pLy8PaOLqypbMBg19J5diLUZYAt/f Dj/EzQ==
+sub.example.com. 3600 IN RRSIG DNSKEY 7 3 3600 20251231235959 20160308093040 38364 sub.example.com. xzyO85eLRwVsg9VI4RnXnjrwf0/TCMub7UcOr7TWWhwt9iR8KFSenx17 EVG1OlgEzRrdZLQWJBPlNBR5aLpsNlzUj+cnCpdG6NtUjcdqRJxb+64Y RktG5Hz35AV7Iegs3L6tFdE4J2moGCDC0y8Rm9wyL+mCUNylpnXUOo8D NDpd7VcYKoieGWxLd8OK5aCYUlB2ziL9yIMOZR+sGEPZWR6ABXDbUF6S ddj7lbZ7y+GHp2XpjDvpmbRSrznNmopzn71O59sCiog8obnGif02EXEn 3L2a8eGx3tMhCZZAPaqJrocTIAmye0vLt0xT22WFPxmcButV1UYZd00m KwJaKgUB450wdub4aAXVvtTx7Us++6zRepZ3VtXARDT+qGzBUkISEuSM FbLHlqqdQeLTcfdu7azEfyCWudoDTbXejFQjFtWkSo6SwEV8sC64rMV6 AFytMBvksBD0tjGrWvPkdDxWa43SQja8BiTlKugtM7zJgqBH9pi1MN4o asc3hyBHBKEiX8ilK7GBTqFph8tdRxawWsaK273pATBLeQfHM2jKcg5p ULhSLxYDvJ+TgYKJkFyFd4C78HffgrashJvrxNsK1QQk05bpTGk9j6ja fzzyB6mDhWGLux1/i++akwTOKsWmFnNe6MXKTN1gnEw4pny3m7zBmh0x gFkbfEo1aDU=
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www.sub.example.com. IN A
+SECTION ANSWER
+www.sub.example.com. 3600 IN A 1.2.3.123
+www.sub.example.com. 3600 IN RRSIG A 7 4 3600 20251231235959 20160308093040 27527 sub.example.com. QiGpNqXdMQWFYzXMk0FhqEJuzAYijUHOywSUS/hgDxoxBRXBam/tfb3d 1Yqv4+ZVI06ZzOvC2YHRCULjBqjzsQbxxqzPtkfBWbAP/urRFsuwo1zx OSbW9xSUYmHbHicRLFxijvZhuJXX/11tja4dj9ZOeYF/HdWP3r38H4WT /8w3vKr7h2StmL2fY43LxqQm23voNiqJ1dsXLtjyoeIqH40jdMqeLKB+ PJ9p4d3HzOg7uIhLSQYi9slUBWQ10a4uxEBEXmeCI5gLQPot8ijBxF2t TsIOMMPieGC5Zlt9YeT6fsdM6HiUDrfCGbuf9TdlmQqNwRcd8orW58HV SgGalg==
+SECTION ADDITIONAL
+ENTRY_END
+RANGE_END
+
+
+STEP 10 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.sub.example.com. IN A
+ENTRY_END
+
+STEP 20 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+www.sub.example.com. IN A
+SECTION ANSWER
+www.sub.example.com. 3600 IN A 1.2.3.123
+www.sub.example.com. 3600 IN RRSIG A 7 4 3600 20251231235959 20160308093040 27527 sub.example.com. QiGpNqXdMQWFYzXMk0FhqEJuzAYijUHOywSUS/hgDxoxBRXBam/tfb3d 1Yqv4+ZVI06ZzOvC2YHRCULjBqjzsQbxxqzPtkfBWbAP/urRFsuwo1zx OSbW9xSUYmHbHicRLFxijvZhuJXX/11tja4dj9ZOeYF/HdWP3r38H4WT /8w3vKr7h2StmL2fY43LxqQm23voNiqJ1dsXLtjyoeIqH40jdMqeLKB+ PJ9p4d3HzOg7uIhLSQYi9slUBWQ10a4uxEBEXmeCI5gLQPot8ijBxF2t TsIOMMPieGC5Zlt9YeT6fsdM6HiUDrfCGbuf9TdlmQqNwRcd8orW58HV SgGalg==
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+STEP 30 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.sub.example.com. IN A
+ENTRY_END
+
+; cached answer
+STEP 40 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+www.sub.example.com. IN A
+SECTION ANSWER
+www.sub.example.com. 3600 IN A 1.2.3.123
+www.sub.example.com. 3600 IN RRSIG A 7 4 3600 20251231235959 20160308093040 27527 sub.example.com. QiGpNqXdMQWFYzXMk0FhqEJuzAYijUHOywSUS/hgDxoxBRXBam/tfb3d 1Yqv4+ZVI06ZzOvC2YHRCULjBqjzsQbxxqzPtkfBWbAP/urRFsuwo1zx OSbW9xSUYmHbHicRLFxijvZhuJXX/11tja4dj9ZOeYF/HdWP3r38H4WT /8w3vKr7h2StmL2fY43LxqQm23voNiqJ1dsXLtjyoeIqH40jdMqeLKB+ PJ9p4d3HzOg7uIhLSQYi9slUBWQ10a4uxEBEXmeCI5gLQPot8ijBxF2t TsIOMMPieGC5Zlt9YeT6fsdM6HiUDrfCGbuf9TdlmQqNwRcd8orW58HV SgGalg==
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/val_root_ds.rpl b/tests/integration/deckard/sets/resolver/val_root_ds.rpl
new file mode 100644
index 0000000..d39ab82
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_root_ds.rpl
@@ -0,0 +1,88 @@
+do-ip6: no
+
+stub-addr: 198.41.0.4 # a.root-servers.net
+trust-anchor: . 172800 IN DS 19036 8 2 49aac11d7b6f6446702e54a1607371607a1a41855200fd2ce1cdde32f24e8fb5
+val-override-date: 20180410000000
+CONFIG_END
+
+SCENARIO_BEGIN query . DS
+; FIX ME: unbound queries way too much, so not providing all those answers
+; pdns test hangs, I don't know why
+
+RANGE_BEGIN 0 10
+ ADDRESS 198.41.0.4
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. DS
+SECTION AUTHORITY
+. 86400 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018040900 1800 900 604800 86400
+. 86400 IN RRSIG SOA 8 0 86400 20180422050000 20180409040000 39570 . oV+H+628tDLFEEoxgZNbRDA4Die3VEdejO7iMSHLEYyX8oFwhqoWF2gp XsRlpEnrt07gRfabkPW3DSzhl8syZ+1m6pQ0JDLLBAGODuEYMOYLcJ4n b4Z4WbKwtaL7beRhLf6aLvh51Ozv8qpmV9ZAC7OmlqUt/1h5V1j0/Apq Df3DijQrXs1SVzMWRsKm3kvutfA7a1CPzMs8RK29ujtlZqm0dIEfresJ VtzN2cx1kzvppNF0pNFXzFwh+emZe/eiV4ZyJp4Fm0UrsLnGqLqoQqkE 63panwTQ7nA8VqbrMxj4DGZGgsVcQudzmPfdUYlXCbG6hLO5yyGNFn2C lehfcQ==
+. 86400 IN NSEC aaa. NS SOA RRSIG NSEC DNSKEY
+. 86400 IN RRSIG NSEC 8 0 86400 20180422050000 20180409040000 39570 . z4xVID27wqu5mcYobS0nFvR5gHsud2HuGKxpvx6gVcyoDMa2vFBTTEqM q2eAATusuN+VSFSgQcoyE8Z7QMVYWkm/nC1LenL4rHLhABRtuo77RwmU R9R5/xkSNoTm7ZL420FWGG3TKrSCDnpEkkloBvtVJsJ4YCg6YuM0hPd2 2P5+teSUH1Py2ODGCVNgTFiUeK6ZVkIbnvL9VfC/g7v4nGLPuDUNsMmr aJ4mgnpqZJZJr2EYKTzxtzKnadXgLEDnwUSczY7yc8ZYU9+6VIu6Hlvm lttaDagf+xwT3BaultN3xOQfQ9BG+dqTuMyA4ZwuirjKN9s7uzqUF+y0 Pl6huw==
+ENTRY_END
+
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. DNSKEY
+SECTION ANSWER
+. 172800 IN DNSKEY 256 3 8 AwEAAdU4aKlDgEpXWWpH5aXHJZI1Vm9Cm42mGAsqkz3akFctS6zsZHC3pNNMug99fKa7OW+tRHIwZEc//mX8Jt6bcw5bPgRHG6u2eT8vUpbXDPVs1ICGR6FhlwFWEOyxbIIiDfd7Eq6eALk5RNcauyE+/ZP+VdrhWZDeEWZRrPBLjByBWTHl+v/f+xvTJ3Stcq2tEqnzS2CCOr6RTJepprYhu+5Yl6aRZmEVBK27WCW1Zrk1LekJvJXfcyKSKk19C5M5JWX58px6nB1IS0pMs6aCIK2yaQQVNUEg9XyQzBSv/rMxVNNy3VAqOjvh+OASpLMm4GECbSSe8jtjwG0I78sfMZc=
+. 172800 IN DNSKEY 257 3 8 AwEAAagAIKlVZrpC6Ia7gEzahOR+9W29euxhJhVVLOyQbSEW0O8gcCjFFVQUTf6v58fLjwBd0YI0EzrAcQqBGCzh/RStIoO8g0NfnfL2MTJRkxoXbfDaUeVPQuYEhg37NZWAJQ9VnMVDxP/VHL496M/QZxkjf5/Efucp2gaDX6RS6CXpoY68LsvPVjR0ZSwzz1apAzvN9dlzEheX7ICJBBtuA6G3LQpzW5hOA2hzCTMjJPJ8LbqF6dsV6DoBQzgul0sGIcGOYl7OyQdXfZ57relSQageu+ipAdTTJ25AsRTAoub8ONGcLmqrAmRLKBP1dfwhYB4N7knNnulqQxA+Uk1ihz0=
+. 172800 IN DNSKEY 257 3 8 AwEAAaz/tAm8yTn4Mfeh5eyI96WSVexTBAvkMgJzkKTOiW1vkIbzxeF3+/4RgWOq7HrxRixHlFlExOLAJr5emLvN7SWXgnLh4+B5xQlNVz8Og8kvArMtNROxVQuCaSnIDdD5LKyWbRd2n9WGe2R8PzgCmr3EgVLrjyBxWezF0jLHwVN8efS3rCj/EWgvIWgb9tarpVUDK/b58Da+sqqls3eNbuv7pr+eoZG+SrDK6nWeL3c6H5Apxz7LjVc1uTIdsIXxuOLYA4/ilBmSVIzuDWfdRUfhHdY6+cn8HFRm+2hM8AnXGXws9555KrUB5qihylGa8subX2Nn6UwNR1AkUTV74bU=
+. 172800 IN DNSKEY 256 3 8 AwEAAaDJd0KOMYGCEF0/cftC2hrFtz5GSn1HOiaxEp053AfbxQ3pT8BEtahPiUkCo1Qx4PECJ23YwaFhfWWjapr6AFxhD8klfZGp95ickoRlm91ZzXX/mcfn9vlUpZK2M8qjljNMzZJSopFY+cxRvib2Irb6YeP2a0vppaLnvR4BeOyEkQolLqvVHW7UqDFiP/CM15BWBsAIdbyo8L1h3OeP63TaYIrWttjGBILeZinSaJ39amiVs8t00RjTaKVo3vY2k6dje1Rh1ELqjNj8+cKA8iWC3VU7ApkyuGDy631RDILa6wCgcBVCzfFfOthQILxQra88tNWzCVoryQ89f1WjBJc=
+. 172800 IN RRSIG DNSKEY 8 0 172800 20180422000000 20180401000000 19036 . D+U+adJuahA0uubWyJxBronfunX2Bqe6GnttiCzzxby6V5bX51IX8lcMCUHt7e6peQhSWcoKGJvsncX0gYj2PaZjUvZjwn2f08NmoV99kUJlitP6rdyk0tWu8PnYfF/6pahezkbq8Wwl0jVndl6jQ3cAskuM0UDWmpQCxAnhoQPkJjibZVp/FpYG0hJeApC8wfOAWh215pbACNwPCA4N0dj5F6KOPERViDEV8/qq7yBMebB+rp3BKT2415pIcp/CGN3cdJIpbCCiLjK786fjNeqxlXziIjFxiFaqw3Jk1cJqMhnluxF7iA2bOH315jjkj4VcDaBJDCIKrcdLv/9b5g==
+ENTRY_END
+
+RANGE_END
+
+
+STEP 10 QUERY
+ENTRY_BEGIN
+REPLY RD AD DO
+SECTION QUESTION
+. DS
+ENTRY_END
+
+STEP 11 CHECK_ANSWER ; unchanged from the authoritative answer
+ENTRY_BEGIN
+REPLY QR RD RA AD NOERROR
+MATCH opcode rcode flags question answer authority additional
+SECTION QUESTION
+. DS
+SECTION AUTHORITY
+. 86400 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018040900 1800 900 604800 86400
+. 86400 IN RRSIG SOA 8 0 86400 20180422050000 20180409040000 39570 . oV+H+628tDLFEEoxgZNbRDA4Die3VEdejO7iMSHLEYyX8oFwhqoWF2gp XsRlpEnrt07gRfabkPW3DSzhl8syZ+1m6pQ0JDLLBAGODuEYMOYLcJ4n b4Z4WbKwtaL7beRhLf6aLvh51Ozv8qpmV9ZAC7OmlqUt/1h5V1j0/Apq Df3DijQrXs1SVzMWRsKm3kvutfA7a1CPzMs8RK29ujtlZqm0dIEfresJ VtzN2cx1kzvppNF0pNFXzFwh+emZe/eiV4ZyJp4Fm0UrsLnGqLqoQqkE 63panwTQ7nA8VqbrMxj4DGZGgsVcQudzmPfdUYlXCbG6hLO5yyGNFn2C lehfcQ==
+. 86400 IN NSEC aaa. NS SOA RRSIG NSEC DNSKEY
+. 86400 IN RRSIG NSEC 8 0 86400 20180422050000 20180409040000 39570 . z4xVID27wqu5mcYobS0nFvR5gHsud2HuGKxpvx6gVcyoDMa2vFBTTEqM q2eAATusuN+VSFSgQcoyE8Z7QMVYWkm/nC1LenL4rHLhABRtuo77RwmU R9R5/xkSNoTm7ZL420FWGG3TKrSCDnpEkkloBvtVJsJ4YCg6YuM0hPd2 2P5+teSUH1Py2ODGCVNgTFiUeK6ZVkIbnvL9VfC/g7v4nGLPuDUNsMmr aJ4mgnpqZJZJr2EYKTzxtzKnadXgLEDnwUSczY7yc8ZYU9+6VIu6Hlvm lttaDagf+xwT3BaultN3xOQfQ9BG+dqTuMyA4ZwuirjKN9s7uzqUF+y0 Pl6huw==
+ENTRY_END
+
+; from cache: exactly the same again, but now authoritatives do not reply
+STEP 20 QUERY
+ENTRY_BEGIN
+REPLY RD AD DO
+SECTION QUESTION
+. DS
+ENTRY_END
+
+STEP 21 CHECK_ANSWER ; unchanged from the authoritative answer
+ENTRY_BEGIN
+REPLY QR RD RA AD NOERROR
+MATCH opcode rcode flags question answer authority additional
+SECTION QUESTION
+. DS
+SECTION AUTHORITY
+. 86400 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018040900 1800 900 604800 86400
+. 86400 IN RRSIG SOA 8 0 86400 20180422050000 20180409040000 39570 . oV+H+628tDLFEEoxgZNbRDA4Die3VEdejO7iMSHLEYyX8oFwhqoWF2gp XsRlpEnrt07gRfabkPW3DSzhl8syZ+1m6pQ0JDLLBAGODuEYMOYLcJ4n b4Z4WbKwtaL7beRhLf6aLvh51Ozv8qpmV9ZAC7OmlqUt/1h5V1j0/Apq Df3DijQrXs1SVzMWRsKm3kvutfA7a1CPzMs8RK29ujtlZqm0dIEfresJ VtzN2cx1kzvppNF0pNFXzFwh+emZe/eiV4ZyJp4Fm0UrsLnGqLqoQqkE 63panwTQ7nA8VqbrMxj4DGZGgsVcQudzmPfdUYlXCbG6hLO5yyGNFn2C lehfcQ==
+. 86400 IN NSEC aaa. NS SOA RRSIG NSEC DNSKEY
+. 86400 IN RRSIG NSEC 8 0 86400 20180422050000 20180409040000 39570 . z4xVID27wqu5mcYobS0nFvR5gHsud2HuGKxpvx6gVcyoDMa2vFBTTEqM q2eAATusuN+VSFSgQcoyE8Z7QMVYWkm/nC1LenL4rHLhABRtuo77RwmU R9R5/xkSNoTm7ZL420FWGG3TKrSCDnpEkkloBvtVJsJ4YCg6YuM0hPd2 2P5+teSUH1Py2ODGCVNgTFiUeK6ZVkIbnvL9VfC/g7v4nGLPuDUNsMmr aJ4mgnpqZJZJr2EYKTzxtzKnadXgLEDnwUSczY7yc8ZYU9+6VIu6Hlvm lttaDagf+xwT3BaultN3xOQfQ9BG+dqTuMyA4ZwuirjKN9s7uzqUF+y0 Pl6huw==
+ENTRY_END
+
+SCENARIO_END
+
diff --git a/tests/integration/deckard/sets/resolver/val_rrsig.rpl b/tests/integration/deckard/sets/resolver/val_rrsig.rpl
new file mode 100644
index 0000000..7fb8fa2
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_rrsig.rpl
@@ -0,0 +1,171 @@
+do-ip6: no
+
+; config options
+; The island of trust is at example.com
+;server:
+ trust-anchor: "example.com. 3600 IN DS 23027 7 1 3B2616A3B46D23EA5E4D709C5D157000779D66A1 "
+val-override-date: "20181130121918"
+; target-fetch-policy: "0 0 0 0 0"
+; fake-sha1: yes
+
+;stub-zone:
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+query-minimization: off
+CONFIG_END
+
+SCENARIO_BEGIN Test validator with qtype RRSIG response
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20181230101918 20181130101918 23027 example.com. NL1XpsE+Edp+/XshOxsDvyADfCIu99Un1DSLAYU9kmVa+6GZMgIQchPl lRcC3YboPLAGp05RP24XBk/GB6pwlLCjg8BgxdJ6nwAXSUwHYTHFs/vk BMyGIbMgYp9PlB80GHSVUV9NK5A2QpIVnLLxuWXz+T3x8+HDAVa4X6mo n3M= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101918 20181130101918 23027 example.com. VW19ITdySwfn5/PP9dW5rzbKtvFs3F1LpMXcMLgPYriNM2t3xsGQZa+T qRlUERcaUPrmgLtMQJgClTg/Pd9wdn9TZmAt6gtd9PDfWe2n3r4SugCR BxJ9QHaYCCSpNOrir5CyblUpefP48VP+glDm0H3+rlSjjbG2K9bgHsKT 0iM= ;{id = 2854}
+ENTRY_END
+
+; response to DNSKEY priming query
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN DNSKEY
+SECTION ANSWER
+example.com. 3600 IN DNSKEY 256 3 7 AwEAAa+ON9qDV53VRATmSZhoARXGtxj0nRF6zg1/erJ9mRNlDZL7bJ/Q oDmfqIRdsTCuXSjLXsNAPVxVZI4YvSWWoe8xVTNa3S2z3PiCZIyGNnD/ d6L42/RxhBureNqf6iRD4smn2BPlf4mk3QHVAAcOvNrVITJExTcxqM7H VK/4eLgP ;{id = 2854 (zsk), size = 1688b}
+example.com. 3600 IN RRSIG DNSKEY 7 2 3600 20181230101918 20181130101918 23027 example.com. K8QveHt1/E6aSUv2Xo0nPaFi9ehOrn5iQCLyo+TNdgqr6qaJTfqbXulF E05EHUacTzuWlaSlyR1AULB6IHi4/HEpRySPudVayZe6qASjeGI6v7D7 9nuJih5K/9kEBYU645291R06DhI1B5PcqlfLcKiwO2Bpax+n1Rc8v23k 600= ;{id = 2854}
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20181230101918 20181130101918 23027 example.com. NL1XpsE+Edp+/XshOxsDvyADfCIu99Un1DSLAYU9kmVa+6GZMgIQchPl lRcC3YboPLAGp05RP24XBk/GB6pwlLCjg8BgxdJ6nwAXSUwHYTHFs/vk BMyGIbMgYp9PlB80GHSVUV9NK5A2QpIVnLLxuWXz+T3x8+HDAVa4X6mo n3M= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101918 20181130101918 23027 example.com. VW19ITdySwfn5/PP9dW5rzbKtvFs3F1LpMXcMLgPYriNM2t3xsGQZa+T qRlUERcaUPrmgLtMQJgClTg/Pd9wdn9TZmAt6gtd9PDfWe2n3r4SugCR BxJ9QHaYCCSpNOrir5CyblUpefP48VP+glDm0H3+rlSjjbG2K9bgHsKT 0iM= ;{id = 2854}
+ENTRY_END
+
+; response to query for A
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101918 20181130101918 23027 example.com. VW19ITdySwfn5/PP9dW5rzbKtvFs3F1LpMXcMLgPYriNM2t3xsGQZa+T qRlUERcaUPrmgLtMQJgClTg/Pd9wdn9TZmAt6gtd9PDfWe2n3r4SugCR BxJ9QHaYCCSpNOrir5CyblUpefP48VP+glDm0H3+rlSjjbG2K9bgHsKT 0iM= ;{id = 2854}
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20181230101918 20181130101918 23027 example.com. NL1XpsE+Edp+/XshOxsDvyADfCIu99Un1DSLAYU9kmVa+6GZMgIQchPl lRcC3YboPLAGp05RP24XBk/GB6pwlLCjg8BgxdJ6nwAXSUwHYTHFs/vk BMyGIbMgYp9PlB80GHSVUV9NK5A2QpIVnLLxuWXz+T3x8+HDAVa4X6mo n3M= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+www.example.com. 3600 IN RRSIG A 7 3 3600 20181230101918 20181130101918 23027 example.com. AudSERijN/0vKfjRw0R0ER2ogfWxZlSQeRKnZSrqS0NXALQjkl0AosJO sMMdZZ3j3JOVqlrDTRFUtHgYl7BKgsy0srbE7RDsgFTjMmGAcgTZE6i1 lv+At+P93kZJemNpIypOTs0AlU8IoU/p+VnmQ8MIQ+lCxNIOQFTLRR3S Cn0= ;{id = 2854}
+ENTRY_END
+
+; RRSIG query
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN RRSIG
+SECTION ANSWER
+;www.example.com. IN A 10.20.30.40
+www.example.com. 3600 IN RRSIG A 7 3 3600 20181230101918 20181130101918 23027 example.com. AudSERijN/0vKfjRw0R0ER2ogfWxZlSQeRKnZSrqS0NXALQjkl0AosJO sMMdZZ3j3JOVqlrDTRFUtHgYl7BKgsy0srbE7RDsgFTjMmGAcgTZE6i1 lv+At+P93kZJemNpIypOTs0AlU8IoU/p+VnmQ8MIQ+lCxNIOQFTLRR3S Cn0= ;{id = 2854}
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20181230101918 20181130101918 23027 example.com. NL1XpsE+Edp+/XshOxsDvyADfCIu99Un1DSLAYU9kmVa+6GZMgIQchPl lRcC3YboPLAGp05RP24XBk/GB6pwlLCjg8BgxdJ6nwAXSUwHYTHFs/vk BMyGIbMgYp9PlB80GHSVUV9NK5A2QpIVnLLxuWXz+T3x8+HDAVa4X6mo n3M= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101918 20181130101918 23027 example.com. VW19ITdySwfn5/PP9dW5rzbKtvFs3F1LpMXcMLgPYriNM2t3xsGQZa+T qRlUERcaUPrmgLtMQJgClTg/Pd9wdn9TZmAt6gtd9PDfWe2n3r4SugCR BxJ9QHaYCCSpNOrir5CyblUpefP48VP+glDm0H3+rlSjjbG2K9bgHsKT 0iM= ;{id = 2854}
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.example.com. IN RRSIG
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH opcode rcode flags question answer
+REPLY QR RD RA DO NOERROR
+SECTION QUESTION
+www.example.com. IN RRSIG
+SECTION ANSWER
+www.example.com. 3600 IN RRSIG A 7 3 3600 20181230101918 20181130101918 23027 example.com. AudSERijN/0vKfjRw0R0ER2ogfWxZlSQeRKnZSrqS0NXALQjkl0AosJO sMMdZZ3j3JOVqlrDTRFUtHgYl7BKgsy0srbE7RDsgFTjMmGAcgTZE6i1 lv+At+P93kZJemNpIypOTs0AlU8IoU/p+VnmQ8MIQ+lCxNIOQFTLRR3S Cn0= ;{id = 2854}
+;SECTION AUTHORITY
+;example.com. IN NS ns.example.com.
+;example.com. 3600 IN RRSIG NS 7 2 3600 20181230101918 20181130101918 23027 example.com. NL1XpsE+Edp+/XshOxsDvyADfCIu99Un1DSLAYU9kmVa+6GZMgIQchPl lRcC3YboPLAGp05RP24XBk/GB6pwlLCjg8BgxdJ6nwAXSUwHYTHFs/vk BMyGIbMgYp9PlB80GHSVUV9NK5A2QpIVnLLxuWXz+T3x8+HDAVa4X6mo n3M= ;{id = 2854}
+;SECTION ADDITIONAL
+;ns.example.com. IN A 1.2.3.4
+;ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101918 20181130101918 23027 example.com. VW19ITdySwfn5/PP9dW5rzbKtvFs3F1LpMXcMLgPYriNM2t3xsGQZa+T qRlUERcaUPrmgLtMQJgClTg/Pd9wdn9TZmAt6gtd9PDfWe2n3r4SugCR BxJ9QHaYCCSpNOrir5CyblUpefP48VP+glDm0H3+rlSjjbG2K9bgHsKT 0iM= ;{id = 2854}
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/val_secds.rpl b/tests/integration/deckard/sets/resolver/val_secds.rpl
new file mode 100644
index 0000000..556a925
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_secds.rpl
@@ -0,0 +1,215 @@
+do-ip6: no
+
+; config options
+; The island of trust is at example.com
+;server:
+ trust-anchor: "example.com. 3600 IN DS 50354 7 1 4BAD1572F3C729F6F04749D8B19E00D8356E3871 "
+val-override-date: "20181130121919"
+; target-fetch-policy: "0 0 0 0 0"
+; fake-sha1: yes
+
+;stub-zone:
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+query-minimization: off
+CONFIG_END
+
+SCENARIO_BEGIN Test validator with secure delegation
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.sub.example.com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.sub.example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20181230101919 20181130101919 50354 example.com. t69qTSQb8vTWf/DKSpTtvWAACIa9sKDKmOILmY73STpsvjo036t1sBXV iJGBtb6P0dC/gUeAXZdZYgTC2vsTJLSjOtzc8lUTVgswvn2QDSaY8eU2 5UwgGbqZF5cOW87a/NQV1pFZSWi9eFo8IBvbCP+mio6wKvFNqQH7Ja8T aNw= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101919 20181130101919 50354 example.com. Jo9iWIAFOGFQlSzoyXWSRmuZvftlr6NyyI2wFnYVa94mivyRbJViL3G9 vPbhSuP7lkD1DzFbH2nztu6LBqavrVCQCGsEixo6f5eUhywptl/hLTLp 8shS5iWfGvZKXobH9n9ryJIQfwPoVHhEfx5FpOKR+A7ORQOgsQb9TaGv EX8= ;{id = 2854}
+ENTRY_END
+
+; response to DNSKEY priming query
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN DNSKEY
+SECTION ANSWER
+example.com. 3600 IN DNSKEY 256 3 7 AwEAAcQBfewjdxsAmqiSCuk/SB/CrZSA3C4DvikJfW9pVEqRbEwe05Ii UmGaajAfF7RtC5GD1Lq7T0wVpIJLl7VwX2oCB+jvBIjGPfQ9yvyrfEdM r/hIQlFoEuPqAOwzxJUiOyJOh6utSEwRSnWLoqd8xsxnUJWC6Q7jLgs1 VF4YEnJ7 ;{id = 2854 (zsk), size = 1688b}
+example.com. 3600 IN RRSIG DNSKEY 7 2 3600 20181230101919 20181130101919 50354 example.com. a2fVpjpw/Bf7coByItHRN6tUhnrSLsvAxGyYz4YyNlRJeW2erOgYvwSQ 5JYRwQQaUrtMD1AnBE9B0Fdey5gIi/9xl5LPBqYbfTR9yxcWJoUwmwBs 2JDx6dwzIr5DItXgSNjKd0x0A2cEjFO25XR6R+ukvFZfIBaZW4d41vjw AFM= ;{id = 2854}
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20181230101919 20181130101919 50354 example.com. t69qTSQb8vTWf/DKSpTtvWAACIa9sKDKmOILmY73STpsvjo036t1sBXV iJGBtb6P0dC/gUeAXZdZYgTC2vsTJLSjOtzc8lUTVgswvn2QDSaY8eU2 5UwgGbqZF5cOW87a/NQV1pFZSWi9eFo8IBvbCP+mio6wKvFNqQH7Ja8T aNw= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101919 20181130101919 50354 example.com. Jo9iWIAFOGFQlSzoyXWSRmuZvftlr6NyyI2wFnYVa94mivyRbJViL3G9 vPbhSuP7lkD1DzFbH2nztu6LBqavrVCQCGsEixo6f5eUhywptl/hLTLp 8shS5iWfGvZKXobH9n9ryJIQfwPoVHhEfx5FpOKR+A7ORQOgsQb9TaGv EX8= ;{id = 2854}
+ENTRY_END
+
+; response for delegation to sub.example.com.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.sub.example.com. IN A
+SECTION ANSWER
+SECTION AUTHORITY
+sub.example.com. IN NS ns.sub.example.com.
+sub.example.com. 3600 IN DS 58437 5 1 CA63FDB4AD33BB461138E76EC4DC94DBE0F038A8
+sub.example.com. 3600 IN RRSIG DS 7 3 3600 20181230101919 20181130101919 50354 example.com. g46bxGtNNjp5Zw4L06Yfz/GHWoZbuhlTYMjy/pwREOo1ns3YwF13EK7y juBEsnzR9t+38koZNRgQ1GGI2cAhBxt95xakkvop64zqvdQ9oLqUdapp LfbuPSruLmNUdv6iePkjBuBiSa0XDMaKzfj+gMaIti/43W2wGFDpD+5Z x88= ;{id = 2854}
+SECTION ADDITIONAL
+ns.sub.example.com. IN A 1.2.3.6
+ENTRY_END
+
+; response for delegation to sub.example.com.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+sub.example.com. IN DNSKEY
+SECTION ANSWER
+SECTION AUTHORITY
+sub.example.com. IN NS ns.sub.example.com.
+sub.example.com. 3600 IN DS 58437 5 1 CA63FDB4AD33BB461138E76EC4DC94DBE0F038A8
+sub.example.com. 3600 IN RRSIG DS 7 3 3600 20181230101919 20181130101919 50354 example.com. g46bxGtNNjp5Zw4L06Yfz/GHWoZbuhlTYMjy/pwREOo1ns3YwF13EK7y juBEsnzR9t+38koZNRgQ1GGI2cAhBxt95xakkvop64zqvdQ9oLqUdapp LfbuPSruLmNUdv6iePkjBuBiSa0XDMaKzfj+gMaIti/43W2wGFDpD+5Z x88= ;{id = 2854}
+SECTION ADDITIONAL
+ns.sub.example.com. IN A 1.2.3.6
+ENTRY_END
+RANGE_END
+
+; ns.sub.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.6
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+sub.example.com. IN NS
+SECTION ANSWER
+sub.example.com. IN NS ns.sub.example.com.
+sub.example.com. 3600 IN RRSIG NS 5 3 3600 20181230101919 20181130101919 58437 sub.example.com. ItcLJAYgLspxtEVeL8fZEb8j1TC6Y92edHMA2/wXO7xiQ+hz7RHJvp2x z3KAAhFX9TJgcrBbWKfpnZ51+IOTgpDLJvZMCsAmHJNmVdITbzzQc5O5 AA2mz0j5Gu9HoMFYZjgHAxRB+YJEYzqMOFAdp4kDhKyVXsqQkiZ/P2BD 41I= ;{id = 30899}
+SECTION ADDITIONAL
+ns.sub.example.com. IN A 1.2.3.6
+ns.sub.example.com. 3600 IN RRSIG A 5 4 3600 20181230101919 20181130101919 58437 sub.example.com. Al3EkHOo8/SiRqHaHxOA/d2KWRRUaTRklYFlh32mjW20m1oY6G+UpuuZ P6JoNxb7MuME2hd097u8voJlpOtPn90vlTrPgl8QfYroicHWhAepHkT1 bRdwOqVnkUtw4B3uAkz/kkSgOmKsmqvcSRMIqULTIVeSXBPHE0331hcF uGc= ;{id = 30899}
+ENTRY_END
+
+; response to DNSKEY priming query
+; sub.example.com. 3600 IN DS 58437 5 1 CA63FDB4AD33BB461138E76EC4DC94DBE0F038A8
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+sub.example.com. IN DNSKEY
+SECTION ANSWER
+sub.example.com. 3600 IN DNSKEY 256 3 5 AwEAAcidUcbaG85xnWPvZBRbP2yb8hg06PeLTFOpZT2GUMRx3EaOanGC G+qffFqMx2427wBoHXXWTlN97aR1H/GBjnH65BQhXC0LFnamFpIA+5kg x8Q6qJP72mGfx0lSnvzSsdnwGJ2DYcSV44fQ/edMxW0YlQH2rkNGlzrr KBMCv3ip ;{id = 30899 (zsk), size = 512b}
+sub.example.com. 3600 IN RRSIG DNSKEY 5 3 3600 20181230101919 20181130101919 58437 sub.example.com. nhsKPftsVfsu1hx+zqQ2oCx+NEVzuyIHLAgylBnIGG/alPdfne8qUzPB f3KNGTwuCGfIhUBL7TveVAm5WcPfFi7BDW0uhHqFyJJoJvMLBuiLmCL5 tB13KS2f/HaowRAFuua7g/1e4SjJ0FXfU+/xuP0wrMsI5GI9QKZJr+Bq yi8= ;{id = 30899}
+SECTION AUTHORITY
+sub.example.com. IN NS ns.sub.example.com.
+sub.example.com. 3600 IN RRSIG NS 5 3 3600 20181230101919 20181130101919 58437 sub.example.com. ItcLJAYgLspxtEVeL8fZEb8j1TC6Y92edHMA2/wXO7xiQ+hz7RHJvp2x z3KAAhFX9TJgcrBbWKfpnZ51+IOTgpDLJvZMCsAmHJNmVdITbzzQc5O5 AA2mz0j5Gu9HoMFYZjgHAxRB+YJEYzqMOFAdp4kDhKyVXsqQkiZ/P2BD 41I= ;{id = 30899}
+SECTION ADDITIONAL
+ns.sub.example.com. IN A 1.2.3.6
+ns.sub.example.com. 3600 IN RRSIG A 5 4 3600 20181230101919 20181130101919 58437 sub.example.com. Al3EkHOo8/SiRqHaHxOA/d2KWRRUaTRklYFlh32mjW20m1oY6G+UpuuZ P6JoNxb7MuME2hd097u8voJlpOtPn90vlTrPgl8QfYroicHWhAepHkT1 bRdwOqVnkUtw4B3uAkz/kkSgOmKsmqvcSRMIqULTIVeSXBPHE0331hcF uGc= ;{id = 30899}
+ENTRY_END
+
+; response to query of interest
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.sub.example.com. IN A
+SECTION ANSWER
+www.sub.example.com. IN A 11.11.11.11
+www.sub.example.com. 3600 IN RRSIG A 5 4 3600 20181230101919 20181130101919 58437 sub.example.com. gXjsKvu10zuDSjsMrDT3GN2tjkVbC4xrGjvY3VUL2+RuNI0iAdNUngTv LcHvFpS8jdgQ8AKRNXjL+I7buQmnmfA335Atlzk9plgFxjv313fn7ri6 s4mhBy6+Kyjf8v/wd3cnO9myXxSGAtp7sUcYI3D4CJaWiu8JQ4GgnE+P fuA= ;{id = 30899}
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.sub.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+www.sub.example.com. IN A
+SECTION ANSWER
+www.sub.example.com. 3600 IN A 11.11.11.11
+www.sub.example.com. 3600 IN RRSIG A 5 4 3600 20181230101919 20181130101919 58437 sub.example.com. gXjsKvu10zuDSjsMrDT3GN2tjkVbC4xrGjvY3VUL2+RuNI0iAdNUngTv LcHvFpS8jdgQ8AKRNXjL+I7buQmnmfA335Atlzk9plgFxjv313fn7ri6 s4mhBy6+Kyjf8v/wd3cnO9myXxSGAtp7sUcYI3D4CJaWiu8JQ4GgnE+P fuA= ;{id = 30899}
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/val_secds_nosig.rpl b/tests/integration/deckard/sets/resolver/val_secds_nosig.rpl
new file mode 100644
index 0000000..1120bd2
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_secds_nosig.rpl
@@ -0,0 +1,235 @@
+do-ip6: no
+
+; config options
+; The island of trust is at example.com
+;server:
+ trust-anchor: "example.com. 3600 IN DS 2854 3 1 46e4ffc6e9a4793b488954bd3f0cc6af0dfb201b"
+ val-override-date: "20070916134226"
+; target-fetch-policy: "0 0 0 0 0"
+; fake-sha1: yes
+
+;stub-zone:
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+;test from testbound
+
+SCENARIO_BEGIN Test validator with no signatures after secure delegation
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854}
+ENTRY_END
+
+; barely valid nodata for AAAA
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.com. IN AAAA
+SECTION ANSWER
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
+ENTRY_END
+
+; response to DNSKEY priming query
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN DNSKEY
+SECTION ANSWER
+example.com. 3600 IN DNSKEY 256 3 3 ALXLUsWqUrY3JYER3T4TBJII s70j+sDS/UT2QRp61SE7S3E EXopNXoFE73JLRmvpi/UrOO/Vz4Se 6wXv/CYCKjGw06U4WRgR YXcpEhJROyNapmdIKSx hOzfLVE1gqA0PweZR8d tY3aNQSRn3sPpwJr6Mi /PqQKAMMrZ9ckJpf1+b QMOOvxgzz2U1GS18b3y ZKcgTMEaJzd/GZYzi/B N2DzQ0MsrSwYXfsNLFO Bbs8PJMW4LYIxeeOe6rUgkWOF 7CC9Dh/dduQ1QrsJhmZAEFfd6ByYV+ ;{id = 2854 (zsk), size = 1688b}
+example.com. 3600 IN RRSIG DNSKEY DSA 2 3600 20070926134150 20070829134150 2854 example.com. MCwCFBQRtlR4BEv9ohi+PGFjp+AHsJuHAhRCvz0shggvnvI88DFnBDCczHUcVA== ;{id = 2854}
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854}
+ENTRY_END
+
+; response for delegation to sub.example.com.
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+sub.example.com. IN A
+SECTION ANSWER
+SECTION AUTHORITY
+sub.example.com. IN NS ns.sub.example.com.
+sub.example.com. 3600 IN DS 30899 RSASHA1 1 f7ed618f24d5e5202927e1d27bc2e84a141cb4b3
+sub.example.com. 3600 IN RRSIG DS 3 3 3600 20070926134150 20070829134150 2854 example.com. MCwCFCW3ix0GD4BSvNLWIbROCJt5DAW9AhRt/kg9kBKJ20UBUdumrBUHqnskdA== ;{id = 2854}
+SECTION ADDITIONAL
+ns.sub.example.com. IN A 1.2.3.6
+ENTRY_END
+
+RANGE_END
+
+; ns.sub.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.6
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+sub.example.com. IN NS
+SECTION ANSWER
+sub.example.com. IN NS ns.sub.example.com.
+;sub.example.com. 3600 IN RRSIG NS 5 3 3600 20070926134150 20070829134150 30899 sub.example.com. wcpHeBILHfo8C9uxMhcW03gcURZeUffiKdSTb50ZjzTHgMNhRyMfpcvSpXEd9548A9UTmWKeLZChfr5Z/glONw== ;{id = 30899}
+SECTION ADDITIONAL
+ns.sub.example.com. IN A 1.2.3.6
+;ns.sub.example.com. 3600 IN RRSIG A 5 4 3600 20070926134150 20070829134150 30899 sub.example.com. UF7shD/gt1FOp2UHgLTNbPzVykklSXFMEtJ1xD+Hholwf/PIzd7zoaIttIYibNa4fUXCqMg22H9P7MRhfmFe6g== ;{id = 30899}
+ENTRY_END
+
+; barely valid nodata for AAAA
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.sub.example.com. IN AAAA
+SECTION AUTHORITY
+sub.example.com. IN NS ns.sub.example.com.
+;sub.example.com. 3600 IN RRSIG NS 5 3 3600 20070926134150 20070829134150 30899 sub.example.com. wcpHeBILHfo8C9uxMhcW03gcURZeUffiKdSTb50ZjzTHgMNhRyMfpcvSpXEd9548A9UTmWKeLZChfr5Z/glONw== ;{id = 30899}
+SECTION ADDITIONAL
+ns.sub.example.com. IN A 1.2.3.6
+;ns.sub.example.com. 3600 IN RRSIG A 5 4 3600 20070926134150 20070829134150 30899 sub.example.com. UF7shD/gt1FOp2UHgLTNbPzVykklSXFMEtJ1xD+Hholwf/PIzd7zoaIttIYibNa4fUXCqMg22H9P7MRhfmFe6g== ;{id = 30899}
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.sub.example.com. IN A
+SECTION ANSWER
+ns.sub.example.com. IN A 1.2.3.6
+;ns.sub.example.com. 3600 IN RRSIG A 5 4 3600 20070926134150 20070829134150 30899 sub.example.com. UF7shD/gt1FOp2UHgLTNbPzVykklSXFMEtJ1xD+Hholwf/PIzd7zoaIttIYibNa4fUXCqMg22H9P7MRhfmFe6g== ;{id = 30899}
+ENTRY_END
+
+; response to DNSKEY priming query
+; sub.example.com. 3600 IN DS 30899 RSASHA1 1 f7ed618f24d5e5202927e1d27bc2e84a141cb4b3
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+sub.example.com. IN DNSKEY
+SECTION ANSWER
+sub.example.com. 3600 IN DNSKEY 256 3 5 AQPQ41chR9DEHt/aIzIFAqanbDlRflJoRs5yz1jFsoRIT7dWf0r+PeDuewdxkszNH6wnU4QL8pfKFRh5PIYVBLK3 ;{id = 30899 (zsk), size = 512b}
+;sub.example.com. 3600 IN RRSIG DNSKEY 5 3 3600 20070926134150 20070829134150 30899 sub.example.com. uNGp99iznjD7oOX02XnQbDnbg75UwBHRvZSKYUorTKvPUnCWMHKdRsQ+mf+Fx3GZ+Fz9BVjoCmQqpnfgXLEYqw== ;{id = 30899}
+SECTION AUTHORITY
+sub.example.com. IN NS ns.sub.example.com.
+;sub.example.com. 3600 IN RRSIG NS 5 3 3600 20070926134150 20070829134150 30899 sub.example.com. wcpHeBILHfo8C9uxMhcW03gcURZeUffiKdSTb50ZjzTHgMNhRyMfpcvSpXEd9548A9UTmWKeLZChfr5Z/glONw== ;{id = 30899}
+SECTION ADDITIONAL
+ns.sub.example.com. IN A 1.2.3.6
+;ns.sub.example.com. 3600 IN RRSIG A 5 4 3600 20070926134150 20070829134150 30899 sub.example.com. UF7shD/gt1FOp2UHgLTNbPzVykklSXFMEtJ1xD+Hholwf/PIzd7zoaIttIYibNa4fUXCqMg22H9P7MRhfmFe6g== ;{id = 30899}
+ENTRY_END
+
+; response to query of interest
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.sub.example.com. IN A
+SECTION ANSWER
+www.sub.example.com. IN A 11.11.11.11
+;www.sub.example.com. 3600 IN RRSIG A 5 4 3600 20070926134150 20070829134150 30899 sub.example.com. 0DqqRfRtm7VSEQ4mmBbzrKRqQAay3JAE8DPDGmjtokrrjN9F1G/HxozDV7bjdIh2EChlQea8FPwf/GepJMUVxg== ;{id = 30899}
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.sub.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA DO SERVFAIL
+SECTION QUESTION
+www.sub.example.com. IN A
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/val_ta_sentinel.rpl b/tests/integration/deckard/sets/resolver/val_ta_sentinel.rpl
new file mode 100644
index 0000000..881ce6e
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_ta_sentinel.rpl
@@ -0,0 +1,587 @@
+stub-addr: 2001:503:ba3e::2:30
+stub-name: rootns.
+trust-anchor: . IN DS 48409 8 2 3D63A0C25BCE86621DE63636F11B35B908EFE8E9381E0E3E9DEFD89EA952C27D
+trust-anchor: example. IN DS 4759 8 2 3384CAE149834F17054DD9150E8C33D3979C4092F5C1B8D35E17A3C36A83810F
+val-override-date: 20180601000000
+query-minimization: off
+harden-glue: off
+CONFIG_END
+
+SCENARIO_BEGIN draft-ietf-dnsop-kskroll-sentinel-14 section 2
+
+
+RANGE_BEGIN 1 1000
+ ADDRESS 2001:503:ba3e::2:30
+ ADDRESS 198.41.0.4
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. IN SOA
+SECTION ANSWER
+. 86400 IN SOA rootns. you.test. 2017071101 1800 900 604800 86400
+. 86400 IN RRSIG SOA 8 0 86400 20180629135151 20180530135151 48409 . vb9XrP5h9Ojhqbs1Rbdiwxvje/TVFafSZlLf372zpYdtSBI6f7x++GYI WNiUG8EFtchEmL8KNsrWbujpa8tXeWXtatW92kG1qZAnOA40Zw1DjnI8 ZI7volYyq/TMmufKcoNAXU2knAmpZhHDZ+TBOc5HK6TwKeQaRQ6hPwxB JKOjXw2mVjQFP5lck2m2LU9a7iubYRvncRDHmqfjJ9XsSfWi1AU2fmk/ ei/bhKnFMWVH2PXtQlsbxRS8+8SaEL6f4rQC1JqwQ8E03SAZdK7oJKOf GRRFOfYOx7JucTwiV18LAa/j0owSMvuPwYjGnk6BY7e4LTMK2vPgJ3yY lqLmTw==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. IN DNSKEY
+SECTION ANSWER
+. 1814400 IN DNSKEY 257 3 8 AwEAAcliJP8Jh/RjL3c8eaUj8dzVdEksENKubqVA5FdrDJ2rC0O/bGG/ MVZt+WacE1o1mRVwTT/TrhhZUAzZ+qOcpB+IWxURsR4vVqVwakHMny7D 2aLXKoVXwTo/VhAQtHDw5G9bxGgwybPUtd5Vz6EIenUsmNYZ+Spde4l8 vpw7UISVL6q0C1mwHMN18P/1yfHmbkS19b6B1S9Y2aputccF1lso3yiF Ig7UNqqD4PNxSo4jByDnajQSP3qg/LSJSOnzBIumb8wc6svxgugy/pxr BFKgGGk4/JdJCKufdfU5jFX4fJ3HM37G/RccrtGhIf2Z1utoOyaILoa9 wT3O1WaYG/U=
+. 1814400 IN RRSIG DNSKEY 8 0 1814400 20180629135151 20180530135151 48409 . HRj68PBD0cR2p1njZcMUBecR5DiBbueyhIX1oqc9K9Rig5i+ONuozacm 3F4kg9DhUYb/1W6+PSp9YLyrJtCZOFLqkTjPiOAyiE6zVAE/U5O5LRZ/ FjqRQoWuA1cFZtrLokaWmW9GS5Kb2+PUCJY5NRz27JFSvaRRkoHIFf4o mA6eQsuWt28Itx0VGPL9+mR+2B+IcnmN+DZb7mxoRknOh0WyNop4eiep oSZcCihYHOdesCtmrxoMkwGEHZpu8a6GN7jaeNXXNUulwQYfzUZJZQo1 Zr9cN7kzIZ5tAs9ffnPRcWVO61MQTxUtuGbipFpba6RhGmML8oO4JkOJ Itp6tg==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. 518400 IN NS rootns.
+. 518400 IN RRSIG NS 8 0 518400 20180629135151 20180530135151 48409 . ZBLk+sK9ky+YBmzceXbBqEUyBc6nWfAtF6vCK/6cCfL1AxBYOoxdwE/G m0oRAl5WHRrreDSM2t79jcyyUZyyOcee2j/mLPjLdJPQr0Dw9KY+843L o4VSWV0L9adSzgXgvQF/p4yW2zNbHia7doA9GTDjkQFj2+7HgdJdGk8S I2GCx822fqzMCdS3XerIZ4EMz8Lt1sWaexdCgi0sCn9SvqzNHTaIXirW /apL0ohiBNp23LGa7+/7UvNrv+Y/gHpKk2bUytnS7soOocd9XpTekBY7 jlRlmnHTAdn9b9Zj2PHn72v1RYIywP33Qb9ze7i2v7s12uUR3lJt9sd/ WVeuXQ==
+SECTION ADDITIONAL
+rootns. 518400 IN A 198.41.0.4
+rootns. 518400 IN AAAA 2001:503:ba3e::2:30
+rootns. 518400 IN RRSIG A 8 1 518400 20180629135151 20180530135151 48409 . QtR9Z2uVwFVlLy5xQzMVmhqdzZw5cSFbq3xOzhr42gkoD9BYfNyTuhz9 57Sc7kvyJalBHaq3OKoYvE+4anjR8bXk20nGvVjzRdiiqavK41yUpbxC xvo5fWUMj5Bg860AcApn4OOLdFjyKOjJX7ro7QvFdA/adt9WEwhQ3AJ9 PN+SHqtx35F49OUbgiNUEbShJ2VyjOL5bt41LZgffkjim+VB2OtO1hDG CqrKyUlbZ0vxGJhtVflt1Jj3atArHfHz4cuFJHLtSu9PK9piYlSQ54XH vPk0YZ2iKK9sNrVF50Vb7NmLFBCVPn/op0Kmr+u6QVREP6uWayoPtqab /NKvwQ==
+rootns. 518400 IN RRSIG AAAA 8 1 518400 20180629135151 20180530135151 48409 . bs+zTG/nH7uQrgW5qfY5p25uXNoPOsH94K/xNVSLm9h1165/AMekPPd8 KVPnCfyZLPhO+/XyZ5fDUd/2iMCT5m/HyjXR0+j92r6f9ePfAJVQX6U0 DJUa882LgYK7k4usmIIWpi66bpGDC1tlJF3WQ4G12Hc/cUmFTMDBTcM8 6CPPDoT00JZQL8u/66GwNYkWw4mmbiq9UAz03R7A983dUx2GLCAmXoGR Lr3hI3btZa5x+GdJhw5t6Mqi58tXSZfUmT7kpCw+K0H/RscQaVDaOLc6 kzBeVn/Lip60ZSd84kiNWKuSA56TfUbpk7VJclY8UI34COHQqNtD+lev wJ1WgQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rootns. IN NS
+SECTION AUTHORITY
+. 86400 IN SOA rootns. you.test. 2017071101 1800 900 604800 86400
+. 86400 IN RRSIG SOA 8 0 86400 20180629135151 20180530135151 48409 . vb9XrP5h9Ojhqbs1Rbdiwxvje/TVFafSZlLf372zpYdtSBI6f7x++GYI WNiUG8EFtchEmL8KNsrWbujpa8tXeWXtatW92kG1qZAnOA40Zw1DjnI8 ZI7volYyq/TMmufKcoNAXU2knAmpZhHDZ+TBOc5HK6TwKeQaRQ6hPwxB JKOjXw2mVjQFP5lck2m2LU9a7iubYRvncRDHmqfjJ9XsSfWi1AU2fmk/ ei/bhKnFMWVH2PXtQlsbxRS8+8SaEL6f4rQC1JqwQ8E03SAZdK7oJKOf GRRFOfYOx7JucTwiV18LAa/j0owSMvuPwYjGnk6BY7e4LTMK2vPgJ3yY lqLmTw==
+rootns. 86400 IN NSEC root-key-sentinel-is-ta-00000.test. A AAAA RRSIG NSEC
+rootns. 86400 IN RRSIG NSEC 8 1 86400 20180629135151 20180530135151 48409 . noqU9JO9z5QXcedzsm7E6RZ5aIIocIH/jSedo6Zy+GImRTeHpc0le399 DUOsqGlcagx7EWRerScB+xmpL7DxKl0FFyeG0ORvPjJ6IyCFTecWjaKW YVurQnzALW+LhfsPSTxBMnnRhxT5Qrw4dtO0gx7fWyssKUnsMcBdmESs tALFNSfJpiV7so9cK2ssHsC+jkM0AQoemSKJrTesxm8FP1BGT27tz/vx yWIlOUGc8/gBgHo4hoXH1oyCrw9KU9kczRqw4CoCGJtZ2/k15BfmbPlC kLrvLibEmp6OYPVWfJRG79uDHhT+Tul07j26WmA+A7IWXSye8W51WbdH 7gJTKQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rootns. IN A
+SECTION ANSWER
+rootns. 518400 IN A 198.41.0.4
+rootns. 518400 IN RRSIG A 8 1 518400 20180629135151 20180530135151 48409 . QtR9Z2uVwFVlLy5xQzMVmhqdzZw5cSFbq3xOzhr42gkoD9BYfNyTuhz9 57Sc7kvyJalBHaq3OKoYvE+4anjR8bXk20nGvVjzRdiiqavK41yUpbxC xvo5fWUMj5Bg860AcApn4OOLdFjyKOjJX7ro7QvFdA/adt9WEwhQ3AJ9 PN+SHqtx35F49OUbgiNUEbShJ2VyjOL5bt41LZgffkjim+VB2OtO1hDG CqrKyUlbZ0vxGJhtVflt1Jj3atArHfHz4cuFJHLtSu9PK9piYlSQ54XH vPk0YZ2iKK9sNrVF50Vb7NmLFBCVPn/op0Kmr+u6QVREP6uWayoPtqab /NKvwQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rootns. IN AAAA
+SECTION ANSWER
+rootns. 518400 IN AAAA 2001:503:ba3e::2:30
+rootns. 518400 IN RRSIG AAAA 8 1 518400 20180629135151 20180530135151 48409 . bs+zTG/nH7uQrgW5qfY5p25uXNoPOsH94K/xNVSLm9h1165/AMekPPd8 KVPnCfyZLPhO+/XyZ5fDUd/2iMCT5m/HyjXR0+j92r6f9ePfAJVQX6U0 DJUa882LgYK7k4usmIIWpi66bpGDC1tlJF3WQ4G12Hc/cUmFTMDBTcM8 6CPPDoT00JZQL8u/66GwNYkWw4mmbiq9UAz03R7A983dUx2GLCAmXoGR Lr3hI3btZa5x+GdJhw5t6Mqi58tXSZfUmT7kpCw+K0H/RscQaVDaOLc6 kzBeVn/Lip60ZSd84kiNWKuSA56TfUbpk7VJclY8UI34COHQqNtD+lev wJ1WgQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+root-key-sentinel-is-ta-48409.test. IN A
+SECTION ANSWER
+root-key-sentinel-is-ta-48409.test. 1 IN A 192.0.2.1
+root-key-sentinel-is-ta-48409.test. 1 IN RRSIG A 8 2 1 20180629135151 20180530135151 48409 . qWJh+EE/O2w382vLo53ci9i1O/rAzJUUnZPmLF+GCwmLLhDl6tlI3y5A cALqIHkK1vrXzD+mED78YpILzZ73izRFieY6DxMtAXViqH9U8KSy6KWp tAWUASDe1gj9DGdDeiKdTAIo/2qk1PiGdZNc2E9vQLIUTJNfwV8aZGIt PTgl/efGEIMGGFQW5RPbDZpcJLQ11/RUi9FHQyseZRwkCa8EiEfgvPJ2 /rwiCPUcM6BdYzKoZ53cAHBbeKkvgAOpQ88qDvtE12aF9F8anxdHd0Ru 2DlmrPPthn7/faXSBbBECIbnjNlWTiyF7r274SQKFCrT0rJx5N9c31n4 ZSIocg==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+root-key-sentinel-is-ta-48409.test. IN AAAA
+SECTION ANSWER
+root-key-sentinel-is-ta-48409.test. 1 IN AAAA 2001:db8::
+root-key-sentinel-is-ta-48409.test. 1 IN RRSIG AAAA 8 2 1 20180629135151 20180530135151 48409 . J4gFrZRSHHDfMoA2zO22H6A55/893OnGO7h3H9znJGZtp7DxT2vxiGJw InBx5/zPubH87rqTa4AkK2GZuDEqVEDU/fjWOjGQOx16V0oeoHi5/R2R sPTzFnb+NvQnQZCRolMHD2keakdzB8b7dfEV80CrRh7uDsiO8aqhSdiV BFJLXFt5qFd+evKw2SG7l9FNMDzukUSAcFIJepM99X7qjQnKsLuzDjyF 4zhgMolAzAwIQzEi4B+G6IQknx5HsvmpNgkbBFjns+Q7ZYutNecPfiYU vaMpSXb5pztCVLbZQEymIXPgsnzdihlMbzh22TZapLbrDBUVEc2yr/QC Tz/CQA==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+root-key-sentinel-is-ta-48409.test. IN TXT
+SECTION ANSWER
+root-key-sentinel-is-ta-48409.test. 1 IN TXT "it works"
+root-key-sentinel-is-ta-48409.test. 1 IN RRSIG TXT 8 2 1 20180629135151 20180530135151 48409 . tl+oiYdq+UDlh6snkobPI/jQbrPM2tESEyDNIec7wCRvCEo6CLd+oMOA H4P7idKJ1Mey0eMl++YI29Vz2KVAIL0Hiamt32VDXyR5QYVVzNQquH5B /P4PDeoSadK1M+VThnSPT685+CLCbAZfu0Hi7+NulEeQLleBMtSGy0pF eG50H7fecNjqmQ2O/3jKRfD8l86+jba3B2FmpPvsxXgR7Ig5jC/XSpSY 0UMXyntDJz7QOSuhh4GcdNEeUqGVTurqnFjgRmZwReVZqeQzCS8Q+eQn cq23FtXxcAqJCFKN68yoorWmlZhZl0DPm4Zpup28wwlIapO+SGwScD0q KyHZYQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+root-key-sentinel-not-ta-48409.test. IN A
+SECTION ANSWER
+root-key-sentinel-not-ta-48409.test. 1 IN A 192.0.2.1
+root-key-sentinel-not-ta-48409.test. 1 IN RRSIG A 8 2 1 20180629135151 20180530135151 48409 . N1vrpd062YN/PGLOmdAdgPOc2iPPBadtv+DlqoCJ8OUEtFH605m7AUlX HDV99dpT7j6I/N+Sp6pDMRIRl+rB/tFXNfQFoB7UliAsKQ9UuKxH/uyc /sZWxPmYb+4Xi1AKmkzvp7M3Babq7hTGG/PnngN3386Qd0MXiw11Tdl9 +HIan1Jz2jMrHuR2NZDILZOW10wYogYD3/DAx6bVaJMjDbIky5ikK2H/ 4QajIhtjuux4GfsFc7KjGzT1/Hqa9LqdsLetvQmKF4yGNjizOgnrHlbF GoICQ1KihXF3IGYcBUyIoMcmhAjz6D0/jQz/Blwx3zvEUj2Hf7Xj+haO ShdguQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+root-key-sentinel-not-ta-48409.test. IN AAAA
+SECTION ANSWER
+root-key-sentinel-not-ta-48409.test. 1 IN AAAA 2001:db8::
+root-key-sentinel-not-ta-48409.test. 1 IN RRSIG AAAA 8 2 1 20180629135151 20180530135151 48409 . UYk1xmrw2A7ojKSTpwuF90WXsXOfNbRI8pi9tDPLmqr0OMn29AW051vG TyLd7L3ogsaoUEDiY2vYyvyZI3kPL9fSRDYgOIk7Cq3hp7k6wMM3IXS6 iIlYnjtvUFGDaE69EpUjwII22lSWaqOo0dCFnacJYWDfShdZcv7yssWG 9nZpki6aiBAjhYXY8tdMnpDJzq9O3zXPQR8xtuFW4S0aVdrHuSPRq935 DWXThocHxOza6OQp/ZkbemkoqAYjTlu0tyITwZsTknxgK1mtM+ArRmhS eykqVs3mmAGIWMN3qIW8SXKVRHI9PPjka0j6+KK+bfmeck0bI2Wu1f3C cnk+nQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+root-key-sentinel-not-ta-48409.test. IN TXT
+SECTION ANSWER
+root-key-sentinel-not-ta-48409.test. 1 IN TXT "it works"
+root-key-sentinel-not-ta-48409.test. 1 IN RRSIG TXT 8 2 1 20180629135151 20180530135151 48409 . NLK3/UMZZ+39KgwbFFoS6qR2QTEULMxDhlWpK1is+AU3CjUn1RNPRJaq m1MnfJdEq3+FFwVDkpmDGh8lQfTBn192oWlo2goHXZXwuoFN49FPHZ+l u42NWMDKtmS6r9JemJR68jH0jy/AsTMdvAbeodg06cbY6F5Q80EtAdkZ iOZPnqPenfxI+U8C2KgBNas7izGbQZF3FxHi7GZz+wrCGBcjcYX9pcD9 /rf1plZYudefFbxG+P97WfMScDD5vt0dUxz3Yt6YUC48jlyo9WYZDLC5 3qOuqah5oXS1lCGJDm+Kta4koVnm6W4pbCzT9XISwRWZ81rp0NbTrhHb Teu7Pw==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+root-key-sentinel-is-ta-00000.test. IN A
+SECTION ANSWER
+root-key-sentinel-is-ta-00000.test. 1 IN A 192.0.2.1
+root-key-sentinel-is-ta-00000.test. 1 IN RRSIG A 8 2 1 20180629135151 20180530135151 48409 . iYK8FfKFt+aD2Mh+hvFxyE0lCs/jHMT8EWlhPGuiPekHkYnbTaRbGJhT sCeL3Cg1MHrtGr8BXSq1RMyKnn6Y0/bhF1nEjk1gB+vAFHUwWe0yX32U H7E139q68ZyrcUkpV+KkY+ltMSKAjBtGRkYZ9sJhFvll7YCD2HtAMPud KEWpTZS2D0fLATDzAJzJF/2qGMvRUIn0sk5+3HqVh7R3stbl4aSEw5Zp swJoSCs1DN5eaLh6Ovas51uDAa4t6Ove6owR/gR9isqdZCbilAaJ6497 xg4r/KsCu6eG7GAAw5XGh8rkpC5YbsCBlXB565Zk5oY4yBgBUiG/iXGC wyLyJA==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+root-key-sentinel-is-ta-00000.test. IN AAAA
+SECTION ANSWER
+root-key-sentinel-is-ta-00000.test. 1 IN AAAA 2001:db8::
+root-key-sentinel-is-ta-00000.test. 1 IN RRSIG AAAA 8 2 1 20180629135151 20180530135151 48409 . QNF7LtVeew75AhniJ7S0ncsmrHWHCnRcU0H3uyCipyL20kHlpc1NOIUY md7BB02MXm+XOpJF/l/uc9v/C0iuAgOpFVp5kVjtp+gTu2mgceXstFuP 3tNmrL2pSRIWaN8+koS0MlAZCrH9+J9RSFrm5twtD7bIvGT0FVvy/RrR pRWPy9hbqjH6O5DFMdksdVTPLEYFXevAHGKvRa5beRXkrL9ANfVzvPYl q2RaO1aMX6+Cy7AquJpU7DUSReEUBr1f7mYVdd/6sjzoXrd893c+2Fc+ WFLVuWER3eTSrLAQ3b3Etz0lqM3MLrEXwjQFl2mw046nlh21T+u2Ds5s s1/b8g==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+root-key-sentinel-is-ta-00000.test. IN TXT
+SECTION ANSWER
+root-key-sentinel-is-ta-00000.test. 1 IN TXT "it works"
+root-key-sentinel-is-ta-00000.test. 1 IN RRSIG TXT 8 2 1 20180629135151 20180530135151 48409 . cGVwlSItiMGEOKkCWRLUn2od/cBvOlSwj8qxCppe4O1FRyTGgEFNV2nf 2zUkhL/agQhXI3qEjFOkq2b1l+4dM3BwDOF7IGhS3yXV3JGnIcwOC7si EMjRZGIvcEenjfugpIwkwkhTZdgIFoyCUr+g6YxA3iL6L77dftAmIkAV 6gvyarwgeYs0Wi+eEGfrZp2MxJjHDXKF+NfCy/fJnYx2n8SRpXya/Uu+ DJ+S4FQDTDyjDhN/+Tvcsb++sjvNfA4ZDwx5gpgNkRF0xsLHMoxCQagH gJBBziP0cq7l2fy5FVMpGNvdkkiYYG8to/2FF/65GhV+RuNcotD91zyW aeSxWw==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+root-key-sentinel-not-ta-00000.test. IN A
+SECTION ANSWER
+root-key-sentinel-not-ta-00000.test. 1 IN A 192.0.2.1
+root-key-sentinel-not-ta-00000.test. 1 IN RRSIG A 8 2 1 20180629135151 20180530135151 48409 . YYqLZKzjD13hpj345YTNMYYEh3US2BY7DqK9YbNIZi4T0/0jAEFPamKW WcX0nPm5N5S+1VqKIdo/brqvOTaxsq7HnPxVfomg3wyaKNvwqxb2MUpa pYl25ORa7yOm3gwVZJ3NBjh65dLXzGn8t8b047ym7Fnz6JAJHUyM4/SH hZhvXYBX+i3Lojq7HDIReqAtH7zzWdKzKLCTNqAhuqfvEI3edVynpth2 SCMNDVaAUlzVfBLEAkHNp26mLSgcarc3vrb2khdDS13Kv0Ev4rj0w0v1 z0DnVs95Yl2XlnShzNTaW5w1F8f81oBbq2Ly2POxERr5cOCNSGIWMi+q XAt7bQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+root-key-sentinel-not-ta-00000.test. IN AAAA
+SECTION ANSWER
+root-key-sentinel-not-ta-00000.test. 1 IN AAAA 2001:db8::
+root-key-sentinel-not-ta-00000.test. 1 IN RRSIG AAAA 8 2 1 20180629135151 20180530135151 48409 . mHz8sEjHOt+UrLPdGr3s+dake/eRQ6QmushFbLex2e6epkvmriVQwdWa QqG4h75UmjNnOlAwpHJA3oRyKxLJKmVgJIAQzhFc6sHLwEVl+kVyxGfu Q17Md+52E/d+mLMHohKRXljTaghp2uLHX8oDtBP+B2HhIDJK+uhfK63A MZ4k1L4jBGCvEGVMO7BhrpHV9zbY21MOb6EIp/F35jB+ftW7gilKxxBK t+Qt1pwtJcDGVC2xZST6fZ2yaR+U+YhOJ7t9j6WVVTWyFSa1CG3lzyRW PNduZeKYTYwox2uqqUxh+Nmzd1oZt7geIw8CGTYS0B++nVUdNJXJnP51 +evqJQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+root-key-sentinel-not-ta-00000.test. IN TXT
+SECTION ANSWER
+root-key-sentinel-not-ta-00000.test. 1 IN TXT "it works"
+root-key-sentinel-not-ta-00000.test. 1 IN RRSIG TXT 8 2 1 20180629135151 20180530135151 48409 . SjAFtdUPy+YU4sZnst5GNNYxjzWhBOVqUAfGIUv3uBo5qZW9ePecUJ8G ZkNUkdT7m+cHd0c1ssOBOT7snjwc3Sy3zD22b6/q3N8VowhDQDPkoDlB vt9raR7eXu273cEBDZTQ9P4Ya2Meu32Aftwa6VMQmXMl+qWXhYqffEt6 bJuoohnCVqOZihqgnoT+sRiDl49RgLb+GnZNbFk5EP9LXOrWcdxczKso tY384WCrniRmg4L6NM5DjnBtUVT+Qs6fhWGqQv23fPiLV8lt4i34aIf2 jAQkIE6KD4aNLlehct7eqFo1aeaiZumqEd9/GoqSat/RE7Qsh6hiRkfA /J7MLg==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+root-key-sentinel-is-ta-04759.test. IN A
+SECTION ANSWER
+root-key-sentinel-is-ta-04759.test. 1 IN A 192.0.2.33
+root-key-sentinel-is-ta-04759.test. 1 IN RRSIG A 8 2 1 20180629135151 20180530135151 48409 . B3RxvVwGi4W0SJPOexXga1Bm4nDiL4u/ITn30YXMPg8yOVOFWQ2axvG/ HdMFU6VSzm5GGIh0e+KR9Jzcvyt2yC3081SrclIkque3LJM1Ar5wa3GO 2M1EC3TuKs+L0WjLXfUTGie7n3mYfoiT+QBfZ4v60JQaD4U+UetZ5Ocn 2rXvuC0Rk9LI+j1Us7u2somZy/swl0Luvg4e+bueHRpTAgKf4nLHFZ8A HEAK0Vy3FG0N4q/oPWx1i9hVNxEaJQIwVcW01KDbP2sqFUNUm3bpT8aH fKRK4hy7MKkDsLrkpcbVbhI4vq8D1GKMtiUjU2kRjQ4VEMzXzXHhPcUi jMf7qw==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+root-key-sentinel-not-ta-04759.test. IN A
+SECTION ANSWER
+root-key-sentinel-not-ta-04759.test. 1 IN A 192.0.2.33
+root-key-sentinel-not-ta-04759.test. 1 IN RRSIG A 8 2 1 20180629135151 20180530135151 48409 . sUfM6dehUU9p1QnVX9QIT3K2kvKoU9qGTMNKdVz84AdJJMGnqMbosBpE LusmcZtwcGNjU8jcFdal/t03b+z0jk5BoEG0lzgFGNSp1S1sDGHYTcrv hAHmWpN4a0BEV/ZIOuu1ZJ8s0vRajnAB75jpSGsRdPmCTG/TKeAUJoF+ gua4lLlHnDlLnIVXThL3THqWqoTwg7Ch12piwrklZXNHbSsgcKwwG4SB 8OGY13ewXpH90EYkAFgmLIsavY7Ddhu8ZcFiE5nh6JQrwi7rsAtsr3cx x2rJrMTSEGP1F103YLzxyI4sTiIOGLaxQ7rGuASLGDQW5Cy0mKGgUAXI B0e7NA==
+ENTRY_END
+RANGE_END
+
+; sentinel does not affect qtypes different than A/AAAA
+; +AD
+STEP 111 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+root-key-sentinel-is-ta-48409.test. IN TXT
+ENTRY_END
+
+STEP 112 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD NOERROR
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+root-key-sentinel-is-ta-48409.test. IN TXT
+SECTION ANSWER
+root-key-sentinel-is-ta-48409.test. IN TXT "it works"
+ENTRY_END
+
+STEP 121 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+root-key-sentinel-not-ta-48409.test. IN TXT
+ENTRY_END
+
+STEP 122 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD NOERROR
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+root-key-sentinel-not-ta-48409.test. IN TXT
+SECTION ANSWER
+root-key-sentinel-not-ta-48409.test. IN TXT "it works"
+ENTRY_END
+
+; RD only
+STEP 131 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+root-key-sentinel-is-ta-00000.test. IN TXT
+ENTRY_END
+
+STEP 132 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA NOERROR
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+root-key-sentinel-is-ta-00000.test. IN TXT
+SECTION ANSWER
+root-key-sentinel-is-ta-00000.test. IN TXT "it works"
+ENTRY_END
+
+STEP 141 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+root-key-sentinel-not-ta-00000.test. IN TXT
+ENTRY_END
+
+STEP 142 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA NOERROR
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+root-key-sentinel-not-ta-00000.test. IN TXT
+SECTION ANSWER
+root-key-sentinel-not-ta-00000.test. IN TXT "it works"
+ENTRY_END
+
+; +CD
+STEP 143 QUERY
+ENTRY_BEGIN
+REPLY RD CD
+SECTION QUESTION
+root-key-sentinel-not-ta-00000.test. IN TXT
+ENTRY_END
+
+STEP 144 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA CD NOERROR
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+root-key-sentinel-not-ta-00000.test. IN TXT
+SECTION ANSWER
+root-key-sentinel-not-ta-00000.test. IN TXT "it works"
+ENTRY_END
+
+; +CD+DO
+STEP 145 QUERY
+ENTRY_BEGIN
+REPLY RD CD DO
+SECTION QUESTION
+root-key-sentinel-not-ta-00000.test. IN TXT
+ENTRY_END
+
+STEP 146 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA CD DO NOERROR
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+root-key-sentinel-not-ta-00000.test. IN TXT
+SECTION ANSWER
+root-key-sentinel-not-ta-00000.test. IN TXT "it works"
+root-key-sentinel-not-ta-00000.test. IN RRSIG TXT 8 2 1 20180629135151 20180530135151 48409 . SjAFtdUPy+YU4sZnst5GNNYxjzWhBOVq UAfGIUv3uBo5qZW9ePecUJ8GZkNUkdT7 m+cHd0c1ssOBOT7snjwc3Sy3zD22b6/q 3N8VowhDQDPkoDlBvt9raR7eXu273cEB DZTQ9P4Ya2Meu32Aftwa6VMQmXMl+qWX hYqffEt6bJuoohnCVqOZihqgnoT+sRiD l49RgLb+GnZNbFk5EP9LXOrWcdxczKso tY384WCrniRmg4L6NM5DjnBtUVT+Qs6f hWGqQv23fPiLV8lt4i34aIf2jAQkIE6K D4aNLlehct7eqFo1aeaiZumqEd9/GoqS at/RE7Qsh6hiRkfA/J7MLg==
+ENTRY_END
+
+
+; keyid 48409 is trusted
+; is-ta hit for keyid 48409 -> NOERROR
+; +AD
+STEP 211 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+root-key-sentinel-is-ta-48409.test. IN A
+ENTRY_END
+
+STEP 212 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD NOERROR
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+root-key-sentinel-is-ta-48409.test. IN A
+SECTION ANSWER
+root-key-sentinel-is-ta-48409.test. 1 IN A 192.0.2.1
+ENTRY_END
+
+; RD only
+STEP 221 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+root-key-sentinel-is-ta-48409.test. IN AAAA
+ENTRY_END
+
+STEP 222 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA NOERROR
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+root-key-sentinel-is-ta-48409.test. IN AAAA
+SECTION ANSWER
+root-key-sentinel-is-ta-48409.test. 1 IN AAAA 2001:db8::
+ENTRY_END
+
+
+; not-ta miss for keyid 48409 -> SERVFAIL
+; +AD
+STEP 311 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+root-key-sentinel-not-ta-48409.test. IN A
+ENTRY_END
+
+STEP 312 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA SERVFAIL
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+root-key-sentinel-not-ta-48409.test. IN A
+ENTRY_END
+
+; query without AD must SERVFAIL as well
+STEP 321 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+root-key-sentinel-not-ta-48409.test. IN AAAA
+ENTRY_END
+
+STEP 322 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA SERVFAIL
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+root-key-sentinel-not-ta-48409.test. IN AAAA
+ENTRY_END
+
+; +CD must disable sentinel logic
+STEP 323 QUERY
+ENTRY_BEGIN
+REPLY RD CD
+SECTION QUESTION
+root-key-sentinel-not-ta-48409.test. IN AAAA
+ENTRY_END
+
+STEP 324 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA CD NOERROR
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+root-key-sentinel-not-ta-48409.test. IN AAAA
+SECTION ANSWER
+root-key-sentinel-not-ta-48409.test. IN AAAA 2001:db8::
+ENTRY_END
+
+; +CD+DO must disable sentinel logic as well
+STEP 325 QUERY
+ENTRY_BEGIN
+REPLY RD CD DO
+SECTION QUESTION
+root-key-sentinel-not-ta-48409.test. IN AAAA
+ENTRY_END
+
+STEP 326 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA CD DO NOERROR
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+root-key-sentinel-not-ta-48409.test. IN AAAA
+SECTION ANSWER
+root-key-sentinel-not-ta-48409.test. IN AAAA 2001:db8::
+root-key-sentinel-not-ta-48409.test. IN RRSIG AAAA 8 2 1 20180629135151 20180530135151 48409 . UYk1xmrw2A7ojKSTpwuF90WXsXOfNbRI 8pi9tDPLmqr0OMn29AW051vGTyLd7L3o gsaoUEDiY2vYyvyZI3kPL9fSRDYgOIk7 Cq3hp7k6wMM3IXS6iIlYnjtvUFGDaE69 EpUjwII22lSWaqOo0dCFnacJYWDfShdZ cv7yssWG9nZpki6aiBAjhYXY8tdMnpDJ zq9O3zXPQR8xtuFW4S0aVdrHuSPRq935 DWXThocHxOza6OQp/ZkbemkoqAYjTlu0 tyITwZsTknxgK1mtM+ArRmhSeykqVs3m mAGIWMN3qIW8SXKVRHI9PPjka0j6+KK+ bfmeck0bI2Wu1f3Ccnk+nQ==
+ENTRY_END
+
+
+; keyid 0x0000 is not trusted
+; is-ta miss for keyid 0x0000 -> SERVFAIL
+; +AD
+STEP 411 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+root-key-sentinel-is-ta-00000.test. IN A
+ENTRY_END
+
+STEP 412 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA SERVFAIL
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+root-key-sentinel-is-ta-00000.test. IN A
+ENTRY_END
+
+STEP 422 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+root-key-sentinel-is-ta-00000.test. IN AAAA
+ENTRY_END
+
+STEP 423 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA SERVFAIL
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+root-key-sentinel-is-ta-00000.test. IN AAAA
+ENTRY_END
+
+; +CD must disable sentinel logic
+STEP 424 QUERY
+ENTRY_BEGIN
+REPLY RD CD
+SECTION QUESTION
+root-key-sentinel-is-ta-00000.test. IN AAAA
+ENTRY_END
+
+STEP 425 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA CD NOERROR
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+root-key-sentinel-is-ta-00000.test. IN AAAA
+SECTION ANSWER
+root-key-sentinel-is-ta-00000.test. IN AAAA 2001:db8::
+ENTRY_END
+
+
+; not-ta hit for keyid 0x0000 -> NOERROR
+STEP 511 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+root-key-sentinel-not-ta-00000.test. IN A
+ENTRY_END
+
+STEP 512 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD NOERROR
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+root-key-sentinel-not-ta-00000.test. IN A
+SECTION ANSWER
+root-key-sentinel-not-ta-00000.test. IN A 192.0.2.1
+ENTRY_END
+
+STEP 521 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+root-key-sentinel-not-ta-00000.test. IN AAAA
+ENTRY_END
+
+STEP 522 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD NOERROR
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+root-key-sentinel-not-ta-00000.test. IN AAAA
+SECTION ANSWER
+root-key-sentinel-not-ta-00000.test. IN AAAA 2001:db8::
+ENTRY_END
+
+
+; TA for non-root domains are interpreted correctly
+; not-ta ignores existing non-root TA keyid 04759 -> NOERROR
+STEP 611 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+root-key-sentinel-not-ta-04759.test. IN A
+ENTRY_END
+
+STEP 612 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA AD NOERROR
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+root-key-sentinel-not-ta-04759.test. IN A
+SECTION ANSWER
+root-key-sentinel-not-ta-04759.test. 1 IN A 192.0.2.33
+ENTRY_END
+
+; is-ta ignores existing non-root TA keyid 04759 -> SERVFAIL
+STEP 621 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+root-key-sentinel-is-ta-04759.test. IN A
+ENTRY_END
+
+STEP 622 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA SERVFAIL
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+root-key-sentinel-is-ta-04759.test. IN A
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/val_ta_sentinel/K.+008+48409.key b/tests/integration/deckard/sets/resolver/val_ta_sentinel/K.+008+48409.key
new file mode 100644
index 0000000..c3e520e
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_ta_sentinel/K.+008+48409.key
@@ -0,0 +1,5 @@
+; This is a key-signing key, keyid 48409, for .
+; Created: 20180118150418 (Thu Jan 18 16:04:18 2018)
+; Publish: 20170711000000 (Tue Jul 11 02:00:00 2017)
+; Activate: 20171011000000 (Wed Oct 11 02:00:00 2017)
+. 1814400 IN DNSKEY 257 3 8 AwEAAcliJP8Jh/RjL3c8eaUj8dzVdEksENKubqVA5FdrDJ2rC0O/bGG/ MVZt+WacE1o1mRVwTT/TrhhZUAzZ+qOcpB+IWxURsR4vVqVwakHMny7D 2aLXKoVXwTo/VhAQtHDw5G9bxGgwybPUtd5Vz6EIenUsmNYZ+Spde4l8 vpw7UISVL6q0C1mwHMN18P/1yfHmbkS19b6B1S9Y2aputccF1lso3yiF Ig7UNqqD4PNxSo4jByDnajQSP3qg/LSJSOnzBIumb8wc6svxgugy/pxr BFKgGGk4/JdJCKufdfU5jFX4fJ3HM37G/RccrtGhIf2Z1utoOyaILoa9 wT3O1WaYG/U=
diff --git a/tests/integration/deckard/sets/resolver/val_ta_sentinel/K.+008+48409.private b/tests/integration/deckard/sets/resolver/val_ta_sentinel/K.+008+48409.private
new file mode 100644
index 0000000..bb7de05
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_ta_sentinel/K.+008+48409.private
@@ -0,0 +1,13 @@
+Private-key-format: v1.3
+Algorithm: 8 (RSASHA256)
+Modulus: yWIk/wmH9GMvdzx5pSPx3NV0SSwQ0q5upUDkV2sMnasLQ79sYb8xVm35ZpwTWjWZFXBNP9OuGFlQDNn6o5ykH4hbFRGxHi9WpXBqQcyfLsPZotcqhVfBOj9WEBC0cPDkb1vEaDDJs9S13lXPoQh6dSyY1hn5Kl17iXy+nDtQhJUvqrQLWbAcw3Xw//XJ8eZuRLX1voHVL1jZqm61xwXWWyjfKIUiDtQ2qoPg83FKjiMHIOdqNBI/eqD8tIlI6fMEi6ZvzBzqy/GC6DL+nGsEUqAYaTj8l0kIq5919TmMVfh8ncczfsb9Fxyu0aEh/ZnW62g7Joguhr3BPc7VZpgb9Q==
+PublicExponent: AQAB
+PrivateExponent: xnCKqjF3Ia92/1S9Pahc1VIVA2GDtkciSn7WQvn+dYMtV3XSU8N114gIwT68pyC3l3OQ+3sYS2/+vJszKnPZGiVgMzO6x1a4V8+dNPdwSEG/PIIvqTOe+UmeAbikRcJqJv1TXaPtreHF0K/YKANVwA7RD/CKIV/6srEUlpiwL+OcHJFhXIubr5Gru6tNbZGQooblQ7w5x0+01WUti6C3SkO6VROvAE10qmwQ7sRb3scIerkZzOFhO8WimJvyfwPo78RCNBmmCm89uW/yvKw4mgnarg6EwZ7wXgqu7C1ZyY6ailFJB17GTJ+y8xiVUC0HB18WAdBXttceqWpxHW9GZQ==
+Prime1: /El9AUtn4x2DthqwK9GHAHAlCbpKtm8RVRYjRae6Dr3CWDPGqGj0LJSslW8g3SnyNDwXT9Et2kbvR2FsDz5lghgjnCnI0F16VpTYbstfNN6YOBP+50JyZyOvH11C1Phn5HChcmWIvoR+GJkflV7WN03s6IG0aAUg0h9ksubh00c=
+Prime2: zFjfXFwH5vWn2Yn8VA2YPP7qteE0wWXCpbobyQrmRTn95DOEHmrX57V0Pd957OKptYpTQSTMFjdFNVp6NSi6CfZp+8sYpwwK9aI4uCEgNnLLzgz4xmCLs27hnZeDw62vuG/TMBiGwv4+7QpEKLeJ5ZzAessEL/ShEAz84o/SHOM=
+Exponent1: aoouPAm4CXVBVfnXQ+nr9Qdm3MDLJFerHh+HLbczH16LX+wdjKkl1F3EtCaF3mAEZIKr5Y0UrAUgryg5FgbnnxTKlPwgTb3sF/wrmj5QKmeGKMho8Qhif6PWJIyh2IY+eX4G7+Ro5uvUxFaFu/KczCYgUd/Ua8kenx2azOIro6k=
+Exponent2: n8PwRj6x8vInnF5UyMakOzQ2/6Km43oTGA2NAb8i0AcKKOvaJQn16fQlgOaDZiDE/Om8M9d4NPpbgt5NY9iGs5lTvYhJqvkwbGG7pMJJdCiGjX/41OjQ8KYFgXffjhLyqunLHPRgEH5FZoC7T3ZIOxw2JQsrJ+9EKc9tvBkj9m8=
+Coefficient: gNp/tXrqbPKEBmvHV744gOuZxH0D2tMKMu8U/gF0IUjbTQqmaLuLgo9wXVHWo8GpEKbUOB9fbOcoptZlNE1TEF//44IcZH3yJM1JvU3nHW24gIi0xI3B4rQrZej2XpeuFxd44S3LTkeHmZjZB3dnCcgH0CqRTrONMRvW7RqB0bw=
+Created: 20180118150418
+Publish: 20170711000000
+Activate: 20171011000000
diff --git a/tests/integration/deckard/sets/resolver/val_ta_sentinel/root.db b/tests/integration/deckard/sets/resolver/val_ta_sentinel/root.db
new file mode 100644
index 0000000..a6c62f7
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_ta_sentinel/root.db
@@ -0,0 +1,61 @@
+; File written on Wed May 30 16:51:51 2018
+; dnssec_signzone version 9.12.0
+. 86400 IN SOA rootns. you.test. 2017071101 1800 900 604800 86400
+. 86400 IN RRSIG SOA 8 0 86400 20180629135151 20180530135151 48409 . vb9XrP5h9Ojhqbs1Rbdiwxvje/TVFafSZlLf372zpYdtSBI6f7x++GYI WNiUG8EFtchEmL8KNsrWbujpa8tXeWXtatW92kG1qZAnOA40Zw1DjnI8 ZI7volYyq/TMmufKcoNAXU2knAmpZhHDZ+TBOc5HK6TwKeQaRQ6hPwxB JKOjXw2mVjQFP5lck2m2LU9a7iubYRvncRDHmqfjJ9XsSfWi1AU2fmk/ ei/bhKnFMWVH2PXtQlsbxRS8+8SaEL6f4rQC1JqwQ8E03SAZdK7oJKOf GRRFOfYOx7JucTwiV18LAa/j0owSMvuPwYjGnk6BY7e4LTMK2vPgJ3yY lqLmTw==
+. 518400 IN NS rootns.
+. 518400 IN RRSIG NS 8 0 518400 20180629135151 20180530135151 48409 . ZBLk+sK9ky+YBmzceXbBqEUyBc6nWfAtF6vCK/6cCfL1AxBYOoxdwE/G m0oRAl5WHRrreDSM2t79jcyyUZyyOcee2j/mLPjLdJPQr0Dw9KY+843L o4VSWV0L9adSzgXgvQF/p4yW2zNbHia7doA9GTDjkQFj2+7HgdJdGk8S I2GCx822fqzMCdS3XerIZ4EMz8Lt1sWaexdCgi0sCn9SvqzNHTaIXirW /apL0ohiBNp23LGa7+/7UvNrv+Y/gHpKk2bUytnS7soOocd9XpTekBY7 jlRlmnHTAdn9b9Zj2PHn72v1RYIywP33Qb9ze7i2v7s12uUR3lJt9sd/ WVeuXQ==
+. 86400 IN NSEC rootns. NS SOA RRSIG NSEC DNSKEY
+. 86400 IN RRSIG NSEC 8 0 86400 20180629135151 20180530135151 48409 . J2mHopzSRvmwst3TVDwMS2wG9XDMcJhk9lYMEifgss/Zo+SR8qL8Z8TS zB89UtHAGH+58INk3DnT7tacOKZtbwNx6LFcGO/QXHHN6DwI1rghuGD9 94mQy57Rl5guKesB76HLBBrn0f+elE6lCLYNa0Unqe9XVWHYrcqAmi1K yi1nQgT1DCmmzAg0Yfq5NSkaq4AHO1b8wzkuvl4WoVS8sKpW5K+GtAK0 ox8OwaClFq6QqjXMawcftEnl3aJawS0ftz1ZBolR3889kFpC/xrvTN29 tkUjYNRNjvIYwvinznKjumL2YsMyYWmn/7FCq3NJEAHljxsRCDCW+vl0 oCG2SQ==
+. 1814400 IN DNSKEY 257 3 8 AwEAAcliJP8Jh/RjL3c8eaUj8dzVdEksENKubqVA5FdrDJ2rC0O/bGG/ MVZt+WacE1o1mRVwTT/TrhhZUAzZ+qOcpB+IWxURsR4vVqVwakHMny7D 2aLXKoVXwTo/VhAQtHDw5G9bxGgwybPUtd5Vz6EIenUsmNYZ+Spde4l8 vpw7UISVL6q0C1mwHMN18P/1yfHmbkS19b6B1S9Y2aputccF1lso3yiF Ig7UNqqD4PNxSo4jByDnajQSP3qg/LSJSOnzBIumb8wc6svxgugy/pxr BFKgGGk4/JdJCKufdfU5jFX4fJ3HM37G/RccrtGhIf2Z1utoOyaILoa9 wT3O1WaYG/U=
+. 1814400 IN RRSIG DNSKEY 8 0 1814400 20180629135151 20180530135151 48409 . HRj68PBD0cR2p1njZcMUBecR5DiBbueyhIX1oqc9K9Rig5i+ONuozacm 3F4kg9DhUYb/1W6+PSp9YLyrJtCZOFLqkTjPiOAyiE6zVAE/U5O5LRZ/ FjqRQoWuA1cFZtrLokaWmW9GS5Kb2+PUCJY5NRz27JFSvaRRkoHIFf4o mA6eQsuWt28Itx0VGPL9+mR+2B+IcnmN+DZb7mxoRknOh0WyNop4eiep oSZcCihYHOdesCtmrxoMkwGEHZpu8a6GN7jaeNXXNUulwQYfzUZJZQo1 Zr9cN7kzIZ5tAs9ffnPRcWVO61MQTxUtuGbipFpba6RhGmML8oO4JkOJ Itp6tg==
+root-key-sentinel-is-ta-04759.test. 1 IN A 192.0.2.33
+root-key-sentinel-is-ta-04759.test. 1 IN RRSIG A 8 2 1 20180629135151 20180530135151 48409 . B3RxvVwGi4W0SJPOexXga1Bm4nDiL4u/ITn30YXMPg8yOVOFWQ2axvG/ HdMFU6VSzm5GGIh0e+KR9Jzcvyt2yC3081SrclIkque3LJM1Ar5wa3GO 2M1EC3TuKs+L0WjLXfUTGie7n3mYfoiT+QBfZ4v60JQaD4U+UetZ5Ocn 2rXvuC0Rk9LI+j1Us7u2somZy/swl0Luvg4e+bueHRpTAgKf4nLHFZ8A HEAK0Vy3FG0N4q/oPWx1i9hVNxEaJQIwVcW01KDbP2sqFUNUm3bpT8aH fKRK4hy7MKkDsLrkpcbVbhI4vq8D1GKMtiUjU2kRjQ4VEMzXzXHhPcUi jMf7qw==
+root-key-sentinel-is-ta-04759.test. 86400 IN NSEC root-key-sentinel-is-ta-48409.test. A RRSIG NSEC
+root-key-sentinel-is-ta-04759.test. 86400 IN RRSIG NSEC 8 2 86400 20180629135151 20180530135151 48409 . lEBshzTtCWvgkCFB8vyIBnnOoHj2BNxUnGs/zSfDD+pdHuaXQ+cO8Gjb DDt+9ZvzHK+Ijt2sqnC6NuNtjACc6XSiPCGM6zoKOlqrnje5tZoA3OUf 0AYxjSRM1U/IzGv2QEsRv3CRQkddPIeXufzrj/d3PL0kHwD9A0kSSiiW Ch5OBhhLPshzfQTQ3nU1TXDPdzsncpvkDtQLgTS0LQDKh0mp92yNlrpT HqMIPyUXr8e8FbtWQ4Y8fJ+IGxbjt6Ek7oKmL6mowE6B6UWwsy3d4S8c i5fZQSfJhRu7Vq5Kyq8CZLLQw1fZ7/QHacjjUTVaVdnq6ze3J9gdJlnj IdoiIg==
+root-key-sentinel-not-ta-04759.test. 1 IN A 192.0.2.33
+root-key-sentinel-not-ta-04759.test. 1 IN RRSIG A 8 2 1 20180629135151 20180530135151 48409 . sUfM6dehUU9p1QnVX9QIT3K2kvKoU9qGTMNKdVz84AdJJMGnqMbosBpE LusmcZtwcGNjU8jcFdal/t03b+z0jk5BoEG0lzgFGNSp1S1sDGHYTcrv hAHmWpN4a0BEV/ZIOuu1ZJ8s0vRajnAB75jpSGsRdPmCTG/TKeAUJoF+ gua4lLlHnDlLnIVXThL3THqWqoTwg7Ch12piwrklZXNHbSsgcKwwG4SB 8OGY13ewXpH90EYkAFgmLIsavY7Ddhu8ZcFiE5nh6JQrwi7rsAtsr3cx x2rJrMTSEGP1F103YLzxyI4sTiIOGLaxQ7rGuASLGDQW5Cy0mKGgUAXI B0e7NA==
+root-key-sentinel-not-ta-04759.test. 86400 IN NSEC root-key-sentinel-not-ta-48409.test. A RRSIG NSEC
+root-key-sentinel-not-ta-04759.test. 86400 IN RRSIG NSEC 8 2 86400 20180629135151 20180530135151 48409 . eMKKf4Itgkz3mxMsl+gz4xUO1xMchTU4INlJkMG4WkgDpINFhu08RrkI AGDuZnsKZwedqCyXmm/pqiAr/IuurIF5XZSL7tocYmtEV1p/unpeKzt/ wzb34Ktm2Sv5Wu/ZgGatg4ddocjhUzVS0QX3DL9qIFCs8U+VJj7wSC6q 1qcSwksYtUmeG3io3UkBuNTqnqpqZRUieBA9XMftpCbdOES/8WdxPI53 59zFBp5TnwJ7y9Wu9ccZv8tI1QBtqz0UdLYMG09QdhoL6rzZUVRZyRpi FFrp4fdEL6perdYZd0awa2nVNCrr9jEwMSxnm5oVbFUY6Tu+M4pdG5d7 JjXUTg==
+rootns. 518400 IN A 198.41.0.4
+rootns. 518400 IN RRSIG A 8 1 518400 20180629135151 20180530135151 48409 . QtR9Z2uVwFVlLy5xQzMVmhqdzZw5cSFbq3xOzhr42gkoD9BYfNyTuhz9 57Sc7kvyJalBHaq3OKoYvE+4anjR8bXk20nGvVjzRdiiqavK41yUpbxC xvo5fWUMj5Bg860AcApn4OOLdFjyKOjJX7ro7QvFdA/adt9WEwhQ3AJ9 PN+SHqtx35F49OUbgiNUEbShJ2VyjOL5bt41LZgffkjim+VB2OtO1hDG CqrKyUlbZ0vxGJhtVflt1Jj3atArHfHz4cuFJHLtSu9PK9piYlSQ54XH vPk0YZ2iKK9sNrVF50Vb7NmLFBCVPn/op0Kmr+u6QVREP6uWayoPtqab /NKvwQ==
+rootns. 518400 IN AAAA 2001:503:ba3e::2:30
+rootns. 518400 IN RRSIG AAAA 8 1 518400 20180629135151 20180530135151 48409 . bs+zTG/nH7uQrgW5qfY5p25uXNoPOsH94K/xNVSLm9h1165/AMekPPd8 KVPnCfyZLPhO+/XyZ5fDUd/2iMCT5m/HyjXR0+j92r6f9ePfAJVQX6U0 DJUa882LgYK7k4usmIIWpi66bpGDC1tlJF3WQ4G12Hc/cUmFTMDBTcM8 6CPPDoT00JZQL8u/66GwNYkWw4mmbiq9UAz03R7A983dUx2GLCAmXoGR Lr3hI3btZa5x+GdJhw5t6Mqi58tXSZfUmT7kpCw+K0H/RscQaVDaOLc6 kzBeVn/Lip60ZSd84kiNWKuSA56TfUbpk7VJclY8UI34COHQqNtD+lev wJ1WgQ==
+rootns. 86400 IN NSEC root-key-sentinel-is-ta-00000.test. A AAAA RRSIG NSEC
+rootns. 86400 IN RRSIG NSEC 8 1 86400 20180629135151 20180530135151 48409 . noqU9JO9z5QXcedzsm7E6RZ5aIIocIH/jSedo6Zy+GImRTeHpc0le399 DUOsqGlcagx7EWRerScB+xmpL7DxKl0FFyeG0ORvPjJ6IyCFTecWjaKW YVurQnzALW+LhfsPSTxBMnnRhxT5Qrw4dtO0gx7fWyssKUnsMcBdmESs tALFNSfJpiV7so9cK2ssHsC+jkM0AQoemSKJrTesxm8FP1BGT27tz/vx yWIlOUGc8/gBgHo4hoXH1oyCrw9KU9kczRqw4CoCGJtZ2/k15BfmbPlC kLrvLibEmp6OYPVWfJRG79uDHhT+Tul07j26WmA+A7IWXSye8W51WbdH 7gJTKQ==
+root-key-sentinel-not-ta-00000.test. 1 IN A 192.0.2.1
+root-key-sentinel-not-ta-00000.test. 1 IN RRSIG A 8 2 1 20180629135151 20180530135151 48409 . YYqLZKzjD13hpj345YTNMYYEh3US2BY7DqK9YbNIZi4T0/0jAEFPamKW WcX0nPm5N5S+1VqKIdo/brqvOTaxsq7HnPxVfomg3wyaKNvwqxb2MUpa pYl25ORa7yOm3gwVZJ3NBjh65dLXzGn8t8b047ym7Fnz6JAJHUyM4/SH hZhvXYBX+i3Lojq7HDIReqAtH7zzWdKzKLCTNqAhuqfvEI3edVynpth2 SCMNDVaAUlzVfBLEAkHNp26mLSgcarc3vrb2khdDS13Kv0Ev4rj0w0v1 z0DnVs95Yl2XlnShzNTaW5w1F8f81oBbq2Ly2POxERr5cOCNSGIWMi+q XAt7bQ==
+root-key-sentinel-not-ta-00000.test. 1 IN TXT "it works"
+root-key-sentinel-not-ta-00000.test. 1 IN RRSIG TXT 8 2 1 20180629135151 20180530135151 48409 . SjAFtdUPy+YU4sZnst5GNNYxjzWhBOVqUAfGIUv3uBo5qZW9ePecUJ8G ZkNUkdT7m+cHd0c1ssOBOT7snjwc3Sy3zD22b6/q3N8VowhDQDPkoDlB vt9raR7eXu273cEBDZTQ9P4Ya2Meu32Aftwa6VMQmXMl+qWXhYqffEt6 bJuoohnCVqOZihqgnoT+sRiDl49RgLb+GnZNbFk5EP9LXOrWcdxczKso tY384WCrniRmg4L6NM5DjnBtUVT+Qs6fhWGqQv23fPiLV8lt4i34aIf2 jAQkIE6KD4aNLlehct7eqFo1aeaiZumqEd9/GoqSat/RE7Qsh6hiRkfA /J7MLg==
+root-key-sentinel-not-ta-00000.test. 1 IN AAAA 2001:db8::
+root-key-sentinel-not-ta-00000.test. 1 IN RRSIG AAAA 8 2 1 20180629135151 20180530135151 48409 . mHz8sEjHOt+UrLPdGr3s+dake/eRQ6QmushFbLex2e6epkvmriVQwdWa QqG4h75UmjNnOlAwpHJA3oRyKxLJKmVgJIAQzhFc6sHLwEVl+kVyxGfu Q17Md+52E/d+mLMHohKRXljTaghp2uLHX8oDtBP+B2HhIDJK+uhfK63A MZ4k1L4jBGCvEGVMO7BhrpHV9zbY21MOb6EIp/F35jB+ftW7gilKxxBK t+Qt1pwtJcDGVC2xZST6fZ2yaR+U+YhOJ7t9j6WVVTWyFSa1CG3lzyRW PNduZeKYTYwox2uqqUxh+Nmzd1oZt7geIw8CGTYS0B++nVUdNJXJnP51 +evqJQ==
+root-key-sentinel-not-ta-00000.test. 86400 IN NSEC root-key-sentinel-not-ta-04759.test. A TXT AAAA RRSIG NSEC
+root-key-sentinel-not-ta-00000.test. 86400 IN RRSIG NSEC 8 2 86400 20180629135151 20180530135151 48409 . Q7l+lP5MRbXUCszYfJ/x2VUT3C9D3ei8W8/3i/EPoc81J6e35Ny3tbQ9 HH8nzN0Y/4kDtrPjlq42bhwf1J0UZLh2z/Zf1s2/9CSQ/qSUAaD9RY4I eRqHA2As1zjKH9scPDYfKOvvia66xRY5lwT7eH95TbE9Kl+Weerh9Zlq kr4jgofO7DT6UCL+DMAyJZV2qfvdgtYLbs2A4nEWPOriqXdHhsGgnWzr FLZCm4BnY7epaVzzkuC9GnZ3cygZUSc0ArmoIR4dRoQYnq3eYvFrxQ/c No6Yj3coRJGH8nFNmENh1bSuoJCEpcS7jVNd0THMnyRjoly+HYn0nD5V K6Zj2w==
+root-key-sentinel-is-ta-48409.test. 1 IN A 192.0.2.1
+root-key-sentinel-is-ta-48409.test. 1 IN RRSIG A 8 2 1 20180629135151 20180530135151 48409 . qWJh+EE/O2w382vLo53ci9i1O/rAzJUUnZPmLF+GCwmLLhDl6tlI3y5A cALqIHkK1vrXzD+mED78YpILzZ73izRFieY6DxMtAXViqH9U8KSy6KWp tAWUASDe1gj9DGdDeiKdTAIo/2qk1PiGdZNc2E9vQLIUTJNfwV8aZGIt PTgl/efGEIMGGFQW5RPbDZpcJLQ11/RUi9FHQyseZRwkCa8EiEfgvPJ2 /rwiCPUcM6BdYzKoZ53cAHBbeKkvgAOpQ88qDvtE12aF9F8anxdHd0Ru 2DlmrPPthn7/faXSBbBECIbnjNlWTiyF7r274SQKFCrT0rJx5N9c31n4 ZSIocg==
+root-key-sentinel-is-ta-48409.test. 1 IN TXT "it works"
+root-key-sentinel-is-ta-48409.test. 1 IN RRSIG TXT 8 2 1 20180629135151 20180530135151 48409 . tl+oiYdq+UDlh6snkobPI/jQbrPM2tESEyDNIec7wCRvCEo6CLd+oMOA H4P7idKJ1Mey0eMl++YI29Vz2KVAIL0Hiamt32VDXyR5QYVVzNQquH5B /P4PDeoSadK1M+VThnSPT685+CLCbAZfu0Hi7+NulEeQLleBMtSGy0pF eG50H7fecNjqmQ2O/3jKRfD8l86+jba3B2FmpPvsxXgR7Ig5jC/XSpSY 0UMXyntDJz7QOSuhh4GcdNEeUqGVTurqnFjgRmZwReVZqeQzCS8Q+eQn cq23FtXxcAqJCFKN68yoorWmlZhZl0DPm4Zpup28wwlIapO+SGwScD0q KyHZYQ==
+root-key-sentinel-is-ta-48409.test. 1 IN AAAA 2001:db8::
+root-key-sentinel-is-ta-48409.test. 1 IN RRSIG AAAA 8 2 1 20180629135151 20180530135151 48409 . J4gFrZRSHHDfMoA2zO22H6A55/893OnGO7h3H9znJGZtp7DxT2vxiGJw InBx5/zPubH87rqTa4AkK2GZuDEqVEDU/fjWOjGQOx16V0oeoHi5/R2R sPTzFnb+NvQnQZCRolMHD2keakdzB8b7dfEV80CrRh7uDsiO8aqhSdiV BFJLXFt5qFd+evKw2SG7l9FNMDzukUSAcFIJepM99X7qjQnKsLuzDjyF 4zhgMolAzAwIQzEi4B+G6IQknx5HsvmpNgkbBFjns+Q7ZYutNecPfiYU vaMpSXb5pztCVLbZQEymIXPgsnzdihlMbzh22TZapLbrDBUVEc2yr/QC Tz/CQA==
+root-key-sentinel-is-ta-48409.test. 86400 IN NSEC root-key-sentinel-not-ta-00000.test. A TXT AAAA RRSIG NSEC
+root-key-sentinel-is-ta-48409.test. 86400 IN RRSIG NSEC 8 2 86400 20180629135151 20180530135151 48409 . EDUa6WBV7AoZTNu/kCroCc7ENrSU/v98WlcNy6ZAJk6e46LuBCWQwkKf EKGnJOlUh2Qoq2M24sVkRnWzaOn42IeKI3IlM8LeYVJL6nFpuImotkV4 VGQsiK//Uc1sLXBsj6x1N3xycKG+5bONyv8GSCS5MvzDwtsn0leUnyby 1G9ZKl7DX58GhBDfft++rp3EyALMasUbON4Jl2+7nzgpCfJUrdzogO0N krpqVZoNUybFomcDAQkDpgTeH5I8X0llSZkNWtpHbkwldCO4r+srq3EJ 2nf3GboKky3wMyWF0pg5XAqAYHoPq0Sz+fCog06+87ZsJBIJ0m58INHs ggiBvg==
+root-key-sentinel-is-ta-00000.test. 1 IN A 192.0.2.1
+root-key-sentinel-is-ta-00000.test. 1 IN RRSIG A 8 2 1 20180629135151 20180530135151 48409 . iYK8FfKFt+aD2Mh+hvFxyE0lCs/jHMT8EWlhPGuiPekHkYnbTaRbGJhT sCeL3Cg1MHrtGr8BXSq1RMyKnn6Y0/bhF1nEjk1gB+vAFHUwWe0yX32U H7E139q68ZyrcUkpV+KkY+ltMSKAjBtGRkYZ9sJhFvll7YCD2HtAMPud KEWpTZS2D0fLATDzAJzJF/2qGMvRUIn0sk5+3HqVh7R3stbl4aSEw5Zp swJoSCs1DN5eaLh6Ovas51uDAa4t6Ove6owR/gR9isqdZCbilAaJ6497 xg4r/KsCu6eG7GAAw5XGh8rkpC5YbsCBlXB565Zk5oY4yBgBUiG/iXGC wyLyJA==
+root-key-sentinel-is-ta-00000.test. 1 IN TXT "it works"
+root-key-sentinel-is-ta-00000.test. 1 IN RRSIG TXT 8 2 1 20180629135151 20180530135151 48409 . cGVwlSItiMGEOKkCWRLUn2od/cBvOlSwj8qxCppe4O1FRyTGgEFNV2nf 2zUkhL/agQhXI3qEjFOkq2b1l+4dM3BwDOF7IGhS3yXV3JGnIcwOC7si EMjRZGIvcEenjfugpIwkwkhTZdgIFoyCUr+g6YxA3iL6L77dftAmIkAV 6gvyarwgeYs0Wi+eEGfrZp2MxJjHDXKF+NfCy/fJnYx2n8SRpXya/Uu+ DJ+S4FQDTDyjDhN/+Tvcsb++sjvNfA4ZDwx5gpgNkRF0xsLHMoxCQagH gJBBziP0cq7l2fy5FVMpGNvdkkiYYG8to/2FF/65GhV+RuNcotD91zyW aeSxWw==
+root-key-sentinel-is-ta-00000.test. 1 IN AAAA 2001:db8::
+root-key-sentinel-is-ta-00000.test. 1 IN RRSIG AAAA 8 2 1 20180629135151 20180530135151 48409 . QNF7LtVeew75AhniJ7S0ncsmrHWHCnRcU0H3uyCipyL20kHlpc1NOIUY md7BB02MXm+XOpJF/l/uc9v/C0iuAgOpFVp5kVjtp+gTu2mgceXstFuP 3tNmrL2pSRIWaN8+koS0MlAZCrH9+J9RSFrm5twtD7bIvGT0FVvy/RrR pRWPy9hbqjH6O5DFMdksdVTPLEYFXevAHGKvRa5beRXkrL9ANfVzvPYl q2RaO1aMX6+Cy7AquJpU7DUSReEUBr1f7mYVdd/6sjzoXrd893c+2Fc+ WFLVuWER3eTSrLAQ3b3Etz0lqM3MLrEXwjQFl2mw046nlh21T+u2Ds5s s1/b8g==
+root-key-sentinel-is-ta-00000.test. 86400 IN NSEC root-key-sentinel-is-ta-04759.test. A TXT AAAA RRSIG NSEC
+root-key-sentinel-is-ta-00000.test. 86400 IN RRSIG NSEC 8 2 86400 20180629135151 20180530135151 48409 . GS5Rur2pdMmvGTJZ6WnDO6RzF1MRF34M5VBvUaBIYn2XqVt7toHL4P8i 7ZXqgiWPLsR/dma4MMphXGZac624kOoCHq2hc0q7ja/8FVbBwaGGIlFN v1XHkv490pjAc+NUtcxnhm+jnT8Wb7/wv5wG1Zd3hblP4opCpANOvoC0 MqyOe8vEW1lcw5KEcE0yKAksarVgAZmmXwkQ4caC9yIG/WC9gJ3fQ70Q Dio74WRERLDS3ShLfRkc0vXr5aUGBuy0mqV4OG3ioRj2jvafxgH6Ov9h g4GYL/aJycGIJZGeXGMR0OGalz+pe8WfzNtSWEuE4l22fPnM6Ne0RfaU 5K4CkQ==
+unsigned. 86400 IN NS rootns.
+unsigned. 86400 IN NSEC . NS RRSIG NSEC
+unsigned. 86400 IN RRSIG NSEC 8 1 86400 20180629135151 20180530135151 48409 . Di6tfHcpredaWGazWKUX26zYKQ+Yw34BCO2vtqufvcAZJN6PhyXct+Px cvfPN5WxTWlcXVbj6xJKYTOe/ItgV4TM1G2SzGrzTB4qs8ybSvECT59h FUUXTM5ZeXqQVIKKuhVJlmWYSneOiuQG0w6wWr/xE+sD+LE5xQ+hnWrp Z3YAbCmFdtCTwDVt8DkN3i30zExEWc/CnQj9gFYWIBPQ22OB1sfjbZSe 85ucMhUjTas7pZki7b716ZhokApLSf5mVjktjHVT+lPpivs/L2KaQKAe 2yKi05bInFJ+FHU29YoZ3zkBTd2+MeKOh9/1O+9O+hCA+yzLiSLG06Xa 1F7Pcg==
+; resign=20180629135151
+root-key-sentinel-not-ta-48409.test. 1 IN A 192.0.2.1
+root-key-sentinel-not-ta-48409.test. 1 IN RRSIG A 8 2 1 20180629135151 20180530135151 48409 . N1vrpd062YN/PGLOmdAdgPOc2iPPBadtv+DlqoCJ8OUEtFH605m7AUlX HDV99dpT7j6I/N+Sp6pDMRIRl+rB/tFXNfQFoB7UliAsKQ9UuKxH/uyc /sZWxPmYb+4Xi1AKmkzvp7M3Babq7hTGG/PnngN3386Qd0MXiw11Tdl9 +HIan1Jz2jMrHuR2NZDILZOW10wYogYD3/DAx6bVaJMjDbIky5ikK2H/ 4QajIhtjuux4GfsFc7KjGzT1/Hqa9LqdsLetvQmKF4yGNjizOgnrHlbF GoICQ1KihXF3IGYcBUyIoMcmhAjz6D0/jQz/Blwx3zvEUj2Hf7Xj+haO ShdguQ==
+root-key-sentinel-not-ta-48409.test. 1 IN TXT "it works"
+root-key-sentinel-not-ta-48409.test. 1 IN RRSIG TXT 8 2 1 20180629135151 20180530135151 48409 . NLK3/UMZZ+39KgwbFFoS6qR2QTEULMxDhlWpK1is+AU3CjUn1RNPRJaq m1MnfJdEq3+FFwVDkpmDGh8lQfTBn192oWlo2goHXZXwuoFN49FPHZ+l u42NWMDKtmS6r9JemJR68jH0jy/AsTMdvAbeodg06cbY6F5Q80EtAdkZ iOZPnqPenfxI+U8C2KgBNas7izGbQZF3FxHi7GZz+wrCGBcjcYX9pcD9 /rf1plZYudefFbxG+P97WfMScDD5vt0dUxz3Yt6YUC48jlyo9WYZDLC5 3qOuqah5oXS1lCGJDm+Kta4koVnm6W4pbCzT9XISwRWZ81rp0NbTrhHb Teu7Pw==
+root-key-sentinel-not-ta-48409.test. 1 IN AAAA 2001:db8::
+root-key-sentinel-not-ta-48409.test. 1 IN RRSIG AAAA 8 2 1 20180629135151 20180530135151 48409 . UYk1xmrw2A7ojKSTpwuF90WXsXOfNbRI8pi9tDPLmqr0OMn29AW051vG TyLd7L3ogsaoUEDiY2vYyvyZI3kPL9fSRDYgOIk7Cq3hp7k6wMM3IXS6 iIlYnjtvUFGDaE69EpUjwII22lSWaqOo0dCFnacJYWDfShdZcv7yssWG 9nZpki6aiBAjhYXY8tdMnpDJzq9O3zXPQR8xtuFW4S0aVdrHuSPRq935 DWXThocHxOza6OQp/ZkbemkoqAYjTlu0tyITwZsTknxgK1mtM+ArRmhS eykqVs3mmAGIWMN3qIW8SXKVRHI9PPjka0j6+KK+bfmeck0bI2Wu1f3C cnk+nQ==
+root-key-sentinel-not-ta-48409.test. 86400 IN NSEC unsigned. A TXT AAAA RRSIG NSEC
+root-key-sentinel-not-ta-48409.test. 86400 IN RRSIG NSEC 8 2 86400 20180629135151 20180530135151 48409 . DKB8iFwqz4u0QaAe/0ppPv3AzvvNVQGAfCnxfbdKkYGCjFZMtuNMef1u YsJLyY5MSS5AiNr+gAJpRrBnYnobGe4ibL2hG/HV41282p7PMu2BiCiE EZw2sTLeMjEyq+yVk5fciL/1/SwNr+fYKj9sTuzUC7L8LIndRoufuEvJ zi7PhWN6NUlWLr4X5o63a2TZqxCtS61/VUkVScfRfNKHs70SF89rXMYQ uaaUSSERcUwGBf1x1qpA7HL/8v4IwbWcLBXv44mTUIaJYvqqwCPbWJHm 5rX0J1UUYObJjj4RrPL1fxW5rZ5XNdtkKfteJLiDvNzBozX11HyTBq6E WtpJSQ==
+; resign=20180629135151
diff --git a/tests/integration/deckard/sets/resolver/val_ta_sentinel_insecure.rpl b/tests/integration/deckard/sets/resolver/val_ta_sentinel_insecure.rpl
new file mode 100644
index 0000000..9d903aa
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_ta_sentinel_insecure.rpl
@@ -0,0 +1,377 @@
+stub-addr: 2001:503:ba3e::2:30
+stub-name: rootns.
+trust-anchor: . IN DS 48409 8 2 3D63A0C25BCE86621DE63636F11B35B908EFE8E9381E0E3E9DEFD89EA952C27D
+val-override-date: 20180601000000
+; avoid the mess with one server for both "." and "unsigned."
+query-minimization: on
+CONFIG_END
+
+SCENARIO_BEGIN draft-ietf-dnsop-kskroll-sentinel-12 section 2 where root key matches but test domain is insecure
+
+
+RANGE_BEGIN 1 1000
+ ADDRESS 2001:503:ba3e::2:30
+ ADDRESS 198.41.0.4
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. IN SOA
+SECTION ANSWER
+. 86400 IN SOA rootns. you.test. 2017071101 1800 900 604800 86400
+. 86400 IN RRSIG SOA 8 0 86400 20180629135151 20180530135151 48409 . vb9XrP5h9Ojhqbs1Rbdiwxvje/TVFafSZlLf372zpYdtSBI6f7x++GYI WNiUG8EFtchEmL8KNsrWbujpa8tXeWXtatW92kG1qZAnOA40Zw1DjnI8 ZI7volYyq/TMmufKcoNAXU2knAmpZhHDZ+TBOc5HK6TwKeQaRQ6hPwxB JKOjXw2mVjQFP5lck2m2LU9a7iubYRvncRDHmqfjJ9XsSfWi1AU2fmk/ ei/bhKnFMWVH2PXtQlsbxRS8+8SaEL6f4rQC1JqwQ8E03SAZdK7oJKOf GRRFOfYOx7JucTwiV18LAa/j0owSMvuPwYjGnk6BY7e4LTMK2vPgJ3yY lqLmTw==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. IN DNSKEY
+SECTION ANSWER
+. 1814400 IN DNSKEY 257 3 8 AwEAAcliJP8Jh/RjL3c8eaUj8dzVdEksENKubqVA5FdrDJ2rC0O/bGG/ MVZt+WacE1o1mRVwTT/TrhhZUAzZ+qOcpB+IWxURsR4vVqVwakHMny7D 2aLXKoVXwTo/VhAQtHDw5G9bxGgwybPUtd5Vz6EIenUsmNYZ+Spde4l8 vpw7UISVL6q0C1mwHMN18P/1yfHmbkS19b6B1S9Y2aputccF1lso3yiF Ig7UNqqD4PNxSo4jByDnajQSP3qg/LSJSOnzBIumb8wc6svxgugy/pxr BFKgGGk4/JdJCKufdfU5jFX4fJ3HM37G/RccrtGhIf2Z1utoOyaILoa9 wT3O1WaYG/U=
+. 1814400 IN RRSIG DNSKEY 8 0 1814400 20180629135151 20180530135151 48409 . HRj68PBD0cR2p1njZcMUBecR5DiBbueyhIX1oqc9K9Rig5i+ONuozacm 3F4kg9DhUYb/1W6+PSp9YLyrJtCZOFLqkTjPiOAyiE6zVAE/U5O5LRZ/ FjqRQoWuA1cFZtrLokaWmW9GS5Kb2+PUCJY5NRz27JFSvaRRkoHIFf4o mA6eQsuWt28Itx0VGPL9+mR+2B+IcnmN+DZb7mxoRknOh0WyNop4eiep oSZcCihYHOdesCtmrxoMkwGEHZpu8a6GN7jaeNXXNUulwQYfzUZJZQo1 Zr9cN7kzIZ5tAs9ffnPRcWVO61MQTxUtuGbipFpba6RhGmML8oO4JkOJ Itp6tg==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. 518400 IN NS rootns.
+. 518400 IN RRSIG NS 8 0 518400 20180629135151 20180530135151 48409 . ZBLk+sK9ky+YBmzceXbBqEUyBc6nWfAtF6vCK/6cCfL1AxBYOoxdwE/G m0oRAl5WHRrreDSM2t79jcyyUZyyOcee2j/mLPjLdJPQr0Dw9KY+843L o4VSWV0L9adSzgXgvQF/p4yW2zNbHia7doA9GTDjkQFj2+7HgdJdGk8S I2GCx822fqzMCdS3XerIZ4EMz8Lt1sWaexdCgi0sCn9SvqzNHTaIXirW /apL0ohiBNp23LGa7+/7UvNrv+Y/gHpKk2bUytnS7soOocd9XpTekBY7 jlRlmnHTAdn9b9Zj2PHn72v1RYIywP33Qb9ze7i2v7s12uUR3lJt9sd/ WVeuXQ==
+SECTION ADDITIONAL
+rootns. 518400 IN A 198.41.0.4
+rootns. 518400 IN AAAA 2001:503:ba3e::2:30
+rootns. 518400 IN RRSIG A 8 1 518400 20180629135151 20180530135151 48409 . QtR9Z2uVwFVlLy5xQzMVmhqdzZw5cSFbq3xOzhr42gkoD9BYfNyTuhz9 57Sc7kvyJalBHaq3OKoYvE+4anjR8bXk20nGvVjzRdiiqavK41yUpbxC xvo5fWUMj5Bg860AcApn4OOLdFjyKOjJX7ro7QvFdA/adt9WEwhQ3AJ9 PN+SHqtx35F49OUbgiNUEbShJ2VyjOL5bt41LZgffkjim+VB2OtO1hDG CqrKyUlbZ0vxGJhtVflt1Jj3atArHfHz4cuFJHLtSu9PK9piYlSQ54XH vPk0YZ2iKK9sNrVF50Vb7NmLFBCVPn/op0Kmr+u6QVREP6uWayoPtqab /NKvwQ==
+rootns. 518400 IN RRSIG AAAA 8 1 518400 20180629135151 20180530135151 48409 . bs+zTG/nH7uQrgW5qfY5p25uXNoPOsH94K/xNVSLm9h1165/AMekPPd8 KVPnCfyZLPhO+/XyZ5fDUd/2iMCT5m/HyjXR0+j92r6f9ePfAJVQX6U0 DJUa882LgYK7k4usmIIWpi66bpGDC1tlJF3WQ4G12Hc/cUmFTMDBTcM8 6CPPDoT00JZQL8u/66GwNYkWw4mmbiq9UAz03R7A983dUx2GLCAmXoGR Lr3hI3btZa5x+GdJhw5t6Mqi58tXSZfUmT7kpCw+K0H/RscQaVDaOLc6 kzBeVn/Lip60ZSd84kiNWKuSA56TfUbpk7VJclY8UI34COHQqNtD+lev wJ1WgQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rootns. IN NS
+SECTION AUTHORITY
+. 86400 IN SOA rootns. you.test. 2017071101 1800 900 604800 86400
+. 86400 IN RRSIG SOA 8 0 86400 20180629135151 20180530135151 48409 . vb9XrP5h9Ojhqbs1Rbdiwxvje/TVFafSZlLf372zpYdtSBI6f7x++GYI WNiUG8EFtchEmL8KNsrWbujpa8tXeWXtatW92kG1qZAnOA40Zw1DjnI8 ZI7volYyq/TMmufKcoNAXU2knAmpZhHDZ+TBOc5HK6TwKeQaRQ6hPwxB JKOjXw2mVjQFP5lck2m2LU9a7iubYRvncRDHmqfjJ9XsSfWi1AU2fmk/ ei/bhKnFMWVH2PXtQlsbxRS8+8SaEL6f4rQC1JqwQ8E03SAZdK7oJKOf GRRFOfYOx7JucTwiV18LAa/j0owSMvuPwYjGnk6BY7e4LTMK2vPgJ3yY lqLmTw==
+rootns. 86400 IN NSEC root-key-sentinel-is-ta-00000.test. A AAAA RRSIG NSEC
+rootns. 86400 IN RRSIG NSEC 8 1 86400 20180629135151 20180530135151 48409 . noqU9JO9z5QXcedzsm7E6RZ5aIIocIH/jSedo6Zy+GImRTeHpc0le399 DUOsqGlcagx7EWRerScB+xmpL7DxKl0FFyeG0ORvPjJ6IyCFTecWjaKW YVurQnzALW+LhfsPSTxBMnnRhxT5Qrw4dtO0gx7fWyssKUnsMcBdmESs tALFNSfJpiV7so9cK2ssHsC+jkM0AQoemSKJrTesxm8FP1BGT27tz/vx yWIlOUGc8/gBgHo4hoXH1oyCrw9KU9kczRqw4CoCGJtZ2/k15BfmbPlC kLrvLibEmp6OYPVWfJRG79uDHhT+Tul07j26WmA+A7IWXSye8W51WbdH 7gJTKQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rootns. IN A
+SECTION ANSWER
+rootns. 518400 IN A 198.41.0.4
+rootns. 518400 IN RRSIG A 8 1 518400 20180629135151 20180530135151 48409 . QtR9Z2uVwFVlLy5xQzMVmhqdzZw5cSFbq3xOzhr42gkoD9BYfNyTuhz9 57Sc7kvyJalBHaq3OKoYvE+4anjR8bXk20nGvVjzRdiiqavK41yUpbxC xvo5fWUMj5Bg860AcApn4OOLdFjyKOjJX7ro7QvFdA/adt9WEwhQ3AJ9 PN+SHqtx35F49OUbgiNUEbShJ2VyjOL5bt41LZgffkjim+VB2OtO1hDG CqrKyUlbZ0vxGJhtVflt1Jj3atArHfHz4cuFJHLtSu9PK9piYlSQ54XH vPk0YZ2iKK9sNrVF50Vb7NmLFBCVPn/op0Kmr+u6QVREP6uWayoPtqab /NKvwQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rootns. IN AAAA
+SECTION ANSWER
+rootns. 518400 IN AAAA 2001:503:ba3e::2:30
+rootns. 518400 IN RRSIG AAAA 8 1 518400 20180629135151 20180530135151 48409 . bs+zTG/nH7uQrgW5qfY5p25uXNoPOsH94K/xNVSLm9h1165/AMekPPd8 KVPnCfyZLPhO+/XyZ5fDUd/2iMCT5m/HyjXR0+j92r6f9ePfAJVQX6U0 DJUa882LgYK7k4usmIIWpi66bpGDC1tlJF3WQ4G12Hc/cUmFTMDBTcM8 6CPPDoT00JZQL8u/66GwNYkWw4mmbiq9UAz03R7A983dUx2GLCAmXoGR Lr3hI3btZa5x+GdJhw5t6Mqi58tXSZfUmT7kpCw+K0H/RscQaVDaOLc6 kzBeVn/Lip60ZSd84kiNWKuSA56TfUbpk7VJclY8UI34COHQqNtD+lev wJ1WgQ==
+ENTRY_END
+
+; The delegation here is slightly hacky
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+unsigned. IN NS
+SECTION ANSWER
+unsigned. 86400 IN NS rootns.
+SECTION AUTHORITY
+unsigned. 86400 IN NSEC . NS RRSIG NSEC
+unsigned. 86400 IN RRSIG NSEC 8 1 86400 20180629135151 20180530135151 48409 . Di6tfHcpredaWGazWKUX26zYKQ+Yw34BCO2vtqufvcAZJN6PhyXct+Px cvfPN5WxTWlcXVbj6xJKYTOe/ItgV4TM1G2SzGrzTB4qs8ybSvECT59h FUUXTM5ZeXqQVIKKuhVJlmWYSneOiuQG0w6wWr/xE+sD+LE5xQ+hnWrp Z3YAbCmFdtCTwDVt8DkN3i30zExEWc/CnQj9gFYWIBPQ22OB1sfjbZSe 85ucMhUjTas7pZki7b716ZhokApLSf5mVjktjHVT+lPpivs/L2KaQKAe 2yKi05bInFJ+FHU29YoZ3zkBTd2+MeKOh9/1O+9O+hCA+yzLiSLG06Xa 1F7Pcg==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+unsigned. IN DS
+SECTION ANSWER
+SECTION AUTHORITY
+unsigned. 86400 IN NSEC . NS RRSIG NSEC
+unsigned. 86400 IN RRSIG NSEC 8 1 86400 20180629135151 20180530135151 48409 . Di6tfHcpredaWGazWKUX26zYKQ+Yw34BCO2vtqufvcAZJN6PhyXct+Px cvfPN5WxTWlcXVbj6xJKYTOe/ItgV4TM1G2SzGrzTB4qs8ybSvECT59h FUUXTM5ZeXqQVIKKuhVJlmWYSneOiuQG0w6wWr/xE+sD+LE5xQ+hnWrp Z3YAbCmFdtCTwDVt8DkN3i30zExEWc/CnQj9gFYWIBPQ22OB1sfjbZSe 85ucMhUjTas7pZki7b716ZhokApLSf5mVjktjHVT+lPpivs/L2KaQKAe 2yKi05bInFJ+FHU29YoZ3zkBTd2+MeKOh9/1O+9O+hCA+yzLiSLG06Xa 1F7Pcg==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+root-key-sentinel-is-ta-48409.unsigned. IN A
+SECTION ANSWER
+root-key-sentinel-is-ta-48409.unsigned. 1 IN A 192.0.2.1
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+root-key-sentinel-is-ta-48409.unsigned. IN AAAA
+SECTION ANSWER
+root-key-sentinel-is-ta-48409.unsigned. 1 IN AAAA 2001:db8::
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+root-key-sentinel-is-ta-48409.unsigned. IN TXT
+SECTION ANSWER
+root-key-sentinel-is-ta-48409.unsigned. 1 IN TXT "it works"
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+root-key-sentinel-not-ta-48409.unsigned. IN A
+SECTION ANSWER
+root-key-sentinel-not-ta-48409.unsigned. 1 IN A 192.0.2.1
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+root-key-sentinel-not-ta-48409.unsigned. IN AAAA
+SECTION ANSWER
+root-key-sentinel-not-ta-48409.unsigned. 1 IN AAAA 2001:db8::
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+root-key-sentinel-not-ta-48409.unsigned. IN TXT
+SECTION ANSWER
+root-key-sentinel-not-ta-48409.unsigned. 1 IN TXT "it works"
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+root-key-sentinel-is-ta-00000.unsigned. IN A
+SECTION ANSWER
+root-key-sentinel-is-ta-00000.unsigned. 1 IN A 192.0.2.1
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+root-key-sentinel-is-ta-00000.unsigned. IN AAAA
+SECTION ANSWER
+root-key-sentinel-is-ta-00000.unsigned. 1 IN AAAA 2001:db8::
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+root-key-sentinel-is-ta-00000.unsigned. IN TXT
+SECTION ANSWER
+root-key-sentinel-is-ta-00000.unsigned. 1 IN TXT "it works"
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+root-key-sentinel-not-ta-00000.unsigned. IN A
+SECTION ANSWER
+root-key-sentinel-not-ta-00000.unsigned. 1 IN A 192.0.2.1
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+root-key-sentinel-not-ta-00000.unsigned. IN AAAA
+SECTION ANSWER
+root-key-sentinel-not-ta-00000.unsigned. 1 IN AAAA 2001:db8::
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+root-key-sentinel-not-ta-00000.unsigned. IN TXT
+SECTION ANSWER
+root-key-sentinel-not-ta-00000.unsigned. 1 IN TXT "it works"
+ENTRY_END
+
+RANGE_END
+
+
+; sentinel does not affect qtypes different than A/AAAA
+STEP 111 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+root-key-sentinel-is-ta-48409.unsigned. IN TXT
+ENTRY_END
+
+STEP 112 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA NOERROR
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+root-key-sentinel-is-ta-48409.unsigned. IN TXT
+SECTION ANSWER
+root-key-sentinel-is-ta-48409.unsigned. IN TXT "it works"
+ENTRY_END
+
+STEP 121 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+root-key-sentinel-not-ta-48409.unsigned. IN TXT
+ENTRY_END
+
+STEP 122 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA NOERROR
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+root-key-sentinel-not-ta-48409.unsigned. IN TXT
+SECTION ANSWER
+root-key-sentinel-not-ta-48409.unsigned. IN TXT "it works"
+ENTRY_END
+
+STEP 131 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+root-key-sentinel-is-ta-00000.unsigned. IN TXT
+ENTRY_END
+
+STEP 132 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA NOERROR
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+root-key-sentinel-is-ta-00000.unsigned. IN TXT
+SECTION ANSWER
+root-key-sentinel-is-ta-00000.unsigned. IN TXT "it works"
+ENTRY_END
+
+STEP 141 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+root-key-sentinel-not-ta-00000.unsigned. IN TXT
+ENTRY_END
+
+STEP 142 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA NOERROR
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+root-key-sentinel-not-ta-00000.unsigned. IN TXT
+SECTION ANSWER
+root-key-sentinel-not-ta-00000.unsigned. IN TXT "it works"
+ENTRY_END
+
+; _is-ta does not affect queries when we do not have TA for root
+STEP 211 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+root-key-sentinel-is-ta-48409.unsigned. IN A
+ENTRY_END
+
+STEP 212 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA NOERROR
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+root-key-sentinel-is-ta-48409.unsigned. IN A
+SECTION ANSWER
+root-key-sentinel-is-ta-48409.unsigned. 1 IN A 192.0.2.1
+ENTRY_END
+
+STEP 221 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+root-key-sentinel-is-ta-48409.unsigned. IN AAAA
+ENTRY_END
+
+STEP 222 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA NOERROR
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+root-key-sentinel-is-ta-48409.unsigned. IN AAAA
+SECTION ANSWER
+root-key-sentinel-is-ta-48409.unsigned. 1 IN AAAA 2001:db8::
+ENTRY_END
+
+; _not-ta does not affect queries when we do not have TA for root
+STEP 311 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+root-key-sentinel-not-ta-48409.unsigned. IN A
+ENTRY_END
+
+STEP 312 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA NOERROR
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+root-key-sentinel-not-ta-48409.unsigned. IN A
+SECTION ANSWER
+root-key-sentinel-not-ta-48409.unsigned. 1 IN A 192.0.2.1
+ENTRY_END
+
+STEP 322 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+root-key-sentinel-not-ta-48409.unsigned. IN AAAA
+ENTRY_END
+
+STEP 323 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA NOERROR
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+root-key-sentinel-not-ta-48409.unsigned. IN AAAA
+SECTION ANSWER
+root-key-sentinel-not-ta-48409.unsigned. IN AAAA 2001:db8::
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/val_ta_sentinel_nokey.rpl b/tests/integration/deckard/sets/resolver/val_ta_sentinel_nokey.rpl
new file mode 100644
index 0000000..8335284
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_ta_sentinel_nokey.rpl
@@ -0,0 +1,362 @@
+stub-addr: 2001:503:ba3e::2:30
+stub-name: rootns.
+; no trust-anchor for the root domain
+val-override-date: 20180601000000
+query-minimization: off
+CONFIG_END
+
+SCENARIO_BEGIN draft-ietf-dnsop-kskroll-sentinel-12 section 2 with no root TA
+
+
+RANGE_BEGIN 1 1000
+ ADDRESS 2001:503:ba3e::2:30
+ ADDRESS 198.41.0.4
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. IN SOA
+SECTION ANSWER
+. 86400 IN SOA rootns. you.test. 2017071101 1800 900 604800 86400
+. 86400 IN RRSIG SOA 8 0 86400 20180629135151 20180530135151 48409 . vb9XrP5h9Ojhqbs1Rbdiwxvje/TVFafSZlLf372zpYdtSBI6f7x++GYI WNiUG8EFtchEmL8KNsrWbujpa8tXeWXtatW92kG1qZAnOA40Zw1DjnI8 ZI7volYyq/TMmufKcoNAXU2knAmpZhHDZ+TBOc5HK6TwKeQaRQ6hPwxB JKOjXw2mVjQFP5lck2m2LU9a7iubYRvncRDHmqfjJ9XsSfWi1AU2fmk/ ei/bhKnFMWVH2PXtQlsbxRS8+8SaEL6f4rQC1JqwQ8E03SAZdK7oJKOf GRRFOfYOx7JucTwiV18LAa/j0owSMvuPwYjGnk6BY7e4LTMK2vPgJ3yY lqLmTw==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. IN DNSKEY
+SECTION ANSWER
+. 1814400 IN DNSKEY 257 3 8 AwEAAcliJP8Jh/RjL3c8eaUj8dzVdEksENKubqVA5FdrDJ2rC0O/bGG/ MVZt+WacE1o1mRVwTT/TrhhZUAzZ+qOcpB+IWxURsR4vVqVwakHMny7D 2aLXKoVXwTo/VhAQtHDw5G9bxGgwybPUtd5Vz6EIenUsmNYZ+Spde4l8 vpw7UISVL6q0C1mwHMN18P/1yfHmbkS19b6B1S9Y2aputccF1lso3yiF Ig7UNqqD4PNxSo4jByDnajQSP3qg/LSJSOnzBIumb8wc6svxgugy/pxr BFKgGGk4/JdJCKufdfU5jFX4fJ3HM37G/RccrtGhIf2Z1utoOyaILoa9 wT3O1WaYG/U=
+. 1814400 IN RRSIG DNSKEY 8 0 1814400 20180629135151 20180530135151 48409 . HRj68PBD0cR2p1njZcMUBecR5DiBbueyhIX1oqc9K9Rig5i+ONuozacm 3F4kg9DhUYb/1W6+PSp9YLyrJtCZOFLqkTjPiOAyiE6zVAE/U5O5LRZ/ FjqRQoWuA1cFZtrLokaWmW9GS5Kb2+PUCJY5NRz27JFSvaRRkoHIFf4o mA6eQsuWt28Itx0VGPL9+mR+2B+IcnmN+DZb7mxoRknOh0WyNop4eiep oSZcCihYHOdesCtmrxoMkwGEHZpu8a6GN7jaeNXXNUulwQYfzUZJZQo1 Zr9cN7kzIZ5tAs9ffnPRcWVO61MQTxUtuGbipFpba6RhGmML8oO4JkOJ Itp6tg==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. 518400 IN NS rootns.
+. 518400 IN RRSIG NS 8 0 518400 20180629135151 20180530135151 48409 . ZBLk+sK9ky+YBmzceXbBqEUyBc6nWfAtF6vCK/6cCfL1AxBYOoxdwE/G m0oRAl5WHRrreDSM2t79jcyyUZyyOcee2j/mLPjLdJPQr0Dw9KY+843L o4VSWV0L9adSzgXgvQF/p4yW2zNbHia7doA9GTDjkQFj2+7HgdJdGk8S I2GCx822fqzMCdS3XerIZ4EMz8Lt1sWaexdCgi0sCn9SvqzNHTaIXirW /apL0ohiBNp23LGa7+/7UvNrv+Y/gHpKk2bUytnS7soOocd9XpTekBY7 jlRlmnHTAdn9b9Zj2PHn72v1RYIywP33Qb9ze7i2v7s12uUR3lJt9sd/ WVeuXQ==
+SECTION ADDITIONAL
+rootns. 518400 IN A 198.41.0.4
+rootns. 518400 IN AAAA 2001:503:ba3e::2:30
+rootns. 518400 IN RRSIG A 8 1 518400 20180629135151 20180530135151 48409 . QtR9Z2uVwFVlLy5xQzMVmhqdzZw5cSFbq3xOzhr42gkoD9BYfNyTuhz9 57Sc7kvyJalBHaq3OKoYvE+4anjR8bXk20nGvVjzRdiiqavK41yUpbxC xvo5fWUMj5Bg860AcApn4OOLdFjyKOjJX7ro7QvFdA/adt9WEwhQ3AJ9 PN+SHqtx35F49OUbgiNUEbShJ2VyjOL5bt41LZgffkjim+VB2OtO1hDG CqrKyUlbZ0vxGJhtVflt1Jj3atArHfHz4cuFJHLtSu9PK9piYlSQ54XH vPk0YZ2iKK9sNrVF50Vb7NmLFBCVPn/op0Kmr+u6QVREP6uWayoPtqab /NKvwQ==
+rootns. 518400 IN RRSIG AAAA 8 1 518400 20180629135151 20180530135151 48409 . bs+zTG/nH7uQrgW5qfY5p25uXNoPOsH94K/xNVSLm9h1165/AMekPPd8 KVPnCfyZLPhO+/XyZ5fDUd/2iMCT5m/HyjXR0+j92r6f9ePfAJVQX6U0 DJUa882LgYK7k4usmIIWpi66bpGDC1tlJF3WQ4G12Hc/cUmFTMDBTcM8 6CPPDoT00JZQL8u/66GwNYkWw4mmbiq9UAz03R7A983dUx2GLCAmXoGR Lr3hI3btZa5x+GdJhw5t6Mqi58tXSZfUmT7kpCw+K0H/RscQaVDaOLc6 kzBeVn/Lip60ZSd84kiNWKuSA56TfUbpk7VJclY8UI34COHQqNtD+lev wJ1WgQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rootns. IN NS
+SECTION AUTHORITY
+. 86400 IN SOA rootns. you.test. 2017071101 1800 900 604800 86400
+. 86400 IN RRSIG SOA 8 0 86400 20180629135151 20180530135151 48409 . vb9XrP5h9Ojhqbs1Rbdiwxvje/TVFafSZlLf372zpYdtSBI6f7x++GYI WNiUG8EFtchEmL8KNsrWbujpa8tXeWXtatW92kG1qZAnOA40Zw1DjnI8 ZI7volYyq/TMmufKcoNAXU2knAmpZhHDZ+TBOc5HK6TwKeQaRQ6hPwxB JKOjXw2mVjQFP5lck2m2LU9a7iubYRvncRDHmqfjJ9XsSfWi1AU2fmk/ ei/bhKnFMWVH2PXtQlsbxRS8+8SaEL6f4rQC1JqwQ8E03SAZdK7oJKOf GRRFOfYOx7JucTwiV18LAa/j0owSMvuPwYjGnk6BY7e4LTMK2vPgJ3yY lqLmTw==
+rootns. 86400 IN NSEC root-key-sentinel-is-ta-00000.test. A AAAA RRSIG NSEC
+rootns. 86400 IN RRSIG NSEC 8 1 86400 20180629135151 20180530135151 48409 . noqU9JO9z5QXcedzsm7E6RZ5aIIocIH/jSedo6Zy+GImRTeHpc0le399 DUOsqGlcagx7EWRerScB+xmpL7DxKl0FFyeG0ORvPjJ6IyCFTecWjaKW YVurQnzALW+LhfsPSTxBMnnRhxT5Qrw4dtO0gx7fWyssKUnsMcBdmESs tALFNSfJpiV7so9cK2ssHsC+jkM0AQoemSKJrTesxm8FP1BGT27tz/vx yWIlOUGc8/gBgHo4hoXH1oyCrw9KU9kczRqw4CoCGJtZ2/k15BfmbPlC kLrvLibEmp6OYPVWfJRG79uDHhT+Tul07j26WmA+A7IWXSye8W51WbdH 7gJTKQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rootns. IN A
+SECTION ANSWER
+rootns. 518400 IN A 198.41.0.4
+rootns. 518400 IN RRSIG A 8 1 518400 20180629135151 20180530135151 48409 . QtR9Z2uVwFVlLy5xQzMVmhqdzZw5cSFbq3xOzhr42gkoD9BYfNyTuhz9 57Sc7kvyJalBHaq3OKoYvE+4anjR8bXk20nGvVjzRdiiqavK41yUpbxC xvo5fWUMj5Bg860AcApn4OOLdFjyKOjJX7ro7QvFdA/adt9WEwhQ3AJ9 PN+SHqtx35F49OUbgiNUEbShJ2VyjOL5bt41LZgffkjim+VB2OtO1hDG CqrKyUlbZ0vxGJhtVflt1Jj3atArHfHz4cuFJHLtSu9PK9piYlSQ54XH vPk0YZ2iKK9sNrVF50Vb7NmLFBCVPn/op0Kmr+u6QVREP6uWayoPtqab /NKvwQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rootns. IN AAAA
+SECTION ANSWER
+rootns. 518400 IN AAAA 2001:503:ba3e::2:30
+rootns. 518400 IN RRSIG AAAA 8 1 518400 20180629135151 20180530135151 48409 . bs+zTG/nH7uQrgW5qfY5p25uXNoPOsH94K/xNVSLm9h1165/AMekPPd8 KVPnCfyZLPhO+/XyZ5fDUd/2iMCT5m/HyjXR0+j92r6f9ePfAJVQX6U0 DJUa882LgYK7k4usmIIWpi66bpGDC1tlJF3WQ4G12Hc/cUmFTMDBTcM8 6CPPDoT00JZQL8u/66GwNYkWw4mmbiq9UAz03R7A983dUx2GLCAmXoGR Lr3hI3btZa5x+GdJhw5t6Mqi58tXSZfUmT7kpCw+K0H/RscQaVDaOLc6 kzBeVn/Lip60ZSd84kiNWKuSA56TfUbpk7VJclY8UI34COHQqNtD+lev wJ1WgQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+root-key-sentinel-is-ta-48409.test. IN A
+SECTION ANSWER
+root-key-sentinel-is-ta-48409.test. 1 IN A 192.0.2.1
+root-key-sentinel-is-ta-48409.test. 1 IN RRSIG A 8 2 1 20180629135151 20180530135151 48409 . qWJh+EE/O2w382vLo53ci9i1O/rAzJUUnZPmLF+GCwmLLhDl6tlI3y5A cALqIHkK1vrXzD+mED78YpILzZ73izRFieY6DxMtAXViqH9U8KSy6KWp tAWUASDe1gj9DGdDeiKdTAIo/2qk1PiGdZNc2E9vQLIUTJNfwV8aZGIt PTgl/efGEIMGGFQW5RPbDZpcJLQ11/RUi9FHQyseZRwkCa8EiEfgvPJ2 /rwiCPUcM6BdYzKoZ53cAHBbeKkvgAOpQ88qDvtE12aF9F8anxdHd0Ru 2DlmrPPthn7/faXSBbBECIbnjNlWTiyF7r274SQKFCrT0rJx5N9c31n4 ZSIocg==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+root-key-sentinel-is-ta-48409.test. IN AAAA
+SECTION ANSWER
+root-key-sentinel-is-ta-48409.test. 1 IN AAAA 2001:db8::
+root-key-sentinel-is-ta-48409.test. 1 IN RRSIG AAAA 8 2 1 20180629135151 20180530135151 48409 . J4gFrZRSHHDfMoA2zO22H6A55/893OnGO7h3H9znJGZtp7DxT2vxiGJw InBx5/zPubH87rqTa4AkK2GZuDEqVEDU/fjWOjGQOx16V0oeoHi5/R2R sPTzFnb+NvQnQZCRolMHD2keakdzB8b7dfEV80CrRh7uDsiO8aqhSdiV BFJLXFt5qFd+evKw2SG7l9FNMDzukUSAcFIJepM99X7qjQnKsLuzDjyF 4zhgMolAzAwIQzEi4B+G6IQknx5HsvmpNgkbBFjns+Q7ZYutNecPfiYU vaMpSXb5pztCVLbZQEymIXPgsnzdihlMbzh22TZapLbrDBUVEc2yr/QC Tz/CQA==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+root-key-sentinel-is-ta-48409.test. IN TXT
+SECTION ANSWER
+root-key-sentinel-is-ta-48409.test. 1 IN TXT "it works"
+root-key-sentinel-is-ta-48409.test. 1 IN RRSIG TXT 8 2 1 20180629135151 20180530135151 48409 . tl+oiYdq+UDlh6snkobPI/jQbrPM2tESEyDNIec7wCRvCEo6CLd+oMOA H4P7idKJ1Mey0eMl++YI29Vz2KVAIL0Hiamt32VDXyR5QYVVzNQquH5B /P4PDeoSadK1M+VThnSPT685+CLCbAZfu0Hi7+NulEeQLleBMtSGy0pF eG50H7fecNjqmQ2O/3jKRfD8l86+jba3B2FmpPvsxXgR7Ig5jC/XSpSY 0UMXyntDJz7QOSuhh4GcdNEeUqGVTurqnFjgRmZwReVZqeQzCS8Q+eQn cq23FtXxcAqJCFKN68yoorWmlZhZl0DPm4Zpup28wwlIapO+SGwScD0q KyHZYQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+root-key-sentinel-not-ta-48409.test. IN A
+SECTION ANSWER
+root-key-sentinel-not-ta-48409.test. 1 IN A 192.0.2.1
+root-key-sentinel-not-ta-48409.test. 1 IN RRSIG A 8 2 1 20180629135151 20180530135151 48409 . N1vrpd062YN/PGLOmdAdgPOc2iPPBadtv+DlqoCJ8OUEtFH605m7AUlX HDV99dpT7j6I/N+Sp6pDMRIRl+rB/tFXNfQFoB7UliAsKQ9UuKxH/uyc /sZWxPmYb+4Xi1AKmkzvp7M3Babq7hTGG/PnngN3386Qd0MXiw11Tdl9 +HIan1Jz2jMrHuR2NZDILZOW10wYogYD3/DAx6bVaJMjDbIky5ikK2H/ 4QajIhtjuux4GfsFc7KjGzT1/Hqa9LqdsLetvQmKF4yGNjizOgnrHlbF GoICQ1KihXF3IGYcBUyIoMcmhAjz6D0/jQz/Blwx3zvEUj2Hf7Xj+haO ShdguQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+root-key-sentinel-not-ta-48409.test. IN AAAA
+SECTION ANSWER
+root-key-sentinel-not-ta-48409.test. 1 IN AAAA 2001:db8::
+root-key-sentinel-not-ta-48409.test. 1 IN RRSIG AAAA 8 2 1 20180629135151 20180530135151 48409 . UYk1xmrw2A7ojKSTpwuF90WXsXOfNbRI8pi9tDPLmqr0OMn29AW051vG TyLd7L3ogsaoUEDiY2vYyvyZI3kPL9fSRDYgOIk7Cq3hp7k6wMM3IXS6 iIlYnjtvUFGDaE69EpUjwII22lSWaqOo0dCFnacJYWDfShdZcv7yssWG 9nZpki6aiBAjhYXY8tdMnpDJzq9O3zXPQR8xtuFW4S0aVdrHuSPRq935 DWXThocHxOza6OQp/ZkbemkoqAYjTlu0tyITwZsTknxgK1mtM+ArRmhS eykqVs3mmAGIWMN3qIW8SXKVRHI9PPjka0j6+KK+bfmeck0bI2Wu1f3C cnk+nQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+root-key-sentinel-not-ta-48409.test. IN TXT
+SECTION ANSWER
+root-key-sentinel-not-ta-48409.test. 1 IN TXT "it works"
+root-key-sentinel-not-ta-48409.test. 1 IN RRSIG TXT 8 2 1 20180629135151 20180530135151 48409 . NLK3/UMZZ+39KgwbFFoS6qR2QTEULMxDhlWpK1is+AU3CjUn1RNPRJaq m1MnfJdEq3+FFwVDkpmDGh8lQfTBn192oWlo2goHXZXwuoFN49FPHZ+l u42NWMDKtmS6r9JemJR68jH0jy/AsTMdvAbeodg06cbY6F5Q80EtAdkZ iOZPnqPenfxI+U8C2KgBNas7izGbQZF3FxHi7GZz+wrCGBcjcYX9pcD9 /rf1plZYudefFbxG+P97WfMScDD5vt0dUxz3Yt6YUC48jlyo9WYZDLC5 3qOuqah5oXS1lCGJDm+Kta4koVnm6W4pbCzT9XISwRWZ81rp0NbTrhHb Teu7Pw==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+root-key-sentinel-is-ta-00000.test. IN A
+SECTION ANSWER
+root-key-sentinel-is-ta-00000.test. 1 IN A 192.0.2.1
+root-key-sentinel-is-ta-00000.test. 1 IN RRSIG A 8 2 1 20180629135151 20180530135151 48409 . iYK8FfKFt+aD2Mh+hvFxyE0lCs/jHMT8EWlhPGuiPekHkYnbTaRbGJhT sCeL3Cg1MHrtGr8BXSq1RMyKnn6Y0/bhF1nEjk1gB+vAFHUwWe0yX32U H7E139q68ZyrcUkpV+KkY+ltMSKAjBtGRkYZ9sJhFvll7YCD2HtAMPud KEWpTZS2D0fLATDzAJzJF/2qGMvRUIn0sk5+3HqVh7R3stbl4aSEw5Zp swJoSCs1DN5eaLh6Ovas51uDAa4t6Ove6owR/gR9isqdZCbilAaJ6497 xg4r/KsCu6eG7GAAw5XGh8rkpC5YbsCBlXB565Zk5oY4yBgBUiG/iXGC wyLyJA==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+root-key-sentinel-is-ta-00000.test. IN AAAA
+SECTION ANSWER
+root-key-sentinel-is-ta-00000.test. 1 IN AAAA 2001:db8::
+root-key-sentinel-is-ta-00000.test. 1 IN RRSIG AAAA 8 2 1 20180629135151 20180530135151 48409 . QNF7LtVeew75AhniJ7S0ncsmrHWHCnRcU0H3uyCipyL20kHlpc1NOIUY md7BB02MXm+XOpJF/l/uc9v/C0iuAgOpFVp5kVjtp+gTu2mgceXstFuP 3tNmrL2pSRIWaN8+koS0MlAZCrH9+J9RSFrm5twtD7bIvGT0FVvy/RrR pRWPy9hbqjH6O5DFMdksdVTPLEYFXevAHGKvRa5beRXkrL9ANfVzvPYl q2RaO1aMX6+Cy7AquJpU7DUSReEUBr1f7mYVdd/6sjzoXrd893c+2Fc+ WFLVuWER3eTSrLAQ3b3Etz0lqM3MLrEXwjQFl2mw046nlh21T+u2Ds5s s1/b8g==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+root-key-sentinel-is-ta-00000.test. IN TXT
+SECTION ANSWER
+root-key-sentinel-is-ta-00000.test. 1 IN TXT "it works"
+root-key-sentinel-is-ta-00000.test. 1 IN RRSIG TXT 8 2 1 20180629135151 20180530135151 48409 . cGVwlSItiMGEOKkCWRLUn2od/cBvOlSwj8qxCppe4O1FRyTGgEFNV2nf 2zUkhL/agQhXI3qEjFOkq2b1l+4dM3BwDOF7IGhS3yXV3JGnIcwOC7si EMjRZGIvcEenjfugpIwkwkhTZdgIFoyCUr+g6YxA3iL6L77dftAmIkAV 6gvyarwgeYs0Wi+eEGfrZp2MxJjHDXKF+NfCy/fJnYx2n8SRpXya/Uu+ DJ+S4FQDTDyjDhN/+Tvcsb++sjvNfA4ZDwx5gpgNkRF0xsLHMoxCQagH gJBBziP0cq7l2fy5FVMpGNvdkkiYYG8to/2FF/65GhV+RuNcotD91zyW aeSxWw==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+root-key-sentinel-not-ta-00000.test. IN A
+SECTION ANSWER
+root-key-sentinel-not-ta-00000.test. 1 IN A 192.0.2.1
+root-key-sentinel-not-ta-00000.test. 1 IN RRSIG A 8 2 1 20180629135151 20180530135151 48409 . YYqLZKzjD13hpj345YTNMYYEh3US2BY7DqK9YbNIZi4T0/0jAEFPamKW WcX0nPm5N5S+1VqKIdo/brqvOTaxsq7HnPxVfomg3wyaKNvwqxb2MUpa pYl25ORa7yOm3gwVZJ3NBjh65dLXzGn8t8b047ym7Fnz6JAJHUyM4/SH hZhvXYBX+i3Lojq7HDIReqAtH7zzWdKzKLCTNqAhuqfvEI3edVynpth2 SCMNDVaAUlzVfBLEAkHNp26mLSgcarc3vrb2khdDS13Kv0Ev4rj0w0v1 z0DnVs95Yl2XlnShzNTaW5w1F8f81oBbq2Ly2POxERr5cOCNSGIWMi+q XAt7bQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+root-key-sentinel-not-ta-00000.test. IN AAAA
+SECTION ANSWER
+root-key-sentinel-not-ta-00000.test. 1 IN AAAA 2001:db8::
+root-key-sentinel-not-ta-00000.test. 1 IN RRSIG AAAA 8 2 1 20180629135151 20180530135151 48409 . mHz8sEjHOt+UrLPdGr3s+dake/eRQ6QmushFbLex2e6epkvmriVQwdWa QqG4h75UmjNnOlAwpHJA3oRyKxLJKmVgJIAQzhFc6sHLwEVl+kVyxGfu Q17Md+52E/d+mLMHohKRXljTaghp2uLHX8oDtBP+B2HhIDJK+uhfK63A MZ4k1L4jBGCvEGVMO7BhrpHV9zbY21MOb6EIp/F35jB+ftW7gilKxxBK t+Qt1pwtJcDGVC2xZST6fZ2yaR+U+YhOJ7t9j6WVVTWyFSa1CG3lzyRW PNduZeKYTYwox2uqqUxh+Nmzd1oZt7geIw8CGTYS0B++nVUdNJXJnP51 +evqJQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode question
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+root-key-sentinel-not-ta-00000.test. IN TXT
+SECTION ANSWER
+root-key-sentinel-not-ta-00000.test. 1 IN TXT "it works"
+root-key-sentinel-not-ta-00000.test. 1 IN RRSIG TXT 8 2 1 20180629135151 20180530135151 48409 . SjAFtdUPy+YU4sZnst5GNNYxjzWhBOVqUAfGIUv3uBo5qZW9ePecUJ8G ZkNUkdT7m+cHd0c1ssOBOT7snjwc3Sy3zD22b6/q3N8VowhDQDPkoDlB vt9raR7eXu273cEBDZTQ9P4Ya2Meu32Aftwa6VMQmXMl+qWXhYqffEt6 bJuoohnCVqOZihqgnoT+sRiDl49RgLb+GnZNbFk5EP9LXOrWcdxczKso tY384WCrniRmg4L6NM5DjnBtUVT+Qs6fhWGqQv23fPiLV8lt4i34aIf2 jAQkIE6KD4aNLlehct7eqFo1aeaiZumqEd9/GoqSat/RE7Qsh6hiRkfA /J7MLg==
+ENTRY_END
+
+RANGE_END
+
+
+; sentinel does not affect qtypes different than A/AAAA
+STEP 111 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+root-key-sentinel-is-ta-48409.test. IN TXT
+ENTRY_END
+
+STEP 112 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA NOERROR
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+root-key-sentinel-is-ta-48409.test. IN TXT
+SECTION ANSWER
+root-key-sentinel-is-ta-48409.test. IN TXT "it works"
+ENTRY_END
+
+STEP 121 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+root-key-sentinel-not-ta-48409.test. IN TXT
+ENTRY_END
+
+STEP 122 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA NOERROR
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+root-key-sentinel-not-ta-48409.test. IN TXT
+SECTION ANSWER
+root-key-sentinel-not-ta-48409.test. IN TXT "it works"
+ENTRY_END
+
+STEP 131 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+root-key-sentinel-is-ta-00000.test. IN TXT
+ENTRY_END
+
+STEP 132 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA NOERROR
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+root-key-sentinel-is-ta-00000.test. IN TXT
+SECTION ANSWER
+root-key-sentinel-is-ta-00000.test. IN TXT "it works"
+ENTRY_END
+
+STEP 141 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+root-key-sentinel-not-ta-00000.test. IN TXT
+ENTRY_END
+
+STEP 142 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA NOERROR
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+root-key-sentinel-not-ta-00000.test. IN TXT
+SECTION ANSWER
+root-key-sentinel-not-ta-00000.test. IN TXT "it works"
+ENTRY_END
+
+; _is-ta does not affect queries when we do not have TA for root
+STEP 211 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+root-key-sentinel-is-ta-48409.test. IN A
+ENTRY_END
+
+STEP 212 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA NOERROR
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+root-key-sentinel-is-ta-48409.test. IN A
+SECTION ANSWER
+root-key-sentinel-is-ta-48409.test. 1 IN A 192.0.2.1
+ENTRY_END
+
+STEP 221 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+root-key-sentinel-is-ta-48409.test. IN AAAA
+ENTRY_END
+
+STEP 222 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA NOERROR
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+root-key-sentinel-is-ta-48409.test. IN AAAA
+SECTION ANSWER
+root-key-sentinel-is-ta-48409.test. 1 IN AAAA 2001:db8::
+ENTRY_END
+
+; _not-ta does not affect queries when we do not have TA for root
+STEP 311 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+root-key-sentinel-not-ta-48409.test. IN A
+ENTRY_END
+
+STEP 312 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA NOERROR
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+root-key-sentinel-not-ta-48409.test. IN A
+SECTION ANSWER
+root-key-sentinel-not-ta-48409.test. IN A 192.0.2.1
+ENTRY_END
+
+STEP 322 QUERY
+ENTRY_BEGIN
+REPLY RD AD
+SECTION QUESTION
+root-key-sentinel-not-ta-48409.test. IN AAAA
+ENTRY_END
+
+STEP 323 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY QR RD RA NOERROR
+MATCH opcode rcode flags question answer
+SECTION QUESTION
+root-key-sentinel-not-ta-48409.test. IN AAAA
+SECTION ANSWER
+root-key-sentinel-not-ta-48409.test. IN AAAA 2001:db8::
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/val_unalgo_ds.rpl b/tests/integration/deckard/sets/resolver/val_unalgo_ds.rpl
new file mode 100644
index 0000000..309c117
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_unalgo_ds.rpl
@@ -0,0 +1,204 @@
+do-ip6: no
+
+; config options
+; The island of trust is at example.com
+;server:
+ trust-anchor: "example.com. 3600 IN DS 20009 7 1 9222285F81978C50F77DA894956E77BDCAD281F0 "
+val-override-date: "20181220170056"
+; target-fetch-policy: "0 0 0 0 0"
+; fake-sha1: yes
+
+;stub-zone:
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+query-minimization: off
+CONFIG_END
+
+SCENARIO_BEGIN Test validator with unknown algorithm delegation
+; DS has unknown algo only.
+; so subzone has to be treated as unsigned.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.sub.example.com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.sub.example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20190119150056 20181220150056 20009 example.com. j8376QAQiddoeX7srgtEIo61o+HTctzVFwJUtWPWHJpk20oez5HaGKHE HrOhk4MZQ5fAmtr6a83yEX4hGPvEQJCjUZBBHRHTwC50sxEPFumdV28j +jW5avFhIgkIX9uuiPbYkrh/1l6rhHtPLX8Q8OqkFMkIhFGVYfaxFIvg 4bU= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20190119150056 20181220150056 20009 example.com. eHFRaqW2U4dTQhLc0CIB/JuUpoNdThLzMvXxEfIQkMdKGbxrv93q90lq xFoohvm+ODFtE6rK9ABOXwK3FycPc0sSzaXX2waNGmXOSTAMCjHj9MKv ATThTPhSpTS72qCwa6dlfno/SALheLCPX0NE/jxRAwM4fyaysqXwIPcs U0k= ;{id = 2854}
+ENTRY_END
+
+; response to DNSKEY priming query
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN DNSKEY
+SECTION ANSWER
+example.com. 3600 IN DNSKEY 256 3 7 AwEAAbqb9jXzpXYl+9sTJ88ra4EHRrDxFcprKz3cu26/yY+3Vhq4oDSr VngEkZI3m9rMasBoGa85mHByLvt16crazzLNwGpC6dbUSz37tL+F2Wra 1N+o+yy56BRL8tteLFKGTMyzq3NCkTbXuNrdE//rkByNrKUZz/VeTK8Y z3CkMyNd ;{id = 2854 (zsk), size = 1688b}
+example.com. 3600 IN RRSIG DNSKEY 7 2 3600 20190119150056 20181220150056 20009 example.com. gDHM55rE/2AqgKnmvpQZTWNEWWvx+41mnBB2pH/n3SyKFre73eswv0n8 0HeJU6A3CIDj3LQxdCmz8nf4tUt1oTfBMejROM1NgdRdGWdZeojVzXH2 /bszvyFV+whX3qryw+5UL6/lo0aF8V6vsTepBeIs7GCvdEZqzKBzyRP8 42E= ;{id = 2854}
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20190119150056 20181220150056 20009 example.com. j8376QAQiddoeX7srgtEIo61o+HTctzVFwJUtWPWHJpk20oez5HaGKHE HrOhk4MZQ5fAmtr6a83yEX4hGPvEQJCjUZBBHRHTwC50sxEPFumdV28j +jW5avFhIgkIX9uuiPbYkrh/1l6rhHtPLX8Q8OqkFMkIhFGVYfaxFIvg 4bU= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20190119150056 20181220150056 20009 example.com. eHFRaqW2U4dTQhLc0CIB/JuUpoNdThLzMvXxEfIQkMdKGbxrv93q90lq xFoohvm+ODFtE6rK9ABOXwK3FycPc0sSzaXX2waNGmXOSTAMCjHj9MKv ATThTPhSpTS72qCwa6dlfno/SALheLCPX0NE/jxRAwM4fyaysqXwIPcs U0k= ;{id = 2854}
+ENTRY_END
+
+; response for delegation to sub.example.com.
+ENTRY_BEGIN
+MATCH opcode qtype subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+sub.example.com. IN A
+SECTION ANSWER
+SECTION AUTHORITY
+sub.example.com. IN NS ns.sub.example.com.
+; algorithm 208 is unknown.
+sub.example.com. 3600 IN DS 31953 208 1 84464F35C846F53CB48251175EB351BDAAD48953
+sub.example.com. 3600 IN RRSIG DS 7 3 3600 20190119150756 20181220150756 20009 example.com. PPiE0aTaIWVV9JjoDRiliQjvyuFiehO3APeMjOMW4z/++rtLGnr66Uf7 M+0411UEndgx4/vuBqMqz6eXeivkgeKVxgoBz51OF2blNKM8JGOcgoOM mB5vjQ07DpNtVSQltDWffvLM8Meifj5shgY1m7dbiS1FHKreaQoT90nz a14= ;{id = 2854}
+;sub.example.com. 3600 IN DS 30899 RSASHA1 1 f7ed618f24d5e5202927e1d27bc2e84a141cb4b3
+;sub.example.com. 3600 IN RRSIG DS 3 3 3600 20070926134150 20070829134150 2854 example.com. MCwCFCW3ix0GD4BSvNLWIbROCJt5DAW9AhRt/kg9kBKJ20UBUdumrBUHqnskdA== ;{id = 2854}
+SECTION ADDITIONAL
+ns.sub.example.com. IN A 1.2.3.6
+ENTRY_END
+RANGE_END
+
+; ns.sub.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.6
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+sub.example.com. IN NS
+SECTION ANSWER
+sub.example.com. IN NS ns.sub.example.com.
+sub.example.com. 3600 IN RRSIG NS 5 3 3600 20190119150056 20181220150056 31953 sub.example.com. pnikDTPPngQdMmFi4RZKDEmmaTdobIYTvop2Tw8LPD2kI9LLr2IkNHn9 dP/CqTrW7Lay0824cMBJ4sHbkN2hm3cP9PPWe+5mnnuPSgPgBd4n2vpQ /RE2sxskWiwoEjIjg9+5AaipctC5Gt2jeHpqv9nA+5TA9Cyw7yUdcWzM u7E= ;{id = 30899}
+SECTION ADDITIONAL
+ns.sub.example.com. IN A 1.2.3.6
+ns.sub.example.com. 3600 IN RRSIG A 5 4 3600 20190119150056 20181220150056 31953 sub.example.com. KAWpoyn0rmTzd/NMNUuEf3J0LP6vP5rmm+6TuuFjfapVssIHsQ5jCcE8 L5n/qr4nn21HVqFJgjcdmnSqWlI5kICBeQacvOA7zHyGuxI3vaf+k0m+ SdxzpBYAdWFZpTCbfd7REgVJPk3WXR4aTVO92s/JMO8xmMKSq/CjmGBd IMQ= ;{id = 30899}
+ENTRY_END
+
+; response to DNSKEY priming query
+; sub.example.com. 3600 IN DS 30899 RSASHA1 1 f7ed618f24d5e5202927e1d27bc2e84a141cb4b3
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+sub.example.com. IN DNSKEY
+SECTION ANSWER
+sub.example.com. 3600 IN DNSKEY 256 3 5 AwEAAa346cld5d0e37nm5x0ic42TOBDBlSl9VhlwforF/dQCQoZmp7Ak gG3b9RVJwUQvNvtS1y9jl1IGrXbrt0HcDOKRHKYyONkk12ZVcZzxS9dC FZAe7IX6Id1N8RwEVYaJFHCiEAmL6HcpSLP2B8cfa7ey5zeZD+Wz/yXo a9MCT6WR ;{id = 30899 (zsk), size = 512b}
+sub.example.com. 3600 IN RRSIG DNSKEY 5 3 3600 20190119150056 20181220150056 31953 sub.example.com. mk+IKcijVYZ/Qp1oC7u4fLzj/fVh/yt93cdRXHr8mtrg0YbbStdJKKWr f6dEAYLXmUa6V1tFwNn/w2vg9RM2qRK+4TylxYLfVVTpOFAhg93mqgX8 rKMlTJ97MqYy0KspIXobrQaS/fap9229cMNeQyJXMfdhNrj8HU/U3fIX dAs= ;{id = 30899}
+SECTION AUTHORITY
+sub.example.com. IN NS ns.sub.example.com.
+sub.example.com. 3600 IN RRSIG NS 5 3 3600 20190119150056 20181220150056 31953 sub.example.com. pnikDTPPngQdMmFi4RZKDEmmaTdobIYTvop2Tw8LPD2kI9LLr2IkNHn9 dP/CqTrW7Lay0824cMBJ4sHbkN2hm3cP9PPWe+5mnnuPSgPgBd4n2vpQ /RE2sxskWiwoEjIjg9+5AaipctC5Gt2jeHpqv9nA+5TA9Cyw7yUdcWzM u7E= ;{id = 30899}
+SECTION ADDITIONAL
+ns.sub.example.com. IN A 1.2.3.6
+ns.sub.example.com. 3600 IN RRSIG A 5 4 3600 20190119150056 20181220150056 31953 sub.example.com. KAWpoyn0rmTzd/NMNUuEf3J0LP6vP5rmm+6TuuFjfapVssIHsQ5jCcE8 L5n/qr4nn21HVqFJgjcdmnSqWlI5kICBeQacvOA7zHyGuxI3vaf+k0m+ SdxzpBYAdWFZpTCbfd7REgVJPk3WXR4aTVO92s/JMO8xmMKSq/CjmGBd IMQ= ;{id = 30899}
+ENTRY_END
+
+; response to query of interest
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.sub.example.com. IN A
+SECTION ANSWER
+www.sub.example.com. IN A 11.11.11.11
+www.sub.example.com. 3600 IN RRSIG A 5 4 3600 20190119150056 20181220150056 31953 sub.example.com. XjoXosfFOUyNzvNKM/CjiepBA9fmdkpMWF3nP7rlQyb91nZsNbxqreEB U7YepFJlAyWAK7ODbkH9LxPd+dXKAnR/1NUTPi43GzSt1W/g5YbBOrFf BqVEV6FGsLu8fX/qNQfFnzTbLk6brw7IlN6SlEkxUnTZyHqwtTY+s2Cm Iww= ;{id = 30899}
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.sub.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA DO NOERROR
+SECTION QUESTION
+www.sub.example.com. IN A
+SECTION ANSWER
+www.sub.example.com. 3600 IN A 11.11.11.11
+www.sub.example.com. 3600 IN RRSIG A 5 4 3600 20190119150056 20181220150056 31953 sub.example.com. XjoXosfFOUyNzvNKM/CjiepBA9fmdkpMWF3nP7rlQyb91nZsNbxqreEB U7YepFJlAyWAK7ODbkH9LxPd+dXKAnR/1NUTPi43GzSt1W/g5YbBOrFf BqVEV6FGsLu8fX/qNQfFnzTbLk6brw7IlN6SlEkxUnTZyHqwtTY+s2Cm Iww= ;{id = 30899}
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/val_unknown_algorithm_insecure.rpl b/tests/integration/deckard/sets/resolver/val_unknown_algorithm_insecure.rpl
new file mode 100644
index 0000000..16af94a
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_unknown_algorithm_insecure.rpl
@@ -0,0 +1,162 @@
+stub-addr: 198.41.0.4
+trust-anchor: . IN DS 17002 8 2 775F52082C6A93154F15799C7BC9A47C0DA27C9828BA1EBAEAE5C1F685E69839
+stub-name: rootns.
+query-minimization: no
+val-override-date: 20170801000000
+CONFIG_END
+
+SCENARIO_BEGIN Test DNSSEC with unknown algorithm
+
+
+RANGE_BEGIN 10 40
+ ADDRESS 198.41.0.4
+ ADDRESS 2001:503:ba3e::2:30
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN DNSKEY
+SECTION ANSWER
+. 86400 IN DNSKEY 257 3 8 AwEAAaw5/EVELuakk5srRepPzmDsF0doS/HpE9QBEn0xqRteeRFENh74 WZjO7Zc8QeH0uKDeVXLhG0akgbjnwlAu3P225pZN4ovq0ep3MRU3Wm5t nvsD43D7QH3UdYe6I04aH+8TtAUBDiiKX5IQq6qcYIPk+xXzd3kk4kmQ wV7OnAeZBqHA2ezViSL2p+h14oZ+zvFSd2ohFN3T5RJIlCfT0mNVa+Xh V2dORjR9/gTd9WPdZj/mmLlpw4tf0HBnCRVjryvAeXgy33WZMChLVwmi Ve3FGKBgkYYjxyBVpgFvIgLPmpJiC28XSleNzfYIAU+3ntti+zCIcI7y eKYmT8mQFB0=
+. 86400 IN RRSIG DNSKEY 8 0 86400 20170815084229 20170716084229 17002 . XwUIQY7CBOvvjWiFDjH8fDY3csUTyDiixrgXPCvrK5bY5Z4HKEyPhe0p msVdtFG8h8//L3F8VG7DRJIm737aUUoDknXBvK/MdxdYMzKc2aaW8I8O yznz6Y4H91qVuUD7kxli+VUXIWfB6a/X6CdZFL+EfXo0SF1DVPMJvGLl 5FCJ+QRRknyZV16J5bhcMz42H8McKdNMABrHuK+rROhkhcwY0jH2sQFi 6LH4raijw06aR4ABtGXqo8N/L0+7kyakYR9ToBFng3yQhfncumzSARzK jL+bLKC+7kKu/fX+kmKRxOsrrUBEmQrZpuWuBoyDHWRoYTluvH8KqWcl r1WTFw==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. 518400 IN NS rootns.
+. 518400 IN RRSIG NS 8 0 518400 20170815084229 20170716084229 17002 . UcQ6SwMvSPPp5R75aY11RLKpbcoJMZIByS8FSkYRhi7wav6kJufiwi3+ +CcM3waQiNMadXsqJxY7brykJkuoTjqz+/n7jV2/F63t9Ntx7k2VPVE+ pqN19bu+24Vq6AQfkBDWwP8fzIxtUIP8Yn/UUTsTA9eV7Bgtk462Fhxc hdac3D3jleit1mnpbdep3F0EmtDb50jWDUDpQzYU0N6X1ApbOV1cNdpY v2Bx4w5rR+qmSyRwHWlTcsnbVeoplIs3hxcorhIv7EGt0wAIBAKCPV+/ ecp3il7/oYpHqfIhRvzCuLkVjIdJYC1gfBSbp9/uSVVqgu9euS7yGnTy AWNamQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+rootns. IN A
+SECTION ANSWER
+rootns. 1 IN A 198.41.0.4
+rootns. 1 IN RRSIG A 8 1 1 20170815084229 20170716084229 17002 . XEdMJ2jS5yOY8hecBZDv2oPpmzFucfW08OPlXdoIvtRVyGI7gWXdnYYC ic2pO/w1cKX4NjzeE8wEiYztz2X6hECh7lEz6gf+sb1j4Z1rjdc/Wbue qwucEOs9LJ+P+6DUeBr0jVYR9Pr55IitDVyvx+aa8jlmTDJO+CUNhBMe cLErM2vWRJ3bYbS6N6o3lV2quGjDimpIfg2esa47A2sTRB4zsnlqH3dQ 6iFlUrIRyfgMxFxf9A/WbLwrp9aFOg069HmKdAAN49ITz2lMwIxb6gYO S2KJM9GSaYOGVfyVf0TvGmBYs5sD2bwyFwEBrVH7Z+I8PgGVpXRO+jtw FICQJg==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+rootns. IN AAAA
+SECTION ANSWER
+rootns. 1 IN AAAA 2001:503:ba3e::2:30
+rootns. 1 IN RRSIG AAAA 8 1 1 20170815084229 20170716084229 17002 . gT1s+QQ6wubnvZkmYYO6nARX6wCjq8PATMqmXhlVqQXRZcayHq9FcnHA xBA+ZPpvbJXJSmiyDwNw09g/5mvuo1v9ZMzWoRh+qnGJ/rplD/sukDmw 4xNvTi+LV/MdGg7fid/wVpycYXZTy/+6eeE3obWrgi7i6OMdzDQlm0/u sifQt8M3aFi8gQvSIZ8cJ6Yo69hZ/X1Kh27ce5H0eOOoj/TxcI4UISEw OrJDAYzNLYHQivLzj/UJePKS3xLrHpagsAYt6JQlCYJJWubXyutOkshj rY1EwVrNJ3wgLdFwBToCymtto9HO+X4oZJIT17KwJpQ3OAwZvcBQM0gs w7hvtw==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+test. IN SOA
+SECTION ANSWER
+test. 86400 IN SOA rootns. you.test. 2017071100 1800 900 604800 86400
+test. 86400 IN RRSIG SOA 253 1 86400 20170815084229 20170716084229 12062 test. UNUSABLE==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+test. IN DS
+SECTION ANSWER
+test. 1 IN DS 12062 253 2 E18BD6A9E00A75C0FE17CFBB300AF4A34C1F3F1CCADDF56646007565 8396477A
+test. 1 IN RRSIG DS 8 1 1 20170815084229 20170716084229 17002 . KIbj4XGbPWamI8atPM2x5EzAQu2KC+raKS5AYBuX+blxyOrIYtVhSc1Z poauPhDbofYNAMu9KqZmQkNjaOW9i5Z9NmGXQgTmC5l0TfGC4mc3a21E 3ykuQlVqVfOIkEvA+1boA19mGYw0IQ6MAP6NazDNvsOepCTAxyh0U5Va CvoD3QQMwSHImvhUwbC3Lao2kOIuIHVF1zge4SK+m9eBg6LCqtcD8nJJ gHIdO7r/o+d9miXjjfztRR0ZTaJGz4tZKXgOLJYxDcgjxLXF6unSB68e 1jsa+BncWwyvvkP75VZ9EvCpBgfCGdwg0eujFaRwa3PE1/nPqUaCgael 1qzbXQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+test. IN DNSKEY
+SECTION ANSWER
+test. 86400 IN DNSKEY 257 3 253 UNUSABLE==
+test. 86400 IN RRSIG DNSKEY 253 0 86400 20170815084229 20170716084229 12062 test. UNUSABLE==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+test2. IN SOA
+SECTION ANSWER
+test2. 86400 IN SOA rootns. you.test2. 2017071100 1800 900 604800 86400
+test2. 86400 IN RRSIG SOA 255 1 86400 20170815084229 20170716084229 12062 test2. UNUSABLE==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+test2. IN DS
+SECTION ANSWER
+test2. 1 IN DS 12062 8 255 E18BD6A9E00A75C0FE17CFBB300AF4A34C1F3F1CCADDF56646007565 8396477A
+test2. 1 IN RRSIG DS 8 1 1 20170816080814 20170717080814 17002 . QKmpsz0Q+9n9GiVdyLosxo9gxNRWDR9RrZho5iYW+8TMkW/T4o5ifkjc 79BQkz48hEjrtKF4qvzWjSnM2YMnSGO63pjngjXSPw6zIoBuEihM9Tf/ SAvJfBFdf3m3XYfF5lleC1GbJfSxCLy8KTepS2JhZo6fvNQ+TfPOOBQT eWAVPaxd2VzbuHMz8mkF8QaNLZJhuaJ7EFx6UzcoDpBL5Lv7uPqtm/Nk ovfmu/NxOkbWsrijiB3YwcP5b/V9Qfgkt27P9o8PFx/u3NzSmirRrvm9 C0apwznU+h2xBQ8hy3VlDxkGeS4IA7cH6o7EeLmuIV7MqLsWmAfhNd6J uuVQ4Q==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+test2. IN DNSKEY
+SECTION ANSWER
+test2. 86400 IN DNSKEY 257 3 255 UNUSABLE==
+test2. 86400 IN RRSIG DNSKEY 255 0 86400 20170815084229 20170716084229 12062 test2. UNUSABLE==
+ENTRY_END
+
+RANGE_END
+
+
+STEP 10 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+test. IN SOA
+ENTRY_END
+
+STEP 20 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH opcode rcode flags question answer
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+test. IN SOA
+SECTION ANSWER
+test. 86400 IN SOA rootns. you.test. 2017071100 1800 900 604800 86400
+ENTRY_END
+
+STEP 30 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+test2. IN SOA
+ENTRY_END
+
+STEP 40 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH opcode rcode flags question answer
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+test2. IN SOA
+SECTION ANSWER
+test2. 86400 IN SOA rootns. you.test2. 2017071100 1800 900 604800 86400
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/val_unknown_algorithm_insecure/K.+008+17002.key b/tests/integration/deckard/sets/resolver/val_unknown_algorithm_insecure/K.+008+17002.key
new file mode 100644
index 0000000..83fa74f
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_unknown_algorithm_insecure/K.+008+17002.key
@@ -0,0 +1,5 @@
+; This is a key-signing key, keyid 17002, for .
+; Created: 20170716090354 (Sun Jul 16 11:03:54 2017)
+; Publish: 20170716090354 (Sun Jul 16 11:03:54 2017)
+; Activate: 20170716090354 (Sun Jul 16 11:03:54 2017)
+. IN DNSKEY 257 3 8 AwEAAaw5/EVELuakk5srRepPzmDsF0doS/HpE9QBEn0xqRteeRFENh74 WZjO7Zc8QeH0uKDeVXLhG0akgbjnwlAu3P225pZN4ovq0ep3MRU3Wm5t nvsD43D7QH3UdYe6I04aH+8TtAUBDiiKX5IQq6qcYIPk+xXzd3kk4kmQ wV7OnAeZBqHA2ezViSL2p+h14oZ+zvFSd2ohFN3T5RJIlCfT0mNVa+Xh V2dORjR9/gTd9WPdZj/mmLlpw4tf0HBnCRVjryvAeXgy33WZMChLVwmi Ve3FGKBgkYYjxyBVpgFvIgLPmpJiC28XSleNzfYIAU+3ntti+zCIcI7y eKYmT8mQFB0=
diff --git a/tests/integration/deckard/sets/resolver/val_unknown_algorithm_insecure/K.+008+17002.private b/tests/integration/deckard/sets/resolver/val_unknown_algorithm_insecure/K.+008+17002.private
new file mode 100644
index 0000000..c68d3b0
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_unknown_algorithm_insecure/K.+008+17002.private
@@ -0,0 +1,13 @@
+Private-key-format: v1.3
+Algorithm: 8 (RSASHA256)
+Modulus: rDn8RUQu5qSTmytF6k/OYOwXR2hL8ekT1AESfTGpG155EUQ2HvhZmM7tlzxB4fS4oN5VcuEbRqSBuOfCUC7c/bbmlk3ii+rR6ncxFTdabm2e+wPjcPtAfdR1h7ojThof7xO0BQEOKIpfkhCrqpxgg+T7FfN3eSTiSZDBXs6cB5kGocDZ7NWJIvan6HXihn7O8VJ3aiEU3dPlEkiUJ9PSY1Vr5eFXZ05GNH3+BN31Y91mP+aYuWnDi1/QcGcJFWOvK8B5eDLfdZkwKEtXCaJV7cUYoGCRhiPHIFWmAW8iAs+akmILbxdKV43N9ggBT7ee22L7MIhwjvJ4piZPyZAUHQ==
+PublicExponent: AQAB
+PrivateExponent: F2eB2r/bR8iRroKA68iQmSc8Op33xBYSdbr3kj/PZUK/XRNR7398XYGxU94Cbfxdoq7UGdpxZHYykrgb9d2IdooGZ+KJqM3uXNh5uRJenacT9bSfkdjy+KaImjs3VQPD1y9sRUnRbLzxI95UFclObF4PqPn/AF18ytZ7ELEvDvEJifyxT80VDKx27LWEUrI2xbNMS+BKF4K/RAXWbbuv60oTuBsi+txKehVw+rFNTum6omFJlYVOIXg+kXp3XH4XfXNze6in85ju4V2EbJ/uRjfQPShQFCpboQN1t+W5K9gXQGtD+OqPQGLI1fAb6iUNjKnt+mG7O9XqjMLoUyq2wQ==
+Prime1: 3Tz87rRCofb+IBdD5c3rZwSxDXGTYyaT0tWxBAXMvN2DkvvC+H2pRR784opawatfDhthm/eyNbI1qFYPmufAEge+73md2RnXAb2SWlFDuYLQsRNiyX0CUwjyeZrsgNkXMfyEY3HZcEKYnGqcRXqzdGRjLTukFVFMeeHOtywRg3k=
+Prime2: x0mQ8im68tlfY/ezTvtro3xaEd0Oh1oX696B/dW8allStZxeUz4PUjDQaXzcilnWFgbbc8s8E7f7iB44l4sEe94Saf+c6X3TAw+0n8GAC0DBSIk9GV6MGiN8gVSlqtVnmsJKTL+ZBm+7fyJrDE9TZRyyzs9cHiRgpudeZ/ojKMU=
+Exponent1: XRqZZus9T2PeNisUS9WIx2XWDM5LNGK7uvJq+EJokuK1yFljB6f6YDhWPA/1eaNg8VLclQJ8YNSKeDkfgBUfY3cXBzirEP4q2XSp7pBca+l9YcfCvwB4xfDx+fMUrHSvqj2WiTMUSoX8K3dCJIsqkkTc5+A9gSshf/ljQPqutCE=
+Exponent2: A071WQ/YSq/RJZe3IliKMOyfkixZUWXtf7zx64Tg2+MfvGQcLMWa+4JT82xfPOzA4Ry8B/AXzzv+sQPPbLSiHmxRYfEcacPs/OAF36EWvxkUHGAq44DuUoDEUGFXXr6sOaWAFkYYBENWmYW4wTuP5t3TGhvXK6ju8dZletRsQQE=
+Coefficient: hQUsEUXSZVHOlJM2Hwkkk01K0Ns4z/KOOl4EKz9UK2rt4hC7ZC48Phg40sIk81NIrChNytXkHR7VYTT4DMWX9iz8J4mgKqV8xiaYHV+ggqdW54QLg1/kRe//kn2vT3NYRakFcC1nB3fdvc2BqTZPvIIUF+CZITvy+L2oQQWiqc8=
+Created: 20170716090354
+Publish: 20170716090354
+Activate: 20170716090354
diff --git a/tests/integration/deckard/sets/resolver/val_unknown_algorithm_insecure/root_unknown_ds_algo_and_digest.db b/tests/integration/deckard/sets/resolver/val_unknown_algorithm_insecure/root_unknown_ds_algo_and_digest.db
new file mode 100644
index 0000000..8ec23cf
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_unknown_algorithm_insecure/root_unknown_ds_algo_and_digest.db
@@ -0,0 +1,11 @@
+. 86400 IN SOA rootns. you.test. 2017071100 1800 900 604800 86400
+
+. 518400 IN NS rootns.
+test. 518400 IN NS rootns.
+test2. 518400 IN NS rootns.
+
+rootns. 1 IN A 198.41.0.4
+rootns. 1 IN AAAA 2001:503:ba3e::2:30
+
+test. IN DS 12062 253 2 E18BD6A9E00A75C0FE17CFBB300AF4A34C1F3F1CCADDF566460075658396477A
+test2. IN DS 12062 8 255 E18BD6A9E00A75C0FE17CFBB300AF4A34C1F3F1CCADDF566460075658396477A
diff --git a/tests/integration/deckard/sets/resolver/val_unknown_algorithm_insecure/test.db b/tests/integration/deckard/sets/resolver/val_unknown_algorithm_insecure/test.db
new file mode 100644
index 0000000..d35184e
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_unknown_algorithm_insecure/test.db
@@ -0,0 +1,5 @@
+test. 86400 IN SOA rootns. you.test. 2017071100 1800 900 604800 86400
+
+test. 518400 IN NS rootns.
+
+test. 86000 IN DNSKEY 257 3 253 aGVsbG93b3JsZAo=
diff --git a/tests/integration/deckard/sets/resolver/val_unknown_algorithm_insecure/test2.db b/tests/integration/deckard/sets/resolver/val_unknown_algorithm_insecure/test2.db
new file mode 100644
index 0000000..872f988
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_unknown_algorithm_insecure/test2.db
@@ -0,0 +1,5 @@
+test2. 86400 IN SOA rootns. you.test2. 2017071100 1800 900 604800 86400
+
+test2. 518400 IN NS rootns.
+
+test2. 86000 IN DNSKEY 257 3 253 aGVsbG93b3JsZAo=
diff --git a/tests/integration/deckard/sets/resolver/val_unsecds.rpl b/tests/integration/deckard/sets/resolver/val_unsecds.rpl
new file mode 100644
index 0000000..d7ccf0e
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_unsecds.rpl
@@ -0,0 +1,195 @@
+do-ip6: no
+
+; config options
+; The island of trust is at example.com
+;server:
+ trust-anchor: "example.com. 3600 IN DS 63707 7 1 26D2BF1DF3D9D9FAE39BD1CD501F9FADD2BE9B54 "
+val-override-date: "20181130121927"
+; target-fetch-policy: "0 0 0 0 0"
+; fake-sha1: yes
+
+;stub-zone:
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+query-minimization: off
+CONFIG_END
+
+SCENARIO_BEGIN Test validator with insecure delegation
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.sub.example.com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.sub.example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20181230101927 20181130101927 63707 example.com. sVrUoXjVsHFV9WiQzbSaRmib8MyTFeaTwaQfDblAGpOULYd0MMHnkFmm 7WFrpyOhoAsYA5D56fKFZaahzsPjEB9xKhnaYROCUAu0rSTy7WTrUlo7 sBj+S5KEDag2UuAr+BlBaH2lzTAUJ639aMRuxbYL1J3Iz3Ik1Ek+jOu2 cN4= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101927 20181130101927 63707 example.com. XIyIWLbcpJNlJ5VtaCxDp39vTXZrBgOG2+0RSBMJVcAxhTfUXRwOHGq8 7Gv3c1QAw8kecxmV+c18momoPV+xOscFAlodGzPVbHeiOHpUsTCWyplt VF0RsyYmztV6NIpX0URekh2PIDFlyN+BwFk6LB9gtwzv9UyXxn0ToEKa J1A= ;{id = 2854}
+ENTRY_END
+
+; response to DNSKEY priming query
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN DNSKEY
+SECTION ANSWER
+example.com. 3600 IN DNSKEY 256 3 7 AwEAAcryZrR8pLOukbTLkfJG6fnZueJ0wg2t4JhAyBhsO3dx6c13dMzm DkiJ7ta5aPBXveWIR0Y616V8a6K9OZgrA828IHU6ExqjLnsLomUuWoLh bCoED1Ie4hgsH/J8lJIpBmEK1WzDZM9GY4IVkM3lZugt9gOys2IkQRXp 0Xa2jWE7 ;{id = 2854 (zsk), size = 1688b}
+example.com. 3600 IN RRSIG DNSKEY 7 2 3600 20181230101927 20181130101927 63707 example.com. eHCaXqQmpmMxKbjEG3OvplZHpUGoY9+jVoJ201VIr8pA6nrOrdysoWos X/vDpyVukA7jOoswubGh2fsSnQj8wEHRxXN6dSA/TdyPy8jbeai5mg5l 2bg8LZpzHN6tV3YdJ0ck6VBiQp8F69shBgyV9YtoFrnE2jH19f1mmFWV Ggw= ;{id = 2854}
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20181230101927 20181130101927 63707 example.com. sVrUoXjVsHFV9WiQzbSaRmib8MyTFeaTwaQfDblAGpOULYd0MMHnkFmm 7WFrpyOhoAsYA5D56fKFZaahzsPjEB9xKhnaYROCUAu0rSTy7WTrUlo7 sBj+S5KEDag2UuAr+BlBaH2lzTAUJ639aMRuxbYL1J3Iz3Ik1Ek+jOu2 cN4= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101927 20181130101927 63707 example.com. XIyIWLbcpJNlJ5VtaCxDp39vTXZrBgOG2+0RSBMJVcAxhTfUXRwOHGq8 7Gv3c1QAw8kecxmV+c18momoPV+xOscFAlodGzPVbHeiOHpUsTCWyplt VF0RsyYmztV6NIpX0URekh2PIDFlyN+BwFk6LB9gtwzv9UyXxn0ToEKa J1A= ;{id = 2854}
+ENTRY_END
+
+; response for delegation to sub.example.com.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.sub.example.com. IN A
+SECTION ANSWER
+SECTION AUTHORITY
+sub.example.com. IN NS ns.sub.example.com.
+sub.example.com. IN NSEC www.example.com. NS RRSIG NSEC
+sub.example.com. 3600 IN RRSIG NSEC 7 3 7200 20181230101927 20181130101927 63707 example.com. SUVC+aUQJUyJX+4pSpD813Y7uPy34DpRN8y0FzmaLnGKvwaKQ4DiQY6J 8LtDFFZ8ExHVUa6xzHpGwX+KixZCj/dCUBZVv8HCkSpMLmtakC7XIFyD ojKIkxJoCbzG77r8JXgv3QyvvItgbpkjZkNClWyGd1HOgMhsnBg6oHcs w8M= ;{id = 2854}
+SECTION ADDITIONAL
+ns.sub.example.com. IN A 1.2.3.6
+ENTRY_END
+
+; query for missing DS record.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+sub.example.com. IN DS
+SECTION ANSWER
+SECTION AUTHORITY
+example.com. IN SOA ns.example.com. h.example.com. 2007090504 1800 1800 2419200 7200
+example.com. 3600 IN RRSIG SOA 7 2 3600 20181230101927 20181130101927 63707 example.com. W8OD1Z8xF+OfFDDD/F55RcMJvGduXXavFTlFCxM9H0Tis8rKgtil55eh B6ArRrLAik1NM7zE2oUMdZRx3fkCdIIuii96ceqhApbohZ0R4m8dQWr+ JGKCFXOsoNVYeyxg6Ohg/em5Hh3zdeHk7p+6XcXwv7Hncx033LH9TNr5 A58= ;{id = 2854}
+sub.example.com. IN NSEC www.example.com. NS RRSIG NSEC
+sub.example.com. 3600 IN RRSIG NSEC 7 3 7200 20181230101927 20181130101927 63707 example.com. SUVC+aUQJUyJX+4pSpD813Y7uPy34DpRN8y0FzmaLnGKvwaKQ4DiQY6J 8LtDFFZ8ExHVUa6xzHpGwX+KixZCj/dCUBZVv8HCkSpMLmtakC7XIFyD ojKIkxJoCbzG77r8JXgv3QyvvItgbpkjZkNClWyGd1HOgMhsnBg6oHcs w8M= ;{id = 2854}
+SECTION ADDITIONAL
+ns.sub.example.com. IN A 1.2.3.6
+ENTRY_END
+
+
+RANGE_END
+
+; ns.sub.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.6
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+sub.example.com. IN NS
+SECTION ANSWER
+sub.example.com. IN NS ns.sub.example.com.
+SECTION ADDITIONAL
+ns.sub.example.com. IN A 1.2.3.6
+ENTRY_END
+
+; response to query of interest
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.sub.example.com. IN A
+SECTION ANSWER
+www.sub.example.com. IN A 11.11.11.11
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.sub.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA DO NOERROR
+SECTION QUESTION
+www.sub.example.com. IN A
+SECTION ANSWER
+www.sub.example.com. 3600 IN A 11.11.11.11
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/val_unsecds_negcache.rpl b/tests/integration/deckard/sets/resolver/val_unsecds_negcache.rpl
new file mode 100644
index 0000000..574fec1
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_unsecds_negcache.rpl
@@ -0,0 +1,196 @@
+do-ip6: no
+
+; config options
+; The island of trust is at example.com
+;server:
+ trust-anchor: "example.com. 3600 IN DS 21095 7 1 1A16E6CECEBF9305C5AB107B5BD5993BFF8716C5 "
+val-override-date: "20181130121925"
+; target-fetch-policy: "0 0 0 0 0"
+; fake-sha1: yes
+
+;stub-zone:
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+query-minimization: off
+CONFIG_END
+
+SCENARIO_BEGIN Test validator with insecure delegation and DS negative cache
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.sub.example.com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.sub.example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20181230101925 20181130101925 21095 example.com. W2tTjoEHLswOuMEbbkRAUV3yacfvMGWiVk4Dow+tF1+yeVDGmhk+5+Pm XNJJ4KJQ3caIWjoQicEj4yUIwb7bRA4awFGbC4NoXMlx7c1rWSZ/HRf3 Iw2BuBFP+74GS/c+HMDQAL3qfkJXKToGYJq/5IfUxOYwOnus8ia9ecAB K5A= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101925 20181130101925 21095 example.com. EyF7Iiq36OLwYxp4sMaecCI/sAFrfDIg75XepCMwr8yVW+LdST0dVA9j 6tls8QaEDg5raQhtJB2RtTHe2NmvAt2pPOH+bil5zpri4FO9fAZA7B4q I9UgzxyG+eej+Ee7TgBBsw7I72kPZuv2FCGuoTqXmVNIpr5vDJ/V/q3M lkk= ;{id = 2854}
+ENTRY_END
+
+; response to DNSKEY priming query
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN DNSKEY
+SECTION ANSWER
+example.com. 3600 IN DNSKEY 256 3 7 AwEAAcE4pogrNoVZ7QNbp63zNoH6uzv+Ohz66upXmXfe9xFEYEYjmqI8 QEYCkuY+s7YgfoukU+XIigoE7dl8FgVyFH2rm3j76raYT+hJzKQJt4T1 B6oiSO8SR6V2fghmbxE8+L3uWjsE2n3LzzKRNM4x9nYpqLbAVLjgWCh2 4NcAXnbn ;{id = 2854 (zsk), size = 1688b}
+example.com. 3600 IN RRSIG DNSKEY 7 2 3600 20181230101925 20181130101925 21095 example.com. SWWwowWn1/R2gXg4oUXL5K/71YtgYj2Q8pj10DRLGW5ZDomkbvVw9jin FaHbMgRAB+1WoY+lsbHdF3gwtva8w9QulAdn+stJeCypIS3tR0oDFIqC rR5DbiduTrS0qE/AfITERWDYtXVmQwqV4FG3L0W6j7ak4/Hj7rZjlx/a juE= ;{id = 2854}
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20181230101925 20181130101925 21095 example.com. W2tTjoEHLswOuMEbbkRAUV3yacfvMGWiVk4Dow+tF1+yeVDGmhk+5+Pm XNJJ4KJQ3caIWjoQicEj4yUIwb7bRA4awFGbC4NoXMlx7c1rWSZ/HRf3 Iw2BuBFP+74GS/c+HMDQAL3qfkJXKToGYJq/5IfUxOYwOnus8ia9ecAB K5A= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101925 20181130101925 21095 example.com. EyF7Iiq36OLwYxp4sMaecCI/sAFrfDIg75XepCMwr8yVW+LdST0dVA9j 6tls8QaEDg5raQhtJB2RtTHe2NmvAt2pPOH+bil5zpri4FO9fAZA7B4q I9UgzxyG+eej+Ee7TgBBsw7I72kPZuv2FCGuoTqXmVNIpr5vDJ/V/q3M lkk= ;{id = 2854}
+ENTRY_END
+
+; response for delegation to sub.example.com.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.sub.example.com. IN A
+SECTION ANSWER
+SECTION AUTHORITY
+sub.example.com. IN NS ns.sub.example.com.
+sub.example.com. IN NSEC www.example.com. NS RRSIG NSEC
+sub.example.com. 3600 IN RRSIG NSEC 7 3 3600 20181230101925 20181130101925 21095 example.com. Xkw2D18bwT1N9/584gwEPiMmUYjJgWCBqax8HIhvCHF2bSdSwAk1ZXDN muy7gkLTTkCb+J9pfkcwsr7j0HqNb8h3FJoF+vfgT3vSMx6V7kATkSVa wR/pllcYDoCq99/Y0fMdHAbGLE5fhoRCqv/6GkMic6rSIjI3RfcQ1y2p D7U= ;{id = 2854}
+SECTION ADDITIONAL
+ns.sub.example.com. IN A 1.2.3.6
+ENTRY_END
+
+; query for missing DS record.
+; get it from the negative cache instead!
+;ENTRY_BEGIN
+;MATCH opcode qtype qname
+;ADJUST copy_id
+;REPLY QR NOERROR
+;SECTION QUESTION
+;sub.example.com. IN DS
+;SECTION ANSWER
+;SECTION AUTHORITY
+;example.com. IN SOA ns.example.com. h.example.com. 2007090504 1800 1800 2419200 7200
+;example.com. 3600 IN RRSIG SOA 3 2 3600 20070926134150 20070829134150 2854 example.com. MCwCFC5uwIHSehZtetK2CMNXttSFUB0XAhROFDAgy/FaxR8zFXJzyPdpQG93Sw== ;{id = 2854}
+;sub.example.com. IN NSEC www.example.com. NS RRSIG NSEC
+;sub.example.com. 3600 IN RRSIG NSEC 7 3 3600 20181230101925 20181130101925 21095 example.com. Xkw2D18bwT1N9/584gwEPiMmUYjJgWCBqax8HIhvCHF2bSdSwAk1ZXDN muy7gkLTTkCb+J9pfkcwsr7j0HqNb8h3FJoF+vfgT3vSMx6V7kATkSVa wR/pllcYDoCq99/Y0fMdHAbGLE5fhoRCqv/6GkMic6rSIjI3RfcQ1y2p D7U= ;{id = 2854}
+;SECTION ADDITIONAL
+;ns.sub.example.com. IN A 1.2.3.6
+;ENTRY_END
+
+
+RANGE_END
+
+; ns.sub.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.6
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+sub.example.com. IN NS
+SECTION ANSWER
+sub.example.com. IN NS ns.sub.example.com.
+SECTION ADDITIONAL
+ns.sub.example.com. IN A 1.2.3.6
+ENTRY_END
+
+; response to query of interest
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.sub.example.com. IN A
+SECTION ANSWER
+www.sub.example.com. IN A 11.11.11.11
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.sub.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA DO NOERROR
+SECTION QUESTION
+www.sub.example.com. IN A
+SECTION ANSWER
+www.sub.example.com. 3600 IN A 11.11.11.11
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/val_unsecds_qtypeds.rpl b/tests/integration/deckard/sets/resolver/val_unsecds_qtypeds.rpl
new file mode 100644
index 0000000..13637dd
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_unsecds_qtypeds.rpl
@@ -0,0 +1,211 @@
+do-ip6: no
+
+; config options
+; The island of trust is at example.com
+;server:
+ trust-anchor: "example.com. 3600 IN DS 47879 7 1 E0A42C63E663B5FD45A89D4B10AE2B8CC68A73EA "
+val-override-date: "20181130121926"
+; target-fetch-policy: "0 0 0 0 0"
+; fake-sha1: yes
+
+;stub-zone:
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+query-minimization: off
+CONFIG_END
+
+SCENARIO_BEGIN Test validator with insecure delegation and qtype DS.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+sub.example.com. IN DS
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+sub.example.com. IN DS
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20181230101926 20181130101926 47879 example.com. MMAsjQBG4R8DD0lll4nK7IGv0olKacqEXSPobc4VH51ci+C0k0lxzlew IF/euSnmhV/AF2Y3cypNO8eC/ngpkXFEBMKGKo48t5zDBZcdRBu200oF ZSeX9bJuEwTJ98rtzIBIeD5TRNsC3ZMRjaT4pcngTgdWnslhxvl4gAp8 UOs= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101926 20181130101926 47879 example.com. oUK4kGg2QKG7XtIvfRlMOqLrdJyvcZGSAFZf5Trczn20xF8JA7s7X38J ZmgZyKPm7nY5i4BSYj2qhld+T0taOrw2dTeRpSa0z1/DNXnz2F97SWhd zkFS8g+idBtP/GbaLt/oNc5fndSzTUsmMYWBi843ub+60ghiLF1ZG1L+ qrU= ;{id = 2854}
+ENTRY_END
+
+; response to DNSKEY priming query
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN DNSKEY
+SECTION ANSWER
+example.com. 3600 IN DNSKEY 256 3 7 AwEAAdf/3DGUDLH9AyZf8VTjS4W83QqnKvcEIPyy5JlxuG63Oytmc82s Xo+Tzf35mIKWzfzEDlaTUuKf16eaGN3IYB5kehh4tKqP1gXWWMmegFzg NhfXOR0utxgJHXdTY/wdBUrKEIuYemZYU7s5DXKx4GGqDeRTmgkUQpO6 V3FtN3Cv ;{id = 2854 (zsk), size = 1688b}
+example.com. 3600 IN RRSIG DNSKEY 7 2 3600 20181230101926 20181130101926 47879 example.com. zJ7IPV9PSF7xqbZnQeiKzoo/ziklv1wvSqKnV7a/aojdAGfSNv0fRCro lcfn5lwiGeLN9UR71MNc4ynZgxxH2pSzoogU0ic40nye25oe1hR4QlBb 6hNBkuZn7LU6/+ovxfZVYsYEO7HvXhkNoRnb72amPAr+IMItifjSf+0l +Ec= ;{id = 2854}
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20181230101926 20181130101926 47879 example.com. MMAsjQBG4R8DD0lll4nK7IGv0olKacqEXSPobc4VH51ci+C0k0lxzlew IF/euSnmhV/AF2Y3cypNO8eC/ngpkXFEBMKGKo48t5zDBZcdRBu200oF ZSeX9bJuEwTJ98rtzIBIeD5TRNsC3ZMRjaT4pcngTgdWnslhxvl4gAp8 UOs= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101926 20181130101926 47879 example.com. oUK4kGg2QKG7XtIvfRlMOqLrdJyvcZGSAFZf5Trczn20xF8JA7s7X38J ZmgZyKPm7nY5i4BSYj2qhld+T0taOrw2dTeRpSa0z1/DNXnz2F97SWhd zkFS8g+idBtP/GbaLt/oNc5fndSzTUsmMYWBi843ub+60ghiLF1ZG1L+ qrU= ;{id = 2854}
+ENTRY_END
+
+; query for missing DS record.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+sub.example.com. IN DS
+SECTION ANSWER
+SECTION AUTHORITY
+example.com. IN SOA ns.example.com. h.example.com. 2007090504 1800 1800 2419200 7200
+example.com. 3600 IN RRSIG SOA 7 2 3600 20181230101926 20181130101926 47879 example.com. FhZjZ1FHaz3TuZFJWoN/eBI3XaY9ZLPjMUKdJ4jSZmGs/OzyU9Dcg6yA QwyeqZ1bN0O+eLDfJc8SpNhEne/Yx9xlll2ITSpdExjHHx3m+/f7ZOOV W2wZDHFlj7r906znxzf4oZCVxsnnsHh/4E1ciPBumeFU8vcL1KTo8WL3 kSA= ;{id = 2854}
+sub.example.com. IN NSEC www.example.com. NS RRSIG NSEC
+sub.example.com. 3600 IN RRSIG NSEC 7 3 7200 20181230101926 20181130101926 47879 example.com. pKjqniTOtDqZtoB79vxB4i7utCRwgXq5Hys2ZNhFd4fLNEnbDppX6dQ1 L2DslNkxCChV4l2Y7dCw1Zo8zhxLiaOCjz28TJR8yRIqTVKZqPs/Ui34 ZsO3uUAF4ZC4eV3lO7pvSeXS5ZJiSVbUQ+zAO4eSHrcaRvt4RPlfzTj3 y20= ;{id = 2854}
+SECTION ADDITIONAL
+ns.sub.example.com. IN A 1.2.3.6
+ENTRY_END
+
+; response for delegation to sub.example.com.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+sub.example.com. IN A
+SECTION ANSWER
+SECTION AUTHORITY
+sub.example.com. IN NS ns.sub.example.com.
+sub.example.com. IN NSEC www.example.com. NS RRSIG NSEC
+sub.example.com. 3600 IN RRSIG NSEC 7 3 7200 20181230101926 20181130101926 47879 example.com. pKjqniTOtDqZtoB79vxB4i7utCRwgXq5Hys2ZNhFd4fLNEnbDppX6dQ1 L2DslNkxCChV4l2Y7dCw1Zo8zhxLiaOCjz28TJR8yRIqTVKZqPs/Ui34 ZsO3uUAF4ZC4eV3lO7pvSeXS5ZJiSVbUQ+zAO4eSHrcaRvt4RPlfzTj3 y20= ;{id = 2854}
+SECTION ADDITIONAL
+ns.sub.example.com. IN A 1.2.3.6
+ENTRY_END
+
+
+RANGE_END
+
+; ns.sub.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.6
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+sub.example.com. IN NS
+SECTION ANSWER
+sub.example.com. IN NS ns.sub.example.com.
+SECTION ADDITIONAL
+ns.sub.example.com. IN A 1.2.3.6
+ENTRY_END
+
+; response to query of interest
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.sub.example.com. IN A
+SECTION ANSWER
+www.sub.example.com. IN A 11.11.11.11
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+; query for missing DS record. on wrong side of zone cut.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+sub.example.com. IN DS
+SECTION ANSWER
+SECTION AUTHORITY
+sub.example.com. IN SOA ns.sub.example.com. h.sub.example.com. 2007090504 1800 1800 2419200 7200
+ENTRY_END
+
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+sub.example.com. IN DS
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+sub.example.com. IN DS
+SECTION ANSWER
+SECTION AUTHORITY
+example.com. IN SOA ns.example.com. h.example.com. 2007090504 1800 1800 2419200 7200
+example.com. 3600 IN RRSIG SOA 7 2 3600 20181230101926 20181130101926 47879 example.com. FhZjZ1FHaz3TuZFJWoN/eBI3XaY9ZLPjMUKdJ4jSZmGs/OzyU9Dcg6yA QwyeqZ1bN0O+eLDfJc8SpNhEne/Yx9xlll2ITSpdExjHHx3m+/f7ZOOV W2wZDHFlj7r906znxzf4oZCVxsnnsHh/4E1ciPBumeFU8vcL1KTo8WL3 kSA= ;{id = 2854}
+sub.example.com. IN NSEC www.example.com. NS RRSIG NSEC
+sub.example.com. 3600 IN RRSIG NSEC 7 3 7200 20181230101926 20181130101926 47879 example.com. pKjqniTOtDqZtoB79vxB4i7utCRwgXq5Hys2ZNhFd4fLNEnbDppX6dQ1 L2DslNkxCChV4l2Y7dCw1Zo8zhxLiaOCjz28TJR8yRIqTVKZqPs/Ui34 ZsO3uUAF4ZC4eV3lO7pvSeXS5ZJiSVbUQ+zAO4eSHrcaRvt4RPlfzTj3 y20= ;{id = 2854}
+SECTION ADDITIONAL
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/val_wild_pos.rpl b/tests/integration/deckard/sets/resolver/val_wild_pos.rpl
new file mode 100644
index 0000000..aaf5557
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_wild_pos.rpl
@@ -0,0 +1,163 @@
+do-ip6: no
+
+; config options
+; The island of trust is at example.com
+;server:
+ trust-anchor: "example.com. 3600 IN DS 38075 7 1 58C0ECEB4566D0E38241313B4A8CD853A42FB511 "
+val-override-date: "20181130121928"
+; target-fetch-policy: "0 0 0 0 0"
+; fake-sha1: yes
+
+;stub-zone:
+; name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+query-minimization: off
+CONFIG_END
+
+SCENARIO_BEGIN Test validator with direct wildcard positive response
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+*.example.com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+*.example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.com. IN AAAA
+SECTION ANSWER
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20181230101928 20181130101928 38075 example.com. VLjbRTUiJ9qkucaMzZrX8yOwPmvBGeu2yv97i60m+eb8rn/9aXHCft8S 1oD4UTjZzNQCKcWr8nnPKFUSdf78Wnjrt3aVBFbCUYKsdz6Ru94O+kWf VUgCWLdL5vrWHgBp22KyFMNmT5jl+u6pBCYfeUR6DQNgMcB/Xk6TIp6P 3xs= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101928 20181130101928 38075 example.com. EcQ0T61tBc0Wv3hnZhRO2rf8gvyX3ERzKQy/f7c881D+30gj/7f5t1G2 mNNgeORipwMdxXtimHy3aE2zPycWlYO0ixp4UTztDcePRLPKOmyF4JRZ svMiaBK65fuuBjiG8Ul5QkgBJldObCcFIYo1GjX9L6o3I3zdU3O3DsbP 1ts= ;{id = 2854}
+ENTRY_END
+
+; response to DNSKEY priming query
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN DNSKEY
+SECTION ANSWER
+example.com. 3600 IN DNSKEY 256 3 7 AwEAAbunHwPamENL1sKnlaDimJmh7EubUP/2CelBZJ7H7PMSCz7GPt3u B5rJP7aOogioqA0yJZubiEJESzfwEsg5f14lWESGzMz8mFfe5pGryUjk tG/n43vmCkTPdyUTeSKW9RWyQAPv0PHMi0rMfe5sXs1eeAo23i7c4BAX /MKh/k5r ;{id = 2854 (zsk), size = 1688b}
+example.com. 3600 IN RRSIG DNSKEY 7 2 3600 20181230101928 20181130101928 38075 example.com. XSdpLw0K9ZLwZXI6/pD58YqfUWHxVr2l1EZ5uKhL2Oa+BLalYhlvJYtx SKRcD6Bc5K526HaJ08kv54j2kxeyUtjNXJf1qcC0xup4lQ3s8gjFx+OS NVhCQoEwSWIbOieL2cfDepEMYOOnxtP4WD6I6C3gIBTMluI/UwEOnRlK lIs= ;{id = 2854}
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20181230101928 20181130101928 38075 example.com. VLjbRTUiJ9qkucaMzZrX8yOwPmvBGeu2yv97i60m+eb8rn/9aXHCft8S 1oD4UTjZzNQCKcWr8nnPKFUSdf78Wnjrt3aVBFbCUYKsdz6Ru94O+kWf VUgCWLdL5vrWHgBp22KyFMNmT5jl+u6pBCYfeUR6DQNgMcB/Xk6TIp6P 3xs= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101928 20181130101928 38075 example.com. EcQ0T61tBc0Wv3hnZhRO2rf8gvyX3ERzKQy/f7c881D+30gj/7f5t1G2 mNNgeORipwMdxXtimHy3aE2zPycWlYO0ixp4UTztDcePRLPKOmyF4JRZ svMiaBK65fuuBjiG8Ul5QkgBJldObCcFIYo1GjX9L6o3I3zdU3O3DsbP 1ts= ;{id = 2854}
+ENTRY_END
+
+; response to query of interest
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+*.example.com. IN A
+SECTION ANSWER
+*.example.com. IN A 10.20.30.40
+*.example.com. 3600 IN RRSIG A 7 2 3600 20181230101928 20181130101928 38075 example.com. RkzaVAFptvrjbFcVTye2cG720T9sstFdEh6rfTb4kDDi36GlKsrWa2hZ XtXLGYf2VisO/ronIOFTN+OpqHEN4zcsft3gRAWN+v2irAWDPD4WRVKh 1DNdJMKi2fDq2A39oe15ZwyjTc+owev5RONrMZBoUdgVb0lzhri2LNgF dgY= ;{id = 2854}
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 7 2 3600 20181230101928 20181130101928 38075 example.com. VLjbRTUiJ9qkucaMzZrX8yOwPmvBGeu2yv97i60m+eb8rn/9aXHCft8S 1oD4UTjZzNQCKcWr8nnPKFUSdf78Wnjrt3aVBFbCUYKsdz6Ru94O+kWf VUgCWLdL5vrWHgBp22KyFMNmT5jl+u6pBCYfeUR6DQNgMcB/Xk6TIp6P 3xs= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101928 20181130101928 38075 example.com. EcQ0T61tBc0Wv3hnZhRO2rf8gvyX3ERzKQy/f7c881D+30gj/7f5t1G2 mNNgeORipwMdxXtimHy3aE2zPycWlYO0ixp4UTztDcePRLPKOmyF4JRZ svMiaBK65fuuBjiG8Ul5QkgBJldObCcFIYo1GjX9L6o3I3zdU3O3DsbP 1ts= ;{id = 2854}
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+*.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH opcode rcode flags question answer
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+*.example.com. IN A
+SECTION ANSWER
+*.example.com. IN A 10.20.30.40
+*.example.com. 3600 IN RRSIG A 7 2 3600 20181230101928 20181130101928 38075 example.com. RkzaVAFptvrjbFcVTye2cG720T9sstFdEh6rfTb4kDDi36GlKsrWa2hZ XtXLGYf2VisO/ronIOFTN+OpqHEN4zcsft3gRAWN+v2irAWDPD4WRVKh 1DNdJMKi2fDq2A39oe15ZwyjTc+owev5RONrMZBoUdgVb0lzhri2LNgF dgY= ;{id = 2854}
+;SECTION AUTHORITY
+;example.com. IN NS ns.example.com.
+;example.com. 3600 IN RRSIG NS 7 2 3600 20181230101928 20181130101928 38075 example.com. VLjbRTUiJ9qkucaMzZrX8yOwPmvBGeu2yv97i60m+eb8rn/9aXHCft8S 1oD4UTjZzNQCKcWr8nnPKFUSdf78Wnjrt3aVBFbCUYKsdz6Ru94O+kWf VUgCWLdL5vrWHgBp22KyFMNmT5jl+u6pBCYfeUR6DQNgMcB/Xk6TIp6P 3xs= ;{id = 2854}
+;SECTION ADDITIONAL
+;ns.example.com. IN A 1.2.3.4
+;ns.example.com. 3600 IN RRSIG A 7 3 3600 20181230101928 20181130101928 38075 example.com. EcQ0T61tBc0Wv3hnZhRO2rf8gvyX3ERzKQy/f7c881D+30gj/7f5t1G2 mNNgeORipwMdxXtimHy3aE2zPycWlYO0ixp4UTztDcePRLPKOmyF4JRZ svMiaBK65fuuBjiG8Ul5QkgBJldObCcFIYo1GjX9L6o3I3zdU3O3DsbP 1ts= ;{id = 2854}
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/val_wild_pos_multi.rpl b/tests/integration/deckard/sets/resolver/val_wild_pos_multi.rpl
new file mode 100644
index 0000000..8224936
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_wild_pos_multi.rpl
@@ -0,0 +1,239 @@
+; config options
+;server:
+ trust-anchor: ". IN DS 41524 8 2 5175938255D97A88F9D16A5A46ED3AE373441DF5058C1666D953005D A6BD57F3"
+ val-override-date: "20170501000000"
+
+;stub-zone:
+; name: "."
+ stub-addr: 10.1.1.1 # ns.
+ stub-name: ns.
+CONFIG_END
+
+SCENARIO_BEGIN Test validation of wildcard responses with multiple synthesized RRs.
+; ns.
+RANGE_BEGIN 0 1000
+ ADDRESS 10.1.1.1
+ ADDRESS 10.2.2.2
+ ADDRESS 10.3.3.3
+ ;ADDRESS ::1 ;FIXME: can't use ::1 in tests since the transition to linux namespaces
+ ADDRESS ::2
+ ADDRESS ::3
+
+ENTRY_BEGIN
+MATCH opcode qtype
+ADJUST copy_id copy_query
+REPLY QR AA REFUSED
+SECTION QUESTION
+. IN RRSIG
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+. IN DNSKEY
+SECTION ANSWER
+. 3600 IN DNSKEY 257 3 8 AwEAAbgyvYQ2Vlff/inpv4NZLlIk2+l1sL0JoeOUlWHZ3eeWXZKxQJak QIXyGi8xsuANzu/YStLp31SfU/Fj4piUciqA+U74Lot1S/jcM7/1eczh 69YqGUAPZkreZ3z2DpWzBN4lgPR/w0OvTada3D42uV2bzuSK/nXMiMpZ vP1vZ1ykNRmbksTzA+HnrefRi2yuMSUqMHbtfbfFwqVTQ1ddVwSK7qIJ 02jo95YJUSZDPUUQlczIsFsa7Zxn6gQZl+iaRuDY6nLxxStYYlcqZhVA G5U8Dx4IznQ0FkEJp9RXtv5rmtClcQpudCl1gE0GC/W+TTUAa3hD597f onH+s/OfdCE=
+. 3600 IN RRSIG DNSKEY 8 0 3600 20170519062759 20170419062759 41524 . GldXJTOYlVu202Dfdn6n6+ueu59rULnFZqpGSWO1b5TWhY0Z58f8JLNq OeGS1R2OxUZHEy6MQGgiBUEbBXxUx5fZh0UI0K9D7FfwIA9A5hmHC86g Ds3YQuGM0XfHT1aVeGPnjbcIGkRvTtD2P8vc12WT0bm56xLzNu33pat8 PB7/60S5KY1quSqw0HksIEo/Brblql6DPVYRUxZE2+xObOehUhc2W1n5 v+/pEzpRJ22CJ17Bvc4Mf8sBGgFqxFzmBcgf4Ae0UG3Fz8GIjwcN80cm dYK9cuaCIKn+m/lk3/tXlNJigNxdYB0N6vr6bBhfHOuv8VhEr+0iKM2G sG0ugg==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. 3600 IN NS ns.
+. 3600 IN RRSIG NS 8 0 3600 20170519062759 20170419062759 41524 . VmrJp+587qjS63rXgtCzIDyja2l8Hp09GB9iUNR33C/P5nkCn3hjsu+u 67c++Ck6/jgKvn9pRW3JdhOaxTeJRZBsYUKq3JtDuHVuV9WaNvDfCJhI /wFMrNTIR1UK9GxHgAWvZ2nBjKNV/nX4w+OB8eDKeT1AGgvoF182pCI0 VX9pbYd2gsMiZsymm5KRuicFxCMxvAa0jmkg9Pua1vQ2kraVjQP/qND4 gEXZaOmGfmm1UUrXlXdnJYrf6j/0zXaVjZdK6TvNh1kEpzXfDX4GLCDa 3dwy7O/h+IRHl7d+X8d1iojdvyJ2qzPkZ9EI7hlEPc7VY2pqNCtC/2WZ c0bf5w==
+SECTION ADDITIONAL
+ns. 3600 IN A 10.1.1.1
+ns. 3600 IN A 10.2.2.2
+ns. 3600 IN A 10.3.3.3
+ns. 3600 IN RRSIG A 8 0 3600 20170519062759 20170419062759 41524 . UtmUBa+ubwWz1BlKcbg/jUhYYPj2qowEjr2IgVMeMopTgESE7Ssg2XMU YY4q2drAXsR/t1uNDIjhDaCXmsyK5yINavxgmPhypt1dnIyXf8+Lfmoi RTP1JKRvsFssQgJMrfCge82oTDYqfmav0NddGNNx829MC5+M/8JtygZU kOczXuwAKclUsFKophlmh3bn3hC6fzBWvRh59j5Voy2oYOw4yHtgDlEN qWQY1BPKYR2FKQG+sVPRhBufWN3uLK2sN8hviaE8gUluwaVx8ekjnr9t twA1h54DRYlJVU2ARCo+xN+hTQG/kt0Rqcr72Vq0LdTxpy+sERQ72tM5 fVvl9Q==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns. IN A
+SECTION ANSWER
+ns. 3600 IN A 10.1.1.1
+ns. 3600 IN A 10.2.2.2
+ns. 3600 IN A 10.3.3.3
+ns. 3600 IN RRSIG A 8 0 3600 20170519062759 20170419062759 41524 . UtmUBa+ubwWz1BlKcbg/jUhYYPj2qowEjr2IgVMeMopTgESE7Ssg2XMU YY4q2drAXsR/t1uNDIjhDaCXmsyK5yINavxgmPhypt1dnIyXf8+Lfmoi RTP1JKRvsFssQgJMrfCge82oTDYqfmav0NddGNNx829MC5+M/8JtygZU kOczXuwAKclUsFKophlmh3bn3hC6fzBWvRh59j5Voy2oYOw4yHtgDlEN qWQY1BPKYR2FKQG+sVPRhBufWN3uLK2sN8hviaE8gUluwaVx8ekjnr9t twA1h54DRYlJVU2ARCo+xN+hTQG/kt0Rqcr72Vq0LdTxpy+sERQ72tM5 fVvl9Q==
+SECTION AUTHORITY
+*. 0 IN NSEC . A AAAA RRSIG NSEC
+*. 0 IN RRSIG NSEC 8 0 0 20170519141813 20170419141813 41524 . FgFsXY4fdEQZlv5xd2WQuH6b0YIuDoOydNXviOPAoK/FYucZPqPxLAGs C1bQQ82YlPy1SU1HMbggjMNT224sllm0WY0P1PjkPN8XkBbFRZtKl6YO 6Jyav58WZCjDLsRfKYMzFPXe7GqvtB61YkvCf6p/sqxOAuWKqSkHIlyJ VUNETyfYKlp5x7CDZiCnPgAppZUEv0kEQKmTCzTgC+ctj2S25eTAgsDb 8R0FCb5ks+AcvWZZyNTbwvstaz92EqSOCCWkGSDF3gp2Pv5SI+3xUeTy c/NuJ+f366C5w0MsaW+9oXo2zy/aOFULzwFtdH8ZizqzwwNdGS1sqvuw 1UaqkA==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns. IN AAAA
+SECTION ANSWER
+ns. 3600 IN AAAA ::1
+ns. 3600 IN AAAA ::2
+ns. 3600 IN AAAA ::3
+ns. 3600 IN RRSIG AAAA 8 0 3600 20170519141813 20170419141813 41524 . q256A5GuT3+3jMaDXhh7Z2w/lPYNxtSLamf4TPcAuIDm41Fnj4M1OU63 ViuoBM2GNP512YZxL9wjkTXVjbQJ3nfIT4D7vRdtNpcA48lceYRslBOP qxuFLxRNbW+a1iLA28IiouecsmJIpfLNfCR9OAMKnuFbdkDHNDYEVyKt TRDuqANfj9s8tEH5SLwoycAtLxP5nBVPqOCgNJAg7j+qNXcA/I+dhqBf xy9eMNmhMbDN09x0+k63vJcdhsgj1sxAqvnq973r+uM7T1WDBjcn71CS fDP3kplHxM4vGpmDvJ5MkStLQ/+kqGNVb9qUl65gBidsA3SYqkZ3KtxT Br/61w==
+SECTION AUTHORITY
+*. 0 IN NSEC . A AAAA RRSIG NSEC
+*. 0 IN RRSIG NSEC 8 0 0 20170519141813 20170419141813 41524 . FgFsXY4fdEQZlv5xd2WQuH6b0YIuDoOydNXviOPAoK/FYucZPqPxLAGs C1bQQ82YlPy1SU1HMbggjMNT224sllm0WY0P1PjkPN8XkBbFRZtKl6YO 6Jyav58WZCjDLsRfKYMzFPXe7GqvtB61YkvCf6p/sqxOAuWKqSkHIlyJ VUNETyfYKlp5x7CDZiCnPgAppZUEv0kEQKmTCzTgC+ctj2S25eTAgsDb 8R0FCb5ks+AcvWZZyNTbwvstaz92EqSOCCWkGSDF3gp2Pv5SI+3xUeTy c/NuJ+f366C5w0MsaW+9oXo2zy/aOFULzwFtdH8ZizqzwwNdGS1sqvuw 1UaqkA==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns. IN TXT
+SECTION AUTHORITY
+. 0 IN SOA . . 0 0 0 0 0
+*. 0 IN NSEC . A AAAA RRSIG NSEC
+. 3600 IN RRSIG SOA 8 0 3600 20170519141813 20170419141813 41524 . iuxo0/dNl+zFK1i7CnGR0ssx39IkWTkqXWOcbm8ZrN/vnV2lt7tkRctV 4MmoCiIFfTd4R+jWorVlV0eu1FVmm8cvEAPJzZKk79hvS7DrL5cvwlDA OXSS8J2ram3h+eJH2FCHkSKPkqJUlpXPsQbnfVFf4bFTYi5rXE+Nkpij qhACwhHb8HZNay1/L/njW2DvnY40rgoArxKoJyw0lDgYWd2YYsqHjDGp Ditdeam33tEdWmn8N2oSOXOaRZ3MjDL0PL0uOanJ2wiLFs33MlGo/Y1q ncGgLBSiLFEOhpYgPP3CRu7QZxjQjinwq+tRRhwaqyfPPliHO22NblwL 7tp8qg==
+*. 0 IN RRSIG NSEC 8 0 0 20170519141813 20170419141813 41524 . FgFsXY4fdEQZlv5xd2WQuH6b0YIuDoOydNXviOPAoK/FYucZPqPxLAGs C1bQQ82YlPy1SU1HMbggjMNT224sllm0WY0P1PjkPN8XkBbFRZtKl6YO 6Jyav58WZCjDLsRfKYMzFPXe7GqvtB61YkvCf6p/sqxOAuWKqSkHIlyJ VUNETyfYKlp5x7CDZiCnPgAppZUEv0kEQKmTCzTgC+ctj2S25eTAgsDb 8R0FCb5ks+AcvWZZyNTbwvstaz92EqSOCCWkGSDF3gp2Pv5SI+3xUeTy c/NuJ+f366C5w0MsaW+9oXo2zy/aOFULzwFtdH8ZizqzwwNdGS1sqvuw 1UaqkA==
+ENTRY_END
+
+RANGE_END
+
+; recursion happens here, we expect NODATA
+STEP 101 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+ns. IN TXT
+ENTRY_END
+
+STEP 102 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+ADJUST copy_id
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+ns. IN TXT
+SECTION AUTHORITY
+. 0 IN SOA . . 0 0 0 0 0
+ENTRY_END
+
+; recursion happens here, we expect positive answer
+STEP 110 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+ns. IN A
+ENTRY_END
+
+STEP 111 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+ADJUST copy_id
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+ns. IN A
+SECTION ANSWER
+ns. 3600 IN A 10.1.1.1
+ns. 3600 IN A 10.2.2.2
+ns. 3600 IN A 10.3.3.3
+ENTRY_END
+
+; recursion happens here, we expect positive answer
+STEP 120 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+ns. IN AAAA
+ENTRY_END
+
+STEP 121 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+ADJUST copy_id
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+ns. IN AAAA
+SECTION ANSWER
+ns. 3600 IN AAAA ::1
+ns. 3600 IN AAAA ::2
+ns. 3600 IN AAAA ::3
+ENTRY_END
+
+
+
+; retry with DNSSEC enabled
+
+; recursion happens here, we expect NODATA wildcard proof
+STEP 131 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+ns. IN TXT
+ENTRY_END
+
+STEP 132 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+ADJUST copy_id
+REPLY QR RD RA AD NOERROR
+SECTION QUESTION
+ns. IN TXT
+SECTION AUTHORITY
+. 0 IN SOA . . 0 0 0 0 0
+*. 0 IN NSEC . A AAAA RRSIG NSEC
+. 3600 IN RRSIG SOA 8 0 3600 20170519141813 20170419141813 41524 . iuxo0/dNl+zFK1i7CnGR0ssx39IkWTkqXWOcbm8ZrN/vnV2lt7tkRctV 4MmoCiIFfTd4R+jWorVlV0eu1FVmm8cvEAPJzZKk79hvS7DrL5cvwlDA OXSS8J2ram3h+eJH2FCHkSKPkqJUlpXPsQbnfVFf4bFTYi5rXE+Nkpij qhACwhHb8HZNay1/L/njW2DvnY40rgoArxKoJyw0lDgYWd2YYsqHjDGp Ditdeam33tEdWmn8N2oSOXOaRZ3MjDL0PL0uOanJ2wiLFs33MlGo/Y1q ncGgLBSiLFEOhpYgPP3CRu7QZxjQjinwq+tRRhwaqyfPPliHO22NblwL 7tp8qg==
+*. 0 IN RRSIG NSEC 8 0 0 20170519141813 20170419141813 41524 . FgFsXY4fdEQZlv5xd2WQuH6b0YIuDoOydNXviOPAoK/FYucZPqPxLAGs C1bQQ82YlPy1SU1HMbggjMNT224sllm0WY0P1PjkPN8XkBbFRZtKl6YO 6Jyav58WZCjDLsRfKYMzFPXe7GqvtB61YkvCf6p/sqxOAuWKqSkHIlyJ VUNETyfYKlp5x7CDZiCnPgAppZUEv0kEQKmTCzTgC+ctj2S25eTAgsDb 8R0FCb5ks+AcvWZZyNTbwvstaz92EqSOCCWkGSDF3gp2Pv5SI+3xUeTy c/NuJ+f366C5w0MsaW+9oXo2zy/aOFULzwFtdH8ZizqzwwNdGS1sqvuw 1UaqkA==
+ENTRY_END
+
+STEP 210 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+ns. IN A
+ENTRY_END
+
+STEP 211 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+ADJUST copy_id
+REPLY QR RD RA AD NOERROR
+SECTION QUESTION
+ns. IN A
+SECTION ANSWER
+ns. 3600 IN A 10.1.1.1
+ns. 3600 IN A 10.2.2.2
+ns. 3600 IN A 10.3.3.3
+ns. 3600 IN RRSIG A 8 0 3600 20170519062759 20170419062759 41524 . UtmUBa+ubwWz1BlKcbg/jUhYYPj2qowEjr2IgVMeMopTgESE7Ssg2XMU YY4q2drAXsR/t1uNDIjhDaCXmsyK5yINavxgmPhypt1dnIyXf8+Lfmoi RTP1JKRvsFssQgJMrfCge82oTDYqfmav0NddGNNx829MC5+M/8JtygZU kOczXuwAKclUsFKophlmh3bn3hC6fzBWvRh59j5Voy2oYOw4yHtgDlEN qWQY1BPKYR2FKQG+sVPRhBufWN3uLK2sN8hviaE8gUluwaVx8ekjnr9t twA1h54DRYlJVU2ARCo+xN+hTQG/kt0Rqcr72Vq0LdTxpy+sERQ72tM5 fVvl9Q==
+SECTION AUTHORITY
+*. 0 IN NSEC . A AAAA RRSIG NSEC
+*. 0 IN RRSIG NSEC 8 0 0 20170519141813 20170419141813 41524 . FgFsXY4fdEQZlv5xd2WQuH6b0YIuDoOydNXviOPAoK/FYucZPqPxLAGs C1bQQ82YlPy1SU1HMbggjMNT224sllm0WY0P1PjkPN8XkBbFRZtKl6YO 6Jyav58WZCjDLsRfKYMzFPXe7GqvtB61YkvCf6p/sqxOAuWKqSkHIlyJ VUNETyfYKlp5x7CDZiCnPgAppZUEv0kEQKmTCzTgC+ctj2S25eTAgsDb 8R0FCb5ks+AcvWZZyNTbwvstaz92EqSOCCWkGSDF3gp2Pv5SI+3xUeTy c/NuJ+f366C5w0MsaW+9oXo2zy/aOFULzwFtdH8ZizqzwwNdGS1sqvuw 1UaqkA==
+ENTRY_END
+
+STEP 220 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+ns. IN AAAA
+ENTRY_END
+
+STEP 221 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+ADJUST copy_id
+REPLY QR RD RA AD NOERROR
+SECTION QUESTION
+ns. IN AAAA
+SECTION ANSWER
+ns. 3600 IN AAAA ::1
+ns. 3600 IN AAAA ::2
+ns. 3600 IN AAAA ::3
+ns. 3600 IN RRSIG AAAA 8 0 3600 20170519141813 20170419141813 41524 . q256A5GuT3+3jMaDXhh7Z2w/lPYNxtSLamf4TPcAuIDm41Fnj4M1OU63 ViuoBM2GNP512YZxL9wjkTXVjbQJ3nfIT4D7vRdtNpcA48lceYRslBOP qxuFLxRNbW+a1iLA28IiouecsmJIpfLNfCR9OAMKnuFbdkDHNDYEVyKt TRDuqANfj9s8tEH5SLwoycAtLxP5nBVPqOCgNJAg7j+qNXcA/I+dhqBf xy9eMNmhMbDN09x0+k63vJcdhsgj1sxAqvnq973r+uM7T1WDBjcn71CS fDP3kplHxM4vGpmDvJ5MkStLQ/+kqGNVb9qUl65gBidsA3SYqkZ3KtxT Br/61w==
+SECTION AUTHORITY
+*. 0 IN NSEC . A AAAA RRSIG NSEC
+*. 0 IN RRSIG NSEC 8 0 0 20170519141813 20170419141813 41524 . FgFsXY4fdEQZlv5xd2WQuH6b0YIuDoOydNXviOPAoK/FYucZPqPxLAGs C1bQQ82YlPy1SU1HMbggjMNT224sllm0WY0P1PjkPN8XkBbFRZtKl6YO 6Jyav58WZCjDLsRfKYMzFPXe7GqvtB61YkvCf6p/sqxOAuWKqSkHIlyJ VUNETyfYKlp5x7CDZiCnPgAppZUEv0kEQKmTCzTgC+ctj2S25eTAgsDb 8R0FCb5ks+AcvWZZyNTbwvstaz92EqSOCCWkGSDF3gp2Pv5SI+3xUeTy c/NuJ+f366C5w0MsaW+9oXo2zy/aOFULzwFtdH8ZizqzwwNdGS1sqvuw 1UaqkA==
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/val_wild_pos_multi/K.+008+41524.key b/tests/integration/deckard/sets/resolver/val_wild_pos_multi/K.+008+41524.key
new file mode 100644
index 0000000..1511e45
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_wild_pos_multi/K.+008+41524.key
@@ -0,0 +1,5 @@
+; This is a key-signing key, keyid 41524, for .
+; Created: 20170319134901 (Sun Mar 19 14:49:01 2017)
+; Publish: 20170319134901 (Sun Mar 19 14:49:01 2017)
+; Activate: 20170319134901 (Sun Mar 19 14:49:01 2017)
+. IN DNSKEY 257 3 8 AwEAAbgyvYQ2Vlff/inpv4NZLlIk2+l1sL0JoeOUlWHZ3eeWXZKxQJak QIXyGi8xsuANzu/YStLp31SfU/Fj4piUciqA+U74Lot1S/jcM7/1eczh 69YqGUAPZkreZ3z2DpWzBN4lgPR/w0OvTada3D42uV2bzuSK/nXMiMpZ vP1vZ1ykNRmbksTzA+HnrefRi2yuMSUqMHbtfbfFwqVTQ1ddVwSK7qIJ 02jo95YJUSZDPUUQlczIsFsa7Zxn6gQZl+iaRuDY6nLxxStYYlcqZhVA G5U8Dx4IznQ0FkEJp9RXtv5rmtClcQpudCl1gE0GC/W+TTUAa3hD597f onH+s/OfdCE=
diff --git a/tests/integration/deckard/sets/resolver/val_wild_pos_multi/K.+008+41524.private b/tests/integration/deckard/sets/resolver/val_wild_pos_multi/K.+008+41524.private
new file mode 100644
index 0000000..2811b2b
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_wild_pos_multi/K.+008+41524.private
@@ -0,0 +1,13 @@
+Private-key-format: v1.3
+Algorithm: 8 (RSASHA256)
+Modulus: uDK9hDZWV9/+Kem/g1kuUiTb6XWwvQmh45SVYdnd55ZdkrFAlqRAhfIaLzGy4A3O79hK0unfVJ9T8WPimJRyKoD5Tvgui3VL+Nwzv/V5zOHr1ioZQA9mSt5nfPYOlbME3iWA9H/DQ69Np1rcPja5XZvO5Ir+dcyIylm8/W9nXKQ1GZuSxPMD4eet59GLbK4xJSowdu19t8XCpVNDV11XBIruognTaOj3lglRJkM9RRCVzMiwWxrtnGfqBBmX6JpG4NjqcvHFK1hiVypmFUAblTwPHgjOdDQWQQmn1Fe2/mua0KVxCm50KXWATQYL9b5NNQBreEPn3t+icf6z8590IQ==
+PublicExponent: AQAB
+PrivateExponent: HEH8fPnxCQ4d6cQoUzgtOQDak9gwQu/lXAqBWD+aIVsaA9UZeYK9O09G4RKYxHKZ2oWuBOlID61ZrWCLdKjhUs/yb0D3swFNpGHztnEsPFg0W+idcwxpvvabnboJxsFt776FJ/0psYqFOTVhMFIo4clzVfBU1TGJkrFtotuiWb28eZ85pFJiQUR+agbWjstXaXMmXeSRPYAueBD/bo6u5DqDagH1fzNxhKUxC9nhpeoIj1AtH4bJuO0v4oxq6yrcGEn6Jus5wku9goLCJqykfRikYwQzyUCP/AQMVC++qiQJ89A66psa0F2lcmps5/2skBEM9QB5Vv12jbIw6j6TeQ==
+Prime1: 6AkeSU4ZcvsxDem0IJLhC4zYEpCN+ZAr/757pkv6oIfQv2PhJmXQ1bmiCsYD/uoRDUFNtNGOFjIlmnGHKIefvCSHlZRxCDDzDAvZ6IthkMQEzDcSQkZIpprCt7QMl1Kz2gjEs84+DNxozB54UbEYG908PrF7CF7ix3RHHEDcX6M=
+Prime2: yzjUYzFjM52Q5cwtMHL8gHnacpzQSUidYLZF+xA4dYjc0pjSRMo87sfp2r6wdm3ZOcfOy0SZl4LvO0Kcrz/VB2v0yiBqanDcM3SBg6n7lz/l5Xaoj5rw9JmYj981nJe8vcerZvJl8MLT00uikr1gqoABxKIvHyt7kYcYB2qqSWs=
+Exponent1: Sjzgm8OJEOidQT5Miz9zESb22rm1MuuVqDVhiks03LeXaiSinI5mynqiBaBlFuH8oqkKG5gQRbm1njxEags6aA+n8YuUvnIq0OfZyDUP+ik8/7l+9gVWqTdKpUvN23xyXof/pyeNYsACJ4x4Imrus7uM0uIl4v+4vufM+JUn7NE=
+Exponent2: HUmqakVC27x4lnWviYz40Pc+wUfSSM17SOXb/gvfZyj7UiqOGzXeRDdxf4H94oOAS/B84BSZ4hkPq0W1WRhk9jXbyImVbJOpWI0Q4U3NIYYm9sP8FP4qfcXpE8sCafgAToWJMUP75w/dAVWkL2u1k7zxBEqvadmVbGrAzsjTk9M=
+Coefficient: ms+SW3tNI975ejCbI1vIB31uUqVfvVvxv7eWtzJEdyxBVQKb0aQnXaTMdXiESNc+H5HMau3lbDOw5IcQkp79fKdxLt3SjMYPdnQmBWg7StY3fV1FJcPEEJeFQjWXxioY8rdvMUTMk1FfjxlllBkCyMWuIE4cbRTNdcq76ozM60g=
+Created: 20170319134901
+Publish: 20170319134901
+Activate: 20170319134901
diff --git a/tests/integration/deckard/sets/resolver/val_wild_pos_multi/dsset-. b/tests/integration/deckard/sets/resolver/val_wild_pos_multi/dsset-.
new file mode 100644
index 0000000..6c9d3b7
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_wild_pos_multi/dsset-.
@@ -0,0 +1,2 @@
+. IN DS 41524 8 1 C042815790A1423F03578E561C4DC09BF9BEC5C0
+. IN DS 41524 8 2 5175938255D97A88F9D16A5A46ED3AE373441DF5058C1666D953005D A6BD57F3
diff --git a/tests/integration/deckard/sets/resolver/val_wild_pos_multi/root.zone b/tests/integration/deckard/sets/resolver/val_wild_pos_multi/root.zone
new file mode 100644
index 0000000..b69eb42
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_wild_pos_multi/root.zone
@@ -0,0 +1,10 @@
+. 3600 IN SOA . . 0 0 0 0 0
+. 3600 IN NS ns.
+
+*. 3600 IN A 10.1.1.1
+*. 3600 IN A 10.2.2.2
+*. 3600 IN A 10.3.3.3
+
+*. 3600 IN AAAA ::1
+*. 3600 IN AAAA ::2
+*. 3600 IN AAAA ::3
diff --git a/tests/integration/deckard/sets/resolver/val_wild_pos_multi/root.zone.signed b/tests/integration/deckard/sets/resolver/val_wild_pos_multi/root.zone.signed
new file mode 100644
index 0000000..ddb5864
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/val_wild_pos_multi/root.zone.signed
@@ -0,0 +1,114 @@
+; File written on Wed Apr 19 17:18:13 2017
+; dnssec_signzone version 9.10.4-P6-RedHat-9.10.4-4.P6.fc25
+. 3600 IN SOA . . (
+ 0 ; serial
+ 0 ; refresh (0 seconds)
+ 0 ; retry (0 seconds)
+ 0 ; expire (0 seconds)
+ 0 ; minimum (0 seconds)
+ )
+ 3600 RRSIG SOA 8 0 3600 (
+ 20170519141813 20170419141813 41524 .
+ iuxo0/dNl+zFK1i7CnGR0ssx39IkWTkqXWOc
+ bm8ZrN/vnV2lt7tkRctV4MmoCiIFfTd4R+jW
+ orVlV0eu1FVmm8cvEAPJzZKk79hvS7DrL5cv
+ wlDAOXSS8J2ram3h+eJH2FCHkSKPkqJUlpXP
+ sQbnfVFf4bFTYi5rXE+NkpijqhACwhHb8HZN
+ ay1/L/njW2DvnY40rgoArxKoJyw0lDgYWd2Y
+ YsqHjDGpDitdeam33tEdWmn8N2oSOXOaRZ3M
+ jDL0PL0uOanJ2wiLFs33MlGo/Y1qncGgLBSi
+ LFEOhpYgPP3CRu7QZxjQjinwq+tRRhwaqyfP
+ PliHO22NblwL7tp8qg== )
+ 3600 NS ns.
+ 3600 RRSIG NS 8 0 3600 (
+ 20170519141813 20170419141813 41524 .
+ mta7nYjyM8qecNDgcuzyosmO6pwXQOJxb+oX
+ hF8yElB1FiVWwPhsxnrGlME3PhCRj9+tvE8B
+ MTW0Js42DtJ5GvD/FJ2RBYFTwXrydffIQafR
+ No3Gxsz0bX8+aIEVzIrTIXe8bMWk5bs9E1Yu
+ c6OKgqteAzfrXi5my8cfro5Bjc5m/Qo/tWbX
+ auPCv/M2N5a9oey1z13msZSpR+/XfCGH0v1e
+ rIZje/A/5PFXXTIVzKsIzazErd9OnbEI6280
+ S56ctV7SbjoDgHyM7XuyVYWzkdhN/evOwu0l
+ YuObCxtgkUR56Ba5Ii3Su4bp0+JNGf/N3yLh
+ gVF7DjoWkfvnlNIXoQ== )
+ 0 NSEC *. NS SOA RRSIG NSEC DNSKEY
+ 0 RRSIG NSEC 8 0 0 (
+ 20170519141813 20170419141813 41524 .
+ qLniiG3AKNGlsOwSCzlPrk08E6beDttOa5Aj
+ phfR90H2mt8uSqxlQD/5oWJVGqDrjAnOvjVO
+ WXDxH+zsWAWI+01ZcAxvd59+7e66qAwRqKmC
+ c/H2m4/2KzbHHZd7kZ1NAPX+dVtwuc7qM0jG
+ mc89GogQaxmRv2em1iA8h0PLCM7Vk4B/bDo3
+ xRMTtdjmUM6DYIeyAQfLxoAAIsXCoAIvXYWt
+ CQDugjWMrHvNMdMjEYzLU+RO7NHnlDKgaXzk
+ IckYe0TL0+FrP65a2lVfOkcUzTjRV6jajWeY
+ LjoaiWu+6IO5Zpm+XnTeIz496xX1RhsSKGuB
+ /NAIdfkWvJ7MGsd4/Q== )
+ 3600 DNSKEY 257 3 8 (
+ AwEAAbgyvYQ2Vlff/inpv4NZLlIk2+l1sL0J
+ oeOUlWHZ3eeWXZKxQJakQIXyGi8xsuANzu/Y
+ StLp31SfU/Fj4piUciqA+U74Lot1S/jcM7/1
+ eczh69YqGUAPZkreZ3z2DpWzBN4lgPR/w0Ov
+ Tada3D42uV2bzuSK/nXMiMpZvP1vZ1ykNRmb
+ ksTzA+HnrefRi2yuMSUqMHbtfbfFwqVTQ1dd
+ VwSK7qIJ02jo95YJUSZDPUUQlczIsFsa7Zxn
+ 6gQZl+iaRuDY6nLxxStYYlcqZhVAG5U8Dx4I
+ znQ0FkEJp9RXtv5rmtClcQpudCl1gE0GC/W+
+ TTUAa3hD597fonH+s/OfdCE=
+ ) ; KSK; alg = RSASHA256 ; key id = 41524
+ 3600 RRSIG DNSKEY 8 0 3600 (
+ 20170519141813 20170419141813 41524 .
+ jm0WoZl7B17L5OMiI4j7EwUXuoZVDuvybewY
+ Z3NfQQOK0zDsnQKZFkG4unV5gp4ORQ5OD/Kt
+ fK9A5KYqEWewqgQcWiJ+PvsyAibVEqpAqrWq
+ OIsnBYJgVzhzFyA1hQOb5j4cpYGCGe5znHoF
+ eeTdIc/ZykCAxFLUMzmHu/ivIuhni6z3gdtS
+ GqVY2eTjWXqyv6ImMZJeL/34+/cKctS7ZCwe
+ rzxmnoDAzS3cUql+hL7Oh7YUWDVfcUkDKqXX
+ 5KMcvjPQhqSERyewQN3n2F9Z4Dxf41TYL2TF
+ /cG6idUt2gLaA+l/+2+CoCwsStzug7bK9mmA
+ cXkidI+IZup7KQ/WcA== )
+*. 3600 IN A 10.1.1.1
+ 3600 IN A 10.2.2.2
+ 3600 IN A 10.3.3.3
+ 3600 RRSIG A 8 0 3600 (
+ 20170519141813 20170419141813 41524 .
+ PK9xvQqB3OB1o/nW7IOlIeZT35lHBujkK9Nq
+ aehnTX7CiYuwe5IpXY7EsGEt6ZtEB+wS54tY
+ UZ9pDyAADLwhQmYHP2jASiY/ZuQj3IL8uymL
+ A/D5xnxfHnsyzqShYEjTTK9+6cL0RQ4t2Fia
+ XkwOQb4+i9wcGTu9zJ/L/WRNzKRqsyQ/fxQB
+ gqDDyBVn47ZIjH0DBDBML7P58dH894bDiLNu
+ 2RwEntgs+bwzUrPYlOA2Le2xNlc8qqzNktWe
+ fr+6OEjn5qXnNccBkbASN9FBV8CJ7Bfl6KKT
+ CRjKv3a/y/mqYOR6pIrw97QYXmjgQvjT4HLy
+ cfu8DpZEweBX9vg5Ag== )
+ 3600 AAAA ::1
+ 3600 AAAA ::2
+ 3600 AAAA ::3
+ 3600 RRSIG AAAA 8 0 3600 (
+ 20170519141813 20170419141813 41524 .
+ q256A5GuT3+3jMaDXhh7Z2w/lPYNxtSLamf4
+ TPcAuIDm41Fnj4M1OU63ViuoBM2GNP512YZx
+ L9wjkTXVjbQJ3nfIT4D7vRdtNpcA48lceYRs
+ lBOPqxuFLxRNbW+a1iLA28IiouecsmJIpfLN
+ fCR9OAMKnuFbdkDHNDYEVyKtTRDuqANfj9s8
+ tEH5SLwoycAtLxP5nBVPqOCgNJAg7j+qNXcA
+ /I+dhqBfxy9eMNmhMbDN09x0+k63vJcdhsgj
+ 1sxAqvnq973r+uM7T1WDBjcn71CSfDP3kplH
+ xM4vGpmDvJ5MkStLQ/+kqGNVb9qUl65gBids
+ A3SYqkZ3KtxTBr/61w== )
+ 0 NSEC . A AAAA RRSIG NSEC
+ 0 RRSIG NSEC 8 0 0 (
+ 20170519141813 20170419141813 41524 .
+ FgFsXY4fdEQZlv5xd2WQuH6b0YIuDoOydNXv
+ iOPAoK/FYucZPqPxLAGsC1bQQ82YlPy1SU1H
+ MbggjMNT224sllm0WY0P1PjkPN8XkBbFRZtK
+ l6YO6Jyav58WZCjDLsRfKYMzFPXe7GqvtB61
+ YkvCf6p/sqxOAuWKqSkHIlyJVUNETyfYKlp5
+ x7CDZiCnPgAppZUEv0kEQKmTCzTgC+ctj2S2
+ 5eTAgsDb8R0FCb5ks+AcvWZZyNTbwvstaz92
+ EqSOCCWkGSDF3gp2Pv5SI+3xUeTyc/NuJ+f3
+ 66C5w0MsaW+9oXo2zy/aOFULzwFtdH8Zizqz
+ wwNdGS1sqvuw1UaqkA== )
diff --git a/tests/integration/deckard/sets/resolver/world_cz_lidovky_www.rpl b/tests/integration/deckard/sets/resolver/world_cz_lidovky_www.rpl
new file mode 100644
index 0000000..d826dbf
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/world_cz_lidovky_www.rpl
@@ -0,0 +1,933 @@
+; FIXME: This uses built-in root hints, if they change this will break forever
+val-override-date: "20170228130000"
+; workarround to avoid regenerating test for the new server selection:
+domain-insecure: net.
+trust-anchor: ". 172800 IN DS 19036 8 2 49aac11d7b6f6446702e54a1607371607a1a41855200fd2ce1cdde32f24e8fb5"
+query-minimization: off
+CONFIG_END
+
+SCENARIO_BEGIN www.lidovky.cz CNAME c23.idnes.cz points from signed domain into unsigned domain hosted on the same server. The result must be NOERROR without AD flag.
+
+;root
+RANGE_BEGIN 0 100
+ ADDRESS 2001:dc3::35
+ ADDRESS 198.41.0.4
+ ADDRESS 192.228.79.201
+ ADDRESS 192.33.4.12
+ ADDRESS 199.7.91.13
+ ADDRESS 192.203.230.10
+ ADDRESS 192.5.5.241
+ ADDRESS 192.112.36.4
+ ADDRESS 198.97.190.53
+ ADDRESS 192.36.148.17
+ ADDRESS 192.58.128.30
+ ADDRESS 193.0.14.129
+ ADDRESS 199.7.83.42
+ ADDRESS 202.12.27.33
+ ADDRESS 2001:503:ba3e::2:30
+ ADDRESS 2001:500:84::b
+ ADDRESS 2001:500:2::c
+ ADDRESS 2001:500:2d::d
+ ADDRESS 2001:500:a8::e
+ ADDRESS 2001:500:2f::f
+ ADDRESS 2001:500:12::d0d
+ ADDRESS 2001:500:1::53
+ ADDRESS 2001:7fe::53
+ ADDRESS 2001:503:c27::2:30
+ ADDRESS 2001:7fd::1
+ ADDRESS 2001:500:9f::42
+ ADDRESS 2001:dc3::35
+
+ ENTRY_BEGIN
+ MATCH opcode qtype qname
+ ADJUST copy_id
+ REPLY QR AA NOERROR
+ SECTION QUESTION
+ k.root-servers.net IN A
+ SECTION ANSWER
+ k.root-servers.net 3600000 IN A 193.0.14.129
+ ENTRY_END
+
+ ENTRY_BEGIN
+ MATCH opcode qtype qname
+ ADJUST copy_id
+ REPLY QR AA NOERROR
+ SECTION QUESTION
+ k.root-servers.net IN AAAA
+ SECTION ANSWER
+ k.root-servers.net 3600000 IN AAAA 2001:7fd::1
+ ENTRY_END
+
+ ENTRY_BEGIN
+ MATCH opcode qtype qname
+ ADJUST copy_id
+ REPLY QR AA RD DO NOERROR
+ SECTION QUESTION
+ . IN DS
+ SECTION AUTHORITY
+ . 86400 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2017022701 1800 900 604800 86400
+ . 86400 IN RRSIG SOA 8 0 86400 20170312170000 20170227160000 61045 . GhyRFKg8xu/asiFmIMifBOFUeJlL++ncqDoBLbYoviben3WNrdU7vJxZ Cm3EZ8HEYr2gFFkupaHBZt+P6GdX9lU8aw7yOZ8ZXV48S209Jo3PkHxH iVOtaC7QzkJPiZUgh06MuWgQoeNJSVqGTCy+TlTlMLqGndNcpT0rkX7H 0gCcuaZcBv0nqEPKqZeq8XFVIfiaUCKz/kkkO0vgP9euN+WT+68hng4F oIQ0eAPIUL6XBW2uWubWS2Yd8C+g/++qeLnte7QYF+9By5HuN6fXskba 0uph3gzjWArn+SYQhEWyqbS6wb0LloAawt9LW7neJYOMFhlU1AOScGjn e8rfBw==
+ . 86400 IN NSEC aaa. NS SOA RRSIG NSEC DNSKEY
+ . 86400 IN RRSIG NSEC 8 0 86400 20170312170000 20170227160000 61045 . MLiCUaeASll0V1x0imORnQodzd/6LuDpa8XfebmNE7eGMda62HCK9kB2 I5Yvcc6naw1nzJVSVNIjDQyAKHgSWy457vwvWbEdCuD5XS8A1/drP13x pfP91XG3qPswx3u1i4cLSTO5VJi1lup1Qr1UrN54kNbRp2sS65VKXOH4 4I6bwA1CBOmU6EHlyI2nymZDqCRaTdWjyoYSZ1zkucSjEgn8GtyniNiS p7AfNLnnJ6poKSCcOj2hSQTb58i7B7TJt/JQWb6ko12rcSEVxZljhqHc XzR+i8Bgfpj9ha83tcZwDFQQy4mKjSkboOEoRe8Z5qKIb5DF0wn0vB+M LClQJg==
+ ENTRY_END
+
+ ENTRY_BEGIN
+ MATCH opcode qtype qname
+ ADJUST copy_id
+ REPLY QR AA RD DO NOERROR
+ SECTION QUESTION
+ . IN NS
+ SECTION ANSWER
+ . 518400 IN NS m.root-servers.net.
+ . 518400 IN NS k.root-servers.net.
+ . 518400 IN NS a.root-servers.net.
+ . 518400 IN NS l.root-servers.net.
+ . 518400 IN NS j.root-servers.net.
+ . 518400 IN NS i.root-servers.net.
+ . 518400 IN NS e.root-servers.net.
+ . 518400 IN NS b.root-servers.net.
+ . 518400 IN NS h.root-servers.net.
+ . 518400 IN NS d.root-servers.net.
+ . 518400 IN NS c.root-servers.net.
+ . 518400 IN NS f.root-servers.net.
+ . 518400 IN NS g.root-servers.net.
+ . 518400 IN RRSIG NS 8 0 518400 20170312170000 20170227160000 61045 . iqk4z3W6lGfSgvbPGl4JPVDca+21mXayctqY0FO1a9YhCSxLQGsV/0eK IfYOGHMCBr2szIactoznQgFybjNG/I5bKo+EU4U0tNNVwrUHWTMsAraQ yIS/efPZyKAHSzKZjlcRVOFbFPA/DWp6JzMhfXaBYMLcsA8ZT/CwCnxF a7wInMupWskMwXXhTgGci+PJVKm+TK5hEtYYnb3Ny2lxoWtTPJuZufM9 1xg2YXs6njo1gKzj3zaTwpndeBbYN78ZfETmPsjyr7X144v9qe7qygCO dTjy+cly1JG1prI9yHaU5zJk3X9VcvWWRR3ACQOFfzthFqyEoHjQmEBe XQHCRg==
+ SECTION ADDITIONAL
+ a.root-servers.net. 3600000 IN A 198.41.0.4
+ b.root-servers.net. 3600000 IN A 192.228.79.201
+ c.root-servers.net. 3600000 IN A 192.33.4.12
+ d.root-servers.net. 3600000 IN A 199.7.91.13
+ e.root-servers.net. 3600000 IN A 192.203.230.10
+ f.root-servers.net. 3600000 IN A 192.5.5.241
+ g.root-servers.net. 3600000 IN A 192.112.36.4
+ h.root-servers.net. 3600000 IN A 198.97.190.53
+ i.root-servers.net. 3600000 IN A 192.36.148.17
+ j.root-servers.net. 3600000 IN A 192.58.128.30
+ k.root-servers.net. 3600000 IN A 193.0.14.129
+ l.root-servers.net. 3600000 IN A 199.7.83.42
+ m.root-servers.net. 3600000 IN A 202.12.27.33
+ a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30
+ b.root-servers.net. 3600000 IN AAAA 2001:500:84::b
+ c.root-servers.net. 3600000 IN AAAA 2001:500:2::c
+ d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d
+ e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e
+ f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f
+ g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d
+ h.root-servers.net. 3600000 IN AAAA 2001:500:1::53
+ i.root-servers.net. 3600000 IN AAAA 2001:7fe::53
+ j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30
+ k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+ l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42
+ m.root-servers.net. 3600000 IN AAAA 2001:dc3::35
+ ENTRY_END
+
+ ENTRY_BEGIN
+ MATCH opcode qtype qname
+ ADJUST copy_id
+ REPLY QR AA RD DO NOERROR
+ SECTION QUESTION
+ . IN DNSKEY
+ SECTION ANSWER
+ . 172800 IN DNSKEY 256 3 8 AwEAAYvgWbYkpeGgdPKaKTJU3Us4YSTRgy7+dzvfArIhi2tKoZ/WR1Df w883SOU6Uw7tpVRkLarN0oIMK/xbOBD1DcXnyfElBwKsz4sVVWmfyr/x +igD/UjrcJ5zEBUrUmVtHyjar7ccaVc1/3ntkhZjI1hcungAlOhPhHlk MeX+5Azx6GdX//An5OgrdyH3o/JmOPMDX1mt806JI/hf0EwAp1pBwo5e 8SrSuR1tD3sgNjr6IzCdrKSgqi92z49zcdis3EaY199WFW60DCS7ydu+ +T5Xa+GyOw1quagwf/JUC/mEpeBQYWrnpkBbpDB3sy4+P2i8iCvavehb RyVm9U0MlIc=
+ . 172800 IN DNSKEY 257 3 8 AwEAAagAIKlVZrpC6Ia7gEzahOR+9W29euxhJhVVLOyQbSEW0O8gcCjF FVQUTf6v58fLjwBd0YI0EzrAcQqBGCzh/RStIoO8g0NfnfL2MTJRkxoX bfDaUeVPQuYEhg37NZWAJQ9VnMVDxP/VHL496M/QZxkjf5/Efucp2gaD X6RS6CXpoY68LsvPVjR0ZSwzz1apAzvN9dlzEheX7ICJBBtuA6G3LQpz W5hOA2hzCTMjJPJ8LbqF6dsV6DoBQzgul0sGIcGOYl7OyQdXfZ57relS Qageu+ipAdTTJ25AsRTAoub8ONGcLmqrAmRLKBP1dfwhYB4N7knNnulq QxA+Uk1ihz0=
+ . 172800 IN RRSIG DNSKEY 8 0 172800 20170313000000 20170220000000 19036 . Dgzxpg2Lr39HXuHwuJWYCGySxsm92RY8TRuSOstPVcHc7we0d4pW7Znt 33j9fzrxdvoVFAvqSioilVKiOY49M8N+sXcsfTK3cnh7ijTA7suXd4ht TClLN7Dn+ZAjhoyjLm5hf7P/jL0K9KKcOqEqS+uqX3W2WeCvUwT3BY6A t2r+pKSVnoX0uFWJX+mmCh4veYW3eoBzAqwAVbCE5hl2tVbf/vzpa8eW kHegVmm5smKzK2ciYOqExl3FtLgf6dp+HTpruS2oN1JPxm4f1IZhVwT0 pSEu8OUNOV8WSbLn3P9aUpq894Tf1i0/AEtFtx2tRCdw3lSKOugfneo0 PYo1JQ==
+ ENTRY_END
+
+ ENTRY_BEGIN
+ MATCH opcode qtype qname
+ ADJUST copy_id
+ REPLY QR RD DO NOERROR
+ SECTION QUESTION
+ cz. IN DS
+ SECTION ANSWER
+ cz. 86400 IN DS 54576 10 2 397E50C85EDE9CDE33F363A9E66FD1B216D788F8DD438A57A423A386 869C8F06
+ cz. 86400 IN RRSIG DS 8 1 86400 20170312170000 20170227160000 61045 . irp/lUXakeZMwVjkZQOOt6xAB2Fcglo7nxmUkHBFjsB5lp61Pg6eyt8u xvGrTdv4mv6PH5q0c7bfKo0Ngtedbq8gZ6VHXfcKUU7vP5BUmePWPyvf khKcafAO7D2wIw9gKxPB0syd3woUP7PlQ1Rg/rUMwDnEXtS7zEqzrVbb VkjdqvdgLUsInAc9zdP72qRp9cJhuoRm0nco1uo2ZLUC04poGxSNzXTw hKhngqHDTqD1nr/Wnq7uXtmLyvFelICSpSHmkrCxnou7EtPybC+W+fna f8o7FebZBnB71t5d8s2kxlb+KrWXUMv8VOdZdZTQTN8M5LeKSBL7RnXM 1FbCiQ==
+ ENTRY_END
+
+ ENTRY_BEGIN
+ MATCH opcode subdomain
+ ADJUST copy_id copy_query
+ REPLY QR RD DO NOERROR
+ SECTION QUESTION
+ CZ. IN NS
+ SECTION AUTHORITY
+ cz. 172800 IN NS b.ns.nic.cz.
+ cz. 172800 IN NS a.ns.nic.cz.
+ cz. 172800 IN NS c.ns.nic.cz.
+ cz. 172800 IN NS d.ns.nic.cz.
+ cz. 86400 IN DS 54576 10 2 397E50C85EDE9CDE33F363A9E66FD1B216D788F8DD438A57A423A386 869C8F06
+ cz. 86400 IN RRSIG DS 8 1 86400 20170312170000 20170227160000 61045 . irp/lUXakeZMwVjkZQOOt6xAB2Fcglo7nxmUkHBFjsB5lp61Pg6eyt8u xvGrTdv4mv6PH5q0c7bfKo0Ngtedbq8gZ6VHXfcKUU7vP5BUmePWPyvf khKcafAO7D2wIw9gKxPB0syd3woUP7PlQ1Rg/rUMwDnEXtS7zEqzrVbb VkjdqvdgLUsInAc9zdP72qRp9cJhuoRm0nco1uo2ZLUC04poGxSNzXTw hKhngqHDTqD1nr/Wnq7uXtmLyvFelICSpSHmkrCxnou7EtPybC+W+fna f8o7FebZBnB71t5d8s2kxlb+KrWXUMv8VOdZdZTQTN8M5LeKSBL7RnXM 1FbCiQ==
+ SECTION ADDITIONAL
+ a.ns.nic.cz. 155678 IN A 194.0.12.1
+ b.ns.nic.cz. 155678 IN A 194.0.13.1
+ c.ns.nic.cz. 153044 IN A 194.0.14.1
+ d.ns.nic.cz. 153044 IN A 193.29.206.1
+ a.ns.nic.cz. 153051 IN AAAA 2001:678:f::1
+ b.ns.nic.cz. 153051 IN AAAA 2001:678:10::1
+ c.ns.nic.cz. 155678 IN AAAA 2001:678:11::1
+ d.ns.nic.cz. 155678 IN AAAA 2001:678:1::1
+ ENTRY_END
+
+
+
+ ENTRY_BEGIN
+ MATCH opcode qtype qname
+ ADJUST copy_id
+ REPLY QR RD DO NOERROR
+ SECTION QUESTION
+ net. IN DS
+ SECTION ANSWER
+ net. 86400 IN DS 35886 8 2 7862B27F5F516EBE19680444D4CE5E762981931842C465F00236401D 8BD973EE
+ net. 86400 IN RRSIG DS 8 1 86400 20170312170000 20170227160000 61045 . bRSoCpmN/6LhmSB7i68N0zO08WwVikjm6HhOyZMhyjF4sfAaDoeTMs5E XjflCZMly1SP8CwkK6Wz6Ozb8nMUHEsYOhASVBkYC/ImBpqIV5LxaCbW 4L7g5Mwam0MBZb4hybI7JUyuiRONVy3YYk+eUvyf4/flu3Cl14a36LYv 2In/ECg9sV8cMOrYs722vigvzH5eHLIZTOhGBE2//uH8pw1YnMW9sYRj f5algDGge4hZvi0ieQyzfT3UqmQEmZZCz+vdlPtgKqIj6+I+V+SZOB2d aBkb/0NrWIx+iE+fqP6jx7I2HCobVnYUvJjL/t6O1shC4mxcDghLLUpf fSnEag==
+ ENTRY_END
+
+ ENTRY_BEGIN
+ MATCH opcode subdomain
+ ADJUST copy_id copy_query
+ REPLY QR RD DO NOERROR
+ SECTION QUESTION
+ net. IN NS
+ SECTION AUTHORITY
+ net. 172800 IN NS j.gtld-servers.net.
+ net. 172800 IN NS e.gtld-servers.net.
+ net. 172800 IN NS c.gtld-servers.net.
+ net. 172800 IN NS m.gtld-servers.net.
+ net. 172800 IN NS d.gtld-servers.net.
+ net. 172800 IN NS i.gtld-servers.net.
+ net. 172800 IN NS a.gtld-servers.net.
+ net. 172800 IN NS g.gtld-servers.net.
+ net. 172800 IN NS h.gtld-servers.net.
+ net. 172800 IN NS b.gtld-servers.net.
+ net. 172800 IN NS k.gtld-servers.net.
+ net. 172800 IN NS f.gtld-servers.net.
+ net. 172800 IN NS l.gtld-servers.net.
+ net. 86400 IN DS 35886 8 2 7862B27F5F516EBE19680444D4CE5E762981931842C465F00236401D 8BD973EE
+ net. 86400 IN RRSIG DS 8 1 86400 20170312170000 20170227160000 61045 . bRSoCpmN/6LhmSB7i68N0zO08WwVikjm6HhOyZMhyjF4sfAaDoeTMs5E XjflCZMly1SP8CwkK6Wz6Ozb8nMUHEsYOhASVBkYC/ImBpqIV5LxaCbW 4L7g5Mwam0MBZb4hybI7JUyuiRONVy3YYk+eUvyf4/flu3Cl14a36LYv 2In/ECg9sV8cMOrYs722vigvzH5eHLIZTOhGBE2//uH8pw1YnMW9sYRj f5algDGge4hZvi0ieQyzfT3UqmQEmZZCz+vdlPtgKqIj6+I+V+SZOB2d aBkb/0NrWIx+iE+fqP6jx7I2HCobVnYUvJjL/t6O1shC4mxcDghLLUpf fSnEag==
+ SECTION ADDITIONAL
+ a.gtld-servers.net. 172800 IN A 192.5.6.30
+ b.gtld-servers.net. 172800 IN A 192.33.14.30
+ c.gtld-servers.net. 172800 IN A 192.26.92.30
+ d.gtld-servers.net. 172800 IN A 192.31.80.30
+ e.gtld-servers.net. 172800 IN A 192.12.94.30
+ f.gtld-servers.net. 172800 IN A 192.35.51.30
+ g.gtld-servers.net. 172800 IN A 192.42.93.30
+ h.gtld-servers.net. 172800 IN A 192.54.112.30
+ i.gtld-servers.net. 172800 IN A 192.43.172.30
+ j.gtld-servers.net. 172800 IN A 192.48.79.30
+ k.gtld-servers.net. 172800 IN A 192.52.178.30
+ l.gtld-servers.net. 172800 IN A 192.41.162.30
+ m.gtld-servers.net. 172800 IN A 192.55.83.30
+ a.gtld-servers.net. 172800 IN AAAA 2001:503:a83e::2:30
+ b.gtld-servers.net. 172800 IN AAAA 2001:503:231d::2:30
+ ENTRY_END
+
+
+RANGE_END
+
+;cz
+RANGE_BEGIN 0 100
+ ADDRESS 194.0.12.1
+ ADDRESS 194.0.13.1
+ ADDRESS 194.0.14.1
+ ADDRESS 193.29.206.1
+ ADDRESS 2001:678:f::1
+ ADDRESS 2001:678:10::1
+ ADDRESS 2001:678:11::1
+ ADDRESS 2001:678:1::1
+
+ ENTRY_BEGIN
+ MATCH opcode qtype qname
+ ADJUST copy_id
+ REPLY QR RD DO NOERROR
+ SECTION QUESTION
+ nic.cz. IN DS
+ SECTION ANSWER
+ nic.cz. 14400 IN DS 61281 13 2 4104D40C8FE2030BF7A09A199FCF37B36F7EC8DDD16F5A84F2E61C24 8D3AFD0F
+ nic.cz. 14400 IN RRSIG DS 10 2 14400 20170312221837 20170228130956 58211 cz. LKiLo/EqBTsv1e6s8p5UfN/qZfd3Dnf5XGO11vW2pELybdmmpD5clR/v mz+cc4zxLiQAxDnBpdUPAPdxcPlILa5mjMfJy2ExsQOZhcbIUInRala6 GhBfGy3bnniJkJCu7sAIsf+HyDM92pFSql67ErS0ROERBhSRVbfunEBy FCo=
+ ENTRY_END
+
+ ENTRY_BEGIN
+ MATCH opcode qtype qname
+ ADJUST copy_id
+ REPLY QR RD DO AA NOERROR
+ SECTION QUESTION
+ a.ns.nic.cz. IN A
+ SECTION ANSWER
+ a.ns.nic.cz. 1800 IN A 194.0.12.1
+ a.ns.nic.cz. 1800 IN RRSIG A 13 4 1800 20170314061428 20170228072511 16836 nic.cz. rJsAWa5cYGooRzu5+jRW5m4ebYHPkHRBwrLT5P7lIkT5VkcoIRYMcdYf gr+pXJFM9IduSZJXfomumKyOYHts7Q==
+ ENTRY_END
+
+ ENTRY_BEGIN
+ MATCH opcode qtype qname
+ ADJUST copy_id
+ REPLY QR RD DO AA NOERROR
+ SECTION QUESTION
+ b.ns.nic.cz. IN A
+ SECTION ANSWER
+ b.ns.nic.cz. 1800 IN A 194.0.13.1
+ b.ns.nic.cz. 1800 IN RRSIG A 13 4 1800 20170314044412 20170228072511 16836 nic.cz. 6dOVqiXZgfp1fltylhOAYvfILWCGu61cpabseUNTmb20TZR1GuI5ueTS lmYa93o46M+01ATfrkwBWZC065G8yg==
+ ENTRY_END
+
+ ENTRY_BEGIN
+ MATCH opcode qtype qname
+ ADJUST copy_id
+ REPLY QR RD DO AA NOERROR
+ SECTION QUESTION
+ c.ns.nic.cz. IN A
+ SECTION ANSWER
+ c.ns.nic.cz. 1800 IN A 194.0.14.1
+ c.ns.nic.cz. 1800 IN RRSIG A 13 4 1800 20170314015427 20170228072511 16836 nic.cz. 824yJyP2dWJ7phi63r1/24v0SbzU9FVi7b8IkXIrQ+3aCTyXKugE8l8C qLz6qwulzu2aG+8SyfvenXDSySqiqQ==
+ ENTRY_END
+
+ ENTRY_BEGIN
+ MATCH opcode qtype qname
+ ADJUST copy_id
+ REPLY QR RD DO AA NOERROR
+ SECTION QUESTION
+ d.ns.nic.cz. IN A
+ SECTION ANSWER
+ d.ns.nic.cz. 1800 IN A 193.29.206.1
+ d.ns.nic.cz. 1800 IN RRSIG A 13 4 1800 20170313233915 20170228072511 16836 nic.cz. KAlDHStrGzdtoBe9epn87lsggg6vVvHPGMPv/njWSTns7BX0//fTxfOc iOXdutsQhq/8Z2o87pKzE2F9FbE6Hw==
+ ENTRY_END
+
+ ENTRY_BEGIN
+ MATCH opcode qtype qname
+ ADJUST copy_id
+ REPLY QR RD DO AA NOERROR
+ SECTION QUESTION
+ a.ns.nic.cz. IN AAAA
+ SECTION ANSWER
+ a.ns.nic.cz. 1800 IN AAAA 2001:678:f::1
+ a.ns.nic.cz. 1800 IN RRSIG AAAA 13 4 1800 20170313215345 20170228072511 16836 nic.cz. GMmWVeCiIzq2kt4VmsDXGSaAWMtDB78+Yz7qgEqu5C1PAUUBQo4o5lU/ igGhIJHk2BSljJxjaL+LlnW3uOeCDQ==
+ ENTRY_END
+
+ ENTRY_BEGIN
+ MATCH opcode qtype qname
+ ADJUST copy_id
+ REPLY QR RD DO AA NOERROR
+ SECTION QUESTION
+ b.ns.nic.cz. IN AAAA
+ SECTION ANSWER
+ b.ns.nic.cz. 1800 IN AAAA 2001:678:10::1
+ b.ns.nic.cz. 1800 IN RRSIG AAAA 13 4 1800 20170314011606 20170228072511 16836 nic.cz. ALfV0l2a4D1CITaZdP5k5Mc+uTZ1dSb3SRm1Z+AQmeQLKI7YrFlOCuUa q90yMQnG+0GMS4uwSmIcT3V2cjpBXw==
+ ENTRY_END
+
+ ENTRY_BEGIN
+ MATCH opcode qtype qname
+ ADJUST copy_id
+ REPLY QR RD DO AA NOERROR
+ SECTION QUESTION
+ c.ns.nic.cz. IN AAAA
+ SECTION ANSWER
+ c.ns.nic.cz. 1800 IN AAAA 2001:678:11::1
+ c.ns.nic.cz. 1800 IN RRSIG AAAA 13 4 1800 20170313184936 20170228072511 16836 nic.cz. U/tpYchWTle9loCW8fPIMoF3zto86UmFFCSnU7sFG9Qxk4I8fNUro1nT fAeJlrI7L7Yx9qlJTAllzrPjuw+3IA==
+ ENTRY_END
+
+ ENTRY_BEGIN
+ MATCH opcode qtype qname
+ ADJUST copy_id
+ REPLY QR RD DO AA NOERROR
+ SECTION QUESTION
+ d.ns.nic.cz. IN AAAA
+ SECTION ANSWER
+ d.ns.nic.cz. 1800 IN AAAA 2001:678:1::1
+ d.ns.nic.cz. 1800 IN RRSIG AAAA 13 4 1800 20170313124110 20170228072511 16836 nic.cz. kOI6MVJDSexQQ6uGT7KBjrTB2PDs49Cm65heInzMGZ20R75wO0JhSlce /T+Rpw3R0XpBre39h2DF7yBgePr+qg==
+ ENTRY_END
+
+ ENTRY_BEGIN
+ MATCH opcode qtype qname
+ ADJUST copy_id
+ REPLY QR RD DO AA NOERROR
+ SECTION QUESTION
+ cz. IN NS
+ SECTION ANSWER
+ cz. 14400 IN NS a.ns.nic.cz.
+ cz. 14400 IN NS b.ns.nic.cz.
+ cz. 14400 IN NS d.ns.nic.cz.
+ cz. 14400 IN NS c.ns.nic.cz.
+ cz. 14400 IN RRSIG NS 10 1 14400 20170307183707 20170222123920 58211 cz. Ma2XNvMziL3GtyLXtKcCBBG12+r7Uor3OFTw6c7Txk573/Y33IMnbN6B iKz0hZw0XK5c6nHciMEDkH2K772fcskHjEnOg+bJMBJlUmqskbVBmwpZ Dd156QC9OIfcE6yJYa6Y1jOegpgCaZLXRDOZodtvvTkYWNP/D01cmsF6 U+4=
+ ENTRY_END
+
+ ENTRY_BEGIN
+ MATCH opcode qtype qname
+ ADJUST copy_id copy_query
+ REPLY QR AA RD DO NOERROR
+ SECTION QUESTION
+ CZ. IN DNSKEY
+ SECTION ANSWER
+ cz. 18000 IN DNSKEY 256 3 10 AwEAAdWL2Br92Vx0dLEOOB8y02ss8LtKIyGlLJ2ymJ02WqR3AAEEZN0f NPKF77kdKsjlG8DlzmSIOR12aa9EhpXqyHOwWI0kHOMJVnn6ZKFIAl71 JP/dYIcshYUxKZZMe+zEAUrVtzlLVDtM6cDOPDuBNa1ujYec3eJl9Ipq eUEG6gAH
+ cz. 18000 IN DNSKEY 257 3 10 AwEAAay0hi4HN2r/BqMQTpIPIVDyjmyF+9ZWvr5Lewx+q+947o/GrRv4 FGFfkZxf9CFfYVUf0jG5Yq4i06pGVNwJl81HS9Ux2oeHRXUvgtLnl5He RVLL+zgI5byx9HSNr4bPO8ZEn5OjoayhkNyGSFr4VWrzQk/K02vLP4d1 cCEzUQy30eyZto2/tG5ZwCU/iRkS1PJOcOW98hiFIfFDZv1XjbEpqEYh T2PATs6rt+BKwSHKGISmg1PNdg+y0rItemYMWr1f9BGAdtTWoPCPCYPj OZMPoIyA4tMscD+ww54Jf/QNoHccY4hO1yHiuAXG7SUn8jo0IKQ9W7JJ xES0aqFCX/0=
+ cz. 18000 IN RRSIG DNSKEY 10 1 18000 20170304000000 20170218000000 54576 cz. paDUYJRI+4qBfPaGBy7nVMQnsp2hQQdiWWMnNunhfemFYi9MtXE2VTG3 DDL4Kue3ImSko/BxCRqHxHq5Sdf4LNexFWqFUlz4CjVeFobGTmmgOlak Sm2WygfZsO3w1OeO5cDCZTbi6XAhkr1cL3sgJR+/aOKIGUs8uIk1pZ5H WGNB1waF7Euxe+joEFtoj2/Tk7G7AlD1/Hw+pw5AkLTNawpHJF1/vnfT mPxdPHhJYCHlQdBE9dLkqQk7swnxMegBiUCeRd7SRiGq+1wubYsGirwl RZfYQpcqMnLH/1KITlVkKNYKnUGLjej4XRCDZOe3j8geIyS7WCJ5OPnU Lw0KDA==
+ cz. 18000 IN RRSIG DNSKEY 10 1 18000 20170313144128 20170228113958 58211 cz. xSEKl8ttuDR9Q3YjtVX+dPfdtwd4OG6rooml9TDIKNlND9LRTceRnpEH EsxUumTrRfWh8P4HWZF+B7hdm8qvcxAS3X3TYT4T7fKV5AFQbbMh+fv9 nut2RcZF40/x/0Hxh6QPLAtMDZs4W8IovQnpiTw8am9UoJNP+tT+dsgw ndA=
+ ENTRY_END
+
+ ENTRY_BEGIN
+ MATCH opcode qtype qname
+ ADJUST copy_id copy_query
+ REPLY QR AA RD DO NOERROR
+ SECTION QUESTION
+ nic.cz. IN DNSKEY
+ SECTION ANSWER
+ nic.cz. 1800 IN DNSKEY 256 3 13 vtFRotT17dIOLFIWi8BVFpHu8Thf/BrslFNNWlH2PPucF1rec69vuJi2 MswwoRtYQpRehbsjsjJ7kxXlTtfaFw==
+ nic.cz. 1800 IN DNSKEY 257 3 13 LM4zvjUgZi2XZKsYooDE0HFYGfWp242fKB+O8sLsuox8S6MJTowY8lBD jZD7JKbmaNot3+1H8zU9TrDzWmmHwQ==
+ nic.cz. 1800 IN RRSIG DNSKEY 13 2 1800 20170313103655 20170228072511 61281 nic.cz. mA899bEiTCULWpuF2JpVSm3wyHWmHIYuRMJj2X2E0AUhdbX2zhuSun8q EjKpr/0FfZCmlJIEC6dXmjIV+X0jhg==
+ nic.cz. 1800 IN RRSIG DNSKEY 13 2 1800 20170313194411 20170228072511 16836 nic.cz. iYJgEoykgdz6aqrE1DwM6fyWUFI2pDShqgfg7TiMaunyuvi2JwUaSbEq Ifm2aO5gF7bqSQjM+Y0NOzZ5nAUKrg==
+ ENTRY_END
+
+ ENTRY_BEGIN
+ MATCH opcode qtype qname
+ ADJUST copy_id
+ REPLY QR RD DO NOERROR
+ SECTION QUESTION
+ lidovky.cz. IN DS
+ SECTION ANSWER
+ lidovky.cz. 14400 IN DS 1901 8 2 1ED680FFBD77C4845A9BE15286FC73A756B6E4150C65DBC52EE4799B 641DFCE3
+ lidovky.cz. 14400 IN DS 4555 8 2 E4B03345B8E0EB3CD9208D2FA60F835A1E391CC485E84CBF3CB1136B D7748913
+ lidovky.cz. 14400 IN RRSIG DS 10 2 14400 20170312182850 20170228113958 58211 cz. yw/iboH4hKxLOv+0Mbyvp4rnT14IxkiOpk6kW7ANJI2AGoBa5L7oGy6F 4eEuc2AZKrn/FP2OZL8mItt0hBCucHpaBeRyx8n78pCuMnEaYs/Buxro 0S/bpkMhTRTTJCQ2uwKHAAfi2Q3PC1CWLKB8p7MbN21JlC3S7ANu0DgL 4Ro=
+ ENTRY_END
+
+ ENTRY_BEGIN
+ MATCH opcode subdomain
+ ADJUST copy_id copy_query
+ REPLY QR RD DO NOERROR
+ SECTION QUESTION
+ lidovky.cz. IN NS
+ SECTION AUTHORITY
+ lidovky.cz. 14400 IN NS ns.mafra.cz.
+ lidovky.cz. 14400 IN NS ns.mafracz.net.
+ lidovky.cz. 14400 IN NS ns2.mafra.cz.
+ lidovky.cz. 14400 IN DS 1901 8 2 1ED680FFBD77C4845A9BE15286FC73A756B6E4150C65DBC52EE4799B 641DFCE3
+ lidovky.cz. 14400 IN DS 4555 8 2 E4B03345B8E0EB3CD9208D2FA60F835A1E391CC485E84CBF3CB1136B D7748913
+ lidovky.cz. 14400 IN RRSIG DS 10 2 14400 20170312182850 20170228113958 58211 cz. yw/iboH4hKxLOv+0Mbyvp4rnT14IxkiOpk6kW7ANJI2AGoBa5L7oGy6F 4eEuc2AZKrn/FP2OZL8mItt0hBCucHpaBeRyx8n78pCuMnEaYs/Buxro 0S/bpkMhTRTTJCQ2uwKHAAfi2Q3PC1CWLKB8p7MbN21JlC3S7ANu0DgL 4Ro=
+ SECTION ADDITIONAL
+ ns.mafra.cz. 18000 IN A 194.79.53.77
+ ns2.mafra.cz. 18000 IN A 194.79.55.77
+ ENTRY_END
+
+ ENTRY_BEGIN
+ MATCH opcode qtype qname
+ ADJUST copy_id
+ REPLY QR RD DO NOERROR
+ SECTION QUESTION
+ mafra.cz. IN DS
+ SECTION AUTHORITY
+ cz. 900 IN SOA a.ns.nic.cz. hostmaster.nic.cz. 1488285598 900 300 604800 900
+ cz. 900 IN RRSIG SOA 10 1 14400 20170314055727 20170228113958 58211 cz. LBUALMOXd40KawVmUNWNlfMbeR0LDwNI5DPu9HqF8rtWCtHxReSGPrYs lyaL6gzVOn+i9Zikolj2arR+XPrb3vDMBjhh1AhP83p6Dfk4z0nEeaVy bJBdCSrcXcOi72RXY1QpO6lfhkpW2rhYtKS0Pq0rPVSF6rFVSLMavD82 X9s=
+ NP199O12UJ32S0N5CTA47VUUQK1B2N6P.cz. 900 IN NSEC3 1 0 10 34817B0B5673BB5D NP19M6SR9GQ4GR722R31PHMCCMV2L47C NS
+ NP199O12UJ32S0N5CTA47VUUQK1B2N6P.cz. 900 IN RRSIG NSEC3 10 2 900 20170309110321 20170224213957 58211 cz. Brz4hpl2jq+rhJlu9tZ6Ij0Ru4+2Yyw5a4OVgN4/umq/9jPn2dWgnOPS 6Mk5WIC9Yun9ZIvncS3oE1dRhXAF+nGZS9jr1tdXLx+1Sow4o0nP8cxw 8Sl8BVjBkDpVSZfGVMN06NjJub57uw5nDF3E/AjoCYDxnb0UrVmIGCUb h7A=
+ ENTRY_END
+
+ ENTRY_BEGIN
+ MATCH opcode subdomain
+ ADJUST copy_id copy_query
+ REPLY QR RD DO NOERROR
+ SECTION QUESTION
+ mafra.cz. IN NS
+ SECTION AUTHORITY
+ mafra.cz. 14400 IN NS ns.mafra.cz.
+ mafra.cz. 14400 IN NS ns.mafracz.net.
+ mafra.cz. 14400 IN NS ns2.mafra.cz.
+ np199o12uj32s0n5cta47vuuqk1b2n6p.cz. 900 IN NSEC3 1 0 10 34817B0B5673BB5D NP19M6SR9GQ4GR722R31PHMCCMV2L47C NS
+ np199o12uj32s0n5cta47vuuqk1b2n6p.cz. 900 IN RRSIG NSEC3 10 2 900 20170309110321 20170224213957 58211 cz. Brz4hpl2jq+rhJlu9tZ6Ij0Ru4+2Yyw5a4OVgN4/umq/9jPn2dWgnOPS 6Mk5WIC9Yun9ZIvncS3oE1dRhXAF+nGZS9jr1tdXLx+1Sow4o0nP8cxw 8Sl8BVjBkDpVSZfGVMN06NjJub57uw5nDF3E/AjoCYDxnb0UrVmIGCUb h7A=
+ SECTION ADDITIONAL
+ ns.mafra.cz. 7275 IN A 194.79.53.77
+ ns2.mafra.cz. 7275 IN A 194.79.55.77
+ ENTRY_END
+
+ ENTRY_BEGIN
+ MATCH opcode qtype qname
+ ADJUST copy_id
+ REPLY QR RD DO NOERROR
+ SECTION QUESTION
+ idnes.cz. IN DS
+ SECTION AUTHORITY
+ cz. 900 IN SOA a.ns.nic.cz. hostmaster.nic.cz. 1488285598 900 300 604800 900
+ cz. 900 IN RRSIG SOA 10 1 14400 20170314055727 20170228113958 58211 cz. LBUALMOXd40KawVmUNWNlfMbeR0LDwNI5DPu9HqF8rtWCtHxReSGPrYs lyaL6gzVOn+i9Zikolj2arR+XPrb3vDMBjhh1AhP83p6Dfk4z0nEeaVy bJBdCSrcXcOi72RXY1QpO6lfhkpW2rhYtKS0Pq0rPVSF6rFVSLMavD82 X9s=
+ AUOICN1434M9JOGSCEGTCFV7NUDKO603.cz. 900 IN NSEC3 1 0 10 34817B0B5673BB5D AUOJ570J8RB3057RHUJ1DAGMCO1GAUDH NS
+ AUOICN1434M9JOGSCEGTCFV7NUDKO603.cz. 900 IN RRSIG NSEC3 10 2 900 20170313031226 20170227134003 58211 cz. CMvsPy0Ce7UR692R7jMat7E9Mm2DHTcZz7b5PlwsNX3i+41Ymlh1TeAs utrGbJUR+cdKQStzN6uNsxGQ84zFmeqOvMKtZBbvdavQbXtDfwTuEplX XolQ82j/0wVYCkpYANkLmyLrwbbZxJ4sSb1sbVRtMN0daeE6y3OleQDk 2Uw=
+ ENTRY_END
+
+ ENTRY_BEGIN
+ MATCH opcode subdomain
+ ADJUST copy_id copy_query
+ REPLY QR RD DO NOERROR
+ SECTION QUESTION
+ idnes.cz. IN NS
+ SECTION AUTHORITY
+ idnes.cz. 14400 IN NS ns.mafra.cz.
+ idnes.cz. 14400 IN NS ns.mafracz.net.
+ idnes.cz. 14400 IN NS ns2.mafra.cz.
+ auoicn1434m9jogscegtcfv7nudko603.cz. 900 IN NSEC3 1 0 10 34817B0B5673BB5D AUOJ570J8RB3057RHUJ1DAGMCO1GAUDH NS
+ auoicn1434m9jogscegtcfv7nudko603.cz. 900 IN RRSIG NSEC3 10 2 900 20170313031226 20170227134003 58211 cz. CMvsPy0Ce7UR692R7jMat7E9Mm2DHTcZz7b5PlwsNX3i+41Ymlh1TeAs utrGbJUR+cdKQStzN6uNsxGQ84zFmeqOvMKtZBbvdavQbXtDfwTuEplX XolQ82j/0wVYCkpYANkLmyLrwbbZxJ4sSb1sbVRtMN0daeE6y3OleQDk 2Uw=
+ SECTION ADDITIONAL
+ ns.mafra.cz. 18000 IN A 194.79.53.77
+ ns2.mafra.cz. 18000 IN A 194.79.55.77
+ ENTRY_END
+
+RANGE_END
+
+;net
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ ADDRESS 192.33.14.30
+ ADDRESS 192.26.92.30
+ ADDRESS 192.31.80.30
+ ADDRESS 192.12.94.30
+ ADDRESS 192.35.51.30
+ ADDRESS 192.42.93.30
+ ADDRESS 192.54.112.30
+ ADDRESS 192.43.172.30
+ ADDRESS 192.48.79.30
+ ADDRESS 192.52.178.30
+ ADDRESS 192.41.162.30
+ ADDRESS 192.55.83.30
+ ADDRESS 2001:503:a83e::2:30
+ ADDRESS 2001:503:231d::2:30
+
+ ENTRY_BEGIN
+ MATCH opcode qtype qname
+ ADJUST copy_id copy_query
+ REPLY QR AA RD DO NOERROR
+ SECTION QUESTION
+ net. IN DNSKEY
+ SECTION ANSWER
+ net. 86400 IN DNSKEY 257 3 8 AQOYBnzqWXIEj6mlgXg4LWC0HP2n8eK8XqgHlmJ/69iuIHsa1TrHDG6T cOra/pyeGKwH0nKZhTmXSuUFGh9BCNiwVDuyyb6OBGy2Nte9Kr8NwWg4 q+zhSoOf4D+gC9dEzg0yFdwT0DKEvmNPt0K4jbQDS4Yimb+uPKuF6yie WWrPYYCrv8C9KC8JMze2uT6NuWBfsl2fDUoV4l65qMww06D7n+p7Rbdw WkAZ0fA63mXVXBZF6kpDtsYD7SUB9jhhfLQE/r85bvg3FaSs5Wi2BaqN 06SzGWI1DHu7axthIOeHwg00zxlhTpoYCH0ldoQz+S65zWYi/fRJiyLS Bb6JZOvn
+ net. 86400 IN DNSKEY 256 3 8 AQPMYWRP6GrTFoGFNQyuta0p4VYHr5Ox7yOl0Zv5ejOeRUnmoVgvHUR0 8lmmKEnBBPPZ89f/spt8VQ3GFUAbjJVzlcF5dQbY26YO/XKNcB2dlCEy quowoOQYsbASUj91c0IfFXAbK10reyShzaUi76p2VG5f0tjq/iC4iMZJ yxcpRQ==
+ net. 86400 IN RRSIG DNSKEY 8 1 86400 20170306173857 20170219173357 35886 net. Vvmjg9riU5c81z+4GEMSV4kEHf0ds2lxyD/UmGB4Vjtu0S71KldD4hh2 nA086G2Ssl1gBFEcVkLdPPpvh/c39mSITollT43u55pBLGQQcRXqPL6X 5xjlsOayD4QfwszBn5/5QTSD9pB5D9AsGQARlQTa0Vp1O9ruFDq0BuVQ F4P2QkNaxM6T+QZdFtqFOe6n3H+Qn0/TEvbM72w0hIBr1po3aSZuJleN SR3Wbubs1H7p1E6a6FH2+rRb3t7Q5DWNT/P5kZU0j+JB1PRknSwWCv7n orxIfhoYuFqU8Gw9w5KSw+Qtc7AjxlawQSAAZPLaq9ZL2cEKkeUrEGTD V41adg==
+ ENTRY_END
+
+ ENTRY_BEGIN
+ MATCH opcode qtype qname
+ ADJUST copy_id
+ REPLY QR RD DO NOERROR
+ SECTION QUESTION
+ net. IN DS
+ SECTION ANSWER
+ net. 900 IN SOA a.gtld-servers.net. nstld.verisign-grs.com. 1488288307 1800 900 604800 86400
+ net. 900 IN RRSIG SOA 8 1 900 20170307132507 20170228121507 16757 net. aeKdMkRb/POrt2pw0h0O8fN8EUXFXJlPHu/aHtIihIEkj85ZpCNrEOxr Zg5jkYtPXQwx+X0cnD/uNMEWPOD3vNW3Ap9Y01RlFBzvlBHeH4YA09tr ElBPqkzN6bNrNJi3V/yJjV2dy7IUvqDO9M5cQEuPHIED2sIh1FATmB6b KMs=
+ A1RT98BS5QGC9NFI51S9HCI47ULJG6JH.net. 86400 IN NSEC3 1 1 0 - A1RUUFFJKCT2Q54P78F8EJGJ8JBK7I8B NS SOA RRSIG DNSKEY NSEC3PARAM
+ A1RT98BS5QGC9NFI51S9HCI47ULJG6JH.net. 86400 IN RRSIG NSEC3 8 2 86400 20170306061207 20170227050207 16757 net. s53ftACmRAtcKkfowIENgWkCuHNoyesDp5kz1g62Uxm9v03ig4TkMMBW cUMvLFCp1XpmiOx9MX5klfJgFrhQPYmaRBuQaI3nrH6B57kjsphtJYvc B6wyRGPHAg+oNecZqQbUBEkzBrppoe4a5nhlOkLgbHKb5qPbN0tV5wBu x5c=
+ ENTRY_END
+
+ ENTRY_BEGIN
+ MATCH opcode qtype qname
+ ADJUST copy_id
+ REPLY QR RD DO AA NOERROR
+ SECTION QUESTION
+ net. IN NS
+ SECTION ANSWER
+ net. 172800 IN NS i.gtld-servers.net.
+ net. 172800 IN NS e.gtld-servers.net.
+ net. 172800 IN NS h.gtld-servers.net.
+ net. 172800 IN NS b.gtld-servers.net.
+ net. 172800 IN NS a.gtld-servers.net.
+ net. 172800 IN NS j.gtld-servers.net.
+ net. 172800 IN NS f.gtld-servers.net.
+ net. 172800 IN NS m.gtld-servers.net.
+ net. 172800 IN NS l.gtld-servers.net.
+ net. 172800 IN NS g.gtld-servers.net.
+ net. 172800 IN NS k.gtld-servers.net.
+ net. 172800 IN NS c.gtld-servers.net.
+ net. 172800 IN NS d.gtld-servers.net.
+ net. 172800 IN RRSIG NS 8 1 172800 20170304061505 20170225050505 16757 net. Pq4fze7lagq5NaKm7P4plOCY4gbFH3ZqZPvWIMojqNgHmoboqXWpth7R s2th1NzR7fxTvxngwVFlO7tR2Sf19epNimuJHEkxAKceLtSfdwxilfMz WvPq5/2tCINU8xo/SOC13ST4zq3PUi+VfPYbRF+5SakOTkU/6m1+9hlo ixo=
+ SECTION ADDITIONAL
+ a.gtld-servers.net. 172800 IN A 192.5.6.30
+ b.gtld-servers.net. 172800 IN A 192.33.14.30
+ c.gtld-servers.net. 172800 IN A 192.26.92.30
+ d.gtld-servers.net. 172800 IN A 192.31.80.30
+ e.gtld-servers.net. 172800 IN A 192.12.94.30
+ f.gtld-servers.net. 172800 IN A 192.35.51.30
+ g.gtld-servers.net. 172800 IN A 192.42.93.30
+ h.gtld-servers.net. 172800 IN A 192.54.112.30
+ i.gtld-servers.net. 172800 IN A 192.43.172.30
+ j.gtld-servers.net. 172800 IN A 192.48.79.30
+ k.gtld-servers.net. 172800 IN A 192.52.178.30
+ l.gtld-servers.net. 172800 IN A 192.41.162.30
+ m.gtld-servers.net. 172800 IN A 192.55.83.30
+ a.gtld-servers.net. 172800 IN AAAA 2001:503:a83e::2:30
+ b.gtld-servers.net. 172800 IN AAAA 2001:503:231d::2:30
+ ENTRY_END
+
+ ENTRY_BEGIN
+ MATCH opcode qtype qname
+ ADJUST copy_id
+ REPLY QR RD DO NOERROR
+ SECTION QUESTION
+ root-servers.net. IN DS
+ SECTION AUTHORITY
+ A1RT98BS5QGC9NFI51S9HCI47ULJG6JH.net. 86400 IN NSEC3 1 1 0 - A1RUUFFJKCT2Q54P78F8EJGJ8JBK7I8B NS SOA RRSIG DNSKEY NSEC3PARAM
+ A1RT98BS5QGC9NFI51S9HCI47ULJG6JH.net. 86400 IN RRSIG NSEC3 8 2 86400 20170306061207 20170227050207 16757 net. s53ftACmRAtcKkfowIENgWkCuHNoyesDp5kz1g62Uxm9v03ig4TkMMBW cUMvLFCp1XpmiOx9MX5klfJgFrhQPYmaRBuQaI3nrH6B57kjsphtJYvc B6wyRGPHAg+oNecZqQbUBEkzBrppoe4a5nhlOkLgbHKb5qPbN0tV5wBu x5c=
+ net. 900 IN SOA a.gtld-servers.net. nstld.verisign-grs.com. 1488288412 1800 900 604800 86400
+ net. 900 IN RRSIG SOA 8 1 900 20170307132652 20170228121652 16757 net. VnpLNPVwJO8pW1+aHC5jGq17aTVQuWMfu7igBcig9XG9li1wVBtawqaB zpiT8zoUWa76qkydyhuKWNjR895eLQz1Ql0cboW8GIddDFfKacpEP9nr QWwqjiMltfXn+iGiumrDbxwHKvwllXhOIShR5uAT640UcJ7QMhrq2jrJ V+Y=
+ T2UFL481TTPOHR68HR18DHJAFU935MJU.net. 86400 IN NSEC3 1 1 0 - T2UKCT9K5I0UHV7B3M3NA6JAIGDJM0GR NS DS RRSIG
+ T2UFL481TTPOHR68HR18DHJAFU935MJU.net. 86400 IN RRSIG NSEC3 8 2 86400 20170307061346 20170228050346 16757 net. KpGr8ZrjFGZ2q39FPpGe9SBR4hJ1e8L9oyvO5JS7Eh4LVdjwsD8B13nQ 7iv6jdCWVIWXh41fB4dcCUvLYqd9d75bACQ4JQVR3ycON9Qwt2XiUyVk iBYm7cp9C78+Uj0/P3TClk90GtZaAb3+JXUZZvrK08HnivVtmTta1Laj TVk=
+ ENTRY_END
+
+ ENTRY_BEGIN
+ MATCH opcode qtype qname
+ ADJUST copy_id
+ REPLY QR RD DO NOERROR
+ SECTION QUESTION
+ gtld-servers.net. IN DS
+ SECTION AUTHORITY
+ A1RT98BS5QGC9NFI51S9HCI47ULJG6JH.net. 86400 IN NSEC3 1 1 0 - A1RUUFFJKCT2Q54P78F8EJGJ8JBK7I8B NS SOA RRSIG DNSKEY NSEC3PARAM
+ A1RT98BS5QGC9NFI51S9HCI47ULJG6JH.net. 86400 IN RRSIG NSEC3 8 2 86400 20170306061207 20170227050207 16757 net. s53ftACmRAtcKkfowIENgWkCuHNoyesDp5kz1g62Uxm9v03ig4TkMMBW cUMvLFCp1XpmiOx9MX5klfJgFrhQPYmaRBuQaI3nrH6B57kjsphtJYvc B6wyRGPHAg+oNecZqQbUBEkzBrppoe4a5nhlOkLgbHKb5qPbN0tV5wBu x5c=
+ net. 900 IN SOA a.gtld-servers.net. nstld.verisign-grs.com. 1488288457 1800 900 604800 86400
+ net. 900 IN RRSIG SOA 8 1 900 20170307132737 20170228121737 16757 net. x5j/Iiv9Bey7T4FSeICdJrAyn5tEubHlhQXGmjM4KAVEq1CybM70rL7s HrwAhyiC/9RobYaMhM4fxmji3h8vWYbWauGMZ5XXmRGL66jE6Zq/M99v zk7RDnedNS+vPAv49PJ5aICGs4hfapPg3Kwf/KKwDzzvactaRYPvptLX u74=
+ 5QD8VL68T2I9KOBD32KJ8LJVH5OH2PQ0.net. 86400 IN NSEC3 1 1 0 - 5QDPPOTUK27KKP9LIGTRB0K1CBVM9CIM NS DS RRSIG
+ 5QD8VL68T2I9KOBD32KJ8LJVH5OH2PQ0.net. 86400 IN RRSIG NSEC3 8 2 86400 20170306060531 20170227045531 16757 net. uV9O+X7Vk1+dgIdqY2qE5RvN4B4Nv+xDLjd5V30sapNI8ARrA8d9pEVY qGNU5tF8+VT3lukCjvfgfopyTjw+SO+x4fwpZenmehwgNFkMHYWAv/1l xrdZHw60JMa/jWy+Rtdqi2uBJMGldGEIiuLEHgkKAjub2wtdiEkl2Azo AeY=
+ ENTRY_END
+
+ ENTRY_BEGIN
+ MATCH opcode qtype subdomain
+ ADJUST copy_id copy_query
+ REPLY QR RD DO NOERROR
+ SECTION QUESTION
+ gtld-servers.net. IN NS
+
+ SECTION AUTHORITY
+ gtld-servers.net. 172800 IN NS av1.nstld.com.
+ gtld-servers.net. 172800 IN NS av2.nstld.com.
+ gtld-servers.net. 172800 IN NS av3.nstld.com.
+ gtld-servers.net. 172800 IN NS av4.nstld.com.
+ A1RT98BS5QGC9NFI51S9HCI47ULJG6JH.net. 86400 IN NSEC3 1 1 0 - A1RUUFFJKCT2Q54P78F8EJGJ8JBK7I8B NS SOA RRSIG DNSKEY NSEC3PARAM
+ A1RT98BS5QGC9NFI51S9HCI47ULJG6JH.net. 86400 IN RRSIG NSEC3 8 2 86400 20170306061207 20170227050207 16757 net. s53ftACmRAtcKkfowIENgWkCuHNoyesDp5kz1g62Uxm9v03ig4TkMMBW cUMvLFCp1XpmiOx9MX5klfJgFrhQPYmaRBuQaI3nrH6B57kjsphtJYvc B6wyRGPHAg+oNecZqQbUBEkzBrppoe4a5nhlOkLgbHKb5qPbN0tV5wBu x5c=
+ 5QD8VL68T2I9KOBD32KJ8LJVH5OH2PQ0.net. 86400 IN NSEC3 1 1 0 - 5QDPPOTUK27KKP9LIGTRB0K1CBVM9CIM NS DS RRSIG
+ 5QD8VL68T2I9KOBD32KJ8LJVH5OH2PQ0.net. 86400 IN RRSIG NSEC3 8 2 86400 20170306060531 20170227045531 16757 net. uV9O+X7Vk1+dgIdqY2qE5RvN4B4Nv+xDLjd5V30sapNI8ARrA8d9pEVY qGNU5tF8+VT3lukCjvfgfopyTjw+SO+x4fwpZenmehwgNFkMHYWAv/1l xrdZHw60JMa/jWy+Rtdqi2uBJMGldGEIiuLEHgkKAjub2wtdiEkl2Azo AeY=
+
+ SECTION ADDITIONAL
+ av1.nstld.com. 172800 IN A 192.42.177.30
+ av1.nstld.com. 172800 IN AAAA 2001:500:124::30
+ av2.nstld.com. 172800 IN A 192.42.178.30
+ av2.nstld.com. 172800 IN AAAA 2001:500:125::30
+ av3.nstld.com. 172800 IN A 192.82.133.30
+ av3.nstld.com. 172800 IN AAAA 2001:500:126::30
+ av4.nstld.com. 172800 IN A 192.82.134.30
+ av4.nstld.com. 172800 IN AAAA 2001:500:127::30
+ ENTRY_END
+
+ ENTRY_BEGIN
+ MATCH opcode qname qtype
+ ADJUST copy_id
+ REPLY QR RD DO NOERROR
+ SECTION QUESTION
+ a.gtld-servers.net. IN A
+ SECTION ANSWER
+ a.gtld-servers.net. 172800 IN A 192.5.6.30
+ ENTRY_END
+
+ ENTRY_BEGIN
+ MATCH opcode subdomain
+ ADJUST copy_id copy_query
+ REPLY QR RD DO NOERROR
+ SECTION QUESTION
+ gtld-servers.net. IN A
+ SECTION AUTHORITY
+ gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2016101000 3600 900 1209600 86400
+ ENTRY_END
+
+ ENTRY_BEGIN
+ MATCH opcode qtype qname
+ ADJUST copy_id copy_query
+ REPLY QR RD DO NOERROR
+ SECTION QUESTION
+ a.root-servers.net. IN A
+ SECTION AUTHORITY
+ root-servers.net. 172800 IN NS a.root-servers.net.
+ SECTION ADDITIONAL
+ a.root-servers.net. 3600000 IN A 198.41.0.4
+ ENTRY_END
+
+ ENTRY_BEGIN
+ MATCH opcode subdomain
+ ADJUST copy_id copy_query
+ REPLY QR RD DO NOERROR
+ SECTION QUESTION
+ root-servers.net. IN AAAA
+ SECTION AUTHORITY
+ root-servers.net. 172800 IN NS a.root-servers.net.
+ SECTION ADDITIONAL
+ a.root-servers.net. 172800 IN A 198.41.0.4
+ ENTRY_END
+
+ ENTRY_BEGIN
+ MATCH opcode qtype qname
+ ADJUST copy_id
+ REPLY QR RD DO NOERROR
+ SECTION QUESTION
+ mafracz.net. IN DS
+ SECTION AUTHORITY
+ A1RT98BS5QGC9NFI51S9HCI47ULJG6JH.net. 86400 IN NSEC3 1 1 0 - A1RUUFFJKCT2Q54P78F8EJGJ8JBK7I8B NS SOA RRSIG DNSKEY NSEC3PARAM
+ A1RT98BS5QGC9NFI51S9HCI47ULJG6JH.net. 86400 IN RRSIG NSEC3 8 2 86400 20170306061207 20170227050207 16757 net. s53ftACmRAtcKkfowIENgWkCuHNoyesDp5kz1g62Uxm9v03ig4TkMMBW cUMvLFCp1XpmiOx9MX5klfJgFrhQPYmaRBuQaI3nrH6B57kjsphtJYvc B6wyRGPHAg+oNecZqQbUBEkzBrppoe4a5nhlOkLgbHKb5qPbN0tV5wBu x5c=
+ net. 900 IN SOA a.gtld-servers.net. nstld.verisign-grs.com. 1488288547 1800 900 604800 86400
+ net. 900 IN RRSIG SOA 8 1 900 20170307132907 20170228121907 16757 net. y7pu7BBxAqE7l+JB4PIg/2l+WPgeOrSo+TRo2vKqVJFa03GttNi4BlWH s0sT3t4Mr0nvWxNf7PlUUct7KFssGGCu6kXC3RiZsXDaTeAnHjAfk9rg v/z6PM7fU3shLjEXDuIY9GtPAw65nbSeK1Sai/3gWUOnlxo1J2r3VXl3 cfE=
+ P61KBBD5BIIR8OO46HQUMTGEQAU7RAQJ.net. 86400 IN NSEC3 1 1 0 - P61TM41BB9FNGTRQ6D1PPAU0E9MD6S63 NS DS RRSIG
+ P61KBBD5BIIR8OO46HQUMTGEQAU7RAQJ.net. 86400 IN RRSIG NSEC3 8 2 86400 20170304061336 20170225050336 16757 net. QKFFK4L57Pzylgc3d/9Z5R++Cqxx5agyEG6HPcGtjCSslA7DEj+qULoy TTWNBpgzPgwwrZy0BdNYBZdC3rpdfiJqCidVXe7bRfUQDHY4NJiuouOv jLGxYf/k8gqKAElV9CriTBkkjALwXdlDvCSMnhczMlu0409YoL3XKBdE TCc=
+ ENTRY_END
+
+ ENTRY_BEGIN
+ MATCH opcode subdomain
+ ADJUST copy_id copy_query
+ REPLY QR RD DO NOERROR
+ SECTION QUESTION
+ mafracz.net. IN NS
+ SECTION AUTHORITY
+ mafracz.net. 172800 IN NS ns.mafra.cz.
+ mafracz.net. 172800 IN NS ns2.mafra.cz.
+ mafracz.net. 172800 IN NS ns.mafracz.net.
+ A1RT98BS5QGC9NFI51S9HCI47ULJG6JH.net. 86400 IN NSEC3 1 1 0 - A1RUUFFJKCT2Q54P78F8EJGJ8JBK7I8B NS SOA RRSIG DNSKEY NSEC3PARAM
+ A1RT98BS5QGC9NFI51S9HCI47ULJG6JH.net. 86400 IN RRSIG NSEC3 8 2 86400 20170306061207 20170227050207 16757 net. s53ftACmRAtcKkfowIENgWkCuHNoyesDp5kz1g62Uxm9v03ig4TkMMBW cUMvLFCp1XpmiOx9MX5klfJgFrhQPYmaRBuQaI3nrH6B57kjsphtJYvc B6wyRGPHAg+oNecZqQbUBEkzBrppoe4a5nhlOkLgbHKb5qPbN0tV5wBu x5c=
+ P61KBBD5BIIR8OO46HQUMTGEQAU7RAQJ.net. 86400 IN NSEC3 1 1 0 - P61TM41BB9FNGTRQ6D1PPAU0E9MD6S63 NS DS RRSIG
+ P61KBBD5BIIR8OO46HQUMTGEQAU7RAQJ.net. 86400 IN RRSIG NSEC3 8 2 86400 20170304061336 20170225050336 16757 net. QKFFK4L57Pzylgc3d/9Z5R++Cqxx5agyEG6HPcGtjCSslA7DEj+qULoy TTWNBpgzPgwwrZy0BdNYBZdC3rpdfiJqCidVXe7bRfUQDHY4NJiuouOv jLGxYf/k8gqKAElV9CriTBkkjALwXdlDvCSMnhczMlu0409YoL3XKBdE TCc=
+ SECTION ADDITIONAL
+ ns.mafracz.net. 165236 IN A 185.17.118.250
+ ENTRY_END
+RANGE_END
+
+
+RANGE_BEGIN 0 100
+ ADDRESS 194.79.53.77
+ ADDRESS 185.17.118.250
+ ADDRESS 194.79.55.77
+
+ ENTRY_BEGIN
+ MATCH opcode qtype qname
+ ADJUST copy_id copy_query
+ REPLY QR AA RD DO NOERROR
+ SECTION QUESTION
+ ns.mafracz.net. IN A
+ SECTION ANSWER
+ ns.mafracz.net. 600 IN A 185.17.118.250
+ SECTION AUTHORITY
+ mafracz.net. 600 IN NS ns2.mafra.cz.
+ mafracz.net. 600 IN NS ns.mafracz.net.
+ mafracz.net. 600 IN NS ns.mafra.cz.
+ SECTION ADDITIONAL
+ ns.mafra.cz. 300 IN A 194.79.53.77
+ ns2.mafra.cz. 300 IN A 194.79.55.77
+ ENTRY_END
+
+ ENTRY_BEGIN
+ MATCH opcode qtype qname
+ ADJUST copy_id copy_query
+ REPLY QR AA RD DO NOERROR
+ SECTION QUESTION
+ lidovky.cz. IN DNSKEY
+ SECTION ANSWER
+ lidovky.cz. 3600 IN DNSKEY 256 3 8 AwEAAb8GYuVqOqVTYuppOCtctAHJ38tuSVriiptyQcxdZsU7U7s2XFVp QAuTxxoBOuvJZLMLXNikOki1KCnQx030Zz73AFx8tiPS6rFzR71TJXTC HlpwDnnK3rkdsu6Ay85cLiRtFpgW1D1WPi5oCJWGs4dJ8L5mcoIYikZt 99cfDKY/
+ lidovky.cz. 3600 IN DNSKEY 256 3 8 AwEAActfDtlHpl0/2f9qMqDt5uslMzxKDNf4FGklmcG+OO2HuhOhnQVx arB6lYxIKofy+uOvUhyGxlxCq08bVKueBpAt0x5kLMAwhc6zmn8niIE6 +UZxLg7+r2ojLTl0qQ2sMoG6ryo4/1GCEwh/TjJp8PuAzE0Q7yQOE6ed jZkWjraJ
+ lidovky.cz. 3600 IN DNSKEY 257 3 8 AwEAAeFABHDi1QXB2WaYeLP07RzSfn9IIjMFrL6+obHNgMpY32skT0fX +4YiF1vrAwI3FyvqvLERcUqZl3kMFk/mBDEBcCCP8osbndEUEEg2fVkZ gPDVWT3nCBMXRRuXmddn+L7o18wTUTBbLCxCT22ROOqahUyDEHvHpUbq LTbY+GGnSNzAD9/BWFdMIGOKzQ8oYFFyWDGZYAcznojZO7gvpduw3slg t3YLv4iDxMIgFokCw+qQhf42xtmox7H6KfCaW59PdFfRRAc20JfpGxJ4 m2PAuuacgOoVkqRLqprJ0/NCmMJgQZ3yKQWe2QWfRP9lhmF9HXAVukyy Yh3+JaqulxM=
+ lidovky.cz. 3600 IN RRSIG DNSKEY 8 2 3600 20170305034217 20170226010009 1901 lidovky.cz. ElBtNV7iyYIWDExYkKJ+pwwIcSwJ6kXfiT3yFiwp43CqXg9KxMK55UBe nCToid81/xgGQmSnmHw8w5LQXs5CjiIamoMYCX0SCie0FsfvFx1871np CvzTeSr4U876wnZVAjmM/FnDP63/4SgIICZpMb3P/MU7M+zr93JgOMXs E0Zp4uR6puh7a52VMRBLBIEx4L8mw2TW3VU9an2FD5r6GnAqI5YqEY8P FpHdkb243AvB3rZBWtDiKFSzD+WsrqrDOL3lmA/Jcb5GcxA2CGxfTSCJ +ndebgdkFSwPXQxW7FQwdS4mTuPixdzonq8XtljLZSomyJ0mnepn0j7k lwklow==
+ ENTRY_END
+
+ ENTRY_BEGIN
+ MATCH opcode qtype qname
+ ADJUST copy_id
+ REPLY QR AA RD DO NOERROR
+ SECTION QUESTION
+ lidovky.cz. IN A
+ SECTION ANSWER
+ lidovky.cz. 300 IN A 185.17.119.32
+ lidovky.cz. 300 IN RRSIG A 8 2 300 20170306080352 20170227090009 61408 lidovky.cz. rDSYYHIlE4Drq4/QLXrTDk+oeY6nh+W0p7cSeH9BGojdE4qIHjWUDjOS C4sEQpZtgG6EKO5j6P2+8bJ/3SmWdFT2GPHgP5eeRHPoo3iaGQMxXebD pbyVHtN//Gb577ycKcbNys/loflzhTWL2K1QXIHk53iWOTlDBg6uJcqi HsI=
+ SECTION AUTHORITY
+ lidovky.cz. 300 IN NS ns2.mafra.cz.
+ lidovky.cz. 300 IN NS ns.mafracz.net.
+ lidovky.cz. 300 IN NS ns.mafra.cz.
+ lidovky.cz. 300 IN RRSIG NS 8 2 300 20170304164701 20170225230009 61408 lidovky.cz. QmaLuzIDTiB/QbIgyxPRTVGFG/P5wFyrzlBtK7LIUsVIk8wuM9GudvQx weBiLPbaj28YypIdkS/z12sIawYenv4R9lswSVCOqT2H1KhXMtbW+BMk p5bCyr1mEJfceas6td4gywOydtfjYwU7WBvFPpMszP22p7jrizeQQpNB dK4=
+ SECTION ADDITIONAL
+ ns.mafra.cz. 300 IN A 194.79.53.77
+ ns.mafracz.net. 600 IN A 185.17.118.250
+ ns2.mafra.cz. 300 IN A 194.79.55.77
+ ENTRY_END
+
+ ENTRY_BEGIN
+ MATCH opcode qtype qname
+ ADJUST copy_id
+ REPLY QR AA RD DO NOERROR
+ SECTION QUESTION
+ www.lidovky.cz. IN A
+ SECTION ANSWER
+ www.lidovky.cz. 300 IN CNAME c23.idnes.cz.
+ www.lidovky.cz. 300 IN RRSIG CNAME 8 3 300 20170305033947 20170226030009 61408 lidovky.cz. VyqkB8Fzxs+LTz9WDKLMmbyrtq+V/5R1sYfYBQJPuVa3pJ1vX2I5M6XK n7TDu9gsW2v+zquOps/8aL/e/+R8ivEJomYzdnvH3EwfgT9WCOYJtlUL +sIq8eu45jXTVsFVLa0Fy5LKeFcfic+4C6AG676o5VSucVJLTWiftW47 RPA=
+ c23.idnes.cz. 300 IN A 185.17.119.54
+ SECTION AUTHORITY
+ idnes.cz. 300 IN NS ns.mafra.cz.
+ idnes.cz. 300 IN NS ns2.mafra.cz.
+ idnes.cz. 300 IN NS ns.mafracz.net.
+ SECTION ADDITIONAL
+ ns.mafra.cz. 300 IN A 194.79.53.77
+ ns.mafracz.net. 600 IN A 185.17.118.250
+ ns2.mafra.cz. 300 IN A 194.79.55.77
+ ENTRY_END
+
+ ENTRY_BEGIN
+ MATCH opcode qtype qname
+ ADJUST copy_id
+ REPLY QR AA RD DO NOERROR
+ SECTION QUESTION
+ c23.idnes.cz. IN A
+ SECTION ANSWER
+ c23.idnes.cz. 300 IN A 185.17.119.54
+ SECTION AUTHORITY
+ idnes.cz. 300 IN NS ns.mafra.cz.
+ idnes.cz. 300 IN NS ns2.mafra.cz.
+ idnes.cz. 300 IN NS ns.mafracz.net.
+ SECTION ADDITIONAL
+ ns.mafra.cz. 300 IN A 194.79.53.77
+ ns.mafracz.net. 600 IN A 185.17.118.250
+ ns2.mafra.cz. 300 IN A 194.79.55.77
+ ENTRY_END
+
+ ENTRY_BEGIN
+ MATCH opcode qtype qname
+ ADJUST copy_id
+ REPLY QR AA RD DO NOERROR
+ SECTION QUESTION
+ ns2.mafra.cz. IN A
+ SECTION ANSWER
+ ns2.mafra.cz. 300 IN A 194.79.55.77
+ SECTION AUTHORITY
+ mafra.cz. 300 IN NS ns.mafra.cz.
+ mafra.cz. 300 IN NS ns2.mafra.cz.
+ mafra.cz. 300 IN NS ns.mafracz.net.
+ SECTION ADDITIONAL
+ ns.mafra.cz. 300 IN A 194.79.53.77
+ ns.mafracz.net. 600 IN A 185.17.118.250
+ ENTRY_END
+
+ ENTRY_BEGIN
+ MATCH opcode qtype qname
+ ADJUST copy_id
+ REPLY QR AA RD DO NOERROR
+ SECTION QUESTION
+ ns.mafra.cz. IN A
+ SECTION ANSWER
+ ns.mafra.cz. 300 IN A 194.79.53.77
+ SECTION AUTHORITY
+ mafra.cz. 300 IN NS ns.mafra.cz.
+ mafra.cz. 300 IN NS ns2.mafra.cz.
+ mafra.cz. 300 IN NS ns.mafracz.net.
+ SECTION ADDITIONAL
+ ns2.mafra.cz. 300 IN A 194.79.55.77
+ ns.mafracz.net. 600 IN A 185.17.118.250
+ ENTRY_END
+
+ ENTRY_BEGIN
+ MATCH opcode qtype qname
+ ADJUST copy_id
+ REPLY QR RD DO AA NOERROR
+ SECTION QUESTION
+ lidovky.cz. IN NS
+ SECTION ANSWER
+ lidovky.cz. 300 IN NS ns.mafra.cz.
+ lidovky.cz. 300 IN NS ns2.mafra.cz.
+ lidovky.cz. 300 IN NS ns.mafracz.net.
+ lidovky.cz. 300 IN RRSIG NS 8 2 300 20170304164701 20170225230009 61408 lidovky.cz. QmaLuzIDTiB/QbIgyxPRTVGFG/P5wFyrzlBtK7LIUsVIk8wuM9GudvQx weBiLPbaj28YypIdkS/z12sIawYenv4R9lswSVCOqT2H1KhXMtbW+BMk p5bCyr1mEJfceas6td4gywOydtfjYwU7WBvFPpMszP22p7jrizeQQpNB dK4=
+ SECTION ADDITIONAL
+ ns.mafra.cz. 300 IN A 194.79.53.77
+ ns.mafracz.net. 600 IN A 185.17.118.250
+ ns2.mafra.cz. 300 IN A 194.79.55.77
+ ENTRY_END
+
+ ENTRY_BEGIN
+ MATCH opcode qtype qname
+ ADJUST copy_id
+ REPLY QR RD DO AA NOERROR
+ SECTION QUESTION
+ mafra.cz. IN NS
+ SECTION ANSWER
+ mafra.cz. 300 IN NS ns.mafra.cz.
+ mafra.cz. 300 IN NS ns2.mafra.cz.
+ mafra.cz. 300 IN NS ns.mafracz.net.
+ SECTION ADDITIONAL
+ ns.mafra.cz. 300 IN A 194.79.53.77
+ ns.mafracz.net. 600 IN A 185.17.118.250
+ ns2.mafra.cz. 300 IN A 194.79.55.77
+ ENTRY_END
+
+ ENTRY_BEGIN
+ MATCH opcode qtype qname
+ ADJUST copy_id
+ REPLY QR RD DO AA NOERROR
+ SECTION QUESTION
+ mafracz.net. IN NS
+ SECTION ANSWER
+ mafracz.net. 300 IN NS ns.mafra.cz.
+ mafracz.net. 300 IN NS ns2.mafra.cz.
+ mafracz.net. 300 IN NS ns.mafracz.net.
+ SECTION ADDITIONAL
+ ns.mafra.cz. 300 IN A 194.79.53.77
+ ns.mafracz.net. 600 IN A 185.17.118.250
+ ns2.mafra.cz. 300 IN A 194.79.55.77
+ ENTRY_END
+
+ ENTRY_BEGIN
+ MATCH opcode qtype qname
+ ADJUST copy_id
+ REPLY QR RD DO AA NOERROR
+ SECTION QUESTION
+ idnes.cz. IN NS
+ SECTION ANSWER
+ idnes.cz. 300 IN NS ns2.mafra.cz.
+ idnes.cz. 300 IN NS ns.mafracz.net.
+ idnes.cz. 300 IN NS ns.mafra.cz.
+
+ SECTION ADDITIONAL
+ ns.mafra.cz. 300 IN A 194.79.53.77
+ ns.mafracz.net. 600 IN A 185.17.118.250
+ ns2.mafra.cz. 300 IN A 194.79.55.77
+ ENTRY_END
+
+ ENTRY_BEGIN
+ MATCH opcode qtype qname
+ ADJUST copy_id
+ REPLY QR RD DO NOERROR
+ SECTION QUESTION
+ ns.mafra.cz. IN AAAA
+ SECTION AUTHORITY
+ mafra.cz. 291 IN SOA ns.mafra.cz. hostmaster.mafra.cz. 2017021601 3600 600 1209600 600
+ ENTRY_END
+
+ ENTRY_BEGIN
+ MATCH opcode qtype qname
+ ADJUST copy_id
+ REPLY QR RD DO NOERROR
+ SECTION QUESTION
+ ns2.mafra.cz. IN AAAA
+ SECTION AUTHORITY
+ mafra.cz. 291 IN SOA ns.mafra.cz. hostmaster.mafra.cz. 2017021601 3600 600 1209600 600
+ ENTRY_END
+
+ ENTRY_BEGIN
+ MATCH opcode qtype qname
+ ADJUST copy_id
+ REPLY QR RD DO NOERROR
+ SECTION QUESTION
+ ns.mafracz.net. IN AAAA
+ SECTION AUTHORITY
+ mafracz.net. 600 IN SOA ns.mafracz.net. hostmaster.mafra.cz. 2015061701 3600 600 86400 3600
+ ENTRY_END
+
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+ REPLY RD DO
+ SECTION QUESTION
+ www.lidovky.cz IN A
+ENTRY_END
+
+STEP 2 CHECK_ANSWER
+ENTRY_BEGIN
+ MATCH rcode question answer flags
+ REPLY QR RD RA NOERROR
+ SECTION QUESTION
+ www.lidovky.cz IN A
+ SECTION ANSWER
+ www.lidovky.cz. 251 IN CNAME c23.idnes.cz.
+ www.lidovky.cz. 251 IN RRSIG CNAME 8 3 300 20170305033947 20170226030009 61408 lidovky.cz. VyqkB8Fzxs+LTz9WDKLMmbyrtq+V/5R1sYfYBQJPuVa3pJ1vX2I5M6XK n7TDu9gsW2v+zquOps/8aL/e/+R8ivEJomYzdnvH3EwfgT9WCOYJtlUL +sIq8eu45jXTVsFVLa0Fy5LKeFcfic+4C6AG676o5VSucVJLTWiftW47 RPA=
+ c23.idnes.cz. 251 IN A 185.17.119.54
+ENTRY_END
+
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/world_cz_rhybar.rpl b/tests/integration/deckard/sets/resolver/world_cz_rhybar.rpl
new file mode 100644
index 0000000..350fc9b
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/world_cz_rhybar.rpl
@@ -0,0 +1,296 @@
+do-ip4: no
+
+; test with real world Internet data
+; attempt to resolve www.rhybar.cz. A with CD first to populate BAD cache
+; and then try to resolve without any DNSSEC flag to see if it validates
+; correctly into Bogus status
+
+val-override-date: 20170201163631
+trust-anchor: ". 172800 IN DS 19036 8 2 49aac11d7b6f6446702e54a1607371607a1a41855200fd2ce1cdde32f24e8fb5"
+stub-addr: 2001:dc3::35
+CONFIG_END
+
+SCENARIO_BEGIN www.rhybar.cz.
+
+; DNS root
+RANGE_BEGIN 0 100
+ ADDRESS 192.33.4.12
+ ADDRESS 2001:500:2d::d
+ ADDRESS 2001:dc3::35
+ ADDRESS 192.36.148.17
+ ADDRESS 2001:500:12::d0d
+ ADDRESS 192.203.230.10
+ ADDRESS 199.7.83.42
+ ADDRESS 198.97.190.53
+ ADDRESS 2001:500:a8::e
+ ADDRESS 2001:500:9f::42
+ ADDRESS 2001:500:2::c
+ ADDRESS 2001:7fd::1
+ ADDRESS 193.0.14.129
+ ADDRESS 202.12.27.33
+ ADDRESS 192.58.128.30
+ ADDRESS 192.5.5.241
+ ADDRESS 2001:7fe::53
+ ADDRESS 198.41.0.4
+ ADDRESS 2001:500:2f::f
+ ADDRESS 199.7.91.13
+ ADDRESS 192.112.36.4
+ ADDRESS 2001:500:84::b
+ ADDRESS 192.228.79.201
+ ADDRESS 2001:503:c27::2:30
+ ADDRESS 2001:500:1::53
+ ADDRESS 2001:503:ba3e::2:30
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. 518400 IN NS a.root-servers.net.
+. 518400 IN NS i.root-servers.net.
+. 518400 IN NS d.root-servers.net.
+. 518400 IN NS j.root-servers.net.
+. 518400 IN NS b.root-servers.net.
+. 518400 IN NS e.root-servers.net.
+. 518400 IN NS k.root-servers.net.
+. 518400 IN NS g.root-servers.net.
+. 518400 IN NS f.root-servers.net.
+. 518400 IN NS c.root-servers.net.
+. 518400 IN NS m.root-servers.net.
+. 518400 IN NS h.root-servers.net.
+. 518400 IN NS l.root-servers.net.
+. 518400 IN RRSIG NS 8 0 518400 20170214050000 20170201040000 61045 . Ey0PFIQr/80otZwczK1hk0h+gxC8IRS9 F1BagrU8rKNcMWpp2cmYLOAeBABkkwdM c1Rg8ENJV17uDVEr32LWDWP1REjCKfI/ 2XXejWZ9jofcbDDNHQgvFX0xg+n3X+YV qG/WzOcHCmDGQNgFVhnC9K0JvO7pXmWS PJmESDO37XKLlFTdRtOYxYJ0wRaAMaBX irFD0qs/ePHyEPso4hg8cYIFeIbVzKgj jv0UrUJgc1V29GilKeYnWq7jHdJt/N0Q 18wgzEB0YlBL07zaq6DBvYCb6cjPoZQm iEKelHQ5MW297YzHGDVia03+5KgJFUhc XGcnMCQqnHxLEuQdY0syBQ==
+SECTION ADDITIONAL
+a.root-servers.net. 3600000 IN A 198.41.0.4
+a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30
+b.root-servers.net. 3600000 IN A 192.228.79.201
+b.root-servers.net. 3600000 IN AAAA 2001:500:84::b
+c.root-servers.net. 3600000 IN A 192.33.4.12
+c.root-servers.net. 3600000 IN AAAA 2001:500:2::c
+d.root-servers.net. 3600000 IN A 199.7.91.13
+d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d
+e.root-servers.net. 3600000 IN A 192.203.230.10
+e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e
+f.root-servers.net. 3600000 IN A 192.5.5.241
+f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f
+g.root-servers.net. 3600000 IN A 192.112.36.4
+g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d
+h.root-servers.net. 3600000 IN A 198.97.190.53
+h.root-servers.net. 3600000 IN AAAA 2001:500:1::53
+i.root-servers.net. 3600000 IN A 192.36.148.17
+i.root-servers.net. 3600000 IN AAAA 2001:7fe::53
+j.root-servers.net. 3600000 IN A 192.58.128.30
+j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30
+k.root-servers.net. 3600000 IN A 193.0.14.129
+k.root-servers.net. 3600000 IN AAAA 2001:7fd::1
+l.root-servers.net. 3600000 IN A 199.7.83.42
+l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42
+m.root-servers.net. 3600000 IN A 202.12.27.33
+m.root-servers.net. 3600000 IN AAAA 2001:dc3::35
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. IN DS
+SECTION AUTHORITY
+. 86400 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2017020101 1800 900 604800 86400
+. 86400 IN RRSIG SOA 8 0 86400 20170214170000 20170201160000 61045 . VD0rE7mpNaBtbxQiVerNLfdrAZc+YYPW u5GzNEOqScwW5EGamZe02t+pns6Z5LCJ dkka3yXTyIAPPrDig0z9VuYXt9pD45bf pB+9/sP0+oVtQZnuXRRsut9/Es3tuuMU 96O5RcFR8s/IeVfOmhq5hgNuSBrbWTxm 2EggbZ8RR1aUMTTTJorLver0xYQp8T6m LKrdRuC/jlgVH8/fmU+EUm0fZAtQTPDJ 5Q0XSigFYuX4aebIVn/YAtPKlG8twdq4 9tQ6QaUq8Qwx0w4fA+mizcPkufAn6/fs PYZlxhzibO+7L6/XpKR04+u1w5OCsNDy Aocf41ba1xkIJOJaqPNwVg==
+. 86400 IN RRSIG NSEC 8 0 86400 20170214170000 20170201160000 61045 . ThWu+J7xTDlcmWecgMSiRBhauX2dAHG4 RED8SZkdAw2w+0E/Du1+BNYBfnnJYJTr zkA4ThfIniNgeH5zWdlNU1ogDp0fcToI 3lz/yJ1zwJlcQFs0WNLKK0QMsjftF1wO VysIstlIu7+xgDTE/yz9fzBUMPpOh4qW 5G3xMU2Exqi4Qnn4LxPVn6jdLuygxwt+ oQ+qaMRSo3QOfBe5rwJsPQgM5S8k27mB jUmrasNHfqkWLy1nscoTtvyuOTIDh5pZ oXHCAaZbrGKAgovXjIeGCga1frtlCOOY JjUfjvahZXH0IHpP5IYkDsjM8r5iMIY7 6qrI5oHNHGeqkwV0/gJKzw==
+. 86400 IN NSEC aaa. NS SOA RRSIG NSEC DNSKEY
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY NOERROR QR AA
+SECTION QUESTION
+. IN DNSKEY
+SECTION ANSWER
+. 172800 IN RRSIG DNSKEY 8 0 172800 20170221000000 20170131000000 19036 . eq4bnmAmFeMpxfwZgDJcj+7oGo5XcBEK TbrXcBfztSS0RWvCzgFHyQSq7zjEV78M zgXCy/NfrN6wBLbSA7v1Q2Y3nWb9phiu SM422iqrUDdXue/iIj5JANdtDpzuiVAJ Fws/JWYl9TfzF3hfk6DjJttByUsZTKsl l6gQZsD/LcZ0cGYPNYWUz1geDXGawqjI 6o5wwdXSpEHUg2M4iN9yU0xeoz2si+E6 K+Sr6ZY20PfrWbanQrRX7Yhz3DMrwjk/ EuzQcLMxkkhqX8Lf9wlBfNk24NaK+L0q 1Fd5i3RNwlxJJP9DkEer7KTP43uoi8SU lzMfjKYd0pUUw7RES4VLdw==
+. 172800 IN DNSKEY 257 3 8 AwEAAagAIKlVZrpC6Ia7gEzahOR+9W29 euxhJhVVLOyQbSEW0O8gcCjFFVQUTf6v 58fLjwBd0YI0EzrAcQqBGCzh/RStIoO8 g0NfnfL2MTJRkxoXbfDaUeVPQuYEhg37 NZWAJQ9VnMVDxP/VHL496M/QZxkjf5/E fucp2gaDX6RS6CXpoY68LsvPVjR0ZSwz z1apAzvN9dlzEheX7ICJBBtuA6G3LQpz W5hOA2hzCTMjJPJ8LbqF6dsV6DoBQzgu l0sGIcGOYl7OyQdXfZ57relSQageu+ip AdTTJ25AsRTAoub8ONGcLmqrAmRLKBP1 dfwhYB4N7knNnulqQxA+Uk1ihz0=
+. 172800 IN DNSKEY 256 3 8 AwEAAYvgWbYkpeGgdPKaKTJU3Us4YSTR gy7+dzvfArIhi2tKoZ/WR1Dfw883SOU6 Uw7tpVRkLarN0oIMK/xbOBD1DcXnyfEl BwKsz4sVVWmfyr/x+igD/UjrcJ5zEBUr UmVtHyjar7ccaVc1/3ntkhZjI1hcungA lOhPhHlkMeX+5Azx6GdX//An5OgrdyH3 o/JmOPMDX1mt806JI/hf0EwAp1pBwo5e 8SrSuR1tD3sgNjr6IzCdrKSgqi92z49z cdis3EaY199WFW60DCS7ydu++T5Xa+Gy Ow1quagwf/JUC/mEpeBQYWrnpkBbpDB3 sy4+P2i8iCvavehbRyVm9U0MlIc=
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+cz. IN DS
+SECTION ANSWER
+cz. 86400 IN DS 54576 10 2 397e50c85ede9cde33f363a9e66fd1b216d788f8dd438a57a423a386869c8f06
+cz. 86400 IN RRSIG DS 8 1 86400 20170214050000 20170201040000 61045 . KFIT2d+AO6xPTOKH4qWqTcthiqONvswz Ya+rnndNcDVOhvS9aKotG1CbyZXes489 GwfyNNsuO5N+WzDWO5Jzm37doLFFq3Yv AxWupLK8/KpM8lYc1VxlrkZ/XxODPOvJ ZEJ3WCLoyvc4PQgKmpjqxmGv+9GafFDO 7m7P0a2dJGxEH8GSDimcXS8dWf72O6DX zse532zD5mvLR8p2mXaoK7i5PbRRMzyB jHnQRVJVw3myhdNa1wB4P4Y9qUGQty9G xXHwJGsiZjADnzA+zWQYhZYQUp2suM/T Ri4JIKtdzitJHJ7psy0uwqC93L9PUnuq kWNz4YrXgWHP9TJtY5uzKw==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY NOERROR QR
+SECTION QUESTION
+cz. IN NS
+SECTION AUTHORITY
+cz. 172800 IN NS a.ns.nic.cz.
+cz. 172800 IN NS b.ns.nic.cz.
+cz. 172800 IN NS c.ns.nic.cz.
+cz. 172800 IN NS d.ns.nic.cz.
+cz. 86400 IN DS 54576 10 2 397e50c85ede9cde33f363a9e66fd1b216d788f8dd438a57a423a386869c8f06
+cz. 86400 IN RRSIG DS 8 1 86400 20170214050000 20170201040000 61045 . KFIT2d+AO6xPTOKH4qWqTcthiqONvswz Ya+rnndNcDVOhvS9aKotG1CbyZXes489 GwfyNNsuO5N+WzDWO5Jzm37doLFFq3Yv AxWupLK8/KpM8lYc1VxlrkZ/XxODPOvJ ZEJ3WCLoyvc4PQgKmpjqxmGv+9GafFDO 7m7P0a2dJGxEH8GSDimcXS8dWf72O6DX zse532zD5mvLR8p2mXaoK7i5PbRRMzyB jHnQRVJVw3myhdNa1wB4P4Y9qUGQty9G xXHwJGsiZjADnzA+zWQYhZYQUp2suM/T Ri4JIKtdzitJHJ7psy0uwqC93L9PUnuq kWNz4YrXgWHP9TJtY5uzKw==
+SECTION ADDITIONAL
+a.ns.nic.cz. 172800 IN A 194.0.12.1
+a.ns.nic.cz. 172800 IN AAAA 2001:678:f::1
+b.ns.nic.cz. 172800 IN A 194.0.13.1
+b.ns.nic.cz. 172800 IN AAAA 2001:678:10::1
+c.ns.nic.cz. 172800 IN A 194.0.14.1
+c.ns.nic.cz. 172800 IN AAAA 2001:678:11::1
+d.ns.nic.cz. 172800 IN A 193.29.206.1
+d.ns.nic.cz. 172800 IN AAAA 2001:678:1::1
+ENTRY_END
+
+; end of M.ROOT-SERVERS.NET.
+RANGE_END
+
+
+; domains: cz. ; ?.ns.nic.cz.
+RANGE_BEGIN 0 100
+ ADDRESS 194.0.12.1
+ ADDRESS 194.0.13.1
+ ADDRESS 194.0.14.1
+ ADDRESS 193.29.206.1
+ ADDRESS 2001:678:f::1
+ ADDRESS 2001:678:10::1
+ ADDRESS 2001:678:11::1
+ ADDRESS 2001:678:1::1
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+cz. IN DNSKEY
+SECTION ANSWER
+cz. 18000 IN RRSIG DNSKEY 10 1 18000 20170208000000 20170125000000 54576 cz. NPdwGLJLADvyArolHZkv3rwBwla2txHr HKSNooiGAkLdddmkiC3+t2K7hHb54H1L fj7tVXgNwIAqx1rNK9uz/4ElQDy1k3Bz UezcPkO/FaRiDOm6Y81XLaSG6p+P5pub zEnP8/e36Vk07/cMF/aZFbqNlMQmOVQH pUezGNP8O8+80Q0OEyv9aKfVg/ahfOt8 s1vxMa6Dd67KsP8rw+VhLseOXMXST98x /QvirAeALoMXOi1AzZ6ai1aG8f0+6G9K 2lS/0ceMhdRBfoflBKz/CaEmIdEAsr7M GPH4PNMwiQ5eb32T0WIr01WQtKScNA5B vNG6PvBxxsgEHRTzOvfOCw==
+cz. 18000 IN RRSIG DNSKEY 10 1 18000 20170214174538 20170201143958 58211 cz. sPVcTvaLVDLnKCBtUbdZ1hkPcje55O2p HMHwnH3vfK+Z96nkbUoyNTnVhvMHCV2r LRoB9CHVxOD1O6gMVu36sO6/6xTi3g7J utvIu/+1RUXlAToVnsbqWpsKLqhAdHqL b3+V1bHYllyIhcWwrZwB465kQYwFrZEn C2TsBC1+6CM=
+cz. 18000 IN DNSKEY 256 3 10 AwEAAdWL2Br92Vx0dLEOOB8y02ss8LtK IyGlLJ2ymJ02WqR3AAEEZN0fNPKF77kd KsjlG8DlzmSIOR12aa9EhpXqyHOwWI0k HOMJVnn6ZKFIAl71JP/dYIcshYUxKZZM e+zEAUrVtzlLVDtM6cDOPDuBNa1ujYec 3eJl9IpqeUEG6gAH
+cz. 18000 IN DNSKEY 257 3 10 AwEAAay0hi4HN2r/BqMQTpIPIVDyjmyF +9ZWvr5Lewx+q+947o/GrRv4FGFfkZxf 9CFfYVUf0jG5Yq4i06pGVNwJl81HS9Ux 2oeHRXUvgtLnl5HeRVLL+zgI5byx9HSN r4bPO8ZEn5OjoayhkNyGSFr4VWrzQk/K 02vLP4d1cCEzUQy30eyZto2/tG5ZwCU/ iRkS1PJOcOW98hiFIfFDZv1XjbEpqEYh T2PATs6rt+BKwSHKGISmg1PNdg+y0rIt emYMWr1f9BGAdtTWoPCPCYPjOZMPoIyA 4tMscD+ww54Jf/QNoHccY4hO1yHiuAXG 7SUn8jo0IKQ9W7JJxES0aqFCX/0=
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rhybar.cz. IN NS
+SECTION ANSWER
+rhybar.cz. 600 IN NS b.ns.nic.cz.
+rhybar.cz. 600 IN NS a.ns.nic.cz.
+rhybar.cz. 600 IN RRSIG NS 5 2 600 20081030080058 20080930080058 5172 rhybar.cz. XNIBK/CmsKZsw6lT2iAa5g+TLOVxPx39 N7vOxqW5lafaC56EuCZxUEmZT6ECvU/W zvQIqE1vqN4X6N/Z+5QTXKM3zcT+Uhay yiLNRNwdlkmG0xo/+bYACj85lhyB3UGJ +vpRWg2VVJOy9RLMyIka/S7nVYpgKUZF AZuxue6K17o=
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rhybar.cz. IN RRSIG
+SECTION ANSWER
+rhybar.cz. 600 IN RRSIG NS 5 2 600 20081030080058 20080930080058 5172 rhybar.cz. XNIBK/CmsKZsw6lT2iAa5g+TLOVxPx39 N7vOxqW5lafaC56EuCZxUEmZT6ECvU/W zvQIqE1vqN4X6N/Z+5QTXKM3zcT+Uhay yiLNRNwdlkmG0xo/+bYACj85lhyB3UGJ +vpRWg2VVJOy9RLMyIka/S7nVYpgKUZF AZuxue6K17o=
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rhybar.cz. IN DS
+SECTION ANSWER
+rhybar.cz. 18000 IN DS 59916 5 2 1A6516C32DCF2038E5382D77ADACADE3EDE99CDD77F019FCDF3741B4 9F8D563B
+rhybar.cz. 18000 IN RRSIG DS 10 2 18000 20170214061134 20170201163953 58211 cz. CGwqHhSb6b8JsjztqPeRDKBC/Sp4O0Igc4r53T+SheWdMwgNwvbXiFD6 krt0FGf1QU/JCkH5L5oYHFeaPXljftB2d0JbzLnA+iaI9Jy1aRmUqvTN /PiDVPYI/SRFvCfk2FLMK5LzMfjPjooiSNv9b1zZKJd8cykq8/jgijXy 5Xk=
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rhybar.cz. IN DNSKEY
+SECTION ANSWER
+rhybar.cz. 600 IN RRSIG DNSKEY 5 2 600 20081030080058 20080930080058 5172 rhybar.cz. Xh5WqcWoiywSm+t4YhGqVVTb1Revz2Bv ETgb1uoY9DaREJhTUIq6zTA5xGS2WpAh YmIb8OV259NxT/jEtEdFIlTIz2nDzr1I 2ZrDoF/qwfJXvda8zy2wz3AHvou8uLeI BJLQKSpZx1YI3ee9YFFw25yfie9M4g1/ PXuMlTHpVVY=
+rhybar.cz. 600 IN RRSIG DNSKEY 5 2 600 20081030080058 20080930080058 44566 rhybar.cz. XkcudN72dM/HiqmKMZeOSjE8NavwtkXJ 2VGCQ5/RmJphEeSd/IZ4f5I67l+LZjvy +J+fplrvXTSnAx6+y5Z1xvo9HdGhCdUX uh6rIy1OScrUwOPOFJplTqccukafWngo iQZuj9mZS41ZcQA1Js+Q5EzhnmCD/7Tu IpmN6V+4eDXQcnf2uagpntWj153yjePd eb2r6NmfDDBQUu6GLIKfI6CtlmsiZWUA JvtBGLK4DxSn/5jxEA9UGHWqiRVxZKk6 ssZ71Fuxc5e2D+7j0XKZrw6kA0z3F8dg FuQQxWtVC0wyycE4H+PQbD7ZVkWeCiLg URHpDlizUB+xK1nGuHuE3Q==
+rhybar.cz. 600 IN DNSKEY 256 3 5 AwEAAb/riVUjNfP1to3wkJyul0MjwiPo jFgFmMiLj1KIKeVIYCIRNx01Q1we5M17 GQFInCXXyTyjCYJfwkL0Xe7ma6m2pHfE MkOiDl42rsgrmkShxPEvZMd5vpT+RyQW Qh26TJ42MRoCJSt6XNeFLXRyjfRcDt7Z xYD3bHNeyaDuUUGt
+rhybar.cz. 600 IN DNSKEY 256 3 5 AwEAAcrTMVXwOcFCGKtXwdt4XATP43qU 96IryyqiZ0oPtuHEEBCikuQDuJhRjNAV 4DYvR6fb/suAnd91EVNgHHTXUlAWwmJR rqIwZ6VuGaZqVG+NJh1Okif7CL8no2Z4 7j6I3HH3pyzrYH2oQVyr64O/8BV2jrk8 RteeEqa7V7gcrFfJ
+rhybar.cz. 600 IN DNSKEY 257 3 5 AwEAAeKle4K3bxJb4k9sMhdm6BmpRK2r ISAGh0egMSXgOlQnU+3TLQ0aH1th7ejZ nn6Zdkeo8MRXDxLkgp1rUSsRM1Q2SmLJ haat7L15qHmj+vCk5IuSIpAdaRsqOKxH lT6a/LWGwGvDIVxY6J9sXaJ4SInflZpa 5wZUCrhDKvpo0hAzNfoK/aFApzZGaAGA LYx6YpbG+SBW2K+s92eyoJCCrQQ+Nata 41l7K6RFAYjP+g3Kp95McNm3xlBve171 u9FUZNUuN2Rn25oEtHHlK9NcHNqWvFJ3 VmXcA6CkGrBPV6vOAwwUtPDSWSZbdolS 69092ZWYTlOJw6g0LVI2feMMrok=
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+rhybar.cz. IN A
+SECTION AUTHORITY
+rhybar.cz. 600 IN SOA a.ns.nic.cz. hostmaster.nic.cz. 2199091609 10800 3600 1209600 7200
+rhybar.cz. 600 IN RRSIG SOA 5 2 600 20081030080058 20080930080058 5172 rhybar.cz. XfQgQHW5sDA+uPzC3L1lE8Etc57iH9/6 AqC8T4Fz+J1PIbiMZKHZrAxgj10dC8xd 6NTjNe3wBPALibRRLo8pe7+XZVmw1Vz4 bCZ93MJ5qeaiZ2IbfsQoqzKtgAPP3HzE 5CYRpkktAXsSLo23Ii9/jS82RouISd0r Bc5WmHYwPRo=
+rhybar.cz. 7200 IN RRSIG NSEC 5 2 7200 20081030080058 20080930080058 5172 rhybar.cz. Xv8ZkTfbfXkJj4FHMBrbIt7afauxnhOS OB6dxwxbhYV1q3wV9vlkUutNoWbChBRu UQVn6f2nCLQ63Zif6MLFKMWHgf91uRby w5JX0IOXbrOyW6sAAUggavNsJcfNpD19 SVRMCRZmIQQ/j8ft5+t703babL+iOiD/ tSbRgZnFpkU=
+rhybar.cz. 7200 IN NSEC www.rhybar.cz. NS SOA RRSIG NSEC DNSKEY
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+www.rhybar.cz. IN A
+SECTION ANSWER
+www.rhybar.cz. 600 IN A 217.31.205.55
+www.rhybar.cz. 600 IN RRSIG A 5 3 600 20081030080058 20080930080058 5172 rhybar.cz. XVkut4l9mw2MhodZFIOD2L57AU2u+I6w GVlK1fr6w5locFC5NIe8ukw79jYdOCH3 WwFgSMscumIz1sGqRPrN/CrhXiU0ymFG Fju9x/k10lv6SGS6lslgnZluet04Cyib GQ2HBnwTx7qK3j+bNzxKLvjpn7DY9f+Y KB8F2FtwNOc=
+ENTRY_END
+
+; end of domain cz.: servers ?.ns.nic.cz.
+RANGE_END
+
+
+; first two steps need to be commented out if you want to reproduce repeated
+; => querying: '2001:dc3::35' score: 93 zone cut: '.' m12n: '.' type: 'DS' proto: 'udp'
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD CD DO
+SECTION QUESTION
+rhybar.cz. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA CD NOERROR
+SECTION QUESTION
+rhybar.cz. IN A
+SECTION AUTHORITY
+rhybar.cz. 600 IN SOA a.ns.nic.cz. hostmaster.nic.cz. 2199091609 10800 3600 1209600 7200
+rhybar.cz. 600 IN RRSIG SOA 5 2 600 20081030080058 20080930080058 5172 rhybar.cz. XfQgQHW5sDA+uPzC3L1lE8Etc57iH9/6AqC8T4Fz+J1PIbiMZKHZrAxg j10dC8xd6NTjNe3wBPALibRRLo8pe7+XZVmw1Vz4bCZ93MJ5qeaiZ2Ib fsQoqzKtgAPP3HzE5CYRpkktAXsSLo23Ii9/jS82RouISd0rBc5WmHYw PRo=
+rhybar.cz. 7200 IN NSEC www.rhybar.cz. NS SOA RRSIG NSEC DNSKEY
+rhybar.cz. 7200 IN RRSIG NSEC 5 2 7200 20081030080058 20080930080058 5172 rhybar.cz. Xv8ZkTfbfXkJj4FHMBrbIt7afauxnhOSOB6dxwxbhYV1q3wV9vlkUutN oWbChBRuUQVn6f2nCLQ63Zif6MLFKMWHgf91uRbyw5JX0IOXbrOyW6sA AUggavNsJcfNpD19SVRMCRZmIQQ/j8ft5+t703babL+iOiD/tSbRgZnF pkU=
+ENTRY_END
+
+STEP 20 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+rhybar.cz. IN A
+ENTRY_END
+
+STEP 21 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH flags rcode question answer
+REPLY QR RD RA SERVFAIL
+SECTION QUESTION
+rhybar.cz. IN A
+SECTION ANSWER
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/world_cz_turris_api.rpl b/tests/integration/deckard/sets/resolver/world_cz_turris_api.rpl
new file mode 100644
index 0000000..a411798
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/world_cz_turris_api.rpl
@@ -0,0 +1,325 @@
+do-ip4: no
+
+val-override-date: 20170213100700
+trust-anchor: ". 172800 IN DS 19036 8 2 49aac11d7b6f6446702e54a1607371607a1a41855200fd2ce1cdde32f24e8fb5"
+stub-addr: 2001:dc3::35
+CONFIG_END
+
+SCENARIO_BEGIN api.turris.cz A/AAAA sanity check
+
+RANGE_BEGIN 0 1000
+ ADDRESS 192.33.4.12
+ ADDRESS 2001:500:2d::d
+ ADDRESS 2001:dc3::35
+ ADDRESS 192.36.148.17
+ ADDRESS 2001:500:12::d0d
+ ADDRESS 192.203.230.10
+ ADDRESS 199.7.83.42
+ ADDRESS 198.97.190.53
+ ADDRESS 2001:500:84::b
+ ADDRESS 2001:500:2::c
+ ADDRESS 2001:7fd::1
+ ADDRESS 193.0.14.129
+ ADDRESS 202.12.27.33
+ ADDRESS 192.58.128.30
+ ADDRESS 192.5.5.241
+ ADDRESS 2001:7fe::53
+ ADDRESS 198.41.0.4
+ ADDRESS 2001:500:2f::f
+ ADDRESS 199.7.91.13
+ ADDRESS 192.112.36.4
+ ADDRESS 2001:500:9f::42
+ ADDRESS 192.228.79.201
+ ADDRESS 2001:503:c27::2:30
+ ADDRESS 2001:500:1::53
+ ADDRESS 2001:503:ba3e::2:30
+ ADDRESS 2001:500:a8::e
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. 518400 IN NS a.root-servers.net.
+. 518400 IN NS b.root-servers.net.
+. 518400 IN NS c.root-servers.net.
+. 518400 IN NS d.root-servers.net.
+. 518400 IN NS e.root-servers.net.
+. 518400 IN NS f.root-servers.net.
+. 518400 IN NS g.root-servers.net.
+. 518400 IN NS h.root-servers.net.
+. 518400 IN NS i.root-servers.net.
+. 518400 IN NS j.root-servers.net.
+. 518400 IN NS k.root-servers.net.
+. 518400 IN NS l.root-servers.net.
+. 518400 IN NS m.root-servers.net.
+. 518400 IN RRSIG NS 8 0 518400 20170226050000 20170213040000 61045 . X7mYRt9jWw1QDQPQNcFehtDLtWX8MnxE MPF8bhuH8pFhd2cEBNu3X2j9eYt/z76B PAzoblrdW5vvfD4ZEnInjp486i4HPpFQ ZtrfZ1Lbu/wwOZ0cjxE56xZuBRQZ0xUk /pzTYGDwpAEWgOOYlSCVq2v6JVIWgpgW WD3qn43QXEhpuTSi2Xp7K4TKp5dlh7wy dbuQ1BjI0mDIqZ7dRGKX2va3sVMNypsF HQsPTnooTCIWKu+zp0/NXo2XnBgdohJF xCrwcAuuPY3f6FAOAhmTmThNFvmE/2D8 7T1sLtJhGfMt7BCTQ01hKu76MOQL3Xfz E2LmzaTHj9w9oHUEoIXJEg==
+SECTION ADDITIONAL
+a.root-servers.net. 518400 IN A 198.41.0.4
+a.root-servers.net. 518400 IN AAAA 2001:503:ba3e::2:30
+b.root-servers.net. 518400 IN A 192.228.79.201
+b.root-servers.net. 518400 IN AAAA 2001:500:84::b
+c.root-servers.net. 518400 IN A 192.33.4.12
+c.root-servers.net. 518400 IN AAAA 2001:500:2::c
+d.root-servers.net. 518400 IN A 199.7.91.13
+d.root-servers.net. 518400 IN AAAA 2001:500:2d::d
+e.root-servers.net. 518400 IN A 192.203.230.10
+e.root-servers.net. 518400 IN AAAA 2001:500:a8::e
+f.root-servers.net. 518400 IN A 192.5.5.241
+f.root-servers.net. 518400 IN AAAA 2001:500:2f::f
+g.root-servers.net. 518400 IN A 192.112.36.4
+g.root-servers.net. 518400 IN AAAA 2001:500:12::d0d
+h.root-servers.net. 518400 IN A 198.97.190.53
+h.root-servers.net. 518400 IN AAAA 2001:500:1::53
+i.root-servers.net. 518400 IN A 192.36.148.17
+i.root-servers.net. 518400 IN AAAA 2001:7fe::53
+j.root-servers.net. 518400 IN A 192.58.128.30
+j.root-servers.net. 518400 IN AAAA 2001:503:c27::2:30
+k.root-servers.net. 518400 IN A 193.0.14.129
+k.root-servers.net. 518400 IN AAAA 2001:7fd::1
+l.root-servers.net. 518400 IN A 199.7.83.42
+l.root-servers.net. 518400 IN AAAA 2001:500:9f::42
+m.root-servers.net. 518400 IN A 202.12.27.33
+m.root-servers.net. 518400 IN AAAA 2001:dc3::35
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+. IN DNSKEY
+SECTION ANSWER
+. 172800 IN RRSIG DNSKEY 8 0 172800 20170303000000 20170210000000 19036 . KHz7GVvg5DxUv70bUhSjRy1JO5soL+h6 M08g8bSKecd+4NmZI87Sn20puZNRuiAS bnG63i89Z2S45NBAR8KtqB6N5CrRhLhf xZcRo5k3Ts6zsC1EJ58upPKzFtu/sJBs PDjcRJJKbXlB4hLukQwVhn/MbsXxZdZG I57WoLFxbbR49NlFJrlrbTi2gieRR1SC LfT9aiBGsJA3T4jXap9FIsikNf1DJA8H cnQTW7hFi8l/O2ni2hbjsIE4S3GRTMyp qDR/s7piy/qukfWwSknk6YZTbzld6Zgb ZK+oOhRgj/W6XW78bJl0onov0F1wD0NQ sec+sk2P+JNMc4xgvQmn9g==
+. 172800 IN DNSKEY 256 3 8 AwEAAYvgWbYkpeGgdPKaKTJU3Us4YSTR gy7+dzvfArIhi2tKoZ/WR1Dfw883SOU6 Uw7tpVRkLarN0oIMK/xbOBD1DcXnyfEl BwKsz4sVVWmfyr/x+igD/UjrcJ5zEBUr UmVtHyjar7ccaVc1/3ntkhZjI1hcungA lOhPhHlkMeX+5Azx6GdX//An5OgrdyH3 o/JmOPMDX1mt806JI/hf0EwAp1pBwo5e 8SrSuR1tD3sgNjr6IzCdrKSgqi92z49z cdis3EaY199WFW60DCS7ydu++T5Xa+Gy Ow1quagwf/JUC/mEpeBQYWrnpkBbpDB3 sy4+P2i8iCvavehbRyVm9U0MlIc=
+. 172800 IN DNSKEY 257 3 8 AwEAAagAIKlVZrpC6Ia7gEzahOR+9W29 euxhJhVVLOyQbSEW0O8gcCjFFVQUTf6v 58fLjwBd0YI0EzrAcQqBGCzh/RStIoO8 g0NfnfL2MTJRkxoXbfDaUeVPQuYEhg37 NZWAJQ9VnMVDxP/VHL496M/QZxkjf5/E fucp2gaDX6RS6CXpoY68LsvPVjR0ZSwz z1apAzvN9dlzEheX7ICJBBtuA6G3LQpz W5hOA2hzCTMjJPJ8LbqF6dsV6DoBQzgu l0sGIcGOYl7OyQdXfZ57relSQageu+ip AdTTJ25AsRTAoub8ONGcLmqrAmRLKBP1 dfwhYB4N7knNnulqQxA+Uk1ihz0=
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+cz. IN DS
+SECTION ANSWER
+cz. 86400 IN DS 54576 10 2 397e50c85ede9cde33f363a9e66fd1b216d788f8dd438a57a423a386869c8f06
+cz. 86400 IN RRSIG DS 8 1 86400 20170226050000 20170213040000 61045 . GozD7iz2HauQt8xFZzS3ednnBCXLdwAS edCXa5mIvbDARxYzEaC6/+XcgBXu26h0 pMyxGcikiifIurQkrzEBtGa/30yiIegy FDXronn44ni5s1lhRtMmFwBYptGDZo15 /g2uDynqfifMGhMbU/IlQJW6QWPRdxS7 bKm4wj/RtE38+CcsZ6fHudvKDJV9xBip 4hqOuu3IdAcrr64OPIJxuwOhXz+NLGEN bDo7tWpKp/vHx5PJTl3SRilxHVTx4f94 FLr2VijkqsuYmG+pYMj6hwPy56/5whaW tP2jLDot0cihVy5229YIf1S4n7zcR+XP 8wOVGu+WQa5wbX4ONucqmg==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY NOERROR QR DO
+SECTION QUESTION
+cz. IN NS
+SECTION AUTHORITY
+cz. 172800 IN NS d.ns.nic.cz.
+cz. 172800 IN NS b.ns.nic.cz.
+cz. 172800 IN NS c.ns.nic.cz.
+cz. 172800 IN NS a.ns.nic.cz.
+cz. 86400 IN DS 54576 10 2 397e50c85ede9cde33f363a9e66fd1b216d788f8dd438a57a423a386869c8f06
+cz. 86400 IN RRSIG DS 8 1 86400 20170226050000 20170213040000 61045 . GozD7iz2HauQt8xFZzS3ednnBCXLdwAS edCXa5mIvbDARxYzEaC6/+XcgBXu26h0 pMyxGcikiifIurQkrzEBtGa/30yiIegy FDXronn44ni5s1lhRtMmFwBYptGDZo15 /g2uDynqfifMGhMbU/IlQJW6QWPRdxS7 bKm4wj/RtE38+CcsZ6fHudvKDJV9xBip 4hqOuu3IdAcrr64OPIJxuwOhXz+NLGEN bDo7tWpKp/vHx5PJTl3SRilxHVTx4f94 FLr2VijkqsuYmG+pYMj6hwPy56/5whaW tP2jLDot0cihVy5229YIf1S4n7zcR+XP 8wOVGu+WQa5wbX4ONucqmg==
+SECTION ADDITIONAL
+a.ns.nic.cz. 172800 IN A 194.0.12.1
+a.ns.nic.cz. 172800 IN AAAA 2001:678:f::1
+b.ns.nic.cz. 172800 IN A 194.0.13.1
+b.ns.nic.cz. 172800 IN AAAA 2001:678:10::1
+c.ns.nic.cz. 172800 IN A 194.0.14.1
+c.ns.nic.cz. 172800 IN AAAA 2001:678:11::1
+d.ns.nic.cz. 172800 IN A 193.29.206.1
+d.ns.nic.cz. 172800 IN AAAA 2001:678:1::1
+ENTRY_END
+RANGE_END
+
+RANGE_BEGIN 0 1000
+ ADDRESS 194.0.14.1
+ ADDRESS 2001:678:11::1
+ ADDRESS 2001:678:1::1
+ ADDRESS 193.29.206.1
+ ADDRESS 2001:678:f::1
+ ADDRESS 2001:678:10::1
+ ADDRESS 194.0.13.1
+ ADDRESS 194.0.12.1
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+cz. IN NS
+SECTION ANSWER
+cz. 18000 IN NS a.ns.nic.cz.
+cz. 18000 IN NS b.ns.nic.cz.
+cz. 18000 IN NS c.ns.nic.cz.
+cz. 18000 IN NS d.ns.nic.cz.
+cz. 18000 IN RRSIG NS 10 1 18000 20170220104540 20170206203958 58211 cz. NNzA115UZfT3uOGUEXJkDqoqKGXwIa3V /PbeHBh39FLO6KRDD9Isy9R6+Jw4Y1v9 9ca5l9eCgXqjAJ9soEqGLBqx+SB8LBNx XDjOS46Ewdc48+KRCqQku5NxsD+xs/hD Kj0/9ck1qdBPJd+547KBxZ+wIPSBvZWL DjhappBGlgw=
+SECTION ADDITIONAL
+a.ns.nic.cz. 18000 IN A 194.0.12.1
+a.ns.nic.cz. 18000 IN AAAA 2001:678:f::1
+b.ns.nic.cz. 18000 IN A 194.0.13.1
+b.ns.nic.cz. 18000 IN AAAA 2001:678:10::1
+d.ns.nic.cz. 18000 IN A 193.29.206.1
+d.ns.nic.cz. 18000 IN AAAA 2001:678:1::1
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+cz. IN DNSKEY
+SECTION ANSWER
+cz. 18000 IN RRSIG DNSKEY 10 1 18000 20170220000000 20170206000000 54576 cz. JU9BdCRGVaWiL+cwmzhfurOd2tMHX3fi DweYGPPnHCUx10BtVszJ5oM/1aphMIPa 72Z1Vk681PpTsGAGgRV1uRhsJ+Agawkd P/KjjSzAot+/oWcBl+wdQfLT5E50SbgC kvIHbexSd60BwMyzS8pFuRjYkC+MoGDg g+vLq8k64AWqB5zWeaC1y4C0kolAwBSo znR1xj1bA+CbdVCkucajBndgct5AHJM4 eyN/o9Qhg3RNUFl9WJ6f8AaewZfB/9fN w8+vaxAixjy99LI0mijONZf9E3FFcDq5 qRuLUcIRB+1HzJ2ZTnj6BP8KmSQyj/Ro y/r9jP0L1v59aE5M6LfZAg==
+cz. 18000 IN RRSIG DNSKEY 10 1 18000 20170226022139 20170213084011 58211 cz. VSe3d54BxyxLtg/w4NWhbx5hYu4yC5WC sRi3oXE/042zoBU6ijJyl/ei1zk4x/7o S2PKunCE2SUscFG6othKoikDERM9YN3T gpv+GC4xe4llnB5dCqHSwwFApfZQnrzV AKiVFLGMbeME+R07r2vh4L9zEzFx2poV WMAii6LsB5E=
+cz. 18000 IN DNSKEY 256 3 10 AwEAAdWL2Br92Vx0dLEOOB8y02ss8LtK IyGlLJ2ymJ02WqR3AAEEZN0fNPKF77kd KsjlG8DlzmSIOR12aa9EhpXqyHOwWI0k HOMJVnn6ZKFIAl71JP/dYIcshYUxKZZM e+zEAUrVtzlLVDtM6cDOPDuBNa1ujYec 3eJl9IpqeUEG6gAH
+cz. 18000 IN DNSKEY 257 3 10 AwEAAay0hi4HN2r/BqMQTpIPIVDyjmyF +9ZWvr5Lewx+q+947o/GrRv4FGFfkZxf 9CFfYVUf0jG5Yq4i06pGVNwJl81HS9Ux 2oeHRXUvgtLnl5HeRVLL+zgI5byx9HSN r4bPO8ZEn5OjoayhkNyGSFr4VWrzQk/K 02vLP4d1cCEzUQy30eyZto2/tG5ZwCU/ iRkS1PJOcOW98hiFIfFDZv1XjbEpqEYh T2PATs6rt+BKwSHKGISmg1PNdg+y0rIt emYMWr1f9BGAdtTWoPCPCYPjOZMPoIyA 4tMscD+ww54Jf/QNoHccY4hO1yHiuAXG 7SUn8jo0IKQ9W7JJxES0aqFCX/0=
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+turris.cz. IN NS
+SECTION ANSWER
+turris.cz. 1800 IN NS a.ns.nic.cz.
+turris.cz. 1800 IN NS b.ns.nic.cz.
+turris.cz. 1800 IN NS d.ns.nic.cz.
+turris.cz. 1800 IN RRSIG NS 13 2 1800 20170221145034 20170207145034 49237 turris.cz. ls7jS7uS5Oiom5djEnUrgeY0B+RdgsAG nzq5NqmnwdQBFmBm7RZNPoboBNC3vA+L pkTgNkLMURgoiZzaRnGsSA==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+turris.cz. IN DS
+SECTION ANSWER
+turris.cz. 18000 IN DS 54959 13 2 afda82e687ffc58d759824274f3c3eb007eea1e46f6108886ec0fa979bfd78c3
+turris.cz. 18000 IN RRSIG DS 10 2 18000 20170225151104 20170213084011 58211 cz. mPn0h45GRfOpPRbFC7R4o1mpenSgLIZ/ pbHqqH8Fz9dyVnAow7ug9XGjhzPgiAj4 X0gG+JTb3TRxsI+FFKUeBJL+/3N392Xf zPEMbtnLupdRQRhfcCc3iGbrUli6b99z E4BAfI+g/jyR/IgRqpJyxsZjuVTcdCX8 nXCYopt/WZY=
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+turris.cz. IN DNSKEY
+SECTION ANSWER
+turris.cz. 1800 IN RRSIG DNSKEY 13 2 1800 20170221145034 20170207145034 54959 turris.cz. FSqPyjAbBJY6xppLOSWj3hLUaiOGnbp4 s8utvSASyFeY1lBF+SmhOTWktIa8kMyU lHUJZUr25yDNcosb5ri6oQ==
+turris.cz. 1800 IN DNSKEY 256 3 13 3TQfQFOmvkZdZXMvK7l2nFo7UkQ48KU9 CNmx3HQOvmMS+tKyQZhTWfCFD0Yp/mSv s622xQS8qEdNbaBazXDnXg==
+turris.cz. 1800 IN DNSKEY 257 3 13 KDAJfPGWgvNAEHUMzmmSa+c3gHfoGIsX nhIO1iAYGTAyVBo+CLTyIk3wxDtt4Yn3 eCrCiYsEAHBJgQvA3pwJ8w==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+api.turris.cz. IN A
+SECTION ANSWER
+api.turris.cz. 1800 IN A 217.31.192.101
+api.turris.cz. 1800 IN RRSIG A 13 3 1800 20170221145034 20170207145034 49237 turris.cz. K78pE5gKDt9p+g9rIKXB52Ez2PuFkgum ezA9+W9JNwslrCaCQ3QdfAXd0GLwjgs7 Z9BavCCAeRPpvxDLVCDjqg==
+SECTION AUTHORITY
+turris.cz. 1800 IN NS d.ns.nic.cz.
+turris.cz. 1800 IN NS b.ns.nic.cz.
+turris.cz. 1800 IN NS a.ns.nic.cz.
+turris.cz. 1800 IN RRSIG NS 13 2 1800 20170221145034 20170207145034 49237 turris.cz. ls7jS7uS5Oiom5djEnUrgeY0B+RdgsAG nzq5NqmnwdQBFmBm7RZNPoboBNC3vA+L pkTgNkLMURgoiZzaRnGsSA==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY NOERROR QR AA DO
+SECTION QUESTION
+api.turris.cz. IN AAAA
+SECTION ANSWER
+api.turris.cz. 1800 IN AAAA 2001:1488:ac15:ff80::101
+api.turris.cz. 1800 IN RRSIG AAAA 13 3 1800 20170221145034 20170207145034 49237 turris.cz. bg+Pcv1wqjAQ63Abe2xW/+BxAEJZlHPW 01ez/I4zcnSwQpltaJNZ6oR4Jbnks43c 9TRQs5qBh2ZjaTBiRmcQ8A==
+SECTION AUTHORITY
+turris.cz. 1800 IN NS a.ns.nic.cz.
+turris.cz. 1800 IN NS b.ns.nic.cz.
+turris.cz. 1800 IN NS d.ns.nic.cz.
+turris.cz. 1800 IN RRSIG NS 13 2 1800 20170221145034 20170207145034 49237 turris.cz. ls7jS7uS5Oiom5djEnUrgeY0B+RdgsAG nzq5NqmnwdQBFmBm7RZNPoboBNC3vA+L pkTgNkLMURgoiZzaRnGsSA==
+ENTRY_END
+
+RANGE_END
+
+
+; IPv6
+STEP 10 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+api.turris.cz. IN AAAA
+ENTRY_END
+
+STEP 11 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY RD RA QR
+SECTION QUESTION
+api.turris.cz. IN AAAA
+SECTION ANSWER
+api.turris.cz. 1800 IN AAAA 2001:1488:ac15:ff80::101
+ENTRY_END
+
+; do we have AD bit & RRSIGs in cache?
+STEP 20 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+api.turris.cz. IN AAAA
+ENTRY_END
+
+STEP 21 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY RD RA QR AD
+SECTION QUESTION
+api.turris.cz. IN AAAA
+SECTION ANSWER
+api.turris.cz. 1800 IN AAAA 2001:1488:ac15:ff80::101
+api.turris.cz. 1800 IN RRSIG AAAA 13 3 1800 20170221145034 20170207145034 49237 turris.cz. bg+Pcv1wqjAQ63Abe2xW/+BxAEJZlHPW 01ez/I4zcnSwQpltaJNZ6oR4Jbnks43c 9TRQs5qBh2ZjaTBiRmcQ8A==
+ENTRY_END
+
+; IPv4
+STEP 110 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+api.turris.cz. IN A
+ENTRY_END
+
+STEP 111 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY RD RA QR
+SECTION QUESTION
+api.turris.cz. IN A
+SECTION ANSWER
+api.turris.cz. 1800 IN A 217.31.192.101
+ENTRY_END
+
+; do we have AD bit & RRSIGs in cache?
+STEP 120 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+api.turris.cz. IN A
+ENTRY_END
+
+STEP 121 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY RD RA QR AD
+SECTION QUESTION
+api.turris.cz. IN A
+SECTION ANSWER
+api.turris.cz. 1800 IN A 217.31.192.101
+api.turris.cz. 1800 IN RRSIG A 13 3 1800 20170221145034 20170207145034 49237 turris.cz. K78pE5gKDt9p+g9rIKXB52Ez2PuFkgum ezA9+W9JNwslrCaCQ3QdfAXd0GLwjgs7 Z9BavCCAeRPpvxDLVCDjqg==
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/world_cz_vutbr_www.rpl b/tests/integration/deckard/sets/resolver/world_cz_vutbr_www.rpl
new file mode 100644
index 0000000..eddfbd0
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/world_cz_vutbr_www.rpl
@@ -0,0 +1,298 @@
+do-ip4: no
+
+; test with real world Internet data
+; attempt to resolve www.vutbr.cz. A leads to CNAME piranha.ro.vutbr.cz.
+; sub-trees vutbr.cz and ro.vutbr.cz. are in separate zones
+; hosted on the same servers with different DNSKEYs
+
+val-override-date: 20170124180319
+trust-anchor: ". 172800 IN DS 19036 8 2 49aac11d7b6f6446702e54a1607371607a1a41855200fd2ce1cdde32f24e8fb5"
+stub-addr: 2001:dc3::35
+CONFIG_END
+
+SCENARIO_BEGIN www.vutbr.cz. CNAME kresd issue #130
+
+; DNS root ; M.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 2001:dc3::35
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA DO NOERROR
+SECTION QUESTION
+. IN DNSKEY
+SECTION ANSWER
+. 16567 IN DNSKEY 257 3 8 AwEAAagAIKlVZrpC6Ia7gEzahOR+9W29euxhJhVVLOyQbSEW0O8gcCjF FVQUTf6v58fLjwBd0YI0EzrAcQqBGCzh/RStIoO8g0NfnfL2MTJRkxoX bfDaUeVPQuYEhg37NZWAJQ9VnMVDxP/VHL496M/QZxkjf5/Efucp2gaD X6RS6CXpoY68LsvPVjR0ZSwzz1apAzvN9dlzEheX7ICJBBtuA6G3LQpz W5hOA2hzCTMjJPJ8LbqF6dsV6DoBQzgul0sGIcGOYl7OyQdXfZ57relS Qageu+ipAdTTJ25AsRTAoub8ONGcLmqrAmRLKBP1dfwhYB4N7knNnulq QxA+Uk1ihz0=
+. 16567 IN DNSKEY 256 3 8 AwEAAYvgWbYkpeGgdPKaKTJU3Us4YSTRgy7+dzvfArIhi2tKoZ/WR1Df w883SOU6Uw7tpVRkLarN0oIMK/xbOBD1DcXnyfElBwKsz4sVVWmfyr/x +igD/UjrcJ5zEBUrUmVtHyjar7ccaVc1/3ntkhZjI1hcungAlOhPhHlk MeX+5Azx6GdX//An5OgrdyH3o/JmOPMDX1mt806JI/hf0EwAp1pBwo5e 8SrSuR1tD3sgNjr6IzCdrKSgqi92z49zcdis3EaY199WFW60DCS7ydu+ +T5Xa+GyOw1quagwf/JUC/mEpeBQYWrnpkBbpDB3sy4+P2i8iCvavehb RyVm9U0MlIc=
+. 16567 IN RRSIG DNSKEY 8 0 172800 20170201000000 20170111000000 19036 . Sh+EpofvZgk3J9szMD2B94FxFgyIUKz3hkbCjgWSTqPQyhqNgqVU8QlS EtOo8YLmS4AX98eit5Gmmb2ObpkGoXBmAzu5w/Qt5WsGsWzLQhYrsy9s lDmFQ2JKUoCyfdwqhlJ8VxjzdFdMUiVl+/GPnv4yjxjM8Ke3VAtBkn6n BO7JkcxxOfcgZdZ4MuvSr40K/SenZE+JlLLL1LF4TMCGqaZTTdOx6kFF KSSgy2AS884htWcK0tnwRc630g6nAI2wdvjlRLBeisbfXanI4v8iiPyT FnMmnV7wJGWJ4gtRJ0UH3u5RWXUPZ+s1tKytk3slXbLyQ9xkEDveuD+h b659gQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR DO NOERROR
+SECTION QUESTION
+cz. IN NS
+SECTION AUTHORITY
+cz. 172800 IN NS d.ns.nic.cz.
+cz. 172800 IN NS a.ns.nic.cz.
+cz. 172800 IN NS c.ns.nic.cz.
+cz. 172800 IN NS b.ns.nic.cz.
+cz. 86400 IN DS 54576 10 2 397E50C85EDE9CDE33F363A9E66FD1B216D788F8DD438A57A423A386 869C8F06
+cz. 86400 IN RRSIG DS 8 1 86400 20170202170000 20170120160000 61045 . ig2BBmA1kOuTqhVogqLciH40Ina7BCrG/fcaNARSWoaFHGOcC/7KsBZO uMttn/hKDJkH3RPsed2Oswl9bXZ+zrhjeXluUqC0zmsUJDBkS+AkiFJL HCpMSIZaXu/w1ZMADGfyQXl7XWCRbl+eyXi2eTG0SdLtRHNhm3CGJP3C xjzVuOTr9oPEyL0U81jhhlJPCFe8xDD441wLLzpEuVX8VP9N2S1QnIjO BhCEE9OTkPgpS7fMPEl0Yq2gfpRl+DCw1Dd0VB3Hh5M3hmrXuFqNYZQK b0JqDFGYhzvcpUs3EiB9IG7rJt51n6pxCTek1M2w+s6mLYzawVfq+b1Q uQD98A==
+SECTION ADDITIONAL
+a.ns.nic.cz. 172800 IN A 194.0.12.1
+b.ns.nic.cz. 172800 IN A 194.0.13.1
+c.ns.nic.cz. 172800 IN A 194.0.14.1
+d.ns.nic.cz. 172800 IN A 193.29.206.1
+a.ns.nic.cz. 172800 IN AAAA 2001:678:f::1
+b.ns.nic.cz. 172800 IN AAAA 2001:678:10::1
+c.ns.nic.cz. 172800 IN AAAA 2001:678:11::1
+d.ns.nic.cz. 172800 IN AAAA 2001:678:1::1
+ENTRY_END
+; end of M.ROOT-SERVERS.NET.
+RANGE_END
+
+
+; domains: cz. ; ?.ns.nic.cz.
+RANGE_BEGIN 0 100
+ ADDRESS 194.0.12.1
+ ADDRESS 194.0.13.1
+ ADDRESS 194.0.14.1
+ ADDRESS 193.29.206.1
+ ADDRESS 2001:678:f::1
+ ADDRESS 2001:678:10::1
+ ADDRESS 2001:678:11::1
+ ADDRESS 2001:678:1::1
+
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+cz. IN DNSKEY
+SECTION ANSWER
+cz. 18000 IN DNSKEY 256 3 10 AwEAAc9e2YFnG56xtTXu42GLGAkwsrFOBBwOZphNat7HQdBmfi0CbmDf oywCUsaSkObNmm+Zu9MYLNJDHsD+vxsZbtHClpYaSEhMEmHrbnj0BMPV A6hwY6YDGFhKudJ62RmB/rmhQ3iwmICsEdRn2w5fu1rHZv8UJOUMkeWd 6GA48mW3
+cz. 18000 IN DNSKEY 256 3 10 AwEAAdWL2Br92Vx0dLEOOB8y02ss8LtKIyGlLJ2ymJ02WqR3AAEEZN0f NPKF77kdKsjlG8DlzmSIOR12aa9EhpXqyHOwWI0kHOMJVnn6ZKFIAl71 JP/dYIcshYUxKZZMe+zEAUrVtzlLVDtM6cDOPDuBNa1ujYec3eJl9Ipq eUEG6gAH
+cz. 18000 IN DNSKEY 257 3 10 AwEAAay0hi4HN2r/BqMQTpIPIVDyjmyF+9ZWvr5Lewx+q+947o/GrRv4 FGFfkZxf9CFfYVUf0jG5Yq4i06pGVNwJl81HS9Ux2oeHRXUvgtLnl5He RVLL+zgI5byx9HSNr4bPO8ZEn5OjoayhkNyGSFr4VWrzQk/K02vLP4d1 cCEzUQy30eyZto2/tG5ZwCU/iRkS1PJOcOW98hiFIfFDZv1XjbEpqEYh T2PATs6rt+BKwSHKGISmg1PNdg+y0rItemYMWr1f9BGAdtTWoPCPCYPj OZMPoIyA4tMscD+ww54Jf/QNoHccY4hO1yHiuAXG7SUn8jo0IKQ9W7JJ xES0aqFCX/0=
+cz. 18000 IN RRSIG DNSKEY 10 1 18000 20170127000000 20170120000000 54576 cz. Fdl//hMdLoZq8//gLt/+3a7LfWqB5/psW9YR3AWNPQGfvrEAcKRBcah+ ikbSCmpAZ6j834xZP1zPd5xMoN33PGXf23iqcgjHvUn50Uq48KRBVYwU H885xNJBl/Po0N8STeG0WNZz2mbUbBbPCGN7CI5yl08usvqOvf2fV8+D 0m//+Fa1cWaqMXpHc6OnhWZ+BN4VdcxxwNbGhH2TZxyiGEMMscEGoIxn yL1pVY8T93LOMwQmuFJ71f8Scij3vYouW/mNuEma/UUZM1bEn8vR1UrP /6JTGPGTG+snHvCxiVtAxCNnqoIJDD+xuonpZLeKN5XU7UDMZPDTtSgX vtzjww==
+cz. 18000 IN RRSIG DNSKEY 10 1 18000 20170205002523 20170123080953 58211 cz. MZ6KTtQisTde4iOBH6oasl7bVrRM5ly7Yxdv2l+2gk1YYk4zX6L3m6oB P26SKi+fj8pM77775bRK7uCI9FlyqXa3MJclLU/GmnRANm6T4sSdz0zs F3FK4UfUmHnzdnWXWTnueDfIZr44yF1y1+4I3E96/9/nEYGO+xsifvIj iks=
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR DO NOERROR
+SECTION QUESTION
+vutbr.cz. IN NS
+SECTION AUTHORITY
+vutbr.cz. 18000 IN NS pipit.cis.vutbr.cz.
+vutbr.cz. 18000 IN NS rhino.cis.vutbr.cz.
+vutbr.cz. 18000 IN DS 5512 5 2 78510F9433A4D536A5B9099193E9D58EE5B5CF71F14D983B4DA2EB16 29CFA1E9
+vutbr.cz. 18000 IN RRSIG DS 10 2 18000 20170204213601 20170123080953 58211 cz. lXNBswz/r/1NY7VQq+BlisC+1yqFmUBIaF30L8XDAbiHLcj/AIj0dEy6 PlBlkEeDAi4W9DvR0jo9LjHvFFJLs54cuEEd3pHTdlw8x0dLd1X7Zkh7 cezfAt2EEqdux/ce/sc86lUKOpLnDtry2piWwVf2EqFg9NlW4cHTm78U gsY=
+SECTION ADDITIONAL
+pipit.cis.vutbr.cz. 18000 IN A 77.93.219.110
+rhino.cis.vutbr.cz. 18000 IN A 147.229.3.10
+pipit.cis.vutbr.cz. 18000 IN AAAA 2a01:430:120::4d5d:db6e
+rhino.cis.vutbr.cz. 18000 IN AAAA 2001:67c:1220:e000::93e5:30a
+ENTRY_END
+
+; end of domain cz.: servers ?.ns.nic.cz.
+RANGE_END
+
+
+; domains: vutbr.cz. + ro.vutbr.cz.
+; servers: pipit.cis.vutbr.cz. + rhino.cis.vutbr.cz. + shark.ro.vutbr.cz.
+; shark.ro.vutbr.cz. in fact serves both domains but is listed only in ro.vutbr.cz NS
+RANGE_BEGIN 0 100
+ ADDRESS 77.93.219.110
+ ADDRESS 147.229.3.10
+ ADDRESS 147.229.2.59
+ ADDRESS 2a01:430:120::4d5d:db6e
+ ADDRESS 2001:67c:1220:e000::93e5:30a
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA DO
+SECTION QUESTION
+vutbr.cz. IN NS
+SECTION ANSWER
+vutbr.cz. 28800 IN NS rhino.cis.vutbr.cz.
+vutbr.cz. 28800 IN NS pipit.cis.vutbr.cz.
+vutbr.cz. 28800 IN RRSIG NS 5 2 28800 20170216060902 20170117060902 39756 vutbr.cz. y6Jj5vfvdlLeecB/++/qyhjCzfnFJyY1sX1Ja+wV0ulq3laeCVV7ICXh PKG+CjHUu/nDOrzT9QJP4qxYDCANneI0yxI82XKhhoTN5O/TxyWH/DyT k8JarRoMooHv2RwKd8jtLIxvj1SaJ+AvlP0pOPraaVgbHtn1SJ4ubxQD cFc=
+SECTION ADDITIONAL
+pipit.cis.vutbr.cz. 86400 IN A 77.93.219.110
+pipit.cis.vutbr.cz. 86400 IN AAAA 2a01:430:120::4d5d:db6e
+rhino.cis.vutbr.cz. 86400 IN A 147.229.3.10
+rhino.cis.vutbr.cz. 86400 IN AAAA 2001:67c:1220:e000::93e5:30a
+pipit.cis.vutbr.cz. 86400 IN RRSIG A 5 4 86400 20170204080646 20170105080646 28257 cis.vutbr.cz. Cz9etHnEOQTzu+6rYJEqx/SQ1tQgPOCyf8HSj4KOsx89jtgiHNC6pep6 ZE0SphMGAs3jC/uGIhlaFNZ3i38OQIMuqwacbz+XZyW5bByvV3QZrhqh dFxMDfmPuNiCAT3crFpUkvVW1OE3YfGHzZGXX7JP5wb1b8A3X6Qih7fV +nQ=
+pipit.cis.vutbr.cz. 86400 IN RRSIG AAAA 5 4 86400 20170204080646 20170105080646 28257 cis.vutbr.cz. piafjh6my2fooZRrzwCu9RQ95gYaMQkhIkDaGX/fT6wXzSdmgFZkS1Nl EMIKdDCQaPrLGMG3p32ptMkAm4esPekeyNtLSMBtXwZyUkgEGn6h1QM2 Yr3TOo8cixfk5nmRRdlYadf5krLb8yI9exiqeymgEQLa1YNRz/bWArlX bn8=
+rhino.cis.vutbr.cz. 86400 IN RRSIG A 5 4 86400 20170204080646 20170105080646 28257 cis.vutbr.cz. X/tDf8e3JEV0LxiItfpQnBzeaRIq693VG8d30iCH4/1I0uqyCfxboWmm /CBpn9A8MCJu9NEEv+4+povNlfUfqi2yjsqJEVj8ztHxD4g9cc284Cv6 ySjxrSZ9axVqoaopEXujiTwwWJUFcgF6pxqyXVksW7sgKJrboM4VSlQD +Sw=
+rhino.cis.vutbr.cz. 86400 IN RRSIG AAAA 5 4 86400 20170204080646 20170105080646 28257 cis.vutbr.cz. T3Yf5PAkSeJtoOH90ea9zZBG9FC3iFhiCSerDn6d9up8GRfzxDsavYJC zQu+3vnOySySn+3TMzQSSFcWdJC2iO7ulaDGr177Gof9QJbKSVSMW7jt YDE2f4/R4Go3NZVwjk/HfpCInoR6pHNA1s/9hMnWtiVopmBdfzyd3/sW YOU=
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA DO
+SECTION QUESTION
+vutbr.cz. IN DNSKEY
+SECTION ANSWER
+vutbr.cz. 28800 IN DNSKEY 256 3 5 AwEAAfwRRuGjpt9v4fzuIWFA9MtGfxDrIKhoFA7DNq6B+iCOoQb6t0HZ I9lGDUSR5DRswDGP569NJ/uVD4tJxGnaK2SBQVxIu+bEP1Ouzk+O43iO 8odw50NBWetljjNDP32B3zHpgJRpxyEqzDQaQ6B4Zer6sDZm9wo5SVJe r9LjJV9p
+vutbr.cz. 28800 IN DNSKEY 257 3 5 AwEAAfhR+s/4SLZZNA+kD2u1UgYBUu+X3Avi60QCaE1o2STterM405s8 mWMWJOlZGtjjIky3TEMxQ0+ZtMbEeJu2wNDLdV/XglX+pJAjyy728WJH 4u2/gJR8ZWsEIc0Jwb4FjwmBiF2Koz0SGVvrzEZ9T1H7dHq2X6f8KzYB otJyrAIWr9tZi/9tHrngZJ5wXELmMPWCfEFapdQMoKWoNvzrMYFli17R Mz7gJzCmNxMRV8/WkjsNPgYsTKpsAT8qEsXiTN9987AIKPHvc5j+/njq +fTXdOqGVpIgSiso+qJMddEMBcu/MBBYVFOwRQe1ez2tMwIX7y5mwDvK 0wsmyRvHugfFuxSnfiJvQr05kSnj0wxD9s9LNhrF4PocrcYqnBN/lBx9 D6633jJ3zT3T5Foe/Vj9A/X7F2oN6FOkdwO+YSEUot980pJQut6DR22U P4bLakyDMiTdOQ31c/dRIoTsccxw+838pXFyEPgiqOHRSeN/w9km6BID cl+32Xq97kXSMQH6AxOUsx9/Mxdj7ISwbS4utaAWoP460+TMcnfJfWfB NEWhuFvnfB9l63ZjZToB2PUVhrTxRwKUlfMLegSJKoZfiae82kK1pN4x FYyquKSykm/oXsM2w4OQvpqGcTwAXzZ5s95J45f7PsCap0bscGKumxsH cDswWpUz/UVosIrr
+vutbr.cz. 28800 IN RRSIG DNSKEY 5 2 28800 20170216060902 20170117060902 5512 vutbr.cz. QHw07MAjA4NFi3On8zaMw/q4IuADXVp4TODfK5PHb8OUIX2Yy+bKLrSX /Cc9ClWUpE69x80F9dFEeRZGJiYOwstNQGQVeq/EKNytm1XmhS8cp3SW CYHBpLjZGPrlhvqPhWd0S4vqPNiD8hDzgFAgaCNfwXDDKXhF2/qtpQ0V pDnytMP6pNPLPMpF2hzaLfCMzABShxcEOAr7+KTbxbffOik4YneG8seu XDtBvCVjP8lJcSU+q+UbotLnjyOgn8vV8pliTNqcvRsJTdtvTlJKHu8B iLkFeCE1DpRhyrVT5zC9NSOcoIv7tau2NE2oUPgtRzK76el6i9L9LcSs G+59j02AINefpAtc6W2khmTnGthibeOy/F9FuFkXUy6AmqIdNszMAj++ 8Mzv3A1OHfsfpIS3tLmC4drhdSHr2ab0Pe0lYQq2a9FSeQzSk6s9gwwZ gMVPVQHbouyvn6BCHaRVDjTV8GPKlk3C8GNaHcHb1hAGSPpw3kqL41dd K92Un4tLIoOYomxUYoyMtyxxwddXyR7ivToUHF7e/yv8MACMEo72N9sf y4zLEqkL1mJ1pCp3csI1bKaaA/c7sqb7PX93iqvoY06k55Pd7kT+lAF1 7QvXGg4U1kDrwytQPyocN8wmsX3//CpWUD07v8fCUqKOcIrVNGnoPmPC PpNe3AtpJoE=
+vutbr.cz. 28800 IN RRSIG DNSKEY 5 2 28800 20170216060902 20170117060902 39756 vutbr.cz. CNDE7Ht7xm8Jo9tuOlJ8N9+vI/Htfpk53MI0HG7B1EZJws/yEV7YFOOL SIAt3rzu1OHjaxr4CG/baqGRPtsaWSBHuLSdSduivxXw8xiQcMKzP6Cz 7xhJkQZxzDJ4oO5L2K2zWHcAJ8lfP1/3NHHoH1p2RATLN5sI7ofQE//W +ck=
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA DO
+SECTION QUESTION
+www.vutbr.cz. IN A
+SECTION ANSWER
+www.vutbr.cz. 300 IN CNAME piranha.ro.vutbr.cz.
+www.vutbr.cz. 300 IN RRSIG CNAME 5 3 300 20170216060902 20170117060902 39756 vutbr.cz. 9B3UC5SOEw1+yKlYlOTINEuNq0Kdglywc5IYJwzeSzQ3ykptzZo3ABSy bYhTqImVkhm/4NFM9/4HWMHPDzTmrWS0mCI/ljCd/oe/PxW/uESvo4P5 EQzlcuH6xBzc1KdEFAJOSmRzFjj3vyK1QN3k/c+1y2oMFOYOR2oOzCw+ MIE=
+piranha.ro.vutbr.cz. 3600 IN A 147.229.2.90
+piranha.ro.vutbr.cz. 3600 IN RRSIG A 5 4 3600 20170222120032 20170123120032 12150 ro.vutbr.cz. Jz8bcAADQjCKTCcF70IK1aHGQlM4ukyN0myABlxoPaqid1mHX5jwR91b kdQmUAh2xDitlgRLbFjbUUgmjSPzQ5Qt7GAFUsVmqxvjbOLZjqHER1dh zmiWO0fDvvP647Osv3RiAP822rNUJcJrUBZU9LmeP05gwIHcpJrhdVBT b7I=
+SECTION AUTHORITY
+ro.vutbr.cz. 86400 IN NS shark.ro.vutbr.cz.
+ro.vutbr.cz. 86400 IN NS rhino.cis.vutbr.cz.
+ro.vutbr.cz. 86400 IN NS pipit.cis.vutbr.cz.
+ro.vutbr.cz. 86400 IN RRSIG NS 5 3 86400 20170222120032 20170123120032 12150 ro.vutbr.cz. HAQ8A+QNsS1WIXdW/fbT3jP+IxObBBvgUmvzsmJBXo8HMtnMAcuCQGmB 2JBQsQethQXsdyLnMK8to/5A9VRkqkAa7edxUoy7SdDi/mzGeLAVhF+5 kXSPD6t1vjiNdnIYAMpiOQbodCGxAnq6jnNyrjEzffdq3qw+5IkFNdG4 7Pw=
+SECTION ADDITIONAL
+rhino.cis.vutbr.cz. 83217 IN A 147.229.3.10
+rhino.cis.vutbr.cz. 83217 IN AAAA 2001:67c:1220:e000::93e5:30a
+shark.ro.vutbr.cz. 3600 IN A 147.229.2.59
+pipit.cis.vutbr.cz. 14794 IN A 77.93.219.110
+pipit.cis.vutbr.cz. 14794 IN AAAA 2a01:430:120::4d5d:db6e
+rhino.cis.vutbr.cz. 83217 IN RRSIG A 5 4 86400 20170204080646 20170105080646 28257 cis.vutbr.cz. X/tDf8e3JEV0LxiItfpQnBzeaRIq693VG8d30iCH4/1I0uqyCfxboWmm /CBpn9A8MCJu9NEEv+4+povNlfUfqi2yjsqJEVj8ztHxD4g9cc284Cv6 ySjxrSZ9axVqoaopEXujiTwwWJUFcgF6pxqyXVksW7sgKJrboM4VSlQD +Sw=
+rhino.cis.vutbr.cz. 83217 IN RRSIG AAAA 5 4 86400 20170204080646 20170105080646 28257 cis.vutbr.cz. T3Yf5PAkSeJtoOH90ea9zZBG9FC3iFhiCSerDn6d9up8GRfzxDsavYJC zQu+3vnOySySn+3TMzQSSFcWdJC2iO7ulaDGr177Gof9QJbKSVSMW7jt YDE2f4/R4Go3NZVwjk/HfpCInoR6pHNA1s/9hMnWtiVopmBdfzyd3/sW YOU=
+shark.ro.vutbr.cz. 3600 IN RRSIG A 5 4 3600 20170222120032 20170123120032 12150 ro.vutbr.cz. SmhgyF48yX/6yH7AdSmGX60NL/xaiKH/oAzB0rnPfQZ6j+UfV57ginVV lj798K9A8jjucUpqE8ua2mZ6/aOhpqlV2iI0CZXG44zOupsCY1/OXBDx YNetBcjoXDQCBQRLLLEUL5FerDVxqT74ngdLdKubwRdrB0TLQlvpBr+F Tc8=
+pipit.cis.vutbr.cz. 85923 IN RRSIG A 5 4 86400 20170204080646 20170105080646 28257 cis.vutbr.cz. Cz9etHnEOQTzu+6rYJEqx/SQ1tQgPOCyf8HSj4KOsx89jtgiHNC6pep6 ZE0SphMGAs3jC/uGIhlaFNZ3i38OQIMuqwacbz+XZyW5bByvV3QZrhqh dFxMDfmPuNiCAT3crFpUkvVW1OE3YfGHzZGXX7JP5wb1b8A3X6Qih7fV +nQ=
+pipit.cis.vutbr.cz. 85923 IN RRSIG AAAA 5 4 86400 20170204080646 20170105080646 28257 cis.vutbr.cz. piafjh6my2fooZRrzwCu9RQ95gYaMQkhIkDaGX/fT6wXzSdmgFZkS1Nl EMIKdDCQaPrLGMG3p32ptMkAm4esPekeyNtLSMBtXwZyUkgEGn6h1QM2 Yr3TOo8cixfk5nmRRdlYadf5krLb8yI9exiqeymgEQLa1YNRz/bWArlX bn8=
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA DO
+SECTION QUESTION
+ro.vutbr.cz. IN NS
+SECTION ANSWER
+ro.vutbr.cz. 86400 IN NS pipit.cis.vutbr.cz.
+ro.vutbr.cz. 86400 IN NS rhino.cis.vutbr.cz.
+ro.vutbr.cz. 86400 IN NS shark.ro.vutbr.cz.
+ro.vutbr.cz. 86400 IN RRSIG NS 5 3 86400 20170222120032 20170123120032 12150 ro.vutbr.cz. HAQ8A+QNsS1WIXdW/fbT3jP+IxObBBvgUmvzsmJBXo8HMtnMAcuCQGmB 2JBQsQethQXsdyLnMK8to/5A9VRkqkAa7edxUoy7SdDi/mzGeLAVhF+5 kXSPD6t1vjiNdnIYAMpiOQbodCGxAnq6jnNyrjEzffdq3qw+5IkFNdG4 7Pw=
+SECTION ADDITIONAL
+rhino.cis.vutbr.cz. 86400 IN A 147.229.3.10
+rhino.cis.vutbr.cz. 86400 IN AAAA 2001:67c:1220:e000::93e5:30a
+shark.ro.vutbr.cz. 3600 IN A 147.229.2.59
+pipit.cis.vutbr.cz. 86400 IN A 77.93.219.110
+pipit.cis.vutbr.cz. 86400 IN AAAA 2a01:430:120::4d5d:db6e
+rhino.cis.vutbr.cz. 86400 IN RRSIG A 5 4 86400 20170204080646 20170105080646 28257 cis.vutbr.cz. X/tDf8e3JEV0LxiItfpQnBzeaRIq693VG8d30iCH4/1I0uqyCfxboWmm /CBpn9A8MCJu9NEEv+4+povNlfUfqi2yjsqJEVj8ztHxD4g9cc284Cv6 ySjxrSZ9axVqoaopEXujiTwwWJUFcgF6pxqyXVksW7sgKJrboM4VSlQD +Sw=
+rhino.cis.vutbr.cz. 86400 IN RRSIG AAAA 5 4 86400 20170204080646 20170105080646 28257 cis.vutbr.cz. T3Yf5PAkSeJtoOH90ea9zZBG9FC3iFhiCSerDn6d9up8GRfzxDsavYJC zQu+3vnOySySn+3TMzQSSFcWdJC2iO7ulaDGr177Gof9QJbKSVSMW7jt YDE2f4/R4Go3NZVwjk/HfpCInoR6pHNA1s/9hMnWtiVopmBdfzyd3/sW YOU=
+shark.ro.vutbr.cz. 3600 IN RRSIG A 5 4 3600 20170222120032 20170123120032 12150 ro.vutbr.cz. SmhgyF48yX/6yH7AdSmGX60NL/xaiKH/oAzB0rnPfQZ6j+UfV57ginVV lj798K9A8jjucUpqE8ua2mZ6/aOhpqlV2iI0CZXG44zOupsCY1/OXBDx YNetBcjoXDQCBQRLLLEUL5FerDVxqT74ngdLdKubwRdrB0TLQlvpBr+F Tc8=
+pipit.cis.vutbr.cz. 86400 IN RRSIG A 5 4 86400 20170204080646 20170105080646 28257 cis.vutbr.cz. Cz9etHnEOQTzu+6rYJEqx/SQ1tQgPOCyf8HSj4KOsx89jtgiHNC6pep6 ZE0SphMGAs3jC/uGIhlaFNZ3i38OQIMuqwacbz+XZyW5bByvV3QZrhqh dFxMDfmPuNiCAT3crFpUkvVW1OE3YfGHzZGXX7JP5wb1b8A3X6Qih7fV +nQ=
+pipit.cis.vutbr.cz. 86400 IN RRSIG AAAA 5 4 86400 20170204080646 20170105080646 28257 cis.vutbr.cz. piafjh6my2fooZRrzwCu9RQ95gYaMQkhIkDaGX/fT6wXzSdmgFZkS1Nl EMIKdDCQaPrLGMG3p32ptMkAm4esPekeyNtLSMBtXwZyUkgEGn6h1QM2 Yr3TOo8cixfk5nmRRdlYadf5krLb8yI9exiqeymgEQLa1YNRz/bWArlX bn8=
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA DO
+SECTION QUESTION
+ro.vutbr.cz. IN DS
+SECTION ANSWER
+ro.vutbr.cz. 28800 IN DS 16627 5 2 1AEE56EAF9D01A51C8C524E55A7FAE0E27207911F0FA6126052CE5B3 39335FC8
+ro.vutbr.cz. 28800 IN DS 16627 5 1 BFDFD0FB1EDFCEBFB9ECB13C93F9CA65755217BA
+ro.vutbr.cz. 28800 IN RRSIG DS 5 3 28800 20170216060902 20170117060902 39756 vutbr.cz. OOJfGI14bRHqeWhRLMOa75pfHo+clR4rMJpvO3PPjmheownqy2awA7u3 xR5FJko7A6e+difoJdAWCMzN7x1qcrd1htOOKOc7wtcb+QC2JH8B/e0G 0gNPw2UKsFL1Qw9HQkSqxyIaCGg3nMLO1hh3AVccZadw2f/jLpAzw5/1 pLA=
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA DO
+SECTION QUESTION
+ro.vutbr.cz. IN DNSKEY
+SECTION ANSWER
+ro.vutbr.cz. 3600 IN DNSKEY 256 3 5 AwEAAb4tyN4pqltB48s1xQS3ZPXnTZJMvgXxiouXU9xtzj4wnhjhZp45 H7ozslWuksrwQWhZ8AASAD5kPFbQRbwpQ7xbEb3xdKHaWCFpyRCTkrqa ZQZQy4gaVqO+oRW42dIQ9K08A/WfvRuRDtw3VWDATp9pUkgpvb1n6+lp 71YK19RX
+ro.vutbr.cz. 3600 IN DNSKEY 257 3 5 AwEAAef6bqTAl94KddNHvit41gw6QBKkiYjUeS+UP58VHybV29RC7sSE +rYmkXabaMOLmoqMQRMepBEaUdM5OoZBWibHrPAbG0Wf+vlMOoWD5+EC 2mCxrUntIlOuS4XpMTh22+l0k1xSPiMGKjY0BDR95Iu3dDezCVl9PkPp tHj/rAnRTH7Q0fH9Mip8sigosd/CmsoY03I0AcZT4z1+XpGsq5Npxwtj 7cz0SRTI/eV5nynNYK+vr6kOfU1fw7p8/wxIfXkks0Xy8ktXa26DFdw1 RoqVlTS1s1diFyF5niCOT6Ei2kAlf0fggZJBypwoK+6J42wwD2OhORX+ lKrhooaN4TU9AcHwgv25XTXhUq4tYh+veazdXNWDjEb3ZyLM8fKERCa9 YtDBFoHM7yFOHbsOhHKMn8F6T2Boi73hU/+wspjL/n8taKevyyygGg+U g4ugo2pTIouAs5DNnv+nUrpctcKZ5nMEUVl+3XBsXplIyz9QEKHWdFzL gyfIZEok8WdYHebcIy1vJrxzqCNw9ixnTn+OK1lwlMToVH1AGpvRKRPo wGSFaIrDyXxKul34j2jEhP9TWRcJqncy166Ueu3c0BKmclM29N8jeWbP 3TqRJ3RRxNj/vk6c/UGmmrHEz8YdNp2L0hv3JgItr2GujCvPApUvLNPW C7DSErQ3JsjV3gah
+ro.vutbr.cz. 3600 IN RRSIG DNSKEY 5 3 3600 20170222120032 20170123120032 12150 ro.vutbr.cz. pN+8YElj24dhtnOQ20sjWxJTjx+FLTMrPms1lWIJKZtp2evQBG5AnAep 6w0QeMUTIh9ter58Dh6wu2IN4uA1h3ThxnSgwLraOChUFBtPTO8h5y8J mAq4KXSfqbEcHzZO/nBAtxSUk7aUz7yWf09xE+iozW3ORRWIXovMYci5 eEw=
+ro.vutbr.cz. 3600 IN RRSIG DNSKEY 5 3 3600 20170222120032 20170123120032 16627 ro.vutbr.cz. DSaIAl+iyToM8+ai9xuRVcRshYyI66XHWkOz0XEbIAwbc8aEMEeFCA91 1vpuBb6H92MXvM8hYsBhZHNIA0ApoIE4bdyEGZY05XN3GYgJ4BEhXJVM RR+inJf+vGGqdlRP6F2sPO+rCqfxWBvSoUFU7DpCpkl7hz2Ex0Clm9C9 YnWgL+tGmAH33s2Y8lTA3hG/0W0NxD5zy1LiyDa8Ls3vV4MC6gVxyloT Capd8FkDL9PmgW0gMRNtIWmc5Hw+j/HRMoy+oRCe8PIfUL/Dpx3iTAH8 iN3wV8apV2uPa0L8QgpixK4Tc87aSainCopVY+NOc5t0HErUzj8i7qA9 J/cRtQvlUzln5vBsrQsVIzIeNV4o8/cM3zFyfdKkHh1tWYKLJKkjfXc5 +7VMvF8PnoHceT/Zr2gCc8tnygRobypzgqy3p69bRJqiT0/eCAgpGusV 1DCOJY0sdiGDZEtpqeINbAgGKAMmmNwjIwYSFowRzdawip1wNd+90RhI +8hvx8Sc5+K5Mom2BF2wGHf/2Kv/ArzyXxqqcNozM61L1AjxIsBHjnLZ TzPlLntmiHUVaqET9Yc3G0K/RdsIpqz4M79N0BX66a58x2a3fLqQdrEC QshZPNxk2S4eCsrVRjHvU4a7e74Rbf/zXp89Y+jmwBbDMdnp+2/h9s6U J0sEBCYyo9M=
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA DO
+SECTION QUESTION
+piranha.ro.vutbr.cz. IN A
+SECTION ANSWER
+piranha.ro.vutbr.cz. 3600 IN A 147.229.2.90
+piranha.ro.vutbr.cz. 3600 IN RRSIG A 5 4 3600 20170222120032 20170123120032 12150 ro.vutbr.cz. Jz8bcAADQjCKTCcF70IK1aHGQlM4ukyN0myABlxoPaqid1mHX5jwR91b kdQmUAh2xDitlgRLbFjbUUgmjSPzQ5Qt7GAFUsVmqxvjbOLZjqHER1dh zmiWO0fDvvP647Osv3RiAP822rNUJcJrUBZU9LmeP05gwIHcpJrhdVBT b7I=
+SECTION AUTHORITY
+ro.vutbr.cz. 86400 IN NS shark.ro.vutbr.cz.
+ro.vutbr.cz. 86400 IN NS rhino.cis.vutbr.cz.
+ro.vutbr.cz. 86400 IN NS pipit.cis.vutbr.cz.
+ro.vutbr.cz. 86400 IN RRSIG NS 5 3 86400 20170222120032 20170123120032 12150 ro.vutbr.cz. HAQ8A+QNsS1WIXdW/fbT3jP+IxObBBvgUmvzsmJBXo8HMtnMAcuCQGmB 2JBQsQethQXsdyLnMK8to/5A9VRkqkAa7edxUoy7SdDi/mzGeLAVhF+5 kXSPD6t1vjiNdnIYAMpiOQbodCGxAnq6jnNyrjEzffdq3qw+5IkFNdG4 7Pw=
+SECTION ADDITIONAL
+rhino.cis.vutbr.cz. 86400 IN A 147.229.3.10
+rhino.cis.vutbr.cz. 86400 IN AAAA 2001:67c:1220:e000::93e5:30a
+shark.ro.vutbr.cz. 3600 IN A 147.229.2.59
+pipit.cis.vutbr.cz. 86400 IN A 77.93.219.110
+pipit.cis.vutbr.cz. 86400 IN AAAA 2a01:430:120::4d5d:db6e
+rhino.cis.vutbr.cz. 86400 IN RRSIG A 5 4 86400 20170204080646 20170105080646 28257 cis.vutbr.cz. X/tDf8e3JEV0LxiItfpQnBzeaRIq693VG8d30iCH4/1I0uqyCfxboWmm /CBpn9A8MCJu9NEEv+4+povNlfUfqi2yjsqJEVj8ztHxD4g9cc284Cv6 ySjxrSZ9axVqoaopEXujiTwwWJUFcgF6pxqyXVksW7sgKJrboM4VSlQD +Sw=
+rhino.cis.vutbr.cz. 86400 IN RRSIG AAAA 5 4 86400 20170204080646 20170105080646 28257 cis.vutbr.cz. T3Yf5PAkSeJtoOH90ea9zZBG9FC3iFhiCSerDn6d9up8GRfzxDsavYJC zQu+3vnOySySn+3TMzQSSFcWdJC2iO7ulaDGr177Gof9QJbKSVSMW7jt YDE2f4/R4Go3NZVwjk/HfpCInoR6pHNA1s/9hMnWtiVopmBdfzyd3/sW YOU=
+shark.ro.vutbr.cz. 3600 IN RRSIG A 5 4 3600 20170222120032 20170123120032 12150 ro.vutbr.cz. SmhgyF48yX/6yH7AdSmGX60NL/xaiKH/oAzB0rnPfQZ6j+UfV57ginVV lj798K9A8jjucUpqE8ua2mZ6/aOhpqlV2iI0CZXG44zOupsCY1/OXBDx YNetBcjoXDQCBQRLLLEUL5FerDVxqT74ngdLdKubwRdrB0TLQlvpBr+F Tc8=
+pipit.cis.vutbr.cz. 86400 IN RRSIG A 5 4 86400 20170204080646 20170105080646 28257 cis.vutbr.cz. Cz9etHnEOQTzu+6rYJEqx/SQ1tQgPOCyf8HSj4KOsx89jtgiHNC6pep6 ZE0SphMGAs3jC/uGIhlaFNZ3i38OQIMuqwacbz+XZyW5bByvV3QZrhqh dFxMDfmPuNiCAT3crFpUkvVW1OE3YfGHzZGXX7JP5wb1b8A3X6Qih7fV +nQ=
+pipit.cis.vutbr.cz. 86400 IN RRSIG AAAA 5 4 86400 20170204080646 20170105080646 28257 cis.vutbr.cz. piafjh6my2fooZRrzwCu9RQ95gYaMQkhIkDaGX/fT6wXzSdmgFZkS1Nl EMIKdDCQaPrLGMG3p32ptMkAm4esPekeyNtLSMBtXwZyUkgEGn6h1QM2 Yr3TOo8cixfk5nmRRdlYadf5krLb8yI9exiqeymgEQLa1YNRz/bWArlX bn8=
+ENTRY_END
+
+; end of pipit.cis.vutbr.cz. & rhino.cis.vutbr.cz.
+RANGE_END
+
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.vutbr.cz. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH flags rcode question answer
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.vutbr.cz. IN A
+SECTION ANSWER
+www.vutbr.cz. IN CNAME piranha.ro.vutbr.cz.
+piranha.ro.vutbr.cz. IN A 147.229.2.90
+ENTRY_END
+
+STEP 20 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.vutbr.cz. IN A
+ENTRY_END
+
+STEP 21 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH flags rcode question answer
+REPLY QR RD RA AD NOERROR
+SECTION QUESTION
+www.vutbr.cz. IN A
+SECTION ANSWER
+www.vutbr.cz. IN CNAME piranha.ro.vutbr.cz.
+www.vutbr.cz. IN RRSIG CNAME 5 3 300 20170216060902 20170117060902 39756 vutbr.cz. 9B3UC5SOEw1+yKlYlOTINEuNq0Kdglywc5IYJwzeSzQ3ykptzZo3ABSy bYhTqImVkhm/4NFM9/4HWMHPDzTmrWS0mCI/ljCd/oe/PxW/uESvo4P5 EQzlcuH6xBzc1KdEFAJOSmRzFjj3vyK1QN3k/c+1y2oMFOYOR2oOzCw+ MIE=
+piranha.ro.vutbr.cz. IN A 147.229.2.90
+piranha.ro.vutbr.cz. 3600 IN RRSIG A 5 4 3600 20170222120032 20170123120032 12150 ro.vutbr.cz. Jz8bcAADQjCKTCcF70IK1aHGQlM4ukyN0myABlxoPaqid1mHX5jwR91b kdQmUAh2xDitlgRLbFjbUUgmjSPzQ5Qt7GAFUsVmqxvjbOLZjqHER1dh zmiWO0fDvvP647Osv3RiAP822rNUJcJrUBZU9LmeP05gwIHcpJrhdVBT b7I=
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/sets/resolver/world_mx_nic_www.rpl b/tests/integration/deckard/sets/resolver/world_mx_nic_www.rpl
new file mode 100644
index 0000000..d333a76
--- /dev/null
+++ b/tests/integration/deckard/sets/resolver/world_mx_nic_www.rpl
@@ -0,0 +1,408 @@
+; test with real world Internet data
+; attempt to resolve www.nic.mx A leads to CNAME www.nicmexico.mx.
+; sub-tree nic.mx is not signed and nixmexico.mx is signed.
+; the answer must not have AD flag set!
+
+val-override-date: 20170124180319
+trust-anchor: ". 172800 IN DS 19036 8 2 49aac11d7b6f6446702e54a1607371607a1a41855200fd2ce1cdde32f24e8fb5"
+stub-addr: 2001:dc3::35
+stub-name: m.root-servers.net
+; we have added missing A/AAAA records for NS names too late
+; when validity of original RRSIGs expired
+; => we disable validation for mx. NS names to avoid need to resign whole test
+domain-insecure: mx-ns.mx.
+do-ip4: false
+CONFIG_END
+
+SCENARIO_BEGIN www.nic.mx. CNAME kresd issue #144
+
+; DNS root ; M.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 2001:dc3::35
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+m.root-servers.net. IN AAAA
+SECTION ANSWER
+m.root-servers.net. 3600 IN AAAA 2001:dc3::35
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+m.root-servers.net. IN A
+SECTION ANSWER
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+net. IN NS
+SECTION ANSWER
+net. 3600 IN NS m.root-servers.net.
+SECTION ADDITIONAL
+m.root-servers.net. 3600 IN AAAA 2001:dc3::35
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+root-servers.net. IN NS
+SECTION ANSWER
+root-servers.net. 3600 IN NS m.root-servers.net.
+SECTION ADDITIONAL
+m.root-servers.net. 3600 IN AAAA 2001:dc3::35
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+net. IN DS
+SECTION ANSWER
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA DO NOERROR
+SECTION QUESTION
+. IN DNSKEY
+SECTION ANSWER
+. 16567 IN DNSKEY 257 3 8 AwEAAagAIKlVZrpC6Ia7gEzahOR+9W29euxhJhVVLOyQbSEW0O8gcCjF FVQUTf6v58fLjwBd0YI0EzrAcQqBGCzh/RStIoO8g0NfnfL2MTJRkxoX bfDaUeVPQuYEhg37NZWAJQ9VnMVDxP/VHL496M/QZxkjf5/Efucp2gaD X6RS6CXpoY68LsvPVjR0ZSwzz1apAzvN9dlzEheX7ICJBBtuA6G3LQpz W5hOA2hzCTMjJPJ8LbqF6dsV6DoBQzgul0sGIcGOYl7OyQdXfZ57relS Qageu+ipAdTTJ25AsRTAoub8ONGcLmqrAmRLKBP1dfwhYB4N7knNnulq QxA+Uk1ihz0=
+. 16567 IN DNSKEY 256 3 8 AwEAAYvgWbYkpeGgdPKaKTJU3Us4YSTRgy7+dzvfArIhi2tKoZ/WR1Df w883SOU6Uw7tpVRkLarN0oIMK/xbOBD1DcXnyfElBwKsz4sVVWmfyr/x +igD/UjrcJ5zEBUrUmVtHyjar7ccaVc1/3ntkhZjI1hcungAlOhPhHlk MeX+5Azx6GdX//An5OgrdyH3o/JmOPMDX1mt806JI/hf0EwAp1pBwo5e 8SrSuR1tD3sgNjr6IzCdrKSgqi92z49zcdis3EaY199WFW60DCS7ydu+ +T5Xa+GyOw1quagwf/JUC/mEpeBQYWrnpkBbpDB3sy4+P2i8iCvavehb RyVm9U0MlIc=
+. 16567 IN RRSIG DNSKEY 8 0 172800 20170201000000 20170111000000 19036 . Sh+EpofvZgk3J9szMD2B94FxFgyIUKz3hkbCjgWSTqPQyhqNgqVU8QlS EtOo8YLmS4AX98eit5Gmmb2ObpkGoXBmAzu5w/Qt5WsGsWzLQhYrsy9s lDmFQ2JKUoCyfdwqhlJ8VxjzdFdMUiVl+/GPnv4yjxjM8Ke3VAtBkn6n BO7JkcxxOfcgZdZ4MuvSr40K/SenZE+JlLLL1LF4TMCGqaZTTdOx6kFF KSSgy2AS884htWcK0tnwRc630g6nAI2wdvjlRLBeisbfXanI4v8iiPyT FnMmnV7wJGWJ4gtRJ0UH3u5RWXUPZ+s1tKytk3slXbLyQ9xkEDveuD+h b659gQ==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR DO NOERROR
+SECTION QUESTION
+mx. IN NS
+SECTION AUTHORITY
+mx. 172800 IN NS c.mx-ns.mx.
+mx. 172800 IN NS m.mx-ns.mx.
+mx. 172800 IN NS e.mx-ns.mx.
+mx. 172800 IN NS i.mx-ns.mx.
+mx. 172800 IN NS o.mx-ns.mx.
+mx. 172800 IN NS x.mx-ns.mx.
+mx. 86400 IN DS 55955 8 2 3d7f3313e86341ec23a02f8ed837572d62cf74bf175ac8b2f19b1e2b8930b0d5
+mx. 86400 IN RRSIG DS 8 1 86400 20170206050000 20170124040000 61045 . DYmv0z7EnlUOu081yDzeh3tourMFyYtBv7IKIiwPN5ZXuHmw0PvqT0oU//DomnA0NdfCRizOSmvDlZITNtlTffEA3mudnbPC+TEpdf1nffHLHQPnjcS0U+zfoBvRK0OHha3J7YgSXFQuCskJAg4P6ktPzgcd2ccv/FRlzzw4CrZOE3AtDWir31xt8c8DxZjysjIptblua7o9kwac+biWoszUl+sJBAXGbn0XXMloTAisYHyyZF9YeTRz3er8gyao8ynRe2KgUZPX4ieVQl+BsXDOmVRYLE8l4hLSRanjoWOR3gAqQUHJwn9xXxhGfApe5tUhaCE7v1EplCw9ykaKVA==
+SECTION ADDITIONAL
+c.mx-ns.mx. 172800 IN A 192.100.224.1
+e.mx-ns.mx. 172800 IN A 189.201.244.1
+i.mx-ns.mx. 172800 IN A 207.248.68.1
+m.mx-ns.mx. 172800 IN A 200.94.176.1
+o.mx-ns.mx. 172800 IN A 200.23.1.1
+x.mx-ns.mx. 172800 IN A 201.131.252.1
+c.mx-ns.mx. 172800 IN AAAA 2001:1258::1
+m.mx-ns.mx. 172800 IN AAAA 2001:13c7:7000::1
+; added AAAA records to stop resolver from asking for them later
+o.mx-ns.mx. 172800 IN AAAA 2001:1258::1
+i.mx-ns.mx. 172800 IN AAAA 2001:1258::1
+x.mx-ns.mx. 172800 IN AAAA 2001:1258::1
+e.mx-ns.mx. 172800 IN AAAA 2001:1258::1
+ENTRY_END
+; end of M.ROOT-SERVERS.NET.
+RANGE_END
+
+; ?.mx-ns.mx.
+RANGE_BEGIN 0 100
+ ADDRESS 192.100.224.1
+ ADDRESS 189.201.244.1
+ ADDRESS 207.248.68.1
+ ADDRESS 200.94.176.1
+ ADDRESS 200.23.1.1
+ ADDRESS 201.131.252.1
+ ADDRESS 2001:1258::1
+ ADDRESS 2001:13c7:7000::1
+
+ENTRY_BEGIN
+MATCH opcode qname qtype
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+mx-ns.mx. IN NS
+SECTION ANSWER
+mx-ns.mx. 172800 IN NS c.mx-ns.mx.
+mx-ns.mx. 172800 IN NS m.mx-ns.mx.
+mx-ns.mx. 172800 IN NS e.mx-ns.mx.
+mx-ns.mx. 172800 IN NS i.mx-ns.mx.
+mx-ns.mx. 172800 IN NS o.mx-ns.mx.
+mx-ns.mx. 172800 IN NS x.mx-ns.mx.
+SECTION ADDITIONAL
+c.mx-ns.mx. 172800 IN A 192.100.224.1
+e.mx-ns.mx. 172800 IN A 189.201.244.1
+i.mx-ns.mx. 172800 IN A 207.248.68.1
+m.mx-ns.mx. 172800 IN A 200.94.176.1
+o.mx-ns.mx. 172800 IN A 200.23.1.1
+x.mx-ns.mx. 172800 IN A 201.131.252.1
+o.mx-ns.mx. 172800 IN AAAA 2001:1258::1
+i.mx-ns.mx. 172800 IN AAAA 2001:1258::1
+x.mx-ns.mx. 172800 IN AAAA 2001:1258::1
+e.mx-ns.mx. 172800 IN AAAA 2001:1258::1
+c.mx-ns.mx. 172800 IN AAAA 2001:1258::1
+m.mx-ns.mx. 172800 IN AAAA 2001:13c7:7000::1
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname qtype
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+mx-ns.mx. IN DS
+SECTION ANSWER
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname qtype
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+i.mx-ns.mx. IN AAAA
+SECTION ANSWER
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname qtype
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+e.mx-ns.mx. IN AAAA
+SECTION ANSWER
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname qtype
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+x.mx-ns.mx. IN AAAA
+SECTION ANSWER
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname qtype
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+o.mx-ns.mx. IN AAAA
+SECTION ANSWER
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+mx. IN DNSKEY
+SECTION ANSWER
+mx. 86400 IN DNSKEY 257 3 8 AwEAAcokawGJMW4OI1eas0vAtfl0etrPSlqkh7n/JPpdMt5fplkWI0oo YS3kYBXYzMxXnpNOK57jp5JodELeZKDrHCrUhAzZiy5iJQDy9Qi85mSC KTHg32+JKjXiMEkTZUlOzNRrXC7apWfZbzbx98CnzkWw0Xj2wDIniptM jnwAJeb8L+Mm5AzZSkUugga/eDvpVsT5MZZnT/DuJdxS5olx+HyTKLct m/LDljtQKJya0UtXUKkVc5cv8y+ja5AivjXXrUmDcgd1P6bntcbjpcFY UuLZMsmyOZ2uViXNEhIdBcP+davulxW++DawqOtvnpuRxfLFsuYw/vDC ilfIGEdgz20=
+mx. 86400 IN DNSKEY 256 3 8 AwEAAcwqWcnh23qhQTbWsbOKbRI4btNQCYRa4ksadH8VjQ++VruqkhPu d7e/RsZMhevCWDJHrjfJ739NmiGIwS58uh1sVACfKRmxLP25/1V9frIi HBxkaVLXPAHm8+ApIhzUzaUTUrmSnDm0/wJryo34zETnA6J4czfzYDLX Vqh3KVtL
+mx. 86400 IN RRSIG DNSKEY 8 1 86400 20170223000000 20170124000000 48529 mx. BYGaUXiyB0vIi4sBwvUuL2Im+zcIpykZD96YdvA3Kpk7RlV3LcLD9L6B +HpwFWMRZ+vt09YW/jrzSR9mlXpZeWR6BhHoo9f2MGOO5dwejnUuipLD +t5wKi91XALmaRN4Z2ptdJ0wVMpfXlkfrNTB+RvYAqx/azDGw5Ewjh7C J5Y=
+mx. 86400 IN RRSIG DNSKEY 8 1 86400 20170303150000 20170102150000 55955 mx. SboaaGva7+GbfoNKa8Ov2GhSIvYStcBeudk0A0+53/LMs7sHuLegE9+P lTqih4sl/W1Yd4a4jWoVYGGYu8M4tb1fzaxvr5eTDwm3gKGirbTsQPFl Ih5gNnC6QJKYBhpN7w/Fn3JmJTBLwhd7tREygGqkNO/LdTwiHfbcIzkU 5UpD9A3/oeZoMQe71AvJstU5PIHxg3PU1CNU9YBcNhYzUfTfcr+hlbmA Nm6RaOBaWJwp4YzcS3uJcaXmpS1t/lbxWIgeOXRhql6ZHqCai0lSmNnm vAydmJI/cqXsJ23Pj22TD1QwDFKTp0u2oIiykeFzdbIG0s2thtmyY4km qh1Ulg==
+ENTRY_END
+
+; nix.mx
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA DO NOERROR
+SECTION QUESTION
+nic.mx. IN NS
+SECTION ANSWER
+nic.mx. 172800 IN NS o.mx-ns.mx.
+nic.mx. 172800 IN NS m.mx-ns.mx.
+nic.mx. 172800 IN NS c.mx-ns.mx.
+nic.mx. 172800 IN NS x.mx-ns.mx.
+nic.mx. 172800 IN NS e.mx-ns.mx.
+nic.mx. 172800 IN NS i.mx-ns.mx.
+SECTION ADDITIONAL
+c.mx-ns.mx. 172800 IN A 192.100.224.1
+c.mx-ns.mx. 172800 IN AAAA 2001:1258::1
+e.mx-ns.mx. 172800 IN A 189.201.244.1
+i.mx-ns.mx. 172800 IN A 207.248.68.1
+m.mx-ns.mx. 172800 IN A 200.94.176.1
+m.mx-ns.mx. 172800 IN AAAA 2001:13c7:7000::1
+o.mx-ns.mx. 172800 IN A 200.23.1.1
+x.mx-ns.mx. 172800 IN A 201.131.252.1
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA DO NOERROR
+SECTION QUESTION
+nic.mx. IN DS
+SECTION AUTHORITY
+qpcf3eq45ur6ndho0ecuj1o25g7d48pi.mx. 1800 IN NSEC3 1 1 100 FBB1D947FF931FC5 QPDGRP34SI0F3CBG41HRN7G8TLFK6C7B NS SOA RRSIG DNSKEY NSEC3PARAM
+qpcf3eq45ur6ndho0ecuj1o25g7d48pi.mx. 1800 IN RRSIG NSEC3 8 2 1800 20170223000000 20170124000000 48529 mx. RI7Ezya54VVVcCiyH2rHBjRwWzsoe2A1vBcwzFUeiKFPsoOsCkvAfpvU uZ96IEa0Ni7ZksS2XFuV9TeQotk/HirhRGq2AauGtF4RLExmZnZouAjz tLZYXhr7mZAqfKLzZV5qNzlYSia3wF9m4wkz4eSBfeJ/6u2AoQP81C3Y Dls=
+mx. 1800 IN SOA m.mx-ns.mx. hostmaster.nic.mx. 1485251802 900 900 604800 1800
+mx. 1800 IN RRSIG SOA 8 1 86400 20170223000000 20170124000000 48529 mx. Gwjg+/GJUJj32FMa9HKESM7zsPFdVVEotOIyXKhZjOX139PhfbcOdfJr bfhDvVV8weMoLHhM0rVko0Sr+H8S3+R8wNOkvoFPqd3G5YV2azS52qOQ xPq1gVT0g3bWtmgF0KV2fGQ2Lcw7ynksenBmpQCggjbh/O98zwfRJkcc Huk=
+1e790cnnc0n6fmd7hhf7o1baus5muq9l.mx. 1800 IN NSEC3 1 1 100 FBB1D947FF931FC5 1EDMBBOCRH8AB8GRQF55CMJV2IS3U6E7 NS DS RRSIG
+1e790cnnc0n6fmd7hhf7o1baus5muq9l.mx. 1800 IN RRSIG NSEC3 8 2 1800 20170223000000 20170124000000 48529 mx. xP9wMq871/wi0N99DkUhXHB1VjyjG5zds0CHIdrm1MC0JPl2atB1nliC tYC/nMC6vHGRk7bcX0kFNDgi0duGuNwKEHyTp2gHBSoMefUtDfJbOoq8 4VSQvS0WaJlK1H3eV21AdhmpZEAe0YB6e7lU5plhqNMX5mxDD5d0ZVD8 TWI=
+ENTRY_END
+
+; this entry is the one which caused kresd to return AD flag despite of missing RRSIGs
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA DO NOERROR
+SECTION QUESTION
+www.nic.mx. IN A
+SECTION ANSWER
+www.nic.mx. 300 IN CNAME www.nicmexico.mx.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR AA DO NOERROR
+SECTION QUESTION
+www.nic.mx. IN RRSIG
+SECTION AUTHORITY
+nic.mx. 1800 IN SOA m.mx-ns.mx. hostmaster.nic.mx. 2016101701 3600 900 604800 1800
+ENTRY_END
+
+; nixmexico.mx
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA RD NOERROR
+SECTION QUESTION
+nicmexico.mx. IN NS
+SECTION ANSWER
+nicmexico.mx. 172800 IN NS o.mx-ns.mx.
+nicmexico.mx. 172800 IN NS m.mx-ns.mx.
+nicmexico.mx. 172800 IN NS e.mx-ns.mx.
+nicmexico.mx. 172800 IN NS x.mx-ns.mx.
+nicmexico.mx. 172800 IN NS i.mx-ns.mx.
+nicmexico.mx. 172800 IN NS c.mx-ns.mx.
+nicmexico.mx. 172800 IN RRSIG NS 7 2 172800 20170221235959 20161221161902 14618 nicmexico.mx. MMPJ1lltyGLyE+s+V7mFb3iJzWkKgnCRtBGgVqynFaKJBgEX+0NFy8Iq o8CKWlXGXitDilaE3xy6ynYnb8CeQuEeaKVLzikUwxu+bTR/tcX1fECp 2i9uDFTl/wrYSyNU4gEy/4Ueev5GsM8XQmK5j8xgUmwc+258eRBZ129O K1E=
+SECTION ADDITIONAL
+c.mx-ns.mx. 172800 IN A 192.100.224.1
+c.mx-ns.mx. 172800 IN AAAA 2001:1258::1
+e.mx-ns.mx. 172800 IN A 189.201.244.1
+i.mx-ns.mx. 172800 IN A 207.248.68.1
+m.mx-ns.mx. 172800 IN A 200.94.176.1
+m.mx-ns.mx. 172800 IN AAAA 2001:13c7:7000::1
+o.mx-ns.mx. 172800 IN A 200.23.1.1
+x.mx-ns.mx. 172800 IN A 201.131.252.1
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA DO
+SECTION QUESTION
+nicmexico.mx. IN DS
+SECTION ANSWER
+nicmexico.mx. 86400 IN DS 25953 7 1 3980E3CBB2DC1F0A39EE58454F218D695C6FCF2B
+nicmexico.mx. 86400 IN DS 25953 7 2 E390593C68F6C5BD1A38E3CF7D9643235AC9C09A1023EBEA8E6D56FC 9EF2AAA6
+nicmexico.mx. 86400 IN RRSIG DS 8 2 86400 20170223000000 20170124000000 48529 mx. kwiqOPNYD6k+CPGGewQ7YWnJqomLkr4wrIT96qnb11l1m+BBtCZnxh1X 9u1I4nQsLC9/gJh1sytYkMogObxd6CsMUwAn8lA7Pnlbz1upINis7oE5 2MoHjYDhhJnfSryTtiw5Xak+Bup3GGmi4KgNsitQXUK8rFg5xAwyjtb6 udg=
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA DO
+SECTION QUESTION
+nicmexico.mx. IN DNSKEY
+SECTION ANSWER
+nicmexico.mx. 172800 IN DNSKEY 257 3 7 AwEAAdU7ho1gF5Swo/P3EMrcm82fE3bSvXec/q4HvGndCS+iEhOVMQgx SmjhdnILgNE23x5v7iprrQdcrC6qG3h5pWromlJt4zqqWD91OuydXGpB vkx9o3gWo9wqr+2mX4cPKsKKhiyQ1EBEbaYZP1PqEWigdTuzVB2zGWAu yCNlbgHX8Q4pgU/P+jdTB0RFkQEa7BtIu/+7JYpB09REdjtn4AgdqaVK rq9gQRxAbpuQezw5vEnK/EFiH+FIa8FWctMhRkC2IdG5THpG8lzZry+Q 04Mih/r7tsY/RbA0asG4RVOFTtHCdjIZc4f4fxNIaR4B7IzBPIWN0d3/ ILI6sObAnJs=
+nicmexico.mx. 172800 IN DNSKEY 256 3 7 AwEAAdlPfZYpM3PWP1ub8MDc4fSBVu3f+lS3ojPAaKNEgXu0mzGP9BtS Rj7kAIR2BQN61sb6b2QIT2QnGSkOjfho0TLm1UjcAMjRC6A4bwVmwYgj OMXd56jRi1zeus3nBz661inwqSOOs4+72SiVLqmbzDV0uFHAZFrSIrS0 Fp5vDTS/
+nicmexico.mx. 172800 IN DNSKEY 256 3 7 AwEAAbmZ5YmUhQKofswApd84tnITiUqh8kyN609rOanl3ga7WEjGs2bD D8RU/oOj31OzfnEFLSLH0fpIWCPWT+lvZ9HFOxAMavXnwncKsAVLNrv+ CuBGTiQ4wa2C/vQ7i/D1SbnXAUs/17Pu9onlAGeDoolgsUAgldfRwEGp tVfY8r71
+nicmexico.mx. 172800 IN RRSIG DNSKEY 7 2 172800 20170221235959 20161221161902 14618 nicmexico.mx. BTeItGos/TVLbiYrisWuJCFmdnA+p3yBHOMfUsvPAOvs5trTincG5wkY EHsq13Dvk9JNjSYh4HPlmlnsXDmUPXm6Z4bd1BXFVPiK3r4I1YGwwP/M ATNjw5V8w+my3PvOQdwyhWiF8dnd0EfeK3t+b/prwZiWs64ezaNiMxUk i5s=
+nicmexico.mx. 172800 IN RRSIG DNSKEY 7 2 172800 20170221235959 20161221161902 25953 nicmexico.mx. NPVmWrmIeGHYOjrfonov29kFG5gP2vaP0qE8sZplYt44MzgBnhLt+cZS sk6NNEhLPgYe4fiPxj3xzT+BjxTUCCQo3CT1KR4uaEIbepBmxDx8dMv6 4c1AO2wNnt8x/OBG+Nwg3gLaf4UtdJvOQsdpOsTzqKKo7WPKxeb462gw 4aZzYh4uhEjTFil8eGLXOlGe8CYThAdwxKbA6tEZxE5UEa2mIb2orSbz ro+ehp6imnn3YWtLWBtkWQqsSaqLug4HUrXgjbqNSZ+FCdO4WIxLgDsz k+jlA7tdkZknE43AQX/md6orKDalCb4OtrC0yrgYDtwVsgP1qZVAjJWW 09nUIg==
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA DO
+SECTION QUESTION
+www.nicmexico.mx. IN A
+SECTION ANSWER
+www.nicmexico.mx. 172800 IN A 200.94.180.55
+www.nicmexico.mx. 172800 IN A 200.94.180.54
+www.nicmexico.mx. 172800 IN A 200.94.180.57
+www.nicmexico.mx. 172800 IN A 200.94.180.56
+www.nicmexico.mx. 172800 IN RRSIG A 7 3 172800 20170221235959 20161221161902 14618 nicmexico.mx. s3THv+Ay2WrcOTG6bo+54Zc/rff/jhzcJKZ3ZRYMXhw3FToSvTOSqsIG 1gzW/Sk6r2oikHH3nNluaMTAXfCULu2mHiQVAuFlnajFSMPcm8KvEyV0 cCT7knkAFqb+ODkimPMufRHiOLbnhQk9/A25qK7J8rCB76IUmzk41hYR NBU=
+SECTION AUTHORITY
+nicmexico.mx. 172800 IN NS m.mx-ns.mx.
+nicmexico.mx. 172800 IN NS c.mx-ns.mx.
+nicmexico.mx. 172800 IN NS i.mx-ns.mx.
+nicmexico.mx. 172800 IN NS o.mx-ns.mx.
+nicmexico.mx. 172800 IN NS x.mx-ns.mx.
+nicmexico.mx. 172800 IN NS e.mx-ns.mx.
+nicmexico.mx. 172800 IN RRSIG NS 7 2 172800 20170221235959 20161221161902 14618 nicmexico.mx. MMPJ1lltyGLyE+s+V7mFb3iJzWkKgnCRtBGgVqynFaKJBgEX+0NFy8Iq o8CKWlXGXitDilaE3xy6ynYnb8CeQuEeaKVLzikUwxu+bTR/tcX1fECp 2i9uDFTl/wrYSyNU4gEy/4Ueev5GsM8XQmK5j8xgUmwc+258eRBZ129O K1E=
+SECTION ADDITIONAL
+c.mx-ns.mx. 172800 IN A 192.100.224.1
+e.mx-ns.mx. 172800 IN A 189.201.244.1
+i.mx-ns.mx. 172800 IN A 207.248.68.1
+m.mx-ns.mx. 172800 IN A 200.94.176.1
+o.mx-ns.mx. 172800 IN A 200.23.1.1
+x.mx-ns.mx. 172800 IN A 201.131.252.1
+c.mx-ns.mx. 172800 IN AAAA 2001:1258::1
+m.mx-ns.mx. 172800 IN AAAA 2001:13c7:7000::1
+ENTRY_END
+
+; end ?.mx-ns.mx.
+RANGE_END
+
+
+STEP 10 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.nic.mx. IN A
+ENTRY_END
+
+STEP 11 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH rcode flags question answer
+REPLY QR RD RA DO NOERROR
+SECTION QUESTION
+www.nic.mx. IN A
+SECTION ANSWER
+www.nic.mx. 300 IN CNAME www.nicmexico.mx.
+www.nicmexico.mx. 171139 IN A 200.94.180.57
+www.nicmexico.mx. 171139 IN A 200.94.180.56
+www.nicmexico.mx. 171139 IN A 200.94.180.54
+www.nicmexico.mx. 171139 IN A 200.94.180.55
+www.nicmexico.mx. 171139 IN RRSIG A 7 3 172800 20170221235959 20161221161902 14618 nicmexico.mx. s3THv+Ay2WrcOTG6bo+54Zc/rff/jhzcJKZ3ZRYMXhw3FToSvTOSqsIG1gzW/Sk6r2oikHH3nNluaMTAXfCULu2mHiQVAuFlnajFSMPcm8KvEyV0cCT7knkAFqb+ODkimPMufRHiOLbnhQk9/A25qK7J8rCB76IUmzk41hYRNBU=
+ENTRY_END
+
+STEP 20 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.nicmexico.mx. IN A
+ENTRY_END
+
+STEP 21 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH rcode flags question answer
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+www.nicmexico.mx. IN A
+SECTION ANSWER
+www.nicmexico.mx. 170708 IN A 200.94.180.55
+www.nicmexico.mx. 170708 IN A 200.94.180.56
+www.nicmexico.mx. 170708 IN A 200.94.180.54
+www.nicmexico.mx. 170708 IN A 200.94.180.57
+www.nicmexico.mx. 172800 IN RRSIG A 7 3 172800 20170221235959 20161221161902 14618 nicmexico.mx. s3THv+Ay2WrcOTG6bo+54Zc/rff/jhzcJKZ3ZRYMXhw3FToSvTOSqsIG 1gzW/Sk6r2oikHH3nNluaMTAXfCULu2mHiQVAuFlnajFSMPcm8KvEyV0 cCT7knkAFqb+ODkimPMufRHiOLbnhQk9/A25qK7J8rCB76IUmzk41hYR NBU=
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/deckard/setup.py b/tests/integration/deckard/setup.py
new file mode 100644
index 0000000..93e22b7
--- /dev/null
+++ b/tests/integration/deckard/setup.py
@@ -0,0 +1,36 @@
+#!/usr/bin/env python3
+from distutils.core import setup
+
+version = '3.0'
+
+setup(
+ name='deckard',
+ version=version,
+ description='DNS toolkit',
+ long_description=(
+ "Deckard is a DNS software testing based on library pydnstest."
+ "It supports parsing and running Unbound-like test scenarios,"
+ "and setting up a mock DNS server. It's based on dnspython."),
+ author='CZ.NIC',
+ author_email='knot-dns-users@lists.nic.cz',
+ license='BSD',
+ url='https://gitlab.nic.cz/knot/deckard',
+ packages=['pydnstest'],
+ python_requires='>=3.5',
+ install_requires=[
+ 'dnspython>=1.15',
+ 'jinja2',
+ 'PyYAML',
+ 'python-augeas'
+ ],
+ classifiers=[
+ 'Intended Audience :: Developers',
+ 'License :: OSI Approved :: BSD License',
+ 'Programming Language :: Python :: 3 :: Only'
+ 'Operating System :: POSIX :: Linux',
+ 'Topic :: Internet :: Name Service (DNS)',
+ 'Topic :: Software Development :: Libraries :: Python Modules',
+ 'Topic :: Software Development :: Quality Assurance',
+ 'Topic :: Software Development :: Testing',
+ ]
+)
diff --git a/tests/integration/deckard/template/dnssec_getdns.j2 b/tests/integration/deckard/template/dnssec_getdns.j2
new file mode 100644
index 0000000..282dc9f
--- /dev/null
+++ b/tests/integration/deckard/template/dnssec_getdns.j2
@@ -0,0 +1,3 @@
+{% for TA in TRUST_ANCHORS %}
+{{TA}}
+{% endfor %}
diff --git a/tests/integration/deckard/template/getdns.j2 b/tests/integration/deckard/template/getdns.j2
new file mode 100644
index 0000000..49064d4
--- /dev/null
+++ b/tests/integration/deckard/template/getdns.j2
@@ -0,0 +1,6 @@
+{ "listen_addresses": [ {{SELF_ADDR}} ]
+, "dns_root_servers": [ {{ROOT_ADDR}} ]
+, "timeout": 2000
+, "dnssec_return_status": GETDNS_EXTENSION_TRUE
+, "dnssec_trust_anchors": "getdns-root.key"
+}
diff --git a/tests/integration/deckard/template/hints_zone.j2 b/tests/integration/deckard/template/hints_zone.j2
new file mode 100644
index 0000000..4262fd4
--- /dev/null
+++ b/tests/integration/deckard/template/hints_zone.j2
@@ -0,0 +1,9 @@
+; This file holds the information on root name servers needed to
+; initialize cache of Internet domain name servers
+
+. 3600000 NS {{ROOT_NAME}}
+{% if ':' in ROOT_ADDR %}
+{{ROOT_NAME}} 3600000 AAAA {{ROOT_ADDR}}
+{% else %}
+{{ROOT_NAME}} 3600000 A {{ROOT_ADDR}}
+{% endif %}
diff --git a/tests/integration/deckard/template/knotd_master.j2 b/tests/integration/deckard/template/knotd_master.j2
new file mode 100644
index 0000000..ccf1f72
--- /dev/null
+++ b/tests/integration/deckard/template/knotd_master.j2
@@ -0,0 +1,29 @@
+#
+# This is a sample of a minimal configuration file for Knot DNS.
+# For more details, see man 5 knot.conf or refer to the server documentation.
+#
+
+server:
+ listen: {{SELF_ADDR}}@53
+
+control:
+ listen: "{{WORKING_DIR}}/knotd.sock"
+
+log:
+ - target: stdout
+ any: info
+
+acl:
+ - id: acl_slave
+ address: {{ROOT_ADDR}}
+ action: transfer
+
+template:
+ - id: default
+ storage: "{{WORKING_DIR}}"
+
+zone:
+ - domain: example.com
+ file: "{{INSTALL_DIR}}/sets/knotd/master/example.com.zone"
+ acl: acl_slave
+
diff --git a/tests/integration/deckard/template/knotd_slave.j2 b/tests/integration/deckard/template/knotd_slave.j2
new file mode 100644
index 0000000..4ac768e
--- /dev/null
+++ b/tests/integration/deckard/template/knotd_slave.j2
@@ -0,0 +1,28 @@
+#
+# This is a sample of a minimal configuration file for Knot DNS.
+# For more details, see man 5 knot.conf or refer to the server documentation.
+#
+
+server:
+ listen: {{SELF_ADDR}}@53
+
+control:
+ listen: "{{WORKING_DIR}}/knotd.sock"
+
+log:
+ - target: stdout
+ any: info
+
+remote:
+ - id: master
+ address: {{ROOT_ADDR}}@53
+
+template:
+ - id: default
+ storage: "{{WORKING_DIR}}"
+
+zone:
+ - domain: example.com
+ file: "{{WORKING_DIR}}/example.com.zone"
+ master: master
+
diff --git a/tests/integration/deckard/template/kresd.j2 b/tests/integration/deckard/template/kresd.j2
new file mode 100644
index 0000000..a4b86b6
--- /dev/null
+++ b/tests/integration/deckard/template/kresd.j2
@@ -0,0 +1,138 @@
+net = { '{{SELF_ADDR}}' }
+{% if ':' in SELF_ADDR %}
+net.outgoing_v6('{{SELF_ADDR}}')
+{% else %}
+net.outgoing_v4('{{SELF_ADDR}}')
+{% endif %}
+
+net.bufsize(4096)
+
+modules = {'stats', 'policy', 'hints'}
+
+-- trace logging for all requests
+policy.add(policy.all(policy.DEBUG_ALWAYS))
+
+-- test. domain is used by some tests, allow it
+policy.add(policy.suffix(policy.PASS, {todname('test.')}))
+{% if FORWARD_ADDR %}
+policy.add(policy.all(policy.FORWARD('{{FORWARD_ADDR}}')))
+{% endif %}
+cache.size = 2*MB
+hints.root({['{{ROOT_NAME}}'] = '{{ROOT_ADDR}}'})
+{% if QMIN == "false" %}
+option('NO_MINIMIZE', true)
+{% else %}
+option('NO_MINIMIZE', false)
+{% endif %}
+{% if DO_NOT_QUERY_LOCALHOST == "false" %}
+option('ALLOW_LOCAL', true)
+{% else %}
+option('ALLOW_LOCAL', false)
+{% endif %}
+
+{% if HARDEN_GLUE == "true" %}
+mode('normal')
+{% else %}
+mode('permissive')
+{% endif %}
+
+-- make sure that value specified at compile-time does not break tests
+trust_anchors.remove('.')
+{% for TAF in TRUST_ANCHOR_FILES %}
+trust_anchors.add_file('{{TAF}}')
+{% endfor %}
+trust_anchors.set_insecure({
+{% for DI in NEGATIVE_TRUST_ANCHORS %}
+"{{DI}}",
+{% endfor %}
+})
+
+{% if DO_IP6 == "true" %}
+net.ipv6 = true
+{% else %}
+net.ipv6 = false
+{% endif %}
+
+{% if DO_IP4 == "true" %}
+net.ipv4 = true
+{% else %}
+net.ipv4 = false
+{% endif %}
+
+{% if FEATURES.min_ttl is defined %}
+cache.min_ttl({{FEATURES.min_ttl}})
+{% endif %}
+
+{% if FEATURES.max_ttl is defined %}
+cache.max_ttl({{FEATURES.max_ttl}})
+{% endif %}
+
+{% if FEATURES.dns64_prefix is defined %}
+modules.load( 'dns64')
+dns64.config('{{FEATURES.dns64_prefix}}')
+{% endif %}
+
+{% if FEATURES.static_hint_name is defined %}
+{% if FEATURES.static_hint_addr is defined %}
+hints['{{FEATURES.static_hint_name}}'] = '{{FEATURES.static_hint_addr}}'
+{% endif %}
+{% endif %}
+
+{% if FEATURES.renumber_src is defined %}
+{% if FEATURES.renumber_dst is defined %}
+modules.load( 'renumber')
+renumber.config({{ '{{' }}'{{FEATURES.renumber_src}}','{{FEATURES.renumber_dst}}' {{ '}}' }})
+{% endif %}
+{% endif %}
+
+{% for policy in FEATURES.policy %}
+{{policy}}
+{% endfor %}
+
+{% if FEATURES.view is defined %}
+modules.load( 'view')
+{% for view in FEATURES.view %}
+{{view}}
+{% endfor %}
+{% endif %}
+
+{% if FEATURES.workarounds is defined %}
+modules = { 'workarounds < iterate' }
+{% endif %}
+
+-- Disable RFC5011 TA update
+if ta_update then
+ modules.unload('ta_update')
+end
+
+-- Disable RFC8145 signaling, scenario doesn't provide expected ansers
+if ta_signal_query then
+ modules.unload('ta_signal_query')
+end
+
+-- Disable RFC8109 priming, scenario doesn't provide expected ansers
+if priming then
+ modules.unload('priming')
+end
+
+-- Disable this module because it make one priming query.
+if detect_time_skew then
+ modules.unload('detect_time_skew')
+end
+
+-- Self-checks on globals
+assert(help() ~= nil)
+assert(worker.id ~= nil)
+-- Self-checks on facilities
+assert(cache.count() == 0)
+assert(cache.stats() ~= nil)
+assert(cache.backends() ~= nil)
+assert(worker.stats() ~= nil)
+assert(net.interfaces() ~= nil)
+-- Self-checks on loaded stuff
+assert(net.list()[1].transport.ip == '{{SELF_ADDR}}')
+assert(#modules.list() > 0)
+-- Self-check timers
+ev = event.recurrent(1 * sec, function (ev) return 1 end)
+event.cancel(ev)
+ev = event.after(0, function (ev) return 1 end)
diff --git a/tests/integration/deckard/template/named.j2 b/tests/integration/deckard/template/named.j2
new file mode 100644
index 0000000..bc0acb7
--- /dev/null
+++ b/tests/integration/deckard/template/named.j2
@@ -0,0 +1,106 @@
+options {
+ querylog yes;
+
+{% if ':' in SELF_ADDR %}
+ listen-on-v6 { {{SELF_ADDR}}; };
+ query-source-v6 address {{SELF_ADDR}};
+{% else %}
+ listen-on { {{SELF_ADDR}}; };
+ query-source address {{SELF_ADDR}};
+{% endif %}
+
+ edns-udp-size 4096;
+ max-cache-size 2097152;
+
+{% if QMIN == "false" %}
+qname-minimization off;
+{% else %}
+qname-minimization strict;
+{% endif %}
+
+ // Disable RFC8145 signaling, scenario doesn't provide expected ansers
+ trust-anchor-telemetry no;
+
+{% if not TRUST_ANCHOR_FILES %}
+ dnssec-validation no;
+{% else %}
+unsupported as of yet
+-- make sure that value specified at compile-time does not break tests
+{% for TAF in TRUST_ANCHOR_FILES %}
+trust_anchors.add_file('{{TAF}}')
+{% endfor %}
+{% endif %}
+
+{% if NEGATIVE_TRUST_ANCHORS %}
+unsupported as of yet
+validate-except {
+{% for DI in NEGATIVE_TRUST_ANCHORS %}
+{{DI}}
+{% endfor %}
+};
+{% endif %}
+
+};
+
+
+{% if FORWARD_ADDR %}
+zone "." {
+ type forward;
+ forward only;
+ forwarders { {{FORWARD_ADDR}}; };
+};
+{% endif %}
+
+zone "." {
+ type hint;
+ file "hints.zone";
+};
+
+
+{% if DO_NOT_QUERY_LOCALHOST == "false" %}
+{% endif %}
+
+{% if HARDEN_GLUE == "true" %}
+{% endif %}
+
+
+{% if DO_IP6 == "true" %}
+{% else %}
+server ::/0 {
+ bogus true;
+};
+{% endif %}
+
+{% if DO_IP4 == "true" %}
+{% else %}
+server 0.0.0.0/0 {
+ bogus true;
+};
+{% endif %}
+
+{% if FEATURES.min_ttl is defined %}
+min-cache-ttl {FEATURES.min_ttl}};
+min-ncache-ttl {FEATURES.min_ttl}};
+{% endif %}
+
+{% if FEATURES.max_ttl is defined %}
+max-cache-ttl {{FEATURES.max_ttl}};
+{% endif %}
+
+{% if FEATURES.dns64_prefix is defined %}
+// dns64.config('{{FEATURES.dns64_prefix}}')
+{% endif %}
+
+{% if FEATURES.static_hint_name is defined %}
+static hint unsupported
+{% endif %}
+
+logging {
+ category resolver {
+ stderr;
+ };
+ channel stderr {
+ stderr;
+ severity debug 10;
+ };
+};
diff --git a/tests/integration/deckard/template/pdns_dnssec.j2 b/tests/integration/deckard/template/pdns_dnssec.j2
new file mode 100644
index 0000000..fbb00d9
--- /dev/null
+++ b/tests/integration/deckard/template/pdns_dnssec.j2
@@ -0,0 +1,5 @@
+-- only DS records are accepted, DNSKEY records will cause errors
+-- addDS takes 2 arguments, the node in the DNS-tree and the data of the corresponding DS record
+{% for TA in TRUST_ANCHORS %}
+addDS('{{TA.split()[0]}}', '{{' '.join(TA.split()[-4:])}}')
+{% endfor %}
diff --git a/tests/integration/deckard/template/pdns_recursor.j2 b/tests/integration/deckard/template/pdns_recursor.j2
new file mode 100644
index 0000000..6bb9923
--- /dev/null
+++ b/tests/integration/deckard/template/pdns_recursor.j2
@@ -0,0 +1,326 @@
+# Autogenerated configuration file template
+#################################
+# aaaa-additional-processing turn on to do AAAA additional processing (slow)
+#
+# aaaa-additional-processing=off
+
+#################################
+# allow-from If set, only allow these comma separated netmasks to recurse
+#
+#allow-from=127.0.0.0/8, 10.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12, ::1/128, fe80::/10
+allow-from=
+
+#################################
+# allow-from-file If set, load allowed netmasks from this file
+#
+# allow-from-file=
+
+#################################
+# auth-can-lower-ttl If we follow RFC 2181 to the letter, an authoritative server can lower the TTL of NS records
+#
+# auth-can-lower-ttl=off
+
+#################################
+# auth-zones Zones for which we have authoritative data, comma separated domain=file pairs
+#
+# auth-zones=
+
+#################################
+# chroot switch to chroot jail
+#
+# chroot=
+
+#################################
+# client-tcp-timeout Timeout in seconds when talking to TCP clients
+#
+# client-tcp-timeout=2
+
+#################################
+# config-dir Location of configuration directory (recursor.conf)
+#
+# config-dir=/etc/powerdns/
+config-dir={{WORKING_DIR}}
+
+#################################
+# daemon Operate as a daemon
+#
+daemon=no
+
+#################################
+# delegation-only Which domains we only accept delegations from
+#
+# delegation-only=
+
+#################################
+# disable-edns Disable EDNS
+#
+# disable-edns=
+
+#################################
+# disable-edns-ping Disable EDNSPing
+#
+# disable-edns-ping=no
+
+#################################
+# disable-packetcache Disable packetcache
+#
+# disable-packetcache=no
+
+dnssec={% if TRUST_ANCHORS|length > 0 %}validate{%else%}process{%endif%}
+
+#################################
+# dont-query If set, do not query these netmasks for DNS data
+#
+# dont-query=127.0.0.0/8, 10.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12, ::1/128, fe80::/10
+dont-query=
+
+# prevent unnecessary fallbacks in Deckard
+edns-outgoing-bufsize=4096
+
+#################################
+# entropy-source If set, read entropy from this file
+#
+# entropy-source=/dev/urandom
+
+#################################
+# etc-hosts-file Path to 'hosts' file
+#
+# etc-hosts-file=/etc/hosts
+
+#################################
+# export-etc-hosts If we should serve up contents from /etc/hosts
+#
+# export-etc-hosts=off
+
+#################################
+# forward-zones Zones for which we forward queries, comma separated domain=ip pairs
+#
+# forward-zones=
+
+#################################
+# forward-zones-file File with (+)domain=ip pairs for forwarding
+#
+# forward-zones-file=
+
+#################################
+# forward-zones-recurse Zones for which we forward queries with recursion bit, comma separated domain=ip pairs
+#
+# forward-zones-recurse=
+{% if FORWARD_ADDR %}
+forward-zones-recurse=.={{FORWARD_ADDR}}
+{% endif %}
+
+#################################
+# hint-file If set, load root hints from this file
+#
+# hint-file=
+{% if ROOT_ADDR %}
+hint-file=hints.pdns
+{% endif %}
+
+#################################
+# ignore-rd-bit Assume each packet requires recursion, for compatability
+#
+# ignore-rd-bit=off
+
+#################################
+# local-address IP addresses to listen on, separated by spaces or commas. Also accepts ports.
+#
+local-address={{SELF_ADDR}}
+
+#################################
+# local-port port to listen on
+#
+local-port=53
+
+#################################
+# log-common-errors If we should log rather common errors
+#
+# log-common-errors=yes
+
+#################################
+# logging-facility Facility to log messages as. 0 corresponds to local0
+#
+# logging-facility=
+
+lua-config-file={{WORKING_DIR}}/dnssec.lua
+
+#################################
+# lua-dns-script Filename containing an optional 'lua' script that will be used to modify dns answers
+#
+# lua-dns-script=
+
+#################################
+# max-cache-entries If set, maximum number of entries in the main cache
+#
+# max-cache-entries=1000000
+max-cache-entries=1000000
+
+#################################
+# max-cache-ttl maximum number of seconds to keep a cached entry in memory
+#
+# max-cache-ttl=86400
+
+#################################
+# max-mthreads Maximum number of simultaneous Mtasker threads
+#
+# max-mthreads=2048
+
+#################################
+# max-negative-ttl maximum number of seconds to keep a negative cached entry in memory
+#
+# max-negative-ttl=3600
+
+#################################
+# max-packetcache-entries maximum number of entries to keep in the packetcache
+#
+# max-packetcache-entries=500000
+
+#################################
+# max-tcp-clients Maximum number of simultaneous TCP clients
+#
+# max-tcp-clients=128
+
+#################################
+# max-tcp-per-client If set, maximum number of TCP sessions per client (IP address)
+#
+# max-tcp-per-client=0
+
+#################################
+# network-timeout Wait this nummer of milliseconds for network i/o
+#
+# network-timeout=1500
+
+#################################
+# no-shuffle Don't change
+#
+# no-shuffle=off
+
+#################################
+# packetcache-servfail-ttl maximum number of seconds to keep a cached servfail entry in packetcache
+#
+# packetcache-servfail-ttl=60
+
+#################################
+# packetcache-ttl maximum number of seconds to keep a cached entry in packetcache
+#
+# packetcache-ttl=3600
+
+#################################
+# pdns-distributes-queries If PowerDNS itself should distribute queries over threads (EXPERIMENTAL)
+#
+# pdns-distributes-queries=no
+
+#################################
+# processes Launch this number of processes (EXPERIMENTAL, DO NOT CHANGE)
+#
+# processes=1
+
+#################################
+# query-local-address Source IP address for sending queries
+#
+{% if ':' in SELF_ADDR %}
+query-local-address=0.0.0.0
+query-local-address6={{SELF_ADDR}}
+{% else %}
+query-local-address={{SELF_ADDR}}
+query-local-address6=::
+{% endif %}
+
+#################################
+# query-local-address6 Source IPv6 address for sending queries
+# query-local-address6=::
+
+#################################
+# quiet Suppress logging of questions and answers
+#
+quiet=no
+
+#################################
+# remotes-ringbuffer-entries maximum number of packets to store statistics for
+#
+# remotes-ringbuffer-entries=0
+
+security-poll-suffix=
+
+#################################
+# serve-rfc1918 If we should be authoritative for RFC 1918 private IP space
+#
+serve-rfc1918=no
+
+#################################
+# server-id Returned when queried for 'server.id' TXT or NSID, defaults to hostname
+#
+# server-id=
+
+#################################
+# setgid If set, change group id to this gid for more security
+#
+#setgid=pdns
+
+#################################
+# setuid If set, change user id to this uid for more security
+#
+#setuid=pdns
+
+#################################
+# single-socket If set, only use a single socket for outgoing queries
+#
+# single-socket=off
+
+#################################
+# soa-minimum-ttl Don't change
+#
+# soa-minimum-ttl=0
+
+#################################
+# soa-serial-offset Don't change
+#
+# soa-serial-offset=0
+
+#################################
+# socket-dir Where the controlsocket will live
+#
+socket-dir={{WORKING_DIR}}
+
+#################################
+# socket-group Group of socket
+#
+# socket-group=
+
+#################################
+# socket-mode Permissions for socket
+#
+# socket-mode=
+
+#################################
+# socket-owner Owner of socket
+#
+# socket-owner=
+
+#################################
+# spoof-nearmiss-max If non-zero, assume spoofing after this many near misses
+#
+# spoof-nearmiss-max=20
+
+#################################
+# stack-size stack size per mthread
+#
+# stack-size=200000
+
+#################################
+# threads Launch this number of threads
+#
+threads=1
+
+#################################
+# trace if we should output heaps of logging
+#
+trace=on
+
+#################################
+# version-string string reported on version.pdns or version.bind
+#
+# version-string=PowerDNS Recursor 3.3 $Id: pdns_recursor.cc 1712 2010-09-11 13:40:03Z ahu $
+
+
diff --git a/tests/integration/deckard/template/unbound.j2 b/tests/integration/deckard/template/unbound.j2
new file mode 100644
index 0000000..eccf8fa
--- /dev/null
+++ b/tests/integration/deckard/template/unbound.j2
@@ -0,0 +1,801 @@
+#
+# Example configuration file.
+#
+# See unbound.conf(5) man page, version 1.5.10.
+#
+# this is a comment.
+
+#Use this to include other text into the file.
+#include: "otherfile.conf"
+
+# The server clause sets the main parameters.
+server:
+ # whitespace is not necessary, but looks cleaner.
+ trust-anchor-signaling: no
+
+ # verbosity number, 0 is least verbose. 1 is default.
+ verbosity: 3
+
+ # print statistics to the log (for every thread) every N seconds.
+ # Set to "" or 0 to disable. Default is disabled.
+ # Needs to be disabled for munin plugin
+ statistics-interval: 0
+
+ # enable cumulative statistics, without clearing them after printing.
+ # Needs to be disabled for munin plugin
+ statistics-cumulative: no
+
+ # enable extended statistics (query types, answer codes, status)
+ # printed from unbound-control. default off, because of speed.
+ # Needs to be enabled for munin plugin
+ extended-statistics: yes
+
+ # number of threads to create. 1 disables threading.
+ num-threads: 1
+
+ # specify the interfaces to answer queries from by ip-address.
+ # The default is to listen to localhost (127.0.0.1 and ::1).
+ # specify 0.0.0.0 and ::0 to bind to all available interfaces.
+ # specify every interface[@port] on a new 'interface:' labelled line.
+ # The listen interfaces are not changed on reload, only on restart.
+ interface: {{SELF_ADDR}}
+ # interface: ::0
+ # interface: 192.0.2.153
+ # interface: 192.0.2.154
+ # interface: 192.0.2.154@5003
+ # interface: 2001:DB8::5
+ #
+ # for dns over tls and raw dns over port 80
+ # interface: 0.0.0.0@443
+ # interface: ::0@443
+ # interface: 0.0.0.0@80
+ # interface: ::0@80
+
+ # enable this feature to copy the source address of queries to reply.
+ # Socket options are not supported on all platforms. experimental.
+ # interface-automatic: yes
+ #
+ # NOTE: Enable this option when specifying interface 0.0.0.0 or ::0
+ # NOTE: Disabled per Fedora policy not to listen to * on default install
+ # NOTE: If deploying on non-default port, eg 80/443, this needs to be disabled
+ interface-automatic: no
+
+ # port to answer queries from
+ # port: 53
+
+ # specify the interfaces to send outgoing queries to authoritative
+ # server from by ip-address. If none, the default (all) interface
+ # is used. Specify every interface on a 'outgoing-interface:' line.
+ outgoing-interface: {{SELF_ADDR}}
+ # outgoing-interface: 2001:DB8::5
+ # outgoing-interface: 2001:DB8::6
+
+ # Specify a netblock to use remainder 64 bits as random bits for
+ # upstream queries. Uses freebind option (Linux).
+ # outgoing-interface: 2001:DB8::/64
+ # Also (Linux:) ip -6 addr add 2001:db8::/64 dev lo
+ # And: ip -6 route add local 2001:db8::/64 dev lo
+ # And set prefer-ip6: yes to use the ip6 randomness from a netblock.
+ # Set this to yes to prefer ipv6 upstream servers over ipv4.
+ # prefer-ip6: no
+
+ # number of ports to allocate per thread, determines the size of the
+ # port range that can be open simultaneously. About double the
+ # num-queries-per-thread, or, use as many as the OS will allow you.
+ # outgoing-range: 4096
+
+ # permit unbound to use this port number or port range for
+ # making outgoing queries, using an outgoing interface.
+ # Only ephemeral ports are allowed by SElinux
+ #outgoing-port-permit: 32768-60999
+
+ # deny unbound the use this of port number or port range for
+ # making outgoing queries, using an outgoing interface.
+ # Use this to make sure unbound does not grab a UDP port that some
+ # other server on this computer needs. The default is to avoid
+ # IANA-assigned port numbers.
+ # If multiple outgoing-port-permit and outgoing-port-avoid options
+ # are present, they are processed in order.
+ # Our SElinux policy does not allow non-ephemeral ports to be used
+ #outgoing-port-avoid: 0-32767
+
+ # number of outgoing simultaneous tcp buffers to hold per thread.
+ # outgoing-num-tcp: 10
+
+ # number of incoming simultaneous tcp buffers to hold per thread.
+ # incoming-num-tcp: 10
+
+ # buffer size for UDP port 53 incoming (SO_RCVBUF socket option).
+ # 0 is system default. Use 4m to catch query spikes for busy servers.
+ # so-rcvbuf: 0
+
+ # buffer size for UDP port 53 outgoing (SO_SNDBUF socket option).
+ # 0 is system default. Use 4m to handle spikes on very busy servers.
+ # so-sndbuf: 0
+
+ # use SO_REUSEPORT to distribute queries over threads.
+ # so-reuseport: no
+
+ # use IP_TRANSPARENT so the interface: addresses can be non-local
+ # and you can config non-existing IPs that are going to work later on
+ # (uses IP_BINDANY on FreeBSD).
+ #ip-transparent: yes
+
+ # use IP_FREEBIND so the interface: addresses can be non-local
+ # and you can bind to nonexisting IPs and interfaces that are down.
+ # Linux only. On Linux you also have ip-transparent that is similar.
+ # ip-freebind: no
+
+ # EDNS reassembly buffer to advertise to UDP peers (the actual buffer
+ # is set with msg-buffer-size). 1480 can solve fragmentation (timeouts).
+ edns-buffer-size: 4096
+
+ # Maximum UDP response size (not applied to TCP response).
+ # Suggested values are 512 to 4096. Default is 4096. 65536 disables it.
+ # 3072 causes +dnssec any isc.org queries to need TC=1. Helps mitigating DDOS
+ max-udp-size: 4096
+
+ # buffer size for handling DNS data. No messages larger than this
+ # size can be sent or received, by UDP or TCP. In bytes.
+ # msg-buffer-size: 65552
+
+ # the amount of memory to use for the message cache.
+ # plain value in bytes or you can append k, m or G. default is "4Mb".
+ # msg-cache-size: 4m
+
+ # the number of slabs to use for the message cache.
+ # the number of slabs must be a power of 2.
+ # more slabs reduce lock contention, but fragment memory usage.
+ # msg-cache-slabs: 4
+
+ # the number of queries that a thread gets to service.
+ # num-queries-per-thread: 1024
+
+ # if very busy, 50% queries run to completion, 50% get timeout in msec
+ # jostle-timeout: 200
+
+ # msec to wait before close of port on timeout UDP. 0 disables.
+ # delay-close: 0
+
+ # the amount of memory to use for the RRset cache.
+ # plain value in bytes or you can append k, m or G. default is "4Mb".
+ # rrset-cache-size: 4m
+
+ # the number of slabs to use for the RRset cache.
+ # the number of slabs must be a power of 2.
+ # more slabs reduce lock contention, but fragment memory usage.
+ # rrset-cache-slabs: 4
+
+ # the time to live (TTL) value lower bound, in seconds. Default 0.
+ # If more than an hour could easily give trouble due to stale data.
+ # cache-min-ttl: 0
+
+ # the time to live (TTL) value cap for RRsets and messages in the
+ # cache. Items are not cached for longer. In seconds.
+ # cache-max-ttl: 86400
+
+ # the time to live (TTL) value cap for negative responses in the cache
+ # cache-max-negative-ttl: 3600
+
+ # the time to live (TTL) value for cached roundtrip times, lameness and
+ # EDNS version information for hosts. In seconds.
+ # infra-host-ttl: 900
+
+ # minimum wait time for responses, increase if uplink is long. In msec.
+ # infra-cache-min-rtt: 50
+
+ # the number of slabs to use for the Infrastructure cache.
+ # the number of slabs must be a power of 2.
+ # more slabs reduce lock contention, but fragment memory usage.
+ # infra-cache-slabs: 4
+
+ # the maximum number of hosts that are cached (roundtrip, EDNS, lame).
+ # infra-cache-numhosts: 10000
+
+ # define a number of tags here, use with local-zone, access-control.
+ # repeat the define-tag statement to add additional tags.
+ # define-tag: "tag1 tag2 tag3"
+
+ # Enable IPv4, "yes" or "no".
+ # do-ip4: yes
+
+ # Enable IPv6, "yes" or "no".
+ {% if DO_IP6 == "true" %}
+ do-ip6: yes
+ {% else %}
+ do-ip6: no
+ {% endif %}
+
+ {% if DO_IP4 == "true" %}
+ do-ip4: yes
+ {% else %}
+ do-ip4: no
+ {% endif %}
+
+ # Enable UDP, "yes" or "no".
+ # NOTE: if setting up an unbound on tls443 for public use, you might want to
+ # disable UDP to avoid being used in DNS amplification attacks.
+ # do-udp: yes
+
+ # Enable TCP, "yes" or "no".
+ # do-tcp: yes
+
+ # upstream connections use TCP only (and no UDP), "yes" or "no"
+ # useful for tunneling scenarios, default no.
+ # tcp-upstream: no
+
+ # Maximum segment size (MSS) of TCP socket on which the server
+ # responds to queries. Default is 0, system default MSS.
+ # tcp-mss: 0
+
+ # Maximum segment size (MSS) of TCP socket for outgoing queries.
+ # Default is 0, system default MSS.
+ # outgoing-tcp-mss: 0
+
+ # Detach from the terminal, run in background, "yes" or "no".
+ do-daemonize: no
+
+ # control which clients are allowed to make (recursive) queries
+ # to this server. Specify classless netblocks with /size and action.
+ # By default everything is refused, except for localhost.
+ # Choose deny (drop message), refuse (polite error reply),
+ # allow (recursive ok), allow_snoop (recursive and nonrecursive ok)
+ # deny_non_local (drop queries unless can be answered from local-data)
+ # refuse_non_local (like deny_non_local but polite error reply).
+ # access-control: 0.0.0.0/0 refuse
+ # access-control: 127.0.0.0/8 allow
+ access-control: ::0/0 allow_snoop
+ # access-control: ::1 allow
+ # access-control: ::ffff:127.0.0.1 allow
+
+ # tag access-control with list of tags (in "" with spaces between)
+ # Clients using this access control element use localzones that
+ # are tagged with one of these tags.
+ # access-control-tag: 192.0.2.0/24 "tag2 tag3"
+
+ # set action for particular tag for given access control element
+ # if you have multiple tag values, the tag used to lookup the action
+ # is the first tag match between access-control-tag and local-zone-tag
+ # where "first" comes from the order of the define-tag values.
+ # access-control-tag-action: 192.0.2.0/24 tag3 refuse
+
+ # set redirect data for particular tag for access control element
+ # access-control-tag-data: 192.0.2.0/24 tag2 "A 127.0.0.1"
+
+ # if given, a chroot(2) is done to the given directory.
+ # i.e. you can chroot to the working directory, for example,
+ # for extra security, but make sure all files are in that directory.
+ #
+ # If chroot is enabled, you should pass the configfile (from the
+ # commandline) as a full path from the original root. After the
+ # chroot has been performed the now defunct portion of the config
+ # file path is removed to be able to reread the config after a reload.
+ #
+ # All other file paths (working dir, logfile, roothints, and
+ # key files) can be specified in several ways:
+ # o as an absolute path relative to the new root.
+ # o as a relative path to the working directory.
+ # o as an absolute path relative to the original root.
+ # In the last case the path is adjusted to remove the unused portion.
+ #
+ # The pid file can be absolute and outside of the chroot, it is
+ # written just prior to performing the chroot and dropping permissions.
+ #
+ # Additionally, unbound may need to access /dev/random (for entropy).
+ # How to do this is specific to your OS.
+ #
+ # If you give "" no chroot is performed. The path must not end in a /.
+ # chroot: "/var/lib/unbound"
+ chroot: ""
+
+ # if given, user privileges are dropped (after binding port),
+ # and the given username is assumed. Default is user "unbound".
+ # If you give "" no privileges are dropped.
+ username: ""
+
+ # the working directory. The relative files in this config are
+ # relative to this directory. If you give "" the working directory
+ # is not changed.
+ # If you give a server: directory: dir before include: file statements
+ # then those includes can be relative to the working directory.
+ directory: ""
+
+ # the log file, "" means log to stderr.
+ # Use of this option sets use-syslog to "no".
+ # logfile: ""
+
+ # Log to syslog(3) if yes. The log facility LOG_DAEMON is used to
+ # log to, with identity "unbound". If yes, it overrides the logfile.
+ use-syslog: no
+
+ # print UTC timestamp in ascii to logfile, default is epoch in seconds.
+ log-time-ascii: yes
+
+ # print one line with time, IP, name, type, class for every query.
+ log-queries: yes
+
+ # the pid file. Can be an absolute path outside of chroot/work dir.
+ pidfile: "unbound.pid"
+
+ # file to read root hints from.
+ # get one from https://www.internic.net/domain/named.cache
+ {% if ROOT_ADDR %}
+ root-hints: "hints.zone"
+ {% endif %}
+
+ # enable to not answer id.server and hostname.bind queries.
+ # hide-identity: no
+
+ # enable to not answer version.server and version.bind queries.
+ # hide-version: no
+
+ # the identity to report. Leave "" or default to return hostname.
+ # identity: ""
+
+ # the version to report. Leave "" or default to return package version.
+ # version: ""
+
+ # the target fetch policy.
+ # series of integers describing the policy per dependency depth.
+ # The number of values in the list determines the maximum dependency
+ # depth the recursor will pursue before giving up. Each integer means:
+ # -1 : fetch all targets opportunistically,
+ # 0: fetch on demand,
+ # positive value: fetch that many targets opportunistically.
+ # Enclose the list of numbers between quotes ("").
+ target-fetch-policy: "0 0 0 0 0"
+
+ # Harden against very small EDNS buffer sizes.
+ # harden-short-bufsize: no
+
+ # Harden against unseemly large queries.
+ # harden-large-queries: no
+
+ # Harden against out of zone rrsets, to avoid spoofing attempts.
+
+ {% if HARDEN_GLUE == "true" %}
+ harden-glue: yes
+ {% else %}
+ harden-glue: no
+ {% endif %}
+
+ # Harden against receiving dnssec-stripped data. If you turn it
+ # off, failing to validate dnskey data for a trustanchor will
+ # trigger insecure mode for that zone (like without a trustanchor).
+ # Default on, which insists on dnssec data for trust-anchored zones.
+ harden-dnssec-stripped: yes
+
+ # Harden against queries that fall under dnssec-signed nxdomain names.
+ harden-below-nxdomain: yes
+
+ # Harden the referral path by performing additional queries for
+ # infrastructure data. Validates the replies (if possible).
+ # Default off, because the lookups burden the server. Experimental
+ # implementation of draft-wijngaards-dnsext-resolver-side-mitigation.
+ harden-referral-path: yes
+
+ # Harden against algorithm downgrade when multiple algorithms are
+ # advertised in the DS record. If no, allows the weakest algorithm
+ # to validate the zone.
+ harden-algo-downgrade: yes
+
+ # Sent minimum amount of information to upstream servers to enhance
+ # privacy. Only sent minimum required labels of the QNAME and set QTYPE
+ # to NS when possible.
+ {% if QMIN == "false" %}
+ qname-minimisation: no
+ {% else %}
+ qname-minimisation: yes
+ {% endif %}
+
+ # Use 0x20-encoded random bits in the query to foil spoof attempts.
+ # This feature is an experimental implementation of draft dns-0x20.
+ use-caps-for-id: yes
+
+ # Domains (and domains in them) without support for dns-0x20 and
+ # the fallback fails because they keep sending different answers.
+ # caps-whitelist: "licdn.com"
+ # caps-whitelist: "senderbase.org"
+
+ # Enforce privacy of these addresses. Strips them away from answers.
+ # It may cause DNSSEC validation to additionally mark it as bogus.
+ # Protects against 'DNS Rebinding' (uses browser as network proxy).
+ # Only 'private-domain' and 'local-data' names are allowed to have
+ # these private addresses. No default.
+ # private-address: 10.0.0.0/8
+ # private-address: 172.16.0.0/12
+ # private-address: 192.168.0.0/16
+ # private-address: 169.254.0.0/16
+ # private-address: fd00::/8
+ # private-address: fe80::/10
+ # private-address: ::ffff:0:0/96
+
+ # Allow the domain (and its subdomains) to contain private addresses.
+ # local-data statements are allowed to contain private addresses too.
+ # private-domain: "example.com"
+
+ # If nonzero, unwanted replies are not only reported in statistics,
+ # but also a running total is kept per thread. If it reaches the
+ # threshold, a warning is printed and a defensive action is taken,
+ # the cache is cleared to flush potential poison out of it.
+ # A suggested value is 10000000, the default is 0 (turned off).
+ unwanted-reply-threshold: 10000000
+
+ # Do not query the following addresses. No DNS queries are sent there.
+ # List one address per entry. List classless netblocks with /size,
+ # do-not-query-address: 127.0.0.1/8
+ # do-not-query-address: ::1
+
+ # if yes, the above default do-not-query-address entries are present.
+ # if no, localhost can be queried (for testing and debugging).
+ {% if DO_NOT_QUERY_LOCALHOST == "false" %}
+ do-not-query-localhost: no
+ {% else %}
+ do-not-query-localhost: yes
+ {% endif %}
+
+ # if yes, perform prefetching of almost expired message cache entries.
+ prefetch: no
+
+ # if yes, perform key lookups adjacent to normal lookups.
+ prefetch-key: no
+
+ # if yes, Unbound rotates RRSet order in response.
+ rrset-roundrobin: yes
+
+ # if yes, Unbound doesn't insert authority/additional sections
+ # into response messages when those sections are not required.
+ minimal-responses: no
+
+ # true to disable DNSSEC lameness check in iterator.
+ # disable-dnssec-lame-check: no
+
+ # module configuration of the server. A string with identifiers
+ # separated by spaces. Syntax: "[dns64] [validator] iterator"
+ # module-config: "validator iterator"
+
+ # File with trusted keys, kept uptodate using RFC5011 probes,
+ # initial file like trust-anchor-file, then it stores metadata.
+ # Use several entries, one per domain name, to track multiple zones.
+ #
+ # If you want to perform DNSSEC validation, run unbound-anchor before
+ # you start unbound (i.e. in the system boot scripts). And enable:
+ # Please note usage of unbound-anchor root anchor is at your own risk
+ # and under the terms of our LICENSE (see that file in the source).
+ # auto-trust-anchor-file: "/var/lib/unbound/root.key"
+
+ {% for TAF in TRUST_ANCHOR_FILES %}
+ auto-trust-anchor-file: "{{TAF}}"
+ {% endfor %}
+
+ # File with DLV trusted keys. Same format as trust-anchor-file.
+ # There can be only one DLV configured, it is trusted from root down.
+ # DLV is going to be decommissioned. Please do not use it any more.
+ # dlv-anchor-file: "dlv.isc.org.key"
+
+ # File with trusted keys for validation. Specify more than one file
+ # with several entries, one file per entry.
+ # Zone file format, with DS and DNSKEY entries.
+ # Note this gets out of date, use auto-trust-anchor-file please.
+
+ # Trusted key for validation. DS or DNSKEY. specify the RR on a
+ # single line, surrounded by "". TTL is ignored. class is IN default.
+ # Note this gets out of date, use auto-trust-anchor-file please.
+ # (These examples are from August 2007 and may not be valid anymore).
+ # trust-anchor: "jelte.nlnetlabs.nl. DS 42860 5 1 14D739EB566D2B1A5E216A0BA4D17FA9B038BE4A"
+
+ # File with trusted keys for validation. Specify more than one file
+ # with several entries, one file per entry. Like trust-anchor-file
+ # but has a different file format. Format is BIND-9 style format,
+ # the trusted-keys { name flag proto algo "key"; }; clauses are read.
+ # you need external update procedures to track changes in keys.
+ # trusted-keys-file: ""
+ #
+ #trusted-keys-file: /etc/unbound/keys.d/*.key
+ #auto-trust-anchor-file: "/var/lib/unbound/root.key"
+
+ # Ignore chain of trust. Domain is treated as insecure.
+ # domain-insecure: "example.com"
+ {% for DI in NEGATIVE_TRUST_ANCHORS %}
+ domain-insecure: "{{DI}}"
+ {% endfor %}
+
+
+ # Override the date for validation with a specific fixed date.
+ # Do not set this unless you are debugging signature inception
+ # and expiration. "" or "0" turns the feature off. -1 ignores date.
+ # val-override-date: ""
+
+ # The time to live for bogus data, rrsets and messages. This avoids
+ # some of the revalidation, until the time interval expires. in secs.
+ # val-bogus-ttl: 60
+
+ # The signature inception and expiration dates are allowed to be off
+ # by 10% of the signature lifetime (expir-incep) from our local clock.
+ # This leeway is capped with a minimum and a maximum. In seconds.
+ # val-sig-skew-min: 3600
+ # val-sig-skew-max: 86400
+
+ # Should additional section of secure message also be kept clean of
+ # unsecure data. Useful to shield the users of this validator from
+ # potential bogus data in the additional section. All unsigned data
+ # in the additional section is removed from secure messages.
+ val-clean-additional: yes
+
+ # Turn permissive mode on to permit bogus messages. Thus, messages
+ # for which security checks failed will be returned to clients,
+ # instead of SERVFAIL. It still performs the security checks, which
+ # result in interesting log files and possibly the AD bit in
+ # replies if the message is found secure. The default is off.
+ # NOTE: TURNING THIS ON DISABLES ALL DNSSEC SECURITY
+ val-permissive-mode: no
+
+ # Ignore the CD flag in incoming queries and refuse them bogus data.
+ # Enable it if the only clients of unbound are legacy servers (w2008)
+ # that set CD but cannot validate themselves.
+ # ignore-cd-flag: no
+
+ # Have the validator log failed validations for your diagnosis.
+ # 0: off. 1: A line per failed user query. 2: With reason and bad IP.
+ val-log-level: 2
+
+ # It is possible to configure NSEC3 maximum iteration counts per
+ # keysize. Keep this table very short, as linear search is done.
+ # A message with an NSEC3 with larger count is marked insecure.
+ # List in ascending order the keysize and count values.
+ # val-nsec3-keysize-iterations: "1024 150 2048 500 4096 2500"
+
+ # instruct the auto-trust-anchor-file probing to add anchors after ttl.
+ # add-holddown: 2592000 # 30 days
+
+ # instruct the auto-trust-anchor-file probing to del anchors after ttl.
+ # del-holddown: 2592000 # 30 days
+
+ # auto-trust-anchor-file probing removes missing anchors after ttl.
+ # If the value 0 is given, missing anchors are not removed.
+ # keep-missing: 31622400 # 366 days
+
+ # debug option that allows very small holddown times for key rollover,
+ # otherwise the RFC mandates probe intervals must be at least 1 hour.
+ # permit-small-holddown: no
+
+ # the amount of memory to use for the key cache.
+ # plain value in bytes or you can append k, m or G. default is "4Mb".
+ # key-cache-size: 4m
+
+ # the number of slabs to use for the key cache.
+ # the number of slabs must be a power of 2.
+ # more slabs reduce lock contention, but fragment memory usage.
+ # key-cache-slabs: 4
+
+ # the amount of memory to use for the negative cache (used for DLV).
+ # plain value in bytes or you can append k, m or G. default is "1Mb".
+ # neg-cache-size: 1m
+
+ # By default, for a number of zones a small default 'nothing here'
+ # reply is built-in. Query traffic is thus blocked. If you
+ # wish to serve such zone you can unblock them by uncommenting one
+ # of the nodefault statements below.
+ # You may also have to use domain-insecure: zone to make DNSSEC work,
+ # unless you have your own trust anchors for this zone.
+ local-zone: "test." nodefault
+ local-zone: "localhost." nodefault
+ local-zone: "127.in-addr.arpa." nodefault
+ local-zone: "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa." nodefault
+ local-zone: "onion." nodefault
+ local-zone: "10.in-addr.arpa." nodefault
+ local-zone: "16.172.in-addr.arpa." nodefault
+ local-zone: "17.172.in-addr.arpa." nodefault
+ local-zone: "18.172.in-addr.arpa." nodefault
+ local-zone: "19.172.in-addr.arpa." nodefault
+ local-zone: "20.172.in-addr.arpa." nodefault
+ local-zone: "21.172.in-addr.arpa." nodefault
+ local-zone: "22.172.in-addr.arpa." nodefault
+ local-zone: "23.172.in-addr.arpa." nodefault
+ local-zone: "24.172.in-addr.arpa." nodefault
+ local-zone: "25.172.in-addr.arpa." nodefault
+ local-zone: "26.172.in-addr.arpa." nodefault
+ local-zone: "27.172.in-addr.arpa." nodefault
+ local-zone: "28.172.in-addr.arpa." nodefault
+ local-zone: "29.172.in-addr.arpa." nodefault
+ local-zone: "30.172.in-addr.arpa." nodefault
+ local-zone: "31.172.in-addr.arpa." nodefault
+ local-zone: "168.192.in-addr.arpa." nodefault
+ local-zone: "0.in-addr.arpa." nodefault
+ local-zone: "254.169.in-addr.arpa." nodefault
+ local-zone: "2.0.192.in-addr.arpa." nodefault
+ local-zone: "100.51.198.in-addr.arpa." nodefault
+ local-zone: "113.0.203.in-addr.arpa." nodefault
+ local-zone: "255.255.255.255.in-addr.arpa." nodefault
+ local-zone: "0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa." nodefault
+ local-zone: "d.f.ip6.arpa." nodefault
+ local-zone: "8.e.f.ip6.arpa." nodefault
+ local-zone: "9.e.f.ip6.arpa." nodefault
+ local-zone: "a.e.f.ip6.arpa." nodefault
+ local-zone: "b.e.f.ip6.arpa." nodefault
+ local-zone: "8.b.d.0.1.0.0.2.ip6.arpa." nodefault
+ # And for 64.100.in-addr.arpa. to 127.100.in-addr.arpa.
+
+ # If unbound is running service for the local host then it is useful
+ # to perform lan-wide lookups to the upstream, and unblock the
+ # long list of local-zones above. If this unbound is a dns server
+ # for a network of computers, disabled is better and stops information
+ # leakage of local lan information.
+ unblock-lan-zones: yes
+
+ # The insecure-lan-zones option disables validation for
+ # these zones, as if they were all listed as domain-insecure.
+ # insecure-lan-zones: no
+
+ # a number of locally served zones can be configured.
+ # local-zone: <zone> <type>
+ # local-data: "<resource record string>"
+ # o deny serves local data (if any), else, drops queries.
+ # o refuse serves local data (if any), else, replies with error.
+ # o static serves local data, else, nxdomain or nodata answer.
+ # o transparent gives local data, but resolves normally for other names
+ # o redirect serves the zone data for any subdomain in the zone.
+ # o nodefault can be used to normally resolve AS112 zones.
+ # o typetransparent resolves normally for other types and other names
+ # o inform resolves normally, but logs client IP address
+ # o inform_deny drops queries and logs client IP address
+ # o always_transparent, always_refuse, always_nxdomain, resolve in
+ # that way but ignore local data for that name.
+ #
+ # defaults are localhost address, reverse for 127.0.0.1 and ::1
+ # and nxdomain for AS112 zones. If you configure one of these zones
+ # the default content is omitted, or you can omit it with 'nodefault'.
+ #
+ # If you configure local-data without specifying local-zone, by
+ # default a transparent local-zone is created for the data.
+ #
+ # You can add locally served data with
+ # local-zone: "local." static
+ # local-data: "mycomputer.local. IN A 192.0.2.51"
+ # local-data: 'mytext.local TXT "content of text record"'
+ #
+ # You can override certain queries with
+ # local-data: "adserver.example.com A 127.0.0.1"
+ #
+ # You can redirect a domain to a fixed address with
+ # (this makes example.com, www.example.com, etc, all go to 192.0.2.3)
+ # local-zone: "example.com" redirect
+ # local-data: "example.com A 192.0.2.3"
+ #
+ # Shorthand to make PTR records, "IPv4 name" or "IPv6 name".
+ # You can also add PTR records using local-data directly, but then
+ # you need to do the reverse notation yourself.
+ # local-data-ptr: "192.0.2.3 www.example.com"
+
+ #include: /etc/unbound/local.d/*.conf
+
+ # tag a localzone with a list of tag names (in "" with spaces between)
+ # local-zone-tag: "example.com" "tag2 tag3"
+
+ # add a netblock specific override to a localzone, with zone type
+ # local-zone-override: "example.com" 192.0.2.0/24 refuse
+
+ # service clients over SSL (on the TCP sockets), with plain DNS inside
+ # the SSL stream. Give the certificate to use and private key.
+ # default is "" (disabled). requires restart to take effect.
+ # ssl-service-key: "/etc/unbound/unbound_server.key"
+ # ssl-service-pem: "/etc/unbound/unbound_server.pem"
+ # ssl-port: 443
+ #
+ # request upstream over SSL (with plain DNS inside the SSL stream).
+ # Default is no. Can be turned on and off with unbound-control.
+ # ssl-upstream: no
+
+ # DNS64 prefix. Must be specified when DNS64 is use.
+ # Enable dns64 in module-config. Used to synthesize IPv6 from IPv4.
+ # dns64-prefix: 64:ff9b::0/96
+
+ # ratelimit for uncached, new queries, this limits recursion effort.
+ # ratelimiting is experimental, and may help against randomqueryflood.
+ # if 0(default) it is disabled, otherwise state qps allowed per zone.
+ # ratelimit: 0
+
+ # ratelimits are tracked in a cache, size in bytes of cache (or k,m).
+ # ratelimit-size: 4m
+ # ratelimit cache slabs, reduces lock contention if equal to cpucount.
+ # ratelimit-slabs: 4
+
+ # 0 blocks when ratelimited, otherwise let 1/xth traffic through
+ # ratelimit-factor: 10
+
+ # override the ratelimit for a specific domain name.
+ # give this setting multiple times to have multiple overrides.
+ # ratelimit-for-domain: example.com 1000
+ # override the ratelimits for all domains below a domain name
+ # can give this multiple times, the name closest to the zone is used.
+ # ratelimit-below-domain: com 1000
+
+# Python config section. To enable:
+# o use --with-pythonmodule to configure before compiling.
+# o list python in the module-config string (above) to enable.
+# o and give a python-script to run.
+python:
+ # Script file to load
+ # python-script: "/etc/unbound/ubmodule-tst.py"
+
+# Remote control config section.
+remote-control:
+ # Enable remote control with unbound-control(8) here.
+ # set up the keys and certificates with unbound-control-setup.
+ # Note: required for unbound-munin package
+ control-enable: no
+
+ # Set to no and use an absolute path as control-interface to use
+ # a unix local named pipe for unbound-control.
+ # control-use-cert: yes
+
+ # what interfaces are listened to for remote control.
+ # give 0.0.0.0 and ::0 to listen to all interfaces.
+ # control-interface: 127.0.0.1
+ # control-interface: ::1
+
+ # port number for remote control operations.
+ # control-port: 8953
+
+ # unbound server key file.
+ #server-key-file: "/etc/unbound/unbound_server.key"
+
+ # unbound server certificate file.
+ #server-cert-file: "/etc/unbound/unbound_server.pem"
+
+ # unbound-control key file.
+ #control-key-file: "/etc/unbound/unbound_control.key"
+
+ # unbound-control certificate file.
+ #control-cert-file: "/etc/unbound/unbound_control.pem"
+
+# Stub and Forward zones
+#include: /etc/unbound/conf.d/*.conf
+
+# Stub zones.
+# Create entries like below, to make all queries for 'example.com' and
+# 'example.org' go to the given list of nameservers. list zero or more
+# nameservers by hostname or by ipaddress. If you set stub-prime to yes,
+# the list is treated as priming hints (default is no).
+# With stub-first yes, it attempts without the stub if it fails.
+# Consider adding domain-insecure: name and local-zone: name nodefault
+# to the server: section if the stub is a locally served zone.
+# stub-zone:
+# name: "example.com"
+# stub-addr: 192.0.2.68
+# stub-prime: no
+# stub-first: no
+# stub-zone:
+# name: "example.org"
+# stub-host: ns.example.com.
+
+# You can now also dynamically create and delete stub-zone's using
+# unbound-control stub_add domain.com 1.2.3.4 5.6.7.8
+# unbound-control stub_remove domain.com 1.2.3.4 5.6.7.8
+
+# Forward zones
+# Create entries like below, to make all queries for 'example.com' and
+# 'example.org' go to the given list of servers. These servers have to handle
+# recursion to other nameservers. List zero or more nameservers by hostname
+# or by ipaddress. Use an entry with name "." to forward all queries.
+# If you enable forward-first, it attempts without the forward if it fails.
+
+{% if FORWARD_ADDR %}
+forward-zone:
+ name: "."
+ forward-addr: {{FORWARD_ADDR}}
+ forward-first: no
+{% endif %}
+
+# forward-zone:
+# name: "example.com"
+# forward-addr: 192.0.2.68
+# forward-addr: 192.0.2.73@5355 # forward to port 5355.
+# forward-first: no
+# forward-zone:
+# name: "example.org"
+# forward-host: fwd.example.com
+#
+# You can now also dynamically create and delete forward-zone's using
+# unbound-control forward_add domain.com 1.2.3.4 5.6.7.8
+# unbound-control forward_remove domain.com 1.2.3.4 5.6.7.8
diff --git a/tests/integration/deckard/template/unbound_dnssec.j2 b/tests/integration/deckard/template/unbound_dnssec.j2
new file mode 100644
index 0000000..282dc9f
--- /dev/null
+++ b/tests/integration/deckard/template/unbound_dnssec.j2
@@ -0,0 +1,3 @@
+{% for TA in TRUST_ANCHORS %}
+{{TA}}
+{% endfor %}
diff --git a/tests/integration/deckard/tests/__init__.py b/tests/integration/deckard/tests/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/integration/deckard/tests/__init__.py
diff --git a/tests/integration/deckard/tests/deckard_raw_id.rpl b/tests/integration/deckard/tests/deckard_raw_id.rpl
new file mode 100644
index 0000000..831c566
--- /dev/null
+++ b/tests/integration/deckard/tests/deckard_raw_id.rpl
@@ -0,0 +1,14 @@
+stub-addr: 1.2.3.4
+CONFIG_END
+SCENARIO_BEGIN Sanity check for Deckard's "ADJUST raw_id" option
+RANGE_BEGIN 0 100
+ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode
+ADJUST raw_id
+RAW
+0000
+ENTRY_END
+RANGE_END
+STEP 1 TIME_PASSES ELAPSE 1
+SCENARIO_END
diff --git a/tests/integration/deckard/tests/deckard_raw_id.yml b/tests/integration/deckard/tests/deckard_raw_id.yml
new file mode 100644
index 0000000..1650a2f
--- /dev/null
+++ b/tests/integration/deckard/tests/deckard_raw_id.yml
@@ -0,0 +1,6 @@
+programs:
+- name: raw_id
+ binary: test_raw_id.py
+ additional: []
+ templates: []
+ configs: []
diff --git a/tests/integration/deckard/tests/test_deckard.py b/tests/integration/deckard/tests/test_deckard.py
new file mode 100644
index 0000000..50096ea
--- /dev/null
+++ b/tests/integration/deckard/tests/test_deckard.py
@@ -0,0 +1,30 @@
+""" This is unittest file for parse methods in scenario.py """
+import os
+import shutil
+import tempfile
+
+from deckard import create_trust_anchor_files
+
+
+def test_create_trust_anchor_files():
+ """Trust anchors must be into separate files grouped by domain."""
+ anchor1a = u'domain1.com.\t3600\tIN\tDS\t11901 7 1 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
+ anchor1b = u'domain1.com.\t3600\tIN\tDS\t11902 7 1 1111111111111111111111111111111111111111'
+ anchor2a = u'domain2.net.\t3600\tIN\tDS\t59835 7 1 cccccccccccccccccccccccccccccccccccccccc'
+ trust_anchors = {'domain1.com': [anchor1a, anchor1b],
+ 'domain2.net': [anchor2a]}
+
+ tmpdir = tempfile.mkdtemp()
+ try:
+ file_names = create_trust_anchor_files(trust_anchors, tmpdir)
+ assert sorted(file_names) == sorted('{wd}/ta/{f}'.format(wd=tmpdir, f=f)
+ for f in [u'domain1.com.key', u'domain2.net.key'])
+ for path in file_names:
+ with open(path) as ta_file:
+ file_name = os.path.basename(path)
+ assert file_name[-4:] == '.key'
+ domain = file_name[:-4]
+ assert ta_file.read() == ''.join(u'{}\n'.format(ta)
+ for ta in trust_anchors[domain])
+ finally:
+ shutil.rmtree(tmpdir)
diff --git a/tests/integration/deckard/tools/answer_checker.py b/tests/integration/deckard/tools/answer_checker.py
new file mode 100644
index 0000000..3754ef3
--- /dev/null
+++ b/tests/integration/deckard/tools/answer_checker.py
@@ -0,0 +1,84 @@
+"""Functions for sending DNS queries and checking recieved answers checking"""
+# pylint: disable=C0301
+# flake8: noqa
+
+from ipaddress import IPv4Address, IPv6Address
+import random
+from typing import Iterable, Optional, Set, Union
+
+import dns.message
+import dns.flags
+
+import pydnstest.matchpart
+import pydnstest.mock_client
+
+def unset_flag(message: dns.message.Message, flag: int) -> dns.message.Message:
+ """Unsets given flag in given DNS message."""
+ message.flags &= ~flag
+ return message
+
+
+def send_and_check(question: Union[dns.message.Message, bytes], # pylint: disable=R0913
+ expected: dns.message.Message,
+ server: Union[IPv4Address, IPv6Address],
+ match_fields: Set[str],
+ port: int = 53,
+ tcp: bool = False,
+ timeout: int = pydnstest.mock_client.SOCKET_OPERATION_TIMEOUT,
+ unset_flags: Iterable[int] = tuple()) -> bool:
+ """Checks if DNS answer recieved for a question from a server matches expected one in specified
+ field. See pydnstest.matchpart for more information on match fields
+
+ Returns True on success, raises an exceptions on failure.
+ """
+ print("Sending query:\n%s\n" % str(question))
+ answer = get_answer(question, server, port, tcp, timeout=timeout)
+
+ for flag in unset_flags:
+ answer = unset_flag(answer, flag)
+
+ print("Got answer:\n%s\n" % answer)
+ print("Matching:\n%s\n%s\n" % (match_fields, expected))
+ for field in match_fields:
+ pydnstest.matchpart.match_part(expected, answer, field)
+
+ return True
+
+
+def get_answer(question: Union[dns.message.Message, bytes],
+ server: Union[IPv4Address, IPv6Address],
+ port: int = 53,
+ tcp: bool = False,
+ timeout: int = pydnstest.mock_client.SOCKET_OPERATION_TIMEOUT) -> dns.message.Message:
+ """Get an DNS message with answer with specific query"""
+ sock = pydnstest.mock_client.setup_socket(str(server), port, tcp=tcp)
+ with sock:
+ pydnstest.mock_client.send_query(sock, question)
+ return pydnstest.mock_client.get_dns_message(sock, timeout=timeout)
+
+
+def string_answer(question: Union[dns.message.Message, bytes],
+ server: Union[IPv4Address, IPv6Address],
+ port: int = 53,
+ tcp: bool = False) -> str:
+ """Prints answer of a server. Good for generating tests."""
+ return get_answer(question, server, port, tcp).to_text()
+
+
+def randomize_case(label: bytes) -> bytes:
+ """Randomize case in a DNS name label"""
+ output = []
+ for byte in label:
+ if random.randint(0, 1):
+ output.append(bytes([byte]).swapcase())
+ else:
+ output.append(bytes([byte]))
+ return b''.join(output)
+
+
+def make_random_case_query(name: str, *args, **kwargs) -> dns.message.Message:
+ """Proxy for dns.message.make_query with rANdoM-cASe"""
+ query = dns.message.make_query(name, *args, **kwargs)
+ for label in query.question[0].name.labels:
+ label = randomize_case(label)
+ return query
diff --git a/tests/integration/deckard/tools/conftest.py b/tests/integration/deckard/tools/conftest.py
new file mode 100644
index 0000000..1b865fb
--- /dev/null
+++ b/tests/integration/deckard/tools/conftest.py
@@ -0,0 +1,19 @@
+import ipaddress
+
+# These are IPs of a.ns.nic.cz
+AUTHORITATIVE_SERVERS = [ipaddress.IPv4Address("194.0.12.1"),
+ ipaddress.IPv6Address("2001:678:f::1")]
+
+
+def pytest_addoption(parser):
+ parser.addoption("--forwarder", action="append", help="IP of forwarder to test")
+
+
+def pytest_generate_tests(metafunc):
+ if 'forwarder' in metafunc.fixturenames:
+ forwarder = metafunc.config.option.forwarder
+ metafunc.parametrize("forwarder", [ipaddress.ip_address(f) for f in forwarder], ids=str)
+ if 'tcp' in metafunc.fixturenames:
+ metafunc.parametrize("tcp", [False, True], ids=lambda x: "TCP" if x else "UDP")
+ if 'server' in metafunc.fixturenames:
+ metafunc.parametrize("server", AUTHORITATIVE_SERVERS, ids=str)
diff --git a/tests/integration/deckard/tools/divide_tests.sh b/tests/integration/deckard/tools/divide_tests.sh
new file mode 100644
index 0000000..1856610
--- /dev/null
+++ b/tests/integration/deckard/tools/divide_tests.sh
@@ -0,0 +1,77 @@
+#!/bin/bash
+
+# Sorts .rpl tests into several categories.
+# Takes a diretory with the tests as an argument and moves the test to its subdirectories.
+# Env variable SCRIPT= sets *_run.sh script for finding working tests, default script is kresd_run.sh
+# Env variable DEST= sets output directory where the tests will be copied and divided into subfolders. Default value is working directory.
+
+set -o nounset
+set -o errexit
+
+SOURCE="$1"
+
+SCRIPT=${SCRIPT:-"./../kresd_run.sh"}
+DEST=${DEST:-"."}
+
+rm -rf "$DEST/sorted_tests"
+mkdir "$DEST/sorted_tests"
+for TEST in "$SOURCE/"*.rpl
+do
+ cp "$TEST" "$DEST/sorted_tests"
+done
+
+# Test with the same name is already imported in deckard/sets/resolver
+echo Already imported:
+mkdir -p "$DEST/sorted_tests/imported"
+for TEST in `comm -12 <(ls -F ../sets/resolver/*.rpl | xargs -n 1 basename) <(ls -F "$DEST/sorted_tests" | xargs -n 1 basename)`
+do
+ echo -e '\t' "$TEST"
+ mv "$DEST/sorted_tests/$TEST" "$DEST/sorted_tests/imported"
+done
+
+# Parse failed
+echo Parse failed:
+mkdir -p "$DEST/sorted_tests/parsefail"
+for TEST in "$DEST/sorted_tests/"*.rpl
+do
+ if ! python3 parse.py "$TEST" >/dev/null 2>/dev/null
+ then
+ echo -e '\t' $(basename "$TEST")
+ mv "$TEST" "$DEST/sorted_tests/parsefail"
+ fi
+done
+
+
+# Invalid DSA signatures (common in old testbound tests)
+echo Invalid DSA signatures:
+mkdir -p "$DEST/sorted_tests/invaliddsa"
+for TEST in "$DEST/sorted_tests/"*.rpl
+do
+ if ! python3 invalid_dsa.py "$TEST" >/dev/null 2>/dev/null
+ then
+ echo -e '\t' $(basename "$TEST")
+ mv "$TEST" "$DEST/sorted_tests/invaliddsa"
+ fi
+done
+
+
+# Working in selected script
+echo Working in $SCRIPT:
+mkdir -p "$DEST/sorted_tests/working"
+for TEST in "$DEST/sorted_tests/"*.rpl
+do
+ if TESTS="$(readlink -m $TEST)" $SCRIPT >/dev/null 2>/dev/null
+ then
+ echo -e '\t' $(basename "$TEST")
+ mv "$TEST" "$DEST/sorted_tests/working"
+ fi
+done
+
+echo Others:
+mkdir -p "$DEST/sorted_tests/others"
+for TEST in "$DEST/sorted_tests/"*.rpl
+do
+ echo -e '\t' $(basename "$TEST")
+ mv "$TEST" "$DEST/sorted_tests/others"
+done
+
diff --git a/tests/integration/deckard/tools/forwarder_check.py b/tests/integration/deckard/tools/forwarder_check.py
new file mode 100644
index 0000000..7660228
--- /dev/null
+++ b/tests/integration/deckard/tools/forwarder_check.py
@@ -0,0 +1,387 @@
+"""Test suite to test forwarders
+Invoke with `python3 -m pytest forwarder_check.py --forwarder [IP of forwarder]`"""
+# pylint: disable=C0301,C0111,C0103
+# flake8: noqa
+import ipaddress
+
+import dns.message
+# NOTE silence incorrectly reported error, may be removed once it passes in CI
+import pytest # pylint: disable=wrong-import-order
+
+import answer_checker
+
+ALL = {"opcode", "qtype", "qname", "flags", "rcode", "answer", "authority", "additional"}
+HEADER = {"opcode", "qtype", "qname", "flags", "rcode"}
+
+VERSION_QUERY = dns.message.make_query("_version.test.knot-resolver.cz", "TXT")
+VERSION_ANSWER = dns.message.from_text(""";
+opcode QUERY
+rcode NOERROR
+flags QR RA RD
+;QUESTION
+_version.test.knot-resolver.cz. IN TXT
+;ANSWER
+_version.test.knot-resolver.cz. 3600 IN TXT "1"
+;AUTHORITY
+;ADDITIONAL
+""")
+
+def test_zone_version(forwarder):
+ return answer_checker.send_and_check(VERSION_QUERY,
+ VERSION_ANSWER,
+ forwarder,
+ ALL - {"additional", "authority"})
+
+SIMPLE_QUERY = answer_checker.make_random_case_query("good-a.test.knot-resolver.cz", "A")
+SIMPLE_ANSWER = dns.message.from_text(""";
+opcode QUERY
+rcode NOERROR
+flags QR RD RA
+;QUESTION
+good-a.test.knot-resolver.cz. IN A
+;ANSWER
+good-a.test.knot-resolver.cz. 3600 IN A 217.31.192.130
+;AUTHORITY
+;ADDITIONAL""")
+
+def test_supports_simple_answers(forwarder, tcp):
+ return answer_checker.send_and_check(SIMPLE_QUERY,
+ SIMPLE_ANSWER,
+ forwarder,
+ ALL - {"additional", "authority"},
+ tcp=tcp)
+
+EDNS_QUERY = answer_checker.make_random_case_query("good-a.test.knot-resolver.cz", "A", use_edns=0)
+
+
+def test_supports_EDNS0(forwarder, tcp):
+ answer = answer_checker.get_answer(EDNS_QUERY, forwarder, tcp=tcp)
+ if answer.edns != 0:
+ raise ValueError("EDNS0 not supported")
+
+DO_QUERY = answer_checker.make_random_case_query("good-a.test.knot-resolver.cz", "A", want_dnssec=True)
+
+
+def test_supports_DO(forwarder, tcp):
+ answer = answer_checker.get_answer(DO_QUERY, forwarder, tcp=tcp)
+ if not answer.flags & dns.flags.DO:
+ raise ValueError("DO bit sent, but not recieved")
+
+CD_QUERY = answer_checker.make_random_case_query("good-a.test.knot-resolver.cz", "A", want_dnssec=True)
+CD_QUERY.flags += dns.flags.CD
+
+
+def test_supports_CD(forwarder, tcp):
+ answer = answer_checker.get_answer(CD_QUERY, forwarder, tcp=tcp)
+ if not answer.flags & dns.flags.CD:
+ raise ValueError("CD bit sent, but not recieved")
+
+RRSIG_QUERY = answer_checker.make_random_case_query("good-a.test.knot-resolver.cz", "A", want_dnssec=True)
+RRSIG_ANSWER = dns.message.from_text(""";
+opcode QUERY
+rcode NOERROR
+flags QR RD RA AD
+edns 0
+eflags DO
+payload 4096
+;QUESTION
+good-a.test.knot-resolver.cz. IN A
+;ANSWER
+good-a.test.knot-resolver.cz. 3600 IN A 217.31.192.130
+good-a.test.knot-resolver.cz. 3600 IN RRSIG A 13 4 3600 20370119135450 20190205122450 58 test.knot-resolver.cz. n7BfrYwvRztj8khwefZxnVUSBm6vvIWH 3HGTfswPSUKqNrg6yqMIxm0dpLVPSIna hPnTnP3CP6G4SEfvAGk33w==
+;AUTHORITY
+;ADDITIONAL""")
+
+
+def test_returns_RRSIG(forwarder, tcp):
+ return answer_checker.send_and_check(RRSIG_QUERY,
+ RRSIG_ANSWER,
+ forwarder,
+ HEADER | {"answerrrsigs"},
+ tcp=tcp)
+
+DNSKEY_QUERY = answer_checker.make_random_case_query("test.knot-resolver.cz", "DNSKEY", want_dnssec=True)
+DNSKEY_ANSWER = dns.message.from_text(""";
+opcode QUERY
+rcode NOERROR
+flags QR RD RA AD
+edns 0
+eflags DO
+payload 4096
+;QUESTION
+test.knot-resolver.cz. IN DNSKEY
+;ANSWER
+test.knot-resolver.cz. 3600 IN DNSKEY 256 3 13 b5ZQUzN5iD9ercgxPeeEh9qI8UzazMa6 vo8GCART4iQNzAcsB6xPYVopHKcjyssH MUiDoQgrjVd6hOLWQqnCtg==
+test.knot-resolver.cz. 3600 IN DNSKEY 257 3 13 xrbuMAmJy3GlxUF46tJgP64cmExKWQBg iRGeLhfub9x3DV69D+2m1zom+CyqHsYY VDIjYOueGzj/8XFucg1bDw==
+test.knot-resolver.cz. 3600 IN RRSIG DNSKEY 13 3 3600 20370119141532 20190205124532 60526 test.knot-resolver.cz. TCJGKcojvwe5cQYJaj+vMS5/lW2xLDVi cABjowFhQ3ttTIfjNINBK1sAJgybmdtd 5GcBlgXOPz+QWRFJUnRU2g==
+;AUTHORITY
+;ADDITIONAL""")
+
+
+def test_supports_DNSKEY(forwarder, tcp):
+ return answer_checker.send_and_check(DNSKEY_QUERY,
+ DNSKEY_ANSWER,
+ forwarder,
+ ALL - {"additional", "authority"},
+ tcp=tcp)
+
+DS_QUERY = answer_checker.make_random_case_query("test.knot-resolver.cz", "DS", want_dnssec=True)
+DS_ANSWER = dns.message.from_text(""";
+opcode QUERY
+rcode NOERROR
+flags QR RD RA AD
+edns 0
+eflags DO
+payload 4096
+;QUESTION
+test.knot-resolver.cz. IN DS
+;ANSWER
+test.knot-resolver.cz. 1800 IN DS 0 8 2 0000000000000baff1ed10ca1beefc0111ded1cedeadadd011c0feecaca0b011
+test.knot-resolver.cz. 1800 IN DS 60526 13 2 9E526A3D1D1D3F78BD11ABDCE8DE5A6CF9212CD2575D28FC10EBC046 F001AEA8
+test.knot-resolver.cz. 1800 IN RRSIG DS 13 3 1800 20190227092958 20190213075958 23292 knot-resolver.cz. 9yBl60FpEgGt5R5JAKWWK1n1AGLSoeQDsX3nfLz/gQtljhKgnKgkM10T MZKIPUUY9jczh89ChoqCYFr+4MzURw==
+;AUTHORITY
+;ADDITIONAL""")
+# DS signature with tag 0 is left dangling in the zone to trigger a bug in building of
+# chain of trust in older versions of Unbound
+
+def test_supports_DS(forwarder, tcp):
+ return answer_checker.send_and_check(DS_QUERY,
+ DS_ANSWER,
+ forwarder,
+ HEADER | {"answerrrsigs"},
+ tcp=tcp)
+
+NSEC_NEGATIVE_QUERY = answer_checker.make_random_case_query("nonexistent.nsec.test.knot-resolver.cz", "A", want_dnssec=True)
+NSEC_NEGATIVE_ANSWER = dns.message.from_text(""";
+opcode QUERY
+rcode NXDOMAIN
+flags QR RD RA AD
+edns 0
+eflags DO
+payload 4096
+;QUESTION
+nonexistent.nsec.test.knot-resolver.cz. IN A
+;ANSWER
+;AUTHORITY
+nsec.test.knot-resolver.cz. 3600 IN SOA knot-s-01.nic.cz. hostmaster.nic.cz. 2018042476 10800 3600 1209600 7200
+nsec.test.knot-resolver.cz. 7200 IN NSEC unsigned.nsec.test.knot-resolver.cz. A NS SOA RRSIG NSEC DNSKEY CDS CDNSKEY
+nsec.test.knot-resolver.cz. 3600 IN RRSIG SOA 13 4 3600 20370126162631 20190212145631 25023 nsec.test.knot-resolver.cz. Nwpe3F7+fiCeGgyP+0WgyGYC5N8MY4Pc bipFKsHBxgkwkdEyV395VvYCbhz5YuJb SyXsv9tXOVN+XSb5Sac8uQ==
+nsec.test.knot-resolver.cz. 7200 IN RRSIG NSEC 13 4 7200 20370126162631 20190212145631 25023 nsec.test.knot-resolver.cz. ugmndbqwWjM5Zc/ZCEt/FeGSuw70sasu jylUhFljwdalhRNNlLNcQY9Tlr8A8Vnc YJCwI36LrwAp9m/W2ysZxQ==
+;ADDITIONAL""")
+
+
+def test_negative_nsec_answers(forwarder, tcp):
+ return answer_checker.send_and_check(NSEC_NEGATIVE_QUERY,
+ NSEC_NEGATIVE_ANSWER,
+ forwarder,
+ HEADER | {"authority"}, tcp=tcp)
+
+NSEC3_NEGATIVE_QUERY = answer_checker.make_random_case_query("nonexistent.nsec3.test.knot-resolver.cz", "A", want_dnssec=True)
+NSEC3_NEGATIVE_ANSWER = dns.message.from_text(""";
+opcode QUERY
+rcode NXDOMAIN
+flags QR RD RA AD
+edns 0
+eflags DO
+payload 4096
+;QUESTION
+nonexistent.nsec3.test.knot-resolver.cz. IN A
+;ANSWER
+;AUTHORITY
+nsec3.test.knot-resolver.cz. 3600 IN SOA knot-s-01.nic.cz. hostmaster.nic.cz. 2018042476 10800 3600 1209600 7200
+mn71vn3kbnse5hkqqs7kc062nf9jna3u.nsec3.test.knot-resolver.cz. 7200 IN NSEC3 1 0 10 9b987e46196cd181 6j18444t948b3ij9dlakm317q132ccii A NS SOA RRSIG DNSKEY NSEC3PARAM CDS CDNSKEY
+af4kdouqgq3k3j0boq2bqlf4hi14c8qa.nsec3.test.knot-resolver.cz. 7200 IN NSEC3 1 0 10 9b987e46196cd181 druje9e1goigmosgk4m6iv7gbktg143a CNAME RRSIG
+nsec3.test.knot-resolver.cz. 3600 IN RRSIG SOA 13 4 3600 20370126162631 20190212145631 52462 nsec3.test.knot-resolver.cz. 9Ne2jUhyILPa5r0lAUdqkHtbkggSiRbt yqRaH3ENGlYcIIA3Rib6U2js+wEQpYVs SdQPcuzwAkYGmsqroSnDIw==
+mn71vn3kbnse5hkqqs7kc062nf9jna3u.nsec3.test.knot-resolver.cz. 7200 IN RRSIG NSEC3 13 5 7200 20370126162631 20190212145631 52462 nsec3.test.knot-resolver.cz. r7DbpNp4KXvV2a4TDoV3whUPpI6mmjKA bk5TQZnA/z1AwFMtzJDQJ7b9RCv2C9Es CbwKEa+/bLNH4N2Ed8RVPQ==
+af4kdouqgq3k3j0boq2bqlf4hi14c8qa.nsec3.test.knot-resolver.cz. 7200 IN RRSIG NSEC3 13 5 7200 20370119135450 20190205122450 52462 nsec3.test.knot-resolver.cz. NXEa3JxBpufEqBDEUNQhH2kQpPQbXYDX /b1soMKA4CwSaRVgiMkw41vevUZ/XtPj SFl0D6ov88QEDLG2RzYy9g==
+;ADDITIONAL""")
+
+
+def test_negative_nsec3_answers(forwarder, tcp):
+ return answer_checker.send_and_check(NSEC3_NEGATIVE_QUERY,
+ NSEC3_NEGATIVE_ANSWER,
+ forwarder,
+ HEADER | {"authority"}, tcp=tcp)
+
+UNKNOWN_TYPE_QUERY = answer_checker.make_random_case_query("weird-type.test.knot-resolver.cz", "TYPE20025", want_dnssec=True)
+UNKNOWN_TYPE_ANSWER = dns.message.from_text(r""";
+opcode QUERY
+rcode NOERROR
+flags QR RD RA AD
+edns 0
+eflags DO
+payload 512
+;QUESTION
+weird-type.test.knot-resolver.cz. IN TYPE20025
+;ANSWER
+weird-type.test.knot-resolver.cz. 3506 IN TYPE20025 \# 4 deadbeef
+weird-type.test.knot-resolver.cz. 3506 IN RRSIG TYPE20025 13 4 3600 20370119135450 20190205122450 58 test.knot-resolver.cz. eHON73HpRyhIalC4xHwu/zWcZWuyVC3T fpBaOQU1MabzitXBUy4dKoAMVXhcpj62 Pqiz2FxMMg6nXRQJupQDAA==
+;AUTHORITY
+;ADDITIONAL
+""")
+
+
+def test_unknown_rrtype(forwarder, tcp):
+ return answer_checker.send_and_check(UNKNOWN_TYPE_QUERY,
+ UNKNOWN_TYPE_ANSWER,
+ forwarder,
+ ALL - {"additional", "authority"},
+ tcp=tcp)
+
+NONEXISTENT_DS_DELEGATION_NSEC_QUERY = answer_checker.make_random_case_query("unsigned.nsec.test.knot-resolver.cz", "DS", want_dnssec=True)
+NONEXISTENT_DS_DELEGATION_NSEC_ANSWER = dns.message.from_text(""";
+opcode QUERY
+rcode NOERROR
+flags QR RD RA AD
+edns 0
+eflags DO
+payload 4096
+;QUESTION
+unsigned.nsec.test.knot-resolver.cz. IN DS
+;ANSWER
+;AUTHORITY
+nsec.test.knot-resolver.cz. 3600 IN SOA knot-s-01.nic.cz. hostmaster.nic.cz. 2018042476 10800 3600 1209600 7200
+unsigned.nsec.test.knot-resolver.cz. 7200 IN NSEC *.wild.nsec.test.knot-resolver.cz. NS RRSIG NSEC
+nsec.test.knot-resolver.cz. 3600 IN RRSIG SOA 13 4 3600 20370126162631 20190212145631 25023 nsec.test.knot-resolver.cz. Nwpe3F7+fiCeGgyP+0WgyGYC5N8MY4Pc bipFKsHBxgkwkdEyV395VvYCbhz5YuJb SyXsv9tXOVN+XSb5Sac8uQ==
+unsigned.nsec.test.knot-resolver.cz. 7200 IN RRSIG NSEC 13 5 7200 20370119135450 20190205122450 25023 nsec.test.knot-resolver.cz. SWIzKCXTRQMz1n7myOioFrfbTljjR4jG NVRV43NWKtXQ6ftIR68wSVZ+6xsATHeG GXYYJxqaoviY+mLrJdJa/g==
+;ADDITIONAL""")
+
+
+def test_delegation_from_nsec_to_unsigned_zone(forwarder, tcp):
+ return answer_checker.send_and_check(NONEXISTENT_DS_DELEGATION_NSEC_QUERY,
+ NONEXISTENT_DS_DELEGATION_NSEC_ANSWER,
+ forwarder,
+ ALL, tcp=tcp)
+
+NONEXISTENT_DS_DELEGATION_NSEC3_QUERY = answer_checker.make_random_case_query("unsigned.nsec3.test.knot-resolver.cz", "DS", want_dnssec=True)
+NONEXISTENT_DS_DELEGATION_NSEC3_ANSWER = dns.message.from_text(""";
+opcode QUERY
+rcode NOERROR
+flags QR RD RA AD
+edns 0
+eflags DO
+payload 4096
+;QUESTION
+unsigned.nsec3.test.knot-resolver.cz. IN DS
+;ANSWER
+;AUTHORITY
+nsec3.test.knot-resolver.cz. 3600 IN SOA knot-s-01.nic.cz. hostmaster.nic.cz. 2018042476 10800 3600 1209600 7200
+gk65ucsupb4m139fn027ci6pl01fk5gs.nsec3.test.knot-resolver.cz. 7200 IN NSEC3 1 0 10 9b987e46196cd181 mn71vn3kbnse5hkqqs7kc062nf9jna3u NS
+nsec3.test.knot-resolver.cz. 3600 IN RRSIG SOA 13 4 3600 20370126162631 20190212145631 52462 nsec3.test.knot-resolver.cz. 9Ne2jUhyILPa5r0lAUdqkHtbkggSiRbt yqRaH3ENGlYcIIA3Rib6U2js+wEQpYVs SdQPcuzwAkYGmsqroSnDIw==
+gk65ucsupb4m139fn027ci6pl01fk5gs.nsec3.test.knot-resolver.cz. 7200 IN RRSIG NSEC3 13 5 7200 20370119135450 20190205122450 52462 nsec3.test.knot-resolver.cz. WjWrhgoRmw8+xMuzcGLqPx76xEvPTQjN OaJOEXzK7409Jc7tVHgpolbNxsDdI0u+ h6s5Du78yx4z0QOCq2VEzg==
+;ADDITIONAL""")
+
+
+def test_delegation_from_nsec3_to_unsigned_zone(forwarder, tcp):
+ return answer_checker.send_and_check(NONEXISTENT_DS_DELEGATION_NSEC3_QUERY,
+ NONEXISTENT_DS_DELEGATION_NSEC3_ANSWER,
+ forwarder,
+ ALL, tcp=tcp)
+
+NONEXISTENT_DELEGATION_FROM_NSEC_QUERY = answer_checker.make_random_case_query("nonexistent.nsec.test.knot-resolver.cz", "DS", want_dnssec=True)
+NONEXISTENT_DELEGATION_FROM_NSEC_ANSWER = dns.message.from_text(""";
+opcode QUERY
+rcode NXDOMAIN
+flags QR RD RA AD
+edns 0
+eflags DO
+payload 4096
+;QUESTION
+nonexistent.nsec.test.knot-resolver.cz. IN DS
+;ANSWER
+;AUTHORITY
+nsec.test.knot-resolver.cz. 3600 IN SOA knot-s-01.nic.cz. hostmaster.nic.cz. 2018042476 10800 3600 1209600 7200
+nsec.test.knot-resolver.cz. 7200 IN NSEC unsigned.nsec.test.knot-resolver.cz. A NS SOA RRSIG NSEC DNSKEY CDS CDNSKEY
+nsec.test.knot-resolver.cz. 3600 IN RRSIG SOA 13 4 3600 20370126162631 20190212145631 25023 nsec.test.knot-resolver.cz. Nwpe3F7+fiCeGgyP+0WgyGYC5N8MY4Pc bipFKsHBxgkwkdEyV395VvYCbhz5YuJb SyXsv9tXOVN+XSb5Sac8uQ==
+nsec.test.knot-resolver.cz. 7200 IN RRSIG NSEC 13 4 7200 20370126162631 20190212145631 25023 nsec.test.knot-resolver.cz. ugmndbqwWjM5Zc/ZCEt/FeGSuw70sasu jylUhFljwdalhRNNlLNcQY9Tlr8A8Vnc YJCwI36LrwAp9m/W2ysZxQ==
+;ADDITIONAL""")
+
+
+def test_nonexistent_delegation_from_nsec(forwarder, tcp):
+ return answer_checker.send_and_check(NONEXISTENT_DELEGATION_FROM_NSEC_QUERY,
+ NONEXISTENT_DELEGATION_FROM_NSEC_ANSWER,
+ forwarder,
+ ALL, tcp=tcp,
+ unset_flags=[dns.flags.AA])
+# Some resolvers treat generated proof of non-existence as authoritative data
+# and set AA flag in this kind of answer, we have to normalize this by unsetting
+# it.
+
+NONEXISTENT_DELEGATION_FROM_NSEC3_QUERY = answer_checker.make_random_case_query("nonexistent.nsec3.test.knot-resolver.cz", "DS", want_dnssec=True)
+NONEXISTENT_DELEGATION_FROM_NSEC3_ANSWER = dns.message.from_text(""";
+opcode QUERY
+rcode NXDOMAIN
+flags QR RD RA AD
+edns 0
+eflags DO
+payload 4096
+;QUESTION
+nonexistent.nsec3.test.knot-resolver.cz. IN DS
+;ANSWER
+;AUTHORITY
+nsec3.test.knot-resolver.cz. 3600 IN SOA knot-s-01.nic.cz. hostmaster.nic.cz. 2018042476 10800 3600 1209600 7200
+mn71vn3kbnse5hkqqs7kc062nf9jna3u.nsec3.test.knot-resolver.cz. 7200 IN NSEC3 1 0 10 9b987e46196cd181 6j18444t948b3ij9dlakm317q132ccii A NS SOA RRSIG DNSKEY NSEC3PARAM CDS CDNSKEY
+af4kdouqgq3k3j0boq2bqlf4hi14c8qa.nsec3.test.knot-resolver.cz. 7200 IN NSEC3 1 0 10 9b987e46196cd181 druje9e1goigmosgk4m6iv7gbktg143a CNAME RRSIG
+nsec3.test.knot-resolver.cz. 3600 IN RRSIG SOA 13 4 3600 20370126162631 20190212145631 52462 nsec3.test.knot-resolver.cz. 9Ne2jUhyILPa5r0lAUdqkHtbkggSiRbt yqRaH3ENGlYcIIA3Rib6U2js+wEQpYVs SdQPcuzwAkYGmsqroSnDIw==
+mn71vn3kbnse5hkqqs7kc062nf9jna3u.nsec3.test.knot-resolver.cz. 7200 IN RRSIG NSEC3 13 5 7200 20370126162631 20190212145631 52462 nsec3.test.knot-resolver.cz. r7DbpNp4KXvV2a4TDoV3whUPpI6mmjKA bk5TQZnA/z1AwFMtzJDQJ7b9RCv2C9Es CbwKEa+/bLNH4N2Ed8RVPQ==
+af4kdouqgq3k3j0boq2bqlf4hi14c8qa.nsec3.test.knot-resolver.cz. 7200 IN RRSIG NSEC3 13 5 7200 20370119135450 20190205122450 52462 nsec3.test.knot-resolver.cz. NXEa3JxBpufEqBDEUNQhH2kQpPQbXYDX /b1soMKA4CwSaRVgiMkw41vevUZ/XtPj SFl0D6ov88QEDLG2RzYy9g==
+;ADDITIONAL""")
+
+
+def test_nonexistent_delegation_from_nsec3(forwarder, tcp):
+ return answer_checker.send_and_check(NONEXISTENT_DELEGATION_FROM_NSEC3_QUERY,
+ NONEXISTENT_DELEGATION_FROM_NSEC3_ANSWER,
+ forwarder,
+ ALL, tcp=tcp,
+ unset_flags=[dns.flags.AA])
+
+
+NONEXISTENT_TYPE_NSEC3_QUERY = answer_checker.make_random_case_query("nsec3.test.knot-resolver.cz", "TYPE65281", want_dnssec=True)
+NONEXISTENT_TYPE_NSEC3_ANSWER = dns.message.from_text(""";
+opcode QUERY
+rcode NOERROR
+flags QR RD RA AD
+edns 0
+eflags DO
+payload 4096
+;QUESTION
+nsec3.test.knot-resolver.cz. IN TYPE65281
+;ANSWER
+;AUTHORITY
+nsec3.test.knot-resolver.cz. 3600 IN SOA knot-s-01.nic.cz. hostmaster.nic.cz. 2018042476 10800 3600 1209600 7200
+mn71vn3kbnse5hkqqs7kc062nf9jna3u.nsec3.test.knot-resolver.cz. 7200 IN NSEC3 1 0 10 9b987e46196cd181 6j18444t948b3ij9dlakm317q132ccii A NS SOA RRSIG DNSKEY NSEC3PARAM CDS CDNSKEY
+nsec3.test.knot-resolver.cz. 3600 IN RRSIG SOA 13 4 3600 20370126162631 20190212145631 52462 nsec3.test.knot-resolver.cz. 9Ne2jUhyILPa5r0lAUdqkHtbkggSiRbt yqRaH3ENGlYcIIA3Rib6U2js+wEQpYVs SdQPcuzwAkYGmsqroSnDIw==
+mn71vn3kbnse5hkqqs7kc062nf9jna3u.nsec3.test.knot-resolver.cz. 7200 IN RRSIG NSEC3 13 5 7200 20370126162631 20190212145631 52462 nsec3.test.knot-resolver.cz. r7DbpNp4KXvV2a4TDoV3whUPpI6mmjKA bk5TQZnA/z1AwFMtzJDQJ7b9RCv2C9Es CbwKEa+/bLNH4N2Ed8RVPQ==
+;ADDITIONAL""")
+
+
+def test_nonexistent_type_nsec3(forwarder, tcp):
+ return answer_checker.send_and_check(NONEXISTENT_TYPE_NSEC3_QUERY,
+ NONEXISTENT_TYPE_NSEC3_ANSWER,
+ forwarder,
+ ALL, tcp=tcp)
+
+NONEXISTENT_TYPE_NSEC_QUERY = answer_checker.make_random_case_query("nsec.test.knot-resolver.cz", "TYPE65281", want_dnssec=True)
+NONEXISTENT_TYPE_NSEC_ANSWER = dns.message.from_text(""";
+opcode QUERY
+rcode NOERROR
+flags QR RD RA AD
+edns 0
+eflags DO
+payload 4096
+;QUESTION
+nsec.test.knot-resolver.cz. IN TYPE65281
+;ANSWER
+;AUTHORITY
+nsec.test.knot-resolver.cz. 3600 IN SOA knot-s-01.nic.cz. hostmaster.nic.cz. 2018042476 10800 3600 1209600 7200
+nsec.test.knot-resolver.cz. 7200 IN NSEC unsigned.nsec.test.knot-resolver.cz. A NS SOA RRSIG NSEC DNSKEY CDS CDNSKEY
+nsec.test.knot-resolver.cz. 3600 IN RRSIG SOA 13 4 3600 20370126162631 20190212145631 25023 nsec.test.knot-resolver.cz. Nwpe3F7+fiCeGgyP+0WgyGYC5N8MY4Pc bipFKsHBxgkwkdEyV395VvYCbhz5YuJb SyXsv9tXOVN+XSb5Sac8uQ==
+nsec.test.knot-resolver.cz. 7200 IN RRSIG NSEC 13 4 7200 20370126162631 20190212145631 25023 nsec.test.knot-resolver.cz. ugmndbqwWjM5Zc/ZCEt/FeGSuw70sasu jylUhFljwdalhRNNlLNcQY9Tlr8A8Vnc YJCwI36LrwAp9m/W2ysZxQ==
+;ADDITIONAL""")
+
+
+def test_nonexistent_type_nsec(forwarder, tcp):
+ return answer_checker.send_and_check(NONEXISTENT_TYPE_NSEC_QUERY,
+ NONEXISTENT_TYPE_NSEC_ANSWER,
+ forwarder,
+ ALL, tcp=tcp)
diff --git a/tests/integration/deckard/tools/generate_answers.py b/tests/integration/deckard/tools/generate_answers.py
new file mode 100644
index 0000000..399f9a7
--- /dev/null
+++ b/tests/integration/deckard/tools/generate_answers.py
@@ -0,0 +1,26 @@
+"""Simple answer generator using local forwarder"""
+# pylint: disable=C0301,C0111,C0103
+# flake8: noqa
+import ipaddress
+
+import answer_checker
+
+d = {"SIMPLE_ANSWER" : answer_checker.make_random_case_query("good-a.test.knot-resolver.cz", "A"),
+ "EDNS_ANSWER" : answer_checker.make_random_case_query("good-a.test.knot-resolver.cz", "A", use_edns=0),
+ "DO_ANSWER" : answer_checker.make_random_case_query("good-a.test.knot-resolver.cz", "A", want_dnssec=True),
+ "CD_ANSWER" : answer_checker.make_random_case_query("good-a.test.knot-resolver.cz", "A", want_dnssec=True),
+ "RRSIG_ANSWER" : answer_checker.make_random_case_query("good-a.test.knot-resolver.cz", "A", want_dnssec=True),
+ "DNSKEY_ANSWER" : answer_checker.make_random_case_query("test.knot-resolver.cz", "DNSKEY", want_dnssec=True),
+ "DS_ANSWER" : answer_checker.make_random_case_query("cz", "DS", want_dnssec=True),
+ "NSEC_NEGATIVE_ANSWER" : answer_checker.make_random_case_query("nonexistent.nsec.test.knot-resolver.cz", "A", want_dnssec=True),
+ "NSEC3_NEGATIVE_ANSWER" : answer_checker.make_random_case_query("nonexistent.nsec3.test.knot-resolver.cz", "A", want_dnssec=True),
+ "UNKNOWN_TYPE_ANSWER" : answer_checker.make_random_case_query("weird-type.test.knot-resolver.cz", "TYPE20025"),
+ "NONEXISTENT_DS_DELEGATION_NSEC_ANSWER" : answer_checker.make_random_case_query("unsigned.nsec.test.knot-resolver.cz", "DS", want_dnssec=True),
+ "NONEXISTENT_DS_DELEGATION_NSEC3_ANSWER" : answer_checker.make_random_case_query("unsigned.nsec3.test.knot-resolver.cz", "DS", want_dnssec=True),
+ "NONEXISTENT_DELEGATION_FROM_NSEC_ANSWER" : answer_checker.make_random_case_query("nonexistent.nsec.test.knot-resolver.cz", "DS", want_dnssec=True),
+ "NONEXISTENT_DELEGATION_FROM_NSEC3_ANSWER" : answer_checker.make_random_case_query("nonexistent.nsec3.test.knot-resolver.cz", "DS", want_dnssec=True),
+ "NONEXISTENT_TYPE_NSEC3_ANSWER" : answer_checker.make_random_case_query("nsec3.test.knot-resolver.cz", "TYPE65281", want_dnssec=True),
+ "NONEXISTENT_TYPE_NSEC_ANSWER" : answer_checker.make_random_case_query("nsec.test.knot-resolver.cz", "TYPE65281", want_dnssec=True)}
+
+for k, v in d.items():
+ print('%s = dns.message.from_text("""%s""")\n' % (k, answer_checker.string_answer(v, ipaddress.IPv4Address("127.0.0.1"))))
diff --git a/tests/integration/deckard/tools/invalid_dsa.py b/tests/integration/deckard/tools/invalid_dsa.py
new file mode 100644
index 0000000..fd1c845
--- /dev/null
+++ b/tests/integration/deckard/tools/invalid_dsa.py
@@ -0,0 +1,83 @@
+"""Returns 1 if there is a DNSSEC DSA signature which is not 41 bytes long.\
+0 otherwise.
+"""
+
+import os
+import sys
+import argparse
+import dns
+import pydnstest
+import pydnstest.scenario
+import pydnstest.augwrap
+
+
+def parse(test):
+ """ Parse the test"""
+ _, config = pydnstest.scenario.parse_file(os.path.realpath(test))
+ aug = pydnstest.augwrap.AugeasWrapper(
+ confpath=os.path.realpath(test),
+ lens='Deckard', loadpath="../pydnstest")
+ node = aug.tree
+ return config, node
+
+
+def get_dsakeys(config, node):
+ """ Make list of all DSA keys in the test"""
+ dsakeys = []
+ for conf in config:
+ if conf[0] == "trust-anchor":
+ conf[1] = conf[1][1:-1]
+ trust_anchor = conf[1].split()
+ for i, word in enumerate(trust_anchor):
+ if word == "DS":
+ algorithm = trust_anchor[i + 2]
+ if algorithm in ("3", "DSA"):
+ dsakeys.append(trust_anchor[i + 1])
+
+ for entry in node.match("/scenario/range/entry"):
+ records = list(entry.match("/section/answer/record"))
+ records.extend(list(entry.match("/section/authority/record")))
+ records.extend(list(entry.match("/section/additional/record")))
+
+ for record in records:
+ if record["/type"].value == "DS":
+ if record["/data"].value[1] in ["3", "DSA"]:
+ dsakeys.append(record["/data"].value[2])
+ return dsakeys
+
+
+def check_rrsig(node, dsakeys):
+ """ Find records with wrong lenght of rrsig"""
+ for key in dsakeys: # pylint: disable=too-many-nested-blocks
+ for entry in node.match("/scenario/range/entry"):
+ records = list(entry.match("/section/answer/record"))
+ records.extend(list(entry.match("/section/authority/record")))
+ records.extend(list(entry.match("/section/additional/record")))
+
+ for record in records:
+ if record["/type"].value == "RRSIG":
+ rrset = dns.rrset.from_text(record["/domain"].value, 300,
+ 1, dns.rdatatype.RRSIG,
+ record["/data"].value)
+ if rrset.items[0].key_tag == int(key):
+ if len(rrset.items[0].signature) != 41:
+ return True
+ return False
+
+
+def main():
+ """Returns 1 if there is a DNSSEC DSA signature which is not 41 bytes long. \
+ 0 otherwise."""
+ argparser = argparse.ArgumentParser()
+ argparser.add_argument("file")
+ args = argparser.parse_args()
+ config, node = parse(args.file)
+ dsakeys = get_dsakeys(config, node)
+ bad_rrsig = check_rrsig(node, dsakeys)
+ if bad_rrsig:
+ sys.exit(1)
+ else:
+ sys.exit(0)
+
+
+main()
diff --git a/tests/integration/deckard/tools/network_check.py b/tests/integration/deckard/tools/network_check.py
new file mode 100644
index 0000000..18a727f
--- /dev/null
+++ b/tests/integration/deckard/tools/network_check.py
@@ -0,0 +1,136 @@
+"""Test suite to determine conditions of current network in regards to DNS(SEC) traffic.
+Invoke with `python3 -m pytest network_check.py`. """
+# pylint: disable=C0301,C0111
+# flake8: noqa
+import ipaddress
+import socket
+
+import pytest
+import dns.message
+
+import answer_checker
+
+ALL = {"opcode", "qtype", "qname", "flags", "rcode", "answer", "authority", "additional"}
+
+VERSION_QUERY = dns.message.make_query("_version.test.knot-resolver.cz", "TXT")
+# dnspython's `makequery` function sets RD bit in the messsages.
+# This is undesirable for query to authoritative servers since they
+# may or may not copy RD flag to the response.
+answer_checker.unset_flag(VERSION_QUERY, dns.flags.RD)
+VERSION_ANSWER = dns.message.from_text(""";
+opcode QUERY
+rcode NOERROR
+flags QR AA
+;QUESTION
+_version.test.knot-resolver.cz. IN TXT
+;ANSWER
+_version.test.knot-resolver.cz. 3600 IN TXT "1"
+;AUTHORITY
+;ADDITIONAL
+""")
+
+def test_zone_version(server):
+ return answer_checker.send_and_check(VERSION_QUERY,
+ VERSION_ANSWER,
+ server,
+ ALL - {"authority"},
+ unset_flags=[dns.flags.AD])
+# Since AD bit may or may not be set by authoritative server
+# (see https://tools.ietf.org/html/rfc4035#section-3.1.6) we normalise the answers
+# by unsetting the AD bit.
+
+QUERY = answer_checker.make_random_case_query("test.knot-resolver.cz", "A", want_dnssec=True, payload=4096)
+answer_checker.unset_flag(QUERY, dns.flags.RD)
+ANSWER = dns.message.from_text(""";
+opcode QUERY
+rcode NOERROR
+flags QR AA
+edns 0
+eflags DO
+payload 4096
+;QUESTION
+test.knot-resolver.cz. IN A
+;ANSWER
+test.knot-resolver.cz. 3600 IN A 217.31.192.130
+test.knot-resolver.cz. 3600 IN RRSIG A 13 3 3600 20370119135450 20190205122450 58 test.knot-resolver.cz. G9DTWRE8QKe0MKyHn+PZcgf+ggIR9Sk+ E9qtd8IlpEt3+y28qPp0lgDQojpQL9sv lqgC0g5e2ZIsZWg1T5ICNQ==
+;AUTHORITY
+;ADDITIONAL
+""")
+
+
+def test_remote_udp_53(server):
+ return answer_checker.send_and_check(QUERY,
+ ANSWER,
+ server,
+ ALL - {"authority"},
+ unset_flags=[dns.flags.AD])
+
+
+def test_remote_tcp_53(server):
+ return answer_checker.send_and_check(QUERY,
+ ANSWER,
+ server,
+ ALL - {"authority"},
+ tcp=True,
+ unset_flags=[dns.flags.AD])
+
+@pytest.mark.parametrize("non_existent_server", [ipaddress.ip_address("192.0.2.1"), ipaddress.ip_address("2001:db::1")])
+def test_nonexistent_addres(non_existent_server):
+ try:
+ answer_checker.get_answer(QUERY, non_existent_server, timeout=1)
+ except socket.timeout:
+ return True
+ return False
+
+
+LONG_QUERY = answer_checker.make_random_case_query("test.knot-resolver.cz", "TXT", use_edns=0, payload=4096, want_dnssec=True)
+answer_checker.unset_flag(LONG_QUERY, dns.flags.RD)
+LONG_ANSWER = dns.message.from_text(""";
+opcode QUERY
+rcode NOERROR
+flags QR AA
+edns 0
+payload 4096
+;QUESTION
+test.knot-resolver.cz. IN TXT
+;ANSWER
+test.knot-resolver.cz. 3600 IN TXT "Davku ve me o pln uvitani stari s tvuj neda? Tik kufr u traslo uf tabuli znaky mesity bimbal vyrvat vydelal pobezi zahajil a tajnosti. By 77 dusic ach prazdna kasari k zac platne potiz. O hon 30 otazek jiz post i rad zeleninu vyhrknu bhutanu nezdalo. I tr" "ida, ptat lzes vypadla newton, utal hm je bas samymi u sobe ukaz kazne medove u placeny ke ah jo zpola o ocich. Sul trimesicni kontrolujte v predstirana po nej mit za devetadevadesati eh mi lezu slava vuz v me smery. Tri akt dlazbu dal lamu, kavkam on zas" "luhy, sad muzikant vek. Paty neme radili trunil docist tech obou zari. My ze 11 tlusti jsemvidel. Podivej i prs kralik at ted o vynahradit ti si ma charakterni nehybny tulak poskytl rad! Muz ztuhla, ci ah propatral misce! Slz eh at? Zenou dilo intuici. Le" "su pud povesti, i jamou tej. V az vdanou zrejmo za ctil 81 kolika u ustrnule malicherny holemi nekradla jinych morfia: pocasi poplaseny zpovidat az dne vyjimecna zidovskem stejny sluzek tajemny hlidat u ruzovym pry jestli vyslychalo zem nerozbrecte farare" " strhla v mem tabule pije a odkraglujem otisky nebot. Ex povidani pusta duse eh zvalel, o pak ma bryle luzka: u posluhovi neudela 30 ze ctverce brovninku. 411 se vi rypaje nova to per ba zchoulostivil remenem. Vaze to lujzou styky, te? Ne me by pazeni tro" "ubil i srovnala dejoveho a prvnich me o zime hlasy nevsimnou. Jejim zajiste za porotam valka sekt. Oni vuli co ryb pruvod. Ode jehoz od lasce ve slouzilo co jektal hryzal lamparny. Zvlastnich ne vybil brejlil uz ah? Husa trit mu straze s zivaje abys chute" " pane ci nepochybujte ubiha k babe ach okoli zle okna deji dverim! Vymyslim do falesne. Pokaceneho leti oka krk. Nohy stejny u vykaslu, rinkotem ondyno, laureat z zabije."
+test.knot-resolver.cz. 3600 IN RRSIG TXT 13 3 3600 20370119135450 20190205122450 58 test.knot-resolver.cz. YYzbiOgNyIe2YcUHUbA8LNrqUYPSHEUA U7tAOLJx54kSlTMYDB5VrnqsAIgp2PtV C1gELBVK4Xtwxrx3ajeLhA==
+;AUTHORITY
+;ADDITIONAL
+""")
+
+
+@pytest.mark.skip(reason="This doesn't work since a.ns.nic.cz (and all CZ.NIC's nameservers in that "
+ "matter) have internal EDNS buffer size of 1232 bytes. The answer is "
+ "unfortunately bigger. :(")
+def test_udp_fragmentation(server):
+ return answer_checker.send_and_check(LONG_QUERY,
+ LONG_ANSWER,
+ server,
+ ALL - {"authority"},
+ unset_flags=[dns.flags.AD])
+
+
+QUERY_WITH_SMALL_PAYLOAD = answer_checker.make_random_case_query("test.knot-resolver.cz", "TXT", use_edns=0, payload=1280, want_dnssec=True)
+answer_checker.unset_flag(QUERY_WITH_SMALL_PAYLOAD, dns.flags.RD)
+TRUNCATED_ANSWER = dns.message.from_text(""";
+opcode QUERY
+rcode NOERROR
+flags QR AA TC
+edns 0
+payload 4096
+;QUESTION
+test.knot-resolver.cz. IN TXT
+;ANSWER
+;AUTHORITY
+;ADDITIONAL
+""")
+
+
+def test_udp_fragmentation_truncated(server):
+ return answer_checker.send_and_check(QUERY_WITH_SMALL_PAYLOAD,
+ TRUNCATED_ANSWER,
+ server,
+ ALL - {"authority"},
+ unset_flags=[dns.flags.AD])
diff --git a/tests/integration/deckard/tools/parse.py b/tests/integration/deckard/tools/parse.py
new file mode 100644
index 0000000..139b284
--- /dev/null
+++ b/tests/integration/deckard/tools/parse.py
@@ -0,0 +1,21 @@
+"""Returns 0 if the test is parsed, 1 if not."""
+
+import sys
+import os
+import argparse
+import pydnstest
+import pydnstest.scenario
+
+
+def main():
+ """Returns 0 if the test is parsed, 1 if not."""
+ argparser = argparse.ArgumentParser()
+ argparser.add_argument("file")
+ args = argparser.parse_args()
+ if pydnstest.scenario.parse_file(os.path.realpath(args.file)):
+ sys.exit(0)
+ else:
+ sys.exit(1)
+
+
+main()
diff --git a/tests/integration/deckard/tools/pydnstest b/tests/integration/deckard/tools/pydnstest
new file mode 120000
index 0000000..c7796c1
--- /dev/null
+++ b/tests/integration/deckard/tools/pydnstest
@@ -0,0 +1 @@
+../pydnstest/ \ No newline at end of file
diff --git a/tests/integration/deckard/unbound_run.sh b/tests/integration/deckard/unbound_run.sh
new file mode 100755
index 0000000..a5189e0
--- /dev/null
+++ b/tests/integration/deckard/unbound_run.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+set -o errexit -o nounset
+
+RUNDIR="$(dirname "$0")"
+cd "$RUNDIR" && ./run.sh --config configs/unbound.yaml "$@"
diff --git a/tests/integration/hints_zone.j2 b/tests/integration/hints_zone.j2
new file mode 100644
index 0000000..1eafe8a
--- /dev/null
+++ b/tests/integration/hints_zone.j2
@@ -0,0 +1,10 @@
+; SPDX-License-Identifier: GPL-3.0-or-later
+; This file holds the information on root name servers needed to
+; initialize cache of Internet domain name servers
+
+. 3600000 NS K.ROOT-SERVERS.NET.
+{% if ':' in ROOT_ADDR %}
+K.ROOT-SERVERS.NET. 3600000 AAAA {{ROOT_ADDR}}
+{% else %}
+K.ROOT-SERVERS.NET. 3600000 A {{ROOT_ADDR}}
+{% endif %}
diff --git a/tests/integration/meson.build b/tests/integration/meson.build
new file mode 100644
index 0000000..ffe3403
--- /dev/null
+++ b/tests/integration/meson.build
@@ -0,0 +1,68 @@
+# tests: integration (using deckard)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# deckard dependencies
+faketime = find_program('faketime')
+git = find_program('git')
+make = find_program('make')
+augeas = dependency('augeas')
+
+# python3 dependencies
+py3_deps += [
+ ['augeas', 'augeas (for deckard)'],
+ ['dns', 'dnspython (for deckard)'],
+ ['dpkt', 'dpkt (for deckard)'],
+ ['jinja2', 'jinja2 (for deckard)'],
+ ['pyroute2', 'pyroute2 (for deckard)'],
+ ['pytest', 'pytest (for deckard)'],
+ ['xdist', 'pytest-xdist (for deckard)'],
+ ['yaml', 'PyYAML (for deckard)'],
+]
+
+prepare_deckard = find_program('../../scripts/test-integration-prepare.sh')
+
+deckard_env = environment()
+deckard_env.prepend('PATH', sbin_dir)
+
+junitxml_prefix = '--junitxml=' + meson.build_root() + '/meson-logs'
+
+deckard_kresd_run = find_program('deckard/kresd_run.sh')
+test(
+ 'integration.deckard',
+ deckard_kresd_run,
+ env: deckard_env,
+ args: [
+ '-n', 'auto',
+ '-Wignore::DeprecationWarning',
+ junitxml_prefix + '/integration.deckard.junit.xml',
+ ],
+ suite: [
+ 'postinstall',
+ 'integration',
+ ],
+ is_parallel: false,
+ timeout: 300,
+)
+
+deckard_run = find_program('deckard/run.sh')
+foreach integr_test : integr_tests
+ deckard_config_path = integr_test[1] / 'deckard.yaml'
+ test(
+ 'integration.' + integr_test[0],
+ deckard_run,
+ env: deckard_env,
+ args: [
+ '-n', 'auto',
+ '-Wignore::DeprecationWarning',
+ '--config=@0@'.format(deckard_config_path),
+ '--scenarios=@0@'.format(integr_test[1]),
+ junitxml_prefix + '/integration.' + integr_test[0] + '.junit.xml',
+ ],
+ suite: [
+ 'postinstall',
+ 'integration',
+ ],
+ is_parallel: false,
+ workdir: meson.source_root(),
+ )
+endforeach
diff --git a/tests/integration/testdata_notimpl/iter_class_any.rpl b/tests/integration/testdata_notimpl/iter_class_any.rpl
new file mode 100644
index 0000000..5c4bb4b
--- /dev/null
+++ b/tests/integration/testdata_notimpl/iter_class_any.rpl
@@ -0,0 +1,150 @@
+; config options
+; The island of trust is at example.com
+server:
+ trust-anchor: "example.com. 3600 IN DS 2854 3 1 46e4ffc6e9a4793b488954bd3f0cc6af0dfb201b"
+ val-override-date: "20070916134226"
+ target-fetch-policy: "0 0 0 0 0"
+
+stub-zone:
+ name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test lookup of class any response
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854}
+ENTRY_END
+
+; response to DNSKEY priming query
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN DNSKEY
+SECTION ANSWER
+example.com. 3600 IN DNSKEY 256 3 3 ALXLUsWqUrY3JYER3T4TBJII s70j+sDS/UT2QRp61SE7S3E EXopNXoFE73JLRmvpi/UrOO/Vz4Se 6wXv/CYCKjGw06U4WRgR YXcpEhJROyNapmdIKSx hOzfLVE1gqA0PweZR8d tY3aNQSRn3sPpwJr6Mi /PqQKAMMrZ9ckJpf1+b QMOOvxgzz2U1GS18b3y ZKcgTMEaJzd/GZYzi/B N2DzQ0MsrSwYXfsNLFO Bbs8PJMW4LYIxeeOe6rUgkWOF 7CC9Dh/dduQ1QrsJhmZAEFfd6ByYV+ ;{id = 2854 (zsk), size = 1688b}
+example.com. 3600 IN RRSIG DNSKEY 3 2 3600 20070926134802 20070829134802 2854 example.com. MCwCFG1yhRNtTEa3Eno2zhVVuy2EJX3wAhQeLyUp6+UXcpC5qGNu9tkrTEgPUg== ;{id = 2854}
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854}
+ENTRY_END
+
+; response to query of interest
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCQMyTjn7WWwpwAR1LlVeLpRgZGuQIUCcJDEkwAuzytTDRlYK7nIMwH1CM= ;{id = 2854}
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+www.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFC99iE9K5y2WNgI0gFvBWaTi9wm6AhUAoUqOpDtG5Zct+Qr9F3mSdnbc6V4= ;{id = 2854}
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.example.com. ANY A
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+www.example.com. ANY A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+www.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFC99iE9K5y2WNgI0gFvBWaTi9wm6AhUAoUqOpDtG5Zct+Qr9F3mSdnbc6V4= ;{id = 2854}
+;SECTION AUTHORITY
+;example.com. IN NS ns.example.com.
+;example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
+;SECTION ADDITIONAL
+;ns.example.com. IN A 1.2.3.4
+;ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCQMyTjn7WWwpwAR1LlVeLpRgZGuQIUCcJDEkwAuzytTDRlYK7nIMwH1CM= ;{id = 2854}
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/testdata_notimpl/iter_dnsseclame_bug.rpl b/tests/integration/testdata_notimpl/iter_dnsseclame_bug.rpl
new file mode 100644
index 0000000..0210e2d
--- /dev/null
+++ b/tests/integration/testdata_notimpl/iter_dnsseclame_bug.rpl
@@ -0,0 +1,465 @@
+; config options
+server:
+ trust-anchor: "example.com. 3600 IN DS 2854 3 1 46e4ffc6e9a4793b488954bd3f0cc6af0dfb201b"
+ val-override-date: "1189950146"
+
+stub-zone:
+ name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+
+CONFIG_END
+
+SCENARIO_BEGIN Bug test dnssec-lame detection at ds point with target queries.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+net. IN A
+SECTION AUTHORITY
+net. IN NS e.gtld-servers.net.
+SECTION ADDITIONAL
+e.gtld-servers.net. IN A 192.12.94.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.net. IN AAAA
+SECTION AUTHORITY
+net. IN NS e.gtld-servers.net.
+SECTION ADDITIONAL
+e.gtld-servers.net. IN A 192.12.94.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.55
+ENTRY_END
+RANGE_END
+
+; e.gtld-servers.net.
+; Note this timing is so it will provide answers at the beginning.
+RANGE_BEGIN 0 30
+ ADDRESS 192.12.94.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+net. IN NS
+SECTION ANSWER
+net. IN NS e.gtld-servers.net.
+SECTION ADDITIONAL
+e.gtld-servers.net. IN A 192.12.94.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+e.gtld-servers.net. IN AAAA
+SECTION ANSWER
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+a.gtld-servers.net. IN AAAA
+SECTION ANSWER
+ENTRY_END
+
+; no example.net delegation answers yet.
+
+RANGE_END
+
+; e.gtld-servers.net.
+; Note this timing is so it will not provide answers at the beginning,
+; but only later on.
+RANGE_BEGIN 30 100
+ ADDRESS 192.12.94.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+net. IN NS
+SECTION ANSWER
+net. IN NS e.gtld-servers.net.
+SECTION ADDITIONAL
+e.gtld-servers.net. IN A 192.12.94.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+e.gtld-servers.net. IN AAAA
+SECTION ANSWER
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+a.gtld-servers.net. IN AAAA
+SECTION ANSWER
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.net. IN A
+SECTION AUTHORITY
+example.net. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.net. IN A 1.2.3.44
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.net. IN AAAA
+SECTION AUTHORITY
+example.net. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.net. IN A 1.2.3.44
+ENTRY_END
+RANGE_END
+
+; ns.example.net.
+; Note this timing is so it will not provide answers at the beginning,
+; but only later on.
+RANGE_BEGIN 30 100
+ ADDRESS 1.2.3.44
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.net. IN NS
+SECTION ANSWER
+example.net. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.net. IN A 1.2.3.44
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns.example.net. IN A
+SECTION ANSWER
+ns.example.net. IN A 1.2.3.44
+SECTION AUTHORITY
+example.net. IN NS ns.example.net.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns.example.net. IN AAAA
+SECTION AUTHORITY
+example.net. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.net. IN A 1.2.3.44
+ENTRY_END
+
+; response to DNSKEY priming query
+; sub.example.com. 3600 IN DS 30899 RSASHA1 1 f7ed618f24d5e5202927e1d27bc2e84a141cb4b3
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+sub.example.com. IN DNSKEY
+SECTION ANSWER
+sub.example.com. 3600 IN DNSKEY 256 3 5 AQPQ41chR9DEHt/aIzIFAqanbDlRflJoRs5yz1jFsoRIT7dWf0r+PeDuewdxkszNH6wnU4QL8pfKFRh5PIYVBLK3 ;{id = 30899 (zsk), size = 512b}
+sub.example.com. 3600 IN RRSIG DNSKEY 5 3 3600 20070926134150 20070829134150 30899 sub.example.com. uNGp99iznjD7oOX02XnQbDnbg75UwBHRvZSKYUorTKvPUnCWMHKdRsQ+mf+Fx3GZ+Fz9BVjoCmQqpnfgXLEYqw== ;{id = 30899}
+SECTION AUTHORITY
+; no NS set. not needed for this test.
+SECTION ADDITIONAL
+ns.sub.example.com. IN A 1.2.3.6
+ns.sub.example.com. 3600 IN RRSIG A 5 4 3600 20070926134150 20070829134150 30899 sub.example.com. UF7shD/gt1FOp2UHgLTNbPzVykklSXFMEtJ1xD+Hholwf/PIzd7zoaIttIYibNa4fUXCqMg22H9P7MRhfmFe6g== ;{id = 30899}
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+sub.example.com. IN NS
+SECTION ANSWER
+sub.example.com. IN NS ns.sub.example.com.
+sub.example.com. IN NS ns.example.net.
+sub.example.com. 3600 IN RRSIG NS 5 3 3600 20070926134150 20070829134150 30899 sub.example.com. C/0b+sqlsdSTkhd+aDXb6ELyuQreosIGBzLCtWxYGD+Q9QGB5rN8uB+4+48yhw36pd3MfeAn06AgAnJ6eu8tJg== ;{id = 30899}
+SECTION ADDITIONAL
+ns.sub.example.com. IN A 1.2.3.6
+ns.sub.example.com. 3600 IN RRSIG A 5 4 3600 20070926134150 20070829134150 30899 sub.example.com. UF7shD/gt1FOp2UHgLTNbPzVykklSXFMEtJ1xD+Hholwf/PIzd7zoaIttIYibNa4fUXCqMg22H9P7MRhfmFe6g== ;{id = 30899}
+ENTRY_END
+
+; response to query of interest
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www.sub.example.com. IN A
+SECTION ANSWER
+www.sub.example.com. IN A 11.11.11.11
+www.sub.example.com. 3600 IN RRSIG A 5 4 3600 20070926134150 20070829134150 30899 sub.example.com. 0DqqRfRtm7VSEQ4mmBbzrKRqQAay3JAE8DPDGmjtokrrjN9F1G/HxozDV7bjdIh2EChlQea8FPwf/GepJMUVxg== ;{id = 30899}
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns.sub.example.com. IN AAAA
+SECTION ANSWER
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.55
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.55
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns.example.com. IN A
+SECTION ANSWER
+ns.example.com. IN A 1.2.3.55
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns.example.com. IN AAAA
+ENTRY_END
+
+; fine DNSKEY response.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+example.com. IN DNSKEY
+SECTION ANSWER
+example.com. 3600 IN DNSKEY 256 3 3 ALXLUsWqUrY3JYER3T4TBJII s70j+sDS/UT2QRp61SE7S3E EXopNXoFE73JLRmvpi/UrOO/Vz4Se 6wXv/CYCKjGw06U4WRgR YXcpEhJROyNapmdIKSx hOzfLVE1gqA0PweZR8d tY3aNQSRn3sPpwJr6Mi /PqQKAMMrZ9ckJpf1+b QMOOvxgzz2U1GS18b3y ZKcgTMEaJzd/GZYzi/B N2DzQ0MsrSwYXfsNLFO Bbs8PJMW4LYIxeeOe6rUgkWOF 7CC9Dh/dduQ1QrsJhmZAEFfd6ByYV+ ;{id = 2854 (zsk), size = 1688b}
+example.com. 3600 IN RRSIG DNSKEY DSA 2 3600 20070926134150 20070829134150 2854 example.com. MCwCFBQRtlR4BEv9ohi+PGFjp+AHsJuHAhRCvz0shggvnvI88DFnBDCczHUcVA== ;{id = 2854}
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
+ENTRY_END
+
+
+; correct delegation with DS
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR AA NOERROR
+SECTION QUESTION
+sub.example.com. IN A
+SECTION ANSWER
+SECTION AUTHORITY
+sub.example.com. IN NS ns.sub.example.com.
+sub.example.com. IN NS ns.example.net.
+sub.example.com. 3600 IN DS 30899 RSASHA1 1 f7ed618f24d5e5202927e1d27bc2e84a141cb4b3
+sub.example.com. 3600 IN RRSIG DS 3 3 3600 20070926134150 20070829134150 2854 example.com. MCwCFCW3ix0GD4BSvNLWIbROCJt5DAW9AhRt/kg9kBKJ20UBUdumrBUHqnskdA== ;{id = 2854}
+SECTION ADDITIONAL
+ns.sub.example.com. IN A 1.2.3.6
+ENTRY_END
+
+; response for delegation to sub.example.com.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+sub.example.com. IN DNSKEY
+SECTION ANSWER
+SECTION AUTHORITY
+sub.example.com. IN NS ns.sub.example.com.
+sub.example.com. IN NS ns.example.net.
+sub.example.com. 3600 IN DS 30899 RSASHA1 1 f7ed618f24d5e5202927e1d27bc2e84a141cb4b3
+sub.example.com. 3600 IN RRSIG DS 3 3 3600 20070926134150 20070829134150 2854 example.com. MCwCFCW3ix0GD4BSvNLWIbROCJt5DAW9AhRt/kg9kBKJ20UBUdumrBUHqnskdA== ;{id = 2854}
+SECTION ADDITIONAL
+ns.sub.example.com. IN A 1.2.3.6
+ENTRY_END
+RANGE_END
+
+; This server is DNSSEC LAME!
+; ns.sub.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.6
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+sub.example.com. IN NS
+SECTION ANSWER
+sub.example.com. IN NS ns.sub.example.com.
+sub.example.com. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.sub.example.com. IN A 1.2.3.6
+ENTRY_END
+
+
+; response to DNSKEY priming query
+; sub.example.com. 3600 IN DS 30899 RSASHA1 1 f7ed618f24d5e5202927e1d27bc2e84a141cb4b3
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+sub.example.com. IN DNSKEY
+SECTION ANSWER
+sub.example.com. 3600 IN DNSKEY 256 3 5 AQPQ41chR9DEHt/aIzIFAqanbDlRflJoRs5yz1jFsoRIT7dWf0r+PeDuewdxkszNH6wnU4QL8pfKFRh5PIYVBLK3 ;{id = 30899 (zsk), size = 512b}
+SECTION AUTHORITY
+sub.example.com. IN NS ns.sub.example.com.
+sub.example.com. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.sub.example.com. IN A 1.2.3.6
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns.sub.example.com. IN AAAA
+SECTION ANSWER
+ENTRY_END
+
+; response to query of interest
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www.sub.example.com. IN A
+SECTION ANSWER
+www.sub.example.com. IN A 11.11.11.11
+SECTION AUTHORITY
+; dnssec-lameness detection depends on this information
+sub.example.com. IN NS ns.sub.example.com.
+sub.example.com. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.sub.example.com. IN A 1.2.3.6
+ENTRY_END
+RANGE_END
+
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.sub.example.com. IN A
+ENTRY_END
+
+STEP 10 NOTHING
+; recursion at time 10.
+; first recursion with answers in 0-30 time
+; with bug it now resolves to the bad version
+; fixed, it stops waiting for more target queries.
+
+STEP 40 NOTHING
+; next recursion with more answers at time 40.
+
+; recursion happens here.
+STEP 50 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+www.sub.example.com. IN A
+SECTION ANSWER
+www.sub.example.com. IN A 11.11.11.11
+www.sub.example.com. 3600 IN RRSIG A 5 4 3600 20070926134150 20070829134150 30899 sub.example.com. 0DqqRfRtm7VSEQ4mmBbzrKRqQAay3JAE8DPDGmjtokrrjN9F1G/HxozDV7bjdIh2EChlQea8FPwf/GepJMUVxg== ;{id = 30899}
+ENTRY_END
+SCENARIO_END
diff --git a/tests/integration/testdata_notimpl/iter_dnsseclame_ds.rpl b/tests/integration/testdata_notimpl/iter_dnsseclame_ds.rpl
new file mode 100644
index 0000000..8b91100
--- /dev/null
+++ b/tests/integration/testdata_notimpl/iter_dnsseclame_ds.rpl
@@ -0,0 +1,414 @@
+; config options
+server:
+ trust-anchor: "example.com. 3600 IN DS 2854 3 1 46e4ffc6e9a4793b488954bd3f0cc6af0dfb201b"
+ val-override-date: "1189950146"
+
+stub-zone:
+ name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+
+CONFIG_END
+
+SCENARIO_BEGIN Test dnssec-lame detection at ds point.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+net. IN A
+SECTION AUTHORITY
+net. IN NS e.gtld-servers.net.
+SECTION ADDITIONAL
+e.gtld-servers.net. IN A 192.12.94.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.net. IN AAAA
+SECTION AUTHORITY
+net. IN NS e.gtld-servers.net.
+SECTION ADDITIONAL
+e.gtld-servers.net. IN A 192.12.94.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.55
+ENTRY_END
+RANGE_END
+
+; e.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.12.94.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+net. IN NS
+SECTION ANSWER
+net. IN NS e.gtld-servers.net.
+SECTION ADDITIONAL
+e.gtld-servers.net. IN A 192.12.94.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+e.gtld-servers.net. IN AAAA
+SECTION ANSWER
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+a.gtld-servers.net. IN AAAA
+SECTION ANSWER
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.net. IN A
+SECTION AUTHORITY
+example.net. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.net. IN A 1.2.3.44
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.net. IN AAAA
+SECTION AUTHORITY
+example.net. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.net. IN A 1.2.3.44
+ENTRY_END
+RANGE_END
+
+; ns.example.net.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.44
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.net. IN NS
+SECTION ANSWER
+example.net. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.net. IN A 1.2.3.44
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns.example.net. IN A
+SECTION ANSWER
+ns.example.net. IN A 1.2.3.44
+SECTION AUTHORITY
+example.net. IN NS ns.example.net.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns.example.net. IN AAAA
+SECTION AUTHORITY
+example.net. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.net. IN A 1.2.3.44
+ENTRY_END
+
+; response to DNSKEY priming query
+; sub.example.com. 3600 IN DS 30899 RSASHA1 1 f7ed618f24d5e5202927e1d27bc2e84a141cb4b3
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+sub.example.com. IN DNSKEY
+SECTION ANSWER
+sub.example.com. 3600 IN DNSKEY 256 3 5 AQPQ41chR9DEHt/aIzIFAqanbDlRflJoRs5yz1jFsoRIT7dWf0r+PeDuewdxkszNH6wnU4QL8pfKFRh5PIYVBLK3 ;{id = 30899 (zsk), size = 512b}
+sub.example.com. 3600 IN RRSIG DNSKEY 5 3 3600 20070926134150 20070829134150 30899 sub.example.com. uNGp99iznjD7oOX02XnQbDnbg75UwBHRvZSKYUorTKvPUnCWMHKdRsQ+mf+Fx3GZ+Fz9BVjoCmQqpnfgXLEYqw== ;{id = 30899}
+SECTION AUTHORITY
+; no NS set. not needed for this test.
+SECTION ADDITIONAL
+ns.sub.example.com. IN A 1.2.3.6
+ns.sub.example.com. 3600 IN RRSIG A 5 4 3600 20070926134150 20070829134150 30899 sub.example.com. UF7shD/gt1FOp2UHgLTNbPzVykklSXFMEtJ1xD+Hholwf/PIzd7zoaIttIYibNa4fUXCqMg22H9P7MRhfmFe6g== ;{id = 30899}
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+sub.example.com. IN NS
+SECTION ANSWER
+sub.example.com. IN NS ns.sub.example.com.
+sub.example.com. IN NS ns.example.net.
+sub.example.com. 3600 IN RRSIG NS 5 3 3600 20070926134150 20070829134150 30899 sub.example.com. C/0b+sqlsdSTkhd+aDXb6ELyuQreosIGBzLCtWxYGD+Q9QGB5rN8uB+4+48yhw36pd3MfeAn06AgAnJ6eu8tJg== ;{id = 30899}
+SECTION ADDITIONAL
+ns.sub.example.com. IN A 1.2.3.6
+ns.sub.example.com. 3600 IN RRSIG A 5 4 3600 20070926134150 20070829134150 30899 sub.example.com. UF7shD/gt1FOp2UHgLTNbPzVykklSXFMEtJ1xD+Hholwf/PIzd7zoaIttIYibNa4fUXCqMg22H9P7MRhfmFe6g== ;{id = 30899}
+ENTRY_END
+
+; response to query of interest
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www.sub.example.com. IN A
+SECTION ANSWER
+www.sub.example.com. IN A 11.11.11.11
+www.sub.example.com. 3600 IN RRSIG A 5 4 3600 20070926134150 20070829134150 30899 sub.example.com. 0DqqRfRtm7VSEQ4mmBbzrKRqQAay3JAE8DPDGmjtokrrjN9F1G/HxozDV7bjdIh2EChlQea8FPwf/GepJMUVxg== ;{id = 30899}
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns.sub.example.com. IN AAAA
+SECTION ANSWER
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.55
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.55
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns.example.com. IN A
+SECTION ANSWER
+ns.example.com. IN A 1.2.3.55
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns.example.com. IN AAAA
+ENTRY_END
+
+; fine DNSKEY response.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+example.com. IN DNSKEY
+SECTION ANSWER
+example.com. 3600 IN DNSKEY 256 3 3 ALXLUsWqUrY3JYER3T4TBJII s70j+sDS/UT2QRp61SE7S3E EXopNXoFE73JLRmvpi/UrOO/Vz4Se 6wXv/CYCKjGw06U4WRgR YXcpEhJROyNapmdIKSx hOzfLVE1gqA0PweZR8d tY3aNQSRn3sPpwJr6Mi /PqQKAMMrZ9ckJpf1+b QMOOvxgzz2U1GS18b3y ZKcgTMEaJzd/GZYzi/B N2DzQ0MsrSwYXfsNLFO Bbs8PJMW4LYIxeeOe6rUgkWOF 7CC9Dh/dduQ1QrsJhmZAEFfd6ByYV+ ;{id = 2854 (zsk), size = 1688b}
+example.com. 3600 IN RRSIG DNSKEY DSA 2 3600 20070926134150 20070829134150 2854 example.com. MCwCFBQRtlR4BEv9ohi+PGFjp+AHsJuHAhRCvz0shggvnvI88DFnBDCczHUcVA== ;{id = 2854}
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
+ENTRY_END
+
+
+; correct delegation with DS
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR AA NOERROR
+SECTION QUESTION
+sub.example.com. IN A
+SECTION ANSWER
+SECTION AUTHORITY
+sub.example.com. IN NS ns.sub.example.com.
+sub.example.com. IN NS ns.example.net.
+sub.example.com. 3600 IN DS 30899 RSASHA1 1 f7ed618f24d5e5202927e1d27bc2e84a141cb4b3
+sub.example.com. 3600 IN RRSIG DS 3 3 3600 20070926134150 20070829134150 2854 example.com. MCwCFCW3ix0GD4BSvNLWIbROCJt5DAW9AhRt/kg9kBKJ20UBUdumrBUHqnskdA== ;{id = 2854}
+SECTION ADDITIONAL
+ns.sub.example.com. IN A 1.2.3.6
+ENTRY_END
+
+; response for delegation to sub.example.com.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+sub.example.com. IN DNSKEY
+SECTION ANSWER
+SECTION AUTHORITY
+sub.example.com. IN NS ns.sub.example.com.
+sub.example.com. IN NS ns.example.net.
+sub.example.com. 3600 IN DS 30899 RSASHA1 1 f7ed618f24d5e5202927e1d27bc2e84a141cb4b3
+sub.example.com. 3600 IN RRSIG DS 3 3 3600 20070926134150 20070829134150 2854 example.com. MCwCFCW3ix0GD4BSvNLWIbROCJt5DAW9AhRt/kg9kBKJ20UBUdumrBUHqnskdA== ;{id = 2854}
+SECTION ADDITIONAL
+ns.sub.example.com. IN A 1.2.3.6
+ENTRY_END
+RANGE_END
+
+; This server is DNSSEC LAME!
+; ns.sub.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.6
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+sub.example.com. IN NS
+SECTION ANSWER
+sub.example.com. IN NS ns.sub.example.com.
+sub.example.com. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.sub.example.com. IN A 1.2.3.6
+ENTRY_END
+
+
+; response to DNSKEY priming query
+; sub.example.com. 3600 IN DS 30899 RSASHA1 1 f7ed618f24d5e5202927e1d27bc2e84a141cb4b3
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+sub.example.com. IN DNSKEY
+SECTION ANSWER
+sub.example.com. 3600 IN DNSKEY 256 3 5 AQPQ41chR9DEHt/aIzIFAqanbDlRflJoRs5yz1jFsoRIT7dWf0r+PeDuewdxkszNH6wnU4QL8pfKFRh5PIYVBLK3 ;{id = 30899 (zsk), size = 512b}
+SECTION AUTHORITY
+sub.example.com. IN NS ns.sub.example.com.
+sub.example.com. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.sub.example.com. IN A 1.2.3.6
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns.sub.example.com. IN AAAA
+SECTION ANSWER
+ENTRY_END
+
+; response to query of interest
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www.sub.example.com. IN A
+SECTION ANSWER
+www.sub.example.com. IN A 11.11.11.11
+SECTION AUTHORITY
+; dnssec-lameness detection depends on this information
+sub.example.com. IN NS ns.sub.example.com.
+sub.example.com. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.sub.example.com. IN A 1.2.3.6
+ENTRY_END
+RANGE_END
+
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.sub.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 20 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+www.sub.example.com. IN A
+SECTION ANSWER
+www.sub.example.com. IN A 11.11.11.11
+www.sub.example.com. 3600 IN RRSIG A 5 4 3600 20070926134150 20070829134150 30899 sub.example.com. 0DqqRfRtm7VSEQ4mmBbzrKRqQAay3JAE8DPDGmjtokrrjN9F1G/HxozDV7bjdIh2EChlQea8FPwf/GepJMUVxg== ;{id = 30899}
+ENTRY_END
+SCENARIO_END
diff --git a/tests/integration/testdata_notimpl/iter_dnsseclame_ds_ok.rpl b/tests/integration/testdata_notimpl/iter_dnsseclame_ds_ok.rpl
new file mode 100644
index 0000000..8b7edeb
--- /dev/null
+++ b/tests/integration/testdata_notimpl/iter_dnsseclame_ds_ok.rpl
@@ -0,0 +1,367 @@
+; config options
+server:
+ trust-anchor: "example.com. 3600 IN DS 2854 3 1 46e4ffc6e9a4793b488954bd3f0cc6af0dfb201b"
+ val-override-date: "1189950146"
+ target-fetch-policy: "0 0 0 0 0"
+
+stub-zone:
+ name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+
+CONFIG_END
+
+SCENARIO_BEGIN Test dnssec-lame detection at ds point, which is ok.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.sub.example.com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.net. IN A
+SECTION AUTHORITY
+net. IN NS e.gtld-servers.net.
+SECTION ADDITIONAL
+e.gtld-servers.net. IN A 192.12.94.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.net. IN AAAA
+SECTION AUTHORITY
+net. IN NS e.gtld-servers.net.
+SECTION ADDITIONAL
+e.gtld-servers.net. IN A 192.12.94.30
+ENTRY_END
+
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.sub.example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.55
+ENTRY_END
+RANGE_END
+
+; e.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.12.94.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+net. IN NS
+SECTION ANSWER
+net. IN NS e.gtld-servers.net.
+SECTION ADDITIONAL
+e.gtld-servers.net. IN A 192.12.94.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.net. IN A
+SECTION AUTHORITY
+example.net. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.net. IN A 1.2.3.44
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.net. IN AAAA
+SECTION AUTHORITY
+example.net. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.net. IN A 1.2.3.44
+ENTRY_END
+RANGE_END
+
+; ns.example.net.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.44
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.net. IN NS
+SECTION ANSWER
+example.net. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.net. IN A 1.2.3.44
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns.example.net. IN A
+SECTION ANSWER
+ns.example.net. IN A 1.2.3.44
+SECTION AUTHORITY
+example.net. IN NS ns.example.net.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns.example.net. IN AAAA
+SECTION AUTHORITY
+example.net. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.net. IN A 1.2.3.44
+ENTRY_END
+
+; response to DNSKEY priming query
+; sub.example.com. 3600 IN DS 30899 RSASHA1 1 f7ed618f24d5e5202927e1d27bc2e84a141cb4b3
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+sub.example.com. IN DNSKEY
+SECTION ANSWER
+sub.example.com. 3600 IN DNSKEY 256 3 5 AQPQ41chR9DEHt/aIzIFAqanbDlRflJoRs5yz1jFsoRIT7dWf0r+PeDuewdxkszNH6wnU4QL8pfKFRh5PIYVBLK3 ;{id = 30899 (zsk), size = 512b}
+sub.example.com. 3600 IN RRSIG DNSKEY 5 3 3600 20070926134150 20070829134150 30899 sub.example.com. uNGp99iznjD7oOX02XnQbDnbg75UwBHRvZSKYUorTKvPUnCWMHKdRsQ+mf+Fx3GZ+Fz9BVjoCmQqpnfgXLEYqw== ;{id = 30899}
+SECTION AUTHORITY
+; no NS set. not needed for this test.
+SECTION ADDITIONAL
+ns.sub.example.com. IN A 1.2.3.6
+ns.sub.example.com. 3600 IN RRSIG A 5 4 3600 20070926134150 20070829134150 30899 sub.example.com. UF7shD/gt1FOp2UHgLTNbPzVykklSXFMEtJ1xD+Hholwf/PIzd7zoaIttIYibNa4fUXCqMg22H9P7MRhfmFe6g== ;{id = 30899}
+ENTRY_END
+
+; response to query of interest
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www.sub.example.com. IN A
+SECTION ANSWER
+www.sub.example.com. IN A 11.11.11.11
+www.sub.example.com. 3600 IN RRSIG A 5 4 3600 20070926134150 20070829134150 30899 sub.example.com. 0DqqRfRtm7VSEQ4mmBbzrKRqQAay3JAE8DPDGmjtokrrjN9F1G/HxozDV7bjdIh2EChlQea8FPwf/GepJMUVxg== ;{id = 30899}
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.55
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.55
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns.example.com. IN A
+SECTION ANSWER
+ns.example.com. IN A 1.2.3.55
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns.example.com. IN AAAA
+ENTRY_END
+
+; fine DNSKEY response.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+example.com. IN DNSKEY
+SECTION ANSWER
+example.com. 3600 IN DNSKEY 256 3 3 ALXLUsWqUrY3JYER3T4TBJII s70j+sDS/UT2QRp61SE7S3E EXopNXoFE73JLRmvpi/UrOO/Vz4Se 6wXv/CYCKjGw06U4WRgR YXcpEhJROyNapmdIKSx hOzfLVE1gqA0PweZR8d tY3aNQSRn3sPpwJr6Mi /PqQKAMMrZ9ckJpf1+b QMOOvxgzz2U1GS18b3y ZKcgTMEaJzd/GZYzi/B N2DzQ0MsrSwYXfsNLFO Bbs8PJMW4LYIxeeOe6rUgkWOF 7CC9Dh/dduQ1QrsJhmZAEFfd6ByYV+ ;{id = 2854 (zsk), size = 1688b}
+example.com. 3600 IN RRSIG DNSKEY DSA 2 3600 20070926134150 20070829134150 2854 example.com. MCwCFBQRtlR4BEv9ohi+PGFjp+AHsJuHAhRCvz0shggvnvI88DFnBDCczHUcVA== ;{id = 2854}
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
+ENTRY_END
+
+; correct delegation with DS
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www.sub.example.com. IN A
+SECTION ANSWER
+SECTION AUTHORITY
+sub.example.com. IN NS ns.sub.example.com.
+sub.example.com. IN NS ns.example.net.
+sub.example.com. 3600 IN DS 30899 RSASHA1 1 f7ed618f24d5e5202927e1d27bc2e84a141cb4b3
+sub.example.com. 3600 IN RRSIG DS 3 3 3600 20070926134150 20070829134150 2854 example.com. MCwCFCW3ix0GD4BSvNLWIbROCJt5DAW9AhRt/kg9kBKJ20UBUdumrBUHqnskdA== ;{id = 2854}
+SECTION ADDITIONAL
+ns.sub.example.com. IN A 1.2.3.6
+ENTRY_END
+
+; response for delegation to sub.example.com.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+sub.example.com. IN DNSKEY
+SECTION ANSWER
+SECTION AUTHORITY
+sub.example.com. IN NS ns.sub.example.com.
+sub.example.com. IN NS ns.example.net.
+sub.example.com. 3600 IN DS 30899 RSASHA1 1 f7ed618f24d5e5202927e1d27bc2e84a141cb4b3
+sub.example.com. 3600 IN RRSIG DS 3 3 3600 20070926134150 20070829134150 2854 example.com. MCwCFCW3ix0GD4BSvNLWIbROCJt5DAW9AhRt/kg9kBKJ20UBUdumrBUHqnskdA== ;{id = 2854}
+SECTION ADDITIONAL
+ns.sub.example.com. IN A 1.2.3.6
+ENTRY_END
+RANGE_END
+
+; server is not DNSSEC lame.
+; ns.sub.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.6
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+sub.example.com. IN NS
+SECTION ANSWER
+sub.example.com. IN NS ns.sub.example.com.
+sub.example.com. IN NS ns.example.net.
+sub.example.com. 3600 IN RRSIG NS 5 3 3600 20070926134150 20070829134150 30899 sub.example.com. C/0b+sqlsdSTkhd+aDXb6ELyuQreosIGBzLCtWxYGD+Q9QGB5rN8uB+4+48yhw36pd3MfeAn06AgAnJ6eu8tJg== ;{id = 30899}
+SECTION ADDITIONAL
+ns.sub.example.com. IN A 1.2.3.6
+ns.sub.example.com. 3600 IN RRSIG A 5 4 3600 20070926134150 20070829134150 30899 sub.example.com. UF7shD/gt1FOp2UHgLTNbPzVykklSXFMEtJ1xD+Hholwf/PIzd7zoaIttIYibNa4fUXCqMg22H9P7MRhfmFe6g== ;{id = 30899}
+ENTRY_END
+
+; response to DNSKEY priming query
+; sub.example.com. 3600 IN DS 30899 RSASHA1 1 f7ed618f24d5e5202927e1d27bc2e84a141cb4b3
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+sub.example.com. IN DNSKEY
+SECTION ANSWER
+sub.example.com. 3600 IN DNSKEY 256 3 5 AQPQ41chR9DEHt/aIzIFAqanbDlRflJoRs5yz1jFsoRIT7dWf0r+PeDuewdxkszNH6wnU4QL8pfKFRh5PIYVBLK3 ;{id = 30899 (zsk), size = 512b}
+sub.example.com. 3600 IN RRSIG DNSKEY 5 3 3600 20070926134150 20070829134150 30899 sub.example.com. uNGp99iznjD7oOX02XnQbDnbg75UwBHRvZSKYUorTKvPUnCWMHKdRsQ+mf+Fx3GZ+Fz9BVjoCmQqpnfgXLEYqw== ;{id = 30899}
+ENTRY_END
+
+; response to query of interest
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www.sub.example.com. IN A
+SECTION ANSWER
+www.sub.example.com. IN A 11.11.11.11
+www.sub.example.com. 3600 IN RRSIG A 5 4 3600 20070926134150 20070829134150 30899 sub.example.com. 0DqqRfRtm7VSEQ4mmBbzrKRqQAay3JAE8DPDGmjtokrrjN9F1G/HxozDV7bjdIh2EChlQea8FPwf/GepJMUVxg== ;{id = 30899}
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns.sub.example.com. IN AAAA
+SECTION ANSWER
+ENTRY_END
+RANGE_END
+
+
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.sub.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 20 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+www.sub.example.com. IN A
+SECTION ANSWER
+www.sub.example.com. IN A 11.11.11.11
+www.sub.example.com. 3600 IN RRSIG A 5 4 3600 20070926134150 20070829134150 30899 sub.example.com. 0DqqRfRtm7VSEQ4mmBbzrKRqQAay3JAE8DPDGmjtokrrjN9F1G/HxozDV7bjdIh2EChlQea8FPwf/GepJMUVxg== ;{id = 30899}
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/testdata_notimpl/iter_dnsseclame_ta.rpl b/tests/integration/testdata_notimpl/iter_dnsseclame_ta.rpl
new file mode 100644
index 0000000..d179401
--- /dev/null
+++ b/tests/integration/testdata_notimpl/iter_dnsseclame_ta.rpl
@@ -0,0 +1,327 @@
+; config options
+server:
+ trust-anchor: "example.com. 3600 IN DS 2854 3 1 46e4ffc6e9a4793b488954bd3f0cc6af0dfb201b"
+ val-override-date: "1189950146"
+
+stub-zone:
+ name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+
+CONFIG_END
+
+SCENARIO_BEGIN Test dnssec-lame detection at anchor point.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+net. IN A
+SECTION AUTHORITY
+net. IN NS e.gtld-servers.net.
+SECTION ADDITIONAL
+e.gtld-servers.net. IN A 192.12.94.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.net. IN AAAA
+SECTION AUTHORITY
+net. IN NS e.gtld-servers.net.
+SECTION ADDITIONAL
+e.gtld-servers.net. IN A 192.12.94.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. IN NS ns.example.net.
+SECTION ADDITIONAL
+; this entry; glue will make unbound take this reference first.
+; it is however, the lame server.
+ns.example.com. IN A 1.2.3.55
+ENTRY_END
+RANGE_END
+
+; e.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.12.94.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+net. IN NS
+SECTION ANSWER
+net. IN NS e.gtld-servers.net.
+SECTION ADDITIONAL
+e.gtld-servers.net. IN A 192.12.94.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+a.gtld-servers.net. IN AAAA
+SECTION ANSWER
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+e.gtld-servers.net. IN AAAA
+SECTION ANSWER
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.net. IN A
+SECTION AUTHORITY
+example.net. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.net. IN A 1.2.3.44
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.net. IN AAAA
+SECTION AUTHORITY
+example.net. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.net. IN A 1.2.3.44
+ENTRY_END
+RANGE_END
+
+; ns.example.net.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.44
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.net. IN NS
+SECTION ANSWER
+example.net. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.net. IN A 1.2.3.44
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns.example.net. IN A
+SECTION ANSWER
+ns.example.net. IN A 1.2.3.44
+SECTION AUTHORITY
+example.net. IN NS ns.example.net.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns.example.net. IN AAAA
+SECTION AUTHORITY
+example.net. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.net. IN A 1.2.3.44
+ENTRY_END
+
+; response to DNSKEY priming query
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+example.com. IN DNSKEY
+SECTION ANSWER
+example.com. 3600 IN DNSKEY 256 3 3 ALXLUsWqUrY3JYER3T4TBJII s70j+sDS/UT2QRp61SE7S3E EXopNXoFE73JLRmvpi/UrOO/Vz4Se 6wXv/CYCKjGw06U4WRgR YXcpEhJROyNapmdIKSx hOzfLVE1gqA0PweZR8d tY3aNQSRn3sPpwJr6Mi /PqQKAMMrZ9ckJpf1+b QMOOvxgzz2U1GS18b3y ZKcgTMEaJzd/GZYzi/B N2DzQ0MsrSwYXfsNLFO Bbs8PJMW4LYIxeeOe6rUgkWOF 7CC9Dh/dduQ1QrsJhmZAEFfd6ByYV+ ;{id = 2854 (zsk), size = 1688b}
+example.com. 3600 IN RRSIG DNSKEY 3 2 3600 20070926134802 20070829134802 2854 example.com. MCwCFG1yhRNtTEa3Eno2zhVVuy2EJX3wAhQeLyUp6+UXcpC5qGNu9tkrTEgPUg== ;{id = 2854}
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+example.com. IN NS ns.example.net.
+example.com. 3600 IN RRSIG NS 3 2 3600 20070926134802 20070829134802 2854 example.com. AJwwYIUGH7HgjehzPVkrVUFmFkSGGksGjUX+/zqpCOG9a/cgGC+n40I= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.55
+ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926134802 20070829134802 2854 example.com. ABUu7ITHLl6vfuWzedIp03igXknUR1gYPBl8X6uIDrvraN1bjQJPXME= ;{id = 2854}
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+www.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFC99iE9K5y2WNgI0gFvBWaTi9wm6AhUAoUqOpDtG5Zct+Qr9F3mSdnbc6V4= ;{id = 2854}
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns.example.com. IN AAAA
+SECTION ANSWER
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.55
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns.example.com. IN A
+SECTION ANSWER
+ns.example.com. IN A 1.2.3.55
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns.example.com. IN AAAA
+ENTRY_END
+
+; lame DNSKEY response.
+; here without sigs (assuming server does unknown-RR type handling)
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+example.com. IN DNSKEY
+SECTION ANSWER
+example.com. 3600 IN DNSKEY 256 3 3 ALXLUsWqUrY3JYER3T4TBJII s70j+sDS/UT2QRp61SE7S3E EXopNXoFE73JLRmvpi/UrOO/Vz4Se 6wXv/CYCKjGw06U4WRgR YXcpEhJROyNapmdIKSx hOzfLVE1gqA0PweZR8d tY3aNQSRn3sPpwJr6Mi /PqQKAMMrZ9ckJpf1+b QMOOvxgzz2U1GS18b3y ZKcgTMEaJzd/GZYzi/B N2DzQ0MsrSwYXfsNLFO Bbs8PJMW4LYIxeeOe6rUgkWOF 7CC9Dh/dduQ1QrsJhmZAEFfd6ByYV+ ;{id = 2854 (zsk), size = 1688b}
+ENTRY_END
+
+; lame NS response
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+example.com. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.55
+ENTRY_END
+
+; the lame response. No RRSIGS.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+; the wrong answer.
+www.example.com. IN A 10.20.30.40
+SECTION AUTHORITY
+; dnssec-lameness detection depends on this information
+example.com. IN NS ns.example.com.
+example.com. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.55
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 20 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+www.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFC99iE9K5y2WNgI0gFvBWaTi9wm6AhUAoUqOpDtG5Zct+Qr9F3mSdnbc6V4= ;{id = 2854}
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/testdata_notimpl/iter_dnsseclame_ta_ok.rpl b/tests/integration/testdata_notimpl/iter_dnsseclame_ta_ok.rpl
new file mode 100644
index 0000000..d53377b
--- /dev/null
+++ b/tests/integration/testdata_notimpl/iter_dnsseclame_ta_ok.rpl
@@ -0,0 +1,303 @@
+; config options
+server:
+ trust-anchor: "example.com. 3600 IN DS 2854 3 1 46e4ffc6e9a4793b488954bd3f0cc6af0dfb201b"
+ val-override-date: "1189950146"
+ target-fetch-policy: "0 0 0 0 0"
+
+stub-zone:
+ name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+
+CONFIG_END
+
+SCENARIO_BEGIN Test dnssec-lame detection with anchor point that is ok.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.net. IN A
+SECTION AUTHORITY
+net. IN NS e.gtld-servers.net.
+SECTION ADDITIONAL
+e.gtld-servers.net. IN A 192.12.94.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.net. IN AAAA
+SECTION AUTHORITY
+net. IN NS e.gtld-servers.net.
+SECTION ADDITIONAL
+e.gtld-servers.net. IN A 192.12.94.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.55
+ENTRY_END
+RANGE_END
+
+; e.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.12.94.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+net. IN NS
+SECTION ANSWER
+net. IN NS e.gtld-servers.net.
+SECTION ADDITIONAL
+e.gtld-servers.net. IN A 192.12.94.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.net. IN A
+SECTION AUTHORITY
+example.net. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.net. IN A 1.2.3.44
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.net. IN AAAA
+SECTION AUTHORITY
+example.net. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.net. IN A 1.2.3.44
+ENTRY_END
+RANGE_END
+
+; ns.example.net.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.44
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.net. IN NS
+SECTION ANSWER
+example.net. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.net. IN A 1.2.3.44
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns.example.net. IN A
+SECTION ANSWER
+ns.example.net. IN A 1.2.3.44
+SECTION AUTHORITY
+example.net. IN NS ns.example.net.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns.example.net. IN AAAA
+SECTION AUTHORITY
+example.net. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.net. IN A 1.2.3.44
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+example.com. IN NS ns.example.net.
+example.com. 3600 IN RRSIG NS 3 2 3600 20070926134802 20070829134802 2854 example.com. AJwwYIUGH7HgjehzPVkrVUFmFkSGGksGjUX+/zqpCOG9a/cgGC+n40I= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.55
+ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926134802 20070829134802 2854 example.com. ABUu7ITHLl6vfuWzedIp03igXknUR1gYPBl8X6uIDrvraN1bjQJPXME= ;{id = 2854}
+ENTRY_END
+
+; response to DNSKEY priming query
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+example.com. IN DNSKEY
+SECTION ANSWER
+example.com. 3600 IN DNSKEY 256 3 3 ALXLUsWqUrY3JYER3T4TBJII s70j+sDS/UT2QRp61SE7S3E EXopNXoFE73JLRmvpi/UrOO/Vz4Se 6wXv/CYCKjGw06U4WRgR YXcpEhJROyNapmdIKSx hOzfLVE1gqA0PweZR8d tY3aNQSRn3sPpwJr6Mi /PqQKAMMrZ9ckJpf1+b QMOOvxgzz2U1GS18b3y ZKcgTMEaJzd/GZYzi/B N2DzQ0MsrSwYXfsNLFO Bbs8PJMW4LYIxeeOe6rUgkWOF 7CC9Dh/dduQ1QrsJhmZAEFfd6ByYV+ ;{id = 2854 (zsk), size = 1688b}
+example.com. 3600 IN RRSIG DNSKEY 3 2 3600 20070926134802 20070829134802 2854 example.com. MCwCFG1yhRNtTEa3Eno2zhVVuy2EJX3wAhQeLyUp6+UXcpC5qGNu9tkrTEgPUg== ;{id = 2854}
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+www.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFC99iE9K5y2WNgI0gFvBWaTi9wm6AhUAoUqOpDtG5Zct+Qr9F3mSdnbc6V4= ;{id = 2854}
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns.example.com. IN AAAA
+SECTION ANSWER
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.55
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns.example.com. IN A
+SECTION ANSWER
+ns.example.com. IN A 1.2.3.55
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns.example.com. IN AAAA
+ENTRY_END
+
+; the response is not lame at all.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+example.com. IN DNSKEY
+SECTION ANSWER
+example.com. 3600 IN DNSKEY 256 3 3 ALXLUsWqUrY3JYER3T4TBJII s70j+sDS/UT2QRp61SE7S3E EXopNXoFE73JLRmvpi/UrOO/Vz4Se 6wXv/CYCKjGw06U4WRgR YXcpEhJROyNapmdIKSx hOzfLVE1gqA0PweZR8d tY3aNQSRn3sPpwJr6Mi /PqQKAMMrZ9ckJpf1+b QMOOvxgzz2U1GS18b3y ZKcgTMEaJzd/GZYzi/B N2DzQ0MsrSwYXfsNLFO Bbs8PJMW4LYIxeeOe6rUgkWOF 7CC9Dh/dduQ1QrsJhmZAEFfd6ByYV+ ;{id = 2854 (zsk), size = 1688b}
+example.com. 3600 IN RRSIG DNSKEY 3 2 3600 20070926134802 20070829134802 2854 example.com. MCwCFG1yhRNtTEa3Eno2zhVVuy2EJX3wAhQeLyUp6+UXcpC5qGNu9tkrTEgPUg== ;{id = 2854}
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+example.com. IN NS ns.example.net.
+example.com. 3600 IN RRSIG NS 3 2 3600 20070926134802 20070829134802 2854 example.com. AJwwYIUGH7HgjehzPVkrVUFmFkSGGksGjUX+/zqpCOG9a/cgGC+n40I= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.55
+ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926134802 20070829134802 2854 example.com. ABUu7ITHLl6vfuWzedIp03igXknUR1gYPBl8X6uIDrvraN1bjQJPXME= ;{id = 2854}
+ENTRY_END
+
+; response is not lame.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+www.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFC99iE9K5y2WNgI0gFvBWaTi9wm6AhUAoUqOpDtG5Zct+Qr9F3mSdnbc6V4= ;{id = 2854}
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 20 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+www.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFC99iE9K5y2WNgI0gFvBWaTi9wm6AhUAoUqOpDtG5Zct+Qr9F3mSdnbc6V4= ;{id = 2854}
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/testdata_notimpl/iter_dp_turnsuseless.rpl b/tests/integration/testdata_notimpl/iter_dp_turnsuseless.rpl
new file mode 100644
index 0000000..9d0c355
--- /dev/null
+++ b/tests/integration/testdata_notimpl/iter_dp_turnsuseless.rpl
@@ -0,0 +1,166 @@
+; config options
+server:
+ target-fetch-policy: "0 0 0 0 0"
+
+stub-zone:
+ name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test parent-child dichotomy where dp turns useless
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+; data for ns-crap does not exist.
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NXDOMAIN
+SECTION QUESTION
+ns-crap. IN NS
+SECTION AUTHORITY
+; very short TTL so it'll expire.
+. 2 SOA . . 1 2 3 4 5
+SECTION ADDITIONAL
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION AUTHORITY
+; very short TTL so it can time out quickly.
+example.com. 2 IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns-crap.
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. 2 IN A 10.20.30.40
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+example.com. IN NS
+ENTRY_END
+
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns-crap.
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+STEP 20 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+STEP 30 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. 2 IN A 10.20.30.40
+ENTRY_END
+
+; parent side stuff times out
+STEP 40 TIME_PASSES ELAPSE 5.0
+
+; actual retry logic must fire
+STEP 50 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+STEP 60 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. 2 IN A 10.20.30.40
+ENTRY_END
+
+
+
+SCENARIO_END
diff --git a/tests/integration/testdata_notimpl/iter_ds_locate_ns.rpl b/tests/integration/testdata_notimpl/iter_ds_locate_ns.rpl
new file mode 100644
index 0000000..d3b613e
--- /dev/null
+++ b/tests/integration/testdata_notimpl/iter_ds_locate_ns.rpl
@@ -0,0 +1,145 @@
+; config options
+server:
+ target-fetch-policy: "0 0 0 0 0"
+
+stub-zone:
+ name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test locate of NS records for parent nameservers of DS
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+; content of root-servers.net
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+root-servers.net. IN NS
+SECTION ANSWER
+root-servers.net. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+k.root-servers.net. IN A
+SECTION ANSWER
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+SECTION AUTHORITY
+root-servers.net. IN NS K.ROOT-SERVERS.NET.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+k.root-servers.net. IN AAAA
+SECTION ANSWER
+SECTION AUTHORITY
+root-servers.net. IN SOA K.ROOT-SERVERS.NET. hostmaster. 1 2 3 4 5
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+root-servers.net. IN DS
+SECTION ANSWER
+SECTION AUTHORITY
+root-servers.net. IN SOA K.ROOT-SERVERS.NET. hostmaster. 1 2 3 4 5
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+net. IN A
+SECTION AUTHORITY
+net. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+net. IN NS
+SECTION ANSWER
+net. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+root-servers.net. IN DS
+SECTION AUTHORITY
+net. IN SOA a.gtld-servers.net. hostmaster. 2 3 4 5 6
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+root-servers.net. IN A
+SECTION AUTHORITY
+root-servers.net. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+root-servers.net. IN DS
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+root-servers.net. IN DS
+SECTION ANSWER
+SECTION AUTHORITY
+net. IN SOA a.gtld-servers.net. hostmaster. 2 3 4 5 6
+SECTION ADDITIONAL
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/testdata_notimpl/iter_ds_locate_ns_cname.rpl b/tests/integration/testdata_notimpl/iter_ds_locate_ns_cname.rpl
new file mode 100644
index 0000000..d99d301
--- /dev/null
+++ b/tests/integration/testdata_notimpl/iter_ds_locate_ns_cname.rpl
@@ -0,0 +1,155 @@
+; config options
+server:
+ target-fetch-policy: "0 0 0 0 0"
+
+stub-zone:
+ name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test locate of NS records for DS with CNAME
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+; content of root-servers.net
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+root-servers.net. IN NS
+SECTION ANSWER
+root-servers.net. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+k.root-servers.net. IN A
+SECTION ANSWER
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+SECTION AUTHORITY
+root-servers.net. IN NS K.ROOT-SERVERS.NET.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+k.root-servers.net. IN AAAA
+SECTION ANSWER
+SECTION AUTHORITY
+root-servers.net. IN SOA K.ROOT-SERVERS.NET. hostmaster. 1 2 3 4 5
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+root-servers.net. IN DS
+SECTION ANSWER
+root-servers.net. IN CNAME blabla.com.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+net. IN A
+SECTION AUTHORITY
+net. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NXDOMAIN
+SECTION QUESTION
+blabla.com. IN DS
+SECTION ANSWER
+SECTION AUTHORITY
+. IN SOA K.ROOT-SERVERS.NET. hostmaster. 1 2 3 4 5
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+net. IN NS
+SECTION ANSWER
+net. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+root-servers.net. IN DS
+SECTION AUTHORITY
+net. IN SOA a.gtld-servers.net. hostmaster. 2 3 4 5 6
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+root-servers.net. IN A
+SECTION AUTHORITY
+root-servers.net. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+root-servers.net. IN DS
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+root-servers.net. IN DS
+SECTION ANSWER
+SECTION AUTHORITY
+net. IN SOA a.gtld-servers.net. hostmaster. 2 3 4 5 6
+SECTION ADDITIONAL
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/testdata_notimpl/iter_ds_locate_ns_detach.rpl b/tests/integration/testdata_notimpl/iter_ds_locate_ns_detach.rpl
new file mode 100644
index 0000000..9288fe5
--- /dev/null
+++ b/tests/integration/testdata_notimpl/iter_ds_locate_ns_detach.rpl
@@ -0,0 +1,296 @@
+; config options
+server:
+ target-fetch-policy: "3 2 1 0 0"
+
+stub-zone:
+ name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test locate of NS records for DS and with detached queries
+; the additional targets looked up cause detached queries.
+; hence the target fetch policy is increased above.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+k.root-servers.net. IN A
+SECTION ANSWER
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+SECTION AUTHORITY
+root-servers.net. IN NS K.ROOT-SERVERS.NET.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+k.root-servers.net. IN AAAA
+SECTION ANSWER
+SECTION AUTHORITY
+root-servers.net. IN SOA K.ROOT-SERVERS.NET. hostmaster. 1 2 3 4 5
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+net. IN DS
+SECTION ANSWER
+SECTION AUTHORITY
+. IN SOA K.ROOT-SERVERS.NET. hostmaster. 1 2 3 4 5
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+net. IN A
+SECTION AUTHORITY
+net. IN NS a.server.net.
+net. IN NS b.server.net.
+net. IN NS c.server.net.
+SECTION ADDITIONAL
+a.server.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.server.net.
+; The b.server.net and c.server.net servers are here to cause
+; extra lookups to be generated (to create detached queries in the
+; iterator), there is no IP address that answers for them set up.
+; force DSNSFind, we host a grandchild zone.
+; also, this range of steps is without responses for b and c, so that
+; they can be force to happen later (after the DSNS is activated).
+RANGE_BEGIN 0 20
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+net. IN NS
+SECTION ANSWER
+net. IN NS a.server.net.
+net. IN NS b.server.net.
+net. IN NS c.server.net.
+SECTION ADDITIONAL
+a.server.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+a.server.net. IN A
+SECTION ANSWER
+a.server.net. IN A 192.5.6.30
+SECTION AUTHORITY
+net. IN NS a.server.net.
+net. IN NS b.server.net.
+net. IN NS c.server.net.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+a.sub.example.net. IN DS
+SECTION AUTHORITY
+sub.example.net. IN SOA a.gtld-servers.net. hostmaster. 2 3 4 5 6
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+sub.example.net. IN NS
+SECTION ANSWER
+sub.example.net. IN NS a.server.net.
+sub.example.net. IN NS b.server.net.
+sub.example.net. IN NS c.server.net.
+SECTION ADDITIONAL
+a.server.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+a.sub.example.net. IN A
+SECTION AUTHORITY
+sub.example.net. IN NS a.server.net.
+SECTION ADDITIONAL
+a.server.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.server.net range with all the answers (to finish the test).
+RANGE_BEGIN 30 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+net. IN NS
+SECTION ANSWER
+net. IN NS a.server.net.
+net. IN NS b.server.net.
+net. IN NS c.server.net.
+SECTION ADDITIONAL
+a.server.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+a.server.net. IN A
+SECTION ANSWER
+a.server.net. IN A 192.5.6.30
+SECTION AUTHORITY
+net. IN NS a.server.net.
+net. IN NS b.server.net.
+net. IN NS c.server.net.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+a.server.net. IN AAAA
+SECTION AUTHORITY
+net. IN SOA a.gtld-servers.net. hostmaster. 2 3 4 5 6
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+b.server.net. IN A
+SECTION AUTHORITY
+net. IN SOA a.gtld-servers.net. hostmaster. 2 3 4 5 6
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+b.server.net. IN AAAA
+SECTION AUTHORITY
+net. IN SOA a.gtld-servers.net. hostmaster. 2 3 4 5 6
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+c.server.net. IN A
+SECTION AUTHORITY
+net. IN SOA a.gtld-servers.net. hostmaster. 2 3 4 5 6
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+c.server.net. IN AAAA
+SECTION AUTHORITY
+net. IN SOA a.gtld-servers.net. hostmaster. 2 3 4 5 6
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+a.sub.example.net. IN DS
+SECTION AUTHORITY
+sub.example.net. IN SOA a.gtld-servers.net. hostmaster. 2 3 4 5 6
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+sub.example.net. IN NS
+SECTION ANSWER
+sub.example.net. IN NS a.server.net.
+sub.example.net. IN NS b.server.net.
+sub.example.net. IN NS c.server.net.
+SECTION ADDITIONAL
+a.server.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+a.sub.example.net. IN A
+SECTION AUTHORITY
+sub.example.net. IN NS a.server.net.
+SECTION ADDITIONAL
+a.server.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+a.sub.example.net. IN DS
+ENTRY_END
+
+; make traffic flow at this time
+STEP 15 TRAFFIC
+
+STEP 20 TRAFFIC
+
+STEP 40 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+a.sub.example.net. IN DS
+SECTION ANSWER
+SECTION AUTHORITY
+sub.example.net. IN SOA a.gtld-servers.net. hostmaster. 2 3 4 5 6
+SECTION ADDITIONAL
+ENTRY_END
+
+STEP 50 TRAFFIC
+
+SCENARIO_END
diff --git a/tests/integration/testdata_notimpl/iter_ds_locate_ns_nosoa.rpl b/tests/integration/testdata_notimpl/iter_ds_locate_ns_nosoa.rpl
new file mode 100644
index 0000000..9c14cea
--- /dev/null
+++ b/tests/integration/testdata_notimpl/iter_ds_locate_ns_nosoa.rpl
@@ -0,0 +1,145 @@
+; config options
+server:
+ target-fetch-policy: "0 0 0 0 0"
+
+stub-zone:
+ name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test locate of NS records for DS without a SOA record
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+; content of root-servers.net
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+root-servers.net. IN NS
+SECTION ANSWER
+root-servers.net. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+k.root-servers.net. IN A
+SECTION ANSWER
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+SECTION AUTHORITY
+root-servers.net. IN NS K.ROOT-SERVERS.NET.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+k.root-servers.net. IN AAAA
+SECTION ANSWER
+SECTION AUTHORITY
+root-servers.net. IN SOA K.ROOT-SERVERS.NET. hostmaster. 1 2 3 4 5
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+root-servers.net. IN DS
+SECTION ANSWER
+SECTION AUTHORITY
+;root-servers.net. IN SOA K.ROOT-SERVERS.NET. hostmaster. 1 2 3 4 5
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+net. IN A
+SECTION AUTHORITY
+net. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+net. IN NS
+SECTION ANSWER
+net. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+root-servers.net. IN DS
+SECTION AUTHORITY
+net. IN SOA a.gtld-servers.net. hostmaster. 2 3 4 5 6
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+root-servers.net. IN A
+SECTION AUTHORITY
+root-servers.net. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+root-servers.net. IN DS
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+root-servers.net. IN DS
+SECTION ANSWER
+SECTION AUTHORITY
+net. IN SOA a.gtld-servers.net. hostmaster. 2 3 4 5 6
+SECTION ADDITIONAL
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/testdata_notimpl/iter_emptydp.rpl b/tests/integration/testdata_notimpl/iter_emptydp.rpl
new file mode 100644
index 0000000..dc17986
--- /dev/null
+++ b/tests/integration/testdata_notimpl/iter_emptydp.rpl
@@ -0,0 +1,263 @@
+; config options
+; The island of trust is at example.com
+server:
+ trust-anchor: "example.com. 3600 IN DS 2854 3 1 46e4ffc6e9a4793b488954bd3f0cc6af0dfb201b"
+ val-override-date: "1189950146"
+ target-fetch-policy: "3 2 1 0 0" # make sure it fetches for test
+
+stub-zone:
+ name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test iterator with empty delegation from cache.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+
+; sneak in some data into the cache to simulate partial data after timeouts
+; gets scrubbed anyway.
+example.net. NS ns.example.net.
+
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+net. IN A
+SECTION AUTHORITY
+net. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+; com zone
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns.example.net.
+SECTION ADDITIONAL
+ENTRY_END
+
+; net zone
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+net. IN NS
+SECTION ANSWER
+net. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+a.gtld-servers.net. IN AAAA
+SECTION ANSWER
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.net. IN A
+SECTION AUTHORITY
+example.net. NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.net. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+; ns.example.net.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+; example.net. zone
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.net. IN NS
+SECTION ANSWER
+example.net. NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.net. IN A 1.2.3.4
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns.example.net. IN A
+SECTION ANSWER
+ns.example.net. IN A 1.2.3.4
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns.example.net. IN AAAA
+SECTION ANSWER
+ENTRY_END
+
+; example.com. zone
+ENTRY_BEGIN
+MATCH opcode qname qtype
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854}
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname qtype
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.com. IN AAAA
+SECTION ANSWER
+; bogus
+ENTRY_END
+
+; response to DNSKEY priming query
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN DNSKEY
+SECTION ANSWER
+example.com. 3600 IN DNSKEY 256 3 3 ALXLUsWqUrY3JYER3T4TBJII s70j+sDS/UT2QRp61SE7S3E EXopNXoFE73JLRmvpi/UrOO/Vz4Se 6wXv/CYCKjGw06U4WRgR YXcpEhJROyNapmdIKSx hOzfLVE1gqA0PweZR8d tY3aNQSRn3sPpwJr6Mi /PqQKAMMrZ9ckJpf1+b QMOOvxgzz2U1GS18b3y ZKcgTMEaJzd/GZYzi/B N2DzQ0MsrSwYXfsNLFO Bbs8PJMW4LYIxeeOe6rUgkWOF 7CC9Dh/dduQ1QrsJhmZAEFfd6ByYV+ ;{id = 2854 (zsk), size = 1688b}
+example.com. 3600 IN RRSIG DNSKEY 3 2 3600 20070926134802 20070829134802 2854 example.com. MCwCFG1yhRNtTEa3Eno2zhVVuy2EJX3wAhQeLyUp6+UXcpC5qGNu9tkrTEgPUg== ;{id = 2854}
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854}
+ENTRY_END
+
+; response to query of interest
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCQMyTjn7WWwpwAR1LlVeLpRgZGuQIUCcJDEkwAuzytTDRlYK7nIMwH1CM= ;{id = 2854}
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+www.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFC99iE9K5y2WNgI0gFvBWaTi9wm6AhUAoUqOpDtG5Zct+Qr9F3mSdnbc6V4= ;{id = 2854}
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+www.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFC99iE9K5y2WNgI0gFvBWaTi9wm6AhUAoUqOpDtG5Zct+Qr9F3mSdnbc6V4= ;{id = 2854}
+;SECTION AUTHORITY
+;example.com. IN NS ns.example.com.
+;example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
+;SECTION ADDITIONAL
+;ns.example.com. IN A 1.2.3.4
+;ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCQMyTjn7WWwpwAR1LlVeLpRgZGuQIUCcJDEkwAuzytTDRlYK7nIMwH1CM= ;{id = 2854}
+ENTRY_END
+
+; make sure glue fetch is done.
+STEP 11 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+ns.example.net. IN AAAA
+ENTRY_END
+
+STEP 12 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+ns.example.net. IN AAAA
+SECTION ANSWER
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/testdata_notimpl/iter_emptydp_for_glue.rpl b/tests/integration/testdata_notimpl/iter_emptydp_for_glue.rpl
new file mode 100644
index 0000000..d469bc2
--- /dev/null
+++ b/tests/integration/testdata_notimpl/iter_emptydp_for_glue.rpl
@@ -0,0 +1,493 @@
+; config options
+; The island of trust is at example.com
+server:
+ trust-anchor: "example.com. 3600 IN DS 2854 3 1 46e4ffc6e9a4793b488954bd3f0cc6af0dfb201b"
+ val-override-date: "1189950146"
+ target-fetch-policy: "3 2 1 0 0" # make sure it fetches for test
+
+stub-zone:
+ name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test iterator with empty delegation for glue address
+; setup:
+; query for www.example.com.
+; needs example.com served by ns.example.net and ns.example.org
+; needs example.net served by ns.example.net and ns.example.org
+; needs example.org served by ns.example.net and ns.example.org
+; but the cache has all these NS rrsets, but not the addresses.
+; observed in the wild this was from the in-addr zone towards two
+; domains with such a setup. and high TTL NS, lower for A.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+
+; sneak in some data into the cache to simulate partial data after timeouts
+; gets scrubbed away now ....
+example.com. NS ns.example.net.
+example.com. NS ns.example.org.
+example.net. NS ns.example.net.
+example.net. NS ns.example.org.
+example.org. NS ns.example.net.
+example.org. NS ns.example.org.
+
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+net. IN A
+SECTION AUTHORITY
+net. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+org. IN A
+SECTION AUTHORITY
+org. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+; com zone
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN A
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN A
+SECTION AUTHORITY
+example.com. NS ns.example.net.
+example.com. NS ns.example.org.
+SECTION ADDITIONAL
+; no glue!
+ENTRY_END
+
+; net zone
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+net. IN A
+SECTION ANSWER
+net. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+a.gtld-servers.net. IN AAAA
+SECTION ANSWER
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.net. IN A
+SECTION AUTHORITY
+example.net. NS ns.example.net.
+example.net. NS ns.example.org.
+SECTION ADDITIONAL
+ns.example.net. IN A 1.2.3.4
+ENTRY_END
+
+; org zone
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+org. IN A
+SECTION ANSWER
+org. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.org. IN A
+SECTION AUTHORITY
+example.org. NS ns.example.net.
+example.org. NS ns.example.org.
+SECTION ADDITIONAL
+ns.example.org. IN A 1.2.3.5
+ENTRY_END
+RANGE_END
+
+; ns.example.net.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+; example.org. zone
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.org. IN NS
+SECTION ANSWER
+example.org. NS ns.example.net.
+example.org. NS ns.example.org.
+SECTION ADDITIONAL
+ns.example.org. IN A 1.2.3.5
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns.example.org. IN A
+SECTION ANSWER
+ns.example.org. IN A 1.2.3.5
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns.example.org. IN AAAA
+SECTION ANSWER
+ENTRY_END
+
+; example.net. zone
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.net. IN NS
+SECTION ANSWER
+example.net. NS ns.example.net.
+example.net. NS ns.example.org.
+SECTION ADDITIONAL
+ns.example.net. IN A 1.2.3.4
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns.example.net. IN A
+SECTION ANSWER
+ns.example.net. IN A 1.2.3.4
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns.example.net. IN AAAA
+SECTION ANSWER
+ENTRY_END
+
+; example.com. zone
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854}
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.com. IN AAAA
+SECTION ANSWER
+; bogus message.
+ENTRY_END
+
+; response to DNSKEY priming query
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN DNSKEY
+SECTION ANSWER
+example.com. 3600 IN DNSKEY 256 3 3 ALXLUsWqUrY3JYER3T4TBJII s70j+sDS/UT2QRp61SE7S3E EXopNXoFE73JLRmvpi/UrOO/Vz4Se 6wXv/CYCKjGw06U4WRgR YXcpEhJROyNapmdIKSx hOzfLVE1gqA0PweZR8d tY3aNQSRn3sPpwJr6Mi /PqQKAMMrZ9ckJpf1+b QMOOvxgzz2U1GS18b3y ZKcgTMEaJzd/GZYzi/B N2DzQ0MsrSwYXfsNLFO Bbs8PJMW4LYIxeeOe6rUgkWOF 7CC9Dh/dduQ1QrsJhmZAEFfd6ByYV+ ;{id = 2854 (zsk), size = 1688b}
+example.com. 3600 IN RRSIG DNSKEY 3 2 3600 20070926134802 20070829134802 2854 example.com. MCwCFG1yhRNtTEa3Eno2zhVVuy2EJX3wAhQeLyUp6+UXcpC5qGNu9tkrTEgPUg== ;{id = 2854}
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854}
+ENTRY_END
+
+; response to query of interest
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCQMyTjn7WWwpwAR1LlVeLpRgZGuQIUCcJDEkwAuzytTDRlYK7nIMwH1CM= ;{id = 2854}
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+www.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFC99iE9K5y2WNgI0gFvBWaTi9wm6AhUAoUqOpDtG5Zct+Qr9F3mSdnbc6V4= ;{id = 2854}
+ENTRY_END
+RANGE_END
+
+; ns.example.org.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.5
+
+; example.org. zone
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.org. IN NS
+SECTION ANSWER
+example.org. NS ns.example.net.
+example.org. NS ns.example.org.
+SECTION ADDITIONAL
+ns.example.org. IN A 1.2.3.5
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns.example.org. IN A
+SECTION ANSWER
+ns.example.org. IN A 1.2.3.5
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns.example.org. IN AAAA
+SECTION ANSWER
+ENTRY_END
+
+; example.net. zone
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.net. IN NS
+SECTION ANSWER
+example.net. NS ns.example.net.
+example.net. NS ns.example.org.
+SECTION ADDITIONAL
+ns.example.net. IN A 1.2.3.4
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns.example.net. IN A
+SECTION ANSWER
+ns.example.net. IN A 1.2.3.4
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns.example.net. IN AAAA
+SECTION ANSWER
+ENTRY_END
+
+; example.com. zone
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854}
+ENTRY_END
+
+; response to DNSKEY priming query
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN DNSKEY
+SECTION ANSWER
+example.com. 3600 IN DNSKEY 256 3 3 ALXLUsWqUrY3JYER3T4TBJII s70j+sDS/UT2QRp61SE7S3E EXopNXoFE73JLRmvpi/UrOO/Vz4Se 6wXv/CYCKjGw06U4WRgR YXcpEhJROyNapmdIKSx hOzfLVE1gqA0PweZR8d tY3aNQSRn3sPpwJr6Mi /PqQKAMMrZ9ckJpf1+b QMOOvxgzz2U1GS18b3y ZKcgTMEaJzd/GZYzi/B N2DzQ0MsrSwYXfsNLFO Bbs8PJMW4LYIxeeOe6rUgkWOF 7CC9Dh/dduQ1QrsJhmZAEFfd6ByYV+ ;{id = 2854 (zsk), size = 1688b}
+example.com. 3600 IN RRSIG DNSKEY 3 2 3600 20070926134802 20070829134802 2854 example.com. MCwCFG1yhRNtTEa3Eno2zhVVuy2EJX3wAhQeLyUp6+UXcpC5qGNu9tkrTEgPUg== ;{id = 2854}
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854}
+ENTRY_END
+
+; response to query of interest
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCQMyTjn7WWwpwAR1LlVeLpRgZGuQIUCcJDEkwAuzytTDRlYK7nIMwH1CM= ;{id = 2854}
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+www.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFC99iE9K5y2WNgI0gFvBWaTi9wm6AhUAoUqOpDtG5Zct+Qr9F3mSdnbc6V4= ;{id = 2854}
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+www.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFC99iE9K5y2WNgI0gFvBWaTi9wm6AhUAoUqOpDtG5Zct+Qr9F3mSdnbc6V4= ;{id = 2854}
+;SECTION AUTHORITY
+;example.com. IN NS ns.example.com.
+;example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
+;SECTION ADDITIONAL
+;ns.example.com. IN A 1.2.3.4
+;ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCQMyTjn7WWwpwAR1LlVeLpRgZGuQIUCcJDEkwAuzytTDRlYK7nIMwH1CM= ;{id = 2854}
+ENTRY_END
+
+; make sure glue fetch is done.
+STEP 11 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+ns.example.net. IN AAAA
+ENTRY_END
+
+STEP 12 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+ns.example.net. IN AAAA
+SECTION ANSWER
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+; make sure NS fetch is done.
+STEP 14 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+example.org. IN NS
+ENTRY_END
+
+STEP 15 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH ; none
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+ns.example.net. IN AAAA
+SECTION ANSWER
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+
+SCENARIO_END
diff --git a/tests/integration/testdata_notimpl/iter_fwdfirst.rpl b/tests/integration/testdata_notimpl/iter_fwdfirst.rpl
new file mode 100644
index 0000000..8f362af
--- /dev/null
+++ b/tests/integration/testdata_notimpl/iter_fwdfirst.rpl
@@ -0,0 +1,157 @@
+; config options
+server:
+ target-fetch-policy: "0 0 0 0 0"
+
+stub-zone:
+ name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+
+forward-zone:
+ name: "example.com"
+ forward-addr: 1.2.3.6 # failing resolver
+ forward-first: yes
+
+CONFIG_END
+
+SCENARIO_BEGIN Test forward-first directive
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+; local resolver (that fails a lot)
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.6
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RA SERVFAIL
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+;example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+;ns.example.com. IN A 1.2.3.4
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RA SERVFAIL
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+;www.example.com. IN A 10.20.30.50
+SECTION AUTHORITY
+;example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+;ns.example.com. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+;SECTION AUTHORITY
+;example.com. IN NS ns.example.com.
+;SECTION ADDITIONAL
+;ns.example.com. IN A 1.2.3.4
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/testdata_notimpl/iter_fwdfirstequal.rpl b/tests/integration/testdata_notimpl/iter_fwdfirstequal.rpl
new file mode 100644
index 0000000..98d5d70
--- /dev/null
+++ b/tests/integration/testdata_notimpl/iter_fwdfirstequal.rpl
@@ -0,0 +1,157 @@
+; config options
+server:
+ target-fetch-policy: "0 0 0 0 0"
+
+stub-zone:
+ name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+
+forward-zone:
+ name: "."
+ forward-addr: 1.2.3.6 # failing resolver
+ forward-first: yes
+
+CONFIG_END
+
+SCENARIO_BEGIN Test forward-first directive with equal stub name configured.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+; local resolver (that fails a lot)
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.6
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RA SERVFAIL
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+;example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+;ns.example.com. IN A 1.2.3.4
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RA SERVFAIL
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+;www.example.com. IN A 10.20.30.50
+SECTION AUTHORITY
+;example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+;ns.example.com. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+;SECTION AUTHORITY
+;example.com. IN NS ns.example.com.
+;SECTION ADDITIONAL
+;ns.example.com. IN A 1.2.3.4
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/testdata_notimpl/iter_fwdstub.rpl b/tests/integration/testdata_notimpl/iter_fwdstub.rpl
new file mode 100644
index 0000000..0cdcc9e
--- /dev/null
+++ b/tests/integration/testdata_notimpl/iter_fwdstub.rpl
@@ -0,0 +1,218 @@
+; config options
+server:
+ target-fetch-policy: "0 0 0 0 0"
+
+stub-zone:
+ name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+forward-zone:
+ name: "example.com"
+ forward-addr: 10.0.0.1
+stub-zone:
+ name: "sub.example.com"
+ stub-addr: 10.0.0.2
+CONFIG_END
+
+SCENARIO_BEGIN Test iterative resolve with a stub under a forward zone
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+; forwarder for example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 10.0.0.1
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.0.0.4
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+
+; fail all other queries
+ENTRY_BEGIN
+MATCH opcode
+ADJUST copy_id copy_query
+REPLY QR SERVFAIL
+SECTION QUESTION
+example.com. IN A
+ENTRY_END
+RANGE_END
+
+; stub for sub.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 10.0.0.2
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+sub.example.com. IN NS
+SECTION ANSWER
+sub.example.com. IN NS ns.sub.example.com.
+SECTION ADDITIONAL
+ns.sub.example.com. IN A 1.2.3.44
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.sub.example.com. IN A
+SECTION ANSWER
+www.sub.example.com. IN A 10.0.0.5
+SECTION AUTHORITY
+sub.example.com. IN NS ns.sub.example.com.
+SECTION ADDITIONAL
+ns.sub.example.com. IN A 1.2.3.44
+ENTRY_END
+RANGE_END
+
+
+; check if forwarder is honored
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.0.0.4
+;SECTION AUTHORITY
+;example.com. IN NS ns.example.com.
+;SECTION ADDITIONAL
+;ns.example.com. IN A 1.2.3.4
+ENTRY_END
+
+; try to resolve from stub zone
+STEP 20 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.sub.example.com. IN A
+ENTRY_END
+
+STEP 30 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.sub.example.com. IN A
+SECTION ANSWER
+www.sub.example.com. IN A 10.0.0.5
+;SECTION AUTHORITY
+;sub.example.com. IN NS ns.sub.example.com.
+;SECTION ADDITIONAL
+;ns.sub.example.com. IN A 1.2.3.44
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/testdata_notimpl/iter_fwdstubroot.rpl b/tests/integration/testdata_notimpl/iter_fwdstubroot.rpl
new file mode 100644
index 0000000..99e1994
--- /dev/null
+++ b/tests/integration/testdata_notimpl/iter_fwdstubroot.rpl
@@ -0,0 +1,175 @@
+; config options
+server:
+ target-fetch-policy: "0 0 0 0 0"
+
+stub-zone:
+ name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+forward-zone:
+ name: "."
+ forward-addr: 10.0.0.1
+stub-zone:
+ name: "sub.example.com"
+ stub-addr: 10.0.0.2
+CONFIG_END
+
+SCENARIO_BEGIN Test iterative resolve with a stub under a forward root zone
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+
+; No answers from the actual root, blocked.
+
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+; forwarder for example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 10.0.0.1
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.0.0.4
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+
+; fail all other queries
+ENTRY_BEGIN
+MATCH opcode
+ADJUST copy_id copy_query
+REPLY QR SERVFAIL
+SECTION QUESTION
+example.com. IN A
+ENTRY_END
+RANGE_END
+
+; stub for sub.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 10.0.0.2
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+sub.example.com. IN NS
+SECTION ANSWER
+sub.example.com. IN NS ns.sub.example.com.
+SECTION ADDITIONAL
+ns.sub.example.com. IN A 1.2.3.44
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.sub.example.com. IN A
+SECTION ANSWER
+www.sub.example.com. IN A 10.0.0.5
+SECTION AUTHORITY
+sub.example.com. IN NS ns.sub.example.com.
+SECTION ADDITIONAL
+ns.sub.example.com. IN A 1.2.3.44
+ENTRY_END
+RANGE_END
+
+; try to resolve from stub zone
+STEP 20 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.sub.example.com. IN A
+ENTRY_END
+
+STEP 30 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.sub.example.com. IN A
+SECTION ANSWER
+www.sub.example.com. IN A 10.0.0.5
+;SECTION AUTHORITY
+;sub.example.com. IN NS ns.sub.example.com.
+;SECTION ADDITIONAL
+;ns.sub.example.com. IN A 1.2.3.44
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/testdata_notimpl/iter_got6only.rpl b/tests/integration/testdata_notimpl/iter_got6only.rpl
new file mode 100644
index 0000000..b842f5c
--- /dev/null
+++ b/tests/integration/testdata_notimpl/iter_got6only.rpl
@@ -0,0 +1,135 @@
+; config options
+server:
+ do-ip6: no
+ target-fetch-policy: "0 0 0 0 0 "
+stub-zone:
+ name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test iterator when only ip6 in dp but doip6 is no
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns.bla.com.
+SECTION ADDITIONAL
+; not included
+;ns.bla.com. IN A 1.2.3.4
+
+; and this one is useless because do-ip6 is "no"
+ns.bla.com. IN AAAA ::53
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.bla.com. IN A
+SECTION ANSWER
+ns.bla.com. IN A 1.2.3.4
+ENTRY_END
+
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+;SECTION AUTHORITY
+;example.com. IN NS ns.example.com.
+;SECTION ADDITIONAL
+;ns.example.com. IN A 1.2.3.4
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/testdata_notimpl/iter_pcdiff.rpl b/tests/integration/testdata_notimpl/iter_pcdiff.rpl
new file mode 100644
index 0000000..8ff4a59
--- /dev/null
+++ b/tests/integration/testdata_notimpl/iter_pcdiff.rpl
@@ -0,0 +1,210 @@
+; config options
+ target-fetch-policy: "0 0 0 0 0"
+ name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test resolution with recursion and parent child differ.
+; and the child gives bad information.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+net. IN NS
+SECTION AUTHORITY
+net. IN NS e.gtld-servers.net.
+SECTION ADDITIONAL
+e.gtld-servers.net. IN A 192.12.94.30
+ENTRY_END
+
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION AUTHORITY
+example.com. IN NS ns.example.net.
+ENTRY_END
+RANGE_END
+
+; e.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.12.94.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+net. IN NS
+SECTION ANSWER
+net. IN NS e.gtld-servers.net.
+SECTION ADDITIONAL
+e.gtld-servers.net. IN A 192.12.94.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.net. IN NS
+SECTION AUTHORITY
+example.net. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.net. IN A 1.2.3.44
+ENTRY_END
+
+RANGE_END
+
+; ns.example.net.
+; The parent-IP version
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.44
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY AA QR NOERROR
+SECTION QUESTION
+example.net. IN NS
+SECTION ANSWER
+example.net. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.net. IN A 1.2.3.55
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY AA QR NOERROR
+SECTION QUESTION
+ns.example.net. IN A
+SECTION ANSWER
+ns.example.net. IN A 1.2.3.55
+SECTION AUTHORITY
+example.net. IN NS ns.example.net.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY AA QR NOERROR
+SECTION QUESTION
+ns.example.net. IN AAAA
+SECTION AUTHORITY
+example.net. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.net. IN A 1.2.3.55
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY AA QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.net.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY AA QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+SECTION AUTHORITY
+example.com. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.net IN A 1.2.3.55
+ENTRY_END
+RANGE_END
+
+; ns.example.net
+; The child IP version. Does not respond to anything (servfail instead
+; of timeouts since this is easier to encode in .rpl file format).
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.55
+ENTRY_BEGIN
+MATCH opcode
+ADJUST copy_id copy_query
+REPLY QR SERVFAIL
+SECTION QUESTION
+example.net. IN NS
+SECTION ANSWER
+ENTRY_END
+
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 20 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+;SECTION AUTHORITY
+;example.com. IN NS ns.example.net.
+; scrubbed off
+;SECTION ADDITIONAL
+;ns.example.net IN A 1.2.3.44
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/testdata_notimpl/iter_pcnamerec.rpl b/tests/integration/testdata_notimpl/iter_pcnamerec.rpl
new file mode 100644
index 0000000..d5cce88
--- /dev/null
+++ b/tests/integration/testdata_notimpl/iter_pcnamerec.rpl
@@ -0,0 +1,275 @@
+; config options
+ target-fetch-policy: "0 0 0 0 0"
+ name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test resolution with parent child differ names recursive.
+; the parent has an extra name that is the only working one.
+; and that name needs its parent-side glue to work.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+net. IN NS
+SECTION AUTHORITY
+net. IN NS e.gtld-servers.net.
+SECTION ADDITIONAL
+e.gtld-servers.net. IN A 192.12.94.30
+ENTRY_END
+
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.55
+ENTRY_END
+RANGE_END
+
+; e.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.12.94.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+net. IN NS
+SECTION ANSWER
+net. IN NS e.gtld-servers.net.
+SECTION ADDITIONAL
+e.gtld-servers.net. IN A 192.12.94.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.net. IN NS
+SECTION AUTHORITY
+example.net. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.net. IN A 1.2.3.44
+ENTRY_END
+
+RANGE_END
+
+; ns.example.net.
+; the working version.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.44
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY AA QR NOERROR
+SECTION QUESTION
+example.net. IN NS
+SECTION ANSWER
+example.net. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.net. IN A 1.2.3.55
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY AA QR NOERROR
+SECTION QUESTION
+ns.example.net. IN A
+SECTION ANSWER
+ns.example.net. IN A 1.2.3.55
+SECTION AUTHORITY
+example.net. IN NS ns.example.net.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY AA QR NOERROR
+SECTION QUESTION
+ns.example.net. IN AAAA
+SECTION AUTHORITY
+example.net. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.net. IN A 1.2.3.55
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY AA QR NOERROR
+SECTION QUESTION
+ns.example.com. IN A
+SECTION ANSWER
+ns.example.com. IN A 1.2.3.55
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY AA QR NOERROR
+SECTION QUESTION
+ns.example.com. IN AAAA
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.55
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY AA QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.55
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY AA QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.55
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY AA QR NOERROR
+SECTION QUESTION
+mail.example.com. IN A
+SECTION ANSWER
+mail.example.com. IN A 10.20.30.20
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.55
+ENTRY_END
+RANGE_END
+
+; ns.example.net
+; Broken. Does not respond to anything (servfail instead
+; of timeouts since this is easier to encode in .rpl file format).
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.55
+ENTRY_BEGIN
+MATCH opcode
+ADJUST copy_id copy_query
+REPLY QR SERVFAIL
+SECTION QUESTION
+example.net. IN NS
+SECTION ANSWER
+ENTRY_END
+
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 20 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+;SECTION AUTHORITY
+;example.com. IN NS ns.example.com.
+;SECTION ADDITIONAL
+;ns.example.com. IN A 1.2.3.55
+ENTRY_END
+
+; now that the bad child NS record is in cache, ask something else.
+STEP 30 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+mail.example.com. IN A
+ENTRY_END
+
+STEP 40 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+mail.example.com. IN A
+SECTION ANSWER
+mail.example.com. IN A 10.20.30.20
+;SECTION AUTHORITY
+;example.com. IN NS ns.example.com.
+;SECTION ADDITIONAL
+;ns.example.com. IN A 1.2.3.55
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/testdata_notimpl/iter_primenoglue.rpl b/tests/integration/testdata_notimpl/iter_primenoglue.rpl
new file mode 100644
index 0000000..2cf72d5
--- /dev/null
+++ b/tests/integration/testdata_notimpl/iter_primenoglue.rpl
@@ -0,0 +1,383 @@
+; config options
+; The island of trust is at example.com
+server:
+ trust-anchor: "example.com. 3600 IN DS 2854 3 1 46e4ffc6e9a4793b488954bd3f0cc6af0dfb201b"
+ val-override-date: "20070916134226"
+ target-fetch-policy: "3 2 1 0 0" # make sure it fetches for test
+
+stub-zone:
+ name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test iterator with root prime answer without glue.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+; glue ommitted!
+;K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+net. IN A
+SECTION AUTHORITY
+net. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+
+; sneak in some data into the cache to simulate partial data after timeouts
+; scrubbed away...
+example.net. NS ns.example.net.
+
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.net. IN A
+SECTION AUTHORITY
+net. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+; com zone
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns.example.net.
+SECTION ADDITIONAL
+ENTRY_END
+
+; net zone
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+net. IN NS
+SECTION ANSWER
+net. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+A.ROOT-SERVERS.NET. IN AAAA
+SECTION ANSWER
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+a.gtld-servers.net. IN AAAA
+SECTION ANSWER
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+K.ROOT-SERVERS.NET. IN A
+SECTION AUTHORITY
+ROOT-SERVERS.NET. IN NS A.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+A.ROOT-SERVERS.NET. IN A 198.41.0.4
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+K.ROOT-SERVERS.NET. IN AAAA
+SECTION ANSWER
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.net. IN A
+SECTION AUTHORITY
+example.net. NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.net. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+; A.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 198.41.0.4
+ENTRY_BEGIN
+MATCH opcode qname qtype
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+ROOT-SERVERS.NET. IN NS
+SECTION ANSWER
+ROOT-SERVERS.NET. IN NS A.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+A.ROOT-SERVERS.NET. IN A 198.41.0.4
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname qtype
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+A.ROOT-SERVERS.NET. IN A
+SECTION ANSWER
+A.ROOT-SERVERS.NET. IN A 198.41.0.4
+SECTION AUTHORITY
+ROOT-SERVERS.NET. IN NS A.ROOT-SERVERS.NET.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname qtype
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+A.ROOT-SERVERS.NET. IN AAAA
+SECTION ANSWER
+SECTION AUTHORITY
+ROOT-SERVERS.NET. IN NS A.ROOT-SERVERS.NET.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+K.ROOT-SERVERS.NET. IN A
+SECTION ANSWER
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+K.ROOT-SERVERS.NET. IN AAAA
+SECTION ANSWER
+; no ip6 address: we want to use only one address for K. to avoid having
+; to duplicate the entries in this file for both addresses.
+ENTRY_END
+RANGE_END
+
+; ns.example.net.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+; example.net. zone
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.net. IN NS
+SECTION ANSWER
+example.net. NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.net. IN A 1.2.3.4
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns.example.net. IN A
+SECTION ANSWER
+ns.example.net. IN A 1.2.3.4
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns.example.net. IN AAAA
+SECTION ANSWER
+ENTRY_END
+
+; example.com. zone
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854}
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname qtype
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.com. IN AAAA
+SECTION ANSWER
+ENTRY_END
+
+
+; response to DNSKEY priming query
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN DNSKEY
+SECTION ANSWER
+example.com. 3600 IN DNSKEY 256 3 3 ALXLUsWqUrY3JYER3T4TBJII s70j+sDS/UT2QRp61SE7S3E EXopNXoFE73JLRmvpi/UrOO/Vz4Se 6wXv/CYCKjGw06U4WRgR YXcpEhJROyNapmdIKSx hOzfLVE1gqA0PweZR8d tY3aNQSRn3sPpwJr6Mi /PqQKAMMrZ9ckJpf1+b QMOOvxgzz2U1GS18b3y ZKcgTMEaJzd/GZYzi/B N2DzQ0MsrSwYXfsNLFO Bbs8PJMW4LYIxeeOe6rUgkWOF 7CC9Dh/dduQ1QrsJhmZAEFfd6ByYV+ ;{id = 2854 (zsk), size = 1688b}
+example.com. 3600 IN RRSIG DNSKEY 3 2 3600 20070926134802 20070829134802 2854 example.com. MCwCFG1yhRNtTEa3Eno2zhVVuy2EJX3wAhQeLyUp6+UXcpC5qGNu9tkrTEgPUg== ;{id = 2854}
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854}
+ENTRY_END
+
+; response to query of interest
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCQMyTjn7WWwpwAR1LlVeLpRgZGuQIUCcJDEkwAuzytTDRlYK7nIMwH1CM= ;{id = 2854}
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+www.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFC99iE9K5y2WNgI0gFvBWaTi9wm6AhUAoUqOpDtG5Zct+Qr9F3mSdnbc6V4= ;{id = 2854}
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+www.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFC99iE9K5y2WNgI0gFvBWaTi9wm6AhUAoUqOpDtG5Zct+Qr9F3mSdnbc6V4= ;{id = 2854}
+;SECTION AUTHORITY
+;example.com. IN NS ns.example.com.
+;example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
+;SECTION ADDITIONAL
+;ns.example.com. IN A 1.2.3.4
+;ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCQMyTjn7WWwpwAR1LlVeLpRgZGuQIUCcJDEkwAuzytTDRlYK7nIMwH1CM= ;{id = 2854}
+ENTRY_END
+
+; make sure glue fetch is done.
+STEP 11 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+ns.example.net. IN AAAA
+ENTRY_END
+
+STEP 12 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+ns.example.net. IN AAAA
+SECTION ANSWER
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+STEP 13 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+K.ROOT-SERVERS.NET. IN AAAA
+ENTRY_END
+
+STEP 14 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+K.ROOT-SERVERS.NET. IN AAAA
+SECTION ANSWER
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/testdata_notimpl/iter_privaddr.rpl b/tests/integration/testdata_notimpl/iter_privaddr.rpl
new file mode 100644
index 0000000..7992910
--- /dev/null
+++ b/tests/integration/testdata_notimpl/iter_privaddr.rpl
@@ -0,0 +1,285 @@
+; config options
+server:
+ target-fetch-policy: "0 0 0 0 0"
+
+ private-address: 10.0.0.0/8
+ private-address: 172.16.0.0/12
+ private-address: 192.168.0.0/16
+ private-address: 169.254.0.0/16
+ private-address: fd00::/8
+ private-address: fe80::/10
+
+ private-domain: "example.net"
+
+stub-zone:
+ name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+
+CONFIG_END
+
+SCENARIO_BEGIN Test iterator scrubber with private addresses.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+; root server authoritative for example.net too.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+mail.example.net. IN A
+SECTION ANSWER
+mail.example.net. IN A 10.20.30.40
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.com. IN A
+SECTION ANSWER
+ns.example.com. IN A 1.2.3.4
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.com. IN AAAA
+SECTION ANSWER
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 192.20.30.40
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+mail.example.com. IN AAAA
+SECTION ANSWER
+mail.example.com. IN AAAA fe80::15
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+foo.example.com. IN A
+SECTION ANSWER
+foo.example.com. IN A 10.20.30.40
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+toss.example.com. IN A
+SECTION ANSWER
+toss.example.com. IN A 10.20.30.40
+toss.example.com. IN A 1.2.3.4
+toss.example.com. IN A 10.20.30.41
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+; public address is not scrubbed
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 2 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 192.20.30.40
+;SECTION AUTHORITY
+;example.com. IN NS ns.example.com.
+;SECTION ADDITIONAL
+;ns.example.com. IN A 1.2.3.4
+ENTRY_END
+
+; IPv4 address is scrubbed
+STEP 3 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+foo.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA SERVFAIL
+SECTION QUESTION
+foo.example.com. IN A
+SECTION ANSWER
+; scrubbed away
+;foo.example.com. IN A 10.20.30.40
+ENTRY_END
+
+; IPv6 address is scrubbed
+STEP 20 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+mail.example.com. IN AAAA
+ENTRY_END
+
+STEP 30 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA SERVFAIL
+SECTION QUESTION
+mail.example.com. IN AAAA
+SECTION ANSWER
+ENTRY_END
+
+; allowed domain is not scrubbed.
+STEP 40 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+mail.example.net. IN A
+ENTRY_END
+
+STEP 50 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+mail.example.net. IN A
+SECTION ANSWER
+mail.example.net. IN A 10.20.30.40
+ENTRY_END
+
+; rest of RRset intact, only 10/8 tossed away.
+STEP 60 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+toss.example.com. IN A
+ENTRY_END
+
+STEP 70 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+toss.example.com. IN A
+SECTION ANSWER
+; toss.example.com. IN A 10.20.30.40
+toss.example.com. IN A 1.2.3.4
+;SECTION AUTHORITY
+;example.com. IN NS ns.example.com.
+;SECTION ADDITIONAL
+;ns.example.com. IN A 1.2.3.4
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/testdata_notimpl/iter_ranoaa_lame.rpl b/tests/integration/testdata_notimpl/iter_ranoaa_lame.rpl
new file mode 100644
index 0000000..c78f36a
--- /dev/null
+++ b/tests/integration/testdata_notimpl/iter_ranoaa_lame.rpl
@@ -0,0 +1,293 @@
+; config options
+server:
+ target-fetch-policy: "0 0 0 0 0"
+
+stub-zone:
+ name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test detection of RA but no AA lameness
+; in this scenario mistakenly, a recursive server is deployed, instead
+; of an authoritative server. It gives answers from cache.
+; However, unbound is doing recursion on behalf of its client, and does
+; not trust the server to do so.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+net. IN A
+SECTION AUTHORITY
+net. IN NS e.gtld-servers.net.
+SECTION ADDITIONAL
+e.gtld-servers.net. IN A 192.12.94.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. IN NS ns.example.net.
+SECTION ADDITIONAL
+; this entry; glue will make unbound take this reference first.
+; it is however, the lame server.
+ns.example.com. IN A 1.2.3.55
+ENTRY_END
+RANGE_END
+
+; e.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.12.94.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+net. IN NS
+SECTION ANSWER
+net. IN NS e.gtld-servers.net.
+SECTION ADDITIONAL
+e.gtld-servers.net. IN A 192.12.94.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.net. IN A
+SECTION AUTHORITY
+example.net. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.net. IN A 1.2.3.44
+ENTRY_END
+RANGE_END
+
+; ns.example.net.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.44
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.net. IN NS
+SECTION ANSWER
+example.net. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.net. IN A 1.2.3.44
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+example.com. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.net IN A 1.2.3.44
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.net. IN A
+SECTION ANSWER
+ns.example.net. IN A 1.2.3.44
+SECTION AUTHORITY
+example.net. IN NS ns.example.net.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.net. IN AAAA
+SECTION AUTHORITY
+example.net. IN NS ns.example.net.
+SECTION ADDITIONAL
+www.example.net. IN A 1.2.3.44
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.net IN A 1.2.3.44
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.com. IN AAAA
+SECTION ANSWER
+ENTRY_END
+
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.55
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+example.com. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.55
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.com. IN A
+SECTION ANSWER
+ns.example.com. IN A 1.2.3.55
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.com. IN AAAA
+SECTION ANSWER
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.net. IN AAAA
+ENTRY_END
+
+; the lame response.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+; the wrong answer.
+www.example.com. IN A 10.20.30.50
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+example.com. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.55
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 20 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+;SECTION AUTHORITY
+;example.com. IN NS ns.example.com.
+;example.com. IN NS ns.example.net.
+; scrubbed off
+;SECTION ADDITIONAL
+;ns.example.net IN A 1.2.3.44
+ENTRY_END
+
+; query still pending
+STEP 30 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+ns.example.net. IN AAAA
+ENTRY_END
+
+; query still pending
+STEP 40 CHECK_ANSWER
+ENTRY_BEGIN
+REPLY RD RA
+SECTION QUESTION
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/testdata_notimpl/iter_scrub_cname_an.rpl b/tests/integration/testdata_notimpl/iter_scrub_cname_an.rpl
new file mode 100644
index 0000000..1fa6c84
--- /dev/null
+++ b/tests/integration/testdata_notimpl/iter_scrub_cname_an.rpl
@@ -0,0 +1,181 @@
+; config options
+server:
+ harden-referral-path: no
+ target-fetch-policy: "0 0 0 0 0"
+
+stub-zone:
+ name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test scrub of CNAME in answer section
+
+STEP 10 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+; root prime is sent
+STEP 20 CHECK_OUT_QUERY
+ENTRY_BEGIN
+MATCH qname qtype opcode
+SECTION QUESTION
+. IN NS
+ENTRY_END
+STEP 30 REPLY
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+; query sent to root server
+STEP 40 CHECK_OUT_QUERY
+ENTRY_BEGIN
+MATCH qname qtype opcode
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+STEP 50 REPLY
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+; query sent to .com server
+STEP 60 CHECK_OUT_QUERY
+ENTRY_BEGIN
+MATCH qname qtype opcode
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+; STEP 62 CHECK_OUT_QUERY
+; ENTRY_BEGIN
+; MATCH qname qtype opcode
+; SECTION QUESTION
+; com. IN NS
+; ENTRY_END
+; STEP 63 REPLY
+; ENTRY_BEGIN
+; MATCH opcode qtype qname
+; ADJUST copy_id
+; REPLY QR NOERROR
+; SECTION QUESTION
+; com. IN NS
+; SECTION ANSWER
+; com. IN NS a.gtld-servers.net.
+; SECTION ADDITIONAL
+; a.gtld-servers.net. IN A 192.5.6.30
+; ENTRY_END
+
+STEP 70 REPLY
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns1.example.com.
+SECTION ADDITIONAL
+ns1.example.com. IN A 168.192.2.2
+ENTRY_END
+
+; this query reply has to be scrubbed
+STEP 80 CHECK_OUT_QUERY
+ENTRY_BEGIN
+MATCH qname qtype opcode
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+; STEP 82 CHECK_OUT_QUERY
+; ENTRY_BEGIN
+; MATCH qname qtype opcode
+; SECTION QUESTION
+; example.com. IN NS
+; ENTRY_END
+; STEP 83 REPLY
+; ENTRY_BEGIN
+; MATCH opcode qtype qname
+; ADJUST copy_id
+; REPLY QR NOERROR
+; SECTION QUESTION
+; example.com. IN NS
+; SECTION ANSWER
+; example.com. IN NS ns1.example.com.
+; SECTION ADDITIONAL
+; ns1.example.com. IN A 168.192.2.2
+; ENTRY_END
+
+STEP 90 REPLY
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN CNAME next.example.com.
+next.example.com. IN A 10.20.30.0
+SECTION AUTHORITY
+example.com. IN NS ns1.example.com.
+SECTION ADDITIONAL
+ns1.example.com. IN A 168.192.2.2
+ENTRY_END
+
+; iterator should try again and ask the other nameserver.
+STEP 100 CHECK_OUT_QUERY
+ENTRY_BEGIN
+MATCH qname qtype opcode
+SECTION QUESTION
+next.example.com. IN A
+ENTRY_END
+STEP 110 REPLY
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+next.example.com. IN A
+SECTION ANSWER
+next.example.com. IN A 10.20.30.40
+SECTION AUTHORITY
+example.com. IN NS ns1.example.com.
+SECTION ADDITIONAL
+ns1.example.com. IN A 168.192.2.2
+ENTRY_END
+
+; is the final answer correct?
+STEP 200 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN CNAME next.example.com.
+next.example.com. IN A 10.20.30.40
+;SECTION AUTHORITY
+;example.com. IN NS ns1.example.com.
+;SECTION ADDITIONAL
+;ns1.example.com. IN A 168.192.2.2
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/testdata_notimpl/iter_scrub_dname_insec.rpl b/tests/integration/testdata_notimpl/iter_scrub_dname_insec.rpl
new file mode 100644
index 0000000..921ef12
--- /dev/null
+++ b/tests/integration/testdata_notimpl/iter_scrub_dname_insec.rpl
@@ -0,0 +1,250 @@
+; config options
+server:
+ harden-referral-path: no
+ target-fetch-policy: "0 0 0 0 0"
+
+stub-zone:
+ name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test scrub of insecure DNAME in answer section
+
+STEP 10 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+x.y.example.com. IN A
+ENTRY_END
+
+; root prime is sent
+STEP 20 CHECK_OUT_QUERY
+ENTRY_BEGIN
+MATCH qname qtype opcode
+SECTION QUESTION
+. IN NS
+ENTRY_END
+STEP 30 REPLY
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+; query sent to root server
+STEP 40 CHECK_OUT_QUERY
+ENTRY_BEGIN
+MATCH qname qtype opcode
+SECTION QUESTION
+x.y.example.com. IN A
+ENTRY_END
+STEP 50 REPLY
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+x.y.example.com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+; query sent to .com server
+STEP 60 CHECK_OUT_QUERY
+ENTRY_BEGIN
+MATCH qname qtype opcode
+SECTION QUESTION
+x.y.example.com. IN A
+ENTRY_END
+
+; STEP 62 CHECK_OUT_QUERY
+; ENTRY_BEGIN
+; MATCH qname qtype opcode
+; SECTION QUESTION
+; com. IN NS
+; ENTRY_END
+; STEP 63 REPLY
+; ENTRY_BEGIN
+; MATCH opcode qtype qname
+; ADJUST copy_id
+; REPLY QR NOERROR
+; SECTION QUESTION
+; com. IN NS
+; SECTION ANSWER
+; com. IN NS a.gtld-servers.net.
+; SECTION ADDITIONAL
+; a.gtld-servers.net. IN A 192.5.6.30
+; ENTRY_END
+
+STEP 70 REPLY
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+x.y.example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns1.example.com.
+SECTION ADDITIONAL
+ns1.example.com. IN A 168.192.2.2
+ENTRY_END
+
+STEP 80 CHECK_OUT_QUERY
+ENTRY_BEGIN
+MATCH qname qtype opcode
+SECTION QUESTION
+x.y.example.com. IN A
+ENTRY_END
+
+; STEP 82 CHECK_OUT_QUERY
+; ENTRY_BEGIN
+; MATCH qname qtype opcode
+; SECTION QUESTION
+; example.com. IN NS
+; ENTRY_END
+; STEP 83 REPLY
+; ENTRY_BEGIN
+; MATCH opcode qtype qname
+; ADJUST copy_id
+; REPLY QR NOERROR
+; SECTION QUESTION
+; example.com. IN NS
+; SECTION ANSWER
+; example.com. IN NS ns1.example.com.
+; SECTION ADDITIONAL
+; ns1.example.com. IN A 168.192.2.2
+; ENTRY_END
+
+STEP 90 REPLY
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+x.y.example.com. IN A
+SECTION ANSWER
+y.example.com. DNAME z.example.com.
+x.y.example.com. IN CNAME x.z.example.com.
+x.z.example.com. IN A 10.20.30.0
+SECTION AUTHORITY
+example.com. IN NS ns1.example.com.
+SECTION ADDITIONAL
+ns1.example.com. IN A 168.192.2.2
+ENTRY_END
+
+STEP 100 CHECK_OUT_QUERY
+ENTRY_BEGIN
+MATCH qname qtype opcode
+SECTION QUESTION
+x.z.example.com. IN A
+ENTRY_END
+STEP 110 REPLY
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+x.z.example.com. IN A
+SECTION ANSWER
+x.z.example.com. IN A 10.20.30.40
+SECTION AUTHORITY
+example.com. IN NS ns1.example.com.
+SECTION ADDITIONAL
+ns1.example.com. IN A 168.192.2.2
+ENTRY_END
+
+; answer to first query (simply puts DNAME in cache)
+STEP 120 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA
+SECTION QUESTION
+x.y.example.com. IN A
+SECTION ANSWER
+y.example.com. DNAME z.example.com.
+x.y.example.com. IN CNAME x.z.example.com.
+x.z.example.com. IN A 10.20.30.40
+;SECTION AUTHORITY
+;example.com. IN NS ns1.example.com.
+;SECTION ADDITIONAL
+;ns1.example.com. IN A 168.192.2.2
+ENTRY_END
+
+; now, DNAME insecure from cache should not be used.
+; new query
+STEP 200 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+other.y.example.com. IN A
+ENTRY_END
+
+STEP 210 CHECK_OUT_QUERY
+ENTRY_BEGIN
+MATCH qname qtype opcode
+SECTION QUESTION
+other.y.example.com. IN A
+ENTRY_END
+STEP 220 REPLY
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+other.y.example.com. IN A
+SECTION ANSWER
+y.example.com. DNAME z.example.com.
+other.y.example.com. IN CNAME other.z.example.com.
+other.z.example.com. IN A 50.60.70.0
+SECTION AUTHORITY
+example.com. IN NS ns1.example.com.
+SECTION ADDITIONAL
+ns1.example.com. IN A 168.192.2.2
+ENTRY_END
+
+STEP 230 CHECK_OUT_QUERY
+ENTRY_BEGIN
+MATCH qname qtype opcode
+SECTION QUESTION
+other.z.example.com. IN A
+ENTRY_END
+STEP 240 REPLY
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+other.z.example.com. IN A
+SECTION ANSWER
+other.z.example.com. IN A 50.60.70.80
+SECTION AUTHORITY
+example.com. IN NS ns1.example.com.
+SECTION ADDITIONAL
+ns1.example.com. IN A 168.192.2.2
+ENTRY_END
+
+STEP 250 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA
+SECTION QUESTION
+other.y.example.com. IN A
+SECTION ANSWER
+y.example.com. DNAME z.example.com.
+other.y.example.com. IN CNAME other.z.example.com.
+other.z.example.com. IN A 50.60.70.80
+;SECTION AUTHORITY
+;example.com. IN NS ns1.example.com.
+;SECTION ADDITIONAL
+;ns1.example.com. IN A 168.192.2.2
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/testdata_notimpl/iter_scrub_dname_sec.rpl b/tests/integration/testdata_notimpl/iter_scrub_dname_sec.rpl
new file mode 100644
index 0000000..0d06bf4
--- /dev/null
+++ b/tests/integration/testdata_notimpl/iter_scrub_dname_sec.rpl
@@ -0,0 +1,212 @@
+; config options
+server:
+ trust-anchor: "example.com. 3600 IN DS 2854 3 1 46e4ffc6e9a4793b488954bd3f0cc6af0dfb201b"
+ trust-anchor: "example.net. 3600 IN DNSKEY 256 3 5 AQPQ41chR9DEHt/aIzIFAqanbDlRflJoRs5yz1jFsoRIT7dWf0r+PeDuewdxkszNH6wnU4QL8pfKFRh5PIYVBLK3 ;{id = 30899 (zsk), size = 512b}"
+ val-override-date: "20070916134226"
+ target-fetch-policy: "0 0 0 0 0"
+
+stub-zone:
+ name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test scrub of secure DNAME in answer section
+
+RANGE_BEGIN 0 100
+; all adresses
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+; ENTRY_BEGIN
+; MATCH opcode qtype qname
+; ADJUST copy_id
+; REPLY QR NOERROR
+; SECTION QUESTION
+; x.y.example.com. IN A
+; SECTION AUTHORITY
+; com. IN NS a.gtld-servers.net.
+; SECTION ADDITIONAL
+; a.gtld-servers.net. IN A 192.5.6.30
+; ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+; ENTRY_BEGIN
+; MATCH opcode qtype qname
+; ADJUST copy_id
+; REPLY QR NOERROR
+; SECTION QUESTION
+; x.y.example.com. IN A
+; SECTION AUTHORITY
+; example.com. IN NS ns1.example.com.
+; SECTION ADDITIONAL
+; ns1.example.com. IN A 168.192.2.2
+; ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+x.y.example.com. IN A
+SECTION ANSWER
+y.example.com. DNAME z.example.com.
+y.example.com. 3600 IN RRSIG DNAME 3 3 3600 20070926134150 20070829134150 2854 example.com. ALCQdkXflwgQVKCFeYgCAx3ipuoPsGJVZjNeUriXE4nd94h50zJWDJ4= ;{id = 2854}
+x.y.example.com. IN CNAME x.z.example.com.
+x.z.example.com. IN A 10.20.30.0
+SECTION AUTHORITY
+example.com. IN NS ns1.example.com.
+example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. AA3IkI13XbKFU5NSqBVA9oM1WiyEKCy4DYFOAdihDf6uHps9lce3kEc= ;{id = 2854}
+SECTION ADDITIONAL
+ns1.example.com. IN A 168.192.2.2
+ns1.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. AKcUlwrSz2xYKnQ7b7oMblRa0rKjfUNT900bIkGjLKLWDUGc8mKZE2M= ;{id = 2854}
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+x.z.example.com. IN A
+SECTION ANSWER
+x.z.example.com. IN A 10.20.30.40
+x.z.example.com. 3600 IN RRSIG A 3 4 3600 20070926134150 20070829134150 2854 example.com. ADZ12PiZGEjVUyLLYkct/SBE2WT4D5IkMOKdcl0dzQ0XRAC5y/0bS7A= ;{id = 2854}
+SECTION AUTHORITY
+example.com. IN NS ns1.example.com.
+example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. ADesKDqTIOswg5QC6eTIQvGu3DHsPMz1htpHLcDJwE8IpURTnMuD0Mw= ;{id = 2854}
+SECTION ADDITIONAL
+ns1.example.com. IN A 168.192.2.2
+ns1.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. ACYkeSRNcLVXeL+R9AM9e1GbxTwXNXpy1M5hcyuVkhkY2d5jGrkye7I= ;{id = 2854}
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns1.example.com.
+example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. ACHcJehLt4Hz+rAdxMPE96o7HJAEFohFXbxrKYlG+0WLfYAvH2nxU8k= ;{id = 2854}
+SECTION ADDITIONAL
+ns1.example.com. IN A 168.192.2.2
+ns1.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. AInP69g8uR1n/aRg4gmGu8UoM+zZYgjOqbNN2IvOxw3bk/q+g05jKg0= ;{id = 2854}
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+example.com. IN DNSKEY
+SECTION ANSWER
+example.com. 3600 IN DNSKEY 256 3 3 ALXLUsWqUrY3JYER3T4TBJII s70j+sDS/UT2QRp61SE7S3E EXopNXoFE73JLRmvpi/UrOO/Vz4Se 6wXv/CYCKjGw06U4WRgR YXcpEhJROyNapmdIKSx hOzfLVE1gqA0PweZR8d tY3aNQSRn3sPpwJr6Mi /PqQKAMMrZ9ckJpf1+b QMOOvxgzz2U1GS18b3y ZKcgTMEaJzd/GZYzi/B N2DzQ0MsrSwYXfsNLFO Bbs8PJMW4LYIxeeOe6rUgkWOF 7CC9Dh/dduQ1QrsJhmZAEFfd6ByYV+ ;{id = 2854 (zsk), size = 1688b}
+example.com. 3600 IN RRSIG DNSKEY DSA 2 3600 20070926134150 20070829134150 2854 example.com. MCwCFBQRtlR4BEv9ohi+PGFjp+AHsJuHAhRCvz0shggvnvI88DFnBDCczHUcVA== ;{id = 2854}
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+
+RANGE_END
+
+STEP 10 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+x.y.example.com. IN A
+ENTRY_END
+
+; answer to first query (simply puts DNAME in cache)
+STEP 90 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA AD DO
+SECTION QUESTION
+x.y.example.com. IN A
+SECTION ANSWER
+y.example.com. DNAME z.example.com.
+y.example.com. 3600 IN RRSIG DNAME 3 3 3600 20070926134150 20070829134150 2854 example.com. ALCQdkXflwgQVKCFeYgCAx3ipuoPsGJVZjNeUriXE4nd94h50zJWDJ4= ;{id = 2854}
+x.y.example.com. IN CNAME x.z.example.com.
+x.z.example.com. IN A 10.20.30.40
+x.z.example.com. 3600 IN RRSIG A 3 4 3600 20070926134150 20070829134150 2854 example.com. ADZ12PiZGEjVUyLLYkct/SBE2WT4D5IkMOKdcl0dzQ0XRAC5y/0bS7A= ;{id = 2854}
+;SECTION AUTHORITY
+;example.com. IN NS ns1.example.com.
+;example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. ADesKDqTIOswg5QC6eTIQvGu3DHsPMz1htpHLcDJwE8IpURTnMuD0Mw= ;{id = 2854}
+;SECTION ADDITIONAL
+;ns1.example.com. IN A 168.192.2.2
+;ns1.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. ACYkeSRNcLVXeL+R9AM9e1GbxTwXNXpy1M5hcyuVkhkY2d5jGrkye7I= ;{id = 2854}
+ENTRY_END
+
+; now, DNAME is secure and can be used from cache.
+; new query
+STEP 200 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+other.y.example.com. IN A
+ENTRY_END
+
+STEP 230 CHECK_OUT_QUERY
+ENTRY_BEGIN
+MATCH qname qtype opcode
+SECTION QUESTION
+other.z.example.com. IN A
+ENTRY_END
+STEP 240 REPLY
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+other.z.example.com. IN A
+SECTION ANSWER
+other.z.example.com. IN A 50.60.70.80
+other.z.example.com. 3600 IN RRSIG A 3 4 3600 20070926134150 20070829134150 2854 example.com. AAp6G89oAvkyAaeF2d35AJNlzMhedGo0Bcppl0IOyF3HRzoc51vjJoU= ;{id = 2854}
+SECTION AUTHORITY
+example.com. IN NS ns1.example.com.
+example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. ADesKDqTIOswg5QC6eTIQvGu3DHsPMz1htpHLcDJwE8IpURTnMuD0Mw= ;{id = 2854}
+SECTION ADDITIONAL
+ns1.example.com. IN A 168.192.2.2
+ns1.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. ACYkeSRNcLVXeL+R9AM9e1GbxTwXNXpy1M5hcyuVkhkY2d5jGrkye7I= ;{id = 2854}
+ENTRY_END
+
+STEP 250 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA AD DO
+SECTION QUESTION
+other.y.example.com. IN A
+SECTION ANSWER
+y.example.com. DNAME z.example.com.
+y.example.com. 3600 IN RRSIG DNAME 3 3 3600 20070926134150 20070829134150 2854 example.com. ALCQdkXflwgQVKCFeYgCAx3ipuoPsGJVZjNeUriXE4nd94h50zJWDJ4= ;{id = 2854}
+other.y.example.com. IN CNAME other.z.example.com.
+other.z.example.com. IN A 50.60.70.80
+other.z.example.com. 3600 IN RRSIG A 3 4 3600 20070926134150 20070829134150 2854 example.com. AAp6G89oAvkyAaeF2d35AJNlzMhedGo0Bcppl0IOyF3HRzoc51vjJoU= ;{id = 2854}
+;SECTION AUTHORITY
+;example.com. IN NS ns1.example.com.
+;example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. ADesKDqTIOswg5QC6eTIQvGu3DHsPMz1htpHLcDJwE8IpURTnMuD0Mw= ;{id = 2854}
+;SECTION ADDITIONAL
+;ns1.example.com. IN A 168.192.2.2
+;ns1.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. ACYkeSRNcLVXeL+R9AM9e1GbxTwXNXpy1M5hcyuVkhkY2d5jGrkye7I= ;{id = 2854}
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/testdata_notimpl/iter_scrub_ns.rpl b/tests/integration/testdata_notimpl/iter_scrub_ns.rpl
new file mode 100644
index 0000000..365f0b5
--- /dev/null
+++ b/tests/integration/testdata_notimpl/iter_scrub_ns.rpl
@@ -0,0 +1,103 @@
+; config options
+server:
+ target-fetch-policy: "0 0 0 0 0"
+
+stub-zone:
+ name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+
+stub-zone:
+ name: "example.com"
+ stub-addr: 1.2.3.4
+CONFIG_END
+
+SCENARIO_BEGIN Test scrubber to scrub NS record for lamelike reply from stub
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+; must be scrubbed
+www.burritolovers.com. IN A 10.20.30.40
+SECTION AUTHORITY
+example1234.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+mail.example.com. IN A
+SECTION ANSWER
+SECTION AUTHORITY
+; LAME
+com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+STEP 20 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+mail.example.com. IN A
+ENTRY_END
+
+STEP 30 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA SERVFAIL
+SECTION QUESTION
+mail.example.com. IN A
+SECTION ANSWER
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/testdata_notimpl/iter_scrub_ns_fwd.rpl b/tests/integration/testdata_notimpl/iter_scrub_ns_fwd.rpl
new file mode 100644
index 0000000..239dc37
--- /dev/null
+++ b/tests/integration/testdata_notimpl/iter_scrub_ns_fwd.rpl
@@ -0,0 +1,103 @@
+; config options
+server:
+ target-fetch-policy: "0 0 0 0 0"
+
+stub-zone:
+ name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+
+forward-zone:
+ name: "example.com"
+ forward-addr: 1.2.3.4
+CONFIG_END
+
+SCENARIO_BEGIN Test scrubber to scrub NS record for lamelike reply from fwd
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY RD RA QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+; must be scrubbed
+www.burritolovers.com. IN A 10.20.30.40
+SECTION AUTHORITY
+example1234.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY RD RA QR NOERROR
+SECTION QUESTION
+mail.example.com. IN A
+SECTION ANSWER
+SECTION AUTHORITY
+; LAME
+com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+STEP 20 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+mail.example.com. IN A
+ENTRY_END
+
+STEP 30 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA SERVFAIL
+SECTION QUESTION
+mail.example.com. IN A
+SECTION ANSWER
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/testdata_notimpl/iter_scrub_ns_side.rpl b/tests/integration/testdata_notimpl/iter_scrub_ns_side.rpl
new file mode 100644
index 0000000..98d00fd
--- /dev/null
+++ b/tests/integration/testdata_notimpl/iter_scrub_ns_side.rpl
@@ -0,0 +1,103 @@
+; config options
+server:
+ target-fetch-policy: "0 0 0 0 0"
+
+stub-zone:
+ name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+
+stub-zone:
+ name: "example.com"
+ stub-addr: 1.2.3.4
+CONFIG_END
+
+SCENARIO_BEGIN Test scrubber to scrub NS record to the side of the query
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+; must be scrubbed
+www.burritolovers.com. IN A 10.20.30.40
+SECTION AUTHORITY
+example1234.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+mail.example.com. IN A
+SECTION ANSWER
+SECTION AUTHORITY
+; not pertinent to the query
+www.example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+STEP 20 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+mail.example.com. IN A
+ENTRY_END
+
+STEP 30 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+mail.example.com. IN A
+SECTION ANSWER
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/testdata_notimpl/iter_stub_noroot.rpl b/tests/integration/testdata_notimpl/iter_stub_noroot.rpl
new file mode 100644
index 0000000..f0740b6
--- /dev/null
+++ b/tests/integration/testdata_notimpl/iter_stub_noroot.rpl
@@ -0,0 +1,64 @@
+; config options
+server:
+ target-fetch-policy: "0 0 0 0 0"
+
+stub-zone:
+ name: "."
+ stub-addr: 81.187.81.187
+stub-zone:
+ name: "lp0.eu"
+ stub-addr: 81.2.80.65
+ stub-prime: no
+CONFIG_END
+
+SCENARIO_BEGIN Test resolve of stub zone without root prime.
+
+; this server does not respond. (for the root)
+RANGE_BEGIN 0 100
+ ADDRESS 81.187.81.187
+ENTRY_BEGIN
+MATCH
+ADJUST copy_id copy_query
+REPLY QR SERVFAIL
+SECTION QUESTION
+. IN NS
+ENTRY_END
+RANGE_END
+
+; lp0.eu server
+RANGE_BEGIN 0 100
+ ADDRESS 81.2.80.65
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+proxima.lp0.eu. IN A
+SECTION ANSWER
+proxima.lp0.eu. IN A 81.2.80.65
+SECTION AUTHORITY
+lp0.eu. IN NS proxima.lp0.eu.
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+proxima.lp0.eu. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+proxima.lp0.eu. IN A
+SECTION ANSWER
+proxima.lp0.eu. IN A 81.2.80.65
+;SECTION AUTHORITY
+;lp0.eu. IN NS proxima.lp0.eu.
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/testdata_notimpl/iter_stubfirst.rpl b/tests/integration/testdata_notimpl/iter_stubfirst.rpl
new file mode 100644
index 0000000..5f16679
--- /dev/null
+++ b/tests/integration/testdata_notimpl/iter_stubfirst.rpl
@@ -0,0 +1,157 @@
+; config options
+server:
+ target-fetch-policy: "0 0 0 0 0"
+
+stub-zone:
+ name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+
+stub-zone:
+ name: "example.com"
+ stub-addr: 1.2.3.6 # failing server
+ stub-first: yes
+
+CONFIG_END
+
+SCENARIO_BEGIN Test stub-first directive
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+; local authority (that fails a lot)
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.6
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA SERVFAIL
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+;example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+;ns.example.com. IN A 1.2.3.4
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA SERVFAIL
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+;www.example.com. IN A 10.20.30.50
+SECTION AUTHORITY
+;example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+;ns.example.com. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+;SECTION AUTHORITY
+;example.com. IN NS ns.example.com.
+;SECTION ADDITIONAL
+;ns.example.com. IN A 1.2.3.4
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/testdata_notimpl/iter_stublastresort.rpl b/tests/integration/testdata_notimpl/iter_stublastresort.rpl
new file mode 100644
index 0000000..040c9be
--- /dev/null
+++ b/tests/integration/testdata_notimpl/iter_stublastresort.rpl
@@ -0,0 +1,259 @@
+; config options
+server:
+ target-fetch-policy: "0 0 0 0 0"
+
+stub-zone:
+ name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+
+stub-zone:
+ name: "example.com"
+ stub-addr: 1.2.3.6
+ stub-prime: yes
+
+CONFIG_END
+
+SCENARIO_BEGIN Test stub with stub-prime and last resort fallback
+; the last resort fallback should not activate, as the
+; configured stub must be used for this data, or its primed data.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN A
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.com. IN A
+SECTION ANSWER
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.com. IN AAAA
+SECTION ANSWER
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+; the stub-prime server.
+; local authority (that fails a lot)
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.6
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.7
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA SERVFAIL
+SECTION QUESTION
+ns.example.com. IN A
+SECTION ANSWER
+;ns.example.com. IN A 1.2.3.7
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA SERVFAIL
+SECTION QUESTION
+ns.example.com. IN AAAA
+SECTION ANSWER
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA SERVFAIL
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+;www.example.com. IN A 10.20.30.70
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+RANGE_END
+
+; the primed server
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.7
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.8
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA
+SECTION QUESTION
+ns.example.com. IN A
+SECTION ANSWER
+ns.example.com. IN A 1.2.3.8
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA
+SECTION QUESTION
+ns.example.com. IN AAAA
+SECTION ANSWER
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA SERVFAIL
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+;www.example.com. IN A 10.20.30.80
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+RANGE_END
+
+; crap server that the primed server refers to.
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.8
+
+ENTRY_BEGIN
+MATCH opcode
+ADJUST copy_id copy_query
+REPLY QR SERVFAIL
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+ENTRY_END
+RANGE_END
+
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA SERVFAIL
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+;www.example.com. IN A 10.20.30.50
+;SECTION AUTHORITY
+;example.com. IN NS ns.example.com.
+;SECTION ADDITIONAL
+;ns.example.com. IN A 1.2.3.4
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/integration/testdata_notimpl/iter_timeout_ra_aaaa.rpl b/tests/integration/testdata_notimpl/iter_timeout_ra_aaaa.rpl
new file mode 100644
index 0000000..baa11c4
--- /dev/null
+++ b/tests/integration/testdata_notimpl/iter_timeout_ra_aaaa.rpl
@@ -0,0 +1,244 @@
+; config options
+server:
+ target-fetch-policy: "0 0 0 0 0"
+
+stub-zone:
+ name: "."
+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test iterator with timeouts on reclame AAAA dropping server
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+ ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns.example.net. IN A
+SECTION ANSWER
+ns.example.net. IN A 1.2.3.4
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns.example.net. IN AAAA
+SECTION ANSWER
+SECTION AUTHORITY
+. IN SOA a. b. 1 2 3 4 5
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+a.gtld-servers.net. IN AAAA
+SECTION ANSWER
+SECTION AUTHORITY
+. IN SOA a. b. 1 2 3 4 5
+ENTRY_END
+
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+ ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN A
+SECTION AUTHORITY
+example.com. 280 IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.net. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+; This server is REC_LAME
+RANGE_BEGIN 0 100
+ ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RA NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com. 280 IN NS ns.example.net.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR RA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. 10 IN A 10.20.30.40
+SECTION AUTHORITY
+example.com. 280 IN NS ns.example.net.
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+;SECTION AUTHORITY
+;example.com. IN NS ns.example.net.
+ENTRY_END
+
+; query for (dropped) AAAA record.
+STEP 20 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN AAAA
+ENTRY_END
+
+; the AAAA query times out.
+STEP 21 TIMEOUT
+STEP 22 TIMEOUT
+STEP 23 TIMEOUT
+STEP 24 TIMEOUT
+STEP 25 TIMEOUT
+
+; we get servfail, but the AAA arrives again (after the servfail times
+; out of the cache)
+STEP 30 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA SERVFAIL
+SECTION QUESTION
+www.example.com. IN AAAA
+ENTRY_END
+STEP 31 TIME_PASSES ELAPSE 6
+STEP 40 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN AAAA
+ENTRY_END
+
+; timeouts for AAAA keep happening.
+STEP 41 TIMEOUT
+STEP 42 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA SERVFAIL
+SECTION QUESTION
+www.example.com. IN AAAA
+ENTRY_END
+STEP 43 TIME_PASSES ELAPSE 12
+
+STEP 50 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN AAAA
+ENTRY_END
+; fallback queries
+STEP 51 TRAFFIC
+; and it fails, no parentside entries and so on.
+STEP 52 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA SERVFAIL
+SECTION QUESTION
+www.example.com. IN AAAA
+ENTRY_END
+STEP 53 TIME_PASSES ELAPSE 12
+
+STEP 60 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN AAAA
+ENTRY_END
+STEP 61 TIMEOUT
+STEP 62 TRAFFIC
+STEP 63 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA SERVFAIL
+SECTION QUESTION
+www.example.com. IN AAAA
+ENTRY_END
+
+STEP 70 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+STEP 72 TRAFFIC
+STEP 73 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 10.20.30.40
+;SECTION AUTHORITY
+;example.com. IN NS ns.example.net.
+ENTRY_END
+
+SCENARIO_END
diff --git a/tests/meson.build b/tests/meson.build
new file mode 100644
index 0000000..818169d
--- /dev/null
+++ b/tests/meson.build
@@ -0,0 +1,61 @@
+# tests
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+## unit tests
+build_unit_tests = false
+if get_option('unit_tests') != 'disabled'
+ message('--- unit_tests dependencies ---')
+ cmocka = dependency('cmocka', required: get_option('unit_tests') == 'enabled')
+ if cmocka.found()
+ build_unit_tests = true
+ subdir('unit')
+ endif
+ message('-------------------------------')
+endif
+
+build_extra_tests = get_option('extra_tests') == 'enabled'
+build_config_tests = get_option('config_tests') == 'enabled'
+if get_option('config_tests') == 'auto'
+ build_config_tests = build_extra_tests
+endif
+
+## config tests
+if build_config_tests
+ message('--- config_tests dependencies ---')
+ cqueues = run_command('luajit', '-l', 'cqueues', '-e', 'os.exit(0)', check: false) # luajit -l $(1) -e "os.exit(0)"
+ if cqueues.returncode() != 0
+ error('missing luajit package: cqueues')
+ endif
+ basexx = run_command('luajit', '-l', 'basexx', '-e', 'os.exit(0)', check: false) # luajit -l $(1) -e "os.exit(0)"
+ if basexx.returncode() != 0
+ error('missing luajit package: basexx')
+ endif
+ ffi = run_command('luajit', '-l', 'ffi', '-e', 'os.exit(0)', check: false) # luajit -l $(1) -e "os.exit(0)"
+ if ffi.returncode() != 0
+ error('missing luajit package: ffi')
+ endif
+ message('---------------------------------')
+
+ subdir('config')
+endif
+
+## extra tests
+if build_extra_tests
+ message('--- extra_tests dependencies ---')
+ python3 = find_program('python3')
+ py3_deps = []
+
+ subdir('pytests')
+ subdir('integration')
+ if build_dnstap
+ subdir('dnstap')
+ endif
+
+ foreach py3_dep : py3_deps
+ py3_import = run_command(python3, '-c', 'import @0@'.format(py3_dep[0]), check: false)
+ if py3_import.returncode() != 0
+ error('missing python3 dependency: @0@'.format(py3_dep[1]))
+ endif
+ endforeach
+ message('--------------------------------')
+endif
diff --git a/tests/packaging/README.rst b/tests/packaging/README.rst
new file mode 100644
index 0000000..997f666
--- /dev/null
+++ b/tests/packaging/README.rst
@@ -0,0 +1,87 @@
+.. SPDX-License-Identifier: GPL-3.0-or-later
+
+Packaging tests
+===============
+
+Packaging tests used pytest, docker and each directory with subdirectory *.packaging*
+is called as *component*.
+
+Run tests for all components:
+
+.. code-block::
+
+ pytest -r fEsxX tests/packaging
+
+List all components:
+
+.. code-block::
+
+ pytest tests/packaging --collect-only
+
+Run test for specific component (*doc/.packaging*):
+
+.. code-block::
+
+ pytest -r fEsxX tests/packaging -k test_collect[debian_10-doc/.packaging]
+
+.. note::
+
+ For debug add argument :code:`-s`.
+
+daemon/.packaging component
+---------------------------
+
+This is special component that is used by all others components.
+For each distribution and version are created two docker images with this component.
+One with building dependencies and one for running dependencies.
+*Build docker image* is tagged as :code:`kr-packaging-tests-<distro><version>-build`
+and *Run docker image* is tagged as :code:`kr-packaging-tests-<distro><version>-run`.
+
+Others components
+-----------------
+
+All others components are based on *daemon/.packaging* component (docker image).
+When component needs new building dependencies, new running dependencies
+or some scripts that change build or run phase (see `File structure of each component`_),
+new docker image is created.
+*Build docker image* is tagged as :code:`kr-packaging-tests-<distro><version>-<component>-build`
+and *Run docker image* is tagged as :code:`kr-packaging-tests-<distro><version>-<component>-run`.
+
+File structure of each component
+------------------------------------
+
+* <distro>
+ * <version>
+ * builddeps - list of build dependencies
+ * rundeps - list of runtime dependencies
+ * pre-build.sh - script called before build phase
+ * post-build.sh - script called after build phase
+ * pre-run.sh - script called before run phase
+ * post-run.sh - script called after run phase
+ * install.sh and build.sh - scripts to rewrite standard commands for building and installing knot-resolvers
+ * pre-test.sh - script called immediately before testing
+* test.config or test.sh - kresd config test or shell script (one of them must exists)
+
+Commands order to create docker image
+-------------------------------------
+
+For *build docker image*:
+
+#. run pre-build.sh
+#. install packages specified in the file *builddeps*
+#. run build.sh
+#. run install.sh
+#. run post-build.sh
+
+For *run docker image*:
+
+#. run pre-run.sh
+#. install packages specified in the file *rundeps*
+#. run pre-test.sh
+#. run test (:code:`kresd -c test.config` or :code:`test.sh`)
+#. run post-build.sh
+
+
+.. note::
+
+ knot-resolver builded in *build docker image* is automatically moved to *run docker image*.
diff --git a/tests/packaging/conftest.py b/tests/packaging/conftest.py
new file mode 100644
index 0000000..7279c15
--- /dev/null
+++ b/tests/packaging/conftest.py
@@ -0,0 +1,10 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+import pytest
+import os
+
+
+def pytest_configure():
+ pytest.KR_PYTESTS_DIR = os.path.dirname(os.path.realpath(__file__))
+ pytest.KR_ROOT_DIR = os.path.join(pytest.KR_PYTESTS_DIR, "..", "..")
+ pytest.KR_PREFIX = "kr-packaging-tests-"
diff --git a/tests/packaging/test_packaging.py b/tests/packaging/test_packaging.py
new file mode 100644
index 0000000..1a9bc41
--- /dev/null
+++ b/tests/packaging/test_packaging.py
@@ -0,0 +1,494 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+import os
+import pytest
+import docker
+import logging
+from pathlib import Path
+from abc import ABC, abstractmethod
+
+
+logging.basicConfig(level=logging.INFO)
+logger = logging.getLogger(__name__)
+logger.setLevel(logging.DEBUG)
+client = docker.from_env()
+
+
+class DockerCmdError(Exception):
+ """ Raised when shell command in Docker container failed """
+ pass
+
+
+class ContainerHandler():
+ def __init__(self, image):
+ self.img_id = image
+ self.container = None
+
+ def run(self):
+ self.container = client.containers.run(self.img_id, network_mode='host',
+ tty=True, detach=True)
+ logger.info('Run container ID={}'.format(self.container))
+
+ def stop(self):
+ self.container.kill()
+
+ def exec_cmd(self, cmd, workdir):
+ # workaround: When exec_run is called in GitLab CI/CD workdir argument doesn't work.
+ inter_cmd = ''
+ if workdir is not None:
+ inter_cmd = 'cd {}; '.format(workdir)
+
+ rcode, out = self.container.exec_run('/bin/sh -c \'' + inter_cmd + cmd + '\'')
+ if rcode != 0:
+ raise DockerCmdError(rcode, out)
+
+ def getFiles(self, output, path):
+ strm, stat = self.container.get_archive(path)
+ with open(output, 'wb') as ofile:
+ for data in strm:
+ ofile.write(data)
+
+
+class DockerImages(ABC):
+ def __init__(self, version):
+ self.version = version
+ self.module = None
+ self.distro = None
+ self.build_id = None
+ self.run_id = None
+
+ @abstractmethod
+ def cmd_pkgs_install(self):
+ raise NotImplementedError
+
+ @abstractmethod
+ def cmd_kresd_install(self):
+ raise NotImplementedError
+
+ @abstractmethod
+ def cmd_kresd_build(self):
+ raise NotImplementedError
+
+ def readDependencies(self, deps_file):
+ """Read dependencies from file"""
+ listf = None
+ try:
+ with open(deps_file, 'r') as f:
+ listf = f.read().splitlines()
+ except FileNotFoundError:
+ pass
+
+ return listf
+
+ def __genDockerFile(self, path, from_image=None):
+ """Generate Dockerfile for build image"""
+ if self.module is None:
+ raise AttributeError
+
+ if from_image is None:
+ if os.path.isfile(os.path.join(self.module, self.distro, 'docker-image-name')):
+ with open(os.path.join(self.module, self.distro, 'docker-image-name')) as f:
+ from_image = f.read()
+ else:
+ from_image = '{0}:{1}'.format(self.distro, self.version)
+
+ distro_dir = os.path.join(self.module, self.distro, self.version)
+
+ dockerf = open(os.path.join(path, 'Dockerfile-build'), 'w')
+
+ dockerf.write('FROM {}\n'.format(from_image))
+ dockerf.write('WORKDIR /root/kresd\n')
+ if self.module == 'daemon/.packaging':
+ dockerf.write('COPY . /root/kresd\n')
+ # when this file doesn't exists, tzdata needs user interaction
+ dockerf.write('RUN if [ ! -f /etc/localtime ];' +
+ 'then ln -fs /usr/share/zoneinfo/Europe/Prague /etc/localtime; fi\n')
+ if os.path.isfile(os.path.join(distro_dir, 'pre-build.sh')):
+ dockerf.write('RUN {}\n'.format(os.path.join(distro_dir, 'pre-build.sh')))
+ if os.path.isfile(os.path.join(distro_dir, 'builddeps')):
+ dockerf.write('RUN {0} {1}\n'.format(self.cmd_pkgs_install(),
+ ' '.join(self.readDependencies(os.path.join(distro_dir, 'builddeps')))))
+ if os.path.isfile(os.path.join(distro_dir, 'build.sh')):
+ dockerf.write('RUN {}\n'.format(os.path.join(distro_dir, 'build.sh')))
+ else:
+ dockerf.write('RUN {}\n'.format(self.cmd_kresd_build()))
+ if os.path.isfile(os.path.join(distro_dir, 'install.sh')):
+ dockerf.write('RUN {}\n'.format(os.path.join(distro_dir, 'install.sh')))
+ else:
+ dockerf.write('RUN {}\n'.format(self.cmd_kresd_install()))
+ if os.path.isfile(os.path.join(distro_dir, 'post-build.sh')):
+ dockerf.write('RUN {}\n'.format(os.path.join(distro_dir, 'post-build.sh')))
+
+ dockerf.close()
+
+ def __genDockerFile_run(self, path, build_id, from_image=None):
+ """Generate Dockerfile for run image"""
+ if self.module is None:
+ raise AttributeError
+
+ if from_image is None:
+ if os.path.isfile(os.path.join(self.module, self.distro, 'docker-image-name')):
+ with open(os.path.join(self.module, self.distro, 'docker-image-name')) as f:
+ from_image = f.read()
+ else:
+ from_image = '{0}:{1}'.format(self.distro, self.version)
+
+ distro_dir = os.path.join(self.module, self.distro, self.version)
+
+ dockerf = open(os.path.join(path, 'Dockerfile-run'), 'w')
+
+ dockerf.write('FROM {}\n'.format(from_image))
+ dockerf.write('COPY --from={} /root/kresd /root/kresd\n'.format(build_id))
+ dockerf.write('WORKDIR /root/kresd\n')
+ if os.path.isfile(os.path.join(distro_dir, 'pre-run.sh')):
+ dockerf.write('RUN {}\n'.format(os.path.join(distro_dir, 'pre-run.sh')))
+ if os.path.isfile(os.path.join(distro_dir, 'rundeps')):
+ dockerf.write('RUN {0} {1}\n'.format(self.cmd_pkgs_install(),
+ ' '.join(self.readDependencies(os.path.join(distro_dir, 'rundeps')))))
+ if os.path.isfile(os.path.join(distro_dir, 'pre-test.sh')):
+ dockerf.write('RUN {}\n'.format(os.path.join(distro_dir, 'pre-test.sh')))
+
+ dockerf.close()
+
+ def build_printing_errors(self, path, dockerfile, network_mode, tag, rm):
+ try:
+ return client.images.build(path=path, dockerfile=dockerfile,
+ network_mode=network_mode, tag=tag, rm=rm)
+ except docker.errors.BuildError as e:
+ iterable = iter(e.build_log)
+ while True:
+ try:
+ item = next(iterable)
+ if item['stream']:
+ for l in item['stream'].splitlines():
+ stripped = l.strip()
+ if stripped:
+ logging.error(stripped)
+ except StopIteration:
+ break
+ raise e
+
+ def build(self, tmpdir, tag="", from_image=None):
+ self.__genDockerFile(tmpdir, from_image=from_image)
+
+ logger.debug('tmpdir={}'.format(tmpdir))
+ logger.debug('datadir={}'.format(pytest.KR_ROOT_DIR))
+ logger.debug('tag={}'.format(tag))
+ image = self.build_printing_errors(path=str(pytest.KR_ROOT_DIR),
+ dockerfile=os.path.join(tmpdir, 'Dockerfile-build'),
+ network_mode='host', tag=tag, rm=True)
+ logger.info('"Build image" ID={} created'.format(image[0].short_id))
+ self.build_id = image[0].short_id
+ return self.build_id
+
+ def build_run(self, tmpdir, build_id, from_image=None, tag=""):
+ self.__genDockerFile_run(tmpdir, build_id, from_image=from_image)
+
+ logger.debug('tmpdir={}'.format(tmpdir))
+ logger.debug('datadir={}'.format(tmpdir))
+ logger.debug('tag={}'.format(tag))
+ image = self.build_printing_errors(path=str(tmpdir),
+ dockerfile=os.path.join(tmpdir, 'Dockerfile-run'),
+ network_mode='host', tag=tag, rm=True)
+ logger.info('"Run image" ID={} created'.format(image[0].short_id))
+ self.run_id = image[0].short_id
+ return self.run_id
+
+
+class DebianImage(DockerImages):
+ def __init__(self, version):
+ super().__init__(version)
+ self.distro = 'debian'
+
+ def cmd_pkgs_install(self):
+ return 'apt-get install -y '
+
+ def cmd_kresd_install(self):
+ return 'ninja -C build_packaging install >/dev/null'
+
+ def cmd_kresd_build(self):
+ return """\\
+ [ -d /root/kresd/build_packaging ] && rm -rf /root/kresd/build_packaging/; \\
+ CFLAGS=\"$CFLAGS -Wall -pedantic -fno-omit-frame-pointer\"; \\
+ LDFLAGS=\"$LDFLAGS -Wl,--as-needed\"; \\
+ meson build_packaging \\
+ --buildtype=plain \\
+ --prefix=/root/kresd/install_packaging \\
+ --libdir=lib \\
+ --default-library=static \\
+ -Dsystemd_files=enabled \\
+ -Dclient=enabled \\
+ -Dkeyfile_default=/usr/share/dns/root.key \\
+ -Droot_hints=/usr/share/dns/root.hints \\
+ -Dinstall_kresd_conf=enabled \\
+ -Dunit_tests=enabled \\
+ -Dc_args=\"${CFLAGS}\" \\
+ -Dc_link_args=\"${LDFLAGS}\"; \\
+ ninja -C build_packaging
+ """
+
+
+class UbuntuImage(DebianImage):
+ def __init__(self, version):
+ super().__init__(version)
+ self.distro = 'ubuntu'
+
+
+class CentosImage(DockerImages):
+ def __init__(self, version):
+ super().__init__(version)
+ self.distro = 'centos'
+
+ def cmd_pkgs_install(self):
+ return "yum install -y "
+
+ def cmd_kresd_install(self):
+ return 'ninja-build -C build_packaging install'
+
+ def cmd_kresd_build(self):
+ return """\\
+ [ -d /root/kresd/build_packaging ] && rm -rf /root/kresd/build_packaging/; \\
+ CFLAGS=\"$CFLAGS -Wall -pedantic -fno-omit-frame-pointer\"; \\
+ LDFLAGS=\"$LDFLAGS -Wl,--as-needed\"; \\
+ meson build_packaging \\
+ --buildtype=plain \\
+ --prefix=/root/kresd/install_packaging \\
+ --sbindir=sbin \\
+ --libdir=lib \\
+ --includedir=include \\
+ --sysconfdir=etc \\
+ --default-library=static \\
+ -Dsystemd_files=enabled \\
+ -Dclient=enabled \\
+ -Dunit_tests=enabled \\
+ -Dmanaged_ta=enabled \\
+ -Dkeyfile_default=/root/kresd/install_packaging/var/lib/knot-resolver/root.keys \\
+ -Dinstall_root_keys=enabled \\
+ -Dinstall_kresd_conf=enabled; \\
+ ninja-build -C build_packaging
+ """
+
+
+class FedoraImage(DockerImages):
+ def __init__(self, version):
+ super().__init__(version)
+ self.distro = 'fedora'
+
+ def cmd_pkgs_install(self):
+ return "dnf install -y "
+
+ def cmd_kresd_install(self):
+ return 'ninja -C build_packaging install >/dev/null'
+
+ def cmd_kresd_build(self):
+ return """\\
+ [ -d /root/kresd/build_packaging ] && rm -rf /root/kresd/build_packaging/; \\
+ CFLAGS=\"$CFLAGS -Wall -pedantic -fno-omit-frame-pointer\"; \\
+ LDFLAGS=\"$LDFLAGS -Wl,--as-needed\"; \\
+ meson build_packaging \\
+ --buildtype=plain \\
+ --prefix=/root/kresd/install_packaging \\
+ --sbindir=sbin \\
+ --libdir=lib \\
+ --includedir=include \\
+ --sysconfdir=etc \\
+ --default-library=static \\
+ -Dsystemd_files=enabled \\
+ -Dclient=enabled \\
+ -Dunit_tests=enabled \\
+ -Dmanaged_ta=enabled \\
+ -Dkeyfile_default=/root/kresd/install_packaging/var/lib/knot-resolver/root.keys \\
+ -Dinstall_root_keys=enabled \\
+ -Dinstall_kresd_conf=enabled; \\
+ ninja -C build_packaging
+ """
+
+
+class LeapImage(FedoraImage):
+ def __init__(self, version):
+ super().__init__(version)
+ self.distro = 'leap'
+
+ def cmd_pkgs_install(self):
+ return "zypper install -y "
+
+
+def create_distro_image(name, version):
+ img = None
+
+ if (name == 'debian'):
+ img = DebianImage(version)
+ elif (name == 'ubuntu'):
+ img = UbuntuImage(version)
+ elif (name == 'centos'):
+ img = CentosImage(version)
+ elif (name == 'fedora'):
+ img = FedoraImage(version)
+ elif (name == 'leap'):
+ img = LeapImage(version)
+ else:
+ img = None
+
+ return img
+
+
+def list_dirs(path, exclude=None):
+ """return all 'packaging' directories with full path"""
+ filtered_dirs = []
+
+ for rootpath, dirs, _ in os.walk(path):
+
+ if (os.path.basename(rootpath) == '.packaging'):
+ fdir = os.path.relpath(rootpath, path)
+ if exclude is not None:
+ if fdir not in exclude:
+ filtered_dirs.append(fdir)
+ else:
+ filtered_dirs.append(fdir)
+
+ return filtered_dirs
+
+
+def list_tests_dirs():
+ """return all 'packaging' directories"""
+ return list_dirs(pytest.KR_ROOT_DIR)
+
+
+def list_distro_vers(distro_root):
+ """
+ return list of { 'name': distro_name, 'version': distro_version)
+ pairs found in distro_root
+ """
+ # transform list of paths like TOP/debian/10 into (debian, 10)
+ dist_ver = [{'name': p.parts[-2], 'version': p.parts[-1]} for p
+ in Path(distro_root).glob('*/*') if p.is_dir()]
+
+ return list(dist_ver)
+
+
+MODULES = list_tests_dirs()
+DISTROS = list_distro_vers(os.path.join(pytest.KR_ROOT_DIR, 'daemon/.packaging'))
+DISTROS_NAMES = ['{0}_{1}'.format(distro['name'], distro['version']) for distro in DISTROS]
+
+
+@pytest.fixture(scope='session', params=DISTROS, ids=DISTROS_NAMES)
+def buildenv(request, tmpdir_factory):
+ distro = request.param
+
+ logger.debug('Creating main images for "{0} {1}"'.format(distro['name'], distro['version']))
+ img = create_distro_image(distro['name'], distro['version'])
+ if img is None:
+ logger.warning('Unknown distro {}'.format(distro['name']))
+ else:
+ img.module = 'daemon/.packaging'
+ tmpdir = tmpdir_factory.mktemp(distro['name']+distro['version'])
+ img.build(tmpdir, tag=pytest.KR_PREFIX+distro['name']+distro['version']+'-build')
+ img.build_run(tmpdir, img.build_id,
+ tag=pytest.KR_PREFIX+distro['name']+distro['version']+'-run')
+
+ yield img
+# client.images.remove(img.run_id)
+# client.images.remove(img.build_id)
+
+
+@pytest.mark.parametrize('module', MODULES)
+def test_collect(module, buildenv, tmp_path):
+ logger.info(' ### Run test {} ###'.format(module))
+
+ if buildenv is None:
+ logger.error('Distro "{0} {1}" isn\'t implemented'.format(buildenv.distro,
+ buildenv.version))
+ assert False
+
+ rcode = None
+ buildmod = None
+ module_dir = os.path.join(pytest.KR_ROOT_DIR, module)
+ distro_dir = os.path.join(module_dir, buildenv.distro, buildenv.version)
+
+ if os.path.isfile(os.path.join(distro_dir, 'NOTSUPPORTED')):
+ pytest.skip('Unsupported linux distribution ({0} {1}:{2})'.format(buildenv.distro, buildenv.version, module))
+
+ try:
+ if module == 'daemon/.packaging':
+ # use main "run image" without changes
+ logging.info('Use main "run image"')
+ ch = ContainerHandler(buildenv.run_id)
+ ch.run()
+ elif buildenv is not None:
+ if os.path.isfile(os.path.join(distro_dir, 'pre-build.sh')) \
+ or os.path.isfile(os.path.join(distro_dir, 'builddeps')):
+ # create module specific "build image"
+ logger.info('Create new "build image"')
+ buildmod = create_distro_image(buildenv.distro, buildenv.version)
+ buildmod.module = module
+ buildmod.build(tmp_path, from_image=buildenv.build_id,
+ tag=pytest.KR_PREFIX+buildmod.distro+buildmod.version+'-' +
+ module.replace('/.packaging', '')+'-build')
+
+ if buildmod is not None:
+ # new build image was made, create new module specific "run image"
+ logger.info('Create module specific "run image" from Dockerfile')
+ buildmod.build_run(tmp_path, buildmod.build_id,
+ tag=pytest.KR_PREFIX+buildmod.distro+buildmod.version+'-' +
+ module.replace('/.packaging', '')+'-run', from_image=buildenv.run_id)
+ ch = ContainerHandler(buildmod.run_id)
+ ch.run()
+ elif os.path.isfile(os.path.join(distro_dir, 'pre-run.sh')) \
+ or os.path.isfile(os.path.join(distro_dir, 'rundeps')):
+ # use main "run image" and apply module specific changes
+ logger.info('Apply module specific changes to "run image"')
+ buildmod = buildenv
+ ch = ContainerHandler(buildmod.run_id)
+ ch.run()
+
+ if os.path.isfile(os.path.join(distro_dir, 'pre-run.sh')):
+ ch.exec_cmd(os.path.join(module, buildenv.distro, buildenv.version,
+ 'pre-run.sh'), '/root/kresd/')
+
+ if os.path.isfile(os.path.join(distro_dir, 'rundeps')):
+ logger.debug(buildmod.cmd_pkgs_install() + ' '.join(
+ buildmod.readDependencies(os.path.join(distro_dir, 'rundeps'))))
+ ch.exec_cmd(buildmod.cmd_pkgs_install() + ' '.join(
+ buildmod.readDependencies(os.path.join(distro_dir, 'rundeps'))),
+ '/root/kresd/')
+
+ if os.path.isfile(os.path.join(distro_dir, 'pre-test.sh')):
+ ch.exec_cmd(os.path.join(module, buildenv.distro, buildenv.version,
+ 'pre-test.sh'), '/root/kresd/')
+ else:
+ # use main "run image" without changes
+ logging.info('Use main "run image"')
+ ch = ContainerHandler(buildenv.run_id)
+ ch.run()
+
+ # run test
+ if os.path.isfile(os.path.join(module_dir, 'test.config')):
+ ch.exec_cmd('/root/kresd/install_packaging/sbin/kresd -n -c ' + os.path.join('..',
+ module, 'test.config'), '/root/kresd/install_packaging/')
+ elif os.path.isfile(os.path.join(module_dir, 'test.sh')):
+ ch.exec_cmd(os.path.join('..', module, 'test.sh'),
+ '/root/kresd/install_packaging/')
+ else:
+ ch.stop()
+ ch.container.remove()
+ logger.error('Test file (test.config or test.sh) not found')
+ assert False
+
+ rcode = 0
+
+ if os.path.isfile(os.path.join(distro_dir, 'post-run.sh')):
+ ch.exec_cmd(os.path.join(module, buildenv.distro, buildenv.version, 'post-run.sh'),
+ '/root/kresd/')
+
+ except DockerCmdError as err:
+ rcode, out = err.args
+ logger.debug('rcode: {}'.format(rcode))
+ logger.error(out.decode('utf-8'))
+ finally:
+ ch.stop()
+ ch.container.remove()
+ if buildmod is not None and buildmod is not buildenv:
+ client.images.remove(buildmod.run_id)
+ client.images.remove(buildmod.build_id)
+
+ assert(rcode == 0)
diff --git a/tests/pytests/README.rst b/tests/pytests/README.rst
new file mode 100644
index 0000000..173dc40
--- /dev/null
+++ b/tests/pytests/README.rst
@@ -0,0 +1,56 @@
+.. SPDX-License-Identifier: GPL-3.0-or-later
+
+Python client tests for kresd
+=============================
+
+The tests run `/usr/bin/env kresd` (can be modified with `$PATH`) with custom config
+and execute client-side testing, such as TCP / TLS connection management.
+
+Requirements
+------------
+
+- pip3 install -r requirements.txt
+
+Executing tests
+---------------
+
+Tests can be executed with the pytest framework.
+
+.. code-block:: bash
+
+ $ pytest-3 # sequential, all tests (with exception of few special tests)
+ $ pytest-3 test_conn_mgmt.py::test_ignore_garbage # specific test only
+ $ pytest-3 --html pytests.html --self-contained-html # html report
+
+It's highly recommended to run these tests in parallel, since lot of them
+wait for kresd timeout. This can be done with `python-xdist`:
+
+.. code-block:: bash
+
+ $ pytest-3 -n 24 # parallel with 24 jobs
+
+Each test spawns an independent kresd instance, so test failures shouldn't affect
+each other.
+
+Some tests are omitted from automatic test collection by default, due to their
+resource constraints. These typically have to be executed separately by providing
+the path to test file directly.
+
+.. code-block:: bash
+
+ $ pytest-3 conn_flood.py
+
+Note: some tests may fail without an internet connection.
+
+Developer notes
+---------------
+
+Typically, each test requires a setup of kresd, and a connected socket to run tests on.
+The framework provides a few useful pytest fixtures to simplify this process:
+
+- `kresd_sock` provides a connected socket to a test-specific, running kresd instance.
+ It expands to 4 values (tests) - IPv4 TCP, IPv6 TCP, IPv4 TLS, IPv6 TLS sockets
+- `make_kresd_sock` is similar to `kresd_sock`, except it's a factory function that
+ produces a new connected socket (of the same type) on each call
+- `kresd`, `kresd_tt` are all Kresd instances, already running
+ and initialized with config (with no / valid TLS certificates)
diff --git a/tests/pytests/certs/tt-certgen-expired.sh b/tests/pytests/certs/tt-certgen-expired.sh
new file mode 100755
index 0000000..23a6978
--- /dev/null
+++ b/tests/pytests/certs/tt-certgen-expired.sh
@@ -0,0 +1,19 @@
+# !/bin/bash
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+if [ ! -d ./demoCA ]; then
+ mkdir ./demoCA
+fi
+if [ ! -d ./demoCA/newcerts ]; then
+ mkdir ./demoCA/newcerts
+fi
+touch ./demoCA/index.txt
+touch ./demoCA/index.txt.attr
+if [ ! -f ./demoCA/serial ]; then
+ echo 01 > ./demoCA/serial
+fi
+
+openssl genrsa -out tt-expired.key.pem 2048
+openssl req -config tt.conf -new -key tt-expired.key.pem -out tt-expired.csr.pem
+openssl ca -config tt.conf -selfsign -keyfile tt-expired.key.pem -out tt-expired.cert.pem -in tt-expired.csr.pem -startdate 19700101000000Z -enddate 19700101000000Z
+
diff --git a/tests/pytests/certs/tt-certgen.sh b/tests/pytests/certs/tt-certgen.sh
new file mode 100755
index 0000000..9414475
--- /dev/null
+++ b/tests/pytests/certs/tt-certgen.sh
@@ -0,0 +1,5 @@
+# !/bin/sh
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+openssl req -config tt.conf -new -x509 -newkey rsa:2048 -nodes -keyout tt.key.pem -sha256 -out tt.cert.pem -days 20000
+
diff --git a/tests/pytests/certs/tt-expired.cert.pem b/tests/pytests/certs/tt-expired.cert.pem
new file mode 100644
index 0000000..c9f8c09
--- /dev/null
+++ b/tests/pytests/certs/tt-expired.cert.pem
@@ -0,0 +1,80 @@
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 1 (0x1)
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: C=CZ, ST=PRAGUE, CN=transport-test-server.com
+ Validity
+ Not Before: Jan 1 00:00:00 1970 GMT
+ Not After : Jan 1 00:00:00 1970 GMT
+ Subject: C=CZ, ST=PRAGUE, CN=transport-test-server.com
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:bf:6b:1a:11:47:01:ac:eb:5c:2d:cf:ce:6a:a4:
+ 00:ce:2f:d1:25:03:5f:06:38:02:92:24:18:92:2a:
+ 69:19:b2:2b:a3:4f:f7:79:de:35:c3:f5:72:37:83:
+ 44:93:f9:76:fc:89:29:32:9c:0d:4b:95:7d:d1:5d:
+ 40:e9:ba:49:50:7d:c6:0a:c8:1e:e7:90:1e:37:7c:
+ 0b:23:a3:e3:bc:c9:53:81:de:d6:5f:cb:b2:3d:36:
+ ac:59:b0:33:91:8f:0c:5f:10:20:70:bf:a3:22:b3:
+ 98:ac:d4:7a:ea:67:b8:b1:8c:cf:e5:fe:8f:a0:a5:
+ 02:ad:6d:ce:f1:62:ab:dc:5d:96:9c:4f:95:47:d5:
+ 82:b7:b3:e3:87:4c:8d:38:85:2a:24:9d:7f:c7:a4:
+ 0e:bd:8a:2d:6b:d2:d4:e8:78:62:1b:aa:25:5f:5a:
+ 64:e5:76:23:ae:11:03:9a:5c:ed:a2:ba:51:ec:b1:
+ f3:ae:ba:5c:eb:dd:49:63:ca:c7:af:0c:16:1d:94:
+ 95:3a:ce:2c:8f:e2:94:7f:1f:a1:76:e2:9f:d1:41:
+ 31:f0:68:e5:ae:df:d0:75:a0:34:f5:25:93:85:b3:
+ 25:50:42:6c:00:c0:fe:3b:e0:fb:00:de:75:33:86:
+ 6a:21:35:14:9d:7f:4a:af:f7:15:f2:d7:bb:2f:de:
+ df:ab
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints:
+ CA:FALSE
+ Netscape Comment:
+ OpenSSL Generated Certificate
+ X509v3 Subject Key Identifier:
+ B3:42:0A:9A:00:19:CB:CB:24:A0:02:45:1E:8A:B0:54:CB:9F:55:FE
+ X509v3 Authority Key Identifier:
+ keyid:B3:42:0A:9A:00:19:CB:CB:24:A0:02:45:1E:8A:B0:54:CB:9F:55:FE
+
+ Signature Algorithm: sha256WithRSAEncryption
+ 32:9a:05:e3:6f:ae:ee:b1:a2:12:0a:9f:0a:e7:78:26:df:90:
+ fb:84:60:ae:13:fc:ff:fd:42:84:23:14:c3:2e:e2:a9:df:4b:
+ 5c:2f:5b:0e:3d:f9:5a:56:50:13:bc:89:1a:08:70:dd:6c:6c:
+ e8:ae:cf:22:39:92:f2:3b:40:03:8f:4e:bc:54:88:6b:fd:8c:
+ b6:eb:30:90:21:db:fc:4e:5c:7e:12:75:e2:52:76:df:19:0f:
+ 30:49:1e:15:bc:ba:6a:e6:f7:af:93:ad:e4:36:da:47:47:a6:
+ 88:b0:ae:46:1e:91:e1:d6:b1:5e:a4:f0:68:02:81:57:86:5d:
+ 17:d1:6c:7e:7a:9f:5e:0d:fc:10:e7:7a:1a:b5:f9:4b:1d:78:
+ a4:9a:9d:d7:c2:64:c3:52:28:7f:a1:b7:25:d7:13:3f:09:7f:
+ f2:fd:dd:c6:91:eb:9b:51:80:e2:36:cb:9f:5b:4e:47:eb:77:
+ d3:cc:8b:18:b5:0b:97:a2:53:8e:fb:9b:94:7d:57:21:32:c6:
+ f3:67:93:a4:9b:eb:46:b7:cd:08:43:99:dd:c1:c3:51:b9:19:
+ ef:92:77:1c:84:67:80:67:95:ba:00:75:3d:7b:8b:ff:24:30:
+ f1:fa:6d:da:31:9d:cf:06:da:5d:04:07:14:45:8c:6b:e7:21:
+ 31:ec:7b:23
+-----BEGIN CERTIFICATE-----
+MIIDfjCCAmagAwIBAgIBATANBgkqhkiG9w0BAQsFADBCMQswCQYDVQQGEwJDWjEP
+MA0GA1UECAwGUFJBR1VFMSIwIAYDVQQDDBl0cmFuc3BvcnQtdGVzdC1zZXJ2ZXIu
+Y29tMCIYDzE5NzAwMTAxMDAwMDAwWhgPMTk3MDAxMDEwMDAwMDBaMEIxCzAJBgNV
+BAYTAkNaMQ8wDQYDVQQIDAZQUkFHVUUxIjAgBgNVBAMMGXRyYW5zcG9ydC10ZXN0
+LXNlcnZlci5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC/axoR
+RwGs61wtz85qpADOL9ElA18GOAKSJBiSKmkZsiujT/d53jXD9XI3g0ST+Xb8iSky
+nA1LlX3RXUDpuklQfcYKyB7nkB43fAsjo+O8yVOB3tZfy7I9NqxZsDORjwxfECBw
+v6Mis5is1HrqZ7ixjM/l/o+gpQKtbc7xYqvcXZacT5VH1YK3s+OHTI04hSoknX/H
+pA69ii1r0tToeGIbqiVfWmTldiOuEQOaXO2iulHssfOuulzr3UljysevDBYdlJU6
+ziyP4pR/H6F24p/RQTHwaOWu39B1oDT1JZOFsyVQQmwAwP474PsA3nUzhmohNRSd
+f0qv9xXy17sv3t+rAgMBAAGjezB5MAkGA1UdEwQCMAAwLAYJYIZIAYb4QgENBB8W
+HU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQWBBSzQgqaABnL
+yySgAkUeirBUy59V/jAfBgNVHSMEGDAWgBSzQgqaABnLyySgAkUeirBUy59V/jAN
+BgkqhkiG9w0BAQsFAAOCAQEAMpoF42+u7rGiEgqfCud4Jt+Q+4RgrhP8//1ChCMU
+wy7iqd9LXC9bDj35WlZQE7yJGghw3Wxs6K7PIjmS8jtAA49OvFSIa/2MtuswkCHb
+/E5cfhJ14lJ23xkPMEkeFby6aub3r5Ot5DbaR0emiLCuRh6R4daxXqTwaAKBV4Zd
+F9FsfnqfXg38EOd6GrX5Sx14pJqd18Jkw1Iof6G3JdcTPwl/8v3dxpHrm1GA4jbL
+n1tOR+t308yLGLULl6JTjvublH1XITLG82eTpJvrRrfNCEOZ3cHDUbkZ75J3HIRn
+gGeVugB1PXuL/yQw8fpt2jGdzwbaXQQHFEWMa+chMex7Iw==
+-----END CERTIFICATE-----
diff --git a/tests/pytests/certs/tt-expired.key.pem b/tests/pytests/certs/tt-expired.key.pem
new file mode 100644
index 0000000..ca2988c
--- /dev/null
+++ b/tests/pytests/certs/tt-expired.key.pem
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEogIBAAKCAQEAv2saEUcBrOtcLc/OaqQAzi/RJQNfBjgCkiQYkippGbIro0/3
+ed41w/VyN4NEk/l2/IkpMpwNS5V90V1A6bpJUH3GCsge55AeN3wLI6PjvMlTgd7W
+X8uyPTasWbAzkY8MXxAgcL+jIrOYrNR66me4sYzP5f6PoKUCrW3O8WKr3F2WnE+V
+R9WCt7Pjh0yNOIUqJJ1/x6QOvYota9LU6HhiG6olX1pk5XYjrhEDmlztorpR7LHz
+rrpc691JY8rHrwwWHZSVOs4sj+KUfx+hduKf0UEx8Gjlrt/QdaA09SWThbMlUEJs
+AMD+O+D7AN51M4ZqITUUnX9Kr/cV8te7L97fqwIDAQABAoIBAEA4ytIpJKLDhHXK
+VtLom2ySFnV4oBUSDarCeYvwtrpsUL/GQJ2etCM+4kdFv2h2NjmcOzpDqSJG0aPA
+ydqhKZ/b0uojIltGuxyafZJDllDsqxvTi9EwImjvQvwEZgjcGaZ7Xqb1ZOJrpzm1
+QFgM3KaVO9tKgR3Avxk40kmidU7FctFi5IELwnH/RR1OHvJbxOE4+i0LlDx0QzhX
+QHtnvHLqLLdqsFk8KvuVuVj1FwqJ6cSL0JrAdt7dnGmXBo4PDqT8Hj0AjM+CcNrV
+1D6Li9xr4y55EZUK2qU/FVDC3LqlYQy5mBfasJAXPQG4RgSVFxJ929HC7gi8vMCO
+UMeLniECgYEA6gBoRwzQ5pJUXfZGW41lJt08utfycGZm7VrA81r0x0F+DcuZ2t6J
+kB9Wnp/MNpB4DJLbl7oM2OlFOO3cw0n3VaFpNMPHVHzNbyi1hp94AIIeDz/sxfUI
+Lx7ynAQSPPQzDRfVJesT8waBdweA71TBOlrFQ2Cp7O4Qf+p0akQSv3cCgYEA0Wnd
+1Gbierv2m6Jnblg+brTMQwbRsOAM2n0V4Gd2kRaLSYd23ebshvx8xTWipRlrb5vP
+UEh+LkfuscqaJDCrikasht9z5FJtfIzHKgTrLSoR3MJRjrnuLJWTQUwSqzd0UNN6
+HigV6p+CqesNnELErak53IMfmkHAhTSkII8R9m0CgYBRY+DhTaDfgegcYouoTm7v
+bKYx6uillciZKCbSvkFDiREaJUYXba31ViEfvT8ff3JyFSaSCKFtVP3BxmIx/ukr
+fKAGPU54oYwm7Mbu00q/CoMAFOD7HbZCBYanI3dggiO7mx2FOdXPguTHDPIYzKcE
+8AuK2vVftpJAm8DwMUtAEwKBgH/eRc5ZGDdbKGS10LQm+9A7Y3IV6to2pIKQ2FfS
+tSo4espmBeXPCGQQLdt5OZvYHqril77s1OdLkutKy74HXecr6lLchHZJAoOHrmDw
+6e0FAC0tFgGxdEYS+vxnCAs17DciOjHJxkAiL/WzCfd9KXzklOkZw6U8OuLbVtBu
+q8gtAoGAbl03XZm+SHrO7XjHK/Fe5YD13cOirg48htvjbpqEDZNQr3l0eVnEj074
+IopDa/wUFlaaqPZ/DVFctqSocyskWIP4u9HfmsNBHjK5zQlge7B1fNVao++YKund
+qnVnXjWQuF2aL8k2geFxdSKmHTF4/N1qEyeyR+tMaFpGfMZOuM8=
+-----END RSA PRIVATE KEY-----
diff --git a/tests/pytests/certs/tt.cert.pem b/tests/pytests/certs/tt.cert.pem
new file mode 100644
index 0000000..2ea4898
--- /dev/null
+++ b/tests/pytests/certs/tt.cert.pem
@@ -0,0 +1,22 @@
+-----BEGIN CERTIFICATE-----
+MIIDkTCCAnmgAwIBAgIJAP/KybHquuyUMA0GCSqGSIb3DQEBCwUAMEIxCzAJBgNV
+BAYTAkNaMQ8wDQYDVQQIDAZQUkFHVUUxIjAgBgNVBAMMGXRyYW5zcG9ydC10ZXN0
+LXNlcnZlci5jb20wIBcNMTgwNzE4MTAwODIzWhgPMjA3MzA0MjAxMDA4MjNaMEIx
+CzAJBgNVBAYTAkNaMQ8wDQYDVQQIDAZQUkFHVUUxIjAgBgNVBAMMGXRyYW5zcG9y
+dC10ZXN0LXNlcnZlci5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
+AQDRAQDAX6+lFKurvm7fgQqm8WyYzT/wxfPJjsVQGe87OlH1KFzVfzYzgEt0RMlM
+eZgipREBZB2zK+WFM5RBHWYAwlI5PKt7EAGn8q1Zm4z+M9Uom3/Hy3bZ9q+AJwjk
+odpHYuFyWJqHIQBqaQ3SFyJwdZ/GsuzEUfWuIl74oyyMAeykTKFGdaVuIlLC3fKm
+8UCnfk99i/LEXUwRcmOV0uaG7deN5ITDDCFdb615yVjLkMhGY/jHK7uuxATOopEk
+4vThQ1aQjSkHwluaqFUW6Zl4QF8WOAufoWQPFZ8XxmUYEIG/sMvLv6dol7ltjEbC
+bfyzlS+9Qbnq6MfhTZF/4jAPAgMBAAGjgYcwgYQwHQYDVR0OBBYEFBNiUgCiKw4b
+CFNKaEkqhkNSer7wMB8GA1UdIwQYMBaAFBNiUgCiKw4bCFNKaEkqhkNSer7wMA8G
+A1UdEwEB/wQFMAMBAf8wJAYDVR0RBB0wG4IZdHJhbnNwb3J0LXRlc3Qtc2VydmVy
+LmNvbTALBgNVHQ8EBAMCAaYwDQYJKoZIhvcNAQELBQADggEBACz1ZQ8XkGobhTcA
+hkSTSw0ko6qwVuJJD5ue3SUcWLATsskohTJmN6bde3IMDRyQvLJAlMdG2p1qMbtA
+OTbnQJTT7oDLaW8w2D+eO5oWTJvxLpl6TxbIfJN/8ITB1ltOCxTU9cVNbd2eh8sj
+l3R4etg9djYRrqtNxCQZOYSwvhHw2MefnwjGVuJEu6JYOn3IE8Jqsh/LI59C87nE
+MetZrXlzC6kSAFfRYgQET9RhBobMU9yFR8zGVHDFoxqNQs2lYKPz/3rFPetL2rjT
+cFwzxkxDdwn+RNisBc1LMfIg7pvSMFR6sAnpjeRHN0Uoem1jj2qtzjbFENDuyQ4/
+HSi4UcE=
+-----END CERTIFICATE-----
diff --git a/tests/pytests/certs/tt.conf b/tests/pytests/certs/tt.conf
new file mode 100644
index 0000000..f011e5a
--- /dev/null
+++ b/tests/pytests/certs/tt.conf
@@ -0,0 +1,353 @@
+# SPDX-License-Identifier: CC0-1.0
+# OpenSSL example configuration file.
+# This is mostly being used for generation of certificate requests.
+#
+
+# This definition stops the following lines choking if HOME isn't
+# defined.
+HOME = .
+RANDFILE = $ENV::HOME/.rnd
+
+# Extra OBJECT IDENTIFIER info:
+#oid_file = $ENV::HOME/.oid
+oid_section = new_oids
+
+# To use this configuration file with the "-extfile" option of the
+# "openssl x509" utility, name here the section containing the
+# X.509v3 extensions to use:
+# extensions =
+# (Alternatively, use a configuration file that has only
+# X.509v3 extensions in its main [= default] section.)
+
+[ new_oids ]
+
+# We can add new OIDs in here for use by 'ca', 'req' and 'ts'.
+# Add a simple OID like this:
+# testoid1=1.2.3.4
+# Or use config file substitution like this:
+# testoid2=${testoid1}.5.6
+
+# Policies used by the TSA examples.
+tsa_policy1 = 1.2.3.4.1
+tsa_policy2 = 1.2.3.4.5.6
+tsa_policy3 = 1.2.3.4.5.7
+
+####################################################################
+[ ca ]
+default_ca = CA_default # The default ca section
+
+####################################################################
+[ CA_default ]
+
+dir = ./demoCA # Where everything is kept
+certs = $dir/certs # Where the issued certs are kept
+crl_dir = $dir/crl # Where the issued crl are kept
+database = $dir/index.txt # database index file.
+#unique_subject = no # Set to 'no' to allow creation of
+ # several certs with same subject.
+new_certs_dir = $dir/newcerts # default place for new certs.
+
+certificate = $dir/cacert.pem # The CA certificate
+serial = $dir/serial # The current serial number
+crlnumber = $dir/crlnumber # the current crl number
+ # must be commented out to leave a V1 CRL
+crl = $dir/crl.pem # The current CRL
+private_key = $dir/private/cakey.pem# The private key
+RANDFILE = $dir/private/.rand # private random number file
+
+x509_extensions = usr_cert # The extensions to add to the cert
+
+# Comment out the following two lines for the "traditional"
+# (and highly broken) format.
+name_opt = ca_default # Subject Name options
+cert_opt = ca_default # Certificate field options
+
+# Extension copying option: use with caution.
+copy_extensions = copy
+
+# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs
+# so this is commented out by default to leave a V1 CRL.
+# crlnumber must also be commented out to leave a V1 CRL.
+# crl_extensions = crl_ext
+
+default_days = 365 # how long to certify for
+default_crl_days= 30 # how long before next CRL
+default_md = default # use public key default MD
+preserve = no # keep passed DN ordering
+
+# A few difference way of specifying how similar the request should look
+# For type CA, the listed attributes must be the same, and the optional
+# and supplied fields are just that :-)
+policy = policy_match
+
+# For the CA policy
+[ policy_match ]
+countryName = optional
+stateOrProvinceName = optional
+organizationName = optional
+organizationalUnitName = optional
+commonName = supplied
+emailAddress = optional
+
+# For the 'anything' policy
+# At this point in time, you must list all acceptable 'object'
+# types.
+[ policy_anything ]
+countryName = optional
+stateOrProvinceName = optional
+localityName = optional
+organizationName = optional
+organizationalUnitName = optional
+commonName = supplied
+emailAddress = optional
+
+####################################################################
+[ req ]
+default_bits = 2048
+default_keyfile = privkey.pem
+distinguished_name = req_distinguished_name
+attributes = req_attributes
+x509_extensions = v3_ca # The extensions to add to the self signed cert
+
+# Passwords for private keys if not present they will be prompted for
+# input_password = secret
+# output_password = secret
+
+# This sets a mask for permitted string types. There are several options.
+# default: PrintableString, T61String, BMPString.
+# pkix : PrintableString, BMPString (PKIX recommendation before 2004)
+# utf8only: only UTF8Strings (PKIX recommendation after 2004).
+# nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings).
+# MASK:XXXX a literal mask value.
+# WARNING: ancient versions of Netscape crash on BMPStrings or UTF8Strings.
+string_mask = utf8only
+
+# req_extensions = v3_req # The extensions to add to a certificate request
+
+[ req_distinguished_name ]
+countryName = Country Name (2 letter code)
+countryName_default = CZ
+countryName_min = 2
+countryName_max = 2
+
+stateOrProvinceName = State or Province Name (full name)
+stateOrProvinceName_default = PRAGUE
+
+localityName = Locality Name (eg, city)
+
+0.organizationName = Organization Name (eg, company)
+0.organizationName_default =
+
+# we can do this but it is not needed normally :-)
+#1.organizationName = Second Organization Name (eg, company)
+#1.organizationName_default = World Wide Web Pty Ltd
+
+organizationalUnitName = Organizational Unit Name (eg, section)
+#organizationalUnitName_default =
+
+commonName = Common Name (e.g. server FQDN or YOUR name)
+commonName_max = 64
+commonName_default = transport-test-server.com
+
+emailAddress = Email Address
+emailAddress_max = 64
+
+# SET-ex3 = SET extension number 3
+
+[ req_attributes ]
+challengePassword = A challenge password
+challengePassword_min = 4
+challengePassword_max = 20
+
+unstructuredName = An optional company name
+
+[ usr_cert ]
+
+# These extensions are added when 'ca' signs a request.
+
+# This goes against PKIX guidelines but some CAs do it and some software
+# requires this to avoid interpreting an end user certificate as a CA.
+
+basicConstraints=CA:FALSE
+
+# Here are some examples of the usage of nsCertType. If it is omitted
+# the certificate can be used for anything *except* object signing.
+
+# This is OK for an SSL server.
+# nsCertType = server
+
+# For an object signing certificate this would be used.
+# nsCertType = objsign
+
+# For normal client use this is typical
+# nsCertType = client, email
+
+# and for everything including object signing:
+# nsCertType = client, email, objsign
+
+# This is typical in keyUsage for a client certificate.
+# keyUsage = nonRepudiation, digitalSignature, keyEncipherment
+
+# This will be displayed in Netscape's comment listbox.
+nsComment = "OpenSSL Generated Certificate"
+
+# PKIX recommendations harmless if included in all certificates.
+subjectKeyIdentifier=hash
+authorityKeyIdentifier=keyid,issuer
+
+# This stuff is for subjectAltName and issuerAltname.
+# Import the email address.
+# subjectAltName=email:copy
+# An alternative to produce certificates that aren't
+# deprecated according to PKIX.
+# subjectAltName=email:move
+
+# Copy subject details
+# issuerAltName=issuer:copy
+
+#nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem
+#nsBaseUrl
+#nsRevocationUrl
+#nsRenewalUrl
+#nsCaPolicyUrl
+#nsSslServerName
+
+# This is required for TSA certificates.
+# extendedKeyUsage = critical,timeStamping
+
+[ v3_req ]
+
+# Extensions to add to a certificate request
+
+basicConstraints = CA:FALSE
+keyUsage = nonRepudiation, digitalSignature, keyEncipherment
+
+[ v3_ca ]
+
+
+# Extensions for a typical CA
+
+
+# PKIX recommendation.
+
+subjectKeyIdentifier=hash
+
+authorityKeyIdentifier=keyid:always,issuer
+
+basicConstraints = critical,CA:true
+
+subjectAltName = @alternate_names
+
+# Key usage: this is typical for a CA certificate. However since it will
+# prevent it being used as an test self-signed certificate it is best
+# left out by default.
+keyUsage = digitalSignature, keyEncipherment, cRLSign, keyCertSign
+
+# Some might want this also
+# nsCertType = sslCA, emailCA
+
+# Include email address in subject alt name: another PKIX recommendation
+# subjectAltName=email:copy
+# Copy issuer details
+# issuerAltName=issuer:copy
+
+# DER hex encoding of an extension: beware experts only!
+# obj=DER:02:03
+# Where 'obj' is a standard or added object
+# You can even override a supported extension:
+# basicConstraints= critical, DER:30:03:01:01:FF
+
+[ crl_ext ]
+
+# CRL extensions.
+# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL.
+
+# issuerAltName=issuer:copy
+authorityKeyIdentifier=keyid:always
+
+[ proxy_cert_ext ]
+# These extensions should be added when creating a proxy certificate
+
+# This goes against PKIX guidelines but some CAs do it and some software
+# requires this to avoid interpreting an end user certificate as a CA.
+
+basicConstraints=CA:FALSE
+
+# Here are some examples of the usage of nsCertType. If it is omitted
+# the certificate can be used for anything *except* object signing.
+
+# This is OK for an SSL server.
+# nsCertType = server
+
+# For an object signing certificate this would be used.
+# nsCertType = objsign
+
+# For normal client use this is typical
+# nsCertType = client, email
+
+# and for everything including object signing:
+# nsCertType = client, email, objsign
+
+# This is typical in keyUsage for a client certificate.
+# keyUsage = nonRepudiation, digitalSignature, keyEncipherment
+
+# This will be displayed in Netscape's comment listbox.
+nsComment = "OpenSSL Generated Certificate"
+
+# PKIX recommendations harmless if included in all certificates.
+subjectKeyIdentifier=hash
+authorityKeyIdentifier=keyid,issuer
+
+# This stuff is for subjectAltName and issuerAltname.
+# Import the email address.
+# subjectAltName=email:copy
+# An alternative to produce certificates that aren't
+# deprecated according to PKIX.
+# subjectAltName=email:move
+
+# Copy subject details
+# issuerAltName=issuer:copy
+
+#nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem
+#nsBaseUrl
+#nsRevocationUrl
+#nsRenewalUrl
+#nsCaPolicyUrl
+#nsSslServerName
+
+# This really needs to be in place for it to be a proxy certificate.
+proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:3,policy:foo
+
+####################################################################
+[ tsa ]
+
+default_tsa = tsa_config1 # the default TSA section
+
+[ tsa_config1 ]
+
+# These are used by the TSA reply generation only.
+dir = ./demoCA # TSA root directory
+serial = $dir/tsaserial # The current serial number (mandatory)
+crypto_device = builtin # OpenSSL engine to use for signing
+signer_cert = $dir/tsacert.pem # The TSA signing certificate
+ # (optional)
+certs = $dir/cacert.pem # Certificate chain to include in reply
+ # (optional)
+signer_key = $dir/private/tsakey.pem # The TSA private key (optional)
+signer_digest = sha256 # Signing digest to use. (Optional)
+default_policy = tsa_policy1 # Policy if request did not specify it
+ # (optional)
+other_policies = tsa_policy2, tsa_policy3 # acceptable policies (optional)
+digests = sha1, sha256, sha384, sha512 # Acceptable message digests (mandatory)
+accuracy = secs:1, millisecs:500, microsecs:100 # (optional)
+clock_precision_digits = 0 # number of digits after dot. (optional)
+ordering = yes # Is ordering defined for timestamps?
+ # (optional, default: no)
+tsa_name = yes # Must the TSA name be included in the reply?
+ # (optional, default: no)
+ess_cert_id_chain = no # Must the ESS cert id chain be included?
+ # (optional, default: no)
+
+[ alternate_names ]
+
+DNS.1 = transport-test-server.com
diff --git a/tests/pytests/certs/tt.key.pem b/tests/pytests/certs/tt.key.pem
new file mode 100644
index 0000000..1974be7
--- /dev/null
+++ b/tests/pytests/certs/tt.key.pem
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDRAQDAX6+lFKur
+vm7fgQqm8WyYzT/wxfPJjsVQGe87OlH1KFzVfzYzgEt0RMlMeZgipREBZB2zK+WF
+M5RBHWYAwlI5PKt7EAGn8q1Zm4z+M9Uom3/Hy3bZ9q+AJwjkodpHYuFyWJqHIQBq
+aQ3SFyJwdZ/GsuzEUfWuIl74oyyMAeykTKFGdaVuIlLC3fKm8UCnfk99i/LEXUwR
+cmOV0uaG7deN5ITDDCFdb615yVjLkMhGY/jHK7uuxATOopEk4vThQ1aQjSkHwlua
+qFUW6Zl4QF8WOAufoWQPFZ8XxmUYEIG/sMvLv6dol7ltjEbCbfyzlS+9Qbnq6Mfh
+TZF/4jAPAgMBAAECggEBALSs10d18FMW0WjAUPxpgxnaLnTRSesMVLjy8ONT6Bkd
+S2hRIh91vxc6WwABzrqLita4N0EqmPoggmNpuUmo7lrNoWLVbbAOoD/da7nA3FuL
+10MpWYcP/ohh1klEdU2gFSAM/LNqoPsbrk5OzqHFWgI5zItqdX8pEucb01nBRWsp
+VMY2vzVuFB2jweZQ5+LCpfSMcRIzlxQa9CG4Peu6YW1Z4b3aUcS63/829JN/ZOGd
+uoRqR+gP71yNIt6i7wA5cot5FRmzlFEGhb1XzBOB1FFHOiknOZzbBtDsGUUmVtfA
+6mXcTumhdHbC0bXnHei/s2s9X0EeyQFYPkoS4NUQ2dECgYEA/7lhgn89K8rpUPnS
+eccTpKVPWp8luQei98Hi/F94kwP32l7Zl7Bmu2nltUoB1GBRXoXY6KzTphmT6ioA
+8joLCKIii5/nOdZAdHbIN2tkXS56h524q5I2jKogjfRrpCaAJE8x99f8L9uTBfZb
+/7BBQDHai1/S6LcpIRf/4g1/xBsCgYEA0Tq4V5hR9mGDUFir1FDGhA3ijDkIE/sO
+3QGTU7W90BL27te98FuQtWOPqfd1fi26WypNpNQUZb3V4x5tmDcpWscfj6I10432
+4zECPlDgaevucJjj245U7WjUhdAvlRy6K8H/8MgRBAjw9h8dwIGIx9gmOqKdA+/h
+ve3xyjKQex0CgYAz0XzQ1LewiA1/OyBLTOvOETFjS5x5QfLkAYXdXfswzz0KIu40
+rqoij/LcKYL1Zg8W+Ehb3amFnuk6KgjHDLvvo+scH+ra7W9iKi+oCzrrJt/tWyhw
+m9Ax8Mdn/H9TY/nTYbjeYAXaLMQ+EQ3TYgPW3kNKusAiJ/tNmW9gfxvEwQKBgGSJ
+Rbj5fTDZjGKYKQDdS3Z6wYhFg0culObHcgaARtPruPHtgtwy82blj0vJl5Bo4qoZ
+urNgIOj+ff8jSOAiaWGwWs8Gz7x289IZY42UCTF8Z9d878g5LT/i5nPiJGsPIboS
+/yuwxtRcg4SQURiGZbY5e60jJDWXF67O3icdguVVAoGARXLufXvZ/9Xf1DmFFxjq
+PJMCa1sfofqjB4KqYbt17vFtTsddCiyqsbpx36oY6nIdm9yUiGo10YaSEJtDEGLS
+L3TPZ4s8M8dcjOfj8Kk75pKbJ7NY4qA64dtbxcZbrFp3/mGZkDing94y+Zc/aFqa
+xQsA/yhmYV9r+FHDL54Cn6I=
+-----END PRIVATE KEY-----
diff --git a/tests/pytests/conftest.py b/tests/pytests/conftest.py
new file mode 100644
index 0000000..4c711f8
--- /dev/null
+++ b/tests/pytests/conftest.py
@@ -0,0 +1,102 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+import socket
+
+import pytest
+
+from kresd import init_portdir, make_kresd
+
+
+@pytest.fixture
+def kresd(tmpdir):
+ with make_kresd(tmpdir) as kresd:
+ yield kresd
+
+
+@pytest.fixture
+def kresd_silent(tmpdir):
+ with make_kresd(tmpdir, verbose=False) as kresd:
+ yield kresd
+
+
+@pytest.fixture
+def kresd_tt(tmpdir):
+ with make_kresd(tmpdir, 'tt') as kresd:
+ yield kresd
+
+
+@pytest.fixture(params=[
+ 'ip_tcp_socket',
+ 'ip6_tcp_socket',
+ 'ip_tls_socket',
+ 'ip6_tls_socket',
+])
+def make_kresd_sock(request, kresd):
+ """Factory function to create sockets of the same kind."""
+ sock_func = getattr(kresd, request.param)
+
+ def _make_kresd_sock():
+ return sock_func()
+
+ return _make_kresd_sock
+
+
+@pytest.fixture(params=[
+ 'ip_tcp_socket',
+ 'ip6_tcp_socket',
+ 'ip_tls_socket',
+ 'ip6_tls_socket',
+])
+def make_kresd_silent_sock(request, kresd_silent):
+ """Factory function to create sockets of the same kind (no verbose)."""
+ sock_func = getattr(kresd_silent, request.param)
+
+ def _make_kresd_sock():
+ return sock_func()
+
+ return _make_kresd_sock
+
+
+@pytest.fixture
+def kresd_sock(make_kresd_sock):
+ return make_kresd_sock()
+
+
+@pytest.fixture(params=[
+ socket.AF_INET,
+ socket.AF_INET6,
+])
+def sock_family(request):
+ return request.param
+
+
+@pytest.fixture(params=[
+ True,
+ False
+])
+def single_buffer(request): # whether to send all data in a single buffer
+ return request.param
+
+
+@pytest.fixture(params=[
+ True,
+ False
+])
+def query_before(request): # whether to send an initial query
+ return request.param
+
+
+@pytest.mark.optionalhook
+def pytest_metadata(metadata): # filter potentially sensitive data from GitLab CI
+ keys_to_delete = []
+ for key in metadata.keys():
+ key_lower = key.lower()
+ if 'password' in key_lower or 'token' in key_lower or \
+ key_lower.startswith('ci') or key_lower.startswith('gitlab'):
+ keys_to_delete.append(key)
+ for key in keys_to_delete:
+ del metadata[key]
+
+
+def pytest_sessionstart(session): # pylint: disable=unused-argument
+ init_portdir()
diff --git a/tests/pytests/conn_flood.py b/tests/pytests/conn_flood.py
new file mode 100644
index 0000000..88bbfa5
--- /dev/null
+++ b/tests/pytests/conn_flood.py
@@ -0,0 +1,85 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+"""Test opening as many connections as possible.
+
+Due to resource-intensity of this test, it's filename doesn't contain
+"test" on purpose, so it doesn't automatically get picked up by pytest
+(to allow easy parallel testing).
+
+To execute this test, pass the filename of this file to pytest directly.
+Also, make sure not to use parallel execution (-n).
+"""
+
+import resource
+import time
+
+import pytest
+
+from kresd import Kresd
+import utils
+
+
+MAX_SOCKETS = 10000 # upper bound of how many connections to open
+MAX_ITERATIONS = 10 # number of iterations to run the test
+
+# we can't use softlimit itself since kresd already has open sockets,
+# so use lesser value
+RESERVED_NOFILE = 40 # 40 is empirical value
+
+
+@pytest.mark.parametrize('sock_func_name', [
+ 'ip_tcp_socket',
+ 'ip6_tcp_socket',
+ 'ip_tls_socket',
+ 'ip6_tls_socket',
+])
+def test_conn_flood(tmpdir, sock_func_name):
+ def create_sockets(make_sock, nsockets):
+ sockets = []
+ next_ping = time.time() + 4 # less than tcp idle timeout / 2
+ while True:
+ additional_sockets = 0
+ while time.time() < next_ping:
+ nsock_to_init = min(100, nsockets - len(sockets))
+ if not nsock_to_init:
+ return sockets
+ sockets.extend([make_sock() for _ in range(nsock_to_init)])
+ additional_sockets += nsock_to_init
+
+ # large number of connections can take a lot of time to open
+ # send some valid data to avoid TCP idle timeout for already open sockets
+ next_ping = time.time() + 4
+ for s in sockets:
+ utils.ping_alive(s)
+
+ # break when no more than 20% additional sockets are created
+ if additional_sockets / len(sockets) < 0.2:
+ return sockets
+
+ max_num_of_open_files = resource.getrlimit(resource.RLIMIT_NOFILE)[0] - RESERVED_NOFILE
+ nsockets = min(max_num_of_open_files, MAX_SOCKETS)
+
+ # create kresd instance with verbose=False
+ ip = '127.0.0.1'
+ ip6 = '::1'
+ with Kresd(tmpdir, ip=ip, ip6=ip6, verbose=False) as kresd:
+ make_sock = getattr(kresd, sock_func_name) # function for creating sockets
+ sockets = create_sockets(make_sock, nsockets)
+ print("\nEstablished {} connections".format(len(sockets)))
+
+ print("Start sending data")
+ for i in range(MAX_ITERATIONS):
+ for s in sockets:
+ utils.ping_alive(s)
+ print("Iteration {} done...".format(i))
+
+ print("Close connections")
+ for s in sockets:
+ s.close()
+
+ # check in kresd is alive
+ print("Check upstream is still alive")
+ sock = make_sock()
+ utils.ping_alive(sock)
+
+ print("OK!")
diff --git a/tests/pytests/kresd.py b/tests/pytests/kresd.py
new file mode 100644
index 0000000..149efe9
--- /dev/null
+++ b/tests/pytests/kresd.py
@@ -0,0 +1,306 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+from collections import namedtuple
+from contextlib import ContextDecorator, contextmanager
+import os
+from pathlib import Path
+import random
+import re
+import shutil
+import socket
+import subprocess
+import time
+
+import jinja2
+
+import utils
+
+
+PYTESTS_DIR = os.path.dirname(os.path.realpath(__file__))
+CERTS_DIR = os.path.join(PYTESTS_DIR, 'certs')
+TEMPLATES_DIR = os.path.join(PYTESTS_DIR, 'templates')
+KRESD_CONF_TEMPLATE = 'kresd.conf.j2'
+KRESD_STARTUP_MSGID = 10005 # special unique ID at the start of the "test" log
+KRESD_PORTDIR = '/tmp/pytest-kresd-portdir'
+KRESD_TESTPORT_MIN = 1024
+KRESD_TESTPORT_MAX = 32768 # avoid overlap with docker ephemeral port range
+
+
+def init_portdir():
+ try:
+ shutil.rmtree(KRESD_PORTDIR)
+ except FileNotFoundError:
+ pass
+ os.makedirs(KRESD_PORTDIR)
+
+
+def create_file_from_template(template_path, dest, data):
+ env = jinja2.Environment(
+ loader=jinja2.FileSystemLoader(TEMPLATES_DIR))
+ template = env.get_template(template_path)
+ rendered_template = template.render(**data)
+
+ with open(dest, "w", encoding='UTF-8') as fh:
+ fh.write(rendered_template)
+
+
+Forward = namedtuple('Forward', ['proto', 'ip', 'port', 'hostname', 'ca_file'])
+
+
+class Kresd(ContextDecorator):
+ def __init__(
+ self, workdir, port=None, tls_port=None, ip=None, ip6=None, certname=None,
+ verbose=True, hints=None, forward=None, policy_test_pass=False):
+ if ip is None and ip6 is None:
+ raise ValueError("IPv4 or IPv6 must be specified!")
+ self.workdir = str(workdir)
+ self.port = port
+ self.tls_port = tls_port
+ self.ip = ip
+ self.ip6 = ip6
+ self.process = None
+ self.sockets = []
+ self.logfile = None
+ self.verbose = verbose
+ self.hints = {} if hints is None else hints
+ self.forward = forward
+ self.policy_test_pass = policy_test_pass
+
+ if certname:
+ self.tls_cert_path = os.path.join(CERTS_DIR, certname + '.cert.pem')
+ self.tls_key_path = os.path.join(CERTS_DIR, certname + '.key.pem')
+ else:
+ self.tls_cert_path = None
+ self.tls_key_path = None
+
+ @property
+ def config_path(self):
+ return str(os.path.join(self.workdir, 'kresd.conf'))
+
+ @property
+ def logfile_path(self):
+ return str(os.path.join(self.workdir, 'kresd.log'))
+
+ def __enter__(self):
+ if self.port is not None:
+ take_port(self.port, self.ip, self.ip6, timeout=120)
+ else:
+ self.port = make_port(self.ip, self.ip6)
+ if self.tls_port is not None:
+ take_port(self.tls_port, self.ip, self.ip6, timeout=120)
+ else:
+ self.tls_port = make_port(self.ip, self.ip6)
+
+ create_file_from_template(KRESD_CONF_TEMPLATE, self.config_path, {'kresd': self})
+ self.logfile = open(self.logfile_path, 'w', encoding='UTF-8')
+ self.process = subprocess.Popen(
+ ['kresd', '-c', self.config_path, '-n', self.workdir],
+ stderr=self.logfile, env=os.environ.copy())
+
+ try:
+ self._wait_for_tcp_port() # wait for ports to be up and responding
+ if not self.all_ports_alive(msgid=10001):
+ raise RuntimeError("Kresd not listening on all ports")
+
+ # issue special msgid to mark start of test log
+ sock = self.ip_tcp_socket() if self.ip else self.ip6_tcp_socket()
+ assert utils.try_ping_alive(sock, close=True, msgid=KRESD_STARTUP_MSGID)
+
+ # sanity check - kresd didn't crash
+ self.process.poll()
+ if self.process.returncode is not None:
+ raise RuntimeError("Kresd crashed with returncode: {}".format(
+ self.process.returncode))
+ except (RuntimeError, ConnectionError): # pylint: disable=try-except-raise
+ with open(self.logfile_path, encoding='UTF-8') as log: # print log for debugging
+ print(log.read())
+ raise
+
+ return self
+
+ def __exit__(self, exc_type, exc_value, traceback):
+ try:
+ if not self.all_ports_alive(msgid=1006):
+ raise RuntimeError("Kresd crashed")
+ finally:
+ for sock in self.sockets:
+ sock.close()
+ self.process.terminate()
+ self.logfile.close()
+ Path(KRESD_PORTDIR, str(self.port)).unlink()
+
+ def all_ports_alive(self, msgid=10001):
+ alive = True
+ if self.ip:
+ alive &= utils.try_ping_alive(self.ip_tcp_socket(), close=True, msgid=msgid)
+ alive &= utils.try_ping_alive(self.ip_tls_socket(), close=True, msgid=msgid + 1)
+ if self.ip6:
+ alive &= utils.try_ping_alive(self.ip6_tcp_socket(), close=True, msgid=msgid + 2)
+ alive &= utils.try_ping_alive(self.ip6_tls_socket(), close=True, msgid=msgid + 3)
+ return alive
+
+ def _wait_for_tcp_port(self, max_delay=10, delay_step=0.2):
+ family = socket.AF_INET if self.ip else socket.AF_INET6
+ i = 0
+ end_time = time.time() + max_delay
+
+ while time.time() < end_time:
+ i += 1
+
+ # use exponential backoff algorithm to choose next delay
+ rand_delay = random.randrange(0, i)
+ time.sleep(rand_delay * delay_step)
+
+ try:
+ sock, dest = self.stream_socket(family, timeout=5)
+ sock.connect(dest)
+ except ConnectionRefusedError:
+ continue
+ else:
+ try:
+ return utils.try_ping_alive(sock, close=True, msgid=10000)
+ except socket.timeout:
+ continue
+ finally:
+ sock.close()
+ raise RuntimeError("Kresd didn't start in time {}".format(dest))
+
+ def socket_dest(self, family, tls=False):
+ port = self.tls_port if tls else self.port
+ if family == socket.AF_INET:
+ return self.ip, port
+ elif family == socket.AF_INET6:
+ return self.ip6, port, 0, 0
+ raise RuntimeError("Unsupported socket family: {}".format(family))
+
+ def stream_socket(self, family, tls=False, timeout=20):
+ """Initialize a socket and return it along with the destination without connecting."""
+ sock = socket.socket(family, socket.SOCK_STREAM)
+ sock.settimeout(timeout)
+ sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
+ dest = self.socket_dest(family, tls)
+ self.sockets.append(sock)
+ return sock, dest
+
+ def _tcp_socket(self, family):
+ sock, dest = self.stream_socket(family)
+ sock.connect(dest)
+ return sock
+
+ def ip_tcp_socket(self):
+ return self._tcp_socket(socket.AF_INET)
+
+ def ip6_tcp_socket(self):
+ return self._tcp_socket(socket.AF_INET6)
+
+ def _tls_socket(self, family):
+ sock, dest = self.stream_socket(family, tls=True)
+ ctx = utils.make_ssl_context(insecure=True)
+ ssock = ctx.wrap_socket(sock)
+ try:
+ ssock.connect(dest)
+ except OSError as exc:
+ if exc.errno == 0: # sometimes happens shortly after startup
+ return None
+ return ssock
+
+ def _tls_socket_with_retry(self, family):
+ sock = self._tls_socket(family)
+ if sock is None:
+ time.sleep(0.1)
+ sock = self._tls_socket(family)
+ if sock is None:
+ raise RuntimeError("Failed to create TLS socket!")
+ return sock
+
+ def ip_tls_socket(self):
+ return self._tls_socket_with_retry(socket.AF_INET)
+
+ def ip6_tls_socket(self):
+ return self._tls_socket_with_retry(socket.AF_INET6)
+
+ def partial_log(self):
+ partial_log = '\n (... omitting log start)\n'
+ with open(self.logfile_path, encoding='UTF-8') as log: # display partial log for debugging
+ past_startup_msgid = False
+ past_startup = False
+ for line in log:
+ if past_startup:
+ partial_log += line
+ else: # find real start of test log (after initial alive-pings)
+ if not past_startup_msgid:
+ if re.match(KRESD_LOG_STARTUP_MSGID, line) is not None:
+ past_startup_msgid = True
+ else:
+ if re.match(KRESD_LOG_IO_CLOSE, line) is not None:
+ past_startup = True
+ return partial_log
+
+
+def is_port_free(port, ip=None, ip6=None):
+ def check(family, type_, dest):
+ sock = socket.socket(family, type_)
+ sock.bind(dest)
+ sock.close()
+
+ try:
+ if ip is not None:
+ check(socket.AF_INET, socket.SOCK_STREAM, (ip, port))
+ check(socket.AF_INET, socket.SOCK_DGRAM, (ip, port))
+ if ip6 is not None:
+ check(socket.AF_INET6, socket.SOCK_STREAM, (ip6, port, 0, 0))
+ check(socket.AF_INET6, socket.SOCK_DGRAM, (ip6, port, 0, 0))
+ except OSError as exc:
+ if exc.errno == 98: # address already in use
+ return False
+ else:
+ raise
+ return True
+
+
+def take_port(port, ip=None, ip6=None, timeout=0):
+ port_path = Path(KRESD_PORTDIR, str(port))
+ end_time = time.time() + timeout
+ try:
+ port_path.touch(exist_ok=False)
+ except FileExistsError as ex:
+ raise ValueError(
+ "Port {} already reserved by system or another kresd instance!".format(port)) from ex
+
+ while True:
+ if is_port_free(port, ip, ip6):
+ # NOTE: The port_path isn't removed, so other instances don't have to attempt to
+ # take the same port again. This has the side effect of leaving many of these
+ # files behind, because when another kresd shuts down and removes its file, the
+ # port still can't be reserved for a while. This shouldn't become an issue unless
+ # we have thousands of tests (and run out of the port range).
+ break
+
+ if time.time() < end_time:
+ time.sleep(5)
+ else:
+ raise ValueError(
+ "Port {} is reserved by system!".format(port))
+ return port
+
+
+def make_port(ip=None, ip6=None):
+ for _ in range(10): # max attempts
+ port = random.randint(KRESD_TESTPORT_MIN, KRESD_TESTPORT_MAX)
+ try:
+ take_port(port, ip, ip6)
+ except ValueError:
+ continue # port reserved by system / another kresd instance
+ return port
+ raise RuntimeError("No available port found!")
+
+
+KRESD_LOG_STARTUP_MSGID = re.compile(r'^\[[^]]+\]\[{}.*'.format(KRESD_STARTUP_MSGID))
+KRESD_LOG_IO_CLOSE = re.compile(r'^\[io \].*closed by peer.*')
+
+
+@contextmanager
+def make_kresd(workdir, certname=None, ip='127.0.0.1', ip6='::1', **kwargs):
+ with Kresd(workdir, ip=ip, ip6=ip6, certname=certname, **kwargs) as kresd:
+ yield kresd
+ print(kresd.partial_log())
diff --git a/tests/pytests/meson.build b/tests/pytests/meson.build
new file mode 100644
index 0000000..d717dc2
--- /dev/null
+++ b/tests/pytests/meson.build
@@ -0,0 +1,77 @@
+# tests: pytests
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# python 3 dependencies
+py3_deps += [
+ ['jinja2', 'jinja2 (for pytests)'],
+ ['dns', 'dnspython (for pytests)'],
+ ['pytest', 'pytest (for pytests)'],
+ ['pytest_html', 'pytest-html (for pytests)'],
+ ['xdist', 'pytest-xdist (for pytests)'],
+]
+
+if gnutls.version().version_compare('<3.6.4')
+ error('pytests require GnuTLS >= 3.6.4')
+endif
+
+# compile tlsproxy
+tlsproxy_src = files([
+ 'proxy/tlsproxy.c',
+ 'proxy/tls-proxy.c',
+])
+tlsproxy = executable(
+ 'tlsproxy',
+ tlsproxy_src,
+ dependencies: [
+ libkres_dep,
+ libuv,
+ gnutls,
+ ],
+)
+
+# path to kresd and tlsproxy
+pytests_env = environment()
+pytests_env.prepend('PATH', sbin_dir, meson.current_build_dir())
+
+test(
+ 'pytests.parallel',
+ python3,
+ args: [
+ '-m', 'pytest',
+ '-d',
+ '--html', 'pytests.parallel.html',
+ '--self-contained-html',
+ '--junitxml=pytests.parallel.junit.xml',
+ '-n', '24',
+ '-v',
+ ],
+ env: pytests_env,
+ suite: [
+ 'postinstall',
+ 'pytests',
+ ],
+ workdir: meson.current_source_dir(),
+ is_parallel: false,
+ timeout: 180,
+ depends: tlsproxy,
+)
+
+test(
+ 'pytests.single',
+ python3,
+ args: [
+ '-m', 'pytest',
+ '--junitxml=pytests.single.junit.xml',
+ '-ra',
+ '--capture=no',
+ 'conn_flood.py',
+ ],
+ env: pytests_env,
+ suite: [
+ 'postinstall',
+ 'pytests',
+ ],
+ workdir: meson.current_source_dir(),
+ is_parallel: false,
+ timeout: 240,
+)
diff --git a/tests/pytests/proxy.py b/tests/pytests/proxy.py
new file mode 100644
index 0000000..b8a53cd
--- /dev/null
+++ b/tests/pytests/proxy.py
@@ -0,0 +1,161 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+from contextlib import contextmanager, ContextDecorator
+import os
+import subprocess
+from typing import Any, Dict, Optional
+
+import dns
+import dns.rcode
+import pytest
+
+from kresd import CERTS_DIR, Forward, Kresd, make_kresd, make_port
+import utils
+
+
+HINTS = {
+ '0.foo.': '127.0.0.1',
+ '1.foo.': '127.0.0.1',
+ '2.foo.': '127.0.0.1',
+ '3.foo.': '127.0.0.1',
+}
+
+
+def resolve_hint(sock, qname):
+ buff, msgid = utils.get_msgbuff(qname)
+ sock.sendall(buff)
+ answer = utils.receive_parse_answer(sock)
+ assert answer.id == msgid
+ assert answer.rcode() == dns.rcode.NOERROR
+ assert answer.answer[0][0].address == HINTS[qname]
+
+
+class Proxy(ContextDecorator):
+ EXECUTABLE = ''
+
+ def __init__(
+ self,
+ local_ip: str = '127.0.0.1',
+ local_port: Optional[int] = None,
+ upstream_ip: str = '127.0.0.1',
+ upstream_port: Optional[int] = None
+ ) -> None:
+ self.local_ip = local_ip
+ self.local_port = local_port
+ self.upstream_ip = upstream_ip
+ self.upstream_port = upstream_port
+ self.proxy = None
+
+ def get_args(self):
+ args = []
+ args.append('--local')
+ args.append(self.local_ip)
+ if self.local_port is not None:
+ args.append('--lport')
+ args.append(str(self.local_port))
+ args.append('--upstream')
+ args.append(self.upstream_ip)
+ if self.upstream_port is not None:
+ args.append('--uport')
+ args.append(str(self.upstream_port))
+ return args
+
+ def __enter__(self):
+ args = [self.EXECUTABLE] + self.get_args()
+ print(' '.join(args))
+
+ try:
+ self.proxy = subprocess.Popen(
+ args, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
+ except subprocess.CalledProcessError:
+ pytest.skip("proxy '{}' failed to run (did you compile it?)"
+ .format(self.EXECUTABLE))
+
+ return self
+
+ def __exit__(self, exc_type, exc_value, traceback):
+ if self.proxy is not None:
+ self.proxy.terminate()
+ self.proxy = None
+
+
+class TLSProxy(Proxy):
+ EXECUTABLE = 'tlsproxy'
+
+ def __init__(
+ self,
+ local_ip: str = '127.0.0.1',
+ local_port: Optional[int] = None,
+ upstream_ip: str = '127.0.0.1',
+ upstream_port: Optional[int] = None,
+ certname: Optional[str] = 'tt',
+ close: Optional[int] = None,
+ rehandshake: bool = False,
+ force_tls13: bool = False
+ ) -> None:
+ super().__init__(local_ip, local_port, upstream_ip, upstream_port)
+ if certname is not None:
+ self.cert_path = os.path.join(CERTS_DIR, certname + '.cert.pem')
+ self.key_path = os.path.join(CERTS_DIR, certname + '.key.pem')
+ else:
+ self.cert_path = None
+ self.key_path = None
+ self.close = close
+ self.rehandshake = rehandshake
+ self.force_tls13 = force_tls13
+
+ def get_args(self):
+ args = super().get_args()
+ if self.cert_path is not None:
+ args.append('--cert')
+ args.append(self.cert_path)
+ if self.key_path is not None:
+ args.append('--key')
+ args.append(self.key_path)
+ if self.close is not None:
+ args.append('--close')
+ args.append(str(self.close))
+ if self.rehandshake:
+ args.append('--rehandshake')
+ if self.force_tls13:
+ args.append('--tls13')
+ return args
+
+
+@contextmanager
+def kresd_tls_client(
+ workdir: str,
+ proxy: TLSProxy,
+ kresd_tls_client_kwargs: Optional[Dict[Any, Any]] = None,
+ kresd_fwd_target_kwargs: Optional[Dict[Any, Any]] = None
+ ) -> Kresd:
+ """kresd_tls_client --(tls)--> tlsproxy --(tcp)--> kresd_fwd_target"""
+ ALLOWED_IPS = {'127.0.0.1', '::1'}
+ assert proxy.local_ip in ALLOWED_IPS, "only localhost IPs supported for proxy"
+ assert proxy.upstream_ip in ALLOWED_IPS, "only localhost IPs are supported for proxy"
+
+ if kresd_tls_client_kwargs is None:
+ kresd_tls_client_kwargs = {}
+ if kresd_fwd_target_kwargs is None:
+ kresd_fwd_target_kwargs = {}
+
+ # run forward target instance
+ dir1 = os.path.join(workdir, 'kresd_fwd_target')
+ os.makedirs(dir1)
+
+ with make_kresd(dir1, hints=HINTS, **kresd_fwd_target_kwargs) as kresd_fwd_target:
+ sock = kresd_fwd_target.ip_tcp_socket()
+ resolve_hint(sock, list(HINTS.keys())[0])
+
+ proxy.local_port = make_port('127.0.0.1', '::1')
+ proxy.upstream_port = kresd_fwd_target.port
+
+ with proxy:
+ # run test kresd instance
+ dir2 = os.path.join(workdir, 'kresd_tls_client')
+ os.makedirs(dir2)
+ forward = Forward(
+ proto='tls', ip=proxy.local_ip, port=proxy.local_port,
+ hostname='transport-test-server.com', ca_file=proxy.cert_path)
+ with make_kresd(dir2, forward=forward, **kresd_tls_client_kwargs) as kresd:
+ yield kresd
diff --git a/tests/pytests/proxy/tls-proxy.c b/tests/pytests/proxy/tls-proxy.c
new file mode 100644
index 0000000..986716c
--- /dev/null
+++ b/tests/pytests/proxy/tls-proxy.c
@@ -0,0 +1,1038 @@
+/* SPDX-License-Identifier: GPL-3.0-or-later */
+
+#include <assert.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <gnutls/gnutls.h>
+#include <uv.h>
+#include "lib/generic/array.h"
+#include "tls-proxy.h"
+
+#define TLS_MAX_SEND_RETRIES 100
+#define CLIENT_ANSWER_CHUNK_SIZE 8
+
+#define MAX_CLIENT_PENDING_SIZE 4096
+
+struct buf {
+ size_t size;
+ char buf[];
+};
+
+enum peer_state {
+ STATE_NOT_CONNECTED,
+ STATE_LISTENING,
+ STATE_CONNECTED,
+ STATE_CONNECT_IN_PROGRESS,
+ STATE_CLOSING_IN_PROGRESS
+};
+
+enum handshake_state {
+ TLS_HS_NOT_STARTED = 0,
+ TLS_HS_EXPECTED,
+ TLS_HS_REAUTH_EXPECTED,
+ TLS_HS_IN_PROGRESS,
+ TLS_HS_DONE,
+ TLS_HS_CLOSING,
+ TLS_HS_LAST
+};
+
+struct tls_ctx {
+ gnutls_session_t session;
+ enum handshake_state handshake_state;
+ /* for reading from the network */
+ const uint8_t *buf;
+ ssize_t nread;
+ ssize_t consumed;
+ uint8_t recv_buf[4096];
+};
+
+struct peer {
+ uv_tcp_t handle;
+ enum peer_state state;
+ struct sockaddr_storage addr;
+ array_t(struct buf *) pending_buf;
+ uint64_t connection_timestamp;
+ struct tls_ctx *tls;
+ struct peer *peer;
+ int active_requests;
+};
+
+struct tls_proxy_ctx {
+ const struct args *a;
+ uv_loop_t *loop;
+ gnutls_certificate_credentials_t tls_credentials;
+ gnutls_priority_t tls_priority_cache;
+ struct {
+ uv_tcp_t handle;
+ struct sockaddr_storage addr;
+ } server;
+ struct sockaddr_storage upstream_addr;
+ array_t(struct peer *) client_list;
+ char uv_wire_buf[65535 * 2];
+ int conn_sequence;
+};
+
+static void read_from_upstream_cb(uv_stream_t *upstream, ssize_t nread, const uv_buf_t *buf);
+static void read_from_client_cb(uv_stream_t *client, ssize_t nread, const uv_buf_t *buf);
+static ssize_t proxy_gnutls_pull(gnutls_transport_ptr_t h, void *buf, size_t len);
+static ssize_t proxy_gnutls_push(gnutls_transport_ptr_t h, const void *buf, size_t len);
+static int tls_process_from_upstream(struct peer *upstream, const uint8_t *buf, ssize_t nread);
+static int tls_process_from_client(struct peer *client, const uint8_t *buf, ssize_t nread);
+static int write_to_upstream_pending(struct peer *peer);
+static int write_to_client_pending(struct peer *peer);
+static void on_client_close(uv_handle_t *handle);
+static void on_upstream_close(uv_handle_t *handle);
+
+static int gnutls_references = 0;
+
+static const char * const tlsv12_priorities =
+ "NORMAL:" /* GnuTLS defaults */
+ "-VERS-TLS1.0:-VERS-TLS1.1:+VERS-TLS1.2:-VERS-TLS1.3:" /* TLS 1.2 only */
+ "-VERS-SSL3.0:-ARCFOUR-128:-COMP-ALL:+COMP-NULL";
+
+static const char * const tlsv13_priorities =
+ "NORMAL:" /* GnuTLS defaults */
+ "-VERS-TLS1.0:-VERS-TLS1.1:-VERS-TLS1.2:+VERS-TLS1.3:" /* TLS 1.3 only */
+ "-VERS-SSL3.0:-ARCFOUR-128:-COMP-ALL:+COMP-NULL";
+
+static struct tls_proxy_ctx *get_proxy(struct peer *peer)
+{
+ return (struct tls_proxy_ctx *)peer->handle.loop->data;
+}
+
+const void *ip_addr(const struct sockaddr *addr)
+{
+ if (!addr) {
+ return NULL;
+ }
+ switch (addr->sa_family) {
+ case AF_INET: return (const void *)&(((const struct sockaddr_in *)addr)->sin_addr);
+ case AF_INET6: return (const void *)&(((const struct sockaddr_in6 *)addr)->sin6_addr);
+ default: return NULL;
+ }
+}
+
+uint16_t ip_addr_port(const struct sockaddr *addr)
+{
+ if (!addr) {
+ return 0;
+ }
+ switch (addr->sa_family) {
+ case AF_INET: return ntohs(((const struct sockaddr_in *)addr)->sin_port);
+ case AF_INET6: return ntohs(((const struct sockaddr_in6 *)addr)->sin6_port);
+ default: return 0;
+ }
+}
+
+static int ip_addr_str(const struct sockaddr *addr, char *buf, size_t *buflen)
+{
+ int ret = 0;
+ if (!addr || !buf || !buflen) {
+ return EINVAL;
+ }
+
+ char str[INET6_ADDRSTRLEN + 6];
+ if (!inet_ntop(addr->sa_family, ip_addr(addr), str, sizeof(str))) {
+ return errno;
+ }
+ int len = strlen(str);
+ str[len] = '#';
+ snprintf(&str[len + 1], 6, "%hu", ip_addr_port(addr));
+ len += 6;
+ str[len] = 0;
+ if (len >= *buflen) {
+ ret = ENOSPC;
+ } else {
+ memcpy(buf, str, len + 1);
+ }
+ *buflen = len;
+ return ret;
+}
+
+static inline char *ip_straddr(const struct sockaddr_storage *saddr_storage)
+{
+ assert(saddr_storage != NULL);
+ const struct sockaddr *addr = (const struct sockaddr *)saddr_storage;
+ /* We are the single-threaded application */
+ static char str[INET6_ADDRSTRLEN + 6];
+ size_t len = sizeof(str);
+ int ret = ip_addr_str(addr, str, &len);
+ return ret != 0 || len == 0 ? NULL : str;
+}
+
+static struct buf *alloc_io_buffer(size_t size)
+{
+ struct buf *buf = calloc(1, sizeof (struct buf) + size);
+ buf->size = size;
+ return buf;
+}
+
+static void free_io_buffer(struct buf *buf)
+{
+ if (!buf) {
+ return;
+ }
+ free(buf);
+}
+
+static struct buf *get_first_pending_buf(struct peer *peer)
+{
+ struct buf *buf = NULL;
+ if (peer->pending_buf.len > 0) {
+ buf = peer->pending_buf.at[0];
+ }
+ return buf;
+}
+
+static struct buf *remove_first_pending_buf(struct peer *peer)
+{
+ if (peer->pending_buf.len == 0) {
+ return NULL;
+ }
+ struct buf * buf = peer->pending_buf.at[0];
+ for (int i = 1; i < peer->pending_buf.len; ++i) {
+ peer->pending_buf.at[i - 1] = peer->pending_buf.at[i];
+ }
+ peer->pending_buf.len -= 1;
+ return buf;
+}
+
+static void clear_pending_bufs(struct peer *peer)
+{
+ for (int i = 0; i < peer->pending_buf.len; ++i) {
+ struct buf *b = peer->pending_buf.at[i];
+ free_io_buffer(b);
+ }
+ peer->pending_buf.len = 0;
+}
+
+static void alloc_uv_buffer(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf)
+{
+ struct tls_proxy_ctx *proxy = (struct tls_proxy_ctx *)handle->loop->data;
+ buf->base = proxy->uv_wire_buf;
+ buf->len = sizeof(proxy->uv_wire_buf);
+}
+
+static void on_client_close(uv_handle_t *handle)
+{
+ struct peer *client = (struct peer *)handle->data;
+ struct peer *upstream = client->peer;
+ fprintf(stdout, "[client] connection with '%s' closed\n", ip_straddr(&client->addr));
+ assert(client->tls);
+ gnutls_deinit(client->tls->session);
+ client->tls->handshake_state = TLS_HS_NOT_STARTED;
+ client->state = STATE_NOT_CONNECTED;
+ if (upstream->state != STATE_NOT_CONNECTED) {
+ if (upstream->state == STATE_CONNECTED) {
+ fprintf(stdout, "[client] closing connection with upstream for '%s'\n",
+ ip_straddr(&client->addr));
+ upstream->state = STATE_CLOSING_IN_PROGRESS;
+ uv_close((uv_handle_t*)&upstream->handle, on_upstream_close);
+ }
+ return;
+ }
+ struct tls_proxy_ctx *proxy = get_proxy(client);
+ for (size_t i = 0; i < proxy->client_list.len; ++i) {
+ struct peer *client_i = proxy->client_list.at[i];
+ if (client_i == client) {
+ fprintf(stdout, "[client] connection structures deallocated for '%s'\n",
+ ip_straddr(&client->addr));
+ array_del(proxy->client_list, i);
+ free(client->tls);
+ free(client);
+ break;
+ }
+ }
+}
+
+static void on_upstream_close(uv_handle_t *handle)
+{
+ struct peer *upstream = (struct peer *)handle->data;
+ struct peer *client = upstream->peer;
+ assert(upstream->tls == NULL);
+ upstream->state = STATE_NOT_CONNECTED;
+ fprintf(stdout, "[upstream] connection with upstream closed for client '%s'\n", ip_straddr(&client->addr));
+ if (client->state != STATE_NOT_CONNECTED) {
+ if (client->state == STATE_CONNECTED) {
+ fprintf(stdout, "[upstream] closing connection to client '%s'\n",
+ ip_straddr(&client->addr));
+ client->state = STATE_CLOSING_IN_PROGRESS;
+ uv_close((uv_handle_t*)&client->handle, on_client_close);
+ }
+ return;
+ }
+ struct tls_proxy_ctx *proxy = get_proxy(upstream);
+ for (size_t i = 0; i < proxy->client_list.len; ++i) {
+ struct peer *client_i = proxy->client_list.at[i];
+ if (client_i == client) {
+ fprintf(stdout, "[upstream] connection structures deallocated for '%s'\n",
+ ip_straddr(&client->addr));
+ array_del(proxy->client_list, i);
+ free(upstream);
+ free(client->tls);
+ free(client);
+ break;
+ }
+ }
+}
+
+static void write_to_client_cb(uv_write_t *req, int status)
+{
+ struct peer *client = (struct peer *)req->handle->data;
+ free(req);
+ client->active_requests -= 1;
+ if (status) {
+ fprintf(stdout, "[client] error writing to client '%s': %s\n",
+ ip_straddr(&client->addr), uv_strerror(status));
+ clear_pending_bufs(client);
+ if (client->state == STATE_CONNECTED) {
+ client->state = STATE_CLOSING_IN_PROGRESS;
+ uv_close((uv_handle_t*)&client->handle, on_client_close);
+ return;
+ }
+ }
+ fprintf(stdout, "[client] successfully wrote to client '%s', pending len is %zd, active requests %i\n",
+ ip_straddr(&client->addr), client->pending_buf.len, client->active_requests);
+ if (client->state == STATE_CONNECTED &&
+ client->tls->handshake_state == TLS_HS_DONE) {
+ struct tls_proxy_ctx *proxy = get_proxy(client);
+ uint64_t elapsed = uv_now(proxy->loop) - client->connection_timestamp;
+ if (!proxy->a->close_connection || elapsed < proxy->a->close_timeout) {
+ write_to_client_pending(client);
+ } else {
+ clear_pending_bufs(client);
+ client->state = STATE_CLOSING_IN_PROGRESS;
+ uv_close((uv_handle_t*)&client->handle, on_client_close);
+ fprintf(stdout, "[client] closing connection to client '%s'\n", ip_straddr(&client->addr));
+ }
+ }
+}
+
+static void write_to_upstream_cb(uv_write_t *req, int status)
+{
+ struct peer *upstream = (struct peer *)req->handle->data;
+ void *data = req->data;
+ free(req);
+ if (status) {
+ fprintf(stdout, "[upstream] error writing to upstream: %s\n", uv_strerror(status));
+ clear_pending_bufs(upstream);
+ upstream->state = STATE_CLOSING_IN_PROGRESS;
+ uv_close((uv_handle_t*)&upstream->handle, on_upstream_close);
+ return;
+ }
+ if (data != NULL) {
+ assert(upstream->pending_buf.len > 0);
+ struct buf *buf = get_first_pending_buf(upstream);
+ assert(data == (void *)buf->buf);
+ fprintf(stdout, "[upstream] successfully wrote %zi bytes to upstream, pending len is %zd\n",
+ buf->size, upstream->pending_buf.len);
+ remove_first_pending_buf(upstream);
+ free_io_buffer(buf);
+ } else {
+ fprintf(stdout, "[upstream] successfully wrote to upstream, pending len is %zd\n",
+ upstream->pending_buf.len);
+ }
+ if (upstream->peer == NULL || upstream->peer->state != STATE_CONNECTED) {
+ clear_pending_bufs(upstream);
+ } else if (upstream->state == STATE_CONNECTED && upstream->pending_buf.len > 0) {
+ write_to_upstream_pending(upstream);
+ }
+}
+
+static void accept_connection_from_client(uv_stream_t *server)
+{
+ struct tls_proxy_ctx *proxy = (struct tls_proxy_ctx *)server->loop->data;
+ struct peer *client = calloc(1, sizeof(struct peer));
+ uv_tcp_init(proxy->loop, &client->handle);
+ uv_tcp_nodelay((uv_tcp_t *)&client->handle, 1);
+
+ int err = uv_accept(server, (uv_stream_t*)&client->handle);
+ if (err != 0) {
+ fprintf(stdout, "[client] incoming connection - uv_accept() failed: (%d) %s\n",
+ err, uv_strerror(err));
+ proxy->conn_sequence = 0;
+ return;
+ }
+
+ client->state = STATE_CONNECTED;
+ array_init(client->pending_buf);
+ client->handle.data = client;
+
+ struct peer *upstream = calloc(1, sizeof(struct peer));
+ uv_tcp_init(proxy->loop, &upstream->handle);
+ uv_tcp_nodelay((uv_tcp_t *)&upstream->handle, 1);
+
+ client->peer = upstream;
+
+ array_init(upstream->pending_buf);
+ upstream->state = STATE_NOT_CONNECTED;
+ upstream->peer = client;
+ upstream->handle.data = upstream;
+
+ struct sockaddr *addr = (struct sockaddr *)&(client->addr);
+ int addr_len = sizeof(client->addr);
+ int ret = uv_tcp_getpeername(&client->handle, addr, &addr_len);
+ if (ret || addr->sa_family == AF_UNSPEC) {
+ client->state = STATE_CLOSING_IN_PROGRESS;
+ uv_close((uv_handle_t*)&client->handle, on_client_close);
+ fprintf(stdout, "[client] incoming connection - uv_tcp_getpeername() failed: (%d) %s\n",
+ err, uv_strerror(err));
+ proxy->conn_sequence = 0;
+ return;
+ }
+ memcpy(&upstream->addr, &proxy->upstream_addr, sizeof(struct sockaddr_storage));
+
+ struct tls_ctx *tls = calloc(1, sizeof(struct tls_ctx));
+ tls->handshake_state = TLS_HS_NOT_STARTED;
+
+ client->tls = tls;
+ const char *errpos = NULL;
+ unsigned int gnutls_flags = GNUTLS_SERVER | GNUTLS_NONBLOCK;
+#if GNUTLS_VERSION_NUMBER >= 0x030604
+ if (proxy->a->tls_13) {
+ gnutls_flags |= GNUTLS_POST_HANDSHAKE_AUTH;
+ }
+#endif
+ err = gnutls_init(&tls->session, gnutls_flags);
+ if (err != GNUTLS_E_SUCCESS) {
+ fprintf(stdout, "[client] gnutls_init() failed: (%d) %s\n",
+ err, gnutls_strerror_name(err));
+ }
+ err = gnutls_priority_set(tls->session, proxy->tls_priority_cache);
+ if (err != GNUTLS_E_SUCCESS) {
+ fprintf(stdout, "[client] gnutls_priority_set() failed: (%d) %s\n",
+ err, gnutls_strerror_name(err));
+ }
+
+ const char *direct_priorities = proxy->a->tls_13 ? tlsv13_priorities : tlsv12_priorities;
+ err = gnutls_priority_set_direct(tls->session, direct_priorities, &errpos);
+ if (err != GNUTLS_E_SUCCESS) {
+ fprintf(stdout, "[client] setting priority '%s' failed at character %zd (...'%s') with %s (%d)\n",
+ direct_priorities, errpos - direct_priorities, errpos,
+ gnutls_strerror_name(err), err);
+ }
+ err = gnutls_credentials_set(tls->session, GNUTLS_CRD_CERTIFICATE, proxy->tls_credentials);
+ if (err != GNUTLS_E_SUCCESS) {
+ fprintf(stdout, "[client] gnutls_credentials_set() failed: (%d) %s\n",
+ err, gnutls_strerror_name(err));
+ }
+ if (proxy->a->tls_13) {
+ gnutls_certificate_server_set_request(tls->session, GNUTLS_CERT_REQUEST);
+ } else {
+ gnutls_certificate_server_set_request(tls->session, GNUTLS_CERT_IGNORE);
+ }
+ gnutls_handshake_set_timeout(tls->session, GNUTLS_DEFAULT_HANDSHAKE_TIMEOUT);
+ gnutls_transport_set_pull_function(tls->session, proxy_gnutls_pull);
+ gnutls_transport_set_push_function(tls->session, proxy_gnutls_push);
+ gnutls_transport_set_ptr(tls->session, client);
+
+ tls->handshake_state = TLS_HS_IN_PROGRESS;
+
+ client->connection_timestamp = uv_now(proxy->loop);
+ proxy->conn_sequence += 1;
+ array_push(proxy->client_list, client);
+
+ fprintf(stdout, "[client] incoming connection from '%s'\n", ip_straddr(&client->addr));
+ uv_read_start((uv_stream_t*)&client->handle, alloc_uv_buffer, read_from_client_cb);
+}
+
+static void dynamic_handle_close_cb(uv_handle_t *handle)
+{
+ free(handle);
+}
+
+static void delayed_accept_timer_cb(uv_timer_t *timer)
+{
+ uv_stream_t *server = (uv_stream_t *)timer->data;
+ fprintf(stdout, "[client] delayed connection processing\n");
+ accept_connection_from_client(server);
+ uv_close((uv_handle_t *)timer, dynamic_handle_close_cb);
+}
+
+static void on_client_connection(uv_stream_t *server, int status)
+{
+ if (status < 0) {
+ fprintf(stdout, "[client] incoming connection error: %s\n", uv_strerror(status));
+ return;
+ }
+ struct tls_proxy_ctx *proxy = (struct tls_proxy_ctx *)server->loop->data;
+ proxy->conn_sequence += 1;
+ if (proxy->a->max_conn_sequence > 0 &&
+ proxy->conn_sequence > proxy->a->max_conn_sequence) {
+ fprintf(stdout, "[client] incoming connection, delaying\n");
+ uv_timer_t *timer = (uv_timer_t*)malloc(sizeof *timer);
+ uv_timer_init(uv_default_loop(), timer);
+ timer->data = server;
+ uv_timer_start(timer, delayed_accept_timer_cb, 10000, 0);
+ proxy->conn_sequence = 0;
+ } else {
+ accept_connection_from_client(server);
+ }
+}
+
+static void on_connect_to_upstream(uv_connect_t *req, int status)
+{
+ struct peer *upstream = (struct peer *)req->handle->data;
+ free(req);
+ if (status < 0) {
+ fprintf(stdout, "[upstream] error connecting to upstream (%s): %s\n",
+ ip_straddr(&upstream->addr),
+ uv_strerror(status));
+ clear_pending_bufs(upstream);
+ upstream->state = STATE_CLOSING_IN_PROGRESS;
+ uv_close((uv_handle_t*)&upstream->handle, on_upstream_close);
+ return;
+ }
+ fprintf(stdout, "[upstream] connected to %s\n", ip_straddr(&upstream->addr));
+
+ upstream->state = STATE_CONNECTED;
+ uv_read_start((uv_stream_t*)&upstream->handle, alloc_uv_buffer, read_from_upstream_cb);
+ if (upstream->pending_buf.len > 0) {
+ write_to_upstream_pending(upstream);
+ }
+}
+
+static void read_from_client_cb(uv_stream_t *handle, ssize_t nread, const uv_buf_t *buf)
+{
+ if (nread == 0) {
+ fprintf(stdout, "[client] reading %zd bytes\n", nread);
+ return;
+ }
+ struct peer *client = (struct peer *)handle->data;
+ if (nread < 0) {
+ if (nread != UV_EOF) {
+ fprintf(stdout, "[client] error reading from '%s': %s\n",
+ ip_straddr(&client->addr),
+ uv_err_name(nread));
+ } else {
+ fprintf(stdout, "[client] closing connection with '%s'\n",
+ ip_straddr(&client->addr));
+ }
+ if (client->state == STATE_CONNECTED) {
+ client->state = STATE_CLOSING_IN_PROGRESS;
+ uv_close((uv_handle_t*)handle, on_client_close);
+ }
+ return;
+ }
+
+ struct tls_proxy_ctx *proxy = get_proxy(client);
+ if (proxy->a->accept_only) {
+ fprintf(stdout, "[client] ignoring %zd bytes from '%s'\n", nread, ip_straddr(&client->addr));
+ return;
+ }
+ fprintf(stdout, "[client] reading %zd bytes from '%s'\n", nread, ip_straddr(&client->addr));
+
+ int res = tls_process_from_client(client, (const uint8_t *)buf->base, nread);
+ if (res < 0) {
+ if (client->state == STATE_CONNECTED) {
+ client->state = STATE_CLOSING_IN_PROGRESS;
+ uv_close((uv_handle_t*)&client->handle, on_client_close);
+ }
+ }
+}
+
+static void read_from_upstream_cb(uv_stream_t *handle, ssize_t nread, const uv_buf_t *buf)
+{
+ fprintf(stdout, "[upstream] reading %zd bytes\n", nread);
+ if (nread == 0) {
+ return;
+ }
+ struct peer *upstream = (struct peer *)handle->data;
+ if (nread < 0) {
+ if (nread != UV_EOF) {
+ fprintf(stdout, "[upstream] error reading from upstream: %s\n", uv_err_name(nread));
+ } else {
+ fprintf(stdout, "[upstream] closing connection\n");
+ }
+ clear_pending_bufs(upstream);
+ if (upstream->state == STATE_CONNECTED) {
+ upstream->state = STATE_CLOSING_IN_PROGRESS;
+ uv_close((uv_handle_t*)&upstream->handle, on_upstream_close);
+ }
+ return;
+ }
+ int res = tls_process_from_upstream(upstream, (const uint8_t *)buf->base, nread);
+ if (res < 0) {
+ fprintf(stdout, "[upstream] error processing tls data to client\n");
+ if (upstream->peer->state == STATE_CONNECTED) {
+ upstream->peer->state = STATE_CLOSING_IN_PROGRESS;
+ uv_close((uv_handle_t*)&upstream->peer->handle, on_client_close);
+ }
+ }
+}
+
+static void push_to_upstream_pending(struct peer *upstream, const char *buf, size_t size)
+{
+ struct buf *b = alloc_io_buffer(size);
+ memcpy(b->buf, buf, b->size);
+ array_push(upstream->pending_buf, b);
+}
+
+static void push_to_client_pending(struct peer *client, const char *buf, size_t size)
+{
+ struct tls_proxy_ctx *proxy = get_proxy(client);
+ while (size > 0) {
+ int temp_size = size;
+ if (proxy->a->rehandshake && temp_size > CLIENT_ANSWER_CHUNK_SIZE) {
+ temp_size = CLIENT_ANSWER_CHUNK_SIZE;
+ }
+ struct buf *b = alloc_io_buffer(temp_size);
+ memcpy(b->buf, buf, b->size);
+ array_push(client->pending_buf, b);
+ size -= temp_size;
+ buf += temp_size;
+ }
+}
+
+static int write_to_upstream_pending(struct peer *upstream)
+{
+ struct buf *buf = get_first_pending_buf(upstream);
+ uv_write_t *req = (uv_write_t *) malloc(sizeof(uv_write_t));
+ uv_buf_t wrbuf = uv_buf_init(buf->buf, buf->size);
+ req->data = buf->buf;
+ fprintf(stdout, "[upstream] writing %zd bytes\n", buf->size);
+ return uv_write(req, (uv_stream_t *)&upstream->handle, &wrbuf, 1, write_to_upstream_cb);
+}
+
+static ssize_t proxy_gnutls_pull(gnutls_transport_ptr_t h, void *buf, size_t len)
+{
+ struct peer *peer = (struct peer *)h;
+ struct tls_ctx *t = peer->tls;
+
+ fprintf(stdout, "[gnutls_pull] pulling %zd bytes\n", len);
+
+ if (t->nread <= t->consumed) {
+ errno = EAGAIN;
+ fprintf(stdout, "[gnutls_pull] return EAGAIN\n");
+ return -1;
+ }
+
+ ssize_t avail = t->nread - t->consumed;
+ ssize_t transfer = (avail <= len ? avail : len);
+ memcpy(buf, t->buf + t->consumed, transfer);
+ t->consumed += transfer;
+ return transfer;
+}
+
+ssize_t proxy_gnutls_push(gnutls_transport_ptr_t h, const void *buf, size_t len)
+{
+ struct peer *client = (struct peer *)h;
+ fprintf(stdout, "[gnutls_push] writing %zd bytes\n", len);
+
+ ssize_t ret = -1;
+ const size_t req_size_aligned = ((sizeof(uv_write_t) / 16) + 1) * 16;
+ char *common_buf = malloc(req_size_aligned + len);
+ uv_write_t *req = (uv_write_t *) common_buf;
+ char *data = common_buf + req_size_aligned;
+ const uv_buf_t uv_buf[1] = {
+ { data, len }
+ };
+ memcpy(data, buf, len);
+ int res = uv_write(req, (uv_stream_t *)&client->handle, uv_buf, 1, write_to_client_cb);
+ if (res == 0) {
+ ret = len;
+ client->active_requests += 1;
+ } else {
+ free(common_buf);
+ errno = EIO;
+ }
+ return ret;
+}
+
+static int write_to_client_pending(struct peer *client)
+{
+ if (client->pending_buf.len == 0) {
+ return 0;
+ }
+
+ struct tls_proxy_ctx *proxy = get_proxy(client);
+ struct buf *buf = get_first_pending_buf(client);
+ fprintf(stdout, "[client] writing %zd bytes\n", buf->size);
+
+ gnutls_session_t tls_session = client->tls->session;
+ assert(client->tls->handshake_state != TLS_HS_IN_PROGRESS);
+
+ char *data = buf->buf;
+ size_t len = buf->size;
+
+ ssize_t count = 0;
+ ssize_t submitted = len;
+ ssize_t retries = 0;
+ do {
+ count = gnutls_record_send(tls_session, data, len);
+ if (count < 0) {
+ if (gnutls_error_is_fatal(count)) {
+ fprintf(stdout, "[client] gnutls_record_send failed: %s (%zd)\n",
+ gnutls_strerror_name(count), count);
+ return -1;
+ }
+ if (++retries > TLS_MAX_SEND_RETRIES) {
+ fprintf(stdout, "[client] gnutls_record_send: too many sequential non-fatal errors (%zd), last error is: %s (%zd)\n",
+ retries, gnutls_strerror_name(count), count);
+ return -1;
+ }
+ } else if (count != 0) {
+ data += count;
+ len -= count;
+ retries = 0;
+ } else {
+ if (++retries < TLS_MAX_SEND_RETRIES) {
+ continue;
+ }
+ fprintf(stdout, "[client] gnutls_record_send: too many retries (%zd)\n",
+ retries);
+ fprintf(stdout, "[client] tls_push_to_client didn't send all data(%zd of %zd)\n",
+ len, submitted);
+ return -1;
+ }
+ } while (len > 0);
+
+ remove_first_pending_buf(client);
+ free_io_buffer(buf);
+
+ fprintf(stdout, "[client] submitted %zd bytes\n", submitted);
+ if (proxy->a->rehandshake) {
+ int err = GNUTLS_E_SUCCESS;
+#if GNUTLS_VERSION_NUMBER >= 0x030604
+ if (proxy->a->tls_13) {
+ int flags = gnutls_session_get_flags(tls_session);
+ if ((flags & GNUTLS_SFLAGS_POST_HANDSHAKE_AUTH) == 0) {
+ /* Client doesn't support post-handshake re-authentication,
+ * nothing to test here */
+ fprintf(stdout, "[client] GNUTLS_SFLAGS_POST_HANDSHAKE_AUTH flag not detected\n");
+ assert(false);
+ }
+ err = gnutls_reauth(tls_session, 0);
+ if (err != GNUTLS_E_INTERRUPTED &&
+ err != GNUTLS_E_AGAIN &&
+ err != GNUTLS_E_GOT_APPLICATION_DATA) {
+ fprintf(stdout, "[client] gnutls_reauth() failed: %s (%i)\n",
+ gnutls_strerror_name(err), err);
+ } else {
+ fprintf(stdout, "[client] post-handshake authentication initiated\n");
+ }
+ client->tls->handshake_state = TLS_HS_REAUTH_EXPECTED;
+ } else {
+ assert (gnutls_safe_renegotiation_status(tls_session) != 0);
+ err = gnutls_rehandshake(tls_session);
+ if (err != GNUTLS_E_SUCCESS) {
+ fprintf(stdout, "[client] gnutls_rehandshake() failed: %s (%i)\n",
+ gnutls_strerror_name(err), err);
+ assert(false);
+ } else {
+ fprintf(stdout, "[client] rehandshake started\n");
+ }
+ client->tls->handshake_state = TLS_HS_EXPECTED;
+ }
+#else
+ assert (gnutls_safe_renegotiation_status(tls_session) != 0);
+ err = gnutls_rehandshake(tls_session);
+ if (err != GNUTLS_E_SUCCESS) {
+ fprintf(stdout, "[client] gnutls_rehandshake() failed: %s (%i)\n",
+ gnutls_strerror_name(err), err);
+ assert(false);
+ } else {
+ fprintf(stdout, "[client] rehandshake started\n");
+ }
+ /* Prevent write-to-client callback from sending next pending chunk.
+ * At the same time tls_process_from_client() must not call gnutls_handshake()
+ * as there can be application data in this direction. */
+ client->tls->handshake_state = TLS_HS_EXPECTED;
+#endif
+ }
+ return submitted;
+}
+
+static int tls_process_from_upstream(struct peer *upstream, const uint8_t *buf, ssize_t len)
+{
+ struct peer *client = upstream->peer;
+
+ fprintf(stdout, "[upstream] pushing %zd bytes to client\n", len);
+
+ ssize_t submitted = 0;
+ if (client->state != STATE_CONNECTED) {
+ return submitted;
+ }
+
+ bool list_was_empty = (client->pending_buf.len == 0);
+ push_to_client_pending(client, (const char *)buf, len);
+ submitted = len;
+ if (client->tls->handshake_state == TLS_HS_DONE) {
+ if (list_was_empty && client->pending_buf.len > 0) {
+ int ret = write_to_client_pending(client);
+ if (ret < 0) {
+ submitted = -1;
+ }
+ }
+ }
+
+ return submitted;
+}
+
+int tls_process_handshake(struct peer *peer)
+{
+ struct tls_ctx *tls = peer->tls;
+ int ret = 1;
+ while (tls->handshake_state == TLS_HS_IN_PROGRESS) {
+ fprintf(stdout, "[tls] TLS handshake in progress...\n");
+ int err = gnutls_handshake(tls->session);
+ if (err == GNUTLS_E_SUCCESS) {
+ tls->handshake_state = TLS_HS_DONE;
+ fprintf(stdout, "[tls] TLS handshake has completed\n");
+ ret = 1;
+ if (peer->pending_buf.len != 0) {
+ write_to_client_pending(peer);
+ }
+ } else if (gnutls_error_is_fatal(err)) {
+ fprintf(stdout, "[tls] gnutls_handshake failed: %s (%d)\n",
+ gnutls_strerror_name(err), err);
+ ret = -1;
+ break;
+ } else {
+ fprintf(stdout, "[tls] gnutls_handshake nonfatal error: %s (%d)\n",
+ gnutls_strerror_name(err), err);
+ ret = 0;
+ break;
+ }
+ }
+ return ret;
+}
+
+#if GNUTLS_VERSION_NUMBER >= 0x030604
+int tls_process_reauth(struct peer *peer)
+{
+ struct tls_ctx *tls = peer->tls;
+ int ret = 1;
+ while (tls->handshake_state == TLS_HS_REAUTH_EXPECTED) {
+ fprintf(stdout, "[tls] TLS re-authentication in progress...\n");
+ int err = gnutls_reauth(tls->session, 0);
+ if (err == GNUTLS_E_SUCCESS) {
+ tls->handshake_state = TLS_HS_DONE;
+ fprintf(stdout, "[tls] TLS re-authentication has completed\n");
+ ret = 1;
+ if (peer->pending_buf.len != 0) {
+ write_to_client_pending(peer);
+ }
+ } else if (err != GNUTLS_E_INTERRUPTED &&
+ err != GNUTLS_E_AGAIN &&
+ err != GNUTLS_E_GOT_APPLICATION_DATA) {
+ /* these are listed as nonfatal errors there
+ * https://www.gnutls.org/manual/gnutls.html#gnutls_005freauth */
+ fprintf(stdout, "[tls] gnutls_reauth failed: %s (%d)\n",
+ gnutls_strerror_name(err), err);
+ ret = -1;
+ break;
+ } else {
+ fprintf(stdout, "[tls] gnutls_reauth nonfatal error: %s (%d)\n",
+ gnutls_strerror_name(err), err);
+ ret = 0;
+ break;
+ }
+ }
+ return ret;
+}
+#endif
+
+int tls_process_from_client(struct peer *client, const uint8_t *buf, ssize_t nread)
+{
+ struct tls_ctx *tls = client->tls;
+
+ tls->buf = buf;
+ tls->nread = nread >= 0 ? nread : 0;
+ tls->consumed = 0;
+
+ fprintf(stdout, "[client] tls_process: reading %zd bytes from client\n", nread);
+
+ int ret = 0;
+ if (tls->handshake_state == TLS_HS_REAUTH_EXPECTED) {
+ ret = tls_process_reauth(client);
+ } else {
+ ret = tls_process_handshake(client);
+ }
+ if (ret <= 0) {
+ return ret;
+ }
+
+ int submitted = 0;
+ while (true) {
+ ssize_t count = gnutls_record_recv(tls->session, tls->recv_buf, sizeof(tls->recv_buf));
+ if (count == GNUTLS_E_AGAIN) {
+ break; /* No data available */
+ } else if (count == GNUTLS_E_INTERRUPTED) {
+ continue; /* Try reading again */
+ } else if (count == GNUTLS_E_REHANDSHAKE) {
+ tls->handshake_state = TLS_HS_IN_PROGRESS;
+ ret = tls_process_handshake(client);
+ if (ret < 0) { /* Critical error */
+ return ret;
+ }
+ if (ret == 0) { /* Non fatal, most likely GNUTLS_E_AGAIN */
+ break;
+ }
+ continue;
+ }
+#if GNUTLS_VERSION_NUMBER >= 0x030604
+ else if (count == GNUTLS_E_REAUTH_REQUEST) {
+ assert(false);
+ tls->handshake_state = TLS_HS_IN_PROGRESS;
+ ret = tls_process_reauth(client);
+ if (ret < 0) { /* Critical error */
+ return ret;
+ }
+ if (ret == 0) { /* Non fatal, most likely GNUTLS_E_AGAIN */
+ break;
+ }
+ continue;
+ }
+#endif
+ else if (count < 0) {
+ fprintf(stdout, "[client] gnutls_record_recv failed: %s (%zd)\n",
+ gnutls_strerror_name(count), count);
+ assert(false);
+ return -1;
+ } else if (count == 0) {
+ break;
+ }
+ struct peer *upstream = client->peer;
+ if (upstream->state == STATE_CONNECTED) {
+ bool upstream_pending_is_empty = (upstream->pending_buf.len == 0);
+ push_to_upstream_pending(upstream, (const char *)tls->recv_buf, count);
+ if (upstream_pending_is_empty) {
+ write_to_upstream_pending(upstream);
+ }
+ } else if (upstream->state == STATE_NOT_CONNECTED) {
+ uv_connect_t *conn = (uv_connect_t *) malloc(sizeof(uv_connect_t));
+ upstream->state = STATE_CONNECT_IN_PROGRESS;
+ fprintf(stdout, "[client] connecting to upstream '%s'\n", ip_straddr(&upstream->addr));
+ uv_tcp_connect(conn, &upstream->handle, (struct sockaddr *)&upstream->addr,
+ on_connect_to_upstream);
+ push_to_upstream_pending(upstream, (const char *)tls->recv_buf, count);
+ } else if (upstream->state == STATE_CONNECT_IN_PROGRESS) {
+ push_to_upstream_pending(upstream, (const char *)tls->recv_buf, count);
+ }
+ submitted += count;
+ }
+ return submitted;
+}
+
+struct tls_proxy_ctx *tls_proxy_allocate()
+{
+ return malloc(sizeof(struct tls_proxy_ctx));
+}
+
+int tls_proxy_init(struct tls_proxy_ctx *proxy, const struct args *a)
+{
+ const char *server_addr = a->local_addr;
+ int server_port = a->local_port;
+ const char *upstream_addr = a->upstream;
+ int upstream_port = a->upstream_port;
+ const char *cert_file = a->cert_file;
+ const char *key_file = a->key_file;
+ proxy->a = a;
+ proxy->loop = uv_default_loop();
+ uv_tcp_init(proxy->loop, &proxy->server.handle);
+ int res = uv_ip4_addr(server_addr, server_port, (struct sockaddr_in *)&proxy->server.addr);
+ if (res != 0) {
+ res = uv_ip6_addr(server_addr, server_port, (struct sockaddr_in6 *)&proxy->server.addr);
+ if (res != 0) {
+ fprintf(stdout, "[proxy] tls_proxy_init: can't parse local address '%s'\n", server_addr);
+ return -1;
+ }
+ }
+ res = uv_ip4_addr(upstream_addr, upstream_port, (struct sockaddr_in *)&proxy->upstream_addr);
+ if (res != 0) {
+ res = uv_ip6_addr(upstream_addr, upstream_port, (struct sockaddr_in6 *)&proxy->upstream_addr);
+ if (res != 0) {
+ fprintf(stdout, "[proxy] tls_proxy_init: can't parse upstream address '%s'\n", upstream_addr);
+ return -1;
+ }
+ }
+ array_init(proxy->client_list);
+ proxy->conn_sequence = 0;
+
+ proxy->loop->data = proxy;
+
+ int err = 0;
+ if (gnutls_references == 0) {
+ err = gnutls_global_init();
+ if (err != GNUTLS_E_SUCCESS) {
+ fprintf(stdout, "[proxy] gnutls_global_init() failed: (%d) %s\n",
+ err, gnutls_strerror_name(err));
+ return -1;
+ }
+ }
+ gnutls_references += 1;
+
+ err = gnutls_certificate_allocate_credentials(&proxy->tls_credentials);
+ if (err != GNUTLS_E_SUCCESS) {
+ fprintf(stdout, "[proxy] gnutls_certificate_allocate_credentials() failed: (%d) %s\n",
+ err, gnutls_strerror_name(err));
+ return -1;
+ }
+
+ err = gnutls_certificate_set_x509_system_trust(proxy->tls_credentials);
+ if (err <= 0) {
+ fprintf(stdout, "[proxy] gnutls_certificate_set_x509_system_trust() failed: (%d) %s\n",
+ err, gnutls_strerror_name(err));
+ return -1;
+ }
+
+ if (cert_file && key_file) {
+ err = gnutls_certificate_set_x509_key_file(proxy->tls_credentials,
+ cert_file, key_file, GNUTLS_X509_FMT_PEM);
+ if (err != GNUTLS_E_SUCCESS) {
+ fprintf(stdout, "[proxy] gnutls_certificate_set_x509_key_file() failed: (%d) %s\n",
+ err, gnutls_strerror_name(err));
+ return -1;
+ }
+ }
+
+ err = gnutls_priority_init(&proxy->tls_priority_cache, NULL, NULL);
+ if (err != GNUTLS_E_SUCCESS) {
+ fprintf(stdout, "[proxy] gnutls_priority_init() failed: (%d) %s\n",
+ err, gnutls_strerror_name(err));
+ return -1;
+ }
+
+ return 0;
+}
+
+void tls_proxy_free(struct tls_proxy_ctx *proxy)
+{
+ if (!proxy) {
+ return;
+ }
+ while (proxy->client_list.len > 0) {
+ size_t last_index = proxy->client_list.len - 1;
+ struct peer *client = proxy->client_list.at[last_index];
+ clear_pending_bufs(client);
+ clear_pending_bufs(client->peer);
+ /* TODO correctly close all the uv_tcp_t */
+ free(client->peer);
+ free(client);
+ array_del(proxy->client_list, last_index);
+ }
+ gnutls_certificate_free_credentials(proxy->tls_credentials);
+ gnutls_priority_deinit(proxy->tls_priority_cache);
+ free(proxy);
+
+ gnutls_references -= 1;
+ if (gnutls_references == 0) {
+ gnutls_global_deinit();
+ }
+}
+
+int tls_proxy_start_listen(struct tls_proxy_ctx *proxy)
+{
+ uv_tcp_bind(&proxy->server.handle, (const struct sockaddr*)&proxy->server.addr, 0);
+ int ret = uv_listen((uv_stream_t*)&proxy->server.handle, 128, on_client_connection);
+ return ret;
+}
+
+int tls_proxy_run(struct tls_proxy_ctx *proxy)
+{
+ return uv_run(proxy->loop, UV_RUN_DEFAULT);
+}
diff --git a/tests/pytests/proxy/tls-proxy.h b/tests/pytests/proxy/tls-proxy.h
new file mode 100644
index 0000000..2dbd9fd
--- /dev/null
+++ b/tests/pytests/proxy/tls-proxy.h
@@ -0,0 +1,34 @@
+#pragma once
+/* SPDX-License-Identifier: GPL-3.0-or-later */
+
+#define __STDC_FORMAT_MACROS
+#include <inttypes.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <netinet/in.h>
+
+struct args {
+ const char *local_addr;
+ uint16_t local_port;
+ const char *upstream;
+ uint16_t upstream_port;
+
+ bool rehandshake;
+ bool close_connection;
+ bool accept_only;
+ bool tls_13;
+
+ uint64_t close_timeout;
+ uint32_t max_conn_sequence;
+
+ const char *cert_file;
+ const char *key_file;
+};
+
+struct tls_proxy_ctx;
+
+struct tls_proxy_ctx *tls_proxy_allocate();
+void tls_proxy_free(struct tls_proxy_ctx *proxy);
+int tls_proxy_init(struct tls_proxy_ctx *proxy, const struct args *a);
+int tls_proxy_start_listen(struct tls_proxy_ctx *proxy);
+int tls_proxy_run(struct tls_proxy_ctx *proxy);
diff --git a/tests/pytests/proxy/tlsproxy.c b/tests/pytests/proxy/tlsproxy.c
new file mode 100644
index 0000000..bcdffb0
--- /dev/null
+++ b/tests/pytests/proxy/tlsproxy.c
@@ -0,0 +1,198 @@
+/* SPDX-License-Identifier: GPL-3.0-or-later */
+
+#include <stdio.h>
+#include <getopt.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <errno.h>
+#include <string.h>
+#include <gnutls/gnutls.h>
+#include "tls-proxy.h"
+
+static char default_local_addr[] = "127.0.0.1";
+static char default_upstream_addr[] = "127.0.0.1";
+static char default_cert_path[] = "../certs/tt.cert.pem";
+static char default_key_path[] = "../certs/tt.key.pem";
+
+void help(char *argv[], struct args *a)
+{
+ printf("Usage: %s [parameters] [rundir]\n", argv[0]);
+ printf("\nParameters:\n"
+ " -l, --local=[addr] Server address to bind to (default: %s).\n"
+ " -p, --lport=[port] Server port to bind to (default: %u).\n"
+ " -u, --upstream=[addr] Upstream address (default: %s).\n"
+ " -d, --uport=[port] Upstream port (default: %u).\n"
+ " -t, --cert=[path] Path to certificate file (default: %s).\n"
+ " -k, --key=[path] Path to key file (default: %s).\n"
+ " -c, --close=[N] Close connection to client after\n"
+ " every N ms (default: %" PRIu64 ").\n"
+ " -f, --fail=[N] Delay every Nth incoming connection by 10 sec,\n"
+ " 0 disables delaying (default: 0).\n"
+ " -r, --rehandshake Do TLS rehandshake after every 8 bytes\n"
+ " sent to the client (default: no).\n"
+ " -a, --acceptonly Accept incoming connections, but don't\n"
+ " connect to upstream (default: no).\n"
+ " -v, --tls13 Force use of TLSv1.3. If not turned on,\n"
+ " TLSv1.2 will be used (default: no).\n"
+ ,
+ a->local_addr, a->local_port,
+ a->upstream, a->upstream_port,
+ a->cert_file, a->key_file,
+ a->close_timeout);
+}
+
+void init_args(struct args *a)
+{
+ a->local_addr = default_local_addr;
+ a->local_port = 54000;
+ a->upstream = default_upstream_addr;
+ a->upstream_port = 53000;
+ a->cert_file = default_cert_path;
+ a->key_file = default_key_path;
+ a->rehandshake = false;
+ a->accept_only = false;
+ a->tls_13 = false;
+ a->close_connection = false;
+ a->close_timeout = 1000;
+ a->max_conn_sequence = 0; /* disabled */
+}
+
+int main(int argc, char **argv)
+{
+ long int li_value = 0;
+ int c = 0, li = 0;
+ struct option opts[] = {
+ {"local", required_argument, 0, 'l'},
+ {"lport", required_argument, 0, 'p'},
+ {"upstream", required_argument, 0, 'u'},
+ {"uport", required_argument, 0, 'd'},
+ {"cert", required_argument, 0, 't'},
+ {"key", required_argument, 0, 'k'},
+ {"close", required_argument, 0, 'c'},
+ {"fail", required_argument, 0, 'f'},
+ {"rehandshake", no_argument, 0, 'r'},
+ {"acceptonly", no_argument, 0, 'a'},
+#if GNUTLS_VERSION_NUMBER >= 0x030604
+ {"tls13", no_argument, 0, 'v'},
+#endif
+ {0, 0, 0, 0}
+ };
+ struct args args;
+ init_args(&args);
+ while ((c = getopt_long(argc, argv, "l:p:u:d:t:k:c:f:rav", opts, &li)) != -1) {
+ switch (c)
+ {
+ case 'l':
+ args.local_addr = optarg;
+ break;
+ case 'u':
+ args.upstream = optarg;
+ break;
+ case 't':
+ args.cert_file = optarg;
+ break;
+ case 'k':
+ args.key_file = optarg;
+ break;
+ case 'p':
+ li_value = strtol(optarg, NULL, 10);
+ if (li_value <= 0 || li_value > UINT16_MAX) {
+ printf("error: '-p' requires a positive"
+ " number less or equal to 65535, not '%s'\n", optarg);
+ return -1;
+ }
+ args.local_port = (uint16_t)li_value;
+ break;
+ case 'd':
+ li_value = strtol(optarg, NULL, 10);
+ if (li_value <= 0 || li_value > UINT16_MAX) {
+ printf("error: '-d' requires a positive"
+ " number less or equal to 65535, not '%s'\n", optarg);
+ return -1;
+ }
+ args.upstream_port = (uint16_t)li_value;
+ break;
+ case 'c':
+ li_value = strtol(optarg, NULL, 10);
+ if (li_value <= 0) {
+ printf("[system] error '-c' requires a positive"
+ " number, not '%s'\n", optarg);
+ return -1;
+ }
+ args.close_connection = true;
+ args.close_timeout = li_value;
+ break;
+ case 'f':
+ li_value = strtol(optarg, NULL, 10);
+ if (li_value <= 0 || li_value > UINT32_MAX) {
+ printf("error: '-f' requires a positive"
+ " number less or equal to %i, not '%s'\n",
+ UINT32_MAX, optarg);
+ return -1;
+ }
+ args.max_conn_sequence = (uint32_t)li_value;
+ break;
+ case 'r':
+ args.rehandshake = true;
+ break;
+ case 'a':
+ args.accept_only = true;
+ break;
+ case 'v':
+#if GNUTLS_VERSION_NUMBER >= 0x030604
+ args.tls_13 = true;
+#endif
+ break;
+ default:
+ init_args(&args);
+ help(argv, &args);
+ return -1;
+ }
+ }
+ if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) {
+ fprintf(stderr, "failed to set up SIGPIPE handler to ignore(%s)\n",
+ strerror(errno));
+ }
+ struct tls_proxy_ctx *proxy = tls_proxy_allocate();
+ if (!proxy) {
+ fprintf(stderr, "can't allocate tls_proxy structure\n");
+ return 1;
+ }
+ int res = tls_proxy_init(proxy, &args);
+ if (res) {
+ fprintf(stderr, "can't initialize tls_proxy structure\n");
+ return res;
+ }
+ res = tls_proxy_start_listen(proxy);
+ if (res) {
+ fprintf(stderr, "error starting listen, error code: %i\n", res);
+ return res;
+ }
+ fprintf(stdout, "Listen on %s#%u\n"
+ "Upstream is expected on %s#%u\n"
+ "Certificate file %s\n"
+ "Key file %s\n"
+ "Rehandshake %s\n"
+ "Close %s\n"
+ "Refuse incoming connections every %ith%s\n"
+ "Only accept, don't forward %s\n"
+ "Force TLSv1.3 %s\n"
+ ,
+ args.local_addr, args.local_port,
+ args.upstream, args.upstream_port,
+ args.cert_file, args.key_file,
+ args.rehandshake ? "yes" : "no",
+ args.close_connection ? "yes" : "no",
+ args.max_conn_sequence, args.max_conn_sequence ? "" : " (disabled)",
+ args.accept_only ? "yes" : "no",
+#if GNUTLS_VERSION_NUMBER >= 0x030604
+ args.tls_13 ? "yes" : "no"
+#else
+ "Not supported"
+#endif
+ );
+ res = tls_proxy_run(proxy);
+ tls_proxy_free(proxy);
+ return res;
+}
+
diff --git a/tests/pytests/pylintrc b/tests/pytests/pylintrc
new file mode 100644
index 0000000..2c406be
--- /dev/null
+++ b/tests/pytests/pylintrc
@@ -0,0 +1,33 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+[MESSAGES CONTROL]
+
+disable=
+ missing-docstring,
+ too-few-public-methods,
+ too-many-arguments,
+ too-many-instance-attributes,
+ fixme,
+ unused-import, # checked by flake8
+ line-too-long, # checked by flake8
+ invalid-name,
+ broad-except,
+ bad-continuation,
+ global-statement,
+ no-else-return,
+ redefined-outer-name, # commonly used with pytest fixtures
+ consider-using-with,
+ consider-using-f-string,
+
+
+[SIMILARITIES]
+min-similarity-lines=6
+ignore-comments=yes
+ignore-docstrings=yes
+ignore-imports=no
+
+[DESIGN]
+max-parents=10
+max-locals=20
+
+[TYPECHECK]
+ignored-modules=ssl
diff --git a/tests/pytests/requirements.txt b/tests/pytests/requirements.txt
new file mode 100644
index 0000000..6e2e4d2
--- /dev/null
+++ b/tests/pytests/requirements.txt
@@ -0,0 +1,5 @@
+dnspython
+jinja2
+pytest
+pytest-html
+pytest-xdist
diff --git a/tests/pytests/templates/kresd.conf.j2 b/tests/pytests/templates/kresd.conf.j2
new file mode 100644
index 0000000..b87515c
--- /dev/null
+++ b/tests/pytests/templates/kresd.conf.j2
@@ -0,0 +1,62 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+modules = {
+ 'hints > policy',
+ 'policy > iterate',
+}
+
+{% if kresd.verbose %}
+log_level('debug')
+{% endif %}
+
+{% if kresd.ip %}
+net.listen('{{ kresd.ip }}', {{ kresd.port }})
+net.listen('{{ kresd.ip }}', {{ kresd.tls_port }}, {tls = true})
+{% endif %}
+
+{% if kresd.ip6 %}
+net.listen('{{ kresd.ip6 }}', {{ kresd.port }})
+net.listen('{{ kresd.ip6 }}', {{ kresd.tls_port }}, {tls = true})
+{% endif %}
+
+net.ipv4=true
+net.ipv6=true
+
+{% if kresd.tls_key_path and kresd.tls_cert_path %}
+net.tls("{{ kresd.tls_cert_path }}", "{{ kresd.tls_key_path }}")
+net.tls_sticket_secret('0123456789ABCDEF0123456789ABCDEF')
+{% endif %}
+
+hints['localhost.'] = '127.0.0.1'
+{% for name, ip in kresd.hints.items() %}
+hints['{{ name }}'] = '{{ ip }}'
+{% endfor %}
+
+policy.add(policy.all(policy.QTRACE))
+
+{% if kresd.forward %}
+policy.add(policy.all(
+ {% if kresd.forward.proto == 'tls' %}
+ policy.TLS_FORWARD({
+ {"{{ kresd.forward.ip }}@{{ kresd.forward.port }}", hostname='{{ kresd.forward.hostname}}', ca_file='{{ kresd.forward.ca_file }}'}})
+ {% endif %}
+))
+{% endif %}
+
+{% if kresd.policy_test_pass %}
+policy.add(policy.suffix(policy.PASS, {todname('test.')}))
+{% endif %}
+
+-- EDNS EDE tests
+policy.add(policy.suffix(policy.DENY, {todname('deny.test.')}))
+policy.add(policy.suffix(policy.REFUSE, {todname('refuse.test.')}))
+policy.add(policy.suffix(policy.ANSWER({ [kres.type.A] = { rdata=kres.str2ip('192.0.2.7'), ttl=300 } }), {todname('forge.test.')}))
+
+-- make sure DNSSEC is turned off for tests
+trust_anchors.remove('.')
+modules.unload("ta_update")
+modules.unload("ta_signal_query")
+modules.unload("priming")
+modules.unload("detect_time_skew")
+
+-- choose a small cache, since it is preallocated
+cache.size = 1 * MB
diff --git a/tests/pytests/test_conn_mgmt.py b/tests/pytests/test_conn_mgmt.py
new file mode 100644
index 0000000..1d15091
--- /dev/null
+++ b/tests/pytests/test_conn_mgmt.py
@@ -0,0 +1,214 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+"""TCP Connection Management tests"""
+
+import socket
+import struct
+import time
+
+import pytest
+
+import utils
+
+
+@pytest.mark.parametrize('garbage_lengths', [
+ (1,),
+ (1024,),
+ (65533,), # max size garbage
+ (65533, 65533),
+ (1024, 1024, 1024),
+ # (0,), # currently kresd uses this as a heuristic of "lost in bytestream"
+ # (0, 1024), # and closes the connection
+])
+def test_ignore_garbage(kresd_sock, garbage_lengths, single_buffer, query_before):
+ """Send chunk of garbage, prefixed by garbage length. It should be ignored."""
+ buff = b''
+ if query_before: # optionally send initial query
+ msg_buff_before, msgid_before = utils.get_msgbuff()
+ if single_buffer:
+ buff += msg_buff_before
+ else:
+ kresd_sock.sendall(msg_buff_before)
+
+ for glength in garbage_lengths: # prepare garbage data
+ if glength is None:
+ continue
+ garbage_buff = utils.get_prefixed_garbage(glength)
+ if single_buffer:
+ buff += garbage_buff
+ else:
+ kresd_sock.sendall(garbage_buff)
+
+ msg_buff, msgid = utils.get_msgbuff() # final query
+ buff += msg_buff
+ kresd_sock.sendall(buff)
+
+ if query_before:
+ answer_before = utils.receive_parse_answer(kresd_sock)
+ assert answer_before.id == msgid_before
+ answer = utils.receive_parse_answer(kresd_sock)
+ assert answer.id == msgid
+
+
+def test_pipelining(kresd_sock):
+ """
+ First query takes longer to resolve - answer to second query should arrive sooner.
+
+ This test requires internet connection.
+ """
+ # initialization (to avoid issues with net.ipv6=true)
+ buff_pre, msgid_pre = utils.get_msgbuff('0.delay.getdnsapi.net.')
+ kresd_sock.sendall(buff_pre)
+ msg_answer = utils.receive_parse_answer(kresd_sock)
+ assert msg_answer.id == msgid_pre
+
+ # test
+ buff1, msgid1 = utils.get_msgbuff('1500.delay.getdnsapi.net.', msgid=1)
+ buff2, msgid2 = utils.get_msgbuff('1.delay.getdnsapi.net.', msgid=2)
+ buff = buff1 + buff2
+ kresd_sock.sendall(buff)
+
+ msg_answer = utils.receive_parse_answer(kresd_sock)
+ assert msg_answer.id == msgid2
+
+ msg_answer = utils.receive_parse_answer(kresd_sock)
+ assert msg_answer.id == msgid1
+
+
+@pytest.mark.parametrize('duration, delay', [
+ (utils.MAX_TIMEOUT, 0.1),
+ (utils.MAX_TIMEOUT, 3),
+ (utils.MAX_TIMEOUT, 7),
+ (utils.MAX_TIMEOUT + 10, 3),
+])
+def test_long_lived(kresd_sock, duration, delay):
+ """Establish and keep connection alive for longer than maximum timeout."""
+ utils.ping_alive(kresd_sock)
+ end_time = time.time() + duration
+
+ while time.time() < end_time:
+ time.sleep(delay)
+ utils.ping_alive(kresd_sock)
+
+
+def test_close(kresd_sock, query_before):
+ """Establish a connection and wait for timeout from kresd."""
+ if query_before:
+ utils.ping_alive(kresd_sock)
+ time.sleep(utils.MAX_TIMEOUT)
+
+ with utils.expect_kresd_close():
+ utils.ping_alive(kresd_sock)
+
+
+def test_slow_lorris(kresd_sock, query_before):
+ """Simulate slow-lorris attack by sending byte after byte with delays in between."""
+ if query_before:
+ utils.ping_alive(kresd_sock)
+
+ buff, _ = utils.get_msgbuff()
+ end_time = time.time() + utils.MAX_TIMEOUT
+
+ with utils.expect_kresd_close():
+ for i in range(len(buff)):
+ b = buff[i:i+1]
+ kresd_sock.send(b)
+ if time.time() > end_time:
+ break
+ time.sleep(1)
+
+
+@pytest.mark.parametrize('sock_func_name', [
+ 'ip_tcp_socket',
+ 'ip6_tcp_socket',
+])
+def test_oob(kresd, sock_func_name):
+ """TCP out-of-band (urgent) data must not crash resolver."""
+ make_sock = getattr(kresd, sock_func_name)
+ sock = make_sock()
+ msg_buff, msgid = utils.get_msgbuff()
+ sock.sendall(msg_buff, socket.MSG_OOB)
+
+ try:
+ msg_answer = utils.receive_parse_answer(sock)
+ assert msg_answer.id == msgid
+ except ConnectionError:
+ pass # TODO kresd responds with TCP RST, this should be fixed
+
+ # check kresd is alive
+ sock2 = make_sock()
+ utils.ping_alive(sock2)
+
+
+def flood_buffer(msgcount):
+ flood_buff = bytes()
+ msgbuff, _ = utils.get_msgbuff()
+ noid_msgbuff = msgbuff[2:]
+
+ def gen_msg(msgid):
+ return struct.pack("!H", len(msgbuff)) + struct.pack("!H", msgid) + noid_msgbuff
+
+ for i in range(msgcount):
+ flood_buff += gen_msg(i)
+ return flood_buff
+
+
+def test_query_flood_close(make_kresd_sock):
+ """Flood resolver with queries and close the connection."""
+ buff = flood_buffer(10000)
+ sock1 = make_kresd_sock()
+ sock1.sendall(buff)
+ sock1.close()
+
+ sock2 = make_kresd_sock()
+ utils.ping_alive(sock2)
+
+
+def test_query_flood_no_recv(make_kresd_sock):
+ """Flood resolver with queries but don't read any data."""
+ # A use-case for TCP_USER_TIMEOUT socket option? See RFC 793 and RFC 5482
+
+ # It seems it doesn't works as expected. libuv doesn't return any error
+ # (neither on uv_write() call, not in the callback) when kresd sends answers,
+ # so kresd can't recognize that client didn't read any answers. At a certain
+ # point, kresd stops receiving queries from the client (whilst client keep
+ # sending) and closes connection due to timeout.
+
+ buff = flood_buffer(10000)
+ sock1 = make_kresd_sock()
+ end_time = time.time() + utils.MAX_TIMEOUT
+
+ with utils.expect_kresd_close(rst_ok=True): # connection must be closed
+ while time.time() < end_time:
+ sock1.sendall(buff)
+ time.sleep(0.5)
+
+ sock2 = make_kresd_sock()
+ utils.ping_alive(sock2) # resolver must stay alive
+
+
+@pytest.mark.parametrize('glength, gcount, delay', [
+ (65533, 100, 0.5),
+ (0, 100000, 0.5),
+ (1024, 1000, 0.5),
+ (65533, 1, 0),
+ (0, 1, 0),
+ (1024, 1, 0),
+])
+def test_query_flood_garbage(make_kresd_silent_sock, glength, gcount, delay, query_before):
+ """Flood resolver with prefixed garbage."""
+ sock1 = make_kresd_silent_sock()
+ if query_before:
+ utils.ping_alive(sock1)
+
+ gbuff = utils.get_prefixed_garbage(glength)
+ buff = gbuff * gcount
+
+ end_time = time.time() + utils.MAX_TIMEOUT
+
+ with utils.expect_kresd_close(rst_ok=True): # connection must be closed
+ while time.time() < end_time:
+ sock1.sendall(buff)
+ time.sleep(delay)
+
+ sock2 = make_kresd_silent_sock()
+ utils.ping_alive(sock2) # resolver must stay alive
diff --git a/tests/pytests/test_edns.py b/tests/pytests/test_edns.py
new file mode 100644
index 0000000..b19af37
--- /dev/null
+++ b/tests/pytests/test_edns.py
@@ -0,0 +1,22 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+"""EDNS tests"""
+
+import dns
+import pytest
+
+import utils
+
+
+@pytest.mark.parametrize('dname, code, text', [
+ ('deny.test.', dns.edns.EDECode.BLOCKED, 'CR36'),
+ ('refuse.test.', dns.edns.EDECode.PROHIBITED, 'EIM4'),
+ ('forge.test.', dns.edns.EDECode.FORGED_ANSWER, '5DO5'),
+])
+def test_edns_ede(kresd_sock, dname, code, text):
+ """Check that kresd responds with EDNS EDE codes in selected cases."""
+ buff, msgid = utils.get_msgbuff(dname)
+ kresd_sock.sendall(buff)
+ answer = utils.receive_parse_answer(kresd_sock)
+ assert answer.id == msgid
+ assert answer.options[0].code == code
+ assert answer.options[0].text == text
diff --git a/tests/pytests/test_prefix.py b/tests/pytests/test_prefix.py
new file mode 100644
index 0000000..2b576b6
--- /dev/null
+++ b/tests/pytests/test_prefix.py
@@ -0,0 +1,114 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+"""TCP Connection Management tests - prefix length
+
+RFC1035
+4.2.2. TCP usage
+The message is prefixed with a two byte length field which gives the message
+length, excluding the two byte length field.
+
+The following test suite focuses on edge cases for the prefix - when it
+is either too short or too long, instead of matching the length of DNS
+message exactly.
+"""
+
+import time
+
+import pytest
+
+import utils
+
+
+@pytest.fixture(params=[
+ 'no_query_before',
+ 'query_before',
+ 'query_before_in_single_buffer',
+])
+def send_query(request):
+ """Function sends a buffer, either by itself, or with a valid query before.
+ If a valid query is sent before, it can be sent either in a separate buffer, or
+ along with the provided buffer."""
+
+ # pylint: disable=possibly-unused-variable
+
+ def no_query_before(sock, buff): # pylint: disable=unused-argument
+ sock.sendall(buff)
+
+ def query_before(sock, buff, single_buffer=False):
+ """Send an initial query and expect a response."""
+ msg_buff, msgid = utils.get_msgbuff()
+
+ if single_buffer:
+ sock.sendall(msg_buff + buff)
+ else:
+ sock.sendall(msg_buff)
+ sock.sendall(buff)
+
+ answer = utils.receive_parse_answer(sock)
+ assert answer.id == msgid
+
+ def query_before_in_single_buffer(sock, buff):
+ return query_before(sock, buff, single_buffer=True)
+
+ return locals()[request.param]
+
+
+@pytest.mark.parametrize('datalen', [
+ 1, # just one byte of DNS header
+ 11, # DNS header size minus 1
+ 14, # DNS Header size plus 2
+])
+def test_prefix_cuts_message(kresd_sock, datalen, send_query):
+ """Prefix is shorter than the DNS message."""
+ wire, _ = utils.prepare_wire()
+ assert datalen < len(wire)
+ invalid_buff = utils.prepare_buffer(wire, datalen)
+
+ send_query(kresd_sock, invalid_buff) # buffer breaks parsing of TCP stream
+
+ with utils.expect_kresd_close():
+ utils.ping_alive(kresd_sock)
+
+
+def test_prefix_greater_than_message(kresd_sock, send_query):
+ """Prefix is greater than the length of the entire DNS message."""
+ wire, invalid_msgid = utils.prepare_wire()
+ datalen = len(wire) + 16
+ invalid_buff = utils.prepare_buffer(wire, datalen)
+
+ send_query(kresd_sock, invalid_buff)
+
+ valid_buff, _ = utils.get_msgbuff()
+ kresd_sock.sendall(valid_buff)
+
+ # invalid_buff is answered (treats additional data as trailing garbage)
+ answer = utils.receive_parse_answer(kresd_sock)
+ assert answer.id == invalid_msgid
+
+ # parsing stream is broken by the invalid_buff, valid query is never answered
+ with utils.expect_kresd_close():
+ utils.receive_parse_answer(kresd_sock)
+
+
+@pytest.mark.parametrize('glength', [
+ 0,
+ 1,
+ 8,
+ 1024,
+ 4096,
+ 20000,
+])
+def test_prefix_trailing_garbage(kresd_sock, glength, query_before):
+ """Send messages with trailing garbage (its length included in prefix)."""
+ if query_before:
+ utils.ping_alive(kresd_sock)
+
+ for _ in range(10):
+ wire, msgid = utils.prepare_wire()
+ wire += utils.get_garbage(glength)
+ buff = utils.prepare_buffer(wire)
+
+ kresd_sock.sendall(buff)
+ answer = utils.receive_parse_answer(kresd_sock)
+ assert answer.id == msgid
+
+ time.sleep(0.1)
diff --git a/tests/pytests/test_random_close.py b/tests/pytests/test_random_close.py
new file mode 100644
index 0000000..a7cc877
--- /dev/null
+++ b/tests/pytests/test_random_close.py
@@ -0,0 +1,54 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+"""TLS test when forward target closes connection after one second
+
+Test utilizes TLS proxy, which forwards queries to configured
+resolver, but closes the connection 1s after establishing.
+
+Kresd must stay alive and be able to answer queries.
+"""
+
+import random
+import string
+import time
+
+from proxy import HINTS, kresd_tls_client, resolve_hint, TLSProxy
+import utils
+
+
+QPS = 500
+
+
+def random_string(size=32, chars=(string.ascii_lowercase + string.digits)):
+ return ''.join(random.choice(chars) for x in range(size))
+
+
+def rsa_cannon(sock, duration, domain='test.', qps=QPS):
+ end_time = time.time() + duration
+
+ while time.time() < end_time:
+ next_time = time.time() + 1/qps
+ buff, _ = utils.get_msgbuff('{}.{}'.format(random_string(), domain))
+ sock.sendall(buff)
+ time_left = next_time - time.time()
+ if time_left > 0:
+ time.sleep(time_left)
+
+
+def test_proxy_random_close(tmpdir):
+ proxy = TLSProxy(close=1000)
+
+ kresd_tls_client_kwargs = {
+ 'verbose': False,
+ 'policy_test_pass': True
+ }
+ kresd_fwd_target_kwargs = {
+ 'verbose': False
+ }
+ with kresd_tls_client(str(tmpdir), proxy, kresd_tls_client_kwargs, kresd_fwd_target_kwargs) \
+ as kresd:
+ sock2 = kresd.ip_tcp_socket()
+ rsa_cannon(sock2, 20)
+ sock3 = kresd.ip_tcp_socket()
+ for hint in HINTS:
+ resolve_hint(sock3, hint)
+ time.sleep(0.1)
diff --git a/tests/pytests/test_rehandshake.py b/tests/pytests/test_rehandshake.py
new file mode 100644
index 0000000..f07ba58
--- /dev/null
+++ b/tests/pytests/test_rehandshake.py
@@ -0,0 +1,52 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+"""TLS rehandshake test
+
+Test is using TLS proxy with rehandshake. When queries are sent, they are
+simply forwarded. When the responses are sent back, a rehandshake is performed
+after every 8 bytes.
+
+It is expected the answer will be received by the source kresd instance
+and sent back to the client (this test).
+"""
+
+import re
+import time
+
+import pytest
+
+from proxy import HINTS, kresd_tls_client, resolve_hint, TLSProxy
+
+
+def verify_rehandshake(tmpdir, proxy):
+ with kresd_tls_client(str(tmpdir), proxy) as kresd:
+ sock2 = kresd.ip_tcp_socket()
+ try:
+ for hint in HINTS:
+ resolve_hint(sock2, hint)
+ time.sleep(0.1)
+ finally:
+ # verify log
+ n_connecting_to = 0
+ n_rehandshake = 0
+ partial_log = kresd.partial_log()
+ print(partial_log)
+ for line in partial_log.splitlines():
+ if re.search(r"connecting to: .*", line) is not None:
+ n_connecting_to += 1
+ elif re.search(r"TLS rehandshake .* has started", line) is not None:
+ n_rehandshake += 1
+ assert n_connecting_to == 1 # should connect exactly once
+ assert n_rehandshake > 0
+
+
+def test_proxy_rehandshake_tls12(tmpdir):
+ proxy = TLSProxy(rehandshake=True)
+ verify_rehandshake(tmpdir, proxy)
+
+
+# TODO fix TLS v1.3 proxy / kresd rehandshake
+@pytest.mark.xfail(
+ reason="TLS 1.3 rehandshake isn't properly supported either in tlsproxy or in kresd")
+def test_proxy_rehandshake_tls13(tmpdir):
+ proxy = TLSProxy(rehandshake=True, force_tls13=True)
+ verify_rehandshake(tmpdir, proxy)
diff --git a/tests/pytests/test_tls.py b/tests/pytests/test_tls.py
new file mode 100644
index 0000000..3e1328a
--- /dev/null
+++ b/tests/pytests/test_tls.py
@@ -0,0 +1,83 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+"""TLS-specific tests"""
+
+import itertools
+import os
+from socket import AF_INET, AF_INET6
+import ssl
+import sys
+
+import pytest
+
+from kresd import make_kresd
+import utils
+
+
+def test_tls_no_cert(kresd, sock_family):
+ """Use TLS without certificates."""
+ sock, dest = kresd.stream_socket(sock_family, tls=True)
+ ctx = utils.make_ssl_context(insecure=True)
+ ssock = ctx.wrap_socket(sock)
+ ssock.connect(dest)
+
+ utils.ping_alive(ssock)
+
+
+def test_tls_selfsigned_cert(kresd_tt, sock_family):
+ """Use TLS with a self signed certificate."""
+ sock, dest = kresd_tt.stream_socket(sock_family, tls=True)
+ ctx = utils.make_ssl_context(verify_location=kresd_tt.tls_cert_path)
+ ssock = ctx.wrap_socket(sock, server_hostname='transport-test-server.com')
+ ssock.connect(dest)
+
+ utils.ping_alive(ssock)
+
+
+def test_tls_cert_hostname_mismatch(kresd_tt, sock_family):
+ """Attempt to use self signed certificate and incorrect hostname."""
+ sock, dest = kresd_tt.stream_socket(sock_family, tls=True)
+ ctx = utils.make_ssl_context(verify_location=kresd_tt.tls_cert_path)
+ ssock = ctx.wrap_socket(sock, server_hostname='wrong-host-name')
+
+ with pytest.raises(ssl.CertificateError):
+ ssock.connect(dest)
+
+
+@pytest.mark.skipif(sys.version_info < (3, 6),
+ reason="requires python3.6 or higher")
+@pytest.mark.parametrize('sf1, sf2, sf3', itertools.product(
+ [AF_INET, AF_INET6], [AF_INET, AF_INET6], [AF_INET, AF_INET6]))
+def test_tls_session_resumption(tmpdir, sf1, sf2, sf3):
+ """Attempt TLS session resumption against the same kresd instance and a different one."""
+ # TODO ensure that session can't be resumed after session ticket key regeneration
+ # at the first kresd instance
+
+ # NOTE TLS 1.3 is intentionally disabled for session resumption tests,
+ # because python's SSLSocket.session isn't compatible with TLS 1.3
+ # https://docs.python.org/3/library/ssl.html?highlight=ssl%20ticket#tls-1-3
+
+ def connect(kresd, ctx, sf, session=None):
+ sock, dest = kresd.stream_socket(sf, tls=True)
+ ssock = ctx.wrap_socket(
+ sock, server_hostname='transport-test-server.com', session=session)
+ ssock.connect(dest)
+ new_session = ssock.session
+ assert new_session.has_ticket
+ assert ssock.session_reused == (session is not None)
+ utils.ping_alive(ssock)
+ ssock.close()
+ return new_session
+
+ workdir = os.path.join(str(tmpdir), 'kresd')
+ os.makedirs(workdir)
+
+ with make_kresd(workdir, 'tt') as kresd:
+ ctx = utils.make_ssl_context(
+ verify_location=kresd.tls_cert_path, extra_options=[ssl.OP_NO_TLSv1_3])
+ session = connect(kresd, ctx, sf1) # initial conn
+ connect(kresd, ctx, sf2, session) # resume session on the same instance
+
+ workdir2 = os.path.join(str(tmpdir), 'kresd2')
+ os.makedirs(workdir2)
+ with make_kresd(workdir2, 'tt') as kresd2:
+ connect(kresd2, ctx, sf3, session) # resume session on a different instance
diff --git a/tests/pytests/utils.py b/tests/pytests/utils.py
new file mode 100644
index 0000000..4b995d4
--- /dev/null
+++ b/tests/pytests/utils.py
@@ -0,0 +1,136 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+from contextlib import contextmanager
+import random
+import ssl
+import struct
+import time
+
+import dns
+import dns.message
+import pytest
+
+
+# default net.tcp_in_idle is 10s, TCP_DEFER_ACCEPT 3s, some extra for
+# Python handling / edge cases
+MAX_TIMEOUT = 16
+
+
+def receive_answer(sock):
+ answer_total_len = 0
+ data = sock.recv(2)
+ if not data:
+ return None
+ answer_total_len = struct.unpack_from("!H", data)[0]
+
+ answer_received_len = 0
+ data_answer = b''
+ while answer_received_len < answer_total_len:
+ data_chunk = sock.recv(answer_total_len - answer_received_len)
+ if not data_chunk:
+ return None
+ data_answer += data_chunk
+ answer_received_len += len(data_answer)
+
+ return data_answer
+
+
+def receive_parse_answer(sock):
+ data_answer = receive_answer(sock)
+
+ if data_answer is None:
+ raise BrokenPipeError("kresd closed connection")
+
+ msg_answer = dns.message.from_wire(data_answer, one_rr_per_rrset=True)
+ return msg_answer
+
+
+def prepare_wire(
+ qname='localhost.',
+ qtype=dns.rdatatype.A,
+ qclass=dns.rdataclass.IN,
+ msgid=None):
+ """Utility function to generate DNS wire format message"""
+ msg = dns.message.make_query(qname, qtype, qclass, use_edns=True)
+ if msgid is not None:
+ msg.id = msgid
+ return msg.to_wire(), msg.id
+
+
+def prepare_buffer(wire, datalen=None):
+ """Utility function to prepare TCP buffer from DNS message in wire format"""
+ assert isinstance(wire, bytes)
+ if datalen is None:
+ datalen = len(wire)
+ return struct.pack("!H", datalen) + wire
+
+
+def get_msgbuff(qname='localhost.', qtype=dns.rdatatype.A, msgid=None):
+ wire, msgid = prepare_wire(qname, qtype, msgid=msgid)
+ buff = prepare_buffer(wire)
+ return buff, msgid
+
+
+def get_garbage(length):
+ return bytes(random.getrandbits(8) for _ in range(length))
+
+
+def get_prefixed_garbage(length):
+ data = get_garbage(length)
+ return prepare_buffer(data)
+
+
+def try_ping_alive(sock, msgid=None, close=False):
+ try:
+ ping_alive(sock, msgid)
+ except AssertionError:
+ return False
+ finally:
+ if close:
+ sock.close()
+ return True
+
+
+def ping_alive(sock, msgid=None):
+ buff, msgid = get_msgbuff(msgid=msgid)
+ sock.sendall(buff)
+ answer = receive_parse_answer(sock)
+ assert answer.id == msgid
+
+
+@contextmanager
+def expect_kresd_close(rst_ok=False):
+ with pytest.raises(BrokenPipeError):
+ try:
+ time.sleep(0.2) # give kresd time to close connection with TCP FIN
+ yield
+ except ConnectionResetError as ex:
+ if rst_ok:
+ raise BrokenPipeError from ex
+ pytest.skip("kresd closed connection with TCP RST")
+ pytest.fail("kresd didn't close the connection")
+
+
+def make_ssl_context(insecure=False, verify_location=None, extra_options=None):
+ # set TLS v1.2+
+ context = ssl.SSLContext(ssl.PROTOCOL_TLS)
+ context.options |= ssl.OP_NO_SSLv2
+ context.options |= ssl.OP_NO_SSLv3
+ context.options |= ssl.OP_NO_TLSv1
+ context.options |= ssl.OP_NO_TLSv1_1
+
+ if extra_options is not None:
+ for option in extra_options:
+ context.options |= option
+
+ if insecure:
+ # turn off certificate verification
+ context.check_hostname = False
+ context.verify_mode = ssl.CERT_NONE
+ else:
+ context.verify_mode = ssl.CERT_REQUIRED
+ context.check_hostname = True
+
+ if verify_location is not None:
+ context.load_verify_locations(verify_location)
+
+ return context
diff --git a/tests/unit/meson.build b/tests/unit/meson.build
new file mode 100644
index 0000000..b10789c
--- /dev/null
+++ b/tests/unit/meson.build
@@ -0,0 +1,37 @@
+# tests: unit
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# mock module for test_module
+mock_cmodule_src = files([
+ 'mock_cmodule.c',
+])
+
+mock_cmodule_mod = shared_module(
+ 'mock_cmodule',
+ mock_cmodule_src,
+ name_prefix: '',
+ dependencies: libknot,
+ include_directories: mod_inc_dir,
+)
+
+# executables with tests
+foreach unit_test : unit_tests
+ exec_test = executable(
+ unit_test[0],
+ unit_test[1],
+ dependencies: [
+ contrib_dep,
+ libkres_dep,
+ libknot,
+ cmocka,
+ lmdb,
+ ],
+ )
+ test(
+ 'unit.' + unit_test[0],
+ exec_test,
+ suite: 'unit',
+ # they take very short time
+ kwargs: meson.version().version_compare('<0.52') ? {} : { 'priority': -5 },
+ )
+endforeach
diff --git a/tests/unit/mock_cmodule.c b/tests/unit/mock_cmodule.c
new file mode 100644
index 0000000..9cc9d1a
--- /dev/null
+++ b/tests/unit/mock_cmodule.c
@@ -0,0 +1,21 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#include "lib/module.h"
+
+/*
+ * Mock module implementation.
+ */
+
+int mock_cmodule_init(struct kr_module *module)
+{
+ return kr_ok();
+}
+
+int mock_cmodule_deinit(struct kr_module *module)
+{
+ return kr_ok();
+}
+
+KR_MODULE_EXPORT(mock_cmodule)
diff --git a/tests/unit/packaging/debian/10/builddeps b/tests/unit/packaging/debian/10/builddeps
new file mode 100644
index 0000000..5c2068b
--- /dev/null
+++ b/tests/unit/packaging/debian/10/builddeps
@@ -0,0 +1 @@
+libcmocka-dev
diff --git a/tests/unit/packaging/test.sh b/tests/unit/packaging/test.sh
new file mode 100755
index 0000000..8212dcd
--- /dev/null
+++ b/tests/unit/packaging/test.sh
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+test -e build_packaging/tests/unit/mock_cmodule.so
diff --git a/tests/unit/test.h b/tests/unit/test.h
new file mode 100644
index 0000000..9a7eb58
--- /dev/null
+++ b/tests/unit/test.h
@@ -0,0 +1,110 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#include <stdlib.h>
+#include <stdarg.h>
+#include <stddef.h>
+#include <setjmp.h>
+#include <limits.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <dirent.h>
+#include <unistd.h>
+#include <cmocka.h>
+
+/* Silence clang/GCC warnings when using cmocka 1.0 */
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+
+#include "lib/defines.h"
+#include "lib/utils.h"
+#include <libknot/descriptor.h>
+#include <libknot/rrset.h>
+
+/* Helpers */
+static inline void *mm_test_malloc(void *ctx, size_t n)
+{ return test_malloc(n); }
+static inline void mm_test_free(void *p)
+{ if (p) test_free(p); }
+
+/** Memory context using CMocka allocator. */
+static inline void test_mm_ctx_init(knot_mm_t *mm)
+{
+ mm->alloc = &mm_test_malloc;
+ mm->free = &mm_test_free;
+}
+
+/** Recursively delete directory. */
+static inline int test_tmpdir_remove(const char *path)
+{
+ char buf[512];
+ struct dirent *ent = NULL;
+ DIR *dir = opendir(path);
+ if (dir == NULL) {
+ return kr_error(errno);
+ }
+ while ((ent = readdir(dir)) != NULL) {
+ /* Skip special dirs (this presumes no files begin with '.') */
+ if (ent->d_name[0] == '.') {
+ continue;
+ }
+ sprintf(buf, "%s/%s", path, ent->d_name);
+ remove(buf);
+ }
+ remove(path);
+ closedir(dir);
+ return 0;
+}
+
+/** Create temporary directory. */
+static inline const char* test_tmpdir_create(void)
+{
+ static char env_path[64];
+ strcpy(env_path, "./tmpXXXXXX");
+ return mkdtemp(env_path);
+}
+
+/** Generate random string with given length. */
+static inline void test_randstr(char* dst, size_t len)
+{
+ if (len == 0) {
+ return;
+ }
+
+ for (int i = 0; i < len - 1; ++i) {
+ dst[i] = '0' + (int) (('Z'-'0') * (rand() / (RAND_MAX + 1.0)));
+ }
+ dst[len - 1] = '\0';
+ return;
+}
+
+/** Init RRSet with type TXT, random owner and random payload.
+ * @note Static memory reused, copy it if you need persistence.
+ */
+static inline void test_random_rr(knot_rrset_t *rr, uint32_t ttl)
+{
+ static uint8_t owner_buf[KNOT_DNAME_MAXLEN] = { 0 };
+ static uint8_t rdata_buf[65535];
+ knot_rdata_t *rdata = (knot_rdata_t *)rdata_buf;
+
+ uint16_t num = rand() % (sizeof(owner_buf) - 2);
+ uint8_t tmp_buf[KNOT_DNAME_MAXLEN];
+
+ /* Create random label. */
+ uint8_t label_len = num % KNOT_DNAME_MAXLABELLEN;
+ owner_buf[0] = label_len;
+ test_randstr((char *)(owner_buf + 1), label_len);
+
+ /* Create payload */
+ tmp_buf[0] = num;
+ test_randstr((char *)(tmp_buf + 1), tmp_buf[0] + 1);
+ knot_rdata_init(rdata, num + 1, tmp_buf);
+
+ /* Assign static buffers. */
+ knot_rrset_init(rr, owner_buf, KNOT_RRTYPE_TXT, KNOT_CLASS_IN, ttl);
+ rr->rrs.count = 1;
+ rr->rrs.rdata = rdata;
+}
+
diff --git a/utils/cache_gc/.gitignore b/utils/cache_gc/.gitignore
new file mode 100644
index 0000000..86ce5b1
--- /dev/null
+++ b/utils/cache_gc/.gitignore
@@ -0,0 +1,2 @@
+kres_cache_gc
+
diff --git a/utils/cache_gc/README.rst b/utils/cache_gc/README.rst
new file mode 100644
index 0000000..8d991b2
--- /dev/null
+++ b/utils/cache_gc/README.rst
@@ -0,0 +1,20 @@
+.. SPDX-License-Identifier: GPL-3.0-or-later
+
+.. _garbage-collector:
+
+Garbage Collector
+-----------------
+
+.. note:: When using systemd, ``kres-cache-gc.service`` is enabled by default
+ and does not need any manual configuration.
+
+Knot Resolver employs a separate garbage collector daemon which periodically
+trims the cache to keep its size below size limit configured using
+:envvar:`cache.size`.
+
+To execute the daemon manually, you can use the following command to run it
+every second:
+
+.. code-block:: bash
+
+ $ kres-cache-gc -c /var/cache/knot-resolver -d 1000
diff --git a/utils/cache_gc/categories.c b/utils/cache_gc/categories.c
new file mode 100644
index 0000000..19dec45
--- /dev/null
+++ b/utils/cache_gc/categories.c
@@ -0,0 +1,56 @@
+/* SPDX-License-Identifier: GPL-3.0-or-later */
+#include "categories.h"
+
+#include <libknot/libknot.h>
+#include "lib/utils.h"
+
+static bool rrtype_is_infrastructure(uint16_t r)
+{
+ switch (r) {
+ case KNOT_RRTYPE_NS:
+ case KNOT_RRTYPE_DS:
+ case KNOT_RRTYPE_DNSKEY:
+ case KNOT_RRTYPE_A:
+ case KNOT_RRTYPE_AAAA:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static int get_random(int to)
+{
+ // We don't need these to be really unpredictable,
+ // but this should be cheap enough not to be noticeable.
+ return kr_rand_bytes(1) % to;
+}
+
+// TODO this is just an example, make this more clever
+category_t kr_gc_categorize(gc_record_info_t * info)
+{
+ category_t res;
+
+ if (!info->valid)
+ return CATEGORIES - 1;
+
+ switch (info->no_labels) {
+ case 0: /* root zone */
+ res = 5;
+ break;
+ case 1: /* TLD */
+ res = 10;
+ break;
+ default: /* SLD and below */
+ res = (rrtype_is_infrastructure(info->rrtype) ? 15 : 20);
+ if (info->entry_size > 300)
+ /* Penalty for big answers */
+ res += 30;
+ break;
+ }
+
+ if (info->expires_in <= 0) {
+ res += 40;
+ }
+
+ return res + get_random(5);
+}
diff --git a/utils/cache_gc/categories.h b/utils/cache_gc/categories.h
new file mode 100644
index 0000000..388fbe7
--- /dev/null
+++ b/utils/cache_gc/categories.h
@@ -0,0 +1,10 @@
+/* SPDX-License-Identifier: GPL-3.0-or-later */
+#pragma once
+
+#include "kr_cache_gc.h"
+
+typedef uint8_t category_t;
+
+#define CATEGORIES 100 // number of categories
+
+category_t kr_gc_categorize(gc_record_info_t * info);
diff --git a/utils/cache_gc/db.c b/utils/cache_gc/db.c
new file mode 100644
index 0000000..fc4a2fd
--- /dev/null
+++ b/utils/cache_gc/db.c
@@ -0,0 +1,280 @@
+/* SPDX-License-Identifier: GPL-3.0-or-later */
+
+#include "db.h"
+
+#include "lib/cache/cdb_lmdb.h"
+#include "lib/cache/impl.h"
+
+#include <ctype.h>
+#include <time.h>
+#include <sys/stat.h>
+
+int kr_gc_cache_open(const char *cache_path, struct kr_cache *kres_db,
+ knot_db_t ** libknot_db)
+{
+ char cache_data[strlen(cache_path) + 10];
+ snprintf(cache_data, sizeof(cache_data), "%s/data.mdb", cache_path);
+
+ struct stat st = { 0 };
+ if (stat(cache_path, &st) || !(st.st_mode & S_IFDIR)
+ || stat(cache_data, &st)) {
+ printf("Error: %s does not exist or is not a LMDB.\n", cache_path);
+ return -ENOENT;
+ }
+
+ struct kr_cdb_opts opts = { .path = cache_path, .maxsize = 0/*don't resize*/ };
+
+ int ret = kr_cache_open(kres_db, NULL, &opts, NULL);
+ if (ret || kres_db->db == NULL) {
+ printf("Error opening Resolver cache (%s).\n", kr_strerror(ret));
+ return -EINVAL;
+ }
+
+ *libknot_db = kr_cdb_pt2knot_db_t(kres_db->db);
+ if (*libknot_db == NULL) {
+ printf("Out of memory.\n");
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
+int kr_gc_cache_check_health(struct kr_cache *kres_db, knot_db_t ** libknot_db)
+{
+ int ret = kr_cache_check_health(kres_db, 0);
+ if (ret == 0) {
+ return 0;
+ } else if (ret != 1) {
+ kr_gc_cache_close(kres_db, *libknot_db);
+ return ret;
+ }
+ /* Cache was reopen. */
+ free(*libknot_db);
+ *libknot_db = kr_cdb_pt2knot_db_t(kres_db->db);
+ if (*libknot_db == NULL) {
+ printf("Out of memory.\n");
+ return -ENOMEM;
+ }
+ return 0;
+}
+
+void kr_gc_cache_close(struct kr_cache *kres_db, knot_db_t * knot_db)
+{
+ free(knot_db);
+ kr_cache_close(kres_db);
+}
+
+int kr_gc_key_consistent(knot_db_val_t key)
+{
+ const uint8_t *kd = key.data;
+ ssize_t i;
+ /* CACHE_KEY_DEF */
+ if (key.len >= 2 && kd[0] == '\0') {
+ /* Beware: root zone is special and starts with
+ * a single \0 followed by type sign */
+ i = 1;
+ } else {
+ /* find the first double zero in the key */
+ for (i = 2; kd[i - 1] || kd[i - 2]; ++i) {
+ if (kr_fails_assert(i < key.len))
+ return kr_error(EINVAL);
+ }
+ }
+ // the next character can be used for classification
+ switch (kd[i]) {
+ case 'E':
+ (void)0; // C can't have a variable definition following a label
+ uint16_t type;
+ if (kr_fails_assert(i + 1 + sizeof(type) <= key.len))
+ return kr_error(EINVAL);
+ memcpy(&type, kd + i + 1, sizeof(type));
+ return type;
+ case '1':
+ return KNOT_RRTYPE_NSEC;
+ case '3':
+ return KNOT_RRTYPE_NSEC3;
+ case 'S': // the rtt_state entries are considered inconsistent, at least for now
+ return -1;
+ default:
+ kr_assert(!EINVAL);
+ return kr_error(EINVAL);
+ }
+}
+
+/// expects that key is consistent! CACHE_KEY_DEF
+static uint8_t entry_labels(knot_db_val_t * key, uint16_t rrtype)
+{
+ uint8_t lab = 0, *p = key->data;
+ while (*p != 0) {
+ while (*p++ != 0) {
+ if (p - (uint8_t *) key->data >= key->len) {
+ return 0;
+ }
+ }
+ lab++;
+ }
+ if (rrtype == KNOT_RRTYPE_NSEC3) {
+ // We don't know the number of labels so easily,
+ // but let's classify everything as directly
+ // below the zone apex (that's most common).
+ ++lab;
+ }
+ return lab;
+}
+
+void debug_printbin(const char *str, unsigned int len)
+{
+ putchar('"');
+ for (int idx = 0; idx < len; idx++) {
+ char c = str[idx];
+ if (isprint(c))
+ putchar(c);
+ else
+ printf("`%02hhx`", c);
+ }
+ putchar('"');
+}
+
+/** Return one entry_h reference from a cache DB value. NULL if not consistent/suitable. */
+static const struct entry_h *val2entry(const knot_db_val_t val, uint16_t ktype)
+{
+ if (ktype != KNOT_RRTYPE_NS)
+ return entry_h_consistent(val, ktype);
+ /* Otherwise we have a multi-purpose entry.
+ * Well, for now we simply choose the most suitable entry;
+ * the only realistic collision is DNAME in apex where we'll prefer NS. */
+ entry_list_t el;
+ if (entry_list_parse(val, el))
+ return NULL;
+ for (int i = ENTRY_APEX_NSECS_CNT; i < EL_LENGTH; ++i) {
+ if (el[i].len)
+ return entry_h_consistent(el[i], EL2RRTYPE(i));
+ }
+ /* Only NSEC* meta-data inside. */
+ return NULL;
+}
+
+int kr_gc_cache_iter(knot_db_t * knot_db, const kr_cache_gc_cfg_t *cfg,
+ kr_gc_iter_callback callback, void *ctx)
+{
+ unsigned int counter_iter = 0;
+ unsigned int counter_gc_consistent = 0;
+ unsigned int counter_kr_consistent = 0;
+
+ knot_db_txn_t txn = { 0 };
+ knot_db_iter_t *it = NULL;
+ const knot_db_api_t *api = knot_db_lmdb_api();
+ gc_record_info_t info = { 0 };
+ int64_t now = time(NULL);
+
+ int ret = api->txn_begin(knot_db, &txn, KNOT_DB_RDONLY);
+ if (ret != KNOT_EOK) {
+ printf("Error starting DB transaction (%s).\n", knot_strerror(ret));
+ return ret;
+ }
+
+ it = api->iter_begin(&txn, KNOT_DB_NOOP); // _FIRST is split for easier debugging
+ if (it == NULL) {
+ printf("Error: failed to create an iterator.\n");
+ api->txn_abort(&txn);
+ return KNOT_ERROR;
+ }
+ it = api->iter_seek(it, NULL, KNOT_DB_FIRST);
+ if (it == NULL)
+ printf("Suspicious: completely empty LMDB at this moment?\n");
+
+ int txn_steps = 0;
+ while (it != NULL) {
+ knot_db_val_t key = { 0 }, val = { 0 };
+ ret = api->iter_key(it, &key);
+ if (ret == KNOT_EOK && key.len == 4 && memcmp("VERS", key.data, 4) == 0) {
+ /* skip DB metadata */
+ goto skip;
+ }
+ if (ret == KNOT_EOK) {
+ ret = api->iter_val(it, &val);
+ }
+ if (ret != KNOT_EOK) {
+ goto error;
+ }
+
+ info.entry_size = key.len + val.len;
+ info.valid = false;
+ const int entry_type = kr_gc_key_consistent(key);
+ const struct entry_h *entry = NULL;
+ if (entry_type >= 0) {
+ counter_gc_consistent++;
+ entry = val2entry(val, entry_type);
+ }
+ /* TODO: perhaps improve some details around here:
+ * - rtt_state entries are considered gc_inconsistent;
+ * therefore they'll be the first to get freed (see kr_gc_categorize())
+ * - xNAME have .rrtype NS
+ * - DNAME hidden on NS name will not be considered here
+ * - if zone has NSEC* meta-data but no NS, it will be seen
+ * here as kr_inconsistent */
+ if (entry != NULL) {
+ info.valid = true;
+ info.rrtype = entry_type;
+ info.expires_in = entry->time + entry->ttl - now;
+ info.no_labels = entry_labels(&key, entry_type);
+ }
+ counter_iter++;
+ counter_kr_consistent += info.valid;
+ if (VERBOSE_STATUS) {
+ if (!entry_type || !entry) { // don't log fully consistent entries
+ printf
+ ("GC %sconsistent, KR %sconsistent, size %zu, key len %zu: ",
+ entry_type ? "" : "in", entry ? "" : "IN",
+ (key.len + val.len), key.len);
+ debug_printbin(key.data, key.len);
+ printf("\n");
+ }
+ }
+ ret = callback(&key, &info, ctx);
+
+ if (ret != KNOT_EOK) {
+ error:
+ printf("Error iterating database (%s).\n",
+ knot_strerror(ret));
+ api->iter_finish(it);
+ api->txn_abort(&txn);
+ return ret;
+ }
+
+ skip: // Advance to the next GC item.
+ if (++txn_steps < cfg->ro_txn_items || !cfg->ro_txn_items/*unlimited*/) {
+ it = api->iter_next(it);
+ } else {
+ /* The transaction has been too long; let's reopen it. */
+ txn_steps = 0;
+ uint8_t key_storage[key.len];
+ memcpy(key_storage, key.data, key.len);
+ key.data = key_storage;
+
+ api->iter_finish(it);
+ api->txn_abort(&txn);
+
+ ret = api->txn_begin(knot_db, &txn, KNOT_DB_RDONLY);
+ if (ret != KNOT_EOK) {
+ printf("Error restarting DB transaction (%s).\n",
+ knot_strerror(ret));
+ return ret;
+ }
+ it = api->iter_begin(&txn, KNOT_DB_NOOP);
+ if (it == NULL) {
+ printf("Error: failed to create an iterator.\n");
+ api->txn_abort(&txn);
+ return KNOT_ERROR;
+ }
+ it = api->iter_seek(it, &key, KNOT_DB_GEQ);
+ // NULL here means we'we reached the end
+ }
+ }
+
+ api->txn_abort(&txn);
+
+ kr_log_debug(CACHE, "iterated %u items, gc consistent %u, kr consistent %u\n",
+ counter_iter, counter_gc_consistent, counter_kr_consistent);
+ return KNOT_EOK;
+}
diff --git a/utils/cache_gc/db.h b/utils/cache_gc/db.h
new file mode 100644
index 0000000..7865471
--- /dev/null
+++ b/utils/cache_gc/db.h
@@ -0,0 +1,37 @@
+/* SPDX-License-Identifier: GPL-3.0-or-later */
+#pragma once
+
+#include <lib/cache/api.h>
+#include <libknot/libknot.h>
+
+#include "kr_cache_gc.h"
+
+int kr_gc_cache_open(const char *cache_path, struct kr_cache *kres_db,
+ knot_db_t ** libknot_db);
+
+/** A wrapper around kr_cdb_api::check_health that keeps libknot_db up to date.
+ * \return zero or negative error code. */
+int kr_gc_cache_check_health(struct kr_cache *kres_db, knot_db_t ** libknot_db);
+
+void kr_gc_cache_close(struct kr_cache *kres_db, knot_db_t * knot_db);
+
+typedef int (*kr_gc_iter_callback)(const knot_db_val_t * key,
+ gc_record_info_t * info, void *ctx);
+
+int kr_gc_cache_iter(knot_db_t * knot_db, const kr_cache_gc_cfg_t *cfg,
+ kr_gc_iter_callback callback, void *ctx);
+
+/** Return RR type corresponding to the key or negative error code.
+ *
+ * Error is returned on unexpected values (those also trigger assertion)
+ * and on other kinds of data in cache (e.g. struct rtt_state).
+ */
+int kr_gc_key_consistent(knot_db_val_t key);
+
+/** Printf a *binary* string in a human-readable way. */
+void debug_printbin(const char *str, unsigned int len);
+
+/** Block run in --verbose mode; optimized when not run. */
+#define VERBOSE_STATUS __builtin_expect(KR_LOG_LEVEL_IS(LOG_DEBUG), false)
+/* TODO: replace when solving GC logging properly */
+
diff --git a/utils/cache_gc/kr_cache_gc.c b/utils/cache_gc/kr_cache_gc.c
new file mode 100644
index 0000000..5978345
--- /dev/null
+++ b/utils/cache_gc/kr_cache_gc.c
@@ -0,0 +1,326 @@
+/* SPDX-License-Identifier: GPL-3.0-or-later */
+// standard includes
+#include <inttypes.h>
+#include <limits.h>
+#include <stdio.h>
+#include <time.h>
+
+// libknot includes
+#include <libknot/libknot.h>
+
+// dynarray is inside libknot since 3.1, but it's differently named
+#ifdef knot_dynarray_declare
+ #define dynarray_declare knot_dynarray_declare
+ #define dynarray_define knot_dynarray_define
+ #define dynarray_foreach knot_dynarray_foreach
+#else
+ #include <contrib/dynarray.h>
+#endif
+
+// resolver includes
+#include <lib/cache/api.h>
+#include <lib/cache/impl.h>
+#include <lib/defines.h>
+#include "lib/cache/cdb_lmdb.h"
+#include "lib/utils.h"
+
+#include "kr_cache_gc.h"
+
+#include "categories.h"
+#include "db.h"
+
+// section: dbval_copy
+
+static knot_db_val_t *dbval_copy(const knot_db_val_t * from)
+{
+ knot_db_val_t *to = malloc(sizeof(knot_db_val_t) + from->len);
+ if (to != NULL) {
+ memcpy(to, from, sizeof(knot_db_val_t));
+ to->data = to + 1; // == ((uit8_t *)to) + sizeof(knot_db_val_t)
+ memcpy(to->data, from->data, from->len);
+ }
+ return to;
+}
+
+// section: rrtype list
+
+dynarray_declare(rrtype, uint16_t, DYNARRAY_VISIBILITY_STATIC, 64)
+ dynarray_define(rrtype, uint16_t, DYNARRAY_VISIBILITY_STATIC)
+static void rrtypelist_add(rrtype_dynarray_t * arr, uint16_t add_type)
+{
+ bool already_present = false;
+ dynarray_foreach(rrtype, uint16_t, i, *arr) {
+ if (*i == add_type) {
+ already_present = true;
+ break;
+ }
+ }
+ if (!already_present) {
+ rrtype_dynarray_add(arr, &add_type);
+ }
+}
+
+static void rrtypelist_print(rrtype_dynarray_t * arr)
+{
+ char type_s[32] = { 0 };
+ dynarray_foreach(rrtype, uint16_t, i, *arr) {
+ knot_rrtype_to_string(*i, type_s, sizeof(type_s));
+ printf(" %s", type_s);
+ }
+ printf("\n");
+}
+
+dynarray_declare(entry, knot_db_val_t *, DYNARRAY_VISIBILITY_STATIC, 256)
+ dynarray_define(entry, knot_db_val_t *, DYNARRAY_VISIBILITY_STATIC)
+static void entry_dynarray_deep_free(entry_dynarray_t * d)
+{
+ dynarray_foreach(entry, knot_db_val_t *, i, *d) {
+ free(*i);
+ }
+ entry_dynarray_free(d);
+}
+
+typedef struct {
+ size_t categories_sizes[CATEGORIES];
+ size_t records;
+} ctx_compute_categories_t;
+
+int cb_compute_categories(const knot_db_val_t * key, gc_record_info_t * info,
+ void *vctx)
+{
+ ctx_compute_categories_t *ctx = vctx;
+ category_t cat = kr_gc_categorize(info);
+ (void)key;
+ ctx->categories_sizes[cat] += info->entry_size;
+ ctx->records++;
+ return KNOT_EOK;
+}
+
+typedef struct {
+ category_t limit_category;
+ entry_dynarray_t to_delete;
+ size_t cfg_temp_keys_space;
+ size_t used_space;
+ size_t oversize_records;
+} ctx_delete_categories_t;
+
+int cb_delete_categories(const knot_db_val_t * key, gc_record_info_t * info,
+ void *vctx)
+{
+ ctx_delete_categories_t *ctx = vctx;
+ category_t cat = kr_gc_categorize(info);
+ if (cat >= ctx->limit_category) {
+ knot_db_val_t *todelete = dbval_copy(key);
+ size_t used = ctx->used_space + key->len + sizeof(*key);
+ if ((ctx->cfg_temp_keys_space > 0 &&
+ used > ctx->cfg_temp_keys_space) || todelete == NULL) {
+ ctx->oversize_records++;
+ free(todelete);
+ } else {
+ entry_dynarray_add(&ctx->to_delete, &todelete);
+ ctx->used_space = used;
+ }
+ }
+ return KNOT_EOK;
+}
+
+struct kr_cache_gc_state {
+ struct kr_cache kres_db;
+ knot_db_t *db;
+};
+
+void kr_cache_gc_free_state(kr_cache_gc_state_t **state)
+{
+ if (kr_fails_assert(state))
+ return;
+ if (!*state) { // not open
+ return;
+ }
+ kr_gc_cache_close(&(*state)->kres_db, (*state)->db);
+ free(*state);
+ *state = NULL;
+}
+
+int kr_cache_gc(kr_cache_gc_cfg_t *cfg, kr_cache_gc_state_t **state)
+{
+ // The whole function works in four "big phases":
+ //// 1. find out whether we should even do analysis and deletion.
+ if (kr_fails_assert(cfg && state))
+ return KNOT_EINVAL;
+ int ret;
+ // Ensure that we have open and "healthy" cache.
+ if (!*state) {
+ *state = calloc(1, sizeof(**state));
+ if (!*state) {
+ return KNOT_ENOMEM;
+ }
+ ret = kr_gc_cache_open(cfg->cache_path, &(*state)->kres_db,
+ &(*state)->db);
+ } else { // To be sure, we guard against the file getting replaced.
+ ret = kr_gc_cache_check_health(&(*state)->kres_db, &(*state)->db);
+ // In particular, missing data.mdb gives us kr_error(ENOENT) == KNOT_ENOENT
+ }
+ if (ret) {
+ free(*state);
+ *state = NULL;
+ return ret;
+ }
+ knot_db_t *const db = (*state)->db; // frequently used shortcut
+
+ const double db_usage = kr_cdb_lmdb()->usage_percent((*state)->kres_db.db);
+ const bool large_usage = db_usage >= cfg->cache_max_usage;
+ if (cfg->dry_run || large_usage || VERBOSE_STATUS) { // don't print this on every size check
+ printf("Usage: %.2lf%%\n", db_usage);
+ }
+ if (cfg->dry_run || !large_usage) {
+ return KNOT_EOK;
+ }
+
+ //// 2. classify all cache items into categories
+ // and compute which categories to delete.
+ kr_timer_t timer_analyze = { 0 }, timer_choose = { 0 }, timer_delete =
+ { 0 }, timer_rw_txn = { 0 };
+
+ kr_timer_start(&timer_analyze);
+ ctx_compute_categories_t cats = { { 0 }
+ };
+ ret = kr_gc_cache_iter(db, cfg, cb_compute_categories, &cats);
+ if (ret != KNOT_EOK) {
+ kr_cache_gc_free_state(state);
+ return ret;
+ }
+
+ //ssize_t amount_tofree = knot_db_lmdb_get_mapsize(db) * cfg->cache_to_be_freed / 100;
+ // Mixing ^^ page usage and entry sizes (key+value lengths) didn't work
+ // too well, probably due to internal fragmentation after some GC cycles.
+ // Therefore let's scale this by the ratio of these two sums.
+ ssize_t cats_sumsize = 0;
+ for (int i = 0; i < CATEGORIES; ++i) {
+ cats_sumsize += cats.categories_sizes[i];
+ }
+ /* use less precise variant to avoid 32-bit overflow */
+ ssize_t amount_tofree = cats_sumsize / 100 * cfg->cache_to_be_freed;
+
+ kr_log_debug(CACHE, "tofree: %zd / %zd\n", amount_tofree, cats_sumsize);
+ if (VERBOSE_STATUS) {
+ for (int i = 0; i < CATEGORIES; i++) {
+ if (cats.categories_sizes[i] > 0) {
+ printf("category %.2d size %zu\n", i,
+ cats.categories_sizes[i]);
+ }
+ }
+ }
+
+ category_t limit_category = CATEGORIES;
+ while (limit_category > 0 && amount_tofree > 0) {
+ amount_tofree -= cats.categories_sizes[--limit_category];
+ }
+
+ printf("Cache analyzed in %.0lf msecs, %zu records, limit category is %d.\n",
+ kr_timer_elapsed(&timer_analyze) * 1000, cats.records, limit_category);
+
+ //// 3. pass whole cache again to collect a list of keys that should be deleted.
+ kr_timer_start(&timer_choose);
+ ctx_delete_categories_t to_del = { 0 };
+ to_del.cfg_temp_keys_space = cfg->temp_keys_space;
+ to_del.limit_category = limit_category;
+ ret = kr_gc_cache_iter(db, cfg, cb_delete_categories, &to_del);
+ if (ret != KNOT_EOK) {
+ entry_dynarray_deep_free(&to_del.to_delete);
+ kr_cache_gc_free_state(state);
+ return ret;
+ }
+ printf
+ ("%zu records to be deleted using %.2lf MBytes of temporary memory, %zu records skipped due to memory limit.\n",
+ to_del.to_delete.size, ((double)to_del.used_space / 1048576.0),
+ to_del.oversize_records);
+
+ //// 4. execute the planned deletions.
+ const knot_db_api_t *api = knot_db_lmdb_api();
+ knot_db_txn_t txn = { 0 };
+ size_t deleted_records = 0, already_gone = 0, rw_txn_count = 0;
+
+ kr_timer_start(&timer_delete);
+ kr_timer_start(&timer_rw_txn);
+ rrtype_dynarray_t deleted_rrtypes = { 0 };
+
+ ret = api->txn_begin(db, &txn, 0);
+ if (ret != KNOT_EOK) {
+ printf("Error starting R/W DB transaction (%s).\n",
+ knot_strerror(ret));
+ entry_dynarray_deep_free(&to_del.to_delete);
+ kr_cache_gc_free_state(state);
+ return ret;
+ }
+
+ dynarray_foreach(entry, knot_db_val_t *, i, to_del.to_delete) {
+ ret = api->del(&txn, *i);
+ switch (ret) {
+ case KNOT_EOK:
+ deleted_records++;
+ const int entry_type = kr_gc_key_consistent(**i);
+ if (entry_type >= 0) // some "inconsistent" entries are OK
+ rrtypelist_add(&deleted_rrtypes, entry_type);
+ break;
+ case KNOT_ENOENT:
+ already_gone++;
+ if (VERBOSE_STATUS) {
+ // kresd normally only inserts (or overwrites),
+ // so it's generally suspicious when a key goes missing.
+ printf("Record already gone (key len %zu): ", (*i)->len);
+ debug_printbin((*i)->data, (*i)->len);
+ printf("\n");
+ }
+ break;
+ case KNOT_ESPACE:
+ printf("Warning: out of space, bailing out to retry later.\n");
+ api->txn_abort(&txn);
+ goto finish;
+ default:
+ printf("Warning: skipping deletion because of error (%s)\n",
+ knot_strerror(ret));
+ api->txn_abort(&txn);
+ ret = api->txn_begin(db, &txn, 0);
+ if (ret != KNOT_EOK) {
+ printf
+ ("Error: can't begin txn because of error (%s)\n",
+ knot_strerror(ret));
+ goto finish;
+ }
+ continue;
+ }
+ if ((cfg->rw_txn_items > 0 &&
+ (deleted_records + already_gone) % cfg->rw_txn_items == 0) ||
+ (cfg->rw_txn_duration > 0 &&
+ kr_timer_elapsed_us(&timer_rw_txn) > cfg->rw_txn_duration)) {
+ ret = api->txn_commit(&txn);
+ if (ret == KNOT_EOK) {
+ rw_txn_count++;
+ usleep(cfg->rw_txn_delay);
+ kr_timer_start(&timer_rw_txn);
+ ret = api->txn_begin(db, &txn, 0);
+ }
+ if (ret != KNOT_EOK) {
+ printf("Error: transaction failed (%s)\n",
+ knot_strerror(ret));
+ goto finish;
+ }
+ }
+ }
+ ret = api->txn_commit(&txn);
+
+finish:
+ printf("Deleted %zu records (%zu already gone) types", deleted_records,
+ already_gone);
+ rrtypelist_print(&deleted_rrtypes);
+ printf("It took %.0lf msecs, %zu transactions (%s)\n\n",
+ kr_timer_elapsed(&timer_delete) * 1000, rw_txn_count, knot_strerror(ret));
+
+ rrtype_dynarray_free(&deleted_rrtypes);
+ entry_dynarray_deep_free(&to_del.to_delete);
+
+ // OK, let's close it in this case.
+ kr_cache_gc_free_state(state);
+
+ return ret;
+}
diff --git a/utils/cache_gc/kr_cache_gc.h b/utils/cache_gc/kr_cache_gc.h
new file mode 100644
index 0000000..c64e99e
--- /dev/null
+++ b/utils/cache_gc/kr_cache_gc.h
@@ -0,0 +1,41 @@
+/* SPDX-License-Identifier: GPL-3.0-or-later */
+#pragma once
+
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+
+typedef struct {
+ size_t entry_size; // amount of bytes occupied in cache by this record
+ bool valid; // fields further down are valid (ignore them if false)
+ int64_t expires_in; // < 0 => already expired
+ uint16_t rrtype;
+ uint8_t no_labels; // 0 == ., 1 == root zone member, 2 == TLD member ...
+ uint8_t rank;
+} gc_record_info_t;
+
+typedef struct {
+ const char *cache_path; // path to the LMDB with resolver cache
+ unsigned long gc_interval; // waiting time between two whole garbage collections in usecs (0 = just one-time cleanup)
+
+ size_t temp_keys_space; // maximum amount of temporary memory for copied keys in bytes (0 = unlimited)
+
+ size_t rw_txn_items; // maximum number of deleted records per RW transaction (0 = unlimited)
+ size_t ro_txn_items; // maximum number of iterated records (RO transactions, 0 = unlimited)
+ unsigned long rw_txn_duration; // maximum duration of RW transaction in usecs (0 = unlimited)
+ unsigned long rw_txn_delay; // waiting time between two RW transactions in usecs
+
+ uint8_t cache_max_usage; // maximum cache usage before triggering GC (percent)
+ uint8_t cache_to_be_freed; // percent of current cache usage to be freed during GC
+
+ bool dry_run;
+} kr_cache_gc_cfg_t;
+
+/** State persisting across kr_cache_gc() invocations (opaque).
+ * NULL pointer represents a clean state. */
+typedef struct kr_cache_gc_state kr_cache_gc_state_t;
+
+/** Do one iteration of cache-size check and (if necessary) GC pass. */
+int kr_cache_gc(kr_cache_gc_cfg_t *cfg, kr_cache_gc_state_t **state);
+void kr_cache_gc_free_state(kr_cache_gc_state_t **state);
+
diff --git a/utils/cache_gc/main.c b/utils/cache_gc/main.c
new file mode 100644
index 0000000..2e863e6
--- /dev/null
+++ b/utils/cache_gc/main.c
@@ -0,0 +1,163 @@
+/* SPDX-License-Identifier: GPL-3.0-or-later */
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "lib/defines.h"
+#include "lib/utils.h"
+#include <libknot/libknot.h>
+#include <lmdb.h>
+
+#include "kresconfig.h"
+#include "kr_cache_gc.h"
+
+volatile static int killed = 0;
+
+static void got_killed(int signum)
+{
+ (void)signum;
+ switch (++killed) {
+ case 1:
+ break;
+ case 2:
+ exit(5);
+ break;
+ case 3:
+ abort();
+ default:
+ kr_assert(false);
+ }
+}
+
+static void print_help()
+{
+ printf("Usage: kr_cache_gc -c <resolver_cache> [ optional params... ]\n");
+ printf("Optional params:\n");
+ printf(" -d <garbage_interval(millis)>\n");
+ printf(" -l <deletes_per_txn>\n");
+ printf(" -L <reads_per_txn>\n");
+ printf(" -m <rw_txn_duration(usecs)>\n");
+ printf(" -u <cache_max_usage(percent)>\n");
+ printf(" -f <cache_to_be_freed(percent-of-current-usage)>\n");
+ printf(" -w <wait_next_rw_txn(usecs)>\n");
+ printf(" -t <temporary_memory(MBytes)>\n");
+ printf(" -n (= dry run)\n");
+}
+
+static long get_nonneg_optarg()
+{
+ char *end;
+ const long result = strtol(optarg, &end, 10);
+ if (result >= 0 && end && *end == '\0')
+ return result;
+ // not OK
+ print_help();
+ exit(2);
+}
+
+int main(int argc, char *argv[])
+{
+ printf("Knot Resolver Cache Garbage Collector, version %s\n", PACKAGE_VERSION);
+ if (setvbuf(stdout, NULL, _IONBF, 0) || setvbuf(stderr, NULL, _IONBF, 0)) {
+ fprintf(stderr, "Failed to to set output buffering (ignored): %s\n",
+ strerror(errno));
+ fflush(stderr);
+ }
+
+ signal(SIGTERM, got_killed);
+ signal(SIGKILL, got_killed);
+ signal(SIGPIPE, got_killed);
+ signal(SIGCHLD, got_killed);
+ signal(SIGINT, got_killed);
+
+ kr_cache_gc_cfg_t cfg = {
+ .ro_txn_items = 200,
+ .rw_txn_items = 100,
+ .cache_max_usage = 80,
+ .cache_to_be_freed = 10
+ };
+
+ int o;
+ while ((o = getopt(argc, argv, "hnvc:d:l:L:m:u:f:w:t:")) != -1) {
+ switch (o) {
+ case 'c':
+ cfg.cache_path = optarg;
+ break;
+ case 'd':
+ cfg.gc_interval = get_nonneg_optarg();
+ cfg.gc_interval *= 1000;
+ break;
+ case 'l':
+ cfg.rw_txn_items = get_nonneg_optarg();
+ break;
+ case 'L':
+ cfg.ro_txn_items = get_nonneg_optarg();
+ break;
+ case 'm':
+ cfg.rw_txn_duration = get_nonneg_optarg();
+ break;
+ case 'u':
+ cfg.cache_max_usage = get_nonneg_optarg();
+ break;
+ case 'f':
+ cfg.cache_to_be_freed = get_nonneg_optarg();
+ break;
+ case 'w':
+ cfg.rw_txn_delay = get_nonneg_optarg();
+ break;
+ case 't':
+ cfg.temp_keys_space = get_nonneg_optarg();
+ cfg.temp_keys_space *= 1048576;
+ break;
+ case 'n':
+ cfg.dry_run = true;
+ break;
+ case 'v':
+ kr_log_level_set(LOG_DEBUG);
+ break;
+ case ':':
+ case '?':
+ case 'h':
+ print_help();
+ return 1;
+ default:
+ kr_assert(false);
+ }
+ }
+
+ if (cfg.cache_path == NULL) {
+ print_help();
+ return 1;
+ }
+
+ int exit_code = 0;
+ kr_cache_gc_state_t *gc_state = NULL;
+ bool last_espace = false;
+ do {
+ int ret = kr_cache_gc(&cfg, &gc_state);
+
+ /* Let's tolerate ESPACE unless twice in a row. */
+ if (ret == KNOT_ESPACE) {
+ if (!last_espace)
+ ret = KNOT_EOK;
+ last_espace = true;
+ } else {
+ last_espace = false;
+ }
+
+ // ENOENT: kresd may not be started yet or cleared the cache now
+ // MDB_MAP_RESIZED: GC bailed out but on next iteration it should be OK
+ if (ret && ret != KNOT_ENOENT && ret != kr_error(MDB_MAP_RESIZED)) {
+ printf("Error (%s)\n", knot_strerror(ret));
+ exit_code = 10;
+ break;
+ }
+
+ usleep(cfg.gc_interval);
+ } while (cfg.gc_interval > 0 && !killed);
+
+ kr_cache_gc_free_state(&gc_state);
+
+ return exit_code;
+}
diff --git a/utils/cache_gc/meson.build b/utils/cache_gc/meson.build
new file mode 100644
index 0000000..02ab6c6
--- /dev/null
+++ b/utils/cache_gc/meson.build
@@ -0,0 +1,31 @@
+## utils/cache_gc
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+cache_gc_src = files([
+ 'categories.c',
+ 'db.c',
+ 'kr_cache_gc.c',
+ 'main.c',
+])
+c_src_lint += cache_gc_src
+
+if build_utils
+ cache_gc = executable(
+ 'kres-cache-gc',
+ cache_gc_src,
+ dependencies: [
+ kresconfig_dep,
+ contrib_dep,
+ libkres_dep,
+ libknot,
+ luajit_inc,
+ ],
+ install: true,
+ install_dir: get_option('sbindir'),
+ )
+
+integr_tests += [
+ ['gc_cache_overflow', meson.current_source_dir() / 'test.integr'],
+]
+
+endif
diff --git a/utils/cache_gc/test.integr/deckard.yaml b/utils/cache_gc/test.integr/deckard.yaml
new file mode 100644
index 0000000..b1a8b15
--- /dev/null
+++ b/utils/cache_gc/test.integr/deckard.yaml
@@ -0,0 +1,37 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+programs:
+- name: kresd1
+ binary: kresd
+ additional:
+ - -n
+ - ../kresd1/
+ templates:
+ - lib/cache/overflow.test.integr/kresd_config.j2
+ - tests/config/test_dns_generators.lua
+ configs:
+ - config
+ - dns_gen.lua
+- name: kresd2
+ binary: kresd
+ additional:
+ - -n
+ - ../kresd1/
+ templates:
+ - lib/cache/overflow.test.integr/kresd_config.j2
+ - tests/config/test_dns_generators.lua
+ configs:
+ - config
+ - dns_gen.lua
+- name: gc
+ binary: kres-cache-gc
+ additional:
+ # small cache needs shorter RW transactions and larger "percentages"
+ - -l8
+ - -u50
+ - -f20
+ - -d1
+ - -c
+ - ../kresd1/
+ conncheck: False
+ templates: []
+ configs: []
diff --git a/utils/cache_gc/test.integr/val_rrsig.rpl b/utils/cache_gc/test.integr/val_rrsig.rpl
new file mode 100644
index 0000000..22002b7
--- /dev/null
+++ b/utils/cache_gc/test.integr/val_rrsig.rpl
@@ -0,0 +1,737 @@
+query-minimization: off
+CONFIG_END
+
+SCENARIO_BEGIN Test validator with qtype RRSIG response
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+STEP 2 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH opcode rcode flags question answer
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 192.0.2.1
+ENTRY_END
+
+STEP 3 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+STEP 4 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH opcode rcode flags question answer
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 192.0.2.1
+ENTRY_END
+
+STEP 5 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+STEP 6 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH opcode rcode flags question answer
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 192.0.2.1
+ENTRY_END
+
+STEP 7 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+STEP 8 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH opcode rcode flags question answer
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 192.0.2.1
+ENTRY_END
+
+STEP 9 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH opcode rcode flags question answer
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 192.0.2.1
+ENTRY_END
+
+STEP 11 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+STEP 12 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH opcode rcode flags question answer
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 192.0.2.1
+ENTRY_END
+
+STEP 13 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+STEP 14 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH opcode rcode flags question answer
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 192.0.2.1
+ENTRY_END
+
+STEP 15 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+STEP 16 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH opcode rcode flags question answer
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 192.0.2.1
+ENTRY_END
+
+STEP 17 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+STEP 18 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH opcode rcode flags question answer
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 192.0.2.1
+ENTRY_END
+
+STEP 19 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+STEP 20 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH opcode rcode flags question answer
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 192.0.2.1
+ENTRY_END
+
+STEP 21 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+STEP 22 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH opcode rcode flags question answer
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 192.0.2.1
+ENTRY_END
+
+STEP 23 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+STEP 24 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH opcode rcode flags question answer
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 192.0.2.1
+ENTRY_END
+
+STEP 25 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+STEP 26 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH opcode rcode flags question answer
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 192.0.2.1
+ENTRY_END
+
+STEP 27 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+STEP 28 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH opcode rcode flags question answer
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 192.0.2.1
+ENTRY_END
+
+STEP 29 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+STEP 30 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH opcode rcode flags question answer
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 192.0.2.1
+ENTRY_END
+
+STEP 31 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+STEP 32 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH opcode rcode flags question answer
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 192.0.2.1
+ENTRY_END
+
+STEP 33 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+STEP 34 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH opcode rcode flags question answer
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 192.0.2.1
+ENTRY_END
+
+STEP 35 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+STEP 36 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH opcode rcode flags question answer
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 192.0.2.1
+ENTRY_END
+
+STEP 37 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+STEP 38 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH opcode rcode flags question answer
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 192.0.2.1
+ENTRY_END
+
+STEP 39 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+STEP 40 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH opcode rcode flags question answer
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 192.0.2.1
+ENTRY_END
+
+STEP 41 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+STEP 42 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH opcode rcode flags question answer
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 192.0.2.1
+ENTRY_END
+
+STEP 43 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+STEP 44 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH opcode rcode flags question answer
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 192.0.2.1
+ENTRY_END
+
+STEP 45 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+STEP 46 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH opcode rcode flags question answer
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 192.0.2.1
+ENTRY_END
+
+STEP 47 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+STEP 48 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH opcode rcode flags question answer
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 192.0.2.1
+ENTRY_END
+
+STEP 49 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+STEP 50 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH opcode rcode flags question answer
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 192.0.2.1
+ENTRY_END
+
+STEP 51 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+STEP 52 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH opcode rcode flags question answer
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 192.0.2.1
+ENTRY_END
+
+STEP 53 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+STEP 54 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH opcode rcode flags question answer
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 192.0.2.1
+ENTRY_END
+
+STEP 55 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+STEP 56 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH opcode rcode flags question answer
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 192.0.2.1
+ENTRY_END
+
+STEP 57 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+STEP 58 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH opcode rcode flags question answer
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 192.0.2.1
+ENTRY_END
+
+STEP 59 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+STEP 60 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH opcode rcode flags question answer
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 192.0.2.1
+ENTRY_END
+
+STEP 61 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+STEP 62 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH opcode rcode flags question answer
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 192.0.2.1
+ENTRY_END
+
+STEP 63 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+STEP 64 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH opcode rcode flags question answer
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 192.0.2.1
+ENTRY_END
+
+STEP 65 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+STEP 66 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH opcode rcode flags question answer
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 192.0.2.1
+ENTRY_END
+
+STEP 67 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+STEP 68 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH opcode rcode flags question answer
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 192.0.2.1
+ENTRY_END
+
+STEP 69 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+STEP 70 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH opcode rcode flags question answer
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 192.0.2.1
+ENTRY_END
+
+STEP 71 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+STEP 72 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH opcode rcode flags question answer
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 192.0.2.1
+ENTRY_END
+
+STEP 73 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+STEP 74 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH opcode rcode flags question answer
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 192.0.2.1
+ENTRY_END
+
+STEP 75 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+STEP 76 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH opcode rcode flags question answer
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 192.0.2.1
+ENTRY_END
+
+STEP 77 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+STEP 78 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH opcode rcode flags question answer
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 192.0.2.1
+ENTRY_END
+
+STEP 79 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+STEP 80 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH opcode rcode flags question answer
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 192.0.2.1
+ENTRY_END
+
+STEP 81 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+STEP 82 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH opcode rcode flags question answer
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 192.0.2.1
+ENTRY_END
+
+STEP 83 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+STEP 84 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH opcode rcode flags question answer
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 192.0.2.1
+ENTRY_END
+
+STEP 85 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+STEP 86 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH opcode rcode flags question answer
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A 192.0.2.1
+ENTRY_END
+
+SCENARIO_END
diff --git a/utils/client/kresc.c b/utils/client/kresc.c
new file mode 100644
index 0000000..16782a1
--- /dev/null
+++ b/utils/client/kresc.c
@@ -0,0 +1,458 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+#include <arpa/inet.h>
+#include <contrib/ccan/asprintf/asprintf.h>
+#include <editline/readline.h>
+#include <errno.h>
+#include <histedit.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/un.h>
+#include <unistd.h>
+
+#define HISTORY_FILE "kresc_history"
+#define PROGRAM_NAME "kresc"
+
+FILE *g_tty = NULL; //!< connection to the daemon
+
+static char *run_cmd(const char *cmd, size_t * out_len);
+
+const char *prompt(EditLine * e)
+{
+ return PROGRAM_NAME "> ";
+}
+
+bool starts_with(const char *a, const char *b)
+{
+ if (strncmp(a, b, strlen(b)) == 0)
+ return 1;
+ return 0;
+}
+
+//! Returns Lua name of type of value, NULL on error. Puts length of type in name_len;
+char *get_type_name(const char *value)
+{
+ if (value == NULL) {
+ return NULL;
+ }
+
+ for (int i = 0; value[i]; i++) {
+ if (value[i] == ')') {
+ //Return NULL to prevent unexpected function call
+ return NULL;
+ }
+ }
+
+ char *cmd = afmt("type(%s)", value);
+ if (!cmd) {
+ perror("While tab-completing.");
+ return NULL;
+ }
+
+ size_t name_len;
+ char *type = run_cmd(cmd, &name_len);
+ if (!type) {
+ return NULL;
+ }
+ free(cmd);
+
+ if (starts_with(type, "[")) {
+ //Return "nil" on non-valid name.
+ free(type);
+ return strdup("nil");
+ } else {
+ type[strlen(type) - 1] = '\0';
+ return type;
+ }
+}
+
+static void complete_function(EditLine * el)
+{
+ //Add left parenthesis to function name.
+ el_insertstr(el, "(");
+}
+
+static void complete_members(EditLine * el, const char *str,
+ const char *str_type, int str_len, char *dot)
+{
+ char *table = strdup(str);
+ if (!table) {
+ perror("While tab-completing");
+ return;
+ }
+ //Get only the table name (without partial member name).
+ if (dot) {
+ *(table + (dot - str)) = '\0';
+ }
+ //Insert a dot after the table name.
+ if (!strncmp(str_type, "table", 5)) {
+ el_insertstr(el, ".");
+ str_len++;
+ }
+ //Check if the substring before dot is a valid table name.
+ const char *t_type = get_type_name(table);
+ if (t_type && !strncmp("table", t_type, 5)) {
+ //Get string of members of the table.
+ char *cmd =
+ afmt
+ ("do local s=\"\"; for i in pairs(%s) do s=s..i..\"\\n\" end return(s) end",
+ table);
+ if (!cmd) {
+ perror("While tab-completing.");
+ goto complete_members_exit;
+ }
+ size_t members_len;
+ char *members = run_cmd(cmd, &members_len);
+ free(cmd);
+ if (!members) {
+ perror("While communication with daemon");
+ goto complete_members_exit;
+ }
+ //Split members by newline.
+ char *members_tok = strdup(members);
+ free(members);
+ if (!members_tok) {
+ goto complete_members_exit;
+ }
+ char *token = strtok(members_tok, "\n");
+ int matches = 0;
+ char *lastmatch = NULL;
+ if (!dot || dot - str + 1 == strlen(str)) {
+ //Prints all members.
+ while (token) {
+ char *member = afmt("%s.%s", table, token);
+ const char *member_type = get_type_name(member);
+ if (member && member_type) {
+ printf("\n%s (%s)", member, member_type);
+ free(member);
+ free((void *)member_type);
+ } else if (member) {
+ printf("\n%s", member);
+ free(member);
+ }
+ token = strtok(NULL, "\n");
+ matches++;
+ }
+ } else {
+ //Print members matching the current line.
+ while (token) {
+ if (starts_with(token, dot + 1)) {
+ const char *member_type =
+ get_type_name(afmt
+ ("%s.%s", table,
+ token));
+ if (member_type) {
+ printf("\n%s.%s (%s)", table,
+ token, member_type);
+ free((void *)member_type);
+ } else {
+ printf("\n%s.%s", table, token);
+ }
+ lastmatch = token;
+ matches++;
+ }
+ token = strtok(NULL, "\n");
+ }
+
+ //Complete matching member.
+ if (matches == 1) {
+ el_deletestr(el, str_len);
+ el_insertstr(el, table);
+ el_insertstr(el, ".");
+ el_insertstr(el, lastmatch);
+ }
+ }
+ if (matches > 1) {
+ printf("\n");
+ }
+ free(members_tok);
+ }
+
+complete_members_exit:
+ free(table);
+ if(t_type) {
+ free((void*)t_type);
+ }
+}
+
+static void complete_globals(EditLine * el, const char *str, int str_len)
+{
+ //Parse Lua globals.
+ size_t globals_len;
+ char *globals = run_cmd("_G.__orig_name_list", &globals_len);
+ if (!globals) {
+ perror("While tab-completing");
+ return;
+ }
+ //Show possible globals.
+ char *globals_tok = strdup(globals);
+ free(globals);
+ if (!globals_tok) {
+ return;
+ }
+ char *token = strtok(globals_tok, "\n");
+ int matches = 0;
+ char *lastmatch = NULL;
+ while (token) {
+ if (str && starts_with(token, str)) {
+ char *name = get_type_name(token);
+ printf("\n%s (%s)", token, name);
+ free(name);
+ lastmatch = token;
+ matches++;
+ }
+ token = strtok(NULL, "\n");
+ }
+ if (matches > 1) {
+ printf("\n");
+ }
+ //Complete matching global.
+ if (matches == 1) {
+ el_deletestr(el, str_len);
+ el_insertstr(el, lastmatch);
+ }
+ free(globals_tok);
+}
+
+static unsigned char complete(EditLine * el, int ch)
+{
+ int argc, pos;
+ const char **argv;
+ const LineInfo *li = el_line(el);
+ Tokenizer *tok = tok_init(NULL);
+
+ //Tokenize current line.
+ int ret = tok_line(tok, li, &argc, &argv, NULL, &pos);
+
+ if (ret != 0) {
+ perror("While tab-completing.");
+ goto complete_exit;
+ }
+ //Show help.
+ if (argc == 0) {
+ size_t help_len;
+ char *help = run_cmd("help()", &help_len);
+ if (help) {
+ printf("\n%s", help);
+ free(help);
+ } else {
+ perror("While communication with daemon");
+ }
+ goto complete_exit;
+ }
+
+ if (argc > 1) {
+ goto complete_exit;
+ }
+ //Get name of type of current line.
+ const char *type = get_type_name(argv[0]);
+
+ if (!type) {
+ goto complete_exit;
+ }
+ //Get position of last dot in current line (useful for parsing table).
+ char *dot = strrchr(argv[0], '.');
+
+ if (strncmp(type, "table", 5) != 0 && !dot) {
+ //Line is not a name of some table and there is no dot in it.
+ complete_globals(el, argv[0], pos);
+ } else if ((dot && strncmp(type, "nil", 3) == 0)
+ || strncmp(type, "table", 5) == 0) {
+ //Current line (or part of it) is a name of some table.
+ complete_members(el, argv[0], type, pos, dot);
+ } else if (strncmp(type, "function", 8) == 0) {
+ //Current line is a function.
+ complete_function(el);
+ }
+ if (type) {
+ free((void *)type);
+ }
+
+complete_exit:
+ tok_reset(tok);
+ tok_end(tok);
+ return CC_REDISPLAY;
+}
+
+//! Initialize connection to the daemon; return 0 on success.
+static int init_tty(const char *path)
+{
+ int fd = socket(AF_UNIX, SOCK_STREAM, 0);
+ if (fd < 0)
+ return 1;
+
+ struct sockaddr_un addr;
+ addr.sun_family = AF_UNIX;
+ size_t plen = strlen(path);
+ if (plen + 1 > sizeof(addr.sun_path)) {
+ fprintf(stderr, "Path too long\n");
+ close(fd);
+ return 1;
+ }
+ memcpy(addr.sun_path, path, plen + 1);
+ if (connect(fd, (const struct sockaddr *)&addr, sizeof(addr))) {
+ perror("While connecting to daemon");
+ close(fd);
+ return 1;
+ }
+ g_tty = fdopen(fd, "r+");
+ if (!g_tty) {
+ perror("While opening TTY");
+ close(fd);
+ return 1;
+ }
+
+ // Switch to binary mode and consume the text "> ".
+ if (fprintf(g_tty, "__binary\n") < 0 || !fread(&addr, 2, 1, g_tty)
+ || fflush(g_tty)) {
+ perror("While initializing TTY");
+ fclose(g_tty);
+ g_tty = NULL;
+ return 1;
+ }
+
+ return 0;
+}
+
+//! Run a command on the daemon; return the answer or NULL on failure, puts answer length to out_len.
+static char *run_cmd(const char *cmd, size_t * out_len)
+{
+ if (!g_tty || !cmd)
+ return NULL;
+ if (fprintf(g_tty, "%s", cmd) < 0 || fflush(g_tty))
+ return NULL;
+ uint32_t len;
+ if (!fread(&len, sizeof(len), 1, g_tty))
+ return NULL;
+ len = ntohl(len);
+ if (!len)
+ return NULL;
+ char *msg = malloc(1 + (size_t) len);
+ if (!msg)
+ return NULL;
+ if (len && !fread(msg, len, 1, g_tty)) {
+ free(msg);
+ return NULL;
+ }
+ msg[len] = '\0';
+ *out_len = len;
+ return msg;
+}
+
+static int interact()
+{
+ EditLine *el;
+ History *hist;
+ int count;
+ const char *line;
+ HistEvent ev;
+ el = el_init(PROGRAM_NAME, stdin, stdout, stderr);
+ el_set(el, EL_PROMPT, prompt);
+ el_set(el, EL_EDITOR, "emacs");
+ el_set(el, EL_ADDFN, PROGRAM_NAME "-complete",
+ "Perform " PROGRAM_NAME " completion.", complete);
+ el_set(el, EL_BIND, "^I", PROGRAM_NAME "-complete", NULL);
+
+ hist = history_init();
+ if (hist == 0) {
+ perror("While initializing command history");
+ return 1;
+ }
+ history(hist, &ev, H_SETSIZE, 800);
+ el_set(el, EL_HIST, history, hist);
+
+ char *hist_file = NULL;
+
+ char *data_home = getenv("XDG_DATA_HOME");
+
+ //Check whether $XDG_DATA_HOME is set.
+ if (!data_home || *data_home == '\0') {
+ const char *home = getenv("HOME"); //This should be set on any POSIX compliant OS, even for nobody
+
+ //Create necessary folders.
+ char *dirs[3] =
+ { afmt("%s/.local", home), afmt("%s/.local/share", home),
+ afmt("%s/.local/share/knot-resolver/", home)
+ };
+ bool ok = true;
+ for (int i = 0; i < 3; i++) {
+ if (mkdir(dirs[i], 0755) && errno != EEXIST) {
+ ok = false;
+ break;
+ }
+ }
+ if (ok) {
+ hist_file =
+ afmt("%s/.local/share/knot-resolver/" HISTORY_FILE, home);
+ }
+ } else {
+ if (!mkdir(afmt("%s/knot-resolver/", data_home), 0755)
+ || errno == EEXIST) {
+ hist_file = afmt("%s/knot-resolver/" HISTORY_FILE, data_home);
+ }
+ }
+
+ //Load history file
+ if (hist_file) {
+ history(hist, &ev, H_LOAD, hist_file);
+ } else {
+ perror("While opening history file");
+ }
+
+ while (1) {
+ line = el_gets(el, &count);
+ if (count > 0) {
+ history(hist, &ev, H_ENTER, line);
+ size_t msg_len;
+ char *msg = run_cmd(line, &msg_len);
+ if (!msg) {
+ perror("While communication with daemon");
+ history_end(hist);
+ el_end(el);
+ free(msg);
+ return 1;
+ }
+ printf("%s", msg);
+ if (msg_len > 0 && msg[msg_len - 1] != '\n') {
+ printf("\n");
+ }
+ if (hist_file) {
+ history(hist, &ev, H_SAVE, hist_file);
+ }
+ free(msg);
+ }
+ }
+ history_end(hist);
+ free(hist_file);
+ el_end(el);
+ if (feof(stdin))
+ return 0;
+ perror("While reading input");
+ return 1;
+}
+
+int main(int argc, char **argv)
+{
+ fprintf(stderr, "Warning! %s is highly experimental, use at own risk.\n", argv[0]);
+ fprintf(stderr, "Please tell authors what features you expect from client utility.\n");
+ if (argc != 2) {
+ fprintf(stderr, "Usage: %s tty/xxxxx\n", argv[0]);
+ return 1;
+ }
+
+ int res = init_tty(argv[1]);
+
+ if (!res)
+ res = interact();
+
+ if (g_tty)
+ fclose(g_tty);
+ return res;
+}
diff --git a/utils/client/meson.build b/utils/client/meson.build
new file mode 100644
index 0000000..761c2cd
--- /dev/null
+++ b/utils/client/meson.build
@@ -0,0 +1,37 @@
+# client
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+kresc_src = files([
+ 'kresc.c',
+])
+c_src_lint += kresc_src
+
+build_client = false
+if get_option('client') != 'disabled'
+ message('--- client dependencies ---')
+ libedit = dependency('libedit', required: false)
+ if libedit.found()
+ build_client = true
+ else # darwin workaround: missing pkgconfig
+ libedit = meson.get_compiler('c').find_library(
+ 'edit', required: get_option('client') == 'enabled')
+ if libedit.found()
+ build_client = true
+ endif
+ endif
+ message('---------------------------')
+endif
+
+
+if build_client
+ kresc = executable(
+ 'kresc',
+ kresc_src,
+ dependencies: [
+ contrib_dep,
+ libedit,
+ ],
+ install: true,
+ install_dir: get_option('sbindir'),
+ )
+endif
diff --git a/utils/meson.build b/utils/meson.build
new file mode 100644
index 0000000..0487538
--- /dev/null
+++ b/utils/meson.build
@@ -0,0 +1,8 @@
+# utils
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+build_utils = get_option('utils') != 'disabled'
+
+subdir('client')
+subdir('cache_gc')
+subdir('upgrade')
diff --git a/utils/upgrade/meson.build b/utils/upgrade/meson.build
new file mode 100644
index 0000000..33983e8
--- /dev/null
+++ b/utils/upgrade/meson.build
@@ -0,0 +1,13 @@
+## utils/upgrade
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+upgrade_config = configuration_data()
+upgrade_config.set('etc_dir', etc_dir)
+upgrade_config.set('systemd_work_dir', systemd_work_dir)
+
+configure_file(
+ input: 'upgrade-4-to-5.lua.in',
+ output: 'upgrade-4-to-5.lua',
+ configuration: upgrade_config,
+ install_dir: lib_dir
+)
diff --git a/utils/upgrade/upgrade-4-to-5.lua.in b/utils/upgrade/upgrade-4-to-5.lua.in
new file mode 100644
index 0000000..28f800b
--- /dev/null
+++ b/utils/upgrade/upgrade-4-to-5.lua.in
@@ -0,0 +1,87 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+
+local upg_dir = '@systemd_work_dir@/.upgrade-4-to-5'
+local out = upg_dir..'/kresd.conf.net'
+local sockets = {
+ { file='kresd.socket', kind='dns' },
+ { file='kresd-tls.socket', kind='tls' },
+ { file='kresd-doh.socket', kind='doh2' },
+ { file='kresd-webmgmt.socket', kind='webmgmt' },
+}
+
+-- globals
+addr_port = {}
+outfile = io.open(out, 'w')
+
+if outfile == nil then
+ -- this is technically an error, but upgrade script shouldn't fail in scriptlets
+ os.exit(0) -- make no changes and exit
+end
+
+outfile:write("-- Suggested network interface configuration\n")
+outfile:write("-- See https://knot-resolver.readthedocs.io/en/stable/upgrading.html\n\n")
+outfile:write("-- Please remove any unused or undesired interfaces and add them to\n")
+outfile:write("-- @etc_dir@/kresd.conf\n\n")
+
+local function write_net_listen(addr, port, kind)
+ -- make sure (addr, port) combination is unique
+ for _, val in ipairs(addr_port) do
+ if val.addr == addr and val.port == port then
+ return
+ end
+ end
+
+ table.insert(addr_port, { addr=addr, port=port })
+ outfile:write(
+ "net.listen('"..addr.."', "..tostring(port)..
+ ", { kind = '"..kind.."', freebind = true })\n")
+end
+
+local function convert(line, kind, ipv6only)
+ local patterns = {
+ '^[^=]+=(%d+%.%d+%.%d+%.%d+):(%d+)', -- IPv4
+ '^[^=]+=%[([^%]]+)%]:(%d+)', -- IPv6
+ '^[^=]+=(/.*)', -- UNIX
+ }
+
+ -- Datagram is either implied (dns) or unsupported (tls/doh/webmgmt)
+ if not line:match('^Listen.*Stream') then
+ return
+ end
+
+ for _, pattern in ipairs(patterns) do
+ local addr, port = line:match(pattern)
+ if addr ~= nil then
+ write_net_listen(addr, port, kind)
+ if not ipv6only then
+ if addr:match('^::$') then
+ write_net_listen('0.0.0.0', port, kind)
+ end
+ if addr:match('^::1$') then
+ write_net_listen('127.0.0.1', port, kind)
+ end
+ end
+ end
+ end
+ return
+end
+
+for _, socket in pairs(sockets) do
+ local ipv6only = false
+ local ipv6only_f = io.open(upg_dir..'/'..socket.file..'.v6only', 'r')
+ if ipv6only_f ~= nil then
+ ipv6only = true
+ io.close(ipv6only_f)
+ end
+ local sockinfo = io.open(upg_dir..'/'..socket.file, 'r')
+ if sockinfo ~= nil then
+ for line in sockinfo:lines() do
+ convert(line, socket.kind, ipv6only)
+ end
+ end
+end
+
+outfile:write("\n")
+
+io.close(outfile)
+os.exit(0)